summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml16
-rw-r--r--.clang-format7
-rw-r--r--.clang-tidy44
-rw-r--r--.gitattributes1
-rw-r--r--.github/config.yml14
-rw-r--r--.gitignore3
-rw-r--r--.travis.yml18
-rw-r--r--COPYRIGHT.txt46
-rw-r--r--DONORS.md83
-rw-r--r--SConstruct15
-rw-r--r--core/SCsub2
-rw-r--r--core/array.cpp226
-rw-r--r--core/array.h9
-rw-r--r--core/bind/core_bind.cpp546
-rw-r--r--core/bind/core_bind.h49
-rw-r--r--core/callable.cpp27
-rw-r--r--core/callable.h11
-rw-r--r--core/callable_method_pointer.cpp1
-rw-r--r--core/callable_method_pointer.h44
-rw-r--r--core/class_db.cpp259
-rw-r--r--core/class_db.h34
-rw-r--r--core/color.cpp87
-rw-r--r--core/color.h43
-rw-r--r--core/color_names.inc4
-rw-r--r--core/command_queue_mt.cpp25
-rw-r--r--core/command_queue_mt.h58
-rw-r--r--core/compressed_translation.cpp38
-rw-r--r--core/compressed_translation.h10
-rw-r--r--core/container_type_validate.h126
-rw-r--r--core/core_string_names.h1
-rw-r--r--core/cowdata.h69
-rw-r--r--core/crypto/crypto.cpp37
-rw-r--r--core/crypto/crypto.h13
-rw-r--r--core/crypto/crypto_core.h5
-rw-r--r--core/crypto/hashing_context.cpp8
-rw-r--r--core/crypto/hashing_context.h4
-rw-r--r--core/debugger/debugger_marshalls.cpp3
-rw-r--r--core/debugger/debugger_marshalls.h32
-rw-r--r--core/debugger/engine_debugger.cpp63
-rw-r--r--core/debugger/engine_debugger.h7
-rw-r--r--core/debugger/local_debugger.cpp55
-rw-r--r--core/debugger/local_debugger.h1
-rw-r--r--core/debugger/remote_debugger.cpp149
-rw-r--r--core/debugger/remote_debugger.h13
-rw-r--r--core/debugger/remote_debugger_peer.cpp38
-rw-r--r--core/debugger/remote_debugger_peer.h4
-rw-r--r--core/debugger/script_debugger.cpp27
-rw-r--r--core/debugger/script_debugger.h1
-rw-r--r--core/dictionary.cpp60
-rw-r--r--core/dictionary.h1
-rw-r--r--core/engine.cpp44
-rw-r--r--core/engine.h33
-rw-r--r--core/error_macros.cpp12
-rw-r--r--core/error_macros.h86
-rw-r--r--core/func_ref.cpp14
-rw-r--r--core/func_ref.h4
-rw-r--r--core/global_constants.cpp141
-rw-r--r--core/hash_map.h141
-rw-r--r--core/hashfuncs.h20
-rw-r--r--core/image.cpp1102
-rw-r--r--core/image.h17
-rw-r--r--core/input/SCsub2
-rw-r--r--core/input/gamecontrollerdb_204.txt269
-rw-r--r--core/input/gamecontrollerdb_205.txt337
-rw-r--r--core/input/godotcontrollerdb.txt19
-rw-r--r--core/input/input.cpp (renamed from core/input/input_filter.cpp)890
-rw-r--r--core/input/input.h (renamed from core/input/input_filter.h)138
-rw-r--r--core/input/input_builders.py13
-rw-r--r--core/input/input_event.cpp366
-rw-r--r--core/input/input_event.h292
-rw-r--r--core/input/input_map.cpp50
-rw-r--r--core/input/input_map.h1
-rw-r--r--core/io/compression.cpp19
-rw-r--r--core/io/compression.h3
-rw-r--r--core/io/config_file.cpp56
-rw-r--r--core/io/config_file.h1
-rw-r--r--core/io/dtls_server.cpp6
-rw-r--r--core/io/dtls_server.h2
-rw-r--r--core/io/file_access_buffered.cpp26
-rw-r--r--core/io/file_access_buffered.h11
-rw-r--r--core/io/file_access_buffered_fa.h42
-rw-r--r--core/io/file_access_compressed.cpp87
-rw-r--r--core/io/file_access_compressed.h37
-rw-r--r--core/io/file_access_encrypted.cpp68
-rw-r--r--core/io/file_access_encrypted.h12
-rw-r--r--core/io/file_access_memory.cpp33
-rw-r--r--core/io/file_access_memory.h5
-rw-r--r--core/io/file_access_network.cpp73
-rw-r--r--core/io/file_access_network.h33
-rw-r--r--core/io/file_access_pack.cpp140
-rw-r--r--core/io/file_access_pack.h41
-rw-r--r--core/io/file_access_zip.cpp81
-rw-r--r--core/io/file_access_zip.h14
-rw-r--r--core/io/http_client.cpp102
-rw-r--r--core/io/http_client.h33
-rw-r--r--core/io/image_loader.cpp33
-rw-r--r--core/io/image_loader.h3
-rw-r--r--core/io/ip.cpp39
-rw-r--r--core/io/ip_address.cpp71
-rw-r--r--core/io/ip_address.h30
-rw-r--r--core/io/json.cpp140
-rw-r--r--core/io/json.h2
-rw-r--r--core/io/logger.cpp43
-rw-r--r--core/io/logger.h7
-rw-r--r--core/io/marshalls.cpp274
-rw-r--r--core/io/marshalls.h29
-rw-r--r--core/io/multiplayer_api.cpp115
-rw-r--r--core/io/multiplayer_api.h7
-rw-r--r--core/io/net_socket.cpp4
-rw-r--r--core/io/net_socket.h1
-rw-r--r--core/io/networked_multiplayer_peer.cpp4
-rw-r--r--core/io/networked_multiplayer_peer.h3
-rw-r--r--core/io/packet_peer.cpp73
-rw-r--r--core/io/packet_peer.h8
-rw-r--r--core/io/packet_peer_dtls.cpp5
-rw-r--r--core/io/packet_peer_dtls.h2
-rw-r--r--core/io/packet_peer_udp.cpp58
-rw-r--r--core/io/packet_peer_udp.h12
-rw-r--r--core/io/pck_packer.cpp59
-rw-r--r--core/io/pck_packer.h6
-rw-r--r--core/io/resource_format_binary.cpp296
-rw-r--r--core/io/resource_format_binary.h24
-rw-r--r--core/io/resource_importer.cpp59
-rw-r--r--core/io/resource_importer.h4
-rw-r--r--core/io/resource_loader.cpp183
-rw-r--r--core/io/resource_loader.h12
-rw-r--r--core/io/resource_saver.cpp44
-rw-r--r--core/io/resource_saver.h1
-rw-r--r--core/io/stream_peer.cpp93
-rw-r--r--core/io/stream_peer.h9
-rw-r--r--core/io/stream_peer_ssl.cpp9
-rw-r--r--core/io/stream_peer_ssl.h4
-rw-r--r--core/io/stream_peer_tcp.cpp46
-rw-r--r--core/io/stream_peer_tcp.h7
-rw-r--r--core/io/tcp_server.cpp16
-rw-r--r--core/io/tcp_server.h1
-rw-r--r--core/io/translation_loader_po.cpp51
-rw-r--r--core/io/translation_loader_po.h4
-rw-r--r--core/io/udp_server.cpp15
-rw-r--r--core/io/xml_parser.cpp136
-rw-r--r--core/io/xml_parser.h13
-rw-r--r--core/io/zip_io.cpp17
-rw-r--r--core/list.h213
-rw-r--r--core/local_vector.h238
-rw-r--r--core/make_binders.py6
-rw-r--r--core/map.h221
-rw-r--r--core/math/a_star.cpp102
-rw-r--r--core/math/a_star.h30
-rw-r--r--core/math/aabb.cpp74
-rw-r--r--core/math/aabb.h165
-rw-r--r--core/math/audio_frame.h4
-rw-r--r--core/math/basis.cpp175
-rw-r--r--core/math/basis.h20
-rw-r--r--core/math/camera_matrix.cpp91
-rw-r--r--core/math/camera_matrix.h4
-rw-r--r--core/math/delaunay_2d.h (renamed from core/math/delaunay.h)25
-rw-r--r--core/math/delaunay_3d.h408
-rw-r--r--core/math/disjoint_set.h5
-rw-r--r--core/math/expression.cpp489
-rw-r--r--core/math/expression.h39
-rw-r--r--core/math/face3.cpp73
-rw-r--r--core/math/face3.h34
-rw-r--r--core/math/geometry.cpp523
-rw-r--r--core/math/geometry.h546
-rw-r--r--core/math/math_fieldwise.cpp1
-rw-r--r--core/math/math_funcs.cpp16
-rw-r--r--core/math/math_funcs.h20
-rw-r--r--core/math/octree.h341
-rw-r--r--core/math/plane.cpp25
-rw-r--r--core/math/plane.h20
-rw-r--r--core/math/quat.cpp13
-rw-r--r--core/math/quat.h15
-rw-r--r--core/math/quick_hull.cpp69
-rw-r--r--core/math/quick_hull.h19
-rw-r--r--core/math/random_number_generator.cpp2
-rw-r--r--core/math/random_number_generator.h7
-rw-r--r--core/math/rect2.cpp80
-rw-r--r--core/math/rect2.h118
-rw-r--r--core/math/transform.cpp27
-rw-r--r--core/math/transform.h13
-rw-r--r--core/math/transform_2d.cpp47
-rw-r--r--core/math/transform_2d.h22
-rw-r--r--core/math/triangle_mesh.cpp145
-rw-r--r--core/math/triangle_mesh.h13
-rw-r--r--core/math/triangulate.cpp45
-rw-r--r--core/math/vector2.cpp60
-rw-r--r--core/math/vector2.h74
-rw-r--r--core/math/vector3.cpp21
-rw-r--r--core/math/vector3.h73
-rw-r--r--core/math/vector3i.cpp6
-rw-r--r--core/math/vector3i.h52
-rw-r--r--core/message_queue.cpp78
-rw-r--r--core/message_queue.h9
-rw-r--r--core/method_bind.cpp20
-rw-r--r--core/method_bind.h51
-rw-r--r--core/method_ptrcall.h8
-rw-r--r--core/node_path.cpp200
-rw-r--r--core/node_path.h9
-rw-r--r--core/oa_hash_map.h61
-rw-r--r--core/object.cpp435
-rw-r--r--core/object.h129
-rw-r--r--core/ordered_hash_map.h37
-rw-r--r--core/os/dir_access.cpp105
-rw-r--r--core/os/dir_access.h26
-rw-r--r--core/os/file_access.cpp177
-rw-r--r--core/os/file_access.h20
-rw-r--r--core/os/keyboard.cpp11
-rw-r--r--core/os/main_loop.cpp26
-rw-r--r--core/os/main_loop.h5
-rw-r--r--core/os/memory.cpp13
-rw-r--r--core/os/memory.h38
-rw-r--r--core/os/midi_driver.cpp9
-rw-r--r--core/os/midi_driver.h1
-rw-r--r--core/os/mutex.h3
-rw-r--r--core/os/os.cpp124
-rw-r--r--core/os/os.h32
-rw-r--r--core/os/rw_lock.cpp4
-rw-r--r--core/os/rw_lock.h20
-rw-r--r--core/os/semaphore.h3
-rw-r--r--core/os/thread.cpp20
-rw-r--r--core/os/thread.h5
-rw-r--r--core/os/thread_dummy.cpp8
-rw-r--r--core/os/thread_dummy.h2
-rw-r--r--core/os/threaded_array_processor.h6
-rw-r--r--core/packed_data_container.cpp88
-rw-r--r--core/packed_data_container.h7
-rw-r--r--core/pair.h2
-rw-r--r--core/pool_allocator.cpp96
-rw-r--r--core/pool_allocator.h15
-rw-r--r--core/print_string.cpp20
-rw-r--r--core/print_string.h13
-rw-r--r--core/project_settings.cpp257
-rw-r--r--core/project_settings.h38
-rw-r--r--core/reference.cpp23
-rw-r--r--core/reference.h58
-rw-r--r--core/register_core_types.cpp17
-rw-r--r--core/resource.cpp108
-rw-r--r--core/resource.h11
-rw-r--r--core/rid.h11
-rw-r--r--core/rid_owner.h27
-rw-r--r--core/ring_buffer.h70
-rw-r--r--core/safe_refcount.cpp40
-rw-r--r--core/safe_refcount.h32
-rw-r--r--core/script_language.cpp100
-rw-r--r--core/script_language.h14
-rw-r--r--core/self_list.h33
-rw-r--r--core/set.h196
-rw-r--r--core/simple_type.h3
-rw-r--r--core/sort_array.h94
-rw-r--r--core/spin_lock.h1
-rw-r--r--core/string_buffer.h10
-rw-r--r--core/string_builder.cpp10
-rw-r--r--core/string_builder.h8
-rw-r--r--core/string_name.cpp78
-rw-r--r--core/string_name.h53
-rw-r--r--core/thread_work_pool.cpp4
-rw-r--r--core/thread_work_pool.h5
-rw-r--r--core/translation.cpp72
-rw-r--r--core/translation.h10
-rw-r--r--core/type_info.h7
-rw-r--r--core/typed_array.h227
-rw-r--r--core/typedefs.h3
-rw-r--r--core/ucaps.h2
-rw-r--r--core/undo_redo.cpp129
-rw-r--r--core/undo_redo.h28
-rw-r--r--core/ustring.cpp1158
-rw-r--r--core/ustring.h31
-rw-r--r--core/variant.cpp1192
-rw-r--r--core/variant.h30
-rw-r--r--core/variant_call.cpp461
-rw-r--r--core/variant_op.cpp847
-rw-r--r--core/variant_parser.cpp409
-rw-r--r--core/variant_parser.h19
-rw-r--r--core/vector.h36
-rw-r--r--core/vmap.h36
-rw-r--r--core/vset.h27
-rw-r--r--doc/classes/@GlobalScope.xml324
-rw-r--r--doc/classes/AnimatedTexture.xml9
-rw-r--r--doc/classes/Area2D.xml4
-rw-r--r--doc/classes/Area3D.xml4
-rw-r--r--doc/classes/Array.xml2
-rw-r--r--doc/classes/ArrayMesh.xml3
-rw-r--r--doc/classes/AudioStreamPlayer.xml2
-rw-r--r--doc/classes/AudioStreamPlayer2D.xml2
-rw-r--r--doc/classes/AudioStreamPlayer3D.xml2
-rw-r--r--doc/classes/BackBufferCopy.xml1
-rw-r--r--doc/classes/BakedLightmap.xml81
-rw-r--r--doc/classes/BakedLightmapData.xml65
-rw-r--r--doc/classes/BaseMaterial3D.xml80
-rw-r--r--doc/classes/CPUParticles2D.xml1
-rw-r--r--doc/classes/Camera3D.xml8
-rw-r--r--doc/classes/CameraEffects.xml12
-rw-r--r--doc/classes/CanvasItem.xml8
-rw-r--r--doc/classes/Color.xml40
-rw-r--r--doc/classes/Control.xml4
-rw-r--r--doc/classes/Cubemap.xml2
-rw-r--r--doc/classes/CubemapArray.xml2
-rw-r--r--doc/classes/Decal.xml111
-rw-r--r--doc/classes/Dictionary.xml1
-rw-r--r--doc/classes/DirectionalLight3D.xml9
-rw-r--r--doc/classes/DisplayServer.xml4
-rw-r--r--doc/classes/DynamicFont.xml2
-rw-r--r--doc/classes/EditorFeatureProfile.xml2
-rw-r--r--doc/classes/EditorFileSystem.xml1
-rw-r--r--doc/classes/EditorInspector.xml7
-rw-r--r--doc/classes/EditorInterface.xml1
-rw-r--r--doc/classes/EditorProperty.xml8
-rw-r--r--doc/classes/EditorResourcePreview.xml1
-rw-r--r--doc/classes/EditorScript.xml2
-rw-r--r--doc/classes/EditorSelection.xml3
-rw-r--r--doc/classes/EditorSettings.xml1
-rw-r--r--doc/classes/Engine.xml4
-rw-r--r--doc/classes/Environment.xml10
-rw-r--r--doc/classes/GIProbe.xml2
-rw-r--r--doc/classes/GPUParticles2D.xml1
-rw-r--r--doc/classes/Generic6DOFJoint3D.xml12
-rw-r--r--doc/classes/GeometryInstance3D.xml42
-rw-r--r--doc/classes/GraphEdit.xml10
-rw-r--r--doc/classes/HSlider.xml2
-rw-r--r--doc/classes/IP_Unix.xml15
-rw-r--r--doc/classes/Image.xml9
-rw-r--r--doc/classes/ImageTextureLayered.xml31
-rw-r--r--doc/classes/ImmediateGeometry3D.xml3
-rw-r--r--doc/classes/Input.xml (renamed from doc/classes/InputFilter.xml)26
-rw-r--r--doc/classes/InputEventJoypadButton.xml2
-rw-r--r--doc/classes/InputEventJoypadMotion.xml2
-rw-r--r--doc/classes/InputEventKey.xml4
-rw-r--r--doc/classes/InputEventWithModifiers.xml12
-rw-r--r--doc/classes/ItemList.xml8
-rw-r--r--doc/classes/JNISingleton.xml (renamed from doc/classes/MonoGCHandle.xml)2
-rw-r--r--doc/classes/KinematicBody3D.xml18
-rw-r--r--doc/classes/Light3D.xml40
-rw-r--r--doc/classes/LightmapProbe.xml (renamed from modules/bullet/doc_classes/BulletPhysicsServer3D.xml)2
-rw-r--r--doc/classes/Lightmapper.xml (renamed from doc/classes/ResourceFormatSaverCrypto.xml)2
-rw-r--r--doc/classes/LightmapperRD.xml (renamed from doc/classes/ResourceFormatLoaderCrypto.xml)2
-rw-r--r--doc/classes/Line2D.xml2
-rw-r--r--doc/classes/LineEdit.xml40
-rw-r--r--doc/classes/LineShape2D.xml2
-rw-r--r--doc/classes/Mesh.xml2
-rw-r--r--doc/classes/MeshDataTool.xml2
-rw-r--r--doc/classes/MeshInstance2D.xml1
-rw-r--r--doc/classes/MultiMeshInstance2D.xml1
-rw-r--r--doc/classes/Node.xml18
-rw-r--r--doc/classes/Node2D.xml8
-rw-r--r--doc/classes/Node3D.xml2
-rw-r--r--doc/classes/OS.xml22
-rw-r--r--doc/classes/Object.xml2
-rw-r--r--doc/classes/PackedScene.xml12
-rw-r--r--doc/classes/Path2D.xml1
-rw-r--r--doc/classes/PhysicalBone3D.xml20
-rw-r--r--doc/classes/PhysicalSkyMaterial.xml3
-rw-r--r--doc/classes/PhysicsBody2D.xml2
-rw-r--r--doc/classes/PhysicsBody3D.xml2
-rw-r--r--doc/classes/PhysicsDirectBodyState2DSW.xml15
-rw-r--r--doc/classes/PhysicsServer2DSW.xml15
-rw-r--r--doc/classes/Polygon2D.xml2
-rw-r--r--doc/classes/PopupMenu.xml8
-rw-r--r--doc/classes/ProjectSettings.xml139
-rw-r--r--doc/classes/RDAttachmentFormat.xml21
-rw-r--r--doc/classes/RDPipelineColorBlendState.xml23
-rw-r--r--doc/classes/RDPipelineColorBlendStateAttachment.xml43
-rw-r--r--doc/classes/RDPipelineDepthStencilState.xml57
-rw-r--r--doc/classes/RDPipelineMultisampleState.xml27
-rw-r--r--doc/classes/RDPipelineRasterizationState.xml37
-rw-r--r--doc/classes/RDSamplerState.xml45
-rw-r--r--doc/classes/RDShaderBytecode.xml71
-rw-r--r--doc/classes/RDShaderFile.xml41
-rw-r--r--doc/classes/RDShaderSource.xml45
-rw-r--r--doc/classes/RDTextureFormat.xml49
-rw-r--r--doc/classes/RDTextureView.xml25
-rw-r--r--doc/classes/RDUniform.xml39
-rw-r--r--doc/classes/RDVertexAttribute.xml25
-rw-r--r--doc/classes/RenderingDevice.xml1586
-rw-r--r--doc/classes/RenderingServer.xml399
-rw-r--r--doc/classes/ResourceFormatLoader.xml2
-rw-r--r--doc/classes/RigidBody2D.xml2
-rw-r--r--doc/classes/ScriptEditor.xml1
-rw-r--r--doc/classes/ShaderGlobalsOverride.xml13
-rw-r--r--doc/classes/Skeleton3D.xml2
-rw-r--r--doc/classes/Sky.xml2
-rw-r--r--doc/classes/SpinBox.xml2
-rw-r--r--doc/classes/Sprite2D.xml1
-rw-r--r--doc/classes/StreamCubemap.xml13
-rw-r--r--doc/classes/StreamCubemapArray.xml13
-rw-r--r--doc/classes/StreamTexture2D.xml (renamed from doc/classes/StreamTexture.xml)2
-rw-r--r--doc/classes/StreamTexture2DArray.xml13
-rw-r--r--doc/classes/StreamTextureLayered.xml25
-rw-r--r--doc/classes/String.xml13
-rw-r--r--doc/classes/StyleBoxTexture.xml1
-rw-r--r--doc/classes/SubViewport.xml24
-rw-r--r--doc/classes/SurfaceTool.xml2
-rw-r--r--doc/classes/TabContainer.xml4
-rw-r--r--doc/classes/TextEdit.xml29
-rw-r--r--doc/classes/Texture2DArray.xml2
-rw-r--r--doc/classes/TextureLayered.xml28
-rw-r--r--doc/classes/TileMap.xml12
-rw-r--r--doc/classes/TileSet.xml1
-rw-r--r--doc/classes/Transform.xml2
-rw-r--r--doc/classes/Tree.xml2
-rw-r--r--doc/classes/TreeItem.xml21
-rw-r--r--doc/classes/Tween.xml5
-rw-r--r--doc/classes/VSlider.xml2
-rw-r--r--doc/classes/Vector2.xml2
-rw-r--r--doc/classes/Vector3.xml4
-rw-r--r--doc/classes/Viewport.xml93
-rw-r--r--doc/classes/VisibilityEnabler2D.xml5
-rw-r--r--doc/classes/VisibilityEnabler3D.xml5
-rw-r--r--doc/classes/VisibilityNotifier2D.xml3
-rw-r--r--doc/classes/VisibilityNotifier3D.xml3
-rw-r--r--doc/classes/VisualShaderNodeInput.xml4
-rw-r--r--doc/classes/VisualShaderNodeIs.xml5
-rw-r--r--doc/classes/VisualShaderNodeOuterProduct.xml2
-rw-r--r--doc/classes/VisualShaderNodeOutput.xml2
-rw-r--r--doc/classes/VisualShaderNodeScalarClamp.xml2
-rw-r--r--doc/classes/VisualShaderNodeScalarDerivativeFunc.xml6
-rw-r--r--doc/classes/VisualShaderNodeScalarInterp.xml2
-rw-r--r--doc/classes/VisualShaderNodeScalarSmoothStep.xml3
-rw-r--r--doc/classes/VisualShaderNodeScalarSwitch.xml2
-rw-r--r--doc/classes/VisualShaderNodeSwitch.xml2
-rw-r--r--doc/classes/VisualShaderNodeTexture.xml14
-rw-r--r--doc/classes/VisualShaderNodeTextureUniform.xml10
-rw-r--r--doc/classes/VisualShaderNodeTextureUniformTriplanar.xml2
-rw-r--r--doc/classes/VisualShaderNodeTransformCompose.xml2
-rw-r--r--doc/classes/VisualShaderNodeTransformConstant.xml3
-rw-r--r--doc/classes/VisualShaderNodeTransformDecompose.xml2
-rw-r--r--doc/classes/VisualShaderNodeTransformFunc.xml5
-rw-r--r--doc/classes/VisualShaderNodeTransformMult.xml7
-rw-r--r--doc/classes/VisualShaderNodeTransformUniform.xml2
-rw-r--r--doc/classes/VisualShaderNodeTransformVecMult.xml7
-rw-r--r--doc/classes/VisualShaderNodeUniform.xml11
-rw-r--r--doc/classes/VisualShaderNodeVec3Constant.xml3
-rw-r--r--doc/classes/VisualShaderNodeVec3Uniform.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorClamp.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorCompose.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorDecompose.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorDerivativeFunc.xml6
-rw-r--r--doc/classes/VisualShaderNodeVectorDistance.xml3
-rw-r--r--doc/classes/VisualShaderNodeVectorFunc.xml38
-rw-r--r--doc/classes/VisualShaderNodeVectorInterp.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorLen.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorOp.xml15
-rw-r--r--doc/classes/VisualShaderNodeVectorRefract.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorScalarMix.xml2
-rw-r--r--doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml3
-rw-r--r--doc/classes/VisualShaderNodeVectorScalarStep.xml3
-rw-r--r--doc/classes/VisualShaderNodeVectorSmoothStep.xml3
-rw-r--r--doc/classes/World2D.xml2
-rw-r--r--doc/classes/World3D.xml2
-rw-r--r--doc/classes/XRController3D.xml2
-rwxr-xr-xdoc/tools/makerst.py19
-rw-r--r--doc/translations/classes.pot7389
-rw-r--r--doc/translations/fr.po7395
-rw-r--r--drivers/alsa/audio_driver_alsa.cpp44
-rw-r--r--drivers/alsa/audio_driver_alsa.h13
-rw-r--r--drivers/alsamidi/midi_driver_alsamidi.cpp13
-rw-r--r--drivers/alsamidi/midi_driver_alsamidi.h1
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.cpp36
-rw-r--r--drivers/coreaudio/audio_driver_coreaudio.h21
-rw-r--r--drivers/coremidi/midi_driver_coremidi.cpp8
-rw-r--r--drivers/coremidi/midi_driver_coremidi.h3
-rw-r--r--drivers/dummy/rasterizer_dummy.h108
-rw-r--r--drivers/dummy/texture_loader_dummy.cpp32
-rw-r--r--drivers/dummy/texture_loader_dummy.h2
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp71
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.h1
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp21
-rw-r--r--drivers/gles2/rasterizer_gles2.h1
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp121
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.h6
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp260
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h26
-rw-r--r--drivers/gles2/shader_compiler_gles2.cpp89
-rw-r--r--drivers/gles2/shader_compiler_gles2.h3
-rw-r--r--drivers/gles2/shader_gles2.cpp24
-rw-r--r--drivers/gles2/shader_gles2.h10
-rw-r--r--drivers/gles2/shaders/blend_shape.glsl2
-rw-r--r--drivers/gles2/shaders/canvas.glsl5
-rw-r--r--drivers/gles2/shaders/canvas_shadow.glsl2
-rw-r--r--drivers/gles2/shaders/copy.glsl3
-rw-r--r--drivers/gles2/shaders/cube_to_dp.glsl2
-rw-r--r--drivers/gles2/shaders/cubemap_filter.glsl4
-rw-r--r--drivers/gles2/shaders/effect_blur.glsl4
-rw-r--r--drivers/gles2/shaders/exposure.glsl2
-rw-r--r--drivers/gles2/shaders/lens_distorted.glsl1
-rw-r--r--drivers/gles2/shaders/particles.glsl7
-rw-r--r--drivers/gles2/shaders/resolve.glsl2
-rw-r--r--drivers/gles2/shaders/scene.glsl26
-rw-r--r--drivers/gles2/shaders/screen_space_reflection.glsl5
-rw-r--r--drivers/gles2/shaders/ssao.glsl2
-rw-r--r--drivers/gles2/shaders/ssao_blur.glsl3
-rw-r--r--drivers/gles2/shaders/ssao_minify.glsl2
-rw-r--r--drivers/gles2/shaders/subsurf_scattering.glsl3
-rw-r--r--drivers/png/image_loader_png.cpp6
-rw-r--r--drivers/png/png_driver_common.cpp8
-rw-r--r--drivers/png/resource_saver_png.cpp6
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.cpp62
-rw-r--r--drivers/pulseaudio/audio_driver_pulseaudio.h37
-rw-r--r--drivers/register_driver_types.cpp5
-rw-r--r--drivers/unix/dir_access_unix.cpp73
-rw-r--r--drivers/unix/dir_access_unix.h1
-rw-r--r--drivers/unix/file_access_unix.cpp59
-rw-r--r--drivers/unix/file_access_unix.h9
-rw-r--r--drivers/unix/ip_unix.cpp23
-rw-r--r--drivers/unix/net_socket_posix.cpp67
-rw-r--r--drivers/unix/net_socket_posix.h7
-rw-r--r--drivers/unix/os_unix.cpp80
-rw-r--r--drivers/unix/os_unix.h1
-rw-r--r--drivers/unix/rw_lock_posix.cpp9
-rw-r--r--drivers/unix/rw_lock_posix.h1
-rw-r--r--drivers/unix/syslog_logger.cpp25
-rw-r--r--drivers/unix/thread_posix.cpp14
-rw-r--r--drivers/unix/thread_posix.h1
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp497
-rw-r--r--drivers/vulkan/rendering_device_vulkan.h33
-rw-r--r--drivers/vulkan/vulkan_context.cpp96
-rw-r--r--drivers/vulkan/vulkan_context.h2
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp49
-rw-r--r--drivers/wasapi/audio_driver_wasapi.h52
-rw-r--r--drivers/windows/dir_access_windows.cpp29
-rw-r--r--drivers/windows/dir_access_windows.h1
-rw-r--r--drivers/windows/file_access_windows.cpp38
-rw-r--r--drivers/windows/file_access_windows.h16
-rw-r--r--drivers/windows/rw_lock_windows.cpp8
-rw-r--r--drivers/windows/rw_lock_windows.h1
-rw-r--r--drivers/windows/thread_windows.cpp16
-rw-r--r--drivers/windows/thread_windows.h7
-rw-r--r--drivers/winmidi/midi_driver_winmidi.cpp5
-rw-r--r--drivers/winmidi/midi_driver_winmidi.h1
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.cpp26
-rw-r--r--drivers/xaudio2/audio_driver_xaudio2.h10
-rw-r--r--editor/animation_bezier_editor.cpp124
-rw-r--r--editor/animation_bezier_editor.h2
-rw-r--r--editor/animation_track_editor.cpp738
-rw-r--r--editor/animation_track_editor.h4
-rw-r--r--editor/animation_track_editor_plugins.cpp160
-rw-r--r--editor/array_property_edit.cpp40
-rw-r--r--editor/array_property_edit.h1
-rw-r--r--editor/audio_stream_preview.cpp18
-rw-r--r--editor/code_editor.cpp181
-rw-r--r--editor/code_editor.h3
-rw-r--r--editor/connections_dialog.cpp187
-rw-r--r--editor/connections_dialog.h3
-rw-r--r--editor/create_dialog.cpp135
-rw-r--r--editor/create_dialog.h1
-rw-r--r--editor/debugger/editor_debugger_inspector.cpp23
-rw-r--r--editor/debugger/editor_debugger_inspector.h4
-rw-r--r--editor/debugger/editor_debugger_node.cpp94
-rw-r--r--editor/debugger/editor_debugger_node.h8
-rw-r--r--editor/debugger/editor_debugger_server.cpp28
-rw-r--r--editor/debugger/editor_debugger_server.h11
-rw-r--r--editor/debugger/editor_debugger_tree.cpp26
-rw-r--r--editor/debugger/editor_debugger_tree.h1
-rw-r--r--editor/debugger/editor_network_profiler.cpp7
-rw-r--r--editor/debugger/editor_network_profiler.h1
-rw-r--r--editor/debugger/editor_profiler.cpp92
-rw-r--r--editor/debugger/editor_profiler.h4
-rw-r--r--editor/debugger/editor_visual_profiler.cpp72
-rw-r--r--editor/debugger/editor_visual_profiler.h2
-rw-r--r--editor/debugger/script_editor_debugger.cpp340
-rw-r--r--editor/debugger/script_editor_debugger.h8
-rw-r--r--editor/dependency_editor.cpp87
-rw-r--r--editor/dictionary_property_edit.cpp24
-rw-r--r--editor/doc_data.cpp310
-rw-r--r--editor/doc_data.h23
-rw-r--r--editor/editor_about.cpp14
-rw-r--r--editor/editor_about.h1
-rw-r--r--editor/editor_asset_installer.cpp28
-rw-r--r--editor/editor_asset_installer.h1
-rw-r--r--editor/editor_atlas_packer.cpp24
-rw-r--r--editor/editor_audio_buses.cpp153
-rw-r--r--editor/editor_audio_buses.h12
-rw-r--r--editor/editor_autoload_settings.cpp100
-rw-r--r--editor/editor_autoload_settings.h1
-rw-r--r--editor/editor_data.cpp285
-rw-r--r--editor/editor_data.h13
-rw-r--r--editor/editor_dir_dialog.cpp25
-rw-r--r--editor/editor_export.cpp255
-rw-r--r--editor/editor_export.h21
-rw-r--r--editor/editor_feature_profile.cpp45
-rw-r--r--editor/editor_feature_profile.h1
-rw-r--r--editor/editor_file_dialog.cpp247
-rw-r--r--editor/editor_file_dialog.h1
-rw-r--r--editor/editor_file_system.cpp273
-rw-r--r--editor/editor_file_system.h5
-rw-r--r--editor/editor_folding.cpp17
-rw-r--r--editor/editor_folding.h1
-rw-r--r--editor/editor_fonts.cpp2
-rw-r--r--editor/editor_help.cpp306
-rw-r--r--editor/editor_help.h2
-rw-r--r--editor/editor_help_search.cpp187
-rw-r--r--editor/editor_help_search.h3
-rw-r--r--editor/editor_inspector.cpp353
-rw-r--r--editor/editor_inspector.h1
-rw-r--r--editor/editor_layouts_dialog.cpp19
-rw-r--r--editor/editor_layouts_dialog.h1
-rw-r--r--editor/editor_log.cpp18
-rw-r--r--editor/editor_log.h1
-rw-r--r--editor/editor_node.cpp849
-rw-r--r--editor/editor_node.h16
-rw-r--r--editor/editor_path.cpp53
-rw-r--r--editor/editor_path.h1
-rw-r--r--editor/editor_plugin.cpp99
-rw-r--r--editor/editor_plugin.h13
-rw-r--r--editor/editor_plugin_settings.cpp13
-rw-r--r--editor/editor_plugin_settings.h1
-rw-r--r--editor/editor_properties.cpp323
-rw-r--r--editor/editor_properties_array_dict.cpp166
-rw-r--r--editor/editor_properties_array_dict.h9
-rw-r--r--editor/editor_resource_preview.cpp43
-rw-r--r--editor/editor_resource_preview.h2
-rw-r--r--editor/editor_run.cpp17
-rw-r--r--editor/editor_run_native.cpp30
-rw-r--r--editor/editor_run_native.h1
-rw-r--r--editor/editor_run_script.cpp8
-rw-r--r--editor/editor_run_script.h1
-rw-r--r--editor/editor_scale.cpp3
-rw-r--r--editor/editor_sectioned_inspector.cpp80
-rw-r--r--editor/editor_sectioned_inspector.h3
-rw-r--r--editor/editor_settings.cpp146
-rw-r--r--editor/editor_settings.h33
-rw-r--r--editor/editor_spin_slider.cpp72
-rw-r--r--editor/editor_sub_scene.cpp31
-rw-r--r--editor/editor_sub_scene.h1
-rw-r--r--editor/editor_themes.cpp53
-rw-r--r--editor/editor_vcs_interface.cpp26
-rw-r--r--editor/editor_vcs_interface.h1
-rw-r--r--editor/export_template_manager.cpp44
-rw-r--r--editor/fileserver/editor_file_server.cpp19
-rw-r--r--editor/fileserver/editor_file_server.h2
-rw-r--r--editor/filesystem_dock.cpp123
-rw-r--r--editor/filesystem_dock.h6
-rw-r--r--editor/find_in_files.cpp68
-rw-r--r--editor/groups_editor.cpp34
-rw-r--r--editor/groups_editor.h2
-rw-r--r--editor/icons/CameraEffects.svg1
-rw-r--r--editor/icons/Cubemap.svg (renamed from editor/icons/CubeMap.svg)0
-rw-r--r--editor/icons/CubemapArray.svg1
-rw-r--r--editor/icons/Decal.svg1
-rw-r--r--editor/icons/ErrorWarning.svg1
-rw-r--r--editor/icons/LightmapProbe.svg1
-rw-r--r--editor/icons/PanoramaSky.svg1
-rw-r--r--editor/icons/PanoramaSkyMaterial.svg1
-rw-r--r--editor/icons/PhysicalSkyMaterial.svg1
-rw-r--r--editor/icons/ProceduralSky.svg1
-rw-r--r--editor/icons/ProceduralSkyMaterial.svg1
-rw-r--r--editor/icons/README.md15
-rw-r--r--editor/icons/RootMotionView.svg1
-rw-r--r--editor/icons/ShaderGlobalsOverride.svg1
-rw-r--r--editor/import/collada.cpp611
-rw-r--r--editor/import/collada.h237
-rw-r--r--editor/import/editor_import_collada.cpp306
-rw-r--r--editor/import/editor_import_collada.h1
-rw-r--r--editor/import/editor_import_plugin.cpp3
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp302
-rw-r--r--editor/import/editor_scene_importer_gltf.h130
-rw-r--r--editor/import/resource_importer_bitmask.cpp15
-rw-r--r--editor/import/resource_importer_csv.cpp8
-rw-r--r--editor/import/resource_importer_csv_translation.cpp25
-rw-r--r--editor/import/resource_importer_image.cpp9
-rw-r--r--editor/import/resource_importer_layered_texture.cpp343
-rw-r--r--editor/import/resource_importer_layered_texture.h34
-rw-r--r--editor/import/resource_importer_obj.cpp41
-rw-r--r--editor/import/resource_importer_obj.h1
-rw-r--r--editor/import/resource_importer_scene.cpp420
-rw-r--r--editor/import/resource_importer_scene.h2
-rw-r--r--editor/import/resource_importer_shader_file.cpp118
-rw-r--r--editor/import/resource_importer_shader_file.h57
-rw-r--r--editor/import/resource_importer_texture.cpp162
-rw-r--r--editor/import/resource_importer_texture.h13
-rw-r--r--editor/import/resource_importer_texture_atlas.cpp25
-rw-r--r--editor/import/resource_importer_wav.cpp37
-rw-r--r--editor/import/resource_importer_wav.h20
-rw-r--r--editor/import_dock.cpp45
-rw-r--r--editor/inspector_dock.cpp45
-rw-r--r--editor/inspector_dock.h1
-rw-r--r--editor/multi_node_edit.cpp41
-rw-r--r--editor/multi_node_edit.h1
-rw-r--r--editor/node_3d_editor_gizmos.cpp850
-rw-r--r--editor/node_3d_editor_gizmos.h55
-rw-r--r--editor/node_dock.cpp11
-rw-r--r--editor/node_dock.h1
-rw-r--r--editor/pane_drag.cpp15
-rw-r--r--editor/pane_drag.h1
-rw-r--r--editor/plugin_config_dialog.cpp4
-rw-r--r--editor/plugin_config_dialog.h1
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp181
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.h25
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.cpp30
-rw-r--r--editor/plugins/animation_blend_space_1d_editor.h1
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.cpp59
-rw-r--r--editor/plugins/animation_blend_space_2d_editor.h1
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp63
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.h1
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp280
-rw-r--r--editor/plugins/animation_player_editor_plugin.h3
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp94
-rw-r--r--editor/plugins/animation_state_machine_editor.h1
-rw-r--r--editor/plugins/animation_tree_editor_plugin.cpp28
-rw-r--r--editor/plugins/animation_tree_editor_plugin.h2
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp108
-rw-r--r--editor/plugins/asset_library_editor_plugin.h5
-rw-r--r--editor/plugins/audio_stream_editor_plugin.cpp23
-rw-r--r--editor/plugins/audio_stream_editor_plugin.h2
-rw-r--r--editor/plugins/baked_lightmap_editor_plugin.cpp79
-rw-r--r--editor/plugins/baked_lightmap_editor_plugin.h8
-rw-r--r--editor/plugins/camera_3d_editor_plugin.cpp14
-rw-r--r--editor/plugins/camera_3d_editor_plugin.h2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp523
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h28
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.h2
-rw-r--r--editor/plugins/collision_polygon_3d_editor_plugin.cpp94
-rw-r--r--editor/plugins/collision_polygon_3d_editor_plugin.h2
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp38
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.cpp26
-rw-r--r--editor/plugins/cpu_particles_2d_editor_plugin.h1
-rw-r--r--editor/plugins/cpu_particles_3d_editor_plugin.cpp13
-rw-r--r--editor/plugins/cpu_particles_3d_editor_plugin.h2
-rw-r--r--editor/plugins/curve_editor_plugin.cpp82
-rw-r--r--editor/plugins/debugger_editor_plugin.cpp37
-rw-r--r--editor/plugins/debugger_editor_plugin.h1
-rw-r--r--editor/plugins/editor_preview_plugins.cpp91
-rw-r--r--editor/plugins/editor_preview_plugins.h4
-rw-r--r--editor/plugins/gi_probe_editor_plugin.cpp12
-rw-r--r--editor/plugins/gi_probe_editor_plugin.h1
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.cpp42
-rw-r--r--editor/plugins/gpu_particles_2d_editor_plugin.h1
-rw-r--r--editor/plugins/gpu_particles_3d_editor_plugin.cpp65
-rw-r--r--editor/plugins/gpu_particles_3d_editor_plugin.h3
-rw-r--r--editor/plugins/gradient_editor_plugin.cpp9
-rw-r--r--editor/plugins/gradient_editor_plugin.h1
-rw-r--r--editor/plugins/item_list_editor_plugin.cpp103
-rw-r--r--editor/plugins/item_list_editor_plugin.h6
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.cpp30
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.h2
-rw-r--r--editor/plugins/line_2d_editor_plugin.cpp6
-rw-r--r--editor/plugins/line_2d_editor_plugin.h2
-rw-r--r--editor/plugins/material_editor_plugin.cpp50
-rw-r--r--editor/plugins/material_editor_plugin.h2
-rw-r--r--editor/plugins/mesh_editor_plugin.cpp22
-rw-r--r--editor/plugins/mesh_editor_plugin.h2
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.cpp53
-rw-r--r--editor/plugins/mesh_instance_3d_editor_plugin.h2
-rw-r--r--editor/plugins/mesh_library_editor_plugin.cpp61
-rw-r--r--editor/plugins/mesh_library_editor_plugin.h2
-rw-r--r--editor/plugins/multimesh_editor_plugin.cpp44
-rw-r--r--editor/plugins/multimesh_editor_plugin.h2
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.cpp25
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.h2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp1068
-rw-r--r--editor/plugins/node_3d_editor_plugin.h22
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp90
-rw-r--r--editor/plugins/path_2d_editor_plugin.h2
-rw-r--r--editor/plugins/path_3d_editor_plugin.cpp112
-rw-r--r--editor/plugins/path_3d_editor_plugin.h3
-rw-r--r--editor/plugins/physical_bone_3d_editor_plugin.cpp11
-rw-r--r--editor/plugins/physical_bone_3d_editor_plugin.h6
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp167
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.h2
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp66
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.h2
-rw-r--r--editor/plugins/root_motion_editor_plugin.cpp18
-rw-r--r--editor/plugins/script_editor_plugin.cpp434
-rw-r--r--editor/plugins/script_editor_plugin.h5
-rw-r--r--editor/plugins/script_text_editor.cpp266
-rw-r--r--editor/plugins/script_text_editor.h4
-rw-r--r--editor/plugins/shader_editor_plugin.cpp77
-rw-r--r--editor/plugins/shader_editor_plugin.h3
-rw-r--r--editor/plugins/shader_file_editor_plugin.cpp324
-rw-r--r--editor/plugins/shader_file_editor_plugin.h92
-rw-r--r--editor/plugins/skeleton_2d_editor_plugin.cpp10
-rw-r--r--editor/plugins/skeleton_2d_editor_plugin.h2
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp9
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.h6
-rw-r--r--editor/plugins/skeleton_ik_3d_editor_plugin.cpp19
-rw-r--r--editor/plugins/skeleton_ik_3d_editor_plugin.h1
-rw-r--r--editor/plugins/sprite_2d_editor_plugin.cpp53
-rw-r--r--editor/plugins/sprite_2d_editor_plugin.h2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp171
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.h2
-rw-r--r--editor/plugins/style_box_editor_plugin.cpp10
-rw-r--r--editor/plugins/style_box_editor_plugin.h2
-rw-r--r--editor/plugins/text_editor.cpp64
-rw-r--r--editor/plugins/text_editor.h1
-rw-r--r--editor/plugins/texture_editor_plugin.cpp32
-rw-r--r--editor/plugins/texture_editor_plugin.h2
-rw-r--r--editor/plugins/texture_layered_editor_plugin.cpp278
-rw-r--r--editor/plugins/texture_layered_editor_plugin.h95
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp214
-rw-r--r--editor/plugins/texture_region_editor_plugin.h1
-rw-r--r--editor/plugins/theme_editor_plugin.cpp127
-rw-r--r--editor/plugins/theme_editor_plugin.h2
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp368
-rw-r--r--editor/plugins/tile_map_editor_plugin.h31
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp270
-rw-r--r--editor/plugins/tile_set_editor_plugin.h3
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp58
-rw-r--r--editor/plugins/version_control_editor_plugin.h1
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp228
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h5
-rw-r--r--editor/progress_dialog.cpp37
-rw-r--r--editor/progress_dialog.h4
-rw-r--r--editor/project_export.cpp193
-rw-r--r--editor/project_export.h1
-rw-r--r--editor/project_manager.cpp200
-rw-r--r--editor/project_manager.h2
-rw-r--r--editor/project_settings_editor.cpp351
-rw-r--r--editor/project_settings_editor.h1
-rw-r--r--editor/property_editor.cpp319
-rw-r--r--editor/property_editor.h2
-rw-r--r--editor/property_selector.cpp95
-rw-r--r--editor/pvrtc_compress.cpp13
-rw-r--r--editor/quick_open.cpp61
-rw-r--r--editor/quick_open.h1
-rw-r--r--editor/rename_dialog.cpp30
-rw-r--r--editor/rename_dialog.h5
-rw-r--r--editor/reparent_dialog.cpp10
-rw-r--r--editor/reparent_dialog.h1
-rw-r--r--editor/run_settings_dialog.cpp14
-rw-r--r--editor/run_settings_dialog.h1
-rw-r--r--editor/scene_tree_dock.cpp547
-rw-r--r--editor/scene_tree_dock.h5
-rw-r--r--editor/scene_tree_editor.cpp273
-rw-r--r--editor/scene_tree_editor.h2
-rw-r--r--editor/script_create_dialog.cpp75
-rw-r--r--editor/settings_config_dialog.cpp52
-rw-r--r--editor/settings_config_dialog.h1
-rw-r--r--editor/shader_globals_editor.cpp37
-rw-r--r--editor/shader_globals_editor.h31
-rw-r--r--editor/translations/af.po11
-rw-r--r--editor/translations/ar.po2946
-rw-r--r--editor/translations/bg.po13
-rw-r--r--editor/translations/bn.po21
-rw-r--r--editor/translations/ca.po12
-rw-r--r--editor/translations/cs.po12
-rw-r--r--editor/translations/da.po12
-rw-r--r--editor/translations/de.po37
-rw-r--r--editor/translations/de_CH.po13
-rw-r--r--editor/translations/editor.pot11
-rw-r--r--editor/translations/el.po31
-rw-r--r--editor/translations/eo.po38
-rw-r--r--editor/translations/es.po130
-rw-r--r--editor/translations/es_AR.po38
-rw-r--r--editor/translations/et.po11
-rw-r--r--editor/translations/eu.po11
-rw-r--r--editor/translations/fa.po30
-rw-r--r--editor/translations/fi.po41
-rw-r--r--editor/translations/fil.po11
-rw-r--r--editor/translations/fr.po112
-rw-r--r--editor/translations/ga.po11
-rw-r--r--editor/translations/he.po62
-rw-r--r--editor/translations/hi.po79
-rw-r--r--editor/translations/hr.po11
-rw-r--r--editor/translations/hu.po13
-rw-r--r--editor/translations/id.po12
-rw-r--r--editor/translations/is.po11
-rw-r--r--editor/translations/it.po42
-rw-r--r--editor/translations/ja.po234
-rw-r--r--editor/translations/ka.po11
-rw-r--r--editor/translations/ko.po36
-rw-r--r--editor/translations/lt.po12
-rw-r--r--editor/translations/lv.po11
-rw-r--r--editor/translations/mi.po11
-rw-r--r--editor/translations/ml.po11
-rw-r--r--editor/translations/mr.po31
-rw-r--r--editor/translations/ms.po11
-rw-r--r--editor/translations/nb.po12
-rw-r--r--editor/translations/nl.po125
-rw-r--r--editor/translations/or.po11
-rw-r--r--editor/translations/pl.po36
-rw-r--r--editor/translations/pr.po11
-rw-r--r--editor/translations/pt_BR.po109
-rw-r--r--editor/translations/pt_PT.po99
-rw-r--r--editor/translations/ro.po12
-rw-r--r--editor/translations/ru.po54
-rw-r--r--editor/translations/si.po11
-rw-r--r--editor/translations/sk.po653
-rw-r--r--editor/translations/sl.po12
-rw-r--r--editor/translations/sq.po12
-rw-r--r--editor/translations/sr_Cyrl.po12
-rw-r--r--editor/translations/sr_Latn.po11
-rw-r--r--editor/translations/sv.po12
-rw-r--r--editor/translations/ta.po11
-rw-r--r--editor/translations/te.po11
-rw-r--r--editor/translations/th.po13
-rw-r--r--editor/translations/tr.po80
-rw-r--r--editor/translations/uk.po31
-rw-r--r--editor/translations/ur_PK.po11
-rw-r--r--editor/translations/vi.po12
-rw-r--r--editor/translations/zh_CN.po37
-rw-r--r--editor/translations/zh_HK.po599
-rw-r--r--editor/translations/zh_TW.po12
-rw-r--r--gles_builders.py74
-rw-r--r--main/main.cpp320
-rw-r--r--main/main.h1
-rw-r--r--main/main_timer_sync.cpp26
-rw-r--r--main/main_timer_sync.h10
-rw-r--r--main/performance.cpp90
-rw-r--r--main/performance.h1
-rw-r--r--main/tests/test_astar.cpp87
-rw-r--r--main/tests/test_class_db.cpp882
-rw-r--r--main/tests/test_class_db.h (renamed from core/path_remap.h)16
-rw-r--r--main/tests/test_gdscript.cpp201
-rw-r--r--main/tests/test_gui.cpp5
-rw-r--r--main/tests/test_main.cpp24
-rw-r--r--main/tests/test_math.cpp107
-rw-r--r--main/tests/test_oa_hash_map.cpp67
-rw-r--r--main/tests/test_ordered_hash_map.cpp10
-rw-r--r--main/tests/test_physics_2d.cpp35
-rw-r--r--main/tests/test_physics_3d.cpp28
-rw-r--r--main/tests/test_render.cpp12
-rw-r--r--main/tests/test_shader_lang.cpp102
-rw-r--r--main/tests/test_string.cpp132
-rw-r--r--misc/dist/html/fixed-size.html5
-rw-r--r--misc/dist/html/full-size.html7
-rw-r--r--misc/dist/linux/org.godotengine.Godot.desktop1
-rwxr-xr-xmisc/hooks/pre-commit-black84
-rwxr-xr-xmisc/hooks/pre-commit-clang-format84
-rwxr-xr-xmisc/hooks/winmessage.ps1103
-rw-r--r--misc/scons/compilation_db.py177
-rw-r--r--modules/arkit/arkit_interface.mm2
-rw-r--r--modules/assimp/editor_scene_importer_assimp.cpp29
-rw-r--r--modules/assimp/import_state.h1
-rw-r--r--modules/assimp/import_utils.h44
-rw-r--r--modules/assimp/register_types.cpp1
-rw-r--r--modules/basis_universal/register_types.cpp8
-rw-r--r--modules/bmp/image_loader_bmp.cpp11
-rw-r--r--modules/bullet/SCsub3
-rw-r--r--modules/bullet/area_bullet.cpp33
-rw-r--r--modules/bullet/area_bullet.h34
-rw-r--r--modules/bullet/btRayShape.cpp8
-rw-r--r--modules/bullet/btRayShape.h1
-rw-r--r--modules/bullet/bullet_physics_server.cpp49
-rw-r--r--modules/bullet/bullet_physics_server.h5
-rw-r--r--modules/bullet/collision_object_bullet.cpp43
-rw-r--r--modules/bullet/collision_object_bullet.h38
-rw-r--r--modules/bullet/cone_twist_joint_bullet.cpp2
-rw-r--r--modules/bullet/config.py11
-rw-r--r--modules/bullet/constraint_bullet.cpp5
-rw-r--r--modules/bullet/constraint_bullet.h7
-rw-r--r--modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml13
-rw-r--r--modules/bullet/generic_6dof_joint_bullet.cpp1
-rw-r--r--modules/bullet/godot_collision_configuration.cpp22
-rw-r--r--modules/bullet/godot_motion_state.h1
-rw-r--r--modules/bullet/godot_ray_world_algorithm.cpp12
-rw-r--r--modules/bullet/godot_ray_world_algorithm.h8
-rw-r--r--modules/bullet/godot_result_callbacks.cpp67
-rw-r--r--modules/bullet/godot_result_callbacks.h39
-rw-r--r--modules/bullet/hinge_joint_bullet.cpp8
-rw-r--r--modules/bullet/joint_bullet.h1
-rw-r--r--modules/bullet/pin_joint_bullet.cpp1
-rw-r--r--modules/bullet/rigid_body_bullet.cpp145
-rw-r--r--modules/bullet/rigid_body_bullet.h43
-rw-r--r--modules/bullet/shape_bullet.cpp34
-rw-r--r--modules/bullet/shape_bullet.h17
-rw-r--r--modules/bullet/slider_joint_bullet.cpp160
-rw-r--r--modules/bullet/soft_body_bullet.cpp42
-rw-r--r--modules/bullet/soft_body_bullet.h23
-rw-r--r--modules/bullet/space_bullet.cpp100
-rw-r--r--modules/bullet/space_bullet.h60
-rw-r--r--modules/camera/camera_win.cpp16
-rw-r--r--modules/camera/camera_win.h2
-rw-r--r--modules/csg/csg.cpp259
-rw-r--r--modules/csg/csg.h4
-rw-r--r--modules/csg/csg_gizmos.cpp99
-rw-r--r--modules/csg/csg_gizmos.h1
-rw-r--r--modules/csg/csg_shape.cpp271
-rw-r--r--modules/csg/csg_shape.h5
-rw-r--r--modules/csg/register_types.cpp1
-rw-r--r--modules/cvtt/image_compress_cvtt.cpp18
-rw-r--r--modules/cvtt/register_types.cpp1
-rw-r--r--modules/dds/register_types.cpp2
-rw-r--r--modules/dds/texture_loader_dds.cpp80
-rw-r--r--modules/dds/texture_loader_dds.h2
-rw-r--r--modules/denoise/SCsub119
-rw-r--r--modules/denoise/config.py6
-rw-r--r--modules/denoise/denoise_wrapper.cpp64
-rw-r--r--modules/denoise/denoise_wrapper.h38
-rw-r--r--modules/denoise/lightmap_denoiser.cpp62
-rw-r--r--modules/denoise/lightmap_denoiser.h56
-rw-r--r--modules/denoise/register_types.cpp (renamed from core/path_remap.cpp)13
-rw-r--r--modules/denoise/register_types.h (renamed from core/math/audio_frame.cpp)5
-rw-r--r--modules/denoise/resource_to_cpp.py70
-rw-r--r--modules/enet/networked_multiplayer_enet.cpp100
-rw-r--r--modules/enet/networked_multiplayer_enet.h2
-rw-r--r--modules/enet/register_types.cpp5
-rw-r--r--modules/etc/image_etc.cpp11
-rw-r--r--modules/etc/register_types.cpp2
-rw-r--r--modules/etc/texture_loader_pkm.cpp21
-rw-r--r--modules/etc/texture_loader_pkm.h2
-rw-r--r--modules/gdnative/gdnative.cpp25
-rw-r--r--modules/gdnative/gdnative.h2
-rw-r--r--modules/gdnative/gdnative/aabb.cpp2
-rw-r--r--modules/gdnative/gdnative/array.cpp34
-rw-r--r--modules/gdnative/gdnative/basis.cpp2
-rw-r--r--modules/gdnative/gdnative/callable.cpp252
-rw-r--r--modules/gdnative/gdnative/color.cpp8
-rw-r--r--modules/gdnative/gdnative/dictionary.cpp2
-rw-r--r--modules/gdnative/gdnative/gdnative.cpp16
-rw-r--r--modules/gdnative/gdnative/node_path.cpp2
-rw-r--r--modules/gdnative/gdnative/packed_arrays.cpp (renamed from modules/gdnative/gdnative/pool_arrays.cpp)326
-rw-r--r--modules/gdnative/gdnative/plane.cpp3
-rw-r--r--modules/gdnative/gdnative/quat.cpp3
-rw-r--r--modules/gdnative/gdnative/rect2.cpp156
-rw-r--r--modules/gdnative/gdnative/rid.cpp2
-rw-r--r--modules/gdnative/gdnative/string.cpp5
-rw-r--r--modules/gdnative/gdnative/string_name.cpp2
-rw-r--r--modules/gdnative/gdnative/transform.cpp2
-rw-r--r--modules/gdnative/gdnative/transform2d.cpp2
-rw-r--r--modules/gdnative/gdnative/variant.cpp133
-rw-r--r--modules/gdnative/gdnative/vector2.cpp156
-rw-r--r--modules/gdnative/gdnative/vector3.cpp151
-rw-r--r--modules/gdnative/gdnative_api.json1302
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.cpp39
-rw-r--r--modules/gdnative/gdnative_library_editor_plugin.h2
-rw-r--r--modules/gdnative/gdnative_library_singleton_editor.cpp18
-rw-r--r--modules/gdnative/include/gdnative/array.h8
-rw-r--r--modules/gdnative/include/gdnative/callable.h126
-rw-r--r--modules/gdnative/include/gdnative/color.h2
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h18
-rw-r--r--modules/gdnative/include/gdnative/packed_arrays.h (renamed from modules/gdnative/include/gdnative/pool_arrays.h)180
-rw-r--r--modules/gdnative/include/gdnative/rect2.h54
-rw-r--r--modules/gdnative/include/gdnative/rid.h2
-rw-r--r--modules/gdnative/include/gdnative/variant.h40
-rw-r--r--modules/gdnative/include/gdnative/vector2.h57
-rw-r--r--modules/gdnative/include/gdnative/vector3.h55
-rw-r--r--modules/gdnative/include/nativescript/godot_nativescript.h9
-rw-r--r--modules/gdnative/include/net/godot_net.h1
-rw-r--r--modules/gdnative/include/videodecoder/godot_videodecoder.h2
-rw-r--r--modules/gdnative/nativescript/api_generator.cpp7
-rw-r--r--modules/gdnative/nativescript/godot_nativescript.cpp18
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp212
-rw-r--r--modules/gdnative/nativescript/nativescript.h31
-rw-r--r--modules/gdnative/nativescript/register_types.cpp1
-rw-r--r--modules/gdnative/net/multiplayer_peer_gdnative.cpp1
-rw-r--r--modules/gdnative/net/packet_peer_gdnative.cpp1
-rw-r--r--modules/gdnative/net/stream_peer_gdnative.h1
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.cpp13
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.h4
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.cpp50
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.h13
-rw-r--r--modules/gdnative/register_types.cpp10
-rw-r--r--modules/gdnative/videodecoder/register_types.cpp2
-rw-r--r--modules/gdnative/videodecoder/video_stream_gdnative.cpp45
-rw-r--r--modules/gdnative/videodecoder/video_stream_gdnative.h49
-rw-r--r--modules/gdnative/xr/xr_interface_gdnative.cpp20
-rw-r--r--modules/gdnavigation/gd_navigation_server.cpp10
-rw-r--r--modules/gdnavigation/gd_navigation_server.h2
-rw-r--r--modules/gdnavigation/nav_map.cpp55
-rw-r--r--modules/gdnavigation/nav_map.h19
-rw-r--r--modules/gdnavigation/nav_region.cpp13
-rw-r--r--modules/gdnavigation/nav_region.h6
-rw-r--r--modules/gdnavigation/nav_utils.h46
-rw-r--r--modules/gdnavigation/navigation_mesh_editor_plugin.cpp14
-rw-r--r--modules/gdnavigation/navigation_mesh_editor_plugin.h1
-rw-r--r--modules/gdnavigation/navigation_mesh_generator.cpp59
-rw-r--r--modules/gdnavigation/rvo_agent.cpp3
-rw-r--r--modules/gdnavigation/rvo_agent.h2
-rw-r--r--modules/gdscript/config.py1
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml2
-rw-r--r--modules/gdscript/doc_classes/GDScriptNativeClass.xml19
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp9
-rw-r--r--modules/gdscript/gdscript.cpp393
-rw-r--r--modules/gdscript/gdscript.h49
-rw-r--r--modules/gdscript/gdscript_compiler.cpp464
-rw-r--r--modules/gdscript/gdscript_compiler.h15
-rw-r--r--modules/gdscript/gdscript_editor.cpp204
-rw-r--r--modules/gdscript/gdscript_function.cpp253
-rw-r--r--modules/gdscript/gdscript_function.h36
-rw-r--r--modules/gdscript/gdscript_functions.cpp140
-rw-r--r--modules/gdscript/gdscript_parser.cpp1122
-rw-r--r--modules/gdscript/gdscript_parser.h157
-rw-r--r--modules/gdscript/gdscript_tokenizer.cpp179
-rw-r--r--modules/gdscript/gdscript_tokenizer.h4
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.cpp34
-rw-r--r--modules/gdscript/language_server/gdscript_extend_parser.h1
-rw-r--r--modules/gdscript/language_server/gdscript_language_protocol.cpp15
-rw-r--r--modules/gdscript/language_server/gdscript_language_server.cpp1
-rw-r--r--modules/gdscript/language_server/gdscript_text_document.cpp17
-rw-r--r--modules/gdscript/language_server/gdscript_workspace.cpp31
-rw-r--r--modules/gdscript/language_server/lsp.hpp61
-rw-r--r--modules/gdscript/register_types.cpp27
-rw-r--r--modules/glslang/register_types.cpp22
-rw-r--r--modules/gridmap/grid_map.cpp174
-rw-r--r--modules/gridmap/grid_map.h9
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp241
-rw-r--r--modules/gridmap/grid_map_editor_plugin.h5
-rw-r--r--modules/gridmap/register_types.cpp1
-rw-r--r--modules/hdr/image_loader_hdr.cpp13
-rw-r--r--modules/hdr/image_loader_hdr.h1
-rw-r--r--modules/hdr/register_types.cpp2
-rw-r--r--modules/jpg/image_loader_jpegd.cpp18
-rw-r--r--modules/jpg/image_loader_jpegd.h1
-rw-r--r--modules/jpg/register_types.cpp2
-rw-r--r--modules/jsonrpc/jsonrpc.cpp7
-rw-r--r--modules/lightmapper_rd/SCsub12
-rw-r--r--modules/lightmapper_rd/config.py6
-rw-r--r--modules/lightmapper_rd/lightmapper_rd.cpp1752
-rw-r--r--modules/lightmapper_rd/lightmapper_rd.h258
-rw-r--r--modules/lightmapper_rd/lm_blendseams.glsl108
-rw-r--r--modules/lightmapper_rd/lm_common_inc.glsl92
-rw-r--r--modules/lightmapper_rd/lm_compute.glsl644
-rw-r--r--modules/lightmapper_rd/lm_raster.glsl157
-rw-r--r--modules/lightmapper_rd/register_types.cpp63
-rw-r--r--modules/lightmapper_rd/register_types.h (renamed from core/os/semaphore.cpp)10
-rw-r--r--modules/mbedtls/crypto_mbedtls.cpp1
-rw-r--r--modules/mbedtls/crypto_mbedtls.h3
-rw-r--r--modules/mbedtls/dtls_server_mbedtls.cpp2
-rw-r--r--modules/mbedtls/dtls_server_mbedtls.h1
-rw-r--r--[-rwxr-xr-x]modules/mbedtls/packet_peer_mbed_dtls.cpp33
-rw-r--r--[-rwxr-xr-x]modules/mbedtls/register_types.cpp2
-rw-r--r--modules/mbedtls/ssl_context_mbedtls.cpp19
-rw-r--r--modules/mbedtls/ssl_context_mbedtls.h2
-rw-r--r--[-rwxr-xr-x]modules/mbedtls/stream_peer_mbedtls.cpp34
-rw-r--r--modules/mobile_vr/mobile_vr_interface.cpp35
-rw-r--r--modules/mobile_vr/mobile_vr_interface.h2
-rw-r--r--modules/mono/SCsub2
-rw-r--r--modules/mono/build_scripts/godot_tools_build.py8
-rw-r--r--modules/mono/build_scripts/solution_builder.py156
-rw-r--r--modules/mono/class_db_api_json.cpp6
-rw-r--r--modules/mono/config.py2
-rw-r--r--modules/mono/csharp_script.cpp358
-rw-r--r--modules/mono/csharp_script.h29
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs14
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj58
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs35
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs27
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj38
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/Properties/AssemblyInfo.cs26
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs14
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs33
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs94
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs219
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs207
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs24
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs24
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj53
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs21
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs46
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs88
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs35
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/ForwarderMessageHandler.cs57
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/GodotTools.IdeMessaging.CLI.csproj17
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/Program.cs218
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs332
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ClientHandshake.cs44
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ClientMessageHandler.cs52
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotIdeMetadata.cs (renamed from modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeMetadata.cs)6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotTools.IdeMessaging.csproj24
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/IHandshake.cs8
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ILogger.cs (renamed from modules/mono/editor/GodotTools/GodotTools.IdeConnection/ILogger.cs)2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/IMessageHandler.cs9
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Message.cs52
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/MessageDecoder.cs100
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Peer.cs302
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Requests/Requests.cs116
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ResponseAwaiter.cs23
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/NotifyAwaiter.cs (renamed from modules/mono/editor/GodotTools/GodotTools/Utils/NotifyAwaiter.cs)4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/SemaphoreExtensions.cs32
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs5
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj60
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/MSBuild.exe0
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs11
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs6
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs91
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/Properties/AssemblyInfo.cs27
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.ProjectEditor/packages.config4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools.sln2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs52
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/BuildTool.cs10
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs91
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildInfo.cs4
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildManager.cs65
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/BuildTab.cs12
-rwxr-xr-xmodules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs2
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs56
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs56
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj128
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs163
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs212
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs360
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs14
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs12
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs7
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/PlaySettings.cs19
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Properties/AssemblyInfo.cs26
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs51
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/packages.config5
-rw-r--r--modules/mono/editor/bindings_generator.cpp545
-rw-r--r--modules/mono/editor/bindings_generator.h235
-rw-r--r--modules/mono/editor/code_completion.cpp249
-rw-r--r--modules/mono/editor/code_completion.h56
-rw-r--r--modules/mono/editor/csharp_project.cpp1
-rw-r--r--modules/mono/editor/editor_internal_calls.cpp19
-rw-r--r--modules/mono/editor/godotsharp_export.cpp93
-rw-r--r--modules/mono/editor/godotsharp_export.h4
-rw-r--r--modules/mono/editor/script_class_parser.cpp29
-rw-r--r--modules/mono/editor/script_class_parser.h1
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs28
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs38
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs31
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs178
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs18
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs4
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs6
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs20
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs18
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj1
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj1
-rw-r--r--modules/mono/glue/arguments_vector.h1
-rw-r--r--modules/mono/glue/gd_glue.cpp1
-rw-r--r--modules/mono/godotsharp_dirs.cpp1
-rw-r--r--modules/mono/managed_callable.cpp1
-rw-r--r--modules/mono/mono_gc_handle.cpp2
-rw-r--r--modules/mono/mono_gc_handle.h10
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp96
-rw-r--r--modules/mono/mono_gd/gd_mono.h24
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp107
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.h17
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.cpp34
-rw-r--r--modules/mono/mono_gd/gd_mono_cache.h24
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp55
-rw-r--r--modules/mono/mono_gd/gd_mono_class.h13
-rw-r--r--modules/mono/mono_gd/gd_mono_field.cpp110
-rw-r--r--modules/mono/mono_gd/gd_mono_field.h1
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp1
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp11
-rw-r--r--modules/mono/mono_gd/gd_mono_log.h1
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp308
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h9
-rw-r--r--modules/mono/mono_gd/gd_mono_method.cpp6
-rw-r--r--modules/mono/mono_gd/gd_mono_method.h1
-rw-r--r--modules/mono/mono_gd/gd_mono_method_thunk.h28
-rw-r--r--modules/mono/mono_gd/gd_mono_property.h1
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp71
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h20
-rw-r--r--modules/mono/mono_gd/managed_type.h9
-rw-r--r--[-rwxr-xr-x]modules/mono/mono_gd/support/android_support.cpp0
-rw-r--r--[-rwxr-xr-x]modules/mono/mono_gd/support/ios_support.mm0
-rw-r--r--modules/mono/signal_awaiter_utils.cpp1
-rw-r--r--modules/mono/utils/macros.h2
-rw-r--r--modules/mono/utils/mono_reg_utils.cpp7
-rw-r--r--modules/mono/utils/mono_reg_utils.h1
-rw-r--r--modules/mono/utils/osx_utils.cpp1
-rw-r--r--modules/mono/utils/string_utils.cpp12
-rw-r--r--modules/opensimplex/noise_texture.cpp40
-rw-r--r--modules/opensimplex/open_simplex_noise.cpp30
-rw-r--r--modules/opensimplex/register_types.cpp1
-rw-r--r--modules/pvr/register_types.cpp2
-rw-r--r--modules/pvr/texture_loader_pvr.cpp98
-rw-r--r--modules/pvr/texture_loader_pvr.h2
-rw-r--r--modules/regex/regex.cpp99
-rw-r--r--modules/regex/regex.h2
-rw-r--r--modules/regex/register_types.cpp1
-rw-r--r--modules/squish/image_compress_squish.cpp17
-rw-r--r--modules/squish/register_types.cpp1
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp25
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.h2
-rw-r--r--modules/stb_vorbis/register_types.cpp1
-rw-r--r--modules/stb_vorbis/resource_importer_ogg_vorbis.cpp10
-rw-r--r--modules/svg/image_loader_svg.cpp8
-rw-r--r--modules/svg/image_loader_svg.h1
-rw-r--r--modules/svg/register_types.cpp2
-rw-r--r--modules/tga/image_loader_tga.cpp15
-rw-r--r--modules/tga/register_types.cpp2
-rw-r--r--modules/theora/register_types.cpp2
-rw-r--r--modules/theora/video_stream_theora.cpp87
-rw-r--r--modules/theora/video_stream_theora.h6
-rw-r--r--modules/tinyexr/SCsub3
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp10
-rw-r--r--modules/tinyexr/image_loader_tinyexr.h1
-rw-r--r--modules/tinyexr/image_saver_tinyexr.cpp21
-rw-r--r--modules/tinyexr/register_types.cpp2
-rw-r--r--modules/upnp/register_types.cpp1
-rw-r--r--modules/upnp/upnp.h1
-rw-r--r--modules/upnp/upnp_device.h1
-rw-r--r--modules/vhacd/register_types.cpp1
-rw-r--r--modules/visual_script/register_types.cpp5
-rw-r--r--modules/visual_script/visual_script.cpp406
-rw-r--r--modules/visual_script/visual_script.h37
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp256
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.h1
-rw-r--r--modules/visual_script/visual_script_editor.cpp809
-rw-r--r--modules/visual_script/visual_script_editor.h1
-rw-r--r--modules/visual_script/visual_script_expression.cpp364
-rw-r--r--modules/visual_script/visual_script_expression.h12
-rw-r--r--modules/visual_script/visual_script_flow_control.cpp189
-rw-r--r--modules/visual_script/visual_script_flow_control.h7
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp448
-rw-r--r--modules/visual_script/visual_script_func_nodes.h4
-rw-r--r--modules/visual_script/visual_script_nodes.cpp703
-rw-r--r--modules/visual_script/visual_script_nodes.h28
-rw-r--r--modules/visual_script/visual_script_property_selector.cpp88
-rw-r--r--modules/visual_script/visual_script_yield_nodes.cpp164
-rw-r--r--modules/visual_script/visual_script_yield_nodes.h2
-rw-r--r--modules/webm/register_types.cpp2
-rw-r--r--modules/webm/video_stream_webm.cpp150
-rw-r--r--modules/webm/video_stream_webm.h32
-rw-r--r--modules/webp/image_loader_webp.cpp14
-rw-r--r--modules/webp/image_loader_webp.h1
-rw-r--r--modules/webp/register_types.cpp2
-rw-r--r--modules/webrtc/webrtc_data_channel_js.cpp7
-rw-r--r--modules/webrtc/webrtc_multiplayer.cpp35
-rw-r--r--modules/webrtc/webrtc_multiplayer.h5
-rw-r--r--modules/webrtc/webrtc_peer_connection.cpp5
-rw-r--r--modules/webrtc/webrtc_peer_connection_gdnative.cpp1
-rw-r--r--modules/webrtc/webrtc_peer_connection_js.h1
-rw-r--r--modules/websocket/editor_debugger_server_websocket.cpp93
-rw-r--r--modules/websocket/editor_debugger_server_websocket.h62
-rw-r--r--modules/websocket/emws_client.cpp18
-rw-r--r--modules/websocket/emws_client.h1
-rw-r--r--modules/websocket/emws_peer.cpp12
-rw-r--r--modules/websocket/emws_peer.h1
-rw-r--r--modules/websocket/emws_server.cpp3
-rw-r--r--modules/websocket/emws_server.h1
-rw-r--r--modules/websocket/packet_buffer.h1
-rw-r--r--modules/websocket/register_types.cpp31
-rw-r--r--modules/websocket/remote_debugger_peer_websocket.cpp133
-rw-r--r--modules/websocket/remote_debugger_peer_websocket.h65
-rw-r--r--modules/websocket/websocket_client.cpp14
-rw-r--r--modules/websocket/websocket_client.h1
-rw-r--r--modules/websocket/websocket_macros.h12
-rw-r--r--modules/websocket/websocket_multiplayer_peer.cpp50
-rw-r--r--modules/websocket/websocket_multiplayer_peer.h1
-rw-r--r--modules/websocket/websocket_peer.h1
-rw-r--r--modules/websocket/websocket_server.cpp9
-rw-r--r--modules/websocket/websocket_server.h1
-rw-r--r--modules/websocket/wsl_client.cpp42
-rw-r--r--modules/websocket/wsl_client.h1
-rw-r--r--modules/websocket/wsl_peer.cpp32
-rw-r--r--modules/websocket/wsl_peer.h1
-rw-r--r--modules/websocket/wsl_server.cpp54
-rw-r--r--modules/websocket/wsl_server.h2
-rw-r--r--modules/xatlas_unwrap/register_types.cpp141
-rw-r--r--platform/android/android_keys_utils.cpp2
-rw-r--r--platform/android/android_keys_utils.h1
-rw-r--r--platform/android/api/api.cpp3
-rw-r--r--platform/android/api/java_class_wrapper.h38
-rw-r--r--platform/android/api/jni_singleton.h19
-rw-r--r--platform/android/audio_driver_jandroid.cpp20
-rw-r--r--platform/android/audio_driver_jandroid.h1
-rw-r--r--platform/android/audio_driver_opensl.cpp19
-rw-r--r--platform/android/audio_driver_opensl.h1
-rw-r--r--platform/android/dir_access_jandroid.cpp20
-rw-r--r--platform/android/dir_access_jandroid.h1
-rw-r--r--platform/android/display_server_android.cpp67
-rw-r--r--platform/android/display_server_android.h5
-rw-r--r--platform/android/export/export.cpp316
-rw-r--r--platform/android/file_access_android.cpp16
-rw-r--r--platform/android/file_access_android.h1
-rw-r--r--platform/android/file_access_jandroid.cpp17
-rw-r--r--platform/android/file_access_jandroid.h1
-rw-r--r--platform/android/java/app/AndroidManifest.xml4
-rw-r--r--platform/android/java/app/build.gradle33
-rw-r--r--platform/android/java/app/config.gradle81
-rw-r--r--platform/android/java/build.gradle3
-rw-r--r--platform/android/java/gradle.properties3
-rw-r--r--platform/android/java/lib/build.gradle4
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Dictionary.java6
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java44
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java19
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java45
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java13
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java11
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java10
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java44
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java6
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java12
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java14
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java14
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java20
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java9
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java1
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java17
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt11
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java7
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java6
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java5
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ConsumeTask.java4
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/GodotPayment.java21
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/HandlePurchaseTask.java2
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsCache.java1
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsManager.java8
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PurchaseTask.java4
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ReleaseAllConsumablesTask.java7
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java8
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/CustomSSLSocketFactory.java2
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/HttpRequester.java6
-rw-r--r--platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/RequestParams.java2
-rw-r--r--platform/android/java_class_wrapper.cpp94
-rw-r--r--platform/android/java_godot_io_wrapper.cpp6
-rw-r--r--platform/android/java_godot_io_wrapper.h2
-rw-r--r--platform/android/java_godot_lib_jni.cpp49
-rw-r--r--platform/android/java_godot_lib_jni.h6
-rw-r--r--platform/android/jni_utils.cpp34
-rw-r--r--platform/android/jni_utils.h1
-rw-r--r--platform/android/net_socket_android.cpp6
-rw-r--r--platform/android/net_socket_android.h7
-rw-r--r--platform/android/os_android.cpp19
-rw-r--r--platform/android/plugin/godot_plugin_config.h251
-rw-r--r--platform/android/plugin/godot_plugin_jni.cpp6
-rw-r--r--platform/android/thread_jandroid.cpp11
-rw-r--r--platform/android/thread_jandroid.h1
-rw-r--r--platform/android/vulkan/vulkan_context_android.h1
-rw-r--r--platform/haiku/audio_driver_media_kit.cpp4
-rw-r--r--platform/haiku/haiku_direct_window.h2
-rw-r--r--platform/haiku/key_mapping_haiku.h2
-rw-r--r--platform/haiku/os_haiku.cpp4
-rw-r--r--platform/haiku/os_haiku.h2
-rw-r--r--platform/iphone/app_delegate.mm74
-rw-r--r--platform/iphone/export/export.cpp60
-rw-r--r--platform/iphone/game_center.h1
-rw-r--r--platform/iphone/game_center.mm15
-rw-r--r--platform/iphone/gl_view.mm21
-rw-r--r--platform/iphone/godot_iphone.cpp5
-rw-r--r--platform/iphone/icloud.h1
-rw-r--r--platform/iphone/icloud.mm6
-rw-r--r--platform/iphone/in_app_store.h1
-rw-r--r--platform/iphone/in_app_store.mm17
-rw-r--r--platform/iphone/ios.h1
-rw-r--r--platform/iphone/ios.mm3
-rw-r--r--platform/iphone/os_iphone.cpp44
-rw-r--r--platform/iphone/os_iphone.h6
-rw-r--r--platform/iphone/view_controller.mm4
-rw-r--r--platform/iphone/vulkan_context_iphone.h1
-rw-r--r--platform/iphone/vulkan_context_iphone.mm1
-rw-r--r--platform/javascript/SCsub27
-rw-r--r--platform/javascript/api/api.cpp6
-rw-r--r--platform/javascript/audio_driver_javascript.cpp88
-rw-r--r--platform/javascript/audio_driver_javascript.h3
-rw-r--r--platform/javascript/detect.py15
-rw-r--r--platform/javascript/display_server_javascript.cpp1193
-rw-r--r--platform/javascript/display_server_javascript.h187
-rw-r--r--platform/javascript/dom_keys.inc151
-rw-r--r--platform/javascript/engine/engine.js175
-rw-r--r--platform/javascript/engine/loader.js33
-rw-r--r--platform/javascript/engine/utils.js18
-rw-r--r--platform/javascript/export/export.cpp66
-rw-r--r--platform/javascript/http_client.h.inc16
-rw-r--r--platform/javascript/http_client_javascript.cpp32
-rw-r--r--platform/javascript/javascript_eval.cpp2
-rw-r--r--platform/javascript/javascript_main.cpp49
-rw-r--r--platform/javascript/native/http_request.js (renamed from platform/javascript/http_request.js)0
-rw-r--r--platform/javascript/native/id_handler.js (renamed from platform/javascript/id_handler.js)0
-rw-r--r--platform/javascript/native/utils.js204
-rw-r--r--platform/javascript/os_javascript.cpp1159
-rw-r--r--platform/javascript/os_javascript.h99
-rw-r--r--platform/linuxbsd/context_gl_x11.cpp10
-rw-r--r--platform/linuxbsd/context_gl_x11.h1
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.cpp9
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.h1
-rw-r--r--platform/linuxbsd/detect.py8
-rw-r--r--platform/linuxbsd/detect_prime_x11.cpp3
-rw-r--r--platform/linuxbsd/display_server_x11.cpp417
-rw-r--r--platform/linuxbsd/display_server_x11.h7
-rw-r--r--platform/linuxbsd/export/export.cpp3
-rw-r--r--platform/linuxbsd/godot_linuxbsd.cpp4
-rw-r--r--platform/linuxbsd/joypad_linux.cpp81
-rw-r--r--platform/linuxbsd/joypad_linux.h10
-rw-r--r--platform/linuxbsd/key_mapping_x11.cpp58
-rw-r--r--platform/linuxbsd/key_mapping_x11.h2
-rw-r--r--platform/linuxbsd/os_linuxbsd.cpp48
-rw-r--r--platform/linuxbsd/os_linuxbsd.h3
-rw-r--r--platform/linuxbsd/vulkan_context_x11.cpp1
-rw-r--r--platform/linuxbsd/vulkan_context_x11.h1
-rw-r--r--platform/osx/context_gl_osx.h1
-rw-r--r--platform/osx/context_gl_osx.mm11
-rw-r--r--platform/osx/crash_handler_osx.h1
-rw-r--r--platform/osx/dir_access_osx.mm1
-rw-r--r--platform/osx/display_server_osx.h2
-rw-r--r--platform/osx/display_server_osx.mm171
-rw-r--r--platform/osx/export/export.cpp361
-rw-r--r--platform/osx/godot_main_osx.mm1
-rw-r--r--platform/osx/joypad_osx.cpp44
-rw-r--r--platform/osx/joypad_osx.h7
-rw-r--r--platform/osx/os_osx.h2
-rw-r--r--platform/osx/os_osx.mm37
-rw-r--r--platform/osx/vulkan_context_osx.h1
-rw-r--r--platform/osx/vulkan_context_osx.mm1
-rw-r--r--platform/server/godot_server.cpp1
-rw-r--r--platform/server/os_server.cpp33
-rw-r--r--platform/server/os_server.h3
-rw-r--r--platform/uwp/app.cpp36
-rw-r--r--platform/uwp/app.h16
-rw-r--r--platform/uwp/context_egl_uwp.cpp10
-rw-r--r--platform/uwp/context_egl_uwp.h1
-rw-r--r--platform/uwp/export/export.cpp216
-rw-r--r--platform/uwp/joypad_uwp.cpp28
-rw-r--r--platform/uwp/joypad_uwp.h4
-rw-r--r--platform/uwp/os_uwp.cpp87
-rw-r--r--platform/uwp/os_uwp.h6
-rw-r--r--platform/uwp/thread_uwp.cpp12
-rw-r--r--platform/uwp/thread_uwp.h9
-rw-r--r--platform/windows/context_gl_windows.cpp11
-rw-r--r--platform/windows/context_gl_windows.h1
-rw-r--r--platform/windows/crash_handler_windows.cpp4
-rw-r--r--platform/windows/crash_handler_windows.h1
-rw-r--r--platform/windows/display_server_windows.cpp531
-rw-r--r--platform/windows/display_server_windows.h138
-rw-r--r--platform/windows/export/export.cpp4
-rw-r--r--platform/windows/godot_windows.cpp1
-rw-r--r--platform/windows/joypad_windows.cpp92
-rw-r--r--platform/windows/joypad_windows.h6
-rw-r--r--platform/windows/key_mapping_windows.cpp19
-rw-r--r--platform/windows/key_mapping_windows.h4
-rw-r--r--platform/windows/os_windows.cpp152
-rw-r--r--platform/windows/os_windows.h14
-rw-r--r--platform/windows/vulkan_context_win.cpp1
-rw-r--r--platform/windows/vulkan_context_win.h1
-rw-r--r--platform/windows/windows_terminal_logger.cpp49
-rw-r--r--scene/2d/animated_sprite_2d.cpp167
-rw-r--r--scene/2d/animated_sprite_2d.h18
-rw-r--r--scene/2d/area_2d.cpp139
-rw-r--r--scene/2d/area_2d.h19
-rw-r--r--scene/2d/audio_stream_player_2d.cpp71
-rw-r--r--scene/2d/audio_stream_player_2d.h2
-rw-r--r--scene/2d/back_buffer_copy.cpp14
-rw-r--r--scene/2d/camera_2d.cpp122
-rw-r--r--scene/2d/camera_2d.h1
-rw-r--r--scene/2d/canvas_modulate.cpp12
-rw-r--r--scene/2d/canvas_modulate.h1
-rw-r--r--scene/2d/collision_object_2d.cpp85
-rw-r--r--scene/2d/collision_object_2d.h2
-rw-r--r--scene/2d/collision_polygon_2d.cpp37
-rw-r--r--scene/2d/collision_polygon_2d.h1
-rw-r--r--scene/2d/collision_shape_2d.cpp30
-rw-r--r--scene/2d/collision_shape_2d.h1
-rw-r--r--scene/2d/cpu_particles_2d.cpp154
-rw-r--r--scene/2d/cpu_particles_2d.h1
-rw-r--r--scene/2d/gpu_particles_2d.cpp73
-rw-r--r--scene/2d/joints_2d.cpp93
-rw-r--r--scene/2d/joints_2d.h4
-rw-r--r--scene/2d/light_2d.cpp67
-rw-r--r--scene/2d/light_2d.h1
-rw-r--r--scene/2d/light_occluder_2d.cpp58
-rw-r--r--scene/2d/light_occluder_2d.h1
-rw-r--r--scene/2d/line_2d.cpp24
-rw-r--r--scene/2d/line_2d.h1
-rw-r--r--scene/2d/line_builder.cpp51
-rw-r--r--scene/2d/mesh_instance_2d.cpp12
-rw-r--r--scene/2d/multimesh_instance_2d.cpp12
-rw-r--r--scene/2d/navigation_2d.cpp2
-rw-r--r--scene/2d/navigation_2d.h1
-rw-r--r--scene/2d/navigation_agent_2d.cpp37
-rw-r--r--scene/2d/navigation_agent_2d.h14
-rw-r--r--scene/2d/navigation_obstacle_2d.cpp17
-rw-r--r--scene/2d/navigation_obstacle_2d.h2
-rw-r--r--scene/2d/navigation_region_2d.cpp111
-rw-r--r--scene/2d/navigation_region_2d.h16
-rw-r--r--scene/2d/node_2d.cpp144
-rw-r--r--scene/2d/node_2d.h6
-rw-r--r--scene/2d/parallax_background.cpp47
-rw-r--r--scene/2d/parallax_background.h1
-rw-r--r--scene/2d/parallax_layer.cpp29
-rw-r--r--scene/2d/parallax_layer.h1
-rw-r--r--scene/2d/path_2d.cpp73
-rw-r--r--scene/2d/path_2d.h2
-rw-r--r--scene/2d/physics_body_2d.cpp207
-rw-r--r--scene/2d/physics_body_2d.h16
-rw-r--r--scene/2d/polygon_2d.cpp87
-rw-r--r--scene/2d/polygon_2d.h1
-rw-r--r--scene/2d/position_2d.cpp12
-rw-r--r--scene/2d/position_2d.h1
-rw-r--r--scene/2d/ray_cast_2d.cpp95
-rw-r--r--scene/2d/ray_cast_2d.h1
-rw-r--r--scene/2d/remote_transform_2d.cpp50
-rw-r--r--scene/2d/remote_transform_2d.h1
-rw-r--r--scene/2d/skeleton_2d.cpp47
-rw-r--r--scene/2d/sprite_2d.cpp97
-rw-r--r--scene/2d/sprite_2d.h1
-rw-r--r--scene/2d/tile_map.cpp334
-rw-r--r--scene/2d/tile_map.h14
-rw-r--r--scene/2d/touch_screen_button.cpp116
-rw-r--r--scene/2d/touch_screen_button.h1
-rw-r--r--scene/2d/visibility_notifier_2d.cpp96
-rw-r--r--scene/2d/visibility_notifier_2d.h2
-rw-r--r--scene/2d/y_sort.cpp4
-rw-r--r--scene/3d/area_3d.cpp147
-rw-r--r--scene/3d/area_3d.h19
-rw-r--r--scene/3d/audio_stream_player_3d.cpp133
-rw-r--r--scene/3d/audio_stream_player_3d.h2
-rw-r--r--scene/3d/baked_lightmap.cpp1624
-rw-r--r--scene/3d/baked_lightmap.h251
-rw-r--r--scene/3d/bone_attachment_3d.cpp23
-rw-r--r--scene/3d/bone_attachment_3d.h1
-rw-r--r--scene/3d/camera_3d.cpp155
-rw-r--r--scene/3d/camera_3d.h2
-rw-r--r--scene/3d/collision_object_3d.cpp63
-rw-r--r--scene/3d/collision_object_3d.h2
-rw-r--r--scene/3d/collision_polygon_3d.cpp28
-rw-r--r--scene/3d/collision_polygon_3d.h1
-rw-r--r--scene/3d/collision_shape_3d.cpp29
-rw-r--r--scene/3d/collision_shape_3d.h1
-rw-r--r--scene/3d/cpu_particles_3d.cpp153
-rw-r--r--scene/3d/cpu_particles_3d.h1
-rw-r--r--scene/3d/decal.cpp16
-rw-r--r--scene/3d/gi_probe.cpp41
-rw-r--r--scene/3d/gi_probe.h1
-rw-r--r--scene/3d/gpu_particles_3d.cpp83
-rw-r--r--scene/3d/immediate_geometry_3d.cpp20
-rw-r--r--scene/3d/immediate_geometry_3d.h1
-rw-r--r--scene/3d/light_3d.cpp66
-rw-r--r--scene/3d/light_3d.h4
-rw-r--r--scene/3d/lightmap_probe.cpp (renamed from core/math/disjoint_set.cpp)7
-rw-r--r--scene/3d/lightmap_probe.h42
-rw-r--r--scene/3d/lightmapper.cpp67
-rw-r--r--scene/3d/lightmapper.h120
-rw-r--r--scene/3d/listener_3d.cpp35
-rw-r--r--scene/3d/listener_3d.h1
-rw-r--r--scene/3d/mesh_instance_3d.cpp109
-rw-r--r--scene/3d/mesh_instance_3d.h2
-rw-r--r--scene/3d/multimesh_instance_3d.cpp15
-rw-r--r--scene/3d/navigation_3d.cpp6
-rw-r--r--scene/3d/navigation_3d.h1
-rw-r--r--scene/3d/navigation_agent_3d.cpp38
-rw-r--r--scene/3d/navigation_agent_3d.h16
-rw-r--r--scene/3d/navigation_obstacle_3d.cpp19
-rw-r--r--scene/3d/navigation_obstacle_3d.h2
-rw-r--r--scene/3d/navigation_region_3d.cpp44
-rw-r--r--scene/3d/navigation_region_3d.h9
-rw-r--r--scene/3d/node_3d.cpp160
-rw-r--r--scene/3d/node_3d.h5
-rw-r--r--scene/3d/path_3d.cpp68
-rw-r--r--scene/3d/path_3d.h2
-rw-r--r--scene/3d/physics_body_3d.cpp399
-rw-r--r--scene/3d/physics_body_3d.h184
-rw-r--r--scene/3d/physics_joint_3d.cpp163
-rw-r--r--scene/3d/physics_joint_3d.h8
-rw-r--r--scene/3d/position_3d.h1
-rw-r--r--scene/3d/proximity_group_3d.cpp35
-rw-r--r--scene/3d/proximity_group_3d.h11
-rw-r--r--scene/3d/ray_cast_3d.cpp119
-rw-r--r--scene/3d/ray_cast_3d.h1
-rw-r--r--scene/3d/reflection_probe.cpp34
-rw-r--r--scene/3d/remote_transform_3d.cpp38
-rw-r--r--scene/3d/skeleton_3d.cpp145
-rw-r--r--scene/3d/skeleton_3d.h6
-rw-r--r--scene/3d/skeleton_ik_3d.cpp88
-rw-r--r--scene/3d/skeleton_ik_3d.h54
-rw-r--r--scene/3d/soft_body_3d.cpp92
-rw-r--r--scene/3d/soft_body_3d.h17
-rw-r--r--scene/3d/spring_arm_3d.cpp17
-rw-r--r--scene/3d/spring_arm_3d.h12
-rw-r--r--scene/3d/sprite_3d.cpp222
-rw-r--r--scene/3d/sprite_3d.h3
-rw-r--r--scene/3d/vehicle_body_3d.cpp96
-rw-r--r--scene/3d/vehicle_body_3d.h2
-rw-r--r--scene/3d/velocity_tracker_3d.cpp11
-rw-r--r--scene/3d/visibility_notifier_3d.cpp66
-rw-r--r--scene/3d/visibility_notifier_3d.h2
-rw-r--r--scene/3d/visual_instance_3d.cpp136
-rw-r--r--scene/3d/visual_instance_3d.h38
-rw-r--r--scene/3d/voxelizer.cpp294
-rw-r--r--scene/3d/voxelizer.h1
-rw-r--r--scene/3d/world_environment.cpp62
-rw-r--r--scene/3d/world_environment.h1
-rw-r--r--scene/3d/xr_nodes.cpp68
-rw-r--r--scene/3d/xr_nodes.h43
-rw-r--r--scene/animation/animation_blend_space_1d.cpp6
-rw-r--r--scene/animation/animation_blend_space_2d.cpp56
-rw-r--r--scene/animation/animation_blend_tree.cpp125
-rw-r--r--scene/animation/animation_blend_tree.h2
-rw-r--r--scene/animation/animation_cache.cpp64
-rw-r--r--scene/animation/animation_cache.h2
-rw-r--r--scene/animation/animation_node_state_machine.cpp69
-rw-r--r--scene/animation/animation_node_state_machine.h2
-rw-r--r--scene/animation/animation_player.cpp327
-rw-r--r--scene/animation/animation_player.h83
-rw-r--r--scene/animation/animation_tree.cpp122
-rw-r--r--scene/animation/animation_tree.h9
-rw-r--r--scene/animation/root_motion_view.cpp7
-rw-r--r--scene/animation/tween.cpp249
-rw-r--r--scene/animation/tween.h1
-rw-r--r--scene/audio/audio_stream_player.cpp48
-rw-r--r--scene/audio/audio_stream_player.h1
-rw-r--r--scene/debugger/scene_debugger.cpp250
-rw-r--r--scene/debugger/scene_debugger.h6
-rw-r--r--scene/gui/base_button.cpp77
-rw-r--r--scene/gui/base_button.h3
-rw-r--r--scene/gui/box_container.cpp61
-rw-r--r--scene/gui/box_container.h3
-rw-r--r--scene/gui/button.cpp96
-rw-r--r--scene/gui/button.h1
-rw-r--r--scene/gui/center_container.cpp27
-rw-r--r--scene/gui/center_container.h1
-rw-r--r--scene/gui/check_box.cpp22
-rw-r--r--scene/gui/check_box.h1
-rw-r--r--scene/gui/check_button.cpp20
-rw-r--r--scene/gui/check_button.h1
-rw-r--r--scene/gui/color_picker.cpp153
-rw-r--r--scene/gui/color_picker.h2
-rw-r--r--scene/gui/color_rect.cpp5
-rw-r--r--scene/gui/container.cpp40
-rw-r--r--scene/gui/container.h1
-rw-r--r--scene/gui/control.cpp455
-rw-r--r--scene/gui/control.h6
-rw-r--r--scene/gui/dialogs.cpp48
-rw-r--r--scene/gui/dialogs.h2
-rw-r--r--scene/gui/file_dialog.cpp178
-rw-r--r--scene/gui/file_dialog.h1
-rw-r--r--scene/gui/gradient_edit.cpp59
-rw-r--r--scene/gui/gradient_edit.h1
-rw-r--r--scene/gui/graph_edit.cpp258
-rw-r--r--scene/gui/graph_edit.h4
-rw-r--r--scene/gui/graph_node.cpp195
-rw-r--r--scene/gui/graph_node.h1
-rw-r--r--scene/gui/grid_container.cpp47
-rw-r--r--scene/gui/grid_container.h1
-rw-r--r--scene/gui/item_list.cpp223
-rw-r--r--scene/gui/item_list.h2
-rw-r--r--scene/gui/label.cpp138
-rw-r--r--scene/gui/label.h45
-rw-r--r--scene/gui/line_edit.cpp307
-rw-r--r--scene/gui/line_edit.h2
-rw-r--r--scene/gui/link_button.cpp23
-rw-r--r--scene/gui/link_button.h1
-rw-r--r--scene/gui/margin_container.cpp27
-rw-r--r--scene/gui/menu_button.cpp23
-rw-r--r--scene/gui/menu_button.h1
-rw-r--r--scene/gui/nine_patch_rect.cpp25
-rw-r--r--scene/gui/nine_patch_rect.h1
-rw-r--r--scene/gui/option_button.cpp80
-rw-r--r--scene/gui/option_button.h1
-rw-r--r--scene/gui/panel.cpp3
-rw-r--r--scene/gui/panel.h1
-rw-r--r--scene/gui/panel_container.cpp36
-rw-r--r--scene/gui/panel_container.h1
-rw-r--r--scene/gui/popup.cpp26
-rw-r--r--scene/gui/popup.h2
-rw-r--r--scene/gui/popup_menu.cpp292
-rw-r--r--scene/gui/popup_menu.h2
-rw-r--r--scene/gui/progress_bar.cpp8
-rw-r--r--scene/gui/progress_bar.h1
-rw-r--r--scene/gui/range.cpp67
-rw-r--r--scene/gui/range.h1
-rw-r--r--scene/gui/reference_rect.cpp8
-rw-r--r--scene/gui/reference_rect.h1
-rw-r--r--scene/gui/rich_text_effect.cpp1
-rw-r--r--scene/gui/rich_text_label.cpp597
-rw-r--r--scene/gui/rich_text_label.h3
-rw-r--r--scene/gui/scroll_bar.cpp121
-rw-r--r--scene/gui/scroll_bar.h4
-rw-r--r--scene/gui/scroll_container.cpp120
-rw-r--r--scene/gui/scroll_container.h1
-rw-r--r--scene/gui/separator.cpp8
-rw-r--r--scene/gui/separator.h3
-rw-r--r--scene/gui/shortcut.cpp11
-rw-r--r--scene/gui/shortcut.h1
-rw-r--r--scene/gui/slider.cpp63
-rw-r--r--scene/gui/slider.h3
-rw-r--r--scene/gui/spin_box.cpp50
-rw-r--r--scene/gui/spin_box.h1
-rw-r--r--scene/gui/split_container.cpp98
-rw-r--r--scene/gui/split_container.h3
-rw-r--r--scene/gui/subviewport_container.cpp71
-rw-r--r--scene/gui/subviewport_container.h3
-rw-r--r--scene/gui/tab_container.cpp223
-rw-r--r--scene/gui/tab_container.h1
-rw-r--r--scene/gui/tabs.cpp157
-rw-r--r--scene/gui/tabs.h2
-rw-r--r--scene/gui/text_edit.cpp1097
-rw-r--r--scene/gui/text_edit.h16
-rw-r--r--scene/gui/texture_button.cpp71
-rw-r--r--scene/gui/texture_button.h1
-rw-r--r--scene/gui/texture_progress.cpp76
-rw-r--r--scene/gui/texture_progress.h1
-rw-r--r--scene/gui/texture_rect.cpp16
-rw-r--r--scene/gui/texture_rect.h1
-rw-r--r--scene/gui/tree.cpp809
-rw-r--r--scene/gui/tree.h8
-rw-r--r--scene/gui/video_player.cpp108
-rw-r--r--scene/gui/video_player.h2
-rw-r--r--scene/main/canvas_item.cpp306
-rw-r--r--scene/main/canvas_item.h20
-rw-r--r--scene/main/canvas_layer.cpp68
-rw-r--r--scene/main/canvas_layer.h1
-rw-r--r--scene/main/http_request.cpp60
-rw-r--r--scene/main/http_request.h1
-rw-r--r--scene/main/instance_placeholder.cpp28
-rw-r--r--scene/main/instance_placeholder.h1
-rw-r--r--scene/main/node.cpp695
-rw-r--r--scene/main/node.h11
-rw-r--r--scene/main/resource_preloader.cpp18
-rw-r--r--scene/main/resource_preloader.h1
-rw-r--r--scene/main/scene_tree.cpp318
-rw-r--r--scene/main/scene_tree.h3
-rw-r--r--scene/main/shader_globals_override.cpp44
-rw-r--r--scene/main/shader_globals_override.h31
-rw-r--r--scene/main/timer.cpp49
-rw-r--r--scene/main/timer.h1
-rw-r--r--scene/main/viewport.cpp696
-rw-r--r--scene/main/viewport.h21
-rw-r--r--scene/main/window.cpp97
-rw-r--r--scene/register_scene_types.cpp38
-rw-r--r--scene/resources/animation.cpp669
-rw-r--r--scene/resources/animation.h16
-rw-r--r--scene/resources/audio_stream_sample.cpp139
-rw-r--r--scene/resources/audio_stream_sample.h2
-rw-r--r--scene/resources/bit_map.cpp73
-rw-r--r--scene/resources/bit_map.h1
-rw-r--r--scene/resources/box_shape_3d.cpp6
-rw-r--r--scene/resources/box_shape_3d.h1
-rw-r--r--scene/resources/capsule_shape_2d.cpp18
-rw-r--r--scene/resources/capsule_shape_3d.cpp10
-rw-r--r--scene/resources/capsule_shape_3d.h1
-rw-r--r--scene/resources/circle_shape_2d.cpp8
-rw-r--r--scene/resources/concave_polygon_shape_2d.cpp23
-rw-r--r--scene/resources/concave_polygon_shape_3d.cpp8
-rw-r--r--scene/resources/concave_polygon_shape_3d.h7
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp13
-rw-r--r--scene/resources/convex_polygon_shape_3d.cpp6
-rw-r--r--scene/resources/convex_polygon_shape_3d.h1
-rw-r--r--scene/resources/curve.cpp297
-rw-r--r--scene/resources/curve.h7
-rw-r--r--scene/resources/cylinder_shape_3d.cpp10
-rw-r--r--scene/resources/cylinder_shape_3d.h1
-rw-r--r--scene/resources/default_theme/default_theme.cpp49
-rw-r--r--scene/resources/dynamic_font.cpp200
-rw-r--r--scene/resources/dynamic_font.h13
-rw-r--r--scene/resources/environment.cpp220
-rw-r--r--scene/resources/environment.h12
-rw-r--r--scene/resources/font.cpp173
-rw-r--r--scene/resources/font.h10
-rw-r--r--scene/resources/gradient.cpp10
-rw-r--r--scene/resources/gradient.h16
-rw-r--r--scene/resources/height_map_shape_3d.cpp9
-rw-r--r--scene/resources/line_shape_2d.cpp39
-rw-r--r--scene/resources/line_shape_2d.h6
-rw-r--r--scene/resources/material.cpp367
-rw-r--r--scene/resources/material.h5
-rw-r--r--scene/resources/mesh.cpp264
-rw-r--r--scene/resources/mesh.h8
-rw-r--r--scene/resources/mesh_data_tool.cpp139
-rw-r--r--scene/resources/mesh_data_tool.h3
-rw-r--r--scene/resources/mesh_library.cpp72
-rw-r--r--scene/resources/mesh_library.h1
-rw-r--r--scene/resources/multimesh.cpp80
-rw-r--r--scene/resources/multimesh.h1
-rw-r--r--scene/resources/navigation_mesh.cpp40
-rw-r--r--scene/resources/navigation_mesh.h2
-rw-r--r--scene/resources/packed_scene.cpp223
-rw-r--r--scene/resources/packed_scene.h5
-rw-r--r--scene/resources/particles_material.cpp195
-rw-r--r--scene/resources/particles_material.h3
-rw-r--r--scene/resources/physics_material.cpp7
-rw-r--r--scene/resources/physics_material.h17
-rw-r--r--scene/resources/polygon_path_finder.cpp69
-rw-r--r--scene/resources/polygon_path_finder.h9
-rw-r--r--scene/resources/primitive_meshes.cpp18
-rw-r--r--scene/resources/primitive_meshes.h8
-rw-r--r--scene/resources/ray_shape_3d.cpp7
-rw-r--r--scene/resources/ray_shape_3d.h1
-rw-r--r--scene/resources/rectangle_shape_2d.cpp7
-rw-r--r--scene/resources/resource_format_text.cpp220
-rw-r--r--scene/resources/resource_format_text.h9
-rw-r--r--scene/resources/segment_shape_2d.cpp24
-rw-r--r--scene/resources/shader.cpp43
-rw-r--r--scene/resources/shader.h9
-rw-r--r--scene/resources/shape_2d.cpp15
-rw-r--r--scene/resources/shape_3d.cpp20
-rw-r--r--scene/resources/shape_3d.h3
-rw-r--r--scene/resources/skin.cpp4
-rw-r--r--scene/resources/sky.cpp7
-rw-r--r--scene/resources/sky_material.cpp88
-rw-r--r--scene/resources/sky_material.h5
-rw-r--r--scene/resources/sphere_shape_3d.cpp7
-rw-r--r--scene/resources/sphere_shape_3d.h1
-rw-r--r--scene/resources/style_box.cpp112
-rw-r--r--scene/resources/style_box.h5
-rw-r--r--scene/resources/surface_tool.cpp164
-rw-r--r--scene/resources/surface_tool.h2
-rw-r--r--scene/resources/text_file.cpp1
-rw-r--r--scene/resources/text_file.h1
-rw-r--r--scene/resources/texture.cpp839
-rw-r--r--scene/resources/texture.h190
-rw-r--r--scene/resources/theme.cpp154
-rw-r--r--scene/resources/theme.h3
-rw-r--r--scene/resources/tile_set.cpp270
-rw-r--r--scene/resources/tile_set.h40
-rw-r--r--scene/resources/video_stream.h2
-rw-r--r--scene/resources/visual_shader.cpp215
-rw-r--r--scene/resources/visual_shader.h18
-rw-r--r--scene/resources/visual_shader_nodes.cpp449
-rw-r--r--scene/resources/visual_shader_nodes.h14
-rw-r--r--scene/resources/world_2d.cpp72
-rw-r--r--scene/resources/world_2d.h1
-rw-r--r--scene/resources/world_3d.cpp63
-rw-r--r--scene/resources/world_margin_shape_3d.cpp6
-rw-r--r--scene/resources/world_margin_shape_3d.h1
-rw-r--r--scene/scene_string_names.cpp7
-rw-r--r--scene/scene_string_names.h5
-rw-r--r--servers/audio/audio_driver_dummy.cpp32
-rw-r--r--servers/audio/audio_driver_dummy.h7
-rw-r--r--servers/audio/audio_filter_sw.cpp47
-rw-r--r--servers/audio/audio_filter_sw.h3
-rw-r--r--servers/audio/audio_rb_resampler.cpp46
-rw-r--r--servers/audio/audio_rb_resampler.h10
-rw-r--r--servers/audio/audio_stream.cpp21
-rw-r--r--servers/audio/audio_stream.h7
-rw-r--r--servers/audio/effects/audio_effect_amplify.cpp3
-rw-r--r--servers/audio/effects/audio_effect_chorus.cpp36
-rw-r--r--servers/audio/effects/audio_effect_chorus.h2
-rw-r--r--servers/audio/effects/audio_effect_compressor.cpp34
-rw-r--r--servers/audio/effects/audio_effect_delay.cpp46
-rw-r--r--servers/audio/effects/audio_effect_distortion.cpp27
-rw-r--r--servers/audio/effects/audio_effect_eq.cpp10
-rw-r--r--servers/audio/effects/audio_effect_filter.cpp32
-rw-r--r--servers/audio/effects/audio_effect_filter.h12
-rw-r--r--servers/audio/effects/audio_effect_limiter.cpp14
-rw-r--r--servers/audio/effects/audio_effect_panner.cpp4
-rw-r--r--servers/audio/effects/audio_effect_phaser.cpp16
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.cpp32
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.h1
-rw-r--r--servers/audio/effects/audio_effect_record.cpp3
-rw-r--r--servers/audio/effects/audio_effect_record.h5
-rw-r--r--servers/audio/effects/audio_effect_reverb.cpp32
-rw-r--r--servers/audio/effects/audio_effect_spectrum_analyzer.cpp12
-rw-r--r--servers/audio/effects/audio_effect_stereo_enhance.cpp14
-rw-r--r--servers/audio/effects/audio_stream_generator.cpp16
-rw-r--r--servers/audio/effects/audio_stream_generator.h1
-rw-r--r--servers/audio/effects/eq.cpp32
-rw-r--r--servers/audio/effects/eq.h3
-rw-r--r--servers/audio/effects/reverb.cpp90
-rw-r--r--servers/audio/effects/reverb.h45
-rw-r--r--servers/audio_server.cpp210
-rw-r--r--servers/audio_server.h25
-rw-r--r--servers/display_server.cpp59
-rw-r--r--servers/display_server.h12
-rw-r--r--servers/navigation_server_2d.cpp11
-rw-r--r--servers/navigation_server_3d.cpp1
-rw-r--r--servers/physics_2d/area_2d_sw.cpp111
-rw-r--r--servers/physics_2d/area_2d_sw.h30
-rw-r--r--servers/physics_2d/area_pair_2d_sw.cpp53
-rw-r--r--servers/physics_2d/area_pair_2d_sw.h2
-rw-r--r--servers/physics_2d/body_2d_sw.cpp150
-rw-r--r--servers/physics_2d/body_2d_sw.h29
-rw-r--r--servers/physics_2d/body_pair_2d_sw.cpp68
-rw-r--r--servers/physics_2d/body_pair_2d_sw.h2
-rw-r--r--servers/physics_2d/broad_phase_2d_basic.cpp42
-rw-r--r--servers/physics_2d/broad_phase_2d_basic.h3
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.cpp191
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.h7
-rw-r--r--servers/physics_2d/broad_phase_2d_sw.h1
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp47
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h2
-rw-r--r--servers/physics_2d/collision_solver_2d_sat.cpp418
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.cpp50
-rw-r--r--servers/physics_2d/constraint_2d_sw.h1
-rw-r--r--servers/physics_2d/joints_2d_sw.cpp64
-rw-r--r--servers/physics_2d/joints_2d_sw.h4
-rw-r--r--servers/physics_2d/physics_server_2d_sw.cpp233
-rw-r--r--servers/physics_2d/physics_server_2d_sw.h4
-rw-r--r--servers/physics_2d/physics_server_2d_wrap_mt.cpp22
-rw-r--r--servers/physics_2d/physics_server_2d_wrap_mt.h16
-rw-r--r--servers/physics_2d/shape_2d_sw.cpp170
-rw-r--r--servers/physics_2d/shape_2d_sw.h46
-rw-r--r--servers/physics_2d/space_2d_sw.cpp302
-rw-r--r--servers/physics_2d/space_2d_sw.h6
-rw-r--r--servers/physics_2d/step_2d_sw.cpp36
-rw-r--r--servers/physics_2d/step_2d_sw.h1
-rw-r--r--servers/physics_3d/area_3d_sw.cpp111
-rw-r--r--servers/physics_3d/area_3d_sw.h30
-rw-r--r--servers/physics_3d/area_pair_3d_sw.cpp53
-rw-r--r--servers/physics_3d/area_pair_3d_sw.h2
-rw-r--r--servers/physics_3d/body_3d_sw.cpp142
-rw-r--r--servers/physics_3d/body_3d_sw.h36
-rw-r--r--servers/physics_3d/body_pair_3d_sw.cpp41
-rw-r--r--servers/physics_3d/body_pair_3d_sw.h1
-rw-r--r--servers/physics_3d/broad_phase_3d_basic.cpp51
-rw-r--r--servers/physics_3d/broad_phase_3d_basic.h3
-rw-r--r--servers/physics_3d/broad_phase_3d_sw.h1
-rw-r--r--servers/physics_3d/broad_phase_octree.cpp25
-rw-r--r--servers/physics_3d/broad_phase_octree.h1
-rw-r--r--servers/physics_3d/collision_object_3d_sw.cpp35
-rw-r--r--servers/physics_3d/collision_object_3d_sw.h5
-rw-r--r--servers/physics_3d/collision_solver_3d_sat.cpp342
-rw-r--r--servers/physics_3d/collision_solver_3d_sw.cpp75
-rw-r--r--servers/physics_3d/constraint_3d_sw.h1
-rw-r--r--servers/physics_3d/gjk_epa.cpp104
-rw-r--r--servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp21
-rw-r--r--servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp75
-rw-r--r--servers/physics_3d/joints/generic_6dof_joint_3d_sw.h2
-rw-r--r--servers/physics_3d/joints/hinge_joint_3d_sw.cpp96
-rw-r--r--servers/physics_3d/joints/hinge_joint_3d_sw.h1
-rw-r--r--servers/physics_3d/joints/jacobian_entry_3d_sw.h2
-rw-r--r--servers/physics_3d/joints/pin_joint_3d_sw.cpp32
-rw-r--r--servers/physics_3d/joints/pin_joint_3d_sw.h1
-rw-r--r--servers/physics_3d/joints/slider_joint_3d_sw.cpp183
-rw-r--r--servers/physics_3d/joints/slider_joint_3d_sw.h10
-rw-r--r--servers/physics_3d/joints_3d_sw.h1
-rw-r--r--servers/physics_3d/physics_server_3d_sw.cpp224
-rw-r--r--servers/physics_3d/physics_server_3d_sw.h8
-rw-r--r--servers/physics_3d/shape_3d_sw.cpp277
-rw-r--r--servers/physics_3d/shape_3d_sw.h17
-rw-r--r--servers/physics_3d/space_3d_sw.cpp283
-rw-r--r--servers/physics_3d/space_3d_sw.h6
-rw-r--r--servers/physics_3d/step_3d_sw.cpp35
-rw-r--r--servers/physics_3d/step_3d_sw.h1
-rw-r--r--servers/physics_server_2d.cpp109
-rw-r--r--servers/physics_server_2d.h17
-rw-r--r--servers/physics_server_3d.cpp72
-rw-r--r--servers/physics_server_3d.h16
-rw-r--r--servers/register_server_types.cpp35
-rw-r--r--servers/rendering/rasterizer.cpp3
-rw-r--r--servers/rendering/rasterizer.h123
-rw-r--r--servers/rendering/rasterizer_rd/light_cluster_builder.cpp8
-rw-r--r--servers/rendering/rasterizer_rd/light_cluster_builder.h3
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp102
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h9
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp68
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_effects_rd.h24
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_rd.cpp16
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_rd.h7
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp341
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h58
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp333
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_scene_rd.h41
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp940
-rw-r--r--servers/rendering/rasterizer_rd/rasterizer_storage_rd.h110
-rw-r--r--servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp10
-rw-r--r--servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h10
-rw-r--r--servers/rendering/rasterizer_rd/shader_compiler_rd.cpp338
-rw-r--r--servers/rendering/rasterizer_rd/shader_compiler_rd.h3
-rw-r--r--servers/rendering/rasterizer_rd/shader_rd.cpp19
-rw-r--r--servers/rendering/rasterizer_rd/shader_rd.h1
-rw-r--r--servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl9
-rw-r--r--servers/rendering/rasterizer_rd/shaders/canvas.glsl19
-rw-r--r--servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl11
-rw-r--r--servers/rendering/rasterizer_rd/shaders/copy.glsl38
-rw-r--r--servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl17
-rw-r--r--servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl5
-rw-r--r--servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl9
-rw-r--r--servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl4
-rw-r--r--servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl7
-rw-r--r--servers/rendering/rasterizer_rd/shaders/giprobe.glsl22
-rw-r--r--servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl83
-rw-r--r--servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl12
-rw-r--r--servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl20
-rw-r--r--servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl7
-rw-r--r--servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl9
-rw-r--r--servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl184
-rw-r--r--servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl61
-rw-r--r--servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl14
-rw-r--r--servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl14
-rw-r--r--servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl13
-rw-r--r--servers/rendering/rasterizer_rd/shaders/sky.glsl11
-rw-r--r--servers/rendering/rasterizer_rd/shaders/specular_merge.glsl14
-rw-r--r--servers/rendering/rasterizer_rd/shaders/ssao.glsl7
-rw-r--r--servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl8
-rw-r--r--servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl5
-rw-r--r--servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl13
-rw-r--r--servers/rendering/rasterizer_rd/shaders/tonemap.glsl17
-rw-r--r--servers/rendering/rendering_device.cpp738
-rw-r--r--servers/rendering/rendering_device.h95
-rw-r--r--servers/rendering/rendering_device_binds.cpp205
-rw-r--r--servers/rendering/rendering_device_binds.h629
-rw-r--r--servers/rendering/rendering_server_canvas.cpp209
-rw-r--r--servers/rendering/rendering_server_canvas.h17
-rw-r--r--servers/rendering/rendering_server_raster.cpp40
-rw-r--r--servers/rendering/rendering_server_raster.h41
-rw-r--r--servers/rendering/rendering_server_scene.cpp757
-rw-r--r--servers/rendering/rendering_server_scene.h38
-rw-r--r--servers/rendering/rendering_server_viewport.cpp69
-rw-r--r--servers/rendering/rendering_server_viewport.h8
-rw-r--r--servers/rendering/rendering_server_wrap_mt.cpp22
-rw-r--r--servers/rendering/rendering_server_wrap_mt.h34
-rw-r--r--servers/rendering/shader_language.cpp948
-rw-r--r--servers/rendering/shader_language.h192
-rw-r--r--servers/rendering/shader_types.cpp3
-rw-r--r--servers/rendering/shader_types.h2
-rw-r--r--servers/rendering_server.cpp349
-rw-r--r--servers/rendering_server.h87
-rw-r--r--servers/xr/xr_interface.cpp6
-rw-r--r--servers/xr/xr_positional_tracker.cpp7
-rw-r--r--servers/xr/xr_positional_tracker.h2
-rw-r--r--servers/xr_server.cpp7
-rw-r--r--thirdparty/README.md131
-rw-r--r--thirdparty/basis_universal/basisu_enc.h1
-rw-r--r--thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.h2
-rw-r--r--thirdparty/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h11
-rw-r--r--thirdparty/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp4
-rw-r--r--thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h6
-rw-r--r--thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp22
-rw-r--r--thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h1
-rw-r--r--thirdparty/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp7
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h6
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp5
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h1
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp12
-rw-r--r--thirdparty/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp8
-rw-r--r--thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp19
-rw-r--r--thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.h43
-rw-r--r--thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp2
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp46
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h7
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp31
-rw-r--r--thirdparty/bullet/BulletSoftBody/btConjugateResidual.h188
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.cpp42
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.h43
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp78
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.h16
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.cpp184
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.h132
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.cpp641
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.h46
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableCorotatedForce.h2
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableGravityForce.h2
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableLagrangianForce.h11
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableMassSpringForce.h46
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableMousePickingForce.h145
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp8
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp187
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h156
-rw-r--r--thirdparty/bullet/BulletSoftBody/btDeformableNeoHookeanForce.h50
-rw-r--r--thirdparty/bullet/BulletSoftBody/btPreconditioner.h213
-rw-r--r--thirdparty/bullet/BulletSoftBody/btSoftBody.cpp636
-rw-r--r--thirdparty/bullet/BulletSoftBody/btSoftBody.h244
-rw-r--r--thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.cpp80
-rw-r--r--thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.h4
-rw-r--r--thirdparty/bullet/BulletSoftBody/btSoftBodyInternals.h798
-rw-r--r--thirdparty/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp3
-rw-r--r--thirdparty/bullet/BulletSoftBody/poly34.cpp419
-rw-r--r--thirdparty/bullet/BulletSoftBody/poly34.h38
-rw-r--r--thirdparty/bullet/LinearMath/btImplicitQRSVD.h4
-rw-r--r--thirdparty/bullet/LinearMath/btMatrix3x3.h16
-rw-r--r--thirdparty/bullet/LinearMath/btMatrixX.h3
-rw-r--r--thirdparty/bullet/LinearMath/btModifiedGramSchmidt.h83
-rw-r--r--thirdparty/bullet/LinearMath/btReducedVector.cpp170
-rw-r--r--thirdparty/bullet/LinearMath/btReducedVector.h320
-rw-r--r--thirdparty/bullet/btBulletCollisionAll.cpp1
-rw-r--r--thirdparty/bullet/btLinearMathAll.cpp1
-rw-r--r--thirdparty/enet/LICENSE2
-rw-r--r--thirdparty/enet/enet/enet.h11
-rw-r--r--thirdparty/enet/enet/utility.h1
-rw-r--r--thirdparty/enet/patches/dtls_support.patch13
-rw-r--r--thirdparty/enet/peer.c27
-rw-r--r--thirdparty/enet/protocol.c56
-rw-r--r--thirdparty/freetype/include/freetype/config/ftconfig.h2
-rw-r--r--thirdparty/freetype/include/freetype/config/ftheader.h2
-rw-r--r--thirdparty/freetype/include/freetype/config/ftoption.h22
-rw-r--r--thirdparty/freetype/include/freetype/config/ftstdlib.h2
-rw-r--r--thirdparty/freetype/include/freetype/freetype.h35
-rw-r--r--thirdparty/freetype/include/freetype/ftadvanc.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftbbox.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftbdf.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftbitmap.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftbzip2.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftcache.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftcid.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftcolor.h17
-rw-r--r--thirdparty/freetype/include/freetype/ftdriver.h2
-rw-r--r--thirdparty/freetype/include/freetype/fterrdef.h2
-rw-r--r--thirdparty/freetype/include/freetype/fterrors.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftfntfmt.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftgasp.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftglyph.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftgxval.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftgzip.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftimage.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftincrem.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftlcdfil.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftlist.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftlzw.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftmac.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftmm.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftmodapi.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftmoderr.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftotval.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftoutln.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftparams.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftpfr.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftrender.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftsizes.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftsnames.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftstroke.h36
-rw-r--r--thirdparty/freetype/include/freetype/ftsynth.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftsystem.h2
-rw-r--r--thirdparty/freetype/include/freetype/fttrigon.h2
-rw-r--r--thirdparty/freetype/include/freetype/fttypes.h2
-rw-r--r--thirdparty/freetype/include/freetype/ftwinfnt.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/autohint.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/cffotypes.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/cfftypes.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftcalc.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftdebug.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftdrv.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftgloadr.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftmemory.h18
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftobjs.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftpsprop.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftrfork.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftserv.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftstream.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/fttrace.h3
-rw-r--r--thirdparty/freetype/include/freetype/internal/ftvalid.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/internal.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/psaux.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/pshints.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svbdf.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svcfftl.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svcid.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svfntfmt.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svgldict.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svgxval.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svkern.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svmetric.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svmm.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svotval.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svpfr.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svpostnm.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svprop.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svpscmap.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svpsinfo.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svsfnt.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svttcmap.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svtteng.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svttglyf.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/services/svwinfnt.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/sfnt.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/t1types.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/tttypes.h2
-rw-r--r--thirdparty/freetype/include/freetype/internal/wofftypes.h203
-rw-r--r--thirdparty/freetype/include/freetype/t1tables.h2
-rw-r--r--thirdparty/freetype/include/freetype/ttnameid.h2
-rw-r--r--thirdparty/freetype/include/freetype/tttables.h2
-rw-r--r--thirdparty/freetype/include/freetype/tttags.h3
-rw-r--r--thirdparty/freetype/include/ft2build.h2
-rw-r--r--thirdparty/freetype/src/autofit/afangles.c2
-rw-r--r--thirdparty/freetype/src/autofit/afblue.c12
-rw-r--r--thirdparty/freetype/src/autofit/afblue.cin2
-rw-r--r--thirdparty/freetype/src/autofit/afblue.dat15
-rw-r--r--thirdparty/freetype/src/autofit/afblue.h88
-rw-r--r--thirdparty/freetype/src/autofit/afblue.hin2
-rw-r--r--thirdparty/freetype/src/autofit/afcjk.c4
-rw-r--r--thirdparty/freetype/src/autofit/afcjk.h2
-rw-r--r--thirdparty/freetype/src/autofit/afcover.h2
-rw-r--r--thirdparty/freetype/src/autofit/afdummy.c2
-rw-r--r--thirdparty/freetype/src/autofit/afdummy.h2
-rw-r--r--thirdparty/freetype/src/autofit/aferrors.h2
-rw-r--r--thirdparty/freetype/src/autofit/afglobal.c2
-rw-r--r--thirdparty/freetype/src/autofit/afglobal.h2
-rw-r--r--thirdparty/freetype/src/autofit/afhints.c2
-rw-r--r--thirdparty/freetype/src/autofit/afhints.h2
-rw-r--r--thirdparty/freetype/src/autofit/afindic.c2
-rw-r--r--thirdparty/freetype/src/autofit/afindic.h2
-rw-r--r--thirdparty/freetype/src/autofit/aflatin.c6
-rw-r--r--thirdparty/freetype/src/autofit/aflatin.h2
-rw-r--r--thirdparty/freetype/src/autofit/aflatin2.c3
-rw-r--r--thirdparty/freetype/src/autofit/aflatin2.h2
-rw-r--r--thirdparty/freetype/src/autofit/afloader.c2
-rw-r--r--thirdparty/freetype/src/autofit/afloader.h2
-rw-r--r--thirdparty/freetype/src/autofit/afmodule.c2
-rw-r--r--thirdparty/freetype/src/autofit/afmodule.h2
-rw-r--r--thirdparty/freetype/src/autofit/afranges.c14
-rw-r--r--thirdparty/freetype/src/autofit/afranges.h2
-rw-r--r--thirdparty/freetype/src/autofit/afscript.h8
-rw-r--r--thirdparty/freetype/src/autofit/afshaper.c2
-rw-r--r--thirdparty/freetype/src/autofit/afshaper.h2
-rw-r--r--thirdparty/freetype/src/autofit/afstyles.h9
-rw-r--r--thirdparty/freetype/src/autofit/aftypes.h2
-rw-r--r--thirdparty/freetype/src/autofit/afwarp.c2
-rw-r--r--thirdparty/freetype/src/autofit/afwarp.h2
-rw-r--r--thirdparty/freetype/src/autofit/afwrtsys.h2
-rw-r--r--thirdparty/freetype/src/autofit/autofit.c2
-rw-r--r--thirdparty/freetype/src/autofit/module.mk2
-rw-r--r--thirdparty/freetype/src/autofit/rules.mk2
-rw-r--r--thirdparty/freetype/src/base/ftadvanc.c2
-rw-r--r--thirdparty/freetype/src/base/ftbase.c2
-rw-r--r--thirdparty/freetype/src/base/ftbase.h2
-rw-r--r--thirdparty/freetype/src/base/ftbbox.c10
-rw-r--r--thirdparty/freetype/src/base/ftbdf.c2
-rw-r--r--thirdparty/freetype/src/base/ftbitmap.c2
-rw-r--r--thirdparty/freetype/src/base/ftcalc.c2
-rw-r--r--thirdparty/freetype/src/base/ftcid.c2
-rw-r--r--thirdparty/freetype/src/base/ftcolor.c2
-rw-r--r--thirdparty/freetype/src/base/ftdbgmem.c8
-rw-r--r--thirdparty/freetype/src/base/ftdebug.c2
-rw-r--r--thirdparty/freetype/src/base/fterrors.c2
-rw-r--r--thirdparty/freetype/src/base/ftfntfmt.c2
-rw-r--r--thirdparty/freetype/src/base/ftfstype.c2
-rw-r--r--thirdparty/freetype/src/base/ftgasp.c2
-rw-r--r--thirdparty/freetype/src/base/ftgloadr.c22
-rw-r--r--thirdparty/freetype/src/base/ftglyph.c2
-rw-r--r--thirdparty/freetype/src/base/ftgxval.c2
-rw-r--r--thirdparty/freetype/src/base/ftinit.c2
-rw-r--r--thirdparty/freetype/src/base/ftlcdfil.c2
-rw-r--r--thirdparty/freetype/src/base/ftmac.c2
-rw-r--r--thirdparty/freetype/src/base/ftmm.c2
-rw-r--r--thirdparty/freetype/src/base/ftobjs.c2
-rw-r--r--thirdparty/freetype/src/base/ftotval.c2
-rw-r--r--thirdparty/freetype/src/base/ftoutln.c4
-rw-r--r--thirdparty/freetype/src/base/ftpatent.c2
-rw-r--r--thirdparty/freetype/src/base/ftpfr.c2
-rw-r--r--thirdparty/freetype/src/base/ftpsprop.c6
-rw-r--r--thirdparty/freetype/src/base/ftrfork.c2
-rw-r--r--thirdparty/freetype/src/base/ftsnames.c2
-rw-r--r--thirdparty/freetype/src/base/ftstream.c4
-rw-r--r--thirdparty/freetype/src/base/ftstroke.c215
-rw-r--r--thirdparty/freetype/src/base/ftsynth.c2
-rw-r--r--thirdparty/freetype/src/base/ftsystem.c2
-rw-r--r--thirdparty/freetype/src/base/fttrigon.c2
-rw-r--r--thirdparty/freetype/src/base/fttype1.c2
-rw-r--r--thirdparty/freetype/src/base/ftutil.c2
-rw-r--r--thirdparty/freetype/src/base/ftver.rc8
-rw-r--r--thirdparty/freetype/src/base/ftwinfnt.c2
-rw-r--r--thirdparty/freetype/src/base/rules.mk2
-rw-r--r--thirdparty/freetype/src/bzip2/ftbzip2.c2
-rw-r--r--thirdparty/freetype/src/bzip2/rules.mk2
-rw-r--r--thirdparty/freetype/src/cache/ftcache.c2
-rw-r--r--thirdparty/freetype/src/cache/ftcbasic.c2
-rw-r--r--thirdparty/freetype/src/cache/ftccache.c2
-rw-r--r--thirdparty/freetype/src/cache/ftccache.h2
-rw-r--r--thirdparty/freetype/src/cache/ftccback.h2
-rw-r--r--thirdparty/freetype/src/cache/ftccmap.c2
-rw-r--r--thirdparty/freetype/src/cache/ftcerror.h2
-rw-r--r--thirdparty/freetype/src/cache/ftcglyph.c2
-rw-r--r--thirdparty/freetype/src/cache/ftcglyph.h2
-rw-r--r--thirdparty/freetype/src/cache/ftcimage.c2
-rw-r--r--thirdparty/freetype/src/cache/ftcimage.h2
-rw-r--r--thirdparty/freetype/src/cache/ftcmanag.c2
-rw-r--r--thirdparty/freetype/src/cache/ftcmanag.h2
-rw-r--r--thirdparty/freetype/src/cache/ftcmru.c2
-rw-r--r--thirdparty/freetype/src/cache/ftcmru.h2
-rw-r--r--thirdparty/freetype/src/cache/ftcsbits.c2
-rw-r--r--thirdparty/freetype/src/cache/ftcsbits.h2
-rw-r--r--thirdparty/freetype/src/cache/rules.mk2
-rw-r--r--thirdparty/freetype/src/cff/cff.c2
-rw-r--r--thirdparty/freetype/src/cff/cffcmap.c2
-rw-r--r--thirdparty/freetype/src/cff/cffcmap.h2
-rw-r--r--thirdparty/freetype/src/cff/cffdrivr.c2
-rw-r--r--thirdparty/freetype/src/cff/cffdrivr.h2
-rw-r--r--thirdparty/freetype/src/cff/cfferrs.h2
-rw-r--r--thirdparty/freetype/src/cff/cffgload.c2
-rw-r--r--thirdparty/freetype/src/cff/cffgload.h2
-rw-r--r--thirdparty/freetype/src/cff/cffload.c4
-rw-r--r--thirdparty/freetype/src/cff/cffload.h2
-rw-r--r--thirdparty/freetype/src/cff/cffobjs.c8
-rw-r--r--thirdparty/freetype/src/cff/cffobjs.h2
-rw-r--r--thirdparty/freetype/src/cff/cffparse.c2
-rw-r--r--thirdparty/freetype/src/cff/cffparse.h2
-rw-r--r--thirdparty/freetype/src/cff/cfftoken.h2
-rw-r--r--thirdparty/freetype/src/cff/module.mk2
-rw-r--r--thirdparty/freetype/src/cff/rules.mk2
-rw-r--r--thirdparty/freetype/src/cid/ciderrs.h2
-rw-r--r--thirdparty/freetype/src/cid/cidgload.c2
-rw-r--r--thirdparty/freetype/src/cid/cidgload.h2
-rw-r--r--thirdparty/freetype/src/cid/cidload.c4
-rw-r--r--thirdparty/freetype/src/cid/cidload.h2
-rw-r--r--thirdparty/freetype/src/cid/cidobjs.c2
-rw-r--r--thirdparty/freetype/src/cid/cidobjs.h2
-rw-r--r--thirdparty/freetype/src/cid/cidparse.c2
-rw-r--r--thirdparty/freetype/src/cid/cidparse.h2
-rw-r--r--thirdparty/freetype/src/cid/cidriver.c2
-rw-r--r--thirdparty/freetype/src/cid/cidriver.h2
-rw-r--r--thirdparty/freetype/src/cid/cidtoken.h2
-rw-r--r--thirdparty/freetype/src/cid/module.mk2
-rw-r--r--thirdparty/freetype/src/cid/rules.mk2
-rw-r--r--thirdparty/freetype/src/cid/type1cid.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/README2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvalid.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvalid.h2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvbsln.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvcommn.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvcommn.h2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxverror.h2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvfeat.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvfeat.h2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvfgen.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvjust.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvkern.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvlcar.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmod.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmod.h2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmort.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmort.h2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmort0.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmort1.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmort2.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmort4.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmort5.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmorx.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmorx.h2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmorx0.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmorx1.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmorx2.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmorx4.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvmorx5.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvopbd.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvprop.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/gxvtrak.c2
-rw-r--r--thirdparty/freetype/src/gxvalid/module.mk2
-rw-r--r--thirdparty/freetype/src/gxvalid/rules.mk2
-rw-r--r--thirdparty/freetype/src/gzip/ftgzip.c12
-rw-r--r--thirdparty/freetype/src/gzip/infutil.h2
-rw-r--r--thirdparty/freetype/src/gzip/rules.mk2
-rw-r--r--thirdparty/freetype/src/lzw/ftlzw.c2
-rw-r--r--thirdparty/freetype/src/lzw/ftzopen.c2
-rw-r--r--thirdparty/freetype/src/lzw/ftzopen.h2
-rw-r--r--thirdparty/freetype/src/lzw/rules.mk2
-rw-r--r--thirdparty/freetype/src/otvalid/module.mk2
-rw-r--r--thirdparty/freetype/src/otvalid/otvalid.c2
-rw-r--r--thirdparty/freetype/src/otvalid/otvalid.h2
-rw-r--r--thirdparty/freetype/src/otvalid/otvbase.c2
-rw-r--r--thirdparty/freetype/src/otvalid/otvcommn.c5
-rw-r--r--thirdparty/freetype/src/otvalid/otvcommn.h2
-rw-r--r--thirdparty/freetype/src/otvalid/otverror.h2
-rw-r--r--thirdparty/freetype/src/otvalid/otvgdef.c2
-rw-r--r--thirdparty/freetype/src/otvalid/otvgpos.c2
-rw-r--r--thirdparty/freetype/src/otvalid/otvgpos.h2
-rw-r--r--thirdparty/freetype/src/otvalid/otvgsub.c2
-rw-r--r--thirdparty/freetype/src/otvalid/otvjstf.c2
-rw-r--r--thirdparty/freetype/src/otvalid/otvmath.c2
-rw-r--r--thirdparty/freetype/src/otvalid/otvmod.c2
-rw-r--r--thirdparty/freetype/src/otvalid/otvmod.h2
-rw-r--r--thirdparty/freetype/src/otvalid/rules.mk2
-rw-r--r--thirdparty/freetype/src/pfr/module.mk2
-rw-r--r--thirdparty/freetype/src/pfr/pfr.c2
-rw-r--r--thirdparty/freetype/src/pfr/pfrcmap.c2
-rw-r--r--thirdparty/freetype/src/pfr/pfrcmap.h2
-rw-r--r--thirdparty/freetype/src/pfr/pfrdrivr.c2
-rw-r--r--thirdparty/freetype/src/pfr/pfrdrivr.h2
-rw-r--r--thirdparty/freetype/src/pfr/pfrerror.h2
-rw-r--r--thirdparty/freetype/src/pfr/pfrgload.c2
-rw-r--r--thirdparty/freetype/src/pfr/pfrgload.h2
-rw-r--r--thirdparty/freetype/src/pfr/pfrload.c2
-rw-r--r--thirdparty/freetype/src/pfr/pfrload.h2
-rw-r--r--thirdparty/freetype/src/pfr/pfrobjs.c2
-rw-r--r--thirdparty/freetype/src/pfr/pfrobjs.h2
-rw-r--r--thirdparty/freetype/src/pfr/pfrsbit.c2
-rw-r--r--thirdparty/freetype/src/pfr/pfrsbit.h2
-rw-r--r--thirdparty/freetype/src/pfr/pfrtypes.h2
-rw-r--r--thirdparty/freetype/src/pfr/rules.mk2
-rw-r--r--thirdparty/freetype/src/psaux/afmparse.c2
-rw-r--r--thirdparty/freetype/src/psaux/afmparse.h2
-rw-r--r--thirdparty/freetype/src/psaux/cffdecode.c7
-rw-r--r--thirdparty/freetype/src/psaux/cffdecode.h2
-rw-r--r--thirdparty/freetype/src/psaux/module.mk2
-rw-r--r--thirdparty/freetype/src/psaux/psaux.c2
-rw-r--r--thirdparty/freetype/src/psaux/psauxerr.h2
-rw-r--r--thirdparty/freetype/src/psaux/psauxmod.c2
-rw-r--r--thirdparty/freetype/src/psaux/psauxmod.h2
-rw-r--r--thirdparty/freetype/src/psaux/psconv.c2
-rw-r--r--thirdparty/freetype/src/psaux/psconv.h2
-rw-r--r--thirdparty/freetype/src/psaux/psft.c8
-rw-r--r--thirdparty/freetype/src/psaux/psintrp.c22
-rw-r--r--thirdparty/freetype/src/psaux/psobjs.c6
-rw-r--r--thirdparty/freetype/src/psaux/psobjs.h2
-rw-r--r--thirdparty/freetype/src/psaux/rules.mk2
-rw-r--r--thirdparty/freetype/src/psaux/t1cmap.c2
-rw-r--r--thirdparty/freetype/src/psaux/t1cmap.h2
-rw-r--r--thirdparty/freetype/src/psaux/t1decode.c85
-rw-r--r--thirdparty/freetype/src/psaux/t1decode.h2
-rw-r--r--thirdparty/freetype/src/pshinter/module.mk2
-rw-r--r--thirdparty/freetype/src/pshinter/pshalgo.c2
-rw-r--r--thirdparty/freetype/src/pshinter/pshalgo.h2
-rw-r--r--thirdparty/freetype/src/pshinter/pshglob.c2
-rw-r--r--thirdparty/freetype/src/pshinter/pshglob.h2
-rw-r--r--thirdparty/freetype/src/pshinter/pshinter.c2
-rw-r--r--thirdparty/freetype/src/pshinter/pshmod.c2
-rw-r--r--thirdparty/freetype/src/pshinter/pshmod.h2
-rw-r--r--thirdparty/freetype/src/pshinter/pshnterr.h2
-rw-r--r--thirdparty/freetype/src/pshinter/pshrec.c2
-rw-r--r--thirdparty/freetype/src/pshinter/pshrec.h2
-rw-r--r--thirdparty/freetype/src/pshinter/rules.mk2
-rw-r--r--thirdparty/freetype/src/psnames/module.mk2
-rw-r--r--thirdparty/freetype/src/psnames/psmodule.c2
-rw-r--r--thirdparty/freetype/src/psnames/psmodule.h2
-rw-r--r--thirdparty/freetype/src/psnames/psnamerr.h2
-rw-r--r--thirdparty/freetype/src/psnames/psnames.c2
-rw-r--r--thirdparty/freetype/src/psnames/pstables.h2
-rw-r--r--thirdparty/freetype/src/psnames/rules.mk2
-rw-r--r--thirdparty/freetype/src/raster/ftmisc.h2
-rw-r--r--thirdparty/freetype/src/raster/ftraster.c2
-rw-r--r--thirdparty/freetype/src/raster/ftraster.h2
-rw-r--r--thirdparty/freetype/src/raster/ftrend1.c2
-rw-r--r--thirdparty/freetype/src/raster/ftrend1.h2
-rw-r--r--thirdparty/freetype/src/raster/module.mk2
-rw-r--r--thirdparty/freetype/src/raster/raster.c2
-rw-r--r--thirdparty/freetype/src/raster/rasterrs.h2
-rw-r--r--thirdparty/freetype/src/raster/rules.mk2
-rw-r--r--thirdparty/freetype/src/sfnt/module.mk2
-rw-r--r--thirdparty/freetype/src/sfnt/pngshim.c3
-rw-r--r--thirdparty/freetype/src/sfnt/pngshim.h2
-rw-r--r--thirdparty/freetype/src/sfnt/rules.mk30
-rw-r--r--thirdparty/freetype/src/sfnt/sfdriver.c2
-rw-r--r--thirdparty/freetype/src/sfnt/sfdriver.h2
-rw-r--r--thirdparty/freetype/src/sfnt/sferrors.h2
-rw-r--r--thirdparty/freetype/src/sfnt/sfnt.c4
-rw-r--r--thirdparty/freetype/src/sfnt/sfobjs.c38
-rw-r--r--thirdparty/freetype/src/sfnt/sfobjs.h2
-rw-r--r--thirdparty/freetype/src/sfnt/sfwoff.c12
-rw-r--r--thirdparty/freetype/src/sfnt/sfwoff.h2
-rw-r--r--thirdparty/freetype/src/sfnt/sfwoff2.c2328
-rw-r--r--thirdparty/freetype/src/sfnt/sfwoff2.h76
-rw-r--r--thirdparty/freetype/src/sfnt/ttbdf.c2
-rw-r--r--thirdparty/freetype/src/sfnt/ttbdf.h2
-rw-r--r--thirdparty/freetype/src/sfnt/ttcmap.c29
-rw-r--r--thirdparty/freetype/src/sfnt/ttcmap.h2
-rw-r--r--thirdparty/freetype/src/sfnt/ttcmapc.h2
-rw-r--r--thirdparty/freetype/src/sfnt/ttcolr.c2
-rw-r--r--thirdparty/freetype/src/sfnt/ttcolr.h2
-rw-r--r--thirdparty/freetype/src/sfnt/ttcpal.c2
-rw-r--r--thirdparty/freetype/src/sfnt/ttcpal.h2
-rw-r--r--thirdparty/freetype/src/sfnt/ttkern.c2
-rw-r--r--thirdparty/freetype/src/sfnt/ttkern.h2
-rw-r--r--thirdparty/freetype/src/sfnt/ttload.c12
-rw-r--r--thirdparty/freetype/src/sfnt/ttload.h2
-rw-r--r--thirdparty/freetype/src/sfnt/ttmtx.c2
-rw-r--r--thirdparty/freetype/src/sfnt/ttmtx.h2
-rw-r--r--thirdparty/freetype/src/sfnt/ttpost.c2
-rw-r--r--thirdparty/freetype/src/sfnt/ttpost.h2
-rw-r--r--thirdparty/freetype/src/sfnt/ttsbit.c2
-rw-r--r--thirdparty/freetype/src/sfnt/ttsbit.h2
-rw-r--r--thirdparty/freetype/src/sfnt/woff2tags.c110
-rw-r--r--thirdparty/freetype/src/sfnt/woff2tags.h39
-rw-r--r--thirdparty/freetype/src/smooth/ftgrays.c2
-rw-r--r--thirdparty/freetype/src/smooth/ftgrays.h2
-rw-r--r--thirdparty/freetype/src/smooth/ftsmerrs.h2
-rw-r--r--thirdparty/freetype/src/smooth/ftsmooth.c9
-rw-r--r--thirdparty/freetype/src/smooth/ftsmooth.h2
-rw-r--r--thirdparty/freetype/src/smooth/module.mk2
-rw-r--r--thirdparty/freetype/src/smooth/rules.mk2
-rw-r--r--thirdparty/freetype/src/smooth/smooth.c2
-rw-r--r--thirdparty/freetype/src/truetype/module.mk2
-rw-r--r--thirdparty/freetype/src/truetype/rules.mk2
-rw-r--r--thirdparty/freetype/src/truetype/truetype.c2
-rw-r--r--thirdparty/freetype/src/truetype/ttdriver.c2
-rw-r--r--thirdparty/freetype/src/truetype/ttdriver.h2
-rw-r--r--thirdparty/freetype/src/truetype/tterrors.h2
-rw-r--r--thirdparty/freetype/src/truetype/ttgload.c34
-rw-r--r--thirdparty/freetype/src/truetype/ttgload.h2
-rw-r--r--thirdparty/freetype/src/truetype/ttgxvar.c133
-rw-r--r--thirdparty/freetype/src/truetype/ttgxvar.h2
-rw-r--r--thirdparty/freetype/src/truetype/ttinterp.c33
-rw-r--r--thirdparty/freetype/src/truetype/ttinterp.h2
-rw-r--r--thirdparty/freetype/src/truetype/ttobjs.c2
-rw-r--r--thirdparty/freetype/src/truetype/ttobjs.h2
-rw-r--r--thirdparty/freetype/src/truetype/ttpload.c4
-rw-r--r--thirdparty/freetype/src/truetype/ttpload.h2
-rw-r--r--thirdparty/freetype/src/truetype/ttsubpix.c2
-rw-r--r--thirdparty/freetype/src/truetype/ttsubpix.h2
-rw-r--r--thirdparty/freetype/src/type1/module.mk2
-rw-r--r--thirdparty/freetype/src/type1/rules.mk2
-rw-r--r--thirdparty/freetype/src/type1/t1afm.c2
-rw-r--r--thirdparty/freetype/src/type1/t1afm.h2
-rw-r--r--thirdparty/freetype/src/type1/t1driver.c2
-rw-r--r--thirdparty/freetype/src/type1/t1driver.h2
-rw-r--r--thirdparty/freetype/src/type1/t1errors.h2
-rw-r--r--thirdparty/freetype/src/type1/t1gload.c2
-rw-r--r--thirdparty/freetype/src/type1/t1gload.h2
-rw-r--r--thirdparty/freetype/src/type1/t1load.c44
-rw-r--r--thirdparty/freetype/src/type1/t1load.h2
-rw-r--r--thirdparty/freetype/src/type1/t1objs.c2
-rw-r--r--thirdparty/freetype/src/type1/t1objs.h2
-rw-r--r--thirdparty/freetype/src/type1/t1parse.c2
-rw-r--r--thirdparty/freetype/src/type1/t1parse.h2
-rw-r--r--thirdparty/freetype/src/type1/t1tokens.h2
-rw-r--r--thirdparty/freetype/src/type1/type1.c2
-rw-r--r--thirdparty/freetype/src/type42/module.mk2
-rw-r--r--thirdparty/freetype/src/type42/rules.mk2
-rw-r--r--thirdparty/freetype/src/type42/t42drivr.c2
-rw-r--r--thirdparty/freetype/src/type42/t42drivr.h2
-rw-r--r--thirdparty/freetype/src/type42/t42error.h2
-rw-r--r--thirdparty/freetype/src/type42/t42objs.c2
-rw-r--r--thirdparty/freetype/src/type42/t42objs.h2
-rw-r--r--thirdparty/freetype/src/type42/t42parse.c2
-rw-r--r--thirdparty/freetype/src/type42/t42parse.h2
-rw-r--r--thirdparty/freetype/src/type42/t42types.h2
-rw-r--r--thirdparty/freetype/src/type42/type42.c2
-rw-r--r--thirdparty/freetype/src/winfonts/fnterrs.h2
-rw-r--r--thirdparty/freetype/src/winfonts/module.mk2
-rw-r--r--thirdparty/freetype/src/winfonts/rules.mk2
-rw-r--r--thirdparty/freetype/src/winfonts/winfnt.c8
-rw-r--r--thirdparty/freetype/src/winfonts/winfnt.h2
-rw-r--r--thirdparty/jpeg-compressor/jpgd.cpp6252
-rw-r--r--thirdparty/jpeg-compressor/jpgd.h634
-rw-r--r--thirdparty/jpeg-compressor/jpgd_idct.h462
-rw-r--r--thirdparty/mbedtls/include/mbedtls/check_config.h21
-rw-r--r--thirdparty/mbedtls/include/mbedtls/version.h8
-rw-r--r--thirdparty/mbedtls/library/ecp.c28
-rw-r--r--thirdparty/mbedtls/library/ssl_cli.c16
-rw-r--r--thirdparty/mbedtls/library/ssl_tls.c34
-rw-r--r--thirdparty/mbedtls/library/x509.c2
-rw-r--r--thirdparty/misc/cubemap_coeffs.h4
-rw-r--r--thirdparty/misc/curl_hostcheck.c217
-rw-r--r--thirdparty/misc/curl_hostcheck.h39
-rw-r--r--thirdparty/misc/fastlz.c796
-rw-r--r--thirdparty/misc/fastlz.h60
-rw-r--r--thirdparty/misc/hq2x.cpp2636
-rw-r--r--thirdparty/misc/hq2x.h19
-rw-r--r--thirdparty/misc/r128.c2
-rw-r--r--thirdparty/misc/r128.h2123
-rw-r--r--thirdparty/misc/stb_rect_pack.h628
-rw-r--r--thirdparty/misc/stb_vorbis.c219
-rw-r--r--thirdparty/oidn/0001-window.h-case-sensitive.patch13
-rw-r--r--thirdparty/oidn/LICENSE.txt202
-rw-r--r--thirdparty/oidn/common/barrier.h52
-rw-r--r--thirdparty/oidn/common/exception.h45
-rw-r--r--thirdparty/oidn/common/platform.cpp114
-rw-r--r--thirdparty/oidn/common/platform.h131
-rw-r--r--thirdparty/oidn/common/ref.h163
-rw-r--r--thirdparty/oidn/common/tensor.cpp83
-rw-r--r--thirdparty/oidn/common/tensor.h66
-rw-r--r--thirdparty/oidn/common/thread.cpp297
-rw-r--r--thirdparty/oidn/common/thread.h202
-rw-r--r--thirdparty/oidn/common/timer.h49
-rw-r--r--thirdparty/oidn/core/api.cpp408
-rw-r--r--thirdparty/oidn/core/autoencoder.cpp519
-rw-r--r--thirdparty/oidn/core/autoencoder.h116
-rw-r--r--thirdparty/oidn/core/buffer.h75
-rw-r--r--thirdparty/oidn/core/common.h133
-rw-r--r--thirdparty/oidn/core/device.cpp205
-rw-r--r--thirdparty/oidn/core/device.h78
-rw-r--r--thirdparty/oidn/core/filter.cpp27
-rw-r--r--thirdparty/oidn/core/filter.h52
-rw-r--r--thirdparty/oidn/core/image.h111
-rw-r--r--thirdparty/oidn/core/input_reorder.h232
-rw-r--r--thirdparty/oidn/core/math.h78
-rw-r--r--thirdparty/oidn/core/network.cpp434
-rw-r--r--thirdparty/oidn/core/network.h112
-rw-r--r--thirdparty/oidn/core/node.h142
-rw-r--r--thirdparty/oidn/core/output_reorder.h126
-rw-r--r--thirdparty/oidn/core/transfer_function.cpp95
-rw-r--r--thirdparty/oidn/core/transfer_function.h201
-rw-r--r--thirdparty/oidn/core/upsample.h92
-rw-r--r--thirdparty/oidn/core/weights_reorder.h99
-rw-r--r--thirdparty/oidn/include/OpenImageDenoise/oidn.h214
-rw-r--r--thirdparty/oidn/include/OpenImageDenoise/oidn.hpp468
-rw-r--r--thirdparty/oidn/include/OpenImageDenoise/version.h23
-rw-r--r--thirdparty/oidn/mkl-dnn/LICENSE214
-rw-r--r--thirdparty/oidn/mkl-dnn/include/mkldnn.h1771
-rw-r--r--thirdparty/oidn/mkl-dnn/include/mkldnn.hpp2615
-rw-r--r--thirdparty/oidn/mkl-dnn/include/mkldnn_debug.h98
-rw-r--r--thirdparty/oidn/mkl-dnn/include/mkldnn_types.h1415
-rw-r--r--thirdparty/oidn/mkl-dnn/include/mkldnn_version.h32
-rw-r--r--thirdparty/oidn/mkl-dnn/include/mkldnn_version.h.in32
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/batch_normalization.cpp104
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/batch_normalization_pd.hpp240
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/c_types_map.hpp550
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/concat.cpp86
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/concat_pd.hpp211
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/convolution.cpp200
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/convolution_pd.cpp56
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/convolution_pd.hpp348
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/deconvolution.cpp188
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/deconvolution_pd.hpp293
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/eltwise.cpp84
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/eltwise_pd.hpp161
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/engine.cpp75
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/engine.hpp119
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/inner_product.cpp106
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/inner_product_pd.cpp56
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/inner_product_pd.hpp321
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/lrn.cpp91
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/lrn_pd.hpp170
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/math_utils.hpp280
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/memory.cpp238
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/memory.hpp63
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/memory_desc_wrapper.cpp212
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/memory_desc_wrapper.hpp400
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/memory_tracking.hpp295
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/mkldnn_debug.cpp131
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/mkldnn_debug_autogenerated.cpp365
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/mkldnn_thread.hpp115
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/mkldnn_thread_parallel_nd.hpp277
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/mkldnn_traits.hpp77
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/nstl.hpp193
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/pooling.cpp114
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/pooling_pd.hpp238
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/primitive.cpp103
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/primitive.hpp76
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/primitive_attr.cpp290
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/primitive_attr.hpp183
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/primitive_desc.cpp78
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/primitive_desc.hpp174
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/primitive_exec_types.cpp90
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/primitive_exec_types.hpp68
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/primitive_iterator.cpp89
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/primitive_iterator.hpp79
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/query.cpp59
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/reorder.cpp68
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/reorder_pd.hpp85
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/rnn.cpp400
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/rnn_pd.hpp280
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/scratchpad.cpp112
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/scratchpad.hpp36
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/shuffle.cpp72
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/shuffle_pd.hpp121
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/softmax.cpp68
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/softmax_pd.hpp161
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/stream.cpp46
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/stream.hpp44
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/sum.cpp79
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/sum_pd.hpp143
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/tag_traits.hpp200
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/type_helpers.hpp348
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/utils.cpp135
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/utils.hpp370
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/verbose.cpp665
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/verbose.hpp62
-rw-r--r--thirdparty/oidn/mkl-dnn/src/common/z_magic.hpp46
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_barrier.cpp112
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_barrier.hpp60
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_pd.hpp40
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_utils.cpp140
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_utils.hpp43
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_concat.cpp51
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_concat_pd.hpp41
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_convolution_pd.hpp74
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_deconvolution_pd.hpp46
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_eltwise_pd.hpp45
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_engine.cpp324
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_engine.hpp70
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_inner_product_pd.hpp84
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_isa_traits.hpp151
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_lrn_pd.hpp42
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_memory.cpp277
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_memory.hpp89
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_pooling_pd.hpp40
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_primitive.hpp83
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_reducer.cpp544
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_reducer.hpp334
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_reorder.cpp262
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_reorder_pd.hpp48
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_shuffle_pd.hpp41
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_softmax_pd.hpp45
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_sum.cpp48
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/cpu_sum_pd.hpp39
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/gemm_utils_f32.cpp372
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/gemm_utils_f32.hpp72
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx512_common_gemm_f32.cpp2131
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx512_common_gemm_f32.hpp36
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx_gemm_f32.cpp2705
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx_gemm_f32.hpp37
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/ref_gemm_f32.cpp346
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/ref_gemm_f32.hpp36
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp280
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.hpp58
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/os_blas.hpp86
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/common.hpp206
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/gemv.hpp28
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32.cpp1409
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32.hpp38
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32_kern.cpp539
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32_kern.hpp101
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemv_s8u8s32.cpp290
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_kernel_gemv_s8u8s32_kern.cpp411
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_kernel_gemv_s8u8s32_kern.hpp64
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_an_kern.cpp819
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_at_kern.cpp2209
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_bn_kern.cpp564
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_bt_kern.cpp501
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_an_kern.cpp1283
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_at_kern.cpp3163
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_bn_kern.cpp821
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_bt_kern.cpp647
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/ref_gemm_s8x8s32.cpp116
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/ref_gemm_s8x8s32.hpp38
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/simple_gemm_s8s8s32.cpp180
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/simple_gemm_s8s8s32.hpp37
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution.cpp307
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution.hpp250
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution_utils.cpp771
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution_utils.hpp66
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm_inner_product.cpp156
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm_inner_product.hpp157
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_convolution.cpp740
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_convolution.hpp266
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_inner_product.cpp453
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_inner_product.hpp166
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_conv_kernel_f32.cpp674
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_conv_kernel_f32.hpp110
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_convolution.cpp545
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_convolution.hpp344
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.cpp1501
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.hpp225
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_convolution.cpp410
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_convolution.hpp302
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_conv_kernel.cpp1255
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_conv_kernel.hpp108
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_convolution.cpp816
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_convolution.hpp344
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_kernel.cpp4539
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_kernel.hpp423
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_winograd_kernel_f32.cpp1163
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_winograd_kernel_f32.hpp179
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution.cpp1526
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution.hpp302
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution_winograd.cpp1215
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution_winograd.hpp318
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_lrn.cpp853
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_lrn.hpp96
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_2x3.cpp1103
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_2x3.hpp144
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3.cpp1020
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3.hpp386
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3_kernel.cpp2596
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3_kernel.hpp291
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_u8s8s32x_wino_convolution.cpp1284
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_u8s8s32x_wino_convolution.hpp128
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_conv_kernel.cpp820
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_conv_kernel.hpp131
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_convolution.cpp292
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_convolution.hpp159
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_deconvolution.hpp140
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_conv_kernel.cpp1182
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_conv_kernel.hpp239
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_convolution.cpp423
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_convolution.hpp115
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_deconvolution.cpp1034
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_deconvolution.hpp237
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_generator.hpp773
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_primitive_conf.hpp481
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_conv_kernel_f32.cpp677
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_conv_kernel_f32.hpp104
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_convolution.cpp134
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_convolution.hpp96
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_conv_kernel_f32.cpp497
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_conv_kernel_f32.hpp93
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_convolution.cpp136
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_convolution.hpp103
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_transpose_src_utils.cpp1192
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_transpose_src_utils.hpp145
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_1x1_conv_utils.hpp327
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_batch_normalization.cpp1407
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_batch_normalization.hpp100
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_conv_kernel_f32.cpp1302
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_conv_kernel_f32.hpp253
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_convolution.cpp427
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_convolution.hpp266
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_eltwise.cpp1142
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_eltwise.hpp193
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_i8i8_pooling.cpp949
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_i8i8_pooling.hpp89
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn.cpp305
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn.hpp103
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn_kernel_f32.cpp1487
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn_kernel_f32.hpp183
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pool_kernel_f32.cpp699
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pool_kernel_f32.hpp192
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pooling.cpp264
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pooling.hpp182
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder.cpp1006
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder.hpp127
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder_utils.cpp313
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jit_utils.cpp115
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jit_utils.hpp32
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/LICENSE.BSD27
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/README.md1
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/ittnotify_config.h595
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/ittnotify_types.h94
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/jitprofiling.c293
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/jitprofiling.h673
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/nchw_pooling.cpp317
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/nchw_pooling.hpp147
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ncsp_batch_normalization.cpp382
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ncsp_batch_normalization.hpp160
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/nhwc_pooling.cpp392
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/nhwc_pooling.hpp210
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/nspc_batch_normalization.cpp288
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/nspc_batch_normalization.hpp169
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_batch_normalization.cpp265
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_batch_normalization.hpp127
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_concat.hpp97
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_convolution.cpp395
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_convolution.hpp194
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_deconvolution.cpp199
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_deconvolution.hpp502
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_eltwise.cpp297
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_eltwise.hpp168
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_inner_product.cpp285
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_inner_product.hpp159
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_lrn.cpp252
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_lrn.hpp136
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_pooling.cpp381
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_pooling.hpp119
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_shuffle.cpp153
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_shuffle.hpp111
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_softmax.cpp264
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_softmax.hpp186
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/ref_sum.hpp101
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_common.cpp90
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_gru.cpp180
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_gru_lbr.cpp170
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_lstm.cpp143
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_rnn.cpp113
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/cpu_rnn_pd.hpp191
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/jit_uni_rnn_postgemm.hpp401
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/ref_rnn.cpp788
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/ref_rnn.hpp328
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_reorders.hpp380
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_utils.cpp426
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_utils.hpp225
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/simple_concat.cpp126
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/simple_concat.hpp155
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/simple_q10n.hpp98
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/simple_reorder.hpp1022
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/simple_sum.cpp91
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/simple_sum.hpp74
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/wino_reorder.hpp376
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/xbyak/COPYRIGHT47
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak.h2658
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_bin2hex.h303
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_mnemonic.h2017
-rw-r--r--thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_util.h772
-rw-r--r--thirdparty/oidn/weights/rtlightmap_hdr.tzabin0 -> 5660131 bytes
-rw-r--r--thirdparty/pcre2/src/config.h6
-rw-r--r--thirdparty/pcre2/src/pcre2.h19
-rw-r--r--thirdparty/pcre2/src/pcre2_auto_possess.c7
-rw-r--r--thirdparty/pcre2/src/pcre2_compile.c535
-rw-r--r--thirdparty/pcre2/src/pcre2_context.c2
-rw-r--r--thirdparty/pcre2/src/pcre2_dfa_match.c129
-rw-r--r--thirdparty/pcre2/src/pcre2_error.c3
-rw-r--r--thirdparty/pcre2/src/pcre2_internal.h105
-rw-r--r--thirdparty/pcre2/src/pcre2_intmodedep.h10
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_compile.c1857
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_match.c1
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_neon_inc.h321
-rw-r--r--thirdparty/pcre2/src/pcre2_jit_simd_inc.h993
-rw-r--r--thirdparty/pcre2/src/pcre2_maketables.c11
-rw-r--r--thirdparty/pcre2/src/pcre2_match.c603
-rw-r--r--thirdparty/pcre2/src/pcre2_match_data.c15
-rw-r--r--thirdparty/pcre2/src/pcre2_study.c306
-rw-r--r--thirdparty/pcre2/src/pcre2_tables.c316
-rw-r--r--thirdparty/pcre2/src/pcre2_ucd.c5623
-rw-r--r--thirdparty/pcre2/src/pcre2_ucp.h7
-rw-r--r--thirdparty/pcre2/src/sljit/sljitConfigInternal.h4
-rw-r--r--thirdparty/pcre2/src/sljit/sljitExecAllocator.c28
-rw-r--r--thirdparty/pcre2/src/sljit/sljitLir.c69
-rw-r--r--thirdparty/pcre2/src/sljit/sljitLir.h22
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeARM_32.c126
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeARM_64.c111
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c76
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c2
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c155
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativePPC_32.c2
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativePPC_64.c3
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativePPC_common.c214
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c2
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c102
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeX86_32.c4
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeX86_64.c54
-rw-r--r--thirdparty/pcre2/src/sljit/sljitNativeX86_common.c125
-rw-r--r--thirdparty/pcre2/src/sljit/sljitUtils.c6
-rw-r--r--thirdparty/recastnavigation/Recast/Include/Recast.h8
-rw-r--r--thirdparty/recastnavigation/Recast/Include/RecastAlloc.h288
-rw-r--r--thirdparty/recastnavigation/Recast/Source/Recast.cpp165
-rw-r--r--thirdparty/recastnavigation/Recast/Source/RecastAlloc.cpp26
-rw-r--r--thirdparty/recastnavigation/Recast/Source/RecastContour.cpp2
-rw-r--r--thirdparty/recastnavigation/Recast/Source/RecastMeshDetail.cpp12
-rw-r--r--thirdparty/recastnavigation/Recast/Source/RecastRegion.cpp198
-rw-r--r--thirdparty/tinyexr/tinyexr.h588
-rw-r--r--thirdparty/vhacd/0005-fix-scale-calculation.patch20
-rw-r--r--thirdparty/vhacd/inc/vhacdVolume.h4
-rw-r--r--thirdparty/xatlas/LICENSE2
-rw-r--r--thirdparty/xatlas/xatlas.cpp4977
-rw-r--r--thirdparty/xatlas/xatlas.h63
2971 files changed, 216198 insertions, 87395 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 3f6e932050..c39a485d35 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -29,7 +29,9 @@ cache:
install:
- SET "PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
- - pip install scons==3.1.2
+ - pip install -U wheel # needed for pip install scons to work, otherwise a flag is missing
+ - pip install scons # use stable scons
+ - if defined VS call "%VS%" %ARCH% # if defined - so we can also use mingw
before_build:
- echo %GD_PLATFORM%
@@ -39,3 +41,15 @@ before_build:
build_script:
- scons platform=%GD_PLATFORM% target=%TARGET% tools=%TOOLS% %OPTIONS% %EXTRA_ARGS%
+
+after_build:
+ - git rev-parse --short=9 HEAD > VERSION_HASH.txt
+ - set /P VERSION_HASH= < VERSION_HASH.txt
+ - cd bin
+ - mv godot.windows.opt.tools.64.exe godot_%APPVEYOR_REPO_BRANCH%-%VERSION_HASH%_win64.exe
+ - 7z a -mx9 godot_%APPVEYOR_REPO_BRANCH%-%VERSION_HASH%_win64.zip *.exe
+
+artifacts:
+ - path: bin/godot_${APPVEYOR_REPO_BRANCH}-${VERSION_HASH}_win64.zip
+ name: Win64 release_debug editor build
+ type: zip \ No newline at end of file
diff --git a/.clang-format b/.clang-format
index eba6d586f0..1c26421a7f 100644
--- a/.clang-format
+++ b/.clang-format
@@ -13,9 +13,9 @@ AlignAfterOpenBracket: DontAlign
AlignTrailingComments: false
AllowAllParametersOfDeclarationOnNextLine: false
# AllowShortBlocksOnASingleLine: false
-AllowShortCaseLabelsOnASingleLine: true
+# AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
-AllowShortIfStatementsOnASingleLine: true
+# AllowShortIfStatementsOnASingleLine: false
# AllowShortLoopsOnASingleLine: false
# AlwaysBreakAfterDefinitionReturnType: None
# AlwaysBreakAfterReturnType: None
@@ -76,7 +76,7 @@ IndentWidth: 4
# IndentWrappedFunctionNames: false
# JavaScriptQuotes: Leave
# JavaScriptWrapImports: true
-# KeepEmptyLinesAtTheStartOfBlocks: true
+KeepEmptyLinesAtTheStartOfBlocks: false
# MacroBlockBegin: ''
# MacroBlockEnd: ''
# MaxEmptyLinesToKeep: 1
@@ -124,4 +124,5 @@ ObjCBlockIndentWidth: 4
### Java specific config ###
Language: Java
# BreakAfterJavaFieldAnnotations: false
+JavaImportGroups: ['org.godotengine', 'android', 'androidx', 'com.android', 'com.google', 'java', 'javax']
...
diff --git a/.clang-tidy b/.clang-tidy
new file mode 100644
index 0000000000..59d0facb96
--- /dev/null
+++ b/.clang-tidy
@@ -0,0 +1,44 @@
+---
+Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,modernize-redundant-void-arg,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-nullptr,readability-braces-around-statements'
+WarningsAsErrors: ''
+HeaderFilterRegex: '.*'
+AnalyzeTemporaryDtors: false
+FormatStyle: none
+CheckOptions:
+CheckOptions:
+ - key: cert-dcl16-c.NewSuffixes
+ value: 'L;LL;LU;LLU'
+ - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
+ value: '0'
+ - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
+ value: '1'
+ - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
+ value: '1'
+ - key: google-readability-function-size.StatementThreshold
+ value: '800'
+ - key: google-readability-namespace-comments.ShortNamespaceLines
+ value: '10'
+ - key: google-readability-namespace-comments.SpacesBeforeComments
+ value: '2'
+ - key: modernize-loop-convert.MaxCopySize
+ value: '16'
+ - key: modernize-loop-convert.MinConfidence
+ value: reasonable
+ - key: modernize-loop-convert.NamingStyle
+ value: CamelCase
+ - key: modernize-pass-by-value.IncludeStyle
+ value: llvm
+ - key: modernize-replace-auto-ptr.IncludeStyle
+ value: llvm
+ - key: modernize-use-bool-literals.IgnoreMacros
+ value: '0'
+ - key: modernize-use-default-member-init.IgnoreMacros
+ value: '0'
+ - key: modernize-use-default-member-init.UseAssignment
+ value: '1'
+ - key: modernize-use-nullptr.NullMacros
+ value: 'NULL'
+ - key: readability-braces-around-statements.ShortStatementLines
+ value: '0'
+...
+
diff --git a/.gitattributes b/.gitattributes
index 40a5e6183f..88c00855d8 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -13,3 +13,4 @@ thirdparty/* linguist-vendored
*.jar binary
*.png binary
*.ttf binary
+*.tza binary
diff --git a/.github/config.yml b/.github/config.yml
new file mode 100644
index 0000000000..f787bec00e
--- /dev/null
+++ b/.github/config.yml
@@ -0,0 +1,14 @@
+blank_issues_enabled: false
+
+contact_links:
+ - name: Godot proposals
+ url: https://github.com/godotengine/godot-proposals
+ about: Please submit feature proposals on the Godot proposals repository, not here.
+
+ - name: Godot documentation repository
+ url: https://github.com/godotengine/godot-docs
+ about: Please report issues with documentation on the Godot documentation repository, not here.
+
+ - name: Godot community channels
+ url: https://godotengine.org/community
+ about: Please ask for technical support on one of the other community channels, not here.
diff --git a/.gitignore b/.gitignore
index 19490b9878..dfb1490aa9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -89,6 +89,9 @@ logs/
*.sln
*.vcxproj*
+# Custom SCons configuration override
+/custom.py
+
# Build results
[Dd]ebug/
[Dd]ebugPublic/
diff --git a/.travis.yml b/.travis.yml
index 8cfd7a1a7f..8878935e52 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -100,15 +100,15 @@ matrix:
packages:
- *linux_deps
-# - name: Javascript export template (release, emscripten latest)
-# stage: build
-# env: PLATFORM=javascript TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-emcc-latest EXTRA_ARGS="use_closure_compiler=yes"
-# os: linux
-# compiler: clang
-# addons:
-# apt:
-# packages:
-# - *linux_deps
+ - name: Javascript export template (release, emscripten latest)
+ stage: build
+ env: PLATFORM=javascript TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-emcc-latest EXTRA_ARGS="use_closure_compiler=yes"
+ os: linux
+ compiler: clang
+ addons:
+ apt:
+ packages:
+ - *linux_deps
before_install:
- eval "${MATRIX_EVAL}"
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index cdc59a4596..2d32bf1fd9 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -128,7 +128,7 @@ License: Expat
Files: ./thirdparty/enet/
Comment: ENet
-Copyright: 2002-2016, Lee Salzman
+Copyright: 2002-2020, Lee Salzman
License: Expat
Files: ./thirdparty/etc2comp/
@@ -154,7 +154,7 @@ License: Expat and Bitstream Vera Fonts Copyright
Files: ./thirdparty/freetype/
Comment: The FreeType Project
-Copyright: 1996-2019, David Turner, Robert Wilhelm, and Werner Lemberg.
+Copyright: 1996-2020, David Turner, Robert Wilhelm, and Werner Lemberg.
License: FTL
Files: ./thirdparty/glad/
@@ -246,12 +246,6 @@ Comment: Clipper
Copyright: 2010-2017, Angus Johnson
License: BSL-1.0
-Files: ./thirdparty/misc/curl_hostcheck.c
- ./thirdparty/misc/curl_hostcheck.h
-Comment: curl
-Copyright: 1998-2012, Daniel Stenberg et al.
-License: curl
-
Files: ./thirdparty/misc/easing_equations.cpp
Comment: Robert Penner's Easing Functions
Copyright: 2001, Robert Penner
@@ -260,15 +254,9 @@ License: BSD-3-clause
Files: ./thirdparty/misc/fastlz.c
./thirdparty/misc/fastlz.h
Comment: FastLZ
-Copyright: 2005-2007, Ariya Hidayat
+Copyright: 2005-2020, Ariya Hidayat
License: Expat
-Files: ./thirdparty/misc/hq2x.cpp
- ./thirdparty/misc/hq2x.h
-Comment: hq2x implementation
-Copyright: 2016, Bruno Ribeiro
-License: Apache-2.0
-
Files: ./thirdparty/misc/ifaddrs-android.cc
./thirdparty/misc/ifaddrs-android.h
Comment: libjingle
@@ -309,6 +297,11 @@ Comment: NanoSVG
Copyright: 2013-2014, Mikko Mononen
License: Zlib
+Files: ./thirdparty/oidn/
+Comment: Intel Open Image Denoise
+Copyright: 2009-2020, Intel Corporation
+License: Apache-2.0
+
Files: ./thirdparty/opus/
Comment: Opus
Copyright: 2001-2011, Xiph.Org, Skype Limited, Octasic,
@@ -335,7 +328,7 @@ License: Zlib
Files: ./thirdparty/rvo2/
Comment: RVO2
-Copyright: 2016, University of North Carolina at Chapel Hill
+Copyright: 2016, University of North Carolina at Chapel Hill
License: Apache 2.0
Files: ./thirdparty/squish/
@@ -375,7 +368,7 @@ License: Expat
Files: ./thirdparty/xatlas/
Comment: xatlas
-Copyright: 2018, Jonathan Young
+Copyright: 2018-2020, Jonathan Young
2013, Thekla, Inc
2006, NVIDIA Corporation, Ignacio Castano
License: Expat
@@ -857,25 +850,6 @@ License: CC-BY-3.0
.
Creative Commons may be contacted at http://creativecommons.org/.
-License: curl
- All rights reserved.
- .
- Permission to use, copy, modify, and distribute this software for any purpose
- with or without fee is hereby granted, provided that the above copyright
- notice and this permission notice appear in all copies.
- .
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
- NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
- OR OTHER DEALINGS IN THE SOFTWARE.
- .
- Except as contained in this notice, the name of a copyright holder shall not
- be used in advertising or otherwise to promote the sale, use or other dealings
- in this Software without prior written authorization of the copyright holder.
-
License: Expat
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/DONORS.md b/DONORS.md
index f11cb85822..134dc0484b 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -25,7 +25,6 @@ generous deed immortalized in the next stable release of Godot Engine.
AD Ford
Alan Beauchamp
Anand Mallik
- Andres Hernandez
Andrew Dunai
Brandon Lamb
Christian Baune
@@ -36,7 +35,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Edward Flick
Gamechuck
GameDev.net
- GameDev.tv
Grady
Hein-Pieter van Braam
Jacob McKenney
@@ -60,13 +58,10 @@ generous deed immortalized in the next stable release of Godot Engine.
## Gold donors
- Andrei
- Dave
David Gehrig
David Graham
David Snopek
Ed Morley
- Florian Krick
Florian Rämisch
Jakub Grzesik
Manuele Finocchiaro
@@ -85,11 +80,9 @@ generous deed immortalized in the next stable release of Godot Engine.
David Giardi
Default Name
eggs
- Felix Bohmann
Florian Breisch
Gamejunkey
Javier Roman
- Jay Horton
Jon Woodward
Karl Werf
Keinan Powers
@@ -100,6 +93,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Matthew Hillier
Mohamed Ikbel Boulabiar
Mored4u
+ Rene
Retro Village
Rob Messick
Ryan Badour
@@ -122,15 +116,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Darrian Little
Horváth Péter
Ivan Trombley
- Jakub Dering
Joan Fons
Joshua Flores
- Krzysztof Jankowski
- Lord Bloodhound
- Pascal Grüter
Petr Malac
Rami
- Reneator
Rob
Robert Willes
Ronnie Ashlock
@@ -144,9 +133,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Adam Nakonieczny
Adam Neumann
+ Adrian Demetrescu
Alexander J Maynard
Alexey Dyadchenko
- Alex Z
Andreas Funke
André Frélicot
aoshiwik
@@ -158,50 +147,42 @@ generous deed immortalized in the next stable release of Godot Engine.
Christian Alexander Bjørklund Bøhler
Christian Leth Jeppesen
Christoph Schröder
+ Codee Leaf
Cody Parker
Coldragon
Craig Ostrin
D
- Daniel Eichler
- David White
- Denis Janßen
Easypete
Eric Monson
- ethan ball
Eugenio Hugo Salgüero Jáñez
Fain
flesk
Gary Hulst
gavlig
GGGames.org
- Green Fox
Guilherme Felipe de C. G. da Silva
Halom Vered
Heath Hayes
- Idzard Kwadijk
Isaac Clausman
Jared White
Jeff Nyte
- Jeremy Sims
- Jerry Ling
Joe Flood
John G Gentzel
- Jon Hermansen
Jose Malheiro
Joshua Lesperance
Juan Velandia
Juraj Móza
Kelteseth
+ kickmaniac
kinfox
+ Lain Ballard
Marcelo Dornbusch Lopes
Markus Fehr
Markus Wiesner
Martin Eigel
Matt Eunson
- Max Bulai
m kaersten
MuffinManKen
- Nick Nikitin
Oliver Dick
Oscar Campos
Patrick Ting
@@ -210,9 +191,8 @@ generous deed immortalized in the next stable release of Godot Engine.
Pete Goodwin
pl
Ranoller
- Robert Larnach
+ Rob McInroy
Rocknight Studios
- Romildo Franco
Ryan
Samuel Judd
Scott Pilet
@@ -221,10 +201,8 @@ generous deed immortalized in the next stable release of Godot Engine.
Sindre Sømme
SleepCircle
spilldata
- Steve Hyatt
Stoned Xander
TheLevelOfDetail .
- Thomas Krampl
Thomas Kurz
Tobias Bocanegra
Urho
@@ -237,6 +215,7 @@ generous deed immortalized in the next stable release of Godot Engine.
1D_Inc
Abraham Haskins
+ Acheron
Adam
Adam Brunnmeier
Adam Carr
@@ -247,7 +226,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Adam Smeltzer
Adam Szymański
Adisibio
- Adrian Demetrescu
Agustinus Arya
Aidan O'Flannagain
Aki Mimoto
@@ -279,14 +257,13 @@ generous deed immortalized in the next stable release of Godot Engine.
B A
Balázs Batári
Benedikt
- Ben G
- Ben Phelan
Ben Vercammen
Bernd Jänichen
Bjarne
Black Block
Blair Allen
Bobby CC Wong
+ Bram
brian
bugcaptor
Burney Waring
@@ -294,6 +271,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Carlo Sitaro
Carl van der Geest
Carwyn Edwards
+ Cas Brugman
Cassidy James
Chris Brown
Chris Chapin
@@ -304,17 +282,17 @@ generous deed immortalized in the next stable release of Godot Engine.
Christopher Schmitt
Christoph Woinke
Clay Heaton
+ Cole Johnson
Curt King
Daniel Johnson
Daniel Kimblad
- Daniel Pontillo
+ Daniel Tebbutt
David May
David Woodard
DiCola Jamn
Dominic Cooney
Dominik Wetzel
Donn Eddy
- Donovan Hutcheon
Dragontrapper
Dr Ewan Murray
Duobix
@@ -322,9 +300,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Dylan Todd
Eduardo Teixeira
Edward Herbert
- Edward Moulsdale
Edward Swartz
Egon Elbre
+ Elgenzay
Elias Nykrem
Elmeri '- Duy Kevin Nguyen
Ephemeral
@@ -335,20 +313,21 @@ generous deed immortalized in the next stable release of Godot Engine.
Evan Rose
Fancy Ants Studios
Fekinox
+ Felix Bohmann
Felix Kollmann
Flaredown
Forty Doubleu
+ fox
FuDiggity
Gadzhi Kharkharov
gamedev by Celio
Gary Thomas
George Marques
- GiulianoB
Greg Olson
GREGORY C FEIN
- Greg P
Greyson Richey
Grid
+ Guillaume Audirac
Guldoman
Hal A
Heribert Hirth
@@ -358,6 +337,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Iiari
iKlem
IndustrialRobot
+ Ivan Nikolaev
Jacob
Jaiden Gerig
Jaime Ruiz-Borau Vizárraga
@@ -368,26 +348,26 @@ generous deed immortalized in the next stable release of Godot Engine.
JARKKO PARVIAINEN
Jeff Hungerford
Jennifer Graves
- Jeremy Kahn
Jesse Dubay
Joel Fivat
Joel Höglund
Joel Setterberg
- Johannes Wuensch
John Gabriel
+ John Walker
Jomei Jackson
+ Jonas
Jonas Bernemann
Jonas Rudlang
Jonas Yamazaki
Jonatan R
Jonathan G
- Jonathon
Jon Bonazza
Jon Sully
Jorge Caballero
Jose Aleman
Jose C. Rubio
Joseph Catrambone
+ Josh Mitchell
Juanfran
Judd
Julian Murgia
@@ -395,16 +375,16 @@ generous deed immortalized in the next stable release of Godot Engine.
Justin Hamilton
Justin Spedding
KaDokta
+ Karel Němec
Kauzig
Keedong Park
Keith Bradner
+ Kent Jofur
Kevin McPhillips
- kickmaniac
Kiri Jolly
Kiyohiro Kawamura (kyorohiro)
Kjetil Haugland
Klagsam
- KR McGinley
KsyTek Games
Kuan Cheang
kycho
@@ -415,6 +395,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Lin Chear
Linus Lind Lundgren
Lionel Gaillard
+ Lukáš Rendvanský
Luigi Renna
LunaticInAHat
Lurkars
@@ -429,10 +410,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Mathieu Rimelen
Matt Edwards
Matthew Little
- Matti Pohjanvirta
+ Mauro Pellegrini
+ Max Fiedler
Maxime Blade
Maxwell
- medecau
Megasploot
Melissa Mears
mewin
@@ -447,6 +428,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Mike Cunningham
Mitchell J. Wagner
MoM
+ Mored4u
Nathan Fish
Natrim
nee
@@ -456,9 +438,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Nicholas
Nicholas Girga
Nick Macholl
+ Niclas Eriksen
Nicolás Montaña
Nicolas SAN AGUSTIN
- Nima Farid
NZ
Oleg Reva
Olivier
@@ -471,13 +453,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Paweł Kowal
Pedro Assuncao
Penguin
- Petrus Prinsloo
Philip Cohoe
Point08
Rad Cat
Rafa Laguna
rainerLinux
- Raphael Leroux
Remi Rampin
Rémi Verschelde
Ricardo Alcantara
@@ -485,7 +465,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Richard Ivánek
Robert Farr (Larington)
Robert Hernandez
- Roberto Sánchez
Roger Smith
Roland RzÄ…sa
Roman Tinkov
@@ -493,26 +472,28 @@ generous deed immortalized in the next stable release of Godot Engine.
Ronan
Ryan Groom
Ryan Hentz
- Sam.C
Sam Edson
Samuele Zolfanelli
- Sasori Olkof
Scott D. Yelich
Scott Longley
+ ScottMakesGames
Sebastian Michailidis
Sebastian Vetter
Sergio Mello-Grand
- sgnsajgon
Shane
Shane Sicienski
Shane Spoor
Siim Raidma
+ Simon Jonas Larsen
Simon Wenner
+ Sintinium
SK
smbe19
smo1704
Stefano Caronia
+ Steve Cloete
Svenne Krap
+ Taylor Fahlman
Terry
tezuvholovdr
thomas
@@ -521,10 +502,10 @@ generous deed immortalized in the next stable release of Godot Engine.
Thomas Kelly
Tim Drumheller
Timothy B. MacDonald
- tinyBigGames LLC
Title Plinsut
Tobbun
Tom Glenn
+ Toni Duran
Torgeir Lilleskog
Torsten Crass
Travis O'Brien
diff --git a/SConstruct b/SConstruct
index e866a4c998..f74940b059 100644
--- a/SConstruct
+++ b/SConstruct
@@ -272,6 +272,14 @@ if selected_platform in platform_list:
else:
env = env_base.Clone()
+ # Compilation DB requires SCons 3.1.1+.
+ from SCons import __version__ as scons_raw_version
+
+ scons_ver = env._get_major_minor_revision(scons_raw_version)
+ if scons_ver >= (3, 1, 1):
+ env.Tool("compilation_db", toolpath=["misc/scons"])
+ env.Alias("compiledb", env.CompilationDatabase("compile_commands.json"))
+
if env["dev"]:
env["verbose"] = True
env["warnings"] = "extra"
@@ -598,6 +606,13 @@ if selected_platform in platform_list:
)
}
)
+ env.Append(
+ BUILDERS={
+ "GLSL_HEADER": env.Builder(
+ action=run_in_subprocess(gles_builders.build_raw_headers), suffix="glsl.gen.h", src_suffix=".glsl"
+ )
+ }
+ )
scons_cache_path = os.environ.get("SCONS_CACHE")
if scons_cache_path != None:
diff --git a/core/SCsub b/core/SCsub
index 0ab4f11d87..80a5f6b623 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -49,9 +49,9 @@ thirdparty_misc_dir = "#thirdparty/misc/"
thirdparty_misc_sources = [
# C sources
"fastlz.c",
+ "r128.c",
"smaz.c",
# C++ sources
- "hq2x.cpp",
"pcg.cpp",
"triangulator.cpp",
"clipper.cpp",
diff --git a/core/array.cpp b/core/array.cpp
index d65bddae61..d1c0688e63 100644
--- a/core/array.cpp
+++ b/core/array.cpp
@@ -30,8 +30,10 @@
#include "array.h"
+#include "container_type_validate.h"
#include "core/hashfuncs.h"
#include "core/object.h"
+#include "core/script_language.h"
#include "core/variant.h"
#include "core/vector.h"
@@ -39,16 +41,18 @@ class ArrayPrivate {
public:
SafeRefCount refcount;
Vector<Variant> array;
+
+ ContainerTypeValidate typed;
};
void Array::_ref(const Array &p_from) const {
-
ArrayPrivate *_fp = p_from._p;
ERR_FAIL_COND(!_fp); // should NOT happen.
- if (_fp == _p)
+ if (_fp == _p) {
return; // whatever it is, nothing to do here move along
+ }
bool success = _fp->refcount.ref();
@@ -60,9 +64,9 @@ void Array::_ref(const Array &p_from) const {
}
void Array::_unref() const {
-
- if (!_p)
+ if (!_p) {
return;
+ }
if (_p->refcount.unref()) {
memdelete(_p);
@@ -71,64 +75,103 @@ void Array::_unref() const {
}
Variant &Array::operator[](int p_idx) {
-
return _p->array.write[p_idx];
}
const Variant &Array::operator[](int p_idx) const {
-
return _p->array[p_idx];
}
int Array::size() const {
-
return _p->array.size();
}
-bool Array::empty() const {
+bool Array::empty() const {
return _p->array.empty();
}
-void Array::clear() {
+void Array::clear() {
_p->array.clear();
}
bool Array::operator==(const Array &p_array) const {
-
return _p == p_array._p;
}
uint32_t Array::hash() const {
-
uint32_t h = hash_djb2_one_32(0);
for (int i = 0; i < _p->array.size(); i++) {
-
h = hash_djb2_one_32(_p->array[i].hash(), h);
}
return h;
}
-void Array::operator=(const Array &p_array) {
- _ref(p_array);
+void Array::_assign(const Array &p_array) {
+ if (_p->typed.type != Variant::OBJECT && _p->typed.type == p_array._p->typed.type) {
+ //same type or untyped, just reference, shuold be fine
+ _ref(p_array);
+ } else if (_p->typed.type == Variant::NIL) { //from typed to untyped, must copy, but this is cheap anyway
+ _p->array = p_array._p->array;
+ } else if (p_array._p->typed.type == Variant::NIL) { //from untyped to typed, must try to check if they are all valid
+ if (_p->typed.type == Variant::OBJECT) {
+ //for objects, it needs full validation, either can be converted or fail
+ for (int i = 0; i < p_array._p->array.size(); i++) {
+ if (!_p->typed.validate(p_array._p->array[i], "assign")) {
+ return;
+ }
+ }
+ _p->array = p_array._p->array; //then just copy, which is cheap anyway
+
+ } else {
+ //for non objects, we need to check if there is a valid conversion, which needs to happen one by one, so this is the worst case.
+ Vector<Variant> new_array;
+ new_array.resize(p_array._p->array.size());
+ for (int i = 0; i < p_array._p->array.size(); i++) {
+ Variant src_val = p_array._p->array[i];
+ if (src_val.get_type() == _p->typed.type) {
+ new_array.write[i] = src_val;
+ } else if (Variant::can_convert_strict(src_val.get_type(), _p->typed.type)) {
+ Variant *ptr = &src_val;
+ Callable::CallError ce;
+ new_array.write[i] = Variant::construct(_p->typed.type, (const Variant **)&ptr, 1, ce, true);
+ if (ce.error != Callable::CallError::CALL_OK) {
+ ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
+ }
+ } else {
+ ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
+ }
+ }
+
+ _p->array = new_array;
+ }
+ } else if (_p->typed.can_reference(p_array._p->typed)) { //same type or compatible
+ _ref(p_array);
+ } else {
+ ERR_FAIL_MSG("Assignment of arrays of incompatible types.");
+ }
+}
+
+void Array::operator=(const Array &p_array) {
+ _assign(p_array);
}
-void Array::push_back(const Variant &p_value) {
+void Array::push_back(const Variant &p_value) {
+ ERR_FAIL_COND(!_p->typed.validate(p_value, "push_back"));
_p->array.push_back(p_value);
}
Error Array::resize(int p_new_size) {
-
return _p->array.resize(p_new_size);
}
void Array::insert(int p_pos, const Variant &p_value) {
-
+ ERR_FAIL_COND(!_p->typed.validate(p_value, "insert"));
_p->array.insert(p_pos, p_value);
}
void Array::erase(const Variant &p_value) {
-
+ ERR_FAIL_COND(!_p->typed.validate(p_value, "erase"));
_p->array.erase(p_value);
}
@@ -143,14 +186,15 @@ Variant Array::back() const {
}
int Array::find(const Variant &p_value, int p_from) const {
-
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find"), -1);
return _p->array.find(p_value, p_from);
}
int Array::rfind(const Variant &p_value, int p_from) const {
-
- if (_p->array.size() == 0)
+ if (_p->array.size() == 0) {
return -1;
+ }
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "rfind"), -1);
if (p_from < 0) {
// Relative offset from the end
@@ -162,7 +206,6 @@ int Array::rfind(const Variant &p_value, int p_from) const {
}
for (int i = p_from; i >= 0; i--) {
-
if (_p->array[i] == p_value) {
return i;
}
@@ -172,18 +215,18 @@ int Array::rfind(const Variant &p_value, int p_from) const {
}
int Array::find_last(const Variant &p_value) const {
-
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "find_last"), -1);
return rfind(p_value);
}
int Array::count(const Variant &p_value) const {
-
- if (_p->array.size() == 0)
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "count"), 0);
+ if (_p->array.size() == 0) {
return 0;
+ }
int amount = 0;
for (int i = 0; i < _p->array.size(); i++) {
-
if (_p->array[i] == p_value) {
amount++;
}
@@ -193,29 +236,30 @@ int Array::count(const Variant &p_value) const {
}
bool Array::has(const Variant &p_value) const {
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "use 'has'"), false);
+
return _p->array.find(p_value, 0) != -1;
}
void Array::remove(int p_pos) {
-
_p->array.remove(p_pos);
}
void Array::set(int p_idx, const Variant &p_value) {
+ ERR_FAIL_COND(!_p->typed.validate(p_value, "set"));
operator[](p_idx) = p_value;
}
const Variant &Array::get(int p_idx) const {
-
return operator[](p_idx);
}
Array Array::duplicate(bool p_deep) const {
-
Array new_arr;
int element_count = size();
new_arr.resize(element_count);
+ new_arr._p->typed = _p->typed;
for (int i = 0; i < element_count; i++) {
new_arr[i] = p_deep ? get(i).duplicate(p_deep) : get(i);
}
@@ -223,59 +267,51 @@ Array Array::duplicate(bool p_deep) const {
return new_arr;
}
-int Array::_fix_slice_index(int p_index, int p_arr_len, int p_top_mod) {
- p_index = CLAMP(p_index, -p_arr_len, p_arr_len + p_top_mod);
- if (p_index < 0) {
- p_index = (p_index % p_arr_len + p_arr_len) % p_arr_len; // positive modulo
+int Array::_clamp_slice_index(int p_index) const {
+ int arr_size = size();
+ int fixed_index = CLAMP(p_index, -arr_size, arr_size - 1);
+ if (fixed_index < 0) {
+ fixed_index = arr_size + fixed_index;
}
- return p_index;
-}
-
-int Array::_clamp_index(int p_index) const {
- return CLAMP(p_index, -size() + 1, size() - 1);
+ return fixed_index;
}
-#define ARRAY_GET_DEEP(idx, is_deep) is_deep ? get(idx).duplicate(is_deep) : get(idx)
-
Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // like python, but inclusive on upper bound
- Array new_arr;
- if (empty()) // Don't try to slice empty arrays.
- return new_arr;
-
- p_begin = Array::_fix_slice_index(p_begin, size(), -1); // can't start out of range
- p_end = Array::_fix_slice_index(p_end, size(), 0);
+ Array new_arr;
- int x = p_begin;
- int new_arr_i = 0;
+ ERR_FAIL_COND_V_MSG(p_step == 0, new_arr, "Array slice step size cannot be zero.");
- ERR_FAIL_COND_V(p_step == 0, new_arr);
- if (Array::_clamp_index(p_begin) == Array::_clamp_index(p_end)) { // don't include element twice
- new_arr.resize(1);
- // new_arr[0] = 1;
- new_arr[0] = ARRAY_GET_DEEP(Array::_clamp_index(p_begin), p_deep);
+ if (empty()) { // Don't try to slice empty arrays.
return new_arr;
- } else {
- int element_count = ceil((int)MAX(0, (p_end - p_begin) / p_step)) + 1;
- if (element_count == 1) { // delta going in wrong direction to reach end
- new_arr.resize(0);
+ }
+ if (p_step > 0) {
+ if (p_begin >= size() || p_end < -size()) {
+ return new_arr;
+ }
+ } else { // p_step < 0
+ if (p_begin < -size() || p_end >= size()) {
return new_arr;
}
- new_arr.resize(element_count);
}
- // if going backwards, have to have a different terminating condition
- if (p_step < 0) {
- while (x >= p_end) {
- new_arr[new_arr_i] = ARRAY_GET_DEEP(Array::_clamp_index(x), p_deep);
- x += p_step;
- new_arr_i += 1;
+ int begin = _clamp_slice_index(p_begin);
+ int end = _clamp_slice_index(p_end);
+
+ int new_arr_size = MAX(((end - begin + p_step) / p_step), 0);
+ new_arr.resize(new_arr_size);
+
+ if (p_step > 0) {
+ int dest_idx = 0;
+ for (int idx = begin; idx <= end; idx += p_step) {
+ ERR_FAIL_COND_V_MSG(dest_idx < 0 || dest_idx >= new_arr_size, Array(), "Bug in Array slice()");
+ new_arr[dest_idx++] = p_deep ? get(idx).duplicate(p_deep) : get(idx);
}
- } else if (p_step > 0) {
- while (x <= p_end) {
- new_arr[new_arr_i] = ARRAY_GET_DEEP(Array::_clamp_index(x), p_deep);
- x += p_step;
- new_arr_i += 1;
+ } else { // p_step < 0
+ int dest_idx = 0;
+ for (int idx = begin; idx >= end; idx += p_step) {
+ ERR_FAIL_COND_V_MSG(dest_idx < 0 || dest_idx >= new_arr_size, Array(), "Bug in Array slice()");
+ new_arr[dest_idx++] = p_deep ? get(idx).duplicate(p_deep) : get(idx);
}
}
@@ -283,40 +319,37 @@ Array Array::slice(int p_begin, int p_end, int p_step, bool p_deep) const { // l
}
struct _ArrayVariantSort {
-
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
bool valid = false;
Variant res;
Variant::evaluate(Variant::OP_LESS, p_l, p_r, res, valid);
- if (!valid)
+ if (!valid) {
res = false;
+ }
return res;
}
};
Array &Array::sort() {
-
_p->array.sort_custom<_ArrayVariantSort>();
return *this;
}
struct _ArrayVariantSortCustom {
-
Object *obj;
StringName func;
_FORCE_INLINE_ bool operator()(const Variant &p_l, const Variant &p_r) const {
-
const Variant *args[2] = { &p_l, &p_r };
Callable::CallError err;
bool res = obj->call(func, args, 2, err);
- if (err.error != Callable::CallError::CALL_OK)
+ if (err.error != Callable::CallError::CALL_OK) {
res = false;
+ }
return res;
}
};
Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
-
ERR_FAIL_NULL_V(p_obj, *this);
SortArray<Variant, _ArrayVariantSortCustom, true> avs;
@@ -327,10 +360,10 @@ Array &Array::sort_custom(Object *p_obj, const StringName &p_function) {
}
void Array::shuffle() {
-
const int n = _p->array.size();
- if (n < 2)
+ if (n < 2) {
return;
+ }
Variant *data = _p->array.ptrw();
for (int i = n - 1; i >= 1; i--) {
const int j = Math::rand() % (i + 1);
@@ -342,7 +375,6 @@ void Array::shuffle() {
template <typename Less>
_FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value, bool p_before, const Less &p_less) {
-
int lo = 0;
int hi = p_array.size();
if (p_before) {
@@ -368,12 +400,12 @@ _FORCE_INLINE_ int bisect(const Vector<Variant> &p_array, const Variant &p_value
}
int Array::bsearch(const Variant &p_value, bool p_before) {
-
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "binary search"), -1);
return bisect(_p->array, p_value, p_before, _ArrayVariantSort());
}
int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringName &p_function, bool p_before) {
-
+ ERR_FAIL_COND_V(!_p->typed.validate(p_value, "custom binary search"), -1);
ERR_FAIL_NULL_V(p_obj, 0);
_ArrayVariantSortCustom less;
@@ -384,18 +416,16 @@ int Array::bsearch_custom(const Variant &p_value, Object *p_obj, const StringNam
}
Array &Array::invert() {
-
_p->array.invert();
return *this;
}
void Array::push_front(const Variant &p_value) {
-
+ ERR_FAIL_COND(!_p->typed.validate(p_value, "push_front"));
_p->array.insert(0, p_value);
}
Variant Array::pop_back() {
-
if (!_p->array.empty()) {
int n = _p->array.size() - 1;
Variant ret = _p->array.get(n);
@@ -406,7 +436,6 @@ Variant Array::pop_back() {
}
Variant Array::pop_front() {
-
if (!_p->array.empty()) {
Variant ret = _p->array.get(0);
_p->array.remove(0);
@@ -416,7 +445,6 @@ Variant Array::pop_front() {
}
Variant Array::min() const {
-
Variant minval;
for (int i = 0; i < size(); i++) {
if (i == 0) {
@@ -439,7 +467,6 @@ Variant Array::min() const {
}
Variant Array::max() const {
-
Variant maxval;
for (int i = 0; i < size(); i++) {
if (i == 0) {
@@ -465,18 +492,37 @@ const void *Array::id() const {
return _p->array.ptr();
}
-Array::Array(const Array &p_from) {
+Array::Array(const Array &p_from, uint32_t p_type, const StringName &p_class_name, const Variant &p_script) {
+ _p = memnew(ArrayPrivate);
+ _p->refcount.init();
+ set_typed(p_type, p_class_name, p_script);
+ _assign(p_from);
+}
+
+void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script) {
+ ERR_FAIL_COND_MSG(_p->array.size() > 0, "Type can only be set when array is empty.");
+ ERR_FAIL_COND_MSG(_p->refcount.get() > 1, "Type can only be set when array has no more than one user.");
+ ERR_FAIL_COND_MSG(_p->typed.type != Variant::NIL, "Type can only be set once.");
+ ERR_FAIL_COND_MSG(p_class_name != StringName() && p_type != Variant::OBJECT, "Class names can only be set for type OBJECT");
+ Ref<Script> script = p_script;
+ ERR_FAIL_COND_MSG(script.is_valid() && p_class_name == StringName(), "Script class can only be set together with base class name");
+
+ _p->typed.type = Variant::Type(p_type);
+ _p->typed.class_name = p_class_name;
+ _p->typed.script = script;
+ _p->typed.where = "TypedArray";
+}
+Array::Array(const Array &p_from) {
_p = nullptr;
_ref(p_from);
}
Array::Array() {
-
_p = memnew(ArrayPrivate);
_p->refcount.init();
}
-Array::~Array() {
+Array::~Array() {
_unref();
}
diff --git a/core/array.h b/core/array.h
index 3b14bdb9fe..d2e0537ad5 100644
--- a/core/array.h
+++ b/core/array.h
@@ -39,13 +39,15 @@ class Object;
class StringName;
class Array {
-
mutable ArrayPrivate *_p;
void _ref(const Array &p_from) const;
void _unref() const;
- int _clamp_index(int p_index) const;
- static int _fix_slice_index(int p_index, int p_arr_len, int p_top_mod);
+ inline int _clamp_slice_index(int p_index) const;
+
+protected:
+ Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
+ void _assign(const Array &p_array);
public:
Variant &operator[](int p_idx);
@@ -101,6 +103,7 @@ public:
const void *id() const;
+ void set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
Array(const Array &p_from);
Array();
~Array();
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index e8955c05df..10f44d357b 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -62,12 +62,14 @@ static const unsigned int MONTH_DAYS_TABLE[2][12] = {
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
+////// _ResourceLoader //////
+
_ResourceLoader *_ResourceLoader::singleton = nullptr;
Error _ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads) {
-
return ResourceLoader::load_threaded_request(p_path, p_type_hint, p_use_sub_threads);
}
+
_ResourceLoader::ThreadLoadStatus _ResourceLoader::load_threaded_get_status(const String &p_path, Array r_progress) {
float progress = 0;
ResourceLoader::ThreadLoadStatus tls = ResourceLoader::load_threaded_get_status(p_path, &progress);
@@ -75,6 +77,7 @@ _ResourceLoader::ThreadLoadStatus _ResourceLoader::load_threaded_get_status(cons
r_progress[0] = progress;
return (ThreadLoadStatus)tls;
}
+
RES _ResourceLoader::load_threaded_get(const String &p_path) {
Error error;
RES res = ResourceLoader::load_threaded_get(p_path, &error);
@@ -82,7 +85,6 @@ RES _ResourceLoader::load_threaded_get(const String &p_path) {
}
RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache) {
-
Error err = OK;
RES ret = ResourceLoader::load(p_path, p_type_hint, p_no_cache, &err);
@@ -91,12 +93,10 @@ RES _ResourceLoader::load(const String &p_path, const String &p_type_hint, bool
}
Vector<String> _ResourceLoader::get_recognized_extensions_for_type(const String &p_type) {
-
List<String> exts;
ResourceLoader::get_recognized_extensions_for_type(p_type, &exts);
Vector<String> ret;
for (List<String>::Element *E = exts.front(); E; E = E->next()) {
-
ret.push_back(E->get());
}
@@ -104,12 +104,10 @@ Vector<String> _ResourceLoader::get_recognized_extensions_for_type(const String
}
void _ResourceLoader::set_abort_on_missing_resources(bool p_abort) {
-
ResourceLoader::set_abort_on_missing_resources(p_abort);
}
PackedStringArray _ResourceLoader::get_dependencies(const String &p_path) {
-
List<String> deps;
ResourceLoader::get_dependencies(p_path, &deps);
@@ -119,10 +117,9 @@ PackedStringArray _ResourceLoader::get_dependencies(const String &p_path) {
}
return ret;
-};
+}
bool _ResourceLoader::has_cached(const String &p_path) {
-
String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
return ResourceCache::has(local_path);
}
@@ -132,7 +129,6 @@ bool _ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
}
void _ResourceLoader::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("load_threaded_request", "path", "type_hint", "use_sub_threads"), &_ResourceLoader::load_threaded_request, DEFVAL(""), DEFVAL(false));
ClassDB::bind_method(D_METHOD("load_threaded_get_status", "path", "progress"), &_ResourceLoader::load_threaded_get_status, DEFVAL(Array()));
ClassDB::bind_method(D_METHOD("load_threaded_get", "path"), &_ResourceLoader::load_threaded_get);
@@ -150,10 +146,7 @@ void _ResourceLoader::_bind_methods() {
BIND_ENUM_CONSTANT(THREAD_LOAD_LOADED);
}
-_ResourceLoader::_ResourceLoader() {
-
- singleton = this;
-}
+////// _ResourceSaver //////
Error _ResourceSaver::save(const String &p_path, const RES &p_resource, SaverFlags p_flags) {
ERR_FAIL_COND_V_MSG(p_resource.is_null(), ERR_INVALID_PARAMETER, "Can't save empty resource to path '" + String(p_path) + "'.");
@@ -161,13 +154,11 @@ Error _ResourceSaver::save(const String &p_path, const RES &p_resource, SaverFla
}
Vector<String> _ResourceSaver::get_recognized_extensions(const RES &p_resource) {
-
ERR_FAIL_COND_V_MSG(p_resource.is_null(), Vector<String>(), "It's not a reference to a valid Resource object.");
List<String> exts;
ResourceSaver::get_recognized_extensions(p_resource, &exts);
Vector<String> ret;
for (List<String>::Element *E = exts.front(); E; E = E->next()) {
-
ret.push_back(E->get());
}
return ret;
@@ -176,7 +167,6 @@ Vector<String> _ResourceSaver::get_recognized_extensions(const RES &p_resource)
_ResourceSaver *_ResourceSaver::singleton = nullptr;
void _ResourceSaver::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("save", "path", "resource", "flags"), &_ResourceSaver::save, DEFVAL(0));
ClassDB::bind_method(D_METHOD("get_recognized_extensions", "type"), &_ResourceSaver::get_recognized_extensions);
@@ -189,10 +179,7 @@ void _ResourceSaver::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_REPLACE_SUBRESOURCE_PATHS);
}
-_ResourceSaver::_ResourceSaver() {
-
- singleton = this;
-}
+////// _OS //////
PackedStringArray _OS::get_connected_midi_inputs() {
return OS::get_singleton()->get_connected_midi_inputs();
@@ -207,87 +194,82 @@ void _OS::close_midi_inputs() {
}
void _OS::set_use_file_access_save_and_swap(bool p_enable) {
-
FileAccess::set_backup_save(p_enable);
}
void _OS::set_low_processor_usage_mode(bool p_enabled) {
-
OS::get_singleton()->set_low_processor_usage_mode(p_enabled);
}
-bool _OS::is_in_low_processor_usage_mode() const {
+bool _OS::is_in_low_processor_usage_mode() const {
return OS::get_singleton()->is_in_low_processor_usage_mode();
}
void _OS::set_low_processor_usage_mode_sleep_usec(int p_usec) {
-
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(p_usec);
}
int _OS::get_low_processor_usage_mode_sleep_usec() const {
-
return OS::get_singleton()->get_low_processor_usage_mode_sleep_usec();
}
String _OS::get_executable_path() const {
-
return OS::get_singleton()->get_executable_path();
}
Error _OS::shell_open(String p_uri) {
-
+ if (p_uri.begins_with("res://")) {
+ WARN_PRINT("Attempting to open an URL with the \"res://\" protocol. Use `ProjectSettings.globalize_path()` to convert a Godot-specific path to a system path before opening it with `OS.shell_open()`.");
+ } else if (p_uri.begins_with("user://")) {
+ WARN_PRINT("Attempting to open an URL with the \"user://\" protocol. Use `ProjectSettings.globalize_path()` to convert a Godot-specific path to a system path before opening it with `OS.shell_open()`.");
+ }
return OS::get_singleton()->shell_open(p_uri);
-};
+}
int _OS::execute(const String &p_path, const Vector<String> &p_arguments, bool p_blocking, Array p_output, bool p_read_stderr) {
-
OS::ProcessID pid = -2;
int exitcode = 0;
List<String> args;
- for (int i = 0; i < p_arguments.size(); i++)
+ for (int i = 0; i < p_arguments.size(); i++) {
args.push_back(p_arguments[i]);
+ }
String pipe;
Error err = OS::get_singleton()->execute(p_path, args, p_blocking, &pid, &pipe, &exitcode, p_read_stderr);
p_output.clear();
p_output.push_back(pipe);
- if (err != OK)
+ if (err != OK) {
return -1;
- else if (p_blocking)
+ } else if (p_blocking) {
return exitcode;
- else
+ } else {
return pid;
+ }
}
Error _OS::kill(int p_pid) {
-
return OS::get_singleton()->kill(p_pid);
}
int _OS::get_process_id() const {
-
return OS::get_singleton()->get_process_id();
-};
+}
bool _OS::has_environment(const String &p_var) const {
-
return OS::get_singleton()->has_environment(p_var);
}
-String _OS::get_environment(const String &p_var) const {
+String _OS::get_environment(const String &p_var) const {
return OS::get_singleton()->get_environment(p_var);
}
String _OS::get_name() const {
-
return OS::get_singleton()->get_name();
}
-Vector<String> _OS::get_cmdline_args() {
+Vector<String> _OS::get_cmdline_args() {
List<String> cmdline = OS::get_singleton()->get_cmdline_args();
Vector<String> cmdlinev;
for (List<String>::Element *E = cmdline.front(); E; E = E->next()) {
-
cmdlinev.push_back(E->get());
}
@@ -295,86 +277,34 @@ Vector<String> _OS::get_cmdline_args() {
}
String _OS::get_locale() const {
-
return OS::get_singleton()->get_locale();
}
String _OS::get_model_name() const {
-
return OS::get_singleton()->get_model_name();
}
Error _OS::set_thread_name(const String &p_name) {
-
return Thread::set_name(p_name);
-};
+}
bool _OS::has_feature(const String &p_feature) const {
-
return OS::get_singleton()->has_feature(p_feature);
}
-/*
-enum Weekday {
- DAY_SUNDAY,
- DAY_MONDAY,
- DAY_TUESDAY,
- DAY_WEDNESDAY,
- DAY_THURSDAY,
- DAY_FRIDAY,
- DAY_SATURDAY
-};
-
-enum Month {
- MONTH_JANUARY,
- MONTH_FEBRUARY,
- MONTH_MARCH,
- MONTH_APRIL,
- MONTH_MAY,
- MONTH_JUNE,
- MONTH_JULY,
- MONTH_AUGUST,
- MONTH_SEPTEMBER,
- MONTH_OCTOBER,
- MONTH_NOVEMBER,
- MONTH_DECEMBER
-};
-*/
-/*
-struct Date {
-
- int year;
- Month month;
- int day;
- Weekday weekday;
- bool dst;
-};
-
-struct Time {
-
- int hour;
- int min;
- int sec;
-};
-*/
-
uint64_t _OS::get_static_memory_usage() const {
-
return OS::get_singleton()->get_static_memory_usage();
}
uint64_t _OS::get_static_memory_peak_usage() const {
-
return OS::get_singleton()->get_static_memory_peak_usage();
}
int _OS::get_exit_code() const {
-
return OS::get_singleton()->get_exit_code();
}
void _OS::set_exit_code(int p_code) {
-
if (p_code < 0 || p_code > 125) {
WARN_PRINT("For portability reasons, the exit code should be set between 0 and 125 (inclusive).");
}
@@ -387,7 +317,6 @@ void _OS::set_exit_code(int p_code) {
* dst
*/
Dictionary _OS::get_datetime(bool utc) const {
-
Dictionary dated = get_date(utc);
Dictionary timed = get_time(utc);
@@ -402,7 +331,6 @@ Dictionary _OS::get_datetime(bool utc) const {
}
Dictionary _OS::get_date(bool utc) const {
-
OS::Date date = OS::get_singleton()->get_date(utc);
Dictionary dated;
dated[YEAR_KEY] = date.year;
@@ -414,7 +342,6 @@ Dictionary _OS::get_date(bool utc) const {
}
Dictionary _OS::get_time(bool utc) const {
-
OS::Time time = OS::get_singleton()->get_time(utc);
Dictionary timed;
timed[HOUR_KEY] = time.hour;
@@ -436,7 +363,6 @@ Dictionary _OS::get_time(bool utc) const {
* @return epoch calculated
*/
int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
-
// Bunch of conversion constants
static const unsigned int SECONDS_PER_MINUTE = 60;
static const unsigned int MINUTES_PER_HOUR = 60;
@@ -509,7 +435,6 @@ int64_t _OS::get_unix_time_from_datetime(Dictionary datetime) const {
* @return dictionary of date and time values
*/
Dictionary _OS::get_datetime_from_unix_time(int64_t unix_time_val) const {
-
OS::Date date;
OS::Time time;
@@ -573,7 +498,6 @@ Dictionary _OS::get_time_zone_info() const {
}
uint64_t _OS::get_unix_time() const {
-
return OS::get_singleton()->get_unix_time();
}
@@ -586,57 +510,46 @@ uint64_t _OS::get_system_time_msecs() const {
}
void _OS::delay_usec(uint32_t p_usec) const {
-
OS::get_singleton()->delay_usec(p_usec);
}
void _OS::delay_msec(uint32_t p_msec) const {
-
OS::get_singleton()->delay_usec(int64_t(p_msec) * 1000);
}
uint32_t _OS::get_ticks_msec() const {
-
return OS::get_singleton()->get_ticks_msec();
}
uint64_t _OS::get_ticks_usec() const {
-
return OS::get_singleton()->get_ticks_usec();
}
uint32_t _OS::get_splash_tick_msec() const {
-
return OS::get_singleton()->get_splash_tick_msec();
}
bool _OS::can_use_threads() const {
-
return OS::get_singleton()->can_use_threads();
}
bool _OS::is_userfs_persistent() const {
-
return OS::get_singleton()->is_userfs_persistent();
}
int _OS::get_processor_count() const {
-
return OS::get_singleton()->get_processor_count();
}
bool _OS::is_stdout_verbose() const {
-
return OS::get_singleton()->is_stdout_verbose();
}
void _OS::dump_memory_to_file(const String &p_file) {
-
OS::get_singleton()->dump_memory_to_file(p_file.utf8().get_data());
}
struct _OSCoreBindImg {
-
String path;
Size2 size;
int fmt;
@@ -646,7 +559,6 @@ struct _OSCoreBindImg {
};
void _OS::print_all_textures_by_size() {
-
List<_OSCoreBindImg> imgs;
int total = 0;
{
@@ -654,9 +566,9 @@ void _OS::print_all_textures_by_size() {
ResourceCache::get_cached_resources(&rsrc);
for (List<Ref<Resource>>::Element *E = rsrc.front(); E; E = E->next()) {
-
- if (!E->get()->is_class("ImageTexture"))
+ if (!E->get()->is_class("ImageTexture")) {
continue;
+ }
Size2 size = E->get()->call("get_size");
int fmt = E->get()->call("get_format");
@@ -675,13 +587,11 @@ void _OS::print_all_textures_by_size() {
imgs.sort();
for (List<_OSCoreBindImg>::Element *E = imgs.front(); E; E = E->next()) {
-
total -= E->get().vram;
}
}
void _OS::print_resources_by_type(const Vector<String> &p_types) {
-
Map<String, int> type_count;
List<Ref<Resource>> resources;
@@ -691,17 +601,18 @@ void _OS::print_resources_by_type(const Vector<String> &p_types) {
ResourceCache::get_cached_resources(&rsrc);
for (List<Ref<Resource>>::Element *E = rsrc.front(); E; E = E->next()) {
-
Ref<Resource> r = E->get();
bool found = false;
for (int i = 0; i < p_types.size(); i++) {
- if (r->is_class(p_types[i]))
+ if (r->is_class(p_types[i])) {
found = true;
+ }
}
- if (!found)
+ if (!found) {
continue;
+ }
if (!type_count.has(r->get_class())) {
type_count[r->get_class()] = 0;
@@ -709,30 +620,25 @@ void _OS::print_resources_by_type(const Vector<String> &p_types) {
type_count[r->get_class()]++;
}
-};
+}
void _OS::print_all_resources(const String &p_to_file) {
-
OS::get_singleton()->print_all_resources(p_to_file);
}
void _OS::print_resources_in_use(bool p_short) {
-
OS::get_singleton()->print_resources_in_use(p_short);
}
void _OS::dump_resources_to_file(const String &p_file) {
-
OS::get_singleton()->dump_resources_to_file(p_file.utf8().get_data());
}
String _OS::get_user_data_dir() const {
-
return OS::get_singleton()->get_user_data_dir();
-};
+}
bool _OS::is_debug_build() const {
-
#ifdef DEBUG_ENABLED
return true;
#else
@@ -741,47 +647,56 @@ bool _OS::is_debug_build() const {
}
String _OS::get_system_dir(SystemDir p_dir) const {
-
return OS::get_singleton()->get_system_dir(OS::SystemDir(p_dir));
}
String _OS::get_keycode_string(uint32_t p_code) const {
-
return keycode_get_string(p_code);
}
bool _OS::is_keycode_unicode(uint32_t p_unicode) const {
-
return keycode_has_unicode(p_unicode);
}
int _OS::find_keycode_from_string(const String &p_code) const {
-
return find_keycode(p_code);
}
bool _OS::request_permission(const String &p_name) {
-
return OS::get_singleton()->request_permission(p_name);
}
bool _OS::request_permissions() {
-
return OS::get_singleton()->request_permissions();
}
Vector<String> _OS::get_granted_permissions() const {
-
return OS::get_singleton()->get_granted_permissions();
}
String _OS::get_unique_id() const {
return OS::get_singleton()->get_unique_id();
}
+
+int _OS::get_tablet_driver_count() const {
+ return OS::get_singleton()->get_tablet_driver_count();
+}
+
+String _OS::get_tablet_driver_name(int p_driver) const {
+ return OS::get_singleton()->get_tablet_driver_name(p_driver);
+}
+
+String _OS::get_current_tablet_driver() const {
+ return OS::get_singleton()->get_current_tablet_driver();
+}
+
+void _OS::set_current_tablet_driver(const String &p_driver) {
+ OS::get_singleton()->set_current_tablet_driver(p_driver);
+}
+
_OS *_OS::singleton = nullptr;
void _OS::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_connected_midi_inputs"), &_OS::get_connected_midi_inputs);
ClassDB::bind_method(D_METHOD("open_midi_inputs"), &_OS::open_midi_inputs);
ClassDB::bind_method(D_METHOD("close_midi_inputs"), &_OS::close_midi_inputs);
@@ -834,8 +749,6 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_debug_build"), &_OS::is_debug_build);
- //ClassDB::bind_method(D_METHOD("get_mouse_button_state"),&_OS::get_mouse_button_state);
-
ClassDB::bind_method(D_METHOD("dump_memory_to_file", "file"), &_OS::dump_memory_to_file);
ClassDB::bind_method(D_METHOD("dump_resources_to_file", "file"), &_OS::dump_resources_to_file);
ClassDB::bind_method(D_METHOD("print_resources_in_use", "short"), &_OS::print_resources_in_use, DEFVAL(false));
@@ -865,9 +778,15 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("request_permissions"), &_OS::request_permissions);
ClassDB::bind_method(D_METHOD("get_granted_permissions"), &_OS::get_granted_permissions);
+ ClassDB::bind_method(D_METHOD("get_tablet_driver_count"), &_OS::get_tablet_driver_count);
+ ClassDB::bind_method(D_METHOD("get_tablet_driver_name", "idx"), &_OS::get_tablet_driver_name);
+ ClassDB::bind_method(D_METHOD("get_current_tablet_driver"), &_OS::get_current_tablet_driver);
+ ClassDB::bind_method(D_METHOD("set_current_tablet_driver", "name"), &_OS::set_current_tablet_driver);
+
ADD_PROPERTY(PropertyInfo(Variant::INT, "exit_code"), "set_exit_code", "get_exit_code");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "low_processor_usage_mode"), "set_low_processor_usage_mode", "is_in_low_processor_usage_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "low_processor_usage_mode_sleep_usec"), "set_low_processor_usage_mode_sleep_usec", "get_low_processor_usage_mode_sleep_usec");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "tablet_driver"), "set_current_tablet_driver", "get_current_tablet_driver");
// Those default values need to be specified for the docs generator,
// to avoid using values from the documentation writer's own OS instance.
@@ -909,57 +828,44 @@ void _OS::_bind_methods() {
BIND_ENUM_CONSTANT(SYSTEM_DIR_RINGTONES);
}
-_OS::_OS() {
-
- singleton = this;
-}
-
-///////////////////// GEOMETRY
+////// _Geometry //////
_Geometry *_Geometry::singleton = nullptr;
_Geometry *_Geometry::get_singleton() {
-
return singleton;
}
Vector<Plane> _Geometry::build_box_planes(const Vector3 &p_extents) {
-
return Geometry::build_box_planes(p_extents);
}
Vector<Plane> _Geometry::build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis) {
-
return Geometry::build_cylinder_planes(p_radius, p_height, p_sides, p_axis);
}
-Vector<Plane> _Geometry::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
+Vector<Plane> _Geometry::build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
return Geometry::build_capsule_planes(p_radius, p_height, p_sides, p_lats, p_axis);
}
bool _Geometry::is_point_in_circle(const Vector2 &p_point, const Vector2 &p_circle_pos, real_t p_circle_radius) {
-
return Geometry::is_point_in_circle(p_point, p_circle_pos, p_circle_radius);
}
real_t _Geometry::segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius) {
-
return Geometry::segment_intersects_circle(p_from, p_to, p_circle_pos, p_circle_radius);
}
Variant _Geometry::segment_intersects_segment_2d(const Vector2 &p_from_a, const Vector2 &p_to_a, const Vector2 &p_from_b, const Vector2 &p_to_b) {
-
Vector2 result;
if (Geometry::segment_intersects_segment_2d(p_from_a, p_to_a, p_from_b, p_to_b, &result)) {
-
return result;
} else {
return Variant();
- };
-};
+ }
+}
Variant _Geometry::line_intersects_line_2d(const Vector2 &p_from_a, const Vector2 &p_dir_a, const Vector2 &p_from_b, const Vector2 &p_dir_b) {
-
Vector2 result;
if (Geometry::line_intersects_line_2d(p_from_a, p_dir_a, p_from_b, p_dir_b, result)) {
return result;
@@ -969,7 +875,6 @@ Variant _Geometry::line_intersects_line_2d(const Vector2 &p_from_a, const Vector
}
Vector<Vector2> _Geometry::get_closest_points_between_segments_2d(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2) {
-
Vector2 r1, r2;
Geometry::get_closest_points_between_segments(p1, q1, p2, q2, r1, r2);
Vector<Vector2> r;
@@ -980,7 +885,6 @@ Vector<Vector2> _Geometry::get_closest_points_between_segments_2d(const Vector2
}
Vector<Vector3> _Geometry::get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2) {
-
Vector3 r1, r2;
Geometry::get_closest_points_between_segments(p1, p2, q1, q2, r1, r2);
Vector<Vector3> r;
@@ -989,78 +893,81 @@ Vector<Vector3> _Geometry::get_closest_points_between_segments(const Vector3 &p1
r.set(1, r2);
return r;
}
-Vector2 _Geometry::get_closest_point_to_segment_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) {
+Vector2 _Geometry::get_closest_point_to_segment_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) {
Vector2 s[2] = { p_a, p_b };
return Geometry::get_closest_point_to_segment_2d(p_point, s);
}
-Vector3 _Geometry::get_closest_point_to_segment(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) {
+Vector3 _Geometry::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 Geometry::get_closest_point_to_segment(p_point, s);
}
-Vector2 _Geometry::get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) {
+Vector2 _Geometry::get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 &p_a, const Vector2 &p_b) {
Vector2 s[2] = { p_a, p_b };
return Geometry::get_closest_point_to_segment_uncapped_2d(p_point, s);
}
-Vector3 _Geometry::get_closest_point_to_segment_uncapped(const Vector3 &p_point, const Vector3 &p_a, const Vector3 &p_b) {
+Vector3 _Geometry::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 Geometry::get_closest_point_to_segment_uncapped(p_point, s);
}
-Variant _Geometry::ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) {
+Variant _Geometry::ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) {
Vector3 res;
- if (Geometry::ray_intersects_triangle(p_from, p_dir, p_v0, p_v1, p_v2, &res))
+ if (Geometry::ray_intersects_triangle(p_from, p_dir, p_v0, p_v1, p_v2, &res)) {
return res;
- else
+ } else {
return Variant();
+ }
}
-Variant _Geometry::segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) {
+Variant _Geometry::segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2) {
Vector3 res;
- if (Geometry::segment_intersects_triangle(p_from, p_to, p_v0, p_v1, p_v2, &res))
+ if (Geometry::segment_intersects_triangle(p_from, p_to, p_v0, p_v1, p_v2, &res)) {
return res;
- else
+ } else {
return Variant();
+ }
}
bool _Geometry::point_is_inside_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) const {
-
return Geometry::is_point_in_triangle(s, a, b, c);
}
Vector<Vector3> _Geometry::segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius) {
-
Vector<Vector3> r;
Vector3 res, norm;
- if (!Geometry::segment_intersects_sphere(p_from, p_to, p_sphere_pos, p_sphere_radius, &res, &norm))
+ if (!Geometry::segment_intersects_sphere(p_from, p_to, p_sphere_pos, p_sphere_radius, &res, &norm)) {
return r;
+ }
r.resize(2);
r.set(0, res);
r.set(1, norm);
return r;
}
-Vector<Vector3> _Geometry::segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius) {
+Vector<Vector3> _Geometry::segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, float p_height, float p_radius) {
Vector<Vector3> r;
Vector3 res, norm;
- if (!Geometry::segment_intersects_cylinder(p_from, p_to, p_height, p_radius, &res, &norm))
+ if (!Geometry::segment_intersects_cylinder(p_from, p_to, p_height, p_radius, &res, &norm)) {
return r;
+ }
r.resize(2);
r.set(0, res);
r.set(1, norm);
return r;
}
-Vector<Vector3> _Geometry::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes) {
+Vector<Vector3> _Geometry::segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const Vector<Plane> &p_planes) {
Vector<Vector3> r;
Vector3 res, norm;
- if (!Geometry::segment_intersects_convex(p_from, p_to, p_planes.ptr(), p_planes.size(), &res, &norm))
+ if (!Geometry::segment_intersects_convex(p_from, p_to, p_planes.ptr(), p_planes.size(), &res, &norm)) {
return r;
+ }
r.resize(2);
r.set(0, res);
@@ -1069,37 +976,30 @@ Vector<Vector3> _Geometry::segment_intersects_convex(const Vector3 &p_from, cons
}
bool _Geometry::is_polygon_clockwise(const Vector<Vector2> &p_polygon) {
-
return Geometry::is_polygon_clockwise(p_polygon);
}
bool _Geometry::is_point_in_polygon(const Point2 &p_point, const Vector<Vector2> &p_polygon) {
-
return Geometry::is_point_in_polygon(p_point, p_polygon);
}
Vector<int> _Geometry::triangulate_polygon(const Vector<Vector2> &p_polygon) {
-
return Geometry::triangulate_polygon(p_polygon);
}
Vector<int> _Geometry::triangulate_delaunay_2d(const Vector<Vector2> &p_points) {
-
return Geometry::triangulate_delaunay_2d(p_points);
}
Vector<Point2> _Geometry::convex_hull_2d(const Vector<Point2> &p_points) {
-
return Geometry::convex_hull_2d(p_points);
}
Vector<Vector3> _Geometry::clip_polygon(const Vector<Vector3> &p_points, const Plane &p_plane) {
-
return Geometry::clip_polygon(p_points, p_plane);
}
Array _Geometry::merge_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) {
-
Vector<Vector<Point2>> polys = Geometry::merge_polygons_2d(p_polygon_a, p_polygon_b);
Array ret;
@@ -1111,7 +1011,6 @@ Array _Geometry::merge_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vec
}
Array _Geometry::clip_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) {
-
Vector<Vector<Point2>> polys = Geometry::clip_polygons_2d(p_polygon_a, p_polygon_b);
Array ret;
@@ -1123,7 +1022,6 @@ Array _Geometry::clip_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vect
}
Array _Geometry::intersect_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) {
-
Vector<Vector<Point2>> polys = Geometry::intersect_polygons_2d(p_polygon_a, p_polygon_b);
Array ret;
@@ -1135,7 +1033,6 @@ Array _Geometry::intersect_polygons_2d(const Vector<Vector2> &p_polygon_a, const
}
Array _Geometry::exclude_polygons_2d(const Vector<Vector2> &p_polygon_a, const Vector<Vector2> &p_polygon_b) {
-
Vector<Vector<Point2>> polys = Geometry::exclude_polygons_2d(p_polygon_a, p_polygon_b);
Array ret;
@@ -1147,7 +1044,6 @@ Array _Geometry::exclude_polygons_2d(const Vector<Vector2> &p_polygon_a, const V
}
Array _Geometry::clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) {
-
Vector<Vector<Point2>> polys = Geometry::clip_polyline_with_polygon_2d(p_polyline, p_polygon);
Array ret;
@@ -1159,7 +1055,6 @@ Array _Geometry::clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline
}
Array _Geometry::intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) {
-
Vector<Vector<Point2>> polys = Geometry::intersect_polyline_with_polygon_2d(p_polyline, p_polygon);
Array ret;
@@ -1171,7 +1066,6 @@ Array _Geometry::intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_pol
}
Array _Geometry::offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) {
-
Vector<Vector<Point2>> polys = Geometry::offset_polygon_2d(p_polygon, p_delta, Geometry::PolyJoinType(p_join_type));
Array ret;
@@ -1183,7 +1077,6 @@ Array _Geometry::offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_de
}
Array _Geometry::offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
-
Vector<Vector<Point2>> polys = Geometry::offset_polyline_2d(p_polygon, p_delta, Geometry::PolyJoinType(p_join_type), Geometry::PolyEndType(p_end_type));
Array ret;
@@ -1195,14 +1088,12 @@ Array _Geometry::offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_d
}
Dictionary _Geometry::make_atlas(const Vector<Size2> &p_rects) {
-
Dictionary ret;
Vector<Size2i> rects;
for (int i = 0; i < p_rects.size(); i++) {
-
rects.push_back(p_rects[i]);
- };
+ }
Vector<Point2i> result;
Size2i size;
@@ -1212,23 +1103,20 @@ Dictionary _Geometry::make_atlas(const Vector<Size2> &p_rects) {
Size2 r_size = size;
Vector<Point2> r_result;
for (int i = 0; i < result.size(); i++) {
-
r_result.push_back(result[i]);
- };
+ }
ret["points"] = r_result;
ret["size"] = r_size;
return ret;
-};
+}
int _Geometry::get_uv84_normal_bit(const Vector3 &p_vector) {
-
return Geometry::get_uv84_normal_bit(p_vector);
}
void _Geometry::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("build_box_planes", "extents"), &_Geometry::build_box_planes);
ClassDB::bind_method(D_METHOD("build_cylinder_planes", "radius", "height", "sides", "axis"), &_Geometry::build_cylinder_planes, DEFVAL(Vector3::AXIS_Z));
ClassDB::bind_method(D_METHOD("build_capsule_planes", "radius", "height", "sides", "lats", "axis"), &_Geometry::build_capsule_planes, DEFVAL(Vector3::AXIS_Z));
@@ -1291,17 +1179,13 @@ void _Geometry::_bind_methods() {
BIND_ENUM_CONSTANT(END_ROUND);
}
-_Geometry::_Geometry() {
- singleton = this;
-}
-
-///////////////////////// FILE
+////// _File //////
Error _File::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const Vector<uint8_t> &p_key) {
-
Error err = open(p_path, p_mode_flags);
- if (err)
+ if (err) {
return err;
+ }
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse(f, p_key, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ);
@@ -1315,10 +1199,10 @@ Error _File::open_encrypted(const String &p_path, ModeFlags p_mode_flags, const
}
Error _File::open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, const String &p_pass) {
-
Error err = open(p_path, p_mode_flags);
- if (err)
+ if (err) {
return err;
+ }
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse_password(f, p_pass, (p_mode_flags == WRITE) ? FileAccessEncrypted::MODE_WRITE_AES256 : FileAccessEncrypted::MODE_READ);
@@ -1333,7 +1217,6 @@ Error _File::open_encrypted_pass(const String &p_path, ModeFlags p_mode_flags, c
}
Error _File::open_compressed(const String &p_path, ModeFlags p_mode_flags, CompressionMode p_compress_mode) {
-
FileAccessCompressed *fac = memnew(FileAccessCompressed);
fac->configure("GCPF", (Compression::Mode)p_compress_mode);
@@ -1350,110 +1233,104 @@ Error _File::open_compressed(const String &p_path, ModeFlags p_mode_flags, Compr
}
Error _File::open(const String &p_path, ModeFlags p_mode_flags) {
-
close();
Error err;
f = FileAccess::open(p_path, p_mode_flags, &err);
- if (f)
+ if (f) {
f->set_endian_swap(eswap);
+ }
return err;
}
void _File::close() {
-
- if (f)
+ if (f) {
memdelete(f);
+ }
f = nullptr;
}
-bool _File::is_open() const {
+bool _File::is_open() const {
return f != nullptr;
}
-String _File::get_path() const {
+String _File::get_path() const {
ERR_FAIL_COND_V_MSG(!f, "", "File must be opened before use.");
return f->get_path();
}
String _File::get_path_absolute() const {
-
ERR_FAIL_COND_V_MSG(!f, "", "File must be opened before use.");
return f->get_path_absolute();
}
void _File::seek(int64_t p_position) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->seek(p_position);
}
-void _File::seek_end(int64_t p_position) {
+void _File::seek_end(int64_t p_position) {
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->seek_end(p_position);
}
-int64_t _File::get_position() const {
+int64_t _File::get_position() const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
return f->get_position();
}
int64_t _File::get_len() const {
-
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
return f->get_len();
}
bool _File::eof_reached() const {
-
ERR_FAIL_COND_V_MSG(!f, false, "File must be opened before use.");
return f->eof_reached();
}
uint8_t _File::get_8() const {
-
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
return f->get_8();
}
-uint16_t _File::get_16() const {
+uint16_t _File::get_16() const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
return f->get_16();
}
-uint32_t _File::get_32() const {
+uint32_t _File::get_32() const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
return f->get_32();
}
-uint64_t _File::get_64() const {
+uint64_t _File::get_64() const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
return f->get_64();
}
float _File::get_float() const {
-
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
return f->get_float();
}
-double _File::get_double() const {
+double _File::get_double() const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
return f->get_double();
}
-real_t _File::get_real() const {
+real_t _File::get_real() const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
return f->get_real();
}
Vector<uint8_t> _File::get_buffer(int p_length) const {
-
Vector<uint8_t> data;
ERR_FAIL_COND_V_MSG(!f, data, "File must be opened before use.");
ERR_FAIL_COND_V_MSG(p_length < 0, data, "Length of buffer cannot be smaller than 0.");
- if (p_length == 0)
+ if (p_length == 0) {
return data;
+ }
Error err = data.resize(p_length);
ERR_FAIL_COND_V_MSG(err != OK, data, "Can't resize data to " + itos(p_length) + " elements.");
@@ -1462,14 +1339,14 @@ Vector<uint8_t> _File::get_buffer(int p_length) const {
int len = f->get_buffer(&w[0], p_length);
ERR_FAIL_COND_V(len < 0, Vector<uint8_t>());
- if (len < p_length)
+ if (len < p_length) {
data.resize(p_length);
+ }
return data;
}
String _File::get_as_text() const {
-
ERR_FAIL_COND_V_MSG(!f, String(), "File must be opened before use.");
String text;
@@ -1489,17 +1366,14 @@ String _File::get_as_text() const {
}
String _File::get_md5(const String &p_path) const {
-
return FileAccess::get_md5(p_path);
}
String _File::get_sha256(const String &p_path) const {
-
return FileAccess::get_sha256(p_path);
}
String _File::get_line() const {
-
ERR_FAIL_COND_V_MSG(!f, String(), "File must be opened before use.");
return f->get_line();
}
@@ -1515,90 +1389,84 @@ Vector<String> _File::get_csv_line(const String &p_delim) const {
*/
void _File::set_endian_swap(bool p_swap) {
-
eswap = p_swap;
- if (f)
+ if (f) {
f->set_endian_swap(p_swap);
+ }
}
-bool _File::get_endian_swap() {
+bool _File::get_endian_swap() {
return eswap;
}
Error _File::get_error() const {
-
- if (!f)
+ if (!f) {
return ERR_UNCONFIGURED;
+ }
return f->get_error();
}
void _File::store_8(uint8_t p_dest) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->store_8(p_dest);
}
-void _File::store_16(uint16_t p_dest) {
+void _File::store_16(uint16_t p_dest) {
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->store_16(p_dest);
}
-void _File::store_32(uint32_t p_dest) {
+void _File::store_32(uint32_t p_dest) {
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->store_32(p_dest);
}
-void _File::store_64(uint64_t p_dest) {
+void _File::store_64(uint64_t p_dest) {
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->store_64(p_dest);
}
void _File::store_float(float p_dest) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->store_float(p_dest);
}
-void _File::store_double(double p_dest) {
+void _File::store_double(double p_dest) {
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->store_double(p_dest);
}
-void _File::store_real(real_t p_real) {
+void _File::store_real(real_t p_real) {
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->store_real(p_real);
}
void _File::store_string(const String &p_string) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->store_string(p_string);
}
void _File::store_pascal_string(const String &p_string) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->store_pascal_string(p_string);
-};
+}
String _File::get_pascal_string() {
-
ERR_FAIL_COND_V_MSG(!f, "", "File must be opened before use.");
return f->get_pascal_string();
-};
+}
void _File::store_line(const String &p_string) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
f->store_line(p_string);
}
@@ -1609,12 +1477,12 @@ void _File::store_csv_line(const Vector<String> &p_values, const String &p_delim
}
void _File::store_buffer(const Vector<uint8_t> &p_buffer) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
int len = p_buffer.size();
- if (len == 0)
+ if (len == 0) {
return;
+ }
const uint8_t *r = p_buffer.ptr();
@@ -1622,12 +1490,10 @@ void _File::store_buffer(const Vector<uint8_t> &p_buffer) {
}
bool _File::file_exists(const String &p_name) const {
-
return FileAccess::exists(p_name);
}
void _File::store_var(const Variant &p_var, bool p_full_objects) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
int len;
Error err = encode_variant(p_var, nullptr, len, p_full_objects);
@@ -1645,7 +1511,6 @@ void _File::store_var(const Variant &p_var, bool p_full_objects) {
}
Variant _File::get_var(bool p_allow_objects) const {
-
ERR_FAIL_COND_V_MSG(!f, Variant(), "File must be opened before use.");
uint32_t len = get_32();
Vector<uint8_t> buff = get_buffer(len);
@@ -1661,12 +1526,10 @@ Variant _File::get_var(bool p_allow_objects) const {
}
uint64_t _File::get_modified_time(const String &p_file) const {
-
return FileAccess::get_modified_time(p_file);
}
void _File::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("open_encrypted", "path", "mode_flags", "key"), &_File::open_encrypted);
ClassDB::bind_method(D_METHOD("open_encrypted_with_pass", "path", "mode_flags", "pass"), &_File::open_encrypted_pass);
ClassDB::bind_method(D_METHOD("open_compressed", "path", "mode_flags", "compression_mode"), &_File::open_compressed, DEFVAL(0));
@@ -1731,35 +1594,30 @@ void _File::_bind_methods() {
BIND_ENUM_CONSTANT(COMPRESSION_GZIP);
}
-_File::_File() {
-
- f = nullptr;
- eswap = false;
-}
-
_File::~_File() {
-
- if (f)
+ if (f) {
memdelete(f);
+ }
}
-///////////////////////////////////////////////////////
+////// _Directory //////
Error _Directory::open(const String &p_path) {
Error err;
DirAccess *alt = DirAccess::open(p_path, &err);
- if (!alt)
+ if (!alt) {
return err;
- if (d)
+ }
+ if (d) {
memdelete(d);
+ }
d = alt;
return OK;
}
Error _Directory::list_dir_begin(bool p_skip_navigational, bool p_skip_hidden) {
-
ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use.");
_list_skip_navigational = p_skip_navigational;
@@ -1769,55 +1627,51 @@ Error _Directory::list_dir_begin(bool p_skip_navigational, bool p_skip_hidden) {
}
String _Directory::get_next() {
-
ERR_FAIL_COND_V_MSG(!d, "", "Directory must be opened before use.");
String next = d->get_next();
while (next != "" && ((_list_skip_navigational && (next == "." || next == "..")) || (_list_skip_hidden && d->current_is_hidden()))) {
-
next = d->get_next();
}
return next;
}
-bool _Directory::current_is_dir() const {
+bool _Directory::current_is_dir() const {
ERR_FAIL_COND_V_MSG(!d, false, "Directory must be opened before use.");
return d->current_is_dir();
}
void _Directory::list_dir_end() {
-
ERR_FAIL_COND_MSG(!d, "Directory must be opened before use.");
d->list_dir_end();
}
int _Directory::get_drive_count() {
-
ERR_FAIL_COND_V_MSG(!d, 0, "Directory must be opened before use.");
return d->get_drive_count();
}
-String _Directory::get_drive(int p_drive) {
+String _Directory::get_drive(int p_drive) {
ERR_FAIL_COND_V_MSG(!d, "", "Directory must be opened before use.");
return d->get_drive(p_drive);
}
+
int _Directory::get_current_drive() {
ERR_FAIL_COND_V_MSG(!d, 0, "Directory must be opened before use.");
return d->get_current_drive();
}
Error _Directory::change_dir(String p_dir) {
-
ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use.");
return d->change_dir(p_dir);
}
-String _Directory::get_current_dir() {
+String _Directory::get_current_dir() {
ERR_FAIL_COND_V_MSG(!d, "", "Directory must be opened before use.");
return d->get_current_dir();
}
-Error _Directory::make_dir(String p_dir) {
+Error _Directory::make_dir(String p_dir) {
ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use.");
if (!p_dir.is_rel_path()) {
DirAccess *d = DirAccess::create_for_path(p_dir);
@@ -1827,8 +1681,8 @@ Error _Directory::make_dir(String p_dir) {
}
return d->make_dir(p_dir);
}
-Error _Directory::make_dir_recursive(String p_dir) {
+Error _Directory::make_dir_recursive(String p_dir) {
ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use.");
if (!p_dir.is_rel_path()) {
DirAccess *d = DirAccess::create_for_path(p_dir);
@@ -1840,7 +1694,6 @@ Error _Directory::make_dir_recursive(String p_dir) {
}
bool _Directory::file_exists(String p_file) {
-
ERR_FAIL_COND_V_MSG(!d, false, "Directory must be opened before use.");
if (!p_file.is_rel_path()) {
@@ -1853,7 +1706,6 @@ bool _Directory::file_exists(String p_file) {
bool _Directory::dir_exists(String p_dir) {
ERR_FAIL_COND_V_MSG(!d, false, "Directory must be opened before use.");
if (!p_dir.is_rel_path()) {
-
DirAccess *d = DirAccess::create_for_path(p_dir);
bool exists = d->dir_exists(p_dir);
memdelete(d);
@@ -1865,18 +1717,16 @@ bool _Directory::dir_exists(String p_dir) {
}
int _Directory::get_space_left() {
-
ERR_FAIL_COND_V_MSG(!d, 0, "Directory must be opened before use.");
return d->get_space_left() / 1024 * 1024; //return value in megabytes, given binding is int
}
Error _Directory::copy(String p_from, String p_to) {
-
ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use.");
return d->copy(p_from, p_to);
}
-Error _Directory::rename(String p_from, String p_to) {
+Error _Directory::rename(String p_from, String p_to) {
ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use.");
if (!p_from.is_rel_path()) {
DirAccess *d = DirAccess::create_for_path(p_from);
@@ -1887,8 +1737,8 @@ Error _Directory::rename(String p_from, String p_to) {
return d->rename(p_from, p_to);
}
-Error _Directory::remove(String p_name) {
+Error _Directory::remove(String p_name) {
ERR_FAIL_COND_V_MSG(!d, ERR_UNCONFIGURED, "Directory must be opened before use.");
if (!p_name.is_rel_path()) {
DirAccess *d = DirAccess::create_for_path(p_name);
@@ -1901,7 +1751,6 @@ Error _Directory::remove(String p_name) {
}
void _Directory::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("open", "path"), &_Directory::open);
ClassDB::bind_method(D_METHOD("list_dir_begin", "skip_navigational", "skip_hidden"), &_Directory::list_dir_begin, DEFVAL(false), DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_next"), &_Directory::get_next);
@@ -1924,16 +1773,17 @@ void _Directory::_bind_methods() {
}
_Directory::_Directory() {
-
d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
}
_Directory::~_Directory() {
-
- if (d)
+ if (d) {
memdelete(d);
+ }
}
+////// _Marshalls //////
+
_Marshalls *_Marshalls::singleton = nullptr;
_Marshalls *_Marshalls::get_singleton() {
@@ -1941,7 +1791,6 @@ _Marshalls *_Marshalls::get_singleton() {
}
String _Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects) {
-
int len;
Error err = encode_variant(p_var, nullptr, len, p_full_objects);
ERR_FAIL_COND_V_MSG(err != OK, "", "Error when trying to encode Variant.");
@@ -1957,10 +1806,9 @@ String _Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects)
ERR_FAIL_COND_V(ret == "", ret);
return ret;
-};
+}
Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects) {
-
int strlen = p_str.length();
CharString cstr = p_str.ascii();
@@ -1976,17 +1824,15 @@ Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects)
ERR_FAIL_COND_V_MSG(err != OK, Variant(), "Error when trying to decode Variant.");
return v;
-};
+}
String _Marshalls::raw_to_base64(const Vector<uint8_t> &p_arr) {
-
String ret = CryptoCore::b64_encode_str(p_arr.ptr(), p_arr.size());
ERR_FAIL_COND_V(ret == "", ret);
return ret;
-};
+}
Vector<uint8_t> _Marshalls::base64_to_raw(const String &p_str) {
-
int strlen = p_str.length();
CharString cstr = p_str.ascii();
@@ -2001,18 +1847,16 @@ Vector<uint8_t> _Marshalls::base64_to_raw(const String &p_str) {
buf.resize(arr_len);
return buf;
-};
+}
String _Marshalls::utf8_to_base64(const String &p_str) {
-
CharString cstr = p_str.utf8();
String ret = CryptoCore::b64_encode_str((unsigned char *)cstr.get_data(), cstr.length());
ERR_FAIL_COND_V(ret == "", ret);
return ret;
-};
+}
String _Marshalls::base64_to_utf8(const String &p_str) {
-
int strlen = p_str.length();
CharString cstr = p_str.ascii();
@@ -2027,10 +1871,9 @@ String _Marshalls::base64_to_utf8(const String &p_str) {
String ret = String::utf8((char *)&w[0]);
return ret;
-};
+}
void _Marshalls::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("variant_to_base64", "variant", "full_objects"), &_Marshalls::variant_to_base64, DEFVAL(false));
ClassDB::bind_method(D_METHOD("base64_to_variant", "base64_str", "allow_objects"), &_Marshalls::base64_to_variant, DEFVAL(false));
@@ -2039,60 +1882,51 @@ void _Marshalls::_bind_methods() {
ClassDB::bind_method(D_METHOD("utf8_to_base64", "utf8_str"), &_Marshalls::utf8_to_base64);
ClassDB::bind_method(D_METHOD("base64_to_utf8", "base64_str"), &_Marshalls::base64_to_utf8);
-};
+}
-////////////////
+////// _Semaphore //////
void _Semaphore::wait() {
-
semaphore.wait();
}
Error _Semaphore::try_wait() {
-
return semaphore.try_wait() ? OK : ERR_BUSY;
}
void _Semaphore::post() {
-
semaphore.post();
}
void _Semaphore::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("wait"), &_Semaphore::wait);
ClassDB::bind_method(D_METHOD("try_wait"), &_Semaphore::try_wait);
ClassDB::bind_method(D_METHOD("post"), &_Semaphore::post);
}
-///////////////
+////// _Mutex //////
void _Mutex::lock() {
-
mutex.lock();
}
Error _Mutex::try_lock() {
-
return mutex.try_lock();
}
void _Mutex::unlock() {
-
mutex.unlock();
}
void _Mutex::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("lock"), &_Mutex::lock);
ClassDB::bind_method(D_METHOD("try_lock"), &_Mutex::try_lock);
ClassDB::bind_method(D_METHOD("unlock"), &_Mutex::unlock);
}
-///////////////
+////// _Thread //////
void _Thread::_start_func(void *ud) {
-
Ref<_Thread> *tud = (Ref<_Thread> *)ud;
Ref<_Thread> t = *tud;
memdelete(tud);
@@ -2103,23 +1937,18 @@ void _Thread::_start_func(void *ud) {
t->ret = t->target_instance->call(t->target_method, arg, 1, ce);
if (ce.error != Callable::CallError::CALL_OK) {
-
String reason;
switch (ce.error) {
case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
-
reason = "Invalid Argument #" + itos(ce.argument);
} break;
case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
-
reason = "Too Many Arguments";
} break;
case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
-
reason = "Too Few Arguments";
} break;
case Callable::CallError::CALL_ERROR_INVALID_METHOD: {
-
reason = "Method Not Found";
} break;
default: {
@@ -2131,7 +1960,6 @@ void _Thread::_start_func(void *ud) {
}
Error _Thread::start(Object *p_instance, const StringName &p_method, const Variant &p_userdata, Priority p_priority) {
-
ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "Thread already started.");
ERR_FAIL_COND_V(!p_instance, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_method == StringName(), ERR_INVALID_PARAMETER);
@@ -2160,19 +1988,18 @@ Error _Thread::start(Object *p_instance, const StringName &p_method, const Varia
}
String _Thread::get_id() const {
-
- if (!thread)
+ if (!thread) {
return String();
+ }
return itos(thread->get_id());
}
bool _Thread::is_active() const {
-
return active;
}
-Variant _Thread::wait_to_finish() {
+Variant _Thread::wait_to_finish() {
ERR_FAIL_COND_V_MSG(!thread, Variant(), "Thread must exist to wait for its completion.");
ERR_FAIL_COND_V_MSG(!active, Variant(), "Thread must be active to wait for its completion.");
Thread::wait_to_finish(thread);
@@ -2181,15 +2008,15 @@ Variant _Thread::wait_to_finish() {
target_method = StringName();
target_instance = nullptr;
userdata = Variant();
- if (thread)
+ if (thread) {
memdelete(thread);
+ }
thread = nullptr;
return r;
}
void _Thread::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("start", "instance", "method", "userdata", "priority"), &_Thread::start, DEFVAL(Variant()), DEFVAL(PRIORITY_NORMAL));
ClassDB::bind_method(D_METHOD("get_id"), &_Thread::get_id);
ClassDB::bind_method(D_METHOD("is_active"), &_Thread::is_active);
@@ -2199,22 +2026,14 @@ void _Thread::_bind_methods() {
BIND_ENUM_CONSTANT(PRIORITY_NORMAL);
BIND_ENUM_CONSTANT(PRIORITY_HIGH);
}
-_Thread::_Thread() {
-
- active = false;
- thread = nullptr;
- target_instance = nullptr;
-}
_Thread::~_Thread() {
-
ERR_FAIL_COND_MSG(active, "Reference to a Thread object was lost while the thread is still running...");
}
-/////////////////////////////////////
+////// _ClassDB //////
PackedStringArray _ClassDB::get_class_list() const {
-
List<StringName> classes;
ClassDB::get_class_list(&classes);
@@ -2227,8 +2046,8 @@ PackedStringArray _ClassDB::get_class_list() const {
return ret;
}
-PackedStringArray _ClassDB::get_inheriters_from_class(const StringName &p_class) const {
+PackedStringArray _ClassDB::get_inheriters_from_class(const StringName &p_class) const {
List<StringName> classes;
ClassDB::get_inheriters_from_class(p_class, &classes);
@@ -2241,27 +2060,28 @@ PackedStringArray _ClassDB::get_inheriters_from_class(const StringName &p_class)
return ret;
}
-StringName _ClassDB::get_parent_class(const StringName &p_class) const {
+StringName _ClassDB::get_parent_class(const StringName &p_class) const {
return ClassDB::get_parent_class(p_class);
}
-bool _ClassDB::class_exists(const StringName &p_class) const {
+bool _ClassDB::class_exists(const StringName &p_class) const {
return ClassDB::class_exists(p_class);
}
-bool _ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) const {
+bool _ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) const {
return ClassDB::is_parent_class(p_class, p_inherits);
}
-bool _ClassDB::can_instance(const StringName &p_class) const {
+bool _ClassDB::can_instance(const StringName &p_class) const {
return ClassDB::can_instance(p_class);
}
-Variant _ClassDB::instance(const StringName &p_class) const {
+Variant _ClassDB::instance(const StringName &p_class) const {
Object *obj = ClassDB::instance(p_class);
- if (!obj)
+ if (!obj) {
return Variant();
+ }
Reference *r = Object::cast_to<Reference>(obj);
if (r) {
@@ -2272,11 +2092,10 @@ Variant _ClassDB::instance(const StringName &p_class) const {
}
bool _ClassDB::has_signal(StringName p_class, StringName p_signal) const {
-
return ClassDB::has_signal(p_class, p_signal);
}
-Dictionary _ClassDB::get_signal(StringName p_class, StringName p_signal) const {
+Dictionary _ClassDB::get_signal(StringName p_class, StringName p_signal) const {
MethodInfo signal;
if (ClassDB::get_signal(p_class, p_signal, &signal)) {
return signal.operator Dictionary();
@@ -2284,8 +2103,8 @@ Dictionary _ClassDB::get_signal(StringName p_class, StringName p_signal) const {
return Dictionary();
}
}
-Array _ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const {
+Array _ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const {
List<MethodInfo> signals;
ClassDB::get_signal_list(p_class, &signals, p_no_inheritance);
Array ret;
@@ -2298,7 +2117,6 @@ Array _ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const
}
Array _ClassDB::get_property_list(StringName p_class, bool p_no_inheritance) const {
-
List<PropertyInfo> plist;
ClassDB::get_property_list(p_class, &plist, p_no_inheritance);
Array ret;
@@ -2327,12 +2145,10 @@ Error _ClassDB::set_property(Object *p_object, const StringName &p_property, con
}
bool _ClassDB::has_method(StringName p_class, StringName p_method, bool p_no_inheritance) const {
-
return ClassDB::has_method(p_class, p_method, p_no_inheritance);
}
Array _ClassDB::get_method_list(StringName p_class, bool p_no_inheritance) const {
-
List<MethodInfo> methods;
ClassDB::get_method_list(p_class, &methods, p_no_inheritance);
Array ret;
@@ -2351,7 +2167,6 @@ Array _ClassDB::get_method_list(StringName p_class, bool p_no_inheritance) const
}
PackedStringArray _ClassDB::get_integer_constant_list(const StringName &p_class, bool p_no_inheritance) const {
-
List<String> constants;
ClassDB::get_integer_constant_list(p_class, &constants, p_no_inheritance);
@@ -2366,31 +2181,27 @@ PackedStringArray _ClassDB::get_integer_constant_list(const StringName &p_class,
}
bool _ClassDB::has_integer_constant(const StringName &p_class, const StringName &p_name) const {
-
bool success;
ClassDB::get_integer_constant(p_class, p_name, &success);
return success;
}
int _ClassDB::get_integer_constant(const StringName &p_class, const StringName &p_name) const {
-
bool found;
int c = ClassDB::get_integer_constant(p_class, p_name, &found);
ERR_FAIL_COND_V(!found, 0);
return c;
}
-StringName _ClassDB::get_category(const StringName &p_node) const {
+StringName _ClassDB::get_category(const StringName &p_node) const {
return ClassDB::get_category(p_node);
}
bool _ClassDB::is_class_enabled(StringName p_class) const {
-
return ClassDB::is_class_enabled(p_class);
}
void _ClassDB::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_class_list"), &_ClassDB::get_class_list);
ClassDB::bind_method(D_METHOD("get_inheriters_from_class", "class"), &_ClassDB::get_inheriters_from_class);
ClassDB::bind_method(D_METHOD("get_parent_class", "class"), &_ClassDB::get_parent_class);
@@ -2420,18 +2231,13 @@ void _ClassDB::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_class_enabled", "class"), &_ClassDB::is_class_enabled);
}
-_ClassDB::_ClassDB() {
-}
-_ClassDB::~_ClassDB() {
-}
-///////////////////////////////
+////// _Engine //////
void _Engine::set_iterations_per_second(int p_ips) {
-
Engine::get_singleton()->set_iterations_per_second(p_ips);
}
-int _Engine::get_iterations_per_second() const {
+int _Engine::get_iterations_per_second() const {
return Engine::get_singleton()->get_iterations_per_second();
}
@@ -2456,17 +2262,14 @@ int _Engine::get_target_fps() const {
}
float _Engine::get_frames_per_second() const {
-
return Engine::get_singleton()->get_frames_per_second();
}
uint64_t _Engine::get_physics_frames() const {
-
return Engine::get_singleton()->get_physics_frames();
}
uint64_t _Engine::get_idle_frames() const {
-
return Engine::get_singleton()->get_idle_frames();
}
@@ -2475,23 +2278,19 @@ void _Engine::set_time_scale(float p_scale) {
}
float _Engine::get_time_scale() {
-
return Engine::get_singleton()->get_time_scale();
}
int _Engine::get_frames_drawn() {
-
return Engine::get_singleton()->get_frames_drawn();
}
MainLoop *_Engine::get_main_loop() const {
-
//needs to remain in OS, since it's actually OS that interacts with it, but it's better exposed here
return OS::get_singleton()->get_main_loop();
}
Dictionary _Engine::get_version_info() const {
-
return Engine::get_singleton()->get_version_info();
}
@@ -2520,27 +2319,22 @@ bool _Engine::is_in_physics_frame() const {
}
bool _Engine::has_singleton(const String &p_name) const {
-
return Engine::get_singleton()->has_singleton(p_name);
}
Object *_Engine::get_singleton_object(const String &p_name) const {
-
return Engine::get_singleton()->get_singleton_object(p_name);
}
void _Engine::set_editor_hint(bool p_enabled) {
-
Engine::get_singleton()->set_editor_hint(p_enabled);
}
bool _Engine::is_editor_hint() const {
-
return Engine::get_singleton()->is_editor_hint();
}
void _Engine::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_iterations_per_second", "iterations_per_second"), &_Engine::set_iterations_per_second);
ClassDB::bind_method(D_METHOD("get_iterations_per_second"), &_Engine::get_iterations_per_second);
ClassDB::bind_method(D_METHOD("set_physics_jitter_fix", "physics_jitter_fix"), &_Engine::set_physics_jitter_fix);
@@ -2583,9 +2377,7 @@ void _Engine::_bind_methods() {
_Engine *_Engine::singleton = nullptr;
-_Engine::_Engine() {
- singleton = this;
-}
+////// _JSON //////
void JSONParseResult::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_error"), &JSONParseResult::get_error);
@@ -2658,7 +2450,3 @@ Ref<JSONParseResult> _JSON::parse(const String &p_json) {
}
_JSON *_JSON::singleton = nullptr;
-
-_JSON::_JSON() {
- singleton = this;
-}
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index d5f44cdc44..e5bd70262d 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -69,7 +69,7 @@ public:
bool has_cached(const String &p_path);
bool exists(const String &p_path, const String &p_type_hint = "");
- _ResourceLoader();
+ _ResourceLoader() { singleton = this; }
};
VARIANT_ENUM_CAST(_ResourceLoader::ThreadLoadStatus);
@@ -98,7 +98,7 @@ public:
Error save(const String &p_path, const RES &p_resource, SaverFlags p_flags);
Vector<String> get_recognized_extensions(const RES &p_resource);
- _ResourceSaver();
+ _ResourceSaver() { singleton = this; }
};
VARIANT_ENUM_CAST(_ResourceSaver::SaverFlags);
@@ -243,9 +243,14 @@ public:
bool request_permissions();
Vector<String> get_granted_permissions() const;
+ int get_tablet_driver_count() const;
+ String get_tablet_driver_name(int p_driver) const;
+ String get_current_tablet_driver() const;
+ void set_current_tablet_driver(const String &p_driver);
+
static _OS *get_singleton() { return singleton; }
- _OS();
+ _OS() { singleton = this; }
};
VARIANT_ENUM_CAST(_OS::VideoDriver);
@@ -254,7 +259,6 @@ VARIANT_ENUM_CAST(_OS::Month);
VARIANT_ENUM_CAST(_OS::SystemDir);
class _Geometry : public Object {
-
GDCLASS(_Geometry, Object);
static _Geometry *singleton;
@@ -327,7 +331,7 @@ public:
Dictionary make_atlas(const Vector<Size2> &p_rects);
- _Geometry();
+ _Geometry() { singleton = this; }
};
VARIANT_ENUM_CAST(_Geometry::PolyBooleanOperation);
@@ -335,10 +339,10 @@ VARIANT_ENUM_CAST(_Geometry::PolyJoinType);
VARIANT_ENUM_CAST(_Geometry::PolyEndType);
class _File : public Reference {
-
GDCLASS(_File, Reference);
- FileAccess *f;
- bool eswap;
+
+ FileAccess *f = nullptr;
+ bool eswap = false;
protected:
static void _bind_methods();
@@ -429,7 +433,7 @@ public:
uint64_t get_modified_time(const String &p_file) const;
- _File();
+ _File() {}
virtual ~_File();
};
@@ -437,7 +441,6 @@ VARIANT_ENUM_CAST(_File::ModeFlags);
VARIANT_ENUM_CAST(_File::CompressionMode);
class _Directory : public Reference {
-
GDCLASS(_Directory, Reference);
DirAccess *d;
@@ -481,7 +484,6 @@ private:
};
class _Marshalls : public Object {
-
GDCLASS(_Marshalls, Object);
static _Marshalls *singleton;
@@ -506,7 +508,6 @@ public:
};
class _Mutex : public Reference {
-
GDCLASS(_Mutex, Reference);
Mutex mutex;
@@ -519,7 +520,6 @@ public:
};
class _Semaphore : public Reference {
-
GDCLASS(_Semaphore, Reference);
Semaphore semaphore;
@@ -532,16 +532,15 @@ public:
};
class _Thread : public Reference {
-
GDCLASS(_Thread, Reference);
protected:
Variant ret;
Variant userdata;
- volatile bool active;
- Object *target_instance;
+ volatile bool active = false;
+ Object *target_instance = nullptr;
StringName target_method;
- Thread *thread;
+ Thread *thread = nullptr;
static void _bind_methods();
static void _start_func(void *ud);
@@ -559,14 +558,13 @@ public:
bool is_active() const;
Variant wait_to_finish();
- _Thread();
+ _Thread() {}
~_Thread();
};
VARIANT_ENUM_CAST(_Thread::Priority);
class _ClassDB : public Object {
-
GDCLASS(_ClassDB, Object);
protected:
@@ -600,8 +598,8 @@ public:
bool is_class_enabled(StringName p_class) const;
- _ClassDB();
- ~_ClassDB();
+ _ClassDB() {}
+ ~_ClassDB() {}
};
class _Engine : public Object {
@@ -649,7 +647,7 @@ public:
void set_editor_hint(bool p_enabled);
bool is_editor_hint() const;
- _Engine();
+ _Engine() { singleton = this; }
};
class _JSON;
@@ -661,7 +659,7 @@ class JSONParseResult : public Reference {
Error error;
String error_string;
- int error_line;
+ int error_line = -1;
Variant result;
@@ -681,8 +679,7 @@ public:
void set_result(const Variant &p_result);
Variant get_result() const;
- JSONParseResult() :
- error_line(-1) {}
+ JSONParseResult() {}
};
class _JSON : public Object {
@@ -698,7 +695,7 @@ public:
String print(const Variant &p_value, const String &p_indent = "", bool p_sort_keys = false);
Ref<JSONParseResult> parse(const String &p_json);
- _JSON();
+ _JSON() { singleton = this; }
};
#endif // CORE_BIND_H
diff --git a/core/callable.cpp b/core/callable.cpp
index 6a5dc151e5..b7bdc715f8 100644
--- a/core/callable.cpp
+++ b/core/callable.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "callable.h"
+
#include "core/script_language.h"
#include "message_queue.h"
#include "object.h"
@@ -39,7 +40,6 @@ void Callable::call_deferred(const Variant **p_arguments, int p_argcount) const
}
void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, CallError &r_call_error) const {
-
if (is_null()) {
r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
r_call_error.argument = 0;
@@ -72,6 +72,7 @@ ObjectID Callable::get_object_id() const {
return ObjectID(object);
}
}
+
StringName Callable::get_method() const {
ERR_FAIL_COND_V_MSG(is_custom(), StringName(),
vformat("Can't get method on CallableCustom \"%s\".", operator String()));
@@ -117,9 +118,11 @@ bool Callable::operator==(const Callable &p_callable) const {
return false;
}
}
+
bool Callable::operator!=(const Callable &p_callable) const {
return !(*this == p_callable);
}
+
bool Callable::operator<(const Callable &p_callable) const {
bool custom_a = is_custom();
bool custom_b = p_callable.is_custom();
@@ -178,7 +181,6 @@ void Callable::operator=(const Callable &p_callable) {
}
Callable::operator String() const {
-
if (is_custom()) {
return custom->get_as_text();
} else {
@@ -191,7 +193,6 @@ Callable::operator String() const {
String class_name = base->get_class();
Ref<Script> script = base->get_script();
if (script.is_valid() && script->get_path().is_resource_file()) {
-
class_name += "(" + script->get_path().get_file() + ")";
}
return class_name + "::" + String(method);
@@ -224,6 +225,7 @@ Callable::Callable(ObjectID p_object, const StringName &p_method) {
object = p_object;
method = p_method;
}
+
Callable::Callable(CallableCustom *p_custom) {
if (p_custom->referenced) {
object = 0;
@@ -233,6 +235,7 @@ Callable::Callable(CallableCustom *p_custom) {
object = 0; //ensure object is all zero, since pointer may be 32 bits
custom = p_custom;
}
+
Callable::Callable(const Callable &p_callable) {
if (p_callable.is_custom()) {
if (!p_callable.custom->ref_count.ref()) {
@@ -255,12 +258,7 @@ Callable::~Callable() {
}
}
-Callable::Callable() {
- object = 0;
-}
-
CallableCustom::CallableCustom() {
- referenced = false;
ref_count.init();
}
@@ -269,9 +267,11 @@ CallableCustom::CallableCustom() {
Object *Signal::get_object() const {
return ObjectDB::get_instance(object);
}
+
ObjectID Signal::get_object_id() const {
return object;
}
+
StringName Signal::get_name() const {
return name;
}
@@ -298,7 +298,6 @@ Signal::operator String() const {
String class_name = base->get_class();
Ref<Script> script = base->get_script();
if (script.is_valid() && script->get_path().is_resource_file()) {
-
class_name += "(" + script->get_path().get_file() + ")";
}
return class_name + "::[signal]" + String(name);
@@ -315,18 +314,20 @@ Error Signal::emit(const Variant **p_arguments, int p_argcount) const {
return obj->emit_signal(name, p_arguments, p_argcount);
}
-Error Signal::connect(const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) {
+Error Signal::connect(const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) {
Object *object = get_object();
ERR_FAIL_COND_V(!object, ERR_UNCONFIGURED);
return object->connect(name, p_callable, p_binds, p_flags);
}
+
void Signal::disconnect(const Callable &p_callable) {
Object *object = get_object();
ERR_FAIL_COND(!object);
object->disconnect(name, p_callable);
}
+
bool Signal::is_connected(const Callable &p_callable) const {
Object *object = get_object();
ERR_FAIL_COND_V(!object, false);
@@ -349,17 +350,15 @@ Array Signal::get_connections() const {
}
return arr;
}
-Signal::Signal(const Object *p_object, const StringName &p_name) {
+Signal::Signal(const Object *p_object, const StringName &p_name) {
ERR_FAIL_COND_MSG(p_object == nullptr, "Object argument to Signal constructor must be non-null");
object = p_object->get_instance_id();
name = p_name;
}
-Signal::Signal(ObjectID p_object, const StringName &p_name) {
+Signal::Signal(ObjectID p_object, const StringName &p_name) {
object = p_object;
name = p_name;
}
-Signal::Signal() {
-}
diff --git a/core/callable.h b/core/callable.h
index 7fa024dccd..7fd6b54cf7 100644
--- a/core/callable.h
+++ b/core/callable.h
@@ -45,11 +45,10 @@ class CallableCustom;
// but can be optimized or customized.
class Callable {
-
//needs to be max 16 bytes in 64 bits
StringName method;
union {
- uint64_t object;
+ uint64_t object = 0;
CallableCustom *custom;
};
@@ -75,7 +74,7 @@ public:
return method == StringName() && object == 0;
}
_FORCE_INLINE_ bool is_custom() const {
- return method == StringName() && custom != 0;
+ return method == StringName() && custom != nullptr;
}
_FORCE_INLINE_ bool is_standard() const {
return method != StringName();
@@ -100,14 +99,14 @@ public:
Callable(ObjectID p_object, const StringName &p_method);
Callable(CallableCustom *p_custom);
Callable(const Callable &p_callable);
- Callable();
+ Callable() {}
~Callable();
};
class CallableCustom {
friend class Callable;
SafeRefCount ref_count;
- bool referenced;
+ bool referenced = false;
public:
typedef bool (*CompareEqualFunc)(const CallableCustom *p_a, const CallableCustom *p_b);
@@ -156,7 +155,7 @@ public:
Array get_connections() const;
Signal(const Object *p_object, const StringName &p_name);
Signal(ObjectID p_object, const StringName &p_name);
- Signal();
+ Signal() {}
};
#endif // CALLABLE_H
diff --git a/core/callable_method_pointer.cpp b/core/callable_method_pointer.cpp
index 8774af6add..21a917cbd7 100644
--- a/core/callable_method_pointer.cpp
+++ b/core/callable_method_pointer.cpp
@@ -48,7 +48,6 @@ bool CallableCustomMethodPointerBase::compare_equal(const CallableCustom *p_a, c
}
bool CallableCustomMethodPointerBase::compare_less(const CallableCustom *p_a, const CallableCustom *p_b) {
-
const CallableCustomMethodPointerBase *a = static_cast<const CallableCustomMethodPointerBase *>(p_a);
const CallableCustomMethodPointerBase *b = static_cast<const CallableCustomMethodPointerBase *>(p_b);
diff --git a/core/callable_method_pointer.h b/core/callable_method_pointer.h
index fb809c2b44..22db7d1c82 100644
--- a/core/callable_method_pointer.h
+++ b/core/callable_method_pointer.h
@@ -38,7 +38,6 @@
#include "core/simple_type.h"
class CallableCustomMethodPointerBase : public CallableCustom {
-
uint32_t *comp_ptr;
uint32_t comp_size;
uint32_t h;
@@ -74,7 +73,6 @@ public:
template <class T>
struct VariantCasterAndValidate {
-
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
@@ -89,7 +87,6 @@ struct VariantCasterAndValidate {
template <class T>
struct VariantCasterAndValidate<T &> {
-
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
@@ -104,7 +101,6 @@ struct VariantCasterAndValidate<T &> {
template <class T>
struct VariantCasterAndValidate<const T &> {
-
static _FORCE_INLINE_ T cast(const Variant **p_args, uint32_t p_arg_idx, Callable::CallError &r_error) {
Variant::Type argtype = GetTypeInfo<T>::VARIANT_TYPE;
if (!Variant::can_convert_strict(p_args[p_arg_idx]->get_type(), argtype)) {
@@ -163,23 +159,37 @@ void call_with_variant_args(T *p_instance, void (T::*p_method)(P...), const Vari
template <class T, class... P>
class CallableCustomMethodPointer : public CallableCustomMethodPointerBase {
-
struct Data {
T *instance;
+#ifdef DEBUG_ENABLED
+ uint64_t object_id;
+#endif
void (T::*method)(P...);
} data;
public:
- virtual ObjectID get_object() const { return data.instance->get_instance_id(); }
+ virtual ObjectID get_object() const {
+#ifdef DEBUG_ENABLED
+ if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
+ return ObjectID();
+ }
+#endif
+ return data.instance->get_instance_id();
+ }
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
-
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND_MSG(ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr, "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
+#endif
call_with_variant_args(data.instance, data.method, p_arguments, p_argcount, r_call_error);
}
CallableCustomMethodPointer(T *p_instance, void (T::*p_method)(P...)) {
zeromem(&data, sizeof(Data)); // Clear beforehand, may have padding bytes.
data.instance = p_instance;
+#ifdef DEBUG_ENABLED
+ data.object_id = p_instance->get_instance_id();
+#endif
data.method = p_method;
_setup((uint32_t *)&data, sizeof(Data));
}
@@ -246,24 +256,38 @@ void call_with_variant_args_ret(T *p_instance, R (T::*p_method)(P...), const Var
template <class T, class R, class... P>
class CallableCustomMethodPointerRet : public CallableCustomMethodPointerBase {
-
struct Data {
T *instance;
+#ifdef DEBUG_ENABLED
+ uint64_t object_id;
+#endif
R(T::*method)
(P...);
} data;
public:
- virtual ObjectID get_object() const { return data.instance->get_instance_id(); }
+ virtual ObjectID get_object() const {
+#ifdef DEBUG_ENABLED
+ if (ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr) {
+ return ObjectID();
+ }
+#endif
+ return data.instance->get_instance_id();
+ }
virtual void call(const Variant **p_arguments, int p_argcount, Variant &r_return_value, Callable::CallError &r_call_error) const {
-
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND_MSG(ObjectDB::get_instance(ObjectID(data.object_id)) == nullptr, "Invalid Object id '" + uitos(data.object_id) + "', can't call method.");
+#endif
call_with_variant_args_ret(data.instance, data.method, p_arguments, p_argcount, r_return_value, r_call_error);
}
CallableCustomMethodPointerRet(T *p_instance, R (T::*p_method)(P...)) {
zeromem(&data, sizeof(Data)); // Clear beforehand, may have padding bytes.
data.instance = p_instance;
+#ifdef DEBUG_ENABLED
+ data.object_id = p_instance->get_instance_id();
+#endif
data.method = p_method;
_setup((uint32_t *)&data, sizeof(Data));
}
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 5e49688e9b..eed9ec17cb 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -40,14 +40,12 @@
#ifdef DEBUG_METHODS_ENABLED
MethodDefinition D_METHOD(const char *p_name) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
return md;
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.push_back(StaticCString::create(p_arg1));
@@ -55,7 +53,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1) {
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(2);
@@ -65,7 +62,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(3);
@@ -76,7 +72,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(4);
@@ -88,7 +83,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(5);
@@ -101,7 +95,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(6);
@@ -115,7 +108,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(7);
@@ -130,7 +122,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(8);
@@ -146,7 +137,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(9);
@@ -163,7 +153,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(10);
@@ -181,7 +170,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(11);
@@ -200,7 +188,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(12);
@@ -220,7 +207,6 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
}
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11, const char *p_arg12, const char *p_arg13) {
-
MethodDefinition md;
md.name = StaticCString::create(p_name);
md.args.resize(13);
@@ -245,12 +231,10 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
ClassDB::APIType ClassDB::current_api = API_CORE;
void ClassDB::set_current_api(APIType p_api) {
-
current_api = p_api;
}
ClassDB::APIType ClassDB::get_current_api() {
-
return current_api;
}
@@ -258,42 +242,27 @@ HashMap<StringName, ClassDB::ClassInfo> ClassDB::classes;
HashMap<StringName, StringName> ClassDB::resource_base_extensions;
HashMap<StringName, StringName> ClassDB::compat_classes;
-ClassDB::ClassInfo::ClassInfo() {
-
- api = API_NONE;
- class_ptr = nullptr;
- creation_func = nullptr;
- inherits_ptr = nullptr;
- disabled = false;
- exposed = false;
-}
-
-ClassDB::ClassInfo::~ClassInfo() {
-}
-
bool ClassDB::is_parent_class(const StringName &p_class, const StringName &p_inherits) {
-
OBJTYPE_RLOCK;
StringName inherits = p_class;
while (inherits.operator String().length()) {
-
- if (inherits == p_inherits)
+ if (inherits == p_inherits) {
return true;
+ }
inherits = get_parent_class(inherits);
}
return false;
}
-void ClassDB::get_class_list(List<StringName> *p_classes) {
+void ClassDB::get_class_list(List<StringName> *p_classes) {
OBJTYPE_RLOCK;
const StringName *k = nullptr;
while ((k = classes.next(k))) {
-
p_classes->push_back(*k);
}
@@ -301,43 +270,40 @@ void ClassDB::get_class_list(List<StringName> *p_classes) {
}
void ClassDB::get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes) {
-
OBJTYPE_RLOCK;
const StringName *k = nullptr;
while ((k = classes.next(k))) {
-
- if (*k != p_class && is_parent_class(*k, p_class))
+ if (*k != p_class && is_parent_class(*k, p_class)) {
p_classes->push_back(*k);
+ }
}
}
void ClassDB::get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes) {
-
OBJTYPE_RLOCK;
const StringName *k = nullptr;
while ((k = classes.next(k))) {
-
- if (*k != p_class && get_parent_class(*k) == p_class)
+ if (*k != p_class && get_parent_class(*k) == p_class) {
p_classes->push_back(*k);
+ }
}
}
StringName ClassDB::get_parent_class_nocheck(const StringName &p_class) {
-
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
- if (!ti)
+ if (!ti) {
return StringName();
+ }
return ti->inherits;
}
StringName ClassDB::get_compatibility_remapped_class(const StringName &p_class) {
-
if (classes.has(p_class)) {
return p_class;
}
@@ -350,7 +316,6 @@ StringName ClassDB::get_compatibility_remapped_class(const StringName &p_class)
}
StringName ClassDB::get_parent_class(const StringName &p_class) {
-
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
@@ -359,7 +324,6 @@ StringName ClassDB::get_parent_class(const StringName &p_class) {
}
ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) {
-
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
@@ -369,7 +333,6 @@ ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) {
}
uint64_t ClassDB::get_api_hash(APIType p_api) {
-
OBJTYPE_RLOCK;
#ifdef DEBUG_METHODS_ENABLED
@@ -380,18 +343,17 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
const StringName *k = nullptr;
while ((k = classes.next(k))) {
-
names.push_back(*k);
}
//must be alphabetically sorted for hash to compute
names.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
-
ClassInfo *t = classes.getptr(E->get());
ERR_FAIL_COND_V_MSG(!t, 0, "Cannot get class '" + String(E->get()) + "'.");
- if (t->api != p_api || !t->exposed)
+ if (t->api != p_api || !t->exposed) {
continue;
+ }
hash = hash_djb2_one_64(t->name.hash(), hash);
hash = hash_djb2_one_64(t->inherits.hash(), hash);
@@ -402,13 +364,13 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
k = nullptr;
while ((k = t->method_map.next(k))) {
-
String name = k->operator String();
ERR_CONTINUE(name.empty());
- if (name[0] == '_')
+ if (name[0] == '_') {
continue; // Ignore non-virtual methods that start with an underscore
+ }
snames.push_back(*k);
}
@@ -416,7 +378,6 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
snames.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *F = snames.front(); F; F = F->next()) {
-
MethodBind *mb = t->method_map[F->get()];
hash = hash_djb2_one_64(mb->get_name().hash(), hash);
hash = hash_djb2_one_64(mb->get_argument_count(), hash);
@@ -449,14 +410,12 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
k = nullptr;
while ((k = t->constant_map.next(k))) {
-
snames.push_back(*k);
}
snames.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *F = snames.front(); F; F = F->next()) {
-
hash = hash_djb2_one_64(F->get().hash(), hash);
hash = hash_djb2_one_64(t->constant_map[F->get()], hash);
}
@@ -469,14 +428,12 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
k = nullptr;
while ((k = t->signal_map.next(k))) {
-
snames.push_back(*k);
}
snames.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *F = snames.front(); F; F = F->next()) {
-
MethodInfo &mi = t->signal_map[F->get()];
hash = hash_djb2_one_64(F->get().hash(), hash);
for (int i = 0; i < mi.arguments.size(); i++) {
@@ -492,14 +449,12 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
k = nullptr;
while ((k = t->property_setget.next(k))) {
-
snames.push_back(*k);
}
snames.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *F = snames.front(); F; F = F->next()) {
-
PropertySetGet *psg = t->property_setget.getptr(F->get());
ERR_FAIL_COND_V(!psg, 0);
@@ -511,7 +466,6 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
//property list
for (List<PropertyInfo>::Element *F = t->property_list.front(); F; F = F->next()) {
-
hash = hash_djb2_one_64(F->get().name.hash(), hash);
hash = hash_djb2_one_64(F->get().type, hash);
hash = hash_djb2_one_64(F->get().hint, hash);
@@ -527,19 +481,16 @@ uint64_t ClassDB::get_api_hash(APIType p_api) {
}
bool ClassDB::class_exists(const StringName &p_class) {
-
OBJTYPE_RLOCK;
return classes.has(p_class);
}
void ClassDB::add_compatibility_class(const StringName &p_class, const StringName &p_fallback) {
-
OBJTYPE_WLOCK;
compat_classes[p_class] = p_fallback;
}
Object *ClassDB::instance(const StringName &p_class) {
-
ClassInfo *ti;
{
OBJTYPE_RLOCK;
@@ -561,8 +512,8 @@ Object *ClassDB::instance(const StringName &p_class) {
#endif
return ti->creation_func();
}
-bool ClassDB::can_instance(const StringName &p_class) {
+bool ClassDB::can_instance(const StringName &p_class) {
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
@@ -576,7 +527,6 @@ bool ClassDB::can_instance(const StringName &p_class) {
}
void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherits) {
-
OBJTYPE_WLOCK;
const StringName &name = p_class;
@@ -590,7 +540,6 @@ void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherit
ti.api = current_api;
if (ti.inherits) {
-
ERR_FAIL_COND(!classes.has(ti.inherits)); //it MUST be registered.
ti.inherits_ptr = &classes[ti.inherits];
@@ -600,17 +549,15 @@ void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherit
}
void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) {
-
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
while (type) {
-
if (type->disabled) {
-
- if (p_no_inheritance)
+ if (p_no_inheritance) {
break;
+ }
type = type->inherits_ptr;
continue;
@@ -619,22 +566,20 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
#ifdef DEBUG_METHODS_ENABLED
for (List<MethodInfo>::Element *E = type->virtual_methods.front(); E; E = E->next()) {
-
p_methods->push_back(E->get());
}
for (List<StringName>::Element *E = type->method_order.front(); E; E = E->next()) {
-
MethodBind *method = type->method_map.get(E->get());
MethodInfo minfo;
minfo.name = E->get();
minfo.id = method->get_method_id();
- if (p_exclude_from_properties && type->methods_in_properties.has(minfo.name))
+ if (p_exclude_from_properties && type->methods_in_properties.has(minfo.name)) {
continue;
+ }
for (int i = 0; i < method->get_argument_count(); i++) {
-
//Variant::Type t=method->get_argument_type(i);
minfo.arguments.push_back(method->get_argument_info(i));
@@ -644,8 +589,9 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
minfo.flags = method->get_hint_flags();
for (int i = 0; i < method->get_argument_count(); i++) {
- if (method->has_default_argument(i))
+ if (method->has_default_argument(i)) {
minfo.default_arguments.push_back(method->get_default_argument(i));
+ }
}
p_methods->push_back(minfo);
@@ -656,7 +602,6 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
const StringName *K = nullptr;
while ((K = type->method_map.next(K))) {
-
MethodBind *m = type->method_map[*K];
MethodInfo mi;
mi.name = m->get_name();
@@ -665,31 +610,30 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
#endif
- if (p_no_inheritance)
+ if (p_no_inheritance) {
break;
+ }
type = type->inherits_ptr;
}
}
MethodBind *ClassDB::get_method(StringName p_class, StringName p_name) {
-
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
while (type) {
-
MethodBind **method = type->method_map.getptr(p_name);
- if (method && *method)
+ if (method && *method) {
return *method;
+ }
type = type->inherits_ptr;
}
return nullptr;
}
void ClassDB::bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int p_constant) {
-
OBJTYPE_WLOCK;
ClassInfo *type = classes.getptr(p_class);
@@ -697,7 +641,6 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
ERR_FAIL_COND(!type);
if (type->constant_map.has(p_name)) {
-
ERR_FAIL();
}
@@ -726,16 +669,15 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
}
void ClassDB::get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance) {
-
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
while (type) {
-
#ifdef DEBUG_METHODS_ENABLED
- for (List<StringName>::Element *E = type->constant_order.front(); E; E = E->next())
+ for (List<StringName>::Element *E = type->constant_order.front(); E; E = E->next()) {
p_constants->push_back(E->get());
+ }
#else
const StringName *K = nullptr;
@@ -744,57 +686,56 @@ void ClassDB::get_integer_constant_list(const StringName &p_class, List<String>
}
#endif
- if (p_no_inheritance)
+ if (p_no_inheritance) {
break;
+ }
type = type->inherits_ptr;
}
}
int ClassDB::get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success) {
-
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
while (type) {
-
int *constant = type->constant_map.getptr(p_name);
if (constant) {
-
- if (p_success)
+ if (p_success) {
*p_success = true;
+ }
return *constant;
}
type = type->inherits_ptr;
}
- if (p_success)
+ if (p_success) {
*p_success = false;
+ }
return 0;
}
StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
-
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
while (type) {
-
const StringName *k = nullptr;
while ((k = type->enum_map.next(k))) {
-
List<StringName> &constants_list = type->enum_map.get(*k);
const List<StringName>::Element *found = constants_list.find(p_name);
- if (found)
+ if (found) {
return *k;
+ }
}
- if (p_no_inheritance)
+ if (p_no_inheritance) {
break;
+ }
type = type->inherits_ptr;
}
@@ -803,33 +744,30 @@ StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const S
}
void ClassDB::get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance) {
-
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
while (type) {
-
const StringName *k = nullptr;
while ((k = type->enum_map.next(k))) {
p_enums->push_back(*k);
}
- if (p_no_inheritance)
+ if (p_no_inheritance) {
break;
+ }
type = type->inherits_ptr;
}
}
void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance) {
-
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
while (type) {
-
const List<StringName> *constants = type->enum_map.getptr(p_enum);
if (constants) {
@@ -838,15 +776,15 @@ void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_
}
}
- if (p_no_inheritance)
+ if (p_no_inheritance) {
break;
+ }
type = type->inherits_ptr;
}
}
void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) {
-
OBJTYPE_WLOCK;
ClassInfo *type = classes.getptr(p_class);
@@ -866,7 +804,6 @@ void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) {
}
void ClassDB::get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance) {
-
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
@@ -875,28 +812,27 @@ void ClassDB::get_signal_list(StringName p_class, List<MethodInfo> *p_signals, b
ClassInfo *check = type;
while (check) {
-
const StringName *S = nullptr;
while ((S = check->signal_map.next(S))) {
-
p_signals->push_back(check->signal_map[*S]);
}
- if (p_no_inheritance)
+ if (p_no_inheritance) {
return;
+ }
check = check->inherits_ptr;
}
}
bool ClassDB::has_signal(StringName p_class, StringName p_signal) {
-
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
- if (check->signal_map.has(p_signal))
+ if (check->signal_map.has(p_signal)) {
return true;
+ }
check = check->inherits_ptr;
}
@@ -904,7 +840,6 @@ bool ClassDB::has_signal(StringName p_class, StringName p_signal) {
}
bool ClassDB::get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal) {
-
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
@@ -922,7 +857,6 @@ bool ClassDB::get_signal(StringName p_class, StringName p_signal, MethodInfo *r_
}
void ClassDB::add_property_group(StringName p_class, const String &p_name, const String &p_prefix) {
-
OBJTYPE_WLOCK;
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_COND(!type);
@@ -931,7 +865,6 @@ void ClassDB::add_property_group(StringName p_class, const String &p_name, const
}
void ClassDB::add_property_subgroup(StringName p_class, const String &p_name, const String &p_prefix) {
-
OBJTYPE_WLOCK;
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_COND(!type);
@@ -940,7 +873,6 @@ void ClassDB::add_property_subgroup(StringName p_class, const String &p_name, co
}
void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index) {
-
lock->read_lock();
ClassInfo *type = classes.getptr(p_class);
lock->read_unlock();
@@ -961,7 +893,6 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
MethodBind *mb_get = nullptr;
if (p_getter) {
-
mb_get = get_method(p_class, p_getter);
#ifdef DEBUG_METHODS_ENABLED
@@ -1006,15 +937,12 @@ void ClassDB::set_property_default_value(StringName p_class, const StringName &p
}
void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator) {
-
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
-
for (List<PropertyInfo>::Element *E = check->property_list.front(); E; E = E->next()) {
-
if (p_validator) {
PropertyInfo pi = E->get();
p_validator->_validate_property(pi);
@@ -1024,22 +952,23 @@ void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list,
}
}
- if (p_no_inheritance)
+ if (p_no_inheritance) {
return;
+ }
check = check->inherits_ptr;
}
}
-bool ClassDB::set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid) {
+bool ClassDB::set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid) {
ClassInfo *type = classes.getptr(p_object->get_class_name());
ClassInfo *check = type;
while (check) {
const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) {
-
if (!psg->setter) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return true; //return true but do nothing
}
@@ -1064,8 +993,9 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
}
}
- if (r_valid)
+ if (r_valid) {
*r_valid = ce.error == Callable::CallError::CALL_OK;
+ }
return true;
}
@@ -1075,15 +1005,16 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
return false;
}
-bool ClassDB::get_property(Object *p_object, const StringName &p_property, Variant &r_value) {
+bool ClassDB::get_property(Object *p_object, const StringName &p_property, Variant &r_value) {
ClassInfo *type = classes.getptr(p_object->get_class_name());
ClassInfo *check = type;
while (check) {
const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) {
- if (!psg->getter)
+ if (!psg->getter) {
return true; //return true but do nothing
+ }
if (psg->index >= 0) {
Variant index = psg->index;
@@ -1092,10 +1023,8 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia
r_value = p_object->call(psg->getter, arg, 1, ce);
} else {
-
Callable::CallError ce;
if (psg->_getptr) {
-
r_value = psg->_getptr->call(p_object, nullptr, 0, ce);
} else {
r_value = p_object->call(psg->getter, nullptr, 0, ce);
@@ -1106,7 +1035,6 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia
const int *c = check->constant_map.getptr(p_property); //constants count
if (c) {
-
r_value = *c;
return true;
}
@@ -1128,57 +1056,55 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia
}
int ClassDB::get_property_index(const StringName &p_class, const StringName &p_property, bool *r_is_valid) {
-
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) {
-
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = true;
+ }
return psg->index;
}
check = check->inherits_ptr;
}
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = false;
+ }
return -1;
}
Variant::Type ClassDB::get_property_type(const StringName &p_class, const StringName &p_property, bool *r_is_valid) {
-
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) {
-
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = true;
+ }
return psg->type;
}
check = check->inherits_ptr;
}
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = false;
+ }
return Variant::NIL;
}
StringName ClassDB::get_property_setter(StringName p_class, const StringName &p_property) {
-
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) {
-
return psg->setter;
}
@@ -1189,13 +1115,11 @@ StringName ClassDB::get_property_setter(StringName p_class, const StringName &p_
}
StringName ClassDB::get_property_getter(StringName p_class, const StringName &p_property) {
-
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
const PropertySetGet *psg = check->property_setget.getptr(p_property);
if (psg) {
-
return psg->getter;
}
@@ -1206,15 +1130,16 @@ StringName ClassDB::get_property_getter(StringName p_class, const StringName &p_
}
bool ClassDB::has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance) {
-
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
- if (check->property_setget.has(p_property))
+ if (check->property_setget.has(p_property)) {
return true;
+ }
- if (p_no_inheritance)
+ if (p_no_inheritance) {
break;
+ }
check = check->inherits_ptr;
}
@@ -1222,7 +1147,6 @@ bool ClassDB::has_property(const StringName &p_class, const StringName &p_proper
}
void ClassDB::set_method_flags(StringName p_class, StringName p_method, int p_flags) {
-
OBJTYPE_WLOCK;
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
@@ -1232,14 +1156,15 @@ void ClassDB::set_method_flags(StringName p_class, StringName p_method, int p_fl
}
bool ClassDB::has_method(StringName p_class, StringName p_method, bool p_no_inheritance) {
-
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
- if (check->method_map.has(p_method))
+ if (check->method_map.has(p_method)) {
return true;
- if (p_no_inheritance)
+ }
+ if (p_no_inheritance) {
return false;
+ }
check = check->inherits_ptr;
}
@@ -1295,7 +1220,6 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const c
defvals.resize(p_defcount);
for (int i = 0; i < p_defcount; i++) {
-
defvals.write[i] = *p_defs[p_defcount - i - 1];
}
@@ -1311,15 +1235,15 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_
#ifdef DEBUG_METHODS_ENABLED
MethodInfo mi = p_method;
- if (p_virtual)
+ if (p_virtual) {
mi.flags |= METHOD_FLAG_VIRTUAL;
+ }
classes[p_class].virtual_methods.push_back(mi);
#endif
}
void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance) {
-
ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'.");
#ifdef DEBUG_METHODS_ENABLED
@@ -1327,13 +1251,13 @@ void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p
ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type;
while (check) {
-
for (List<MethodInfo>::Element *E = check->virtual_methods.front(); E; E = E->next()) {
p_methods->push_back(E->get());
}
- if (p_no_inheritance)
+ if (p_no_inheritance) {
return;
+ }
check = check->inherits_ptr;
}
@@ -1341,7 +1265,6 @@ void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p
}
void ClassDB::set_class_enabled(StringName p_class, bool p_enable) {
-
OBJTYPE_WLOCK;
ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'.");
@@ -1349,7 +1272,6 @@ void ClassDB::set_class_enabled(StringName p_class, bool p_enable) {
}
bool ClassDB::is_class_enabled(StringName p_class) {
-
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
@@ -1364,7 +1286,6 @@ bool ClassDB::is_class_enabled(StringName p_class) {
}
bool ClassDB::is_class_exposed(StringName p_class) {
-
OBJTYPE_RLOCK;
ClassInfo *ti = classes.getptr(p_class);
@@ -1373,7 +1294,6 @@ bool ClassDB::is_class_exposed(StringName p_class) {
}
StringName ClassDB::get_category(const StringName &p_node) {
-
ERR_FAIL_COND_V(!classes.has(p_node), StringName());
#ifdef DEBUG_ENABLED
return classes[p_node].category;
@@ -1383,31 +1303,29 @@ StringName ClassDB::get_category(const StringName &p_node) {
}
void ClassDB::add_resource_base_extension(const StringName &p_extension, const StringName &p_class) {
-
- if (resource_base_extensions.has(p_extension))
+ if (resource_base_extensions.has(p_extension)) {
return;
+ }
resource_base_extensions[p_extension] = p_class;
}
void ClassDB::get_resource_base_extensions(List<String> *p_extensions) {
-
const StringName *K = nullptr;
while ((K = resource_base_extensions.next(K))) {
-
p_extensions->push_back(*K);
}
}
void ClassDB::get_extensions_for_type(const StringName &p_class, List<String> *p_extensions) {
-
const StringName *K = nullptr;
while ((K = resource_base_extensions.next(K))) {
StringName cmp = resource_base_extensions[*K];
- if (is_parent_class(p_class, cmp) || is_parent_class(cmp, p_class))
+ if (is_parent_class(p_class, cmp) || is_parent_class(cmp, p_class)) {
p_extensions->push_back(*K);
+ }
}
}
@@ -1415,9 +1333,7 @@ HashMap<StringName, HashMap<StringName, Variant>> ClassDB::default_values;
Set<StringName> ClassDB::default_values_cached;
Variant ClassDB::class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid) {
-
if (!default_values_cached.has(p_class)) {
-
if (!default_values.has(p_class)) {
default_values[p_class] = HashMap<StringName, Variant>();
}
@@ -1434,12 +1350,10 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con
}
if (c) {
-
List<PropertyInfo> plist;
c->get_property_list(&plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
if (E->get().usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR)) {
-
if (!default_values[p_class].has(E->get().name)) {
Variant v = c->get(E->get().name);
default_values[p_class][E->get().name] = v;
@@ -1456,45 +1370,46 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con
}
if (!default_values.has(p_class)) {
- if (r_valid != nullptr) *r_valid = false;
+ if (r_valid != nullptr) {
+ *r_valid = false;
+ }
return Variant();
}
if (!default_values[p_class].has(p_property)) {
- if (r_valid != nullptr) *r_valid = false;
+ if (r_valid != nullptr) {
+ *r_valid = false;
+ }
return Variant();
}
- if (r_valid != nullptr) *r_valid = true;
+ if (r_valid != nullptr) {
+ *r_valid = true;
+ }
return default_values[p_class][p_property];
}
RWLock *ClassDB::lock = nullptr;
void ClassDB::init() {
-
lock = RWLock::create();
}
void ClassDB::cleanup_defaults() {
-
default_values.clear();
default_values_cached.clear();
}
void ClassDB::cleanup() {
-
//OBJTYPE_LOCK; hah not here
const StringName *k = nullptr;
while ((k = classes.next(k))) {
-
ClassInfo &ti = classes[*k];
const StringName *m = nullptr;
while ((m = ti.method_map.next(m))) {
-
memdelete(ti.method_map[*m]);
}
}
diff --git a/core/class_db.h b/core/class_db.h
index f760aa1738..eae2a9afd4 100644
--- a/core/class_db.h
+++ b/core/class_db.h
@@ -48,7 +48,6 @@
#ifdef DEBUG_METHODS_ENABLED
struct MethodDefinition {
-
StringName name;
Vector<StringName> args;
MethodDefinition() {}
@@ -103,7 +102,6 @@ public:
public:
struct PropertySetGet {
-
int index;
StringName setter;
StringName getter;
@@ -113,10 +111,10 @@ public:
};
struct ClassInfo {
+ APIType api = API_NONE;
+ ClassInfo *inherits_ptr = nullptr;
+ void *class_ptr = nullptr;
- APIType api;
- ClassInfo *inherits_ptr;
- void *class_ptr;
HashMap<StringName, MethodBind *> method_map;
HashMap<StringName, int> constant_map;
HashMap<StringName, List<StringName>> enum_map;
@@ -133,11 +131,12 @@ public:
StringName inherits;
StringName name;
- bool disabled;
- bool exposed;
- Object *(*creation_func)();
- ClassInfo();
- ~ClassInfo();
+ bool disabled = false;
+ bool exposed = false;
+ Object *(*creation_func)() = nullptr;
+
+ ClassInfo() {}
+ ~ClassInfo() {}
};
template <class T>
@@ -167,13 +166,11 @@ public:
// DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!!
template <class T>
static void _add_class() {
-
_add_class2(T::get_class_static(), T::get_parent_class_static());
}
template <class T>
static void register_class() {
-
GLOBAL_LOCK_FUNCTION;
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
@@ -186,7 +183,6 @@ public:
template <class T>
static void register_virtual_class() {
-
GLOBAL_LOCK_FUNCTION;
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
@@ -198,13 +194,11 @@ public:
template <class T>
static Object *_create_ptr_func() {
-
return T::create();
}
template <class T>
static void register_custom_instance_class() {
-
GLOBAL_LOCK_FUNCTION;
T::initialize_class();
ClassInfo *t = classes.getptr(T::get_class_static());
@@ -231,7 +225,6 @@ public:
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method) {
-
MethodBind *bind = create_method_bind(p_method);
return bind_methodfi(METHOD_FLAGS_DEFAULT, bind, p_method_name, nullptr, 0); //use static function, much smaller binary usage
@@ -239,7 +232,6 @@ public:
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1) {
-
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[1] = { &p_def1 };
@@ -248,7 +240,6 @@ public:
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2) {
-
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[2] = { &p_def1, &p_def2 };
@@ -257,7 +248,6 @@ public:
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3) {
-
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[3] = { &p_def1, &p_def2, &p_def3 };
@@ -266,7 +256,6 @@ public:
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4) {
-
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[4] = { &p_def1, &p_def2, &p_def3, &p_def4 };
@@ -275,7 +264,6 @@ public:
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5) {
-
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[5] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5 };
@@ -284,7 +272,6 @@ public:
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6) {
-
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[6] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6 };
@@ -293,7 +280,6 @@ public:
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7) {
-
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[7] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7 };
@@ -302,7 +288,6 @@ public:
template <class N, class M>
static MethodBind *bind_method(N p_method_name, M p_method, const Variant &p_def1, const Variant &p_def2, const Variant &p_def3, const Variant &p_def4, const Variant &p_def5, const Variant &p_def6, const Variant &p_def7, const Variant &p_def8) {
-
MethodBind *bind = create_method_bind(p_method);
const Variant *ptr[8] = { &p_def1, &p_def2, &p_def3, &p_def4, &p_def5, &p_def6, &p_def7, &p_def8 };
@@ -311,7 +296,6 @@ public:
template <class M>
static MethodBind *bind_vararg_method(uint32_t p_flags, StringName p_name, M p_method, const MethodInfo &p_info = MethodInfo(), const Vector<Variant> &p_default_args = Vector<Variant>(), bool p_return_nil_is_variant = true) {
-
GLOBAL_LOCK_FUNCTION;
MethodBind *bind = create_vararg_method_bind(p_method, p_info, p_return_nil_is_variant);
diff --git a/core/color.cpp b/core/color.cpp
index 03aeb2085b..27a2d0af5c 100644
--- a/core/color.cpp
+++ b/core/color.cpp
@@ -36,7 +36,6 @@
#include "core/print_string.h"
uint32_t Color::to_argb32() const {
-
uint32_t c = (uint8_t)Math::round(a * 255);
c <<= 8;
c |= (uint8_t)Math::round(r * 255);
@@ -49,7 +48,6 @@ uint32_t Color::to_argb32() const {
}
uint32_t Color::to_abgr32() const {
-
uint32_t c = (uint8_t)Math::round(a * 255);
c <<= 8;
c |= (uint8_t)Math::round(b * 255);
@@ -62,7 +60,6 @@ uint32_t Color::to_abgr32() const {
}
uint32_t Color::to_rgba32() const {
-
uint32_t c = (uint8_t)Math::round(r * 255);
c <<= 8;
c |= (uint8_t)Math::round(g * 255);
@@ -75,7 +72,6 @@ uint32_t Color::to_rgba32() const {
}
uint64_t Color::to_abgr64() const {
-
uint64_t c = (uint16_t)Math::round(a * 65535);
c <<= 16;
c |= (uint16_t)Math::round(b * 65535);
@@ -88,7 +84,6 @@ uint64_t Color::to_abgr64() const {
}
uint64_t Color::to_argb64() const {
-
uint64_t c = (uint16_t)Math::round(a * 65535);
c <<= 16;
c |= (uint16_t)Math::round(r * 65535);
@@ -101,7 +96,6 @@ uint64_t Color::to_argb64() const {
}
uint64_t Color::to_rgba64() const {
-
uint64_t c = (uint16_t)Math::round(r * 65535);
c <<= 16;
c |= (uint16_t)Math::round(g * 65535);
@@ -114,7 +108,6 @@ uint64_t Color::to_rgba64() const {
}
float Color::get_h() const {
-
float min = MIN(r, g);
min = MIN(min, b);
float max = MAX(r, g);
@@ -122,26 +115,28 @@ float Color::get_h() const {
float delta = max - min;
- if (delta == 0)
+ if (delta == 0) {
return 0;
+ }
float h;
- if (r == max)
+ if (r == max) {
h = (g - b) / delta; // between yellow & magenta
- else if (g == max)
+ } else if (g == max) {
h = 2 + (b - r) / delta; // between cyan & yellow
- else
+ } else {
h = 4 + (r - g) / delta; // between magenta & cyan
+ }
h /= 6.0;
- if (h < 0)
+ if (h < 0) {
h += 1.0;
+ }
return h;
}
float Color::get_s() const {
-
float min = MIN(r, g);
min = MIN(min, b);
float max = MAX(r, g);
@@ -153,14 +148,12 @@ float Color::get_s() const {
}
float Color::get_v() const {
-
float max = MAX(r, g);
max = MAX(max, b);
return max;
}
void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
-
int i;
float f, p, q, t;
a = p_alpha;
@@ -215,25 +208,22 @@ void Color::set_hsv(float p_h, float p_s, float p_v, float p_alpha) {
}
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);
}
void Color::invert() {
-
r = 1.0 - r;
g = 1.0 - g;
b = 1.0 - b;
}
-void Color::contrast() {
+void Color::contrast() {
r = Math::fmod(r + 0.5, 1.0);
g = Math::fmod(g + 0.5, 1.0);
b = Math::fmod(b + 0.5, 1.0);
}
Color Color::hex(uint32_t p_hex) {
-
float a = (p_hex & 0xFF) / 255.0;
p_hex >>= 8;
float b = (p_hex & 0xFF) / 255.0;
@@ -246,7 +236,6 @@ Color Color::hex(uint32_t p_hex) {
}
Color Color::hex64(uint64_t p_hex) {
-
float a = (p_hex & 0xFFFF) / 65535.0;
p_hex >>= 16;
float b = (p_hex & 0xFFFF) / 65535.0;
@@ -259,7 +248,6 @@ Color Color::hex64(uint64_t p_hex) {
}
Color Color::from_rgbe9995(uint32_t p_rgbe) {
-
float r = p_rgbe & 0x1ff;
float g = (p_rgbe >> 9) & 0x1ff;
float b = (p_rgbe >> 18) & 0x1ff;
@@ -274,11 +262,9 @@ Color Color::from_rgbe9995(uint32_t p_rgbe) {
}
static float _parse_col(const String &p_str, int p_ofs) {
-
int ig = 0;
for (int i = 0; i < 2; i++) {
-
int c = p_str[i + p_ofs];
int v = 0;
@@ -294,36 +280,36 @@ static float _parse_col(const String &p_str, int p_ofs) {
return -1;
}
- if (i == 0)
+ if (i == 0) {
ig += v * 16;
- else
+ } else {
ig += v;
+ }
}
return ig;
}
Color Color::inverted() const {
-
Color c = *this;
c.invert();
return c;
}
Color Color::contrasted() const {
-
Color c = *this;
c.contrast();
return c;
}
Color Color::html(const String &p_color) {
-
String color = p_color;
- if (color.length() == 0)
+ if (color.length() == 0) {
return Color();
- if (color[0] == '#')
+ }
+ if (color[0] == '#') {
color = color.substr(1, color.length() - 1);
+ }
if (color.length() == 3 || color.length() == 4) {
String exp_color;
for (int i = 0; i < color.length(); i++) {
@@ -362,13 +348,14 @@ Color Color::html(const String &p_color) {
}
bool Color::html_is_valid(const String &p_color) {
-
String color = p_color;
- if (color.length() == 0)
+ if (color.length() == 0) {
return false;
- if (color[0] == '#')
+ }
+ if (color[0] == '#') {
color = color.substr(1, color.length() - 1);
+ }
bool alpha = false;
@@ -406,7 +393,9 @@ bool Color::html_is_valid(const String &p_color) {
}
Color Color::named(const String &p_name) {
- if (_named_colors.empty()) _populate_named_colors(); // from color_names.inc
+ if (_named_colors.empty()) {
+ _populate_named_colors(); // from color_names.inc
+ }
String name = p_name;
// Normalize name
name = name.replace(" ", "");
@@ -422,19 +411,18 @@ Color Color::named(const String &p_name) {
}
String _to_hex(float p_val) {
-
int v = Math::round(p_val * 255);
v = CLAMP(v, 0, 255);
String ret;
for (int i = 0; i < 2; i++) {
-
CharType c[2] = { 0, 0 };
int lv = v & 0xF;
- if (lv < 10)
+ if (lv < 10) {
c[0] = '0' + lv;
- else
+ } else {
c[0] = 'a' + lv - 10;
+ }
v >>= 4;
String cs = (const CharType *)c;
@@ -445,21 +433,21 @@ String _to_hex(float p_val) {
}
String Color::to_html(bool p_alpha) const {
-
String txt;
txt += _to_hex(r);
txt += _to_hex(g);
txt += _to_hex(b);
- if (p_alpha)
+ if (p_alpha) {
txt = _to_hex(a) + txt;
+ }
return txt;
}
Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
-
p_h = Math::fmod(p_h * 360.0f, 360.0f);
- if (p_h < 0.0)
+ if (p_h < 0.0) {
p_h += 360.0f;
+ }
const float h_ = p_h / 60.0f;
const float c = p_v * p_s;
@@ -509,12 +497,10 @@ Color Color::from_hsv(float p_h, float p_s, float p_v, float p_a) const {
}
Color::operator String() const {
-
return rtos(r) + ", " + rtos(g) + ", " + rtos(b) + ", " + rtos(a);
}
Color Color::operator+(const Color &p_color) const {
-
return Color(
r + p_color.r,
g + p_color.g,
@@ -523,7 +509,6 @@ Color Color::operator+(const Color &p_color) const {
}
Color Color::operator-(const Color &p_color) const {
-
return Color(
r - p_color.r,
g - p_color.g,
@@ -532,7 +517,6 @@ Color Color::operator-(const Color &p_color) const {
}
void Color::operator-=(const Color &p_color) {
-
r = r - p_color.r;
g = g - p_color.g;
b = b - p_color.b;
@@ -540,7 +524,6 @@ void Color::operator-=(const Color &p_color) {
}
Color Color::operator*(const Color &p_color) const {
-
return Color(
r * p_color.r,
g * p_color.g,
@@ -549,7 +532,6 @@ Color Color::operator*(const Color &p_color) const {
}
Color Color::operator*(const real_t &rvalue) const {
-
return Color(
r * rvalue,
g * rvalue,
@@ -558,7 +540,6 @@ Color Color::operator*(const real_t &rvalue) const {
}
void Color::operator*=(const Color &p_color) {
-
r = r * p_color.r;
g = g * p_color.g;
b = b * p_color.b;
@@ -566,7 +547,6 @@ void Color::operator*=(const Color &p_color) {
}
void Color::operator*=(const real_t &rvalue) {
-
r = r * rvalue;
g = g * rvalue;
b = b * rvalue;
@@ -574,7 +554,6 @@ void Color::operator*=(const real_t &rvalue) {
}
Color Color::operator/(const Color &p_color) const {
-
return Color(
r / p_color.r,
g / p_color.g,
@@ -583,7 +562,6 @@ Color Color::operator/(const Color &p_color) const {
}
Color Color::operator/(const real_t &rvalue) const {
-
return Color(
r / rvalue,
g / rvalue,
@@ -592,7 +570,6 @@ Color Color::operator/(const real_t &rvalue) const {
}
void Color::operator/=(const Color &p_color) {
-
r = r / p_color.r;
g = g / p_color.g;
b = b / p_color.b;
@@ -600,7 +577,6 @@ void Color::operator/=(const Color &p_color) {
}
void Color::operator/=(const real_t &rvalue) {
-
if (rvalue == 0) {
r = 1.0;
g = 1.0;
@@ -612,10 +588,9 @@ void Color::operator/=(const real_t &rvalue) {
b = b / rvalue;
a = a / rvalue;
}
-};
+}
Color Color::operator-() const {
-
return Color(
1.0 - r,
1.0 - g,
diff --git a/core/color.h b/core/color.h
index 16dc721072..258965fd16 100644
--- a/core/color.h
+++ b/core/color.h
@@ -35,16 +35,14 @@
#include "core/ustring.h"
struct Color {
-
union {
-
struct {
float r;
float g;
float b;
float a;
};
- float components[4];
+ float components[4] = { 0, 0, 0, 1.0 };
};
bool operator==(const Color &p_color) const { return (r == p_color.r && g == p_color.g && b == p_color.b && a == p_color.a); }
@@ -97,8 +95,7 @@ struct Color {
Color inverted() const;
Color contrasted() const;
- _FORCE_INLINE_ Color linear_interpolate(const Color &p_b, float p_t) const {
-
+ _FORCE_INLINE_ Color lerp(const Color &p_b, float p_t) const {
Color res = *this;
res.r += (p_t * (p_b.r - r));
@@ -110,7 +107,6 @@ struct Color {
}
_FORCE_INLINE_ Color darkened(float p_amount) const {
-
Color res = *this;
res.r = res.r * (1.0f - p_amount);
res.g = res.g * (1.0f - p_amount);
@@ -119,7 +115,6 @@ struct Color {
}
_FORCE_INLINE_ Color lightened(float p_amount) const {
-
Color res = *this;
res.r = res.r + (1.0f - res.r) * p_amount;
res.g = res.g + (1.0f - res.g) * p_amount;
@@ -128,7 +123,6 @@ struct Color {
}
_FORCE_INLINE_ uint32_t to_rgbe9995() const {
-
const float pow2to9 = 512.0f;
const float B = 15.0f;
//const float Emax = 31.0f;
@@ -162,7 +156,6 @@ struct Color {
}
_FORCE_INLINE_ Color blend(const Color &p_over) const {
-
Color res;
float sa = 1.0 - p_over.a;
res.a = a * sa + p_over.a;
@@ -177,7 +170,6 @@ struct Color {
}
_FORCE_INLINE_ Color to_linear() const {
-
return Color(
r < 0.04045 ? r * (1.0 / 12.92) : Math::pow((r + 0.055) * (1.0 / (1 + 0.055)), 2.4),
g < 0.04045 ? g * (1.0 / 12.92) : Math::pow((g + 0.055) * (1.0 / (1 + 0.055)), 2.4),
@@ -185,7 +177,6 @@ struct Color {
a);
}
_FORCE_INLINE_ Color to_srgb() const {
-
return Color(
r < 0.0031308 ? 12.92 * r : (1.0 + 0.055) * Math::pow(r, 1.0f / 2.4f) - 0.055,
g < 0.0031308 ? 12.92 * g : (1.0 + 0.055) * Math::pow(g, 1.0f / 2.4f) - 0.055,
@@ -204,15 +195,7 @@ struct Color {
_FORCE_INLINE_ bool operator<(const Color &p_color) const; //used in set keys
operator String() const;
- /**
- * No construct parameters, r=0, g=0, b=0. a=255
- */
- _FORCE_INLINE_ Color() {
- r = 0;
- g = 0;
- b = 0;
- a = 1.0;
- }
+ _FORCE_INLINE_ Color() {}
/**
* RGB / RGBA construct parameters. Alpha is optional, but defaults to 1.0
@@ -223,20 +206,32 @@ struct Color {
b = p_b;
a = p_a;
}
+
+ /**
+ * 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;
+ }
};
bool Color::operator<(const Color &p_color) const {
-
if (r == p_color.r) {
if (g == p_color.g) {
if (b == p_color.b) {
return (a < p_color.a);
- } else
+ } else {
return (b < p_color.b);
- } else
+ }
+ } else {
return g < p_color.g;
- } else
+ }
+ } else {
return r < p_color.r;
+ }
}
#endif // COLOR_H
diff --git a/core/color_names.inc b/core/color_names.inc
index 428a8473fe..2b50d88b02 100644
--- a/core/color_names.inc
+++ b/core/color_names.inc
@@ -3,7 +3,9 @@
static Map<String, Color> _named_colors;
static void _populate_named_colors() {
- if (!_named_colors.empty()) return;
+ if (!_named_colors.empty()) {
+ return;
+ }
_named_colors.insert("aliceblue", Color(0.94, 0.97, 1.00));
_named_colors.insert("antiquewhite", Color(0.98, 0.92, 0.84));
_named_colors.insert("aqua", Color(0.00, 1.00, 1.00));
diff --git a/core/command_queue_mt.cpp b/core/command_queue_mt.cpp
index 3ce769c72c..ace210ca2c 100644
--- a/core/command_queue_mt.cpp
+++ b/core/command_queue_mt.cpp
@@ -33,30 +33,24 @@
#include "core/os/os.h"
void CommandQueueMT::lock() {
-
mutex.lock();
}
void CommandQueueMT::unlock() {
-
mutex.unlock();
}
void CommandQueueMT::wait_for_flush() {
-
// wait one millisecond for a flush to happen
OS::get_singleton()->delay_usec(1000);
}
CommandQueueMT::SyncSemaphore *CommandQueueMT::_alloc_sync_sem() {
-
int idx = -1;
while (true) {
-
lock();
for (int i = 0; i < SYNC_SEMAPHORES; i++) {
-
if (!sync_sems[i].in_use) {
sync_sems[i].in_use = true;
idx = i;
@@ -100,25 +94,14 @@ tryagain:
}
CommandQueueMT::CommandQueueMT(bool p_sync) {
-
- read_ptr = 0;
- write_ptr = 0;
- dealloc_ptr = 0;
- command_mem = (uint8_t *)memalloc(COMMAND_MEM_SIZE);
-
- for (int i = 0; i < SYNC_SEMAPHORES; i++) {
-
- sync_sems[i].in_use = false;
- }
- if (p_sync)
+ if (p_sync) {
sync = memnew(Semaphore);
- else
- sync = nullptr;
+ }
}
CommandQueueMT::~CommandQueueMT() {
-
- if (sync)
+ if (sync) {
memdelete(sync);
+ }
memfree(command_mem);
}
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h
index 558453bdf5..d7a6a5bc43 100644
--- a/core/command_queue_mt.h
+++ b/core/command_queue_mt.h
@@ -253,7 +253,8 @@
cmd->method = p_method; \
SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \
unlock(); \
- if (sync) sync->post(); \
+ if (sync) \
+ sync->post(); \
}
#define CMD_RET_TYPE(N) CommandRet##N<T, M, COMMA_SEP_LIST(TYPE_ARG, N) COMMA(N) R>
@@ -269,7 +270,8 @@
cmd->ret = r_ret; \
cmd->sync_sem = ss; \
unlock(); \
- if (sync) sync->post(); \
+ if (sync) \
+ sync->post(); \
ss->sem.wait(); \
ss->in_use = false; \
}
@@ -286,7 +288,8 @@
SEMIC_SEP_LIST(CMD_ASSIGN_PARAM, N); \
cmd->sync_sem = ss; \
unlock(); \
- if (sync) sync->post(); \
+ if (sync) \
+ sync->post(); \
ss->sem.wait(); \
ss->in_use = false; \
}
@@ -294,22 +297,18 @@
#define MAX_CMD_PARAMS 15
class CommandQueueMT {
-
struct SyncSemaphore {
-
Semaphore sem;
- bool in_use;
+ bool in_use = false;
};
struct CommandBase {
-
virtual void call() = 0;
- virtual void post(){};
- virtual ~CommandBase(){};
+ virtual void post() {}
+ virtual ~CommandBase() {}
};
struct SyncCommand : public CommandBase {
-
SyncSemaphore *sync_sem;
virtual void post() {
@@ -336,17 +335,16 @@ class CommandQueueMT {
SYNC_SEMAPHORES = 8
};
- uint8_t *command_mem;
- uint32_t read_ptr;
- uint32_t write_ptr;
- uint32_t dealloc_ptr;
+ uint8_t *command_mem = (uint8_t *)memalloc(COMMAND_MEM_SIZE);
+ uint32_t read_ptr = 0;
+ uint32_t write_ptr = 0;
+ uint32_t dealloc_ptr = 0;
SyncSemaphore sync_sems[SYNC_SEMAPHORES];
Mutex mutex;
- Semaphore *sync;
+ Semaphore *sync = nullptr;
template <class T>
T *allocate() {
-
// alloc size is size+T+safeguard
uint32_t alloc_size = ((sizeof(T) + 8 - 1) & ~(8 - 1)) + 8;
@@ -355,7 +353,6 @@ class CommandQueueMT {
if (write_ptr < dealloc_ptr) {
// behind dealloc_ptr, check that there is room
if ((dealloc_ptr - write_ptr) <= alloc_size) {
-
// There is no more room, try to deallocate something
if (dealloc_one()) {
goto tryagain;
@@ -402,12 +399,10 @@ class CommandQueueMT {
template <class T>
T *allocate_and_lock() {
-
lock();
T *ret;
while ((ret = allocate<T>()) == nullptr) {
-
unlock();
// sleep a little until fetch happened and some room is made
wait_for_flush();
@@ -418,12 +413,16 @@ class CommandQueueMT {
}
bool flush_one(bool p_lock = true) {
- if (p_lock) lock();
+ if (p_lock) {
+ lock();
+ }
tryagain:
// tried to read an empty queue
if (read_ptr == write_ptr) {
- if (p_lock) unlock();
+ if (p_lock) {
+ unlock();
+ }
return false;
}
@@ -442,15 +441,21 @@ class CommandQueueMT {
read_ptr += size;
- if (p_lock) unlock();
+ if (p_lock) {
+ unlock();
+ }
cmd->call();
- if (p_lock) lock();
+ if (p_lock) {
+ lock();
+ }
cmd->post();
cmd->~CommandBase();
*(uint32_t *)&command_mem[size_ptr] &= ~1;
- if (p_lock) unlock();
+ if (p_lock) {
+ unlock();
+ }
return true;
}
@@ -480,11 +485,10 @@ public:
}
void flush_all() {
-
//ERR_FAIL_COND(sync);
lock();
- while (flush_one(false))
- ;
+ while (flush_one(false)) {
+ }
unlock();
}
diff --git a/core/compressed_translation.cpp b/core/compressed_translation.cpp
index 0225524bc8..a66997aa52 100644
--- a/core/compressed_translation.cpp
+++ b/core/compressed_translation.cpp
@@ -37,7 +37,6 @@ extern "C" {
}
struct _PHashTranslationCmp {
-
int orig_len;
CharString compressed;
int offset;
@@ -65,7 +64,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
int total_string_size = 0;
for (List<StringName>::Element *E = keys.front(); E; E = E->next()) {
-
//hash string
CharString cs = E->get().operator String().utf8();
uint32_t h = hash(0, cs.get_data());
@@ -108,21 +106,19 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
int bucket_table_size = 0;
for (int i = 0; i < size; i++) {
-
const Vector<Pair<int, CharString>> &b = buckets[i];
Map<uint32_t, int> &t = table.write[i];
- if (b.size() == 0)
+ if (b.size() == 0) {
continue;
+ }
int d = 1;
int item = 0;
while (item < b.size()) {
-
uint32_t slot = hash(d, b[item].second.get_data());
if (t.has(slot)) {
-
item = 0;
d++;
t.clear();
@@ -151,7 +147,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
int collisions = 0;
for (int i = 0; i < size; i++) {
-
const Map<uint32_t, int> &t = table[i];
if (t.size() == 0) {
htw[i] = 0xFFFFFFFF; //nothing
@@ -165,7 +160,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
btw[btindex++] = hfunc_table[i];
for (Map<uint32_t, int>::Element *E = t.front(); E; E = E->next()) {
-
btw[btindex++] = E->key();
btw[btindex++] = compressed[E->get()].offset;
btw[btindex++] = compressed[E->get()].compressed.size();
@@ -187,7 +181,6 @@ void PHashTranslation::generate(const Ref<Translation> &p_from) {
}
bool PHashTranslation::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name.operator String();
if (name == "hash_table") {
hash_table = p_value;
@@ -197,33 +190,34 @@ bool PHashTranslation::_set(const StringName &p_name, const Variant &p_value) {
strings = p_value;
} else if (name == "load_from") {
generate(p_value);
- } else
+ } else {
return false;
+ }
return true;
}
bool PHashTranslation::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name.operator String();
- if (name == "hash_table")
+ if (name == "hash_table") {
r_ret = hash_table;
- else if (name == "bucket_table")
+ } else if (name == "bucket_table") {
r_ret = bucket_table;
- else if (name == "strings")
+ } else if (name == "strings") {
r_ret = strings;
- else
+ } else {
return false;
+ }
return true;
}
StringName PHashTranslation::get_message(const StringName &p_src_text) const {
-
int htsize = hash_table.size();
- if (htsize == 0)
+ if (htsize == 0) {
return StringName();
+ }
CharString str = p_src_text.operator String().utf8();
uint32_t h = hash(0, str.get_data());
@@ -248,9 +242,7 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
int idx = -1;
for (int i = 0; i < bucket.size; i++) {
-
if (bucket.elem[i].key == h) {
-
idx = i;
break;
}
@@ -261,13 +253,11 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
}
if (bucket.elem[idx].comp_size == bucket.elem[idx].uncomp_size) {
-
String rstr;
rstr.parse_utf8(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].uncomp_size);
return rstr;
} else {
-
CharString uncomp;
uncomp.resize(bucket.elem[idx].uncomp_size + 1);
smaz_decompress(&sptr[bucket.elem[idx].str_offset], bucket.elem[idx].comp_size, uncomp.ptrw(), bucket.elem[idx].uncomp_size);
@@ -278,16 +268,12 @@ StringName PHashTranslation::get_message(const StringName &p_src_text) const {
}
void PHashTranslation::_get_property_list(List<PropertyInfo> *p_list) const {
-
p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "hash_table"));
p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "bucket_table"));
p_list->push_back(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "strings"));
p_list->push_back(PropertyInfo(Variant::OBJECT, "load_from", PROPERTY_HINT_RESOURCE_TYPE, "Translation", PROPERTY_USAGE_EDITOR));
}
-void PHashTranslation::_bind_methods() {
+void PHashTranslation::_bind_methods() {
ClassDB::bind_method(D_METHOD("generate", "from"), &PHashTranslation::generate);
}
-
-PHashTranslation::PHashTranslation() {
-}
diff --git a/core/compressed_translation.h b/core/compressed_translation.h
index d599240dfe..3c029bdf58 100644
--- a/core/compressed_translation.h
+++ b/core/compressed_translation.h
@@ -34,7 +34,6 @@
#include "core/translation.h"
class PHashTranslation : public Translation {
-
GDCLASS(PHashTranslation, Translation);
//this translation uses a sort of modified perfect hash algorithm
@@ -48,12 +47,10 @@ class PHashTranslation : public Translation {
Vector<uint8_t> strings;
struct Bucket {
-
int size;
uint32_t func;
struct Elem {
-
uint32_t key;
uint32_t str_offset;
uint32_t comp_size;
@@ -64,11 +61,10 @@ class PHashTranslation : public Translation {
};
_FORCE_INLINE_ uint32_t hash(uint32_t d, const char *p_str) const {
-
- if (d == 0)
+ if (d == 0) {
d = 0x1000193;
+ }
while (*p_str) {
-
d = (d * 0x1000193) ^ uint32_t(*p_str);
p_str++;
}
@@ -86,7 +82,7 @@ public:
virtual StringName get_message(const StringName &p_src_text) const; //overridable for other implementations
void generate(const Ref<Translation> &p_from);
- PHashTranslation();
+ PHashTranslation() {}
};
#endif // COMPRESSED_TRANSLATION_H
diff --git a/core/container_type_validate.h b/core/container_type_validate.h
new file mode 100644
index 0000000000..f2724e884d
--- /dev/null
+++ b/core/container_type_validate.h
@@ -0,0 +1,126 @@
+/*************************************************************************/
+/* container_type_validate.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef CONTAINER_TYPE_VALIDATE_H
+#define CONTAINER_TYPE_VALIDATE_H
+
+#include "core/script_language.h"
+#include "core/variant.h"
+
+struct ContainerTypeValidate {
+ Variant::Type type = Variant::NIL;
+ StringName class_name;
+ Ref<Script> script;
+ const char *where = "conatiner";
+
+ _FORCE_INLINE_ bool can_reference(const ContainerTypeValidate &p_type) const {
+ if (type == p_type.type) {
+ if (type != Variant::OBJECT) {
+ return true; //nothing else to check
+ }
+ } else {
+ return false;
+ }
+
+ //both are object
+
+ if ((class_name != StringName()) != (p_type.class_name != StringName())) {
+ return false; //both need to have class or none
+ }
+
+ if (class_name != p_type.class_name) {
+ if (!ClassDB::is_parent_class(p_type.class_name, class_name)) {
+ return false;
+ }
+ }
+
+ if (script.is_null() != p_type.script.is_null()) {
+ return false;
+ }
+
+ if (script != p_type.script) {
+ if (!p_type.script->inherits_script(script)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ _FORCE_INLINE_ bool validate(const Variant &p_variant, const char *p_operation = "use") {
+ if (type == Variant::NIL) {
+ return true;
+ }
+
+ ERR_FAIL_COND_V_MSG(type != p_variant.get_type(), false, "Attempted to " + String(p_operation) + " a variable of type '" + Variant::get_type_name(p_variant.get_type()) + "' into a " + where + " of type '" + Variant::get_type_name(type) + "'.");
+ if (type != p_variant.get_type()) {
+ return false;
+ }
+
+ if (type != Variant::OBJECT) {
+ return true;
+ }
+#ifdef DEBUG_ENABLED
+ ObjectID object_id = p_variant;
+ if (object_id == ObjectID()) {
+ return true; //fine its null;
+ }
+ Object *object = ObjectDB::get_instance(object_id);
+ ERR_FAIL_COND_V_MSG(object == nullptr, false, "Attempted to " + String(p_operation) + " an invalid (previously freed?) object instance into a '" + String(where) + ".");
+#else
+ Object *object = p_variant;
+ if (object == nullptr) {
+ return true; //fine
+ }
+#endif
+ if (class_name == StringName()) {
+ return true; //all good, no class type requested
+ }
+
+ StringName obj_class = object->get_class_name();
+ if (obj_class != class_name) {
+ ERR_FAIL_COND_V_MSG(!ClassDB::is_parent_class(object->get_class_name(), class_name), false, "Attempted to " + String(p_operation) + " an object of type '" + object->get_class() + "' into a " + where + ", which does not inherit from '" + String(class_name) + "'.");
+ }
+
+ if (script.is_null()) {
+ return true; //all good
+ }
+
+ Ref<Script> other_script = object->get_script();
+
+ //check base script..
+ ERR_FAIL_COND_V_MSG(other_script.is_null(), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'.");
+ ERR_FAIL_COND_V_MSG(!other_script->inherits_script(script), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'.");
+
+ return true;
+ }
+};
+
+#endif // CONTAINER_TYPE_VALIDATE_H
diff --git a/core/core_string_names.h b/core/core_string_names.h
index 2ade44f4e0..1a18c84572 100644
--- a/core/core_string_names.h
+++ b/core/core_string_names.h
@@ -34,7 +34,6 @@
#include "core/string_name.h"
class CoreStringNames {
-
friend void register_core_types();
friend void unregister_core_types();
diff --git a/core/cowdata.h b/core/cowdata.h
index 975a572906..82daefb5bd 100644
--- a/core/cowdata.h
+++ b/core/cowdata.h
@@ -54,30 +54,30 @@ class CowData {
friend class VMap;
private:
- mutable T *_ptr;
+ mutable T *_ptr = nullptr;
// internal helpers
_FORCE_INLINE_ uint32_t *_get_refcount() const {
-
- if (!_ptr)
+ if (!_ptr) {
return nullptr;
+ }
return reinterpret_cast<uint32_t *>(_ptr) - 2;
}
_FORCE_INLINE_ uint32_t *_get_size() const {
-
- if (!_ptr)
+ if (!_ptr) {
return nullptr;
+ }
return reinterpret_cast<uint32_t *>(_ptr) - 1;
}
_FORCE_INLINE_ T *_get_data() const {
-
- if (!_ptr)
+ if (!_ptr) {
return nullptr;
+ }
return reinterpret_cast<T *>(_ptr);
}
@@ -125,31 +125,29 @@ public:
_FORCE_INLINE_ int size() const {
uint32_t *size = (uint32_t *)_get_size();
- if (size)
+ if (size) {
return *size;
- else
+ } else {
return 0;
+ }
}
_FORCE_INLINE_ void clear() { resize(0); }
- _FORCE_INLINE_ bool empty() const { return _ptr == 0; }
+ _FORCE_INLINE_ bool empty() const { return _ptr == nullptr; }
_FORCE_INLINE_ void set(int p_index, const T &p_elem) {
-
CRASH_BAD_INDEX(p_index, size());
_copy_on_write();
_get_data()[p_index] = p_elem;
}
_FORCE_INLINE_ T &get_m(int p_index) {
-
CRASH_BAD_INDEX(p_index, size());
_copy_on_write();
return _get_data()[p_index];
}
_FORCE_INLINE_ const T &get(int p_index) const {
-
CRASH_BAD_INDEX(p_index, size());
return _get_data()[p_index];
@@ -158,46 +156,45 @@ public:
Error resize(int p_size);
_FORCE_INLINE_ void remove(int p_index) {
-
ERR_FAIL_INDEX(p_index, size());
T *p = ptrw();
int len = size();
for (int i = p_index; i < len - 1; i++) {
-
p[i] = p[i + 1];
- };
+ }
resize(len - 1);
- };
+ }
Error insert(int p_pos, const T &p_val) {
-
ERR_FAIL_INDEX_V(p_pos, size() + 1, ERR_INVALID_PARAMETER);
resize(size() + 1);
- for (int i = (size() - 1); i > p_pos; i--)
+ for (int i = (size() - 1); i > p_pos; i--) {
set(i, get(i - 1));
+ }
set(p_pos, p_val);
return OK;
- };
+ }
int find(const T &p_val, int p_from = 0) const;
- _FORCE_INLINE_ CowData();
+ _FORCE_INLINE_ CowData() {}
_FORCE_INLINE_ ~CowData();
_FORCE_INLINE_ CowData(CowData<T> &p_from) { _ref(p_from); };
};
template <class T>
void CowData<T>::_unref(void *p_data) {
-
- if (!p_data)
+ if (!p_data) {
return;
+ }
uint32_t *refc = _get_refcount();
- if (atomic_decrement(refc) > 0)
+ if (atomic_decrement(refc) > 0) {
return; // still in use
+ }
// clean up
if (!__has_trivial_destructor(T)) {
@@ -216,9 +213,9 @@ void CowData<T>::_unref(void *p_data) {
template <class T>
void CowData<T>::_copy_on_write() {
-
- if (!_ptr)
+ if (!_ptr) {
return;
+ }
uint32_t *refc = _get_refcount();
@@ -250,13 +247,13 @@ void CowData<T>::_copy_on_write() {
template <class T>
Error CowData<T>::resize(int p_size) {
-
ERR_FAIL_COND_V(p_size < 0, ERR_INVALID_PARAMETER);
int current_size = size();
- if (p_size == current_size)
+ if (p_size == current_size) {
return OK;
+ }
if (p_size == 0) {
// wants to clean up
@@ -273,7 +270,6 @@ Error CowData<T>::resize(int p_size) {
ERR_FAIL_COND_V(!_get_alloc_size_checked(p_size, &alloc_size), ERR_OUT_OF_MEMORY);
if (p_size > current_size) {
-
if (alloc_size != current_alloc_size) {
if (current_size == 0) {
// alloc from scratch
@@ -304,7 +300,6 @@ Error CowData<T>::resize(int p_size) {
*_get_size() = p_size;
} else if (p_size < current_size) {
-
if (!__has_trivial_destructor(T)) {
// deinitialize no longer needed elements
for (uint32_t i = p_size; i < *_get_size(); i++) {
@@ -351,15 +346,16 @@ void CowData<T>::_ref(const CowData *p_from) {
template <class T>
void CowData<T>::_ref(const CowData &p_from) {
-
- if (_ptr == p_from._ptr)
+ if (_ptr == p_from._ptr) {
return; // self assign, do nothing.
+ }
_unref(_ptr);
_ptr = nullptr;
- if (!p_from._ptr)
+ if (!p_from._ptr) {
return; //nothing to do
+ }
if (atomic_conditional_increment(p_from._get_refcount()) > 0) { // could reference
_ptr = p_from._ptr;
@@ -367,14 +363,7 @@ void CowData<T>::_ref(const CowData &p_from) {
}
template <class T>
-CowData<T>::CowData() {
-
- _ptr = nullptr;
-}
-
-template <class T>
CowData<T>::~CowData() {
-
_unref(_ptr);
}
diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp
index ab8548e3ba..eb942c60c9 100644
--- a/core/crypto/crypto.cpp
+++ b/core/crypto/crypto.cpp
@@ -38,8 +38,9 @@
CryptoKey *(*CryptoKey::_create)() = nullptr;
CryptoKey *CryptoKey::create() {
- if (_create)
+ if (_create) {
return _create();
+ }
return nullptr;
}
@@ -50,8 +51,9 @@ void CryptoKey::_bind_methods() {
X509Certificate *(*X509Certificate::_create)() = nullptr;
X509Certificate *X509Certificate::create() {
- if (_create)
+ if (_create) {
return _create();
+ }
return nullptr;
}
@@ -65,15 +67,16 @@ void X509Certificate::_bind_methods() {
void (*Crypto::_load_default_certificates)(String p_path) = nullptr;
Crypto *(*Crypto::_create)() = nullptr;
Crypto *Crypto::create() {
- if (_create)
+ if (_create) {
return _create();
+ }
return memnew(Crypto);
}
void Crypto::load_default_certificates(String p_path) {
-
- if (_load_default_certificates)
+ if (_load_default_certificates) {
_load_default_certificates(p_path);
+ }
}
void Crypto::_bind_methods() {
@@ -94,51 +97,46 @@ Ref<X509Certificate> Crypto::generate_self_signed_certificate(Ref<CryptoKey> p_k
ERR_FAIL_V_MSG(nullptr, "generate_self_signed_certificate is not available when mbedtls module is disabled.");
}
-Crypto::Crypto() {
-}
-
/// Resource loader/saver
-RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
+RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
String el = p_path.get_extension().to_lower();
if (el == "crt") {
X509Certificate *cert = X509Certificate::create();
- if (cert)
+ if (cert) {
cert->load(p_path);
+ }
return cert;
} else if (el == "key") {
CryptoKey *key = CryptoKey::create();
- if (key)
+ if (key) {
key->load(p_path);
+ }
return key;
}
return nullptr;
}
void ResourceFormatLoaderCrypto::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("crt");
p_extensions->push_back("key");
}
bool ResourceFormatLoaderCrypto::handles_type(const String &p_type) const {
-
return p_type == "X509Certificate" || p_type == "CryptoKey";
}
String ResourceFormatLoaderCrypto::get_resource_type(const String &p_path) const {
-
String el = p_path.get_extension().to_lower();
- if (el == "crt")
+ if (el == "crt") {
return "X509Certificate";
- else if (el == "key")
+ } else if (el == "key") {
return "CryptoKey";
+ }
return "";
}
Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
Error err;
Ref<X509Certificate> cert = p_resource;
Ref<CryptoKey> key = p_resource;
@@ -154,7 +152,6 @@ Error ResourceFormatSaverCrypto::save(const String &p_path, const RES &p_resourc
}
void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
-
const X509Certificate *cert = Object::cast_to<X509Certificate>(*p_resource);
const CryptoKey *key = Object::cast_to<CryptoKey>(*p_resource);
if (cert) {
@@ -164,7 +161,7 @@ void ResourceFormatSaverCrypto::get_recognized_extensions(const RES &p_resource,
p_extensions->push_back("key");
}
}
-bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const {
+bool ResourceFormatSaverCrypto::recognize(const RES &p_resource) const {
return Object::cast_to<X509Certificate>(*p_resource) || Object::cast_to<CryptoKey>(*p_resource);
}
diff --git a/core/crypto/crypto.h b/core/crypto/crypto.h
index e515367de5..cf21648a4a 100644
--- a/core/crypto/crypto.h
+++ b/core/crypto/crypto.h
@@ -31,11 +31,10 @@
#ifndef CRYPTO_H
#define CRYPTO_H
-#include "core/reference.h"
-#include "core/resource.h"
-
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
+#include "core/reference.h"
+#include "core/resource.h"
class CryptoKey : public Resource {
GDCLASS(CryptoKey, Resource);
@@ -80,22 +79,18 @@ public:
virtual Ref<CryptoKey> generate_rsa(int p_bytes);
virtual Ref<X509Certificate> generate_self_signed_certificate(Ref<CryptoKey> p_key, String p_issuer_name, String p_not_before, String p_not_after);
- Crypto();
+ Crypto() {}
};
class ResourceFormatLoaderCrypto : public ResourceFormatLoader {
- GDCLASS(ResourceFormatLoaderCrypto, ResourceFormatLoader);
-
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
class ResourceFormatSaverCrypto : public ResourceFormatSaver {
- GDCLASS(ResourceFormatSaverCrypto, ResourceFormatSaver);
-
public:
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
diff --git a/core/crypto/crypto_core.h b/core/crypto/crypto_core.h
index b3be58e8ee..36d8ace723 100644
--- a/core/crypto/crypto_core.h
+++ b/core/crypto/crypto_core.h
@@ -34,10 +34,8 @@
#include "core/reference.h"
class CryptoCore {
-
public:
class MD5Context {
-
private:
void *ctx; // To include, or not to include...
@@ -51,7 +49,6 @@ public:
};
class SHA1Context {
-
private:
void *ctx; // To include, or not to include...
@@ -65,7 +62,6 @@ public:
};
class SHA256Context {
-
private:
void *ctx; // To include, or not to include...
@@ -79,7 +75,6 @@ public:
};
class AESContext {
-
private:
void *ctx; // To include, or not to include...
diff --git a/core/crypto/hashing_context.cpp b/core/crypto/hashing_context.cpp
index af43bc9bad..fb0dadfbab 100644
--- a/core/crypto/hashing_context.cpp
+++ b/core/crypto/hashing_context.cpp
@@ -104,7 +104,6 @@ void HashingContext::_create_ctx(HashType p_type) {
}
void HashingContext::_delete_ctx() {
-
switch (type) {
case HASH_MD5:
memdelete((CryptoCore::MD5Context *)ctx);
@@ -128,11 +127,8 @@ void HashingContext::_bind_methods() {
BIND_ENUM_CONSTANT(HASH_SHA256);
}
-HashingContext::HashingContext() {
- ctx = nullptr;
-}
-
HashingContext::~HashingContext() {
- if (ctx != nullptr)
+ if (ctx != nullptr) {
_delete_ctx();
+ }
}
diff --git a/core/crypto/hashing_context.h b/core/crypto/hashing_context.h
index 230ba7ee85..f9454fa891 100644
--- a/core/crypto/hashing_context.h
+++ b/core/crypto/hashing_context.h
@@ -44,7 +44,7 @@ public:
};
private:
- void *ctx;
+ void *ctx = nullptr;
HashType type;
protected:
@@ -57,7 +57,7 @@ public:
Error update(PackedByteArray p_chunk);
PackedByteArray finish();
- HashingContext();
+ HashingContext() {}
~HashingContext();
};
diff --git a/core/debugger/debugger_marshalls.cpp b/core/debugger/debugger_marshalls.cpp
index 410c55129d..3f949b0ae1 100644
--- a/core/debugger/debugger_marshalls.cpp
+++ b/core/debugger/debugger_marshalls.cpp
@@ -228,8 +228,9 @@ Array DebuggerMarshalls::ScriptStackVariable::serialize(int max_size) {
int len = 0;
Error err = encode_variant(var, nullptr, len, true);
- if (err != OK)
+ if (err != OK) {
ERR_PRINT("Failed to encode variant.");
+ }
if (len > max_size) {
arr.push_back(Variant());
diff --git a/core/debugger/debugger_marshalls.h b/core/debugger/debugger_marshalls.h
index 04229c0afc..7b7f4ac4b5 100644
--- a/core/debugger/debugger_marshalls.h
+++ b/core/debugger/debugger_marshalls.h
@@ -35,18 +35,14 @@
#include "servers/rendering_server.h"
struct DebuggerMarshalls {
-
// Memory usage
struct ResourceInfo {
String path;
String format;
String type;
RID id;
- int vram;
+ int vram = 0;
bool operator<(const ResourceInfo &p_img) const { return vram == p_img.vram ? id < p_img.id : vram > p_img.vram; }
- ResourceInfo() {
- vram = 0;
- }
};
struct ResourceUsage {
@@ -119,10 +115,7 @@ struct DebuggerMarshalls {
struct ScriptStackVariable {
String name;
Variant value;
- int type;
- ScriptStackVariable() {
- type = -1;
- }
+ int type = -1;
Array serialize(int max_size = 1 << 20); // 1 MiB default.
bool deserialize(const Array &p_arr);
@@ -137,27 +130,18 @@ struct DebuggerMarshalls {
};
struct OutputError {
- int hr;
- int min;
- int sec;
- int msec;
+ int hr = -1;
+ int min = -1;
+ int sec = -1;
+ int msec = -1;
String source_file;
String source_func;
- int source_line;
+ int source_line = -1;
String error;
String error_descr;
- bool warning;
+ bool warning = false;
Vector<ScriptLanguage::StackInfo> callstack;
- OutputError() {
- hr = -1;
- min = -1;
- sec = -1;
- msec = -1;
- source_line = -1;
- warning = false;
- }
-
Array serialize();
bool deserialize(const Array &p_arr);
};
diff --git a/core/debugger/engine_debugger.cpp b/core/debugger/engine_debugger.cpp
index bfe38d0f4a..5c9fb67de4 100644
--- a/core/debugger/engine_debugger.cpp
+++ b/core/debugger/engine_debugger.cpp
@@ -32,6 +32,7 @@
#include "core/debugger/local_debugger.h"
#include "core/debugger/remote_debugger.h"
+#include "core/debugger/remote_debugger_peer.h"
#include "core/debugger/script_debugger.h"
#include "core/os/os.h"
@@ -40,6 +41,7 @@ ScriptDebugger *EngineDebugger::script_debugger = nullptr;
Map<StringName, EngineDebugger::Profiler> EngineDebugger::profilers;
Map<StringName, EngineDebugger::Capture> EngineDebugger::captures;
+Map<String, EngineDebugger::CreatePeerFunc> EngineDebugger::protocols;
void EngineDebugger::register_profiler(const StringName &p_name, const Profiler &p_func) {
ERR_FAIL_COND_MSG(profilers.has(p_name), "Profiler already registered: " + p_name);
@@ -66,6 +68,11 @@ void EngineDebugger::unregister_message_capture(const StringName &p_name) {
captures.erase(p_name);
}
+void EngineDebugger::register_uri_handler(const String &p_protocol, CreatePeerFunc p_func) {
+ ERR_FAIL_COND_MSG(protocols.has(p_protocol), "Protocol handler already registered: " + p_protocol);
+ protocols.insert(p_protocol, p_func);
+}
+
void EngineDebugger::profiler_enable(const StringName &p_name, bool p_enabled, const Array &p_opts) {
ERR_FAIL_COND_MSG(!profilers.has(p_name), "Can't change profiler state, no profiler: " + p_name);
Profiler &p = profilers[p_name];
@@ -104,8 +111,9 @@ Error EngineDebugger::capture_parse(const StringName &p_name, const String &p_ms
void EngineDebugger::line_poll() {
// The purpose of this is just processing events every now and then when the script might get too busy otherwise bugs like infinite loops can't be caught
- if (poll_every % 2048 == 0)
+ if (poll_every % 2048 == 0) {
poll_events(false);
+ }
poll_every++;
}
@@ -117,40 +125,49 @@ void EngineDebugger::iteration(uint64_t p_frame_ticks, uint64_t p_idle_ticks, ui
// Notify tick to running profilers
for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) {
Profiler &p = E->get();
- if (!p.active || !p.tick)
+ if (!p.active || !p.tick) {
continue;
+ }
p.tick(p.data, frame_time, idle_time, physics_time, physics_frame_time);
}
singleton->poll_events(true);
}
void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Vector<String> p_breakpoints) {
- if (p_uri.empty())
+ register_uri_handler("tcp://", RemoteDebuggerPeerTCP::create); // TCP is the default protocol. Platforms/modules can add more.
+ if (p_uri.empty()) {
return;
+ }
if (p_uri == "local://") {
singleton = memnew(LocalDebugger);
script_debugger = memnew(ScriptDebugger);
// Tell the OS that we want to handle termination signals.
OS::get_singleton()->initialize_debugging();
- } else {
- singleton = RemoteDebugger::create_for_uri(p_uri);
- if (!singleton)
+ } else if (p_uri.find("://") >= 0) {
+ const String proto = p_uri.substr(0, p_uri.find("://") + 3);
+ if (!protocols.has(proto)) {
return;
+ }
+ RemoteDebuggerPeer *peer = protocols[proto](p_uri);
+ if (!peer) {
+ return;
+ }
+ singleton = memnew(RemoteDebugger(Ref<RemoteDebuggerPeer>(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());
singleton->send_message("set_pid", msg);
}
- if (!singleton)
+ if (!singleton) {
return;
+ }
// There is a debugger, parse breakpoints.
ScriptDebugger *singleton_script_debugger = singleton->get_script_debugger();
singleton_script_debugger->set_skip_breakpoints(p_skip_breakpoints);
for (int i = 0; i < p_breakpoints.size(); i++) {
-
String bp = p_breakpoints[i];
int sp = bp.find_last(":");
ERR_CONTINUE_MSG(sp == -1, "Invalid breakpoint: '" + bp + "', expected file:line format.");
@@ -160,27 +177,31 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve
}
void EngineDebugger::deinitialize() {
- if (!singleton)
- return;
-
- // Stop all profilers
- for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) {
- if (E->get().active)
- singleton->profiler_enable(E->key(), false);
+ if (singleton) {
+ // Stop all profilers
+ for (Map<StringName, Profiler>::Element *E = profilers.front(); E; E = E->next()) {
+ if (E->get().active) {
+ singleton->profiler_enable(E->key(), false);
+ }
+ }
+
+ // Flush any remaining message
+ singleton->poll_events(false);
+
+ memdelete(singleton);
+ singleton = nullptr;
}
- // Flush any remaining message
- singleton->poll_events(false);
-
- memdelete(singleton);
- singleton = nullptr;
+ // Clear profilers/captuers/protocol handlers.
profilers.clear();
captures.clear();
+ protocols.clear();
}
EngineDebugger::~EngineDebugger() {
- if (script_debugger)
+ if (script_debugger) {
memdelete(script_debugger);
+ }
script_debugger = nullptr;
singleton = nullptr;
}
diff --git a/core/debugger/engine_debugger.h b/core/debugger/engine_debugger.h
index 7b6b77ca9b..8d5ebb2394 100644
--- a/core/debugger/engine_debugger.h
+++ b/core/debugger/engine_debugger.h
@@ -38,6 +38,7 @@
#include "core/variant.h"
#include "core/vector.h"
+class RemoteDebuggerPeer;
class ScriptDebugger;
class EngineDebugger {
@@ -45,8 +46,11 @@ public:
typedef void (*ProfilingToggle)(void *p_user, bool p_enable, const Array &p_opts);
typedef void (*ProfilingTick)(void *p_user, float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time);
typedef void (*ProfilingAdd)(void *p_user, const Array &p_arr);
+
typedef Error (*CaptureFunc)(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured);
+ typedef RemoteDebuggerPeer *(*CreatePeerFunc)(const String &p_uri);
+
class Profiler {
friend class EngineDebugger;
@@ -94,6 +98,7 @@ protected:
static Map<StringName, Profiler> profilers;
static Map<StringName, Capture> captures;
+ static Map<String, CreatePeerFunc> protocols;
public:
_FORCE_INLINE_ static EngineDebugger *get_singleton() { return singleton; }
@@ -113,6 +118,8 @@ public:
static void unregister_message_capture(const StringName &p_name);
static bool has_capture(const StringName &p_name);
+ static void register_uri_handler(const String &p_protocol, CreatePeerFunc p_func);
+
void iteration(uint64_t p_frame_ticks, uint64_t p_idle_ticks, uint64_t p_physics_ticks, float p_physics_frame_time);
void profiler_enable(const StringName &p_name, bool p_enabled, const Array &p_opts = Array());
Error capture_parse(const StringName &p_name, const String &p_msg, const Array &p_args, bool &r_captured);
diff --git a/core/debugger/local_debugger.cpp b/core/debugger/local_debugger.cpp
index 6d88ceb2c1..876be79418 100644
--- a/core/debugger/local_debugger.cpp
+++ b/core/debugger/local_debugger.cpp
@@ -36,7 +36,6 @@
struct LocalDebugger::ScriptsProfiler {
struct ProfileInfoSort {
-
bool operator()(const ScriptLanguage::ProfilingInfo &A, const ScriptLanguage::ProfilingInfo &B) const {
return A.total_time > B.total_time;
}
@@ -70,17 +69,19 @@ struct LocalDebugger::ScriptsProfiler {
void _print_frame_data(bool p_accumulated) {
uint64_t diff = OS::get_singleton()->get_ticks_usec() - idle_accum;
- if (!p_accumulated && diff < 1000000) //show every one second
+ if (!p_accumulated && diff < 1000000) { //show every one second
return;
+ }
idle_accum = OS::get_singleton()->get_ticks_usec();
int ofs = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
- if (p_accumulated)
+ if (p_accumulated) {
ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&pinfo.write[ofs], pinfo.size() - ofs);
- else
+ } else {
ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&pinfo.write[ofs], pinfo.size() - ofs);
+ }
}
SortArray<ScriptLanguage::ProfilingInfo, ProfileInfoSort> sort;
@@ -89,7 +90,6 @@ struct LocalDebugger::ScriptsProfiler {
// compute total script frame time
uint64_t script_time_us = 0;
for (int i = 0; i < ofs; i++) {
-
script_time_us += pinfo[i].self_time;
}
float script_time = USEC_TO_SEC(script_time_us);
@@ -102,7 +102,6 @@ struct LocalDebugger::ScriptsProfiler {
}
for (int i = 0; i < ofs; i++) {
-
print_line(itos(i) + ":" + pinfo[i].signature);
float tt = USEC_TO_SEC(pinfo[i].total_time);
float st = USEC_TO_SEC(pinfo[i].self_time);
@@ -116,7 +115,6 @@ struct LocalDebugger::ScriptsProfiler {
};
void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
-
ScriptLanguage *script_lang = script_debugger->get_break_language();
if (!target_function.empty()) {
@@ -135,7 +133,6 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
int current_frame = 0;
int total_frames = script_lang->debug_get_stack_level_count();
while (true) {
-
OS::get_singleton()->print("debug> ");
String line = OS::get_singleton()->get_stdin_string().strip_edges();
@@ -146,18 +143,15 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
print_line("\nDebugger Break, Reason: '" + script_lang->debug_get_error() + "'");
print_line("*Frame " + itos(current_frame) + " - " + script_lang->debug_get_stack_level_source(current_frame) + ":" + itos(script_lang->debug_get_stack_level_line(current_frame)) + " in function '" + script_lang->debug_get_stack_level_function(current_frame) + "'");
print_line("Enter \"help\" for assistance.");
- } else if (line == "c" || line == "continue")
+ } else if (line == "c" || line == "continue") {
break;
- else if (line == "bt" || line == "breakpoint") {
-
+ } else if (line == "bt" || line == "breakpoint") {
for (int i = 0; i < total_frames; i++) {
-
String cfi = (current_frame == i) ? "*" : " "; //current frame indicator
print_line(cfi + "Frame " + itos(i) + " - " + script_lang->debug_get_stack_level_source(i) + ":" + itos(script_lang->debug_get_stack_level_line(i)) + " in function '" + script_lang->debug_get_stack_level_function(i) + "'");
}
} else if (line.begins_with("fr") || line.begins_with("frame")) {
-
if (line.get_slice_count(" ") == 1) {
print_line("*Frame " + itos(current_frame) + " - " + script_lang->debug_get_stack_level_source(current_frame) + ":" + itos(script_lang->debug_get_stack_level_line(current_frame)) + " in function '" + script_lang->debug_get_stack_level_function(current_frame) + "'");
} else {
@@ -171,9 +165,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
}
} else if (line.begins_with("set")) {
-
if (line.get_slice_count(" ") == 1) {
-
for (Map<String, String>::Element *E = options.front(); E; E = E->next()) {
print_line("\t" + E->key() + "=" + E->value());
}
@@ -185,13 +177,11 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
if (value_pos < 0) {
print_line("Error: Invalid set format. Use: set key=value");
} else {
-
String key = key_value.left(value_pos);
if (!options.has(key)) {
print_line("Error: Unknown option " + key);
} else {
-
// Allow explicit tab character
String value = key_value.right(value_pos + 1).replace("\\t", "\t");
@@ -201,49 +191,41 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
}
} else if (line == "lv" || line == "locals") {
-
List<String> locals;
List<Variant> values;
script_lang->debug_get_stack_level_locals(current_frame, &locals, &values);
print_variables(locals, values, variable_prefix);
} else if (line == "gv" || line == "globals") {
-
List<String> globals;
List<Variant> values;
script_lang->debug_get_globals(&globals, &values);
print_variables(globals, values, variable_prefix);
} else if (line == "mv" || line == "members") {
-
List<String> members;
List<Variant> values;
script_lang->debug_get_stack_level_members(current_frame, &members, &values);
print_variables(members, values, variable_prefix);
} else if (line.begins_with("p") || line.begins_with("print")) {
-
if (line.get_slice_count(" ") <= 1) {
print_line("Usage: print <expre>");
} else {
-
String expr = line.get_slicec(' ', 2);
String res = script_lang->debug_parse_stack_level_expression(current_frame, expr);
print_line(res);
}
} else if (line == "s" || line == "step") {
-
script_debugger->set_depth(-1);
script_debugger->set_lines_left(1);
break;
} else if (line == "n" || line == "next") {
-
script_debugger->set_depth(0);
script_debugger->set_lines_left(1);
break;
} else if (line == "fin" || line == "finish") {
-
String current_function = script_lang->debug_get_stack_level_function(0);
for (int i = 0; i < total_frames; i++) {
@@ -259,9 +241,7 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
target_function = "";
} else if (line.begins_with("br") || line.begins_with("break")) {
-
if (line.get_slice_count(" ") <= 1) {
-
const Map<int, Set<StringName>> &breakpoints = script_debugger->get_breakpoints();
if (breakpoints.size() == 0) {
print_line("No Breakpoints.");
@@ -274,14 +254,14 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
}
} else {
-
Pair<String, int> breakpoint = to_breakpoint(line);
String source = breakpoint.first;
int linenr = breakpoint.second;
- if (source.empty())
+ if (source.empty()) {
continue;
+ }
script_debugger->insert_breakpoint(linenr, source);
@@ -289,7 +269,6 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
}
} else if (line == "q" || line == "quit") {
-
// Do not stop again on quit
script_debugger->clear_breakpoints();
script_debugger->set_depth(-1);
@@ -298,18 +277,17 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
SceneTree::get_singleton()->quit();
break;
} else if (line.begins_with("delete")) {
-
if (line.get_slice_count(" ") <= 1) {
script_debugger->clear_breakpoints();
} else {
-
Pair<String, int> breakpoint = to_breakpoint(line);
String source = breakpoint.first;
int linenr = breakpoint.second;
- if (source.empty())
+ if (source.empty()) {
continue;
+ }
script_debugger->remove_breakpoint(linenr, source);
@@ -317,7 +295,6 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
}
} else if (line == "h" || line == "help") {
-
print_line("Built-In Debugger command list:\n");
print_line("\tc,continue\t\t Continue execution.");
print_line("\tbt,backtrace\t\t Show stack trace (frames).");
@@ -340,18 +317,15 @@ void LocalDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
}
void LocalDebugger::print_variables(const List<String> &names, const List<Variant> &values, const String &variable_prefix) {
-
String value;
Vector<String> value_lines;
const List<Variant>::Element *V = values.front();
for (const List<String>::Element *E = names.front(); E; E = E->next()) {
-
value = String(V->get());
if (variable_prefix.empty()) {
print_line(E->get() + ": " + String(V->get()));
} else {
-
print_line(E->get() + ":");
value_lines = value.split("\n");
for (int i = 0; i < value_lines.size(); ++i) {
@@ -364,7 +338,6 @@ void LocalDebugger::print_variables(const List<String> &names, const List<Varian
}
Pair<String, int> LocalDebugger::to_breakpoint(const String &p_line) {
-
String breakpoint_part = p_line.get_slicec(' ', 1);
Pair<String, int> breakpoint;
@@ -381,18 +354,15 @@ Pair<String, int> LocalDebugger::to_breakpoint(const String &p_line) {
}
void LocalDebugger::send_message(const String &p_message, const Array &p_args) {
-
// This needs to be cleaned up entirely.
// print_line("MESSAGE: '" + p_message + "' - " + String(Variant(p_args)));
}
void LocalDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type) {
-
print_line("ERROR: '" + (p_descr.empty() ? p_err : p_descr) + "'");
}
LocalDebugger::LocalDebugger() {
-
options["variable_prefix"] = "";
// Bind scripts profiler.
@@ -411,6 +381,7 @@ LocalDebugger::LocalDebugger() {
LocalDebugger::~LocalDebugger() {
unregister_profiler("scripts");
- if (scripts_profiler)
+ if (scripts_profiler) {
memdelete(scripts_profiler);
+ }
}
diff --git a/core/debugger/local_debugger.h b/core/debugger/local_debugger.h
index 2c4302f4da..d342da6d44 100644
--- a/core/debugger/local_debugger.h
+++ b/core/debugger/local_debugger.h
@@ -36,7 +36,6 @@
#include "core/script_language.h"
class LocalDebugger : public EngineDebugger {
-
private:
struct ScriptsProfiler;
diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp
index e6bcc5f77e..62f600c5e5 100644
--- a/core/debugger/remote_debugger.cpp
+++ b/core/debugger/remote_debugger.cpp
@@ -33,7 +33,7 @@
#include "core/debugger/debugger_marshalls.h"
#include "core/debugger/engine_debugger.h"
#include "core/debugger/script_debugger.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "core/script_language.h"
@@ -57,7 +57,6 @@ void RemoteDebugger::_bind_profiler(const String &p_name, T *p_prof) {
}
struct RemoteDebugger::NetworkProfiler {
-
public:
typedef DebuggerMarshalls::MultiplayerNodeInfo NodeInfo;
struct BandwidthFrame {
@@ -97,8 +96,9 @@ public:
}
void init_node(const ObjectID p_node) {
- if (multiplayer_node_data.has(p_node))
+ if (multiplayer_node_data.has(p_node)) {
return;
+ }
multiplayer_node_data.insert(p_node, DebuggerMarshalls::MultiplayerNodeInfo());
multiplayer_node_data[p_node].node = p_node;
multiplayer_node_data[p_node].node_path = Object::cast_to<Node>(ObjectDB::get_instance(p_node))->get_path();
@@ -191,7 +191,6 @@ struct RemoteDebugger::ScriptsProfiler {
typedef DebuggerMarshalls::ScriptFunctionSignature FunctionSignature;
typedef DebuggerMarshalls::ScriptFunctionInfo FunctionInfo;
struct ProfileInfoSort {
-
bool operator()(ScriptLanguage::ProfilingInfo *A, ScriptLanguage::ProfilingInfo *B) const {
return A->total_time < B->total_time;
}
@@ -220,10 +219,11 @@ struct RemoteDebugger::ScriptsProfiler {
void write_frame_data(Vector<FunctionInfo> &r_funcs, uint64_t &r_total, bool p_accumulated) {
int ofs = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
- if (p_accumulated)
+ if (p_accumulated) {
ofs += ScriptServer::get_language(i)->profiling_get_accumulated_data(&info.write[ofs], info.size() - ofs);
- else
+ } else {
ofs += ScriptServer::get_language(i)->profiling_get_frame_data(&info.write[ofs], info.size() - ofs);
+ }
}
for (int i = 0; i < ofs; i++) {
@@ -270,7 +270,6 @@ struct RemoteDebugger::ScriptsProfiler {
};
struct RemoteDebugger::ServersProfiler {
-
bool skip_profile_frame = false;
typedef DebuggerMarshalls::ServerInfo ServerInfo;
typedef DebuggerMarshalls::ServerFunctionInfo ServerFunctionInfo;
@@ -347,7 +346,6 @@ struct RemoteDebugger::ServersProfiler {
};
struct RemoteDebugger::VisualProfiler {
-
typedef DebuggerMarshalls::ServerInfo ServerInfo;
typedef DebuggerMarshalls::ServerFunctionInfo ServerFunctionInfo;
@@ -362,8 +360,9 @@ struct RemoteDebugger::VisualProfiler {
void tick(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time) {
Vector<RS::FrameProfileArea> profile_areas = RS::get_singleton()->get_frame_profile();
DebuggerMarshalls::VisualProfilerFrame frame;
- if (!profile_areas.size())
+ if (!profile_areas.size()) {
return;
+ }
frame.frame_number = RS::get_singleton()->get_frame_profile_frame();
frame.areas.append_array(profile_areas);
@@ -372,19 +371,20 @@ struct RemoteDebugger::VisualProfiler {
};
struct RemoteDebugger::PerformanceProfiler {
-
Object *performance = nullptr;
int last_perf_time = 0;
void toggle(bool p_enable, const Array &p_opts) {}
void add(const Array &p_data) {}
void tick(float p_frame_time, float p_idle_time, float p_physics_time, float p_physics_frame_time) {
- if (!performance)
+ if (!performance) {
return;
+ }
uint64_t pt = OS::get_singleton()->get_ticks_msec();
- if (pt - last_perf_time < 1000)
+ if (pt - last_perf_time < 1000) {
return;
+ }
last_perf_time = pt;
int max = performance->get("MONITOR_MAX");
Array arr;
@@ -401,14 +401,12 @@ struct RemoteDebugger::PerformanceProfiler {
};
void RemoteDebugger::_send_resource_usage() {
-
DebuggerMarshalls::ResourceUsage usage;
List<RS::TextureInfo> tinfo;
RS::get_singleton()->texture_debug_usage(&tinfo);
for (List<RS::TextureInfo>::Element *E = tinfo.front(); E; E = E->next()) {
-
DebuggerMarshalls::ResourceInfo info;
info.path = E->get().path;
info.vram = E->get().bytes;
@@ -430,26 +428,29 @@ Error RemoteDebugger::_put_msg(String p_message, Array p_data) {
msg.push_back(p_message);
msg.push_back(p_data);
Error err = peer->put_message(msg);
- if (err != OK)
+ if (err != OK) {
n_messages_dropped++;
+ }
return err;
}
void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *p_file, int p_line, const char *p_err, const char *p_descr, ErrorHandlerType p_type) {
-
- if (p_type == ERR_HANDLER_SCRIPT)
+ if (p_type == ERR_HANDLER_SCRIPT) {
return; //ignore script errors, those go through debugger
+ }
RemoteDebugger *rd = (RemoteDebugger *)p_this;
- if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) // Can't handle recursive errors during flush.
+ if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) { // Can't handle recursive errors during flush.
return;
+ }
Vector<ScriptLanguage::StackInfo> si;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
si = ScriptServer::get_language(i)->debug_get_current_stack_info();
- if (si.size())
+ if (si.size()) {
break;
+ }
}
// send_error will lock internally.
@@ -457,17 +458,18 @@ void RemoteDebugger::_err_handler(void *p_this, const char *p_func, const char *
}
void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p_error) {
-
RemoteDebugger *rd = (RemoteDebugger *)p_this;
- if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) // Can't handle recursive prints during flush.
+ if (rd->flushing && Thread::get_caller_id() == rd->flush_thread) { // Can't handle recursive prints during flush.
return;
+ }
String s = p_string;
int allowed_chars = MIN(MAX(rd->max_chars_per_second - rd->char_count, 0), s.length());
- if (allowed_chars == 0)
+ if (allowed_chars == 0 && s.length() > 0) {
return;
+ }
if (allowed_chars < s.length()) {
s = s.substr(0, allowed_chars);
@@ -478,12 +480,19 @@ void RemoteDebugger::_print_handler(void *p_this, const String &p_string, bool p
rd->char_count += allowed_chars;
bool overflowed = rd->char_count >= rd->max_chars_per_second;
if (rd->is_peer_connected()) {
- if (overflowed)
+ if (overflowed) {
s += "[...]";
- rd->output_strings.push_back(s);
+ }
+
+ OutputString output_string;
+ output_string.message = s;
+ output_string.type = p_error ? MESSAGE_TYPE_ERROR : MESSAGE_TYPE_LOG;
+ rd->output_strings.push_back(output_string);
if (overflowed) {
- rd->output_strings.push_back("[output overflow, print less text!]");
+ output_string.message = "[output overflow, print less text!]";
+ output_string.type = MESSAGE_TYPE_ERROR;
+ rd->output_strings.push_back(output_string);
}
}
}
@@ -505,27 +514,45 @@ void RemoteDebugger::flush_output() {
flush_thread = Thread::get_caller_id();
flushing = true;
MutexLock lock(mutex);
- if (!is_peer_connected())
+ if (!is_peer_connected()) {
return;
+ }
if (n_messages_dropped > 0) {
ErrorMessage err_msg = _create_overflow_error("TOO_MANY_MESSAGES", "Too many messages! " + String::num_int64(n_messages_dropped) + " messages were dropped. Profiling might misbheave, try raising 'network/limits/debugger/max_queued_messages' in project setting.");
- if (_put_msg("error", err_msg.serialize()) == OK)
+ if (_put_msg("error", err_msg.serialize()) == OK) {
n_messages_dropped = 0;
+ }
}
if (output_strings.size()) {
-
// Join output strings so we generate less messages.
+ Vector<String> joined_log_strings;
Vector<String> strings;
- strings.resize(output_strings.size());
- String *w = strings.ptrw();
+ Vector<int> types;
for (int i = 0; i < output_strings.size(); i++) {
- w[i] = output_strings[i];
+ const OutputString &output_string = output_strings[i];
+ if (output_string.type == MESSAGE_TYPE_ERROR) {
+ if (!joined_log_strings.empty()) {
+ strings.push_back(String("\n").join(joined_log_strings));
+ types.push_back(MESSAGE_TYPE_LOG);
+ joined_log_strings.clear();
+ }
+ strings.push_back(output_string.message);
+ types.push_back(MESSAGE_TYPE_ERROR);
+ } else {
+ joined_log_strings.push_back(output_string.message);
+ }
+ }
+
+ if (!joined_log_strings.empty()) {
+ strings.push_back(String("\n").join(joined_log_strings));
+ types.push_back(MESSAGE_TYPE_LOG);
}
Array arr;
arr.push_back(strings);
+ arr.push_back(types);
_put_msg("output", arr);
output_strings.clear();
}
@@ -551,7 +578,6 @@ void RemoteDebugger::flush_output() {
}
void RemoteDebugger::send_message(const String &p_message, const Array &p_args) {
-
MutexLock lock(mutex);
if (is_peer_connected()) {
_put_msg(p_message, p_args);
@@ -559,7 +585,6 @@ void RemoteDebugger::send_message(const String &p_message, const Array &p_args)
}
void RemoteDebugger::send_error(const String &p_func, const String &p_file, int p_line, const String &p_err, const String &p_descr, ErrorHandlerType p_type) {
-
ErrorMessage oe;
oe.error = p_err;
oe.error_descr = p_descr;
@@ -574,8 +599,9 @@ void RemoteDebugger::send_error(const String &p_func, const String &p_file, int
oe.msec = time % 1000;
oe.callstack.append_array(script_debugger->get_error_stack_info());
- if (flushing && Thread::get_caller_id() == flush_thread) // Can't handle recursive errors during flush.
+ if (flushing && Thread::get_caller_id() == flush_thread) { // Can't handle recursive errors during flush.
return;
+ }
MutexLock lock(mutex);
@@ -586,7 +612,6 @@ void RemoteDebugger::send_error(const String &p_func, const String &p_file, int
}
if (is_peer_connected()) {
-
if (oe.warning) {
if (warn_count > max_warnings_per_second) {
n_warnings_dropped++;
@@ -634,22 +659,27 @@ Error RemoteDebugger::_try_capture(const String &p_msg, const Array &p_data, boo
return OK;
}
const String cap = p_msg.substr(0, idx);
- if (!has_capture(cap))
+ if (!has_capture(cap)) {
return ERR_UNAVAILABLE; // Unknown message...
+ }
const String msg = p_msg.substr(idx + 1);
return capture_parse(cap, msg, p_data, r_captured);
}
void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
-
//this function is called when there is a debugger break (bug on script)
//or when execution is paused from editor
- if (script_debugger->is_skipping_breakpoints() && !p_is_error_breakpoint)
+ if (script_debugger->is_skipping_breakpoints() && !p_is_error_breakpoint) {
return;
+ }
ERR_FAIL_COND_MSG(!is_peer_connected(), "Script Debugger failed to connect, but being used anyway.");
+ if (!peer->can_block()) {
+ return; // Peer does not support blocking IO. We could at least send the error though.
+ }
+
ScriptLanguage *script_lang = script_debugger->get_break_language();
const String error_str = script_lang ? script_lang->debug_get_error() : "";
Array msg;
@@ -659,9 +689,10 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
servers_profiler->skip_profile_frame = true; // Avoid frame time spike in debug.
- InputFilter::MouseMode mouse_mode = InputFilter::get_singleton()->get_mouse_mode();
- if (mouse_mode != InputFilter::MOUSE_MODE_VISIBLE)
- InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
+ Input::MouseMode mouse_mode = Input::get_singleton()->get_mouse_mode();
+ if (mouse_mode != Input::MOUSE_MODE_VISIBLE) {
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ }
uint64_t loop_begin_usec = 0;
uint64_t loop_time_sec = 0;
@@ -672,7 +703,6 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
peer->poll();
if (peer->has_message()) {
-
Array cmd = peer->get_message();
ERR_CONTINUE(cmd.size() != 2);
@@ -750,10 +780,11 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
} else if (command == "breakpoint") {
ERR_FAIL_COND(data.size() < 3);
bool set = data[2];
- if (set)
+ if (set) {
script_debugger->insert_breakpoint(data[1], data[0]);
- else
+ } else {
script_debugger->remove_breakpoint(data[1], data[0]);
+ }
} else if (command == "set_skip_breakpoints") {
ERR_FAIL_COND(data.size() < 1);
@@ -761,8 +792,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
} else {
bool captured = false;
ERR_CONTINUE(_try_capture(command, data, captured) != OK);
- if (!captured)
+ if (!captured) {
WARN_PRINT("Unknown message received from debugger: " + command);
+ }
}
} else {
OS::get_singleton()->delay_usec(10000);
@@ -779,18 +811,19 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) {
send_message("debug_exit", Array());
- if (mouse_mode != InputFilter::MOUSE_MODE_VISIBLE)
- InputFilter::get_singleton()->set_mouse_mode(mouse_mode);
+ if (mouse_mode != Input::MOUSE_MODE_VISIBLE) {
+ Input::get_singleton()->set_mouse_mode(mouse_mode);
+ }
}
void RemoteDebugger::poll_events(bool p_is_idle) {
- if (peer.is_null())
+ if (peer.is_null()) {
return;
+ }
flush_output();
peer->poll();
while (peer->has_message()) {
-
Array arr = peer->get_message();
ERR_CONTINUE(arr.size() != 2);
@@ -806,8 +839,9 @@ void RemoteDebugger::poll_events(bool p_is_idle) {
}
const String cap = cmd.substr(0, idx);
- if (!has_capture(cap))
+ if (!has_capture(cap)) {
continue; // Unknown message...
+ }
const String msg = cmd.substr(idx + 1);
capture_parse(cap, msg, arr[1], parsed);
@@ -830,10 +864,11 @@ Error RemoteDebugger::_core_capture(const String &p_cmd, const Array &p_data, bo
} else if (p_cmd == "breakpoint") {
ERR_FAIL_COND_V(p_data.size() < 3, ERR_INVALID_DATA);
bool set = p_data[2];
- if (set)
+ if (set) {
script_debugger->insert_breakpoint(p_data[1], p_data[0]);
- else
+ } else {
script_debugger->remove_breakpoint(p_data[1], p_data[0]);
+ }
} else if (p_cmd == "set_skip_breakpoints") {
ERR_FAIL_COND_V(p_data.size() < 1, ERR_INVALID_DATA);
@@ -863,13 +898,6 @@ Error RemoteDebugger::_profiler_capture(const String &p_cmd, const Array &p_data
return OK;
}
-RemoteDebugger *RemoteDebugger::create_for_uri(const String &p_uri) {
- Ref<RemoteDebuggerPeer> peer = RemoteDebuggerPeer::create_from_uri(p_uri);
- if (peer.is_valid())
- return memnew(RemoteDebugger(peer));
- return nullptr;
-}
-
RemoteDebugger::RemoteDebugger(Ref<RemoteDebuggerPeer> p_peer) {
peer = p_peer;
max_chars_per_second = GLOBAL_GET("network/limits/debugger/max_chars_per_second");
@@ -931,6 +959,7 @@ RemoteDebugger::~RemoteDebugger() {
memdelete(servers_profiler);
memdelete(network_profiler);
memdelete(visual_profiler);
- if (performance_profiler)
+ if (performance_profiler) {
memdelete(performance_profiler);
+ }
}
diff --git a/core/debugger/remote_debugger.h b/core/debugger/remote_debugger.h
index f805eec631..dc7e4436e1 100644
--- a/core/debugger/remote_debugger.h
+++ b/core/debugger/remote_debugger.h
@@ -40,6 +40,11 @@
#include "core/ustring.h"
class RemoteDebugger : public EngineDebugger {
+public:
+ enum MessageType {
+ MESSAGE_TYPE_LOG,
+ MESSAGE_TYPE_ERROR,
+ };
private:
typedef DebuggerMarshalls::OutputError ErrorMessage;
@@ -57,7 +62,11 @@ private:
Ref<RemoteDebuggerPeer> peer;
- List<String> output_strings;
+ struct OutputString {
+ String message;
+ MessageType type;
+ };
+ List<OutputString> output_strings;
List<ErrorMessage> errors;
int n_messages_dropped = 0;
@@ -99,8 +108,6 @@ private:
Error _try_capture(const String &p_name, const Array &p_data, bool &r_captured);
public:
- static RemoteDebugger *create_for_uri(const String &p_uri);
-
// Overrides
void poll_events(bool p_is_idle);
void send_message(const String &p_message, const Array &p_args);
diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp
index ed04431177..faa3a75fda 100644
--- a/core/debugger/remote_debugger_peer.cpp
+++ b/core/debugger/remote_debugger_peer.cpp
@@ -52,8 +52,9 @@ Array RemoteDebuggerPeerTCP::get_message() {
Error RemoteDebuggerPeerTCP::put_message(const Array &p_arr) {
MutexLock lock(mutex);
- if (out_queue.size() >= max_queued_messages)
+ if (out_queue.size() >= max_queued_messages) {
return ERR_OUT_OF_MEMORY;
+ }
out_queue.push_back(p_arr);
return OK;
@@ -99,8 +100,9 @@ void RemoteDebuggerPeerTCP::_write_out() {
while (tcp_client->poll(NetSocket::POLL_TYPE_OUT) == OK) {
uint8_t *buf = out_buf.ptrw();
if (out_left <= 0) {
- if (out_queue.size() == 0)
+ if (out_queue.size() == 0) {
break; // Nothing left to send
+ }
mutex.lock();
Variant var = out_queue[0];
out_queue.pop_front();
@@ -154,12 +156,12 @@ void RemoteDebuggerPeerTCP::_read_in() {
}
Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_port) {
-
IP_Address ip;
- if (p_host.is_valid_ip_address())
+ if (p_host.is_valid_ip_address()) {
ip = p_host;
- else
+ } else {
ip = IP::get_singleton()->resolve_hostname(p_host);
+ }
int port = p_port;
@@ -169,23 +171,20 @@ Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_po
tcp_client->connect_to_host(ip, port);
for (int i = 0; i < tries; i++) {
-
if (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTED) {
print_verbose("Remote Debugger: Connected!");
break;
} else {
-
const int ms = waits[i];
OS::get_singleton()->delay_usec(ms * 1000);
print_verbose("Remote Debugger: Connection failed with status: '" + String::num(tcp_client->get_status()) + "', retrying in " + String::num(ms) + " msec.");
- };
- };
+ }
+ }
if (tcp_client->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
-
ERR_PRINT("Remote Debugger: Unable to connect. Status: " + String::num(tcp_client->get_status()) + ".");
return FAILED;
- };
+ }
connected = true;
#ifndef NO_THREADS
running = true;
@@ -198,8 +197,9 @@ void RemoteDebuggerPeerTCP::_thread_func(void *p_ud) {
RemoteDebuggerPeerTCP *peer = (RemoteDebuggerPeerTCP *)p_ud;
while (peer->running && peer->is_peer_connected()) {
peer->_poll();
- if (!peer->is_peer_connected())
+ if (!peer->is_peer_connected()) {
break;
+ }
peer->tcp_client->poll(NetSocket::POLL_TYPE_IN_OUT, 1);
}
}
@@ -218,9 +218,8 @@ void RemoteDebuggerPeerTCP::_poll() {
}
}
-Ref<RemoteDebuggerPeer> RemoteDebuggerPeer::create_from_uri(const String p_uri) {
- if (!p_uri.begins_with("tcp://"))
- return Ref<RemoteDebuggerPeer>(); // Only TCP supported for now, more to come.
+RemoteDebuggerPeer *RemoteDebuggerPeerTCP::create(const String &p_uri) {
+ ERR_FAIL_COND_V(!p_uri.begins_with("tcp://"), nullptr);
String debug_host = p_uri.replace("tcp://", "");
uint16_t debug_port = 6007;
@@ -230,10 +229,13 @@ Ref<RemoteDebuggerPeer> RemoteDebuggerPeer::create_from_uri(const String p_uri)
debug_port = debug_host.substr(sep_pos + 1).to_int();
debug_host = debug_host.substr(0, sep_pos);
}
- Ref<RemoteDebuggerPeerTCP> peer = Ref<RemoteDebuggerPeer>(memnew(RemoteDebuggerPeerTCP));
+
+ RemoteDebuggerPeerTCP *peer = memnew(RemoteDebuggerPeerTCP);
Error err = peer->connect_to_host(debug_host, debug_port);
- if (err != OK)
- return Ref<RemoteDebuggerPeer>();
+ if (err != OK) {
+ memdelete(peer);
+ return nullptr;
+ }
return peer;
}
diff --git a/core/debugger/remote_debugger_peer.h b/core/debugger/remote_debugger_peer.h
index e4b838f145..3a75a2a02b 100644
--- a/core/debugger/remote_debugger_peer.h
+++ b/core/debugger/remote_debugger_peer.h
@@ -42,7 +42,6 @@ protected:
int max_queued_messages = 4096;
public:
- static Ref<RemoteDebuggerPeer> create_from_uri(const String p_uri);
virtual bool is_peer_connected() = 0;
virtual bool has_message() = 0;
virtual Error put_message(const Array &p_arr) = 0;
@@ -50,6 +49,7 @@ public:
virtual void close() = 0;
virtual void poll() = 0;
virtual int get_max_message_size() const = 0;
+ virtual bool can_block() const { return true; } // If blocking io is allowed on main thread (debug).
RemoteDebuggerPeer();
};
@@ -77,6 +77,8 @@ private:
void _read_in();
public:
+ static RemoteDebuggerPeer *create(const String &p_uri);
+
Error connect_to_host(const String &p_host, uint16_t p_port);
void poll();
diff --git a/core/debugger/script_debugger.cpp b/core/debugger/script_debugger.cpp
index 935ad01d80..0cd3238efb 100644
--- a/core/debugger/script_debugger.cpp
+++ b/core/debugger/script_debugger.cpp
@@ -33,69 +33,63 @@
#include "core/debugger/engine_debugger.h"
void ScriptDebugger::set_lines_left(int p_left) {
-
lines_left = p_left;
}
int ScriptDebugger::get_lines_left() const {
-
return lines_left;
}
void ScriptDebugger::set_depth(int p_depth) {
-
depth = p_depth;
}
int ScriptDebugger::get_depth() const {
-
return depth;
}
void ScriptDebugger::insert_breakpoint(int p_line, const StringName &p_source) {
-
- if (!breakpoints.has(p_line))
+ if (!breakpoints.has(p_line)) {
breakpoints[p_line] = Set<StringName>();
+ }
breakpoints[p_line].insert(p_source);
}
void ScriptDebugger::remove_breakpoint(int p_line, const StringName &p_source) {
-
- if (!breakpoints.has(p_line))
+ if (!breakpoints.has(p_line)) {
return;
+ }
breakpoints[p_line].erase(p_source);
- if (breakpoints[p_line].size() == 0)
+ if (breakpoints[p_line].size() == 0) {
breakpoints.erase(p_line);
+ }
}
-bool ScriptDebugger::is_breakpoint(int p_line, const StringName &p_source) const {
- if (!breakpoints.has(p_line))
+bool ScriptDebugger::is_breakpoint(int p_line, const StringName &p_source) const {
+ if (!breakpoints.has(p_line)) {
return false;
+ }
return breakpoints[p_line].has(p_source);
}
-bool ScriptDebugger::is_breakpoint_line(int p_line) const {
+bool ScriptDebugger::is_breakpoint_line(int p_line) const {
return breakpoints.has(p_line);
}
String ScriptDebugger::breakpoint_find_source(const String &p_source) const {
-
return p_source;
}
void ScriptDebugger::clear_breakpoints() {
-
breakpoints.clear();
}
void ScriptDebugger::set_skip_breakpoints(bool p_skip_breakpoints) {
-
skip_breakpoints = p_skip_breakpoints;
}
bool ScriptDebugger::is_skipping_breakpoints() {
-
return skip_breakpoints;
}
@@ -118,6 +112,5 @@ Vector<ScriptLanguage::StackInfo> ScriptDebugger::get_error_stack_info() const {
}
ScriptLanguage *ScriptDebugger::get_break_language() const {
-
return break_lang;
}
diff --git a/core/debugger/script_debugger.h b/core/debugger/script_debugger.h
index e5066273d2..0068691825 100644
--- a/core/debugger/script_debugger.h
+++ b/core/debugger/script_debugger.h
@@ -38,7 +38,6 @@
#include "core/vector.h"
class ScriptDebugger {
-
typedef ScriptLanguage::StackInfo StackInfo;
int lines_left = -1;
diff --git a/core/dictionary.cpp b/core/dictionary.cpp
index bc3b792bd5..052e1bdae1 100644
--- a/core/dictionary.cpp
+++ b/core/dictionary.cpp
@@ -35,15 +35,14 @@
#include "core/variant.h"
struct DictionaryPrivate {
-
SafeRefCount refcount;
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> variant_map;
};
void Dictionary::get_key_list(List<Variant> *p_keys) const {
-
- if (_p->variant_map.empty())
+ if (_p->variant_map.empty()) {
return;
+ }
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
p_keys->push_back(E.key());
@@ -51,7 +50,6 @@ void Dictionary::get_key_list(List<Variant> *p_keys) const {
}
Variant Dictionary::get_key_at_index(int p_index) const {
-
int index = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
if (index == p_index) {
@@ -64,7 +62,6 @@ Variant Dictionary::get_key_at_index(int p_index) const {
}
Variant Dictionary::get_value_at_index(int p_index) const {
-
int index = 0;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
if (index == p_index) {
@@ -77,38 +74,37 @@ Variant Dictionary::get_value_at_index(int p_index) const {
}
Variant &Dictionary::operator[](const Variant &p_key) {
-
return _p->variant_map[p_key];
}
const Variant &Dictionary::operator[](const Variant &p_key) const {
-
return _p->variant_map[p_key];
}
-const Variant *Dictionary::getptr(const Variant &p_key) const {
+const Variant *Dictionary::getptr(const Variant &p_key) const {
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
- if (!E)
+ if (!E) {
return nullptr;
+ }
return &E.get();
}
Variant *Dictionary::getptr(const Variant &p_key) {
-
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(p_key);
- if (!E)
+ if (!E) {
return nullptr;
+ }
return &E.get();
}
Variant Dictionary::get_valid(const Variant &p_key) const {
-
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::ConstElement E = ((const OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator> *)&_p->variant_map)->find(p_key);
- if (!E)
+ if (!E) {
return Variant();
+ }
return E.get();
}
@@ -122,16 +118,14 @@ Variant Dictionary::get(const Variant &p_key, const Variant &p_default) const {
}
int Dictionary::size() const {
-
return _p->variant_map.size();
}
-bool Dictionary::empty() const {
+bool Dictionary::empty() const {
return !_p->variant_map.size();
}
bool Dictionary::has(const Variant &p_key) const {
-
return _p->variant_map.has(p_key);
}
@@ -145,51 +139,47 @@ bool Dictionary::has_all(const Array &p_keys) const {
}
bool Dictionary::erase(const Variant &p_key) {
-
return _p->variant_map.erase(p_key);
}
bool Dictionary::operator==(const Dictionary &p_dictionary) const {
-
return _p == p_dictionary._p;
}
bool Dictionary::operator!=(const Dictionary &p_dictionary) const {
-
return _p != p_dictionary._p;
}
void Dictionary::_ref(const Dictionary &p_from) const {
-
//make a copy first (thread safe)
- if (!p_from._p->refcount.ref())
+ if (!p_from._p->refcount.ref()) {
return; // couldn't copy
+ }
//if this is the same, unreference the other one
if (p_from._p == _p) {
_p->refcount.unref();
return;
}
- if (_p)
+ if (_p) {
_unref();
+ }
_p = p_from._p;
}
void Dictionary::clear() {
-
_p->variant_map.clear();
}
void Dictionary::_unref() const {
-
ERR_FAIL_COND(!_p);
if (_p->refcount.unref()) {
memdelete(_p);
}
_p = nullptr;
}
-uint32_t Dictionary::hash() const {
+uint32_t Dictionary::hash() const {
uint32_t h = hash_djb2_one_32(Variant::DICTIONARY);
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
@@ -201,10 +191,10 @@ uint32_t Dictionary::hash() const {
}
Array Dictionary::keys() const {
-
Array varr;
- if (_p->variant_map.empty())
+ if (_p->variant_map.empty()) {
return varr;
+ }
varr.resize(size());
@@ -218,10 +208,10 @@ Array Dictionary::keys() const {
}
Array Dictionary::values() const {
-
Array varr;
- if (_p->variant_map.empty())
+ if (_p->variant_map.empty()) {
return varr;
+ }
varr.resize(size());
@@ -235,22 +225,22 @@ Array Dictionary::values() const {
}
const Variant *Dictionary::next(const Variant *p_key) const {
-
if (p_key == nullptr) {
// caller wants to get the first element
- if (_p->variant_map.front())
+ if (_p->variant_map.front()) {
return &_p->variant_map.front().key();
+ }
return nullptr;
}
OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.find(*p_key);
- if (E && E.next())
+ if (E && E.next()) {
return &E.next().key();
+ }
return nullptr;
}
Dictionary Dictionary::duplicate(bool p_deep) const {
-
Dictionary n;
for (OrderedHashMap<Variant, Variant, VariantHasher, VariantComparator>::Element E = _p->variant_map.front(); E; E = E.next()) {
@@ -261,7 +251,6 @@ Dictionary Dictionary::duplicate(bool p_deep) const {
}
void Dictionary::operator=(const Dictionary &p_dictionary) {
-
_ref(p_dictionary);
}
@@ -275,11 +264,10 @@ Dictionary::Dictionary(const Dictionary &p_from) {
}
Dictionary::Dictionary() {
-
_p = memnew(DictionaryPrivate);
_p->refcount.init();
}
-Dictionary::~Dictionary() {
+Dictionary::~Dictionary() {
_unref();
}
diff --git a/core/dictionary.h b/core/dictionary.h
index c6cbacc144..a01d96ba01 100644
--- a/core/dictionary.h
+++ b/core/dictionary.h
@@ -40,7 +40,6 @@ class Variant;
struct DictionaryPrivate;
class Dictionary {
-
mutable DictionaryPrivate *_p;
void _ref(const Dictionary &p_from) const;
diff --git a/core/engine.cpp b/core/engine.cpp
index 5361e09a8a..c8bfffd020 100644
--- a/core/engine.cpp
+++ b/core/engine.cpp
@@ -37,18 +37,18 @@
#include "core/version_hash.gen.h"
void Engine::set_iterations_per_second(int p_ips) {
-
ERR_FAIL_COND_MSG(p_ips <= 0, "Engine iterations per second must be greater than 0.");
ips = p_ips;
}
-int Engine::get_iterations_per_second() const {
+int Engine::get_iterations_per_second() const {
return ips;
}
void Engine::set_physics_jitter_fix(float p_threshold) {
- if (p_threshold < 0)
+ if (p_threshold < 0) {
p_threshold = 0;
+ }
physics_jitter_fix = p_threshold;
}
@@ -65,32 +65,26 @@ int Engine::get_target_fps() const {
}
uint64_t Engine::get_frames_drawn() {
-
return frames_drawn;
}
void Engine::set_frame_delay(uint32_t p_msec) {
-
_frame_delay = p_msec;
}
uint32_t Engine::get_frame_delay() const {
-
return _frame_delay;
}
void Engine::set_time_scale(float p_scale) {
-
_time_scale = p_scale;
}
float Engine::get_time_scale() const {
-
return _time_scale;
}
Dictionary Engine::get_version_info() const {
-
Dictionary dict;
dict["major"] = VERSION_MAJOR;
dict["minor"] = VERSION_MINOR;
@@ -104,8 +98,9 @@ Dictionary Engine::get_version_info() const {
dict["hash"] = hash.length() == 0 ? String("unknown") : hash;
String stringver = String(dict["major"]) + "." + String(dict["minor"]);
- if ((int)dict["patch"] != 0)
+ if ((int)dict["patch"] != 0) {
stringver += "." + String(dict["patch"]);
+ }
stringver += "-" + String(dict["status"]) + " (" + String(dict["build"]) + ")";
dict["string"] = stringver;
@@ -185,27 +180,24 @@ String Engine::get_license_text() const {
}
void Engine::add_singleton(const Singleton &p_singleton) {
-
singletons.push_back(p_singleton);
singleton_ptrs[p_singleton.name] = p_singleton.ptr;
}
Object *Engine::get_singleton_object(const String &p_name) const {
-
const Map<StringName, Object *>::Element *E = singleton_ptrs.find(p_name);
ERR_FAIL_COND_V_MSG(!E, nullptr, "Failed to retrieve non-existent singleton '" + p_name + "'.");
return E->get();
-};
+}
bool Engine::has_singleton(const String &p_name) const {
-
return singleton_ptrs.has(p_name);
-};
+}
void Engine::get_singletons(List<Singleton> *p_singletons) {
-
- for (List<Singleton>::Element *E = singletons.front(); E; E = E->next())
+ for (List<Singleton>::Element *E = singletons.front(); E; E = E->next()) {
p_singletons->push_back(E->get());
+ }
}
Engine *Engine::singleton = nullptr;
@@ -217,23 +209,7 @@ Engine *Engine::get_singleton() {
bool Engine::is_abort_on_gpu_errors_enabled() const {
return abort_on_gpu_errors;
}
-Engine::Engine() {
+Engine::Engine() {
singleton = this;
- frames_drawn = 0;
- ips = 60;
- physics_jitter_fix = 0.5;
- _physics_interpolation_fraction = 0.0f;
- _frame_delay = 0;
- _fps = 1;
- _target_fps = 0;
- _time_scale = 1.0;
- _pixel_snap = false;
- _physics_frames = 0;
- _idle_frames = 0;
- _in_physics = false;
- _frame_ticks = 0;
- _frame_step = 0;
- editor_hint = false;
- abort_on_gpu_errors = false;
}
diff --git a/core/engine.h b/core/engine.h
index 8512779d4c..fef330c0c1 100644
--- a/core/engine.h
+++ b/core/engine.h
@@ -37,7 +37,6 @@
#include "core/vector.h"
class Engine {
-
public:
struct Singleton {
StringName name;
@@ -51,28 +50,28 @@ public:
private:
friend class Main;
- uint64_t frames_drawn;
- uint32_t _frame_delay;
- uint64_t _frame_ticks;
- float _frame_step;
+ uint64_t frames_drawn = 0;
+ uint32_t _frame_delay = 0;
+ uint64_t _frame_ticks = 0;
+ float _frame_step = 0;
- int ips;
- float physics_jitter_fix;
- float _fps;
- int _target_fps;
- float _time_scale;
- bool _pixel_snap;
- uint64_t _physics_frames;
- float _physics_interpolation_fraction;
- bool abort_on_gpu_errors;
+ int ips = 60;
+ float physics_jitter_fix = 0.5;
+ float _fps = 1;
+ int _target_fps = 0;
+ float _time_scale = 1.0;
+ bool _pixel_snap = false;
+ uint64_t _physics_frames = 0;
+ float _physics_interpolation_fraction = 0.0f;
+ bool abort_on_gpu_errors = false;
- uint64_t _idle_frames;
- bool _in_physics;
+ uint64_t _idle_frames = 0;
+ bool _in_physics = false;
List<Singleton> singletons;
Map<StringName, Object *> singleton_ptrs;
- bool editor_hint;
+ bool editor_hint = false;
static Engine *singleton;
diff --git a/core/error_macros.cpp b/core/error_macros.cpp
index 5de070844a..2fae939965 100644
--- a/core/error_macros.cpp
+++ b/core/error_macros.cpp
@@ -37,7 +37,6 @@
static ErrorHandlerList *error_handler_list = nullptr;
void add_error_handler(ErrorHandlerList *p_handler) {
-
_global_lock();
p_handler->next = error_handler_list;
error_handler_list = p_handler;
@@ -45,20 +44,18 @@ void add_error_handler(ErrorHandlerList *p_handler) {
}
void remove_error_handler(ErrorHandlerList *p_handler) {
-
_global_lock();
ErrorHandlerList *prev = nullptr;
ErrorHandlerList *l = error_handler_list;
while (l) {
-
if (l == p_handler) {
-
- if (prev)
+ if (prev) {
prev->next = l->next;
- else
+ } else {
error_handler_list = l->next;
+ }
break;
}
prev = l;
@@ -77,13 +74,11 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
}
void _err_print_error(const char *p_function, const char *p_file, int p_line, const char *p_error, const char *p_message, ErrorHandlerType p_type) {
-
OS::get_singleton()->print_error(p_function, p_file, p_line, p_error, p_message, (Logger::ErrorType)p_type);
_global_lock();
ErrorHandlerList *l = error_handler_list;
while (l) {
-
l->errfunc(l->userdata, p_function, p_file, p_line, p_error, p_message, p_type);
l = l->next;
}
@@ -104,7 +99,6 @@ void _err_print_error(const char *p_function, const char *p_file, int p_line, co
}
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 fatal) {
-
String fstr(fatal ? "FATAL: " : "");
String err(fstr + "Index " + p_index_str + " = " + itos(p_index) + " is out of bounds (" + p_size_str + " = " + itos(p_size) + ").");
_err_print_error(p_function, p_file, p_line, err.utf8().get_data(), p_message);
diff --git a/core/error_macros.h b/core/error_macros.h
index 18c46c9e7d..46a1623115 100644
--- a/core/error_macros.h
+++ b/core/error_macros.h
@@ -47,17 +47,12 @@ enum ErrorHandlerType {
typedef void (*ErrorHandlerFunc)(void *, const char *, const char *, int p_line, const char *, const char *, ErrorHandlerType p_type);
struct ErrorHandlerList {
+ ErrorHandlerFunc errfunc = nullptr;
+ void *userdata = nullptr;
- ErrorHandlerFunc errfunc;
- void *userdata;
+ ErrorHandlerList *next = nullptr;
- ErrorHandlerList *next;
-
- ErrorHandlerList() {
- errfunc = 0;
- next = 0;
- userdata = 0;
- }
+ ErrorHandlerList() {}
};
void add_error_handler(ErrorHandlerList *p_handler);
@@ -108,6 +103,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* running application to fail or crash.
* Always try to return processable data, so the engine can keep running well.
* Use the _MSG versions to print a meaningful message to help with debugging.
+ *
+ * The `((void)0)` no-op statement is used as a trick to force us to put a semicolon after
+ * those macros, making them look like proper statements.
+ * The if wrappers are used to ensure that the macro replacement does not trigger unexpected
+ * issues when expanded e.g. after an `if (cond) ERR_FAIL();` without braces.
*/
// Index out of bounds error macros.
@@ -366,11 +366,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Ensures `m_cond` is false.
* If `m_cond` is true, the current function returns `m_retval`.
*/
-#define ERR_FAIL_COND_V(m_cond, m_retval) \
- if (unlikely(m_cond)) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. returned: " _STR(m_retval)); \
- return m_retval; \
- } else \
+#define ERR_FAIL_COND_V(m_cond, m_retval) \
+ if (unlikely(m_cond)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returning: " _STR(m_retval)); \
+ return m_retval; \
+ } else \
((void)0)
/**
@@ -380,11 +380,11 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* If checking for null use ERR_FAIL_NULL_V_MSG instead.
* If checking index bounds use ERR_FAIL_INDEX_V_MSG instead.
*/
-#define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg) \
- if (unlikely(m_cond)) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. returned: " _STR(m_retval), DEBUG_STR(m_msg)); \
- return m_retval; \
- } else \
+#define ERR_FAIL_COND_V_MSG(m_cond, m_retval, m_msg) \
+ if (unlikely(m_cond)) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Condition \"" _STR(m_cond) "\" is true. Returning: " _STR(m_retval), DEBUG_STR(m_msg)); \
+ return m_retval; \
+ } else \
((void)0)
/**
@@ -477,7 +477,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*/
#define ERR_FAIL() \
if (1) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed."); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed."); \
return; \
} else \
((void)0)
@@ -490,7 +490,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*/
#define ERR_FAIL_MSG(m_msg) \
if (1) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed.", DEBUG_STR(m_msg)); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed.", DEBUG_STR(m_msg)); \
return; \
} else \
((void)0)
@@ -504,7 +504,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*/
#define ERR_FAIL_V(m_retval) \
if (1) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " _STR(m_retval)); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed. Returning: " _STR(m_retval)); \
return m_retval; \
} else \
((void)0)
@@ -517,7 +517,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*/
#define ERR_FAIL_V_MSG(m_retval, m_msg) \
if (1) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/Function Failed, returning: " _STR(m_retval), DEBUG_STR(m_msg)); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "Method/function failed. Returning: " _STR(m_retval), DEBUG_STR(m_msg)); \
return m_retval; \
} else \
((void)0)
@@ -530,19 +530,19 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* Prints `m_msg`.
*/
#define ERR_PRINT(m_msg) \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg))
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg)
/**
* Prints `m_msg` once during the application lifetime.
*/
-#define ERR_PRINT_ONCE(m_msg) \
- if (1) { \
- static bool first_print = true; \
- if (first_print) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg)); \
- first_print = false; \
- } \
- } else \
+#define ERR_PRINT_ONCE(m_msg) \
+ if (1) { \
+ static bool first_print = true; \
+ if (first_print) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg); \
+ first_print = false; \
+ } \
+ } else \
((void)0)
// Print warning message macros.
@@ -553,21 +553,21 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
* If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
*/
#define WARN_PRINT(m_msg) \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg), ERR_HANDLER_WARNING)
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, ERR_HANDLER_WARNING)
/**
* Prints `m_msg` once during the application lifetime.
*
* If warning about deprecated usage, use `WARN_DEPRECATED` or `WARN_DEPRECATED_MSG` instead.
*/
-#define WARN_PRINT_ONCE(m_msg) \
- if (1) { \
- static bool first_print = true; \
- if (first_print) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, DEBUG_STR(m_msg), ERR_HANDLER_WARNING); \
- first_print = false; \
- } \
- } else \
+#define WARN_PRINT_ONCE(m_msg) \
+ if (1) { \
+ static bool first_print = true; \
+ if (first_print) { \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, m_msg, ERR_HANDLER_WARNING); \
+ first_print = false; \
+ } \
+ } else \
((void)0)
// Print deprecated warning message macros.
@@ -606,7 +606,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*/
#define CRASH_NOW() \
if (1) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/Function Failed."); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/function failed."); \
GENERATE_TRAP(); \
} else \
((void)0)
@@ -618,7 +618,7 @@ void _err_print_index_error(const char *p_function, const char *p_file, int p_li
*/
#define CRASH_NOW_MSG(m_msg) \
if (1) { \
- _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/Function Failed.", DEBUG_STR(m_msg)); \
+ _err_print_error(FUNCTION_STR, __FILE__, __LINE__, "FATAL: Method/function failed.", DEBUG_STR(m_msg)); \
GENERATE_TRAP(); \
} else \
((void)0)
diff --git a/core/func_ref.cpp b/core/func_ref.cpp
index 338c17946b..4427d94d2a 100644
--- a/core/func_ref.cpp
+++ b/core/func_ref.cpp
@@ -31,7 +31,6 @@
#include "func_ref.h"
Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (id.is_null()) {
r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
@@ -47,7 +46,6 @@ Variant FuncRef::call_func(const Variant **p_args, int p_argcount, Callable::Cal
}
Variant FuncRef::call_funcv(const Array &p_args) {
-
ERR_FAIL_COND_V(id.is_null(), Variant());
Object *obj = ObjectDB::get_instance(id);
@@ -58,29 +56,28 @@ Variant FuncRef::call_funcv(const Array &p_args) {
}
void FuncRef::set_instance(Object *p_obj) {
-
ERR_FAIL_NULL(p_obj);
id = p_obj->get_instance_id();
}
void FuncRef::set_function(const StringName &p_func) {
-
function = p_func;
}
bool FuncRef::is_valid() const {
- if (id.is_null())
+ if (id.is_null()) {
return false;
+ }
Object *obj = ObjectDB::get_instance(id);
- if (!obj)
+ if (!obj) {
return false;
+ }
return obj->has_method(function);
}
void FuncRef::_bind_methods() {
-
{
MethodInfo mi;
mi.name = "call_func";
@@ -94,6 +91,3 @@ void FuncRef::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_function", "name"), &FuncRef::set_function);
ClassDB::bind_method(D_METHOD("is_valid"), &FuncRef::is_valid);
}
-
-FuncRef::FuncRef() {
-}
diff --git a/core/func_ref.h b/core/func_ref.h
index 8cb3be6e61..6b0b22bab5 100644
--- a/core/func_ref.h
+++ b/core/func_ref.h
@@ -34,7 +34,6 @@
#include "core/reference.h"
class FuncRef : public Reference {
-
GDCLASS(FuncRef, Reference);
ObjectID id;
StringName function;
@@ -48,7 +47,8 @@ public:
void set_instance(Object *p_obj);
void set_function(const StringName &p_func);
bool is_valid() const;
- FuncRef();
+
+ FuncRef() {}
};
#endif // FUNC_REF_H
diff --git a/core/global_constants.cpp b/core/global_constants.cpp
index 6f6b8c1dd3..6281e56395 100644
--- a/core/global_constants.cpp
+++ b/core/global_constants.cpp
@@ -36,7 +36,6 @@
#include "core/variant.h"
struct _GlobalConstant {
-
#ifdef DEBUG_METHODS_ENABLED
StringName enum_name;
#endif
@@ -88,7 +87,8 @@ static Vector<_GlobalConstant> _global_constants;
VARIANT_ENUM_CAST(KeyList);
VARIANT_ENUM_CAST(KeyModifierMask);
VARIANT_ENUM_CAST(ButtonList);
-VARIANT_ENUM_CAST(JoystickList);
+VARIANT_ENUM_CAST(JoyButtonList);
+VARIANT_ENUM_CAST(JoyAxisList);
VARIANT_ENUM_CAST(MidiMessageList);
void register_global_constants() {
@@ -388,90 +388,70 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_XBUTTON1);
BIND_GLOBAL_ENUM_CONSTANT(BUTTON_MASK_XBUTTON2);
- //joypads
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_0);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_1);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_2);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_3);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_4);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_5);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_6);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_7);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_8);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_9);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_10);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_11);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_12);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_13);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_14);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_15);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_MAX);
-
- BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_CIRCLE);
+ // Joypad buttons
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_INVALID_BUTTON);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_A);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_B);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_X);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_Y);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_BACK);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_GUIDE);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_START);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_LEFT_STICK);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_RIGHT_STICK);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_LEFT_SHOULDER);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_RIGHT_SHOULDER);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_DPAD_UP);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_DPAD_DOWN);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_DPAD_LEFT);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_DPAD_RIGHT);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_SDL_BUTTONS);
BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_X);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_CROSS);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_CIRCLE);
BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_SQUARE);
BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_TRIANGLE);
-
- BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_B);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_SELECT);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_START);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_PS);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_L1);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_R1);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_L3);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_SONY_R3);
BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_A);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_B);
BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_X);
BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_Y);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_BACK);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_START);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_HOME);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_LS);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_RS);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_LB);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_XBOX_RB);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_BUTTON_MAX);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_DS_A);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_DS_B);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_DS_X);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_DS_Y);
-
- BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_GRIP);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_PAD);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_TRIGGER);
-
- BIND_GLOBAL_ENUM_CONSTANT(JOY_OCULUS_AX);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_OCULUS_BY);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_OCULUS_MENU);
-
- BIND_GLOBAL_ENUM_CONSTANT(JOY_OPENVR_MENU);
-
- BIND_GLOBAL_ENUM_CONSTANT(JOY_SELECT);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_START);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_DPAD_UP);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_DPAD_DOWN);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_DPAD_LEFT);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_DPAD_RIGHT);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_L);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_L2);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_L3);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_R);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_R2);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_R3);
-
- BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_0);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_1);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_2);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_3);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_4);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_5);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_6);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_7);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_8);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_9);
+ // Joypad axes
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_INVALID_AXIS);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_LEFT_X);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_LEFT_Y);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_RIGHT_X);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_RIGHT_Y);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_TRIGGER_LEFT);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_TRIGGER_RIGHT);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_SDL_AXES);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_0_X);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_0_Y);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_1_X);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_1_Y);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_2_X);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_2_Y);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_3_X);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_3_Y);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_4_X);
+ BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_4_Y);
BIND_GLOBAL_ENUM_CONSTANT(JOY_AXIS_MAX);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_LX);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_LY);
-
- BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_RX);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_RY);
-
- BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_L2);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_ANALOG_R2);
-
- BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_ANALOG_TRIGGER);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_VR_ANALOG_GRIP);
-
- BIND_GLOBAL_ENUM_CONSTANT(JOY_OPENVR_TOUCHPADX);
- BIND_GLOBAL_ENUM_CONSTANT(JOY_OPENVR_TOUCHPADY);
-
// midi
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_OFF);
BIND_GLOBAL_ENUM_CONSTANT(MIDI_MESSAGE_NOTE_ON);
@@ -568,6 +548,7 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_INTERNATIONALIZED);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_GROUP);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_CATEGORY);
+ BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SUBGROUP);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_NO_INSTANCE_STATE);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_RESTART_IF_CHANGED);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_USAGE_SCRIPT_VARIABLE);
@@ -656,33 +637,27 @@ void register_global_constants() {
}
void unregister_global_constants() {
-
_global_constants.clear();
}
int GlobalConstants::get_global_constant_count() {
-
return _global_constants.size();
}
#ifdef DEBUG_METHODS_ENABLED
StringName GlobalConstants::get_global_constant_enum(int p_idx) {
-
return _global_constants[p_idx].enum_name;
}
#else
StringName GlobalConstants::get_global_constant_enum(int p_idx) {
-
return StringName();
}
#endif
const char *GlobalConstants::get_global_constant_name(int p_idx) {
-
return _global_constants[p_idx].name;
}
int GlobalConstants::get_global_constant_value(int p_idx) {
-
return _global_constants[p_idx].value;
}
diff --git a/core/hash_map.h b/core/hash_map.h
index f27a86cc02..78592f8d82 100644
--- a/core/hash_map.h
+++ b/core/hash_map.h
@@ -59,7 +59,6 @@ template <class TKey, class TData, class Hasher = HashMapHasherDefault, class Co
class HashMap {
public:
struct Pair {
-
TKey key;
TData data;
@@ -75,8 +74,8 @@ public:
friend class HashMap;
uint32_t hash;
- Element *next;
- Element() { next = 0; }
+ Element *next = nullptr;
+ Element() {}
Pair pair;
public:
@@ -94,34 +93,32 @@ public:
};
private:
- Element **hash_table;
- uint8_t hash_table_power;
- uint32_t elements;
+ Element **hash_table = nullptr;
+ uint8_t hash_table_power = 0;
+ uint32_t elements = 0;
void make_hash_table() {
-
ERR_FAIL_COND(hash_table);
hash_table = memnew_arr(Element *, (1 << MIN_HASH_TABLE_POWER));
hash_table_power = MIN_HASH_TABLE_POWER;
elements = 0;
- for (int i = 0; i < (1 << MIN_HASH_TABLE_POWER); i++)
- hash_table[i] = 0;
+ for (int i = 0; i < (1 << MIN_HASH_TABLE_POWER); i++) {
+ hash_table[i] = nullptr;
+ }
}
void erase_hash_table() {
-
ERR_FAIL_COND_MSG(elements, "Cannot erase hash table if there are still elements inside.");
memdelete_arr(hash_table);
- hash_table = 0;
+ hash_table = nullptr;
hash_table_power = 0;
elements = 0;
}
void check_hash_table() {
-
int new_hash_table_power = -1;
if ((int)elements > ((1 << hash_table_power) * RELATIONSHIP)) {
@@ -129,40 +126,36 @@ private:
new_hash_table_power = hash_table_power + 1;
while ((int)elements > ((1 << new_hash_table_power) * RELATIONSHIP)) {
-
new_hash_table_power++;
}
} else if ((hash_table_power > (int)MIN_HASH_TABLE_POWER) && ((int)elements < ((1 << (hash_table_power - 1)) * RELATIONSHIP))) {
-
/* rehash down */
new_hash_table_power = hash_table_power - 1;
while ((int)elements < ((1 << (new_hash_table_power - 1)) * RELATIONSHIP)) {
-
new_hash_table_power--;
}
- if (new_hash_table_power < (int)MIN_HASH_TABLE_POWER)
+ if (new_hash_table_power < (int)MIN_HASH_TABLE_POWER) {
new_hash_table_power = MIN_HASH_TABLE_POWER;
+ }
}
- if (new_hash_table_power == -1)
+ if (new_hash_table_power == -1) {
return;
+ }
Element **new_hash_table = memnew_arr(Element *, ((uint64_t)1 << new_hash_table_power));
ERR_FAIL_COND_MSG(!new_hash_table, "Out of memory.");
for (int i = 0; i < (1 << new_hash_table_power); i++) {
-
- new_hash_table[i] = 0;
+ new_hash_table[i] = nullptr;
}
if (hash_table) {
for (int i = 0; i < (1 << hash_table_power); i++) {
-
while (hash_table[i]) {
-
Element *se = hash_table[i];
hash_table[i] = se->next;
int new_pos = se->hash & ((1 << new_hash_table_power) - 1);
@@ -179,17 +172,14 @@ private:
/* I want to have only one function.. */
_FORCE_INLINE_ const Element *get_element(const TKey &p_key) const {
-
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
Element *e = hash_table[index];
while (e) {
-
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && Comparator::compare(e->pair.key, p_key)) {
-
/* the pair exists in this hashtable, so just update data */
return e;
}
@@ -201,7 +191,6 @@ private:
}
Element *create_element(const TKey &p_key) {
-
/* if element doesn't exist, create it */
Element *e = memnew(Element);
ERR_FAIL_COND_V_MSG(!e, nullptr, "Out of memory.");
@@ -219,27 +208,26 @@ private:
}
void copy_from(const HashMap &p_t) {
-
- if (&p_t == this)
+ if (&p_t == this) {
return; /* much less bother with that */
+ }
clear();
- if (!p_t.hash_table || p_t.hash_table_power == 0)
+ if (!p_t.hash_table || p_t.hash_table_power == 0) {
return; /* not copying from empty table */
+ }
hash_table = memnew_arr(Element *, (uint64_t)1 << p_t.hash_table_power);
hash_table_power = p_t.hash_table_power;
elements = p_t.elements;
for (int i = 0; i < (1 << p_t.hash_table_power); i++) {
-
hash_table[i] = nullptr;
const Element *e = p_t.hash_table[i];
while (e) {
-
Element *le = memnew(Element); /* local element */
*le = *e; /* copy data */
@@ -259,20 +247,20 @@ public:
}
Element *set(const Pair &p_pair) {
-
Element *e = nullptr;
- if (!hash_table)
+ if (!hash_table) {
make_hash_table(); // if no table, make one
- else
+ } else {
e = const_cast<Element *>(get_element(p_pair.key));
+ }
/* if we made it up to here, the pair doesn't exist, create and assign */
if (!e) {
-
e = create_element(p_pair.key);
- if (!e)
+ if (!e) {
return nullptr;
+ }
check_hash_table(); // perform mantenience routine
}
@@ -281,7 +269,6 @@ public:
}
bool has(const TKey &p_key) const {
-
return getptr(p_key) != nullptr;
}
@@ -292,14 +279,12 @@ public:
*/
const TData &get(const TKey &p_key) const {
-
const TData *res = getptr(p_key);
ERR_FAIL_COND_V(!res, *res);
return *res;
}
TData &get(const TKey &p_key) {
-
TData *res = getptr(p_key);
ERR_FAIL_COND_V(!res, *res);
return *res;
@@ -311,27 +296,29 @@ public:
*/
_FORCE_INLINE_ TData *getptr(const TKey &p_key) {
-
- if (unlikely(!hash_table))
+ if (unlikely(!hash_table)) {
return nullptr;
+ }
Element *e = const_cast<Element *>(get_element(p_key));
- if (e)
+ if (e) {
return &e->pair.data;
+ }
return nullptr;
}
_FORCE_INLINE_ const TData *getptr(const TKey &p_key) const {
-
- if (unlikely(!hash_table))
+ if (unlikely(!hash_table)) {
return nullptr;
+ }
const Element *e = const_cast<Element *>(get_element(p_key));
- if (e)
+ if (e) {
return &e->pair.data;
+ }
return nullptr;
}
@@ -343,9 +330,9 @@ public:
template <class C>
_FORCE_INLINE_ TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) {
-
- if (unlikely(!hash_table))
+ if (unlikely(!hash_table)) {
return nullptr;
+ }
uint32_t hash = p_custom_hash;
uint32_t index = hash & ((1 << hash_table_power) - 1);
@@ -353,10 +340,8 @@ public:
Element *e = hash_table[index];
while (e) {
-
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && Comparator::compare(e->pair.key, p_custom_key)) {
-
/* the pair exists in this hashtable, so just update data */
return &e->pair.data;
}
@@ -369,9 +354,9 @@ public:
template <class C>
_FORCE_INLINE_ const TData *custom_getptr(C p_custom_key, uint32_t p_custom_hash) const {
-
- if (unlikely(!hash_table))
+ if (unlikely(!hash_table)) {
return nullptr;
+ }
uint32_t hash = p_custom_hash;
uint32_t index = hash & ((1 << hash_table_power) - 1);
@@ -379,10 +364,8 @@ public:
const Element *e = hash_table[index];
while (e) {
-
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && Comparator::compare(e->pair.key, p_custom_key)) {
-
/* the pair exists in this hashtable, so just update data */
return &e->pair.data;
}
@@ -398,9 +381,9 @@ public:
*/
bool erase(const TKey &p_key) {
-
- if (unlikely(!hash_table))
+ if (unlikely(!hash_table)) {
return false;
+ }
uint32_t hash = Hasher::hash(p_key);
uint32_t index = hash & ((1 << hash_table_power) - 1);
@@ -408,12 +391,9 @@ public:
Element *e = hash_table[index];
Element *p = nullptr;
while (e) {
-
/* checking hash first avoids comparing key, which may take longer */
if (e->hash == hash && Comparator::compare(e->pair.key, p_key)) {
-
if (p) {
-
p->next = e->next;
} else {
//begin of list
@@ -423,10 +403,11 @@ public:
memdelete(e);
elements--;
- if (elements == 0)
+ if (elements == 0) {
erase_hash_table();
- else
+ } else {
check_hash_table();
+ }
return true;
}
@@ -444,14 +425,14 @@ public:
inline TData &operator[](const TKey &p_key) { //assignment
Element *e = nullptr;
- if (!hash_table)
+ if (!hash_table) {
make_hash_table(); // if no table, make one
- else
+ } else {
e = const_cast<Element *>(get_element(p_key));
+ }
/* if we made it up to here, the pair doesn't exist, create */
if (!e) {
-
e = create_element(p_key);
CRASH_COND(!e);
check_hash_table(); // perform mantenience routine
@@ -476,14 +457,13 @@ public:
*
*/
const TKey *next(const TKey *p_key) const {
-
- if (unlikely(!hash_table))
+ if (unlikely(!hash_table)) {
return nullptr;
+ }
if (!p_key) { /* get the first key */
for (int i = 0; i < (1 << hash_table_power); i++) {
-
if (hash_table[i]) {
return &hash_table[i]->pair.key;
}
@@ -501,7 +481,6 @@ public:
uint32_t index = e->hash & ((1 << hash_table_power) - 1);
index++;
for (int i = index; i < (1 << hash_table_power); i++) {
-
if (hash_table[i]) {
return &hash_table[i]->pair.key;
}
@@ -515,23 +494,18 @@ public:
}
inline unsigned int size() const {
-
return elements;
}
inline bool empty() const {
-
return elements == 0;
}
void clear() {
-
/* clean up */
if (hash_table) {
for (int i = 0; i < (1 << hash_table_power); i++) {
-
while (hash_table[i]) {
-
Element *e = hash_table[i];
hash_table[i] = e->next;
memdelete(e);
@@ -541,27 +515,20 @@ public:
memdelete_arr(hash_table);
}
- hash_table = 0;
+ hash_table = nullptr;
hash_table_power = 0;
elements = 0;
}
void operator=(const HashMap &p_table) {
-
copy_from(p_table);
}
- HashMap() {
- hash_table = nullptr;
- elements = 0;
- hash_table_power = 0;
- }
-
void get_key_value_ptr_array(const Pair **p_pairs) const {
- if (unlikely(!hash_table))
+ if (unlikely(!hash_table)) {
return;
+ }
for (int i = 0; i < (1 << hash_table_power); i++) {
-
Element *e = hash_table[i];
while (e) {
*p_pairs = &e->pair;
@@ -572,10 +539,10 @@ public:
}
void get_key_list(List<TKey> *p_keys) const {
- if (unlikely(!hash_table))
+ if (unlikely(!hash_table)) {
return;
+ }
for (int i = 0; i < (1 << hash_table_power); i++) {
-
Element *e = hash_table[i];
while (e) {
p_keys->push_back(e->pair.key);
@@ -584,17 +551,13 @@ public:
}
}
- HashMap(const HashMap &p_table) {
-
- hash_table = nullptr;
- elements = 0;
- hash_table_power = 0;
+ HashMap() {}
+ HashMap(const HashMap &p_table) {
copy_from(p_table);
}
~HashMap() {
-
clear();
}
};
diff --git a/core/hashfuncs.h b/core/hashfuncs.h
index a41a034843..d984f6c524 100644
--- a/core/hashfuncs.h
+++ b/core/hashfuncs.h
@@ -49,29 +49,28 @@
* @return 32-bits hashcode
*/
static inline uint32_t hash_djb2(const char *p_cstr) {
-
const unsigned char *chr = (const unsigned char *)p_cstr;
uint32_t hash = 5381;
uint32_t c;
- while ((c = *chr++))
+ while ((c = *chr++)) {
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+ }
return hash;
}
static inline uint32_t hash_djb2_buffer(const uint8_t *p_buff, int p_len, uint32_t p_prev = 5381) {
-
uint32_t hash = p_prev;
- for (int i = 0; i < p_len; i++)
+ for (int i = 0; i < p_len; i++) {
hash = ((hash << 5) + hash) + p_buff[i]; /* hash * 33 + c */
+ }
return hash;
}
static inline uint32_t hash_djb2_one_32(uint32_t p_in, uint32_t p_prev = 5381) {
-
return ((p_prev << 5) + p_prev) + p_in;
}
@@ -93,19 +92,19 @@ static inline uint32_t hash_djb2_one_float(double p_in, uint32_t p_prev = 5381)
} u;
// Normalize +/- 0.0 and NaN values so they hash the same.
- if (p_in == 0.0f)
+ if (p_in == 0.0f) {
u.d = 0.0;
- else if (Math::is_nan(p_in))
+ } else if (Math::is_nan(p_in)) {
u.d = Math_NAN;
- else
+ } else {
u.d = p_in;
+ }
return ((p_prev << 5) + p_prev) + hash_one_uint64(u.i);
}
template <class T>
static inline uint32_t make_uint32_t(T p_in) {
-
union {
T t;
uint32_t _u32;
@@ -116,13 +115,11 @@ static inline uint32_t make_uint32_t(T p_in) {
}
static inline uint64_t hash_djb2_one_64(uint64_t p_in, uint64_t p_prev = 5381) {
-
return ((p_prev << 5) + p_prev) + p_in;
}
template <class T>
static inline uint64_t make_uint64_t(T p_in) {
-
union {
T t;
uint64_t _u64;
@@ -134,7 +131,6 @@ static inline uint64_t make_uint64_t(T p_in) {
}
struct HashMapHasherDefault {
-
static _FORCE_INLINE_ uint32_t hash(const String &p_string) { return p_string.hash(); }
static _FORCE_INLINE_ uint32_t hash(const char *p_cstr) { return hash_djb2(p_cstr); }
static _FORCE_INLINE_ uint32_t hash(const uint64_t p_int) { return hash_one_uint64(p_int); }
diff --git a/core/image.cpp b/core/image.cpp
index 2097f27b01..4ab71128cd 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -37,8 +37,6 @@
#include "core/os/copymem.h"
#include "core/print_string.h"
-#include "thirdparty/misc/hq2x.h"
-
#include <stdio.h>
const char *Image::format_names[Image::FORMAT_MAX] = {
@@ -90,7 +88,6 @@ SaveEXRFunc Image::save_exr_func = nullptr;
SavePNGBufferFunc Image::save_png_buffer_func = nullptr;
void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel) {
-
uint32_t ofs = (p_y * width + p_x) * p_pixelsize;
for (uint32_t i = 0; i < p_pixelsize; i++) {
@@ -99,7 +96,6 @@ void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data,
}
void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_data, uint8_t *p_pixel) {
-
uint32_t ofs = (p_y * width + p_x) * p_pixelsize;
for (uint32_t i = 0; i < p_pixelsize; i++) {
@@ -108,29 +104,41 @@ void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p
}
int Image::get_format_pixel_size(Format p_format) {
-
switch (p_format) {
case FORMAT_L8:
return 1; //luminance
case FORMAT_LA8:
return 2; //luminance-alpha
- case FORMAT_R8: return 1;
- case FORMAT_RG8: return 2;
- case FORMAT_RGB8: return 3;
- case FORMAT_RGBA8: return 4;
- case FORMAT_RGBA4444: return 2;
- case FORMAT_RGB565: return 2;
+ case FORMAT_R8:
+ return 1;
+ case FORMAT_RG8:
+ return 2;
+ case FORMAT_RGB8:
+ return 3;
+ case FORMAT_RGBA8:
+ return 4;
+ case FORMAT_RGBA4444:
+ return 2;
+ case FORMAT_RGB565:
+ return 2;
case FORMAT_RF:
return 4; //float
- case FORMAT_RGF: return 8;
- case FORMAT_RGBF: return 12;
- case FORMAT_RGBAF: return 16;
+ case FORMAT_RGF:
+ return 8;
+ case FORMAT_RGBF:
+ return 12;
+ case FORMAT_RGBAF:
+ return 16;
case FORMAT_RH:
return 2; //half float
- case FORMAT_RGH: return 4;
- case FORMAT_RGBH: return 6;
- case FORMAT_RGBAH: return 8;
- case FORMAT_RGBE9995: return 4;
+ case FORMAT_RGH:
+ return 4;
+ case FORMAT_RGBH:
+ return 6;
+ case FORMAT_RGBAH:
+ return 8;
+ case FORMAT_RGBE9995:
+ return 4;
case FORMAT_DXT1:
return 1; //s3tc bc1
case FORMAT_DXT3:
@@ -149,22 +157,32 @@ int Image::get_format_pixel_size(Format p_format) {
return 1; //unsigned float
case FORMAT_PVRTC2:
return 1; //pvrtc
- case FORMAT_PVRTC2A: return 1;
- case FORMAT_PVRTC4: return 1;
- case FORMAT_PVRTC4A: return 1;
+ case FORMAT_PVRTC2A:
+ return 1;
+ case FORMAT_PVRTC4:
+ return 1;
+ case FORMAT_PVRTC4A:
+ return 1;
case FORMAT_ETC:
return 1; //etc1
case FORMAT_ETC2_R11:
return 1; //etc2
case FORMAT_ETC2_R11S:
return 1; //signed: return 1; NOT srgb.
- case FORMAT_ETC2_RG11: return 1;
- case FORMAT_ETC2_RG11S: return 1;
- case FORMAT_ETC2_RGB8: return 1;
- case FORMAT_ETC2_RGBA8: return 1;
- case FORMAT_ETC2_RGB8A1: return 1;
- case FORMAT_ETC2_RA_AS_RG: return 1;
- case FORMAT_DXT5_RA_AS_RG: return 1;
+ case FORMAT_ETC2_RG11:
+ return 1;
+ case FORMAT_ETC2_RG11S:
+ return 1;
+ case FORMAT_ETC2_RGB8:
+ return 1;
+ case FORMAT_ETC2_RGBA8:
+ return 1;
+ case FORMAT_ETC2_RGB8A1:
+ return 1;
+ case FORMAT_ETC2_RA_AS_RG:
+ return 1;
+ case FORMAT_DXT5_RA_AS_RG:
+ return 1;
case FORMAT_MAX: {
}
}
@@ -172,7 +190,6 @@ int Image::get_format_pixel_size(Format p_format) {
}
void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
-
switch (p_format) {
case FORMAT_DXT1: //s3tc bc1
case FORMAT_DXT3: //bc2
@@ -185,25 +202,21 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
} break;
case FORMAT_PVRTC2:
case FORMAT_PVRTC2A: {
-
r_w = 16;
r_h = 8;
} break;
case FORMAT_PVRTC4A:
case FORMAT_PVRTC4: {
-
r_w = 8;
r_h = 8;
} break;
case FORMAT_ETC: {
-
r_w = 4;
r_h = 4;
} break;
case FORMAT_BPTC_RGBA:
case FORMAT_BPTC_RGBF:
case FORMAT_BPTC_RGBFU: {
-
r_w = 4;
r_h = 4;
} break;
@@ -216,7 +229,6 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
case FORMAT_ETC2_RGB8A1:
case FORMAT_ETC2_RA_AS_RG:
case FORMAT_DXT5_RA_AS_RG: {
-
r_w = 4;
r_h = 4;
@@ -230,17 +242,16 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
}
int Image::get_format_pixel_rshift(Format p_format) {
-
- if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC4 || p_format == FORMAT_PVRTC4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1)
+ if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC4 || p_format == FORMAT_PVRTC4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1) {
return 1;
- else if (p_format == FORMAT_PVRTC2 || p_format == FORMAT_PVRTC2A)
+ } else if (p_format == FORMAT_PVRTC2 || p_format == FORMAT_PVRTC2A) {
return 2;
- else
+ } else {
return 0;
+ }
}
int Image::get_format_block_size(Format p_format) {
-
switch (p_format) {
case FORMAT_DXT1: //s3tc bc1
case FORMAT_DXT3: //bc2
@@ -252,22 +263,18 @@ int Image::get_format_block_size(Format p_format) {
}
case FORMAT_PVRTC2:
case FORMAT_PVRTC2A: {
-
return 4;
}
case FORMAT_PVRTC4A:
case FORMAT_PVRTC4: {
-
return 4;
}
case FORMAT_ETC: {
-
return 4;
}
case FORMAT_BPTC_RGBA:
case FORMAT_BPTC_RGBF:
case FORMAT_BPTC_RGBFU: {
-
return 4;
}
case FORMAT_ETC2_R11: //etc2
@@ -281,7 +288,6 @@ int Image::get_format_block_size(Format p_format) {
case FORMAT_DXT5_RA_AS_RG: //used to make basis universal happy
{
-
return 4;
}
default: {
@@ -292,7 +298,6 @@ int Image::get_format_block_size(Format p_format) {
}
void Image::_get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_width, int &r_height) const {
-
int w = width;
int h = height;
int ofs = 0;
@@ -322,7 +327,6 @@ void Image::_get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_widt
}
int Image::get_mipmap_offset(int p_mipmap) const {
-
ERR_FAIL_INDEX_V(p_mipmap, get_mipmap_count() + 1, -1);
int ofs, w, h;
@@ -331,7 +335,6 @@ int Image::get_mipmap_offset(int p_mipmap) const {
}
int Image::get_mipmap_byte_size(int p_mipmap) const {
-
ERR_FAIL_INDEX_V(p_mipmap, get_mipmap_count() + 1, -1);
int ofs, w, h;
@@ -342,7 +345,6 @@ int Image::get_mipmap_byte_size(int p_mipmap) const {
}
void Image::get_mipmap_offset_and_size(int p_mipmap, int &r_ofs, int &r_size) const {
-
int ofs, w, h;
_get_mipmap_offset_and_size(p_mipmap, ofs, w, h);
int ofs2;
@@ -352,7 +354,6 @@ void Image::get_mipmap_offset_and_size(int p_mipmap, int &r_ofs, int &r_size) co
}
void Image::get_mipmap_offset_size_and_dimensions(int p_mipmap, int &r_ofs, int &r_size, int &w, int &h) const {
-
int ofs;
_get_mipmap_offset_and_size(p_mipmap, ofs, w, h);
int ofs2, w2, h2;
@@ -362,42 +363,36 @@ void Image::get_mipmap_offset_size_and_dimensions(int p_mipmap, int &r_ofs, int
}
int Image::get_width() const {
-
return width;
}
int Image::get_height() const {
-
return height;
}
Vector2 Image::get_size() const {
-
return Vector2(width, height);
}
bool Image::has_mipmaps() const {
-
return mipmaps;
}
int Image::get_mipmap_count() const {
-
- if (mipmaps)
+ if (mipmaps) {
return get_image_required_mipmaps(width, height, format);
- else
+ } else {
return 0;
+ }
}
//using template generates perfectly optimized code due to constant expression reduction and unused variable removal present in all compilers
template <uint32_t read_bytes, bool read_alpha, uint32_t write_bytes, bool write_alpha, bool read_gray, bool write_gray>
static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p_dst) {
-
uint32_t max_bytes = MAX(read_bytes, write_bytes);
for (int y = 0; y < p_height; y++) {
for (int x = 0; x < p_width; x++) {
-
const uint8_t *rofs = &p_src[((y * p_width) + x) * (read_bytes + (read_alpha ? 1 : 0))];
uint8_t *wofs = &p_dst[((y * p_width) + x) * (write_bytes + (write_alpha ? 1 : 0))];
@@ -408,9 +403,7 @@ static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p
rgba[1] = rofs[0];
rgba[2] = rofs[0];
} else {
-
for (uint32_t i = 0; i < max_bytes; i++) {
-
rgba[i] = (i < read_bytes) ? rofs[i] : 0;
}
}
@@ -424,7 +417,6 @@ static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p
wofs[0] = uint8_t((uint16_t(rofs[0]) + uint16_t(rofs[1]) + uint16_t(rofs[2])) / 3);
} else {
for (uint32_t i = 0; i < write_bytes; i++) {
-
wofs[i] = rgba[i];
}
}
@@ -437,25 +429,23 @@ static void _convert(int p_width, int p_height, const uint8_t *p_src, uint8_t *p
}
void Image::convert(Format p_new_format) {
-
- if (data.size() == 0)
+ if (data.size() == 0) {
return;
+ }
- if (p_new_format == format)
+ if (p_new_format == format) {
return;
+ }
if (format > FORMAT_RGBE9995 || p_new_format > FORMAT_RGBE9995) {
-
ERR_FAIL_MSG("Cannot convert to <-> from compressed formats. Use compress() and decompress() instead.");
} else if (format > FORMAT_RGBA8 || p_new_format > FORMAT_RGBA8) {
-
//use put/set pixel which is slower but works with non byte formats
- Image new_img(width, height, 0, p_new_format);
+ Image new_img(width, height, false, p_new_format);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
-
new_img.set_pixel(i, j, get_pixel(i, j));
}
}
@@ -469,7 +459,7 @@ void Image::convert(Format p_new_format) {
return;
}
- Image new_img(width, height, 0, p_new_format);
+ Image new_img(width, height, false, p_new_format);
const uint8_t *rptr = data.ptr();
uint8_t *wptr = new_img.data.ptrw();
@@ -477,69 +467,127 @@ void Image::convert(Format p_new_format) {
int conversion_type = format | p_new_format << 8;
switch (conversion_type) {
-
- case FORMAT_L8 | (FORMAT_LA8 << 8): _convert<1, false, 1, true, true, true>(width, height, rptr, wptr); break;
- case FORMAT_L8 | (FORMAT_R8 << 8): _convert<1, false, 1, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_L8 | (FORMAT_RG8 << 8): _convert<1, false, 2, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_L8 | (FORMAT_RGB8 << 8): _convert<1, false, 3, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_L8 | (FORMAT_RGBA8 << 8): _convert<1, false, 3, true, true, false>(width, height, rptr, wptr); break;
- case FORMAT_LA8 | (FORMAT_L8 << 8): _convert<1, true, 1, false, true, true>(width, height, rptr, wptr); break;
- case FORMAT_LA8 | (FORMAT_R8 << 8): _convert<1, true, 1, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_LA8 | (FORMAT_RG8 << 8): _convert<1, true, 2, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_LA8 | (FORMAT_RGB8 << 8): _convert<1, true, 3, false, true, false>(width, height, rptr, wptr); break;
- case FORMAT_LA8 | (FORMAT_RGBA8 << 8): _convert<1, true, 3, true, true, false>(width, height, rptr, wptr); break;
- case FORMAT_R8 | (FORMAT_L8 << 8): _convert<1, false, 1, false, false, true>(width, height, rptr, wptr); break;
- case FORMAT_R8 | (FORMAT_LA8 << 8): _convert<1, false, 1, true, false, true>(width, height, rptr, wptr); break;
- case FORMAT_R8 | (FORMAT_RG8 << 8): _convert<1, false, 2, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_R8 | (FORMAT_RGB8 << 8): _convert<1, false, 3, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_R8 | (FORMAT_RGBA8 << 8): _convert<1, false, 3, true, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RG8 | (FORMAT_L8 << 8): _convert<2, false, 1, false, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RG8 | (FORMAT_LA8 << 8): _convert<2, false, 1, true, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RG8 | (FORMAT_R8 << 8): _convert<2, false, 1, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RG8 | (FORMAT_RGB8 << 8): _convert<2, false, 3, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RG8 | (FORMAT_RGBA8 << 8): _convert<2, false, 3, true, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGB8 | (FORMAT_L8 << 8): _convert<3, false, 1, false, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RGB8 | (FORMAT_LA8 << 8): _convert<3, false, 1, true, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RGB8 | (FORMAT_R8 << 8): _convert<3, false, 1, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGB8 | (FORMAT_RG8 << 8): _convert<3, false, 2, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGB8 | (FORMAT_RGBA8 << 8): _convert<3, false, 3, true, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGBA8 | (FORMAT_L8 << 8): _convert<3, true, 1, false, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RGBA8 | (FORMAT_LA8 << 8): _convert<3, true, 1, true, false, true>(width, height, rptr, wptr); break;
- case FORMAT_RGBA8 | (FORMAT_R8 << 8): _convert<3, true, 1, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGBA8 | (FORMAT_RG8 << 8): _convert<3, true, 2, false, false, false>(width, height, rptr, wptr); break;
- case FORMAT_RGBA8 | (FORMAT_RGB8 << 8): _convert<3, true, 3, false, false, false>(width, height, rptr, wptr); break;
+ case FORMAT_L8 | (FORMAT_LA8 << 8):
+ _convert<1, false, 1, true, true, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_L8 | (FORMAT_R8 << 8):
+ _convert<1, false, 1, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_L8 | (FORMAT_RG8 << 8):
+ _convert<1, false, 2, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_L8 | (FORMAT_RGB8 << 8):
+ _convert<1, false, 3, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_L8 | (FORMAT_RGBA8 << 8):
+ _convert<1, false, 3, true, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_LA8 | (FORMAT_L8 << 8):
+ _convert<1, true, 1, false, true, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_LA8 | (FORMAT_R8 << 8):
+ _convert<1, true, 1, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_LA8 | (FORMAT_RG8 << 8):
+ _convert<1, true, 2, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_LA8 | (FORMAT_RGB8 << 8):
+ _convert<1, true, 3, false, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_LA8 | (FORMAT_RGBA8 << 8):
+ _convert<1, true, 3, true, true, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_R8 | (FORMAT_L8 << 8):
+ _convert<1, false, 1, false, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_R8 | (FORMAT_LA8 << 8):
+ _convert<1, false, 1, true, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_R8 | (FORMAT_RG8 << 8):
+ _convert<1, false, 2, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_R8 | (FORMAT_RGB8 << 8):
+ _convert<1, false, 3, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_R8 | (FORMAT_RGBA8 << 8):
+ _convert<1, false, 3, true, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RG8 | (FORMAT_L8 << 8):
+ _convert<2, false, 1, false, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RG8 | (FORMAT_LA8 << 8):
+ _convert<2, false, 1, true, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RG8 | (FORMAT_R8 << 8):
+ _convert<2, false, 1, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RG8 | (FORMAT_RGB8 << 8):
+ _convert<2, false, 3, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RG8 | (FORMAT_RGBA8 << 8):
+ _convert<2, false, 3, true, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGB8 | (FORMAT_L8 << 8):
+ _convert<3, false, 1, false, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGB8 | (FORMAT_LA8 << 8):
+ _convert<3, false, 1, true, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGB8 | (FORMAT_R8 << 8):
+ _convert<3, false, 1, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGB8 | (FORMAT_RG8 << 8):
+ _convert<3, false, 2, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGB8 | (FORMAT_RGBA8 << 8):
+ _convert<3, false, 3, true, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGBA8 | (FORMAT_L8 << 8):
+ _convert<3, true, 1, false, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGBA8 | (FORMAT_LA8 << 8):
+ _convert<3, true, 1, true, false, true>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGBA8 | (FORMAT_R8 << 8):
+ _convert<3, true, 1, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGBA8 | (FORMAT_RG8 << 8):
+ _convert<3, true, 2, false, false, false>(width, height, rptr, wptr);
+ break;
+ case FORMAT_RGBA8 | (FORMAT_RGB8 << 8):
+ _convert<3, true, 3, false, false, false>(width, height, rptr, wptr);
+ break;
}
bool gen_mipmaps = mipmaps;
_copy_internals_from(new_img);
- if (gen_mipmaps)
+ if (gen_mipmaps) {
generate_mipmaps();
+ }
}
Image::Format Image::get_format() const {
-
return format;
}
static double _bicubic_interp_kernel(double x) {
-
x = ABS(x);
double bc = 0;
- if (x <= 1)
+ if (x <= 1) {
bc = (1.5 * x - 2.5) * x * x + 1;
- else if (x < 2)
+ } else if (x < 2) {
bc = ((-0.5 * x + 2.5) * x - 4) * x + 2;
+ }
return bc;
}
template <int CC, class T>
static void _scale_cubic(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) {
-
// get source image size
int width = p_src_width;
int height = p_src_height;
@@ -580,20 +628,24 @@ static void _scale_cubic(const uint8_t *__restrict p_src, uint8_t *__restrict p_
k1 = _bicubic_interp_kernel(dy - (double)n);
oy2 = oy1 + n;
- if (oy2 < 0)
+ if (oy2 < 0) {
oy2 = 0;
- if (oy2 > ymax)
+ }
+ if (oy2 > ymax) {
oy2 = ymax;
+ }
for (int m = -1; m < 3; m++) {
// get X coefficient
k2 = k1 * _bicubic_interp_kernel((double)m - dx);
ox2 = ox1 + m;
- if (ox2 < 0)
+ if (ox2 < 0) {
ox2 = 0;
- if (ox2 > xmax)
+ }
+ if (ox2 > xmax) {
ox2 = xmax;
+ }
// get pixel of original image
const T *__restrict p = ((T *)p_src) + (oy2 * p_src_width + ox2) * CC;
@@ -623,7 +675,6 @@ static void _scale_cubic(const uint8_t *__restrict p_src, uint8_t *__restrict p_
template <int CC, class T>
static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) {
-
enum {
FRAC_BITS = 8,
FRAC_LEN = (1 << FRAC_BITS),
@@ -632,14 +683,14 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict
};
for (uint32_t i = 0; i < p_dst_height; i++) {
-
uint32_t src_yofs_up_fp = (i * p_src_height * FRAC_LEN / p_dst_height);
uint32_t src_yofs_frac = src_yofs_up_fp & FRAC_MASK;
uint32_t src_yofs_up = src_yofs_up_fp >> FRAC_BITS;
uint32_t src_yofs_down = (i + 1) * p_src_height / p_dst_height;
- if (src_yofs_down >= p_src_height)
+ if (src_yofs_down >= p_src_height) {
src_yofs_down = p_src_height - 1;
+ }
//src_yofs_up*=CC;
//src_yofs_down*=CC;
@@ -648,19 +699,18 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict
uint32_t y_ofs_down = src_yofs_down * p_src_width * CC;
for (uint32_t j = 0; j < p_dst_width; j++) {
-
uint32_t src_xofs_left_fp = (j * p_src_width * FRAC_LEN / p_dst_width);
uint32_t src_xofs_frac = src_xofs_left_fp & FRAC_MASK;
uint32_t src_xofs_left = src_xofs_left_fp >> FRAC_BITS;
uint32_t src_xofs_right = (j + 1) * p_src_width / p_dst_width;
- if (src_xofs_right >= p_src_width)
+ if (src_xofs_right >= p_src_width) {
src_xofs_right = p_src_width - 1;
+ }
src_xofs_left *= CC;
src_xofs_right *= CC;
for (uint32_t l = 0; l < CC; l++) {
-
if (sizeof(T) == 1) { //uint8
uint32_t p00 = p_src[y_ofs_up + src_xofs_left + l] << FRAC_BITS;
uint32_t p10 = p_src[y_ofs_up + src_xofs_right + l] << FRAC_BITS;
@@ -714,19 +764,15 @@ static void _scale_bilinear(const uint8_t *__restrict p_src, uint8_t *__restrict
template <int CC, class T>
static void _scale_nearest(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) {
-
for (uint32_t i = 0; i < p_dst_height; i++) {
-
uint32_t src_yofs = i * p_src_height / p_dst_height;
uint32_t y_ofs = src_yofs * p_src_width * CC;
for (uint32_t j = 0; j < p_dst_width; j++) {
-
uint32_t src_xofs = j * p_src_width / p_dst_width;
src_xofs *= CC;
for (uint32_t l = 0; l < CC; l++) {
-
const T *src = ((const T *)p_src);
T *dst = ((T *)p_dst);
@@ -745,7 +791,6 @@ static float _lanczos(float p_x) {
template <int CC, class T>
static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, uint32_t p_src_width, uint32_t p_src_height, uint32_t p_dst_width, uint32_t p_dst_height) {
-
int32_t src_width = p_src_width;
int32_t src_height = p_src_height;
int32_t dst_height = p_dst_height;
@@ -764,40 +809,40 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
float *kernel = memnew_arr(float, half_kernel * 2);
for (int32_t buffer_x = 0; buffer_x < dst_width; buffer_x++) {
-
// The corresponding point on the source image
float src_x = (buffer_x + 0.5f) * x_scale; // Offset by 0.5 so it uses the pixel's center
int32_t start_x = MAX(0, int32_t(src_x) - half_kernel + 1);
int32_t end_x = MIN(src_width - 1, int32_t(src_x) + half_kernel);
// Create the kernel used by all the pixels of the column
- for (int32_t target_x = start_x; target_x <= end_x; target_x++)
+ for (int32_t target_x = start_x; target_x <= end_x; target_x++) {
kernel[target_x - start_x] = _lanczos((target_x + 0.5f - src_x) / scale_factor);
+ }
for (int32_t buffer_y = 0; buffer_y < src_height; buffer_y++) {
-
float pixel[CC] = { 0 };
float weight = 0;
for (int32_t target_x = start_x; target_x <= end_x; target_x++) {
-
float lanczos_val = kernel[target_x - start_x];
weight += lanczos_val;
const T *__restrict src_data = ((const T *)p_src) + (buffer_y * src_width + target_x) * CC;
for (uint32_t i = 0; i < CC; i++) {
- if (sizeof(T) == 2) //half float
+ if (sizeof(T) == 2) { //half float
pixel[i] += Math::half_to_float(src_data[i]) * lanczos_val;
- else
+ } else {
pixel[i] += src_data[i] * lanczos_val;
+ }
}
}
float *dst_data = ((float *)buffer) + (buffer_y * dst_width + buffer_x) * CC;
- for (uint32_t i = 0; i < CC; i++)
+ for (uint32_t i = 0; i < CC; i++) {
dst_data[i] = pixel[i] / weight; // Normalize the sum of all the samples
+ }
}
}
@@ -814,28 +859,27 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
float *kernel = memnew_arr(float, half_kernel * 2);
for (int32_t dst_y = 0; dst_y < dst_height; dst_y++) {
-
float buffer_y = (dst_y + 0.5f) * y_scale;
int32_t start_y = MAX(0, int32_t(buffer_y) - half_kernel + 1);
int32_t end_y = MIN(src_height - 1, int32_t(buffer_y) + half_kernel);
- for (int32_t target_y = start_y; target_y <= end_y; target_y++)
+ for (int32_t target_y = start_y; target_y <= end_y; target_y++) {
kernel[target_y - start_y] = _lanczos((target_y + 0.5f - buffer_y) / scale_factor);
+ }
for (int32_t dst_x = 0; dst_x < dst_width; dst_x++) {
-
float pixel[CC] = { 0 };
float weight = 0;
for (int32_t target_y = start_y; target_y <= end_y; target_y++) {
-
float lanczos_val = kernel[target_y - start_y];
weight += lanczos_val;
float *buffer_data = ((float *)buffer) + (target_y * dst_width + dst_x) * CC;
- for (uint32_t i = 0; i < CC; i++)
+ for (uint32_t i = 0; i < CC; i++) {
pixel[i] += buffer_data[i] * lanczos_val;
+ }
}
T *dst_data = ((T *)p_dst) + (dst_y * dst_width + dst_x) * CC;
@@ -843,12 +887,13 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
for (uint32_t i = 0; i < CC; i++) {
pixel[i] /= weight;
- if (sizeof(T) == 1) //byte
+ if (sizeof(T) == 1) { //byte
dst_data[i] = CLAMP(Math::fast_ftoi(pixel[i]), 0, 255);
- else if (sizeof(T) == 2) //half float
+ } else if (sizeof(T) == 2) { //half float
dst_data[i] = Math::make_half_float(pixel[i]);
- else // float
+ } else { // float
dst_data[i] = pixel[i];
+ }
}
}
}
@@ -860,11 +905,9 @@ static void _scale_lanczos(const uint8_t *__restrict p_src, uint8_t *__restrict
}
static void _overlay(const uint8_t *__restrict p_src, uint8_t *__restrict p_dst, float p_alpha, uint32_t p_width, uint32_t p_height, uint32_t p_pixel_size) {
-
uint16_t alpha = MIN((uint16_t)(p_alpha * 256.0f), 256);
for (uint32_t i = 0; i < p_width * p_height * p_pixel_size; i++) {
-
p_dst[i] = (p_dst[i] * (256 - alpha) + p_src[i] * alpha) >> 8;
}
}
@@ -874,23 +917,24 @@ bool Image::is_size_po2() const {
}
void Image::resize_to_po2(bool p_square) {
-
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats.");
int w = next_power_of_2(width);
int h = next_power_of_2(height);
+ if (p_square) {
+ w = h = MAX(w, h);
+ }
if (w == width && h == height) {
-
- if (!p_square || w == h)
+ if (!p_square || w == h) {
return; //nothing to do
+ }
}
resize(w, h);
}
void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
-
ERR_FAIL_COND_MSG(data.size() == 0, "Cannot resize image before creating it, use create() or create_from_data() first.");
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot resize in compressed or custom image formats.");
@@ -902,10 +946,11 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, "Image height cannot be greater than " + itos(MAX_HEIGHT) + ".");
ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, "Too many pixels for image, maximum is " + itos(MAX_PIXELS));
- if (p_width == width && p_height == height)
+ if (p_width == width && p_height == height) {
return;
+ }
- Image dst(p_width, p_height, 0, format);
+ Image dst(p_width, p_height, false, format);
// Setup mipmap-aware scaling
Image dst2;
@@ -925,7 +970,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
}
bool interpolate_mipmaps = mipmap_aware && mip1 != mip2;
if (interpolate_mipmaps) {
- dst2.create(p_width, p_height, 0, format);
+ dst2.create(p_width, p_height, false, format);
}
bool had_mipmaps = mipmaps;
@@ -941,37 +986,58 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
unsigned char *w_ptr = w;
switch (p_interpolation) {
-
case INTERPOLATE_NEAREST: {
-
if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
switch (get_format_pixel_size(format)) {
- case 1: _scale_nearest<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 2: _scale_nearest<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 3: _scale_nearest<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_nearest<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 1:
+ _scale_nearest<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 2:
+ _scale_nearest<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 3:
+ _scale_nearest<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_nearest<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
switch (get_format_pixel_size(format)) {
- case 4: _scale_nearest<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_nearest<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 12: _scale_nearest<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 16: _scale_nearest<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 4:
+ _scale_nearest<1, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_nearest<2, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 12:
+ _scale_nearest<3, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 16:
+ _scale_nearest<4, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
switch (get_format_pixel_size(format)) {
- case 2: _scale_nearest<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_nearest<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 6: _scale_nearest<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_nearest<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 2:
+ _scale_nearest<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_nearest<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 6:
+ _scale_nearest<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_nearest<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
}
} break;
case INTERPOLATE_BILINEAR:
case INTERPOLATE_TRILINEAR: {
-
for (int i = 0; i < 2; ++i) {
int src_width;
int src_height;
@@ -1010,24 +1076,48 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
switch (get_format_pixel_size(format)) {
- case 1: _scale_bilinear<1, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 2: _scale_bilinear<2, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 3: _scale_bilinear<3, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 4: _scale_bilinear<4, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
+ case 1:
+ _scale_bilinear<1, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 2:
+ _scale_bilinear<2, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 3:
+ _scale_bilinear<3, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 4:
+ _scale_bilinear<4, uint8_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
switch (get_format_pixel_size(format)) {
- case 4: _scale_bilinear<1, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 8: _scale_bilinear<2, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 12: _scale_bilinear<3, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 16: _scale_bilinear<4, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
+ case 4:
+ _scale_bilinear<1, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 8:
+ _scale_bilinear<2, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 12:
+ _scale_bilinear<3, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 16:
+ _scale_bilinear<4, float>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
switch (get_format_pixel_size(format)) {
- case 2: _scale_bilinear<1, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 4: _scale_bilinear<2, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 6: _scale_bilinear<3, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
- case 8: _scale_bilinear<4, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height); break;
+ case 2:
+ _scale_bilinear<1, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 4:
+ _scale_bilinear<2, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 6:
+ _scale_bilinear<3, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
+ case 8:
+ _scale_bilinear<4, uint16_t>(src_ptr, w_ptr, src_width, src_height, p_width, p_height);
+ break;
}
}
}
@@ -1040,52 +1130,98 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
} break;
case INTERPOLATE_CUBIC: {
-
if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
switch (get_format_pixel_size(format)) {
- case 1: _scale_cubic<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 2: _scale_cubic<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 3: _scale_cubic<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_cubic<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 1:
+ _scale_cubic<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 2:
+ _scale_cubic<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 3:
+ _scale_cubic<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_cubic<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
switch (get_format_pixel_size(format)) {
- case 4: _scale_cubic<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_cubic<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 12: _scale_cubic<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 16: _scale_cubic<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 4:
+ _scale_cubic<1, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_cubic<2, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 12:
+ _scale_cubic<3, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 16:
+ _scale_cubic<4, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
switch (get_format_pixel_size(format)) {
- case 2: _scale_cubic<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_cubic<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 6: _scale_cubic<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_cubic<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 2:
+ _scale_cubic<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_cubic<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 6:
+ _scale_cubic<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_cubic<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
}
} break;
case INTERPOLATE_LANCZOS: {
-
if (format >= FORMAT_L8 && format <= FORMAT_RGBA8) {
switch (get_format_pixel_size(format)) {
- case 1: _scale_lanczos<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 2: _scale_lanczos<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 3: _scale_lanczos<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_lanczos<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 1:
+ _scale_lanczos<1, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 2:
+ _scale_lanczos<2, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 3:
+ _scale_lanczos<3, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_lanczos<4, uint8_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RF && format <= FORMAT_RGBAF) {
switch (get_format_pixel_size(format)) {
- case 4: _scale_lanczos<1, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_lanczos<2, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 12: _scale_lanczos<3, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 16: _scale_lanczos<4, float>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 4:
+ _scale_lanczos<1, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_lanczos<2, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 12:
+ _scale_lanczos<3, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 16:
+ _scale_lanczos<4, float>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
} else if (format >= FORMAT_RH && format <= FORMAT_RGBAH) {
switch (get_format_pixel_size(format)) {
- case 2: _scale_lanczos<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 4: _scale_lanczos<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 6: _scale_lanczos<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
- case 8: _scale_lanczos<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height); break;
+ case 2:
+ _scale_lanczos<1, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 4:
+ _scale_lanczos<2, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 6:
+ _scale_lanczos<3, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
+ case 8:
+ _scale_lanczos<4, uint16_t>(r_ptr, w_ptr, width, height, p_width, p_height);
+ break;
}
}
} break;
@@ -1095,14 +1231,14 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
dst._copy_internals_from(dst2);
}
- if (had_mipmaps)
+ if (had_mipmaps) {
dst.generate_mipmaps();
+ }
_copy_internals_from(dst);
}
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(p_x < 0, "Start x position cannot be smaller than 0.");
@@ -1116,13 +1252,14 @@ void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
will most likely either not be used much, or in critical areas, for now it won't, because
it's a waste of time. */
- if (p_width == width && p_height == height && p_x == 0 && p_y == 0)
+ if (p_width == width && p_height == height && p_x == 0 && p_y == 0) {
return;
+ }
uint8_t pdata[16]; //largest is 16
uint32_t pixel_size = get_format_pixel_size(format);
- Image dst(p_width, p_height, 0, format);
+ Image dst(p_width, p_height, false, format);
{
const uint8_t *r = data.ptr();
@@ -1131,12 +1268,11 @@ void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
int m_h = p_y + p_height;
int m_w = p_x + p_width;
for (int y = p_y; y < m_h; y++) {
-
for (int x = p_x; x < m_w; x++) {
-
if ((x >= width || y >= height)) {
- for (uint32_t i = 0; i < pixel_size; i++)
+ for (uint32_t i = 0; i < pixel_size; i++) {
pdata[i] = 0;
+ }
} else {
_get_pixelb(x, y, pixel_size, r, pdata);
}
@@ -1146,18 +1282,17 @@ void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) {
}
}
- if (has_mipmaps())
+ if (has_mipmaps()) {
dst.generate_mipmaps();
+ }
_copy_internals_from(dst);
}
void Image::crop(int p_width, int p_height) {
-
crop_from_point(0, 0, p_width, p_height);
}
void Image::flip_y() {
-
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_y in compressed or custom image formats.");
bool used_mipmaps = has_mipmaps();
@@ -1172,9 +1307,7 @@ void Image::flip_y() {
uint32_t pixel_size = get_format_pixel_size(format);
for (int y = 0; y < height / 2; y++) {
-
for (int x = 0; x < width; x++) {
-
_get_pixelb(x, y, pixel_size, w, up);
_get_pixelb(x, height - y - 1, pixel_size, w, down);
@@ -1190,7 +1323,6 @@ void Image::flip_y() {
}
void Image::flip_x() {
-
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_x in compressed or custom image formats.");
bool used_mipmaps = has_mipmaps();
@@ -1205,9 +1337,7 @@ void Image::flip_x() {
uint32_t pixel_size = get_format_pixel_size(format);
for (int y = 0; y < height; y++) {
-
for (int x = 0; x < width / 2; x++) {
-
_get_pixelb(x, y, pixel_size, w, up);
_get_pixelb(width - x - 1, y, pixel_size, w, down);
@@ -1223,7 +1353,6 @@ void Image::flip_x() {
}
int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps, int *r_mm_width, int *r_mm_height) {
-
int size = 0;
int w = p_width;
int h = p_height;
@@ -1238,7 +1367,6 @@ int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &
int minw = 1, minh = 1;
while (true) {
-
int bw = w % block != 0 ? w + (block - w % block) : w;
int bh = h % block != 0 ? h + (block - h % block) : h;
@@ -1256,28 +1384,28 @@ int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &
*r_mm_height = bh;
}
- if (p_mipmaps >= 0 && mm == p_mipmaps)
+ if (p_mipmaps >= 0 && mm == p_mipmaps) {
break;
+ }
if (p_mipmaps >= 0) {
-
w = MAX(minw, w >> 1);
h = MAX(minh, h >> 1);
} else {
- if (w == minw && h == minh)
+ if (w == minw && h == minh) {
break;
+ }
w = MAX(minw, w >> 1);
h = MAX(minh, h >> 1);
}
mm++;
- };
+ }
r_mipmaps = mm;
return size;
}
bool Image::_can_modify(Format p_format) const {
-
return p_format <= FORMAT_RGBE9995;
}
@@ -1285,7 +1413,6 @@ template <class Component, int CC, bool renormalize,
void (*average_func)(Component &, const Component &, const Component &, const Component &, const Component &),
void (*renormalize_func)(Component *)>
static void _generate_po2_mipmap(const Component *p_src, Component *p_dst, uint32_t p_width, uint32_t p_height) {
-
//fast power of 2 mipmap generation
uint32_t dst_w = MAX(p_width >> 1, 1);
uint32_t dst_h = MAX(p_height >> 1, 1);
@@ -1294,7 +1421,6 @@ static void _generate_po2_mipmap(const Component *p_src, Component *p_dst, uint3
int down_step = (p_height == 1) ? 0 : (p_width * CC);
for (uint32_t i = 0; i < dst_h; i++) {
-
const Component *rup_ptr = &p_src[i * 2 * down_step];
const Component *rdown_ptr = rup_ptr + down_step;
Component *dst_ptr = &p_dst[i * dst_w * CC];
@@ -1317,52 +1443,10 @@ static void _generate_po2_mipmap(const Component *p_src, Component *p_dst, uint3
}
}
-void Image::expand_x2_hq2x() {
-
- ERR_FAIL_COND(!_can_modify(format));
-
- bool used_mipmaps = has_mipmaps();
- if (used_mipmaps) {
- clear_mipmaps();
- }
-
- Format current = format;
-
- if (current != FORMAT_RGBA8)
- convert(FORMAT_RGBA8);
-
- Vector<uint8_t> dest;
- dest.resize(width * 2 * height * 2 * 4);
-
- {
- const uint8_t *r = data.ptr();
- uint8_t *w = dest.ptrw();
-
- ERR_FAIL_COND(!r);
-
- hq2x_resize((const uint32_t *)r, width, height, (uint32_t *)w);
- }
-
- width *= 2;
- height *= 2;
- data = dest;
-
- if (current != FORMAT_RGBA8)
- convert(current);
-
- // FIXME: This is likely meant to use "used_mipmaps" as defined above, but if we do,
- // we end up with a regression: GH-22747
- if (mipmaps) {
- generate_mipmaps();
- }
-}
-
void Image::shrink_x2() {
-
ERR_FAIL_COND(data.size() == 0);
if (mipmaps) {
-
//just use the lower mipmap as base and copy all
Vector<uint8_t> new_img;
@@ -1384,7 +1468,6 @@ void Image::shrink_x2() {
data = new_img;
} else {
-
Vector<uint8_t> new_img;
ERR_FAIL_COND(!_can_modify(format));
@@ -1398,25 +1481,52 @@ void Image::shrink_x2() {
const uint8_t *r = data.ptr();
switch (format) {
-
case FORMAT_L8:
- case FORMAT_R8: _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
- case FORMAT_LA8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
- case FORMAT_RG8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
- case FORMAT_RGB8: _generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
- case FORMAT_RGBA8: _generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height); break;
-
- case FORMAT_RF: _generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
- case FORMAT_RGF: _generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
- case FORMAT_RGBF: _generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
- case FORMAT_RGBAF: _generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height); break;
-
- case FORMAT_RH: _generate_po2_mipmap<uint16_t, 1, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
- case FORMAT_RGH: _generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
- case FORMAT_RGBH: _generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
- case FORMAT_RGBAH: _generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height); break;
-
- case FORMAT_RGBE9995: _generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(r), reinterpret_cast<uint32_t *>(w), width, height); break;
+ case FORMAT_R8:
+ _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height);
+ break;
+ case FORMAT_LA8:
+ _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height);
+ break;
+ case FORMAT_RG8:
+ _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height);
+ break;
+ case FORMAT_RGB8:
+ _generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height);
+ break;
+ case FORMAT_RGBA8:
+ _generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(r, w, width, height);
+ break;
+
+ case FORMAT_RF:
+ _generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height);
+ break;
+ case FORMAT_RGF:
+ _generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height);
+ break;
+ case FORMAT_RGBF:
+ _generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height);
+ break;
+ case FORMAT_RGBAF:
+ _generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(r), reinterpret_cast<float *>(w), width, height);
+ break;
+
+ case FORMAT_RH:
+ _generate_po2_mipmap<uint16_t, 1, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height);
+ break;
+ case FORMAT_RGH:
+ _generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height);
+ break;
+ case FORMAT_RGBH:
+ _generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height);
+ break;
+ case FORMAT_RGBAH:
+ _generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(r), reinterpret_cast<uint16_t *>(w), width, height);
+ break;
+
+ case FORMAT_RGBE9995:
+ _generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(r), reinterpret_cast<uint32_t *>(w), width, height);
+ break;
default: {
}
}
@@ -1429,16 +1539,13 @@ void Image::shrink_x2() {
}
void Image::normalize() {
-
bool used_mipmaps = has_mipmaps();
if (used_mipmaps) {
clear_mipmaps();
}
for (int y = 0; y < height; y++) {
-
for (int x = 0; x < width; x++) {
-
Color c = get_pixel(x, y);
Vector3 v(c.r * 2.0 - 1.0, c.g * 2.0 - 1.0, c.b * 2.0 - 1.0);
v.normalize();
@@ -1455,7 +1562,6 @@ 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(format == FORMAT_RGBA4444, ERR_UNAVAILABLE, "Cannot generate mipmaps from RGBA4444 format.");
@@ -1475,28 +1581,32 @@ Error Image::generate_mipmaps(bool p_renormalize) {
int prev_w = width;
for (int i = 1; i <= mmcount; i++) {
-
int ofs, w, h;
_get_mipmap_offset_and_size(i, ofs, w, h);
switch (format) {
-
case FORMAT_L8:
- case FORMAT_R8: _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); break;
+ case FORMAT_R8:
+ _generate_po2_mipmap<uint8_t, 1, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
+ break;
case FORMAT_LA8:
- case FORMAT_RG8: _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h); break;
+ case FORMAT_RG8:
+ _generate_po2_mipmap<uint8_t, 2, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
+ break;
case FORMAT_RGB8:
- if (p_renormalize)
+ if (p_renormalize) {
_generate_po2_mipmap<uint8_t, 3, true, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
- else
+ } else {
_generate_po2_mipmap<uint8_t, 3, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
+ }
break;
case FORMAT_RGBA8:
- if (p_renormalize)
+ if (p_renormalize) {
_generate_po2_mipmap<uint8_t, 4, true, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
- else
+ } else {
_generate_po2_mipmap<uint8_t, 4, false, Image::average_4_uint8, Image::renormalize_uint8>(&wp[prev_ofs], &wp[ofs], prev_w, prev_h);
+ }
break;
case FORMAT_RF:
_generate_po2_mipmap<float, 1, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
@@ -1505,17 +1615,19 @@ Error Image::generate_mipmaps(bool p_renormalize) {
_generate_po2_mipmap<float, 2, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
break;
case FORMAT_RGBF:
- if (p_renormalize)
+ if (p_renormalize) {
_generate_po2_mipmap<float, 3, true, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
- else
+ } else {
_generate_po2_mipmap<float, 3, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
+ }
break;
case FORMAT_RGBAF:
- if (p_renormalize)
+ if (p_renormalize) {
_generate_po2_mipmap<float, 4, true, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
- else
+ } else {
_generate_po2_mipmap<float, 4, false, Image::average_4_float, Image::renormalize_float>(reinterpret_cast<const float *>(&wp[prev_ofs]), reinterpret_cast<float *>(&wp[ofs]), prev_w, prev_h);
+ }
break;
case FORMAT_RH:
@@ -1525,24 +1637,27 @@ Error Image::generate_mipmaps(bool p_renormalize) {
_generate_po2_mipmap<uint16_t, 2, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
break;
case FORMAT_RGBH:
- if (p_renormalize)
+ if (p_renormalize) {
_generate_po2_mipmap<uint16_t, 3, true, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
- else
+ } else {
_generate_po2_mipmap<uint16_t, 3, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
+ }
break;
case FORMAT_RGBAH:
- if (p_renormalize)
+ if (p_renormalize) {
_generate_po2_mipmap<uint16_t, 4, true, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
- else
+ } else {
_generate_po2_mipmap<uint16_t, 4, false, Image::average_4_half, Image::renormalize_half>(reinterpret_cast<const uint16_t *>(&wp[prev_ofs]), reinterpret_cast<uint16_t *>(&wp[ofs]), prev_w, prev_h);
+ }
break;
case FORMAT_RGBE9995:
- if (p_renormalize)
+ if (p_renormalize) {
_generate_po2_mipmap<uint32_t, 1, true, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(&wp[prev_ofs]), reinterpret_cast<uint32_t *>(&wp[ofs]), prev_w, prev_h);
- else
+ } else {
_generate_po2_mipmap<uint32_t, 1, false, Image::average_4_rgbe9995, Image::renormalize_rgbe9995>(reinterpret_cast<const uint32_t *>(&wp[prev_ofs]), reinterpret_cast<uint32_t *>(&wp[ofs]), prev_w, prev_h);
+ }
break;
default: {
@@ -1560,7 +1675,6 @@ Error Image::generate_mipmaps(bool p_renormalize) {
}
Error Image::generate_mipmap_roughness(RoughnessChannel p_roughness_channel, const Ref<Image> &p_normal_map) {
-
Vector<double> normal_sat_vec; //summed area table
double *normal_sat = nullptr; //summed area table for normalmap
int normal_w = 0, normal_h = 0;
@@ -1625,7 +1739,6 @@ Error Image::generate_mipmap_roughness(RoughnessChannel p_roughness_channel, con
uint8_t *base_ptr = data.ptrw();
for (int i = 1; i <= mmcount; i++) {
-
int ofs, w, h;
_get_mipmap_offset_and_size(i, ofs, w, h);
uint8_t *ptr = &base_ptr[ofs];
@@ -1756,12 +1869,13 @@ Error Image::generate_mipmap_roughness(RoughnessChannel p_roughness_channel, con
}
void Image::clear_mipmaps() {
-
- if (!mipmaps)
+ if (!mipmaps) {
return;
+ }
- if (empty())
+ if (empty()) {
return;
+ }
int ofs, w, h;
_get_mipmap_offset_and_size(1, ofs, w, h);
@@ -1771,17 +1885,14 @@ void Image::clear_mipmaps() {
}
bool Image::empty() const {
-
return (data.size() == 0);
}
Vector<uint8_t> Image::get_data() const {
-
return data;
}
void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
-
ERR_FAIL_INDEX(p_width - 1, MAX_WIDTH);
ERR_FAIL_INDEX(p_height - 1, MAX_HEIGHT);
ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, "Too many pixels for image, maximum is " + itos(MAX_PIXELS));
@@ -1802,7 +1913,6 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma
}
void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
-
ERR_FAIL_INDEX(p_width - 1, MAX_WIDTH);
ERR_FAIL_INDEX(p_height - 1, MAX_HEIGHT);
ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, "Too many pixels for image, maximum is " + itos(MAX_PIXELS));
@@ -1821,7 +1931,6 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_forma
}
void Image::create(const char **p_xpm) {
-
int size_width = 0;
int size_height = 0;
int pixelchars = 0;
@@ -1841,16 +1950,13 @@ void Image::create(const char **p_xpm) {
HashMap<String, Color> colormap;
int colormap_size = 0;
uint32_t pixel_size = 0;
- uint8_t *w;
+ uint8_t *data_write = nullptr;
while (status != DONE) {
-
const char *line_ptr = p_xpm[line];
switch (status) {
-
case READING_HEADER: {
-
String line_str = line_ptr;
line_str.replace("\t", " ");
@@ -1865,25 +1971,24 @@ void Image::create(const char **p_xpm) {
status = READING_COLORS;
} break;
case READING_COLORS: {
-
String colorstring;
for (int i = 0; i < pixelchars; i++) {
-
colorstring += *line_ptr;
line_ptr++;
}
//skip spaces
while (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == 0) {
- if (*line_ptr == 0)
+ if (*line_ptr == 0) {
break;
+ }
line_ptr++;
}
if (*line_ptr == 'c') {
-
line_ptr++;
while (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == 0) {
- if (*line_ptr == 0)
+ if (*line_ptr == 0) {
break;
+ }
line_ptr++;
}
@@ -1895,55 +2000,63 @@ void Image::create(const char **p_xpm) {
//uint8_t col_a=255;
for (int i = 0; i < 6; i++) {
-
char v = line_ptr[i];
- if (v >= '0' && v <= '9')
+ if (v >= '0' && v <= '9') {
v -= '0';
- else if (v >= 'A' && v <= 'F')
+ } else if (v >= 'A' && v <= 'F') {
v = (v - 'A') + 10;
- else if (v >= 'a' && v <= 'f')
+ } else if (v >= 'a' && v <= 'f') {
v = (v - 'a') + 10;
- else
+ } else {
break;
+ }
switch (i) {
- case 0: col_r = v << 4; break;
- case 1: col_r |= v; break;
- case 2: col_g = v << 4; break;
- case 3: col_g |= v; break;
- case 4: col_b = v << 4; break;
- case 5: col_b |= v; break;
- };
+ case 0:
+ col_r = v << 4;
+ break;
+ case 1:
+ col_r |= v;
+ break;
+ case 2:
+ col_g = v << 4;
+ break;
+ case 3:
+ col_g |= v;
+ break;
+ case 4:
+ col_b = v << 4;
+ break;
+ case 5:
+ col_b |= v;
+ break;
+ }
}
// magenta mask
if (col_r == 255 && col_g == 0 && col_b == 255) {
-
colormap[colorstring] = Color(0, 0, 0, 0);
has_alpha = true;
} else {
-
colormap[colorstring] = Color(col_r / 255.0, col_g / 255.0, col_b / 255.0, 1.0);
}
}
}
if (line == colormap_size) {
-
status = READING_PIXELS;
- create(size_width, size_height, 0, has_alpha ? FORMAT_RGBA8 : FORMAT_RGB8);
- w = data.ptrw();
+ create(size_width, size_height, false, has_alpha ? FORMAT_RGBA8 : FORMAT_RGB8);
+ data_write = data.ptrw();
pixel_size = has_alpha ? 4 : 3;
}
} break;
case READING_PIXELS: {
-
int y = line - colormap_size - 1;
for (int x = 0; x < size_width; x++) {
-
char pixelstr[6] = { 0, 0, 0, 0, 0, 0 };
- for (int i = 0; i < pixelchars; i++)
+ for (int i = 0; i < pixelchars; i++) {
pixelstr[i] = line_ptr[x * pixelchars + i];
+ }
Color *colorptr = colormap.getptr(pixelstr);
ERR_FAIL_COND(!colorptr);
@@ -1951,11 +2064,12 @@ void Image::create(const char **p_xpm) {
for (uint32_t i = 0; i < pixel_size; i++) {
pixel[i] = CLAMP((*colorptr)[i] * 255, 0, 255);
}
- _put_pixelb(x, y, pixel_size, w, pixel);
+ _put_pixelb(x, y, pixel_size, data_write, pixel);
}
- if (y == (size_height - 1))
+ if (y == (size_height - 1)) {
status = DONE;
+ }
} break;
default: {
}
@@ -1973,7 +2087,6 @@ void Image::create(const char **p_xpm) {
if (value < DETECT_ALPHA_MIN_THRESHOLD) \
bit = true; \
else if (value < DETECT_ALPHA_MAX_THRESHOLD) { \
- \
detected = true; \
break; \
} \
@@ -1983,22 +2096,22 @@ void Image::create(const char **p_xpm) {
{ \
uint8_t value = m_value; \
if (value > 0) { \
- \
detected = true; \
break; \
} \
}
bool Image::is_invisible() const {
-
if (format == FORMAT_L8 ||
- format == FORMAT_RGB8 || format == FORMAT_RG8)
+ format == FORMAT_RGB8 || format == FORMAT_RG8) {
return false;
+ }
int len = data.size();
- if (len == 0)
+ if (len == 0) {
return true;
+ }
int w, h;
_get_mipmap_offset_and_size(1, len, w, h);
@@ -2009,16 +2122,13 @@ bool Image::is_invisible() const {
bool detected = false;
switch (format) {
-
case FORMAT_LA8: {
-
for (int i = 0; i < (len >> 1); i++) {
DETECT_NON_ALPHA(data_ptr[(i << 1) + 1]);
}
} break;
case FORMAT_RGBA8: {
-
for (int i = 0; i < (len >> 2); i++) {
DETECT_NON_ALPHA(data_ptr[(i << 2) + 3])
}
@@ -2039,11 +2149,11 @@ bool Image::is_invisible() const {
}
Image::AlphaMode Image::detect_alpha() const {
-
int len = data.size();
- if (len == 0)
+ if (len == 0) {
return ALPHA_NONE;
+ }
int w, h;
_get_mipmap_offset_and_size(1, len, w, h);
@@ -2055,16 +2165,13 @@ Image::AlphaMode Image::detect_alpha() const {
bool detected = false;
switch (format) {
-
case FORMAT_LA8: {
-
for (int i = 0; i < (len >> 1); i++) {
DETECT_ALPHA(data_ptr[(i << 1) + 1]);
}
} break;
case FORMAT_RGBA8: {
-
for (int i = 0; i < (len >> 2); i++) {
DETECT_ALPHA(data_ptr[(i << 2) + 3])
}
@@ -2080,12 +2187,13 @@ Image::AlphaMode Image::detect_alpha() const {
}
}
- if (detected)
+ if (detected) {
return ALPHA_BLEND;
- else if (bit)
+ } else if (bit) {
return ALPHA_BIT;
- else
+ } else {
return ALPHA_NONE;
+ }
}
Error Image::load(const String &p_path) {
@@ -2098,9 +2206,9 @@ Error Image::load(const String &p_path) {
}
Error Image::save_png(const String &p_path) const {
-
- if (save_png_func == nullptr)
+ if (save_png_func == nullptr) {
return ERR_UNAVAILABLE;
+ }
return save_png_func(p_path, Ref<Image>((Image *)this));
}
@@ -2114,21 +2222,19 @@ Vector<uint8_t> Image::save_png_to_buffer() const {
}
Error Image::save_exr(const String &p_path, bool p_grayscale) const {
-
- if (save_exr_func == nullptr)
+ if (save_exr_func == nullptr) {
return ERR_UNAVAILABLE;
+ }
return save_exr_func(p_path, Ref<Image>((Image *)this), p_grayscale);
}
int Image::get_image_data_size(int p_width, int p_height, Format p_format, bool p_mipmaps) {
-
int mm;
return _get_dst_image_size(p_width, p_height, p_format, mm, p_mipmaps ? -1 : 0);
}
int Image::get_image_required_mipmaps(int p_width, int p_height, Format p_format) {
-
int mm;
_get_dst_image_size(p_width, p_height, p_format, mm, -1);
return mm;
@@ -2142,7 +2248,6 @@ Size2i Image::get_image_mipmap_size(int p_width, int p_height, Format p_format,
}
int Image::get_image_mipmap_offset(int p_width, int p_height, Format p_format, int p_mipmap) {
-
if (p_mipmap <= 0) {
return 0;
}
@@ -2151,7 +2256,6 @@ int Image::get_image_mipmap_offset(int p_width, int p_height, Format p_format, i
}
int Image::get_image_mipmap_offset_and_dimensions(int p_width, int p_height, Format p_format, int p_mipmap, int &r_w, int &r_h) {
-
if (p_mipmap <= 0) {
r_w = p_width;
r_h = p_height;
@@ -2166,57 +2270,49 @@ bool Image::is_compressed() const {
}
Error Image::decompress() {
-
- if (((format >= FORMAT_DXT1 && format <= FORMAT_RGTC_RG) || (format == FORMAT_DXT5_RA_AS_RG)) && _image_decompress_bc)
+ if (((format >= FORMAT_DXT1 && format <= FORMAT_RGTC_RG) || (format == FORMAT_DXT5_RA_AS_RG)) && _image_decompress_bc) {
_image_decompress_bc(this);
- else if (format >= FORMAT_BPTC_RGBA && format <= FORMAT_BPTC_RGBFU && _image_decompress_bptc)
+ } else if (format >= FORMAT_BPTC_RGBA && format <= FORMAT_BPTC_RGBFU && _image_decompress_bptc) {
_image_decompress_bptc(this);
- else if (format >= FORMAT_PVRTC2 && format <= FORMAT_PVRTC4A && _image_decompress_pvrtc)
+ } else if (format >= FORMAT_PVRTC2 && format <= FORMAT_PVRTC4A && _image_decompress_pvrtc) {
_image_decompress_pvrtc(this);
- else if (format == FORMAT_ETC && _image_decompress_etc1)
+ } else if (format == FORMAT_ETC && _image_decompress_etc1) {
_image_decompress_etc1(this);
- else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RA_AS_RG && _image_decompress_etc2)
+ } else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RA_AS_RG && _image_decompress_etc2) {
_image_decompress_etc2(this);
- else
+ } else {
return ERR_UNAVAILABLE;
+ }
return OK;
}
Error Image::compress(CompressMode p_mode, CompressSource p_source, float p_lossy_quality) {
-
return compress_from_channels(p_mode, detect_used_channels(p_source), p_lossy_quality);
}
-Error Image::compress_from_channels(CompressMode p_mode, UsedChannels p_channels, float p_lossy_quality) {
+Error Image::compress_from_channels(CompressMode p_mode, UsedChannels p_channels, float p_lossy_quality) {
switch (p_mode) {
-
case COMPRESS_S3TC: {
-
ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE);
_image_compress_bc_func(this, p_lossy_quality, p_channels);
} break;
case COMPRESS_PVRTC2: {
-
ERR_FAIL_COND_V(!_image_compress_pvrtc2_func, ERR_UNAVAILABLE);
_image_compress_pvrtc2_func(this);
} break;
case COMPRESS_PVRTC4: {
-
ERR_FAIL_COND_V(!_image_compress_pvrtc4_func, ERR_UNAVAILABLE);
_image_compress_pvrtc4_func(this);
} break;
case COMPRESS_ETC: {
-
ERR_FAIL_COND_V(!_image_compress_etc1_func, ERR_UNAVAILABLE);
_image_compress_etc1_func(this, p_lossy_quality);
} break;
case COMPRESS_ETC2: {
-
ERR_FAIL_COND_V(!_image_compress_etc2_func, ERR_UNAVAILABLE);
_image_compress_etc2_func(this, p_lossy_quality, p_channels);
} break;
case COMPRESS_BPTC: {
-
ERR_FAIL_COND_V(!_image_compress_bptc_func, ERR_UNAVAILABLE);
_image_compress_bptc_func(this, p_lossy_quality, p_channels);
} break;
@@ -2226,7 +2322,6 @@ Error Image::compress_from_channels(CompressMode p_mode, UsedChannels p_channels
}
Image::Image(const char **p_xpm) {
-
width = 0;
height = 0;
mipmaps = false;
@@ -2236,7 +2331,6 @@ Image::Image(const char **p_xpm) {
}
Image::Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
-
width = 0;
height = 0;
mipmaps = p_use_mipmaps;
@@ -2246,7 +2340,6 @@ Image::Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
}
Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
-
width = 0;
height = 0;
mipmaps = p_mipmaps;
@@ -2256,48 +2349,52 @@ Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const V
}
Rect2 Image::get_used_rect() const {
-
- if (format != FORMAT_LA8 && format != FORMAT_RGBA8 && format != FORMAT_RGBAF && format != FORMAT_RGBAH && format != FORMAT_RGBA4444 && format != FORMAT_RGB565)
+ if (format != FORMAT_LA8 && format != FORMAT_RGBA8 && format != FORMAT_RGBAF && format != FORMAT_RGBAH && format != FORMAT_RGBA4444 && format != FORMAT_RGB565) {
return Rect2(Point2(), Size2(width, height));
+ }
int len = data.size();
- if (len == 0)
+ if (len == 0) {
return Rect2();
+ }
int minx = 0xFFFFFF, miny = 0xFFFFFFF;
int maxx = -1, maxy = -1;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
-
- if (!(get_pixel(i, j).a > 0))
+ if (!(get_pixel(i, j).a > 0)) {
continue;
- if (i > maxx)
+ }
+ if (i > maxx) {
maxx = i;
- if (j > maxy)
+ }
+ if (j > maxy) {
maxy = j;
- if (i < minx)
+ }
+ if (i < minx) {
minx = i;
- if (j < miny)
+ }
+ if (j < miny) {
miny = j;
+ }
}
}
- if (maxx == -1)
+ if (maxx == -1) {
return Rect2();
- else
+ } else {
return Rect2(minx, miny, maxx - minx + 1, maxy - miny + 1);
+ }
}
Ref<Image> Image::get_rect(const Rect2 &p_area) const {
-
Ref<Image> img = memnew(Image(p_area.size.x, p_area.size.y, mipmaps, format));
img->blit_rect(Ref<Image>((Image *)this), p_area, Point2(0, 0));
return img;
}
void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
-
ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
int dsize = data.size();
int srcdsize = p_src->data.size();
@@ -2308,13 +2405,16 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
- if (p_dest.x < 0)
+ if (p_dest.x < 0) {
clipped_src_rect.position.x = ABS(p_dest.x);
- if (p_dest.y < 0)
+ }
+ if (p_dest.y < 0) {
clipped_src_rect.position.y = ABS(p_dest.y);
+ }
- if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
+ if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) {
return;
+ }
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
@@ -2328,9 +2428,7 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
int pixel_size = get_format_pixel_size(format);
for (int i = 0; i < dest_rect.size.y; i++) {
-
for (int j = 0; j < dest_rect.size.x; j++) {
-
int src_x = clipped_src_rect.position.x + j;
int src_y = clipped_src_rect.position.y + i;
@@ -2348,7 +2446,6 @@ void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Po
}
void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) {
-
ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
ERR_FAIL_COND_MSG(p_mask.is_null(), "It's not a reference to a valid Image object.");
int dsize = data.size();
@@ -2363,13 +2460,16 @@ void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, co
Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
- if (p_dest.x < 0)
+ if (p_dest.x < 0) {
clipped_src_rect.position.x = ABS(p_dest.x);
- if (p_dest.y < 0)
+ }
+ if (p_dest.y < 0) {
clipped_src_rect.position.y = ABS(p_dest.y);
+ }
- if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
+ if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) {
return;
+ }
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
@@ -2385,14 +2485,11 @@ void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, co
Ref<Image> msk = p_mask;
for (int i = 0; i < dest_rect.size.y; i++) {
-
for (int j = 0; j < dest_rect.size.x; j++) {
-
int src_x = clipped_src_rect.position.x + j;
int src_y = clipped_src_rect.position.y + i;
if (msk->get_pixel(src_x, src_y).a != 0) {
-
int dst_x = dest_rect.position.x + j;
int dst_y = dest_rect.position.y + i;
@@ -2408,7 +2505,6 @@ void Image::blit_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, co
}
void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
-
ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
int dsize = data.size();
int srcdsize = p_src->data.size();
@@ -2418,13 +2514,16 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P
Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
- if (p_dest.x < 0)
+ if (p_dest.x < 0) {
clipped_src_rect.position.x = ABS(p_dest.x);
- if (p_dest.y < 0)
+ }
+ if (p_dest.y < 0) {
clipped_src_rect.position.y = ABS(p_dest.y);
+ }
- if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
+ if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) {
return;
+ }
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
@@ -2432,9 +2531,7 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P
Ref<Image> img = p_src;
for (int i = 0; i < dest_rect.size.y; i++) {
-
for (int j = 0; j < dest_rect.size.x; j++) {
-
int src_x = clipped_src_rect.position.x + j;
int src_y = clipped_src_rect.position.y + i;
@@ -2453,7 +2550,6 @@ void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const P
}
void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) {
-
ERR_FAIL_COND_MSG(p_src.is_null(), "It's not a reference to a valid Image object.");
ERR_FAIL_COND_MSG(p_mask.is_null(), "It's not a reference to a valid Image object.");
int dsize = data.size();
@@ -2468,13 +2564,16 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c
Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
- if (p_dest.x < 0)
+ if (p_dest.x < 0) {
clipped_src_rect.position.x = ABS(p_dest.x);
- if (p_dest.y < 0)
+ }
+ if (p_dest.y < 0) {
clipped_src_rect.position.y = ABS(p_dest.y);
+ }
- if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
+ if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0) {
return;
+ }
Point2 src_underscan = Point2(MIN(0, p_src_rect.position.x), MIN(0, p_src_rect.position.y));
Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest - src_underscan, clipped_src_rect.size));
@@ -2483,9 +2582,7 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c
Ref<Image> msk = p_mask;
for (int i = 0; i < dest_rect.size.y; i++) {
-
for (int j = 0; j < dest_rect.size.x; j++) {
-
int src_x = clipped_src_rect.position.x + j;
int src_y = clipped_src_rect.position.y + i;
@@ -2493,7 +2590,6 @@ void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, c
//Color c = msk->get_pixel(src_x, src_y);
//if (c.a == 0) continue;
if (msk->get_pixel(src_x, src_y).a != 0) {
-
int dst_x = dest_rect.position.x + j;
int dst_y = dest_rect.position.y + i;
@@ -2521,9 +2617,7 @@ void Image::fill(const Color &c) {
set_pixel(0, 0, c);
for (int y = 0; y < height; y++) {
-
for (int x = 0; x < width; x++) {
-
uint8_t *dst = &dst_data_ptr[(y * width + x) * pixel_size];
for (int k = 0; k < pixel_size; k++) {
@@ -2557,7 +2651,6 @@ Vector<uint8_t> (*Image::basis_universal_packer)(const Ref<Image> &, Image::Used
Ref<Image> (*Image::basis_universal_unpacker)(const Vector<uint8_t> &) = nullptr;
void Image::_set_data(const Dictionary &p_data) {
-
ERR_FAIL_COND(!p_data.has("width"));
ERR_FAIL_COND(!p_data.has("height"));
ERR_FAIL_COND(!p_data.has("format"));
@@ -2583,7 +2676,6 @@ void Image::_set_data(const Dictionary &p_data) {
}
Dictionary Image::_get_data() const {
-
Dictionary d;
d["width"] = width;
d["height"] = height;
@@ -2598,7 +2690,6 @@ Color Image::get_pixelv(const Point2 &p_src) const {
}
Color Image::_get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const {
-
switch (format) {
case FORMAT_L8: {
float l = ptr[ofs] / 255.0;
@@ -2610,12 +2701,10 @@ Color Image::_get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const {
return Color(l, l, l, a);
}
case FORMAT_R8: {
-
float r = ptr[ofs] / 255.0;
return Color(r, 0, 0, 1);
}
case FORMAT_RG8: {
-
float r = ptr[ofs * 2 + 0] / 255.0;
float g = ptr[ofs * 2 + 1] / 255.0;
return Color(r, g, 0, 1);
@@ -2642,7 +2731,6 @@ Color Image::_get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const {
return Color(r, g, b, a);
}
case FORMAT_RGB565: {
-
uint16_t u = ((uint16_t *)ptr)[ofs];
float r = (u & 0x1F) / 31.0;
float g = ((u >> 5) & 0x3F) / 63.0;
@@ -2650,25 +2738,21 @@ Color Image::_get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const {
return Color(r, g, b, 1.0);
}
case FORMAT_RF: {
-
float r = ((float *)ptr)[ofs];
return Color(r, 0, 0, 1);
}
case FORMAT_RGF: {
-
float r = ((float *)ptr)[ofs * 2 + 0];
float g = ((float *)ptr)[ofs * 2 + 1];
return Color(r, g, 0, 1);
}
case FORMAT_RGBF: {
-
float r = ((float *)ptr)[ofs * 3 + 0];
float g = ((float *)ptr)[ofs * 3 + 1];
float b = ((float *)ptr)[ofs * 3 + 2];
return Color(r, g, b, 1);
}
case FORMAT_RGBAF: {
-
float r = ((float *)ptr)[ofs * 4 + 0];
float g = ((float *)ptr)[ofs * 4 + 1];
float b = ((float *)ptr)[ofs * 4 + 2];
@@ -2676,25 +2760,21 @@ Color Image::_get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const {
return Color(r, g, b, a);
}
case FORMAT_RH: {
-
uint16_t r = ((uint16_t *)ptr)[ofs];
return Color(Math::half_to_float(r), 0, 0, 1);
}
case FORMAT_RGH: {
-
uint16_t r = ((uint16_t *)ptr)[ofs * 2 + 0];
uint16_t g = ((uint16_t *)ptr)[ofs * 2 + 1];
return Color(Math::half_to_float(r), Math::half_to_float(g), 0, 1);
}
case FORMAT_RGBH: {
-
uint16_t r = ((uint16_t *)ptr)[ofs * 3 + 0];
uint16_t g = ((uint16_t *)ptr)[ofs * 3 + 1];
uint16_t b = ((uint16_t *)ptr)[ofs * 3 + 2];
return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), 1);
}
case FORMAT_RGBAH: {
-
uint16_t r = ((uint16_t *)ptr)[ofs * 4 + 0];
uint16_t g = ((uint16_t *)ptr)[ofs * 4 + 1];
uint16_t b = ((uint16_t *)ptr)[ofs * 4 + 2];
@@ -2720,11 +2800,9 @@ void Image::_set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color)
ptr[ofs * 2 + 1] = uint8_t(CLAMP(p_color.a * 255.0, 0, 255));
} break;
case FORMAT_R8: {
-
ptr[ofs] = uint8_t(CLAMP(p_color.r * 255.0, 0, 255));
} break;
case FORMAT_RG8: {
-
ptr[ofs * 2 + 0] = uint8_t(CLAMP(p_color.r * 255.0, 0, 255));
ptr[ofs * 2 + 1] = uint8_t(CLAMP(p_color.g * 255.0, 0, 255));
} break;
@@ -2741,7 +2819,6 @@ void Image::_set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color)
} break;
case FORMAT_RGBA4444: {
-
uint16_t rgba = 0;
rgba = uint16_t(CLAMP(p_color.r * 15.0, 0, 15)) << 12;
@@ -2753,7 +2830,6 @@ void Image::_set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color)
} break;
case FORMAT_RGB565: {
-
uint16_t rgba = 0;
rgba = uint16_t(CLAMP(p_color.r * 31.0, 0, 31));
@@ -2764,51 +2840,42 @@ void Image::_set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color)
} break;
case FORMAT_RF: {
-
((float *)ptr)[ofs] = p_color.r;
} break;
case FORMAT_RGF: {
-
((float *)ptr)[ofs * 2 + 0] = p_color.r;
((float *)ptr)[ofs * 2 + 1] = p_color.g;
} break;
case FORMAT_RGBF: {
-
((float *)ptr)[ofs * 3 + 0] = p_color.r;
((float *)ptr)[ofs * 3 + 1] = p_color.g;
((float *)ptr)[ofs * 3 + 2] = p_color.b;
} break;
case FORMAT_RGBAF: {
-
((float *)ptr)[ofs * 4 + 0] = p_color.r;
((float *)ptr)[ofs * 4 + 1] = p_color.g;
((float *)ptr)[ofs * 4 + 2] = p_color.b;
((float *)ptr)[ofs * 4 + 3] = p_color.a;
} break;
case FORMAT_RH: {
-
((uint16_t *)ptr)[ofs] = Math::make_half_float(p_color.r);
} break;
case FORMAT_RGH: {
-
((uint16_t *)ptr)[ofs * 2 + 0] = Math::make_half_float(p_color.r);
((uint16_t *)ptr)[ofs * 2 + 1] = Math::make_half_float(p_color.g);
} break;
case FORMAT_RGBH: {
-
((uint16_t *)ptr)[ofs * 3 + 0] = Math::make_half_float(p_color.r);
((uint16_t *)ptr)[ofs * 3 + 1] = Math::make_half_float(p_color.g);
((uint16_t *)ptr)[ofs * 3 + 2] = Math::make_half_float(p_color.b);
} break;
case FORMAT_RGBAH: {
-
((uint16_t *)ptr)[ofs * 4 + 0] = Math::make_half_float(p_color.r);
((uint16_t *)ptr)[ofs * 4 + 1] = Math::make_half_float(p_color.g);
((uint16_t *)ptr)[ofs * 4 + 2] = Math::make_half_float(p_color.b);
((uint16_t *)ptr)[ofs * 4 + 3] = Math::make_half_float(p_color.a);
} break;
case FORMAT_RGBE9995: {
-
((uint32_t *)ptr)[ofs] = p_color.to_rgbe9995();
} break;
@@ -2843,24 +2910,26 @@ void Image::set_pixel(int p_x, int p_y, const Color &p_color) {
}
Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
-
ERR_FAIL_COND_V(data.size() == 0, USED_CHANNELS_RGBA);
ERR_FAIL_COND_V(is_compressed(), USED_CHANNELS_RGBA);
bool r = false, g = false, b = false, a = false, c = false;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
-
Color col = get_pixel(i, j);
- if (col.r > 0.001)
+ if (col.r > 0.001) {
r = true;
- if (col.g > 0.001)
+ }
+ if (col.g > 0.001) {
g = true;
- if (col.b > 0.001)
+ }
+ if (col.b > 0.001) {
b = true;
- if (col.a < 0.999)
+ }
+ if (col.a < 0.999) {
a = true;
+ }
if (col.r != col.b || col.r != col.g || col.b != col.g) {
c = true;
@@ -2870,18 +2939,19 @@ Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
UsedChannels used_channels;
- if (!c && !a)
+ if (!c && !a) {
used_channels = USED_CHANNELS_L;
- else if (!c && a)
+ } else if (!c && a) {
used_channels = USED_CHANNELS_LA;
- else if (r && !g && !b && !a)
+ } else if (r && !g && !b && !a) {
used_channels = USED_CHANNELS_R;
- else if (r && g && !b && !a)
+ } else if (r && g && !b && !a) {
used_channels = USED_CHANNELS_RG;
- else if (r && g && b && !a)
+ } else if (r && g && b && !a) {
used_channels = USED_CHANNELS_RGB;
- else
+ } else {
used_channels = USED_CHANNELS_RGBA;
+ }
if (p_source == COMPRESS_SOURCE_SRGB && (used_channels == USED_CHANNELS_R || used_channels == USED_CHANNELS_RG)) {
//R and RG do not support SRGB
@@ -2898,17 +2968,28 @@ Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
void Image::optimize_channels() {
switch (detect_used_channels()) {
- case USED_CHANNELS_L: convert(FORMAT_L8); break;
- case USED_CHANNELS_LA: convert(FORMAT_LA8); break;
- case USED_CHANNELS_R: convert(FORMAT_R8); break;
- case USED_CHANNELS_RG: convert(FORMAT_RG8); break;
- case USED_CHANNELS_RGB: convert(FORMAT_RGB8); break;
- case USED_CHANNELS_RGBA: convert(FORMAT_RGBA8); break;
+ case USED_CHANNELS_L:
+ convert(FORMAT_L8);
+ break;
+ case USED_CHANNELS_LA:
+ convert(FORMAT_LA8);
+ break;
+ case USED_CHANNELS_R:
+ convert(FORMAT_R8);
+ break;
+ case USED_CHANNELS_RG:
+ convert(FORMAT_RG8);
+ break;
+ case USED_CHANNELS_RGB:
+ convert(FORMAT_RGB8);
+ break;
+ case USED_CHANNELS_RGBA:
+ convert(FORMAT_RGBA8);
+ break;
}
}
void Image::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_width"), &Image::get_width);
ClassDB::bind_method(D_METHOD("get_height"), &Image::get_height);
ClassDB::bind_method(D_METHOD("get_size"), &Image::get_size);
@@ -2923,7 +3004,6 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("resize_to_po2", "square"), &Image::resize_to_po2, DEFVAL(false));
ClassDB::bind_method(D_METHOD("resize", "width", "height", "interpolation"), &Image::resize, DEFVAL(INTERPOLATE_BILINEAR));
ClassDB::bind_method(D_METHOD("shrink_x2"), &Image::shrink_x2);
- ClassDB::bind_method(D_METHOD("expand_x2_hq2x"), &Image::expand_x2_hq2x);
ClassDB::bind_method(D_METHOD("crop", "width", "height"), &Image::crop);
ClassDB::bind_method(D_METHOD("flip_x"), &Image::flip_x);
@@ -2938,6 +3018,7 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("load", "path"), &Image::load);
ClassDB::bind_method(D_METHOD("save_png", "path"), &Image::save_png);
+ ClassDB::bind_method(D_METHOD("save_png_to_buffer"), &Image::save_png_to_buffer);
ClassDB::bind_method(D_METHOD("save_exr", "path", "grayscale"), &Image::save_exr, DEFVAL(false));
ClassDB::bind_method(D_METHOD("detect_alpha"), &Image::detect_alpha);
@@ -3054,17 +3135,14 @@ void Image::_bind_methods() {
}
void Image::set_compress_bc_func(void (*p_compress_func)(Image *, float, UsedChannels)) {
-
_image_compress_bc_func = p_compress_func;
}
void Image::set_compress_bptc_func(void (*p_compress_func)(Image *, float, UsedChannels)) {
-
_image_compress_bptc_func = p_compress_func;
}
void Image::normalmap_to_xy() {
-
convert(Image::FORMAT_RGBA8);
{
@@ -3072,7 +3150,6 @@ void Image::normalmap_to_xy() {
uint8_t *data_ptr = data.ptrw();
for (int i = 0; i < len; i++) {
-
data_ptr[(i << 2) + 3] = data_ptr[(i << 2) + 0]; //x to w
data_ptr[(i << 2) + 0] = data_ptr[(i << 2) + 1]; //y to xz
data_ptr[(i << 2) + 2] = data_ptr[(i << 2) + 1];
@@ -3083,15 +3160,15 @@ void Image::normalmap_to_xy() {
}
Ref<Image> Image::rgbe_to_srgb() {
-
- if (data.size() == 0)
+ if (data.size() == 0) {
return Ref<Image>();
+ }
ERR_FAIL_COND_V(format != FORMAT_RGBE9995, Ref<Image>());
Ref<Image> new_image;
new_image.instance();
- new_image->create(width, height, 0, Image::FORMAT_RGB8);
+ new_image->create(width, height, false, Image::FORMAT_RGB8);
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
@@ -3107,7 +3184,6 @@ Ref<Image> Image::rgbe_to_srgb() {
}
Ref<Image> Image::get_image_from_mipmap(int p_mipamp) const {
-
int ofs, size, w, h;
get_mipmap_offset_size_and_dimensions(p_mipamp, ofs, size, w, h);
@@ -3149,11 +3225,15 @@ void Image::bumpmap_to_normalmap(float bump_scale) {
for (int ty = 0; ty < height; ty++) {
int py = ty + 1;
- if (py >= height) py -= height;
+ if (py >= height) {
+ py -= height;
+ }
for (int tx = 0; tx < width; tx++) {
int px = tx + 1;
- if (px >= width) px -= width;
+ if (px >= width) {
+ px -= width;
+ }
float here = read_ptr[ty * width + tx];
float to_right = read_ptr[ty * width + px];
float above = read_ptr[py * width + tx];
@@ -3175,33 +3255,29 @@ void Image::bumpmap_to_normalmap(float bump_scale) {
}
void Image::srgb_to_linear() {
-
- if (data.size() == 0)
+ if (data.size() == 0) {
return;
+ }
static const uint8_t srgb2lin[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 26, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 53, 54, 55, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 85, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 101, 102, 103, 105, 106, 107, 109, 110, 112, 113, 114, 116, 117, 119, 120, 122, 123, 125, 126, 128, 129, 131, 132, 134, 135, 137, 139, 140, 142, 144, 145, 147, 148, 150, 152, 153, 155, 157, 159, 160, 162, 164, 166, 167, 169, 171, 173, 175, 176, 178, 180, 182, 184, 186, 188, 190, 192, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 235, 237, 239, 241, 243, 245, 248, 250, 252, 255 };
ERR_FAIL_COND(format != FORMAT_RGB8 && format != FORMAT_RGBA8);
if (format == FORMAT_RGBA8) {
-
int len = data.size() / 4;
uint8_t *data_ptr = data.ptrw();
for (int i = 0; i < len; i++) {
-
data_ptr[(i << 2) + 0] = srgb2lin[data_ptr[(i << 2) + 0]];
data_ptr[(i << 2) + 1] = srgb2lin[data_ptr[(i << 2) + 1]];
data_ptr[(i << 2) + 2] = srgb2lin[data_ptr[(i << 2) + 2]];
}
} else if (format == FORMAT_RGB8) {
-
int len = data.size() / 3;
uint8_t *data_ptr = data.ptrw();
for (int i = 0; i < len; i++) {
-
data_ptr[(i * 3) + 0] = srgb2lin[data_ptr[(i * 3) + 0]];
data_ptr[(i * 3) + 1] = srgb2lin[data_ptr[(i * 3) + 1]];
data_ptr[(i * 3) + 2] = srgb2lin[data_ptr[(i * 3) + 2]];
@@ -3210,18 +3286,18 @@ void Image::srgb_to_linear() {
}
void Image::premultiply_alpha() {
-
- if (data.size() == 0)
+ if (data.size() == 0) {
return;
+ }
- if (format != FORMAT_RGBA8)
+ if (format != FORMAT_RGBA8) {
return; //not needed
+ }
uint8_t *data_ptr = data.ptrw();
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
-
uint8_t *ptr = &data_ptr[(i * width + j) * 4];
ptr[0] = (uint16_t(ptr[0]) * uint16_t(ptr[3])) >> 8;
@@ -3232,12 +3308,13 @@ void Image::premultiply_alpha() {
}
void Image::fix_alpha_edges() {
-
- if (data.size() == 0)
+ if (data.size() == 0) {
return;
+ }
- if (format != FORMAT_RGBA8)
+ if (format != FORMAT_RGBA8) {
return; //not needed
+ }
Vector<uint8_t> dcopy = data;
const uint8_t *srcptr = dcopy.ptr();
@@ -3250,12 +3327,12 @@ void Image::fix_alpha_edges() {
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
-
const uint8_t *rptr = &srcptr[(i * width + j) * 4];
uint8_t *wptr = &data_ptr[(i * width + j) * 4];
- if (rptr[3] >= alpha_threshold)
+ if (rptr[3] >= alpha_threshold) {
continue;
+ }
int closest_dist = max_dist;
uint8_t closest_color[3];
@@ -3267,17 +3344,18 @@ void Image::fix_alpha_edges() {
for (int k = from_y; k <= to_y; k++) {
for (int l = from_x; l <= to_x; l++) {
-
int dy = i - k;
int dx = j - l;
int dist = dy * dy + dx * dx;
- if (dist >= closest_dist)
+ if (dist >= closest_dist) {
continue;
+ }
const uint8_t *rp2 = &srcptr[(k * width + l) << 2];
- if (rp2[3] < alpha_threshold)
+ if (rp2[3] < alpha_threshold) {
continue;
+ }
closest_dist = dist;
closest_color[0] = rp2[0];
@@ -3287,7 +3365,6 @@ void Image::fix_alpha_edges() {
}
if (closest_dist != max_dist) {
-
wptr[0] = closest_color[0];
wptr[1] = closest_color[1];
wptr[2] = closest_color[2];
@@ -3297,7 +3374,6 @@ void Image::fix_alpha_edges() {
}
String Image::get_format_name(Format p_format) {
-
ERR_FAIL_INDEX_V(p_format, FORMAT_MAX, String());
return format_names[p_format];
}
@@ -3326,6 +3402,7 @@ void Image::convert_rg_to_ra_rgba8() {
w[i + 2] = 0;
}
}
+
void Image::convert_ra_rgba8_to_rg() {
ERR_FAIL_COND(format != FORMAT_RGBA8);
ERR_FAIL_COND(!data.size());
@@ -3405,7 +3482,6 @@ void Image::renormalize_rgbe9995(uint32_t *p_rgb) {
}
Image::Image(const uint8_t *p_mem_png_jpg, int p_len) {
-
width = 0;
height = 0;
mipmaps = false;
@@ -3421,20 +3497,12 @@ Image::Image(const uint8_t *p_mem_png_jpg, int p_len) {
}
Ref<Resource> Image::duplicate(bool p_subresources) const {
-
Ref<Image> copy;
copy.instance();
copy->_copy_internals_from(*this);
return copy;
}
-Image::Image() {
-
- width = 0;
- height = 0;
- mipmaps = false;
- format = FORMAT_L8;
-}
-
-Image::~Image() {
+void Image::set_as_black() {
+ zeromem(data.ptrw(), data.size());
}
diff --git a/core/image.h b/core/image.h
index 5bd73fa677..53c203998e 100644
--- a/core/image.h
+++ b/core/image.h
@@ -33,7 +33,6 @@
#include "core/color.h"
#include "core/math/rect2.h"
-
#include "core/resource.h"
/**
@@ -172,10 +171,11 @@ private:
create(p_width, p_height, p_use_mipmaps, p_format, p_data);
}
- Format format;
+ Format format = FORMAT_L8;
Vector<uint8_t> data;
- int width, height;
- bool mipmaps;
+ int width = 0;
+ int height = 0;
+ bool mipmaps = false;
void _copy_internals_from(const Image &p_image) {
format = p_image.format;
@@ -235,7 +235,6 @@ public:
void resize_to_po2(bool p_square = false);
void resize(int p_width, int p_height, Interpolation p_interpolation = INTERPOLATE_BILINEAR);
void shrink_x2();
- void expand_x2_hq2x();
bool is_size_po2() const;
/**
* Crop the image to a specific size, if larger, then the image is filled by black
@@ -286,7 +285,7 @@ public:
/**
* create an empty image
*/
- Image();
+ Image() {}
/**
* create an empty image of a specific size and format
*/
@@ -296,6 +295,8 @@ public:
*/
Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const Vector<uint8_t> &p_data);
+ ~Image() {}
+
enum AlphaMode {
ALPHA_NONE,
ALPHA_BIT,
@@ -376,6 +377,8 @@ public:
void set_pixelv(const Point2 &p_dst, const Color &p_color);
void set_pixel(int p_x, int p_y, const Color &p_color);
+ void set_as_black();
+
void copy_internals_from(const Ref<Image> &p_image) {
ERR_FAIL_COND_MSG(p_image.is_null(), "It's not a reference to a valid Image object.");
format = p_image->format;
@@ -384,8 +387,6 @@ public:
mipmaps = p_image->mipmaps;
data = p_image->data;
}
-
- ~Image();
};
VARIANT_ENUM_CAST(Image::Format)
diff --git a/core/input/SCsub b/core/input/SCsub
index d46e52a347..c641819698 100644
--- a/core/input/SCsub
+++ b/core/input/SCsub
@@ -8,8 +8,6 @@ import input_builders
# Order matters here. Higher index controller database files write on top of lower index database files.
controller_databases = [
- "#core/input/gamecontrollerdb_204.txt",
- "#core/input/gamecontrollerdb_205.txt",
"#core/input/gamecontrollerdb.txt",
"#core/input/godotcontrollerdb.txt",
]
diff --git a/core/input/gamecontrollerdb_204.txt b/core/input/gamecontrollerdb_204.txt
deleted file mode 100644
index 7fbe925b25..0000000000
--- a/core/input/gamecontrollerdb_204.txt
+++ /dev/null
@@ -1,269 +0,0 @@
-# Game Controller DB for SDL in 2.0.4 format
-# Source: https://github.com/gabomdq/SDL_GameControllerDB
-
-# Windows
-02200090000000000000504944564944,8Bitdo NES30 PRO USB,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
-20380900000000000000504944564944,8Bitdo NES30 PRO Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
-10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
-8f0e1200000000000000504944564944,Acme,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
-341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-c0111352000000000000504944564944,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows,
-d81d0b00000000000000504944564944,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,
-e8206058000000000000504944564944,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-5e048e02000000000000504944564944,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-791d0103000000000000504944564944,Dual Box WII,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-4f0423b3000000000000504944564944,Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-341a0108000000000000504944564944,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-0d0f8500000000000000504944564944,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-0d0f5e00000000000000504944564944,Fighting Commander 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:a3,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-0d0f5f00000000000000504944564944,Fighting Commander 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-0d0f8400000000000000504944564944,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-0d0f8700000000000000504944564944,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-0d0f8800000000000000504944564944,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
-0d0f2700000000000000504944564944,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-79000600000000000000504944564944,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
-28040140000000000000504944564944,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-45130010000000000000504944564944,Generic USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-0d0f4900000000000000504944564944,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-d8140862000000000000504944564944,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
-0d0f4000000000000000504944564944,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
-0d0f6e00000000000000504944564944,HORIPAD 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-0d0fee00000000000000504944564944,HORIPAD mini4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-0d0f4d00000000000000504944564944,HORIPAD3 A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-25090017000000000000504944564944,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,
-d81d0f00000000000000504944564944,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-d81d1000000000000000504944564944,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-83056020000000000000504944564944,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows,
-6f0e2401000000000000504944564944,INJUSTICE FightStick for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-49190204000000000000504944564944,Ipega PG-9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
-6d0418c2000000000000504944564944,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-38075032000000000000504944564944,Mad Catz FightPad PRO PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-38075082000000000000504944564944,Mad Catz FightPad PRO PS4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-38078433000000000000504944564944,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-38078483000000000000504944564944,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b6,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-38078134000000000000504944564944,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-38078184000000000000504944564944,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-38078034000000000000504944564944,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-38078084000000000000504944564944,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-38078532000000000000504944564944,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-38073888000000000000504944564944,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-38071888000000000000504944564944,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-25090128000000000000504944564944,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,
-79004318000000000000504944564944,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
-8f0e1030000000000000504944564944,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows,
-2509e803000000000000504944564944,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
-79000018000000000000504944564944,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-8f0e0d31000000000000504944564944,Multilaser JS071 USB,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-100801e5000000000000504944564944,NEXT Classic USB Game Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-bd1215d0000000000000504944564944,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
-4b12014d000000000000504944564944,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,
-36280100000000000000504944564944,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b15,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b14,x:b1,y:b2,platform:Windows,
-4d6963726f736f66742050432d6a6f79,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a5,righty:a4,x:b1,y:b2,platform:Windows,
-120cf60e000000000000504944564944,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
-8f0e0300000000000000504944564944,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
-d6206dca000000000000504944564944,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-10080100000000000000504944564944,PS1 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
-10080300000000000000504944564944,PS2 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
-4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,
-88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
-25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,
-10008200000000000000504944564944,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-300f0011000000000000504944564944,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows,
-300f1611000000000000504944564944,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
-222c0020000000000000504944564944,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows,
-300f1210000000000000504944564944,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
-341a0104000000000000504944564944,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows,
-222c0223000000000000504944564944,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-222c0023000000000000504944564944,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-0d0f1100000000000000504944564944,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-0d0f6a00000000000000504944564944,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-0d0f6b00000000000000504944564944,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-0d0f8a00000000000000504944564944,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-0d0f8b00000000000000504944564944,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-0d0f7000000000000000504944564944,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-0d0f2200000000000000504944564944,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-00f00300000000000000504944564944,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
-00f0f100000000000000504944564944,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
-6f0e1e01000000000000504944564944,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-300f1201000000000000504944564944,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
-a3060cff000000000000504944564944,Saitek P2500,a:b2,b:b3,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b9,rightx:a2,righty:a3,start:b4,x:b0,y:b1,platform:Windows,
-300f1001000000000000504944564944,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
-9b280500000000000000504944564944,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
-79001100000000000000504944564944,Sega Saturn Gamepad,a:b1,b:b2,leftshoulder:b6,lefttrigger:b3,leftx:a0,lefty:a4,rightshoulder:b7,righttrigger:b0,start:b8,x:b4,y:b5,platform:Windows,
-4c05cc09000000000000504944564944,Sony DualShock 4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-4c05a00b000000000000504944564944,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-ff113133000000000000504944564944,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows,
-4f0415b3000000000000504944564944,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
-4f0400b3000000000000504944564944,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,
-66660488000000000000504944564944,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
-38076652000000000000504944564944,UnKnown,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
-63252305000000000000504944564944,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-79001b18000000000000504944564944,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-
-# Mac OS X
-10280000000000000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
-830500000000000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-79000000000000000600000000000000,G-Shark GP-702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Mac OS X,
-AD1B00000000000001F9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
-0d0f0000000000004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-0d0f0000000000006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-83050000000000006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
-6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-2509000000000000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,
-79000000000000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
-d814000000000000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
-8f0e0000000000000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
-4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
-4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-891600000000000000fd000000000000,Razer Onza Tournament,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-79000000000000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
-81170000000000007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,
-b4040000000000000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,
-351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
-4c05000000000000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-4c05000000000000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-11010000000000002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,
-11010000000000001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,
-4f0400000000000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,
-4f0400000000000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
-bd1200000000000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
-10080000000000000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,
-050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,
-050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,
-5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-5e04000000000000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-5e04000000000000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,
-5e04000000000000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-
-# Linux
-05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
-05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
-030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
-03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,
-030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
-03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b1,y:b3,platform:Linux,
-0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:a0,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:a3,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006f0e00001f01000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick ,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
-030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick ,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
-03000000ff1100004133000010010000,GreenAsia Inc.USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
-06000000adde0000efbe000002010000,Hidromancer Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,
-03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,
-030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
-03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,
-030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,
-03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
-03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
-030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006d04000016c2000010010000,Logitech Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,
-05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,
-03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
-030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400008e02000062230000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e040000dd02000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
-030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
-05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
-030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
-050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
-03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
-05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
-03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
-03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
-050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
-05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
-060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
-030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
-030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
-050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
-03000000790000001100000010010000,RetroLink Saturn Classic Controller,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
-0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
-0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
-030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
-03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,
-03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,
-03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
-03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux,
-030000004c050000c405000011810000,Sony DualShock 4,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
-050000004c050000cc09000000810000,Sony DualShock 4 (CUH-ZCT2U) (Bluetooth),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
-030000004c050000cc09000011810000,Sony DualShock 4 (CUH-ZCT2U) (USB),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
-030000004c050000cc09000011010000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-050000004c050000cc09000000010000,Sony DualShock 4 V2 BT,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
-030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
-030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
-030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
-030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,
-030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,
-03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,
-03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
-03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
-03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
-030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
-030000005e040000d102000001010000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,
-xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-
-# Android
-4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
-
-# iOS
-4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS,
-4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS,
diff --git a/core/input/gamecontrollerdb_205.txt b/core/input/gamecontrollerdb_205.txt
deleted file mode 100644
index 55c45eb148..0000000000
--- a/core/input/gamecontrollerdb_205.txt
+++ /dev/null
@@ -1,337 +0,0 @@
-# Game Controller DB for SDL in 2.0.5 format
-# Source: https://github.com/gabomdq/SDL_GameControllerDB
-
-# Windows
-03000000022000000090000000000000,8Bitdo NES30 PRO USB,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
-03000000203800000900000000000000,8Bitdo NES30 PRO Wireless,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
-03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
-10280900000000000000504944564944,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Windows,
-030000008f0e00001200000000000000,Acme,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Windows,
-03000000341a00003608000000000000,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-341a3608000000000000504944564944,Afterglow PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000c01100001352000000000000,Battalife Joystick,a:b6,b:b7,back:b2,leftshoulder:b0,leftx:a0,lefty:a1,rightshoulder:b1,start:b3,x:b4,y:b5,platform:Windows,
-030000006b1400000055000000000000,bigben ps3padstreetnew,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-0300000066f700000500000000000000,BrutalLegendTest,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
-03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,
-e8206058000000000000504944564944,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-030000005e0400008e02000000000000,Controller (XBOX 360 For Windows),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-030000004f04000023b3000000000000,Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000341a00000108000000000000,EXEQ RF USB Gamepad 8206,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-030000000d0f00008500000000000000,Fighting Commander 2016 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00005e00000000000000,Fighting Commander 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:a3,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00005f00000000000000,Fighting Commander 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00008400000000000000,Fighting Commander 5,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
-030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Windows,
-03000000790000000600000000000000,G-Shark GS-GP702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
-03000000260900002625000000000000,Gamecube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,lefttrigger:a4,leftx:a0,lefty:a1,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Windows,
-030000008f0e00000d31000000000000,GAMEPAD 3 TURBO,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000280400000140000000000000,GamePad Pro USB,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-03000000ffff00000000000000000000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-ffff0000000000000000504944564944,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-030000006d04000016c2000000000000,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-6d0416c2000000000000504944564944,Generic DirectInput Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000451300000010000000000000,Generic USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-03000000341a00000302000000000000,Hama Scorpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00004900000000000000,Hatsune Miku Sho Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000d81400000862000000000000,HitBox Edition Cthulhu+,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00004000000000000000,Hori Fighting Stick Mini 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b4,rightshoulder:b7,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00006e00000000000000,HORIPAD 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00004d00000000000000,HORIPAD3 A,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000250900000017000000000000,HRAP2 on PS/SS/N64 Joypad to USB BOX,a:b2,b:b1,back:b9,leftshoulder:b5,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b6,start:b8,x:b3,y:b0,platform:Windows,
-03000000d81d00000f00000000000000,iBUFFALO BSGP1204 Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-03000000d81d00001000000000000000,iBUFFALO BSGP1204P Series,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Windows,
-03000000b50700001403000000000000,IMPACT BLACK,a:b2,b:b3,back:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
-030000006f0e00002401000000000000,INJUSTICE FightStick for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-03000000491900000204000000000000,Ipega PG-9023,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,platform:Windows,
-030000006d04000019c2000000000000,Logitech Cordless RumblePad 2 USB,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000006d04000011c2000000000000,Logitech Cordless Wingman,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b5,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b2,righttrigger:b7,rightx:a3,righty:a4,x:b4,platform:Windows,
-6d0418c2000000000000504944564944,Logitech F510 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-6d0419c2000000000000504944564944,Logitech F710 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000006d04000018c2000000000000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700005032000000000000,Mad Catz FightPad PRO PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700005082000000000000,Mad Catz FightPad PRO PS4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700008433000000000000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700008483000000000000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b6,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700008134000000000000,Mad Catz FightStick TE2+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b7,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b4,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700008184000000000000,Mad Catz FightStick TE2+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,leftstick:b10,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b4,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700008034000000000000,Mad Catz TE2 PS3 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700008084000000000000,Mad Catz TE2 PS4 Fightstick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700008532000000000000,Madcatz Arcade Fightstick TE S PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700003888000000000000,Madcatz Arcade Fightstick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000380700001888000000000000,MadCatz SFIV FightStick PS3,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b5,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b4,righttrigger:b6,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000008305000031b0000000000000,MaxfireBlaze3,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
-03000000250900000128000000000000,Mayflash Arcade Stick,a:b1,b:b2,back:b8,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b5,y:b6,platform:Windows,
-03000000790000004318000000000000,Mayflash GameCube Controller Adapter,a:b1,b:b2,back:b0,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b0,leftshoulder:b4,leftstick:b0,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b0,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
-030000008f0e00001030000000000000,Mayflash USB Adapter for original Sega Saturn controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b5,rightshoulder:b2,righttrigger:b7,start:b9,x:b3,y:b4,platform:Windows,
-0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
-03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000001008000001e5000000000000,NEXT Classic USB Game Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-03000000bd12000015d0000000000000,Nintendo Retrolink USB Super SNES Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Windows,
-030000004b120000014d000000000000,NYKO AIRFLO,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:a3,leftstick:a0,lefttrigger:b6,rightshoulder:b5,rightstick:a2,righttrigger:b7,start:b9,x:b2,y:b3,platform:Windows,
-03000000362800000100000000000000,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b15,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a3,righty:a4,start:b14,x:b1,y:b2,platform:Windows,
-4d6963726f736f66742050432d6a6f79,OUYA Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b13,rightx:a5,righty:a4,x:b1,y:b2,platform:Windows,
-03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,platform:Windows,
-030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
-03000000d62000006dca000000000000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000008f0e00007530000000000000,PS (R) Gamepad,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b1,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000e30500009605000000000000,PS to USB convert cable,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
-03000000100800000100000000000000,PS1 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
-03000000100800000300000000000000,PS2 USB,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a4,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
-03000000888800000803000000000000,PS3,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
-030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,
-4c056802000000000000504944564944,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Windows,
-88880803000000000000504944564944,PS3 Controller,a:b2,b:b1,back:b8,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b9,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b0,y:b3,platform:Windows,
-03000000250900000500000000000000,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,
-25090500000000000000504944564944,PS3 DualShock,a:b2,b:b1,back:b9,dpdown:h0.8,dpleft:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b0,y:b3,platform:Windows,
-03000000100000008200000000000000,PS360+ v1.66,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:h0.4,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-4c05c405000000000000504944564944,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000300f00000011000000000000,QanBa Arcade JoyStick 1008,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b10,x:b0,y:b3,platform:Windows,
-03000000300f00001611000000000000,QanBa Arcade JoyStick 4018,a:b1,b:b2,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,platform:Windows,
-03000000222c00000020000000000000,QANBA DRONE ARCADE JOYSTICK,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,rightshoulder:b5,righttrigger:a4,start:b9,x:b0,y:b3,platform:Windows,
-03000000300f00001210000000000000,QanBa Joystick Plus,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b9,x:b2,y:b3,platform:Windows,
-03000000341a00000104000000000000,QanBa Joystick Q4RAF,a:b5,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b0,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b3,righttrigger:b7,start:b9,x:b1,y:b2,platform:Windows,
-03000000222c00000223000000000000,Qanba Obsidian Arcade Joystick PS3 Mode,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-03000000222c00000023000000000000,Qanba Obsidian Arcade Joystick PS4 Mode,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000321500000003000000000000,Razer Hydra,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a2,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-030000000d0f00001100000000000000,REAL ARCADE PRO.3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00006a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00006b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00008a00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00008b00000000000000,Real Arcade Pro.4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00007000000000000000,REAL ARCADE PRO.4 VLX,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,rightshoulder:b5,rightstick:b11,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00002200000000000000,REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00005b00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000000d0f00005c00000000000000,Real Arcade Pro.V4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-0300000000f000000300000000000000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
-0300000000f00000f100000000000000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Windows,
-030000006f0e00001e01000000000000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Windows,
-030000004f04000003d0000000000000,run'n'drive,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b7,leftshoulder:a3,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:a4,rightstick:b11,righttrigger:b5,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-03000000a30600001af5000000000000,Saitek Cyborg,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
-03000000a306000023f6000000000000,Saitek Cyborg V.1 Game pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
-03000000300f00001201000000000000,Saitek Dual Analog Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
-03000000a30600000cff000000000000,Saitek P2500,a:b2,b:b3,back:b5,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b6,leftstick:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b9,rightx:a2,righty:a3,start:b4,x:b0,y:b1,platform:Windows,
-03000000a30600000c04000000000000,Saitek P2900,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
-03000000300f00001001000000000000,Saitek P480 Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
-03000000a30600000b04000000000000,Saitek P990,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
-03000000300f00001101000000000000,saitek rumble pad,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
-0300000000050000289b000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
-030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,platform:Windows,
-03000000790000001100000000000000,Sega Saturn Gamepad,a:b1,b:b2,leftshoulder:b6,lefttrigger:b3,leftx:a0,lefty:a4,rightshoulder:b7,righttrigger:b0,start:b8,x:b4,y:b5,platform:Windows,
-03000000341a00000208000000000000,SL-6555-SBK,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:-a4,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a3,righty:a2,start:b7,x:b2,y:b3,platform:Windows,
-030000004c050000cc09000000000000,Sony DualShock 4,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Windows,
-030000008f0e00000800000000000000,SpeedLink Strike FX Wireless,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-03000000ff1100003133000000000000,SVEN X-PAD,a:b2,b:b3,back:b4,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a4,start:b5,x:b0,y:b1,platform:Windows,
-03000000fa1900000706000000000000,Team 5,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-03000000b50700001203000000000000,Techmobility X6-38V,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Windows,
-030000004f04000015b3000000000000,Thrustmaster Dual Analog 2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
-030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Windows,
-030000004f04000004b3000000000000,Thrustmaster Firestorm Dual Power 3,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Windows,
-03000000666600000488000000000000,TigerGame PS/PS2 Game Controller Adapter,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Windows,
-03000000d90400000200000000000000,TwinShock PS2,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Windows,
-03000000380700006652000000000000,UnKnown,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Windows,
-03000000632500002305000000000000,USB Vibration Joystick (BM),a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
-03000000790000001b18000000000000,Venom Arcade Joystick,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Windows,
-03000000786901006e70000000000000,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Windows,
-
-# Mac OS X
-03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
-10280000000000000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
-830500000000000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-03000000790000000600000000000000,G-Shark GP-702,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Mac OS X,
-03000000ad1b000001f9000000000000,Gamestop BB-070 X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Mac OS X,
-030000000d0f00005f00000000000000,HORI Fighting Commander 4 PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-030000000d0f00005e00000000000000,HORI Fighting Commander 4 PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-030000000d0f00004d00000000000000,HORI Gem Pad 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-030000000d0f00006600000000000000,HORIPAD FPS PLUS 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-03000000830500006020000000000000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Mac OS X,
-030000006d04000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-6d0400000000000016c2000000000000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-030000006d04000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-6d0400000000000018c2000000000000,Logitech F510 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-6d040000000000001fc2000000000000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-030000006d04000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-6d0400000000000019c2000000000000,Logitech Wireless Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
-0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Mac OS X,
-03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,platform:Mac OS X,
-03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Mac OS X,
-030000008f0e00000300000000000000,Piranha xtreme,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Mac OS X,
-030000004c0500006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
-4c050000000000006802000000000000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Mac OS X,
-030000004c050000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-4c05000000000000c405000000000000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-030000008916000000fd000000000000,Razer Onza TE,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-03000000790000001100000000000000,Retrolink Classic Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a3,lefty:a4,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
-03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,platform:Mac OS X,
-03000000b40400000a01000000000000,Sega Saturn USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Mac OS X,
-030000003512000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
-351200000000000021ab000000000000,SFC30 Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Mac OS X,
-030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
-11010000000000002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,
-11010000000000001714000000000000,SteelSeries Stratus XL,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,platform:Mac OS X,
-030000004f04000015b3000000000000,Thrustmaster Dual Analog 3.2,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Mac OS X,
-030000004f04000000b3000000000000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Mac OS X,
-03000000bd12000015d0000000000000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Mac OS X,
-03000000100800000100000000000000,Twin USB Joystick,a:b4,b:b2,back:b16,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b12,leftstick:b20,lefttrigger:b8,leftx:a0,lefty:a2,rightshoulder:b14,rightstick:b22,righttrigger:b10,rightx:a6,righty:a4,start:b18,x:b6,y:b0,platform:Mac OS X,
-050000005769696d6f74652028303000,Wii Remote,a:b4,b:b5,back:b7,dpdown:b3,dpleft:b0,dpright:b1,dpup:b2,guide:b8,leftshoulder:b11,lefttrigger:b12,leftx:a0,lefty:a1,start:b6,x:b10,y:b9,platform:Mac OS X,
-050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,platform:Mac OS X,
-030000005e0400008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-5e040000000000008e02000000000000,X360 Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-030000005e040000dd02000000000000,Xbox One Wired Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-030000005e040000e002000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Mac OS X,
-030000005e040000ea02000000000000,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,platform:Mac OS X,
-
-# Linux
-05000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a6,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
-05000000c82d00002038000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
-03000000c82d00000190000011010000,8Bitdo NES30 Pro 8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,
-05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,platform:Linux,
-05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,platform:Linux,
-030000006f0e00003901000020060000,Afterglow Wired Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000100000008200000011010000,Akishop Customs PS360+ v1.66,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,
-03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
-03000000b40400000a01000000010000,CYPRESS USB Gamepad,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
-03000000790000000600000010010000,DragonRise Inc. Generic USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b3,y:b0,platform:Linux,
-030000006f0e00003001000001010000,EA Sports PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000341a000005f7000010010000,GameCube {HuiJia USB box},a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b0,y:b3,platform:Linux,
-03000000260900008888000000010000,GameCube {WiseGroup USB box},a:b0,b:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3,start:b7,x:b1,y:b3,platform:Linux,
-0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-030000006f0e00000104000000010000,Gamestop Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006f0e00001304000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:a0,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:a3,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006f0e00001f01000000010000,Generic X-Box pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000f0250000c183000010010000,Goodbetterbest Ltd USB Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000280400000140000000010000,Gravis GamePad Pro USB ,a:b1,b:b2,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-030000008f0e00000300000010010000,GreenAsia Inc. USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
-030000008f0e00001200000010010000,GreenAsia Inc. USB Joystick,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
-03000000ff1100004133000010010000,GreenAsia Inc.USB Joystick,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
-0500000047532067616d657061640000,GS gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-06000000adde0000efbe000002010000,Hidromancer Game Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,platform:Linux,
-03000000c9110000f055000011010000,HJC Game GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-030000000d0f00000d00000000010000,hori,a:b0,b:b6,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftx:b4,lefty:b5,rightshoulder:b7,start:b9,x:b1,y:b2,platform:Linux,
-030000000d0f00001000000011010000,HORI CO. LTD. FIGHTING STICK 3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,platform:Linux,
-03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000000d0f00006700000001010000,HORIPAD ONE,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000830500006020000010010000,iBuffalo USB 2-axis 8-button Gamepad,a:b1,b:b0,back:b6,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b3,y:b2,platform:Linux,
-050000006964726f69643a636f6e0000,idroid:con,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,platform:Linux,
-030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,platform:Linux,
-03000000300f00001001000010010000,Jess Tech Dual Analog Rumble Pad,a:b2,b:b3,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b1,platform:Linux,
-03000000ba2200002010000001010000,Jess Technology USB Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
-030000006f0e00000103000000020000,Logic3 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006d04000019c2000010010000,Logitech Cordless RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006d04000016c2000011010000,Logitech F310 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006d0400001dc2000014400000,Logitech F310 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006d0400001ec2000020200000,Logitech F510 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006d04000019c2000011010000,Logitech F710 Gamepad (DInput),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006d0400001fc2000005030000,Logitech F710 Gamepad (XInput),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000006d04000016c2000010010000,Logitech Logitech Dual Action,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006d04000018c2000010010000,Logitech RumblePad 2,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,platform:Linux,
-05000000380700006652000025010000,Mad Catz C.T.R.L.R ,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000ad1b00002ef0000090040000,Mad Catz Fightpad SFxT,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,platform:Linux,
-03000000380700008034000011010000,Mad Catz fightstick (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000380700008084000011010000,Mad Catz fightstick (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-03000000380700008433000011010000,Mad Catz FightStick TE S+ PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000380700008483000011010000,Mad Catz FightStick TE S+ PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-03000000380700001647000010040000,Mad Catz Wired Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000380700003847000090040000,Mad Catz Wired Xbox 360 Controller (SFIV),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-03000000ad1b000016f0000090040000,Mad Catz Xbox 360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000380700001888000010010000,MadCatz PC USB Wired Stick 8818,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000380700003888000010010000,MadCatz PC USB Wired Stick 8838,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:a0,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000780000000600000010010000,Microntek USB Joystick,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
-030000005e0400008e02000004010000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400008e02000062230000,Microsoft X-Box 360 pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e040000dd02000003020000,Microsoft X-Box One pad v2,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400008502000000010000,Microsoft X-Box pad (Japan),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
-030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
-05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Linux,
-030000001008000001e5000010010000,NEXT Classic USB Game Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:b5,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
-050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b1,b:b0,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
-03000000451300000830000010010000,NYKO CORE,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000005e0400000202000000010000,Old Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
-05000000362800000100000002010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
-05000000362800000100000003010000,OUYA Game Controller,a:b0,b:b3,dpdown:b9,dpleft:b10,dpright:b11,dpup:b8,guide:b14,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,x:b1,y:b2,platform:Linux,
-03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
-03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
-050000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
-05000000504c415953544154494f4e00,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
-060000004c0500006802000000010000,PS3 Controller (Bluetooth),a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:b9,rightx:a2,righty:a3,start:b3,x:b15,y:b12,platform:Linux,
-030000004c050000c405000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000004c050000cc09000011010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-050000004c050000c405000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-050000004c050000cc09000000010000,PS4 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000009b2800000300000001010000,raphnet.net 4nes4snes v1.5,a:b0,b:b4,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b1,y:b5,platform:Linux,
-030000008916000001fd000024010000,Razer Onza Classic Edition,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000008916000000fd000024010000,Razer Onza Tournament,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000c6240000045d000025010000,Razer Sabertooth,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000321500000009000011010000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
-050000003215000000090000163a0000,Razer Serval,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
-03000000790000001100000010010000,RetroLink Saturn Classic Controller,a:b0,b:b1,back:b5,guide:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b8,x:b3,y:b4,platform:Linux,
-0300000000f000000300000000010000,RetroUSB.com RetroPad,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
-0300000000f00000f100000000010000,RetroUSB.com Super RetroPort,a:b1,b:b5,back:b2,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b3,x:b0,y:b4,platform:Linux,
-030000006f0e00001e01000011010000,Rock Candy Gamepad for PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-030000006f0e00004601000001010000,Rock Candy Wired Controller for Xbox One,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000a306000023f6000011010000,Saitek Cyborg V.1 Game Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
-03000000a30600000c04000011010000,Saitek P2900 Wireless Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b12,x:b0,y:b3,platform:Linux,
-03000000a30600000901000000010000,Saitek P880,a:b2,b:b3,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,platform:Linux,
-03000000a306000018f5000010010000,Saitek PLC Saitek P3200 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a4,start:b9,x:b0,y:b3,platform:Linux,
-03000000c01600008704000011010000,Serial/Keyboard/Mouse/Joystick,a:b12,b:b10,back:b4,dpdown:b2,dpleft:b3,dpright:b1,dpup:b0,leftshoulder:b9,leftstick:b14,lefttrigger:b6,leftx:a1,lefty:a0,rightshoulder:b8,rightstick:b15,righttrigger:b7,rightx:a2,righty:a3,start:b5,x:b13,y:b11,platform:Linux,
-030000004c050000c405000011810000,Sony DualShock 4,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
-050000004c050000cc09000000810000,Sony DualShock 4 (CUH-ZCT2U) (Bluetooth),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
-030000004c050000cc09000011810000,Sony DualShock 4 (CUH-ZCT2U) (USB),a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
-030000004c050000a00b000011010000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000004c0500006802000011810000,Sony PLAYSTATION(R)3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
-050000004c0500006802000000810000,Sony PLAYSTATION(R)3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,platform:Linux,
-03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
-030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000666600000488000000010000,Super Joy Box 5 Pro,a:b2,b:b1,back:b9,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,platform:Linux,
-030000004f04000020b3000010010000,Thrustmaster 2 in 1 DT,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
-030000004f04000015b3000010010000,Thrustmaster Dual Analog 4,a:b0,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b1,y:b3,platform:Linux,
-030000004f04000023b3000000010000,Thrustmaster Dual Trigger 3-in-1,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000004f04000000b3000010010000,Thrustmaster Firestorm Dual Power,a:b0,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b11,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b10,x:b1,y:b3,platform:Linux,
-030000004f04000008d0000000010000,Thrustmaster Run N Drive Wireless,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,
-030000004f04000009d0000000010000,Thrustmaster Run N Drive Wireless PS3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
-03000000bd12000015d0000010010000,Tomee SNES USB Controller,a:b2,b:b1,back:b8,leftshoulder:b4,leftx:a0,lefty:a1,rightshoulder:b5,start:b9,x:b3,y:b0,platform:Linux,
-03000000d814000007cd000011010000,Toodles 2008 Chimp PC/PS3,a:b0,b:b1,back:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b9,x:b3,y:b2,platform:Linux,
-03000000100800000100000010010000,Twin USB PS2 Adapter,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
-03000000100800000300000010010000,USB Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,platform:Linux,
-03000000790000001100000000010000,USB Gamepad1,a:b2,b:b1,back:b8,dpdown:a0,dpleft:a1,dpright:a2,dpup:a4,start:b9,platform:Linux,
-03000000de280000ff11000001000000,Valve Streaming Gamepad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-05000000ac0500003232000001000000,VR-BOX,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b2,y:b3,platform:Linux,
-030000005e0400008e02000010010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400008e02000014010000,X360 Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400001907000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e0400009102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e040000a102000000010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-030000005e040000a102000007010000,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:Linux,
-0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,platform:Linux,
-030000005e040000d102000001010000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-050000005e040000e002000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-03000000c0160000e105000001010000,Xin-Mo Xin-Mo Dual Arcade,a:b4,b:b3,back:b6,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b9,leftshoulder:b2,leftx:a0,lefty:a1,rightshoulder:b5,start:b7,x:b1,y:b0,platform:Linux,
-xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-
-# Android
-4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
-
-# iOS
-4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,platform:iOS,
-4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,platform:iOS,
diff --git a/core/input/godotcontrollerdb.txt b/core/input/godotcontrollerdb.txt
index 472b01947b..51ddda1e4e 100644
--- a/core/input/godotcontrollerdb.txt
+++ b/core/input/godotcontrollerdb.txt
@@ -1,28 +1,11 @@
-# Game Controller DB for SDL in 2.0.6+ format
+# Game Controller DB for Godot in SDL 2.0.10 format
# Source: https://github.com/godotengine/godot
# Windows
-9000318000000000000504944564944,Mayflash Wiimote PC Adapter,a:b2,b:h0.4,x:b0,y:b1,back:b4,start:b5,guide:b11,leftshoulder:b6,rightshoulder:b3,leftx:a0,lefty:a1,platform:Windows,
-c911f055000000000000504944564944,GAMEPAD,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
__XINPUT_DEVICE__,XInput Gamepad,a:b12,b:b13,x:b14,y:b15,start:b4,back:b5,leftstick:b6,rightstick:b7,leftshoulder:b8,rightshoulder:b9,dpup:b0,dpdown:b1,dpleft:b2,dpright:b3,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,platform:Windows,
-# Linux
-030000006f0e00001302000000010000,Afterglow Gamepad for Xbox 360,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-05000000362800000100000004010000,OUYA Game Controller,leftx:a0,lefty:a1,dpdown:b9,rightstick:b7,rightshoulder:b5,rightx:a3,start:b16,righty:a4,dpleft:b10,lefttrigger:b12,x:b1,dpup:b8,back:b14,leftstick:b6,leftshoulder:b4,y:b2,a:b0,dpright:b11,righttrigger:b13,b:b3,platform:Linux,
-030000005e0400008e02000001000000,Microsoft X-Box 360 pad,leftstick:b9,leftx:a0,lefty:a1,dpdown:h0.1,rightstick:b10,rightshoulder:b5,rightx:a3,start:b7,righty:a4,dpleft:h0.2,lefttrigger:a2,x:b2,dpup:h0.4,back:b6,leftshoulder:b4,y:b3,a:b0,dpright:h0.8,righttrigger:a5,b:b1,platform:Linux,
-03000000fd0500002a26000000010000,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b5,rightshoulder:b7,rightx:a2,start:b11,righty:a3,dpleft:h0.8,lefttrigger:b8,x:b0,dpup:h0.1,back:b10,leftstick:b2,leftshoulder:b6,y:b1,a:b3,dpright:h0.2,righttrigger:b9,b:b4,platform:Linux,
-030000006f0e00002801000011010000,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:h0.8,lefttrigger:b6,x:b0,dpup:h0.1,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b1,dpright:h0.2,righttrigger:b7,b:b2,platform:Linux,
-030000000d0f00004d00000011010000,HORI Gem Pad 3,x:b0,a:b1,b:b2,y:b3,back:b8,guide:b12,start:b9,dpleft:h0.8,dpdown:h0.4,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,leftstick:b10,rightstick:b11,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Linux,
-030000005e040000ea02000001030000,Xbox One Wireless Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
-
# Android
-4f5559412047616d6520436f6e74726f,OUYA Game Controller,leftx:a1,lefty:a3,dpdown:b12,rightstick:b8,rightshoulder:b10,rightx:a6,start:b-86,righty:a7,dpleft:b13,lefttrigger:b15,x:b2,dpup:b11,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:b14,righttrigger:b16,b:b1,platform:Android,
Default Android Gamepad,Default Controller,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,back:b4,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Android,
-532e542e442e20496e74657261637420,3dfx InterAct HammerHead FX,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b25,rightshoulder:b27,rightx:a2,start:b31,righty:a3,dpleft:h0.8,lefttrigger:b28,x:b20,dpup:h0.1,back:b30,leftstick:b22,leftshoulder:b26,y:b21,a:b23,dpright:h0.2,righttrigger:b29,b:b24,platform:Android,
-506572666f726d616e63652044657369,PDP Rock Candy Wireless Controller for PS3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:h0.2,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,platform:Android,
-4d6963726f736f667420582d426f7820,Microsoft X-Box 360 pad,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a4,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a5,b:b1,platform:Android,
-484f524920434f2e2c4c544420205041,Hori Gem Pad 3,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b6,rightshoulder:b18,rightx:a2,start:b16,righty:a3,dpleft:h0.8,lefttrigger:b9,x:b0,dpup:h0.1,back:b15,leftstick:b4,leftshoulder:b3,y:b2,a:b1,dpright:h0.2,righttrigger:b10,b:b17,platform:Android,
-47656e6572696320582d426f78207061,Logitech F-310,leftx:a0,lefty:a1,dpdown:h0.4,rightstick:b8,rightshoulder:b10,rightx:a2,start:b6,righty:a3,dpleft:h0.8,lefttrigger:a5,x:b2,dpup:h0.1,leftstick:b7,leftshoulder:b9,y:b3,a:b0,dpright:h0.2,righttrigger:a4,b:b1,platform:Android,
# Javascript
Default HTML5 Gamepad, Default Mapping,leftx:a0,lefty:a1,dpdown:b13,rightstick:b11,rightshoulder:b5,rightx:a2,start:b9,righty:a3,dpleft:b14,lefttrigger:a6,x:b2,dpup:b12,back:b8,leftstick:b10,leftshoulder:b4,y:b3,a:b0,dpright:b15,righttrigger:a7,b:b1,platform:Javascript,
diff --git a/core/input/input_filter.cpp b/core/input/input.cpp
index 2e8442a905..4d152c1ac4 100644
--- a/core/input/input_filter.cpp
+++ b/core/input/input.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* input_filter.cpp */
+/* input.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "input_filter.h"
+#include "input.h"
#include "core/input/default_controller_mappings.h"
#include "core/input/input_map.h"
@@ -39,71 +39,149 @@
#include "editor/editor_settings.h"
#endif
-InputFilter *InputFilter::singleton = nullptr;
+static const char *_joy_buttons[JOY_SDL_BUTTONS + 1] = {
+ "a",
+ "b",
+ "x",
+ "y",
+ "back",
+ "guide",
+ "start",
+ "leftstick",
+ "rightstick",
+ "leftshoulder",
+ "rightshoulder",
+ "dpup",
+ "dpdown",
+ "dpleft",
+ "dpright",
+ nullptr
+};
+
+static const char *_joy_button_names[JOY_BUTTON_MAX] = {
+ "Face Bottom",
+ "Face Right",
+ "Face Left",
+ "Face Top",
+ "Select",
+ "Guide",
+ "Start",
+ "Left Stick",
+ "Right Stick",
+ "Left Shoulder",
+ "Right Shoulder",
+ "D-Pad Up",
+ "D-Pad Down",
+ "D-Pad Left",
+ "D-Pad Right",
+ "Button 15",
+ "Button 16",
+ "Button 17",
+ "Button 18",
+ "Button 19",
+ "Button 20",
+ "Button 21",
+ "Button 22",
+ "Button 23",
+ "Button 24",
+ "Button 25",
+ "Button 26",
+ "Button 27",
+ "Button 28",
+ "Button 29",
+ "Button 30",
+ "Button 31",
+ "Button 32",
+ "Button 33",
+ "Button 34",
+ "Button 35"
+};
+
+static const char *_joy_axes[JOY_SDL_AXES + 1] = {
+ "leftx",
+ "lefty",
+ "rightx",
+ "righty",
+ "lefttrigger",
+ "righttrigger",
+ nullptr
+};
+
+static const char *_joy_axis_names[JOY_AXIS_MAX] = {
+ "Left Stick X",
+ "Left Stick Y",
+ "Right Stick X",
+ "Right Stick Y",
+ "Left Trigger",
+ "Right Trigger",
+ "Joystick 3 Stick X",
+ "Joystick 3 Stick Y",
+ "Joystick 4 Stick X",
+ "Joystick 4 Stick Y"
+};
-void (*InputFilter::set_mouse_mode_func)(InputFilter::MouseMode) = nullptr;
-InputFilter::MouseMode (*InputFilter::get_mouse_mode_func)() = nullptr;
-void (*InputFilter::warp_mouse_func)(const Vector2 &p_to_pos) = nullptr;
-InputFilter::CursorShape (*InputFilter::get_current_cursor_shape_func)() = nullptr;
-void (*InputFilter::set_custom_mouse_cursor_func)(const RES &, InputFilter::CursorShape, const Vector2 &) = nullptr;
+Input *Input::singleton = nullptr;
-InputFilter *InputFilter::get_singleton() {
+void (*Input::set_mouse_mode_func)(Input::MouseMode) = nullptr;
+Input::MouseMode (*Input::get_mouse_mode_func)() = nullptr;
+void (*Input::warp_mouse_func)(const Vector2 &p_to_pos) = nullptr;
+Input::CursorShape (*Input::get_current_cursor_shape_func)() = nullptr;
+void (*Input::set_custom_mouse_cursor_func)(const RES &, Input::CursorShape, const Vector2 &) = nullptr;
+Input *Input::get_singleton() {
return singleton;
}
-void InputFilter::set_mouse_mode(MouseMode p_mode) {
+void Input::set_mouse_mode(MouseMode p_mode) {
ERR_FAIL_INDEX((int)p_mode, 4);
set_mouse_mode_func(p_mode);
}
-InputFilter::MouseMode InputFilter::get_mouse_mode() const {
-
+Input::MouseMode Input::get_mouse_mode() const {
return get_mouse_mode_func();
}
-void InputFilter::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &InputFilter::is_key_pressed);
- ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &InputFilter::is_mouse_button_pressed);
- ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &InputFilter::is_joy_button_pressed);
- ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &InputFilter::is_action_pressed);
- ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action"), &InputFilter::is_action_just_pressed);
- ClassDB::bind_method(D_METHOD("is_action_just_released", "action"), &InputFilter::is_action_just_released);
- ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &InputFilter::get_action_strength);
- ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &InputFilter::add_joy_mapping, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("remove_joy_mapping", "guid"), &InputFilter::remove_joy_mapping);
- ClassDB::bind_method(D_METHOD("joy_connection_changed", "device", "connected", "name", "guid"), &InputFilter::joy_connection_changed);
- ClassDB::bind_method(D_METHOD("is_joy_known", "device"), &InputFilter::is_joy_known);
- ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &InputFilter::get_joy_axis);
- ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &InputFilter::get_joy_name);
- ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &InputFilter::get_joy_guid);
- ClassDB::bind_method(D_METHOD("get_connected_joypads"), &InputFilter::get_connected_joypads);
- ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &InputFilter::get_joy_vibration_strength);
- ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &InputFilter::get_joy_vibration_duration);
- ClassDB::bind_method(D_METHOD("get_joy_button_string", "button_index"), &InputFilter::get_joy_button_string);
- ClassDB::bind_method(D_METHOD("get_joy_button_index_from_string", "button"), &InputFilter::get_joy_button_index_from_string);
- ClassDB::bind_method(D_METHOD("get_joy_axis_string", "axis_index"), &InputFilter::get_joy_axis_string);
- ClassDB::bind_method(D_METHOD("get_joy_axis_index_from_string", "axis"), &InputFilter::get_joy_axis_index_from_string);
- ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &InputFilter::start_joy_vibration, DEFVAL(0));
- ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &InputFilter::stop_joy_vibration);
- ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &InputFilter::vibrate_handheld, DEFVAL(500));
- ClassDB::bind_method(D_METHOD("get_gravity"), &InputFilter::get_gravity);
- ClassDB::bind_method(D_METHOD("get_accelerometer"), &InputFilter::get_accelerometer);
- ClassDB::bind_method(D_METHOD("get_magnetometer"), &InputFilter::get_magnetometer);
- ClassDB::bind_method(D_METHOD("get_gyroscope"), &InputFilter::get_gyroscope);
- ClassDB::bind_method(D_METHOD("get_last_mouse_speed"), &InputFilter::get_last_mouse_speed);
- ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &InputFilter::get_mouse_button_mask);
- ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &InputFilter::set_mouse_mode);
- ClassDB::bind_method(D_METHOD("get_mouse_mode"), &InputFilter::get_mouse_mode);
- ClassDB::bind_method(D_METHOD("warp_mouse_position", "to"), &InputFilter::warp_mouse_position);
- ClassDB::bind_method(D_METHOD("action_press", "action", "strength"), &InputFilter::action_press, DEFVAL(1.f));
- ClassDB::bind_method(D_METHOD("action_release", "action"), &InputFilter::action_release);
- ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &InputFilter::set_default_cursor_shape, DEFVAL(CURSOR_ARROW));
- ClassDB::bind_method(D_METHOD("get_current_cursor_shape"), &InputFilter::get_current_cursor_shape);
- ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &InputFilter::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
- ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &InputFilter::parse_input_event);
- ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &InputFilter::set_use_accumulated_input);
+void Input::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("is_key_pressed", "keycode"), &Input::is_key_pressed);
+ ClassDB::bind_method(D_METHOD("is_mouse_button_pressed", "button"), &Input::is_mouse_button_pressed);
+ ClassDB::bind_method(D_METHOD("is_joy_button_pressed", "device", "button"), &Input::is_joy_button_pressed);
+ ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &Input::is_action_pressed);
+ ClassDB::bind_method(D_METHOD("is_action_just_pressed", "action"), &Input::is_action_just_pressed);
+ ClassDB::bind_method(D_METHOD("is_action_just_released", "action"), &Input::is_action_just_released);
+ ClassDB::bind_method(D_METHOD("get_action_strength", "action"), &Input::get_action_strength);
+ ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &Input::add_joy_mapping, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("remove_joy_mapping", "guid"), &Input::remove_joy_mapping);
+ ClassDB::bind_method(D_METHOD("joy_connection_changed", "device", "connected", "name", "guid"), &Input::joy_connection_changed);
+ ClassDB::bind_method(D_METHOD("is_joy_known", "device"), &Input::is_joy_known);
+ ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis);
+ ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name);
+ ClassDB::bind_method(D_METHOD("get_joy_guid", "device"), &Input::get_joy_guid);
+ ClassDB::bind_method(D_METHOD("get_connected_joypads"), &Input::get_connected_joypads);
+ ClassDB::bind_method(D_METHOD("get_joy_vibration_strength", "device"), &Input::get_joy_vibration_strength);
+ ClassDB::bind_method(D_METHOD("get_joy_vibration_duration", "device"), &Input::get_joy_vibration_duration);
+ ClassDB::bind_method(D_METHOD("get_joy_button_string", "button_index"), &Input::get_joy_button_string);
+ ClassDB::bind_method(D_METHOD("get_joy_button_index_from_string", "button"), &Input::get_joy_button_index_from_string);
+ ClassDB::bind_method(D_METHOD("get_joy_axis_string", "axis_index"), &Input::get_joy_axis_string);
+ ClassDB::bind_method(D_METHOD("get_joy_axis_index_from_string", "axis"), &Input::get_joy_axis_index_from_string);
+ ClassDB::bind_method(D_METHOD("start_joy_vibration", "device", "weak_magnitude", "strong_magnitude", "duration"), &Input::start_joy_vibration, DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("stop_joy_vibration", "device"), &Input::stop_joy_vibration);
+ ClassDB::bind_method(D_METHOD("vibrate_handheld", "duration_ms"), &Input::vibrate_handheld, DEFVAL(500));
+ ClassDB::bind_method(D_METHOD("get_gravity"), &Input::get_gravity);
+ ClassDB::bind_method(D_METHOD("get_accelerometer"), &Input::get_accelerometer);
+ ClassDB::bind_method(D_METHOD("get_magnetometer"), &Input::get_magnetometer);
+ ClassDB::bind_method(D_METHOD("get_gyroscope"), &Input::get_gyroscope);
+ ClassDB::bind_method(D_METHOD("get_last_mouse_speed"), &Input::get_last_mouse_speed);
+ ClassDB::bind_method(D_METHOD("get_mouse_button_mask"), &Input::get_mouse_button_mask);
+ ClassDB::bind_method(D_METHOD("set_mouse_mode", "mode"), &Input::set_mouse_mode);
+ ClassDB::bind_method(D_METHOD("get_mouse_mode"), &Input::get_mouse_mode);
+ ClassDB::bind_method(D_METHOD("warp_mouse_position", "to"), &Input::warp_mouse_position);
+ ClassDB::bind_method(D_METHOD("action_press", "action", "strength"), &Input::action_press, DEFVAL(1.f));
+ ClassDB::bind_method(D_METHOD("action_release", "action"), &Input::action_release);
+ ClassDB::bind_method(D_METHOD("set_default_cursor_shape", "shape"), &Input::set_default_cursor_shape, DEFVAL(CURSOR_ARROW));
+ ClassDB::bind_method(D_METHOD("get_current_cursor_shape"), &Input::get_current_cursor_shape);
+ ClassDB::bind_method(D_METHOD("set_custom_mouse_cursor", "image", "shape", "hotspot"), &Input::set_custom_mouse_cursor, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
+ ClassDB::bind_method(D_METHOD("parse_input_event", "event"), &Input::parse_input_event);
+ ClassDB::bind_method(D_METHOD("set_use_accumulated_input", "enable"), &Input::set_use_accumulated_input);
BIND_ENUM_CONSTANT(MOUSE_MODE_VISIBLE);
BIND_ENUM_CONSTANT(MOUSE_MODE_HIDDEN);
@@ -131,22 +209,22 @@ void InputFilter::_bind_methods() {
ADD_SIGNAL(MethodInfo("joy_connection_changed", PropertyInfo(Variant::INT, "device"), PropertyInfo(Variant::BOOL, "connected")));
}
-void InputFilter::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
+void Input::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
#ifdef TOOLS_ENABLED
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\"";
String pf = p_function;
if (p_idx == 0 && (pf == "is_action_pressed" || pf == "action_press" || pf == "action_release" || pf == "is_action_just_pressed" || pf == "is_action_just_released" || pf == "get_action_strength")) {
-
List<PropertyInfo> pinfo;
ProjectSettings::get_singleton()->get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
const PropertyInfo &pi = E->get();
- if (!pi.name.begins_with("input/"))
+ if (!pi.name.begins_with("input/")) {
continue;
+ }
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
r_options->push_back(quote_style + name + quote_style);
@@ -155,8 +233,7 @@ void InputFilter::get_argument_options(const StringName &p_function, int p_idx,
#endif
}
-void InputFilter::SpeedTrack::update(const Vector2 &p_delta_p) {
-
+void Input::SpeedTrack::update(const Vector2 &p_delta_p) {
uint64_t tick = OS::get_singleton()->get_ticks_usec();
uint32_t tdiff = tick - last_tick;
float delta_t = tdiff / 1000000.0;
@@ -165,66 +242,60 @@ void InputFilter::SpeedTrack::update(const Vector2 &p_delta_p) {
accum += p_delta_p;
accum_t += delta_t;
- if (accum_t > max_ref_frame * 10)
+ if (accum_t > max_ref_frame * 10) {
accum_t = max_ref_frame * 10;
+ }
while (accum_t >= min_ref_frame) {
-
float slice_t = min_ref_frame / accum_t;
Vector2 slice = accum * slice_t;
accum = accum - slice;
accum_t -= min_ref_frame;
- speed = (slice / min_ref_frame).linear_interpolate(speed, min_ref_frame / max_ref_frame);
+ speed = (slice / min_ref_frame).lerp(speed, min_ref_frame / max_ref_frame);
}
}
-void InputFilter::SpeedTrack::reset() {
+void Input::SpeedTrack::reset() {
last_tick = OS::get_singleton()->get_ticks_usec();
speed = Vector2();
accum_t = 0;
}
-InputFilter::SpeedTrack::SpeedTrack() {
-
+Input::SpeedTrack::SpeedTrack() {
min_ref_frame = 0.1;
max_ref_frame = 0.3;
reset();
}
-bool InputFilter::is_key_pressed(int p_keycode) const {
-
+bool Input::is_key_pressed(int p_keycode) const {
_THREAD_SAFE_METHOD_
return keys_pressed.has(p_keycode);
}
-bool InputFilter::is_mouse_button_pressed(int p_button) const {
-
+bool Input::is_mouse_button_pressed(int p_button) const {
_THREAD_SAFE_METHOD_
return (mouse_button_mask & (1 << (p_button - 1))) != 0;
}
static int _combine_device(int p_value, int p_device) {
-
return p_value | (p_device << 20);
}
-bool InputFilter::is_joy_button_pressed(int p_device, int p_button) const {
-
+bool Input::is_joy_button_pressed(int p_device, int p_button) const {
_THREAD_SAFE_METHOD_
return joy_buttons_pressed.has(_combine_device(p_button, p_device));
}
-bool InputFilter::is_action_pressed(const StringName &p_action) const {
-
+bool Input::is_action_pressed(const StringName &p_action) const {
return action_state.has(p_action) && action_state[p_action].pressed;
}
-bool InputFilter::is_action_just_pressed(const StringName &p_action) const {
-
+bool Input::is_action_just_pressed(const StringName &p_action) const {
const Map<StringName, Action>::Element *E = action_state.find(p_action);
- if (!E)
+ if (!E) {
return false;
+ }
if (Engine::get_singleton()->is_in_physics_frame()) {
return E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames();
@@ -233,11 +304,11 @@ bool InputFilter::is_action_just_pressed(const StringName &p_action) const {
}
}
-bool InputFilter::is_action_just_released(const StringName &p_action) const {
-
+bool Input::is_action_just_released(const StringName &p_action) const {
const Map<StringName, Action>::Element *E = action_state.find(p_action);
- if (!E)
+ if (!E) {
return false;
+ }
if (Engine::get_singleton()->is_in_physics_frame()) {
return !E->get().pressed && E->get().physics_frame == Engine::get_singleton()->get_physics_frames();
@@ -246,16 +317,16 @@ bool InputFilter::is_action_just_released(const StringName &p_action) const {
}
}
-float InputFilter::get_action_strength(const StringName &p_action) const {
+float Input::get_action_strength(const StringName &p_action) const {
const Map<StringName, Action>::Element *E = action_state.find(p_action);
- if (!E)
+ if (!E) {
return 0.0f;
+ }
return E->get().strength;
}
-float InputFilter::get_joy_axis(int p_device, int p_axis) const {
-
+float Input::get_joy_axis(int p_device, int p_axis) const {
_THREAD_SAFE_METHOD_
int c = _combine_device(p_axis, p_device);
if (_joy_axis.has(c)) {
@@ -265,13 +336,12 @@ float InputFilter::get_joy_axis(int p_device, int p_axis) const {
}
}
-String InputFilter::get_joy_name(int p_idx) {
-
+String Input::get_joy_name(int p_idx) {
_THREAD_SAFE_METHOD_
return joy_names[p_idx].name;
-};
+}
-Vector2 InputFilter::get_joy_vibration_strength(int p_device) {
+Vector2 Input::get_joy_vibration_strength(int p_device) {
if (joy_vibration.has(p_device)) {
return Vector2(joy_vibration[p_device].weak_magnitude, joy_vibration[p_device].strong_magnitude);
} else {
@@ -279,7 +349,7 @@ Vector2 InputFilter::get_joy_vibration_strength(int p_device) {
}
}
-uint64_t InputFilter::get_joy_vibration_timestamp(int p_device) {
+uint64_t Input::get_joy_vibration_timestamp(int p_device) {
if (joy_vibration.has(p_device)) {
return joy_vibration[p_device].timestamp;
} else {
@@ -287,7 +357,7 @@ uint64_t InputFilter::get_joy_vibration_timestamp(int p_device) {
}
}
-float InputFilter::get_joy_vibration_duration(int p_device) {
+float Input::get_joy_vibration_duration(int p_device) {
if (joy_vibration.has(p_device)) {
return joy_vibration[p_device].duration;
} else {
@@ -296,7 +366,6 @@ float InputFilter::get_joy_vibration_duration(int p_device) {
}
static String _hex_str(uint8_t p_byte) {
-
static const char *dict = "0123456789abcdef";
char ret[3];
ret[2] = 0;
@@ -305,24 +374,22 @@ static String _hex_str(uint8_t p_byte) {
ret[1] = dict[p_byte & 0xf];
return ret;
-};
-
-void InputFilter::joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid) {
+}
+void Input::joy_connection_changed(int p_idx, bool p_connected, String p_name, String p_guid) {
_THREAD_SAFE_METHOD_
Joypad js;
js.name = p_connected ? p_name : "";
js.uid = p_connected ? p_guid : "";
if (p_connected) {
-
String uidname = p_guid;
if (p_guid == "") {
int uidlen = MIN(p_name.length(), 16);
for (int i = 0; i < uidlen; i++) {
uidname = uidname + _hex_str(p_name[i]);
- };
- };
+ }
+ }
js.uid = uidname;
js.connected = true;
int mapping = fallback_mapping;
@@ -330,56 +397,49 @@ void InputFilter::joy_connection_changed(int p_idx, bool p_connected, String p_n
if (js.uid == map_db[i].uid) {
mapping = i;
js.name = map_db[i].name;
- };
- };
+ }
+ }
js.mapping = mapping;
} else {
js.connected = false;
for (int i = 0; i < JOY_BUTTON_MAX; i++) {
-
- if (i < JOY_AXIS_MAX)
- set_joy_axis(p_idx, i, 0.0f);
-
int c = _combine_device(i, p_idx);
joy_buttons_pressed.erase(c);
- };
- };
+ }
+ for (int i = 0; i < JOY_AXIS_MAX; i++) {
+ set_joy_axis(p_idx, i, 0.0f);
+ }
+ }
joy_names[p_idx] = js;
emit_signal("joy_connection_changed", p_idx, p_connected);
-};
-
-Vector3 InputFilter::get_gravity() const {
+}
+Vector3 Input::get_gravity() const {
_THREAD_SAFE_METHOD_
return gravity;
}
-Vector3 InputFilter::get_accelerometer() const {
-
+Vector3 Input::get_accelerometer() const {
_THREAD_SAFE_METHOD_
return accelerometer;
}
-Vector3 InputFilter::get_magnetometer() const {
-
+Vector3 Input::get_magnetometer() const {
_THREAD_SAFE_METHOD_
return magnetometer;
}
-Vector3 InputFilter::get_gyroscope() const {
-
+Vector3 Input::get_gyroscope() const {
_THREAD_SAFE_METHOD_
return gyroscope;
}
-void InputFilter::parse_input_event(const Ref<InputEvent> &p_event) {
-
+void Input::parse_input_event(const Ref<InputEvent> &p_event) {
_parse_input_event_impl(p_event, false);
}
-void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
-
+void Input::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated) {
// Notes on mouse-touch emulation:
// - Emulated mouse events are parsed, that is, re-routed to this method, so they make the same effects
// as true mouse events. The only difference is the situation is flagged as emulated so they are not
@@ -391,16 +451,16 @@ void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p
Ref<InputEventKey> k = p_event;
if (k.is_valid() && !k->is_echo() && k->get_keycode() != 0) {
- if (k->is_pressed())
+ if (k->is_pressed()) {
keys_pressed.insert(k->get_keycode());
- else
+ } else {
keys_pressed.erase(k->get_keycode());
+ }
}
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
-
if (mb->is_pressed()) {
mouse_button_mask |= (1 << (mb->get_button_index() - 1));
} else {
@@ -424,7 +484,6 @@ void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
Point2 pos = mm->get_global_position();
if (mouse_pos != pos) {
set_mouse_position(pos);
@@ -445,7 +504,6 @@ void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p
Ref<InputEventScreenTouch> st = p_event;
if (st.is_valid()) {
-
if (st->is_pressed()) {
SpeedTrack &track = touch_speed_track[st->get_index()];
track.reset();
@@ -456,7 +514,6 @@ void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p
}
if (emulate_mouse_from_touch) {
-
bool translate = false;
if (st->is_pressed()) {
if (mouse_from_touch_index == -1) {
@@ -493,13 +550,11 @@ void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p
Ref<InputEventScreenDrag> sd = p_event;
if (sd.is_valid()) {
-
SpeedTrack &track = touch_speed_track[sd->get_index()];
track.update(sd->get_relative());
sd->set_speed(track.speed);
if (emulate_mouse_from_touch && sd->get_index() == mouse_from_touch_index) {
-
Ref<InputEventMouseMotion> motion_event;
motion_event.instance();
@@ -517,13 +572,13 @@ void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p
Ref<InputEventJoypadButton> jb = p_event;
if (jb.is_valid()) {
-
int c = _combine_device(jb->get_button_index(), jb->get_device());
- if (jb->is_pressed())
+ if (jb->is_pressed()) {
joy_buttons_pressed.insert(c);
- else
+ } else {
joy_buttons_pressed.erase(c);
+ }
}
Ref<InputEventJoypadMotion> jm = p_event;
@@ -535,7 +590,6 @@ void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p
Ref<InputEventGesture> ge = p_event;
if (ge.is_valid()) {
-
if (event_dispatch_function) {
event_dispatch_function(ge);
}
@@ -543,7 +597,6 @@ void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p
for (const Map<StringName, InputMap::Action>::Element *E = InputMap::get_singleton()->get_action_map().front(); E; E = E->next()) {
if (InputMap::get_singleton()->event_is_action(p_event, E->key())) {
-
// Save the action's state
if (!p_event->is_echo() && is_action_pressed(E->key()) != p_event->is_action_pressed(E->key())) {
Action action;
@@ -557,18 +610,18 @@ void InputFilter::_parse_input_event_impl(const Ref<InputEvent> &p_event, bool p
}
}
- if (event_dispatch_function)
+ if (event_dispatch_function) {
event_dispatch_function(p_event);
+ }
}
-void InputFilter::set_joy_axis(int p_device, int p_axis, float p_value) {
-
+void Input::set_joy_axis(int p_device, int p_axis, float p_value) {
_THREAD_SAFE_METHOD_
int c = _combine_device(p_axis, p_device);
_joy_axis[c] = p_value;
}
-void InputFilter::start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration) {
+void Input::start_joy_vibration(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration) {
_THREAD_SAFE_METHOD_
if (p_weak_magnitude < 0.f || p_weak_magnitude > 1.f || p_strong_magnitude < 0.f || p_strong_magnitude > 1.f) {
return;
@@ -581,7 +634,7 @@ void InputFilter::start_joy_vibration(int p_device, float p_weak_magnitude, floa
joy_vibration[p_device] = vibration;
}
-void InputFilter::stop_joy_vibration(int p_device) {
+void Input::stop_joy_vibration(int p_device) {
_THREAD_SAFE_METHOD_
VibrationInfo vibration;
vibration.weak_magnitude = 0;
@@ -591,64 +644,56 @@ void InputFilter::stop_joy_vibration(int p_device) {
joy_vibration[p_device] = vibration;
}
-void InputFilter::vibrate_handheld(int p_duration_ms) {
+void Input::vibrate_handheld(int p_duration_ms) {
OS::get_singleton()->vibrate_handheld(p_duration_ms);
}
-void InputFilter::set_gravity(const Vector3 &p_gravity) {
-
+void Input::set_gravity(const Vector3 &p_gravity) {
_THREAD_SAFE_METHOD_
gravity = p_gravity;
}
-void InputFilter::set_accelerometer(const Vector3 &p_accel) {
-
+void Input::set_accelerometer(const Vector3 &p_accel) {
_THREAD_SAFE_METHOD_
accelerometer = p_accel;
}
-void InputFilter::set_magnetometer(const Vector3 &p_magnetometer) {
-
+void Input::set_magnetometer(const Vector3 &p_magnetometer) {
_THREAD_SAFE_METHOD_
magnetometer = p_magnetometer;
}
-void InputFilter::set_gyroscope(const Vector3 &p_gyroscope) {
-
+void Input::set_gyroscope(const Vector3 &p_gyroscope) {
_THREAD_SAFE_METHOD_
gyroscope = p_gyroscope;
}
-void InputFilter::set_mouse_position(const Point2 &p_posf) {
-
+void Input::set_mouse_position(const Point2 &p_posf) {
mouse_speed_track.update(p_posf - mouse_pos);
mouse_pos = p_posf;
}
-Point2 InputFilter::get_mouse_position() const {
-
+Point2 Input::get_mouse_position() const {
return mouse_pos;
}
-Point2 InputFilter::get_last_mouse_speed() const {
+Point2 Input::get_last_mouse_speed() const {
return mouse_speed_track.speed;
}
-int InputFilter::get_mouse_button_mask() const {
-
+int Input::get_mouse_button_mask() const {
return mouse_button_mask; // do not trust OS implementation, should remove it - OS::get_singleton()->get_mouse_button_state();
}
-void InputFilter::warp_mouse_position(const Vector2 &p_to) {
+void Input::warp_mouse_position(const Vector2 &p_to) {
warp_mouse_func(p_to);
}
-Point2i InputFilter::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect) {
-
+Point2i Input::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect) {
// The relative distance reported for the next event after a warp is in the boundaries of the
// size of the rect on that axis, but it may be greater, in which case there's not problem as fmod()
// will warp it, but if the pointer has moved in the opposite direction between the pointer relocation
@@ -673,11 +718,10 @@ Point2i InputFilter::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motio
return rel_warped;
}
-void InputFilter::iteration(float p_step) {
+void Input::iteration(float p_step) {
}
-void InputFilter::action_press(const StringName &p_action, float p_strength) {
-
+void Input::action_press(const StringName &p_action, float p_strength) {
Action action;
action.physics_frame = Engine::get_singleton()->get_physics_frames();
@@ -688,8 +732,7 @@ void InputFilter::action_press(const StringName &p_action, float p_strength) {
action_state[p_action] = action;
}
-void InputFilter::action_release(const StringName &p_action) {
-
+void Input::action_release(const StringName &p_action) {
Action action;
action.physics_frame = Engine::get_singleton()->get_physics_frames();
@@ -700,20 +743,17 @@ void InputFilter::action_release(const StringName &p_action) {
action_state[p_action] = action;
}
-void InputFilter::set_emulate_touch_from_mouse(bool p_emulate) {
-
+void Input::set_emulate_touch_from_mouse(bool p_emulate) {
emulate_touch_from_mouse = p_emulate;
}
-bool InputFilter::is_emulating_touch_from_mouse() const {
-
+bool Input::is_emulating_touch_from_mouse() const {
return emulate_touch_from_mouse;
}
// Calling this whenever the game window is focused helps unstucking the "touch mouse"
// if the OS or its abstraction class hasn't properly reported that touch pointers raised
-void InputFilter::ensure_touch_mouse_raised() {
-
+void Input::ensure_touch_mouse_raised() {
if (mouse_from_touch_index != -1) {
mouse_from_touch_index = -1;
@@ -731,25 +771,22 @@ void InputFilter::ensure_touch_mouse_raised() {
}
}
-void InputFilter::set_emulate_mouse_from_touch(bool p_emulate) {
-
+void Input::set_emulate_mouse_from_touch(bool p_emulate) {
emulate_mouse_from_touch = p_emulate;
}
-bool InputFilter::is_emulating_mouse_from_touch() const {
-
+bool Input::is_emulating_mouse_from_touch() const {
return emulate_mouse_from_touch;
}
-InputFilter::CursorShape InputFilter::get_default_cursor_shape() const {
-
+Input::CursorShape Input::get_default_cursor_shape() const {
return default_shape;
}
-void InputFilter::set_default_cursor_shape(CursorShape p_shape) {
-
- if (default_shape == p_shape)
+void Input::set_default_cursor_shape(CursorShape p_shape) {
+ if (default_shape == p_shape) {
return;
+ }
default_shape = p_shape;
// The default shape is set in Viewport::_gui_input_event. To instantly
@@ -761,19 +798,19 @@ void InputFilter::set_default_cursor_shape(CursorShape p_shape) {
parse_input_event(mm);
}
-InputFilter::CursorShape InputFilter::get_current_cursor_shape() const {
-
+Input::CursorShape Input::get_current_cursor_shape() const {
return get_current_cursor_shape_func();
}
-void InputFilter::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
- if (Engine::get_singleton()->is_editor_hint())
+void Input::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+ if (Engine::get_singleton()->is_editor_hint()) {
return;
+ }
set_custom_mouse_cursor_func(p_cursor, p_shape, p_hotspot);
}
-void InputFilter::accumulate_input_event(const Ref<InputEvent> &p_event) {
+void Input::accumulate_input_event(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (!use_accumulated_input) {
@@ -786,39 +823,37 @@ void InputFilter::accumulate_input_event(const Ref<InputEvent> &p_event) {
accumulated_events.push_back(p_event);
}
-void InputFilter::flush_accumulated_events() {
+void Input::flush_accumulated_events() {
while (accumulated_events.front()) {
parse_input_event(accumulated_events.front()->get());
accumulated_events.pop_front();
}
}
-void InputFilter::set_use_accumulated_input(bool p_enable) {
-
+void Input::set_use_accumulated_input(bool p_enable) {
use_accumulated_input = p_enable;
}
-void InputFilter::release_pressed_events() {
-
+void Input::release_pressed_events() {
flush_accumulated_events(); // this is needed to release actions strengths
keys_pressed.clear();
joy_buttons_pressed.clear();
_joy_axis.clear();
- for (Map<StringName, InputFilter::Action>::Element *E = action_state.front(); E; E = E->next()) {
- if (E->get().pressed)
+ for (Map<StringName, Input::Action>::Element *E = action_state.front(); E; E = E->next()) {
+ if (E->get().pressed) {
action_release(E->key());
+ }
}
}
-void InputFilter::set_event_dispatch_function(EventDispatchFunc p_function) {
+void Input::set_event_dispatch_function(EventDispatchFunc p_function) {
event_dispatch_function = p_function;
}
-void InputFilter::joy_button(int p_device, int p_button, bool p_pressed) {
-
+void Input::joy_button(int p_device, int p_button, bool p_pressed) {
_THREAD_SAFE_METHOD_;
Joypad &joy = joy_names[p_device];
//printf("got button %i, mapping is %i\n", p_button, joy.mapping);
@@ -831,21 +866,9 @@ void InputFilter::joy_button(int p_device, int p_button, bool p_pressed) {
return;
}
- const Map<int, JoyEvent>::Element *el = map_db[joy.mapping].buttons.find(p_button);
- if (!el) {
- //don't process un-mapped events for now, it could mess things up badly for devices with additional buttons/axis
- //return _button_event(p_last_id, p_device, p_button, p_pressed);
- return;
- }
+ JoyEvent map = _get_mapped_button_event(map_db[joy.mapping], p_button);
- JoyEvent map = el->get();
if (map.type == TYPE_BUTTON) {
- //fake additional axis event for triggers
- if (map.index == JOY_L2 || map.index == JOY_R2) {
- float value = p_pressed ? 1.0f : 0.0f;
- int axis = map.index == JOY_L2 ? JOY_ANALOG_L2 : JOY_ANALOG_R2;
- _axis_event(p_device, axis, value);
- }
_button_event(p_device, map.index, p_pressed);
return;
}
@@ -856,8 +879,7 @@ void InputFilter::joy_button(int p_device, int p_button, bool p_pressed) {
// no event?
}
-void InputFilter::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
-
+void Input::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
_THREAD_SAFE_METHOD_;
ERR_FAIL_INDEX(p_axis, JOY_AXIS_MAX);
@@ -869,13 +891,10 @@ void InputFilter::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
}
if (p_value.value > joy.last_axis[p_axis]) {
-
if (p_value.value < joy.last_axis[p_axis] + joy.filter) {
-
return;
}
} else if (p_value.value > joy.last_axis[p_axis] - joy.filter) {
-
return;
}
@@ -899,34 +918,21 @@ void InputFilter::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
if (joy.mapping == -1) {
_axis_event(p_device, p_axis, val);
return;
- };
-
- const Map<int, JoyEvent>::Element *el = map_db[joy.mapping].axis.find(p_axis);
- if (!el) {
- //return _axis_event(p_last_id, p_device, p_axis, p_value);
- return;
- };
+ }
- JoyEvent map = el->get();
+ JoyEvent map = _get_mapped_axis_event(map_db[joy.mapping], p_axis, p_value);
if (map.type == TYPE_BUTTON) {
- //send axis event for triggers
- if (map.index == JOY_L2 || map.index == JOY_R2) {
- float value = p_value.min == 0 ? p_value.value : 0.5f + p_value.value / 2.0f;
- int axis = map.index == JOY_L2 ? JOY_ANALOG_L2 : JOY_ANALOG_R2;
- _axis_event(p_device, axis, value);
- }
-
- if (map.index == JOY_DPAD_UP || map.index == JOY_DPAD_DOWN) {
+ if (map.index == JOY_BUTTON_DPAD_UP || map.index == JOY_BUTTON_DPAD_DOWN) {
bool pressed = p_value.value != 0.0f;
- int button = p_value.value < 0 ? JOY_DPAD_UP : JOY_DPAD_DOWN;
+ int button = p_value.value < 0 ? JOY_BUTTON_DPAD_UP : JOY_BUTTON_DPAD_DOWN;
if (!pressed) {
- if (joy_buttons_pressed.has(_combine_device(JOY_DPAD_UP, p_device))) {
- _button_event(p_device, JOY_DPAD_UP, false);
+ if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_UP, p_device))) {
+ _button_event(p_device, JOY_BUTTON_DPAD_UP, false);
}
- if (joy_buttons_pressed.has(_combine_device(JOY_DPAD_DOWN, p_device))) {
- _button_event(p_device, JOY_DPAD_DOWN, false);
+ if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_DOWN, p_device))) {
+ _button_event(p_device, JOY_BUTTON_DPAD_DOWN, false);
}
}
if (pressed == joy_buttons_pressed.has(_combine_device(button, p_device))) {
@@ -935,16 +941,17 @@ void InputFilter::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
_button_event(p_device, button, true);
return;
}
- if (map.index == JOY_DPAD_LEFT || map.index == JOY_DPAD_RIGHT) {
+
+ if (map.index == JOY_BUTTON_DPAD_LEFT || map.index == JOY_BUTTON_DPAD_RIGHT) {
bool pressed = p_value.value != 0.0f;
- int button = p_value.value < 0 ? JOY_DPAD_LEFT : JOY_DPAD_RIGHT;
+ int button = p_value.value < 0 ? JOY_BUTTON_DPAD_LEFT : JOY_BUTTON_DPAD_RIGHT;
if (!pressed) {
- if (joy_buttons_pressed.has(_combine_device(JOY_DPAD_LEFT, p_device))) {
- _button_event(p_device, JOY_DPAD_LEFT, false);
+ if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_LEFT, p_device))) {
+ _button_event(p_device, JOY_BUTTON_DPAD_LEFT, false);
}
- if (joy_buttons_pressed.has(_combine_device(JOY_DPAD_RIGHT, p_device))) {
- _button_event(p_device, JOY_DPAD_RIGHT, false);
+ if (joy_buttons_pressed.has(_combine_device(JOY_BUTTON_DPAD_RIGHT, p_device))) {
+ _button_event(p_device, JOY_BUTTON_DPAD_RIGHT, false);
}
}
if (pressed == joy_buttons_pressed.has(_combine_device(button, p_device))) {
@@ -953,36 +960,50 @@ void InputFilter::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) {
_button_event(p_device, button, true);
return;
}
+
float deadzone = p_value.min == 0 ? 0.5f : 0.0f;
bool pressed = p_value.value > deadzone;
if (pressed == joy_buttons_pressed.has(_combine_device(map.index, p_device))) {
// button already pressed or released, this is an axis bounce value
return;
}
+
_button_event(p_device, map.index, pressed);
return;
}
if (map.type == TYPE_AXIS) {
-
- _axis_event(p_device, map.index, val);
+ _axis_event(p_device, map.index, map.value);
return;
}
//printf("invalid mapping\n");
}
-void InputFilter::joy_hat(int p_device, int p_val) {
-
+void Input::joy_hat(int p_device, int p_val) {
_THREAD_SAFE_METHOD_;
const Joypad &joy = joy_names[p_device];
- const JoyEvent *map;
+ JoyEvent map[HAT_MAX];
- if (joy.mapping == -1) {
- map = hat_map_default;
- } else {
- map = map_db[joy.mapping].hat;
- };
+ map[HAT_UP].type = TYPE_BUTTON;
+ map[HAT_UP].index = JOY_BUTTON_DPAD_UP;
+ map[HAT_UP].value = 0;
+
+ map[HAT_RIGHT].type = TYPE_BUTTON;
+ map[HAT_RIGHT].index = JOY_BUTTON_DPAD_RIGHT;
+ map[HAT_RIGHT].value = 0;
+
+ map[HAT_DOWN].type = TYPE_BUTTON;
+ map[HAT_DOWN].index = JOY_BUTTON_DPAD_DOWN;
+ map[HAT_DOWN].value = 0;
+
+ map[HAT_LEFT].type = TYPE_BUTTON;
+ map[HAT_LEFT].index = JOY_BUTTON_DPAD_LEFT;
+ map[HAT_LEFT].value = 0;
+
+ if (joy.mapping != -1) {
+ _get_mapped_hat_events(map_db[joy.mapping], 0, map);
+ }
int cur_val = joy_names[p_device].hat_current;
@@ -1003,8 +1024,7 @@ void InputFilter::joy_hat(int p_device, int p_val) {
joy_names[p_device].hat_current = p_val;
}
-void InputFilter::_button_event(int p_device, int p_index, bool p_pressed) {
-
+void Input::_button_event(int p_device, int p_index, bool p_pressed) {
Ref<InputEventJoypadButton> ievent;
ievent.instance();
ievent->set_device(p_device);
@@ -1014,8 +1034,7 @@ void InputFilter::_button_event(int p_device, int p_index, bool p_pressed) {
parse_input_event(ievent);
}
-void InputFilter::_axis_event(int p_device, int p_axis, float p_value) {
-
+void Input::_axis_event(int p_device, int p_axis, float p_value) {
Ref<InputEventJoypadMotion> ievent;
ievent.instance();
ievent->set_device(p_device);
@@ -1023,52 +1042,147 @@ void InputFilter::_axis_event(int p_device, int p_axis, float p_value) {
ievent->set_axis_value(p_value);
parse_input_event(ievent);
-};
-
-InputFilter::JoyEvent InputFilter::_find_to_event(String p_to) {
-
- // string names of the SDL buttons in the same order as input_event.h godot buttons
- static const char *buttons[] = { "a", "b", "x", "y", "leftshoulder", "rightshoulder", "lefttrigger", "righttrigger", "leftstick", "rightstick", "back", "start", "dpup", "dpdown", "dpleft", "dpright", "guide", nullptr };
-
- static const char *axis[] = { "leftx", "lefty", "rightx", "righty", nullptr };
+}
- JoyEvent ret;
- ret.type = -1;
- ret.index = 0;
+Input::JoyEvent Input::_get_mapped_button_event(const JoyDeviceMapping &mapping, int p_button) {
+ JoyEvent event;
+ event.type = TYPE_MAX;
+
+ for (int i = 0; i < mapping.bindings.size(); i++) {
+ const JoyBinding binding = mapping.bindings[i];
+ if (binding.inputType == TYPE_BUTTON && binding.input.button == p_button) {
+ event.type = binding.outputType;
+ switch (binding.outputType) {
+ case TYPE_BUTTON:
+ event.index = binding.output.button;
+ return event;
+ case TYPE_AXIS:
+ event.index = binding.output.axis.axis;
+ return event;
+ default:
+ ERR_PRINT_ONCE("Joypad button mapping error.");
+ }
+ }
+ }
+ return event;
+}
- int i = 0;
- while (buttons[i]) {
+Input::JoyEvent Input::_get_mapped_axis_event(const JoyDeviceMapping &mapping, int p_axis, const JoyAxis &p_value) {
+ JoyEvent event;
+ event.type = TYPE_MAX;
- if (p_to == buttons[i]) {
- ret.type = TYPE_BUTTON;
- ret.index = i;
- ret.value = 0;
- return ret;
- };
- ++i;
- };
+ for (int i = 0; i < mapping.bindings.size(); i++) {
+ const JoyBinding binding = mapping.bindings[i];
+ if (binding.inputType == TYPE_AXIS && binding.input.axis.axis == p_axis) {
+ float value = p_value.value;
+ if (binding.input.axis.invert) {
+ value = -value;
+ }
+ if (binding.input.axis.range == FULL_AXIS ||
+ (binding.input.axis.range == POSITIVE_HALF_AXIS && value > 0) ||
+ (binding.input.axis.range == NEGATIVE_HALF_AXIS && value < 0)) {
+ event.type = binding.outputType;
+ switch (binding.outputType) {
+ case TYPE_BUTTON:
+ event.index = binding.output.button;
+ return event;
+ case TYPE_AXIS:
+ event.index = binding.output.axis.axis;
+ event.value = value;
+ if (binding.output.axis.range != binding.input.axis.range) {
+ float shifted_positive_value = 0;
+ switch (binding.input.axis.range) {
+ case POSITIVE_HALF_AXIS:
+ shifted_positive_value = value;
+ break;
+ case NEGATIVE_HALF_AXIS:
+ shifted_positive_value = value + 1;
+ break;
+ case FULL_AXIS:
+ shifted_positive_value = (value + 1) / 2;
+ break;
+ }
+ switch (binding.output.axis.range) {
+ case POSITIVE_HALF_AXIS:
+ event.value = shifted_positive_value;
+ break;
+ case NEGATIVE_HALF_AXIS:
+ event.value = shifted_positive_value - 1;
+ break;
+ case FULL_AXIS:
+ event.value = (shifted_positive_value * 2) - 1;
+ break;
+ }
+ }
+ return event;
+ default:
+ ERR_PRINT_ONCE("Joypad axis mapping error.");
+ }
+ }
+ }
+ }
+ return event;
+}
- i = 0;
- while (axis[i]) {
+void Input::_get_mapped_hat_events(const JoyDeviceMapping &mapping, int p_hat, JoyEvent r_events[]) {
+ for (int i = 0; i < mapping.bindings.size(); i++) {
+ const JoyBinding binding = mapping.bindings[i];
+ if (binding.inputType == TYPE_HAT && binding.input.hat.hat == p_hat) {
+ int index;
+ switch (binding.input.hat.hat_mask) {
+ case HAT_MASK_UP:
+ index = 0;
+ break;
+ case HAT_MASK_RIGHT:
+ index = 1;
+ break;
+ case HAT_MASK_DOWN:
+ index = 2;
+ break;
+ case HAT_MASK_LEFT:
+ index = 3;
+ break;
+ default:
+ ERR_PRINT_ONCE("Joypad button mapping error.");
+ continue;
+ }
- if (p_to == axis[i]) {
- ret.type = TYPE_AXIS;
- ret.index = i;
- ret.value = 0;
- return ret;
- };
- ++i;
- };
+ r_events[index].type = binding.outputType;
+ switch (binding.outputType) {
+ case TYPE_BUTTON:
+ r_events[index].index = binding.output.button;
+ break;
+ case TYPE_AXIS:
+ r_events[index].index = binding.output.axis.axis;
+ break;
+ default:
+ ERR_PRINT_ONCE("Joypad button mapping error.");
+ }
+ }
+ }
+}
- return ret;
-};
+JoyButtonList Input::_get_output_button(String output) {
+ for (int i = 0; _joy_buttons[i]; i++) {
+ if (output == _joy_buttons[i]) {
+ return JoyButtonList(i);
+ }
+ }
+ return JoyButtonList::JOY_INVALID_BUTTON;
+}
-void InputFilter::parse_mapping(String p_mapping) {
+JoyAxisList Input::_get_output_axis(String output) {
+ for (int i = 0; _joy_axes[i]; i++) {
+ if (output == _joy_axes[i]) {
+ return JoyAxisList(i);
+ }
+ }
+ return JoyAxisList::JOY_INVALID_AXIS;
+}
+void Input::parse_mapping(String p_mapping) {
_THREAD_SAFE_METHOD_;
JoyDeviceMapping mapping;
- for (int i = 0; i < HAT_MAX; ++i)
- mapping.hat[i].index = 1024 + i;
Vector<String> entry = p_mapping.split(",");
if (entry.size() < 2) {
@@ -1083,52 +1197,89 @@ void InputFilter::parse_mapping(String p_mapping) {
int idx = 1;
while (++idx < entry.size()) {
-
- if (entry[idx] == "")
+ if (entry[idx] == "") {
continue;
+ }
- String from = entry[idx].get_slice(":", 1).replace(" ", "");
- String to = entry[idx].get_slice(":", 0).replace(" ", "");
+ String output = entry[idx].get_slice(":", 0).replace(" ", "");
+ String input = entry[idx].get_slice(":", 1).replace(" ", "");
+ ERR_CONTINUE_MSG(output.length() < 1 || input.length() < 2,
+ String(entry[idx] + "\nInvalid device mapping entry: " + entry[idx]));
- JoyEvent to_event = _find_to_event(to);
- if (to_event.type == -1)
+ if (output == "platform") {
continue;
+ }
- String etype = from.substr(0, 1);
- if (etype == "a") {
+ JoyAxisRange output_range = FULL_AXIS;
+ if (output[0] == '+' || output[0] == '-') {
+ ERR_CONTINUE_MSG(output.length() < 2, String(entry[idx] + "\nInvalid output: " + entry[idx]));
+ output = output.right(1);
+ if (output[0] == '+') {
+ output_range = POSITIVE_HALF_AXIS;
+ } else if (output[0] == '-') {
+ output_range = NEGATIVE_HALF_AXIS;
+ }
+ }
- int aid = from.substr(1, from.length() - 1).to_int();
- mapping.axis[aid] = to_event;
+ JoyAxisRange input_range = FULL_AXIS;
+ if (input[0] == '+') {
+ input_range = POSITIVE_HALF_AXIS;
+ input = input.right(1);
+ } else if (input[0] == '-') {
+ input_range = NEGATIVE_HALF_AXIS;
+ input = input.right(1);
+ }
+ bool invert_axis = false;
+ if (input[input.length() - 1] == '~') {
+ invert_axis = true;
+ }
- } else if (etype == "b") {
+ JoyButtonList output_button = _get_output_button(output);
+ JoyAxisList output_axis = _get_output_axis(output);
+ ERR_CONTINUE_MSG(output_button == JOY_INVALID_BUTTON && output_axis == JOY_INVALID_AXIS,
+ String(entry[idx] + "\nUnrecognised output string: " + output));
+ ERR_CONTINUE_MSG(output_button != JOY_INVALID_BUTTON && output_axis != JOY_INVALID_AXIS,
+ String("BUG: Output string matched both button and axis: " + output));
+
+ JoyBinding binding;
+ if (output_button != JOY_INVALID_BUTTON) {
+ binding.outputType = TYPE_BUTTON;
+ binding.output.button = output_button;
+ } else if (output_axis != JOY_INVALID_AXIS) {
+ binding.outputType = TYPE_AXIS;
+ binding.output.axis.axis = output_axis;
+ binding.output.axis.range = output_range;
+ }
- int bid = from.substr(1, from.length() - 1).to_int();
- mapping.buttons[bid] = to_event;
+ switch (input[0]) {
+ case 'b':
+ binding.inputType = TYPE_BUTTON;
+ binding.input.button = input.right(1).to_int();
+ break;
+ case 'a':
+ binding.inputType = TYPE_AXIS;
+ binding.input.axis.axis = input.right(1).to_int();
+ binding.input.axis.range = input_range;
+ binding.input.axis.invert = invert_axis;
+ break;
+ case 'h':
+ ERR_CONTINUE_MSG(input.length() != 4 || input[2] != '.',
+ String(entry[idx] + "\nInvalid hat input: " + input));
+ binding.inputType = TYPE_HAT;
+ binding.input.hat.hat = input.substr(1, 1).to_int();
+ binding.input.hat.hat_mask = static_cast<HatMask>(input.right(3).to_int());
+ break;
+ default:
+ ERR_CONTINUE_MSG(true, String(entry[idx] + "\nUnrecognised input string: " + input));
+ }
- } else if (etype == "h") {
+ mapping.bindings.push_back(binding);
+ }
- int hat_value = from.get_slice(".", 1).to_int();
- switch (hat_value) {
- case 1:
- mapping.hat[HAT_UP] = to_event;
- break;
- case 2:
- mapping.hat[HAT_RIGHT] = to_event;
- break;
- case 4:
- mapping.hat[HAT_DOWN] = to_event;
- break;
- case 8:
- mapping.hat[HAT_LEFT] = to_event;
- break;
- };
- };
- };
map_db.push_back(mapping);
- //printf("added mapping with uuid %ls\n", mapping.uid.c_str());
-};
+}
-void InputFilter::add_joy_mapping(String p_mapping, bool p_update_existing) {
+void Input::add_joy_mapping(String p_mapping, bool p_update_existing) {
parse_mapping(p_mapping);
if (p_update_existing) {
Vector<String> entry = p_mapping.split(",");
@@ -1141,7 +1292,7 @@ void InputFilter::add_joy_mapping(String p_mapping, bool p_update_existing) {
}
}
-void InputFilter::remove_joy_mapping(String p_guid) {
+void Input::remove_joy_mapping(String p_guid) {
for (int i = map_db.size() - 1; i >= 0; i--) {
if (p_guid == map_db[i].uid) {
map_db.remove(i);
@@ -1154,8 +1305,7 @@ void InputFilter::remove_joy_mapping(String p_guid) {
}
}
-void InputFilter::set_fallback_mapping(String p_guid) {
-
+void Input::set_fallback_mapping(String p_guid) {
for (int i = 0; i < map_db.size(); i++) {
if (map_db[i].uid == p_guid) {
fallback_mapping = i;
@@ -1165,17 +1315,17 @@ void InputFilter::set_fallback_mapping(String p_guid) {
}
//platforms that use the remapping system can override and call to these ones
-bool InputFilter::is_joy_known(int p_device) {
+bool Input::is_joy_known(int p_device) {
int mapping = joy_names[p_device].mapping;
return mapping != -1 ? (mapping != fallback_mapping) : false;
}
-String InputFilter::get_joy_guid(int p_device) const {
+String Input::get_joy_guid(int p_device) const {
ERR_FAIL_COND_V(!joy_names.has(p_device), "");
return joy_names[p_device].uid;
}
-Array InputFilter::get_connected_joypads() {
+Array Input::get_connected_joypads() {
Array ret;
Map<int, Joypad>::Element *elem = joy_names.front();
while (elem) {
@@ -1187,53 +1337,21 @@ Array InputFilter::get_connected_joypads() {
return ret;
}
-static const char *_buttons[JOY_BUTTON_MAX] = {
- "Face Button Bottom",
- "Face Button Right",
- "Face Button Left",
- "Face Button Top",
- "L",
- "R",
- "L2",
- "R2",
- "L3",
- "R3",
- "Select",
- "Start",
- "DPAD Up",
- "DPAD Down",
- "DPAD Left",
- "DPAD Right"
-};
-
-static const char *_axes[JOY_AXIS_MAX] = {
- "Left Stick X",
- "Left Stick Y",
- "Right Stick X",
- "Right Stick Y",
- "",
- "",
- "L2",
- "R2",
- "",
- ""
-};
-
-String InputFilter::get_joy_button_string(int p_button) {
- ERR_FAIL_INDEX_V(p_button, JOY_BUTTON_MAX, "");
- return _buttons[p_button];
+String Input::get_joy_button_string(int p_button) {
+ ERR_FAIL_INDEX_V(p_button, JOY_BUTTON_MAX, "Invalid button");
+ return _joy_button_names[p_button];
}
-int InputFilter::get_joy_button_index_from_string(String p_button) {
+int Input::get_joy_button_index_from_string(String p_button) {
for (int i = 0; i < JOY_BUTTON_MAX; i++) {
- if (p_button == _buttons[i]) {
+ if (p_button == _joy_button_names[i]) {
return i;
}
}
- ERR_FAIL_V(-1);
+ ERR_FAIL_V(JOY_INVALID_BUTTON);
}
-int InputFilter::get_unused_joy_id() {
+int Input::get_unused_joy_id() {
for (int i = 0; i < JOYPADS_MAX; i++) {
if (!joy_names.has(i) || !joy_names[i].connected) {
return i;
@@ -1242,49 +1360,22 @@ int InputFilter::get_unused_joy_id() {
return -1;
}
-String InputFilter::get_joy_axis_string(int p_axis) {
- ERR_FAIL_INDEX_V(p_axis, JOY_AXIS_MAX, "");
- return _axes[p_axis];
+String Input::get_joy_axis_string(int p_axis) {
+ ERR_FAIL_INDEX_V(p_axis, JOY_AXIS_MAX, "Invalid axis");
+ return _joy_axis_names[p_axis];
}
-int InputFilter::get_joy_axis_index_from_string(String p_axis) {
+int Input::get_joy_axis_index_from_string(String p_axis) {
for (int i = 0; i < JOY_AXIS_MAX; i++) {
- if (p_axis == _axes[i]) {
+ if (p_axis == _joy_axis_names[i]) {
return i;
}
}
- ERR_FAIL_V(-1);
+ ERR_FAIL_V(JOY_INVALID_AXIS);
}
-InputFilter::InputFilter() {
-
+Input::Input() {
singleton = this;
- use_accumulated_input = true;
- mouse_button_mask = 0;
- mouse_window = 0;
- emulate_touch_from_mouse = false;
- emulate_mouse_from_touch = false;
- mouse_from_touch_index = -1;
- event_dispatch_function = nullptr;
- default_shape = CURSOR_ARROW;
-
- hat_map_default[HAT_UP].type = TYPE_BUTTON;
- hat_map_default[HAT_UP].index = JOY_DPAD_UP;
- hat_map_default[HAT_UP].value = 0;
-
- hat_map_default[HAT_RIGHT].type = TYPE_BUTTON;
- hat_map_default[HAT_RIGHT].index = JOY_DPAD_RIGHT;
- hat_map_default[HAT_RIGHT].value = 0;
-
- hat_map_default[HAT_DOWN].type = TYPE_BUTTON;
- hat_map_default[HAT_DOWN].index = JOY_DPAD_DOWN;
- hat_map_default[HAT_DOWN].value = 0;
-
- hat_map_default[HAT_LEFT].type = TYPE_BUTTON;
- hat_map_default[HAT_LEFT].index = JOY_DPAD_LEFT;
- hat_map_default[HAT_LEFT].value = 0;
-
- fallback_mapping = -1;
// Parse default mappings.
{
@@ -1299,8 +1390,9 @@ InputFilter::InputFilter() {
if (env_mapping != "") {
Vector<String> entries = env_mapping.split("\n");
for (int i = 0; i < entries.size(); i++) {
- if (entries[i] == "")
+ if (entries[i] == "") {
continue;
+ }
parse_mapping(entries[i]);
}
}
diff --git a/core/input/input_filter.h b/core/input/input.h
index 908a005228..91e3b83b95 100644
--- a/core/input/input_filter.h
+++ b/core/input/input.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* input_filter.h */
+/* input.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -35,12 +35,11 @@
#include "core/object.h"
#include "core/os/thread_safe.h"
-class InputFilter : public Object {
-
- GDCLASS(InputFilter, Object);
+class Input : public Object {
+ GDCLASS(Input, Object);
_THREAD_SAFE_CLASS_
- static InputFilter *singleton;
+ static Input *singleton;
public:
enum MouseMode {
@@ -100,7 +99,7 @@ public:
typedef void (*EventDispatchFunc)(const Ref<InputEvent> &p_event);
private:
- int mouse_button_mask;
+ int mouse_button_mask = 0;
Set<int> keys_pressed;
Set<int> joy_buttons_pressed;
@@ -111,7 +110,7 @@ private:
Vector3 magnetometer;
Vector3 gyroscope;
Vector2 mouse_pos;
- int64_t mouse_window;
+ int64_t mouse_window = 0;
struct Action {
uint64_t physics_frame;
@@ -122,22 +121,13 @@ private:
Map<StringName, Action> action_state;
- bool emulate_touch_from_mouse;
- bool emulate_mouse_from_touch;
+ bool emulate_touch_from_mouse = false;
+ bool emulate_mouse_from_touch = false;
+ bool use_accumulated_input = false;
- int mouse_from_touch_index;
-
- struct VibrationInfo {
- float weak_magnitude;
- float strong_magnitude;
- float duration; // Duration in seconds
- uint64_t timestamp;
- };
-
- Map<int, VibrationInfo> joy_vibration;
+ int mouse_from_touch_index = -1;
struct SpeedTrack {
-
uint64_t last_tick;
Vector2 speed;
Vector2 accum;
@@ -153,37 +143,21 @@ private:
struct Joypad {
StringName name;
StringName uid;
- bool connected;
- bool last_buttons[JOY_BUTTON_MAX + 19]; //apparently SDL specifies 35 possible buttons on android
- float last_axis[JOY_AXIS_MAX];
- float filter;
- int last_hat;
- int mapping;
- int hat_current;
-
- Joypad() {
- for (int i = 0; i < JOY_AXIS_MAX; i++) {
-
- last_axis[i] = 0.0f;
- }
- for (int i = 0; i < JOY_BUTTON_MAX + 19; i++) {
-
- last_buttons[i] = false;
- }
- connected = false;
- last_hat = HAT_MASK_CENTER;
- filter = 0.01f;
- mapping = -1;
- hat_current = 0;
- }
+ bool connected = false;
+ bool last_buttons[JOY_BUTTON_MAX] = { false };
+ float last_axis[JOY_AXIS_MAX] = { 0.0f };
+ float filter = 0.01f;
+ int last_hat = HAT_MASK_CENTER;
+ int mapping = -1;
+ int hat_current = 0;
};
SpeedTrack mouse_speed_track;
Map<int, SpeedTrack> touch_speed_track;
Map<int, Joypad> joy_names;
- int fallback_mapping;
+ int fallback_mapping = -1;
- CursorShape default_shape;
+ CursorShape default_shape = CURSOR_ARROW;
enum JoyType {
TYPE_BUTTON,
@@ -192,26 +166,61 @@ private:
TYPE_MAX,
};
+ enum JoyAxisRange {
+ NEGATIVE_HALF_AXIS = -1,
+ FULL_AXIS = 0,
+ POSITIVE_HALF_AXIS = 1
+ };
+
struct JoyEvent {
int type;
int index;
- int value;
+ float value;
};
- struct JoyDeviceMapping {
+ struct JoyBinding {
+ JoyType inputType;
+ union {
+ int button;
+
+ struct {
+ int axis;
+ JoyAxisRange range;
+ bool invert;
+ } axis;
+
+ struct {
+ int hat;
+ HatMask hat_mask;
+ } hat;
+ } input;
+
+ JoyType outputType;
+ union {
+ JoyButtonList button;
+
+ struct {
+ JoyAxisList axis;
+ JoyAxisRange range;
+ } axis;
+
+ } output;
+ };
+
+ struct JoyDeviceMapping {
String uid;
String name;
- Map<int, JoyEvent> buttons;
- Map<int, JoyEvent> axis;
- JoyEvent hat[HAT_MAX];
+ Vector<JoyBinding> bindings;
};
- JoyEvent hat_map_default[HAT_MAX];
-
Vector<JoyDeviceMapping> map_db;
- JoyEvent _find_to_event(String p_to);
+ JoyEvent _get_mapped_button_event(const JoyDeviceMapping &mapping, int p_button);
+ JoyEvent _get_mapped_axis_event(const JoyDeviceMapping &mapping, int p_axis, const JoyAxis &p_value);
+ void _get_mapped_hat_events(const JoyDeviceMapping &mapping, int p_hat, JoyEvent r_events[HAT_MAX]);
+ JoyButtonList _get_output_button(String output);
+ JoyAxisList _get_output_axis(String output);
void _button_event(int p_device, int p_index, bool p_pressed);
void _axis_event(int p_device, int p_axis, float p_value);
float _handle_deadzone(int p_device, int p_axis, float p_value);
@@ -219,7 +228,7 @@ private:
void _parse_input_event_impl(const Ref<InputEvent> &p_event, bool p_is_emulated);
List<Ref<InputEvent>> accumulated_events;
- bool use_accumulated_input;
+
friend class DisplayServer;
static void (*set_mouse_mode_func)(MouseMode);
@@ -229,9 +238,18 @@ private:
static CursorShape (*get_current_cursor_shape_func)();
static void (*set_custom_mouse_cursor_func)(const RES &, CursorShape, const Vector2 &);
- EventDispatchFunc event_dispatch_function;
+ EventDispatchFunc event_dispatch_function = nullptr;
protected:
+ struct VibrationInfo {
+ float weak_magnitude;
+ float strong_magnitude;
+ float duration; // Duration in seconds
+ uint64_t timestamp;
+ };
+
+ Map<int, VibrationInfo> joy_vibration;
+
static void _bind_methods();
public:
@@ -239,7 +257,7 @@ public:
MouseMode get_mouse_mode() const;
void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const;
- static InputFilter *get_singleton();
+ static Input *get_singleton();
bool is_key_pressed(int p_keycode) const;
bool is_mouse_button_pressed(int p_button) const;
@@ -299,7 +317,7 @@ public:
CursorShape get_default_cursor_shape() const;
void set_default_cursor_shape(CursorShape p_shape);
CursorShape get_current_cursor_shape() const;
- void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = InputFilter::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
+ void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape = Input::CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
void parse_mapping(String p_mapping);
void joy_button(int p_device, int p_button, bool p_pressed);
@@ -328,10 +346,10 @@ public:
void set_event_dispatch_function(EventDispatchFunc p_function);
- InputFilter();
+ Input();
};
-VARIANT_ENUM_CAST(InputFilter::MouseMode);
-VARIANT_ENUM_CAST(InputFilter::CursorShape);
+VARIANT_ENUM_CAST(Input::MouseMode);
+VARIANT_ENUM_CAST(Input::CursorShape);
#endif // INPUT_H
diff --git a/core/input/input_builders.py b/core/input/input_builders.py
index 53b90f2073..748ec06133 100644
--- a/core/input/input_builders.py
+++ b/core/input/input_builders.py
@@ -42,18 +42,7 @@ def make_default_controller_mappings(target, source, env):
src_path, current_platform, platform_mappings[current_platform][guid]
)
)
- valid_mapping = True
- for input_map in line_parts[2:]:
- if "+" in input_map or "-" in input_map or "~" in input_map:
- g.write(
- "// WARNING - DISCARDED UNSUPPORTED MAPPING TYPE FROM DATABASE {}: {} {}\n".format(
- src_path, current_platform, line
- )
- )
- valid_mapping = False
- break
- if valid_mapping:
- platform_mappings[current_platform][guid] = line
+ platform_mappings[current_platform][guid] = line
platform_variables = {
"Linux": "#if X11_ENABLED",
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index 80219331c0..6ba082f86f 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -45,26 +45,22 @@ int InputEvent::get_device() const {
}
bool InputEvent::is_action(const StringName &p_action) const {
-
return InputMap::get_singleton()->event_is_action(Ref<InputEvent>((InputEvent *)this), p_action);
}
bool InputEvent::is_action_pressed(const StringName &p_action, bool p_allow_echo) const {
-
bool pressed;
bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed);
return valid && pressed && (p_allow_echo || !is_echo());
}
bool InputEvent::is_action_released(const StringName &p_action) const {
-
bool pressed;
bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed);
return valid && !pressed;
}
float InputEvent::get_action_strength(const StringName &p_action) const {
-
bool pressed;
float strength;
bool valid = InputMap::get_singleton()->event_get_action_status(Ref<InputEvent>((InputEvent *)this), p_action, &pressed, &strength);
@@ -72,42 +68,34 @@ float InputEvent::get_action_strength(const StringName &p_action) const {
}
bool InputEvent::is_pressed() const {
-
return false;
}
bool InputEvent::is_echo() const {
-
return false;
}
Ref<InputEvent> InputEvent::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
-
return Ref<InputEvent>((InputEvent *)this);
}
String InputEvent::as_text() const {
-
return String();
}
bool InputEvent::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
-
return false;
}
bool InputEvent::shortcut_match(const Ref<InputEvent> &p_event) const {
-
return false;
}
bool InputEvent::is_action_type() const {
-
return false;
}
void InputEvent::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_device", "device"), &InputEvent::set_device);
ClassDB::bind_method(D_METHOD("get_device"), &InputEvent::get_device);
@@ -132,14 +120,9 @@ void InputEvent::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "device"), "set_device", "get_device");
}
-InputEvent::InputEvent() {
-
- device = 0;
-}
-////////////////
+///////////////////////////////////
void InputEventFromWindow::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_window_id", "id"), &InputEventFromWindow::set_window_id);
ClassDB::bind_method(D_METHOD("get_window_id"), &InputEventFromWindow::get_window_id);
ADD_PROPERTY(PropertyInfo(Variant::INT, "window_id"), "set_window_id", "get_window_id");
@@ -148,64 +131,54 @@ void InputEventFromWindow::_bind_methods() {
void InputEventFromWindow::set_window_id(int64_t p_id) {
window_id = p_id;
}
+
int64_t InputEventFromWindow::get_window_id() const {
return window_id;
}
-InputEventFromWindow::InputEventFromWindow() {
- window_id = 0;
-}
-
-//////////////////
+///////////////////////////////////
void InputEventWithModifiers::set_shift(bool p_enabled) {
-
shift = p_enabled;
}
bool InputEventWithModifiers::get_shift() const {
-
return shift;
}
void InputEventWithModifiers::set_alt(bool p_enabled) {
-
alt = p_enabled;
}
-bool InputEventWithModifiers::get_alt() const {
+bool InputEventWithModifiers::get_alt() const {
return alt;
}
void InputEventWithModifiers::set_control(bool p_enabled) {
-
control = p_enabled;
}
-bool InputEventWithModifiers::get_control() const {
+bool InputEventWithModifiers::get_control() const {
return control;
}
void InputEventWithModifiers::set_metakey(bool p_enabled) {
-
meta = p_enabled;
}
-bool InputEventWithModifiers::get_metakey() const {
+bool InputEventWithModifiers::get_metakey() const {
return meta;
}
void InputEventWithModifiers::set_command(bool p_enabled) {
-
command = p_enabled;
}
-bool InputEventWithModifiers::get_command() const {
+bool InputEventWithModifiers::get_command() const {
return command;
}
void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModifiers *event) {
-
set_alt(event->get_alt());
set_shift(event->get_shift());
set_control(event->get_control());
@@ -213,7 +186,6 @@ void InputEventWithModifiers::set_modifiers_from_event(const InputEventWithModif
}
void InputEventWithModifiers::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_alt", "enable"), &InputEventWithModifiers::set_alt);
ClassDB::bind_method(D_METHOD("get_alt"), &InputEventWithModifiers::get_alt);
@@ -236,101 +208,89 @@ void InputEventWithModifiers::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "command"), "set_command", "get_command");
}
-InputEventWithModifiers::InputEventWithModifiers() {
-
- alt = false;
- shift = false;
- control = false;
- meta = false;
-}
-
-//////////////////////////////////
+///////////////////////////////////
void InputEventKey::set_pressed(bool p_pressed) {
-
pressed = p_pressed;
}
bool InputEventKey::is_pressed() const {
-
return pressed;
}
void InputEventKey::set_keycode(uint32_t p_keycode) {
-
keycode = p_keycode;
}
uint32_t InputEventKey::get_keycode() const {
-
return keycode;
}
void InputEventKey::set_physical_keycode(uint32_t p_keycode) {
-
physical_keycode = p_keycode;
}
uint32_t InputEventKey::get_physical_keycode() const {
-
return physical_keycode;
}
void InputEventKey::set_unicode(uint32_t p_unicode) {
-
unicode = p_unicode;
}
uint32_t InputEventKey::get_unicode() const {
-
return unicode;
}
void InputEventKey::set_echo(bool p_enable) {
-
echo = p_enable;
}
bool InputEventKey::is_echo() const {
-
return echo;
}
uint32_t InputEventKey::get_keycode_with_modifiers() const {
-
uint32_t sc = keycode;
- if (get_control())
+ if (get_control()) {
sc |= KEY_MASK_CTRL;
- if (get_alt())
+ }
+ if (get_alt()) {
sc |= KEY_MASK_ALT;
- if (get_shift())
+ }
+ if (get_shift()) {
sc |= KEY_MASK_SHIFT;
- if (get_metakey())
+ }
+ if (get_metakey()) {
sc |= KEY_MASK_META;
+ }
return sc;
}
uint32_t InputEventKey::get_physical_keycode_with_modifiers() const {
-
uint32_t sc = physical_keycode;
- if (get_control())
+ if (get_control()) {
sc |= KEY_MASK_CTRL;
- if (get_alt())
+ }
+ if (get_alt()) {
sc |= KEY_MASK_ALT;
- if (get_shift())
+ }
+ if (get_shift()) {
sc |= KEY_MASK_SHIFT;
- if (get_metakey())
+ }
+ if (get_metakey()) {
sc |= KEY_MASK_META;
+ }
return sc;
}
String InputEventKey::as_text() const {
-
String kc = keycode_get_string(keycode);
- if (kc == String())
+ if (kc == String()) {
return kc;
+ }
if (get_metakey()) {
kc = find_keycode_name(KEY_META) + ("+" + kc);
@@ -348,10 +308,10 @@ String InputEventKey::as_text() const {
}
bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
-
Ref<InputEventKey> key = p_event;
- if (key.is_null())
+ if (key.is_null()) {
return false;
+ }
bool match = false;
if (get_keycode() == 0) {
@@ -366,19 +326,21 @@ bool InputEventKey::action_match(const Ref<InputEvent> &p_event, bool *p_pressed
match = get_keycode() == key->get_keycode() && (!key->is_pressed() || (code & event_code) == code);
}
if (match) {
- if (p_pressed != nullptr)
+ if (p_pressed != nullptr) {
*p_pressed = key->is_pressed();
- if (p_strength != nullptr)
+ }
+ if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
+ }
}
return match;
}
bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const {
-
Ref<InputEventKey> key = p_event;
- if (key.is_null())
+ if (key.is_null()) {
return false;
+ }
uint32_t code = get_keycode_with_modifiers();
uint32_t event_code = key->get_keycode_with_modifiers();
@@ -387,7 +349,6 @@ bool InputEventKey::shortcut_match(const Ref<InputEvent> &p_event) const {
}
void InputEventKey::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventKey::set_pressed);
ClassDB::bind_method(D_METHOD("set_keycode", "keycode"), &InputEventKey::set_keycode);
@@ -411,46 +372,33 @@ void InputEventKey::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "echo"), "set_echo", "is_echo");
}
-InputEventKey::InputEventKey() {
-
- pressed = false;
- keycode = 0;
- physical_keycode = 0;
- unicode = 0; ///unicode
- echo = false;
-}
-
-////////////////////////////////////////
+///////////////////////////////////
void InputEventMouse::set_button_mask(int p_mask) {
-
button_mask = p_mask;
}
-int InputEventMouse::get_button_mask() const {
+int InputEventMouse::get_button_mask() const {
return button_mask;
}
void InputEventMouse::set_position(const Vector2 &p_pos) {
-
pos = p_pos;
}
-Vector2 InputEventMouse::get_position() const {
+Vector2 InputEventMouse::get_position() const {
return pos;
}
void InputEventMouse::set_global_position(const Vector2 &p_global_pos) {
-
global_pos = p_global_pos;
}
-Vector2 InputEventMouse::get_global_position() const {
+Vector2 InputEventMouse::get_global_position() const {
return global_pos;
}
void InputEventMouse::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_button_mask", "button_mask"), &InputEventMouse::set_button_mask);
ClassDB::bind_method(D_METHOD("get_button_mask"), &InputEventMouse::get_button_mask);
@@ -465,52 +413,41 @@ void InputEventMouse::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position"), "set_global_position", "get_global_position");
}
-InputEventMouse::InputEventMouse() {
-
- button_mask = 0;
-}
-
-///////////////////////////////////////
+///////////////////////////////////
void InputEventMouseButton::set_factor(float p_factor) {
-
factor = p_factor;
}
-float InputEventMouseButton::get_factor() {
-
+float InputEventMouseButton::get_factor() const {
return factor;
}
void InputEventMouseButton::set_button_index(int p_index) {
-
button_index = p_index;
}
-int InputEventMouseButton::get_button_index() const {
+int InputEventMouseButton::get_button_index() const {
return button_index;
}
void InputEventMouseButton::set_pressed(bool p_pressed) {
-
pressed = p_pressed;
}
-bool InputEventMouseButton::is_pressed() const {
+bool InputEventMouseButton::is_pressed() const {
return pressed;
}
void InputEventMouseButton::set_doubleclick(bool p_doubleclick) {
-
doubleclick = p_doubleclick;
}
-bool InputEventMouseButton::is_doubleclick() const {
+bool InputEventMouseButton::is_doubleclick() const {
return doubleclick;
}
Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
-
Vector2 g = get_global_position();
Vector2 l = p_xform.xform(get_position() + p_local_ofs);
@@ -534,24 +471,25 @@ Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, co
}
bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
-
Ref<InputEventMouseButton> mb = p_event;
- if (mb.is_null())
+ if (mb.is_null()) {
return false;
+ }
bool match = mb->button_index == button_index;
if (match) {
- if (p_pressed != nullptr)
+ if (p_pressed != nullptr) {
*p_pressed = mb->is_pressed();
- if (p_strength != nullptr)
+ }
+ if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
+ }
}
return match;
}
String InputEventMouseButton::as_text() const {
-
String button_index_string = "";
switch (get_button_index()) {
case BUTTON_LEFT:
@@ -589,7 +527,6 @@ String InputEventMouseButton::as_text() const {
}
void InputEventMouseButton::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_factor", "factor"), &InputEventMouseButton::set_factor);
ClassDB::bind_method(D_METHOD("get_factor"), &InputEventMouseButton::get_factor);
@@ -608,58 +545,41 @@ void InputEventMouseButton::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "doubleclick"), "set_doubleclick", "is_doubleclick");
}
-InputEventMouseButton::InputEventMouseButton() {
-
- factor = 1;
- button_index = 0;
- pressed = false;
- doubleclick = false;
-}
-
-////////////////////////////////////////////
+///////////////////////////////////
void InputEventMouseMotion::set_tilt(const Vector2 &p_tilt) {
-
tilt = p_tilt;
}
Vector2 InputEventMouseMotion::get_tilt() const {
-
return tilt;
}
void InputEventMouseMotion::set_pressure(float p_pressure) {
-
pressure = p_pressure;
}
float InputEventMouseMotion::get_pressure() const {
-
return pressure;
}
void InputEventMouseMotion::set_relative(const Vector2 &p_relative) {
-
relative = p_relative;
}
Vector2 InputEventMouseMotion::get_relative() const {
-
return relative;
}
void InputEventMouseMotion::set_speed(const Vector2 &p_speed) {
-
speed = p_speed;
}
Vector2 InputEventMouseMotion::get_speed() const {
-
return speed;
}
Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
-
Vector2 g = get_global_position();
Vector2 l = p_xform.xform(get_position() + p_local_ofs);
Vector2 r = p_xform.basis_xform(get_relative());
@@ -686,7 +606,6 @@ Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, co
}
String InputEventMouseMotion::as_text() const {
-
String button_mask_string = "";
switch (get_button_mask()) {
case BUTTON_MASK_LEFT:
@@ -708,14 +627,14 @@ String InputEventMouseMotion::as_text() const {
button_mask_string = itos(get_button_mask());
break;
}
- return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")";
+ return "InputEventMouseMotion : button_mask=" + button_mask_string + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + "), pressure=(" + rtos(get_pressure()) + "), tilt=(" + String(get_tilt()) + ")";
}
bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseMotion> motion = p_event;
- if (motion.is_null())
+ if (motion.is_null()) {
return false;
+ }
if (get_window_id() != motion->get_window_id()) {
return false;
@@ -754,7 +673,6 @@ bool InputEventMouseMotion::accumulate(const Ref<InputEvent> &p_event) {
}
void InputEventMouseMotion::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_tilt", "tilt"), &InputEventMouseMotion::set_tilt);
ClassDB::bind_method(D_METHOD("get_tilt"), &InputEventMouseMotion::get_tilt);
@@ -773,50 +691,41 @@ void InputEventMouseMotion::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed");
}
-InputEventMouseMotion::InputEventMouseMotion() {
-
- pressure = 0;
-}
-
-////////////////////////////////////////
+///////////////////////////////////
void InputEventJoypadMotion::set_axis(int p_axis) {
-
axis = p_axis;
}
int InputEventJoypadMotion::get_axis() const {
-
return axis;
}
void InputEventJoypadMotion::set_axis_value(float p_value) {
-
axis_value = p_value;
}
float InputEventJoypadMotion::get_axis_value() const {
-
return axis_value;
}
bool InputEventJoypadMotion::is_pressed() const {
-
return Math::abs(axis_value) >= 0.5f;
}
bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
-
Ref<InputEventJoypadMotion> jm = p_event;
- if (jm.is_null())
+ if (jm.is_null()) {
return false;
+ }
bool match = (axis == jm->axis); // Matches even if not in the same direction, but returns a "not pressed" event.
if (match) {
bool same_direction = (((axis_value < 0) == (jm->axis_value < 0)) || jm->axis_value == 0);
bool pressed = same_direction ? Math::abs(jm->get_axis_value()) >= p_deadzone : false;
- if (p_pressed != nullptr)
+ if (p_pressed != nullptr) {
*p_pressed = pressed;
+ }
if (p_strength != nullptr) {
if (pressed) {
if (p_deadzone == 1.0f) {
@@ -833,12 +742,10 @@ bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event, bool *
}
String InputEventJoypadMotion::as_text() const {
-
return "InputEventJoypadMotion : axis=" + itos(axis) + ", axis_value=" + String(Variant(axis_value));
}
void InputEventJoypadMotion::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_axis", "axis"), &InputEventJoypadMotion::set_axis);
ClassDB::bind_method(D_METHOD("get_axis"), &InputEventJoypadMotion::get_axis);
@@ -849,74 +756,65 @@ void InputEventJoypadMotion::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "axis_value"), "set_axis_value", "get_axis_value");
}
-InputEventJoypadMotion::InputEventJoypadMotion() {
-
- axis = 0;
- axis_value = 0;
-}
-/////////////////////////////////
+///////////////////////////////////
void InputEventJoypadButton::set_button_index(int p_index) {
-
button_index = p_index;
}
int InputEventJoypadButton::get_button_index() const {
-
return button_index;
}
void InputEventJoypadButton::set_pressed(bool p_pressed) {
-
pressed = p_pressed;
}
-bool InputEventJoypadButton::is_pressed() const {
+bool InputEventJoypadButton::is_pressed() const {
return pressed;
}
void InputEventJoypadButton::set_pressure(float p_pressure) {
-
pressure = p_pressure;
}
-float InputEventJoypadButton::get_pressure() const {
+float InputEventJoypadButton::get_pressure() const {
return pressure;
}
bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
-
Ref<InputEventJoypadButton> jb = p_event;
- if (jb.is_null())
+ if (jb.is_null()) {
return false;
+ }
bool match = button_index == jb->button_index;
if (match) {
- if (p_pressed != nullptr)
+ if (p_pressed != nullptr) {
*p_pressed = jb->is_pressed();
- if (p_strength != nullptr)
+ }
+ if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
+ }
}
return match;
}
bool InputEventJoypadButton::shortcut_match(const Ref<InputEvent> &p_event) const {
-
Ref<InputEventJoypadButton> button = p_event;
- if (button.is_null())
+ if (button.is_null()) {
return false;
+ }
return button_index == button->button_index;
}
String InputEventJoypadButton::as_text() const {
-
return "InputEventJoypadButton : button_index=" + itos(button_index) + ", pressed=" + (pressed ? "true" : "false") + ", pressure=" + String(Variant(pressure));
}
void InputEventJoypadButton::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_button_index", "button_index"), &InputEventJoypadButton::set_button_index);
ClassDB::bind_method(D_METHOD("get_button_index"), &InputEventJoypadButton::get_button_index);
@@ -931,44 +829,33 @@ void InputEventJoypadButton::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
}
-InputEventJoypadButton::InputEventJoypadButton() {
-
- button_index = 0;
- pressure = 0;
- pressed = false;
-}
-
-//////////////////////////////////////////////
+///////////////////////////////////
void InputEventScreenTouch::set_index(int p_index) {
-
index = p_index;
}
-int InputEventScreenTouch::get_index() const {
+int InputEventScreenTouch::get_index() const {
return index;
}
void InputEventScreenTouch::set_position(const Vector2 &p_pos) {
-
pos = p_pos;
}
-Vector2 InputEventScreenTouch::get_position() const {
+Vector2 InputEventScreenTouch::get_position() const {
return pos;
}
void InputEventScreenTouch::set_pressed(bool p_pressed) {
-
pressed = p_pressed;
}
-bool InputEventScreenTouch::is_pressed() const {
+bool InputEventScreenTouch::is_pressed() const {
return pressed;
}
Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
-
Ref<InputEventScreenTouch> st;
st.instance();
st->set_device(get_device());
@@ -981,12 +868,10 @@ Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, co
}
String InputEventScreenTouch::as_text() const {
-
return "InputEventScreenTouch : index=" + itos(index) + ", pressed=" + (pressed ? "true" : "false") + ", position=(" + String(get_position()) + ")";
}
void InputEventScreenTouch::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenTouch::set_index);
ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenTouch::get_index);
@@ -1001,53 +886,41 @@ void InputEventScreenTouch::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
}
-InputEventScreenTouch::InputEventScreenTouch() {
-
- index = 0;
- pressed = false;
-}
-
-/////////////////////////////
+///////////////////////////////////
void InputEventScreenDrag::set_index(int p_index) {
-
index = p_index;
}
int InputEventScreenDrag::get_index() const {
-
return index;
}
void InputEventScreenDrag::set_position(const Vector2 &p_pos) {
-
pos = p_pos;
}
-Vector2 InputEventScreenDrag::get_position() const {
+Vector2 InputEventScreenDrag::get_position() const {
return pos;
}
void InputEventScreenDrag::set_relative(const Vector2 &p_relative) {
-
relative = p_relative;
}
-Vector2 InputEventScreenDrag::get_relative() const {
+Vector2 InputEventScreenDrag::get_relative() const {
return relative;
}
void InputEventScreenDrag::set_speed(const Vector2 &p_speed) {
-
speed = p_speed;
}
-Vector2 InputEventScreenDrag::get_speed() const {
+Vector2 InputEventScreenDrag::get_speed() const {
return speed;
}
Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
-
Ref<InputEventScreenDrag> sd;
sd.instance();
@@ -1064,12 +937,10 @@ Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, con
}
String InputEventScreenDrag::as_text() const {
-
return "InputEventScreenDrag : index=" + itos(index) + ", position=(" + String(get_position()) + "), relative=(" + String(get_relative()) + "), speed=(" + String(get_speed()) + ")";
}
void InputEventScreenDrag::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenDrag::set_index);
ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenDrag::get_index);
@@ -1088,27 +959,21 @@ void InputEventScreenDrag::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed");
}
-InputEventScreenDrag::InputEventScreenDrag() {
-
- index = 0;
-}
-/////////////////////////////
+///////////////////////////////////
void InputEventAction::set_action(const StringName &p_action) {
-
action = p_action;
}
-StringName InputEventAction::get_action() const {
+StringName InputEventAction::get_action() const {
return action;
}
void InputEventAction::set_pressed(bool p_pressed) {
-
pressed = p_pressed;
}
-bool InputEventAction::is_pressed() const {
+bool InputEventAction::is_pressed() const {
return pressed;
}
@@ -1121,40 +986,40 @@ float InputEventAction::get_strength() const {
}
bool InputEventAction::shortcut_match(const Ref<InputEvent> &p_event) const {
- if (p_event.is_null())
+ if (p_event.is_null()) {
return false;
+ }
return p_event->is_action(action);
}
bool InputEventAction::is_action(const StringName &p_action) const {
-
return action == p_action;
}
bool InputEventAction::action_match(const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength, float p_deadzone) const {
-
Ref<InputEventAction> act = p_event;
- if (act.is_null())
+ if (act.is_null()) {
return false;
+ }
bool match = action == act->action;
if (match) {
- if (p_pressed != nullptr)
+ if (p_pressed != nullptr) {
*p_pressed = act->pressed;
- if (p_strength != nullptr)
+ }
+ if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? 1.0f : 0.0f;
+ }
}
return match;
}
String InputEventAction::as_text() const {
-
return "InputEventAction : action=" + action + ", pressed=(" + (pressed ? "true" : "false");
}
void InputEventAction::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_action", "action"), &InputEventAction::set_action);
ClassDB::bind_method(D_METHOD("get_action"), &InputEventAction::get_action);
@@ -1171,19 +1036,13 @@ void InputEventAction::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "strength", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_strength", "get_strength");
}
-InputEventAction::InputEventAction() {
- pressed = false;
- strength = 1.0f;
-}
-/////////////////////////////
+///////////////////////////////////
void InputEventGesture::set_position(const Vector2 &p_pos) {
-
pos = p_pos;
}
void InputEventGesture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventGesture::set_position);
ClassDB::bind_method(D_METHOD("get_position"), &InputEventGesture::get_position);
@@ -1191,23 +1050,20 @@ void InputEventGesture::_bind_methods() {
}
Vector2 InputEventGesture::get_position() const {
-
return pos;
}
-/////////////////////////////
-void InputEventMagnifyGesture::set_factor(real_t p_factor) {
+///////////////////////////////////
+void InputEventMagnifyGesture::set_factor(real_t p_factor) {
factor = p_factor;
}
real_t InputEventMagnifyGesture::get_factor() const {
-
return factor;
}
Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
-
Ref<InputEventMagnifyGesture> ev;
ev.instance();
@@ -1223,26 +1079,19 @@ Ref<InputEvent> InputEventMagnifyGesture::xformed_by(const Transform2D &p_xform,
}
String InputEventMagnifyGesture::as_text() const {
-
return "InputEventMagnifyGesture : factor=" + rtos(get_factor()) + ", position=(" + String(get_position()) + ")";
}
void InputEventMagnifyGesture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_factor", "factor"), &InputEventMagnifyGesture::set_factor);
ClassDB::bind_method(D_METHOD("get_factor"), &InputEventMagnifyGesture::get_factor);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "factor"), "set_factor", "get_factor");
}
-InputEventMagnifyGesture::InputEventMagnifyGesture() {
-
- factor = 1.0;
-}
-/////////////////////////////
+///////////////////////////////////
void InputEventPanGesture::set_delta(const Vector2 &p_delta) {
-
delta = p_delta;
}
@@ -1251,7 +1100,6 @@ Vector2 InputEventPanGesture::get_delta() const {
}
Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
-
Ref<InputEventPanGesture> ev;
ev.instance();
@@ -1267,26 +1115,19 @@ Ref<InputEvent> InputEventPanGesture::xformed_by(const Transform2D &p_xform, con
}
String InputEventPanGesture::as_text() const {
-
return "InputEventPanGesture : delta=(" + String(get_delta()) + "), position=(" + String(get_position()) + ")";
}
void InputEventPanGesture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_delta", "delta"), &InputEventPanGesture::set_delta);
ClassDB::bind_method(D_METHOD("get_delta"), &InputEventPanGesture::get_delta);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "delta"), "set_delta", "get_delta");
}
-InputEventPanGesture::InputEventPanGesture() {
-
- delta = Vector2(0, 0);
-}
-/////////////////////////////
+///////////////////////////////////
void InputEventMIDI::set_channel(const int p_channel) {
-
channel = p_channel;
}
@@ -1295,7 +1136,6 @@ int InputEventMIDI::get_channel() const {
}
void InputEventMIDI::set_message(const int p_message) {
-
message = p_message;
}
@@ -1304,7 +1144,6 @@ int InputEventMIDI::get_message() const {
}
void InputEventMIDI::set_pitch(const int p_pitch) {
-
pitch = p_pitch;
}
@@ -1313,7 +1152,6 @@ int InputEventMIDI::get_pitch() const {
}
void InputEventMIDI::set_velocity(const int p_velocity) {
-
velocity = p_velocity;
}
@@ -1322,7 +1160,6 @@ int InputEventMIDI::get_velocity() const {
}
void InputEventMIDI::set_instrument(const int p_instrument) {
-
instrument = p_instrument;
}
@@ -1331,7 +1168,6 @@ int InputEventMIDI::get_instrument() const {
}
void InputEventMIDI::set_pressure(const int p_pressure) {
-
pressure = p_pressure;
}
@@ -1340,7 +1176,6 @@ int InputEventMIDI::get_pressure() const {
}
void InputEventMIDI::set_controller_number(const int p_controller_number) {
-
controller_number = p_controller_number;
}
@@ -1349,7 +1184,6 @@ int InputEventMIDI::get_controller_number() const {
}
void InputEventMIDI::set_controller_value(const int p_controller_value) {
-
controller_value = p_controller_value;
}
@@ -1358,12 +1192,10 @@ int InputEventMIDI::get_controller_value() const {
}
String InputEventMIDI::as_text() const {
-
return "InputEventMIDI : channel=(" + itos(get_channel()) + "), message=(" + itos(get_message()) + ")";
}
void InputEventMIDI::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_channel", "channel"), &InputEventMIDI::set_channel);
ClassDB::bind_method(D_METHOD("get_channel"), &InputEventMIDI::get_channel);
ClassDB::bind_method(D_METHOD("set_message", "message"), &InputEventMIDI::set_message);
@@ -1390,15 +1222,3 @@ void InputEventMIDI::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_number"), "set_controller_number", "get_controller_number");
ADD_PROPERTY(PropertyInfo(Variant::INT, "controller_value"), "set_controller_value", "get_controller_value");
}
-
-InputEventMIDI::InputEventMIDI() {
-
- channel = 0;
- message = 0;
- pitch = 0;
- velocity = 0;
- instrument = 0;
- pressure = 0;
- controller_number = 0;
- controller_value = 0;
-}
diff --git a/core/input/input_event.h b/core/input/input_event.h
index 2fdcdd0319..dd1cc11982 100644
--- a/core/input/input_event.h
+++ b/core/input/input_event.h
@@ -59,98 +59,84 @@ enum ButtonList {
BUTTON_MASK_XBUTTON2 = (1 << (BUTTON_XBUTTON2 - 1))
};
-enum JoystickList {
-
- JOY_BUTTON_0 = 0,
- JOY_BUTTON_1 = 1,
- JOY_BUTTON_2 = 2,
- JOY_BUTTON_3 = 3,
- JOY_BUTTON_4 = 4,
- JOY_BUTTON_5 = 5,
- JOY_BUTTON_6 = 6,
- JOY_BUTTON_7 = 7,
- JOY_BUTTON_8 = 8,
- JOY_BUTTON_9 = 9,
- JOY_BUTTON_10 = 10,
- JOY_BUTTON_11 = 11,
- JOY_BUTTON_12 = 12,
- JOY_BUTTON_13 = 13,
- JOY_BUTTON_14 = 14,
- JOY_BUTTON_15 = 15,
- JOY_BUTTON_MAX = 16,
-
- JOY_L = JOY_BUTTON_4,
- JOY_R = JOY_BUTTON_5,
- JOY_L2 = JOY_BUTTON_6,
- JOY_R2 = JOY_BUTTON_7,
- JOY_L3 = JOY_BUTTON_8,
- JOY_R3 = JOY_BUTTON_9,
- JOY_SELECT = JOY_BUTTON_10,
- JOY_START = JOY_BUTTON_11,
- JOY_DPAD_UP = JOY_BUTTON_12,
- JOY_DPAD_DOWN = JOY_BUTTON_13,
- JOY_DPAD_LEFT = JOY_BUTTON_14,
- JOY_DPAD_RIGHT = JOY_BUTTON_15,
-
- JOY_SONY_CIRCLE = JOY_BUTTON_1,
- JOY_SONY_X = JOY_BUTTON_0,
- JOY_SONY_SQUARE = JOY_BUTTON_2,
- JOY_SONY_TRIANGLE = JOY_BUTTON_3,
-
- JOY_XBOX_A = JOY_BUTTON_0,
- JOY_XBOX_B = JOY_BUTTON_1,
- JOY_XBOX_X = JOY_BUTTON_2,
- JOY_XBOX_Y = JOY_BUTTON_3,
-
- JOY_DS_A = JOY_BUTTON_1,
- JOY_DS_B = JOY_BUTTON_0,
- JOY_DS_X = JOY_BUTTON_3,
- JOY_DS_Y = JOY_BUTTON_2,
-
- JOY_WII_C = JOY_BUTTON_5,
- JOY_WII_Z = JOY_BUTTON_6,
-
- JOY_WII_MINUS = JOY_BUTTON_10,
- JOY_WII_PLUS = JOY_BUTTON_11,
-
- JOY_VR_GRIP = JOY_BUTTON_2,
- JOY_VR_PAD = JOY_BUTTON_14,
- JOY_VR_TRIGGER = JOY_BUTTON_15,
-
- JOY_OCULUS_AX = JOY_BUTTON_7,
- JOY_OCULUS_BY = JOY_BUTTON_1,
- JOY_OCULUS_MENU = JOY_BUTTON_3,
-
- JOY_OPENVR_MENU = JOY_BUTTON_1,
-
- // end of history
-
- JOY_AXIS_0 = 0,
- JOY_AXIS_1 = 1,
- JOY_AXIS_2 = 2,
- JOY_AXIS_3 = 3,
- JOY_AXIS_4 = 4,
- JOY_AXIS_5 = 5,
- JOY_AXIS_6 = 6,
- JOY_AXIS_7 = 7,
- JOY_AXIS_8 = 8,
- JOY_AXIS_9 = 9,
- JOY_AXIS_MAX = 10,
-
- JOY_ANALOG_LX = JOY_AXIS_0,
- JOY_ANALOG_LY = JOY_AXIS_1,
-
- JOY_ANALOG_RX = JOY_AXIS_2,
- JOY_ANALOG_RY = JOY_AXIS_3,
-
- JOY_ANALOG_L2 = JOY_AXIS_6,
- JOY_ANALOG_R2 = JOY_AXIS_7,
-
- JOY_VR_ANALOG_TRIGGER = JOY_AXIS_2,
- JOY_VR_ANALOG_GRIP = JOY_AXIS_4,
-
- JOY_OPENVR_TOUCHPADX = JOY_AXIS_0,
- JOY_OPENVR_TOUCHPADY = JOY_AXIS_1,
+enum JoyButtonList {
+
+ JOY_INVALID_BUTTON = -1,
+
+ // SDL Buttons
+ JOY_BUTTON_A = 0,
+ JOY_BUTTON_B = 1,
+ JOY_BUTTON_X = 2,
+ JOY_BUTTON_Y = 3,
+ JOY_BUTTON_BACK = 4,
+ JOY_BUTTON_GUIDE = 5,
+ JOY_BUTTON_START = 6,
+ JOY_BUTTON_LEFT_STICK = 7,
+ JOY_BUTTON_RIGHT_STICK = 8,
+ JOY_BUTTON_LEFT_SHOULDER = 9,
+ JOY_BUTTON_RIGHT_SHOULDER = 10,
+ JOY_BUTTON_DPAD_UP = 11,
+ JOY_BUTTON_DPAD_DOWN = 12,
+ JOY_BUTTON_DPAD_LEFT = 13,
+ JOY_BUTTON_DPAD_RIGHT = 14,
+ JOY_SDL_BUTTONS = 15,
+
+ // Sony Buttons
+ JOY_SONY_X = JOY_BUTTON_A,
+ JOY_SONY_CROSS = JOY_BUTTON_A,
+ JOY_SONY_CIRCLE = JOY_BUTTON_B,
+ JOY_SONY_SQUARE = JOY_BUTTON_X,
+ JOY_SONY_TRIANGLE = JOY_BUTTON_Y,
+ JOY_SONY_SELECT = JOY_BUTTON_BACK,
+ JOY_SONY_START = JOY_BUTTON_START,
+ JOY_SONY_PS = JOY_BUTTON_GUIDE,
+ JOY_SONY_L1 = JOY_BUTTON_LEFT_SHOULDER,
+ JOY_SONY_R1 = JOY_BUTTON_RIGHT_SHOULDER,
+ JOY_SONY_L3 = JOY_BUTTON_LEFT_STICK,
+ JOY_SONY_R3 = JOY_BUTTON_RIGHT_STICK,
+
+ // Xbox Buttons
+ JOY_XBOX_A = JOY_BUTTON_A,
+ JOY_XBOX_B = JOY_BUTTON_B,
+ JOY_XBOX_X = JOY_BUTTON_X,
+ JOY_XBOX_Y = JOY_BUTTON_Y,
+ JOY_XBOX_BACK = JOY_BUTTON_BACK,
+ JOY_XBOX_START = JOY_BUTTON_START,
+ JOY_XBOX_HOME = JOY_BUTTON_GUIDE,
+ JOY_XBOX_LS = JOY_BUTTON_LEFT_STICK,
+ JOY_XBOX_RS = JOY_BUTTON_RIGHT_STICK,
+ JOY_XBOX_LB = JOY_BUTTON_LEFT_SHOULDER,
+ JOY_XBOX_RB = JOY_BUTTON_RIGHT_SHOULDER,
+
+ JOY_BUTTON_MAX = 36 // Apparently Android supports up to 36 buttons.
+};
+
+enum JoyAxisList {
+
+ JOY_INVALID_AXIS = -1,
+
+ // SDL Axes
+ JOY_AXIS_LEFT_X = 0,
+ JOY_AXIS_LEFT_Y = 1,
+ JOY_AXIS_RIGHT_X = 2,
+ JOY_AXIS_RIGHT_Y = 3,
+ JOY_AXIS_TRIGGER_LEFT = 4,
+ JOY_AXIS_TRIGGER_RIGHT = 5,
+ JOY_SDL_AXES = 6,
+
+ // Joystick axes.
+ JOY_AXIS_0_X = 0,
+ JOY_AXIS_0_Y = 1,
+ JOY_AXIS_1_X = 2,
+ JOY_AXIS_1_Y = 3,
+ JOY_AXIS_2_X = 4,
+ JOY_AXIS_2_Y = 5,
+ JOY_AXIS_3_X = 6,
+ JOY_AXIS_3_Y = 7,
+ JOY_AXIS_4_X = 8,
+ JOY_AXIS_4_Y = 9,
+
+ JOY_AXIS_MAX = 10 // OpenVR supports up to 5 Joysticks making a total of 10 axes.
};
enum MidiMessageList {
@@ -171,7 +157,7 @@ enum MidiMessageList {
class InputEvent : public Resource {
GDCLASS(InputEvent, Resource);
- int device;
+ int device = 0;
protected:
static void _bind_methods();
@@ -191,7 +177,6 @@ public:
// To be removed someday, since they do not make sense for all events
virtual bool is_pressed() const;
virtual bool is_echo() const;
- // ...-.
virtual String as_text() const;
@@ -202,14 +187,14 @@ public:
virtual bool is_action_type() const;
virtual bool accumulate(const Ref<InputEvent> &p_event) { return false; }
- InputEvent();
+
+ InputEvent() {}
};
class InputEventFromWindow : public InputEvent {
-
GDCLASS(InputEventFromWindow, InputEvent);
- int64_t window_id;
+ int64_t window_id = 0;
protected:
static void _bind_methods();
@@ -218,28 +203,27 @@ public:
void set_window_id(int64_t p_id);
int64_t get_window_id() const;
- InputEventFromWindow();
+ InputEventFromWindow() {}
};
class InputEventWithModifiers : public InputEventFromWindow {
GDCLASS(InputEventWithModifiers, InputEventFromWindow);
- bool shift;
- bool alt;
+ bool shift = false;
+ bool alt = false;
#ifdef APPLE_STYLE_KEYS
union {
bool command;
- bool meta; //< windows/mac key
+ bool meta = false; //< windows/mac key
};
- bool control;
+ bool control = false;
#else
union {
bool command; //< windows/mac key
- bool control;
+ bool control = false;
};
- bool meta; //< windows/mac key
-
+ bool meta = false; //< windows/mac key
#endif
protected:
@@ -263,20 +247,19 @@ public:
void set_modifiers_from_event(const InputEventWithModifiers *event);
- InputEventWithModifiers();
+ InputEventWithModifiers() {}
};
class InputEventKey : public InputEventWithModifiers {
-
GDCLASS(InputEventKey, InputEventWithModifiers);
- bool pressed; /// otherwise release
+ bool pressed = false; /// otherwise release
- uint32_t keycode; ///< check keyboard.h , KeyCode enum, without modifier masks
- uint32_t physical_keycode;
- uint32_t unicode; ///unicode
+ uint32_t keycode = 0; ///< check keyboard.h , KeyCode enum, without modifier masks
+ uint32_t physical_keycode = 0;
+ uint32_t unicode = 0; ///unicode
- bool echo; /// true if this is an echo key
+ bool echo = false; /// true if this is an echo key
protected:
static void _bind_methods();
@@ -307,14 +290,13 @@ public:
virtual String as_text() const;
- InputEventKey();
+ InputEventKey() {}
};
class InputEventMouse : public InputEventWithModifiers {
-
GDCLASS(InputEventMouse, InputEventWithModifiers);
- int button_mask;
+ int button_mask = 0;
Vector2 pos;
Vector2 global_pos;
@@ -332,24 +314,23 @@ public:
void set_global_position(const Vector2 &p_global_pos);
Vector2 get_global_position() const;
- InputEventMouse();
+ InputEventMouse() {}
};
class InputEventMouseButton : public InputEventMouse {
-
GDCLASS(InputEventMouseButton, InputEventMouse);
- float factor;
- int button_index;
- bool pressed; //otherwise released
- bool doubleclick; //last even less than doubleclick time
+ float factor = 1;
+ int button_index = 0;
+ bool pressed = false; //otherwise released
+ bool doubleclick = false; //last even less than doubleclick time
protected:
static void _bind_methods();
public:
void set_factor(float p_factor);
- float get_factor();
+ float get_factor() const;
void set_button_index(int p_index);
int get_button_index() const;
@@ -366,15 +347,14 @@ public:
virtual bool is_action_type() const { return true; }
virtual String as_text() const;
- InputEventMouseButton();
+ InputEventMouseButton() {}
};
class InputEventMouseMotion : public InputEventMouse {
-
GDCLASS(InputEventMouseMotion, InputEventMouse);
Vector2 tilt;
- float pressure;
+ float pressure = 0;
Vector2 relative;
Vector2 speed;
@@ -399,14 +379,13 @@ public:
virtual bool accumulate(const Ref<InputEvent> &p_event);
- InputEventMouseMotion();
+ InputEventMouseMotion() {}
};
class InputEventJoypadMotion : public InputEvent {
-
GDCLASS(InputEventJoypadMotion, InputEvent);
- int axis; ///< Joypad axis
- float axis_value; ///< -1 to 1
+ int axis = 0; ///< Joypad axis
+ float axis_value = 0; ///< -1 to 1
protected:
static void _bind_methods();
@@ -425,15 +404,15 @@ public:
virtual bool is_action_type() const { return true; }
virtual String as_text() const;
- InputEventJoypadMotion();
+ InputEventJoypadMotion() {}
};
class InputEventJoypadButton : public InputEvent {
GDCLASS(InputEventJoypadButton, InputEvent);
- int button_index;
- bool pressed;
- float pressure; //0 to 1
+ int button_index = 0;
+ bool pressed = false;
+ float pressure = 0; //0 to 1
protected:
static void _bind_methods();
@@ -453,14 +432,14 @@ public:
virtual bool is_action_type() const { return true; }
virtual String as_text() const;
- InputEventJoypadButton();
+ InputEventJoypadButton() {}
};
class InputEventScreenTouch : public InputEventFromWindow {
GDCLASS(InputEventScreenTouch, InputEventFromWindow);
- int index;
+ int index = 0;
Vector2 pos;
- bool pressed;
+ bool pressed = false;
protected:
static void _bind_methods();
@@ -478,13 +457,12 @@ public:
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
virtual String as_text() const;
- InputEventScreenTouch();
+ InputEventScreenTouch() {}
};
class InputEventScreenDrag : public InputEventFromWindow {
-
GDCLASS(InputEventScreenDrag, InputEventFromWindow);
- int index;
+ int index = 0;
Vector2 pos;
Vector2 relative;
Vector2 speed;
@@ -508,16 +486,15 @@ public:
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
virtual String as_text() const;
- InputEventScreenDrag();
+ InputEventScreenDrag() {}
};
class InputEventAction : public InputEvent {
-
GDCLASS(InputEventAction, InputEvent);
StringName action;
- bool pressed;
- float strength;
+ bool pressed = false;
+ float strength = 1.0f;
protected:
static void _bind_methods();
@@ -540,11 +517,10 @@ public:
virtual bool is_action_type() const { return true; }
virtual String as_text() const;
- InputEventAction();
+ InputEventAction() {}
};
class InputEventGesture : public InputEventWithModifiers {
-
GDCLASS(InputEventGesture, InputEventWithModifiers);
Vector2 pos;
@@ -558,9 +534,8 @@ public:
};
class InputEventMagnifyGesture : public InputEventGesture {
-
GDCLASS(InputEventMagnifyGesture, InputEventGesture);
- real_t factor;
+ real_t factor = 1.0;
protected:
static void _bind_methods();
@@ -572,11 +547,10 @@ public:
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
virtual String as_text() const;
- InputEventMagnifyGesture();
+ InputEventMagnifyGesture() {}
};
class InputEventPanGesture : public InputEventGesture {
-
GDCLASS(InputEventPanGesture, InputEventGesture);
Vector2 delta;
@@ -590,20 +564,20 @@ public:
virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
virtual String as_text() const;
- InputEventPanGesture();
+ InputEventPanGesture() {}
};
class InputEventMIDI : public InputEvent {
GDCLASS(InputEventMIDI, InputEvent);
- int channel;
- int message;
- int pitch;
- int velocity;
- int instrument;
- int pressure;
- int controller_number;
- int controller_value;
+ int channel = 0;
+ int message = 0;
+ int pitch = 0;
+ int velocity = 0;
+ int instrument = 0;
+ int pressure = 0;
+ int controller_number = 0;
+ int controller_value = 0;
protected:
static void _bind_methods();
@@ -635,7 +609,7 @@ public:
virtual String as_text() const;
- InputEventMIDI();
+ InputEventMIDI() {}
};
#endif // INPUT_EVENT_H
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index 6b6acf062d..3cb4b43a26 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -38,7 +38,6 @@ InputMap *InputMap::singleton = nullptr;
int InputMap::ALL_DEVICES = -1;
void InputMap::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("has_action", "action"), &InputMap::has_action);
ClassDB::bind_method(D_METHOD("get_actions"), &InputMap::_get_actions);
ClassDB::bind_method(D_METHOD("add_action", "action", "deadzone"), &InputMap::add_action, DEFVAL(0.5f));
@@ -55,7 +54,6 @@ void InputMap::_bind_methods() {
}
void InputMap::add_action(const StringName &p_action, float p_deadzone) {
-
ERR_FAIL_COND_MSG(input_map.has(p_action), "InputMap already has action '" + String(p_action) + "'.");
input_map[p_action] = Action();
static int last_id = 1;
@@ -65,20 +63,18 @@ void InputMap::add_action(const StringName &p_action, float p_deadzone) {
}
void InputMap::erase_action(const StringName &p_action) {
-
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
input_map.erase(p_action);
}
Array InputMap::_get_actions() {
-
Array ret;
List<StringName> actions = get_actions();
- if (actions.empty())
+ if (actions.empty()) {
return ret;
+ }
for (const List<StringName>::Element *E = actions.front(); E; E = E->next()) {
-
ret.push_back(E->get());
}
@@ -86,7 +82,6 @@ Array InputMap::_get_actions() {
}
List<StringName> InputMap::get_actions() const {
-
List<StringName> actions = List<StringName>();
if (input_map.empty()) {
return actions;
@@ -100,9 +95,7 @@ List<StringName> InputMap::get_actions() const {
}
List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Ref<InputEvent> &p_event, bool *p_pressed, float *p_strength) const {
-
for (List<Ref<InputEvent>>::Element *E = p_action.inputs.front(); E; E = E->next()) {
-
const Ref<InputEvent> e = E->get();
//if (e.type != Ref<InputEvent>::KEY && e.device != p_event.device) -- unsure about the KEY comparison, why is this here?
@@ -120,56 +113,50 @@ List<Ref<InputEvent>>::Element *InputMap::_find_event(Action &p_action, const Re
}
bool InputMap::has_action(const StringName &p_action) const {
-
return input_map.has(p_action);
}
void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone) {
-
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
input_map[p_action].deadzone = p_deadzone;
}
void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
-
ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object.");
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
- if (_find_event(input_map[p_action], p_event))
+ if (_find_event(input_map[p_action], p_event)) {
return; //already gots
+ }
input_map[p_action].inputs.push_back(p_event);
}
bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
-
ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
return (_find_event(input_map[p_action], p_event) != nullptr);
}
void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
-
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event);
- if (E)
+ if (E) {
input_map[p_action].inputs.erase(E);
+ }
}
void InputMap::action_erase_events(const StringName &p_action) {
-
ERR_FAIL_COND_MSG(!input_map.has(p_action), "Request for nonexistent InputMap action '" + String(p_action) + "'.");
input_map[p_action].inputs.clear();
}
Array InputMap::_get_action_list(const StringName &p_action) {
-
Array ret;
const List<Ref<InputEvent>> *al = get_action_list(p_action);
if (al) {
for (const List<Ref<InputEvent>>::Element *E = al->front(); E; E = E->next()) {
-
ret.push_back(E->get());
}
}
@@ -178,10 +165,10 @@ Array InputMap::_get_action_list(const StringName &p_action) {
}
const List<Ref<InputEvent>> *InputMap::get_action_list(const StringName &p_action) {
-
const Map<StringName, Action>::Element *E = input_map.find(p_action);
- if (!E)
+ if (!E) {
return nullptr;
+ }
return &E->get().inputs;
}
@@ -196,10 +183,12 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
Ref<InputEventAction> input_event_action = p_event;
if (input_event_action.is_valid()) {
- if (p_pressed != nullptr)
+ if (p_pressed != nullptr) {
*p_pressed = input_event_action->is_pressed();
- if (p_strength != nullptr)
+ }
+ if (p_strength != nullptr) {
*p_strength = (p_pressed != nullptr && *p_pressed) ? input_event_action->get_strength() : 0.0f;
+ }
return input_event_action->get_action() == p_action;
}
@@ -207,10 +196,12 @@ bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const Str
float strength;
List<Ref<InputEvent>>::Element *event = _find_event(E->get(), p_event, &pressed, &strength);
if (event != nullptr) {
- if (p_pressed != nullptr)
+ if (p_pressed != nullptr) {
*p_pressed = pressed;
- if (p_strength != nullptr)
+ }
+ if (p_strength != nullptr) {
*p_strength = strength;
+ }
return true;
} else {
return false;
@@ -222,7 +213,6 @@ const Map<StringName, InputMap::Action> &InputMap::get_action_map() const {
}
void InputMap::load_from_globals() {
-
input_map.clear();
List<PropertyInfo> pinfo;
@@ -231,8 +221,9 @@ void InputMap::load_from_globals() {
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
const PropertyInfo &pi = E->get();
- if (!pi.name.begins_with("input/"))
+ if (!pi.name.begins_with("input/")) {
continue;
+ }
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
@@ -243,15 +234,15 @@ void InputMap::load_from_globals() {
add_action(name, deadzone);
for (int i = 0; i < events.size(); i++) {
Ref<InputEvent> event = events[i];
- if (event.is_null())
+ if (event.is_null()) {
continue;
+ }
action_add_event(name, event);
}
}
}
void InputMap::load_default() {
-
Ref<InputEventKey> key;
add_action("ui_accept");
@@ -332,7 +323,6 @@ void InputMap::load_default() {
}
InputMap::InputMap() {
-
ERR_FAIL_COND_MSG(singleton, "Singleton in InputMap already exist.");
singleton = this;
}
diff --git a/core/input/input_map.h b/core/input/input_map.h
index e03bc5fd4f..3abc224ccf 100644
--- a/core/input/input_map.h
+++ b/core/input/input_map.h
@@ -35,7 +35,6 @@
#include "core/object.h"
class InputMap : public Object {
-
GDCLASS(InputMap, Object);
public:
diff --git a/core/io/compression.cpp b/core/io/compression.cpp
index 20c9fdca6f..99ca8107e4 100644
--- a/core/io/compression.cpp
+++ b/core/io/compression.cpp
@@ -40,10 +40,8 @@
#include <zstd.h>
int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode) {
-
switch (p_mode) {
case MODE_FASTLZ: {
-
if (p_src_size < 16) {
uint8_t src[16];
zeromem(&src[p_src_size], 16 - p_src_size);
@@ -56,7 +54,6 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
} break;
case MODE_DEFLATE:
case MODE_GZIP: {
-
int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16;
z_stream strm;
@@ -65,8 +62,9 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
strm.opaque = Z_NULL;
int level = p_mode == MODE_DEFLATE ? zlib_level : gzip_level;
int err = deflateInit2(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY);
- if (err != Z_OK)
+ if (err != Z_OK) {
return -1;
+ }
strm.avail_in = p_src_size;
int aout = deflateBound(&strm, p_src_size);
@@ -97,19 +95,17 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
}
int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
-
switch (p_mode) {
case MODE_FASTLZ: {
-
int ss = p_src_size + p_src_size * 6 / 100;
- if (ss < 66)
+ if (ss < 66) {
ss = 66;
+ }
return ss;
} break;
case MODE_DEFLATE:
case MODE_GZIP: {
-
int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16;
z_stream strm;
@@ -117,14 +113,14 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
int err = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY);
- if (err != Z_OK)
+ if (err != Z_OK) {
return -1;
+ }
int aout = deflateBound(&strm, p_src_size);
deflateEnd(&strm);
return aout;
} break;
case MODE_ZSTD: {
-
return ZSTD_compressBound(p_src_size);
} break;
}
@@ -133,10 +129,8 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
}
int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode) {
-
switch (p_mode) {
case MODE_FASTLZ: {
-
int ret_size = 0;
if (p_dst_max_size < 16) {
@@ -150,7 +144,6 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
} break;
case MODE_DEFLATE:
case MODE_GZIP: {
-
int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16;
z_stream strm;
diff --git a/core/io/compression.h b/core/io/compression.h
index 8354b581fa..f195f96ba5 100644
--- a/core/io/compression.h
+++ b/core/io/compression.h
@@ -34,7 +34,6 @@
#include "core/typedefs.h"
class Compression {
-
public:
static int zlib_level;
static int gzip_level;
@@ -53,7 +52,7 @@ public:
static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_ZSTD);
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);
- Compression();
+ Compression() {}
};
#endif // COMPRESSION_H
diff --git a/core/io/config_file.cpp b/core/io/config_file.cpp
index 73230e3a3c..1af9142317 100644
--- a/core/io/config_file.cpp
+++ b/core/io/config_file.cpp
@@ -35,14 +35,12 @@
#include "core/variant_parser.h"
PackedStringArray ConfigFile::_get_sections() const {
-
List<String> s;
get_sections(&s);
PackedStringArray arr;
arr.resize(s.size());
int idx = 0;
for (const List<String>::Element *E = s.front(); E; E = E->next()) {
-
arr.set(idx++, E->get());
}
@@ -50,14 +48,12 @@ PackedStringArray ConfigFile::_get_sections() const {
}
PackedStringArray ConfigFile::_get_section_keys(const String &p_section) const {
-
List<String> s;
get_section_keys(p_section, &s);
PackedStringArray arr;
arr.resize(s.size());
int idx = 0;
for (const List<String>::Element *E = s.front(); E; E = E->next()) {
-
arr.set(idx++, E->get());
}
@@ -65,11 +61,11 @@ PackedStringArray ConfigFile::_get_section_keys(const String &p_section) const {
}
void ConfigFile::set_value(const String &p_section, const String &p_key, const Variant &p_value) {
-
if (p_value.get_type() == Variant::NIL) {
//erase
- if (!values.has(p_section))
+ if (!values.has(p_section)) {
return; // ?
+ }
values[p_section].erase(p_key);
if (values[p_section].empty()) {
values.erase(p_section);
@@ -83,8 +79,8 @@ void ConfigFile::set_value(const String &p_section, const String &p_key, const V
values[p_section][p_key] = p_value;
}
}
-Variant ConfigFile::get_value(const String &p_section, const String &p_key, Variant p_default) const {
+Variant ConfigFile::get_value(const String &p_section, const String &p_key, Variant p_default) const {
if (!values.has(p_section) || !values[p_section].has(p_key)) {
ERR_FAIL_COND_V_MSG(p_default.get_type() == Variant::NIL, Variant(),
vformat("Couldn't find the given section \"%s\" and key \"%s\", and no default was given.", p_section, p_key));
@@ -95,24 +91,23 @@ Variant ConfigFile::get_value(const String &p_section, const String &p_key, Vari
}
bool ConfigFile::has_section(const String &p_section) const {
-
return values.has(p_section);
}
-bool ConfigFile::has_section_key(const String &p_section, const String &p_key) const {
- if (!values.has(p_section))
+bool ConfigFile::has_section_key(const String &p_section, const String &p_key) const {
+ if (!values.has(p_section)) {
return false;
+ }
return values[p_section].has(p_key);
}
void ConfigFile::get_sections(List<String> *r_sections) const {
-
for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::ConstElement E = values.front(); E; E = E.next()) {
r_sections->push_back(E.key());
}
}
-void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys) const {
+void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys) const {
ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot get keys from nonexistent section \"%s\".", p_section));
for (OrderedHashMap<String, Variant>::ConstElement E = values[p_section].front(); E; E = E.next()) {
@@ -121,13 +116,11 @@ void ConfigFile::get_section_keys(const String &p_section, List<String> *r_keys)
}
void ConfigFile::erase_section(const String &p_section) {
-
ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot erase nonexistent section \"%s\".", p_section));
values.erase(p_section);
}
void ConfigFile::erase_section_key(const String &p_section, const String &p_key) {
-
ERR_FAIL_COND_MSG(!values.has(p_section), vformat("Cannot erase key \"%s\" from nonexistent section \"%s\".", p_key, p_section));
ERR_FAIL_COND_MSG(!values[p_section].has(p_key), vformat("Cannot erase nonexistent key \"%s\" from section \"%s\".", p_key, p_section));
@@ -135,13 +128,13 @@ void ConfigFile::erase_section_key(const String &p_section, const String &p_key)
}
Error ConfigFile::save(const String &p_path) {
-
Error err;
FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
if (err) {
- if (file)
+ if (file) {
memdelete(file);
+ }
return err;
}
@@ -149,12 +142,12 @@ Error ConfigFile::save(const String &p_path) {
}
Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
-
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
- if (err)
+ if (err) {
return err;
+ }
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_WRITE_AES256);
@@ -167,12 +160,12 @@ Error ConfigFile::save_encrypted(const String &p_path, const Vector<uint8_t> &p_
}
Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass) {
-
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE, &err);
- if (err)
+ if (err) {
return err;
+ }
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_WRITE_AES256);
@@ -186,15 +179,13 @@ Error ConfigFile::save_encrypted_pass(const String &p_path, const String &p_pass
}
Error ConfigFile::_internal_save(FileAccess *file) {
-
for (OrderedHashMap<String, OrderedHashMap<String, Variant>>::Element E = values.front(); E; E = E.next()) {
-
- if (E != values.front())
+ if (E != values.front()) {
file->store_string("\n");
+ }
file->store_string("[" + E.key() + "]\n\n");
for (OrderedHashMap<String, Variant>::Element F = E.get().front(); F; F = F.next()) {
-
String vstr;
VariantWriter::write_to_string(F.get(), vstr);
file->store_string(F.key() + "=" + vstr + "\n");
@@ -207,23 +198,23 @@ Error ConfigFile::_internal_save(FileAccess *file) {
}
Error ConfigFile::load(const String &p_path) {
-
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
- if (!f)
+ if (!f) {
return err;
+ }
return _internal_load(p_path, f);
}
Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_key) {
-
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
- if (err)
+ if (err) {
return err;
+ }
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse(f, p_key, FileAccessEncrypted::MODE_READ);
@@ -236,12 +227,12 @@ Error ConfigFile::load_encrypted(const String &p_path, const Vector<uint8_t> &p_
}
Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass) {
-
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
- if (err)
+ if (err) {
return err;
+ }
FileAccessEncrypted *fae = memnew(FileAccessEncrypted);
err = fae->open_and_parse_password(f, p_pass, FileAccessEncrypted::MODE_READ);
@@ -255,7 +246,6 @@ Error ConfigFile::load_encrypted_pass(const String &p_path, const String &p_pass
}
Error ConfigFile::_internal_load(const String &p_path, FileAccess *f) {
-
VariantParser::StreamFile stream;
stream.f = f;
@@ -267,14 +257,12 @@ Error ConfigFile::_internal_load(const String &p_path, FileAccess *f) {
}
Error ConfigFile::parse(const String &p_data) {
-
VariantParser::StreamString stream;
stream.s = p_data;
return _parse("<string>", &stream);
}
Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream) {
-
String assign;
Variant value;
VariantParser::Tag next_tag;
@@ -285,7 +273,6 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream)
String section;
while (true) {
-
assign = Variant();
next_tag.fields.clear();
next_tag.name = String();
@@ -309,7 +296,6 @@ Error ConfigFile::_parse(const String &p_path, VariantParser::Stream *p_stream)
}
void ConfigFile::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_value", "section", "key", "value"), &ConfigFile::set_value);
ClassDB::bind_method(D_METHOD("get_value", "section", "key", "default"), &ConfigFile::get_value, DEFVAL(Variant()));
diff --git a/core/io/config_file.h b/core/io/config_file.h
index 39fc2ab412..ae06960f02 100644
--- a/core/io/config_file.h
+++ b/core/io/config_file.h
@@ -37,7 +37,6 @@
#include "core/variant_parser.h"
class ConfigFile : public Reference {
-
GDCLASS(ConfigFile, Reference);
OrderedHashMap<String, OrderedHashMap<String, Variant>> values;
diff --git a/core/io/dtls_server.cpp b/core/io/dtls_server.cpp
index 5bda06e5b9..0278027c50 100644
--- a/core/io/dtls_server.cpp
+++ b/core/io/dtls_server.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "dtls_server.h"
+
#include "core/os/file_access.h"
#include "core/project_settings.h"
@@ -36,7 +37,6 @@ DTLSServer *(*DTLSServer::_create)() = nullptr;
bool DTLSServer::available = false;
DTLSServer *DTLSServer::create() {
-
return _create();
}
@@ -45,10 +45,6 @@ bool DTLSServer::is_available() {
}
void DTLSServer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("setup", "key", "certificate", "chain"), &DTLSServer::setup, DEFVAL(Ref<X509Certificate>()));
ClassDB::bind_method(D_METHOD("take_connection", "udp_peer"), &DTLSServer::take_connection);
}
-
-DTLSServer::DTLSServer() {
-}
diff --git a/core/io/dtls_server.h b/core/io/dtls_server.h
index 7b08138f7f..ae1d3bcd98 100644
--- a/core/io/dtls_server.h
+++ b/core/io/dtls_server.h
@@ -51,7 +51,7 @@ public:
virtual void stop() = 0;
virtual Ref<PacketPeerDTLS> take_connection(Ref<PacketPeerUDP> p_peer) = 0;
- DTLSServer();
+ DTLSServer() {}
};
#endif // DTLS_SERVER_H
diff --git a/core/io/file_access_buffered.cpp b/core/io/file_access_buffered.cpp
index ab0fb3943c..6208f3a4d1 100644
--- a/core/io/file_access_buffered.cpp
+++ b/core/io/file_access_buffered.cpp
@@ -33,28 +33,23 @@
#include "core/error_macros.h"
Error FileAccessBuffered::set_error(Error p_error) const {
-
return (last_error = p_error);
}
void FileAccessBuffered::set_cache_size(int p_size) {
-
cache_size = p_size;
}
int FileAccessBuffered::get_cache_size() {
-
return cache_size;
}
int FileAccessBuffered::cache_data_left() const {
-
if (file.offset >= file.size) {
return 0;
}
if (cache.offset == -1 || file.offset < cache.offset || file.offset >= cache.offset + cache.buffer.size()) {
-
return read_data_block(file.offset, cache_size);
}
@@ -62,37 +57,30 @@ int FileAccessBuffered::cache_data_left() const {
}
void FileAccessBuffered::seek(size_t p_position) {
-
file.offset = p_position;
}
void FileAccessBuffered::seek_end(int64_t p_position) {
-
file.offset = file.size + p_position;
}
size_t FileAccessBuffered::get_position() const {
-
return file.offset;
}
size_t FileAccessBuffered::get_len() const {
-
return file.size;
}
bool FileAccessBuffered::eof_reached() const {
-
return file.offset > file.size;
}
uint8_t FileAccessBuffered::get_8() const {
-
ERR_FAIL_COND_V_MSG(!file.open, 0, "Can't get data, when file is not opened.");
uint8_t byte = 0;
if (cache_data_left() >= 1) {
-
byte = cache.buffer[file.offset - cache.offset];
}
@@ -102,15 +90,12 @@ uint8_t FileAccessBuffered::get_8() const {
}
int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
-
ERR_FAIL_COND_V_MSG(!file.open, -1, "Can't get buffer, when file is not opened.");
if (p_length > cache_size) {
-
int total_read = 0;
if (!(cache.offset == -1 || file.offset < cache.offset || file.offset >= cache.offset + cache.buffer.size())) {
-
int size = (cache.buffer.size() - (file.offset - cache.offset));
size = size - (size % 4);
//const uint8_t* read = cache.buffer.ptr();
@@ -134,7 +119,6 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
int to_read = p_length;
int total_read = 0;
while (to_read > 0) {
-
int left = cache_data_left();
if (left == 0) {
file.offset += to_read;
@@ -158,19 +142,9 @@ int FileAccessBuffered::get_buffer(uint8_t *p_dest, int p_length) const {
}
bool FileAccessBuffered::is_open() const {
-
return file.open;
}
Error FileAccessBuffered::get_error() const {
-
return last_error;
}
-
-FileAccessBuffered::FileAccessBuffered() {
-
- cache_size = DEFAULT_CACHE_SIZE;
-}
-
-FileAccessBuffered::~FileAccessBuffered() {
-}
diff --git a/core/io/file_access_buffered.h b/core/io/file_access_buffered.h
index a6177c20be..61c0fa7489 100644
--- a/core/io/file_access_buffered.h
+++ b/core/io/file_access_buffered.h
@@ -36,14 +36,13 @@
#include "core/ustring.h"
class FileAccessBuffered : public FileAccess {
-
public:
enum {
DEFAULT_CACHE_SIZE = 128 * 1024,
};
private:
- int cache_size;
+ int cache_size = DEFAULT_CACHE_SIZE;
int cache_data_left() const;
mutable Error last_error;
@@ -52,7 +51,6 @@ protected:
Error set_error(Error p_error) const;
mutable struct File {
-
bool open;
int size;
int offset;
@@ -61,12 +59,11 @@ protected:
} file;
mutable struct Cache {
-
Vector<uint8_t> buffer;
int offset;
} cache;
- virtual int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const = 0;
+ virtual int read_data_block(int p_offset, int p_size, uint8_t *p_dest = nullptr) const = 0;
void set_cache_size(int p_size);
int get_cache_size();
@@ -87,8 +84,8 @@ public:
virtual Error get_error() const;
- FileAccessBuffered();
- virtual ~FileAccessBuffered();
+ FileAccessBuffered() {}
+ virtual ~FileAccessBuffered() {}
};
#endif
diff --git a/core/io/file_access_buffered_fa.h b/core/io/file_access_buffered_fa.h
index 6ec77d503b..f22e54e154 100644
--- a/core/io/file_access_buffered_fa.h
+++ b/core/io/file_access_buffered_fa.h
@@ -35,22 +35,18 @@
template <class T>
class FileAccessBufferedFA : public FileAccessBuffered {
-
T f;
int read_data_block(int p_offset, int p_size, uint8_t *p_dest = 0) const {
-
ERR_FAIL_COND_V_MSG(!f.is_open(), -1, "Can't read data block when file is not opened.");
((T *)&f)->seek(p_offset);
if (p_dest) {
-
f.get_buffer(p_dest, p_size);
return p_size;
} else {
-
cache.offset = p_offset;
cache.buffer.resize(p_size);
@@ -62,43 +58,37 @@ class FileAccessBufferedFA : public FileAccessBuffered {
f.get_buffer(cache.buffer.ptrw(), p_size);
return p_size;
- };
- };
+ }
+ }
static FileAccess *create() {
-
return memnew(FileAccessBufferedFA<T>());
- };
+ }
protected:
virtual void _set_access_type(AccessType p_access) {
f._set_access_type(p_access);
FileAccessBuffered::_set_access_type(p_access);
- };
+ }
public:
void flush() {
-
f.flush();
- };
+ }
void store_8(uint8_t p_dest) {
-
f.store_8(p_dest);
- };
+ }
void store_buffer(const uint8_t *p_src, int p_length) {
-
f.store_buffer(p_src, p_length);
- };
+ }
bool file_exists(const String &p_name) {
-
return f.file_exists(p_name);
- };
+ }
Error _open(const String &p_path, int p_mode_flags) {
-
close();
Error ret = f._open(p_path, p_mode_flags);
@@ -116,10 +106,9 @@ public:
cache.offset = 0;
return set_error(OK);
- };
+ }
void close() {
-
f.close();
file.offset = 0;
@@ -130,16 +119,9 @@ public:
cache.buffer.resize(0);
cache.offset = 0;
set_error(OK);
- };
-
- /*
- static void make_default() {
- FileAccess::create_func = FileAccessBufferedFA<T>::create;
- };
- */
+ }
virtual uint64_t _get_modified_time(const String &p_file) {
-
return f._get_modified_time(p_file);
}
@@ -151,9 +133,7 @@ public:
return f._set_unix_permissions(p_file, p_permissions);
}
- FileAccessBufferedFA(){
-
- };
+ FileAccessBufferedFA() {}
};
#endif // FILE_ACCESS_BUFFERED_FA_H
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index c76142d22d..7817ccb773 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -33,13 +33,13 @@
#include "core/print_string.h"
void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_mode, int p_block_size) {
-
magic = p_magic.ascii().get_data();
- if (magic.length() > 4)
+ if (magic.length() > 4) {
magic = magic.substr(0, 4);
- else {
- while (magic.length() < 4)
+ } else {
+ while (magic.length() < 4) {
magic += " ";
+ }
}
cmode = p_mode;
@@ -59,7 +59,6 @@ void FileAccessCompressed::configure(const String &p_magic, Compression::Mode p_
}
Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
-
f = p_base;
cmode = (Compression::Mode)f->get_32();
block_size = f->get_32();
@@ -72,7 +71,6 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
int acc_ofs = f->get_position() + bc * 4;
int max_bs = 0;
for (int i = 0; i < bc; i++) {
-
ReadBlock rb;
rb.offset = acc_ofs;
rb.csize = f->get_32();
@@ -98,11 +96,11 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
}
Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
-
ERR_FAIL_COND_V(p_mode_flags == READ_WRITE, ERR_UNAVAILABLE);
- if (f)
+ if (f) {
close();
+ }
Error err;
f = FileAccess::open(p_path, p_mode_flags, &err);
@@ -114,7 +112,6 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
}
if (p_mode_flags & WRITE) {
-
buffer.clear();
writing = true;
write_pos = 0;
@@ -125,7 +122,6 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
//don't store anything else unless it's done saving!
} else {
-
char rmagic[5];
f->get_buffer((uint8_t *)rmagic, 4);
rmagic[4] = 0;
@@ -138,10 +134,11 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
return OK;
}
-void FileAccessCompressed::close() {
- if (!f)
+void FileAccessCompressed::close() {
+ if (!f) {
return;
+ }
if (writing) {
//save block table and all compressed blocks
@@ -159,7 +156,6 @@ void FileAccessCompressed::close() {
Vector<int> block_sizes;
for (int i = 0; i < bc; i++) {
-
int bl = i == (bc - 1) ? write_max % block_size : block_size;
uint8_t *bp = &write_ptr[i * block_size];
@@ -172,15 +168,15 @@ void FileAccessCompressed::close() {
}
f->seek(16); //ok write block sizes
- for (int i = 0; i < bc; i++)
+ for (int i = 0; i < bc; i++) {
f->store_32(block_sizes[i]);
+ }
f->seek_end();
f->store_buffer((const uint8_t *)mgc.get_data(), mgc.length()); //magic at the end too
buffer.clear();
} else {
-
comp_buffer.clear();
buffer.clear();
read_blocks.clear();
@@ -191,21 +187,17 @@ void FileAccessCompressed::close() {
}
bool FileAccessCompressed::is_open() const {
-
return f != nullptr;
}
void FileAccessCompressed::seek(size_t p_position) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
if (writing) {
-
ERR_FAIL_COND(p_position > write_max);
write_pos = p_position;
} else {
-
ERR_FAIL_COND(p_position > read_total);
if (p_position == read_total) {
at_end = true;
@@ -214,7 +206,6 @@ void FileAccessCompressed::seek(size_t p_position) {
read_eof = false;
int block_idx = p_position / block_size;
if (block_idx != read_block) {
-
read_block = block_idx;
f->seek(read_blocks[read_block].offset);
f->get_buffer(comp_buffer.ptrw(), read_blocks[read_block].csize);
@@ -228,32 +219,26 @@ void FileAccessCompressed::seek(size_t p_position) {
}
void FileAccessCompressed::seek_end(int64_t p_position) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
if (writing) {
-
seek(write_max + p_position);
} else {
-
seek(read_total + p_position);
}
}
-size_t FileAccessCompressed::get_position() const {
+size_t FileAccessCompressed::get_position() const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
if (writing) {
-
return write_pos;
} else {
-
return read_block * block_size + read_pos;
}
}
-size_t FileAccessCompressed::get_len() const {
+size_t FileAccessCompressed::get_len() const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
if (writing) {
-
return write_max;
} else {
return read_total;
@@ -261,7 +246,6 @@ size_t FileAccessCompressed::get_len() const {
}
bool FileAccessCompressed::eof_reached() const {
-
ERR_FAIL_COND_V_MSG(!f, false, "File must be opened before use.");
if (writing) {
return false;
@@ -271,7 +255,6 @@ bool FileAccessCompressed::eof_reached() const {
}
uint8_t FileAccessCompressed::get_8() const {
-
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
@@ -301,8 +284,8 @@ uint8_t FileAccessCompressed::get_8() const {
return ret;
}
-int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
+int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
@@ -312,7 +295,6 @@ int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
}
for (int i = 0; i < p_length; i++) {
-
p_dst[i] = read_ptr[read_pos];
read_pos++;
if (read_pos >= read_block_size) {
@@ -328,8 +310,9 @@ int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
} else {
read_block--;
at_end = true;
- if (i < p_length - 1)
+ if (i < p_length - 1) {
read_eof = true;
+ }
return i;
}
}
@@ -339,7 +322,6 @@ int FileAccessCompressed::get_buffer(uint8_t *p_dst, int p_length) const {
}
Error FileAccessCompressed::get_error() const {
-
return read_eof ? ERR_FILE_EOF : OK;
}
@@ -351,7 +333,6 @@ void FileAccessCompressed::flush() {
}
void FileAccessCompressed::store_8(uint8_t p_dest) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
ERR_FAIL_COND_MSG(!writing, "File has not been opened in read mode.");
@@ -360,25 +341,26 @@ void FileAccessCompressed::store_8(uint8_t p_dest) {
}
bool FileAccessCompressed::file_exists(const String &p_name) {
-
FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
- if (!fa)
+ if (!fa) {
return false;
+ }
memdelete(fa);
return true;
}
uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) {
-
- if (f)
+ if (f) {
return f->get_modified_time(p_file);
- else
+ } else {
return 0;
+ }
}
uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) {
- if (f)
+ if (f) {
return f->_get_unix_permissions(p_file);
+ }
return 0;
}
@@ -389,27 +371,8 @@ Error FileAccessCompressed::_set_unix_permissions(const String &p_file, uint32_t
return FAILED;
}
-FileAccessCompressed::FileAccessCompressed() :
- cmode(Compression::MODE_ZSTD),
- writing(false),
- write_ptr(nullptr),
- write_buffer_size(0),
- write_max(0),
- block_size(0),
- read_eof(false),
- at_end(false),
- read_ptr(nullptr),
- read_block(0),
- read_block_count(0),
- read_block_size(0),
- read_pos(0),
- read_total(0),
- magic("GCMP"),
- f(nullptr) {
-}
-
FileAccessCompressed::~FileAccessCompressed() {
-
- if (f)
+ if (f) {
close();
+ }
}
diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h
index 0bb311faa8..52284b347e 100644
--- a/core/io/file_access_compressed.h
+++ b/core/io/file_access_compressed.h
@@ -35,16 +35,15 @@
#include "core/os/file_access.h"
class FileAccessCompressed : public FileAccess {
-
- Compression::Mode cmode;
- bool writing;
- uint32_t write_pos;
- uint8_t *write_ptr;
- uint32_t write_buffer_size;
- uint32_t write_max;
- uint32_t block_size;
- mutable bool read_eof;
- mutable bool at_end;
+ Compression::Mode cmode = Compression::MODE_ZSTD;
+ bool writing = false;
+ uint32_t write_pos = 0;
+ uint8_t *write_ptr = nullptr;
+ uint32_t write_buffer_size = 0;
+ uint32_t write_max = 0;
+ uint32_t block_size = 0;
+ mutable bool read_eof = false;
+ mutable bool at_end = false;
struct ReadBlock {
int csize;
@@ -52,17 +51,17 @@ class FileAccessCompressed : public FileAccess {
};
mutable Vector<uint8_t> comp_buffer;
- uint8_t *read_ptr;
- mutable int read_block;
- int read_block_count;
- mutable int read_block_size;
- mutable int read_pos;
+ uint8_t *read_ptr = nullptr;
+ mutable int read_block = 0;
+ int read_block_count = 0;
+ mutable int read_block_size = 0;
+ mutable int read_pos = 0;
Vector<ReadBlock> read_blocks;
- uint32_t read_total;
+ uint32_t read_total = 0;
- String magic;
+ String magic = "GCMP";
mutable Vector<uint8_t> buffer;
- FileAccess *f;
+ FileAccess *f = nullptr;
public:
void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_ZSTD, int p_block_size = 4096);
@@ -94,7 +93,7 @@ public:
virtual uint32_t _get_unix_permissions(const String &p_file);
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
- FileAccessCompressed();
+ FileAccessCompressed() {}
virtual ~FileAccessCompressed();
};
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index a5b3807789..5938914cb0 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -40,7 +40,6 @@
#define COMP_MAGIC 0x43454447
Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode) {
-
ERR_FAIL_COND_V_MSG(file != nullptr, ERR_ALREADY_IN_USE, "Can't open file while another file from path '" + file->get_path_absolute() + "' is open.");
ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER);
@@ -48,7 +47,6 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
eofed = false;
if (p_mode == MODE_WRITE_AES256) {
-
data.clear();
writing = true;
file = p_base;
@@ -56,7 +54,6 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
key = p_key;
} else if (p_mode == MODE_READ) {
-
writing = false;
key = p_key;
uint32_t magic = p_base->get_32();
@@ -85,7 +82,6 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
ctx.set_decode_key(key.ptrw(), 256);
for (size_t i = 0; i < ds; i += 16) {
-
ctx.decrypt_ecb(&data.write[i], &data.write[i]);
}
@@ -103,13 +99,11 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
}
Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const String &p_key, Mode p_mode) {
-
String cs = p_key.md5_text();
ERR_FAIL_COND_V(cs.length() != 32, ERR_INVALID_PARAMETER);
Vector<uint8_t> key;
key.resize(32);
for (int i = 0; i < 32; i++) {
-
key.write[i] = cs[i];
}
@@ -117,16 +111,15 @@ Error FileAccessEncrypted::open_and_parse_password(FileAccess *p_base, const Str
}
Error FileAccessEncrypted::_open(const String &p_path, int p_mode_flags) {
-
return OK;
}
-void FileAccessEncrypted::close() {
- if (!file)
+void FileAccessEncrypted::close() {
+ if (!file) {
return;
+ }
if (writing) {
-
Vector<uint8_t> compressed;
size_t len = data.size();
if (len % 16) {
@@ -146,7 +139,6 @@ void FileAccessEncrypted::close() {
ctx.set_encode_key(key.ptrw(), 256);
for (size_t i = 0; i < len; i += 16) {
-
ctx.encrypt_ecb(&compressed.write[i], &compressed.write[i]);
}
@@ -163,7 +155,6 @@ void FileAccessEncrypted::close() {
data.clear();
} else {
-
file->close();
memdelete(file);
data.clear();
@@ -172,55 +163,51 @@ void FileAccessEncrypted::close() {
}
bool FileAccessEncrypted::is_open() const {
-
return file != nullptr;
}
String FileAccessEncrypted::get_path() const {
-
- if (file)
+ if (file) {
return file->get_path();
- else
+ } else {
return "";
+ }
}
String FileAccessEncrypted::get_path_absolute() const {
-
- if (file)
+ if (file) {
return file->get_path_absolute();
- else
+ } else {
return "";
+ }
}
void FileAccessEncrypted::seek(size_t p_position) {
-
- if (p_position > (size_t)data.size())
+ if (p_position > (size_t)data.size()) {
p_position = data.size();
+ }
pos = p_position;
eofed = false;
}
void FileAccessEncrypted::seek_end(int64_t p_position) {
-
seek(data.size() + p_position);
}
-size_t FileAccessEncrypted::get_position() const {
+size_t FileAccessEncrypted::get_position() const {
return pos;
}
-size_t FileAccessEncrypted::get_len() const {
+size_t FileAccessEncrypted::get_len() const {
return data.size();
}
bool FileAccessEncrypted::eof_reached() const {
-
return eofed;
}
uint8_t FileAccessEncrypted::get_8() const {
-
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
if (pos >= data.size()) {
eofed = true;
@@ -231,13 +218,12 @@ uint8_t FileAccessEncrypted::get_8() const {
pos++;
return b;
}
-int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const {
+int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V_MSG(writing, 0, "File has not been opened in read mode.");
int to_copy = MIN(p_length, data.size() - pos);
for (int i = 0; i < to_copy; i++) {
-
p_dst[i] = data[pos++];
}
@@ -249,25 +235,19 @@ int FileAccessEncrypted::get_buffer(uint8_t *p_dst, int p_length) const {
}
Error FileAccessEncrypted::get_error() const {
-
return eofed ? ERR_FILE_EOF : OK;
}
void FileAccessEncrypted::store_buffer(const uint8_t *p_src, int p_length) {
-
ERR_FAIL_COND_MSG(!writing, "File has not been opened in read mode.");
if (pos < data.size()) {
-
for (int i = 0; i < p_length; i++) {
-
store_8(p_src[i]);
}
} else if (pos == data.size()) {
-
data.resize(pos + p_length);
for (int i = 0; i < p_length; i++) {
-
data.write[pos + i] = p_src[i];
}
pos += p_length;
@@ -281,7 +261,6 @@ void FileAccessEncrypted::flush() {
}
void FileAccessEncrypted::store_8(uint8_t p_dest) {
-
ERR_FAIL_COND_MSG(!writing, "File has not been opened in read mode.");
if (pos < data.size()) {
@@ -294,21 +273,19 @@ void FileAccessEncrypted::store_8(uint8_t p_dest) {
}
bool FileAccessEncrypted::file_exists(const String &p_name) {
-
FileAccess *fa = FileAccess::open(p_name, FileAccess::READ);
- if (!fa)
+ if (!fa) {
return false;
+ }
memdelete(fa);
return true;
}
uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) {
-
return 0;
}
uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) {
-
return 0;
}
@@ -317,17 +294,8 @@ Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t
return ERR_UNAVAILABLE;
}
-FileAccessEncrypted::FileAccessEncrypted() {
-
- file = nullptr;
- pos = 0;
- eofed = false;
- mode = MODE_MAX;
- writing = false;
-}
-
FileAccessEncrypted::~FileAccessEncrypted() {
-
- if (file)
+ if (file) {
close();
+ }
}
diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h
index 7a9f4ecdd8..e269c1e30c 100644
--- a/core/io/file_access_encrypted.h
+++ b/core/io/file_access_encrypted.h
@@ -42,15 +42,15 @@ public:
};
private:
- Mode mode;
+ Mode mode = MODE_MAX;
Vector<uint8_t> key;
- bool writing;
- FileAccess *file;
+ bool writing = false;
+ FileAccess *file = nullptr;
size_t base;
size_t length;
Vector<uint8_t> data;
- mutable int pos;
- mutable bool eofed;
+ mutable int pos = 0;
+ mutable bool eofed = false;
public:
Error open_and_parse(FileAccess *p_base, const Vector<uint8_t> &p_key, Mode p_mode);
@@ -85,7 +85,7 @@ public:
virtual uint32_t _get_unix_permissions(const String &p_file);
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
- FileAccessEncrypted();
+ FileAccessEncrypted() {}
~FileAccessEncrypted();
};
diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp
index a2379ce88f..a65ff92a89 100644
--- a/core/io/file_access_memory.cpp
+++ b/core/io/file_access_memory.cpp
@@ -38,36 +38,34 @@
static Map<String, Vector<uint8_t>> *files = nullptr;
void FileAccessMemory::register_file(String p_name, Vector<uint8_t> p_data) {
-
if (!files) {
files = memnew((Map<String, Vector<uint8_t>>));
}
String name;
- if (ProjectSettings::get_singleton())
+ if (ProjectSettings::get_singleton()) {
name = ProjectSettings::get_singleton()->globalize_path(p_name);
- else
+ } else {
name = p_name;
+ }
//name = DirAccess::normalize_path(name);
(*files)[name] = p_data;
}
void FileAccessMemory::cleanup() {
-
- if (!files)
+ if (!files) {
return;
+ }
memdelete(files);
}
FileAccess *FileAccessMemory::create() {
-
return memnew(FileAccessMemory);
}
bool FileAccessMemory::file_exists(const String &p_name) {
-
String name = fix_path(p_name);
//name = DirAccess::normalize_path(name);
@@ -75,7 +73,6 @@ bool FileAccessMemory::file_exists(const String &p_name) {
}
Error FileAccessMemory::open_custom(const uint8_t *p_data, int p_len) {
-
data = (uint8_t *)p_data;
length = p_len;
pos = 0;
@@ -83,7 +80,6 @@ Error FileAccessMemory::open_custom(const uint8_t *p_data, int p_len) {
}
Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
-
ERR_FAIL_COND_V(!files, ERR_FILE_NOT_FOUND);
String name = fix_path(p_path);
@@ -100,46 +96,38 @@ Error FileAccessMemory::_open(const String &p_path, int p_mode_flags) {
}
void FileAccessMemory::close() {
-
data = nullptr;
}
bool FileAccessMemory::is_open() const {
-
return data != nullptr;
}
void FileAccessMemory::seek(size_t p_position) {
-
ERR_FAIL_COND(!data);
pos = p_position;
}
void FileAccessMemory::seek_end(int64_t p_position) {
-
ERR_FAIL_COND(!data);
pos = length + p_position;
}
size_t FileAccessMemory::get_position() const {
-
ERR_FAIL_COND_V(!data, 0);
return pos;
}
size_t FileAccessMemory::get_len() const {
-
ERR_FAIL_COND_V(!data, 0);
return length;
}
bool FileAccessMemory::eof_reached() const {
-
return pos > length;
}
uint8_t FileAccessMemory::get_8() const {
-
uint8_t ret = 0;
if (pos < length) {
ret = data[pos];
@@ -150,7 +138,6 @@ uint8_t FileAccessMemory::get_8() const {
}
int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const {
-
ERR_FAIL_COND_V(!data, -1);
int left = length - pos;
@@ -158,7 +145,7 @@ int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const {
if (read < p_length) {
WARN_PRINT("Reading less data than requested");
- };
+ }
copymem(p_dst, &data[pos], read);
pos += p_length;
@@ -167,7 +154,6 @@ int FileAccessMemory::get_buffer(uint8_t *p_dst, int p_length) const {
}
Error FileAccessMemory::get_error() const {
-
return pos >= length ? ERR_FILE_EOF : OK;
}
@@ -176,14 +162,12 @@ void FileAccessMemory::flush() {
}
void FileAccessMemory::store_8(uint8_t p_byte) {
-
ERR_FAIL_COND(!data);
ERR_FAIL_COND(pos >= length);
data[pos++] = p_byte;
}
void FileAccessMemory::store_buffer(const uint8_t *p_src, int p_length) {
-
int left = length - pos;
int write = MIN(p_length, left);
if (write < p_length) {
@@ -193,8 +177,3 @@ void FileAccessMemory::store_buffer(const uint8_t *p_src, int p_length) {
copymem(&data[pos], p_src, write);
pos += p_length;
}
-
-FileAccessMemory::FileAccessMemory() {
-
- data = nullptr;
-}
diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h
index 2db14db265..1a9bd3fbbb 100644
--- a/core/io/file_access_memory.h
+++ b/core/io/file_access_memory.h
@@ -34,8 +34,7 @@
#include "core/os/file_access.h"
class FileAccessMemory : public FileAccess {
-
- uint8_t *data;
+ uint8_t *data = nullptr;
int length;
mutable int pos;
@@ -73,7 +72,7 @@ public:
virtual uint32_t _get_unix_permissions(const String &p_file) { return 0; }
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) { return FAILED; }
- FileAccessMemory();
+ FileAccessMemory() {}
};
#endif // FILE_ACCESS_MEMORY_H
diff --git a/core/io/file_access_network.cpp b/core/io/file_access_network.cpp
index a3f307393f..6890740d90 100644
--- a/core/io/file_access_network.cpp
+++ b/core/io/file_access_network.cpp
@@ -41,19 +41,16 @@
#define DEBUG_TIME(m_what)
void FileAccessNetworkClient::lock_mutex() {
-
mutex.lock();
lockcount++;
}
void FileAccessNetworkClient::unlock_mutex() {
-
lockcount--;
mutex.unlock();
}
void FileAccessNetworkClient::put_32(int p_32) {
-
uint8_t buf[4];
encode_uint32(p_32, buf);
client->put_data(buf, 4);
@@ -61,7 +58,6 @@ void FileAccessNetworkClient::put_32(int p_32) {
}
void FileAccessNetworkClient::put_64(int64_t p_64) {
-
uint8_t buf[8];
encode_uint64(p_64, buf);
client->put_data(buf, 8);
@@ -69,24 +65,20 @@ void FileAccessNetworkClient::put_64(int64_t p_64) {
}
int FileAccessNetworkClient::get_32() {
-
uint8_t buf[4];
client->get_data(buf, 4);
return decode_uint32(buf);
}
int64_t FileAccessNetworkClient::get_64() {
-
uint8_t buf[8];
client->get_data(buf, 8);
return decode_uint64(buf);
}
void FileAccessNetworkClient::_thread_func() {
-
client->set_no_delay(true);
while (!quit) {
-
DEBUG_PRINT("SEM WAIT - " + itos(sem->get()));
sem.wait();
DEBUG_TIME("sem_unlock");
@@ -123,13 +115,12 @@ void FileAccessNetworkClient::_thread_func() {
}
}
- if (accesses.has(id))
+ if (accesses.has(id)) {
fa = accesses[id];
+ }
switch (response) {
-
case FileAccessNetwork::RESPONSE_OPEN: {
-
DEBUG_TIME("sem_open");
int status = get_32();
if (status != OK) {
@@ -143,7 +134,6 @@ void FileAccessNetworkClient::_thread_func() {
} break;
case FileAccessNetwork::RESPONSE_DATA: {
-
int64_t offset = get_64();
uint32_t len = get_32();
@@ -151,19 +141,18 @@ void FileAccessNetworkClient::_thread_func() {
block.resize(len);
client->get_data(block.ptrw(), len);
- if (fa) //may have been queued
+ if (fa) { //may have been queued
fa->_set_block(offset, block);
+ }
} break;
case FileAccessNetwork::RESPONSE_FILE_EXISTS: {
-
int status = get_32();
fa->exists_modtime = status != 0;
fa->sem.post();
} break;
case FileAccessNetwork::RESPONSE_GET_MODTIME: {
-
uint64_t status = get_64();
fa->exists_modtime = status;
fa->sem.post();
@@ -176,14 +165,12 @@ void FileAccessNetworkClient::_thread_func() {
}
void FileAccessNetworkClient::_thread_func(void *s) {
-
FileAccessNetworkClient *self = (FileAccessNetworkClient *)s;
self->_thread_func();
}
Error FileAccessNetworkClient::connect(const String &p_host, int p_port, const String &p_password) {
-
IP_Address ip;
if (p_host.is_valid_ip_address()) {
@@ -222,17 +209,11 @@ Error FileAccessNetworkClient::connect(const String &p_host, int p_port, const S
FileAccessNetworkClient *FileAccessNetworkClient::singleton = nullptr;
FileAccessNetworkClient::FileAccessNetworkClient() {
-
- thread = nullptr;
- quit = false;
singleton = this;
- last_id = 0;
client.instance();
- lockcount = 0;
}
FileAccessNetworkClient::~FileAccessNetworkClient() {
-
if (thread) {
quit = true;
sem.post();
@@ -242,7 +223,6 @@ FileAccessNetworkClient::~FileAccessNetworkClient() {
}
void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block) {
-
int page = p_offset / page_size;
ERR_FAIL_INDEX(page, pages.size());
if (page < pages.size() - 1) {
@@ -264,11 +244,11 @@ void FileAccessNetwork::_set_block(int p_offset, const Vector<uint8_t> &p_block)
}
void FileAccessNetwork::_respond(size_t p_len, Error p_status) {
-
DEBUG_PRINT("GOT RESPONSE - len: " + itos(p_len) + " status: " + itos(p_status));
response = p_status;
- if (response != OK)
+ if (response != OK) {
return;
+ }
opened = true;
total_size = p_len;
int pc = ((total_size - 1) / page_size) + 1;
@@ -276,10 +256,10 @@ void FileAccessNetwork::_respond(size_t p_len, Error p_status) {
}
Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
-
ERR_FAIL_COND_V(p_mode_flags != READ, ERR_UNAVAILABLE);
- if (opened)
+ if (opened) {
close();
+ }
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
DEBUG_PRINT("open: " + p_path);
@@ -311,9 +291,9 @@ Error FileAccessNetwork::_open(const String &p_path, int p_mode_flags) {
}
void FileAccessNetwork::close() {
-
- if (!opened)
+ if (!opened) {
return;
+ }
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
@@ -325,13 +305,12 @@ void FileAccessNetwork::close() {
opened = false;
nc->unlock_mutex();
}
-bool FileAccessNetwork::is_open() const {
+bool FileAccessNetwork::is_open() const {
return opened;
}
void FileAccessNetwork::seek(size_t p_position) {
-
ERR_FAIL_COND_MSG(!opened, "File must be opened before use.");
eof_flag = p_position > total_size;
@@ -343,39 +322,35 @@ void FileAccessNetwork::seek(size_t p_position) {
}
void FileAccessNetwork::seek_end(int64_t p_position) {
-
seek(total_size + p_position);
}
-size_t FileAccessNetwork::get_position() const {
+size_t FileAccessNetwork::get_position() const {
ERR_FAIL_COND_V_MSG(!opened, 0, "File must be opened before use.");
return pos;
}
-size_t FileAccessNetwork::get_len() const {
+size_t FileAccessNetwork::get_len() const {
ERR_FAIL_COND_V_MSG(!opened, 0, "File must be opened before use.");
return total_size;
}
bool FileAccessNetwork::eof_reached() const {
-
ERR_FAIL_COND_V_MSG(!opened, false, "File must be opened before use.");
return eof_flag;
}
uint8_t FileAccessNetwork::get_8() const {
-
uint8_t v;
get_buffer(&v, 1);
return v;
}
void FileAccessNetwork::_queue_page(int p_page) const {
-
- if (p_page >= pages.size())
+ if (p_page >= pages.size()) {
return;
+ }
if (pages[p_page].buffer.empty() && !pages[p_page].queued) {
-
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
{
MutexLock lock(nc->blockrequest_mutex);
@@ -394,7 +369,6 @@ void FileAccessNetwork::_queue_page(int p_page) const {
}
int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
-
//bool eof=false;
if (pos + p_length > total_size) {
eof_flag = true;
@@ -408,7 +382,6 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
uint8_t *buff = last_page_buff;
for (int i = 0; i < p_length; i++) {
-
int page = pos / page_size;
if (page != last_page) {
@@ -416,7 +389,6 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
if (pages[page].buffer.empty()) {
waiting_on_page = page;
for (int j = 0; j < read_ahead; j++) {
-
_queue_page(page + j);
}
buffer_mutex.unlock();
@@ -424,9 +396,7 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
page_sem.wait();
DEBUG_PRINT("done");
} else {
-
for (int j = 0; j < read_ahead; j++) {
-
_queue_page(page + j);
}
//queue pages
@@ -446,7 +416,6 @@ int FileAccessNetwork::get_buffer(uint8_t *p_dst, int p_length) const {
}
Error FileAccessNetwork::get_error() const {
-
return pos == total_size ? ERR_FILE_EOF : OK;
}
@@ -455,12 +424,10 @@ void FileAccessNetwork::flush() {
}
void FileAccessNetwork::store_8(uint8_t p_dest) {
-
ERR_FAIL();
}
bool FileAccessNetwork::file_exists(const String &p_path) {
-
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
nc->put_32(id);
@@ -477,7 +444,6 @@ bool FileAccessNetwork::file_exists(const String &p_path) {
}
uint64_t FileAccessNetwork::_get_modified_time(const String &p_file) {
-
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
nc->put_32(id);
@@ -504,7 +470,6 @@ Error FileAccessNetwork::_set_unix_permissions(const String &p_file, uint32_t p_
}
void FileAccessNetwork::configure() {
-
GLOBAL_DEF("network/remote_fs/page_size", 65536);
ProjectSettings::get_singleton()->set_custom_property_info("network/remote_fs/page_size", PropertyInfo(Variant::INT, "network/remote_fs/page_size", PROPERTY_HINT_RANGE, "1,65536,1,or_greater")); //is used as denominator and can't be zero
GLOBAL_DEF("network/remote_fs/page_read_ahead", 4);
@@ -512,10 +477,6 @@ void FileAccessNetwork::configure() {
}
FileAccessNetwork::FileAccessNetwork() {
-
- eof_flag = false;
- opened = false;
- pos = 0;
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
nc->lock_mutex();
id = nc->last_id++;
@@ -523,13 +484,9 @@ FileAccessNetwork::FileAccessNetwork() {
nc->unlock_mutex();
page_size = GLOBAL_GET("network/remote_fs/page_size");
read_ahead = GLOBAL_GET("network/remote_fs/page_read_ahead");
- last_activity_val = 0;
- waiting_on_page = -1;
- last_page = -1;
}
FileAccessNetwork::~FileAccessNetwork() {
-
close();
FileAccessNetworkClient *nc = FileAccessNetworkClient::singleton;
diff --git a/core/io/file_access_network.h b/core/io/file_access_network.h
index 7f664b46f7..dc5ce1e883 100644
--- a/core/io/file_access_network.h
+++ b/core/io/file_access_network.h
@@ -39,9 +39,7 @@
class FileAccessNetwork;
class FileAccessNetworkClient {
-
struct BlockRequest {
-
int id;
uint64_t offset;
int size;
@@ -50,13 +48,14 @@ class FileAccessNetworkClient {
List<BlockRequest> block_requests;
Semaphore sem;
- Thread *thread;
- bool quit;
+ Thread *thread = nullptr;
+ bool quit = false;
Mutex mutex;
Mutex blockrequest_mutex;
Map<int, FileAccessNetwork *> accesses;
Ref<StreamPeerTCP> client;
- int last_id;
+ int last_id = 0;
+ int lockcount = 0;
Vector<uint8_t> block;
@@ -67,7 +66,6 @@ class FileAccessNetworkClient {
void put_64(int64_t p_64);
int get_32();
int64_t get_64();
- int lockcount;
void lock_mutex();
void unlock_mutex();
@@ -84,31 +82,26 @@ public:
};
class FileAccessNetwork : public FileAccess {
-
Semaphore sem;
Semaphore page_sem;
Mutex buffer_mutex;
- bool opened;
+ bool opened = false;
size_t total_size;
- mutable size_t pos;
+ mutable size_t pos = 0;
int id;
- mutable bool eof_flag;
- mutable int last_page;
- mutable uint8_t *last_page_buff;
+ mutable bool eof_flag = false;
+ mutable int last_page = -1;
+ mutable uint8_t *last_page_buff = nullptr;
int page_size;
int read_ahead;
- mutable int waiting_on_page;
- mutable int last_activity_val;
+ mutable int waiting_on_page = -1;
+
struct Page {
- int activity;
- bool queued;
+ int activity = 0;
+ bool queued = false;
Vector<uint8_t> buffer;
- Page() {
- activity = 0;
- queued = false;
- }
};
mutable Vector<Page> pages;
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index aa10afe642..37240f234a 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -30,26 +30,21 @@
#include "file_access_pack.h"
-#include "core/project_settings.h"
#include "core/version.h"
#include <stdio.h>
-Error PackedData::add_pack(const String &p_path, bool p_replace_files, const String &p_destination) {
-
+Error PackedData::add_pack(const String &p_path, bool p_replace_files) {
for (int i = 0; i < sources.size(); i++) {
-
- if (sources[i]->try_open_pack(p_path, p_replace_files, p_destination)) {
-
+ if (sources[i]->try_open_pack(p_path, p_replace_files)) {
return OK;
- };
- };
+ }
+ }
return ERR_FILE_UNRECOGNIZED;
-};
+}
void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files) {
-
PathMD5 pmd5(path.md5_buffer());
//printf("adding path %ls, %lli, %lli\n", path.c_str(), pmd5.a, pmd5.b);
@@ -59,12 +54,14 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
pf.pack = pkg_path;
pf.offset = ofs;
pf.size = size;
- for (int i = 0; i < 16; i++)
+ for (int i = 0; i < 16; i++) {
pf.md5[i] = p_md5[i];
+ }
pf.src = p_src;
- if (!exists || p_replace_files)
+ if (!exists || p_replace_files) {
files[pmd5] = pf;
+ }
if (!exists) {
//search for dir
@@ -76,9 +73,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
Vector<String> ds = p.get_base_dir().split("/");
for (int j = 0; j < ds.size(); j++) {
-
if (!cd->subdirs.has(ds[j])) {
-
PackedDir *pd = memnew(PackedDir);
pd->name = ds[j];
pd->parent = cd;
@@ -90,7 +85,7 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
}
}
String filename = path.get_file();
- // Don't add as a file if the path points to a directory.
+ // Don't add as a file if the path points to a directory
if (!filename.empty()) {
cd->files.insert(filename);
}
@@ -98,33 +93,28 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o
}
void PackedData::add_pack_source(PackSource *p_source) {
-
if (p_source != nullptr) {
sources.push_back(p_source);
}
-};
+}
PackedData *PackedData::singleton = nullptr;
PackedData::PackedData() {
-
singleton = this;
root = memnew(PackedDir);
- root->parent = nullptr;
- disabled = false;
add_pack_source(memnew(PackedSourcePCK));
}
void PackedData::_free_packed_dirs(PackedDir *p_dir) {
-
- for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next())
+ for (Map<String, PackedDir *>::Element *E = p_dir->subdirs.front(); E; E = E->next()) {
_free_packed_dirs(E->get());
+ }
memdelete(p_dir);
}
PackedData::~PackedData() {
-
for (int i = 0; i < sources.size(); i++) {
memdelete(sources[i]);
}
@@ -133,11 +123,11 @@ PackedData::~PackedData() {
//////////////////////////////////////////////////////////////////
-bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination) {
-
+bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- if (!f)
+ if (!f) {
return false;
+ }
uint32_t magic = f->get_32();
@@ -147,7 +137,6 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
f->seek(f->get_position() - 4);
magic = f->get_32();
if (magic != PACK_HEADER_MAGIC) {
-
f->close();
memdelete(f);
return false;
@@ -159,7 +148,6 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
magic = f->get_32();
if (magic != PACK_HEADER_MAGIC) {
-
f->close();
memdelete(f);
return false;
@@ -190,7 +178,6 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
int file_count = f->get_32();
for (int i = 0; i < file_count; i++) {
-
uint32_t sl = f->get_32();
CharString cs;
cs.resize(sl + 1);
@@ -199,62 +186,39 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
String path;
path.parse_utf8(cs.ptr());
- if (p_destination != "") {
- String destination = ProjectSettings::get_singleton()->localize_path(p_destination);
- ERR_FAIL_COND_V_MSG(!destination.begins_with("res://"), false, "The destination path must be within the resource filesystem (res://).");
-
- if (!destination.ends_with("/")) {
- destination += "/";
- }
-
- DirAccess *dir = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- if (!dir->dir_exists(destination)) {
- memdelete(dir);
-
- ERR_FAIL_V_MSG(false, vformat("The destination path \"%s\" does not exist.", destination));
- }
- memdelete(dir);
-
- path = path.replace_first("res://", destination);
- }
uint64_t ofs = f->get_64();
uint64_t size = f->get_64();
uint8_t md5[16];
f->get_buffer(md5, 16);
PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5, this, p_replace_files);
- };
+ }
f->close();
memdelete(f);
return true;
-};
+}
FileAccess *PackedSourcePCK::get_file(const String &p_path, PackedData::PackedFile *p_file) {
-
return memnew(FileAccessPack(p_path, *p_file));
-};
+}
//////////////////////////////////////////////////////////////////
Error FileAccessPack::_open(const String &p_path, int p_mode_flags) {
-
ERR_FAIL_V(ERR_UNAVAILABLE);
return ERR_UNAVAILABLE;
}
void FileAccessPack::close() {
-
f->close();
}
bool FileAccessPack::is_open() const {
-
return f->is_open();
}
void FileAccessPack::seek(size_t p_position) {
-
if (p_position > pf.size) {
eof = true;
} else {
@@ -264,26 +228,24 @@ void FileAccessPack::seek(size_t p_position) {
f->seek(pf.offset + p_position);
pos = p_position;
}
-void FileAccessPack::seek_end(int64_t p_position) {
+void FileAccessPack::seek_end(int64_t p_position) {
seek(pf.size + p_position);
}
-size_t FileAccessPack::get_position() const {
+size_t FileAccessPack::get_position() const {
return pos;
}
-size_t FileAccessPack::get_len() const {
+size_t FileAccessPack::get_len() const {
return pf.size;
}
bool FileAccessPack::eof_reached() const {
-
return eof;
}
uint8_t FileAccessPack::get_8() const {
-
if (pos >= pf.size) {
eof = true;
return 0;
@@ -294,9 +256,9 @@ uint8_t FileAccessPack::get_8() const {
}
int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {
-
- if (eof)
+ if (eof) {
return 0;
+ }
uint64_t to_read = p_length;
if (to_read + pos > pf.size) {
@@ -306,8 +268,9 @@ int FileAccessPack::get_buffer(uint8_t *p_dst, int p_length) const {
pos += p_length;
- if (to_read <= 0)
+ if (to_read <= 0) {
return 0;
+ }
f->get_buffer(p_dst, to_read);
return to_read;
@@ -319,36 +282,31 @@ void FileAccessPack::set_endian_swap(bool p_swap) {
}
Error FileAccessPack::get_error() const {
-
- if (eof)
+ if (eof) {
return ERR_FILE_EOF;
+ }
return OK;
}
void FileAccessPack::flush() {
-
ERR_FAIL();
}
void FileAccessPack::store_8(uint8_t p_dest) {
-
ERR_FAIL();
}
void FileAccessPack::store_buffer(const uint8_t *p_src, int p_length) {
-
ERR_FAIL();
}
bool FileAccessPack::file_exists(const String &p_name) {
-
return false;
}
FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file) :
pf(p_file),
f(FileAccess::open(pf.pack, FileAccess::READ)) {
-
ERR_FAIL_COND_MSG(!f, "Can't open pack-referenced file '" + String(pf.pack) + "'.");
f->seek(pf.offset);
@@ -357,8 +315,9 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil
}
FileAccessPack::~FileAccessPack() {
- if (f)
+ if (f) {
memdelete(f);
+ }
}
//////////////////////////////////////////////////////////////////////////////////
@@ -366,17 +325,14 @@ FileAccessPack::~FileAccessPack() {
//////////////////////////////////////////////////////////////////////////////////
Error DirAccessPack::list_dir_begin() {
-
list_dirs.clear();
list_files.clear();
for (Map<String, PackedData::PackedDir *>::Element *E = current->subdirs.front(); E; E = E->next()) {
-
list_dirs.push_back(E->key());
}
for (Set<String>::Element *E = current->files.front(); E; E = E->next()) {
-
list_files.push_back(E->get());
}
@@ -384,7 +340,6 @@ Error DirAccessPack::list_dir_begin() {
}
String DirAccessPack::get_next() {
-
if (list_dirs.size()) {
cdir = true;
String d = list_dirs.front()->get();
@@ -399,31 +354,29 @@ String DirAccessPack::get_next() {
return String();
}
}
-bool DirAccessPack::current_is_dir() const {
+bool DirAccessPack::current_is_dir() const {
return cdir;
}
-bool DirAccessPack::current_is_hidden() const {
+bool DirAccessPack::current_is_hidden() const {
return false;
}
-void DirAccessPack::list_dir_end() {
+void DirAccessPack::list_dir_end() {
list_dirs.clear();
list_files.clear();
}
int DirAccessPack::get_drive_count() {
-
return 0;
}
-String DirAccessPack::get_drive(int p_drive) {
+String DirAccessPack::get_drive(int p_drive) {
return "";
}
Error DirAccessPack::change_dir(String p_dir) {
-
String nd = p_dir.replace("\\", "/");
bool absolute = false;
if (nd.begins_with("res://")) {
@@ -433,7 +386,9 @@ Error DirAccessPack::change_dir(String p_dir) {
nd = nd.simplify_path();
- if (nd == "") nd = ".";
+ if (nd == "") {
+ nd = ".";
+ }
if (nd.begins_with("/")) {
nd = nd.replace_first("/", "");
@@ -444,13 +399,13 @@ Error DirAccessPack::change_dir(String p_dir) {
PackedData::PackedDir *pd;
- if (absolute)
+ if (absolute) {
pd = PackedData::get_singleton()->root;
- else
+ } else {
pd = current;
+ }
for (int i = 0; i < paths.size(); i++) {
-
String p = paths[i];
if (p == ".") {
continue;
@@ -459,11 +414,9 @@ Error DirAccessPack::change_dir(String p_dir) {
pd = pd->parent;
}
} else if (pd->subdirs.has(p)) {
-
pd = pd->subdirs[p];
} else {
-
return ERR_INVALID_PARAMETER;
}
}
@@ -474,7 +427,6 @@ Error DirAccessPack::change_dir(String p_dir) {
}
String DirAccessPack::get_current_dir(bool p_include_drive) {
-
PackedData::PackedDir *pd = current;
String p = current->name;
@@ -487,35 +439,30 @@ String DirAccessPack::get_current_dir(bool p_include_drive) {
}
bool DirAccessPack::file_exists(String p_file) {
-
p_file = fix_path(p_file);
return current->files.has(p_file);
}
bool DirAccessPack::dir_exists(String p_dir) {
-
p_dir = fix_path(p_dir);
return current->subdirs.has(p_dir);
}
Error DirAccessPack::make_dir(String p_dir) {
-
return ERR_UNAVAILABLE;
}
Error DirAccessPack::rename(String p_from, String p_to) {
-
return ERR_UNAVAILABLE;
}
-Error DirAccessPack::remove(String p_name) {
+Error DirAccessPack::remove(String p_name) {
return ERR_UNAVAILABLE;
}
size_t DirAccessPack::get_space_left() {
-
return 0;
}
@@ -524,10 +471,5 @@ String DirAccessPack::get_filesystem_type() const {
}
DirAccessPack::DirAccessPack() {
-
current = PackedData::get_singleton()->root;
- cdir = false;
-}
-
-DirAccessPack::~DirAccessPack() {
}
diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h
index 1a46bef0f6..348bc0c450 100644
--- a/core/io/file_access_pack.h
+++ b/core/io/file_access_pack.h
@@ -51,7 +51,6 @@ class PackedData {
public:
struct PackedFile {
-
String pack;
uint64_t offset; //if offset is ZERO, the file was ERASED
uint64_t size;
@@ -61,17 +60,16 @@ public:
private:
struct PackedDir {
- PackedDir *parent;
+ PackedDir *parent = nullptr;
String name;
Map<String, PackedDir *> subdirs;
Set<String> files;
};
struct PathMD5 {
- uint64_t a;
- uint64_t b;
+ uint64_t a = 0;
+ uint64_t b = 0;
bool operator<(const PathMD5 &p_md5) const {
-
if (p_md5.a == a) {
return b < p_md5.b;
} else {
@@ -81,16 +79,14 @@ private:
bool operator==(const PathMD5 &p_md5) const {
return a == p_md5.a && b == p_md5.b;
- };
+ }
- PathMD5() {
- a = b = 0;
- };
+ PathMD5() {}
PathMD5(const Vector<uint8_t> p_buf) {
a = *((uint64_t *)&p_buf[0]);
b = *((uint64_t *)&p_buf[8]);
- };
+ }
};
Map<PathMD5, PackedFile> files;
@@ -98,10 +94,9 @@ private:
Vector<PackSource *> sources;
PackedDir *root;
- //Map<String,PackedDir*> dirs;
static PackedData *singleton;
- bool disabled;
+ bool disabled = false;
void _free_packed_dirs(PackedDir *p_dir);
@@ -113,7 +108,7 @@ public:
_FORCE_INLINE_ bool is_disabled() const { return disabled; }
static PackedData *get_singleton() { return singleton; }
- Error add_pack(const String &p_path, bool p_replace_files, const String &p_destination);
+ Error add_pack(const String &p_path, bool p_replace_files);
_FORCE_INLINE_ FileAccess *try_open_path(const String &p_path);
_FORCE_INLINE_ bool has_path(const String &p_path);
@@ -123,22 +118,19 @@ public:
};
class PackSource {
-
public:
- virtual bool try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination = "") = 0;
+ virtual bool try_open_pack(const String &p_path, bool p_replace_files) = 0;
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0;
virtual ~PackSource() {}
};
class PackedSourcePCK : public PackSource {
-
public:
- virtual bool try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination = "");
+ virtual bool try_open_pack(const String &p_path, bool p_replace_files);
virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
};
class FileAccessPack : public FileAccess {
-
PackedData::PackedFile pf;
mutable size_t pos;
@@ -181,29 +173,28 @@ public:
};
FileAccess *PackedData::try_open_path(const String &p_path) {
-
PathMD5 pmd5(p_path.md5_buffer());
Map<PathMD5, PackedFile>::Element *E = files.find(pmd5);
- if (!E)
+ if (!E) {
return nullptr; //not found
- if (E->get().offset == 0)
+ }
+ if (E->get().offset == 0) {
return nullptr; //was erased
+ }
return E->get().src->get_file(p_path, &E->get());
}
bool PackedData::has_path(const String &p_path) {
-
return files.has(PathMD5(p_path.md5_buffer()));
}
class DirAccessPack : public DirAccess {
-
PackedData::PackedDir *current;
List<String> list_dirs;
List<String> list_files;
- bool cdir;
+ bool cdir = false;
public:
virtual Error list_dir_begin();
@@ -231,7 +222,7 @@ public:
virtual String get_filesystem_type() const;
DirAccessPack();
- ~DirAccessPack();
+ ~DirAccessPack() {}
};
#endif // FILE_ACCESS_PACK_H
diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp
index 5696e47193..c3a62706c7 100644
--- a/core/io/file_access_zip.cpp
+++ b/core/io/file_access_zip.cpp
@@ -40,7 +40,6 @@ ZipArchive *ZipArchive::instance = nullptr;
extern "C" {
static void *godot_open(void *data, const char *p_fname, int mode) {
-
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
return nullptr;
}
@@ -52,30 +51,25 @@ static void *godot_open(void *data, const char *p_fname, int mode) {
}
static uLong godot_read(void *data, void *fdata, void *buf, uLong size) {
-
FileAccess *f = (FileAccess *)data;
f->get_buffer((uint8_t *)buf, size);
return size;
}
static uLong godot_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
-
return 0;
}
static long godot_tell(voidpf opaque, voidpf stream) {
-
FileAccess *f = (FileAccess *)opaque;
return f->get_position();
}
static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
-
FileAccess *f = (FileAccess *)opaque;
int pos = offset;
switch (origin) {
-
case ZLIB_FILEFUNC_SEEK_CUR:
pos = f->get_position() + offset;
break;
@@ -91,32 +85,27 @@ static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
}
static int godot_close(voidpf opaque, voidpf stream) {
-
FileAccess *f = (FileAccess *)opaque;
f->close();
return 0;
}
static int godot_testerror(voidpf opaque, voidpf stream) {
-
FileAccess *f = (FileAccess *)opaque;
return f->get_error() != OK ? 1 : 0;
}
static voidpf godot_alloc(voidpf opaque, uInt items, uInt size) {
-
return memalloc(items * size);
}
static void godot_free(voidpf opaque, voidpf address) {
-
memfree(address);
}
} // extern "C"
void ZipArchive::close_handle(unzFile p_file) const {
-
ERR_FAIL_COND_MSG(!p_file, "Cannot close a file if none is open.");
FileAccess *f = (FileAccess *)unzGetOpaque(p_file);
unzCloseCurrentFile(p_file);
@@ -125,7 +114,6 @@ void ZipArchive::close_handle(unzFile p_file) const {
}
unzFile ZipArchive::get_file_handle(String p_file) const {
-
ERR_FAIL_COND_V_MSG(!file_exists(p_file), nullptr, "File '" + p_file + " doesn't exist.");
File file = files[p_file];
@@ -152,7 +140,6 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
ERR_FAIL_COND_V(!pkg, nullptr);
int unz_err = unzGoToFilePos(pkg, &file.file_pos);
if (unz_err != UNZ_OK || unzOpenCurrentFile(pkg) != UNZ_OK) {
-
unzClose(pkg);
ERR_FAIL_V(nullptr);
}
@@ -160,17 +147,18 @@ unzFile ZipArchive::get_file_handle(String p_file) const {
return pkg;
}
-bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination) {
-
+bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) {
//printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz"));
- if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0)
+ if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0) {
return false;
+ }
zlib_filefunc_def io;
FileAccess *fa = FileAccess::open(p_path, FileAccess::READ);
- if (!fa)
+ if (!fa) {
return false;
+ }
io.opaque = fa;
io.zopen_file = godot_open;
io.zread_file = godot_read;
@@ -195,7 +183,6 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, const
int pkg_num = packages.size() - 1;
for (uint64_t i = 0; i < gi.number_entry; i++) {
-
char filename_inzip[256];
unz_file_info64 file_info;
@@ -206,26 +193,7 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, const
f.package = pkg_num;
unzGetFilePos(zfile, &f.file_pos);
- String fname;
- if (p_destination != "") {
- String destination = "res://" + p_destination;
- if (!destination.ends_with("/")) {
- destination += "/";
- }
-
- DirAccess *dir = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- if (!dir->dir_exists(destination)) {
- memdelete(dir);
-
- return false;
- }
- memdelete(dir);
-
- fname = destination + filename_inzip;
- } else {
- fname = String("res://") + filename_inzip;
- }
-
+ String fname = String("res://") + filename_inzip;
files[fname] = f;
uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -241,17 +209,14 @@ bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files, const
}
bool ZipArchive::file_exists(String p_name) const {
-
return files.has(p_name);
}
FileAccess *ZipArchive::get_file(const String &p_path, PackedData::PackedFile *p_file) {
-
return memnew(FileAccessZip(p_path, *p_file));
}
ZipArchive *ZipArchive::get_singleton() {
-
if (instance == nullptr) {
instance = memnew(ZipArchive);
}
@@ -260,15 +225,11 @@ ZipArchive *ZipArchive::get_singleton() {
}
ZipArchive::ZipArchive() {
-
instance = this;
- //fa_create_func = FileAccess::get_create_func();
}
ZipArchive::~ZipArchive() {
-
for (int i = 0; i < packages.size(); i++) {
-
FileAccess *f = (FileAccess *)unzGetOpaque(packages[i].zfile);
unzClose(packages[i].zfile);
memdelete(f);
@@ -278,7 +239,6 @@ ZipArchive::~ZipArchive() {
}
Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
-
close();
ERR_FAIL_COND_V(p_mode_flags & FileAccess::WRITE, FAILED);
@@ -294,9 +254,9 @@ Error FileAccessZip::_open(const String &p_path, int p_mode_flags) {
}
void FileAccessZip::close() {
-
- if (!zfile)
+ if (!zfile) {
return;
+ }
ZipArchive *arch = ZipArchive::get_singleton();
ERR_FAIL_COND(!arch);
@@ -305,65 +265,57 @@ void FileAccessZip::close() {
}
bool FileAccessZip::is_open() const {
-
return zfile != nullptr;
}
void FileAccessZip::seek(size_t p_position) {
-
ERR_FAIL_COND(!zfile);
unzSeekCurrentFile(zfile, p_position);
}
void FileAccessZip::seek_end(int64_t p_position) {
-
ERR_FAIL_COND(!zfile);
unzSeekCurrentFile(zfile, get_len() + p_position);
}
size_t FileAccessZip::get_position() const {
-
ERR_FAIL_COND_V(!zfile, 0);
return unztell(zfile);
}
size_t FileAccessZip::get_len() const {
-
ERR_FAIL_COND_V(!zfile, 0);
return file_info.uncompressed_size;
}
bool FileAccessZip::eof_reached() const {
-
ERR_FAIL_COND_V(!zfile, true);
return at_eof;
}
uint8_t FileAccessZip::get_8() const {
-
uint8_t ret = 0;
get_buffer(&ret, 1);
return ret;
}
int FileAccessZip::get_buffer(uint8_t *p_dst, int p_length) const {
-
ERR_FAIL_COND_V(!zfile, -1);
at_eof = unzeof(zfile);
- if (at_eof)
+ if (at_eof) {
return 0;
+ }
int read = unzReadCurrentFile(zfile, p_dst, p_length);
ERR_FAIL_COND_V(read < 0, read);
- if (read < p_length)
+ if (read < p_length) {
at_eof = true;
+ }
return read;
}
Error FileAccessZip::get_error() const {
-
if (!zfile) {
-
return ERR_UNCONFIGURED;
}
if (eof_reached()) {
@@ -374,28 +326,23 @@ Error FileAccessZip::get_error() const {
}
void FileAccessZip::flush() {
-
ERR_FAIL();
}
void FileAccessZip::store_8(uint8_t p_dest) {
-
ERR_FAIL();
}
bool FileAccessZip::file_exists(const String &p_name) {
-
return false;
}
-FileAccessZip::FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file) :
- zfile(nullptr) {
+FileAccessZip::FileAccessZip(const String &p_path, const PackedData::PackedFile &p_file) {
_open(p_path, FileAccess::READ);
}
FileAccessZip::~FileAccessZip() {
-
close();
}
-#endif
+#endif // MINIZIP_ENABLED
diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h
index 5bcaea7ed9..776e830f36 100644
--- a/core/io/file_access_zip.h
+++ b/core/io/file_access_zip.h
@@ -41,22 +41,17 @@
#include <stdlib.h>
class ZipArchive : public PackSource {
-
public:
struct File {
-
- int package;
+ int package = -1;
unz_file_pos file_pos;
- File() {
-
- package = -1;
- };
+ File() {}
};
private:
struct Package {
String filename;
- unzFile zfile;
+ unzFile zfile = nullptr;
};
Vector<Package> packages;
@@ -74,7 +69,7 @@ public:
bool file_exists(String p_name) const;
- virtual bool try_open_pack(const String &p_path, bool p_replace_files, const String &p_destination = "");
+ virtual bool try_open_pack(const String &p_path, bool p_replace_files);
FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file);
static ZipArchive *get_singleton();
@@ -84,7 +79,6 @@ public:
};
class FileAccessZip : public FileAccess {
-
unzFile zfile;
unz_file_info64 file_info;
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 56f8f1ff91..40debae9e5 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -47,7 +47,6 @@ const char *HTTPClient::_methods[METHOD_MAX] = {
#ifndef JAVASCRIPT_ENABLED
Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl, bool p_verify_host) {
-
close();
conn_port = p_port;
@@ -58,10 +57,8 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl,
String host_lower = conn_host.to_lower();
if (host_lower.begins_with("http://")) {
-
conn_host = conn_host.substr(7, conn_host.length() - 7);
} else if (host_lower.begins_with("https://")) {
-
ssl = true;
conn_host = conn_host.substr(8, conn_host.length() - 8);
}
@@ -97,7 +94,6 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl,
}
void HTTPClient::set_connection(const Ref<StreamPeer> &p_connection) {
-
ERR_FAIL_COND_MSG(p_connection.is_null(), "Connection is not a reference to a valid StreamPeer object.");
close();
@@ -106,12 +102,10 @@ void HTTPClient::set_connection(const Ref<StreamPeer> &p_connection) {
}
Ref<StreamPeer> HTTPClient::get_connection() const {
-
return connection;
}
Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) {
-
ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
@@ -179,7 +173,6 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector
}
Error HTTPClient::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body) {
-
ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(!p_url.begins_with("/"), ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
@@ -235,27 +228,23 @@ Error HTTPClient::request(Method p_method, const String &p_url, const Vector<Str
}
bool HTTPClient::has_response() const {
-
return response_headers.size() != 0;
}
bool HTTPClient::is_response_chunked() const {
-
return chunked;
}
int HTTPClient::get_response_code() const {
-
return response_num;
}
Error HTTPClient::get_response_headers(List<String> *r_response) {
-
- if (!response_headers.size())
+ if (!response_headers.size()) {
return ERR_INVALID_PARAMETER;
+ }
for (int i = 0; i < response_headers.size(); i++) {
-
r_response->push_back(response_headers[i]);
}
@@ -265,15 +254,14 @@ Error HTTPClient::get_response_headers(List<String> *r_response) {
}
void HTTPClient::close() {
-
- if (tcp_connection->get_status() != StreamPeerTCP::STATUS_NONE)
+ if (tcp_connection->get_status() != StreamPeerTCP::STATUS_NONE) {
tcp_connection->disconnect_from_host();
+ }
connection.unref();
status = STATUS_DISCONNECTED;
head_request = false;
if (resolving != IP::RESOLVER_INVALID_ID) {
-
IP::get_singleton()->erase_resolve_item(resolving);
resolving = IP::RESOLVER_INVALID_ID;
}
@@ -283,16 +271,14 @@ void HTTPClient::close() {
body_size = -1;
body_left = 0;
chunk_left = 0;
- chunk_trailer_part = 0;
+ chunk_trailer_part = false;
read_until_eof = false;
response_num = 0;
handshaking = false;
}
Error HTTPClient::poll() {
-
switch (status) {
-
case STATUS_RESOLVING: {
ERR_FAIL_COND_V(resolving == IP::RESOLVER_INVALID_ID, ERR_BUG);
@@ -302,7 +288,6 @@ Error HTTPClient::poll() {
return OK; // Still resolving
case IP::RESOLVER_STATUS_DONE: {
-
IP_Address host = IP::get_singleton()->get_resolve_item_address(resolving);
Error err = tcp_connection->connect_to_host(host, conn_port);
IP::get_singleton()->erase_resolve_item(resolving);
@@ -316,7 +301,6 @@ Error HTTPClient::poll() {
} break;
case IP::RESOLVER_STATUS_NONE:
case IP::RESOLVER_STATUS_ERROR: {
-
IP::get_singleton()->erase_resolve_item(resolving);
resolving = IP::RESOLVER_INVALID_ID;
close();
@@ -326,10 +310,8 @@ Error HTTPClient::poll() {
}
} break;
case STATUS_CONNECTING: {
-
StreamPeerTCP::Status s = tcp_connection->get_status();
switch (s) {
-
case StreamPeerTCP::STATUS_CONNECTING: {
return OK;
} break;
@@ -379,7 +361,6 @@ Error HTTPClient::poll() {
} break;
case StreamPeerTCP::STATUS_ERROR:
case StreamPeerTCP::STATUS_NONE: {
-
close();
status = STATUS_CANT_CONNECT;
return ERR_CANT_CONNECT;
@@ -404,7 +385,6 @@ Error HTTPClient::poll() {
return OK;
} break;
case STATUS_REQUESTING: {
-
while (true) {
uint8_t byte;
int rec = 0;
@@ -415,15 +395,15 @@ Error HTTPClient::poll() {
return ERR_CONNECTION_ERROR;
}
- if (rec == 0)
+ if (rec == 0) {
return OK; // Still requesting, keep trying!
+ }
response_str.push_back(byte);
int rs = response_str.size();
if (
(rs >= 2 && response_str[rs - 2] == '\n' && response_str[rs - 1] == '\n') ||
(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;
@@ -445,11 +425,11 @@ Error HTTPClient::poll() {
bool keep_alive = true;
for (int i = 0; i < responses.size(); i++) {
-
String header = responses[i].strip_edges();
String s = header.to_lower();
- if (s.length() == 0)
+ if (s.length() == 0) {
continue;
+ }
if (s.begins_with("content-length:")) {
body_size = s.substr(s.find(":") + 1, s.length()).strip_edges().to_int();
body_left = body_size;
@@ -464,11 +444,9 @@ Error HTTPClient::poll() {
}
if (i == 0 && responses[i].begins_with("HTTP")) {
-
String num = responses[i].get_slicec(' ', 1);
response_num = num.to_int();
} else {
-
response_headers.push_back(header);
}
}
@@ -480,14 +458,11 @@ Error HTTPClient::poll() {
}
if (body_size != -1 || chunked) {
-
status = STATUS_BODY;
} else if (!keep_alive) {
-
read_until_eof = true;
status = STATUS_BODY;
} else {
-
status = STATUS_CONNECTED;
}
return OK;
@@ -513,29 +488,26 @@ Error HTTPClient::poll() {
}
int HTTPClient::get_response_body_length() const {
-
return body_size;
}
PackedByteArray HTTPClient::read_response_body_chunk() {
-
ERR_FAIL_COND_V(status != STATUS_BODY, PackedByteArray());
PackedByteArray ret;
Error err = OK;
if (chunked) {
-
while (true) {
-
if (chunk_trailer_part) {
// We need to consume the trailer part too or keep-alive will break
uint8_t b;
int rec = 0;
err = _get_http_data(&b, 1, rec);
- if (rec == 0)
+ if (rec == 0) {
break;
+ }
chunk.push_back(b);
int cs = chunk.size();
@@ -557,8 +529,9 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
int rec = 0;
err = _get_http_data(&b, 1, rec);
- if (rec == 0)
+ if (rec == 0) {
break;
+ }
chunk.push_back(b);
@@ -569,18 +542,17 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
}
if (chunk.size() > 2 && chunk[chunk.size() - 2] == '\r' && chunk[chunk.size() - 1] == '\n') {
-
int len = 0;
for (int i = 0; i < chunk.size() - 2; i++) {
char c = chunk[i];
int v = 0;
- if (c >= '0' && c <= '9')
+ if (c >= '0' && c <= '9') {
v = c - '0';
- else if (c >= 'a' && c <= 'f')
+ } else if (c >= 'a' && c <= 'f') {
v = c - 'a' + 10;
- else if (c >= 'A' && c <= 'F')
+ } else if (c >= 'A' && c <= 'F') {
v = c - 'A' + 10;
- else {
+ } else {
ERR_PRINT("HTTP Chunk len not in hex!!");
status = STATUS_CONNECTION_ERROR;
break;
@@ -605,7 +577,6 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
chunk.resize(chunk_left);
}
} else {
-
int rec = 0;
err = _get_http_data(&chunk.write[chunk.size() - chunk_left], chunk_left, rec);
if (rec == 0) {
@@ -614,7 +585,6 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
chunk_left -= rec;
if (chunk_left == 0) {
-
if (chunk[chunk.size() - 2] != '\r' || chunk[chunk.size() - 1] != '\n') {
ERR_PRINT("HTTP Invalid chunk terminator (not \\r\\n)");
status = STATUS_CONNECTION_ERROR;
@@ -632,7 +602,6 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
}
} else {
-
int to_read = !read_until_eof ? MIN(body_left, read_chunk_size) : read_chunk_size;
ret.resize(to_read);
int _offset = 0;
@@ -652,24 +621,21 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
body_left -= rec;
}
}
- if (err != OK)
+ if (err != OK) {
break;
+ }
}
}
if (err != OK) {
-
close();
if (err == ERR_FILE_EOF) {
-
status = STATUS_DISCONNECTED; // Server disconnected
} else {
-
status = STATUS_CONNECTION_ERROR;
}
} else if (body_left == 0 && !chunked && !read_until_eof) {
-
status = STATUS_CONNECTED;
}
@@ -677,24 +643,19 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
}
HTTPClient::Status HTTPClient::get_status() const {
-
return status;
}
void HTTPClient::set_blocking_mode(bool p_enable) {
-
blocking = p_enable;
}
bool HTTPClient::is_blocking_mode_enabled() const {
-
return blocking;
}
Error HTTPClient::_get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received) {
-
if (blocking) {
-
// We can't use StreamPeer.get_data, since when reaching EOF we will get an
// error without knowing how many bytes we received.
Error err = ERR_FILE_EOF;
@@ -729,27 +690,10 @@ int HTTPClient::get_read_chunk_size() const {
}
HTTPClient::HTTPClient() {
-
tcp_connection.instance();
- resolving = IP::RESOLVER_INVALID_ID;
- status = STATUS_DISCONNECTED;
- head_request = false;
- conn_port = -1;
- body_size = -1;
- chunked = false;
- body_left = 0;
- read_until_eof = false;
- chunk_left = 0;
- chunk_trailer_part = false;
- response_num = 0;
- ssl = false;
- blocking = false;
- handshaking = false;
- read_chunk_size = 4096;
}
-HTTPClient::~HTTPClient() {
-}
+HTTPClient::~HTTPClient() {}
#endif // #ifndef JAVASCRIPT_ENABLED
@@ -784,15 +728,15 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) {
}
Dictionary HTTPClient::_get_response_headers_as_dictionary() {
-
List<String> rh;
get_response_headers(&rh);
Dictionary ret;
for (const List<String>::Element *E = rh.front(); E; E = E->next()) {
const String &s = E->get();
int sp = s.find(":");
- if (sp == -1)
+ if (sp == -1) {
continue;
+ }
String key = s.substr(0, sp).strip_edges();
String value = s.substr(sp + 1, s.length()).strip_edges();
ret[key] = value;
@@ -802,7 +746,6 @@ Dictionary HTTPClient::_get_response_headers_as_dictionary() {
}
PackedStringArray HTTPClient::_get_response_headers() {
-
List<String> rh;
get_response_headers(&rh);
PackedStringArray ret;
@@ -816,7 +759,6 @@ PackedStringArray HTTPClient::_get_response_headers() {
}
void HTTPClient::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port", "use_ssl", "verify_host"), &HTTPClient::connect_to_host, DEFVAL(-1), DEFVAL(false), DEFVAL(true));
ClassDB::bind_method(D_METHOD("set_connection", "connection"), &HTTPClient::set_connection);
ClassDB::bind_method(D_METHOD("get_connection"), &HTTPClient::get_connection);
diff --git a/core/io/http_client.h b/core/io/http_client.h
index 03ba20f8dd..1dc1f3d76a 100644
--- a/core/io/http_client.h
+++ b/core/io/http_client.h
@@ -37,7 +37,6 @@
#include "core/reference.h"
class HTTPClient : public Reference {
-
GDCLASS(HTTPClient, Reference);
public:
@@ -158,32 +157,32 @@ private:
};
#ifndef JAVASCRIPT_ENABLED
- Status status;
- IP::ResolverID resolving;
- int conn_port;
+ Status status = STATUS_DISCONNECTED;
+ IP::ResolverID resolving = IP::RESOLVER_INVALID_ID;
+ int conn_port = -1;
String conn_host;
- bool ssl;
- bool ssl_verify_host;
- bool blocking;
- bool handshaking;
- bool head_request;
+ bool ssl = false;
+ bool ssl_verify_host = false;
+ bool blocking = false;
+ bool handshaking = false;
+ bool head_request = false;
Vector<uint8_t> response_str;
- bool chunked;
+ bool chunked = false;
Vector<uint8_t> chunk;
- int chunk_left;
- bool chunk_trailer_part;
- int body_size;
- int body_left;
- bool read_until_eof;
+ int chunk_left = 0;
+ bool chunk_trailer_part = false;
+ int body_size = -1;
+ int body_left = 0;
+ bool read_until_eof = false;
Ref<StreamPeerTCP> tcp_connection;
Ref<StreamPeer> connection;
- int response_num;
+ int response_num = 0;
Vector<String> response_headers;
- int read_chunk_size;
+ int read_chunk_size = 4096;
Error _get_http_data(uint8_t *p_buffer, int p_bytes, int &r_received);
diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp
index 2770adbd36..b1e92eb87f 100644
--- a/core/io/image_loader.cpp
+++ b/core/io/image_loader.cpp
@@ -33,13 +33,12 @@
#include "core/print_string.h"
bool ImageFormatLoader::recognize(const String &p_extension) const {
-
List<String> extensions;
get_recognized_extensions(&extensions);
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
-
- if (E->get().nocasecmp_to(p_extension) == 0)
+ if (E->get().nocasecmp_to(p_extension) == 0) {
return true;
+ }
}
return false;
@@ -61,43 +60,41 @@ Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_c
String extension = p_file.get_extension();
for (int i = 0; i < loader.size(); i++) {
-
- if (!loader[i]->recognize(extension))
+ if (!loader[i]->recognize(extension)) {
continue;
+ }
Error err = loader[i]->load_image(p_image, f, p_force_linear, p_scale);
if (err != OK) {
ERR_PRINT("Error loading image: " + p_file);
}
if (err != ERR_FILE_UNRECOGNIZED) {
-
- if (!p_custom)
+ if (!p_custom) {
memdelete(f);
+ }
return err;
}
}
- if (!p_custom)
+ if (!p_custom) {
memdelete(f);
+ }
return ERR_FILE_UNRECOGNIZED;
}
void ImageLoader::get_recognized_extensions(List<String> *p_extensions) {
-
for (int i = 0; i < loader.size(); i++) {
-
loader[i]->get_recognized_extensions(p_extensions);
}
}
ImageFormatLoader *ImageLoader::recognize(const String &p_extension) {
-
for (int i = 0; i < loader.size(); i++) {
-
- if (loader[i]->recognize(p_extension))
+ if (loader[i]->recognize(p_extension)) {
return loader[i];
+ }
}
return nullptr;
@@ -106,22 +103,18 @@ ImageFormatLoader *ImageLoader::recognize(const String &p_extension) {
Vector<ImageFormatLoader *> ImageLoader::loader;
void ImageLoader::add_image_format_loader(ImageFormatLoader *p_loader) {
-
loader.push_back(p_loader);
}
void ImageLoader::remove_image_format_loader(ImageFormatLoader *p_loader) {
-
loader.erase(p_loader);
}
const Vector<ImageFormatLoader *> &ImageLoader::get_image_format_loaders() {
-
return loader;
}
void ImageLoader::cleanup() {
-
while (loader.size()) {
remove_image_format_loader(loader[0]);
}
@@ -129,8 +122,7 @@ void ImageLoader::cleanup() {
/////////////////
-RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
+RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
if (r_error) {
@@ -192,16 +184,13 @@ RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_origin
}
void ResourceFormatLoaderImage::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("image");
}
bool ResourceFormatLoaderImage::handles_type(const String &p_type) const {
-
return p_type == "Image";
}
String ResourceFormatLoaderImage::get_resource_type(const String &p_path) const {
-
return p_path.get_extension().to_lower() == "image" ? "Image" : String();
}
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index 18b4df98f7..9682f144c7 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -53,7 +53,6 @@ public:
};
class ImageLoader {
-
static Vector<ImageFormatLoader *> loader;
friend class ResourceFormatLoaderImage;
@@ -73,7 +72,7 @@ public:
class ResourceFormatLoaderImage : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index 5de7fb7186..24b8ec7cc1 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -39,9 +39,7 @@ VARIANT_ENUM_CAST(IP::ResolverStatus);
/************* RESOLVER ******************/
struct _IP_ResolverPrivate {
-
struct QueueItem {
-
volatile IP::ResolverStatus status;
IP_Address response;
String hostname;
@@ -56,16 +54,16 @@ struct _IP_ResolverPrivate {
QueueItem() {
clear();
- };
+ }
};
QueueItem queue[IP::RESOLVER_MAX_QUERIES];
IP::ResolverID find_empty_id() const {
-
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
- if (queue[i].status == IP::RESOLVER_STATUS_NONE)
+ if (queue[i].status == IP::RESOLVER_STATUS_NONE) {
return i;
+ }
}
return IP::RESOLVER_INVALID_ID;
}
@@ -78,26 +76,24 @@ struct _IP_ResolverPrivate {
bool thread_abort;
void resolve_queues() {
-
for (int i = 0; i < IP::RESOLVER_MAX_QUERIES; i++) {
-
- if (queue[i].status != IP::RESOLVER_STATUS_WAITING)
+ if (queue[i].status != IP::RESOLVER_STATUS_WAITING) {
continue;
+ }
queue[i].response = IP::get_singleton()->resolve_hostname(queue[i].hostname, queue[i].type);
- if (!queue[i].response.is_valid())
+ if (!queue[i].response.is_valid()) {
queue[i].status = IP::RESOLVER_STATUS_ERROR;
- else
+ } else {
queue[i].status = IP::RESOLVER_STATUS_DONE;
+ }
}
}
static void _thread_function(void *self) {
-
_IP_ResolverPrivate *ipr = (_IP_ResolverPrivate *)self;
while (!ipr->thread_abort) {
-
ipr->sem.wait();
MutexLock lock(ipr->mutex);
@@ -113,7 +109,6 @@ struct _IP_ResolverPrivate {
};
IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
-
MutexLock lock(resolver->mutex);
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
@@ -128,7 +123,6 @@ IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
}
IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Type p_type) {
-
MutexLock lock(resolver->mutex);
ResolverID id = resolver->find_empty_id();
@@ -147,17 +141,17 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
} else {
resolver->queue[id].response = IP_Address();
resolver->queue[id].status = IP::RESOLVER_STATUS_WAITING;
- if (resolver->thread)
+ if (resolver->thread) {
resolver->sem.post();
- else
+ } else {
resolver->resolve_queues();
+ }
}
return id;
}
IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
-
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP::RESOLVER_STATUS_NONE);
MutexLock lock(resolver->mutex);
@@ -171,7 +165,6 @@ IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
}
IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
-
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP_Address());
MutexLock lock(resolver->mutex);
@@ -186,7 +179,6 @@ IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
}
void IP::erase_resolve_item(ResolverID p_id) {
-
ERR_FAIL_INDEX(p_id, IP::RESOLVER_MAX_QUERIES);
MutexLock lock(resolver->mutex);
@@ -195,7 +187,6 @@ void IP::erase_resolve_item(ResolverID p_id) {
}
void IP::clear_cache(const String &p_hostname) {
-
MutexLock lock(resolver->mutex);
if (p_hostname.empty()) {
@@ -209,7 +200,6 @@ void IP::clear_cache(const String &p_hostname) {
}
Array IP::_get_local_addresses() const {
-
Array addresses;
List<IP_Address> ip_addresses;
get_local_addresses(&ip_addresses);
@@ -221,7 +211,6 @@ Array IP::_get_local_addresses() const {
}
Array IP::_get_local_interfaces() const {
-
Array results;
Map<String, Interface_Info> interfaces;
get_local_interfaces(&interfaces);
@@ -245,7 +234,6 @@ Array IP::_get_local_interfaces() const {
}
void IP::get_local_addresses(List<IP_Address> *r_addresses) const {
-
Map<String, Interface_Info> interfaces;
get_local_interfaces(&interfaces);
for (Map<String, Interface_Info>::Element *E = interfaces.front(); E; E = E->next()) {
@@ -256,7 +244,6 @@ void IP::get_local_addresses(List<IP_Address> *r_addresses) const {
}
void IP::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("resolve_hostname", "host", "ip_type"), &IP::resolve_hostname, DEFVAL(IP::TYPE_ANY));
ClassDB::bind_method(D_METHOD("resolve_hostname_queue_item", "host", "ip_type"), &IP::resolve_hostname_queue_item, DEFVAL(IP::TYPE_ANY));
ClassDB::bind_method(D_METHOD("get_resolve_item_status", "id"), &IP::get_resolve_item_status);
@@ -283,21 +270,18 @@ void IP::_bind_methods() {
IP *IP::singleton = nullptr;
IP *IP::get_singleton() {
-
return singleton;
}
IP *(*IP::_create)() = nullptr;
IP *IP::create() {
-
ERR_FAIL_COND_V_MSG(singleton, nullptr, "IP singleton already exist.");
ERR_FAIL_COND_V(!_create, nullptr);
return _create();
}
IP::IP() {
-
singleton = this;
resolver = memnew(_IP_ResolverPrivate);
@@ -312,7 +296,6 @@ IP::IP() {
}
IP::~IP() {
-
#ifndef NO_THREADS
if (resolver->thread) {
resolver->thread_abort = true;
diff --git a/core/io/ip_address.cpp b/core/io/ip_address.cpp
index f5fd8ae205..c7a0ae5605 100644
--- a/core/io/ip_address.cpp
+++ b/core/io/ip_address.cpp
@@ -39,40 +39,40 @@ IP_Address::operator Variant() const {
#include <string.h>
IP_Address::operator String() const {
-
- if (wildcard)
+ if (wildcard) {
return "*";
+ }
- if (!valid)
+ if (!valid) {
return "";
+ }
- if (is_ipv4())
+ if (is_ipv4()) {
// IPv4 address mapped to IPv6
return itos(field8[12]) + "." + itos(field8[13]) + "." + itos(field8[14]) + "." + itos(field8[15]);
+ }
String ret;
for (int i = 0; i < 8; i++) {
- if (i > 0)
+ if (i > 0) {
ret = ret + ":";
+ }
uint16_t num = (field8[i * 2] << 8) + field8[i * 2 + 1];
ret = ret + String::num_int64(num, 16);
- };
+ }
return ret;
}
static void _parse_hex(const String &p_string, int p_start, uint8_t *p_dst) {
-
uint16_t ret = 0;
for (int i = p_start; i < p_start + 4; i++) {
-
if (i >= p_string.length()) {
break;
- };
+ }
int n = 0;
CharType c = p_string[i];
if (c >= '0' && c <= '9') {
-
n = c - '0';
} else if (c >= 'a' && c <= 'f') {
n = 10 + (c - 'a');
@@ -82,17 +82,16 @@ static void _parse_hex(const String &p_string, int p_start, uint8_t *p_dst) {
break;
} else {
ERR_FAIL_MSG("Invalid character in IPv6 address: " + p_string + ".");
- };
+ }
ret = ret << 4;
ret += n;
- };
+ }
p_dst[0] = ret >> 8;
p_dst[1] = ret & 0xff;
-};
+}
void IP_Address::_parse_ipv6(const String &p_string) {
-
static const int parts_total = 8;
int parts[parts_total] = { 0 };
int parts_count = 0;
@@ -102,20 +101,17 @@ void IP_Address::_parse_ipv6(const String &p_string) {
int parts_idx = 0;
for (int i = 0; i < p_string.length(); i++) {
-
CharType c = p_string[i];
if (c == ':') {
-
if (i == 0) {
continue; // next must be a ":"
- };
+ }
if (!part_found) {
part_skip = true;
parts[parts_idx++] = -1;
- };
+ }
part_found = false;
} else if (c == '.') {
-
part_ipv4 = true;
} else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
@@ -123,58 +119,54 @@ void IP_Address::_parse_ipv6(const String &p_string) {
parts[parts_idx++] = i;
part_found = true;
++parts_count;
- };
+ }
} else {
ERR_FAIL_MSG("Invalid character in IPv6 address: " + p_string + ".");
- };
- };
+ }
+ }
int parts_extra = 0;
if (part_skip) {
parts_extra = parts_total - parts_count;
- };
+ }
int idx = 0;
for (int i = 0; i < parts_idx; i++) {
-
if (parts[i] == -1) {
-
for (int j = 0; j < parts_extra; j++) {
field16[idx++] = 0;
- };
+ }
continue;
- };
+ }
if (part_ipv4 && i == parts_idx - 1) {
_parse_ipv4(p_string, parts[i], (uint8_t *)&field16[idx]); // should be the last one
} else {
_parse_hex(p_string, parts[i], (uint8_t *)&(field16[idx++]));
- };
- };
-};
+ }
+ }
+}
void IP_Address::_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);
} else {
ip = p_string;
- };
+ }
int slices = ip.get_slice_count(".");
ERR_FAIL_COND_MSG(slices != 4, "Invalid IP address string: " + ip + ".");
for (int i = 0; i < 4; i++) {
p_ret[i] = ip.get_slicec('.', i).to_int();
}
-};
+}
void IP_Address::clear() {
-
memset(&field8[0], 0, sizeof(field8));
valid = false;
wildcard = false;
-};
+}
bool IP_Address::is_ipv4() const {
return (field32[0] == 0 && field32[1] == 0 && field16[4] == 0 && field16[5] == 0xffff);
@@ -199,12 +191,12 @@ const uint8_t *IP_Address::get_ipv6() const {
void IP_Address::set_ipv6(const uint8_t *p_buf) {
clear();
valid = true;
- for (int i = 0; i < 16; i++)
+ for (int i = 0; i < 16; i++) {
field8[i] = p_buf[i];
+ }
}
IP_Address::IP_Address(const String &p_string) {
-
clear();
if (p_string == "*") {
@@ -228,15 +220,13 @@ IP_Address::IP_Address(const String &p_string) {
}
_FORCE_INLINE_ static void _32_to_buf(uint8_t *p_dst, uint32_t p_n) {
-
p_dst[0] = (p_n >> 24) & 0xff;
p_dst[1] = (p_n >> 16) & 0xff;
p_dst[2] = (p_n >> 8) & 0xff;
p_dst[3] = (p_n >> 0) & 0xff;
-};
+}
IP_Address::IP_Address(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, bool is_v6) {
-
clear();
valid = true;
if (!is_v6) {
@@ -247,7 +237,6 @@ IP_Address::IP_Address(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d, b
field8[14] = p_c;
field8[15] = p_d;
} else {
-
_32_to_buf(&field8[0], p_a);
_32_to_buf(&field8[4], p_b);
_32_to_buf(&field8[8], p_c);
diff --git a/core/io/ip_address.h b/core/io/ip_address.h
index 89cf37ff8f..2f8f83503e 100644
--- a/core/io/ip_address.h
+++ b/core/io/ip_address.h
@@ -34,7 +34,6 @@
#include "core/ustring.h"
struct IP_Address {
-
private:
union {
uint8_t field8[16];
@@ -52,19 +51,32 @@ protected:
public:
//operator Variant() const;
bool operator==(const IP_Address &p_ip) const {
- if (p_ip.valid != valid) return false;
- if (!valid) return false;
- for (int i = 0; i < 4; i++)
- if (field32[i] != p_ip.field32[i])
+ if (p_ip.valid != valid) {
+ return false;
+ }
+ if (!valid) {
+ return false;
+ }
+ for (int i = 0; i < 4; i++) {
+ if (field32[i] != p_ip.field32[i]) {
return false;
+ }
+ }
return true;
}
+
bool operator!=(const IP_Address &p_ip) const {
- if (p_ip.valid != valid) return true;
- if (!valid) return true;
- for (int i = 0; i < 4; i++)
- if (field32[i] != p_ip.field32[i])
+ if (p_ip.valid != valid) {
+ return true;
+ }
+ if (!valid) {
+ return true;
+ }
+ for (int i = 0; i < 4; i++) {
+ if (field32[i] != p_ip.field32[i]) {
return true;
+ }
+ }
return false;
}
diff --git a/core/io/json.cpp b/core/io/json.cpp
index 3a0edceb81..1c603865ad 100644
--- a/core/io/json.cpp
+++ b/core/io/json.cpp
@@ -46,17 +46,16 @@ const char *JSON::tk_name[TK_MAX] = {
};
static String _make_indent(const String &p_indent, int p_size) {
-
String indent_text = "";
if (!p_indent.empty()) {
- for (int i = 0; i < p_size; i++)
+ for (int i = 0; i < p_size; i++) {
indent_text += p_indent;
+ }
}
return indent_text;
}
String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys) {
-
String colon = ":";
String end_statement = "";
@@ -66,18 +65,20 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
}
switch (p_var.get_type()) {
-
- case Variant::NIL: return "null";
- case Variant::BOOL: return p_var.operator bool() ? "true" : "false";
- case Variant::INT: return itos(p_var);
- case Variant::FLOAT: return rtos(p_var);
+ case Variant::NIL:
+ return "null";
+ case Variant::BOOL:
+ return p_var.operator bool() ? "true" : "false";
+ case Variant::INT:
+ return itos(p_var);
+ case Variant::FLOAT:
+ return rtos(p_var);
case Variant::PACKED_INT32_ARRAY:
case Variant::PACKED_INT64_ARRAY:
case Variant::PACKED_FLOAT32_ARRAY:
case Variant::PACKED_FLOAT64_ARRAY:
case Variant::PACKED_STRING_ARRAY:
case Variant::ARRAY: {
-
String s = "[";
s += end_statement;
Array a = p_var;
@@ -90,20 +91,19 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
}
s += end_statement + _make_indent(p_indent, p_cur_indent) + "]";
return s;
- };
+ }
case Variant::DICTIONARY: {
-
String s = "{";
s += end_statement;
Dictionary d = p_var;
List<Variant> keys;
d.get_key_list(&keys);
- if (p_sort_keys)
+ if (p_sort_keys) {
keys.sort();
+ }
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
if (E != keys.front()) {
s += ",";
s += end_statement;
@@ -115,69 +115,59 @@ String JSON::_print_var(const Variant &p_var, const String &p_indent, int p_cur_
s += end_statement + _make_indent(p_indent, p_cur_indent) + "}";
return s;
- };
- default: return "\"" + String(p_var).json_escape() + "\"";
+ }
+ default:
+ return "\"" + String(p_var).json_escape() + "\"";
}
}
String JSON::print(const Variant &p_var, const String &p_indent, bool p_sort_keys) {
-
return _print_var(p_var, p_indent, 0, p_sort_keys);
}
Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str) {
-
while (p_len > 0) {
switch (p_str[index]) {
-
case '\n': {
-
line++;
index++;
break;
- };
+ }
case 0: {
r_token.type = TK_EOF;
return OK;
} break;
case '{': {
-
r_token.type = TK_CURLY_BRACKET_OPEN;
index++;
return OK;
- };
+ }
case '}': {
-
r_token.type = TK_CURLY_BRACKET_CLOSE;
index++;
return OK;
- };
+ }
case '[': {
-
r_token.type = TK_BRACKET_OPEN;
index++;
return OK;
- };
+ }
case ']': {
-
r_token.type = TK_BRACKET_CLOSE;
index++;
return OK;
- };
+ }
case ':': {
-
r_token.type = TK_COLON;
index++;
return OK;
- };
+ }
case ',': {
-
r_token.type = TK_COMMA;
index++;
return OK;
- };
+ }
case '"': {
-
index++;
String str;
while (true) {
@@ -198,12 +188,21 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
CharType res = 0;
switch (next) {
-
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'f': res = 12; break;
- case 'r': res = 13; break;
+ case 'b':
+ res = 8;
+ break;
+ case 't':
+ res = 9;
+ break;
+ case 'n':
+ res = 10;
+ break;
+ case 'f':
+ res = 12;
+ break;
+ case 'r':
+ res = 13;
+ break;
case 'u': {
// hex number
for (int j = 0; j < 4; j++) {
@@ -213,7 +212,6 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
return ERR_PARSE_ERROR;
}
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
-
r_err_str = "Malformed hex constant in string";
return ERR_PARSE_ERROR;
}
@@ -245,8 +243,9 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
str += res;
} else {
- if (p_str[index] == '\n')
+ if (p_str[index] == '\n') {
line++;
+ }
str += p_str[index];
}
index++;
@@ -258,7 +257,6 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
} break;
default: {
-
if (p_str[index] <= 32) {
index++;
break;
@@ -274,11 +272,9 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
return OK;
} else if ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) {
-
String id;
while ((p_str[index] >= 'A' && p_str[index] <= 'Z') || (p_str[index] >= 'a' && p_str[index] <= 'z')) {
-
id += p_str[index];
index++;
}
@@ -298,45 +294,41 @@ Error JSON::_get_token(const CharType *p_str, int &index, int p_len, Token &r_to
}
Error JSON::_parse_value(Variant &value, Token &token, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
-
if (token.type == TK_CURLY_BRACKET_OPEN) {
-
Dictionary d;
Error err = _parse_object(d, p_str, index, p_len, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
value = d;
return OK;
} else if (token.type == TK_BRACKET_OPEN) {
-
Array a;
Error err = _parse_array(a, p_str, index, p_len, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
value = a;
return OK;
} else if (token.type == TK_IDENTIFIER) {
-
String id = token.value;
- if (id == "true")
+ if (id == "true") {
value = true;
- else if (id == "false")
+ } else if (id == "false") {
value = false;
- else if (id == "null")
+ } else if (id == "null") {
value = Variant();
- else {
+ } else {
r_err_str = "Expected 'true','false' or 'null', got '" + id + "'.";
return ERR_PARSE_ERROR;
}
return OK;
} else if (token.type == TK_NUMBER) {
-
value = token.value;
return OK;
} else if (token.type == TK_STRING) {
-
value = token.value;
return OK;
} else {
@@ -346,25 +338,21 @@ Error JSON::_parse_value(Variant &value, Token &token, const CharType *p_str, in
}
Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
-
Token token;
bool need_comma = false;
while (index < p_len) {
-
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
if (token.type == TK_BRACKET_CLOSE) {
-
return OK;
}
if (need_comma) {
-
if (token.type != TK_COMMA) {
-
r_err_str = "Expected ','";
return ERR_PARSE_ERROR;
} else {
@@ -375,8 +363,9 @@ Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_
Variant v;
err = _parse_value(v, token, p_str, index, p_len, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
array.push_back(v);
need_comma = true;
@@ -386,29 +375,24 @@ Error JSON::_parse_array(Array &array, const CharType *p_str, int &index, int p_
}
Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index, int p_len, int &line, String &r_err_str) {
-
bool at_key = true;
String key;
Token token;
bool need_comma = false;
while (index < p_len) {
-
if (at_key) {
-
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
if (token.type == TK_CURLY_BRACKET_CLOSE) {
-
return OK;
}
if (need_comma) {
-
if (token.type != TK_COMMA) {
-
r_err_str = "Expected '}' or ','";
return ERR_PARSE_ERROR;
} else {
@@ -418,31 +402,31 @@ Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index,
}
if (token.type != TK_STRING) {
-
r_err_str = "Expected key";
return ERR_PARSE_ERROR;
}
key = token.value;
err = _get_token(p_str, index, p_len, token, line, r_err_str);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
if (token.type != TK_COLON) {
-
r_err_str = "Expected ':'";
return ERR_PARSE_ERROR;
}
at_key = false;
} else {
-
Error err = _get_token(p_str, index, p_len, token, line, r_err_str);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
Variant v;
err = _parse_value(v, token, p_str, index, p_len, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
object[key] = v;
need_comma = true;
at_key = true;
@@ -453,7 +437,6 @@ Error JSON::_parse_object(Dictionary &object, const CharType *p_str, int &index,
}
Error JSON::parse(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line) {
-
const CharType *str = p_json.ptr();
int idx = 0;
int len = p_json.length();
@@ -462,8 +445,9 @@ Error JSON::parse(const String &p_json, Variant &r_ret, String &r_err_str, int &
String aux_key;
Error err = _get_token(str, idx, len, token, r_err_line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
err = _parse_value(r_ret, token, str, idx, len, r_err_line, r_err_str);
diff --git a/core/io/json.h b/core/io/json.h
index 2e851afcf4..4fc5630a93 100644
--- a/core/io/json.h
+++ b/core/io/json.h
@@ -34,7 +34,6 @@
#include "core/variant.h"
class JSON {
-
enum TokenType {
TK_CURLY_BRACKET_OPEN,
TK_CURLY_BRACKET_CLOSE,
@@ -58,7 +57,6 @@ class JSON {
};
struct Token {
-
TokenType type;
Variant value;
};
diff --git a/core/io/logger.cpp b/core/io/logger.cpp
index 48aebeda3d..ef78b1194e 100644
--- a/core/io/logger.cpp
+++ b/core/io/logger.cpp
@@ -34,17 +34,6 @@
#include "core/os/os.h"
#include "core/print_string.h"
-// va_copy was defined in the C99, but not in C++ standards before C++11.
-// When you compile C++ without --std=c++<XX> option, compilers still define
-// va_copy, otherwise you have to use the internal version (__va_copy).
-#if !defined(va_copy)
-#if defined(__GNUC__)
-#define va_copy(d, s) __va_copy((d), (s))
-#else
-#define va_copy(d, s) ((d) = (s))
-#endif
-#endif
-
#if defined(MINGW_ENABLED) || defined(_MSC_VER)
#define sprintf sprintf_s
#endif
@@ -60,18 +49,29 @@ void Logger::log_error(const char *p_function, const char *p_file, int p_line, c
const char *err_type = "ERROR";
switch (p_type) {
- case ERR_ERROR: err_type = "ERROR"; break;
- case ERR_WARNING: err_type = "WARNING"; break;
- case ERR_SCRIPT: err_type = "SCRIPT ERROR"; break;
- case ERR_SHADER: err_type = "SHADER ERROR"; break;
- default: ERR_PRINT("Unknown error type"); break;
+ case ERR_ERROR:
+ err_type = "ERROR";
+ break;
+ case ERR_WARNING:
+ err_type = "WARNING";
+ break;
+ case ERR_SCRIPT:
+ err_type = "SCRIPT ERROR";
+ break;
+ case ERR_SHADER:
+ err_type = "SHADER ERROR";
+ break;
+ default:
+ ERR_PRINT("Unknown error type");
+ break;
}
const char *err_details;
- if (p_rationale && *p_rationale)
+ if (p_rationale && *p_rationale) {
err_details = p_rationale;
- else
+ } else {
err_details = p_code;
+ }
logf_error("%s: %s\n", err_type, err_details);
logf_error(" at: %s (%s:%i) - %s\n", p_function, p_file, p_line, p_code);
@@ -103,8 +103,6 @@ void Logger::logf_error(const char *p_format, ...) {
va_end(argp);
}
-Logger::~Logger() {}
-
void RotatedFileLogger::close_file() {
if (file) {
memdelete(file);
@@ -181,8 +179,7 @@ void RotatedFileLogger::rotate_file() {
RotatedFileLogger::RotatedFileLogger(const String &p_base_path, int p_max_files) :
base_path(p_base_path.simplify_path()),
- max_files(p_max_files > 0 ? p_max_files : 1),
- file(nullptr) {
+ max_files(p_max_files > 0 ? p_max_files : 1) {
rotate_file();
}
@@ -237,8 +234,6 @@ void StdLogger::logv(const char *p_format, va_list p_list, bool p_err) {
}
}
-StdLogger::~StdLogger() {}
-
CompositeLogger::CompositeLogger(Vector<Logger *> p_loggers) :
loggers(p_loggers) {
}
diff --git a/core/io/logger.h b/core/io/logger.h
index 7028551185..277be9ed35 100644
--- a/core/io/logger.h
+++ b/core/io/logger.h
@@ -55,17 +55,16 @@ public:
void logf(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
void logf_error(const char *p_format, ...) _PRINTF_FORMAT_ATTRIBUTE_2_3;
- virtual ~Logger();
+ virtual ~Logger() {}
};
/**
* Writes messages to stdout/stderr.
*/
class StdLogger : public Logger {
-
public:
virtual void logv(const char *p_format, va_list p_list, bool p_err) _PRINTF_FORMAT_ATTRIBUTE_2_0;
- virtual ~StdLogger();
+ virtual ~StdLogger() {}
};
/**
@@ -78,7 +77,7 @@ class RotatedFileLogger : public Logger {
String base_path;
int max_files;
- FileAccess *file;
+ FileAccess *file = nullptr;
void rotate_file_without_closing();
void close_file();
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index 81bc45b2f7..eb39b1433f 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -49,13 +49,9 @@ void EncodedObjectAsID::set_object_id(ObjectID p_id) {
}
ObjectID EncodedObjectAsID::get_object_id() const {
-
return id;
}
-EncodedObjectAsID::EncodedObjectAsID() {
-}
-
#define _S(a) ((int32_t)a)
#define ERR_FAIL_ADD_OF(a, b, err) ERR_FAIL_COND_V(_S(b) < 0 || _S(a) < 0 || _S(a) > INT_MAX - _S(b), err)
#define ERR_FAIL_MUL_OF(a, b, err) ERR_FAIL_COND_V(_S(a) < 0 || _S(b) <= 0 || _S(a) > INT_MAX / _S(b), err)
@@ -100,7 +96,6 @@ static Error _decode_string(const uint8_t *&buf, int &len, int *r_len, String &r
}
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len, bool p_allow_objects) {
-
const uint8_t *buf = p_buffer;
int len = p_len;
@@ -112,95 +107,95 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
buf += 4;
len -= 4;
- if (r_len)
+ if (r_len) {
*r_len = 4;
+ }
switch (type & ENCODE_MASK) {
-
case Variant::NIL: {
-
r_variant = Variant();
} break;
case Variant::BOOL: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
bool val = decode_uint32(buf);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4;
+ }
} break;
case Variant::INT: {
-
if (type & ENCODE_FLAG_64) {
ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
int64_t val = decode_uint64(buf);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 8;
+ }
} else {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t val = decode_uint32(buf);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4;
+ }
}
} break;
case Variant::FLOAT: {
-
if (type & ENCODE_FLAG_64) {
ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
double val = decode_double(buf);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 8;
+ }
} else {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
float val = decode_float(buf);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4;
+ }
}
} break;
case Variant::STRING: {
-
String str;
Error err = _decode_string(buf, len, r_len, str);
- if (err)
+ if (err) {
return err;
+ }
r_variant = str;
} break;
// math types
case Variant::VECTOR2: {
-
ERR_FAIL_COND_V(len < 4 * 2, ERR_INVALID_DATA);
Vector2 val;
val.x = decode_float(&buf[0]);
val.y = decode_float(&buf[4]);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 2;
+ }
} break;
case Variant::VECTOR2I: {
-
ERR_FAIL_COND_V(len < 4 * 2, ERR_INVALID_DATA);
Vector2i val;
val.x = decode_uint32(&buf[0]);
val.y = decode_uint32(&buf[4]);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 2;
+ }
} break;
case Variant::RECT2: {
-
ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA);
Rect2 val;
val.position.x = decode_float(&buf[0]);
@@ -209,12 +204,12 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.size.y = decode_float(&buf[12]);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 4;
+ }
} break;
case Variant::RECT2I: {
-
ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA);
Rect2i val;
val.position.x = decode_uint32(&buf[0]);
@@ -223,12 +218,12 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.size.y = decode_uint32(&buf[12]);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 4;
+ }
} break;
case Variant::VECTOR3: {
-
ERR_FAIL_COND_V(len < 4 * 3, ERR_INVALID_DATA);
Vector3 val;
val.x = decode_float(&buf[0]);
@@ -236,12 +231,12 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.z = decode_float(&buf[8]);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 3;
+ }
} break;
case Variant::VECTOR3I: {
-
ERR_FAIL_COND_V(len < 4 * 3, ERR_INVALID_DATA);
Vector3i val;
val.x = decode_uint32(&buf[0]);
@@ -249,29 +244,28 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.z = decode_uint32(&buf[8]);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 3;
+ }
} break;
case Variant::TRANSFORM2D: {
-
ERR_FAIL_COND_V(len < 4 * 6, ERR_INVALID_DATA);
Transform2D val;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
-
val.elements[i][j] = decode_float(&buf[(i * 2 + j) * 4]);
}
}
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 6;
+ }
} break;
case Variant::PLANE: {
-
ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA);
Plane val;
val.normal.x = decode_float(&buf[0]);
@@ -280,12 +274,12 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.d = decode_float(&buf[12]);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 4;
+ }
} break;
case Variant::QUAT: {
-
ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA);
Quat val;
val.x = decode_float(&buf[0]);
@@ -294,12 +288,12 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.w = decode_float(&buf[12]);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 4;
+ }
} break;
case Variant::AABB: {
-
ERR_FAIL_COND_V(len < 4 * 6, ERR_INVALID_DATA);
AABB val;
val.position.x = decode_float(&buf[0]);
@@ -310,34 +304,32 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.size.z = decode_float(&buf[20]);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 6;
+ }
} break;
case Variant::BASIS: {
-
ERR_FAIL_COND_V(len < 4 * 9, ERR_INVALID_DATA);
Basis val;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
-
val.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]);
}
}
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 9;
+ }
} break;
case Variant::TRANSFORM: {
-
ERR_FAIL_COND_V(len < 4 * 12, ERR_INVALID_DATA);
Transform val;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
-
val.basis.elements[i][j] = decode_float(&buf[(i * 3 + j) * 4]);
}
}
@@ -347,14 +339,14 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 12;
+ }
} break;
// misc types
case Variant::COLOR: {
-
ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA);
Color val;
val.r = decode_float(&buf[0]);
@@ -363,22 +355,22 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
val.a = decode_float(&buf[12]);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4 * 4;
+ }
} break;
case Variant::STRING_NAME: {
-
String str;
Error err = _decode_string(buf, len, r_len, str);
- if (err)
+ if (err) {
return err;
+ }
r_variant = StringName(str);
} break;
case Variant::NODE_PATH: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t strlen = decode_uint32(buf);
@@ -395,25 +387,28 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
len -= 12;
buf += 12;
- if (flags & 2) // Obsolete format with property separate from subpath
+ if (flags & 2) { // Obsolete format with property separate from subpath
subnamecount++;
+ }
uint32_t total = namecount + subnamecount;
- if (r_len)
+ if (r_len) {
(*r_len) += 12;
+ }
for (uint32_t i = 0; i < total; i++) {
-
String str;
Error err = _decode_string(buf, len, r_len, str);
- if (err)
+ if (err) {
return err;
+ }
- if (i < namecount)
+ if (i < namecount) {
names.push_back(str);
- else
+ } else {
subnames.push_back(str);
+ }
}
r_variant = NodePath(names, subnames, flags & 1);
@@ -426,17 +421,16 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::_RID: {
-
r_variant = RID();
} break;
case Variant::OBJECT: {
-
if (type & ENCODE_FLAG_OBJECT_AS_ID) {
//this _is_ allowed
ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
ObjectID val = ObjectID(decode_uint64(buf));
- if (r_len)
+ if (r_len) {
(*r_len) += 8;
+ }
if (val.is_null()) {
r_variant = (Object *)nullptr;
@@ -453,13 +447,13 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
String str;
Error err = _decode_string(buf, len, r_len, str);
- if (err)
+ if (err) {
return err;
+ }
if (str == String()) {
r_variant = (Object *)nullptr;
} else {
-
Object *obj = ClassDB::instance(str);
ERR_FAIL_COND_V(!obj, ERR_UNAVAILABLE);
@@ -473,17 +467,18 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
}
for (int i = 0; i < count; i++) {
-
str = String();
err = _decode_string(buf, len, r_len, str);
- if (err)
+ if (err) {
return err;
+ }
Variant value;
int used;
err = decode_variant(value, buf, len, &used, p_allow_objects);
- if (err)
+ if (err) {
return err;
+ }
buf += used;
len -= used;
@@ -505,16 +500,13 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::CALLABLE: {
-
r_variant = Callable();
} break;
case Variant::SIGNAL: {
-
r_variant = Signal();
} break;
case Variant::DICTIONARY: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
// bool shared = count&0x80000000;
@@ -530,7 +522,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
Dictionary d;
for (int i = 0; i < count; i++) {
-
Variant key, value;
int used;
@@ -559,7 +550,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::ARRAY: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
// bool shared = count&0x80000000;
@@ -575,7 +565,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
Array varr;
for (int i = 0; i < count; i++) {
-
int used = 0;
Variant v;
Error err = decode_variant(v, buf, len, &used, p_allow_objects);
@@ -594,7 +583,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
// arrays
case Variant::PACKED_BYTE_ARRAY: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
buf += 4;
@@ -607,7 +595,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
data.resize(count);
uint8_t *w = data.ptrw();
for (int32_t i = 0; i < count; i++) {
-
w[i] = buf[i];
}
}
@@ -615,14 +602,14 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
r_variant = data;
if (r_len) {
- if (count % 4)
+ if (count % 4) {
(*r_len) += 4 - count % 4;
+ }
(*r_len) += 4 + count;
}
} break;
case Variant::PACKED_INT32_ARRAY: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
buf += 4;
@@ -637,7 +624,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
data.resize(count);
int32_t *w = data.ptrw();
for (int32_t i = 0; i < count; i++) {
-
w[i] = decode_uint32(&buf[i * 4]);
}
}
@@ -648,7 +634,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::PACKED_INT64_ARRAY: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int64_t count = decode_uint64(buf);
buf += 4;
@@ -663,7 +648,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
data.resize(count);
int64_t *w = data.ptrw();
for (int64_t i = 0; i < count; i++) {
-
w[i] = decode_uint64(&buf[i * 8]);
}
}
@@ -674,7 +658,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
buf += 4;
@@ -689,7 +672,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
data.resize(count);
float *w = data.ptrw();
for (int32_t i = 0; i < count; i++) {
-
w[i] = decode_float(&buf[i * 4]);
}
}
@@ -701,7 +683,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::PACKED_FLOAT64_ARRAY: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int64_t count = decode_uint64(buf);
buf += 4;
@@ -716,7 +697,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
data.resize(count);
double *w = data.ptrw();
for (int64_t i = 0; i < count; i++) {
-
w[i] = decode_double(&buf[i * 8]);
}
}
@@ -728,7 +708,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::PACKED_STRING_ARRAY: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
@@ -736,16 +715,17 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
buf += 4;
len -= 4;
- if (r_len)
+ if (r_len) {
(*r_len) += 4;
+ }
//printf("string count: %i\n",count);
for (int32_t i = 0; i < count; i++) {
-
String str;
Error err = _decode_string(buf, len, r_len, str);
- if (err)
+ if (err) {
return err;
+ }
strings.push_back(str);
}
@@ -754,7 +734,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
} break;
case Variant::PACKED_VECTOR2_ARRAY: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
buf += 4;
@@ -773,22 +752,21 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
Vector2 *w = varray.ptrw();
for (int32_t i = 0; i < count; i++) {
-
w[i].x = decode_float(buf + i * 4 * 2 + 4 * 0);
w[i].y = decode_float(buf + i * 4 * 2 + 4 * 1);
}
int adv = 4 * 2 * count;
- if (r_len)
+ if (r_len) {
(*r_len) += adv;
+ }
}
r_variant = varray;
} break;
case Variant::PACKED_VECTOR3_ARRAY: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
buf += 4;
@@ -808,7 +786,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
Vector3 *w = varray.ptrw();
for (int32_t i = 0; i < count; i++) {
-
w[i].x = decode_float(buf + i * 4 * 3 + 4 * 0);
w[i].y = decode_float(buf + i * 4 * 3 + 4 * 1);
w[i].z = decode_float(buf + i * 4 * 3 + 4 * 2);
@@ -816,15 +793,15 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
int adv = 4 * 3 * count;
- if (r_len)
+ if (r_len) {
(*r_len) += adv;
+ }
}
r_variant = varray;
} break;
case Variant::PACKED_COLOR_ARRAY: {
-
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t count = decode_uint32(buf);
buf += 4;
@@ -844,7 +821,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
Color *w = carray.ptrw();
for (int32_t i = 0; i < count; i++) {
-
w[i].r = decode_float(buf + i * 4 * 4 + 4 * 0);
w[i].g = decode_float(buf + i * 4 * 4 + 4 * 1);
w[i].b = decode_float(buf + i * 4 * 4 + 4 * 2);
@@ -853,8 +829,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
int adv = 4 * 4 * count;
- if (r_len)
+ if (r_len) {
(*r_len) += adv;
+ }
}
r_variant = carray;
@@ -869,7 +846,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
}
static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) {
-
CharString utf8 = p_string.utf8();
if (buf) {
@@ -889,7 +865,6 @@ static void _encode_string(const String &p_string, uint8_t *&buf, int &r_len) {
}
Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bool p_full_objects) {
-
uint8_t *buf = r_buffer;
r_len = 0;
@@ -897,7 +872,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
uint32_t flags = 0;
switch (p_variant.get_type()) {
-
case Variant::INT: {
int64_t val = p_variant;
if (val > (int64_t)INT_MAX || val < (int64_t)INT_MIN) {
@@ -905,7 +879,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
}
} break;
case Variant::FLOAT: {
-
double d = p_variant;
float f = d;
if (double(f) != d) {
@@ -913,7 +886,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
}
} break;
case Variant::OBJECT: {
-
// Test for potential wrong values sent by the debugger when it breaks.
Object *obj = p_variant.get_validated_object();
if (!obj) {
@@ -940,13 +912,10 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4;
switch (p_variant.get_type()) {
-
case Variant::NIL: {
-
//nothing to do
} break;
case Variant::BOOL: {
-
if (buf) {
encode_uint32(p_variant.operator bool(), buf);
}
@@ -955,7 +924,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::INT: {
-
if (flags & ENCODE_FLAG_64) {
//64 bits
if (buf) {
@@ -972,7 +940,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
}
} break;
case Variant::FLOAT: {
-
if (flags & ENCODE_FLAG_64) {
if (buf) {
encode_double(p_variant.operator double(), buf);
@@ -981,7 +948,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 8;
} else {
-
if (buf) {
encode_float(p_variant.operator float(), buf);
}
@@ -991,14 +957,14 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::NODE_PATH: {
-
NodePath np = p_variant;
if (buf) {
encode_uint32(uint32_t(np.get_name_count()) | 0x80000000, buf); //for compatibility with the old format
encode_uint32(np.get_subname_count(), buf + 4);
uint32_t np_flags = 0;
- if (np.is_absolute())
+ if (np.is_absolute()) {
np_flags |= 1;
+ }
encode_uint32(np_flags, buf + 8);
@@ -1010,20 +976,21 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
int total = np.get_name_count() + np.get_subname_count();
for (int i = 0; i < total; i++) {
-
String str;
- if (i < np.get_name_count())
+ if (i < np.get_name_count()) {
str = np.get_name(i);
- else
+ } else {
str = np.get_subname(i - np.get_name_count());
+ }
CharString utf8 = str.utf8();
int pad = 0;
- if (utf8.length() % 4)
+ if (utf8.length() % 4) {
pad = 4 - utf8.length() % 4;
+ }
if (buf) {
encode_uint32(utf8.length(), buf);
@@ -1037,19 +1004,16 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::STRING: {
-
_encode_string(p_variant, buf, r_len);
} break;
case Variant::STRING_NAME: {
-
_encode_string(p_variant, buf, r_len);
} break;
// math types
case Variant::VECTOR2: {
-
if (buf) {
Vector2 v2 = p_variant;
encode_float(v2.x, &buf[0]);
@@ -1060,7 +1024,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::VECTOR2I: {
-
if (buf) {
Vector2i v2 = p_variant;
encode_uint32(v2.x, &buf[0]);
@@ -1071,7 +1034,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::RECT2: {
-
if (buf) {
Rect2 r2 = p_variant;
encode_float(r2.position.x, &buf[0]);
@@ -1083,7 +1045,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::RECT2I: {
-
if (buf) {
Rect2i r2 = p_variant;
encode_uint32(r2.position.x, &buf[0]);
@@ -1095,7 +1056,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::VECTOR3: {
-
if (buf) {
Vector3 v3 = p_variant;
encode_float(v3.x, &buf[0]);
@@ -1107,7 +1067,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::VECTOR3I: {
-
if (buf) {
Vector3i v3 = p_variant;
encode_uint32(v3.x, &buf[0]);
@@ -1119,12 +1078,10 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::TRANSFORM2D: {
-
if (buf) {
Transform2D val = p_variant;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
-
copymem(&buf[(i * 2 + j) * 4], &val.elements[i][j], sizeof(float));
}
}
@@ -1134,7 +1091,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::PLANE: {
-
if (buf) {
Plane p = p_variant;
encode_float(p.normal.x, &buf[0]);
@@ -1147,7 +1103,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::QUAT: {
-
if (buf) {
Quat q = p_variant;
encode_float(q.x, &buf[0]);
@@ -1160,7 +1115,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::AABB: {
-
if (buf) {
AABB aabb = p_variant;
encode_float(aabb.position.x, &buf[0]);
@@ -1175,12 +1129,10 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::BASIS: {
-
if (buf) {
Basis val = p_variant;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
-
copymem(&buf[(i * 3 + j) * 4], &val.elements[i][j], sizeof(float));
}
}
@@ -1190,12 +1142,10 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::TRANSFORM: {
-
if (buf) {
Transform val = p_variant;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
-
copymem(&buf[(i * 3 + j) * 4], &val.basis.elements[i][j], sizeof(float));
}
}
@@ -1211,7 +1161,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
// misc types
case Variant::COLOR: {
-
if (buf) {
Color c = p_variant;
encode_float(c.r, &buf[0]);
@@ -1224,18 +1173,13 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::_RID: {
-
} break;
case Variant::CALLABLE: {
-
} break;
case Variant::SIGNAL: {
-
} break;
case Variant::OBJECT: {
-
if (p_full_objects) {
-
Object *obj = p_variant;
if (!obj) {
if (buf) {
@@ -1251,9 +1195,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
int pc = 0;
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
pc++;
}
@@ -1265,25 +1209,26 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4;
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
_encode_string(E->get().name, buf, r_len);
int len;
Error err = encode_variant(obj->get(E->get().name), buf, len, p_full_objects);
- if (err)
+ if (err) {
return err;
+ }
ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len;
- if (buf)
+ if (buf) {
buf += len;
+ }
}
}
} else {
if (buf) {
-
Object *obj = p_variant.get_validated_object();
ObjectID id;
if (obj) {
@@ -1298,7 +1243,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::DICTIONARY: {
-
Dictionary d = p_variant;
if (buf) {
@@ -1311,7 +1255,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
d.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
/*
CharString utf8 = E->->utf8();
@@ -1329,20 +1272,21 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_variant(E->get(), buf, len, p_full_objects);
ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len;
- if (buf)
+ if (buf) {
buf += len;
+ }
Variant *v = d.getptr(E->get());
ERR_FAIL_COND_V(!v, ERR_BUG);
encode_variant(*v, buf, len, p_full_objects);
ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len;
- if (buf)
+ if (buf) {
buf += len;
+ }
}
} break;
case Variant::ARRAY: {
-
Array v = p_variant;
if (buf) {
@@ -1353,19 +1297,18 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4;
for (int i = 0; i < v.size(); i++) {
-
int len;
encode_variant(v.get(i), buf, len, p_full_objects);
ERR_FAIL_COND_V(len % 4, ERR_BUG);
r_len += len;
- if (buf)
+ if (buf) {
buf += len;
+ }
}
} break;
// arrays
case Variant::PACKED_BYTE_ARRAY: {
-
Vector<uint8_t> data = p_variant;
int datalen = data.size();
int datasize = sizeof(uint8_t);
@@ -1381,13 +1324,13 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4 + datalen * datasize;
while (r_len % 4) {
r_len++;
- if (buf)
+ if (buf) {
*(buf++) = 0;
+ }
}
} break;
case Variant::PACKED_INT32_ARRAY: {
-
Vector<int32_t> data = p_variant;
int datalen = data.size();
int datasize = sizeof(int32_t);
@@ -1396,15 +1339,15 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_uint32(datalen, buf);
buf += 4;
const int32_t *r = data.ptr();
- for (int32_t i = 0; i < datalen; i++)
+ for (int32_t i = 0; i < datalen; i++) {
encode_uint32(r[i], &buf[i * datasize]);
+ }
}
r_len += 4 + datalen * datasize;
} break;
case Variant::PACKED_INT64_ARRAY: {
-
Vector<int64_t> data = p_variant;
int datalen = data.size();
int datasize = sizeof(int64_t);
@@ -1413,15 +1356,15 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_uint64(datalen, buf);
buf += 4;
const int64_t *r = data.ptr();
- for (int64_t i = 0; i < datalen; i++)
+ for (int64_t i = 0; i < datalen; i++) {
encode_uint64(r[i], &buf[i * datasize]);
+ }
}
r_len += 4 + datalen * datasize;
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
-
Vector<float> data = p_variant;
int datalen = data.size();
int datasize = sizeof(float);
@@ -1430,15 +1373,15 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_uint32(datalen, buf);
buf += 4;
const float *r = data.ptr();
- for (int i = 0; i < datalen; i++)
+ for (int i = 0; i < datalen; i++) {
encode_float(r[i], &buf[i * datasize]);
+ }
}
r_len += 4 + datalen * datasize;
} break;
case Variant::PACKED_FLOAT64_ARRAY: {
-
Vector<double> data = p_variant;
int datalen = data.size();
int datasize = sizeof(double);
@@ -1447,15 +1390,15 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
encode_uint32(datalen, buf);
buf += 4;
const double *r = data.ptr();
- for (int i = 0; i < datalen; i++)
+ for (int i = 0; i < datalen; i++) {
encode_double(r[i], &buf[i * datasize]);
+ }
}
r_len += 4 + datalen * datasize;
} break;
case Variant::PACKED_STRING_ARRAY: {
-
Vector<String> data = p_variant;
int len = data.size();
@@ -1467,7 +1410,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4;
for (int i = 0; i < len; i++) {
-
CharString utf8 = data.get(i).utf8();
if (buf) {
@@ -1480,14 +1422,14 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4 + utf8.length() + 1;
while (r_len % 4) {
r_len++; //pad
- if (buf)
+ if (buf) {
*(buf++) = 0;
+ }
}
}
} break;
case Variant::PACKED_VECTOR2_ARRAY: {
-
Vector<Vector2> data = p_variant;
int len = data.size();
@@ -1499,9 +1441,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4;
if (buf) {
-
for (int i = 0; i < len; i++) {
-
Vector2 v = data.get(i);
encode_float(v.x, &buf[0]);
@@ -1514,7 +1454,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::PACKED_VECTOR3_ARRAY: {
-
Vector<Vector3> data = p_variant;
int len = data.size();
@@ -1526,9 +1465,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4;
if (buf) {
-
for (int i = 0; i < len; i++) {
-
Vector3 v = data.get(i);
encode_float(v.x, &buf[0]);
@@ -1542,7 +1479,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
} break;
case Variant::PACKED_COLOR_ARRAY: {
-
Vector<Color> data = p_variant;
int len = data.size();
@@ -1554,9 +1490,7 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo
r_len += 4;
if (buf) {
-
for (int i = 0; i < len; i++) {
-
Color c = data.get(i);
encode_float(c.r, &buf[0]);
diff --git a/core/io/marshalls.h b/core/io/marshalls.h
index d029ed238c..c8ed497528 100644
--- a/core/io/marshalls.h
+++ b/core/io/marshalls.h
@@ -41,21 +41,17 @@
*/
union MarshallFloat {
-
uint32_t i; ///< int
float f; ///< float
};
union MarshallDouble {
-
uint64_t l; ///< long long
double d; ///< double
};
static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
-
for (int i = 0; i < 2; i++) {
-
*p_arr = p_uint & 0xFF;
p_arr++;
p_uint >>= 8;
@@ -65,9 +61,7 @@ static inline unsigned int encode_uint16(uint16_t p_uint, uint8_t *p_arr) {
}
static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
-
for (int i = 0; i < 4; i++) {
-
*p_arr = p_uint & 0xFF;
p_arr++;
p_uint >>= 8;
@@ -77,7 +71,6 @@ static inline unsigned int encode_uint32(uint32_t p_uint, uint8_t *p_arr) {
}
static inline unsigned int encode_float(float p_float, uint8_t *p_arr) {
-
MarshallFloat mf;
mf.f = p_float;
encode_uint32(mf.i, p_arr);
@@ -86,9 +79,7 @@ static inline unsigned int encode_float(float p_float, uint8_t *p_arr) {
}
static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
-
for (int i = 0; i < 8; i++) {
-
*p_arr = p_uint & 0xFF;
p_arr++;
p_uint >>= 8;
@@ -98,7 +89,6 @@ static inline unsigned int encode_uint64(uint64_t p_uint, uint8_t *p_arr) {
}
static inline unsigned int encode_double(double p_double, uint8_t *p_arr) {
-
MarshallDouble md;
md.d = p_double;
encode_uint64(md.l, p_arr);
@@ -107,30 +97,27 @@ static inline unsigned int encode_double(double p_double, uint8_t *p_arr) {
}
static inline int encode_cstring(const char *p_string, uint8_t *p_data) {
-
int len = 0;
while (*p_string) {
-
if (p_data) {
-
*p_data = (uint8_t)*p_string;
p_data++;
}
p_string++;
len++;
- };
+ }
- if (p_data) *p_data = 0;
+ if (p_data) {
+ *p_data = 0;
+ }
return len + 1;
}
static inline uint16_t decode_uint16(const uint8_t *p_arr) {
-
uint16_t u = 0;
for (int i = 0; i < 2; i++) {
-
uint16_t b = *p_arr;
b <<= (i * 8);
u |= b;
@@ -141,11 +128,9 @@ static inline uint16_t decode_uint16(const uint8_t *p_arr) {
}
static inline uint32_t decode_uint32(const uint8_t *p_arr) {
-
uint32_t u = 0;
for (int i = 0; i < 4; i++) {
-
uint32_t b = *p_arr;
b <<= (i * 8);
u |= b;
@@ -156,18 +141,15 @@ static inline uint32_t decode_uint32(const uint8_t *p_arr) {
}
static inline float decode_float(const uint8_t *p_arr) {
-
MarshallFloat mf;
mf.i = decode_uint32(p_arr);
return mf.f;
}
static inline uint64_t decode_uint64(const uint8_t *p_arr) {
-
uint64_t u = 0;
for (int i = 0; i < 8; i++) {
-
uint64_t b = (*p_arr) & 0xFF;
b <<= (i * 8);
u |= b;
@@ -178,7 +160,6 @@ static inline uint64_t decode_uint64(const uint8_t *p_arr) {
}
static inline double decode_double(const uint8_t *p_arr) {
-
MarshallDouble md;
md.l = decode_uint64(p_arr);
return md.d;
@@ -196,7 +177,7 @@ public:
void set_object_id(ObjectID p_id);
ObjectID get_object_id() const;
- EncodedObjectAsID();
+ EncodedObjectAsID() {}
};
Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len = nullptr, bool p_allow_objects = false);
diff --git a/core/io/multiplayer_api.cpp b/core/io/multiplayer_api.cpp
index 3bec52416e..2f17d9e746 100644
--- a/core/io/multiplayer_api.cpp
+++ b/core/io/multiplayer_api.cpp
@@ -33,6 +33,7 @@
#include "core/debugger/engine_debugger.h"
#include "core/io/marshalls.h"
#include "scene/main/node.h"
+
#include <stdint.h>
#define NODE_ID_COMPRESSION_SHIFT 3
@@ -44,9 +45,7 @@
#endif
_FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_master, bool &r_skip_rpc) {
-
switch (mode) {
-
case MultiplayerAPI::RPC_MODE_DISABLED: {
// Do nothing.
} break;
@@ -54,8 +53,9 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
// Do nothing also. Remote cannot produce a local call.
} break;
case MultiplayerAPI::RPC_MODE_MASTERSYNC: {
- if (is_master)
+ if (is_master) {
r_skip_rpc = true; // I am the master, so skip remote call.
+ }
[[fallthrough]];
}
case MultiplayerAPI::RPC_MODE_REMOTESYNC:
@@ -64,8 +64,9 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
return true;
} break;
case MultiplayerAPI::RPC_MODE_MASTER: {
- if (is_master)
+ if (is_master) {
r_skip_rpc = true; // I am the master, so skip remote call.
+ }
return is_master;
} break;
case MultiplayerAPI::RPC_MODE_PUPPET: {
@@ -77,7 +78,6 @@ _FORCE_INLINE_ bool _should_call_local(MultiplayerAPI::RPCMode mode, bool is_mas
_FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, int p_remote_id) {
switch (mode) {
-
case MultiplayerAPI::RPC_MODE_DISABLED: {
return false;
} break;
@@ -99,17 +99,17 @@ _FORCE_INLINE_ bool _can_call_mode(Node *p_node, MultiplayerAPI::RPCMode mode, i
}
void MultiplayerAPI::poll() {
-
- if (!network_peer.is_valid() || network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED)
+ if (!network_peer.is_valid() || network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED) {
return;
+ }
network_peer->poll();
- if (!network_peer.is_valid()) // It's possible that polling might have resulted in a disconnection, so check here.
+ if (!network_peer.is_valid()) { // It's possible that polling might have resulted in a disconnection, so check here.
return;
+ }
while (network_peer->get_available_packet_count()) {
-
int sender = network_peer->get_packet_peer();
const uint8_t *packet;
int len;
@@ -143,8 +143,9 @@ void MultiplayerAPI::set_root_node(Node *p_node) {
}
void MultiplayerAPI::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_peer) {
-
- if (p_peer == network_peer) return; // Nothing to do
+ if (p_peer == network_peer) {
+ return; // Nothing to do
+ }
ERR_FAIL_COND_MSG(p_peer.is_valid() && p_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_DISCONNECTED,
"Supplied NetworkedMultiplayerPeer must be connecting or connected.");
@@ -183,6 +184,7 @@ void _profile_node_data(const String &p_what, ObjectID p_id) {
EngineDebugger::profiler_add_frame_data("multiplayer", values);
}
}
+
void _profile_bandwidth_data(const String &p_inout, int p_size) {
if (EngineDebugger::is_profiling("multiplayer")) {
Array values;
@@ -206,7 +208,6 @@ int get_packet_len(uint32_t p_node_target, int p_packet_len) {
}
void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_packet_len) {
-
ERR_FAIL_COND_MSG(root_node == nullptr, "Multiplayer root node was not initialized. If you are using custom multiplayer, remember to set the root node via MultiplayerAPI.set_root_node before using it.");
ERR_FAIL_COND_MSG(p_packet_len < 1, "Invalid packet received. Size too small.");
@@ -218,20 +219,16 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
uint8_t packet_type = p_packet[0] & 7;
switch (packet_type) {
-
case NETWORK_COMMAND_SIMPLIFY_PATH: {
-
_process_simplify_path(p_from, p_packet, p_packet_len);
} break;
case NETWORK_COMMAND_CONFIRM_PATH: {
-
_process_confirm_path(p_from, p_packet, p_packet_len);
} break;
case NETWORK_COMMAND_REMOTE_CALL:
case NETWORK_COMMAND_REMOTE_SET: {
-
// Extract packet meta
int packet_min_size = 1;
int name_id_offset = 1;
@@ -302,25 +299,21 @@ void MultiplayerAPI::_process_packet(int p_from, const uint8_t *p_packet, int p_
const int packet_len = get_packet_len(node_target, p_packet_len);
if (packet_type == NETWORK_COMMAND_REMOTE_CALL) {
-
_process_rpc(node, name_id, p_from, p_packet, packet_len, packet_min_size);
} else {
-
_process_rset(node, name_id, p_from, p_packet, packet_len, packet_min_size);
}
} break;
case NETWORK_COMMAND_RAW: {
-
_process_raw(p_from, p_packet, p_packet_len);
} break;
}
}
Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, uint32_t p_node_target, int p_packet_len) {
-
Node *node = nullptr;
if (p_node_target & 0x80000000) {
@@ -337,8 +330,9 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, uin
node = root_node->get_node(np);
- if (!node)
+ if (!node) {
ERR_PRINT("Failed to get path from RPC: " + String(np) + ".");
+ }
} else {
// Use cached path.
int id = p_node_target;
@@ -353,14 +347,14 @@ Node *MultiplayerAPI::_process_get_node(int p_from, const uint8_t *p_packet, uin
// Do proper caching later.
node = root_node->get_node(ni->path);
- if (!node)
+ if (!node) {
ERR_PRINT("Failed to get cached path from RPC: " + String(ni->path) + ".");
+ }
}
return node;
}
void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
-
ERR_FAIL_COND_MSG(p_offset > p_packet_len, "Invalid packet received. Size too small.");
// Check that remote can call the RPC on this node.
@@ -413,7 +407,6 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id,
p_offset += len;
} else {
for (int i = 0; i < argc; i++) {
-
ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
int vlen;
@@ -436,7 +429,6 @@ void MultiplayerAPI::_process_rpc(Node *p_node, const uint16_t p_rpc_method_id,
}
void MultiplayerAPI::_process_rset(Node *p_node, const uint16_t p_rpc_property_id, int p_from, const uint8_t *p_packet, int p_packet_len, int p_offset) {
-
ERR_FAIL_COND_MSG(p_offset >= p_packet_len, "Invalid packet received. Size too small.");
// Check that remote can call the RSET on this node.
@@ -470,7 +462,6 @@ void MultiplayerAPI::_process_rset(Node *p_node, const uint16_t p_rpc_property_i
}
void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
-
ERR_FAIL_COND_MSG(p_packet_len < 38, "Invalid packet received. Size too small.");
int ofs = 1;
@@ -519,7 +510,6 @@ void MultiplayerAPI::_process_simplify_path(int p_from, const uint8_t *p_packet,
}
void MultiplayerAPI::_process_confirm_path(int p_from, const uint8_t *p_packet, int p_packet_len) {
-
ERR_FAIL_COND_MSG(p_packet_len < 3, "Invalid packet received. Size too small.");
const bool valid_rpc_checksum = p_packet[1];
@@ -546,12 +536,13 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC
List<int> peers_to_add; // If one is missing, take note to add it.
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
-
- if (p_target < 0 && E->get() == -p_target)
+ if (p_target < 0 && E->get() == -p_target) {
continue; // Continue, excluded.
+ }
- if (p_target > 0 && E->get() != p_target)
+ if (p_target > 0 && E->get() != p_target) {
continue; // Continue, not for this peer.
+ }
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
@@ -567,7 +558,6 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC
}
if (peers_to_add.size() > 0) {
-
// Those that need to be added, send a message for this.
// Encode function name.
@@ -592,7 +582,6 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC
ofs += encode_cstring(path.get_data(), &packet.write[ofs]);
for (List<int>::Element *E = peers_to_add.front(); E; E = E->next()) {
-
network_peer->set_target_peer(E->get()); // To all of you.
network_peer->set_transfer_mode(NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
network_peer->put_packet(packet.ptr(), packet.size());
@@ -617,7 +606,6 @@ bool MultiplayerAPI::_send_confirm_path(Node *p_node, NodePath p_path, PathSentC
#define ENCODE_32 2 << 5
#define ENCODE_64 3 << 5
Error MultiplayerAPI::_encode_and_compress_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
-
// Unreachable because `VARIANT_MAX` == 27 and `ENCODE_VARIANT_MASK` == 31
CRASH_COND(p_variant.get_type() > VARIANT_META_TYPE_MASK);
@@ -679,8 +667,9 @@ Error MultiplayerAPI::_encode_and_compress_variant(const Variant &p_variant, uin
default:
// Any other case is not yet compressed.
Error err = encode_variant(p_variant, r_buffer, r_len, allow_object_decoding);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
if (r_buffer) {
// The first byte is not used by the marshaling, so store the type
// so we know how to decompress and decode this variant.
@@ -690,8 +679,8 @@ Error MultiplayerAPI::_encode_and_compress_variant(const Variant &p_variant, uin
return OK;
}
-Error MultiplayerAPI::_decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len) {
+Error MultiplayerAPI::_decode_and_decompress_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int *r_len) {
const uint8_t *buf = p_buffer;
int len = p_len;
@@ -705,55 +694,61 @@ Error MultiplayerAPI::_decode_and_decompress_variant(Variant &r_variant, const u
case Variant::BOOL: {
bool val = (buf[0] & VARIANT_META_BOOL_MASK) > 0;
r_variant = val;
- if (r_len)
+ if (r_len) {
*r_len = 1;
+ }
} break;
case Variant::INT: {
buf += 1;
len -= 1;
- if (r_len)
+ if (r_len) {
*r_len = 1;
+ }
if (encode_mode == ENCODE_8) {
// 8 bits.
ERR_FAIL_COND_V(len < 1, ERR_INVALID_DATA);
int8_t val = buf[0];
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 1;
+ }
} else if (encode_mode == ENCODE_16) {
// 16 bits.
ERR_FAIL_COND_V(len < 2, ERR_INVALID_DATA);
int16_t val = decode_uint16(buf);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 2;
+ }
} else if (encode_mode == ENCODE_32) {
// 32 bits.
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
int32_t val = decode_uint32(buf);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 4;
+ }
} else {
// 64 bits.
ERR_FAIL_COND_V(len < 8, ERR_INVALID_DATA);
int64_t val = decode_uint64(buf);
r_variant = val;
- if (r_len)
+ if (r_len) {
(*r_len) += 8;
+ }
}
} break;
default:
Error err = decode_variant(r_variant, p_buffer, p_len, r_len, allow_object_decoding);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
}
return OK;
}
void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount) {
-
ERR_FAIL_COND_MSG(network_peer.is_null(), "Attempt to remote call/set when networking is not active in SceneTree.");
ERR_FAIL_COND_MSG(network_peer->get_connection_status() == NetworkedMultiplayerPeer::CONNECTION_CONNECTING, "Attempt to remote call/set when networking is not connected yet in SceneTree.");
@@ -787,8 +782,9 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
int ofs = 0;
-#define MAKE_ROOM(m_amount) \
- if (packet_cache.size() < m_amount) packet_cache.resize(m_amount);
+#define MAKE_ROOM(m_amount) \
+ if (packet_cache.size() < m_amount) \
+ packet_cache.resize(m_amount);
// Encode meta.
// The meta is composed by a single byte that contains (starting from the least segnificant bit):
@@ -838,7 +834,6 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
}
if (p_set) {
-
// Take the rpc property ID
uint16_t property_id = p_from->get_node_rset_property_id(p_name);
if (property_id == UINT16_MAX && p_from->get_script_instance()) {
@@ -931,7 +926,6 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
network_peer->set_transfer_mode(p_unreliable ? NetworkedMultiplayerPeer::TRANSFER_MODE_UNRELIABLE : NetworkedMultiplayerPeer::TRANSFER_MODE_RELIABLE);
if (has_all_peers) {
-
// They all have verified paths, so send fast.
network_peer->set_target_peer(p_to); // To all of you.
network_peer->put_packet(packet_cache.ptr(), ofs); // A message with love.
@@ -948,12 +942,13 @@ void MultiplayerAPI::_send_rpc(Node *p_from, int p_to, bool p_unreliable, bool p
encode_cstring(pname.get_data(), &(packet_cache.write[ofs]));
for (Set<int>::Element *E = connected_peers.front(); E; E = E->next()) {
-
- if (p_to < 0 && E->get() == -p_to)
+ if (p_to < 0 && E->get() == -p_to) {
continue; // Continue, excluded.
+ }
- if (p_to > 0 && E->get() != p_to)
+ if (p_to > 0 && E->get() != p_to) {
continue; // Continue, not for this peer.
+ }
Map<int, bool>::Element *F = psc->confirmed_peers.find(E->get());
ERR_CONTINUE(!F); // Should never happen.
@@ -995,22 +990,18 @@ void MultiplayerAPI::_del_peer(int p_id) {
}
void MultiplayerAPI::_connected_to_server() {
-
emit_signal("connected_to_server");
}
void MultiplayerAPI::_connection_failed() {
-
emit_signal("connection_failed");
}
void MultiplayerAPI::_server_disconnected() {
-
emit_signal("server_disconnected");
}
void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_method, const Variant **p_arg, int p_argcount) {
-
ERR_FAIL_COND_MSG(!network_peer.is_valid(), "Trying to call an RPC while no network peer is active.");
ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "Trying to call an RPC on a node which is not inside SceneTree.");
ERR_FAIL_COND_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, "Trying to call an RPC via a network peer which is not connected.");
@@ -1037,7 +1028,6 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
}
if (!skip_rpc) {
-
#ifdef DEBUG_ENABLED
_profile_node_data("out_rpc", p_node->get_instance_id());
#endif
@@ -1078,7 +1068,6 @@ void MultiplayerAPI::rpcp(Node *p_node, int p_peer_id, bool p_unreliable, const
}
void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const StringName &p_property, const Variant &p_value) {
-
ERR_FAIL_COND_MSG(!network_peer.is_valid(), "Trying to RSET while no network peer is active.");
ERR_FAIL_COND_MSG(!p_node->is_inside_tree(), "Trying to RSET on a node which is not inside SceneTree.");
ERR_FAIL_COND_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, "Trying to send an RSET via a network peer which is not connected.");
@@ -1143,7 +1132,6 @@ void MultiplayerAPI::rsetp(Node *p_node, int p_peer_id, bool p_unreliable, const
}
Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, NetworkedMultiplayerPeer::TransferMode p_mode) {
-
ERR_FAIL_COND_V_MSG(p_data.size() < 1, ERR_INVALID_DATA, "Trying to send an empty raw packet.");
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), ERR_UNCONFIGURED, "Trying to send a raw packet while no network peer is active.");
ERR_FAIL_COND_V_MSG(network_peer->get_connection_status() != NetworkedMultiplayerPeer::CONNECTION_CONNECTED, ERR_UNCONFIGURED, "Trying to send a raw packet via a network peer which is not connected.");
@@ -1160,7 +1148,6 @@ Error MultiplayerAPI::send_bytes(Vector<uint8_t> p_data, int p_to, NetworkedMult
}
void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_packet_len) {
-
ERR_FAIL_COND_MSG(p_packet_len < 2, "Invalid packet received. Size too small.");
Vector<uint8_t> out;
@@ -1174,32 +1161,27 @@ void MultiplayerAPI::_process_raw(int p_from, const uint8_t *p_packet, int p_pac
}
int MultiplayerAPI::get_network_unique_id() const {
-
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), 0, "No network peer is assigned. Unable to get unique network ID.");
return network_peer->get_unique_id();
}
bool MultiplayerAPI::is_network_server() const {
-
// XXX Maybe fail silently? Maybe should actually return true to make development of both local and online multiplayer easier?
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), false, "No network peer is assigned. I can't be a server.");
return network_peer->is_server();
}
void MultiplayerAPI::set_refuse_new_network_connections(bool p_refuse) {
-
ERR_FAIL_COND_MSG(!network_peer.is_valid(), "No network peer is assigned. Unable to set 'refuse_new_connections'.");
network_peer->set_refuse_new_connections(p_refuse);
}
bool MultiplayerAPI::is_refusing_new_network_connections() const {
-
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), false, "No network peer is assigned. Unable to get 'refuse_new_connections'.");
return network_peer->is_refusing_new_connections();
}
Vector<int> MultiplayerAPI::get_network_connected_peers() const {
-
ERR_FAIL_COND_V_MSG(!network_peer.is_valid(), Vector<int>(), "No network peer is assigned. Assume no peers are connected.");
Vector<int> ret;
@@ -1211,12 +1193,10 @@ Vector<int> MultiplayerAPI::get_network_connected_peers() const {
}
void MultiplayerAPI::set_allow_object_decoding(bool p_enable) {
-
allow_object_decoding = p_enable;
}
bool MultiplayerAPI::is_object_decoding_allowed() const {
-
return allow_object_decoding;
}
@@ -1259,10 +1239,7 @@ void MultiplayerAPI::_bind_methods() {
BIND_ENUM_CONSTANT(RPC_MODE_PUPPETSYNC);
}
-MultiplayerAPI::MultiplayerAPI() :
- allow_object_decoding(false) {
- rpc_sender_id = 0;
- root_node = nullptr;
+MultiplayerAPI::MultiplayerAPI() {
clear();
}
diff --git a/core/io/multiplayer_api.h b/core/io/multiplayer_api.h
index 4eb4a53e99..06eab7796c 100644
--- a/core/io/multiplayer_api.h
+++ b/core/io/multiplayer_api.h
@@ -35,7 +35,6 @@
#include "core/reference.h"
class MultiplayerAPI : public Reference {
-
GDCLASS(MultiplayerAPI, Reference);
private:
@@ -56,14 +55,14 @@ private:
};
Ref<NetworkedMultiplayerPeer> network_peer;
- int rpc_sender_id;
+ int rpc_sender_id = 0;
Set<int> connected_peers;
HashMap<NodePath, PathSentCache> path_send_cache;
Map<int, PathGetCache> path_get_cache;
int last_send_cache_id;
Vector<uint8_t> packet_cache;
- Node *root_node;
- bool allow_object_decoding;
+ Node *root_node = nullptr;
+ bool allow_object_decoding = false;
protected:
static void _bind_methods();
diff --git a/core/io/net_socket.cpp b/core/io/net_socket.cpp
index 838c674cec..130a2e245e 100644
--- a/core/io/net_socket.cpp
+++ b/core/io/net_socket.cpp
@@ -33,9 +33,9 @@
NetSocket *(*NetSocket::_create)() = nullptr;
NetSocket *NetSocket::create() {
-
- if (_create)
+ if (_create) {
return _create();
+ }
ERR_PRINT("Unable to create network socket, platform not supported");
return nullptr;
diff --git a/core/io/net_socket.h b/core/io/net_socket.h
index 376fd87a27..746945eced 100644
--- a/core/io/net_socket.h
+++ b/core/io/net_socket.h
@@ -35,7 +35,6 @@
#include "core/reference.h"
class NetSocket : public Reference {
-
protected:
static NetSocket *(*_create)();
diff --git a/core/io/networked_multiplayer_peer.cpp b/core/io/networked_multiplayer_peer.cpp
index b2f810d212..f521f2bb79 100644
--- a/core/io/networked_multiplayer_peer.cpp
+++ b/core/io/networked_multiplayer_peer.cpp
@@ -31,7 +31,6 @@
#include "networked_multiplayer_peer.h"
void NetworkedMultiplayerPeer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_transfer_mode", "mode"), &NetworkedMultiplayerPeer::set_transfer_mode);
ClassDB::bind_method(D_METHOD("get_transfer_mode"), &NetworkedMultiplayerPeer::get_transfer_mode);
ClassDB::bind_method(D_METHOD("set_target_peer", "id"), &NetworkedMultiplayerPeer::set_target_peer);
@@ -66,6 +65,3 @@ void NetworkedMultiplayerPeer::_bind_methods() {
ADD_SIGNAL(MethodInfo("connection_succeeded"));
ADD_SIGNAL(MethodInfo("connection_failed"));
}
-
-NetworkedMultiplayerPeer::NetworkedMultiplayerPeer() {
-}
diff --git a/core/io/networked_multiplayer_peer.h b/core/io/networked_multiplayer_peer.h
index c1f1924051..dc76237f45 100644
--- a/core/io/networked_multiplayer_peer.h
+++ b/core/io/networked_multiplayer_peer.h
@@ -34,7 +34,6 @@
#include "core/io/packet_peer.h"
class NetworkedMultiplayerPeer : public PacketPeer {
-
GDCLASS(NetworkedMultiplayerPeer, PacketPeer);
protected:
@@ -74,7 +73,7 @@ public:
virtual ConnectionStatus get_connection_status() const = 0;
- NetworkedMultiplayerPeer();
+ NetworkedMultiplayerPeer() {}
};
VARIANT_ENUM_CAST(NetworkedMultiplayerPeer::TransferMode)
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index 38abb5c0d6..dacd548a3e 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -35,13 +35,7 @@
/* helpers / binders */
-PacketPeer::PacketPeer() :
- last_get_error(OK),
- encode_buffer_max_size(8 * 1024 * 1024) {
-}
-
void PacketPeer::set_encode_buffer_max_size(int p_max_size) {
-
ERR_FAIL_COND_MSG(p_max_size < 1024, "Max encode buffer must be at least 1024 bytes");
ERR_FAIL_COND_MSG(p_max_size > 256 * 1024 * 1024, "Max encode buffer cannot exceed 256 MiB");
encode_buffer_max_size = next_power_of_2(p_max_size);
@@ -49,59 +43,61 @@ void PacketPeer::set_encode_buffer_max_size(int p_max_size) {
}
int PacketPeer::get_encode_buffer_max_size() const {
-
return encode_buffer_max_size;
}
Error PacketPeer::get_packet_buffer(Vector<uint8_t> &r_buffer) {
-
const uint8_t *buffer;
int buffer_size;
Error err = get_packet(&buffer, buffer_size);
- if (err)
+ if (err) {
return err;
+ }
r_buffer.resize(buffer_size);
- if (buffer_size == 0)
+ if (buffer_size == 0) {
return OK;
+ }
uint8_t *w = r_buffer.ptrw();
- for (int i = 0; i < buffer_size; i++)
+ for (int i = 0; i < buffer_size; i++) {
w[i] = buffer[i];
+ }
return OK;
}
Error PacketPeer::put_packet_buffer(const Vector<uint8_t> &p_buffer) {
-
int len = p_buffer.size();
- if (len == 0)
+ if (len == 0) {
return OK;
+ }
const uint8_t *r = p_buffer.ptr();
return put_packet(&r[0], len);
}
Error PacketPeer::get_var(Variant &r_variant, bool p_allow_objects) {
-
const uint8_t *buffer;
int buffer_size;
Error err = get_packet(&buffer, buffer_size);
- if (err)
+ if (err) {
return err;
+ }
return decode_variant(r_variant, buffer, buffer_size, nullptr, p_allow_objects);
}
Error PacketPeer::put_var(const Variant &p_packet, bool p_full_objects) {
-
int len;
Error err = encode_variant(p_packet, nullptr, len, p_full_objects); // compute len first
- if (err)
+ if (err) {
return err;
+ }
- if (len == 0)
+ if (len == 0) {
return OK;
+ }
ERR_FAIL_COND_V_MSG(len > encode_buffer_max_size, ERR_OUT_OF_MEMORY, "Failed to encode variant, encode size is bigger then encode_buffer_max_size. Consider raising it via 'set_encode_buffer_max_size'.");
@@ -128,20 +124,18 @@ Variant PacketPeer::_bnd_get_var(bool p_allow_objects) {
Error PacketPeer::_put_packet(const Vector<uint8_t> &p_buffer) {
return put_packet_buffer(p_buffer);
}
-Vector<uint8_t> PacketPeer::_get_packet() {
+Vector<uint8_t> PacketPeer::_get_packet() {
Vector<uint8_t> raw;
last_get_error = get_packet_buffer(raw);
return raw;
}
Error PacketPeer::_get_packet_error() const {
-
return last_get_error;
}
void PacketPeer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_var", "allow_objects"), &PacketPeer::_bnd_get_var, DEFVAL(false));
ClassDB::bind_method(D_METHOD("put_var", "var", "full_objects"), &PacketPeer::put_var, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_packet"), &PacketPeer::_get_packet);
@@ -153,18 +147,16 @@ void PacketPeer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_encode_buffer_max_size", "max_size"), &PacketPeer::set_encode_buffer_max_size);
ADD_PROPERTY(PropertyInfo(Variant::INT, "encode_buffer_max_size"), "set_encode_buffer_max_size", "get_encode_buffer_max_size");
-};
+}
/***************/
void PacketPeerStream::_set_stream_peer(REF p_peer) {
-
ERR_FAIL_COND_MSG(p_peer.is_null(), "It's not a reference to a valid Resource object.");
set_stream_peer(p_peer);
}
void PacketPeerStream::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_stream_peer", "peer"), &PacketPeerStream::set_stream_peer);
ClassDB::bind_method(D_METHOD("get_stream_peer"), &PacketPeerStream::get_stream_peer);
ClassDB::bind_method(D_METHOD("set_input_buffer_max_size", "max_size_bytes"), &PacketPeerStream::set_input_buffer_max_size);
@@ -178,16 +170,17 @@ void PacketPeerStream::_bind_methods() {
}
Error PacketPeerStream::_poll_buffer() const {
-
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
int read = 0;
ERR_FAIL_COND_V(input_buffer.size() < ring_buffer.space_left(), ERR_UNAVAILABLE);
Error err = peer->get_partial_data(input_buffer.ptrw(), ring_buffer.space_left(), read);
- if (err)
+ if (err) {
return err;
- if (read == 0)
+ }
+ if (read == 0) {
return OK;
+ }
int w = ring_buffer.write(&input_buffer[0], read);
ERR_FAIL_COND_V(w != read, ERR_BUG);
@@ -196,7 +189,6 @@ Error PacketPeerStream::_poll_buffer() const {
}
int PacketPeerStream::get_available_packet_count() const {
-
_poll_buffer();
uint32_t remaining = ring_buffer.data_left();
@@ -205,14 +197,14 @@ int PacketPeerStream::get_available_packet_count() const {
int count = 0;
while (remaining >= 4) {
-
uint8_t lbuf[4];
ring_buffer.copy(lbuf, ofs, 4);
uint32_t len = decode_uint32(lbuf);
remaining -= 4;
ofs += 4;
- if (len > remaining)
+ if (len > remaining) {
break;
+ }
remaining -= len;
ofs += len;
count++;
@@ -222,7 +214,6 @@ int PacketPeerStream::get_available_packet_count() const {
}
Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
-
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
_poll_buffer();
@@ -244,50 +235,48 @@ Error PacketPeerStream::get_packet(const uint8_t **r_buffer, int &r_buffer_size)
}
Error PacketPeerStream::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
-
ERR_FAIL_COND_V(peer.is_null(), ERR_UNCONFIGURED);
Error err = _poll_buffer(); //won't hurt to poll here too
- if (err)
+ if (err) {
return err;
+ }
- if (p_buffer_size == 0)
+ if (p_buffer_size == 0) {
return OK;
+ }
ERR_FAIL_COND_V(p_buffer_size < 0, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_buffer_size + 4 > output_buffer.size(), ERR_INVALID_PARAMETER);
encode_uint32(p_buffer_size, output_buffer.ptrw());
uint8_t *dst = &output_buffer.write[4];
- for (int i = 0; i < p_buffer_size; i++)
+ for (int i = 0; i < p_buffer_size; i++) {
dst[i] = p_buffer[i];
+ }
return peer->put_data(&output_buffer[0], p_buffer_size + 4);
}
int PacketPeerStream::get_max_packet_size() const {
-
return output_buffer.size();
}
void PacketPeerStream::set_stream_peer(const Ref<StreamPeer> &p_peer) {
-
//ERR_FAIL_COND(p_peer.is_null());
if (p_peer.ptr() != peer.ptr()) {
ring_buffer.advance_read(ring_buffer.data_left()); // reset the ring buffer
- };
+ }
peer = p_peer;
}
Ref<StreamPeer> PacketPeerStream::get_stream_peer() const {
-
return peer;
}
void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
-
ERR_FAIL_COND_MSG(p_max_size < 0, "Max size of input buffer size cannot be smaller than 0.");
//warning may lose packets
ERR_FAIL_COND_MSG(ring_buffer.data_left(), "Buffer in use, resizing would cause loss of data.");
@@ -296,22 +285,18 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
}
int PacketPeerStream::get_input_buffer_max_size() const {
-
return input_buffer.size() - 4;
}
void PacketPeerStream::set_output_buffer_max_size(int p_max_size) {
-
output_buffer.resize(next_power_of_2(p_max_size + 4));
}
int PacketPeerStream::get_output_buffer_max_size() const {
-
return output_buffer.size() - 4;
}
PacketPeerStream::PacketPeerStream() {
-
int rbsize = GLOBAL_GET("network/limits/packet_peer_stream/max_buffer_po2");
ring_buffer.resize(rbsize);
diff --git a/core/io/packet_peer.h b/core/io/packet_peer.h
index 62144259cc..f0ba50087f 100644
--- a/core/io/packet_peer.h
+++ b/core/io/packet_peer.h
@@ -36,7 +36,6 @@
#include "core/ring_buffer.h"
class PacketPeer : public Reference {
-
GDCLASS(PacketPeer, Reference);
Variant _bnd_get_var(bool p_allow_objects = false);
@@ -47,9 +46,9 @@ class PacketPeer : public Reference {
Vector<uint8_t> _get_packet();
Error _get_packet_error() const;
- mutable Error last_get_error;
+ mutable Error last_get_error = OK;
- int encode_buffer_max_size;
+ int encode_buffer_max_size = 8 * 1024 * 1024;
Vector<uint8_t> encode_buffer;
public:
@@ -70,12 +69,11 @@ public:
void set_encode_buffer_max_size(int p_max_size);
int get_encode_buffer_max_size() const;
- PacketPeer();
+ PacketPeer() {}
~PacketPeer() {}
};
class PacketPeerStream : public PacketPeer {
-
GDCLASS(PacketPeerStream, PacketPeer);
//the way the buffers work sucks, will change later
diff --git a/core/io/packet_peer_dtls.cpp b/core/io/packet_peer_dtls.cpp
index 6da115eed2..67579c339a 100644
--- a/core/io/packet_peer_dtls.cpp
+++ b/core/io/packet_peer_dtls.cpp
@@ -36,7 +36,6 @@ PacketPeerDTLS *(*PacketPeerDTLS::_create)() = nullptr;
bool PacketPeerDTLS::available = false;
PacketPeerDTLS *PacketPeerDTLS::create() {
-
return _create();
}
@@ -45,7 +44,6 @@ bool PacketPeerDTLS::is_available() {
}
void PacketPeerDTLS::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("poll"), &PacketPeerDTLS::poll);
ClassDB::bind_method(D_METHOD("connect_to_peer", "packet_peer", "validate_certs", "for_hostname", "valid_certificate"), &PacketPeerDTLS::connect_to_peer, DEFVAL(true), DEFVAL(String()), DEFVAL(Ref<X509Certificate>()));
ClassDB::bind_method(D_METHOD("get_status"), &PacketPeerDTLS::get_status);
@@ -57,6 +55,3 @@ void PacketPeerDTLS::_bind_methods() {
BIND_ENUM_CONSTANT(STATUS_ERROR);
BIND_ENUM_CONSTANT(STATUS_ERROR_HOSTNAME_MISMATCH);
}
-
-PacketPeerDTLS::PacketPeerDTLS() {
-}
diff --git a/core/io/packet_peer_dtls.h b/core/io/packet_peer_dtls.h
index 4f9f4535bc..c2ff4e1a7f 100644
--- a/core/io/packet_peer_dtls.h
+++ b/core/io/packet_peer_dtls.h
@@ -60,7 +60,7 @@ public:
static PacketPeerDTLS *create();
static bool is_available();
- PacketPeerDTLS();
+ PacketPeerDTLS() {}
};
VARIANT_ENUM_CAST(PacketPeerDTLS::Status);
diff --git a/core/io/packet_peer_udp.cpp b/core/io/packet_peer_udp.cpp
index f800ffc3db..862fca96fc 100644
--- a/core/io/packet_peer_udp.cpp
+++ b/core/io/packet_peer_udp.cpp
@@ -33,18 +33,17 @@
#include "core/io/ip.h"
void PacketPeerUDP::set_blocking_mode(bool p_enable) {
-
blocking = p_enable;
}
void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) {
broadcast = p_enabled;
- if (_sock.is_valid() && _sock->is_open())
+ if (_sock.is_valid() && _sock->is_open()) {
_sock->set_broadcasting_enabled(p_enabled);
+ }
}
Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_if_name) {
-
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
ERR_FAIL_COND_V(!p_multi_address.is_valid(), ERR_INVALID_PARAMETER);
@@ -59,26 +58,24 @@ Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_i
}
Error PacketPeerUDP::leave_multicast_group(IP_Address p_multi_address, String p_if_name) {
-
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
ERR_FAIL_COND_V(!_sock->is_open(), ERR_UNCONFIGURED);
return _sock->leave_multicast_group(p_multi_address, p_if_name);
}
String PacketPeerUDP::_get_packet_ip() const {
-
return get_packet_address();
}
Error PacketPeerUDP::_set_dest_address(const String &p_address, int p_port) {
-
IP_Address ip;
if (p_address.is_valid_ip_address()) {
ip = p_address;
} else {
ip = IP::get_singleton()->resolve_hostname(p_address);
- if (!ip.is_valid())
+ if (!ip.is_valid()) {
return ERR_CANT_RESOLVE;
+ }
}
set_dest_address(ip, p_port);
@@ -86,22 +83,23 @@ Error PacketPeerUDP::_set_dest_address(const String &p_address, int p_port) {
}
int PacketPeerUDP::get_available_packet_count() const {
-
// TODO we should deprecate this, and expose poll instead!
Error err = const_cast<PacketPeerUDP *>(this)->_poll();
- if (err != OK)
+ if (err != OK) {
return -1;
+ }
return queue_count;
}
Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
-
Error err = _poll();
- if (err != OK)
+ if (err != OK) {
return err;
- if (queue_count == 0)
+ }
+ if (queue_count == 0) {
return ERR_UNAVAILABLE;
+ }
uint32_t size = 0;
uint8_t ipv6[16];
@@ -117,7 +115,6 @@ Error PacketPeerUDP::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
}
Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
-
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
ERR_FAIL_COND_V(!peer_addr.is_valid(), ERR_UNCONFIGURED);
@@ -139,10 +136,11 @@ Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
err = _sock->sendto(p_buffer, p_buffer_size, sent, peer_addr, peer_port);
}
if (err != OK) {
- if (err != ERR_BUSY)
+ if (err != ERR_BUSY) {
return FAILED;
- else if (!blocking)
+ } else if (!blocking) {
return ERR_BUSY;
+ }
// Keep trying to send full packet
continue;
}
@@ -154,12 +152,10 @@ Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
}
int PacketPeerUDP::get_max_packet_size() const {
-
return 512; // uhm maybe not
}
Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_recv_buffer_size) {
-
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE);
ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);
@@ -167,13 +163,15 @@ Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_
Error err;
IP::Type ip_type = IP::TYPE_ANY;
- if (p_bind_address.is_valid())
+ if (p_bind_address.is_valid()) {
ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+ }
err = _sock->open(NetSocket::TYPE_UDP, ip_type);
- if (err != OK)
+ if (err != OK) {
return ERR_CANT_CREATE;
+ }
_sock->set_blocking_enabled(false);
_sock->set_reuse_address_enabled(true);
@@ -245,22 +243,20 @@ bool PacketPeerUDP::is_connected_to_host() const {
}
void PacketPeerUDP::close() {
-
- if (_sock.is_valid())
+ if (_sock.is_valid()) {
_sock->close();
+ }
rb.resize(16);
queue_count = 0;
connected = false;
}
Error PacketPeerUDP::wait() {
-
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
return _sock->poll(NetSocket::POLL_TYPE_IN, -1);
}
Error PacketPeerUDP::_poll() {
-
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
if (!_sock->is_open()) {
@@ -282,8 +278,9 @@ Error PacketPeerUDP::_poll() {
}
if (err != OK) {
- if (err == ERR_BUSY)
+ if (err == ERR_BUSY) {
break;
+ }
return FAILED;
}
@@ -304,30 +301,26 @@ Error PacketPeerUDP::_poll() {
return OK;
}
-bool PacketPeerUDP::is_listening() const {
+bool PacketPeerUDP::is_listening() const {
return _sock.is_valid() && _sock->is_open();
}
IP_Address PacketPeerUDP::get_packet_address() const {
-
return packet_ip;
}
int PacketPeerUDP::get_packet_port() const {
-
return packet_port;
}
void PacketPeerUDP::set_dest_address(const IP_Address &p_address, int p_port) {
-
ERR_FAIL_COND_MSG(connected, "Destination address cannot be set for connected sockets");
peer_addr = p_address;
peer_port = p_port;
}
void PacketPeerUDP::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("listen", "port", "bind_address", "recv_buf_size"), &PacketPeerUDP::listen, DEFVAL("*"), DEFVAL(65536));
ClassDB::bind_method(D_METHOD("close"), &PacketPeerUDP::close);
ClassDB::bind_method(D_METHOD("wait"), &PacketPeerUDP::wait);
@@ -343,17 +336,10 @@ void PacketPeerUDP::_bind_methods() {
}
PacketPeerUDP::PacketPeerUDP() :
- packet_port(0),
- queue_count(0),
- peer_port(0),
- connected(false),
- blocking(true),
- broadcast(false),
_sock(Ref<NetSocket>(NetSocket::create())) {
rb.resize(16);
}
PacketPeerUDP::~PacketPeerUDP() {
-
close();
}
diff --git a/core/io/packet_peer_udp.h b/core/io/packet_peer_udp.h
index b5a9fc9ec3..23fc5460a6 100644
--- a/core/io/packet_peer_udp.h
+++ b/core/io/packet_peer_udp.h
@@ -47,14 +47,14 @@ protected:
uint8_t recv_buffer[PACKET_BUFFER_SIZE];
uint8_t packet_buffer[PACKET_BUFFER_SIZE];
IP_Address packet_ip;
- int packet_port;
- int queue_count;
+ int packet_port = 0;
+ int queue_count = 0;
IP_Address peer_addr;
- int peer_port;
- bool connected;
- bool blocking;
- bool broadcast;
+ int peer_port = 0;
+ bool connected = false;
+ bool blocking = true;
+ bool broadcast = false;
Ref<NetSocket> _sock;
static void _bind_methods();
diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp
index 5c4b3379ee..374b2a5e07 100644
--- a/core/io/pck_packer.cpp
+++ b/core/io/pck_packer.cpp
@@ -35,34 +35,31 @@
#include "core/version.h"
static uint64_t _align(uint64_t p_n, int p_alignment) {
-
- if (p_alignment == 0)
+ if (p_alignment == 0) {
return p_n;
+ }
uint64_t rest = p_n % p_alignment;
- if (rest == 0)
+ if (rest == 0) {
return p_n;
- else
+ } else {
return p_n + (p_alignment - rest);
-};
+ }
+}
static void _pad(FileAccess *p_file, int p_bytes) {
-
for (int i = 0; i < p_bytes; i++) {
-
p_file->store_8(0);
- };
-};
+ }
+}
void PCKPacker::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("pck_start", "pck_name", "alignment"), &PCKPacker::pck_start, DEFVAL(0));
ClassDB::bind_method(D_METHOD("add_file", "pck_path", "source_path"), &PCKPacker::add_file);
ClassDB::bind_method(D_METHOD("flush", "verbose"), &PCKPacker::flush, DEFVAL(false));
-};
+}
Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
-
if (file != nullptr) {
memdelete(file);
}
@@ -80,21 +77,19 @@ Error PCKPacker::pck_start(const String &p_file, int p_alignment) {
file->store_32(VERSION_PATCH);
for (int i = 0; i < 16; i++) {
-
file->store_32(0); // reserved
- };
+ }
files.clear();
return OK;
-};
+}
Error PCKPacker::add_file(const String &p_file, const String &p_src) {
-
FileAccess *f = FileAccess::open(p_src, FileAccess::READ);
if (!f) {
return ERR_FILE_CANT_OPEN;
- };
+ }
File pf;
pf.path = p_file;
@@ -108,10 +103,9 @@ Error PCKPacker::add_file(const String &p_file, const String &p_src) {
memdelete(f);
return OK;
-};
+}
Error PCKPacker::flush(bool p_verbose) {
-
ERR_FAIL_COND_V_MSG(!file, ERR_INVALID_PARAMETER, "File must be opened before use.");
// write the index
@@ -119,7 +113,6 @@ Error PCKPacker::flush(bool p_verbose) {
file->store_32(files.size());
for (int i = 0; i < files.size(); i++) {
-
file->store_pascal_string(files[i].path);
files.write[i].offset_offset = file->get_position();
file->store_64(0); // offset
@@ -130,7 +123,7 @@ Error PCKPacker::flush(bool p_verbose) {
file->store_32(0);
file->store_32(0);
file->store_32(0);
- };
+ }
uint64_t ofs = file->get_position();
ofs = _align(ofs, alignment);
@@ -142,15 +135,13 @@ Error PCKPacker::flush(bool p_verbose) {
int count = 0;
for (int i = 0; i < files.size(); i++) {
-
FileAccess *src = FileAccess::open(files[i].src_path, FileAccess::READ);
uint64_t to_write = files[i].size;
while (to_write > 0) {
-
int read = src->get_buffer(buf, MIN(to_write, buf_max));
file->store_buffer(buf, read);
to_write -= read;
- };
+ }
uint64_t pos = file->get_position();
file->seek(files[i].offset_offset); // go back to store the file's offset
@@ -167,27 +158,23 @@ Error PCKPacker::flush(bool p_verbose) {
if (count % 100 == 0) {
printf("%i/%i (%.2f)\r", count, files.size(), float(count) / files.size() * 100);
fflush(stdout);
- };
- };
- };
+ }
+ }
+ }
- if (p_verbose)
+ if (p_verbose) {
printf("\n");
+ }
file->close();
memdelete_arr(buf);
return OK;
-};
-
-PCKPacker::PCKPacker() {
-
- file = nullptr;
-};
+}
PCKPacker::~PCKPacker() {
if (file != nullptr) {
memdelete(file);
- };
+ }
file = nullptr;
-};
+}
diff --git a/core/io/pck_packer.h b/core/io/pck_packer.h
index 6058de8345..2929967a68 100644
--- a/core/io/pck_packer.h
+++ b/core/io/pck_packer.h
@@ -36,16 +36,14 @@
class FileAccess;
class PCKPacker : public Reference {
-
GDCLASS(PCKPacker, Reference);
- FileAccess *file;
+ FileAccess *file = nullptr;
int alignment;
static void _bind_methods();
struct File {
-
String path;
String src_path;
int size;
@@ -58,7 +56,7 @@ public:
Error add_file(const String &p_file, const String &p_src);
Error flush(bool p_verbose = false);
- PCKPacker();
+ PCKPacker() {}
~PCKPacker();
};
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index a640565ecf..5097f6d98b 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -94,24 +94,24 @@ enum {
};
void ResourceLoaderBinary::_advance_padding(uint32_t p_len) {
-
uint32_t extra = 4 - (p_len % 4);
if (extra < 4) {
- for (uint32_t i = 0; i < extra; i++)
+ for (uint32_t i = 0; i < extra; i++) {
f->get_8(); //pad to 32
+ }
}
}
StringName ResourceLoaderBinary::_get_string() {
-
uint32_t id = f->get_32();
if (id & 0x80000000) {
uint32_t len = id & 0x7FFFFFFF;
if ((int)len > str_buf.size()) {
str_buf.resize(len);
}
- if (len == 0)
+ if (len == 0) {
return StringName();
+ }
f->get_buffer((uint8_t *)&str_buf[0], len);
String s;
s.parse_utf8(&str_buf[0]);
@@ -122,42 +122,32 @@ StringName ResourceLoaderBinary::_get_string() {
}
Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
-
uint32_t type = f->get_32();
print_bl("find property of type: " + itos(type));
switch (type) {
-
case VARIANT_NIL: {
-
r_v = Variant();
} break;
case VARIANT_BOOL: {
-
r_v = bool(f->get_32());
} break;
case VARIANT_INT: {
-
r_v = int(f->get_32());
} break;
case VARIANT_INT64: {
-
r_v = int64_t(f->get_64());
} break;
case VARIANT_FLOAT: {
-
r_v = f->get_real();
} break;
case VARIANT_DOUBLE: {
-
r_v = f->get_double();
} break;
case VARIANT_STRING: {
-
r_v = get_unicode_string();
} break;
case VARIANT_VECTOR2: {
-
Vector2 v;
v.x = f->get_real();
v.y = f->get_real();
@@ -165,7 +155,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_VECTOR2I: {
-
Vector2i v;
v.x = f->get_32();
v.y = f->get_32();
@@ -173,7 +162,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_RECT2: {
-
Rect2 v;
v.position.x = f->get_real();
v.position.y = f->get_real();
@@ -183,7 +171,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_RECT2I: {
-
Rect2i v;
v.position.x = f->get_32();
v.position.y = f->get_32();
@@ -193,7 +180,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_VECTOR3: {
-
Vector3 v;
v.x = f->get_real();
v.y = f->get_real();
@@ -201,7 +187,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
r_v = v;
} break;
case VARIANT_VECTOR3I: {
-
Vector3i v;
v.x = f->get_32();
v.y = f->get_32();
@@ -209,7 +194,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
r_v = v;
} break;
case VARIANT_PLANE: {
-
Plane v;
v.normal.x = f->get_real();
v.normal.y = f->get_real();
@@ -227,7 +211,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_AABB: {
-
AABB v;
v.position.x = f->get_real();
v.position.y = f->get_real();
@@ -239,7 +222,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_MATRIX32: {
-
Transform2D v;
v.elements[0].x = f->get_real();
v.elements[0].y = f->get_real();
@@ -251,7 +233,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_MATRIX3: {
-
Basis v;
v.elements[0].x = f->get_real();
v.elements[0].y = f->get_real();
@@ -266,7 +247,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_TRANSFORM: {
-
Transform v;
v.basis.elements[0].x = f->get_real();
v.basis.elements[0].y = f->get_real();
@@ -283,7 +263,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
r_v = v;
} break;
case VARIANT_COLOR: {
-
Color v;
v.r = f->get_real();
v.g = f->get_real();
@@ -293,12 +272,10 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_STRING_NAME: {
-
r_v = StringName(get_unicode_string());
} break;
case VARIANT_NODE_PATH: {
-
Vector<StringName> names;
Vector<StringName> subnames;
bool absolute;
@@ -311,10 +288,12 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
subname_count += 1; // has a property field, so we should count it as well
}
- for (int i = 0; i < name_count; i++)
+ for (int i = 0; i < name_count; i++) {
names.push_back(_get_string());
- for (uint32_t i = 0; i < subname_count; i++)
+ }
+ for (uint32_t i = 0; i < subname_count; i++) {
subnames.push_back(_get_string());
+ }
NodePath np = NodePath(names, subnames, absolute);
@@ -322,15 +301,12 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_RID: {
-
r_v = f->get_32();
} break;
case VARIANT_OBJECT: {
-
uint32_t objtype = f->get_32();
switch (objtype) {
-
case OBJECT_EMPTY: {
//do none
@@ -338,11 +314,19 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
case OBJECT_INTERNAL_RESOURCE: {
uint32_t index = f->get_32();
String path = res_path + "::" + itos(index);
- RES res = ResourceLoader::load(path);
- if (res.is_null()) {
- WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
+
+ if (use_nocache) {
+ if (!internal_index_cache.has(path)) {
+ WARN_PRINT(String("Couldn't load resource (no cache): " + path).utf8().get_data());
+ }
+ r_v = internal_index_cache[path];
+ } else {
+ RES res = ResourceLoader::load(path);
+ if (res.is_null()) {
+ WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data());
+ }
+ r_v = res;
}
- r_v = res;
} break;
case OBJECT_EXTERNAL_RESOURCE: {
@@ -376,7 +360,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
WARN_PRINT("Broken external resource! (index out of size)");
r_v = Variant();
} else {
-
if (external_resources[erindex].cache.is_null()) {
//cache not here yet, wait for it?
if (use_sub_threads) {
@@ -385,10 +368,8 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
if (err != OK || external_resources[erindex].cache.is_null()) {
if (!ResourceLoader::get_abort_on_missing_resources()) {
-
ResourceLoader::notify_dependency_error(local_path, external_resources[erindex].path, external_resources[erindex].type);
} else {
-
error = ERR_FILE_MISSING_DEPENDENCIES;
ERR_FAIL_V_MSG(error, "Can't load dependency: " + external_resources[erindex].path + ".");
}
@@ -401,23 +382,19 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
default: {
-
ERR_FAIL_V(ERR_FILE_CORRUPT);
} break;
}
} break;
case VARIANT_CALLABLE: {
-
r_v = Callable();
} break;
case VARIANT_SIGNAL: {
-
r_v = Signal();
} break;
case VARIANT_DICTIONARY: {
-
uint32_t len = f->get_32();
Dictionary d; //last bit means shared
len &= 0x7FFFFFFF;
@@ -433,7 +410,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
r_v = d;
} break;
case VARIANT_ARRAY: {
-
uint32_t len = f->get_32();
Array a; //last bit means shared
len &= 0x7FFFFFFF;
@@ -448,7 +424,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_RAW_ARRAY: {
-
uint32_t len = f->get_32();
Vector<uint8_t> array;
@@ -461,7 +436,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_INT32_ARRAY: {
-
uint32_t len = f->get_32();
Vector<int32_t> array;
@@ -472,7 +446,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
{
uint32_t *ptr = (uint32_t *)w.ptr();
for (int i = 0; i < len; i++) {
-
ptr[i] = BSWAP32(ptr[i]);
}
}
@@ -482,7 +455,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
r_v = array;
} break;
case VARIANT_INT64_ARRAY: {
-
uint32_t len = f->get_32();
Vector<int64_t> array;
@@ -493,7 +465,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
{
uint64_t *ptr = (uint64_t *)w.ptr();
for (int i = 0; i < len; i++) {
-
ptr[i] = BSWAP64(ptr[i]);
}
}
@@ -503,7 +474,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
r_v = array;
} break;
case VARIANT_FLOAT32_ARRAY: {
-
uint32_t len = f->get_32();
Vector<float> array;
@@ -514,7 +484,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
{
uint32_t *ptr = (uint32_t *)w.ptr();
for (int i = 0; i < len; i++) {
-
ptr[i] = BSWAP32(ptr[i]);
}
}
@@ -524,7 +493,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
r_v = array;
} break;
case VARIANT_FLOAT64_ARRAY: {
-
uint32_t len = f->get_32();
Vector<double> array;
@@ -535,7 +503,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
{
uint64_t *ptr = (uint64_t *)w.ptr();
for (int i = 0; i < len; i++) {
-
ptr[i] = BSWAP64(ptr[i]);
}
}
@@ -545,19 +512,18 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
r_v = array;
} break;
case VARIANT_STRING_ARRAY: {
-
uint32_t len = f->get_32();
Vector<String> array;
array.resize(len);
String *w = array.ptrw();
- for (uint32_t i = 0; i < len; i++)
+ for (uint32_t i = 0; i < len; i++) {
w[i] = get_unicode_string();
+ }
r_v = array;
} break;
case VARIANT_VECTOR2_ARRAY: {
-
uint32_t len = f->get_32();
Vector<Vector2> array;
@@ -569,7 +535,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
{
uint32_t *ptr = (uint32_t *)w.ptr();
for (int i = 0; i < len * 2; i++) {
-
ptr[i] = BSWAP32(ptr[i]);
}
}
@@ -584,7 +549,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_VECTOR3_ARRAY: {
-
uint32_t len = f->get_32();
Vector<Vector3> array;
@@ -596,7 +560,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
{
uint32_t *ptr = (uint32_t *)w.ptr();
for (int i = 0; i < len * 3; i++) {
-
ptr[i] = BSWAP32(ptr[i]);
}
}
@@ -611,7 +574,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
} break;
case VARIANT_COLOR_ARRAY: {
-
uint32_t len = f->get_32();
Vector<Color> array;
@@ -623,7 +585,6 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
{
uint32_t *ptr = (uint32_t *)w.ptr();
for (int i = 0; i < len * 4; i++) {
-
ptr[i] = BSWAP32(ptr[i]);
}
}
@@ -645,23 +606,21 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) {
}
void ResourceLoaderBinary::set_local_path(const String &p_local_path) {
-
res_path = p_local_path;
}
Ref<Resource> ResourceLoaderBinary::get_resource() {
-
return resource;
}
-Error ResourceLoaderBinary::load() {
- if (error != OK)
+Error ResourceLoaderBinary::load() {
+ if (error != OK) {
return error;
+ }
int stage = 0;
for (int i = 0; i < external_resources.size(); i++) {
-
String path = external_resources[i].path;
if (remaps.has(path)) {
@@ -680,10 +639,8 @@ Error ResourceLoaderBinary::load() {
if (external_resources[i].cache.is_null()) {
if (!ResourceLoader::get_abort_on_missing_resources()) {
-
ResourceLoader::notify_dependency_error(local_path, path, external_resources[i].type);
} else {
-
error = ERR_FILE_MISSING_DEPENDENCIES;
ERR_FAIL_V_MSG(error, "Can't load dependency: " + path + ".");
}
@@ -693,10 +650,8 @@ Error ResourceLoaderBinary::load() {
Error err = ResourceLoader::load_threaded_request(path, external_resources[i].type, use_sub_threads, local_path);
if (err != OK) {
if (!ResourceLoader::get_abort_on_missing_resources()) {
-
ResourceLoader::notify_dependency_error(local_path, path, external_resources[i].type);
} else {
-
error = ERR_FILE_MISSING_DEPENDENCIES;
ERR_FAIL_V_MSG(error, "Can't load dependency: " + path + ".");
}
@@ -707,7 +662,6 @@ Error ResourceLoaderBinary::load() {
}
for (int i = 0; i < internal_resources.size(); i++) {
-
bool main = i == (internal_resources.size() - 1);
//maybe it is loaded already
@@ -715,24 +669,26 @@ Error ResourceLoaderBinary::load() {
int subindex = 0;
if (!main) {
-
path = internal_resources[i].path;
+
if (path.begins_with("local://")) {
path = path.replace_first("local://", "");
subindex = path.to_int();
path = res_path + "::" + path;
}
- if (ResourceCache::has(path)) {
- //already loaded, don't do anything
- stage++;
- error = OK;
- continue;
+ if (!use_nocache) {
+ if (ResourceCache::has(path)) {
+ //already loaded, don't do anything
+ stage++;
+ error = OK;
+ continue;
+ }
}
} else {
-
- if (!ResourceCache::has(res_path))
+ if (!use_nocache && !ResourceCache::has(res_path)) {
path = res_path;
+ }
}
uint64_t offset = internal_resources[i].offset;
@@ -757,15 +713,20 @@ Error ResourceLoaderBinary::load() {
RES res = RES(r);
- r->set_path(path);
+ if (path != String()) {
+ r->set_path(path);
+ }
r->set_subindex(subindex);
+ if (!main) {
+ internal_index_cache[path] = res;
+ }
+
int pc = f->get_32();
//set properties
for (int j = 0; j < pc; j++) {
-
StringName name = _get_string();
if (name == StringName()) {
@@ -776,8 +737,9 @@ Error ResourceLoaderBinary::load() {
Variant value;
error = parse_variant(value);
- if (error)
+ if (error) {
return error;
+ }
res->set(name, value);
}
@@ -793,7 +755,6 @@ Error ResourceLoaderBinary::load() {
resource_cache.push_back(res);
if (main) {
-
f->close();
resource = res;
resource->set_as_translation_remapped(translation_remapped);
@@ -806,19 +767,16 @@ Error ResourceLoaderBinary::load() {
}
void ResourceLoaderBinary::set_translation_remapped(bool p_remapped) {
-
translation_remapped = p_remapped;
}
static void save_ustring(FileAccess *f, const String &p_string) {
-
CharString utf8 = p_string.utf8();
f->store_32(utf8.length() + 1);
f->store_buffer((const uint8_t *)utf8.get_data(), utf8.length() + 1);
}
static String get_ustring(FileAccess *f) {
-
int len = f->get_32();
Vector<char> str_buf;
str_buf.resize(len);
@@ -829,13 +787,13 @@ static String get_ustring(FileAccess *f) {
}
String ResourceLoaderBinary::get_unicode_string() {
-
int len = f->get_32();
if (len > str_buf.size()) {
str_buf.resize(len);
}
- if (len == 0)
+ if (len == 0) {
return String();
+ }
f->get_buffer((uint8_t *)&str_buf[0], len);
String s;
s.parse_utf8(&str_buf[0]);
@@ -843,13 +801,12 @@ String ResourceLoaderBinary::get_unicode_string() {
}
void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) {
-
open(p_f);
- if (error)
+ if (error) {
return;
+ }
for (int i = 0; i < external_resources.size(); i++) {
-
String dep = external_resources[i].path;
if (p_add_types && external_resources[i].type != String()) {
@@ -861,7 +818,6 @@ void ResourceLoaderBinary::get_dependencies(FileAccess *p_f, List<String> *p_dep
}
void ResourceLoaderBinary::open(FileAccess *p_f) {
-
error = OK;
f = p_f;
@@ -906,7 +862,6 @@ void ResourceLoaderBinary::open(FileAccess *p_f) {
print_bl("format: " + itos(ver_format));
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
-
f->close();
ERR_FAIL_MSG("File format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path + ".");
}
@@ -916,13 +871,13 @@ void ResourceLoaderBinary::open(FileAccess *p_f) {
print_bl("type: " + type);
importmd_ofs = f->get_64();
- for (int i = 0; i < 14; i++)
+ for (int i = 0; i < 14; i++) {
f->get_32(); //skip a few reserved fields
+ }
uint32_t string_table_size = f->get_32();
string_map.resize(string_table_size);
for (uint32_t i = 0; i < string_table_size; i++) {
-
StringName s = get_unicode_string();
string_map.write[i] = s;
}
@@ -931,7 +886,6 @@ void ResourceLoaderBinary::open(FileAccess *p_f) {
uint32_t ext_resources_size = f->get_32();
for (uint32_t i = 0; i < ext_resources_size; i++) {
-
ExtResource er;
er.type = get_unicode_string();
@@ -944,7 +898,6 @@ void ResourceLoaderBinary::open(FileAccess *p_f) {
uint32_t int_resources_size = f->get_32();
for (uint32_t i = 0; i < int_resources_size; i++) {
-
IntResource ir;
ir.path = get_unicode_string();
ir.offset = f->get_64();
@@ -954,7 +907,6 @@ void ResourceLoaderBinary::open(FileAccess *p_f) {
print_bl("int resources: " + itos(int_resources_size));
if (f->eof_reached()) {
-
error = ERR_FILE_CORRUPT;
f->close();
ERR_FAIL_MSG("Premature end of file (EOF): " + local_path + ".");
@@ -962,7 +914,6 @@ void ResourceLoaderBinary::open(FileAccess *p_f) {
}
String ResourceLoaderBinary::recognize(FileAccess *p_f) {
-
error = OK;
f = p_f;
@@ -996,7 +947,6 @@ String ResourceLoaderBinary::recognize(FileAccess *p_f) {
uint32_t ver_format = f->get_32();
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
-
f->close();
return "";
}
@@ -1006,27 +956,16 @@ String ResourceLoaderBinary::recognize(FileAccess *p_f) {
return type;
}
-ResourceLoaderBinary::ResourceLoaderBinary() :
- translation_remapped(false),
- ver_format(0),
- f(nullptr),
- importmd_ofs(0),
- error(OK) {
-
- progress = nullptr;
- use_sub_threads = false;
-}
-
ResourceLoaderBinary::~ResourceLoaderBinary() {
-
- if (f)
+ if (f) {
memdelete(f);
+ }
}
-RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
- if (r_error)
+RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
+ }
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
@@ -1034,6 +973,7 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi
ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot open file '" + p_path + "'.");
ResourceLoaderBinary loader;
+ loader.use_nocache = p_no_cache;
loader.use_sub_threads = p_use_sub_threads;
loader.progress = r_progress;
String path = p_original_path != "" ? p_original_path : p_path;
@@ -1055,7 +995,6 @@ RES ResourceFormatLoaderBinary::load(const String &p_path, const String &p_origi
}
void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
-
if (p_type == "") {
get_recognized_extensions(p_extensions);
return;
@@ -1071,8 +1010,8 @@ void ResourceFormatLoaderBinary::get_recognized_extensions_for_type(const String
p_extensions->push_back(ext);
}
}
-void ResourceFormatLoaderBinary::get_recognized_extensions(List<String> *p_extensions) const {
+void ResourceFormatLoaderBinary::get_recognized_extensions(List<String> *p_extensions) const {
List<String> extensions;
ClassDB::get_resource_base_extensions(&extensions);
extensions.sort();
@@ -1084,12 +1023,10 @@ void ResourceFormatLoaderBinary::get_recognized_extensions(List<String> *p_exten
}
bool ResourceFormatLoaderBinary::handles_type(const String &p_type) const {
-
return true; //handles all
}
void ResourceFormatLoaderBinary::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
-
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_MSG(!f, "Cannot open file '" + p_path + "'.");
@@ -1101,7 +1038,6 @@ void ResourceFormatLoaderBinary::get_dependencies(const String &p_path, List<Str
}
Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
-
//Error error=OK;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
@@ -1167,7 +1103,6 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
uint32_t ver_format = f->get_32();
if (ver_format < FORMAT_VERSION_CAN_RENAME_DEPS) {
-
memdelete(f);
memdelete(fw);
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
@@ -1199,7 +1134,6 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
}
if (ver_format > FORMAT_VERSION || ver_major > VERSION_MAJOR) {
-
memdelete(f);
memdelete(fw);
ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "File format '" + itos(FORMAT_VERSION) + "." + itos(ver_major) + "." + itos(ver_minor) + "' is too new! Please upgrade to a new engine version: " + local_path + ".");
@@ -1228,7 +1162,6 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
fw->store_32(string_table_size);
for (uint32_t i = 0; i < string_table_size; i++) {
-
String s = get_ustring(f);
save_ustring(fw, s);
}
@@ -1237,7 +1170,6 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
uint32_t ext_resources_size = f->get_32();
fw->store_32(ext_resources_size);
for (uint32_t i = 0; i < ext_resources_size; i++) {
-
String type = get_ustring(f);
String path = get_ustring(f);
@@ -1268,7 +1200,6 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
fw->store_32(int_resources_size);
for (uint32_t i = 0; i < int_resources_size; i++) {
-
String path = get_ustring(f);
uint64_t offset = f->get_64();
save_ustring(fw, path);
@@ -1302,7 +1233,6 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
}
String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const {
-
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
return ""; //could not rwead
@@ -1321,36 +1251,30 @@ String ResourceFormatLoaderBinary::get_resource_type(const String &p_path) const
///////////////////////////////////////////////////////////
void ResourceFormatSaverBinaryInstance::_pad_buffer(FileAccess *f, int p_bytes) {
-
int extra = 4 - (p_bytes % 4);
if (extra < 4) {
- for (int i = 0; i < extra; i++)
+ for (int i = 0; i < extra; i++) {
f->store_8(0); //pad to 32
+ }
}
}
void ResourceFormatSaverBinaryInstance::_write_variant(const Variant &p_property, const PropertyInfo &p_hint) {
-
write_variant(f, p_property, resource_set, external_resources, string_map, p_hint);
}
void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Variant &p_property, Set<RES> &resource_set, Map<RES, int> &external_resources, Map<StringName, int> &string_map, const PropertyInfo &p_hint) {
-
switch (p_property.get_type()) {
-
case Variant::NIL: {
-
f->store_32(VARIANT_NIL);
// don't store anything
} break;
case Variant::BOOL: {
-
f->store_32(VARIANT_BOOL);
bool val = p_property;
f->store_32(val);
} break;
case Variant::INT: {
-
int64_t val = p_property;
if (val > 0x7FFFFFFF || val < -(int64_t)0x80000000) {
f->store_32(VARIANT_INT64);
@@ -1363,28 +1287,24 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::FLOAT: {
-
double d = p_property;
float fl = d;
if (double(fl) != d) {
f->store_32(VARIANT_DOUBLE);
f->store_double(d);
} else {
-
f->store_32(VARIANT_FLOAT);
f->store_real(fl);
}
} break;
case Variant::STRING: {
-
f->store_32(VARIANT_STRING);
String val = p_property;
save_unicode_string(f, val);
} break;
case Variant::VECTOR2: {
-
f->store_32(VARIANT_VECTOR2);
Vector2 val = p_property;
f->store_real(val.x);
@@ -1392,7 +1312,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::VECTOR2I: {
-
f->store_32(VARIANT_VECTOR2I);
Vector2i val = p_property;
f->store_32(val.x);
@@ -1400,7 +1319,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::RECT2: {
-
f->store_32(VARIANT_RECT2);
Rect2 val = p_property;
f->store_real(val.position.x);
@@ -1410,7 +1328,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::RECT2I: {
-
f->store_32(VARIANT_RECT2I);
Rect2i val = p_property;
f->store_32(val.position.x);
@@ -1420,7 +1337,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::VECTOR3: {
-
f->store_32(VARIANT_VECTOR3);
Vector3 val = p_property;
f->store_real(val.x);
@@ -1429,7 +1345,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::VECTOR3I: {
-
f->store_32(VARIANT_VECTOR3I);
Vector3i val = p_property;
f->store_32(val.x);
@@ -1438,7 +1353,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::PLANE: {
-
f->store_32(VARIANT_PLANE);
Plane val = p_property;
f->store_real(val.normal.x);
@@ -1448,7 +1362,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::QUAT: {
-
f->store_32(VARIANT_QUAT);
Quat val = p_property;
f->store_real(val.x);
@@ -1458,7 +1371,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::AABB: {
-
f->store_32(VARIANT_AABB);
AABB val = p_property;
f->store_real(val.position.x);
@@ -1470,7 +1382,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::TRANSFORM2D: {
-
f->store_32(VARIANT_MATRIX32);
Transform2D val = p_property;
f->store_real(val.elements[0].x);
@@ -1482,7 +1393,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::BASIS: {
-
f->store_32(VARIANT_MATRIX3);
Basis val = p_property;
f->store_real(val.elements[0].x);
@@ -1497,7 +1407,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::TRANSFORM: {
-
f->store_32(VARIANT_TRANSFORM);
Transform val = p_property;
f->store_real(val.basis.elements[0].x);
@@ -1515,7 +1424,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::COLOR: {
-
f->store_32(VARIANT_COLOR);
Color val = p_property;
f->store_real(val.r);
@@ -1525,7 +1433,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::STRING_NAME: {
-
f->store_32(VARIANT_STRING_NAME);
String val = p_property;
save_unicode_string(f, val);
@@ -1537,8 +1444,9 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
NodePath np = p_property;
f->store_16(np.get_name_count());
uint16_t snc = np.get_subname_count();
- if (np.is_absolute())
+ if (np.is_absolute()) {
snc |= 0x8000;
+ }
f->store_16(snc);
for (int i = 0; i < np.get_name_count(); i++) {
if (string_map.has(np.get_name(i))) {
@@ -1557,14 +1465,12 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::_RID: {
-
f->store_32(VARIANT_RID);
WARN_PRINT("Can't save RIDs.");
RID val = p_property;
f->store_32(val.get_id());
} break;
case Variant::OBJECT: {
-
f->store_32(VARIANT_OBJECT);
RES res = p_property;
if (res.is_null()) {
@@ -1576,7 +1482,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
f->store_32(OBJECT_EXTERNAL_RESOURCE_INDEX);
f->store_32(external_resources[res]);
} else {
-
if (!resource_set.has(res)) {
f->store_32(OBJECT_EMPTY);
ERR_FAIL_MSG("Resource was not pre cached for the resource section, most likely due to circular reference.");
@@ -1589,18 +1494,15 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::CALLABLE: {
-
f->store_32(VARIANT_CALLABLE);
WARN_PRINT("Can't save Callables.");
} break;
case Variant::SIGNAL: {
-
f->store_32(VARIANT_SIGNAL);
WARN_PRINT("Can't save Signals.");
} break;
case Variant::DICTIONARY: {
-
f->store_32(VARIANT_DICTIONARY);
Dictionary d = p_property;
f->store_32(uint32_t(d.size()));
@@ -1609,7 +1511,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
d.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
/*
if (!_check_type(dict[E->get()]))
continue;
@@ -1621,18 +1522,15 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::ARRAY: {
-
f->store_32(VARIANT_ARRAY);
Array a = p_property;
f->store_32(uint32_t(a.size()));
for (int i = 0; i < a.size(); i++) {
-
write_variant(f, a[i], resource_set, external_resources, string_map);
}
} break;
case Variant::PACKED_BYTE_ARRAY: {
-
f->store_32(VARIANT_RAW_ARRAY);
Vector<uint8_t> arr = p_property;
int len = arr.size();
@@ -1643,29 +1541,28 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::PACKED_INT32_ARRAY: {
-
f->store_32(VARIANT_INT32_ARRAY);
Vector<int32_t> arr = p_property;
int len = arr.size();
f->store_32(len);
const int32_t *r = arr.ptr();
- for (int i = 0; i < len; i++)
+ for (int i = 0; i < len; i++) {
f->store_32(r[i]);
+ }
} break;
case Variant::PACKED_INT64_ARRAY: {
-
f->store_32(VARIANT_INT64_ARRAY);
Vector<int64_t> arr = p_property;
int len = arr.size();
f->store_32(len);
const int64_t *r = arr.ptr();
- for (int i = 0; i < len; i++)
+ for (int i = 0; i < len; i++) {
f->store_64(r[i]);
+ }
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
-
f->store_32(VARIANT_FLOAT32_ARRAY);
Vector<float> arr = p_property;
int len = arr.size();
@@ -1677,7 +1574,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::PACKED_FLOAT64_ARRAY: {
-
f->store_32(VARIANT_FLOAT64_ARRAY);
Vector<double> arr = p_property;
int len = arr.size();
@@ -1689,7 +1585,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::PACKED_STRING_ARRAY: {
-
f->store_32(VARIANT_STRING_ARRAY);
Vector<String> arr = p_property;
int len = arr.size();
@@ -1701,7 +1596,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::PACKED_VECTOR3_ARRAY: {
-
f->store_32(VARIANT_VECTOR3_ARRAY);
Vector<Vector3> arr = p_property;
int len = arr.size();
@@ -1715,7 +1609,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::PACKED_VECTOR2_ARRAY: {
-
f->store_32(VARIANT_VECTOR2_ARRAY);
Vector<Vector2> arr = p_property;
int len = arr.size();
@@ -1728,7 +1621,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
case Variant::PACKED_COLOR_ARRAY: {
-
f->store_32(VARIANT_COLOR_ARRAY);
Vector<Color> arr = p_property;
int len = arr.size();
@@ -1743,21 +1635,19 @@ void ResourceFormatSaverBinaryInstance::write_variant(FileAccess *f, const Varia
} break;
default: {
-
ERR_FAIL_MSG("Invalid variant.");
}
}
}
void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant, bool p_main) {
-
switch (p_variant.get_type()) {
case Variant::OBJECT: {
-
RES res = p_variant;
- if (res.is_null() || external_resources.has(res))
+ if (res.is_null() || external_resources.has(res)) {
return;
+ }
if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) {
if (res->get_path() == path) {
@@ -1769,17 +1659,16 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
return;
}
- if (resource_set.has(res))
+ if (resource_set.has(res)) {
return;
+ }
List<PropertyInfo> property_list;
res->get_property_list(&property_list);
for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
-
if (E->get().usage & PROPERTY_USAGE_STORAGE) {
-
Variant value = res->get(E->get().name);
if (E->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
RES sres = value;
@@ -1803,11 +1692,9 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
} break;
case Variant::ARRAY: {
-
Array varray = p_variant;
int len = varray.size();
for (int i = 0; i < len; i++) {
-
const Variant &v = varray.get(i);
_find_resources(v);
}
@@ -1815,12 +1702,10 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
} break;
case Variant::DICTIONARY: {
-
Dictionary d = p_variant;
List<Variant> keys;
d.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
_find_resources(E->get());
Variant v = d[E->get()];
_find_resources(v);
@@ -1829,10 +1714,12 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
case Variant::NODE_PATH: {
//take the chance and save node path strings
NodePath np = p_variant;
- for (int i = 0; i < np.get_name_count(); i++)
+ for (int i = 0; i < np.get_name_count(); i++) {
get_string_index(np.get_name(i));
- for (int i = 0; i < np.get_subname_count(); i++)
+ }
+ for (int i = 0; i < np.get_subname_count(); i++) {
get_string_index(np.get_subname(i));
+ }
} break;
default: {
@@ -1841,7 +1728,6 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
}
void ResourceFormatSaverBinaryInstance::save_unicode_string(FileAccess *f, const String &p_string, bool p_bit_on_len) {
-
CharString utf8 = p_string.utf8();
if (p_bit_on_len) {
f->store_32((utf8.length() + 1) | 0x80000000);
@@ -1852,10 +1738,10 @@ void ResourceFormatSaverBinaryInstance::save_unicode_string(FileAccess *f, const
}
int ResourceFormatSaverBinaryInstance::get_string_index(const String &p_string) {
-
StringName s = p_string;
- if (string_map.has(s))
+ if (string_map.has(s)) {
return string_map[s];
+ }
string_map[s] = strings.size();
strings.push_back(s);
@@ -1863,15 +1749,15 @@ int ResourceFormatSaverBinaryInstance::get_string_index(const String &p_string)
}
Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
Error err;
if (p_flags & ResourceSaver::FLAG_COMPRESS) {
FileAccessCompressed *fac = memnew(FileAccessCompressed);
fac->configure("RSCC");
f = fac;
err = fac->_open(p_path, FileAccess::WRITE);
- if (err)
+ if (err) {
memdelete(f);
+ }
} else {
f = FileAccess::open(p_path, FileAccess::WRITE, &err);
@@ -1885,8 +1771,9 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
big_endian = p_flags & ResourceSaver::FLAG_SAVE_BIG_ENDIAN;
takeover_paths = p_flags & ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
- if (!p_path.begins_with("res://"))
+ if (!p_path.begins_with("res://")) {
takeover_paths = false;
+ }
local_path = p_path.get_base_dir();
path = ProjectSettings::get_singleton()->localize_path(p_path);
@@ -1902,8 +1789,9 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
if (big_endian) {
f->store_32(1);
f->set_endian_swap(true);
- } else
+ } else {
f->store_32(0);
+ }
f->store_32(0); //64 bits file, false for now
f->store_32(VERSION_MAJOR);
@@ -1918,15 +1806,14 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
save_unicode_string(f, p_resource->get_class());
f->store_64(0); //offset to import metadata
- for (int i = 0; i < 14; i++)
+ for (int i = 0; i < 14; i++) {
f->store_32(0); // reserved
+ }
List<ResourceData> resources;
{
-
for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) {
-
ResourceData &rd = resources.push_back(ResourceData())->get();
rd.type = E->get()->get_class();
@@ -1934,9 +1821,9 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
E->get()->get_property_list(&property_list);
for (List<PropertyInfo>::Element *F = property_list.front(); F; F = F->next()) {
-
- if (skip_editor && F->get().name.begins_with("__editor"))
+ if (skip_editor && F->get().name.begins_with("__editor")) {
continue;
+ }
if ((F->get().usage & PROPERTY_USAGE_STORAGE)) {
Property p;
p.name_idx = get_string_index(F->get().name);
@@ -1981,7 +1868,6 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
}
for (int i = 0; i < save_order.size(); i++) {
-
save_unicode_string(f, save_order[i]->get_save_class());
String path = save_order[i]->get_path();
path = relative_paths ? local_path.path_to_file(path) : path;
@@ -1993,10 +1879,8 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
Set<int> used_indices;
for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) {
-
RES r = E->get();
if (r->get_path() == "" || r->get_path().find("::") != -1) {
-
if (r->get_subindex() != 0) {
if (used_indices.has(r->get_subindex())) {
r->set_subindex(0); //repeated
@@ -2008,7 +1892,6 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
}
for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) {
-
RES r = E->get();
if (r->get_path() == "" || r->get_path().find("::") != -1) {
if (r->get_subindex() == 0) {
@@ -2039,7 +1922,6 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
//now actually save the resources
for (List<ResourceData>::Element *E = resources.front(); E; E = E->next()) {
-
ResourceData &rd = E->get();
ofs_table.push_back(f->get_position());
@@ -2047,7 +1929,6 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
f->store_32(rd.properties.size());
for (List<Property>::Element *F = rd.properties.front(); F; F = F->next()) {
-
Property &p = F->get();
f->store_32(p.name_idx);
_write_variant(p.value, F->get().pi);
@@ -2076,28 +1957,25 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const RES &p
}
Error ResourceFormatSaverBinary::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
ResourceFormatSaverBinaryInstance saver;
return saver.save(local_path, p_resource, p_flags);
}
bool ResourceFormatSaverBinary::recognize(const RES &p_resource) const {
-
return true; //all recognized
}
void ResourceFormatSaverBinary::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
-
String base = p_resource->get_base_extension().to_lower();
p_extensions->push_back(base);
- if (base != "res")
+ if (base != "res") {
p_extensions->push_back("res");
+ }
}
ResourceFormatSaverBinary *ResourceFormatSaverBinary::singleton = nullptr;
ResourceFormatSaverBinary::ResourceFormatSaverBinary() {
-
singleton = this;
}
diff --git a/core/io/resource_format_binary.h b/core/io/resource_format_binary.h
index da67e1e648..54cddca49e 100644
--- a/core/io/resource_format_binary.h
+++ b/core/io/resource_format_binary.h
@@ -36,17 +36,16 @@
#include "core/os/file_access.h"
class ResourceLoaderBinary {
-
- bool translation_remapped;
+ bool translation_remapped = false;
String local_path;
String res_path;
String type;
Ref<Resource> resource;
- uint32_t ver_format;
+ uint32_t ver_format = 0;
- FileAccess *f;
+ FileAccess *f = nullptr;
- uint64_t importmd_ofs;
+ uint64_t importmd_ofs = 0;
Vector<char> str_buf;
List<RES> resource_cache;
@@ -61,8 +60,8 @@ class ResourceLoaderBinary {
RES cache;
};
- bool use_sub_threads;
- float *progress;
+ bool use_sub_threads = false;
+ float *progress = nullptr;
Vector<ExtResource> external_resources;
struct IntResource {
@@ -71,12 +70,15 @@ class ResourceLoaderBinary {
};
Vector<IntResource> internal_resources;
+ Map<String, RES> internal_index_cache;
String get_unicode_string();
void _advance_padding(uint32_t p_len);
Map<String, String> remaps;
- Error error;
+ Error error = OK;
+
+ bool use_nocache = false;
friend class ResourceFormatLoaderBinary;
@@ -95,13 +97,13 @@ public:
String recognize(FileAccess *p_f);
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
- ResourceLoaderBinary();
+ ResourceLoaderBinary() {}
~ResourceLoaderBinary();
};
class ResourceFormatLoaderBinary : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
@@ -111,7 +113,6 @@ public:
};
class ResourceFormatSaverBinaryInstance {
-
String local_path;
String path;
@@ -144,7 +145,6 @@ class ResourceFormatSaverBinaryInstance {
};
struct ResourceData {
-
String type;
List<Property> properties;
};
diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp
index ceb73cab77..9ed159bd20 100644
--- a/core/io/resource_importer.cpp
+++ b/core/io/resource_importer.cpp
@@ -38,7 +38,6 @@ bool ResourceFormatImporter::SortImporterByName::operator()(const Ref<ResourceIm
}
Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndType &r_path_and_type, bool *r_valid) const {
-
Error err;
FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
@@ -64,7 +63,6 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
String error_text;
bool path_found = false; //first match must have priority
while (true) {
-
assign = Variant();
next_tag.fields.clear();
next_tag.name = String();
@@ -91,7 +89,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
r_path_and_type.path = value;
path_found = true; //first match must have priority
} else if (assign == "type") {
- r_path_and_type.type = value;
+ r_path_and_type.type = ClassDB::get_compatibility_remapped_class(value);
} else if (assign == "importer") {
r_path_and_type.importer = value;
} else if (assign == "group_file") {
@@ -117,20 +115,19 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy
return OK;
}
-RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
+RES ResourceFormatImporter::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
PathAndType pat;
Error err = _get_path_and_type(p_path, pat);
if (err != OK) {
-
- if (r_error)
+ if (r_error) {
*r_error = err;
+ }
return RES();
}
- RES res = ResourceLoader::_load(pat.path, p_path, pat.type, false, r_error, p_use_sub_threads, r_progress);
+ RES res = ResourceLoader::_load(pat.path, p_path, pat.type, p_no_cache, r_error, p_use_sub_threads, r_progress);
#ifdef TOOLS_ENABLED
if (res.is_valid()) {
@@ -143,7 +140,6 @@ RES ResourceFormatImporter::load(const String &p_path, const String &p_original_
}
void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extensions) const {
-
Set<String> found;
for (int i = 0; i < importers.size(); i++) {
@@ -159,7 +155,6 @@ void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extension
}
void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
-
if (p_type == "") {
get_recognized_extensions(p_extensions);
return;
@@ -169,11 +164,13 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_
for (int i = 0; i < importers.size(); i++) {
String res_type = importers[i]->get_resource_type();
- if (res_type == String())
+ if (res_type == String()) {
continue;
+ }
- if (!ClassDB::is_parent_class(res_type, p_type))
+ if (!ClassDB::is_parent_class(res_type, p_type)) {
continue;
+ }
List<String> local_exts;
importers[i]->get_recognized_extensions(&local_exts);
@@ -187,26 +184,21 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String &p_
}
bool ResourceFormatImporter::exists(const String &p_path) const {
-
return FileAccess::exists(p_path + ".import");
}
bool ResourceFormatImporter::recognize_path(const String &p_path, const String &p_for_type) const {
-
return FileAccess::exists(p_path + ".import");
}
bool ResourceFormatImporter::can_be_imported(const String &p_path) const {
-
return ResourceFormatLoader::recognize_path(p_path);
}
int ResourceFormatImporter::get_import_order(const String &p_path) const {
-
Ref<ResourceImporter> importer;
if (FileAccess::exists(p_path + ".import")) {
-
PathAndType pat;
Error err = _get_path_and_type(p_path, pat);
@@ -214,37 +206,35 @@ int ResourceFormatImporter::get_import_order(const String &p_path) const {
importer = get_importer_by_name(pat.importer);
}
} else {
-
importer = get_importer_by_extension(p_path.get_extension().to_lower());
}
- if (importer.is_valid())
+ if (importer.is_valid()) {
return importer->get_import_order();
+ }
return 0;
}
bool ResourceFormatImporter::handles_type(const String &p_type) const {
-
for (int i = 0; i < importers.size(); i++) {
-
String res_type = importers[i]->get_resource_type();
- if (res_type == String())
+ if (res_type == String()) {
continue;
- if (ClassDB::is_parent_class(res_type, p_type))
+ }
+ if (ClassDB::is_parent_class(res_type, p_type)) {
return true;
+ }
}
return true;
}
String ResourceFormatImporter::get_internal_resource_path(const String &p_path) const {
-
PathAndType pat;
Error err = _get_path_and_type(p_path, pat);
if (err != OK) {
-
return String();
}
@@ -252,12 +242,12 @@ String ResourceFormatImporter::get_internal_resource_path(const String &p_path)
}
void ResourceFormatImporter::get_internal_resource_path_list(const String &p_path, List<String> *r_paths) {
-
Error err;
FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err);
- if (!f)
+ if (!f) {
return;
+ }
VariantParser::StreamFile stream;
stream.f = f;
@@ -269,7 +259,6 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat
int lines = 0;
String error_text;
while (true) {
-
assign = Variant();
next_tag.fields.clear();
next_tag.name = String();
@@ -298,7 +287,6 @@ 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);
@@ -306,7 +294,6 @@ String ResourceFormatImporter::get_import_group_file(const String &p_path) const
}
bool ResourceFormatImporter::is_import_valid(const String &p_path) const {
-
bool valid = true;
PathAndType pat;
_get_path_and_type(p_path, pat, &valid);
@@ -314,12 +301,10 @@ bool ResourceFormatImporter::is_import_valid(const String &p_path) const {
}
String ResourceFormatImporter::get_resource_type(const String &p_path) const {
-
PathAndType pat;
Error err = _get_path_and_type(p_path, pat);
if (err != OK) {
-
return "";
}
@@ -331,7 +316,6 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons
Error err = _get_path_and_type(p_path, pat);
if (err != OK) {
-
return Variant();
}
@@ -339,12 +323,10 @@ Variant ResourceFormatImporter::get_resource_metadata(const String &p_path) cons
}
void ResourceFormatImporter::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
-
PathAndType pat;
Error err = _get_path_and_type(p_path, pat);
if (err != OK) {
-
return;
}
@@ -352,7 +334,6 @@ void ResourceFormatImporter::get_dependencies(const String &p_path, List<String>
}
Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_name(const String &p_name) const {
-
for (int i = 0; i < importers.size(); i++) {
if (importers[i]->get_importer_name() == p_name) {
return importers[i];
@@ -363,7 +344,6 @@ Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_name(const String
}
void ResourceFormatImporter::get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter>> *r_importers) {
-
for (int i = 0; i < importers.size(); i++) {
List<String> local_exts;
importers[i]->get_recognized_extensions(&local_exts);
@@ -376,12 +356,10 @@ void ResourceFormatImporter::get_importers_for_extension(const String &p_extensi
}
Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const String &p_extension) const {
-
Ref<ResourceImporter> importer;
float priority = 0;
for (int i = 0; i < importers.size(); i++) {
-
List<String> local_exts;
importers[i]->get_recognized_extensions(&local_exts);
for (List<String>::Element *F = local_exts.front(); F; F = F->next()) {
@@ -396,12 +374,10 @@ Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const St
}
String ResourceFormatImporter::get_import_base_path(const String &p_for_file) const {
-
return "res://.import/" + p_for_file.get_file() + "-" + p_for_file.md5_text();
}
bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) const {
-
bool valid = true;
PathAndType pat;
_get_path_and_type(p_path, pat, &valid);
@@ -422,7 +398,6 @@ bool ResourceFormatImporter::are_import_settings_valid(const String &p_path) con
}
String ResourceFormatImporter::get_import_settings_hash() const {
-
Vector<Ref<ResourceImporter>> sorted_importers = importers;
sorted_importers.sort_custom<SortImporterByName>();
diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h
index dbac80599a..d31a9a0194 100644
--- a/core/io/resource_importer.h
+++ b/core/io/resource_importer.h
@@ -36,7 +36,6 @@
class ResourceImporter;
class ResourceFormatImporter : public ResourceFormatLoader {
-
struct PathAndType {
String path;
String type;
@@ -58,7 +57,7 @@ class ResourceFormatImporter : public ResourceFormatLoader {
public:
static ResourceFormatImporter *get_singleton() { return singleton; }
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual bool recognize_path(const String &p_path, const String &p_for_type = String()) const;
@@ -93,7 +92,6 @@ public:
};
class ResourceImporter : public Reference {
-
GDCLASS(ResourceImporter, Reference);
public:
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index 05a41013c2..f9d2c9067c 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -33,7 +33,6 @@
#include "core/io/resource_importer.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
-#include "core/path_remap.h"
#include "core/print_string.h"
#include "core/project_settings.h"
#include "core/translation.h"
@@ -50,7 +49,6 @@ Ref<ResourceFormatLoader> ResourceLoader::loader[ResourceLoader::MAX_LOADERS];
int ResourceLoader::loader_count = 0;
bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_for_type) const {
-
String extension = p_path.get_extension();
List<String> extensions;
@@ -61,16 +59,15 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_
}
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
-
- if (E->get().nocasecmp_to(extension) == 0)
+ if (E->get().nocasecmp_to(extension) == 0) {
return true;
+ }
}
return false;
}
bool ResourceFormatLoader::handles_type(const String &p_type) const {
-
if (get_script_instance() && get_script_instance()->has_method("handles_type")) {
// I guess custom loaders for custom resources should use "Resource"
return get_script_instance()->call("handles_type", p_type);
@@ -80,7 +77,6 @@ bool ResourceFormatLoader::handles_type(const String &p_type) const {
}
String ResourceFormatLoader::get_resource_type(const String &p_path) const {
-
if (get_script_instance() && get_script_instance()->has_method("get_resource_type")) {
return get_script_instance()->call("get_resource_type", p_path);
}
@@ -89,13 +85,12 @@ String ResourceFormatLoader::get_resource_type(const String &p_path) const {
}
void ResourceFormatLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
-
- if (p_type == "" || handles_type(p_type))
+ if (p_type == "" || handles_type(p_type)) {
get_recognized_extensions(p_extensions);
+ }
}
void ResourceLoader::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) {
-
for (int i = 0; i < loader_count; i++) {
loader[i]->get_recognized_extensions_for_type(p_type, p_extensions);
}
@@ -106,7 +101,6 @@ bool ResourceFormatLoader::exists(const String &p_path) const {
}
void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions) const {
-
if (get_script_instance() && get_script_instance()->has_method("get_recognized_extensions")) {
PackedStringArray exts = get_script_instance()->call("get_recognized_extensions");
@@ -119,20 +113,19 @@ void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions)
}
}
-RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
+RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (get_script_instance() && get_script_instance()->has_method("load")) {
Variant res = get_script_instance()->call("load", p_path, p_original_path, p_use_sub_threads);
if (res.get_type() == Variant::INT) {
-
- if (r_error)
+ if (r_error) {
*r_error = (Error)res.operator int64_t();
+ }
} else {
-
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return res;
}
@@ -143,7 +136,6 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa
}
void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
-
if (get_script_instance() && get_script_instance()->has_method("get_dependencies")) {
PackedStringArray deps = get_script_instance()->call("get_dependencies", p_path, p_add_types);
@@ -157,9 +149,7 @@ void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *
}
Error ResourceFormatLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
-
if (get_script_instance() && get_script_instance()->has_method("rename_dependencies")) {
-
Dictionary deps_dict;
for (Map<String, String>::Element *E = p_map.front(); E; E = E->next()) {
deps_dict[E->key()] = E->value();
@@ -173,7 +163,6 @@ Error ResourceFormatLoader::rename_dependencies(const String &p_path, const Map<
}
void ResourceFormatLoader::_bind_methods() {
-
{
MethodInfo info = MethodInfo(Variant::NIL, "load", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "original_path"));
info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
@@ -190,17 +179,15 @@ void ResourceFormatLoader::_bind_methods() {
///////////////////////////////////
RES ResourceLoader::_load(const String &p_path, const String &p_original_path, const String &p_type_hint, bool p_no_cache, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
bool found = false;
// Try all loaders and pick the first match for the type hint
for (int i = 0; i < loader_count; i++) {
-
if (!loader[i]->recognize_path(p_path, p_type_hint)) {
continue;
}
found = true;
- RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress);
+ RES res = loader[i]->load(p_path, p_original_path != String() ? p_original_path : p_path, r_error, p_use_sub_threads, r_progress, p_no_cache);
if (res.is_null()) {
continue;
}
@@ -219,7 +206,6 @@ RES ResourceLoader::_load(const String &p_path, const String &p_original_path, c
}
void ResourceLoader::_thread_load_function(void *p_userdata) {
-
ThreadLoadTask &load_task = *(ThreadLoadTask *)p_userdata;
load_task.loader_id = Thread::get_caller_id();
@@ -238,7 +224,6 @@ void ResourceLoader::_thread_load_function(void *p_userdata) {
load_task.status = THREAD_LOAD_LOADED;
}
if (load_task.semaphore) {
-
if (load_task.start_next && thread_waiting_count > 0) {
thread_waiting_count--;
//thread loading count remains constant, this ends but another one begins
@@ -259,8 +244,9 @@ void ResourceLoader::_thread_load_function(void *p_userdata) {
if (load_task.resource.is_valid()) {
load_task.resource->set_path(load_task.local_path);
- if (load_task.xl_remapped)
+ if (load_task.xl_remapped) {
load_task.resource->set_as_translation_remapped(true);
+ }
#ifdef TOOLS_ENABLED
@@ -279,13 +265,14 @@ void ResourceLoader::_thread_load_function(void *p_userdata) {
thread_load_mutex->unlock();
}
-Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, const String &p_source_resource) {
+Error ResourceLoader::load_threaded_request(const String &p_path, const String &p_type_hint, bool p_use_sub_threads, const String &p_source_resource) {
String local_path;
- if (p_path.is_rel_path())
+ if (p_path.is_rel_path()) {
local_path = "res://" + p_path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ }
thread_load_mutex->lock();
@@ -388,7 +375,6 @@ Error ResourceLoader::load_threaded_request(const String &p_path, const String &
}
float ResourceLoader::_dependency_get_progress(const String &p_path) {
-
if (thread_load_tasks.has(p_path)) {
ThreadLoadTask &load_task = thread_load_tasks[p_path];
int dep_count = load_task.sub_tasks.size();
@@ -411,12 +397,12 @@ float ResourceLoader::_dependency_get_progress(const String &p_path) {
}
ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const String &p_path, float *r_progress) {
-
String local_path;
- if (p_path.is_rel_path())
+ if (p_path.is_rel_path()) {
local_path = "res://" + p_path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ }
thread_load_mutex->lock();
if (!thread_load_tasks.has(local_path)) {
@@ -434,13 +420,14 @@ ResourceLoader::ThreadLoadStatus ResourceLoader::load_threaded_get_status(const
return status;
}
-RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) {
+RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) {
String local_path;
- if (p_path.is_rel_path())
+ if (p_path.is_rel_path()) {
local_path = "res://" + p_path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ }
thread_load_mutex->lock();
if (!thread_load_tasks.has(local_path)) {
@@ -517,18 +504,18 @@ RES ResourceLoader::load_threaded_get(const String &p_path, Error *r_error) {
}
RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p_no_cache, Error *r_error) {
-
- if (r_error)
+ if (r_error) {
*r_error = ERR_CANT_OPEN;
+ }
String local_path;
- if (p_path.is_rel_path())
+ if (p_path.is_rel_path()) {
local_path = "res://" + p_path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ }
if (!p_no_cache) {
-
thread_load_mutex->lock();
//Is it already being loaded? poll until done
@@ -593,7 +580,6 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
return load_threaded_get(p_path, r_error);
} else {
-
bool xl_remapped = false;
String path = _path_remap(local_path, &xl_remapped);
@@ -610,8 +596,9 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
return RES();
}
- if (xl_remapped)
+ if (xl_remapped) {
res->set_as_translation_remapped(true);
+ }
#ifdef TOOLS_ENABLED
@@ -628,15 +615,14 @@ RES ResourceLoader::load(const String &p_path, const String &p_type_hint, bool p
}
bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
-
String local_path;
- if (p_path.is_rel_path())
+ if (p_path.is_rel_path()) {
local_path = "res://" + p_path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ }
if (ResourceCache::has(local_path)) {
-
return true; // If cached, it probably exists
}
@@ -645,20 +631,19 @@ bool ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
// Try all loaders and pick the first match for the type hint
for (int i = 0; i < loader_count; i++) {
-
if (!loader[i]->recognize_path(path, p_type_hint)) {
continue;
}
- if (loader[i]->exists(path))
+ if (loader[i]->exists(path)) {
return true;
+ }
}
return false;
}
void ResourceLoader::add_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader, bool p_at_front) {
-
ERR_FAIL_COND(p_format_loader.is_null());
ERR_FAIL_COND(loader_count >= MAX_LOADERS);
@@ -674,14 +659,14 @@ void ResourceLoader::add_resource_format_loader(Ref<ResourceFormatLoader> p_form
}
void ResourceLoader::remove_resource_format_loader(Ref<ResourceFormatLoader> p_format_loader) {
-
ERR_FAIL_COND(p_format_loader.is_null());
// Find loader
int i = 0;
for (; i < loader_count; ++i) {
- if (loader[i] == p_format_loader)
+ if (loader[i] == p_format_loader) {
break;
+ }
}
ERR_FAIL_COND(i >= loader_count); // Not found
@@ -695,19 +680,19 @@ void ResourceLoader::remove_resource_format_loader(Ref<ResourceFormatLoader> p_f
}
int ResourceLoader::get_import_order(const String &p_path) {
-
String path = _path_remap(p_path);
String local_path;
- if (path.is_rel_path())
+ if (path.is_rel_path()) {
local_path = "res://" + path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(path);
+ }
for (int i = 0; i < loader_count; i++) {
-
- if (!loader[i]->recognize_path(local_path))
+ if (!loader[i]->recognize_path(local_path)) {
continue;
+ }
/*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue;
@@ -723,15 +708,16 @@ String ResourceLoader::get_import_group_file(const String &p_path) {
String path = _path_remap(p_path);
String local_path;
- if (path.is_rel_path())
+ if (path.is_rel_path()) {
local_path = "res://" + path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(path);
+ }
for (int i = 0; i < loader_count; i++) {
-
- if (!loader[i]->recognize_path(local_path))
+ if (!loader[i]->recognize_path(local_path)) {
continue;
+ }
/*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue;
@@ -744,19 +730,19 @@ String ResourceLoader::get_import_group_file(const String &p_path) {
}
bool ResourceLoader::is_import_valid(const String &p_path) {
-
String path = _path_remap(p_path);
String local_path;
- if (path.is_rel_path())
+ if (path.is_rel_path()) {
local_path = "res://" + path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(path);
+ }
for (int i = 0; i < loader_count; i++) {
-
- if (!loader[i]->recognize_path(local_path))
+ if (!loader[i]->recognize_path(local_path)) {
continue;
+ }
/*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue;
@@ -769,19 +755,19 @@ bool ResourceLoader::is_import_valid(const String &p_path) {
}
bool ResourceLoader::is_imported(const String &p_path) {
-
String path = _path_remap(p_path);
String local_path;
- if (path.is_rel_path())
+ if (path.is_rel_path()) {
local_path = "res://" + path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(path);
+ }
for (int i = 0; i < loader_count; i++) {
-
- if (!loader[i]->recognize_path(local_path))
+ if (!loader[i]->recognize_path(local_path)) {
continue;
+ }
/*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue;
@@ -794,19 +780,19 @@ bool ResourceLoader::is_imported(const String &p_path) {
}
void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
-
String path = _path_remap(p_path);
String local_path;
- if (path.is_rel_path())
+ if (path.is_rel_path()) {
local_path = "res://" + path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(path);
+ }
for (int i = 0; i < loader_count; i++) {
-
- if (!loader[i]->recognize_path(local_path))
+ if (!loader[i]->recognize_path(local_path)) {
continue;
+ }
/*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue;
@@ -817,19 +803,19 @@ void ResourceLoader::get_dependencies(const String &p_path, List<String> *p_depe
}
Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
-
String path = _path_remap(p_path);
String local_path;
- if (path.is_rel_path())
+ if (path.is_rel_path()) {
local_path = "res://" + path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(path);
+ }
for (int i = 0; i < loader_count; i++) {
-
- if (!loader[i]->recognize_path(local_path))
+ if (!loader[i]->recognize_path(local_path)) {
continue;
+ }
/*
if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
continue;
@@ -842,15 +828,14 @@ Error ResourceLoader::rename_dependencies(const String &p_path, const Map<String
}
String ResourceLoader::get_resource_type(const String &p_path) {
-
String local_path;
- if (p_path.is_rel_path())
+ if (p_path.is_rel_path()) {
local_path = "res://" + p_path;
- else
+ } else {
local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ }
for (int i = 0; i < loader_count; i++) {
-
String result = loader[i]->get_resource_type(local_path);
if (result != "") {
return result;
@@ -861,7 +846,6 @@ String ResourceLoader::get_resource_type(const String &p_path) {
}
String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_remapped) {
-
String new_path = p_path;
if (translation_remaps.has(p_path)) {
@@ -920,7 +904,6 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
FileAccess *f = FileAccess::open(p_path + ".remap", FileAccess::READ, &err);
if (f) {
-
VariantParser::StreamFile stream;
stream.f = f;
@@ -931,7 +914,6 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
int lines = 0;
String error_text;
while (true) {
-
assign = Variant();
next_tag.fields.clear();
next_tag.name = String();
@@ -960,9 +942,7 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem
}
String ResourceLoader::import_remap(const String &p_path) {
-
if (ResourceFormatImporter::get_singleton()->recognize_path(p_path)) {
-
return ResourceFormatImporter::get_singleton()->get_internal_resource_path(p_path);
}
@@ -974,7 +954,6 @@ String ResourceLoader::path_remap(const String &p_path) {
}
void ResourceLoader::reload_translation_remaps() {
-
if (ResourceCache::lock) {
ResourceCache::lock->read_lock();
}
@@ -999,15 +978,14 @@ void ResourceLoader::reload_translation_remaps() {
}
void ResourceLoader::load_translation_remaps() {
-
- if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps"))
+ if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
return;
+ }
Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
List<Variant> keys;
remaps.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
Array langs = remaps[E->get()];
Vector<String> lang_remaps;
lang_remaps.resize(langs.size());
@@ -1024,9 +1002,9 @@ void ResourceLoader::clear_translation_remaps() {
}
void ResourceLoader::load_path_remaps() {
-
- if (!ProjectSettings::get_singleton()->has_setting("path_remap/remapped_paths"))
+ if (!ProjectSettings::get_singleton()->has_setting("path_remap/remapped_paths")) {
return;
+ }
Vector<String> remaps = ProjectSettings::get_singleton()->get("path_remap/remapped_paths");
int rc = remaps.size();
@@ -1034,13 +1012,11 @@ void ResourceLoader::load_path_remaps() {
const String *r = remaps.ptr();
for (int i = 0; i < rc; i += 2) {
-
path_remaps[r[i]] = r[i + 1];
}
}
void ResourceLoader::clear_path_remaps() {
-
path_remaps.clear();
}
@@ -1060,9 +1036,9 @@ Ref<ResourceFormatLoader> ResourceLoader::_find_custom_resource_format_loader(St
}
bool ResourceLoader::add_custom_resource_format_loader(String script_path) {
-
- if (_find_custom_resource_format_loader(script_path).is_valid())
+ if (_find_custom_resource_format_loader(script_path).is_valid()) {
return false;
+ }
Ref<Resource> res = ResourceLoader::load(script_path);
ERR_FAIL_COND_V(res.is_null(), false);
@@ -1085,10 +1061,10 @@ bool ResourceLoader::add_custom_resource_format_loader(String script_path) {
}
void ResourceLoader::remove_custom_resource_format_loader(String script_path) {
-
Ref<ResourceFormatLoader> custom_loader = _find_custom_resource_format_loader(script_path);
- if (custom_loader.is_valid())
+ if (custom_loader.is_valid()) {
remove_resource_format_loader(custom_loader);
+ }
}
void ResourceLoader::add_custom_loaders() {
@@ -1100,7 +1076,6 @@ void ResourceLoader::add_custom_loaders() {
ScriptServer::get_global_class_list(&global_classes);
for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
-
StringName class_name = E->get();
StringName base_class = ScriptServer::get_global_class_native_base(class_name);
@@ -1112,7 +1087,6 @@ void ResourceLoader::add_custom_loaders() {
}
void ResourceLoader::remove_custom_loaders() {
-
Vector<Ref<ResourceFormatLoader>> custom_loaders;
for (int i = 0; i < loader_count; ++i) {
if (loader[i]->get_script_instance()) {
@@ -1135,7 +1109,6 @@ void ResourceLoader::initialize() {
}
void ResourceLoader::finalize() {
-
memdelete(thread_load_mutex);
memdelete(thread_load_semaphore);
}
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index be4adf9091..9322b5273a 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -36,14 +36,13 @@
#include "core/resource.h"
class ResourceFormatLoader : public Reference {
-
GDCLASS(ResourceFormatLoader, Reference);
protected:
static void _bind_methods();
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual bool exists(const String &p_path) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
@@ -67,7 +66,6 @@ typedef Error (*ResourceLoaderImport)(const String &p_path);
typedef void (*ResourceLoadedCallback)(RES p_resource, const String &p_path);
class ResourceLoader {
-
enum {
MAX_LOADERS = 64
};
@@ -160,7 +158,9 @@ public:
static bool get_timestamp_on_load() { return timestamp_on_load; }
static void notify_load_error(const String &p_err) {
- if (err_notify) err_notify(err_notify_ud, p_err);
+ if (err_notify) {
+ err_notify(err_notify_ud, p_err);
+ }
}
static void set_error_notify_func(void *p_ud, ResourceLoadErrorNotify p_err_notify) {
err_notify = p_err_notify;
@@ -168,7 +168,9 @@ public:
}
static void notify_dependency_error(const String &p_path, const String &p_dependency, const String &p_type) {
- if (dep_err_notify) dep_err_notify(dep_err_notify_ud, p_path, p_dependency, p_type);
+ if (dep_err_notify) {
+ dep_err_notify(dep_err_notify_ud, p_path, p_dependency, p_type);
+ }
}
static void set_dependency_error_notify_func(void *p_ud, DependencyErrorNotify p_err_notify) {
dep_err_notify = p_err_notify;
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 09128adb50..a8da215b61 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -41,7 +41,6 @@ bool ResourceSaver::timestamp_on_save = false;
ResourceSavedCallback ResourceSaver::save_callback = nullptr;
Error ResourceFormatSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
if (get_script_instance() && get_script_instance()->has_method("save")) {
return (Error)get_script_instance()->call("save", p_path, p_resource, p_flags).operator int64_t();
}
@@ -50,7 +49,6 @@ Error ResourceFormatSaver::save(const String &p_path, const RES &p_resource, uin
}
bool ResourceFormatSaver::recognize(const RES &p_resource) const {
-
if (get_script_instance() && get_script_instance()->has_method("recognize")) {
return get_script_instance()->call("recognize", p_resource);
}
@@ -59,7 +57,6 @@ bool ResourceFormatSaver::recognize(const RES &p_resource) const {
}
void ResourceFormatSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
-
if (get_script_instance() && get_script_instance()->has_method("get_recognized_extensions")) {
PackedStringArray exts = get_script_instance()->call("get_recognized_extensions", p_resource);
@@ -73,7 +70,6 @@ void ResourceFormatSaver::get_recognized_extensions(const RES &p_resource, List<
}
void ResourceFormatSaver::_bind_methods() {
-
{
PropertyInfo arg0 = PropertyInfo(Variant::STRING, "path");
PropertyInfo arg1 = PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource");
@@ -86,40 +82,40 @@ void ResourceFormatSaver::_bind_methods() {
}
Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
String extension = p_path.get_extension();
Error err = ERR_FILE_UNRECOGNIZED;
for (int i = 0; i < saver_count; i++) {
-
- if (!saver[i]->recognize(p_resource))
+ if (!saver[i]->recognize(p_resource)) {
continue;
+ }
List<String> extensions;
bool recognized = false;
saver[i]->get_recognized_extensions(p_resource, &extensions);
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
-
- if (E->get().nocasecmp_to(extension) == 0)
+ if (E->get().nocasecmp_to(extension) == 0) {
recognized = true;
+ }
}
- if (!recognized)
+ if (!recognized) {
continue;
+ }
String old_path = p_resource->get_path();
String local_path = ProjectSettings::get_singleton()->localize_path(p_path);
RES rwcopy = p_resource;
- if (p_flags & FLAG_CHANGE_PATH)
+ if (p_flags & FLAG_CHANGE_PATH) {
rwcopy->set_path(local_path);
+ }
err = saver[i]->save(p_path, p_resource, p_flags);
if (err == OK) {
-
#ifdef TOOLS_ENABLED
((Resource *)p_resource.ptr())->set_edited(false);
@@ -130,11 +126,13 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t
}
#endif
- if (p_flags & FLAG_CHANGE_PATH)
+ if (p_flags & FLAG_CHANGE_PATH) {
rwcopy->set_path(old_path);
+ }
- if (save_callback && p_path.begins_with("res://"))
+ if (save_callback && p_path.begins_with("res://")) {
save_callback(p_resource, p_path);
+ }
return OK;
}
@@ -144,20 +142,16 @@ Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t
}
void ResourceSaver::set_save_callback(ResourceSavedCallback p_callback) {
-
save_callback = p_callback;
}
void ResourceSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) {
-
for (int i = 0; i < saver_count; i++) {
-
saver[i]->get_recognized_extensions(p_resource, p_extensions);
}
}
void ResourceSaver::add_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver, bool p_at_front) {
-
ERR_FAIL_COND_MSG(p_format_saver.is_null(), "It's not a reference to a valid ResourceFormatSaver object.");
ERR_FAIL_COND(saver_count >= MAX_SAVERS);
@@ -173,14 +167,14 @@ void ResourceSaver::add_resource_format_saver(Ref<ResourceFormatSaver> p_format_
}
void ResourceSaver::remove_resource_format_saver(Ref<ResourceFormatSaver> p_format_saver) {
-
ERR_FAIL_COND_MSG(p_format_saver.is_null(), "It's not a reference to a valid ResourceFormatSaver object.");
// Find saver
int i = 0;
for (; i < saver_count; ++i) {
- if (saver[i] == p_format_saver)
+ if (saver[i] == p_format_saver) {
break;
+ }
}
ERR_FAIL_COND(i >= saver_count); // Not found
@@ -203,9 +197,9 @@ Ref<ResourceFormatSaver> ResourceSaver::_find_custom_resource_format_saver(Strin
}
bool ResourceSaver::add_custom_resource_format_saver(String script_path) {
-
- if (_find_custom_resource_format_saver(script_path).is_valid())
+ if (_find_custom_resource_format_saver(script_path).is_valid()) {
return false;
+ }
Ref<Resource> res = ResourceLoader::load(script_path);
ERR_FAIL_COND_V(res.is_null(), false);
@@ -228,10 +222,10 @@ bool ResourceSaver::add_custom_resource_format_saver(String script_path) {
}
void ResourceSaver::remove_custom_resource_format_saver(String script_path) {
-
Ref<ResourceFormatSaver> custom_saver = _find_custom_resource_format_saver(script_path);
- if (custom_saver.is_valid())
+ if (custom_saver.is_valid()) {
remove_resource_format_saver(custom_saver);
+ }
}
void ResourceSaver::add_custom_savers() {
@@ -243,7 +237,6 @@ void ResourceSaver::add_custom_savers() {
ScriptServer::get_global_class_list(&global_classes);
for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
-
StringName class_name = E->get();
StringName base_class = ScriptServer::get_global_class_native_base(class_name);
@@ -255,7 +248,6 @@ void ResourceSaver::add_custom_savers() {
}
void ResourceSaver::remove_custom_savers() {
-
Vector<Ref<ResourceFormatSaver>> custom_savers;
for (int i = 0; i < saver_count; ++i) {
if (saver[i]->get_script_instance()) {
diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h
index 2ddebf0581..8b4cdd86f8 100644
--- a/core/io/resource_saver.h
+++ b/core/io/resource_saver.h
@@ -50,7 +50,6 @@ public:
typedef void (*ResourceSavedCallback)(Ref<Resource> p_resource, const String &p_path);
class ResourceSaver {
-
enum {
MAX_SAVERS = 64
};
diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp
index b28b17aa95..403f61bb24 100644
--- a/core/io/stream_peer.cpp
+++ b/core/io/stream_peer.cpp
@@ -33,16 +33,15 @@
#include "core/io/marshalls.h"
Error StreamPeer::_put_data(const Vector<uint8_t> &p_data) {
-
int len = p_data.size();
- if (len == 0)
+ if (len == 0) {
return OK;
+ }
const uint8_t *r = p_data.ptr();
return put_data(&r[0], len);
}
Array StreamPeer::_put_partial_data(const Vector<uint8_t> &p_data) {
-
Array ret;
int len = p_data.size();
@@ -65,13 +64,11 @@ Array StreamPeer::_put_partial_data(const Vector<uint8_t> &p_data) {
}
Array StreamPeer::_get_data(int p_bytes) {
-
Array ret;
Vector<uint8_t> data;
data.resize(p_bytes);
if (data.size() != p_bytes) {
-
ret.push_back(ERR_OUT_OF_MEMORY);
ret.push_back(Vector<uint8_t>());
return ret;
@@ -86,13 +83,11 @@ Array StreamPeer::_get_data(int p_bytes) {
}
Array StreamPeer::_get_partial_data(int p_bytes) {
-
Array ret;
Vector<uint8_t> data;
data.resize(p_bytes);
if (data.size() != p_bytes) {
-
ret.push_back(ERR_OUT_OF_MEMORY);
ret.push_back(Vector<uint8_t>());
return ret;
@@ -105,7 +100,6 @@ Array StreamPeer::_get_partial_data(int p_bytes) {
if (err != OK) {
data.resize(0);
} else if (received != data.size()) {
-
data.resize(received);
}
@@ -115,12 +109,10 @@ Array StreamPeer::_get_partial_data(int p_bytes) {
}
void StreamPeer::set_big_endian(bool p_enable) {
-
big_endian = p_enable;
}
bool StreamPeer::is_big_endian_enabled() const {
-
return big_endian;
}
@@ -129,11 +121,10 @@ void StreamPeer::put_u8(uint8_t p_val) {
}
void StreamPeer::put_8(int8_t p_val) {
-
put_data((const uint8_t *)&p_val, 1);
}
-void StreamPeer::put_u16(uint16_t p_val) {
+void StreamPeer::put_u16(uint16_t p_val) {
if (big_endian) {
p_val = BSWAP16(p_val);
}
@@ -141,8 +132,8 @@ void StreamPeer::put_u16(uint16_t p_val) {
encode_uint16(p_val, buf);
put_data(buf, 2);
}
-void StreamPeer::put_16(int16_t p_val) {
+void StreamPeer::put_16(int16_t p_val) {
if (big_endian) {
p_val = BSWAP16(p_val);
}
@@ -150,8 +141,8 @@ void StreamPeer::put_16(int16_t p_val) {
encode_uint16(p_val, buf);
put_data(buf, 2);
}
-void StreamPeer::put_u32(uint32_t p_val) {
+void StreamPeer::put_u32(uint32_t p_val) {
if (big_endian) {
p_val = BSWAP32(p_val);
}
@@ -159,8 +150,8 @@ void StreamPeer::put_u32(uint32_t p_val) {
encode_uint32(p_val, buf);
put_data(buf, 4);
}
-void StreamPeer::put_32(int32_t p_val) {
+void StreamPeer::put_32(int32_t p_val) {
if (big_endian) {
p_val = BSWAP32(p_val);
}
@@ -168,8 +159,8 @@ void StreamPeer::put_32(int32_t p_val) {
encode_uint32(p_val, buf);
put_data(buf, 4);
}
-void StreamPeer::put_u64(uint64_t p_val) {
+void StreamPeer::put_u64(uint64_t p_val) {
if (big_endian) {
p_val = BSWAP64(p_val);
}
@@ -177,8 +168,8 @@ void StreamPeer::put_u64(uint64_t p_val) {
encode_uint64(p_val, buf);
put_data(buf, 8);
}
-void StreamPeer::put_64(int64_t p_val) {
+void StreamPeer::put_64(int64_t p_val) {
if (big_endian) {
p_val = BSWAP64(p_val);
}
@@ -186,8 +177,8 @@ void StreamPeer::put_64(int64_t p_val) {
encode_uint64(p_val, buf);
put_data(buf, 8);
}
-void StreamPeer::put_float(float p_val) {
+void StreamPeer::put_float(float p_val) {
uint8_t buf[4];
encode_float(p_val, buf);
@@ -198,8 +189,8 @@ void StreamPeer::put_float(float p_val) {
put_data(buf, 4);
}
-void StreamPeer::put_double(double p_val) {
+void StreamPeer::put_double(double p_val) {
uint8_t buf[8];
encode_double(p_val, buf);
if (big_endian) {
@@ -208,20 +199,20 @@ void StreamPeer::put_double(double p_val) {
}
put_data(buf, 8);
}
-void StreamPeer::put_string(const String &p_string) {
+void StreamPeer::put_string(const String &p_string) {
CharString cs = p_string.ascii();
put_u32(cs.length());
put_data((const uint8_t *)cs.get_data(), cs.length());
}
-void StreamPeer::put_utf8_string(const String &p_string) {
+void StreamPeer::put_utf8_string(const String &p_string) {
CharString cs = p_string.utf8();
put_u32(cs.length());
put_data((const uint8_t *)cs.get_data(), cs.length());
}
-void StreamPeer::put_var(const Variant &p_variant, bool p_full_objects) {
+void StreamPeer::put_var(const Variant &p_variant, bool p_full_objects) {
int len = 0;
Vector<uint8_t> buf;
encode_variant(p_variant, nullptr, len, p_full_objects);
@@ -232,19 +223,18 @@ void StreamPeer::put_var(const Variant &p_variant, bool p_full_objects) {
}
uint8_t StreamPeer::get_u8() {
-
uint8_t buf[1];
get_data(buf, 1);
return buf[0];
}
-int8_t StreamPeer::get_8() {
+int8_t StreamPeer::get_8() {
uint8_t buf[1];
get_data(buf, 1);
return buf[0];
}
-uint16_t StreamPeer::get_u16() {
+uint16_t StreamPeer::get_u16() {
uint8_t buf[2];
get_data(buf, 2);
uint16_t r = decode_uint16(buf);
@@ -253,8 +243,8 @@ uint16_t StreamPeer::get_u16() {
}
return r;
}
-int16_t StreamPeer::get_16() {
+int16_t StreamPeer::get_16() {
uint8_t buf[2];
get_data(buf, 2);
uint16_t r = decode_uint16(buf);
@@ -263,8 +253,8 @@ int16_t StreamPeer::get_16() {
}
return r;
}
-uint32_t StreamPeer::get_u32() {
+uint32_t StreamPeer::get_u32() {
uint8_t buf[4];
get_data(buf, 4);
uint32_t r = decode_uint32(buf);
@@ -273,8 +263,8 @@ uint32_t StreamPeer::get_u32() {
}
return r;
}
-int32_t StreamPeer::get_32() {
+int32_t StreamPeer::get_32() {
uint8_t buf[4];
get_data(buf, 4);
uint32_t r = decode_uint32(buf);
@@ -283,8 +273,8 @@ int32_t StreamPeer::get_32() {
}
return r;
}
-uint64_t StreamPeer::get_u64() {
+uint64_t StreamPeer::get_u64() {
uint8_t buf[8];
get_data(buf, 8);
uint64_t r = decode_uint64(buf);
@@ -293,8 +283,8 @@ uint64_t StreamPeer::get_u64() {
}
return r;
}
-int64_t StreamPeer::get_64() {
+int64_t StreamPeer::get_64() {
uint8_t buf[8];
get_data(buf, 8);
uint64_t r = decode_uint64(buf);
@@ -303,8 +293,8 @@ int64_t StreamPeer::get_64() {
}
return r;
}
-float StreamPeer::get_float() {
+float StreamPeer::get_float() {
uint8_t buf[4];
get_data(buf, 4);
@@ -317,7 +307,6 @@ float StreamPeer::get_float() {
}
double StreamPeer::get_double() {
-
uint8_t buf[8];
get_data(buf, 8);
@@ -328,10 +317,11 @@ double StreamPeer::get_double() {
return decode_double(buf);
}
-String StreamPeer::get_string(int p_bytes) {
- if (p_bytes < 0)
+String StreamPeer::get_string(int p_bytes) {
+ if (p_bytes < 0) {
p_bytes = get_u32();
+ }
ERR_FAIL_COND_V(p_bytes < 0, String());
Vector<char> buf;
@@ -342,10 +332,11 @@ String StreamPeer::get_string(int p_bytes) {
buf.write[p_bytes] = 0;
return buf.ptr();
}
-String StreamPeer::get_utf8_string(int p_bytes) {
- if (p_bytes < 0)
+String StreamPeer::get_utf8_string(int p_bytes) {
+ if (p_bytes < 0) {
p_bytes = get_u32();
+ }
ERR_FAIL_COND_V(p_bytes < 0, String());
Vector<uint8_t> buf;
@@ -358,8 +349,8 @@ String StreamPeer::get_utf8_string(int p_bytes) {
ret.parse_utf8((const char *)buf.ptr(), buf.size());
return ret;
}
-Variant StreamPeer::get_var(bool p_allow_objects) {
+Variant StreamPeer::get_var(bool p_allow_objects) {
int len = get_32();
Vector<uint8_t> var;
Error err = var.resize(len);
@@ -375,7 +366,6 @@ Variant StreamPeer::get_var(bool p_allow_objects) {
}
void StreamPeer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("put_data", "data"), &StreamPeer::_put_data);
ClassDB::bind_method(D_METHOD("put_partial_data", "data"), &StreamPeer::_put_partial_data);
@@ -417,10 +407,10 @@ void StreamPeer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "big_endian"), "set_big_endian", "is_big_endian_enabled");
}
+
////////////////////////////////
void StreamPeerBuffer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("seek", "position"), &StreamPeerBuffer::seek);
ClassDB::bind_method(D_METHOD("get_size"), &StreamPeerBuffer::get_size);
ClassDB::bind_method(D_METHOD("get_position"), &StreamPeerBuffer::get_position);
@@ -434,9 +424,9 @@ void StreamPeerBuffer::_bind_methods() {
}
Error StreamPeerBuffer::put_data(const uint8_t *p_data, int p_bytes) {
-
- if (p_bytes <= 0)
+ if (p_bytes <= 0) {
return OK;
+ }
if (pointer + p_bytes > data.size()) {
data.resize(pointer + p_bytes);
@@ -450,23 +440,21 @@ Error StreamPeerBuffer::put_data(const uint8_t *p_data, int p_bytes) {
}
Error StreamPeerBuffer::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) {
-
r_sent = p_bytes;
return put_data(p_data, p_bytes);
}
Error StreamPeerBuffer::get_data(uint8_t *p_buffer, int p_bytes) {
-
int recv;
get_partial_data(p_buffer, p_bytes, recv);
- if (recv != p_bytes)
+ if (recv != p_bytes) {
return ERR_INVALID_PARAMETER;
+ }
return OK;
}
Error StreamPeerBuffer::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) {
-
if (pointer + p_bytes > data.size()) {
r_received = data.size() - pointer;
if (r_received <= 0) {
@@ -487,57 +475,44 @@ Error StreamPeerBuffer::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_
}
int StreamPeerBuffer::get_available_bytes() const {
-
return data.size() - pointer;
}
void StreamPeerBuffer::seek(int p_pos) {
-
ERR_FAIL_COND(p_pos < 0);
ERR_FAIL_COND(p_pos > data.size());
pointer = p_pos;
}
-int StreamPeerBuffer::get_size() const {
+int StreamPeerBuffer::get_size() const {
return data.size();
}
int StreamPeerBuffer::get_position() const {
-
return pointer;
}
void StreamPeerBuffer::resize(int p_size) {
-
data.resize(p_size);
}
void StreamPeerBuffer::set_data_array(const Vector<uint8_t> &p_data) {
-
data = p_data;
pointer = 0;
}
Vector<uint8_t> StreamPeerBuffer::get_data_array() const {
-
return data;
}
void StreamPeerBuffer::clear() {
-
data.resize(0);
pointer = 0;
}
Ref<StreamPeerBuffer> StreamPeerBuffer::duplicate() const {
-
Ref<StreamPeerBuffer> spb;
spb.instance();
spb->data = data;
return spb;
}
-
-StreamPeerBuffer::StreamPeerBuffer() {
-
- pointer = 0;
-}
diff --git a/core/io/stream_peer.h b/core/io/stream_peer.h
index 9358a2c07c..ec0b989ed8 100644
--- a/core/io/stream_peer.h
+++ b/core/io/stream_peer.h
@@ -47,7 +47,7 @@ protected:
Array _get_data(int p_bytes);
Array _get_partial_data(int p_bytes);
- bool big_endian;
+ bool big_endian = false;
public:
virtual Error put_data(const uint8_t *p_data, int p_bytes) = 0; ///< put a whole chunk of data, blocking until it sent
@@ -89,15 +89,14 @@ public:
String get_utf8_string(int p_bytes = -1);
Variant get_var(bool p_allow_objects = false);
- StreamPeer() { big_endian = false; }
+ StreamPeer() {}
};
class StreamPeerBuffer : public StreamPeer {
-
GDCLASS(StreamPeerBuffer, StreamPeer);
Vector<uint8_t> data;
- int pointer;
+ int pointer = 0;
protected:
static void _bind_methods();
@@ -123,7 +122,7 @@ public:
Ref<StreamPeerBuffer> duplicate() const;
- StreamPeerBuffer();
+ StreamPeerBuffer() {}
};
#endif // STREAM_PEER_H
diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp
index d98935f77c..3dc31c6769 100644
--- a/core/io/stream_peer_ssl.cpp
+++ b/core/io/stream_peer_ssl.cpp
@@ -35,9 +35,9 @@
StreamPeerSSL *(*StreamPeerSSL::_create)() = nullptr;
StreamPeerSSL *StreamPeerSSL::create() {
-
- if (_create)
+ if (_create) {
return _create();
+ }
return nullptr;
}
@@ -56,7 +56,6 @@ bool StreamPeerSSL::is_blocking_handshake_enabled() const {
}
void StreamPeerSSL::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("poll"), &StreamPeerSSL::poll);
ClassDB::bind_method(D_METHOD("accept_stream", "stream", "private_key", "certificate", "chain"), &StreamPeerSSL::accept_stream, DEFVAL(Ref<X509Certificate>()));
ClassDB::bind_method(D_METHOD("connect_to_stream", "stream", "validate_certs", "for_hostname", "valid_certificate"), &StreamPeerSSL::connect_to_stream, DEFVAL(false), DEFVAL(String()), DEFVAL(Ref<X509Certificate>()));
@@ -73,7 +72,3 @@ void StreamPeerSSL::_bind_methods() {
BIND_ENUM_CONSTANT(STATUS_ERROR);
BIND_ENUM_CONSTANT(STATUS_ERROR_HOSTNAME_MISMATCH);
}
-
-StreamPeerSSL::StreamPeerSSL() {
- blocking_handshake = true;
-}
diff --git a/core/io/stream_peer_ssl.h b/core/io/stream_peer_ssl.h
index de3cb09c60..81b95b856d 100644
--- a/core/io/stream_peer_ssl.h
+++ b/core/io/stream_peer_ssl.h
@@ -43,7 +43,7 @@ protected:
static bool available;
- bool blocking_handshake;
+ bool blocking_handshake = true;
public:
enum Status {
@@ -68,7 +68,7 @@ public:
static bool is_available();
- StreamPeerSSL();
+ StreamPeerSSL() {}
};
VARIANT_ENUM_CAST(StreamPeerSSL::Status);
diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp
index f0c5816d73..cce728c30a 100644
--- a/core/io/stream_peer_tcp.cpp
+++ b/core/io/stream_peer_tcp.cpp
@@ -33,7 +33,6 @@
#include "core/project_settings.h"
Error StreamPeerTCP::_poll_connection() {
-
ERR_FAIL_COND_V(status != STATUS_CONNECTING || !_sock.is_valid() || !_sock->is_open(), FAILED);
Error err = _sock->connect_to_host(peer_host, peer_port);
@@ -58,7 +57,6 @@ Error StreamPeerTCP::_poll_connection() {
}
void StreamPeerTCP::accept_socket(Ref<NetSocket> p_sock, IP_Address p_host, uint16_t p_port) {
-
_sock = p_sock;
_sock->set_blocking_enabled(false);
@@ -70,7 +68,6 @@ void StreamPeerTCP::accept_socket(Ref<NetSocket> p_sock, IP_Address p_host, uint
}
Error StreamPeerTCP::connect_to_host(const IP_Address &p_host, uint16_t p_port) {
-
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE);
ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER);
@@ -103,18 +100,14 @@ Error StreamPeerTCP::connect_to_host(const IP_Address &p_host, uint16_t p_port)
}
Error StreamPeerTCP::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool p_block) {
-
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
if (status == STATUS_NONE || status == STATUS_ERROR) {
-
return FAILED;
}
if (status != STATUS_CONNECTED) {
-
if (_poll_connection() != OK) {
-
return FAILED;
}
@@ -124,8 +117,9 @@ Error StreamPeerTCP::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool
}
}
- if (!_sock->is_open())
+ if (!_sock->is_open()) {
return FAILED;
+ }
Error err;
int data_to_send = p_bytes;
@@ -133,12 +127,10 @@ Error StreamPeerTCP::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool
int total_sent = 0;
while (data_to_send) {
-
int sent_amount = 0;
err = _sock->send(offset, data_to_send, sent_amount);
if (err != OK) {
-
if (err != ERR_BUSY) {
disconnect_from_host();
return FAILED;
@@ -156,7 +148,6 @@ Error StreamPeerTCP::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool
return FAILED;
}
} else {
-
data_to_send -= sent_amount;
offset += sent_amount;
total_sent += sent_amount;
@@ -169,16 +160,12 @@ Error StreamPeerTCP::write(const uint8_t *p_data, int p_bytes, int &r_sent, bool
}
Error StreamPeerTCP::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool p_block) {
-
if (!is_connected_to_host()) {
-
return FAILED;
}
if (status == STATUS_CONNECTING) {
-
if (_poll_connection() != OK) {
-
return FAILED;
}
@@ -194,12 +181,10 @@ Error StreamPeerTCP::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool
r_received = 0;
while (to_read) {
-
int read = 0;
err = _sock->recv(p_buffer + total_read, to_read, read);
if (err != OK) {
-
if (err != ERR_BUSY) {
disconnect_from_host();
return FAILED;
@@ -218,13 +203,11 @@ Error StreamPeerTCP::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool
}
} else if (read == 0) {
-
disconnect_from_host();
r_received = total_read;
return ERR_FILE_EOF;
} else {
-
to_read -= read;
total_read += read;
@@ -241,18 +224,15 @@ Error StreamPeerTCP::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool
}
void StreamPeerTCP::set_no_delay(bool p_enabled) {
-
ERR_FAIL_COND(!is_connected_to_host());
_sock->set_tcp_no_delay_enabled(p_enabled);
}
bool StreamPeerTCP::is_connected_to_host() const {
-
return _sock.is_valid() && _sock->is_open() && (status == STATUS_CONNECTED || status == STATUS_CONNECTING);
}
StreamPeerTCP::Status StreamPeerTCP::get_status() {
-
if (status == STATUS_CONNECTING) {
_poll_connection();
} else if (status == STATUS_CONNECTED) {
@@ -278,9 +258,9 @@ StreamPeerTCP::Status StreamPeerTCP::get_status() {
}
void StreamPeerTCP::disconnect_from_host() {
-
- if (_sock.is_valid() && _sock->is_open())
+ if (_sock.is_valid() && _sock->is_open()) {
_sock->close();
+ }
timeout = 0;
status = STATUS_NONE;
@@ -294,59 +274,51 @@ Error StreamPeerTCP::poll(NetSocket::PollType p_type, int timeout) {
}
Error StreamPeerTCP::put_data(const uint8_t *p_data, int p_bytes) {
-
int total;
return write(p_data, p_bytes, total, true);
}
Error StreamPeerTCP::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) {
-
return write(p_data, p_bytes, r_sent, false);
}
Error StreamPeerTCP::get_data(uint8_t *p_buffer, int p_bytes) {
-
int total;
return read(p_buffer, p_bytes, total, true);
}
Error StreamPeerTCP::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) {
-
return read(p_buffer, p_bytes, r_received, false);
}
int StreamPeerTCP::get_available_bytes() const {
-
ERR_FAIL_COND_V(!_sock.is_valid(), -1);
return _sock->get_available_bytes();
}
IP_Address StreamPeerTCP::get_connected_host() const {
-
return peer_host;
}
uint16_t StreamPeerTCP::get_connected_port() const {
-
return peer_port;
}
Error StreamPeerTCP::_connect(const String &p_address, int p_port) {
-
IP_Address ip;
if (p_address.is_valid_ip_address()) {
ip = p_address;
} else {
ip = IP::get_singleton()->resolve_hostname(p_address);
- if (!ip.is_valid())
+ if (!ip.is_valid()) {
return ERR_CANT_RESOLVE;
+ }
}
return connect_to_host(ip, p_port);
}
void StreamPeerTCP::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("connect_to_host", "host", "port"), &StreamPeerTCP::_connect);
ClassDB::bind_method(D_METHOD("is_connected_to_host"), &StreamPeerTCP::is_connected_to_host);
ClassDB::bind_method(D_METHOD("get_status"), &StreamPeerTCP::get_status);
@@ -362,13 +334,9 @@ void StreamPeerTCP::_bind_methods() {
}
StreamPeerTCP::StreamPeerTCP() :
- _sock(Ref<NetSocket>(NetSocket::create())),
- timeout(0),
- status(STATUS_NONE),
- peer_port(0) {
+ _sock(Ref<NetSocket>(NetSocket::create())) {
}
StreamPeerTCP::~StreamPeerTCP() {
-
disconnect_from_host();
}
diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h
index 86df9ab8cf..ab98d494d6 100644
--- a/core/io/stream_peer_tcp.h
+++ b/core/io/stream_peer_tcp.h
@@ -37,7 +37,6 @@
#include "core/io/stream_peer.h"
class StreamPeerTCP : public StreamPeer {
-
GDCLASS(StreamPeerTCP, StreamPeer);
OBJ_CATEGORY("Networking");
@@ -52,10 +51,10 @@ public:
protected:
Ref<NetSocket> _sock;
- uint64_t timeout;
- Status status;
+ uint64_t timeout = 0;
+ Status status = STATUS_NONE;
IP_Address peer_host;
- uint16_t peer_port;
+ uint16_t peer_port = 0;
Error _connect(const String &p_address, int p_port);
Error _poll_connection();
diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp
index 69c2ba7943..d7061b6bf4 100644
--- a/core/io/tcp_server.cpp
+++ b/core/io/tcp_server.cpp
@@ -31,7 +31,6 @@
#include "tcp_server.h"
void TCP_Server::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &TCP_Server::listen, DEFVAL("*"));
ClassDB::bind_method(D_METHOD("is_connection_available"), &TCP_Server::is_connection_available);
ClassDB::bind_method(D_METHOD("is_listening"), &TCP_Server::is_listening);
@@ -40,7 +39,6 @@ void TCP_Server::_bind_methods() {
}
Error TCP_Server::listen(uint16_t p_port, const IP_Address &p_bind_address) {
-
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE);
ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);
@@ -49,8 +47,9 @@ Error TCP_Server::listen(uint16_t p_port, const IP_Address &p_bind_address) {
IP::Type ip_type = IP::TYPE_ANY;
// If the bind address is valid use its type as the socket type
- if (p_bind_address.is_valid())
+ if (p_bind_address.is_valid()) {
ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+ }
err = _sock->open(NetSocket::TYPE_TCP, ip_type);
@@ -62,7 +61,6 @@ Error TCP_Server::listen(uint16_t p_port, const IP_Address &p_bind_address) {
err = _sock->bind(p_bind_address, p_port);
if (err != OK) {
-
_sock->close();
return ERR_ALREADY_IN_USE;
}
@@ -83,18 +81,17 @@ bool TCP_Server::is_listening() const {
}
bool TCP_Server::is_connection_available() const {
-
ERR_FAIL_COND_V(!_sock.is_valid(), false);
- if (!_sock->is_open())
+ if (!_sock->is_open()) {
return false;
+ }
Error err = _sock->poll(NetSocket::POLL_TYPE_IN, 0);
return (err == OK);
}
Ref<StreamPeerTCP> TCP_Server::take_connection() {
-
Ref<StreamPeerTCP> conn;
if (!is_connection_available()) {
return conn;
@@ -104,8 +101,9 @@ Ref<StreamPeerTCP> TCP_Server::take_connection() {
IP_Address ip;
uint16_t port = 0;
ns = _sock->accept(ip, port);
- if (!ns.is_valid())
+ if (!ns.is_valid()) {
return conn;
+ }
conn = Ref<StreamPeerTCP>(memnew(StreamPeerTCP));
conn->accept_socket(ns, ip, port);
@@ -113,7 +111,6 @@ Ref<StreamPeerTCP> TCP_Server::take_connection() {
}
void TCP_Server::stop() {
-
if (_sock.is_valid()) {
_sock->close();
}
@@ -124,6 +121,5 @@ TCP_Server::TCP_Server() :
}
TCP_Server::~TCP_Server() {
-
stop();
}
diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h
index ca52b13ba1..eb715a745c 100644
--- a/core/io/tcp_server.h
+++ b/core/io/tcp_server.h
@@ -37,7 +37,6 @@
#include "core/io/stream_peer_tcp.h"
class TCP_Server : public Reference {
-
GDCLASS(TCP_Server, Reference);
protected:
diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp
index 5da236d029..0e0a948953 100644
--- a/core/io/translation_loader_po.cpp
+++ b/core/io/translation_loader_po.cpp
@@ -34,7 +34,6 @@
#include "core/translation.h"
RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
-
enum Status {
STATUS_NONE,
@@ -48,8 +47,9 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
String msg_str;
String config;
- if (r_error)
+ if (r_error) {
*r_error = ERR_FILE_CORRUPT;
+ }
Ref<Translation> translation = Ref<Translation>(memnew(Translation));
int line = 1;
@@ -58,13 +58,11 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
bool is_eof = false;
while (!is_eof) {
-
String l = f->get_line().strip_edges();
is_eof = f->eof_reached();
// If we reached last line and it's not a content line, break, otherwise let processing that last loop
if (is_eof && l.empty()) {
-
if (status == STATUS_READING_ID) {
memdelete(f);
ERR_FAIL_V_MSG(RES(), f->get_path() + ":" + itos(line) + " Unexpected EOF while reading 'msgid' at file: ");
@@ -74,18 +72,18 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
}
if (l.begins_with("msgid")) {
-
if (status == STATUS_READING_ID) {
-
memdelete(f);
ERR_FAIL_V_MSG(RES(), f->get_path() + ":" + itos(line) + " Unexpected 'msgid', was expecting 'msgstr' while parsing: ");
}
if (msg_id != "") {
- if (!skip_this)
+ if (!skip_this) {
translation->add_message(msg_id, msg_str);
- } else if (config == "")
+ }
+ } else if (config == "") {
config = msg_str;
+ }
l = l.substr(5, l.length()).strip_edges();
status = STATUS_READING_ID;
@@ -96,9 +94,7 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
}
if (l.begins_with("msgstr")) {
-
if (status != STATUS_READING_ID) {
-
memdelete(f);
ERR_FAIL_V_MSG(RES(), f->get_path() + ":" + itos(line) + " Unexpected 'msgstr', was expecting 'msgid' while parsing: ");
}
@@ -142,10 +138,11 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
l = l.substr(0, end_pos);
l = l.c_unescape();
- if (status == STATUS_READING_ID)
+ if (status == STATUS_READING_ID) {
msg_id += l;
- else
+ } else {
msg_str += l;
+ }
line++;
}
@@ -154,23 +151,24 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
memdelete(f);
if (status == STATUS_READING_STRING) {
-
if (msg_id != "") {
- if (!skip_this)
+ if (!skip_this) {
translation->add_message(msg_id, msg_str);
- } else if (config == "")
+ }
+ } else if (config == "") {
config = msg_str;
+ }
}
ERR_FAIL_COND_V_MSG(config == "", RES(), "No config found in file: " + f->get_path() + ".");
Vector<String> configs = config.split("\n");
for (int i = 0; i < configs.size(); i++) {
-
String c = configs[i].strip_edges();
int p = c.find(":");
- if (p == -1)
+ if (p == -1) {
continue;
+ }
String prop = c.substr(0, p).strip_edges();
String value = c.substr(p + 1, c.length()).strip_edges();
@@ -179,16 +177,17 @@ RES TranslationLoaderPO::load_translation(FileAccess *f, Error *r_error) {
}
}
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return translation;
}
-RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
- if (r_error)
+RES TranslationLoaderPO::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_CANT_OPEN;
+ }
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot open file '" + p_path + "'.");
@@ -197,21 +196,17 @@ RES TranslationLoaderPO::load(const String &p_path, const String &p_original_pat
}
void TranslationLoaderPO::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("po");
//p_extensions->push_back("mo"); //mo in the future...
}
-bool TranslationLoaderPO::handles_type(const String &p_type) const {
+bool TranslationLoaderPO::handles_type(const String &p_type) const {
return (p_type == "Translation");
}
String TranslationLoaderPO::get_resource_type(const String &p_path) const {
-
- if (p_path.get_extension().to_lower() == "po")
+ if (p_path.get_extension().to_lower() == "po") {
return "Translation";
+ }
return "";
}
-
-TranslationLoaderPO::TranslationLoaderPO() {
-}
diff --git a/core/io/translation_loader_po.h b/core/io/translation_loader_po.h
index 9d3117b630..a196a37dc0 100644
--- a/core/io/translation_loader_po.h
+++ b/core/io/translation_loader_po.h
@@ -38,12 +38,12 @@
class TranslationLoaderPO : public ResourceFormatLoader {
public:
static RES load_translation(FileAccess *f, Error *r_error = nullptr);
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
- TranslationLoaderPO();
+ TranslationLoaderPO() {}
};
#endif // TRANSLATION_LOADER_PO_H
diff --git a/core/io/udp_server.cpp b/core/io/udp_server.cpp
index 16b7863cdd..1d329daf8b 100644
--- a/core/io/udp_server.cpp
+++ b/core/io/udp_server.cpp
@@ -31,7 +31,6 @@
#include "udp_server.h"
void UDPServer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &UDPServer::listen, DEFVAL("*"));
ClassDB::bind_method(D_METHOD("is_connection_available"), &UDPServer::is_connection_available);
ClassDB::bind_method(D_METHOD("is_listening"), &UDPServer::is_listening);
@@ -40,7 +39,6 @@ void UDPServer::_bind_methods() {
}
Error UDPServer::listen(uint16_t p_port, const IP_Address &p_bind_address) {
-
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
ERR_FAIL_COND_V(_sock->is_open(), ERR_ALREADY_IN_USE);
ERR_FAIL_COND_V(!p_bind_address.is_valid() && !p_bind_address.is_wildcard(), ERR_INVALID_PARAMETER);
@@ -48,13 +46,15 @@ Error UDPServer::listen(uint16_t p_port, const IP_Address &p_bind_address) {
Error err;
IP::Type ip_type = IP::TYPE_ANY;
- if (p_bind_address.is_valid())
+ if (p_bind_address.is_valid()) {
ip_type = p_bind_address.is_ipv4() ? IP::TYPE_IPV4 : IP::TYPE_IPV6;
+ }
err = _sock->open(NetSocket::TYPE_UDP, ip_type);
- if (err != OK)
+ if (err != OK) {
return ERR_CANT_CREATE;
+ }
_sock->set_blocking_enabled(false);
_sock->set_reuse_address_enabled(true);
@@ -76,18 +76,17 @@ bool UDPServer::is_listening() const {
}
bool UDPServer::is_connection_available() const {
-
ERR_FAIL_COND_V(!_sock.is_valid(), false);
- if (!_sock->is_open())
+ if (!_sock->is_open()) {
return false;
+ }
Error err = _sock->poll(NetSocket::POLL_TYPE_IN, 0);
return (err == OK);
}
Ref<PacketPeerUDP> UDPServer::take_connection() {
-
Ref<PacketPeerUDP> conn;
if (!is_connection_available()) {
return conn;
@@ -101,7 +100,6 @@ Ref<PacketPeerUDP> UDPServer::take_connection() {
}
void UDPServer::stop() {
-
if (_sock.is_valid()) {
_sock->close();
}
@@ -114,6 +112,5 @@ UDPServer::UDPServer() :
}
UDPServer::~UDPServer() {
-
stop();
}
diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp
index 9613ad3f10..b11267b60f 100644
--- a/core/io/xml_parser.cpp
+++ b/core/io/xml_parser.cpp
@@ -38,9 +38,11 @@ VARIANT_ENUM_CAST(XMLParser::NodeType);
static bool _equalsn(const CharType *str1, const CharType *str2, int len) {
int i;
- for (i = 0; i < len && str1[i] && str2[i]; ++i)
- if (str1[i] != str2[i])
+ for (i = 0; i < len && str1[i] && str2[i]; ++i) {
+ if (str1[i] != str2[i]) {
return false;
+ }
+ }
// if one (or both) of the strings was smaller then they
// are only equal if they have the same length
@@ -48,12 +50,12 @@ static bool _equalsn(const CharType *str1, const CharType *str2, int len) {
}
String XMLParser::_replace_special_characters(const String &origstr) {
-
int pos = origstr.find("&");
int oldPos = 0;
- if (pos == -1)
+ if (pos == -1) {
return origstr;
+ }
String newstr;
@@ -84,8 +86,9 @@ String XMLParser::_replace_special_characters(const String &origstr) {
pos = origstr.find("&", pos);
}
- if (oldPos < origstr.length() - 1)
+ if (oldPos < origstr.length() - 1) {
newstr += (origstr.substr(oldPos, origstr.length() - oldPos));
+ }
return newstr;
}
@@ -100,12 +103,15 @@ bool XMLParser::_set_text(char *start, char *end) {
// only white space, so that this text won't be reported
if (end - start < 3) {
char *p = start;
- for (; p != end; ++p)
- if (!_is_white_space(*p))
+ for (; p != end; ++p) {
+ if (!_is_white_space(*p)) {
break;
+ }
+ }
- if (p == end)
+ if (p == end) {
return false;
+ }
}
// set current text to the parsed text, and replace xml special characters
@@ -126,8 +132,9 @@ void XMLParser::_parse_closing_xml_element() {
++P;
const char *pBeginClose = P;
- while (*P != '>')
+ while (*P != '>') {
++P;
+ }
node_name = String::utf8(pBeginClose, (int)(P - pBeginClose));
#ifdef DEBUG_XML
@@ -141,16 +148,17 @@ void XMLParser::_ignore_definition() {
char *F = P;
// move until end marked with '>' reached
- while (*P != '>')
+ while (*P != '>') {
++P;
+ }
node_name.parse_utf8(F, P - F);
++P;
}
bool XMLParser::_parse_cdata() {
-
- if (*(P + 1) != '[')
+ if (*(P + 1) != '[') {
return false;
+ }
node_type = NODE_CDATA;
@@ -161,8 +169,9 @@ bool XMLParser::_parse_cdata() {
++count;
}
- if (!*P)
+ if (!*P) {
return true;
+ }
char *cDataBegin = P;
char *cDataEnd = nullptr;
@@ -178,10 +187,11 @@ bool XMLParser::_parse_cdata() {
++P;
}
- if (cDataEnd)
+ if (cDataEnd) {
node_name = String::utf8(cDataBegin, (int)(cDataEnd - cDataBegin));
- else
+ } else {
node_name = "";
+ }
#ifdef DEBUG_XML
print_line("XML CDATA: " + node_name);
#endif
@@ -190,7 +200,6 @@ bool XMLParser::_parse_cdata() {
}
void XMLParser::_parse_comment() {
-
node_type = NODE_COMMENT;
P += 1;
@@ -200,10 +209,11 @@ void XMLParser::_parse_comment() {
// move until end of comment reached
while (count) {
- if (*P == '>')
+ if (*P == '>') {
--count;
- else if (*P == '<')
+ } else if (*P == '<') {
++count;
+ }
++P;
}
@@ -217,7 +227,6 @@ void XMLParser::_parse_comment() {
}
void XMLParser::_parse_opening_xml_element() {
-
node_type = NODE_ELEMENT;
node_empty = false;
attributes.clear();
@@ -226,46 +235,52 @@ void XMLParser::_parse_opening_xml_element() {
const char *startName = P;
// find end of element
- while (*P != '>' && !_is_white_space(*P))
+ while (*P != '>' && !_is_white_space(*P)) {
++P;
+ }
const char *endName = P;
// find attributes
while (*P != '>') {
- if (_is_white_space(*P))
+ if (_is_white_space(*P)) {
++P;
- else {
+ } else {
if (*P != '/') {
// we've got an attribute
// read the attribute names
const char *attributeNameBegin = P;
- while (!_is_white_space(*P) && *P != '=')
+ while (!_is_white_space(*P) && *P != '=') {
++P;
+ }
const char *attributeNameEnd = P;
++P;
// read the attribute value
// check for quotes and single quotes, thx to murphy
- while ((*P != '\"') && (*P != '\'') && *P)
+ while ((*P != '\"') && (*P != '\'') && *P) {
++P;
+ }
- if (!*P) // malformatted xml file
+ if (!*P) { // malformatted xml file
return;
+ }
const char attributeQuoteChar = *P;
++P;
const char *attributeValueBegin = P;
- while (*P != attributeQuoteChar && *P)
+ while (*P != attributeQuoteChar && *P) {
++P;
+ }
- if (!*P) // malformatted xml file
+ if (!*P) { // malformatted xml file
return;
+ }
const char *attributeValueEnd = P;
++P;
@@ -304,21 +319,23 @@ void XMLParser::_parse_opening_xml_element() {
}
void XMLParser::_parse_current_node() {
-
char *start = P;
node_offset = P - data;
// more forward until '<' found
- while (*P != '<' && *P)
+ while (*P != '<' && *P) {
++P;
+ }
- if (!*P)
+ if (!*P) {
return;
+ }
if (P - start > 0) {
// we found some text, store it
- if (_set_text(start, P))
+ if (_set_text(start, P)) {
return;
+ }
}
++P;
@@ -332,8 +349,9 @@ void XMLParser::_parse_current_node() {
_ignore_definition();
break;
case '!':
- if (!_parse_cdata())
+ if (!_parse_cdata()) {
_parse_comment();
+ }
break;
default:
_parse_opening_xml_element();
@@ -342,22 +360,19 @@ void XMLParser::_parse_current_node() {
}
uint64_t XMLParser::get_node_offset() const {
-
return node_offset;
-};
+}
Error XMLParser::seek(uint64_t p_pos) {
-
ERR_FAIL_COND_V(!data, ERR_FILE_EOF);
ERR_FAIL_COND_V(p_pos >= length, ERR_FILE_EOF);
P = data + p_pos;
return read();
-};
+}
void XMLParser::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("read"), &XMLParser::read);
ClassDB::bind_method(D_METHOD("get_node_type"), &XMLParser::get_node_type);
ClassDB::bind_method(D_METHOD("get_node_name"), &XMLParser::get_node_name);
@@ -383,10 +398,9 @@ void XMLParser::_bind_methods() {
BIND_ENUM_CONSTANT(NODE_COMMENT);
BIND_ENUM_CONSTANT(NODE_CDATA);
BIND_ENUM_CONSTANT(NODE_UNKNOWN);
-};
+}
Error XMLParser::read() {
-
// if not end reached, parse the node
if (P && (P - data) < (int64_t)length - 1 && *P != 0) {
_parse_current_node();
@@ -397,11 +411,10 @@ Error XMLParser::read() {
}
XMLParser::NodeType XMLParser::get_node_type() {
-
return node_type;
}
-String XMLParser::get_node_data() const {
+String XMLParser::get_node_data() const {
ERR_FAIL_COND_V(node_type != NODE_TEXT, "");
return node_name;
}
@@ -410,31 +423,32 @@ String XMLParser::get_node_name() const {
ERR_FAIL_COND_V(node_type == NODE_TEXT, "");
return node_name;
}
-int XMLParser::get_attribute_count() const {
+int XMLParser::get_attribute_count() const {
return attributes.size();
}
-String XMLParser::get_attribute_name(int p_idx) const {
+String XMLParser::get_attribute_name(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, attributes.size(), "");
return attributes[p_idx].name;
}
-String XMLParser::get_attribute_value(int p_idx) const {
+String XMLParser::get_attribute_value(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, attributes.size(), "");
return attributes[p_idx].value;
}
-bool XMLParser::has_attribute(const String &p_name) const {
+bool XMLParser::has_attribute(const String &p_name) const {
for (int i = 0; i < attributes.size(); i++) {
- if (attributes[i].name == p_name)
+ if (attributes[i].name == p_name) {
return true;
+ }
}
return false;
}
-String XMLParser::get_attribute_value(const String &p_name) const {
+String XMLParser::get_attribute_value(const String &p_name) const {
int idx = -1;
for (int i = 0; i < attributes.size(); i++) {
if (attributes[i].name == p_name) {
@@ -449,7 +463,6 @@ String XMLParser::get_attribute_value(const String &p_name) const {
}
String XMLParser::get_attribute_value_safe(const String &p_name) const {
-
int idx = -1;
for (int i = 0; i < attributes.size(); i++) {
if (attributes[i].name == p_name) {
@@ -458,17 +471,17 @@ String XMLParser::get_attribute_value_safe(const String &p_name) const {
}
}
- if (idx < 0)
+ if (idx < 0) {
return "";
+ }
return attributes[idx].value;
}
-bool XMLParser::is_empty() const {
+bool XMLParser::is_empty() const {
return node_empty;
}
Error XMLParser::open_buffer(const Vector<uint8_t> &p_buffer) {
-
ERR_FAIL_COND_V(p_buffer.size() == 0, ERR_INVALID_DATA);
if (data) {
@@ -484,7 +497,6 @@ Error XMLParser::open_buffer(const Vector<uint8_t> &p_buffer) {
}
Error XMLParser::open(const String &p_path) {
-
Error err;
FileAccess *file = FileAccess::open(p_path, FileAccess::READ, &err);
@@ -508,10 +520,10 @@ Error XMLParser::open(const String &p_path) {
}
void XMLParser::skip_section() {
-
// skip if this element is empty anyway.
- if (is_empty())
+ if (is_empty()) {
return;
+ }
// read until we've reached the last element in this section
int tagcount = 1;
@@ -520,15 +532,16 @@ void XMLParser::skip_section() {
if (get_node_type() == XMLParser::NODE_ELEMENT &&
!is_empty()) {
++tagcount;
- } else if (get_node_type() == XMLParser::NODE_ELEMENT_END)
+ } else if (get_node_type() == XMLParser::NODE_ELEMENT_END) {
--tagcount;
+ }
}
}
void XMLParser::close() {
-
- if (data)
+ if (data) {
memdelete_arr(data);
+ }
data = nullptr;
length = 0;
P = nullptr;
@@ -538,22 +551,19 @@ void XMLParser::close() {
}
int XMLParser::get_current_line() const {
-
return 0;
}
XMLParser::XMLParser() {
-
- data = nullptr;
- close();
special_characters.push_back("&amp;");
special_characters.push_back("<lt;");
special_characters.push_back(">gt;");
special_characters.push_back("\"quot;");
special_characters.push_back("'apos;");
}
-XMLParser::~XMLParser() {
- if (data)
+XMLParser::~XMLParser() {
+ if (data) {
memdelete_arr(data);
+ }
}
diff --git a/core/io/xml_parser.h b/core/io/xml_parser.h
index 26c3e6802f..ee2174d52c 100644
--- a/core/io/xml_parser.h
+++ b/core/io/xml_parser.h
@@ -41,7 +41,6 @@
*/
class XMLParser : public Reference {
-
GDCLASS(XMLParser, Reference);
public:
@@ -66,15 +65,15 @@ public:
};
private:
- char *data;
- char *P;
- uint64_t length;
+ char *data = nullptr;
+ char *P = nullptr;
+ uint64_t length = 0;
void unescape(String &p_str);
Vector<String> special_characters;
String node_name;
- bool node_empty;
- NodeType node_type;
- uint64_t node_offset;
+ bool node_empty = false;
+ NodeType node_type = NODE_NONE;
+ uint64_t node_offset = 0;
struct Attribute {
String name;
diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp
index 3a2a207d22..b8e7fd34d0 100644
--- a/core/io/zip_io.cpp
+++ b/core/io/zip_io.cpp
@@ -33,7 +33,6 @@
#include "core/os/copymem.h"
void *zipio_open(void *data, const char *p_fname, int mode) {
-
FileAccess *&f = *(FileAccess **)data;
String fname;
@@ -42,42 +41,37 @@ void *zipio_open(void *data, const char *p_fname, int mode) {
if (mode & ZLIB_FILEFUNC_MODE_WRITE) {
f = FileAccess::open(fname, FileAccess::WRITE);
} else {
-
f = FileAccess::open(fname, FileAccess::READ);
}
- if (!f)
+ if (!f) {
return nullptr;
+ }
return data;
}
uLong zipio_read(void *data, void *fdata, void *buf, uLong size) {
-
FileAccess *f = *(FileAccess **)data;
return f->get_buffer((uint8_t *)buf, size);
}
uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size) {
-
FileAccess *f = *(FileAccess **)opaque;
f->store_buffer((uint8_t *)buf, size);
return size;
}
long zipio_tell(voidpf opaque, voidpf stream) {
-
FileAccess *f = *(FileAccess **)opaque;
return f->get_position();
}
long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
-
FileAccess *f = *(FileAccess **)opaque;
int pos = offset;
switch (origin) {
-
case ZLIB_FILEFUNC_SEEK_CUR:
pos = f->get_position() + offset;
break;
@@ -86,14 +80,13 @@ long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {
break;
default:
break;
- };
+ }
f->seek(pos);
return 0;
}
int zipio_close(voidpf opaque, voidpf stream) {
-
FileAccess *&f = *(FileAccess **)opaque;
if (f) {
f->close();
@@ -104,25 +97,21 @@ int zipio_close(voidpf opaque, voidpf stream) {
}
int zipio_testerror(voidpf opaque, voidpf stream) {
-
FileAccess *f = *(FileAccess **)opaque;
return (f && f->get_error() != OK) ? 1 : 0;
}
voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) {
-
voidpf ptr = memalloc(items * size);
zeromem(ptr, items * size);
return ptr;
}
void zipio_free(voidpf opaque, voidpf address) {
-
memfree(address);
}
zlib_filefunc_def zipio_create_io_from_file(FileAccess **p_file) {
-
zlib_filefunc_def io;
io.opaque = p_file;
io.zopen_file = zipio_open;
diff --git a/core/list.h b/core/list.h
index be2dccd876..6052a619fb 100644
--- a/core/list.h
+++ b/core/list.h
@@ -49,127 +49,117 @@ class List {
public:
class Element {
-
private:
friend class List<T, A>;
T value;
- Element *next_ptr;
- Element *prev_ptr;
- _Data *data;
+ Element *next_ptr = nullptr;
+ Element *prev_ptr = nullptr;
+ _Data *data = nullptr;
public:
/**
* Get NEXT Element iterator, for constant lists.
*/
_FORCE_INLINE_ const Element *next() const {
-
return next_ptr;
- };
+ }
/**
* Get NEXT Element iterator,
*/
_FORCE_INLINE_ Element *next() {
-
return next_ptr;
- };
+ }
/**
* Get PREV Element iterator, for constant lists.
*/
_FORCE_INLINE_ const Element *prev() const {
-
return prev_ptr;
- };
+ }
/**
* Get PREV Element iterator,
*/
_FORCE_INLINE_ Element *prev() {
-
return prev_ptr;
- };
+ }
/**
* * operator, for using as *iterator, when iterators are defined on stack.
*/
_FORCE_INLINE_ const T &operator*() const {
return value;
- };
+ }
/**
* operator->, for using as iterator->, when iterators are defined on stack, for constant lists.
*/
_FORCE_INLINE_ const T *operator->() const {
-
return &value;
- };
+ }
/**
* * operator, for using as *iterator, when iterators are defined on stack,
*/
_FORCE_INLINE_ T &operator*() {
return value;
- };
+ }
/**
* operator->, for using as iterator->, when iterators are defined on stack, for constant lists.
*/
_FORCE_INLINE_ T *operator->() {
return &value;
- };
+ }
/**
* get the value stored in this element.
*/
_FORCE_INLINE_ T &get() {
return value;
- };
+ }
/**
* get the value stored in this element, for constant lists
*/
_FORCE_INLINE_ const T &get() const {
return value;
- };
+ }
/**
* set the value stored in this element.
*/
_FORCE_INLINE_ void set(const T &p_value) {
value = (T &)p_value;
- };
+ }
void erase() {
-
data->erase(this);
}
- _FORCE_INLINE_ Element() {
- next_ptr = 0;
- prev_ptr = 0;
- data = nullptr;
- };
+ _FORCE_INLINE_ Element() {}
};
private:
struct _Data {
-
Element *first;
Element *last;
int size_cache;
bool erase(const Element *p_I) {
-
ERR_FAIL_COND_V(!p_I, false);
ERR_FAIL_COND_V(p_I->data != this, false);
if (first == p_I) {
first = p_I->next_ptr;
- };
+ }
- if (last == p_I)
+ if (last == p_I) {
last = p_I->prev_ptr;
+ }
- if (p_I->prev_ptr)
+ if (p_I->prev_ptr) {
p_I->prev_ptr->next_ptr = p_I->next_ptr;
+ }
- if (p_I->next_ptr)
+ if (p_I->next_ptr) {
p_I->next_ptr->prev_ptr = p_I->prev_ptr;
+ }
memdelete_allocator<Element, A>(const_cast<Element *>(p_I));
size_cache--;
@@ -178,47 +168,42 @@ private:
}
};
- _Data *_data;
+ _Data *_data = nullptr;
public:
/**
* return a const iterator to the beginning of the list.
*/
_FORCE_INLINE_ const Element *front() const {
-
- return _data ? _data->first : 0;
- };
+ return _data ? _data->first : nullptr;
+ }
/**
* return an iterator to the beginning of the list.
*/
_FORCE_INLINE_ Element *front() {
- return _data ? _data->first : 0;
- };
+ return _data ? _data->first : nullptr;
+ }
/**
* return a const iterator to the last member of the list.
*/
_FORCE_INLINE_ const Element *back() const {
-
- return _data ? _data->last : 0;
- };
+ return _data ? _data->last : nullptr;
+ }
/**
* return an iterator to the last member of the list.
*/
_FORCE_INLINE_ Element *back() {
-
- return _data ? _data->last : 0;
- };
+ return _data ? _data->last : nullptr;
+ }
/**
* store a new element at the end of the list
*/
Element *push_back(const T &value) {
-
if (!_data) {
-
_data = memnew_allocator(_Data, A);
_data->first = nullptr;
_data->last = nullptr;
@@ -229,37 +214,35 @@ public:
n->value = (T &)value;
n->prev_ptr = _data->last;
- n->next_ptr = 0;
+ n->next_ptr = nullptr;
n->data = _data;
if (_data->last) {
-
_data->last->next_ptr = n;
}
_data->last = n;
- if (!_data->first)
+ if (!_data->first) {
_data->first = n;
+ }
_data->size_cache++;
return n;
- };
+ }
void pop_back() {
-
- if (_data && _data->last)
+ if (_data && _data->last) {
erase(_data->last);
+ }
}
/**
* store a new element at the beginning of the list
*/
Element *push_front(const T &value) {
-
if (!_data) {
-
_data = memnew_allocator(_Data, A);
_data->first = nullptr;
_data->last = nullptr;
@@ -268,29 +251,29 @@ public:
Element *n = memnew_allocator(Element, A);
n->value = (T &)value;
- n->prev_ptr = 0;
+ n->prev_ptr = nullptr;
n->next_ptr = _data->first;
n->data = _data;
if (_data->first) {
-
_data->first->prev_ptr = n;
}
_data->first = n;
- if (!_data->last)
+ if (!_data->last) {
_data->last = n;
+ }
_data->size_cache++;
return n;
- };
+ }
void pop_front() {
-
- if (_data && _data->first)
+ if (_data && _data->first) {
erase(_data->first);
+ }
}
Element *insert_after(Element *p_element, const T &p_value) {
@@ -350,21 +333,21 @@ public:
*/
template <class T_v>
Element *find(const T_v &p_val) {
-
Element *it = front();
while (it) {
- if (it->value == p_val) return it;
+ if (it->value == p_val) {
+ return it;
+ }
it = it->next();
- };
+ }
return nullptr;
- };
+ }
/**
* erase an element in the list, by iterator pointing to it. Return true if it was found/erased.
*/
bool erase(const Element *p_I) {
-
if (_data) {
bool ret = _data->erase(p_I);
@@ -377,22 +360,20 @@ public:
}
return false;
- };
+ }
/**
* erase the first element in the list, that contains value
*/
bool erase(const T &value) {
-
Element *I = find(value);
return erase(I);
- };
+ }
/**
* return whether the list is empty
*/
_FORCE_INLINE_ bool empty() const {
-
return (!_data || !_data->size_cache);
}
@@ -400,19 +381,16 @@ public:
* clear the list
*/
void clear() {
-
while (front()) {
erase(front());
- };
- };
+ }
+ }
_FORCE_INLINE_ int size() const {
-
return _data ? _data->size_cache : 0;
}
void swap(Element *p_A, Element *p_B) {
-
ERR_FAIL_COND(!p_A || !p_B);
ERR_FAIL_COND(p_A->data != _data);
ERR_FAIL_COND(p_B->data != _data);
@@ -426,32 +404,33 @@ public:
p_B->next_ptr = A_next;
p_B->prev_ptr = A_prev;
- if (p_A->prev_ptr)
+ if (p_A->prev_ptr) {
p_A->prev_ptr->next_ptr = p_A;
- if (p_A->next_ptr)
+ }
+ if (p_A->next_ptr) {
p_A->next_ptr->prev_ptr = p_A;
+ }
- if (p_B->prev_ptr)
+ if (p_B->prev_ptr) {
p_B->prev_ptr->next_ptr = p_B;
- if (p_B->next_ptr)
+ }
+ if (p_B->next_ptr) {
p_B->next_ptr->prev_ptr = p_B;
+ }
}
/**
* copy the list
*/
void operator=(const List &p_list) {
-
clear();
const Element *it = p_list.front();
while (it) {
-
push_back(it->get());
it = it->next();
}
}
T &operator[](int p_index) {
-
CRASH_BAD_INDEX(p_index, size());
Element *I = front();
@@ -465,7 +444,6 @@ public:
}
const T &operator[](int p_index) const {
-
CRASH_BAD_INDEX(p_index, size());
const Element *I = front();
@@ -479,20 +457,22 @@ public:
}
void move_to_back(Element *p_I) {
-
ERR_FAIL_COND(p_I->data != _data);
- if (!p_I->next_ptr)
+ if (!p_I->next_ptr) {
return;
+ }
if (_data->first == p_I) {
_data->first = p_I->next_ptr;
- };
+ }
- if (_data->last == p_I)
+ if (_data->last == p_I) {
_data->last = p_I->prev_ptr;
+ }
- if (p_I->prev_ptr)
+ if (p_I->prev_ptr) {
p_I->prev_ptr->next_ptr = p_I->next_ptr;
+ }
p_I->next_ptr->prev_ptr = p_I->prev_ptr;
@@ -503,12 +483,10 @@ public:
}
void invert() {
-
int s = size() / 2;
Element *F = front();
Element *B = back();
for (int i = 0; i < s; i++) {
-
SWAP(F->value, B->value);
F = F->next();
B = B->prev();
@@ -516,22 +494,24 @@ public:
}
void move_to_front(Element *p_I) {
-
ERR_FAIL_COND(p_I->data != _data);
- if (!p_I->prev_ptr)
+ if (!p_I->prev_ptr) {
return;
+ }
if (_data->first == p_I) {
_data->first = p_I->next_ptr;
- };
+ }
- if (_data->last == p_I)
+ if (_data->last == p_I) {
_data->last = p_I->prev_ptr;
+ }
p_I->prev_ptr->next_ptr = p_I->next_ptr;
- if (p_I->next_ptr)
+ if (p_I->next_ptr) {
p_I->next_ptr->prev_ptr = p_I->prev_ptr;
+ }
_data->first->prev_ptr = p_I;
p_I->next_ptr = _data->first;
@@ -540,7 +520,6 @@ public:
}
void move_before(Element *value, Element *where) {
-
if (value->prev_ptr) {
value->prev_ptr->next_ptr = value->next_ptr;
} else {
@@ -557,7 +536,7 @@ public:
value->prev_ptr = _data->last;
_data->last = value;
return;
- };
+ }
value->prev_ptr = where->prev_ptr;
@@ -565,59 +544,56 @@ public:
where->prev_ptr->next_ptr = value;
} else {
_data->first = value;
- };
+ }
where->prev_ptr = value;
- };
+ }
/**
* simple insertion sort
*/
void sort() {
-
sort_custom<Comparator<T>>();
}
template <class C>
void sort_custom_inplace() {
-
- if (size() < 2)
+ if (size() < 2) {
return;
+ }
Element *from = front();
Element *current = from;
Element *to = from;
while (current) {
-
Element *next = current->next_ptr;
if (from != current) {
-
current->prev_ptr = nullptr;
current->next_ptr = from;
Element *find = from;
C less;
while (find && less(find->value, current->value)) {
-
current->prev_ptr = find;
current->next_ptr = find->next_ptr;
find = find->next_ptr;
}
- if (current->prev_ptr)
+ if (current->prev_ptr) {
current->prev_ptr->next_ptr = current;
- else
+ } else {
from = current;
+ }
- if (current->next_ptr)
+ if (current->next_ptr) {
current->next_ptr->prev_ptr = current;
- else
+ } else {
to = current;
+ }
} else {
-
current->prev_ptr = nullptr;
current->next_ptr = nullptr;
}
@@ -630,29 +606,26 @@ public:
template <class C>
struct AuxiliaryComparator {
-
C compare;
_FORCE_INLINE_ bool operator()(const Element *a, const Element *b) const {
-
return compare(a->value, b->value);
}
};
template <class C>
void sort_custom() {
-
//this version uses auxiliary memory for speed.
//if you don't want to use auxiliary memory, use the in_place version
int s = size();
- if (s < 2)
+ if (s < 2) {
return;
+ }
Element **aux_buffer = memnew_arr(Element *, s);
int idx = 0;
for (Element *E = front(); E; E = E->next_ptr) {
-
aux_buffer[idx] = E;
idx++;
}
@@ -669,7 +642,6 @@ public:
aux_buffer[s - 1]->next_ptr = nullptr;
for (int i = 1; i < s - 1; i++) {
-
aux_buffer[i]->prev_ptr = aux_buffer[i - 1];
aux_buffer[i]->next_ptr = aux_buffer[i + 1];
}
@@ -685,27 +657,22 @@ public:
* copy constructor for the list
*/
List(const List &p_list) {
-
- _data = nullptr;
const Element *it = p_list.front();
while (it) {
-
push_back(it->get());
it = it->next();
}
}
- List() {
- _data = nullptr;
- };
+ List() {}
+
~List() {
clear();
if (_data) {
-
ERR_FAIL_COND(_data->size_cache);
memdelete_allocator<_Data, A>(_data);
}
- };
+ }
};
#endif // LIST_H
diff --git a/core/local_vector.h b/core/local_vector.h
new file mode 100644
index 0000000000..b09a28b25a
--- /dev/null
+++ b/core/local_vector.h
@@ -0,0 +1,238 @@
+/*************************************************************************/
+/* local_vector.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef LOCAL_VECTOR_H
+#define LOCAL_VECTOR_H
+
+#include "core/error_macros.h"
+#include "core/os/copymem.h"
+#include "core/os/memory.h"
+#include "core/sort_array.h"
+#include "core/vector.h"
+
+template <class T, class U = uint32_t, bool force_trivial = false>
+class LocalVector {
+private:
+ U count = 0;
+ U capacity = 0;
+ T *data = nullptr;
+
+public:
+ _FORCE_INLINE_ void push_back(T p_elem) {
+ if (unlikely(count == capacity)) {
+ if (capacity == 0) {
+ capacity = 1;
+ } else {
+ capacity <<= 1;
+ }
+ data = (T *)memrealloc(data, capacity * sizeof(T));
+ CRASH_COND_MSG(!data, "Out of memory");
+ }
+
+ if (!__has_trivial_constructor(T) && !force_trivial) {
+ memnew_placement(&data[count++], T(p_elem));
+ } else {
+ data[count++] = p_elem;
+ }
+ }
+
+ void remove(U p_index) {
+ ERR_FAIL_UNSIGNED_INDEX(p_index, count);
+ for (U i = p_index; i < count; i++) {
+ data[i] = data[i + 1];
+ }
+ count--;
+ if (!__has_trivial_destructor(T) && !force_trivial) {
+ data[count].~T();
+ }
+ }
+
+ void erase(const T &p_val) {
+ U idx = find(p_val);
+ if (idx >= 0) {
+ remove(idx);
+ }
+ }
+
+ void invert() {
+ for (U i = 0; i < count / 2; i++) {
+ SWAP(data[i], data[count - i - 1]);
+ }
+ }
+
+ _FORCE_INLINE_ void clear() { resize(0); }
+ _FORCE_INLINE_ void reset() {
+ clear();
+ if (data) {
+ memfree(data);
+ data = nullptr;
+ capacity = 0;
+ }
+ }
+ _FORCE_INLINE_ bool empty() const { return count == 0; }
+ _FORCE_INLINE_ void reserve(U p_size) {
+ p_size = nearest_power_of_2_templated(p_size);
+ if (p_size > capacity) {
+ capacity = p_size;
+ data = (T *)memrealloc(data, capacity * sizeof(T));
+ CRASH_COND_MSG(!data, "Out of memory");
+ }
+ }
+
+ _FORCE_INLINE_ U size() const { return count; }
+ void resize(U p_size) {
+ if (p_size < count) {
+ if (!__has_trivial_destructor(T) && !force_trivial) {
+ for (U i = p_size; i < count; i++) {
+ data[i].~T();
+ }
+ }
+ count = p_size;
+ } else if (p_size > count) {
+ if (unlikely(p_size > capacity)) {
+ if (capacity == 0) {
+ capacity = 1;
+ }
+ while (capacity < p_size) {
+ capacity <<= 1;
+ }
+ data = (T *)memrealloc(data, capacity * sizeof(T));
+ CRASH_COND_MSG(!data, "Out of memory");
+ }
+ if (!__has_trivial_constructor(T) && !force_trivial) {
+ for (U i = count; i < p_size; i++) {
+ memnew_placement(&data[i], T);
+ }
+ }
+ count = p_size;
+ }
+ }
+ _FORCE_INLINE_ const T &operator[](U p_index) const {
+ CRASH_BAD_UNSIGNED_INDEX(p_index, count);
+ return data[p_index];
+ }
+ _FORCE_INLINE_ T &operator[](U p_index) {
+ CRASH_BAD_UNSIGNED_INDEX(p_index, count);
+ return data[p_index];
+ }
+
+ void insert(U p_pos, T p_val) {
+ ERR_FAIL_UNSIGNED_INDEX(p_pos, count + 1);
+ if (p_pos == count) {
+ push_back(p_val);
+ } else {
+ resize(count + 1);
+ for (U i = count; i > p_pos; i--) {
+ data[i] = data[i - 1];
+ }
+ data[p_pos] = p_val;
+ }
+ }
+
+ int64_t find(const T &p_val, U p_from = 0) const {
+ for (U i = 0; i < count; i++) {
+ if (data[i] == p_val) {
+ return int64_t(i);
+ }
+ }
+ return -1;
+ }
+
+ template <class C>
+ void sort_custom() {
+ U len = count;
+ if (len == 0) {
+ return;
+ }
+
+ SortArray<T, C> sorter;
+ sorter.sort(data, len);
+ }
+
+ void sort() {
+ sort_custom<_DefaultComparator<T>>();
+ }
+
+ void ordered_insert(T p_val) {
+ U i;
+ for (i = 0; i < count; i++) {
+ if (p_val < data[i]) {
+ break;
+ }
+ }
+ insert(i, p_val);
+ }
+
+ operator Vector<T>() const {
+ Vector<T> ret;
+ ret.resize(size());
+ T *w = ret.ptrw();
+ copymem(w, data, sizeof(T) * count);
+ return ret;
+ }
+
+ Vector<uint8_t> to_byte_array() const { //useful to pass stuff to gpu or variant
+ Vector<uint8_t> ret;
+ ret.resize(count * sizeof(T));
+ uint8_t *w = ret.ptrw();
+ copymem(w, data, sizeof(T) * count);
+ return ret;
+ }
+
+ _FORCE_INLINE_ LocalVector() {}
+ _FORCE_INLINE_ LocalVector(const LocalVector &p_from) {
+ resize(p_from.size());
+ for (U i = 0; i < p_from.count; i++) {
+ data[i] = p_from.data[i];
+ }
+ }
+ inline LocalVector &operator=(const LocalVector &p_from) {
+ resize(p_from.size());
+ for (U i = 0; i < p_from.count; i++) {
+ data[i] = p_from.data[i];
+ }
+ return *this;
+ }
+ inline LocalVector &operator=(const Vector<T> &p_from) {
+ resize(p_from.size());
+ for (U i = 0; i < count; i++) {
+ data[i] = p_from[i];
+ }
+ return *this;
+ }
+
+ _FORCE_INLINE_ ~LocalVector() {
+ if (data) {
+ reset();
+ }
+ }
+};
+
+#endif // LOCAL_VECTOR_H
diff --git a/core/make_binders.py b/core/make_binders.py
index 94bee95bfb..7d0d08cde6 100644
--- a/core/make_binders.py
+++ b/core/make_binders.py
@@ -75,7 +75,7 @@ public:
#endif
$ifret _set_returns(true); $
- };
+ }
};
template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
@@ -170,7 +170,7 @@ public:
$ifret _set_returns(true); $
- };
+ }
};
template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
@@ -266,7 +266,7 @@ public:
#endif
$ifret _set_returns(true); $
- };
+ }
};
template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$>
diff --git a/core/map.h b/core/map.h
index 6b9dff51de..fd4f500556 100644
--- a/core/map.h
+++ b/core/map.h
@@ -39,7 +39,6 @@
template <class K, class V, class C = Comparator<K>, class A = DefaultAllocator>
class Map {
-
enum Color {
RED,
BLACK
@@ -48,67 +47,54 @@ class Map {
public:
class Element {
-
private:
friend class Map<K, V, C, A>;
- int color;
- Element *right;
- Element *left;
- Element *parent;
- Element *_next;
- Element *_prev;
+ int color = RED;
+ Element *right = nullptr;
+ Element *left = nullptr;
+ Element *parent = nullptr;
+ Element *_next = nullptr;
+ Element *_prev = nullptr;
K _key;
V _value;
//_Data *data;
public:
const Element *next() const {
-
return _next;
}
Element *next() {
-
return _next;
}
const Element *prev() const {
-
return _prev;
}
Element *prev() {
-
return _prev;
}
const K &key() const {
return _key;
- };
+ }
V &value() {
return _value;
- };
+ }
const V &value() const {
return _value;
- };
+ }
V &get() {
return _value;
- };
+ }
const V &get() const {
return _value;
- };
- Element() {
- color = RED;
- right = nullptr;
- left = nullptr;
- parent = nullptr;
- _next = nullptr;
- _prev = nullptr;
- };
+ }
+ Element() {}
};
private:
struct _Data {
-
- Element *_root;
+ Element *_root = nullptr;
Element *_nil;
- int size_cache;
+ int size_cache = 0;
_FORCE_INLINE_ _Data() {
#ifdef GLOBALNIL_DISABLED
@@ -118,19 +104,15 @@ private:
#else
_nil = (Element *)&_GlobalNilClass::_nil;
#endif
- _root = nullptr;
- size_cache = 0;
}
void _create_root() {
-
_root = memnew_allocator(Element, A);
_root->parent = _root->left = _root->right = _nil;
_root->color = BLACK;
}
void _free_root() {
-
if (_root) {
memdelete_allocator<Element, A>(_root);
_root = nullptr;
@@ -138,7 +120,6 @@ private:
}
~_Data() {
-
_free_root();
#ifdef GLOBALNIL_DISABLED
@@ -150,62 +131,61 @@ private:
_Data _data;
inline void _set_color(Element *p_node, int p_color) {
-
ERR_FAIL_COND(p_node == _data._nil && p_color == RED);
p_node->color = p_color;
}
inline void _rotate_left(Element *p_node) {
-
Element *r = p_node->right;
p_node->right = r->left;
- if (r->left != _data._nil)
+ if (r->left != _data._nil) {
r->left->parent = p_node;
+ }
r->parent = p_node->parent;
- if (p_node == p_node->parent->left)
+ if (p_node == p_node->parent->left) {
p_node->parent->left = r;
- else
+ } else {
p_node->parent->right = r;
+ }
r->left = p_node;
p_node->parent = r;
}
inline void _rotate_right(Element *p_node) {
-
Element *l = p_node->left;
p_node->left = l->right;
- if (l->right != _data._nil)
+ if (l->right != _data._nil) {
l->right->parent = p_node;
+ }
l->parent = p_node->parent;
- if (p_node == p_node->parent->right)
+ if (p_node == p_node->parent->right) {
p_node->parent->right = l;
- else
+ } else {
p_node->parent->left = l;
+ }
l->right = p_node;
p_node->parent = l;
}
inline Element *_successor(Element *p_node) const {
-
Element *node = p_node;
if (node->right != _data._nil) {
-
node = node->right;
while (node->left != _data._nil) { /* returns the minimum of the right subtree of node */
node = node->left;
}
return node;
} else {
-
while (node == node->parent->right) {
node = node->parent;
}
- if (node->parent == _data._root)
+ if (node->parent == _data._root) {
return nullptr; // No successor, as p_node = last node
+ }
return node->parent;
}
}
@@ -214,43 +194,41 @@ private:
Element *node = p_node;
if (node->left != _data._nil) {
-
node = node->left;
while (node->right != _data._nil) { /* returns the minimum of the left subtree of node */
node = node->right;
}
return node;
} else {
-
while (node == node->parent->left) {
node = node->parent;
}
- if (node == _data._root)
+ if (node == _data._root) {
return nullptr; // No predecessor, as p_node = first node
+ }
return node->parent;
}
}
Element *_find(const K &p_key) const {
-
Element *node = _data._root->left;
C less;
while (node != _data._nil) {
- if (less(p_key, node->_key))
+ if (less(p_key, node->_key)) {
node = node->left;
- else if (less(node->_key, p_key))
+ } else if (less(node->_key, p_key)) {
node = node->right;
- else
+ } else {
return node; // found
+ }
}
return nullptr;
}
Element *_find_closest(const K &p_key) const {
-
Element *node = _data._root->left;
Element *prev = nullptr;
C less;
@@ -258,25 +236,27 @@ private:
while (node != _data._nil) {
prev = node;
- if (less(p_key, node->_key))
+ if (less(p_key, node->_key)) {
node = node->left;
- else if (less(node->_key, p_key))
+ } else if (less(node->_key, p_key)) {
node = node->right;
- else
+ } else {
return node; // found
+ }
}
- if (prev == nullptr)
+ if (prev == nullptr) {
return nullptr; // tree empty
+ }
- if (less(p_key, prev->_key))
+ if (less(p_key, prev->_key)) {
prev = prev->_prev;
+ }
return prev;
}
void _insert_rb_fix(Element *p_new_node) {
-
Element *node = p_new_node;
Element *nparent = node->parent;
Element *ngrand_parent;
@@ -325,20 +305,18 @@ private:
}
Element *_insert(const K &p_key, const V &p_value) {
-
Element *new_parent = _data._root;
Element *node = _data._root->left;
C less;
while (node != _data._nil) {
-
new_parent = node;
- if (less(p_key, node->_key))
+ if (less(p_key, node->_key)) {
node = node->left;
- else if (less(node->_key, p_key))
+ } else if (less(node->_key, p_key)) {
node = node->right;
- else {
+ } else {
node->_value = p_value;
return node; // Return existing node with new value
}
@@ -360,10 +338,12 @@ private:
new_node->_next = _successor(new_node);
new_node->_prev = _predecessor(new_node);
- if (new_node->_next)
+ if (new_node->_next) {
new_node->_next->_prev = new_node;
- if (new_node->_prev)
+ }
+ if (new_node->_prev) {
new_node->_prev->_next = new_node;
+ }
_data.size_cache++;
_insert_rb_fix(new_node);
@@ -371,7 +351,6 @@ private:
}
void _erase_fix_rb(Element *p_node) {
-
Element *root = _data._root->left;
Element *node = _data._nil;
Element *sibling = p_node;
@@ -433,7 +412,6 @@ private:
}
void _erase(Element *p_node) {
-
Element *rp = ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : p_node->_next;
Element *node = (rp->left == _data._nil) ? rp->right : rp->left;
@@ -454,17 +432,18 @@ private:
}
if (rp != p_node) {
-
ERR_FAIL_COND(rp == _data._nil);
rp->left = p_node->left;
rp->right = p_node->right;
rp->parent = p_node->parent;
rp->color = p_node->color;
- if (p_node->left != _data._nil)
+ if (p_node->left != _data._nil) {
p_node->left->parent = rp;
- if (p_node->right != _data._nil)
+ }
+ if (p_node->right != _data._nil) {
p_node->right->parent = rp;
+ }
if (p_node == p_node->parent->left) {
p_node->parent->left = rp;
@@ -473,10 +452,12 @@ private:
}
}
- if (p_node->_next)
+ if (p_node->_next) {
p_node->_next->_prev = p_node->_prev;
- if (p_node->_prev)
+ }
+ if (p_node->_prev) {
p_node->_prev->_next = p_node->_next;
+ }
memdelete_allocator<Element, A>(p_node);
_data.size_cache--;
@@ -484,21 +465,22 @@ private:
}
void _calculate_depth(Element *p_element, int &max_d, int d) const {
-
- if (p_element == _data._nil)
+ if (p_element == _data._nil) {
return;
+ }
_calculate_depth(p_element->left, max_d, d + 1);
_calculate_depth(p_element->right, max_d, d + 1);
- if (d > max_d)
+ if (d > max_d) {
max_d = d;
+ }
}
void _cleanup_tree(Element *p_element) {
-
- if (p_element == _data._nil)
+ if (p_element == _data._nil) {
return;
+ }
_cleanup_tree(p_element->left);
_cleanup_tree(p_element->right);
@@ -506,91 +488,90 @@ private:
}
void _copy_from(const Map &p_map) {
-
clear();
// not the fastest way, but safeset to write.
for (Element *I = p_map.front(); I; I = I->next()) {
-
insert(I->key(), I->value());
}
}
public:
const Element *find(const K &p_key) const {
-
- if (!_data._root)
+ if (!_data._root) {
return nullptr;
+ }
const Element *res = _find(p_key);
return res;
}
Element *find(const K &p_key) {
-
- if (!_data._root)
+ if (!_data._root) {
return nullptr;
+ }
Element *res = _find(p_key);
return res;
}
const Element *find_closest(const K &p_key) const {
-
- if (!_data._root)
+ if (!_data._root) {
return nullptr;
+ }
const Element *res = _find_closest(p_key);
return res;
}
Element *find_closest(const K &p_key) {
-
- if (!_data._root)
+ if (!_data._root) {
return nullptr;
+ }
Element *res = _find_closest(p_key);
return res;
}
bool has(const K &p_key) const {
-
return find(p_key) != nullptr;
}
Element *insert(const K &p_key, const V &p_value) {
-
- if (!_data._root)
+ if (!_data._root) {
_data._create_root();
+ }
return _insert(p_key, p_value);
}
void erase(Element *p_element) {
-
- if (!_data._root || !p_element)
+ if (!_data._root || !p_element) {
return;
+ }
_erase(p_element);
- if (_data.size_cache == 0 && _data._root)
+ if (_data.size_cache == 0 && _data._root) {
_data._free_root();
+ }
}
bool erase(const K &p_key) {
-
- if (!_data._root)
+ if (!_data._root) {
return false;
+ }
Element *e = find(p_key);
- if (!e)
+ if (!e) {
return false;
+ }
_erase(e);
- if (_data.size_cache == 0 && _data._root)
+ if (_data.size_cache == 0 && _data._root) {
_data._free_root();
+ }
return true;
}
const V &operator[](const K &p_key) const {
-
CRASH_COND(!_data._root);
const Element *e = find(p_key);
CRASH_COND(!e);
@@ -598,43 +579,48 @@ public:
}
V &operator[](const K &p_key) {
-
- if (!_data._root)
+ if (!_data._root) {
_data._create_root();
+ }
Element *e = find(p_key);
- if (!e)
+ if (!e) {
e = insert(p_key, V());
+ }
return e->_value;
}
Element *front() const {
-
- if (!_data._root)
+ if (!_data._root) {
return nullptr;
+ }
Element *e = _data._root->left;
- if (e == _data._nil)
+ if (e == _data._nil) {
return nullptr;
+ }
- while (e->left != _data._nil)
+ while (e->left != _data._nil) {
e = e->left;
+ }
return e;
}
Element *back() const {
-
- if (!_data._root)
+ if (!_data._root) {
return nullptr;
+ }
Element *e = _data._root->left;
- if (e == _data._nil)
+ if (e == _data._nil) {
return nullptr;
+ }
- while (e->right != _data._nil)
+ while (e->right != _data._nil) {
e = e->right;
+ }
return e;
}
@@ -644,8 +630,9 @@ public:
int calculate_depth() const {
// used for debug mostly
- if (!_data._root)
+ if (!_data._root) {
return 0;
+ }
int max_d = 0;
_calculate_depth(_data._root->left, max_d, 0);
@@ -653,9 +640,9 @@ public:
}
void clear() {
-
- if (!_data._root)
+ if (!_data._root) {
return;
+ }
_cleanup_tree(_data._root->left);
_data._root->left = _data._nil;
@@ -664,20 +651,16 @@ public:
}
void operator=(const Map &p_map) {
-
_copy_from(p_map);
}
Map(const Map &p_map) {
-
_copy_from(p_map);
}
- _FORCE_INLINE_ Map() {
- }
+ _FORCE_INLINE_ Map() {}
~Map() {
-
clear();
}
};
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 3e3e6c50a7..45c4a207c3 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -35,7 +35,6 @@
#include "scene/scene_string_names.h"
int AStar::get_available_point_id() const {
-
if (points.empty()) {
return 1;
}
@@ -54,7 +53,6 @@ int AStar::get_available_point_id() const {
}
void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
-
ERR_FAIL_COND(p_id < 0);
ERR_FAIL_COND(p_weight_scale < 1);
@@ -78,7 +76,6 @@ void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
}
Vector3 AStar::get_point_position(int p_id) const {
-
Point *p;
bool p_exists = points.lookup(p_id, p);
ERR_FAIL_COND_V(!p_exists, Vector3());
@@ -87,7 +84,6 @@ Vector3 AStar::get_point_position(int p_id) const {
}
void AStar::set_point_position(int p_id, const Vector3 &p_pos) {
-
Point *p;
bool p_exists = points.lookup(p_id, p);
ERR_FAIL_COND(!p_exists);
@@ -96,7 +92,6 @@ void AStar::set_point_position(int p_id, const Vector3 &p_pos) {
}
real_t AStar::get_point_weight_scale(int p_id) const {
-
Point *p;
bool p_exists = points.lookup(p_id, p);
ERR_FAIL_COND_V(!p_exists, 0);
@@ -105,7 +100,6 @@ real_t AStar::get_point_weight_scale(int p_id) const {
}
void AStar::set_point_weight_scale(int p_id, real_t p_weight_scale) {
-
Point *p;
bool p_exists = points.lookup(p_id, p);
ERR_FAIL_COND(!p_exists);
@@ -115,13 +109,11 @@ void AStar::set_point_weight_scale(int p_id, real_t p_weight_scale) {
}
void AStar::remove_point(int p_id) {
-
Point *p;
bool p_exists = points.lookup(p_id, p);
ERR_FAIL_COND(!p_exists);
for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
-
Segment s(p_id, (*it.key));
segments.erase(s);
@@ -130,7 +122,6 @@ void AStar::remove_point(int p_id) {
}
for (OAHashMap<int, Point *>::Iterator it = p->unlinked_neighbours.iter(); it.valid; it = p->unlinked_neighbours.next_iter(it)) {
-
Segment s(p_id, (*it.key));
segments.erase(s);
@@ -144,7 +135,6 @@ void AStar::remove_point(int p_id) {
}
void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
-
ERR_FAIL_COND(p_id == p_with_id);
Point *a;
@@ -164,7 +154,9 @@ void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
}
Segment s(p_id, p_with_id);
- if (bidirectional) s.direction = Segment::BIDIRECTIONAL;
+ if (bidirectional) {
+ s.direction = Segment::BIDIRECTIONAL;
+ }
Set<Segment>::Element *element = segments.find(s);
if (element != nullptr) {
@@ -181,7 +173,6 @@ void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
}
void AStar::disconnect_points(int p_id, int p_with_id, bool bidirectional) {
-
Point *a;
bool a_exists = points.lookup(p_id, a);
ERR_FAIL_COND(!a_exists);
@@ -207,25 +198,25 @@ void AStar::disconnect_points(int p_id, int p_with_id, bool bidirectional) {
b->unlinked_neighbours.remove(a->id);
}
} else {
- if (s.direction == Segment::NONE)
+ if (s.direction == Segment::NONE) {
b->unlinked_neighbours.remove(a->id);
- else
+ } else {
a->unlinked_neighbours.set(b->id, b);
+ }
}
segments.erase(element);
- if (s.direction != Segment::NONE)
+ if (s.direction != Segment::NONE) {
segments.insert(s);
+ }
}
}
bool AStar::has_point(int p_id) const {
-
return points.has(p_id);
}
Array AStar::get_points() {
-
Array point_list;
for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
@@ -236,7 +227,6 @@ Array AStar::get_points() {
}
Vector<int> AStar::get_point_connections(int p_id) {
-
Point *p;
bool p_exists = points.lookup(p_id, p);
ERR_FAIL_COND_V(!p_exists, Vector<int>());
@@ -251,7 +241,6 @@ Vector<int> AStar::get_point_connections(int p_id) {
}
bool AStar::are_points_connected(int p_id, int p_with_id, bool bidirectional) const {
-
Segment s(p_id, p_with_id);
const Set<Segment>::Element *element = segments.find(s);
@@ -260,7 +249,6 @@ bool AStar::are_points_connected(int p_id, int p_with_id, bool bidirectional) co
}
void AStar::clear() {
-
last_free_id = 0;
for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
memdelete(*(it.value));
@@ -284,13 +272,13 @@ void AStar::reserve_space(int p_num_nodes) {
}
int AStar::get_closest_point(const Vector3 &p_point, bool p_include_disabled) const {
-
int closest_id = -1;
real_t closest_dist = 1e20;
for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
-
- if (!p_include_disabled && !(*it.value)->enabled) continue; // Disabled points should not be considered.
+ if (!p_include_disabled && !(*it.value)->enabled) {
+ continue; // Disabled points should not be considered.
+ }
real_t d = p_point.distance_squared_to((*it.value)->pos);
if (closest_id < 0 || d < closest_dist) {
@@ -303,13 +291,11 @@ int AStar::get_closest_point(const Vector3 &p_point, bool p_include_disabled) co
}
Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const {
-
bool found = false;
real_t closest_dist = 1e20;
Vector3 closest_point;
for (const Set<Segment>::Element *E = segments.front(); E; E = E->next()) {
-
Point *from_point = nullptr, *to_point = nullptr;
points.lookup(E->get().u, from_point);
points.lookup(E->get().v, to_point);
@@ -326,7 +312,6 @@ Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const {
Vector3 p = Geometry::get_closest_point_to_segment(p_point, segment);
real_t d = p_point.distance_squared_to(p);
if (!found || d < closest_dist) {
-
closest_point = p;
closest_dist = d;
found = true;
@@ -337,10 +322,11 @@ Vector3 AStar::get_closest_position_in_segment(const Vector3 &p_point) const {
}
bool AStar::_solve(Point *begin_point, Point *end_point) {
-
pass++;
- if (!end_point->enabled) return false;
+ if (!end_point->enabled) {
+ return false;
+ }
bool found_route = false;
@@ -352,7 +338,6 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
open_list.push_back(begin_point);
while (!open_list.empty()) {
-
Point *p = open_list[0]; // The currently processed point
if (p == end_point) {
@@ -365,7 +350,6 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
p->closed_pass = pass; // Mark the point as closed
for (OAHashMap<int, Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
-
Point *e = *(it.value); // The neighbour point
if (!e->enabled || e->closed_pass == pass) {
@@ -400,9 +384,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
}
real_t AStar::_estimate_cost(int p_from_id, int p_to_id) {
-
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost))
+ if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) {
return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id);
+ }
Point *from_point;
bool from_exists = points.lookup(p_from_id, from_point);
@@ -416,9 +400,9 @@ real_t AStar::_estimate_cost(int p_from_id, int p_to_id) {
}
real_t AStar::_compute_cost(int p_from_id, int p_to_id) {
-
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost))
+ if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) {
return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id);
+ }
Point *from_point;
bool from_exists = points.lookup(p_from_id, from_point);
@@ -432,7 +416,6 @@ real_t AStar::_compute_cost(int p_from_id, int p_to_id) {
}
Vector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
-
Point *a;
bool from_exists = points.lookup(p_from_id, a);
ERR_FAIL_COND_V(!from_exists, Vector<Vector3>());
@@ -451,7 +434,9 @@ Vector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
- if (!found_route) return Vector<Vector3>();
+ if (!found_route) {
+ return Vector<Vector3>();
+ }
Point *p = end_point;
int pc = 1; // Begin point
@@ -480,7 +465,6 @@ Vector<Vector3> AStar::get_point_path(int p_from_id, int p_to_id) {
}
Vector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
-
Point *a;
bool from_exists = points.lookup(p_from_id, a);
ERR_FAIL_COND_V(!from_exists, Vector<int>());
@@ -499,7 +483,9 @@ Vector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
- if (!found_route) return Vector<int>();
+ if (!found_route) {
+ return Vector<int>();
+ }
Point *p = end_point;
int pc = 1; // Begin point
@@ -528,7 +514,6 @@ Vector<int> AStar::get_id_path(int p_from_id, int p_to_id) {
}
void AStar::set_point_disabled(int p_id, bool p_disabled) {
-
Point *p;
bool p_exists = points.lookup(p_id, p);
ERR_FAIL_COND(!p_exists);
@@ -537,7 +522,6 @@ void AStar::set_point_disabled(int p_id, bool p_disabled) {
}
bool AStar::is_point_disabled(int p_id) const {
-
Point *p;
bool p_exists = points.lookup(p_id, p);
ERR_FAIL_COND_V(!p_exists, false);
@@ -546,7 +530,6 @@ bool AStar::is_point_disabled(int p_id) const {
}
void AStar::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_available_point_id"), &AStar::get_available_point_id);
ClassDB::bind_method(D_METHOD("add_point", "id", "position", "weight_scale"), &AStar::add_point, DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("get_point_position", "id"), &AStar::get_point_position);
@@ -580,11 +563,6 @@ void AStar::_bind_methods() {
BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
}
-AStar::AStar() {
- last_free_id = 0;
- pass = 1;
-}
-
AStar::~AStar() {
clear();
}
@@ -678,9 +656,9 @@ Vector2 AStar2D::get_closest_position_in_segment(const Vector2 &p_point) const {
}
real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) {
-
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost))
+ if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) {
return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id);
+ }
AStar::Point *from_point;
bool from_exists = astar.points.lookup(p_from_id, from_point);
@@ -694,9 +672,9 @@ real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) {
}
real_t AStar2D::_compute_cost(int p_from_id, int p_to_id) {
-
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost))
+ if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) {
return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id);
+ }
AStar::Point *from_point;
bool from_exists = astar.points.lookup(p_from_id, from_point);
@@ -710,7 +688,6 @@ real_t AStar2D::_compute_cost(int p_from_id, int p_to_id) {
}
Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
-
AStar::Point *a;
bool from_exists = astar.points.lookup(p_from_id, a);
ERR_FAIL_COND_V(!from_exists, Vector<Vector2>());
@@ -729,7 +706,9 @@ Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
AStar::Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
- if (!found_route) return Vector<Vector2>();
+ if (!found_route) {
+ return Vector<Vector2>();
+ }
AStar::Point *p = end_point;
int pc = 1; // Begin point
@@ -758,7 +737,6 @@ Vector<Vector2> AStar2D::get_point_path(int p_from_id, int p_to_id) {
}
Vector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
-
AStar::Point *a;
bool from_exists = astar.points.lookup(p_from_id, a);
ERR_FAIL_COND_V(!from_exists, Vector<int>());
@@ -777,7 +755,9 @@ Vector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
AStar::Point *end_point = b;
bool found_route = _solve(begin_point, end_point);
- if (!found_route) return Vector<int>();
+ if (!found_route) {
+ return Vector<int>();
+ }
AStar::Point *p = end_point;
int pc = 1; // Begin point
@@ -806,10 +786,11 @@ Vector<int> AStar2D::get_id_path(int p_from_id, int p_to_id) {
}
bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) {
-
astar.pass++;
- if (!end_point->enabled) return false;
+ if (!end_point->enabled) {
+ return false;
+ }
bool found_route = false;
@@ -821,7 +802,6 @@ bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) {
open_list.push_back(begin_point);
while (!open_list.empty()) {
-
AStar::Point *p = open_list[0]; // The currently processed point
if (p == end_point) {
@@ -834,7 +814,6 @@ bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) {
p->closed_pass = astar.pass; // Mark the point as closed
for (OAHashMap<int, AStar::Point *>::Iterator it = p->neighbours.iter(); it.valid; it = p->neighbours.next_iter(it)) {
-
AStar::Point *e = *(it.value); // The neighbour point
if (!e->enabled || e->closed_pass == astar.pass) {
@@ -869,7 +848,6 @@ bool AStar2D::_solve(AStar::Point *begin_point, AStar::Point *end_point) {
}
void AStar2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_available_point_id"), &AStar2D::get_available_point_id);
ClassDB::bind_method(D_METHOD("add_point", "id", "position", "weight_scale"), &AStar2D::add_point, DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("get_point_position", "id"), &AStar2D::get_point_position);
@@ -902,9 +880,3 @@ void AStar2D::_bind_methods() {
BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
}
-
-AStar2D::AStar2D() {
-}
-
-AStar2D::~AStar2D() {
-}
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 8c10ace33c..ba1c3033b8 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -41,23 +41,19 @@
*/
class AStar : public Reference {
-
GDCLASS(AStar, Reference);
friend class AStar2D;
struct Point {
-
- Point() :
- neighbours(4u),
- unlinked_neighbours(4u) {}
+ Point() {}
int id;
Vector3 pos;
real_t weight_scale;
bool enabled;
- OAHashMap<int, Point *> neighbours;
- OAHashMap<int, Point *> unlinked_neighbours;
+ OAHashMap<int, Point *> neighbours = 4u;
+ OAHashMap<int, Point *> unlinked_neighbours = 4u;
// Used for pathfinding.
Point *prev_point;
@@ -85,7 +81,7 @@ class AStar : public Reference {
int32_t u;
int32_t v;
};
- uint64_t key;
+ uint64_t key = 0;
};
enum {
@@ -94,13 +90,11 @@ class AStar : public Reference {
BACKWARD = 2,
BIDIRECTIONAL = FORWARD | BACKWARD
};
- unsigned char direction;
+ unsigned char direction = NONE;
bool operator<(const Segment &p_s) const { return key < p_s.key; }
- Segment() {
- key = 0;
- direction = NONE;
- }
+
+ Segment() {}
Segment(int p_from, int p_to) {
if (p_from < p_to) {
u = p_from;
@@ -114,8 +108,8 @@ class AStar : public Reference {
}
};
- int last_free_id;
- uint64_t pass;
+ int last_free_id = 0;
+ uint64_t pass = 1;
OAHashMap<int, Point *> points;
Set<Segment> segments;
@@ -159,7 +153,7 @@ public:
Vector<Vector3> get_point_path(int p_from_id, int p_to_id);
Vector<int> get_id_path(int p_from_id, int p_to_id);
- AStar();
+ AStar() {}
~AStar();
};
@@ -206,8 +200,8 @@ public:
Vector<Vector2> get_point_path(int p_from_id, int p_to_id);
Vector<int> get_id_path(int p_from_id, int p_to_id);
- AStar2D();
- ~AStar2D();
+ AStar2D() {}
+ ~AStar2D() {}
};
#endif // A_STAR_H
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index 19d60fea72..f5c667dab0 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -33,21 +33,18 @@
#include "core/print_string.h"
real_t AABB::get_area() 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 {
+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) {
-
Vector3 beg_1, beg_2;
Vector3 end_1, end_2;
Vector3 min, max;
@@ -70,12 +67,10 @@ void AABB::merge_with(const AABB &p_aabb) {
}
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);
}
AABB AABB::intersection(const AABB &p_aabb) const {
-
Vector3 src_min = position;
Vector3 src_max = position + size;
Vector3 dst_min = p_aabb.position;
@@ -83,26 +78,23 @@ AABB AABB::intersection(const AABB &p_aabb) const {
Vector3 min, max;
- if (src_min.x > dst_max.x || src_max.x < dst_min.x)
+ if (src_min.x > dst_max.x || src_max.x < dst_min.x) {
return AABB();
- else {
-
+ } else {
min.x = (src_min.x > dst_min.x) ? src_min.x : dst_min.x;
max.x = (src_max.x < dst_max.x) ? src_max.x : dst_max.x;
}
- if (src_min.y > dst_max.y || src_max.y < dst_min.y)
+ if (src_min.y > dst_max.y || src_max.y < dst_min.y) {
return AABB();
- else {
-
+ } else {
min.y = (src_min.y > dst_min.y) ? src_min.y : dst_min.y;
max.y = (src_max.y < dst_max.y) ? src_max.y : dst_max.y;
}
- if (src_min.z > dst_max.z || src_max.z < dst_min.z)
+ if (src_min.z > dst_max.z || src_max.z < dst_min.z) {
return AABB();
- else {
-
+ } else {
min.z = (src_min.z > dst_min.z) ? src_min.z : dst_min.z;
max.z = (src_max.z < dst_max.z) ? src_max.z : dst_max.z;
}
@@ -111,7 +103,6 @@ AABB AABB::intersection(const AABB &p_aabb) const {
}
bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const {
-
Vector3 c1, c2;
Vector3 end = position + size;
real_t near = -1e20;
@@ -143,8 +134,9 @@ bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *
}
}
- if (r_clip)
+ if (r_clip) {
*r_clip = c1;
+ }
if (r_normal) {
*r_normal = Vector3();
(*r_normal)[axis] = p_dir[axis] ? -1 : 1;
@@ -154,7 +146,6 @@ bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *
}
bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip, Vector3 *r_normal) const {
-
real_t min = 0, max = 1;
int axis = 0;
real_t sign = 0;
@@ -168,18 +159,18 @@ bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector
real_t csign;
if (seg_from < seg_to) {
-
- if (seg_from > box_end || seg_to < box_begin)
+ if (seg_from > box_end || seg_to < box_begin) {
return false;
+ }
real_t length = seg_to - seg_from;
cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0;
cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1;
csign = -1.0;
} else {
-
- if (seg_to > box_end || seg_from < box_begin)
+ if (seg_to > box_end || seg_from < box_begin) {
return false;
+ }
real_t length = seg_to - seg_from;
cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0;
cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1;
@@ -191,10 +182,12 @@ bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector
axis = i;
sign = csign;
}
- if (cmax < max)
+ if (cmax < max) {
max = cmax;
- if (max < min)
+ }
+ if (max < min) {
return false;
+ }
}
Vector3 rel = p_to - p_from;
@@ -205,14 +198,14 @@ bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector
*r_normal = normal;
}
- if (r_clip)
+ if (r_clip) {
*r_clip = p_from + rel * min;
+ }
return true;
}
bool AABB::intersects_plane(const Plane &p_plane) const {
-
Vector3 points[8] = {
Vector3(position.x, position.y, position.z),
Vector3(position.x, position.y, position.z + size.z),
@@ -228,18 +221,17 @@ bool AABB::intersects_plane(const Plane &p_plane) const {
bool under = false;
for (int i = 0; i < 8; i++) {
-
- if (p_plane.distance_to(points[i]) > 0)
+ if (p_plane.distance_to(points[i]) > 0) {
over = true;
- else
+ } else {
under = true;
+ }
}
return under && over;
}
Vector3 AABB::get_longest_axis() const {
-
Vector3 axis(1, 0, 0);
real_t max_size = size.x;
@@ -254,8 +246,8 @@ Vector3 AABB::get_longest_axis() const {
return axis;
}
-int AABB::get_longest_axis_index() const {
+int AABB::get_longest_axis_index() const {
int axis = 0;
real_t max_size = size.x;
@@ -272,7 +264,6 @@ int AABB::get_longest_axis_index() const {
}
Vector3 AABB::get_shortest_axis() const {
-
Vector3 axis(1, 0, 0);
real_t max_size = size.x;
@@ -287,8 +278,8 @@ Vector3 AABB::get_shortest_axis() const {
return axis;
}
-int AABB::get_shortest_axis_index() const {
+int AABB::get_shortest_axis_index() const {
int axis = 0;
real_t max_size = size.x;
@@ -305,35 +296,31 @@ int AABB::get_shortest_axis_index() const {
}
AABB AABB::merge(const AABB &p_with) const {
-
AABB aabb = *this;
aabb.merge_with(p_with);
return aabb;
}
+
AABB AABB::expand(const Vector3 &p_vector) const {
AABB aabb = *this;
aabb.expand_to(p_vector);
return aabb;
}
-AABB AABB::grow(real_t p_by) const {
+AABB AABB::grow(real_t p_by) const {
AABB aabb = *this;
aabb.grow_by(p_by);
return aabb;
}
void AABB::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const {
-
ERR_FAIL_INDEX(p_edge, 12);
switch (p_edge) {
-
case 0: {
-
r_from = Vector3(position.x + size.x, position.y, position.z);
r_to = Vector3(position.x, position.y, position.z);
} break;
case 1: {
-
r_from = Vector3(position.x + size.x, position.y, position.z + size.z);
r_to = Vector3(position.x + size.x, position.y, position.z);
} break;
@@ -343,18 +330,15 @@ void AABB::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const {
} break;
case 3: {
-
r_from = Vector3(position.x, position.y, position.z);
r_to = Vector3(position.x, position.y, position.z + size.z);
} break;
case 4: {
-
r_from = Vector3(position.x, position.y + size.y, position.z);
r_to = Vector3(position.x + size.x, position.y + size.y, position.z);
} break;
case 5: {
-
r_from = Vector3(position.x + size.x, position.y + size.y, position.z);
r_to = Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
} break;
@@ -364,31 +348,26 @@ void AABB::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const {
} break;
case 7: {
-
r_from = Vector3(position.x, position.y + size.y, position.z + size.z);
r_to = Vector3(position.x, position.y + size.y, position.z);
} break;
case 8: {
-
r_from = Vector3(position.x, position.y, position.z + size.z);
r_to = Vector3(position.x, position.y + size.y, position.z + size.z);
} break;
case 9: {
-
r_from = Vector3(position.x, position.y, position.z);
r_to = Vector3(position.x, position.y + size.y, position.z);
} break;
case 10: {
-
r_from = Vector3(position.x + size.x, position.y, position.z);
r_to = Vector3(position.x + size.x, position.y + size.y, position.z);
} break;
case 11: {
-
r_from = Vector3(position.x + size.x, position.y, position.z + size.z);
r_to = Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
@@ -397,6 +376,5 @@ void AABB::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const {
}
AABB::operator String() const {
-
return String() + position + " - " + size;
}
diff --git a/core/math/aabb.h b/core/math/aabb.h
index eca74e6755..4106fbb93c 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -47,12 +47,10 @@ public:
real_t get_area() const; /// get area
_FORCE_INLINE_ bool has_no_area() const {
-
return (size.x <= 0 || size.y <= 0 || size.z <= 0);
}
_FORCE_INLINE_ bool has_no_surface() const {
-
return (size.x <= 0 && size.y <= 0 && size.z <= 0);
}
@@ -76,7 +74,7 @@ public:
bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip = nullptr, Vector3 *r_normal = nullptr) const;
_FORCE_INLINE_ bool smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const;
- _FORCE_INLINE_ bool intersects_convex_shape(const Plane *p_planes, int p_plane_count) const;
+ _FORCE_INLINE_ bool intersects_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) const;
_FORCE_INLINE_ bool inside_convex_shape(const Plane *p_planes, int p_plane_count) const;
bool intersects_plane(const Plane &p_plane) const;
@@ -111,43 +109,52 @@ public:
};
inline bool AABB::intersects(const AABB &p_aabb) const {
-
- if (position.x >= (p_aabb.position.x + p_aabb.size.x))
+ if (position.x >= (p_aabb.position.x + p_aabb.size.x)) {
return false;
- if ((position.x + size.x) <= p_aabb.position.x)
+ }
+ if ((position.x + size.x) <= p_aabb.position.x) {
return false;
- if (position.y >= (p_aabb.position.y + p_aabb.size.y))
+ }
+ if (position.y >= (p_aabb.position.y + p_aabb.size.y)) {
return false;
- if ((position.y + size.y) <= p_aabb.position.y)
+ }
+ if ((position.y + size.y) <= p_aabb.position.y) {
return false;
- if (position.z >= (p_aabb.position.z + p_aabb.size.z))
+ }
+ if (position.z >= (p_aabb.position.z + p_aabb.size.z)) {
return false;
- if ((position.z + size.z) <= p_aabb.position.z)
+ }
+ if ((position.z + size.z) <= p_aabb.position.z) {
return false;
+ }
return true;
}
inline bool AABB::intersects_inclusive(const AABB &p_aabb) const {
-
- if (position.x > (p_aabb.position.x + p_aabb.size.x))
+ if (position.x > (p_aabb.position.x + p_aabb.size.x)) {
return false;
- if ((position.x + size.x) < p_aabb.position.x)
+ }
+ if ((position.x + size.x) < p_aabb.position.x) {
return false;
- if (position.y > (p_aabb.position.y + p_aabb.size.y))
+ }
+ if (position.y > (p_aabb.position.y + p_aabb.size.y)) {
return false;
- if ((position.y + size.y) < p_aabb.position.y)
+ }
+ if ((position.y + size.y) < p_aabb.position.y) {
return false;
- if (position.z > (p_aabb.position.z + p_aabb.size.z))
+ }
+ if (position.z > (p_aabb.position.z + p_aabb.size.z)) {
return false;
- if ((position.z + size.z) < p_aabb.position.z)
+ }
+ if ((position.z + size.z) < p_aabb.position.z) {
return false;
+ }
return true;
}
inline bool AABB::encloses(const AABB &p_aabb) const {
-
Vector3 src_min = position;
Vector3 src_max = position + size;
Vector3 dst_min = p_aabb.position;
@@ -163,7 +170,6 @@ inline bool AABB::encloses(const AABB &p_aabb) const {
}
Vector3 AABB::get_support(const Vector3 &p_normal) const {
-
Vector3 half_extents = size * 0.5;
Vector3 ofs = position + half_extents;
@@ -175,23 +181,29 @@ Vector3 AABB::get_support(const Vector3 &p_normal) const {
}
Vector3 AABB::get_endpoint(int p_point) const {
-
switch (p_point) {
- case 0: return Vector3(position.x, position.y, position.z);
- case 1: return Vector3(position.x, position.y, position.z + size.z);
- case 2: return Vector3(position.x, position.y + size.y, position.z);
- case 3: return Vector3(position.x, position.y + size.y, position.z + size.z);
- case 4: return Vector3(position.x + size.x, position.y, position.z);
- case 5: return Vector3(position.x + size.x, position.y, position.z + size.z);
- case 6: return Vector3(position.x + size.x, position.y + size.y, position.z);
- case 7: return Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
- };
+ case 0:
+ return Vector3(position.x, position.y, position.z);
+ case 1:
+ return Vector3(position.x, position.y, position.z + size.z);
+ case 2:
+ return Vector3(position.x, position.y + size.y, position.z);
+ case 3:
+ return Vector3(position.x, position.y + size.y, position.z + size.z);
+ case 4:
+ return Vector3(position.x + size.x, position.y, position.z);
+ case 5:
+ return Vector3(position.x + size.x, position.y, position.z + size.z);
+ case 6:
+ return Vector3(position.x + size.x, position.y + size.y, position.z);
+ case 7:
+ return Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
+ }
ERR_FAIL_V(Vector3());
}
-bool AABB::intersects_convex_shape(const Plane *p_planes, int p_plane_count) const {
-
+bool AABB::intersects_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) const {
Vector3 half_extents = size * 0.5;
Vector3 ofs = position + half_extents;
@@ -202,15 +214,38 @@ bool AABB::intersects_convex_shape(const Plane *p_planes, int p_plane_count) con
(p.normal.y > 0) ? -half_extents.y : half_extents.y,
(p.normal.z > 0) ? -half_extents.z : half_extents.z);
point += ofs;
- if (p.is_point_over(point))
+ if (p.is_point_over(point)) {
+ return false;
+ }
+ }
+
+ // Make sure all points in the shape aren't fully separated from the AABB on
+ // each axis.
+ int bad_point_counts_positive[3] = { 0 };
+ int bad_point_counts_negative[3] = { 0 };
+
+ for (int k = 0; k < 3; k++) {
+ for (int i = 0; i < p_point_count; i++) {
+ if (p_points[i].coord[k] > ofs.coord[k] + half_extents.coord[k]) {
+ bad_point_counts_positive[k]++;
+ }
+ if (p_points[i].coord[k] < ofs.coord[k] - half_extents.coord[k]) {
+ bad_point_counts_negative[k]++;
+ }
+ }
+
+ if (bad_point_counts_negative[k] == p_point_count) {
+ return false;
+ }
+ if (bad_point_counts_positive[k] == p_point_count) {
return false;
+ }
}
return true;
}
bool AABB::inside_convex_shape(const Plane *p_planes, int p_plane_count) const {
-
Vector3 half_extents = size * 0.5;
Vector3 ofs = position + half_extents;
@@ -221,56 +256,66 @@ bool AABB::inside_convex_shape(const Plane *p_planes, int p_plane_count) const {
(p.normal.y < 0) ? -half_extents.y : half_extents.y,
(p.normal.z < 0) ? -half_extents.z : half_extents.z);
point += ofs;
- if (p.is_point_over(point))
+ if (p.is_point_over(point)) {
return false;
+ }
}
return true;
}
bool AABB::has_point(const Vector3 &p_point) const {
-
- if (p_point.x < position.x)
+ if (p_point.x < position.x) {
return false;
- if (p_point.y < position.y)
+ }
+ if (p_point.y < position.y) {
return false;
- if (p_point.z < position.z)
+ }
+ if (p_point.z < position.z) {
return false;
- if (p_point.x > position.x + size.x)
+ }
+ if (p_point.x > position.x + size.x) {
return false;
- if (p_point.y > position.y + size.y)
+ }
+ if (p_point.y > position.y + size.y) {
return false;
- if (p_point.z > position.z + size.z)
+ }
+ if (p_point.z > position.z + size.z) {
return false;
+ }
return true;
}
inline void AABB::expand_to(const Vector3 &p_vector) {
-
Vector3 begin = position;
Vector3 end = position + size;
- if (p_vector.x < begin.x)
+ if (p_vector.x < begin.x) {
begin.x = p_vector.x;
- if (p_vector.y < begin.y)
+ }
+ if (p_vector.y < begin.y) {
begin.y = p_vector.y;
- if (p_vector.z < begin.z)
+ }
+ if (p_vector.z < begin.z) {
begin.z = p_vector.z;
+ }
- if (p_vector.x > end.x)
+ if (p_vector.x > end.x) {
end.x = p_vector.x;
- if (p_vector.y > end.y)
+ }
+ if (p_vector.y > end.y) {
end.y = p_vector.y;
- if (p_vector.z > end.z)
+ }
+ if (p_vector.z > end.z) {
end.z = p_vector.z;
+ }
position = begin;
size = end - begin;
}
void AABB::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const {
-
Vector3 half_extents(size.x * 0.5, size.y * 0.5, size.z * 0.5);
Vector3 center(position.x + half_extents.x, position.y + half_extents.y, position.z + half_extents.z);
@@ -281,7 +326,6 @@ void AABB::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r
}
inline real_t AABB::get_longest_axis_size() const {
-
real_t max_size = size.x;
if (size.y > max_size) {
@@ -296,7 +340,6 @@ inline real_t AABB::get_longest_axis_size() const {
}
inline real_t AABB::get_shortest_axis_size() const {
-
real_t max_size = size.x;
if (size.y < max_size) {
@@ -311,7 +354,6 @@ inline real_t AABB::get_shortest_axis_size() const {
}
bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const {
-
real_t divx = 1.0 / p_dir.x;
real_t divy = 1.0 / p_dir.y;
real_t divz = 1.0 / p_dir.z;
@@ -332,12 +374,15 @@ bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real
tymin = (upbound.y - p_from.y) * divy;
tymax = (position.y - p_from.y) * divy;
}
- if ((tmin > tymax) || (tymin > tmax))
+ if ((tmin > tymax) || (tymin > tmax)) {
return false;
- if (tymin > tmin)
+ }
+ if (tymin > tmin) {
tmin = tymin;
- if (tymax < tmax)
+ }
+ if (tymax < tmax) {
tmax = tymax;
+ }
if (p_dir.z >= 0) {
tzmin = (position.z - p_from.z) * divz;
tzmax = (upbound.z - p_from.z) * divz;
@@ -345,17 +390,19 @@ bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real
tzmin = (upbound.z - p_from.z) * divz;
tzmax = (position.z - p_from.z) * divz;
}
- if ((tmin > tzmax) || (tzmin > tmax))
+ if ((tmin > tzmax) || (tzmin > tmax)) {
return false;
- if (tzmin > tmin)
+ }
+ if (tzmin > tmin) {
tmin = tzmin;
- if (tzmax < tmax)
+ }
+ if (tzmax < tmax) {
tmax = tzmax;
+ }
return ((tmin < t1) && (tmax > t0));
}
void AABB::grow_by(real_t p_amount) {
-
position.x -= p_amount;
position.y -= p_amount;
position.z -= p_amount;
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h
index e1dbb385e4..91f533eafb 100644
--- a/core/math/audio_frame.h
+++ b/core/math/audio_frame.h
@@ -48,7 +48,6 @@ static inline float undenormalise(volatile float f) {
}
struct AudioFrame {
-
//left and right samples
float l, r;
@@ -104,8 +103,7 @@ struct AudioFrame {
r = ::undenormalise(r);
}
- _FORCE_INLINE_ AudioFrame linear_interpolate(const AudioFrame &p_b, float p_t) const {
-
+ _FORCE_INLINE_ AudioFrame lerp(const AudioFrame &p_b, float p_t) const {
AudioFrame res = *this;
res.l += (p_t * (p_b.l - l));
diff --git a/core/math/basis.cpp b/core/math/basis.cpp
index 0f519a20d8..cbfd09810c 100644
--- a/core/math/basis.cpp
+++ b/core/math/basis.cpp
@@ -38,16 +38,13 @@
(elements[row1][col1] * elements[row2][col2] - elements[row1][col2] * elements[row2][col1])
void Basis::from_z(const Vector3 &p_z) {
-
if (Math::abs(p_z.z) > Math_SQRT12) {
-
// choose p in y-z plane
real_t a = p_z[1] * p_z[1] + p_z[2] * p_z[2];
real_t k = 1.0 / Math::sqrt(a);
elements[0] = Vector3(0, -p_z[2] * k, p_z[1] * k);
elements[1] = Vector3(a * k, -p_z[0] * elements[0][2], p_z[0] * elements[0][1]);
} else {
-
// choose p in x-y plane
real_t a = p_z.x * p_z.x + p_z.y * p_z.y;
real_t k = 1.0 / Math::sqrt(a);
@@ -58,7 +55,6 @@ void Basis::from_z(const Vector3 &p_z) {
}
void Basis::invert() {
-
real_t co[3] = {
cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1)
};
@@ -76,7 +72,6 @@ void Basis::invert() {
}
void Basis::orthonormalize() {
-
// Gram-Schmidt Process
Vector3 x = get_axis(0);
@@ -95,7 +90,6 @@ void Basis::orthonormalize() {
}
Basis Basis::orthonormalized() const {
-
Basis c = *this;
c.orthonormalize();
return c;
@@ -120,19 +114,20 @@ bool Basis::is_rotation() const {
}
bool Basis::is_symmetric() const {
-
- if (!Math::is_equal_approx_ratio(elements[0][1], elements[1][0], UNIT_EPSILON))
+ if (!Math::is_equal_approx_ratio(elements[0][1], elements[1][0], UNIT_EPSILON)) {
return false;
- if (!Math::is_equal_approx_ratio(elements[0][2], elements[2][0], UNIT_EPSILON))
+ }
+ if (!Math::is_equal_approx_ratio(elements[0][2], elements[2][0], UNIT_EPSILON)) {
return false;
- if (!Math::is_equal_approx_ratio(elements[1][2], elements[2][1], UNIT_EPSILON))
+ }
+ if (!Math::is_equal_approx_ratio(elements[1][2], elements[2][1], UNIT_EPSILON)) {
return false;
+ }
return true;
}
Basis Basis::diagonalize() {
-
//NOTE: only implemented for symmetric matrices
//with the Jacobi iterative method method
#ifdef MATH_CHECKS
@@ -193,21 +188,18 @@ Basis Basis::diagonalize() {
}
Basis Basis::inverse() const {
-
Basis inv = *this;
inv.invert();
return inv;
}
void Basis::transpose() {
-
SWAP(elements[0][1], elements[1][0]);
SWAP(elements[0][2], elements[2][0]);
SWAP(elements[1][2], elements[2][1]);
}
Basis Basis::transposed() const {
-
Basis tr = *this;
tr.transpose();
return tr;
@@ -216,7 +208,6 @@ Basis Basis::transposed() const {
// Multiplies the matrix from left by the scaling matrix: M -> S.M
// See the comment for Basis::rotated for further explanation.
void Basis::scale(const Vector3 &p_scale) {
-
elements[0][0] *= p_scale.x;
elements[0][1] *= p_scale.x;
elements[0][2] *= p_scale.x;
@@ -260,7 +251,6 @@ Basis Basis::scaled_local(const Vector3 &p_scale) const {
}
Vector3 Basis::get_scale_abs() const {
-
return Vector3(
Vector3(elements[0][0], elements[1][0], elements[2][0]).length(),
Vector3(elements[0][1], elements[1][1], elements[2][1]).length(),
@@ -340,8 +330,8 @@ void Basis::rotate_local(const Vector3 &p_axis, real_t p_phi) {
// M -> (M.R.Minv).M = M.R.
*this = rotated_local(p_axis, p_phi);
}
-Basis Basis::rotated_local(const Vector3 &p_axis, real_t p_phi) const {
+Basis Basis::rotated_local(const Vector3 &p_axis, real_t p_phi) const {
return (*this) * Basis(p_axis, p_phi);
}
@@ -430,7 +420,6 @@ void Basis::get_rotation_axis_angle_local(Vector3 &p_axis, real_t &p_angle) cons
// the angles in the decomposition R = X(a1).Y(a2).Z(a3) where Z(a) rotates
// around the z-axis by a and so on.
Vector3 Basis::get_euler_xyz() const {
-
// Euler angles in XYZ convention.
// See https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
//
@@ -474,7 +463,6 @@ Vector3 Basis::get_euler_xyz() const {
// and similar for other axes.
// The current implementation uses XYZ convention (Z is the first rotation).
void Basis::set_euler_xyz(const Vector3 &p_euler) {
-
real_t c, s;
c = Math::cos(p_euler.x);
@@ -497,7 +485,6 @@ void Basis::set_euler_xyz(const Vector3 &p_euler) {
// as in first-Z, then-X, last-Y. The angles for X, Y, and Z rotations are returned
// as the x, y, and z components of a Vector3 respectively.
Vector3 Basis::get_euler_yxz() const {
-
/* checking this is a bad idea, because obtaining from scaled transform is a valid use case
#ifdef MATH_CHECKS
ERR_FAIL_COND(!is_rotation());
@@ -546,7 +533,6 @@ Vector3 Basis::get_euler_yxz() const {
// and similar for other axes.
// The current implementation uses YXZ convention (Z is the first rotation).
void Basis::set_euler_yxz(const Vector3 &p_euler) {
-
real_t c, s;
c = Math::cos(p_euler.x);
@@ -566,16 +552,15 @@ void Basis::set_euler_yxz(const Vector3 &p_euler) {
}
bool Basis::is_equal_approx(const Basis &p_basis) const {
-
return elements[0].is_equal_approx(p_basis.elements[0]) && elements[1].is_equal_approx(p_basis.elements[1]) && elements[2].is_equal_approx(p_basis.elements[2]);
}
bool Basis::is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsilon) const {
-
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
- if (!Math::is_equal_approx_ratio(a.elements[i][j], b.elements[i][j], p_epsilon))
+ if (!Math::is_equal_approx_ratio(a.elements[i][j], b.elements[i][j], p_epsilon)) {
return false;
+ }
}
}
@@ -583,11 +568,11 @@ bool Basis::is_equal_approx_ratio(const Basis &a, const Basis &b, real_t p_epsil
}
bool Basis::operator==(const Basis &p_matrix) const {
-
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
- if (elements[i][j] != p_matrix.elements[i][j])
+ if (elements[i][j] != p_matrix.elements[i][j]) {
return false;
+ }
}
}
@@ -595,19 +580,16 @@ bool Basis::operator==(const Basis &p_matrix) const {
}
bool Basis::operator!=(const Basis &p_matrix) const {
-
return (!(*this == p_matrix));
}
Basis::operator String() const {
-
String mtx;
for (int i = 0; i < 3; i++) {
-
for (int j = 0; j < 3; j++) {
-
- if (i != 0 || j != 0)
+ if (i != 0 || j != 0) {
mtx += ", ";
+ }
mtx += rtos(elements[i][j]);
}
@@ -617,7 +599,6 @@ Basis::operator String() const {
}
Quat Basis::get_quat() const {
-
#ifdef MATH_CHECKS
ERR_FAIL_COND_V_MSG(!is_rotation(), Quat(), "Basis must be normalized in order to be casted to a Quaternion. Use get_rotation_quat() or call orthonormalized() instead.");
#endif
@@ -681,35 +662,33 @@ static const Basis _ortho_bases[24] = {
};
int Basis::get_orthogonal_index() const {
-
//could be sped up if i come up with a way
Basis orth = *this;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
-
real_t v = orth[i][j];
- if (v > 0.5)
+ if (v > 0.5) {
v = 1.0;
- else if (v < -0.5)
+ } else if (v < -0.5) {
v = -1.0;
- else
+ } else {
v = 0;
+ }
orth[i][j] = v;
}
}
for (int i = 0; i < 24; i++) {
-
- if (_ortho_bases[i] == orth)
+ if (_ortho_bases[i] == orth) {
return i;
+ }
}
return 0;
}
void Basis::set_orthogonal_index(int p_index) {
-
//there only exist 24 orthogonal bases in r3
ERR_FAIL_INDEX(p_index, 24);
@@ -783,7 +762,9 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
real_t s = Math::sqrt((elements[1][2] - elements[2][1]) * (elements[1][2] - elements[2][1]) + (elements[2][0] - elements[0][2]) * (elements[2][0] - elements[0][2]) + (elements[0][1] - elements[1][0]) * (elements[0][1] - elements[1][0])); // s=|axis||sin(angle)|, used to normalise
angle = Math::acos((elements[0][0] + elements[1][1] + elements[2][2] - 1) / 2);
- if (angle < 0) s = -s;
+ if (angle < 0) {
+ s = -s;
+ }
x = (elements[2][1] - elements[1][2]) / s;
y = (elements[0][2] - elements[2][0]) / s;
z = (elements[1][0] - elements[0][1]) / s;
@@ -793,7 +774,6 @@ void Basis::get_axis_angle(Vector3 &r_axis, real_t &r_angle) const {
}
void Basis::set_quat(const Quat &p_quat) {
-
real_t d = p_quat.length_squared();
real_t s = 2.0 / d;
real_t xs = p_quat.x * s, ys = p_quat.y * s, zs = p_quat.z * s;
@@ -865,7 +845,6 @@ void Basis::set_diagonal(const Vector3 &p_diag) {
}
Basis Basis::slerp(const Basis &target, const real_t &t) const {
-
//consider scale
Quat from(*this);
Quat to(target);
@@ -877,3 +856,113 @@ Basis Basis::slerp(const Basis &target, const real_t &t) const {
return b;
}
+
+void Basis::rotate_sh(real_t *p_values) {
+ // code by John Hable
+ // http://filmicworlds.com/blog/simple-and-fast-spherical-harmonic-rotation/
+ // this code is Public Domain
+
+ const static real_t s_c3 = 0.94617469575; // (3*sqrt(5))/(4*sqrt(pi))
+ const static real_t s_c4 = -0.31539156525; // (-sqrt(5))/(4*sqrt(pi))
+ const static real_t s_c5 = 0.54627421529; // (sqrt(15))/(4*sqrt(pi))
+
+ const static real_t s_c_scale = 1.0 / 0.91529123286551084;
+ const static real_t s_c_scale_inv = 0.91529123286551084;
+
+ const static real_t s_rc2 = 1.5853309190550713 * s_c_scale;
+ const static real_t s_c4_div_c3 = s_c4 / s_c3;
+ const static real_t s_c4_div_c3_x2 = (s_c4 / s_c3) * 2.0;
+
+ const static real_t s_scale_dst2 = s_c3 * s_c_scale_inv;
+ const static real_t s_scale_dst4 = s_c5 * s_c_scale_inv;
+
+ real_t src[9] = { p_values[0], p_values[1], p_values[2], p_values[3], p_values[4], p_values[5], p_values[6], p_values[7], p_values[8] };
+
+ real_t m00 = elements[0][0];
+ real_t m01 = elements[0][1];
+ real_t m02 = elements[0][2];
+ real_t m10 = elements[1][0];
+ real_t m11 = elements[1][1];
+ real_t m12 = elements[1][2];
+ real_t m20 = elements[2][0];
+ real_t m21 = elements[2][1];
+ real_t m22 = elements[2][2];
+
+ p_values[0] = src[0];
+ p_values[1] = m11 * src[1] - m12 * src[2] + m10 * src[3];
+ p_values[2] = -m21 * src[1] + m22 * src[2] - m20 * src[3];
+ p_values[3] = m01 * src[1] - m02 * src[2] + m00 * src[3];
+
+ real_t sh0 = src[7] + src[8] + src[8] - src[5];
+ real_t sh1 = src[4] + s_rc2 * src[6] + src[7] + src[8];
+ real_t sh2 = src[4];
+ real_t sh3 = -src[7];
+ real_t sh4 = -src[5];
+
+ // Rotations. R0 and R1 just use the raw matrix columns
+ real_t r2x = m00 + m01;
+ real_t r2y = m10 + m11;
+ real_t r2z = m20 + m21;
+
+ real_t r3x = m00 + m02;
+ real_t r3y = m10 + m12;
+ real_t r3z = m20 + m22;
+
+ real_t r4x = m01 + m02;
+ real_t r4y = m11 + m12;
+ real_t r4z = m21 + m22;
+
+ // dense matrix multiplication one column at a time
+
+ // column 0
+ real_t sh0_x = sh0 * m00;
+ real_t sh0_y = sh0 * m10;
+ real_t d0 = sh0_x * m10;
+ real_t d1 = sh0_y * m20;
+ real_t d2 = sh0 * (m20 * m20 + s_c4_div_c3);
+ real_t d3 = sh0_x * m20;
+ real_t d4 = sh0_x * m00 - sh0_y * m10;
+
+ // column 1
+ real_t sh1_x = sh1 * m02;
+ real_t sh1_y = sh1 * m12;
+ d0 += sh1_x * m12;
+ d1 += sh1_y * m22;
+ d2 += sh1 * (m22 * m22 + s_c4_div_c3);
+ d3 += sh1_x * m22;
+ d4 += sh1_x * m02 - sh1_y * m12;
+
+ // column 2
+ real_t sh2_x = sh2 * r2x;
+ real_t sh2_y = sh2 * r2y;
+ d0 += sh2_x * r2y;
+ d1 += sh2_y * r2z;
+ d2 += sh2 * (r2z * r2z + s_c4_div_c3_x2);
+ d3 += sh2_x * r2z;
+ d4 += sh2_x * r2x - sh2_y * r2y;
+
+ // column 3
+ real_t sh3_x = sh3 * r3x;
+ real_t sh3_y = sh3 * r3y;
+ d0 += sh3_x * r3y;
+ d1 += sh3_y * r3z;
+ d2 += sh3 * (r3z * r3z + s_c4_div_c3_x2);
+ d3 += sh3_x * r3z;
+ d4 += sh3_x * r3x - sh3_y * r3y;
+
+ // column 4
+ real_t sh4_x = sh4 * r4x;
+ real_t sh4_y = sh4 * r4y;
+ d0 += sh4_x * r4y;
+ d1 += sh4_y * r4z;
+ d2 += sh4 * (r4z * r4z + s_c4_div_c3_x2);
+ d3 += sh4_x * r4z;
+ d4 += sh4_x * r4x - sh4_y * r4y;
+
+ // extra multipliers
+ p_values[4] = d0;
+ p_values[5] = -d1;
+ p_values[6] = d2 * s_scale_dst2;
+ p_values[7] = -d3;
+ p_values[8] = d4 * s_scale_dst4;
+}
diff --git a/core/math/basis.h b/core/math/basis.h
index 0261cf67c6..d870a6b099 100644
--- a/core/math/basis.h
+++ b/core/math/basis.h
@@ -39,11 +39,9 @@ public:
Vector3 elements[3];
_FORCE_INLINE_ const Vector3 &operator[](int axis) const {
-
return elements[axis];
}
_FORCE_INLINE_ Vector3 &operator[](int axis) {
-
return elements[axis];
}
@@ -159,13 +157,13 @@ public:
bool is_rotation() const;
Basis slerp(const Basis &target, const real_t &t) const;
+ void rotate_sh(real_t *p_values);
operator String() const;
/* create / set */
_FORCE_INLINE_ void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
-
elements[0][0] = xx;
elements[0][1] = xy;
elements[0][2] = xz;
@@ -177,18 +175,15 @@ public:
elements[2][2] = zz;
}
_FORCE_INLINE_ void set(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z) {
-
set_axis(0, p_x);
set_axis(1, p_y);
set_axis(2, p_z);
}
_FORCE_INLINE_ Vector3 get_column(int i) const {
-
return Vector3(elements[0][i], elements[1][i], elements[2][i]);
}
_FORCE_INLINE_ Vector3 get_row(int i) const {
-
return Vector3(elements[i][0], elements[i][1], elements[i][2]);
}
_FORCE_INLINE_ Vector3 get_main_diagonal() const {
@@ -220,7 +215,6 @@ public:
elements[0].z * m[0].z + elements[1].z * m[1].z + elements[2].z * m[2].z);
}
Basis(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz) {
-
set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
}
@@ -248,7 +242,6 @@ public:
}
_FORCE_INLINE_ Basis() {
-
elements[0][0] = 1;
elements[0][1] = 0;
elements[0][2] = 0;
@@ -262,7 +255,6 @@ public:
};
_FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) {
-
set(
p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]),
p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]),
@@ -270,7 +262,6 @@ _FORCE_INLINE_ void Basis::operator*=(const Basis &p_matrix) {
}
_FORCE_INLINE_ Basis Basis::operator*(const Basis &p_matrix) const {
-
return Basis(
p_matrix.tdotx(elements[0]), p_matrix.tdoty(elements[0]), p_matrix.tdotz(elements[0]),
p_matrix.tdotx(elements[1]), p_matrix.tdoty(elements[1]), p_matrix.tdotz(elements[1]),
@@ -278,49 +269,42 @@ _FORCE_INLINE_ Basis Basis::operator*(const Basis &p_matrix) const {
}
_FORCE_INLINE_ void Basis::operator+=(const Basis &p_matrix) {
-
elements[0] += p_matrix.elements[0];
elements[1] += p_matrix.elements[1];
elements[2] += p_matrix.elements[2];
}
_FORCE_INLINE_ 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) {
-
elements[0] -= p_matrix.elements[0];
elements[1] -= p_matrix.elements[1];
elements[2] -= p_matrix.elements[2];
}
_FORCE_INLINE_ 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) {
-
elements[0] *= p_val;
elements[1] *= p_val;
elements[2] *= p_val;
}
_FORCE_INLINE_ Basis Basis::operator*(real_t p_val) const {
-
Basis ret(*this);
ret *= p_val;
return ret;
}
Vector3 Basis::xform(const Vector3 &p_vector) const {
-
return Vector3(
elements[0].dot(p_vector),
elements[1].dot(p_vector),
@@ -328,7 +312,6 @@ Vector3 Basis::xform(const Vector3 &p_vector) const {
}
Vector3 Basis::xform_inv(const Vector3 &p_vector) const {
-
return Vector3(
(elements[0][0] * p_vector.x) + (elements[1][0] * p_vector.y) + (elements[2][0] * p_vector.z),
(elements[0][1] * p_vector.x) + (elements[1][1] * p_vector.y) + (elements[2][1] * p_vector.z),
@@ -336,7 +319,6 @@ Vector3 Basis::xform_inv(const Vector3 &p_vector) const {
}
real_t Basis::determinant() const {
-
return elements[0][0] * (elements[1][1] * elements[2][2] - elements[2][1] * elements[1][2]) -
elements[1][0] * (elements[0][1] * elements[2][2] - elements[2][1] * elements[0][2]) +
elements[2][0] * (elements[0][1] * elements[1][2] - elements[1][1] * elements[0][2]);
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index c36070e47f..22ab83f358 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -33,30 +33,38 @@
#include "core/math/math_funcs.h"
#include "core/print_string.h"
-void CameraMatrix::set_identity() {
+float CameraMatrix::determinant() const {
+ return matrix[0][3] * matrix[1][2] * matrix[2][1] * matrix[3][0] - matrix[0][2] * matrix[1][3] * matrix[2][1] * matrix[3][0] -
+ matrix[0][3] * matrix[1][1] * matrix[2][2] * matrix[3][0] + matrix[0][1] * matrix[1][3] * matrix[2][2] * matrix[3][0] +
+ matrix[0][2] * matrix[1][1] * matrix[2][3] * matrix[3][0] - matrix[0][1] * matrix[1][2] * matrix[2][3] * matrix[3][0] -
+ matrix[0][3] * matrix[1][2] * matrix[2][0] * matrix[3][1] + matrix[0][2] * matrix[1][3] * matrix[2][0] * matrix[3][1] +
+ matrix[0][3] * matrix[1][0] * matrix[2][2] * matrix[3][1] - matrix[0][0] * matrix[1][3] * matrix[2][2] * matrix[3][1] -
+ matrix[0][2] * matrix[1][0] * matrix[2][3] * matrix[3][1] + matrix[0][0] * matrix[1][2] * matrix[2][3] * matrix[3][1] +
+ matrix[0][3] * matrix[1][1] * matrix[2][0] * matrix[3][2] - matrix[0][1] * matrix[1][3] * matrix[2][0] * matrix[3][2] -
+ matrix[0][3] * matrix[1][0] * matrix[2][1] * matrix[3][2] + matrix[0][0] * matrix[1][3] * matrix[2][1] * matrix[3][2] +
+ matrix[0][1] * matrix[1][0] * matrix[2][3] * matrix[3][2] - matrix[0][0] * matrix[1][1] * matrix[2][3] * matrix[3][2] -
+ matrix[0][2] * matrix[1][1] * matrix[2][0] * matrix[3][3] + matrix[0][1] * matrix[1][2] * matrix[2][0] * matrix[3][3] +
+ matrix[0][2] * matrix[1][0] * matrix[2][1] * matrix[3][3] - matrix[0][0] * matrix[1][2] * matrix[2][1] * matrix[3][3] -
+ matrix[0][1] * matrix[1][0] * matrix[2][2] * matrix[3][3] + matrix[0][0] * matrix[1][1] * matrix[2][2] * matrix[3][3];
+}
+void CameraMatrix::set_identity() {
for (int i = 0; i < 4; i++) {
-
for (int j = 0; j < 4; j++) {
-
matrix[i][j] = (i == j) ? 1 : 0;
}
}
}
void CameraMatrix::set_zero() {
-
for (int i = 0; i < 4; i++) {
-
for (int j = 0; j < 4; j++) {
-
matrix[i][j] = 0;
}
}
}
Plane CameraMatrix::xform4(const Plane &p_vec4) const {
-
Plane ret;
ret.normal.x = matrix[0][0] * p_vec4.normal.x + matrix[1][0] * p_vec4.normal.y + matrix[2][0] * p_vec4.normal.z + matrix[3][0] * p_vec4.d;
@@ -67,7 +75,6 @@ Plane CameraMatrix::xform4(const Plane &p_vec4) const {
}
void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov) {
-
if (p_flip_fov) {
p_fovy_degrees = get_fovy(p_fovy_degrees, 1.0 / p_aspect);
}
@@ -109,18 +116,18 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_
left = -xmax + frustumshift;
right = xmax + frustumshift;
modeltranslation = p_intraocular_dist / 2.0;
- }; break;
+ } break;
case 2: { // right eye
left = -xmax - frustumshift;
right = xmax - frustumshift;
modeltranslation = -p_intraocular_dist / 2.0;
- }; break;
+ } break;
default: { // mono, should give the same result as set_perspective(p_fovy_degrees,p_aspect,p_z_near,p_z_far,p_flip_fov)
left = -xmax;
right = xmax;
modeltranslation = 0.0;
- }; break;
- };
+ } break;
+ }
set_frustum(left, right, -ymax, ymax, p_z_near, p_z_far);
@@ -150,17 +157,16 @@ void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_
switch (p_eye) {
case 1: { // left eye
set_frustum(-f2 * p_z_near, f1 * p_z_near, -f3 * p_z_near, f3 * p_z_near, p_z_near, p_z_far);
- }; break;
+ } break;
case 2: { // right eye
set_frustum(-f1 * p_z_near, f2 * p_z_near, -f3 * p_z_near, f3 * p_z_near, p_z_near, p_z_far);
- }; break;
+ } break;
default: { // mono, does not apply here!
- }; break;
- };
-};
+ } break;
+ }
+}
void CameraMatrix::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar) {
-
set_identity();
matrix[0][0] = 2.0 / (p_right - p_left);
@@ -173,7 +179,6 @@ void CameraMatrix::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom
}
void CameraMatrix::set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov) {
-
if (!p_flip_fov) {
p_size *= p_aspect;
}
@@ -182,7 +187,6 @@ void CameraMatrix::set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear
}
void CameraMatrix::set_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far) {
-
ERR_FAIL_COND(p_right <= p_left);
ERR_FAIL_COND(p_top <= p_bottom);
ERR_FAIL_COND(p_far <= p_near);
@@ -223,7 +227,6 @@ void CameraMatrix::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset,
}
real_t CameraMatrix::get_z_far() const {
-
const real_t *matrix = (const real_t *)this->matrix;
Plane new_plane = Plane(matrix[3] - matrix[2],
matrix[7] - matrix[6],
@@ -235,8 +238,8 @@ real_t CameraMatrix::get_z_far() const {
return new_plane.d;
}
-real_t CameraMatrix::get_z_near() const {
+real_t CameraMatrix::get_z_near() const {
const real_t *matrix = (const real_t *)this->matrix;
Plane new_plane = Plane(matrix[3] + matrix[2],
matrix[7] + matrix[6],
@@ -248,7 +251,6 @@ real_t CameraMatrix::get_z_near() const {
}
Vector2 CameraMatrix::get_viewport_half_extents() const {
-
const real_t *matrix = (const real_t *)this->matrix;
///////--- Near Plane ---///////
Plane near_plane = Plane(matrix[3] + matrix[2],
@@ -277,7 +279,6 @@ Vector2 CameraMatrix::get_viewport_half_extents() const {
}
void CameraMatrix::get_far_plane_size(real_t &r_width, real_t &r_height) const {
-
const real_t *matrix = (const real_t *)this->matrix;
///////--- Far Plane ---///////
Plane far_plane = Plane(matrix[3] - matrix[2],
@@ -307,7 +308,6 @@ void CameraMatrix::get_far_plane_size(real_t &r_width, real_t &r_height) const {
}
bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8points) const {
-
Vector<Plane> planes = get_projection_planes(Transform());
const Planes intersections[8][3] = {
{ PLANE_FAR, PLANE_LEFT, PLANE_TOP },
@@ -321,7 +321,6 @@ bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8point
};
for (int i = 0; i < 8; i++) {
-
Vector3 point;
bool res = planes[intersections[i][0]].intersect_3(planes[intersections[i][1]], planes[intersections[i][2]], &point);
ERR_FAIL_COND_V(!res, false);
@@ -332,7 +331,6 @@ bool CameraMatrix::get_endpoints(const Transform &p_transform, Vector3 *p_8point
}
Vector<Plane> CameraMatrix::get_projection_planes(const Transform &p_transform) const {
-
/** Fast Plane Extraction from combined modelview/projection matrices.
* References:
* https://web.archive.org/web/20011221205252/http://www.markmorley.com/opengl/frustumculling.html
@@ -415,14 +413,12 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform &p_transform)
}
CameraMatrix CameraMatrix::inverse() const {
-
CameraMatrix cm = *this;
cm.invert();
return cm;
}
void CameraMatrix::invert() {
-
int i, j, k;
int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */
real_t pvt_val; /* Value of current pivot element */
@@ -473,20 +469,26 @@ void CameraMatrix::invert() {
/** Divide column by minus pivot value **/
for (i = 0; i < 4; i++) {
- if (i != k) matrix[i][k] /= (-pvt_val);
+ if (i != k) {
+ matrix[i][k] /= (-pvt_val);
+ }
}
/** Reduce the matrix **/
for (i = 0; i < 4; i++) {
hold = matrix[i][k];
for (j = 0; j < 4; j++) {
- if (i != k && j != k) matrix[i][j] += hold * matrix[k][j];
+ if (i != k && j != k) {
+ matrix[i][j] += hold * matrix[k][j];
+ }
}
}
/** Divide row by pivot **/
for (j = 0; j < 4; j++) {
- if (j != k) matrix[k][j] /= pvt_val;
+ if (j != k) {
+ matrix[k][j] /= pvt_val;
+ }
}
/** Replace pivot by reciprocal (at last we can touch it). **/
@@ -506,12 +508,13 @@ void CameraMatrix::invert() {
}
j = pvt_i[k]; /* Columns to swap correspond to pivot ROW */
- if (j != k) /* If columns are different */
+ if (j != k) { /* If columns are different */
for (i = 0; i < 4; i++) {
hold = matrix[i][k];
matrix[i][k] = -matrix[i][j];
matrix[i][j] = hold;
}
+ }
}
}
@@ -522,19 +525,18 @@ void CameraMatrix::flip_y() {
}
CameraMatrix::CameraMatrix() {
-
set_identity();
}
CameraMatrix CameraMatrix::operator*(const CameraMatrix &p_matrix) const {
-
CameraMatrix 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++)
+ for (int k = 0; k < 4; k++) {
ab += matrix[k][i] * p_matrix.matrix[j][k];
+ }
new_matrix.matrix[j][i] = ab;
}
}
@@ -543,7 +545,6 @@ CameraMatrix CameraMatrix::operator*(const CameraMatrix &p_matrix) const {
}
void CameraMatrix::set_depth_correction(bool p_flip_y) {
-
real_t *m = &matrix[0][0];
m[0] = 1;
@@ -565,7 +566,6 @@ void CameraMatrix::set_depth_correction(bool p_flip_y) {
}
void CameraMatrix::set_light_bias() {
-
real_t *m = &matrix[0][0];
m[0] = 0.5;
@@ -587,7 +587,6 @@ void CameraMatrix::set_light_bias() {
}
void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) {
-
real_t *m = &matrix[0][0];
m[0] = p_rect.size.width;
@@ -609,30 +608,28 @@ void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) {
}
CameraMatrix::operator String() const {
-
String str;
- for (int i = 0; i < 4; i++)
- for (int j = 0; j < 4; j++)
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
str += String((j > 0) ? ", " : "\n") + rtos(matrix[i][j]);
+ }
+ }
return str;
}
real_t CameraMatrix::get_aspect() const {
-
Vector2 vp_he = get_viewport_half_extents();
return vp_he.x / vp_he.y;
}
int CameraMatrix::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);
}
bool CameraMatrix::is_orthogonal() const {
-
return matrix[3][3] == 1.0;
}
@@ -660,7 +657,6 @@ real_t CameraMatrix::get_fov() const {
}
void CameraMatrix::make_scale(const Vector3 &p_scale) {
-
set_identity();
matrix[0][0] = p_scale.x;
matrix[1][1] = p_scale.y;
@@ -668,7 +664,6 @@ void CameraMatrix::make_scale(const Vector3 &p_scale) {
}
void CameraMatrix::scale_translate_to_fit(const AABB &p_aabb) {
-
Vector3 min = p_aabb.position;
Vector3 max = p_aabb.position + p_aabb.size;
@@ -694,7 +689,6 @@ void CameraMatrix::scale_translate_to_fit(const AABB &p_aabb) {
}
CameraMatrix::operator Transform() const {
-
Transform tr;
const real_t *m = &matrix[0][0];
@@ -718,7 +712,6 @@ CameraMatrix::operator Transform() const {
}
CameraMatrix::CameraMatrix(const Transform &p_transform) {
-
const Transform &tr = p_transform;
real_t *m = &matrix[0][0];
diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h
index c10193bc84..49fdecae02 100644
--- a/core/math/camera_matrix.h
+++ b/core/math/camera_matrix.h
@@ -35,7 +35,6 @@
#include "core/math/transform.h"
struct CameraMatrix {
-
enum Planes {
PLANE_NEAR,
PLANE_FAR,
@@ -47,6 +46,7 @@ struct CameraMatrix {
real_t matrix[4][4];
+ float determinant() const;
void set_identity();
void set_zero();
void set_light_bias();
@@ -61,7 +61,6 @@ struct CameraMatrix {
void set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov = false);
static real_t get_fovy(real_t p_fovx, real_t p_aspect) {
-
return Math::rad2deg(Math::atan(p_aspect * Math::tan(Math::deg2rad(p_fovx) * 0.5)) * 2.0);
}
@@ -115,7 +114,6 @@ struct CameraMatrix {
};
Vector3 CameraMatrix::xform(const Vector3 &p_vec3) const {
-
Vector3 ret;
ret.x = matrix[0][0] * p_vec3.x + matrix[1][0] * p_vec3.y + matrix[2][0] * p_vec3.z + matrix[3][0];
ret.y = matrix[0][1] * p_vec3.x + matrix[1][1] * p_vec3.y + matrix[2][1] * p_vec3.z + matrix[3][1];
diff --git a/core/math/delaunay.h b/core/math/delaunay_2d.h
index 29f84210d2..d637671686 100644
--- a/core/math/delaunay.h
+++ b/core/math/delaunay_2d.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* delaunay.h */
+/* delaunay_2d.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,39 +28,35 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef DELAUNAY_H
-#define DELAUNAY_H
+#ifndef DELAUNAY_2D_H
+#define DELAUNAY_2D_H
#include "core/math/rect2.h"
class Delaunay2D {
public:
struct Triangle {
-
int points[3];
- bool bad;
- Triangle() { bad = false; }
+ bool bad = false;
+ Triangle() {}
Triangle(int p_a, int p_b, int p_c) {
points[0] = p_a;
points[1] = p_b;
points[2] = p_c;
- bad = false;
}
};
struct Edge {
int edge[2];
- bool bad;
- Edge() { bad = false; }
+ bool bad = false;
+ Edge() {}
Edge(int p_a, int p_b) {
- bad = false;
edge[0] = p_a;
edge[1] = p_b;
}
};
static bool circum_circle_contains(const Vector<Vector2> &p_vertices, const Triangle &p_triangle, int p_vertex) {
-
Vector2 p1 = p_vertices[p_triangle.points[0]];
Vector2 p2 = p_vertices[p_triangle.points[1]];
Vector2 p3 = p_vertices[p_triangle.points[2]];
@@ -92,7 +88,6 @@ public:
}
static Vector<Triangle> triangulate(const Vector<Vector2> &p_points) {
-
Vector<Vector2> points = p_points;
Vector<Triangle> triangles;
@@ -115,9 +110,6 @@ public:
triangles.push_back(Triangle(p_points.size() + 0, p_points.size() + 1, p_points.size() + 2));
for (int i = 0; i < p_points.size(); i++) {
- //std::cout << "Traitement du point " << *p << std::endl;
- //std::cout << "_triangles contains " << _triangles.size() << " elements" << std::endl;
-
Vector<Edge> polygon;
for (int j = 0; j < triangles.size(); j++) {
@@ -146,7 +138,6 @@ public:
}
for (int j = 0; j < polygon.size(); j++) {
-
if (polygon[j].bad) {
continue;
}
@@ -172,4 +163,4 @@ public:
}
};
-#endif // DELAUNAY_H
+#endif // DELAUNAY_2D_H
diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h
new file mode 100644
index 0000000000..014b4c4621
--- /dev/null
+++ b/core/math/delaunay_3d.h
@@ -0,0 +1,408 @@
+/*************************************************************************/
+/* delaunay_3d.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef DELAUNAY_3D_H
+#define DELAUNAY_3D_H
+
+#include "core/local_vector.h"
+#include "core/math/aabb.h"
+#include "core/math/camera_matrix.h"
+#include "core/math/vector3.h"
+#include "core/oa_hash_map.h"
+#include "core/os/file_access.h"
+#include "core/print_string.h"
+#include "core/variant.h"
+#include "core/vector.h"
+
+#include "thirdparty/misc/r128.h"
+
+class Delaunay3D {
+ struct Simplex;
+
+ enum {
+ ACCEL_GRID_SIZE = 16
+ };
+ struct GridPos {
+ Vector3i pos;
+ List<Simplex *>::Element *E = nullptr;
+ };
+
+ struct Simplex {
+ uint32_t points[4];
+ R128 circum_center_x;
+ R128 circum_center_y;
+ R128 circum_center_z;
+ R128 circum_r2;
+ LocalVector<GridPos> grid_positions;
+ List<Simplex *>::Element *SE = nullptr;
+
+ _FORCE_INLINE_ Simplex() {}
+ _FORCE_INLINE_ Simplex(uint32_t p_a, uint32_t p_b, uint32_t p_c, uint32_t p_d) {
+ points[0] = p_a;
+ points[1] = p_b;
+ points[2] = p_c;
+ points[3] = p_d;
+ }
+ };
+
+ struct Triangle {
+ uint32_t triangle[3];
+ bool bad = false;
+ _FORCE_INLINE_ bool operator==(const Triangle &p_triangle) const {
+ return triangle[0] == p_triangle.triangle[0] && triangle[1] == p_triangle.triangle[1] && triangle[2] == p_triangle.triangle[2];
+ }
+
+ _FORCE_INLINE_ Triangle() {}
+ _FORCE_INLINE_ Triangle(uint32_t p_a, uint32_t p_b, uint32_t p_c) {
+ if (p_a > p_b) {
+ SWAP(p_a, p_b);
+ }
+ if (p_b > p_c) {
+ SWAP(p_b, p_c);
+ }
+ if (p_a > p_b) {
+ SWAP(p_a, p_b);
+ }
+
+ triangle[0] = p_a;
+ triangle[1] = p_b;
+ triangle[2] = p_c;
+ }
+ };
+
+ struct TriangleHasher {
+ _FORCE_INLINE_ static uint32_t hash(const Triangle &p_triangle) {
+ uint32_t h = hash_djb2_one_32(p_triangle.triangle[0]);
+ h = hash_djb2_one_32(p_triangle.triangle[1], h);
+ return hash_djb2_one_32(p_triangle.triangle[2], h);
+ }
+ };
+
+ _FORCE_INLINE_ static void circum_sphere_compute(const Vector3 *p_points, Simplex *p_simplex) {
+ // the only part in the algorithm where there may be precision errors is this one, so ensure that
+ // we do it as maximum precision as possible
+
+ R128 v0_x = p_points[p_simplex->points[0]].x;
+ R128 v0_y = p_points[p_simplex->points[0]].y;
+ R128 v0_z = p_points[p_simplex->points[0]].z;
+ R128 v1_x = p_points[p_simplex->points[1]].x;
+ R128 v1_y = p_points[p_simplex->points[1]].y;
+ R128 v1_z = p_points[p_simplex->points[1]].z;
+ R128 v2_x = p_points[p_simplex->points[2]].x;
+ R128 v2_y = p_points[p_simplex->points[2]].y;
+ R128 v2_z = p_points[p_simplex->points[2]].z;
+ R128 v3_x = p_points[p_simplex->points[3]].x;
+ R128 v3_y = p_points[p_simplex->points[3]].y;
+ R128 v3_z = p_points[p_simplex->points[3]].z;
+
+ //Create the rows of our "unrolled" 3x3 matrix
+ R128 row1_x = v1_x - v0_x;
+ R128 row1_y = v1_y - v0_y;
+ R128 row1_z = v1_z - v0_z;
+
+ R128 row2_x = v2_x - v0_x;
+ R128 row2_y = v2_y - v0_y;
+ R128 row2_z = v2_z - v0_z;
+
+ R128 row3_x = v3_x - v0_x;
+ R128 row3_y = v3_y - v0_y;
+ R128 row3_z = v3_z - v0_z;
+
+ R128 sq_lenght1 = row1_x * row1_x + row1_y * row1_y + row1_z * row1_z;
+ R128 sq_lenght2 = row2_x * row2_x + row2_y * row2_y + row2_z * row2_z;
+ R128 sq_lenght3 = row3_x * row3_x + row3_y * row3_y + row3_z * row3_z;
+
+ //Compute the determinant of said matrix
+ R128 determinant = row1_x * (row2_y * row3_z - row3_y * row2_z) - row2_x * (row1_y * row3_z - row3_y * row1_z) + row3_x * (row1_y * row2_z - row2_y * row1_z);
+
+ // Compute the volume of the tetrahedron, and precompute a scalar quantity for re-use in the formula
+ R128 volume = determinant / R128(6.f);
+ R128 i12volume = R128(1.f) / (volume * R128(12.f));
+
+ R128 center_x = v0_x + i12volume * ((row2_y * row3_z - row3_y * row2_z) * sq_lenght1 - (row1_y * row3_z - row3_y * row1_z) * sq_lenght2 + (row1_y * row2_z - row2_y * row1_z) * sq_lenght3);
+ R128 center_y = v0_y + i12volume * (-(row2_x * row3_z - row3_x * row2_z) * sq_lenght1 + (row1_x * row3_z - row3_x * row1_z) * sq_lenght2 - (row1_x * row2_z - row2_x * row1_z) * sq_lenght3);
+ R128 center_z = v0_z + i12volume * ((row2_x * row3_y - row3_x * row2_y) * sq_lenght1 - (row1_x * row3_y - row3_x * row1_y) * sq_lenght2 + (row1_x * row2_y - row2_x * row1_y) * sq_lenght3);
+
+ //Once we know the center, the radius is clearly the distance to any vertex
+
+ R128 rel1_x = center_x - v0_x;
+ R128 rel1_y = center_y - v0_y;
+ R128 rel1_z = center_z - v0_z;
+
+ R128 radius1 = rel1_x * rel1_x + rel1_y * rel1_y + rel1_z * rel1_z;
+
+ p_simplex->circum_center_x = center_x;
+ p_simplex->circum_center_y = center_y;
+ p_simplex->circum_center_z = center_z;
+ p_simplex->circum_r2 = radius1;
+ }
+
+ _FORCE_INLINE_ static bool simplex_contains(const Vector3 *p_points, const Simplex &p_simplex, uint32_t p_vertex) {
+ R128 v_x = p_points[p_vertex].x;
+ R128 v_y = p_points[p_vertex].y;
+ R128 v_z = p_points[p_vertex].z;
+
+ R128 rel2_x = p_simplex.circum_center_x - v_x;
+ R128 rel2_y = p_simplex.circum_center_y - v_y;
+ R128 rel2_z = p_simplex.circum_center_z - v_z;
+
+ R128 radius2 = rel2_x * rel2_x + rel2_y * rel2_y + rel2_z * rel2_z;
+
+ return radius2 < (p_simplex.circum_r2 - R128(0.00001));
+ }
+
+ static bool simplex_is_coplanar(const Vector3 *p_points, const Simplex &p_simplex) {
+ Plane p(p_points[p_simplex.points[0]], p_points[p_simplex.points[1]], p_points[p_simplex.points[2]]);
+ if (ABS(p.distance_to(p_points[p_simplex.points[3]])) < CMP_EPSILON) {
+ return true;
+ }
+
+ CameraMatrix cm;
+
+ cm.matrix[0][0] = p_points[p_simplex.points[0]].x;
+ cm.matrix[0][1] = p_points[p_simplex.points[1]].x;
+ cm.matrix[0][2] = p_points[p_simplex.points[2]].x;
+ cm.matrix[0][3] = p_points[p_simplex.points[3]].x;
+
+ cm.matrix[1][0] = p_points[p_simplex.points[0]].y;
+ cm.matrix[1][1] = p_points[p_simplex.points[1]].y;
+ cm.matrix[1][2] = p_points[p_simplex.points[2]].y;
+ cm.matrix[1][3] = p_points[p_simplex.points[3]].y;
+
+ cm.matrix[2][0] = p_points[p_simplex.points[0]].z;
+ cm.matrix[2][1] = p_points[p_simplex.points[1]].z;
+ cm.matrix[2][2] = p_points[p_simplex.points[2]].z;
+ cm.matrix[2][3] = p_points[p_simplex.points[3]].z;
+
+ cm.matrix[3][0] = 1.0;
+ cm.matrix[3][1] = 1.0;
+ cm.matrix[3][2] = 1.0;
+ cm.matrix[3][3] = 1.0;
+
+ return ABS(cm.determinant()) <= CMP_EPSILON;
+ }
+
+public:
+ struct OutputSimplex {
+ uint32_t points[4];
+ };
+
+ static Vector<OutputSimplex> tetrahedralize(const Vector<Vector3> &p_points) {
+ uint32_t point_count = p_points.size();
+ Vector3 *points = (Vector3 *)memalloc(sizeof(Vector3) * (point_count + 4));
+
+ {
+ const Vector3 *src_points = p_points.ptr();
+ AABB rect;
+ for (uint32_t i = 0; i < point_count; i++) {
+ Vector3 point = src_points[i];
+ if (i == 0) {
+ rect.position = point;
+ } else {
+ rect.expand_to(point);
+ }
+ points[i] = point;
+ }
+
+ for (uint32_t i = 0; i < point_count; i++) {
+ points[i] = (points[i] - rect.position) / rect.size;
+ }
+
+ float delta_max = Math::sqrt(2.0) * 20.0;
+ Vector3 center = Vector3(0.5, 0.5, 0.5);
+
+ // any simplex that contains everything is good
+ points[point_count + 0] = center + Vector3(0, 1, 0) * delta_max;
+ points[point_count + 1] = center + Vector3(0, -1, 1) * delta_max;
+ points[point_count + 2] = center + Vector3(1, -1, -1) * delta_max;
+ points[point_count + 3] = center + Vector3(-1, -1, -1) * delta_max;
+ }
+
+ List<Simplex *> acceleration_grid[ACCEL_GRID_SIZE][ACCEL_GRID_SIZE][ACCEL_GRID_SIZE];
+
+ List<Simplex *> simplex_list;
+ {
+ //create root simplex
+ Simplex *root = memnew(Simplex(point_count + 0, point_count + 1, point_count + 2, point_count + 3));
+ root->SE = simplex_list.push_back(root);
+
+ for (uint32_t i = 0; i < ACCEL_GRID_SIZE; i++) {
+ for (uint32_t j = 0; j < ACCEL_GRID_SIZE; j++) {
+ for (uint32_t k = 0; k < ACCEL_GRID_SIZE; k++) {
+ GridPos gp;
+ gp.E = acceleration_grid[i][j][k].push_back(root);
+ gp.pos = Vector3i(i, j, k);
+ root->grid_positions.push_back(gp);
+ }
+ }
+ }
+
+ circum_sphere_compute(points, root);
+ }
+
+ OAHashMap<Triangle, uint32_t, TriangleHasher> triangles_inserted;
+ LocalVector<Triangle> triangles;
+
+ for (uint32_t i = 0; i < point_count; i++) {
+ bool unique = true;
+ for (uint32_t j = i + 1; j < point_count; j++) {
+ if (points[i].is_equal_approx(points[j])) {
+ unique = false;
+ break;
+ }
+ }
+ if (!unique) {
+ continue;
+ }
+
+ Vector3i grid_pos = Vector3i(points[i] * ACCEL_GRID_SIZE);
+ grid_pos.x = CLAMP(grid_pos.x, 0, ACCEL_GRID_SIZE - 1);
+ grid_pos.y = CLAMP(grid_pos.y, 0, ACCEL_GRID_SIZE - 1);
+ grid_pos.z = CLAMP(grid_pos.z, 0, ACCEL_GRID_SIZE - 1);
+
+ for (List<Simplex *>::Element *E = acceleration_grid[grid_pos.x][grid_pos.y][grid_pos.z].front(); E;) {
+ List<Simplex *>::Element *N = E->next(); //may be deleted
+
+ Simplex *simplex = E->get();
+
+ if (simplex_contains(points, *simplex, i)) {
+ static const uint32_t triangle_order[4][3] = {
+ { 0, 1, 2 },
+ { 0, 1, 3 },
+ { 0, 2, 3 },
+ { 1, 2, 3 },
+ };
+
+ for (uint32_t k = 0; k < 4; k++) {
+ Triangle t = Triangle(simplex->points[triangle_order[k][0]], simplex->points[triangle_order[k][1]], simplex->points[triangle_order[k][2]]);
+ uint32_t *p = triangles_inserted.lookup_ptr(t);
+ if (p) {
+ triangles[*p].bad = true;
+ } else {
+ triangles_inserted.insert(t, triangles.size());
+ triangles.push_back(t);
+ }
+ }
+
+ //remove simplex and continue
+ simplex_list.erase(simplex->SE);
+
+ for (uint32_t k = 0; k < simplex->grid_positions.size(); k++) {
+ Vector3i p = simplex->grid_positions[k].pos;
+ acceleration_grid[p.x][p.y][p.z].erase(simplex->grid_positions[k].E);
+ }
+ memdelete(simplex);
+ }
+ E = N;
+ }
+
+ uint32_t good_triangles = 0;
+ for (uint32_t j = 0; j < triangles.size(); j++) {
+ if (triangles[j].bad) {
+ continue;
+ }
+ Simplex *new_simplex = memnew(Simplex(triangles[j].triangle[0], triangles[j].triangle[1], triangles[j].triangle[2], i));
+ circum_sphere_compute(points, new_simplex);
+ new_simplex->SE = simplex_list.push_back(new_simplex);
+ {
+ Vector3 center;
+ center.x = double(new_simplex->circum_center_x);
+ center.y = double(new_simplex->circum_center_y);
+ center.z = double(new_simplex->circum_center_z);
+
+ float radius2 = Math::sqrt(double(new_simplex->circum_r2));
+ radius2 += 0.0001; //
+ Vector3 extents = Vector3(radius2, radius2, radius2);
+ Vector3i from = Vector3i((center - extents) * ACCEL_GRID_SIZE);
+ Vector3i to = Vector3i((center + extents) * ACCEL_GRID_SIZE);
+ from.x = CLAMP(from.x, 0, ACCEL_GRID_SIZE - 1);
+ from.y = CLAMP(from.y, 0, ACCEL_GRID_SIZE - 1);
+ from.z = CLAMP(from.z, 0, ACCEL_GRID_SIZE - 1);
+ to.x = CLAMP(to.x, 0, ACCEL_GRID_SIZE - 1);
+ to.y = CLAMP(to.y, 0, ACCEL_GRID_SIZE - 1);
+ to.z = CLAMP(to.z, 0, ACCEL_GRID_SIZE - 1);
+
+ for (int32_t x = from.x; x <= to.x; x++) {
+ for (int32_t y = from.y; y <= to.y; y++) {
+ for (int32_t z = from.z; z <= to.z; z++) {
+ GridPos gp;
+ gp.pos = Vector3(x, y, z);
+ gp.E = acceleration_grid[x][y][z].push_back(new_simplex);
+ new_simplex->grid_positions.push_back(gp);
+ }
+ }
+ }
+ }
+
+ good_triangles++;
+ }
+
+ //print_line("at point " + itos(i) + "/" + itos(point_count) + " simplices added " + itos(good_triangles) + "/" + itos(simplex_list.size()) + " - triangles: " + itos(triangles.size()));
+ triangles.clear();
+ triangles_inserted.clear();
+ }
+
+ //print_line("end with simplices: " + itos(simplex_list.size()));
+ Vector<OutputSimplex> ret_simplices;
+ ret_simplices.resize(simplex_list.size());
+ OutputSimplex *ret_simplicesw = ret_simplices.ptrw();
+ uint32_t simplices_written = 0;
+
+ for (List<Simplex *>::Element *E = simplex_list.front(); E; E = E->next()) {
+ Simplex *simplex = E->get();
+ bool invalid = false;
+ for (int j = 0; j < 4; j++) {
+ if (simplex->points[j] >= point_count) {
+ invalid = true;
+ break;
+ }
+ }
+ if (invalid || simplex_is_coplanar(points, *simplex)) {
+ memdelete(simplex);
+ continue;
+ }
+
+ ret_simplicesw[simplices_written].points[0] = simplex->points[0];
+ ret_simplicesw[simplices_written].points[1] = simplex->points[1];
+ ret_simplicesw[simplices_written].points[2] = simplex->points[2];
+ ret_simplicesw[simplices_written].points[3] = simplex->points[3];
+ simplices_written++;
+ memdelete(simplex);
+ }
+
+ ret_simplices.resize(simplices_written);
+
+ memfree(points);
+
+ return ret_simplices;
+ }
+};
+
+#endif // DELAUNAY_3D_H
diff --git a/core/math/disjoint_set.h b/core/math/disjoint_set.h
index 32b9875e4c..198f46e111 100644
--- a/core/math/disjoint_set.h
+++ b/core/math/disjoint_set.h
@@ -41,7 +41,6 @@
/* This DisjointSet class uses Find with path compression and Union by rank */
template <typename T, class C = Comparator<T>, class AL = DefaultAllocator>
class DisjointSet {
-
struct Element {
T object;
Element *parent = nullptr;
@@ -103,7 +102,6 @@ typename DisjointSet<T, C, AL>::Element *DisjointSet<T, C, AL>::insert_or_get(T
template <typename T, class C, class AL>
void DisjointSet<T, C, AL>::create_union(T a, T b) {
-
Element *x = insert_or_get(a);
Element *y = insert_or_get(b);
@@ -111,8 +109,9 @@ void DisjointSet<T, C, AL>::create_union(T a, T b) {
Element *y_root = get_parent(y);
// Already in the same set
- if (x_root == y_root)
+ if (x_root == y_root) {
return;
+ }
// Not in the same set, merge
if (x_root->rank < y_root->rank) {
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index 859b9be8c5..db3bf2f830 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -110,25 +110,22 @@ const char *Expression::func_name[Expression::FUNC_MAX] = {
};
Expression::BuiltinFunc Expression::find_function(const String &p_string) {
-
for (int i = 0; i < FUNC_MAX; i++) {
- if (p_string == func_name[i])
+ if (p_string == func_name[i]) {
return BuiltinFunc(i);
+ }
}
return FUNC_MAX;
}
String Expression::get_func_name(BuiltinFunc p_func) {
-
ERR_FAIL_INDEX_V(p_func, FUNC_MAX, String());
return func_name[p_func];
}
int Expression::get_func_argument_count(BuiltinFunc p_func) {
-
switch (p_func) {
-
case MATH_RANDOMIZE:
case MATH_RAND:
case MATH_RANDF:
@@ -220,194 +217,157 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
r_error.error = Callable::CallError::CALL_OK;
switch (p_func) {
case MATH_SIN: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::sin((double)*p_inputs[0]);
} break;
case MATH_COS: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::cos((double)*p_inputs[0]);
} break;
case MATH_TAN: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::tan((double)*p_inputs[0]);
} break;
case MATH_SINH: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::sinh((double)*p_inputs[0]);
} break;
case MATH_COSH: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::cosh((double)*p_inputs[0]);
} break;
case MATH_TANH: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::tanh((double)*p_inputs[0]);
} break;
case MATH_ASIN: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::asin((double)*p_inputs[0]);
} break;
case MATH_ACOS: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::acos((double)*p_inputs[0]);
} break;
case MATH_ATAN: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::atan((double)*p_inputs[0]);
} break;
case MATH_ATAN2: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::atan2((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case MATH_SQRT: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::sqrt((double)*p_inputs[0]);
} break;
case MATH_FMOD: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::fmod((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case MATH_FPOSMOD: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::fposmod((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case MATH_POSMOD: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::posmod((int)*p_inputs[0], (int)*p_inputs[1]);
} break;
case MATH_FLOOR: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::floor((double)*p_inputs[0]);
} break;
case MATH_CEIL: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::ceil((double)*p_inputs[0]);
} break;
case MATH_ROUND: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::round((double)*p_inputs[0]);
} break;
case MATH_ABS: {
-
if (p_inputs[0]->get_type() == Variant::INT) {
-
int64_t i = *p_inputs[0];
*r_return = ABS(i);
} else if (p_inputs[0]->get_type() == Variant::FLOAT) {
-
real_t r = *p_inputs[0];
*r_return = Math::abs(r);
} else {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::FLOAT;
}
} break;
case MATH_SIGN: {
-
if (p_inputs[0]->get_type() == Variant::INT) {
-
int64_t i = *p_inputs[0];
*r_return = i < 0 ? -1 : (i > 0 ? +1 : 0);
} else if (p_inputs[0]->get_type() == Variant::FLOAT) {
-
real_t r = *p_inputs[0];
*r_return = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0);
} else {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::FLOAT;
}
} break;
case MATH_POW: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::pow((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case MATH_LOG: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::log((double)*p_inputs[0]);
} break;
case MATH_EXP: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::exp((double)*p_inputs[0]);
} break;
case MATH_ISNAN: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::is_nan((double)*p_inputs[0]);
} break;
case MATH_ISINF: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::is_inf((double)*p_inputs[0]);
} break;
case MATH_EASE: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::ease((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case MATH_STEP_DECIMALS: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::step_decimals((double)*p_inputs[0]);
} break;
case MATH_STEPIFY: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::stepify((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case MATH_LERP: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
*r_return = Math::lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case MATH_LERP_ANGLE: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
*r_return = Math::lerp_angle((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case MATH_INVERSE_LERP: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
*r_return = Math::inverse_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case MATH_RANGE_LERP: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
@@ -422,14 +382,12 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
*r_return = Math::smoothstep((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case MATH_MOVE_TOWARD: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
*r_return = Math::move_toward((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case MATH_DECTIME: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
@@ -446,20 +404,17 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
*r_return = Math::randf();
} break;
case MATH_RANDOM: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::random((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case MATH_SEED: {
-
VALIDATE_ARG_NUM(0);
uint64_t seed = *p_inputs[0];
Math::seed(seed);
} break;
case MATH_RANDSEED: {
-
VALIDATE_ARG_NUM(0);
uint64_t seed = *p_inputs[0];
int ret = Math::rand_from_seed(&seed);
@@ -470,22 +425,18 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
} break;
case MATH_DEG2RAD: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::deg2rad((double)*p_inputs[0]);
} break;
case MATH_RAD2DEG: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::rad2deg((double)*p_inputs[0]);
} break;
case MATH_LINEAR2DB: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::linear2db((double)*p_inputs[0]);
} break;
case MATH_DB2LINEAR: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::db2linear((double)*p_inputs[0]);
} break;
@@ -516,9 +467,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
*r_return = Math::wrapf((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case LOGIC_MAX: {
-
if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) {
-
int64_t a = *p_inputs[0];
int64_t b = *p_inputs[1];
*r_return = MAX(a, b);
@@ -534,9 +483,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
} break;
case LOGIC_MIN: {
-
if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) {
-
int64_t a = *p_inputs[0];
int64_t b = *p_inputs[1];
*r_return = MIN(a, b);
@@ -551,9 +498,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
}
} break;
case LOGIC_CLAMP: {
-
if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT && p_inputs[2]->get_type() == Variant::INT) {
-
int64_t a = *p_inputs[0];
int64_t b = *p_inputs[1];
int64_t c = *p_inputs[2];
@@ -571,15 +516,12 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
}
} break;
case LOGIC_NEAREST_PO2: {
-
VALIDATE_ARG_NUM(0);
int64_t num = *p_inputs[0];
*r_return = next_power_of_2(num);
} break;
case OBJ_WEAKREF: {
-
if (p_inputs[0]->get_type() != Variant::OBJECT) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -588,10 +530,8 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
}
if (p_inputs[0]->is_ref()) {
-
REF r = *p_inputs[0];
if (!r.is_valid()) {
-
return;
}
@@ -601,7 +541,6 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
} else {
Object *obj = *p_inputs[0];
if (!obj) {
-
return;
}
Ref<WeakRef> wref = memnew(WeakRef);
@@ -611,9 +550,7 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
} break;
case FUNC_FUNCREF: {
-
if (p_inputs[0]->get_type() != Variant::OBJECT) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -621,7 +558,6 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
return;
}
if (p_inputs[1]->get_type() != Variant::STRING && p_inputs[1]->get_type() != Variant::NODE_PATH) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING;
@@ -638,11 +574,9 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
} break;
case TYPE_CONVERT: {
-
VALIDATE_ARG_NUM(1);
int type = *p_inputs[1];
if (type < 0 || type >= Variant::VARIANT_MAX) {
-
r_error_str = RTR("Invalid type argument to convert(), use TYPE_* constants.");
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
@@ -650,31 +584,25 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
return;
} else {
-
*r_return = Variant::construct(Variant::Type(type), p_inputs, 1, r_error);
}
} break;
case TYPE_OF: {
-
*r_return = p_inputs[0]->get_type();
} break;
case TYPE_EXISTS: {
-
*r_return = ClassDB::class_exists(*p_inputs[0]);
} break;
case TEXT_CHAR: {
-
CharType result[2] = { *p_inputs[0], 0 };
*r_return = String(result);
} break;
case TEXT_ORD: {
-
if (p_inputs[0]->get_type() != Variant::STRING) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -685,7 +613,6 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
String str = *p_inputs[0];
if (str.length() != 1) {
-
r_error_str = RTR("Expected a string of length 1 (a character).");
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
@@ -698,39 +625,33 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
} break;
case TEXT_STR: {
-
String str = *p_inputs[0];
*r_return = str;
} break;
case TEXT_PRINT: {
-
String str = *p_inputs[0];
print_line(str);
} break;
case TEXT_PRINTERR: {
-
String str = *p_inputs[0];
print_error(str);
} break;
case TEXT_PRINTRAW: {
-
String str = *p_inputs[0];
OS::get_singleton()->print("%s", str.utf8().get_data());
} break;
case VAR_TO_STR: {
-
String vars;
VariantWriter::write_to_string(*p_inputs[0], vars);
*r_return = vars;
} break;
case STR_TO_VAR: {
-
if (p_inputs[0]->get_type() != Variant::STRING) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
@@ -756,7 +677,6 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
} break;
case VAR_TO_BYTES: {
-
PackedByteArray barr;
bool full_objects = *p_inputs[1];
int len;
@@ -777,7 +697,6 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
*r_return = barr;
} break;
case BYTES_TO_VAR: {
-
if (p_inputs[0]->get_type() != Variant::PACKED_BYTE_ARRAY) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
@@ -805,7 +724,6 @@ void Expression::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant
} break;
case COLORN: {
-
VALIDATE_ARG_NUM(1);
Color color = Color::named(*p_inputs[0]);
@@ -826,60 +744,49 @@ static bool _is_number(CharType c) {
}
Error Expression::_get_token(Token &r_token) {
-
while (true) {
#define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++])
CharType cchar = GET_CHAR();
switch (cchar) {
-
case 0: {
r_token.type = TK_EOF;
return OK;
- };
+ }
case '{': {
-
r_token.type = TK_CURLY_BRACKET_OPEN;
return OK;
- };
+ }
case '}': {
-
r_token.type = TK_CURLY_BRACKET_CLOSE;
return OK;
- };
+ }
case '[': {
-
r_token.type = TK_BRACKET_OPEN;
return OK;
- };
+ }
case ']': {
-
r_token.type = TK_BRACKET_CLOSE;
return OK;
- };
+ }
case '(': {
-
r_token.type = TK_PARENTHESIS_OPEN;
return OK;
- };
+ }
case ')': {
-
r_token.type = TK_PARENTHESIS_CLOSE;
return OK;
- };
+ }
case ',': {
-
r_token.type = TK_COMMA;
return OK;
- };
+ }
case ':': {
-
r_token.type = TK_COLON;
return OK;
- };
+ }
case '$': {
-
r_token.type = TK_INPUT;
int index = 0;
do {
@@ -896,9 +803,8 @@ Error Expression::_get_token(Token &r_token) {
r_token.value = index;
return OK;
- };
+ }
case '=': {
-
cchar = GET_CHAR();
if (cchar == '=') {
r_token.type = TK_OP_EQUAL;
@@ -908,9 +814,8 @@ Error Expression::_get_token(Token &r_token) {
return ERR_PARSE_ERROR;
}
return OK;
- };
+ }
case '!': {
-
if (expression[str_ofs] == '=') {
r_token.type = TK_OP_NOT_EQUAL;
str_ofs++;
@@ -918,9 +823,8 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_OP_NOT;
}
return OK;
- };
+ }
case '>': {
-
if (expression[str_ofs] == '=') {
r_token.type = TK_OP_GREATER_EQUAL;
str_ofs++;
@@ -931,9 +835,8 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_OP_GREATER;
}
return OK;
- };
+ }
case '<': {
-
if (expression[str_ofs] == '=') {
r_token.type = TK_OP_LESS_EQUAL;
str_ofs++;
@@ -944,29 +847,28 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_OP_LESS;
}
return OK;
- };
+ }
case '+': {
r_token.type = TK_OP_ADD;
return OK;
- };
+ }
case '-': {
r_token.type = TK_OP_SUB;
return OK;
- };
+ }
case '/': {
r_token.type = TK_OP_DIV;
return OK;
- };
+ }
case '*': {
r_token.type = TK_OP_MUL;
return OK;
- };
+ }
case '%': {
r_token.type = TK_OP_MOD;
return OK;
- };
+ }
case '&': {
-
if (expression[str_ofs] == '&') {
r_token.type = TK_OP_AND;
str_ofs++;
@@ -974,9 +876,8 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_OP_BIT_AND;
}
return OK;
- };
+ }
case '|': {
-
if (expression[str_ofs] == '|') {
r_token.type = TK_OP_OR;
str_ofs++;
@@ -984,24 +885,20 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_OP_BIT_OR;
}
return OK;
- };
+ }
case '^': {
-
r_token.type = TK_OP_BIT_XOR;
return OK;
- };
+ }
case '~': {
-
r_token.type = TK_OP_BIT_INVERT;
return OK;
- };
+ }
case '"': {
-
String str;
while (true) {
-
CharType ch = GET_CHAR();
if (ch == 0) {
@@ -1022,12 +919,21 @@ Error Expression::_get_token(Token &r_token) {
CharType res = 0;
switch (next) {
-
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'f': res = 12; break;
- case 'r': res = 13; break;
+ case 'b':
+ res = 8;
+ break;
+ case 't':
+ res = 9;
+ break;
+ case 'n':
+ res = 10;
+ break;
+ case 'f':
+ res = 12;
+ break;
+ case 'r':
+ res = 13;
+ break;
case 'u': {
// hex number
for (int j = 0; j < 4; j++) {
@@ -1039,7 +945,6 @@ Error Expression::_get_token(Token &r_token) {
return ERR_PARSE_ERROR;
}
if (!(_is_number(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
-
_set_error("Malformed hex constant in string");
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
@@ -1081,7 +986,6 @@ Error Expression::_get_token(Token &r_token) {
} break;
default: {
-
if (cchar <= 32) {
break;
}
@@ -1104,10 +1008,8 @@ Error Expression::_get_token(Token &r_token) {
bool is_float = false;
while (true) {
-
switch (reading) {
case READING_INT: {
-
if (_is_number(c)) {
//pass
} else if (c == '.') {
@@ -1121,9 +1023,7 @@ Error Expression::_get_token(Token &r_token) {
} break;
case READING_DEC: {
-
if (_is_number(c)) {
-
} else if (c == 'e') {
reading = READING_EXP;
@@ -1133,13 +1033,13 @@ Error Expression::_get_token(Token &r_token) {
} break;
case READING_EXP: {
-
if (_is_number(c)) {
exp_beg = true;
} else if ((c == '-' || c == '+') && !exp_sign && !exp_beg) {
- if (c == '-')
+ if (c == '-') {
is_float = true;
+ }
exp_sign = true;
} else {
@@ -1148,8 +1048,9 @@ Error Expression::_get_token(Token &r_token) {
} break;
}
- if (reading == READING_DONE)
+ if (reading == READING_DONE) {
break;
+ }
num += String::chr(c);
c = GET_CHAR();
}
@@ -1158,19 +1059,18 @@ Error Expression::_get_token(Token &r_token) {
r_token.type = TK_CONSTANT;
- if (is_float)
+ if (is_float) {
r_token.value = num.to_double();
- else
+ } else {
r_token.value = num.to_int64();
+ }
return OK;
} else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') {
-
String id;
bool first = true;
while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && _is_number(cchar))) {
-
id += String::chr(cchar);
cchar = GET_CHAR();
first = false;
@@ -1210,7 +1110,6 @@ Error Expression::_get_token(Token &r_token) {
} else if (id == "self") {
r_token.type = TK_SELF;
} else {
-
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
if (id == Variant::get_type_name(Variant::Type(i))) {
r_token.type = TK_BASIC_TYPE;
@@ -1293,7 +1192,6 @@ const char *Expression::token_name[TK_MAX] = {
};
Expression::ENode *Expression::_parse_expression() {
-
Vector<ExpressionNode> expression;
while (true) {
@@ -1302,8 +1200,9 @@ Expression::ENode *Expression::_parse_expression() {
Token tk;
_get_token(tk);
- if (error_set)
+ if (error_set) {
return nullptr;
+ }
switch (tk.type) {
case TK_CURLY_BRACKET_OPEN: {
@@ -1311,7 +1210,6 @@ Expression::ENode *Expression::_parse_expression() {
DictionaryNode *dn = alloc_node<DictionaryNode>();
while (true) {
-
int cofs = str_ofs;
_get_token(tk);
if (tk.type == TK_CURLY_BRACKET_CLOSE) {
@@ -1320,8 +1218,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs; //revert
//parse an expression
ENode *subexpr = _parse_expression();
- if (!subexpr)
+ if (!subexpr) {
return nullptr;
+ }
dn->dict.push_back(subexpr);
_get_token(tk);
@@ -1331,8 +1230,9 @@ Expression::ENode *Expression::_parse_expression() {
}
subexpr = _parse_expression();
- if (!subexpr)
+ if (!subexpr) {
return nullptr;
+ }
dn->dict.push_back(subexpr);
@@ -1355,7 +1255,6 @@ Expression::ENode *Expression::_parse_expression() {
ArrayNode *an = alloc_node<ArrayNode>();
while (true) {
-
int cofs = str_ofs;
_get_token(tk);
if (tk.type == TK_BRACKET_CLOSE) {
@@ -1364,8 +1263,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs; //revert
//parse an expression
ENode *subexpr = _parse_expression();
- if (!subexpr)
+ if (!subexpr) {
return nullptr;
+ }
an->array.push_back(subexpr);
cofs = str_ofs;
@@ -1384,8 +1284,9 @@ Expression::ENode *Expression::_parse_expression() {
case TK_PARENTHESIS_OPEN: {
//a suexpression
ENode *e = _parse_expression();
- if (error_set)
+ if (error_set) {
return nullptr;
+ }
_get_token(tk);
if (tk.type != TK_PARENTHESIS_CLOSE) {
_set_error("Expected ')'");
@@ -1396,7 +1297,6 @@ Expression::ENode *Expression::_parse_expression() {
} break;
case TK_IDENTIFIER: {
-
String identifier = tk.value;
int cofs = str_ofs;
@@ -1409,7 +1309,6 @@ Expression::ENode *Expression::_parse_expression() {
func_call->base = self_node;
while (true) {
-
int cofs2 = str_ofs;
_get_token(tk);
if (tk.type == TK_PARENTHESIS_CLOSE) {
@@ -1418,8 +1317,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs2; //revert
//parse an expression
ENode *subexpr = _parse_expression();
- if (!subexpr)
+ if (!subexpr) {
return nullptr;
+ }
func_call->arguments.push_back(subexpr);
@@ -1452,7 +1352,6 @@ Expression::ENode *Expression::_parse_expression() {
input->index = input_index;
expr = input;
} else {
-
NamedIndexNode *index = alloc_node<NamedIndexNode>();
SelfNode *self_node = alloc_node<SelfNode>();
index->base = self_node;
@@ -1462,13 +1361,11 @@ Expression::ENode *Expression::_parse_expression() {
}
} break;
case TK_INPUT: {
-
InputNode *input = alloc_node<InputNode>();
input->index = tk.value;
expr = input;
} break;
case TK_SELF: {
-
SelfNode *self = alloc_node<SelfNode>();
expr = self;
} break;
@@ -1491,7 +1388,6 @@ Expression::ENode *Expression::_parse_expression() {
constructor->data_type = bt;
while (true) {
-
int cofs = str_ofs;
_get_token(tk);
if (tk.type == TK_PARENTHESIS_CLOSE) {
@@ -1500,8 +1396,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs; //revert
//parse an expression
ENode *subexpr = _parse_expression();
- if (!subexpr)
+ if (!subexpr) {
return nullptr;
+ }
constructor->arguments.push_back(subexpr);
@@ -1532,7 +1429,6 @@ Expression::ENode *Expression::_parse_expression() {
bifunc->func = BuiltinFunc(int(tk.value));
while (true) {
-
int cofs = str_ofs;
_get_token(tk);
if (tk.type == TK_PARENTHESIS_CLOSE) {
@@ -1541,8 +1437,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs; //revert
//parse an expression
ENode *subexpr = _parse_expression();
- if (!subexpr)
+ if (!subexpr) {
return nullptr;
+ }
bifunc->arguments.push_back(subexpr);
@@ -1566,7 +1463,6 @@ Expression::ENode *Expression::_parse_expression() {
} break;
case TK_OP_SUB: {
-
ExpressionNode e;
e.is_op = true;
e.op = Variant::OP_NEGATE;
@@ -1574,7 +1470,6 @@ Expression::ENode *Expression::_parse_expression() {
continue;
} break;
case TK_OP_NOT: {
-
ExpressionNode e;
e.is_op = true;
e.op = Variant::OP_NOT;
@@ -1593,8 +1488,9 @@ Expression::ENode *Expression::_parse_expression() {
while (true) {
int cofs2 = str_ofs;
_get_token(tk);
- if (error_set)
+ if (error_set) {
return nullptr;
+ }
bool done = false;
@@ -1606,8 +1502,9 @@ Expression::ENode *Expression::_parse_expression() {
index->base = expr;
ENode *what = _parse_expression();
- if (!what)
+ if (!what) {
return nullptr;
+ }
index->index = what;
@@ -1638,7 +1535,6 @@ Expression::ENode *Expression::_parse_expression() {
func_call->base = expr;
while (true) {
-
int cofs3 = str_ofs;
_get_token(tk);
if (tk.type == TK_PARENTHESIS_CLOSE) {
@@ -1647,8 +1543,9 @@ Expression::ENode *Expression::_parse_expression() {
str_ofs = cofs3; //revert
//parse an expression
ENode *subexpr = _parse_expression();
- if (!subexpr)
+ if (!subexpr) {
return nullptr;
+ }
func_call->arguments.push_back(subexpr);
@@ -1681,8 +1578,9 @@ Expression::ENode *Expression::_parse_expression() {
} break;
}
- if (done)
+ if (done) {
break;
+ }
}
//push expression
@@ -1697,35 +1595,78 @@ Expression::ENode *Expression::_parse_expression() {
int cofs = str_ofs;
_get_token(tk);
- if (error_set)
+ if (error_set) {
return nullptr;
+ }
Variant::Operator op = Variant::OP_MAX;
switch (tk.type) {
- case TK_OP_IN: op = Variant::OP_IN; break;
- case TK_OP_EQUAL: op = Variant::OP_EQUAL; break;
- case TK_OP_NOT_EQUAL: op = Variant::OP_NOT_EQUAL; break;
- case TK_OP_LESS: op = Variant::OP_LESS; break;
- case TK_OP_LESS_EQUAL: op = Variant::OP_LESS_EQUAL; break;
- case TK_OP_GREATER: op = Variant::OP_GREATER; break;
- case TK_OP_GREATER_EQUAL: op = Variant::OP_GREATER_EQUAL; break;
- case TK_OP_AND: op = Variant::OP_AND; break;
- case TK_OP_OR: op = Variant::OP_OR; break;
- case TK_OP_NOT: op = Variant::OP_NOT; break;
- case TK_OP_ADD: op = Variant::OP_ADD; break;
- case TK_OP_SUB: op = Variant::OP_SUBTRACT; break;
- case TK_OP_MUL: op = Variant::OP_MULTIPLY; break;
- case TK_OP_DIV: op = Variant::OP_DIVIDE; break;
- case TK_OP_MOD: op = Variant::OP_MODULE; break;
- case TK_OP_SHIFT_LEFT: op = Variant::OP_SHIFT_LEFT; break;
- case TK_OP_SHIFT_RIGHT: op = Variant::OP_SHIFT_RIGHT; break;
- case TK_OP_BIT_AND: op = Variant::OP_BIT_AND; break;
- case TK_OP_BIT_OR: op = Variant::OP_BIT_OR; break;
- case TK_OP_BIT_XOR: op = Variant::OP_BIT_XOR; break;
- case TK_OP_BIT_INVERT: op = Variant::OP_BIT_NEGATE; break;
+ case TK_OP_IN:
+ op = Variant::OP_IN;
+ break;
+ case TK_OP_EQUAL:
+ op = Variant::OP_EQUAL;
+ break;
+ case TK_OP_NOT_EQUAL:
+ op = Variant::OP_NOT_EQUAL;
+ break;
+ case TK_OP_LESS:
+ op = Variant::OP_LESS;
+ break;
+ case TK_OP_LESS_EQUAL:
+ op = Variant::OP_LESS_EQUAL;
+ break;
+ case TK_OP_GREATER:
+ op = Variant::OP_GREATER;
+ break;
+ case TK_OP_GREATER_EQUAL:
+ op = Variant::OP_GREATER_EQUAL;
+ break;
+ case TK_OP_AND:
+ op = Variant::OP_AND;
+ break;
+ case TK_OP_OR:
+ op = Variant::OP_OR;
+ break;
+ case TK_OP_NOT:
+ op = Variant::OP_NOT;
+ break;
+ case TK_OP_ADD:
+ op = Variant::OP_ADD;
+ break;
+ case TK_OP_SUB:
+ op = Variant::OP_SUBTRACT;
+ break;
+ case TK_OP_MUL:
+ op = Variant::OP_MULTIPLY;
+ break;
+ case TK_OP_DIV:
+ op = Variant::OP_DIVIDE;
+ break;
+ case TK_OP_MOD:
+ op = Variant::OP_MODULE;
+ break;
+ case TK_OP_SHIFT_LEFT:
+ op = Variant::OP_SHIFT_LEFT;
+ break;
+ case TK_OP_SHIFT_RIGHT:
+ op = Variant::OP_SHIFT_RIGHT;
+ break;
+ case TK_OP_BIT_AND:
+ op = Variant::OP_BIT_AND;
+ break;
+ case TK_OP_BIT_OR:
+ op = Variant::OP_BIT_OR;
+ break;
+ case TK_OP_BIT_XOR:
+ op = Variant::OP_BIT_XOR;
+ break;
+ case TK_OP_BIT_INVERT:
+ op = Variant::OP_BIT_NEGATE;
+ break;
default: {
- };
+ }
}
if (op == Variant::OP_MAX) { //stop appending stuff
@@ -1745,15 +1686,12 @@ Expression::ENode *Expression::_parse_expression() {
/* Reduce the set set of expressions and place them in an operator tree, respecting precedence */
while (expression.size() > 1) {
-
int next_op = -1;
int min_priority = 0xFFFFF;
bool is_unary = false;
for (int i = 0; i < expression.size(); i++) {
-
if (!expression[i].is_op) {
-
continue;
}
@@ -1762,7 +1700,6 @@ Expression::ENode *Expression::_parse_expression() {
bool unary = false;
switch (expression[i].op) {
-
case Variant::OP_BIT_NEGATE:
priority = 0;
unary = true;
@@ -1772,36 +1709,74 @@ Expression::ENode *Expression::_parse_expression() {
unary = true;
break;
- case Variant::OP_MULTIPLY: priority = 2; break;
- case Variant::OP_DIVIDE: priority = 2; break;
- case Variant::OP_MODULE: priority = 2; break;
+ case Variant::OP_MULTIPLY:
+ priority = 2;
+ break;
+ case Variant::OP_DIVIDE:
+ priority = 2;
+ break;
+ case Variant::OP_MODULE:
+ priority = 2;
+ break;
- case Variant::OP_ADD: priority = 3; break;
- case Variant::OP_SUBTRACT: priority = 3; break;
+ case Variant::OP_ADD:
+ priority = 3;
+ break;
+ case Variant::OP_SUBTRACT:
+ priority = 3;
+ break;
- case Variant::OP_SHIFT_LEFT: priority = 4; break;
- case Variant::OP_SHIFT_RIGHT: priority = 4; break;
+ case Variant::OP_SHIFT_LEFT:
+ priority = 4;
+ break;
+ case Variant::OP_SHIFT_RIGHT:
+ priority = 4;
+ break;
- case Variant::OP_BIT_AND: priority = 5; break;
- case Variant::OP_BIT_XOR: priority = 6; break;
- case Variant::OP_BIT_OR: priority = 7; break;
+ case Variant::OP_BIT_AND:
+ priority = 5;
+ break;
+ case Variant::OP_BIT_XOR:
+ priority = 6;
+ break;
+ case Variant::OP_BIT_OR:
+ priority = 7;
+ break;
- case Variant::OP_LESS: priority = 8; break;
- case Variant::OP_LESS_EQUAL: priority = 8; break;
- case Variant::OP_GREATER: priority = 8; break;
- case Variant::OP_GREATER_EQUAL: priority = 8; break;
+ case Variant::OP_LESS:
+ priority = 8;
+ break;
+ case Variant::OP_LESS_EQUAL:
+ priority = 8;
+ break;
+ case Variant::OP_GREATER:
+ priority = 8;
+ break;
+ case Variant::OP_GREATER_EQUAL:
+ priority = 8;
+ break;
- case Variant::OP_EQUAL: priority = 8; break;
- case Variant::OP_NOT_EQUAL: priority = 8; break;
+ case Variant::OP_EQUAL:
+ priority = 8;
+ break;
+ case Variant::OP_NOT_EQUAL:
+ priority = 8;
+ break;
- case Variant::OP_IN: priority = 10; break;
+ case Variant::OP_IN:
+ priority = 10;
+ break;
case Variant::OP_NOT:
priority = 11;
unary = true;
break;
- case Variant::OP_AND: priority = 12; break;
- case Variant::OP_OR: priority = 13; break;
+ case Variant::OP_AND:
+ priority = 12;
+ break;
+ case Variant::OP_OR:
+ priority = 13;
+ break;
default: {
_set_error("Parser bug, invalid operator in expression: " + itos(expression[i].op));
@@ -1820,17 +1795,14 @@ Expression::ENode *Expression::_parse_expression() {
}
if (next_op == -1) {
-
_set_error("Yet another parser bug....");
ERR_FAIL_V(nullptr);
}
// OK! create operator..
if (is_unary) {
-
int expr_pos = next_op;
while (expression[expr_pos].is_op) {
-
expr_pos++;
if (expr_pos == expression.size()) {
//can happen..
@@ -1841,7 +1813,6 @@ Expression::ENode *Expression::_parse_expression() {
//consecutively do unary operators
for (int i = expr_pos - 1; i >= next_op; i--) {
-
OperatorNode *op = alloc_node<OperatorNode>();
op->op = expression[i].op;
op->nodes[0] = expression[i + 1].node;
@@ -1852,7 +1823,6 @@ Expression::ENode *Expression::_parse_expression() {
}
} else {
-
if (next_op < 1 || next_op >= (expression.size() - 1)) {
_set_error("Parser bug...");
ERR_FAIL_V(nullptr);
@@ -1862,7 +1832,6 @@ Expression::ENode *Expression::_parse_expression() {
op->op = expression[next_op].op;
if (expression[next_op - 1].is_op) {
-
_set_error("Parser bug...");
ERR_FAIL_V(nullptr);
}
@@ -1891,9 +1860,9 @@ Expression::ENode *Expression::_parse_expression() {
}
bool Expression::_compile_expression() {
-
- if (!expression_dirty)
+ if (!expression_dirty) {
return error_set;
+ }
if (nodes) {
memdelete(nodes);
@@ -1921,10 +1890,8 @@ bool Expression::_compile_expression() {
}
bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression::ENode *p_node, Variant &r_ret, String &r_error_str) {
-
switch (p_node->type) {
case Expression::ENode::TYPE_INPUT: {
-
const Expression::InputNode *in = static_cast<const Expression::InputNode *>(p_node);
if (in->index < 0 || in->index >= p_inputs.size()) {
r_error_str = vformat(RTR("Invalid input %i (not passed) in expression"), in->index);
@@ -1933,13 +1900,11 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
r_ret = p_inputs[in->index];
} break;
case Expression::ENode::TYPE_CONSTANT: {
-
const Expression::ConstantNode *c = static_cast<const Expression::ConstantNode *>(p_node);
r_ret = c->value;
} break;
case Expression::ENode::TYPE_SELF: {
-
if (!p_instance) {
r_error_str = RTR("self can't be used because instance is null (not passed)");
return true;
@@ -1947,20 +1912,21 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
r_ret = p_instance;
} break;
case Expression::ENode::TYPE_OPERATOR: {
-
const Expression::OperatorNode *op = static_cast<const Expression::OperatorNode *>(p_node);
Variant a;
bool ret = _execute(p_inputs, p_instance, op->nodes[0], a, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
Variant b;
if (op->nodes[1]) {
ret = _execute(p_inputs, p_instance, op->nodes[1], b, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
}
bool valid = true;
@@ -1972,19 +1938,20 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
} break;
case Expression::ENode::TYPE_INDEX: {
-
const Expression::IndexNode *index = static_cast<const Expression::IndexNode *>(p_node);
Variant base;
bool ret = _execute(p_inputs, p_instance, index->base, base, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
Variant idx;
ret = _execute(p_inputs, p_instance, index->index, idx, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
bool valid;
r_ret = base.get(idx, &valid);
@@ -1995,13 +1962,13 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
} break;
case Expression::ENode::TYPE_NAMED_INDEX: {
-
const Expression::NamedIndexNode *index = static_cast<const Expression::NamedIndexNode *>(p_node);
Variant base;
bool ret = _execute(p_inputs, p_instance, index->base, base, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
bool valid;
r_ret = base.get_named(index->name, &valid);
@@ -2017,12 +1984,12 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Array arr;
arr.resize(array->array.size());
for (int i = 0; i < array->array.size(); i++) {
-
Variant value;
bool ret = _execute(p_inputs, p_instance, array->array[i], value, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
arr[i] = value;
}
@@ -2034,17 +2001,18 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
Dictionary d;
for (int i = 0; i < dictionary->dict.size(); i += 2) {
-
Variant key;
bool ret = _execute(p_inputs, p_instance, dictionary->dict[i + 0], key, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
Variant value;
ret = _execute(p_inputs, p_instance, dictionary->dict[i + 1], value, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
d[key] = value;
}
@@ -2052,7 +2020,6 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
r_ret = d;
} break;
case Expression::ENode::TYPE_CONSTRUCTOR: {
-
const Expression::ConstructorNode *constructor = static_cast<const Expression::ConstructorNode *>(p_node);
Vector<Variant> arr;
@@ -2061,12 +2028,12 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
argp.resize(constructor->arguments.size());
for (int i = 0; i < constructor->arguments.size(); i++) {
-
Variant value;
bool ret = _execute(p_inputs, p_instance, constructor->arguments[i], value, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
arr.write[i] = value;
argp.write[i] = &arr[i];
}
@@ -2081,7 +2048,6 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
} break;
case Expression::ENode::TYPE_BUILTIN_FUNC: {
-
const Expression::BuiltinFuncNode *bifunc = static_cast<const Expression::BuiltinFuncNode *>(p_node);
Vector<Variant> arr;
@@ -2090,11 +2056,11 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
argp.resize(bifunc->arguments.size());
for (int i = 0; i < bifunc->arguments.size(); i++) {
-
Variant value;
bool ret = _execute(p_inputs, p_instance, bifunc->arguments[i], value, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
arr.write[i] = value;
argp.write[i] = &arr[i];
}
@@ -2109,14 +2075,14 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
} break;
case Expression::ENode::TYPE_CALL: {
-
const Expression::CallNode *call = static_cast<const Expression::CallNode *>(p_node);
Variant base;
bool ret = _execute(p_inputs, p_instance, call->base, base, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
Vector<Variant> arr;
Vector<const Variant *> argp;
@@ -2124,12 +2090,12 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
argp.resize(call->arguments.size());
for (int i = 0; i < call->arguments.size(); i++) {
-
Variant value;
ret = _execute(p_inputs, p_instance, call->arguments[i], value, r_error_str);
- if (ret)
+ if (ret) {
return true;
+ }
arr.write[i] = value;
argp.write[i] = &arr[i];
}
@@ -2148,7 +2114,6 @@ bool Expression::_execute(const Array &p_inputs, Object *p_instance, Expression:
}
Error Expression::parse(const String &p_expression, const Vector<String> &p_input_names) {
-
if (nodes) {
memdelete(nodes);
nodes = nullptr;
@@ -2176,7 +2141,6 @@ Error Expression::parse(const String &p_expression, const Vector<String> &p_inpu
}
Variant Expression::execute(Array p_inputs, Object *p_base, bool p_show_error) {
-
ERR_FAIL_COND_V_MSG(error_set, Variant(), "There was previously a parse error: " + error_str + ".");
execution_error = false;
@@ -2201,26 +2165,13 @@ String Expression::get_error_text() const {
}
void Expression::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("parse", "expression", "input_names"), &Expression::parse, DEFVAL(Vector<String>()));
ClassDB::bind_method(D_METHOD("execute", "inputs", "base_instance", "show_error"), &Expression::execute, DEFVAL(Array()), DEFVAL(Variant()), DEFVAL(true));
ClassDB::bind_method(D_METHOD("has_execute_failed"), &Expression::has_execute_failed);
ClassDB::bind_method(D_METHOD("get_error_text"), &Expression::get_error_text);
}
-Expression::Expression() :
- output_type(Variant::NIL),
- sequenced(false),
- error_set(true),
- root(nullptr),
- nodes(nullptr),
- execution_error(false) {
- str_ofs = 0;
- expression_dirty = false;
-}
-
Expression::~Expression() {
-
if (nodes) {
memdelete(nodes);
}
diff --git a/core/math/expression.h b/core/math/expression.h
index 78de225ebf..59a9a2f4ed 100644
--- a/core/math/expression.h
+++ b/core/math/expression.h
@@ -118,23 +118,20 @@ private:
static const char *func_name[FUNC_MAX];
struct Input {
-
- Variant::Type type;
+ Variant::Type type = Variant::NIL;
String name;
- Input() :
- type(Variant::NIL) {
- }
+ Input() {}
};
Vector<Input> inputs;
- Variant::Type output_type;
+ Variant::Type output_type = Variant::NIL;
String expression;
- bool sequenced;
- int str_ofs;
- bool expression_dirty;
+ bool sequenced = false;
+ int str_ofs = 0;
+ bool expression_dirty = false;
bool _compile_expression();
@@ -182,14 +179,14 @@ private:
static const char *token_name[TK_MAX];
struct Token {
-
TokenType type;
Variant value;
};
void _set_error(const String &p_err) {
- if (error_set)
+ if (error_set) {
return;
+ }
error_str = p_err;
error_set = true;
}
@@ -197,10 +194,9 @@ private:
Error _get_token(Token &r_token);
String error_str;
- bool error_set;
+ bool error_set = true;
struct ENode {
-
enum Type {
TYPE_INPUT,
TYPE_CONSTANT,
@@ -215,11 +211,11 @@ private:
TYPE_CALL
};
- ENode *next;
+ ENode *next = nullptr;
Type type;
- ENode() { next = nullptr; }
+ ENode() {}
virtual ~ENode() {
if (next) {
memdelete(next);
@@ -228,7 +224,6 @@ private:
};
struct ExpressionNode {
-
bool is_op;
union {
Variant::Operator op;
@@ -239,7 +234,6 @@ private:
ENode *_parse_expression();
struct InputNode : public ENode {
-
int index;
InputNode() {
type = TYPE_INPUT;
@@ -247,7 +241,6 @@ private:
};
struct ConstantNode : public ENode {
-
Variant value;
ConstantNode() {
type = TYPE_CONSTANT;
@@ -255,7 +248,6 @@ private:
};
struct OperatorNode : public ENode {
-
Variant::Operator op;
ENode *nodes[2];
@@ -266,7 +258,6 @@ private:
};
struct SelfNode : public ENode {
-
SelfNode() {
type = TYPE_SELF;
}
@@ -339,12 +330,12 @@ private:
return node;
}
- ENode *root;
- ENode *nodes;
+ ENode *root = nullptr;
+ ENode *nodes = nullptr;
Vector<String> input_names;
- bool execution_error;
+ bool execution_error = false;
bool _execute(const Array &p_inputs, Object *p_instance, Expression::ENode *p_node, Variant &r_ret, String &r_error_str);
protected:
@@ -356,7 +347,7 @@ public:
bool has_execute_failed() const;
String get_error_text() const;
- Expression();
+ Expression() {}
~Expression();
};
diff --git a/core/math/face3.cpp b/core/math/face3.cpp
index 74331b391f..6d76e116be 100644
--- a/core/math/face3.cpp
+++ b/core/math/face3.cpp
@@ -33,7 +33,6 @@
#include "core/math/geometry.h"
int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_over[3]) const {
-
ERR_FAIL_COND_V(is_degenerate(), 0);
Vector3 above[4];
@@ -43,7 +42,6 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_
int below_count = 0;
for (int i = 0; i < 3; i++) {
-
if (p_plane.has_point(vertex[i], CMP_EPSILON)) { // point is in plane
ERR_FAIL_COND_V(above_count >= 4, 0);
@@ -52,7 +50,6 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_
below[below_count++] = vertex[i];
} else {
-
if (p_plane.is_point_over(vertex[i])) {
//Point is over
ERR_FAIL_COND_V(above_count >= 4, 0);
@@ -67,8 +64,9 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_
/* Check for Intersection between this and the next vertex*/
Vector3 inters;
- if (!p_plane.intersects_segment(vertex[i], vertex[(i + 1) % 3], &inters))
+ if (!p_plane.intersects_segment(vertex[i], vertex[(i + 1) % 3], &inters)) {
continue;
+ }
/* Intersection goes to both */
ERR_FAIL_COND_V(above_count >= 4, 0);
@@ -83,13 +81,11 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_
ERR_FAIL_COND_V(above_count >= 4 && below_count >= 4, 0); //bug in the algo
if (above_count >= 3) {
-
p_res[polygons_created] = Face3(above[0], above[1], above[2]);
p_is_point_over[polygons_created] = true;
polygons_created++;
if (above_count == 4) {
-
p_res[polygons_created] = Face3(above[2], above[3], above[0]);
p_is_point_over[polygons_created] = true;
polygons_created++;
@@ -97,13 +93,11 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_
}
if (below_count >= 3) {
-
p_res[polygons_created] = Face3(below[0], below[1], below[2]);
p_is_point_over[polygons_created] = false;
polygons_created++;
if (below_count == 4) {
-
p_res[polygons_created] = Face3(below[2], below[3], below[0]);
p_is_point_over[polygons_created] = false;
polygons_created++;
@@ -114,52 +108,49 @@ int Face3::split_by_plane(const Plane &p_plane, Face3 p_res[3], bool p_is_point_
}
bool Face3::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection) const {
-
return Geometry::ray_intersects_triangle(p_from, p_dir, vertex[0], vertex[1], vertex[2], p_intersection);
}
bool Face3::intersects_segment(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection) const {
-
return Geometry::segment_intersects_triangle(p_from, p_dir, vertex[0], vertex[1], vertex[2], p_intersection);
}
bool Face3::is_degenerate() const {
-
Vector3 normal = vec3_cross(vertex[0] - vertex[1], vertex[0] - vertex[2]);
return (normal.length_squared() < CMP_EPSILON2);
}
Face3::Side Face3::get_side_of(const Face3 &p_face, ClockDirection p_clock_dir) const {
-
int over = 0, under = 0;
Plane plane = get_plane(p_clock_dir);
for (int i = 0; i < 3; i++) {
-
const Vector3 &v = p_face.vertex[i];
- if (plane.has_point(v)) //coplanar, don't bother
+ if (plane.has_point(v)) { //coplanar, don't bother
continue;
+ }
- if (plane.is_point_over(v))
+ if (plane.is_point_over(v)) {
over++;
- else
+ } else {
under++;
+ }
}
- if (over > 0 && under == 0)
+ if (over > 0 && under == 0) {
return SIDE_OVER;
- else if (under > 0 && over == 0)
+ } else if (under > 0 && over == 0) {
return SIDE_UNDER;
- else if (under == 0 && over == 0)
+ } else if (under == 0 && over == 0) {
return SIDE_COPLANAR;
- else
+ } else {
return SIDE_SPANNING;
+ }
}
Vector3 Face3::get_random_point_inside() const {
-
real_t a = Math::random(0, 1);
real_t b = Math::random(0, 1);
if (a > b) {
@@ -170,32 +161,28 @@ Vector3 Face3::get_random_point_inside() const {
}
Plane Face3::get_plane(ClockDirection p_dir) const {
-
return Plane(vertex[0], vertex[1], vertex[2], p_dir);
}
Vector3 Face3::get_median_point() const {
-
return (vertex[0] + vertex[1] + vertex[2]) / 3.0;
}
real_t Face3::get_area() const {
-
return vec3_cross(vertex[0] - vertex[1], vertex[0] - vertex[2]).length();
}
ClockDirection Face3::get_clock_dir() const {
-
Vector3 normal = vec3_cross(vertex[0] - vertex[1], vertex[0] - vertex[2]);
//printf("normal is %g,%g,%g x %g,%g,%g- wtfu is %g\n",tofloat(normal.x),tofloat(normal.y),tofloat(normal.z),tofloat(vertex[0].x),tofloat(vertex[0].y),tofloat(vertex[0].z),tofloat( normal.dot( vertex[0] ) ) );
return (normal.dot(vertex[0]) >= 0) ? CLOCKWISE : COUNTERCLOCKWISE;
}
bool Face3::intersects_aabb(const AABB &p_aabb) const {
-
/** TEST PLANE **/
- if (!p_aabb.intersects_plane(get_plane()))
+ if (!p_aabb.intersects_plane(get_plane())) {
return false;
+ }
#define TEST_AXIS(m_ax) \
/** TEST FACE AXIS */ \
@@ -228,7 +215,6 @@ bool Face3::intersects_aabb(const AABB &p_aabb) const {
};
for (int i = 0; i < 12; i++) {
-
Vector3 from, to;
p_aabb.get_edge(i, from, to);
Vector3 e1 = from - to;
@@ -237,58 +223,57 @@ bool Face3::intersects_aabb(const AABB &p_aabb) const {
Vector3 axis = vec3_cross(e1, e2);
- if (axis.length_squared() < 0.0001)
+ if (axis.length_squared() < 0.0001) {
continue; // coplanar
+ }
axis.normalize();
real_t minA, maxA, minB, maxB;
p_aabb.project_range_in_plane(Plane(axis, 0), minA, maxA);
project_range(axis, Transform(), minB, maxB);
- if (maxA < minB || maxB < minA)
+ if (maxA < minB || maxB < minA) {
return false;
+ }
}
}
return true;
}
Face3::operator String() const {
-
return String() + vertex[0] + ", " + vertex[1] + ", " + vertex[2];
}
void Face3::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
-
for (int i = 0; i < 3; i++) {
-
Vector3 v = p_transform.xform(vertex[i]);
real_t d = p_normal.dot(v);
- if (i == 0 || d > r_max)
+ if (i == 0 || d > r_max) {
r_max = d;
+ }
- if (i == 0 || d < r_min)
+ if (i == 0 || d < r_min) {
r_min = d;
+ }
}
}
void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, Vector3 *p_vertices, int *p_count, int p_max) const {
-
#define _FACE_IS_VALID_SUPPORT_THRESHOLD 0.98
#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.05
- if (p_max <= 0)
+ if (p_max <= 0) {
return;
+ }
Vector3 n = p_transform.basis.xform_inv(p_normal);
/** TEST FACE AS SUPPORT **/
if (get_plane().normal.dot(n) > _FACE_IS_VALID_SUPPORT_THRESHOLD) {
-
*p_count = MIN(3, p_max);
for (int i = 0; i < *p_count; i++) {
-
p_vertices[i] = p_transform.xform(vertex[i]);
}
@@ -301,7 +286,6 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V
real_t support_max = 0;
for (int i = 0; i < 3; i++) {
-
real_t d = n.dot(vertex[i]);
if (i == 0 || d > support_max) {
@@ -313,19 +297,19 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V
/** TEST EDGES AS SUPPORT **/
for (int i = 0; i < 3; i++) {
-
- if (i != vert_support_idx && i + 1 != vert_support_idx)
+ if (i != vert_support_idx && i + 1 != vert_support_idx) {
continue;
+ }
// check if edge is valid as a support
real_t dot = (vertex[i] - vertex[(i + 1) % 3]).normalized().dot(n);
dot = ABS(dot);
if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
-
*p_count = MIN(2, p_max);
- for (int j = 0; j < *p_count; j++)
+ for (int j = 0; j < *p_count; j++) {
p_vertices[j] = p_transform.xform(vertex[(j + i) % 3]);
+ }
return;
}
@@ -336,7 +320,6 @@ void Face3::get_support(const Vector3 &p_normal, const Transform &p_transform, V
}
Vector3 Face3::get_closest_point_to(const Vector3 &p_point) const {
-
Vector3 edge0 = vertex[1] - vertex[0];
Vector3 edge1 = vertex[2] - vertex[0];
Vector3 v0 = vertex[0] - p_point;
diff --git a/core/math/face3.h b/core/math/face3.h
index f4b8721caa..fb40e8ab9e 100644
--- a/core/math/face3.h
+++ b/core/math/face3.h
@@ -69,8 +69,8 @@ public:
Vector3 get_median_point() const;
Vector3 get_closest_point_to(const Vector3 &p_point) const;
- bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection = 0) const;
- bool intersects_segment(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection = 0) const;
+ bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection = nullptr) const;
+ bool intersects_segment(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection = nullptr) const;
ClockDirection get_clock_dir() const; ///< todo, test if this is returning the proper clockwisity
@@ -78,7 +78,6 @@ public:
void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const;
AABB get_aabb() const {
-
AABB aabb(vertex[0], Vector3());
aabb.expand_to(vertex[1]);
aabb.expand_to(vertex[2]);
@@ -98,7 +97,6 @@ public:
};
bool Face3::intersects_aabb2(const AABB &p_aabb) const {
-
Vector3 perp = (vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]);
Vector3 half_extents = p_aabb.size * 0.5;
@@ -113,8 +111,9 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
real_t dist_a = perp.dot(ofs + sup) - d;
real_t dist_b = perp.dot(ofs - sup) - d;
- if (dist_a * dist_b > 0)
+ if (dist_a * dist_b > 0) {
return false; //does not intersect the plane
+ }
#define TEST_AXIS(m_ax) \
{ \
@@ -145,17 +144,13 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
};
for (int i = 0; i < 12; i++) {
-
Vector3 from, to;
switch (i) {
-
case 0: {
-
from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z);
to = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z);
} break;
case 1: {
-
from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z);
to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z);
} break;
@@ -165,18 +160,15 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
} break;
case 3: {
-
from = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z);
to = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z);
} break;
case 4: {
-
from = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
} break;
case 5: {
-
from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z);
} break;
@@ -186,31 +178,26 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
} break;
case 7: {
-
from = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z);
to = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
} break;
case 8: {
-
from = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z);
to = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z);
} break;
case 9: {
-
from = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z);
to = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
} break;
case 10: {
-
from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z);
to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
} break;
case 11: {
-
from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z);
to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z);
@@ -223,8 +210,9 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
Vector3 axis = vec3_cross(e1, e2);
- if (axis.length_squared() < 0.0001)
+ if (axis.length_squared() < 0.0001) {
continue; // coplanar
+ }
//axis.normalize();
Vector3 sup2 = Vector3(
@@ -240,18 +228,20 @@ bool Face3::intersects_aabb2(const AABB &p_aabb) const {
real_t minT = 1e20, maxT = -1e20;
for (int k = 0; k < 3; k++) {
-
real_t vert_d = axis.dot(vertex[k]);
- if (vert_d > maxT)
+ if (vert_d > maxT) {
maxT = vert_d;
+ }
- if (vert_d < minT)
+ if (vert_d < minT) {
minT = vert_d;
+ }
}
- if (maxB < minT || maxT < minB)
+ if (maxB < minT || maxT < minB) {
return false;
+ }
}
}
return true;
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index 3e07e9253e..a4e9169a6f 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -31,33 +31,33 @@
#include "geometry.h"
#include "core/print_string.h"
+
#include "thirdparty/misc/clipper.hpp"
#include "thirdparty/misc/triangulator.h"
+#define STB_RECT_PACK_IMPLEMENTATION
+#include "thirdparty/misc/stb_rect_pack.h"
#define SCALE_FACTOR 100000.0 // Based on CMP_EPSILON.
// This implementation is very inefficient, commenting unless bugs happen. See the other one.
/*
bool Geometry::is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon) {
-
Vector<int> indices = Geometry::triangulate_polygon(p_polygon);
for (int j = 0; j + 3 <= indices.size(); j += 3) {
int i1 = indices[j], i2 = indices[j + 1], i3 = indices[j + 2];
- if (Geometry::is_point_in_triangle(p_point, p_polygon[i1], p_polygon[i2], p_polygon[i3]))
+ if (Geometry::is_point_in_triangle(p_point, p_polygon[i1], p_polygon[i2], p_polygon[i3])) {
return true;
+ }
}
return false;
}
*/
void Geometry::MeshData::optimize_vertices() {
-
Map<int, int> vtx_remap;
for (int i = 0; i < faces.size(); i++) {
-
for (int j = 0; j < faces[i].indices.size(); j++) {
-
int idx = faces[i].indices[j];
if (!vtx_remap.has(idx)) {
int ni = vtx_remap.size();
@@ -69,7 +69,6 @@ void Geometry::MeshData::optimize_vertices() {
}
for (int i = 0; i < edges.size(); i++) {
-
int a = edges[i].a;
int b = edges[i].b;
@@ -90,36 +89,28 @@ void Geometry::MeshData::optimize_vertices() {
new_vertices.resize(vtx_remap.size());
for (int i = 0; i < vertices.size(); i++) {
-
- if (vtx_remap.has(i))
+ if (vtx_remap.has(i)) {
new_vertices.write[vtx_remap[i]] = vertices[i];
+ }
}
vertices = new_vertices;
}
struct _FaceClassify {
-
struct _Link {
-
- int face;
- int edge;
+ int face = -1;
+ int edge = -1;
void clear() {
face = -1;
edge = -1;
}
- _Link() {
- face = -1;
- edge = -1;
- }
+ _Link() {}
};
- bool valid;
- int group;
+ bool valid = false;
+ int group = -1;
_Link links[3];
Face3 face;
- _FaceClassify() {
- group = -1;
- valid = false;
- };
+ _FaceClassify() {}
};
static bool _connect_faces(_FaceClassify *p_faces, int len, int p_group) {
@@ -129,42 +120,36 @@ static bool _connect_faces(_FaceClassify *p_faces, int len, int p_group) {
bool error = false;
for (int i = 0; i < len; i++) {
-
for (int j = 0; j < 3; j++) {
-
p_faces[i].links[j].clear();
}
}
for (int i = 0; i < len; i++) {
-
- if (p_faces[i].group != p_group)
+ if (p_faces[i].group != p_group) {
continue;
+ }
for (int j = i + 1; j < len; j++) {
-
- if (p_faces[j].group != p_group)
+ if (p_faces[j].group != p_group) {
continue;
+ }
for (int k = 0; k < 3; k++) {
-
Vector3 vi1 = p_faces[i].face.vertex[k];
Vector3 vi2 = p_faces[i].face.vertex[(k + 1) % 3];
for (int l = 0; l < 3; l++) {
-
Vector3 vj2 = p_faces[j].face.vertex[l];
Vector3 vj1 = p_faces[j].face.vertex[(l + 1) % 3];
if (vi1.distance_to(vj1) < 0.00001 &&
vi2.distance_to(vj2) < 0.00001) {
if (p_faces[i].links[k].face != -1) {
-
ERR_PRINT("already linked\n");
error = true;
break;
}
if (p_faces[j].links[l].face != -1) {
-
ERR_PRINT("already linked\n");
error = true;
break;
@@ -176,37 +161,38 @@ static bool _connect_faces(_FaceClassify *p_faces, int len, int p_group) {
p_faces[j].links[l].edge = k;
}
}
- if (error)
+ if (error) {
break;
+ }
}
- if (error)
+ if (error) {
break;
+ }
}
- if (error)
+ if (error) {
break;
+ }
}
for (int i = 0; i < len; i++) {
-
p_faces[i].valid = true;
for (int j = 0; j < 3; j++) {
-
- if (p_faces[i].links[j].face == -1)
+ if (p_faces[i].links[j].face == -1) {
p_faces[i].valid = false;
+ }
}
}
return error;
}
static bool _group_face(_FaceClassify *p_faces, int len, int p_index, int p_group) {
-
- if (p_faces[p_index].group >= 0)
+ if (p_faces[p_index].group >= 0) {
return false;
+ }
p_faces[p_index].group = p_group;
for (int i = 0; i < 3; i++) {
-
ERR_FAIL_INDEX_V(p_faces[p_index].links[i].face, len, true);
_group_face(p_faces, len, p_faces[p_index].links[i].face, p_group);
}
@@ -215,7 +201,6 @@ static bool _group_face(_FaceClassify *p_faces, int len, int p_index, int p_grou
}
Vector<Vector<Face3>> Geometry::separate_objects(Vector<Face3> p_array) {
-
Vector<Vector<Face3>> objects;
int len = p_array.size();
@@ -229,7 +214,6 @@ Vector<Vector<Face3>> Geometry::separate_objects(Vector<Face3> p_array) {
_FaceClassify *_fcptr = fc.ptrw();
for (int i = 0; i < len; i++) {
-
_fcptr[i].face = arrayptr[i];
}
@@ -241,9 +225,9 @@ Vector<Vector<Face3>> Geometry::separate_objects(Vector<Face3> p_array) {
int group = 0;
for (int i = 0; i < len; i++) {
-
- if (!_fcptr[i].valid)
+ if (!_fcptr[i].valid) {
continue;
+ }
if (_group_face(_fcptr, len, i, group)) {
group++;
}
@@ -252,20 +236,18 @@ Vector<Vector<Face3>> Geometry::separate_objects(Vector<Face3> p_array) {
// Group connected faces in separate objects.
for (int i = 0; i < len; i++) {
-
_fcptr[i].face = arrayptr[i];
}
if (group >= 0) {
-
objects.resize(group);
Vector<Face3> *group_faces = objects.ptrw();
for (int i = 0; i < len; i++) {
- if (!_fcptr[i].valid)
+ if (!_fcptr[i].valid) {
continue;
+ }
if (_fcptr[i].group >= 0 && _fcptr[i].group < group) {
-
group_faces[_fcptr[i].group].push_back(_fcptr[i].face);
}
}
@@ -302,16 +284,15 @@ enum _CellFlags {
};
static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, const Vector3 &voxelsize, const Face3 &p_face) {
-
AABB aabb(Vector3(x, y, z), Vector3(len_x, len_y, len_z));
aabb.position = aabb.position * voxelsize;
aabb.size = aabb.size * voxelsize;
- if (!p_face.intersects_aabb(aabb))
+ if (!p_face.intersects_aabb(aabb)) {
return;
+ }
if (len_x == 1 && len_y == 1 && len_z == 1) {
-
p_cell_status[x][y][z] = _CELL_SOLID;
return;
}
@@ -340,15 +321,12 @@ static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int
int new_len_z;
for (int i = 0; i < div_x; i++) {
-
_SPLIT(i, div_x, x, len_x, new_x, new_len_x);
for (int j = 0; j < div_y; j++) {
-
_SPLIT(j, div_y, y, len_y, new_y, new_len_y);
for (int k = 0; k < div_z; k++) {
-
_SPLIT(k, div_z, z, len_z, new_z, new_len_z);
_plot_face(p_cell_status, new_x, new_y, new_z, new_len_x, new_len_y, new_len_z, voxelsize, p_face);
@@ -358,14 +336,13 @@ static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int
}
static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z) {
-
- if (p_cell_status[x][y][z] & 3)
+ if (p_cell_status[x][y][z] & 3) {
return; // Nothing to do, already used and/or visited.
+ }
p_cell_status[x][y][z] = _CELL_PREV_FIRST;
while (true) {
-
uint8_t &c = p_cell_status[x][y][z];
if ((c & _CELL_STEP_MASK) == _CELL_STEP_NONE) {
@@ -419,9 +396,7 @@ static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z,
uint8_t prev = 0;
switch (c & _CELL_STEP_MASK) {
-
case _CELL_STEP_Y_POS: {
-
next_y++;
prev = _CELL_PREV_Y_NEG;
} break;
@@ -445,18 +420,23 @@ static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z,
next_z--;
prev = _CELL_PREV_Z_POS;
} break;
- default: ERR_FAIL();
+ default:
+ ERR_FAIL();
}
- if (next_x < 0 || next_x >= len_x)
+ if (next_x < 0 || next_x >= len_x) {
continue;
- if (next_y < 0 || next_y >= len_y)
+ }
+ if (next_y < 0 || next_y >= len_y) {
continue;
- if (next_z < 0 || next_z >= len_z)
+ }
+ if (next_z < 0 || next_z >= len_z) {
continue;
+ }
- if (p_cell_status[next_x][next_y][next_z] & 3)
+ if (p_cell_status[next_x][next_y][next_z] & 3) {
continue;
+ }
x = next_x;
y = next_y;
@@ -466,13 +446,13 @@ static inline void _mark_outside(uint8_t ***p_cell_status, int x, int y, int z,
}
static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, Vector<Face3> &p_faces) {
-
ERR_FAIL_INDEX(x, len_x);
ERR_FAIL_INDEX(y, len_y);
ERR_FAIL_INDEX(z, len_z);
- if (p_cell_status[x][y][z] & _CELL_EXTERIOR)
+ if (p_cell_status[x][y][z] & _CELL_EXTERIOR) {
return;
+ }
#define vert(m_idx) Vector3(((m_idx)&4) >> 2, ((m_idx)&2) >> 1, (m_idx)&1)
@@ -487,7 +467,6 @@ static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, i
};
for (int i = 0; i < 6; i++) {
-
Vector3 face_points[4];
int disp_x = x + ((i % 3) == 0 ? ((i < 3) ? 1 : -1) : 0);
int disp_y = y + (((i - 1) % 3) == 0 ? ((i < 3) ? 1 : -1) : 0);
@@ -495,21 +474,27 @@ static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, i
bool plot = false;
- if (disp_x < 0 || disp_x >= len_x)
+ if (disp_x < 0 || disp_x >= len_x) {
plot = true;
- if (disp_y < 0 || disp_y >= len_y)
+ }
+ if (disp_y < 0 || disp_y >= len_y) {
plot = true;
- if (disp_z < 0 || disp_z >= len_z)
+ }
+ if (disp_z < 0 || disp_z >= len_z) {
plot = true;
+ }
- if (!plot && (p_cell_status[disp_x][disp_y][disp_z] & _CELL_EXTERIOR))
+ if (!plot && (p_cell_status[disp_x][disp_y][disp_z] & _CELL_EXTERIOR)) {
plot = true;
+ }
- if (!plot)
+ if (!plot) {
continue;
+ }
- for (int j = 0; j < 4; j++)
+ for (int j = 0; j < 4; j++) {
face_points[j] = vert(indices[i][j]) + Vector3(x, y, z);
+ }
p_faces.push_back(
Face3(
@@ -526,7 +511,6 @@ static inline void _build_faces(uint8_t ***p_cell_status, int x, int y, int z, i
}
Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
-
#define _MIN_SIZE 1.0
#define _MAX_LENGTH 20
@@ -536,12 +520,9 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
AABB global_aabb;
for (int i = 0; i < face_count; i++) {
-
if (i == 0) {
-
global_aabb = faces[i].get_aabb();
} else {
-
global_aabb.merge_with(faces[i].get_aabb());
}
}
@@ -551,20 +532,23 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
// Determine amount of cells in grid axis.
int div_x, div_y, div_z;
- if (global_aabb.size.x / _MIN_SIZE < _MAX_LENGTH)
+ if (global_aabb.size.x / _MIN_SIZE < _MAX_LENGTH) {
div_x = (int)(global_aabb.size.x / _MIN_SIZE) + 1;
- else
+ } else {
div_x = _MAX_LENGTH;
+ }
- if (global_aabb.size.y / _MIN_SIZE < _MAX_LENGTH)
+ if (global_aabb.size.y / _MIN_SIZE < _MAX_LENGTH) {
div_y = (int)(global_aabb.size.y / _MIN_SIZE) + 1;
- else
+ } else {
div_y = _MAX_LENGTH;
+ }
- if (global_aabb.size.z / _MIN_SIZE < _MAX_LENGTH)
+ if (global_aabb.size.z / _MIN_SIZE < _MAX_LENGTH) {
div_z = (int)(global_aabb.size.z / _MIN_SIZE) + 1;
- else
+ } else {
div_z = _MAX_LENGTH;
+ }
Vector3 voxelsize = global_aabb.size;
voxelsize.x /= div_x;
@@ -575,15 +559,12 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
uint8_t ***cell_status = memnew_arr(uint8_t **, div_x);
for (int i = 0; i < div_x; i++) {
-
cell_status[i] = memnew_arr(uint8_t *, div_y);
for (int j = 0; j < div_y; j++) {
-
cell_status[i][j] = memnew_arr(uint8_t, div_z);
for (int k = 0; k < div_z; k++) {
-
cell_status[i][j][k] = 0;
}
}
@@ -592,10 +573,8 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
// Plot faces into cells.
for (int i = 0; i < face_count; i++) {
-
Face3 f = faces[i];
for (int j = 0; j < 3; j++) {
-
f.vertex[j] -= global_aabb.position;
}
_plot_face(cell_status, 0, 0, 0, div_x, div_y, div_z, voxelsize, f);
@@ -604,27 +583,21 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
// Determine which cells connect to the outside by traversing the outside and recursively flood-fill marking.
for (int i = 0; i < div_x; i++) {
-
for (int j = 0; j < div_y; j++) {
-
_mark_outside(cell_status, i, j, 0, div_x, div_y, div_z);
_mark_outside(cell_status, i, j, div_z - 1, div_x, div_y, div_z);
}
}
for (int i = 0; i < div_z; i++) {
-
for (int j = 0; j < div_y; j++) {
-
_mark_outside(cell_status, 0, j, i, div_x, div_y, div_z);
_mark_outside(cell_status, div_x - 1, j, i, div_x, div_y, div_z);
}
}
for (int i = 0; i < div_x; i++) {
-
for (int j = 0; j < div_z; j++) {
-
_mark_outside(cell_status, i, 0, j, div_x, div_y, div_z);
_mark_outside(cell_status, i, div_y - 1, j, div_x, div_y, div_z);
}
@@ -635,11 +608,8 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
Vector<Face3> wrapped_faces;
for (int i = 0; i < div_x; i++) {
-
for (int j = 0; j < div_y; j++) {
-
for (int k = 0; k < div_z; k++) {
-
_build_faces(cell_status, i, j, k, div_x, div_y, div_z, wrapped_faces);
}
}
@@ -651,9 +621,7 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
Face3 *wrapped_faces_ptr = wrapped_faces.ptrw();
for (int i = 0; i < wrapped_faces_count; i++) {
-
for (int j = 0; j < 3; j++) {
-
Vector3 &v = wrapped_faces_ptr[i].vertex[j];
v = v * voxelsize;
v += global_aabb.position;
@@ -663,9 +631,7 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
// clean up grid
for (int i = 0; i < div_x; i++) {
-
for (int j = 0; j < div_y; j++) {
-
memdelete_arr(cell_status[i][j]);
}
@@ -673,8 +639,9 @@ Vector<Face3> Geometry::wrap_geometry(Vector<Face3> p_array, real_t *p_error) {
}
memdelete_arr(cell_status);
- if (p_error)
+ if (p_error) {
*p_error = voxelsize.length();
+ }
return wrapped_faces;
}
@@ -714,20 +681,19 @@ Vector<Vector<Vector2>> Geometry::decompose_polygon_in_convex(Vector<Point2> pol
}
Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
-
MeshData mesh;
#define SUBPLANE_SIZE 1024.0
real_t subplane_size = 1024.0; // Should compute this from the actual plane.
for (int i = 0; i < p_planes.size(); i++) {
-
Plane p = p_planes[i];
Vector3 ref = Vector3(0.0, 1.0, 0.0);
- if (ABS(p.normal.dot(ref)) > 0.95)
+ if (ABS(p.normal.dot(ref)) > 0.95) {
ref = Vector3(0.0, 0.0, 1.0); // Change axis.
+ }
Vector3 right = p.normal.cross(ref).normalized();
Vector3 up = p.normal.cross(right).normalized();
@@ -742,21 +708,22 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
vertices.push_back(center + up * subplane_size + right * subplane_size);
for (int j = 0; j < p_planes.size(); j++) {
-
- if (j == i)
+ if (j == i) {
continue;
+ }
Vector<Vector3> new_vertices;
Plane clip = p_planes[j];
- if (clip.normal.dot(p.normal) > 0.95)
+ if (clip.normal.dot(p.normal) > 0.95) {
continue;
+ }
- if (vertices.size() < 3)
+ if (vertices.size() < 3) {
break;
+ }
for (int k = 0; k < vertices.size(); k++) {
-
int k_n = (k + 1) % vertices.size();
Vector3 edge0_A = vertices[k];
@@ -772,13 +739,13 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
// Check for different sides and non coplanar.
if ((dist0 * dist1) < 0) {
-
// Calculate intersection.
Vector3 rel = edge1_A - edge0_A;
real_t den = clip.normal.dot(rel);
- if (Math::is_zero_approx(den))
+ if (Math::is_zero_approx(den)) {
continue; // Point too short.
+ }
real_t dist = -(clip.normal.dot(edge0_A) - clip.d) / den;
Vector3 inters = edge0_A + rel * dist;
@@ -789,8 +756,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
vertices = new_vertices;
}
- if (vertices.size() < 3)
+ if (vertices.size() < 3) {
continue;
+ }
// Result is a clockwise face.
@@ -798,19 +766,15 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
// Add face indices.
for (int j = 0; j < vertices.size(); j++) {
-
int idx = -1;
for (int k = 0; k < mesh.vertices.size(); k++) {
-
if (mesh.vertices[k].distance_to(vertices[j]) < 0.001) {
-
idx = k;
break;
}
}
if (idx == -1) {
-
idx = mesh.vertices.size();
mesh.vertices.push_back(vertices[j]);
}
@@ -823,13 +787,11 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
// Add edge.
for (int j = 0; j < face.indices.size(); j++) {
-
int a = face.indices[j];
int b = face.indices[(j + 1) % face.indices.size()];
bool found = false;
for (int k = 0; k < mesh.edges.size(); k++) {
-
if (mesh.edges[k].a == a && mesh.edges[k].b == b) {
found = true;
break;
@@ -840,8 +802,9 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
}
}
- if (found)
+ if (found) {
continue;
+ }
MeshData::Edge edge;
edge.a = a;
edge.b = b;
@@ -853,7 +816,6 @@ Geometry::MeshData Geometry::build_convex_mesh(const Vector<Plane> &p_planes) {
}
Vector<Plane> Geometry::build_box_planes(const Vector3 &p_extents) {
-
Vector<Plane> planes;
planes.push_back(Plane(Vector3(1, 0, 0), p_extents.x));
@@ -867,11 +829,9 @@ Vector<Plane> Geometry::build_box_planes(const Vector3 &p_extents) {
}
Vector<Plane> Geometry::build_cylinder_planes(real_t p_radius, real_t p_height, int p_sides, Vector3::Axis p_axis) {
-
Vector<Plane> planes;
for (int i = 0; i < p_sides; i++) {
-
Vector3 normal;
normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_sides);
normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_sides);
@@ -889,7 +849,6 @@ Vector<Plane> Geometry::build_cylinder_planes(real_t p_radius, real_t p_height,
}
Vector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats, int p_lons, Vector3::Axis p_axis) {
-
Vector<Plane> planes;
Vector3 axis;
@@ -901,7 +860,6 @@ Vector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats, int p_l
axis_neg[p_axis] = -1.0;
for (int i = 0; i < p_lons; i++) {
-
Vector3 normal;
normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_lons);
normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_lons);
@@ -909,9 +867,8 @@ Vector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats, int p_l
planes.push_back(Plane(normal, p_radius));
for (int j = 1; j <= p_lats; j++) {
-
// FIXME: This is stupid.
- Vector3 angle = normal.linear_interpolate(axis, j / (real_t)p_lats).normalized();
+ Vector3 angle = normal.lerp(axis, j / (real_t)p_lats).normalized();
Vector3 pos = angle * p_radius;
planes.push_back(Plane(pos, angle));
planes.push_back(Plane(pos * axis_neg, angle * axis_neg));
@@ -922,7 +879,6 @@ Vector<Plane> Geometry::build_sphere_planes(real_t p_radius, int p_lats, int p_l
}
Vector<Plane> Geometry::build_capsule_planes(real_t p_radius, real_t p_height, int p_sides, int p_lats, Vector3::Axis p_axis) {
-
Vector<Plane> planes;
Vector3 axis;
@@ -934,7 +890,6 @@ Vector<Plane> Geometry::build_capsule_planes(real_t p_radius, real_t p_height, i
axis_neg[p_axis] = -1.0;
for (int i = 0; i < p_sides; i++) {
-
Vector3 normal;
normal[(p_axis + 1) % 3] = Math::cos(i * (2.0 * Math_PI) / p_sides);
normal[(p_axis + 2) % 3] = Math::sin(i * (2.0 * Math_PI) / p_sides);
@@ -942,8 +897,7 @@ Vector<Plane> Geometry::build_capsule_planes(real_t p_radius, real_t p_height, i
planes.push_back(Plane(normal, p_radius));
for (int j = 1; j <= p_lats; j++) {
-
- Vector3 angle = normal.linear_interpolate(axis, j / (real_t)p_lats).normalized();
+ Vector3 angle = normal.lerp(axis, j / (real_t)p_lats).normalized();
Vector3 pos = axis * p_height * 0.5 + angle * p_radius;
planes.push_back(Plane(pos, angle));
planes.push_back(Plane(pos * axis_neg, angle * axis_neg));
@@ -954,7 +908,6 @@ Vector<Plane> Geometry::build_capsule_planes(real_t p_radius, real_t p_height, i
}
struct _AtlasWorkRect {
-
Size2i s;
Point2i p;
int idx;
@@ -962,14 +915,12 @@ struct _AtlasWorkRect {
};
struct _AtlasWorkRectResult {
-
Vector<_AtlasWorkRect> result;
int max_w;
int max_h;
};
void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size) {
-
// Super simple, almost brute force scanline stacking fitter.
// It's pretty basic for now, but it tries to make sure that the aspect ratio of the
// resulting atlas is somehow square. This is necessary because video cards have limits.
@@ -992,55 +943,57 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
Vector<_AtlasWorkRectResult> results;
for (int i = 0; i <= 12; i++) {
-
int w = 1 << i;
int max_h = 0;
int max_w = 0;
- if (w < widest)
+ if (w < widest) {
continue;
+ }
Vector<int> hmax;
hmax.resize(w);
- for (int j = 0; j < w; j++)
+ for (int j = 0; j < w; j++) {
hmax.write[j] = 0;
+ }
// Place them.
int ofs = 0;
int limit_h = 0;
for (int j = 0; j < wrects.size(); j++) {
-
if (ofs + wrects[j].s.width > w) {
-
ofs = 0;
}
int from_y = 0;
for (int k = 0; k < wrects[j].s.width; k++) {
-
- if (hmax[ofs + k] > from_y)
+ if (hmax[ofs + k] > from_y) {
from_y = hmax[ofs + k];
+ }
}
wrects.write[j].p.x = ofs;
wrects.write[j].p.y = from_y;
int end_h = from_y + wrects[j].s.height;
int end_w = ofs + wrects[j].s.width;
- if (ofs == 0)
+ if (ofs == 0) {
limit_h = end_h;
+ }
for (int k = 0; k < wrects[j].s.width; k++) {
-
hmax.write[ofs + k] = end_h;
}
- if (end_h > max_h)
+ if (end_h > max_h) {
max_h = end_h;
+ }
- if (end_w > max_w)
+ if (end_w > max_w) {
max_w = end_w;
+ }
- if (ofs == 0 || end_h > limit_h) // While h limit not reached, keep stacking.
+ if (ofs == 0 || end_h > limit_h) { // While h limit not reached, keep stacking.
ofs += wrects[j].s.width;
+ }
}
_AtlasWorkRectResult result;
@@ -1056,7 +1009,6 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
real_t best_aspect = 1e20;
for (int i = 0; i < results.size(); i++) {
-
real_t h = next_power_of_2(results[i].max_h);
real_t w = next_power_of_2(results[i].max_w);
real_t aspect = h > w ? h / w : w / h;
@@ -1069,7 +1021,6 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
r_result.resize(p_rects.size());
for (int i = 0; i < p_rects.size(); i++) {
-
r_result.write[results[best].result[i].idx] = results[best].result[i].p;
}
@@ -1077,16 +1028,23 @@ void Geometry::make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_resu
}
Vector<Vector<Point2>> Geometry::_polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open) {
-
using namespace ClipperLib;
ClipType op = ctUnion;
switch (p_op) {
- case OPERATION_UNION: op = ctUnion; break;
- case OPERATION_DIFFERENCE: op = ctDifference; break;
- case OPERATION_INTERSECTION: op = ctIntersection; break;
- case OPERATION_XOR: op = ctXor; break;
+ case OPERATION_UNION:
+ op = ctUnion;
+ break;
+ case OPERATION_DIFFERENCE:
+ op = ctDifference;
+ break;
+ case OPERATION_INTERSECTION:
+ op = ctIntersection;
+ break;
+ case OPERATION_XOR:
+ op = ctXor;
+ break;
}
Path path_a, path_b;
@@ -1129,25 +1087,40 @@ Vector<Vector<Point2>> Geometry::_polypaths_do_operation(PolyBooleanOperation p_
}
Vector<Vector<Point2>> Geometry::_polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
-
using namespace ClipperLib;
JoinType jt = jtSquare;
switch (p_join_type) {
- case JOIN_SQUARE: jt = jtSquare; break;
- case JOIN_ROUND: jt = jtRound; break;
- case JOIN_MITER: jt = jtMiter; break;
+ case JOIN_SQUARE:
+ jt = jtSquare;
+ break;
+ case JOIN_ROUND:
+ jt = jtRound;
+ break;
+ case JOIN_MITER:
+ jt = jtMiter;
+ break;
}
EndType et = etClosedPolygon;
switch (p_end_type) {
- case END_POLYGON: et = etClosedPolygon; break;
- case END_JOINED: et = etClosedLine; break;
- case END_BUTT: et = etOpenButt; break;
- case END_SQUARE: et = etOpenSquare; break;
- case END_ROUND: et = etOpenRound; break;
+ case END_POLYGON:
+ et = etClosedPolygon;
+ break;
+ case END_JOINED:
+ et = etClosedLine;
+ break;
+ case END_BUTT:
+ et = etOpenButt;
+ break;
+ case END_SQUARE:
+ et = etOpenSquare;
+ break;
+ case END_ROUND:
+ et = etOpenRound;
+ break;
}
ClipperOffset co(2.0, 0.25 * SCALE_FACTOR); // Defaults from ClipperOffset.
Path path;
@@ -1178,3 +1151,227 @@ Vector<Vector<Point2>> Geometry::_polypath_offset(const Vector<Point2> &p_polypa
}
return polypaths;
}
+
+Vector<Vector3> Geometry::compute_convex_mesh_points(const Plane *p_planes, int p_plane_count) {
+ Vector<Vector3> points;
+
+ // Iterate through every unique combination of any three planes.
+ for (int i = p_plane_count - 1; i >= 0; i--) {
+ for (int j = i - 1; j >= 0; j--) {
+ for (int k = j - 1; k >= 0; k--) {
+ // Find the point where these planes all cross over (if they
+ // do at all).
+ Vector3 convex_shape_point;
+ if (p_planes[i].intersect_3(p_planes[j], p_planes[k], &convex_shape_point)) {
+ // See if any *other* plane excludes this point because it's
+ // on the wrong side.
+ bool excluded = false;
+ for (int n = 0; n < p_plane_count; n++) {
+ if (n != i && n != j && n != k) {
+ real_t dp = p_planes[n].normal.dot(convex_shape_point);
+ if (dp - p_planes[n].d > CMP_EPSILON) {
+ excluded = true;
+ break;
+ }
+ }
+ }
+
+ // Only add the point if it passed all tests.
+ if (!excluded) {
+ points.push_back(convex_shape_point);
+ }
+ }
+ }
+ }
+ }
+
+ return points;
+}
+
+Vector<Point2i> Geometry::pack_rects(const Vector<Size2i> &p_sizes, const Size2i &p_atlas_size) {
+ Vector<stbrp_node> nodes;
+ nodes.resize(p_atlas_size.width);
+
+ stbrp_context context;
+ stbrp_init_target(&context, p_atlas_size.width, p_atlas_size.height, nodes.ptrw(), p_atlas_size.width);
+
+ Vector<stbrp_rect> rects;
+ rects.resize(p_sizes.size());
+
+ for (int i = 0; i < p_sizes.size(); i++) {
+ rects.write[i].id = 0;
+ rects.write[i].w = p_sizes[i].width;
+ rects.write[i].h = p_sizes[i].height;
+ rects.write[i].x = 0;
+ rects.write[i].y = 0;
+ rects.write[i].was_packed = 0;
+ }
+
+ int res = stbrp_pack_rects(&context, rects.ptrw(), rects.size());
+ if (res == 0) { //pack failed
+ return Vector<Point2i>();
+ }
+
+ Vector<Point2i> ret;
+ ret.resize(p_sizes.size());
+
+ for (int i = 0; i < p_sizes.size(); i++) {
+ Point2i r(rects[i].x, rects[i].y);
+ ret.write[i] = r;
+ }
+
+ return ret;
+}
+
+Vector<Vector3i> Geometry::partial_pack_rects(const Vector<Vector2i> &p_sizes, const Size2i &p_atlas_size) {
+ Vector<stbrp_node> nodes;
+ nodes.resize(p_atlas_size.width);
+ zeromem(nodes.ptrw(), sizeof(stbrp_node) * nodes.size());
+
+ stbrp_context context;
+ stbrp_init_target(&context, p_atlas_size.width, p_atlas_size.height, nodes.ptrw(), p_atlas_size.width);
+
+ Vector<stbrp_rect> rects;
+ rects.resize(p_sizes.size());
+
+ for (int i = 0; i < p_sizes.size(); i++) {
+ rects.write[i].id = i;
+ rects.write[i].w = p_sizes[i].width;
+ rects.write[i].h = p_sizes[i].height;
+ rects.write[i].x = 0;
+ rects.write[i].y = 0;
+ rects.write[i].was_packed = 0;
+ }
+
+ stbrp_pack_rects(&context, rects.ptrw(), rects.size());
+
+ Vector<Vector3i> ret;
+ ret.resize(p_sizes.size());
+
+ for (int i = 0; i < p_sizes.size(); i++) {
+ ret.write[rects[i].id] = Vector3i(rects[i].x, rects[i].y, rects[i].was_packed != 0 ? 1 : 0);
+ }
+
+ return ret;
+}
+
+#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) {
+ float *d = (float *)alloca(sizeof(float) * n + sizeof(int) * n + sizeof(float) * (n + 1));
+ int *v = (int *)&(d[n]);
+ float *z = (float *)&v[n];
+
+ int k = 0;
+ v[0] = 0;
+ z[0] = -INF;
+ z[1] = +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]) {
+ k--;
+ s = ((f[q * stride] + square(q)) - (f[v[k] * stride] + square(v[k]))) / (2 * q - 2 * v[k]);
+ }
+ k++;
+ v[k] = q;
+
+ z[k] = s;
+ z[k + 1] = +INF;
+ }
+
+ k = 0;
+ for (int q = 0; q <= n - 1; q++) {
+ while (z[k + 1] < q) {
+ k++;
+ }
+ d[q] = square(q - v[k]) + f[v[k] * stride];
+ }
+
+ for (int i = 0; i < n; i++) {
+ f[i * stride] = d[i];
+ }
+}
+
+#undef square
+
+Vector<uint32_t> Geometry::generate_edf(const Vector<bool> &p_voxels, const Vector3i &p_size, bool p_negative) {
+ uint32_t float_count = p_size.x * p_size.y * p_size.z;
+
+ ERR_FAIL_COND_V((uint32_t)p_voxels.size() != float_count, Vector<uint32_t>());
+
+ float *work_memory = memnew_arr(float, float_count);
+ for (uint32_t i = 0; i < float_count; i++) {
+ work_memory[i] = INF;
+ }
+
+ uint32_t y_mult = p_size.x;
+ uint32_t z_mult = y_mult * p_size.y;
+
+ //plot solid cells
+ {
+ const bool *voxr = p_voxels.ptr();
+ for (uint32_t i = 0; i < float_count; i++) {
+ bool plot = voxr[i];
+ if (p_negative) {
+ plot = !plot;
+ }
+ if (plot) {
+ work_memory[i] = 0;
+ }
+ }
+ }
+
+ //process in each direction
+
+ //xy->z
+
+ for (int i = 0; i < p_size.x; i++) {
+ for (int j = 0; j < p_size.y; j++) {
+ edt(&work_memory[i + j * y_mult], z_mult, p_size.z);
+ }
+ }
+
+ //xz->y
+
+ for (int i = 0; i < p_size.x; i++) {
+ for (int j = 0; j < p_size.z; j++) {
+ edt(&work_memory[i + j * z_mult], y_mult, p_size.y);
+ }
+ }
+
+ //yz->x
+ for (int i = 0; i < p_size.y; i++) {
+ for (int j = 0; j < p_size.z; j++) {
+ edt(&work_memory[i * y_mult + j * z_mult], 1, p_size.x);
+ }
+ }
+
+ Vector<uint32_t> ret;
+ ret.resize(float_count);
+ {
+ uint32_t *w = ret.ptrw();
+ for (uint32_t i = 0; i < float_count; i++) {
+ w[i] = uint32_t(Math::sqrt(work_memory[i]));
+ }
+ }
+
+ return ret;
+}
+
+Vector<int8_t> Geometry::generate_sdf8(const Vector<uint32_t> &p_positive, const Vector<uint32_t> &p_negative) {
+ ERR_FAIL_COND_V(p_positive.size() != p_negative.size(), Vector<int8_t>());
+ Vector<int8_t> sdf8;
+ int s = p_positive.size();
+ sdf8.resize(s);
+
+ const uint32_t *rpos = p_positive.ptr();
+ const uint32_t *rneg = p_negative.ptr();
+ int8_t *wsdf = sdf8.ptrw();
+ for (int i = 0; i < s; i++) {
+ int32_t diff = int32_t(rpos[i]) - int32_t(rneg[i]);
+ wsdf[i] = CLAMP(diff, -128, 127);
+ }
+ return sdf8;
+}
diff --git a/core/math/geometry.h b/core/math/geometry.h
index e47d18b056..a61bf20c4c 100644
--- a/core/math/geometry.h
+++ b/core/math/geometry.h
@@ -31,13 +31,12 @@
#ifndef GEOMETRY_H
#define GEOMETRY_H
-#include "core/math/delaunay.h"
+#include "core/math/delaunay_2d.h"
#include "core/math/face3.h"
#include "core/math/rect2.h"
#include "core/math/triangulate.h"
#include "core/math/vector3.h"
#include "core/object.h"
-
#include "core/print_string.h"
#include "core/vector.h"
@@ -46,7 +45,6 @@ class Geometry {
public:
static real_t get_closest_points_between_segments(const Vector2 &p1, const Vector2 &q1, const Vector2 &p2, const Vector2 &q2, Vector2 &c1, Vector2 &c2) {
-
Vector2 d1 = q1 - p1; // Direction vector of segment S1.
Vector2 d2 = q2 - p2; // Direction vector of segment S2.
Vector2 r = p1 - p2;
@@ -80,8 +78,9 @@ public:
// clamp to segment S1. Else pick arbitrary s (here 0).
if (denom != 0.0) {
s = CLAMP((b * f - c * e) / denom, 0.0, 1.0);
- } else
+ } else {
s = 0.0;
+ }
// Compute point on L2 closest to S1(s) using
// t = Dot((P1 + D1*s) - P2,D2) / Dot(D2,D2) = (b*s + f) / e
t = (b * s + f) / e;
@@ -104,7 +103,6 @@ public:
}
static void get_closest_points_between_segments(const Vector3 &p1, const Vector3 &p2, const Vector3 &q1, const Vector3 &q2, Vector3 &c1, Vector3 &c2) {
-
// Do the function 'd' as defined by pb. I think is is dot product of some sort.
#define d_of(m, n, o, p) ((m.x - n.x) * (o.x - p.x) + (m.y - n.y) * (o.y - p.y) + (m.z - n.z) * (o.z - p.z))
@@ -113,12 +111,20 @@ public:
real_t mub = (d_of(p1, q1, q2, q1) + mua * d_of(q2, q1, p2, p1)) / d_of(q2, q1, q2, q1);
// Clip the value between [0..1] constraining the solution to lie on the original curves.
- if (mua < 0) mua = 0;
- if (mub < 0) mub = 0;
- if (mua > 1) mua = 1;
- if (mub > 1) mub = 1;
- c1 = p1.linear_interpolate(p2, mua);
- c2 = q1.linear_interpolate(q2, mub);
+ if (mua < 0) {
+ mua = 0;
+ }
+ if (mub < 0) {
+ mub = 0;
+ }
+ if (mua > 1) {
+ mua = 1;
+ }
+ if (mub > 1) {
+ mub = 1;
+ }
+ c1 = p1.lerp(p2, mua);
+ c2 = q1.lerp(q2, mub);
}
static real_t get_closest_distance_between_segments(const Vector3 &p_from_a, const Vector3 &p_to_a, const Vector3 &p_from_b, const Vector3 &p_to_b) {
@@ -157,22 +163,22 @@ public:
if (tN < 0.0) { // tc < 0 => the t=0 edge is visible.
tN = 0.0;
// Recompute sc for this edge.
- if (-d < 0.0)
+ if (-d < 0.0) {
sN = 0.0;
- else if (-d > a)
+ } else if (-d > a) {
sN = sD;
- else {
+ } else {
sN = -d;
sD = a;
}
} else if (tN > tD) { // tc > 1 => the t=1 edge is visible.
tN = tD;
// Recompute sc for this edge.
- if ((-d + b) < 0.0)
+ if ((-d + b) < 0.0) {
sN = 0;
- else if ((-d + b) > a)
+ } else if ((-d + b) > a) {
sN = sD;
- else {
+ } else {
sN = (-d + b);
sD = a;
}
@@ -187,120 +193,134 @@ public:
return dP.length(); // Return the closest distance.
}
- static inline bool ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2, Vector3 *r_res = 0) {
+ static inline bool ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2, Vector3 *r_res = nullptr) {
Vector3 e1 = p_v1 - p_v0;
Vector3 e2 = p_v2 - p_v0;
Vector3 h = p_dir.cross(e2);
real_t a = e1.dot(h);
- if (Math::is_zero_approx(a)) // Parallel test.
+ if (Math::is_zero_approx(a)) { // Parallel test.
return false;
+ }
real_t f = 1.0 / a;
Vector3 s = p_from - p_v0;
real_t u = f * s.dot(h);
- if (u < 0.0 || u > 1.0)
+ if (u < 0.0 || u > 1.0) {
return false;
+ }
Vector3 q = s.cross(e1);
real_t v = f * p_dir.dot(q);
- if (v < 0.0 || u + v > 1.0)
+ if (v < 0.0 || u + v > 1.0) {
return false;
+ }
// At this stage we can compute t to find out where
// the intersection point is on the line.
real_t t = f * e2.dot(q);
if (t > 0.00001) { // ray intersection
- if (r_res)
+ if (r_res) {
*r_res = p_from + p_dir * t;
+ }
return true;
- } else // This means that there is a line intersection but not a ray intersection.
+ } else { // This means that there is a line intersection but not a ray intersection.
return false;
+ }
}
- static inline bool segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2, Vector3 *r_res = 0) {
-
+ static inline bool segment_intersects_triangle(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_v0, const Vector3 &p_v1, const Vector3 &p_v2, Vector3 *r_res = nullptr) {
Vector3 rel = p_to - p_from;
Vector3 e1 = p_v1 - p_v0;
Vector3 e2 = p_v2 - p_v0;
Vector3 h = rel.cross(e2);
real_t a = e1.dot(h);
- if (Math::is_zero_approx(a)) // Parallel test.
+ if (Math::is_zero_approx(a)) { // Parallel test.
return false;
+ }
real_t f = 1.0 / a;
Vector3 s = p_from - p_v0;
real_t u = f * s.dot(h);
- if (u < 0.0 || u > 1.0)
+ if (u < 0.0 || u > 1.0) {
return false;
+ }
Vector3 q = s.cross(e1);
real_t v = f * rel.dot(q);
- if (v < 0.0 || u + v > 1.0)
+ if (v < 0.0 || u + v > 1.0) {
return false;
+ }
// At this stage we can compute t to find out where
// the intersection point is on the line.
real_t t = f * e2.dot(q);
if (t > CMP_EPSILON && t <= 1.0) { // Ray intersection.
- if (r_res)
+ if (r_res) {
*r_res = p_from + rel * t;
+ }
return true;
- } else // This means that there is a line intersection but not a ray intersection.
+ } else { // This means that there is a line intersection but not a ray intersection.
return false;
+ }
}
- static inline bool segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 *r_res = 0, Vector3 *r_norm = 0) {
-
+ static inline bool segment_intersects_sphere(const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_sphere_pos, real_t p_sphere_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr) {
Vector3 sphere_pos = p_sphere_pos - p_from;
Vector3 rel = (p_to - p_from);
real_t rel_l = rel.length();
- if (rel_l < CMP_EPSILON)
+ if (rel_l < CMP_EPSILON) {
return false; // Both points are the same.
+ }
Vector3 normal = rel / rel_l;
real_t sphere_d = normal.dot(sphere_pos);
real_t ray_distance = sphere_pos.distance_to(normal * sphere_d);
- if (ray_distance >= p_sphere_radius)
+ if (ray_distance >= p_sphere_radius) {
return false;
+ }
real_t inters_d2 = p_sphere_radius * p_sphere_radius - ray_distance * ray_distance;
real_t inters_d = sphere_d;
- if (inters_d2 >= CMP_EPSILON)
+ if (inters_d2 >= CMP_EPSILON) {
inters_d -= Math::sqrt(inters_d2);
+ }
// Check in segment.
- if (inters_d < 0 || inters_d > rel_l)
+ if (inters_d < 0 || inters_d > rel_l) {
return false;
+ }
Vector3 result = p_from + normal * inters_d;
- if (r_res)
+ if (r_res) {
*r_res = result;
- if (r_norm)
+ }
+ if (r_norm) {
*r_norm = (result - p_sphere_pos).normalized();
+ }
return true;
}
- static inline bool segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, real_t p_height, real_t p_radius, Vector3 *r_res = 0, Vector3 *r_norm = 0) {
-
+ static inline bool segment_intersects_cylinder(const Vector3 &p_from, const Vector3 &p_to, real_t p_height, real_t p_radius, Vector3 *r_res = nullptr, Vector3 *r_norm = nullptr) {
Vector3 rel = (p_to - p_from);
real_t rel_l = rel.length();
- if (rel_l < CMP_EPSILON)
+ if (rel_l < CMP_EPSILON) {
return false; // Both points are the same.
+ }
// First check if they are parallel.
Vector3 normal = (rel / rel_l);
@@ -317,13 +337,15 @@ public:
real_t dist = z_dir.dot(p_from);
- if (dist >= p_radius)
+ if (dist >= p_radius) {
return false; // Too far away.
+ }
// Convert to 2D.
real_t w2 = p_radius * p_radius - dist * dist;
- if (w2 < CMP_EPSILON)
+ if (w2 < CMP_EPSILON) {
return false; // Avoid numerical error.
+ }
Size2 size(Math::sqrt(w2), p_height * 0.5);
Vector3 x_dir = z_dir.cross(Vector3(0, 0, 1)).normalized();
@@ -336,7 +358,6 @@ public:
int axis = -1;
for (int i = 0; i < 2; i++) {
-
real_t seg_from = from2D[i];
real_t seg_to = to2D[i];
real_t box_begin = -size[i];
@@ -344,17 +365,17 @@ public:
real_t cmin, cmax;
if (seg_from < seg_to) {
-
- if (seg_from > box_end || seg_to < box_begin)
+ if (seg_from > box_end || seg_to < box_begin) {
return false;
+ }
real_t length = seg_to - seg_from;
cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0;
cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1;
} else {
-
- if (seg_to > box_end || seg_from < box_begin)
+ if (seg_to > box_end || seg_from < box_begin) {
return false;
+ }
real_t length = seg_to - seg_from;
cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0;
cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1;
@@ -364,10 +385,12 @@ public:
min = cmin;
axis = i;
}
- if (cmax < max)
+ if (cmax < max) {
max = cmax;
- if (max < min)
+ }
+ if (max < min) {
return false;
+ }
}
// Convert to 3D again.
@@ -383,45 +406,47 @@ public:
res_normal.normalize();
- if (r_res)
+ if (r_res) {
*r_res = result;
- if (r_norm)
+ }
+ if (r_norm) {
*r_norm = res_normal;
+ }
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) {
-
real_t min = -1e20, max = 1e20;
Vector3 rel = p_to - p_from;
real_t rel_l = rel.length();
- if (rel_l < CMP_EPSILON)
+ if (rel_l < CMP_EPSILON) {
return false;
+ }
Vector3 dir = rel / rel_l;
int min_index = -1;
for (int i = 0; i < p_plane_count; i++) {
-
const Plane &p = p_planes[i];
real_t den = p.normal.dot(dir);
- if (Math::abs(den) <= CMP_EPSILON)
+ if (Math::abs(den) <= CMP_EPSILON) {
continue; // Ignore parallel plane.
+ }
real_t dist = -p.distance_to(p_from) / den;
if (den > 0) {
// Backwards facing plane.
- if (dist < max)
+ if (dist < max) {
max = dist;
+ }
} else {
-
// Front facing plane.
if (dist > min) {
min = dist;
@@ -430,42 +455,46 @@ public:
}
}
- if (max <= min || min < 0 || min > rel_l || min_index == -1) // Exit conditions.
+ if (max <= min || min < 0 || min > rel_l || min_index == -1) { // Exit conditions.
return false; // No intersection.
+ }
- if (p_res)
+ if (p_res) {
*p_res = p_from + dir * min;
- if (p_norm)
+ }
+ if (p_norm) {
*p_norm = p_planes[min_index].normal;
+ }
return true;
}
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];
real_t l2 = n.length_squared();
- if (l2 < 1e-20)
+ if (l2 < 1e-20) {
return p_segment[0]; // Both points are the same, just give any.
+ }
real_t d = n.dot(p) / l2;
- if (d <= 0.0)
+ if (d <= 0.0) {
return p_segment[0]; // Before first point.
- else if (d >= 1.0)
+ } else if (d >= 1.0) {
return p_segment[1]; // After first point.
- else
+ } else {
return p_segment[0] + n * d; // Inside.
+ }
}
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];
real_t l2 = n.length_squared();
- if (l2 < 1e-20)
+ if (l2 < 1e-20) {
return p_segment[0]; // Both points are the same, just give any.
+ }
real_t d = n.dot(p) / l2;
@@ -473,21 +502,22 @@ public:
}
static Vector2 get_closest_point_to_segment_2d(const Vector2 &p_point, const Vector2 *p_segment) {
-
Vector2 p = p_point - p_segment[0];
Vector2 n = p_segment[1] - p_segment[0];
real_t l2 = n.length_squared();
- if (l2 < 1e-20)
+ if (l2 < 1e-20) {
return p_segment[0]; // Both points are the same, just give any.
+ }
real_t d = n.dot(p) / l2;
- if (d <= 0.0)
+ if (d <= 0.0) {
return p_segment[0]; // Before first point.
- else if (d >= 1.0)
+ } else if (d >= 1.0) {
return p_segment[1]; // After first point.
- else
+ } else {
return p_segment[0] + n * d; // Inside.
+ }
}
static bool is_point_in_triangle(const Vector2 &s, const Vector2 &a, const Vector2 &b, const Vector2 &c) {
@@ -497,18 +527,20 @@ public:
bool orientation = an.cross(bn) > 0;
- if ((bn.cross(cn) > 0) != orientation) return false;
+ if ((bn.cross(cn) > 0) != orientation) {
+ return false;
+ }
return (cn.cross(an) > 0) == orientation;
}
static Vector2 get_closest_point_to_segment_uncapped_2d(const Vector2 &p_point, const Vector2 *p_segment) {
-
Vector2 p = p_point - p_segment[0];
Vector2 n = p_segment[1] - p_segment[0];
real_t l2 = n.length_squared();
- if (l2 < 1e-20)
+ if (l2 < 1e-20) {
return p_segment[0]; // Both points are the same, just give any.
+ }
real_t d = n.dot(p) / l2;
@@ -516,7 +548,6 @@ public:
}
static bool line_intersects_line_2d(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/
const real_t denom = p_dir_b.y * p_dir_a.x - p_dir_b.x * p_dir_a.y;
@@ -531,62 +562,68 @@ public:
}
static bool segment_intersects_segment_2d(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;
Vector2 C = p_from_b - p_from_a;
Vector2 D = p_to_b - p_from_a;
real_t ABlen = B.dot(B);
- if (ABlen <= 0)
+ if (ABlen <= 0) {
return false;
+ }
Vector2 Bn = B / ABlen;
C = Vector2(C.x * Bn.x + C.y * Bn.y, C.y * Bn.x - C.x * Bn.y);
D = Vector2(D.x * Bn.x + D.y * Bn.y, D.y * Bn.x - D.x * Bn.y);
- if ((C.y < 0 && D.y < 0) || (C.y >= 0 && D.y >= 0))
+ if ((C.y < 0 && D.y < 0) || (C.y >= 0 && D.y >= 0)) {
return false;
+ }
real_t ABpos = D.x + (C.x - D.x) * D.y / (D.y - C.y);
// Fail if segment C-D crosses line A-B outside of segment A-B.
- if (ABpos < 0 || ABpos > 1.0)
+ if (ABpos < 0 || ABpos > 1.0) {
return false;
+ }
// (4) Apply the discovered position to line A-B in the original coordinate system.
- if (r_result)
+ if (r_result) {
*r_result = p_from_a + B * ABpos;
+ }
return true;
}
static inline bool point_in_projected_triangle(const Vector3 &p_point, const Vector3 &p_v1, const Vector3 &p_v2, const Vector3 &p_v3) {
-
Vector3 face_n = (p_v1 - p_v3).cross(p_v1 - p_v2);
Vector3 n1 = (p_point - p_v3).cross(p_point - p_v2);
- if (face_n.dot(n1) < 0)
+ if (face_n.dot(n1) < 0) {
return false;
+ }
Vector3 n2 = (p_v1 - p_v3).cross(p_v1 - p_point);
- if (face_n.dot(n2) < 0)
+ if (face_n.dot(n2) < 0) {
return false;
+ }
Vector3 n3 = (p_v1 - p_point).cross(p_v1 - p_v2);
- if (face_n.dot(n3) < 0)
+ if (face_n.dot(n3) < 0) {
return false;
+ }
return true;
}
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]);
- if (d > p_sphere_radius || d < -p_sphere_radius) // Not touching the plane of the face, return.
+ if (d > p_sphere_radius || d < -p_sphere_radius) {
+ // Not touching the plane of the face, return.
return false;
+ }
Vector3 contact = p_sphere_pos - (p_normal * d);
@@ -604,7 +641,6 @@ public:
const Vector3 verts[4] = { p_triangle[0], p_triangle[1], p_triangle[2], p_triangle[0] }; // for() friendly
for (int i = 0; i < 3; i++) {
-
// Check edge cylinder.
Vector3 n1 = verts[i] - verts[i + 1];
@@ -629,7 +665,6 @@ public:
real_t sphere_at = n1.dot(n2);
if (sphere_at >= 0 && sphere_at < n1.dot(n1)) {
-
r_triangle_contact = p_sphere_pos - axis * (axis.dot(n2));
r_sphere_contact = p_sphere_pos - axis * p_sphere_radius;
// Point inside here.
@@ -639,7 +674,6 @@ public:
real_t r2 = p_sphere_radius * p_sphere_radius;
if (n2.length_squared() < r2) {
-
Vector3 n = (p_sphere_pos - verts[i + 1]).normalized();
r_triangle_contact = verts[i + 1];
@@ -662,12 +696,10 @@ public:
}
static inline bool is_point_in_circle(const Vector2 &p_point, const Vector2 &p_circle_pos, real_t p_circle_radius) {
-
return p_point.distance_squared_to(p_circle_pos) <= p_circle_radius * p_circle_radius;
}
static real_t segment_intersects_circle(const Vector2 &p_from, const Vector2 &p_to, const Vector2 &p_circle_pos, real_t p_circle_radius) {
-
Vector2 line_vec = p_to - p_from;
Vector2 vec_to_line = p_from - p_circle_pos;
@@ -683,7 +715,9 @@ public:
// If the term we intend to square root is less than 0 then the answer won't be real,
// so it definitely won't be t in the range 0 to 1.
- if (sqrtterm < 0) return -1;
+ if (sqrtterm < 0) {
+ return -1;
+ }
// If we can assume that the line segment starts outside the circle (e.g. for continuous time collision detection)
// then the following can be skipped and we can just return the equivalent of res1.
@@ -691,21 +725,25 @@ public:
real_t res1 = (-b - sqrtterm) / (2 * a);
real_t res2 = (-b + sqrtterm) / (2 * a);
- if (res1 >= 0 && res1 <= 1) return res1;
- if (res2 >= 0 && res2 <= 1) return res2;
+ if (res1 >= 0 && res1 <= 1) {
+ return res1;
+ }
+ if (res2 >= 0 && res2 <= 1) {
+ return res2;
+ }
return -1;
}
static inline Vector<Vector3> clip_polygon(const Vector<Vector3> &polygon, const Plane &p_plane) {
-
enum LocationCache {
LOC_INSIDE = 1,
LOC_BOUNDARY = 0,
LOC_OUTSIDE = -1
};
- if (polygon.size() == 0)
+ if (polygon.size() == 0) {
return polygon;
+ }
int *location_cache = (int *)alloca(sizeof(int) * polygon.size());
int inside_count = 0;
@@ -727,11 +765,8 @@ public:
}
if (outside_count == 0) {
-
return polygon; // No changes.
-
} else if (inside_count == 0) {
-
return Vector<Vector3>(); // Empty.
}
@@ -791,49 +826,40 @@ public:
};
static Vector<Vector<Point2>> merge_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
-
return _polypaths_do_operation(OPERATION_UNION, p_polygon_a, p_polygon_b);
}
static Vector<Vector<Point2>> clip_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
-
return _polypaths_do_operation(OPERATION_DIFFERENCE, p_polygon_a, p_polygon_b);
}
static Vector<Vector<Point2>> intersect_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
-
return _polypaths_do_operation(OPERATION_INTERSECTION, p_polygon_a, p_polygon_b);
}
static Vector<Vector<Point2>> exclude_polygons_2d(const Vector<Point2> &p_polygon_a, const Vector<Point2> &p_polygon_b) {
-
return _polypaths_do_operation(OPERATION_XOR, p_polygon_a, p_polygon_b);
}
static Vector<Vector<Point2>> clip_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) {
-
return _polypaths_do_operation(OPERATION_DIFFERENCE, p_polyline, p_polygon, true);
}
static Vector<Vector<Point2>> intersect_polyline_with_polygon_2d(const Vector<Vector2> &p_polyline, const Vector<Vector2> &p_polygon) {
-
return _polypaths_do_operation(OPERATION_INTERSECTION, p_polyline, p_polygon, true);
}
static Vector<Vector<Point2>> offset_polygon_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type) {
-
return _polypath_offset(p_polygon, p_delta, p_join_type, END_POLYGON);
}
static Vector<Vector<Point2>> offset_polyline_2d(const Vector<Vector2> &p_polygon, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type) {
-
ERR_FAIL_COND_V_MSG(p_end_type == END_POLYGON, Vector<Vector<Point2>>(), "Attempt to offset a polyline like a polygon (use offset_polygon_2d instead).");
return _polypath_offset(p_polygon, p_delta, p_join_type, p_end_type);
}
static Vector<int> triangulate_delaunay_2d(const Vector<Vector2> &p_points) {
-
Vector<Delaunay2D::Triangle> tr = Delaunay2D::triangulate(p_points);
Vector<int> triangles;
@@ -846,17 +872,18 @@ public:
}
static Vector<int> triangulate_polygon(const Vector<Vector2> &p_polygon) {
-
Vector<int> triangles;
- if (!Triangulate::triangulate(p_polygon, triangles))
+ if (!Triangulate::triangulate(p_polygon, triangles)) {
return Vector<int>(); //fail
+ }
return triangles;
}
static bool is_polygon_clockwise(const Vector<Vector2> &p_polygon) {
int c = p_polygon.size();
- if (c < 3)
+ if (c < 3) {
return false;
+ }
const Vector2 *p = p_polygon.ptr();
real_t sum = 0;
for (int i = 0; i < c; i++) {
@@ -871,8 +898,9 @@ public:
// Alternate implementation that should be faster.
static bool is_point_in_polygon(const Vector2 &p_point, const Vector<Vector2> &p_polygon) {
int c = p_polygon.size();
- if (c < 3)
+ if (c < 3) {
return false;
+ }
const Vector2 *p = p_polygon.ptr();
Vector2 further_away(-1e20, -1e20);
Vector2 further_away_opposite(1e20, 1e20);
@@ -905,7 +933,6 @@ public:
static Vector<Face3> wrap_geometry(Vector<Face3> p_array, real_t *p_error = nullptr);
struct MeshData {
-
struct Face {
Plane plane;
Vector<int> indices;
@@ -914,7 +941,6 @@ public:
Vector<Face> faces;
struct Edge {
-
int a, b;
};
@@ -926,7 +952,6 @@ public:
};
_FORCE_INLINE_ static int get_uv84_normal_bit(const Vector3 &p_vector) {
-
int lat = Math::fast_ftoi(Math::floor(Math::acos(p_vector.dot(Vector3(0, 1, 0))) * 4.0 / Math_PI + 0.5));
if (lat == 0) {
@@ -941,33 +966,35 @@ public:
}
_FORCE_INLINE_ static int get_uv84_normal_bit_neighbors(int p_idx) {
-
if (p_idx == 24) {
return 1 | 2 | 4 | 8;
} else if (p_idx == 25) {
return (1 << 23) | (1 << 22) | (1 << 21) | (1 << 20);
} else {
-
int ret = 0;
- if ((p_idx % 8) == 0)
+ if ((p_idx % 8) == 0) {
ret |= (1 << (p_idx + 7));
- else
+ } else {
ret |= (1 << (p_idx - 1));
- if ((p_idx % 8) == 7)
+ }
+ if ((p_idx % 8) == 7) {
ret |= (1 << (p_idx - 7));
- else
+ } else {
ret |= (1 << (p_idx + 1));
+ }
int mask = ret | (1 << p_idx);
- if (p_idx < 8)
+ if (p_idx < 8) {
ret |= 24;
- else
+ } else {
ret |= mask >> 8;
+ }
- if (p_idx >= 16)
+ if (p_idx >= 16) {
ret |= 25;
- else
+ } else {
ret |= mask << 8;
+ }
return ret;
}
@@ -989,15 +1016,17 @@ public:
// Build lower hull.
for (int i = 0; i < n; ++i) {
- while (k >= 2 && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0)
+ while (k >= 2 && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0) {
k--;
+ }
H.write[k++] = P[i];
}
// Build upper hull.
for (int i = n - 2, t = k + 1; i >= 0; i--) {
- while (k >= t && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0)
+ while (k >= t && vec2_cross(H[k - 2], H[k - 1], P[i]) <= 0) {
k--;
+ }
H.write[k++] = P[i];
}
@@ -1014,6 +1043,265 @@ public:
static void make_atlas(const Vector<Size2i> &p_rects, Vector<Point2i> &r_result, Size2i &r_size);
+ static Vector<Vector3> compute_convex_mesh_points(const Plane *p_planes, int p_plane_count);
+
+#define FINDMINMAX(x0, x1, x2, min, max) \
+ min = max = x0; \
+ if (x1 < min) { \
+ min = x1; \
+ } \
+ if (x1 > max) { \
+ max = x1; \
+ } \
+ if (x2 < min) { \
+ min = x2; \
+ } \
+ if (x2 > max) { \
+ max = x2; \
+ }
+
+ _FORCE_INLINE_ static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) {
+ int q;
+ Vector3 vmin, vmax;
+ for (q = 0; q <= 2; q++) {
+ if (normal[q] > 0.0f) {
+ vmin[q] = -maxbox[q];
+ vmax[q] = maxbox[q];
+ } else {
+ vmin[q] = maxbox[q];
+ vmax[q] = -maxbox[q];
+ }
+ }
+ if (normal.dot(vmin) + d > 0.0f) {
+ return false;
+ }
+ if (normal.dot(vmax) + d >= 0.0f) {
+ return true;
+ }
+
+ return false;
+ }
+
+/*======================== X-tests ========================*/
+#define AXISTEST_X01(a, b, fa, fb) \
+ p0 = a * v0.y - b * v0.z; \
+ p2 = a * v2.y - b * v2.z; \
+ if (p0 < p2) { \
+ min = p0; \
+ max = p2; \
+ } else { \
+ min = p2; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) { \
+ return false; \
+ }
+
+#define AXISTEST_X2(a, b, fa, fb) \
+ p0 = a * v0.y - b * v0.z; \
+ p1 = a * v1.y - b * v1.z; \
+ if (p0 < p1) { \
+ min = p0; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) { \
+ return false; \
+ }
+
+/*======================== Y-tests ========================*/
+#define AXISTEST_Y02(a, b, fa, fb) \
+ p0 = -a * v0.x + b * v0.z; \
+ p2 = -a * v2.x + b * v2.z; \
+ if (p0 < p2) { \
+ min = p0; \
+ max = p2; \
+ } else { \
+ min = p2; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) { \
+ return false; \
+ }
+
+#define AXISTEST_Y1(a, b, fa, fb) \
+ p0 = -a * v0.x + b * v0.z; \
+ p1 = -a * v1.x + b * v1.z; \
+ if (p0 < p1) { \
+ min = p0; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
+ if (min > rad || max < -rad) { \
+ return false; \
+ }
+
+ /*======================== Z-tests ========================*/
+
+#define AXISTEST_Z12(a, b, fa, fb) \
+ p1 = a * v1.x - b * v1.y; \
+ p2 = a * v2.x - b * v2.y; \
+ if (p2 < p1) { \
+ min = p2; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p2; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
+ if (min > rad || max < -rad) { \
+ return false; \
+ }
+
+#define AXISTEST_Z0(a, b, fa, fb) \
+ p0 = a * v0.x - b * v0.y; \
+ p1 = a * v1.x - b * v1.y; \
+ if (p0 < p1) { \
+ min = p0; \
+ max = p1; \
+ } else { \
+ min = p1; \
+ max = p0; \
+ } \
+ rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
+ if (min > rad || max < -rad) { \
+ return false; \
+ }
+
+ _FORCE_INLINE_ static bool triangle_box_overlap(const Vector3 &boxcenter, const Vector3 boxhalfsize, const Vector3 *triverts) {
+ /* use separating axis theorem to test overlap between triangle and box */
+ /* need to test for overlap in these directions: */
+ /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */
+ /* we do not even need to test these) */
+ /* 2) normal of the triangle */
+ /* 3) crossproduct(edge from tri, {x,y,z}-directin) */
+ /* this gives 3x3=9 more tests */
+ Vector3 v0, v1, v2;
+ float min, max, d, p0, p1, p2, rad, fex, fey, fez;
+ Vector3 normal, e0, e1, e2;
+
+ /* This is the fastest branch on Sun */
+ /* move everything so that the boxcenter is in (0,0,0) */
+
+ v0 = triverts[0] - boxcenter;
+ v1 = triverts[1] - boxcenter;
+ v2 = triverts[2] - boxcenter;
+
+ /* compute triangle edges */
+ e0 = v1 - v0; /* tri edge 0 */
+ e1 = v2 - v1; /* tri edge 1 */
+ e2 = v0 - v2; /* tri edge 2 */
+
+ /* Bullet 3: */
+ /* test the 9 tests first (this was faster) */
+ fex = Math::abs(e0.x);
+ fey = Math::abs(e0.y);
+ fez = Math::abs(e0.z);
+ AXISTEST_X01(e0.z, e0.y, fez, fey);
+ AXISTEST_Y02(e0.z, e0.x, fez, fex);
+ AXISTEST_Z12(e0.y, e0.x, fey, fex);
+
+ fex = Math::abs(e1.x);
+ fey = Math::abs(e1.y);
+ fez = Math::abs(e1.z);
+ AXISTEST_X01(e1.z, e1.y, fez, fey);
+ AXISTEST_Y02(e1.z, e1.x, fez, fex);
+ AXISTEST_Z0(e1.y, e1.x, fey, fex);
+
+ fex = Math::abs(e2.x);
+ fey = Math::abs(e2.y);
+ fez = Math::abs(e2.z);
+ AXISTEST_X2(e2.z, e2.y, fez, fey);
+ AXISTEST_Y1(e2.z, e2.x, fez, fex);
+ AXISTEST_Z12(e2.y, e2.x, fey, fex);
+
+ /* Bullet 1: */
+ /* first test overlap in the {x,y,z}-directions */
+ /* find min, max of the triangle each direction, and test for overlap in */
+ /* that direction -- this is equivalent to testing a minimal AABB around */
+ /* the triangle against the AABB */
+
+ /* test in X-direction */
+ FINDMINMAX(v0.x, v1.x, v2.x, min, max);
+ if (min > boxhalfsize.x || max < -boxhalfsize.x) {
+ return false;
+ }
+
+ /* test in Y-direction */
+ FINDMINMAX(v0.y, v1.y, v2.y, min, max);
+ if (min > boxhalfsize.y || max < -boxhalfsize.y) {
+ return false;
+ }
+
+ /* test in Z-direction */
+ FINDMINMAX(v0.z, v1.z, v2.z, min, max);
+ if (min > boxhalfsize.z || max < -boxhalfsize.z) {
+ return false;
+ }
+
+ /* Bullet 2: */
+ /* test if the box intersects the plane of the triangle */
+ /* compute plane equation of triangle: normal*x+d=0 */
+ normal = e0.cross(e1);
+ d = -normal.dot(v0); /* plane eq: normal.x+d=0 */
+ return planeBoxOverlap(normal, d, boxhalfsize); /* if true, box and triangle overlaps */
+ }
+
+ static Vector<Point2i> pack_rects(const Vector<Size2i> &p_sizes, const Size2i &p_atlas_size);
+ static Vector<Vector3i> partial_pack_rects(const Vector<Vector2i> &p_sizes, const Size2i &p_atlas_size);
+
+ static Vector<uint32_t> generate_edf(const Vector<bool> &p_voxels, const Vector3i &p_size, bool p_negative);
+ static Vector<int8_t> generate_sdf8(const Vector<uint32_t> &p_positive, const Vector<uint32_t> &p_negative);
+
+ static Vector3 triangle_get_barycentric_coords(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_c, const Vector3 &p_pos) {
+ Vector3 v0 = p_b - p_a;
+ Vector3 v1 = p_c - p_a;
+ Vector3 v2 = p_pos - p_a;
+
+ float d00 = v0.dot(v0);
+ float d01 = v0.dot(v1);
+ float d11 = v1.dot(v1);
+ float d20 = v2.dot(v0);
+ float d21 = v2.dot(v1);
+ float denom = (d00 * d11 - d01 * d01);
+ if (denom == 0) {
+ return Vector3(); //invalid triangle, return empty
+ }
+ float v = (d11 * d20 - d01 * d21) / denom;
+ float w = (d00 * d21 - d01 * d20) / denom;
+ float u = 1.0f - v - w;
+ return Vector3(u, v, w);
+ }
+
+ static Color tetrahedron_get_barycentric_coords(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_c, const Vector3 &p_d, const Vector3 &p_pos) {
+ Vector3 vap = p_pos - p_a;
+ Vector3 vbp = p_pos - p_b;
+
+ Vector3 vab = p_b - p_a;
+ Vector3 vac = p_c - p_a;
+ Vector3 vad = p_d - p_a;
+
+ Vector3 vbc = p_c - p_b;
+ Vector3 vbd = p_d - p_b;
+ // ScTP computes the scalar triple product
+#define STP(m_a, m_b, m_c) ((m_a).dot((m_b).cross((m_c))))
+ float va6 = STP(vbp, vbd, vbc);
+ float vb6 = STP(vap, vac, vad);
+ float vc6 = STP(vap, vad, vab);
+ float vd6 = STP(vap, vab, vac);
+ float v6 = 1 / STP(vab, vac, vad);
+ return Color(va6 * v6, vb6 * v6, vc6 * v6, vd6 * v6);
+#undef STP
+ }
+
private:
static Vector<Vector<Point2>> _polypaths_do_operation(PolyBooleanOperation p_op, const Vector<Point2> &p_polypath_a, const Vector<Point2> &p_polypath_b, bool is_a_open = false);
static Vector<Vector<Point2>> _polypath_offset(const Vector<Point2> &p_polypath, real_t p_delta, PolyJoinType p_join_type, PolyEndType p_end_type);
diff --git a/core/math/math_fieldwise.cpp b/core/math/math_fieldwise.cpp
index a47d4ef7ad..ef2a0c5339 100644
--- a/core/math/math_fieldwise.cpp
+++ b/core/math/math_fieldwise.cpp
@@ -41,7 +41,6 @@
}
Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const String &p_field) {
-
ERR_FAIL_COND_V(p_target.get_type() != p_source.get_type(), p_target);
/* clang-format makes a mess of this macro usage */
diff --git a/core/math/math_funcs.cpp b/core/math/math_funcs.cpp
index 7417e64ac1..1585c96b38 100644
--- a/core/math/math_funcs.cpp
+++ b/core/math/math_funcs.cpp
@@ -94,16 +94,18 @@ double Math::dectime(double p_value, double p_amount, double p_step) {
double sgn = p_value < 0 ? -1.0 : 1.0;
double val = Math::abs(p_value);
val -= p_amount * p_step;
- if (val < 0.0)
+ if (val < 0.0) {
val = 0.0;
+ }
return val * sgn;
}
double Math::ease(double p_x, double p_c) {
- if (p_x < 0)
+ if (p_x < 0) {
p_x = 0;
- else if (p_x > 1.0)
+ } else if (p_x > 1.0) {
p_x = 1.0;
+ }
if (p_c > 0) {
if (p_c < 1.0) {
return 1.0 - Math::pow(1.0 - p_x, 1.0 / p_c);
@@ -118,8 +120,9 @@ double Math::ease(double p_x, double p_c) {
} else {
return (1.0 - Math::pow(1.0 - (p_x - 0.5) * 2.0, -p_c)) * 0.5 + 0.5;
}
- } else
+ } else {
return 0; // no ease (raw)
+ }
}
double Math::stepify(double p_value, double p_step) {
@@ -130,7 +133,6 @@ double Math::stepify(double p_value, double p_step) {
}
uint32_t Math::larger_prime(uint32_t p_val) {
-
static const uint32_t primes[] = {
5,
13,
@@ -166,10 +168,10 @@ uint32_t Math::larger_prime(uint32_t p_val) {
int idx = 0;
while (true) {
-
ERR_FAIL_COND_V(primes[idx] == 0, 0);
- if (primes[idx] > p_val)
+ if (primes[idx] > p_val) {
return primes[idx];
+ }
idx++;
}
}
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 3e1eb14a6a..7a9fd60e23 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -41,7 +41,6 @@
#include <math.h>
class Math {
-
static RandomPCG default_rand;
public:
@@ -233,12 +232,16 @@ public:
static _ALWAYS_INLINE_ float range_lerp(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_weight) {
- if (is_equal_approx(p_from, p_to)) return p_from;
+ if (is_equal_approx(p_from, p_to)) {
+ return p_from;
+ }
double x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0, 1.0);
return x * x * (3.0 - 2.0 * x);
}
static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_weight) {
- if (is_equal_approx(p_from, p_to)) return p_from;
+ if (is_equal_approx(p_from, p_to)) {
+ return p_from;
+ }
float x = CLAMP((p_weight - p_from) / (p_to - p_from), 0.0f, 1.0f);
return x * x * (3.0f - 2.0f * x);
}
@@ -326,7 +329,6 @@ public:
}
static _ALWAYS_INLINE_ float absf(float g) {
-
union {
float f;
uint32_t i;
@@ -338,7 +340,6 @@ public:
}
static _ALWAYS_INLINE_ double absd(double g) {
-
union {
double d;
uint64_t i;
@@ -350,7 +351,6 @@ public:
//this function should be as fast as possible and rounding mode should not matter
static _ALWAYS_INLINE_ int fast_ftoi(float a) {
-
static int b;
#if (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0603) || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // windows 8 phone?
@@ -405,7 +405,6 @@ public:
}
static _ALWAYS_INLINE_ float halfptr_to_float(const uint16_t *h) {
-
union {
uint32_t u32;
float f32;
@@ -420,7 +419,6 @@ public:
}
static _ALWAYS_INLINE_ uint16_t make_half_float(float f) {
-
union {
float fv;
uint32_t ui;
@@ -451,7 +449,6 @@ public:
}
// check if exponent is <= -15
else if (exp <= 0x38000000) {
-
/*// store a denorm half-float value or zero
exp = (0x38000000 - exp) >> 23;
mantissa >>= (14 + exp);
@@ -476,10 +473,11 @@ public:
if (p_step != 0) {
float a = Math::stepify(p_target - p_offset, p_step + p_separation) + p_offset;
float b = a;
- if (p_target >= 0)
+ if (p_target >= 0) {
b -= p_separation;
- else
+ } else {
b += p_step;
+ }
return (Math::abs(p_target - a) < Math::abs(p_target - b)) ? a : b;
}
return p_target;
diff --git a/core/math/octree.h b/core/math/octree.h
index 5225fbecb4..c05fc4e9ed 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -34,6 +34,7 @@
#include "core/list.h"
#include "core/map.h"
#include "core/math/aabb.h"
+#include "core/math/geometry.h"
#include "core/math/vector3.h"
#include "core/print_string.h"
#include "core/variant.h"
@@ -51,7 +52,6 @@ public:
private:
enum {
-
NEG = 0,
POS = 1,
};
@@ -68,7 +68,6 @@ private:
};
struct PairKey {
-
union {
struct {
OctreeElementID A;
@@ -78,18 +77,14 @@ private:
};
_FORCE_INLINE_ bool operator<(const PairKey &p_pair) const {
-
return key < p_pair.key;
}
_FORCE_INLINE_ PairKey(OctreeElementID p_A, OctreeElementID p_B) {
-
if (p_A < p_B) {
-
A = p_A;
B = p_B;
} else {
-
B = p_A;
A = p_B;
}
@@ -101,53 +96,37 @@ private:
struct Element;
struct Octant {
-
// cached for FAST plane check
AABB aabb;
- uint64_t last_pass;
- Octant *parent;
- Octant *children[8];
+ uint64_t last_pass = 0;
+ Octant *parent = nullptr;
+ Octant *children[8] = { nullptr };
- int children_count; // cache for amount of childrens (fast check for removal)
- int parent_index; // cache for parent index (fast check for removal)
+ int children_count = 0; // cache for amount of childrens (fast check for removal)
+ int parent_index = -1; // cache for parent index (fast check for removal)
List<Element *, AL> pairable_elements;
List<Element *, AL> elements;
- Octant() {
- children_count = 0;
- parent_index = -1;
- last_pass = 0;
- parent = nullptr;
- for (int i = 0; i < 8; i++)
- children[i] = nullptr;
- }
-
- ~Octant() {
-
- /*
- for (int i=0;i<8;i++)
- memdelete_notnull(children[i]);
- */
- }
+ Octant() {}
+ ~Octant() {}
};
struct PairData;
struct Element {
+ Octree *octree = nullptr;
- Octree *octree;
-
- T *userdata;
- int subindex;
- bool pairable;
- uint32_t pairable_mask;
- uint32_t pairable_type;
+ T *userdata = nullptr;
+ int subindex = 0;
+ bool pairable = false;
+ uint32_t pairable_mask = 0;
+ uint32_t pairable_type = 0;
- uint64_t last_pass;
- OctreeElementID _id;
- Octant *common_parent;
+ uint64_t last_pass = 0;
+ OctreeElementID _id = 0;
+ Octant *common_parent = nullptr;
AABB aabb;
AABB container_aabb;
@@ -155,28 +134,16 @@ private:
List<PairData *, AL> pair_list;
struct OctantOwner {
-
Octant *octant;
typename List<Element *, AL>::Element *E;
}; // an element can be in max 8 octants
List<OctantOwner, AL> octant_owners;
- Element() {
- last_pass = 0;
- _id = 0;
- pairable = false;
- subindex = 0;
- userdata = 0;
- octree = 0;
- pairable_mask = 0;
- pairable_type = 0;
- common_parent = nullptr;
- }
+ Element() {}
};
struct PairData {
-
int refcount;
bool intersect;
Element *A, *B;
@@ -203,19 +170,15 @@ private:
int pair_count;
_FORCE_INLINE_ void _pair_check(PairData *p_pair) {
-
bool intersect = p_pair->A->aabb.intersects_inclusive(p_pair->B->aabb);
if (intersect != p_pair->intersect) {
-
if (intersect) {
-
if (pair_callback) {
p_pair->ud = pair_callback(pair_callback_userdata, p_pair->A->_id, p_pair->A->userdata, p_pair->A->subindex, p_pair->B->_id, p_pair->B->userdata, p_pair->B->subindex);
}
pair_count++;
} else {
-
if (unpair_callback) {
unpair_callback(pair_callback_userdata, p_pair->A->_id, p_pair->A->userdata, p_pair->A->subindex, p_pair->B->_id, p_pair->B->userdata, p_pair->B->subindex, p_pair->ud);
}
@@ -227,19 +190,19 @@ private:
}
_FORCE_INLINE_ void _pair_reference(Element *p_A, Element *p_B) {
-
- if (p_A == p_B || (p_A->userdata == p_B->userdata && p_A->userdata))
+ if (p_A == p_B || (p_A->userdata == p_B->userdata && p_A->userdata)) {
return;
+ }
if (!(p_A->pairable_type & p_B->pairable_mask) &&
- !(p_B->pairable_type & p_A->pairable_mask))
+ !(p_B->pairable_type & p_A->pairable_mask)) {
return; // none can pair with none
+ }
PairKey key(p_A->_id, p_B->_id);
typename PairMap::Element *E = pair_map.find(key);
if (!E) {
-
PairData pdata;
pdata.refcount = 1;
pdata.A = p_A;
@@ -254,15 +217,14 @@ private:
pair_callback(pair_callback_userdata,p_A->userdata,p_B->userdata);
*/
} else {
-
E->get().refcount++;
}
}
_FORCE_INLINE_ void _pair_unreference(Element *p_A, Element *p_B) {
-
- if (p_A == p_B)
+ if (p_A == p_B) {
return;
+ }
PairKey key(p_A->_id, p_B->_id);
typename PairMap::Element *E = pair_map.find(key);
@@ -295,24 +257,18 @@ private:
}
_FORCE_INLINE_ void _element_check_pairs(Element *p_element) {
-
typename List<PairData *, AL>::Element *E = p_element->pair_list.front();
while (E) {
-
_pair_check(E->get());
E = E->next();
}
}
_FORCE_INLINE_ void _optimize() {
-
while (root && root->children_count < 2 && !root->elements.size() && !(use_pairs && root->pairable_elements.size())) {
-
Octant *new_root = nullptr;
if (root->children_count == 1) {
-
for (int i = 0; i < 8; i++) {
-
if (root->children[i]) {
new_root = root->children[i];
root->children[i] = nullptr;
@@ -338,9 +294,10 @@ private:
void _unpair_element(Element *p_element, Octant *p_octant);
struct _CullConvexData {
-
const Plane *planes;
int plane_count;
+ const Vector3 *points;
+ int point_count;
T **result_array;
int *result_idx;
int result_max;
@@ -353,14 +310,14 @@ private:
void _cull_point(Octant *p_octant, const Vector3 &p_point, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask);
void _remove_tree(Octant *p_octant) {
-
- if (!p_octant)
+ if (!p_octant) {
return;
+ }
for (int i = 0; i < 8; i++) {
-
- if (p_octant->children[i])
+ if (p_octant->children[i]) {
_remove_tree(p_octant->children[i]);
+ }
}
memdelete_allocator<Octant, AL>(p_octant);
@@ -402,7 +359,6 @@ T *Octree<T, use_pairs, AL>::get(OctreeElementID p_id) const {
template <class T, bool use_pairs, class AL>
bool Octree<T, use_pairs, AL>::is_pairable(OctreeElementID p_id) const {
-
const typename ElementMap::Element *E = element_map.find(p_id);
ERR_FAIL_COND_V(!E, false);
return E->get().pairable;
@@ -410,7 +366,6 @@ bool Octree<T, use_pairs, AL>::is_pairable(OctreeElementID p_id) const {
template <class T, bool use_pairs, class AL>
int Octree<T, use_pairs, AL>::get_subindex(OctreeElementID p_id) const {
-
const typename ElementMap::Element *E = element_map.find(p_id);
ERR_FAIL_COND_V(!E, -1);
return E->get().subindex;
@@ -420,7 +375,6 @@ int Octree<T, use_pairs, AL>::get_subindex(OctreeElementID p_id) const {
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_octant) {
-
real_t element_size = p_element->aabb.get_longest_axis_size() * 1.01; // avoid precision issues
if (p_octant->aabb.size.x / OCTREE_DIVISOR < element_size) {
@@ -431,11 +385,9 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
owner.octant = p_octant;
if (use_pairs && p_element->pairable) {
-
p_octant->pairable_elements.push_back(p_element);
owner.E = p_octant->pairable_elements.back();
} else {
-
p_octant->elements.push_back(p_element);
owner.E = p_octant->elements.back();
}
@@ -450,11 +402,9 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
}
if (use_pairs && p_octant->children_count > 0) {
-
pass++; //elements below this only get ONE reference added
for (int i = 0; i < 8; i++) {
-
if (p_octant->children[i]) {
_pair_element(p_element, p_octant->children[i]);
}
@@ -466,7 +416,6 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
bool candidate = p_element->common_parent == nullptr;
for (int i = 0; i < 8; i++) {
-
if (p_octant->children[i]) {
/* element exists, go straight to it */
if (p_octant->children[i]->aabb.intersects_inclusive(p_element->aabb)) {
@@ -479,12 +428,15 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
AABB aabb = p_octant->aabb;
aabb.size *= 0.5;
- if (i & 1)
+ if (i & 1) {
aabb.position.x += aabb.size.x;
- if (i & 2)
+ }
+ if (i & 2) {
aabb.position.y += aabb.size.y;
- if (i & 4)
+ }
+ if (i & 4) {
aabb.position.z += aabb.size.z;
+ }
if (aabb.intersects_inclusive(p_element->aabb)) {
/* if actually intersects, create the child */
@@ -506,13 +458,11 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
}
if (candidate && splits > 1) {
-
p_element->common_parent = p_octant;
}
}
if (use_pairs) {
-
typename List<Element *, AL>::Element *E = p_octant->pairable_elements.front();
while (E) {
@@ -533,14 +483,12 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_ensure_valid_root(const AABB &p_aabb) {
-
if (!root) {
// octre is empty
AABB base(Vector3(), Vector3(1.0, 1.0, 1.0) * unit_size);
while (!base.encloses(p_aabb)) {
-
if (ABS(base.position.x + base.size.x) <= ABS(base.position.x)) {
/* grow towards positive */
base.size *= 2.0;
@@ -559,11 +507,9 @@ void Octree<T, use_pairs, AL>::_ensure_valid_root(const AABB &p_aabb) {
octant_count++;
} else {
-
AABB base = root->aabb;
while (!base.encloses(p_aabb)) {
-
ERR_FAIL_COND_MSG(base.size.x > OCTREE_SIZE_LIMIT, "Octree upper size limit reached, does the AABB supplied contain NAN?");
Octant *gp = memnew_allocator(Octant, AL);
@@ -592,15 +538,14 @@ void Octree<T, use_pairs, AL>::_ensure_valid_root(const AABB &p_aabb) {
template <class T, bool use_pairs, class AL>
bool Octree<T, use_pairs, AL>::_remove_element_from_octant(Element *p_element, Octant *p_octant, Octant *p_limit) {
-
bool octant_removed = false;
while (true) {
-
// check all exit conditions
- if (p_octant == p_limit) // reached limit, nothing to erase, exit
+ if (p_octant == p_limit) { // reached limit, nothing to erase, exit
return octant_removed;
+ }
bool unpaired = false;
@@ -629,7 +574,6 @@ bool Octree<T, use_pairs, AL>::_remove_element_from_octant(Element *p_element, O
Octant *parent = p_octant->parent;
if (p_octant->children_count == 0 && p_octant->elements.empty() && p_octant->pairable_elements.empty()) {
-
// erase octant
if (p_octant == root) { // won't have a parent, just erase
@@ -648,8 +592,9 @@ bool Octree<T, use_pairs, AL>::_remove_element_from_octant(Element *p_element, O
octant_removed = true;
}
- if (!removed && !unpaired)
+ if (!removed && !unpaired) {
return octant_removed; // no reason to keep going up anymore! was already visited and was not removed
+ }
p_octant = parent;
}
@@ -659,7 +604,6 @@ bool Octree<T, use_pairs, AL>::_remove_element_from_octant(Element *p_element, O
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_unpair_element(Element *p_element, Octant *p_octant) {
-
// always test pairable
typename List<Element *, AL>::Element *E = p_octant->pairable_elements.front();
while (E) {
@@ -684,25 +628,24 @@ void Octree<T, use_pairs, AL>::_unpair_element(Element *p_element, Octant *p_oct
p_octant->last_pass = pass;
- if (p_octant->children_count == 0)
+ if (p_octant->children_count == 0) {
return; // small optimization for leafs
+ }
for (int i = 0; i < 8; i++) {
-
- if (p_octant->children[i])
+ if (p_octant->children[i]) {
_unpair_element(p_element, p_octant->children[i]);
+ }
}
}
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_pair_element(Element *p_element, Octant *p_octant) {
-
// always test pairable
typename List<Element *, AL>::Element *E = p_octant->pairable_elements.front();
while (E) {
-
if (E->get()->last_pass != pass) { // only get ONE reference
_pair_reference(p_element, E->get());
E->get()->last_pass = pass;
@@ -723,30 +666,30 @@ void Octree<T, use_pairs, AL>::_pair_element(Element *p_element, Octant *p_octan
}
p_octant->last_pass = pass;
- if (p_octant->children_count == 0)
+ if (p_octant->children_count == 0) {
return; // small optimization for leafs
+ }
for (int i = 0; i < 8; i++) {
-
- if (p_octant->children[i])
+ if (p_octant->children[i]) {
_pair_element(p_element, p_octant->children[i]);
+ }
}
}
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_remove_element(Element *p_element) {
-
pass++; // will do a new pass for this
typename List<typename Element::OctantOwner, AL>::Element *I = p_element->octant_owners.front();
/* FIRST remove going up normally */
for (; I; I = I->next()) {
-
Octant *o = I->get().octant;
- if (!use_pairs) // small speedup
+ if (!use_pairs) { // small speedup
o->elements.erase(I->get().E);
+ }
_remove_element_from_octant(p_element, o);
}
@@ -756,30 +699,28 @@ void Octree<T, use_pairs, AL>::_remove_element(Element *p_element) {
I = p_element->octant_owners.front();
if (use_pairs) {
-
for (; I; I = I->next()) {
-
Octant *o = I->get().octant;
// erase children pairs, they are erased ONCE even if repeated
pass++;
for (int i = 0; i < 8; i++) {
-
- if (o->children[i])
+ if (o->children[i]) {
_unpair_element(p_element, o->children[i]);
+ }
}
- if (p_element->pairable)
+ if (p_element->pairable) {
o->pairable_elements.erase(I->get().E);
- else
+ } else {
o->elements.erase(I->get().E);
+ }
}
}
p_element->octant_owners.clear();
if (use_pairs) {
-
int remaining = p_element->pair_list.size();
//p_element->pair_list.clear();
ERR_FAIL_COND(remaining);
@@ -788,7 +729,6 @@ void Octree<T, use_pairs, AL>::_remove_element(Element *p_element) {
template <class T, bool use_pairs, class AL>
OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const AABB &p_aabb, int p_subindex, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
-
// check for AABB validity
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_V(p_aabb.position.x > 1e15 || p_aabb.position.x < -1e15, 0);
@@ -819,8 +759,9 @@ OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const AABB &p_aa
if (!e.aabb.has_no_surface()) {
_ensure_valid_root(p_aabb);
_insert_element(&e, root);
- if (use_pairs)
+ if (use_pairs) {
_element_check_pairs(&e);
+ }
}
return last_element_id - 1;
@@ -828,7 +769,6 @@ OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const AABB &p_aa
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
-
#ifdef DEBUG_ENABLED
// check for AABB validity
ERR_FAIL_COND(p_aabb.position.x > 1e15 || p_aabb.position.x < -1e15);
@@ -849,7 +789,6 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
bool new_has_surf = !p_aabb.has_no_surface();
if (old_has_surf != new_has_surf) {
-
if (old_has_surf) {
_remove_element(&e); // removing
e.common_parent = nullptr;
@@ -860,22 +799,24 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
e.common_parent = nullptr;
e.aabb = p_aabb;
_insert_element(&e, root);
- if (use_pairs)
+ if (use_pairs) {
_element_check_pairs(&e);
+ }
}
return;
}
- if (!old_has_surf) // doing nothing
+ if (!old_has_surf) { // doing nothing
return;
+ }
// it still is enclosed in the same AABB it was assigned to
if (e.container_aabb.encloses(p_aabb)) {
-
e.aabb = p_aabb;
- if (use_pairs)
+ if (use_pairs) {
_element_check_pairs(&e); // must check pairs anyway
+ }
return;
}
@@ -895,8 +836,9 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
//src is now the place towards where insertion is going to happen
pass++;
- while (common_parent && !common_parent->aabb.encloses(p_aabb))
+ while (common_parent && !common_parent->aabb.encloses(p_aabb)) {
common_parent = common_parent->parent;
+ }
ERR_FAIL_COND(!common_parent);
@@ -910,7 +852,6 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
pass++;
for (typename List<typename Element::OctantOwner, AL>::Element *F = owners.front(); F;) {
-
Octant *o = F->get().octant;
typename List<typename Element::OctantOwner, AL>::Element *N = F->next();
@@ -919,13 +860,13 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
o->elements.erase( F->get().E );
*/
- if (use_pairs && e.pairable)
+ if (use_pairs && e.pairable) {
o->pairable_elements.erase(F->get().E);
- else
+ } else {
o->elements.erase(F->get().E);
+ }
if (_remove_element_from_octant(&e, o, common_parent->parent)) {
-
owners.erase(F);
}
@@ -935,15 +876,14 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
if (use_pairs) {
//unpair child elements in anything that survived
for (typename List<typename Element::OctantOwner, AL>::Element *F = owners.front(); F; F = F->next()) {
-
Octant *o = F->get().octant;
// erase children pairs, unref ONCE
pass++;
for (int i = 0; i < 8; i++) {
-
- if (o->children[i])
+ if (o->children[i]) {
_unpair_element(&e, o->children[i]);
+ }
}
}
@@ -955,14 +895,14 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const AABB &p_aabb) {
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::set_pairable(OctreeElementID p_id, bool p_pairable, uint32_t p_pairable_type, uint32_t p_pairable_mask) {
-
typename ElementMap::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
Element &e = E->get();
- if (p_pairable == e.pairable && e.pairable_type == p_pairable_type && e.pairable_mask == p_pairable_mask)
+ if (p_pairable == e.pairable && e.pairable_type == p_pairable_type && e.pairable_mask == p_pairable_mask) {
return; // no changes, return
+ }
if (!e.aabb.has_no_surface()) {
_remove_element(&e);
@@ -976,21 +916,20 @@ void Octree<T, use_pairs, AL>::set_pairable(OctreeElementID p_id, bool p_pairabl
if (!e.aabb.has_no_surface()) {
_ensure_valid_root(e.aabb);
_insert_element(&e, root);
- if (use_pairs)
+ if (use_pairs) {
_element_check_pairs(&e);
+ }
}
}
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::erase(OctreeElementID p_id) {
-
typename ElementMap::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
Element &e = E->get();
if (!e.aabb.has_no_surface()) {
-
_remove_element(&e);
}
@@ -1000,30 +939,27 @@ void Octree<T, use_pairs, AL>::erase(OctreeElementID p_id) {
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p_cull) {
-
- if (*p_cull->result_idx == p_cull->result_max)
+ if (*p_cull->result_idx == p_cull->result_max) {
return; //pointless
+ }
if (!p_octant->elements.empty()) {
-
typename List<Element *, AL>::Element *I;
I = p_octant->elements.front();
for (; I; I = I->next()) {
-
Element *e = I->get();
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_cull->mask)))
+ if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_cull->mask))) {
continue;
+ }
e->last_pass = pass;
- if (e->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count)) {
-
+ if (e->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
if (*p_cull->result_idx < p_cull->result_max) {
p_cull->result_array[*p_cull->result_idx] = e->userdata;
(*p_cull->result_idx)++;
} else {
-
return; // pointless to continue
}
}
@@ -1031,26 +967,22 @@ void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p
}
if (use_pairs && !p_octant->pairable_elements.empty()) {
-
typename List<Element *, AL>::Element *I;
I = p_octant->pairable_elements.front();
for (; I; I = I->next()) {
-
Element *e = I->get();
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_cull->mask)))
+ if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_cull->mask))) {
continue;
+ }
e->last_pass = pass;
- if (e->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count)) {
-
+ if (e->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
if (*p_cull->result_idx < p_cull->result_max) {
-
p_cull->result_array[*p_cull->result_idx] = e->userdata;
(*p_cull->result_idx)++;
} else {
-
return; // pointless to continue
}
}
@@ -1058,8 +990,7 @@ void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p
}
for (int i = 0; i < 8; i++) {
-
- if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count)) {
+ if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_convex_shape(p_cull->planes, p_cull->plane_count, p_cull->points, p_cull->point_count)) {
_cull_convex(p_octant->children[i], p_cull);
}
}
@@ -1067,33 +998,30 @@ void Octree<T, use_pairs, AL>::_cull_convex(Octant *p_octant, _CullConvexData *p
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
-
- if (*p_result_idx == p_result_max)
+ if (*p_result_idx == p_result_max) {
return; //pointless
+ }
if (!p_octant->elements.empty()) {
-
typename List<Element *, AL>::Element *I;
I = p_octant->elements.front();
for (; I; I = I->next()) {
-
Element *e = I->get();
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask)))
+ if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue;
+ }
e->last_pass = pass;
if (p_aabb.intersects_inclusive(e->aabb)) {
-
if (*p_result_idx < p_result_max) {
-
p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array)
+ if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex;
+ }
(*p_result_idx)++;
} else {
-
return; // pointless to continue
}
}
@@ -1101,27 +1029,24 @@ void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb,
}
if (use_pairs && !p_octant->pairable_elements.empty()) {
-
typename List<Element *, AL>::Element *I;
I = p_octant->pairable_elements.front();
for (; I; I = I->next()) {
-
Element *e = I->get();
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask)))
+ if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue;
+ }
e->last_pass = pass;
if (p_aabb.intersects_inclusive(e->aabb)) {
-
if (*p_result_idx < p_result_max) {
-
p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array)
+ if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex;
+ }
(*p_result_idx)++;
} else {
-
return; // pointless to continue
}
}
@@ -1129,7 +1054,6 @@ void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb,
}
for (int i = 0; i < 8; i++) {
-
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_inclusive(p_aabb)) {
_cull_aabb(p_octant->children[i], p_aabb, p_result_array, p_result_idx, p_result_max, p_subindex_array, p_mask);
}
@@ -1138,33 +1062,30 @@ void Octree<T, use_pairs, AL>::_cull_aabb(Octant *p_octant, const AABB &p_aabb,
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
-
- if (*p_result_idx == p_result_max)
+ if (*p_result_idx == p_result_max) {
return; //pointless
+ }
if (!p_octant->elements.empty()) {
-
typename List<Element *, AL>::Element *I;
I = p_octant->elements.front();
for (; I; I = I->next()) {
-
Element *e = I->get();
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask)))
+ if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue;
+ }
e->last_pass = pass;
if (e->aabb.intersects_segment(p_from, p_to)) {
-
if (*p_result_idx < p_result_max) {
-
p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array)
+ if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex;
+ }
(*p_result_idx)++;
} else {
-
return; // pointless to continue
}
}
@@ -1172,30 +1093,27 @@ void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_
}
if (use_pairs && !p_octant->pairable_elements.empty()) {
-
typename List<Element *, AL>::Element *I;
I = p_octant->pairable_elements.front();
for (; I; I = I->next()) {
-
Element *e = I->get();
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask)))
+ if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue;
+ }
e->last_pass = pass;
if (e->aabb.intersects_segment(p_from, p_to)) {
-
if (*p_result_idx < p_result_max) {
-
p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array)
+ if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex;
+ }
(*p_result_idx)++;
} else {
-
return; // pointless to continue
}
}
@@ -1203,7 +1121,6 @@ void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_
}
for (int i = 0; i < 8; i++) {
-
if (p_octant->children[i] && p_octant->children[i]->aabb.intersects_segment(p_from, p_to)) {
_cull_segment(p_octant->children[i], p_from, p_to, p_result_array, p_result_idx, p_result_max, p_subindex_array, p_mask);
}
@@ -1212,33 +1129,30 @@ void Octree<T, use_pairs, AL>::_cull_segment(Octant *p_octant, const Vector3 &p_
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_point, T **p_result_array, int *p_result_idx, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
-
- if (*p_result_idx == p_result_max)
+ if (*p_result_idx == p_result_max) {
return; //pointless
+ }
if (!p_octant->elements.empty()) {
-
typename List<Element *, AL>::Element *I;
I = p_octant->elements.front();
for (; I; I = I->next()) {
-
Element *e = I->get();
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask)))
+ if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue;
+ }
e->last_pass = pass;
if (e->aabb.has_point(p_point)) {
-
if (*p_result_idx < p_result_max) {
-
p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array)
+ if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex;
+ }
(*p_result_idx)++;
} else {
-
return; // pointless to continue
}
}
@@ -1246,30 +1160,27 @@ void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_po
}
if (use_pairs && !p_octant->pairable_elements.empty()) {
-
typename List<Element *, AL>::Element *I;
I = p_octant->pairable_elements.front();
for (; I; I = I->next()) {
-
Element *e = I->get();
- if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask)))
+ if (e->last_pass == pass || (use_pairs && !(e->pairable_type & p_mask))) {
continue;
+ }
e->last_pass = pass;
if (e->aabb.has_point(p_point)) {
-
if (*p_result_idx < p_result_max) {
-
p_result_array[*p_result_idx] = e->userdata;
- if (p_subindex_array)
+ if (p_subindex_array) {
p_subindex_array[*p_result_idx] = e->subindex;
+ }
(*p_result_idx)++;
} else {
-
return; // pointless to continue
}
}
@@ -1277,7 +1188,6 @@ void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_po
}
for (int i = 0; i < 8; i++) {
-
//could be optimized..
if (p_octant->children[i] && p_octant->children[i]->aabb.has_point(p_point)) {
_cull_point(p_octant->children[i], p_point, p_result_array, p_result_idx, p_result_max, p_subindex_array, p_mask);
@@ -1287,15 +1197,22 @@ void Octree<T, use_pairs, AL>::_cull_point(Octant *p_octant, const Vector3 &p_po
template <class T, bool use_pairs, class AL>
int Octree<T, use_pairs, AL>::cull_convex(const Vector<Plane> &p_convex, T **p_result_array, int p_result_max, uint32_t p_mask) {
+ if (!root || p_convex.size() == 0) {
+ return 0;
+ }
- if (!root)
+ Vector<Vector3> convex_points = Geometry::compute_convex_mesh_points(&p_convex[0], p_convex.size());
+ if (convex_points.size() == 0) {
return 0;
+ }
int result_count = 0;
pass++;
_CullConvexData cdata;
cdata.planes = &p_convex[0];
cdata.plane_count = p_convex.size();
+ cdata.points = &convex_points[0];
+ cdata.point_count = convex_points.size();
cdata.result_array = p_result_array;
cdata.result_max = p_result_max;
cdata.result_idx = &result_count;
@@ -1308,9 +1225,9 @@ int Octree<T, use_pairs, AL>::cull_convex(const Vector<Plane> &p_convex, T **p_r
template <class T, bool use_pairs, class AL>
int Octree<T, use_pairs, AL>::cull_aabb(const AABB &p_aabb, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
-
- if (!root)
+ if (!root) {
return 0;
+ }
int result_count = 0;
pass++;
@@ -1321,9 +1238,9 @@ int Octree<T, use_pairs, AL>::cull_aabb(const AABB &p_aabb, T **p_result_array,
template <class T, bool use_pairs, class AL>
int Octree<T, use_pairs, AL>::cull_segment(const Vector3 &p_from, const Vector3 &p_to, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
-
- if (!root)
+ if (!root) {
return 0;
+ }
int result_count = 0;
pass++;
@@ -1334,9 +1251,9 @@ int Octree<T, use_pairs, AL>::cull_segment(const Vector3 &p_from, const Vector3
template <class T, bool use_pairs, class AL>
int Octree<T, use_pairs, AL>::cull_point(const Vector3 &p_point, T **p_result_array, int p_result_max, int *p_subindex_array, uint32_t p_mask) {
-
- if (!root)
+ if (!root) {
return 0;
+ }
int result_count = 0;
pass++;
@@ -1347,20 +1264,18 @@ int Octree<T, use_pairs, AL>::cull_point(const Vector3 &p_point, T **p_result_ar
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::set_pair_callback(PairCallback p_callback, void *p_userdata) {
-
pair_callback = p_callback;
pair_callback_userdata = p_userdata;
}
+
template <class T, bool use_pairs, class AL>
void Octree<T, use_pairs, AL>::set_unpair_callback(UnpairCallback p_callback, void *p_userdata) {
-
unpair_callback = p_callback;
unpair_callback_userdata = p_userdata;
}
template <class T, bool use_pairs, class AL>
Octree<T, use_pairs, AL>::Octree(real_t p_unit_size) {
-
last_element_id = 1;
pass = 1;
unit_size = p_unit_size;
diff --git a/core/math/plane.cpp b/core/math/plane.cpp
index a3818698bc..df37ceb0e5 100644
--- a/core/math/plane.cpp
+++ b/core/math/plane.cpp
@@ -33,12 +33,10 @@
#include "core/math/math_funcs.h"
void Plane::set_normal(const Vector3 &p_normal) {
-
normal = p_normal;
}
void Plane::normalize() {
-
real_t l = normal.length();
if (l == 0) {
*this = Plane(0, 0, 0, 0);
@@ -49,27 +47,25 @@ void Plane::normalize() {
}
Plane Plane::normalized() const {
-
Plane p = *this;
p.normalize();
return p;
}
Vector3 Plane::get_any_point() const {
-
return get_normal() * d;
}
Vector3 Plane::get_any_perpendicular_normal() const {
-
static const Vector3 p1 = Vector3(1, 0, 0);
static const Vector3 p2 = Vector3(0, 1, 0);
Vector3 p;
- if (ABS(normal.dot(p1)) > 0.99) // if too similar to p1
+ if (ABS(normal.dot(p1)) > 0.99) { // if too similar to p1
p = p2; // use p2
- else
+ } else {
p = p1; // use p1
+ }
p -= normal * normal.dot(p);
p.normalize();
@@ -80,7 +76,6 @@ Vector3 Plane::get_any_perpendicular_normal() const {
/* intersections */
bool Plane::intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r_result) const {
-
const Plane &p_plane0 = *this;
Vector3 normal0 = p_plane0.normal;
Vector3 normal1 = p_plane1.normal;
@@ -88,8 +83,9 @@ bool Plane::intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r
real_t denom = vec3_cross(normal0, normal1).dot(normal2);
- if (Math::is_zero_approx(denom))
+ if (Math::is_zero_approx(denom)) {
return false;
+ }
if (r_result) {
*r_result = ((vec3_cross(normal1, normal2) * p_plane0.d) +
@@ -102,13 +98,11 @@ bool Plane::intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r
}
bool Plane::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection) const {
-
Vector3 segment = p_dir;
real_t den = normal.dot(segment);
//printf("den is %i\n",den);
if (Math::is_zero_approx(den)) {
-
return false;
}
@@ -127,13 +121,11 @@ bool Plane::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3
}
bool Plane::intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 *p_intersection) const {
-
Vector3 segment = p_begin - p_end;
real_t den = normal.dot(segment);
//printf("den is %i\n",den);
if (Math::is_zero_approx(den)) {
-
return false;
}
@@ -141,7 +133,6 @@ bool Plane::intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vec
//printf("dist is %i\n",dist);
if (dist < -CMP_EPSILON || dist > (1.0 + CMP_EPSILON)) {
-
return false;
}
@@ -153,12 +144,14 @@ bool Plane::intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vec
/* misc */
-bool Plane::is_equal_approx(const Plane &p_plane) const {
+bool Plane::is_equal_approx_any_side(const Plane &p_plane) const {
+ return (normal.is_equal_approx(p_plane.normal) && Math::is_equal_approx(d, p_plane.d)) || (normal.is_equal_approx(-p_plane.normal) && Math::is_equal_approx(d, -p_plane.d));
+}
+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);
}
Plane::operator String() const {
-
return normal.operator String() + ", " + rtos(d);
}
diff --git a/core/math/plane.h b/core/math/plane.h
index 771c8fc705..9a3e5a485f 100644
--- a/core/math/plane.h
+++ b/core/math/plane.h
@@ -36,7 +36,7 @@
class Plane {
public:
Vector3 normal;
- real_t d;
+ real_t d = 0;
void set_normal(const Vector3 &p_normal);
_FORCE_INLINE_ Vector3 get_normal() const { return normal; }; ///Point is coplanar, CMP_EPSILON for precision
@@ -56,12 +56,11 @@ public:
/* intersections */
- bool intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r_result = 0) const;
+ bool intersect_3(const Plane &p_plane1, const Plane &p_plane2, Vector3 *r_result = nullptr) const;
bool intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *p_intersection) const;
bool intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 *p_intersection) const;
_FORCE_INLINE_ Vector3 project(const Vector3 &p_point) const {
-
return p_point - normal * distance_to(p_point);
}
@@ -69,13 +68,13 @@ public:
Plane operator-() const { return Plane(-normal, -d); }
bool is_equal_approx(const Plane &p_plane) const;
+ bool is_equal_approx_any_side(const Plane &p_plane) const;
_FORCE_INLINE_ bool operator==(const Plane &p_plane) const;
_FORCE_INLINE_ bool operator!=(const Plane &p_plane) const;
operator String() const;
- _FORCE_INLINE_ Plane() :
- d(0) {}
+ _FORCE_INLINE_ Plane() {}
_FORCE_INLINE_ 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) {}
@@ -86,17 +85,14 @@ public:
};
bool Plane::is_point_over(const Vector3 &p_point) const {
-
return (normal.dot(p_point) > d);
}
real_t Plane::distance_to(const Vector3 &p_point) const {
-
return (normal.dot(p_point) - d);
}
bool Plane::has_point(const Vector3 &p_point, real_t _epsilon) const {
-
real_t dist = normal.dot(p_point) - d;
dist = ABS(dist);
return (dist <= _epsilon);
@@ -113,23 +109,21 @@ Plane::Plane(const Vector3 &p_point, const Vector3 &p_normal) :
}
Plane::Plane(const Vector3 &p_point1, const Vector3 &p_point2, const Vector3 &p_point3, ClockDirection p_dir) {
-
- if (p_dir == CLOCKWISE)
+ if (p_dir == CLOCKWISE) {
normal = (p_point1 - p_point3).cross(p_point1 - p_point2);
- else
+ } else {
normal = (p_point1 - p_point2).cross(p_point1 - p_point3);
+ }
normal.normalize();
d = normal.dot(p_point1);
}
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 {
-
return normal != p_plane.normal || d != p_plane.d;
}
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index 61cd41b23d..c10f5da494 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -107,7 +107,6 @@ Vector3 Quat::get_euler_yxz() const {
}
void Quat::operator*=(const Quat &q) {
-
set(w * q.x + x * q.w + y * q.z - z * q.y,
w * q.y + y * q.w + z * q.x - x * q.z,
w * q.z + z * q.w + x * q.y - y * q.x,
@@ -115,19 +114,16 @@ void Quat::operator*=(const Quat &q) {
}
Quat Quat::operator*(const Quat &q) const {
-
Quat r = *this;
r *= q;
return r;
}
bool Quat::is_equal_approx(const Quat &p_quat) const {
-
return Math::is_equal_approx(x, p_quat.x) && Math::is_equal_approx(y, p_quat.y) && Math::is_equal_approx(z, p_quat.z) && Math::is_equal_approx(w, p_quat.w);
}
real_t Quat::length() const {
-
return Math::sqrt(length_squared());
}
@@ -206,7 +202,9 @@ Quat Quat::slerpni(const Quat &q, const real_t &t) const {
real_t dot = from.dot(q);
- if (Math::absf(dot) > 0.9999) return from;
+ if (Math::absf(dot) > 0.9999) {
+ return from;
+ }
real_t theta = Math::acos(dot),
sinT = 1.0 / Math::sin(theta),
@@ -232,7 +230,6 @@ Quat Quat::cubic_slerp(const Quat &q, const Quat &prep, const Quat &postq, const
}
Quat::operator String() const {
-
return String::num(x) + ", " + String::num(y) + ", " + String::num(z) + ", " + String::num(w);
}
@@ -241,9 +238,9 @@ void Quat::set_axis_angle(const Vector3 &axis, const real_t &angle) {
ERR_FAIL_COND_MSG(!axis.is_normalized(), "The axis Vector3 must be normalized.");
#endif
real_t d = axis.length();
- if (d == 0)
+ if (d == 0) {
set(0, 0, 0, 0);
- else {
+ } else {
real_t sin_angle = Math::sin(angle * 0.5);
real_t cos_angle = Math::cos(angle * 0.5);
real_t s = sin_angle / d;
diff --git a/core/math/quat.h b/core/math/quat.h
index b3135ad1ca..64d0f00912 100644
--- a/core/math/quat.h
+++ b/core/math/quat.h
@@ -40,7 +40,7 @@
class Quat {
public:
- real_t x, y, z, w;
+ real_t x = 0, y = 0, z = 0, w = 1;
_FORCE_INLINE_ real_t length_squared() const;
bool is_equal_approx(const Quat &p_quat) const;
@@ -112,7 +112,9 @@ public:
z = p_z;
w = p_w;
}
- inline Quat(real_t p_x, real_t p_y, real_t p_z, real_t p_w) :
+
+ _FORCE_INLINE_ Quat() {}
+ _FORCE_INLINE_ Quat(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),
@@ -147,7 +149,6 @@ public:
z = 0;
w = 0;
} else {
-
real_t s = Math::sqrt((1.0 + d) * 2.0);
real_t rs = 1.0 / s;
@@ -157,13 +158,6 @@ public:
w = s * 0.5;
}
}
-
- inline Quat() :
- x(0),
- y(0),
- z(0),
- w(1) {
- }
};
real_t Quat::dot(const Quat &q) const {
@@ -196,7 +190,6 @@ void Quat::operator*=(const real_t &s) {
}
void Quat::operator/=(const real_t &s) {
-
*this *= 1.0 / s;
}
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index 7fbb26c377..fe16904448 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -35,12 +35,10 @@
uint32_t QuickHull::debug_stop_after = 0xFFFFFFFF;
Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_mesh) {
-
/* CREATE AABB VOLUME */
AABB aabb;
for (int i = 0; i < p_points.size(); i++) {
-
if (i == 0) {
aabb.position = p_points[i];
} else {
@@ -57,7 +55,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
Set<Vector3> valid_cache;
for (int i = 0; i < p_points.size(); i++) {
-
Vector3 sp = p_points[i].snapped(Vector3(0.0001, 0.0001, 0.0001));
if (valid_cache.has(sp)) {
valid_points.write[i] = false;
@@ -78,12 +75,11 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
real_t max = 0, min = 0;
for (int i = 0; i < p_points.size(); i++) {
-
- if (!valid_points[i])
+ if (!valid_points[i]) {
continue;
+ }
real_t d = p_points[i][longest_axis];
if (i == 0 || d < min) {
-
simplex[0] = i;
min = d;
}
@@ -102,15 +98,14 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
Vector3 rel12 = p_points[simplex[0]] - p_points[simplex[1]];
for (int i = 0; i < p_points.size(); i++) {
-
- if (!valid_points[i])
+ if (!valid_points[i]) {
continue;
+ }
Vector3 n = rel12.cross(p_points[simplex[0]] - p_points[i]).cross(rel12).normalized();
real_t d = Math::abs(n.dot(p_points[simplex[0]]) - n.dot(p_points[i]));
if (i == 0 || d > maxd) {
-
maxd = d;
simplex[2] = i;
}
@@ -124,14 +119,13 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
Plane p(p_points[simplex[0]], p_points[simplex[1]], p_points[simplex[2]]);
for (int i = 0; i < p_points.size(); i++) {
-
- if (!valid_points[i])
+ if (!valid_points[i]) {
continue;
+ }
real_t d = Math::abs(p.distance_to(p_points[i]));
if (i == 0 || d > maxd) {
-
maxd = d;
simplex[3] = i;
}
@@ -152,7 +146,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
List<Face> faces;
for (int i = 0; i < 4; i++) {
-
static const int face_order[4][3] = {
{ 0, 1, 2 },
{ 0, 1, 3 },
@@ -183,22 +176,24 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
/* COMPUTE AVAILABLE VERTICES */
for (int i = 0; i < p_points.size(); i++) {
-
- if (i == simplex[0])
+ if (i == simplex[0]) {
continue;
- if (i == simplex[1])
+ }
+ if (i == simplex[1]) {
continue;
- if (i == simplex[2])
+ }
+ if (i == simplex[2]) {
continue;
- if (i == simplex[3])
+ }
+ if (i == simplex[3]) {
continue;
- if (!valid_points[i])
+ }
+ if (!valid_points[i]) {
continue;
+ }
for (List<Face>::Element *E = faces.front(); E; E = E->next()) {
-
if (E->get().plane.distance_to(p_points[i]) > over_tolerance) {
-
E->get().points_over.push_back(i);
break;
}
@@ -219,7 +214,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
uint32_t debug_stop = debug_stop_after;
while (debug_stop > 0 && faces.back()->get().points_over.size()) {
-
debug_stop--;
Face &f = faces.back()->get();
@@ -228,7 +222,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
real_t next_d = 0;
for (int i = 0; i < f.points_over.size(); i++) {
-
real_t d = f.plane.distance_to(p_points[f.points_over[i]]);
if (d > next_d) {
@@ -247,9 +240,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
Map<Edge, FaceConnect> lit_edges; //create this on the flight, should not be that bad for performance and simplifies code a lot
for (List<Face>::Element *E = faces.front(); E; E = E->next()) {
-
if (E->get().plane.distance_to(v) > 0) {
-
lit_faces.push_back(E);
for (int i = 0; i < 3; i++) {
@@ -265,7 +256,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
//left
F->get().left = E;
} else {
-
F->get().right = E;
}
}
@@ -276,7 +266,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
List<List<Face>::Element *> new_faces; //new faces
for (Map<Edge, FaceConnect>::Element *E = lit_edges.front(); E; E = E->next()) {
-
FaceConnect &fc = E->get();
if (fc.left && fc.right) {
continue; //edge is uninteresting, not on horizont
@@ -304,17 +293,15 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
//distribute points into new faces
for (List<List<Face>::Element *>::Element *F = lit_faces.front(); F; F = F->next()) {
-
Face &lf = F->get()->get();
for (int i = 0; i < lf.points_over.size(); i++) {
-
- if (lf.points_over[i] == f.points_over[next]) //do not add current one
+ if (lf.points_over[i] == f.points_over[next]) { //do not add current one
continue;
+ }
Vector3 p = p_points[lf.points_over[i]];
for (List<List<Face>::Element *>::Element *E = new_faces.front(); E; E = E->next()) {
-
Face &f2 = E->get()->get();
if (f2.plane.distance_to(p) > over_tolerance) {
f2.points_over.push_back(lf.points_over[i]);
@@ -327,7 +314,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
//erase lit faces
while (lit_faces.size()) {
-
faces.erase(lit_faces.front()->get());
lit_faces.pop_front();
}
@@ -335,7 +321,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
//put faces that contain no points on the front
for (List<List<Face>::Element *>::Element *E = new_faces.front(); E; E = E->next()) {
-
Face &f2 = E->get()->get();
if (f2.points_over.size() == 0) {
faces.move_to_front(E->get());
@@ -352,7 +337,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
List<Geometry::MeshData::Face> ret_faces;
for (List<Face>::Element *E = faces.front(); E; E = E->next()) {
-
Geometry::MeshData::Face f;
f.plane = E->get().plane;
@@ -363,7 +347,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
List<Geometry::MeshData::Face>::Element *F = ret_faces.push_back(f);
for (int i = 0; i < 3; i++) {
-
uint32_t a = E->get().vertices[i];
uint32_t b = E->get().vertices[(i + 1) % 3];
Edge e(a, b);
@@ -376,7 +359,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
//left
G->get().left = F;
} else {
-
G->get().right = F;
}
}
@@ -385,11 +367,9 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
//fill faces
for (List<Geometry::MeshData::Face>::Element *E = ret_faces.front(); E; E = E->next()) {
-
Geometry::MeshData::Face &f = E->get();
for (int i = 0; i < f.indices.size(); i++) {
-
int a = E->get().indices[i];
int b = E->get().indices[(i + 1) % f.indices.size()];
Edge e(a, b);
@@ -411,7 +391,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
if (O->get().indices[j] == a) {
//append the rest
for (int k = 0; k < ois; k++) {
-
int idx = O->get().indices[(k + j) % ois];
int idxn = O->get().indices[(k + j + 1) % ois];
if (idx == b && idxn == a) { //already have b!
@@ -427,10 +406,11 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
Map<Edge, RetFaceConnect>::Element *F2 = ret_edges.find(e2);
ERR_CONTINUE(!F2);
//change faceconnect, point to this face instead
- if (F2->get().left == O)
+ if (F2->get().left == O) {
F2->get().left = E;
- else if (F2->get().right == O)
+ } else if (F2->get().right == O) {
F2->get().right = E;
+ }
}
break;
@@ -439,11 +419,13 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
// remove all edge connections to this face
for (Map<Edge, RetFaceConnect>::Element *G = ret_edges.front(); G; G = G->next()) {
- if (G->get().left == O)
+ if (G->get().left == O) {
G->get().left = nullptr;
+ }
- if (G->get().right == O)
+ if (G->get().right == O) {
G->get().right = nullptr;
+ }
}
ret_edges.erase(F); //remove the edge
@@ -463,7 +445,6 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
r_mesh.edges.resize(ret_edges.size());
idx = 0;
for (Map<Edge, RetFaceConnect>::Element *E = ret_edges.front(); E; E = E->next()) {
-
Geometry::MeshData::Edge e;
e.a = E->key().vertices[0];
e.b = E->key().vertices[1];
diff --git a/core/math/quick_hull.h b/core/math/quick_hull.h
index 173f919a73..29f709febe 100644
--- a/core/math/quick_hull.h
+++ b/core/math/quick_hull.h
@@ -37,10 +37,8 @@
#include "core/set.h"
class QuickHull {
-
public:
struct Edge {
-
union {
uint32_t vertices[2];
uint64_t id;
@@ -51,7 +49,6 @@ public:
}
Edge(int p_vtx_a = 0, int p_vtx_b = 0) {
-
if (p_vtx_a > p_vtx_b) {
SWAP(p_vtx_a, p_vtx_b);
}
@@ -62,31 +59,23 @@ public:
};
struct Face {
-
Plane plane;
uint32_t vertices[3];
Vector<int> points_over;
bool operator<(const Face &p_face) const {
-
return points_over.size() < p_face.points_over.size();
}
};
private:
struct FaceConnect {
- List<Face>::Element *left, *right;
- FaceConnect() {
- left = nullptr;
- right = nullptr;
- }
+ List<Face>::Element *left, *right = nullptr;
+ FaceConnect() {}
};
struct RetFaceConnect {
- List<Geometry::MeshData::Face>::Element *left, *right;
- RetFaceConnect() {
- left = nullptr;
- right = nullptr;
- }
+ List<Geometry::MeshData::Face>::Element *left, *right = nullptr;
+ RetFaceConnect() {}
};
public:
diff --git a/core/math/random_number_generator.cpp b/core/math/random_number_generator.cpp
index 1a1bffb562..67f4c0b14a 100644
--- a/core/math/random_number_generator.cpp
+++ b/core/math/random_number_generator.cpp
@@ -30,8 +30,6 @@
#include "random_number_generator.h"
-RandomNumberGenerator::RandomNumberGenerator() {}
-
void RandomNumberGenerator::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_seed", "seed"), &RandomNumberGenerator::set_seed);
ClassDB::bind_method(D_METHOD("get_seed"), &RandomNumberGenerator::get_seed);
diff --git a/core/math/random_number_generator.h b/core/math/random_number_generator.h
index e7f188bb42..920308e597 100644
--- a/core/math/random_number_generator.h
+++ b/core/math/random_number_generator.h
@@ -59,13 +59,14 @@ public:
_FORCE_INLINE_ int randi_range(int from, int to) {
unsigned int ret = randbase.rand();
- if (to < from)
+ if (to < from) {
return ret % (from - to + 1) + to;
- else
+ } else {
return ret % (to - from + 1) + from;
+ }
}
- RandomNumberGenerator();
+ RandomNumberGenerator() {}
};
#endif // RANDOM_NUMBER_GENERATOR_H
diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp
index 12b9904c88..0cc3c4ca0f 100644
--- a/core/math/rect2.cpp
+++ b/core/math/rect2.cpp
@@ -31,12 +31,10 @@
#include "core/math/transform_2d.h" // Includes rect2.h but Rect2 needs Transform2D
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::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const {
-
real_t min = 0, max = 1;
int axis = 0;
real_t sign = 0;
@@ -50,18 +48,18 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2
real_t csign;
if (seg_from < seg_to) {
-
- if (seg_from > box_end || seg_to < box_begin)
+ if (seg_from > box_end || seg_to < box_begin) {
return false;
+ }
real_t length = seg_to - seg_from;
cmin = (seg_from < box_begin) ? ((box_begin - seg_from) / length) : 0;
cmax = (seg_to > box_end) ? ((box_end - seg_from) / length) : 1;
csign = -1.0;
} else {
-
- if (seg_to > box_end || seg_from < box_begin)
+ if (seg_to > box_end || seg_from < box_begin) {
return false;
+ }
real_t length = seg_to - seg_from;
cmin = (seg_from > box_end) ? (box_end - seg_from) / length : 0;
cmax = (seg_to < box_begin) ? (box_begin - seg_from) / length : 1;
@@ -73,10 +71,12 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2
axis = i;
sign = csign;
}
- if (cmax < max)
+ if (cmax < max) {
max = cmax;
- if (max < min)
+ }
+ if (max < min) {
return false;
+ }
}
Vector2 rel = p_to - p_from;
@@ -87,14 +87,14 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2
*r_normal = normal;
}
- if (r_pos)
+ if (r_pos) {
*r_pos = p_from + rel * min;
+ }
return true;
}
bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const {
-
//SAT intersection between local and transformed rect2
Vector2 xf_points[4] = {
@@ -108,14 +108,18 @@ bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_re
//base rect2 first (faster)
- if (xf_points[0].y > position.y)
+ if (xf_points[0].y > position.y) {
goto next1;
- if (xf_points[1].y > position.y)
+ }
+ if (xf_points[1].y > position.y) {
goto next1;
- if (xf_points[2].y > position.y)
+ }
+ if (xf_points[2].y > position.y) {
goto next1;
- if (xf_points[3].y > position.y)
+ }
+ if (xf_points[3].y > position.y) {
goto next1;
+ }
return false;
@@ -123,27 +127,35 @@ next1:
low_limit = position.y + size.y;
- if (xf_points[0].y < low_limit)
+ if (xf_points[0].y < low_limit) {
goto next2;
- if (xf_points[1].y < low_limit)
+ }
+ if (xf_points[1].y < low_limit) {
goto next2;
- if (xf_points[2].y < low_limit)
+ }
+ if (xf_points[2].y < low_limit) {
goto next2;
- if (xf_points[3].y < low_limit)
+ }
+ if (xf_points[3].y < low_limit) {
goto next2;
+ }
return false;
next2:
- if (xf_points[0].x > position.x)
+ if (xf_points[0].x > position.x) {
goto next3;
- if (xf_points[1].x > position.x)
+ }
+ if (xf_points[1].x > position.x) {
goto next3;
- if (xf_points[2].x > position.x)
+ }
+ if (xf_points[2].x > position.x) {
goto next3;
- if (xf_points[3].x > position.x)
+ }
+ if (xf_points[3].x > position.x) {
goto next3;
+ }
return false;
@@ -151,14 +163,18 @@ next3:
low_limit = position.x + size.x;
- if (xf_points[0].x < low_limit)
+ if (xf_points[0].x < low_limit) {
goto next4;
- if (xf_points[1].x < low_limit)
+ }
+ if (xf_points[1].x < low_limit) {
goto next4;
- if (xf_points[2].x < low_limit)
+ }
+ if (xf_points[2].x < low_limit) {
goto next4;
- if (xf_points[3].x < low_limit)
+ }
+ if (xf_points[3].x < low_limit) {
goto next4;
+ }
return false;
@@ -201,10 +217,12 @@ next4:
maxb = MAX(dp, maxb);
minb = MIN(dp, minb);
- if (mina > maxb)
+ if (mina > maxb) {
return false;
- if (minb > maxa)
+ }
+ if (minb > maxa) {
return false;
+ }
maxa = p_xform.elements[1].dot(xf_points2[0]);
mina = maxa;
@@ -236,10 +254,12 @@ next4:
maxb = MAX(dp, maxb);
minb = MIN(dp, minb);
- if (mina > maxb)
+ if (mina > maxb) {
return false;
- if (minb > maxa)
+ }
+ if (minb > maxa) {
return false;
+ }
return true;
}
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 30dbfdbbe5..14393325ec 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -36,7 +36,6 @@
struct Transform2D;
struct Rect2 {
-
Point2 position;
Size2 size;
@@ -49,30 +48,37 @@ struct Rect2 {
inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const {
if (p_include_borders) {
- if (position.x > (p_rect.position.x + p_rect.size.width))
+ if (position.x > (p_rect.position.x + p_rect.size.width)) {
return false;
- if ((position.x + size.width) < p_rect.position.x)
+ }
+ if ((position.x + size.width) < p_rect.position.x) {
return false;
- if (position.y > (p_rect.position.y + p_rect.size.height))
+ }
+ if (position.y > (p_rect.position.y + p_rect.size.height)) {
return false;
- if ((position.y + size.height) < p_rect.position.y)
+ }
+ if ((position.y + size.height) < p_rect.position.y) {
return false;
+ }
} else {
- if (position.x >= (p_rect.position.x + p_rect.size.width))
+ if (position.x >= (p_rect.position.x + p_rect.size.width)) {
return false;
- if ((position.x + size.width) <= p_rect.position.x)
+ }
+ if ((position.x + size.width) <= p_rect.position.x) {
return false;
- if (position.y >= (p_rect.position.y + p_rect.size.height))
+ }
+ if (position.y >= (p_rect.position.y + p_rect.size.height)) {
return false;
- if ((position.y + size.height) <= p_rect.position.y)
+ }
+ if ((position.y + size.height) <= p_rect.position.y) {
return false;
+ }
}
return true;
}
inline real_t distance_to(const Vector2 &p_point) const {
-
real_t dist = 0.0;
bool inside = true;
@@ -97,10 +103,11 @@ struct Rect2 {
inside = false;
}
- if (inside)
+ if (inside) {
return 0;
- else
+ } else {
return dist;
+ }
}
bool intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const;
@@ -108,22 +115,21 @@ struct Rect2 {
bool intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos = nullptr, Point2 *r_normal = nullptr) const;
inline bool encloses(const Rect2 &p_rect) const {
-
return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
((p_rect.position.x + p_rect.size.x) <= (position.x + size.x)) &&
((p_rect.position.y + p_rect.size.y) <= (position.y + size.y));
}
_FORCE_INLINE_ bool has_no_area() const {
-
return (size.x <= 0 || size.y <= 0);
}
inline Rect2 clip(const Rect2 &p_rect) const { /// return a clipped rect
Rect2 new_rect = p_rect;
- if (!intersects(new_rect))
+ if (!intersects(new_rect)) {
return Rect2();
+ }
new_rect.position.x = MAX(p_rect.position.x, position.x);
new_rect.position.y = MAX(p_rect.position.y, position.y);
@@ -150,17 +156,21 @@ struct Rect2 {
new_rect.size = new_rect.size - new_rect.position; //make relative again
return new_rect;
- };
+ }
inline bool has_point(const Point2 &p_point) const {
- if (p_point.x < position.x)
+ if (p_point.x < position.x) {
return false;
- if (p_point.y < position.y)
+ }
+ if (p_point.y < position.y) {
return false;
+ }
- if (p_point.x >= (position.x + size.x))
+ if (p_point.x >= (position.x + size.x)) {
return false;
- if (p_point.y >= (position.y + size.y))
+ }
+ if (p_point.y >= (position.y + size.y)) {
return false;
+ }
return true;
}
@@ -170,7 +180,6 @@ struct Rect2 {
bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; }
inline Rect2 grow(real_t p_by) const {
-
Rect2 g = *this;
g.position.x -= p_by;
g.position.y -= p_by;
@@ -189,7 +198,6 @@ struct Rect2 {
}
inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const {
-
Rect2 g = *this;
g.position.x -= p_left;
g.position.y -= p_top;
@@ -200,7 +208,6 @@ struct Rect2 {
}
_FORCE_INLINE_ Rect2 expand(const Vector2 &p_vector) const {
-
Rect2 r = *this;
r.expand_to(p_vector);
return r;
@@ -211,22 +218,25 @@ struct Rect2 {
Vector2 begin = position;
Vector2 end = position + size;
- if (p_vector.x < begin.x)
+ if (p_vector.x < begin.x) {
begin.x = p_vector.x;
- if (p_vector.y < begin.y)
+ }
+ if (p_vector.y < begin.y) {
begin.y = p_vector.y;
+ }
- if (p_vector.x > end.x)
+ if (p_vector.x > end.x) {
end.x = p_vector.x;
- if (p_vector.y > end.y)
+ }
+ if (p_vector.y > end.y) {
end.y = p_vector.y;
+ }
position = begin;
size = end - begin;
}
_FORCE_INLINE_ Rect2 abs() const {
-
return Rect2(Point2(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs());
}
@@ -244,7 +254,6 @@ struct Rect2 {
};
struct Rect2i {
-
Point2i position;
Size2i size;
@@ -256,35 +265,38 @@ struct Rect2i {
int get_area() const { return size.width * size.height; }
inline bool intersects(const Rect2i &p_rect) const {
- if (position.x > (p_rect.position.x + p_rect.size.width))
+ if (position.x > (p_rect.position.x + p_rect.size.width)) {
return false;
- if ((position.x + size.width) < p_rect.position.x)
+ }
+ if ((position.x + size.width) < p_rect.position.x) {
return false;
- if (position.y > (p_rect.position.y + p_rect.size.height))
+ }
+ if (position.y > (p_rect.position.y + p_rect.size.height)) {
return false;
- if ((position.y + size.height) < p_rect.position.y)
+ }
+ if ((position.y + size.height) < p_rect.position.y) {
return false;
+ }
return true;
}
inline bool encloses(const Rect2i &p_rect) const {
-
return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) &&
((p_rect.position.y + p_rect.size.y) < (position.y + size.y));
}
_FORCE_INLINE_ bool has_no_area() const {
-
return (size.x <= 0 || size.y <= 0);
}
inline Rect2i clip(const Rect2i &p_rect) const { /// return a clipped rect
Rect2i new_rect = p_rect;
- if (!intersects(new_rect))
+ if (!intersects(new_rect)) {
return Rect2i();
+ }
new_rect.position.x = MAX(p_rect.position.x, position.x);
new_rect.position.y = MAX(p_rect.position.y, position.y);
@@ -311,17 +323,21 @@ struct Rect2i {
new_rect.size = new_rect.size - new_rect.position; //make relative again
return new_rect;
- };
+ }
bool has_point(const Point2 &p_point) const {
- if (p_point.x < position.x)
+ if (p_point.x < position.x) {
return false;
- if (p_point.y < position.y)
+ }
+ if (p_point.y < position.y) {
return false;
+ }
- if (p_point.x >= (position.x + size.x))
+ if (p_point.x >= (position.x + size.x)) {
return false;
- if (p_point.y >= (position.y + size.y))
+ }
+ if (p_point.y >= (position.y + size.y)) {
return false;
+ }
return true;
}
@@ -330,7 +346,6 @@ struct Rect2i {
bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; }
Rect2i grow(int p_by) const {
-
Rect2i g = *this;
g.position.x -= p_by;
g.position.y -= p_by;
@@ -349,7 +364,6 @@ struct Rect2i {
}
inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const {
-
Rect2i g = *this;
g.position.x -= p_left;
g.position.y -= p_top;
@@ -360,44 +374,46 @@ struct Rect2i {
}
_FORCE_INLINE_ Rect2i expand(const Vector2i &p_vector) const {
-
Rect2i r = *this;
r.expand_to(p_vector);
return r;
}
inline void expand_to(const Point2i &p_vector) {
-
Point2i begin = position;
Point2i end = position + size;
- if (p_vector.x < begin.x)
+ if (p_vector.x < begin.x) {
begin.x = p_vector.x;
- if (p_vector.y < begin.y)
+ }
+ if (p_vector.y < begin.y) {
begin.y = p_vector.y;
+ }
- if (p_vector.x > end.x)
+ if (p_vector.x > end.x) {
end.x = p_vector.x;
- if (p_vector.y > end.y)
+ }
+ if (p_vector.y > end.y) {
end.y = p_vector.y;
+ }
position = begin;
size = end - begin;
}
_FORCE_INLINE_ Rect2i abs() const {
-
return Rect2i(Point2i(position.x + MIN(size.x, 0), position.y + MIN(size.y, 0)), size.abs());
}
operator String() const { return String(position) + ", " + String(size); }
operator Rect2() const { return Rect2(position, size); }
+
+ Rect2i() {}
Rect2i(const Rect2 &p_r2) :
position(p_r2.position),
size(p_r2.size) {
}
- Rect2i() {}
Rect2i(int p_x, int p_y, int p_width, int p_height) :
position(Point2(p_x, p_y)),
size(Size2(p_width, p_height)) {
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index 9dad3262d2..0274dd18af 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -35,20 +35,17 @@
#include "core/print_string.h"
void Transform::affine_invert() {
-
basis.invert();
origin = basis.xform(-origin);
}
Transform Transform::affine_inverse() const {
-
Transform ret = *this;
ret.affine_invert();
return ret;
}
void Transform::invert() {
-
basis.transpose();
origin = basis.xform(-origin);
}
@@ -62,22 +59,18 @@ Transform Transform::inverse() const {
}
void Transform::rotate(const Vector3 &p_axis, real_t p_phi) {
-
*this = rotated(p_axis, p_phi);
}
Transform Transform::rotated(const Vector3 &p_axis, real_t p_phi) const {
-
return Transform(Basis(p_axis, p_phi), Vector3()) * (*this);
}
void Transform::rotate_basis(const Vector3 &p_axis, real_t p_phi) {
-
basis.rotate(p_axis, p_phi);
}
Transform Transform::looking_at(const Vector3 &p_target, const Vector3 &p_up) const {
-
Transform t = *this;
t.set_look_at(origin, p_target, p_up);
return t;
@@ -117,7 +110,6 @@ void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const
}
Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c) const {
-
/* not sure if very "efficient" but good enough? */
Vector3 src_scale = basis.get_scale();
@@ -129,88 +121,77 @@ Transform Transform::interpolate_with(const Transform &p_transform, real_t p_c)
Vector3 dst_loc = p_transform.origin;
Transform interp;
- interp.basis.set_quat_scale(src_rot.slerp(dst_rot, p_c).normalized(), src_scale.linear_interpolate(dst_scale, p_c));
- interp.origin = src_loc.linear_interpolate(dst_loc, p_c);
+ interp.basis.set_quat_scale(src_rot.slerp(dst_rot, p_c).normalized(), src_scale.lerp(dst_scale, p_c));
+ interp.origin = src_loc.lerp(dst_loc, p_c);
return interp;
}
void Transform::scale(const Vector3 &p_scale) {
-
basis.scale(p_scale);
origin *= p_scale;
}
Transform Transform::scaled(const Vector3 &p_scale) const {
-
Transform t = *this;
t.scale(p_scale);
return t;
}
void Transform::scale_basis(const Vector3 &p_scale) {
-
basis.scale(p_scale);
}
void Transform::translate(real_t p_tx, real_t p_ty, real_t p_tz) {
translate(Vector3(p_tx, p_ty, p_tz));
}
-void Transform::translate(const Vector3 &p_translation) {
+void Transform::translate(const Vector3 &p_translation) {
for (int i = 0; i < 3; i++) {
origin[i] += basis[i].dot(p_translation);
}
}
Transform Transform::translated(const Vector3 &p_translation) const {
-
Transform t = *this;
t.translate(p_translation);
return t;
}
void Transform::orthonormalize() {
-
basis.orthonormalize();
}
Transform Transform::orthonormalized() const {
-
Transform _copy = *this;
_copy.orthonormalize();
return _copy;
}
bool Transform::is_equal_approx(const Transform &p_transform) const {
-
return basis.is_equal_approx(p_transform.basis) && origin.is_equal_approx(p_transform.origin);
}
bool Transform::operator==(const Transform &p_transform) const {
-
return (basis == p_transform.basis && origin == p_transform.origin);
}
-bool Transform::operator!=(const Transform &p_transform) const {
+bool Transform::operator!=(const Transform &p_transform) const {
return (basis != p_transform.basis || origin != p_transform.origin);
}
void Transform::operator*=(const Transform &p_transform) {
-
origin = xform(p_transform.origin);
basis *= p_transform.basis;
}
Transform Transform::operator*(const Transform &p_transform) const {
-
Transform t = *this;
t *= p_transform;
return t;
}
Transform::operator String() const {
-
return basis.operator String() + " - " + origin.operator String();
}
diff --git a/core/math/transform.h b/core/math/transform.h
index c6e3be4c70..71847d36ac 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -92,14 +92,12 @@ public:
Transform interpolate_with(const Transform &p_transform, real_t p_c) const;
_FORCE_INLINE_ Transform inverse_xform(const Transform &t) const {
-
Vector3 v = t.origin - origin;
return Transform(basis.transpose_xform(t.basis),
basis.xform(v));
}
void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t tx, real_t ty, real_t tz) {
-
basis.set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
origin.x = tx;
origin.y = ty;
@@ -114,14 +112,13 @@ public:
};
_FORCE_INLINE_ Vector3 Transform::xform(const Vector3 &p_vector) const {
-
return Vector3(
basis[0].dot(p_vector) + origin.x,
basis[1].dot(p_vector) + origin.y,
basis[2].dot(p_vector) + origin.z);
}
-_FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3 &p_vector) const {
+_FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3 &p_vector) const {
Vector3 v = p_vector - origin;
return Vector3(
@@ -131,7 +128,6 @@ _FORCE_INLINE_ Vector3 Transform::xform_inv(const Vector3 &p_vector) const {
}
_FORCE_INLINE_ Plane Transform::xform(const Plane &p_plane) const {
-
Vector3 point = p_plane.normal * p_plane.d;
Vector3 point_dir = point + p_plane.normal;
point = xform(point);
@@ -143,8 +139,8 @@ _FORCE_INLINE_ Plane Transform::xform(const Plane &p_plane) const {
return Plane(normal, d);
}
-_FORCE_INLINE_ Plane Transform::xform_inv(const Plane &p_plane) const {
+_FORCE_INLINE_ Plane Transform::xform_inv(const Plane &p_plane) const {
Vector3 point = p_plane.normal * p_plane.d;
Vector3 point_dir = point + p_plane.normal;
xform_inv(point);
@@ -158,7 +154,6 @@ _FORCE_INLINE_ Plane Transform::xform_inv(const Plane &p_plane) const {
}
_FORCE_INLINE_ AABB Transform::xform(const AABB &p_aabb) const {
-
/* http://dev.theomader.com/transform-bounding-boxes/ */
Vector3 min = p_aabb.position;
Vector3 max = p_aabb.position + p_aabb.size;
@@ -184,7 +179,6 @@ _FORCE_INLINE_ AABB Transform::xform(const AABB &p_aabb) const {
}
_FORCE_INLINE_ AABB Transform::xform_inv(const AABB &p_aabb) const {
-
/* define vertices */
Vector3 vertices[8] = {
Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z),
@@ -202,7 +196,6 @@ _FORCE_INLINE_ AABB Transform::xform_inv(const AABB &p_aabb) const {
ret.position = xform_inv(vertices[0]);
for (int i = 1; i < 8; i++) {
-
ret.expand_to(xform_inv(vertices[i]));
}
@@ -210,7 +203,6 @@ _FORCE_INLINE_ AABB Transform::xform_inv(const AABB &p_aabb) const {
}
Vector<Vector3> Transform::xform(const Vector<Vector3> &p_array) const {
-
Vector<Vector3> array;
array.resize(p_array.size());
@@ -224,7 +216,6 @@ Vector<Vector3> Transform::xform(const Vector<Vector3> &p_array) const {
}
Vector<Vector3> Transform::xform_inv(const Vector<Vector3> &p_array) const {
-
Vector<Vector3> array;
array.resize(p_array.size());
diff --git a/core/math/transform_2d.cpp b/core/math/transform_2d.cpp
index f28b664e46..dee1b3b23e 100644
--- a/core/math/transform_2d.cpp
+++ b/core/math/transform_2d.cpp
@@ -38,14 +38,12 @@ void Transform2D::invert() {
}
Transform2D Transform2D::inverse() const {
-
Transform2D inv = *this;
inv.invert();
return inv;
}
void Transform2D::affine_invert() {
-
real_t det = basis_determinant();
#ifdef MATH_CHECKS
ERR_FAIL_COND(det == 0);
@@ -60,7 +58,6 @@ void Transform2D::affine_invert() {
}
Transform2D Transform2D::affine_inverse() const {
-
Transform2D inv = *this;
inv.affine_invert();
return inv;
@@ -70,6 +67,16 @@ void Transform2D::rotate(real_t p_phi) {
*this = Transform2D(p_phi, Vector2()) * (*this);
}
+real_t Transform2D::get_skew() const {
+ real_t det = basis_determinant();
+ return Math::acos(elements[0].normalized().dot(SGN(det) * elements[1].normalized())) - Math_PI * 0.5;
+}
+
+void Transform2D::set_skew(float p_angle) {
+ real_t det = basis_determinant();
+ elements[1] = SGN(det) * elements[0].rotated((Math_PI * 0.5 + p_angle)).normalized() * elements[1].length();
+}
+
real_t Transform2D::get_rotation() const {
real_t det = basis_determinant();
Transform2D m = orthonormalized();
@@ -91,7 +98,6 @@ void Transform2D::set_rotation(real_t p_rot) {
}
Transform2D::Transform2D(real_t p_rot, const Vector2 &p_pos) {
-
real_t cr = Math::cos(p_rot);
real_t sr = Math::sin(p_rot);
elements[0][0] = cr;
@@ -117,24 +123,23 @@ void Transform2D::scale(const Size2 &p_scale) {
scale_basis(p_scale);
elements[2] *= p_scale;
}
-void Transform2D::scale_basis(const Size2 &p_scale) {
+void Transform2D::scale_basis(const Size2 &p_scale) {
elements[0][0] *= p_scale.x;
elements[0][1] *= p_scale.y;
elements[1][0] *= p_scale.x;
elements[1][1] *= p_scale.y;
}
-void Transform2D::translate(real_t p_tx, real_t p_ty) {
+void Transform2D::translate(real_t p_tx, real_t p_ty) {
translate(Vector2(p_tx, p_ty));
}
-void Transform2D::translate(const Vector2 &p_translation) {
+void Transform2D::translate(const Vector2 &p_translation) {
elements[2] += basis_xform(p_translation);
}
void Transform2D::orthonormalize() {
-
// Gram-Schmidt Process
Vector2 x = elements[0];
@@ -149,39 +154,36 @@ void Transform2D::orthonormalize() {
}
Transform2D Transform2D::orthonormalized() const {
-
Transform2D on = *this;
on.orthonormalize();
return on;
}
bool Transform2D::is_equal_approx(const Transform2D &p_transform) const {
-
return elements[0].is_equal_approx(p_transform.elements[0]) && elements[1].is_equal_approx(p_transform.elements[1]) && elements[2].is_equal_approx(p_transform.elements[2]);
}
bool Transform2D::operator==(const Transform2D &p_transform) const {
-
for (int i = 0; i < 3; i++) {
- if (elements[i] != p_transform.elements[i])
+ if (elements[i] != p_transform.elements[i]) {
return false;
+ }
}
return true;
}
bool Transform2D::operator!=(const Transform2D &p_transform) const {
-
for (int i = 0; i < 3; i++) {
- if (elements[i] != p_transform.elements[i])
+ if (elements[i] != p_transform.elements[i]) {
return true;
+ }
}
return false;
}
void Transform2D::operator*=(const Transform2D &p_transform) {
-
elements[2] = xform(p_transform.elements[2]);
real_t x0, x1, y0, y1;
@@ -198,54 +200,46 @@ void Transform2D::operator*=(const Transform2D &p_transform) {
}
Transform2D Transform2D::operator*(const Transform2D &p_transform) const {
-
Transform2D t = *this;
t *= p_transform;
return t;
}
Transform2D Transform2D::scaled(const Size2 &p_scale) const {
-
Transform2D copy = *this;
copy.scale(p_scale);
return copy;
}
Transform2D Transform2D::basis_scaled(const Size2 &p_scale) const {
-
Transform2D copy = *this;
copy.scale_basis(p_scale);
return copy;
}
Transform2D Transform2D::untranslated() const {
-
Transform2D copy = *this;
copy.elements[2] = Vector2();
return copy;
}
Transform2D Transform2D::translated(const Vector2 &p_offset) const {
-
Transform2D copy = *this;
copy.translate(p_offset);
return copy;
}
Transform2D Transform2D::rotated(real_t p_phi) const {
-
Transform2D copy = *this;
copy.rotate(p_phi);
return copy;
}
real_t Transform2D::basis_determinant() const {
-
return elements[0].x * elements[1].y - elements[0].y * elements[1].x;
}
Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t p_c) const {
-
//extract parameters
Vector2 p1 = get_origin();
Vector2 p2 = p_transform.get_origin();
@@ -267,7 +261,7 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t
Vector2 v;
if (dot > 0.9995) {
- v = Vector2::linear_interpolate(v1, v2, p_c).normalized(); //linearly interpolate to avoid numerical precision issues
+ v = v1.lerp(v2, p_c).normalized(); //linearly interpolate to avoid numerical precision issues
} else {
real_t angle = p_c * Math::acos(dot);
Vector2 v3 = (v2 - v1 * dot).normalized();
@@ -275,12 +269,11 @@ Transform2D Transform2D::interpolate_with(const Transform2D &p_transform, real_t
}
//construct matrix
- Transform2D res(Math::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c));
- res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c));
+ Transform2D res(Math::atan2(v.y, v.x), p1.lerp(p2, p_c));
+ res.scale_basis(s1.lerp(s2, p_c));
return res;
}
Transform2D::operator String() const {
-
return String(String() + elements[0] + ", " + elements[1] + ", " + elements[2]);
}
diff --git a/core/math/transform_2d.h b/core/math/transform_2d.h
index fa43762aa4..46e97abaa7 100644
--- a/core/math/transform_2d.h
+++ b/core/math/transform_2d.h
@@ -70,7 +70,10 @@ struct Transform2D {
void set_rotation(real_t p_rot);
real_t get_rotation() const;
+ real_t get_skew() const;
+ void set_skew(float p_angle);
_FORCE_INLINE_ void set_rotation_and_scale(real_t p_rot, const Size2 &p_scale);
+ _FORCE_INLINE_ void set_rotation_scale_and_skew(real_t p_rot, const Size2 &p_scale, float p_skew);
void rotate(real_t p_phi);
void scale(const Size2 &p_scale);
@@ -117,7 +120,6 @@ struct Transform2D {
operator String() const;
Transform2D(real_t xx, real_t xy, real_t yx, real_t yy, real_t ox, real_t oy) {
-
elements[0][0] = xx;
elements[0][1] = xy;
elements[1][0] = yx;
@@ -134,36 +136,33 @@ struct Transform2D {
};
Vector2 Transform2D::basis_xform(const Vector2 &p_vec) const {
-
return Vector2(
tdotx(p_vec),
tdoty(p_vec));
}
Vector2 Transform2D::basis_xform_inv(const Vector2 &p_vec) const {
-
return Vector2(
elements[0].dot(p_vec),
elements[1].dot(p_vec));
}
Vector2 Transform2D::xform(const Vector2 &p_vec) const {
-
return Vector2(
tdotx(p_vec),
tdoty(p_vec)) +
elements[2];
}
-Vector2 Transform2D::xform_inv(const Vector2 &p_vec) const {
+Vector2 Transform2D::xform_inv(const Vector2 &p_vec) const {
Vector2 v = p_vec - elements[2];
return Vector2(
elements[0].dot(v),
elements[1].dot(v));
}
-Rect2 Transform2D::xform(const Rect2 &p_rect) const {
+Rect2 Transform2D::xform(const Rect2 &p_rect) const {
Vector2 x = elements[0] * p_rect.size.x;
Vector2 y = elements[1] * p_rect.size.y;
Vector2 pos = xform(p_rect.position);
@@ -177,15 +176,20 @@ Rect2 Transform2D::xform(const Rect2 &p_rect) const {
}
void Transform2D::set_rotation_and_scale(real_t p_rot, const Size2 &p_scale) {
-
elements[0][0] = Math::cos(p_rot) * p_scale.x;
elements[1][1] = Math::cos(p_rot) * p_scale.y;
elements[1][0] = -Math::sin(p_rot) * p_scale.y;
elements[0][1] = Math::sin(p_rot) * p_scale.x;
}
-Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const {
+void Transform2D::set_rotation_scale_and_skew(real_t p_rot, const Size2 &p_scale, float p_skew) {
+ elements[0][0] = Math::cos(p_rot) * p_scale.x;
+ elements[1][1] = Math::cos(p_rot + p_skew) * p_scale.y;
+ elements[1][0] = -Math::sin(p_rot + p_skew) * p_scale.y;
+ elements[0][1] = Math::sin(p_rot) * p_scale.x;
+}
+Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const {
Vector2 ends[4] = {
xform_inv(p_rect.position),
xform_inv(Vector2(p_rect.position.x, p_rect.position.y + p_rect.size.y)),
@@ -203,7 +207,6 @@ Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const {
}
Vector<Vector2> Transform2D::xform(const Vector<Vector2> &p_array) const {
-
Vector<Vector2> array;
array.resize(p_array.size());
@@ -217,7 +220,6 @@ Vector<Vector2> Transform2D::xform(const Vector<Vector2> &p_array) const {
}
Vector<Vector2> Transform2D::xform_inv(const Vector<Vector2> &p_array) const {
-
Vector<Vector2> array;
array.resize(p_array.size());
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index 01d38cf24e..c9a546e385 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -33,30 +33,25 @@
#include "core/sort_array.h"
int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, int p_depth, int &max_depth, int &max_alloc) {
-
if (p_depth > max_depth) {
max_depth = p_depth;
}
if (p_size == 1) {
-
return p_bb[p_from] - p_bvh;
} else if (p_size == 0) {
-
return -1;
}
AABB aabb;
aabb = p_bb[p_from]->aabb;
for (int i = 1; i < p_size; i++) {
-
aabb.merge_with(p_bb[p_from + i]->aabb);
}
int li = aabb.get_longest_axis_index();
switch (li) {
-
case Vector3::AXIS_X: {
SortArray<BVH *, BVHCmpX> sort_x;
sort_x.nth_element(0, p_size, p_size / 2, &p_bb[p_from]);
@@ -90,9 +85,9 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in
}
void TriangleMesh::get_indices(Vector<int> *r_triangles_indices) const {
-
- if (!valid)
+ if (!valid) {
return;
+ }
const int triangles_num = triangles.size();
@@ -110,7 +105,6 @@ void TriangleMesh::get_indices(Vector<int> *r_triangles_indices) const {
}
void TriangleMesh::create(const Vector<Vector3> &p_faces) {
-
valid = false;
int fc = p_faces.size();
@@ -122,7 +116,6 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces) {
BVH *bw = bvh.ptrw();
{
-
//create faces and indices and base bvh
//except for the Set for repeated triangles, everything
//goes in-place.
@@ -132,12 +125,10 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces) {
Map<Vector3, int> db;
for (int i = 0; i < fc; i++) {
-
Triangle &f = w[i];
const Vector3 *v = &r[i * 3];
for (int j = 0; j < 3; j++) {
-
int vidx = -1;
Vector3 vs = v[j].snapped(Vector3(0.0001, 0.0001, 0.0001));
Map<Vector3, int>::Element *E = db.find(vs);
@@ -149,10 +140,11 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces) {
}
f.indices[j] = vidx;
- if (j == 0)
+ if (j == 0) {
bw[i].aabb.position = vs;
- else
+ } else {
bw[i].aabb.expand_to(vs);
+ }
}
f.normal = Face3(r[i * 3 + 0], r[i * 3 + 1], r[i * 3 + 2]).get_plane().get_normal();
@@ -174,7 +166,6 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces) {
bwptrs.resize(fc);
BVH **bwp = bwptrs.ptrw();
for (int i = 0; i < fc; i++) {
-
bwp[i] = &bw[i];
}
@@ -188,7 +179,6 @@ void TriangleMesh::create(const Vector<Vector3> &p_faces) {
}
Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const {
-
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
enum {
@@ -215,23 +205,18 @@ Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const {
stack[0] = pos;
while (true) {
-
uint32_t node = stack[level] & NODE_IDX_MASK;
const BVH &b = bvhptr[node];
bool done = false;
switch (stack[level] >> VISITED_BIT_SHIFT) {
case TEST_AABB_BIT: {
-
bool valid = b.aabb.intersects(p_aabb);
if (!valid) {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
if (b.face_index >= 0) {
-
const Triangle &s = triangleptr[b.face_index];
n += s.normal;
n_count++;
@@ -239,49 +224,47 @@ Vector3 TriangleMesh::get_area_normal(const AABB &p_aabb) const {
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
}
}
continue;
}
case VISIT_LEFT_BIT: {
-
stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = b.left | TEST_AABB_BIT;
level++;
continue;
}
case VISIT_RIGHT_BIT: {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = b.right | TEST_AABB_BIT;
level++;
continue;
}
case VISIT_DONE_BIT: {
-
if (level == 0) {
done = true;
break;
- } else
+ } else {
level--;
+ }
continue;
}
}
- if (done)
+ if (done) {
break;
+ }
}
- if (n_count > 0)
+ if (n_count > 0) {
n /= n_count;
+ }
return n;
}
bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const {
-
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
enum {
@@ -309,35 +292,28 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
stack[0] = pos;
while (true) {
-
uint32_t node = stack[level] & NODE_IDX_MASK;
const BVH &b = bvhptr[node];
bool done = false;
switch (stack[level] >> VISITED_BIT_SHIFT) {
case TEST_AABB_BIT: {
-
bool valid = b.aabb.intersects_segment(p_begin, p_end);
//bool valid = b.aabb.intersects(ray_aabb);
if (!valid) {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
if (b.face_index >= 0) {
-
const Triangle &s = triangleptr[b.face_index];
Face3 f3(vertexptr[s.indices[0]], vertexptr[s.indices[1]], vertexptr[s.indices[2]]);
Vector3 res;
if (f3.intersects_segment(p_begin, p_end, &res)) {
-
real_t nd = n.dot(res);
if (nd < d) {
-
d = nd;
r_point = res;
r_normal = f3.get_plane().get_normal();
@@ -348,52 +324,49 @@ bool TriangleMesh::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
}
}
continue;
}
case VISIT_LEFT_BIT: {
-
stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = b.left | TEST_AABB_BIT;
level++;
continue;
}
case VISIT_RIGHT_BIT: {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = b.right | TEST_AABB_BIT;
level++;
continue;
}
case VISIT_DONE_BIT: {
-
if (level == 0) {
done = true;
break;
- } else
+ } else {
level--;
+ }
continue;
}
}
- if (done)
+ if (done) {
break;
+ }
}
if (inters) {
-
- if (n.dot(r_normal) > 0)
+ if (n.dot(r_normal) > 0) {
r_normal = -r_normal;
+ }
}
return inters;
}
bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal) const {
-
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
enum {
@@ -421,33 +394,26 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V
stack[0] = pos;
while (true) {
-
uint32_t node = stack[level] & NODE_IDX_MASK;
const BVH &b = bvhptr[node];
bool done = false;
switch (stack[level] >> VISITED_BIT_SHIFT) {
case TEST_AABB_BIT: {
-
bool valid = b.aabb.intersects_ray(p_begin, p_dir);
if (!valid) {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
if (b.face_index >= 0) {
-
const Triangle &s = triangleptr[b.face_index];
Face3 f3(vertexptr[s.indices[0]], vertexptr[s.indices[1]], vertexptr[s.indices[2]]);
Vector3 res;
if (f3.intersects_ray(p_begin, p_dir, &res)) {
-
real_t nd = n.dot(res);
if (nd < d) {
-
d = nd;
r_point = res;
r_normal = f3.get_plane().get_normal();
@@ -458,51 +424,49 @@ bool TriangleMesh::intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, V
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
}
}
continue;
}
case VISIT_LEFT_BIT: {
-
stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = b.left | TEST_AABB_BIT;
level++;
continue;
}
case VISIT_RIGHT_BIT: {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = b.right | TEST_AABB_BIT;
level++;
continue;
}
case VISIT_DONE_BIT: {
-
if (level == 0) {
done = true;
break;
- } else
+ } else {
level--;
+ }
continue;
}
}
- if (done)
+ if (done) {
break;
+ }
}
if (inters) {
-
- if (n.dot(r_normal) > 0)
+ if (n.dot(r_normal) > 0) {
r_normal = -r_normal;
+ }
}
return inters;
}
-bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_count) const {
+bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) const {
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
//p_fully_inside = true;
@@ -528,23 +492,18 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou
stack[0] = pos;
while (true) {
-
uint32_t node = stack[level] & NODE_IDX_MASK;
const BVH &b = bvhptr[node];
bool done = false;
switch (stack[level] >> VISITED_BIT_SHIFT) {
case TEST_AABB_BIT: {
-
- bool valid = b.aabb.intersects_convex_shape(p_planes, p_plane_count);
+ bool valid = b.aabb.intersects_convex_shape(p_planes, p_plane_count, p_points, p_point_count);
if (!valid) {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
if (b.face_index >= 0) {
-
const Triangle &s = triangleptr[b.face_index];
for (int j = 0; j < 3; ++j) {
@@ -558,14 +517,18 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou
if (p.intersects_segment(point, next_point, &res)) {
bool inisde = true;
for (int k = 0; k < p_plane_count; k++) {
- if (k == i) continue;
+ if (k == i) {
+ continue;
+ }
const Plane &pp = p_planes[k];
if (pp.is_point_over(res)) {
inisde = false;
break;
}
}
- if (inisde) return true;
+ if (inisde) {
+ return true;
+ }
}
if (p.is_point_over(point)) {
@@ -573,51 +536,51 @@ bool TriangleMesh::intersect_convex_shape(const Plane *p_planes, int p_plane_cou
break;
}
}
- if (over) return true;
+ if (over) {
+ return true;
+ }
}
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
}
}
continue;
}
case VISIT_LEFT_BIT: {
-
stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = b.left | TEST_AABB_BIT;
level++;
continue;
}
case VISIT_RIGHT_BIT: {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = b.right | TEST_AABB_BIT;
level++;
continue;
}
case VISIT_DONE_BIT: {
-
if (level == 0) {
done = true;
break;
- } else
+ } else {
level--;
+ }
continue;
}
}
- if (done)
+ if (done) {
break;
+ }
}
return false;
}
-bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count, Vector3 p_scale) const {
+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 {
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * max_depth);
enum {
@@ -643,84 +606,81 @@ bool TriangleMesh::inside_convex_shape(const Plane *p_planes, int p_plane_count,
stack[0] = pos;
while (true) {
-
uint32_t node = stack[level] & NODE_IDX_MASK;
const BVH &b = bvhptr[node];
bool done = false;
switch (stack[level] >> VISITED_BIT_SHIFT) {
case TEST_AABB_BIT: {
-
- bool intersects = scale.xform(b.aabb).intersects_convex_shape(p_planes, p_plane_count);
- if (!intersects) return false;
+ bool intersects = scale.xform(b.aabb).intersects_convex_shape(p_planes, p_plane_count, p_points, p_point_count);
+ if (!intersects) {
+ return false;
+ }
bool inside = scale.xform(b.aabb).inside_convex_shape(p_planes, p_plane_count);
if (inside) {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
if (b.face_index >= 0) {
const Triangle &s = triangleptr[b.face_index];
for (int j = 0; j < 3; ++j) {
Vector3 point = scale.xform(vertexptr[s.indices[j]]);
for (int i = 0; i < p_plane_count; i++) {
const Plane &p = p_planes[i];
- if (p.is_point_over(point)) return false;
+ if (p.is_point_over(point)) {
+ return false;
+ }
}
}
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
}
}
continue;
}
case VISIT_LEFT_BIT: {
-
stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = b.left | TEST_AABB_BIT;
level++;
continue;
}
case VISIT_RIGHT_BIT: {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = b.right | TEST_AABB_BIT;
level++;
continue;
}
case VISIT_DONE_BIT: {
-
if (level == 0) {
done = true;
break;
- } else
+ } else {
level--;
+ }
continue;
}
}
- if (done)
+ if (done) {
break;
+ }
}
return true;
}
bool TriangleMesh::is_valid() const {
-
return valid;
}
Vector<Face3> TriangleMesh::get_faces() const {
-
- if (!valid)
+ if (!valid) {
return Vector<Face3>();
+ }
Vector<Face3> faces;
int ts = triangles.size();
@@ -740,7 +700,6 @@ Vector<Face3> TriangleMesh::get_faces() const {
}
TriangleMesh::TriangleMesh() {
-
valid = false;
max_depth = 0;
}
diff --git a/core/math/triangle_mesh.h b/core/math/triangle_mesh.h
index fdbfb90465..86412cf725 100644
--- a/core/math/triangle_mesh.h
+++ b/core/math/triangle_mesh.h
@@ -35,11 +35,9 @@
#include "core/reference.h"
class TriangleMesh : public Reference {
-
GDCLASS(TriangleMesh, Reference);
struct Triangle {
-
Vector3 normal;
int indices[3];
};
@@ -48,7 +46,6 @@ class TriangleMesh : public Reference {
Vector<Vector3> vertices;
struct BVH {
-
AABB aabb;
Vector3 center; //used for sorting
int left;
@@ -58,24 +55,18 @@ class TriangleMesh : public Reference {
};
struct BVHCmpX {
-
bool operator()(const BVH *p_left, const BVH *p_right) const {
-
return p_left->center.x < p_right->center.x;
}
};
struct BVHCmpY {
-
bool operator()(const BVH *p_left, const BVH *p_right) const {
-
return p_left->center.y < p_right->center.y;
}
};
struct BVHCmpZ {
-
bool operator()(const BVH *p_left, const BVH *p_right) const {
-
return p_left->center.z < p_right->center.z;
}
};
@@ -90,8 +81,8 @@ public:
bool is_valid() const;
bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const;
bool intersect_ray(const Vector3 &p_begin, const Vector3 &p_dir, Vector3 &r_point, Vector3 &r_normal) const;
- bool intersect_convex_shape(const Plane *p_planes, int p_plane_count) const;
- bool inside_convex_shape(const Plane *p_planes, int p_plane_count, Vector3 p_scale = Vector3(1, 1, 1)) const;
+ bool intersect_convex_shape(const Plane *p_planes, int p_plane_count, const Vector3 *p_points, int p_point_count) 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;
Vector3 get_area_normal(const AABB &p_aabb) const;
Vector<Face3> get_faces() const;
diff --git a/core/math/triangulate.cpp b/core/math/triangulate.cpp
index cbcb232745..12bd384c6a 100644
--- a/core/math/triangulate.cpp
+++ b/core/math/triangulate.cpp
@@ -31,7 +31,6 @@
#include "triangulate.h"
real_t Triangulate::get_area(const Vector<Vector2> &contour) {
-
int n = contour.size();
const Vector2 *c = &contour[0];
@@ -80,7 +79,7 @@ bool Triangulate::is_inside_triangle(real_t Ax, real_t Ay,
} else {
return ((aCROSSbp >= 0.0) && (bCROSScp >= 0.0) && (cCROSSap >= 0.0));
}
-};
+}
bool Triangulate::snip(const Vector<Vector2> &p_contour, int u, int v, int w, int n, const Vector<int> &V, bool relaxed) {
int p;
@@ -103,13 +102,19 @@ bool Triangulate::snip(const Vector<Vector2> &p_contour, int u, int v, int w, in
// To avoid that we allow zero-area triangles if all else failed.
float threshold = relaxed ? -CMP_EPSILON : CMP_EPSILON;
- if (threshold > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) return false;
+ if (threshold > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) {
+ return false;
+ }
for (p = 0; p < n; p++) {
- if ((p == u) || (p == v) || (p == w)) continue;
+ if ((p == u) || (p == v) || (p == w)) {
+ continue;
+ }
Px = contour[V[p]].x;
Py = contour[V[p]].y;
- if (is_inside_triangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py, relaxed)) return false;
+ if (is_inside_triangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py, relaxed)) {
+ return false;
+ }
}
return true;
@@ -119,19 +124,24 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
/* allocate and initialize list of Vertices in polygon */
int n = contour.size();
- if (n < 3) return false;
+ if (n < 3) {
+ return false;
+ }
Vector<int> V;
V.resize(n);
/* we want a counter-clockwise polygon in V */
- if (0.0 < get_area(contour))
- for (int v = 0; v < n; v++)
+ if (0.0 < get_area(contour)) {
+ for (int v = 0; v < n; v++) {
V.write[v] = v;
- else
- for (int v = 0; v < n; v++)
+ }
+ } else {
+ for (int v = 0; v < n; v++) {
V.write[v] = (n - 1) - v;
+ }
+ }
bool relaxed = false;
@@ -161,11 +171,17 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
/* three consecutive vertices in current polygon, <u,v,w> */
int u = v;
- if (nv <= u) u = 0; /* previous */
+ if (nv <= u) {
+ u = 0; /* previous */
+ }
v = u + 1;
- if (nv <= v) v = 0; /* new v */
+ if (nv <= v) {
+ v = 0; /* new v */
+ }
int w = v + 1;
- if (nv <= w) w = 0; /* next */
+ if (nv <= w) {
+ w = 0; /* next */
+ }
if (snip(contour, u, v, w, nv, V, relaxed)) {
int a, b, c, s, t;
@@ -181,8 +197,9 @@ bool Triangulate::triangulate(const Vector<Vector2> &contour, Vector<int> &resul
result.push_back(c);
/* remove v from remaining polygon */
- for (s = v, t = v + 1; t < nv; s++, t++)
+ for (s = v, t = v + 1; t < nv; s++, t++) {
V.write[s] = V[t];
+ }
nv--;
diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp
index f4259e388b..233421e070 100644
--- a/core/math/vector2.cpp
+++ b/core/math/vector2.cpp
@@ -31,25 +31,20 @@
#include "vector2.h"
real_t Vector2::angle() const {
-
return Math::atan2(y, x);
}
real_t Vector2::length() const {
-
return Math::sqrt(x * x + y * y);
}
real_t Vector2::length_squared() const {
-
return x * x + y * y;
}
void Vector2::normalize() {
-
real_t l = x * x + y * y;
if (l != 0) {
-
l = Math::sqrt(l);
x /= l;
y /= l;
@@ -57,7 +52,6 @@ void Vector2::normalize() {
}
Vector2 Vector2::normalized() const {
-
Vector2 v = *this;
v.normalize();
return v;
@@ -69,61 +63,51 @@ bool Vector2::is_normalized() const {
}
real_t Vector2::distance_to(const Vector2 &p_vector2) const {
-
return Math::sqrt((x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y));
}
real_t Vector2::distance_squared_to(const Vector2 &p_vector2) const {
-
return (x - p_vector2.x) * (x - p_vector2.x) + (y - p_vector2.y) * (y - p_vector2.y);
}
real_t Vector2::angle_to(const Vector2 &p_vector2) const {
-
return Math::atan2(cross(p_vector2), dot(p_vector2));
}
real_t Vector2::angle_to_point(const Vector2 &p_vector2) const {
-
return Math::atan2(y - p_vector2.y, x - p_vector2.x);
}
real_t Vector2::dot(const Vector2 &p_other) const {
-
return x * p_other.x + y * p_other.y;
}
real_t Vector2::cross(const Vector2 &p_other) const {
-
return x * p_other.y - y * p_other.x;
}
Vector2 Vector2::sign() const {
-
return Vector2(SGN(x), SGN(y));
}
Vector2 Vector2::floor() const {
-
return Vector2(Math::floor(x), Math::floor(y));
}
Vector2 Vector2::ceil() const {
-
return Vector2(Math::ceil(x), Math::ceil(y));
}
Vector2 Vector2::round() const {
-
return Vector2(Math::round(x), Math::round(y));
}
Vector2 Vector2::rotated(real_t p_by) const {
-
- Vector2 v;
- v.set_rotation(angle() + p_by);
- v *= length();
- return v;
+ real_t sine = Math::sin(p_by);
+ real_t cosi = Math::cos(p_by);
+ return Vector2(
+ x * cosi - y * sine,
+ x * sine + y * cosi);
}
Vector2 Vector2::posmod(const real_t p_mod) const {
@@ -139,18 +123,15 @@ Vector2 Vector2::project(const Vector2 &p_b) const {
}
Vector2 Vector2::snapped(const Vector2 &p_by) const {
-
return Vector2(
Math::stepify(x, p_by.x),
Math::stepify(y, p_by.y));
}
Vector2 Vector2::clamped(real_t p_len) const {
-
real_t l = length();
Vector2 v = *this;
if (l > 0 && p_len < l) {
-
v /= l;
v *= p_len;
}
@@ -159,7 +140,6 @@ Vector2 Vector2::clamped(real_t p_len) const {
}
Vector2 Vector2::cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const {
-
Vector2 p0 = p_pre_a;
Vector2 p1 = *this;
Vector2 p2 = p_b;
@@ -210,65 +190,57 @@ bool Vector2::is_equal_approx(const Vector2 &p_v) const {
/* Vector2i */
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) {
+void Vector2i::operator+=(const Vector2i &p_v) {
x += p_v.x;
y += p_v.y;
}
-Vector2i Vector2i::operator-(const Vector2i &p_v) const {
+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) {
+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*(const int &rvalue) const {
-
return Vector2i(x * rvalue, y * rvalue);
-};
-void Vector2i::operator*=(const int &rvalue) {
+}
+void Vector2i::operator*=(const int &rvalue) {
x *= rvalue;
y *= rvalue;
-};
+}
Vector2i Vector2i::operator/(const Vector2i &p_v1) const {
-
return Vector2i(x / p_v1.x, y / p_v1.y);
-};
+}
Vector2i Vector2i::operator/(const int &rvalue) const {
-
return Vector2i(x / rvalue, y / rvalue);
-};
+}
void Vector2i::operator/=(const int &rvalue) {
-
x /= rvalue;
y /= 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 {
+bool Vector2i::operator!=(const Vector2i &p_vec2) const {
return x != p_vec2.x || y != p_vec2.y;
}
diff --git a/core/math/vector2.h b/core/math/vector2.h
index ba5558102f..8a08d3bf64 100644
--- a/core/math/vector2.h
+++ b/core/math/vector2.h
@@ -37,18 +37,17 @@
struct Vector2i;
struct Vector2 {
-
enum Axis {
AXIS_X,
AXIS_Y,
};
union {
- real_t x;
+ real_t x = 0;
real_t width;
};
union {
- real_t y;
+ real_t y = 0;
real_t height;
};
@@ -82,8 +81,7 @@ struct Vector2 {
Vector2 clamped(real_t p_len) const;
- _FORCE_INLINE_ static Vector2 linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t);
- _FORCE_INLINE_ Vector2 linear_interpolate(const Vector2 &p_b, real_t p_t) const;
+ _FORCE_INLINE_ Vector2 lerp(const Vector2 &p_b, real_t p_t) const;
_FORCE_INLINE_ Vector2 slerp(const Vector2 &p_b, real_t p_t) const;
Vector2 cubic_interpolate(const Vector2 &p_b, const Vector2 &p_pre_a, const Vector2 &p_post_b, real_t p_t) const;
Vector2 move_toward(const Vector2 &p_to, const real_t p_delta) const;
@@ -123,20 +121,12 @@ struct Vector2 {
real_t angle() const;
- void set_rotation(real_t p_radians) {
-
- x = Math::cos(p_radians);
- y = Math::sin(p_radians);
- }
-
_FORCE_INLINE_ Vector2 abs() const {
-
return Vector2(Math::abs(x), Math::abs(y));
}
Vector2 rotated(real_t p_by) const;
Vector2 tangent() const {
-
return Vector2(y, -x);
}
@@ -149,89 +139,78 @@ struct Vector2 {
operator String() const { return String::num(x) + ", " + String::num(y); }
+ _FORCE_INLINE_ Vector2() {}
_FORCE_INLINE_ Vector2(real_t p_x, real_t p_y) {
x = p_x;
y = p_y;
}
- _FORCE_INLINE_ Vector2() { x = y = 0; }
};
_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 operator*(real_t p_scalar, const Vector2 &p_vec) {
-
return p_vec * p_scalar;
}
_FORCE_INLINE_ 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) {
+_FORCE_INLINE_ 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 {
+_FORCE_INLINE_ 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) {
+_FORCE_INLINE_ 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 {
-
return Vector2(x * p_v1.x, y * p_v1.y);
-};
+}
_FORCE_INLINE_ Vector2 Vector2::operator*(const real_t &rvalue) const {
-
return Vector2(x * rvalue, y * rvalue);
-};
-_FORCE_INLINE_ void Vector2::operator*=(const real_t &rvalue) {
+}
+_FORCE_INLINE_ void Vector2::operator*=(const real_t &rvalue) {
x *= rvalue;
y *= rvalue;
-};
+}
_FORCE_INLINE_ Vector2 Vector2::operator/(const Vector2 &p_v1) const {
-
return Vector2(x / p_v1.x, y / p_v1.y);
-};
+}
_FORCE_INLINE_ Vector2 Vector2::operator/(const real_t &rvalue) const {
-
return Vector2(x / rvalue, y / rvalue);
-};
+}
_FORCE_INLINE_ void Vector2::operator/=(const real_t &rvalue) {
-
x /= rvalue;
y /= rvalue;
-};
+}
_FORCE_INLINE_ Vector2 Vector2::operator-() const {
-
return Vector2(-x, -y);
}
_FORCE_INLINE_ 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 {
+_FORCE_INLINE_ bool Vector2::operator!=(const Vector2 &p_vec2) const {
return x != p_vec2.x || y != p_vec2.y;
}
-Vector2 Vector2::linear_interpolate(const Vector2 &p_b, real_t p_t) const {
-
+Vector2 Vector2::lerp(const Vector2 &p_b, real_t p_t) const {
Vector2 res = *this;
res.x += (p_t * (p_b.x - x));
@@ -254,34 +233,23 @@ Vector2 Vector2::direction_to(const Vector2 &p_b) const {
return ret;
}
-Vector2 Vector2::linear_interpolate(const Vector2 &p_a, const Vector2 &p_b, real_t p_t) {
-
- Vector2 res = p_a;
-
- res.x += (p_t * (p_b.x - p_a.x));
- res.y += (p_t * (p_b.y - p_a.y));
-
- return res;
-}
-
typedef Vector2 Size2;
typedef Vector2 Point2;
/* INTEGER STUFF */
struct Vector2i {
-
enum Axis {
AXIS_X,
AXIS_Y,
};
union {
- int x;
+ int x = 0;
int width;
};
union {
- int y;
+ int y = 0;
int height;
};
@@ -324,6 +292,8 @@ struct Vector2i {
operator String() const { return String::num(x) + ", " + String::num(y); }
operator Vector2() const { return Vector2(x, y); }
+
+ inline Vector2i() {}
inline Vector2i(const Vector2 &p_vec2) {
x = (int)p_vec2.x;
y = (int)p_vec2.y;
@@ -332,10 +302,6 @@ struct Vector2i {
x = p_x;
y = p_y;
}
- inline Vector2i() {
- x = 0;
- y = 0;
- }
};
typedef Vector2i Size2i;
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index 353b2acd16..568df48c62 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -33,12 +33,10 @@
#include "core/math/basis.h"
void Vector3::rotate(const Vector3 &p_axis, real_t p_phi) {
-
*this = Basis(p_axis, p_phi).xform(*this);
}
Vector3 Vector3::rotated(const Vector3 &p_axis, real_t p_phi) const {
-
Vector3 r = *this;
r.rotate(p_axis, p_phi);
return r;
@@ -48,36 +46,33 @@ void Vector3::set_axis(int p_axis, real_t p_value) {
ERR_FAIL_INDEX(p_axis, 3);
coord[p_axis] = p_value;
}
-real_t Vector3::get_axis(int p_axis) const {
+real_t Vector3::get_axis(int p_axis) const {
ERR_FAIL_INDEX_V(p_axis, 3, 0);
return operator[](p_axis);
}
int Vector3::min_axis() const {
-
return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2);
}
-int Vector3::max_axis() const {
+int Vector3::max_axis() const {
return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0);
}
void Vector3::snap(Vector3 p_val) {
-
x = Math::stepify(x, p_val.x);
y = Math::stepify(y, p_val.y);
z = Math::stepify(z, p_val.z);
}
-Vector3 Vector3::snapped(Vector3 p_val) const {
+Vector3 Vector3::snapped(Vector3 p_val) const {
Vector3 v = *this;
v.snap(p_val);
return v;
}
Vector3 Vector3::cubic_interpolaten(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_t) const {
-
Vector3 p0 = p_pre_a;
Vector3 p1 = *this;
Vector3 p2 = p_b;
@@ -90,10 +85,12 @@ Vector3 Vector3::cubic_interpolaten(const Vector3 &p_b, const Vector3 &p_pre_a,
real_t bc = p1.distance_to(p2);
real_t cd = p2.distance_to(p3);
- if (ab > 0)
+ if (ab > 0) {
p0 = p1 + (p0 - p1) * (bc / ab);
- if (cd > 0)
+ }
+ if (cd > 0) {
p3 = p2 + (p3 - p2) * (bc / cd);
+ }
}
real_t t = p_t;
@@ -109,7 +106,6 @@ Vector3 Vector3::cubic_interpolaten(const Vector3 &p_b, const Vector3 &p_pre_a,
}
Vector3 Vector3::cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_t) const {
-
Vector3 p0 = p_pre_a;
Vector3 p1 = *this;
Vector3 p2 = p_b;
@@ -135,7 +131,6 @@ Vector3 Vector3::move_toward(const Vector3 &p_to, const real_t p_delta) const {
}
Basis Vector3::outer(const Vector3 &p_b) const {
-
Vector3 row0(x * p_b.x, x * p_b.y, x * p_b.z);
Vector3 row1(y * p_b.x, y * p_b.y, y * p_b.z);
Vector3 row2(z * p_b.x, z * p_b.y, z * p_b.z);
@@ -150,11 +145,9 @@ Basis Vector3::to_diagonal_matrix() const {
}
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);
}
Vector3::operator String() const {
-
return (rtos(x) + ", " + rtos(y) + ", " + rtos(z));
}
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 3bf8644af9..0bc1a467f2 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -38,7 +38,6 @@
class Basis;
struct Vector3 {
-
enum Axis {
AXIS_X,
AXIS_Y,
@@ -52,16 +51,14 @@ struct Vector3 {
real_t z;
};
- real_t coord[3];
+ real_t coord[3] = { 0 };
};
_FORCE_INLINE_ const real_t &operator[](int p_axis) const {
-
return coord[p_axis];
}
_FORCE_INLINE_ real_t &operator[](int p_axis) {
-
return coord[p_axis];
}
@@ -89,7 +86,7 @@ struct Vector3 {
/* Static Methods between 2 vector3s */
- _FORCE_INLINE_ Vector3 linear_interpolate(const Vector3 &p_b, real_t p_t) const;
+ _FORCE_INLINE_ Vector3 lerp(const Vector3 &p_b, real_t p_t) const;
_FORCE_INLINE_ Vector3 slerp(const Vector3 &p_b, real_t p_t) const;
Vector3 cubic_interpolate(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_t) const;
Vector3 cubic_interpolaten(const Vector3 &p_b, const Vector3 &p_pre_a, const Vector3 &p_post_b, real_t p_t) const;
@@ -152,22 +149,20 @@ struct Vector3 {
return Vector3i(x, y, z);
}
+ _FORCE_INLINE_ Vector3() {}
_FORCE_INLINE_ Vector3(const Vector3i &p_ivec) {
x = p_ivec.x;
y = p_ivec.y;
z = p_ivec.z;
}
-
_FORCE_INLINE_ Vector3(real_t p_x, real_t p_y, real_t p_z) {
x = p_x;
y = p_y;
z = p_z;
}
- _FORCE_INLINE_ Vector3() { x = y = z = 0; }
};
Vector3 Vector3::cross(const Vector3 &p_b) const {
-
Vector3 ret(
(y * p_b.z) - (z * p_b.y),
(z * p_b.x) - (x * p_b.z),
@@ -177,37 +172,30 @@ Vector3 Vector3::cross(const Vector3 &p_b) const {
}
real_t Vector3::dot(const Vector3 &p_b) const {
-
return x * p_b.x + y * p_b.y + z * p_b.z;
}
Vector3 Vector3::abs() const {
-
return Vector3(Math::abs(x), Math::abs(y), Math::abs(z));
}
Vector3 Vector3::sign() const {
-
return Vector3(SGN(x), SGN(y), SGN(z));
}
Vector3 Vector3::floor() const {
-
return Vector3(Math::floor(x), Math::floor(y), Math::floor(z));
}
Vector3 Vector3::ceil() const {
-
return Vector3(Math::ceil(x), Math::ceil(y), Math::ceil(z));
}
Vector3 Vector3::round() const {
-
return Vector3(Math::round(x), Math::round(y), Math::round(z));
}
-Vector3 Vector3::linear_interpolate(const Vector3 &p_b, real_t p_t) const {
-
+Vector3 Vector3::lerp(const Vector3 &p_b, real_t p_t) const {
return Vector3(
x + (p_t * (p_b.x - x)),
y + (p_t * (p_b.y - y)),
@@ -220,12 +208,10 @@ Vector3 Vector3::slerp(const Vector3 &p_b, real_t p_t) const {
}
real_t Vector3::distance_to(const Vector3 &p_b) const {
-
return (p_b - *this).length();
}
real_t Vector3::distance_squared_to(const Vector3 &p_b) const {
-
return (p_b - *this).length_squared();
}
@@ -242,7 +228,6 @@ Vector3 Vector3::project(const Vector3 &p_b) const {
}
real_t Vector3::angle_to(const Vector3 &p_b) const {
-
return Math::atan2(cross(p_b).length(), dot(p_b));
}
@@ -255,7 +240,6 @@ Vector3 Vector3::direction_to(const Vector3 &p_b) const {
/* Operators */
Vector3 &Vector3::operator+=(const Vector3 &p_v) {
-
x += p_v.x;
y += p_v.y;
z += p_v.z;
@@ -263,36 +247,32 @@ Vector3 &Vector3::operator+=(const Vector3 &p_v) {
}
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) {
-
x -= p_v.x;
y -= p_v.y;
z -= p_v.z;
return *this;
}
-Vector3 Vector3::operator-(const Vector3 &p_v) const {
+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) {
-
x *= p_v.x;
y *= p_v.y;
z *= p_v.z;
return *this;
}
-Vector3 Vector3::operator*(const Vector3 &p_v) const {
+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) {
-
x /= p_v.x;
y /= p_v.y;
z /= p_v.z;
@@ -300,12 +280,10 @@ Vector3 &Vector3::operator/=(const Vector3 &p_v) {
}
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) {
-
x *= p_scalar;
y *= p_scalar;
z *= p_scalar;
@@ -313,17 +291,14 @@ Vector3 &Vector3::operator*=(real_t p_scalar) {
}
_FORCE_INLINE_ Vector3 operator*(real_t p_scalar, const Vector3 &p_vec) {
-
return p_vec * p_scalar;
}
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) {
-
x /= p_scalar;
y /= p_scalar;
z /= p_scalar;
@@ -331,85 +306,78 @@ Vector3 &Vector3::operator/=(real_t p_scalar) {
}
Vector3 Vector3::operator/(real_t p_scalar) const {
-
return Vector3(x / p_scalar, y / p_scalar, z / p_scalar);
}
Vector3 Vector3::operator-() const {
-
return Vector3(-x, -y, -z);
}
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 {
-
return x != p_v.x || y != p_v.y || z != p_v.z;
}
bool Vector3::operator<(const Vector3 &p_v) const {
-
if (Math::is_equal_approx(x, p_v.x)) {
- if (Math::is_equal_approx(y, p_v.y))
+ if (Math::is_equal_approx(y, p_v.y)) {
return z < p_v.z;
- else
+ } else {
return y < p_v.y;
+ }
} else {
return x < p_v.x;
}
}
bool Vector3::operator>(const Vector3 &p_v) const {
-
if (Math::is_equal_approx(x, p_v.x)) {
- if (Math::is_equal_approx(y, p_v.y))
+ if (Math::is_equal_approx(y, p_v.y)) {
return z > p_v.z;
- else
+ } else {
return y > p_v.y;
+ }
} else {
return x > p_v.x;
}
}
bool Vector3::operator<=(const Vector3 &p_v) const {
-
if (Math::is_equal_approx(x, p_v.x)) {
- if (Math::is_equal_approx(y, p_v.y))
+ if (Math::is_equal_approx(y, p_v.y)) {
return z <= p_v.z;
- else
+ } else {
return y < p_v.y;
+ }
} else {
return x < p_v.x;
}
}
bool Vector3::operator>=(const Vector3 &p_v) const {
-
if (Math::is_equal_approx(x, p_v.x)) {
- if (Math::is_equal_approx(y, p_v.y))
+ if (Math::is_equal_approx(y, p_v.y)) {
return z >= p_v.z;
- else
+ } else {
return y > p_v.y;
+ }
} else {
return x > p_v.x;
}
}
_FORCE_INLINE_ Vector3 vec3_cross(const Vector3 &p_a, const Vector3 &p_b) {
-
return p_a.cross(p_b);
}
_FORCE_INLINE_ real_t vec3_dot(const Vector3 &p_a, const Vector3 &p_b) {
-
return p_a.dot(p_b);
}
real_t Vector3::length() const {
-
real_t x2 = x * x;
real_t y2 = y * y;
real_t z2 = z * z;
@@ -418,7 +386,6 @@ real_t Vector3::length() const {
}
real_t Vector3::length_squared() const {
-
real_t x2 = x * x;
real_t y2 = y * y;
real_t z2 = z * z;
@@ -427,7 +394,6 @@ real_t Vector3::length_squared() const {
}
void Vector3::normalize() {
-
real_t lengthsq = length_squared();
if (lengthsq == 0) {
x = y = z = 0;
@@ -440,7 +406,6 @@ void Vector3::normalize() {
}
Vector3 Vector3::normalized() const {
-
Vector3 v = *this;
v.normalize();
return v;
@@ -452,12 +417,10 @@ bool Vector3::is_normalized() const {
}
Vector3 Vector3::inverse() const {
-
return Vector3(1.0 / x, 1.0 / y, 1.0 / z);
}
void Vector3::zero() {
-
x = y = z = 0;
}
diff --git a/core/math/vector3i.cpp b/core/math/vector3i.cpp
index 8a4ddf03b9..718a1553a0 100644
--- a/core/math/vector3i.cpp
+++ b/core/math/vector3i.cpp
@@ -34,22 +34,20 @@ void Vector3i::set_axis(int p_axis, int32_t p_value) {
ERR_FAIL_INDEX(p_axis, 3);
coord[p_axis] = p_value;
}
-int32_t Vector3i::get_axis(int p_axis) const {
+int32_t Vector3i::get_axis(int p_axis) const {
ERR_FAIL_INDEX_V(p_axis, 3, 0);
return operator[](p_axis);
}
int Vector3i::min_axis() const {
-
return x < y ? (x < z ? 0 : 2) : (y < z ? 1 : 2);
}
-int Vector3i::max_axis() const {
+int Vector3i::max_axis() const {
return x < y ? (y < z ? 2 : 1) : (x < z ? 2 : 0);
}
Vector3i::operator String() const {
-
return (itos(x) + ", " + itos(y) + ", " + itos(z));
}
diff --git a/core/math/vector3i.h b/core/math/vector3i.h
index 6f9754d3b9..08729ad056 100644
--- a/core/math/vector3i.h
+++ b/core/math/vector3i.h
@@ -35,7 +35,6 @@
#include "core/ustring.h"
struct Vector3i {
-
enum Axis {
AXIS_X,
AXIS_Y,
@@ -49,16 +48,14 @@ struct Vector3i {
int32_t z;
};
- int32_t coord[3];
+ int32_t coord[3] = { 0 };
};
_FORCE_INLINE_ const int32_t &operator[](int p_axis) const {
-
return coord[p_axis];
}
_FORCE_INLINE_ int32_t &operator[](int p_axis) {
-
return coord[p_axis];
}
@@ -100,28 +97,25 @@ struct Vector3i {
operator String() 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;
}
- _FORCE_INLINE_ Vector3i() { x = y = z = 0; }
};
Vector3i Vector3i::abs() const {
-
return Vector3i(ABS(x), ABS(y), ABS(z));
}
Vector3i Vector3i::sign() const {
-
return Vector3i(SGN(x), SGN(y), SGN(z));
}
/* Operators */
Vector3i &Vector3i::operator+=(const Vector3i &p_v) {
-
x += p_v.x;
y += p_v.y;
z += p_v.z;
@@ -129,36 +123,32 @@ Vector3i &Vector3i::operator+=(const Vector3i &p_v) {
}
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) {
-
x -= p_v.x;
y -= p_v.y;
z -= p_v.z;
return *this;
}
-Vector3i Vector3i::operator-(const Vector3i &p_v) const {
+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) {
-
x *= p_v.x;
y *= p_v.y;
z *= p_v.z;
return *this;
}
-Vector3i Vector3i::operator*(const Vector3i &p_v) const {
+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) {
-
x /= p_v.x;
y /= p_v.y;
z /= p_v.z;
@@ -166,12 +156,10 @@ Vector3i &Vector3i::operator/=(const Vector3i &p_v) {
}
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) {
-
x *= p_scalar;
y *= p_scalar;
z *= p_scalar;
@@ -179,17 +167,14 @@ Vector3i &Vector3i::operator*=(int32_t p_scalar) {
}
_FORCE_INLINE_ Vector3i operator*(int32_t p_scalar, const Vector3i &p_vec) {
-
return p_vec * p_scalar;
}
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) {
-
x /= p_scalar;
y /= p_scalar;
z /= p_scalar;
@@ -197,75 +182,70 @@ Vector3i &Vector3i::operator/=(int32_t p_scalar) {
}
Vector3i Vector3i::operator/(int32_t p_scalar) const {
-
return Vector3i(x / p_scalar, y / p_scalar, z / p_scalar);
}
Vector3i Vector3i::operator-() const {
-
return Vector3i(-x, -y, -z);
}
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 {
-
return (x != p_v.x || y != p_v.y || z != p_v.z);
}
bool Vector3i::operator<(const Vector3i &p_v) const {
-
if (x == p_v.x) {
- if (y == p_v.y)
+ if (y == p_v.y) {
return z < p_v.z;
- else
+ } else {
return y < p_v.y;
+ }
} else {
return x < p_v.x;
}
}
bool Vector3i::operator>(const Vector3i &p_v) const {
-
if (x == p_v.x) {
- if (y == p_v.y)
+ if (y == p_v.y) {
return z > p_v.z;
- else
+ } else {
return y > p_v.y;
+ }
} else {
return x > p_v.x;
}
}
bool Vector3i::operator<=(const Vector3i &p_v) const {
-
if (x == p_v.x) {
- if (y == p_v.y)
+ if (y == p_v.y) {
return z <= p_v.z;
- else
+ } else {
return y < p_v.y;
+ }
} else {
return x < p_v.x;
}
}
bool Vector3i::operator>=(const Vector3i &p_v) const {
-
if (x == p_v.x) {
- if (y == p_v.y)
+ if (y == p_v.y) {
return z >= p_v.z;
- else
+ } else {
return y > p_v.y;
+ }
} else {
return x > p_v.x;
}
}
void Vector3i::zero() {
-
x = y = z = 0;
}
diff --git a/core/message_queue.cpp b/core/message_queue.cpp
index 652c424492..6dcf24e7ed 100644
--- a/core/message_queue.cpp
+++ b/core/message_queue.cpp
@@ -37,24 +37,22 @@
MessageQueue *MessageQueue::singleton = nullptr;
MessageQueue *MessageQueue::get_singleton() {
-
return singleton;
}
Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error) {
-
return push_callable(Callable(p_id, p_method), p_args, p_argcount, p_show_error);
}
Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS;
int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
argc++;
}
@@ -62,15 +60,15 @@ Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, VARIANT
}
Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Variant &p_value) {
-
_THREAD_SAFE_METHOD_
uint8_t room_needed = sizeof(Message) + sizeof(Variant);
if ((buffer_end + room_needed) >= buffer_size) {
String type;
- if (ObjectDB::get_instance(p_id))
+ if (ObjectDB::get_instance(p_id)) {
type = ObjectDB::get_instance(p_id)->get_class();
+ }
print_line("Failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id));
statistics();
ERR_FAIL_V_MSG(ERR_OUT_OF_MEMORY, "Message queue out of memory. Try increasing 'memory/limits/message_queue/max_size_kb' in project settings.");
@@ -91,7 +89,6 @@ Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Vari
}
Error MessageQueue::push_notification(ObjectID p_id, int p_notification) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(p_notification < 0, ERR_INVALID_PARAMETER);
@@ -117,21 +114,18 @@ Error MessageQueue::push_notification(ObjectID p_id, int p_notification) {
}
Error MessageQueue::push_call(Object *p_object, const StringName &p_method, VARIANT_ARG_DECLARE) {
-
return push_call(p_object->get_instance_id(), p_method, VARIANT_ARG_PASS);
}
Error MessageQueue::push_notification(Object *p_object, int p_notification) {
-
return push_notification(p_object->get_instance_id(), p_notification);
}
-Error MessageQueue::push_set(Object *p_object, const StringName &p_prop, const Variant &p_value) {
+Error MessageQueue::push_set(Object *p_object, const StringName &p_prop, const Variant &p_value) {
return push_set(p_object->get_instance_id(), p_prop, p_value);
}
Error MessageQueue::push_callable(const Callable &p_callable, const Variant **p_args, int p_argcount, bool p_show_error) {
-
_THREAD_SAFE_METHOD_
int room_needed = sizeof(Message) + sizeof(Variant) * p_argcount;
@@ -146,13 +140,13 @@ Error MessageQueue::push_callable(const Callable &p_callable, const Variant **p_
msg->args = p_argcount;
msg->callable = p_callable;
msg->type = TYPE_CALL;
- if (p_show_error)
+ if (p_show_error) {
msg->type |= FLAG_SHOW_ERROR;
+ }
buffer_end += sizeof(Message);
for (int i = 0; i < p_argcount; i++) {
-
Variant *v = memnew_placement(&buffer[buffer_end], Variant);
buffer_end += sizeof(Variant);
*v = *p_args[i];
@@ -161,8 +155,22 @@ Error MessageQueue::push_callable(const Callable &p_callable, const Variant **p_
return OK;
}
-void MessageQueue::statistics() {
+Error MessageQueue::push_callable(const Callable &p_callable, VARIANT_ARG_DECLARE) {
+ VARIANT_ARGPTRS;
+
+ int argc = 0;
+ for (int i = 0; i < VARIANT_ARG_MAX; i++) {
+ if (argptr[i]->get_type() == Variant::NIL) {
+ break;
+ }
+ argc++;
+ }
+
+ return push_callable(p_callable, argptr, argc);
+}
+
+void MessageQueue::statistics() {
Map<StringName, int> set_count;
Map<int, int> notify_count;
Map<Callable, int> call_count;
@@ -175,30 +183,28 @@ void MessageQueue::statistics() {
Object *target = message->callable.get_object();
if (target != nullptr) {
-
switch (message->type & FLAG_MASK) {
-
case TYPE_CALL: {
-
- if (!call_count.has(message->callable))
+ if (!call_count.has(message->callable)) {
call_count[message->callable] = 0;
+ }
call_count[message->callable]++;
} break;
case TYPE_NOTIFICATION: {
-
- if (!notify_count.has(message->notification))
+ if (!notify_count.has(message->notification)) {
notify_count[message->notification] = 0;
+ }
notify_count[message->notification]++;
} break;
case TYPE_SET: {
-
StringName t = message->callable.get_method();
- if (!set_count.has(t))
+ if (!set_count.has(t)) {
set_count[t] = 0;
+ }
set_count[t]++;
@@ -213,8 +219,9 @@ void MessageQueue::statistics() {
}
read_pos += sizeof(Message);
- if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION)
+ if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
read_pos += sizeof(Variant) * message->args;
+ }
}
print_line("TOTAL BYTES: " + itos(buffer_end));
@@ -234,12 +241,10 @@ void MessageQueue::statistics() {
}
int MessageQueue::get_max_buffer_usage() const {
-
return buffer_max_used;
}
void MessageQueue::_call_function(const Callable &p_callable, const Variant *p_args, int p_argcount, bool p_show_error) {
-
const Variant **argptrs = nullptr;
if (p_argcount) {
argptrs = (const Variant **)alloca(sizeof(Variant *) * p_argcount);
@@ -252,13 +257,11 @@ void MessageQueue::_call_function(const Callable &p_callable, const Variant *p_a
Variant ret;
p_callable.call(argptrs, p_argcount, ret, ce);
if (p_show_error && ce.error != Callable::CallError::CALL_OK) {
-
ERR_PRINT("Error calling deferred method: " + Variant::get_callable_error_text(p_callable, argptrs, p_argcount, ce) + ".");
}
}
void MessageQueue::flush() {
-
if (buffer_end > buffer_max_used) {
buffer_max_used = buffer_end;
}
@@ -275,14 +278,14 @@ void MessageQueue::flush() {
flushing = true;
while (read_pos < buffer_end) {
-
//lock on each iteration, so a call can re-add itself to the message queue
Message *message = (Message *)&buffer[read_pos];
uint32_t advance = sizeof(Message);
- if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION)
+ if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
advance += sizeof(Variant) * message->args;
+ }
//pre-advance so this function is reentrant
read_pos += advance;
@@ -292,10 +295,8 @@ void MessageQueue::flush() {
Object *target = message->callable.get_object();
if (target != nullptr) {
-
switch (message->type & FLAG_MASK) {
case TYPE_CALL: {
-
Variant *args = (Variant *)(message + 1);
// messages don't expect a return value
@@ -304,13 +305,11 @@ void MessageQueue::flush() {
} break;
case TYPE_NOTIFICATION: {
-
// messages don't expect a return value
target->notification(message->notification);
} break;
case TYPE_SET: {
-
Variant *arg = (Variant *)(message + 1);
// messages don't expect a return value
target->set(message->callable.get_method(), *arg);
@@ -337,18 +336,13 @@ void MessageQueue::flush() {
}
bool MessageQueue::is_flushing() const {
-
return flushing;
}
MessageQueue::MessageQueue() {
-
ERR_FAIL_COND_MSG(singleton != nullptr, "A MessageQueue singleton already exists.");
singleton = this;
- flushing = false;
- buffer_end = 0;
- buffer_max_used = 0;
buffer_size = GLOBAL_DEF_RST("memory/limits/message_queue/max_size_kb", DEFAULT_QUEUE_SIZE_KB);
ProjectSettings::get_singleton()->set_custom_property_info("memory/limits/message_queue/max_size_kb", PropertyInfo(Variant::INT, "memory/limits/message_queue/max_size_kb", PROPERTY_HINT_RANGE, "1024,4096,1,or_greater"));
buffer_size *= 1024;
@@ -356,23 +350,23 @@ MessageQueue::MessageQueue() {
}
MessageQueue::~MessageQueue() {
-
uint32_t read_pos = 0;
while (read_pos < buffer_end) {
-
Message *message = (Message *)&buffer[read_pos];
Variant *args = (Variant *)(message + 1);
int argc = message->args;
if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
- for (int i = 0; i < argc; i++)
+ for (int i = 0; i < argc; i++) {
args[i].~Variant();
+ }
}
message->~Message();
read_pos += sizeof(Message);
- if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION)
+ if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION) {
read_pos += sizeof(Variant) * message->args;
+ }
}
singleton = nullptr;
diff --git a/core/message_queue.h b/core/message_queue.h
index 9ba748bb42..7d13e26208 100644
--- a/core/message_queue.h
+++ b/core/message_queue.h
@@ -35,7 +35,6 @@
#include "core/os/thread_safe.h"
class MessageQueue {
-
_THREAD_SAFE_CLASS_
enum {
@@ -53,7 +52,6 @@ class MessageQueue {
};
struct Message {
-
Callable callable;
int16_t type;
union {
@@ -63,15 +61,15 @@ class MessageQueue {
};
uint8_t *buffer;
- uint32_t buffer_end;
- uint32_t buffer_max_used;
+ uint32_t buffer_end = 0;
+ uint32_t buffer_max_used = 0;
uint32_t buffer_size;
void _call_function(const Callable &p_callable, const Variant *p_args, int p_argcount, bool p_show_error);
static MessageQueue *singleton;
- bool flushing;
+ bool flushing = false;
public:
static MessageQueue *get_singleton();
@@ -81,6 +79,7 @@ public:
Error push_notification(ObjectID p_id, int p_notification);
Error push_set(ObjectID p_id, const StringName &p_prop, const Variant &p_value);
Error push_callable(const Callable &p_callable, const Variant **p_args, int p_argcount, bool p_show_error = false);
+ Error push_callable(const Callable &p_callable, VARIANT_ARG_LIST);
Error push_call(Object *p_object, const StringName &p_method, VARIANT_ARG_LIST);
Error push_notification(Object *p_object, int p_notification);
diff --git a/core/method_bind.cpp b/core/method_bind.cpp
index c513de9ca0..3244c63292 100644
--- a/core/method_bind.cpp
+++ b/core/method_bind.cpp
@@ -36,7 +36,6 @@
#ifdef DEBUG_METHODS_ENABLED
PropertyInfo MethodBind::get_argument_info(int p_argument) const {
-
ERR_FAIL_INDEX_V(p_argument, get_argument_count(), PropertyInfo());
PropertyInfo info = _gen_argument_type_info(p_argument);
@@ -45,35 +44,32 @@ PropertyInfo MethodBind::get_argument_info(int p_argument) const {
}
PropertyInfo MethodBind::get_return_info() const {
-
return _gen_argument_type_info(-1);
}
#endif
void MethodBind::_set_const(bool p_const) {
-
_const = p_const;
}
void MethodBind::_set_returns(bool p_returns) {
-
_returns = p_returns;
}
StringName MethodBind::get_name() const {
return name;
}
+
void MethodBind::set_name(const StringName &p_name) {
name = p_name;
}
#ifdef DEBUG_METHODS_ENABLED
void MethodBind::set_argument_names(const Vector<StringName> &p_names) {
-
arg_names = p_names;
}
-Vector<StringName> MethodBind::get_argument_names() const {
+Vector<StringName> MethodBind::get_argument_names() const {
return arg_names;
}
@@ -86,7 +82,6 @@ void MethodBind::set_default_arguments(const Vector<Variant> &p_defargs) {
#ifdef DEBUG_METHODS_ENABLED
void MethodBind::_generate_argument_types(int p_count) {
-
set_argument_count(p_count);
Variant::Type *argt = memnew_arr(Variant::Type, p_count + 1);
@@ -104,19 +99,12 @@ void MethodBind::_generate_argument_types(int p_count) {
MethodBind::MethodBind() {
static int last_id = 0;
method_id = last_id++;
- hint_flags = METHOD_FLAGS_DEFAULT;
- argument_count = 0;
- default_argument_count = 0;
-#ifdef DEBUG_METHODS_ENABLED
- argument_types = nullptr;
-#endif
- _const = false;
- _returns = false;
}
MethodBind::~MethodBind() {
#ifdef DEBUG_METHODS_ENABLED
- if (argument_types)
+ if (argument_types) {
memdelete_arr(argument_types);
+ }
#endif
}
diff --git a/core/method_bind.h b/core/method_bind.h
index 588b472b62..ff2c771f81 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -39,6 +39,7 @@
#include "core/method_ptrcall.h"
#include "core/object.h"
#include "core/type_info.h"
+#include "core/typedefs.h"
#include "core/variant.h"
#include <stdio.h>
@@ -58,27 +59,21 @@ enum MethodFlags {
template <class T>
struct VariantCaster {
-
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
-
return p_variant;
}
};
template <class T>
struct VariantCaster<T &> {
-
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
-
return p_variant;
}
};
template <class T>
struct VariantCaster<const T &> {
-
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
-
return p_variant;
}
};
@@ -92,7 +87,6 @@ struct VariantCaster<const T &> {
MAKE_ENUM_TYPE_INFO(m_enum) \
template <> \
struct VariantCaster<m_enum> { \
- \
static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
return (m_enum)p_variant.operator int(); \
} \
@@ -113,7 +107,6 @@ struct VariantCaster<const T &> {
MAKE_ENUM_TYPE_INFO(m_enum) \
template <> \
struct VariantCaster<m_enum> { \
- \
static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
return (m_enum)p_variant.operator int(); \
} \
@@ -164,7 +157,9 @@ struct VariantObjectClassChecker<Control *> {
#define CHECK_NOARG(m_arg) \
{ \
if (p_arg##m_arg.get_type() != Variant::NIL) { \
- if (r_argerror) *r_argerror = (m_arg - 1); \
+ if (r_argerror) { \
+ *r_argerror = (m_arg - 1); \
+ } \
return CALL_ERROR_EXTRA_ARGUMENT; \
} \
}
@@ -204,20 +199,19 @@ struct PtrToArg<wchar_t> {
#endif
class MethodBind {
-
int method_id;
- uint32_t hint_flags;
+ uint32_t hint_flags = METHOD_FLAGS_DEFAULT;
StringName name;
Vector<Variant> default_arguments;
- int default_argument_count;
- int argument_count;
+ int default_argument_count = 0;
+ int argument_count = 0;
- bool _const;
- bool _returns;
+ bool _const = false;
+ bool _returns = false;
protected:
#ifdef DEBUG_METHODS_ENABLED
- Variant::Type *argument_types;
+ Variant::Type *argument_types = nullptr;
Vector<StringName> arg_names;
#endif
void _set_const(bool p_const);
@@ -235,29 +229,28 @@ public:
_FORCE_INLINE_ int get_default_argument_count() const { return default_argument_count; }
_FORCE_INLINE_ Variant has_default_argument(int p_arg) const {
-
int idx = argument_count - p_arg - 1;
- if (idx < 0 || idx >= default_arguments.size())
+ if (idx < 0 || idx >= default_arguments.size()) {
return false;
- else
+ } else {
return true;
+ }
}
_FORCE_INLINE_ Variant get_default_argument(int p_arg) const {
-
int idx = argument_count - p_arg - 1;
- if (idx < 0 || idx >= default_arguments.size())
+ if (idx < 0 || idx >= default_arguments.size()) {
return Variant();
- else
+ } else {
return default_arguments[idx];
+ }
}
#ifdef DEBUG_METHODS_ENABLED
_FORCE_INLINE_ Variant::Type get_argument_type(int p_argument) const {
-
ERR_FAIL_COND_V(p_argument < -1 || p_argument > argument_count, Variant::NIL);
return argument_types[p_argument + 1];
}
@@ -302,17 +295,15 @@ public:
typedef Variant (T::*NativeCall)(const Variant **, int, Callable::CallError &);
protected:
- NativeCall call_method;
+ NativeCall call_method = nullptr;
#ifdef DEBUG_METHODS_ENABLED
-
MethodInfo arguments;
-
#endif
+
public:
#ifdef DEBUG_METHODS_ENABLED
virtual PropertyInfo _gen_argument_type_info(int p_arg) const {
-
if (p_arg < 0) {
return arguments.return_val;
} else if (p_arg < arguments.arguments.size()) {
@@ -338,23 +329,19 @@ public:
#endif
virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
-
T *instance = static_cast<T *>(p_object);
return (instance->*call_method)(p_args, p_arg_count, r_error);
}
void set_method_info(const MethodInfo &p_info, bool p_return_nil_is_variant) {
-
set_argument_count(p_info.arguments.size());
#ifdef DEBUG_METHODS_ENABLED
Variant::Type *at = memnew_arr(Variant::Type, p_info.arguments.size() + 1);
at[0] = p_info.return_val.type;
if (p_info.arguments.size()) {
-
Vector<StringName> names;
names.resize(p_info.arguments.size());
for (int i = 0; i < p_info.arguments.size(); i++) {
-
at[i + 1] = p_info.arguments[i].type;
names.write[i] = p_info.arguments[i].name;
}
@@ -382,14 +369,12 @@ public:
virtual bool is_vararg() const { return true; }
MethodBindVarArg() {
- call_method = nullptr;
_set_returns(true);
}
};
template <class T>
MethodBind *create_vararg_method_bind(Variant (T::*p_method)(const Variant **, int, Callable::CallError &), const MethodInfo &p_info, bool p_return_nil_is_variant) {
-
MethodBindVarArg<T> *a = memnew((MethodBindVarArg<T>));
a->set_method(p_method);
a->set_method_info(p_info, p_return_nil_is_variant);
diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h
index 7ae0a788bd..022ed2a5d6 100644
--- a/core/method_ptrcall.h
+++ b/core/method_ptrcall.h
@@ -150,28 +150,22 @@ MAKE_PTRARG_BY_REFERENCE(Variant);
template <class T>
struct PtrToArg<T *> {
-
_FORCE_INLINE_ static T *convert(const void *p_ptr) {
-
return const_cast<T *>(reinterpret_cast<const T *>(p_ptr));
}
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
-
*((T **)p_ptr) = p_var;
}
};
template <class T>
struct PtrToArg<const T *> {
-
_FORCE_INLINE_ static const T *convert(const void *p_ptr) {
-
return reinterpret_cast<const T *>(p_ptr);
}
_FORCE_INLINE_ static void encode(T *p_var, void *p_ptr) {
-
*((T **)p_ptr) = p_var;
}
};
@@ -181,12 +175,10 @@ struct PtrToArg<const T *> {
template <>
struct PtrToArg<ObjectID> {
_FORCE_INLINE_ static const ObjectID convert(const void *p_ptr) {
-
return ObjectID(*reinterpret_cast<const uint64_t *>(p_ptr));
}
_FORCE_INLINE_ static void encode(const ObjectID &p_val, void *p_ptr) {
-
*((uint64_t *)p_ptr) = p_val;
}
};
diff --git a/core/node_path.cpp b/core/node_path.cpp
index 83233622a0..2a51dca74a 100644
--- a/core/node_path.cpp
+++ b/core/node_path.cpp
@@ -33,7 +33,6 @@
#include "core/print_string.h"
void NodePath::_update_hash_cache() const {
-
uint32_t h = data->absolute ? 1 : 0;
int pc = data->path.size();
const StringName *sn = data->path.ptr();
@@ -51,7 +50,6 @@ void NodePath::_update_hash_cache() const {
}
void NodePath::prepend_period() {
-
if (data->path.size() && data->path[0].operator String() != ".") {
data->path.insert(0, ".");
data->hash_cache_valid = false;
@@ -59,59 +57,60 @@ void NodePath::prepend_period() {
}
bool NodePath::is_absolute() const {
-
- if (!data)
+ if (!data) {
return false;
+ }
return data->absolute;
}
-int NodePath::get_name_count() const {
- if (!data)
+int NodePath::get_name_count() const {
+ if (!data) {
return 0;
+ }
return data->path.size();
}
-StringName NodePath::get_name(int p_idx) const {
+StringName NodePath::get_name(int p_idx) const {
ERR_FAIL_COND_V(!data, StringName());
ERR_FAIL_INDEX_V(p_idx, data->path.size(), StringName());
return data->path[p_idx];
}
int NodePath::get_subname_count() const {
-
- if (!data)
+ if (!data) {
return 0;
+ }
return data->subpath.size();
}
-StringName NodePath::get_subname(int p_idx) const {
+StringName NodePath::get_subname(int p_idx) const {
ERR_FAIL_COND_V(!data, StringName());
ERR_FAIL_INDEX_V(p_idx, data->subpath.size(), StringName());
return data->subpath[p_idx];
}
void NodePath::unref() {
-
if (data && data->refcount.unref()) {
-
memdelete(data);
}
data = nullptr;
}
bool NodePath::operator==(const NodePath &p_path) const {
-
- if (data == p_path.data)
+ if (data == p_path.data) {
return true;
+ }
- if (!data || !p_path.data)
+ if (!data || !p_path.data) {
return false;
+ }
- if (data->absolute != p_path.data->absolute)
+ if (data->absolute != p_path.data->absolute) {
return false;
+ }
int path_size = data->path.size();
@@ -129,85 +128,74 @@ bool NodePath::operator==(const NodePath &p_path) const {
const StringName *r_path_ptr = p_path.data->path.ptr();
for (int i = 0; i < path_size; i++) {
-
- if (l_path_ptr[i] != r_path_ptr[i])
+ if (l_path_ptr[i] != r_path_ptr[i]) {
return false;
+ }
}
const StringName *l_subpath_ptr = data->subpath.ptr();
const StringName *r_subpath_ptr = p_path.data->subpath.ptr();
for (int i = 0; i < subpath_size; i++) {
-
- if (l_subpath_ptr[i] != r_subpath_ptr[i])
+ if (l_subpath_ptr[i] != r_subpath_ptr[i]) {
return false;
+ }
}
return true;
}
-bool NodePath::operator!=(const NodePath &p_path) const {
+bool NodePath::operator!=(const NodePath &p_path) const {
return (!(*this == p_path));
}
void NodePath::operator=(const NodePath &p_path) {
-
- if (this == &p_path)
+ if (this == &p_path) {
return;
+ }
unref();
if (p_path.data && p_path.data->refcount.ref()) {
-
data = p_path.data;
}
}
NodePath::operator String() const {
-
- if (!data)
+ if (!data) {
return String();
+ }
String ret;
- if (data->absolute)
+ if (data->absolute) {
ret = "/";
+ }
for (int i = 0; i < data->path.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
ret += "/";
+ }
ret += data->path[i].operator String();
}
for (int i = 0; i < data->subpath.size(); i++) {
-
ret += ":" + data->subpath[i].operator String();
}
return ret;
}
-NodePath::NodePath(const NodePath &p_path) {
-
- data = nullptr;
-
- if (p_path.data && p_path.data->refcount.ref()) {
-
- data = p_path.data;
- }
-}
-
Vector<StringName> NodePath::get_names() const {
-
- if (data)
+ if (data) {
return data->path;
+ }
return Vector<StringName>();
}
Vector<StringName> NodePath::get_subnames() const {
-
- if (data)
+ if (data) {
return data->subpath;
+ }
return Vector<StringName>();
}
@@ -227,7 +215,6 @@ StringName NodePath::get_concatenated_subnames() const {
}
NodePath NodePath::rel_path_to(const NodePath &p_np) const {
-
ERR_FAIL_COND_V(!is_absolute(), NodePath());
ERR_FAIL_COND_V(!p_np.is_absolute(), NodePath());
@@ -238,12 +225,15 @@ NodePath NodePath::rel_path_to(const NodePath &p_np) const {
int common_parent = 0;
while (true) {
- if (src_dirs.size() == common_parent)
+ if (src_dirs.size() == common_parent) {
break;
- if (dst_dirs.size() == common_parent)
+ }
+ if (dst_dirs.size() == common_parent) {
break;
- if (src_dirs[common_parent] != dst_dirs[common_parent])
+ }
+ if (src_dirs[common_parent] != dst_dirs[common_parent]) {
break;
+ }
common_parent++;
}
@@ -252,23 +242,21 @@ NodePath NodePath::rel_path_to(const NodePath &p_np) const {
Vector<StringName> relpath;
for (int i = src_dirs.size() - 1; i > common_parent; i--) {
-
relpath.push_back("..");
}
for (int i = common_parent + 1; i < dst_dirs.size(); i++) {
-
relpath.push_back(dst_dirs[i]);
}
- if (relpath.size() == 0)
+ if (relpath.size() == 0) {
relpath.push_back(".");
+ }
return NodePath(relpath, p_np.get_subnames(), false);
}
NodePath NodePath::get_as_property_path() const {
-
if (!data || !data->path.size()) {
return *this;
} else {
@@ -285,44 +273,18 @@ NodePath NodePath::get_as_property_path() const {
}
}
-NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
-
- data = nullptr;
-
- if (p_path.size() == 0)
- return;
-
- data = memnew(Data);
- data->refcount.init();
- data->absolute = p_absolute;
- data->path = p_path;
- data->has_slashes = true;
- data->hash_cache_valid = false;
-}
-
-NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) {
-
- data = nullptr;
-
- if (p_path.size() == 0 && p_subpath.size() == 0)
- return;
-
- data = memnew(Data);
- data->refcount.init();
- data->absolute = p_absolute;
- data->path = p_path;
- data->subpath = p_subpath;
- data->has_slashes = true;
- data->hash_cache_valid = false;
+bool NodePath::is_empty() const {
+ return !data;
}
void NodePath::simplify() {
-
- if (!data)
+ if (!data) {
return;
+ }
for (int i = 0; i < data->path.size(); i++) {
- if (data->path.size() == 1)
+ if (data->path.size() == 1) {
break;
+ }
if (data->path[i].operator String() == ".") {
data->path.remove(i);
i--;
@@ -341,18 +303,48 @@ void NodePath::simplify() {
}
NodePath NodePath::simplified() const {
-
NodePath np = *this;
np.simplify();
return np;
}
-NodePath::NodePath(const String &p_path) {
+NodePath::NodePath(const Vector<StringName> &p_path, bool p_absolute) {
+ if (p_path.size() == 0) {
+ return;
+ }
- data = nullptr;
+ data = memnew(Data);
+ data->refcount.init();
+ data->absolute = p_absolute;
+ data->path = p_path;
+ data->has_slashes = true;
+ data->hash_cache_valid = false;
+}
- if (p_path.length() == 0)
+NodePath::NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute) {
+ if (p_path.size() == 0 && p_subpath.size() == 0) {
return;
+ }
+
+ data = memnew(Data);
+ data->refcount.init();
+ data->absolute = p_absolute;
+ data->path = p_path;
+ data->subpath = p_subpath;
+ data->has_slashes = true;
+ data->hash_cache_valid = false;
+}
+
+NodePath::NodePath(const NodePath &p_path) {
+ if (p_path.data && p_path.data->refcount.ref()) {
+ data = p_path.data;
+ }
+}
+
+NodePath::NodePath(const String &p_path) {
+ if (p_path.length() == 0) {
+ return;
+ }
String path = p_path;
Vector<StringName> subpath;
@@ -364,16 +356,15 @@ NodePath::NodePath(const String &p_path) {
int subpath_pos = path.find(":");
if (subpath_pos != -1) {
-
int from = subpath_pos + 1;
for (int i = from; i <= path.length(); i++) {
-
if (path[i] == ':' || path[i] == 0) {
-
String str = path.substr(from, i - from);
if (str == "") {
- if (path[i] == 0) continue; // Allow end-of-path :
+ if (path[i] == 0) {
+ continue; // Allow end-of-path :
+ }
ERR_FAIL_MSG("Invalid NodePath '" + p_path + "'.");
}
@@ -387,22 +378,21 @@ NodePath::NodePath(const String &p_path) {
}
for (int i = (int)absolute; i < path.length(); i++) {
-
if (path[i] == '/') {
-
last_is_slash = true;
has_slashes = true;
} else {
-
- if (last_is_slash)
+ if (last_is_slash) {
slices++;
+ }
last_is_slash = false;
}
}
- if (slices == 0 && !absolute && !subpath.size())
+ if (slices == 0 && !absolute && !subpath.size()) {
return;
+ }
data = memnew(Data);
data->refcount.init();
@@ -411,19 +401,17 @@ NodePath::NodePath(const String &p_path) {
data->subpath = subpath;
data->hash_cache_valid = false;
- if (slices == 0)
+ if (slices == 0) {
return;
+ }
data->path.resize(slices);
last_is_slash = true;
int from = (int)absolute;
int slice = 0;
for (int i = (int)absolute; i < path.length() + 1; i++) {
-
if (path[i] == '/' || path[i] == 0) {
-
if (!last_is_slash) {
-
String name = path.substr(from, i - from);
ERR_FAIL_INDEX(slice, data->path.size());
data->path.write[slice++] = name;
@@ -436,16 +424,6 @@ NodePath::NodePath(const String &p_path) {
}
}
-bool NodePath::is_empty() const {
-
- return !data;
-}
-NodePath::NodePath() {
-
- data = nullptr;
-}
-
NodePath::~NodePath() {
-
unref();
}
diff --git a/core/node_path.h b/core/node_path.h
index 76de36cd9f..7c06bf01ce 100644
--- a/core/node_path.h
+++ b/core/node_path.h
@@ -35,9 +35,7 @@
#include "core/ustring.h"
class NodePath {
-
struct Data {
-
SafeRefCount refcount;
Vector<StringName> path;
Vector<StringName> subpath;
@@ -48,7 +46,7 @@ class NodePath {
mutable uint32_t hash_cache;
};
- mutable Data *data;
+ mutable Data *data = nullptr;
void unref();
void _update_hash_cache() const;
@@ -71,8 +69,9 @@ public:
NodePath get_parent() const;
_FORCE_INLINE_ uint32_t hash() const {
- if (!data)
+ if (!data) {
return 0;
+ }
if (!data->hash_cache_valid) {
_update_hash_cache();
}
@@ -93,7 +92,7 @@ public:
NodePath(const Vector<StringName> &p_path, const Vector<StringName> &p_subpath, bool p_absolute);
NodePath(const NodePath &p_path);
NodePath(const String &p_path);
- NodePath();
+ NodePath() {}
~NodePath();
};
diff --git a/core/oa_hash_map.h b/core/oa_hash_map.h
index 71e3ba9068..c595e445d5 100644
--- a/core/oa_hash_map.h
+++ b/core/oa_hash_map.h
@@ -45,12 +45,14 @@
*
* The entries are stored inplace, so huge keys or values might fill cache lines
* a lot faster.
+ *
+ * Only used keys and values are constructed. For free positions there's space
+ * in the arrays for each, but that memory is kept uninitialized.
*/
template <class TKey, class TValue,
class Hasher = HashMapHasherDefault,
class Comparator = HashMapComparatorDefault<TKey>>
class OAHashMap {
-
private:
TValue *values;
TKey *keys;
@@ -58,7 +60,7 @@ private:
uint32_t capacity;
- uint32_t num_elements;
+ uint32_t num_elements = 0;
static const uint32_t EMPTY_HASH = 0;
@@ -90,7 +92,7 @@ private:
uint32_t pos = hash % capacity;
uint32_t distance = 0;
- while (42) {
+ while (true) {
if (hashes[pos] == EMPTY_HASH) {
return false;
}
@@ -110,7 +112,6 @@ private:
}
void _insert_with_hash(uint32_t p_hash, const TKey &p_key, const TValue &p_value) {
-
uint32_t hash = p_hash;
uint32_t distance = 0;
uint32_t pos = hash % capacity;
@@ -118,7 +119,7 @@ private:
TKey key = p_key;
TValue value = p_value;
- while (42) {
+ while (true) {
if (hashes[pos] == EMPTY_HASH) {
_construct(pos, hash, key, value);
@@ -140,7 +141,6 @@ private:
}
void _resize_and_rehash(uint32_t p_new_capacity) {
-
uint32_t old_capacity = capacity;
capacity = p_new_capacity;
@@ -149,9 +149,9 @@ private:
uint32_t *old_hashes = hashes;
num_elements = 0;
- keys = memnew_arr(TKey, capacity);
- values = memnew_arr(TValue, capacity);
- hashes = memnew_arr(uint32_t, capacity);
+ keys = static_cast<TKey *>(Memory::alloc_static(sizeof(TKey) * capacity));
+ values = static_cast<TValue *>(Memory::alloc_static(sizeof(TValue) * capacity));
+ hashes = static_cast<uint32_t *>(Memory::alloc_static(sizeof(uint32_t) * capacity));
for (uint32_t i = 0; i < capacity; i++) {
hashes[i] = 0;
@@ -163,11 +163,14 @@ private:
}
_insert_with_hash(old_hashes[i], old_keys[i], old_values[i]);
+
+ old_keys[i].~TKey();
+ old_values[i].~TValue();
}
- memdelete_arr(old_keys);
- memdelete_arr(old_values);
- memdelete_arr(old_hashes);
+ Memory::free_static(old_keys);
+ Memory::free_static(old_values);
+ Memory::free_static(old_hashes);
}
void _resize_and_rehash() {
@@ -183,9 +186,7 @@ public:
}
void clear() {
-
for (uint32_t i = 0; i < capacity; i++) {
-
if (hashes[i] == EMPTY_HASH) {
continue;
}
@@ -199,7 +200,6 @@ public:
}
void insert(const TKey &p_key, const TValue &p_value) {
-
if (num_elements + 1 > 0.9 * capacity) {
_resize_and_rehash();
}
@@ -214,8 +214,7 @@ public:
bool exists = _lookup_pos(p_key, pos);
if (exists) {
- values[pos].~TValue();
- memnew_placement(&values[pos], TValue(p_data));
+ values[pos] = p_data;
} else {
insert(p_key, p_data);
}
@@ -232,8 +231,7 @@ public:
bool exists = _lookup_pos(p_key, pos);
if (exists) {
- r_data.~TValue();
- memnew_placement(&r_data, TValue(values[pos]));
+ r_data = values[pos];
return true;
}
@@ -300,7 +298,7 @@ public:
bool valid;
const TKey *key;
- const TValue *value;
+ TValue *value;
private:
uint32_t pos;
@@ -317,7 +315,6 @@ public:
}
Iterator next_iter(const Iterator &p_iter) const {
-
if (!p_iter.valid) {
return p_iter;
}
@@ -348,13 +345,11 @@ public:
OAHashMap &operator=(const OAHashMap &) = delete; // Same for assignment operator.
OAHashMap(uint32_t p_initial_capacity = 64) {
-
capacity = p_initial_capacity;
- num_elements = 0;
- keys = memnew_arr(TKey, p_initial_capacity);
- values = memnew_arr(TValue, p_initial_capacity);
- hashes = memnew_arr(uint32_t, p_initial_capacity);
+ keys = static_cast<TKey *>(Memory::alloc_static(sizeof(TKey) * capacity));
+ values = static_cast<TValue *>(Memory::alloc_static(sizeof(TValue) * capacity));
+ hashes = static_cast<uint32_t *>(Memory::alloc_static(sizeof(uint32_t) * capacity));
for (uint32_t i = 0; i < p_initial_capacity; i++) {
hashes[i] = EMPTY_HASH;
@@ -362,10 +357,18 @@ public:
}
~OAHashMap() {
+ for (uint32_t i = 0; i < capacity; i++) {
+ if (hashes[i] == EMPTY_HASH) {
+ continue;
+ }
+
+ values[i].~TValue();
+ keys[i].~TKey();
+ }
- memdelete_arr(keys);
- memdelete_arr(values);
- memdelete_arr(hashes);
+ Memory::free_static(keys);
+ Memory::free_static(values);
+ Memory::free_static(hashes);
}
};
diff --git a/core/object.cpp b/core/object.cpp
index b0e6f2bdae..f3c5a13809 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -42,7 +42,6 @@
#ifdef DEBUG_ENABLED
struct _ObjectDebugLock {
-
Object *obj;
_ObjectDebugLock(Object *p_obj) {
@@ -63,7 +62,6 @@ struct _ObjectDebugLock {
#endif
PropertyInfo::operator Dictionary() const {
-
Dictionary d;
d["name"] = name;
d["class_name"] = class_name;
@@ -75,36 +73,38 @@ PropertyInfo::operator Dictionary() const {
}
PropertyInfo PropertyInfo::from_dict(const Dictionary &p_dict) {
-
PropertyInfo pi;
- if (p_dict.has("type"))
+ if (p_dict.has("type")) {
pi.type = Variant::Type(int(p_dict["type"]));
+ }
- if (p_dict.has("name"))
+ if (p_dict.has("name")) {
pi.name = p_dict["name"];
+ }
- if (p_dict.has("class_name"))
+ if (p_dict.has("class_name")) {
pi.class_name = p_dict["class_name"];
+ }
- if (p_dict.has("hint"))
+ if (p_dict.has("hint")) {
pi.hint = PropertyHint(int(p_dict["hint"]));
+ }
- if (p_dict.has("hint_string"))
-
+ if (p_dict.has("hint_string")) {
pi.hint_string = p_dict["hint_string"];
+ }
- if (p_dict.has("usage"))
+ if (p_dict.has("usage")) {
pi.usage = p_dict["usage"];
+ }
return pi;
}
Array convert_property_list(const List<PropertyInfo> *p_list) {
-
Array va;
for (const List<PropertyInfo>::Element *E = p_list->front(); E; E = E->next()) {
-
va.push_back(Dictionary(E->get()));
}
@@ -112,13 +112,13 @@ Array convert_property_list(const List<PropertyInfo> *p_list) {
}
MethodInfo::operator Dictionary() const {
-
Dictionary d;
d["name"] = name;
d["args"] = convert_property_list(&arguments);
Array da;
- for (int i = 0; i < default_arguments.size(); i++)
+ for (int i = 0; i < default_arguments.size(); i++) {
da.push_back(default_arguments[i]);
+ }
d["default_args"] = da;
d["flags"] = flags;
d["id"] = id;
@@ -127,17 +127,12 @@ MethodInfo::operator Dictionary() const {
return d;
}
-MethodInfo::MethodInfo() :
- flags(METHOD_FLAG_NORMAL),
- id(0) {
-}
-
MethodInfo MethodInfo::from_dict(const Dictionary &p_dict) {
-
MethodInfo mi;
- if (p_dict.has("name"))
+ if (p_dict.has("name")) {
mi.name = p_dict["name"];
+ }
Array args;
if (p_dict.has("args")) {
args = p_dict["args"];
@@ -159,35 +154,37 @@ MethodInfo MethodInfo::from_dict(const Dictionary &p_dict) {
mi.return_val = PropertyInfo::from_dict(p_dict["return"]);
}
- if (p_dict.has("flags"))
+ if (p_dict.has("flags")) {
mi.flags = p_dict["flags"];
+ }
return mi;
}
+MethodInfo::MethodInfo() :
+ flags(METHOD_FLAG_NORMAL) {}
+
MethodInfo::MethodInfo(const String &p_name) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
}
+
MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
arguments.push_back(p_param1);
}
+
MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
arguments.push_back(p_param1);
arguments.push_back(p_param2);
}
MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
arguments.push_back(p_param1);
arguments.push_back(p_param2);
arguments.push_back(p_param3);
@@ -195,8 +192,7 @@ MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1, const
MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
arguments.push_back(p_param1);
arguments.push_back(p_param2);
arguments.push_back(p_param3);
@@ -205,8 +201,7 @@ MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1, const
MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4, const PropertyInfo &p_param5) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
arguments.push_back(p_param1);
arguments.push_back(p_param2);
arguments.push_back(p_param3);
@@ -215,28 +210,26 @@ MethodInfo::MethodInfo(const String &p_name, const PropertyInfo &p_param1, const
}
MethodInfo::MethodInfo(Variant::Type ret) :
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
return_val.type = ret;
}
MethodInfo::MethodInfo(Variant::Type ret, const String &p_name) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
return_val.type = ret;
}
+
MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
return_val.type = ret;
arguments.push_back(p_param1);
}
+
MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
return_val.type = ret;
arguments.push_back(p_param1);
arguments.push_back(p_param2);
@@ -244,8 +237,7 @@ MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyIn
MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
return_val.type = ret;
arguments.push_back(p_param1);
arguments.push_back(p_param2);
@@ -254,8 +246,7 @@ MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyIn
MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
return_val.type = ret;
arguments.push_back(p_param1);
arguments.push_back(p_param2);
@@ -265,8 +256,7 @@ MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyIn
MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4, const PropertyInfo &p_param5) :
name(p_name),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
return_val.type = ret;
arguments.push_back(p_param1);
arguments.push_back(p_param2);
@@ -278,23 +268,20 @@ MethodInfo::MethodInfo(Variant::Type ret, const String &p_name, const PropertyIn
MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name) :
name(p_name),
return_val(p_ret),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
}
MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1) :
name(p_name),
return_val(p_ret),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
arguments.push_back(p_param1);
}
MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2) :
name(p_name),
return_val(p_ret),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
arguments.push_back(p_param1);
arguments.push_back(p_param2);
}
@@ -302,8 +289,7 @@ MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const Pr
MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3) :
name(p_name),
return_val(p_ret),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
arguments.push_back(p_param1);
arguments.push_back(p_param2);
arguments.push_back(p_param3);
@@ -312,8 +298,7 @@ MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const Pr
MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4) :
name(p_name),
return_val(p_ret),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
arguments.push_back(p_param1);
arguments.push_back(p_param2);
arguments.push_back(p_param3);
@@ -323,8 +308,7 @@ MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const Pr
MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4, const PropertyInfo &p_param5) :
name(p_name),
return_val(p_ret),
- flags(METHOD_FLAG_NORMAL),
- id(0) {
+ flags(METHOD_FLAG_NORMAL) {
arguments.push_back(p_param1);
arguments.push_back(p_param2);
arguments.push_back(p_param3);
@@ -333,7 +317,6 @@ MethodInfo::MethodInfo(const PropertyInfo &p_ret, const String &p_name, const Pr
}
Object::Connection::operator Variant() const {
-
Dictionary d;
d["signal"] = signal;
d["callable"] = callable;
@@ -343,28 +326,30 @@ Object::Connection::operator Variant() const {
}
bool Object::Connection::operator<(const Connection &p_conn) const {
-
if (signal == p_conn.signal) {
return callable < p_conn.callable;
} else {
return signal < p_conn.signal;
}
}
-Object::Connection::Connection(const Variant &p_variant) {
+Object::Connection::Connection(const Variant &p_variant) {
Dictionary d = p_variant;
- if (d.has("signal"))
+ if (d.has("signal")) {
signal = d["signal"];
- if (d.has("callable"))
+ }
+ if (d.has("callable")) {
callable = d["callable"];
- if (d.has("flags"))
+ }
+ if (d.has("flags")) {
flags = d["flags"];
- if (d.has("binds"))
+ }
+ if (d.has("binds")) {
binds = d["binds"];
+ }
}
bool Object::_predelete() {
-
_predelete_ok = 1;
notification(NOTIFICATION_PREDELETE, true);
if (_predelete_ok) {
@@ -381,21 +366,21 @@ void Object::_postinitialize() {
void Object::get_valid_parents_static(List<String> *p_parents) {
}
+
void Object::_get_valid_parents_static(List<String> *p_parents) {
}
void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid) {
-
#ifdef TOOLS_ENABLED
_edited = true;
#endif
if (script_instance) {
-
if (script_instance->set(p_name, p_value)) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return;
}
}
@@ -413,23 +398,26 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid
if (p_name == CoreStringNames::get_singleton()->_script) {
set_script(p_value);
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return;
} else if (p_name == CoreStringNames::get_singleton()->_meta) {
//set_meta(p_name,p_value);
metadata = p_value.duplicate();
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return;
}
//something inside the object... :|
bool success = _setv(p_name, p_value);
if (success) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return;
}
@@ -437,8 +425,9 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid
bool valid;
setvar(p_name, p_value, &valid);
if (valid) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return;
}
}
@@ -448,26 +437,27 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid
bool valid;
script_instance->property_set_fallback(p_name, p_value, &valid);
if (valid) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return;
}
}
#endif
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
}
Variant Object::get(const StringName &p_name, bool *r_valid) const {
-
Variant ret;
if (script_instance) {
-
if (script_instance->get(p_name, ret)) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return ret;
}
}
@@ -475,30 +465,34 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
//try built-in setgetter
{
if (ClassDB::get_property(const_cast<Object *>(this), p_name, ret)) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return ret;
}
}
if (p_name == CoreStringNames::get_singleton()->_script) {
ret = get_script();
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return ret;
} else if (p_name == CoreStringNames::get_singleton()->_meta) {
ret = metadata;
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return ret;
} else {
//something inside the object... :|
bool success = _getv(p_name, ret);
if (success) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return ret;
}
@@ -507,8 +501,9 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
bool valid;
ret = getvar(p_name, &valid);
if (valid) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return ret;
}
}
@@ -518,23 +513,26 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const {
bool valid;
ret = script_instance->property_get_fallback(p_name, &valid);
if (valid) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return ret;
}
}
#endif
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return Variant();
}
}
void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_value, bool *r_valid) {
if (p_names.empty()) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return;
}
if (p_names.size() == 1) {
@@ -543,7 +541,9 @@ void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_val
}
bool valid = false;
- if (!r_valid) r_valid = &valid;
+ if (!r_valid) {
+ r_valid = &valid;
+ }
List<Variant> value_stack;
@@ -566,7 +566,6 @@ void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_val
value_stack.push_back(p_value); // p_names[p_names.size() - 1]
for (int i = p_names.size() - 1; i > 0; i--) {
-
value_stack.back()->prev()->get().set_named(p_names[i], value_stack.back()->get(), r_valid);
value_stack.pop_back();
@@ -584,8 +583,9 @@ void Object::set_indexed(const Vector<StringName> &p_names, const Variant &p_val
Variant Object::get_indexed(const Vector<StringName> &p_names, bool *r_valid) const {
if (p_names.empty()) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return Variant();
}
bool valid = false;
@@ -594,17 +594,18 @@ Variant Object::get_indexed(const Vector<StringName> &p_names, bool *r_valid) co
for (int i = 1; i < p_names.size(); i++) {
current_value = current_value.get_named(p_names[i], &valid);
- if (!valid)
+ if (!valid) {
break;
+ }
}
- if (r_valid)
+ if (r_valid) {
*r_valid = valid;
+ }
return current_value;
}
void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) const {
-
if (script_instance && p_reversed) {
p_list->push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY));
script_instance->get_property_list(p_list);
@@ -631,7 +632,6 @@ void Object::_validate_property(PropertyInfo &property) const {
}
void Object::get_method_list(List<MethodInfo> *p_list) const {
-
ClassDB::get_method_list(get_class_name(), p_list);
if (script_instance) {
script_instance->get_method_list(p_list);
@@ -639,7 +639,6 @@ void Object::get_method_list(List<MethodInfo> *p_list) const {
}
Variant Object::_call_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (p_argcount < 1) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
@@ -659,7 +658,6 @@ Variant Object::_call_bind(const Variant **p_args, int p_argcount, Callable::Cal
}
Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (p_argcount < 1) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
@@ -684,24 +682,19 @@ Variant Object::_call_deferred_bind(const Variant **p_args, int p_argcount, Call
#ifdef DEBUG_ENABLED
static void _test_call_error(const StringName &p_func, const Callable::CallError &error) {
-
switch (error.error) {
-
case Callable::CallError::CALL_OK:
case Callable::CallError::CALL_ERROR_INVALID_METHOD:
break;
case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
-
ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Invalid type for argument " + itos(error.argument) + ", expected " + Variant::get_type_name(Variant::Type(error.expected)) + ".");
break;
}
case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
-
ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Too many arguments, expected " + itos(error.argument) + ".");
break;
}
case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
-
ERR_FAIL_MSG("Error calling function: " + String(p_func) + " - Too few arguments, expected " + itos(error.argument) + ".");
break;
}
@@ -716,7 +709,6 @@ static void _test_call_error(const StringName &p_func, const Callable::CallError
#endif
void Object::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) {
-
if (p_method == CoreStringNames::get_singleton()->_free) {
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_MSG(Object::cast_to<Reference>(this), "Can't 'free' a reference.");
@@ -742,21 +734,18 @@ void Object::call_multilevel(const StringName &p_method, const Variant **p_args,
MethodBind *method = ClassDB::get_method(get_class_name(), p_method);
if (method) {
-
method->call(this, p_args, p_argcount, error);
_test_call_error(p_method, error);
}
}
void Object::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) {
-
MethodBind *method = ClassDB::get_method(get_class_name(), p_method);
Callable::CallError error;
OBJ_DEBUG_LOCK
if (method) {
-
method->call(this, p_args, p_argcount, error);
_test_call_error(p_method, error);
}
@@ -770,7 +759,6 @@ void Object::call_multilevel_reversed(const StringName &p_method, const Variant
}
bool Object::has_method(const StringName &p_method) const {
-
if (p_method == CoreStringNames::get_singleton()->_free) {
return true;
}
@@ -785,15 +773,16 @@ bool Object::has_method(const StringName &p_method) const {
}
Variant Object::getvar(const Variant &p_key, bool *r_valid) const {
-
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return Variant();
}
-void Object::setvar(const Variant &p_key, const Variant &p_value, bool *r_valid) {
- if (r_valid)
+void Object::setvar(const Variant &p_key, const Variant &p_value, bool *r_valid) {
+ if (r_valid) {
*r_valid = false;
+ }
}
Variant Object::callv(const StringName &p_method, const Array &p_args) {
@@ -815,13 +804,13 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) {
}
Variant Object::call(const StringName &p_name, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS;
int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
argc++;
}
@@ -832,13 +821,13 @@ Variant Object::call(const StringName &p_name, VARIANT_ARG_DECLARE) {
}
void Object::call_multilevel(const StringName &p_name, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS;
int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
argc++;
}
@@ -847,7 +836,6 @@ void Object::call_multilevel(const StringName &p_name, VARIANT_ARG_DECLARE) {
}
Variant Object::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
r_error.error = Callable::CallError::CALL_OK;
if (p_method == CoreStringNames::get_singleton()->_free) {
@@ -883,7 +871,6 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a
ret = script_instance->call(p_method, p_args, p_argcount, r_error);
//force jumptable
switch (r_error.error) {
-
case Callable::CallError::CALL_OK:
return ret;
case Callable::CallError::CALL_ERROR_INVALID_METHOD:
@@ -909,7 +896,6 @@ Variant Object::call(const StringName &p_method, const Variant **p_args, int p_a
}
void Object::notification(int p_notification, bool p_reversed) {
-
_notificationv(p_notification, p_reversed);
if (script_instance) {
@@ -921,8 +907,9 @@ String Object::to_string() {
if (script_instance) {
bool valid;
String ret = script_instance->to_string(&valid);
- if (valid)
+ if (valid) {
return ret;
+ }
}
return "[" + get_class() + ":" + itos(get_instance_id()) + "]";
}
@@ -931,27 +918,22 @@ void Object::_changed_callback(Object *p_changed, const char *p_prop) {
}
void Object::add_change_receptor(Object *p_receptor) {
-
change_receptors.insert(p_receptor);
}
void Object::remove_change_receptor(Object *p_receptor) {
-
change_receptors.erase(p_receptor);
}
void Object::property_list_changed_notify() {
-
_change_notify();
}
void Object::cancel_delete() {
-
_predelete_ok = true;
}
void Object::set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance) {
-
//this function is not meant to be used in any of these ways
ERR_FAIL_COND(p_script.is_null());
ERR_FAIL_COND(!p_instance);
@@ -962,9 +944,9 @@ void Object::set_script_and_instance(const Variant &p_script, ScriptInstance *p_
}
void Object::set_script(const Variant &p_script) {
-
- if (script == p_script)
+ if (script == p_script) {
return;
+ }
if (script_instance) {
memdelete(script_instance);
@@ -989,43 +971,41 @@ void Object::set_script(const Variant &p_script) {
}
void Object::set_script_instance(ScriptInstance *p_instance) {
-
- if (script_instance == p_instance)
+ if (script_instance == p_instance) {
return;
+ }
- if (script_instance)
+ if (script_instance) {
memdelete(script_instance);
+ }
script_instance = p_instance;
- if (p_instance)
+ if (p_instance) {
script = p_instance->get_script();
- else
+ } else {
script = Variant();
+ }
}
Variant Object::get_script() const {
-
return script;
}
bool Object::has_meta(const String &p_name) const {
-
return metadata.has(p_name);
}
void Object::set_meta(const String &p_name, const Variant &p_value) {
-
if (p_value.get_type() == Variant::NIL) {
metadata.erase(p_name);
return;
- };
+ }
metadata[p_name] = p_value;
}
Variant Object::get_meta(const String &p_name) const {
-
ERR_FAIL_COND_V(!metadata.has(p_name), Variant());
return metadata[p_name];
}
@@ -1035,20 +1015,17 @@ void Object::remove_meta(const String &p_name) {
}
Array Object::_get_property_list_bind() const {
-
List<PropertyInfo> lpi;
get_property_list(&lpi);
return convert_property_list(&lpi);
}
Array Object::_get_method_list_bind() const {
-
List<MethodInfo> ml;
get_method_list(&ml);
Array ret;
for (List<MethodInfo>::Element *E = ml.front(); E; E = E->next()) {
-
Dictionary d = E->get();
//va.push_back(d);
ret.push_back(d);
@@ -1058,30 +1035,26 @@ Array Object::_get_method_list_bind() const {
}
Vector<String> Object::_get_meta_list_bind() const {
-
Vector<String> _metaret;
List<Variant> keys;
metadata.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
_metaret.push_back(E->get());
}
return _metaret;
}
-void Object::get_meta_list(List<String> *p_list) const {
+void Object::get_meta_list(List<String> *p_list) const {
List<Variant> keys;
metadata.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
p_list->push_back(E->get());
}
}
void Object::add_user_signal(const MethodInfo &p_signal) {
-
ERR_FAIL_COND_MSG(p_signal.name == "", "Signal name cannot be empty.");
ERR_FAIL_COND_MSG(ClassDB::has_signal(get_class_name(), p_signal.name), "User signal's name conflicts with a built-in signal of '" + get_class_name() + "'.");
ERR_FAIL_COND_MSG(signal_map.has(p_signal.name), "Trying to add already existing signal '" + p_signal.name + "'.");
@@ -1091,20 +1064,18 @@ void Object::add_user_signal(const MethodInfo &p_signal) {
}
bool Object::_has_user_signal(const StringName &p_name) const {
-
- if (!signal_map.has(p_name))
+ if (!signal_map.has(p_name)) {
return false;
+ }
return signal_map[p_name].user.name.length() > 0;
}
struct _ObjectSignalDisconnectData {
-
StringName signal;
Callable callable;
};
Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
ERR_FAIL_COND_V(p_argcount < 1, Variant());
@@ -1132,9 +1103,9 @@ Variant Object::_emit_signal(const Variant **p_args, int p_argcount, Callable::C
}
Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int p_argcount) {
-
- if (_block_signals)
+ if (_block_signals) {
return ERR_CANT_ACQUIRE_RESOURCE; //no emit, signals blocked
+ }
SignalData *s = signal_map.getptr(p_name);
if (!s) {
@@ -1163,7 +1134,6 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
Error err = OK;
for (int i = 0; i < ssize; i++) {
-
const Connection &c = slot_map.getv(i).conn;
Object *target = c.callable.get_object();
@@ -1201,8 +1171,9 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
if (ce.error != Callable::CallError::CALL_OK) {
#ifdef DEBUG_ENABLED
- if (c.flags & CONNECT_PERSIST && Engine::get_singleton()->is_editor_hint() && (script.is_null() || !Ref<Script>(script)->is_tool()))
+ if (c.flags & CONNECT_PERSIST && Engine::get_singleton()->is_editor_hint() && (script.is_null() || !Ref<Script>(script)->is_tool())) {
continue;
+ }
#endif
if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD && !ClassDB::class_exists(target->get_class_name())) {
//most likely object is not initialized yet, do not throw error.
@@ -1221,7 +1192,6 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
}
#endif
if (disconnect) {
-
_ObjectSignalDisconnectData dd;
dd.signal = p_name;
dd.callable = c.callable;
@@ -1230,7 +1200,6 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
}
while (!disconnect_data.empty()) {
-
const _ObjectSignalDisconnectData &dd = disconnect_data.front()->get();
_disconnect(dd.signal, dd.callable);
@@ -1241,15 +1210,14 @@ Error Object::emit_signal(const StringName &p_name, const Variant **p_args, int
}
Error Object::emit_signal(const StringName &p_name, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS;
int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
-
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
argc++;
}
@@ -1257,7 +1225,6 @@ Error Object::emit_signal(const StringName &p_name, VARIANT_ARG_DECLARE) {
}
void Object::_add_user_signal(const String &p_name, const Array &p_args) {
-
// this version of add_user_signal is meant to be used from scripts or external apis
// without access to ADD_SIGNAL in bind_methods
// added events are per instance, as opposed to the other ones, which are global
@@ -1266,14 +1233,15 @@ void Object::_add_user_signal(const String &p_name, const Array &p_args) {
mi.name = p_name;
for (int i = 0; i < p_args.size(); i++) {
-
Dictionary d = p_args[i];
PropertyInfo param;
- if (d.has("name"))
+ if (d.has("name")) {
param.name = d["name"];
- if (d.has("type"))
+ }
+ if (d.has("type")) {
param.type = (Variant::Type)(int)d["type"];
+ }
mi.arguments.push_back(param);
}
@@ -1282,13 +1250,11 @@ void Object::_add_user_signal(const String &p_name, const Array &p_args) {
}
Array Object::_get_signal_list() const {
-
List<MethodInfo> signal_list;
get_signal_list(&signal_list);
Array ret;
for (List<MethodInfo>::Element *E = signal_list.front(); E; E = E->next()) {
-
ret.push_back(Dictionary(E->get()));
}
@@ -1296,14 +1262,12 @@ Array Object::_get_signal_list() const {
}
Array Object::_get_signal_connection_list(const String &p_signal) const {
-
List<Connection> conns;
get_all_signal_connections(&conns);
Array ret;
for (List<Connection>::Element *E = conns.front(); E; E = E->next()) {
-
Connection &c = E->get();
if (c.signal.get_name() == p_signal) {
ret.push_back(c);
@@ -1314,7 +1278,6 @@ Array Object::_get_signal_connection_list(const String &p_signal) const {
}
Array Object::_get_incoming_connections() const {
-
Array ret;
int connections_amount = connections.size();
for (int idx_conn = 0; idx_conn < connections_amount; idx_conn++) {
@@ -1344,7 +1307,6 @@ bool Object::has_signal(const StringName &p_name) const {
}
void Object::get_signal_list(List<MethodInfo> *p_signals) const {
-
if (!script.is_null()) {
Ref<Script> scr = script;
if (scr.is_valid()) {
@@ -1357,7 +1319,6 @@ void Object::get_signal_list(List<MethodInfo> *p_signals) const {
const StringName *S = nullptr;
while ((S = signal_map.next(S))) {
-
if (signal_map[*S].user.name != "") {
//user signal
p_signals->push_back(signal_map[*S].user);
@@ -1366,37 +1327,33 @@ void Object::get_signal_list(List<MethodInfo> *p_signals) const {
}
void Object::get_all_signal_connections(List<Connection> *p_connections) const {
-
const StringName *S = nullptr;
while ((S = signal_map.next(S))) {
-
const SignalData *s = &signal_map[*S];
for (int i = 0; i < s->slot_map.size(); i++) {
-
p_connections->push_back(s->slot_map.getv(i).conn);
}
}
}
void Object::get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const {
-
const SignalData *s = signal_map.getptr(p_signal);
- if (!s)
+ if (!s) {
return; //nothing
+ }
- for (int i = 0; i < s->slot_map.size(); i++)
+ for (int i = 0; i < s->slot_map.size(); i++) {
p_connections->push_back(s->slot_map.getv(i).conn);
+ }
}
int Object::get_persistent_signal_connection_count() const {
-
int count = 0;
const StringName *S = nullptr;
while ((S = signal_map.next(S))) {
-
const SignalData *s = &signal_map[*S];
for (int i = 0; i < s->slot_map.size(); i++) {
@@ -1410,18 +1367,16 @@ int Object::get_persistent_signal_connection_count() const {
}
void Object::get_signals_connected_to_this(List<Connection> *p_connections) const {
-
for (const List<Connection>::Element *E = connections.front(); E; E = E->next()) {
p_connections->push_back(E->get());
}
}
Error Object::connect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method, const Vector<Variant> &p_binds, uint32_t p_flags) {
-
return connect(p_signal, Callable(p_to_object, p_to_method), p_binds, p_flags);
}
-Error Object::connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) {
+Error Object::connect(const StringName &p_signal, const Callable &p_callable, const Vector<Variant> &p_binds, uint32_t p_flags) {
ERR_FAIL_COND_V(p_callable.is_null(), ERR_INVALID_PARAMETER);
Object *target_object = p_callable.get_object();
@@ -1432,7 +1387,6 @@ Error Object::connect(const StringName &p_signal, const Callable &p_callable, co
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal);
//check in script
if (!signal_is_valid && !script.is_null()) {
-
if (Ref<Script>(script)->has_script_signal(p_signal)) {
signal_is_valid = true;
}
@@ -1482,21 +1436,21 @@ Error Object::connect(const StringName &p_signal, const Callable &p_callable, co
}
bool Object::is_connected_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) const {
-
return is_connected(p_signal, Callable(p_to_object, p_to_method));
}
bool Object::is_connected(const StringName &p_signal, const Callable &p_callable) const {
-
ERR_FAIL_COND_V(p_callable.is_null(), false);
const SignalData *s = signal_map.getptr(p_signal);
if (!s) {
bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal);
- if (signal_is_valid)
+ if (signal_is_valid) {
return false;
+ }
- if (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal))
+ if (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal)) {
return false;
+ }
ERR_FAIL_V_MSG(false, "Nonexistent signal: " + p_signal + ".");
}
@@ -1509,7 +1463,6 @@ bool Object::is_connected(const StringName &p_signal, const Callable &p_callable
}
void Object::disconnect_compat(const StringName &p_signal, Object *p_to_object, const StringName &p_to_method) {
-
_disconnect(p_signal, Callable(p_to_object, p_to_method));
}
@@ -1518,7 +1471,6 @@ void Object::disconnect(const StringName &p_signal, const Callable &p_callable)
}
void Object::_disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force) {
-
ERR_FAIL_COND(p_callable.is_null());
Object *target_object = p_callable.get_object();
@@ -1548,65 +1500,60 @@ void Object::_disconnect(const StringName &p_signal, const Callable &p_callable,
}
void Object::_set_bind(const String &p_set, const Variant &p_value) {
-
set(p_set, p_value);
}
Variant Object::_get_bind(const String &p_name) const {
-
return get(p_name);
}
void Object::_set_indexed_bind(const NodePath &p_name, const Variant &p_value) {
-
set_indexed(p_name.get_as_property_path().get_subnames(), p_value);
}
Variant Object::_get_indexed_bind(const NodePath &p_name) const {
-
return get_indexed(p_name.get_as_property_path().get_subnames());
}
void Object::initialize_class() {
-
static bool initialized = false;
- if (initialized)
+ if (initialized) {
return;
+ }
ClassDB::_add_class<Object>();
_bind_methods();
initialized = true;
}
StringName Object::tr(const StringName &p_message) const {
-
- if (!_can_translate || !TranslationServer::get_singleton())
+ if (!_can_translate || !TranslationServer::get_singleton()) {
return p_message;
+ }
return TranslationServer::get_singleton()->translate(p_message);
}
void Object::_clear_internal_resource_paths(const Variant &p_var) {
-
switch (p_var.get_type()) {
-
case Variant::OBJECT: {
-
RES r = p_var;
- if (!r.is_valid())
+ if (!r.is_valid()) {
return;
+ }
- if (!r->get_path().begins_with("res://") || r->get_path().find("::") == -1)
+ if (!r->get_path().begins_with("res://") || r->get_path().find("::") == -1) {
return; //not an internal resource
+ }
Object *object = p_var;
- if (!object)
+ if (!object) {
return;
+ }
r->set_path("");
r->clear_internal_resource_paths();
} break;
case Variant::ARRAY: {
-
Array a = p_var;
for (int i = 0; i < a.size(); i++) {
_clear_internal_resource_paths(a[i]);
@@ -1614,13 +1561,11 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) {
} break;
case Variant::DICTIONARY: {
-
Dictionary d = p_var;
List<Variant> keys;
d.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
_clear_internal_resource_paths(E->get());
_clear_internal_resource_paths(d[E->get()]);
}
@@ -1632,35 +1577,31 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) {
#ifdef TOOLS_ENABLED
void Object::editor_set_section_unfold(const String &p_section, bool p_unfolded) {
-
set_edited(true);
- if (p_unfolded)
+ if (p_unfolded) {
editor_section_folding.insert(p_section);
- else
+ } else {
editor_section_folding.erase(p_section);
+ }
}
bool Object::editor_is_section_unfolded(const String &p_section) {
-
return editor_section_folding.has(p_section);
}
#endif
void Object::clear_internal_resource_paths() {
-
List<PropertyInfo> pinfo;
get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
_clear_internal_resource_paths(get(E->get().name));
}
}
void Object::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_class"), &Object::get_class);
ClassDB::bind_method(D_METHOD("is_class", "class"), &Object::is_class);
ClassDB::bind_method(D_METHOD("set", "property", "value"), &Object::_set_bind);
@@ -1765,7 +1706,6 @@ void Object::_bind_methods() {
}
void Object::call_deferred(const StringName &p_method, VARIANT_ARG_DECLARE) {
-
MessageQueue::get_singleton()->push_call(this, p_method, VARIANT_ARG_PASS);
}
@@ -1774,58 +1714,57 @@ void Object::set_deferred(const StringName &p_property, const Variant &p_value)
}
void Object::set_block_signals(bool p_block) {
-
_block_signals = p_block;
}
bool Object::is_blocking_signals() const {
-
return _block_signals;
}
void Object::get_translatable_strings(List<String> *p_strings) const {
-
List<PropertyInfo> plist;
get_property_list(&plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_INTERNATIONALIZED))
+ if (!(E->get().usage & PROPERTY_USAGE_INTERNATIONALIZED)) {
continue;
+ }
String text = get(E->get().name);
- if (text == "")
+ if (text == "") {
continue;
+ }
p_strings->push_back(text);
}
}
Variant::Type Object::get_static_property_type(const StringName &p_property, bool *r_valid) const {
-
bool valid;
Variant::Type t = ClassDB::get_property_type(get_class_name(), p_property, &valid);
if (valid) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return t;
}
if (get_script_instance()) {
return get_script_instance()->get_property_type(p_property, r_valid);
}
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return Variant::NIL;
}
Variant::Type Object::get_static_property_type_indexed(const Vector<StringName> &p_path, bool *r_valid) const {
-
if (p_path.size() == 0) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return Variant::NIL;
}
@@ -1833,8 +1772,9 @@ Variant::Type Object::get_static_property_type_indexed(const Vector<StringName>
bool valid = false;
Variant::Type t = get_static_property_type(p_path[0], &valid);
if (!valid) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return Variant::NIL;
}
@@ -1845,22 +1785,25 @@ Variant::Type Object::get_static_property_type_indexed(const Vector<StringName>
for (int i = 1; i < p_path.size(); i++) {
if (check.get_type() == Variant::OBJECT || check.get_type() == Variant::DICTIONARY || check.get_type() == Variant::ARRAY) {
// We cannot be sure about the type of properties this types can have
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return Variant::NIL;
}
check = check.get_named(p_path[i], &valid);
if (!valid) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return Variant::NIL;
}
}
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return check.get_type();
}
@@ -1871,18 +1814,15 @@ bool Object::is_queued_for_deletion() const {
#ifdef TOOLS_ENABLED
void Object::set_edited(bool p_edited) {
-
_edited = p_edited;
_edited_version++;
}
bool Object::is_edited() const {
-
return _edited;
}
uint32_t Object::get_edited_version() const {
-
return _edited_version;
}
#endif
@@ -1909,7 +1849,6 @@ void *Object::get_script_instance_binding(int p_script_language_index) {
}
bool Object::has_script_instance_binding(int p_script_language_index) {
-
return _script_instance_bindings[p_script_language_index] != nullptr;
}
@@ -1922,39 +1861,26 @@ void Object::set_script_instance_binding(int p_script_language_index, void *p_da
void Object::_construct_object(bool p_reference) {
type_is_reference = p_reference;
- _class_ptr = nullptr;
- _block_signals = false;
- _predelete_ok = 0;
_instance_id = ObjectDB::add_instance(this);
- _can_translate = true;
- _is_queued_for_deletion = false;
- _emitting = false;
- instance_binding_count = 0;
memset(_script_instance_bindings, 0, sizeof(void *) * MAX_SCRIPT_INSTANCE_BINDINGS);
- script_instance = nullptr;
-#ifdef TOOLS_ENABLED
-
- _edited = false;
- _edited_version = 0;
-#endif
#ifdef DEBUG_ENABLED
_lock_index.init(1);
#endif
}
+
Object::Object(bool p_reference) {
_construct_object(p_reference);
}
Object::Object() {
-
_construct_object(false);
}
Object::~Object() {
-
- if (script_instance)
+ if (script_instance) {
memdelete(script_instance);
+ }
script_instance = nullptr;
const StringName *S = nullptr;
@@ -1965,7 +1891,6 @@ Object::~Object() {
}
while ((S = signal_map.next(nullptr))) {
-
SignalData *s = &signal_map[*S];
//brute force disconnect for performance
@@ -1973,7 +1898,6 @@ Object::~Object() {
const VMap<Callable, SignalData::Slot>::Pair *slot_list = s->slot_map.get_array();
for (int i = 0; i < slot_count; i++) {
-
slot_list[i].value.conn.callable.get_object()->connections.erase(slot_list[i].value.cE);
}
@@ -1982,7 +1906,6 @@ Object::~Object() {
//signals from nodes that connect to this node
while (connections.size()) {
-
Connection c = connections.front()->get();
c.signal.get_object()->_disconnect(c.signal.get_name(), c.callable, true);
}
@@ -2001,17 +1924,14 @@ Object::~Object() {
}
bool predelete_handler(Object *p_object) {
-
return p_object->_predelete();
}
void postinitialize_handler(Object *p_object) {
-
p_object->_postinitialize();
}
void ObjectDB::debug_objects(DebugFunc p_func) {
-
spin_lock.lock();
for (uint32_t i = 0; i < slot_count; i++) {
uint32_t slot = object_slots[i].next_free;
@@ -2030,15 +1950,12 @@ ObjectDB::ObjectSlot *ObjectDB::object_slots = nullptr;
uint64_t ObjectDB::validator_counter = 0;
int ObjectDB::get_object_count() {
-
return slot_count;
}
ObjectID ObjectDB::add_instance(Object *p_object) {
-
spin_lock.lock();
if (unlikely(slot_count == slot_max)) {
-
CRASH_COND(slot_count == (1 << OBJECTDB_SLOT_MAX_COUNT_BITS));
uint32_t new_slot_max = slot_max > 0 ? slot_max * 2 : 1;
@@ -2114,12 +2031,10 @@ void ObjectDB::remove_instance(Object *p_object) {
}
void ObjectDB::setup() {
-
//nothing to do now
}
void ObjectDB::cleanup() {
-
if (slot_count > 0) {
spin_lock.lock();
@@ -2130,10 +2045,12 @@ void ObjectDB::cleanup() {
Object *obj = object_slots[slot].object;
String node_name;
- if (obj->is_class("Node"))
+ if (obj->is_class("Node")) {
node_name = " - Node name: " + String(obj->call("get_name"));
- if (obj->is_class("Resource"))
+ }
+ if (obj->is_class("Resource")) {
node_name = " - Resource name: " + String(obj->call("get_name")) + " Path: " + String(obj->call("get_path"));
+ }
uint64_t id = uint64_t(slot) | (uint64_t(object_slots[slot].validator) << OBJECTDB_VALIDATOR_BITS) | (object_slots[slot].is_reference ? OBJECTDB_REFERENCE_BIT : 0);
print_line("Leaked instance: " + String(obj->get_class()) + ":" + itos(id) + node_name);
diff --git a/core/object.h b/core/object.h
index 1eaab5034e..95662f6208 100644
--- a/core/object.h
+++ b/core/object.h
@@ -91,6 +91,7 @@ enum PropertyHint {
PROPERTY_HINT_NODE_PATH_VALID_TYPES,
PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
PROPERTY_HINT_INT_IS_OBJECTID,
+ PROPERTY_HINT_ARRAY_TYPE,
PROPERTY_HINT_MAX,
// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit
};
@@ -137,13 +138,12 @@ enum PropertyUsageFlags {
#define ADD_SUBGROUP(m_name, m_prefix) ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix)
struct PropertyInfo {
-
- Variant::Type type;
+ Variant::Type type = Variant::NIL;
String name;
StringName class_name; //for classes
- PropertyHint hint;
+ PropertyHint hint = PROPERTY_HINT_NONE;
String hint_string;
- uint32_t usage;
+ uint32_t usage = PROPERTY_USAGE_DEFAULT;
_FORCE_INLINE_ PropertyInfo added_usage(int p_fl) const {
PropertyInfo pi = *this;
@@ -155,11 +155,7 @@ struct PropertyInfo {
static PropertyInfo from_dict(const Dictionary &p_dict);
- PropertyInfo() :
- type(Variant::NIL),
- hint(PROPERTY_HINT_NONE),
- usage(PROPERTY_USAGE_DEFAULT) {
- }
+ PropertyInfo() {}
PropertyInfo(Variant::Type p_type, const String p_name, PropertyHint p_hint = PROPERTY_HINT_NONE, const String &p_hint_string = "", uint32_t p_usage = PROPERTY_USAGE_DEFAULT, const StringName &p_class_name = StringName()) :
type(p_type),
@@ -167,7 +163,6 @@ struct PropertyInfo {
hint(p_hint),
hint_string(p_hint_string),
usage(p_usage) {
-
if (hint == PROPERTY_HINT_RESOURCE_TYPE) {
class_name = hint_string;
} else {
@@ -177,10 +172,7 @@ struct PropertyInfo {
PropertyInfo(const StringName &p_class_name) :
type(Variant::OBJECT),
- class_name(p_class_name),
- hint(PROPERTY_HINT_NONE),
- usage(PROPERTY_USAGE_DEFAULT) {
- }
+ class_name(p_class_name) {}
bool operator==(const PropertyInfo &p_info) const {
return ((type == p_info.type) &&
@@ -199,11 +191,10 @@ struct PropertyInfo {
Array convert_property_list(const List<PropertyInfo> *p_list);
struct MethodInfo {
-
String name;
PropertyInfo return_val;
- uint32_t flags;
- int id;
+ uint32_t flags; // NOLINT - prevent clang-tidy to assign method_bind.h constant here, it should stay in .cpp.
+ int id = 0;
List<PropertyInfo> arguments;
Vector<Variant> default_arguments;
@@ -213,6 +204,7 @@ struct MethodInfo {
operator Dictionary() const;
static MethodInfo from_dict(const Dictionary &p_dict);
+
MethodInfo();
MethodInfo(const String &p_name);
MethodInfo(const String &p_name, const PropertyInfo &p_param1);
@@ -268,8 +260,9 @@ public:
return String(#m_class); \
} \
virtual const StringName *_get_class_namev() const { \
- if (!_class_name) \
+ if (!_class_name) { \
_class_name = get_class_static(); \
+ } \
return &_class_name; \
} \
static _FORCE_INLINE_ void *get_class_ptr_static() { \
@@ -289,8 +282,9 @@ public:
static String get_category_static() { \
String category = m_inherits::get_category_static(); \
if (_get_category != m_inherits::_get_category) { \
- if (category != "") \
+ if (category != "") { \
category += "/"; \
+ } \
category += _get_category(); \
} \
return category; \
@@ -302,7 +296,6 @@ public:
virtual bool is_class_ptr(void *p_ptr) const { return (p_ptr == get_class_ptr_static()) ? true : m_inherits::is_class_ptr(p_ptr); } \
\
static void get_valid_parents_static(List<String> *p_parents) { \
- \
if (m_class::_get_valid_parents_static != m_inherits::_get_valid_parents_static) { \
m_class::_get_valid_parents_static(p_parents); \
} \
@@ -318,12 +311,14 @@ protected:
public: \
static void initialize_class() { \
static bool initialized = false; \
- if (initialized) \
+ if (initialized) { \
return; \
+ } \
m_inherits::initialize_class(); \
ClassDB::_add_class<m_class>(); \
- if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) \
+ if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \
_bind_methods(); \
+ } \
initialized = true; \
} \
\
@@ -336,8 +331,9 @@ protected:
} \
virtual bool _getv(const StringName &p_name, Variant &r_ret) const { \
if (m_class::_get_get() != m_inherits::_get_get()) { \
- if (_get(p_name, r_ret)) \
+ if (_get(p_name, r_ret)) { \
return true; \
+ } \
} \
return m_inherits::_getv(p_name, r_ret); \
} \
@@ -345,7 +341,9 @@ protected:
return (bool (Object::*)(const StringName &, const Variant &)) & m_class::_set; \
} \
virtual bool _setv(const StringName &p_name, const Variant &p_property) { \
- if (m_inherits::_setv(p_name, p_property)) return true; \
+ if (m_inherits::_setv(p_name, p_property)) { \
+ return true; \
+ } \
if (m_class::_get_set() != m_inherits::_get_set()) { \
return _set(p_name, p_property); \
} \
@@ -359,13 +357,15 @@ protected:
m_inherits::_get_property_listv(p_list, p_reversed); \
} \
p_list->push_back(PropertyInfo(Variant::NIL, get_class_static(), PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); \
- if (!_is_gpl_reversed()) \
+ if (!_is_gpl_reversed()) { \
ClassDB::get_property_list(#m_class, p_list, true, this); \
+ } \
if (m_class::_get_get_property_list() != m_inherits::_get_get_property_list()) { \
_get_property_list(p_list); \
} \
- if (_is_gpl_reversed()) \
+ if (_is_gpl_reversed()) { \
ClassDB::get_property_list(#m_class, p_list, true, this); \
+ } \
if (p_reversed) { \
m_inherits::_get_property_listv(p_list, p_reversed); \
} \
@@ -374,13 +374,15 @@ protected:
return (void (Object::*)(int)) & m_class::_notification; \
} \
virtual void _notificationv(int p_notification, bool p_reversed) { \
- if (!p_reversed) \
+ if (!p_reversed) { \
m_inherits::_notificationv(p_notification, p_reversed); \
+ } \
if (m_class::_get_notification() != m_inherits::_get_notification()) { \
_notification(p_notification); \
} \
- if (p_reversed) \
+ if (p_reversed) { \
m_inherits::_notificationv(p_notification, p_reversed); \
+ } \
} \
\
private:
@@ -410,18 +412,16 @@ public:
};
struct Connection {
-
::Signal signal;
Callable callable;
- uint32_t flags;
+ uint32_t flags = 0;
Vector<Variant> binds;
bool operator<(const Connection &p_conn) const;
operator Variant() const;
- Connection() {
- flags = 0;
- }
+
+ Connection() {}
Connection(const Variant &p_variant);
};
@@ -437,18 +437,14 @@ private:
friend void postinitialize_handler(Object *);
struct SignalData {
-
struct Slot {
-
- int reference_count;
+ int reference_count = 0;
Connection conn;
- List<Connection>::Element *cE;
- Slot() { reference_count = 0; }
+ List<Connection>::Element *cE = nullptr;
};
MethodInfo user;
VMap<Callable, Slot> slot_map;
- SignalData() {}
};
HashMap<StringName, SignalData> signal_map;
@@ -456,24 +452,24 @@ private:
#ifdef DEBUG_ENABLED
SafeRefCount _lock_index;
#endif
- bool _block_signals;
- int _predelete_ok;
+ bool _block_signals = false;
+ int _predelete_ok = 0;
Set<Object *> change_receptors;
ObjectID _instance_id;
bool _predelete();
void _postinitialize();
- bool _can_translate;
- bool _emitting;
+ bool _can_translate = true;
+ bool _emitting = false;
#ifdef TOOLS_ENABLED
- bool _edited;
- uint32_t _edited_version;
+ bool _edited = false;
+ uint32_t _edited_version = 0;
Set<String> editor_section_folding;
#endif
- ScriptInstance *script_instance;
+ ScriptInstance *script_instance = nullptr;
Variant script; //reference does not yet exist, store it in a
Dictionary metadata;
mutable StringName _class_name;
- mutable const StringName *_class_ptr;
+ mutable const StringName *_class_ptr = nullptr;
void _add_user_signal(const String &p_name, const Array &p_args = Array());
bool _has_user_signal(const StringName &p_name) const;
@@ -492,8 +488,9 @@ private:
friend class Reference;
bool type_is_reference = false;
- uint32_t instance_binding_count;
+ uint32_t instance_binding_count = 0;
void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS];
+
Object(bool p_reference);
protected:
@@ -501,14 +498,14 @@ protected:
virtual bool _setv(const StringName &p_name, const Variant &p_property) { return false; };
virtual bool _getv(const StringName &p_name, Variant &r_property) const { return false; };
virtual void _get_property_listv(List<PropertyInfo> *p_list, bool p_reversed) const {};
- virtual void _notificationv(int p_notification, bool p_reversed){};
+ virtual void _notificationv(int p_notification, bool p_reversed) {}
static String _get_category() { return ""; }
static void _bind_methods();
bool _set(const StringName &p_name, const Variant &p_property) { return false; };
bool _get(const StringName &p_name, Variant &r_property) const { return false; };
void _get_property_list(List<PropertyInfo> *p_list) const {};
- void _notification(int p_notification){};
+ void _notification(int p_notification) {}
_FORCE_INLINE_ static void (*_get_bind_methods())() {
return &Object::_bind_methods;
@@ -539,8 +536,9 @@ protected:
Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
virtual const StringName *_get_class_namev() const {
- if (!_class_name)
+ if (!_class_name) {
_class_name = get_class_static();
+ }
return &_class_name;
}
@@ -557,14 +555,15 @@ protected:
public: //should be protected, but bug in clang++
static void initialize_class();
- _FORCE_INLINE_ static void register_custom_data_to_otdb(){};
+ _FORCE_INLINE_ static void register_custom_data_to_otdb() {}
public:
#ifdef TOOLS_ENABLED
_FORCE_INLINE_ void _change_notify(const char *p_property = "") {
_edited = true;
- for (Set<Object *>::Element *E = change_receptors.front(); E; E = E->next())
+ for (Set<Object *>::Element *E = change_receptors.front(); E; E = E->next()) {
((Object *)(E->get()))->_changed_callback(this, p_property);
+ }
}
#else
_FORCE_INLINE_ void _change_notify(const char *p_what = "") {}
@@ -577,8 +576,8 @@ public:
bool _is_gpl_reversed() const { return false; }
_FORCE_INLINE_ ObjectID get_instance_id() const { return _instance_id; }
- // this is used for editors
+ // this is used for editors
void add_change_receptor(Object *p_receptor);
void remove_change_receptor(Object *p_receptor);
@@ -587,12 +586,14 @@ public:
#ifndef NO_SAFE_CAST
return dynamic_cast<T *>(p_object);
#else
- if (!p_object)
+ if (!p_object) {
return nullptr;
- if (p_object->is_class_ptr(T::get_class_ptr_static()))
+ }
+ if (p_object->is_class_ptr(T::get_class_ptr_static())) {
return static_cast<T *>(p_object);
- else
+ } else {
return nullptr;
+ }
#endif
}
@@ -601,17 +602,18 @@ public:
#ifndef NO_SAFE_CAST
return dynamic_cast<const T *>(p_object);
#else
- if (!p_object)
+ if (!p_object) {
return nullptr;
- if (p_object->is_class_ptr(T::get_class_ptr_static()))
+ }
+ if (p_object->is_class_ptr(T::get_class_ptr_static())) {
return static_cast<const T *>(p_object);
- else
+ } else {
return nullptr;
+ }
#endif
}
enum {
-
NOTIFICATION_POSTINITIALIZE = 0,
NOTIFICATION_PREDELETE = 1
};
@@ -721,7 +723,7 @@ public:
StringName tr(const StringName &p_message) const; // translate message (internationalization)
- bool _is_queued_for_deletion; // set to true by SceneTree::queue_delete()
+ bool _is_queued_for_deletion = false; // set to true by SceneTree::queue_delete()
bool is_queued_for_deletion() const;
_FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate = p_enable; }
@@ -743,6 +745,7 @@ public:
void clear_internal_resource_paths();
_ALWAYS_INLINE_ bool is_reference() const { return type_is_reference; }
+
Object();
virtual ~Object();
};
@@ -751,7 +754,6 @@ bool predelete_handler(Object *p_object);
void postinitialize_handler(Object *p_object);
class ObjectDB {
-
//this needs to add up to 63, 1 bit is for reference
#define OBJECTDB_VALIDATOR_BITS 39
#define OBJECTDB_VALIDATOR_MASK ((uint64_t(1) << OBJECTDB_VALIDATOR_BITS) - 1)
@@ -786,7 +788,6 @@ public:
typedef void (*DebugFunc)(Object *p_obj);
_ALWAYS_INLINE_ static Object *get_instance(ObjectID p_instance_id) {
-
uint64_t id = p_instance_id;
uint32_t slot = id & OBJECTDB_SLOT_MAX_COUNT_MASK;
diff --git a/core/ordered_hash_map.h b/core/ordered_hash_map.h
index 05debd529f..e6a6340a2f 100644
--- a/core/ordered_hash_map.h
+++ b/core/ordered_hash_map.h
@@ -55,9 +55,9 @@ public:
class Element {
friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>;
- typename InternalList::Element *list_element;
- typename InternalList::Element *prev_element;
- typename InternalList::Element *next_element;
+ typename InternalList::Element *list_element = nullptr;
+ typename InternalList::Element *prev_element = nullptr;
+ typename InternalList::Element *next_element = nullptr;
Element(typename InternalList::Element *p_element) {
list_element = p_element;
@@ -69,11 +69,7 @@ public:
}
public:
- _FORCE_INLINE_ Element() :
- list_element(nullptr),
- prev_element(nullptr),
- next_element(nullptr) {
- }
+ _FORCE_INLINE_ Element() {}
Element next() const {
return Element(next_element);
@@ -110,42 +106,40 @@ public:
const K &key() const {
CRASH_COND(!list_element);
return *(list_element->get().first);
- };
+ }
V &value() {
CRASH_COND(!list_element);
return list_element->get().second;
- };
+ }
const V &value() const {
CRASH_COND(!list_element);
return list_element->get().second;
- };
+ }
V &get() {
CRASH_COND(!list_element);
return list_element->get().second;
- };
+ }
const V &get() const {
CRASH_COND(!list_element);
return list_element->get().second;
- };
+ }
};
class ConstElement {
friend class OrderedHashMap<K, V, Hasher, Comparator, MIN_HASH_TABLE_POWER, RELATIONSHIP>;
- const typename InternalList::Element *list_element;
+ const typename InternalList::Element *list_element = nullptr;
ConstElement(const typename InternalList::Element *p_element) :
list_element(p_element) {
}
public:
- _FORCE_INLINE_ ConstElement() :
- list_element(nullptr) {
- }
+ _FORCE_INLINE_ ConstElement() {}
ConstElement(const ConstElement &other) :
list_element(other.list_element) {
@@ -178,17 +172,17 @@ public:
const K &key() const {
CRASH_COND(!list_element);
return *(list_element->get().first);
- };
+ }
const V &value() const {
CRASH_COND(!list_element);
return list_element->get().second;
- };
+ }
const V &get() const {
CRASH_COND(!list_element);
return list_element->get().second;
- };
+ }
};
ConstElement find(const K &p_key) const {
@@ -299,8 +293,7 @@ public:
_copy_from(p_map);
}
- _FORCE_INLINE_ OrderedHashMap() {
- }
+ _FORCE_INLINE_ OrderedHashMap() {}
};
#endif // ORDERED_HASH_MAP_H
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index 94c8cd5d73..5e1cb8ea29 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -36,56 +36,56 @@
#include "core/project_settings.h"
String DirAccess::_get_root_path() const {
-
switch (_access_type) {
-
- case ACCESS_RESOURCES: return ProjectSettings::get_singleton()->get_resource_path();
- case ACCESS_USERDATA: return OS::get_singleton()->get_user_data_dir();
- default: return "";
+ case ACCESS_RESOURCES:
+ return ProjectSettings::get_singleton()->get_resource_path();
+ case ACCESS_USERDATA:
+ return OS::get_singleton()->get_user_data_dir();
+ default:
+ return "";
}
}
-String DirAccess::_get_root_string() const {
+String DirAccess::_get_root_string() const {
switch (_access_type) {
-
- case ACCESS_RESOURCES: return "res://";
- case ACCESS_USERDATA: return "user://";
- default: return "";
+ case ACCESS_RESOURCES:
+ return "res://";
+ case ACCESS_USERDATA:
+ return "user://";
+ default:
+ return "";
}
}
int DirAccess::get_current_drive() {
-
String path = get_current_dir().to_lower();
for (int i = 0; i < get_drive_count(); i++) {
String d = get_drive(i).to_lower();
- if (path.begins_with(d))
+ if (path.begins_with(d)) {
return i;
+ }
}
return 0;
}
bool DirAccess::drives_are_shortcuts() {
-
return false;
}
static Error _erase_recursive(DirAccess *da) {
-
List<String> dirs;
List<String> files;
da->list_dir_begin();
String n = da->get_next();
while (n != String()) {
-
if (n != "." && n != "..") {
-
- if (da->current_is_dir())
+ if (da->current_is_dir()) {
dirs.push_back(n);
- else
+ } else {
files.push_back(n);
+ }
}
n = da->get_next();
@@ -94,10 +94,8 @@ static Error _erase_recursive(DirAccess *da) {
da->list_dir_end();
for (List<String>::Element *E = dirs.front(); E; E = E->next()) {
-
Error err = da->change_dir(E->get());
if (err == OK) {
-
err = _erase_recursive(da);
if (err) {
da->change_dir("..");
@@ -117,7 +115,6 @@ static Error _erase_recursive(DirAccess *da) {
}
for (List<String>::Element *E = files.front(); E; E = E->next()) {
-
Error err = da->remove(da->get_current_dir().plus_file(E->get()));
if (err) {
return err;
@@ -128,15 +125,13 @@ static Error _erase_recursive(DirAccess *da) {
}
Error DirAccess::erase_contents_recursive() {
-
return _erase_recursive(this);
}
Error DirAccess::make_dir_recursive(String p_dir) {
-
if (p_dir.length() < 1) {
return OK;
- };
+ }
String full_dir;
@@ -154,13 +149,13 @@ Error DirAccess::make_dir_recursive(String p_dir) {
String base;
- if (full_dir.begins_with("res://"))
+ if (full_dir.begins_with("res://")) {
base = "res://";
- else if (full_dir.begins_with("user://"))
+ } else if (full_dir.begins_with("user://")) {
base = "user://";
- else if (full_dir.begins_with("/"))
+ } else if (full_dir.begins_with("/")) {
base = "/";
- else if (full_dir.find(":/") != -1) {
+ } else if (full_dir.find(":/") != -1) {
base = full_dir.substr(0, full_dir.find(":/") + 2);
} else {
ERR_FAIL_V(ERR_INVALID_PARAMETER);
@@ -172,11 +167,9 @@ Error DirAccess::make_dir_recursive(String p_dir) {
String curpath = base;
for (int i = 0; i < subdirs.size(); i++) {
-
curpath = curpath.plus_file(subdirs[i]);
Error err = make_dir(curpath);
if (err != OK && err != ERR_ALREADY_EXISTS) {
-
ERR_FAIL_V(err);
}
}
@@ -185,42 +178,34 @@ Error DirAccess::make_dir_recursive(String p_dir) {
}
String DirAccess::fix_path(String p_path) const {
-
switch (_access_type) {
-
case ACCESS_RESOURCES: {
-
if (ProjectSettings::get_singleton()) {
if (p_path.begins_with("res://")) {
-
String resource_path = ProjectSettings::get_singleton()->get_resource_path();
if (resource_path != "") {
-
return p_path.replace_first("res:/", resource_path);
- };
+ }
return p_path.replace_first("res://", "");
}
}
} break;
case ACCESS_USERDATA: {
-
if (p_path.begins_with("user://")) {
-
String data_dir = OS::get_singleton()->get_user_data_dir();
if (data_dir != "") {
-
return p_path.replace_first("user:/", data_dir);
- };
+ }
return p_path.replace_first("user://", "");
}
} break;
case ACCESS_FILESYSTEM: {
-
return p_path;
} break;
- case ACCESS_MAX: break; // Can't happen, but silences warning
+ case ACCESS_MAX:
+ break; // Can't happen, but silences warning
}
return p_path;
@@ -229,16 +214,12 @@ String DirAccess::fix_path(String p_path) const {
DirAccess::CreateFunc DirAccess::create_func[ACCESS_MAX] = { nullptr, nullptr, nullptr };
DirAccess *DirAccess::create_for_path(const String &p_path) {
-
DirAccess *da = nullptr;
if (p_path.begins_with("res://")) {
-
da = create(ACCESS_RESOURCES);
} else if (p_path.begins_with("user://")) {
-
da = create(ACCESS_USERDATA);
} else {
-
da = create(ACCESS_FILESYSTEM);
}
@@ -246,13 +227,13 @@ DirAccess *DirAccess::create_for_path(const String &p_path) {
}
DirAccess *DirAccess::open(const String &p_path, Error *r_error) {
-
DirAccess *da = create_for_path(p_path);
ERR_FAIL_COND_V_MSG(!da, nullptr, "Cannot create DirAccess for path '" + p_path + "'.");
Error err = da->change_dir(p_path);
- if (r_error)
+ if (r_error) {
*r_error = err;
+ }
if (err != OK) {
memdelete(da);
return nullptr;
@@ -262,20 +243,19 @@ DirAccess *DirAccess::open(const String &p_path, Error *r_error) {
}
DirAccess *DirAccess::create(AccessType p_access) {
-
DirAccess *da = create_func[p_access] ? create_func[p_access]() : nullptr;
if (da) {
da->_access_type = p_access;
}
return da;
-};
+}
String DirAccess::get_full_path(const String &p_path, AccessType p_access) {
-
DirAccess *d = DirAccess::create(p_access);
- if (!d)
+ if (!d) {
return p_path;
+ }
d->change_dir(p_path);
String full = d->get_current_dir();
@@ -284,7 +264,6 @@ String DirAccess::get_full_path(const String &p_path, AccessType p_access) {
}
Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) {
-
//printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data());
Error err;
FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ, &err);
@@ -296,7 +275,6 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) {
FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE, &err);
if (err) {
-
fsrc->close();
memdelete(fsrc);
ERR_PRINT("Failed to open " + p_to);
@@ -308,7 +286,6 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) {
fsrc->seek(0);
err = OK;
while (size--) {
-
if (fsrc->get_error() != OK) {
err = fsrc->get_error();
break;
@@ -325,8 +302,9 @@ Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) {
fdst->close();
err = FileAccess::set_unix_permissions(p_to, p_chmod_flags);
// If running on a platform with no chmod support (i.e., Windows), don't fail
- if (err == ERR_UNAVAILABLE)
+ if (err == ERR_UNAVAILABLE) {
err = OK;
+ }
}
memdelete(fsrc);
@@ -360,12 +338,10 @@ Error DirAccess::_copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flag
list_dir_begin();
String n = get_next();
while (n != String()) {
-
if (n != "." && n != "..") {
-
- if (current_is_dir())
+ if (current_is_dir()) {
dirs.push_back(n);
- else {
+ } else {
const String &rel_path = n;
if (!n.is_rel_path()) {
list_dir_end();
@@ -433,17 +409,8 @@ Error DirAccess::copy_dir(String p_from, String p_to, int p_chmod_flags) {
}
bool DirAccess::exists(String p_dir) {
-
DirAccess *da = DirAccess::create_for_path(p_dir);
bool valid = da->change_dir(p_dir) == OK;
memdelete(da);
return valid;
}
-
-DirAccess::DirAccess() {
-
- _access_type = ACCESS_FILESYSTEM;
-}
-
-DirAccess::~DirAccess() {
-}
diff --git a/core/os/dir_access.h b/core/os/dir_access.h
index 60eb553968..6bce9a4c12 100644
--- a/core/os/dir_access.h
+++ b/core/os/dir_access.h
@@ -47,7 +47,7 @@ public:
typedef DirAccess *(*CreateFunc)();
private:
- AccessType _access_type;
+ AccessType _access_type = ACCESS_FILESYSTEM;
static CreateFunc create_func[ACCESS_MAX]; ///< set this to instance a filesystem object
Error _copy_dir(DirAccess *p_target_da, String p_to, int p_chmod_flags);
@@ -61,7 +61,6 @@ protected:
template <class T>
static DirAccess *_create_builtin() {
-
return memnew(T);
}
@@ -110,42 +109,33 @@ public:
static String get_full_path(const String &p_path, AccessType p_access);
static DirAccess *create_for_path(const String &p_path);
- /*
- enum DirType {
-
- FILE_TYPE_INVALID,
- FILE_TYPE_FILE,
- FILE_TYPE_DIR,
- };
-
- //virtual DirType get_file_type() const=0;
-*/
static DirAccess *create(AccessType p_access);
template <class T>
static void make_default(AccessType p_access) {
-
create_func[p_access] = _create_builtin<T>;
}
static DirAccess *open(const String &p_path, Error *r_error = nullptr);
- DirAccess();
- virtual ~DirAccess();
+ DirAccess() {}
+ virtual ~DirAccess() {}
};
struct DirAccessRef {
-
_FORCE_INLINE_ DirAccess *operator->() {
-
return f;
}
operator bool() const { return f != nullptr; }
+
DirAccess *f;
+
DirAccessRef(DirAccess *fa) { f = fa; }
~DirAccessRef() {
- if (f) memdelete(f);
+ if (f) {
+ memdelete(f);
+ }
}
};
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 3922f031b7..20b3435911 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -43,7 +43,6 @@ FileAccess::FileCloseFailNotify FileAccess::close_fail_notify = nullptr;
bool FileAccess::backup_save = false;
FileAccess *FileAccess::create(AccessType p_access) {
-
ERR_FAIL_INDEX_V(p_access, ACCESS_MAX, nullptr);
FileAccess *ret = create_func[p_access]();
@@ -52,34 +51,30 @@ FileAccess *FileAccess::create(AccessType p_access) {
}
bool FileAccess::exists(const String &p_name) {
-
- if (PackedData::get_singleton() && PackedData::get_singleton()->has_path(p_name))
+ if (PackedData::get_singleton() && PackedData::get_singleton()->has_path(p_name)) {
return true;
+ }
FileAccess *f = open(p_name, READ);
- if (!f)
+ if (!f) {
return false;
+ }
memdelete(f);
return true;
}
void FileAccess::_set_access_type(AccessType p_access) {
-
_access_type = p_access;
-};
+}
FileAccess *FileAccess::create_for_path(const String &p_path) {
-
FileAccess *ret = nullptr;
if (p_path.begins_with("res://")) {
-
ret = create(ACCESS_RESOURCES);
} else if (p_path.begins_with("user://")) {
-
ret = create(ACCESS_USERDATA);
} else {
-
ret = create(ACCESS_FILESYSTEM);
}
@@ -87,20 +82,19 @@ FileAccess *FileAccess::create_for_path(const String &p_path) {
}
Error FileAccess::reopen(const String &p_path, int p_mode_flags) {
-
return _open(p_path, p_mode_flags);
-};
+}
FileAccess *FileAccess::open(const String &p_path, int p_mode_flags, Error *r_error) {
-
//try packed data first
FileAccess *ret = nullptr;
if (!(p_mode_flags & WRITE) && PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled()) {
ret = PackedData::get_singleton()->try_open_path(p_path);
if (ret) {
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return ret;
}
}
@@ -108,10 +102,10 @@ FileAccess *FileAccess::open(const String &p_path, int p_mode_flags, Error *r_er
ret = create_for_path(p_path);
Error err = ret->_open(p_path, p_mode_flags);
- if (r_error)
+ if (r_error) {
*r_error = err;
+ }
if (err != OK) {
-
memdelete(ret);
ret = nullptr;
}
@@ -120,9 +114,8 @@ FileAccess *FileAccess::open(const String &p_path, int p_mode_flags, Error *r_er
}
FileAccess::CreateFunc FileAccess::get_create_func(AccessType p_access) {
-
return create_func[p_access];
-};
+}
String FileAccess::fix_path(const String &p_path) const {
//helper used by file accesses that use a single filesystem
@@ -130,40 +123,33 @@ String FileAccess::fix_path(const String &p_path) const {
String r_path = p_path.replace("\\", "/");
switch (_access_type) {
-
case ACCESS_RESOURCES: {
-
if (ProjectSettings::get_singleton()) {
if (r_path.begins_with("res://")) {
-
String resource_path = ProjectSettings::get_singleton()->get_resource_path();
if (resource_path != "") {
-
return r_path.replace("res:/", resource_path);
- };
+ }
return r_path.replace("res://", "");
}
}
} break;
case ACCESS_USERDATA: {
-
if (r_path.begins_with("user://")) {
-
String data_dir = OS::get_singleton()->get_user_data_dir();
if (data_dir != "") {
-
return r_path.replace("user:/", data_dir);
- };
+ }
return r_path.replace("user://", "");
}
} break;
case ACCESS_FILESYSTEM: {
-
return r_path;
} break;
- case ACCESS_MAX: break; // Can't happen, but silences warning
+ case ACCESS_MAX:
+ break; // Can't happen, but silences warning
}
return r_path;
@@ -172,7 +158,6 @@ String FileAccess::fix_path(const String &p_path) const {
/* these are all implemented for ease of porting, then can later be optimized */
uint16_t FileAccess::get_16() const {
-
uint16_t res;
uint8_t a, b;
@@ -180,7 +165,6 @@ uint16_t FileAccess::get_16() const {
b = get_8();
if (endian_swap) {
-
SWAP(a, b);
}
@@ -190,8 +174,8 @@ uint16_t FileAccess::get_16() const {
return res;
}
-uint32_t FileAccess::get_32() const {
+uint32_t FileAccess::get_32() const {
uint32_t res;
uint16_t a, b;
@@ -199,7 +183,6 @@ uint32_t FileAccess::get_32() const {
b = get_16();
if (endian_swap) {
-
SWAP(a, b);
}
@@ -209,8 +192,8 @@ uint32_t FileAccess::get_32() const {
return res;
}
-uint64_t FileAccess::get_64() const {
+uint64_t FileAccess::get_64() const {
uint64_t res;
uint32_t a, b;
@@ -218,7 +201,6 @@ uint64_t FileAccess::get_64() const {
b = get_32();
if (endian_swap) {
-
SWAP(a, b);
}
@@ -230,38 +212,35 @@ uint64_t FileAccess::get_64() const {
}
float FileAccess::get_float() const {
-
MarshallFloat m;
m.i = get_32();
return m.f;
-};
+}
real_t FileAccess::get_real() const {
-
- if (real_is_double)
+ if (real_is_double) {
return get_double();
- else
+ } else {
return get_float();
+ }
}
double FileAccess::get_double() const {
-
MarshallDouble m;
m.l = get_64();
return m.d;
-};
+}
String FileAccess::get_token() const {
-
CharString token;
CharType c = get_8();
while (!eof_reached()) {
-
if (c <= ' ') {
- if (token.length())
+ if (token.length()) {
break;
+ }
} else {
token += c;
}
@@ -277,19 +256,16 @@ class CharBuffer {
char *buffer;
int capacity;
- int written;
+ int written = 0;
bool grow() {
-
if (vector.resize(next_power_of_2(1 + written)) != OK) {
-
return false;
}
if (buffer == stack_buffer) { // first chunk?
for (int i = 0; i < written; i++) {
-
vector.write[i] = stack_buffer[i];
}
}
@@ -304,14 +280,11 @@ class CharBuffer {
public:
_FORCE_INLINE_ CharBuffer() :
buffer(stack_buffer),
- capacity(sizeof(stack_buffer) / sizeof(char)),
- written(0) {
+ capacity(sizeof(stack_buffer) / sizeof(char)) {
}
_FORCE_INLINE_ void push_back(char c) {
-
if (written >= capacity) {
-
ERR_FAIL_COND(!grow());
}
@@ -319,24 +292,22 @@ public:
}
_FORCE_INLINE_ const char *get_data() const {
-
return buffer;
}
};
String FileAccess::get_line() const {
-
CharBuffer line;
CharType c = get_8();
while (!eof_reached()) {
-
if (c == '\n' || c == '\0') {
line.push_back(0);
return String::utf8(line.get_data());
- } else if (c != '\r')
+ } else if (c != '\r') {
line.push_back(c);
+ }
c = get_8();
}
@@ -345,21 +316,21 @@ String FileAccess::get_line() const {
}
Vector<String> FileAccess::get_csv_line(const String &p_delim) const {
-
ERR_FAIL_COND_V(p_delim.length() != 1, Vector<String>());
String l;
int qc = 0;
do {
- if (eof_reached())
+ if (eof_reached()) {
break;
+ }
l += get_line() + "\n";
qc = 0;
for (int i = 0; i < l.length(); i++) {
-
- if (l[i] == '"')
+ if (l[i] == '"') {
qc++;
+ }
}
} while (qc % 2);
@@ -371,7 +342,6 @@ Vector<String> FileAccess::get_csv_line(const String &p_delim) const {
bool in_quote = false;
String current;
for (int i = 0; i < l.length(); i++) {
-
CharType c = l[i];
CharType s[2] = { 0, 0 };
@@ -384,7 +354,6 @@ Vector<String> FileAccess::get_csv_line(const String &p_delim) const {
current += s;
i++;
} else {
-
in_quote = !in_quote;
}
} else {
@@ -399,10 +368,10 @@ Vector<String> FileAccess::get_csv_line(const String &p_delim) const {
}
int FileAccess::get_buffer(uint8_t *p_dst, int p_length) const {
-
int i = 0;
- for (i = 0; i < p_length && !eof_reached(); i++)
+ for (i = 0; i < p_length && !eof_reached(); i++) {
p_dst[i] = get_8();
+ }
return i;
}
@@ -425,44 +394,40 @@ String FileAccess::get_as_utf8_string() const {
}
void FileAccess::store_16(uint16_t p_dest) {
-
uint8_t a, b;
a = p_dest & 0xFF;
b = p_dest >> 8;
if (endian_swap) {
-
SWAP(a, b);
}
store_8(a);
store_8(b);
}
-void FileAccess::store_32(uint32_t p_dest) {
+void FileAccess::store_32(uint32_t p_dest) {
uint16_t a, b;
a = p_dest & 0xFFFF;
b = p_dest >> 16;
if (endian_swap) {
-
SWAP(a, b);
}
store_16(a);
store_16(b);
}
-void FileAccess::store_64(uint64_t p_dest) {
+void FileAccess::store_64(uint64_t p_dest) {
uint32_t a, b;
a = p_dest & 0xFFFFFFFF;
b = p_dest >> 32;
if (endian_swap) {
-
SWAP(a, b);
}
@@ -471,31 +436,29 @@ void FileAccess::store_64(uint64_t p_dest) {
}
void FileAccess::store_real(real_t p_real) {
-
- if (sizeof(real_t) == 4)
+ if (sizeof(real_t) == 4) {
store_float(p_real);
- else
+ } else {
store_double(p_real);
+ }
}
void FileAccess::store_float(float p_dest) {
-
MarshallFloat m;
m.f = p_dest;
store_32(m.i);
-};
+}
void FileAccess::store_double(double p_dest) {
-
MarshallDouble m;
m.d = p_dest;
store_64(m.l);
-};
+}
uint64_t FileAccess::get_modified_time(const String &p_file) {
-
- if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file))
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) {
return 0;
+ }
FileAccess *fa = create_for_path(p_file);
ERR_FAIL_COND_V_MSG(!fa, 0, "Cannot create FileAccess for path '" + p_file + "'.");
@@ -506,9 +469,9 @@ uint64_t FileAccess::get_modified_time(const String &p_file) {
}
uint32_t FileAccess::get_unix_permissions(const String &p_file) {
-
- if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file))
+ if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && PackedData::get_singleton()->has_path(p_file)) {
return 0;
+ }
FileAccess *fa = create_for_path(p_file);
ERR_FAIL_COND_V_MSG(!fa, 0, "Cannot create FileAccess for path '" + p_file + "'.");
@@ -519,7 +482,6 @@ uint32_t FileAccess::get_unix_permissions(const String &p_file) {
}
Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) {
-
FileAccess *fa = create_for_path(p_file);
ERR_FAIL_COND_V_MSG(!fa, ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'.");
@@ -529,23 +491,21 @@ Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissi
}
void FileAccess::store_string(const String &p_string) {
-
- if (p_string.length() == 0)
+ if (p_string.length() == 0) {
return;
+ }
CharString cs = p_string.utf8();
store_buffer((uint8_t *)&cs[0], cs.length());
}
void FileAccess::store_pascal_string(const String &p_string) {
-
CharString cs = p_string.utf8();
store_32(cs.length());
store_buffer((uint8_t *)&cs[0], cs.length());
-};
+}
String FileAccess::get_pascal_string() {
-
uint32_t sl = get_32();
CharString cs;
cs.resize(sl + 1);
@@ -556,16 +516,14 @@ String FileAccess::get_pascal_string() {
ret.parse_utf8(cs.ptr());
return ret;
-};
+}
void FileAccess::store_line(const String &p_line) {
-
store_string(p_line);
store_8('\n');
}
void FileAccess::store_csv_line(const Vector<String> &p_values, const String &p_delim) {
-
ERR_FAIL_COND(p_delim.length() != 1);
String line = "";
@@ -587,13 +545,12 @@ void FileAccess::store_csv_line(const Vector<String> &p_values, const String &p_
}
void FileAccess::store_buffer(const uint8_t *p_src, int p_length) {
-
- for (int i = 0; i < p_length; i++)
+ for (int i = 0; i < p_length; i++) {
store_8(p_src[i]);
+ }
}
Vector<uint8_t> FileAccess::get_file_as_array(const String &p_path, Error *r_error) {
-
FileAccess *f = FileAccess::open(p_path, READ, r_error);
if (!f) {
if (r_error) { // if error requested, do not throw error
@@ -609,7 +566,6 @@ Vector<uint8_t> FileAccess::get_file_as_array(const String &p_path, Error *r_err
}
String FileAccess::get_file_as_string(const String &p_path, Error *r_error) {
-
Error err;
Vector<uint8_t> array = get_file_as_array(p_path, &err);
if (r_error) {
@@ -628,10 +584,10 @@ String FileAccess::get_file_as_string(const String &p_path, Error *r_error) {
}
String FileAccess::get_md5(const String &p_file) {
-
FileAccess *f = FileAccess::open(p_file, READ);
- if (!f)
+ if (!f) {
return String();
+ }
CryptoCore::MD5Context ctx;
ctx.start();
@@ -639,14 +595,13 @@ String FileAccess::get_md5(const String &p_file) {
unsigned char step[32768];
while (true) {
-
int br = f->get_buffer(step, 32768);
if (br > 0) {
-
ctx.update(step, br);
}
- if (br < 4096)
+ if (br < 4096) {
break;
+ }
}
unsigned char hash[16];
@@ -658,7 +613,6 @@ String FileAccess::get_md5(const String &p_file) {
}
String FileAccess::get_multiple_md5(const Vector<String> &p_file) {
-
CryptoCore::MD5Context ctx;
ctx.start();
@@ -669,14 +623,13 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) {
unsigned char step[32768];
while (true) {
-
int br = f->get_buffer(step, 32768);
if (br > 0) {
-
ctx.update(step, br);
}
- if (br < 4096)
+ if (br < 4096) {
break;
+ }
}
memdelete(f);
}
@@ -688,10 +641,10 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) {
}
String FileAccess::get_sha256(const String &p_file) {
-
FileAccess *f = FileAccess::open(p_file, READ);
- if (!f)
+ if (!f) {
return String();
+ }
CryptoCore::SHA256Context ctx;
ctx.start();
@@ -699,14 +652,13 @@ String FileAccess::get_sha256(const String &p_file) {
unsigned char step[32768];
while (true) {
-
int br = f->get_buffer(step, 32768);
if (br > 0) {
-
ctx.update(step, br);
}
- if (br < 4096)
+ if (br < 4096) {
break;
+ }
}
unsigned char hash[32];
@@ -715,10 +667,3 @@ String FileAccess::get_sha256(const String &p_file) {
memdelete(f);
return String::hex_encode_buffer(hash, 32);
}
-
-FileAccess::FileAccess() {
-
- endian_swap = false;
- real_is_double = false;
- _access_type = ACCESS_FILESYSTEM;
-};
diff --git a/core/os/file_access.h b/core/os/file_access.h
index 010cc74a87..48b9ee4269 100644
--- a/core/os/file_access.h
+++ b/core/os/file_access.h
@@ -41,7 +41,6 @@
*/
class FileAccess {
-
public:
enum AccessType {
ACCESS_RESOURCES,
@@ -53,8 +52,8 @@ public:
typedef void (*FileCloseFailNotify)(const String &);
typedef FileAccess *(*CreateFunc)();
- bool endian_swap;
- bool real_is_double;
+ bool endian_swap = false;
+ bool real_is_double = false;
virtual uint32_t _get_unix_permissions(const String &p_file) = 0;
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) = 0;
@@ -69,11 +68,10 @@ protected:
private:
static bool backup_save;
- AccessType _access_type;
+ AccessType _access_type = ACCESS_FILESYSTEM;
static CreateFunc create_func[ACCESS_MAX]; /** default file access creation function for a platform */
template <class T>
static FileAccess *_create_builtin() {
-
return memnew(T);
}
@@ -172,27 +170,29 @@ public:
template <class T>
static void make_default(AccessType p_access) {
-
create_func[p_access] = _create_builtin<T>;
}
- FileAccess();
+ FileAccess() {}
virtual ~FileAccess() {}
};
struct FileAccessRef {
-
_FORCE_INLINE_ FileAccess *operator->() {
-
return f;
}
operator bool() const { return f != nullptr; }
+
FileAccess *f;
+
operator FileAccess *() { return f; }
+
FileAccessRef(FileAccess *fa) { f = fa; }
~FileAccessRef() {
- if (f) memdelete(f);
+ if (f) {
+ memdelete(f);
+ }
}
};
diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp
index c65d3fefc2..d088151a6d 100644
--- a/core/os/keyboard.cpp
+++ b/core/os/keyboard.cpp
@@ -293,9 +293,7 @@ static const _KeyCodeText _keycodes[] = {
};
bool keycode_has_unicode(uint32_t p_keycode) {
-
switch (p_keycode) {
-
case KEY_ESCAPE:
case KEY_TAB:
case KEY_BACKTAB:
@@ -394,7 +392,6 @@ bool keycode_has_unicode(uint32_t p_keycode) {
}
String keycode_get_string(uint32_t p_code) {
-
String codestr;
if (p_code & KEY_MASK_SHIFT) {
codestr += find_keycode_name(KEY_SHIFT);
@@ -418,9 +415,7 @@ String keycode_get_string(uint32_t p_code) {
const _KeyCodeText *kct = &_keycodes[0];
while (kct->text) {
-
if (kct->code == (int)p_code) {
-
codestr += kct->text;
return codestr;
}
@@ -433,11 +428,9 @@ String keycode_get_string(uint32_t p_code) {
}
int find_keycode(const String &p_code) {
-
const _KeyCodeText *kct = &_keycodes[0];
while (kct->text) {
-
if (p_code.nocasecmp_to(kct->text) == 0) {
return kct->code;
}
@@ -448,11 +441,9 @@ int find_keycode(const String &p_code) {
}
const char *find_keycode_name(int p_keycode) {
-
const _KeyCodeText *kct = &_keycodes[0];
while (kct->text) {
-
if (kct->code == p_keycode) {
return kct->text;
}
@@ -463,12 +454,10 @@ const char *find_keycode_name(int p_keycode) {
}
int keycode_get_count() {
-
const _KeyCodeText *kct = &_keycodes[0];
int count = 0;
while (kct->text) {
-
count++;
kct++;
}
diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp
index 0d1a080682..dc68c2a9f9 100644
--- a/core/os/main_loop.cpp
+++ b/core/os/main_loop.cpp
@@ -33,7 +33,6 @@
#include "core/script_language.h"
void MainLoop::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("init"), &MainLoop::init);
ClassDB::bind_method(D_METHOD("iteration", "delta"), &MainLoop::iteration);
ClassDB::bind_method(D_METHOD("idle", "delta"), &MainLoop::idle);
@@ -56,41 +55,36 @@ void MainLoop::_bind_methods() {
};
void MainLoop::set_init_script(const Ref<Script> &p_init_script) {
-
init_script = p_init_script;
}
-MainLoop::MainLoop() {
-}
-
-MainLoop::~MainLoop() {
-}
-
void MainLoop::init() {
-
- if (init_script.is_valid())
+ if (init_script.is_valid()) {
set_script(init_script);
+ }
- if (get_script_instance())
+ if (get_script_instance()) {
get_script_instance()->call("_initialize");
+ }
}
-bool MainLoop::iteration(float p_time) {
- if (get_script_instance())
+bool MainLoop::iteration(float p_time) {
+ if (get_script_instance()) {
return get_script_instance()->call("_iteration", p_time);
+ }
return false;
}
-bool MainLoop::idle(float p_time) {
- if (get_script_instance())
+bool MainLoop::idle(float p_time) {
+ if (get_script_instance()) {
return get_script_instance()->call("_idle", p_time);
+ }
return false;
}
void MainLoop::finish() {
-
if (get_script_instance()) {
get_script_instance()->call("_finalize");
set_script(Variant()); //clear script
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index 8f6c8c91b1..90790a45a1 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -36,7 +36,6 @@
#include "core/script_language.h"
class MainLoop : public Object {
-
GDCLASS(MainLoop, Object);
OBJ_CATEGORY("Main Loop");
@@ -64,8 +63,8 @@ public:
void set_init_script(const Ref<Script> &p_init_script);
- MainLoop();
- virtual ~MainLoop();
+ MainLoop() {}
+ virtual ~MainLoop() {}
};
#endif // MAIN_LOOP_H
diff --git a/core/os/memory.cpp b/core/os/memory.cpp
index d921c10ad4..8457c52092 100644
--- a/core/os/memory.cpp
+++ b/core/os/memory.cpp
@@ -38,28 +38,23 @@
#include <stdlib.h>
void *operator new(size_t p_size, const char *p_description) {
-
return Memory::alloc_static(p_size, false);
}
void *operator new(size_t p_size, void *(*p_allocfunc)(size_t p_size)) {
-
return p_allocfunc(p_size);
}
#ifdef _MSC_VER
void operator delete(void *p_mem, const char *p_description) {
-
CRASH_NOW_MSG("Call to placement delete should not happen.");
}
void operator delete(void *p_mem, void *(*p_allocfunc)(size_t p_size)) {
-
CRASH_NOW_MSG("Call to placement delete should not happen.");
}
void operator delete(void *p_mem, void *p_pointer, size_t check, const char *p_description) {
-
CRASH_NOW_MSG("Call to placement delete should not happen.");
}
#endif
@@ -72,7 +67,6 @@ uint64_t Memory::max_usage = 0;
uint64_t Memory::alloc_count = 0;
void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
-
#ifdef DEBUG_ENABLED
bool prepad = true;
#else
@@ -102,7 +96,6 @@ void *Memory::alloc_static(size_t p_bytes, bool p_pad_align) {
}
void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
-
if (p_memory == nullptr) {
return alloc_static(p_bytes, p_pad_align);
}
@@ -144,7 +137,6 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
return mem + PAD_ALIGN;
}
} else {
-
mem = (uint8_t *)realloc(mem, p_bytes);
ERR_FAIL_COND_V(mem == nullptr && p_bytes > 0, nullptr);
@@ -154,7 +146,6 @@ void *Memory::realloc_static(void *p_memory, size_t p_bytes, bool p_pad_align) {
}
void Memory::free_static(void *p_ptr, bool p_pad_align) {
-
ERR_FAIL_COND(p_ptr == nullptr);
uint8_t *mem = (uint8_t *)p_ptr;
@@ -177,13 +168,11 @@ void Memory::free_static(void *p_ptr, bool p_pad_align) {
free(mem);
} else {
-
free(mem);
}
}
uint64_t Memory::get_mem_available() {
-
return -1; // 0xFFFF...
}
@@ -204,8 +193,6 @@ uint64_t Memory::get_mem_max_usage() {
}
_GlobalNil::_GlobalNil() {
-
- color = 1;
left = this;
right = this;
parent = this;
diff --git a/core/os/memory.h b/core/os/memory.h
index dcaedd92ba..46ffb4124b 100644
--- a/core/os/memory.h
+++ b/core/os/memory.h
@@ -41,7 +41,6 @@
#endif
class Memory {
-
Memory();
#ifdef DEBUG_ENABLED
static uint64_t mem_usage;
@@ -87,7 +86,6 @@ _ALWAYS_INLINE_ void postinitialize_handler(void *) {}
template <class T>
_ALWAYS_INLINE_ T *_post_initialize(T *p_obj) {
-
postinitialize_handler(p_obj);
return p_obj;
}
@@ -110,44 +108,48 @@ _ALWAYS_INLINE_ bool predelete_handler(void *) {
template <class T>
void memdelete(T *p_class) {
-
- if (!predelete_handler(p_class))
+ if (!predelete_handler(p_class)) {
return; // doesn't want to be deleted
- if (!__has_trivial_destructor(T))
+ }
+ if (!__has_trivial_destructor(T)) {
p_class->~T();
+ }
Memory::free_static(p_class, false);
}
template <class T, class A>
void memdelete_allocator(T *p_class) {
-
- if (!predelete_handler(p_class))
+ if (!predelete_handler(p_class)) {
return; // doesn't want to be deleted
- if (!__has_trivial_destructor(T))
+ }
+ if (!__has_trivial_destructor(T)) {
p_class->~T();
+ }
A::free(p_class);
}
-#define memdelete_notnull(m_v) \
- { \
- if (m_v) memdelete(m_v); \
+#define memdelete_notnull(m_v) \
+ { \
+ if (m_v) { \
+ memdelete(m_v); \
+ } \
}
#define memnew_arr(m_class, m_count) memnew_arr_template<m_class>(m_count)
template <typename T>
T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
-
- if (p_elements == 0)
- return 0;
+ if (p_elements == 0) {
+ return nullptr;
+ }
/** overloading operator new[] cannot be done , because it may not return the real allocated address (it may pad the 'element count' before the actual array). Because of that, it must be done by hand. This is the
same strategy used by std::vector, and the Vector class, so it should be safe.*/
size_t len = sizeof(T) * p_elements;
uint64_t *mem = (uint64_t *)Memory::alloc_static(len, true);
- T *failptr = 0; //get rid of a warning
+ T *failptr = nullptr; //get rid of a warning
ERR_FAIL_COND_V(!mem, failptr);
*(mem - 1) = p_elements;
@@ -170,14 +172,12 @@ T *memnew_arr_template(size_t p_elements, const char *p_descr = "") {
template <typename T>
size_t memarr_len(const T *p_class) {
-
uint64_t *ptr = (uint64_t *)p_class;
return *(ptr - 1);
}
template <typename T>
void memdelete_arr(T *p_class) {
-
uint64_t *ptr = (uint64_t *)p_class;
if (!__has_trivial_destructor(T)) {
@@ -192,8 +192,7 @@ void memdelete_arr(T *p_class) {
}
struct _GlobalNil {
-
- int color;
+ int color = 1;
_GlobalNil *right;
_GlobalNil *left;
_GlobalNil *parent;
@@ -202,7 +201,6 @@ struct _GlobalNil {
};
struct _GlobalNilClass {
-
static _GlobalNil _nil;
};
diff --git a/core/os/midi_driver.cpp b/core/os/midi_driver.cpp
index 985f6f38e5..e9919aeb86 100644
--- a/core/os/midi_driver.cpp
+++ b/core/os/midi_driver.cpp
@@ -30,23 +30,20 @@
#include "midi_driver.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/os.h"
uint8_t MIDIDriver::last_received_message = 0x00;
MIDIDriver *MIDIDriver::singleton = nullptr;
MIDIDriver *MIDIDriver::get_singleton() {
-
return singleton;
}
void MIDIDriver::set_singleton() {
-
singleton = this;
}
void MIDIDriver::receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_t length) {
-
Ref<InputEventMIDI> event;
event.instance();
uint32_t param_position = 1;
@@ -117,17 +114,15 @@ void MIDIDriver::receive_input_packet(uint64_t timestamp, uint8_t *data, uint32_
break;
}
- InputFilter *id = InputFilter::get_singleton();
+ Input *id = Input::get_singleton();
id->parse_input_event(event);
}
PackedStringArray MIDIDriver::get_connected_inputs() {
-
PackedStringArray list;
return list;
}
MIDIDriver::MIDIDriver() {
-
set_singleton();
}
diff --git a/core/os/midi_driver.h b/core/os/midi_driver.h
index b7377a8a40..bc922e1fcf 100644
--- a/core/os/midi_driver.h
+++ b/core/os/midi_driver.h
@@ -39,7 +39,6 @@
*/
class MIDIDriver {
-
static MIDIDriver *singleton;
static uint8_t last_received_message;
diff --git a/core/os/mutex.h b/core/os/mutex.h
index 526549dd93..d42cbed821 100644
--- a/core/os/mutex.h
+++ b/core/os/mutex.h
@@ -82,8 +82,7 @@ extern template class MutexLock<MutexImpl<std::mutex>>;
#else
class FakeMutex {
-
- FakeMutex(){};
+ FakeMutex() {}
};
template <class MutexT>
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 0636810e4b..c29930e485 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -30,7 +30,7 @@
#include "os.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
#include "core/os/midi_driver.h"
@@ -43,7 +43,6 @@
OS *OS::singleton = nullptr;
OS *OS::get_singleton() {
-
return singleton;
}
@@ -83,20 +82,22 @@ String OS::get_iso_date_time(bool local) const {
uint64_t OS::get_splash_tick_msec() const {
return _msec_splash;
}
-uint64_t OS::get_unix_time() const {
+uint64_t OS::get_unix_time() const {
return 0;
-};
+}
+
uint64_t OS::get_system_time_secs() const {
return 0;
}
+
uint64_t OS::get_system_time_msecs() const {
return 0;
}
-void OS::debug_break(){
+void OS::debug_break() {
// something
-};
+}
void OS::_set_logger(CompositeLogger *p_logger) {
if (_logger) {
@@ -116,19 +117,17 @@ void OS::add_logger(Logger *p_logger) {
}
void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type) {
-
_logger->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
}
void OS::print(const char *p_format, ...) {
-
va_list argp;
va_start(argp, p_format);
_logger->logv(p_format, argp, false);
va_end(argp);
-};
+}
void OS::printerr(const char *p_format, ...) {
va_list argp;
@@ -137,73 +136,63 @@ void OS::printerr(const char *p_format, ...) {
_logger->logv(p_format, argp, true);
va_end(argp);
-};
+}
void OS::set_low_processor_usage_mode(bool p_enabled) {
-
low_processor_usage_mode = p_enabled;
}
bool OS::is_in_low_processor_usage_mode() const {
-
return low_processor_usage_mode;
}
void OS::set_low_processor_usage_mode_sleep_usec(int p_usec) {
-
low_processor_usage_mode_sleep_usec = p_usec;
}
int OS::get_low_processor_usage_mode_sleep_usec() const {
-
return low_processor_usage_mode_sleep_usec;
}
String OS::get_executable_path() const {
-
return _execpath;
}
int OS::get_process_id() const {
-
return -1;
-};
+}
void OS::vibrate_handheld(int p_duration_ms) {
-
WARN_PRINT("vibrate_handheld() only works with Android and iOS");
}
bool OS::is_stdout_verbose() const {
-
return _verbose_stdout;
}
void OS::dump_memory_to_file(const char *p_file) {
-
//Memory::dump_static_mem_to_file(p_file);
}
static FileAccess *_OSPRF = nullptr;
static void _OS_printres(Object *p_obj) {
-
Resource *res = Object::cast_to<Resource>(p_obj);
- if (!res)
+ if (!res) {
return;
+ }
String str = itos(res->get_instance_id()) + String(res->get_class()) + ":" + String(res->get_name()) + " - " + res->get_path();
- if (_OSPRF)
+ if (_OSPRF) {
_OSPRF->store_line(str);
- else
+ } else {
print_line(str);
+ }
}
void OS::print_all_resources(String p_to_file) {
-
ERR_FAIL_COND(p_to_file != "" && _OSPRF);
if (p_to_file != "") {
-
Error err;
_OSPRF = FileAccess::open(p_to_file, FileAccess::WRITE, &err);
if (err != OK) {
@@ -215,50 +204,43 @@ void OS::print_all_resources(String p_to_file) {
ObjectDB::debug_objects(_OS_printres);
if (p_to_file != "") {
-
- if (_OSPRF)
+ if (_OSPRF) {
memdelete(_OSPRF);
+ }
_OSPRF = nullptr;
}
}
void OS::print_resources_in_use(bool p_short) {
-
ResourceCache::dump(nullptr, p_short);
}
void OS::dump_resources_to_file(const char *p_file) {
-
ResourceCache::dump(p_file);
}
void OS::set_no_window_mode(bool p_enable) {
-
_no_window = p_enable;
}
bool OS::is_no_window_mode_enabled() const {
-
return _no_window;
}
int OS::get_exit_code() const {
-
return _exit_code;
}
-void OS::set_exit_code(int p_code) {
+void OS::set_exit_code(int p_code) {
_exit_code = p_code;
}
String OS::get_locale() const {
-
return "en";
}
// Helper function to ensure that a dir name/path will be valid on the OS
String OS::get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separator) const {
-
Vector<String> invalid_chars = String(": * ? \" < > |").split(" ");
if (p_allow_dir_separator) {
// Dir separators are allowed, but disallow ".." to avoid going up the filesystem
@@ -278,76 +260,64 @@ String OS::get_safe_dir_name(const String &p_dir_name, bool p_allow_dir_separato
// Get properly capitalized engine name for system paths
String OS::get_godot_dir_name() const {
-
// Default to lowercase, so only override when different case is needed
return String(VERSION_SHORT_NAME).to_lower();
}
// OS equivalent of XDG_DATA_HOME
String OS::get_data_path() const {
-
return ".";
}
// OS equivalent of XDG_CONFIG_HOME
String OS::get_config_path() const {
-
return ".";
}
// OS equivalent of XDG_CACHE_HOME
String OS::get_cache_path() const {
-
return ".";
}
// Path to macOS .app bundle resources
String OS::get_bundle_resource_dir() const {
-
return ".";
-};
+}
// OS specific path for user://
String OS::get_user_data_dir() const {
-
return ".";
-};
+}
// Absolute path to res://
String OS::get_resource_dir() const {
-
return ProjectSettings::get_singleton()->get_resource_path();
}
// Access system-specific dirs like Documents, Downloads, etc.
String OS::get_system_dir(SystemDir p_dir) const {
-
return ".";
}
Error OS::shell_open(String p_uri) {
return ERR_UNAVAILABLE;
-};
+}
// implement these with the canvas?
uint64_t OS::get_static_memory_usage() const {
-
return Memory::get_mem_usage();
}
uint64_t OS::get_static_memory_peak_usage() const {
-
return Memory::get_mem_max_usage();
}
Error OS::set_cwd(const String &p_cwd) {
-
return ERR_CANT_OPEN;
}
uint64_t OS::get_free_static_memory() const {
-
return Memory::get_mem_available();
}
@@ -355,7 +325,6 @@ void OS::yield() {
}
void OS::ensure_user_data_dir() {
-
String dd = get_user_data_dir();
DirAccess *da = DirAccess::open(dd);
if (da) {
@@ -371,28 +340,23 @@ void OS::ensure_user_data_dir() {
}
String OS::get_model_name() const {
-
return "GenericDevice";
}
void OS::set_cmdline(const char *p_execpath, const List<String> &p_args) {
-
_execpath = p_execpath;
_cmdline = p_args;
-};
+}
String OS::get_unique_id() const {
-
ERR_FAIL_V("");
}
int OS::get_processor_count() const {
-
return 1;
}
bool OS::can_use_threads() const {
-
#ifdef NO_THREADS
return false;
#else
@@ -401,24 +365,25 @@ bool OS::can_use_threads() const {
}
void OS::set_has_server_feature_callback(HasServerFeatureCallback p_callback) {
-
has_server_feature_callback = p_callback;
}
bool OS::has_feature(const String &p_feature) {
-
- if (p_feature == get_name())
+ if (p_feature == get_name()) {
return true;
+ }
#ifdef DEBUG_ENABLED
- if (p_feature == "debug")
+ if (p_feature == "debug") {
return true;
+ }
#else
if (p_feature == "release")
return true;
#endif
#ifdef TOOLS_ENABLED
- if (p_feature == "editor")
+ if (p_feature == "editor") {
return true;
+ }
#else
if (p_feature == "standalone")
return true;
@@ -458,15 +423,17 @@ bool OS::has_feature(const String &p_feature) {
}
#endif
- if (_check_internal_feature_support(p_feature))
+ if (_check_internal_feature_support(p_feature)) {
return true;
+ }
if (has_server_feature_callback && has_server_feature_callback(p_feature)) {
return true;
}
- if (ProjectSettings::get_singleton()->has_custom_feature(p_feature))
+ if (ProjectSettings::get_singleton()->has_custom_feature(p_feature)) {
return true;
+ }
return false;
}
@@ -485,48 +452,33 @@ List<String> OS::get_restart_on_exit_arguments() const {
}
PackedStringArray OS::get_connected_midi_inputs() {
-
- if (MIDIDriver::get_singleton())
+ if (MIDIDriver::get_singleton()) {
return MIDIDriver::get_singleton()->get_connected_inputs();
+ }
PackedStringArray list;
return list;
}
void OS::open_midi_inputs() {
-
- if (MIDIDriver::get_singleton())
+ if (MIDIDriver::get_singleton()) {
MIDIDriver::get_singleton()->open();
+ }
}
void OS::close_midi_inputs() {
-
- if (MIDIDriver::get_singleton())
+ if (MIDIDriver::get_singleton()) {
MIDIDriver::get_singleton()->close();
+ }
}
OS::OS() {
void *volatile stack_bottom;
- restart_on_exit = false;
singleton = this;
- _keep_screen_on = true; // set default value to true, because this had been true before godot 2.0.
- low_processor_usage_mode = false;
- low_processor_usage_mode_sleep_usec = 10000;
- _verbose_stdout = false;
- _no_window = false;
- _exit_code = 0;
-
- _render_thread_mode = RENDER_THREAD_SAFE;
- _allow_hidpi = false;
- _allow_layered = false;
_stack_bottom = (void *)(&stack_bottom);
- _logger = nullptr;
-
- has_server_feature_callback = nullptr;
-
Vector<Logger *> loggers;
loggers.push_back(memnew(StdLogger));
_set_logger(memnew(CompositeLogger(loggers)));
diff --git a/core/os/os.h b/core/os/os.h
index 714a10bf76..9ca034a01c 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -42,21 +42,20 @@
#include <stdarg.h>
class OS {
-
static OS *singleton;
String _execpath;
List<String> _cmdline;
- bool _keep_screen_on;
- bool low_processor_usage_mode;
- int low_processor_usage_mode_sleep_usec;
- bool _verbose_stdout;
+ bool _keep_screen_on = true; // set default value to true, because this had been true before godot 2.0.
+ bool low_processor_usage_mode = false;
+ int low_processor_usage_mode_sleep_usec = 10000;
+ bool _verbose_stdout = false;
String _local_clipboard;
uint64_t _msec_splash;
- bool _no_window;
- int _exit_code;
+ bool _no_window = false;
+ int _exit_code = 0;
int _orientation;
- bool _allow_hidpi;
- bool _allow_layered;
+ bool _allow_hidpi = false;
+ bool _allow_layered = false;
bool _use_vsync;
bool _vsync_via_compositor;
@@ -64,9 +63,9 @@ class OS {
void *_stack_bottom;
- CompositeLogger *_logger;
+ CompositeLogger *_logger = nullptr;
- bool restart_on_exit;
+ bool restart_on_exit = false;
List<String> restart_commandline;
protected:
@@ -86,8 +85,8 @@ public:
protected:
friend class Main;
- HasServerFeatureCallback has_server_feature_callback;
- RenderThreadMode _render_thread_mode;
+ HasServerFeatureCallback has_server_feature_callback = nullptr;
+ RenderThreadMode _render_thread_mode = RENDER_THREAD_SAFE;
// functions used by main to initialize/deinitialize the OS
void add_logger(Logger *p_logger);
@@ -149,6 +148,11 @@ public:
bool is_layered_allowed() const { return _allow_layered; }
bool is_hidpi_allowed() const { return _allow_hidpi; }
+ virtual int get_tablet_driver_count() const { return 0; };
+ virtual String get_tablet_driver_name(int p_driver) const { return ""; };
+ virtual String get_current_tablet_driver() const { return ""; };
+ virtual void set_current_tablet_driver(const String &p_driver){};
+
void ensure_user_data_dir();
virtual MainLoop *get_main_loop() const = 0;
@@ -183,7 +187,6 @@ public:
};
struct Date {
-
int year;
Month month;
int day;
@@ -192,7 +195,6 @@ public:
};
struct Time {
-
int hour;
int min;
int sec;
diff --git a/core/os/rw_lock.cpp b/core/os/rw_lock.cpp
index 1dd2c3bccb..a668fe2b4c 100644
--- a/core/os/rw_lock.cpp
+++ b/core/os/rw_lock.cpp
@@ -37,11 +37,7 @@
RWLock *(*RWLock::create_func)() = nullptr;
RWLock *RWLock::create() {
-
ERR_FAIL_COND_V(!create_func, nullptr);
return create_func();
}
-
-RWLock::~RWLock() {
-}
diff --git a/core/os/rw_lock.h b/core/os/rw_lock.h
index 64dfbef20c..1035072cce 100644
--- a/core/os/rw_lock.h
+++ b/core/os/rw_lock.h
@@ -48,34 +48,40 @@ public:
static RWLock *create(); ///< Create a rwlock
- virtual ~RWLock();
+ virtual ~RWLock() {}
};
class RWLockRead {
-
RWLock *lock;
public:
RWLockRead(const RWLock *p_lock) {
lock = const_cast<RWLock *>(p_lock);
- if (lock) lock->read_lock();
+ if (lock) {
+ lock->read_lock();
+ }
}
~RWLockRead() {
- if (lock) lock->read_unlock();
+ if (lock) {
+ lock->read_unlock();
+ }
}
};
class RWLockWrite {
-
RWLock *lock;
public:
RWLockWrite(RWLock *p_lock) {
lock = p_lock;
- if (lock) lock->write_lock();
+ if (lock) {
+ lock->write_lock();
+ }
}
~RWLockWrite() {
- if (lock) lock->write_unlock();
+ if (lock) {
+ lock->write_unlock();
+ }
}
};
diff --git a/core/os/semaphore.h b/core/os/semaphore.h
index 3d9d1ab984..077e04704b 100644
--- a/core/os/semaphore.h
+++ b/core/os/semaphore.h
@@ -54,8 +54,9 @@ public:
_ALWAYS_INLINE_ void wait() const {
std::unique_lock<decltype(mutex_)> lock(mutex_);
- while (!count_) // Handle spurious wake-ups.
+ while (!count_) { // Handle spurious wake-ups.
condition_.wait(lock);
+ }
--count_;
}
diff --git a/core/os/thread.cpp b/core/os/thread.cpp
index 294b52f00c..fc0ce3c9b4 100644
--- a/core/os/thread.cpp
+++ b/core/os/thread.cpp
@@ -38,37 +38,29 @@ Error (*Thread::set_name_func)(const String &) = nullptr;
Thread::ID Thread::_main_thread_id = 0;
Thread::ID Thread::get_caller_id() {
-
- if (get_thread_id_func)
+ if (get_thread_id_func) {
return get_thread_id_func();
+ }
return 0;
}
Thread *Thread::create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings) {
-
if (create_func) {
-
return create_func(p_callback, p_user, p_settings);
}
return nullptr;
}
void Thread::wait_to_finish(Thread *p_thread) {
-
- if (wait_to_finish_func)
+ if (wait_to_finish_func) {
wait_to_finish_func(p_thread);
+ }
}
Error Thread::set_name(const String &p_name) {
-
- if (set_name_func)
+ if (set_name_func) {
return set_name_func(p_name);
+ }
return ERR_UNAVAILABLE;
-};
-
-Thread::Thread() {
-}
-
-Thread::~Thread() {
}
diff --git a/core/os/thread.h b/core/os/thread.h
index 76d296bcf7..f761d4ca43 100644
--- a/core/os/thread.h
+++ b/core/os/thread.h
@@ -46,7 +46,6 @@ public:
};
struct Settings {
-
Priority priority;
Settings() { priority = PRIORITY_NORMAL; }
};
@@ -63,7 +62,7 @@ protected:
static ID _main_thread_id;
- Thread();
+ Thread() {}
public:
virtual ID get_id() const = 0;
@@ -74,7 +73,7 @@ public:
static void wait_to_finish(Thread *p_thread); ///< waits until thread is finished, and deallocates it.
static Thread *create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings = Settings()); ///< Static function to create a thread, will call p_callback
- virtual ~Thread();
+ virtual ~Thread() {}
};
#endif // THREAD_H
diff --git a/core/os/thread_dummy.cpp b/core/os/thread_dummy.cpp
index 9dcddcae11..2672cd7ad9 100644
--- a/core/os/thread_dummy.cpp
+++ b/core/os/thread_dummy.cpp
@@ -34,16 +34,16 @@
Thread *ThreadDummy::create(ThreadCreateCallback p_callback, void *p_user, const Thread::Settings &p_settings) {
return memnew(ThreadDummy);
-};
+}
void ThreadDummy::make_default() {
Thread::create_func = &ThreadDummy::create;
-};
+}
RWLock *RWLockDummy::create() {
return memnew(RWLockDummy);
-};
+}
void RWLockDummy::make_default() {
RWLock::create_func = &RWLockDummy::create;
-};
+}
diff --git a/core/os/thread_dummy.h b/core/os/thread_dummy.h
index 066ee498ac..37d9ee0846 100644
--- a/core/os/thread_dummy.h
+++ b/core/os/thread_dummy.h
@@ -36,7 +36,6 @@
#include "core/os/thread.h"
class ThreadDummy : public Thread {
-
static Thread *create(ThreadCreateCallback p_callback, void *p_user, const Settings &p_settings = Settings());
public:
@@ -46,7 +45,6 @@ public:
};
class RWLockDummy : public RWLock {
-
static RWLock *create();
public:
diff --git a/core/os/threaded_array_processor.h b/core/os/threaded_array_processor.h
index 00dc53286e..d27399e4cc 100644
--- a/core/os/threaded_array_processor.h
+++ b/core/os/threaded_array_processor.h
@@ -54,19 +54,18 @@ struct ThreadArrayProcessData {
template <class T>
void process_array_thread(void *ud) {
-
T &data = *(T *)ud;
while (true) {
uint32_t index = atomic_increment(&data.index);
- if (index >= data.elements)
+ if (index >= data.elements) {
break;
+ }
data.process(index);
}
}
template <class C, class M, class U>
void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) {
-
ThreadArrayProcessData<C, U> data;
data.method = p_method;
data.instance = p_instance;
@@ -93,7 +92,6 @@ void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_us
template <class C, class M, class U>
void thread_process_array(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) {
-
ThreadArrayProcessData<C, U> data;
data.method = p_method;
data.instance = p_instance;
diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp
index 04deba2c14..e335ec0daa 100644
--- a/core/packed_data_container.cpp
+++ b/core/packed_data_container.cpp
@@ -34,51 +34,50 @@
#include "core/io/marshalls.h"
Variant PackedDataContainer::getvar(const Variant &p_key, bool *r_valid) const {
-
bool err = false;
Variant ret = _key_at_ofs(0, p_key, err);
- if (r_valid)
+ if (r_valid) {
*r_valid = !err;
+ }
return ret;
}
int PackedDataContainer::size() const {
-
return _size(0);
-};
+}
Variant PackedDataContainer::_iter_init_ofs(const Array &p_iter, uint32_t p_offset) {
-
Array ref = p_iter;
uint32_t size = _size(p_offset);
- if (size == 0 || ref.size() != 1)
+ if (size == 0 || ref.size() != 1) {
return false;
- else {
+ } else {
ref[0] = 0;
return true;
}
}
Variant PackedDataContainer::_iter_next_ofs(const Array &p_iter, uint32_t p_offset) {
-
Array ref = p_iter;
int size = _size(p_offset);
- if (ref.size() != 1)
+ if (ref.size() != 1) {
return false;
+ }
int pos = ref[0];
- if (pos < 0 || pos >= size)
+ if (pos < 0 || pos >= size) {
return false;
+ }
pos += 1;
ref[0] = pos;
return pos != size;
}
Variant PackedDataContainer::_iter_get_ofs(const Variant &p_iter, uint32_t p_offset) {
-
int size = _size(p_offset);
int pos = p_iter;
- if (pos < 0 || pos >= size)
+ if (pos < 0 || pos >= size) {
return Variant();
+ }
const uint8_t *rd = data.ptr();
const uint8_t *r = &rd[p_offset];
@@ -86,12 +85,10 @@ Variant PackedDataContainer::_iter_get_ofs(const Variant &p_iter, uint32_t p_off
bool err = false;
if (type == TYPE_ARRAY) {
-
uint32_t vpos = decode_uint32(rd + p_offset + 8 + pos * 4);
return _get_at_ofs(vpos, rd, err);
} else if (type == TYPE_DICT) {
-
uint32_t vpos = decode_uint32(rd + p_offset + 8 + pos * 12 + 4);
return _get_at_ofs(vpos, rd, err);
} else {
@@ -100,11 +97,9 @@ Variant PackedDataContainer::_iter_get_ofs(const Variant &p_iter, uint32_t p_off
}
Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, bool &err) const {
-
uint32_t type = decode_uint32(p_buf + p_ofs);
if (type == TYPE_ARRAY || type == TYPE_DICT) {
-
Ref<PackedDataContainerRef> pdcr = memnew(PackedDataContainerRef);
Ref<PackedDataContainer> pdc = Ref<PackedDataContainer>((PackedDataContainer *)this);
@@ -112,12 +107,10 @@ Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, b
pdcr->offset = p_ofs;
return pdcr;
} else {
-
Variant v;
Error rerr = decode_variant(v, p_buf + p_ofs, datalen - p_ofs, nullptr, false);
if (rerr != OK) {
-
err = true;
ERR_FAIL_COND_V_MSG(err != OK, Variant(), "Error when trying to decode Variant.");
}
@@ -126,45 +119,38 @@ Variant PackedDataContainer::_get_at_ofs(uint32_t p_ofs, const uint8_t *p_buf, b
}
uint32_t PackedDataContainer::_type_at_ofs(uint32_t p_ofs) const {
-
const uint8_t *rd = data.ptr();
const uint8_t *r = &rd[p_ofs];
uint32_t type = decode_uint32(r);
return type;
-};
+}
int PackedDataContainer::_size(uint32_t p_ofs) const {
-
const uint8_t *rd = data.ptr();
ERR_FAIL_COND_V(!rd, 0);
const uint8_t *r = &rd[p_ofs];
uint32_t type = decode_uint32(r);
if (type == TYPE_ARRAY) {
-
uint32_t len = decode_uint32(r + 4);
return len;
} else if (type == TYPE_DICT) {
-
uint32_t len = decode_uint32(r + 4);
return len;
- };
+ }
return -1;
-};
+}
Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, bool &err) const {
-
const uint8_t *rd = data.ptr();
const uint8_t *r = &rd[p_ofs];
uint32_t type = decode_uint32(r);
if (type == TYPE_ARRAY) {
-
if (p_key.is_num()) {
-
int idx = p_key;
int len = decode_uint32(r + 4);
if (idx < 0 || idx >= len) {
@@ -180,7 +166,6 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, b
}
} else if (type == TYPE_DICT) {
-
uint32_t hash = p_key.hash();
uint32_t len = decode_uint32(r + 4);
@@ -189,16 +174,18 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, b
uint32_t khash = decode_uint32(r + 8 + i * 12 + 0);
if (khash == hash) {
Variant key = _get_at_ofs(decode_uint32(r + 8 + i * 12 + 4), rd, err);
- if (err)
+ if (err) {
return Variant();
+ }
if (key == p_key) {
//key matches, return value
return _get_at_ofs(decode_uint32(r + 8 + i * 12 + 8), rd, err);
}
found = true;
} else {
- if (found)
+ if (found) {
break;
+ }
}
}
@@ -206,18 +193,14 @@ Variant PackedDataContainer::_key_at_ofs(uint32_t p_ofs, const Variant &p_key, b
return Variant();
} else {
-
err = true;
return Variant();
}
}
uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpdata, Map<String, uint32_t> &string_cache) {
-
switch (p_data.get_type()) {
-
case Variant::STRING: {
-
String s = p_data;
if (string_cache.has(s)) {
return string_cache[s];
@@ -251,7 +234,6 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
case Variant::PACKED_COLOR_ARRAY:
case Variant::STRING_NAME:
case Variant::NODE_PATH: {
-
uint32_t pos = tmpdata.size();
int len;
encode_variant(p_data, nullptr, len, false);
@@ -263,11 +245,9 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
// misc types
case Variant::_RID:
case Variant::OBJECT: {
-
return _pack(Variant(), tmpdata, string_cache);
} break;
case Variant::DICTIONARY: {
-
Dictionary d = p_data;
//size is known, use sort
uint32_t pos = tmpdata.size();
@@ -281,7 +261,6 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
List<DictKey> sortk;
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
DictKey dk;
dk.hash = E->get().hash();
dk.key = E->get();
@@ -292,7 +271,6 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
int idx = 0;
for (List<DictKey>::Element *E = sortk.front(); E; E = E->next()) {
-
encode_uint32(E->get().hash, &tmpdata.write[pos + 8 + idx * 12 + 0]);
uint32_t ofs = _pack(E->get().key, tmpdata, string_cache);
encode_uint32(ofs, &tmpdata.write[pos + 8 + idx * 12 + 4]);
@@ -305,7 +283,6 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
} break;
case Variant::ARRAY: {
-
Array a = p_data;
//size is known, use sort
uint32_t pos = tmpdata.size();
@@ -315,7 +292,6 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
encode_uint32(len, &tmpdata.write[pos + 4]);
for (int i = 0; i < len; i++) {
-
uint32_t ofs = _pack(a[i], tmpdata, string_cache);
encode_uint32(ofs, &tmpdata.write[pos + 8 + i * 4]);
}
@@ -332,7 +308,6 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
}
Error PackedDataContainer::pack(const Variant &p_data) {
-
Vector<uint8_t> tmpdata;
Map<String, uint32_t> string_cache;
_pack(p_data, tmpdata, string_cache);
@@ -345,7 +320,6 @@ Error PackedDataContainer::pack(const Variant &p_data) {
}
void PackedDataContainer::_set_data(const Vector<uint8_t> &p_data) {
-
data = p_data;
datalen = data.size();
}
@@ -355,21 +329,18 @@ Vector<uint8_t> PackedDataContainer::_get_data() const {
}
Variant PackedDataContainer::_iter_init(const Array &p_iter) {
-
return _iter_init_ofs(p_iter, 0);
}
Variant PackedDataContainer::_iter_next(const Array &p_iter) {
-
return _iter_next_ofs(p_iter, 0);
}
-Variant PackedDataContainer::_iter_get(const Variant &p_iter) {
+Variant PackedDataContainer::_iter_get(const Variant &p_iter) {
return _iter_get_ofs(p_iter, 0);
}
void PackedDataContainer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_set_data"), &PackedDataContainer::_set_data);
ClassDB::bind_method(D_METHOD("_get_data"), &PackedDataContainer::_get_data);
ClassDB::bind_method(D_METHOD("_iter_init"), &PackedDataContainer::_iter_init);
@@ -381,34 +352,25 @@ void PackedDataContainer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "__data__"), "_set_data", "_get_data");
}
-PackedDataContainer::PackedDataContainer() {
-
- datalen = 0;
-}
-
//////////////////
Variant PackedDataContainerRef::_iter_init(const Array &p_iter) {
-
return from->_iter_init_ofs(p_iter, offset);
}
Variant PackedDataContainerRef::_iter_next(const Array &p_iter) {
-
return from->_iter_next_ofs(p_iter, offset);
}
-Variant PackedDataContainerRef::_iter_get(const Variant &p_iter) {
+Variant PackedDataContainerRef::_iter_get(const Variant &p_iter) {
return from->_iter_get_ofs(p_iter, offset);
}
bool PackedDataContainerRef::_is_dictionary() const {
-
return from->_type_at_ofs(offset) == PackedDataContainer::TYPE_DICT;
-};
+}
void PackedDataContainerRef::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("size"), &PackedDataContainerRef::size);
ClassDB::bind_method(D_METHOD("_iter_init"), &PackedDataContainerRef::_iter_init);
ClassDB::bind_method(D_METHOD("_iter_get"), &PackedDataContainerRef::_iter_get);
@@ -417,18 +379,14 @@ void PackedDataContainerRef::_bind_methods() {
}
Variant PackedDataContainerRef::getvar(const Variant &p_key, bool *r_valid) const {
-
bool err = false;
Variant ret = from->_key_at_ofs(offset, p_key, err);
- if (r_valid)
+ if (r_valid) {
*r_valid = !err;
+ }
return ret;
}
int PackedDataContainerRef::size() const {
-
return from->_size(offset);
-};
-
-PackedDataContainerRef::PackedDataContainerRef() {
}
diff --git a/core/packed_data_container.h b/core/packed_data_container.h
index 0f08a1cb7b..b41e9aaefc 100644
--- a/core/packed_data_container.h
+++ b/core/packed_data_container.h
@@ -34,7 +34,6 @@
#include "core/resource.h"
class PackedDataContainer : public Resource {
-
GDCLASS(PackedDataContainer, Resource);
enum {
@@ -49,7 +48,7 @@ class PackedDataContainer : public Resource {
};
Vector<uint8_t> data;
- int datalen;
+ int datalen = 0;
uint32_t _pack(const Variant &p_data, Vector<uint8_t> &tmpdata, Map<String, uint32_t> &string_cache);
@@ -78,7 +77,7 @@ public:
int size() const;
- PackedDataContainer();
+ PackedDataContainer() {}
};
class PackedDataContainerRef : public Reference {
@@ -100,7 +99,7 @@ public:
int size() const;
virtual Variant getvar(const Variant &p_key, bool *r_valid = nullptr) const;
- PackedDataContainerRef();
+ PackedDataContainerRef() {}
};
#endif // PACKED_DATA_CONTAINER_H
diff --git a/core/pair.h b/core/pair.h
index 26a317e9d4..89ea2b9fd9 100644
--- a/core/pair.h
+++ b/core/pair.h
@@ -33,7 +33,6 @@
template <class F, class S>
struct Pair {
-
F first;
S second;
@@ -60,7 +59,6 @@ bool operator!=(const Pair<F, S> &pair, const Pair<F, S> &other) {
template <class F, class S>
struct PairSort {
-
bool operator()(const Pair<F, S> &A, const Pair<F, S> &B) const {
return A.first < B.first;
}
diff --git a/core/pool_allocator.cpp b/core/pool_allocator.cpp
index b74540395c..b222c20a00 100644
--- a/core/pool_allocator.cpp
+++ b/core/pool_allocator.cpp
@@ -53,12 +53,11 @@ void PoolAllocator::mt_unlock() const {
}
bool PoolAllocator::get_free_entry(EntryArrayPos *p_pos) {
-
- if (entry_count == entry_max)
+ if (entry_count == entry_max) {
return false;
+ }
for (int i = 0; i < entry_max; i++) {
-
if (entry_array[i].len == 0) {
*p_pos = i;
return true;
@@ -77,13 +76,11 @@ bool PoolAllocator::get_free_entry(EntryArrayPos *p_pos) {
* @return false if hole found, true if no hole found
*/
bool PoolAllocator::find_hole(EntryArrayPos *p_pos, int p_for_size) {
-
/* position where previous entry ends. Defaults to zero (begin of pool) */
int prev_entry_end_pos = 0;
for (int i = 0; i < entry_count; i++) {
-
Entry &entry = entry_array[entry_indices[i]];
/* determine hole size to previous entry */
@@ -111,13 +108,12 @@ bool PoolAllocator::find_hole(EntryArrayPos *p_pos, int p_for_size) {
}
void PoolAllocator::compact(int p_up_to) {
-
uint32_t prev_entry_end_pos = 0;
- if (p_up_to < 0)
+ if (p_up_to < 0) {
p_up_to = entry_count;
+ }
for (int i = 0; i < p_up_to; i++) {
-
Entry &entry = entry_array[entry_indices[i]];
/* determine hole size to previous entry */
@@ -126,7 +122,6 @@ void PoolAllocator::compact(int p_up_to) {
/* if we can compact, do it */
if (hole_size > 0 && !entry.lock) {
-
COMPACT_CHUNK(entry, prev_entry_end_pos);
}
@@ -136,11 +131,9 @@ void PoolAllocator::compact(int p_up_to) {
}
void PoolAllocator::compact_up(int p_from) {
-
uint32_t next_entry_end_pos = pool_size; // - static_area_size;
for (int i = entry_count - 1; i >= p_from; i--) {
-
Entry &entry = entry_array[entry_indices[i]];
/* determine hole size to nextious entry */
@@ -149,7 +142,6 @@ void PoolAllocator::compact_up(int p_from) {
/* if we can compact, do it */
if (hole_size > 0 && !entry.lock) {
-
COMPACT_CHUNK(entry, (next_entry_end_pos - aligned(entry.len)));
}
@@ -159,30 +151,29 @@ void PoolAllocator::compact_up(int p_from) {
}
bool PoolAllocator::find_entry_index(EntryIndicesPos *p_map_pos, Entry *p_entry) {
-
EntryArrayPos entry_pos = entry_max;
for (int i = 0; i < entry_count; i++) {
-
if (&entry_array[entry_indices[i]] == p_entry) {
-
entry_pos = i;
break;
}
}
- if (entry_pos == entry_max)
+ if (entry_pos == entry_max) {
return false;
+ }
*p_map_pos = entry_pos;
return true;
}
PoolAllocator::ID PoolAllocator::alloc(int p_size) {
-
ERR_FAIL_COND_V(p_size < 1, POOL_ALLOCATOR_INVALID_ID);
#ifdef DEBUG_ENABLED
- if (p_size > free_mem) OS::get_singleton()->debug_break();
+ if (p_size > free_mem) {
+ OS::get_singleton()->debug_break();
+ }
#endif
ERR_FAIL_COND_V(p_size > free_mem, POOL_ALLOCATOR_INVALID_ID);
@@ -220,7 +211,6 @@ PoolAllocator::ID PoolAllocator::alloc(int p_size) {
/* move all entry indices up, make room for this one */
for (int i = entry_count; i > new_entry_indices_pos; i--) {
-
entry_indices[i] = entry_indices[i - 1];
}
@@ -235,8 +225,9 @@ PoolAllocator::ID PoolAllocator::alloc(int p_size) {
entry.lock = 0;
entry.check = (check_count++) & CHECK_MASK;
free_mem -= size_to_alloc;
- if (free_mem < free_mem_peak)
+ if (free_mem < free_mem_peak) {
free_mem_peak = free_mem;
+ }
ID retval = (entry_indices[new_entry_indices_pos] << CHECK_BITS) | entry.check;
mt_unlock();
@@ -247,7 +238,6 @@ PoolAllocator::ID PoolAllocator::alloc(int p_size) {
}
PoolAllocator::Entry *PoolAllocator::get_entry(ID p_mem) {
-
unsigned int check = p_mem & CHECK_MASK;
int entry = p_mem >> CHECK_BITS;
ERR_FAIL_INDEX_V(entry, entry_max, nullptr);
@@ -258,7 +248,6 @@ PoolAllocator::Entry *PoolAllocator::get_entry(ID p_mem) {
}
const PoolAllocator::Entry *PoolAllocator::get_entry(ID p_mem) const {
-
unsigned int check = p_mem & CHECK_MASK;
int entry = p_mem >> CHECK_BITS;
ERR_FAIL_INDEX_V(entry, entry_max, nullptr);
@@ -269,7 +258,6 @@ const PoolAllocator::Entry *PoolAllocator::get_entry(ID p_mem) const {
}
void PoolAllocator::free(ID p_mem) {
-
mt_lock();
Entry *e = get_entry(p_mem);
if (!e) {
@@ -287,13 +275,11 @@ void PoolAllocator::free(ID p_mem) {
bool index_found = find_entry_index(&entry_indices_pos, e);
if (!index_found) {
-
mt_unlock();
ERR_FAIL_COND(!index_found);
}
for (int i = entry_indices_pos; i < (entry_count - 1); i++) {
-
entry_indices[i] = entry_indices[i + 1];
}
@@ -304,13 +290,11 @@ void PoolAllocator::free(ID p_mem) {
}
int PoolAllocator::get_size(ID p_mem) const {
-
int size;
mt_lock();
const Entry *e = get_entry(p_mem);
if (!e) {
-
mt_unlock();
ERR_PRINT("!e");
return 0;
@@ -324,7 +308,6 @@ int PoolAllocator::get_size(ID p_mem) const {
}
Error PoolAllocator::resize(ID p_mem, int p_new_size) {
-
mt_lock();
Entry *e = get_entry(p_mem);
@@ -341,12 +324,10 @@ Error PoolAllocator::resize(ID p_mem, int p_new_size) {
uint32_t alloc_size = aligned(p_new_size);
if ((uint32_t)aligned(e->len) == alloc_size) {
-
e->len = p_new_size;
mt_unlock();
return OK;
} else if (e->len > (uint32_t)p_new_size) {
-
free_mem += aligned(e->len);
free_mem -= alloc_size;
e->len = p_new_size;
@@ -360,14 +341,13 @@ Error PoolAllocator::resize(ID p_mem, int p_new_size) {
if (uint32_t(_free + aligned(e->len)) < alloc_size) {
mt_unlock();
ERR_FAIL_V(ERR_OUT_OF_MEMORY);
- };
+ }
EntryIndicesPos entry_indices_pos;
bool index_found = find_entry_index(&entry_indices_pos, e);
if (!index_found) {
-
mt_unlock();
ERR_FAIL_COND_V(!index_found, ERR_BUG);
}
@@ -378,7 +358,7 @@ Error PoolAllocator::resize(ID p_mem, int p_new_size) {
next_pos = pool_size; // - static_area_size;
} else {
next_pos = entry_array[entry_indices[entry_indices_pos + 1]].pos;
- };
+ }
if ((next_pos - e->pos) > alloc_size) {
free_mem += aligned(e->len);
@@ -397,8 +377,9 @@ Error PoolAllocator::resize(ID p_mem, int p_new_size) {
e->len = p_new_size;
free_mem -= alloc_size;
mt_unlock();
- if (free_mem < free_mem_peak)
+ if (free_mem < free_mem_peak) {
free_mem_peak = free_mem;
+ }
return OK;
}
@@ -412,8 +393,9 @@ Error PoolAllocator::resize(ID p_mem, int p_new_size) {
e->len = p_new_size;
free_mem -= alloc_size;
mt_unlock();
- if (free_mem < free_mem_peak)
+ if (free_mem < free_mem_peak) {
free_mem_peak = free_mem;
+ }
return OK;
}
@@ -422,13 +404,12 @@ Error PoolAllocator::resize(ID p_mem, int p_new_size) {
}
Error PoolAllocator::lock(ID p_mem) {
-
- if (!needs_locking)
+ if (!needs_locking) {
return OK;
+ }
mt_lock();
Entry *e = get_entry(p_mem);
if (!e) {
-
mt_unlock();
ERR_PRINT("!e");
return ERR_INVALID_PARAMETER;
@@ -439,14 +420,13 @@ Error PoolAllocator::lock(ID p_mem) {
}
bool PoolAllocator::is_locked(ID p_mem) const {
-
- if (!needs_locking)
+ if (!needs_locking) {
return false;
+ }
mt_lock();
const Entry *e = ((PoolAllocator *)(this))->get_entry(p_mem);
if (!e) {
-
mt_unlock();
ERR_PRINT("!e");
return false;
@@ -457,9 +437,7 @@ bool PoolAllocator::is_locked(ID p_mem) const {
}
const void *PoolAllocator::get(ID p_mem) const {
-
if (!needs_locking) {
-
const Entry *e = get_entry(p_mem);
ERR_FAIL_COND_V(!e, nullptr);
return &pool[e->pos];
@@ -469,19 +447,16 @@ const void *PoolAllocator::get(ID p_mem) const {
const Entry *e = get_entry(p_mem);
if (!e) {
-
mt_unlock();
ERR_FAIL_COND_V(!e, nullptr);
}
if (e->lock == 0) {
-
mt_unlock();
ERR_PRINT("e->lock == 0");
return nullptr;
}
if ((int)e->pos >= pool_size) {
-
mt_unlock();
ERR_PRINT("e->pos<0 || e->pos>=pool_size");
return nullptr;
@@ -494,9 +469,7 @@ const void *PoolAllocator::get(ID p_mem) const {
}
void *PoolAllocator::get(ID p_mem) {
-
if (!needs_locking) {
-
Entry *e = get_entry(p_mem);
ERR_FAIL_COND_V(!e, nullptr);
return &pool[e->pos];
@@ -506,12 +479,10 @@ void *PoolAllocator::get(ID p_mem) {
Entry *e = get_entry(p_mem);
if (!e) {
-
mt_unlock();
ERR_FAIL_COND_V(!e, nullptr);
}
if (e->lock == 0) {
-
//assert(0);
mt_unlock();
ERR_PRINT("e->lock == 0");
@@ -519,7 +490,6 @@ void *PoolAllocator::get(ID p_mem) {
}
if ((int)e->pos >= pool_size) {
-
mt_unlock();
ERR_PRINT("e->pos<0 || e->pos>=pool_size");
return nullptr;
@@ -530,10 +500,11 @@ void *PoolAllocator::get(ID p_mem) {
return ptr;
}
-void PoolAllocator::unlock(ID p_mem) {
- if (!needs_locking)
+void PoolAllocator::unlock(ID p_mem) {
+ if (!needs_locking) {
return;
+ }
mt_lock();
Entry *e = get_entry(p_mem);
if (!e) {
@@ -550,22 +521,18 @@ void PoolAllocator::unlock(ID p_mem) {
}
int PoolAllocator::get_used_mem() const {
-
return pool_size - free_mem;
}
int PoolAllocator::get_free_peak() {
-
return free_mem_peak;
}
int PoolAllocator::get_free_mem() {
-
return free_mem;
}
void PoolAllocator::create_pool(void *p_mem, int p_size, int p_max_entries) {
-
pool = (uint8_t *)p_mem;
pool_size = p_size;
@@ -581,7 +548,6 @@ void PoolAllocator::create_pool(void *p_mem, int p_size, int p_max_entries) {
}
PoolAllocator::PoolAllocator(int p_size, bool p_needs_locking, int p_max_entries) {
-
mem_ptr = memalloc(p_size);
ERR_FAIL_COND(!mem_ptr);
align = 1;
@@ -590,9 +556,7 @@ PoolAllocator::PoolAllocator(int p_size, bool p_needs_locking, int p_max_entries
}
PoolAllocator::PoolAllocator(void *p_mem, int p_size, int p_align, bool p_needs_locking, int p_max_entries) {
-
if (p_align > 1) {
-
uint8_t *mem8 = (uint8_t *)p_mem;
uint64_t ofs = (uint64_t)mem8;
if (ofs % p_align) {
@@ -600,8 +564,8 @@ PoolAllocator::PoolAllocator(void *p_mem, int p_size, int p_align, bool p_needs_
mem8 += p_align - (ofs % p_align);
p_size -= dif;
p_mem = (void *)mem8;
- };
- };
+ }
+ }
create_pool(p_mem, p_size, p_max_entries);
needs_locking = p_needs_locking;
@@ -610,22 +574,22 @@ PoolAllocator::PoolAllocator(void *p_mem, int p_size, int p_align, bool p_needs_
}
PoolAllocator::PoolAllocator(int p_align, int p_size, bool p_needs_locking, int p_max_entries) {
-
ERR_FAIL_COND(p_align < 1);
mem_ptr = Memory::alloc_static(p_size + p_align, true);
uint8_t *mem8 = (uint8_t *)mem_ptr;
uint64_t ofs = (uint64_t)mem8;
- if (ofs % p_align)
+ if (ofs % p_align) {
mem8 += p_align - (ofs % p_align);
+ }
create_pool(mem8, p_size, p_max_entries);
needs_locking = p_needs_locking;
align = p_align;
}
PoolAllocator::~PoolAllocator() {
-
- if (mem_ptr)
+ if (mem_ptr) {
memfree(mem_ptr);
+ }
memdelete_arr(entry_array);
memdelete_arr(entry_indices);
diff --git a/core/pool_allocator.h b/core/pool_allocator.h
index 8c1710ebe0..7d77af6266 100644
--- a/core/pool_allocator.h
+++ b/core/pool_allocator.h
@@ -60,11 +60,10 @@ private:
};
struct Entry {
-
- unsigned int pos;
- unsigned int len;
- unsigned int lock;
- unsigned int check;
+ unsigned int pos = 0;
+ unsigned int len = 0;
+ unsigned int lock = 0;
+ unsigned int check = 0;
inline void clear() {
pos = 0;
@@ -72,7 +71,7 @@ private:
lock = 0;
check = 0;
}
- Entry() { clear(); }
+ Entry() {}
};
typedef int EntryArrayPos;
@@ -99,10 +98,10 @@ private:
return p_entry.pos + aligned(p_entry.len);
}
inline int aligned(int p_size) const {
-
int rem = p_size % align;
- if (rem)
+ if (rem) {
p_size += align - rem;
+ }
return p_size;
}
diff --git a/core/print_string.cpp b/core/print_string.cpp
index 8eb1d9e86a..54de229471 100644
--- a/core/print_string.cpp
+++ b/core/print_string.cpp
@@ -39,7 +39,6 @@ bool _print_line_enabled = true;
bool _print_error_enabled = true;
void add_print_handler(PrintHandlerList *p_handler) {
-
_global_lock();
p_handler->next = print_handler_list;
print_handler_list = p_handler;
@@ -47,20 +46,18 @@ void add_print_handler(PrintHandlerList *p_handler) {
}
void remove_print_handler(PrintHandlerList *p_handler) {
-
_global_lock();
PrintHandlerList *prev = nullptr;
PrintHandlerList *l = print_handler_list;
while (l) {
-
if (l == p_handler) {
-
- if (prev)
+ if (prev) {
prev->next = l->next;
- else
+ } else {
print_handler_list = l->next;
+ }
break;
}
prev = l;
@@ -73,16 +70,15 @@ void remove_print_handler(PrintHandlerList *p_handler) {
}
void print_line(String p_string) {
-
- if (!_print_line_enabled)
+ if (!_print_line_enabled) {
return;
+ }
OS::get_singleton()->print("%s\n", p_string.utf8().get_data());
_global_lock();
PrintHandlerList *l = print_handler_list;
while (l) {
-
l->printfunc(l->userdata, p_string, false);
l = l->next;
}
@@ -91,16 +87,15 @@ void print_line(String p_string) {
}
void print_error(String p_string) {
-
- if (!_print_error_enabled)
+ if (!_print_error_enabled) {
return;
+ }
OS::get_singleton()->printerr("%s\n", p_string.utf8().get_data());
_global_lock();
PrintHandlerList *l = print_handler_list;
while (l) {
-
l->printfunc(l->userdata, p_string, true);
l = l->next;
}
@@ -109,7 +104,6 @@ void print_error(String p_string) {
}
void print_verbose(String p_string) {
-
if (OS::get_singleton()->is_stdout_verbose()) {
print_line(p_string);
}
diff --git a/core/print_string.h b/core/print_string.h
index d83cc35dd6..4d03f4a6de 100644
--- a/core/print_string.h
+++ b/core/print_string.h
@@ -38,17 +38,12 @@ extern void (*_print_func)(String);
typedef void (*PrintHandlerFunc)(void *, const String &p_string, bool p_error);
struct PrintHandlerList {
+ PrintHandlerFunc printfunc = nullptr;
+ void *userdata = nullptr;
- PrintHandlerFunc printfunc;
- void *userdata;
+ PrintHandlerList *next = nullptr;
- PrintHandlerList *next;
-
- PrintHandlerList() {
- printfunc = 0;
- next = 0;
- userdata = 0;
- }
+ PrintHandlerList() {}
};
void add_print_handler(PrintHandlerList *p_handler);
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 201ab8e90a..83d94ad607 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -46,30 +46,28 @@
ProjectSettings *ProjectSettings::singleton = nullptr;
ProjectSettings *ProjectSettings::get_singleton() {
-
return singleton;
}
String ProjectSettings::get_resource_path() const {
-
return resource_path;
-};
+}
String ProjectSettings::localize_path(const String &p_path) const {
-
- if (resource_path == "")
+ if (resource_path == "") {
return p_path; //not initialized yet
+ }
if (p_path.begins_with("res://") || p_path.begins_with("user://") ||
- (p_path.is_abs_path() && !p_path.begins_with(resource_path)))
+ (p_path.is_abs_path() && !p_path.begins_with(resource_path))) {
return p_path.simplify_path();
+ }
DirAccess *dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
String path = p_path.replace("\\", "/").simplify_path();
if (dir->change_dir(path) == OK) {
-
String cwd = dir->get_current_dir();
cwd = cwd.replace("\\", "/");
@@ -89,59 +87,52 @@ String ProjectSettings::localize_path(const String &p_path) const {
if (!cwd.begins_with(res_path)) {
return p_path;
- };
+ }
return cwd.replace_first(res_path, "res://");
} else {
-
memdelete(dir);
int sep = path.find_last("/");
if (sep == -1) {
return "res://" + path;
- };
+ }
String parent = path.substr(0, sep);
String plocal = localize_path(parent);
if (plocal == "") {
return "";
- };
+ }
// Only strip the starting '/' from 'path' if its parent ('plocal') ends with '/'
if (plocal[plocal.length() - 1] == '/') {
sep += 1;
}
return plocal + path.substr(sep, path.size() - sep);
- };
+ }
}
void ProjectSettings::set_initial_value(const String &p_name, const Variant &p_value) {
-
ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + ".");
props[p_name].initial = p_value;
}
-void ProjectSettings::set_restart_if_changed(const String &p_name, bool p_restart) {
+void ProjectSettings::set_restart_if_changed(const String &p_name, bool p_restart) {
ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + ".");
props[p_name].restart_if_changed = p_restart;
}
String ProjectSettings::globalize_path(const String &p_path) const {
-
if (p_path.begins_with("res://")) {
-
if (resource_path != "") {
-
return p_path.replace("res:/", resource_path);
- };
+ }
return p_path.replace("res://", "");
} else if (p_path.begins_with("user://")) {
-
String data_dir = OS::get_singleton()->get_user_data_dir();
if (data_dir != "") {
-
return p_path.replace("user:/", data_dir);
- };
+ }
return p_path.replace("user://", "");
}
@@ -149,17 +140,14 @@ String ProjectSettings::globalize_path(const String &p_path) const {
}
bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) {
-
_THREAD_SAFE_METHOD_
- if (p_value.get_type() == Variant::NIL)
+ if (p_value.get_type() == Variant::NIL) {
props.erase(p_name);
- else {
-
+ } else {
if (p_name == CoreStringNames::get_singleton()->_custom_features) {
Vector<String> custom_feature_array = String(p_value).split(",");
for (int i = 0; i < custom_feature_array.size(); i++) {
-
custom_features.insert(custom_feature_array[i]);
}
return true;
@@ -180,15 +168,15 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) {
}
if (override_valid) {
-
feature_overrides[s[0]] = p_name;
}
}
}
if (props.has(p_name)) {
- if (!props[p_name].overridden)
+ if (!props[p_name].overridden) {
props[p_name].variant = p_value;
+ }
} else {
props[p_name] = VariantContainer(p_value, last_order++);
@@ -197,8 +185,8 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) {
return true;
}
-bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const {
+bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const {
_THREAD_SAFE_METHOD_
StringName name = p_name;
@@ -214,7 +202,6 @@ bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const {
}
struct _VCSort {
-
String name;
Variant::Type type;
int order;
@@ -224,26 +211,26 @@ struct _VCSort {
};
void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const {
-
_THREAD_SAFE_METHOD_
Set<_VCSort> vclist;
for (Map<StringName, VariantContainer>::Element *E = props.front(); E; E = E->next()) {
-
const VariantContainer *v = &E->get();
- if (v->hide_from_editor)
+ if (v->hide_from_editor) {
continue;
+ }
_VCSort vc;
vc.name = E->key();
vc.order = v->order;
vc.type = v->variant.get_type();
- if (vc.name.begins_with("input/") || vc.name.begins_with("import/") || vc.name.begins_with("export/") || vc.name.begins_with("/remap") || vc.name.begins_with("/locale") || vc.name.begins_with("/autoload"))
+ if (vc.name.begins_with("input/") || vc.name.begins_with("import/") || vc.name.begins_with("export/") || vc.name.begins_with("/remap") || vc.name.begins_with("/locale") || vc.name.begins_with("/autoload")) {
vc.flags = PROPERTY_USAGE_STORAGE;
- else
+ } else {
vc.flags = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE;
+ }
if (v->restart_if_changed) {
vc.flags |= PROPERTY_USAGE_RESTART_IF_CHANGED;
@@ -252,31 +239,33 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const {
}
for (Set<_VCSort>::Element *E = vclist.front(); E; E = E->next()) {
-
String prop_info_name = E->get().name;
int dot = prop_info_name.find(".");
- if (dot != -1)
+ if (dot != -1) {
prop_info_name = prop_info_name.substr(0, dot);
+ }
if (custom_prop_info.has(prop_info_name)) {
PropertyInfo pi = custom_prop_info[prop_info_name];
pi.name = E->get().name;
pi.usage = E->get().flags;
p_list->push_back(pi);
- } else
+ } else {
p_list->push_back(PropertyInfo(E->get().type, E->get().name, PROPERTY_HINT_NONE, "", E->get().flags));
+ }
}
}
-bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files, const String &p_destination) {
-
- if (PackedData::get_singleton()->is_disabled())
+bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files) {
+ if (PackedData::get_singleton()->is_disabled()) {
return false;
+ }
- bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files, p_destination) == OK;
+ bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files) == OK;
- if (!ok)
+ if (!ok) {
return false;
+ }
//if data.pck is found, all directory access will be from here
DirAccess::make_default<DirAccessPack>(DirAccess::ACCESS_RESOURCES);
@@ -286,7 +275,6 @@ bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_f
}
void ProjectSettings::_convert_to_last_version(int p_from_version) {
-
if (p_from_version <= 3) {
// Converts the actions from array to dictionary (array of events to dictionary with deadzone + events)
for (Map<StringName, ProjectSettings::VariantContainer>::Element *E = props.front(); E; E = E->next()) {
@@ -322,11 +310,9 @@ void ProjectSettings::_convert_to_last_version(int p_from_version) {
* If nothing was found, error out.
*/
Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, bool p_upwards) {
-
// If looking for files in a network client, use it directly
if (FileAccessNetworkClient::get_singleton()) {
-
Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary");
if (err == OK) {
// Optional, we don't mind if it fails
@@ -338,7 +324,6 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
// Attempt with a user-defined main pack first
if (p_main_pack != "") {
-
bool ok = _load_resource_pack(p_main_pack);
ERR_FAIL_COND_V_MSG(!ok, ERR_CANT_OPEN, "Cannot open resource pack '" + p_main_pack + "'.");
@@ -362,40 +347,29 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
// We need to test both possibilities as extensions for Linux binaries are optional
// (so both 'mygame.bin' and 'mygame' should be able to find 'mygame.pck').
- bool found = false;
-
String exec_dir = exec_path.get_base_dir();
String exec_filename = exec_path.get_file();
String exec_basename = exec_filename.get_basename();
- // Try to load data pack at the location of the executable
- // As mentioned above, we have two potential names to attempt
-
- if (_load_resource_pack(exec_dir.plus_file(exec_basename + ".pck")) ||
- _load_resource_pack(exec_dir.plus_file(exec_filename + ".pck"))) {
- found = true;
- } else {
- // If we couldn't find them next to the executable, we attempt
- // the current working directory. Same story, two tests.
- if (_load_resource_pack(exec_basename + ".pck") ||
- _load_resource_pack(exec_filename + ".pck")) {
- found = true;
- }
- }
+ // Attempt with PCK bundled into executable
+ bool found = _load_resource_pack(exec_path);
#ifdef OSX_ENABLED
- // Attempt to load PCK from macOS .app bundle resources
if (!found) {
- if (_load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().plus_file(exec_basename + ".pck"))) {
- found = true;
- }
+ // Attempt to load PCK from macOS .app bundle resources
+ found = _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().plus_file(exec_basename + ".pck"));
}
#endif
- // Attempt with PCK bundled into executable
if (!found) {
- if (_load_resource_pack(exec_path)) {
- found = true;
+ // Try to load data pack at the location of the executable
+ // As mentioned above, we have two potential names to attempt
+ found = _load_resource_pack(exec_dir.plus_file(exec_basename + ".pck")) || _load_resource_pack(exec_dir.plus_file(exec_filename + ".pck"));
+
+ if (!found) {
+ // If we couldn't find them next to the executable, we attempt
+ // the current working directory. Same story, two tests.
+ found = _load_resource_pack(exec_basename + ".pck") || _load_resource_pack(exec_filename + ".pck");
}
}
@@ -454,8 +428,9 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
if (p_upwards) {
// Try to load settings ascending through parent directories
d->change_dir("..");
- if (d->get_current_dir() == current_dir)
+ if (d->get_current_dir() == current_dir) {
break; // not doing anything useful
+ }
current_dir = d->get_current_dir();
} else {
break;
@@ -466,11 +441,13 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
resource_path = resource_path.replace("\\", "/"); // windows path to unix path just in case
memdelete(d);
- if (!found)
+ if (!found) {
return err;
+ }
- if (resource_path.length() && resource_path[resource_path.length() - 1] == '/')
+ if (resource_path.length() && resource_path[resource_path.length() - 1] == '/') {
resource_path = resource_path.substr(0, resource_path.length() - 1); // chop end
+ }
return OK;
}
@@ -488,19 +465,16 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo
}
bool ProjectSettings::has_setting(String p_var) const {
-
_THREAD_SAFE_METHOD_
return props.has(p_var);
}
void ProjectSettings::set_registering_order(bool p_enable) {
-
registering_order = p_enable;
}
Error ProjectSettings::_load_settings_binary(const String &p_path) {
-
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err != OK) {
@@ -510,7 +484,6 @@ Error ProjectSettings::_load_settings_binary(const String &p_path) {
uint8_t hdr[4];
f->get_buffer(hdr, 4);
if (hdr[0] != 'E' || hdr[1] != 'C' || hdr[2] != 'F' || hdr[3] != 'G') {
-
memdelete(f);
ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Corrupted header in binary project.binary (not ECFG).");
}
@@ -518,7 +491,6 @@ Error ProjectSettings::_load_settings_binary(const String &p_path) {
uint32_t count = f->get_32();
for (uint32_t i = 0; i < count; i++) {
-
uint32_t slen = f->get_32();
CharString cs;
cs.resize(slen + 1);
@@ -543,7 +515,6 @@ Error ProjectSettings::_load_settings_binary(const String &p_path) {
}
Error ProjectSettings::_load_settings_text(const String &p_path) {
-
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
@@ -566,7 +537,6 @@ Error ProjectSettings::_load_settings_text(const String &p_path) {
int config_version = 0;
while (true) {
-
assign = Variant();
next_tag.fields.clear();
next_tag.name = String();
@@ -605,7 +575,6 @@ Error ProjectSettings::_load_settings_text(const String &p_path) {
}
Error ProjectSettings::_load_settings_text_or_binary(const String &p_text_path, const String &p_bin_path) {
-
// Attempt first to load the text-based project.godot file
Error err_text = _load_settings_text(p_text_path);
if (err_text == OK) {
@@ -622,19 +591,16 @@ Error ProjectSettings::_load_settings_text_or_binary(const String &p_text_path,
}
int ProjectSettings::get_order(const String &p_name) const {
-
ERR_FAIL_COND_V_MSG(!props.has(p_name), -1, "Request for nonexistent project setting: " + p_name + ".");
return props[p_name].order;
}
void ProjectSettings::set_order(const String &p_name, int p_order) {
-
ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + ".");
props[p_name].order = p_order;
}
void ProjectSettings::set_builtin_order(const String &p_name) {
-
ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + ".");
if (props[p_name].order >= NO_BUILTIN_ORDER_BASE) {
props[p_name].order = last_builtin_order++;
@@ -642,18 +608,15 @@ void ProjectSettings::set_builtin_order(const String &p_name) {
}
void ProjectSettings::clear(const String &p_name) {
-
ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + ".");
props.erase(p_name);
}
Error ProjectSettings::save() {
-
return save_custom(get_resource_path().plus_file("project.godot"));
}
Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<String, List<String>> &props, const CustomMap &p_custom, const String &p_custom_features) {
-
Error err;
FileAccess *file = FileAccess::open(p_file, FileAccess::WRITE, &err);
ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't save project.binary at " + p_file + ".");
@@ -664,9 +627,7 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
int count = 0;
for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) {
-
for (List<String>::Element *F = E->get().front(); F; F = F->next()) {
-
count++;
}
}
@@ -701,33 +662,35 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
}
for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) {
-
for (List<String>::Element *F = E->get().front(); F; F = F->next()) {
-
String key = F->get();
- if (E->key() != "")
+ if (E->key() != "") {
key = E->key() + "/" + key;
+ }
Variant value;
- if (p_custom.has(key))
+ if (p_custom.has(key)) {
value = p_custom[key];
- else
+ } else {
value = get(key);
+ }
file->store_32(key.length());
file->store_string(key);
int len;
err = encode_variant(value, nullptr, len, true);
- if (err != OK)
+ if (err != OK) {
memdelete(file);
+ }
ERR_FAIL_COND_V_MSG(err != OK, ERR_INVALID_DATA, "Error when trying to encode Variant.");
Vector<uint8_t> buff;
buff.resize(len);
err = encode_variant(value, buff.ptrw(), len, true);
- if (err != OK)
+ if (err != OK) {
memdelete(file);
+ }
ERR_FAIL_COND_V_MSG(err != OK, ERR_INVALID_DATA, "Error when trying to encode Variant.");
file->store_32(len);
file->store_buffer(buff.ptr(), buff.size());
@@ -741,7 +704,6 @@ Error ProjectSettings::_save_settings_binary(const String &p_file, const Map<Str
}
Error ProjectSettings::_save_settings_text(const String &p_file, const Map<String, List<String>> &props, const CustomMap &p_custom, const String &p_custom_features) {
-
Error err;
FileAccess *file = FileAccess::open(p_file, FileAccess::WRITE, &err);
@@ -757,27 +719,30 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
file->store_line("");
file->store_string("config_version=" + itos(CONFIG_VERSION) + "\n");
- if (p_custom_features != String())
+ if (p_custom_features != String()) {
file->store_string("custom_features=\"" + p_custom_features + "\"\n");
+ }
file->store_string("\n");
for (Map<String, List<String>>::Element *E = props.front(); E; E = E->next()) {
-
- if (E != props.front())
+ if (E != props.front()) {
file->store_string("\n");
+ }
- if (E->key() != "")
+ if (E->key() != "") {
file->store_string("[" + E->key() + "]\n\n");
+ }
for (List<String>::Element *F = E->get().front(); F; F = F->next()) {
-
String key = F->get();
- if (E->key() != "")
+ if (E->key() != "") {
key = E->key() + "/" + key;
+ }
Variant value;
- if (p_custom.has(key))
+ if (p_custom.has(key)) {
value = p_custom[key];
- else
+ } else {
value = get(key);
+ }
String vstr;
VariantWriter::write_to_string(value, vstr);
@@ -794,39 +759,39 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
Error ProjectSettings::_save_custom_bnd(const String &p_file) { // add other params as dictionary and array?
return save_custom(p_file);
-};
+}
Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_custom, const Vector<String> &p_custom_features, bool p_merge_with_current) {
-
ERR_FAIL_COND_V_MSG(p_path == "", ERR_INVALID_PARAMETER, "Project settings save path cannot be empty.");
Set<_VCSort> vclist;
if (p_merge_with_current) {
for (Map<StringName, VariantContainer>::Element *G = props.front(); G; G = G->next()) {
-
const VariantContainer *v = &G->get();
- if (v->hide_from_editor)
+ if (v->hide_from_editor) {
continue;
+ }
- if (p_custom.has(G->key()))
+ if (p_custom.has(G->key())) {
continue;
+ }
_VCSort vc;
vc.name = G->key(); //*k;
vc.order = v->order;
vc.type = v->variant.get_type();
vc.flags = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE;
- if (v->variant == v->initial)
+ if (v->variant == v->initial) {
continue;
+ }
vclist.insert(vc);
}
}
for (const Map<String, Variant>::Element *E = p_custom.front(); E; E = E->next()) {
-
// Lookup global prop to store in the same order
Map<StringName, VariantContainer>::Element *global_prop = props.find(E->key());
@@ -841,16 +806,14 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
Map<String, List<String>> props;
for (Set<_VCSort>::Element *E = vclist.front(); E; E = E->next()) {
-
String category = E->get().name;
String name = E->get().name;
int div = category.find("/");
- if (div < 0)
+ if (div < 0) {
category = "";
- else {
-
+ } else {
category = category.substr(0, div);
name = name.substr(div + 1, name.size());
}
@@ -860,25 +823,24 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust
String custom_features;
for (int i = 0; i < p_custom_features.size(); i++) {
- if (i > 0)
+ if (i > 0) {
custom_features += ",";
+ }
String f = p_custom_features[i].strip_edges().replace("\"", "");
custom_features += f;
}
- if (p_path.ends_with(".godot"))
+ if (p_path.ends_with(".godot")) {
return _save_settings_text(p_path, props, p_custom, custom_features);
- else if (p_path.ends_with(".binary"))
+ } else if (p_path.ends_with(".binary")) {
return _save_settings_binary(p_path, props, p_custom, custom_features);
- else {
-
+ } else {
ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unknown config file format: " + p_path + ".");
}
}
Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restart_if_changed) {
-
Variant ret;
if (!ProjectSettings::get_singleton()->has_setting(p_var)) {
ProjectSettings::get_singleton()->set(p_var, p_default);
@@ -892,15 +854,14 @@ Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default, bool p_restar
}
Vector<String> ProjectSettings::get_optimizer_presets() const {
-
List<PropertyInfo> pi;
ProjectSettings::get_singleton()->get_property_list(&pi);
Vector<String> names;
for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
-
- if (!E->get().name.begins_with("optimizer_presets/"))
+ if (!E->get().name.begins_with("optimizer_presets/")) {
continue;
+ }
names.push_back(E->get().name.get_slicec('/', 1));
}
@@ -910,7 +871,6 @@ Vector<String> ProjectSettings::get_optimizer_presets() const {
}
void ProjectSettings::_add_property_info_bind(const Dictionary &p_info) {
-
ERR_FAIL_COND(!p_info.has("name"));
ERR_FAIL_COND(!p_info.has("type"));
@@ -920,16 +880,17 @@ void ProjectSettings::_add_property_info_bind(const Dictionary &p_info) {
pinfo.type = Variant::Type(p_info["type"].operator int());
ERR_FAIL_INDEX(pinfo.type, Variant::VARIANT_MAX);
- if (p_info.has("hint"))
+ if (p_info.has("hint")) {
pinfo.hint = PropertyHint(p_info["hint"].operator int());
- if (p_info.has("hint_string"))
+ }
+ if (p_info.has("hint_string")) {
pinfo.hint_string = p_info["hint_string"];
+ }
set_custom_property_info(pinfo.name, pinfo);
}
void ProjectSettings::set_custom_property_info(const String &p_prop, const PropertyInfo &p_info) {
-
ERR_FAIL_COND(!props.has(p_prop));
custom_prop_info[p_prop] = p_info;
custom_prop_info[p_prop].name = p_prop;
@@ -940,27 +901,25 @@ const Map<StringName, PropertyInfo> &ProjectSettings::get_custom_property_info()
}
void ProjectSettings::set_disable_feature_overrides(bool p_disable) {
-
disable_feature_overrides = p_disable;
}
bool ProjectSettings::is_using_datapack() const {
-
return using_datapack;
}
bool ProjectSettings::property_can_revert(const String &p_name) {
-
- if (!props.has(p_name))
+ if (!props.has(p_name)) {
return false;
+ }
return props[p_name].initial != props[p_name].variant;
}
Variant ProjectSettings::property_get_revert(const String &p_name) {
-
- if (!props.has(p_name))
+ if (!props.has(p_name)) {
return Variant();
+ }
return props[p_name].initial;
}
@@ -978,7 +937,6 @@ bool ProjectSettings::has_custom_feature(const String &p_feature) const {
}
void ProjectSettings::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("has_setting", "name"), &ProjectSettings::has_setting);
ClassDB::bind_method(D_METHOD("set_setting", "name", "value"), &ProjectSettings::set_setting);
ClassDB::bind_method(D_METHOD("get_setting", "name"), &ProjectSettings::get_setting);
@@ -990,7 +948,7 @@ void ProjectSettings::_bind_methods() {
ClassDB::bind_method(D_METHOD("localize_path", "path"), &ProjectSettings::localize_path);
ClassDB::bind_method(D_METHOD("globalize_path", "path"), &ProjectSettings::globalize_path);
ClassDB::bind_method(D_METHOD("save"), &ProjectSettings::save);
- ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files", "destination"), &ProjectSettings::_load_resource_pack, DEFVAL(true), DEFVAL(""));
+ ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files"), &ProjectSettings::_load_resource_pack, DEFVAL(true));
ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ProjectSettings::property_can_revert);
ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ProjectSettings::property_get_revert);
@@ -998,12 +956,7 @@ void ProjectSettings::_bind_methods() {
}
ProjectSettings::ProjectSettings() {
-
singleton = this;
- last_order = NO_BUILTIN_ORDER_BASE;
- last_builtin_order = 0;
- disable_feature_overrides = false;
- registering_order = true;
Array events;
Dictionary action;
@@ -1025,8 +978,9 @@ ProjectSettings::ProjectSettings() {
PackedStringArray extensions = PackedStringArray();
extensions.push_back("gd");
- if (Engine::get_singleton()->has_singleton("GodotSharp"))
+ if (Engine::get_singleton()->has_singleton("GodotSharp")) {
extensions.push_back("cs");
+ }
extensions.push_back("shader");
GLOBAL_DEF("editor/search_in_file_extensions", extensions);
@@ -1048,7 +1002,7 @@ ProjectSettings::ProjectSettings() {
key->set_keycode(KEY_SPACE);
events.push_back(key);
joyb.instance();
- joyb->set_button_index(JOY_BUTTON_0);
+ joyb->set_button_index(JOY_BUTTON_A);
events.push_back(joyb);
action["events"] = events;
GLOBAL_DEF("input/ui_accept", action);
@@ -1061,7 +1015,7 @@ ProjectSettings::ProjectSettings() {
key->set_keycode(KEY_SPACE);
events.push_back(key);
joyb.instance();
- joyb->set_button_index(JOY_BUTTON_3);
+ joyb->set_button_index(JOY_BUTTON_Y);
events.push_back(joyb);
action["events"] = events;
GLOBAL_DEF("input/ui_select", action);
@@ -1074,7 +1028,7 @@ ProjectSettings::ProjectSettings() {
key->set_keycode(KEY_ESCAPE);
events.push_back(key);
joyb.instance();
- joyb->set_button_index(JOY_BUTTON_1);
+ joyb->set_button_index(JOY_BUTTON_B);
events.push_back(joyb);
action["events"] = events;
GLOBAL_DEF("input/ui_cancel", action);
@@ -1108,7 +1062,7 @@ ProjectSettings::ProjectSettings() {
key->set_keycode(KEY_LEFT);
events.push_back(key);
joyb.instance();
- joyb->set_button_index(JOY_DPAD_LEFT);
+ joyb->set_button_index(JOY_BUTTON_DPAD_LEFT);
events.push_back(joyb);
action["events"] = events;
GLOBAL_DEF("input/ui_left", action);
@@ -1121,7 +1075,7 @@ ProjectSettings::ProjectSettings() {
key->set_keycode(KEY_RIGHT);
events.push_back(key);
joyb.instance();
- joyb->set_button_index(JOY_DPAD_RIGHT);
+ joyb->set_button_index(JOY_BUTTON_DPAD_RIGHT);
events.push_back(joyb);
action["events"] = events;
GLOBAL_DEF("input/ui_right", action);
@@ -1134,7 +1088,7 @@ ProjectSettings::ProjectSettings() {
key->set_keycode(KEY_UP);
events.push_back(key);
joyb.instance();
- joyb->set_button_index(JOY_DPAD_UP);
+ joyb->set_button_index(JOY_BUTTON_DPAD_UP);
events.push_back(joyb);
action["events"] = events;
GLOBAL_DEF("input/ui_up", action);
@@ -1147,7 +1101,7 @@ ProjectSettings::ProjectSettings() {
key->set_keycode(KEY_DOWN);
events.push_back(key);
joyb.instance();
- joyb->set_button_index(JOY_DPAD_DOWN);
+ joyb->set_button_index(JOY_BUTTON_DPAD_DOWN);
events.push_back(joyb);
action["events"] = events;
GLOBAL_DEF("input/ui_down", action);
@@ -1214,11 +1168,8 @@ ProjectSettings::ProjectSettings() {
Compression::gzip_level = GLOBAL_DEF("compression/formats/gzip/compression_level", Z_DEFAULT_COMPRESSION);
custom_prop_info["compression/formats/gzip/compression_level"] = PropertyInfo(Variant::INT, "compression/formats/gzip/compression_level", PROPERTY_HINT_RANGE, "-1,9,1");
-
- using_datapack = false;
}
ProjectSettings::~ProjectSettings() {
-
singleton = nullptr;
}
diff --git a/core/project_settings.h b/core/project_settings.h
index 6e6b2fe4c7..3ed80738a1 100644
--- a/core/project_settings.h
+++ b/core/project_settings.h
@@ -36,7 +36,6 @@
#include "core/set.h"
class ProjectSettings : public Object {
-
GDCLASS(ProjectSettings, Object);
_THREAD_SAFE_CLASS_
@@ -50,38 +49,31 @@ public:
protected:
struct VariantContainer {
- int order;
- bool persist;
+ int order = 0;
+ bool persist = false;
Variant variant;
Variant initial;
- bool hide_from_editor;
- bool overridden;
- bool restart_if_changed;
- VariantContainer() :
- order(0),
- persist(false),
- hide_from_editor(false),
- overridden(false),
- restart_if_changed(false) {
- }
+ bool hide_from_editor = false;
+ bool overridden = false;
+ bool restart_if_changed = false;
+
+ VariantContainer() {}
+
VariantContainer(const Variant &p_variant, int p_order, bool p_persist = false) :
order(p_order),
persist(p_persist),
- variant(p_variant),
- hide_from_editor(false),
- overridden(false),
- restart_if_changed(false) {
+ variant(p_variant) {
}
};
- bool registering_order;
- int last_order;
- int last_builtin_order;
+ bool registering_order = true;
+ int last_order = 0;
+ int last_builtin_order = NO_BUILTIN_ORDER_BASE;
Map<StringName, VariantContainer> props;
String resource_path;
Map<StringName, PropertyInfo> custom_prop_info;
- bool disable_feature_overrides;
- bool using_datapack;
+ bool disable_feature_overrides = false;
+ bool using_datapack = false;
List<String> input_presets;
Set<String> custom_features;
@@ -104,7 +96,7 @@ protected:
void _convert_to_last_version(int p_from_version);
- bool _load_resource_pack(const String &p_pack, bool p_replace_files = true, const String &p_destination = "");
+ bool _load_resource_pack(const String &p_pack, bool p_replace_files = true);
void _add_property_info_bind(const Dictionary &p_info);
diff --git a/core/reference.cpp b/core/reference.cpp
index dd65ccce69..d1dba0d9bf 100644
--- a/core/reference.cpp
+++ b/core/reference.cpp
@@ -33,22 +33,18 @@
#include "core/script_language.h"
bool Reference::init_ref() {
-
if (reference()) {
-
if (!is_referenced() && refcount_init.unref()) {
unreference(); // first referencing is already 1, so compensate for the ref above
}
return true;
} else {
-
return false;
}
}
void Reference::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("init_ref"), &Reference::init_ref);
ClassDB::bind_method(D_METHOD("reference"), &Reference::reference);
ClassDB::bind_method(D_METHOD("unreference"), &Reference::unreference);
@@ -59,7 +55,6 @@ int Reference::reference_get_count() const {
}
bool Reference::reference() {
-
uint32_t rc_val = refcount.refval();
bool success = rc_val != 0;
@@ -80,7 +75,6 @@ bool Reference::reference() {
}
bool Reference::unreference() {
-
uint32_t rc_val = refcount.unrefval();
bool die = rc_val == 0;
@@ -104,25 +98,21 @@ bool Reference::unreference() {
Reference::Reference() :
Object(true) {
-
refcount.init();
refcount_init.init();
}
-Reference::~Reference() {
-}
-
Variant WeakRef::get_ref() const {
-
- if (ref.is_null())
+ if (ref.is_null()) {
return Variant();
+ }
Object *obj = ObjectDB::get_instance(ref);
- if (!obj)
+ if (!obj) {
return Variant();
+ }
Reference *r = cast_to<Reference>(obj);
if (r) {
-
return REF(r);
}
@@ -134,14 +124,9 @@ void WeakRef::set_obj(Object *p_object) {
}
void WeakRef::set_ref(const REF &p_ref) {
-
ref = p_ref.is_valid() ? p_ref->get_instance_id() : ObjectID();
}
-WeakRef::WeakRef() {
-}
-
void WeakRef::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_ref"), &WeakRef::get_ref);
}
diff --git a/core/reference.h b/core/reference.h
index 30a93d82a6..f5794b0b67 100644
--- a/core/reference.h
+++ b/core/reference.h
@@ -36,7 +36,6 @@
#include "core/safe_refcount.h"
class Reference : public Object {
-
GDCLASS(Reference, Object);
SafeRefCount refcount;
SafeRefCount refcount_init;
@@ -52,32 +51,32 @@ public:
int reference_get_count() const;
Reference();
- ~Reference();
+ ~Reference() {}
};
template <class T>
class Ref {
-
- T *reference;
+ T *reference = nullptr;
void ref(const Ref &p_from) {
-
- if (p_from.reference == reference)
+ if (p_from.reference == reference) {
return;
+ }
unref();
reference = p_from.reference;
- if (reference)
+ if (reference) {
reference->reference();
+ }
}
void ref_pointer(T *p_ref) {
-
ERR_FAIL_COND(!p_ref);
- if (p_ref->init_ref())
+ if (p_ref->init_ref()) {
reference = p_ref;
+ }
}
//virtual Reference * get_reference() const { return reference; }
@@ -90,60 +89,48 @@ public:
}
_FORCE_INLINE_ bool operator<(const Ref<T> &p_r) const {
-
return reference < p_r.reference;
}
_FORCE_INLINE_ bool operator==(const Ref<T> &p_r) const {
-
return reference == p_r.reference;
}
_FORCE_INLINE_ bool operator!=(const Ref<T> &p_r) const {
-
return reference != p_r.reference;
}
_FORCE_INLINE_ T *operator->() {
-
return reference;
}
_FORCE_INLINE_ T *operator*() {
-
return reference;
}
_FORCE_INLINE_ const T *operator->() const {
-
return reference;
}
_FORCE_INLINE_ const T *ptr() const {
-
return reference;
}
_FORCE_INLINE_ T *ptr() {
-
return reference;
}
_FORCE_INLINE_ const T *operator*() const {
-
return reference;
}
operator Variant() const {
-
return Variant(reference);
}
void operator=(const Ref &p_from) {
-
ref(p_from);
}
template <class T_Other>
void operator=(const Ref<T_Other> &p_from) {
-
Reference *refb = const_cast<Reference *>(static_cast<const Reference *>(p_from.ptr()));
if (!refb) {
unref();
@@ -156,7 +143,6 @@ public:
}
void operator=(const Variant &p_variant) {
-
Object *object = p_variant.get_validated_object();
if (object == reference) {
@@ -189,15 +175,11 @@ public:
}
Ref(const Ref &p_from) {
-
- reference = nullptr;
ref(p_from);
}
template <class T_Other>
Ref(const Ref<T_Other> &p_from) {
-
- reference = nullptr;
Reference *refb = const_cast<Reference *>(static_cast<const Reference *>(p_from.ptr()));
if (!refb) {
unref();
@@ -210,26 +192,21 @@ public:
}
Ref(T *p_reference) {
-
- reference = nullptr;
- if (p_reference)
+ if (p_reference) {
ref_pointer(p_reference);
+ }
}
Ref(const Variant &p_variant) {
-
Object *object = p_variant.get_validated_object();
if (!object) {
- reference = nullptr;
return;
}
T *r = Object::cast_to<T>(object);
if (r && r->reference()) {
reference = r;
- } else {
- reference = nullptr;
}
}
@@ -242,7 +219,6 @@ public:
// mutexes will avoid more crashes?
if (reference && reference->unreference()) {
-
memdelete(reference);
}
reference = nullptr;
@@ -252,13 +228,9 @@ public:
ref(memnew(T));
}
- Ref() {
-
- reference = nullptr;
- }
+ Ref() {}
~Ref() {
-
unref();
}
};
@@ -266,7 +238,6 @@ public:
typedef Ref<Reference> REF;
class WeakRef : public Reference {
-
GDCLASS(WeakRef, Reference);
ObjectID ref;
@@ -279,30 +250,25 @@ public:
void set_obj(Object *p_object);
void set_ref(const REF &p_ref);
- WeakRef();
+ WeakRef() {}
};
#ifdef PTRCALL_ENABLED
template <class T>
struct PtrToArg<Ref<T>> {
-
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
-
return Ref<T>(const_cast<T *>(reinterpret_cast<const T *>(p_ptr)));
}
_FORCE_INLINE_ static void encode(Ref<T> p_val, const void *p_ptr) {
-
*(Ref<Reference> *)p_ptr = p_val;
}
};
template <class T>
struct PtrToArg<const Ref<T> &> {
-
_FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) {
-
return Ref<T>((T *)p_ptr);
}
};
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 905f43d61b..3870141ecf 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -38,7 +38,7 @@
#include "core/crypto/hashing_context.h"
#include "core/engine.h"
#include "core/func_ref.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/input/input_map.h"
#include "core/io/config_file.h"
#include "core/io/dtls_server.h"
@@ -65,7 +65,6 @@
#include "core/math/triangle_mesh.h"
#include "core/os/main_loop.h"
#include "core/packed_data_container.h"
-#include "core/path_remap.h"
#include "core/project_settings.h"
#include "core/translation.h"
#include "core/undo_redo.h"
@@ -98,7 +97,6 @@ extern void register_variant_methods();
extern void unregister_variant_methods();
void register_core_types() {
-
//consistency check
static_assert(sizeof(Callable) <= 16);
@@ -233,12 +231,11 @@ void register_core_settings() {
GLOBAL_DEF_RST("network/limits/packet_peer_stream/max_buffer_po2", (16));
ProjectSettings::get_singleton()->set_custom_property_info("network/limits/packet_peer_stream/max_buffer_po2", PropertyInfo(Variant::INT, "network/limits/packet_peer_stream/max_buffer_po2", PROPERTY_HINT_RANGE, "0,64,1,or_greater"));
- GLOBAL_DEF("network/ssl/certificates", "");
- ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt"));
+ GLOBAL_DEF("network/ssl/certificate_bundle_override", "");
+ ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificate_bundle_override", PropertyInfo(Variant::STRING, "network/ssl/certificate_bundle_override", PROPERTY_HINT_FILE, "*.crt"));
}
void register_core_singletons() {
-
ClassDB::register_class<ProjectSettings>();
ClassDB::register_virtual_class<IP>();
ClassDB::register_class<_Geometry>();
@@ -249,7 +246,7 @@ void register_core_singletons() {
ClassDB::register_class<_ClassDB>();
ClassDB::register_class<_Marshalls>();
ClassDB::register_class<TranslationServer>();
- ClassDB::register_virtual_class<InputFilter>();
+ ClassDB::register_virtual_class<Input>();
ClassDB::register_class<InputMap>();
ClassDB::register_class<_JSON>();
ClassDB::register_class<Expression>();
@@ -264,13 +261,12 @@ void register_core_singletons() {
Engine::get_singleton()->add_singleton(Engine::Singleton("ClassDB", _classdb));
Engine::get_singleton()->add_singleton(Engine::Singleton("Marshalls", _Marshalls::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("TranslationServer", TranslationServer::get_singleton()));
- Engine::get_singleton()->add_singleton(Engine::Singleton("Input", InputFilter::get_singleton()));
+ Engine::get_singleton()->add_singleton(Engine::Singleton("Input", Input::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("InputMap", InputMap::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("JSON", _JSON::get_singleton()));
}
void unregister_core_types() {
-
memdelete(_resource_loader);
memdelete(_resource_saver);
memdelete(_os);
@@ -301,8 +297,9 @@ void unregister_core_types() {
ResourceLoader::remove_resource_format_loader(resource_format_loader_crypto);
resource_format_loader_crypto.unref();
- if (ip)
+ if (ip) {
memdelete(ip);
+ }
ResourceLoader::finalize();
diff --git a/core/resource.cpp b/core/resource.cpp
index 8d5c441b21..0af8c9c2b3 100644
--- a/core/resource.cpp
+++ b/core/resource.cpp
@@ -39,7 +39,6 @@
#include <stdio.h>
void Resource::emit_changed() {
-
emit_signal(CoreStringNames::get_singleton()->changed);
}
@@ -47,12 +46,11 @@ void Resource::_resource_path_changed() {
}
void Resource::set_path(const String &p_path, bool p_take_over) {
-
- if (path_cache == p_path)
+ if (path_cache == p_path) {
return;
+ }
if (path_cache != "") {
-
ResourceCache::lock->write_lock();
ResourceCache::resources.erase(path_cache);
ResourceCache::lock->write_unlock();
@@ -66,7 +64,6 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
if (has_path) {
if (p_take_over) {
-
ResourceCache::lock->write_lock();
Resource **res = ResourceCache::resources.getptr(p_path);
if (res) {
@@ -84,7 +81,6 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
path_cache = p_path;
if (path_cache != "") {
-
ResourceCache::lock->write_lock();
ResourceCache::resources[path_cache] = this;
ResourceCache::lock->write_unlock();
@@ -95,62 +91,58 @@ void Resource::set_path(const String &p_path, bool p_take_over) {
}
String Resource::get_path() const {
-
return path_cache;
}
void Resource::set_subindex(int p_sub_index) {
-
subindex = p_sub_index;
}
int Resource::get_subindex() const {
-
return subindex;
}
void Resource::set_name(const String &p_name) {
-
name = p_name;
_change_notify("resource_name");
}
-String Resource::get_name() const {
+String Resource::get_name() const {
return name;
}
bool Resource::editor_can_reload_from_file() {
-
return true; //by default yes
}
void Resource::reload_from_file() {
-
String path = get_path();
- if (!path.is_resource_file())
+ if (!path.is_resource_file()) {
return;
+ }
Ref<Resource> s = ResourceLoader::load(ResourceLoader::path_remap(path), get_class(), true);
- if (!s.is_valid())
+ if (!s.is_valid()) {
return;
+ }
List<PropertyInfo> pi;
s->get_property_list(&pi);
for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
- if (E->get().name == "resource_path")
+ }
+ if (E->get().name == "resource_path") {
continue; //do not change path
+ }
set(E->get().name, s->get(E->get().name));
}
}
Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource>> &remap_cache) {
-
List<PropertyInfo> plist;
get_property_list(&plist);
@@ -160,20 +152,17 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res
r->local_scene = p_for_scene;
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
Variant p = get(E->get().name);
if (p.get_type() == Variant::OBJECT) {
-
RES sr = p;
if (sr.is_valid()) {
-
if (sr->is_local_to_scene()) {
if (remap_cache.has(sr)) {
p = remap_cache[sr];
} else {
-
RES dupe = sr->duplicate_for_local_scene(p_for_scene, remap_cache);
p = dupe;
remap_cache[sr] = dupe;
@@ -191,22 +180,19 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res
}
void Resource::configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource>> &remap_cache) {
-
List<PropertyInfo> plist;
get_property_list(&plist);
local_scene = p_for_scene;
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
Variant p = get(E->get().name);
if (p.get_type() == Variant::OBJECT) {
-
RES sr = p;
if (sr.is_valid()) {
-
if (sr->is_local_to_scene()) {
if (!remap_cache.has(sr)) {
sr->configure_for_local_scene(p_for_scene, remap_cache);
@@ -219,7 +205,6 @@ void Resource::configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, R
}
Ref<Resource> Resource::duplicate(bool p_subresources) const {
-
List<PropertyInfo> plist;
get_property_list(&plist);
@@ -227,21 +212,19 @@ Ref<Resource> Resource::duplicate(bool p_subresources) const {
ERR_FAIL_COND_V(!r, Ref<Resource>());
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
Variant p = get(E->get().name);
if ((p.get_type() == Variant::DICTIONARY || p.get_type() == Variant::ARRAY)) {
r->set(E->get().name, p.duplicate(p_subresources));
} else if (p.get_type() == Variant::OBJECT && (p_subresources || (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE))) {
-
RES sr = p;
if (sr.is_valid()) {
r->set(E->get().name, sr->duplicate(p_subresources));
}
} else {
-
r->set(E->get().name, p);
}
}
@@ -250,34 +233,27 @@ Ref<Resource> Resource::duplicate(bool p_subresources) const {
}
void Resource::_set_path(const String &p_path) {
-
set_path(p_path, false);
}
void Resource::_take_over_path(const String &p_path) {
-
set_path(p_path, true);
}
RID Resource::get_rid() const {
-
return RID();
}
void Resource::register_owner(Object *p_owner) {
-
owners.insert(p_owner->get_instance_id());
}
void Resource::unregister_owner(Object *p_owner) {
-
owners.erase(p_owner->get_instance_id());
}
void Resource::notify_change_to_owners() {
-
for (Set<ObjectID>::Element *E = owners.front(); E; E = E->next()) {
-
Object *obj = ObjectDB::get_instance(E->get());
ERR_CONTINUE_MSG(!obj, "Object was deleted, while still owning a resource."); //wtf
//TODO store string
@@ -288,14 +264,12 @@ void Resource::notify_change_to_owners() {
#ifdef TOOLS_ENABLED
uint32_t Resource::hash_edited_version() const {
-
uint32_t hash = hash_djb2_one_32(get_edited_version());
List<PropertyInfo> plist;
get_property_list(&plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
if (E->get().usage & PROPERTY_USAGE_STORAGE && E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE) {
RES res = get(E->get().name);
if (res.is_valid()) {
@@ -310,19 +284,17 @@ uint32_t Resource::hash_edited_version() const {
#endif
void Resource::set_local_to_scene(bool p_enable) {
-
local_to_scene = p_enable;
}
bool Resource::is_local_to_scene() const {
-
return local_to_scene;
}
Node *Resource::get_local_scene() const {
-
- if (local_scene)
+ if (local_scene) {
return local_scene;
+ }
if (_get_local_scene_func) {
return _get_local_scene_func();
@@ -332,17 +304,17 @@ Node *Resource::get_local_scene() const {
}
void Resource::setup_local_to_scene() {
-
- if (get_script_instance())
+ if (get_script_instance()) {
get_script_instance()->call("_setup_local_to_scene");
+ }
}
Node *(*Resource::_get_local_scene_func)() = nullptr;
void Resource::set_as_translation_remapped(bool p_remapped) {
-
- if (remapped_list.in_list() == p_remapped)
+ if (remapped_list.in_list() == p_remapped) {
return;
+ }
if (ResourceCache::lock) {
ResourceCache::lock->write_lock();
@@ -360,7 +332,6 @@ void Resource::set_as_translation_remapped(bool p_remapped) {
}
bool Resource::is_translation_remapped() const {
-
return remapped_list.in_list();
}
@@ -406,7 +377,6 @@ int Resource::get_id_for_path(const String &p_path) const {
#endif
void Resource::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_path", "path"), &Resource::_set_path);
ClassDB::bind_method(D_METHOD("take_over_path", "path"), &Resource::_take_over_path);
ClassDB::bind_method(D_METHOD("get_path"), &Resource::get_path);
@@ -429,20 +399,9 @@ void Resource::_bind_methods() {
}
Resource::Resource() :
- remapped_list(this) {
-
-#ifdef TOOLS_ENABLED
- last_modified_time = 0;
- import_last_modified_time = 0;
-#endif
-
- subindex = 0;
- local_to_scene = false;
- local_scene = nullptr;
-}
+ remapped_list(this) {}
Resource::~Resource() {
-
if (path_cache != "") {
ResourceCache::lock->write_lock();
ResourceCache::resources.erase(path_cache);
@@ -464,7 +423,6 @@ RWLock *ResourceCache::path_cache_lock = nullptr;
#endif
void ResourceCache::setup() {
-
lock = RWLock::create();
#ifdef TOOLS_ENABLED
path_cache_lock = RWLock::create();
@@ -472,8 +430,9 @@ void ResourceCache::setup() {
}
void ResourceCache::clear() {
- if (resources.size())
+ if (resources.size()) {
ERR_PRINT("Resources Still in use at Exit!");
+ }
resources.clear();
memdelete(lock);
@@ -483,7 +442,6 @@ void ResourceCache::clear() {
}
void ResourceCache::reload_externals() {
-
/*
const String *K=nullptr;
while ((K=resources.next(K))) {
@@ -493,15 +451,14 @@ void ResourceCache::reload_externals() {
}
bool ResourceCache::has(const String &p_path) {
-
lock->read_lock();
bool b = resources.has(p_path);
lock->read_unlock();
return b;
}
-Resource *ResourceCache::get(const String &p_path) {
+Resource *ResourceCache::get(const String &p_path) {
lock->read_lock();
Resource **res = resources.getptr(p_path);
@@ -516,11 +473,9 @@ Resource *ResourceCache::get(const String &p_path) {
}
void ResourceCache::get_cached_resources(List<Ref<Resource>> *p_resources) {
-
lock->read_lock();
const String *K = nullptr;
while ((K = resources.next(K))) {
-
Resource *r = resources[*K];
p_resources->push_back(Ref<Resource>(r));
}
@@ -528,7 +483,6 @@ void ResourceCache::get_cached_resources(List<Ref<Resource>> *p_resources) {
}
int ResourceCache::get_cached_resource_count() {
-
lock->read_lock();
int rc = resources.size();
lock->read_unlock();
@@ -550,7 +504,6 @@ void ResourceCache::dump(const char *p_file, bool p_short) {
const String *K = nullptr;
while ((K = resources.next(K))) {
-
Resource *r = resources[*K];
if (!type_count.has(r->get_class())) {
@@ -560,15 +513,16 @@ void ResourceCache::dump(const char *p_file, bool p_short) {
type_count[r->get_class()]++;
if (!p_short) {
- if (f)
+ if (f) {
f->store_line(r->get_class() + ": " + r->get_path());
+ }
}
}
for (Map<String, int>::Element *E = type_count.front(); E; E = E->next()) {
-
- if (f)
+ if (f) {
f->store_line(E->key() + " count: " + itos(E->get()));
+ }
}
if (f) {
f->close();
diff --git a/core/resource.h b/core/resource.h
index 3b7812c870..ad2f3ce913 100644
--- a/core/resource.h
+++ b/core/resource.h
@@ -45,7 +45,6 @@ public:
private:
class Resource : public Reference {
-
GDCLASS(Resource, Reference);
OBJ_CATEGORY("Resources");
RES_BASE_EXTENSION("res");
@@ -57,19 +56,19 @@ class Resource : public Reference {
String name;
String path_cache;
- int subindex;
+ int subindex = 0;
virtual bool _use_builtin_script() const { return true; }
#ifdef TOOLS_ENABLED
- uint64_t last_modified_time;
- uint64_t import_last_modified_time;
+ uint64_t last_modified_time = 0;
+ uint64_t import_last_modified_time = 0;
String import_path;
#endif
- bool local_to_scene;
+ bool local_to_scene = false;
friend class SceneState;
- Node *local_scene;
+ Node *local_scene = nullptr;
SelfList<Resource> remapped_list;
diff --git a/core/rid.h b/core/rid.h
index a2f73423a3..4b65f3fb6a 100644
--- a/core/rid.h
+++ b/core/rid.h
@@ -37,27 +37,22 @@ class RID_AllocBase;
class RID {
friend class RID_AllocBase;
- uint64_t _id;
+ uint64_t _id = 0;
public:
_FORCE_INLINE_ bool operator==(const RID &p_rid) const {
-
return _id == p_rid._id;
}
_FORCE_INLINE_ bool operator<(const RID &p_rid) const {
-
return _id < p_rid._id;
}
_FORCE_INLINE_ bool operator<=(const RID &p_rid) const {
-
return _id <= p_rid._id;
}
_FORCE_INLINE_ bool operator>(const RID &p_rid) const {
-
return _id > p_rid._id;
}
_FORCE_INLINE_ bool operator!=(const RID &p_rid) const {
-
return _id != p_rid._id;
}
_FORCE_INLINE_ bool is_valid() const { return _id != 0; }
@@ -65,9 +60,7 @@ public:
_FORCE_INLINE_ uint64_t get_id() const { return _id; }
- _FORCE_INLINE_ RID() {
- _id = 0;
- }
+ _FORCE_INLINE_ RID() {}
};
#endif // RID_H
diff --git a/core/rid_owner.h b/core/rid_owner.h
index ad6996b9a7..2489475c68 100644
--- a/core/rid_owner.h
+++ b/core/rid_owner.h
@@ -39,11 +39,11 @@
#include "core/safe_refcount.h"
#include "core/set.h"
#include "core/spin_lock.h"
+
#include <stdio.h>
#include <typeinfo>
class RID_AllocBase {
-
static volatile uint64_t base_id;
protected:
@@ -67,22 +67,20 @@ public:
template <class T, bool THREAD_SAFE = false>
class RID_Alloc : public RID_AllocBase {
-
- T **chunks;
- uint32_t **free_list_chunks;
- uint32_t **validator_chunks;
+ T **chunks = nullptr;
+ uint32_t **free_list_chunks = nullptr;
+ uint32_t **validator_chunks = nullptr;
uint32_t elements_in_chunk;
- uint32_t max_alloc;
- uint32_t alloc_count;
+ uint32_t max_alloc = 0;
+ uint32_t alloc_count = 0;
- const char *description;
+ const char *description = nullptr;
SpinLock spin_lock;
public:
RID make_rid(const T &p_value) {
-
if (THREAD_SAFE) {
spin_lock.lock();
}
@@ -136,7 +134,6 @@ public:
}
_FORCE_INLINE_ T *getornull(const RID &p_rid) {
-
if (THREAD_SAFE) {
spin_lock.lock();
}
@@ -171,7 +168,6 @@ public:
}
_FORCE_INLINE_ bool owns(const RID &p_rid) {
-
if (THREAD_SAFE) {
spin_lock.lock();
}
@@ -200,7 +196,6 @@ public:
}
_FORCE_INLINE_ void free(const RID &p_rid) {
-
if (THREAD_SAFE) {
spin_lock.lock();
}
@@ -288,14 +283,7 @@ public:
}
RID_Alloc(uint32_t p_target_chunk_byte_size = 4096) {
- chunks = nullptr;
- free_list_chunks = nullptr;
- validator_chunks = nullptr;
-
elements_in_chunk = sizeof(T) > p_target_chunk_byte_size ? 1 : (p_target_chunk_byte_size / sizeof(T));
- max_alloc = 0;
- alloc_count = 0;
- description = nullptr;
}
~RID_Alloc() {
@@ -412,4 +400,5 @@ public:
RID_Owner(uint32_t p_target_chunk_byte_size = 4096) :
alloc(p_target_chunk_byte_size) {}
};
+
#endif // RID_OWNER_H
diff --git a/core/ring_buffer.h b/core/ring_buffer.h
index 620a3a3846..6b71d12cf3 100644
--- a/core/ring_buffer.h
+++ b/core/ring_buffer.h
@@ -35,10 +35,9 @@
template <typename T>
class RingBuffer {
-
Vector<T> data;
- int read_pos;
- int write_pos;
+ int read_pos = 0;
+ int write_pos = 0;
int size_mask;
inline int inc(int &p_var, int p_size) const {
@@ -46,13 +45,13 @@ class RingBuffer {
p_var += p_size;
p_var = p_var & size_mask;
return ret;
- };
+ }
public:
T read() {
ERR_FAIL_COND_V(space_left() < 1, T());
return data.ptr()[inc(read_pos, 1)];
- };
+ }
int read(T *p_buf, int p_size, bool p_advance = true) {
int left = data_left();
@@ -67,23 +66,23 @@ public:
const T *read = data.ptr();
for (int i = 0; i < total; i++) {
p_buf[dst++] = read[pos + i];
- };
+ }
to_read -= total;
pos = 0;
- };
+ }
if (p_advance) {
inc(read_pos, p_size);
- };
+ }
return p_size;
- };
+ }
int copy(T *p_buf, int p_offset, int p_size) const {
-
int left = data_left();
if ((p_offset + p_size) > left) {
p_size -= left - p_offset;
- if (p_size <= 0)
+ if (p_size <= 0) {
return 0;
+ }
}
p_size = MIN(left, p_size);
int pos = read_pos;
@@ -96,20 +95,20 @@ public:
int total = end - pos;
for (int i = 0; i < total; i++) {
p_buf[dst++] = data[pos + i];
- };
+ }
to_read -= total;
pos = 0;
- };
+ }
return p_size;
- };
+ }
int find(const T &t, int p_offset, int p_max_size) const {
-
int left = data_left();
if ((p_offset + p_max_size) > left) {
p_max_size -= left - p_offset;
- if (p_max_size <= 0)
+ if (p_max_size <= 0) {
return 0;
+ }
}
p_max_size = MIN(left, p_max_size);
int pos = read_pos;
@@ -120,9 +119,10 @@ public:
end = MIN(end, size());
int total = end - pos;
for (int i = 0; i < total; i++) {
- if (data[pos + i] == t)
+ if (data[pos + i] == t) {
return i + (p_max_size - to_read);
- };
+ }
+ }
to_read -= total;
pos = 0;
}
@@ -133,7 +133,7 @@ public:
p_n = MIN(p_n, data_left());
inc(read_pos, p_n);
return p_n;
- };
+ }
inline int decrease_write(int p_n) {
p_n = MIN(p_n, data_left());
@@ -145,10 +145,9 @@ public:
ERR_FAIL_COND_V(space_left() < 1, FAILED);
data.write[inc(write_pos, 1)] = p_v;
return OK;
- };
+ }
int write(const T *p_buf, int p_size) {
-
int left = space_left();
p_size = MIN(left, p_size);
@@ -156,39 +155,38 @@ public:
int to_write = p_size;
int src = 0;
while (to_write) {
-
int end = pos + to_write;
end = MIN(end, size());
int total = end - pos;
for (int i = 0; i < total; i++) {
data.write[pos + i] = p_buf[src++];
- };
+ }
to_write -= total;
pos = 0;
- };
+ }
inc(write_pos, p_size);
return p_size;
- };
+ }
inline int space_left() const {
int left = read_pos - write_pos;
if (left < 0) {
return size() + left - 1;
- };
+ }
if (left == 0) {
return size() - 1;
- };
+ }
return left - 1;
- };
+ }
inline int data_left() const {
return size() - space_left() - 1;
- };
+ }
inline int size() const {
return data.size();
- };
+ }
inline void clear() {
read_pos = 0;
@@ -203,22 +201,20 @@ public:
if (old_size < new_size && read_pos > write_pos) {
for (int i = 0; i < write_pos; i++) {
data.write[(old_size + i) & mask] = data[i];
- };
+ }
write_pos = (old_size + write_pos) & mask;
} else {
read_pos = read_pos & mask;
write_pos = write_pos & mask;
- };
+ }
size_mask = mask;
- };
+ }
RingBuffer<T>(int p_power = 0) {
- read_pos = 0;
- write_pos = 0;
resize(p_power);
- };
- ~RingBuffer<T>(){};
+ }
+ ~RingBuffer<T>() {}
};
#endif // RING_BUFFER_H
diff --git a/core/safe_refcount.cpp b/core/safe_refcount.cpp
index e4604faa09..d5ee778ef7 100644
--- a/core/safe_refcount.cpp
+++ b/core/safe_refcount.cpp
@@ -42,79 +42,71 @@
/* taken from boost */ \
while (true) { \
m_cpp_type tmp = static_cast<m_cpp_type const volatile &>(*(m_pw)); \
- if (tmp == 0) \
+ if (tmp == 0) { \
return 0; /* if zero, can't add to it anymore */ \
- if (m_win_cmpxchg((m_win_type volatile *)(m_pw), tmp + 1, tmp) == tmp) \
+ } \
+ if (m_win_cmpxchg((m_win_type volatile *)(m_pw), tmp + 1, tmp) == tmp) { \
return tmp + 1; \
+ } \
}
#define ATOMIC_EXCHANGE_IF_GREATER_BODY(m_pw, m_val, m_win_type, m_win_cmpxchg, m_cpp_type) \
while (true) { \
m_cpp_type tmp = static_cast<m_cpp_type const volatile &>(*(m_pw)); \
- if (tmp >= m_val) \
+ if (tmp >= m_val) { \
return tmp; /* already greater, or equal */ \
- if (m_win_cmpxchg((m_win_type volatile *)(m_pw), m_val, tmp) == tmp) \
+ } \
+ if (m_win_cmpxchg((m_win_type volatile *)(m_pw), m_val, tmp) == tmp) { \
return m_val; \
+ } \
}
-_ALWAYS_INLINE_ uint32_t _atomic_conditional_increment_impl(volatile uint32_t *pw){
-
- ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONG, InterlockedCompareExchange, uint32_t)
+_ALWAYS_INLINE_ uint32_t _atomic_conditional_increment_impl(volatile uint32_t *pw) {
+ ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONG, InterlockedCompareExchange, uint32_t);
}
_ALWAYS_INLINE_ uint32_t _atomic_decrement_impl(volatile uint32_t *pw) {
-
return InterlockedDecrement((LONG volatile *)pw);
}
_ALWAYS_INLINE_ uint32_t _atomic_increment_impl(volatile uint32_t *pw) {
-
return InterlockedIncrement((LONG volatile *)pw);
}
_ALWAYS_INLINE_ uint32_t _atomic_sub_impl(volatile uint32_t *pw, volatile uint32_t val) {
-
return InterlockedExchangeAdd((LONG volatile *)pw, -(int32_t)val) - val;
}
_ALWAYS_INLINE_ uint32_t _atomic_add_impl(volatile uint32_t *pw, volatile uint32_t val) {
-
return InterlockedAdd((LONG volatile *)pw, val);
}
-_ALWAYS_INLINE_ uint32_t _atomic_exchange_if_greater_impl(volatile uint32_t *pw, volatile uint32_t val){
-
- ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONG, InterlockedCompareExchange, uint32_t)
+_ALWAYS_INLINE_ uint32_t _atomic_exchange_if_greater_impl(volatile uint32_t *pw, volatile uint32_t val) {
+ ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONG, InterlockedCompareExchange, uint32_t);
}
-_ALWAYS_INLINE_ uint64_t _atomic_conditional_increment_impl(volatile uint64_t *pw){
-
- ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONGLONG, InterlockedCompareExchange64, uint64_t)
+_ALWAYS_INLINE_ uint64_t _atomic_conditional_increment_impl(volatile uint64_t *pw) {
+ ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONGLONG, InterlockedCompareExchange64, uint64_t);
}
_ALWAYS_INLINE_ uint64_t _atomic_decrement_impl(volatile uint64_t *pw) {
-
return InterlockedDecrement64((LONGLONG volatile *)pw);
}
_ALWAYS_INLINE_ uint64_t _atomic_increment_impl(volatile uint64_t *pw) {
-
return InterlockedIncrement64((LONGLONG volatile *)pw);
}
_ALWAYS_INLINE_ uint64_t _atomic_sub_impl(volatile uint64_t *pw, volatile uint64_t val) {
-
return InterlockedExchangeAdd64((LONGLONG volatile *)pw, -(int64_t)val) - val;
}
_ALWAYS_INLINE_ uint64_t _atomic_add_impl(volatile uint64_t *pw, volatile uint64_t val) {
-
return InterlockedAdd64((LONGLONG volatile *)pw, val);
}
-_ALWAYS_INLINE_ uint64_t _atomic_exchange_if_greater_impl(volatile uint64_t *pw, volatile uint64_t val){
-
- ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONGLONG, InterlockedCompareExchange64, uint64_t)
+_ALWAYS_INLINE_ uint64_t _atomic_exchange_if_greater_impl(volatile uint64_t *pw, volatile uint64_t val) {
+ ATOMIC_EXCHANGE_IF_GREATER_BODY(pw, val, LONGLONG, InterlockedCompareExchange64, uint64_t);
}
// The actual advertised functions; they'll call the right implementation
diff --git a/core/safe_refcount.h b/core/safe_refcount.h
index 953a877397..dc4e62354a 100644
--- a/core/safe_refcount.h
+++ b/core/safe_refcount.h
@@ -43,9 +43,9 @@
template <class T>
static _ALWAYS_INLINE_ T atomic_conditional_increment(volatile T *pw) {
-
- if (*pw == 0)
+ if (*pw == 0) {
return 0;
+ }
(*pw)++;
@@ -54,7 +54,6 @@ static _ALWAYS_INLINE_ T atomic_conditional_increment(volatile T *pw) {
template <class T>
static _ALWAYS_INLINE_ T atomic_decrement(volatile T *pw) {
-
(*pw)--;
return *pw;
@@ -62,7 +61,6 @@ static _ALWAYS_INLINE_ T atomic_decrement(volatile T *pw) {
template <class T>
static _ALWAYS_INLINE_ T atomic_increment(volatile T *pw) {
-
(*pw)++;
return *pw;
@@ -70,7 +68,6 @@ static _ALWAYS_INLINE_ T atomic_increment(volatile T *pw) {
template <class T, class V>
static _ALWAYS_INLINE_ T atomic_sub(volatile T *pw, volatile V val) {
-
(*pw) -= val;
return *pw;
@@ -78,7 +75,6 @@ static _ALWAYS_INLINE_ T atomic_sub(volatile T *pw, volatile V val) {
template <class T, class V>
static _ALWAYS_INLINE_ T atomic_add(volatile T *pw, volatile V val) {
-
(*pw) += val;
return *pw;
@@ -86,9 +82,9 @@ static _ALWAYS_INLINE_ T atomic_add(volatile T *pw, volatile V val) {
template <class T, class V>
static _ALWAYS_INLINE_ T atomic_exchange_if_greater(volatile T *pw, volatile V val) {
-
- if (val > *pw)
+ if (val > *pw) {
*pw = val;
+ }
return *pw;
}
@@ -102,49 +98,47 @@ static _ALWAYS_INLINE_ T atomic_exchange_if_greater(volatile T *pw, volatile V v
template <class T>
static _ALWAYS_INLINE_ T atomic_conditional_increment(volatile T *pw) {
-
while (true) {
T tmp = static_cast<T const volatile &>(*pw);
- if (tmp == 0)
+ if (tmp == 0) {
return 0; // if zero, can't add to it anymore
- if (__sync_val_compare_and_swap(pw, tmp, tmp + 1) == tmp)
+ }
+ if (__sync_val_compare_and_swap(pw, tmp, tmp + 1) == tmp) {
return tmp + 1;
+ }
}
}
template <class T>
static _ALWAYS_INLINE_ T atomic_decrement(volatile T *pw) {
-
return __sync_sub_and_fetch(pw, 1);
}
template <class T>
static _ALWAYS_INLINE_ T atomic_increment(volatile T *pw) {
-
return __sync_add_and_fetch(pw, 1);
}
template <class T, class V>
static _ALWAYS_INLINE_ T atomic_sub(volatile T *pw, volatile V val) {
-
return __sync_sub_and_fetch(pw, val);
}
template <class T, class V>
static _ALWAYS_INLINE_ T atomic_add(volatile T *pw, volatile V val) {
-
return __sync_add_and_fetch(pw, val);
}
template <class T, class V>
static _ALWAYS_INLINE_ T atomic_exchange_if_greater(volatile T *pw, volatile V val) {
-
while (true) {
T tmp = static_cast<T const volatile &>(*pw);
- if (tmp >= val)
+ if (tmp >= val) {
return tmp; // already greater, or equal
- if (__sync_val_compare_and_swap(pw, tmp, val) == tmp)
+ }
+ if (__sync_val_compare_and_swap(pw, tmp, val) == tmp) {
return val;
+ }
}
}
@@ -171,7 +165,6 @@ uint64_t atomic_exchange_if_greater(volatile uint64_t *pw, volatile uint64_t val
#endif
struct SafeRefCount {
-
uint32_t count;
public:
@@ -203,7 +196,6 @@ public:
}
_ALWAYS_INLINE_ void init(uint32_t p_value = 1) {
-
count = p_value;
}
};
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 82cac6bc9a..38a970f3c6 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -34,6 +34,7 @@
#include "core/debugger/engine_debugger.h"
#include "core/debugger/script_debugger.h"
#include "core/project_settings.h"
+
#include <stdint.h>
ScriptLanguage *ScriptServer::_languages[MAX_LANGUAGES];
@@ -45,11 +46,10 @@ bool ScriptServer::languages_finished = false;
ScriptEditRequestFunction ScriptServer::edit_request_func = nullptr;
void Script::_notification(int p_what) {
-
if (p_what == NOTIFICATION_POSTINITIALIZE) {
-
- if (EngineDebugger::is_active())
+ if (EngineDebugger::is_active()) {
EngineDebugger::get_script_debugger()->set_break_language(get_language());
+ }
}
}
@@ -100,7 +100,6 @@ Dictionary Script::_get_script_constant_map() {
}
void Script::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("can_instance"), &Script::can_instance);
//ClassDB::bind_method(D_METHOD("instance_create","base_object"),&Script::instance_create);
ClassDB::bind_method(D_METHOD("instance_has", "base_object"), &Script::instance_has);
@@ -125,30 +124,25 @@ void Script::_bind_methods() {
}
void ScriptServer::set_scripting_enabled(bool p_enabled) {
-
scripting_enabled = p_enabled;
}
bool ScriptServer::is_scripting_enabled() {
-
return scripting_enabled;
}
ScriptLanguage *ScriptServer::get_language(int p_idx) {
-
ERR_FAIL_INDEX_V(p_idx, _language_count, nullptr);
return _languages[p_idx];
}
void ScriptServer::register_language(ScriptLanguage *p_language) {
-
ERR_FAIL_COND(_language_count >= MAX_LANGUAGES);
_languages[_language_count++] = p_language;
}
void ScriptServer::unregister_language(ScriptLanguage *p_language) {
-
for (int i = 0; i < _language_count; i++) {
if (_languages[i] == p_language) {
_language_count--;
@@ -161,7 +155,6 @@ void ScriptServer::unregister_language(ScriptLanguage *p_language) {
}
void ScriptServer::init_languages() {
-
{ //load global classes
global_classes_clear();
if (ProjectSettings::get_singleton()->has_setting("_global_script_classes")) {
@@ -169,8 +162,9 @@ void ScriptServer::init_languages() {
for (int i = 0; i < script_classes.size(); i++) {
Dictionary c = script_classes[i];
- if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base"))
+ if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) {
continue;
+ }
add_global_class(c["class"], c["base"], c["language"], c["path"]);
}
}
@@ -182,7 +176,6 @@ void ScriptServer::init_languages() {
}
void ScriptServer::finish_languages() {
-
for (int i = 0; i < _language_count; i++) {
_languages[i]->finish();
}
@@ -191,24 +184,20 @@ void ScriptServer::finish_languages() {
}
void ScriptServer::set_reload_scripts_on_save(bool p_enable) {
-
reload_scripts_on_save = p_enable;
}
bool ScriptServer::is_reload_scripts_on_save_enabled() {
-
return reload_scripts_on_save;
}
void ScriptServer::thread_enter() {
-
for (int i = 0; i < _language_count; i++) {
_languages[i]->thread_enter();
}
}
void ScriptServer::thread_exit() {
-
for (int i = 0; i < _language_count; i++) {
_languages[i]->thread_exit();
}
@@ -228,16 +217,20 @@ void ScriptServer::add_global_class(const StringName &p_class, const StringName
g.base = p_base;
global_classes[p_class] = g;
}
+
void ScriptServer::remove_global_class(const StringName &p_class) {
global_classes.erase(p_class);
}
+
bool ScriptServer::is_global_class(const StringName &p_class) {
return global_classes.has(p_class);
}
+
StringName ScriptServer::get_global_class_language(const StringName &p_class) {
ERR_FAIL_COND_V(!global_classes.has(p_class), StringName());
return global_classes[p_class].language;
}
+
String ScriptServer::get_global_class_path(const String &p_class) {
ERR_FAIL_COND_V(!global_classes.has(p_class), String());
return global_classes[p_class].path;
@@ -247,6 +240,7 @@ StringName ScriptServer::get_global_class_base(const String &p_class) {
ERR_FAIL_COND_V(!global_classes.has(p_class), String());
return global_classes[p_class].base;
}
+
StringName ScriptServer::get_global_class_native_base(const String &p_class) {
ERR_FAIL_COND_V(!global_classes.has(p_class), String());
String base = global_classes[p_class].base;
@@ -255,6 +249,7 @@ StringName ScriptServer::get_global_class_native_base(const String &p_class) {
}
return base;
}
+
void ScriptServer::get_global_class_list(List<StringName> *r_global_classes) {
const StringName *K = nullptr;
List<StringName> classes;
@@ -266,6 +261,7 @@ void ScriptServer::get_global_class_list(List<StringName> *r_global_classes) {
r_global_classes->push_back(E->get());
}
}
+
void ScriptServer::save_global_classes() {
List<StringName> gc;
get_global_class_list(&gc);
@@ -285,27 +281,26 @@ void ScriptServer::save_global_classes() {
////////////////////
void ScriptInstance::get_property_state(List<Pair<StringName, Variant>> &state) {
-
List<PropertyInfo> pinfo;
get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
if (E->get().usage & PROPERTY_USAGE_STORAGE) {
Pair<StringName, Variant> p;
p.first = E->get().name;
- if (get(p.first, p.second))
+ if (get(p.first, p.second)) {
state.push_back(p);
+ }
}
}
}
Variant ScriptInstance::call(const StringName &p_method, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS;
int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
argc++;
}
@@ -324,23 +319,25 @@ void ScriptInstance::call_multilevel_reversed(const StringName &p_method, const
}
void ScriptInstance::property_set_fallback(const StringName &, const Variant &, bool *r_valid) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
}
Variant ScriptInstance::property_get_fallback(const StringName &, bool *r_valid) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return Variant();
}
void ScriptInstance::call_multilevel(const StringName &p_method, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS;
int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
argc++;
}
@@ -359,9 +356,9 @@ void ScriptLanguage::frame() {
}
bool PlaceHolderScriptInstance::set(const StringName &p_name, const Variant &p_value) {
-
- if (script->is_placeholder_fallback_enabled())
+ if (script->is_placeholder_fallback_enabled()) {
return false;
+ }
if (values.has(p_name)) {
Variant defval;
@@ -384,8 +381,8 @@ bool PlaceHolderScriptInstance::set(const StringName &p_name, const Variant &p_v
}
return false;
}
-bool PlaceHolderScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
+bool PlaceHolderScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
if (values.has(p_name)) {
r_ret = values[p_name];
return true;
@@ -408,7 +405,6 @@ bool PlaceHolderScriptInstance::get(const StringName &p_name, Variant &r_ret) co
}
void PlaceHolderScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const {
-
if (script->is_placeholder_fallback_enabled()) {
for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
p_properties->push_back(E->get());
@@ -425,38 +421,41 @@ void PlaceHolderScriptInstance::get_property_list(List<PropertyInfo> *p_properti
}
Variant::Type PlaceHolderScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
-
if (values.has(p_name)) {
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = true;
+ }
return values[p_name].get_type();
}
if (constants.has(p_name)) {
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = true;
+ }
return constants[p_name].get_type();
}
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = false;
+ }
return Variant::NIL;
}
void PlaceHolderScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
-
- if (script->is_placeholder_fallback_enabled())
+ if (script->is_placeholder_fallback_enabled()) {
return;
+ }
if (script.is_valid()) {
script->get_script_method_list(p_list);
}
}
-bool PlaceHolderScriptInstance::has_method(const StringName &p_method) const {
- if (script->is_placeholder_fallback_enabled())
+bool PlaceHolderScriptInstance::has_method(const StringName &p_method) const {
+ if (script->is_placeholder_fallback_enabled()) {
return false;
+ }
if (script.is_valid()) {
return script->has_method(p_method);
@@ -465,17 +464,15 @@ bool PlaceHolderScriptInstance::has_method(const StringName &p_method) const {
}
void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, const Map<StringName, Variant> &p_values) {
-
Set<StringName> new_values;
for (const List<PropertyInfo>::Element *E = p_properties.front(); E; E = E->next()) {
-
StringName n = E->get().name;
new_values.insert(n);
if (!values.has(n) || values[n].get_type() != E->get().type) {
-
- if (p_values.has(n))
+ if (p_values.has(n)) {
values[n] = p_values[n];
+ }
}
}
@@ -483,9 +480,9 @@ void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, c
List<StringName> to_remove;
for (Map<StringName, Variant>::Element *E = values.front(); E; E = E->next()) {
-
- if (!new_values.has(E->key()))
+ if (!new_values.has(E->key())) {
to_remove.push_back(E->key());
+ }
Variant defval;
if (script->get_property_default_value(E->key(), defval)) {
@@ -497,13 +494,11 @@ void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, c
}
while (to_remove.size()) {
-
values.erase(to_remove.front()->get());
to_remove.pop_front();
}
if (owner && owner->get_script_instance() == this) {
-
owner->_change_notify();
}
//change notify
@@ -513,7 +508,6 @@ void PlaceHolderScriptInstance::update(const List<PropertyInfo> &p_properties, c
}
void PlaceHolderScriptInstance::property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid) {
-
if (script->is_placeholder_fallback_enabled()) {
Map<StringName, Variant>::Element *E = values.find(p_name);
@@ -535,31 +529,34 @@ void PlaceHolderScriptInstance::property_set_fallback(const StringName &p_name,
}
}
- if (r_valid)
+ if (r_valid) {
*r_valid = false; // Cannot change the value in either case
+ }
}
Variant PlaceHolderScriptInstance::property_get_fallback(const StringName &p_name, bool *r_valid) {
-
if (script->is_placeholder_fallback_enabled()) {
const Map<StringName, Variant>::Element *E = values.find(p_name);
if (E) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return E->value();
}
E = constants.find(p_name);
if (E) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return E->value();
}
}
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return Variant();
}
@@ -579,7 +576,6 @@ PlaceHolderScriptInstance::PlaceHolderScriptInstance(ScriptLanguage *p_language,
}
PlaceHolderScriptInstance::~PlaceHolderScriptInstance() {
-
if (script.is_valid()) {
script->_placeholder_erased(this);
}
diff --git a/core/script_language.h b/core/script_language.h
index 2d86c5166d..b6c2a47245 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -112,7 +112,6 @@ class ScriptInstance;
class PlaceHolderScriptInstance;
class Script : public Resource {
-
GDCLASS(Script, Resource);
OBJ_SAVE_TYPE(Script);
@@ -135,6 +134,8 @@ public:
virtual Ref<Script> get_base_script() const = 0; //for script inheritance
+ virtual bool inherits_script(const Ref<Script> &p_script) const = 0;
+
virtual StringName get_instance_base_type() const = 0; // this may not work in all scripts, will return empty if so
virtual ScriptInstance *instance_create(Object *p_this) = 0;
virtual PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) { return nullptr; }
@@ -203,8 +204,9 @@ public:
virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
virtual void notification(int p_notification) = 0;
virtual String to_string(bool *r_valid) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return String();
}
@@ -251,14 +253,12 @@ struct ScriptCodeCompletionOption {
KIND_FILE_PATH,
KIND_PLAIN_TEXT,
};
- Kind kind;
+ Kind kind = KIND_PLAIN_TEXT;
String display;
String insert_text;
RES icon;
- ScriptCodeCompletionOption() {
- kind = KIND_PLAIN_TEXT;
- }
+ ScriptCodeCompletionOption() {}
ScriptCodeCompletionOption(const String &p_text, Kind p_kind) {
display = p_text;
@@ -268,7 +268,6 @@ struct ScriptCodeCompletionOption {
};
class ScriptCodeCompletionCache {
-
static ScriptCodeCompletionCache *singleton;
public:
@@ -406,7 +405,6 @@ public:
extern uint8_t script_encryption_key[32];
class PlaceHolderScriptInstance : public ScriptInstance {
-
Object *owner;
List<PropertyInfo> properties;
Map<StringName, Variant> values;
diff --git a/core/self_list.h b/core/self_list.h
index 19d2783208..3104bcb714 100644
--- a/core/self_list.h
+++ b/core/self_list.h
@@ -38,13 +38,11 @@ template <class T>
class SelfList {
public:
class List {
-
- SelfList<T> *_first;
- SelfList<T> *_last;
+ SelfList<T> *_first = nullptr;
+ SelfList<T> *_last = nullptr;
public:
void add(SelfList<T> *p_elem) {
-
ERR_FAIL_COND(p_elem->_root);
p_elem->_root = this;
@@ -62,7 +60,6 @@ public:
}
void add_last(SelfList<T> *p_elem) {
-
ERR_FAIL_COND(p_elem->_root);
p_elem->_root = this;
@@ -80,7 +77,6 @@ public:
}
void remove(SelfList<T> *p_elem) {
-
ERR_FAIL_COND(p_elem->_root != this);
if (p_elem->_next) {
p_elem->_next->_prev = p_elem->_prev;
@@ -105,21 +101,24 @@ public:
_FORCE_INLINE_ SelfList<T> *first() { return _first; }
_FORCE_INLINE_ const SelfList<T> *first() const { return _first; }
- _FORCE_INLINE_ List() {
- _first = nullptr;
- _last = nullptr;
- }
+
+ _FORCE_INLINE_ List() {}
_FORCE_INLINE_ ~List() { ERR_FAIL_COND(_first != nullptr); }
};
private:
- List *_root;
+ List *_root = nullptr;
T *_self;
- SelfList<T> *_next;
- SelfList<T> *_prev;
+ SelfList<T> *_next = nullptr;
+ SelfList<T> *_prev = nullptr;
public:
_FORCE_INLINE_ bool in_list() const { return _root; }
+ _FORCE_INLINE_ void remove_from_list() {
+ if (_root) {
+ _root->remove(this);
+ }
+ }
_FORCE_INLINE_ SelfList<T> *next() { return _next; }
_FORCE_INLINE_ SelfList<T> *prev() { return _prev; }
_FORCE_INLINE_ const SelfList<T> *next() const { return _next; }
@@ -127,17 +126,13 @@ public:
_FORCE_INLINE_ T *self() const { return _self; }
_FORCE_INLINE_ SelfList(T *p_self) {
-
_self = p_self;
- _next = nullptr;
- _prev = nullptr;
- _root = nullptr;
}
_FORCE_INLINE_ ~SelfList() {
-
- if (_root)
+ if (_root) {
_root->remove(this);
+ }
}
};
diff --git a/core/set.h b/core/set.h
index c17ee15350..1bc0a3f41e 100644
--- a/core/set.h
+++ b/core/set.h
@@ -39,7 +39,6 @@
template <class T, class C = Comparator<T>, class A = DefaultAllocator>
class Set {
-
enum Color {
RED,
BLACK
@@ -48,54 +47,41 @@ class Set {
public:
class Element {
-
private:
friend class Set<T, C, A>;
- int color;
- Element *right;
- Element *left;
- Element *parent;
- Element *_next;
- Element *_prev;
+ int color = RED;
+ Element *right = nullptr;
+ Element *left = nullptr;
+ Element *parent = nullptr;
+ Element *_next = nullptr;
+ Element *_prev = nullptr;
T value;
//_Data *data;
public:
const Element *next() const {
-
return _next;
}
Element *next() {
-
return _next;
}
const Element *prev() const {
-
return _prev;
}
Element *prev() {
-
return _prev;
}
const T &get() const {
return value;
};
- Element() {
- color = RED;
- right = nullptr;
- left = nullptr;
- parent = nullptr;
- _next = nullptr;
- _prev = nullptr;
- };
+ Element() {}
};
private:
struct _Data {
-
- Element *_root;
+ Element *_root = nullptr;
Element *_nil;
- int size_cache;
+ int size_cache = 0;
_FORCE_INLINE_ _Data() {
#ifdef GLOBALNIL_DISABLED
@@ -105,19 +91,15 @@ private:
#else
_nil = (Element *)&_GlobalNilClass::_nil;
#endif
- _root = nullptr;
- size_cache = 0;
}
void _create_root() {
-
_root = memnew_allocator(Element, A);
_root->parent = _root->left = _root->right = _nil;
_root->color = BLACK;
}
void _free_root() {
-
if (_root) {
memdelete_allocator<Element, A>(_root);
_root = nullptr;
@@ -125,7 +107,6 @@ private:
}
~_Data() {
-
_free_root();
#ifdef GLOBALNIL_DISABLED
@@ -137,62 +118,61 @@ private:
_Data _data;
inline void _set_color(Element *p_node, int p_color) {
-
ERR_FAIL_COND(p_node == _data._nil && p_color == RED);
p_node->color = p_color;
}
inline void _rotate_left(Element *p_node) {
-
Element *r = p_node->right;
p_node->right = r->left;
- if (r->left != _data._nil)
+ if (r->left != _data._nil) {
r->left->parent = p_node;
+ }
r->parent = p_node->parent;
- if (p_node == p_node->parent->left)
+ if (p_node == p_node->parent->left) {
p_node->parent->left = r;
- else
+ } else {
p_node->parent->right = r;
+ }
r->left = p_node;
p_node->parent = r;
}
inline void _rotate_right(Element *p_node) {
-
Element *l = p_node->left;
p_node->left = l->right;
- if (l->right != _data._nil)
+ if (l->right != _data._nil) {
l->right->parent = p_node;
+ }
l->parent = p_node->parent;
- if (p_node == p_node->parent->right)
+ if (p_node == p_node->parent->right) {
p_node->parent->right = l;
- else
+ } else {
p_node->parent->left = l;
+ }
l->right = p_node;
p_node->parent = l;
}
inline Element *_successor(Element *p_node) const {
-
Element *node = p_node;
if (node->right != _data._nil) {
-
node = node->right;
while (node->left != _data._nil) { /* returns the minimum of the right subtree of node */
node = node->left;
}
return node;
} else {
-
while (node == node->parent->right) {
node = node->parent;
}
- if (node->parent == _data._root)
+ if (node->parent == _data._root) {
return nullptr; // No successor, as p_node = last node
+ }
return node->parent;
}
}
@@ -201,43 +181,41 @@ private:
Element *node = p_node;
if (node->left != _data._nil) {
-
node = node->left;
while (node->right != _data._nil) { /* returns the minimum of the left subtree of node */
node = node->right;
}
return node;
} else {
-
while (node == node->parent->left) {
node = node->parent;
}
- if (node == _data._root)
+ if (node == _data._root) {
return nullptr; // No predecessor, as p_node = first node.
+ }
return node->parent;
}
}
Element *_find(const T &p_value) const {
-
Element *node = _data._root->left;
C less;
while (node != _data._nil) {
- if (less(p_value, node->value))
+ if (less(p_value, node->value)) {
node = node->left;
- else if (less(node->value, p_value))
+ } else if (less(node->value, p_value)) {
node = node->right;
- else
+ } else {
return node; // found
+ }
}
return nullptr;
}
Element *_lower_bound(const T &p_value) const {
-
Element *node = _data._root->left;
Element *prev = nullptr;
C less;
@@ -245,25 +223,27 @@ private:
while (node != _data._nil) {
prev = node;
- if (less(p_value, node->value))
+ if (less(p_value, node->value)) {
node = node->left;
- else if (less(node->value, p_value))
+ } else if (less(node->value, p_value)) {
node = node->right;
- else
+ } else {
return node; // found
+ }
}
- if (prev == nullptr)
+ if (prev == nullptr) {
return nullptr; // tree empty
+ }
- if (less(prev->value, p_value))
+ if (less(prev->value, p_value)) {
prev = prev->_next;
+ }
return prev;
}
void _insert_rb_fix(Element *p_new_node) {
-
Element *node = p_new_node;
Element *nparent = node->parent;
Element *ngrand_parent;
@@ -312,20 +292,18 @@ private:
}
Element *_insert(const T &p_value) {
-
Element *new_parent = _data._root;
Element *node = _data._root->left;
C less;
while (node != _data._nil) {
-
new_parent = node;
- if (less(p_value, node->value))
+ if (less(p_value, node->value)) {
node = node->left;
- else if (less(node->value, p_value))
+ } else if (less(node->value, p_value)) {
node = node->right;
- else {
+ } else {
return node; // Return existing node
}
}
@@ -345,10 +323,12 @@ private:
new_node->_next = _successor(new_node);
new_node->_prev = _predecessor(new_node);
- if (new_node->_next)
+ if (new_node->_next) {
new_node->_next->_prev = new_node;
- if (new_node->_prev)
+ }
+ if (new_node->_prev) {
new_node->_prev->_next = new_node;
+ }
_data.size_cache++;
_insert_rb_fix(new_node);
@@ -356,7 +336,6 @@ private:
}
void _erase_fix_rb(Element *p_node) {
-
Element *root = _data._root->left;
Element *node = _data._nil;
Element *sibling = p_node;
@@ -418,7 +397,6 @@ private:
}
void _erase(Element *p_node) {
-
Element *rp = ((p_node->left == _data._nil) || (p_node->right == _data._nil)) ? p_node : p_node->_next;
Element *node = (rp->left == _data._nil) ? rp->right : rp->left;
@@ -439,17 +417,18 @@ private:
}
if (rp != p_node) {
-
ERR_FAIL_COND(rp == _data._nil);
rp->left = p_node->left;
rp->right = p_node->right;
rp->parent = p_node->parent;
rp->color = p_node->color;
- if (p_node->left != _data._nil)
+ if (p_node->left != _data._nil) {
p_node->left->parent = rp;
- if (p_node->right != _data._nil)
+ }
+ if (p_node->right != _data._nil) {
p_node->right->parent = rp;
+ }
if (p_node == p_node->parent->left) {
p_node->parent->left = rp;
@@ -458,10 +437,12 @@ private:
}
}
- if (p_node->_next)
+ if (p_node->_next) {
p_node->_next->_prev = p_node->_prev;
- if (p_node->_prev)
+ }
+ if (p_node->_prev) {
p_node->_prev->_next = p_node->_next;
+ }
memdelete_allocator<Element, A>(p_node);
_data.size_cache--;
@@ -469,21 +450,22 @@ private:
}
void _calculate_depth(Element *p_element, int &max_d, int d) const {
-
- if (p_element == _data._nil)
+ if (p_element == _data._nil) {
return;
+ }
_calculate_depth(p_element->left, max_d, d + 1);
_calculate_depth(p_element->right, max_d, d + 1);
- if (d > max_d)
+ if (d > max_d) {
max_d = d;
+ }
}
void _cleanup_tree(Element *p_element) {
-
- if (p_element == _data._nil)
+ if (p_element == _data._nil) {
return;
+ }
_cleanup_tree(p_element->left);
_cleanup_tree(p_element->right);
@@ -491,102 +473,105 @@ private:
}
void _copy_from(const Set &p_set) {
-
clear();
// not the fastest way, but safeset to write.
for (Element *I = p_set.front(); I; I = I->next()) {
-
insert(I->get());
}
}
public:
const Element *find(const T &p_value) const {
-
- if (!_data._root)
+ if (!_data._root) {
return nullptr;
+ }
const Element *res = _find(p_value);
return res;
}
Element *find(const T &p_value) {
-
- if (!_data._root)
+ if (!_data._root) {
return nullptr;
+ }
Element *res = _find(p_value);
return res;
}
Element *lower_bound(const T &p_value) const {
-
return _lower_bound(p_value);
}
bool has(const T &p_value) const {
-
return find(p_value) != nullptr;
}
Element *insert(const T &p_value) {
-
- if (!_data._root)
+ if (!_data._root) {
_data._create_root();
+ }
return _insert(p_value);
}
void erase(Element *p_element) {
-
- if (!_data._root || !p_element)
+ if (!_data._root || !p_element) {
return;
+ }
_erase(p_element);
- if (_data.size_cache == 0 && _data._root)
+ if (_data.size_cache == 0 && _data._root) {
_data._free_root();
+ }
}
bool erase(const T &p_value) {
-
- if (!_data._root)
+ if (!_data._root) {
return false;
+ }
Element *e = find(p_value);
- if (!e)
+ if (!e) {
return false;
+ }
_erase(e);
- if (_data.size_cache == 0 && _data._root)
+ if (_data.size_cache == 0 && _data._root) {
_data._free_root();
+ }
return true;
}
Element *front() const {
-
- if (!_data._root)
+ if (!_data._root) {
return nullptr;
+ }
Element *e = _data._root->left;
- if (e == _data._nil)
+ if (e == _data._nil) {
return nullptr;
+ }
- while (e->left != _data._nil)
+ while (e->left != _data._nil) {
e = e->left;
+ }
return e;
}
Element *back() const {
-
- if (!_data._root)
+ if (!_data._root) {
return nullptr;
+ }
Element *e = _data._root->left;
- if (e == _data._nil)
+ if (e == _data._nil) {
return nullptr;
+ }
- while (e->right != _data._nil)
+ while (e->right != _data._nil) {
e = e->right;
+ }
return e;
}
@@ -596,8 +581,9 @@ public:
int calculate_depth() const {
// used for debug mostly
- if (!_data._root)
+ if (!_data._root) {
return 0;
+ }
int max_d = 0;
_calculate_depth(_data._root->left, max_d, 0);
@@ -605,9 +591,9 @@ public:
}
void clear() {
-
- if (!_data._root)
+ if (!_data._root) {
return;
+ }
_cleanup_tree(_data._root->left);
_data._root->left = _data._nil;
@@ -616,20 +602,16 @@ public:
}
void operator=(const Set &p_set) {
-
_copy_from(p_set);
}
Set(const Set &p_set) {
-
_copy_from(p_set);
}
- _FORCE_INLINE_ Set() {
- }
+ _FORCE_INLINE_ Set() {}
~Set() {
-
clear();
}
};
diff --git a/core/simple_type.h b/core/simple_type.h
index da031854c6..10dc36cbd4 100644
--- a/core/simple_type.h
+++ b/core/simple_type.h
@@ -35,19 +35,16 @@
template <class T>
struct GetSimpleTypeT {
-
typedef T type_t;
};
template <class T>
struct GetSimpleTypeT<T &> {
-
typedef T type_t;
};
template <class T>
struct GetSimpleTypeT<T const> {
-
typedef T type_t;
};
diff --git a/core/sort_array.h b/core/sort_array.h
index 8aff0fb502..93cc6f727d 100644
--- a/core/sort_array.h
+++ b/core/sort_array.h
@@ -42,7 +42,6 @@
template <class T>
struct _DefaultComparator {
-
_FORCE_INLINE_ bool operator()(const T &a, const T &b) const { return (a < b); }
};
@@ -54,7 +53,6 @@ struct _DefaultComparator {
template <class T, class Comparator = _DefaultComparator<T>, bool Validate = SORT_ARRAY_VALIDATE_ENABLED>
class SortArray {
-
enum {
INTROSORT_THRESHOLD = 16
@@ -64,36 +62,36 @@ public:
Comparator compare;
inline const T &median_of_3(const T &a, const T &b, const T &c) const {
-
- if (compare(a, b))
- if (compare(b, c))
+ if (compare(a, b)) {
+ if (compare(b, c)) {
return b;
- else if (compare(a, c))
+ } else if (compare(a, c)) {
return c;
- else
+ } else {
return a;
- else if (compare(a, c))
+ }
+ } else if (compare(a, c)) {
return a;
- else if (compare(b, c))
+ } else if (compare(b, c)) {
return c;
- else
+ } else {
return b;
+ }
}
inline int bitlog(int n) const {
int k;
- for (k = 0; n != 1; n >>= 1)
+ for (k = 0; n != 1; n >>= 1) {
++k;
+ }
return k;
}
/* Heap / Heapsort functions */
inline void push_heap(int p_first, int p_hole_idx, int p_top_index, T p_value, T *p_array) const {
-
int parent = (p_hole_idx - 1) / 2;
while (p_hole_idx > p_top_index && compare(p_array[p_first + parent], p_value)) {
-
p_array[p_first + p_hole_idx] = p_array[p_first + parent];
p_hole_idx = parent;
parent = (p_hole_idx - 1) / 2;
@@ -102,24 +100,21 @@ public:
}
inline void pop_heap(int p_first, int p_last, int p_result, T p_value, T *p_array) const {
-
p_array[p_result] = p_array[p_first];
adjust_heap(p_first, 0, p_last - p_first, p_value, p_array);
}
inline void pop_heap(int p_first, int p_last, T *p_array) const {
-
pop_heap(p_first, p_last - 1, p_last - 1, p_array[p_last - 1], p_array);
}
inline void adjust_heap(int p_first, int p_hole_idx, int p_len, T p_value, T *p_array) const {
-
int top_index = p_hole_idx;
int second_child = 2 * p_hole_idx + 2;
while (second_child < p_len) {
-
- if (compare(p_array[p_first + second_child], p_array[p_first + (second_child - 1)]))
+ if (compare(p_array[p_first + second_child], p_array[p_first + (second_child - 1)])) {
second_child--;
+ }
p_array[p_first + p_hole_idx] = p_array[p_first + second_child];
p_hole_idx = second_child;
@@ -134,46 +129,47 @@ public:
}
inline void sort_heap(int p_first, int p_last, T *p_array) const {
-
while (p_last - p_first > 1) {
-
pop_heap(p_first, p_last--, p_array);
}
}
inline void make_heap(int p_first, int p_last, T *p_array) const {
- if (p_last - p_first < 2)
+ if (p_last - p_first < 2) {
return;
+ }
int len = p_last - p_first;
int parent = (len - 2) / 2;
while (true) {
adjust_heap(p_first, parent, len, p_array[p_first + parent], p_array);
- if (parent == 0)
+ if (parent == 0) {
return;
+ }
parent--;
}
}
inline void partial_sort(int p_first, int p_last, int p_middle, T *p_array) const {
-
make_heap(p_first, p_middle, p_array);
- for (int i = p_middle; i < p_last; i++)
- if (compare(p_array[i], p_array[p_first]))
+ for (int i = p_middle; i < p_last; i++) {
+ if (compare(p_array[i], p_array[p_first])) {
pop_heap(p_first, p_middle, i, p_array[i], p_array);
+ }
+ }
sort_heap(p_first, p_middle, p_array);
}
inline void partial_select(int p_first, int p_last, int p_middle, T *p_array) const {
-
make_heap(p_first, p_middle, p_array);
- for (int i = p_middle; i < p_last; i++)
- if (compare(p_array[i], p_array[p_first]))
+ for (int i = p_middle; i < p_last; i++) {
+ if (compare(p_array[i], p_array[p_first])) {
pop_heap(p_first, p_middle, i, p_array[i], p_array);
+ }
+ }
}
inline int partitioner(int p_first, int p_last, T p_pivot, T *p_array) const {
-
const int unmodified_first = p_first;
const int unmodified_last = p_last;
@@ -192,8 +188,9 @@ public:
p_last--;
}
- if (!(p_first < p_last))
+ if (!(p_first < p_last)) {
return p_first;
+ }
SWAP(p_array[p_first], p_array[p_last]);
p_first++;
@@ -201,9 +198,7 @@ public:
}
inline void introsort(int p_first, int p_last, T *p_array, int p_max_depth) const {
-
while (p_last - p_first > INTROSORT_THRESHOLD) {
-
if (p_max_depth == 0) {
partial_sort(p_first, p_last, p_last, p_array);
return;
@@ -226,9 +221,7 @@ public:
}
inline void introselect(int p_first, int p_nth, int p_last, T *p_array, int p_max_depth) const {
-
while (p_last - p_first > 3) {
-
if (p_max_depth == 0) {
partial_select(p_first, p_nth + 1, p_last, p_array);
SWAP(p_first, p_nth);
@@ -246,17 +239,17 @@ public:
p_array[p_last - 1]),
p_array);
- if (cut <= p_nth)
+ if (cut <= p_nth) {
p_first = cut;
- else
+ } else {
p_last = cut;
+ }
}
insertion_sort(p_first, p_last, p_array);
}
inline void unguarded_linear_insert(int p_last, T p_value, T *p_array) const {
-
int next = p_last - 1;
while (compare(p_value, p_array[next])) {
if (Validate) {
@@ -270,45 +263,43 @@ public:
}
inline void linear_insert(int p_first, int p_last, T *p_array) const {
-
T val = p_array[p_last];
if (compare(val, p_array[p_first])) {
-
- for (int i = p_last; i > p_first; i--)
+ for (int i = p_last; i > p_first; i--) {
p_array[i] = p_array[i - 1];
+ }
p_array[p_first] = val;
- } else
+ } else {
unguarded_linear_insert(p_last, val, p_array);
+ }
}
inline void insertion_sort(int p_first, int p_last, T *p_array) const {
-
- if (p_first == p_last)
+ if (p_first == p_last) {
return;
- for (int i = p_first + 1; i != p_last; i++)
+ }
+ for (int i = p_first + 1; i != p_last; i++) {
linear_insert(p_first, i, p_array);
+ }
}
inline void unguarded_insertion_sort(int p_first, int p_last, T *p_array) const {
-
- for (int i = p_first; i != p_last; i++)
+ for (int i = p_first; i != p_last; i++) {
unguarded_linear_insert(i, p_array[i], p_array);
+ }
}
inline void final_insertion_sort(int p_first, int p_last, T *p_array) const {
-
if (p_last - p_first > INTROSORT_THRESHOLD) {
insertion_sort(p_first, p_first + INTROSORT_THRESHOLD, p_array);
unguarded_insertion_sort(p_first + INTROSORT_THRESHOLD, p_last, p_array);
} else {
-
insertion_sort(p_first, p_last, p_array);
}
}
inline void sort_range(int p_first, int p_last, T *p_array) const {
-
if (p_first != p_last) {
introsort(p_first, p_last, p_array, bitlog(p_last - p_first) * 2);
final_insertion_sort(p_first, p_last, p_array);
@@ -316,14 +307,13 @@ public:
}
inline void sort(T *p_array, int p_len) const {
-
sort_range(0, p_len, p_array);
}
inline void nth_element(int p_first, int p_last, int p_nth, T *p_array) const {
-
- if (p_first == p_last || p_nth == p_last)
+ if (p_first == p_last || p_nth == p_last) {
return;
+ }
introselect(p_first, p_nth, p_last, p_array, bitlog(p_last - p_first) * 2);
}
};
diff --git a/core/spin_lock.h b/core/spin_lock.h
index c48631f94a..1bb810bb29 100644
--- a/core/spin_lock.h
+++ b/core/spin_lock.h
@@ -32,6 +32,7 @@
#define SPIN_LOCK_H
#include "core/typedefs.h"
+
#include <atomic>
class SpinLock {
diff --git a/core/string_buffer.h b/core/string_buffer.h
index a140f0abf7..956a6333d9 100644
--- a/core/string_buffer.h
+++ b/core/string_buffer.h
@@ -35,10 +35,9 @@
template <int SHORT_BUFFER_SIZE = 64>
class StringBuffer {
-
CharType short_buffer[SHORT_BUFFER_SIZE];
String buffer;
- int string_length;
+ int string_length = 0;
_FORCE_INLINE_ CharType *current_buffer_ptr() {
return static_cast<String &>(buffer).empty() ? short_buffer : buffer.ptrw();
@@ -78,10 +77,6 @@ public:
_FORCE_INLINE_ operator String() {
return as_string();
}
-
- StringBuffer() {
- string_length = 0;
- }
};
template <int SHORT_BUFFER_SIZE>
@@ -123,8 +118,9 @@ StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::append(const C
template <int SHORT_BUFFER_SIZE>
StringBuffer<SHORT_BUFFER_SIZE> &StringBuffer<SHORT_BUFFER_SIZE>::reserve(int p_size) {
- if (p_size < SHORT_BUFFER_SIZE || p_size < buffer.size())
+ if (p_size < SHORT_BUFFER_SIZE || p_size < buffer.size()) {
return *this;
+ }
bool need_copy = string_length > 0 && buffer.empty();
buffer.resize(next_power_of_2(p_size));
diff --git a/core/string_builder.cpp b/core/string_builder.cpp
index 46c7e1c53f..c8d6498f27 100644
--- a/core/string_builder.cpp
+++ b/core/string_builder.cpp
@@ -33,9 +33,9 @@
#include <string.h>
StringBuilder &StringBuilder::append(const String &p_string) {
-
- if (p_string == String())
+ if (p_string == String()) {
return *this;
+ }
strings.push_back(p_string);
appended_strings.push_back(-1);
@@ -46,7 +46,6 @@ StringBuilder &StringBuilder::append(const String &p_string) {
}
StringBuilder &StringBuilder::append(const char *p_cstring) {
-
int32_t len = strlen(p_cstring);
c_strings.push_back(p_cstring);
@@ -58,9 +57,9 @@ StringBuilder &StringBuilder::append(const char *p_cstring) {
}
String StringBuilder::as_string() const {
-
- if (string_length == 0)
+ if (string_length == 0) {
return "";
+ }
CharType *buffer = memnew_arr(CharType, string_length);
@@ -80,7 +79,6 @@ String StringBuilder::as_string() const {
godot_string_elem++;
} else {
-
const char *s = c_strings[c_string_elem];
for (int32_t j = 0; j < appended_strings[i]; j++) {
diff --git a/core/string_builder.h b/core/string_builder.h
index dd8a154890..2a37d14218 100644
--- a/core/string_builder.h
+++ b/core/string_builder.h
@@ -32,12 +32,10 @@
#define STRING_BUILDER_H
#include "core/ustring.h"
-
#include "core/vector.h"
class StringBuilder {
-
- uint32_t string_length;
+ uint32_t string_length = 0;
Vector<String> strings;
Vector<const char *> c_strings;
@@ -80,9 +78,7 @@ public:
return as_string();
}
- StringBuilder() {
- string_length = 0;
- }
+ StringBuilder() {}
};
#endif // STRING_BUILDER_H
diff --git a/core/string_name.cpp b/core/string_name.cpp
index 9cbac97a7c..cbf6009681 100644
--- a/core/string_name.cpp
+++ b/core/string_name.cpp
@@ -42,7 +42,6 @@ StaticCString StaticCString::create(const char *p_ptr) {
StringName::_Data *StringName::_table[STRING_TABLE_LEN];
StringName _scs_create(const char *p_chr) {
-
return (p_chr[0] ? StringName(StaticCString::create(p_chr)) : StringName());
}
@@ -50,24 +49,19 @@ bool StringName::configured = false;
Mutex StringName::mutex;
void StringName::setup() {
-
ERR_FAIL_COND(configured);
for (int i = 0; i < STRING_TABLE_LEN; i++) {
-
_table[i] = nullptr;
}
configured = true;
}
void StringName::cleanup() {
-
MutexLock lock(mutex);
int lost_strings = 0;
for (int i = 0; i < STRING_TABLE_LEN; i++) {
-
while (_table[i]) {
-
_Data *d = _table[i];
lost_strings++;
if (OS::get_singleton()->is_stdout_verbose()) {
@@ -88,11 +82,9 @@ void StringName::cleanup() {
}
void StringName::unref() {
-
ERR_FAIL_COND(!configured);
if (_data && _data->refcount.unref()) {
-
MutexLock lock(mutex);
if (_data->prev) {
@@ -114,9 +106,7 @@ void StringName::unref() {
}
bool StringName::operator==(const String &p_name) const {
-
if (!_data) {
-
return (p_name.length() == 0);
}
@@ -124,9 +114,7 @@ bool StringName::operator==(const String &p_name) const {
}
bool StringName::operator==(const char *p_name) const {
-
if (!_data) {
-
return (p_name[0] == 0);
}
@@ -134,32 +122,28 @@ bool StringName::operator==(const char *p_name) const {
}
bool StringName::operator!=(const String &p_name) const {
-
return !(operator==(p_name));
}
bool StringName::operator!=(const StringName &p_name) const {
-
// the real magic of all this mess happens here.
// this is why path comparisons are very fast
return _data != p_name._data;
}
void StringName::operator=(const StringName &p_name) {
-
- if (this == &p_name)
+ if (this == &p_name) {
return;
+ }
unref();
if (p_name._data && p_name._data->refcount.ref()) {
-
_data = p_name._data;
}
}
StringName::StringName(const StringName &p_name) {
-
_data = nullptr;
ERR_FAIL_COND(!configured);
@@ -170,13 +154,13 @@ StringName::StringName(const StringName &p_name) {
}
StringName::StringName(const char *p_name) {
-
_data = nullptr;
ERR_FAIL_COND(!configured);
- if (!p_name || p_name[0] == 0)
+ if (!p_name || p_name[0] == 0) {
return; //empty, ignore
+ }
MutexLock lock(mutex);
@@ -187,10 +171,10 @@ StringName::StringName(const char *p_name) {
_data = _table[idx];
while (_data) {
-
// compare hash first
- if (_data->hash == hash && _data->get_name() == p_name)
+ if (_data->hash == hash && _data->get_name() == p_name) {
break;
+ }
_data = _data->next;
}
@@ -209,13 +193,13 @@ StringName::StringName(const char *p_name) {
_data->cname = nullptr;
_data->next = _table[idx];
_data->prev = nullptr;
- if (_table[idx])
+ if (_table[idx]) {
_table[idx]->prev = _data;
+ }
_table[idx] = _data;
}
StringName::StringName(const StaticCString &p_static_string) {
-
_data = nullptr;
ERR_FAIL_COND(!configured);
@@ -231,10 +215,10 @@ StringName::StringName(const StaticCString &p_static_string) {
_data = _table[idx];
while (_data) {
-
// compare hash first
- if (_data->hash == hash && _data->get_name() == p_static_string.ptr)
+ if (_data->hash == hash && _data->get_name() == p_static_string.ptr) {
break;
+ }
_data = _data->next;
}
@@ -253,19 +237,20 @@ StringName::StringName(const StaticCString &p_static_string) {
_data->cname = p_static_string.ptr;
_data->next = _table[idx];
_data->prev = nullptr;
- if (_table[idx])
+ if (_table[idx]) {
_table[idx]->prev = _data;
+ }
_table[idx] = _data;
}
StringName::StringName(const String &p_name) {
-
_data = nullptr;
ERR_FAIL_COND(!configured);
- if (p_name == String())
+ if (p_name == String()) {
return;
+ }
MutexLock lock(mutex);
@@ -275,9 +260,9 @@ StringName::StringName(const String &p_name) {
_data = _table[idx];
while (_data) {
-
- if (_data->hash == hash && _data->get_name() == p_name)
+ if (_data->hash == hash && _data->get_name() == p_name) {
break;
+ }
_data = _data->next;
}
@@ -296,18 +281,19 @@ StringName::StringName(const String &p_name) {
_data->cname = nullptr;
_data->next = _table[idx];
_data->prev = nullptr;
- if (_table[idx])
+ if (_table[idx]) {
_table[idx]->prev = _data;
+ }
_table[idx] = _data;
}
StringName StringName::search(const char *p_name) {
-
ERR_FAIL_COND_V(!configured, StringName());
ERR_FAIL_COND_V(!p_name, StringName());
- if (!p_name[0])
+ if (!p_name[0]) {
return StringName();
+ }
MutexLock lock(mutex);
@@ -317,10 +303,10 @@ StringName StringName::search(const char *p_name) {
_Data *_data = _table[idx];
while (_data) {
-
// compare hash first
- if (_data->hash == hash && _data->get_name() == p_name)
+ if (_data->hash == hash && _data->get_name() == p_name) {
break;
+ }
_data = _data->next;
}
@@ -332,12 +318,12 @@ StringName StringName::search(const char *p_name) {
}
StringName StringName::search(const CharType *p_name) {
-
ERR_FAIL_COND_V(!configured, StringName());
ERR_FAIL_COND_V(!p_name, StringName());
- if (!p_name[0])
+ if (!p_name[0]) {
return StringName();
+ }
MutexLock lock(mutex);
@@ -348,10 +334,10 @@ StringName StringName::search(const CharType *p_name) {
_Data *_data = _table[idx];
while (_data) {
-
// compare hash first
- if (_data->hash == hash && _data->get_name() == p_name)
+ if (_data->hash == hash && _data->get_name() == p_name) {
break;
+ }
_data = _data->next;
}
@@ -361,8 +347,8 @@ StringName StringName::search(const CharType *p_name) {
return StringName(); //does not exist
}
-StringName StringName::search(const String &p_name) {
+StringName StringName::search(const String &p_name) {
ERR_FAIL_COND_V(p_name == "", StringName());
MutexLock lock(mutex);
@@ -374,10 +360,10 @@ StringName StringName::search(const String &p_name) {
_Data *_data = _table[idx];
while (_data) {
-
// compare hash first
- if (_data->hash == hash && p_name == _data->get_name())
+ if (_data->hash == hash && p_name == _data->get_name()) {
break;
+ }
_data = _data->next;
}
@@ -388,12 +374,6 @@ StringName StringName::search(const String &p_name) {
return StringName(); //does not exist
}
-StringName::StringName() {
-
- _data = nullptr;
-}
-
StringName::~StringName() {
-
unref();
}
diff --git a/core/string_name.h b/core/string_name.h
index aec87b8e66..df6b458581 100644
--- a/core/string_name.h
+++ b/core/string_name.h
@@ -36,13 +36,11 @@
#include "core/ustring.h"
struct StaticCString {
-
const char *ptr;
static StaticCString create(const char *p_ptr);
};
class StringName {
-
enum {
STRING_TABLE_BITS = 12,
@@ -52,28 +50,22 @@ class StringName {
struct _Data {
SafeRefCount refcount;
- const char *cname;
+ const char *cname = nullptr;
String name;
String get_name() const { return cname ? String(cname) : name; }
- int idx;
- uint32_t hash;
- _Data *prev;
- _Data *next;
- _Data() {
- cname = nullptr;
- next = prev = nullptr;
- idx = 0;
- hash = 0;
- }
+ int idx = 0;
+ uint32_t hash = 0;
+ _Data *prev = nullptr;
+ _Data *next = nullptr;
+ _Data() {}
};
static _Data *_table[STRING_TABLE_LEN];
- _Data *_data;
+ _Data *_data = nullptr;
union _HashUnion {
-
_Data *ptr;
uint32_t hash;
};
@@ -90,13 +82,12 @@ class StringName {
StringName(_Data *p_data) { _data = p_data; }
public:
- operator const void *() const { return (_data && (_data->cname || !_data->name.empty())) ? (void *)1 : 0; }
+ operator const void *() const { return (_data && (_data->cname || !_data->name.empty())) ? (void *)1 : nullptr; }
bool operator==(const String &p_name) const;
bool operator==(const char *p_name) const;
bool operator!=(const String &p_name) const;
_FORCE_INLINE_ bool operator<(const StringName &p_name) const {
-
return _data < p_name._data;
}
_FORCE_INLINE_ bool operator==(const StringName &p_name) const {
@@ -105,11 +96,11 @@ public:
return _data == p_name._data;
}
_FORCE_INLINE_ uint32_t hash() const {
-
- if (_data)
+ if (_data) {
return _data->hash;
- else
+ } else {
return 0;
+ }
}
_FORCE_INLINE_ const void *data_unique_pointer() const {
return (void *)_data;
@@ -117,12 +108,12 @@ public:
bool operator!=(const StringName &p_name) const;
_FORCE_INLINE_ operator String() const {
-
if (_data) {
- if (_data->cname)
+ if (_data->cname) {
return String(_data->cname);
- else
+ } else {
return _data->name;
+ }
}
return String();
@@ -133,24 +124,22 @@ public:
static StringName search(const String &p_name);
struct AlphCompare {
-
_FORCE_INLINE_ bool operator()(const StringName &l, const StringName &r) const {
-
const char *l_cname = l._data ? l._data->cname : "";
const char *r_cname = r._data ? r._data->cname : "";
if (l_cname) {
-
- if (r_cname)
+ if (r_cname) {
return is_str_less(l_cname, r_cname);
- else
+ } else {
return is_str_less(l_cname, r._data->name.ptr());
+ }
} else {
-
- if (r_cname)
+ if (r_cname) {
return is_str_less(l._data->name.ptr(), r_cname);
- else
+ } else {
return is_str_less(l._data->name.ptr(), r._data->name.ptr());
+ }
}
}
};
@@ -160,7 +149,7 @@ public:
StringName(const StringName &p_name);
StringName(const String &p_name);
StringName(const StaticCString &p_static_string);
- StringName();
+ StringName() {}
~StringName();
};
diff --git a/core/thread_work_pool.cpp b/core/thread_work_pool.cpp
index c8311f102f..3a95e83ffc 100644
--- a/core/thread_work_pool.cpp
+++ b/core/thread_work_pool.cpp
@@ -29,10 +29,10 @@
/*************************************************************************/
#include "thread_work_pool.h"
+
#include "core/os/os.h"
void ThreadWorkPool::_thread_function(ThreadData *p_thread) {
-
while (true) {
p_thread->start.wait();
if (p_thread->exit.load()) {
@@ -59,7 +59,6 @@ void ThreadWorkPool::init(int p_thread_count) {
}
void ThreadWorkPool::finish() {
-
if (threads == nullptr) {
return;
}
@@ -78,6 +77,5 @@ void ThreadWorkPool::finish() {
}
ThreadWorkPool::~ThreadWorkPool() {
-
finish();
}
diff --git a/core/thread_work_pool.h b/core/thread_work_pool.h
index 214d2c4aa7..e21d3974ee 100644
--- a/core/thread_work_pool.h
+++ b/core/thread_work_pool.h
@@ -33,10 +33,11 @@
#include "core/os/memory.h"
#include "core/os/semaphore.h"
+
#include <atomic>
#include <thread>
-class ThreadWorkPool {
+class ThreadWorkPool {
std::atomic<uint32_t> index;
struct BaseWork {
@@ -52,7 +53,6 @@ class ThreadWorkPool {
M method;
U userdata;
virtual void work() {
-
while (true) {
uint32_t work_index = index->fetch_add(1, std::memory_order_relaxed);
if (work_index >= max_elements) {
@@ -79,7 +79,6 @@ class ThreadWorkPool {
public:
template <class C, class M, class U>
void do_work(uint32_t p_elements, C *p_instance, M p_method, U p_userdata) {
-
ERR_FAIL_COND(!threads); //never initialized
index.store(0);
diff --git a/core/translation.cpp b/core/translation.cpp
index 3f45bb17c9..4f835bd7b4 100644
--- a/core/translation.cpp
+++ b/core/translation.cpp
@@ -795,12 +795,10 @@ static const char *locale_renames[][2] = {
///////////////////////////////////////////////
Vector<String> Translation::_get_messages() const {
-
Vector<String> msgs;
msgs.resize(translation_map.size() * 2);
int idx = 0;
for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) {
-
msgs.set(idx + 0, E->key());
msgs.set(idx + 1, E->get());
idx += 2;
@@ -810,12 +808,10 @@ Vector<String> Translation::_get_messages() const {
}
Vector<String> Translation::_get_message_list() const {
-
Vector<String> msgs;
msgs.resize(translation_map.size());
int idx = 0;
for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) {
-
msgs.set(idx, E->key());
idx += 1;
}
@@ -824,20 +820,17 @@ Vector<String> Translation::_get_message_list() const {
}
void Translation::_set_messages(const Vector<String> &p_messages) {
-
int msg_count = p_messages.size();
ERR_FAIL_COND(msg_count % 2);
const String *r = p_messages.ptr();
for (int i = 0; i < msg_count; i += 2) {
-
add_message(r[i + 0], r[i + 1]);
}
}
void Translation::set_locale(const String &p_locale) {
-
String univ_locale = TranslationServer::standardize_locale(p_locale);
if (!TranslationServer::is_locale_valid(univ_locale)) {
@@ -856,38 +849,33 @@ void Translation::set_locale(const String &p_locale) {
}
void Translation::add_message(const StringName &p_src_text, const StringName &p_xlated_text) {
-
translation_map[p_src_text] = p_xlated_text;
}
-StringName Translation::get_message(const StringName &p_src_text) const {
+StringName Translation::get_message(const StringName &p_src_text) const {
const Map<StringName, StringName>::Element *E = translation_map.find(p_src_text);
- if (!E)
+ if (!E) {
return StringName();
+ }
return E->get();
}
void Translation::erase_message(const StringName &p_src_text) {
-
translation_map.erase(p_src_text);
}
void Translation::get_message_list(List<StringName> *r_messages) const {
-
for (const Map<StringName, StringName>::Element *E = translation_map.front(); E; E = E->next()) {
-
r_messages->push_back(E->key());
}
}
int Translation::get_message_count() const {
-
return translation_map.size();
-};
+}
void Translation::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_locale", "locale"), &Translation::set_locale);
ClassDB::bind_method(D_METHOD("get_locale"), &Translation::get_locale);
ClassDB::bind_method(D_METHOD("add_message", "src_message", "xlated_message"), &Translation::add_message);
@@ -902,20 +890,15 @@ void Translation::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "locale"), "set_locale", "get_locale");
}
-Translation::Translation() :
- locale("en") {
-}
-
///////////////////////////////////////////////
bool TranslationServer::is_locale_valid(const String &p_locale) {
-
const char **ptr = locale_list;
while (*ptr) {
-
- if (*ptr == p_locale)
+ if (*ptr == p_locale) {
return true;
+ }
ptr++;
}
@@ -923,7 +906,6 @@ bool TranslationServer::is_locale_valid(const String &p_locale) {
}
String TranslationServer::standardize_locale(const String &p_locale) {
-
// Replaces '-' with '_' for macOS Sierra-style locales
String univ_locale = p_locale.replace("-", "_");
@@ -941,7 +923,6 @@ String TranslationServer::standardize_locale(const String &p_locale) {
}
String TranslationServer::get_language_code(const String &p_locale) {
-
ERR_FAIL_COND_V_MSG(p_locale.length() < 2, p_locale, "Invalid locale '" + p_locale + "'.");
// Most language codes are two letters, but some are three,
// so we have to look for a regional code separator ('_' or '-')
@@ -958,7 +939,6 @@ String TranslationServer::get_language_code(const String &p_locale) {
}
void TranslationServer::set_locale(const String &p_locale) {
-
String univ_locale = standardize_locale(p_locale);
if (!is_locale_valid(univ_locale)) {
@@ -983,20 +963,19 @@ void TranslationServer::set_locale(const String &p_locale) {
}
String TranslationServer::get_locale() const {
-
return locale;
}
String TranslationServer::get_locale_name(const String &p_locale) const {
-
- if (!locale_name_map.has(p_locale)) return String();
+ if (!locale_name_map.has(p_locale)) {
+ return String();
+ }
return locale_name_map[p_locale];
}
Array TranslationServer::get_loaded_locales() const {
Array locales;
for (const Set<Ref<Translation>>::Element *E = translations.front(); E; E = E->next()) {
-
const Ref<Translation> &t = E->get();
ERR_FAIL_COND_V(t.is_null(), Array());
String l = t->get_locale();
@@ -1008,7 +987,6 @@ Array TranslationServer::get_loaded_locales() const {
}
Vector<String> TranslationServer::get_all_locales() {
-
Vector<String> locales;
const char **ptr = locale_list;
@@ -1022,7 +1000,6 @@ Vector<String> TranslationServer::get_all_locales() {
}
Vector<String> TranslationServer::get_all_locale_names() {
-
Vector<String> locales;
const char **ptr = locale_names;
@@ -1036,25 +1013,23 @@ Vector<String> TranslationServer::get_all_locale_names() {
}
void TranslationServer::add_translation(const Ref<Translation> &p_translation) {
-
translations.insert(p_translation);
}
-void TranslationServer::remove_translation(const Ref<Translation> &p_translation) {
+void TranslationServer::remove_translation(const Ref<Translation> &p_translation) {
translations.erase(p_translation);
}
void TranslationServer::clear() {
-
translations.clear();
-};
+}
StringName TranslationServer::translate(const StringName &p_message) const {
-
// Match given message against the translation catalog for the project locale.
- if (!enabled)
+ if (!enabled) {
return p_message;
+ }
ERR_FAIL_COND_V_MSG(locale.length() < 2, p_message, "Could not translate message as configured locale '" + locale + "' is invalid.");
@@ -1144,7 +1119,6 @@ StringName TranslationServer::translate(const StringName &p_message) const {
TranslationServer *TranslationServer::singleton = nullptr;
bool TranslationServer::_load_translations(const String &p_from) {
-
if (ProjectSettings::get_singleton()->has_setting(p_from)) {
Vector<String> translations = ProjectSettings::get_singleton()->get(p_from);
@@ -1154,10 +1128,10 @@ bool TranslationServer::_load_translations(const String &p_from) {
const String *r = translations.ptr();
for (int i = 0; i < tcount; i++) {
-
Ref<Translation> tr = ResourceLoader::load(r[i]);
- if (tr.is_valid())
+ if (tr.is_valid()) {
add_translation(tr);
+ }
}
}
return true;
@@ -1167,21 +1141,22 @@ bool TranslationServer::_load_translations(const String &p_from) {
}
void TranslationServer::setup() {
-
String test = GLOBAL_DEF("locale/test", "");
test = test.strip_edges();
- if (test != "")
+ if (test != "") {
set_locale(test);
- else
+ } else {
set_locale(OS::get_singleton()->get_locale());
+ }
fallback = GLOBAL_DEF("locale/fallback", "en");
#ifdef TOOLS_ENABLED
{
String options = "";
int idx = 0;
while (locale_list[idx]) {
- if (idx > 0)
+ if (idx > 0) {
options += ",";
+ }
options += locale_list[idx];
idx++;
}
@@ -1219,7 +1194,6 @@ StringName TranslationServer::doc_translate(const StringName &p_message) const {
}
void TranslationServer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_locale", "locale"), &TranslationServer::set_locale);
ClassDB::bind_method(D_METHOD("get_locale"), &TranslationServer::get_locale);
@@ -1236,7 +1210,6 @@ void TranslationServer::_bind_methods() {
}
void TranslationServer::load_translations() {
-
String locale = get_locale();
_load_translations("locale/translations"); //all
_load_translations("locale/translations_" + locale.substr(0, 2));
@@ -1246,13 +1219,10 @@ void TranslationServer::load_translations() {
}
}
-TranslationServer::TranslationServer() :
- locale("en"),
- enabled(true) {
+TranslationServer::TranslationServer() {
singleton = this;
for (int i = 0; locale_list[i]; ++i) {
-
locale_name_map.insert(locale_list[i], String::utf8(locale_names[i]));
}
}
diff --git a/core/translation.h b/core/translation.h
index 29a068f450..4f50a1a4bc 100644
--- a/core/translation.h
+++ b/core/translation.h
@@ -34,12 +34,11 @@
#include "core/resource.h"
class Translation : public Resource {
-
GDCLASS(Translation, Resource);
OBJ_SAVE_TYPE(Translation);
RES_BASE_EXTENSION("translation");
- String locale;
+ String locale = "en";
Map<StringName, StringName> translation_map;
Vector<String> _get_message_list() const;
@@ -61,14 +60,13 @@ public:
void get_message_list(List<StringName> *r_messages) const;
int get_message_count() const;
- Translation();
+ Translation() {}
};
class TranslationServer : public Object {
-
GDCLASS(TranslationServer, Object);
- String locale;
+ String locale = "en";
String fallback;
Set<Ref<Translation>> translations;
@@ -77,7 +75,7 @@ class TranslationServer : public Object {
Map<String, String> locale_name_map;
- bool enabled;
+ bool enabled = true;
static TranslationServer *singleton;
bool _load_translations(const String &p_from);
diff --git a/core/type_info.h b/core/type_info.h
index 816d0d9381..e3d2b5bd53 100644
--- a/core/type_info.h
+++ b/core/type_info.h
@@ -35,7 +35,6 @@
template <bool C, typename T = void>
struct EnableIf {
-
typedef T type;
};
@@ -45,19 +44,16 @@ struct EnableIf<false, T> {
template <typename, typename>
struct TypesAreSame {
-
static bool const value = false;
};
template <typename A>
struct TypesAreSame<A, A> {
-
static bool const value = true;
};
template <typename B, typename D>
struct TypeInherits {
-
static D *get_d();
static char (&test(B *))[1];
@@ -262,8 +258,9 @@ struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>:
template <typename T>
inline StringName __constant_get_enum_name(T param, const String &p_constant) {
- if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL)
+ if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) {
ERR_PRINT("Missing VARIANT_ENUM_CAST for constant's enum: " + p_constant);
+ }
return GetTypeInfo<T>::get_class_info().class_name;
}
diff --git a/core/typed_array.h b/core/typed_array.h
new file mode 100644
index 0000000000..86f26d7550
--- /dev/null
+++ b/core/typed_array.h
@@ -0,0 +1,227 @@
+/*************************************************************************/
+/* typed_array.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TYPED_ARRAY_H
+#define TYPED_ARRAY_H
+
+#include "core/array.h"
+#include "core/method_ptrcall.h"
+#include "core/variant.h"
+
+template <class T>
+class TypedArray : public Array {
+public:
+ template <class U>
+ _FORCE_INLINE_ void operator=(const TypedArray<U> &p_array) {
+ static_assert(__is_base_of(T, U));
+ _assign(p_array);
+ }
+
+ _FORCE_INLINE_ void operator=(const Array &p_array) {
+ _assign(p_array);
+ }
+ _FORCE_INLINE_ TypedArray(const Variant &p_variant) :
+ Array(Array(p_variant), Variant::OBJECT, T::get_class_static(), Variant()) {
+ }
+ _FORCE_INLINE_ TypedArray(const Array &p_array) :
+ Array(p_array, Variant::OBJECT, T::get_class_static(), Variant()) {
+ }
+ _FORCE_INLINE_ TypedArray() {
+ set_typed(Variant::OBJECT, T::get_class_static(), Variant());
+ }
+};
+
+//specialization for the rest of variant types
+
+#define MAKE_TYPED_ARRAY(m_type, m_variant_type) \
+ template <> \
+ class TypedArray<m_type> : public Array { \
+ public: \
+ _FORCE_INLINE_ void operator=(const Array &p_array) { \
+ _assign(p_array); \
+ } \
+ _FORCE_INLINE_ TypedArray(const Variant &p_variant) : \
+ Array(Array(p_variant), m_variant_type, StringName(), Variant()) { \
+ } \
+ _FORCE_INLINE_ TypedArray(const Array &p_array) : \
+ Array(p_array, m_variant_type, StringName(), Variant()) { \
+ } \
+ _FORCE_INLINE_ TypedArray() { \
+ set_typed(m_variant_type, StringName(), Variant()); \
+ } \
+ };
+
+MAKE_TYPED_ARRAY(bool, Variant::BOOL)
+MAKE_TYPED_ARRAY(uint8_t, Variant::INT)
+MAKE_TYPED_ARRAY(int8_t, Variant::INT)
+MAKE_TYPED_ARRAY(uint16_t, Variant::INT)
+MAKE_TYPED_ARRAY(int16_t, Variant::INT)
+MAKE_TYPED_ARRAY(uint32_t, Variant::INT)
+MAKE_TYPED_ARRAY(int32_t, Variant::INT)
+MAKE_TYPED_ARRAY(uint64_t, Variant::INT)
+MAKE_TYPED_ARRAY(int64_t, Variant::INT)
+MAKE_TYPED_ARRAY(float, Variant::FLOAT)
+MAKE_TYPED_ARRAY(double, Variant::FLOAT)
+MAKE_TYPED_ARRAY(String, Variant::STRING)
+MAKE_TYPED_ARRAY(Vector2, Variant::VECTOR2)
+MAKE_TYPED_ARRAY(Vector2i, Variant::VECTOR2I)
+MAKE_TYPED_ARRAY(Rect2, Variant::RECT2)
+MAKE_TYPED_ARRAY(Rect2i, Variant::RECT2I)
+MAKE_TYPED_ARRAY(Vector3, Variant::VECTOR3)
+MAKE_TYPED_ARRAY(Vector3i, Variant::VECTOR3I)
+MAKE_TYPED_ARRAY(Transform2D, Variant::TRANSFORM2D)
+MAKE_TYPED_ARRAY(Plane, Variant::PLANE)
+MAKE_TYPED_ARRAY(Quat, Variant::QUAT)
+MAKE_TYPED_ARRAY(AABB, Variant::AABB)
+MAKE_TYPED_ARRAY(Basis, Variant::BASIS)
+MAKE_TYPED_ARRAY(Transform, Variant::TRANSFORM)
+MAKE_TYPED_ARRAY(Color, Variant::COLOR)
+MAKE_TYPED_ARRAY(StringName, Variant::STRING_NAME)
+MAKE_TYPED_ARRAY(NodePath, Variant::NODE_PATH)
+MAKE_TYPED_ARRAY(RID, Variant::_RID)
+MAKE_TYPED_ARRAY(Callable, Variant::CALLABLE)
+MAKE_TYPED_ARRAY(Signal, Variant::SIGNAL)
+MAKE_TYPED_ARRAY(Dictionary, Variant::DICTIONARY)
+MAKE_TYPED_ARRAY(Array, Variant::ARRAY)
+MAKE_TYPED_ARRAY(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY)
+MAKE_TYPED_ARRAY(Vector<int32_t>, Variant::PACKED_INT32_ARRAY)
+MAKE_TYPED_ARRAY(Vector<int64_t>, Variant::PACKED_INT64_ARRAY)
+MAKE_TYPED_ARRAY(Vector<float>, Variant::PACKED_FLOAT32_ARRAY)
+MAKE_TYPED_ARRAY(Vector<double>, Variant::PACKED_FLOAT64_ARRAY)
+MAKE_TYPED_ARRAY(Vector<String>, Variant::PACKED_STRING_ARRAY)
+MAKE_TYPED_ARRAY(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
+MAKE_TYPED_ARRAY(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TYPED_ARRAY(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
+
+#ifdef PTRCALL_ENABLED
+
+template <class T>
+struct PtrToArg<TypedArray<T>> {
+ _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
+ return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr));
+ }
+
+ _FORCE_INLINE_ static void encode(TypedArray<T> p_val, void *p_ptr) {
+ *(Array *)p_ptr = p_val;
+ }
+};
+
+template <class T>
+struct PtrToArg<const TypedArray<T> &> {
+ _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
+ return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr));
+ }
+};
+
+#endif // PTRCALL_ENABLED
+
+#ifdef DEBUG_METHODS_ENABLED
+
+template <class T>
+struct GetTypeInfo<TypedArray<T>> {
+ static const Variant::Type VARIANT_TYPE = Variant::ARRAY;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
+ static inline PropertyInfo get_class_info() {
+ return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, T::get_class_static());
+ }
+};
+
+template <class T>
+struct GetTypeInfo<const TypedArray<T> &> {
+ static const Variant::Type VARIANT_TYPE = Variant::ARRAY;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
+ static inline PropertyInfo get_class_info() {
+ return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, T::get_class_static());
+ }
+};
+
+#define MAKE_TYPED_ARRAY_INFO(m_type, m_variant_type) \
+ template <> \
+ struct GetTypeInfo<TypedArray<m_type>> { \
+ static const Variant::Type VARIANT_TYPE = Variant::ARRAY; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \
+ } \
+ }; \
+ template <> \
+ struct GetTypeInfo<const TypedArray<m_type> &> { \
+ static const Variant::Type VARIANT_TYPE = Variant::ARRAY; \
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE; \
+ static inline PropertyInfo get_class_info() { \
+ return PropertyInfo(Variant::ARRAY, String(), PROPERTY_HINT_ARRAY_TYPE, Variant::get_type_name(m_variant_type)); \
+ } \
+ };
+
+MAKE_TYPED_ARRAY_INFO(bool, Variant::BOOL)
+MAKE_TYPED_ARRAY_INFO(uint8_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(int8_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(uint16_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(int16_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(uint32_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(int32_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(uint64_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(int64_t, Variant::INT)
+MAKE_TYPED_ARRAY_INFO(float, Variant::FLOAT)
+MAKE_TYPED_ARRAY_INFO(double, Variant::FLOAT)
+MAKE_TYPED_ARRAY_INFO(String, Variant::STRING)
+MAKE_TYPED_ARRAY_INFO(Vector2, Variant::VECTOR2)
+MAKE_TYPED_ARRAY_INFO(Vector2i, Variant::VECTOR2I)
+MAKE_TYPED_ARRAY_INFO(Rect2, Variant::RECT2)
+MAKE_TYPED_ARRAY_INFO(Rect2i, Variant::RECT2I)
+MAKE_TYPED_ARRAY_INFO(Vector3, Variant::VECTOR3)
+MAKE_TYPED_ARRAY_INFO(Vector3i, Variant::VECTOR3I)
+MAKE_TYPED_ARRAY_INFO(Transform2D, Variant::TRANSFORM2D)
+MAKE_TYPED_ARRAY_INFO(Plane, Variant::PLANE)
+MAKE_TYPED_ARRAY_INFO(Quat, Variant::QUAT)
+MAKE_TYPED_ARRAY_INFO(AABB, Variant::AABB)
+MAKE_TYPED_ARRAY_INFO(Basis, Variant::BASIS)
+MAKE_TYPED_ARRAY_INFO(Transform, Variant::TRANSFORM)
+MAKE_TYPED_ARRAY_INFO(Color, Variant::COLOR)
+MAKE_TYPED_ARRAY_INFO(StringName, Variant::STRING_NAME)
+MAKE_TYPED_ARRAY_INFO(NodePath, Variant::NODE_PATH)
+MAKE_TYPED_ARRAY_INFO(RID, Variant::_RID)
+MAKE_TYPED_ARRAY_INFO(Callable, Variant::CALLABLE)
+MAKE_TYPED_ARRAY_INFO(Signal, Variant::SIGNAL)
+MAKE_TYPED_ARRAY_INFO(Dictionary, Variant::DICTIONARY)
+MAKE_TYPED_ARRAY_INFO(Array, Variant::ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<uint8_t>, Variant::PACKED_BYTE_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<int32_t>, Variant::PACKED_INT32_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<int64_t>, Variant::PACKED_INT64_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<float>, Variant::PACKED_FLOAT32_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<double>, Variant::PACKED_FLOAT64_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<String>, Variant::PACKED_STRING_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
+MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
+
+#endif
+
+#endif // TYPED_ARRAY_H
diff --git a/core/typedefs.h b/core/typedefs.h
index bafbffcded..4bfa5debac 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -185,8 +185,9 @@ static _FORCE_INLINE_ T nearest_power_of_2_templated(T x) {
// Function to find the nearest (bigger) power of 2 to an integer.
static inline unsigned int nearest_shift(unsigned int p_number) {
for (int i = 30; i >= 0; i--) {
- if (p_number & (1 << i))
+ if (p_number & (1 << i)) {
return i + 1;
+ }
}
return 0;
diff --git a/core/ucaps.h b/core/ucaps.h
index ad71731617..79b346acba 100644
--- a/core/ucaps.h
+++ b/core/ucaps.h
@@ -1373,7 +1373,6 @@ static const int reverse_caps_table[CAPS_LEN - 1][2] = {
};
static int _find_upper(int ch) {
-
int low = 0;
int high = CAPS_LEN - 1;
int middle;
@@ -1394,7 +1393,6 @@ static int _find_upper(int ch) {
}
static int _find_lower(int ch) {
-
int low = 0;
int high = CAPS_LEN - 2;
int middle;
diff --git a/core/undo_redo.cpp b/core/undo_redo.cpp
index 62ad3e9f98..90750f2c6e 100644
--- a/core/undo_redo.cpp
+++ b/core/undo_redo.cpp
@@ -33,19 +33,17 @@
#include "core/os/os.h"
void UndoRedo::_discard_redo() {
-
- if (current_action == actions.size() - 1)
+ if (current_action == actions.size() - 1) {
return;
+ }
for (int i = current_action + 1; i < actions.size(); i++) {
-
for (List<Operation>::Element *E = actions.write[i].do_ops.front(); E; E = E->next()) {
-
if (E->get().type == Operation::TYPE_REFERENCE) {
-
Object *obj = ObjectDB::get_instance(E->get().object);
- if (obj)
+ if (obj) {
memdelete(obj);
+ }
}
}
//ERASE do data
@@ -55,31 +53,26 @@ void UndoRedo::_discard_redo() {
}
void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
-
uint32_t ticks = OS::get_singleton()->get_ticks_msec();
if (action_level == 0) {
-
_discard_redo();
// Check if the merge operation is valid
if (p_mode != MERGE_DISABLE && actions.size() && actions[actions.size() - 1].name == p_name && actions[actions.size() - 1].last_tick + 800 > ticks) {
-
current_action = actions.size() - 2;
if (p_mode == MERGE_ENDS) {
-
// Clear all do ops from last action, and delete all object references
List<Operation>::Element *E = actions.write[current_action + 1].do_ops.front();
while (E) {
-
if (E->get().type == Operation::TYPE_REFERENCE) {
-
Object *obj = ObjectDB::get_instance(E->get().object);
- if (obj)
+ if (obj) {
memdelete(obj);
+ }
}
E = E->next();
@@ -92,7 +85,6 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
merge_mode = p_mode;
merging = true;
} else {
-
Action new_action;
new_action.name = p_name;
new_action.last_tick = ticks;
@@ -106,15 +98,15 @@ void UndoRedo::create_action(const String &p_name, MergeMode p_mode) {
}
void UndoRedo::add_do_method(Object *p_object, const StringName &p_method, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS
ERR_FAIL_COND(p_object == nullptr);
ERR_FAIL_COND(action_level <= 0);
ERR_FAIL_COND((current_action + 1) >= actions.size());
Operation do_op;
do_op.object = p_object->get_instance_id();
- if (Object::cast_to<Resource>(p_object))
+ if (Object::cast_to<Resource>(p_object)) {
do_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
+ }
do_op.type = Operation::TYPE_METHOD;
do_op.name = p_method;
@@ -126,20 +118,21 @@ void UndoRedo::add_do_method(Object *p_object, const StringName &p_method, VARIA
}
void UndoRedo::add_undo_method(Object *p_object, const StringName &p_method, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS
ERR_FAIL_COND(p_object == nullptr);
ERR_FAIL_COND(action_level <= 0);
ERR_FAIL_COND((current_action + 1) >= actions.size());
// No undo if the merge mode is MERGE_ENDS
- if (merge_mode == MERGE_ENDS)
+ if (merge_mode == MERGE_ENDS) {
return;
+ }
Operation undo_op;
undo_op.object = p_object->get_instance_id();
- if (Object::cast_to<Resource>(p_object))
+ if (Object::cast_to<Resource>(p_object)) {
undo_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
+ }
undo_op.type = Operation::TYPE_METHOD;
undo_op.name = p_method;
@@ -149,87 +142,92 @@ void UndoRedo::add_undo_method(Object *p_object, const StringName &p_method, VAR
}
actions.write[current_action + 1].undo_ops.push_back(undo_op);
}
-void UndoRedo::add_do_property(Object *p_object, const StringName &p_property, const Variant &p_value) {
+void UndoRedo::add_do_property(Object *p_object, const StringName &p_property, const Variant &p_value) {
ERR_FAIL_COND(p_object == nullptr);
ERR_FAIL_COND(action_level <= 0);
ERR_FAIL_COND((current_action + 1) >= actions.size());
Operation do_op;
do_op.object = p_object->get_instance_id();
- if (Object::cast_to<Resource>(p_object))
+ if (Object::cast_to<Resource>(p_object)) {
do_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
+ }
do_op.type = Operation::TYPE_PROPERTY;
do_op.name = p_property;
do_op.args[0] = p_value;
actions.write[current_action + 1].do_ops.push_back(do_op);
}
-void UndoRedo::add_undo_property(Object *p_object, const StringName &p_property, const Variant &p_value) {
+void UndoRedo::add_undo_property(Object *p_object, const StringName &p_property, const Variant &p_value) {
ERR_FAIL_COND(p_object == nullptr);
ERR_FAIL_COND(action_level <= 0);
ERR_FAIL_COND((current_action + 1) >= actions.size());
// No undo if the merge mode is MERGE_ENDS
- if (merge_mode == MERGE_ENDS)
+ if (merge_mode == MERGE_ENDS) {
return;
+ }
Operation undo_op;
undo_op.object = p_object->get_instance_id();
- if (Object::cast_to<Resource>(p_object))
+ if (Object::cast_to<Resource>(p_object)) {
undo_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
+ }
undo_op.type = Operation::TYPE_PROPERTY;
undo_op.name = p_property;
undo_op.args[0] = p_value;
actions.write[current_action + 1].undo_ops.push_back(undo_op);
}
-void UndoRedo::add_do_reference(Object *p_object) {
+void UndoRedo::add_do_reference(Object *p_object) {
ERR_FAIL_COND(p_object == nullptr);
ERR_FAIL_COND(action_level <= 0);
ERR_FAIL_COND((current_action + 1) >= actions.size());
Operation do_op;
do_op.object = p_object->get_instance_id();
- if (Object::cast_to<Resource>(p_object))
+ if (Object::cast_to<Resource>(p_object)) {
do_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
+ }
do_op.type = Operation::TYPE_REFERENCE;
actions.write[current_action + 1].do_ops.push_back(do_op);
}
-void UndoRedo::add_undo_reference(Object *p_object) {
+void UndoRedo::add_undo_reference(Object *p_object) {
ERR_FAIL_COND(p_object == nullptr);
ERR_FAIL_COND(action_level <= 0);
ERR_FAIL_COND((current_action + 1) >= actions.size());
// No undo if the merge mode is MERGE_ENDS
- if (merge_mode == MERGE_ENDS)
+ if (merge_mode == MERGE_ENDS) {
return;
+ }
Operation undo_op;
undo_op.object = p_object->get_instance_id();
- if (Object::cast_to<Resource>(p_object))
+ if (Object::cast_to<Resource>(p_object)) {
undo_op.resref = Ref<Resource>(Object::cast_to<Resource>(p_object));
+ }
undo_op.type = Operation::TYPE_REFERENCE;
actions.write[current_action + 1].undo_ops.push_back(undo_op);
}
void UndoRedo::_pop_history_tail() {
-
_discard_redo();
- if (!actions.size())
+ if (!actions.size()) {
return;
+ }
for (List<Operation>::Element *E = actions.write[0].undo_ops.front(); E; E = E->next()) {
-
if (E->get().type == Operation::TYPE_REFERENCE) {
-
Object *obj = ObjectDB::get_instance(E->get().object);
- if (obj)
+ if (obj) {
memdelete(obj);
+ }
}
}
@@ -244,11 +242,11 @@ bool UndoRedo::is_committing_action() const {
}
void UndoRedo::commit_action() {
-
ERR_FAIL_COND(action_level <= 0);
action_level--;
- if (action_level > 0)
+ if (action_level > 0) {
return; //still nested
+ }
if (merging) {
version--;
@@ -264,19 +262,16 @@ void UndoRedo::commit_action() {
}
void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
-
for (; E; E = E->next()) {
-
Operation &op = E->get();
Object *obj = ObjectDB::get_instance(op.object);
- if (!obj) //may have been deleted and this is fine
+ if (!obj) { //may have been deleted and this is fine
continue;
+ }
switch (op.type) {
-
case Operation::TYPE_METHOD: {
-
Vector<const Variant *> argptrs;
argptrs.resize(VARIANT_ARG_MAX);
int argc = 0;
@@ -297,8 +292,9 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
}
#ifdef TOOLS_ENABLED
Resource *res = Object::cast_to<Resource>(obj);
- if (res)
+ if (res) {
res->set_edited(true);
+ }
#endif
@@ -307,12 +303,12 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
}
} break;
case Operation::TYPE_PROPERTY: {
-
obj->set(op.name, op.args[0]);
#ifdef TOOLS_ENABLED
Resource *res = Object::cast_to<Resource>(obj);
- if (res)
+ if (res) {
res->set_edited(true);
+ }
#endif
if (property_callback) {
property_callback(prop_callback_ud, obj, op.name, op.args[0]);
@@ -326,11 +322,11 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
}
bool UndoRedo::redo() {
-
ERR_FAIL_COND_V(action_level > 0, false);
- if ((current_action + 1) >= actions.size())
+ if ((current_action + 1) >= actions.size()) {
return false; //nothing to redo
+ }
current_action++;
@@ -342,10 +338,10 @@ bool UndoRedo::redo() {
}
bool UndoRedo::undo() {
-
ERR_FAIL_COND_V(action_level > 0, false);
- if (current_action < 0)
+ if (current_action < 0) {
return false; //nothing to redo
+ }
_process_operation_list(actions.write[current_action].undo_ops.front());
current_action--;
version--;
@@ -355,12 +351,12 @@ bool UndoRedo::undo() {
}
void UndoRedo::clear_history(bool p_increase_version) {
-
ERR_FAIL_COND(action_level > 0);
_discard_redo();
- while (actions.size())
+ while (actions.size()) {
_pop_history_tail();
+ }
if (p_increase_version) {
version++;
@@ -369,70 +365,45 @@ void UndoRedo::clear_history(bool p_increase_version) {
}
String UndoRedo::get_current_action_name() const {
-
ERR_FAIL_COND_V(action_level > 0, "");
- if (current_action < 0)
+ if (current_action < 0) {
return "";
+ }
return actions[current_action].name;
}
bool UndoRedo::has_undo() {
-
return current_action >= 0;
}
bool UndoRedo::has_redo() {
-
return (current_action + 1) < actions.size();
}
uint64_t UndoRedo::get_version() const {
-
return version;
}
void UndoRedo::set_commit_notify_callback(CommitNotifyCallback p_callback, void *p_ud) {
-
callback = p_callback;
callback_ud = p_ud;
}
void UndoRedo::set_method_notify_callback(MethodNotifyCallback p_method_callback, void *p_ud) {
-
method_callback = p_method_callback;
method_callbck_ud = p_ud;
}
void UndoRedo::set_property_notify_callback(PropertyNotifyCallback p_property_callback, void *p_ud) {
-
property_callback = p_property_callback;
prop_callback_ud = p_ud;
}
-UndoRedo::UndoRedo() {
-
- committing = 0;
- version = 1;
- action_level = 0;
- current_action = -1;
- merge_mode = MERGE_DISABLE;
- merging = false;
- callback = nullptr;
- callback_ud = nullptr;
-
- method_callbck_ud = nullptr;
- prop_callback_ud = nullptr;
- method_callback = nullptr;
- property_callback = nullptr;
-}
-
UndoRedo::~UndoRedo() {
-
clear_history();
}
Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (p_argcount < 2) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
@@ -461,7 +432,6 @@ Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Callabl
Variant v[VARIANT_ARG_MAX];
for (int i = 0; i < MIN(VARIANT_ARG_MAX, p_argcount - 2); ++i) {
-
v[i] = *p_args[i + 2];
}
@@ -470,7 +440,6 @@ Variant UndoRedo::_add_do_method(const Variant **p_args, int p_argcount, Callabl
}
Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (p_argcount < 2) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
@@ -499,7 +468,6 @@ Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Calla
Variant v[VARIANT_ARG_MAX];
for (int i = 0; i < MIN(VARIANT_ARG_MAX, p_argcount - 2); ++i) {
-
v[i] = *p_args[i + 2];
}
@@ -508,7 +476,6 @@ Variant UndoRedo::_add_undo_method(const Variant **p_args, int p_argcount, Calla
}
void UndoRedo::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("create_action", "name", "merge_mode"), &UndoRedo::create_action, DEFVAL(MERGE_DISABLE));
ClassDB::bind_method(D_METHOD("commit_action"), &UndoRedo::commit_action);
ClassDB::bind_method(D_METHOD("is_committing_action"), &UndoRedo::is_committing_action);
diff --git a/core/undo_redo.h b/core/undo_redo.h
index 3b91e9ce36..b46f7ff867 100644
--- a/core/undo_redo.h
+++ b/core/undo_redo.h
@@ -35,7 +35,6 @@
#include "core/resource.h"
class UndoRedo : public Object {
-
GDCLASS(UndoRedo, Object);
OBJ_SAVE_TYPE(UndoRedo);
@@ -55,7 +54,6 @@ public:
private:
struct Operation {
-
enum Type {
TYPE_METHOD,
TYPE_PROPERTY,
@@ -77,25 +75,25 @@ private:
};
Vector<Action> actions;
- int current_action;
- int action_level;
- MergeMode merge_mode;
- bool merging;
- uint64_t version;
+ int current_action = -1;
+ int action_level = 0;
+ MergeMode merge_mode = MERGE_DISABLE;
+ bool merging = false;
+ uint64_t version = 1;
void _pop_history_tail();
void _process_operation_list(List<Operation>::Element *E);
void _discard_redo();
- CommitNotifyCallback callback;
- void *callback_ud;
- void *method_callbck_ud;
- void *prop_callback_ud;
+ CommitNotifyCallback callback = nullptr;
+ void *callback_ud = nullptr;
+ void *method_callbck_ud = nullptr;
+ void *prop_callback_ud = nullptr;
- MethodNotifyCallback method_callback;
- PropertyNotifyCallback property_callback;
+ MethodNotifyCallback method_callback = nullptr;
+ PropertyNotifyCallback property_callback = nullptr;
- int committing;
+ int committing = 0;
protected:
static void _bind_methods();
@@ -128,7 +126,7 @@ public:
void set_method_notify_callback(MethodNotifyCallback p_method_callback, void *p_ud);
void set_property_notify_callback(PropertyNotifyCallback p_property_callback, void *p_ud);
- UndoRedo();
+ UndoRedo() {}
~UndoRedo();
};
diff --git a/core/ustring.cpp b/core/ustring.cpp
index fbe3fcb1b2..7dbaed9fbe 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -28,10 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifdef _MSC_VER
-#define _CRT_SECURE_NO_WARNINGS // to disable build-time warning which suggested to use strcpy_s instead strcpy
-#endif
-
#include "ustring.h"
#include "core/color.h"
@@ -51,6 +47,10 @@
#include <stdlib.h>
#endif
+#ifdef _MSC_VER
+#define _CRT_SECURE_NO_WARNINGS // to disable build-time warning which suggested to use strcpy_s instead strcpy
+#endif
+
#if defined(MINGW_ENABLED) || defined(_MSC_VER)
#define snprintf _snprintf_s
#endif
@@ -69,13 +69,11 @@ bool is_symbol(CharType c) {
}
bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end) {
-
const String &s = p_s;
int beg = CLAMP(p_col, 0, s.length());
int end = beg;
if (s[beg] > 32 || beg == s.length()) {
-
bool symbol = beg < s.length() && is_symbol(s[beg]);
while (beg > 0 && s[beg - 1] > 32 && (symbol == is_symbol(s[beg - 1]))) {
@@ -85,15 +83,15 @@ bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end) {
end++;
}
- if (end < s.length())
+ if (end < s.length()) {
end += 1;
+ }
r_beg = beg;
r_end = end;
return true;
} else {
-
return false;
}
}
@@ -101,7 +99,6 @@ bool select_word(const String &p_s, int p_col, int &r_beg, int &r_end) {
/** STRING **/
bool CharString::operator<(const CharString &p_right) const {
-
if (length() == 0) {
return p_right.length() != 0;
}
@@ -110,7 +107,6 @@ bool CharString::operator<(const CharString &p_right) const {
}
CharString &CharString::operator+=(char p_char) {
-
resize(size() ? size() + 1 : 2);
set(length(), 0);
set(length() - 1, p_char);
@@ -119,21 +115,19 @@ CharString &CharString::operator+=(char p_char) {
}
const char *CharString::get_data() const {
-
- if (size())
+ if (size()) {
return &operator[](0);
- else
+ } else {
return "";
+ }
}
CharString &CharString::operator=(const char *p_cstr) {
-
copy_from(p_cstr);
return *this;
}
void CharString::copy_from(const char *p_cstr) {
-
if (!p_cstr) {
resize(0);
return;
@@ -154,20 +148,18 @@ void CharString::copy_from(const char *p_cstr) {
}
void String::copy_from(const char *p_cstr) {
-
if (!p_cstr) {
-
resize(0);
return;
}
int len = 0;
const char *ptr = p_cstr;
- while (*(ptr++) != 0)
+ while (*(ptr++) != 0) {
len++;
+ }
if (len == 0) {
-
resize(0);
return;
}
@@ -177,26 +169,23 @@ void String::copy_from(const char *p_cstr) {
CharType *dst = this->ptrw();
for (int i = 0; i < len + 1; i++) {
-
dst[i] = p_cstr[i];
}
}
void String::copy_from(const CharType *p_cstr, const int p_clip_to) {
-
if (!p_cstr) {
-
resize(0);
return;
}
int len = 0;
const CharType *ptr = p_cstr;
- while ((p_clip_to < 0 || len < p_clip_to) && *(ptr++) != 0)
+ while ((p_clip_to < 0 || len < p_clip_to) && *(ptr++) != 0) {
len++;
+ }
if (len == 0) {
-
resize(0);
return;
}
@@ -220,18 +209,18 @@ void String::copy_from_unchecked(const CharType *p_char, const int p_length) {
}
void String::copy_from(const CharType &p_char) {
-
resize(2);
set(0, p_char);
set(1, 0);
}
bool String::operator==(const String &p_str) const {
-
- if (length() != p_str.length())
+ if (length() != p_str.length()) {
return false;
- if (empty())
+ }
+ if (empty()) {
return true;
+ }
int l = length();
@@ -240,43 +229,33 @@ bool String::operator==(const String &p_str) const {
/* Compare char by char */
for (int i = 0; i < l; i++) {
-
- if (src[i] != dst[i])
+ if (src[i] != dst[i]) {
return false;
+ }
}
return true;
}
bool String::operator!=(const String &p_str) const {
-
return !(*this == p_str);
}
String String::operator+(const String &p_str) const {
-
String res = *this;
res += p_str;
return res;
}
-/*
-String String::operator+(CharType p_chr) const {
-
- String res=*this;
- res+=p_chr;
- return res;
-}
-*/
String &String::operator+=(const String &p_str) {
-
if (empty()) {
*this = p_str;
return *this;
}
- if (p_str.empty())
+ if (p_str.empty()) {
return *this;
+ }
int from = length();
@@ -287,20 +266,19 @@ String &String::operator+=(const String &p_str) {
set(length(), 0);
- for (int i = 0; i < p_str.length(); i++)
+ for (int i = 0; i < p_str.length(); i++) {
dst[from + i] = src[i];
+ }
return *this;
}
String &String::operator+=(const CharType *p_str) {
-
*this += String(p_str);
return *this;
}
String &String::operator+=(CharType p_char) {
-
resize(size() ? size() + 1 : 2);
set(length(), 0);
set(length() - 1, p_char);
@@ -309,14 +287,15 @@ String &String::operator+=(CharType p_char) {
}
String &String::operator+=(const char *p_str) {
-
- if (!p_str || p_str[0] == 0)
+ if (!p_str || p_str[0] == 0) {
return *this;
+ }
int src_len = 0;
const char *ptr = p_str;
- while (*(ptr++) != 0)
+ while (*(ptr++) != 0) {
src_len++;
+ }
int from = length();
@@ -326,56 +305,58 @@ String &String::operator+=(const char *p_str) {
set(length(), 0);
- for (int i = 0; i < src_len; i++)
+ for (int i = 0; i < src_len; i++) {
dst[from + i] = p_str[i];
+ }
return *this;
}
void String::operator=(const char *p_str) {
-
copy_from(p_str);
}
void String::operator=(const CharType *p_str) {
-
copy_from(p_str);
}
bool String::operator==(const StrRange &p_str_range) const {
-
int len = p_str_range.len;
- if (length() != len)
+ if (length() != len) {
return false;
- if (empty())
+ }
+ if (empty()) {
return true;
+ }
const CharType *c_str = p_str_range.c_str;
const CharType *dst = &operator[](0);
/* Compare char by char */
for (int i = 0; i < len; i++) {
-
- if (c_str[i] != dst[i])
+ if (c_str[i] != dst[i]) {
return false;
+ }
}
return true;
}
bool String::operator==(const char *p_str) const {
-
int len = 0;
const char *aux = p_str;
- while (*(aux++) != 0)
+ while (*(aux++) != 0) {
len++;
+ }
- if (length() != len)
+ if (length() != len) {
return false;
- if (empty())
+ }
+ if (empty()) {
return true;
+ }
int l = length();
@@ -383,26 +364,28 @@ bool String::operator==(const char *p_str) const {
/* Compare char by char */
for (int i = 0; i < l; i++) {
-
- if (p_str[i] != dst[i])
+ if (p_str[i] != dst[i]) {
return false;
+ }
}
return true;
}
bool String::operator==(const CharType *p_str) const {
-
int len = 0;
const CharType *aux = p_str;
- while (*(aux++) != 0)
+ while (*(aux++) != 0) {
len++;
+ }
- if (length() != len)
+ if (length() != len) {
return false;
- if (empty())
+ }
+ if (empty()) {
return true;
+ }
int l = length();
@@ -410,78 +393,78 @@ bool String::operator==(const CharType *p_str) const {
/* Compare char by char */
for (int i = 0; i < l; i++) {
-
- if (p_str[i] != dst[i])
+ if (p_str[i] != dst[i]) {
return false;
+ }
}
return true;
}
bool String::operator!=(const char *p_str) const {
-
return (!(*this == p_str));
}
bool String::operator!=(const CharType *p_str) const {
-
return (!(*this == p_str));
}
bool String::operator<(const CharType *p_str) const {
-
- if (empty() && p_str[0] == 0)
+ if (empty() && p_str[0] == 0) {
return false;
- if (empty())
+ }
+ if (empty()) {
return true;
+ }
return is_str_less(c_str(), p_str);
}
bool String::operator<=(const String &p_str) const {
-
return (*this < p_str) || (*this == p_str);
}
bool String::operator<(const char *p_str) const {
-
- if (empty() && p_str[0] == 0)
+ if (empty() && p_str[0] == 0) {
return false;
- if (empty())
+ }
+ if (empty()) {
return true;
+ }
return is_str_less(c_str(), p_str);
}
bool String::operator<(const String &p_str) const {
-
return operator<(p_str.c_str());
}
signed char String::nocasecmp_to(const String &p_str) const {
-
- if (empty() && p_str.empty())
+ if (empty() && p_str.empty()) {
return 0;
- if (empty())
+ }
+ if (empty()) {
return -1;
- if (p_str.empty())
+ }
+ if (p_str.empty()) {
return 1;
+ }
const CharType *that_str = p_str.c_str();
const CharType *this_str = c_str();
while (true) {
-
- if (*that_str == 0 && *this_str == 0)
+ if (*that_str == 0 && *this_str == 0) {
return 0; //we're equal
- else if (*this_str == 0)
+ } else if (*this_str == 0) {
return -1; //if this is empty, and the other one is not, then we're less.. I think?
- else if (*that_str == 0)
+ } else if (*that_str == 0) {
return 1; //otherwise the other one is smaller..
- else if (_find_upper(*this_str) < _find_upper(*that_str)) //more than
+ } else if (_find_upper(*this_str) < _find_upper(*that_str)) { //more than
return -1;
- else if (_find_upper(*this_str) > _find_upper(*that_str)) //less than
+ } else if (_find_upper(*this_str) > _find_upper(*that_str)) { //less than
return 1;
+ }
this_str++;
that_str++;
@@ -489,29 +472,31 @@ signed char String::nocasecmp_to(const String &p_str) const {
}
signed char String::casecmp_to(const String &p_str) const {
-
- if (empty() && p_str.empty())
+ if (empty() && p_str.empty()) {
return 0;
- if (empty())
+ }
+ if (empty()) {
return -1;
- if (p_str.empty())
+ }
+ if (p_str.empty()) {
return 1;
+ }
const CharType *that_str = p_str.c_str();
const CharType *this_str = c_str();
while (true) {
-
- if (*that_str == 0 && *this_str == 0)
+ if (*that_str == 0 && *this_str == 0) {
return 0; //we're equal
- else if (*this_str == 0)
+ } else if (*this_str == 0) {
return -1; //if this is empty, and the other one is not, then we're less.. I think?
- else if (*that_str == 0)
+ } else if (*that_str == 0) {
return 1; //otherwise the other one is smaller..
- else if (*this_str < *that_str) //more than
+ } else if (*this_str < *that_str) { //more than
return -1;
- else if (*this_str > *that_str) //less than
+ } else if (*this_str > *that_str) { //less than
return 1;
+ }
this_str++;
that_str++;
@@ -519,84 +504,87 @@ signed char String::casecmp_to(const String &p_str) const {
}
signed char String::naturalnocasecmp_to(const String &p_str) const {
-
const CharType *this_str = c_str();
const CharType *that_str = p_str.c_str();
if (this_str && that_str) {
-
while (*this_str == '.' || *that_str == '.') {
- if (*this_str++ != '.')
+ if (*this_str++ != '.') {
return 1;
- if (*that_str++ != '.')
+ }
+ if (*that_str++ != '.') {
return -1;
- if (!*that_str)
+ }
+ if (!*that_str) {
return 1;
- if (!*this_str)
+ }
+ if (!*this_str) {
return -1;
+ }
}
while (*this_str) {
-
- if (!*that_str)
+ if (!*that_str) {
return 1;
- else if (IS_DIGIT(*this_str)) {
-
+ } else if (IS_DIGIT(*this_str)) {
int64_t this_int, that_int;
- if (!IS_DIGIT(*that_str))
+ if (!IS_DIGIT(*that_str)) {
return -1;
+ }
/* Compare the numbers */
- this_int = to_int(this_str);
- that_int = to_int(that_str);
+ this_int = to_int(this_str, -1, true);
+ that_int = to_int(that_str, -1, true);
- if (this_int < that_int)
+ if (this_int < that_int) {
return -1;
- else if (this_int > that_int)
+ } else if (this_int > that_int) {
return 1;
+ }
/* Skip */
- while (IS_DIGIT(*this_str))
+ while (IS_DIGIT(*this_str)) {
this_str++;
- while (IS_DIGIT(*that_str))
+ }
+ while (IS_DIGIT(*that_str)) {
that_str++;
- } else if (IS_DIGIT(*that_str))
+ }
+ } else if (IS_DIGIT(*that_str)) {
return 1;
- else {
- if (_find_upper(*this_str) < _find_upper(*that_str)) //more than
+ } else {
+ if (_find_upper(*this_str) < _find_upper(*that_str)) { //more than
return -1;
- else if (_find_upper(*this_str) > _find_upper(*that_str)) //less than
+ } else if (_find_upper(*this_str) > _find_upper(*that_str)) { //less than
return 1;
+ }
this_str++;
that_str++;
}
}
- if (*that_str)
+ if (*that_str) {
return -1;
+ }
}
return 0;
}
void String::erase(int p_pos, int p_chars) {
-
*this = left(p_pos) + substr(p_pos + p_chars, length() - ((p_pos + p_chars)));
}
String String::capitalize() const {
-
String aux = this->camelcase_to_underscore(true).replace("_", " ").strip_edges();
String cap;
for (int i = 0; i < aux.get_slice_count(" "); i++) {
-
String slice = aux.get_slicec(' ', i);
if (slice.length() > 0) {
-
slice[0] = _find_upper(slice[0]);
- if (i > 0)
+ if (i > 0) {
cap += " ";
+ }
cap += slice;
}
}
@@ -657,18 +645,19 @@ String String::get_with_code_lines() const {
}
return ret;
}
-int String::get_slice_count(String p_splitter) const {
- if (empty())
+int String::get_slice_count(String p_splitter) const {
+ if (empty()) {
return 0;
- if (p_splitter.empty())
+ }
+ if (p_splitter.empty()) {
return 0;
+ }
int pos = 0;
int slices = 1;
while ((pos = find(p_splitter, pos)) >= 0) {
-
slices++;
pos += p_splitter.length();
}
@@ -677,35 +666,37 @@ int String::get_slice_count(String p_splitter) const {
}
String String::get_slice(String p_splitter, int p_slice) const {
-
- if (empty() || p_splitter.empty())
+ if (empty() || p_splitter.empty()) {
return "";
+ }
int pos = 0;
int prev_pos = 0;
//int slices=1;
- if (p_slice < 0)
+ if (p_slice < 0) {
return "";
- if (find(p_splitter) == -1)
+ }
+ if (find(p_splitter) == -1) {
return *this;
+ }
int i = 0;
while (true) {
-
pos = find(p_splitter, pos);
- if (pos == -1)
+ if (pos == -1) {
pos = length(); //reached end
+ }
int from = prev_pos;
//int to=pos;
if (p_slice == i) {
-
return substr(from, pos - from);
}
- if (pos == length()) //reached end and no find
+ if (pos == length()) { //reached end and no find
break;
+ }
pos += p_splitter.length();
prev_pos = pos;
i++;
@@ -715,23 +706,21 @@ String String::get_slice(String p_splitter, int p_slice) const {
}
String String::get_slicec(CharType p_splitter, int p_slice) const {
-
- if (empty())
+ if (empty()) {
return String();
+ }
- if (p_slice < 0)
+ if (p_slice < 0) {
return String();
+ }
const CharType *c = this->ptr();
int i = 0;
int prev = 0;
int count = 0;
while (true) {
-
if (c[i] == 0 || c[i] == p_splitter) {
-
if (p_slice == count) {
-
return substr(prev, i - prev);
} else if (c[i] == 0) {
return String();
@@ -746,22 +735,22 @@ String String::get_slicec(CharType p_splitter, int p_slice) const {
}
Vector<String> String::split_spaces() const {
-
Vector<String> ret;
int from = 0;
int i = 0;
int len = length();
- if (len == 0)
+ if (len == 0) {
return ret;
+ }
bool inside = false;
while (true) {
-
bool empty = operator[](i) < 33;
- if (i == 0)
+ if (i == 0) {
inside = !empty;
+ }
if (!empty && !inside) {
inside = true;
@@ -769,13 +758,13 @@ Vector<String> String::split_spaces() const {
}
if (empty && inside) {
-
ret.push_back(substr(from, i - from));
inside = false;
}
- if (i == len)
+ if (i == len) {
break;
+ }
i++;
}
@@ -783,21 +772,19 @@ Vector<String> String::split_spaces() const {
}
Vector<String> String::split(const String &p_splitter, bool p_allow_empty, int p_maxsplit) const {
-
Vector<String> ret;
int from = 0;
int len = length();
while (true) {
-
int end = find(p_splitter, from);
- if (end < 0)
+ if (end < 0) {
end = len;
+ }
if (p_allow_empty || (end > from)) {
- if (p_maxsplit <= 0)
+ if (p_maxsplit <= 0) {
ret.push_back(substr(from, end - from));
- else {
-
+ } else {
// Put rest of the string and leave cycle.
if (p_maxsplit == ret.size()) {
ret.push_back(substr(from, len));
@@ -809,8 +796,9 @@ Vector<String> String::split(const String &p_splitter, bool p_allow_empty, int p
}
}
- if (end == len)
+ if (end == len) {
break;
+ }
from = end + p_splitter.length();
}
@@ -819,13 +807,11 @@ Vector<String> String::split(const String &p_splitter, bool p_allow_empty, int p
}
Vector<String> String::rsplit(const String &p_splitter, bool p_allow_empty, int p_maxsplit) const {
-
Vector<String> ret;
const int len = length();
int remaining_len = len;
while (true) {
-
if (remaining_len < p_splitter.length() || (p_maxsplit > 0 && p_maxsplit == ret.size())) {
// no room for another splitter or hit max splits, push what's left and we're done
if (p_allow_empty || remaining_len > 0) {
@@ -855,21 +841,22 @@ Vector<String> String::rsplit(const String &p_splitter, bool p_allow_empty, int
}
Vector<float> String::split_floats(const String &p_splitter, bool p_allow_empty) const {
-
Vector<float> ret;
int from = 0;
int len = length();
while (true) {
-
int end = find(p_splitter, from);
- if (end < 0)
+ if (end < 0) {
end = len;
- if (p_allow_empty || (end > from))
+ }
+ if (p_allow_empty || (end > from)) {
ret.push_back(String::to_double(&c_str()[from]));
+ }
- if (end == len)
+ if (end == len) {
break;
+ }
from = end + p_splitter.length();
}
@@ -878,13 +865,11 @@ Vector<float> String::split_floats(const String &p_splitter, bool p_allow_empty)
}
Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_allow_empty) const {
-
Vector<float> ret;
int from = 0;
int len = length();
while (true) {
-
int idx;
int end = findmk(p_splitters, from, &idx);
int spl_len = 1;
@@ -898,8 +883,9 @@ Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_
ret.push_back(String::to_double(&c_str()[from]));
}
- if (end == len)
+ if (end == len) {
break;
+ }
from = end + spl_len;
}
@@ -908,21 +894,22 @@ Vector<float> String::split_floats_mk(const Vector<String> &p_splitters, bool p_
}
Vector<int> String::split_ints(const String &p_splitter, bool p_allow_empty) const {
-
Vector<int> ret;
int from = 0;
int len = length();
while (true) {
-
int end = find(p_splitter, from);
- if (end < 0)
+ if (end < 0) {
end = len;
- if (p_allow_empty || (end > from))
+ }
+ if (p_allow_empty || (end > from)) {
ret.push_back(String::to_int(&c_str()[from], end - from));
+ }
- if (end == len)
+ if (end == len) {
break;
+ }
from = end + p_splitter.length();
}
@@ -931,13 +918,11 @@ Vector<int> String::split_ints(const String &p_splitter, bool p_allow_empty) con
}
Vector<int> String::split_ints_mk(const Vector<String> &p_splitters, bool p_allow_empty) const {
-
Vector<int> ret;
int from = 0;
int len = length();
while (true) {
-
int idx;
int end = findmk(p_splitters, from, &idx);
int spl_len = 1;
@@ -947,11 +932,13 @@ Vector<int> String::split_ints_mk(const Vector<String> &p_splitters, bool p_allo
spl_len = p_splitters[idx].length();
}
- if (p_allow_empty || (end > from))
+ if (p_allow_empty || (end > from)) {
ret.push_back(String::to_int(&c_str()[from], end - from));
+ }
- if (end == len)
+ if (end == len) {
break;
+ }
from = end + spl_len;
}
@@ -971,47 +958,42 @@ String String::join(Vector<String> parts) {
}
CharType String::char_uppercase(CharType p_char) {
-
return _find_upper(p_char);
}
CharType String::char_lowercase(CharType p_char) {
-
return _find_lower(p_char);
}
String String::to_upper() const {
-
String upper = *this;
for (int i = 0; i < upper.size(); i++) {
-
const CharType s = upper[i];
const CharType t = _find_upper(s);
- if (s != t) // avoid copy on write
+ if (s != t) { // avoid copy on write
upper[i] = t;
+ }
}
return upper;
}
String String::to_lower() const {
-
String lower = *this;
for (int i = 0; i < lower.size(); i++) {
-
const CharType s = lower[i];
const CharType t = _find_lower(s);
- if (s != t) // avoid copy on write
+ if (s != t) { // avoid copy on write
lower[i] = t;
+ }
}
return lower;
}
const CharType *String::c_str() const {
-
static const CharType zero = 0;
return size() ? &operator[](0) : &zero;
@@ -1038,23 +1020,22 @@ String String::hex_encode_buffer(const uint8_t *p_buffer, int p_len) {
}
String String::chr(CharType p_char) {
-
CharType c[2] = { p_char, 0 };
return String(c);
}
-String String::num(double p_num, int p_decimals) {
+String String::num(double p_num, int p_decimals) {
#ifndef NO_USE_STDLIB
- if (p_decimals > 16)
+ if (p_decimals > 16) {
p_decimals = 16;
+ }
char fmt[7];
fmt[0] = '%';
fmt[1] = '.';
if (p_decimals < 0) {
-
fmt[1] = 'l';
fmt[2] = 'f';
fmt[3] = 0;
@@ -1082,28 +1063,24 @@ String String::num(double p_num, int p_decimals) {
buf[255] = 0;
//destroy trailing zeroes
{
-
bool period = false;
int z = 0;
while (buf[z]) {
- if (buf[z] == '.')
+ if (buf[z] == '.') {
period = true;
+ }
z++;
}
if (period) {
z--;
while (z > 0) {
-
if (buf[z] == '0') {
-
buf[z] = 0;
} else if (buf[z] == '.') {
-
buf[z] = 0;
break;
} else {
-
break;
}
@@ -1126,7 +1103,6 @@ String String::num(double p_num, int p_decimals) {
/* decimal part */
if (p_decimals > 0 || (p_decimals == -1 && (int)p_num != p_num)) {
-
double dec = p_num - (float)((int)p_num);
int digit = 0;
@@ -1137,14 +1113,12 @@ String String::num(double p_num, int p_decimals) {
int dec_max = 0;
while (true) {
-
dec *= 10.0;
dec_int = dec_int * 10 + (int)dec % 10;
dec_max = dec_max * 10 + 9;
digit++;
if (p_decimals == -1) {
-
if (digit == MAX_DIGITS) //no point in going to infinite
break;
@@ -1160,18 +1134,15 @@ String String::num(double p_num, int p_decimals) {
if (last > 5) {
if (dec_int == dec_max) {
-
dec_int = 0;
intn++;
} else {
-
dec_int++;
}
}
String decimal;
for (int i = 0; i < digit; i++) {
-
char num[2] = { 0, 0 };
num[0] = '0' + dec_int % 10;
decimal = num + decimal;
@@ -1185,7 +1156,6 @@ String String::num(double p_num, int p_decimals) {
s = "0";
else {
while (intn) {
-
CharType num = '0' + (intn % 10);
intn /= 10;
s = num + s;
@@ -1200,7 +1170,6 @@ String String::num(double p_num, int p_decimals) {
}
String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
-
bool sign = p_num < 0;
int64_t n = p_num;
@@ -1211,8 +1180,9 @@ String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
chars++;
} while (n);
- if (sign)
+ if (sign) {
chars++;
+ }
String s;
s.resize(chars + 1);
CharType *c = s.ptrw();
@@ -1230,14 +1200,14 @@ String String::num_int64(int64_t p_num, int base, bool capitalize_hex) {
n /= base;
} while (n);
- if (sign)
+ if (sign) {
c[0] = '-';
+ }
return s;
}
String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) {
-
uint64_t n = p_num;
int chars = 0;
@@ -1267,7 +1237,6 @@ String String::num_uint64(uint64_t p_num, int base, bool capitalize_hex) {
}
String String::num_real(double p_num) {
-
String s;
String sd;
/* integer part */
@@ -1279,7 +1248,6 @@ String String::num_real(double p_num) {
/* decimal part */
if ((int)p_num != p_num) {
-
double dec = p_num - (float)((int)p_num);
int digit = 0;
@@ -1289,17 +1257,18 @@ String String::num_real(double p_num) {
int dec_max = 0;
while (true) {
-
dec *= 10.0;
dec_int = dec_int * 10 + (int)dec % 10;
dec_max = dec_max * 10 + 9;
digit++;
- if ((dec - (float)((int)dec)) < 1e-6)
+ if ((dec - (float)((int)dec)) < 1e-6) {
break;
+ }
- if (digit == decimals)
+ if (digit == decimals) {
break;
+ }
}
dec *= 10;
@@ -1307,18 +1276,15 @@ String String::num_real(double p_num) {
if (last > 5) {
if (dec_int == dec_max) {
-
dec_int = 0;
intn++;
} else {
-
dec_int++;
}
}
String decimal;
for (int i = 0; i < digit; i++) {
-
char num[2] = { 0, 0 };
num[0] = '0' + dec_int % 10;
decimal = num + decimal;
@@ -1329,12 +1295,10 @@ String String::num_real(double p_num) {
sd = ".0";
}
- if (intn == 0)
-
+ if (intn == 0) {
s = "0";
- else {
+ } else {
while (intn) {
-
CharType num = '0' + (intn % 10);
intn /= 10;
s = num + s;
@@ -1342,13 +1306,13 @@ String String::num_real(double p_num) {
}
s = s + sd;
- if (neg)
+ if (neg) {
s = "-" + s;
+ }
return s;
}
String String::num_scientific(double p_num) {
-
#ifndef NO_USE_STDLIB
char buf[256];
@@ -1379,33 +1343,33 @@ String String::num_scientific(double p_num) {
}
CharString String::ascii(bool p_allow_extended) const {
-
- if (!length())
+ if (!length()) {
return CharString();
+ }
CharString cs;
cs.resize(size());
- for (int i = 0; i < size(); i++)
+ for (int i = 0; i < size(); i++) {
cs[i] = operator[](i);
+ }
return cs;
}
String String::utf8(const char *p_utf8, int p_len) {
-
String ret;
ret.parse_utf8(p_utf8, p_len);
return ret;
-};
+}
bool String::parse_utf8(const char *p_utf8, int p_len) {
-
#define _UNICERROR(m_err) print_line("Unicode parsing error: " + String(m_err) + ". Is the string valid UTF-8?");
- if (!p_utf8)
+ if (!p_utf8) {
return true;
+ }
String aux;
@@ -1414,13 +1378,12 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
/* HANDLE BOM (Byte Order Mark) */
if (p_len < 0 || p_len >= 3) {
-
bool has_bom = uint8_t(p_utf8[0]) == 0xEF && uint8_t(p_utf8[1]) == 0xBB && uint8_t(p_utf8[2]) == 0xBF;
if (has_bom) {
-
//just skip it
- if (p_len >= 0)
+ if (p_len >= 0) {
p_len -= 3;
+ }
p_utf8 += 3;
}
}
@@ -1430,25 +1393,23 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
const char *ptrtmp_limit = &p_utf8[p_len];
int skip = 0;
while (ptrtmp != ptrtmp_limit && *ptrtmp) {
-
if (skip == 0) {
-
uint8_t c = *ptrtmp >= 0 ? *ptrtmp : uint8_t(256 + *ptrtmp);
/* Determine the number of characters in sequence */
- if ((c & 0x80) == 0)
+ if ((c & 0x80) == 0) {
skip = 0;
- else if ((c & 0xE0) == 0xC0)
+ } else if ((c & 0xE0) == 0xC0) {
skip = 1;
- else if ((c & 0xF0) == 0xE0)
+ } else if ((c & 0xF0) == 0xE0) {
skip = 2;
- else if ((c & 0xF8) == 0xF0)
+ } else if ((c & 0xF8) == 0xF0) {
skip = 3;
- else if ((c & 0xFC) == 0xF8)
+ } else if ((c & 0xFC) == 0xF8) {
skip = 4;
- else if ((c & 0xFE) == 0xFC)
+ } else if ((c & 0xFE) == 0xFC) {
skip = 5;
- else {
+ } else {
_UNICERROR("invalid skip");
return true; //invalid utf8
}
@@ -1462,7 +1423,6 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
str_size++;
} else {
-
--skip;
}
@@ -1486,23 +1446,22 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
dst[str_size] = 0;
while (cstr_size) {
-
int len = 0;
/* Determine the number of characters in sequence */
- if ((*p_utf8 & 0x80) == 0)
+ if ((*p_utf8 & 0x80) == 0) {
len = 1;
- else if ((*p_utf8 & 0xE0) == 0xC0)
+ } else if ((*p_utf8 & 0xE0) == 0xC0) {
len = 2;
- else if ((*p_utf8 & 0xF0) == 0xE0)
+ } else if ((*p_utf8 & 0xF0) == 0xE0) {
len = 3;
- else if ((*p_utf8 & 0xF8) == 0xF0)
+ } else if ((*p_utf8 & 0xF8) == 0xF0) {
len = 4;
- else if ((*p_utf8 & 0xFC) == 0xF8)
+ } else if ((*p_utf8 & 0xFC) == 0xF8) {
len = 5;
- else if ((*p_utf8 & 0xFE) == 0xFC)
+ } else if ((*p_utf8 & 0xFE) == 0xFC) {
len = 6;
- else {
+ } else {
_UNICERROR("invalid len");
return true; //invalid UTF8
@@ -1523,14 +1482,12 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
uint32_t unichar = 0;
- if (len == 1)
+ if (len == 1) {
unichar = *p_utf8;
- else {
-
+ } else {
unichar = (0xFF >> (len + 1)) & *p_utf8;
for (int i = 1; i < len; i++) {
-
if ((p_utf8[i] & 0xC0) != 0x80) {
_UNICERROR("invalid utf8");
return true; //invalid utf8
@@ -1557,19 +1514,18 @@ bool String::parse_utf8(const char *p_utf8, int p_len) {
}
CharString String::utf8() const {
-
int l = length();
- if (!l)
+ if (!l) {
return CharString();
+ }
const CharType *d = &operator[](0);
int fl = 0;
for (int i = 0; i < l; i++) {
-
uint32_t c = d[i];
- if (c <= 0x7f) // 7 bits.
+ if (c <= 0x7f) { // 7 bits.
fl += 1;
- else if (c <= 0x7ff) { // 11 bits
+ } else if (c <= 0x7ff) { // 11 bits
fl += 2;
} else if (c <= 0xffff) { // 16 bits
fl += 3;
@@ -1594,12 +1550,11 @@ CharString String::utf8() const {
#define APPEND_CHAR(m_c) *(cdst++) = m_c
for (int i = 0; i < l; i++) {
-
uint32_t c = d[i];
- if (c <= 0x7f) // 7 bits.
+ if (c <= 0x7f) { // 7 bits.
APPEND_CHAR(c);
- else if (c <= 0x7ff) { // 11 bits
+ } else if (c <= 0x7ff) { // 11 bits
APPEND_CHAR(uint32_t(0xc0 | ((c >> 6) & 0x1f))); // Top 5 bits.
APPEND_CHAR(uint32_t(0x80 | (c & 0x3f))); // Bottom 6 bits.
@@ -1643,30 +1598,30 @@ String::String(CharType p_char) {
shared=nullptr;
copy_from(p_char);
}
+
+
*/
String::String(const char *p_str) {
-
copy_from(p_str);
}
String::String(const CharType *p_str, int p_clip_to_len) {
-
copy_from(p_str, p_clip_to_len);
}
String::String(const StrRange &p_range) {
-
- if (!p_range.c_str)
+ if (!p_range.c_str) {
return;
+ }
copy_from(p_range.c_str, p_range.len);
}
int String::hex_to_int(bool p_with_prefix) const {
-
- if (p_with_prefix && length() < 3)
+ if (p_with_prefix && length() < 3) {
return 0;
+ }
const CharType *s = ptr();
@@ -1677,15 +1632,15 @@ int String::hex_to_int(bool p_with_prefix) const {
}
if (p_with_prefix) {
- if (s[0] != '0' || s[1] != 'x')
+ if (s[0] != '0' || s[1] != 'x') {
return 0;
+ }
s += 2;
}
int hex = 0;
while (*s) {
-
CharType c = LOWERCASE(*s);
int n;
if (c >= '0' && c <= '9') {
@@ -1706,9 +1661,9 @@ int String::hex_to_int(bool p_with_prefix) const {
}
int64_t String::hex_to_int64(bool p_with_prefix) const {
-
- if (p_with_prefix && length() < 3)
+ if (p_with_prefix && length() < 3) {
return 0;
+ }
const CharType *s = ptr();
@@ -1719,15 +1674,15 @@ int64_t String::hex_to_int64(bool p_with_prefix) const {
}
if (p_with_prefix) {
- if (s[0] != '0' || s[1] != 'x')
+ if (s[0] != '0' || s[1] != 'x') {
return 0;
+ }
s += 2;
}
int64_t hex = 0;
while (*s) {
-
CharType c = LOWERCASE(*s);
int64_t n;
if (c >= '0' && c <= '9') {
@@ -1748,9 +1703,9 @@ int64_t String::hex_to_int64(bool p_with_prefix) const {
}
int64_t String::bin_to_int64(bool p_with_prefix) const {
-
- if (p_with_prefix && length() < 3)
+ if (p_with_prefix && length() < 3) {
return 0;
+ }
const CharType *s = ptr();
@@ -1761,15 +1716,15 @@ int64_t String::bin_to_int64(bool p_with_prefix) const {
}
if (p_with_prefix) {
- if (s[0] != '0' || s[1] != 'b')
+ if (s[0] != '0' || s[1] != 'b') {
return 0;
+ }
s += 2;
}
int64_t binary = 0;
while (*s) {
-
CharType c = LOWERCASE(*s);
int64_t n;
if (c == '0' || c == '1') {
@@ -1788,9 +1743,9 @@ int64_t String::bin_to_int64(bool p_with_prefix) const {
}
int String::to_int() const {
-
- if (length() == 0)
+ if (length() == 0) {
return 0;
+ }
int to = (find(".") >= 0) ? find(".") : length();
@@ -1798,16 +1753,13 @@ int String::to_int() const {
int sign = 1;
for (int i = 0; i < to; i++) {
-
CharType c = operator[](i);
if (c >= '0' && c <= '9') {
-
ERR_FAIL_COND_V_MSG(integer > INT32_MAX / 10, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + *this + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
integer *= 10;
integer += c - '0';
} else if (integer == 0 && c == '-') {
-
sign = -sign;
}
}
@@ -1816,9 +1768,9 @@ int String::to_int() const {
}
int64_t String::to_int64() const {
-
- if (length() == 0)
+ if (length() == 0) {
return 0;
+ }
int to = (find(".") >= 0) ? find(".") : length();
@@ -1826,16 +1778,13 @@ int64_t String::to_int64() const {
int64_t sign = 1;
for (int i = 0; i < to; i++) {
-
CharType c = operator[](i);
if (c >= '0' && c <= '9') {
-
ERR_FAIL_COND_V_MSG(integer > INT64_MAX / 10, sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + *this + " as 64-bit integer, provided value is " + (sign == 1 ? "too big." : "too small."));
integer *= 10;
integer += c - '0';
} else if (integer == 0 && c == '-') {
-
sign = -sign;
}
}
@@ -1844,62 +1793,60 @@ int64_t String::to_int64() const {
}
int String::to_int(const char *p_str, int p_len) {
-
int to = 0;
- if (p_len >= 0)
+ if (p_len >= 0) {
to = p_len;
- else {
- while (p_str[to] != 0 && p_str[to] != '.')
+ } else {
+ while (p_str[to] != 0 && p_str[to] != '.') {
to++;
+ }
}
int integer = 0;
int sign = 1;
for (int i = 0; i < to; i++) {
-
char c = p_str[i];
if (c >= '0' && c <= '9') {
-
ERR_FAIL_COND_V_MSG(integer > INT32_MAX / 10, sign == 1 ? INT32_MAX : INT32_MIN, "Cannot represent " + String(p_str).substr(0, to) + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
integer *= 10;
integer += c - '0';
} else if (c == '-' && integer == 0) {
-
sign = -sign;
- } else if (c != ' ')
+ } else if (c != ' ') {
break;
+ }
}
return integer * sign;
}
bool String::is_numeric() const {
-
if (length() == 0) {
return false;
- };
+ }
int s = 0;
- if (operator[](0) == '-') ++s;
+ if (operator[](0) == '-') {
+ ++s;
+ }
bool dot = false;
for (int i = s; i < length(); i++) {
-
CharType c = operator[](i);
if (c == '.') {
if (dot) {
return false;
- };
+ }
dot = true;
}
if (c < '0' || c > '9') {
return false;
- };
- };
+ }
+ }
return true; // TODO: Use the parser below for this instead
-};
+}
template <class C>
static double built_in_strtod(const C *string, /* A decimal ASCII floating-point number,
@@ -1916,7 +1863,6 @@ static double built_in_strtod(const C *string, /* A decimal ASCII floating-point
C **endPtr = nullptr) /* If non-nullptr, store terminating Cacter's
* address here. */
{
-
static const int maxExponent = 511; /* Largest possible base 10 exponent. Any
* exponent larger than this will already
* produce underflow or overflow, so there's
@@ -2118,7 +2064,6 @@ done:
#define READING_DONE 4
double String::to_double(const char *p_str) {
-
#ifndef NO_USE_STDLIB
return built_in_strtod<char>(p_str);
//return atof(p_str); DOES NOT WORK ON ANDROID(??)
@@ -2128,19 +2073,17 @@ double String::to_double(const char *p_str) {
}
float String::to_float() const {
-
return to_double();
}
double String::to_double(const CharType *p_str, const CharType **r_end) {
-
return built_in_strtod<CharType>(p_str, (CharType **)r_end);
}
-int64_t String::to_int(const CharType *p_str, int p_len) {
-
- if (p_len == 0 || !p_str[0])
+int64_t String::to_int(const CharType *p_str, int p_len, bool p_clamp) {
+ if (p_len == 0 || !p_str[0]) {
return 0;
+ }
///@todo make more exact so saving and loading does not lose precision
int64_t integer = 0;
@@ -2151,7 +2094,6 @@ int64_t String::to_int(const CharType *p_str, int p_len) {
const CharType *limit = &p_str[p_len];
while (*str && reading != READING_DONE && str != limit) {
-
CharType c = *(str++);
switch (reading) {
case READING_SIGN: {
@@ -2172,16 +2114,22 @@ int64_t String::to_int(const CharType *p_str, int p_len) {
[[fallthrough]];
}
case READING_INT: {
-
if (c >= '0' && c <= '9') {
-
if (integer > INT64_MAX / 10) {
String number("");
str = p_str;
while (*str && str != limit) {
number += *(str++);
}
- ERR_FAIL_V_MSG(sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + number + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+ if (p_clamp) {
+ if (sign == 1) {
+ return INT64_MAX;
+ } else {
+ return INT64_MIN;
+ }
+ } else {
+ ERR_FAIL_V_MSG(sign == 1 ? INT64_MAX : INT64_MIN, "Cannot represent " + number + " as integer, provided value is " + (sign == 1 ? "too big." : "too small."));
+ }
}
integer *= 10;
integer += c - '0';
@@ -2197,9 +2145,9 @@ int64_t String::to_int(const CharType *p_str, int p_len) {
}
double String::to_double() const {
-
- if (empty())
+ if (empty()) {
return 0;
+ }
#ifndef NO_USE_STDLIB
return built_in_strtod<CharType>(c_str());
//return wcstod(c_str(),nullptr ); DOES NOT WORK ON ANDROID :(
@@ -2209,91 +2157,88 @@ double String::to_double() const {
}
bool operator==(const char *p_chr, const String &p_str) {
-
return p_str == p_chr;
}
String operator+(const char *p_chr, const String &p_str) {
-
String tmp = p_chr;
tmp += p_str;
return tmp;
}
-String operator+(CharType p_chr, const String &p_str) {
+String operator+(CharType p_chr, const String &p_str) {
return (String::chr(p_chr) + p_str);
}
uint32_t String::hash(const char *p_cstr) {
-
uint32_t hashv = 5381;
uint32_t c;
- while ((c = *p_cstr++))
+ while ((c = *p_cstr++)) {
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
+ }
return hashv;
}
uint32_t String::hash(const char *p_cstr, int p_len) {
-
uint32_t hashv = 5381;
- for (int i = 0; i < p_len; i++)
+ for (int i = 0; i < p_len; i++) {
hashv = ((hashv << 5) + hashv) + p_cstr[i]; /* hash * 33 + c */
+ }
return hashv;
}
uint32_t String::hash(const CharType *p_cstr, int p_len) {
-
uint32_t hashv = 5381;
- for (int i = 0; i < p_len; i++)
+ for (int i = 0; i < p_len; i++) {
hashv = ((hashv << 5) + hashv) + p_cstr[i]; /* hash * 33 + c */
+ }
return hashv;
}
uint32_t String::hash(const CharType *p_cstr) {
-
uint32_t hashv = 5381;
uint32_t c;
- while ((c = *p_cstr++))
+ while ((c = *p_cstr++)) {
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
+ }
return hashv;
}
uint32_t String::hash() const {
-
/* simple djb2 hashing */
const CharType *chr = c_str();
uint32_t hashv = 5381;
uint32_t c;
- while ((c = *chr++))
+ while ((c = *chr++)) {
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
+ }
return hashv;
}
uint64_t String::hash64() const {
-
/* simple djb2 hashing */
const CharType *chr = c_str();
uint64_t hashv = 5381;
uint64_t c;
- while ((c = *chr++))
+ while ((c = *chr++)) {
hashv = ((hashv << 5) + hashv) + c; /* hash * 33 + c */
+ }
return hashv;
}
String String::md5_text() const {
-
CharString cs = utf8();
unsigned char hash[16];
CryptoCore::md5((unsigned char *)cs.ptr(), cs.length(), hash);
@@ -2315,7 +2260,6 @@ String String::sha256_text() const {
}
Vector<uint8_t> String::md5_buffer() const {
-
CharString cs = utf8();
unsigned char hash[16];
CryptoCore::md5((unsigned char *)cs.ptr(), cs.length(), hash);
@@ -2326,7 +2270,7 @@ Vector<uint8_t> String::md5_buffer() const {
ret.write[i] = hash[i];
}
return ret;
-};
+}
Vector<uint8_t> String::sha1_buffer() const {
CharString cs = utf8();
@@ -2356,38 +2300,41 @@ Vector<uint8_t> String::sha256_buffer() const {
}
String String::insert(int p_at_pos, const String &p_string) const {
-
- if (p_at_pos < 0)
+ if (p_at_pos < 0) {
return *this;
+ }
- if (p_at_pos > length())
+ if (p_at_pos > length()) {
p_at_pos = length();
+ }
String pre;
- if (p_at_pos > 0)
+ if (p_at_pos > 0) {
pre = substr(0, p_at_pos);
+ }
String post;
- if (p_at_pos < length())
+ if (p_at_pos < length()) {
post = substr(p_at_pos, length() - p_at_pos);
+ }
return pre + p_string + post;
}
-String String::substr(int p_from, int p_chars) const {
- if (p_chars == -1)
+String String::substr(int p_from, int p_chars) const {
+ if (p_chars == -1) {
p_chars = length() - p_from;
+ }
- if (empty() || p_from < 0 || p_from >= length() || p_chars <= 0)
+ if (empty() || p_from < 0 || p_from >= length() || p_chars <= 0) {
return "";
+ }
if ((p_from + p_chars) > length()) {
-
p_chars = length() - p_from;
}
if (p_from == 0 && p_chars >= length()) {
-
return String(*this);
}
@@ -2397,12 +2344,10 @@ String String::substr(int p_from, int p_chars) const {
}
int String::find_last(const String &p_str) const {
-
int pos = -1;
int findfrom = 0;
int findres = -1;
while ((findres = find(p_str, findfrom)) != -1) {
-
pos = findres;
findfrom = pos + 1;
}
@@ -2411,32 +2356,30 @@ int String::find_last(const String &p_str) const {
}
int String::find(const String &p_str, int p_from) const {
-
- if (p_from < 0)
+ if (p_from < 0) {
return -1;
+ }
const int src_len = p_str.length();
const int len = length();
- if (src_len == 0 || len == 0)
+ if (src_len == 0 || len == 0) {
return -1; // won't find anything!
+ }
const CharType *src = c_str();
const CharType *str = p_str.c_str();
for (int i = p_from; i <= (len - src_len); i++) {
-
bool found = true;
for (int j = 0; j < src_len; j++) {
-
int read_pos = i + j;
if (read_pos >= len) {
-
ERR_PRINT("read_pos>=len");
return -1;
- };
+ }
if (src[read_pos] != str[j]) {
found = false;
@@ -2444,54 +2387,51 @@ int String::find(const String &p_str, int p_from) const {
}
}
- if (found)
+ if (found) {
return i;
+ }
}
return -1;
}
int String::find(const char *p_str, int p_from) const {
-
- if (p_from < 0)
+ if (p_from < 0) {
return -1;
+ }
const int len = length();
- if (len == 0)
+ if (len == 0) {
return -1; // won't find anything!
+ }
const CharType *src = c_str();
int src_len = 0;
- while (p_str[src_len] != '\0')
+ while (p_str[src_len] != '\0') {
src_len++;
+ }
if (src_len == 1) {
-
const char needle = p_str[0];
for (int i = p_from; i < len; i++) {
-
if (src[i] == needle) {
return i;
}
}
} else {
-
for (int i = p_from; i <= (len - src_len); i++) {
-
bool found = true;
for (int j = 0; j < src_len; j++) {
-
int read_pos = i + j;
if (read_pos >= len) {
-
ERR_PRINT("read_pos>=len");
return -1;
- };
+ }
if (src[read_pos] != p_str[j]) {
found = false;
@@ -2499,8 +2439,9 @@ int String::find(const char *p_str, int p_from) const {
}
}
- if (found)
+ if (found) {
return i;
+ }
}
}
@@ -2512,83 +2453,82 @@ int String::find_char(const CharType &p_char, int p_from) const {
}
int String::findmk(const Vector<String> &p_keys, int p_from, int *r_key) const {
-
- if (p_from < 0)
+ if (p_from < 0) {
return -1;
- if (p_keys.size() == 0)
+ }
+ if (p_keys.size() == 0) {
return -1;
+ }
//int src_len=p_str.length();
const String *keys = &p_keys[0];
int key_count = p_keys.size();
int len = length();
- if (len == 0)
+ if (len == 0) {
return -1; // won't find anything!
+ }
const CharType *src = c_str();
for (int i = p_from; i < len; i++) {
-
bool found = true;
for (int k = 0; k < key_count; k++) {
-
found = true;
- if (r_key)
+ if (r_key) {
*r_key = k;
+ }
const CharType *cmp = keys[k].c_str();
int l = keys[k].length();
for (int j = 0; j < l; j++) {
-
int read_pos = i + j;
if (read_pos >= len) {
-
found = false;
break;
- };
+ }
if (src[read_pos] != cmp[j]) {
found = false;
break;
}
}
- if (found)
+ if (found) {
break;
+ }
}
- if (found)
+ if (found) {
return i;
+ }
}
return -1;
}
int String::findn(const String &p_str, int p_from) const {
-
- if (p_from < 0)
+ if (p_from < 0) {
return -1;
+ }
int src_len = p_str.length();
- if (src_len == 0 || length() == 0)
+ if (src_len == 0 || length() == 0) {
return -1; // won't find anything!
+ }
const CharType *srcd = c_str();
for (int i = p_from; i <= (length() - src_len); i++) {
-
bool found = true;
for (int j = 0; j < src_len; j++) {
-
int read_pos = i + j;
if (read_pos >= length()) {
-
ERR_PRINT("read_pos>=length()");
return -1;
- };
+ }
CharType src = _find_lower(srcd[read_pos]);
CharType dst = _find_lower(p_str[j]);
@@ -2599,46 +2539,46 @@ int String::findn(const String &p_str, int p_from) const {
}
}
- if (found)
+ if (found) {
return i;
+ }
}
return -1;
}
int String::rfind(const String &p_str, int p_from) const {
-
// establish a limit
int limit = length() - p_str.length();
- if (limit < 0)
+ if (limit < 0) {
return -1;
+ }
// establish a starting point
- if (p_from < 0)
+ if (p_from < 0) {
p_from = limit;
- else if (p_from > limit)
+ } else if (p_from > limit) {
p_from = limit;
+ }
int src_len = p_str.length();
int len = length();
- if (src_len == 0 || len == 0)
+ if (src_len == 0 || len == 0) {
return -1; // won't find anything!
+ }
const CharType *src = c_str();
for (int i = p_from; i >= 0; i--) {
-
bool found = true;
for (int j = 0; j < src_len; j++) {
-
int read_pos = i + j;
if (read_pos >= len) {
-
ERR_PRINT("read_pos>=len");
return -1;
- };
+ }
if (src[read_pos] != p_str[j]) {
found = false;
@@ -2646,45 +2586,46 @@ int String::rfind(const String &p_str, int p_from) const {
}
}
- if (found)
+ if (found) {
return i;
+ }
}
return -1;
}
-int String::rfindn(const String &p_str, int p_from) const {
+int String::rfindn(const String &p_str, int p_from) const {
// establish a limit
int limit = length() - p_str.length();
- if (limit < 0)
+ if (limit < 0) {
return -1;
+ }
// establish a starting point
- if (p_from < 0)
+ if (p_from < 0) {
p_from = limit;
- else if (p_from > limit)
+ } else if (p_from > limit) {
p_from = limit;
+ }
int src_len = p_str.length();
int len = length();
- if (src_len == 0 || len == 0)
+ if (src_len == 0 || len == 0) {
return -1; // won't find anything!
+ }
const CharType *src = c_str();
for (int i = p_from; i >= 0; i--) {
-
bool found = true;
for (int j = 0; j < src_len; j++) {
-
int read_pos = i + j;
if (read_pos >= len) {
-
ERR_PRINT("read_pos>=len");
return -1;
- };
+ }
CharType srcc = _find_lower(src[read_pos]);
CharType dstc = _find_lower(p_str[j]);
@@ -2695,56 +2636,59 @@ int String::rfindn(const String &p_str, int p_from) const {
}
}
- if (found)
+ if (found) {
return i;
+ }
}
return -1;
}
bool String::ends_with(const String &p_string) const {
-
int pos = find_last(p_string);
- if (pos == -1)
+ if (pos == -1) {
return false;
+ }
return pos + p_string.length() == length();
}
bool String::begins_with(const String &p_string) const {
-
- if (p_string.length() > length())
+ if (p_string.length() > length()) {
return false;
+ }
int l = p_string.length();
- if (l == 0)
+ if (l == 0) {
return true;
+ }
const CharType *src = &p_string[0];
const CharType *str = &operator[](0);
int i = 0;
for (; i < l; i++) {
-
- if (src[i] != str[i])
+ if (src[i] != str[i]) {
return false;
+ }
}
// only if i == l the p_string matches the beginning
return i == l;
}
-bool String::begins_with(const char *p_string) const {
+bool String::begins_with(const char *p_string) const {
int l = length();
- if (l == 0 || !p_string)
+ if (l == 0 || !p_string) {
return false;
+ }
const CharType *str = &operator[](0);
int i = 0;
while (*p_string && i < l) {
-
- if (*p_string != str[i])
+ if (*p_string != str[i]) {
return false;
+ }
i++;
p_string++;
}
@@ -2753,22 +2697,18 @@ bool String::begins_with(const char *p_string) const {
}
bool String::is_enclosed_in(const String &p_string) const {
-
return begins_with(p_string) && ends_with(p_string);
}
bool String::is_subsequence_of(const String &p_string) const {
-
return _base_is_subsequence_of(p_string, false);
}
bool String::is_subsequence_ofi(const String &p_string) const {
-
return _base_is_subsequence_of(p_string, true);
}
bool String::is_quoted() const {
-
return is_enclosed_in("\"") || is_enclosed_in("'");
}
@@ -2818,7 +2758,6 @@ int String::countn(const String &p_string, int p_from, int p_to) const {
}
bool String::_base_is_subsequence_of(const String &p_string, bool case_insensitive) const {
-
int len = length();
if (len == 0) {
// Technically an empty string is subsequence of any string
@@ -2911,22 +2850,21 @@ static bool _wildcard_match(const CharType *p_pattern, const CharType *p_string,
}
bool String::match(const String &p_wildcard) const {
-
- if (!p_wildcard.length() || !length())
+ if (!p_wildcard.length() || !length()) {
return false;
+ }
return _wildcard_match(p_wildcard.c_str(), c_str(), true);
}
bool String::matchn(const String &p_wildcard) const {
-
- if (!p_wildcard.length() || !length())
+ if (!p_wildcard.length() || !length()) {
return false;
+ }
return _wildcard_match(p_wildcard.c_str(), c_str(), false);
}
String String::format(const Variant &values, String placeholder) const {
-
String new_string = String(this->ptr());
if (values.get_type() == Variant::ARRAY) {
@@ -2998,20 +2936,17 @@ String String::format(const Variant &values, String placeholder) const {
}
String String::replace(const String &p_key, const String &p_with) const {
-
String new_string;
int search_from = 0;
int result = 0;
while ((result = find(p_key, search_from)) >= 0) {
-
new_string += substr(search_from, result - search_from);
new_string += p_with;
search_from = result + p_key.length();
}
if (search_from == 0) {
-
return *this;
}
@@ -3021,23 +2956,21 @@ String String::replace(const String &p_key, const String &p_with) const {
}
String String::replace(const char *p_key, const char *p_with) const {
-
String new_string;
int search_from = 0;
int result = 0;
while ((result = find(p_key, search_from)) >= 0) {
-
new_string += substr(search_from, result - search_from);
new_string += p_with;
int k = 0;
- while (p_key[k] != '\0')
+ while (p_key[k] != '\0') {
k++;
+ }
search_from = result + k;
}
if (search_from == 0) {
-
return *this;
}
@@ -3047,7 +2980,6 @@ String String::replace(const char *p_key, const char *p_with) const {
}
String String::replace_first(const String &p_key, const String &p_with) const {
-
int pos = find(p_key);
if (pos >= 0) {
return substr(0, pos) + p_with + substr(pos + p_key.length(), length());
@@ -3055,21 +2987,19 @@ String String::replace_first(const String &p_key, const String &p_with) const {
return *this;
}
-String String::replacen(const String &p_key, const String &p_with) const {
+String String::replacen(const String &p_key, const String &p_with) const {
String new_string;
int search_from = 0;
int result = 0;
while ((result = findn(p_key, search_from)) >= 0) {
-
new_string += substr(search_from, result - search_from);
new_string += p_with;
search_from = result + p_key.length();
}
if (search_from == 0) {
-
return *this;
}
@@ -3078,7 +3008,6 @@ String String::replacen(const String &p_key, const String &p_with) const {
}
String String::repeat(int p_count) const {
-
ERR_FAIL_COND_V_MSG(p_count < 0, "", "Parameter count should be a positive number.");
String new_string;
@@ -3086,43 +3015,45 @@ String String::repeat(int p_count) const {
new_string.resize(length() * p_count + 1);
- for (int i = 0; i < p_count; i++)
- for (int j = 0; j < length(); j++)
+ for (int i = 0; i < p_count; i++) {
+ for (int j = 0; j < length(); j++) {
new_string[i * length() + j] = src[j];
+ }
+ }
return new_string;
}
String String::left(int p_pos) const {
-
- if (p_pos <= 0)
+ if (p_pos <= 0) {
return "";
+ }
- if (p_pos >= length())
+ if (p_pos >= length()) {
return *this;
+ }
return substr(0, p_pos);
}
String String::right(int p_pos) const {
-
- if (p_pos >= length())
+ if (p_pos >= length()) {
return "";
+ }
- if (p_pos <= 0)
+ if (p_pos <= 0) {
return *this;
+ }
return substr(p_pos, (length() - p_pos));
}
CharType String::ord_at(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, length(), 0);
return operator[](p_idx);
}
String String::dedent() const {
-
String new_string;
String indent;
bool has_indent = false;
@@ -3131,11 +3062,11 @@ String String::dedent() const {
int indent_stop = -1;
for (int i = 0; i < length(); i++) {
-
CharType c = operator[](i);
if (c == '\n') {
- if (has_text)
+ if (has_text) {
new_string += substr(indent_stop, i - indent_stop);
+ }
new_string += "\n";
has_text = false;
line_start = i + 1;
@@ -3151,57 +3082,58 @@ String String::dedent() const {
}
if (has_indent && indent_stop < 0) {
int j = i - line_start;
- if (j >= indent.length() || c != indent[j])
+ if (j >= indent.length() || c != indent[j]) {
indent_stop = i;
+ }
}
}
}
- if (has_text)
+ if (has_text) {
new_string += substr(indent_stop, length() - indent_stop);
+ }
return new_string;
}
String String::strip_edges(bool left, bool right) const {
-
int len = length();
int beg = 0, end = len;
if (left) {
for (int i = 0; i < len; i++) {
-
- if (operator[](i) <= 32)
+ if (operator[](i) <= 32) {
beg++;
- else
+ } else {
break;
+ }
}
}
if (right) {
for (int i = (int)(len - 1); i >= 0; i--) {
-
- if (operator[](i) <= 32)
+ if (operator[](i) <= 32) {
end--;
- else
+ } else {
break;
+ }
}
}
- if (beg == 0 && end == len)
+ if (beg == 0 && end == len) {
return *this;
+ }
return substr(beg, end - beg);
}
String String::strip_escapes() const {
-
String new_string;
for (int i = 0; i < length(); i++) {
-
// Escape characters on first page of the ASCII table, before 32 (Space).
- if (operator[](i) < 32)
+ if (operator[](i) < 32) {
continue;
+ }
new_string += operator[](i);
}
@@ -3209,65 +3141,60 @@ String String::strip_escapes() const {
}
String String::lstrip(const String &p_chars) const {
-
int len = length();
int beg;
for (beg = 0; beg < len; beg++) {
-
- if (p_chars.find_char(get(beg)) == -1)
+ if (p_chars.find_char(get(beg)) == -1) {
break;
+ }
}
- if (beg == 0)
+ if (beg == 0) {
return *this;
+ }
return substr(beg, len - beg);
}
String String::rstrip(const String &p_chars) const {
-
int len = length();
int end;
for (end = len - 1; end >= 0; end--) {
-
- if (p_chars.find_char(get(end)) == -1)
+ if (p_chars.find_char(get(end)) == -1) {
break;
+ }
}
- if (end == len - 1)
+ if (end == len - 1) {
return *this;
+ }
return substr(0, end + 1);
}
String String::simplify_path() const {
-
String s = *this;
String drive;
if (s.begins_with("local://")) {
drive = "local://";
s = s.substr(8, s.length());
} else if (s.begins_with("res://")) {
-
drive = "res://";
s = s.substr(6, s.length());
} else if (s.begins_with("user://")) {
-
drive = "user://";
s = s.substr(7, s.length());
} else if (s.begins_with("/") || s.begins_with("\\")) {
-
drive = s.substr(0, 1);
s = s.substr(1, s.length() - 1);
} else {
-
int p = s.find(":/");
- if (p == -1)
+ if (p == -1) {
p = s.find(":\\");
+ }
if (p != -1 && p < s.find("/")) {
-
drive = s.substr(0, p + 2);
s = s.substr(p + 2, s.length());
}
@@ -3276,21 +3203,20 @@ String String::simplify_path() const {
s = s.replace("\\", "/");
while (true) { // in case of using 2 or more slash
String compare = s.replace("//", "/");
- if (s == compare)
+ if (s == compare) {
break;
- else
+ } else {
s = compare;
+ }
}
Vector<String> dirs = s.split("/", false);
for (int i = 0; i < dirs.size(); i++) {
-
String d = dirs[i];
if (d == ".") {
dirs.remove(i);
i--;
} else if (d == "..") {
-
if (i == 0) {
dirs.remove(i);
i--;
@@ -3305,9 +3231,9 @@ String String::simplify_path() const {
s = "";
for (int i = 0; i < dirs.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
s += "/";
+ }
s += dirs[i];
}
@@ -3315,17 +3241,16 @@ String String::simplify_path() const {
}
static int _humanize_digits(int p_num) {
-
- if (p_num < 100)
+ if (p_num < 100) {
return 2;
- else if (p_num < 1024)
+ } else if (p_num < 1024) {
return 1;
- else
+ } else {
return 0;
+ }
}
String String::humanize_size(uint64_t p_size) {
-
uint64_t _div = 1;
Vector<String> prefixes;
prefixes.push_back(RTR("B"));
@@ -3348,36 +3273,38 @@ String String::humanize_size(uint64_t p_size) {
return String::num(p_size / divisor).pad_decimals(digits) + " " + prefixes[prefix_idx];
}
-bool String::is_abs_path() const {
- if (length() > 1)
+bool String::is_abs_path() const {
+ if (length() > 1) {
return (operator[](0) == '/' || operator[](0) == '\\' || find(":/") != -1 || find(":\\") != -1);
- else if ((length()) == 1)
+ } else if ((length()) == 1) {
return (operator[](0) == '/' || operator[](0) == '\\');
- else
+ } else {
return false;
+ }
}
bool String::is_valid_identifier() const {
-
int len = length();
- if (len == 0)
+ if (len == 0) {
return false;
+ }
const wchar_t *str = &operator[](0);
for (int i = 0; i < len; i++) {
-
if (i == 0) {
- if (str[0] >= '0' && str[0] <= '9')
+ if (str[0] >= '0' && str[0] <= '9') {
return false; // no start with number plz
+ }
}
bool valid_char = (str[i] >= '0' && str[i] <= '9') || (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z') || str[i] == '_';
- if (!valid_char)
+ if (!valid_char) {
return false;
+ }
}
return true;
@@ -3386,7 +3313,6 @@ bool String::is_valid_identifier() const {
//kind of poor should be rewritten properly
String String::word_wrap(int p_chars_per_line) const {
-
int from = 0;
int last_space = 0;
String ret;
@@ -3463,7 +3389,6 @@ String String::http_unescape() const {
}
String String::c_unescape() const {
-
String escaped = *this;
escaped = escaped.replace("\\a", "\a");
escaped = escaped.replace("\\b", "\b");
@@ -3481,7 +3406,6 @@ String String::c_unescape() const {
}
String String::c_escape() const {
-
String escaped = *this;
escaped = escaped.replace("\\", "\\\\");
escaped = escaped.replace("\a", "\\a");
@@ -3499,7 +3423,6 @@ String String::c_escape() const {
}
String String::c_escape_multiline() const {
-
String escaped = *this;
escaped = escaped.replace("\\", "\\\\");
escaped = escaped.replace("\"", "\\\"");
@@ -3508,7 +3431,6 @@ String String::c_escape_multiline() const {
}
String String::json_escape() const {
-
String escaped = *this;
escaped = escaped.replace("\\", "\\\\");
escaped = escaped.replace("\b", "\\b");
@@ -3523,7 +3445,6 @@ String String::json_escape() const {
}
String String::xml_escape(bool p_escape_quotes) const {
-
String str = *this;
str = str.replace("&", "&amp;");
str = str.replace("<", "&lt;");
@@ -3533,29 +3454,24 @@ String String::xml_escape(bool p_escape_quotes) const {
str = str.replace("\"", "&quot;");
}
/*
- for (int i=1;i<32;i++) {
+for (int i=1;i<32;i++) {
- char chr[2]={i,0};
- str=str.replace(chr,"&#"+String::num(i)+";");
- }*/
+ char chr[2]={i,0};
+ str=str.replace(chr,"&#"+String::num(i)+";");
+}*/
return str;
}
static _FORCE_INLINE_ int _xml_unescape(const CharType *p_src, int p_src_len, CharType *p_dst) {
-
int len = 0;
while (p_src_len) {
-
if (*p_src == '&') {
-
int eat = 0;
if (p_src_len >= 4 && p_src[1] == '#') {
-
CharType c = 0;
for (int i = 2; i < p_src_len; i++) {
-
eat = i + 1;
CharType ct = p_src[i];
if (ct == ';') {
@@ -3573,49 +3489,50 @@ static _FORCE_INLINE_ int _xml_unescape(const CharType *p_src, int p_src_len, Ch
c |= ct;
}
- if (p_dst)
+ if (p_dst) {
*p_dst = c;
+ }
} else if (p_src_len >= 4 && p_src[1] == 'g' && p_src[2] == 't' && p_src[3] == ';') {
-
- if (p_dst)
+ if (p_dst) {
*p_dst = '>';
+ }
eat = 4;
} else if (p_src_len >= 4 && p_src[1] == 'l' && p_src[2] == 't' && p_src[3] == ';') {
-
- if (p_dst)
+ if (p_dst) {
*p_dst = '<';
+ }
eat = 4;
} else if (p_src_len >= 5 && p_src[1] == 'a' && p_src[2] == 'm' && p_src[3] == 'p' && p_src[4] == ';') {
-
- if (p_dst)
+ if (p_dst) {
*p_dst = '&';
+ }
eat = 5;
} else if (p_src_len >= 6 && p_src[1] == 'q' && p_src[2] == 'u' && p_src[3] == 'o' && p_src[4] == 't' && p_src[5] == ';') {
-
- if (p_dst)
+ if (p_dst) {
*p_dst = '"';
+ }
eat = 6;
} else if (p_src_len >= 6 && p_src[1] == 'a' && p_src[2] == 'p' && p_src[3] == 'o' && p_src[4] == 's' && p_src[5] == ';') {
-
- if (p_dst)
+ if (p_dst) {
*p_dst = '\'';
+ }
eat = 6;
} else {
-
- if (p_dst)
+ if (p_dst) {
*p_dst = *p_src;
+ }
eat = 1;
}
- if (p_dst)
+ if (p_dst) {
p_dst++;
+ }
len++;
p_src += eat;
p_src_len -= eat;
} else {
-
if (p_dst) {
*p_dst = *p_src;
p_dst++;
@@ -3630,12 +3547,12 @@ static _FORCE_INLINE_ int _xml_unescape(const CharType *p_src, int p_src_len, Ch
}
String String::xml_unescape() const {
-
String str;
int l = length();
int len = _xml_unescape(c_str(), l, nullptr);
- if (len == 0)
+ if (len == 0) {
return String();
+ }
str.resize(len + 1);
_xml_unescape(c_str(), l, str.ptrw());
str[len] = 0;
@@ -3643,7 +3560,6 @@ String String::xml_unescape() const {
}
String String::pad_decimals(int p_digits) const {
-
String s = *this;
int c = s.find(".");
@@ -3670,7 +3586,6 @@ String String::pad_decimals(int p_digits) const {
}
String String::pad_zeros(int p_digits) const {
-
String s = *this;
int end = s.find(".");
@@ -3678,8 +3593,9 @@ String String::pad_zeros(int p_digits) const {
end = s.length();
}
- if (end == 0)
+ if (end == 0) {
return s;
+ }
int begin = 0;
@@ -3687,11 +3603,11 @@ String String::pad_zeros(int p_digits) const {
begin++;
}
- if (begin >= end)
+ if (begin >= end) {
return s;
+ }
while (end - begin < p_digits) {
-
s = s.insert(begin, "0");
end++;
}
@@ -3700,7 +3616,6 @@ String String::pad_zeros(int p_digits) const {
}
String String::trim_prefix(const String &p_prefix) const {
-
String s = *this;
if (s.begins_with(p_prefix)) {
return s.substr(p_prefix.length(), s.length() - p_prefix.length());
@@ -3709,7 +3624,6 @@ String String::trim_prefix(const String &p_prefix) const {
}
String String::trim_suffix(const String &p_suffix) const {
-
String s = *this;
if (s.ends_with(p_suffix)) {
return s.substr(0, s.length() - p_suffix.length());
@@ -3718,40 +3632,42 @@ String String::trim_suffix(const String &p_suffix) const {
}
bool String::is_valid_integer() const {
-
int len = length();
- if (len == 0)
+ if (len == 0) {
return false;
+ }
int from = 0;
- if (len != 1 && (operator[](0) == '+' || operator[](0) == '-'))
+ if (len != 1 && (operator[](0) == '+' || operator[](0) == '-')) {
from++;
+ }
for (int i = from; i < len; i++) {
-
- if (operator[](i) < '0' || operator[](i) > '9')
+ if (operator[](i) < '0' || operator[](i) > '9') {
return false; // no start with number plz
+ }
}
return true;
}
bool String::is_valid_hex_number(bool p_with_prefix) const {
-
int len = length();
- if (len == 0)
+ if (len == 0) {
return false;
+ }
int from = 0;
- if (len != 1 && (operator[](0) == '+' || operator[](0) == '-'))
+ if (len != 1 && (operator[](0) == '+' || operator[](0) == '-')) {
from++;
+ }
if (p_with_prefix) {
-
- if (len < 3)
+ if (len < 3) {
return false;
+ }
if (operator[](from) != '0' || operator[](from + 1) != 'x') {
return false;
}
@@ -3759,22 +3675,22 @@ bool String::is_valid_hex_number(bool p_with_prefix) const {
}
for (int i = from; i < len; i++) {
-
CharType c = operator[](i);
- if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
+ if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
continue;
+ }
return false;
}
return true;
-};
+}
bool String::is_valid_float() const {
-
int len = length();
- if (len == 0)
+ if (len == 0) {
return false;
+ }
int from = 0;
if (operator[](0) == '+' || operator[](0) == '-') {
@@ -3788,71 +3704,70 @@ bool String::is_valid_float() const {
bool numbers_found = false;
for (int i = from; i < len; i++) {
-
if (operator[](i) >= '0' && operator[](i) <= '9') {
-
- if (exponent_found)
+ if (exponent_found) {
exponent_values_found = true;
- else
+ } else {
numbers_found = true;
+ }
} else if (numbers_found && !exponent_found && operator[](i) == 'e') {
exponent_found = true;
} else if (!period_found && !exponent_found && operator[](i) == '.') {
period_found = true;
} else if ((operator[](i) == '-' || operator[](i) == '+') && exponent_found && !exponent_values_found && !sign_found) {
sign_found = true;
- } else
+ } else {
return false; // no start with number plz
+ }
}
return numbers_found;
}
String String::path_to_file(const String &p_path) const {
-
// Don't get base dir for src, this is expected to be a dir already.
String src = this->replace("\\", "/");
String dst = p_path.replace("\\", "/").get_base_dir();
String rel = src.path_to(dst);
- if (rel == dst) // failed
+ if (rel == dst) { // failed
return p_path;
- else
+ } else {
return rel + p_path.get_file();
+ }
}
String String::path_to(const String &p_path) const {
-
String src = this->replace("\\", "/");
String dst = p_path.replace("\\", "/");
- if (!src.ends_with("/"))
+ if (!src.ends_with("/")) {
src += "/";
- if (!dst.ends_with("/"))
+ }
+ if (!dst.ends_with("/")) {
dst += "/";
+ }
String base;
if (src.begins_with("res://") && dst.begins_with("res://")) {
-
base = "res:/";
src = src.replace("res://", "/");
dst = dst.replace("res://", "/");
} else if (src.begins_with("user://") && dst.begins_with("user://")) {
-
base = "user:/";
src = src.replace("user://", "/");
dst = dst.replace("user://", "/");
} else if (src.begins_with("/") && dst.begins_with("/")) {
-
//nothing
} else {
//dos style
String src_begin = src.get_slicec('/', 0);
String dst_begin = dst.get_slicec('/', 0);
- if (src_begin != dst_begin)
+ if (src_begin != dst_begin) {
return p_path; //impossible to do this
+ }
base = src_begin;
src = src.substr(src_begin.length(), src.length());
@@ -3867,12 +3782,15 @@ String String::path_to(const String &p_path) const {
int common_parent = 0;
while (true) {
- if (src_dirs.size() == common_parent)
+ if (src_dirs.size() == common_parent) {
break;
- if (dst_dirs.size() == common_parent)
+ }
+ if (dst_dirs.size() == common_parent) {
break;
- if (src_dirs[common_parent] != dst_dirs[common_parent])
+ }
+ if (src_dirs[common_parent] != dst_dirs[common_parent]) {
break;
+ }
common_parent++;
}
@@ -3881,27 +3799,24 @@ String String::path_to(const String &p_path) const {
String dir;
for (int i = src_dirs.size() - 1; i > common_parent; i--) {
-
dir += "../";
}
for (int i = common_parent + 1; i < dst_dirs.size(); i++) {
-
dir += dst_dirs[i] + "/";
}
- if (dir.length() == 0)
+ if (dir.length() == 0) {
dir = "./";
+ }
return dir;
}
bool String::is_valid_html_color() const {
-
return Color::html_is_valid(*this);
}
bool String::is_valid_filename() const {
-
String stripped = strip_edges();
if (*this != stripped) {
return false;
@@ -3915,55 +3830,54 @@ bool String::is_valid_filename() const {
}
bool String::is_valid_ip_address() const {
-
if (find(":") >= 0) {
-
Vector<String> ip = split(":");
for (int i = 0; i < ip.size(); i++) {
-
String n = ip[i];
- if (n.empty())
+ if (n.empty()) {
continue;
+ }
if (n.is_valid_hex_number(false)) {
int nint = n.hex_to_int(false);
- if (nint < 0 || nint > 0xffff)
+ if (nint < 0 || nint > 0xffff) {
return false;
+ }
continue;
- };
- if (!n.is_valid_ip_address())
+ }
+ if (!n.is_valid_ip_address()) {
return false;
- };
+ }
+ }
} else {
Vector<String> ip = split(".");
- if (ip.size() != 4)
+ if (ip.size() != 4) {
return false;
+ }
for (int i = 0; i < ip.size(); i++) {
-
String n = ip[i];
- if (!n.is_valid_integer())
+ if (!n.is_valid_integer()) {
return false;
+ }
int val = n.to_int();
- if (val < 0 || val > 255)
+ if (val < 0 || val > 255) {
return false;
+ }
}
- };
+ }
return true;
}
bool String::is_resource_file() const {
-
return begins_with("res://") && find("::") == -1;
}
bool String::is_rel_path() const {
-
return !is_abs_path();
}
String String::get_base_dir() const {
-
int basepos = find("://");
String rs;
String base;
@@ -3976,52 +3890,52 @@ String String::get_base_dir() const {
rs = substr(1, length());
base = "/";
} else {
-
rs = *this;
}
}
int sep = MAX(rs.find_last("/"), rs.find_last("\\"));
- if (sep == -1)
+ if (sep == -1) {
return base;
+ }
return base + rs.substr(0, sep);
}
String String::get_file() const {
-
int sep = MAX(find_last("/"), find_last("\\"));
- if (sep == -1)
+ if (sep == -1) {
return *this;
+ }
return substr(sep + 1, length());
}
String String::get_extension() const {
-
int pos = find_last(".");
- if (pos < 0 || pos < MAX(find_last("/"), find_last("\\")))
+ if (pos < 0 || pos < MAX(find_last("/"), find_last("\\"))) {
return "";
+ }
return substr(pos + 1, length());
}
String String::plus_file(const String &p_file) const {
- if (empty())
+ if (empty()) {
return p_file;
- if (operator[](length() - 1) == '/' || (p_file.size() > 0 && p_file.operator[](0) == '/'))
+ }
+ if (operator[](length() - 1) == '/' || (p_file.size() > 0 && p_file.operator[](0) == '/')) {
return *this + p_file;
+ }
return *this + "/" + p_file;
}
String String::percent_encode() const {
-
CharString cs = utf8();
String encoded;
for (int i = 0; i < cs.length(); i++) {
uint8_t c = cs[i];
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '~' || c == '.') {
-
char p[2] = { (char)c, 0 };
encoded += p;
} else {
@@ -4036,34 +3950,34 @@ String String::percent_encode() const {
return encoded;
}
-String String::percent_decode() const {
+String String::percent_decode() const {
CharString pe;
CharString cs = utf8();
for (int i = 0; i < cs.length(); i++) {
-
uint8_t c = cs[i];
if (c == '%' && i < length() - 2) {
-
uint8_t a = LOWERCASE(cs[i + 1]);
uint8_t b = LOWERCASE(cs[i + 2]);
- if (a >= '0' && a <= '9')
+ if (a >= '0' && a <= '9') {
c = (a - '0') << 4;
- else if (a >= 'a' && a <= 'f')
+ } else if (a >= 'a' && a <= 'f') {
c = (a - 'a' + 10) << 4;
- else
+ } else {
continue;
+ }
uint8_t d = 0;
- if (b >= '0' && b <= '9')
+ if (b >= '0' && b <= '9') {
d = (b - '0');
- else if (b >= 'a' && b <= 'f')
+ } else if (b >= 'a' && b <= 'f') {
d = (b - 'a' + 10);
- else
+ } else {
continue;
+ }
c += d;
i += 2;
}
@@ -4087,31 +4001,27 @@ String String::property_name_encode() const {
}
String String::get_basename() const {
-
int pos = find_last(".");
- if (pos < 0 || pos < MAX(find_last("/"), find_last("\\")))
+ if (pos < 0 || pos < MAX(find_last("/"), find_last("\\"))) {
return *this;
+ }
return substr(0, pos);
}
String itos(int64_t p_val) {
-
return String::num_int64(p_val);
}
String uitos(uint64_t p_val) {
-
return String::num_uint64(p_val);
}
String rtos(double p_val) {
-
return String::num(p_val);
}
String rtoss(double p_val) {
-
return String::num_scientific(p_val);
}
@@ -4120,19 +4030,22 @@ String String::rpad(int min_length, const String &character) const {
String s = *this;
int padding = min_length - s.length();
if (padding > 0) {
- for (int i = 0; i < padding; i++)
+ for (int i = 0; i < padding; i++) {
s = s + character;
+ }
}
return s;
}
+
// Left-pad with a character.
String String::lpad(int min_length, const String &character) const {
String s = *this;
int padding = min_length - s.length();
if (padding > 0) {
- for (int i = 0; i < padding; i++)
+ for (int i = 0; i < padding; i++) {
s = character + s;
+ }
}
return s;
@@ -4182,9 +4095,14 @@ String String::sprintf(const Array &values, bool *error) const {
int base = 16;
bool capitalize = false;
switch (c) {
- case 'd': base = 10; break;
- case 'o': base = 8; break;
- case 'x': break;
+ case 'd':
+ base = 10;
+ break;
+ case 'o':
+ base = 8;
+ break;
+ case 'x':
+ break;
case 'X':
base = 16;
capitalize = true;
diff --git a/core/ustring.h b/core/ustring.h
index ee7e3b1e16..5b13a1c704 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -51,8 +51,9 @@ class CharProxy {
public:
_FORCE_INLINE_ operator T() const {
- if (unlikely(_index == _cowdata.size()))
+ if (unlikely(_index == _cowdata.size())) {
return _null;
+ }
return _cowdata.get(_index);
}
@@ -71,7 +72,6 @@ public:
};
class CharString {
-
CowData<char> _cowdata;
static const char _null;
@@ -84,8 +84,9 @@ public:
_FORCE_INLINE_ char get(int p_index) const { return _cowdata.get(p_index); }
_FORCE_INLINE_ void set(int p_index, const char &p_elem) { _cowdata.set(p_index, p_elem); }
_FORCE_INLINE_ const char &operator[](int p_index) const {
- if (unlikely(p_index == _cowdata.size()))
+ if (unlikely(p_index == _cowdata.size())) {
return _null;
+ }
return _cowdata.get(p_index);
}
@@ -113,7 +114,6 @@ protected:
typedef wchar_t CharType;
struct StrRange {
-
const CharType *c_str;
int len;
@@ -124,7 +124,6 @@ struct StrRange {
};
class String {
-
CowData<CharType> _cowdata;
static const CharType _null;
@@ -154,8 +153,9 @@ public:
Error resize(int p_size) { return _cowdata.resize(p_size); }
_FORCE_INLINE_ const CharType &operator[](int p_index) const {
- if (unlikely(p_index == _cowdata.size()))
+ if (unlikely(p_index == _cowdata.size())) {
return _null;
+ }
return _cowdata.get(p_index);
}
@@ -254,7 +254,7 @@ public:
static int to_int(const char *p_str, int p_len = -1);
static double to_double(const char *p_str);
static double to_double(const CharType *p_str, const CharType **r_end = nullptr);
- static int64_t to_int(const CharType *p_str, int p_len = -1);
+ static int64_t to_int(const CharType *p_str, int p_len = -1, bool p_clamp = false);
String capitalize() const;
String camelcase_to_underscore(bool lowercase = true) const;
@@ -377,36 +377,31 @@ String rtos(double p_val);
String rtoss(double p_val); //scientific version
struct NoCaseComparator {
-
bool operator()(const String &p_a, const String &p_b) const {
-
return p_a.nocasecmp_to(p_b) < 0;
}
};
struct NaturalNoCaseComparator {
-
bool operator()(const String &p_a, const String &p_b) const {
-
return p_a.naturalnocasecmp_to(p_b) < 0;
}
};
template <typename L, typename R>
_FORCE_INLINE_ bool is_str_less(const L *l_ptr, const R *r_ptr) {
-
while (true) {
-
- if (*l_ptr == 0 && *r_ptr == 0)
+ if (*l_ptr == 0 && *r_ptr == 0) {
return false;
- else if (*l_ptr == 0)
+ } else if (*l_ptr == 0) {
return true;
- else if (*r_ptr == 0)
+ } else if (*r_ptr == 0) {
return false;
- else if (*l_ptr < *r_ptr)
+ } else if (*l_ptr < *r_ptr) {
return true;
- else if (*l_ptr > *r_ptr)
+ } else if (*l_ptr > *r_ptr) {
return false;
+ }
l_ptr++;
r_ptr++;
diff --git a/core/variant.cpp b/core/variant.cpp
index b3611536b8..21aaa0fe9e 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -41,177 +41,136 @@
#include "scene/main/node.h"
String Variant::get_type_name(Variant::Type p_type) {
-
switch (p_type) {
case NIL: {
-
return "Nil";
} break;
// atomic types
case BOOL: {
-
return "bool";
} break;
case INT: {
-
return "int";
} break;
case FLOAT: {
-
return "float";
} break;
case STRING: {
-
return "String";
} break;
// math types
case VECTOR2: {
-
return "Vector2";
} break;
case VECTOR2I: {
-
return "Vector2i";
} break;
case RECT2: {
-
return "Rect2";
} break;
case RECT2I: {
-
return "Rect2i";
} break;
case TRANSFORM2D: {
-
return "Transform2D";
} break;
case VECTOR3: {
-
return "Vector3";
} break;
case VECTOR3I: {
-
return "Vector3i";
} break;
case PLANE: {
-
return "Plane";
} break;
- /*
- case QUAT: {
-
-
- } break;*/
case AABB: {
-
return "AABB";
} break;
case QUAT: {
-
return "Quat";
} break;
case BASIS: {
-
return "Basis";
} break;
case TRANSFORM: {
-
return "Transform";
} break;
// misc types
case COLOR: {
-
return "Color";
} break;
case _RID: {
-
return "RID";
} break;
case OBJECT: {
-
return "Object";
} break;
case CALLABLE: {
-
return "Callable";
} break;
case SIGNAL: {
-
return "Signal";
} break;
case STRING_NAME: {
-
return "StringName";
} break;
case NODE_PATH: {
-
return "NodePath";
} break;
case DICTIONARY: {
-
return "Dictionary";
} break;
case ARRAY: {
-
return "Array";
} break;
// arrays
case PACKED_BYTE_ARRAY: {
-
return "PackedByteArray";
} break;
case PACKED_INT32_ARRAY: {
-
return "PackedInt32Array";
} break;
case PACKED_INT64_ARRAY: {
-
return "PackedInt64Array";
} break;
case PACKED_FLOAT32_ARRAY: {
-
return "PackedFloat32Array";
} break;
case PACKED_FLOAT64_ARRAY: {
-
return "PackedFloat64Array";
} break;
case PACKED_STRING_ARRAY: {
-
return "PackedStringArray";
} break;
case PACKED_VECTOR2_ARRAY: {
-
return "PackedVector2Array";
} break;
case PACKED_VECTOR3_ARRAY: {
-
return "PackedVector3Array";
} break;
case PACKED_COLOR_ARRAY: {
-
return "PackedColorArray";
} break;
@@ -223,22 +182,22 @@ String Variant::get_type_name(Variant::Type p_type) {
}
bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
-
- if (p_type_from == p_type_to)
+ if (p_type_from == p_type_to) {
return true;
- if (p_type_to == NIL && p_type_from != NIL) //nil can convert to anything
+ }
+ if (p_type_to == NIL && p_type_from != NIL) { //nil can convert to anything
return true;
+ }
if (p_type_from == NIL) {
return (p_type_to == OBJECT);
- };
+ }
const Type *valid_types = nullptr;
const Type *invalid_types = nullptr;
switch (p_type_to) {
case BOOL: {
-
static const Type valid[] = {
INT,
FLOAT,
@@ -249,7 +208,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case INT: {
-
static const Type valid[] = {
BOOL,
FLOAT,
@@ -261,7 +219,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case FLOAT: {
-
static const Type valid[] = {
BOOL,
INT,
@@ -273,7 +230,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case STRING: {
-
static const Type invalid[] = {
OBJECT,
NIL
@@ -282,7 +238,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
invalid_types = invalid;
} break;
case VECTOR2: {
-
static const Type valid[] = {
VECTOR2I,
NIL,
@@ -292,7 +247,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case VECTOR2I: {
-
static const Type valid[] = {
VECTOR2,
NIL,
@@ -302,7 +256,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case RECT2: {
-
static const Type valid[] = {
RECT2I,
NIL,
@@ -312,7 +265,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case RECT2I: {
-
static const Type valid[] = {
RECT2,
NIL,
@@ -322,7 +274,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case TRANSFORM2D: {
-
static const Type valid[] = {
TRANSFORM,
NIL
@@ -331,7 +282,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case VECTOR3: {
-
static const Type valid[] = {
VECTOR3I,
NIL,
@@ -341,7 +291,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case VECTOR3I: {
-
static const Type valid[] = {
VECTOR3,
NIL,
@@ -352,7 +301,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case QUAT: {
-
static const Type valid[] = {
BASIS,
NIL
@@ -362,7 +310,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case BASIS: {
-
static const Type valid[] = {
QUAT,
VECTOR3,
@@ -373,7 +320,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case TRANSFORM: {
-
static const Type valid[] = {
TRANSFORM2D,
QUAT,
@@ -386,7 +332,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case COLOR: {
-
static const Type valid[] = {
STRING,
INT,
@@ -398,7 +343,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case _RID: {
-
static const Type valid[] = {
OBJECT,
NIL
@@ -407,7 +351,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case OBJECT: {
-
static const Type valid[] = {
NIL
};
@@ -415,7 +358,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case STRING_NAME: {
-
static const Type valid[] = {
STRING,
NIL
@@ -424,7 +366,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case NODE_PATH: {
-
static const Type valid[] = {
STRING,
NIL
@@ -433,7 +374,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case ARRAY: {
-
static const Type valid[] = {
PACKED_BYTE_ARRAY,
PACKED_INT32_ARRAY,
@@ -451,7 +391,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
// arrays
case PACKED_BYTE_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -460,7 +399,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case PACKED_INT32_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -468,7 +406,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case PACKED_INT64_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -476,7 +413,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case PACKED_FLOAT32_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -485,7 +421,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case PACKED_FLOAT64_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -494,7 +429,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case PACKED_STRING_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -502,7 +436,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
valid_types = valid;
} break;
case PACKED_VECTOR2_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -511,7 +444,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case PACKED_VECTOR3_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -520,7 +452,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
} break;
case PACKED_COLOR_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -534,22 +465,20 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
}
if (valid_types) {
-
int i = 0;
while (valid_types[i] != NIL) {
-
- if (p_type_from == valid_types[i])
+ if (p_type_from == valid_types[i]) {
return true;
+ }
i++;
}
} else if (invalid_types) {
-
int i = 0;
while (invalid_types[i] != NIL) {
-
- if (p_type_from == invalid_types[i])
+ if (p_type_from == invalid_types[i]) {
return false;
+ }
i++;
}
@@ -560,21 +489,21 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
}
bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type_to) {
-
- if (p_type_from == p_type_to)
+ if (p_type_from == p_type_to) {
return true;
- if (p_type_to == NIL && p_type_from != NIL) //nil can convert to anything
+ }
+ if (p_type_to == NIL && p_type_from != NIL) { //nil can convert to anything
return true;
+ }
if (p_type_from == NIL) {
return (p_type_to == OBJECT);
- };
+ }
const Type *valid_types = nullptr;
switch (p_type_to) {
case BOOL: {
-
static const Type valid[] = {
INT,
FLOAT,
@@ -585,7 +514,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case INT: {
-
static const Type valid[] = {
BOOL,
FLOAT,
@@ -597,7 +525,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case FLOAT: {
-
static const Type valid[] = {
BOOL,
INT,
@@ -609,7 +536,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case STRING: {
-
static const Type valid[] = {
NODE_PATH,
STRING_NAME,
@@ -619,7 +545,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case VECTOR2: {
-
static const Type valid[] = {
VECTOR2I,
NIL,
@@ -629,7 +554,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case VECTOR2I: {
-
static const Type valid[] = {
VECTOR2,
NIL,
@@ -639,7 +563,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case RECT2: {
-
static const Type valid[] = {
RECT2I,
NIL,
@@ -649,7 +572,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case RECT2I: {
-
static const Type valid[] = {
RECT2,
NIL,
@@ -659,7 +581,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case TRANSFORM2D: {
-
static const Type valid[] = {
TRANSFORM,
NIL
@@ -668,7 +589,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case VECTOR3: {
-
static const Type valid[] = {
VECTOR3I,
NIL,
@@ -678,7 +598,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case VECTOR3I: {
-
static const Type valid[] = {
VECTOR3,
NIL,
@@ -689,7 +608,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case QUAT: {
-
static const Type valid[] = {
BASIS,
NIL
@@ -699,7 +617,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case BASIS: {
-
static const Type valid[] = {
QUAT,
VECTOR3,
@@ -710,7 +627,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case TRANSFORM: {
-
static const Type valid[] = {
TRANSFORM2D,
QUAT,
@@ -723,7 +639,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case COLOR: {
-
static const Type valid[] = {
STRING,
INT,
@@ -735,7 +650,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case _RID: {
-
static const Type valid[] = {
OBJECT,
NIL
@@ -744,7 +658,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case OBJECT: {
-
static const Type valid[] = {
NIL
};
@@ -752,7 +665,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case STRING_NAME: {
-
static const Type valid[] = {
STRING,
NIL
@@ -761,7 +673,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case NODE_PATH: {
-
static const Type valid[] = {
STRING,
NIL
@@ -770,7 +681,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case ARRAY: {
-
static const Type valid[] = {
PACKED_BYTE_ARRAY,
PACKED_INT32_ARRAY,
@@ -788,7 +698,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
// arrays
case PACKED_BYTE_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -797,7 +706,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case PACKED_INT32_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -805,7 +713,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case PACKED_INT64_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -813,7 +720,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case PACKED_FLOAT32_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -822,7 +728,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case PACKED_FLOAT64_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -831,7 +736,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case PACKED_STRING_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -839,7 +743,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
valid_types = valid;
} break;
case PACKED_VECTOR2_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -848,7 +751,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case PACKED_VECTOR3_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -857,7 +759,6 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
} break;
case PACKED_COLOR_ARRAY: {
-
static const Type valid[] = {
ARRAY,
NIL
@@ -871,12 +772,11 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
}
if (valid_types) {
-
int i = 0;
while (valid_types[i] != NIL) {
-
- if (p_type_from == valid_types[i])
+ if (p_type_from == valid_types[i]) {
return true;
+ }
i++;
}
}
@@ -885,9 +785,9 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type
}
bool Variant::operator==(const Variant &p_variant) const {
-
- if (type != p_variant.type) //evaluation of operator== needs to be more strict
+ if (type != p_variant.type) { //evaluation of operator== needs to be more strict
return false;
+ }
bool v;
Variant r;
evaluate(OP_EQUAL, *this, p_variant, r, v);
@@ -895,9 +795,9 @@ bool Variant::operator==(const Variant &p_variant) const {
}
bool Variant::operator!=(const Variant &p_variant) const {
-
- if (type != p_variant.type) //evaluation of operator== needs to be more strict
+ if (type != p_variant.type) { //evaluation of operator== needs to be more strict
return true;
+ }
bool v;
Variant r;
evaluate(OP_NOT_EQUAL, *this, p_variant, r, v);
@@ -905,8 +805,9 @@ bool Variant::operator!=(const Variant &p_variant) const {
}
bool Variant::operator<(const Variant &p_variant) const {
- if (type != p_variant.type) //if types differ, then order by type first
+ if (type != p_variant.type) { //if types differ, then order by type first
return type < p_variant.type;
+ }
bool v;
Variant r;
evaluate(OP_LESS, *this, p_variant, r, v);
@@ -914,186 +815,145 @@ bool Variant::operator<(const Variant &p_variant) const {
}
bool Variant::is_zero() const {
-
switch (type) {
case NIL: {
-
return true;
} break;
// atomic types
case BOOL: {
-
return !(_data._bool);
} break;
case INT: {
-
return _data._int == 0;
} break;
case FLOAT: {
-
return _data._float == 0;
} break;
case STRING: {
-
return *reinterpret_cast<const String *>(_data._mem) == String();
} break;
// math types
case VECTOR2: {
-
return *reinterpret_cast<const Vector2 *>(_data._mem) == Vector2();
} break;
case VECTOR2I: {
-
return *reinterpret_cast<const Vector2i *>(_data._mem) == Vector2i();
} break;
case RECT2: {
-
return *reinterpret_cast<const Rect2 *>(_data._mem) == Rect2();
} break;
case RECT2I: {
-
return *reinterpret_cast<const Rect2i *>(_data._mem) == Rect2i();
} break;
case TRANSFORM2D: {
-
return *_data._transform2d == Transform2D();
} break;
case VECTOR3: {
-
return *reinterpret_cast<const Vector3 *>(_data._mem) == Vector3();
} break;
case VECTOR3I: {
-
return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i();
} break;
case PLANE: {
-
return *reinterpret_cast<const Plane *>(_data._mem) == Plane();
} break;
- /*
- case QUAT: {
-
-
- } break;*/
case AABB: {
-
return *_data._aabb == ::AABB();
} break;
case QUAT: {
-
return *reinterpret_cast<const Quat *>(_data._mem) == Quat();
} break;
case BASIS: {
-
return *_data._basis == Basis();
} break;
case TRANSFORM: {
-
return *_data._transform == Transform();
} break;
// misc types
case COLOR: {
-
return *reinterpret_cast<const Color *>(_data._mem) == Color();
} break;
case _RID: {
-
return *reinterpret_cast<const RID *>(_data._mem) == RID();
} break;
case OBJECT: {
-
return _get_obj().obj == nullptr;
} break;
case CALLABLE: {
-
return reinterpret_cast<const Callable *>(_data._mem)->is_null();
} break;
case SIGNAL: {
-
return reinterpret_cast<const Signal *>(_data._mem)->is_null();
} break;
case STRING_NAME: {
-
return *reinterpret_cast<const StringName *>(_data._mem) != StringName();
} break;
case NODE_PATH: {
-
return reinterpret_cast<const NodePath *>(_data._mem)->is_empty();
} break;
case DICTIONARY: {
-
return reinterpret_cast<const Dictionary *>(_data._mem)->empty();
} break;
case ARRAY: {
-
return reinterpret_cast<const Array *>(_data._mem)->empty();
} break;
// arrays
case PACKED_BYTE_ARRAY: {
-
return PackedArrayRef<uint8_t>::get_array(_data.packed_array).size() == 0;
} break;
case PACKED_INT32_ARRAY: {
-
return PackedArrayRef<int32_t>::get_array(_data.packed_array).size() == 0;
} break;
case PACKED_INT64_ARRAY: {
-
return PackedArrayRef<int64_t>::get_array(_data.packed_array).size() == 0;
} break;
case PACKED_FLOAT32_ARRAY: {
-
return PackedArrayRef<float>::get_array(_data.packed_array).size() == 0;
} break;
case PACKED_FLOAT64_ARRAY: {
-
return PackedArrayRef<double>::get_array(_data.packed_array).size() == 0;
} break;
case PACKED_STRING_ARRAY: {
-
return PackedArrayRef<String>::get_array(_data.packed_array).size() == 0;
} break;
case PACKED_VECTOR2_ARRAY: {
-
return PackedArrayRef<Vector2>::get_array(_data.packed_array).size() == 0;
} break;
case PACKED_VECTOR3_ARRAY: {
-
return PackedArrayRef<Vector3>::get_array(_data.packed_array).size() == 0;
} break;
case PACKED_COLOR_ARRAY: {
-
return PackedArrayRef<Color>::get_array(_data.packed_array).size() == 0;
} break;
@@ -1105,65 +965,52 @@ bool Variant::is_zero() const {
}
bool Variant::is_one() const {
-
switch (type) {
case NIL: {
-
return true;
} break;
// atomic types
case BOOL: {
-
return _data._bool;
} break;
case INT: {
-
return _data._int == 1;
} break;
case FLOAT: {
-
return _data._float == 1;
} break;
case VECTOR2: {
-
return *reinterpret_cast<const Vector2 *>(_data._mem) == Vector2(1, 1);
} break;
case VECTOR2I: {
-
return *reinterpret_cast<const Vector2i *>(_data._mem) == Vector2i(1, 1);
} break;
case RECT2: {
-
return *reinterpret_cast<const Rect2 *>(_data._mem) == Rect2(1, 1, 1, 1);
} break;
case RECT2I: {
-
return *reinterpret_cast<const Rect2i *>(_data._mem) == Rect2i(1, 1, 1, 1);
} break;
case VECTOR3: {
-
return *reinterpret_cast<const Vector3 *>(_data._mem) == Vector3(1, 1, 1);
} break;
case VECTOR3I: {
-
return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(1, 1, 1);
} break;
case PLANE: {
-
return *reinterpret_cast<const Plane *>(_data._mem) == Plane(1, 1, 1, 1);
} break;
case COLOR: {
-
return *reinterpret_cast<const Color *>(_data._mem) == Color(1, 1, 1, 1);
} break;
@@ -1185,7 +1032,6 @@ bool Variant::is_null() const {
}
void Variant::reference(const Variant &p_variant) {
-
switch (type) {
case NIL:
case BOOL:
@@ -1200,93 +1046,73 @@ void Variant::reference(const Variant &p_variant) {
switch (p_variant.type) {
case NIL: {
-
// none
} break;
// atomic types
case BOOL: {
-
_data._bool = p_variant._data._bool;
} break;
case INT: {
-
_data._int = p_variant._data._int;
} break;
case FLOAT: {
-
_data._float = p_variant._data._float;
} break;
case STRING: {
-
memnew_placement(_data._mem, String(*reinterpret_cast<const String *>(p_variant._data._mem)));
} break;
// math types
case VECTOR2: {
-
memnew_placement(_data._mem, Vector2(*reinterpret_cast<const Vector2 *>(p_variant._data._mem)));
} break;
case VECTOR2I: {
-
memnew_placement(_data._mem, Vector2i(*reinterpret_cast<const Vector2i *>(p_variant._data._mem)));
} break;
case RECT2: {
-
memnew_placement(_data._mem, Rect2(*reinterpret_cast<const Rect2 *>(p_variant._data._mem)));
} break;
case RECT2I: {
-
memnew_placement(_data._mem, Rect2i(*reinterpret_cast<const Rect2i *>(p_variant._data._mem)));
} break;
case TRANSFORM2D: {
-
_data._transform2d = memnew(Transform2D(*p_variant._data._transform2d));
} break;
case VECTOR3: {
-
memnew_placement(_data._mem, Vector3(*reinterpret_cast<const Vector3 *>(p_variant._data._mem)));
} break;
case VECTOR3I: {
-
memnew_placement(_data._mem, Vector3i(*reinterpret_cast<const Vector3i *>(p_variant._data._mem)));
} break;
case PLANE: {
-
memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem)));
} break;
case AABB: {
-
_data._aabb = memnew(::AABB(*p_variant._data._aabb));
} break;
case QUAT: {
-
memnew_placement(_data._mem, Quat(*reinterpret_cast<const Quat *>(p_variant._data._mem)));
} break;
case BASIS: {
-
_data._basis = memnew(Basis(*p_variant._data._basis));
} break;
case TRANSFORM: {
-
_data._transform = memnew(Transform(*p_variant._data._transform));
} break;
// misc types
case COLOR: {
-
memnew_placement(_data._mem, Color(*reinterpret_cast<const Color *>(p_variant._data._mem)));
} break;
case _RID: {
-
memnew_placement(_data._mem, RID(*reinterpret_cast<const RID *>(p_variant._data._mem)));
} break;
case OBJECT: {
-
memnew_placement(_data._mem, ObjData);
if (p_variant._get_obj().obj && p_variant._get_obj().id.is_reference()) {
@@ -1303,37 +1129,30 @@ void Variant::reference(const Variant &p_variant) {
} break;
case CALLABLE: {
-
memnew_placement(_data._mem, Callable(*reinterpret_cast<const Callable *>(p_variant._data._mem)));
} break;
case SIGNAL: {
-
memnew_placement(_data._mem, Signal(*reinterpret_cast<const Signal *>(p_variant._data._mem)));
} break;
case STRING_NAME: {
-
memnew_placement(_data._mem, StringName(*reinterpret_cast<const StringName *>(p_variant._data._mem)));
} break;
case NODE_PATH: {
-
memnew_placement(_data._mem, NodePath(*reinterpret_cast<const NodePath *>(p_variant._data._mem)));
} break;
case DICTIONARY: {
-
memnew_placement(_data._mem, Dictionary(*reinterpret_cast<const Dictionary *>(p_variant._data._mem)));
} break;
case ARRAY: {
-
memnew_placement(_data._mem, Array(*reinterpret_cast<const Array *>(p_variant._data._mem)));
} break;
// arrays
case PACKED_BYTE_ARRAY: {
-
_data.packed_array = static_cast<PackedArrayRef<uint8_t> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<uint8_t>::create();
@@ -1341,7 +1160,6 @@ void Variant::reference(const Variant &p_variant) {
} break;
case PACKED_INT32_ARRAY: {
-
_data.packed_array = static_cast<PackedArrayRef<int32_t> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<int32_t>::create();
@@ -1349,7 +1167,6 @@ void Variant::reference(const Variant &p_variant) {
} break;
case PACKED_INT64_ARRAY: {
-
_data.packed_array = static_cast<PackedArrayRef<int64_t> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<int64_t>::create();
@@ -1357,7 +1174,6 @@ void Variant::reference(const Variant &p_variant) {
} break;
case PACKED_FLOAT32_ARRAY: {
-
_data.packed_array = static_cast<PackedArrayRef<float> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<float>::create();
@@ -1365,7 +1181,6 @@ void Variant::reference(const Variant &p_variant) {
} break;
case PACKED_FLOAT64_ARRAY: {
-
_data.packed_array = static_cast<PackedArrayRef<double> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<double>::create();
@@ -1373,7 +1188,6 @@ void Variant::reference(const Variant &p_variant) {
} break;
case PACKED_STRING_ARRAY: {
-
_data.packed_array = static_cast<PackedArrayRef<String> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<String>::create();
@@ -1381,7 +1195,6 @@ void Variant::reference(const Variant &p_variant) {
} break;
case PACKED_VECTOR2_ARRAY: {
-
_data.packed_array = static_cast<PackedArrayRef<Vector2> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<Vector2>::create();
@@ -1389,7 +1202,6 @@ void Variant::reference(const Variant &p_variant) {
} break;
case PACKED_VECTOR3_ARRAY: {
-
_data.packed_array = static_cast<PackedArrayRef<Vector3> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<Vector3>::create();
@@ -1397,7 +1209,6 @@ void Variant::reference(const Variant &p_variant) {
} break;
case PACKED_COLOR_ARRAY: {
-
_data.packed_array = static_cast<PackedArrayRef<Color> *>(p_variant._data.packed_array)->reference();
if (!_data.packed_array) {
_data.packed_array = PackedArrayRef<Color>::create();
@@ -1411,28 +1222,53 @@ void Variant::reference(const Variant &p_variant) {
void Variant::zero() {
switch (type) {
- case NIL: break;
- case BOOL: this->_data._bool = false; break;
- case INT: this->_data._int = 0; break;
- case FLOAT: this->_data._float = 0; break;
- case VECTOR2: *reinterpret_cast<Vector2 *>(this->_data._mem) = Vector2(); break;
- case VECTOR2I: *reinterpret_cast<Vector2i *>(this->_data._mem) = Vector2i(); break;
- case RECT2: *reinterpret_cast<Rect2 *>(this->_data._mem) = Rect2(); break;
- case RECT2I: *reinterpret_cast<Rect2i *>(this->_data._mem) = Rect2i(); break;
- case VECTOR3: *reinterpret_cast<Vector3 *>(this->_data._mem) = Vector3(); break;
- case VECTOR3I: *reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i(); break;
- case PLANE: *reinterpret_cast<Plane *>(this->_data._mem) = Plane(); break;
- case QUAT: *reinterpret_cast<Quat *>(this->_data._mem) = Quat(); break;
- case COLOR: *reinterpret_cast<Color *>(this->_data._mem) = Color(); break;
- default: this->clear(); break;
+ case NIL:
+ break;
+ case BOOL:
+ this->_data._bool = false;
+ break;
+ case INT:
+ this->_data._int = 0;
+ break;
+ case FLOAT:
+ this->_data._float = 0;
+ break;
+ case VECTOR2:
+ *reinterpret_cast<Vector2 *>(this->_data._mem) = Vector2();
+ break;
+ case VECTOR2I:
+ *reinterpret_cast<Vector2i *>(this->_data._mem) = Vector2i();
+ break;
+ case RECT2:
+ *reinterpret_cast<Rect2 *>(this->_data._mem) = Rect2();
+ break;
+ case RECT2I:
+ *reinterpret_cast<Rect2i *>(this->_data._mem) = Rect2i();
+ break;
+ case VECTOR3:
+ *reinterpret_cast<Vector3 *>(this->_data._mem) = Vector3();
+ break;
+ case VECTOR3I:
+ *reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i();
+ break;
+ case PLANE:
+ *reinterpret_cast<Plane *>(this->_data._mem) = Plane();
+ break;
+ case QUAT:
+ *reinterpret_cast<Quat *>(this->_data._mem) = Quat();
+ break;
+ case COLOR:
+ *reinterpret_cast<Color *>(this->_data._mem) = Color();
+ break;
+ default:
+ this->clear();
+ break;
}
}
void Variant::clear() {
-
switch (type) {
case STRING: {
-
reinterpret_cast<String *>(_data._mem)->~String();
} break;
/*
@@ -1443,35 +1279,28 @@ void Variant::clear() {
COLOR,
VECTOR2,
RECT2
- */
+ */
case TRANSFORM2D: {
-
memdelete(_data._transform2d);
} break;
case AABB: {
-
memdelete(_data._aabb);
} break;
case BASIS: {
-
memdelete(_data._basis);
} break;
case TRANSFORM: {
-
memdelete(_data._transform);
} break;
// misc types
case STRING_NAME: {
-
reinterpret_cast<StringName *>(_data._mem)->~StringName();
} break;
case NODE_PATH: {
-
reinterpret_cast<NodePath *>(_data._mem)->~NodePath();
} break;
case OBJECT: {
-
if (_get_obj().id.is_reference()) {
//we are safe that there is a reference here
Reference *reference = static_cast<Reference *>(_get_obj().obj);
@@ -1487,56 +1316,43 @@ void Variant::clear() {
reinterpret_cast<RID *>(_data._mem)->~RID();
} break;
case CALLABLE: {
-
reinterpret_cast<Callable *>(_data._mem)->~Callable();
} break;
case SIGNAL: {
-
reinterpret_cast<Signal *>(_data._mem)->~Signal();
} break;
case DICTIONARY: {
-
reinterpret_cast<Dictionary *>(_data._mem)->~Dictionary();
} break;
case ARRAY: {
-
reinterpret_cast<Array *>(_data._mem)->~Array();
} break;
// arrays
case PACKED_BYTE_ARRAY: {
-
PackedArrayRefBase::destroy(_data.packed_array);
} break;
case PACKED_INT32_ARRAY: {
-
PackedArrayRefBase::destroy(_data.packed_array);
} break;
case PACKED_INT64_ARRAY: {
-
PackedArrayRefBase::destroy(_data.packed_array);
} break;
case PACKED_FLOAT32_ARRAY: {
-
PackedArrayRefBase::destroy(_data.packed_array);
} break;
case PACKED_FLOAT64_ARRAY: {
-
PackedArrayRefBase::destroy(_data.packed_array);
} break;
case PACKED_STRING_ARRAY: {
-
PackedArrayRefBase::destroy(_data.packed_array);
} break;
case PACKED_VECTOR2_ARRAY: {
-
PackedArrayRefBase::destroy(_data.packed_array);
} break;
case PACKED_VECTOR3_ARRAY: {
-
PackedArrayRefBase::destroy(_data.packed_array);
} break;
case PACKED_COLOR_ARRAY: {
-
PackedArrayRefBase::destroy(_data.packed_array);
} break;
default: {
@@ -1547,83 +1363,72 @@ void Variant::clear() {
}
Variant::operator signed int() const {
-
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
-
return 0;
}
}
}
-Variant::operator unsigned int() const {
+Variant::operator unsigned int() const {
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
-
return 0;
}
}
}
Variant::operator int64_t() const {
-
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int64();
- default: {
-
+ case NIL:
return 0;
- }
- }
-}
-
-/*
-Variant::operator long unsigned int() const {
-
- switch( type ) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._real;
- case STRING: return operator String().to_int();
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int64();
default: {
-
return 0;
}
}
-
- return 0;
-};
-*/
+}
Variant::operator uint64_t() const {
-
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
-
return 0;
}
}
@@ -1641,141 +1446,159 @@ Variant::operator ObjectID() const {
#ifdef NEED_LONG_INT
Variant::operator signed long() const {
-
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._real;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._real;
+ case STRING:
+ return operator String().to_int();
default: {
-
return 0;
}
}
return 0;
-};
+}
Variant::operator unsigned long() const {
-
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._real;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._real;
+ case STRING:
+ return operator String().to_int();
default: {
-
return 0;
}
}
return 0;
-};
+}
#endif
Variant::operator signed short() const {
-
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
-
return 0;
}
}
}
-Variant::operator unsigned short() const {
+Variant::operator unsigned short() const {
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
-
return 0;
}
}
}
-Variant::operator signed char() const {
+Variant::operator signed char() const {
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
-
return 0;
}
}
}
-Variant::operator unsigned char() const {
+Variant::operator unsigned char() const {
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1 : 0;
- case INT: return _data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_int();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1 : 0;
+ case INT:
+ return _data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_int();
default: {
-
return 0;
}
}
}
Variant::operator CharType() const {
-
return operator unsigned int();
}
Variant::operator float() const {
-
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1.0 : 0.0;
- case INT: return (float)_data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_double();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1.0 : 0.0;
+ case INT:
+ return (float)_data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_double();
default: {
-
return 0;
}
}
}
-Variant::operator double() const {
+Variant::operator double() const {
switch (type) {
-
- case NIL: return 0;
- case BOOL: return _data._bool ? 1.0 : 0.0;
- case INT: return (double)_data._int;
- case FLOAT: return _data._float;
- case STRING: return operator String().to_double();
+ case NIL:
+ return 0;
+ case BOOL:
+ return _data._bool ? 1.0 : 0.0;
+ case INT:
+ return (double)_data._int;
+ case FLOAT:
+ return _data._float;
+ case STRING:
+ return operator String().to_double();
default: {
-
return 0;
}
}
}
Variant::operator StringName() const {
-
if (type == STRING_NAME) {
return *reinterpret_cast<const StringName *>(_data._mem);
} else if (type == STRING) {
@@ -1786,12 +1609,10 @@ Variant::operator StringName() const {
}
struct _VariantStrPair {
-
String key;
String value;
bool operator<(const _VariantStrPair &p) const {
-
return key < p.key;
}
};
@@ -1804,44 +1625,54 @@ Variant::operator String() const {
String Variant::stringify(List<const void *> &stack) const {
switch (type) {
-
- case NIL: return "Null";
- case BOOL: return _data._bool ? "True" : "False";
- case INT: return itos(_data._int);
- case FLOAT: return rtos(_data._float);
- case STRING: return *reinterpret_cast<const String *>(_data._mem);
- case VECTOR2: return "(" + operator Vector2() + ")";
- case VECTOR2I: return "(" + operator Vector2i() + ")";
- case RECT2: return "(" + operator Rect2() + ")";
- case RECT2I: return "(" + operator Rect2i() + ")";
+ case NIL:
+ return "Null";
+ case BOOL:
+ return _data._bool ? "True" : "False";
+ case INT:
+ return itos(_data._int);
+ case FLOAT:
+ return rtos(_data._float);
+ case STRING:
+ return *reinterpret_cast<const String *>(_data._mem);
+ case VECTOR2:
+ return "(" + operator Vector2() + ")";
+ case VECTOR2I:
+ return "(" + operator Vector2i() + ")";
+ case RECT2:
+ return "(" + operator Rect2() + ")";
+ case RECT2I:
+ return "(" + operator Rect2i() + ")";
case TRANSFORM2D: {
-
Transform2D mat32 = operator Transform2D();
return "(" + Variant(mat32.elements[0]).operator String() + ", " + Variant(mat32.elements[1]).operator String() + ", " + Variant(mat32.elements[2]).operator String() + ")";
} break;
- case VECTOR3: return "(" + operator Vector3() + ")";
- case VECTOR3I: return "(" + operator Vector3i() + ")";
+ case VECTOR3:
+ return "(" + operator Vector3() + ")";
+ case VECTOR3I:
+ return "(" + operator Vector3i() + ")";
case PLANE:
return operator Plane();
//case QUAT:
- case AABB: return operator ::AABB();
- case QUAT: return "(" + operator Quat() + ")";
+ case AABB:
+ return operator ::AABB();
+ case QUAT:
+ return "(" + operator Quat() + ")";
case BASIS: {
-
Basis mat3 = operator Basis();
String mtx("(");
for (int i = 0; i < 3; i++) {
-
- if (i != 0)
+ if (i != 0) {
mtx += ", ";
+ }
mtx += "(";
for (int j = 0; j < 3; j++) {
-
- if (j != 0)
+ if (j != 0) {
mtx += ", ";
+ }
mtx += Variant(mat3.elements[i][j]).operator String();
}
@@ -1851,12 +1682,15 @@ String Variant::stringify(List<const void *> &stack) const {
return mtx + ")";
} break;
- case TRANSFORM: return operator Transform();
- case STRING_NAME: return operator StringName();
- case NODE_PATH: return operator NodePath();
- case COLOR: return String::num(operator Color().r) + "," + String::num(operator Color().g) + "," + String::num(operator Color().b) + "," + String::num(operator Color().a);
+ case TRANSFORM:
+ return operator Transform();
+ case STRING_NAME:
+ return operator StringName();
+ case NODE_PATH:
+ return operator NodePath();
+ case COLOR:
+ return String::num(operator Color().r) + "," + String::num(operator Color().g) + "," + String::num(operator Color().b) + "," + String::num(operator Color().a);
case DICTIONARY: {
-
const Dictionary &d = *reinterpret_cast<const Dictionary *>(_data._mem);
if (stack.find(d.id())) {
return "{...}";
@@ -1872,7 +1706,6 @@ String Variant::stringify(List<const void *> &stack) const {
Vector<_VariantStrPair> pairs;
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
_VariantStrPair sp;
sp.key = E->get().stringify(stack);
sp.value = d[E->get()].stringify(stack);
@@ -1883,8 +1716,9 @@ String Variant::stringify(List<const void *> &stack) const {
pairs.sort();
for (int i = 0; i < pairs.size(); i++) {
- if (i > 0)
+ if (i > 0) {
str += ", ";
+ }
str += pairs[i].key + ":" + pairs[i].value;
}
str += "}";
@@ -1892,98 +1726,90 @@ String Variant::stringify(List<const void *> &stack) const {
return str;
} break;
case PACKED_VECTOR2_ARRAY: {
-
Vector<Vector2> vec = operator Vector<Vector2>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
str += ", ";
+ }
str = str + Variant(vec[i]);
}
str += "]";
return str;
} break;
case PACKED_VECTOR3_ARRAY: {
-
Vector<Vector3> vec = operator Vector<Vector3>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
str += ", ";
+ }
str = str + Variant(vec[i]);
}
str += "]";
return str;
} break;
case PACKED_STRING_ARRAY: {
-
Vector<String> vec = operator Vector<String>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
str += ", ";
+ }
str = str + vec[i];
}
str += "]";
return str;
} break;
case PACKED_INT32_ARRAY: {
-
Vector<int32_t> vec = operator Vector<int32_t>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
str += ", ";
+ }
str = str + itos(vec[i]);
}
str += "]";
return str;
} break;
case PACKED_INT64_ARRAY: {
-
Vector<int64_t> vec = operator Vector<int64_t>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
str += ", ";
+ }
str = str + itos(vec[i]);
}
str += "]";
return str;
} break;
case PACKED_FLOAT32_ARRAY: {
-
Vector<float> vec = operator Vector<float>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
str += ", ";
+ }
str = str + rtos(vec[i]);
}
str += "]";
return str;
} break;
case PACKED_FLOAT64_ARRAY: {
-
Vector<double> vec = operator Vector<double>();
String str("[");
for (int i = 0; i < vec.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
str += ", ";
+ }
str = str + rtos(vec[i]);
}
str += "]";
return str;
} break;
case ARRAY: {
-
Array arr = operator Array();
if (stack.find(arr.id())) {
return "[...]";
@@ -1992,8 +1818,9 @@ String Variant::stringify(List<const void *> &stack) const {
String str("[");
for (int i = 0; i < arr.size(); i++) {
- if (i)
+ if (i) {
str += ", ";
+ }
str += arr[i].stringify(stack);
}
@@ -2003,16 +1830,15 @@ String Variant::stringify(List<const void *> &stack) const {
} break;
case OBJECT: {
-
if (_get_obj().obj) {
-
if (!_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
return "[Freed Object]";
- };
+ }
return _get_obj().obj->to_string();
- } else
+ } else {
return "[Object:null]";
+ }
} break;
case CALLABLE: {
@@ -2036,131 +1862,131 @@ String Variant::stringify(List<const void *> &stack) const {
}
Variant::operator Vector2() const {
-
- if (type == VECTOR2)
+ if (type == VECTOR2) {
return *reinterpret_cast<const Vector2 *>(_data._mem);
- else if (type == VECTOR2I)
+ } else if (type == VECTOR2I) {
return *reinterpret_cast<const Vector2i *>(_data._mem);
- else if (type == VECTOR3)
+ } else if (type == VECTOR3) {
return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y);
- else if (type == VECTOR3I)
+ } else if (type == VECTOR3I) {
return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y);
- else
+ } else {
return Vector2();
+ }
}
Variant::operator Vector2i() const {
-
- if (type == VECTOR2I)
+ if (type == VECTOR2I) {
return *reinterpret_cast<const Vector2i *>(_data._mem);
- else if (type == VECTOR2)
+ } else if (type == VECTOR2) {
return *reinterpret_cast<const Vector2 *>(_data._mem);
- else if (type == VECTOR3)
+ } else if (type == VECTOR3) {
return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y);
- else if (type == VECTOR3I)
+ } else if (type == VECTOR3I) {
return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y);
- else
+ } else {
return Vector2i();
+ }
}
Variant::operator Rect2() const {
-
- if (type == RECT2)
+ if (type == RECT2) {
return *reinterpret_cast<const Rect2 *>(_data._mem);
- else if (type == RECT2I)
+ } else if (type == RECT2I) {
return *reinterpret_cast<const Rect2i *>(_data._mem);
- else
+ } else {
return Rect2();
+ }
}
Variant::operator Rect2i() const {
-
- if (type == RECT2I)
+ if (type == RECT2I) {
return *reinterpret_cast<const Rect2i *>(_data._mem);
- else if (type == RECT2)
+ } else if (type == RECT2) {
return *reinterpret_cast<const Rect2 *>(_data._mem);
- else
+ } else {
return Rect2i();
+ }
}
Variant::operator Vector3() const {
-
- if (type == VECTOR3)
+ if (type == VECTOR3) {
return *reinterpret_cast<const Vector3 *>(_data._mem);
- else if (type == VECTOR3I)
+ } else if (type == VECTOR3I) {
return *reinterpret_cast<const Vector3i *>(_data._mem);
- else if (type == VECTOR2)
+ } else if (type == VECTOR2) {
return Vector3(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0);
- else if (type == VECTOR2I)
+ } else if (type == VECTOR2I) {
return Vector3(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0);
- else
+ } else {
return Vector3();
+ }
}
Variant::operator Vector3i() const {
-
- if (type == VECTOR3I)
+ if (type == VECTOR3I) {
return *reinterpret_cast<const Vector3i *>(_data._mem);
- else if (type == VECTOR3)
+ } else if (type == VECTOR3) {
return *reinterpret_cast<const Vector3 *>(_data._mem);
- else if (type == VECTOR2)
+ } else if (type == VECTOR2) {
return Vector3i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0);
- else if (type == VECTOR2I)
+ } else if (type == VECTOR2I) {
return Vector3i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0);
- else
+ } else {
return Vector3i();
+ }
}
Variant::operator Plane() const {
-
- if (type == PLANE)
+ if (type == PLANE) {
return *reinterpret_cast<const Plane *>(_data._mem);
- else
+ } else {
return Plane();
+ }
}
-Variant::operator ::AABB() const {
- if (type == AABB)
+Variant::operator ::AABB() const {
+ if (type == AABB) {
return *_data._aabb;
- else
+ } else {
return ::AABB();
+ }
}
Variant::operator Basis() const {
-
- if (type == BASIS)
+ if (type == BASIS) {
return *_data._basis;
- else if (type == QUAT)
+ } else if (type == QUAT) {
return *reinterpret_cast<const Quat *>(_data._mem);
- else if (type == VECTOR3) {
+ } else if (type == VECTOR3) {
return Basis(*reinterpret_cast<const Vector3 *>(_data._mem));
- } else if (type == TRANSFORM) // unexposed in Variant::can_convert?
+ } else if (type == TRANSFORM) { // unexposed in Variant::can_convert?
return _data._transform->basis;
- else
+ } else {
return Basis();
+ }
}
Variant::operator Quat() const {
-
- if (type == QUAT)
+ if (type == QUAT) {
return *reinterpret_cast<const Quat *>(_data._mem);
- else if (type == BASIS)
+ } else if (type == BASIS) {
return *_data._basis;
- else if (type == TRANSFORM)
+ } else if (type == TRANSFORM) {
return _data._transform->basis;
- else
+ } else {
return Quat();
+ }
}
Variant::operator Transform() const {
-
- if (type == TRANSFORM)
+ if (type == TRANSFORM) {
return *_data._transform;
- else if (type == BASIS)
+ } else if (type == BASIS) {
return Transform(*_data._basis, Vector3());
- else if (type == QUAT)
+ } else if (type == QUAT) {
return Transform(Basis(*reinterpret_cast<const Quat *>(_data._mem)), Vector3());
- else if (type == TRANSFORM2D) {
+ } else if (type == TRANSFORM2D) {
const Transform2D &t = *_data._transform2d;
Transform m;
m.basis.elements[0][0] = t.elements[0][0];
@@ -2170,12 +1996,12 @@ Variant::operator Transform() const {
m.origin[0] = t.elements[2][0];
m.origin[1] = t.elements[2][1];
return m;
- } else
+ } else {
return Transform();
+ }
}
Variant::operator Transform2D() const {
-
if (type == TRANSFORM2D) {
return *_data._transform2d;
} else if (type == TRANSFORM) {
@@ -2188,43 +2014,43 @@ Variant::operator Transform2D() const {
m.elements[2][0] = t.origin[0];
m.elements[2][1] = t.origin[1];
return m;
- } else
+ } else {
return Transform2D();
+ }
}
Variant::operator Color() const {
-
- if (type == COLOR)
+ if (type == COLOR) {
return *reinterpret_cast<const Color *>(_data._mem);
- else if (type == STRING)
+ } else if (type == STRING) {
return Color::html(operator String());
- else if (type == INT)
+ } else if (type == INT) {
return Color::hex(operator int());
- else
+ } else {
return Color();
+ }
}
Variant::operator NodePath() const {
-
- if (type == NODE_PATH)
+ if (type == NODE_PATH) {
return *reinterpret_cast<const NodePath *>(_data._mem);
- else if (type == STRING)
+ } else if (type == STRING) {
return NodePath(operator String());
- else
+ } else {
return NodePath();
+ }
}
Variant::operator RID() const {
-
- if (type == _RID)
+ if (type == _RID) {
return *reinterpret_cast<const RID *>(_data._mem);
- else if (type == OBJECT && _get_obj().obj == nullptr) {
+ } else if (type == OBJECT && _get_obj().obj == nullptr) {
return RID();
} else if (type == OBJECT && _get_obj().obj) {
#ifdef DEBUG_ENABLED
if (EngineDebugger::is_active()) {
ERR_FAIL_COND_V_MSG(ObjectDB::get_instance(_get_obj().id) == nullptr, RID(), "Invalid pointer (object was freed).");
- };
+ }
#endif
Callable::CallError ce;
Variant ret = _get_obj().obj->call(CoreStringNames::get_singleton()->get_rid, nullptr, 0, ce);
@@ -2238,11 +2064,11 @@ Variant::operator RID() const {
}
Variant::operator Object *() const {
-
- if (type == OBJECT)
+ if (type == OBJECT) {
return _get_obj().obj;
- else
+ } else {
return nullptr;
+ }
}
Object *Variant::get_validated_object_with_check(bool &r_previously_freed) const {
@@ -2257,59 +2083,59 @@ Object *Variant::get_validated_object_with_check(bool &r_previously_freed) const
}
Object *Variant::get_validated_object() const {
- if (type == OBJECT)
+ if (type == OBJECT) {
return ObjectDB::get_instance(_get_obj().id);
- else
+ } else {
return nullptr;
+ }
}
Variant::operator Node *() const {
-
- if (type == OBJECT)
+ if (type == OBJECT) {
return Object::cast_to<Node>(_get_obj().obj);
- else
+ } else {
return nullptr;
+ }
}
-Variant::operator Control *() const {
- if (type == OBJECT)
+Variant::operator Control *() const {
+ if (type == OBJECT) {
return Object::cast_to<Control>(_get_obj().obj);
- else
+ } else {
return nullptr;
+ }
}
Variant::operator Dictionary() const {
-
- if (type == DICTIONARY)
+ if (type == DICTIONARY) {
return *reinterpret_cast<const Dictionary *>(_data._mem);
- else
+ } else {
return Dictionary();
+ }
}
Variant::operator Callable() const {
-
- if (type == CALLABLE)
+ if (type == CALLABLE) {
return *reinterpret_cast<const Callable *>(_data._mem);
- else
+ } else {
return Callable();
+ }
}
Variant::operator Signal() const {
-
- if (type == SIGNAL)
+ if (type == SIGNAL) {
return *reinterpret_cast<const Signal *>(_data._mem);
- else
+ } else {
return Signal();
+ }
}
template <class DA, class SA>
inline DA _convert_array(const SA &p_array) {
-
DA da;
da.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
-
da.set(i, Variant(p_array.get(i)));
}
@@ -2318,9 +2144,7 @@ inline DA _convert_array(const SA &p_array) {
template <class DA>
inline DA _convert_array_from_variant(const Variant &p_variant) {
-
switch (p_variant.get_type()) {
-
case Variant::ARRAY: {
return _convert_array<DA, Array>(p_variant.operator Array());
}
@@ -2358,169 +2182,172 @@ inline DA _convert_array_from_variant(const Variant &p_variant) {
}
Variant::operator Array() const {
-
- if (type == ARRAY)
+ if (type == ARRAY) {
return *reinterpret_cast<const Array *>(_data._mem);
- else
+ } else {
return _convert_array_from_variant<Array>(*this);
+ }
}
Variant::operator Vector<uint8_t>() const {
-
- if (type == PACKED_BYTE_ARRAY)
+ if (type == PACKED_BYTE_ARRAY) {
return static_cast<PackedArrayRef<uint8_t> *>(_data.packed_array)->array;
- else
+ } else {
return _convert_array_from_variant<Vector<uint8_t>>(*this);
+ }
}
-Variant::operator Vector<int32_t>() const {
- if (type == PACKED_INT32_ARRAY)
+Variant::operator Vector<int32_t>() const {
+ if (type == PACKED_INT32_ARRAY) {
return static_cast<PackedArrayRef<int32_t> *>(_data.packed_array)->array;
- else
+ } else {
return _convert_array_from_variant<Vector<int>>(*this);
+ }
}
-Variant::operator Vector<int64_t>() const {
- if (type == PACKED_INT64_ARRAY)
+Variant::operator Vector<int64_t>() const {
+ if (type == PACKED_INT64_ARRAY) {
return static_cast<PackedArrayRef<int64_t> *>(_data.packed_array)->array;
- else
+ } else {
return _convert_array_from_variant<Vector<int64_t>>(*this);
+ }
}
Variant::operator Vector<float>() const {
-
- if (type == PACKED_FLOAT32_ARRAY)
+ if (type == PACKED_FLOAT32_ARRAY) {
return static_cast<PackedArrayRef<float> *>(_data.packed_array)->array;
- else
+ } else {
return _convert_array_from_variant<Vector<float>>(*this);
+ }
}
Variant::operator Vector<double>() const {
-
- if (type == PACKED_FLOAT64_ARRAY)
+ if (type == PACKED_FLOAT64_ARRAY) {
return static_cast<PackedArrayRef<double> *>(_data.packed_array)->array;
- else
+ } else {
return _convert_array_from_variant<Vector<double>>(*this);
+ }
}
Variant::operator Vector<String>() const {
-
- if (type == PACKED_STRING_ARRAY)
+ if (type == PACKED_STRING_ARRAY) {
return static_cast<PackedArrayRef<String> *>(_data.packed_array)->array;
- else
+ } else {
return _convert_array_from_variant<Vector<String>>(*this);
+ }
}
-Variant::operator Vector<Vector3>() const {
- if (type == PACKED_VECTOR3_ARRAY)
+Variant::operator Vector<Vector3>() const {
+ if (type == PACKED_VECTOR3_ARRAY) {
return static_cast<PackedArrayRef<Vector3> *>(_data.packed_array)->array;
- else
+ } else {
return _convert_array_from_variant<Vector<Vector3>>(*this);
+ }
}
-Variant::operator Vector<Vector2>() const {
- if (type == PACKED_VECTOR2_ARRAY)
+Variant::operator Vector<Vector2>() const {
+ if (type == PACKED_VECTOR2_ARRAY) {
return static_cast<PackedArrayRef<Vector2> *>(_data.packed_array)->array;
- else
+ } else {
return _convert_array_from_variant<Vector<Vector2>>(*this);
+ }
}
Variant::operator Vector<Color>() const {
-
- if (type == PACKED_COLOR_ARRAY)
+ if (type == PACKED_COLOR_ARRAY) {
return static_cast<PackedArrayRef<Color> *>(_data.packed_array)->array;
- else
+ } else {
return _convert_array_from_variant<Vector<Color>>(*this);
+ }
}
/* helpers */
Variant::operator Vector<RID>() const {
-
Array va = operator Array();
Vector<RID> rids;
rids.resize(va.size());
- for (int i = 0; i < rids.size(); i++)
+ for (int i = 0; i < rids.size(); i++) {
rids.write[i] = va[i];
+ }
return rids;
}
Variant::operator Vector<Plane>() const {
-
Array va = operator Array();
Vector<Plane> planes;
int va_size = va.size();
- if (va_size == 0)
+ if (va_size == 0) {
return planes;
+ }
planes.resize(va_size);
Plane *w = planes.ptrw();
- for (int i = 0; i < va_size; i++)
+ for (int i = 0; i < va_size; i++) {
w[i] = va[i];
+ }
return planes;
}
Variant::operator Vector<Face3>() const {
-
Vector<Vector3> va = operator Vector<Vector3>();
Vector<Face3> faces;
int va_size = va.size();
- if (va_size == 0)
+ if (va_size == 0) {
return faces;
+ }
faces.resize(va_size / 3);
Face3 *w = faces.ptrw();
const Vector3 *r = va.ptr();
- for (int i = 0; i < va_size; i++)
+ for (int i = 0; i < va_size; i++) {
w[i / 3].vertex[i % 3] = r[i];
+ }
return faces;
}
Variant::operator Vector<Variant>() const {
-
Array va = operator Array();
Vector<Variant> variants;
int va_size = va.size();
- if (va_size == 0)
+ if (va_size == 0) {
return variants;
+ }
variants.resize(va_size);
Variant *w = variants.ptrw();
- for (int i = 0; i < va_size; i++)
+ for (int i = 0; i < va_size; i++) {
w[i] = va[i];
+ }
return variants;
}
-Variant::operator Vector<StringName>() const {
+Variant::operator Vector<StringName>() const {
Vector<String> from = operator Vector<String>();
Vector<StringName> to;
int len = from.size();
to.resize(len);
for (int i = 0; i < len; i++) {
-
to.write[i] = from[i];
}
return to;
}
Variant::operator Margin() const {
-
return (Margin) operator int();
}
-Variant::operator Orientation() const {
+Variant::operator Orientation() const {
return (Orientation) operator int();
}
Variant::operator IP_Address() const {
-
if (type == PACKED_FLOAT32_ARRAY || type == PACKED_INT32_ARRAY || type == PACKED_FLOAT64_ARRAY || type == PACKED_INT64_ARRAY || type == PACKED_BYTE_ARRAY) {
-
Vector<int> addr = operator Vector<int>();
if (addr.size() == 4) {
return IP_Address(addr.get(0), addr.get(1), addr.get(2), addr.get(3));
@@ -2531,26 +2358,16 @@ Variant::operator IP_Address() const {
}
Variant::Variant(bool p_bool) {
-
type = BOOL;
_data._bool = p_bool;
}
-/*
-Variant::Variant(long unsigned int p_long) {
-
- type=INT;
- _data._int=p_long;
-};
-*/
-
Variant::Variant(signed int p_int) {
-
type = INT;
_data._int = p_int;
}
-Variant::Variant(unsigned int p_int) {
+Variant::Variant(unsigned int p_int) {
type = INT;
_data._int = p_int;
}
@@ -2558,56 +2375,52 @@ Variant::Variant(unsigned int p_int) {
#ifdef NEED_LONG_INT
Variant::Variant(signed long p_int) {
-
type = INT;
_data._int = p_int;
}
-Variant::Variant(unsigned long p_int) {
+Variant::Variant(unsigned long p_int) {
type = INT;
_data._int = p_int;
}
#endif
Variant::Variant(int64_t p_int) {
-
type = INT;
_data._int = p_int;
}
Variant::Variant(uint64_t p_int) {
-
type = INT;
_data._int = p_int;
}
Variant::Variant(signed short p_short) {
-
type = INT;
_data._int = p_short;
}
-Variant::Variant(unsigned short p_short) {
+Variant::Variant(unsigned short p_short) {
type = INT;
_data._int = p_short;
}
-Variant::Variant(signed char p_char) {
+Variant::Variant(signed char p_char) {
type = INT;
_data._int = p_char;
}
-Variant::Variant(unsigned char p_char) {
+Variant::Variant(unsigned char p_char) {
type = INT;
_data._int = p_char;
}
-Variant::Variant(float p_float) {
+Variant::Variant(float p_float) {
type = FLOAT;
_data._float = p_float;
}
-Variant::Variant(double p_double) {
+Variant::Variant(double p_double) {
type = FLOAT;
_data._float = p_double;
}
@@ -2618,121 +2431,106 @@ Variant::Variant(const ObjectID &p_id) {
}
Variant::Variant(const StringName &p_string) {
-
type = STRING_NAME;
memnew_placement(_data._mem, StringName(p_string));
}
-Variant::Variant(const String &p_string) {
+Variant::Variant(const String &p_string) {
type = STRING;
memnew_placement(_data._mem, String(p_string));
}
Variant::Variant(const char *const p_cstring) {
-
type = STRING;
memnew_placement(_data._mem, String((const char *)p_cstring));
}
Variant::Variant(const CharType *p_wstring) {
-
type = STRING;
memnew_placement(_data._mem, String(p_wstring));
}
-Variant::Variant(const Vector3 &p_vector3) {
+Variant::Variant(const Vector3 &p_vector3) {
type = VECTOR3;
memnew_placement(_data._mem, Vector3(p_vector3));
}
-Variant::Variant(const Vector3i &p_vector3i) {
+Variant::Variant(const Vector3i &p_vector3i) {
type = VECTOR3I;
memnew_placement(_data._mem, Vector3i(p_vector3i));
}
Variant::Variant(const Vector2 &p_vector2) {
-
type = VECTOR2;
memnew_placement(_data._mem, Vector2(p_vector2));
}
Variant::Variant(const Vector2i &p_vector2i) {
-
type = VECTOR2I;
memnew_placement(_data._mem, Vector2i(p_vector2i));
}
Variant::Variant(const Rect2 &p_rect2) {
-
type = RECT2;
memnew_placement(_data._mem, Rect2(p_rect2));
}
Variant::Variant(const Rect2i &p_rect2i) {
-
type = RECT2I;
memnew_placement(_data._mem, Rect2i(p_rect2i));
}
Variant::Variant(const Plane &p_plane) {
-
type = PLANE;
memnew_placement(_data._mem, Plane(p_plane));
}
-Variant::Variant(const ::AABB &p_aabb) {
+Variant::Variant(const ::AABB &p_aabb) {
type = AABB;
_data._aabb = memnew(::AABB(p_aabb));
}
Variant::Variant(const Basis &p_matrix) {
-
type = BASIS;
_data._basis = memnew(Basis(p_matrix));
}
Variant::Variant(const Quat &p_quat) {
-
type = QUAT;
memnew_placement(_data._mem, Quat(p_quat));
}
-Variant::Variant(const Transform &p_transform) {
+Variant::Variant(const Transform &p_transform) {
type = TRANSFORM;
_data._transform = memnew(Transform(p_transform));
}
Variant::Variant(const Transform2D &p_transform) {
-
type = TRANSFORM2D;
_data._transform2d = memnew(Transform2D(p_transform));
}
-Variant::Variant(const Color &p_color) {
+Variant::Variant(const Color &p_color) {
type = COLOR;
memnew_placement(_data._mem, Color(p_color));
}
Variant::Variant(const NodePath &p_node_path) {
-
type = NODE_PATH;
memnew_placement(_data._mem, NodePath(p_node_path));
}
Variant::Variant(const RID &p_rid) {
-
type = _RID;
memnew_placement(_data._mem, RID(p_rid));
}
Variant::Variant(const Object *p_object) {
-
type = OBJECT;
memnew_placement(_data._mem, ObjData);
if (p_object) {
-
if (p_object->is_reference()) {
Reference *reference = const_cast<Reference *>(static_cast<const Reference *>(p_object));
if (!reference->init_ref()) {
@@ -2751,30 +2549,26 @@ Variant::Variant(const Object *p_object) {
}
Variant::Variant(const Callable &p_callable) {
-
type = CALLABLE;
memnew_placement(_data._mem, Callable(p_callable));
}
-Variant::Variant(const Signal &p_callable) {
+Variant::Variant(const Signal &p_callable) {
type = SIGNAL;
memnew_placement(_data._mem, Signal(p_callable));
}
Variant::Variant(const Dictionary &p_dictionary) {
-
type = DICTIONARY;
memnew_placement(_data._mem, Dictionary(p_dictionary));
}
Variant::Variant(const Array &p_array) {
-
type = ARRAY;
memnew_placement(_data._mem, Array(p_array));
}
Variant::Variant(const Vector<Plane> &p_array) {
-
type = ARRAY;
Array *plane_array = memnew_placement(_data._mem, Array);
@@ -2782,13 +2576,11 @@ Variant::Variant(const Vector<Plane> &p_array) {
plane_array->resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
-
plane_array->operator[](i) = Variant(p_array[i]);
}
}
Variant::Variant(const Vector<RID> &p_array) {
-
type = ARRAY;
Array *rid_array = memnew_placement(_data._mem, Array);
@@ -2796,65 +2588,57 @@ Variant::Variant(const Vector<RID> &p_array) {
rid_array->resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
-
rid_array->set(i, Variant(p_array[i]));
}
}
Variant::Variant(const Vector<uint8_t> &p_byte_array) {
-
type = PACKED_BYTE_ARRAY;
_data.packed_array = PackedArrayRef<uint8_t>::create(p_byte_array);
}
-Variant::Variant(const Vector<int32_t> &p_int32_array) {
+Variant::Variant(const Vector<int32_t> &p_int32_array) {
type = PACKED_INT32_ARRAY;
_data.packed_array = PackedArrayRef<int32_t>::create(p_int32_array);
}
Variant::Variant(const Vector<int64_t> &p_int64_array) {
-
type = PACKED_INT64_ARRAY;
_data.packed_array = PackedArrayRef<int64_t>::create(p_int64_array);
}
Variant::Variant(const Vector<float> &p_float32_array) {
-
type = PACKED_FLOAT32_ARRAY;
_data.packed_array = PackedArrayRef<float>::create(p_float32_array);
}
Variant::Variant(const Vector<double> &p_float64_array) {
-
type = PACKED_FLOAT64_ARRAY;
_data.packed_array = PackedArrayRef<double>::create(p_float64_array);
}
Variant::Variant(const Vector<String> &p_string_array) {
-
type = PACKED_STRING_ARRAY;
_data.packed_array = PackedArrayRef<String>::create(p_string_array);
}
-Variant::Variant(const Vector<Vector3> &p_vector3_array) {
+Variant::Variant(const Vector<Vector3> &p_vector3_array) {
type = PACKED_VECTOR3_ARRAY;
_data.packed_array = PackedArrayRef<Vector3>::create(p_vector3_array);
}
Variant::Variant(const Vector<Vector2> &p_vector2_array) {
-
type = PACKED_VECTOR2_ARRAY;
_data.packed_array = PackedArrayRef<Vector2>::create(p_vector2_array);
}
-Variant::Variant(const Vector<Color> &p_color_array) {
+Variant::Variant(const Vector<Color> &p_color_array) {
type = PACKED_COLOR_ARRAY;
_data.packed_array = PackedArrayRef<Color>::create(p_color_array);
}
Variant::Variant(const Vector<Face3> &p_face_array) {
-
Vector<Vector3> vertices;
int face_count = p_face_array.size();
vertices.resize(face_count * 3);
@@ -2864,9 +2648,9 @@ Variant::Variant(const Vector<Face3> &p_face_array) {
Vector3 *w = vertices.ptrw();
for (int i = 0; i < face_count; i++) {
-
- for (int j = 0; j < 3; j++)
+ for (int j = 0; j < 3; j++) {
w[i * 3 + j] = r[i].vertex[j];
+ }
}
}
@@ -2887,20 +2671,20 @@ Variant::Variant(const Vector<Variant> &p_array) {
}
Variant::Variant(const Vector<StringName> &p_array) {
-
type = NIL;
Vector<String> v;
int len = p_array.size();
v.resize(len);
- for (int i = 0; i < len; i++)
+ for (int i = 0; i < len; i++) {
v.set(i, p_array[i]);
+ }
*this = v;
}
void Variant::operator=(const Variant &p_variant) {
-
- if (unlikely(this == &p_variant))
+ if (unlikely(this == &p_variant)) {
return;
+ }
if (unlikely(type != p_variant.type)) {
reference(p_variant);
@@ -2909,90 +2693,70 @@ void Variant::operator=(const Variant &p_variant) {
switch (p_variant.type) {
case NIL: {
-
// none
} break;
// atomic types
case BOOL: {
-
_data._bool = p_variant._data._bool;
} break;
case INT: {
-
_data._int = p_variant._data._int;
} break;
case FLOAT: {
-
_data._float = p_variant._data._float;
} break;
case STRING: {
-
*reinterpret_cast<String *>(_data._mem) = *reinterpret_cast<const String *>(p_variant._data._mem);
} break;
// math types
case VECTOR2: {
-
*reinterpret_cast<Vector2 *>(_data._mem) = *reinterpret_cast<const Vector2 *>(p_variant._data._mem);
} break;
case VECTOR2I: {
-
*reinterpret_cast<Vector2i *>(_data._mem) = *reinterpret_cast<const Vector2i *>(p_variant._data._mem);
} break;
case RECT2: {
-
*reinterpret_cast<Rect2 *>(_data._mem) = *reinterpret_cast<const Rect2 *>(p_variant._data._mem);
} break;
case RECT2I: {
-
*reinterpret_cast<Rect2i *>(_data._mem) = *reinterpret_cast<const Rect2i *>(p_variant._data._mem);
} break;
case TRANSFORM2D: {
-
*_data._transform2d = *(p_variant._data._transform2d);
} break;
case VECTOR3: {
-
*reinterpret_cast<Vector3 *>(_data._mem) = *reinterpret_cast<const Vector3 *>(p_variant._data._mem);
} break;
case VECTOR3I: {
-
*reinterpret_cast<Vector3i *>(_data._mem) = *reinterpret_cast<const Vector3i *>(p_variant._data._mem);
} break;
case PLANE: {
-
*reinterpret_cast<Plane *>(_data._mem) = *reinterpret_cast<const Plane *>(p_variant._data._mem);
} break;
case AABB: {
-
*_data._aabb = *(p_variant._data._aabb);
} break;
case QUAT: {
-
*reinterpret_cast<Quat *>(_data._mem) = *reinterpret_cast<const Quat *>(p_variant._data._mem);
} break;
case BASIS: {
-
*_data._basis = *(p_variant._data._basis);
} break;
case TRANSFORM: {
-
*_data._transform = *(p_variant._data._transform);
} break;
// misc types
case COLOR: {
-
*reinterpret_cast<Color *>(_data._mem) = *reinterpret_cast<const Color *>(p_variant._data._mem);
} break;
case _RID: {
-
*reinterpret_cast<RID *>(_data._mem) = *reinterpret_cast<const RID *>(p_variant._data._mem);
} break;
case OBJECT: {
-
if (_get_obj().id.is_reference()) {
//we are safe that there is a reference here
Reference *reference = static_cast<Reference *>(_get_obj().obj);
@@ -3015,66 +2779,51 @@ void Variant::operator=(const Variant &p_variant) {
} break;
case CALLABLE: {
-
*reinterpret_cast<Callable *>(_data._mem) = *reinterpret_cast<const Callable *>(p_variant._data._mem);
} break;
case SIGNAL: {
-
*reinterpret_cast<Signal *>(_data._mem) = *reinterpret_cast<const Signal *>(p_variant._data._mem);
} break;
case STRING_NAME: {
-
*reinterpret_cast<StringName *>(_data._mem) = *reinterpret_cast<const StringName *>(p_variant._data._mem);
} break;
case NODE_PATH: {
-
*reinterpret_cast<NodePath *>(_data._mem) = *reinterpret_cast<const NodePath *>(p_variant._data._mem);
} break;
case DICTIONARY: {
-
*reinterpret_cast<Dictionary *>(_data._mem) = *reinterpret_cast<const Dictionary *>(p_variant._data._mem);
} break;
case ARRAY: {
-
*reinterpret_cast<Array *>(_data._mem) = *reinterpret_cast<const Array *>(p_variant._data._mem);
} break;
// arrays
case PACKED_BYTE_ARRAY: {
-
_data.packed_array = PackedArrayRef<uint8_t>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
case PACKED_INT32_ARRAY: {
-
_data.packed_array = PackedArrayRef<int32_t>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
case PACKED_INT64_ARRAY: {
-
_data.packed_array = PackedArrayRef<int64_t>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
case PACKED_FLOAT32_ARRAY: {
-
_data.packed_array = PackedArrayRef<float>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
case PACKED_FLOAT64_ARRAY: {
-
_data.packed_array = PackedArrayRef<double>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
case PACKED_STRING_ARRAY: {
-
_data.packed_array = PackedArrayRef<String>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
case PACKED_VECTOR2_ARRAY: {
-
_data.packed_array = PackedArrayRef<Vector2>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
case PACKED_VECTOR3_ARRAY: {
-
_data.packed_array = PackedArrayRef<Vector3>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
case PACKED_COLOR_ARRAY: {
-
_data.packed_array = PackedArrayRef<Color>::reference_from(_data.packed_array, p_variant._data.packed_array);
} break;
default: {
@@ -3083,77 +2832,56 @@ void Variant::operator=(const Variant &p_variant) {
}
Variant::Variant(const IP_Address &p_address) {
-
type = STRING;
memnew_placement(_data._mem, String(p_address));
}
Variant::Variant(const Variant &p_variant) {
-
- type = NIL;
reference(p_variant);
}
-/*
-Variant::~Variant() {
-
- clear();
-}*/
-
uint32_t Variant::hash() const {
-
switch (type) {
case NIL: {
-
return 0;
} break;
case BOOL: {
-
return _data._bool ? 1 : 0;
} break;
case INT: {
-
return _data._int;
} break;
case FLOAT: {
-
return hash_djb2_one_float(_data._float);
} break;
case STRING: {
-
return reinterpret_cast<const String *>(_data._mem)->hash();
} break;
// math types
case VECTOR2: {
-
uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Vector2 *>(_data._mem)->x);
return hash_djb2_one_float(reinterpret_cast<const Vector2 *>(_data._mem)->y, hash);
} break;
case VECTOR2I: {
-
uint32_t hash = hash_djb2_one_32(reinterpret_cast<const Vector2i *>(_data._mem)->x);
return hash_djb2_one_32(reinterpret_cast<const Vector2i *>(_data._mem)->y, hash);
} break;
case RECT2: {
-
uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->position.x);
hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->position.y, hash);
hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.x, hash);
return hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.y, hash);
} break;
case RECT2I: {
-
uint32_t hash = hash_djb2_one_32(reinterpret_cast<const Rect2i *>(_data._mem)->position.x);
hash = hash_djb2_one_32(reinterpret_cast<const Rect2i *>(_data._mem)->position.y, hash);
hash = hash_djb2_one_32(reinterpret_cast<const Rect2i *>(_data._mem)->size.x, hash);
return hash_djb2_one_32(reinterpret_cast<const Rect2i *>(_data._mem)->size.y, hash);
} break;
case TRANSFORM2D: {
-
uint32_t hash = 5831;
for (int i = 0; i < 3; i++) {
-
for (int j = 0; j < 2; j++) {
hash = hash_djb2_one_float(_data._transform2d->elements[i][j], hash);
}
@@ -3162,35 +2890,25 @@ uint32_t Variant::hash() const {
return hash;
} break;
case VECTOR3: {
-
uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Vector3 *>(_data._mem)->x);
hash = hash_djb2_one_float(reinterpret_cast<const Vector3 *>(_data._mem)->y, hash);
return hash_djb2_one_float(reinterpret_cast<const Vector3 *>(_data._mem)->z, hash);
} break;
case VECTOR3I: {
-
uint32_t hash = hash_djb2_one_32(reinterpret_cast<const Vector3i *>(_data._mem)->x);
hash = hash_djb2_one_32(reinterpret_cast<const Vector3i *>(_data._mem)->y, hash);
return hash_djb2_one_32(reinterpret_cast<const Vector3i *>(_data._mem)->z, hash);
} break;
case PLANE: {
-
uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->normal.x);
hash = hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->normal.y, hash);
hash = hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->normal.z, hash);
return hash_djb2_one_float(reinterpret_cast<const Plane *>(_data._mem)->d, hash);
} break;
- /*
- case QUAT: {
-
-
- } break;*/
case AABB: {
-
uint32_t hash = 5831;
for (int i = 0; i < 3; i++) {
-
hash = hash_djb2_one_float(_data._aabb->position[i], hash);
hash = hash_djb2_one_float(_data._aabb->size[i], hash);
}
@@ -3199,7 +2917,6 @@ uint32_t Variant::hash() const {
} break;
case QUAT: {
-
uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Quat *>(_data._mem)->x);
hash = hash_djb2_one_float(reinterpret_cast<const Quat *>(_data._mem)->y, hash);
hash = hash_djb2_one_float(reinterpret_cast<const Quat *>(_data._mem)->z, hash);
@@ -3207,10 +2924,8 @@ uint32_t Variant::hash() const {
} break;
case BASIS: {
-
uint32_t hash = 5831;
for (int i = 0; i < 3; i++) {
-
for (int j = 0; j < 3; j++) {
hash = hash_djb2_one_float(_data._basis->elements[i][j], hash);
}
@@ -3220,10 +2935,8 @@ uint32_t Variant::hash() const {
} break;
case TRANSFORM: {
-
uint32_t hash = 5831;
for (int i = 0; i < 3; i++) {
-
for (int j = 0; j < 3; j++) {
hash = hash_djb2_one_float(_data._transform->basis.elements[i][j], hash);
}
@@ -3236,7 +2949,6 @@ uint32_t Variant::hash() const {
// misc types
case COLOR: {
-
uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->r);
hash = hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->g, hash);
hash = hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->b, hash);
@@ -3244,45 +2956,36 @@ uint32_t Variant::hash() const {
} break;
case _RID: {
-
return hash_djb2_one_64(reinterpret_cast<const RID *>(_data._mem)->get_id());
} break;
case OBJECT: {
-
return hash_djb2_one_64(make_uint64_t(_get_obj().obj));
} break;
case STRING_NAME: {
-
return reinterpret_cast<const StringName *>(_data._mem)->hash();
} break;
case NODE_PATH: {
-
return reinterpret_cast<const NodePath *>(_data._mem)->hash();
} break;
case DICTIONARY: {
-
return reinterpret_cast<const Dictionary *>(_data._mem)->hash();
} break;
case CALLABLE: {
-
return reinterpret_cast<const Callable *>(_data._mem)->hash();
} break;
case SIGNAL: {
-
const Signal &s = *reinterpret_cast<const Signal *>(_data._mem);
uint32_t hash = s.get_name().hash();
return hash_djb2_one_64(s.get_object_id(), hash);
} break;
case ARRAY: {
-
const Array &arr = *reinterpret_cast<const Array *>(_data._mem);
return arr.hash();
} break;
case PACKED_BYTE_ARRAY: {
-
const Vector<uint8_t> &arr = PackedArrayRef<uint8_t>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3294,7 +2997,6 @@ uint32_t Variant::hash() const {
} break;
case PACKED_INT32_ARRAY: {
-
const Vector<int32_t> &arr = PackedArrayRef<int32_t>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3306,7 +3008,6 @@ uint32_t Variant::hash() const {
} break;
case PACKED_INT64_ARRAY: {
-
const Vector<int64_t> &arr = PackedArrayRef<int64_t>::get_array(_data.packed_array);
int len = arr.size();
if (likely(len)) {
@@ -3318,7 +3019,6 @@ uint32_t Variant::hash() const {
} break;
case PACKED_FLOAT32_ARRAY: {
-
const Vector<float> &arr = PackedArrayRef<float>::get_array(_data.packed_array);
int len = arr.size();
@@ -3331,7 +3031,6 @@ uint32_t Variant::hash() const {
} break;
case PACKED_FLOAT64_ARRAY: {
-
const Vector<double> &arr = PackedArrayRef<double>::get_array(_data.packed_array);
int len = arr.size();
@@ -3344,7 +3043,6 @@ uint32_t Variant::hash() const {
} break;
case PACKED_STRING_ARRAY: {
-
uint32_t hash = 5831;
const Vector<String> &arr = PackedArrayRef<String>::get_array(_data.packed_array);
int len = arr.size();
@@ -3360,7 +3058,6 @@ uint32_t Variant::hash() const {
return hash;
} break;
case PACKED_VECTOR2_ARRAY: {
-
uint32_t hash = 5831;
const Vector<Vector2> &arr = PackedArrayRef<Vector2>::get_array(_data.packed_array);
int len = arr.size();
@@ -3377,7 +3074,6 @@ uint32_t Variant::hash() const {
return hash;
} break;
case PACKED_VECTOR3_ARRAY: {
-
uint32_t hash = 5831;
const Vector<Vector3> &arr = PackedArrayRef<Vector3>::get_array(_data.packed_array);
int len = arr.size();
@@ -3395,7 +3091,6 @@ uint32_t Variant::hash() const {
return hash;
} break;
case PACKED_COLOR_ARRAY: {
-
uint32_t hash = 5831;
const Vector<Color> &arr = PackedArrayRef<Color>::get_array(_data.packed_array);
int len = arr.size();
@@ -3462,8 +3157,9 @@ uint32_t Variant::hash() const {
return true
bool Variant::hash_compare(const Variant &p_variant) const {
- if (type != p_variant.type)
+ if (type != p_variant.type) {
return false;
+ }
switch (type) {
case FLOAT: {
@@ -3501,8 +3197,9 @@ bool Variant::hash_compare(const Variant &p_variant) const {
Transform2D *r = p_variant._data._transform2d;
for (int i = 0; i < 3; i++) {
- if (!(hash_compare_vector2(l->elements[i], r->elements[i])))
+ if (!(hash_compare_vector2(l->elements[i], r->elements[i]))) {
return false;
+ }
}
return true;
@@ -3550,8 +3247,9 @@ bool Variant::hash_compare(const Variant &p_variant) const {
const Basis *r = p_variant._data._basis;
for (int i = 0; i < 3; i++) {
- if (!(hash_compare_vector3(l->elements[i], r->elements[i])))
+ if (!(hash_compare_vector3(l->elements[i], r->elements[i]))) {
return false;
+ }
}
return true;
@@ -3562,8 +3260,9 @@ bool Variant::hash_compare(const Variant &p_variant) const {
const Transform *r = p_variant._data._transform;
for (int i = 0; i < 3; i++) {
- if (!(hash_compare_vector3(l->basis.elements[i], r->basis.elements[i])))
+ if (!(hash_compare_vector3(l->basis.elements[i], r->basis.elements[i]))) {
return false;
+ }
}
return hash_compare_vector3(l->origin, r->origin);
@@ -3580,12 +3279,14 @@ bool Variant::hash_compare(const Variant &p_variant) const {
const Array &l = *(reinterpret_cast<const Array *>(_data._mem));
const Array &r = *(reinterpret_cast<const Array *>(p_variant._data._mem));
- if (l.size() != r.size())
+ if (l.size() != r.size()) {
return false;
+ }
for (int i = 0; i < l.size(); ++i) {
- if (!l[i].hash_compare(r[i]))
+ if (!l[i].hash_compare(r[i])) {
return false;
+ }
}
return true;
@@ -3623,38 +3324,35 @@ bool Variant::hash_compare(const Variant &p_variant) const {
}
bool Variant::is_ref() const {
-
return type == OBJECT && _get_obj().id.is_reference();
}
Vector<Variant> varray() {
-
return Vector<Variant>();
}
Vector<Variant> varray(const Variant &p_arg1) {
-
Vector<Variant> v;
v.push_back(p_arg1);
return v;
}
-Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2) {
+Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2) {
Vector<Variant> v;
v.push_back(p_arg1);
v.push_back(p_arg2);
return v;
}
-Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3) {
+Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3) {
Vector<Variant> v;
v.push_back(p_arg1);
v.push_back(p_arg2);
v.push_back(p_arg3);
return v;
}
-Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4) {
+Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4) {
Vector<Variant> v;
v.push_back(p_arg1);
v.push_back(p_arg2);
@@ -3664,7 +3362,6 @@ Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Varia
}
Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5) {
-
Vector<Variant> v;
v.push_back(p_arg1);
v.push_back(p_arg2);
@@ -3678,12 +3375,13 @@ void Variant::static_assign(const Variant &p_variant) {
}
bool Variant::is_shared() const {
-
switch (type) {
-
- case OBJECT: return true;
- case ARRAY: return true;
- case DICTIONARY: return true;
+ case OBJECT:
+ return true;
+ case ARRAY:
+ return true;
+ case DICTIONARY:
+ return true;
default: {
}
}
@@ -3695,8 +3393,9 @@ Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) {
VARIANT_ARGPTRS;
int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
argc++;
}
@@ -3705,20 +3404,16 @@ Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) {
Variant ret = call(p_method, argptr, argc, error);
switch (error.error) {
-
case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
-
String err = "Invalid type for argument #" + itos(error.argument) + ", expected '" + Variant::get_type_name(Variant::Type(error.expected)) + "'.";
ERR_PRINT(err.utf8().get_data());
} break;
case Callable::CallError::CALL_ERROR_INVALID_METHOD: {
-
String err = "Invalid method '" + p_method + "' for type '" + Variant::get_type_name(type) + "'.";
ERR_PRINT(err.utf8().get_data());
} break;
case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
-
String err = "Too many arguments for method '" + p_method + "'";
ERR_PRINT(err.utf8().get_data());
} break;
@@ -3730,12 +3425,10 @@ Variant Variant::call(const StringName &p_method, VARIANT_ARG_DECLARE) {
}
void Variant::construct_from_string(const String &p_string, Variant &r_value, ObjectConstruct p_obj_construct, void *p_construct_ud) {
-
r_value = Variant();
}
String Variant::get_construct_string() const {
-
String vars;
VariantWriter::write_to_string(*this, vars);
@@ -3743,7 +3436,6 @@ String Variant::get_construct_string() const {
}
String Variant::get_call_error_text(Object *p_base, const StringName &p_method, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) {
-
String err_text;
if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
@@ -3768,14 +3460,12 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method,
String class_name = p_base->get_class();
Ref<Script> script = p_base->get_script();
if (script.is_valid() && script->get_path().is_resource_file()) {
-
class_name += "(" + script->get_path().get_file() + ")";
}
return "'" + class_name + "::" + String(p_method) + "': " + err_text;
}
String Variant::get_callable_error_text(const Callable &p_callable, const Variant **p_argptrs, int p_argcount, const Callable::CallError &ce) {
-
String err_text;
if (ce.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
@@ -3801,26 +3491,20 @@ String Variant::get_callable_error_text(const Callable &p_callable, const Varian
}
String vformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) {
-
Array args;
if (p1.get_type() != Variant::NIL) {
-
args.push_back(p1);
if (p2.get_type() != Variant::NIL) {
-
args.push_back(p2);
if (p3.get_type() != Variant::NIL) {
-
args.push_back(p3);
if (p4.get_type() != Variant::NIL) {
-
args.push_back(p4);
if (p5.get_type() != Variant::NIL) {
-
args.push_back(p5);
}
}
diff --git a/core/variant.h b/core/variant.h
index a832f7ccf8..50b7a21eda 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -67,13 +67,6 @@ typedef Vector<Vector2> PackedVector2Array;
typedef Vector<Vector3> PackedVector3Array;
typedef Vector<Color> PackedColorArray;
-// Temporary workaround until c++11 alignas()
-#ifdef __GNUC__
-#define GCC_ALIGNED_8 __attribute__((aligned(8)))
-#else
-#define GCC_ALIGNED_8
-#endif
-
class Variant {
public:
// If this changes the table in variant_op must be updated
@@ -130,10 +123,9 @@ private:
// Variant takes 20 bytes when real_t is float, and 36 if double
// it only allocates extra memory for aabb/matrix.
- Type type;
+ Type type = NIL;
struct ObjData {
-
ObjectID id;
Object *obj;
};
@@ -211,7 +203,7 @@ private:
PackedArrayRefBase *packed_array;
void *_ptr; //generic pointer
uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)];
- } _data GCC_ALIGNED_8;
+ } _data alignas(8);
void reference(const Variant &p_variant);
void clear();
@@ -227,10 +219,10 @@ public:
bool is_ref() const;
_FORCE_INLINE_ bool is_num() const {
return type == INT || type == FLOAT;
- };
+ }
_FORCE_INLINE_ bool is_array() const {
return type >= ARRAY;
- };
+ }
bool is_shared() const;
bool is_zero() const;
bool is_one() const;
@@ -410,7 +402,6 @@ public:
static String get_operator_name(Operator p_op);
static void evaluate(const Operator &p_op, const Variant &p_a, const Variant &p_b, Variant &r_ret, bool &r_valid);
static _FORCE_INLINE_ Variant evaluate(const Operator &p_op, const Variant &p_a, const Variant &p_b) {
-
bool valid = true;
Variant res;
evaluate(p_op, p_a, p_b, res, valid);
@@ -476,12 +467,13 @@ public:
static void construct_from_string(const String &p_string, Variant &r_value, ObjectConstruct p_obj_construct = nullptr, void *p_construct_ud = nullptr);
void operator=(const Variant &p_variant); // only this is enough for all the other types
+
Variant(const Variant &p_variant);
- _FORCE_INLINE_ Variant() {
- type = NIL;
- }
+ _FORCE_INLINE_ Variant() {}
_FORCE_INLINE_ ~Variant() {
- if (type != Variant::NIL) clear();
+ if (type != Variant::NIL) {
+ clear();
+ }
}
};
@@ -496,22 +488,18 @@ Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Varia
Vector<Variant> varray(const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5);
struct VariantHasher {
-
static _FORCE_INLINE_ uint32_t hash(const Variant &p_variant) { return p_variant.hash(); }
};
struct VariantComparator {
-
static _FORCE_INLINE_ bool compare(const Variant &p_lhs, const Variant &p_rhs) { return p_lhs.hash_compare(p_rhs); }
};
Variant::ObjData &Variant::_get_obj() {
-
return *reinterpret_cast<ObjData *>(&_data._mem[0]);
}
const Variant::ObjData &Variant::_get_obj() const {
-
return *reinterpret_cast<const ObjData *>(&_data._mem[0]);
}
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 391c293810..404468a7b4 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -42,14 +42,11 @@ typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_a
typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args);
struct _VariantCall {
-
static void Vector3_dot(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
r_ret = reinterpret_cast<Vector3 *>(p_self._data._mem)->dot(*reinterpret_cast<const Vector3 *>(p_args[0]->_data._mem));
}
struct FuncData {
-
int arg_count;
Vector<Variant> default_args;
Vector<Variant::Type> arg_types;
@@ -62,16 +59,16 @@ struct _VariantCall {
VariantFunc func;
_FORCE_INLINE_ bool verify_arguments(const Variant **p_args, Callable::CallError &r_error) {
-
- if (arg_count == 0)
+ if (arg_count == 0) {
return true;
+ }
const Variant::Type *tptr = &arg_types[0];
for (int i = 0; i < arg_count; i++) {
-
- if (tptr[i] == Variant::NIL || tptr[i] == p_args[i]->type)
+ if (tptr[i] == Variant::NIL || tptr[i] == p_args[i]->type) {
continue; // all good
+ }
if (!Variant::can_convert(p_args[i]->type, tptr[i])) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = i;
@@ -102,21 +99,25 @@ struct _VariantCall {
#endif
ERR_FAIL_COND(p_argcount > VARIANT_ARG_MAX);
const Variant *newargs[VARIANT_ARG_MAX];
- for (int i = 0; i < p_argcount; i++)
+ for (int i = 0; i < p_argcount; i++) {
newargs[i] = p_args[i];
+ }
// fill in any remaining parameters with defaults
int first_default_arg = arg_count - def_argcount;
- for (int i = p_argcount; i < arg_count; i++)
+ for (int i = p_argcount; i < arg_count; i++) {
newargs[i] = &default_args[i - first_default_arg];
+ }
#ifdef DEBUG_ENABLED
- if (!verify_arguments(newargs, r_error))
+ if (!verify_arguments(newargs, r_error)) {
return;
+ }
#endif
func(r_ret, p_self, newargs);
} else {
#ifdef DEBUG_ENABLED
- if (!verify_arguments(p_args, r_error))
+ if (!verify_arguments(p_args, r_error)) {
return;
+ }
#endif
func(r_ret, p_self, p_args);
}
@@ -124,7 +125,6 @@ struct _VariantCall {
};
struct TypeFunc {
-
Map<StringName, FuncData> functions;
};
@@ -143,14 +143,12 @@ struct _VariantCall {
//void addfunc(Variant::Type p_type, const StringName& p_name,VariantFunc p_func);
static void make_func_return_variant(Variant::Type p_type, const StringName &p_name) {
-
#ifdef DEBUG_ENABLED
type_funcs[p_type].functions[p_name].returns = true;
#endif
}
static void addfunc(bool p_const, Variant::Type p_type, Variant::Type p_return, bool p_has_return, const StringName &p_name, VariantFunc p_func, const Vector<Variant> &p_defaultarg, const Arg &p_argtype1 = Arg(), const Arg &p_argtype2 = Arg(), const Arg &p_argtype3 = Arg(), const Arg &p_argtype4 = Arg(), const Arg &p_argtype5 = Arg()) {
-
FuncData funcdata;
funcdata.func = p_func;
funcdata.default_args = p_defaultarg;
@@ -164,8 +162,9 @@ struct _VariantCall {
funcdata.arg_names.push_back(p_argtype1.name);
#endif
- } else
+ } else {
goto end;
+ }
if (p_argtype2.name) {
funcdata.arg_types.push_back(p_argtype2.type);
@@ -173,8 +172,9 @@ struct _VariantCall {
funcdata.arg_names.push_back(p_argtype2.name);
#endif
- } else
+ } else {
goto end;
+ }
if (p_argtype3.name) {
funcdata.arg_types.push_back(p_argtype3.type);
@@ -182,24 +182,27 @@ struct _VariantCall {
funcdata.arg_names.push_back(p_argtype3.name);
#endif
- } else
+ } else {
goto end;
+ }
if (p_argtype4.name) {
funcdata.arg_types.push_back(p_argtype4.type);
#ifdef DEBUG_ENABLED
funcdata.arg_names.push_back(p_argtype4.name);
#endif
- } else
+ } else {
goto end;
+ }
if (p_argtype5.name) {
funcdata.arg_types.push_back(p_argtype5.type);
#ifdef DEBUG_ENABLED
funcdata.arg_names.push_back(p_argtype5.name);
#endif
- } else
+ } else {
goto end;
+ }
end:
@@ -262,6 +265,7 @@ struct _VariantCall {
VCALL_LOCALMEM3R(String, split);
VCALL_LOCALMEM3R(String, rsplit);
VCALL_LOCALMEM2R(String, split_floats);
+ VCALL_LOCALMEM1R(String, join);
VCALL_LOCALMEM0R(String, to_upper);
VCALL_LOCALMEM0R(String, to_lower);
VCALL_LOCALMEM1R(String, left);
@@ -314,7 +318,6 @@ struct _VariantCall {
VCALL_LOCALMEM1R(String, trim_suffix);
static void _call_String_to_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
String *s = reinterpret_cast<String *>(p_self._data._mem);
if (s->empty()) {
r_ret = PackedByteArray();
@@ -332,7 +335,6 @@ struct _VariantCall {
}
static void _call_String_to_utf8(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
String *s = reinterpret_cast<String *>(p_self._data._mem);
if (s->empty()) {
r_ret = PackedByteArray();
@@ -362,7 +364,7 @@ struct _VariantCall {
VCALL_LOCALMEM1R(Vector2, angle_to);
VCALL_LOCALMEM1R(Vector2, angle_to_point);
VCALL_LOCALMEM1R(Vector2, direction_to);
- VCALL_LOCALMEM2R(Vector2, linear_interpolate);
+ VCALL_LOCALMEM2R(Vector2, lerp);
VCALL_LOCALMEM2R(Vector2, slerp);
VCALL_LOCALMEM4R(Vector2, cubic_interpolate);
VCALL_LOCALMEM2R(Vector2, move_toward);
@@ -426,7 +428,7 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Vector3, inverse);
VCALL_LOCALMEM1R(Vector3, snapped);
VCALL_LOCALMEM2R(Vector3, rotated);
- VCALL_LOCALMEM2R(Vector3, linear_interpolate);
+ VCALL_LOCALMEM2R(Vector3, lerp);
VCALL_LOCALMEM2R(Vector3, slerp);
VCALL_LOCALMEM4R(Vector3, cubic_interpolate);
VCALL_LOCALMEM2R(Vector3, move_toward);
@@ -464,26 +466,29 @@ struct _VariantCall {
//return vector3 if intersected, nil if not
static void _call_Plane_intersect_3(Variant &r_ret, Variant &p_self, const Variant **p_args) {
Vector3 result;
- if (reinterpret_cast<Plane *>(p_self._data._mem)->intersect_3(*p_args[0], *p_args[1], &result))
+ if (reinterpret_cast<Plane *>(p_self._data._mem)->intersect_3(*p_args[0], *p_args[1], &result)) {
r_ret = result;
- else
+ } else {
r_ret = Variant();
+ }
}
static void _call_Plane_intersects_ray(Variant &r_ret, Variant &p_self, const Variant **p_args) {
Vector3 result;
- if (reinterpret_cast<Plane *>(p_self._data._mem)->intersects_ray(*p_args[0], *p_args[1], &result))
+ if (reinterpret_cast<Plane *>(p_self._data._mem)->intersects_ray(*p_args[0], *p_args[1], &result)) {
r_ret = result;
- else
+ } else {
r_ret = Variant();
+ }
}
static void _call_Plane_intersects_segment(Variant &r_ret, Variant &p_self, const Variant **p_args) {
Vector3 result;
- if (reinterpret_cast<Plane *>(p_self._data._mem)->intersects_segment(*p_args[0], *p_args[1], &result))
+ if (reinterpret_cast<Plane *>(p_self._data._mem)->intersects_segment(*p_args[0], *p_args[1], &result)) {
r_ret = result;
- else
+ } else {
r_ret = Variant();
+ }
}
VCALL_LOCALMEM0R(Quat, length);
@@ -509,7 +514,7 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Color, to_rgba64);
VCALL_LOCALMEM0R(Color, inverted);
VCALL_LOCALMEM0R(Color, contrasted);
- VCALL_LOCALMEM2R(Color, linear_interpolate);
+ VCALL_LOCALMEM2R(Color, lerp);
VCALL_LOCALMEM1R(Color, blend);
VCALL_LOCALMEM1R(Color, lightened);
VCALL_LOCALMEM1R(Color, darkened);
@@ -591,7 +596,6 @@ struct _VariantCall {
VCALL_LOCALMEM0R(Array, min);
static void _call_PackedByteArray_get_string_from_ascii(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
String s;
if (ba->size() > 0) {
@@ -607,7 +611,6 @@ struct _VariantCall {
}
static void _call_PackedByteArray_get_string_from_utf8(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
String s;
if (ba->size() > 0) {
@@ -618,7 +621,6 @@ struct _VariantCall {
}
static void _call_PackedByteArray_compress(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
PackedByteArray compressed;
if (ba->size() > 0) {
@@ -634,7 +636,6 @@ struct _VariantCall {
}
static void _call_PackedByteArray_decompress(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
PackedByteArray *ba = reinterpret_cast<PackedByteArray *>(p_self._data._mem);
PackedByteArray decompressed;
Compression::Mode mode = (Compression::Mode)(int)(*p_args[1]);
@@ -860,42 +861,58 @@ struct _VariantCall {
VCALL_PTR1R(Transform2D, is_equal_approx);
static void _call_Transform2D_xform(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
switch (p_args[0]->type) {
-
- case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Vector2()); return;
- case Variant::RECT2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Rect2()); return;
- case Variant::PACKED_VECTOR2_ARRAY: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator PackedVector2Array()); return;
- default: r_ret = Variant();
+ case Variant::VECTOR2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Vector2());
+ return;
+ case Variant::RECT2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator Rect2());
+ return;
+ case Variant::PACKED_VECTOR2_ARRAY:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform(p_args[0]->operator PackedVector2Array());
+ return;
+ default:
+ r_ret = Variant();
+ ERR_PRINT("Invalid type in function 'xform' in base 'Transform2D'. Valid types are Vector2, Rect2, and PackedVector2Array.");
}
}
static void _call_Transform2D_xform_inv(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
switch (p_args[0]->type) {
-
- case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector2()); return;
- case Variant::RECT2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Rect2()); return;
- case Variant::PACKED_VECTOR2_ARRAY: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator PackedVector2Array()); return;
- default: r_ret = Variant();
+ case Variant::VECTOR2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector2());
+ return;
+ case Variant::RECT2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Rect2());
+ return;
+ case Variant::PACKED_VECTOR2_ARRAY:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->xform_inv(p_args[0]->operator PackedVector2Array());
+ return;
+ default:
+ r_ret = Variant();
+ ERR_PRINT("Invalid type in function 'xform_inv' in base 'Transform2D'. Valid types are Vector2, Rect2, and PackedVector2Array.");
}
}
static void _call_Transform2D_basis_xform(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
switch (p_args[0]->type) {
-
- case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->basis_xform(p_args[0]->operator Vector2()); return;
- default: r_ret = Variant();
+ case Variant::VECTOR2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->basis_xform(p_args[0]->operator Vector2());
+ return;
+ default:
+ r_ret = Variant();
+ ERR_PRINT("Invalid type in function 'basis_xform' in base 'Transform2D'. Only Vector2 is valid.");
}
}
static void _call_Transform2D_basis_xform_inv(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
switch (p_args[0]->type) {
-
- case Variant::VECTOR2: r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->basis_xform_inv(p_args[0]->operator Vector2()); return;
- default: r_ret = Variant();
+ case Variant::VECTOR2:
+ r_ret = reinterpret_cast<Transform2D *>(p_self._data._ptr)->basis_xform_inv(p_args[0]->operator Vector2());
+ return;
+ default:
+ r_ret = Variant();
+ ERR_PRINT("Invalid type in function 'basis_xform_inv' in base 'Transform2D'. Only Vector2 is valid.");
}
}
@@ -928,39 +945,46 @@ struct _VariantCall {
VCALL_PTR1R(Transform, is_equal_approx);
static void _call_Transform_xform(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
switch (p_args[0]->type) {
-
- case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Vector3()); return;
- case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Plane()); return;
- case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::AABB()); return;
- case Variant::PACKED_VECTOR3_ARRAY: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::PackedVector3Array()); return;
- default: r_ret = Variant();
+ case Variant::VECTOR3:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Vector3());
+ return;
+ case Variant::PLANE:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator Plane());
+ return;
+ case Variant::AABB:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::AABB());
+ return;
+ case Variant::PACKED_VECTOR3_ARRAY:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform(p_args[0]->operator ::PackedVector3Array());
+ return;
+ default:
+ r_ret = Variant();
+ ERR_PRINT("Invalid type in function 'xform' in base 'Transform'. Valid types are Vector3, Plane, AABB, and PackedVector3Array.");
}
}
static void _call_Transform_xform_inv(Variant &r_ret, Variant &p_self, const Variant **p_args) {
-
switch (p_args[0]->type) {
-
- case Variant::VECTOR3: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector3()); return;
- case Variant::PLANE: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Plane()); return;
- case Variant::AABB: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::AABB()); return;
- case Variant::PACKED_VECTOR3_ARRAY: r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::PackedVector3Array()); return;
- default: r_ret = Variant();
+ case Variant::VECTOR3:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Vector3());
+ return;
+ case Variant::PLANE:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator Plane());
+ return;
+ case Variant::AABB:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::AABB());
+ return;
+ case Variant::PACKED_VECTOR3_ARRAY:
+ r_ret = reinterpret_cast<Transform *>(p_self._data._ptr)->xform_inv(p_args[0]->operator ::PackedVector3Array());
+ return;
+ default:
+ r_ret = Variant();
+ ERR_PRINT("Invalid type in function 'xform_inv' in base 'Transform'. Valid types are Vector3, Plane, AABB, and PackedVector3Array.");
}
}
- /*
- VCALL_PTR0( Transform, invert );
- VCALL_PTR0( Transform, affine_invert );
- VCALL_PTR2( Transform, rotate );
- VCALL_PTR1( Transform, scale );
- VCALL_PTR1( Transform, translate );
- VCALL_PTR0( Transform, orthonormalize ); */
-
struct ConstructData {
-
int arg_count;
Vector<Variant::Type> arg_types;
Vector<String> arg_names;
@@ -968,50 +992,41 @@ struct _VariantCall {
};
struct ConstructFunc {
-
List<ConstructData> constructors;
};
static ConstructFunc *construct_funcs;
static void Vector2_init1(Variant &r_ret, const Variant **p_args) {
-
r_ret = Vector2(*p_args[0], *p_args[1]);
}
static void Vector2i_init1(Variant &r_ret, const Variant **p_args) {
-
r_ret = Vector2i(*p_args[0], *p_args[1]);
}
static void Rect2_init1(Variant &r_ret, const Variant **p_args) {
-
r_ret = Rect2(*p_args[0], *p_args[1]);
}
static void Rect2_init2(Variant &r_ret, const Variant **p_args) {
-
r_ret = Rect2(*p_args[0], *p_args[1], *p_args[2], *p_args[3]);
}
static void Rect2i_init1(Variant &r_ret, const Variant **p_args) {
-
r_ret = Rect2i(*p_args[0], *p_args[1]);
}
static void Rect2i_init2(Variant &r_ret, const Variant **p_args) {
-
r_ret = Rect2i(*p_args[0], *p_args[1], *p_args[2], *p_args[3]);
}
static void Transform2D_init2(Variant &r_ret, const Variant **p_args) {
-
Transform2D m(*p_args[0], *p_args[1]);
r_ret = m;
}
static void Transform2D_init3(Variant &r_ret, const Variant **p_args) {
-
Transform2D m;
m[0] = *p_args[0];
m[1] = *p_args[1];
@@ -1020,76 +1035,65 @@ struct _VariantCall {
}
static void Vector3_init1(Variant &r_ret, const Variant **p_args) {
-
r_ret = Vector3(*p_args[0], *p_args[1], *p_args[2]);
}
static void Vector3i_init1(Variant &r_ret, const Variant **p_args) {
-
r_ret = Vector3i(*p_args[0], *p_args[1], *p_args[2]);
}
static void Plane_init1(Variant &r_ret, const Variant **p_args) {
-
r_ret = Plane(*p_args[0], *p_args[1], *p_args[2], *p_args[3]);
}
static void Plane_init2(Variant &r_ret, const Variant **p_args) {
-
r_ret = Plane(*p_args[0], *p_args[1], *p_args[2]);
}
static void Plane_init3(Variant &r_ret, const Variant **p_args) {
-
r_ret = Plane(p_args[0]->operator Vector3(), p_args[1]->operator real_t());
}
static void Plane_init4(Variant &r_ret, const Variant **p_args) {
-
r_ret = Plane(p_args[0]->operator Vector3(), p_args[1]->operator Vector3());
}
static void Quat_init1(Variant &r_ret, const Variant **p_args) {
-
r_ret = Quat(*p_args[0], *p_args[1], *p_args[2], *p_args[3]);
}
static void Quat_init2(Variant &r_ret, const Variant **p_args) {
-
r_ret = Quat(((Vector3)(*p_args[0])), ((real_t)(*p_args[1])));
}
static void Quat_init3(Variant &r_ret, const Variant **p_args) {
-
r_ret = Quat(((Vector3)(*p_args[0])));
}
static void Color_init1(Variant &r_ret, const Variant **p_args) {
-
r_ret = Color(*p_args[0], *p_args[1], *p_args[2], *p_args[3]);
}
static void Color_init2(Variant &r_ret, const Variant **p_args) {
-
r_ret = Color(*p_args[0], *p_args[1], *p_args[2]);
}
static void Color_init3(Variant &r_ret, const Variant **p_args) {
-
r_ret = Color::html(*p_args[0]);
}
static void Color_init4(Variant &r_ret, const Variant **p_args) {
-
r_ret = Color::hex(*p_args[0]);
}
- static void AABB_init1(Variant &r_ret, const Variant **p_args) {
+ static void Color_init5(Variant &r_ret, const Variant **p_args) {
+ r_ret = Color(((Color)(*p_args[0])), *p_args[1]);
+ }
+ static void AABB_init1(Variant &r_ret, const Variant **p_args) {
r_ret = ::AABB(*p_args[0], *p_args[1]);
}
static void Basis_init1(Variant &r_ret, const Variant **p_args) {
-
Basis m;
m.set_axis(0, *p_args[0]);
m.set_axis(1, *p_args[1]);
@@ -1098,12 +1102,10 @@ struct _VariantCall {
}
static void Basis_init2(Variant &r_ret, const Variant **p_args) {
-
r_ret = Basis(p_args[0]->operator Vector3(), p_args[1]->operator real_t());
}
static void Transform_init1(Variant &r_ret, const Variant **p_args) {
-
Transform t;
t.basis.set_axis(0, *p_args[0]);
t.basis.set_axis(1, *p_args[1]);
@@ -1113,17 +1115,14 @@ struct _VariantCall {
}
static void Transform_init2(Variant &r_ret, const Variant **p_args) {
-
r_ret = Transform(p_args[0]->operator Basis(), p_args[1]->operator Vector3());
}
static void Callable_init2(Variant &r_ret, const Variant **p_args) {
-
r_ret = Callable(p_args[0]->operator ObjectID(), p_args[1]->operator String());
}
static void Signal_init2(Variant &r_ret, const Variant **p_args) {
-
r_ret = Signal(p_args[0]->operator ObjectID(), p_args[1]->operator String());
}
@@ -1132,31 +1131,34 @@ struct _VariantCall {
const String &p_name2 = "", const Variant::Type p_type2 = Variant::NIL,
const String &p_name3 = "", const Variant::Type p_type3 = Variant::NIL,
const String &p_name4 = "", const Variant::Type p_type4 = Variant::NIL) {
-
ConstructData cd;
cd.func = p_func;
cd.arg_count = 0;
- if (p_name1 == "")
+ if (p_name1 == "") {
goto end;
+ }
cd.arg_count++;
cd.arg_names.push_back(p_name1);
cd.arg_types.push_back(p_type1);
- if (p_name2 == "")
+ if (p_name2 == "") {
goto end;
+ }
cd.arg_count++;
cd.arg_names.push_back(p_name2);
cd.arg_types.push_back(p_type2);
- if (p_name3 == "")
+ if (p_name3 == "") {
goto end;
+ }
cd.arg_count++;
cd.arg_names.push_back(p_name3);
cd.arg_types.push_back(p_type3);
- if (p_name4 == "")
+ if (p_name4 == "") {
goto end;
+ }
cd.arg_count++;
cd.arg_names.push_back(p_name4);
cd.arg_types.push_back(p_type4);
@@ -1167,18 +1169,19 @@ struct _VariantCall {
}
struct ConstantData {
-
Map<StringName, int> value;
#ifdef DEBUG_ENABLED
List<StringName> value_ordered;
#endif
Map<StringName, Variant> variant_value;
+#ifdef DEBUG_ENABLED
+ List<StringName> variant_value_ordered;
+#endif
};
static ConstantData *constant_data;
static void add_constant(int p_type, StringName p_constant_name, int p_constant_value) {
-
constant_data[p_type].value[p_constant_name] = p_constant_value;
#ifdef DEBUG_ENABLED
constant_data[p_type].value_ordered.push_back(p_constant_name);
@@ -1186,8 +1189,10 @@ struct _VariantCall {
}
static void add_variant_constant(int p_type, StringName p_constant_name, const Variant &p_constant_value) {
-
constant_data[p_type].variant_value[p_constant_name] = p_constant_value;
+#ifdef DEBUG_ENABLED
+ constant_data[p_type].variant_value_ordered.push_back(p_constant_name);
+#endif
}
};
@@ -1196,7 +1201,6 @@ _VariantCall::ConstructFunc *_VariantCall::construct_funcs = nullptr;
_VariantCall::ConstantData *_VariantCall::constant_data = nullptr;
Variant Variant::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
Variant ret;
call_ptr(p_method, p_args, p_argcount, &ret, r_error);
return ret;
@@ -1224,13 +1228,11 @@ void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p
//else if (type==Variant::METHOD) {
} else {
-
r_error.error = Callable::CallError::CALL_OK;
Map<StringName, _VariantCall::FuncData>::Element *E = _VariantCall::type_funcs[type].functions.find(p_method);
if (E) {
-
_VariantCall::FuncData &funcdata = E->get();
funcdata.call(ret, *this, p_args, p_argcount, r_error);
@@ -1239,7 +1241,6 @@ void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p
bool valid = false;
if (type == CALLABLE) {
if (p_method == CoreStringNames::get_singleton()->call) {
-
reinterpret_cast<const Callable *>(_data._mem)->call(p_args, p_argcount, ret, r_error);
valid = true;
}
@@ -1264,14 +1265,14 @@ void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p
}
}
- if (r_error.error == Callable::CallError::CALL_OK && r_ret)
+ if (r_error.error == Callable::CallError::CALL_OK && r_ret) {
*r_ret = ret;
+ }
}
#define VCALL(m_type, m_method) _VariantCall::_call_##m_type##_##m_method
Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, int p_argcount, Callable::CallError &r_error, bool p_strict) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
ERR_FAIL_INDEX_V(p_type, VARIANT_MAX, Variant());
@@ -1283,50 +1284,74 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
return Variant();
// atomic types
- case BOOL: return Variant(false);
- case INT: return 0;
- case FLOAT: return 0.0f;
+ case BOOL:
+ return Variant(false);
+ case INT:
+ return 0;
+ case FLOAT:
+ return 0.0f;
case STRING:
return String();
// math types
case VECTOR2:
return Vector2();
- case RECT2: return Rect2();
- case VECTOR3: return Vector3();
- case TRANSFORM2D: return Transform2D();
- case PLANE: return Plane();
- case QUAT: return Quat();
+ case RECT2:
+ return Rect2();
+ case VECTOR3:
+ return Vector3();
+ case TRANSFORM2D:
+ return Transform2D();
+ case PLANE:
+ return Plane();
+ case QUAT:
+ return Quat();
case AABB:
return ::AABB();
- case BASIS: return Basis();
+ case BASIS:
+ return Basis();
case TRANSFORM:
return Transform();
// misc types
- case COLOR: return Color();
+ case COLOR:
+ return Color();
case STRING_NAME:
return StringName();
case NODE_PATH:
return NodePath();
- case _RID: return RID();
- case OBJECT: return (Object *)nullptr;
- case CALLABLE: return Callable();
- case SIGNAL: return Signal();
- case DICTIONARY: return Dictionary();
+ case _RID:
+ return RID();
+ case OBJECT:
+ return (Object *)nullptr;
+ case CALLABLE:
+ return Callable();
+ case SIGNAL:
+ return Signal();
+ case DICTIONARY:
+ return Dictionary();
case ARRAY:
return Array();
- case PACKED_BYTE_ARRAY: return PackedByteArray();
- case PACKED_INT32_ARRAY: return PackedInt32Array();
- case PACKED_INT64_ARRAY: return PackedInt64Array();
- case PACKED_FLOAT32_ARRAY: return PackedFloat32Array();
- case PACKED_FLOAT64_ARRAY: return PackedFloat64Array();
- case PACKED_STRING_ARRAY: return PackedStringArray();
+ case PACKED_BYTE_ARRAY:
+ return PackedByteArray();
+ case PACKED_INT32_ARRAY:
+ return PackedInt32Array();
+ case PACKED_INT64_ARRAY:
+ return PackedInt64Array();
+ case PACKED_FLOAT32_ARRAY:
+ return PackedFloat32Array();
+ case PACKED_FLOAT64_ARRAY:
+ return PackedFloat64Array();
+ case PACKED_STRING_ARRAY:
+ return PackedStringArray();
case PACKED_VECTOR2_ARRAY:
return PackedVector2Array();
- case PACKED_VECTOR3_ARRAY: return PackedVector3Array();
- case PACKED_COLOR_ARRAY: return PackedColorArray();
- default: return Variant();
+ case PACKED_VECTOR3_ARRAY:
+ return PackedVector3Array();
+ case PACKED_COLOR_ARRAY:
+ return PackedColorArray();
+ default:
+ return Variant();
}
} else if (p_argcount == 1 && p_args[0]->type == p_type) {
@@ -1336,7 +1361,6 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
switch (p_type) {
case NIL: {
-
return Variant();
} break;
case BOOL: {
@@ -1357,54 +1381,78 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
case VECTOR2I: {
return Vector2i(*p_args[0]);
}
- case RECT2: return (Rect2(*p_args[0]));
- case RECT2I: return (Rect2i(*p_args[0]));
- case VECTOR3: return (Vector3(*p_args[0]));
- case VECTOR3I: return (Vector3i(*p_args[0]));
- case PLANE: return (Plane(*p_args[0]));
- case QUAT: return (p_args[0]->operator Quat());
+ case RECT2:
+ return (Rect2(*p_args[0]));
+ case RECT2I:
+ return (Rect2i(*p_args[0]));
+ case VECTOR3:
+ return (Vector3(*p_args[0]));
+ case VECTOR3I:
+ return (Vector3i(*p_args[0]));
+ case TRANSFORM2D:
+ return (Transform2D(p_args[0]->operator Transform2D()));
+ case PLANE:
+ return (Plane(*p_args[0]));
+ case QUAT:
+ return (p_args[0]->operator Quat());
case AABB:
return (::AABB(*p_args[0]));
- case BASIS: return (Basis(p_args[0]->operator Basis()));
+ case BASIS:
+ return (Basis(p_args[0]->operator Basis()));
case TRANSFORM:
return (Transform(p_args[0]->operator Transform()));
// misc types
- case COLOR: return p_args[0]->type == Variant::STRING ? Color::html(*p_args[0]) : Color::hex(*p_args[0]);
+ case COLOR:
+ return p_args[0]->type == Variant::STRING ? Color::html(*p_args[0]) : Color::hex(*p_args[0]);
case STRING_NAME:
return (StringName(p_args[0]->operator StringName()));
case NODE_PATH:
return (NodePath(p_args[0]->operator NodePath()));
- case _RID: return (RID(*p_args[0]));
- case OBJECT: return ((Object *)(p_args[0]->operator Object *()));
- case CALLABLE: return ((Callable)(p_args[0]->operator Callable()));
- case SIGNAL: return ((Signal)(p_args[0]->operator Signal()));
- case DICTIONARY: return p_args[0]->operator Dictionary();
+ case _RID:
+ return (RID(*p_args[0]));
+ case OBJECT:
+ return ((Object *)(p_args[0]->operator Object *()));
+ case CALLABLE:
+ return ((Callable)(p_args[0]->operator Callable()));
+ case SIGNAL:
+ return ((Signal)(p_args[0]->operator Signal()));
+ case DICTIONARY:
+ return p_args[0]->operator Dictionary();
case ARRAY:
return p_args[0]->operator Array();
// arrays
- case PACKED_BYTE_ARRAY: return (PackedByteArray(*p_args[0]));
- case PACKED_INT32_ARRAY: return (PackedInt32Array(*p_args[0]));
- case PACKED_INT64_ARRAY: return (PackedInt64Array(*p_args[0]));
- case PACKED_FLOAT32_ARRAY: return (PackedFloat32Array(*p_args[0]));
- case PACKED_FLOAT64_ARRAY: return (PackedFloat64Array(*p_args[0]));
- case PACKED_STRING_ARRAY: return (PackedStringArray(*p_args[0]));
+ case PACKED_BYTE_ARRAY:
+ return (PackedByteArray(*p_args[0]));
+ case PACKED_INT32_ARRAY:
+ return (PackedInt32Array(*p_args[0]));
+ case PACKED_INT64_ARRAY:
+ return (PackedInt64Array(*p_args[0]));
+ case PACKED_FLOAT32_ARRAY:
+ return (PackedFloat32Array(*p_args[0]));
+ case PACKED_FLOAT64_ARRAY:
+ return (PackedFloat64Array(*p_args[0]));
+ case PACKED_STRING_ARRAY:
+ return (PackedStringArray(*p_args[0]));
case PACKED_VECTOR2_ARRAY:
return (PackedVector2Array(*p_args[0]));
- case PACKED_VECTOR3_ARRAY: return (PackedVector3Array(*p_args[0]));
- case PACKED_COLOR_ARRAY: return (PackedColorArray(*p_args[0]));
- default: return Variant();
+ case PACKED_VECTOR3_ARRAY:
+ return (PackedVector3Array(*p_args[0]));
+ case PACKED_COLOR_ARRAY:
+ return (PackedColorArray(*p_args[0]));
+ default:
+ return Variant();
}
} else if (p_argcount >= 1) {
-
_VariantCall::ConstructFunc &c = _VariantCall::construct_funcs[p_type];
for (List<_VariantCall::ConstructData>::Element *E = c.constructors.front(); E; E = E->next()) {
const _VariantCall::ConstructData &cd = E->get();
- if (cd.arg_count != p_argcount)
+ if (cd.arg_count != p_argcount) {
continue;
+ }
//validate parameters
for (int i = 0; i < cd.arg_count; i++) {
@@ -1426,11 +1474,11 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
}
bool Variant::has_method(const StringName &p_method) const {
-
if (type == OBJECT) {
Object *obj = get_validated_object();
- if (!obj)
+ if (!obj) {
return false;
+ }
return obj->has_method(p_method);
}
@@ -1440,69 +1488,68 @@ bool Variant::has_method(const StringName &p_method) const {
}
Vector<Variant::Type> Variant::get_method_argument_types(Variant::Type p_type, const StringName &p_method) {
-
const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
- if (!E)
+ if (!E) {
return Vector<Variant::Type>();
+ }
return E->get().arg_types;
}
bool Variant::is_method_const(Variant::Type p_type, const StringName &p_method) {
-
const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
- if (!E)
+ if (!E) {
return false;
+ }
return E->get()._const;
}
Vector<StringName> Variant::get_method_argument_names(Variant::Type p_type, const StringName &p_method) {
-
const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
- if (!E)
+ if (!E) {
return Vector<StringName>();
+ }
return E->get().arg_names;
}
Variant::Type Variant::get_method_return_type(Variant::Type p_type, const StringName &p_method, bool *r_has_return) {
-
const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
- if (!E)
+ if (!E) {
return Variant::NIL;
+ }
- if (r_has_return)
+ if (r_has_return) {
*r_has_return = E->get().returns;
+ }
return E->get().return_type;
}
Vector<Variant> Variant::get_method_default_arguments(Variant::Type p_type, const StringName &p_method) {
-
const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[p_type];
const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.find(p_method);
- if (!E)
+ if (!E) {
return Vector<Variant>();
+ }
return E->get().default_args;
}
void Variant::get_method_list(List<MethodInfo> *p_list) const {
-
const _VariantCall::TypeFunc &tf = _VariantCall::type_funcs[type];
for (const Map<StringName, _VariantCall::FuncData>::Element *E = tf.functions.front(); E; E = E->next()) {
-
const _VariantCall::FuncData &fd = E->get();
MethodInfo mi;
@@ -1513,7 +1560,6 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const {
}
for (int i = 0; i < fd.arg_types.size(); i++) {
-
PropertyInfo pi;
pi.type = fd.arg_types[i];
#ifdef DEBUG_ENABLED
@@ -1528,8 +1574,9 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const {
ret.type = fd.return_type;
if (fd.returns) {
ret.name = "ret";
- if (fd.return_type == Variant::NIL)
+ if (fd.return_type == Variant::NIL) {
ret.usage = PROPERTY_USAGE_NIL_IS_VARIANT;
+ }
}
mi.return_val = ret;
#endif
@@ -1538,7 +1585,6 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const {
}
if (type == CALLABLE) {
-
MethodInfo mi;
mi.name = "call";
mi.return_val.usage = PROPERTY_USAGE_NIL_IS_VARIANT;
@@ -1553,7 +1599,6 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const {
}
if (type == SIGNAL) {
-
MethodInfo mi;
mi.name = "emit";
mi.flags |= METHOD_FLAG_VARARG;
@@ -1563,18 +1608,15 @@ void Variant::get_method_list(List<MethodInfo> *p_list) const {
}
void Variant::get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_list) {
-
ERR_FAIL_INDEX(p_type, VARIANT_MAX);
//custom constructors
for (const List<_VariantCall::ConstructData>::Element *E = _VariantCall::construct_funcs[p_type].constructors.front(); E; E = E->next()) {
-
const _VariantCall::ConstructData &cd = E->get();
MethodInfo mi;
mi.name = Variant::get_type_name(p_type);
mi.return_val.type = p_type;
for (int i = 0; i < cd.arg_count; i++) {
-
PropertyInfo pi;
pi.name = cd.arg_names[i];
pi.type = cd.arg_types[i];
@@ -1584,10 +1626,12 @@ void Variant::get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_lis
}
//default constructors
for (int i = 0; i < VARIANT_MAX; i++) {
- if (i == p_type)
+ if (i == p_type) {
continue;
- if (!Variant::can_convert(Variant::Type(i), p_type))
+ }
+ if (!Variant::can_convert(Variant::Type(i), p_type)) {
continue;
+ }
MethodInfo mi;
mi.name = Variant::get_type_name(p_type);
@@ -1601,39 +1645,39 @@ void Variant::get_constructor_list(Variant::Type p_type, List<MethodInfo> *p_lis
}
void Variant::get_constants_for_type(Variant::Type p_type, List<StringName> *p_constants) {
-
ERR_FAIL_INDEX(p_type, Variant::VARIANT_MAX);
_VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type];
#ifdef DEBUG_ENABLED
for (List<StringName>::Element *E = cd.value_ordered.front(); E; E = E->next()) {
-
p_constants->push_back(E->get());
#else
for (Map<StringName, int>::Element *E = cd.value.front(); E; E = E->next()) {
-
p_constants->push_back(E->key());
#endif
}
+#ifdef DEBUG_ENABLED
+ for (List<StringName>::Element *E = cd.variant_value_ordered.front(); E; E = E->next()) {
+ p_constants->push_back(E->get());
+#else
for (Map<StringName, Variant>::Element *E = cd.variant_value.front(); E; E = E->next()) {
-
p_constants->push_back(E->key());
+#endif
}
}
bool Variant::has_constant(Variant::Type p_type, const StringName &p_value) {
-
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, false);
_VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type];
return cd.value.has(p_value) || cd.variant_value.has(p_value);
}
Variant Variant::get_constant_value(Variant::Type p_type, const StringName &p_value, bool *r_valid) {
-
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
ERR_FAIL_INDEX_V(p_type, Variant::VARIANT_MAX, 0);
_VariantCall::ConstantData &cd = _VariantCall::constant_data[p_type];
@@ -1642,21 +1686,22 @@ Variant Variant::get_constant_value(Variant::Type p_type, const StringName &p_va
if (!E) {
Map<StringName, Variant>::Element *F = cd.variant_value.find(p_value);
if (F) {
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return F->get();
} else {
return -1;
}
}
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return E->get();
}
void register_variant_methods() {
-
_VariantCall::type_funcs = memnew_arr(_VariantCall::TypeFunc, Variant::VARIANT_MAX);
_VariantCall::construct_funcs = memnew_arr(_VariantCall::ConstructFunc, Variant::VARIANT_MAX);
@@ -1739,6 +1784,7 @@ void register_variant_methods() {
ADDFUNC3R(STRING, PACKED_STRING_ARRAY, String, split, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
ADDFUNC3R(STRING, PACKED_STRING_ARRAY, String, rsplit, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
ADDFUNC2R(STRING, PACKED_FLOAT32_ARRAY, String, split_floats, STRING, "delimiter", BOOL, "allow_empty", varray(true));
+ ADDFUNC1R(STRING, STRING, String, join, PACKED_STRING_ARRAY, "parts", varray());
ADDFUNC0R(STRING, STRING, String, to_upper, varray());
ADDFUNC0R(STRING, STRING, String, to_lower, varray());
@@ -1809,7 +1855,7 @@ void register_variant_methods() {
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmod, FLOAT, "mod", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, posmodv, VECTOR2, "modv", varray());
ADDFUNC1R(VECTOR2, VECTOR2, Vector2, project, VECTOR2, "b", varray());
- ADDFUNC2R(VECTOR2, VECTOR2, Vector2, linear_interpolate, VECTOR2, "b", FLOAT, "t", varray());
+ ADDFUNC2R(VECTOR2, VECTOR2, Vector2, lerp, VECTOR2, "b", FLOAT, "t", varray());
ADDFUNC2R(VECTOR2, VECTOR2, Vector2, slerp, VECTOR2, "b", FLOAT, "t", varray());
ADDFUNC4R(VECTOR2, VECTOR2, Vector2, cubic_interpolate, VECTOR2, "b", VECTOR2, "pre_a", VECTOR2, "post_b", FLOAT, "t", varray());
ADDFUNC2R(VECTOR2, VECTOR2, Vector2, move_toward, VECTOR2, "to", FLOAT, "delta", varray());
@@ -1874,7 +1920,7 @@ void register_variant_methods() {
ADDFUNC0R(VECTOR3, VECTOR3, Vector3, inverse, varray());
ADDFUNC1R(VECTOR3, VECTOR3, Vector3, snapped, VECTOR3, "by", varray());
ADDFUNC2R(VECTOR3, VECTOR3, Vector3, rotated, VECTOR3, "axis", FLOAT, "phi", varray());
- ADDFUNC2R(VECTOR3, VECTOR3, Vector3, linear_interpolate, VECTOR3, "b", FLOAT, "t", varray());
+ ADDFUNC2R(VECTOR3, VECTOR3, Vector3, lerp, VECTOR3, "b", FLOAT, "t", varray());
ADDFUNC2R(VECTOR3, VECTOR3, Vector3, slerp, VECTOR3, "b", FLOAT, "t", varray());
ADDFUNC4R(VECTOR3, VECTOR3, Vector3, cubic_interpolate, VECTOR3, "b", VECTOR3, "pre_a", VECTOR3, "post_b", FLOAT, "t", varray());
ADDFUNC2R(VECTOR3, VECTOR3, Vector3, move_toward, VECTOR3, "to", FLOAT, "delta", varray());
@@ -1933,7 +1979,7 @@ void register_variant_methods() {
ADDFUNC0R(COLOR, INT, Color, to_rgba64, varray());
ADDFUNC0R(COLOR, COLOR, Color, inverted, varray());
ADDFUNC0R(COLOR, COLOR, Color, contrasted, varray());
- ADDFUNC2R(COLOR, COLOR, Color, linear_interpolate, COLOR, "b", FLOAT, "t", varray());
+ ADDFUNC2R(COLOR, COLOR, Color, lerp, COLOR, "b", FLOAT, "t", varray());
ADDFUNC1R(COLOR, COLOR, Color, blend, COLOR, "over", varray());
ADDFUNC1R(COLOR, COLOR, Color, lightened, FLOAT, "amount", varray());
ADDFUNC1R(COLOR, COLOR, Color, darkened, FLOAT, "amount", varray());
@@ -2217,6 +2263,8 @@ void register_variant_methods() {
_VariantCall::add_constructor(_VariantCall::Color_init1, Variant::COLOR, "r", Variant::FLOAT, "g", Variant::FLOAT, "b", Variant::FLOAT, "a", Variant::FLOAT);
_VariantCall::add_constructor(_VariantCall::Color_init2, Variant::COLOR, "r", Variant::FLOAT, "g", Variant::FLOAT, "b", Variant::FLOAT);
+ // init3 and init4 are the constructors for HTML hex strings and integers respectively which don't need binding here, so we skip to init5.
+ _VariantCall::add_constructor(_VariantCall::Color_init5, Variant::COLOR, "c", Variant::COLOR, "a", Variant::FLOAT);
_VariantCall::add_constructor(_VariantCall::AABB_init1, Variant::AABB, "position", Variant::VECTOR3, "size", Variant::VECTOR3);
@@ -2314,7 +2362,6 @@ void register_variant_methods() {
}
void unregister_variant_methods() {
-
memdelete_arr(_VariantCall::type_funcs);
memdelete_arr(_VariantCall::construct_funcs);
memdelete_arr(_VariantCall::constant_data);
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index f173c88054..2c79e2029e 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -78,43 +78,44 @@
#define TYPE(PREFIX, OP, TYPE) &&PREFIX##_##OP##_##TYPE
/* clang-format off */
-#define TYPES(PREFIX, OP) { \
- TYPE(PREFIX, OP, NIL), \
- TYPE(PREFIX, OP, BOOL), \
- TYPE(PREFIX, OP, INT), \
- TYPE(PREFIX, OP, FLOAT), \
- TYPE(PREFIX, OP, STRING), \
- TYPE(PREFIX, OP, VECTOR2), \
- TYPE(PREFIX, OP, VECTOR2I), \
- TYPE(PREFIX, OP, RECT2), \
- TYPE(PREFIX, OP, RECT2I), \
- TYPE(PREFIX, OP, VECTOR3), \
- TYPE(PREFIX, OP, VECTOR3I), \
- TYPE(PREFIX, OP, TRANSFORM2D), \
- TYPE(PREFIX, OP, PLANE), \
- TYPE(PREFIX, OP, QUAT), \
- TYPE(PREFIX, OP, AABB), \
- TYPE(PREFIX, OP, BASIS), \
- TYPE(PREFIX, OP, TRANSFORM), \
- TYPE(PREFIX, OP, COLOR), \
+#define TYPES(PREFIX, OP) { \
+ TYPE(PREFIX, OP, NIL), \
+ TYPE(PREFIX, OP, BOOL), \
+ TYPE(PREFIX, OP, INT), \
+ TYPE(PREFIX, OP, FLOAT), \
+ TYPE(PREFIX, OP, STRING), \
+ TYPE(PREFIX, OP, VECTOR2), \
+ TYPE(PREFIX, OP, VECTOR2I), \
+ TYPE(PREFIX, OP, RECT2), \
+ TYPE(PREFIX, OP, RECT2I), \
+ TYPE(PREFIX, OP, VECTOR3), \
+ TYPE(PREFIX, OP, VECTOR3I), \
+ TYPE(PREFIX, OP, TRANSFORM2D), \
+ TYPE(PREFIX, OP, PLANE), \
+ TYPE(PREFIX, OP, QUAT), \
+ TYPE(PREFIX, OP, AABB), \
+ TYPE(PREFIX, OP, BASIS), \
+ TYPE(PREFIX, OP, TRANSFORM), \
+ TYPE(PREFIX, OP, COLOR), \
TYPE(PREFIX, OP, STRING_NAME), \
- TYPE(PREFIX, OP, NODE_PATH), \
- TYPE(PREFIX, OP, _RID), \
- TYPE(PREFIX, OP, OBJECT), \
+ TYPE(PREFIX, OP, NODE_PATH), \
+ TYPE(PREFIX, OP, _RID), \
+ TYPE(PREFIX, OP, OBJECT), \
TYPE(PREFIX, OP, CALLABLE), \
- TYPE(PREFIX, OP, SIGNAL), \
- TYPE(PREFIX, OP, DICTIONARY), \
- TYPE(PREFIX, OP, ARRAY), \
+ TYPE(PREFIX, OP, SIGNAL), \
+ TYPE(PREFIX, OP, DICTIONARY), \
+ TYPE(PREFIX, OP, ARRAY), \
TYPE(PREFIX, OP, PACKED_BYTE_ARRAY), \
- TYPE(PREFIX, OP, PACKED_INT32_ARRAY), \
- TYPE(PREFIX, OP, PACKED_INT64_ARRAY), \
- TYPE(PREFIX, OP, PACKED_FLOAT32_ARRAY), \
- TYPE(PREFIX, OP, PACKED_FLOAT64_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_INT32_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_INT64_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_FLOAT32_ARRAY), \
+ TYPE(PREFIX, OP, PACKED_FLOAT64_ARRAY), \
TYPE(PREFIX, OP, PACKED_STRING_ARRAY), \
TYPE(PREFIX, OP, PACKED_VECTOR2_ARRAY), \
TYPE(PREFIX, OP, PACKED_VECTOR3_ARRAY), \
TYPE(PREFIX, OP, PACKED_COLOR_ARRAY), \
}
+
/* clang-format on */
#define CASES(PREFIX) static const void *switch_table_##PREFIX[25][Variant::VARIANT_MAX] = { \
@@ -159,7 +160,6 @@
#endif
Variant::operator bool() const {
-
return booleanize();
}
@@ -181,22 +181,27 @@ bool Variant::booleanize() const {
return; \
}
-#define DEFAULT_OP_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
- if (p_b.type == FLOAT) _RETURN(p_a._data.m_type m_op p_b._data._float); \
- \
- _RETURN_FAIL \
- };
-
-#define DEFAULT_OP_NUM_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
- if (p_b.type == FLOAT) _RETURN(p_a._data.m_type m_op p_b._data._float); \
- if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
- \
- _RETURN_FAIL \
- };
+#define DEFAULT_OP_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._int); \
+ if (p_b.type == FLOAT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._float); \
+ \
+ _RETURN_FAIL \
+ }
+
+#define DEFAULT_OP_NUM_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._int); \
+ if (p_b.type == FLOAT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._float); \
+ if (p_b.type == NIL) \
+ _RETURN(!(p_b.type m_op NIL)); \
+ \
+ _RETURN_FAIL \
+ }
#ifdef DEBUG_ENABLED
#define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \
@@ -217,84 +222,108 @@ bool Variant::booleanize() const {
} \
\
_RETURN_FAIL \
- };
+ }
#else
-#define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type / p_b._data._int); \
- if (p_b.type == FLOAT) _RETURN(p_a._data.m_type / p_b._data._float); \
- \
- _RETURN_FAIL \
- };
+#define DEFAULT_OP_NUM_DIV(m_prefix, m_op_name, m_name, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) \
+ _RETURN(p_a._data.m_type / p_b._data._int); \
+ if (p_b.type == FLOAT) \
+ _RETURN(p_a._data.m_type / p_b._data._float); \
+ \
+ _RETURN_FAIL \
+ }
#endif
#define DEFAULT_OP_NUM_NEG(m_prefix, m_op_name, m_name, m_type) \
CASE_TYPE(m_prefix, m_op_name, m_name) { \
_RETURN(-p_a._data.m_type); \
- };
+ }
#define DEFAULT_OP_NUM_POS(m_prefix, m_op_name, m_name, m_type) \
CASE_TYPE(m_prefix, m_op_name, m_name) { \
_RETURN(p_a._data.m_type); \
- };
-
-#define DEFAULT_OP_NUM_VEC(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == INT) _RETURN(p_a._data.m_type m_op p_b._data._int); \
- if (p_b.type == FLOAT) _RETURN(p_a._data.m_type m_op p_b._data._float); \
- if (p_b.type == VECTOR2) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
- if (p_b.type == VECTOR3) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
- if (p_b.type == VECTOR2I) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
- if (p_b.type == VECTOR3I) _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
- \
- _RETURN_FAIL \
- };
-
-#define DEFAULT_OP_STR_REV(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const String *>(p_a._data._mem)); \
- if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const StringName *>(p_a._data._mem)); \
- if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const NodePath *>(p_a._data._mem)); \
- \
- _RETURN_FAIL \
- };
-
-#define DEFAULT_OP_STR(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
- if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
- if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
- \
- _RETURN_FAIL \
- };
-
-#define DEFAULT_OP_STR_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
- if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
- if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
- if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
- \
- _RETURN_FAIL \
- };
-
-#define DEFAULT_OP_STR_NULL_NP(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
- if (p_b.type == NODE_PATH) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
- if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
- \
- _RETURN_FAIL \
- };
-
-#define DEFAULT_OP_STR_NULL_SN(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == STRING) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
- if (p_b.type == STRING_NAME) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
- if (p_b.type == NIL) _RETURN(!(p_b.type m_op NIL)); \
- \
- _RETURN_FAIL \
- };
+ }
+
+#define DEFAULT_OP_NUM_VEC(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == INT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._int); \
+ if (p_b.type == FLOAT) \
+ _RETURN(p_a._data.m_type m_op p_b._data._float); \
+ if (p_b.type == VECTOR2) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR3) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR2I) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector2 *>(p_b._data._mem)); \
+ if (p_b.type == VECTOR3I) \
+ _RETURN(p_a._data.m_type m_op *reinterpret_cast<const Vector3 *>(p_b._data._mem)); \
+ \
+ _RETURN_FAIL \
+ }
+
+#define DEFAULT_OP_STR_REV(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const String *>(p_a._data._mem)); \
+ if (p_b.type == STRING_NAME) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const StringName *>(p_a._data._mem)); \
+ if (p_b.type == NODE_PATH) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const NodePath *>(p_a._data._mem)); \
+ \
+ _RETURN_FAIL \
+ }
+
+#define DEFAULT_OP_STR(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
+ if (p_b.type == STRING_NAME) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
+ if (p_b.type == NODE_PATH) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
+ \
+ _RETURN_FAIL \
+ }
+
+#define DEFAULT_OP_STR_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
+ if (p_b.type == STRING_NAME) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
+ if (p_b.type == NODE_PATH) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
+ if (p_b.type == NIL) \
+ _RETURN(!(p_b.type m_op NIL)); \
+ \
+ _RETURN_FAIL \
+ }
+
+#define DEFAULT_OP_STR_NULL_NP(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
+ if (p_b.type == NODE_PATH) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const NodePath *>(p_b._data._mem)); \
+ if (p_b.type == NIL) \
+ _RETURN(!(p_b.type m_op NIL)); \
+ \
+ _RETURN_FAIL \
+ }
+
+#define DEFAULT_OP_STR_NULL_SN(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == STRING) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const String *>(p_b._data._mem)); \
+ if (p_b.type == STRING_NAME) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const StringName *>(p_b._data._mem)); \
+ if (p_b.type == NIL) \
+ _RETURN(!(p_b.type m_op NIL)); \
+ \
+ _RETURN_FAIL \
+ }
#define DEFAULT_OP_LOCALMEM_REV(m_prefix, m_op_name, m_name, m_op, m_type) \
CASE_TYPE(m_prefix, m_op_name, m_name) { \
@@ -302,7 +331,7 @@ bool Variant::booleanize() const {
_RETURN(*reinterpret_cast<const m_type *>(p_b._data._mem) m_op *reinterpret_cast<const m_type *>(p_a._data._mem)); \
\
_RETURN_FAIL \
- };
+ }
#define DEFAULT_OP_LOCALMEM(m_prefix, m_op_name, m_name, m_op, m_type) \
CASE_TYPE(m_prefix, m_op_name, m_name) { \
@@ -310,7 +339,7 @@ bool Variant::booleanize() const {
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \
\
_RETURN_FAIL \
- };
+ }
#define DEFAULT_OP_LOCALMEM_NULL(m_prefix, m_op_name, m_name, m_op, m_type) \
CASE_TYPE(m_prefix, m_op_name, m_name) { \
@@ -320,7 +349,7 @@ bool Variant::booleanize() const {
_RETURN(!(p_b.type m_op NIL)); \
\
_RETURN_FAIL \
- };
+ }
#define DEFAULT_OP_LOCALMEM_NEG(m_prefix, m_op_name, m_name, m_type) \
CASE_TYPE(m_prefix, m_op_name, m_name) { \
@@ -332,13 +361,16 @@ bool Variant::booleanize() const {
_RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem)); \
}
-#define DEFAULT_OP_LOCALMEM_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \
- CASE_TYPE(m_prefix, m_op_name, m_name) { \
- if (p_b.type == m_name) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \
- if (p_b.type == INT) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._int); \
- if (p_b.type == FLOAT) _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._float); \
- \
- _RETURN_FAIL \
+#define DEFAULT_OP_LOCALMEM_NUM(m_prefix, m_op_name, m_name, m_op, m_type) \
+ CASE_TYPE(m_prefix, m_op_name, m_name) { \
+ if (p_b.type == m_name) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op *reinterpret_cast<const m_type *>(p_b._data._mem)); \
+ if (p_b.type == INT) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._int); \
+ if (p_b.type == FLOAT) \
+ _RETURN(*reinterpret_cast<const m_type *>(p_a._data._mem) m_op p_b._data._float); \
+ \
+ _RETURN_FAIL \
}
#define DEFAULT_OP_PTR(m_op, m_name, m_sub) \
@@ -403,7 +435,6 @@ bool Variant::booleanize() const {
if (a_len m_opa array_b.size()) { \
_RETURN(m_ret_s); \
} else { \
- \
const m_type *ra = array_a.ptr(); \
const m_type *rb = array_b.ptr(); \
\
@@ -429,14 +460,14 @@ bool Variant::booleanize() const {
void Variant::evaluate(const Operator &p_op, const Variant &p_a,
const Variant &p_b, Variant &r_ret, bool &r_valid) {
-
CASES(math);
r_valid = true;
SWITCH(math, p_op, p_a.type) {
SWITCH_OP(math, OP_EQUAL, p_a.type) {
CASE_TYPE(math, OP_EQUAL, NIL) {
- if (p_b.type == NIL) _RETURN(true);
+ if (p_b.type == NIL)
+ _RETURN(true);
if (p_b.type == OBJECT)
_RETURN(p_b._get_obj().obj == nullptr);
@@ -532,7 +563,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
SWITCH_OP(math, OP_NOT_EQUAL, p_a.type) {
CASE_TYPE(math, OP_NOT_EQUAL, NIL) {
- if (p_b.type == NIL) _RETURN(false);
+ if (p_b.type == NIL)
+ _RETURN(false);
if (p_b.type == OBJECT)
_RETURN(p_b._get_obj().obj != nullptr);
@@ -884,10 +916,12 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
int asize = array_a.size();
int bsize = array_b.size();
sum.resize(asize + bsize);
- for (int i = 0; i < asize; i++)
+ for (int i = 0; i < asize; i++) {
sum[i] = array_a[i];
- for (int i = 0; i < bsize; i++)
+ }
+ for (int i = 0; i < bsize; i++) {
sum[i + asize] = array_b[i];
+ }
_RETURN(sum);
}
@@ -981,7 +1015,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
case VECTOR2: {
_RETURN(p_a._data._transform2d->xform(*(const Vector2 *)p_b._data._mem));
}
- default: _RETURN_FAIL;
+ default:
+ _RETURN_FAIL;
}
}
@@ -996,7 +1031,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
case FLOAT: {
_RETURN(*reinterpret_cast<const Quat *>(p_a._data._mem) * p_b._data._float);
}
- default: _RETURN_FAIL;
+ default:
+ _RETURN_FAIL;
}
}
@@ -1008,7 +1044,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
case BASIS: {
_RETURN(*p_a._data._basis * *p_b._data._basis);
}
- default: _RETURN_FAIL;
+ default:
+ _RETURN_FAIL;
}
}
@@ -1020,7 +1057,8 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
case TRANSFORM: {
_RETURN(*p_a._data._transform * *p_b._data._transform);
}
- default: _RETURN_FAIL;
+ default:
+ _RETURN_FAIL;
}
}
@@ -1380,7 +1418,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a,
}
void Variant::set_named(const StringName &p_index, const Variant &p_value, bool *r_valid) {
-
bool valid = false;
switch (type) {
case VECTOR2: {
@@ -1428,7 +1465,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
} break;
case RECT2: {
-
if (p_value.type == Variant::VECTOR2) {
Rect2 *v = reinterpret_cast<Rect2 *>(_data._mem);
//scalar name
@@ -1445,7 +1481,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
}
} break;
case RECT2I: {
-
if (p_value.type == Variant::VECTOR2I) {
Rect2i *v = reinterpret_cast<Rect2i *>(_data._mem);
//scalar name
@@ -1462,7 +1497,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
}
} break;
case TRANSFORM2D: {
-
if (p_value.type == Variant::VECTOR2) {
Transform2D *v = _data._transform2d;
if (p_index == CoreStringNames::singleton->x) {
@@ -1479,7 +1513,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
} break;
case VECTOR3: {
-
if (p_value.type == Variant::INT) {
Vector3 *v = reinterpret_cast<Vector3 *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
@@ -1508,7 +1541,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
} break;
case VECTOR3I: {
-
if (p_value.type == Variant::INT) {
Vector3i *v = reinterpret_cast<Vector3i *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
@@ -1537,7 +1569,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
} break;
case PLANE: {
-
if (p_value.type == Variant::INT) {
Plane *v = reinterpret_cast<Plane *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
@@ -1579,7 +1610,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
} break;
case QUAT: {
-
if (p_value.type == Variant::INT) {
Quat *v = reinterpret_cast<Quat *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
@@ -1614,7 +1644,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
} break;
case AABB: {
-
if (p_value.type == Variant::VECTOR3) {
::AABB *v = _data._aabb;
//scalar name
@@ -1631,7 +1660,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
}
} break;
case BASIS: {
-
if (p_value.type == Variant::VECTOR3) {
Basis *v = _data._basis;
//scalar name
@@ -1648,7 +1676,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
}
} break;
case TRANSFORM: {
-
if (p_value.type == Variant::BASIS && p_index == CoreStringNames::singleton->basis) {
_data._transform->basis = *p_value._data._basis;
valid = true;
@@ -1659,7 +1686,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
} break;
case COLOR: {
-
if (p_value.type == Variant::INT) {
Color *v = reinterpret_cast<Color *>(_data._mem);
if (p_index == CoreStringNames::singleton->r) {
@@ -1735,7 +1761,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
}
} break;
case OBJECT: {
-
#ifdef DEBUG_ENABLED
if (!_get_obj().obj) {
break;
@@ -1758,7 +1783,6 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
}
Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
-
if (r_valid) {
*r_valid = true;
}
@@ -1782,7 +1806,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
} break;
case RECT2: {
-
const Rect2 *v = reinterpret_cast<const Rect2 *>(_data._mem);
//scalar name
if (p_index == CoreStringNames::singleton->position) {
@@ -1794,7 +1817,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
}
} break;
case RECT2I: {
-
const Rect2i *v = reinterpret_cast<const Rect2i *>(_data._mem);
//scalar name
if (p_index == CoreStringNames::singleton->position) {
@@ -1806,7 +1828,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
}
} break;
case TRANSFORM2D: {
-
const Transform2D *v = _data._transform2d;
if (p_index == CoreStringNames::singleton->x) {
return v->elements[0];
@@ -1818,7 +1839,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
} break;
case VECTOR3: {
-
const Vector3 *v = reinterpret_cast<const Vector3 *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
return v->x;
@@ -1830,7 +1850,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
} break;
case VECTOR3I: {
-
const Vector3i *v = reinterpret_cast<const Vector3i *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
return v->x;
@@ -1842,7 +1861,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
} break;
case PLANE: {
-
const Plane *v = reinterpret_cast<const Plane *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
return v->normal.x;
@@ -1858,7 +1876,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
} break;
case QUAT: {
-
const Quat *v = reinterpret_cast<const Quat *>(_data._mem);
if (p_index == CoreStringNames::singleton->x) {
return v->x;
@@ -1872,7 +1889,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
} break;
case AABB: {
-
const ::AABB *v = _data._aabb;
//scalar name
if (p_index == CoreStringNames::singleton->position) {
@@ -1884,7 +1900,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
}
} break;
case BASIS: {
-
const Basis *v = _data._basis;
//scalar name
if (p_index == CoreStringNames::singleton->x) {
@@ -1897,7 +1912,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
} break;
case TRANSFORM: {
-
if (p_index == CoreStringNames::singleton->basis) {
return _data._transform->basis;
} else if (p_index == CoreStringNames::singleton->origin) {
@@ -1906,7 +1920,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
} break;
case COLOR: {
-
const Color *v = reinterpret_cast<const Color *>(_data._mem);
if (p_index == CoreStringNames::singleton->r) {
return v->r;
@@ -1933,17 +1946,17 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
}
} break;
case OBJECT: {
-
#ifdef DEBUG_ENABLED
if (!_get_obj().obj) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return "Instance base is null.";
} else {
-
if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return "Attempted use of stray pointer object.";
}
}
@@ -1983,7 +1996,8 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
#define DEFAULT_OP_DVECTOR_SET(m_name, m_type, skip_cond) \
case m_name: { \
- if (skip_cond) return; \
+ if (skip_cond) \
+ return; \
\
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { \
int index = p_index; \
@@ -2000,7 +2014,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
#define DEFAULT_OP_DVECTOR_GET(m_name, m_type) \
case m_name: { \
- \
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) { \
int index = p_index; \
const Vector<m_type> *arr = &PackedArrayRef<m_type>::get_array(_data.packed_array); \
@@ -2015,7 +2028,6 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
} break;
void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid) {
-
static bool _dummy = false;
bool &valid = r_valid ? *r_valid : _dummy;
@@ -2035,24 +2047,24 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
return;
} break;
case STRING: {
-
- if (p_index.type != Variant::INT && p_index.type != Variant::FLOAT)
+ if (p_index.type != Variant::INT && p_index.type != Variant::FLOAT) {
return;
+ }
int idx = p_index;
String *str = reinterpret_cast<String *>(_data._mem);
int len = str->length();
- if (idx < 0)
+ if (idx < 0) {
idx += len;
- if (idx < 0 || idx >= len)
+ }
+ if (idx < 0 || idx >= len) {
return;
+ }
String chr;
if (p_value.type == Variant::INT || p_value.type == Variant::FLOAT) {
-
chr = String::chr(p_value);
} else if (p_value.type == Variant::STRING) {
-
chr = p_value;
} else {
return;
@@ -2064,18 +2076,18 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case VECTOR2: {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) {
return;
+ }
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
// scalar index
int idx = p_index;
- if (idx < 0)
+ if (idx < 0) {
idx += 2;
+ }
if (idx >= 0 && idx < 2) {
-
Vector2 *v = reinterpret_cast<Vector2 *>(_data._mem);
valid = true;
(*v)[idx] = p_value;
@@ -2099,18 +2111,18 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case VECTOR2I: {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) {
return;
+ }
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
// scalar index
int idx = p_index;
- if (idx < 0)
+ if (idx < 0) {
idx += 2;
+ }
if (idx >= 0 && idx < 2) {
-
Vector2i *v = reinterpret_cast<Vector2i *>(_data._mem);
valid = true;
(*v)[idx] = p_value;
@@ -2134,9 +2146,9 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case RECT2: {
-
- if (p_value.type != Variant::VECTOR2)
+ if (p_value.type != Variant::VECTOR2) {
return;
+ }
if (p_index.get_type() == Variant::STRING) {
//scalar name
@@ -2159,9 +2171,9 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
} break;
case RECT2I: {
-
- if (p_value.type != Variant::VECTOR2I)
+ if (p_value.type != Variant::VECTOR2I) {
return;
+ }
if (p_index.get_type() == Variant::STRING) {
//scalar name
@@ -2184,16 +2196,16 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
} break;
case TRANSFORM2D: {
-
- if (p_value.type != Variant::VECTOR2)
+ if (p_value.type != Variant::VECTOR2) {
return;
+ }
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
-
int index = p_index;
- if (index < 0)
+ if (index < 0) {
index += 3;
+ }
if (index >= 0 && index < 3) {
Transform2D *v = _data._transform2d;
@@ -2202,7 +2214,6 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
return;
}
} else if (p_index.get_type() == Variant::STRING && p_value.get_type() == Variant::VECTOR2) {
-
//scalar name
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
Transform2D *v = _data._transform2d;
@@ -2223,24 +2234,23 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case VECTOR3: {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) {
return;
+ }
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
//scalar index
int idx = p_index;
- if (idx < 0)
+ if (idx < 0) {
idx += 3;
+ }
if (idx >= 0 && idx < 3) {
-
Vector3 *v = reinterpret_cast<Vector3 *>(_data._mem);
valid = true;
(*v)[idx] = p_value;
return;
}
} else if (p_index.get_type() == Variant::STRING) {
-
//scalar name
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
Vector3 *v = reinterpret_cast<Vector3 *>(_data._mem);
@@ -2261,24 +2271,23 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case VECTOR3I: {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) {
return;
+ }
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
//scalar index
int idx = p_index;
- if (idx < 0)
+ if (idx < 0) {
idx += 3;
+ }
if (idx >= 0 && idx < 3) {
-
Vector3i *v = reinterpret_cast<Vector3i *>(_data._mem);
valid = true;
(*v)[idx] = p_value;
return;
}
} else if (p_index.get_type() == Variant::STRING) {
-
//scalar name
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
Vector3i *v = reinterpret_cast<Vector3i *>(_data._mem);
@@ -2299,35 +2308,38 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case PLANE: {
-
if (p_index.get_type() == Variant::STRING) {
//scalar name
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
Plane *v = reinterpret_cast<Plane *>(_data._mem);
if (*str == "x") {
- if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) {
return;
+ }
valid = true;
v->normal.x = p_value;
return;
} else if (*str == "y") {
- if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) {
return;
+ }
valid = true;
v->normal.y = p_value;
return;
} else if (*str == "z") {
- if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) {
return;
+ }
valid = true;
v->normal.z = p_value;
return;
} else if (*str == "normal") {
- if (p_value.type != Variant::VECTOR3)
+ if (p_value.type != Variant::VECTOR3) {
return;
+ }
valid = true;
v->normal = p_value;
@@ -2341,12 +2353,11 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case QUAT: {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) {
return;
+ }
if (p_index.get_type() == Variant::STRING) {
-
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
Quat *v = reinterpret_cast<Quat *>(_data._mem);
if (*str == "x") {
@@ -2370,9 +2381,9 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case AABB: {
-
- if (p_value.type != Variant::VECTOR3)
+ if (p_value.type != Variant::VECTOR3) {
return;
+ }
if (p_index.get_type() == Variant::STRING) {
//scalar name
@@ -2395,16 +2406,16 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
} break;
case BASIS: {
-
- if (p_value.type != Variant::VECTOR3)
+ if (p_value.type != Variant::VECTOR3) {
return;
+ }
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
-
int index = p_index;
- if (index < 0)
+ if (index < 0) {
index += 3;
+ }
if (index >= 0 && index < 3) {
Basis *v = _data._basis;
@@ -2413,7 +2424,6 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
return;
}
} else if (p_index.get_type() == Variant::STRING) {
-
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
Basis *v = _data._basis;
@@ -2434,41 +2444,42 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case TRANSFORM: {
-
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
-
- if (p_value.type != Variant::VECTOR3)
+ if (p_value.type != Variant::VECTOR3) {
return;
+ }
int index = p_index;
- if (index < 0)
+ if (index < 0) {
index += 4;
+ }
if (index >= 0 && index < 4) {
Transform *v = _data._transform;
valid = true;
- if (index == 3)
+ if (index == 3) {
v->origin = p_value;
- else
+ } else {
v->basis.set_axis(index, p_value);
+ }
return;
}
} else if (p_index.get_type() == Variant::STRING) {
-
Transform *v = _data._transform;
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
if (*str == "basis") {
-
- if (p_value.type != Variant::BASIS)
+ if (p_value.type != Variant::BASIS) {
return;
+ }
valid = true;
v->basis = p_value;
return;
}
if (*str == "origin") {
- if (p_value.type != Variant::VECTOR3)
+ if (p_value.type != Variant::VECTOR3) {
return;
+ }
valid = true;
v->origin = p_value;
return;
@@ -2477,12 +2488,11 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
} break;
case COLOR: {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT)
+ if (p_value.type != Variant::INT && p_value.type != Variant::FLOAT) {
return;
+ }
if (p_index.get_type() == Variant::STRING) {
-
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
Color *v = reinterpret_cast<Color *>(_data._mem);
if (*str == "r") {
@@ -2531,10 +2541,10 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
return;
}
} else if (p_index.get_type() == Variant::INT) {
-
int idx = p_index;
- if (idx < 0)
+ if (idx < 0) {
idx += 4;
+ }
if (idx >= 0 && idx < 4) {
Color *v = reinterpret_cast<Color *>(_data._mem);
(*v)[idx] = p_value;
@@ -2550,14 +2560,12 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
case _RID: {
} break;
case OBJECT: {
-
Object *obj = _get_obj().obj;
//only if debugging!
if (obj) {
#ifdef DEBUG_ENABLED
if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
-
WARN_PRINT("Attempted use of previously freed pointer object.");
valid = false;
return;
@@ -2574,7 +2582,6 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
} break;
case DICTIONARY: {
-
Dictionary *dic = reinterpret_cast<Dictionary *>(_data._mem);
dic->operator[](p_index) = p_value;
valid = true; //always valid, i guess? should this really be ok?
@@ -2596,7 +2603,6 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
Variant Variant::get(const Variant &p_index, bool *r_valid) const {
-
static bool _dummy = false;
bool &valid = r_valid ? *r_valid : _dummy;
@@ -2617,16 +2623,15 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
return Variant();
} break;
case STRING: {
-
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
//string index
int idx = p_index;
const String *str = reinterpret_cast<const String *>(_data._mem);
- if (idx < 0)
+ if (idx < 0) {
idx += str->length();
+ }
if (idx >= 0 && idx < str->length()) {
-
valid = true;
return str->substr(idx, 1);
}
@@ -2634,14 +2639,13 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case VECTOR2: {
-
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
// scalar index
int idx = p_index;
- if (idx < 0)
+ if (idx < 0) {
idx += 2;
+ }
if (idx >= 0 && idx < 2) {
-
const Vector2 *v = reinterpret_cast<const Vector2 *>(_data._mem);
valid = true;
return (*v)[idx];
@@ -2662,14 +2666,13 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case VECTOR2I: {
-
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
// scalar index
int idx = p_index;
- if (idx < 0)
+ if (idx < 0) {
idx += 2;
+ }
if (idx >= 0 && idx < 2) {
-
const Vector2i *v = reinterpret_cast<const Vector2i *>(_data._mem);
valid = true;
return (*v)[idx];
@@ -2690,7 +2693,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case RECT2: {
-
if (p_index.get_type() == Variant::STRING) {
//scalar name
@@ -2709,7 +2711,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
} break;
case RECT2I: {
-
if (p_index.get_type() == Variant::STRING) {
//scalar name
@@ -2728,20 +2729,18 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
} break;
case VECTOR3: {
-
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
//scalar index
int idx = p_index;
- if (idx < 0)
+ if (idx < 0) {
idx += 3;
+ }
if (idx >= 0 && idx < 3) {
-
const Vector3 *v = reinterpret_cast<const Vector3 *>(_data._mem);
valid = true;
return (*v)[idx];
}
} else if (p_index.get_type() == Variant::STRING) {
-
//scalar name
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
const Vector3 *v = reinterpret_cast<const Vector3 *>(_data._mem);
@@ -2759,20 +2758,18 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case VECTOR3I: {
-
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
//scalar index
int idx = p_index;
- if (idx < 0)
+ if (idx < 0) {
idx += 3;
+ }
if (idx >= 0 && idx < 3) {
-
const Vector3i *v = reinterpret_cast<const Vector3i *>(_data._mem);
valid = true;
return (*v)[idx];
}
} else if (p_index.get_type() == Variant::STRING) {
-
//scalar name
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
const Vector3i *v = reinterpret_cast<const Vector3i *>(_data._mem);
@@ -2790,13 +2787,12 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case TRANSFORM2D: {
-
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
-
int index = p_index;
- if (index < 0)
+ if (index < 0) {
index += 3;
+ }
if (index >= 0 && index < 3) {
const Transform2D *v = _data._transform2d;
@@ -2804,7 +2800,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
return v->elements[index];
}
} else if (p_index.get_type() == Variant::STRING) {
-
//scalar name
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
const Transform2D *v = _data._transform2d;
@@ -2822,7 +2817,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case PLANE: {
-
if (p_index.get_type() == Variant::STRING) {
//scalar name
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
@@ -2847,9 +2841,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case QUAT: {
-
if (p_index.get_type() == Variant::STRING) {
-
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
const Quat *v = reinterpret_cast<const Quat *>(_data._mem);
if (*str == "x") {
@@ -2869,7 +2861,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case AABB: {
-
if (p_index.get_type() == Variant::STRING) {
//scalar name
@@ -2888,12 +2879,11 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
} break;
case BASIS: {
-
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
-
int index = p_index;
- if (index < 0)
+ if (index < 0) {
index += 3;
+ }
if (index >= 0 && index < 3) {
const Basis *v = _data._basis;
@@ -2901,7 +2891,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
return v->get_axis(index);
}
} else if (p_index.get_type() == Variant::STRING) {
-
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
const Basis *v = _data._basis;
@@ -2919,19 +2908,17 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case TRANSFORM: {
-
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
-
int index = p_index;
- if (index < 0)
+ if (index < 0) {
index += 4;
+ }
if (index >= 0 && index < 4) {
const Transform *v = _data._transform;
valid = true;
return index == 3 ? v->origin : v->basis.get_axis(index);
}
} else if (p_index.get_type() == Variant::STRING) {
-
const Transform *v = _data._transform;
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
@@ -2947,9 +2934,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case COLOR: {
-
if (p_index.get_type() == Variant::STRING) {
-
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
const Color *v = reinterpret_cast<const Color *>(_data._mem);
if (*str == "r") {
@@ -2987,10 +2972,10 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
return (int)Math::round(v->a * 255.0);
}
} else if (p_index.get_type() == Variant::INT) {
-
int idx = p_index;
- if (idx < 0)
+ if (idx < 0) {
idx += 4;
+ }
if (idx >= 0 && idx < 4) {
const Color *v = reinterpret_cast<const Color *>(_data._mem);
valid = true;
@@ -3008,7 +2993,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
case OBJECT: {
Object *obj = _get_obj().obj;
if (obj) {
-
#ifdef DEBUG_ENABLED
if (EngineDebugger::is_active() && !_get_obj().id.is_reference() && ObjectDB::get_instance(_get_obj().id) == nullptr) {
@@ -3026,7 +3010,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
} break;
case DICTIONARY: {
-
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
const Variant *res = dic->getptr(p_index);
if (res) {
@@ -3052,14 +3035,12 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
bool Variant::in(const Variant &p_index, bool *r_valid) const {
-
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
switch (type) {
-
case STRING: {
-
if (p_index.get_type() == Variant::STRING) {
//string index
String idx = p_index;
@@ -3072,7 +3053,6 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
case OBJECT: {
Object *obj = _get_obj().obj;
if (obj) {
-
bool valid = false;
#ifdef DEBUG_ENABLED
@@ -3093,26 +3073,25 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
return valid;
} else {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
}
return false;
} break;
case DICTIONARY: {
-
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
return dic->has(p_index);
} break;
case ARRAY: {
-
const Array *arr = reinterpret_cast<const Array *>(_data._mem);
int l = arr->size();
if (l) {
for (int i = 0; i < l; i++) {
-
- if (evaluate(OP_EQUAL, (*arr)[i], p_index))
+ if (evaluate(OP_EQUAL, (*arr)[i], p_index)) {
return true;
+ }
}
}
@@ -3121,15 +3100,15 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
} break;
case PACKED_BYTE_ARRAY: {
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
-
int index = p_index;
const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array);
int l = arr->size();
if (l) {
const uint8_t *r = arr->ptr();
for (int i = 0; i < l; i++) {
- if (r[i] == index)
+ if (r[i] == index) {
return true;
+ }
}
}
@@ -3139,15 +3118,15 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
} break;
case PACKED_INT32_ARRAY: {
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
-
int32_t index = p_index;
const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array);
int32_t l = arr->size();
if (l) {
const int32_t *r = arr->ptr();
for (int32_t i = 0; i < l; i++) {
- if (r[i] == index)
+ if (r[i] == index) {
return true;
+ }
}
}
@@ -3156,15 +3135,15 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
} break;
case PACKED_INT64_ARRAY: {
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
-
int64_t index = p_index;
const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array);
int64_t l = arr->size();
if (l) {
const int64_t *r = arr->ptr();
for (int64_t i = 0; i < l; i++) {
- if (r[i] == index)
+ if (r[i] == index) {
return true;
+ }
}
}
@@ -3172,17 +3151,16 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
}
} break;
case PACKED_FLOAT32_ARRAY: {
-
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
-
real_t index = p_index;
const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array);
int l = arr->size();
if (l) {
const float *r = arr->ptr();
for (int i = 0; i < l; i++) {
- if (r[i] == index)
+ if (r[i] == index) {
return true;
+ }
}
}
@@ -3191,17 +3169,16 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
} break;
case PACKED_FLOAT64_ARRAY: {
-
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::FLOAT) {
-
real_t index = p_index;
const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array);
int l = arr->size();
if (l) {
const double *r = arr->ptr();
for (int i = 0; i < l; i++) {
- if (r[i] == index)
+ if (r[i] == index) {
return true;
+ }
}
}
@@ -3211,7 +3188,6 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
} break;
case PACKED_STRING_ARRAY: {
if (p_index.get_type() == Variant::STRING) {
-
String index = p_index;
const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array);
@@ -3219,8 +3195,9 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
if (l) {
const String *r = arr->ptr();
for (int i = 0; i < l; i++) {
- if (r[i] == index)
+ if (r[i] == index) {
return true;
+ }
}
}
@@ -3230,7 +3207,6 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
} break; //25
case PACKED_VECTOR2_ARRAY: {
if (p_index.get_type() == Variant::VECTOR2) {
-
Vector2 index = p_index;
const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array);
@@ -3238,8 +3214,9 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
if (l) {
const Vector2 *r = arr->ptr();
for (int i = 0; i < l; i++) {
- if (r[i] == index)
+ if (r[i] == index) {
return true;
+ }
}
}
@@ -3249,7 +3226,6 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
} break;
case PACKED_VECTOR3_ARRAY: {
if (p_index.get_type() == Variant::VECTOR3) {
-
Vector3 index = p_index;
const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array);
@@ -3257,8 +3233,9 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
if (l) {
const Vector3 *r = arr->ptr();
for (int i = 0; i < l; i++) {
- if (r[i] == index)
+ if (r[i] == index) {
return true;
+ }
}
}
@@ -3267,9 +3244,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
} break;
case PACKED_COLOR_ARRAY: {
-
if (p_index.get_type() == Variant::COLOR) {
-
Color index = p_index;
const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array);
@@ -3277,8 +3252,9 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
if (l) {
const Color *r = arr->ptr();
for (int i = 0; i < l; i++) {
- if (r[i] == index)
+ if (r[i] == index) {
return true;
+ }
}
}
@@ -3289,63 +3265,55 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
}
}
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return false;
}
void Variant::get_property_list(List<PropertyInfo> *p_list) const {
-
switch (type) {
case VECTOR2: {
-
p_list->push_back(PropertyInfo(Variant::FLOAT, "x"));
p_list->push_back(PropertyInfo(Variant::FLOAT, "y"));
} break;
case VECTOR2I: {
-
p_list->push_back(PropertyInfo(Variant::INT, "x"));
p_list->push_back(PropertyInfo(Variant::INT, "y"));
} break;
case RECT2: {
-
p_list->push_back(PropertyInfo(Variant::VECTOR2, "position"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "end"));
} break;
case RECT2I: {
-
p_list->push_back(PropertyInfo(Variant::VECTOR2I, "position"));
p_list->push_back(PropertyInfo(Variant::VECTOR2I, "size"));
p_list->push_back(PropertyInfo(Variant::VECTOR2I, "end"));
} break;
case VECTOR3: {
-
p_list->push_back(PropertyInfo(Variant::FLOAT, "x"));
p_list->push_back(PropertyInfo(Variant::FLOAT, "y"));
p_list->push_back(PropertyInfo(Variant::FLOAT, "z"));
} break;
case VECTOR3I: {
-
p_list->push_back(PropertyInfo(Variant::INT, "x"));
p_list->push_back(PropertyInfo(Variant::INT, "y"));
p_list->push_back(PropertyInfo(Variant::INT, "z"));
} break;
case TRANSFORM2D: {
-
p_list->push_back(PropertyInfo(Variant::VECTOR2, "x"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "y"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "origin"));
} break;
case PLANE: {
-
p_list->push_back(PropertyInfo(Variant::VECTOR3, "normal"));
p_list->push_back(PropertyInfo(Variant::FLOAT, "x"));
p_list->push_back(PropertyInfo(Variant::FLOAT, "y"));
@@ -3354,7 +3322,6 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
} break;
case QUAT: {
-
p_list->push_back(PropertyInfo(Variant::FLOAT, "x"));
p_list->push_back(PropertyInfo(Variant::FLOAT, "y"));
p_list->push_back(PropertyInfo(Variant::FLOAT, "z"));
@@ -3367,14 +3334,12 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::VECTOR3, "end"));
} break;
case BASIS: {
-
p_list->push_back(PropertyInfo(Variant::VECTOR3, "x"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "y"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "z"));
} break;
case TRANSFORM: {
-
p_list->push_back(PropertyInfo(Variant::BASIS, "basis"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "origin"));
@@ -3400,7 +3365,6 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
case _RID: {
} break;
case OBJECT: {
-
Object *obj = _get_obj().obj;
if (obj) {
#ifdef DEBUG_ENABLED
@@ -3417,7 +3381,6 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
} break;
case DICTIONARY: {
-
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
List<Variant> keys;
dic->get_key_list(&keys);
@@ -3437,7 +3400,6 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
case PACKED_VECTOR2_ARRAY:
case PACKED_VECTOR3_ARRAY:
case PACKED_COLOR_ARRAY: {
-
//nothing
} break;
default: {
@@ -3446,7 +3408,6 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
}
bool Variant::iter_init(Variant &r_iter, bool &valid) const {
-
valid = true;
switch (type) {
case INT: {
@@ -3458,17 +3419,25 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
return _data._float > 0.0;
} break;
case VECTOR2: {
- int64_t from = reinterpret_cast<const Vector2 *>(_data._mem)->x;
- int64_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
+ double from = reinterpret_cast<const Vector2 *>(_data._mem)->x;
+ double to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
+
+ r_iter = from;
+
+ return from < to;
+ } break;
+ case VECTOR2I: {
+ int64_t from = reinterpret_cast<const Vector2i *>(_data._mem)->x;
+ int64_t to = reinterpret_cast<const Vector2i *>(_data._mem)->y;
r_iter = from;
return from < to;
} break;
case VECTOR3: {
- int64_t from = reinterpret_cast<const Vector3 *>(_data._mem)->x;
- int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
- int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
+ double from = reinterpret_cast<const Vector3 *>(_data._mem)->x;
+ double to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
+ double step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
r_iter = from;
@@ -3476,13 +3445,24 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
return false;
} else if (from < to) {
return step > 0;
- } else {
- return step < 0;
}
- //return true;
+ return step < 0;
} break;
- case OBJECT: {
+ case VECTOR3I: {
+ int64_t from = reinterpret_cast<const Vector3i *>(_data._mem)->x;
+ int64_t to = reinterpret_cast<const Vector3i *>(_data._mem)->y;
+ int64_t step = reinterpret_cast<const Vector3i *>(_data._mem)->z;
+
+ r_iter = from;
+ if (from == to) {
+ return false;
+ } else if (from < to) {
+ return step > 0;
+ }
+ return step < 0;
+ } break;
+ case OBJECT: {
if (!_get_obj().obj) {
valid = false;
return false;
@@ -3514,18 +3494,18 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
} break;
case STRING: {
-
const String *str = reinterpret_cast<const String *>(_data._mem);
- if (str->empty())
+ if (str->empty()) {
return false;
+ }
r_iter = 0;
return true;
} break;
case DICTIONARY: {
-
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
- if (dic->empty())
+ if (dic->empty()) {
return false;
+ }
const Variant *next = dic->next(nullptr);
r_iter = *next;
@@ -3533,81 +3513,87 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
} break;
case ARRAY: {
-
const Array *arr = reinterpret_cast<const Array *>(_data._mem);
- if (arr->empty())
+ if (arr->empty()) {
return false;
+ }
r_iter = 0;
return true;
} break;
case PACKED_BYTE_ARRAY: {
const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array);
- if (arr->size() == 0)
+ if (arr->size() == 0) {
return false;
+ }
r_iter = 0;
return true;
} break;
case PACKED_INT32_ARRAY: {
const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array);
- if (arr->size() == 0)
+ if (arr->size() == 0) {
return false;
+ }
r_iter = 0;
return true;
} break;
case PACKED_INT64_ARRAY: {
const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array);
- if (arr->size() == 0)
+ if (arr->size() == 0) {
return false;
+ }
r_iter = 0;
return true;
} break;
case PACKED_FLOAT32_ARRAY: {
const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array);
- if (arr->size() == 0)
+ if (arr->size() == 0) {
return false;
+ }
r_iter = 0;
return true;
} break;
case PACKED_FLOAT64_ARRAY: {
const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array);
- if (arr->size() == 0)
+ if (arr->size() == 0) {
return false;
+ }
r_iter = 0;
return true;
} break;
case PACKED_STRING_ARRAY: {
const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array);
- if (arr->size() == 0)
+ if (arr->size() == 0) {
return false;
+ }
r_iter = 0;
return true;
} break;
case PACKED_VECTOR2_ARRAY: {
-
const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array);
- if (arr->size() == 0)
+ if (arr->size() == 0) {
return false;
+ }
r_iter = 0;
return true;
} break;
case PACKED_VECTOR3_ARRAY: {
-
const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array);
- if (arr->size() == 0)
+ if (arr->size() == 0) {
return false;
+ }
r_iter = 0;
return true;
} break;
case PACKED_COLOR_ARRAY: {
-
const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array);
- if (arr->size() == 0)
+ if (arr->size() == 0) {
return false;
+ }
r_iter = 0;
return true;
@@ -3619,56 +3605,91 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
valid = false;
return false;
}
-bool Variant::iter_next(Variant &r_iter, bool &valid) const {
+bool Variant::iter_next(Variant &r_iter, bool &valid) const {
valid = true;
switch (type) {
case INT: {
int64_t idx = r_iter;
idx++;
- if (idx >= _data._int)
+ if (idx >= _data._int) {
return false;
+ }
r_iter = idx;
return true;
} break;
case FLOAT: {
int64_t idx = r_iter;
idx++;
- if (idx >= _data._float)
+ if (idx >= _data._float) {
return false;
+ }
r_iter = idx;
return true;
} break;
case VECTOR2: {
- int64_t to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
+ double to = reinterpret_cast<const Vector2 *>(_data._mem)->y;
+
+ double idx = r_iter;
+ idx++;
+
+ if (idx >= to) {
+ return false;
+ }
+
+ r_iter = idx;
+ return true;
+ } break;
+ case VECTOR2I: {
+ int64_t to = reinterpret_cast<const Vector2i *>(_data._mem)->y;
int64_t idx = r_iter;
idx++;
- if (idx >= to)
+ if (idx >= to) {
return false;
+ }
r_iter = idx;
return true;
} break;
case VECTOR3: {
- int64_t to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
- int64_t step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
+ double to = reinterpret_cast<const Vector3 *>(_data._mem)->y;
+ double step = reinterpret_cast<const Vector3 *>(_data._mem)->z;
+
+ double idx = r_iter;
+ idx += step;
+
+ if (step < 0 && idx <= to) {
+ return false;
+ }
+
+ if (step > 0 && idx >= to) {
+ return false;
+ }
+
+ r_iter = idx;
+ return true;
+ } break;
+ case VECTOR3I: {
+ int64_t to = reinterpret_cast<const Vector3i *>(_data._mem)->y;
+ int64_t step = reinterpret_cast<const Vector3i *>(_data._mem)->z;
int64_t idx = r_iter;
idx += step;
- if (step < 0 && idx <= to)
+ if (step < 0 && idx <= to) {
return false;
+ }
- if (step > 0 && idx >= to)
+ if (step > 0 && idx >= to) {
return false;
+ }
r_iter = idx;
return true;
} break;
case OBJECT: {
-
if (!_get_obj().obj) {
valid = false;
return false;
@@ -3701,33 +3722,33 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
} break;
case STRING: {
-
const String *str = reinterpret_cast<const String *>(_data._mem);
int idx = r_iter;
idx++;
- if (idx >= str->length())
+ if (idx >= str->length()) {
return false;
+ }
r_iter = idx;
return true;
} break;
case DICTIONARY: {
-
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
const Variant *next = dic->next(&r_iter);
- if (!next)
+ if (!next) {
return false;
+ }
r_iter = *next;
return true;
} break;
case ARRAY: {
-
const Array *arr = reinterpret_cast<const Array *>(_data._mem);
int idx = r_iter;
idx++;
- if (idx >= arr->size())
+ if (idx >= arr->size()) {
return false;
+ }
r_iter = idx;
return true;
} break;
@@ -3735,8 +3756,9 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
const Vector<uint8_t> *arr = &PackedArrayRef<uint8_t>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
- if (idx >= arr->size())
+ if (idx >= arr->size()) {
return false;
+ }
r_iter = idx;
return true;
@@ -3745,8 +3767,9 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
const Vector<int32_t> *arr = &PackedArrayRef<int32_t>::get_array(_data.packed_array);
int32_t idx = r_iter;
idx++;
- if (idx >= arr->size())
+ if (idx >= arr->size()) {
return false;
+ }
r_iter = idx;
return true;
@@ -3755,8 +3778,9 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
const Vector<int64_t> *arr = &PackedArrayRef<int64_t>::get_array(_data.packed_array);
int64_t idx = r_iter;
idx++;
- if (idx >= arr->size())
+ if (idx >= arr->size()) {
return false;
+ }
r_iter = idx;
return true;
@@ -3765,8 +3789,9 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
const Vector<float> *arr = &PackedArrayRef<float>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
- if (idx >= arr->size())
+ if (idx >= arr->size()) {
return false;
+ }
r_iter = idx;
return true;
@@ -3775,8 +3800,9 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
const Vector<double> *arr = &PackedArrayRef<double>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
- if (idx >= arr->size())
+ if (idx >= arr->size()) {
return false;
+ }
r_iter = idx;
return true;
@@ -3785,38 +3811,39 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
const Vector<String> *arr = &PackedArrayRef<String>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
- if (idx >= arr->size())
+ if (idx >= arr->size()) {
return false;
+ }
r_iter = idx;
return true;
} break;
case PACKED_VECTOR2_ARRAY: {
-
const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
- if (idx >= arr->size())
+ if (idx >= arr->size()) {
return false;
+ }
r_iter = idx;
return true;
} break;
case PACKED_VECTOR3_ARRAY: {
-
const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
- if (idx >= arr->size())
+ if (idx >= arr->size()) {
return false;
+ }
r_iter = idx;
return true;
} break;
case PACKED_COLOR_ARRAY: {
-
const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array);
int idx = r_iter;
idx++;
- if (idx >= arr->size())
+ if (idx >= arr->size()) {
return false;
+ }
r_iter = idx;
return true;
} break;
@@ -3829,27 +3856,27 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
}
Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
-
r_valid = true;
switch (type) {
case INT: {
-
return r_iter;
} break;
case FLOAT: {
-
return r_iter;
} break;
case VECTOR2: {
-
+ return r_iter;
+ } break;
+ case VECTOR2I: {
return r_iter;
} break;
case VECTOR3: {
-
+ return r_iter;
+ } break;
+ case VECTOR3I: {
return r_iter;
} break;
case OBJECT: {
-
if (!_get_obj().obj) {
r_valid = false;
return Variant();
@@ -3877,17 +3904,14 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
} break;
case STRING: {
-
const String *str = reinterpret_cast<const String *>(_data._mem);
return str->substr(r_iter, 1);
} break;
case DICTIONARY: {
-
return r_iter; //iterator is the same as the key
} break;
case ARRAY: {
-
const Array *arr = reinterpret_cast<const Array *>(_data._mem);
int idx = r_iter;
#ifdef DEBUG_ENABLED
@@ -3965,7 +3989,6 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
return arr->get(idx);
} break;
case PACKED_VECTOR2_ARRAY: {
-
const Vector<Vector2> *arr = &PackedArrayRef<Vector2>::get_array(_data.packed_array);
int idx = r_iter;
#ifdef DEBUG_ENABLED
@@ -3977,7 +4000,6 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
return arr->get(idx);
} break;
case PACKED_VECTOR3_ARRAY: {
-
const Vector<Vector3> *arr = &PackedArrayRef<Vector3>::get_array(_data.packed_array);
int idx = r_iter;
#ifdef DEBUG_ENABLED
@@ -3989,7 +4011,6 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
return arr->get(idx);
} break;
case PACKED_COLOR_ARRAY: {
-
const Vector<Color> *arr = &PackedArrayRef<Color>::get_array(_data.packed_array);
int idx = r_iter;
#ifdef DEBUG_ENABLED
@@ -4142,7 +4163,6 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst)
}
void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &r_dst) {
-
if (a.type != b.type) {
if (a.is_num() && b.is_num()) {
//not as efficient but..
@@ -4157,7 +4177,6 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
switch (a.type) {
-
case NIL: {
r_dst = Variant();
}
@@ -4195,22 +4214,21 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
int split = csize / 2;
for (int i = 0; i < csize; i++) {
-
CharType chr = ' ';
if (i < split) {
-
- if (i < sa.length())
+ if (i < sa.length()) {
chr = sa[i];
- else if (i < sb.length())
+ } else if (i < sb.length()) {
chr = sb[i];
+ }
} else {
-
- if (i < sb.length())
+ if (i < sb.length()) {
chr = sb[i];
- else if (i < sa.length())
+ } else if (i < sa.length()) {
chr = sa[i];
+ }
}
dst[i] = chr;
@@ -4220,7 +4238,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case VECTOR2: {
- r_dst = reinterpret_cast<const Vector2 *>(a._data._mem)->linear_interpolate(*reinterpret_cast<const Vector2 *>(b._data._mem), c);
+ r_dst = reinterpret_cast<const Vector2 *>(a._data._mem)->lerp(*reinterpret_cast<const Vector2 *>(b._data._mem), c);
}
return;
case VECTOR2I: {
@@ -4233,7 +4251,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
return;
case RECT2: {
- r_dst = Rect2(reinterpret_cast<const Rect2 *>(a._data._mem)->position.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->position, c), reinterpret_cast<const Rect2 *>(a._data._mem)->size.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->size, c));
+ r_dst = Rect2(reinterpret_cast<const Rect2 *>(a._data._mem)->position.lerp(reinterpret_cast<const Rect2 *>(b._data._mem)->position, c), reinterpret_cast<const Rect2 *>(a._data._mem)->size.lerp(reinterpret_cast<const Rect2 *>(b._data._mem)->size, c));
}
return;
case RECT2I: {
@@ -4254,7 +4272,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
return;
case VECTOR3: {
- r_dst = reinterpret_cast<const Vector3 *>(a._data._mem)->linear_interpolate(*reinterpret_cast<const Vector3 *>(b._data._mem), c);
+ r_dst = reinterpret_cast<const Vector3 *>(a._data._mem)->lerp(*reinterpret_cast<const Vector3 *>(b._data._mem), c);
}
return;
case VECTOR3I: {
@@ -4281,7 +4299,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case AABB: {
- r_dst = ::AABB(a._data._aabb->position.linear_interpolate(b._data._aabb->position, c), a._data._aabb->size.linear_interpolate(b._data._aabb->size, c));
+ r_dst = ::AABB(a._data._aabb->position.lerp(b._data._aabb->position, c), a._data._aabb->size.lerp(b._data._aabb->size, c));
}
return;
case BASIS: {
@@ -4293,7 +4311,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case COLOR: {
- r_dst = reinterpret_cast<const Color *>(a._data._mem)->linear_interpolate(*reinterpret_cast<const Color *>(b._data._mem), c);
+ r_dst = reinterpret_cast<const Color *>(a._data._mem)->lerp(*reinterpret_cast<const Color *>(b._data._mem), c);
}
return;
case STRING_NAME: {
@@ -4328,10 +4346,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
const Vector<int32_t> *arr_b = &PackedArrayRef<int32_t>::get_array(b._data.packed_array);
int32_t sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
-
r_dst = a;
} else {
-
Vector<int32_t> v;
v.resize(sz);
{
@@ -4354,10 +4370,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
const Vector<int64_t> *arr_b = &PackedArrayRef<int64_t>::get_array(b._data.packed_array);
int64_t sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
-
r_dst = a;
} else {
-
Vector<int64_t> v;
v.resize(sz);
{
@@ -4380,10 +4394,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
const Vector<float> *arr_b = &PackedArrayRef<float>::get_array(b._data.packed_array);
int sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
-
r_dst = a;
} else {
-
Vector<float> v;
v.resize(sz);
{
@@ -4406,10 +4418,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
const Vector<double> *arr_b = &PackedArrayRef<double>::get_array(b._data.packed_array);
int sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
-
r_dst = a;
} else {
-
Vector<double> v;
v.resize(sz);
{
@@ -4436,10 +4446,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
const Vector<Vector2> *arr_b = &PackedArrayRef<Vector2>::get_array(b._data.packed_array);
int sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
-
r_dst = a;
} else {
-
Vector<Vector2> v;
v.resize(sz);
{
@@ -4448,7 +4456,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
const Vector2 *br = arr_b->ptr();
for (int i = 0; i < sz; i++) {
- vw[i] = ar[i].linear_interpolate(br[i], c);
+ vw[i] = ar[i].lerp(br[i], c);
}
}
r_dst = v;
@@ -4456,15 +4464,12 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case PACKED_VECTOR3_ARRAY: {
-
const Vector<Vector3> *arr_a = &PackedArrayRef<Vector3>::get_array(a._data.packed_array);
const Vector<Vector3> *arr_b = &PackedArrayRef<Vector3>::get_array(b._data.packed_array);
int sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
-
r_dst = a;
} else {
-
Vector<Vector3> v;
v.resize(sz);
{
@@ -4473,7 +4478,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
const Vector3 *br = arr_b->ptr();
for (int i = 0; i < sz; i++) {
- vw[i] = ar[i].linear_interpolate(br[i], c);
+ vw[i] = ar[i].lerp(br[i], c);
}
}
r_dst = v;
@@ -4485,10 +4490,8 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
const Vector<Color> *arr_b = &PackedArrayRef<Color>::get_array(b._data.packed_array);
int sz = arr_a->size();
if (sz == 0 || arr_b->size() != sz) {
-
r_dst = a;
} else {
-
Vector<Color> v;
v.resize(sz);
{
@@ -4497,7 +4500,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
const Color *br = arr_b->ptr();
for (int i = 0; i < sz; i++) {
- vw[i] = ar[i].linear_interpolate(br[i], c);
+ vw[i] = ar[i].lerp(br[i], c);
}
}
r_dst = v;
@@ -4505,7 +4508,6 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
default: {
-
r_dst = a;
}
}
@@ -4541,7 +4543,6 @@ static const char *_op_names[Variant::OP_MAX] = {
};
String Variant::get_operator_name(Operator p_op) {
-
ERR_FAIL_INDEX_V(p_op, OP_MAX, "");
return _op_names[p_op];
}
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 0a578faf78..bdcad03353 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -36,21 +36,18 @@
#include "core/string_buffer.h"
CharType VariantParser::StreamFile::get_char() {
-
return f->get_8();
}
bool VariantParser::StreamFile::is_utf8() const {
-
return true;
}
-bool VariantParser::StreamFile::is_eof() const {
+bool VariantParser::StreamFile::is_eof() const {
return f->eof_reached();
}
CharType VariantParser::StreamString::get_char() {
-
if (pos > s.length()) {
return 0;
} else if (pos == s.length()) {
@@ -66,6 +63,7 @@ CharType VariantParser::StreamString::get_char() {
bool VariantParser::StreamString::is_utf8() const {
return false;
}
+
bool VariantParser::StreamString::is_eof() const {
return pos > s.length();
}
@@ -93,11 +91,9 @@ const char *VariantParser::tk_name[TK_MAX] = {
};
Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, String &r_err_str) {
-
bool string_name = false;
while (true) {
-
CharType cchar;
if (p_stream->saved) {
cchar = p_stream->saved;
@@ -111,82 +107,69 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
}
switch (cchar) {
-
case '\n': {
-
line++;
break;
- };
+ }
case 0: {
r_token.type = TK_EOF;
return OK;
} break;
case '{': {
-
r_token.type = TK_CURLY_BRACKET_OPEN;
return OK;
- };
+ }
case '}': {
-
r_token.type = TK_CURLY_BRACKET_CLOSE;
return OK;
- };
+ }
case '[': {
-
r_token.type = TK_BRACKET_OPEN;
return OK;
- };
+ }
case ']': {
-
r_token.type = TK_BRACKET_CLOSE;
return OK;
- };
+ }
case '(': {
-
r_token.type = TK_PARENTHESIS_OPEN;
return OK;
- };
+ }
case ')': {
-
r_token.type = TK_PARENTHESIS_CLOSE;
return OK;
- };
+ }
case ':': {
-
r_token.type = TK_COLON;
return OK;
- };
+ }
case ';': {
-
while (true) {
CharType ch = p_stream->get_char();
if (p_stream->is_eof()) {
r_token.type = TK_EOF;
return OK;
}
- if (ch == '\n')
+ if (ch == '\n') {
break;
+ }
}
break;
- };
+ }
case ',': {
-
r_token.type = TK_COMMA;
return OK;
- };
+ }
case '.': {
-
r_token.type = TK_PERIOD;
return OK;
- };
+ }
case '=': {
-
r_token.type = TK_EQUAL;
return OK;
- };
+ }
case '#': {
-
StringBuffer<> color_str;
color_str += '#';
while (true) {
@@ -206,7 +189,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
r_token.value = Color::html(color_str.as_string());
r_token.type = TK_COLOR;
return OK;
- };
+ }
case '@': {
cchar = p_stream->get_char();
if (cchar != '"') {
@@ -219,10 +202,8 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
[[fallthrough]];
}
case '"': {
-
String str;
while (true) {
-
CharType ch = p_stream->get_char();
if (ch == 0) {
@@ -242,12 +223,21 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
CharType res = 0;
switch (next) {
-
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'f': res = 12; break;
- case 'r': res = 13; break;
+ case 'b':
+ res = 8;
+ break;
+ case 't':
+ res = 9;
+ break;
+ case 'n':
+ res = 10;
+ break;
+ case 'f':
+ res = 12;
+ break;
+ case 'r':
+ res = 13;
+ break;
case 'u': {
//hex number
for (int j = 0; j < 4; j++) {
@@ -258,7 +248,6 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
return ERR_PARSE_ERROR;
}
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
-
r_err_str = "Malformed hex constant in string";
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
@@ -290,8 +279,9 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
str += res;
} else {
- if (ch == '\n')
+ if (ch == '\n') {
line++;
+ }
str += ch;
}
}
@@ -311,7 +301,6 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
} break;
default: {
-
if (cchar <= 32) {
break;
}
@@ -338,10 +327,8 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
bool is_float = false;
while (true) {
-
switch (reading) {
case READING_INT: {
-
if (c >= '0' && c <= '9') {
//pass
} else if (c == '.') {
@@ -356,9 +343,7 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
} break;
case READING_DEC: {
-
if (c >= '0' && c <= '9') {
-
} else if (c == 'e') {
reading = READING_EXP;
} else {
@@ -367,7 +352,6 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
} break;
case READING_EXP: {
-
if (c >= '0' && c <= '9') {
exp_beg = true;
@@ -380,8 +364,9 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
} break;
}
- if (reading == READING_DONE)
+ if (reading == READING_DONE) {
break;
+ }
num += c;
c = p_stream->get_char();
}
@@ -390,19 +375,18 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
r_token.type = TK_NUMBER;
- if (is_float)
+ if (is_float) {
r_token.value = num.as_double();
- else
+ } else {
r_token.value = num.as_int();
+ }
return OK;
} else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') {
-
StringBuffer<> id;
bool first = true;
while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && cchar >= '0' && cchar <= '9')) {
-
id += cchar;
cchar = p_stream->get_char();
first = false;
@@ -427,7 +411,6 @@ Error VariantParser::get_token(Stream *p_stream, Token &r_token, int &line, Stri
}
Error VariantParser::_parse_enginecfg(Stream *p_stream, Vector<String> &strings, int &line, String &r_err_str) {
-
Token token;
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_OPEN) {
@@ -438,7 +421,6 @@ Error VariantParser::_parse_enginecfg(Stream *p_stream, Vector<String> &strings,
String accum;
while (true) {
-
CharType c = p_stream->get_char();
if (p_stream->is_eof()) {
@@ -460,7 +442,6 @@ Error VariantParser::_parse_enginecfg(Stream *p_stream, Vector<String> &strings,
template <class T>
Error VariantParser::_parse_construct(Stream *p_stream, Vector<T> &r_construct, int &line, String &r_err_str) {
-
Token token;
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_OPEN) {
@@ -470,7 +451,6 @@ Error VariantParser::_parse_construct(Stream *p_stream, Vector<T> &r_construct,
bool first = true;
while (true) {
-
if (!first) {
get_token(p_stream, token, line, r_err_str);
if (token.type == TK_COMMA) {
@@ -499,7 +479,6 @@ Error VariantParser::_parse_construct(Stream *p_stream, Vector<T> &r_construct,
}
Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) {
-
/* {
Error err = get_token(p_stream,token,line,r_err_str);
if (err)
@@ -507,41 +486,40 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}*/
if (token.type == TK_CURLY_BRACKET_OPEN) {
-
Dictionary d;
Error err = _parse_dictionary(d, p_stream, line, r_err_str, p_res_parser);
- if (err)
+ if (err) {
return err;
+ }
value = d;
return OK;
} else if (token.type == TK_BRACKET_OPEN) {
-
Array a;
Error err = _parse_array(a, p_stream, line, r_err_str, p_res_parser);
- if (err)
+ if (err) {
return err;
+ }
value = a;
return OK;
} else if (token.type == TK_IDENTIFIER) {
-
String id = token.value;
- if (id == "true")
+ if (id == "true") {
value = true;
- else if (id == "false")
+ } else if (id == "false") {
value = false;
- else if (id == "null" || id == "nil")
+ } else if (id == "null" || id == "nil") {
value = Variant();
- else if (id == "inf")
+ } else if (id == "inf") {
value = Math_INF;
- else if (id == "nan")
+ } else if (id == "nan") {
value = Math_NAN;
- else if (id == "Vector2") {
-
+ } else if (id == "Vector2") {
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 2) {
r_err_str = "Expected 2 arguments for constructor";
@@ -550,11 +528,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = Vector2(args[0], args[1]);
return OK;
} else if (id == "Vector2i") {
-
Vector<int32_t> args;
Error err = _parse_construct<int32_t>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 2) {
r_err_str = "Expected 2 arguments for constructor";
@@ -563,11 +541,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = Vector2i(args[0], args[1]);
return OK;
} else if (id == "Rect2") {
-
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 4) {
r_err_str = "Expected 4 arguments for constructor";
@@ -576,11 +554,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = Rect2(args[0], args[1], args[2], args[3]);
return OK;
} else if (id == "Rect2i") {
-
Vector<int32_t> args;
Error err = _parse_construct<int32_t>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 4) {
r_err_str = "Expected 4 arguments for constructor";
@@ -589,11 +567,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = Rect2i(args[0], args[1], args[2], args[3]);
return OK;
} else if (id == "Vector3") {
-
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 3) {
r_err_str = "Expected 3 arguments for constructor";
@@ -602,11 +580,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = Vector3(args[0], args[1], args[2]);
return OK;
} else if (id == "Vector3i") {
-
Vector<int32_t> args;
Error err = _parse_construct<int32_t>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 3) {
r_err_str = "Expected 3 arguments for constructor";
@@ -618,8 +596,9 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 6) {
r_err_str = "Expected 6 arguments for constructor";
@@ -631,11 +610,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = m;
return OK;
} else if (id == "Plane") {
-
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 4) {
r_err_str = "Expected 4 arguments for constructor";
@@ -644,11 +623,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = Plane(args[0], args[1], args[2], args[3]);
return OK;
} else if (id == "Quat") {
-
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 4) {
r_err_str = "Expected 4 arguments for constructor";
@@ -658,11 +637,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "AABB" || id == "Rect3") {
-
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 6) {
r_err_str = "Expected 6 arguments for constructor";
@@ -675,8 +654,9 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 9) {
r_err_str = "Expected 9 arguments for constructor";
@@ -685,11 +665,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = Basis(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
return OK;
} else if (id == "Transform") {
-
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 12) {
r_err_str = "Expected 12 arguments for constructor";
@@ -699,11 +679,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "Color") {
-
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (args.size() != 4) {
r_err_str = "Expected 4 arguments for constructor";
@@ -713,7 +693,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "NodePath") {
-
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_OPEN) {
r_err_str = "Expected '('";
@@ -735,7 +714,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
} else if (id == "RID") {
-
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_OPEN) {
r_err_str = "Expected '('";
@@ -758,7 +736,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "Object") {
-
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_OPEN) {
r_err_str = "Expected '('";
@@ -793,17 +770,16 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
bool need_comma = false;
while (true) {
-
if (p_stream->is_eof()) {
r_err_str = "Unexpected End of File while parsing Object()";
return ERR_FILE_CORRUPT;
}
if (at_key) {
-
Error err = get_token(p_stream, token2, line, r_err_str);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
if (token2.type == TK_PARENTHESIS_CLOSE) {
Reference *reference = Object::cast_to<Reference>(obj);
@@ -816,9 +792,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
if (need_comma) {
-
if (token2.type != TK_COMMA) {
-
r_err_str = "Expected '}' or ','";
return ERR_PARSE_ERROR;
} else {
@@ -836,24 +810,25 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
err = get_token(p_stream, token2, line, r_err_str);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
if (token2.type != TK_COLON) {
-
r_err_str = "Expected ':'";
return ERR_PARSE_ERROR;
}
at_key = false;
} else {
-
Error err = get_token(p_stream, token2, line, r_err_str);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
Variant v;
err = parse_value(token2, v, p_stream, line, r_err_str, p_res_parser);
- if (err)
+ if (err) {
return err;
+ }
obj->set(key, v);
need_comma = true;
at_key = true;
@@ -861,7 +836,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
} else if (id == "Resource" || id == "SubResource" || id == "ExtResource") {
-
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_OPEN) {
r_err_str = "Expected '('";
@@ -869,37 +843,36 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
if (p_res_parser && id == "Resource" && p_res_parser->func) {
-
RES res;
Error err = p_res_parser->func(p_res_parser->userdata, p_stream, res, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
value = res;
return OK;
} else if (p_res_parser && id == "ExtResource" && p_res_parser->ext_func) {
-
RES res;
Error err = p_res_parser->ext_func(p_res_parser->userdata, p_stream, res, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
value = res;
return OK;
} else if (p_res_parser && id == "SubResource" && p_res_parser->sub_func) {
-
RES res;
Error err = p_res_parser->sub_func(p_res_parser->userdata, p_stream, res, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
value = res;
return OK;
} else {
-
get_token(p_stream, token, line, r_err_str);
if (token.type == TK_STRING) {
String path = token.value;
@@ -925,11 +898,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
} else if (id == "PackedByteArray" || id == "PoolByteArray" || id == "ByteArray") {
-
Vector<uint8_t> args;
Error err = _parse_construct<uint8_t>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
Vector<uint8_t> arr;
{
@@ -946,11 +919,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "PackedInt32Array" || id == "PackedIntArray" || id == "PoolIntArray" || id == "IntArray") {
-
Vector<int32_t> args;
Error err = _parse_construct<int32_t>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
Vector<int32_t> arr;
{
@@ -967,11 +940,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "PackedInt64Array") {
-
Vector<int64_t> args;
Error err = _parse_construct<int64_t>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
Vector<int64_t> arr;
{
@@ -988,11 +961,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "PackedFloat32Array" || id == "PackedRealArray" || id == "PoolRealArray" || id == "FloatArray") {
-
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
Vector<float> arr;
{
@@ -1008,11 +981,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "PackedFloat64Array") {
-
Vector<double> args;
Error err = _parse_construct<double>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
Vector<double> arr;
{
@@ -1028,7 +1001,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "PackedStringArray" || id == "PoolStringArray" || id == "StringArray") {
-
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_OPEN) {
r_err_str = "Expected '('";
@@ -1039,7 +1011,6 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
bool first = true;
while (true) {
-
if (!first) {
get_token(p_stream, token, line, r_err_str);
if (token.type == TK_COMMA) {
@@ -1079,11 +1050,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "PackedVector2Array" || id == "PoolVector2Array" || id == "Vector2Array") {
-
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
Vector<Vector2> arr;
{
@@ -1100,11 +1071,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "PackedVector3Array" || id == "PoolVector3Array" || id == "Vector3Array") {
-
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
Vector<Vector3> arr;
{
@@ -1121,11 +1092,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (id == "PackedColorArray" || id == "PoolColorArray" || id == "ColorArray") {
-
Vector<float> args;
Error err = _parse_construct<float>(p_stream, args, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
Vector<Color> arr;
{
@@ -1148,19 +1119,15 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (token.type == TK_NUMBER) {
-
value = token.value;
return OK;
} else if (token.type == TK_STRING) {
-
value = token.value;
return OK;
} else if (token.type == TK_STRING_NAME) {
-
value = token.value;
return OK;
} else if (token.type == TK_COLOR) {
-
value = token.value;
return OK;
} else {
@@ -1170,30 +1137,26 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
Error VariantParser::_parse_array(Array &array, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) {
-
Token token;
bool need_comma = false;
while (true) {
-
if (p_stream->is_eof()) {
r_err_str = "Unexpected End of File while parsing array";
return ERR_FILE_CORRUPT;
}
Error err = get_token(p_stream, token, line, r_err_str);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
if (token.type == TK_BRACKET_CLOSE) {
-
return OK;
}
if (need_comma) {
-
if (token.type != TK_COMMA) {
-
r_err_str = "Expected ','";
return ERR_PARSE_ERROR;
} else {
@@ -1204,8 +1167,9 @@ Error VariantParser::_parse_array(Array &array, Stream *p_stream, int &line, Str
Variant v;
err = parse_value(token, v, p_stream, line, r_err_str, p_res_parser);
- if (err)
+ if (err) {
return err;
+ }
array.push_back(v);
need_comma = true;
@@ -1213,34 +1177,29 @@ Error VariantParser::_parse_array(Array &array, Stream *p_stream, int &line, Str
}
Error VariantParser::_parse_dictionary(Dictionary &object, Stream *p_stream, int &line, String &r_err_str, ResourceParser *p_res_parser) {
-
bool at_key = true;
Variant key;
Token token;
bool need_comma = false;
while (true) {
-
if (p_stream->is_eof()) {
r_err_str = "Unexpected End of File while parsing dictionary";
return ERR_FILE_CORRUPT;
}
if (at_key) {
-
Error err = get_token(p_stream, token, line, r_err_str);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
if (token.type == TK_CURLY_BRACKET_CLOSE) {
-
return OK;
}
if (need_comma) {
-
if (token.type != TK_COMMA) {
-
r_err_str = "Expected '}' or ','";
return ERR_PARSE_ERROR;
} else {
@@ -1251,29 +1210,31 @@ Error VariantParser::_parse_dictionary(Dictionary &object, Stream *p_stream, int
err = parse_value(token, key, p_stream, line, r_err_str, p_res_parser);
- if (err)
+ if (err) {
return err;
+ }
err = get_token(p_stream, token, line, r_err_str);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
if (token.type != TK_COLON) {
-
r_err_str = "Expected ':'";
return ERR_PARSE_ERROR;
}
at_key = false;
} else {
-
Error err = get_token(p_stream, token, line, r_err_str);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
Variant v;
err = parse_value(token, v, p_stream, line, r_err_str, p_res_parser);
- if (err)
+ if (err) {
return err;
+ }
object[key] = v;
need_comma = true;
at_key = true;
@@ -1282,7 +1243,6 @@ Error VariantParser::_parse_dictionary(Dictionary &object, Stream *p_stream, int
}
Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, String &r_err_str, Tag &r_tag, ResourceParser *p_res_parser, bool p_simple_tag) {
-
r_tag.fields.clear();
if (token.type != TK_BRACKET_OPEN) {
@@ -1291,19 +1251,18 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin
}
if (p_simple_tag) {
-
r_tag.name = "";
r_tag.fields.clear();
while (true) {
-
CharType c = p_stream->get_char();
if (p_stream->is_eof()) {
r_err_str = "Unexpected EOF while parsing simple tag";
return ERR_PARSE_ERROR;
}
- if (c == ']')
+ if (c == ']') {
break;
+ }
r_tag.name += String::chr(c);
}
@@ -1323,15 +1282,15 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin
bool parsing_tag = true;
while (true) {
-
if (p_stream->is_eof()) {
r_err_str = "Unexpected End of File while parsing tag: " + r_tag.name;
return ERR_FILE_CORRUPT;
}
get_token(p_stream, token, line, r_err_str);
- if (token.type == TK_BRACKET_CLOSE)
+ if (token.type == TK_BRACKET_CLOSE) {
break;
+ }
if (parsing_tag && token.type == TK_PERIOD) {
r_tag.name += "."; //support tags such as [someprop.Android] for specific platforms
@@ -1363,8 +1322,9 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin
get_token(p_stream, token, line, r_err_str);
Variant value;
Error err = parse_value(token, value, p_stream, line, r_err_str, p_res_parser);
- if (err)
+ if (err) {
return err;
+ }
r_tag.fields[id] = value;
}
@@ -1373,7 +1333,6 @@ Error VariantParser::_parse_tag(Token &token, Stream *p_stream, int &line, Strin
}
Error VariantParser::parse_tag(Stream *p_stream, int &line, String &r_err_str, Tag &r_tag, ResourceParser *p_res_parser, bool p_simple_tag) {
-
Token token;
get_token(p_stream, token, line, r_err_str);
@@ -1390,13 +1349,11 @@ Error VariantParser::parse_tag(Stream *p_stream, int &line, String &r_err_str, T
}
Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r_err_str, Tag &r_tag, String &r_assign, Variant &r_value, ResourceParser *p_res_parser, bool p_simple_tag) {
-
//assign..
r_assign = "";
String what;
while (true) {
-
CharType c;
if (p_stream->saved) {
c = p_stream->saved;
@@ -1406,8 +1363,9 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r
c = p_stream->get_char();
}
- if (p_stream->is_eof())
+ if (p_stream->is_eof()) {
return ERR_FILE_EOF;
+ }
if (c == ';') { //comment
while (true) {
@@ -1415,8 +1373,9 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r
if (p_stream->is_eof()) {
return ERR_FILE_EOF;
}
- if (ch == '\n')
+ if (ch == '\n') {
break;
+ }
}
continue;
}
@@ -1435,8 +1394,9 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r
p_stream->saved = '"';
Token tk;
Error err = get_token(p_stream, tk, line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (tk.type != TK_STRING) {
r_err_str = "Error reading quoted string";
return ERR_INVALID_DATA;
@@ -1460,11 +1420,11 @@ Error VariantParser::parse_tag_assign_eof(Stream *p_stream, int &line, String &r
}
Error VariantParser::parse(Stream *p_stream, Variant &r_ret, String &r_err_str, int &r_err_line, ResourceParser *p_res_parser) {
-
Token token;
Error err = get_token(p_stream, token, r_err_line, r_err_str);
- if (err)
+ if (err) {
return err;
+ }
if (token.type == TK_EOF) {
return ERR_FILE_EOF;
@@ -1478,103 +1438,88 @@ Error VariantParser::parse(Stream *p_stream, Variant &r_ret, String &r_err_str,
////////////////////////////////////////////////////////////////////////////////
static String rtosfix(double p_value) {
-
- if (p_value == 0.0)
+ if (p_value == 0.0) {
return "0"; //avoid negative zero (-0) being written, which may annoy git, svn, etc. for changes when they don't exist.
- else
+ } else {
return rtoss(p_value);
+ }
}
Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_string_func, void *p_store_string_ud, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud) {
-
switch (p_variant.get_type()) {
-
case Variant::NIL: {
p_store_string_func(p_store_string_ud, "null");
} break;
case Variant::BOOL: {
-
p_store_string_func(p_store_string_ud, p_variant.operator bool() ? "true" : "false");
} break;
case Variant::INT: {
-
p_store_string_func(p_store_string_ud, itos(p_variant.operator int64_t()));
} break;
case Variant::FLOAT: {
-
String s = rtosfix(p_variant.operator real_t());
if (s != "inf" && s != "nan") {
- if (s.find(".") == -1 && s.find("e") == -1)
+ if (s.find(".") == -1 && s.find("e") == -1) {
s += ".0";
+ }
}
p_store_string_func(p_store_string_ud, s);
} break;
case Variant::STRING: {
-
String str = p_variant;
str = "\"" + str.c_escape_multiline() + "\"";
p_store_string_func(p_store_string_ud, str);
} break;
case Variant::VECTOR2: {
-
Vector2 v = p_variant;
p_store_string_func(p_store_string_ud, "Vector2( " + rtosfix(v.x) + ", " + rtosfix(v.y) + " )");
} break;
case Variant::VECTOR2I: {
-
Vector2i v = p_variant;
p_store_string_func(p_store_string_ud, "Vector2i( " + itos(v.x) + ", " + itos(v.y) + " )");
} break;
case Variant::RECT2: {
-
Rect2 aabb = p_variant;
p_store_string_func(p_store_string_ud, "Rect2( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + " )");
} break;
case Variant::RECT2I: {
-
Rect2i aabb = p_variant;
p_store_string_func(p_store_string_ud, "Rect2i( " + itos(aabb.position.x) + ", " + itos(aabb.position.y) + ", " + itos(aabb.size.x) + ", " + itos(aabb.size.y) + " )");
} break;
case Variant::VECTOR3: {
-
Vector3 v = p_variant;
p_store_string_func(p_store_string_ud, "Vector3( " + rtosfix(v.x) + ", " + rtosfix(v.y) + ", " + rtosfix(v.z) + " )");
} break;
case Variant::VECTOR3I: {
-
Vector3i v = p_variant;
p_store_string_func(p_store_string_ud, "Vector3i( " + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + " )");
} break;
case Variant::PLANE: {
-
Plane p = p_variant;
p_store_string_func(p_store_string_ud, "Plane( " + rtosfix(p.normal.x) + ", " + rtosfix(p.normal.y) + ", " + rtosfix(p.normal.z) + ", " + rtosfix(p.d) + " )");
} break;
case Variant::AABB: {
-
AABB aabb = p_variant;
p_store_string_func(p_store_string_ud, "AABB( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )");
} break;
case Variant::QUAT: {
-
Quat quat = p_variant;
p_store_string_func(p_store_string_ud, "Quat( " + rtosfix(quat.x) + ", " + rtosfix(quat.y) + ", " + rtosfix(quat.z) + ", " + rtosfix(quat.w) + " )");
} break;
case Variant::TRANSFORM2D: {
-
String s = "Transform2D( ";
Transform2D m3 = p_variant;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
-
- if (i != 0 || j != 0)
+ if (i != 0 || j != 0) {
s += ", ";
+ }
s += rtosfix(m3.elements[i][j]);
}
}
@@ -1583,14 +1528,13 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::BASIS: {
-
String s = "Basis( ";
Basis m3 = p_variant;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
-
- if (i != 0 || j != 0)
+ if (i != 0 || j != 0) {
s += ", ";
+ }
s += rtosfix(m3.elements[i][j]);
}
}
@@ -1599,15 +1543,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::TRANSFORM: {
-
String s = "Transform( ";
Transform t = p_variant;
Basis &m3 = t.basis;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
-
- if (i != 0 || j != 0)
+ if (i != 0 || j != 0) {
s += ", ";
+ }
s += rtosfix(m3.elements[i][j]);
}
}
@@ -1619,13 +1562,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
// misc types
case Variant::COLOR: {
-
Color c = p_variant;
p_store_string_func(p_store_string_ud, "Color( " + rtosfix(c.r) + ", " + rtosfix(c.g) + ", " + rtosfix(c.b) + ", " + rtosfix(c.a) + " )");
} break;
case Variant::STRING_NAME: {
-
String str = p_variant;
str = "@\"" + str.c_escape() + "\"";
@@ -1633,7 +1574,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::NODE_PATH: {
-
String str = p_variant;
str = "NodePath(\"" + str.c_escape() + "\")";
@@ -1642,7 +1582,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::OBJECT: {
-
Object *obj = p_variant;
if (!obj) {
@@ -1657,13 +1596,11 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
//try external function
if (p_encode_res_func) {
-
res_text = p_encode_res_func(p_encode_res_ud, res);
}
//try path because it's a file
if (res_text == String() && res->get_path().is_resource_file()) {
-
//external resource
String path = res->get_path();
res_text = "Resource( \"" + path + "\")";
@@ -1684,7 +1621,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
obj->get_property_list(&props);
bool first = true;
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
if (E->get().usage & PROPERTY_USAGE_STORAGE || E->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE) {
//must be serialized
@@ -1704,7 +1640,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::DICTIONARY: {
-
Dictionary dict = p_variant;
List<Variant> keys;
@@ -1713,7 +1648,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, "{\n");
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
/*
if (!_check_type(dict[E->get()]))
continue;
@@ -1721,22 +1655,22 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
write(E->get(), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
p_store_string_func(p_store_string_ud, ": ");
write(dict[E->get()], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
- if (E->next())
+ if (E->next()) {
p_store_string_func(p_store_string_ud, ",\n");
+ }
}
p_store_string_func(p_store_string_ud, "\n}");
} break;
case Variant::ARRAY: {
-
p_store_string_func(p_store_string_ud, "[ ");
Array array = p_variant;
int len = array.size();
for (int i = 0; i < len; i++) {
-
- if (i > 0)
+ if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
+ }
write(array[i], p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
}
p_store_string_func(p_store_string_ud, " ]");
@@ -1744,7 +1678,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::PACKED_BYTE_ARRAY: {
-
p_store_string_func(p_store_string_ud, "PackedByteArray( ");
String s;
Vector<uint8_t> data = p_variant;
@@ -1752,9 +1685,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
const uint8_t *ptr = data.ptr();
for (int i = 0; i < len; i++) {
-
- if (i > 0)
+ if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
+ }
p_store_string_func(p_store_string_ud, itos(ptr[i]));
}
@@ -1763,16 +1696,15 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::PACKED_INT32_ARRAY: {
-
p_store_string_func(p_store_string_ud, "PackedInt32Array( ");
Vector<int32_t> data = p_variant;
int32_t len = data.size();
const int32_t *ptr = data.ptr();
for (int32_t i = 0; i < len; i++) {
-
- if (i > 0)
+ if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
+ }
p_store_string_func(p_store_string_ud, itos(ptr[i]));
}
@@ -1781,16 +1713,15 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::PACKED_INT64_ARRAY: {
-
p_store_string_func(p_store_string_ud, "PackedInt64Array( ");
Vector<int64_t> data = p_variant;
int64_t len = data.size();
const int64_t *ptr = data.ptr();
for (int64_t i = 0; i < len; i++) {
-
- if (i > 0)
+ if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
+ }
p_store_string_func(p_store_string_ud, itos(ptr[i]));
}
@@ -1799,16 +1730,15 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
-
p_store_string_func(p_store_string_ud, "PackedFloat32Array( ");
Vector<float> data = p_variant;
int len = data.size();
const float *ptr = data.ptr();
for (int i = 0; i < len; i++) {
-
- if (i > 0)
+ if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
+ }
p_store_string_func(p_store_string_ud, rtosfix(ptr[i]));
}
@@ -1816,16 +1746,15 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::PACKED_FLOAT64_ARRAY: {
-
p_store_string_func(p_store_string_ud, "PackedFloat64Array( ");
Vector<double> data = p_variant;
int len = data.size();
const double *ptr = data.ptr();
for (int i = 0; i < len; i++) {
-
- if (i > 0)
+ if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
+ }
p_store_string_func(p_store_string_ud, rtosfix(ptr[i]));
}
@@ -1833,7 +1762,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::PACKED_STRING_ARRAY: {
-
p_store_string_func(p_store_string_ud, "PackedStringArray( ");
Vector<String> data = p_variant;
int len = data.size();
@@ -1843,9 +1771,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
//write_string("\n");
for (int i = 0; i < len; i++) {
-
- if (i > 0)
+ if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
+ }
String str = ptr[i];
p_store_string_func(p_store_string_ud, "\"" + str.c_escape() + "\"");
}
@@ -1854,16 +1782,15 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::PACKED_VECTOR2_ARRAY: {
-
p_store_string_func(p_store_string_ud, "PackedVector2Array( ");
Vector<Vector2> data = p_variant;
int len = data.size();
const Vector2 *ptr = data.ptr();
for (int i = 0; i < len; i++) {
-
- if (i > 0)
+ if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
+ }
p_store_string_func(p_store_string_ud, rtosfix(ptr[i].x) + ", " + rtosfix(ptr[i].y));
}
@@ -1871,16 +1798,15 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::PACKED_VECTOR3_ARRAY: {
-
p_store_string_func(p_store_string_ud, "PackedVector3Array( ");
Vector<Vector3> data = p_variant;
int len = data.size();
const Vector3 *ptr = data.ptr();
for (int i = 0; i < len; i++) {
-
- if (i > 0)
+ if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
+ }
p_store_string_func(p_store_string_ud, rtosfix(ptr[i].x) + ", " + rtosfix(ptr[i].y) + ", " + rtosfix(ptr[i].z));
}
@@ -1888,7 +1814,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
} break;
case Variant::PACKED_COLOR_ARRAY: {
-
p_store_string_func(p_store_string_ud, "PackedColorArray( ");
Vector<Color> data = p_variant;
@@ -1896,9 +1821,9 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
const Color *ptr = data.ptr();
for (int i = 0; i < len; i++) {
-
- if (i > 0)
+ if (i > 0) {
p_store_string_func(p_store_string_ud, ", ");
+ }
p_store_string_func(p_store_string_ud, rtosfix(ptr[i].r) + ", " + rtosfix(ptr[i].g) + ", " + rtosfix(ptr[i].b) + ", " + rtosfix(ptr[i].a));
}
@@ -1913,14 +1838,12 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
}
static Error _write_to_str(void *ud, const String &p_string) {
-
String *str = (String *)ud;
(*str) += p_string;
return OK;
}
Error VariantWriter::write_to_string(const Variant &p_variant, String &r_string, EncodeResourceFunc p_encode_res_func, void *p_encode_res_ud) {
-
r_string = String();
return write(p_variant, _write_to_str, &r_string, p_encode_res_func, p_encode_res_ud);
diff --git a/core/variant_parser.h b/core/variant_parser.h
index 63ed51bcc9..b55d7b2df0 100644
--- a/core/variant_parser.h
+++ b/core/variant_parser.h
@@ -38,45 +38,40 @@
class VariantParser {
public:
struct Stream {
-
virtual CharType get_char() = 0;
virtual bool is_utf8() const = 0;
virtual bool is_eof() const = 0;
- CharType saved;
+ CharType saved = 0;
- Stream() :
- saved(0) {}
+ Stream() {}
virtual ~Stream() {}
};
struct StreamFile : public Stream {
-
- FileAccess *f;
+ FileAccess *f = nullptr;
virtual CharType get_char();
virtual bool is_utf8() const;
virtual bool is_eof() const;
- StreamFile() { f = nullptr; }
+ StreamFile() {}
};
struct StreamString : public Stream {
-
String s;
- int pos;
+ int pos = 0;
virtual CharType get_char();
virtual bool is_utf8() const;
virtual bool is_eof() const;
- StreamString() { pos = 0; }
+ StreamString() {}
};
typedef Error (*ParseResourceFunc)(void *p_self, Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str);
struct ResourceParser {
-
void *userdata = nullptr;
ParseResourceFunc func;
ParseResourceFunc ext_func;
@@ -113,13 +108,11 @@ public:
};
struct Token {
-
TokenType type;
Variant value;
};
struct Tag {
-
String name;
Map<String, Variant> fields;
};
diff --git a/core/vector.h b/core/vector.h
index 7277179621..4c152fb084 100644
--- a/core/vector.h
+++ b/core/vector.h
@@ -39,6 +39,7 @@
#include "core/cowdata.h"
#include "core/error_macros.h"
+#include "core/os/copymem.h"
#include "core/os/memory.h"
#include "core/sort_array.h"
@@ -69,7 +70,9 @@ public:
void remove(int p_index) { _cowdata.remove(p_index); }
void erase(const T &p_val) {
int idx = find(p_val);
- if (idx >= 0) remove(idx);
+ if (idx >= 0) {
+ remove(idx);
+ }
}
void invert();
@@ -91,10 +94,10 @@ public:
template <class C>
void sort_custom() {
-
int len = _cowdata.size();
- if (len == 0)
+ if (len == 0) {
return;
+ }
T *data = ptrw();
SortArray<T, C> sorter;
@@ -102,30 +105,32 @@ public:
}
void sort() {
-
sort_custom<_DefaultComparator<T>>();
}
void ordered_insert(const T &p_val) {
int i;
for (i = 0; i < _cowdata.size(); i++) {
-
if (p_val < operator[](i)) {
break;
- };
- };
+ }
+ }
insert(i, p_val);
}
- _FORCE_INLINE_ Vector() {}
- _FORCE_INLINE_ Vector(const Vector &p_from) { _cowdata._ref(p_from._cowdata); }
inline Vector &operator=(const Vector &p_from) {
_cowdata._ref(p_from._cowdata);
return *this;
}
- Vector<T> subarray(int p_from, int p_to) const {
+ Vector<uint8_t> to_byte_array() const {
+ Vector<uint8_t> ret;
+ ret.resize(size() * sizeof(T));
+ copymem(ret.ptrw(), ptr(), sizeof(T) * size());
+ return ret;
+ }
+ Vector<T> subarray(int p_from, int p_to) const {
if (p_from < 0) {
p_from = size() + p_from;
}
@@ -148,12 +153,14 @@ public:
return slice;
}
+ _FORCE_INLINE_ Vector() {}
+ _FORCE_INLINE_ Vector(const Vector &p_from) { _cowdata._ref(p_from._cowdata); }
+
_FORCE_INLINE_ ~Vector() {}
};
template <class T>
void Vector<T>::invert() {
-
for (int i = 0; i < size() / 2; i++) {
T *p = ptrw();
SWAP(p[i], p[size() - i - 1]);
@@ -163,17 +170,18 @@ void Vector<T>::invert() {
template <class T>
void Vector<T>::append_array(Vector<T> p_other) {
const int ds = p_other.size();
- if (ds == 0)
+ if (ds == 0) {
return;
+ }
const int bs = size();
resize(bs + ds);
- for (int i = 0; i < ds; ++i)
+ for (int i = 0; i < ds; ++i) {
ptrw()[bs + i] = p_other[i];
+ }
}
template <class T>
bool Vector<T>::push_back(T p_elem) {
-
Error err = resize(size() + 1);
ERR_FAIL_COND_V(err, true);
set(size() - 1, p_elem);
diff --git a/core/vmap.h b/core/vmap.h
index 84ae1aaf66..c91ea9b3c9 100644
--- a/core/vmap.h
+++ b/core/vmap.h
@@ -38,14 +38,12 @@ template <class T, class V>
class VMap {
public:
struct Pair {
-
T key;
V value;
_FORCE_INLINE_ Pair() {}
_FORCE_INLINE_ Pair(const T &p_key, const V &p_value) {
-
key = p_key;
value = p_value;
}
@@ -55,10 +53,10 @@ private:
CowData<Pair> _cowdata;
_FORCE_INLINE_ int _find(const T &p_val, bool &r_exact) const {
-
r_exact = false;
- if (_cowdata.empty())
+ if (_cowdata.empty()) {
return 0;
+ }
int low = 0;
int high = _cowdata.size() - 1;
@@ -66,8 +64,9 @@ private:
int middle = 0;
#ifdef DEBUG_ENABLED
- if (low > high)
+ if (low > high) {
ERR_PRINT("low > high, this may be a bug");
+ }
#endif
while (low <= high) {
middle = (low + high) / 2;
@@ -83,15 +82,16 @@ private:
}
//return the position where this would be inserted
- if (a[middle].key < p_val)
+ if (a[middle].key < p_val) {
middle++;
+ }
return middle;
}
_FORCE_INLINE_ int _find_exact(const T &p_val) const {
-
- if (_cowdata.empty())
+ if (_cowdata.empty()) {
return -1;
+ }
int low = 0;
int high = _cowdata.size() - 1;
@@ -115,7 +115,6 @@ private:
public:
int insert(const T &p_key, const V &p_val) {
-
bool exact;
int pos = _find(p_key, exact);
if (exact) {
@@ -127,25 +126,22 @@ public:
}
bool has(const T &p_val) const {
-
return _find_exact(p_val) != -1;
}
void erase(const T &p_val) {
-
int pos = _find_exact(p_val);
- if (pos < 0)
+ if (pos < 0) {
return;
+ }
_cowdata.remove(pos);
}
int find(const T &p_val) const {
-
return _find_exact(p_val);
}
int find_nearest(const T &p_val) const {
-
bool exact;
return _find(p_val, exact);
}
@@ -154,37 +150,30 @@ public:
_FORCE_INLINE_ bool empty() const { return _cowdata.empty(); }
const Pair *get_array() const {
-
return _cowdata.ptr();
}
Pair *get_array() {
-
return _cowdata.ptrw();
}
const V &getv(int p_index) const {
-
return _cowdata.get(p_index).value;
}
V &getv(int p_index) {
-
return _cowdata.get_m(p_index).value;
}
const T &getk(int p_index) const {
-
return _cowdata.get(p_index).key;
}
T &getk(int p_index) {
-
return _cowdata.get_m(p_index).key;
}
inline const V &operator[](const T &p_key) const {
-
int pos = _find_exact(p_key);
CRASH_COND(pos < 0);
@@ -193,7 +182,6 @@ public:
}
inline V &operator[](const T &p_key) {
-
int pos = _find_exact(p_key);
if (pos < 0) {
pos = insert(p_key, V());
@@ -202,11 +190,13 @@ public:
return _cowdata.get_m(pos).value;
}
- _FORCE_INLINE_ VMap(){};
+ _FORCE_INLINE_ VMap() {}
_FORCE_INLINE_ VMap(const VMap &p_from) { _cowdata._ref(p_from._cowdata); }
+
inline VMap &operator=(const VMap &p_from) {
_cowdata._ref(p_from._cowdata);
return *this;
}
};
+
#endif // VMAP_H
diff --git a/core/vset.h b/core/vset.h
index b96a115d21..034b8fe851 100644
--- a/core/vset.h
+++ b/core/vset.h
@@ -36,14 +36,13 @@
template <class T>
class VSet {
-
Vector<T> _data;
_FORCE_INLINE_ int _find(const T &p_val, bool &r_exact) const {
-
r_exact = false;
- if (_data.empty())
+ if (_data.empty()) {
return 0;
+ }
int low = 0;
int high = _data.size() - 1;
@@ -51,8 +50,9 @@ class VSet {
int middle = 0;
#ifdef DEBUG_ENABLED
- if (low > high)
+ if (low > high) {
ERR_PRINT("low > high, this may be a bug");
+ }
#endif
while (low <= high) {
@@ -69,15 +69,16 @@ class VSet {
}
//return the position where this would be inserted
- if (a[middle] < p_val)
+ if (a[middle] < p_val) {
middle++;
+ }
return middle;
}
_FORCE_INLINE_ int _find_exact(const T &p_val) const {
-
- if (_data.empty())
+ if (_data.empty()) {
return -1;
+ }
int low = 0;
int high = _data.size() - 1;
@@ -101,29 +102,27 @@ class VSet {
public:
void insert(const T &p_val) {
-
bool exact;
int pos = _find(p_val, exact);
- if (exact)
+ if (exact) {
return;
+ }
_data.insert(pos, p_val);
}
bool has(const T &p_val) const {
-
return _find_exact(p_val) != -1;
}
void erase(const T &p_val) {
-
int pos = _find_exact(p_val);
- if (pos < 0)
+ if (pos < 0) {
return;
+ }
_data.remove(pos);
}
int find(const T &p_val) const {
-
return _find_exact(p_val);
}
@@ -132,12 +131,10 @@ public:
_FORCE_INLINE_ int size() const { return _data.size(); }
inline T &operator[](int p_index) {
-
return _data.write[p_index];
}
inline const T &operator[](int p_index) const {
-
return _data[p_index];
}
};
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index f462aa989d..03eb733e54 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -12,9 +12,6 @@
<methods>
</methods>
<members>
- <member name="XRServer" type="XRServer" setter="" getter="">
- The [XRServer] singleton.
- </member>
<member name="AudioServer" type="AudioServer" setter="" getter="">
The [AudioServer] singleton.
</member>
@@ -24,20 +21,20 @@
<member name="ClassDB" type="ClassDB" setter="" getter="">
The [ClassDB] singleton.
</member>
+ <member name="DisplayServer" type="DisplayServer" setter="" getter="">
+ The [DisplayServer] singleton.
+ </member>
<member name="Engine" type="Engine" setter="" getter="">
The [Engine] singleton.
</member>
<member name="Geometry" type="Geometry" setter="" getter="">
The [Geometry] singleton.
</member>
- <member name="GodotSharp" type="GodotSharp" setter="" getter="">
- The [GodotSharp] singleton. Only available when using Godot's Mono build.
- </member>
<member name="IP" type="IP" setter="" getter="">
The [IP] singleton.
</member>
- <member name="Input" type="InputFilter" setter="" getter="">
- The [InputFilter] singleton.
+ <member name="Input" type="Input" setter="" getter="">
+ The [Input] singleton.
</member>
<member name="InputMap" type="InputMap" setter="" getter="">
The [InputMap] singleton.
@@ -95,6 +92,9 @@
<member name="VisualScriptEditor" type="VisualScriptEditor" setter="" getter="">
The [VisualScriptEditor] singleton.
</member>
+ <member name="XRServer" type="XRServer" setter="" getter="">
+ The [XRServer] singleton.
+ </member>
</members>
<constants>
<constant name="MARGIN_LEFT" value="0" enum="Margin">
@@ -155,7 +155,7 @@
Tab key.
</constant>
<constant name="KEY_BACKTAB" value="16777219" enum="KeyList">
- Shift+Tab key.
+ Shift + Tab key.
</constant>
<constant name="KEY_BACKSPACE" value="16777220" enum="KeyList">
Backspace key.
@@ -943,212 +943,185 @@
<constant name="BUTTON_MASK_XBUTTON2" value="256" enum="ButtonList">
Extra mouse button 2 mask.
</constant>
- <constant name="JOY_BUTTON_0" value="0" enum="JoystickList">
- Gamepad button 0.
- </constant>
- <constant name="JOY_BUTTON_1" value="1" enum="JoystickList">
- Gamepad button 1.
+ <constant name="JOY_INVALID_BUTTON" value="-1" enum="JoyButtonList">
+ An invalid game controller button.
</constant>
- <constant name="JOY_BUTTON_2" value="2" enum="JoystickList">
- Gamepad button 2.
+ <constant name="JOY_BUTTON_A" value="0" enum="JoyButtonList">
+ Game controller SDL button A.
</constant>
- <constant name="JOY_BUTTON_3" value="3" enum="JoystickList">
- Gamepad button 3.
+ <constant name="JOY_BUTTON_B" value="1" enum="JoyButtonList">
+ Game controller SDL button B.
</constant>
- <constant name="JOY_BUTTON_4" value="4" enum="JoystickList">
- Gamepad button 4.
+ <constant name="JOY_BUTTON_X" value="2" enum="JoyButtonList">
+ Game controller SDL button X.
</constant>
- <constant name="JOY_BUTTON_5" value="5" enum="JoystickList">
- Gamepad button 5.
+ <constant name="JOY_BUTTON_Y" value="3" enum="JoyButtonList">
+ Game controller SDL button Y.
</constant>
- <constant name="JOY_BUTTON_6" value="6" enum="JoystickList">
- Gamepad button 6.
+ <constant name="JOY_BUTTON_BACK" value="4" enum="JoyButtonList">
+ Game controller SDL back button.
</constant>
- <constant name="JOY_BUTTON_7" value="7" enum="JoystickList">
- Gamepad button 7.
+ <constant name="JOY_BUTTON_GUIDE" value="5" enum="JoyButtonList">
+ Game controller SDL guide button.
</constant>
- <constant name="JOY_BUTTON_8" value="8" enum="JoystickList">
- Gamepad button 8.
+ <constant name="JOY_BUTTON_START" value="6" enum="JoyButtonList">
+ Game controller SDL start button.
</constant>
- <constant name="JOY_BUTTON_9" value="9" enum="JoystickList">
- Gamepad button 9.
+ <constant name="JOY_BUTTON_LEFT_STICK" value="7" enum="JoyButtonList">
+ Game controller SDL left stick button.
</constant>
- <constant name="JOY_BUTTON_10" value="10" enum="JoystickList">
- Gamepad button 10.
+ <constant name="JOY_BUTTON_RIGHT_STICK" value="8" enum="JoyButtonList">
+ Game controller SDL right stick button.
</constant>
- <constant name="JOY_BUTTON_11" value="11" enum="JoystickList">
- Gamepad button 11.
+ <constant name="JOY_BUTTON_LEFT_SHOULDER" value="9" enum="JoyButtonList">
+ Game controller SDL left shoulder button.
</constant>
- <constant name="JOY_BUTTON_12" value="12" enum="JoystickList">
- Gamepad button 12.
+ <constant name="JOY_BUTTON_RIGHT_SHOULDER" value="10" enum="JoyButtonList">
+ Game controller SDL right shoulder button.
</constant>
- <constant name="JOY_BUTTON_13" value="13" enum="JoystickList">
- Gamepad button 13.
+ <constant name="JOY_BUTTON_DPAD_UP" value="11" enum="JoyButtonList">
+ Game controller SDL D-pad up button.
</constant>
- <constant name="JOY_BUTTON_14" value="14" enum="JoystickList">
- Gamepad button 14.
+ <constant name="JOY_BUTTON_DPAD_DOWN" value="12" enum="JoyButtonList">
+ Game controller SDL D-pad down button.
</constant>
- <constant name="JOY_BUTTON_15" value="15" enum="JoystickList">
- Gamepad button 15.
+ <constant name="JOY_BUTTON_DPAD_LEFT" value="13" enum="JoyButtonList">
+ Game controller SDL D-pad left button.
</constant>
- <constant name="JOY_BUTTON_MAX" value="16" enum="JoystickList">
- Represents the maximum number of joystick buttons supported.
+ <constant name="JOY_BUTTON_DPAD_RIGHT" value="14" enum="JoyButtonList">
+ Game controller SDL D-pad right button.
</constant>
- <constant name="JOY_SONY_CIRCLE" value="1" enum="JoystickList">
- DualShock circle button.
+ <constant name="JOY_SDL_BUTTONS" value="15" enum="JoyButtonList">
+ The number of SDL game controller buttons.
</constant>
- <constant name="JOY_SONY_X" value="0" enum="JoystickList">
- DualShock X button.
+ <constant name="JOY_SONY_X" value="0" enum="JoyButtonList">
+ Sony DualShock controller X button maps to SDL button A.
</constant>
- <constant name="JOY_SONY_SQUARE" value="2" enum="JoystickList">
- DualShock square button.
+ <constant name="JOY_SONY_CROSS" value="0" enum="JoyButtonList">
+ Sony DualShock controller cross button maps to SDL button A.
</constant>
- <constant name="JOY_SONY_TRIANGLE" value="3" enum="JoystickList">
- DualShock triangle button.
+ <constant name="JOY_SONY_CIRCLE" value="1" enum="JoyButtonList">
+ Sony DualShock controller circle button maps to SDL button B.
</constant>
- <constant name="JOY_XBOX_B" value="1" enum="JoystickList">
- Xbox controller B button.
+ <constant name="JOY_SONY_SQUARE" value="2" enum="JoyButtonList">
+ Sony DualShock controller square button maps to SDL button X.
</constant>
- <constant name="JOY_XBOX_A" value="0" enum="JoystickList">
- Xbox controller A button.
+ <constant name="JOY_SONY_TRIANGLE" value="3" enum="JoyButtonList">
+ Sony DualShock controller triangle button maps to SDL button Y.
</constant>
- <constant name="JOY_XBOX_X" value="2" enum="JoystickList">
- Xbox controller X button.
+ <constant name="JOY_SONY_SELECT" value="4" enum="JoyButtonList">
+ Sony DualShock controller select button maps to SDL back button.
</constant>
- <constant name="JOY_XBOX_Y" value="3" enum="JoystickList">
- Xbox controller Y button.
+ <constant name="JOY_SONY_START" value="6" enum="JoyButtonList">
+ Sony DualShock controller start button maps to SDL start button.
</constant>
- <constant name="JOY_DS_A" value="1" enum="JoystickList">
- Nintendo controller A button.
+ <constant name="JOY_SONY_PS" value="5" enum="JoyButtonList">
+ Sony DualShock controller PS button maps to SDL guide button.
</constant>
- <constant name="JOY_DS_B" value="0" enum="JoystickList">
- Nintendo controller B button.
+ <constant name="JOY_SONY_L1" value="9" enum="JoyButtonList">
+ Sony DualShock controller L1 button maps to SDL left shoulder button.
</constant>
- <constant name="JOY_DS_X" value="3" enum="JoystickList">
- Nintendo controller X button.
+ <constant name="JOY_SONY_R1" value="10" enum="JoyButtonList">
+ Sony DualShock controller R1 button maps to SDL right shoulder button.
</constant>
- <constant name="JOY_DS_Y" value="2" enum="JoystickList">
- Nintendo controller Y button.
+ <constant name="JOY_SONY_L3" value="7" enum="JoyButtonList">
+ Sony DualShock controller L3 button maps to SDL left stick button.
</constant>
- <constant name="JOY_VR_GRIP" value="2" enum="JoystickList">
- Grip (side) buttons on a VR controller.
+ <constant name="JOY_SONY_R3" value="8" enum="JoyButtonList">
+ Sony DualShock controller R3 button maps to SDL right stick button.
</constant>
- <constant name="JOY_VR_PAD" value="14" enum="JoystickList">
- Push down on the touchpad or main joystick on a VR controller.
+ <constant name="JOY_XBOX_A" value="0" enum="JoyButtonList">
+ Xbox game controller A button maps to SDL button A.
</constant>
- <constant name="JOY_VR_TRIGGER" value="15" enum="JoystickList">
- Trigger on a VR controller.
+ <constant name="JOY_XBOX_B" value="1" enum="JoyButtonList">
+ Xbox game controller B button maps to SDL button B.
</constant>
- <constant name="JOY_OCULUS_AX" value="7" enum="JoystickList">
- A button on the right Oculus Touch controller, X button on the left controller (also when used in OpenVR).
+ <constant name="JOY_XBOX_X" value="2" enum="JoyButtonList">
+ Xbox game controller X button maps to SDL button X.
</constant>
- <constant name="JOY_OCULUS_BY" value="1" enum="JoystickList">
- B button on the right Oculus Touch controller, Y button on the left controller (also when used in OpenVR).
+ <constant name="JOY_XBOX_Y" value="3" enum="JoyButtonList">
+ Xbox game controller Y button maps to SDL button Y.
</constant>
- <constant name="JOY_OCULUS_MENU" value="3" enum="JoystickList">
- Menu button on either Oculus Touch controller.
+ <constant name="JOY_XBOX_BACK" value="4" enum="JoyButtonList">
+ Xbox game controller back button maps to SDL back button.
</constant>
- <constant name="JOY_OPENVR_MENU" value="1" enum="JoystickList">
- Menu button in OpenVR (Except when Oculus Touch controllers are used).
+ <constant name="JOY_XBOX_START" value="6" enum="JoyButtonList">
+ Xbox game controller start button maps to SDL start button.
</constant>
- <constant name="JOY_SELECT" value="10" enum="JoystickList">
- Gamepad button Select.
+ <constant name="JOY_XBOX_HOME" value="5" enum="JoyButtonList">
+ Xbox game controller home button maps to SDL guide button.
</constant>
- <constant name="JOY_START" value="11" enum="JoystickList">
- Gamepad button Start.
+ <constant name="JOY_XBOX_LS" value="7" enum="JoyButtonList">
+ Xbox game controller left stick button maps to SDL left stick button.
</constant>
- <constant name="JOY_DPAD_UP" value="12" enum="JoystickList">
- Gamepad DPad up.
+ <constant name="JOY_XBOX_RS" value="8" enum="JoyButtonList">
+ Xbox game controller right stick button maps to SDL right stick button.
</constant>
- <constant name="JOY_DPAD_DOWN" value="13" enum="JoystickList">
- Gamepad DPad down.
+ <constant name="JOY_XBOX_LB" value="9" enum="JoyButtonList">
+ Xbox game controller left bumper button maps to SDL left shoulder button.
</constant>
- <constant name="JOY_DPAD_LEFT" value="14" enum="JoystickList">
- Gamepad DPad left.
+ <constant name="JOY_XBOX_RB" value="10" enum="JoyButtonList">
+ Xbox game controller right bumper button maps to SDL right shoulder button.
</constant>
- <constant name="JOY_DPAD_RIGHT" value="15" enum="JoystickList">
- Gamepad DPad right.
+ <constant name="JOY_BUTTON_MAX" value="36" enum="JoyButtonList">
+ The maximum number of game controller buttons.
</constant>
- <constant name="JOY_L" value="4" enum="JoystickList">
- Gamepad left Shoulder button.
+ <constant name="JOY_INVALID_AXIS" value="-1" enum="JoyAxisList">
+ An invalid game controller axis.
</constant>
- <constant name="JOY_L2" value="6" enum="JoystickList">
- Gamepad left trigger.
+ <constant name="JOY_AXIS_LEFT_X" value="0" enum="JoyAxisList">
+ Game controller left joystick x-axis.
</constant>
- <constant name="JOY_L3" value="8" enum="JoystickList">
- Gamepad left stick click.
+ <constant name="JOY_AXIS_LEFT_Y" value="1" enum="JoyAxisList">
+ Game controller left joystick y-axis.
</constant>
- <constant name="JOY_R" value="5" enum="JoystickList">
- Gamepad right Shoulder button.
+ <constant name="JOY_AXIS_RIGHT_X" value="2" enum="JoyAxisList">
+ Game controller right joystick x-axis.
</constant>
- <constant name="JOY_R2" value="7" enum="JoystickList">
- Gamepad right trigger.
+ <constant name="JOY_AXIS_RIGHT_Y" value="3" enum="JoyAxisList">
+ Game controller right joystick y-axis.
</constant>
- <constant name="JOY_R3" value="9" enum="JoystickList">
- Gamepad right stick click.
+ <constant name="JOY_AXIS_TRIGGER_LEFT" value="4" enum="JoyAxisList">
+ Game controller left trigger axis.
</constant>
- <constant name="JOY_AXIS_0" value="0" enum="JoystickList">
- Gamepad left stick horizontal axis.
+ <constant name="JOY_AXIS_TRIGGER_RIGHT" value="5" enum="JoyAxisList">
+ Game controller right trigger axis.
</constant>
- <constant name="JOY_AXIS_1" value="1" enum="JoystickList">
- Gamepad left stick vertical axis.
+ <constant name="JOY_SDL_AXES" value="6" enum="JoyAxisList">
+ The number of SDL game controller axes.
</constant>
- <constant name="JOY_AXIS_2" value="2" enum="JoystickList">
- Gamepad right stick horizontal axis.
+ <constant name="JOY_AXIS_0_X" value="0" enum="JoyAxisList">
+ Game controller joystick 0 x-axis.
</constant>
- <constant name="JOY_AXIS_3" value="3" enum="JoystickList">
- Gamepad right stick vertical axis.
+ <constant name="JOY_AXIS_0_Y" value="1" enum="JoyAxisList">
+ Game controller joystick 0 y-axis.
</constant>
- <constant name="JOY_AXIS_4" value="4" enum="JoystickList">
- Generic gamepad axis 4.
+ <constant name="JOY_AXIS_1_X" value="2" enum="JoyAxisList">
+ Game controller joystick 1 x-axis.
</constant>
- <constant name="JOY_AXIS_5" value="5" enum="JoystickList">
- Generic gamepad axis 5.
+ <constant name="JOY_AXIS_1_Y" value="3" enum="JoyAxisList">
+ Game controller joystick 1 y-axis.
</constant>
- <constant name="JOY_AXIS_6" value="6" enum="JoystickList">
- Gamepad left trigger analog axis.
+ <constant name="JOY_AXIS_2_X" value="4" enum="JoyAxisList">
+ Game controller joystick 2 x-axis.
</constant>
- <constant name="JOY_AXIS_7" value="7" enum="JoystickList">
- Gamepad right trigger analog axis.
+ <constant name="JOY_AXIS_2_Y" value="5" enum="JoyAxisList">
+ Game controller joystick 2 y-axis.
</constant>
- <constant name="JOY_AXIS_8" value="8" enum="JoystickList">
- Generic gamepad axis 8.
+ <constant name="JOY_AXIS_3_X" value="6" enum="JoyAxisList">
+ Game controller joystick 3 x-axis.
</constant>
- <constant name="JOY_AXIS_9" value="9" enum="JoystickList">
- Generic gamepad axis 9.
+ <constant name="JOY_AXIS_3_Y" value="7" enum="JoyAxisList">
+ Game controller joystick 3 y-axis.
</constant>
- <constant name="JOY_AXIS_MAX" value="10" enum="JoystickList">
- Represents the maximum number of joystick axes supported.
+ <constant name="JOY_AXIS_4_X" value="8" enum="JoyAxisList">
+ Game controller joystick 4 x-axis.
</constant>
- <constant name="JOY_ANALOG_LX" value="0" enum="JoystickList">
- Gamepad left stick horizontal axis.
+ <constant name="JOY_AXIS_4_Y" value="9" enum="JoyAxisList">
+ Game controller joystick 4 y-axis.
</constant>
- <constant name="JOY_ANALOG_LY" value="1" enum="JoystickList">
- Gamepad left stick vertical axis.
- </constant>
- <constant name="JOY_ANALOG_RX" value="2" enum="JoystickList">
- Gamepad right stick horizontal axis.
- </constant>
- <constant name="JOY_ANALOG_RY" value="3" enum="JoystickList">
- Gamepad right stick vertical axis.
- </constant>
- <constant name="JOY_ANALOG_L2" value="6" enum="JoystickList">
- Gamepad left analog trigger.
- </constant>
- <constant name="JOY_ANALOG_R2" value="7" enum="JoystickList">
- Gamepad right analog trigger.
- </constant>
- <constant name="JOY_VR_ANALOG_TRIGGER" value="2" enum="JoystickList">
- VR Controller analog trigger.
- </constant>
- <constant name="JOY_VR_ANALOG_GRIP" value="4" enum="JoystickList">
- VR Controller analog grip (side buttons).
- </constant>
- <constant name="JOY_OPENVR_TOUCHPADX" value="0" enum="JoystickList">
- OpenVR touchpad X axis (Joystick axis on Oculus Touch and Windows MR controllers).
- </constant>
- <constant name="JOY_OPENVR_TOUCHPADY" value="1" enum="JoystickList">
- OpenVR touchpad Y axis (Joystick axis on Oculus Touch and Windows MR controllers).
+ <constant name="JOY_AXIS_MAX" value="10" enum="JoyAxisList">
+ The maximum number of game controller axes.
</constant>
<constant name="MIDI_MESSAGE_NOTE_OFF" value="8" enum="MidiMessageList">
MIDI note OFF message.
@@ -1177,10 +1150,10 @@
[codeblock]
var err = method_that_returns_error()
if err != OK:
- print("Failure!)
+ print("Failure!")
# Or, equivalent:
if err:
- print("Still failing!)
+ print("Still failing!")
[/codeblock]
</constant>
<constant name="FAILED" value="1" enum="Error">
@@ -1345,52 +1318,52 @@
<constant name="PROPERTY_HINT_LENGTH" value="5" enum="PropertyHint">
Deprecated hint, unused.
</constant>
- <constant name="PROPERTY_HINT_KEY_ACCEL" value="7" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_KEY_ACCEL" value="6" enum="PropertyHint">
Deprecated hint, unused.
</constant>
- <constant name="PROPERTY_HINT_FLAGS" value="8" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_FLAGS" value="7" enum="PropertyHint">
Hints that an integer property is a bitmask with named bit flags. For example, to allow toggling bits 0, 1, 2 and 4, the hint could be something like [code]"Bit0,Bit1,Bit2,,Bit4"[/code].
</constant>
- <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="9" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_2D_RENDER" value="8" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D render layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="10" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_2D_PHYSICS" value="9" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 2D physics layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="11" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_RENDER" value="10" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 3D render layers.
</constant>
- <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="12" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_LAYERS_3D_PHYSICS" value="11" enum="PropertyHint">
Hints that an integer property is a bitmask using the optionally named 3D physics layers.
</constant>
- <constant name="PROPERTY_HINT_FILE" value="13" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_FILE" value="12" enum="PropertyHint">
Hints that a string property is a path to a file. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
</constant>
- <constant name="PROPERTY_HINT_DIR" value="14" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_DIR" value="13" enum="PropertyHint">
Hints that a string property is a path to a directory. Editing it will show a file dialog for picking the path.
</constant>
- <constant name="PROPERTY_HINT_GLOBAL_FILE" value="15" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_GLOBAL_FILE" value="14" enum="PropertyHint">
Hints that a string property is an absolute path to a file outside the project folder. Editing it will show a file dialog for picking the path. The hint string can be a set of filters with wildcards like [code]"*.png,*.jpg"[/code].
</constant>
- <constant name="PROPERTY_HINT_GLOBAL_DIR" value="16" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_GLOBAL_DIR" value="15" enum="PropertyHint">
Hints that a string property is an absolute path to a directory outside the project folder. Editing it will show a file dialog for picking the path.
</constant>
- <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="17" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_RESOURCE_TYPE" value="16" enum="PropertyHint">
Hints that a property is an instance of a [Resource]-derived type, optionally specified via the hint string (e.g. [code]"Texture2D"[/code]). Editing it will show a popup menu of valid resource types to instantiate.
</constant>
- <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="18" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_MULTILINE_TEXT" value="17" enum="PropertyHint">
Hints that a string property is text with line breaks. Editing it will show a text input field where line breaks can be typed.
</constant>
- <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="19" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_PLACEHOLDER_TEXT" value="18" enum="PropertyHint">
Hints that a string property should have a placeholder text visible on its input field, whenever the property is empty. The hint string is the placeholder text to use.
</constant>
- <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="20" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_COLOR_NO_ALPHA" value="19" enum="PropertyHint">
Hints that a color property should be edited without changing its alpha component, i.e. only R, G and B channels are edited.
</constant>
- <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="21" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSY" value="20" enum="PropertyHint">
Hints that an image is compressed using lossy compression.
</constant>
- <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="22" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS" value="21" enum="PropertyHint">
Hints that an image is compressed using lossless compression.
</constant>
<constant name="PROPERTY_USAGE_STORAGE" value="1" enum="PropertyUsageFlags">
@@ -1420,6 +1393,9 @@
<constant name="PROPERTY_USAGE_CATEGORY" value="256" enum="PropertyUsageFlags">
Used to categorize properties together in the editor.
</constant>
+ <constant name="PROPERTY_USAGE_SUBGROUP" value="512" enum="PropertyUsageFlags">
+ Used to group properties together in the editor in a subgroup (under a group).
+ </constant>
<constant name="PROPERTY_USAGE_NO_INSTANCE_STATE" value="2048" enum="PropertyUsageFlags">
The property does not save its state in [PackedScene].
</constant>
diff --git a/doc/classes/AnimatedTexture.xml b/doc/classes/AnimatedTexture.xml
index 80b910aaa7..285e0d5f39 100644
--- a/doc/classes/AnimatedTexture.xml
+++ b/doc/classes/AnimatedTexture.xml
@@ -61,6 +61,9 @@
</method>
</methods>
<members>
+ <member name="current_frame" type="int" setter="set_current_frame" getter="get_current_frame">
+ Sets the currently visible frame of the texture.
+ </member>
<member name="fps" type="float" setter="set_fps" getter="get_fps" default="4.0">
Animation speed in frames per second. This value defines the default time interval between two frames of the animation, and thus the overall duration of the animation loop based on the [member frames] property. A value of 0 means no predefined number of frames per second, the animation will play according to each frame's frame delay (see [method set_frame_delay]).
For example, an animation with 8 frames, no frame delay and a [code]fps[/code] value of 2 will run for 4 seconds, with each frame lasting 0.5 seconds.
@@ -68,6 +71,12 @@
<member name="frames" type="int" setter="set_frames" getter="get_frames" default="1">
Number of frames to use in the animation. While you can create the frames independently with [method set_frame_texture], you need to set this value for the animation to take new frames into account. The maximum number of frames is [constant MAX_FRAMES].
</member>
+ <member name="oneshot" type="bool" setter="set_oneshot" getter="get_oneshot" default="false">
+ If [code]true[/code], the animation will only play once and will not loop back to the first frame after reaching the end. Note that reaching the end will not set [member pause] to [code]true[/code].
+ </member>
+ <member name="pause" type="bool" setter="set_pause" getter="get_pause" default="false">
+ If [code]true[/code], the animation will pause where it currently is (i.e. at [member current_frame]). The animation will continue from where it was paused when changing this property to [code]false[/code].
+ </member>
</members>
<constants>
<constant name="MAX_FRAMES" value="256">
diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml
index 0c1317f19d..4190cbe6b9 100644
--- a/doc/classes/Area2D.xml
+++ b/doc/classes/Area2D.xml
@@ -29,14 +29,14 @@
</description>
</method>
<method name="get_overlapping_areas" qualifiers="const">
- <return type="Array">
+ <return type="Area2D[]">
</return>
<description>
Returns a list of intersecting [Area2D]s. For performance reasons (collisions are all processed at the same time) this list is modified once during the physics step, not immediately after objects are moved. Consider using signals instead.
</description>
</method>
<method name="get_overlapping_bodies" qualifiers="const">
- <return type="Array">
+ <return type="Node2D[]">
</return>
<description>
Returns a list of intersecting [PhysicsBody2D]s. For performance reasons (collisions are all processed at the same time) this list is modified once during the physics step, not immediately after objects are moved. Consider using signals instead.
diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml
index 1adfc878e2..a94cecd879 100644
--- a/doc/classes/Area3D.xml
+++ b/doc/classes/Area3D.xml
@@ -28,14 +28,14 @@
</description>
</method>
<method name="get_overlapping_areas" qualifiers="const">
- <return type="Array">
+ <return type="Area3D[]">
</return>
<description>
Returns a list of intersecting [Area3D]s. For performance reasons (collisions are all processed at the same time) this list is modified once during the physics step, not immediately after objects are moved. Consider using signals instead.
</description>
</method>
<method name="get_overlapping_bodies" qualifiers="const">
- <return type="Array">
+ <return type="Node3D[]">
</return>
<description>
Returns a list of intersecting [PhysicsBody3D]s. For performance reasons (collisions are all processed at the same time) this list is modified once during the physics step, not immediately after objects are moved. Consider using signals instead.
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index 20296bbf45..7593f7dff4 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -20,7 +20,7 @@
var array2 = [3, "Four"]
print(array1 + array2) # ["One", 2, 3, "Four"]
[/codeblock]
- Arrays are always passed by reference.
+ [b]Note:[/b] Arrays are always passed by reference. To get a copy of an array which can be modified independently of the original array, use [method duplicate].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml
index 9e742ea581..b45716544a 100644
--- a/doc/classes/ArrayMesh.xml
+++ b/doc/classes/ArrayMesh.xml
@@ -22,6 +22,8 @@
m.mesh = arr_mesh
[/codeblock]
The [MeshInstance3D] is ready to be added to the [SceneTree] to be shown.
+ See also [ImmediateGeometry3D], [MeshDataTool] and [SurfaceTool] for procedural geometry generation.
+ [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/content/procedural_geometry/arraymesh.html</link>
@@ -56,7 +58,6 @@
Surfaces are created to be rendered using a [code]primitive[/code], which may be any of the types defined in [enum Mesh.PrimitiveType]. (As a note, when using indices, it is recommended to only use points, lines or triangles.) [method Mesh.get_surface_count] will become the [code]surf_idx[/code] for this new surface.
The [code]arrays[/code] argument is an array of arrays. See [enum ArrayType] for the values used in this array. For example, [code]arrays[0][/code] is the array of vertices. That first vertex sub-array is always required; the others are optional. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data and the index array defines the vertex order. All sub-arrays must have the same length as the vertex array or be empty, except for [constant ARRAY_INDEX] if it is used.
Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data, and the index array defines the order of the vertices.
- Godot uses clockwise winding order for front faces of triangle primitive modes.
</description>
</method>
<method name="clear_blend_shapes">
diff --git a/doc/classes/AudioStreamPlayer.xml b/doc/classes/AudioStreamPlayer.xml
index eab6505734..dbc3d3e21b 100644
--- a/doc/classes/AudioStreamPlayer.xml
+++ b/doc/classes/AudioStreamPlayer.xml
@@ -61,7 +61,7 @@
If the audio configuration has more than two speakers, this sets the target channels. See [enum MixTarget] constants.
</member>
<member name="pitch_scale" type="float" setter="set_pitch_scale" getter="get_pitch_scale" default="1.0">
- Changes the pitch and the tempo of the audio.
+ The pitch and the tempo of the audio, as a multiplier of the audio sample's sample rate.
</member>
<member name="playing" type="bool" setter="_set_playing" getter="is_playing" default="false">
If [code]true[/code], audio is playing.
diff --git a/doc/classes/AudioStreamPlayer2D.xml b/doc/classes/AudioStreamPlayer2D.xml
index fdbef1b89e..844e2316ba 100644
--- a/doc/classes/AudioStreamPlayer2D.xml
+++ b/doc/classes/AudioStreamPlayer2D.xml
@@ -67,7 +67,7 @@
Maximum distance from which audio is still hearable.
</member>
<member name="pitch_scale" type="float" setter="set_pitch_scale" getter="get_pitch_scale" default="1.0">
- Changes the pitch and the tempo of the audio.
+ The pitch and the tempo of the audio, as a multiplier of the audio sample's sample rate.
</member>
<member name="playing" type="bool" setter="_set_playing" getter="is_playing" default="false">
If [code]true[/code], audio is playing.
diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml
index 3eeb524e9c..bd90e3bd1a 100644
--- a/doc/classes/AudioStreamPlayer3D.xml
+++ b/doc/classes/AudioStreamPlayer3D.xml
@@ -91,7 +91,7 @@
Decides if audio should pause when source is outside of [member max_distance] range.
</member>
<member name="pitch_scale" type="float" setter="set_pitch_scale" getter="get_pitch_scale" default="1.0">
- Changes the pitch and the tempo of the audio.
+ The pitch and the tempo of the audio, as a multiplier of the audio sample's sample rate.
</member>
<member name="playing" type="bool" setter="_set_playing" getter="is_playing" default="false">
If [code]true[/code], audio is playing.
diff --git a/doc/classes/BackBufferCopy.xml b/doc/classes/BackBufferCopy.xml
index 1f7554f978..7cc6a5613b 100644
--- a/doc/classes/BackBufferCopy.xml
+++ b/doc/classes/BackBufferCopy.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
Node for back-buffering the currently-displayed screen. The region defined in the BackBufferCopy node is bufferized with the content of the screen it covers, or the entire screen according to the copy mode set. Use the [code]texture(SCREEN_TEXTURE, ...)[/code] function in your shader scripts to access the buffer.
+ [b]Note:[/b] Since this node inherits from [Node2D] (and not [Control]), anchors and margins won't apply to child [Control]-derived nodes. This can be problematic when resizing the window. To avoid this, add [Control]-derived nodes as [i]siblings[/i] to the BackBufferCopy node instead of adding them as children.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/BakedLightmap.xml b/doc/classes/BakedLightmap.xml
new file mode 100644
index 0000000000..6fd08fc4e4
--- /dev/null
+++ b/doc/classes/BakedLightmap.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="BakedLightmap" inherits="VisualInstance3D" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="bias" type="float" setter="set_bias" getter="get_bias" default="0.0005">
+ </member>
+ <member name="bounces" type="int" setter="set_bounces" getter="get_bounces" default="1">
+ </member>
+ <member name="directional" type="bool" setter="set_directional" getter="is_directional" default="false">
+ </member>
+ <member name="environment_custom_color" type="Color" setter="set_environment_custom_color" getter="get_environment_custom_color">
+ </member>
+ <member name="environment_custom_energy" type="float" setter="set_environment_custom_energy" getter="get_environment_custom_energy">
+ </member>
+ <member name="environment_custom_sky" type="Sky" setter="set_environment_custom_sky" getter="get_environment_custom_sky">
+ </member>
+ <member name="environment_mode" type="int" setter="set_environment_mode" getter="get_environment_mode" enum="BakedLightmap.EnvironmentMode" default="0">
+ </member>
+ <member name="generate_probes_subdiv" type="int" setter="set_generate_probes" getter="get_generate_probes" enum="BakedLightmap.GenerateProbes" default="0">
+ </member>
+ <member name="interior" type="bool" setter="set_interior" getter="is_interior" default="false">
+ </member>
+ <member name="light_data" type="BakedLightmapData" setter="set_light_data" getter="get_light_data">
+ </member>
+ <member name="max_texture_size" type="int" setter="set_max_texture_size" getter="get_max_texture_size" default="16384">
+ </member>
+ <member name="quality" type="int" setter="set_bake_quality" getter="get_bake_quality" enum="BakedLightmap.BakeQuality" default="1">
+ </member>
+ <member name="use_denoiser" type="bool" setter="set_use_denoiser" getter="is_using_denoiser" default="true">
+ </member>
+ </members>
+ <constants>
+ <constant name="BAKE_QUALITY_LOW" value="0" enum="BakeQuality">
+ </constant>
+ <constant name="BAKE_QUALITY_MEDIUM" value="1" enum="BakeQuality">
+ </constant>
+ <constant name="BAKE_QUALITY_HIGH" value="2" enum="BakeQuality">
+ </constant>
+ <constant name="BAKE_QUALITY_ULTRA" value="3" enum="BakeQuality">
+ </constant>
+ <constant name="GENERATE_PROBES_DISABLED" value="0" enum="GenerateProbes">
+ </constant>
+ <constant name="GENERATE_PROBES_SUBDIV_4" value="1" enum="GenerateProbes">
+ </constant>
+ <constant name="GENERATE_PROBES_SUBDIV_8" value="2" enum="GenerateProbes">
+ </constant>
+ <constant name="GENERATE_PROBES_SUBDIV_16" value="3" enum="GenerateProbes">
+ </constant>
+ <constant name="GENERATE_PROBES_SUBDIV_32" value="4" enum="GenerateProbes">
+ </constant>
+ <constant name="BAKE_ERROR_OK" value="0" enum="BakeError">
+ </constant>
+ <constant name="BAKE_ERROR_NO_LIGHTMAPPER" value="1" enum="BakeError">
+ </constant>
+ <constant name="BAKE_ERROR_NO_SAVE_PATH" value="2" enum="BakeError">
+ </constant>
+ <constant name="BAKE_ERROR_NO_MESHES" value="3" enum="BakeError">
+ </constant>
+ <constant name="BAKE_ERROR_MESHES_INVALID" value="4" enum="BakeError">
+ </constant>
+ <constant name="BAKE_ERROR_CANT_CREATE_IMAGE" value="5" enum="BakeError">
+ </constant>
+ <constant name="BAKE_ERROR_USER_ABORTED" value="6" enum="BakeError">
+ </constant>
+ <constant name="ENVIRONMENT_MODE_DISABLED" value="0" enum="EnvironmentMode">
+ </constant>
+ <constant name="ENVIRONMENT_MODE_SCENE" value="1" enum="EnvironmentMode">
+ </constant>
+ <constant name="ENVIRONMENT_MODE_CUSTOM_SKY" value="2" enum="EnvironmentMode">
+ </constant>
+ <constant name="ENVIRONMENT_MODE_CUSTOM_COLOR" value="3" enum="EnvironmentMode">
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/BakedLightmapData.xml b/doc/classes/BakedLightmapData.xml
new file mode 100644
index 0000000000..026477782a
--- /dev/null
+++ b/doc/classes/BakedLightmapData.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="BakedLightmapData" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="add_user">
+ <return type="void">
+ </return>
+ <argument index="0" name="path" type="NodePath">
+ </argument>
+ <argument index="1" name="lightmap" type="Rect2">
+ </argument>
+ <argument index="2" name="offset" type="int">
+ </argument>
+ <argument index="3" name="arg3" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="clear_users">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_user_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_user_path" qualifiers="const">
+ <return type="NodePath">
+ </return>
+ <argument index="0" name="user_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="is_using_spherical_harmonics" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_uses_spherical_harmonics">
+ <return type="void">
+ </return>
+ <argument index="0" name="uses_spherical_harmonics" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="light_texture" type="TextureLayered" setter="set_light_texture" getter="get_light_texture">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml
index 5bb94d2858..1da4e23437 100644
--- a/doc/classes/BaseMaterial3D.xml
+++ b/doc/classes/BaseMaterial3D.xml
@@ -108,6 +108,15 @@
<member name="ao_texture_channel" type="int" setter="set_ao_texture_channel" getter="get_ao_texture_channel" enum="BaseMaterial3D.TextureChannel">
Specifies the channel of the [member ao_texture] in which the ambient occlusion information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use.
</member>
+ <member name="backlight" type="Color" setter="set_backlight" getter="get_backlight">
+ The color used by the backlight effect. Represents the light passing through an object.
+ </member>
+ <member name="backlight_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
+ If [code]true[/code], the backlight effect is enabled.
+ </member>
+ <member name="backlight_texture" type="Texture2D" setter="set_texture" getter="get_texture">
+ Texture used to control the backlight effect per-pixel. Added to [member backlight].
+ </member>
<member name="billboard_keep_scale" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the shader will keep the scale set for the mesh. Otherwise the scale is lost when billboarding. Only applies when [member billboard_mode] is [constant BILLBOARD_ENABLED].
</member>
@@ -150,6 +159,7 @@
</member>
<member name="detail_normal" type="Texture2D" setter="set_texture" getter="get_texture">
Texture that specifies the per-pixel normal of the detail overlay.
+ [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="detail_uv_layer" type="int" setter="set_detail_uv" getter="get_detail_uv" enum="BaseMaterial3D.DetailUV">
Specifies whether to use [code]UV[/code] or [code]UV2[/code] for the detail layer. See [enum DetailUV] for options.
@@ -241,6 +251,7 @@
</member>
<member name="normal_texture" type="Texture2D" setter="set_texture" getter="get_texture">
Texture used to specify the normal at a given pixel. The [code]normal_texture[/code] only uses the red and green channels. The normal read from [code]normal_texture[/code] is oriented around the surface normal provided by the [Mesh].
+ [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="orm_texture" type="Texture2D" setter="set_texture" getter="get_texture">
</member>
@@ -296,6 +307,7 @@
Specifies the channel of the [member ao_texture] in which the ambient occlusion information is stored. This is useful when you store the information for multiple effects in a single texture. For example if you stored metallic in the red channel, roughness in the blue, and ambient occlusion in the green you could reduce the number of textures you use.
</member>
<member name="shading_mode" type="int" setter="set_shading_mode" getter="get_shading_mode" enum="BaseMaterial3D.ShadingMode" default="1">
+ Sets whether the shading takes place per-pixel or per-vertex. Per-vertex lighting is faster, making it the best choice for mobile applications, however it looks considerably worse than per-pixel.
</member>
<member name="shadow_to_opacity" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], enables the "shadow to opacity" render mode where lighting modifies the alpha so shadowed areas are opaque and non-shadowed areas are transparent. Useful for overlaying shadows onto a camera feed in AR.
@@ -307,6 +319,7 @@
If [code]true[/code], subsurface scattering is enabled. Emulates light that penetrates an object's surface, is scattered, and then emerges.
</member>
<member name="subsurf_scatter_skin_mode" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code], subsurface scattering will use a special mode optimized for the color and density of human skin.
</member>
<member name="subsurf_scatter_strength" type="float" setter="set_subsurface_scattering_strength" getter="get_subsurface_scattering_strength">
The strength of the subsurface scattering effect.
@@ -314,21 +327,24 @@
<member name="subsurf_scatter_texture" type="Texture2D" setter="set_texture" getter="get_texture">
Texture used to control the subsurface scattering strength. Stored in the red texture channel. Multiplied by [member subsurf_scatter_strength].
</member>
+ <member name="subsurf_scatter_transmittance_boost" type="float" setter="set_transmittance_boost" getter="get_transmittance_boost">
+ </member>
+ <member name="subsurf_scatter_transmittance_color" type="Color" setter="set_transmittance_color" getter="get_transmittance_color">
+ </member>
+ <member name="subsurf_scatter_transmittance_curve" type="float" setter="set_transmittance_curve" getter="get_transmittance_curve">
+ </member>
+ <member name="subsurf_scatter_transmittance_depth" type="float" setter="set_transmittance_depth" getter="get_transmittance_depth">
+ </member>
+ <member name="subsurf_scatter_transmittance_enabled" type="bool" setter="set_feature" getter="get_feature">
+ </member>
+ <member name="subsurf_scatter_transmittance_texture" type="Texture2D" setter="set_texture" getter="get_texture">
+ </member>
<member name="texture_filter" type="int" setter="set_texture_filter" getter="get_texture_filter" enum="BaseMaterial3D.TextureFilter" default="3">
Filter flags for the texture. See [enum TextureFilter] for options.
</member>
<member name="texture_repeat" type="bool" setter="set_flag" getter="get_flag" default="true">
Repeat flags for the texture. See [enum TextureFilter] for options.
</member>
- <member name="transmission" type="Color" setter="set_transmission" getter="get_transmission">
- The color used by the transmission effect. Represents the light passing through an object.
- </member>
- <member name="transmission_enabled" type="bool" setter="set_feature" getter="get_feature" default="false">
- If [code]true[/code], the transmission effect is enabled.
- </member>
- <member name="transmission_texture" type="Texture2D" setter="set_texture" getter="get_texture">
- Texture used to control the transmission effect per-pixel. Added to [member transmission].
- </member>
<member name="transparency" type="int" setter="set_transparency" getter="get_transparency" enum="BaseMaterial3D.Transparency" default="0">
If [code]true[/code], transparency is enabled on the body. See also [member blend_mode].
</member>
@@ -407,39 +423,47 @@
<constant name="TEXTURE_SUBSURFACE_SCATTERING" value="10" enum="TextureParam">
Texture specifying per-pixel subsurface scattering.
</constant>
- <constant name="TEXTURE_TRANSMISSION" value="11" enum="TextureParam">
- Texture specifying per-pixel transmission color.
+ <constant name="TEXTURE_SUBSURFACE_TRANSMITTANCE" value="11" enum="TextureParam">
+ Texture specifying per-pixel transmittance for subsurface scattering.
+ </constant>
+ <constant name="TEXTURE_BACKLIGHT" value="12" enum="TextureParam">
+ Texture specifying per-pixel backlight color.
</constant>
- <constant name="TEXTURE_REFRACTION" value="12" enum="TextureParam">
+ <constant name="TEXTURE_REFRACTION" value="13" enum="TextureParam">
Texture specifying per-pixel refraction strength.
</constant>
- <constant name="TEXTURE_DETAIL_MASK" value="13" enum="TextureParam">
+ <constant name="TEXTURE_DETAIL_MASK" value="14" enum="TextureParam">
Texture specifying per-pixel detail mask blending value.
</constant>
- <constant name="TEXTURE_DETAIL_ALBEDO" value="14" enum="TextureParam">
+ <constant name="TEXTURE_DETAIL_ALBEDO" value="15" enum="TextureParam">
Texture specifying per-pixel detail color.
</constant>
- <constant name="TEXTURE_DETAIL_NORMAL" value="15" enum="TextureParam">
+ <constant name="TEXTURE_DETAIL_NORMAL" value="16" enum="TextureParam">
Texture specifying per-pixel detail normal.
</constant>
- <constant name="TEXTURE_ORM" value="16" enum="TextureParam">
+ <constant name="TEXTURE_ORM" value="17" enum="TextureParam">
+ Texture holding ambient occlusion, roughness, and metallic.
</constant>
- <constant name="TEXTURE_MAX" value="17" enum="TextureParam">
+ <constant name="TEXTURE_MAX" value="18" enum="TextureParam">
Represents the size of the [enum TextureParam] enum.
</constant>
<constant name="TEXTURE_FILTER_NEAREST" value="0" enum="TextureFilter">
The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
</constant>
<constant name="TEXTURE_FILTER_LINEAR" value="1" enum="TextureFilter">
- The texture filter blends between the nearest four pixels. Use this for most cases where you want to avoid a pixelated style.
+ The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps.
</constant>
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="2" enum="TextureFilter">
+ The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps.
</constant>
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="3" enum="TextureFilter">
+ The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. Use this for most cases as mipmaps are important to smooth out pixels that are far from the camera.
</constant>
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="4" enum="TextureFilter">
+ The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera.
</constant>
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter">
+ The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing.
</constant>
<constant name="TEXTURE_FILTER_MAX" value="6" enum="TextureFilter">
Represents the size of the [enum TextureFilter] enum.
@@ -457,8 +481,10 @@
The material will use the texture's alpha values for transparency.
</constant>
<constant name="TRANSPARENCY_ALPHA_SCISSOR" value="2" enum="Transparency">
+ The material will cut off all values below a threshold, the rest will remain opaque.
</constant>
<constant name="TRANSPARENCY_ALPHA_DEPTH_PRE_PASS" value="3" enum="Transparency">
+ The material will use the texture's alpha value for transparency, but will still be rendered in the pre-pass.
</constant>
<constant name="TRANSPARENCY_MAX" value="4" enum="Transparency">
Represents the size of the [enum Transparency] enum.
@@ -494,20 +520,24 @@
Constant for setting [member ao_enabled].
</constant>
<constant name="FEATURE_HEIGHT_MAPPING" value="6" enum="Feature">
+ Constant for setting [member heightmap_enabled].
</constant>
- <constant name="FEATURE_SUBSURACE_SCATTERING" value="7" enum="Feature">
+ <constant name="FEATURE_SUBSURFACE_SCATTERING" value="7" enum="Feature">
Constant for setting [member subsurf_scatter_enabled].
</constant>
- <constant name="FEATURE_TRANSMISSION" value="8" enum="Feature">
- Constant for setting [member transmission_enabled].
+ <constant name="FEATURE_SUBSURFACE_TRANSMITTANCE" value="8" enum="Feature">
+ Constant for setting [member subsurf_scatter_transmittance_enabled].
+ </constant>
+ <constant name="FEATURE_BACKLIGHT" value="9" enum="Feature">
+ Constant for setting [member backlight_enabled].
</constant>
- <constant name="FEATURE_REFRACTION" value="9" enum="Feature">
+ <constant name="FEATURE_REFRACTION" value="10" enum="Feature">
Constant for setting [member refraction_enabled].
</constant>
- <constant name="FEATURE_DETAIL" value="10" enum="Feature">
+ <constant name="FEATURE_DETAIL" value="11" enum="Feature">
Constant for setting [member detail_enabled].
</constant>
- <constant name="FEATURE_MAX" value="11" enum="Feature">
+ <constant name="FEATURE_MAX" value="12" enum="Feature">
Represents the size of the [enum Feature] enum.
</constant>
<constant name="BLEND_MODE_MIX" value="0" enum="BlendMode">
@@ -589,11 +619,13 @@
Enables the shadow to opacity feature.
</constant>
<constant name="FLAG_USE_TEXTURE_REPEAT" value="16" enum="Flags">
+ Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture.
</constant>
<constant name="FLAG_INVERT_HEIGHTMAP" value="17" enum="Flags">
Invert values read from a depth texture to convert them to height values (heightmap).
</constant>
<constant name="FLAG_SUBSURFACE_MODE_SKIN" value="18" enum="Flags">
+ Enables the skin mode for subsurface scattering which is used to improve the look of subsurface scattering when used for human skin.
</constant>
<constant name="FLAG_MAX" value="19" enum="Flags">
Represents the size of the [enum Flags] enum.
diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml
index c2b821699d..df3ef71a2a 100644
--- a/doc/classes/CPUParticles2D.xml
+++ b/doc/classes/CPUParticles2D.xml
@@ -240,6 +240,7 @@
</member>
<member name="normalmap" type="Texture2D" setter="set_normalmap" getter="get_normalmap">
Normal map to be used for the [member texture] property.
+ [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false">
If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end.
diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml
index bfba23c7ee..598b4bd685 100644
--- a/doc/classes/Camera3D.xml
+++ b/doc/classes/Camera3D.xml
@@ -176,6 +176,7 @@
If not [constant DOPPLER_TRACKING_DISABLED], this camera will simulate the [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] for objects changed in particular [code]_process[/code] methods. See [enum DopplerTracking] for possible values.
</member>
<member name="effects" type="CameraEffects" setter="set_effects" getter="get_effects">
+ The [CameraEffects] to use for this camera.
</member>
<member name="environment" type="Environment" setter="set_environment" getter="get_environment">
The [Environment] to use for this camera.
@@ -183,8 +184,13 @@
<member name="far" type="float" setter="set_zfar" getter="get_zfar" default="100.0">
The distance to the far culling boundary for this camera relative to its local Z axis.
</member>
- <member name="fov" type="float" setter="set_fov" getter="get_fov" default="70.0">
+ <member name="fov" type="float" setter="set_fov" getter="get_fov" default="75.0">
The camera's field of view angle (in degrees). Only applicable in perspective mode. Since [member keep_aspect] locks one axis, [code]fov[/code] sets the other axis' field of view angle.
+ For reference, the default vertical field of view value ([code]75.0[/code]) is equivalent to an horizontal FOV of:
+ - ~91.31 degrees in a 4:3 viewport
+ - ~101.67 degrees in a 16:10 viewport
+ - ~107.51 degrees in a 16:9 viewport
+ - ~121.63 degrees in a 21:9 viewport
</member>
<member name="frustum_offset" type="Vector2" setter="set_frustum_offset" getter="get_frustum_offset" default="Vector2( 0, 0 )">
The camera's frustum offset. This can be changed from the default to create "tilted frustum" effects such as [url=https://zdoom.org/wiki/Y-shearing]Y-shearing[/url].
diff --git a/doc/classes/CameraEffects.xml b/doc/classes/CameraEffects.xml
index 23f0a1c7af..ea9ab85b80 100644
--- a/doc/classes/CameraEffects.xml
+++ b/doc/classes/CameraEffects.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CameraEffects" inherits="Resource" version="4.0">
<brief_description>
+ Contains camera-specific effects such as depth of field and exposure override.
</brief_description>
<description>
+ Contains camera-specific effects such as depth of field and exposure override.
+ See also [Environment] for general 3D environment settings.
</description>
<tutorials>
</tutorials>
@@ -10,22 +13,31 @@
</methods>
<members>
<member name="dof_blur_amount" type="float" setter="set_dof_blur_amount" getter="get_dof_blur_amount" default="0.1">
+ The amount of blur for both near and far depth-of-field effects. The amount of blur increases the radius of the blur effect, making the affected area blurrier. However, If the amount is too high, you might start to see lines appearing, especially when using a low quality blur.
</member>
<member name="dof_blur_far_distance" type="float" setter="set_dof_blur_far_distance" getter="get_dof_blur_far_distance" default="10.0">
+ The distance from the camera where the far blur effect affects the rendering.
</member>
<member name="dof_blur_far_enabled" type="bool" setter="set_dof_blur_far_enabled" getter="is_dof_blur_far_enabled" default="false">
+ If [code]true[/code], enables the depth-of-field far blur effect. This has a significant performance cost. Consider disabling it in scenes where there are no far away objects.
</member>
<member name="dof_blur_far_transition" type="float" setter="set_dof_blur_far_transition" getter="get_dof_blur_far_transition" default="5.0">
+ The length of the transition between the no-blur area and far blur.
</member>
<member name="dof_blur_near_distance" type="float" setter="set_dof_blur_near_distance" getter="get_dof_blur_near_distance" default="2.0">
+ Distance from the camera where the near blur effect affects the rendering.
</member>
<member name="dof_blur_near_enabled" type="bool" setter="set_dof_blur_near_enabled" getter="is_dof_blur_near_enabled" default="false">
+ If [code]true[/code], enables the depth-of-field near blur effect. This has a significant performance cost. Consider disabling it in scenes where there are no nearby objects.
</member>
<member name="dof_blur_near_transition" type="float" setter="set_dof_blur_near_transition" getter="get_dof_blur_near_transition" default="1.0">
+ The length of the transition between the near blur and no-blur area.
</member>
<member name="override_exposure" type="float" setter="set_override_exposure" getter="get_override_exposure" default="1.0">
+ The exposure override value to use. Higher values will result in a brighter scene. Only effective if [member override_exposure_enable] is [code]true[/code].
</member>
<member name="override_exposure_enable" type="bool" setter="set_override_exposure_enabled" getter="is_override_exposure_enabled" default="false">
+ If [code]true[/code], overrides the manual or automatic exposure defined in the [Environment] with the value in [member override_exposure].
</member>
</members>
<constants>
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index 38e4453cf2..b3a3722836 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -608,8 +608,10 @@
If [code]true[/code], the object draws on top of its parent.
</member>
<member name="texture_filter" type="int" setter="set_texture_filter" getter="get_texture_filter" enum="CanvasItem.TextureFilter" default="0">
+ The texture filtering mode to use on this [CanvasItem].
</member>
<member name="texture_repeat" type="int" setter="set_texture_repeat" getter="get_texture_repeat" enum="CanvasItem.TextureRepeat" default="0">
+ The texture repeating mode to use on this [CanvasItem].
</member>
<member name="use_parent_material" type="bool" setter="set_use_parent_material" getter="get_use_parent_material" default="false">
If [code]true[/code], the parent [CanvasItem]'s [member material] property is used as this one's material.
@@ -666,12 +668,18 @@
The texture filter blends between the nearest four pixels. Use this for most cases where you want to avoid a pixelated style.
</constant>
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="TextureFilter">
+ The texture filter reads from the nearest pixel in the nearest mipmap. This is the fastest way to read from textures with mipmaps.
</constant>
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="4" enum="TextureFilter">
+ The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps. Use this for non-pixel art textures that may be viewed at a low scale (e.g. due to [Camera2D] zoom), as mipmaps are important to smooth out pixels that are smaller than on-screen pixels.
</constant>
<constant name="TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="TextureFilter">
+ The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera.
+ [b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant TEXTURE_FILTER_NEAREST_WITH_MIPMAPS] is usually more appropriate.
</constant>
<constant name="TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="6" enum="TextureFilter">
+ The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing.
+ [b]Note:[/b] This texture filter is rarely useful in 2D projects. [constant TEXTURE_FILTER_LINEAR_WITH_MIPMAPS] is usually more appropriate.
</constant>
<constant name="TEXTURE_FILTER_MAX" value="7" enum="TextureFilter">
Represents the size of the [enum TextureFilter] enum.
diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml
index d495be2ffd..b35d4fb36a 100644
--- a/doc/classes/Color.xml
+++ b/doc/classes/Color.xml
@@ -42,6 +42,20 @@
<method name="Color">
<return type="Color">
</return>
+ <argument index="0" name="c" type="Color">
+ </argument>
+ <argument index="1" name="a" type="float">
+ </argument>
+ <description>
+ Constructs a color from an existing color, but with a custom alpha value.
+ [codeblock]
+ var red = Color(Color.red, 0.5) # 50% transparent red.
+ [/codeblock]
+ </description>
+ </method>
+ <method name="Color">
+ <return type="Color">
+ </return>
<argument index="0" name="r" type="float">
</argument>
<argument index="1" name="g" type="float">
@@ -149,32 +163,32 @@
Returns [code]true[/code] if this color and [code]color[/code] are approximately equal, by running [method @GDScript.is_equal_approx] on each component.
</description>
</method>
- <method name="lightened">
+ <method name="lerp">
<return type="Color">
</return>
- <argument index="0" name="amount" type="float">
+ <argument index="0" name="b" type="Color">
+ </argument>
+ <argument index="1" name="t" type="float">
</argument>
<description>
- Returns a new color resulting from making this color lighter by the specified percentage (ratio from 0 to 1).
+ Returns the linear interpolation with another color. The interpolation factor [code]t[/code] is between 0 and 1.
[codeblock]
- var green = Color(0.0, 1.0, 0.0)
- var lightgreen = green.lightened(0.2) # 20% lighter than regular green
+ var c1 = Color(1.0, 0.0, 0.0)
+ var c2 = Color(0.0, 1.0, 0.0)
+ var li_c = c1.lerp(c2, 0.5) # A color of an RGBA(128, 128, 0, 255)
[/codeblock]
</description>
</method>
- <method name="linear_interpolate">
+ <method name="lightened">
<return type="Color">
</return>
- <argument index="0" name="b" type="Color">
- </argument>
- <argument index="1" name="t" type="float">
+ <argument index="0" name="amount" type="float">
</argument>
<description>
- Returns the linear interpolation with another color. The interpolation factor [code]t[/code] is between 0 and 1.
+ Returns a new color resulting from making this color lighter by the specified percentage (ratio from 0 to 1).
[codeblock]
- var c1 = Color(1.0, 0.0, 0.0)
- var c2 = Color(0.0, 1.0, 0.0)
- var li_c = c1.linear_interpolate(c2, 0.5) # A color of an RGBA(128, 128, 0, 255)
+ var green = Color(0.0, 1.0, 0.0)
+ var lightgreen = green.lightened(0.2) # 20% lighter than regular green
[/codeblock]
</description>
</method>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 0c8d42021a..9dbb843902 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -798,11 +798,11 @@
Tells Godot which node it should give keyboard focus to if the user presses the top arrow on the keyboard or top on a gamepad by default. You can change the key by editing the [code]ui_top[/code] input action. The node must be a [Control]. If this property is not set, Godot will give focus to the closest [Control] to the bottom of this one.
</member>
<member name="focus_next" type="NodePath" setter="set_focus_next" getter="get_focus_next" default="NodePath(&quot;&quot;)">
- Tells Godot which node it should give keyboard focus to if the user presses Tab on a keyboard by default. You can change the key by editing the [code]ui_focus_next[/code] input action.
+ Tells Godot which node it should give keyboard focus to if the user presses [kbd]Tab[/kbd] on a keyboard by default. You can change the key by editing the [code]ui_focus_next[/code] input action.
If this property is not set, Godot will select a "best guess" based on surrounding nodes in the scene tree.
</member>
<member name="focus_previous" type="NodePath" setter="set_focus_previous" getter="get_focus_previous" default="NodePath(&quot;&quot;)">
- Tells Godot which node it should give keyboard focus to if the user presses Shift+Tab on a keyboard by default. You can change the key by editing the [code]ui_focus_prev[/code] input action.
+ Tells Godot which node it should give keyboard focus to if the user presses [kbd]Shift + Tab[/kbd] on a keyboard by default. You can change the key by editing the [code]ui_focus_prev[/code] input action.
If this property is not set, Godot will select a "best guess" based on surrounding nodes in the scene tree.
</member>
<member name="grow_horizontal" type="int" setter="set_h_grow_direction" getter="get_h_grow_direction" enum="Control.GrowDirection" default="1">
diff --git a/doc/classes/Cubemap.xml b/doc/classes/Cubemap.xml
index 16431c65c9..61cb1d43f0 100644
--- a/doc/classes/Cubemap.xml
+++ b/doc/classes/Cubemap.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="Cubemap" inherits="TextureLayered" version="4.0">
+<class name="Cubemap" inherits="ImageTextureLayered" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/CubemapArray.xml b/doc/classes/CubemapArray.xml
index 03cfd75acf..627baf79e0 100644
--- a/doc/classes/CubemapArray.xml
+++ b/doc/classes/CubemapArray.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="CubemapArray" inherits="TextureLayered" version="4.0">
+<class name="CubemapArray" inherits="ImageTextureLayered" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/Decal.xml b/doc/classes/Decal.xml
new file mode 100644
index 0000000000..f7329d1537
--- /dev/null
+++ b/doc/classes/Decal.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="Decal" inherits="VisualInstance3D" version="4.0">
+ <brief_description>
+ Node that projects a texture onto a [MeshInstance3D].
+ </brief_description>
+ <description>
+ [Decal]s are used to project a texture onto a [Mesh] in the scene. Use Decals to add detail to a scene without affecting the underlying [Mesh]. They are often used to add weathering to building, add dirt or mud to the ground, or add variety to props. Decals can be moved at any time, making them suitable for things like blob shadows or laser sight dots.
+ They are made of an [AABB] and a group of [Texture2D]s specifying [Color], normal, ORM (ambient occlusion, roughness, metallic), and emission. Decals are projected within their [AABB] so altering the orientation of the Decal affects the direction in which they are projected. By default, Decals are projected down (i.e. from positive Y to negative Y).
+ The [Texture2D]s associated with the Decal are automatically stored in a texture atlas which is used for drawing the decals so all decals can be drawn at once. Godot uses clustered decals, meaning they are stored in cluster data and drawn when the mesh is drawn, they are not drawn as a postprocessing effect after.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_texture" qualifiers="const">
+ <return type="Texture2D">
+ </return>
+ <argument index="0" name="type" type="int" enum="Decal.DecalTexture">
+ </argument>
+ <description>
+ Returns the [Texture2D] associated with the specified [enum DecalTexture]. This is a convenience method, in most cases you should access the texture directly.
+ For example, instead of [code]albedo_tex = $Decal.get_texture(Decal.TEXTURE_ALBEDO)[/code], use [code]albedo_tex = $Decal.texture_albedo[/code].
+ One case where this is better than accessing the texture directly is when you want to copy one Decal's textures to another. For example:
+ [codeblock]
+ for i in Decal.TEXTURE_MAX:
+ $NewDecal.set_texture(i, $OldDecal.get_texture(i))
+ [/codeblock]
+ </description>
+ </method>
+ <method name="set_texture">
+ <return type="void">
+ </return>
+ <argument index="0" name="type" type="int" enum="Decal.DecalTexture">
+ </argument>
+ <argument index="1" name="texture" type="Texture2D">
+ </argument>
+ <description>
+ Sets the [Texture2D] associated with the specified [enum DecalTexture]. This is a convenience method, in most cases you should access the texture directly.
+ For example, instead of [code]$Decal.set_texture(Decal.TEXTURE_ALBEDO, albedo_tex)[/code], use [code]$Decal.texture_albedo = albedo_tex[/code].
+ One case where this is better than accessing the texture directly is when you want to copy one Decal's textures to another. For example:
+ [codeblock]
+ for i in Decal.TEXTURE_MAX:
+ $NewDecal.set_texture(i, $OldDecal.get_texture(i))
+ [/codeblock]
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="albedo_mix" type="float" setter="set_albedo_mix" getter="get_albedo_mix" default="1.0">
+ Blends the albedo [Color] of the decal with albedo [Color] of the underlying mesh.
+ </member>
+ <member name="cull_mask" type="int" setter="set_cull_mask" getter="get_cull_mask" default="1048575">
+ Specifies which [member VisualInstance3D.layers] this decal will project on. By default, Decals affect all layers. This is used so you can specify which types of objects receive the Decal and which do not. This is especially useful so you an ensure that dynamic objects don't accidentally receive a Decal intended for the terrain under them.
+ </member>
+ <member name="distance_fade_begin" type="float" setter="set_distance_fade_begin" getter="get_distance_fade_begin" default="10.0">
+ Distance from the camera at which the Decal begins to fade away.
+ </member>
+ <member name="distance_fade_enabled" type="bool" setter="set_enable_distance_fade" getter="is_distance_fade_enabled" default="false">
+ If [code]true[/code], decals will smoothly fade away when far from the active [Camera3D] starting at [member distance_fade_begin]. The Decal will fade out over [member distance_fade_length], after which it will be culled and not sent to the shader at all. Use this to reduce the number of active Decals in a scene and thus improve performance.
+ </member>
+ <member name="distance_fade_length" type="float" setter="set_distance_fade_length" getter="get_distance_fade_length" default="1.0">
+ Distance over which the Decal fades. The Decal becomes slowly more transparent over this distance and is completely invisible at the end.
+ </member>
+ <member name="emission_energy" type="float" setter="set_emission_energy" getter="get_emission_energy" default="1.0">
+ Energy multiplier for the emission texture. This will make the decal emit light at a higher intensity.
+ </member>
+ <member name="extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3( 1, 1, 1 )">
+ Sets the size of the [AABB] used by the decal. The AABB goes from [code]-extents[/code] to [code]extents[/code].
+ </member>
+ <member name="lower_fade" type="float" setter="set_lower_fade" getter="get_lower_fade" default="0.3">
+ Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB].
+ </member>
+ <member name="modulate" type="Color" setter="set_modulate" getter="get_modulate" default="Color( 1, 1, 1, 1 )">
+ Changes the [Color] of the Decal by multiplying it with this value.
+ </member>
+ <member name="normal_fade" type="float" setter="set_normal_fade" getter="get_normal_fade" default="0.0">
+ Fades the Decal if the angle between the Decal's [AABB] and the target surface becomes too large. A value of [code]0[/code] projects the Decal regardless of angle, a value of [code]1[/code] limits the Decal to surfaces that are nearly perpendicular.
+ </member>
+ <member name="texture_albedo" type="Texture2D" setter="set_texture" getter="get_texture">
+ [Texture2D] with the base [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object.
+ </member>
+ <member name="texture_emission" type="Texture2D" setter="set_texture" getter="get_texture">
+ [Texture2D] with the emission [Color] of the Decal. Either this or the [member texture_emission] must be set for the Decal to be visible. Use the alpha channel like a mask to smoothly blend the edges of the decal with the underlying object.
+ </member>
+ <member name="texture_normal" type="Texture2D" setter="set_texture" getter="get_texture">
+ [Texture2D] with the per-pixel normalmap for the decal. Use this to add extra detail to decals.
+ </member>
+ <member name="texture_orm" type="Texture2D" setter="set_texture" getter="get_texture">
+ [Texture2D] storing ambient occlusion, roughness, and metallic for the decal. Use this to add extra detail to decals.
+ </member>
+ <member name="upper_fade" type="float" setter="set_upper_fade" getter="get_upper_fade" default="0.3">
+ Sets the curve over which the decal will fade as the surface gets further from the center of the [AABB].
+ </member>
+ </members>
+ <constants>
+ <constant name="TEXTURE_ALBEDO" value="0" enum="DecalTexture">
+ [Texture2D] corresponding to [member texture_albedo].
+ </constant>
+ <constant name="TEXTURE_NORMAL" value="1" enum="DecalTexture">
+ [Texture2D] corresponding to [member texture_normal].
+ </constant>
+ <constant name="TEXTURE_ORM" value="2" enum="DecalTexture">
+ [Texture2D] corresponding to [member texture_orm].
+ </constant>
+ <constant name="TEXTURE_EMISSION" value="3" enum="DecalTexture">
+ [Texture2D] corresponding to [member texture_emission].
+ </constant>
+ <constant name="TEXTURE_MAX" value="4" enum="DecalTexture">
+ Max size of [enum DecalTexture] enum.
+ </constant>
+ </constants>
+</class>
diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml
index e982e00d6d..385f4b7e59 100644
--- a/doc/classes/Dictionary.xml
+++ b/doc/classes/Dictionary.xml
@@ -7,6 +7,7 @@
Dictionary type. Associative container which contains values referenced by unique keys. Dictionaries are composed of pairs of keys (which must be unique) and values. Dictionaries will preserve the insertion order when adding elements, even though this may not be reflected when printing the dictionary. In other programming languages, this data structure is sometimes referred to as an hash map or associative array.
You can define a dictionary by placing a comma-separated list of [code]key: value[/code] pairs in curly braces [code]{}[/code].
Erasing elements while iterating over them [b]is not supported[/b] and will result in undefined behavior.
+ [b]Note:[/b] Dictionaries are always passed by reference. To get a copy of a dictionary which can be modified independently of the original dictionary, use [method duplicate].
Creating a dictionary:
[codeblock]
var my_dir = {} # Creates an empty dictionary.
diff --git a/doc/classes/DirectionalLight3D.xml b/doc/classes/DirectionalLight3D.xml
index a5d476f5c8..6c88dcf42e 100644
--- a/doc/classes/DirectionalLight3D.xml
+++ b/doc/classes/DirectionalLight3D.xml
@@ -12,9 +12,6 @@
<methods>
</methods>
<members>
- <member name="directional_shadow_bias_split_scale" type="float" setter="set_param" getter="get_param" default="0.25">
- Amount of extra bias for shadow splits that are far away. If self-shadowing occurs only on the splits far away, increasing this value can fix them.
- </member>
<member name="directional_shadow_blend_splits" type="bool" setter="set_blend_splits" getter="is_blend_splits_enabled" default="false">
If [code]true[/code], shadow detail is sacrificed in exchange for smoother transitions between splits.
</member>
@@ -22,6 +19,7 @@
Optimizes shadow rendering for detail versus movement. See [enum ShadowDepthRange].
</member>
<member name="directional_shadow_fade_start" type="float" setter="set_param" getter="get_param" default="0.8">
+ Proportion of [member directional_shadow_max_distance] at which point the shadow starts to fade. At [member directional_shadow_max_distance] the shadow will disappear.
</member>
<member name="directional_shadow_max_distance" type="float" setter="set_param" getter="get_param" default="100.0">
The maximum distance for shadow splits.
@@ -29,8 +27,8 @@
<member name="directional_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" enum="DirectionalLight3D.ShadowMode" default="2">
The light's shadow rendering algorithm. See [enum ShadowMode].
</member>
- <member name="directional_shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="0.8">
- Can be used to fix special cases of self shadowing when objects are perpendicular to the light.
+ <member name="directional_shadow_pancake_size" type="float" setter="set_param" getter="get_param" default="20.0">
+ Sets the size of the directional shadow pancake. The pancake offsets the start of the shadow's camera frustum to provide a higher effective depth resolution for the shadow. However, a high pancake size can cause artifacts in the shadows of large objects that are close to the edge of the frustum. Reducing the pancake size can help. Setting the size to [code]0[/code] turns off the pancaking effect.
</member>
<member name="directional_shadow_split_1" type="float" setter="set_param" getter="get_param" default="0.1">
The distance from camera to shadow split 1. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_2_SPLITS[/code] or [code]SHADOW_PARALLEL_4_SPLITS[/code].
@@ -41,7 +39,6 @@
<member name="directional_shadow_split_3" type="float" setter="set_param" getter="get_param" default="0.5">
The distance from shadow split 2 to split 3. Relative to [member directional_shadow_max_distance]. Only used when [member directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code].
</member>
- <member name="shadow_bias" type="float" setter="set_param" getter="get_param" override="true" default="0.1" />
</members>
<constants>
<constant name="SHADOW_ORTHOGONAL" value="0" enum="ShadowMode">
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 90828089f9..7fe712753c 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -592,6 +592,10 @@
</argument>
<argument index="2" name="max_length" type="int" default="-1">
</argument>
+ <argument index="3" name="cursor_start" type="int" default="-1">
+ </argument>
+ <argument index="4" name="cursor_end" type="int" default="-1">
+ </argument>
<description>
</description>
</method>
diff --git a/doc/classes/DynamicFont.xml b/doc/classes/DynamicFont.xml
index 11610fa523..0864c3ba36 100644
--- a/doc/classes/DynamicFont.xml
+++ b/doc/classes/DynamicFont.xml
@@ -12,7 +12,7 @@
dynamic_font.size = 64
$"Label".set("custom_fonts/font", dynamic_font)
[/codeblock]
- [b]Note:[/b] DynamicFont doesn't support features such as right-to-left typesetting, ligatures, text shaping, variable fonts and optional font features yet. If you wish to "bake" an optional font feature into a TTF font file, you can use [url=https://fontforge.org/]FontForge[/url] to do so. In FontForge, use [b]File > Generate Fonts[/b], click [b]Options[/b], choose the desired features then generate the font.
+ [b]Note:[/b] DynamicFont doesn't support features such as right-to-left typesetting, ligatures, text shaping, variable fonts and optional font features yet. If you wish to "bake" an optional font feature into a TTF font file, you can use [url=https://fontforge.org/]FontForge[/url] to do so. In FontForge, use [b]File &gt; Generate Fonts[/b], click [b]Options[/b], choose the desired features then generate the font.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/EditorFeatureProfile.xml b/doc/classes/EditorFeatureProfile.xml
index 53db8dd293..eb03d3010f 100644
--- a/doc/classes/EditorFeatureProfile.xml
+++ b/doc/classes/EditorFeatureProfile.xml
@@ -72,7 +72,7 @@
<argument index="0" name="path" type="String">
</argument>
<description>
- Saves the editor feature profile to a file in JSON format. It can then be imported using the feature profile manager's [b]Import[/b] button or the [method load_from_file] button.
+ Saves the editor feature profile to a file in JSON format. It can then be imported using the feature profile manager's [b]Import[/b] button or the [method load_from_file] button.
</description>
</method>
<method name="set_disable_class">
diff --git a/doc/classes/EditorFileSystem.xml b/doc/classes/EditorFileSystem.xml
index 30e1de1f5e..9bb51af2d0 100644
--- a/doc/classes/EditorFileSystem.xml
+++ b/doc/classes/EditorFileSystem.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
This object holds information of all resources in the filesystem, their types, etc.
+ [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_resource_filesystem].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/EditorInspector.xml b/doc/classes/EditorInspector.xml
index 61d240c1dc..2f62fe9e40 100644
--- a/doc/classes/EditorInspector.xml
+++ b/doc/classes/EditorInspector.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
The editor inspector is by default located on the right-hand side of the editor. It's used to edit the properties of the selected node. For example, you can select a node such as the Sprite2D then edit its transform through the inspector tool. The editor inspector is an essential tool in the game development workflow.
+ [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_inspector].
</description>
<tutorials>
</tutorials>
@@ -26,6 +27,12 @@
<description>
</description>
</signal>
+ <signal name="property_deleted">
+ <argument index="0" name="property" type="String">
+ </argument>
+ <description>
+ </description>
+ </signal>
<signal name="property_edited">
<argument index="0" name="property" type="String">
</argument>
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index 5e76f90fc4..499c3b8271 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
EditorInterface gives you control over Godot editor's window. It allows customizing the window, saving and (re-)loading scenes, rendering mesh previews, inspecting and editing resources and objects, and provides access to [EditorSettings], [EditorFileSystem], [EditorResourcePreview], [ScriptEditor], the editor viewport, and information about scenes.
+ [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorPlugin.get_editor_interface].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml
index 3216541b20..4da3b58b94 100644
--- a/doc/classes/EditorProperty.xml
+++ b/doc/classes/EditorProperty.xml
@@ -78,6 +78,8 @@
<member name="checked" type="bool" setter="set_checked" getter="is_checked" default="false">
Used by the inspector, when the property is checked.
</member>
+ <member name="deletable" type="bool" setter="set_deletable" getter="is_deletable" default="false">
+ </member>
<member name="draw_red" type="bool" setter="set_draw_red" getter="is_draw_red" default="false">
Used by the inspector, when the property must draw with error color.
</member>
@@ -128,6 +130,12 @@
Emitted when a property was checked. Used internally.
</description>
</signal>
+ <signal name="property_deleted">
+ <argument index="0" name="property" type="StringName">
+ </argument>
+ <description>
+ </description>
+ </signal>
<signal name="property_keyed">
<argument index="0" name="property" type="StringName">
</argument>
diff --git a/doc/classes/EditorResourcePreview.xml b/doc/classes/EditorResourcePreview.xml
index aac75c5c8e..0c1d969518 100644
--- a/doc/classes/EditorResourcePreview.xml
+++ b/doc/classes/EditorResourcePreview.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
This object is used to generate previews for resources of files.
+ [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_resource_previewer].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/EditorScript.xml b/doc/classes/EditorScript.xml
index 410301351f..e96044bf48 100644
--- a/doc/classes/EditorScript.xml
+++ b/doc/classes/EditorScript.xml
@@ -4,7 +4,7 @@
Base script that can be used to add extension functions to the editor.
</brief_description>
<description>
- Scripts extending this class and implementing its [method _run] method can be executed from the Script Editor's [b]File &gt; Run[/b] menu option (or by pressing [code]Ctrl+Shift+X[/code]) while the editor is running. This is useful for adding custom in-editor functionality to Godot. For more complex additions, consider using [EditorPlugin]s instead.
+ Scripts extending this class and implementing its [method _run] method can be executed from the Script Editor's [b]File &gt; Run[/b] menu option (or by pressing [kbd]Ctrl + Shift + X[/kbd]) while the editor is running. This is useful for adding custom in-editor functionality to Godot. For more complex additions, consider using [EditorPlugin]s instead.
[b]Note:[/b] Extending scripts need to have [code]tool[/code] mode enabled.
[b]Example script:[/b]
[codeblock]
diff --git a/doc/classes/EditorSelection.xml b/doc/classes/EditorSelection.xml
index caafd3c15f..1ff9744b70 100644
--- a/doc/classes/EditorSelection.xml
+++ b/doc/classes/EditorSelection.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
This object manages the SceneTree selection in the editor.
+ [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_selection].
</description>
<tutorials>
</tutorials>
@@ -26,7 +27,7 @@
</description>
</method>
<method name="get_selected_nodes">
- <return type="Array">
+ <return type="Node[]">
</return>
<description>
Gets the list of selected nodes.
diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml
index 73ef807c5f..19921ff5c8 100644
--- a/doc/classes/EditorSettings.xml
+++ b/doc/classes/EditorSettings.xml
@@ -11,6 +11,7 @@
settings.get(prop)
list_of_settings = settings.get_property_list()
[/codeblock]
+ [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_editor_settings].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Engine.xml b/doc/classes/Engine.xml
index 45c153b6dc..12701d8688 100644
--- a/doc/classes/Engine.xml
+++ b/doc/classes/Engine.xml
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Engine" inherits="Object" version="4.0">
<brief_description>
- Access to basic engine properties.
+ Access to engine properties.
</brief_description>
<description>
- The [Engine] class allows you to query and modify the project's run-time parameters, such as frames per second, time scale, and others.
+ The [Engine] singleton allows you to query and modify the project's run-time parameters, such as frames per second, time scale, and others.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml
index 6f55bfc229..3642d92771 100644
--- a/doc/classes/Environment.xml
+++ b/doc/classes/Environment.xml
@@ -265,18 +265,25 @@
Represents the size of the [enum BGMode] enum.
</constant>
<constant name="AMBIENT_SOURCE_BG" value="0" enum="AmbientSource">
+ Gather ambient light from whichever source is specified as the background.
</constant>
<constant name="AMBIENT_SOURCE_DISABLED" value="1" enum="AmbientSource">
+ Disable ambient light.
</constant>
<constant name="AMBIENT_SOURCE_COLOR" value="2" enum="AmbientSource">
+ Specify a specific [Color] for ambient light.
</constant>
<constant name="AMBIENT_SOURCE_SKY" value="3" enum="AmbientSource">
+ Gather ambient light from the [Sky] regardless of what the background is.
</constant>
<constant name="REFLECTION_SOURCE_BG" value="0" enum="ReflectionSource">
+ Use the background for reflections.
</constant>
<constant name="REFLECTION_SOURCE_DISABLED" value="1" enum="ReflectionSource">
+ Disable reflections.
</constant>
<constant name="REFLECTION_SOURCE_SKY" value="2" enum="ReflectionSource">
+ Use the [Sky] for reflections regardless of what the background is.
</constant>
<constant name="GLOW_BLEND_MODE_ADDITIVE" value="0" enum="GlowBlendMode">
Additive glow blending mode. Mostly used for particles, glows (bloom), lens flare, bright sources.
@@ -291,6 +298,7 @@
Replace glow blending mode. Replaces all pixels' color by the glow value. This can be used to simulate a full-screen blur effect by tweaking the glow parameters to match the original image's brightness.
</constant>
<constant name="GLOW_BLEND_MODE_MIX" value="4" enum="GlowBlendMode">
+ Mixes the glow with the underlying color to avoid increasing brightness as much while still maintaining a glow effect.
</constant>
<constant name="TONE_MAPPER_LINEAR" value="0" enum="ToneMapper">
Linear tonemapper operator. Reads the linear data and passes it on unmodified.
@@ -314,7 +322,7 @@
2×2 blur for the screen-space ambient occlusion effect.
</constant>
<constant name="SSAO_BLUR_3x3" value="3" enum="SSAOBlur">
- 3×3 blur for the screen-space ambient occlusion effect (slowest).
+ 3×3 blur for the screen-space ambient occlusion effect. Increases the radius of the blur for a smoother look, but can result in checkerboard-like artifacts.
</constant>
</constants>
</class>
diff --git a/doc/classes/GIProbe.xml b/doc/classes/GIProbe.xml
index df50244c77..23dd562653 100644
--- a/doc/classes/GIProbe.xml
+++ b/doc/classes/GIProbe.xml
@@ -19,7 +19,7 @@
<argument index="1" name="create_visual_debug" type="bool" default="false">
</argument>
<description>
- Bakes the effect from all [GeometryInstance3D]s marked with [member GeometryInstance3D.use_in_baked_light] and [Light3D]s marked with either [constant Light3D.BAKE_INDIRECT] or [constant Light3D.BAKE_ALL]. If [code]create_visual_debug[/code] is [code]true[/code], after baking the light, this will generate a [MultiMesh] that has a cube representing each solid cell with each cube colored to the cell's albedo color. This can be used to visualize the [GIProbe]'s data and debug any issues that may be occurring.
+ Bakes the effect from all [GeometryInstance3D]s marked with [constant GeometryInstance3D.GI_MODE_BAKED] and [Light3D]s marked with either [constant Light3D.BAKE_INDIRECT] or [constant Light3D.BAKE_ALL]. If [code]create_visual_debug[/code] is [code]true[/code], after baking the light, this will generate a [MultiMesh] that has a cube representing each solid cell with each cube colored to the cell's albedo color. This can be used to visualize the [GIProbe]'s data and debug any issues that may be occurring.
</description>
</method>
<method name="debug_bake">
diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml
index 64a2522f2f..ee67b5052c 100644
--- a/doc/classes/GPUParticles2D.xml
+++ b/doc/classes/GPUParticles2D.xml
@@ -53,6 +53,7 @@
</member>
<member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map">
Normal map to be used for the [member texture] property.
+ [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false">
If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end.
diff --git a/doc/classes/Generic6DOFJoint3D.xml b/doc/classes/Generic6DOFJoint3D.xml
index fae567dc58..ae86ab7365 100644
--- a/doc/classes/Generic6DOFJoint3D.xml
+++ b/doc/classes/Generic6DOFJoint3D.xml
@@ -373,6 +373,12 @@
<constant name="PARAM_LINEAR_MOTOR_FORCE_LIMIT" value="6" enum="Param">
The maximum force the linear motor will apply while trying to reach the velocity target.
</constant>
+ <constant name="PARAM_LINEAR_SPRING_STIFFNESS" value="7" enum="Param">
+ </constant>
+ <constant name="PARAM_LINEAR_SPRING_DAMPING" value="8" enum="Param">
+ </constant>
+ <constant name="PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT" value="9" enum="Param">
+ </constant>
<constant name="PARAM_ANGULAR_LOWER_LIMIT" value="10" enum="Param">
The minimum rotation in negative direction to break loose and rotate around the axes.
</constant>
@@ -400,6 +406,12 @@
<constant name="PARAM_ANGULAR_MOTOR_FORCE_LIMIT" value="18" enum="Param">
Maximum acceleration for the motor at the axes.
</constant>
+ <constant name="PARAM_ANGULAR_SPRING_STIFFNESS" value="19" enum="Param">
+ </constant>
+ <constant name="PARAM_ANGULAR_SPRING_DAMPING" value="20" enum="Param">
+ </constant>
+ <constant name="PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT" value="21" enum="Param">
+ </constant>
<constant name="PARAM_MAX" value="22" enum="Param">
Represents the size of the [enum Param] enum.
</constant>
diff --git a/doc/classes/GeometryInstance3D.xml b/doc/classes/GeometryInstance3D.xml
index 7df5f0ea50..cc85ce295b 100644
--- a/doc/classes/GeometryInstance3D.xml
+++ b/doc/classes/GeometryInstance3D.xml
@@ -9,13 +9,12 @@
<tutorials>
</tutorials>
<methods>
- <method name="get_flag" qualifiers="const">
- <return type="bool">
+ <method name="get_shader_instance_uniform" qualifiers="const">
+ <return type="Variant">
</return>
- <argument index="0" name="flag" type="int" enum="GeometryInstance3D.Flags">
+ <argument index="0" name="uniform" type="StringName">
</argument>
<description>
- Returns the [enum GeometryInstance3D.Flags] that have been set for this object.
</description>
</method>
<method name="set_custom_aabb">
@@ -27,15 +26,14 @@
Overrides the bounding box of this node with a custom one. To remove it, set an [AABB] with all fields set to zero.
</description>
</method>
- <method name="set_flag">
+ <method name="set_shader_instance_uniform">
<return type="void">
</return>
- <argument index="0" name="flag" type="int" enum="GeometryInstance3D.Flags">
+ <argument index="0" name="uniform" type="StringName">
</argument>
- <argument index="1" name="value" type="bool">
+ <argument index="1" name="value" type="Variant">
</argument>
<description>
- Sets the [enum GeometryInstance3D.Flags] specified. See [enum GeometryInstance3D.Flags] for options.
</description>
</method>
</methods>
@@ -46,6 +44,10 @@
<member name="extra_cull_margin" type="float" setter="set_extra_cull_margin" getter="get_extra_cull_margin" default="0.0">
The extra distance added to the GeometryInstance3D's bounding box ([AABB]) to increase its cull box.
</member>
+ <member name="gi_lightmap_scale" type="int" setter="set_lightmap_scale" getter="get_lightmap_scale" enum="GeometryInstance3D.LightmapScale" default="0">
+ </member>
+ <member name="gi_mode" type="int" setter="set_gi_mode" getter="get_gi_mode" enum="GeometryInstance3D.GIMode" default="0">
+ </member>
<member name="lod_max_distance" type="float" setter="set_lod_max_distance" getter="get_lod_max_distance" default="0.0">
The GeometryInstance3D's max LOD distance.
[b]Note:[/b] This property currently has no effect.
@@ -66,11 +68,6 @@
The material override for the whole geometry.
If a material is assigned to this property, it will be used instead of any material set in any material slot of the mesh.
</member>
- <member name="use_dynamic_gi" type="bool" setter="set_flag" getter="get_flag" default="false">
- </member>
- <member name="use_in_baked_light" type="bool" setter="set_flag" getter="get_flag" default="false">
- If [code]true[/code], this GeometryInstance3D will be used when baking lights using a [GIProbe].
- </member>
</members>
<constants>
<constant name="SHADOW_CASTING_SETTING_OFF" value="0" enum="ShadowCastingSetting">
@@ -88,16 +85,21 @@
Will only show the shadows casted from this object.
In other words, the actual mesh will not be visible, only the shadows casted from the mesh will be.
</constant>
- <constant name="FLAG_USE_BAKED_LIGHT" value="0" enum="Flags">
- Will allow the GeometryInstance3D to be used when baking lights using a [GIProbe].
+ <constant name="GI_MODE_DISABLED" value="0" enum="GIMode">
+ </constant>
+ <constant name="GI_MODE_BAKED" value="1" enum="GIMode">
+ </constant>
+ <constant name="GI_MODE_DYNAMIC" value="2" enum="GIMode">
+ </constant>
+ <constant name="LIGHTMAP_SCALE_1X" value="0" enum="LightmapScale">
+ </constant>
+ <constant name="LIGHTMAP_SCALE_2X" value="1" enum="LightmapScale">
</constant>
- <constant name="FLAG_USE_DYNAMIC_GI" value="1" enum="Flags">
+ <constant name="LIGHTMAP_SCALE_4X" value="2" enum="LightmapScale">
</constant>
- <constant name="FLAG_DRAW_NEXT_FRAME_IF_VISIBLE" value="2" enum="Flags">
- Unused in this class, exposed for consistency with [enum RenderingServer.InstanceFlags].
+ <constant name="LIGHTMAP_SCALE_8X" value="3" enum="LightmapScale">
</constant>
- <constant name="FLAG_MAX" value="3" enum="Flags">
- Represents the size of the [enum Flags] enum.
+ <constant name="LIGHTMAP_SCALE_MAX" value="4" enum="LightmapScale">
</constant>
</constants>
</class>
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index c41ffd4bff..9d00ffe233 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -240,7 +240,7 @@
</signal>
<signal name="copy_nodes_request">
<description>
- Emitted when the user presses [code]Ctrl + C[/code].
+ Emitted when the user presses [kbd]Ctrl + C[/kbd].
</description>
</signal>
<signal name="delete_nodes_request">
@@ -273,9 +273,15 @@
Emitted when a GraphNode is selected.
</description>
</signal>
+ <signal name="node_unselected">
+ <argument index="0" name="node" type="Node">
+ </argument>
+ <description>
+ </description>
+ </signal>
<signal name="paste_nodes_request">
<description>
- Emitted when the user presses [code]Ctrl + V[/code].
+ Emitted when the user presses [kbd]Ctrl + V[/kbd].
</description>
</signal>
<signal name="popup_request">
diff --git a/doc/classes/HSlider.xml b/doc/classes/HSlider.xml
index 2738958058..afe9d10d2e 100644
--- a/doc/classes/HSlider.xml
+++ b/doc/classes/HSlider.xml
@@ -19,6 +19,8 @@
<theme_item name="grabber_area" type="StyleBox">
The background of the area to the left of the grabber.
</theme_item>
+ <theme_item name="grabber_area_highlight" type="StyleBox">
+ </theme_item>
<theme_item name="grabber_disabled" type="Texture2D">
The texture for the grabber when it's disabled.
</theme_item>
diff --git a/doc/classes/IP_Unix.xml b/doc/classes/IP_Unix.xml
deleted file mode 100644
index 79cdf2ce08..0000000000
--- a/doc/classes/IP_Unix.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="IP_Unix" inherits="IP" version="4.0">
- <brief_description>
- UNIX IP support. See [IP].
- </brief_description>
- <description>
- UNIX-specific implementation of IP support functions. See [IP].
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml
index 8cffe07fc0..55d2275194 100644
--- a/doc/classes/Image.xml
+++ b/doc/classes/Image.xml
@@ -190,13 +190,6 @@
<description>
</description>
</method>
- <method name="expand_x2_hq2x">
- <return type="void">
- </return>
- <description>
- Stretches the image and enlarges it by a factor of 2. No interpolation is done.
- </description>
- </method>
<method name="fill">
<return type="void">
</return>
@@ -350,7 +343,7 @@
<argument index="0" name="path" type="String">
</argument>
<description>
- Loads an image from file [code]path[/code].
+ Loads an image from file [code]path[/code]. See [url=https://docs.godotengine.org/en/latest/getting_started/workflow/assets/importing_images.html#supported-image-formats]Supported image formats[/url] for a list of supported image formats and limitations.
</description>
</method>
<method name="load_jpg_from_buffer">
diff --git a/doc/classes/ImageTextureLayered.xml b/doc/classes/ImageTextureLayered.xml
new file mode 100644
index 0000000000..d06b44afa9
--- /dev/null
+++ b/doc/classes/ImageTextureLayered.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="ImageTextureLayered" inherits="TextureLayered" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="create_from_images">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="images" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="update_layer">
+ <return type="void">
+ </return>
+ <argument index="0" name="image" type="Image">
+ </argument>
+ <argument index="1" name="layer" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/ImmediateGeometry3D.xml b/doc/classes/ImmediateGeometry3D.xml
index 1c0831c922..d2d663847f 100644
--- a/doc/classes/ImmediateGeometry3D.xml
+++ b/doc/classes/ImmediateGeometry3D.xml
@@ -5,6 +5,9 @@
</brief_description>
<description>
Draws simple geometry from code. Uses a drawing mode similar to OpenGL 1.x.
+ See also [ArrayMesh], [MeshDataTool] and [SurfaceTool] for procedural geometry generation.
+ [b]Note:[/b] ImmediateGeometry3D is best suited to small amounts of mesh data that change every frame. It will be slow when handling large amounts of mesh data. If mesh data doesn't change often, use [ArrayMesh], [MeshDataTool] or [SurfaceTool] instead.
+ [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/InputFilter.xml b/doc/classes/Input.xml
index 54184ae8a3..fc3c3776ce 100644
--- a/doc/classes/InputFilter.xml
+++ b/doc/classes/Input.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="InputFilter" inherits="Object" version="4.0">
+<class name="Input" inherits="Object" version="4.0">
<brief_description>
A singleton that deals with inputs.
</brief_description>
@@ -68,7 +68,7 @@
</description>
</method>
<method name="get_current_cursor_shape" qualifiers="const">
- <return type="int" enum="InputFilter.CursorShape">
+ <return type="int" enum="Input.CursorShape">
</return>
<description>
Returns the currently assigned cursor shape (see [enum CursorShape]).
@@ -96,7 +96,7 @@
<argument index="1" name="axis" type="int">
</argument>
<description>
- Returns the current value of the joypad axis at given index (see [enum JoystickList]).
+ Returns the current value of the joypad axis at given index (see [enum JoyAxisList]).
</description>
</method>
<method name="get_joy_axis_index_from_string">
@@ -114,7 +114,7 @@
<argument index="0" name="axis_index" type="int">
</argument>
<description>
- Receives a [enum JoystickList] axis and returns its equivalent name as a string.
+ Receives a [enum JoyAxisList] axis and returns its equivalent name as a string.
</description>
</method>
<method name="get_joy_button_index_from_string">
@@ -132,7 +132,7 @@
<argument index="0" name="button_index" type="int">
</argument>
<description>
- Receives a gamepad button from [enum JoystickList] and returns its equivalent name as a string.
+ Receives a gamepad button from [enum JoyButtonList] and returns its equivalent name as a string.
</description>
</method>
<method name="get_joy_guid" qualifiers="const">
@@ -193,7 +193,7 @@
</description>
</method>
<method name="get_mouse_mode" qualifiers="const">
- <return type="int" enum="InputFilter.MouseMode">
+ <return type="int" enum="Input.MouseMode">
</return>
<description>
Returns the mouse mode. See the constants for more information.
@@ -235,7 +235,7 @@
<argument index="1" name="button" type="int">
</argument>
<description>
- Returns [code]true[/code] if you are pressing the joypad button (see [enum JoystickList]).
+ Returns [code]true[/code] if you are pressing the joypad button (see [enum JoyButtonList]).
</description>
</method>
<method name="is_joy_known">
@@ -244,7 +244,7 @@
<argument index="0" name="device" type="int">
</argument>
<description>
- Returns [code]true[/code] if the system knows the specified device. This means that it sets all button and axis indices exactly as defined in [enum JoystickList]. Unknown joypads are not expected to match these constants, but you can still retrieve events from them.
+ Returns [code]true[/code] if the system knows the specified device. This means that it sets all button and axis indices. Unknown joypads are not expected to match these constants, but you can still retrieve events from them.
</description>
</method>
<method name="is_key_pressed" qualifiers="const">
@@ -277,7 +277,7 @@
<argument index="3" name="guid" type="String">
</argument>
<description>
- Notifies the [InputFilter] singleton that a connection has changed, to update the state for the [code]device[/code] index.
+ Notifies the [Input] singleton that a connection has changed, to update the state for the [code]device[/code] index.
This is used internally and should not have to be called from user scripts. See [signal joy_connection_changed] for the signal emitted when this is triggered internally.
</description>
</method>
@@ -293,7 +293,7 @@
var a = InputEventAction.new()
a.action = "ui_cancel"
a.pressed = true
- InputFilter.parse_input_event(a)
+ Input.parse_input_event(a)
[/codeblock]
</description>
</method>
@@ -311,7 +311,7 @@
</return>
<argument index="0" name="image" type="Resource">
</argument>
- <argument index="1" name="shape" type="int" enum="InputFilter.CursorShape" default="0">
+ <argument index="1" name="shape" type="int" enum="Input.CursorShape" default="0">
</argument>
<argument index="2" name="hotspot" type="Vector2" default="Vector2( 0, 0 )">
</argument>
@@ -326,7 +326,7 @@
<method name="set_default_cursor_shape">
<return type="void">
</return>
- <argument index="0" name="shape" type="int" enum="InputFilter.CursorShape" default="0">
+ <argument index="0" name="shape" type="int" enum="Input.CursorShape" default="0">
</argument>
<description>
Sets the default cursor shape to be used in the viewport instead of [constant CURSOR_ARROW].
@@ -337,7 +337,7 @@
<method name="set_mouse_mode">
<return type="void">
</return>
- <argument index="0" name="mode" type="int" enum="InputFilter.MouseMode">
+ <argument index="0" name="mode" type="int" enum="Input.MouseMode">
</argument>
<description>
Sets the mouse mode. See the constants for more information.
diff --git a/doc/classes/InputEventJoypadButton.xml b/doc/classes/InputEventJoypadButton.xml
index 19aa97e1ec..7876bace75 100644
--- a/doc/classes/InputEventJoypadButton.xml
+++ b/doc/classes/InputEventJoypadButton.xml
@@ -13,7 +13,7 @@
</methods>
<members>
<member name="button_index" type="int" setter="set_button_index" getter="get_button_index" default="0">
- Button identifier. One of the [enum JoystickList] button constants.
+ Button identifier. One of the [enum JoyButtonList] button constants.
</member>
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" default="false">
If [code]true[/code], the button's state is pressed. If [code]false[/code], the button's state is released.
diff --git a/doc/classes/InputEventJoypadMotion.xml b/doc/classes/InputEventJoypadMotion.xml
index 01e02b79b1..bfd961ce1f 100644
--- a/doc/classes/InputEventJoypadMotion.xml
+++ b/doc/classes/InputEventJoypadMotion.xml
@@ -13,7 +13,7 @@
</methods>
<members>
<member name="axis" type="int" setter="set_axis" getter="get_axis" default="0">
- Axis identifier. Use one of the [enum JoystickList] axis constants.
+ Axis identifier. Use one of the [enum JoyAxisList] axis constants.
</member>
<member name="axis_value" type="float" setter="set_axis_value" getter="get_axis_value" default="0.0">
Current position of the joystick on the given axis. The value ranges from [code]-1.0[/code] to [code]1.0[/code]. A value of [code]0[/code] means the axis is in its resting position.
diff --git a/doc/classes/InputEventKey.xml b/doc/classes/InputEventKey.xml
index 34afa90553..767e67c615 100644
--- a/doc/classes/InputEventKey.xml
+++ b/doc/classes/InputEventKey.xml
@@ -14,7 +14,7 @@
<return type="int">
</return>
<description>
- Returns the keycode combined with modifier keys such as [code]Shift[/code] or [code]Alt[/code]. See also [InputEventWithModifiers].
+ Returns the keycode combined with modifier keys such as [kbd]Shift[/kbd] or [kbd]Alt[/kbd]. See also [InputEventWithModifiers].
To get a human-readable representation of the [InputEventKey] with modifiers, use [code]OS.get_keycode_string(event.get_keycode_with_modifiers())[/code] where [code]event[/code] is the [InputEventKey].
</description>
</method>
@@ -22,7 +22,7 @@
<return type="int">
</return>
<description>
- Returns the physical keycode combined with modifier keys such as [code]Shift[/code] or [code]Alt[/code]. See also [InputEventWithModifiers].
+ Returns the physical keycode combined with modifier keys such as [kbd]Shift[/kbd] or [kbd]Alt[/kbd]. See also [InputEventWithModifiers].
To get a human-readable representation of the [InputEventKey] with modifiers, use [code]OS.get_keycode_string(event.get_physical_keycode_with_modifiers())[/code] where [code]event[/code] is the [InputEventKey].
</description>
</method>
diff --git a/doc/classes/InputEventWithModifiers.xml b/doc/classes/InputEventWithModifiers.xml
index 34faf18e24..cc7de2ca32 100644
--- a/doc/classes/InputEventWithModifiers.xml
+++ b/doc/classes/InputEventWithModifiers.xml
@@ -4,7 +4,7 @@
Base class for keys events with modifiers.
</brief_description>
<description>
- Contains keys events information with modifiers support like [code]Shift[/code] or [code]Alt[/code]. See [method Node._input].
+ Contains keys events information with modifiers support like [kbd]Shift[/kbd] or [kbd]Alt[/kbd]. See [method Node._input].
</description>
<tutorials>
<link>https://docs.godotengine.org/en/latest/tutorials/inputs/inputevent.html</link>
@@ -13,19 +13,19 @@
</methods>
<members>
<member name="alt" type="bool" setter="set_alt" getter="get_alt" default="false">
- State of the [code]Alt[/code] modifier.
+ State of the [kbd]Alt[/kbd] modifier.
</member>
<member name="command" type="bool" setter="set_command" getter="get_command" default="false">
- State of the [code]Command[/code] modifier.
+ State of the [kbd]Cmd[/kbd] modifier.
</member>
<member name="control" type="bool" setter="set_control" getter="get_control" default="false">
- State of the [code]Ctrl[/code] modifier.
+ State of the [kbd]Ctrl[/kbd] modifier.
</member>
<member name="meta" type="bool" setter="set_metakey" getter="get_metakey" default="false">
- State of the [code]Meta[/code] modifier.
+ State of the [kbd]Meta[/kbd] modifier.
</member>
<member name="shift" type="bool" setter="set_shift" getter="get_shift" default="false">
- State of the [code]Shift[/code] modifier.
+ State of the [kbd]Shift[/kbd] modifier.
</member>
</members>
<constants>
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml
index c6ed1e22ed..25420bd77b 100644
--- a/doc/classes/ItemList.xml
+++ b/doc/classes/ItemList.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
This control provides a selectable list of items that may be in a single (or multiple columns) with option of text, icons, or both text and icon. Tooltips are supported and may be different for every item in the list.
- Selectable items in the list may be selected or deselected and multiple selection may be enabled. Selection with right mouse button may also be enabled to allow use of popup context menus. Items may also be "activated" by double-clicking them or by pressing Enter.
+ Selectable items in the list may be selected or deselected and multiple selection may be enabled. Selection with right mouse button may also be enabled to allow use of popup context menus. Items may also be "activated" by double-clicking them or by pressing [kbd]Enter[/kbd].
Item text only supports single-line strings, newline characters (e.g. [code]\n[/code]) in the string won't produce a newline. Text wrapping is enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to fully fit its content by default. You need to set [member fixed_column_width] greater than zero to wrap the text.
</description>
<tutorials>
@@ -278,7 +278,7 @@
</argument>
<description>
Disables (or enables) the item at the specified index.
- Disabled items cannot be selected and do not trigger activation signals (when double-clicking or pressing Enter).
+ Disabled items cannot be selected and do not trigger activation signals (when double-clicking or pressing [kbd]Enter[/kbd]).
</description>
</method>
<method name="set_item_icon">
@@ -452,7 +452,7 @@
<argument index="0" name="index" type="int">
</argument>
<description>
- Triggered when specified list item is activated via double-clicking or by pressing Enter.
+ Triggered when specified list item is activated via double-clicking or by pressing [kbd]Enter[/kbd].
</description>
</signal>
<signal name="item_rmb_selected">
@@ -508,7 +508,7 @@
Only allow selecting a single item.
</constant>
<constant name="SELECT_MULTI" value="1" enum="SelectMode">
- Allows selecting multiple items by holding Ctrl or Shift.
+ Allows selecting multiple items by holding [kbd]Ctrl[/kbd] or [kbd]Shift[/kbd].
</constant>
</constants>
<theme_items>
diff --git a/doc/classes/MonoGCHandle.xml b/doc/classes/JNISingleton.xml
index 1e33dd1359..84ab1a49c1 100644
--- a/doc/classes/MonoGCHandle.xml
+++ b/doc/classes/JNISingleton.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="MonoGCHandle" inherits="Reference" version="4.0">
+<class name="JNISingleton" inherits="Object" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/KinematicBody3D.xml b/doc/classes/KinematicBody3D.xml
index 5f9b36f97d..5477c6bab6 100644
--- a/doc/classes/KinematicBody3D.xml
+++ b/doc/classes/KinematicBody3D.xml
@@ -18,7 +18,7 @@
<argument index="0" name="axis" type="int" enum="PhysicsServer3D.BodyAxis">
</argument>
<description>
- Returns [code]true[/code] if the specified [code]axis[/code] is locked. See also [member move_lock_x], [member move_lock_y] and [member move_lock_z].
+ Returns [code]true[/code] if the specified [code]axis[/code] is locked. See also [member axis_lock_motion_x], [member axis_lock_motion_y] and [member axis_lock_motion_z].
</description>
</method>
<method name="get_floor_normal" qualifiers="const">
@@ -108,7 +108,7 @@
This method should be used in [method Node._physics_process] (or in a method called by [method Node._physics_process]), as it uses the physics step's [code]delta[/code] value automatically in calculations. Otherwise, the simulation will run at an incorrect speed.
[code]linear_velocity[/code] is the velocity vector (typically meters per second). Unlike in [method move_and_collide], you should [i]not[/i] multiply it by [code]delta[/code] — the physics engine handles applying the velocity.
[code]up_direction[/code] is the up direction, used to determine what is a wall and what is a floor or a ceiling. If set to the default value of [code]Vector3(0, 0, 0)[/code], everything is considered a wall.
- If [code]stop_on_slope[/code] is [code]true[/code], body will not slide on slopes if you include gravity in [code]linear_velocity[/code].
+ If [code]stop_on_slope[/code] is [code]true[/code], body will not slide on slopes when you include gravity in [code]linear_velocity[/code] and the body is standing still.
If the body collides, it will change direction a maximum of [code]max_slides[/code] times before it stops.
[code]floor_max_angle[/code] is the maximum angle (in radians) where a slope is still considered a floor (or a ceiling), rather than a wall. The default value equals 45 degrees.
If [code]infinite_inertia[/code] is [code]true[/code], body will be able to push [RigidBody3D] nodes, but it won't also detect any collisions with them. If [code]false[/code], it will interact with [RigidBody3D] nodes like with [StaticBody3D].
@@ -145,7 +145,7 @@
<argument index="1" name="lock" type="bool">
</argument>
<description>
- Locks or unlocks the specified [code]axis[/code] depending on the value of [code]lock[/code]. See also [member move_lock_x], [member move_lock_y] and [member move_lock_z].
+ Locks or unlocks the specified [code]axis[/code] depending on the value of [code]lock[/code]. See also [member axis_lock_motion_x], [member axis_lock_motion_y] and [member axis_lock_motion_z].
</description>
</method>
<method name="test_move">
@@ -163,18 +163,18 @@
</method>
</methods>
<members>
- <member name="collision/safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin" default="0.001">
- If the body is at least this close to another body, this body will consider them to be colliding.
- </member>
- <member name="move_lock_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
+ <member name="axis_lock_motion_x" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
Lock the body's X axis movement.
</member>
- <member name="move_lock_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
+ <member name="axis_lock_motion_y" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
Lock the body's Y axis movement.
</member>
- <member name="move_lock_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
+ <member name="axis_lock_motion_z" type="bool" setter="set_axis_lock" getter="get_axis_lock" default="false">
Lock the body's Z axis movement.
</member>
+ <member name="collision/safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin" default="0.001">
+ If the body is at least this close to another body, this body will consider them to be colliding.
+ </member>
</members>
<constants>
</constants>
diff --git a/doc/classes/Light3D.xml b/doc/classes/Light3D.xml
index 623b2a2bb0..cb21db2d00 100644
--- a/doc/classes/Light3D.xml
+++ b/doc/classes/Light3D.xml
@@ -56,13 +56,16 @@
<member name="light_negative" type="bool" setter="set_negative" getter="is_negative" default="false">
If [code]true[/code], the light's effect is reversed, darkening areas and casting bright shadows.
</member>
+ <member name="light_projector" type="Texture2D" setter="set_projector" getter="get_projector">
+ [Texture2D] projected by light. [member shadow_enabled] must be on for the projector to work. Light projectors make the light appear as if it is shining through a colored but transparent object, almost like light shining through stained glass.
+ </member>
<member name="light_size" type="float" setter="set_param" getter="get_param" default="0.0">
The size of the light in Godot units. Only available for [OmniLight3D]s and [SpotLight3D]s.
</member>
<member name="light_specular" type="float" setter="set_param" getter="get_param" default="0.5">
The intensity of the specular blob in objects affected by the light. At [code]0[/code] the light becomes a pure diffuse light.
</member>
- <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.15">
+ <member name="shadow_bias" type="float" setter="set_param" getter="get_param" default="0.02">
Used to adjust shadow appearance. Too small a value results in self-shadowing, while too large a value causes shadows to separate from casters. Adjust as needed.
</member>
<member name="shadow_blur" type="float" setter="set_param" getter="get_param" default="1.0">
@@ -71,15 +74,17 @@
<member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color( 0, 0, 0, 1 )">
The color of shadows cast by this light.
</member>
- <member name="shadow_contact" type="float" setter="set_param" getter="get_param" default="0.0">
- Attempts to reduce [member shadow_bias] gap.
- </member>
<member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow" default="false">
If [code]true[/code], the light will cast shadows.
</member>
+ <member name="shadow_normal_bias" type="float" setter="set_param" getter="get_param" default="1.0">
+ Offsets the lookup into the shadow map by the objects normal. This can be used reduce self-shadowing artifacts without using [member shadow_bias]. In practice, this value should be tweaked along with [member shadow_bias] to reduce artifacts as much as possible.
+ </member>
<member name="shadow_reverse_cull_face" type="bool" setter="set_shadow_reverse_cull_face" getter="get_shadow_reverse_cull_face" default="false">
If [code]true[/code], reverses the backface culling of the mesh. This can be useful when you have a flat mesh that has a light behind it. If you need to cast a shadow on both sides of the mesh, set the mesh to use double-sided shadows with [constant GeometryInstance3D.SHADOW_CASTING_SETTING_DOUBLE_SIDED].
</member>
+ <member name="shadow_transmittance_bias" type="float" setter="set_param" getter="get_param" default="0.05">
+ </member>
</members>
<constants>
<constant name="PARAM_ENERGY" value="0" enum="Param">
@@ -94,18 +99,18 @@
<constant name="PARAM_RANGE" value="3" enum="Param">
Constant for accessing [member OmniLight3D.omni_range] or [member SpotLight3D.spot_range].
</constant>
- <constant name="PARAM_ATTENUATION" value="4" enum="Param">
+ <constant name="PARAM_SIZE" value="4" enum="Param">
+ Constant for accessing [member light_size].
+ </constant>
+ <constant name="PARAM_ATTENUATION" value="5" enum="Param">
Constant for accessing [member OmniLight3D.omni_attenuation] or [member SpotLight3D.spot_attenuation].
</constant>
- <constant name="PARAM_SPOT_ANGLE" value="5" enum="Param">
+ <constant name="PARAM_SPOT_ANGLE" value="6" enum="Param">
Constant for accessing [member SpotLight3D.spot_angle].
</constant>
- <constant name="PARAM_SPOT_ATTENUATION" value="6" enum="Param">
+ <constant name="PARAM_SPOT_ATTENUATION" value="7" enum="Param">
Constant for accessing [member SpotLight3D.spot_angle_attenuation].
</constant>
- <constant name="PARAM_CONTACT_SHADOW_SIZE" value="7" enum="Param">
- Constant for accessing [member shadow_contact].
- </constant>
<constant name="PARAM_SHADOW_MAX_DISTANCE" value="8" enum="Param">
Constant for accessing [member DirectionalLight3D.directional_shadow_max_distance].
</constant>
@@ -119,17 +124,24 @@
Constant for accessing [member DirectionalLight3D.directional_shadow_split_3].
</constant>
<constant name="PARAM_SHADOW_FADE_START" value="12" enum="Param">
+ Constant for accessing [member DirectionalLight3D.directional_shadow_fade_start].
</constant>
<constant name="PARAM_SHADOW_NORMAL_BIAS" value="13" enum="Param">
- Constant for accessing [member DirectionalLight3D.directional_shadow_normal_bias].
+ Constant for accessing [member shadow_normal_bias].
</constant>
<constant name="PARAM_SHADOW_BIAS" value="14" enum="Param">
Constant for accessing [member shadow_bias].
</constant>
- <constant name="PARAM_SHADOW_BIAS_SPLIT_SCALE" value="15" enum="Param">
- Constant for accessing [member DirectionalLight3D.directional_shadow_bias_split_scale].
+ <constant name="PARAM_SHADOW_PANCAKE_SIZE" value="15" enum="Param">
+ Constant for accessing [member DirectionalLight3D.directional_shadow_pancake_size].
+ </constant>
+ <constant name="PARAM_SHADOW_BLUR" value="16" enum="Param">
+ Constant for accessing [member shadow_blur].
+ </constant>
+ <constant name="PARAM_TRANSMITTANCE_BIAS" value="17" enum="Param">
+ Constant for accessing [member shadow_transmittance_bias].
</constant>
- <constant name="PARAM_MAX" value="16" enum="Param">
+ <constant name="PARAM_MAX" value="18" enum="Param">
Represents the size of the [enum Param] enum.
</constant>
<constant name="BAKE_DISABLED" value="0" enum="BakeMode">
diff --git a/modules/bullet/doc_classes/BulletPhysicsServer3D.xml b/doc/classes/LightmapProbe.xml
index b20595b4f6..3af71f3774 100644
--- a/modules/bullet/doc_classes/BulletPhysicsServer3D.xml
+++ b/doc/classes/LightmapProbe.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="BulletPhysicsServer3D" inherits="PhysicsServer3D" version="4.0">
+<class name="LightmapProbe" inherits="Node3D" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/ResourceFormatSaverCrypto.xml b/doc/classes/Lightmapper.xml
index 31db8ff4f5..e80194858a 100644
--- a/doc/classes/ResourceFormatSaverCrypto.xml
+++ b/doc/classes/Lightmapper.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ResourceFormatSaverCrypto" inherits="ResourceFormatSaver" version="4.0">
+<class name="Lightmapper" inherits="Reference" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/ResourceFormatLoaderCrypto.xml b/doc/classes/LightmapperRD.xml
index fda529fdbd..0993b28f19 100644
--- a/doc/classes/ResourceFormatLoaderCrypto.xml
+++ b/doc/classes/LightmapperRD.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ResourceFormatLoaderCrypto" inherits="ResourceFormatLoader" version="4.0">
+<class name="LightmapperRD" inherits="Lightmapper" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/Line2D.xml b/doc/classes/Line2D.xml
index 68cec3e624..cfd23b28bd 100644
--- a/doc/classes/Line2D.xml
+++ b/doc/classes/Line2D.xml
@@ -72,7 +72,7 @@
<member name="begin_cap_mode" type="int" setter="set_begin_cap_mode" getter="get_begin_cap_mode" enum="Line2D.LineCapMode" default="0">
Controls the style of the line's first point. Use [enum LineCapMode] constants.
</member>
- <member name="default_color" type="Color" setter="set_default_color" getter="get_default_color" default="Color( 0.4, 0.5, 1, 1 )">
+ <member name="default_color" type="Color" setter="set_default_color" getter="get_default_color" default="Color( 1, 1, 1, 1 )">
The line's color. Will not be used if a gradient is set.
</member>
<member name="end_cap_mode" type="int" setter="set_end_cap_mode" getter="get_end_cap_mode" enum="Line2D.LineCapMode" default="0">
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index 447446ba10..3eeb892719 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -5,27 +5,27 @@
</brief_description>
<description>
LineEdit provides a single-line string editor, used for text fields.
- It features many built-in shortcuts which will always be available ([code]Ctrl[/code] here maps to [code]Command[/code] on macOS):
- - Ctrl + C: Copy
- - Ctrl + X: Cut
- - Ctrl + V or Ctrl + Y: Paste/"yank"
- - Ctrl + Z: Undo
- - Ctrl + Shift + Z: Redo
- - Ctrl + U: Delete text from the cursor position to the beginning of the line
- - Ctrl + K: Delete text from the cursor position to the end of the line
- - Ctrl + A: Select all text
- - Up/Down arrow: Move the cursor to the beginning/end of the line
+ It features many built-in shortcuts which will always be available ([kbd]Ctrl[/kbd] here maps to [kbd]Cmd[/kbd] on macOS):
+ - [kbd]Ctrl + C[/kbd]: Copy
+ - [kbd]Ctrl + X[/kbd]: Cut
+ - [kbd]Ctrl + V[/kbd] or [kbd]Ctrl + Y[/kbd]: Paste/"yank"
+ - [kbd]Ctrl + Z[/kbd]: Undo
+ - [kbd]Ctrl + Shift + Z[/kbd]: Redo
+ - [kbd]Ctrl + U[/kbd]: Delete text from the cursor position to the beginning of the line
+ - [kbd]Ctrl + K[/kbd]: Delete text from the cursor position to the end of the line
+ - [kbd]Ctrl + A[/kbd]: Select all text
+ - [kbd]Up Arrow[/kbd]/[kbd]Down Arrow[/kbd]: Move the cursor to the beginning/end of the line
On macOS, some extra keyboard shortcuts are available:
- - Ctrl + F: Like the right arrow key, move the cursor one character right
- - Ctrl + B: Like the left arrow key, move the cursor one character left
- - Ctrl + P: Like the up arrow key, move the cursor to the previous line
- - Ctrl + N: Like the down arrow key, move the cursor to the next line
- - Ctrl + D: Like the Delete key, delete the character on the right side of cursor
- - Ctrl + H: Like the Backspace key, delete the character on the left side of the cursor
- - Ctrl + A: Like the Home key, move the cursor to the beginning of the line
- - Ctrl + E: Like the End key, move the cursor to the end of the line
- - Command + Left arrow: Like the Home key, move the cursor to the beginning of the line
- - Command + Right arrow: Like the End key, move the cursor to the end of the line
+ - [kbd]Ctrl + F[/kbd]: Same as [kbd]Right Arrow[/kbd], move the cursor one character right
+ - [kbd]Ctrl + B[/kbd]: Same as [kbd]Left Arrow[/kbd], move the cursor one character left
+ - [kbd]Ctrl + P[/kbd]: Same as [kbd]Up Arrow[/kbd], move the cursor to the previous line
+ - [kbd]Ctrl + N[/kbd]: Same as [kbd]Down Arrow[/kbd], move the cursor to the next line
+ - [kbd]Ctrl + D[/kbd]: Same as [kbd]Delete[/kbd], delete the character on the right side of cursor
+ - [kbd]Ctrl + H[/kbd]: Same as [kbd]Backspace[/kbd], delete the character on the left side of the cursor
+ - [kbd]Ctrl + A[/kbd]: Same as [kbd]Home[/kbd], move the cursor to the beginning of the line
+ - [kbd]Ctrl + E[/kbd]: Same as [kbd]End[/kbd], move the cursor to the end of the line
+ - [kbd]Cmd + Left Arrow[/kbd]: Same as [kbd]Home[/kbd], move the cursor to the beginning of the line
+ - [kbd]Cmd + Right Arrow[/kbd]: Same as [kbd]End[/kbd], move the cursor to the end of the line
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/LineShape2D.xml b/doc/classes/LineShape2D.xml
index d3cfc94a8c..58caf1b1de 100644
--- a/doc/classes/LineShape2D.xml
+++ b/doc/classes/LineShape2D.xml
@@ -11,7 +11,7 @@
<methods>
</methods>
<members>
- <member name="d" type="float" setter="set_d" getter="get_d" default="0.0">
+ <member name="distance" type="float" setter="set_distance" getter="get_distance" default="0.0">
The line's distance from the origin.
</member>
<member name="normal" type="Vector2" setter="set_normal" getter="get_normal" default="Vector2( 0, 1 )">
diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml
index 6958c815a6..367099e455 100644
--- a/doc/classes/Mesh.xml
+++ b/doc/classes/Mesh.xml
@@ -102,7 +102,7 @@
</method>
</methods>
<members>
- <member name="lightmap_size_hint" type="Vector2" setter="set_lightmap_size_hint" getter="get_lightmap_size_hint" default="Vector2( 0, 0 )">
+ <member name="lightmap_size_hint" type="Vector2i" setter="set_lightmap_size_hint" getter="get_lightmap_size_hint" default="Vector2i( 0, 0 )">
Sets a hint to be used for lightmap resolution.
</member>
</members>
diff --git a/doc/classes/MeshDataTool.xml b/doc/classes/MeshDataTool.xml
index 81ff5969e3..dcc3bbf2a6 100644
--- a/doc/classes/MeshDataTool.xml
+++ b/doc/classes/MeshDataTool.xml
@@ -17,6 +17,8 @@
mesh.surface_remove(0)
mdt.commit_to_surface(mesh)
[/codeblock]
+ See also [ArrayMesh], [ImmediateGeometry3D] and [SurfaceTool] for procedural geometry generation.
+ [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/MeshInstance2D.xml b/doc/classes/MeshInstance2D.xml
index 0cfc8deb0a..689f8d83e1 100644
--- a/doc/classes/MeshInstance2D.xml
+++ b/doc/classes/MeshInstance2D.xml
@@ -17,6 +17,7 @@
</member>
<member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map">
The normal map that will be used if using the default [CanvasItemMaterial].
+ [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="texture" type="Texture2D" setter="set_texture" getter="get_texture">
The [Texture2D] that will be used if using the default [CanvasItemMaterial]. Can be accessed as [code]TEXTURE[/code] in CanvasItem shader.
diff --git a/doc/classes/MultiMeshInstance2D.xml b/doc/classes/MultiMeshInstance2D.xml
index 07f21514ef..a461c8e056 100644
--- a/doc/classes/MultiMeshInstance2D.xml
+++ b/doc/classes/MultiMeshInstance2D.xml
@@ -17,6 +17,7 @@
</member>
<member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map">
The normal map that will be used if using the default [CanvasItemMaterial].
+ [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="texture" type="Texture2D" setter="set_texture" getter="get_texture">
The [Texture2D] that will be used if using the default [CanvasItemMaterial]. Can be accessed as [code]TEXTURE[/code] in CanvasItem shader.
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 8c588f0373..04c8d2bf57 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -129,21 +129,19 @@
child_node.get_parent().remove_child(child_node)
add_child(child_node)
[/codeblock]
- If you need the child node to be added below a specific node in the list of children, use [method add_child_below_node] instead of this method.
+ If you need the child node to be added below a specific node in the list of children, use [method add_sibling] instead of this method.
[b]Note:[/b] If you want a child to be persisted to a [PackedScene], you must set [member owner] in addition to calling [method add_child]. This is typically relevant for [url=https://godot.readthedocs.io/en/latest/tutorials/misc/running_code_in_the_editor.html]tool scripts[/url] and [url=https://godot.readthedocs.io/en/latest/tutorials/plugins/editor/index.html]editor plugins[/url]. If [method add_child] is called without setting [member owner], the newly added [Node] will not be visible in the scene tree, though it will be visible in the 2D/3D view.
</description>
</method>
- <method name="add_child_below_node">
+ <method name="add_sibling">
<return type="void">
</return>
- <argument index="0" name="preceding_node" type="Node">
+ <argument index="0" name="sibling" type="Node">
</argument>
- <argument index="1" name="node" type="Node">
- </argument>
- <argument index="2" name="legible_unique_name" type="bool" default="false">
+ <argument index="1" name="legible_unique_name" type="bool" default="false">
</argument>
<description>
- Adds a child node below the [code]preceding_node[/code].
+ Adds a [code]sibling[/code] node to current's node parent, at the the same level as that node, right below it.
If [code]legible_unique_name[/code] is [code]true[/code], the child node will have an human-readable name based on the name of the node being instanced instead of its type.
Use [method add_child] instead of this method if you don't need the child node to be added below a specific node in the list of children.
</description>
@@ -221,7 +219,7 @@
</description>
</method>
<method name="get_children" qualifiers="const">
- <return type="Array">
+ <return type="Node[]">
</return>
<description>
Returns an array of references to node's children.
@@ -305,7 +303,7 @@
<return type="Node">
</return>
<description>
- Returns the parent node of the current node, or an empty [Node] if the node lacks a parent.
+ Returns the parent node of the current node, or a [code]null instance[/code] if the node lacks a parent.
</description>
</method>
<method name="get_path" qualifiers="const">
@@ -932,7 +930,7 @@
Implemented on all platforms.
</constant>
<constant name="NOTIFICATION_WM_CLOSE_REQUEST" value="1006">
- Notification received from the OS when a close request is sent (e.g. closing the window with a "Close" button or Alt+F4).
+ Notification received from the OS when a close request is sent (e.g. closing the window with a "Close" button or [kbd]Alt + F4[/kbd]).
Implemented on desktop platforms.
</constant>
<constant name="NOTIFICATION_WM_GO_BACK_REQUEST" value="1007">
diff --git a/doc/classes/Node2D.xml b/doc/classes/Node2D.xml
index 9f017e9aed..d29c556216 100644
--- a/doc/classes/Node2D.xml
+++ b/doc/classes/Node2D.xml
@@ -92,7 +92,7 @@
<argument index="0" name="local_point" type="Vector2">
</argument>
<description>
- Converts a local point's coordinates to global coordinates.
+ Transforms the provided local position into a position in global coordinate space. The input is expected to be local relative to the [Node2D] it is called on. e.g. Applying this method to the positions of child nodes will correctly transform their positions into the global coordinate space, but applying it to a node's own position will give an incorrect result, as it will incorporate the node's own transformation into its global position.
</description>
</method>
<method name="to_local" qualifiers="const">
@@ -101,7 +101,7 @@
<argument index="0" name="global_point" type="Vector2">
</argument>
<description>
- Converts a global point's coordinates to local coordinates.
+ Transforms the provided global position into a position in local coordinate space. The output will be local relative to the [Node2D] it is called on. e.g. It is appropriate for determining the positions of child nodes, but it is not appropriate for determining its own position relative to its parent.
</description>
</method>
<method name="translate">
@@ -142,6 +142,10 @@
<member name="scale" type="Vector2" setter="set_scale" getter="get_scale" default="Vector2( 1, 1 )">
The node's scale. Unscaled value: [code](1, 1)[/code].
</member>
+ <member name="skew" type="float" setter="set_skew" getter="get_skew" default="0.0">
+ </member>
+ <member name="skew_degrees" type="float" setter="set_skew_degrees" getter="get_skew_degrees" default="0.0">
+ </member>
<member name="transform" type="Transform2D" setter="set_transform" getter="get_transform">
Local [Transform2D].
</member>
diff --git a/doc/classes/Node3D.xml b/doc/classes/Node3D.xml
index 3e7d4d4c05..05d00b9f31 100644
--- a/doc/classes/Node3D.xml
+++ b/doc/classes/Node3D.xml
@@ -26,7 +26,7 @@
Returns the parent [Node3D], or an empty [Object] if no parent exists or parent is not of type [Node3D].
</description>
</method>
- <method name="get_world" qualifiers="const">
+ <method name="get_world_3d" qualifiers="const">
<return type="World3D">
</return>
<description>
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index db79ee7765..03203e2ebb 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -268,6 +268,24 @@
Returns the epoch time of the operating system in seconds.
</description>
</method>
+ <method name="get_tablet_driver_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the total number of available tablet drivers.
+ [b]Note:[/b] This method is implemented on Windows.
+ </description>
+ </method>
+ <method name="get_tablet_driver_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="idx" type="int">
+ </argument>
+ <description>
+ Returns the tablet driver name for the given index.
+ [b]Note:[/b] This method is implemented on Windows.
+ </description>
+ </method>
<method name="get_ticks_msec" qualifiers="const">
<return type="int">
</return>
@@ -484,6 +502,7 @@
- [code]OS.shell_open("C:\\Users\name\Downloads")[/code] on Windows opens the file explorer at the user's Downloads folder.
- [code]OS.shell_open("https://godotengine.org")[/code] opens the default web browser on the official Godot website.
- [code]OS.shell_open("mailto:example@example.com")[/code] opens the default email client with the "To" field set to [code]example@example.com[/code]. See [url=https://blog.escapecreative.com/customizing-mailto-links/]Customizing [code]mailto:[/code] Links[/url] for a list of fields that can be added.
+ Use [method ProjectSettings.globalize_path] to convert a [code]res://[/code] or [code]user://[/code] path into a system path for use with this method.
[b]Note:[/b] This method is implemented on Android, iOS, HTML5, Linux, macOS and Windows.
</description>
</method>
@@ -499,6 +518,9 @@
<member name="low_processor_usage_mode_sleep_usec" type="int" setter="set_low_processor_usage_mode_sleep_usec" getter="get_low_processor_usage_mode_sleep_usec" default="6900">
The amount of sleeping between frames when the low-processor usage mode is enabled (in microseconds). Higher values will result in lower CPU usage.
</member>
+ <member name="tablet_driver" type="String" setter="set_current_tablet_driver" getter="get_current_tablet_driver" default="&quot;&quot;">
+ The current tablet drvier in use.
+ </member>
</members>
<constants>
<constant name="VIDEO_DRIVER_GLES2" value="0" enum="VideoDriver">
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index 35e87d1a2a..87bcab25db 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -192,7 +192,7 @@
<return type="void">
</return>
<description>
- Deletes the object from memory. Any pre-existing reference to the freed object will now return [code]null[/code].
+ Deletes the object from memory. Any pre-existing reference to the freed object will become invalid, e.g. [code]is_instance_valid(object)[/code] will return [code]false[/code].
</description>
</method>
<method name="get" qualifiers="const">
diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml
index e422545b7b..2d70dea012 100644
--- a/doc/classes/PackedScene.xml
+++ b/doc/classes/PackedScene.xml
@@ -9,23 +9,25 @@
[b]Note:[/b] The node doesn't need to own itself.
[b]Example of saving a node with different owners:[/b] The following example creates 3 objects: [code]Node2D[/code] ([code]node[/code]), [code]RigidBody2D[/code] ([code]rigid[/code]) and [code]CollisionObject2D[/code] ([code]collision[/code]). [code]collision[/code] is a child of [code]rigid[/code] which is a child of [code]node[/code]. Only [code]rigid[/code] is owned by [code]node[/code] and [code]pack[/code] will therefore only save those two nodes, but not [code]collision[/code].
[codeblock]
- # Create the objects
+ # Create the objects.
var node = Node2D.new()
var rigid = RigidBody2D.new()
var collision = CollisionShape2D.new()
- # Create the object hierarchy
+ # Create the object hierarchy.
rigid.add_child(collision)
node.add_child(rigid)
- # Change owner of rigid, but not of collision
+ # Change owner of `rigid`, but not of `collision`.
rigid.owner = node
var scene = PackedScene.new()
- # Only node and rigid are now packed
+ # Only `node` and `rigid` are now packed.
var result = scene.pack(node)
if result == OK:
- ResourceSaver.save("res://path/name.scn", scene) # Or "user://..."
+ var error = ResourceSaver.save("res://path/name.scn", scene) # Or "user://..."
+ if error != OK:
+ push_error("An error occurred while saving the scene to disk.")
[/codeblock]
</description>
<tutorials>
diff --git a/doc/classes/Path2D.xml b/doc/classes/Path2D.xml
index ab266a2f73..57e2091268 100644
--- a/doc/classes/Path2D.xml
+++ b/doc/classes/Path2D.xml
@@ -15,7 +15,6 @@
<member name="curve" type="Curve2D" setter="set_curve" getter="get_curve">
A [Curve2D] describing the path.
</member>
- <member name="self_modulate" type="Color" setter="set_self_modulate" getter="get_self_modulate" override="true" default="Color( 0.5, 0.6, 1, 0.7 )" />
</members>
<constants>
</constants>
diff --git a/doc/classes/PhysicalBone3D.xml b/doc/classes/PhysicalBone3D.xml
index 75f1f3eab4..58930aae37 100644
--- a/doc/classes/PhysicalBone3D.xml
+++ b/doc/classes/PhysicalBone3D.xml
@@ -25,6 +25,14 @@
<description>
</description>
</method>
+ <method name="get_axis_lock" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="axis" type="int" enum="PhysicsServer3D.BodyAxis">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_bone_id" qualifiers="const">
<return type="int">
</return>
@@ -43,6 +51,16 @@
<description>
</description>
</method>
+ <method name="set_axis_lock">
+ <return type="void">
+ </return>
+ <argument index="0" name="axis" type="int" enum="PhysicsServer3D.BodyAxis">
+ </argument>
+ <argument index="1" name="lock" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" default="-1.0">
@@ -84,7 +102,7 @@
<member name="joint_offset" type="Transform" setter="set_joint_offset" getter="get_joint_offset" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )">
Sets the joint's transform.
</member>
- <member name="joint_rotation" type="Vector3" setter="set_joint_rotation" getter="get_joint_rotation" default="Vector3( 0, 0, 0 )">
+ <member name="joint_rotation" type="Vector3" setter="set_joint_rotation" getter="get_joint_rotation">
Sets the joint's rotation in radians.
</member>
<member name="joint_rotation_degrees" type="Vector3" setter="set_joint_rotation_degrees" getter="get_joint_rotation_degrees" default="Vector3( 0, 0, 0 )">
diff --git a/doc/classes/PhysicalSkyMaterial.xml b/doc/classes/PhysicalSkyMaterial.xml
index 89b43158dc..2e0f9c52f2 100644
--- a/doc/classes/PhysicalSkyMaterial.xml
+++ b/doc/classes/PhysicalSkyMaterial.xml
@@ -31,6 +31,9 @@
<member name="mie_eccentricity" type="float" setter="set_mie_eccentricity" getter="get_mie_eccentricity" default="0.8">
Controls the direction of the mie scattering. A value of [code]1[/code] means that when light hits a particle it passing through straight forward. A value of [code]-1[/code] means that all light is scatter backwards.
</member>
+ <member name="night_sky" type="Texture2D" setter="set_night_sky" getter="get_night_sky">
+ [Texture2D] for the night sky. This is added to the sky, so if it is bright enough, it may be visible during the day.
+ </member>
<member name="rayleigh_coefficient" type="float" setter="set_rayleigh_coefficient" getter="get_rayleigh_coefficient" default="2.0">
Controls the strength of the rayleigh scattering. Rayleigh scattering results from light colliding with small particles. It is responsible for the blue color of the sky.
</member>
diff --git a/doc/classes/PhysicsBody2D.xml b/doc/classes/PhysicsBody2D.xml
index 28d6ce7048..6afbd1ee8e 100644
--- a/doc/classes/PhysicsBody2D.xml
+++ b/doc/classes/PhysicsBody2D.xml
@@ -20,7 +20,7 @@
</description>
</method>
<method name="get_collision_exceptions">
- <return type="Array">
+ <return type="PhysicsBody2D[]">
</return>
<description>
Returns an array of nodes that were added as collision exceptions for this body.
diff --git a/doc/classes/PhysicsBody3D.xml b/doc/classes/PhysicsBody3D.xml
index f0ba2a7f5f..2301a07a5c 100644
--- a/doc/classes/PhysicsBody3D.xml
+++ b/doc/classes/PhysicsBody3D.xml
@@ -20,7 +20,7 @@
</description>
</method>
<method name="get_collision_exceptions">
- <return type="Array">
+ <return type="PhysicsBody3D[]">
</return>
<description>
Returns an array of nodes that were added as collision exceptions for this body.
diff --git a/doc/classes/PhysicsDirectBodyState2DSW.xml b/doc/classes/PhysicsDirectBodyState2DSW.xml
deleted file mode 100644
index 94fc4213b7..0000000000
--- a/doc/classes/PhysicsDirectBodyState2DSW.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="PhysicsDirectBodyState2DSW" inherits="PhysicsDirectBodyState2D" version="4.0">
- <brief_description>
- Software implementation of [PhysicsDirectBodyState2D].
- </brief_description>
- <description>
- Software implementation of [PhysicsDirectBodyState2D]. This object exposes no new methods or properties and should not be used, as [PhysicsDirectBodyState2D] selects the best implementation available.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/PhysicsServer2DSW.xml b/doc/classes/PhysicsServer2DSW.xml
deleted file mode 100644
index dac5e360f0..0000000000
--- a/doc/classes/PhysicsServer2DSW.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="PhysicsServer2DSW" inherits="PhysicsServer2D" version="4.0">
- <brief_description>
- Software implementation of [PhysicsServer2D].
- </brief_description>
- <description>
- This class exposes no new methods or properties and should not be used, as [PhysicsServer2D] automatically selects the best implementation available.
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/Polygon2D.xml b/doc/classes/Polygon2D.xml
index 13332ca4f0..335df1ac3f 100644
--- a/doc/classes/Polygon2D.xml
+++ b/doc/classes/Polygon2D.xml
@@ -102,6 +102,8 @@
If [code]true[/code], polygon will be inverted, containing the area outside the defined points and extending to the [code]invert_border[/code].
</member>
<member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map">
+ The normal map gives depth to the Polygon2D.
+ [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )">
The offset applied to each vertex.
diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml
index 569da5c58b..ce55c90c68 100644
--- a/doc/classes/PopupMenu.xml
+++ b/doc/classes/PopupMenu.xml
@@ -242,6 +242,12 @@
Removes all items from the [PopupMenu].
</description>
</method>
+ <method name="get_current_index" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_item_accelerator" qualifiers="const">
<return type="int">
</return>
@@ -585,7 +591,7 @@
</method>
</methods>
<members>
- <member name="allow_search" type="bool" setter="set_allow_search" getter="get_allow_search" default="false">
+ <member name="allow_search" type="bool" setter="set_allow_search" getter="get_allow_search" default="true">
If [code]true[/code], allows to navigate [PopupMenu] with letter keys.
</member>
<member name="hide_on_checkable_item_selection" type="bool" setter="set_hide_on_checkable_item_selection" getter="is_hide_on_checkable_item_selection" default="true">
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 66bf8c8286..daf8cb1d2f 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -92,10 +92,8 @@
</argument>
<argument index="1" name="replace_files" type="bool" default="true">
</argument>
- <argument index="2" name="destination" type="String" default="">
- </argument>
<description>
- Loads the contents of the .pck or .zip file specified by [code]pack[/code] into the resource filesystem ([code]res://[/code]) at the [code]destination[/code] path, if given. Returns [code]true[/code] on success.
+ Loads the contents of the .pck or .zip file specified by [code]pack[/code] into the resource filesystem ([code]res://[/code]). Returns [code]true[/code] on success.
[b]Note:[/b] If a file from [code]pack[/code] shares the same path as a file already in the resource filesystem, any attempts to load that file will use the file from [code]pack[/code] unless [code]replace_files[/code] is set to [code]false[/code].
</description>
</method>
@@ -262,19 +260,19 @@
Setting to hardcode audio delay when playing video. Best to leave this untouched unless you know what you are doing.
</member>
<member name="compression/formats/gzip/compression_level" type="int" setter="" getter="" default="-1">
- Default compression level for gzip. Affects compressed scenes and resources.
+ The default compression level for gzip. Affects compressed scenes and resources. Higher levels result in smaller files at the cost of compression speed. Decompression speed is mostly unaffected by the compression level. [code]-1[/code] uses the default gzip compression level, which is identical to [code]6[/code] but could change in the future due to underlying zlib updates.
</member>
<member name="compression/formats/zlib/compression_level" type="int" setter="" getter="" default="-1">
- Default compression level for Zlib. Affects compressed scenes and resources.
+ The default compression level for Zlib. Affects compressed scenes and resources. Higher levels result in smaller files at the cost of compression speed. Decompression speed is mostly unaffected by the compression level. [code]-1[/code] uses the default gzip compression level, which is identical to [code]6[/code] but could change in the future due to underlying zlib updates.
</member>
<member name="compression/formats/zstd/compression_level" type="int" setter="" getter="" default="3">
- Default compression level for Zstandard. Affects compressed scenes and resources.
+ The default compression level for Zstandard. Affects compressed scenes and resources. Higher levels result in smaller files at the cost of compression speed. Decompression speed is mostly unaffected by the compression level.
</member>
<member name="compression/formats/zstd/long_distance_matching" type="bool" setter="" getter="" default="false">
- Enables long-distance matching in Zstandard.
+ Enables [url=https://github.com/facebook/zstd/releases/tag/v1.3.2]long-distance matching[/url] in Zstandard.
</member>
<member name="compression/formats/zstd/window_log_size" type="int" setter="" getter="" default="27">
- Largest size limit (in power of 2) allowed when compressing using long-distance matching with Zstandard.
+ Largest size limit (in power of 2) allowed when compressing using long-distance matching with Zstandard. Higher values can result in better compression, but will require more memory when compressing and decompressing.
</member>
<member name="debug/gdscript/completion/autocomplete_setters_and_getters" type="bool" setter="" getter="" default="false">
If [code]true[/code], displays getters and setters in autocompletion results in the script editor. This setting is meant to be used when porting old projects (Godot 2), as using member variables is the preferred style from Godot 3 onwards.
@@ -452,6 +450,9 @@
<member name="display/window/size/width" type="int" setter="" getter="" default="1024">
Sets the game's main viewport width. On desktop platforms, this is the default window size. Stretch mode settings also use this as a reference when enabled.
</member>
+ <member name="display/window/tablet_driver" type="String" setter="" getter="" default="&quot;&quot;">
+ Specifies the tablet driver to use. If left empty, the default driver will be used.
+ </member>
<member name="display/window/vsync/use_vsync" type="bool" setter="" getter="" default="true">
If [code]true[/code], enables vertical synchronization. This eliminates tearing that may appear in moving scenes, at the cost of higher input latency and stuttering at lower framerates. If [code]false[/code], vertical synchronization will be disabled, however, many platforms will enforce it regardless (such as mobile platforms and HTML5).
</member>
@@ -471,6 +472,8 @@
<member name="gui/common/swap_ok_cancel" type="bool" setter="" getter="" default="false">
If [code]true[/code], swaps OK and Cancel buttons in dialogs on Windows and UWP to follow interface conventions.
</member>
+ <member name="gui/common/text_edit_undo_stack_max_size" type="int" setter="" getter="" default="1024">
+ </member>
<member name="gui/theme/custom" type="String" setter="" getter="" default="&quot;&quot;">
Path to a custom [Theme] resource file to use for the project ([code]theme[/code] or generic [code]tres[/code]/[code]res[/code] extension).
</member>
@@ -841,38 +844,15 @@
<member name="network/limits/webrtc/max_channel_in_buffer_kb" type="int" setter="" getter="" default="64">
Maximum size (in kiB) for the [WebRTCDataChannel] input buffer.
</member>
- <member name="network/limits/websocket_client/max_in_buffer_kb" type="int" setter="" getter="" default="64">
- Maximum size (in kiB) for the [WebSocketClient] input buffer.
- </member>
- <member name="network/limits/websocket_client/max_in_packets" type="int" setter="" getter="" default="1024">
- Maximum number of concurrent input packets for [WebSocketClient].
- </member>
- <member name="network/limits/websocket_client/max_out_buffer_kb" type="int" setter="" getter="" default="64">
- Maximum size (in kiB) for the [WebSocketClient] output buffer.
- </member>
- <member name="network/limits/websocket_client/max_out_packets" type="int" setter="" getter="" default="1024">
- Maximum number of concurrent output packets for [WebSocketClient].
- </member>
- <member name="network/limits/websocket_server/max_in_buffer_kb" type="int" setter="" getter="" default="64">
- Maximum size (in kiB) for the [WebSocketServer] input buffer.
- </member>
- <member name="network/limits/websocket_server/max_in_packets" type="int" setter="" getter="" default="1024">
- Maximum number of concurrent input packets for [WebSocketServer].
- </member>
- <member name="network/limits/websocket_server/max_out_buffer_kb" type="int" setter="" getter="" default="64">
- Maximum size (in kiB) for the [WebSocketServer] output buffer.
- </member>
- <member name="network/limits/websocket_server/max_out_packets" type="int" setter="" getter="" default="1024">
- Maximum number of concurrent output packets for [WebSocketServer].
- </member>
<member name="network/remote_fs/page_read_ahead" type="int" setter="" getter="" default="4">
Amount of read ahead used by remote filesystem. Higher values decrease the effects of latency at the cost of higher bandwidth usage.
</member>
<member name="network/remote_fs/page_size" type="int" setter="" getter="" default="65536">
Page size used by remote filesystem (in bytes).
</member>
- <member name="network/ssl/certificates" type="String" setter="" getter="" default="&quot;&quot;">
- CA certificates bundle to use for SSL connections. If not defined, Godot's internal CA certificates are used.
+ <member name="network/ssl/certificate_bundle_override" type="String" setter="" getter="" default="&quot;&quot;">
+ The CA certificates bundle to use for SSL connections. If this is set to a non-empty value, this will [i]override[/i] Godot's default [url=https://github.com/godotengine/godot/blob/master/thirdparty/certs/ca-certificates.crt]Mozilla certificate bundle[/url]. If left empty, the default certificate bundle will be used.
+ If in doubt, leave this setting empty.
</member>
<member name="node/name_casing" type="int" setter="" getter="" default="0">
When creating node names automatically, set the type of casing in this project. This is mostly an editor setting.
@@ -974,9 +954,37 @@
<member name="rendering/environment/default_environment" type="String" setter="" getter="" default="&quot;&quot;">
[Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, it is best to delete [code]default_env.tres[/code], or to specify a different default environment here.
</member>
+ <member name="rendering/gpu_lightmapper/performance/max_rays_per_pass" type="int" setter="" getter="" default="32">
+ </member>
+ <member name="rendering/gpu_lightmapper/performance/max_rays_per_probe_pass" type="int" setter="" getter="" default="64">
+ </member>
+ <member name="rendering/gpu_lightmapper/performance/region_size" type="int" setter="" getter="" default="512">
+ </member>
+ <member name="rendering/gpu_lightmapper/quality/high_quality_probe_ray_count" type="int" setter="" getter="" default="512">
+ </member>
+ <member name="rendering/gpu_lightmapper/quality/high_quality_ray_count" type="int" setter="" getter="" default="256">
+ </member>
+ <member name="rendering/gpu_lightmapper/quality/low_quality_probe_ray_count" type="int" setter="" getter="" default="64">
+ </member>
+ <member name="rendering/gpu_lightmapper/quality/low_quality_ray_count" type="int" setter="" getter="" default="16">
+ </member>
+ <member name="rendering/gpu_lightmapper/quality/medium_quality_probe_ray_count" type="int" setter="" getter="" default="256">
+ </member>
+ <member name="rendering/gpu_lightmapper/quality/medium_quality_ray_count" type="int" setter="" getter="" default="64">
+ </member>
+ <member name="rendering/gpu_lightmapper/quality/ultra_quality_probe_ray_count" type="int" setter="" getter="" default="2048">
+ </member>
+ <member name="rendering/gpu_lightmapper/quality/ultra_quality_ray_count" type="int" setter="" getter="" default="1024">
+ </member>
+ <member name="rendering/high_end/global_shader_variables_buffer_size" type="int" setter="" getter="" default="65536">
+ </member>
+ <member name="rendering/lightmapper/probe_capture_update_speed" type="float" setter="" getter="" default="15">
+ </member>
<member name="rendering/limits/rendering/max_renderable_elements" type="int" setter="" getter="" default="128000">
Max amount of elements renderable in a frame. If more than this are visible per frame, they will be dropped. Keep in mind elements refer to mesh surfaces and not meshes themselves.
</member>
+ <member name="rendering/limits/time/time_rollover_secs" type="float" setter="" getter="" default="3600">
+ </member>
<member name="rendering/quality/2d/gles2_use_nvidia_rect_flicker_workaround" type="bool" setter="" getter="" default="false">
Some NVIDIA GPU drivers have a bug which produces flickering issues for the [code]draw_rect[/code] method, especially as used in [TileMap]. Refer to [url=https://github.com/godotengine/godot/issues/9913]GitHub issue 9913[/url] for details.
If [code]true[/code], this option enables a "safe" code path for such NVIDIA GPUs at the cost of performance. This option only impacts the GLES2 rendering backend, and only desktop platforms. It is not necessary when using the Vulkan backend.
@@ -984,6 +992,15 @@
<member name="rendering/quality/2d/use_pixel_snap" type="bool" setter="" getter="" default="false">
If [code]true[/code], forces snapping of polygons to pixels in 2D rendering. May help in some pixel art styles.
</member>
+ <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2">
+ Sets the quality of the depth of field effect. Higher quality takes more samples, which is slower but looks smoother.
+ </member>
+ <member name="rendering/quality/depth_of_field/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1">
+ Sets the depth of field shape. Can be Box, Hexagon, or Circle. Box is the fastest. Circle is the most realistic, but also the most expensive to compute.
+ </member>
+ <member name="rendering/quality/depth_of_field/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], jitters DOF samples to make effect slightly blurrier and hide lines created from low sample rates. This can result in a slightly grainy appearance when used with a low number of samples.
+ </member>
<member name="rendering/quality/depth_prepass/disable_for_vendors" type="String" setter="" getter="" default="&quot;PowerVR,Mali,Adreno,Apple&quot;">
Disables depth pre-pass for some GPU vendors (usually mobile), as their architecture already does this.
</member>
@@ -1000,7 +1017,7 @@
Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality settings use more samples when reading from shadow maps and are thus slower. Low quality settings may result in shadows looking grainy.
</member>
<member name="rendering/quality/directional_shadow/soft_shadow_quality.mobile" type="int" setter="" getter="" default="0">
- Lower-end override for [member rendering/quality/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
+ Lower-end override for [member rendering/quality/directional_shadow/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/quality/driver/driver_name" type="String" setter="" getter="" default="&quot;Vulkan&quot;">
The video driver to use ("GLES2" or "Vulkan").
@@ -1008,32 +1025,17 @@
[b]FIXME:[/b] No longer valid after DisplayServer split:
In such cases, this property is not updated, so use [code]OS.get_current_video_driver[/code] to query it at run-time.
</member>
- <member name="rendering/quality/filters/depth_of_field_bokeh_quality" type="int" setter="" getter="" default="2">
- </member>
- <member name="rendering/quality/filters/depth_of_field_bokeh_shape" type="int" setter="" getter="" default="1">
- </member>
- <member name="rendering/quality/filters/depth_of_field_use_jitter" type="bool" setter="" getter="" default="false">
- </member>
- <member name="rendering/quality/filters/max_anisotropy" type="int" setter="" getter="" default="4">
- </member>
- <member name="rendering/quality/filters/msaa" type="int" setter="" getter="" default="0">
- Sets the number of MSAA samples to use. MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware.
- [b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend.
- </member>
- <member name="rendering/quality/filters/screen_space_roughness_limiter" type="int" setter="" getter="" default="0">
- </member>
- <member name="rendering/quality/filters/screen_space_roughness_limiter_curve" type="float" setter="" getter="" default="1.0">
- </member>
- <member name="rendering/quality/filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false">
- If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used.
- </member>
<member name="rendering/quality/gi_probes/anisotropic" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], take additional samples when rendering objects affected by a [GIProbe] to reduce artifacts from only sampling in one direction.
</member>
<member name="rendering/quality/gi_probes/quality" type="int" setter="" getter="" default="1">
+ Sets the number of cone samples taken when rendering objects affected by [GIProbe]s.
</member>
<member name="rendering/quality/glow/upscale_mode" type="int" setter="" getter="" default="1">
+ Sets how the glow effect is upscaled before being copied onto the screen. Linear is faster, but looks blocky. Bicubic is slower but looks smooth.
</member>
<member name="rendering/quality/glow/upscale_mode.mobile" type="int" setter="" getter="" default="0">
+ Lower-end override for [member rendering/quality/glow/upscale_mode] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/quality/intended_usage/framebuffer_allocation" type="int" setter="" getter="" default="2">
Strategy used for framebuffer allocation. The simpler it is, the less resources it uses (but the less features it supports). If set to "2D Without Sampling" or "3D Without Effects", sample buffers will not be allocated. This means [code]SCREEN_TEXTURE[/code] and [code]DEPTH_TEXTURE[/code] will not be available in shaders and post-processing effects will not be available in the [Environment].
@@ -1068,7 +1070,22 @@
<member name="rendering/quality/reflections/texture_array_reflections.mobile" type="bool" setter="" getter="" default="false">
Lower-end override for [member rendering/quality/reflections/texture_array_reflections] on mobile devices, due to performance concerns or driver support.
</member>
+ <member name="rendering/quality/screen_filters/msaa" type="int" setter="" getter="" default="0">
+ Sets the number of MSAA samples to use (as a power of two). MSAA is used to reduce aliasing around the edges of polygons. A higher MSAA value results in smoother edges but can be significantly slower on some hardware.
+ [b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend.
+ </member>
+ <member name="rendering/quality/screen_filters/screen_space_aa" type="int" setter="" getter="" default="0">
+ Sets the screen-space antialiasing mode for the default screen [Viewport]. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry.
+ Another way to combat specular aliasing is to enable [member rendering/quality/screen_filters/screen_space_roughness_limiter].
+ </member>
+ <member name="rendering/quality/screen_filters/screen_space_roughness_limiter" type="int" setter="" getter="" default="0">
+ Enables the screen-space roughness limiter which increases material roughness in areas with a high normal frequency (i.e. when normals change a lot from pixel to pixel). This helps to reduce the amount of specular aliasing in a scene. Specular aliasing looks like random bright pixels that occur in reflections.
+ </member>
+ <member name="rendering/quality/screen_filters/screen_space_roughness_limiter_curve" type="float" setter="" getter="" default="1.0">
+ Curves the amount of the roughness limited effect. A higher value limits the effect to very sharply curved surfaces, while a lower threshold extends the effect to smoother surfaces.
+ </member>
<member name="rendering/quality/screen_space_reflection/roughness_quality" type="int" setter="" getter="" default="1">
+ Sets the quality for rough screen-space reflections. Turning off will make all screen space reflections sharp, while higher values make rough reflections look better.
</member>
<member name="rendering/quality/shading/force_blinn_over_ggx" type="bool" setter="" getter="" default="false">
If [code]true[/code], uses faster but lower-quality Blinn model to generate blurred reflections instead of the GGX model.
@@ -1113,14 +1130,25 @@
Lower-end override for [member rendering/quality/shadows/soft_shadow_quality] on mobile devices, due to performance concerns or driver support.
</member>
<member name="rendering/quality/ssao/half_size" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], screen-space ambient occlusion will be rendered at half size and then upscaled before being added to the scene. This is significantly faster but may miss small details.
</member>
<member name="rendering/quality/ssao/quality" type="int" setter="" getter="" default="1">
+ Sets the quality of the screen-space ambient occlusion effect. Higher values take more samples and so will result in better quality, at the cost of performance.
</member>
<member name="rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale" type="float" setter="" getter="" default="0.01">
+ Scales the depth over which the subsurface scattering effect is applied. A high value may allow light to scatter into a part of the mesh or another mesh that is close in screen space but far in depth.
</member>
<member name="rendering/quality/subsurface_scattering/subsurface_scattering_quality" type="int" setter="" getter="" default="1">
+ Sets the quality of the subsurface scattering effect. Higher values are slower but look nicer.
</member>
<member name="rendering/quality/subsurface_scattering/subsurface_scattering_scale" type="float" setter="" getter="" default="0.05">
+ Scales the distance over which samples are taken for subsurface scattering effect. Changing this does not impact performance, but higher values will result in significant artifacts as the samples will become obviously spread out. A lower value results in a smaller spread of scattered light.
+ </member>
+ <member name="rendering/quality/texture_filters/anisotropic_filtering_level" type="int" setter="" getter="" default="2">
+ Sets the maximum number of samples to take when using anisotropic filtering on textures (as a power of two). A higher sample count will result in sharper textures at oblique angles, but is more expensive to compute. A value of [code]0[/code] forcibly disables anisotropic filtering, even on materials where it is enabled.
+ </member>
+ <member name="rendering/quality/texture_filters/use_nearest_mipmap_filter" type="bool" setter="" getter="" default="false">
+ If [code]true[/code], uses nearest-neighbor mipmap filtering when using mipmaps (also called "bilinear filtering"), which will result in visible seams appearing between mipmap stages. This may increase performance in mobile as less memory bandwidth is used. If [code]false[/code], linear mipmap filtering (also called "trilinear filtering") is used.
</member>
<member name="rendering/threads/thread_model" type="int" setter="" getter="" default="1">
Thread model for rendering. Rendering on a thread can vastly improve performance, but synchronizing to the main thread can cause a bit more jitter.
@@ -1148,6 +1176,9 @@
</member>
<member name="rendering/vulkan/staging_buffer/texture_upload_region_size_px" type="int" setter="" getter="" default="64">
</member>
+ <member name="world/2d/cell_size" type="int" setter="" getter="" default="100">
+ Cell size used for the 2D hash grid that [VisibilityNotifier2D] uses.
+ </member>
</members>
<constants>
</constants>
diff --git a/doc/classes/RDAttachmentFormat.xml b/doc/classes/RDAttachmentFormat.xml
new file mode 100644
index 0000000000..4ee7b9b28e
--- /dev/null
+++ b/doc/classes/RDAttachmentFormat.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDAttachmentFormat" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="36">
+ </member>
+ <member name="samples" type="int" setter="set_samples" getter="get_samples" enum="RenderingDevice.TextureSamples" default="0">
+ </member>
+ <member name="usage_flags" type="int" setter="set_usage_flags" getter="get_usage_flags" default="0">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDPipelineColorBlendState.xml b/doc/classes/RDPipelineColorBlendState.xml
new file mode 100644
index 0000000000..adc6f1f6a3
--- /dev/null
+++ b/doc/classes/RDPipelineColorBlendState.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDPipelineColorBlendState" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="attachments" type="RDPipelineColorBlendStateAttachment[]" setter="set_attachments" getter="get_attachments" default="[ ]">
+ </member>
+ <member name="blend_constant" type="Color" setter="set_blend_constant" getter="get_blend_constant" default="Color( 0, 0, 0, 1 )">
+ </member>
+ <member name="enable_logic_op" type="bool" setter="set_enable_logic_op" getter="get_enable_logic_op" default="false">
+ </member>
+ <member name="logic_op" type="int" setter="set_logic_op" getter="get_logic_op" enum="RenderingDevice.LogicOperation" default="0">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDPipelineColorBlendStateAttachment.xml b/doc/classes/RDPipelineColorBlendStateAttachment.xml
new file mode 100644
index 0000000000..7f118b5f0b
--- /dev/null
+++ b/doc/classes/RDPipelineColorBlendStateAttachment.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDPipelineColorBlendStateAttachment" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="set_as_mix">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="alpha_blend_op" type="int" setter="set_alpha_blend_op" getter="get_alpha_blend_op" enum="RenderingDevice.BlendOperation" default="0">
+ </member>
+ <member name="color_blend_op" type="int" setter="set_color_blend_op" getter="get_color_blend_op" enum="RenderingDevice.BlendOperation" default="0">
+ </member>
+ <member name="dst_alpha_blend_factor" type="int" setter="set_dst_alpha_blend_factor" getter="get_dst_alpha_blend_factor" enum="RenderingDevice.BlendFactor" default="0">
+ </member>
+ <member name="dst_color_blend_factor" type="int" setter="set_dst_color_blend_factor" getter="get_dst_color_blend_factor" enum="RenderingDevice.BlendFactor" default="0">
+ </member>
+ <member name="enable_blend" type="bool" setter="set_enable_blend" getter="get_enable_blend" default="false">
+ </member>
+ <member name="src_alpha_blend_factor" type="int" setter="set_src_alpha_blend_factor" getter="get_src_alpha_blend_factor" enum="RenderingDevice.BlendFactor" default="0">
+ </member>
+ <member name="src_color_blend_factor" type="int" setter="set_src_color_blend_factor" getter="get_src_color_blend_factor" enum="RenderingDevice.BlendFactor" default="0">
+ </member>
+ <member name="write_a" type="bool" setter="set_write_a" getter="get_write_a" default="true">
+ </member>
+ <member name="write_b" type="bool" setter="set_write_b" getter="get_write_b" default="true">
+ </member>
+ <member name="write_g" type="bool" setter="set_write_g" getter="get_write_g" default="true">
+ </member>
+ <member name="write_r" type="bool" setter="set_write_r" getter="get_write_r" default="true">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDPipelineDepthStencilState.xml b/doc/classes/RDPipelineDepthStencilState.xml
new file mode 100644
index 0000000000..562ff52819
--- /dev/null
+++ b/doc/classes/RDPipelineDepthStencilState.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDPipelineDepthStencilState" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="back_op_compare" type="int" setter="set_back_op_compare" getter="get_back_op_compare" enum="RenderingDevice.CompareOperator" default="7">
+ </member>
+ <member name="back_op_compare_mask" type="int" setter="set_back_op_compare_mask" getter="get_back_op_compare_mask" default="0">
+ </member>
+ <member name="back_op_depth_fail" type="int" setter="set_back_op_depth_fail" getter="get_back_op_depth_fail" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="back_op_fail" type="int" setter="set_back_op_fail" getter="get_back_op_fail" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="back_op_pass" type="int" setter="set_back_op_pass" getter="get_back_op_pass" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="back_op_reference" type="int" setter="set_back_op_reference" getter="get_back_op_reference" default="0">
+ </member>
+ <member name="back_op_write_mask" type="int" setter="set_back_op_write_mask" getter="get_back_op_write_mask" default="0">
+ </member>
+ <member name="depth_compare_operator" type="int" setter="set_depth_compare_operator" getter="get_depth_compare_operator" enum="RenderingDevice.CompareOperator" default="7">
+ </member>
+ <member name="depth_range_max" type="float" setter="set_depth_range_max" getter="get_depth_range_max" default="0.0">
+ </member>
+ <member name="depth_range_min" type="float" setter="set_depth_range_min" getter="get_depth_range_min" default="0.0">
+ </member>
+ <member name="enable_depth_range" type="bool" setter="set_enable_depth_range" getter="get_enable_depth_range" default="false">
+ </member>
+ <member name="enable_depth_test" type="bool" setter="set_enable_depth_test" getter="get_enable_depth_test" default="false">
+ </member>
+ <member name="enable_depth_write" type="bool" setter="set_enable_depth_write" getter="get_enable_depth_write" default="false">
+ </member>
+ <member name="enable_stencil" type="bool" setter="set_enable_stencil" getter="get_enable_stencil" default="false">
+ </member>
+ <member name="front_op_compare" type="int" setter="set_front_op_compare" getter="get_front_op_compare" enum="RenderingDevice.CompareOperator" default="7">
+ </member>
+ <member name="front_op_compare_mask" type="int" setter="set_front_op_compare_mask" getter="get_front_op_compare_mask" default="0">
+ </member>
+ <member name="front_op_depth_fail" type="int" setter="set_front_op_depth_fail" getter="get_front_op_depth_fail" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="front_op_fail" type="int" setter="set_front_op_fail" getter="get_front_op_fail" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="front_op_pass" type="int" setter="set_front_op_pass" getter="get_front_op_pass" enum="RenderingDevice.StencilOperation" default="1">
+ </member>
+ <member name="front_op_reference" type="int" setter="set_front_op_reference" getter="get_front_op_reference" default="0">
+ </member>
+ <member name="front_op_write_mask" type="int" setter="set_front_op_write_mask" getter="get_front_op_write_mask" default="0">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDPipelineMultisampleState.xml b/doc/classes/RDPipelineMultisampleState.xml
new file mode 100644
index 0000000000..4658c7d9ba
--- /dev/null
+++ b/doc/classes/RDPipelineMultisampleState.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDPipelineMultisampleState" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="enable_alpha_to_coverage" type="bool" setter="set_enable_alpha_to_coverage" getter="get_enable_alpha_to_coverage" default="false">
+ </member>
+ <member name="enable_alpha_to_one" type="bool" setter="set_enable_alpha_to_one" getter="get_enable_alpha_to_one" default="false">
+ </member>
+ <member name="enable_sample_shading" type="bool" setter="set_enable_sample_shading" getter="get_enable_sample_shading" default="false">
+ </member>
+ <member name="min_sample_shading" type="float" setter="set_min_sample_shading" getter="get_min_sample_shading" default="0.0">
+ </member>
+ <member name="sample_count" type="int" setter="set_sample_count" getter="get_sample_count" enum="RenderingDevice.TextureSamples" default="0">
+ </member>
+ <member name="sample_masks" type="int[]" setter="set_sample_masks" getter="get_sample_masks" default="[ ]">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDPipelineRasterizationState.xml b/doc/classes/RDPipelineRasterizationState.xml
new file mode 100644
index 0000000000..5064dd6deb
--- /dev/null
+++ b/doc/classes/RDPipelineRasterizationState.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDPipelineRasterizationState" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="cull_mode" type="int" setter="set_cull_mode" getter="get_cull_mode" enum="RenderingDevice.PolygonCullMode" default="0">
+ </member>
+ <member name="depth_bias_clamp" type="float" setter="set_depth_bias_clamp" getter="get_depth_bias_clamp" default="0.0">
+ </member>
+ <member name="depth_bias_constant_factor" type="float" setter="set_depth_bias_constant_factor" getter="get_depth_bias_constant_factor" default="0.0">
+ </member>
+ <member name="depth_bias_enable" type="bool" setter="set_depth_bias_enable" getter="get_depth_bias_enable" default="false">
+ </member>
+ <member name="depth_bias_slope_factor" type="float" setter="set_depth_bias_slope_factor" getter="get_depth_bias_slope_factor" default="0.0">
+ </member>
+ <member name="discard_primitives" type="bool" setter="set_discard_primitives" getter="get_discard_primitives" default="false">
+ </member>
+ <member name="enable_depth_clamp" type="bool" setter="set_enable_depth_clamp" getter="get_enable_depth_clamp" default="false">
+ </member>
+ <member name="front_face" type="int" setter="set_front_face" getter="get_front_face" enum="RenderingDevice.PolygonFrontFace" default="0">
+ </member>
+ <member name="line_width" type="float" setter="set_line_width" getter="get_line_width" default="1.0">
+ </member>
+ <member name="patch_control_points" type="int" setter="set_patch_control_points" getter="get_patch_control_points" default="1">
+ </member>
+ <member name="wireframe" type="bool" setter="set_wireframe" getter="get_wireframe" default="false">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDSamplerState.xml b/doc/classes/RDSamplerState.xml
new file mode 100644
index 0000000000..ab31960b7c
--- /dev/null
+++ b/doc/classes/RDSamplerState.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDSamplerState" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="anisotropy_max" type="float" setter="set_anisotropy_max" getter="get_anisotropy_max" default="1.0">
+ </member>
+ <member name="border_color" type="int" setter="set_border_color" getter="get_border_color" enum="RenderingDevice.SamplerBorderColor" default="2">
+ </member>
+ <member name="compare_op" type="int" setter="set_compare_op" getter="get_compare_op" enum="RenderingDevice.CompareOperator" default="7">
+ </member>
+ <member name="enable_compare" type="bool" setter="set_enable_compare" getter="get_enable_compare" default="false">
+ </member>
+ <member name="lod_bias" type="float" setter="set_lod_bias" getter="get_lod_bias" default="0.0">
+ </member>
+ <member name="mag_filter" type="int" setter="set_mag_filter" getter="get_mag_filter" enum="RenderingDevice.SamplerFilter" default="0">
+ </member>
+ <member name="max_lod" type="float" setter="set_max_lod" getter="get_max_lod" default="1e+20">
+ </member>
+ <member name="min_filter" type="int" setter="set_min_filter" getter="get_min_filter" enum="RenderingDevice.SamplerFilter" default="0">
+ </member>
+ <member name="min_lod" type="float" setter="set_min_lod" getter="get_min_lod" default="0.0">
+ </member>
+ <member name="mip_filter" type="int" setter="set_mip_filter" getter="get_mip_filter" enum="RenderingDevice.SamplerFilter" default="0">
+ </member>
+ <member name="repeat_u" type="int" setter="set_repeat_u" getter="get_repeat_u" enum="RenderingDevice.SamplerRepeatMode" default="2">
+ </member>
+ <member name="repeat_v" type="int" setter="set_repeat_v" getter="get_repeat_v" enum="RenderingDevice.SamplerRepeatMode" default="2">
+ </member>
+ <member name="repeat_w" type="int" setter="set_repeat_w" getter="get_repeat_w" enum="RenderingDevice.SamplerRepeatMode" default="2">
+ </member>
+ <member name="unnormalized_uvw" type="bool" setter="set_unnormalized_uvw" getter="get_unnormalized_uvw" default="false">
+ </member>
+ <member name="use_anisotropy" type="bool" setter="set_use_anisotropy" getter="get_use_anisotropy" default="false">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDShaderBytecode.xml b/doc/classes/RDShaderBytecode.xml
new file mode 100644
index 0000000000..7a3501004e
--- /dev/null
+++ b/doc/classes/RDShaderBytecode.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDShaderBytecode" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_stage_bytecode" qualifiers="const">
+ <return type="PackedByteArray">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_stage_compile_error" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_stage_bytecode">
+ <return type="void">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <argument index="1" name="bytecode" type="PackedByteArray">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_stage_compile_error">
+ <return type="void">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <argument index="1" name="compile_error" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="bytecode_compute" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )">
+ </member>
+ <member name="bytecode_fragment" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )">
+ </member>
+ <member name="bytecode_tesselation_control" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )">
+ </member>
+ <member name="bytecode_tesselation_evaluation" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )">
+ </member>
+ <member name="bytecode_vertex" type="PackedByteArray" setter="set_stage_bytecode" getter="get_stage_bytecode" default="PackedByteArray( )">
+ </member>
+ <member name="compile_error_compute" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
+ </member>
+ <member name="compile_error_fragment" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
+ </member>
+ <member name="compile_error_tesselation_control" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
+ </member>
+ <member name="compile_error_tesselation_evaluation" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
+ </member>
+ <member name="compile_error_vertex" type="String" setter="set_stage_compile_error" getter="get_stage_compile_error" default="&quot;&quot;">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDShaderFile.xml b/doc/classes/RDShaderFile.xml
new file mode 100644
index 0000000000..14e70d53ea
--- /dev/null
+++ b/doc/classes/RDShaderFile.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDShaderFile" inherits="Resource" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_bytecode" qualifiers="const">
+ <return type="RDShaderBytecode">
+ </return>
+ <argument index="0" name="version" type="StringName" default="@&quot;&quot;">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_version_list" qualifiers="const">
+ <return type="PackedStringArray">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_bytecode">
+ <return type="void">
+ </return>
+ <argument index="0" name="bytecode" type="RDShaderBytecode">
+ </argument>
+ <argument index="1" name="version" type="StringName" default="@&quot;&quot;">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="base_error" type="String" setter="set_base_error" getter="get_base_error" default="&quot;&quot;">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDShaderSource.xml b/doc/classes/RDShaderSource.xml
new file mode 100644
index 0000000000..c1cfd34bb7
--- /dev/null
+++ b/doc/classes/RDShaderSource.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDShaderSource" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="get_stage_source" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_stage_source">
+ <return type="void">
+ </return>
+ <argument index="0" name="stage" type="int" enum="RenderingDevice.ShaderStage">
+ </argument>
+ <argument index="1" name="source" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="language" type="int" setter="set_language" getter="get_language" enum="RenderingDevice.ShaderLanguage" default="0">
+ </member>
+ <member name="source_compute" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
+ </member>
+ <member name="source_fragment" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
+ </member>
+ <member name="source_tesselation_control" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
+ </member>
+ <member name="source_tesselation_evaluation" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
+ </member>
+ <member name="source_vertex" type="String" setter="set_stage_source" getter="get_stage_source" default="&quot;&quot;">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDTextureFormat.xml b/doc/classes/RDTextureFormat.xml
new file mode 100644
index 0000000000..664d4cadff
--- /dev/null
+++ b/doc/classes/RDTextureFormat.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDTextureFormat" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="add_shareable_format">
+ <return type="void">
+ </return>
+ <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="remove_shareable_format">
+ <return type="void">
+ </return>
+ <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="array_layers" type="int" setter="set_array_layers" getter="get_array_layers" default="1">
+ </member>
+ <member name="depth" type="int" setter="set_depth" getter="get_depth" default="1">
+ </member>
+ <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="8">
+ </member>
+ <member name="height" type="int" setter="set_height" getter="get_height" default="1">
+ </member>
+ <member name="mipmaps" type="int" setter="set_mipmaps" getter="get_mipmaps" default="1">
+ </member>
+ <member name="samples" type="int" setter="set_samples" getter="get_samples" enum="RenderingDevice.TextureSamples" default="0">
+ </member>
+ <member name="type" type="int" setter="set_type" getter="get_type" enum="RenderingDevice.TextureType" default="1">
+ </member>
+ <member name="usage_bits" type="int" setter="set_usage_bits" getter="get_usage_bits" default="0">
+ </member>
+ <member name="width" type="int" setter="set_width" getter="get_width" default="1">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDTextureView.xml b/doc/classes/RDTextureView.xml
new file mode 100644
index 0000000000..73b2a7ae4a
--- /dev/null
+++ b/doc/classes/RDTextureView.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDTextureView" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="format_override" type="int" setter="set_format_override" getter="get_format_override" enum="RenderingDevice.DataFormat" default="226">
+ </member>
+ <member name="swizzle_a" type="int" setter="set_swizzle_a" getter="get_swizzle_a" enum="RenderingDevice.TextureSwizzle" default="6">
+ </member>
+ <member name="swizzle_b" type="int" setter="set_swizzle_b" getter="get_swizzle_b" enum="RenderingDevice.TextureSwizzle" default="5">
+ </member>
+ <member name="swizzle_g" type="int" setter="set_swizzle_g" getter="get_swizzle_g" enum="RenderingDevice.TextureSwizzle" default="4">
+ </member>
+ <member name="swizzle_r" type="int" setter="set_swizzle_r" getter="get_swizzle_r" enum="RenderingDevice.TextureSwizzle" default="3">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDUniform.xml b/doc/classes/RDUniform.xml
new file mode 100644
index 0000000000..e5bace32af
--- /dev/null
+++ b/doc/classes/RDUniform.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDUniform" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="add_id">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="clear_ids">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_ids" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="binding" type="int" setter="set_binding" getter="get_binding" default="0">
+ </member>
+ <member name="type" type="int" setter="set_type" getter="get_type" enum="RenderingDevice.UniformType" default="3">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RDVertexAttribute.xml b/doc/classes/RDVertexAttribute.xml
new file mode 100644
index 0000000000..56fe40b51d
--- /dev/null
+++ b/doc/classes/RDVertexAttribute.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="RDVertexAttribute" inherits="Reference" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="format" type="int" setter="set_format" getter="get_format" enum="RenderingDevice.DataFormat" default="226">
+ </member>
+ <member name="frequency" type="int" setter="set_frequency" getter="get_frequency" enum="RenderingDevice.VertexFrequency" default="0">
+ </member>
+ <member name="location" type="int" setter="set_location" getter="get_location" default="0">
+ </member>
+ <member name="offset" type="int" setter="set_offset" getter="get_offset" default="0">
+ </member>
+ <member name="stride" type="int" setter="set_stride" getter="get_stride" default="0">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/RenderingDevice.xml b/doc/classes/RenderingDevice.xml
index 2615f0a2e9..8a44d213e8 100644
--- a/doc/classes/RenderingDevice.xml
+++ b/doc/classes/RenderingDevice.xml
@@ -7,7 +7,1593 @@
<tutorials>
</tutorials>
<methods>
+ <method name="buffer_get_data">
+ <return type="PackedByteArray">
+ </return>
+ <argument index="0" name="buffer" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="buffer_update">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="buffer" type="RID">
+ </argument>
+ <argument index="1" name="offset" type="int">
+ </argument>
+ <argument index="2" name="size_bytes" type="int">
+ </argument>
+ <argument index="3" name="data" type="PackedByteArray">
+ </argument>
+ <argument index="4" name="sync_with_draw" type="bool" default="true">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="capture_timestamp">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="sync_to_draw" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_add_barrier">
+ <return type="void">
+ </return>
+ <argument index="0" name="compute_list" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_begin">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_bind_compute_pipeline">
+ <return type="void">
+ </return>
+ <argument index="0" name="compute_list" type="int">
+ </argument>
+ <argument index="1" name="compute_pipeline" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_bind_uniform_set">
+ <return type="void">
+ </return>
+ <argument index="0" name="compute_list" type="int">
+ </argument>
+ <argument index="1" name="uniform_set" type="RID">
+ </argument>
+ <argument index="2" name="set_index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_dispatch">
+ <return type="void">
+ </return>
+ <argument index="0" name="compute_list" type="int">
+ </argument>
+ <argument index="1" name="x_groups" type="int">
+ </argument>
+ <argument index="2" name="y_groups" type="int">
+ </argument>
+ <argument index="3" name="z_groups" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_end">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="compute_list_set_push_constant">
+ <return type="void">
+ </return>
+ <argument index="0" name="compute_list" type="int">
+ </argument>
+ <argument index="1" name="buffer" type="PackedByteArray">
+ </argument>
+ <argument index="2" name="size_bytes" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_pipeline_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="shader" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="compute_pipeline_is_valid">
+ <return type="bool">
+ </return>
+ <argument index="0" name="compute_pieline" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="create_local_device">
+ <return type="RenderingDevice">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_begin">
+ <return type="int">
+ </return>
+ <argument index="0" name="framebuffer" type="RID">
+ </argument>
+ <argument index="1" name="initial_color_action" type="int" enum="RenderingDevice.InitialAction">
+ </argument>
+ <argument index="2" name="final_color_action" type="int" enum="RenderingDevice.FinalAction">
+ </argument>
+ <argument index="3" name="initial_depth_action" type="int" enum="RenderingDevice.InitialAction">
+ </argument>
+ <argument index="4" name="final_depth_action" type="int" enum="RenderingDevice.FinalAction">
+ </argument>
+ <argument index="5" name="clear_color_values" type="PackedColorArray" default="PackedColorArray( )">
+ </argument>
+ <argument index="6" name="clear_depth" type="float" default="1.0">
+ </argument>
+ <argument index="7" name="clear_stencil" type="int" default="0">
+ </argument>
+ <argument index="8" name="region" type="Rect2" default="Rect2i( 0, 0, 0, 0 )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_begin_for_screen">
+ <return type="int">
+ </return>
+ <argument index="0" name="screen" type="int" default="0">
+ </argument>
+ <argument index="1" name="clear_color" type="Color" default="Color( 0, 0, 0, 1 )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_begin_split">
+ <return type="PackedInt64Array">
+ </return>
+ <argument index="0" name="framebuffer" type="RID">
+ </argument>
+ <argument index="1" name="splits" type="int">
+ </argument>
+ <argument index="2" name="initial_color_action" type="int" enum="RenderingDevice.InitialAction">
+ </argument>
+ <argument index="3" name="final_color_action" type="int" enum="RenderingDevice.FinalAction">
+ </argument>
+ <argument index="4" name="initial_depth_action" type="int" enum="RenderingDevice.InitialAction">
+ </argument>
+ <argument index="5" name="final_depth_action" type="int" enum="RenderingDevice.FinalAction">
+ </argument>
+ <argument index="6" name="clear_color_values" type="PackedColorArray" default="PackedColorArray( )">
+ </argument>
+ <argument index="7" name="clear_depth" type="float" default="1.0">
+ </argument>
+ <argument index="8" name="clear_stencil" type="int" default="0">
+ </argument>
+ <argument index="9" name="region" type="Rect2" default="Rect2i( 0, 0, 0, 0 )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_bind_index_array">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="index_array" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_bind_render_pipeline">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="render_pipeline" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_bind_uniform_set">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="uniform_set" type="RID">
+ </argument>
+ <argument index="2" name="set_index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_bind_vertex_array">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="vertex_array" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_disable_scissor">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_draw">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="use_indices" type="bool">
+ </argument>
+ <argument index="2" name="instances" type="int">
+ </argument>
+ <argument index="3" name="procedural_vertex_count" type="int" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_enable_scissor">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="rect" type="Rect2" default="Rect2i( 0, 0, 0, 0 )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_end">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="draw_list_set_push_constant">
+ <return type="void">
+ </return>
+ <argument index="0" name="draw_list" type="int">
+ </argument>
+ <argument index="1" name="buffer" type="PackedByteArray">
+ </argument>
+ <argument index="2" name="size_bytes" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="framebuffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="textures" type="Array">
+ </argument>
+ <argument index="1" name="validate_with_format" type="int" default="-1">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="framebuffer_format_create">
+ <return type="int">
+ </return>
+ <argument index="0" name="attachments" type="RDAttachmentFormat[]">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="framebuffer_format_get_texture_samples">
+ <return type="int" enum="RenderingDevice.TextureSamples">
+ </return>
+ <argument index="0" name="format" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="framebuffer_get_format">
+ <return type="int">
+ </return>
+ <argument index="0" name="framebuffer" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="free">
+ <return type="void">
+ </return>
+ <argument index="0" name="rid" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_captured_timestamp_cpu_time" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_captured_timestamp_gpu_time" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_captured_timestamp_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_captured_timestamps_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_captured_timestamps_frame" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_frame_delay" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="index_array_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="index_buffer" type="RID">
+ </argument>
+ <argument index="1" name="index_offset" type="int">
+ </argument>
+ <argument index="2" name="index_count" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="index_buffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="size_indices" type="int">
+ </argument>
+ <argument index="1" name="format" type="int" enum="RenderingDevice.IndexBufferFormat">
+ </argument>
+ <argument index="2" name="data" type="PackedByteArray" default="PackedByteArray( )">
+ </argument>
+ <argument index="3" name="arg3" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="limit_get">
+ <return type="int">
+ </return>
+ <argument index="0" name="limit" type="int" enum="RenderingDevice.Limit">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="render_pipeline_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="shader" type="RID">
+ </argument>
+ <argument index="1" name="framebuffer_format" type="int">
+ </argument>
+ <argument index="2" name="vertex_format" type="int">
+ </argument>
+ <argument index="3" name="primitive" type="int" enum="RenderingDevice.RenderPrimitive">
+ </argument>
+ <argument index="4" name="rasterization_state" type="RDPipelineRasterizationState">
+ </argument>
+ <argument index="5" name="multisample_state" type="RDPipelineMultisampleState">
+ </argument>
+ <argument index="6" name="stencil_state" type="RDPipelineDepthStencilState">
+ </argument>
+ <argument index="7" name="color_blend_state" type="RDPipelineColorBlendState">
+ </argument>
+ <argument index="8" name="dynamic_state_flags" type="int" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="render_pipeline_is_valid">
+ <return type="bool">
+ </return>
+ <argument index="0" name="render_pipeline" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="sampler_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="state" type="RDSamplerState">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="screen_get_framebuffer_format" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="screen_get_height" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="screen" type="int" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="screen_get_width" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="screen" type="int" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shader_compile_from_source">
+ <return type="RDShaderBytecode">
+ </return>
+ <argument index="0" name="shader_source" type="RDShaderSource">
+ </argument>
+ <argument index="1" name="allow_cache" type="bool" default="true">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shader_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="shader_data" type="RDShaderBytecode">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="shader_get_vertex_input_attribute_mask">
+ <return type="int">
+ </return>
+ <argument index="0" name="shader" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="storage_buffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="size_bytes" type="int">
+ </argument>
+ <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="submit">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="sync">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="texture_buffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="size_bytes" type="int">
+ </argument>
+ <argument index="1" name="format" type="int" enum="RenderingDevice.DataFormat">
+ </argument>
+ <argument index="2" name="data" type="PackedByteArray" default="PackedByteArray( )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_clear">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="texture" type="RID">
+ </argument>
+ <argument index="1" name="color" type="Color">
+ </argument>
+ <argument index="2" name="base_mipmap" type="int">
+ </argument>
+ <argument index="3" name="mipmap_count" type="int">
+ </argument>
+ <argument index="4" name="base_layer" type="int">
+ </argument>
+ <argument index="5" name="layer_count" type="int">
+ </argument>
+ <argument index="6" name="sync_with_draw" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_copy">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="from_texture" type="RID">
+ </argument>
+ <argument index="1" name="to_texture" type="RID">
+ </argument>
+ <argument index="2" name="from_pos" type="Vector3">
+ </argument>
+ <argument index="3" name="to_pos" type="Vector3">
+ </argument>
+ <argument index="4" name="size" type="Vector3">
+ </argument>
+ <argument index="5" name="src_mipmap" type="int">
+ </argument>
+ <argument index="6" name="dst_mipmap" type="int">
+ </argument>
+ <argument index="7" name="src_layer" type="int">
+ </argument>
+ <argument index="8" name="dst_layer" type="int">
+ </argument>
+ <argument index="9" name="sync_with_draw" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="format" type="RDTextureFormat">
+ </argument>
+ <argument index="1" name="view" type="RDTextureView">
+ </argument>
+ <argument index="2" name="data" type="PackedByteArray[]" default="[ ]">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_create_shared">
+ <return type="RID">
+ </return>
+ <argument index="0" name="view" type="RDTextureView">
+ </argument>
+ <argument index="1" name="with_texture" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_create_shared_from_slice">
+ <return type="RID">
+ </return>
+ <argument index="0" name="view" type="RDTextureView">
+ </argument>
+ <argument index="1" name="with_texture" type="RID">
+ </argument>
+ <argument index="2" name="layer" type="int">
+ </argument>
+ <argument index="3" name="mipmap" type="int">
+ </argument>
+ <argument index="4" name="slice_type" type="int" enum="RenderingDevice.TextureSliceType" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_get_data">
+ <return type="PackedByteArray">
+ </return>
+ <argument index="0" name="texture" type="RID">
+ </argument>
+ <argument index="1" name="layer" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_is_format_supported_for_usage" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="format" type="int" enum="RenderingDevice.DataFormat">
+ </argument>
+ <argument index="1" name="usage_flags" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_is_shared">
+ <return type="bool">
+ </return>
+ <argument index="0" name="texture" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_is_valid">
+ <return type="bool">
+ </return>
+ <argument index="0" name="texture" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_resolve_multisample">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="from_texture" type="RID">
+ </argument>
+ <argument index="1" name="to_texture" type="RID">
+ </argument>
+ <argument index="2" name="sync_with_draw" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="texture_update">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="texture" type="RID">
+ </argument>
+ <argument index="1" name="layer" type="int">
+ </argument>
+ <argument index="2" name="data" type="PackedByteArray">
+ </argument>
+ <argument index="3" name="sync_with_draw" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="uniform_buffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="size_bytes" type="int">
+ </argument>
+ <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="uniform_set_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="uniforms" type="Array">
+ </argument>
+ <argument index="1" name="shader" type="RID">
+ </argument>
+ <argument index="2" name="shader_set" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="uniform_set_is_valid">
+ <return type="bool">
+ </return>
+ <argument index="0" name="uniform_set" type="RID">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="vertex_buffer_create">
+ <return type="RID">
+ </return>
+ <argument index="0" name="size_bytes" type="int">
+ </argument>
+ <argument index="1" name="data" type="PackedByteArray" default="PackedByteArray( )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="vertex_format_create">
+ <return type="int">
+ </return>
+ <argument index="0" name="vertex_descriptions" type="RDVertexAttribute[]">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<constants>
+ <constant name="DATA_FORMAT_R4G4_UNORM_PACK8" value="0" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R4G4B4A4_UNORM_PACK16" value="1" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B4G4R4A4_UNORM_PACK16" value="2" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R5G6B5_UNORM_PACK16" value="3" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B5G6R5_UNORM_PACK16" value="4" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R5G5B5A1_UNORM_PACK16" value="5" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B5G5R5A1_UNORM_PACK16" value="6" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A1R5G5B5_UNORM_PACK16" value="7" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_UNORM" value="8" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_SNORM" value="9" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_USCALED" value="10" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_SSCALED" value="11" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_UINT" value="12" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_SINT" value="13" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8_SRGB" value="14" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_UNORM" value="15" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_SNORM" value="16" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_USCALED" value="17" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_SSCALED" value="18" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_UINT" value="19" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_SINT" value="20" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8_SRGB" value="21" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_UNORM" value="22" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_SNORM" value="23" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_USCALED" value="24" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_SSCALED" value="25" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_UINT" value="26" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_SINT" value="27" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8_SRGB" value="28" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_UNORM" value="29" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_SNORM" value="30" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_USCALED" value="31" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_SSCALED" value="32" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_UINT" value="33" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_SINT" value="34" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8_SRGB" value="35" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_UNORM" value="36" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_SNORM" value="37" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_USCALED" value="38" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_SSCALED" value="39" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_UINT" value="40" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_SINT" value="41" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R8G8B8A8_SRGB" value="42" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_UNORM" value="43" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_SNORM" value="44" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_USCALED" value="45" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_SSCALED" value="46" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_UINT" value="47" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_SINT" value="48" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8A8_SRGB" value="49" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_UNORM_PACK32" value="50" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_SNORM_PACK32" value="51" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_USCALED_PACK32" value="52" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_SSCALED_PACK32" value="53" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_UINT_PACK32" value="54" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_SINT_PACK32" value="55" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A8B8G8R8_SRGB_PACK32" value="56" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_UNORM_PACK32" value="57" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_SNORM_PACK32" value="58" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_USCALED_PACK32" value="59" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_SSCALED_PACK32" value="60" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_UINT_PACK32" value="61" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2R10G10B10_SINT_PACK32" value="62" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_UNORM_PACK32" value="63" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_SNORM_PACK32" value="64" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_USCALED_PACK32" value="65" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_SSCALED_PACK32" value="66" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_UINT_PACK32" value="67" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_A2B10G10R10_SINT_PACK32" value="68" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_UNORM" value="69" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_SNORM" value="70" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_USCALED" value="71" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_SSCALED" value="72" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_UINT" value="73" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_SINT" value="74" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16_SFLOAT" value="75" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_UNORM" value="76" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_SNORM" value="77" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_USCALED" value="78" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_SSCALED" value="79" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_UINT" value="80" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_SINT" value="81" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16_SFLOAT" value="82" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_UNORM" value="83" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_SNORM" value="84" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_USCALED" value="85" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_SSCALED" value="86" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_UINT" value="87" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_SINT" value="88" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16_SFLOAT" value="89" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_UNORM" value="90" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_SNORM" value="91" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_USCALED" value="92" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_SSCALED" value="93" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_UINT" value="94" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_SINT" value="95" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R16G16B16A16_SFLOAT" value="96" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32_UINT" value="97" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32_SINT" value="98" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32_SFLOAT" value="99" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32_UINT" value="100" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32_SINT" value="101" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32_SFLOAT" value="102" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32_UINT" value="103" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32_SINT" value="104" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32_SFLOAT" value="105" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32A32_UINT" value="106" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32A32_SINT" value="107" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R32G32B32A32_SFLOAT" value="108" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64_UINT" value="109" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64_SINT" value="110" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64_SFLOAT" value="111" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64_UINT" value="112" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64_SINT" value="113" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64_SFLOAT" value="114" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64_UINT" value="115" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64_SINT" value="116" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64_SFLOAT" value="117" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64A64_UINT" value="118" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64A64_SINT" value="119" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R64G64B64A64_SFLOAT" value="120" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B10G11R11_UFLOAT_PACK32" value="121" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32" value="122" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_D16_UNORM" value="123" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_X8_D24_UNORM_PACK32" value="124" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_D32_SFLOAT" value="125" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_S8_UINT" value="126" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_D16_UNORM_S8_UINT" value="127" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_D24_UNORM_S8_UINT" value="128" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_D32_SFLOAT_S8_UINT" value="129" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC1_RGB_UNORM_BLOCK" value="130" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC1_RGB_SRGB_BLOCK" value="131" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC1_RGBA_UNORM_BLOCK" value="132" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC1_RGBA_SRGB_BLOCK" value="133" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC2_UNORM_BLOCK" value="134" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC2_SRGB_BLOCK" value="135" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC3_UNORM_BLOCK" value="136" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC3_SRGB_BLOCK" value="137" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC4_UNORM_BLOCK" value="138" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC4_SNORM_BLOCK" value="139" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC5_UNORM_BLOCK" value="140" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC5_SNORM_BLOCK" value="141" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC6H_UFLOAT_BLOCK" value="142" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC6H_SFLOAT_BLOCK" value="143" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC7_UNORM_BLOCK" value="144" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_BC7_SRGB_BLOCK" value="145" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK" value="146" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK" value="147" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK" value="148" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK" value="149" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK" value="150" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK" value="151" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_EAC_R11_UNORM_BLOCK" value="152" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_EAC_R11_SNORM_BLOCK" value="153" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_EAC_R11G11_UNORM_BLOCK" value="154" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_EAC_R11G11_SNORM_BLOCK" value="155" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_4x4_UNORM_BLOCK" value="156" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_4x4_SRGB_BLOCK" value="157" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_5x4_UNORM_BLOCK" value="158" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_5x4_SRGB_BLOCK" value="159" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_5x5_UNORM_BLOCK" value="160" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_5x5_SRGB_BLOCK" value="161" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_6x5_UNORM_BLOCK" value="162" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_6x5_SRGB_BLOCK" value="163" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_6x6_UNORM_BLOCK" value="164" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_6x6_SRGB_BLOCK" value="165" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x5_UNORM_BLOCK" value="166" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x5_SRGB_BLOCK" value="167" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x6_UNORM_BLOCK" value="168" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x6_SRGB_BLOCK" value="169" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x8_UNORM_BLOCK" value="170" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_8x8_SRGB_BLOCK" value="171" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x5_UNORM_BLOCK" value="172" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x5_SRGB_BLOCK" value="173" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x6_UNORM_BLOCK" value="174" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x6_SRGB_BLOCK" value="175" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x8_UNORM_BLOCK" value="176" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x8_SRGB_BLOCK" value="177" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x10_UNORM_BLOCK" value="178" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_10x10_SRGB_BLOCK" value="179" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_12x10_UNORM_BLOCK" value="180" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_12x10_SRGB_BLOCK" value="181" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_12x12_UNORM_BLOCK" value="182" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_ASTC_12x12_SRGB_BLOCK" value="183" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8B8G8R8_422_UNORM" value="184" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B8G8R8G8_422_UNORM" value="185" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM" value="186" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM" value="187" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM" value="188" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM" value="189" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM" value="190" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R10X6_UNORM_PACK16" value="191" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R10X6G10X6_UNORM_2PACK16" value="192" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16" value="193" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16" value="194" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16" value="195" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16" value="196" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16" value="197" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16" value="198" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16" value="199" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16" value="200" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R12X4_UNORM_PACK16" value="201" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R12X4G12X4_UNORM_2PACK16" value="202" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16" value="203" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16" value="204" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16" value="205" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16" value="206" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16" value="207" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16" value="208" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16" value="209" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16" value="210" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16B16G16R16_422_UNORM" value="211" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_B16G16R16G16_422_UNORM" value="212" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM" value="213" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM" value="214" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM" value="215" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM" value="216" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM" value="217" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG" value="218" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG" value="219" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG" value="220" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG" value="221" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG" value="222" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG" value="223" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG" value="224" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG" value="225" enum="DataFormat">
+ </constant>
+ <constant name="DATA_FORMAT_MAX" value="226" enum="DataFormat">
+ </constant>
+ <constant name="TEXTURE_TYPE_1D" value="0" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_2D" value="1" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_3D" value="2" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_CUBE" value="3" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_1D_ARRAY" value="4" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_2D_ARRAY" value="5" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_CUBE_ARRAY" value="6" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_TYPE_MAX" value="7" enum="TextureType">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_1" value="0" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_2" value="1" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_4" value="2" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_8" value="3" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_16" value="4" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_32" value="5" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_64" value="6" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_SAMPLES_MAX" value="7" enum="TextureSamples">
+ </constant>
+ <constant name="TEXTURE_USAGE_SAMPLING_BIT" value="1" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_COLOR_ATTACHMENT_BIT" value="2" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT" value="4" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_STORAGE_BIT" value="8" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_STORAGE_ATOMIC_BIT" value="16" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_CPU_READ_BIT" value="32" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_CAN_UPDATE_BIT" value="64" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_CAN_COPY_FROM_BIT" value="128" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_CAN_COPY_TO_BIT" value="256" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT" value="512" enum="TextureUsageBits">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_IDENTITY" value="0" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_ZERO" value="1" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_ONE" value="2" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_R" value="3" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_G" value="4" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_B" value="5" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_A" value="6" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SWIZZLE_MAX" value="7" enum="TextureSwizzle">
+ </constant>
+ <constant name="TEXTURE_SLICE_2D" value="0" enum="TextureSliceType">
+ </constant>
+ <constant name="TEXTURE_SLICE_CUBEMAP" value="1" enum="TextureSliceType">
+ </constant>
+ <constant name="TEXTURE_SLICE_3D" value="2" enum="TextureSliceType">
+ </constant>
+ <constant name="SAMPLER_FILTER_NEAREST" value="0" enum="SamplerFilter">
+ </constant>
+ <constant name="SAMPLER_FILTER_LINEAR" value="1" enum="SamplerFilter">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_REPEAT" value="0" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_MIRRORED_REPEAT" value="1" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE" value="2" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER" value="3" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE" value="4" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_REPEAT_MODE_MAX" value="5" enum="SamplerRepeatMode">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK" value="0" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK" value="1" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK" value="2" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK" value="3" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE" value="4" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE" value="5" enum="SamplerBorderColor">
+ </constant>
+ <constant name="SAMPLER_BORDER_COLOR_MAX" value="6" enum="SamplerBorderColor">
+ </constant>
+ <constant name="VERTEX_FREQUENCY_VERTEX" value="0" enum="VertexFrequency">
+ </constant>
+ <constant name="VERTEX_FREQUENCY_INSTANCE" value="1" enum="VertexFrequency">
+ </constant>
+ <constant name="INDEX_BUFFER_FORMAT_UINT16" value="0" enum="IndexBufferFormat">
+ </constant>
+ <constant name="INDEX_BUFFER_FORMAT_UINT32" value="1" enum="IndexBufferFormat">
+ </constant>
+ <constant name="UNIFORM_TYPE_SAMPLER" value="0" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_SAMPLER_WITH_TEXTURE" value="1" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_TEXTURE" value="2" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_IMAGE" value="3" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_TEXTURE_BUFFER" value="4" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER" value="5" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_IMAGE_BUFFER" value="6" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_UNIFORM_BUFFER" value="7" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_STORAGE_BUFFER" value="8" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_INPUT_ATTACHMENT" value="9" enum="UniformType">
+ </constant>
+ <constant name="UNIFORM_TYPE_MAX" value="10" enum="UniformType">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_POINTS" value="0" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_LINES" value="1" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_LINES_WITH_ADJACENCY" value="2" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_LINESTRIPS" value="3" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_LINESTRIPS_WITH_ADJACENCY" value="4" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TRIANGLES" value="5" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TRIANGLES_WITH_ADJACENCY" value="6" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS" value="7" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_AJACENCY" value="8" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX" value="9" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_TESSELATION_PATCH" value="10" enum="RenderPrimitive">
+ </constant>
+ <constant name="RENDER_PRIMITIVE_MAX" value="11" enum="RenderPrimitive">
+ </constant>
+ <constant name="POLYGON_CULL_DISABLED" value="0" enum="PolygonCullMode">
+ </constant>
+ <constant name="POLYGON_CULL_FRONT" value="1" enum="PolygonCullMode">
+ </constant>
+ <constant name="POLYGON_CULL_BACK" value="2" enum="PolygonCullMode">
+ </constant>
+ <constant name="POLYGON_FRONT_FACE_CLOCKWISE" value="0" enum="PolygonFrontFace">
+ </constant>
+ <constant name="POLYGON_FRONT_FACE_COUNTER_CLOCKWISE" value="1" enum="PolygonFrontFace">
+ </constant>
+ <constant name="STENCIL_OP_KEEP" value="0" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_ZERO" value="1" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_REPLACE" value="2" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_INCREMENT_AND_CLAMP" value="3" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_DECREMENT_AND_CLAMP" value="4" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_INVERT" value="5" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_INCREMENT_AND_WRAP" value="6" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_DECREMENT_AND_WRAP" value="7" enum="StencilOperation">
+ </constant>
+ <constant name="STENCIL_OP_MAX" value="8" enum="StencilOperation">
+ </constant>
+ <constant name="COMPARE_OP_NEVER" value="0" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_LESS" value="1" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_EQUAL" value="2" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_LESS_OR_EQUAL" value="3" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_GREATER" value="4" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_NOT_EQUAL" value="5" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_GREATER_OR_EQUAL" value="6" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_ALWAYS" value="7" enum="CompareOperator">
+ </constant>
+ <constant name="COMPARE_OP_MAX" value="8" enum="CompareOperator">
+ </constant>
+ <constant name="LOGIC_OP_CLEAR" value="0" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_AND" value="1" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_AND_REVERSE" value="2" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_COPY" value="3" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_AND_INVERTED" value="4" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_NO_OP" value="5" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_XOR" value="6" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_OR" value="7" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_NOR" value="8" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_EQUIVALENT" value="9" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_INVERT" value="10" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_OR_REVERSE" value="11" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_COPY_INVERTED" value="12" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_OR_INVERTED" value="13" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_NAND" value="14" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_SET" value="15" enum="LogicOperation">
+ </constant>
+ <constant name="LOGIC_OP_MAX" value="16" enum="LogicOperation">
+ </constant>
+ <constant name="BLEND_FACTOR_ZERO" value="0" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE" value="1" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_SRC_COLOR" value="2" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_SRC_COLOR" value="3" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_DST_COLOR" value="4" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_DST_COLOR" value="5" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_SRC_ALPHA" value="6" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_SRC_ALPHA" value="7" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_DST_ALPHA" value="8" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_DST_ALPHA" value="9" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_CONSTANT_COLOR" value="10" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR" value="11" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_CONSTANT_ALPHA" value="12" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA" value="13" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_SRC_ALPHA_SATURATE" value="14" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_SRC1_COLOR" value="15" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_SRC1_COLOR" value="16" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_SRC1_ALPHA" value="17" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA" value="18" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_FACTOR_MAX" value="19" enum="BlendFactor">
+ </constant>
+ <constant name="BLEND_OP_ADD" value="0" enum="BlendOperation">
+ </constant>
+ <constant name="BLEND_OP_SUBTRACT" value="1" enum="BlendOperation">
+ </constant>
+ <constant name="BLEND_OP_REVERSE_SUBTRACT" value="2" enum="BlendOperation">
+ </constant>
+ <constant name="BLEND_OP_MINIMUM" value="3" enum="BlendOperation">
+ </constant>
+ <constant name="BLEND_OP_MAXIMUM" value="4" enum="BlendOperation">
+ </constant>
+ <constant name="BLEND_OP_MAX" value="5" enum="BlendOperation">
+ </constant>
+ <constant name="DYNAMIC_STATE_LINE_WIDTH" value="1" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_DEPTH_BIAS" value="2" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_BLEND_CONSTANTS" value="4" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_DEPTH_BOUNDS" value="8" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_STENCIL_COMPARE_MASK" value="16" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_STENCIL_WRITE_MASK" value="32" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="DYNAMIC_STATE_STENCIL_REFERENCE" value="64" enum="PipelineDynamicStateFlags">
+ </constant>
+ <constant name="INITIAL_ACTION_CLEAR" value="0" enum="InitialAction">
+ </constant>
+ <constant name="INITIAL_ACTION_KEEP" value="1" enum="InitialAction">
+ </constant>
+ <constant name="INITIAL_ACTION_DROP" value="2" enum="InitialAction">
+ </constant>
+ <constant name="INITIAL_ACTION_CONTINUE" value="3" enum="InitialAction">
+ </constant>
+ <constant name="INITIAL_ACTION_MAX" value="4" enum="InitialAction">
+ </constant>
+ <constant name="FINAL_ACTION_READ" value="0" enum="FinalAction">
+ </constant>
+ <constant name="FINAL_ACTION_DISCARD" value="1" enum="FinalAction">
+ </constant>
+ <constant name="FINAL_ACTION_CONTINUE" value="2" enum="FinalAction">
+ </constant>
+ <constant name="FINAL_ACTION_MAX" value="3" enum="FinalAction">
+ </constant>
+ <constant name="SHADER_STAGE_VERTEX" value="0" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_FRAGMENT" value="1" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_TESSELATION_CONTROL" value="2" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_TESSELATION_EVALUATION" value="3" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_COMPUTE" value="4" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_MAX" value="5" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_VERTEX_BIT" value="1" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_FRAGMENT_BIT" value="2" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_TESSELATION_CONTROL_BIT" value="4" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_TESSELATION_EVALUATION_BIT" value="8" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_STAGE_COMPUTE_BIT" value="16" enum="ShaderStage">
+ </constant>
+ <constant name="SHADER_LANGUAGE_GLSL" value="0" enum="ShaderLanguage">
+ </constant>
+ <constant name="SHADER_LANGUAGE_HLSL" value="1" enum="ShaderLanguage">
+ </constant>
+ <constant name="LIMIT_MAX_BOUND_UNIFORM_SETS" value="0" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS" value="1" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURES_PER_UNIFORM_SET" value="2" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET" value="3" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET" value="4" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET" value="5" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET" value="6" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_DRAW_INDEXED_INDEX" value="7" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_FRAMEBUFFER_HEIGHT" value="8" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_FRAMEBUFFER_WIDTH" value="9" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURE_ARRAY_LAYERS" value="10" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURE_SIZE_1D" value="11" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURE_SIZE_2D" value="12" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURE_SIZE_3D" value="13" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURE_SIZE_CUBE" value="14" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_TEXTURES_PER_SHADER_STAGE" value="15" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE" value="16" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE" value="17" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE" value="18" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE" value="19" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_PUSH_CONSTANT_SIZE" value="20" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_UNIFORM_BUFFER_SIZE" value="21" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET" value="22" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES" value="23" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_VERTEX_INPUT_BINDINGS" value="24" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE" value="25" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT" value="26" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE" value="27" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X" value="28" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y" value="29" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z" value="30" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS" value="31" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X" value="32" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y" value="33" enum="Limit">
+ </constant>
+ <constant name="LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z" value="34" enum="Limit">
+ </constant>
+ <constant name="INVALID_ID" value="-1">
+ </constant>
+ <constant name="INVALID_FORMAT_ID" value="-1">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index bfdcf1bb79..d8be6d4bd7 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -4,12 +4,12 @@
Server for anything visible.
</brief_description>
<description>
- Server for anything visible. The visual server is the API backend for everything visible. The whole scene system mounts on it to display.
- The visual server is completely opaque, the internals are entirely implementation specific and cannot be accessed.
- The visual server can be used to bypass the scene system entirely.
+ Server for anything visible. The rendering server is the API backend for everything visible. The whole scene system mounts on it to display.
+ The rendering server is completely opaque, the internals are entirely implementation specific and cannot be accessed.
+ The rendering server can be used to bypass the scene system entirely.
Resources are created using the [code]*_create[/code] functions.
All objects are drawn to a viewport. You can use the [Viewport] attached to the [SceneTree] or you can create one yourself with [method viewport_create]. When using a custom scenario or canvas, the scenario or canvas needs to be attached to the viewport using [method viewport_set_scenario] or [method viewport_attach_canvas].
- In 3D, all visual objects must be associated with a scenario. The scenario is a visual representation of the world. If accessing the visual server from a running game, the scenario can be accessed from the scene tree from any [Node3D] node with [method Node3D.get_world]. Otherwise, a scenario can be created with [method scenario_create].
+ In 3D, all visual objects must be associated with a scenario. The scenario is a visual representation of the world. If accessing the rendering server from a running game, the scenario can be accessed from the scene tree from any [Node3D] node with [method Node3D.get_world_3d]. Otherwise, a scenario can be created with [method scenario_create].
Similarly in 2D, a canvas is needed to draw all canvas items.
In 3D, all visible objects are comprised of a resource and an instance. A resource can be a mesh, a particle system, a light, or any other 3D object. In order to be visible resources must be attached to an instance using [method instance_set_base]. The instance must also be attached to the scenario using [method instance_set_scenario] in order to be visible.
In 2D, all visible objects are some form of canvas item. In order to be visible, a canvas item needs to be the child of a canvas attached to a viewport, or it needs to be the child of another canvas item that is eventually attached to the canvas.
@@ -947,6 +947,58 @@
Returns the id of a white texture. Creates one if none exists.
</description>
</method>
+ <method name="global_variable_add">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <argument index="1" name="type" type="int" enum="RenderingServer.GlobalVariableType">
+ </argument>
+ <argument index="2" name="default_value" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="global_variable_get" qualifiers="const">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="global_variable_get_list" qualifiers="const">
+ <return type="PackedStringArray">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="global_variable_get_type" qualifiers="const">
+ <return type="int" enum="RenderingServer.GlobalVariableType">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="global_variable_remove">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="global_variable_set">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <argument index="1" name="value" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="has_changed" qualifiers="const">
<return type="bool">
</return>
@@ -1113,7 +1165,7 @@
<return type="void">
</return>
<description>
- Initializes the visual server. This function is called internally by platform-dependent code during engine initialization. If called from a running game, it will not do anything.
+ Initializes the rendering server. This function is called internally by platform-dependent code during engine initialization. If called from a running game, it will not do anything.
</description>
</method>
<method name="instance_attach_object_instance_id">
@@ -1230,7 +1282,7 @@
<argument index="1" name="base" type="RID">
</argument>
<description>
- Sets the base of the instance. A base can be any of the 3D objects that are created in the RenderingServer that can be displayed. For example, any of the light types, mesh, multimesh, immediate geometry, particle system, reflection probe, lightmap capture, and the GI probe are all types that can be set as the base of an instance in order to be displayed in the scenario.
+ Sets the base of the instance. A base can be any of the 3D objects that are created in the RenderingServer that can be displayed. For example, any of the light types, mesh, multimesh, immediate geometry, particle system, reflection probe, lightmap, and the GI probe are all types that can be set as the base of an instance in order to be displayed in the scenario.
</description>
</method>
<method name="instance_set_blend_shape_weight">
@@ -1325,19 +1377,6 @@
Sets the world space transform of the instance. Equivalent to [member Node3D.transform].
</description>
</method>
- <method name="instance_set_use_lightmap">
- <return type="void">
- </return>
- <argument index="0" name="instance" type="RID">
- </argument>
- <argument index="1" name="lightmap_instance" type="RID">
- </argument>
- <argument index="2" name="lightmap" type="RID">
- </argument>
- <description>
- Sets the lightmap to use with this instance.
- </description>
- </method>
<method name="instance_set_visible">
<return type="void">
</return>
@@ -1532,115 +1571,6 @@
Sets whether GI probes capture light information from this light.
</description>
</method>
- <method name="lightmap_capture_create">
- <return type="RID">
- </return>
- <description>
- Creates a lightmap capture and adds it to the RenderingServer. It can be accessed with the RID that is returned. This RID will be used in all [code]lightmap_capture_*[/code] RenderingServer functions.
- Once finished with your RID, you will want to free the RID using the RenderingServer's [method free_rid] static method.
- To place in a scene, attach this lightmap capture to an instance using [method instance_set_base] using the returned RID.
- </description>
- </method>
- <method name="lightmap_capture_get_bounds" qualifiers="const">
- <return type="AABB">
- </return>
- <argument index="0" name="capture" type="RID">
- </argument>
- <description>
- Returns the size of the lightmap capture area.
- </description>
- </method>
- <method name="lightmap_capture_get_energy" qualifiers="const">
- <return type="float">
- </return>
- <argument index="0" name="capture" type="RID">
- </argument>
- <description>
- Returns the energy multiplier used by the lightmap capture.
- </description>
- </method>
- <method name="lightmap_capture_get_octree" qualifiers="const">
- <return type="PackedByteArray">
- </return>
- <argument index="0" name="capture" type="RID">
- </argument>
- <description>
- Returns the octree used by the lightmap capture.
- </description>
- </method>
- <method name="lightmap_capture_get_octree_cell_subdiv" qualifiers="const">
- <return type="int">
- </return>
- <argument index="0" name="capture" type="RID">
- </argument>
- <description>
- Returns the cell subdivision amount used by this lightmap capture's octree.
- </description>
- </method>
- <method name="lightmap_capture_get_octree_cell_transform" qualifiers="const">
- <return type="Transform">
- </return>
- <argument index="0" name="capture" type="RID">
- </argument>
- <description>
- Returns the cell transform for this lightmap capture's octree.
- </description>
- </method>
- <method name="lightmap_capture_set_bounds">
- <return type="void">
- </return>
- <argument index="0" name="capture" type="RID">
- </argument>
- <argument index="1" name="bounds" type="AABB">
- </argument>
- <description>
- Sets the size of the area covered by the lightmap capture.
- </description>
- </method>
- <method name="lightmap_capture_set_energy">
- <return type="void">
- </return>
- <argument index="0" name="capture" type="RID">
- </argument>
- <argument index="1" name="energy" type="float">
- </argument>
- <description>
- Sets the energy multiplier for this lightmap capture.
- </description>
- </method>
- <method name="lightmap_capture_set_octree">
- <return type="void">
- </return>
- <argument index="0" name="capture" type="RID">
- </argument>
- <argument index="1" name="octree" type="PackedByteArray">
- </argument>
- <description>
- Sets the octree to be used by this lightmap capture.
- </description>
- </method>
- <method name="lightmap_capture_set_octree_cell_subdiv">
- <return type="void">
- </return>
- <argument index="0" name="capture" type="RID">
- </argument>
- <argument index="1" name="subdiv" type="int">
- </argument>
- <description>
- Sets the subdivision level of this lightmap capture's octree.
- </description>
- </method>
- <method name="lightmap_capture_set_octree_cell_transform">
- <return type="void">
- </return>
- <argument index="0" name="capture" type="RID">
- </argument>
- <argument index="1" name="xform" type="Transform">
- </argument>
- <description>
- Sets the octree cell transform for this lightmap capture's octree.
- </description>
- </method>
<method name="make_sphere_mesh">
<return type="RID">
</return>
@@ -3110,12 +3040,6 @@
<constant name="MAX_CURSORS" value="8">
Unused enum in Godot 3.x.
</constant>
- <constant name="MATERIAL_RENDER_PRIORITY_MIN" value="-128">
- The minimum renderpriority of all materials.
- </constant>
- <constant name="MATERIAL_RENDER_PRIORITY_MAX" value="127">
- The maximum renderpriority of all materials.
- </constant>
<constant name="TEXTURE_LAYERED_2D_ARRAY" value="0" enum="TextureLayeredType">
</constant>
<constant name="TEXTURE_LAYERED_CUBEMAP" value="1" enum="TextureLayeredType">
@@ -3149,6 +3073,12 @@
<constant name="SHADER_MAX" value="4" enum="ShaderMode">
Represents the size of the [enum ShaderMode] enum.
</constant>
+ <constant name="MATERIAL_RENDER_PRIORITY_MIN" value="-128">
+ The minimum renderpriority of all materials.
+ </constant>
+ <constant name="MATERIAL_RENDER_PRIORITY_MAX" value="127">
+ The maximum renderpriority of all materials.
+ </constant>
<constant name="ARRAY_VERTEX" value="0" enum="ArrayType">
Array is a vertex array.
</constant>
@@ -3224,14 +3154,14 @@
<constant name="ARRAY_COMPRESS_INDEX" value="131072" enum="ArrayFormat">
Flag used to mark a compressed index array.
</constant>
+ <constant name="ARRAY_COMPRESS_DEFAULT" value="31744" enum="ArrayFormat">
+ Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant ARRAY_COMPRESS_TEX_UV] and [constant ARRAY_COMPRESS_TEX_UV2] quickly.
+ </constant>
<constant name="ARRAY_FLAG_USE_2D_VERTICES" value="262144" enum="ArrayFormat">
Flag used to mark that the array contains 2D vertices.
</constant>
<constant name="ARRAY_FLAG_USE_DYNAMIC_UPDATE" value="1048576" enum="ArrayFormat">
</constant>
- <constant name="ARRAY_COMPRESS_DEFAULT" value="31744" enum="ArrayFormat">
- Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant ARRAY_COMPRESS_TEX_UV] and [constant ARRAY_COMPRESS_TEX_UV2] quickly.
- </constant>
<constant name="PRIMITIVE_POINTS" value="0" enum="PrimitiveType">
Primitive to draw consists of points.
</constant>
@@ -3307,6 +3237,7 @@
Proportion of shadow atlas occupied by the third split. The fourth split occupies the rest.
</constant>
<constant name="LIGHT_PARAM_SHADOW_FADE_START" value="12" enum="LightParam">
+ Proportion of shadow max distance where the shadow will start to fade out.
</constant>
<constant name="LIGHT_PARAM_SHADOW_NORMAL_BIAS" value="13" enum="LightParam">
Normal bias used to offset shadow lookup by object normal. Can be used to fix self-shadowing artifacts.
@@ -3314,10 +3245,15 @@
<constant name="LIGHT_PARAM_SHADOW_BIAS" value="14" enum="LightParam">
Bias the shadow lookup to fix self-shadowing artifacts.
</constant>
- <constant name="LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE" value="15" enum="LightParam">
- Increases bias on further splits to fix self-shadowing that only occurs far away from the camera.
+ <constant name="LIGHT_PARAM_SHADOW_PANCAKE_SIZE" value="15" enum="LightParam">
+ Sets the size of the directional shadow pancake. The pancake offsets the start of the shadow's camera frustum to provide a higher effective depth resolution for the shadow. However, a high pancake size can cause artifacts in the shadows of large objects that are close to the edge of the frustum. Reducing the pancake size can help. Setting the size to [code]0[/code] turns off the pancaking effect.
+ </constant>
+ <constant name="LIGHT_PARAM_SHADOW_BLUR" value="16" enum="LightParam">
+ Blurs the edges of the shadow. Can be used to hide pixel artifacts in low resolution shadow maps. A high value can make shadows appear grainy and can cause other unwanted artifacts. Try to keep as near default as possible.
</constant>
- <constant name="LIGHT_PARAM_MAX" value="16" enum="LightParam">
+ <constant name="LIGHT_PARAM_TRANSMITTANCE_BIAS" value="17" enum="LightParam">
+ </constant>
+ <constant name="LIGHT_PARAM_MAX" value="18" enum="LightParam">
Represents the size of the [enum LightParam] enum.
</constant>
<constant name="LIGHT_OMNI_SHADOW_DUAL_PARABOLOID" value="0" enum="LightOmniShadowMode">
@@ -3347,6 +3283,16 @@
<constant name="REFLECTION_PROBE_UPDATE_ALWAYS" value="1" enum="ReflectionProbeUpdateMode">
Reflection probe will update each frame. This mode is necessary to capture moving objects.
</constant>
+ <constant name="DECAL_TEXTURE_ALBEDO" value="0" enum="DecalTexture">
+ </constant>
+ <constant name="DECAL_TEXTURE_NORMAL" value="1" enum="DecalTexture">
+ </constant>
+ <constant name="DECAL_TEXTURE_ORM" value="2" enum="DecalTexture">
+ </constant>
+ <constant name="DECAL_TEXTURE_EMISSION" value="3" enum="DecalTexture">
+ </constant>
+ <constant name="DECAL_TEXTURE_MAX" value="4" enum="DecalTexture">
+ </constant>
<constant name="PARTICLES_DRAW_ORDER_INDEX" value="0" enum="ParticlesDrawOrder">
Draw particles in the order that they appear in the particles array.
</constant>
@@ -3383,22 +3329,24 @@
Multisample antialiasing is disabled.
</constant>
<constant name="VIEWPORT_MSAA_2X" value="1" enum="ViewportMSAA">
- Multisample antialiasing is set to 2×.
+ Multisample antialiasing uses 2 samples per pixel.
</constant>
<constant name="VIEWPORT_MSAA_4X" value="2" enum="ViewportMSAA">
- Multisample antialiasing is set to 4×.
+ Multisample antialiasing uses 4 samples per pixel.
</constant>
<constant name="VIEWPORT_MSAA_8X" value="3" enum="ViewportMSAA">
- Multisample antialiasing is set to 8×.
+ Multisample antialiasing uses 8 samples per pixel.
</constant>
<constant name="VIEWPORT_MSAA_16X" value="4" enum="ViewportMSAA">
- Multisample antialiasing is set to 16×.
+ Multisample antialiasing uses 16 samples per pixel.
</constant>
- <constant name="VIEWPORT_MSAA_EXT_2X" value="5" enum="ViewportMSAA">
- Multisample antialiasing is set to 2× on external texture. Special mode for GLES2 Android VR (Oculus Quest and Go).
+ <constant name="VIEWPORT_MSAA_MAX" value="5" enum="ViewportMSAA">
</constant>
- <constant name="VIEWPORT_MSAA_EXT_4X" value="6" enum="ViewportMSAA">
- Multisample antialiasing is set to 4× on external texture. Special mode for GLES2 Android VR (Oculus Quest and Go).
+ <constant name="VIEWPORT_SCREEN_SPACE_AA_DISABLED" value="0" enum="ViewportScreenSpaceAA">
+ </constant>
+ <constant name="VIEWPORT_SCREEN_SPACE_AA_FXAA" value="1" enum="ViewportScreenSpaceAA">
+ </constant>
+ <constant name="VIEWPORT_SCREEN_SPACE_AA_MAX" value="2" enum="ViewportScreenSpaceAA">
</constant>
<constant name="VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME" value="0" enum="ViewportRenderInfo">
Number of objects drawn in a single frame.
@@ -3425,37 +3373,54 @@
Debug draw is disabled. Default setting.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_UNSHADED" value="1" enum="ViewportDebugDraw">
- Debug draw sets objects to unshaded.
+ Objects are displayed without light information.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_LIGHTING" value="2" enum="ViewportDebugDraw">
+ Objects are displayed with only light information.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_OVERDRAW" value="3" enum="ViewportDebugDraw">
- Overwrites clear color to [code](0,0,0,0)[/code].
+ Objects are displayed semi-transparent with additive blending so you can see where they are drawing over top of one another. A higher overdraw means you are wasting performance on drawing pixels that are being hidden behind others.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_WIREFRAME" value="4" enum="ViewportDebugDraw">
Debug draw draws objects in wireframe.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER" value="5" enum="ViewportDebugDraw">
+ Normal buffer is drawn instead of regular scene so you can see the per-pixel normals that will be used by post-processing effects.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO" value="6" enum="ViewportDebugDraw">
+ Objects are displayed with only the albedo value from [GIProbe]s.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING" value="7" enum="ViewportDebugDraw">
+ Objects are displayed with only the lighting value from [GIProbe]s.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION" value="8" enum="ViewportDebugDraw">
+ Objects are displayed with only the emission color from [GIProbe]s.
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_SHADOW_ATLAS" value="9" enum="ViewportDebugDraw">
+ Draws the shadow atlas that stores shadows from [OmniLight3D]s and [SpotLight3D]s in the upper left quadrant of the [Viewport].
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS" value="10" enum="ViewportDebugDraw">
+ Draws the shadow atlas that stores shadows from [DirectionalLight3D]s in the upper left quadrant of the [Viewport].
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_SCENE_LUMINANCE" value="11" enum="ViewportDebugDraw">
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_SSAO" value="12" enum="ViewportDebugDraw">
+ Draws the screen space ambient occlusion texture instead of the scene so that you can clearly see how it is affecting objects. In order for this display mode to work, you must have [member Environment.ssao_enabled] set in your [WorldEnvironment].
</constant>
<constant name="VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER" value="13" enum="ViewportDebugDraw">
+ Draws the roughness limiter post process over the Viewport so you can see where it has an effect. It must be enabled in [member ProjectSettings.rendering/quality/screen_filters/screen_space_roughness_limiter] to work.
+ </constant>
+ <constant name="VIEWPORT_DEBUG_DRAW_PSSM_SPLITS" value="14" enum="ViewportDebugDraw">
+ Colors each PSSM split for the [DirectionalLight3D]s in the scene a different color so you can see where the splits are. In order they will be colored red, green, blue, yellow.
+ </constant>
+ <constant name="VIEWPORT_DEBUG_DRAW_DECAL_ATLAS" value="15" enum="ViewportDebugDraw">
</constant>
<constant name="SKY_MODE_QUALITY" value="0" enum="SkyMode">
+ Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant Sky.PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples].
</constant>
<constant name="SKY_MODE_REALTIME" value="1" enum="SkyMode">
+ Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times.
+ [b]Note:[/b] The fast filtering algorithm is limited to 256x256 cubemaps, so [member Sky.radiance_size] must be set to [constant Sky.RADIANCE_SIZE_256].
</constant>
<constant name="ENV_BG_CLEAR_COLOR" value="0" enum="EnvironmentBG">
Use the clear color as background.
@@ -3479,28 +3444,40 @@
Represents the size of the [enum EnvironmentBG] enum.
</constant>
<constant name="ENV_AMBIENT_SOURCE_BG" value="0" enum="EnvironmentAmbientSource">
+ Gather ambient light from whichever source is specified as the background.
</constant>
<constant name="ENV_AMBIENT_SOURCE_DISABLED" value="1" enum="EnvironmentAmbientSource">
+ Disable ambient light.
</constant>
<constant name="ENV_AMBIENT_SOURCE_COLOR" value="2" enum="EnvironmentAmbientSource">
+ Specify a specific [Color] for ambient light.
</constant>
<constant name="ENV_AMBIENT_SOURCE_SKY" value="3" enum="EnvironmentAmbientSource">
+ Gather ambient light from the [Sky] regardless of what the background is.
</constant>
<constant name="ENV_REFLECTION_SOURCE_BG" value="0" enum="EnvironmentReflectionSource">
+ Use the background for reflections.
</constant>
<constant name="ENV_REFLECTION_SOURCE_DISABLED" value="1" enum="EnvironmentReflectionSource">
+ Disable reflections.
</constant>
<constant name="ENV_REFLECTION_SOURCE_SKY" value="2" enum="EnvironmentReflectionSource">
+ Use the [Sky] for reflections regardless of what the background is.
</constant>
<constant name="ENV_GLOW_BLEND_MODE_ADDITIVE" value="0" enum="EnvironmentGlowBlendMode">
+ Additive glow blending mode. Mostly used for particles, glows (bloom), lens flare, bright sources.
</constant>
<constant name="ENV_GLOW_BLEND_MODE_SCREEN" value="1" enum="EnvironmentGlowBlendMode">
+ Screen glow blending mode. Increases brightness, used frequently with bloom.
</constant>
<constant name="ENV_GLOW_BLEND_MODE_SOFTLIGHT" value="2" enum="EnvironmentGlowBlendMode">
+ Soft light glow blending mode. Modifies contrast, exposes shadows and highlights (vivid bloom).
</constant>
<constant name="ENV_GLOW_BLEND_MODE_REPLACE" value="3" enum="EnvironmentGlowBlendMode">
+ Replace glow blending mode. Replaces all pixels' color by the glow value. This can be used to simulate a full-screen blur effect by tweaking the glow parameters to match the original image's brightness.
</constant>
<constant name="ENV_GLOW_BLEND_MODE_MIX" value="4" enum="EnvironmentGlowBlendMode">
+ Mixes the glow with the underlying color to avoid increasing brightness as much while still maintaining a glow effect.
</constant>
<constant name="ENV_TONE_MAPPER_LINEAR" value="0" enum="EnvironmentToneMapper">
Output color as they came in.
@@ -3514,6 +3491,14 @@
<constant name="ENV_TONE_MAPPER_ACES" value="3" enum="EnvironmentToneMapper">
Use the ACES tonemapper.
</constant>
+ <constant name="ENV_SSR_ROUGNESS_QUALITY_DISABLED" value="0" enum="EnvironmentSSRRoughnessQuality">
+ </constant>
+ <constant name="ENV_SSR_ROUGNESS_QUALITY_LOW" value="1" enum="EnvironmentSSRRoughnessQuality">
+ </constant>
+ <constant name="ENV_SSR_ROUGNESS_QUALITY_MEDIUM" value="2" enum="EnvironmentSSRRoughnessQuality">
+ </constant>
+ <constant name="ENV_SSR_ROUGNESS_QUALITY_HIGH" value="3" enum="EnvironmentSSRRoughnessQuality">
+ </constant>
<constant name="ENV_SSAO_BLUR_DISABLED" value="0" enum="EnvironmentSSAOBlur">
Disables the blur set for SSAO. Will make SSAO look noisier.
</constant>
@@ -3533,23 +3518,51 @@
Medium quality screen space ambient occlusion.
</constant>
<constant name="ENV_SSAO_QUALITY_HIGH" value="2" enum="EnvironmentSSAOQuality">
- Highest quality screen space ambient occlusion.
+ High quality screen space ambient occlusion.
</constant>
<constant name="ENV_SSAO_QUALITY_ULTRA" value="3" enum="EnvironmentSSAOQuality">
+ Highest quality screen space ambient occlusion.
+ </constant>
+ <constant name="SUB_SURFACE_SCATTERING_QUALITY_DISABLED" value="0" enum="SubSurfaceScatteringQuality">
+ </constant>
+ <constant name="SUB_SURFACE_SCATTERING_QUALITY_LOW" value="1" enum="SubSurfaceScatteringQuality">
+ </constant>
+ <constant name="SUB_SURFACE_SCATTERING_QUALITY_MEDIUM" value="2" enum="SubSurfaceScatteringQuality">
+ </constant>
+ <constant name="SUB_SURFACE_SCATTERING_QUALITY_HIGH" value="3" enum="SubSurfaceScatteringQuality">
</constant>
<constant name="DOF_BLUR_QUALITY_VERY_LOW" value="0" enum="DOFBlurQuality">
+ Lowest quality DOF blur. This is the fastest setting, but you may be able to see filtering artifacts.
</constant>
<constant name="DOF_BLUR_QUALITY_LOW" value="1" enum="DOFBlurQuality">
+ Low quality DOF blur.
</constant>
<constant name="DOF_BLUR_QUALITY_MEDIUM" value="2" enum="DOFBlurQuality">
+ Medium quality DOF blur.
</constant>
<constant name="DOF_BLUR_QUALITY_HIGH" value="3" enum="DOFBlurQuality">
+ Highest quality DOF blur. Results in the smoothest looking blur by taking the most samples, but is also significantly slower.
</constant>
<constant name="DOF_BOKEH_BOX" value="0" enum="DOFBokehShape">
+ Calculate the DOF blur using a box filter. The fastest option, but results in obvious lines in blur pattern.
</constant>
<constant name="DOF_BOKEH_HEXAGON" value="1" enum="DOFBokehShape">
+ Calculates DOF blur using a hexagon shaped filter.
</constant>
<constant name="DOF_BOKEH_CIRCLE" value="2" enum="DOFBokehShape">
+ Calculates DOF blur using a circle shaped filter. Best quality and most realistic, but slowest. Use only for areas where a lot of performance can be dedicated to post-processing (e.g. cutscenes).
+ </constant>
+ <constant name="SHADOW_QUALITY_HARD" value="0" enum="ShadowQuality">
+ </constant>
+ <constant name="SHADOW_QUALITY_SOFT_LOW" value="1" enum="ShadowQuality">
+ </constant>
+ <constant name="SHADOW_QUALITY_SOFT_MEDIUM" value="2" enum="ShadowQuality">
+ </constant>
+ <constant name="SHADOW_QUALITY_SOFT_HIGH" value="3" enum="ShadowQuality">
+ </constant>
+ <constant name="SHADOW_QUALITY_SOFT_ULTRA" value="4" enum="ShadowQuality">
+ </constant>
+ <constant name="SHADOW_QUALITY_MAX" value="5" enum="ShadowQuality">
</constant>
<constant name="SCENARIO_DEBUG_DISABLED" value="0" enum="ScenarioDebugMode">
Do not use a debug mode.
@@ -3584,13 +3597,16 @@
<constant name="INSTANCE_REFLECTION_PROBE" value="6" enum="InstanceType">
The instance is a reflection probe.
</constant>
- <constant name="INSTANCE_GI_PROBE" value="7" enum="InstanceType">
+ <constant name="INSTANCE_DECAL" value="7" enum="InstanceType">
+ The instance is a decal.
+ </constant>
+ <constant name="INSTANCE_GI_PROBE" value="8" enum="InstanceType">
The instance is a GI probe.
</constant>
- <constant name="INSTANCE_LIGHTMAP_CAPTURE" value="8" enum="InstanceType">
- The instance is a lightmap capture.
+ <constant name="INSTANCE_LIGHTMAP" value="9" enum="InstanceType">
+ The instance is a lightmap.
</constant>
- <constant name="INSTANCE_MAX" value="9" enum="InstanceType">
+ <constant name="INSTANCE_MAX" value="10" enum="InstanceType">
Represents the size of the [enum InstanceType] enum.
</constant>
<constant name="INSTANCE_GEOMETRY_MASK" value="30" enum="InstanceType">
@@ -3600,6 +3616,7 @@
Allows the instance to be used in baked lighting.
</constant>
<constant name="INSTANCE_FLAG_USE_DYNAMIC_GI" value="1" enum="InstanceFlags">
+ Allows the instance to be used with dynamic global illumination.
</constant>
<constant name="INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE" value="2" enum="InstanceFlags">
When set, manually requests to draw geometry on next frame.
@@ -3629,30 +3646,43 @@
The nine patch gets filled with tiles where needed and stretches them a bit if needed.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_DEFAULT" value="0" enum="CanvasItemTextureFilter">
+ Uses the default filter mode for this [Viewport].
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="1" enum="CanvasItemTextureFilter">
+ The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR" value="2" enum="CanvasItemTextureFilter">
+ The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="CanvasItemTextureFilter">
+ The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="4" enum="CanvasItemTextureFilter">
+ The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC" value="5" enum="CanvasItemTextureFilter">
+ The texture filter reads from the nearest pixel, but selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC" value="6" enum="CanvasItemTextureFilter">
+ The texture filter blends between the nearest 4 pixels and selects a mipmap based on the angle between the surface and the camera view. This reduces artifacts on surfaces that are almost in line with the camera. This is the slowest of the filtering options, but results in the highest quality texturing.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_FILTER_MAX" value="7" enum="CanvasItemTextureFilter">
+ Max value for [enum CanvasItemTextureFilter] enum.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT" value="0" enum="CanvasItemTextureRepeat">
+ Uses the default repeat mode for this [Viewport].
</constant>
<constant name="CANVAS_ITEM_TEXTURE_REPEAT_DISABLED" value="1" enum="CanvasItemTextureRepeat">
+ Disables textures repeating. Instead, when reading UVs outside the 0-1 range, the value will be clamped to the edge of the texture, resulting in a stretched out look at the borders of the texture.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_REPEAT_ENABLED" value="2" enum="CanvasItemTextureRepeat">
+ Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_REPEAT_MIRROR" value="3" enum="CanvasItemTextureRepeat">
+ Flip the texture when repeating so that the edge lines up instead of abruptly changing.
</constant>
<constant name="CANVAS_ITEM_TEXTURE_REPEAT_MAX" value="4" enum="CanvasItemTextureRepeat">
+ Max value for [enum CanvasItemTextureRepeat] enum.
</constant>
<constant name="CANVAS_LIGHT_MODE_ADD" value="0" enum="CanvasLightMode">
Adds light color additive to the canvas.
@@ -3676,6 +3706,7 @@
Use PCF13 filtering to filter canvas light shadows.
</constant>
<constant name="CANVAS_LIGHT_FILTER_MAX" value="3" enum="CanvasLightShadowFilter">
+ Max value of the [enum CanvasLightShadowFilter] enum.
</constant>
<constant name="CANVAS_OCCLUDER_POLYGON_CULL_DISABLED" value="0" enum="CanvasOccluderPolygonCullMode">
Culling of the canvas occluder is disabled.
@@ -3686,6 +3717,64 @@
<constant name="CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE" value="2" enum="CanvasOccluderPolygonCullMode">
Culling of the canvas occluder is counterclockwise.
</constant>
+ <constant name="GLOBAL_VAR_TYPE_BOOL" value="0" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_BVEC2" value="1" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_BVEC3" value="2" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_BVEC4" value="3" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_INT" value="4" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_IVEC2" value="5" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_IVEC3" value="6" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_IVEC4" value="7" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_RECT2I" value="8" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_UINT" value="9" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_UVEC2" value="10" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_UVEC3" value="11" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_UVEC4" value="12" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_FLOAT" value="13" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_VEC2" value="14" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_VEC3" value="15" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_VEC4" value="16" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_COLOR" value="17" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_RECT2" value="18" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_MAT2" value="19" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_MAT3" value="20" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_MAT4" value="21" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_TRANSFORM_2D" value="22" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_TRANSFORM" value="23" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_SAMPLER2D" value="24" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_SAMPLER2DARRAY" value="25" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_SAMPLER3D" value="26" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_SAMPLERCUBE" value="27" enum="GlobalVariableType">
+ </constant>
+ <constant name="GLOBAL_VAR_TYPE_MAX" value="28" enum="GlobalVariableType">
+ </constant>
<constant name="INFO_OBJECTS_IN_FRAME" value="0" enum="RenderInfo">
The amount of objects in the frame.
</constant>
diff --git a/doc/classes/ResourceFormatLoader.xml b/doc/classes/ResourceFormatLoader.xml
index 713f2c1726..ad0c438f98 100644
--- a/doc/classes/ResourceFormatLoader.xml
+++ b/doc/classes/ResourceFormatLoader.xml
@@ -6,7 +6,7 @@
<description>
Godot loads resources in the editor or in exported games using ResourceFormatLoaders. They are queried automatically via the [ResourceLoader] singleton, or when a resource with internal dependencies is loaded. Each file type may load as a different resource type, so multiple ResourceFormatLoaders are registered in the engine.
Extending this class allows you to define your own loader. Be sure to respect the documented return types and values. You should give it a global class name with [code]class_name[/code] for it to be registered. Like built-in ResourceFormatLoaders, it will be called automatically when loading resources of its handled type(s). You may also implement a [ResourceFormatSaver].
- [b]Note:[/b] You can also extend [EditorImportPlugin] if the resource type you need exists but Godot is unable to load its format. Choosing one way over another depends if the format is suitable or not for the final exported game. For example, it's better to import [code].png[/code] textures as [code].stex[/code] ([StreamTexture]) first, so they can be loaded with better efficiency on the graphics card.
+ [b]Note:[/b] You can also extend [EditorImportPlugin] if the resource type you need exists but Godot is unable to load its format. Choosing one way over another depends if the format is suitable or not for the final exported game. For example, it's better to import [code].png[/code] textures as [code].stex[/code] ([StreamTexture2D]) first, so they can be loaded with better efficiency on the graphics card.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml
index e746d7fc96..8379fc5b58 100644
--- a/doc/classes/RigidBody2D.xml
+++ b/doc/classes/RigidBody2D.xml
@@ -81,7 +81,7 @@
</description>
</method>
<method name="get_colliding_bodies" qualifiers="const">
- <return type="Array">
+ <return type="Node2D[]">
</return>
<description>
Returns a list of the bodies colliding with this one. Use [member contacts_reported] to set the maximum number reported. You must also set [member contact_monitor] to [code]true[/code].
diff --git a/doc/classes/ScriptEditor.xml b/doc/classes/ScriptEditor.xml
index 10d6e5f578..f0ad781f77 100644
--- a/doc/classes/ScriptEditor.xml
+++ b/doc/classes/ScriptEditor.xml
@@ -4,6 +4,7 @@
Godot editor's script editor.
</brief_description>
<description>
+ [b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_script_editor].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ShaderGlobalsOverride.xml b/doc/classes/ShaderGlobalsOverride.xml
new file mode 100644
index 0000000000..2aa00aa5a9
--- /dev/null
+++ b/doc/classes/ShaderGlobalsOverride.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="ShaderGlobalsOverride" inherits="Node" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml
index 08404fb467..4460b519fc 100644
--- a/doc/classes/Skeleton3D.xml
+++ b/doc/classes/Skeleton3D.xml
@@ -157,7 +157,7 @@
<method name="physical_bones_start_simulation">
<return type="void">
</return>
- <argument index="0" name="bones" type="Array" default="[ ]">
+ <argument index="0" name="bones" type="StringName[]" default="[ ]">
</argument>
<description>
</description>
diff --git a/doc/classes/Sky.xml b/doc/classes/Sky.xml
index f574f42431..78c75d9c2b 100644
--- a/doc/classes/Sky.xml
+++ b/doc/classes/Sky.xml
@@ -49,7 +49,7 @@
Represents the size of the [enum RadianceSize] enum.
</constant>
<constant name="PROCESS_MODE_QUALITY" value="0" enum="ProcessMode">
- Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime.
+ Uses high quality importance sampling to process the radiance map. In general, this results in much higher quality than [constant PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be used if you plan on changing the sky at runtime. If you are finding that the reflection is not blurry enough and is showing sparkles or fireflies, try increasing [member ProjectSettings.rendering/quality/reflections/ggx_samples].
</constant>
<constant name="PROCESS_MODE_REALTIME" value="1" enum="ProcessMode">
Uses the fast filtering algorithm to process the radiance map. In general this results in lower quality, but substantially faster run times.
diff --git a/doc/classes/SpinBox.xml b/doc/classes/SpinBox.xml
index c8ba8ab697..e674ceb57e 100644
--- a/doc/classes/SpinBox.xml
+++ b/doc/classes/SpinBox.xml
@@ -45,7 +45,7 @@
Adds the specified [code]prefix[/code] string before the numerical value of the [SpinBox].
</member>
<member name="suffix" type="String" setter="set_suffix" getter="get_suffix" default="&quot;&quot;">
- Adds the specified [code]prefix[/code] string after the numerical value of the [SpinBox].
+ Adds the specified [code]suffix[/code] string after the numerical value of the [SpinBox].
</member>
</members>
<constants>
diff --git a/doc/classes/Sprite2D.xml b/doc/classes/Sprite2D.xml
index 950fda4e20..92f561d7b5 100644
--- a/doc/classes/Sprite2D.xml
+++ b/doc/classes/Sprite2D.xml
@@ -54,6 +54,7 @@
</member>
<member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map">
The normal map gives depth to the Sprite2D.
+ [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )">
The texture's drawing offset.
diff --git a/doc/classes/StreamCubemap.xml b/doc/classes/StreamCubemap.xml
new file mode 100644
index 0000000000..16648266eb
--- /dev/null
+++ b/doc/classes/StreamCubemap.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="StreamCubemap" inherits="StreamTextureLayered" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/StreamCubemapArray.xml b/doc/classes/StreamCubemapArray.xml
new file mode 100644
index 0000000000..b84973fd14
--- /dev/null
+++ b/doc/classes/StreamCubemapArray.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="StreamCubemapArray" inherits="StreamTextureLayered" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/StreamTexture.xml b/doc/classes/StreamTexture2D.xml
index 03afcb5b0d..214298475c 100644
--- a/doc/classes/StreamTexture.xml
+++ b/doc/classes/StreamTexture2D.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="StreamTexture" inherits="Texture2D" version="4.0">
+<class name="StreamTexture2D" inherits="Texture2D" version="4.0">
<brief_description>
A [code].stex[/code] texture.
</brief_description>
diff --git a/doc/classes/StreamTexture2DArray.xml b/doc/classes/StreamTexture2DArray.xml
new file mode 100644
index 0000000000..ec545b24d0
--- /dev/null
+++ b/doc/classes/StreamTexture2DArray.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="StreamTexture2DArray" inherits="StreamTextureLayered" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/StreamTextureLayered.xml b/doc/classes/StreamTextureLayered.xml
new file mode 100644
index 0000000000..10a7aae976
--- /dev/null
+++ b/doc/classes/StreamTextureLayered.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="StreamTextureLayered" inherits="TextureLayered" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ <method name="load">
+ <return type="int" enum="Error">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="load_path" type="String" setter="load" getter="get_load_path" default="&quot;&quot;">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index a72b8f05d8..0dd6923129 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -620,6 +620,19 @@
Returns [code]true[/code] if this string contains a valid IP address.
</description>
</method>
+ <method name="join">
+ <return type="String">
+ </return>
+ <argument index="0" name="parts" type="PackedStringArray">
+ </argument>
+ <description>
+ Return a [String] which is the concatenation of the [code]parts[/code]. The separator between elements is the string providing this method.
+ Example:
+ [codeblock]
+ print(", ".join(["One", "Two", "Three", "Four"]))
+ [/codeblock]
+ </description>
+ </method>
<method name="json_escape">
<return type="String">
</return>
diff --git a/doc/classes/StyleBoxTexture.xml b/doc/classes/StyleBoxTexture.xml
index 8ed94c8c26..f8aa14cb2b 100644
--- a/doc/classes/StyleBoxTexture.xml
+++ b/doc/classes/StyleBoxTexture.xml
@@ -121,6 +121,7 @@
</member>
<member name="normal_map" type="Texture2D" setter="set_normal_map" getter="get_normal_map">
The normal map to use when drawing this style box.
+ [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</member>
<member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2( 0, 0, 0, 0 )">
Species a sub-region of the texture to use.
diff --git a/doc/classes/SubViewport.xml b/doc/classes/SubViewport.xml
index e877050bf8..6014762e3d 100644
--- a/doc/classes/SubViewport.xml
+++ b/doc/classes/SubViewport.xml
@@ -9,9 +9,6 @@
<methods>
</methods>
<members>
- <member name="xr" type="bool" setter="set_use_xr" getter="is_using_xr" default="false">
- If [code]true[/code], the sub-viewport will be used in AR/VR process.
- </member>
<member name="render_target_clear_mode" type="int" setter="set_clear_mode" getter="get_clear_mode" enum="SubViewport.ClearMode" default="0">
The clear mode when the sub-viewport is used as a render target.
</member>
@@ -27,8 +24,20 @@
<member name="size_2d_override_stretch" type="bool" setter="set_size_2d_override_stretch" getter="is_size_2d_override_stretch_enabled" default="false">
If [code]true[/code], the 2D size override affects stretch as well.
</member>
+ <member name="xr" type="bool" setter="set_use_xr" getter="is_using_xr" default="false">
+ If [code]true[/code], the sub-viewport will be used in AR/VR process.
+ </member>
</members>
<constants>
+ <constant name="CLEAR_MODE_ALWAYS" value="0" enum="ClearMode">
+ Always clear the render target before drawing.
+ </constant>
+ <constant name="CLEAR_MODE_NEVER" value="1" enum="ClearMode">
+ Never clear the render target.
+ </constant>
+ <constant name="CLEAR_MODE_ONLY_NEXT_FRAME" value="2" enum="ClearMode">
+ Clear the render target next frame, then switch to [constant CLEAR_MODE_NEVER].
+ </constant>
<constant name="UPDATE_DISABLED" value="0" enum="UpdateMode">
Do not update the render target.
</constant>
@@ -44,14 +53,5 @@
<constant name="UPDATE_ALWAYS" value="4" enum="UpdateMode">
Always update the render target.
</constant>
- <constant name="CLEAR_MODE_ALWAYS" value="0" enum="ClearMode">
- Always clear the render target before drawing.
- </constant>
- <constant name="CLEAR_MODE_NEVER" value="1" enum="ClearMode">
- Never clear the render target.
- </constant>
- <constant name="CLEAR_MODE_ONLY_NEXT_FRAME" value="2" enum="ClearMode">
- Clear the render target next frame, then switch to [constant CLEAR_MODE_NEVER].
- </constant>
</constants>
</class>
diff --git a/doc/classes/SurfaceTool.xml b/doc/classes/SurfaceTool.xml
index 4304a8df5e..eeb6b6cd9d 100644
--- a/doc/classes/SurfaceTool.xml
+++ b/doc/classes/SurfaceTool.xml
@@ -15,6 +15,8 @@
The above [SurfaceTool] now contains one vertex of a triangle which has a UV coordinate and a specified [Color]. If another vertex were added without calling [method add_uv] or [method add_color], then the last values would be used.
Vertex attributes must be passed [b]before[/b] calling [method add_vertex]. Failure to do so will result in an error when committing the vertex information to a mesh.
Additionally, the attributes used before the first vertex is added determine the format of the mesh. For example, if you only add UVs to the first vertex, you cannot add color to any of the subsequent vertices.
+ See also [ArrayMesh], [ImmediateGeometry3D] and [MeshDataTool] for procedural geometry generation.
+ [b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml
index 22e92ae5d9..d56781105b 100644
--- a/doc/classes/TabContainer.xml
+++ b/doc/classes/TabContainer.xml
@@ -204,8 +204,8 @@
<theme_item name="font_color_fg" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )">
Font color of the currently selected tab.
</theme_item>
- <theme_item name="hseparation" type="int" default="4">
- Horizontal separation between tabs.
+ <theme_item name="icon_separation" type="int" default="4">
+ Space between tab's name and its icon.
</theme_item>
<theme_item name="increment" type="Texture2D">
Icon for the right arrow button that appears when there are too many tabs to fit in the container width. When the button is disabled (i.e. the last tab is visible) it appears semi-transparent.
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index b515b27b31..0c6615c53b 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -299,7 +299,7 @@
</description>
</method>
<method name="search" qualifiers="const">
- <return type="PackedInt32Array">
+ <return type="Dictionary">
</return>
<argument index="0" name="key" type="String">
</argument>
@@ -311,13 +311,13 @@
</argument>
<description>
Perform a search inside the text. Search flags can be specified in the [enum SearchFlags] enum.
- Returns an empty [code]PackedInt32Array[/code] if no result was found. Otherwise, the result line and column can be accessed at indices specified in the [enum SearchResult] enum, e.g:
+ Returns an empty [code]Dictionary[/code] if no result was found. Otherwise, returns a [code]Dictionary[/code] containing [code]line[/code] and [code]column[/code] entries, e.g:
[codeblock]
var result = search(key, flags, line, column)
- if result.size() &gt; 0:
+ if !result.empty():
# Result found.
- var res_line = result[TextEdit.SEARCH_RESULT_LINE]
- var res_column = result[TextEdit.SEARCH_RESULT_COLUMN]
+ var line_number = result.line
+ var column_number = result.column
[/codeblock]
</description>
</method>
@@ -343,6 +343,17 @@
Select all the text.
</description>
</method>
+ <method name="set_line">
+ <return type="void">
+ </return>
+ <argument index="0" name="line" type="int">
+ </argument>
+ <argument index="1" name="new_text" type="String">
+ </argument>
+ <description>
+ Sets the text for a specific line.
+ </description>
+ </method>
<method name="set_line_as_hidden">
<return type="void">
</return>
@@ -433,6 +444,7 @@
</member>
<member name="mouse_default_cursor_shape" type="int" setter="set_default_cursor_shape" getter="get_default_cursor_shape" override="true" enum="Control.CursorShape" default="1" />
<member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color" default="false">
+ If [code]true[/code], custom [code]font_color_selected[/code] will be used for selected text.
</member>
<member name="readonly" type="bool" setter="set_readonly" getter="is_readonly" default="false">
If [code]true[/code], read-only mode is enabled. Existing text cannot be modified and new text cannot be added.
@@ -524,12 +536,6 @@
<constant name="SEARCH_BACKWARDS" value="4" enum="SearchFlags">
Search from end to beginning.
</constant>
- <constant name="SEARCH_RESULT_COLUMN" value="0" enum="SearchResult">
- Used to access the result column from [method search].
- </constant>
- <constant name="SEARCH_RESULT_LINE" value="1" enum="SearchResult">
- Used to access the result line from [method search].
- </constant>
<constant name="MENU_CUT" value="0" enum="MenuItems">
Cuts (copies and clears) the selected text.
</constant>
@@ -611,6 +617,7 @@
<theme_item name="font_color_readonly" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )">
</theme_item>
<theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )">
+ Sets the [Color] of the selected text. [member override_selected_font_color] has to be enabled.
</theme_item>
<theme_item name="function_color" type="Color" default="Color( 0.4, 0.64, 0.81, 1 )">
</theme_item>
diff --git a/doc/classes/Texture2DArray.xml b/doc/classes/Texture2DArray.xml
index 657506120e..bb9283803d 100644
--- a/doc/classes/Texture2DArray.xml
+++ b/doc/classes/Texture2DArray.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="Texture2DArray" inherits="TextureLayered" version="4.0">
+<class name="Texture2DArray" inherits="ImageTextureLayered" version="4.0">
<brief_description>
</brief_description>
<description>
diff --git a/doc/classes/TextureLayered.xml b/doc/classes/TextureLayered.xml
index 66e5b69ab4..d81c3c7c5a 100644
--- a/doc/classes/TextureLayered.xml
+++ b/doc/classes/TextureLayered.xml
@@ -9,14 +9,6 @@
<tutorials>
</tutorials>
<methods>
- <method name="create_from_images">
- <return type="int" enum="Error">
- </return>
- <argument index="0" name="images" type="Array">
- </argument>
- <description>
- </description>
- </method>
<method name="get_format" qualifiers="const">
<return type="int" enum="Image.Format">
</return>
@@ -40,6 +32,12 @@
Returns an [Image] resource with the data from specified [code]layer[/code].
</description>
</method>
+ <method name="get_layered_type" qualifiers="const">
+ <return type="int" enum="TextureLayered.LayeredType">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_layers" qualifiers="const">
<return type="int">
</return>
@@ -53,17 +51,19 @@
Returns the width of the texture. Width is typically represented by the X-axis.
</description>
</method>
- <method name="update_layer">
- <return type="void">
+ <method name="has_mipmaps" qualifiers="const">
+ <return type="bool">
</return>
- <argument index="0" name="image" type="Image">
- </argument>
- <argument index="1" name="layer" type="int">
- </argument>
<description>
</description>
</method>
</methods>
<constants>
+ <constant name="LAYERED_TYPE_2D_ARRAY" value="0" enum="LayeredType">
+ </constant>
+ <constant name="LAYERED_TYPE_CUBEMAP" value="1" enum="LayeredType">
+ </constant>
+ <constant name="LAYERED_TYPE_CUBEMAP_ARRAY" value="2" enum="LayeredType">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index 5b7694b775..9df2b656f4 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -74,19 +74,19 @@
</description>
</method>
<method name="get_used_cells" qualifiers="const">
- <return type="Array">
+ <return type="Vector2i[]">
</return>
<description>
Returns a [Vector2] array with the positions of all cells containing a tile from the tileset (i.e. a tile index different from [code]-1[/code]).
</description>
</method>
- <method name="get_used_cells_by_id" qualifiers="const">
- <return type="Array">
+ <method name="get_used_cells_by_index" qualifiers="const">
+ <return type="Vector2i[]">
</return>
- <argument index="0" name="id" type="int">
+ <argument index="0" name="index" type="int">
</argument>
<description>
- Returns an array of all cells with the given tile [code]id[/code].
+ Returns an array of all cells with the given tile [code]index[/code].
</description>
</method>
<method name="get_used_rect">
@@ -273,7 +273,7 @@
<member name="cell_tile_origin" type="int" setter="set_tile_origin" getter="get_tile_origin" enum="TileMap.TileOrigin" default="0">
Position for tile origin. See [enum TileOrigin] for possible values.
</member>
- <member name="cell_y_sort" type="bool" setter="set_y_sort_mode" getter="is_y_sort_mode_enabled" default="false">
+ <member name="cell_y_sort" type="bool" setter="set_y_sort_enabled" getter="is_y_sort_enabled" default="false">
If [code]true[/code], the TileMap's children will be drawn in order of their Y coordinate.
</member>
<member name="centered_textures" type="bool" setter="set_centered_textures" getter="is_centered_textures_enabled" default="false">
diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml
index 65988ae2b7..c647f83598 100644
--- a/doc/classes/TileSet.xml
+++ b/doc/classes/TileSet.xml
@@ -590,6 +590,7 @@
</argument>
<description>
Sets the tile's normal map texture.
+ [b]Note:[/b] Godot expects the normal map to use X+, Y-, and Z+ coordinates. See [url=http://wiki.polycount.com/wiki/Normal_Map_Technical_Details#Common_Swizzle_Coordinates]this page[/url] for a comparison of normal map coordinates expected by popular engines.
</description>
</method>
<method name="tile_set_occluder_offset">
diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml
index e4d367c344..4175f01eb4 100644
--- a/doc/classes/Transform.xml
+++ b/doc/classes/Transform.xml
@@ -135,7 +135,7 @@
<argument index="0" name="scale" type="Vector3">
</argument>
<description>
- Scales the transform by the given scale factor, using matrix multiplication.
+ Scales basis and origin of the transform by the given scale factor, using matrix multiplication.
</description>
</method>
<method name="translated">
diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index b01ba3850f..0b2fb80480 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -16,7 +16,7 @@
var subchild1 = tree.create_item(child1)
subchild1.set_text(0, "Subchild1")
[/codeblock]
- To iterate over all the [TreeItem] objects in a [Tree] object, use [method TreeItem.get_next] and [method TreeItem.get_children] after getting the root through [method get_root].
+ To iterate over all the [TreeItem] objects in a [Tree] object, use [method TreeItem.get_next] and [method TreeItem.get_children] after getting the root through [method get_root]. You can use [method Object.free] on a [TreeItem] to remove it from the [Tree].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index 84aa3a3686..126d6b4180 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -5,6 +5,7 @@
</brief_description>
<description>
Control for a single item inside a [Tree]. May have child [TreeItem]s and be styled as well as contain buttons.
+ You can remove a [TreeItem] by using [method Object.free].
</description>
<tutorials>
</tutorials>
@@ -248,6 +249,14 @@
<description>
</description>
</method>
+ <method name="get_suffix" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="column" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_text" qualifiers="const">
<return type="String">
</return>
@@ -350,7 +359,7 @@
<argument index="0" name="child" type="Object">
</argument>
<description>
- Removes the given child TreeItem.
+ Removes the given child [TreeItem] and all its children from the [Tree]. Note that it doesn't free the item from memory, so it can be reused later. To completely remove a [TreeItem] use [method Object.free].
</description>
</method>
<method name="select">
@@ -571,6 +580,16 @@
If [code]true[/code], the given column is selectable.
</description>
</method>
+ <method name="set_suffix">
+ <return type="void">
+ </return>
+ <argument index="0" name="column" type="int">
+ </argument>
+ <argument index="1" name="text" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_text">
<return type="void">
</return>
diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml
index 371b027534..1938a3facb 100644
--- a/doc/classes/Tween.xml
+++ b/doc/classes/Tween.xml
@@ -6,7 +6,7 @@
<description>
Tweens are useful for animations requiring a numerical property to be interpolated over a range of values. The name [i]tween[/i] comes from [i]in-betweening[/i], an animation technique where you specify [i]keyframes[/i] and the computer interpolates the frames that appear between them.
[Tween] is more suited than [AnimationPlayer] for animations where you don't know the final values in advance. For example, interpolating a dynamically-chosen camera zoom value is best done with a [Tween] node; it would be difficult to do the same thing with an [AnimationPlayer] node.
- Here is a brief usage example that causes a 2D node to move smoothly between two positions:
+ Here is a brief usage example that makes a 2D node move smoothly between two positions:
[codeblock]
var tween = get_node("Tween")
tween.interpolate_property($Node2D, "position",
@@ -15,7 +15,8 @@
tween.start()
[/codeblock]
Many methods require a property name, such as [code]"position"[/code] above. You can find the correct property name by hovering over the property in the Inspector. You can also provide the components of a property directly by using [code]"property:component"[/code] (eg. [code]position:x[/code]), where it would only apply to that particular component.
- Many of the methods accept [code]trans_type[/code] and [code]ease_type[/code]. The first accepts an [enum TransitionType] constant, and refers to the way the timing of the animation is handled (see [code]http://easings.net/[/code] for some examples). The second accepts an [enum EaseType] constant, and controls the where [code]trans_type[/code] is applied to the interpolation (in the beginning, the end, or both). If you don't know which transition and easing to pick, you can try different [enum TransitionType] constants with [constant EASE_IN_OUT], and use the one that looks best.
+ Many of the methods accept [code]trans_type[/code] and [code]ease_type[/code]. The first accepts an [enum TransitionType] constant, and refers to the way the timing of the animation is handled (see [url=https://easings.net/]easings.net[/url] for some examples). The second accepts an [enum EaseType] constant, and controls the where [code]trans_type[/code] is applied to the interpolation (in the beginning, the end, or both). If you don't know which transition and easing to pick, you can try different [enum TransitionType] constants with [constant EASE_IN_OUT], and use the one that looks best.
+ [url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VSlider.xml b/doc/classes/VSlider.xml
index 3faafdfe80..9394d6b430 100644
--- a/doc/classes/VSlider.xml
+++ b/doc/classes/VSlider.xml
@@ -23,6 +23,8 @@
<theme_item name="grabber_area" type="StyleBox">
The background of the area below the grabber.
</theme_item>
+ <theme_item name="grabber_area_highlight" type="StyleBox">
+ </theme_item>
<theme_item name="grabber_disabled" type="Texture2D">
The texture for the grabber when it's disabled.
</theme_item>
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 7b02a1a4c9..64ebc1fa09 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -193,7 +193,7 @@
Returns the vector's length squared. Prefer this method over [method length] if you need to sort vectors or need the squared length for some formula.
</description>
</method>
- <method name="linear_interpolate">
+ <method name="lerp">
<return type="Vector2">
</return>
<argument index="0" name="b" type="Vector2">
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index 600c03ba7d..29222bb4d1 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -169,7 +169,7 @@
Returns the vector's length squared. Prefer this function over [method length] if you need to sort vectors or need the squared length for some formula.
</description>
</method>
- <method name="linear_interpolate">
+ <method name="lerp">
<return type="Vector3">
</return>
<argument index="0" name="b" type="Vector3">
@@ -309,7 +309,7 @@
<argument index="0" name="by" type="Vector3">
</argument>
<description>
- Returns a copy of the vector snapped to the lowest neared multiple.
+ Returns the vector snapped to a grid with the given size.
</description>
</method>
<method name="to_diagonal_matrix">
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 5826822c6e..3b52c80c9a 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -16,18 +16,18 @@
<link>https://docs.godotengine.org/en/latest/tutorials/viewports/index.html</link>
</tutorials>
<methods>
- <method name="find_world" qualifiers="const">
- <return type="World3D">
+ <method name="find_world_2d" qualifiers="const">
+ <return type="World2D">
</return>
<description>
- Returns the 3D world of the viewport, or if none the world of the parent viewport.
+ Returns the 2D world of the viewport.
</description>
</method>
- <method name="find_world_2d" qualifiers="const">
- <return type="World2D">
+ <method name="find_world_3d" qualifiers="const">
+ <return type="World3D">
</return>
<description>
- Returns the 2D world of the viewport.
+ Returns the 3D world of the viewport, or if none the world of the parent viewport.
</description>
</method>
<method name="get_camera" qualifiers="const">
@@ -192,8 +192,10 @@
If [code]true[/code], the viewport will process 3D audio streams.
</member>
<member name="canvas_item_default_texture_filter" type="int" setter="set_default_canvas_item_texture_filter" getter="get_default_canvas_item_texture_filter" enum="Viewport.DefaultCanvasItemTextureFilter" default="1">
+ Sets the default filter mode used by [CanvasItem]s in this Viewport. See [enum DefaultCanvasItemTextureFilter] for options.
</member>
<member name="canvas_item_default_texture_repeat" type="int" setter="set_default_canvas_item_texture_repeat" getter="get_default_canvas_item_texture_repeat" enum="Viewport.DefaultCanvasItemTextureRepeat" default="0">
+ Sets the default repeat mode used by [CanvasItem]s in this Viewport. See [enum DefaultCanvasItemTextureRepeat] for options.
</member>
<member name="canvas_transform" type="Transform2D" setter="set_canvas_transform" getter="get_canvas_transform">
The canvas transform of the viewport, useful for changing the on-screen positions of all child [CanvasItem]s. This is relative to the global canvas transform of the viewport.
@@ -217,12 +219,15 @@
<member name="msaa" type="int" setter="set_msaa" getter="get_msaa" enum="Viewport.MSAA" default="0">
The multisample anti-aliasing mode. A higher number results in smoother edges at the cost of significantly worse performance. A value of 4 is best unless targeting very high-end systems.
</member>
- <member name="own_world" type="bool" setter="set_use_own_world" getter="is_using_own_world" default="false">
- If [code]true[/code], the viewport will use [World3D] defined in [code]world[/code] property.
+ <member name="own_world_3d" type="bool" setter="set_use_own_world_3d" getter="is_using_own_world_3d" default="false">
+ If [code]true[/code], the viewport will use the [World3D] defined in [member world_3d].
</member>
<member name="physics_object_picking" type="bool" setter="set_physics_object_picking" getter="get_physics_object_picking" default="false">
If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process.
</member>
+ <member name="screen_space_aa" type="int" setter="set_screen_space_aa" getter="get_screen_space_aa" enum="Viewport.ScreenSpaceAA" default="0">
+ Sets the screen-space antialiasing method used. Screen-space antialiasing works by selectively blurring edges in a post-process shader. It differs from MSAA which takes multiple coverage samples while rendering objects. Screen-space AA methods are typically faster than MSAA and will smooth out specular aliasing, but tend to make scenes appear blurry.
+ </member>
<member name="shadow_atlas_quad_0" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv" default="2">
The subdivision amount of the first quadrant on the shadow atlas.
</member>
@@ -242,12 +247,12 @@
<member name="transparent_bg" type="bool" setter="set_transparent_background" getter="has_transparent_background" default="false">
If [code]true[/code], the viewport should render its background as transparent.
</member>
- <member name="world" type="World3D" setter="set_world" getter="get_world">
- The custom [World3D] which can be used as 3D environment source.
- </member>
<member name="world_2d" type="World2D" setter="set_world_2d" getter="get_world_2d">
The custom [World2D] which can be used as 2D environment source.
</member>
+ <member name="world_3d" type="World3D" setter="set_world_3d" getter="get_world_3d">
+ The custom [World3D] which can be used as 3D environment source.
+ </member>
</members>
<signals>
<signal name="gui_focus_changed">
@@ -288,6 +293,33 @@
<constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_MAX" value="7" enum="ShadowAtlasQuadrantSubdiv">
Represents the size of the [enum ShadowAtlasQuadrantSubdiv] enum.
</constant>
+ <constant name="MSAA_DISABLED" value="0" enum="MSAA">
+ Multisample antialiasing mode disabled. This is the default value, and also the fastest setting.
+ </constant>
+ <constant name="MSAA_2X" value="1" enum="MSAA">
+ Use 2x Multisample Antialiasing.
+ </constant>
+ <constant name="MSAA_4X" value="2" enum="MSAA">
+ Use 4x Multisample Antialiasing.
+ </constant>
+ <constant name="MSAA_8X" value="3" enum="MSAA">
+ Use 8x Multisample Antialiasing. Likely unsupported on low-end and older hardware.
+ </constant>
+ <constant name="MSAA_16X" value="4" enum="MSAA">
+ Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end hardware.
+ </constant>
+ <constant name="MSAA_MAX" value="5" enum="MSAA">
+ Represents the size of the [enum MSAA] enum.
+ </constant>
+ <constant name="SCREEN_SPACE_AA_DISABLED" value="0" enum="ScreenSpaceAA">
+ Do not perform any antialiasing in the full screen post-process.
+ </constant>
+ <constant name="SCREEN_SPACE_AA_FXAA" value="1" enum="ScreenSpaceAA">
+ Use fast approximate antialiasing. FXAA is a popular screen-space antialising method, which is fast but will make the image look blurry, especially at lower resolutions. It can still work relatively well at large resolutions such as 1440p and 4K.
+ </constant>
+ <constant name="SCREEN_SPACE_AA_MAX" value="2" enum="ScreenSpaceAA">
+ Represents the size of the [enum ScreenSpaceAA] enum.
+ </constant>
<constant name="RENDER_INFO_OBJECTS_IN_FRAME" value="0" enum="RenderInfo">
Amount of objects in frame.
</constant>
@@ -315,58 +347,71 @@
<constant name="DEBUG_DRAW_UNSHADED" value="1" enum="DebugDraw">
Objects are displayed without light information.
</constant>
+ <constant name="DEBUG_DRAW_LIGHTING" value="2" enum="DebugDraw">
+ </constant>
<constant name="DEBUG_DRAW_OVERDRAW" value="3" enum="DebugDraw">
- Objected are displayed semi-transparent with additive blending so you can see where they intersect.
+ Objects are displayed semi-transparent with additive blending so you can see where they are drawing over top of one another. A higher overdraw means you are wasting performance on drawing pixels that are being hidden behind others.
</constant>
<constant name="DEBUG_DRAW_WIREFRAME" value="4" enum="DebugDraw">
Objects are displayed in wireframe style.
</constant>
+ <constant name="DEBUG_DRAW_NORMAL_BUFFER" value="5" enum="DebugDraw">
+ </constant>
<constant name="DEBUG_DRAW_GI_PROBE_ALBEDO" value="6" enum="DebugDraw">
+ Objects are displayed with only the albedo value from [GIProbe]s.
</constant>
<constant name="DEBUG_DRAW_GI_PROBE_LIGHTING" value="7" enum="DebugDraw">
+ Objects are displayed with only the lighting value from [GIProbe]s.
</constant>
<constant name="DEBUG_DRAW_GI_PROBE_EMISSION" value="8" enum="DebugDraw">
+ Objects are displayed with only the emission color from [GIProbe]s.
</constant>
<constant name="DEBUG_DRAW_SHADOW_ATLAS" value="9" enum="DebugDraw">
+ Draws the shadow atlas that stores shadows from [OmniLight3D]s and [SpotLight3D]s in the upper left quadrant of the [Viewport].
</constant>
<constant name="DEBUG_DRAW_DIRECTIONAL_SHADOW_ATLAS" value="10" enum="DebugDraw">
+ Draws the shadow atlas that stores shadows from [DirectionalLight3D]s in the upper left quadrant of the [Viewport].
</constant>
<constant name="DEBUG_DRAW_SCENE_LUMINANCE" value="11" enum="DebugDraw">
</constant>
<constant name="DEBUG_DRAW_SSAO" value="12" enum="DebugDraw">
+ Draws the screen-space ambient occlusion texture instead of the scene so that you can clearly see how it is affecting objects. In order for this display mode to work, you must have [member Environment.ssao_enabled] set in your [WorldEnvironment].
</constant>
- <constant name="MSAA_DISABLED" value="0" enum="MSAA">
- Multisample anti-aliasing mode disabled. This is the default value.
- </constant>
- <constant name="MSAA_2X" value="1" enum="MSAA">
- Use 2x Multisample Antialiasing.
+ <constant name="DEBUG_DRAW_ROUGHNESS_LIMITER" value="13" enum="DebugDraw">
+ Draws the roughness limiter post process over the Viewport so you can see where it has an effect. It must be enabled in [member ProjectSettings.rendering/quality/screen_filters/screen_space_roughness_limiter] to work.
</constant>
- <constant name="MSAA_4X" value="2" enum="MSAA">
- Use 4x Multisample Antialiasing.
+ <constant name="DEBUG_DRAW_PSSM_SPLITS" value="14" enum="DebugDraw">
+ Colors each PSSM split for the [DirectionalLight3D]s in the scene a different color so you can see where the splits are. In order, they will be colored red, green, blue, and yellow.
</constant>
- <constant name="MSAA_8X" value="3" enum="MSAA">
- Use 8x Multisample Antialiasing. Likely unsupported on low-end and older hardware.
- </constant>
- <constant name="MSAA_16X" value="4" enum="MSAA">
- Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end hardware.
+ <constant name="DEBUG_DRAW_DECAL_ATLAS" value="15" enum="DebugDraw">
+ Draws the decal atlas used by [Decal]s and light projector textures in the upper left quadrant of the [Viewport].
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST" value="0" enum="DefaultCanvasItemTextureFilter">
+ The texture filter reads from the nearest pixel only. The simplest and fastest method of filtering, but the texture will look pixelized.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR" value="1" enum="DefaultCanvasItemTextureFilter">
+ The texture filter blends between the nearest 4 pixels. Use this when you want to avoid a pixelated style, but do not want mipmaps.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS" value="2" enum="DefaultCanvasItemTextureFilter">
+ The texture filter reads from the nearest pixel in the nearest mipmap. The fastest way to read from textures with mipmaps.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS" value="3" enum="DefaultCanvasItemTextureFilter">
+ The texture filter blends between the nearest 4 pixels and between the nearest 2 mipmaps.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX" value="4" enum="DefaultCanvasItemTextureFilter">
+ Max value for [enum DefaultCanvasItemTextureFilter] enum.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED" value="0" enum="DefaultCanvasItemTextureRepeat">
+ Disables textures repeating. Instead, when reading UVs outside the 0-1 range, the value will be clamped to the edge of the texture, resulting in a stretched out look at the borders of the texture.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED" value="1" enum="DefaultCanvasItemTextureRepeat">
+ Enables the texture to repeat when UV coordinates are outside the 0-1 range. If using one of the linear filtering modes, this can result in artifacts at the edges of a texture when the sampler filters across the edges of the texture.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR" value="2" enum="DefaultCanvasItemTextureRepeat">
+ Flip the texture when repeating so that the edge lines up instead of abruptly changing.
</constant>
<constant name="DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MAX" value="3" enum="DefaultCanvasItemTextureRepeat">
+ Max value for [enum DefaultCanvasItemTextureRepeat] enum.
</constant>
</constants>
</class>
diff --git a/doc/classes/VisibilityEnabler2D.xml b/doc/classes/VisibilityEnabler2D.xml
index 0bdecafbfa..a5abf16a8d 100644
--- a/doc/classes/VisibilityEnabler2D.xml
+++ b/doc/classes/VisibilityEnabler2D.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisibilityEnabler2D" inherits="VisibilityNotifier2D" version="4.0">
<brief_description>
- Enables certain nodes only when visible.
+ Enables certain nodes only when approximately visible.
</brief_description>
<description>
The VisibilityEnabler2D will disable [RigidBody2D], [AnimationPlayer], and other nodes when they are not visible. It will only affect nodes with the same root node as the VisibilityEnabler2D, and the root node itself.
- Note that VisibilityEnabler2D will not affect nodes added after scene initialization.
+ [b]Note:[/b] For performance reasons, VisibilityEnabler2D uses an approximate heuristic with precision determined by [member ProjectSettings.world/2d/cell_size]. If you need exact visibility checking, use another method such as adding an [Area2D] node as a child of a [Camera2D] node.
+ [b]Note:[/b] VisibilityEnabler2D will not affect nodes added after scene initialization.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisibilityEnabler3D.xml b/doc/classes/VisibilityEnabler3D.xml
index 9c25c6c7c8..342a37e7a4 100644
--- a/doc/classes/VisibilityEnabler3D.xml
+++ b/doc/classes/VisibilityEnabler3D.xml
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisibilityEnabler3D" inherits="VisibilityNotifier3D" version="4.0">
<brief_description>
- Enables certain nodes only when visible.
+ Enables certain nodes only when approximately visible.
</brief_description>
<description>
The VisibilityEnabler3D will disable [RigidBody3D] and [AnimationPlayer] nodes when they are not visible. It will only affect other nodes within the same scene as the VisibilityEnabler3D itself.
- Note that VisibilityEnabler3D will not affect nodes added after scene initialization.
+ [b]Note:[/b] VisibilityEnabler3D uses an approximate heuristic for performance reasons. It doesn't take walls and other occlusion into account. If you need exact visibility checking, use another method such as adding an [Area3D] node as a child of a [Camera3D] node.
+ [b]Note:[/b] VisibilityEnabler3D will not affect nodes added after scene initialization.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisibilityNotifier2D.xml b/doc/classes/VisibilityNotifier2D.xml
index f2a4a59d77..391163ef94 100644
--- a/doc/classes/VisibilityNotifier2D.xml
+++ b/doc/classes/VisibilityNotifier2D.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisibilityNotifier2D" inherits="Node2D" version="4.0">
<brief_description>
- Detects when the node is visible on screen.
+ Detects approximately when the node is visible on screen.
</brief_description>
<description>
The VisibilityNotifier2D detects when it is visible on the screen. It also notifies when its bounding rectangle enters or exits the screen or a viewport.
+ [b]Note:[/b] For performance reasons, VisibilityNotifier2D uses an approximate heuristic with precision determined by [member ProjectSettings.world/2d/cell_size]. If you need exact visibility checking, use another method such as adding an [Area2D] node as a child of a [Camera2D] node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisibilityNotifier3D.xml b/doc/classes/VisibilityNotifier3D.xml
index d8a605c69c..eb7bb91f26 100644
--- a/doc/classes/VisibilityNotifier3D.xml
+++ b/doc/classes/VisibilityNotifier3D.xml
@@ -1,10 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisibilityNotifier3D" inherits="Node3D" version="4.0">
<brief_description>
- Detects when the node is visible on screen.
+ Detects approximately when the node is visible on screen.
</brief_description>
<description>
The VisibilityNotifier3D detects when it is visible on the screen. It also notifies when its bounding rectangle enters or exits the screen or a [Camera3D]'s view.
+ [b]Note:[/b] VisibilityNotifier3D uses an approximate heuristic for performance reasons. It doesn't take walls and other occlusion into account. If you need exact visibility checking, use another method such as adding an [Area3D] node as a child of a [Camera3D] node.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeInput.xml b/doc/classes/VisualShaderNodeInput.xml
index ed629508d0..9261d0088d 100644
--- a/doc/classes/VisualShaderNodeInput.xml
+++ b/doc/classes/VisualShaderNodeInput.xml
@@ -4,8 +4,10 @@
Represents the input shader parameter within the visual shader graph.
</brief_description>
<description>
+ Gives access to input variables (built-ins) available for the shader. See the shading reference for the list of available built-ins for each shader type (check [code]Tutorials[/code] section for link).
</description>
<tutorials>
+ <link>https://docs.godotengine.org/en/stable/tutorials/shading/shading_reference/index.html</link>
</tutorials>
<methods>
<method name="get_input_real_name" qualifiers="const">
@@ -18,7 +20,7 @@
</methods>
<members>
<member name="input_name" type="String" setter="set_input_name" getter="get_input_name" default="&quot;[None]&quot;">
- One of the several input constants in lower-case style like: "vertex"([/code]VERTEX[code]) or "point_size"([code]POINT_SIZE[/code]).
+ One of the several input constants in lower-case style like: "vertex"([code]VERTEX[/code]) or "point_size"([code]POINT_SIZE[/code]).
</member>
</members>
<signals>
diff --git a/doc/classes/VisualShaderNodeIs.xml b/doc/classes/VisualShaderNodeIs.xml
index 184c9e099f..b767a9638e 100644
--- a/doc/classes/VisualShaderNodeIs.xml
+++ b/doc/classes/VisualShaderNodeIs.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeIs" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ A boolean comparison operator to be used within the visual shader graph.
</brief_description>
<description>
+ Returns the boolean result of the comparison between [code]INF[/code] or [code]NaN[/code] and a scalar parameter.
</description>
<tutorials>
</tutorials>
@@ -10,12 +12,15 @@
</methods>
<members>
<member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeIs.Function" default="0">
+ The comparison function. See [enum Function] for options.
</member>
</members>
<constants>
<constant name="FUNC_IS_INF" value="0" enum="Function">
+ Comparison with [code]INF[/code] (Infinity).
</constant>
<constant name="FUNC_IS_NAN" value="1" enum="Function">
+ Comparison with [code]NaN[/code] (Not a Number; denotes invalid numeric results, e.g. division by zero).
</constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeOuterProduct.xml b/doc/classes/VisualShaderNodeOuterProduct.xml
index b8d4fd687f..ba6822bfce 100644
--- a/doc/classes/VisualShaderNodeOuterProduct.xml
+++ b/doc/classes/VisualShaderNodeOuterProduct.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeOuterProduct" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Calculates an outer product of two vectors within the visual shader graph.
</brief_description>
<description>
+ [code]OuterProduct[/code] treats the first parameter [code]c[/code] as a column vector (matrix with one column) and the second parameter [code]r[/code] as a row vector (matrix with one row) and does a linear algebraic matrix multiply [code]c * r[/code], yielding a matrix whose number of rows is the number of components in [code]c[/code] and whose number of columns is the number of components in [code]r[/code].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeOutput.xml b/doc/classes/VisualShaderNodeOutput.xml
index c63e307bad..2b4aed9ae4 100644
--- a/doc/classes/VisualShaderNodeOutput.xml
+++ b/doc/classes/VisualShaderNodeOutput.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeOutput" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Represents the output shader parameters within the visual shader graph.
</brief_description>
<description>
+ This visual shader node is present in all shader graphs in form of "Output" block with mutliple output value ports.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeScalarClamp.xml b/doc/classes/VisualShaderNodeScalarClamp.xml
index fd963dcb5d..7432e8dfca 100644
--- a/doc/classes/VisualShaderNodeScalarClamp.xml
+++ b/doc/classes/VisualShaderNodeScalarClamp.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeScalarClamp" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Clamps a scalar value within the visual shader graph.
</brief_description>
<description>
+ Constrains a value to lie between [code]min[/code] and [code]max[/code] values.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeScalarDerivativeFunc.xml b/doc/classes/VisualShaderNodeScalarDerivativeFunc.xml
index fa9aa07761..33777c1e49 100644
--- a/doc/classes/VisualShaderNodeScalarDerivativeFunc.xml
+++ b/doc/classes/VisualShaderNodeScalarDerivativeFunc.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeScalarDerivativeFunc" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Calculates a scalar derivative within the visual shader graph.
</brief_description>
<description>
+ This node is only available in [code]Fragment[/code] and [code]Light[/code] visual shaders.
</description>
<tutorials>
</tutorials>
@@ -10,14 +12,18 @@
</methods>
<members>
<member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeScalarDerivativeFunc.Function" default="0">
+ The derivative type. See [enum Function] for options.
</member>
</members>
<constants>
<constant name="FUNC_SUM" value="0" enum="Function">
+ Sum of absolute derivative in [code]x[/code] and [code]y[/code].
</constant>
<constant name="FUNC_X" value="1" enum="Function">
+ Derivative in [code]x[/code] using local differencing.
</constant>
<constant name="FUNC_Y" value="2" enum="Function">
+ Derivative in [code]y[/code] using local differencing.
</constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeScalarInterp.xml b/doc/classes/VisualShaderNodeScalarInterp.xml
index a25ab750cc..393ea70e1a 100644
--- a/doc/classes/VisualShaderNodeScalarInterp.xml
+++ b/doc/classes/VisualShaderNodeScalarInterp.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeScalarInterp" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Linearly interpolates between two scalars within the visual shader graph.
</brief_description>
<description>
+ Translates to [code]mix(a, b, weight)[/code] in the shader language.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeScalarSmoothStep.xml b/doc/classes/VisualShaderNodeScalarSmoothStep.xml
index 1ac16e451f..e619cc8571 100644
--- a/doc/classes/VisualShaderNodeScalarSmoothStep.xml
+++ b/doc/classes/VisualShaderNodeScalarSmoothStep.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeScalarSmoothStep" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Calculates a scalar SmoothStep function within the visual shader graph.
</brief_description>
<description>
+ Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language.
+ Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeScalarSwitch.xml b/doc/classes/VisualShaderNodeScalarSwitch.xml
index 789c8972bb..2ad5202745 100644
--- a/doc/classes/VisualShaderNodeScalarSwitch.xml
+++ b/doc/classes/VisualShaderNodeScalarSwitch.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeScalarSwitch" inherits="VisualShaderNodeSwitch" version="4.0">
<brief_description>
+ A boolean/scalar function for use within the visual shader graph.
</brief_description>
<description>
+ Returns an associated scalar if the provided boolean value is [code]true[/code] or [code]false[/code].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeSwitch.xml b/doc/classes/VisualShaderNodeSwitch.xml
index 5bbb9168a0..9f8a12c0fd 100644
--- a/doc/classes/VisualShaderNodeSwitch.xml
+++ b/doc/classes/VisualShaderNodeSwitch.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeSwitch" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ A boolean/vector function for use within the visual shader graph.
</brief_description>
<description>
+ Returns an associated vector if the provided boolean value is [code]true[/code] or [code]false[/code].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeTexture.xml b/doc/classes/VisualShaderNodeTexture.xml
index a28a7f5c65..8e389e0b40 100644
--- a/doc/classes/VisualShaderNodeTexture.xml
+++ b/doc/classes/VisualShaderNodeTexture.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTexture" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Performs a texture lookup within the visual shader graph.
</brief_description>
<description>
+ Performs a lookup operation on the provided texture, with support for multiple texture sources to choose from.
</description>
<tutorials>
</tutorials>
@@ -10,30 +12,42 @@
</methods>
<members>
<member name="source" type="int" setter="set_source" getter="get_source" enum="VisualShaderNodeTexture.Source" default="0">
+ Determines the source for the lookup. See [enum Source] for options.
</member>
<member name="texture" type="Texture2D" setter="set_texture" getter="get_texture">
+ The source texture, if needed for the selected [member source].
</member>
<member name="texture_type" type="int" setter="set_texture_type" getter="get_texture_type" enum="VisualShaderNodeTexture.TextureType" default="0">
+ Specifies the type of the texture if [member source] is set to [constant SOURCE_TEXTURE]. See [enum TextureType] for options.
</member>
</members>
<constants>
<constant name="SOURCE_TEXTURE" value="0" enum="Source">
+ Use the texture given as an argument for this function.
</constant>
<constant name="SOURCE_SCREEN" value="1" enum="Source">
+ Use the current viewport's texture as the source.
</constant>
<constant name="SOURCE_2D_TEXTURE" value="2" enum="Source">
+ Use the texture from this shader's texture built-in (e.g. a texture of a [Sprite2D]).
</constant>
<constant name="SOURCE_2D_NORMAL" value="3" enum="Source">
+ Use the texture from this shader's normal map built-in.
</constant>
<constant name="SOURCE_DEPTH" value="4" enum="Source">
+ Use the depth texture available for this shader.
</constant>
<constant name="SOURCE_PORT" value="5" enum="Source">
+ Use the texture provided in the input port for this function.
</constant>
<constant name="TYPE_DATA" value="0" enum="TextureType">
+ No hints are added to the uniform declaration.
</constant>
<constant name="TYPE_COLOR" value="1" enum="TextureType">
+ Adds [code]hint_albedo[/code] as hint to the uniform declaration for proper sRGB to linear conversion.
</constant>
<constant name="TYPE_NORMALMAP" value="2" enum="TextureType">
+ Adds [code]hint_normal[/code] as hint to the uniform declaration, which internally converts the texture for proper usage as normal map.
</constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeTextureUniform.xml b/doc/classes/VisualShaderNodeTextureUniform.xml
index 4e2c39a297..107f08ba28 100644
--- a/doc/classes/VisualShaderNodeTextureUniform.xml
+++ b/doc/classes/VisualShaderNodeTextureUniform.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTextureUniform" inherits="VisualShaderNodeUniform" version="4.0">
<brief_description>
+ Performs a uniform texture lookup within the visual shader graph.
</brief_description>
<description>
+ Performs a lookup operation on the texture provided as a uniform for the shader.
</description>
<tutorials>
</tutorials>
@@ -10,22 +12,30 @@
</methods>
<members>
<member name="color_default" type="int" setter="set_color_default" getter="get_color_default" enum="VisualShaderNodeTextureUniform.ColorDefault" default="0">
+ Sets the default color if no texture is assigned to the uniform.
</member>
<member name="texture_type" type="int" setter="set_texture_type" getter="get_texture_type" enum="VisualShaderNodeTextureUniform.TextureType" default="0">
+ Defines the type of data provided by the source texture. See [enum TextureType] for options.
</member>
</members>
<constants>
<constant name="TYPE_DATA" value="0" enum="TextureType">
+ No hints are added to the uniform declaration.
</constant>
<constant name="TYPE_COLOR" value="1" enum="TextureType">
+ Adds [code]hint_albedo[/code] as hint to the uniform declaration for proper sRGB to linear conversion.
</constant>
<constant name="TYPE_NORMALMAP" value="2" enum="TextureType">
+ Adds [code]hint_normal[/code] as hint to the uniform declaration, which internally converts the texture for proper usage as normal map.
</constant>
<constant name="TYPE_ANISO" value="3" enum="TextureType">
+ Adds [code]hint_aniso[/code] as hint to the uniform declaration to use for a flowmap.
</constant>
<constant name="COLOR_DEFAULT_WHITE" value="0" enum="ColorDefault">
+ Defaults to white color.
</constant>
<constant name="COLOR_DEFAULT_BLACK" value="1" enum="ColorDefault">
+ Defaults to black color.
</constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeTextureUniformTriplanar.xml b/doc/classes/VisualShaderNodeTextureUniformTriplanar.xml
index 3d69575444..28504cc7ac 100644
--- a/doc/classes/VisualShaderNodeTextureUniformTriplanar.xml
+++ b/doc/classes/VisualShaderNodeTextureUniformTriplanar.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTextureUniformTriplanar" inherits="VisualShaderNodeTextureUniform" version="4.0">
<brief_description>
+ Performs a uniform texture lookup with triplanar within the visual shader graph.
</brief_description>
<description>
+ Performs a lookup operation on the texture provided as a uniform for the shader, with support for triplanar mapping.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeTransformCompose.xml b/doc/classes/VisualShaderNodeTransformCompose.xml
index 6d9cab7ab0..41762b0099 100644
--- a/doc/classes/VisualShaderNodeTransformCompose.xml
+++ b/doc/classes/VisualShaderNodeTransformCompose.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTransformCompose" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Composes a [Transform] from four [Vector3]s within the visual shader graph.
</brief_description>
<description>
+ Creates a 4x4 transform matrix using four vectors of type [code]vec3[/code]. Each vector is one row in the matrix and the last column is a [code]vec4(0, 0, 0, 1)[/code].
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeTransformConstant.xml b/doc/classes/VisualShaderNodeTransformConstant.xml
index 15422e1728..e5004e5bb6 100644
--- a/doc/classes/VisualShaderNodeTransformConstant.xml
+++ b/doc/classes/VisualShaderNodeTransformConstant.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTransformConstant" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ A [Transform] constant for use within the visual shader graph.
</brief_description>
<description>
+ A constant [Transform], which can be used as an input node.
</description>
<tutorials>
</tutorials>
@@ -10,6 +12,7 @@
</methods>
<members>
<member name="constant" type="Transform" setter="set_constant" getter="get_constant" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )">
+ A [Transform] constant which represents the state of this node.
</member>
</members>
<constants>
diff --git a/doc/classes/VisualShaderNodeTransformDecompose.xml b/doc/classes/VisualShaderNodeTransformDecompose.xml
index 4d3c464781..c8d893db00 100644
--- a/doc/classes/VisualShaderNodeTransformDecompose.xml
+++ b/doc/classes/VisualShaderNodeTransformDecompose.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTransformDecompose" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Decomposes a [Transform] into four [Vector3]s within the visual shader graph.
</brief_description>
<description>
+ Takes a 4x4 transform matrix and decomposes it into four [code]vec3[/code] values, one from each row of the matrix.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeTransformFunc.xml b/doc/classes/VisualShaderNodeTransformFunc.xml
index d2b6fcef2b..d0b5c5129d 100644
--- a/doc/classes/VisualShaderNodeTransformFunc.xml
+++ b/doc/classes/VisualShaderNodeTransformFunc.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTransformFunc" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Computes a [Transform] function within the visual shader graph.
</brief_description>
<description>
+ Computes an inverse or transpose function on the provided [Transform].
</description>
<tutorials>
</tutorials>
@@ -10,12 +12,15 @@
</methods>
<members>
<member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeTransformFunc.Function" default="0">
+ The function to be computed. See [enum Function] for options.
</member>
</members>
<constants>
<constant name="FUNC_INVERSE" value="0" enum="Function">
+ Perform the inverse operation on the [Transform] matrix.
</constant>
<constant name="FUNC_TRANSPOSE" value="1" enum="Function">
+ Perform the transpose operation on the [Transform] matrix.
</constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeTransformMult.xml b/doc/classes/VisualShaderNodeTransformMult.xml
index 5893d1413b..02b6e0cd1c 100644
--- a/doc/classes/VisualShaderNodeTransformMult.xml
+++ b/doc/classes/VisualShaderNodeTransformMult.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTransformMult" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Multiplies [Transform] by [Transform] within the visual shader graph.
</brief_description>
<description>
+ A multiplication operation on two transforms (4x4 matrices), with support for different multiplication operators.
</description>
<tutorials>
</tutorials>
@@ -10,16 +12,21 @@
</methods>
<members>
<member name="operator" type="int" setter="set_operator" getter="get_operator" enum="VisualShaderNodeTransformMult.Operator" default="0">
+ The multiplication type to be performed on the transforms. See [enum Operator] for options.
</member>
</members>
<constants>
<constant name="OP_AxB" value="0" enum="Operator">
+ Multiplies transform [code]a[/code] by the transform [code]b[/code].
</constant>
<constant name="OP_BxA" value="1" enum="Operator">
+ Multiplies transform [code]b[/code] by the transform [code]a[/code].
</constant>
<constant name="OP_AxB_COMP" value="2" enum="Operator">
+ Performs a component-wise multiplication of transform [code]a[/code] by the transform [code]b[/code].
</constant>
<constant name="OP_BxA_COMP" value="3" enum="Operator">
+ Performs a component-wise multiplication of transform [code]b[/code] by the transform [code]a[/code].
</constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeTransformUniform.xml b/doc/classes/VisualShaderNodeTransformUniform.xml
index 7605ef96d5..43696c8226 100644
--- a/doc/classes/VisualShaderNodeTransformUniform.xml
+++ b/doc/classes/VisualShaderNodeTransformUniform.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTransformUniform" inherits="VisualShaderNodeUniform" version="4.0">
<brief_description>
+ A [Transform] uniform for use within the visual shader graph.
</brief_description>
<description>
+ Translated to [code]uniform mat4[/code] in the shader language.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeTransformVecMult.xml b/doc/classes/VisualShaderNodeTransformVecMult.xml
index d53c3c5ae5..3d5f87f727 100644
--- a/doc/classes/VisualShaderNodeTransformVecMult.xml
+++ b/doc/classes/VisualShaderNodeTransformVecMult.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeTransformVecMult" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Multiplies a [Transform] and a [Vector3] within the visual shader graph.
</brief_description>
<description>
+ A multiplication operation on a transform (4x4 matrix) and a vector, with support for different multiplication operators.
</description>
<tutorials>
</tutorials>
@@ -10,16 +12,21 @@
</methods>
<members>
<member name="operator" type="int" setter="set_operator" getter="get_operator" enum="VisualShaderNodeTransformVecMult.Operator" default="0">
+ The multiplication type to be performed. See [enum Operator] for options.
</member>
</members>
<constants>
<constant name="OP_AxB" value="0" enum="Operator">
+ Multiplies transform [code]a[/code] by the vector [code]b[/code].
</constant>
<constant name="OP_BxA" value="1" enum="Operator">
+ Multiplies vector [code]b[/code] by the transform [code]a[/code].
</constant>
<constant name="OP_3x3_AxB" value="2" enum="Operator">
+ Multiplies transform [code]a[/code] by the vector [code]b[/code], skipping the last row and column of the transform.
</constant>
<constant name="OP_3x3_BxA" value="3" enum="Operator">
+ Multiplies vector [code]b[/code] by the transform [code]a[/code], skipping the last row and column of the transform.
</constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeUniform.xml b/doc/classes/VisualShaderNodeUniform.xml
index c4362f6f2a..83261344bd 100644
--- a/doc/classes/VisualShaderNodeUniform.xml
+++ b/doc/classes/VisualShaderNodeUniform.xml
@@ -1,17 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeUniform" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ A base type for the uniforms within the visual shader graph.
</brief_description>
<description>
+ A uniform represents a variable in the shader which is set externally, i.e. from the [ShaderMaterial]. Uniforms are exposed as properties in the [ShaderMaterial] and can be assigned from the inspector or from a script.
</description>
<tutorials>
</tutorials>
<methods>
</methods>
<members>
+ <member name="qualifier" type="int" setter="set_qualifier" getter="get_qualifier" enum="VisualShaderNodeUniform.Qualifier" default="0">
+ </member>
<member name="uniform_name" type="String" setter="set_uniform_name" getter="get_uniform_name" default="&quot;&quot;">
+ Name of the uniform, by which it can be accessed through the [ShaderMaterial] properties.
</member>
</members>
<constants>
+ <constant name="QUAL_NONE" value="0" enum="Qualifier">
+ </constant>
+ <constant name="QUAL_GLOBAL" value="1" enum="Qualifier">
+ </constant>
+ <constant name="QUAL_INSTANCE" value="2" enum="Qualifier">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeVec3Constant.xml b/doc/classes/VisualShaderNodeVec3Constant.xml
index 8532c5476f..4dfc9dc081 100644
--- a/doc/classes/VisualShaderNodeVec3Constant.xml
+++ b/doc/classes/VisualShaderNodeVec3Constant.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVec3Constant" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ A [Vector3] constant to be used within the visual shader graph.
</brief_description>
<description>
+ A constant [Vector3], which can be used as an input node.
</description>
<tutorials>
</tutorials>
@@ -10,6 +12,7 @@
</methods>
<members>
<member name="constant" type="Vector3" setter="set_constant" getter="get_constant" default="Vector3( 0, 0, 0 )">
+ A [Vector3] constant which represents the state of this node.
</member>
</members>
<constants>
diff --git a/doc/classes/VisualShaderNodeVec3Uniform.xml b/doc/classes/VisualShaderNodeVec3Uniform.xml
index f2b4c4778b..c8b44fdc8d 100644
--- a/doc/classes/VisualShaderNodeVec3Uniform.xml
+++ b/doc/classes/VisualShaderNodeVec3Uniform.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVec3Uniform" inherits="VisualShaderNodeUniform" version="4.0">
<brief_description>
+ A [Vector3] uniform to be used within the visual shader graph.
</brief_description>
<description>
+ Translated to [code]uniform vec3[/code] in the shader language.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeVectorClamp.xml b/doc/classes/VisualShaderNodeVectorClamp.xml
index 85c093f84c..567fed8a41 100644
--- a/doc/classes/VisualShaderNodeVectorClamp.xml
+++ b/doc/classes/VisualShaderNodeVectorClamp.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorClamp" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Clamps a vector value within the visual shader graph.
</brief_description>
<description>
+ Constrains a value to lie between [code]min[/code] and [code]max[/code] values. The operation is performed on each component of the vector individually.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeVectorCompose.xml b/doc/classes/VisualShaderNodeVectorCompose.xml
index e5e4924a9e..c9ff3cd38e 100644
--- a/doc/classes/VisualShaderNodeVectorCompose.xml
+++ b/doc/classes/VisualShaderNodeVectorCompose.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorCompose" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Composes a [Vector3] from three scalars within the visual shader graph.
</brief_description>
<description>
+ Creates a [code]vec3[/code] using three scalar values that can be provided from separate inputs.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeVectorDecompose.xml b/doc/classes/VisualShaderNodeVectorDecompose.xml
index 5378f38b6d..95af323c9b 100644
--- a/doc/classes/VisualShaderNodeVectorDecompose.xml
+++ b/doc/classes/VisualShaderNodeVectorDecompose.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorDecompose" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Decomposes a [Vector3] into three scalars within the visual shader graph.
</brief_description>
<description>
+ Takes a [code]vec3[/code] and decomposes it into three scalar values that can be used as separate inputs.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeVectorDerivativeFunc.xml b/doc/classes/VisualShaderNodeVectorDerivativeFunc.xml
index d62512d68b..859c47bc33 100644
--- a/doc/classes/VisualShaderNodeVectorDerivativeFunc.xml
+++ b/doc/classes/VisualShaderNodeVectorDerivativeFunc.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorDerivativeFunc" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Calculates a vector derivative within the visual shader graph.
</brief_description>
<description>
+ This node is only available in [code]Fragment[/code] and [code]Light[/code] visual shaders.
</description>
<tutorials>
</tutorials>
@@ -10,14 +12,18 @@
</methods>
<members>
<member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeVectorDerivativeFunc.Function" default="0">
+ A derivative type. See [enum Function] for options.
</member>
</members>
<constants>
<constant name="FUNC_SUM" value="0" enum="Function">
+ Sum of absolute derivative in [code]x[/code] and [code]y[/code].
</constant>
<constant name="FUNC_X" value="1" enum="Function">
+ Derivative in [code]x[/code] using local differencing.
</constant>
<constant name="FUNC_Y" value="2" enum="Function">
+ Derivative in [code]y[/code] using local differencing.
</constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeVectorDistance.xml b/doc/classes/VisualShaderNodeVectorDistance.xml
index 2e681156a5..2da04b122e 100644
--- a/doc/classes/VisualShaderNodeVectorDistance.xml
+++ b/doc/classes/VisualShaderNodeVectorDistance.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorDistance" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Returns the distance between two points. To be used within the visual shader graph.
</brief_description>
<description>
+ Calculates distance from point represented by vector [code]p0[/code] to vector [code]p1[/code].
+ Translated to [code]distance(p0, p1)[/code] in the shader language.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeVectorFunc.xml b/doc/classes/VisualShaderNodeVectorFunc.xml
index 0b3f317b8b..cbda3dfb46 100644
--- a/doc/classes/VisualShaderNodeVectorFunc.xml
+++ b/doc/classes/VisualShaderNodeVectorFunc.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorFunc" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ A vector function to be used within the visual shader graph.
</brief_description>
<description>
+ A visual shader node able to perform different functions using vectors.
</description>
<tutorials>
</tutorials>
@@ -10,78 +12,114 @@
</methods>
<members>
<member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeVectorFunc.Function" default="0">
+ The function to be performed. See [enum Function] for options.
</member>
</members>
<constants>
<constant name="FUNC_NORMALIZE" value="0" enum="Function">
+ Normalizes the vector so that it has a length of [code]1[/code] but points in the same direction.
</constant>
<constant name="FUNC_SATURATE" value="1" enum="Function">
+ Clamps the value between [code]0.0[/code] and [code]1.0[/code].
</constant>
<constant name="FUNC_NEGATE" value="2" enum="Function">
+ Returns the opposite value of the parameter.
</constant>
<constant name="FUNC_RECIPROCAL" value="3" enum="Function">
+ Returns [code]1/vector[/code].
</constant>
<constant name="FUNC_RGB2HSV" value="4" enum="Function">
+ Converts RGB vector to HSV equivalent.
</constant>
<constant name="FUNC_HSV2RGB" value="5" enum="Function">
+ Converts HSV vector to RGB equivalent.
</constant>
<constant name="FUNC_ABS" value="6" enum="Function">
+ Returns the absolute value of the parameter.
</constant>
<constant name="FUNC_ACOS" value="7" enum="Function">
+ Returns the arc-cosine of the parameter.
</constant>
<constant name="FUNC_ACOSH" value="8" enum="Function">
+ Returns the inverse hyperbolic cosine of the parameter.
</constant>
<constant name="FUNC_ASIN" value="9" enum="Function">
+ Returns the arc-sine of the parameter.
</constant>
<constant name="FUNC_ASINH" value="10" enum="Function">
+ Returns the inverse hyperbolic sine of the parameter.
</constant>
<constant name="FUNC_ATAN" value="11" enum="Function">
+ Returns the arc-tangent of the parameter.
</constant>
<constant name="FUNC_ATANH" value="12" enum="Function">
+ Returns the inverse hyperbolic tangent of the parameter.
</constant>
<constant name="FUNC_CEIL" value="13" enum="Function">
+ Finds the nearest integer that is greater than or equal to the parameter.
</constant>
<constant name="FUNC_COS" value="14" enum="Function">
+ Returns the cosine of the parameter.
</constant>
<constant name="FUNC_COSH" value="15" enum="Function">
+ Returns the hyperbolic cosine of the parameter.
</constant>
<constant name="FUNC_DEGREES" value="16" enum="Function">
+ Converts a quantity in radians to degrees.
</constant>
<constant name="FUNC_EXP" value="17" enum="Function">
+ Base-e Exponential.
</constant>
<constant name="FUNC_EXP2" value="18" enum="Function">
+ Base-2 Exponential.
</constant>
<constant name="FUNC_FLOOR" value="19" enum="Function">
+ Finds the nearest integer less than or equal to the parameter.
</constant>
<constant name="FUNC_FRAC" value="20" enum="Function">
+ Computes the fractional part of the argument.
</constant>
<constant name="FUNC_INVERSE_SQRT" value="21" enum="Function">
+ Returns the inverse of the square root of the parameter.
</constant>
<constant name="FUNC_LOG" value="22" enum="Function">
+ Natural logarithm.
</constant>
<constant name="FUNC_LOG2" value="23" enum="Function">
+ Base-2 logarithm.
</constant>
<constant name="FUNC_RADIANS" value="24" enum="Function">
+ Converts a quantity in degrees to radians.
</constant>
<constant name="FUNC_ROUND" value="25" enum="Function">
+ Finds the nearest integer to the parameter.
</constant>
<constant name="FUNC_ROUNDEVEN" value="26" enum="Function">
+ Finds the nearest even integer to the parameter.
</constant>
<constant name="FUNC_SIGN" value="27" enum="Function">
+ Extracts the sign of the parameter, i.e. returns [code]-1[/code] if the parameter is negative, [code]1[/code] if it's positive and [code]0[/code] otherwise.
</constant>
<constant name="FUNC_SIN" value="28" enum="Function">
+ Returns the sine of the parameter.
</constant>
<constant name="FUNC_SINH" value="29" enum="Function">
+ Returns the hyperbolic sine of the parameter.
</constant>
<constant name="FUNC_SQRT" value="30" enum="Function">
+ Returns the square root of the parameter.
</constant>
<constant name="FUNC_TAN" value="31" enum="Function">
+ Returns the tangent of the parameter.
</constant>
<constant name="FUNC_TANH" value="32" enum="Function">
+ Returns the hyperbolic tangent of the parameter.
</constant>
<constant name="FUNC_TRUNC" value="33" enum="Function">
+ Returns a value equal to the nearest integer to the parameter whose absolute value is not larger than the absolute value of the parameter.
</constant>
<constant name="FUNC_ONEMINUS" value="34" enum="Function">
+ Returns [code]1.0 - vector[/code].
</constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeVectorInterp.xml b/doc/classes/VisualShaderNodeVectorInterp.xml
index 4d6d3ac577..b63d34b742 100644
--- a/doc/classes/VisualShaderNodeVectorInterp.xml
+++ b/doc/classes/VisualShaderNodeVectorInterp.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorInterp" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Linearly interpolates between two vectors within the visual shader graph.
</brief_description>
<description>
+ Translates to [code]mix(a, b, weight)[/code] in the shader language, where [code]weight[/code] is a [Vector3] with weights for each component.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeVectorLen.xml b/doc/classes/VisualShaderNodeVectorLen.xml
index ade575310c..77261d3190 100644
--- a/doc/classes/VisualShaderNodeVectorLen.xml
+++ b/doc/classes/VisualShaderNodeVectorLen.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorLen" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Returns the length of a [Vector3] within the visual shader graph.
</brief_description>
<description>
+ Translated to [code]length(p0)[/code] in the shader language.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeVectorOp.xml b/doc/classes/VisualShaderNodeVectorOp.xml
index 8c391d09a2..d56c012f8f 100644
--- a/doc/classes/VisualShaderNodeVectorOp.xml
+++ b/doc/classes/VisualShaderNodeVectorOp.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorOp" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ A vector operator to be used within the visual shader graph.
</brief_description>
<description>
+ A visual shader node for use of vector operators. Operates on vector [code]a[/code] and vector [code]b[/code].
</description>
<tutorials>
</tutorials>
@@ -10,32 +12,45 @@
</methods>
<members>
<member name="operator" type="int" setter="set_operator" getter="get_operator" enum="VisualShaderNodeVectorOp.Operator" default="0">
+ The operator to be used. See [enum Operator] for options.
</member>
</members>
<constants>
<constant name="OP_ADD" value="0" enum="Operator">
+ Adds two vectors.
</constant>
<constant name="OP_SUB" value="1" enum="Operator">
+ Subtracts a vector from a vector.
</constant>
<constant name="OP_MUL" value="2" enum="Operator">
+ Multiplies two vectors.
</constant>
<constant name="OP_DIV" value="3" enum="Operator">
+ Divides vector by vector.
</constant>
<constant name="OP_MOD" value="4" enum="Operator">
+ Returns the remainder of the two vectors.
</constant>
<constant name="OP_POW" value="5" enum="Operator">
+ Returns the value of the first parameter raised to the power of the second, for each component of the vectors.
</constant>
<constant name="OP_MAX" value="6" enum="Operator">
+ Returns the greater of two values, for each component of the vectors.
</constant>
<constant name="OP_MIN" value="7" enum="Operator">
+ Returns the lesser of two values, for each component of the vectors.
</constant>
<constant name="OP_CROSS" value="8" enum="Operator">
+ Calculates the cross product of two vectors.
</constant>
<constant name="OP_ATAN2" value="9" enum="Operator">
+ Returns the arc-tangent of the parameters.
</constant>
<constant name="OP_REFLECT" value="10" enum="Operator">
+ Returns the vector that points in the direction of reflection. [code]a[/code] is incident vector and [code]b[/code] is the normal vector.
</constant>
<constant name="OP_STEP" value="11" enum="Operator">
+ Vector step operator. Returns [code]0.0[/code] if [code]a[/code] is smaller than [code]b[/code] and [code]1.0[/code] otherwise.
</constant>
</constants>
</class>
diff --git a/doc/classes/VisualShaderNodeVectorRefract.xml b/doc/classes/VisualShaderNodeVectorRefract.xml
index c5962e7e10..0fa90a69cf 100644
--- a/doc/classes/VisualShaderNodeVectorRefract.xml
+++ b/doc/classes/VisualShaderNodeVectorRefract.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorRefract" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Returns the [Vector3] that points in the direction of refraction. For use within the visual shader graph.
</brief_description>
<description>
+ Translated to [code]refract(I, N, eta)[/code] in the shader language, where [code]I[/code] is the incident vector, [code]N[/code] is the normal vector and [code]eta[/code] is the ratio of the indicies of the refraction.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeVectorScalarMix.xml b/doc/classes/VisualShaderNodeVectorScalarMix.xml
index c425bfe45e..791a9e6be1 100644
--- a/doc/classes/VisualShaderNodeVectorScalarMix.xml
+++ b/doc/classes/VisualShaderNodeVectorScalarMix.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorScalarMix" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Linearly interpolates between two vectors using a scalar. For use within the visual shader graph.
</brief_description>
<description>
+ Translates to [code]mix(a, b, weight)[/code] in the shader language, where [code]a[/code] and [code]b[/code] are vectors and [code]weight[/code] is a scalar.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml b/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml
index 2f341d71e0..580abaf5fe 100644
--- a/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml
+++ b/doc/classes/VisualShaderNodeVectorScalarSmoothStep.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorScalarSmoothStep" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Calculates a vector SmoothStep function using scalar within the visual shader graph.
</brief_description>
<description>
+ Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language, where [code]x[/code] is a scalar.
+ Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeVectorScalarStep.xml b/doc/classes/VisualShaderNodeVectorScalarStep.xml
index 11da106001..d61414f3a8 100644
--- a/doc/classes/VisualShaderNodeVectorScalarStep.xml
+++ b/doc/classes/VisualShaderNodeVectorScalarStep.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorScalarStep" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Calculates a vector Step function within the visual shader graph.
</brief_description>
<description>
+ Translates to [code]step(edge, x)[/code] in the shader language.
+ Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge[/code] and [code]1.0[/code] otherwise.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeVectorSmoothStep.xml b/doc/classes/VisualShaderNodeVectorSmoothStep.xml
index 54e9f1bd7d..1b77a3c535 100644
--- a/doc/classes/VisualShaderNodeVectorSmoothStep.xml
+++ b/doc/classes/VisualShaderNodeVectorSmoothStep.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualShaderNodeVectorSmoothStep" inherits="VisualShaderNode" version="4.0">
<brief_description>
+ Calculates a vector SmoothStep function within the visual shader graph.
</brief_description>
<description>
+ Translates to [code]smoothstep(edge0, edge1, x)[/code] in the shader language, where [code]x[/code] is a vector.
+ Returns [code]0.0[/code] if [code]x[/code] is smaller than [code]edge0[/code] and [code]1.0[/code] if [code]x[/code] is larger than [code]edge1[/code]. Otherwise the return value is interpolated between [code]0.0[/code] and [code]1.0[/code] using Hermite polynomials.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/World2D.xml b/doc/classes/World2D.xml
index 2d8382b7e3..e66f21a0e7 100644
--- a/doc/classes/World2D.xml
+++ b/doc/classes/World2D.xml
@@ -16,7 +16,7 @@
The [RID] of this world's canvas resource. Used by the [RenderingServer] for 2D drawing.
</member>
<member name="direct_space_state" type="PhysicsDirectSpaceState2D" setter="" getter="get_direct_space_state">
- The state of this world's physics space. This allows arbitrary querying for collision.
+ Direct access to the world's physics 2D space state. Used for querying current and potential collisions. Must only be accessed from the main thread within [code]_physics_process(delta)[/code].
</member>
<member name="space" type="RID" setter="" getter="get_space">
The [RID] of this world's physics space resource. Used by the [PhysicsServer2D] for 2D physics, treating it as both a space and an area.
diff --git a/doc/classes/World3D.xml b/doc/classes/World3D.xml
index 4224a2a2c3..6d3b94794e 100644
--- a/doc/classes/World3D.xml
+++ b/doc/classes/World3D.xml
@@ -15,7 +15,7 @@
<member name="camera_effects" type="CameraEffects" setter="set_camera_effects" getter="get_camera_effects">
</member>
<member name="direct_space_state" type="PhysicsDirectSpaceState3D" setter="" getter="get_direct_space_state">
- The World3D's physics direct space state, used for making various queries. Might be used only during [code]_physics_process[/code].
+ Direct access to the world's physics 3D space state. Used for querying current and potential collisions. Must only be accessed from within [code]_physics_process(delta)[/code].
</member>
<member name="environment" type="Environment" setter="set_environment" getter="get_environment">
The World3D's [Environment].
diff --git a/doc/classes/XRController3D.xml b/doc/classes/XRController3D.xml
index e4a06a80db..8e80eb9a32 100644
--- a/doc/classes/XRController3D.xml
+++ b/doc/classes/XRController3D.xml
@@ -62,7 +62,7 @@
<argument index="0" name="button" type="int">
</argument>
<description>
- Returns [code]true[/code] if the button at index [code]button[/code] is pressed. See [enum JoystickList], in particular the [code]JOY_VR_*[/code] constants.
+ Returns [code]true[/code] if the button at index [code]button[/code] is pressed. See [enum JoyButtonList].
</description>
</method>
</methods>
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index c6c6cae6c0..a14ef7c665 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -901,6 +901,12 @@ def rstize_text(text, state): # type: (str, State) -> str
tag_text = "``"
tag_depth += 1
inside_code = True
+ elif cmd == "kbd":
+ tag_text = ":kbd:`"
+ tag_depth += 1
+ elif cmd == "/kbd":
+ tag_text = "`"
+ tag_depth -= 1
elif cmd.startswith("enum "):
tag_text = make_enum(cmd[5:], state)
escape_post = True
@@ -973,11 +979,14 @@ def format_table(f, data, remove_empty_columns=False): # type: (TextIO, Iterabl
f.write("\n")
-def make_type(t, state): # type: (str, State) -> str
- if t in state.classes:
- return ":ref:`{0}<class_{0}>`".format(t)
- print_error("Unresolved type '{}', file: {}".format(t, state.current_class), state)
- return t
+def make_type(klass, state): # type: (str, State) -> str
+ link_type = klass
+ if link_type.endswith("[]"): # Typed array, strip [] to link to contained type.
+ link_type = link_type[:-2]
+ if link_type in state.classes:
+ return ":ref:`{}<class_{}>`".format(klass, link_type)
+ print_error("Unresolved type '{}', file: {}".format(klass, state.current_class), state)
+ return klass
def make_enum(t, state): # type: (str, State) -> str
diff --git a/doc/translations/classes.pot b/doc/translations/classes.pot
index 641d80c5ca..28db7e4e04 100644
--- a/doc/translations/classes.pot
+++ b/doc/translations/classes.pot
@@ -480,7 +480,7 @@ msgid ""
"[float], the return value is a [float].\n"
"If both are of the same vector type ([Vector2], [Vector3] or [Color]), the "
"return value will be of the same type ([code]lerp[/code] then calls the "
-"vector type's [code]linear_interpolate[/code] method).\n"
+"vector type's [code]lerp[/code] method).\n"
"[codeblock]\n"
"lerp(0, 4, 0.75) # Returns 3.0\n"
"lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Returns Vector2(2, 3.5)\n"
@@ -1204,19 +1204,19 @@ msgid ""
msgstr ""
#: doc/classes/@GlobalScope.xml:16
-msgid "The [ARVRServer] singleton."
+msgid "The [AudioServer] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:19
-msgid "The [AudioServer] singleton."
+msgid "The [CameraServer] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:22
-msgid "The [CameraServer] singleton."
+msgid "The [ClassDB] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:25
-msgid "The [ClassDB] singleton."
+msgid "The [DisplayServer] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:28
@@ -1228,90 +1228,89 @@ msgid "The [Geometry] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:34
-msgid ""
-"The [GodotSharp] singleton. Only available when using Godot's Mono build."
+msgid "The [IP] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:37
-msgid "The [IP] singleton."
+msgid "The [Input] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:40
-msgid "The [InputFilter] singleton."
-msgstr ""
-
-#: doc/classes/@GlobalScope.xml:43
msgid "The [InputMap] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:46
+#: doc/classes/@GlobalScope.xml:43
msgid "The [JSON] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:49
+#: doc/classes/@GlobalScope.xml:46
msgid ""
"The [JavaClassWrapper] singleton.\n"
"[b]Note:[/b] Only implemented on Android."
msgstr ""
-#: doc/classes/@GlobalScope.xml:53
+#: doc/classes/@GlobalScope.xml:50
msgid ""
"The [JavaScript] singleton.\n"
"[b]Note:[/b] Only implemented on HTML5."
msgstr ""
-#: doc/classes/@GlobalScope.xml:57
+#: doc/classes/@GlobalScope.xml:54
msgid "The [Marshalls] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:60
+#: doc/classes/@GlobalScope.xml:57
msgid "The [NavigationMeshGenerator] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:63 doc/classes/@GlobalScope.xml:66
+#: doc/classes/@GlobalScope.xml:60 doc/classes/@GlobalScope.xml:63
msgid "The [NavigationServer2D] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:69
+#: doc/classes/@GlobalScope.xml:66
msgid "The [OS] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:72
+#: doc/classes/@GlobalScope.xml:69
msgid "The [Performance] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:75
+#: doc/classes/@GlobalScope.xml:72
msgid "The [PhysicsServer2D] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:78
+#: doc/classes/@GlobalScope.xml:75
msgid "The [PhysicsServer3D] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:81
+#: doc/classes/@GlobalScope.xml:78
msgid "The [ProjectSettings] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:84
+#: doc/classes/@GlobalScope.xml:81
msgid "The [RenderingServer] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:87
+#: doc/classes/@GlobalScope.xml:84
msgid "The [ResourceLoader] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:90
+#: doc/classes/@GlobalScope.xml:87
msgid "The [ResourceSaver] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:93
+#: doc/classes/@GlobalScope.xml:90
msgid "The [TranslationServer] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:96
+#: doc/classes/@GlobalScope.xml:93
msgid "The [VisualScriptEditor] singleton."
msgstr ""
+#: doc/classes/@GlobalScope.xml:96
+msgid "The [XRServer] singleton."
+msgstr ""
+
#: doc/classes/@GlobalScope.xml:101
msgid "Left margin, usually used for [Control] or [StyleBox]-derived classes."
msgstr ""
@@ -1394,7 +1393,7 @@ msgid "Tab key."
msgstr ""
#: doc/classes/@GlobalScope.xml:158
-msgid "Shift+Tab key."
+msgid "Shift + Tab key."
msgstr ""
#: doc/classes/@GlobalScope.xml:161
@@ -3124,305 +3123,311 @@ msgid "Used to categorize properties together in the editor."
msgstr ""
#: doc/classes/@GlobalScope.xml:1424
-msgid "The property does not save its state in [PackedScene]."
+msgid ""
+"Used to group properties together in the editor in a subgroup (under a "
+"group)."
msgstr ""
#: doc/classes/@GlobalScope.xml:1427
-msgid "Editing the property prompts the user for restarting the editor."
+msgid "The property does not save its state in [PackedScene]."
msgstr ""
#: doc/classes/@GlobalScope.xml:1430
+msgid "Editing the property prompts the user for restarting the editor."
+msgstr ""
+
+#: doc/classes/@GlobalScope.xml:1433
msgid ""
"The property is a script variable which should be serialized and saved in "
"the scene file."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1433
+#: doc/classes/@GlobalScope.xml:1436
msgid "Default usage (storage, editor and network)."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1436
+#: doc/classes/@GlobalScope.xml:1439
msgid ""
"Default usage for translatable strings (storage, editor, network and "
"internationalized)."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1439
+#: doc/classes/@GlobalScope.xml:1442
msgid ""
"Default usage but without showing the property in the editor (storage, "
"network)."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1442
+#: doc/classes/@GlobalScope.xml:1445
msgid "Flag for a normal method."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1445
+#: doc/classes/@GlobalScope.xml:1448
msgid "Flag for an editor method."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1448 doc/classes/@GlobalScope.xml:1454
-#: doc/classes/@GlobalScope.xml:1460
+#: doc/classes/@GlobalScope.xml:1451 doc/classes/@GlobalScope.xml:1457
+#: doc/classes/@GlobalScope.xml:1463
msgid "Deprecated method flag, unused."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1451
+#: doc/classes/@GlobalScope.xml:1454
msgid "Flag for a constant method."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1457
+#: doc/classes/@GlobalScope.xml:1460
msgid "Flag for a virtual method."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1463
+#: doc/classes/@GlobalScope.xml:1466
msgid "Default method flags."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1466
+#: doc/classes/@GlobalScope.xml:1469
msgid "Variable is [code]null[/code]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1469
+#: doc/classes/@GlobalScope.xml:1472
msgid "Variable is of type [bool]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1472
+#: doc/classes/@GlobalScope.xml:1475
msgid "Variable is of type [int]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1475
+#: doc/classes/@GlobalScope.xml:1478
msgid "Variable is of type [float] (real)."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1478
+#: doc/classes/@GlobalScope.xml:1481
msgid "Variable is of type [String]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1481
+#: doc/classes/@GlobalScope.xml:1484
msgid "Variable is of type [Vector2]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1484
+#: doc/classes/@GlobalScope.xml:1487
msgid "Variable is of type [Vector2i]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1487
+#: doc/classes/@GlobalScope.xml:1490
msgid "Variable is of type [Rect2]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1490
+#: doc/classes/@GlobalScope.xml:1493
msgid "Variable is of type [Rect2i]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1493
+#: doc/classes/@GlobalScope.xml:1496
msgid "Variable is of type [Vector3]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1496
+#: doc/classes/@GlobalScope.xml:1499
msgid "Variable is of type [Vector3i]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1499
+#: doc/classes/@GlobalScope.xml:1502
msgid "Variable is of type [Transform2D]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1502
+#: doc/classes/@GlobalScope.xml:1505
msgid "Variable is of type [Plane]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1505
+#: doc/classes/@GlobalScope.xml:1508
msgid "Variable is of type [Quat]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1508
+#: doc/classes/@GlobalScope.xml:1511
msgid "Variable is of type [AABB]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1511
+#: doc/classes/@GlobalScope.xml:1514
msgid "Variable is of type [Basis]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1514
+#: doc/classes/@GlobalScope.xml:1517
msgid "Variable is of type [Transform]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1517
+#: doc/classes/@GlobalScope.xml:1520
msgid "Variable is of type [Color]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1520
+#: doc/classes/@GlobalScope.xml:1523
msgid "Variable is of type [StringName]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1523
+#: doc/classes/@GlobalScope.xml:1526
msgid "Variable is of type [NodePath]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1526
+#: doc/classes/@GlobalScope.xml:1529
msgid "Variable is of type [RID]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1529
+#: doc/classes/@GlobalScope.xml:1532
msgid "Variable is of type [Object]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1532
+#: doc/classes/@GlobalScope.xml:1535
msgid "Variable is of type [Callable]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1535
+#: doc/classes/@GlobalScope.xml:1538
msgid "Variable is of type [Signal]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1538
+#: doc/classes/@GlobalScope.xml:1541
msgid "Variable is of type [Dictionary]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1541
+#: doc/classes/@GlobalScope.xml:1544
msgid "Variable is of type [Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1544
+#: doc/classes/@GlobalScope.xml:1547
msgid "Variable is of type [PackedByteArray]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1547
+#: doc/classes/@GlobalScope.xml:1550
msgid "Variable is of type [PackedInt32Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1550
+#: doc/classes/@GlobalScope.xml:1553
msgid "Variable is of type [PackedInt64Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1553
+#: doc/classes/@GlobalScope.xml:1556
msgid "Variable is of type [PackedFloat32Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1556
+#: doc/classes/@GlobalScope.xml:1559
msgid "Variable is of type [PackedFloat64Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1559
+#: doc/classes/@GlobalScope.xml:1562
msgid "Variable is of type [PackedStringArray]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1562
+#: doc/classes/@GlobalScope.xml:1565
msgid "Variable is of type [PackedVector2Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1565
+#: doc/classes/@GlobalScope.xml:1568
msgid "Variable is of type [PackedVector3Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1568
+#: doc/classes/@GlobalScope.xml:1571
msgid "Variable is of type [PackedColorArray]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1571
+#: doc/classes/@GlobalScope.xml:1574
msgid "Represents the size of the [enum Variant.Type] enum."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1574
+#: doc/classes/@GlobalScope.xml:1577
msgid "Equality operator ([code]==[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1577
+#: doc/classes/@GlobalScope.xml:1580
msgid "Inequality operator ([code]!=[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1580
+#: doc/classes/@GlobalScope.xml:1583
msgid "Less than operator ([code]<[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1583
+#: doc/classes/@GlobalScope.xml:1586
msgid "Less than or equal operator ([code]<=[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1586
+#: doc/classes/@GlobalScope.xml:1589
msgid "Greater than operator ([code]>[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1589
+#: doc/classes/@GlobalScope.xml:1592
msgid "Greater than or equal operator ([code]>=[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1592
+#: doc/classes/@GlobalScope.xml:1595
msgid "Addition operator ([code]+[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1595
+#: doc/classes/@GlobalScope.xml:1598
msgid "Subtraction operator ([code]-[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1598
+#: doc/classes/@GlobalScope.xml:1601
msgid "Multiplication operator ([code]*[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1601
+#: doc/classes/@GlobalScope.xml:1604
msgid "Division operator ([code]/[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1604
+#: doc/classes/@GlobalScope.xml:1607
msgid "Unary negation operator ([code]-[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1607
+#: doc/classes/@GlobalScope.xml:1610
msgid "Unary plus operator ([code]+[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1610
+#: doc/classes/@GlobalScope.xml:1613
msgid "Remainder/modulo operator ([code]%[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1613
+#: doc/classes/@GlobalScope.xml:1616
msgid "String concatenation operator ([code]+[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1616
+#: doc/classes/@GlobalScope.xml:1619
msgid "Left shift operator ([code]<<[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1619
+#: doc/classes/@GlobalScope.xml:1622
msgid "Right shift operator ([code]>>[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1622
+#: doc/classes/@GlobalScope.xml:1625
msgid "Bitwise AND operator ([code]&[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1625
+#: doc/classes/@GlobalScope.xml:1628
msgid "Bitwise OR operator ([code]|[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1628
+#: doc/classes/@GlobalScope.xml:1631
msgid "Bitwise XOR operator ([code]^[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1631
+#: doc/classes/@GlobalScope.xml:1634
msgid "Bitwise NOT operator ([code]~[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1634
+#: doc/classes/@GlobalScope.xml:1637
msgid "Logical AND operator ([code]and[/code] or [code]&&[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1637
+#: doc/classes/@GlobalScope.xml:1640
msgid "Logical OR operator ([code]or[/code] or [code]||[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1640
+#: doc/classes/@GlobalScope.xml:1643
msgid "Logical XOR operator (not implemented in GDScript)."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1643
+#: doc/classes/@GlobalScope.xml:1646
msgid "Logical NOT operator ([code]not[/code] or [code]![/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1646
+#: doc/classes/@GlobalScope.xml:1649
msgid "Logical IN operator ([code]in[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1649
+#: doc/classes/@GlobalScope.xml:1652
msgid "Represents the size of the [enum Variant.Operator] enum."
msgstr ""
@@ -3794,6 +3799,10 @@ msgid ""
msgstr ""
#: doc/classes/AnimatedTexture.xml:65
+msgid "Sets the currently visible frame of the texture."
+msgstr ""
+
+#: doc/classes/AnimatedTexture.xml:68
msgid ""
"Animation speed in frames per second. This value defines the default time "
"interval between two frames of the animation, and thus the overall duration "
@@ -3804,7 +3813,7 @@ msgid ""
"code] value of 2 will run for 4 seconds, with each frame lasting 0.5 seconds."
msgstr ""
-#: doc/classes/AnimatedTexture.xml:69
+#: doc/classes/AnimatedTexture.xml:72
msgid ""
"Number of frames to use in the animation. While you can create the frames "
"independently with [method set_frame_texture], you need to set this value "
@@ -3812,7 +3821,21 @@ msgid ""
"frames is [constant MAX_FRAMES]."
msgstr ""
-#: doc/classes/AnimatedTexture.xml:74
+#: doc/classes/AnimatedTexture.xml:75
+msgid ""
+"If [code]true[/code], the animation will only play once and will not loop "
+"back to the first frame after reaching the end. Note that reaching the end "
+"will not set [member pause] to [code]true[/code]."
+msgstr ""
+
+#: doc/classes/AnimatedTexture.xml:78
+msgid ""
+"If [code]true[/code], the animation will pause where it currently is (i.e. "
+"at [member current_frame]). The animation will continue from where it was "
+"paused when changing this property to [code]false[/code]."
+msgstr ""
+
+#: doc/classes/AnimatedTexture.xml:83
msgid ""
"The maximum number of frames supported by [AnimatedTexture]. If you need "
"more frames in your animation, use [AnimationPlayer] or [AnimatedSprite2D]."
@@ -6092,22 +6115,27 @@ msgid ""
"var m = MeshInstance3D.new()\n"
"m.mesh = arr_mesh\n"
"[/codeblock]\n"
-"The [MeshInstance3D] is ready to be added to the [SceneTree] to be shown."
+"The [MeshInstance3D] is ready to be added to the [SceneTree] to be shown.\n"
+"See also [ImmediateGeometry3D], [MeshDataTool] and [SurfaceTool] for "
+"procedural geometry generation.\n"
+"[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-"
+"OpenGL/Face-culling]winding order[/url] for front faces of triangle "
+"primitive modes."
msgstr ""
-#: doc/classes/ArrayMesh.xml:27
+#: doc/classes/ArrayMesh.xml:29
msgid ""
"https://docs.godotengine.org/en/latest/tutorials/content/procedural_geometry/"
"arraymesh.html"
msgstr ""
-#: doc/classes/ArrayMesh.xml:36
+#: doc/classes/ArrayMesh.xml:38
msgid ""
"Adds name for a blend shape that will be added with [method "
"add_surface_from_arrays]. Must be called before surface is added."
msgstr ""
-#: doc/classes/ArrayMesh.xml:55
+#: doc/classes/ArrayMesh.xml:57
msgid ""
"Creates a new surface.\n"
"Surfaces are created to be rendered using a [code]primitive[/code], which "
@@ -6125,141 +6153,139 @@ msgid ""
"it is used.\n"
"Adding an index array puts this function into \"index mode\" where the "
"vertex and other arrays become the sources of data, and the index array "
-"defines the order of the vertices.\n"
-"Godot uses clockwise winding order for front faces of triangle primitive "
-"modes."
+"defines the order of the vertices."
msgstr ""
-#: doc/classes/ArrayMesh.xml:66
+#: doc/classes/ArrayMesh.xml:67
msgid "Removes all blend shapes from this [ArrayMesh]."
msgstr ""
-#: doc/classes/ArrayMesh.xml:73
+#: doc/classes/ArrayMesh.xml:74
msgid "Removes all surfaces from this [ArrayMesh]."
msgstr ""
-#: doc/classes/ArrayMesh.xml:80
+#: doc/classes/ArrayMesh.xml:81
msgid "Returns the number of blend shapes that the [ArrayMesh] holds."
msgstr ""
-#: doc/classes/ArrayMesh.xml:89
+#: doc/classes/ArrayMesh.xml:90
msgid "Returns the name of the blend shape at this index."
msgstr ""
-#: doc/classes/ArrayMesh.xml:100
+#: doc/classes/ArrayMesh.xml:101
msgid ""
"Will perform a UV unwrap on the [ArrayMesh] to prepare the mesh for "
"lightmapping."
msgstr ""
-#: doc/classes/ArrayMesh.xml:107
+#: doc/classes/ArrayMesh.xml:108
msgid "Will regenerate normal maps for the [ArrayMesh]."
msgstr ""
-#: doc/classes/ArrayMesh.xml:116
+#: doc/classes/ArrayMesh.xml:117
msgid ""
"Returns the index of the first surface with this name held within this "
"[ArrayMesh]. If none are found, -1 is returned."
msgstr ""
-#: doc/classes/ArrayMesh.xml:125
+#: doc/classes/ArrayMesh.xml:126
msgid ""
"Returns the length in indices of the index array in the requested surface "
"(see [method add_surface_from_arrays])."
msgstr ""
-#: doc/classes/ArrayMesh.xml:134
+#: doc/classes/ArrayMesh.xml:135
msgid ""
"Returns the length in vertices of the vertex array in the requested surface "
"(see [method add_surface_from_arrays])."
msgstr ""
-#: doc/classes/ArrayMesh.xml:143
+#: doc/classes/ArrayMesh.xml:144
msgid ""
"Returns the format mask of the requested surface (see [method "
"add_surface_from_arrays])."
msgstr ""
-#: doc/classes/ArrayMesh.xml:152
+#: doc/classes/ArrayMesh.xml:153
msgid "Gets the name assigned to this surface."
msgstr ""
-#: doc/classes/ArrayMesh.xml:161
+#: doc/classes/ArrayMesh.xml:162
msgid ""
"Returns the primitive type of the requested surface (see [method "
"add_surface_from_arrays])."
msgstr ""
-#: doc/classes/ArrayMesh.xml:172
+#: doc/classes/ArrayMesh.xml:173
msgid "Sets a name for a given surface."
msgstr ""
-#: doc/classes/ArrayMesh.xml:185
+#: doc/classes/ArrayMesh.xml:186
msgid ""
"Updates a specified region of mesh arrays on the GPU.\n"
"[b]Warning:[/b] Only use if you know what you are doing. You can easily "
"cause crashes by calling this function with improper arguments."
msgstr ""
-#: doc/classes/ArrayMesh.xml:192
+#: doc/classes/ArrayMesh.xml:193
msgid "Sets the blend shape mode to one of [enum Mesh.BlendShapeMode]."
msgstr ""
-#: doc/classes/ArrayMesh.xml:195
+#: doc/classes/ArrayMesh.xml:196
msgid ""
"Overrides the [AABB] with one defined by user for use with frustum culling. "
"Especially useful to avoid unexpected culling when using a shader to offset "
"vertices."
msgstr ""
-#: doc/classes/ArrayMesh.xml:200
+#: doc/classes/ArrayMesh.xml:201
msgid "Default value used for index_array_len when no indices are present."
msgstr ""
-#: doc/classes/ArrayMesh.xml:203
+#: doc/classes/ArrayMesh.xml:204
msgid "Amount of weights/bone indices per vertex (always 4)."
msgstr ""
-#: doc/classes/ArrayMesh.xml:206
+#: doc/classes/ArrayMesh.xml:207
msgid ""
"[PackedVector3Array], [PackedVector2Array], or [Array] of vertex positions."
msgstr ""
-#: doc/classes/ArrayMesh.xml:209
+#: doc/classes/ArrayMesh.xml:210
msgid "[PackedVector3Array] of vertex normals."
msgstr ""
-#: doc/classes/ArrayMesh.xml:212
+#: doc/classes/ArrayMesh.xml:213
msgid ""
"[PackedFloat32Array] of vertex tangents. Each element in groups of 4 floats, "
"first 3 floats determine the tangent, and the last the binormal direction as "
"-1 or 1."
msgstr ""
-#: doc/classes/ArrayMesh.xml:215
+#: doc/classes/ArrayMesh.xml:216
msgid "[PackedColorArray] of vertex colors."
msgstr ""
-#: doc/classes/ArrayMesh.xml:218
+#: doc/classes/ArrayMesh.xml:219
msgid "[PackedVector2Array] for UV coordinates."
msgstr ""
-#: doc/classes/ArrayMesh.xml:221
+#: doc/classes/ArrayMesh.xml:222
msgid "[PackedVector2Array] for second UV coordinates."
msgstr ""
-#: doc/classes/ArrayMesh.xml:224
+#: doc/classes/ArrayMesh.xml:225
msgid ""
"[PackedFloat32Array] or [PackedInt32Array] of bone indices. Each element in "
"groups of 4 floats."
msgstr ""
-#: doc/classes/ArrayMesh.xml:227
+#: doc/classes/ArrayMesh.xml:228
msgid ""
"[PackedFloat32Array] of bone weights. Each element in groups of 4 floats."
msgstr ""
-#: doc/classes/ArrayMesh.xml:230
+#: doc/classes/ArrayMesh.xml:231
msgid ""
"[PackedInt32Array] of integers used as indices referencing vertices, colors, "
"normals, tangents, and textures. All of those arrays must have the same "
@@ -6273,709 +6299,47 @@ msgid ""
"the start and end of each line."
msgstr ""
-#: doc/classes/ArrayMesh.xml:234 doc/classes/Mesh.xml:210
-#: doc/classes/RenderingServer.xml:3180
+#: doc/classes/ArrayMesh.xml:235 doc/classes/Mesh.xml:210
+#: doc/classes/RenderingServer.xml:3232
msgid "Represents the size of the [enum ArrayType] enum."
msgstr ""
-#: doc/classes/ArrayMesh.xml:237
+#: doc/classes/ArrayMesh.xml:238
msgid "Array format will include vertices (mandatory)."
msgstr ""
-#: doc/classes/ArrayMesh.xml:240
+#: doc/classes/ArrayMesh.xml:241
msgid "Array format will include normals."
msgstr ""
-#: doc/classes/ArrayMesh.xml:243
+#: doc/classes/ArrayMesh.xml:244
msgid "Array format will include tangents."
msgstr ""
-#: doc/classes/ArrayMesh.xml:246
+#: doc/classes/ArrayMesh.xml:247
msgid "Array format will include a color array."
msgstr ""
-#: doc/classes/ArrayMesh.xml:249
+#: doc/classes/ArrayMesh.xml:250
msgid "Array format will include UVs."
msgstr ""
-#: doc/classes/ArrayMesh.xml:252
+#: doc/classes/ArrayMesh.xml:253
msgid "Array format will include another set of UVs."
msgstr ""
-#: doc/classes/ArrayMesh.xml:255
+#: doc/classes/ArrayMesh.xml:256
msgid "Array format will include bone indices."
msgstr ""
-#: doc/classes/ArrayMesh.xml:258
+#: doc/classes/ArrayMesh.xml:259
msgid "Array format will include bone weights."
msgstr ""
-#: doc/classes/ArrayMesh.xml:261
+#: doc/classes/ArrayMesh.xml:262
msgid "Index array will be used."
msgstr ""
-#: doc/classes/ARVRAnchor.xml:4
-msgid "An anchor point in AR space."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:7
-msgid ""
-"The [ARVRAnchor] point is a spatial node that maps a real world location "
-"identified by the AR platform to a position within the game world. For "
-"example, as long as plane detection in ARKit is on, ARKit will identify and "
-"update the position of planes (tables, floors, etc) and create anchors for "
-"them.\n"
-"This node is mapped to one of the anchors through its unique ID. When you "
-"receive a signal that a new anchor is available, you should add this node to "
-"your scene for that anchor. You can predefine nodes and set the ID; the "
-"nodes will simply remain on 0,0,0 until a plane is recognized.\n"
-"Keep in mind that, as long as plane detection is enabled, the size, placing "
-"and orientation of an anchor will be updated as the detection logic learns "
-"more about the real world out there especially if only part of the surface "
-"is in view."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:18
-msgid "Returns the name given to this anchor."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:25
-msgid ""
-"Returns [code]true[/code] if the anchor is being tracked and [code]false[/"
-"code] if no anchor with this ID is currently known."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:32
-msgid ""
-"If provided by the [ARVRInterface], this returns a mesh object for the "
-"anchor. For an anchor, this can be a shape related to the object being "
-"tracked or it can be a mesh that provides topology related to the anchor and "
-"can be used to create shadows/reflections on surfaces or for generating "
-"collision shapes."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:39
-msgid ""
-"Returns a plane aligned with our anchor; handy for intersection testing."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:46
-msgid ""
-"Returns the estimated size of the plane that was detected. Say when the "
-"anchor relates to a table in the real world, this is the estimated size of "
-"the surface of that table."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:52
-msgid ""
-"The anchor's ID. You can set this before the anchor itself exists. The first "
-"anchor gets an ID of [code]1[/code], the second an ID of [code]2[/code], "
-"etc. When anchors get removed, the engine can then assign the corresponding "
-"ID to new anchors. The most common situation where anchors \"disappear\" is "
-"when the AR server identifies that two anchors represent different parts of "
-"the same plane and merges them."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:60
-msgid ""
-"Emitted when the mesh associated with the anchor changes or when one becomes "
-"available. This is especially important for topology that is constantly "
-"being [code]mesh_updated[/code]."
-msgstr ""
-
-#: doc/classes/ARVRCamera.xml:4
-msgid ""
-"A camera node with a few overrules for AR/VR applied, such as location "
-"tracking."
-msgstr ""
-
-#: doc/classes/ARVRCamera.xml:7
-msgid ""
-"This is a helper spatial node for our camera; note that, if stereoscopic "
-"rendering is applicable (VR-HMD), most of the camera properties are ignored, "
-"as the HMD information overrides them. The only properties that can be "
-"trusted are the near and far planes.\n"
-"The position and orientation of this node is automatically updated by the "
-"ARVR Server to represent the location of the HMD if such tracking is "
-"available and can thus be used by game logic. Note that, in contrast to the "
-"ARVR Controller, the render thread has access to the most up-to-date "
-"tracking data of the HMD and the location of the ARVRCamera can lag a few "
-"milliseconds behind what is used for rendering as a result."
-msgstr ""
-
-#: doc/classes/ARVRCamera.xml:11 doc/classes/ARVRController.xml:12
-#: doc/classes/ARVRInterface.xml:11 doc/classes/ARVROrigin.xml:13
-#: doc/classes/ARVRPositionalTracker.xml:12 doc/classes/ARVRServer.xml:10
-msgid "https://docs.godotengine.org/en/latest/tutorials/vr/index.html"
-msgstr ""
-
-#: doc/classes/ARVRController.xml:4
-msgid "A spatial node representing a spatially-tracked controller."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:7
-msgid ""
-"This is a helper spatial node that is linked to the tracking of controllers. "
-"It also offers several handy passthroughs to the state of buttons and such "
-"on the controllers.\n"
-"Controllers are linked by their ID. You can create controller nodes before "
-"the controllers are available. If your game always uses two controllers (one "
-"for each hand), you can predefine the controllers with ID 1 and 2; they will "
-"become active as soon as the controllers are identified. If you expect "
-"additional controllers to be used, you should react to the signals and add "
-"ARVRController nodes to your scene.\n"
-"The position of the controller node is automatically updated by the "
-"[ARVRServer]. This makes this node ideal to add child nodes to visualize the "
-"controller."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:19
-msgid ""
-"If active, returns the name of the associated controller if provided by the "
-"AR/VR SDK used."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:26
-msgid ""
-"Returns the hand holding this controller, if known. See [enum "
-"ARVRPositionalTracker.TrackerHand]."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:33
-msgid ""
-"Returns [code]true[/code] if the bound controller is active. ARVR systems "
-"attempt to track active controllers."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:42
-msgid ""
-"Returns the value of the given axis for things like triggers, touchpads, "
-"etc. that are embedded into the controller."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:49
-msgid ""
-"Returns the ID of the joystick object bound to this. Every controller "
-"tracked by the [ARVRServer] that has buttons and axis will also be "
-"registered as a joystick within Godot. This means that all the normal "
-"joystick tracking and input mapping will work for buttons and axis found on "
-"the AR/VR controllers. This ID is purely offered as information so you can "
-"link up the controller with its joystick entry."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:56
-msgid ""
-"If provided by the [ARVRInterface], this returns a mesh associated with the "
-"controller. This can be used to visualize the controller."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:65
-msgid ""
-"Returns [code]true[/code] if the button at index [code]button[/code] is "
-"pressed. See [enum JoystickList], in particular the [code]JOY_VR_*[/code] "
-"constants."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:71
-msgid ""
-"The controller's ID.\n"
-"A controller ID of 0 is unbound and will always result in an inactive node. "
-"Controller ID 1 is reserved for the first controller that identifies itself "
-"as the left-hand controller and ID 2 is reserved for the first controller "
-"that identifies itself as the right-hand controller.\n"
-"For any other controller that the [ARVRServer] detects, we continue with "
-"controller ID 3.\n"
-"When a controller is turned off, its slot is freed. This ensures controllers "
-"will keep the same ID even when controllers with lower IDs are turned off."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:77
-msgid ""
-"The degree to which the controller vibrates. Ranges from [code]0.0[/code] to "
-"[code]1.0[/code] with precision [code].01[/code]. If changed, updates "
-"[member ARVRPositionalTracker.rumble] accordingly.\n"
-"This is a useful property to animate if you want the controller to vibrate "
-"for a limited duration."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:86
-msgid "Emitted when a button on this controller is pressed."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:93
-msgid "Emitted when a button on this controller is released."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:100
-msgid ""
-"Emitted when the mesh associated with the controller changes or when one "
-"becomes available. Generally speaking this will be a static mesh after "
-"becoming available."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:4
-msgid "Base class for an AR/VR interface implementation."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:7
-msgid ""
-"This class needs to be implemented to make an AR or VR platform available to "
-"Godot and these should be implemented as C++ modules or GDNative modules "
-"(note that for GDNative the subclass ARVRScriptInterface should be used). "
-"Part of the interface is exposed to GDScript so you can detect, enable and "
-"configure an AR or VR platform.\n"
-"Interfaces should be written in such a way that simply enabling them will "
-"give us a working setup. You can query the available interfaces through "
-"[ARVRServer]."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:18
-msgid ""
-"If this is an AR interface that requires displaying a camera feed as the "
-"background, this method returns the feed ID in the [CameraServer] for this "
-"interface."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:25
-msgid ""
-"Returns a combination of [enum Capabilities] flags providing information "
-"about the capabilities of this interface."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:32
-msgid "Returns the name of this interface (OpenVR, OpenHMD, ARKit, etc)."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:39
-msgid ""
-"Returns the resolution at which we should render our intermediate results "
-"before things like lens distortion are applied by the VR platform."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:46
-msgid ""
-"If supported, returns the status of our tracking. This will allow you to "
-"provide feedback to the user whether there are issues with positional "
-"tracking."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:53
-msgid ""
-"Call this to initialize this interface. The first interface that is "
-"initialized is identified as the primary interface and it will be used for "
-"rendering output.\n"
-"After initializing the interface you want to use you then need to enable the "
-"AR/VR mode of a viewport and rendering should commence.\n"
-"[b]Note:[/b] You must enable the AR/VR mode on the main viewport for any "
-"device that uses the main output of Godot, such as for mobile VR.\n"
-"If you do this for a platform that handles its own output (such as OpenVR) "
-"Godot will show just one eye without distortion on screen. Alternatively, "
-"you can add a separate viewport node to your scene and enable AR/VR on that "
-"viewport. It will be used to output to the HMD, leaving you free to do "
-"anything you like in the main window, such as using a separate camera as a "
-"spectator camera or rendering something completely different.\n"
-"While currently not used, you can activate additional interfaces. You may "
-"wish to do this if you want to track controllers from other platforms. "
-"However, at this point in time only one interface can render to an HMD."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:64
-msgid ""
-"Returns [code]true[/code] if the current output of this interface is in "
-"stereo."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:71
-msgid "Turns the interface off."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:77
-msgid "On an AR interface, [code]true[/code] if anchor detection is enabled."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:80
-msgid "[code]true[/code] if this interface been initialized."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:83
-msgid "[code]true[/code] if this is the primary interface."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:88
-msgid "No ARVR capabilities."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:91
-msgid ""
-"This interface can work with normal rendering output (non-HMD based AR)."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:94
-msgid "This interface supports stereoscopic rendering."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:97
-msgid "This interface supports AR (video background and real world tracking)."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:100
-msgid ""
-"This interface outputs to an external device. If the main viewport is used, "
-"the on screen output is an unmodified buffer of either the left or right eye "
-"(stretched if the viewport size is not changed to the same aspect ratio of "
-"[method get_render_targetsize]). Using a separate viewport node frees up the "
-"main viewport for other purposes."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:103
-msgid ""
-"Mono output, this is mostly used internally when retrieving positioning "
-"information for our camera node or when stereo scopic rendering is not "
-"supported."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:106
-msgid ""
-"Left eye output, this is mostly used internally when rendering the image for "
-"the left eye and obtaining positioning and projection information."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:109
-msgid ""
-"Right eye output, this is mostly used internally when rendering the image "
-"for the right eye and obtaining positioning and projection information."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:112
-msgid "Tracking is behaving as expected."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:115
-msgid ""
-"Tracking is hindered by excessive motion (the player is moving faster than "
-"tracking can keep up)."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:118
-msgid ""
-"Tracking is hindered by insufficient features, it's too dark (for camera-"
-"based tracking), player is blocked, etc."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:121
-msgid ""
-"We don't know the status of the tracking or this interface does not provide "
-"feedback."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:124
-msgid ""
-"Tracking is not functional (camera not plugged in or obscured, lighthouses "
-"turned off, etc.)."
-msgstr ""
-
-#: modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml:4
-msgid "GDNative wrapper for an ARVR interface."
-msgstr ""
-
-#: modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml:7
-msgid ""
-"This is a wrapper class for GDNative implementations of the ARVR interface. "
-"To use a GDNative ARVR interface, simply instantiate this object and set "
-"your GDNative library containing the ARVR interface implementation."
-msgstr ""
-
-#: doc/classes/ARVROrigin.xml:4
-msgid "The origin point in AR/VR."
-msgstr ""
-
-#: doc/classes/ARVROrigin.xml:7
-msgid ""
-"This is a special node within the AR/VR system that maps the physical "
-"location of the center of our tracking space to the virtual location within "
-"our game world.\n"
-"There should be only one of these nodes in your scene and you must have one. "
-"All the ARVRCamera, ARVRController and ARVRAnchor nodes should be direct "
-"children of this node for spatial tracking to work correctly.\n"
-"It is the position of this node that you update when your character needs to "
-"move through your game world while we're not moving in the real world. "
-"Movement in the real world is always in relation to this origin point.\n"
-"For example, if your character is driving a car, the ARVROrigin node should "
-"be a child node of this car. Or, if you're implementing a teleport system to "
-"move your character, you should change the position of this node."
-msgstr ""
-
-#: doc/classes/ARVROrigin.xml:19
-msgid ""
-"Allows you to adjust the scale to your game's units. Most AR/VR platforms "
-"assume a scale of 1 game world unit = 1 real world meter.\n"
-"[b]Note:[/b] This method is a passthrough to the [ARVRServer] itself."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:4
-msgid "A tracked object."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:7
-msgid ""
-"An instance of this object represents a device that is tracked, such as a "
-"controller or anchor point. HMDs aren't represented here as they are handled "
-"internally.\n"
-"As controllers are turned on and the AR/VR interface detects them, instances "
-"of this object are automatically added to this list of active tracking "
-"objects accessible through the [ARVRServer].\n"
-"The [ARVRController] and [ARVRAnchor] both consume objects of this type and "
-"should be used in your project. The positional trackers are just under-the-"
-"hood objects that make this all work. These are mostly exposed so that "
-"GDNative-based interfaces can interact with them."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:19
-msgid ""
-"Returns the hand holding this tracker, if known. See [enum TrackerHand] "
-"constants."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:26
-msgid ""
-"If this is a controller that is being tracked, the controller will also be "
-"represented by a joystick entry with this ID."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:33
-msgid ""
-"Returns the mesh related to a controller or anchor point if one is available."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:40
-msgid "Returns the controller or anchor point's name if available."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:47
-msgid "Returns the controller's orientation matrix."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:54
-msgid "Returns the world-space controller position."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:61
-msgid ""
-"Returns the internal tracker ID. This uniquely identifies the tracker per "
-"tracker type and matches the ID you need to specify for nodes such as the "
-"[ARVRController] and [ARVRAnchor] nodes."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:68
-msgid "Returns [code]true[/code] if this device tracks orientation."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:75
-msgid "Returns [code]true[/code] if this device tracks position."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:84
-msgid "Returns the transform combining this device's orientation and position."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:91
-msgid "Returns the tracker's type."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:97
-msgid ""
-"The degree to which the tracker rumbles. Ranges from [code]0.0[/code] to "
-"[code]1.0[/code] with precision [code].01[/code]."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:102
-msgid "The hand this tracker is held in is unknown or not applicable."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:105
-msgid "This tracker is the left hand controller."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:108
-msgid "This tracker is the right hand controller."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:4
-msgid "Server for AR and VR features."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:7
-msgid ""
-"The AR/VR server is the heart of our Advanced and Virtual Reality solution "
-"and handles all the processing."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:21
-msgid ""
-"This is an important function to understand correctly. AR and VR platforms "
-"all handle positioning slightly differently.\n"
-"For platforms that do not offer spatial tracking, our origin point (0,0,0) "
-"is the location of our HMD, but you have little control over the direction "
-"the player is facing in the real world.\n"
-"For platforms that do offer spatial tracking, our origin point depends very "
-"much on the system. For OpenVR, our origin point is usually the center of "
-"the tracking space, on the ground. For other platforms, it's often the "
-"location of the tracking camera.\n"
-"This method allows you to center your tracker on the location of the HMD. It "
-"will take the current location of the HMD and use that to adjust all your "
-"tracking data; in essence, realigning the real world to your player's "
-"current position in the game world.\n"
-"For this method to produce usable results, tracking information must be "
-"available. This often takes a few frames after starting your game.\n"
-"You should call this method after a few seconds have passed. For instance, "
-"when the user requests a realignment of the display holding a designated "
-"button on a controller for a short period of time, or when implementing a "
-"teleport mechanism."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:35
-msgid ""
-"Finds an interface by its name. For instance, if your project uses "
-"capabilities of an AR/VR platform, you can find the interface for that "
-"platform by name and initialize it."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:42
-msgid "Returns the primary interface's transformation."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:51
-msgid ""
-"Returns the interface registered at a given index in our list of interfaces."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:58
-msgid ""
-"Returns the number of interfaces currently registered with the AR/VR server. "
-"If your project supports multiple AR/VR platforms, you can look through the "
-"available interface, and either present the user with a selection or simply "
-"try to initialize each interface and use the first one that returns "
-"[code]true[/code]."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:65
-msgid ""
-"Returns a list of available interfaces the ID and name of each interface."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:72
-msgid ""
-"Returns the absolute timestamp (in μs) of the last [ARVRServer] commit of "
-"the AR/VR eyes to [RenderingServer]. The value comes from an internal call "
-"to [method OS.get_ticks_usec]."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:79
-msgid ""
-"Returns the duration (in μs) of the last frame. This is computed as the "
-"difference between [method get_last_commit_usec] and [method "
-"get_last_process_usec] when committing."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:86
-msgid ""
-"Returns the absolute timestamp (in μs) of the last [ARVRServer] process "
-"callback. The value comes from an internal call to [method OS."
-"get_ticks_usec]."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:93
-msgid ""
-"Returns the reference frame transform. Mostly used internally and exposed "
-"for GDNative build interfaces."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:102
-msgid "Returns the positional tracker at the given ID."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:109
-msgid "Returns the number of trackers currently registered."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:115
-msgid "The primary [ARVRInterface] currently bound to the [ARVRServer]."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:118
-msgid ""
-"Allows you to adjust the scale to your game's units. Most AR/VR platforms "
-"assume a scale of 1 game world unit = 1 real world meter."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:126
-msgid "Emitted when a new interface has been added."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:133
-msgid "Emitted when an interface is removed."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:144
-msgid ""
-"Emitted when a new tracker has been added. If you don't use a fixed number "
-"of controllers or if you're using [ARVRAnchor]s for an AR solution, it is "
-"important to react to this signal to add the appropriate [ARVRController] or "
-"[ARVRAnchor] nodes related to this new tracker."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:155
-msgid ""
-"Emitted when a tracker is removed. You should remove any [ARVRController] or "
-"[ARVRAnchor] points if applicable. This is not mandatory, the nodes simply "
-"become inactive and will be made active again when a new tracker becomes "
-"available (i.e. a new controller is switched on that takes the place of the "
-"previous one)."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:161
-msgid "The tracker tracks the location of a controller."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:164
-msgid "The tracker tracks the location of a base station."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:167
-msgid "The tracker tracks the location and size of an AR anchor."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:170
-msgid "Used internally to filter trackers of any known type."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:173
-msgid "Used internally if we haven't set the tracker type yet."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:176
-msgid "Used internally to select all trackers."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:179
-msgid ""
-"Fully reset the orientation of the HMD. Regardless of what direction the "
-"user is looking to in the real world. The user will look dead ahead in the "
-"virtual world."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:182
-msgid ""
-"Resets the orientation but keeps the tilt of the device. So if we're looking "
-"down, we keep looking down but heading will be reset."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:185
-msgid ""
-"Does not reset the orientation of the HMD, only the position of the player "
-"gets centered."
-msgstr ""
-
#: doc/classes/AStar.xml:4
msgid ""
"An implementation of A* to find shortest paths among connected points in "
@@ -8377,7 +7741,9 @@ msgstr ""
#: doc/classes/AudioStreamPlayer.xml:64 doc/classes/AudioStreamPlayer2D.xml:70
#: doc/classes/AudioStreamPlayer3D.xml:94
-msgid "Changes the pitch and the tempo of the audio."
+msgid ""
+"The pitch and the tempo of the audio, as a multiplier of the audio sample's "
+"sample rate."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml:67 doc/classes/AudioStreamPlayer2D.xml:73
@@ -8622,15 +7988,23 @@ msgid "Audio format. See [enum Format] constants for values."
msgstr ""
#: doc/classes/AudioStreamSample.xml:33
-msgid "Loop start in bytes."
+msgid ""
+"The loop start point (in number of samples, relative to the beginning of the "
+"sample). This information will be imported automatically from the WAV file "
+"if present."
msgstr ""
#: doc/classes/AudioStreamSample.xml:36
-msgid "Loop end in bytes."
+msgid ""
+"The loop end point (in number of samples, relative to the beginning of the "
+"sample). This information will be imported automatically from the WAV file "
+"if present."
msgstr ""
#: doc/classes/AudioStreamSample.xml:39
-msgid "Loop mode. See [enum LoopMode] constants for values."
+msgid ""
+"The loop mode. This information will be imported automatically from the WAV "
+"file if present. See [enum LoopMode] constants for values."
msgstr ""
#: doc/classes/AudioStreamSample.xml:42
@@ -8659,19 +8033,19 @@ msgstr ""
#: doc/classes/AudioStreamSample.xml:62
msgid ""
-"Audio loops the data between [member loop_begin] and [member loop_end] "
+"Audio loops the data between [member loop_begin] and [member loop_end], "
"playing forward only."
msgstr ""
#: doc/classes/AudioStreamSample.xml:65
msgid ""
-"Audio loops the data between [member loop_begin] and [member loop_end] "
+"Audio loops the data between [member loop_begin] and [member loop_end], "
"playing back and forth."
msgstr ""
#: doc/classes/AudioStreamSample.xml:68
msgid ""
-"Audio loops the data between [member loop_begin] and [member loop_end] "
+"Audio loops the data between [member loop_begin] and [member loop_end], "
"playing backward only."
msgstr ""
@@ -8688,30 +8062,35 @@ msgid ""
"in the BackBufferCopy node is bufferized with the content of the screen it "
"covers, or the entire screen according to the copy mode set. Use the "
"[code]texture(SCREEN_TEXTURE, ...)[/code] function in your shader scripts to "
-"access the buffer."
+"access the buffer.\n"
+"[b]Note:[/b] Since this node inherits from [Node2D] (and not [Control]), "
+"anchors and margins won't apply to child [Control]-derived nodes. This can "
+"be problematic when resizing the window. To avoid this, add [Control]-"
+"derived nodes as [i]siblings[/i] to the BackBufferCopy node instead of "
+"adding them as children."
msgstr ""
-#: doc/classes/BackBufferCopy.xml:15
+#: doc/classes/BackBufferCopy.xml:16
msgid "Buffer mode. See [enum CopyMode] constants."
msgstr ""
-#: doc/classes/BackBufferCopy.xml:18
+#: doc/classes/BackBufferCopy.xml:19
msgid ""
"The area covered by the BackBufferCopy. Only used if [member copy_mode] is "
"[constant COPY_MODE_RECT]."
msgstr ""
-#: doc/classes/BackBufferCopy.xml:23
+#: doc/classes/BackBufferCopy.xml:24
msgid ""
"Disables the buffering mode. This means the BackBufferCopy node will "
"directly use the portion of screen it covers."
msgstr ""
-#: doc/classes/BackBufferCopy.xml:26
+#: doc/classes/BackBufferCopy.xml:27
msgid "BackBufferCopy buffers a rectangular region."
msgstr ""
-#: doc/classes/BackBufferCopy.xml:29
+#: doc/classes/BackBufferCopy.xml:30
msgid "BackBufferCopy buffers the entire screen."
msgstr ""
@@ -8781,80 +8160,83 @@ msgstr ""
#: doc/classes/BaseButton.xml:62
msgid ""
"If [code]true[/code], the button stays pressed when moving the cursor "
-"outside the button while pressing it."
+"outside the button while pressing it.\n"
+"[b]Note:[/b] This property only affects the button's visual appearance. "
+"Signals will be emitted at the same moment regardless of this property's "
+"value."
msgstr ""
-#: doc/classes/BaseButton.xml:65
+#: doc/classes/BaseButton.xml:66
msgid ""
"If [code]true[/code], the button's state is pressed. Means the button is "
"pressed down or toggled (if [member toggle_mode] is active)."
msgstr ""
-#: doc/classes/BaseButton.xml:68
+#: doc/classes/BaseButton.xml:69
msgid "[ShortCut] associated to the button."
msgstr ""
-#: doc/classes/BaseButton.xml:71
+#: doc/classes/BaseButton.xml:72
msgid ""
"If [code]true[/code], the button will add information about its shortcut in "
"the tooltip."
msgstr ""
-#: doc/classes/BaseButton.xml:74
+#: doc/classes/BaseButton.xml:75
msgid ""
"If [code]true[/code], the button is in toggle mode. Makes the button flip "
"state between pressed and unpressed each time its area is clicked."
msgstr ""
-#: doc/classes/BaseButton.xml:80
+#: doc/classes/BaseButton.xml:81
msgid "Emitted when the button starts being held down."
msgstr ""
-#: doc/classes/BaseButton.xml:85
+#: doc/classes/BaseButton.xml:86
msgid "Emitted when the button stops being held down."
msgstr ""
-#: doc/classes/BaseButton.xml:90
+#: doc/classes/BaseButton.xml:91
msgid ""
"Emitted when the button is toggled or pressed. This is on [signal "
"button_down] if [member action_mode] is [constant ACTION_MODE_BUTTON_PRESS] "
"and on [signal button_up] otherwise."
msgstr ""
-#: doc/classes/BaseButton.xml:97
+#: doc/classes/BaseButton.xml:98
msgid ""
"Emitted when the button was just toggled between pressed and normal states "
"(only if [member toggle_mode] is active). The new state is contained in the "
"[code]button_pressed[/code] argument."
msgstr ""
-#: doc/classes/BaseButton.xml:103
+#: doc/classes/BaseButton.xml:104
msgid ""
"The normal state (i.e. not pressed, not hovered, not toggled and enabled) of "
"buttons."
msgstr ""
-#: doc/classes/BaseButton.xml:106
+#: doc/classes/BaseButton.xml:107
msgid "The state of buttons are pressed."
msgstr ""
-#: doc/classes/BaseButton.xml:109
+#: doc/classes/BaseButton.xml:110
msgid "The state of buttons are hovered."
msgstr ""
-#: doc/classes/BaseButton.xml:112
+#: doc/classes/BaseButton.xml:113
msgid "The state of buttons are disabled."
msgstr ""
-#: doc/classes/BaseButton.xml:115
+#: doc/classes/BaseButton.xml:116
msgid "The state of buttons are both hovered and pressed."
msgstr ""
-#: doc/classes/BaseButton.xml:118
+#: doc/classes/BaseButton.xml:119
msgid "Require just a press to consider the button clicked."
msgstr ""
-#: doc/classes/BaseButton.xml:121
+#: doc/classes/BaseButton.xml:122
msgid ""
"Require a press and a subsequent release before considering the button "
"clicked."
@@ -8978,8 +8360,8 @@ msgid ""
"the object."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:109 doc/classes/BaseMaterial3D.xml:275
-#: doc/classes/BaseMaterial3D.xml:296
+#: doc/classes/BaseMaterial3D.xml:109 doc/classes/BaseMaterial3D.xml:284
+#: doc/classes/BaseMaterial3D.xml:305
msgid ""
"Specifies the channel of the [member ao_texture] in which the ambient "
"occlusion information is stored. This is useful when you store the "
@@ -8990,29 +8372,45 @@ msgstr ""
#: doc/classes/BaseMaterial3D.xml:112
msgid ""
+"The color used by the backlight effect. Represents the light passing through "
+"an object."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:115
+msgid "If [code]true[/code], the backlight effect is enabled."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:118
+msgid ""
+"Texture used to control the backlight effect per-pixel. Added to [member "
+"backlight]."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:121
+msgid ""
"If [code]true[/code], the shader will keep the scale set for the mesh. "
"Otherwise the scale is lost when billboarding. Only applies when [member "
"billboard_mode] is [constant BILLBOARD_ENABLED]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:115
+#: doc/classes/BaseMaterial3D.xml:124
msgid "Controls how the object faces the camera. See [enum BillboardMode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:118
+#: doc/classes/BaseMaterial3D.xml:127
msgid ""
"The material's blend mode.\n"
"[b]Note:[/b] Values other than [code]Mix[/code] force the object into the "
"transparent pipeline. See [enum BlendMode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:122
+#: doc/classes/BaseMaterial3D.xml:131
msgid ""
"Sets the strength of the clearcoat effect. Setting to [code]0[/code] looks "
"the same as disabling the clearcoat effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:125
+#: doc/classes/BaseMaterial3D.xml:134
msgid ""
"If [code]true[/code], clearcoat rendering is enabled. Adds a secondary "
"transparent pass to the lighting calculation resulting in an added specular "
@@ -9020,42 +8418,42 @@ msgid ""
"can be either glossy or rough."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:128
+#: doc/classes/BaseMaterial3D.xml:137
msgid ""
"Sets the roughness of the clearcoat pass. A higher value results in a "
"smoother clearcoat while a lower value results in a rougher clearcoat."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:131
+#: doc/classes/BaseMaterial3D.xml:140
msgid ""
"Texture that defines the strength of the clearcoat effect and the glossiness "
"of the clearcoat. Strength is specified in the red channel while glossiness "
"is specified in the green channel."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:134
+#: doc/classes/BaseMaterial3D.xml:143
msgid ""
"Which side of the object is not drawn when backfaces are rendered. See [enum "
"CullMode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:137
+#: doc/classes/BaseMaterial3D.xml:146
msgid ""
"Determines when depth rendering takes place. See [enum DepthDrawMode]. See "
"also [member transparency]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:140
+#: doc/classes/BaseMaterial3D.xml:149
msgid "Texture that specifies the color of the detail overlay."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:143
+#: doc/classes/BaseMaterial3D.xml:152
msgid ""
"Specifies how the [member detail_albedo] should blend with the current "
"[code]ALBEDO[/code]. See [enum BlendMode] for options."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:146
+#: doc/classes/BaseMaterial3D.xml:155
msgid ""
"If [code]true[/code], enables the detail overlay. Detail is a second texture "
"that gets mixed over the surface of the object based on [member "
@@ -9063,99 +8461,99 @@ msgid ""
"between two different albedo/normal textures."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:149
+#: doc/classes/BaseMaterial3D.xml:158
msgid ""
"Texture used to specify how the detail textures get blended with the base "
"textures."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:152
+#: doc/classes/BaseMaterial3D.xml:161
msgid "Texture that specifies the per-pixel normal of the detail overlay."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:155
+#: doc/classes/BaseMaterial3D.xml:164
msgid ""
"Specifies whether to use [code]UV[/code] or [code]UV2[/code] for the detail "
"layer. See [enum DetailUV] for options."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:158
+#: doc/classes/BaseMaterial3D.xml:167
msgid ""
"The algorithm used for diffuse light scattering. See [enum DiffuseMode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:161
+#: doc/classes/BaseMaterial3D.xml:170
msgid "If [code]true[/code], the object receives no ambient light."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:164
+#: doc/classes/BaseMaterial3D.xml:173
msgid ""
"If [code]true[/code], the object receives no shadow that would otherwise be "
"cast onto it."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:167
+#: doc/classes/BaseMaterial3D.xml:176
msgid "Distance at which the object fades fully and is no longer visible."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:170
+#: doc/classes/BaseMaterial3D.xml:179
msgid ""
"Distance at which the object starts to fade. If the object is less than this "
"distance away it will appear normal."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:173
+#: doc/classes/BaseMaterial3D.xml:182
msgid ""
"Specifies which type of fade to use. Can be any of the [enum "
"DistanceFadeMode]s."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:176
+#: doc/classes/BaseMaterial3D.xml:185
msgid "The emitted light's color. See [member emission_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:179
+#: doc/classes/BaseMaterial3D.xml:188
msgid ""
"If [code]true[/code], the body emits light. Emitting light makes the object "
"appear brighter. The object can also cast light on other objects if a "
"[GIProbe] is used and this object is used in baked lighting."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:182
+#: doc/classes/BaseMaterial3D.xml:191
msgid "The emitted light's strength. See [member emission_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:185
+#: doc/classes/BaseMaterial3D.xml:194
msgid "Use [code]UV2[/code] to read from the [member emission_texture]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:188
+#: doc/classes/BaseMaterial3D.xml:197
msgid ""
"Sets how [member emission] interacts with [member emission_texture]. Can "
"either add or multiply. See [enum EmissionOperator] for options."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:191
+#: doc/classes/BaseMaterial3D.xml:200
msgid "Texture that specifies how much surface emits light at a given point."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:194
+#: doc/classes/BaseMaterial3D.xml:203
msgid ""
"If [code]true[/code], the object is rendered at the same size regardless of "
"distance."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:197
+#: doc/classes/BaseMaterial3D.xml:206
msgid ""
"If [code]true[/code], enables the vertex grow setting. See [member "
"grow_amount]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:200
+#: doc/classes/BaseMaterial3D.xml:209
msgid "Grows object vertices in the direction of their normals."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:221
+#: doc/classes/BaseMaterial3D.xml:230
msgid ""
"A high value makes the material appear more like a metal. Non-metals use "
"their albedo as the diffuse color and add diffuse to the specular "
@@ -9168,7 +8566,7 @@ msgid ""
"roughness]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:224
+#: doc/classes/BaseMaterial3D.xml:233
msgid ""
"Sets the size of the specular lobe. The specular lobe is the bright spot "
"that is reflected from light sources.\n"
@@ -9177,13 +8575,13 @@ msgid ""
"roughness]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:228
+#: doc/classes/BaseMaterial3D.xml:237
msgid ""
"Texture used to specify metallic for an object. This is multiplied by "
"[member metallic]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:231
+#: doc/classes/BaseMaterial3D.xml:240
msgid ""
"Specifies the channel of the [member metallic_texture] in which the metallic "
"information is stored. This is useful when you store the information for "
@@ -9192,21 +8590,21 @@ msgid ""
"you could reduce the number of textures you use."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:234
+#: doc/classes/BaseMaterial3D.xml:243
msgid ""
"If [code]true[/code], depth testing is disabled and the object will be drawn "
"in render order."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:237
+#: doc/classes/BaseMaterial3D.xml:246
msgid "If [code]true[/code], normal mapping is enabled."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:240
+#: doc/classes/BaseMaterial3D.xml:249
msgid "The strength of the normal map's effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:243
+#: doc/classes/BaseMaterial3D.xml:252
msgid ""
"Texture used to specify the normal at a given pixel. The "
"[code]normal_texture[/code] only uses the red and green channels. The normal "
@@ -9214,93 +8612,100 @@ msgid ""
"provided by the [Mesh]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:248
+#: doc/classes/BaseMaterial3D.xml:257
msgid ""
"The number of horizontal frames in the particle sprite sheet. Only enabled "
"when using [constant BILLBOARD_PARTICLES]. See [member billboard_mode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:251
+#: doc/classes/BaseMaterial3D.xml:260
msgid ""
"If [code]true[/code], particle animations are looped. Only enabled when "
"using [constant BILLBOARD_PARTICLES]. See [member billboard_mode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:254
+#: doc/classes/BaseMaterial3D.xml:263
msgid ""
"The number of vertical frames in the particle sprite sheet. Only enabled "
"when using [constant BILLBOARD_PARTICLES]. See [member billboard_mode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:257
+#: doc/classes/BaseMaterial3D.xml:266
msgid "The point size in pixels. See [member use_point_size]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:260
+#: doc/classes/BaseMaterial3D.xml:269
msgid ""
"Distance over which the fade effect takes place. The larger the distance the "
"longer it takes for an object to fade."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:263
+#: doc/classes/BaseMaterial3D.xml:272
msgid ""
"If [code]true[/code], the proximity fade effect is enabled. The proximity "
"fade effect fades out each pixel based on its distance to another object."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:266
+#: doc/classes/BaseMaterial3D.xml:275
msgid ""
"If [code]true[/code], the refraction effect is enabled. Distorts "
"transparency based on light from behind the object."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:269
+#: doc/classes/BaseMaterial3D.xml:278
msgid "The strength of the refraction effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:272
+#: doc/classes/BaseMaterial3D.xml:281
msgid ""
"Texture that controls the strength of the refraction per-pixel. Multiplied "
"by [member refraction_scale]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:278
+#: doc/classes/BaseMaterial3D.xml:287
msgid "Sets the strength of the rim lighting effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:281
+#: doc/classes/BaseMaterial3D.xml:290
msgid ""
"If [code]true[/code], rim effect is enabled. Rim lighting increases the "
"brightness at glancing angles on an object."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:284
+#: doc/classes/BaseMaterial3D.xml:293
msgid ""
"Texture used to set the strength of the rim lighting effect per-pixel. "
"Multiplied by [member rim]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:287
+#: doc/classes/BaseMaterial3D.xml:296
msgid ""
"The amount of to blend light and albedo color when rendering rim effect. If "
"[code]0[/code] the light color is used, while [code]1[/code] means albedo "
"color is used. An intermediate value generally works best."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:290
+#: doc/classes/BaseMaterial3D.xml:299
msgid ""
"Surface reflection. A value of [code]0[/code] represents a perfect mirror "
"while a value of [code]1[/code] completely blurs the reflection. See also "
"[member metallic]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:293
+#: doc/classes/BaseMaterial3D.xml:302
msgid ""
"Texture used to control the roughness per-pixel. Multiplied by [member "
"roughness]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:301
+#: doc/classes/BaseMaterial3D.xml:308
+msgid ""
+"Sets whether the shading takes place per-pixel or per-vertex. Per-vertex "
+"lighting is faster, making it the best choice for mobile applications, "
+"however it looks considerably worse than per-pixel."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:311
msgid ""
"If [code]true[/code], enables the \"shadow to opacity\" render mode where "
"lighting modifies the alpha so shadowed areas are opaque and non-shadowed "
@@ -9308,77 +8713,67 @@ msgid ""
"AR."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:304
+#: doc/classes/BaseMaterial3D.xml:314
msgid "The method for rendering the specular blob. See [enum SpecularMode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:307
+#: doc/classes/BaseMaterial3D.xml:317
msgid ""
"If [code]true[/code], subsurface scattering is enabled. Emulates light that "
"penetrates an object's surface, is scattered, and then emerges."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:312
+#: doc/classes/BaseMaterial3D.xml:320
+msgid ""
+"If [code]true[/code], subsurface scattering will use a special mode "
+"optimized for the color and density of human skin."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:323
msgid "The strength of the subsurface scattering effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:315
+#: doc/classes/BaseMaterial3D.xml:326
msgid ""
"Texture used to control the subsurface scattering strength. Stored in the "
"red texture channel. Multiplied by [member subsurf_scatter_strength]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:318
+#: doc/classes/BaseMaterial3D.xml:341
msgid "Filter flags for the texture. See [enum TextureFilter] for options."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:321
+#: doc/classes/BaseMaterial3D.xml:344
msgid "Repeat flags for the texture. See [enum TextureFilter] for options."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:324
-msgid ""
-"The color used by the transmission effect. Represents the light passing "
-"through an object."
-msgstr ""
-
-#: doc/classes/BaseMaterial3D.xml:327
-msgid "If [code]true[/code], the transmission effect is enabled."
-msgstr ""
-
-#: doc/classes/BaseMaterial3D.xml:330
-msgid ""
-"Texture used to control the transmission effect per-pixel. Added to [member "
-"transmission]."
-msgstr ""
-
-#: doc/classes/BaseMaterial3D.xml:333
+#: doc/classes/BaseMaterial3D.xml:347
msgid ""
"If [code]true[/code], transparency is enabled on the body. See also [member "
"blend_mode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:336
+#: doc/classes/BaseMaterial3D.xml:350
msgid ""
"If [code]true[/code], render point size can be changed.\n"
"[b]Note:[/b] this is only effective for objects whose geometry is point-"
"based rather than triangle-based. See also [member point_size]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:340
+#: doc/classes/BaseMaterial3D.xml:354
msgid ""
"How much to offset the [code]UV[/code] coordinates. This amount will be "
"added to [code]UV[/code] in the vertex function. This can be used to offset "
"a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:343
+#: doc/classes/BaseMaterial3D.xml:357
msgid ""
"How much to scale the [code]UV[/code] coordinates. This is multiplied by "
"[code]UV[/code] in the vertex function."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:346
+#: doc/classes/BaseMaterial3D.xml:360
msgid ""
"If [code]true[/code], instead of using [code]UV[/code] textures will use a "
"triplanar texture lookup to determine how to apply textures. Triplanar uses "
@@ -9392,32 +8787,32 @@ msgid ""
"when you are trying to achieve crisp texturing."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:349 doc/classes/BaseMaterial3D.xml:364
+#: doc/classes/BaseMaterial3D.xml:363 doc/classes/BaseMaterial3D.xml:378
msgid ""
"A lower number blends the texture more softly while a higher number blends "
"the texture more sharply."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:352
+#: doc/classes/BaseMaterial3D.xml:366
msgid ""
"If [code]true[/code], triplanar mapping for [code]UV[/code] is calculated in "
"world space rather than object local space. See also [member uv1_triplanar]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:355
+#: doc/classes/BaseMaterial3D.xml:369
msgid ""
"How much to offset the [code]UV2[/code] coordinates. This amount will be "
"added to [code]UV2[/code] in the vertex function. This can be used to offset "
"a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:358
+#: doc/classes/BaseMaterial3D.xml:372
msgid ""
"How much to scale the [code]UV2[/code] coordinates. This is multiplied by "
"[code]UV2[/code] in the vertex function."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:361
+#: doc/classes/BaseMaterial3D.xml:375
msgid ""
"If [code]true[/code], instead of using [code]UV2[/code] textures will use a "
"triplanar texture lookup to determine how to apply textures. Triplanar uses "
@@ -9431,368 +8826,443 @@ msgid ""
"when you are trying to achieve crisp texturing."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:367
+#: doc/classes/BaseMaterial3D.xml:381
msgid ""
"If [code]true[/code], triplanar mapping for [code]UV2[/code] is calculated "
"in world space rather than object local space. See also [member "
"uv2_triplanar]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:370
+#: doc/classes/BaseMaterial3D.xml:384
msgid ""
"If [code]true[/code], the model's vertex colors are processed as sRGB mode."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:373
+#: doc/classes/BaseMaterial3D.xml:387
msgid "If [code]true[/code], the vertex color is used as albedo color."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:378
+#: doc/classes/BaseMaterial3D.xml:392
msgid "Texture specifying per-pixel color."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:381
+#: doc/classes/BaseMaterial3D.xml:395
msgid "Texture specifying per-pixel metallic value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:384
+#: doc/classes/BaseMaterial3D.xml:398
msgid "Texture specifying per-pixel roughness value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:387
+#: doc/classes/BaseMaterial3D.xml:401
msgid "Texture specifying per-pixel emission color."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:390
+#: doc/classes/BaseMaterial3D.xml:404
msgid "Texture specifying per-pixel normal vector."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:393
+#: doc/classes/BaseMaterial3D.xml:407
msgid "Texture specifying per-pixel rim value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:396
+#: doc/classes/BaseMaterial3D.xml:410
msgid "Texture specifying per-pixel clearcoat value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:399
+#: doc/classes/BaseMaterial3D.xml:413
msgid ""
"Texture specifying per-pixel flowmap direction for use with [member "
"anisotropy]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:402
+#: doc/classes/BaseMaterial3D.xml:416
msgid "Texture specifying per-pixel ambient occlusion value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:405
+#: doc/classes/BaseMaterial3D.xml:419
msgid "Texture specifying per-pixel height."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:408
+#: doc/classes/BaseMaterial3D.xml:422
msgid "Texture specifying per-pixel subsurface scattering."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:411
-msgid "Texture specifying per-pixel transmission color."
+#: doc/classes/BaseMaterial3D.xml:425
+msgid "Texture specifying per-pixel transmittance for subsurface scattering."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:428
+msgid "Texture specifying per-pixel backlight color."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:414
+#: doc/classes/BaseMaterial3D.xml:431
msgid "Texture specifying per-pixel refraction strength."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:417
+#: doc/classes/BaseMaterial3D.xml:434
msgid "Texture specifying per-pixel detail mask blending value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:420
+#: doc/classes/BaseMaterial3D.xml:437
msgid "Texture specifying per-pixel detail color."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:423
+#: doc/classes/BaseMaterial3D.xml:440
msgid "Texture specifying per-pixel detail normal."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:428
+#: doc/classes/BaseMaterial3D.xml:443
+msgid "Texture holding ambient occlusion, roughness, and metallic."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:446
msgid "Represents the size of the [enum TextureParam] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:431
+#: doc/classes/BaseMaterial3D.xml:449 doc/classes/RenderingServer.xml:3774
+#: doc/classes/Viewport.xml:390
msgid ""
"The texture filter reads from the nearest pixel only. The simplest and "
"fastest method of filtering, but the texture will look pixelized."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:434 doc/classes/CanvasItem.xml:665
+#: doc/classes/BaseMaterial3D.xml:452 doc/classes/RenderingServer.xml:3777
+#: doc/classes/Viewport.xml:393
msgid ""
-"The texture filter blends between the nearest four pixels. Use this for most "
-"cases where you want to avoid a pixelated style."
+"The texture filter blends between the nearest 4 pixels. Use this when you "
+"want to avoid a pixelated style, but do not want mipmaps."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:455 doc/classes/RenderingServer.xml:3780
+#: doc/classes/Viewport.xml:396
+msgid ""
+"The texture filter reads from the nearest pixel in the nearest mipmap. The "
+"fastest way to read from textures with mipmaps."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:458
+msgid ""
+"The texture filter blends between the nearest 4 pixels and between the "
+"nearest 2 mipmaps. Use this for most cases as mipmaps are important to "
+"smooth out pixels that are far from the camera."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:445 doc/classes/CanvasItem.xml:676
+#: doc/classes/BaseMaterial3D.xml:461 doc/classes/RenderingServer.xml:3786
+msgid ""
+"The texture filter reads from the nearest pixel, but selects a mipmap based "
+"on the angle between the surface and the camera view. This reduces artifacts "
+"on surfaces that are almost in line with the camera."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:464 doc/classes/RenderingServer.xml:3789
+msgid ""
+"The texture filter blends between the nearest 4 pixels and selects a mipmap "
+"based on the angle between the surface and the camera view. This reduces "
+"artifacts on surfaces that are almost in line with the camera. This is the "
+"slowest of the filtering options, but results in the highest quality "
+"texturing."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:467 doc/classes/CanvasItem.xml:677
msgid "Represents the size of the [enum TextureFilter] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:448
+#: doc/classes/BaseMaterial3D.xml:470
msgid "Use [code]UV[/code] with the detail texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:451
+#: doc/classes/BaseMaterial3D.xml:473
msgid "Use [code]UV2[/code] with the detail texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:454
+#: doc/classes/BaseMaterial3D.xml:476
msgid "The material will not use transparency."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:457
+#: doc/classes/BaseMaterial3D.xml:479
msgid "The material will use the texture's alpha values for transparency."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:464
+#: doc/classes/BaseMaterial3D.xml:482
+msgid ""
+"The material will cut off all values below a threshold, the rest will remain "
+"opaque."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:485
+msgid ""
+"The material will use the texture's alpha value for transparency, but will "
+"still be rendered in the pre-pass."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:488
msgid "Represents the size of the [enum Transparency] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:467
+#: doc/classes/BaseMaterial3D.xml:491
msgid "The object will not receive shadows."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:470
+#: doc/classes/BaseMaterial3D.xml:494
msgid ""
"The object will be shaded per pixel. Useful for realistic shading effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:473
+#: doc/classes/BaseMaterial3D.xml:497
msgid ""
"The object will be shaded per vertex. Useful when you want cheaper shaders "
"and do not care about visual quality."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:476
+#: doc/classes/BaseMaterial3D.xml:500
msgid "Represents the size of the [enum ShadingMode] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:479
+#: doc/classes/BaseMaterial3D.xml:503
msgid "Constant for setting [member emission_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:482
+#: doc/classes/BaseMaterial3D.xml:506
msgid "Constant for setting [member normal_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:485
+#: doc/classes/BaseMaterial3D.xml:509
msgid "Constant for setting [member rim_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:488
+#: doc/classes/BaseMaterial3D.xml:512
msgid "Constant for setting [member clearcoat_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:491
+#: doc/classes/BaseMaterial3D.xml:515
msgid "Constant for setting [member anisotropy_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:494
+#: doc/classes/BaseMaterial3D.xml:518
msgid "Constant for setting [member ao_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:499
+#: doc/classes/BaseMaterial3D.xml:521
+msgid "Constant for setting [member heightmap_enabled]."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:524
msgid "Constant for setting [member subsurf_scatter_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:502
-msgid "Constant for setting [member transmission_enabled]."
+#: doc/classes/BaseMaterial3D.xml:527
+msgid "Constant for setting [member subsurf_scatter_transmittance_enabled]."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:530
+msgid "Constant for setting [member backlight_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:505
+#: doc/classes/BaseMaterial3D.xml:533
msgid "Constant for setting [member refraction_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:508
+#: doc/classes/BaseMaterial3D.xml:536
msgid "Constant for setting [member detail_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:511 doc/classes/EditorFeatureProfile.xml:148
+#: doc/classes/BaseMaterial3D.xml:539 doc/classes/EditorFeatureProfile.xml:148
msgid "Represents the size of the [enum Feature] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:514
+#: doc/classes/BaseMaterial3D.xml:542
msgid ""
"Default blend mode. The color of the object is blended over the background "
"based on the object's alpha value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:517
+#: doc/classes/BaseMaterial3D.xml:545
msgid "The color of the object is added to the background."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:520
+#: doc/classes/BaseMaterial3D.xml:548
msgid "The color of the object is subtracted from the background."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:523
+#: doc/classes/BaseMaterial3D.xml:551
msgid "The color of the object is multiplied by the background."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:526
+#: doc/classes/BaseMaterial3D.xml:554
msgid "Default depth draw mode. Depth is drawn only for opaque objects."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:529
+#: doc/classes/BaseMaterial3D.xml:557
msgid "Depth draw is calculated for both opaque and transparent objects."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:532
+#: doc/classes/BaseMaterial3D.xml:560
msgid "No depth draw."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:535
+#: doc/classes/BaseMaterial3D.xml:563
msgid "Default cull mode. The back of the object is culled when not visible."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:538
+#: doc/classes/BaseMaterial3D.xml:566
msgid "The front of the object is culled when not visible."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:541
+#: doc/classes/BaseMaterial3D.xml:569
msgid "No culling is performed."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:544
+#: doc/classes/BaseMaterial3D.xml:572
msgid ""
"Disables the depth test, so this object is drawn on top of all others. "
"However, objects drawn after it in the draw order may cover it."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:547
+#: doc/classes/BaseMaterial3D.xml:575
msgid "Set [code]ALBEDO[/code] to the per-vertex color specified in the mesh."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:550
+#: doc/classes/BaseMaterial3D.xml:578
msgid ""
"Vertex color is in sRGB space and needs to be converted to linear. Only "
"applies in the Vulkan renderer."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:553
+#: doc/classes/BaseMaterial3D.xml:581
msgid ""
"Uses point size to alter the size of primitive points. Also changes the "
"albedo texture lookup to use [code]POINT_COORD[/code] instead of [code]UV[/"
"code]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:556
+#: doc/classes/BaseMaterial3D.xml:584
msgid ""
"Object is scaled by depth so that it always appears the same size on screen."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:559
+#: doc/classes/BaseMaterial3D.xml:587
msgid ""
"Shader will keep the scale set for the mesh. Otherwise the scale is lost "
"when billboarding. Only applies when [member billboard_mode] is [constant "
"BILLBOARD_ENABLED]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:562 doc/classes/BaseMaterial3D.xml:568
+#: doc/classes/BaseMaterial3D.xml:590 doc/classes/BaseMaterial3D.xml:596
msgid ""
"Use triplanar texture lookup for all texture lookups that would normally use "
"[code]UV[/code]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:565 doc/classes/BaseMaterial3D.xml:571
+#: doc/classes/BaseMaterial3D.xml:593 doc/classes/BaseMaterial3D.xml:599
msgid ""
"Use triplanar texture lookup for all texture lookups that would normally use "
"[code]UV2[/code]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:574
+#: doc/classes/BaseMaterial3D.xml:602
msgid ""
"Use [code]UV2[/code] coordinates to look up from the [member ao_texture]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:577
+#: doc/classes/BaseMaterial3D.xml:605
msgid ""
"Use [code]UV2[/code] coordinates to look up from the [member "
"emission_texture]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:580
+#: doc/classes/BaseMaterial3D.xml:608
msgid "Forces the shader to convert albedo from sRGB space to linear space."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:583
+#: doc/classes/BaseMaterial3D.xml:611
msgid "Disables receiving shadows from other objects."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:586
+#: doc/classes/BaseMaterial3D.xml:614
msgid "Disables receiving ambient light."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:589
+#: doc/classes/BaseMaterial3D.xml:617
msgid "Enables the shadow to opacity feature."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:594
+#: doc/classes/BaseMaterial3D.xml:620 doc/classes/RenderingServer.xml:3801
+#: doc/classes/Viewport.xml:408
+msgid ""
+"Enables the texture to repeat when UV coordinates are outside the 0-1 range. "
+"If using one of the linear filtering modes, this can result in artifacts at "
+"the edges of a texture when the sampler filters across the edges of the "
+"texture."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:623
msgid ""
"Invert values read from a depth texture to convert them to height values "
"(heightmap)."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:599 doc/classes/CPUParticles2D.xml:355
-#: doc/classes/CPUParticles3D.xml:364 doc/classes/GeometryInstance3D.xml:100
+#: doc/classes/BaseMaterial3D.xml:626
+msgid ""
+"Enables the skin mode for subsurface scattering which is used to improve the "
+"look of subsurface scattering when used for human skin."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:629 doc/classes/CPUParticles2D.xml:355
+#: doc/classes/CPUParticles3D.xml:364 doc/classes/GeometryInstance3D.xml:118
#: doc/classes/ParticlesMaterial.xml:315
msgid "Represents the size of the [enum Flags] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:602
+#: doc/classes/BaseMaterial3D.xml:632
msgid "Default diffuse scattering algorithm."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:605
+#: doc/classes/BaseMaterial3D.xml:635
msgid "Diffuse scattering ignores roughness."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:608
+#: doc/classes/BaseMaterial3D.xml:638
msgid "Extends Lambert to cover more than 90 degrees when roughness increases."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:611
+#: doc/classes/BaseMaterial3D.xml:641
msgid "Attempts to use roughness to emulate microsurfacing."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:614
+#: doc/classes/BaseMaterial3D.xml:644
msgid "Uses a hard cut for lighting, with smoothing affected by roughness."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:617
+#: doc/classes/BaseMaterial3D.xml:647
msgid "Default specular blob."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:620 doc/classes/BaseMaterial3D.xml:623
+#: doc/classes/BaseMaterial3D.xml:650 doc/classes/BaseMaterial3D.xml:653
msgid "Older specular algorithm, included for compatibility."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:626
+#: doc/classes/BaseMaterial3D.xml:656
msgid "Toon blob which changes size based on roughness."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:629
+#: doc/classes/BaseMaterial3D.xml:659
msgid "No specular blob."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:632
+#: doc/classes/BaseMaterial3D.xml:662
msgid "Billboard mode is disabled."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:635
+#: doc/classes/BaseMaterial3D.xml:665
msgid "The object's Z axis will always face the camera."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:638
+#: doc/classes/BaseMaterial3D.xml:668
msgid "The object's X axis will always face the camera."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:641
+#: doc/classes/BaseMaterial3D.xml:671
msgid ""
"Used for particle systems when assigned to [GPUParticles3D] and "
"[CPUParticles3D] nodes. Enables [code]particles_anim_*[/code] properties.\n"
@@ -9800,45 +9270,45 @@ msgid ""
"anim_speed] should also be set to a positive value for the animation to play."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:645
+#: doc/classes/BaseMaterial3D.xml:675
msgid "Used to read from the red channel of a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:648
+#: doc/classes/BaseMaterial3D.xml:678
msgid "Used to read from the green channel of a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:651
+#: doc/classes/BaseMaterial3D.xml:681
msgid "Used to read from the blue channel of a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:654
+#: doc/classes/BaseMaterial3D.xml:684
msgid "Used to read from the alpha channel of a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:657
+#: doc/classes/BaseMaterial3D.xml:687
msgid "Currently unused."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:660
+#: doc/classes/BaseMaterial3D.xml:690
msgid "Adds the emission color to the color from the emission texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:663
+#: doc/classes/BaseMaterial3D.xml:693
msgid "Multiplies the emission color by the color from the emission texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:666
+#: doc/classes/BaseMaterial3D.xml:696
msgid "Do not use distance fade."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:669
+#: doc/classes/BaseMaterial3D.xml:699
msgid ""
"Smoothly fades the object out based on each pixel's distance from the camera "
"using the alpha channel."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:672
+#: doc/classes/BaseMaterial3D.xml:702
msgid ""
"Smoothly fades the object out based on each pixel's distance from the camera "
"using a dither approach. Dithering discards pixels based on a set pattern to "
@@ -9846,7 +9316,7 @@ msgid ""
"faster than [constant DISTANCE_FADE_PIXEL_ALPHA]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:675
+#: doc/classes/BaseMaterial3D.xml:705
msgid ""
"Smoothly fades the object out based on the object's distance from the camera "
"using a dither approach. Dithering discards pixels based on a set pattern to "
@@ -10520,176 +9990,181 @@ msgid ""
"scenes than manually changing the position of [CanvasItem]-based nodes.\n"
"This node is intended to be a simple helper to get things going quickly and "
"it may happen that more functionality is desired to change how the camera "
-"works. To make your own custom camera node, simply inherit from [Node2D] and "
-"change the transform of the canvas by calling get_viewport()."
-"set_canvas_transform(m) in [Viewport]."
+"works. To make your own custom camera node, inherit from [Node2D] and change "
+"the transform of the canvas by setting [member Viewport.canvas_transform] in "
+"[Viewport] (you can obtain the current [Viewport] by using [method Node."
+"get_viewport]).\n"
+"Note that the [Camera2D] node's [code]position[/code] doesn't represent the "
+"actual position of the screen, which may differ due to applied smoothing or "
+"limits. You can use [method get_camera_screen_center] to get the real "
+"position."
msgstr ""
-#: doc/classes/Camera2D.xml:17
+#: doc/classes/Camera2D.xml:18
msgid "Aligns the camera to the tracked node."
msgstr ""
-#: doc/classes/Camera2D.xml:24
+#: doc/classes/Camera2D.xml:25
msgid ""
"Removes any [Camera2D] from the ancestor [Viewport]'s internal currently-"
"assigned camera."
msgstr ""
-#: doc/classes/Camera2D.xml:31
+#: doc/classes/Camera2D.xml:32
msgid "Forces the camera to update scroll immediately."
msgstr ""
-#: doc/classes/Camera2D.xml:38
+#: doc/classes/Camera2D.xml:39
msgid "Returns the camera position."
msgstr ""
-#: doc/classes/Camera2D.xml:45
+#: doc/classes/Camera2D.xml:46
msgid ""
"Returns the location of the [Camera2D]'s screen-center, relative to the "
"origin."
msgstr ""
-#: doc/classes/Camera2D.xml:54
+#: doc/classes/Camera2D.xml:55
msgid ""
"Returns the specified margin. See also [member drag_margin_bottom], [member "
"drag_margin_top], [member drag_margin_left], and [member drag_margin_right]."
msgstr ""
-#: doc/classes/Camera2D.xml:63
+#: doc/classes/Camera2D.xml:64
msgid ""
"Returns the specified camera limit. See also [member limit_bottom], [member "
"limit_top], [member limit_left], and [member limit_right]."
msgstr ""
-#: doc/classes/Camera2D.xml:70
+#: doc/classes/Camera2D.xml:71
msgid ""
"Make this the current 2D camera for the scene (viewport and layer), in case "
"there are many cameras in the scene."
msgstr ""
-#: doc/classes/Camera2D.xml:77
+#: doc/classes/Camera2D.xml:78
msgid ""
"Sets the camera's position immediately to its current smoothing "
"destination.\n"
"This has no effect if smoothing is disabled."
msgstr ""
-#: doc/classes/Camera2D.xml:89
+#: doc/classes/Camera2D.xml:90
msgid ""
"Sets the specified margin. See also [member drag_margin_bottom], [member "
"drag_margin_top], [member drag_margin_left], and [member drag_margin_right]."
msgstr ""
-#: doc/classes/Camera2D.xml:100
+#: doc/classes/Camera2D.xml:101
msgid ""
"Sets the specified camera limit. See also [member limit_bottom], [member "
"limit_top], [member limit_left], and [member limit_right]."
msgstr ""
-#: doc/classes/Camera2D.xml:106
+#: doc/classes/Camera2D.xml:107
msgid "The Camera2D's anchor point. See [enum AnchorMode] constants."
msgstr ""
-#: doc/classes/Camera2D.xml:109
+#: doc/classes/Camera2D.xml:110
msgid ""
"If [code]true[/code], the camera is the active camera for the current scene. "
"Only one camera can be current, so setting a different camera [code]current[/"
"code] will disable this one."
msgstr ""
-#: doc/classes/Camera2D.xml:112
+#: doc/classes/Camera2D.xml:113
msgid ""
"The custom [Viewport] node attached to the [Camera2D]. If [code]null[/code] "
"or not a [Viewport], uses the default viewport instead."
msgstr ""
-#: doc/classes/Camera2D.xml:115
+#: doc/classes/Camera2D.xml:116
msgid ""
"Bottom margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-#: doc/classes/Camera2D.xml:118
+#: doc/classes/Camera2D.xml:119
msgid ""
"If [code]true[/code], the camera only moves when reaching the horizontal "
"drag margins. If [code]false[/code], the camera moves horizontally "
"regardless of margins."
msgstr ""
-#: doc/classes/Camera2D.xml:121
+#: doc/classes/Camera2D.xml:122
msgid ""
"Left margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-#: doc/classes/Camera2D.xml:124
+#: doc/classes/Camera2D.xml:125
msgid ""
"Right margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-#: doc/classes/Camera2D.xml:127
+#: doc/classes/Camera2D.xml:128
msgid ""
"Top margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-#: doc/classes/Camera2D.xml:130
+#: doc/classes/Camera2D.xml:131
msgid ""
"If [code]true[/code], the camera only moves when reaching the vertical drag "
"margins. If [code]false[/code], the camera moves vertically regardless of "
"margins."
msgstr ""
-#: doc/classes/Camera2D.xml:133
+#: doc/classes/Camera2D.xml:134
msgid ""
"If [code]true[/code], draws the camera's drag margin rectangle in the editor."
msgstr ""
-#: doc/classes/Camera2D.xml:136
+#: doc/classes/Camera2D.xml:137
msgid ""
"If [code]true[/code], draws the camera's limits rectangle in the editor."
msgstr ""
-#: doc/classes/Camera2D.xml:139
+#: doc/classes/Camera2D.xml:140
msgid ""
"If [code]true[/code], draws the camera's screen rectangle in the editor."
msgstr ""
-#: doc/classes/Camera2D.xml:142
+#: doc/classes/Camera2D.xml:143
msgid ""
"Bottom scroll limit in pixels. The camera stops moving when reaching this "
"value."
msgstr ""
-#: doc/classes/Camera2D.xml:145
+#: doc/classes/Camera2D.xml:146
msgid ""
"Left scroll limit in pixels. The camera stops moving when reaching this "
"value."
msgstr ""
-#: doc/classes/Camera2D.xml:148
+#: doc/classes/Camera2D.xml:149
msgid ""
"Right scroll limit in pixels. The camera stops moving when reaching this "
"value."
msgstr ""
-#: doc/classes/Camera2D.xml:151
+#: doc/classes/Camera2D.xml:152
msgid ""
"If [code]true[/code], the camera smoothly stops when reaches its limits."
msgstr ""
-#: doc/classes/Camera2D.xml:154
+#: doc/classes/Camera2D.xml:155
msgid ""
"Top scroll limit in pixels. The camera stops moving when reaching this value."
msgstr ""
-#: doc/classes/Camera2D.xml:157
+#: doc/classes/Camera2D.xml:158
msgid ""
"The camera's offset, useful for looking around or camera shake animations."
msgstr ""
-#: doc/classes/Camera2D.xml:160
+#: doc/classes/Camera2D.xml:161
msgid ""
"The horizontal offset of the camera, relative to the drag margins.\n"
"[b]Note:[/b] Offset H is used only to force offset relative to margins. It's "
@@ -10697,33 +10172,33 @@ msgid ""
"initial offset."
msgstr ""
-#: doc/classes/Camera2D.xml:164
+#: doc/classes/Camera2D.xml:165
msgid ""
"The vertical offset of the camera, relative to the drag margins.\n"
"[b]Note:[/b] Used the same as [member offset_h]."
msgstr ""
-#: doc/classes/Camera2D.xml:168
+#: doc/classes/Camera2D.xml:169
msgid "The camera's process callback. See [enum Camera2DProcessMode]."
msgstr ""
-#: doc/classes/Camera2D.xml:171
+#: doc/classes/Camera2D.xml:172
msgid "If [code]true[/code], the camera rotates with the target."
msgstr ""
-#: doc/classes/Camera2D.xml:174
+#: doc/classes/Camera2D.xml:175
msgid ""
"If [code]true[/code], the camera smoothly moves towards the target at "
"[member smoothing_speed]."
msgstr ""
-#: doc/classes/Camera2D.xml:177
+#: doc/classes/Camera2D.xml:178
msgid ""
"Speed in pixels per second of the camera's smoothing effect when [member "
"smoothing_enabled] is [code]true[/code]."
msgstr ""
-#: doc/classes/Camera2D.xml:180
+#: doc/classes/Camera2D.xml:181
msgid ""
"The camera's zoom relative to the viewport. Values larger than "
"[code]Vector2(1, 1)[/code] zoom out and smaller values zoom in. For an "
@@ -10731,23 +10206,23 @@ msgid ""
"[code]Vector2(4, 4)[/code] for a 4× zoom-out."
msgstr ""
-#: doc/classes/Camera2D.xml:185
+#: doc/classes/Camera2D.xml:186
msgid ""
"The camera's position is fixed so that the top-left corner is always at the "
"origin."
msgstr ""
-#: doc/classes/Camera2D.xml:188
+#: doc/classes/Camera2D.xml:189
msgid ""
"The camera's position takes into account vertical/horizontal offsets and the "
"screen size."
msgstr ""
-#: doc/classes/Camera2D.xml:191 doc/classes/ClippedCamera3D.xml:104
+#: doc/classes/Camera2D.xml:192 doc/classes/ClippedCamera3D.xml:104
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
-#: doc/classes/Camera2D.xml:194 doc/classes/ClippedCamera3D.xml:107
+#: doc/classes/Camera2D.xml:195 doc/classes/ClippedCamera3D.xml:107
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -11009,6 +10484,72 @@ msgid ""
"Audio's [code]pitch shift[/code])."
msgstr ""
+#: doc/classes/CameraEffects.xml:4
+msgid ""
+"Contains camera-specific effects such as depth of field and exposure "
+"override."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:7
+msgid ""
+"Contains camera-specific effects such as depth of field and exposure "
+"override.\n"
+"See also [Environment] for general 3D environment settings."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:16
+msgid ""
+"The amount of blur for both near and far depth-of-field effects. The amount "
+"of blur increases the radius of the blur effect, making the affected area "
+"blurrier. However, If the amount is too high, you might start to see lines "
+"appearing, especially when using a low quality blur."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:19
+msgid ""
+"The distance from the camera where the far blur effect affects the rendering."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:22
+msgid ""
+"If [code]true[/code], enables the depth-of-field far blur effect. This has a "
+"significant performance cost. Consider disabling it in scenes where there "
+"are no far away objects."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:25
+msgid "The length of the transition between the no-blur area and far blur."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:28
+msgid ""
+"Distance from the camera where the near blur effect affects the rendering."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:31
+msgid ""
+"If [code]true[/code], enables the depth-of-field near blur effect. This has "
+"a significant performance cost. Consider disabling it in scenes where there "
+"are no nearby objects."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:34
+msgid "The length of the transition between the near blur and no-blur area."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:37
+msgid ""
+"The exposure override value to use. Higher values will result in a brighter "
+"scene. Only effective if [member override_exposure_enable] is [code]true[/"
+"code]."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:40
+msgid ""
+"If [code]true[/code], overrides the manual or automatic exposure defined in "
+"the [Environment] with the value in [member override_exposure]."
+msgstr ""
+
#: doc/classes/CameraFeed.xml:4
msgid ""
"A camera feed gives you access to a single physical camera attached to your "
@@ -11019,7 +10560,7 @@ msgstr ""
msgid ""
"A camera feed gives you access to a single physical camera attached to your "
"device. When enabled, Godot will start capturing frames from the camera "
-"which can then be used.\n"
+"which can then be used. See also [CameraServer].\n"
"[b]Note:[/b] Many cameras will return YCbCr images which are split into two "
"textures and need to be combined in a shader. Godot does this automatically "
"for you if you set the environment to show the camera image in the "
@@ -11034,50 +10575,54 @@ msgstr ""
msgid ""
"The [CameraServer] keeps track of different cameras accessible in Godot. "
"These are external cameras such as webcams or the cameras on your phone.\n"
-"It is notably used to provide AR modules with a video feed from the camera."
+"It is notably used to provide AR modules with a video feed from the camera.\n"
+"[b]Note:[/b] This class is currently only implemented on macOS and iOS. On "
+"other platforms, no [CameraFeed]s will be available."
msgstr ""
-#: doc/classes/CameraServer.xml:19
-msgid "Adds a camera feed to the camera server."
+#: doc/classes/CameraServer.xml:20
+msgid "Adds the camera [code]feed[/code] to the camera server."
msgstr ""
-#: doc/classes/CameraServer.xml:26
+#: doc/classes/CameraServer.xml:27
msgid "Returns an array of [CameraFeed]s."
msgstr ""
-#: doc/classes/CameraServer.xml:35
-msgid "Returns the [CameraFeed] with this id."
+#: doc/classes/CameraServer.xml:36
+msgid ""
+"Returns the [CameraFeed] corresponding to the camera with the given "
+"[code]index[/code]."
msgstr ""
-#: doc/classes/CameraServer.xml:42
+#: doc/classes/CameraServer.xml:43
msgid "Returns the number of [CameraFeed]s registered."
msgstr ""
-#: doc/classes/CameraServer.xml:51
-msgid "Removes a [CameraFeed]."
+#: doc/classes/CameraServer.xml:52
+msgid "Removes the specified camera [code]feed[/code]."
msgstr ""
-#: doc/classes/CameraServer.xml:60
-msgid "Emitted when a [CameraFeed] is added (e.g. webcam is plugged in)."
+#: doc/classes/CameraServer.xml:61
+msgid "Emitted when a [CameraFeed] is added (e.g. a webcam is plugged in)."
msgstr ""
-#: doc/classes/CameraServer.xml:67
-msgid "Emitted when a [CameraFeed] is removed (e.g. webcam is unplugged)."
+#: doc/classes/CameraServer.xml:68
+msgid "Emitted when a [CameraFeed] is removed (e.g. a webcam is unplugged)."
msgstr ""
-#: doc/classes/CameraServer.xml:73
+#: doc/classes/CameraServer.xml:74
msgid "The RGBA camera image."
msgstr ""
-#: doc/classes/CameraServer.xml:76
-msgid "The YCbCr camera image."
+#: doc/classes/CameraServer.xml:77
+msgid "The [url=https://en.wikipedia.org/wiki/YCbCr]YCbCr[/url] camera image."
msgstr ""
-#: doc/classes/CameraServer.xml:79
+#: doc/classes/CameraServer.xml:80
msgid "The Y component camera image."
msgstr ""
-#: doc/classes/CameraServer.xml:82
+#: doc/classes/CameraServer.xml:83
msgid "The CbCr component camera image."
msgstr ""
@@ -11133,97 +10678,100 @@ msgid ""
"its children) and self modulation (only for itself), as well as its blend "
"mode.\n"
"Ultimately, a transform notification can be requested, which will notify the "
-"node that its global position changed in case the parent tree changed."
+"node that its global position changed in case the parent tree changed.\n"
+"[b]Note:[/b] Unless otherwise specified, all methods that have angle "
+"parameters must have angles specified as [i]radians[/i]. To convert degrees "
+"to radians, use [method @GDScript.deg2rad]."
msgstr ""
-#: doc/classes/CanvasItem.xml:14 doc/classes/CanvasLayer.xml:10
+#: doc/classes/CanvasItem.xml:15 doc/classes/CanvasLayer.xml:10
#: doc/classes/InputEvent.xml:11 doc/classes/Viewport.xml:15
msgid "https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html"
msgstr ""
-#: doc/classes/CanvasItem.xml:15 doc/classes/Control.xml:19
+#: doc/classes/CanvasItem.xml:16 doc/classes/Control.xml:19
#: doc/classes/Node2D.xml:10
msgid ""
"https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html"
msgstr ""
-#: doc/classes/CanvasItem.xml:22
+#: doc/classes/CanvasItem.xml:23
msgid ""
"Overridable function called by the engine (if defined) to draw the canvas "
"item."
msgstr ""
-#: doc/classes/CanvasItem.xml:43
+#: doc/classes/CanvasItem.xml:44
msgid ""
"Draws an arc between the given angles. The larger the value of "
"[code]point_count[/code], the smoother the curve."
msgstr ""
-#: doc/classes/CanvasItem.xml:60
+#: doc/classes/CanvasItem.xml:61
msgid ""
"Draws a string character using a custom font. Returns the advance, depending "
"on the character width and kerning with an optional next character."
msgstr ""
-#: doc/classes/CanvasItem.xml:73
+#: doc/classes/CanvasItem.xml:74
msgid "Draws a colored circle."
msgstr ""
-#: doc/classes/CanvasItem.xml:98
+#: doc/classes/CanvasItem.xml:99
msgid "Draws a colored polygon of any amount of points, convex or concave."
msgstr ""
-#: doc/classes/CanvasItem.xml:113
+#: doc/classes/CanvasItem.xml:114
msgid "Draws a line from a 2D point to another, with a given color and width."
msgstr ""
-#: doc/classes/CanvasItem.xml:138
+#: doc/classes/CanvasItem.xml:139
msgid ""
"Draws a [Mesh] in 2D, using the provided texture. See [MeshInstance2D] for "
"related documentation."
msgstr ""
-#: doc/classes/CanvasItem.xml:151
+#: doc/classes/CanvasItem.xml:152
msgid "Draws multiple, parallel lines with a uniform [code]color[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:164
+#: doc/classes/CanvasItem.xml:165
msgid ""
"Draws multiple, parallel lines with a uniform [code]width[/code] and segment-"
"by-segment coloring. Colors assigned to line segments match by index between "
"[code]points[/code] and [code]colors[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:185
+#: doc/classes/CanvasItem.xml:186
msgid ""
"Draws a [MultiMesh] in 2D with the provided texture. See "
"[MultiMeshInstance2D] for related documentation."
msgstr ""
-#: doc/classes/CanvasItem.xml:210
+#: doc/classes/CanvasItem.xml:211
msgid "Draws a polygon of any amount of points, convex or concave."
msgstr ""
-#: doc/classes/CanvasItem.xml:223
+#: doc/classes/CanvasItem.xml:224
msgid ""
"Draws interconnected line segments with a uniform [code]color[/code] and "
"[code]width[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:236
+#: doc/classes/CanvasItem.xml:237
msgid ""
"Draws interconnected line segments with a uniform [code]width[/code] and "
"segment-by-segment coloring. Colors assigned to line segments match by index "
"between [code]points[/code] and [code]colors[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:263
+#: doc/classes/CanvasItem.xml:264
msgid ""
"Draws a custom primitive. 1 point for a point, 2 points for a line, 3 points "
"for a triangle, and 4 points for a quad."
msgstr ""
-#: doc/classes/CanvasItem.xml:278
+#: doc/classes/CanvasItem.xml:279
msgid ""
"Draws a rectangle. If [code]filled[/code] is [code]true[/code], the "
"rectangle will be filled with the [code]color[/code] specified. If "
@@ -11233,272 +10781,278 @@ msgid ""
"[code]false[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:292
+#: doc/classes/CanvasItem.xml:293
msgid ""
"Sets a custom transform for drawing via components. Anything drawn "
"afterwards will be transformed by this."
msgstr ""
-#: doc/classes/CanvasItem.xml:301
+#: doc/classes/CanvasItem.xml:302
msgid ""
"Sets a custom transform for drawing via matrix. Anything drawn afterwards "
"will be transformed by this."
msgstr ""
-#: doc/classes/CanvasItem.xml:318
+#: doc/classes/CanvasItem.xml:319
msgid "Draws a string using a custom font."
msgstr ""
-#: doc/classes/CanvasItem.xml:329
+#: doc/classes/CanvasItem.xml:330
msgid "Draws a styled rectangle."
msgstr ""
-#: doc/classes/CanvasItem.xml:352
+#: doc/classes/CanvasItem.xml:353
msgid "Draws a texture at a given position."
msgstr ""
-#: doc/classes/CanvasItem.xml:379
+#: doc/classes/CanvasItem.xml:380
msgid ""
"Draws a textured rectangle at a given position, optionally modulated by a "
"color. If [code]transpose[/code] is [code]true[/code], the texture will have "
"its X and Y coordinates swapped."
msgstr ""
-#: doc/classes/CanvasItem.xml:408
+#: doc/classes/CanvasItem.xml:409
msgid ""
"Draws a textured rectangle region at a given position, optionally modulated "
"by a color. If [code]transpose[/code] is [code]true[/code], the texture will "
"have its X and Y coordinates swapped."
msgstr ""
-#: doc/classes/CanvasItem.xml:415 doc/classes/Node3D.xml:18
+#: doc/classes/CanvasItem.xml:416 doc/classes/Node3D.xml:19
msgid ""
"Forces the transform to update. Transform changes in physics are not instant "
"for performance reasons. Transforms are accumulated and then set. Use this "
"if you need an up-to-date transform when doing physics operations."
msgstr ""
-#: doc/classes/CanvasItem.xml:422
+#: doc/classes/CanvasItem.xml:423
msgid "Returns the [RID] of the [World2D] canvas where this item is in."
msgstr ""
-#: doc/classes/CanvasItem.xml:429
+#: doc/classes/CanvasItem.xml:430
msgid "Returns the canvas item RID used by [RenderingServer] for this item."
msgstr ""
-#: doc/classes/CanvasItem.xml:436
+#: doc/classes/CanvasItem.xml:437
msgid "Returns the transform matrix of this item's canvas."
msgstr ""
-#: doc/classes/CanvasItem.xml:443
+#: doc/classes/CanvasItem.xml:444
msgid "Returns the global position of the mouse."
msgstr ""
-#: doc/classes/CanvasItem.xml:450
+#: doc/classes/CanvasItem.xml:451
msgid "Returns the global transform matrix of this item."
msgstr ""
-#: doc/classes/CanvasItem.xml:457
+#: doc/classes/CanvasItem.xml:458
msgid ""
"Returns the global transform matrix of this item in relation to the canvas."
msgstr ""
-#: doc/classes/CanvasItem.xml:464
+#: doc/classes/CanvasItem.xml:465
msgid "Returns the mouse position relative to this item's position."
msgstr ""
-#: doc/classes/CanvasItem.xml:471
+#: doc/classes/CanvasItem.xml:472
msgid "Returns the transform matrix of this item."
msgstr ""
-#: doc/classes/CanvasItem.xml:478
+#: doc/classes/CanvasItem.xml:479
msgid "Returns the viewport's boundaries as a [Rect2]."
msgstr ""
-#: doc/classes/CanvasItem.xml:485
+#: doc/classes/CanvasItem.xml:486
msgid "Returns this item's transform in relation to the viewport."
msgstr ""
-#: doc/classes/CanvasItem.xml:492
+#: doc/classes/CanvasItem.xml:493
msgid "Returns the [World2D] where this item is in."
msgstr ""
-#: doc/classes/CanvasItem.xml:499
+#: doc/classes/CanvasItem.xml:500
msgid "Hide the [CanvasItem] if it's currently visible."
msgstr ""
-#: doc/classes/CanvasItem.xml:506
+#: doc/classes/CanvasItem.xml:507
msgid ""
"Returns [code]true[/code] if local transform notifications are communicated "
"to children."
msgstr ""
-#: doc/classes/CanvasItem.xml:513
+#: doc/classes/CanvasItem.xml:514
msgid ""
"Returns [code]true[/code] if the node is set as top-level. See [method "
"set_as_toplevel]."
msgstr ""
-#: doc/classes/CanvasItem.xml:520
+#: doc/classes/CanvasItem.xml:521
msgid ""
"Returns [code]true[/code] if global transform notifications are communicated "
"to children."
msgstr ""
-#: doc/classes/CanvasItem.xml:527
+#: doc/classes/CanvasItem.xml:528
msgid ""
"Returns [code]true[/code] if the node is present in the [SceneTree], its "
"[member visible] property is [code]true[/code] and its inherited visibility "
"is also [code]true[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:536
+#: doc/classes/CanvasItem.xml:537
msgid "Assigns [code]screen_point[/code] as this node's new local transform."
msgstr ""
-#: doc/classes/CanvasItem.xml:545
+#: doc/classes/CanvasItem.xml:546
msgid ""
"Transformations issued by [code]event[/code]'s inputs are applied in local "
"space instead of global space."
msgstr ""
-#: doc/classes/CanvasItem.xml:554
+#: doc/classes/CanvasItem.xml:555
msgid ""
"If [code]enable[/code] is [code]true[/code], the node won't inherit its "
"transform from parent canvas items."
msgstr ""
-#: doc/classes/CanvasItem.xml:563
+#: doc/classes/CanvasItem.xml:564
msgid ""
"If [code]enable[/code] is [code]true[/code], children will be updated with "
"local transform data."
msgstr ""
-#: doc/classes/CanvasItem.xml:572
+#: doc/classes/CanvasItem.xml:573
msgid ""
"If [code]enable[/code] is [code]true[/code], children will be updated with "
"global transform data."
msgstr ""
-#: doc/classes/CanvasItem.xml:579
+#: doc/classes/CanvasItem.xml:580
msgid ""
"Show the [CanvasItem] if it's currently hidden. For controls that inherit "
"[Popup], the correct way to make them visible is to call one of the multiple "
"[code]popup*()[/code] functions instead."
msgstr ""
-#: doc/classes/CanvasItem.xml:586
+#: doc/classes/CanvasItem.xml:587
msgid ""
"Queue the [CanvasItem] for update. [constant NOTIFICATION_DRAW] will be "
"called on idle time to request redraw."
msgstr ""
-#: doc/classes/CanvasItem.xml:592
+#: doc/classes/CanvasItem.xml:593
msgid ""
"The rendering layers in which this [CanvasItem] responds to [Light2D] nodes."
msgstr ""
-#: doc/classes/CanvasItem.xml:595
+#: doc/classes/CanvasItem.xml:596
msgid "The material applied to textures on this [CanvasItem]."
msgstr ""
-#: doc/classes/CanvasItem.xml:598
+#: doc/classes/CanvasItem.xml:599
msgid "The color applied to textures on this [CanvasItem]."
msgstr ""
-#: doc/classes/CanvasItem.xml:601
+#: doc/classes/CanvasItem.xml:602
msgid ""
"The color applied to textures on this [CanvasItem]. This is not inherited by "
"children [CanvasItem]s."
msgstr ""
-#: doc/classes/CanvasItem.xml:604
+#: doc/classes/CanvasItem.xml:605
msgid "If [code]true[/code], the object draws behind its parent."
msgstr ""
-#: doc/classes/CanvasItem.xml:607
+#: doc/classes/CanvasItem.xml:608
msgid "If [code]true[/code], the object draws on top of its parent."
msgstr ""
-#: doc/classes/CanvasItem.xml:614
+#: doc/classes/CanvasItem.xml:615
msgid ""
"If [code]true[/code], the parent [CanvasItem]'s [member material] property "
"is used as this one's material."
msgstr ""
-#: doc/classes/CanvasItem.xml:617
+#: doc/classes/CanvasItem.xml:618
msgid ""
"If [code]true[/code], this [CanvasItem] is drawn. For controls that inherit "
"[Popup], the correct way to make them visible is to call one of the multiple "
"[code]popup*()[/code] functions instead."
msgstr ""
-#: doc/classes/CanvasItem.xml:623
+#: doc/classes/CanvasItem.xml:624
msgid ""
"Emitted when the [CanvasItem] must redraw. This can only be connected "
"realtime, as deferred will not allow drawing."
msgstr ""
-#: doc/classes/CanvasItem.xml:628
+#: doc/classes/CanvasItem.xml:629
msgid "Emitted when becoming hidden."
msgstr ""
-#: doc/classes/CanvasItem.xml:633
+#: doc/classes/CanvasItem.xml:634
msgid "Emitted when the item rect has changed."
msgstr ""
-#: doc/classes/CanvasItem.xml:638
+#: doc/classes/CanvasItem.xml:639
msgid "Emitted when the visibility (hidden/visible) changes."
msgstr ""
-#: doc/classes/CanvasItem.xml:644
+#: doc/classes/CanvasItem.xml:645
msgid ""
"The [CanvasItem]'s transform has changed. This notification is only received "
"if enabled by [method set_notify_transform] or [method "
"set_notify_local_transform]."
msgstr ""
-#: doc/classes/CanvasItem.xml:647
+#: doc/classes/CanvasItem.xml:648
msgid "The [CanvasItem] is requested to draw."
msgstr ""
-#: doc/classes/CanvasItem.xml:650
+#: doc/classes/CanvasItem.xml:651
msgid "The [CanvasItem]'s visibility has changed."
msgstr ""
-#: doc/classes/CanvasItem.xml:653
+#: doc/classes/CanvasItem.xml:654
msgid "The [CanvasItem] has entered the canvas."
msgstr ""
-#: doc/classes/CanvasItem.xml:656
+#: doc/classes/CanvasItem.xml:657
msgid "The [CanvasItem] has exited the canvas."
msgstr ""
-#: doc/classes/CanvasItem.xml:659 doc/classes/CanvasItem.xml:679
+#: doc/classes/CanvasItem.xml:660 doc/classes/CanvasItem.xml:680
msgid "The [CanvasItem] will inherit the filter from its parent."
msgstr ""
-#: doc/classes/CanvasItem.xml:662
+#: doc/classes/CanvasItem.xml:663
msgid ""
"The texture filter reads from the nearest pixel only. The simplest and "
"fastest method of filtering. Useful for pixel art."
msgstr ""
-#: doc/classes/CanvasItem.xml:682
+#: doc/classes/CanvasItem.xml:666
+msgid ""
+"The texture filter blends between the nearest four pixels. Use this for most "
+"cases where you want to avoid a pixelated style."
+msgstr ""
+
+#: doc/classes/CanvasItem.xml:683
msgid "Texture will not repeat."
msgstr ""
-#: doc/classes/CanvasItem.xml:685
+#: doc/classes/CanvasItem.xml:686
msgid "Texture will repeat normally."
msgstr ""
-#: doc/classes/CanvasItem.xml:688
+#: doc/classes/CanvasItem.xml:689
msgid ""
"Texture will repeat in a 2x2 tiled mode, where elements at even positions "
"are mirrored."
msgstr ""
-#: doc/classes/CanvasItem.xml:691
+#: doc/classes/CanvasItem.xml:692
msgid "Represents the size of the [enum TextureRepeat] enum."
msgstr ""
@@ -12686,25 +12240,24 @@ msgid ""
"component."
msgstr ""
-#: doc/classes/Color.xml:158
+#: doc/classes/Color.xml:160
msgid ""
-"Returns a new color resulting from making this color lighter by the "
-"specified percentage (ratio from 0 to 1).\n"
+"Returns the linear interpolation with another color. The interpolation "
+"factor [code]t[/code] is between 0 and 1.\n"
"[codeblock]\n"
-"var green = Color(0.0, 1.0, 0.0)\n"
-"var lightgreen = green.lightened(0.2) # 20% lighter than regular green\n"
+"var c1 = Color(1.0, 0.0, 0.0)\n"
+"var c2 = Color(0.0, 1.0, 0.0)\n"
+"var li_c = c1.lerp(c2, 0.5) # A color of an RGBA(128, 128, 0, 255)\n"
"[/codeblock]"
msgstr ""
-#: doc/classes/Color.xml:173
+#: doc/classes/Color.xml:174
msgid ""
-"Returns the linear interpolation with another color. The interpolation "
-"factor [code]t[/code] is between 0 and 1.\n"
+"Returns a new color resulting from making this color lighter by the "
+"specified percentage (ratio from 0 to 1).\n"
"[codeblock]\n"
-"var c1 = Color(1.0, 0.0, 0.0)\n"
-"var c2 = Color(0.0, 1.0, 0.0)\n"
-"var li_c = c1.linear_interpolate(c2, 0.5) # A color of an RGBA(128, 128, 0, "
-"255)\n"
+"var green = Color(0.0, 1.0, 0.0)\n"
+"var lightgreen = green.lightened(0.2) # 20% lighter than regular green\n"
"[/codeblock]"
msgstr ""
@@ -13726,7 +13279,7 @@ msgid ""
msgstr ""
#: doc/classes/ConeTwistJoint3D.xml:77 doc/classes/Generic6DOFJoint3D.xml:404
-#: doc/classes/HingeJoint3D.xml:109 doc/classes/Light3D.xml:124
+#: doc/classes/HingeJoint3D.xml:109 doc/classes/Light3D.xml:145
#: doc/classes/SliderJoint3D.xml:170
msgid "Represents the size of the [enum Param] enum."
msgstr ""
@@ -14610,8 +14163,8 @@ msgstr ""
#: doc/classes/Control.xml:801
msgid ""
"Tells Godot which node it should give keyboard focus to if the user presses "
-"Tab on a keyboard by default. You can change the key by editing the "
-"[code]ui_focus_next[/code] input action.\n"
+"[kbd]Tab[/kbd] on a keyboard by default. You can change the key by editing "
+"the [code]ui_focus_next[/code] input action.\n"
"If this property is not set, Godot will select a \"best guess\" based on "
"surrounding nodes in the scene tree."
msgstr ""
@@ -14619,8 +14172,8 @@ msgstr ""
#: doc/classes/Control.xml:805
msgid ""
"Tells Godot which node it should give keyboard focus to if the user presses "
-"Shift+Tab on a keyboard by default. You can change the key by editing the "
-"[code]ui_focus_prev[/code] input action.\n"
+"[kbd]Shift + Tab[/kbd] on a keyboard by default. You can change the key by "
+"editing the [code]ui_focus_prev[/code] input action.\n"
"If this property is not set, Godot will select a \"best guess\" based on "
"surrounding nodes in the scene tree."
msgstr ""
@@ -14702,9 +14255,9 @@ msgstr ""
#: doc/classes/Control.xml:841
msgid ""
-"Enables whether rendering of children should be clipped to this control's "
-"rectangle. If [code]true[/code], parts of a child which would be visibly "
-"outside of this control's rectangle will not be rendered."
+"Enables whether rendering of [CanvasItem] based children should be clipped "
+"to this control's rectangle. If [code]true[/code], parts of a child which "
+"would be visibly outside of this control's rectangle will not be rendered."
msgstr ""
#: doc/classes/Control.xml:844
@@ -16860,6 +16413,172 @@ msgid ""
"stiffness multiplied by the size difference from its resting length."
msgstr ""
+#: doc/classes/Decal.xml:4
+msgid "Node that projects a texture onto a [MeshInstance3D]."
+msgstr ""
+
+#: doc/classes/Decal.xml:7
+msgid ""
+"[Decal]s are used to project a texture onto a [Mesh] in the scene. Use "
+"Decals to add detail to a scene without affecting the underlying [Mesh]. "
+"They are often used to add weathering to building, add dirt or mud to the "
+"ground, or add variety to props. Decals can be moved at any time, making "
+"them suitable for things like blob shadows or laser sight dots.\n"
+"They are made of an [AABB] and a group of [Texture2D]s specifying [Color], "
+"normal, ORM (ambient occlusion, roughness, metallic), and emission. Decals "
+"are projected within their [AABB] so altering the orientation of the Decal "
+"affects the direction in which they are projected. By default, Decals are "
+"projected down (i.e. from positive Y to negative Y).\n"
+"The [Texture2D]s associated with the Decal are automatically stored in a "
+"texture atlas which is used for drawing the decals so all decals can be "
+"drawn at once. Godot uses clustered decals, meaning they are stored in "
+"cluster data and drawn when the mesh is drawn, they are not drawn as a "
+"postprocessing effect after."
+msgstr ""
+
+#: doc/classes/Decal.xml:20
+msgid ""
+"Returns the [Texture2D] associated with the specified [enum DecalTexture]. "
+"This is a convenience method, in most cases you should access the texture "
+"directly. \n"
+"For example, instead of [code]albedo_tex = $Decal.get_texture(Decal."
+"TEXTURE_ALBEDO)[/code], use [code]albedo_tex = $Decal.texture_albedo[/"
+"code].\n"
+"One case where this is better than accessing the texture directly is when "
+"you want to copy one Decal's textures to another. For example:\n"
+"[codeblock]\n"
+"for i in Decal.TEXTURE_MAX:\n"
+" $NewDecal.set_texture(i, $OldDecal.get_texture(i))\n"
+"[/codeblock]"
+msgstr ""
+
+#: doc/classes/Decal.xml:37
+msgid ""
+"Sets the [Texture2D] associated with the specified [enum DecalTexture]. This "
+"is a convenience method, in most cases you should access the texture "
+"directly. \n"
+"For example, instead of [code]$Decal.set_texture(Decal.TEXTURE_ALBEDO, "
+"albedo_tex)[/code], use [code]$Decal.texture_albedo = albedo_tex[/code].\n"
+"One case where this is better than accessing the texture directly is when "
+"you want to copy one Decal's textures to another. For example:\n"
+"[codeblock]\n"
+"for i in Decal.TEXTURE_MAX:\n"
+" $NewDecal.set_texture(i, $OldDecal.get_texture(i))\n"
+"[/codeblock]"
+msgstr ""
+
+#: doc/classes/Decal.xml:49
+msgid ""
+"Blends the albedo [Color] of the decal with albedo [Color] of the underlying "
+"mesh."
+msgstr ""
+
+#: doc/classes/Decal.xml:52
+msgid ""
+"Specifies which [member VisualInstance3D.layers] this decal will project on. "
+"By default, Decals affect all layers. This is used so you can specify which "
+"types of objects receive the Decal and which do not. This is especially "
+"useful so you an ensure that dynamic objects don't accidentally receive a "
+"Decal intended for the terrain under them."
+msgstr ""
+
+#: doc/classes/Decal.xml:55
+msgid "Distance from the camera at which the Decal begins to fade away."
+msgstr ""
+
+#: doc/classes/Decal.xml:58
+msgid ""
+"If [code]true[/code], decals will smoothly fade away when far from the "
+"active [Camera3D] starting at [member distance_fade_begin]. The Decal will "
+"fade out over [member distance_fade_length], after which it will be culled "
+"and not sent to the shader at all. Use this to reduce the number of active "
+"Decals in a scene and thus improve performance."
+msgstr ""
+
+#: doc/classes/Decal.xml:61
+msgid ""
+"Distance over which the Decal fades. The Decal becomes slowly more "
+"transparent over this distance and is completely invisible at the end."
+msgstr ""
+
+#: doc/classes/Decal.xml:64
+msgid ""
+"Energy multiplier for the emission texture. This will make the decal emit "
+"light at a higher intensity."
+msgstr ""
+
+#: doc/classes/Decal.xml:67
+msgid ""
+"Sets the size of the [AABB] used by the decal. The AABB goes from [code]-"
+"extents[/code] to [code]extents[/code]."
+msgstr ""
+
+#: doc/classes/Decal.xml:70 doc/classes/Decal.xml:91
+msgid ""
+"Sets the curve over which the decal will fade as the surface gets further "
+"from the center of the [AABB]."
+msgstr ""
+
+#: doc/classes/Decal.xml:73
+msgid "Changes the [Color] of the Decal by multiplying it with this value."
+msgstr ""
+
+#: doc/classes/Decal.xml:76
+msgid ""
+"Fades the Decal if the angle between the Decal's [AABB] and the target "
+"surface becomes too large. A value of [code]0[/code] projects the Decal "
+"regardless of angle, a value of [code]1[/code] limits the Decal to surfaces "
+"that are nearly perpendicular."
+msgstr ""
+
+#: doc/classes/Decal.xml:79
+msgid ""
+"[Texture2D] with the base [Color] of the Decal. Either this or the [member "
+"texture_emission] must be set for the Decal to be visible. Use the alpha "
+"channel like a mask to smoothly blend the edges of the decal with the "
+"underlying object."
+msgstr ""
+
+#: doc/classes/Decal.xml:82
+msgid ""
+"[Texture2D] with the emission [Color] of the Decal. Either this or the "
+"[member texture_emission] must be set for the Decal to be visible. Use the "
+"alpha channel like a mask to smoothly blend the edges of the decal with the "
+"underlying object."
+msgstr ""
+
+#: doc/classes/Decal.xml:85
+msgid ""
+"[Texture2D] with the per-pixel normalmap for the decal. Use this to add "
+"extra detail to decals."
+msgstr ""
+
+#: doc/classes/Decal.xml:88
+msgid ""
+"[Texture2D] storing ambient occlusion, roughness, and metallic for the "
+"decal. Use this to add extra detail to decals."
+msgstr ""
+
+#: doc/classes/Decal.xml:96
+msgid "[Texture2D] corresponding to [member texture_albedo]."
+msgstr ""
+
+#: doc/classes/Decal.xml:99
+msgid "[Texture2D] corresponding to [member texture_normal]."
+msgstr ""
+
+#: doc/classes/Decal.xml:102
+msgid "[Texture2D] corresponding to [member texture_orm]."
+msgstr ""
+
+#: doc/classes/Decal.xml:105
+msgid "[Texture2D] corresponding to [member texture_emission]."
+msgstr ""
+
+#: doc/classes/Decal.xml:108
+msgid "Max size of [enum DecalTexture] enum."
+msgstr ""
+
#: doc/classes/Dictionary.xml:4
msgid "Dictionary type."
msgstr ""
@@ -16867,30 +16586,40 @@ msgstr ""
#: doc/classes/Dictionary.xml:7
msgid ""
"Dictionary type. Associative container which contains values referenced by "
-"unique keys. Dictionary are composed of pairs of keys (which must be unique) "
-"and values. You can define a dictionary by placing a comma separated list of "
-"[code]key: value[/code] pairs in curly braces [code]{}[/code].\n"
-"Erasing elements while iterating over them [b]is not supported[/b].\n"
+"unique keys. Dictionaries are composed of pairs of keys (which must be "
+"unique) and values. Dictionaries will preserve the insertion order when "
+"adding elements, even though this may not be reflected when printing the "
+"dictionary. In other programming languages, this data structure is sometimes "
+"referred to as an hash map or associative array.\n"
+"You can define a dictionary by placing a comma-separated list of [code]key: "
+"value[/code] pairs in curly braces [code]{}[/code].\n"
+"Erasing elements while iterating over them [b]is not supported[/b] and will "
+"result in undefined behavior.\n"
"Creating a dictionary:\n"
"[codeblock]\n"
"var my_dir = {} # Creates an empty dictionary.\n"
"var points_dir = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
-"var my_dir = {\n"
+"var another_dir = {\n"
" key1: value1,\n"
" key2: value2,\n"
" key3: value3,\n"
"}\n"
"[/codeblock]\n"
-"You can access values of a dictionary by referencing appropriate key in "
-"above example [code]points_dir[\"White\"][/code] would return value of 50.\n"
+"You can access a dictionary's values by referencing the appropriate key. In "
+"the above example, [code]points_dir[\"White\"][/code] will return [code]50[/"
+"code]. You can also write [code]points_dir.White[/code], which is "
+"equivalent. However, you'll have to use the bracket syntax if the key you're "
+"accessing the dictionary with isn't a fixed string (such as a number or "
+"variable).\n"
"[codeblock]\n"
"export(String, \"White\", \"Yellow\", \"Orange\") var my_color\n"
"var points_dir = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
"\n"
"func _ready():\n"
+" # We can't use dot syntax here as `my_color` is a variable.\n"
" var points = points_dir[my_color]\n"
"[/codeblock]\n"
-"In the above code [code]points[/code] will be assigned the value that is "
+"In the above code, [code]points[/code] will be assigned the value that is "
"paired with the appropriate color selected in [code]my_color[/code].\n"
"Dictionaries can contain more complex data:\n"
"[codeblock]\n"
@@ -16901,16 +16630,24 @@ msgid ""
"assign to it:\n"
"[codeblock]\n"
"var points_dir = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
-"var points_dir[\"Blue\"] = 150 # Add \"Blue\" as a key and assign 150 as its "
+"points_dir[\"Blue\"] = 150 # Add \"Blue\" as a key and assign 150 as its "
"value.\n"
"[/codeblock]\n"
"Finally, dictionaries can contain different types of keys and values in the "
"same dictionary:\n"
"[codeblock]\n"
-"var my_dir = {\"String Key\": 5, 4: [1, 2, 3], 7: \"Hello\"} # This is a "
-"valid dictionary.\n"
+"# This is a valid dictionary.\n"
+"# To access the string \"Nested value\" below, use `my_dir.sub_dir.sub_key` "
+"or `my_dir[\"sub_dir\"][\"sub_key\"]`.\n"
+"# Indexing styles can be mixed and matched depending on your needs.\n"
+"var my_dir = {\n"
+" \"String Key\": 5,\n"
+" 4: [1, 2, 3],\n"
+" 7: \"Hello\",\n"
+" \"sub_dir\": {\"sub_key\": \"Nested value\"},\n"
+"}\n"
"[/codeblock]\n"
-"[b]Note:[/b] Unlike [Array]s you can't compare dictionaries directly:\n"
+"[b]Note:[/b] Unlike [Array]s, you can't compare dictionaries directly:\n"
"[codeblock]\n"
"array1 = [1, 2, 3]\n"
"array2 = [1, 2, 3]\n"
@@ -16935,49 +16672,52 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/Dictionary.xml:65
+#: doc/classes/Dictionary.xml:75
msgid ""
"https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/"
"gdscript_basics.html#dictionary"
msgstr ""
-#: doc/classes/Dictionary.xml:72
+#: doc/classes/Dictionary.xml:82
msgid "Clear the dictionary, removing all key/value pairs."
msgstr ""
-#: doc/classes/Dictionary.xml:81
-msgid "Creates a copy of the dictionary, and returns it."
+#: doc/classes/Dictionary.xml:91
+msgid ""
+"Creates a copy of the dictionary, and returns it. The [code]deep[/code] "
+"parameter causes inner dictionaries and arrays to be copied recursively, but "
+"does not apply to objects."
msgstr ""
-#: doc/classes/Dictionary.xml:88
+#: doc/classes/Dictionary.xml:98
msgid "Returns [code]true[/code] if the dictionary is empty."
msgstr ""
-#: doc/classes/Dictionary.xml:97
+#: doc/classes/Dictionary.xml:107
msgid ""
"Erase a dictionary key/value pair by key. Returns [code]true[/code] if the "
"given key was present in the dictionary, [code]false[/code] otherwise. Does "
"not erase elements while iterating over the dictionary."
msgstr ""
-#: doc/classes/Dictionary.xml:108
+#: doc/classes/Dictionary.xml:118
msgid ""
"Returns the current value for the specified key in the [Dictionary]. If the "
"key does not exist, the method returns the value of the optional default "
"argument, or [code]null[/code] if it is omitted."
msgstr ""
-#: doc/classes/Dictionary.xml:117
+#: doc/classes/Dictionary.xml:127
msgid "Returns [code]true[/code] if the dictionary has a given key."
msgstr ""
-#: doc/classes/Dictionary.xml:126
+#: doc/classes/Dictionary.xml:136
msgid ""
"Returns [code]true[/code] if the dictionary has all of the keys in the given "
"array."
msgstr ""
-#: doc/classes/Dictionary.xml:133
+#: doc/classes/Dictionary.xml:143
msgid ""
"Returns a hashed integer value representing the dictionary contents. This "
"can be used to compare dictionaries by value:\n"
@@ -16990,15 +16730,15 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/Dictionary.xml:146
+#: doc/classes/Dictionary.xml:156
msgid "Returns the list of keys in the [Dictionary]."
msgstr ""
-#: doc/classes/Dictionary.xml:153
+#: doc/classes/Dictionary.xml:163
msgid "Returns the size of the dictionary (in pairs)."
msgstr ""
-#: doc/classes/Dictionary.xml:160
+#: doc/classes/Dictionary.xml:170
msgid "Returns the list of values in the [Dictionary]."
msgstr ""
@@ -17024,37 +16764,42 @@ msgstr ""
#: doc/classes/DirectionalLight3D.xml:16
msgid ""
-"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
+"transitions between splits."
msgstr ""
#: doc/classes/DirectionalLight3D.xml:19
msgid ""
-"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"Optimizes shadow rendering for detail versus movement. See [enum "
+"ShadowDepthRange]."
msgstr ""
#: doc/classes/DirectionalLight3D.xml:22
msgid ""
-"Optimizes shadow rendering for detail versus movement. See [enum "
-"ShadowDepthRange]."
+"Proportion of [member directional_shadow_max_distance] at which point the "
+"shadow starts to fade. At [member directional_shadow_max_distance] the "
+"shadow will disappear."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:27
+#: doc/classes/DirectionalLight3D.xml:25
msgid "The maximum distance for shadow splits."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:30
+#: doc/classes/DirectionalLight3D.xml:28
msgid "The light's shadow rendering algorithm. See [enum ShadowMode]."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:33
+#: doc/classes/DirectionalLight3D.xml:31 doc/classes/RenderingServer.xml:3371
msgid ""
-"Can be used to fix special cases of self shadowing when objects are "
-"perpendicular to the light."
+"Sets the size of the directional shadow pancake. The pancake offsets the "
+"start of the shadow's camera frustum to provide a higher effective depth "
+"resolution for the shadow. However, a high pancake size can cause artifacts "
+"in the shadows of large objects that are close to the edge of the frustum. "
+"Reducing the pancake size can help. Setting the size to [code]0[/code] turns "
+"off the pancaking effect."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:36
+#: doc/classes/DirectionalLight3D.xml:34
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
@@ -17062,7 +16807,7 @@ msgid ""
"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:39
+#: doc/classes/DirectionalLight3D.xml:37
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
@@ -17070,34 +16815,34 @@ msgid ""
"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:42
+#: doc/classes/DirectionalLight3D.xml:40
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:48
+#: doc/classes/DirectionalLight3D.xml:45
msgid ""
"Renders the entire scene's shadow map from an orthogonal point of view. May "
"result in blockier shadows on close objects."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:51
+#: doc/classes/DirectionalLight3D.xml:48
msgid "Splits the view frustum in 2 areas, each with its own shadow map."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:54
+#: doc/classes/DirectionalLight3D.xml:51
msgid "Splits the view frustum in 4 areas, each with its own shadow map."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:57
+#: doc/classes/DirectionalLight3D.xml:54
msgid ""
"Keeps the shadow stable when the camera moves, at the cost of lower "
"effective shadow resolution."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:60
+#: doc/classes/DirectionalLight3D.xml:57
msgid ""
"Tries to achieve maximum shadow resolution. May result in saw effect on "
"shadow edges."
@@ -17387,61 +17132,67 @@ msgid ""
"dynamic_font.font_data = load(\"res://BarlowCondensed-Bold.ttf\")\n"
"dynamic_font.size = 64\n"
"$\"Label\".set(\"custom_fonts/font\", dynamic_font)\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"[b]Note:[/b] DynamicFont doesn't support features such as right-to-left "
+"typesetting, ligatures, text shaping, variable fonts and optional font "
+"features yet. If you wish to \"bake\" an optional font feature into a TTF "
+"font file, you can use [url=https://fontforge.org/]FontForge[/url] to do so. "
+"In FontForge, use [b]File > Generate Fonts[/b], click [b]Options[/b], choose "
+"the desired features then generate the font."
msgstr ""
-#: doc/classes/DynamicFont.xml:25
+#: doc/classes/DynamicFont.xml:26
msgid "Adds a fallback font."
msgstr ""
-#: doc/classes/DynamicFont.xml:34
+#: doc/classes/DynamicFont.xml:35
msgid "Returns the fallback font at index [code]idx[/code]."
msgstr ""
-#: doc/classes/DynamicFont.xml:41
+#: doc/classes/DynamicFont.xml:42
msgid "Returns the number of fallback fonts."
msgstr ""
-#: doc/classes/DynamicFont.xml:50
+#: doc/classes/DynamicFont.xml:51
msgid ""
"Returns the spacing for the given [code]type[/code] (see [enum SpacingType])."
msgstr ""
-#: doc/classes/DynamicFont.xml:59
+#: doc/classes/DynamicFont.xml:60
msgid "Removes the fallback font at index [code]idx[/code]."
msgstr ""
-#: doc/classes/DynamicFont.xml:70
+#: doc/classes/DynamicFont.xml:71
msgid "Sets the fallback font at index [code]idx[/code]."
msgstr ""
-#: doc/classes/DynamicFont.xml:81
+#: doc/classes/DynamicFont.xml:82
msgid ""
"Sets the spacing for [code]type[/code] (see [enum SpacingType]) to "
"[code]value[/code] in pixels (not relative to the font size)."
msgstr ""
-#: doc/classes/DynamicFont.xml:87
+#: doc/classes/DynamicFont.xml:88
msgid "Extra spacing at the bottom in pixels."
msgstr ""
-#: doc/classes/DynamicFont.xml:90
+#: doc/classes/DynamicFont.xml:91
msgid "Extra character spacing in pixels."
msgstr ""
-#: doc/classes/DynamicFont.xml:93
+#: doc/classes/DynamicFont.xml:94
msgid "Extra space spacing in pixels."
msgstr ""
-#: doc/classes/DynamicFont.xml:96
+#: doc/classes/DynamicFont.xml:97
msgid "Extra spacing at the top in pixels."
msgstr ""
-#: doc/classes/DynamicFont.xml:99
+#: doc/classes/DynamicFont.xml:100
msgid "The font data."
msgstr ""
-#: doc/classes/DynamicFont.xml:102
+#: doc/classes/DynamicFont.xml:103
msgid ""
"The font outline's color.\n"
"[b]Note:[/b] It's recommended to leave this at the default value so that you "
@@ -17450,27 +17201,27 @@ msgid ""
"outline modulate theme item."
msgstr ""
-#: doc/classes/DynamicFont.xml:106
+#: doc/classes/DynamicFont.xml:107
msgid "The font outline's thickness in pixels (not relative to the font size)."
msgstr ""
-#: doc/classes/DynamicFont.xml:109
+#: doc/classes/DynamicFont.xml:110
msgid "The font size in pixels."
msgstr ""
-#: doc/classes/DynamicFont.xml:114
+#: doc/classes/DynamicFont.xml:115
msgid "Spacing at the top."
msgstr ""
-#: doc/classes/DynamicFont.xml:117
+#: doc/classes/DynamicFont.xml:118
msgid "Spacing at the bottom."
msgstr ""
-#: doc/classes/DynamicFont.xml:120
+#: doc/classes/DynamicFont.xml:121
msgid "Character spacing."
msgstr ""
-#: doc/classes/DynamicFont.xml:123
+#: doc/classes/DynamicFont.xml:124
msgid "Space spacing."
msgstr ""
@@ -17585,7 +17336,7 @@ msgstr ""
msgid ""
"Saves the editor feature profile to a file in JSON format. It can then be "
"imported using the feature profile manager's [b]Import[/b] button or the "
-"[method load_from_file] button."
+"[method load_from_file] button."
msgstr ""
#: doc/classes/EditorFeatureProfile.xml:86
@@ -17799,56 +17550,58 @@ msgstr ""
#: doc/classes/EditorFileSystem.xml:7
msgid ""
"This object holds information of all resources in the filesystem, their "
-"types, etc."
+"types, etc.\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_resource_filesystem]."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:18
+#: doc/classes/EditorFileSystem.xml:19
msgid "Gets the type of the file, given the full path."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:25
+#: doc/classes/EditorFileSystem.xml:26
msgid "Gets the root directory object."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:34
+#: doc/classes/EditorFileSystem.xml:35
msgid "Returns a view into the filesystem at [code]path[/code]."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:41
+#: doc/classes/EditorFileSystem.xml:42
msgid "Returns the scan progress for 0 to 1 if the FS is being scanned."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:48
+#: doc/classes/EditorFileSystem.xml:49
msgid "Returns [code]true[/code] of the filesystem is being scanned."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:55
+#: doc/classes/EditorFileSystem.xml:56
msgid "Scan the filesystem for changes."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:62
+#: doc/classes/EditorFileSystem.xml:63
msgid "Check if the source of any imported resource changed."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:71
+#: doc/classes/EditorFileSystem.xml:72
msgid ""
"Update a file information. Call this if an external program (not Godot) "
"modified the file."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:78
+#: doc/classes/EditorFileSystem.xml:79
msgid "Scans the script files and updates the list of custom class names."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:85
+#: doc/classes/EditorFileSystem.xml:86
msgid "Emitted if the filesystem changed."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:92
+#: doc/classes/EditorFileSystem.xml:93
msgid "Remitted if a resource is reimported."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:105
+#: doc/classes/EditorFileSystem.xml:106
msgid "Emitted if the source of any imported file changed."
msgstr ""
@@ -18052,7 +17805,9 @@ msgid ""
"editor. It's used to edit the properties of the selected node. For example, "
"you can select a node such as the Sprite2D then edit its transform through "
"the inspector tool. The editor inspector is an essential tool in the game "
-"development workflow."
+"development workflow.\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_inspector]."
msgstr ""
#: doc/classes/EditorInspectorPlugin.xml:4
@@ -18122,95 +17877,97 @@ msgid ""
"customizing the window, saving and (re-)loading scenes, rendering mesh "
"previews, inspecting and editing resources and objects, and provides access "
"to [EditorSettings], [EditorFileSystem], [EditorResourcePreview], "
-"[ScriptEditor], the editor viewport, and information about scenes."
+"[ScriptEditor], the editor viewport, and information about scenes.\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorPlugin.get_editor_interface]."
msgstr ""
-#: doc/classes/EditorInterface.xml:18
+#: doc/classes/EditorInterface.xml:19
msgid "Edits the given [Resource]."
msgstr ""
-#: doc/classes/EditorInterface.xml:25
+#: doc/classes/EditorInterface.xml:26
msgid ""
"Returns the main container of Godot editor's window. You can use it, for "
"example, to retrieve the size of the container and place your controls "
"accordingly."
msgstr ""
-#: doc/classes/EditorInterface.xml:38
+#: doc/classes/EditorInterface.xml:39
msgid "Returns the edited (current) scene's root [Node]."
msgstr ""
-#: doc/classes/EditorInterface.xml:45
+#: doc/classes/EditorInterface.xml:46
msgid "Returns the [EditorSettings]."
msgstr ""
-#: doc/classes/EditorInterface.xml:52
+#: doc/classes/EditorInterface.xml:53
msgid "Returns the editor [Viewport]."
msgstr ""
-#: doc/classes/EditorInterface.xml:71
+#: doc/classes/EditorInterface.xml:72
msgid "Returns an [Array] with the file paths of the currently opened scenes."
msgstr ""
-#: doc/classes/EditorInterface.xml:78
+#: doc/classes/EditorInterface.xml:79
msgid "Returns the [EditorFileSystem]."
msgstr ""
-#: doc/classes/EditorInterface.xml:85
+#: doc/classes/EditorInterface.xml:86
msgid "Returns the [EditorResourcePreview]."
msgstr ""
-#: doc/classes/EditorInterface.xml:92
+#: doc/classes/EditorInterface.xml:93
msgid "Returns the [ScriptEditor]."
msgstr ""
-#: doc/classes/EditorInterface.xml:105
+#: doc/classes/EditorInterface.xml:106
msgid "Returns the [EditorSelection]."
msgstr ""
-#: doc/classes/EditorInterface.xml:116
+#: doc/classes/EditorInterface.xml:117
msgid ""
"Shows the given property on the given [code]object[/code] in the Editor's "
"Inspector dock."
msgstr ""
-#: doc/classes/EditorInterface.xml:125
+#: doc/classes/EditorInterface.xml:126
msgid ""
"Returns the enabled status of a plugin. The plugin name is the same as its "
"directory name."
msgstr ""
-#: doc/classes/EditorInterface.xml:136
+#: doc/classes/EditorInterface.xml:137
msgid ""
"Returns mesh previews rendered at the given size as an [Array] of "
"[Texture2D]s."
msgstr ""
-#: doc/classes/EditorInterface.xml:145
+#: doc/classes/EditorInterface.xml:146
msgid "Opens the scene at the given path."
msgstr ""
-#: doc/classes/EditorInterface.xml:154
+#: doc/classes/EditorInterface.xml:155
msgid "Reloads the scene at the given path."
msgstr ""
-#: doc/classes/EditorInterface.xml:161
+#: doc/classes/EditorInterface.xml:162
msgid ""
"Saves the scene. Returns either [code]OK[/code] or [code]ERR_CANT_CREATE[/"
"code] (see [@GlobalScope] constants)."
msgstr ""
-#: doc/classes/EditorInterface.xml:172
+#: doc/classes/EditorInterface.xml:173
msgid "Saves the scene as a file at [code]path[/code]."
msgstr ""
-#: doc/classes/EditorInterface.xml:181
+#: doc/classes/EditorInterface.xml:182
msgid ""
"Selects the file, with the path provided by [code]file[/code], in the "
"FileSystem dock."
msgstr ""
-#: doc/classes/EditorInterface.xml:208
+#: doc/classes/EditorInterface.xml:209
msgid ""
"Sets the enabled status of a plugin. The plugin name is the same as its "
"directory name."
@@ -18823,57 +18580,57 @@ msgstr ""
msgid "Used by the inspector, when the property is checked."
msgstr ""
-#: doc/classes/EditorProperty.xml:82
+#: doc/classes/EditorProperty.xml:84
msgid "Used by the inspector, when the property must draw with error color."
msgstr ""
-#: doc/classes/EditorProperty.xml:85
+#: doc/classes/EditorProperty.xml:87
msgid "Used by the inspector, when the property can add keys for animation."
msgstr ""
-#: doc/classes/EditorProperty.xml:88
+#: doc/classes/EditorProperty.xml:90
msgid "Sets this property to change the label (if you want to show one)."
msgstr ""
-#: doc/classes/EditorProperty.xml:91
+#: doc/classes/EditorProperty.xml:93
msgid "Used by the inspector, when the property is read-only."
msgstr ""
-#: doc/classes/EditorProperty.xml:101
+#: doc/classes/EditorProperty.xml:103
msgid ""
"Emit it if you want multiple properties modified at the same time. Do not "
"use if added via [method EditorInspectorPlugin.parse_property]."
msgstr ""
-#: doc/classes/EditorProperty.xml:110
+#: doc/classes/EditorProperty.xml:112
msgid "Used by sub-inspectors. Emit it if what was selected was an Object ID."
msgstr ""
-#: doc/classes/EditorProperty.xml:119
+#: doc/classes/EditorProperty.xml:121
msgid ""
"Do not emit this manually, use the [method emit_changed] method instead."
msgstr ""
-#: doc/classes/EditorProperty.xml:128
+#: doc/classes/EditorProperty.xml:130
msgid "Emitted when a property was checked. Used internally."
msgstr ""
-#: doc/classes/EditorProperty.xml:135
+#: doc/classes/EditorProperty.xml:143
msgid ""
"Emit it if you want to add this value as an animation key (check for keying "
"being enabled first)."
msgstr ""
-#: doc/classes/EditorProperty.xml:144
+#: doc/classes/EditorProperty.xml:152
msgid "Emit it if you want to key a property with a single value."
msgstr ""
-#: doc/classes/EditorProperty.xml:153
+#: doc/classes/EditorProperty.xml:161
msgid ""
"If you want a sub-resource to be edited, emit this signal with the resource."
msgstr ""
-#: doc/classes/EditorProperty.xml:162
+#: doc/classes/EditorProperty.xml:170
msgid "Emitted when selected. Used internally."
msgstr ""
@@ -18882,20 +18639,23 @@ msgid "Helper to generate previews of resources or files."
msgstr ""
#: doc/classes/EditorResourcePreview.xml:7
-msgid "This object is used to generate previews for resources of files."
+msgid ""
+"This object is used to generate previews for resources of files.\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_resource_previewer]."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:18
+#: doc/classes/EditorResourcePreview.xml:19
msgid "Create an own, custom preview generator."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:27
+#: doc/classes/EditorResourcePreview.xml:28
msgid ""
"Check if the resource changed, if so, it will be invalidated and the "
"corresponding signal emitted."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:42
+#: doc/classes/EditorResourcePreview.xml:43
msgid ""
"Queue a resource being edited for preview (using an instance). Once the "
"preview is ready, your receiver.receiver_func will be called either "
@@ -18904,7 +18664,7 @@ msgid ""
"can be anything."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:57
+#: doc/classes/EditorResourcePreview.xml:58
msgid ""
"Queue a resource file for preview (using a path). Once the preview is ready, "
"your receiver.receiver_func will be called either containing the preview "
@@ -18912,11 +18672,11 @@ msgid ""
"the format: (path,texture,userdata). Userdata can be anything."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:66
+#: doc/classes/EditorResourcePreview.xml:67
msgid "Removes a custom preview generator."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:75
+#: doc/classes/EditorResourcePreview.xml:76
msgid ""
"Emitted if a preview was invalidated (changed). [code]path[/code] "
"corresponds to the path of the preview."
@@ -19074,7 +18834,7 @@ msgstr ""
msgid ""
"Scripts extending this class and implementing its [method _run] method can "
"be executed from the Script Editor's [b]File > Run[/b] menu option (or by "
-"pressing [code]Ctrl+Shift+X[/code]) while the editor is running. This is "
+"pressing [kbd]Ctrl + Shift + X[/kbd]) while the editor is running. This is "
"useful for adding custom in-editor functionality to Godot. For more complex "
"additions, consider using [EditorPlugin]s instead.\n"
"[b]Note:[/b] Extending scripts need to have [code]tool[/code] mode enabled.\n"
@@ -19114,33 +18874,36 @@ msgid "Manages the SceneTree selection in the editor."
msgstr ""
#: doc/classes/EditorSelection.xml:7
-msgid "This object manages the SceneTree selection in the editor."
+msgid ""
+"This object manages the SceneTree selection in the editor.\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_selection]."
msgstr ""
-#: doc/classes/EditorSelection.xml:18
+#: doc/classes/EditorSelection.xml:19
msgid "Adds a node to the selection."
msgstr ""
-#: doc/classes/EditorSelection.xml:25
+#: doc/classes/EditorSelection.xml:26
msgid "Clear the selection."
msgstr ""
-#: doc/classes/EditorSelection.xml:32
+#: doc/classes/EditorSelection.xml:33
msgid "Gets the list of selected nodes."
msgstr ""
-#: doc/classes/EditorSelection.xml:39
+#: doc/classes/EditorSelection.xml:40
msgid ""
"Gets the list of selected nodes, optimized for transform operations (i.e. "
"moving them, rotating, etc). This list avoids situations where a node is "
"selected and also child/grandchild."
msgstr ""
-#: doc/classes/EditorSelection.xml:48
+#: doc/classes/EditorSelection.xml:49
msgid "Removes a node from the selection."
msgstr ""
-#: doc/classes/EditorSelection.xml:55
+#: doc/classes/EditorSelection.xml:56
msgid "Emitted when the selection changes."
msgstr ""
@@ -19157,10 +18920,12 @@ msgid ""
"settings.set(prop,value)\n"
"settings.get(prop)\n"
"list_of_settings = settings.get_property_list()\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_editor_settings]."
msgstr ""
-#: doc/classes/EditorSettings.xml:24
+#: doc/classes/EditorSettings.xml:25
msgid ""
"Adds a custom property info to a property. The dictionary must contain:\n"
"- [code]name[/code]: [String] (the name of the property)\n"
@@ -19182,27 +18947,27 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/EditorSettings.xml:49
+#: doc/classes/EditorSettings.xml:50
msgid "Erase a given setting (pass full property path)."
msgstr ""
-#: doc/classes/EditorSettings.xml:56
+#: doc/classes/EditorSettings.xml:57
msgid "Gets the list of favorite files and directories for this project."
msgstr ""
-#: doc/classes/EditorSettings.xml:75
+#: doc/classes/EditorSettings.xml:76
msgid ""
"Gets the specific project settings path. Projects all have a unique sub-"
"directory inside the settings path where project specific settings are saved."
msgstr ""
-#: doc/classes/EditorSettings.xml:82
+#: doc/classes/EditorSettings.xml:83
msgid ""
"Gets the list of recently visited folders in the file dialog for this "
"project."
msgstr ""
-#: doc/classes/EditorSettings.xml:97
+#: doc/classes/EditorSettings.xml:98
msgid ""
"Gets the global settings path for the engine. Inside this path, you can find "
"some standard paths such as:\n"
@@ -19210,21 +18975,21 @@ msgid ""
"[code]settings/templates[/code] - Where export templates are located"
msgstr ""
-#: doc/classes/EditorSettings.xml:132
+#: doc/classes/EditorSettings.xml:133
msgid "Sets the list of favorite files and directories for this project."
msgstr ""
-#: doc/classes/EditorSettings.xml:165
+#: doc/classes/EditorSettings.xml:166
msgid ""
"Sets the list of recently visited folders in the file dialog for this "
"project."
msgstr ""
-#: doc/classes/EditorSettings.xml:182
+#: doc/classes/EditorSettings.xml:183
msgid "Emitted when editor settings change."
msgstr ""
-#: doc/classes/EditorSettings.xml:188
+#: doc/classes/EditorSettings.xml:189
msgid ""
"Emitted when editor settings change. It used by various editor plugins to "
"update their visuals on theme changes or logic on configuration changes."
@@ -19967,7 +19732,7 @@ msgid ""
"is visible, \"ghost trail\" artifacts will be visible when moving the camera."
msgstr ""
-#: doc/classes/Environment.xml:262 doc/classes/RenderingServer.xml:3476
+#: doc/classes/Environment.xml:262 doc/classes/RenderingServer.xml:3563
msgid "Displays a camera feed in the background."
msgstr ""
@@ -19975,64 +19740,103 @@ msgstr ""
msgid "Represents the size of the [enum BGMode] enum."
msgstr ""
-#: doc/classes/Environment.xml:282
+#: doc/classes/Environment.xml:268 doc/classes/RenderingServer.xml:3569
+msgid ""
+"Gather ambient light from whichever source is specified as the background."
+msgstr ""
+
+#: doc/classes/Environment.xml:271 doc/classes/RenderingServer.xml:3572
+msgid "Disable ambient light."
+msgstr ""
+
+#: doc/classes/Environment.xml:274 doc/classes/RenderingServer.xml:3575
+msgid "Specify a specific [Color] for ambient light."
+msgstr ""
+
+#: doc/classes/Environment.xml:277 doc/classes/RenderingServer.xml:3578
+msgid ""
+"Gather ambient light from the [Sky] regardless of what the background is."
+msgstr ""
+
+#: doc/classes/Environment.xml:280 doc/classes/RenderingServer.xml:3581
+msgid "Use the background for reflections."
+msgstr ""
+
+#: doc/classes/Environment.xml:283 doc/classes/RenderingServer.xml:3584
+msgid "Disable reflections."
+msgstr ""
+
+#: doc/classes/Environment.xml:286 doc/classes/RenderingServer.xml:3587
+msgid "Use the [Sky] for reflections regardless of what the background is."
+msgstr ""
+
+#: doc/classes/Environment.xml:289 doc/classes/RenderingServer.xml:3590
msgid ""
"Additive glow blending mode. Mostly used for particles, glows (bloom), lens "
"flare, bright sources."
msgstr ""
-#: doc/classes/Environment.xml:285
+#: doc/classes/Environment.xml:292 doc/classes/RenderingServer.xml:3593
msgid ""
"Screen glow blending mode. Increases brightness, used frequently with bloom."
msgstr ""
-#: doc/classes/Environment.xml:288
+#: doc/classes/Environment.xml:295 doc/classes/RenderingServer.xml:3596
msgid ""
"Soft light glow blending mode. Modifies contrast, exposes shadows and "
"highlights (vivid bloom)."
msgstr ""
-#: doc/classes/Environment.xml:291
+#: doc/classes/Environment.xml:298 doc/classes/RenderingServer.xml:3599
msgid ""
"Replace glow blending mode. Replaces all pixels' color by the glow value. "
"This can be used to simulate a full-screen blur effect by tweaking the glow "
"parameters to match the original image's brightness."
msgstr ""
-#: doc/classes/Environment.xml:296
+#: doc/classes/Environment.xml:301 doc/classes/RenderingServer.xml:3602
+msgid ""
+"Mixes the glow with the underlying color to avoid increasing brightness as "
+"much while still maintaining a glow effect."
+msgstr ""
+
+#: doc/classes/Environment.xml:304
msgid ""
"Linear tonemapper operator. Reads the linear data and passes it on "
"unmodified."
msgstr ""
-#: doc/classes/Environment.xml:299
+#: doc/classes/Environment.xml:307
msgid ""
"Reinhardt tonemapper operator. Performs a variation on rendered pixels' "
"colors by this formula: [code]color = color / (1 + color)[/code]."
msgstr ""
-#: doc/classes/Environment.xml:302
+#: doc/classes/Environment.xml:310
msgid "Filmic tonemapper operator."
msgstr ""
-#: doc/classes/Environment.xml:305
+#: doc/classes/Environment.xml:313
msgid "Academy Color Encoding System tonemapper operator."
msgstr ""
-#: doc/classes/Environment.xml:308
+#: doc/classes/Environment.xml:316
msgid "No blur for the screen-space ambient occlusion effect (fastest)."
msgstr ""
-#: doc/classes/Environment.xml:311
+#: doc/classes/Environment.xml:319
msgid "1×1 blur for the screen-space ambient occlusion effect."
msgstr ""
-#: doc/classes/Environment.xml:314
+#: doc/classes/Environment.xml:322
msgid "2×2 blur for the screen-space ambient occlusion effect."
msgstr ""
-#: doc/classes/Environment.xml:317
-msgid "3×3 blur for the screen-space ambient occlusion effect (slowest)."
+#: doc/classes/Environment.xml:325
+msgid ""
+"3×3 blur for the screen-space ambient occlusion effect. Increases the radius "
+"of the blur for a smoother look, but can result in checkerboard-like "
+"artifacts."
msgstr ""
#: doc/classes/Expression.xml:4
@@ -20293,26 +20097,38 @@ msgid ""
msgstr ""
#: doc/classes/File.xml:299
-msgid "Stores an integer as 16 bits in the file."
+msgid ""
+"Stores an integer as 16 bits in the file.\n"
+"[b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, "
+"2^16 - 1][/code]."
msgstr ""
-#: doc/classes/File.xml:308
-msgid "Stores an integer as 32 bits in the file."
+#: doc/classes/File.xml:309
+msgid ""
+"Stores an integer as 32 bits in the file.\n"
+"[b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, "
+"2^32 - 1][/code]."
msgstr ""
-#: doc/classes/File.xml:317
-msgid "Stores an integer as 64 bits in the file."
+#: doc/classes/File.xml:319
+msgid ""
+"Stores an integer as 64 bits in the file.\n"
+"[b]Note:[/b] The [code]value[/code] must lie in the interval [code][-2^63, "
+"2^63 - 1][/code] (i.e. be a valid [int] value)."
msgstr ""
-#: doc/classes/File.xml:326
-msgid "Stores an integer as 8 bits in the file."
+#: doc/classes/File.xml:329
+msgid ""
+"Stores an integer as 8 bits in the file.\n"
+"[b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, 255]"
+"[/code]."
msgstr ""
-#: doc/classes/File.xml:335
+#: doc/classes/File.xml:339
msgid "Stores the given array of bytes in the file."
msgstr ""
-#: doc/classes/File.xml:346
+#: doc/classes/File.xml:350
msgid ""
"Store the given [PackedStringArray] in the file as a line formatted in the "
"CSV (Comma-Separated Values) format. You can pass a different delimiter "
@@ -20321,45 +20137,45 @@ msgid ""
"Text will be encoded as UTF-8."
msgstr ""
-#: doc/classes/File.xml:356
+#: doc/classes/File.xml:360
msgid "Stores a floating-point number as 64 bits in the file."
msgstr ""
-#: doc/classes/File.xml:365
+#: doc/classes/File.xml:369
msgid "Stores a floating-point number as 32 bits in the file."
msgstr ""
-#: doc/classes/File.xml:374
+#: doc/classes/File.xml:378
msgid ""
"Stores the given [String] as a line in the file.\n"
"Text will be encoded as UTF-8."
msgstr ""
-#: doc/classes/File.xml:384
+#: doc/classes/File.xml:388
msgid ""
"Stores the given [String] as a line in the file in Pascal format (i.e. also "
"store the length of the string).\n"
"Text will be encoded as UTF-8."
msgstr ""
-#: doc/classes/File.xml:394
+#: doc/classes/File.xml:398
msgid "Stores a floating-point number in the file."
msgstr ""
-#: doc/classes/File.xml:403
+#: doc/classes/File.xml:407
msgid ""
"Stores the given [String] in the file.\n"
"Text will be encoded as UTF-8."
msgstr ""
-#: doc/classes/File.xml:415
+#: doc/classes/File.xml:419
msgid ""
"Stores any Variant value in the file. If [code]full_objects[/code] is "
"[code]true[/code], encoding objects is allowed (and can potentially include "
"code)."
msgstr ""
-#: doc/classes/File.xml:421
+#: doc/classes/File.xml:425
msgid ""
"If [code]true[/code], the file's endianness is swapped. Use this if you're "
"dealing with files written on big-endian machines.\n"
@@ -20367,44 +20183,44 @@ msgid ""
"reset to [code]false[/code] whenever you open the file."
msgstr ""
-#: doc/classes/File.xml:427
+#: doc/classes/File.xml:431
msgid "Opens the file for read operations."
msgstr ""
-#: doc/classes/File.xml:430
+#: doc/classes/File.xml:434
msgid ""
"Opens the file for write operations. Create it if the file does not exist "
"and truncate if it exists."
msgstr ""
-#: doc/classes/File.xml:433
+#: doc/classes/File.xml:437
msgid ""
"Opens the file for read and write operations. Does not truncate the file."
msgstr ""
-#: doc/classes/File.xml:436
+#: doc/classes/File.xml:440
msgid ""
"Opens the file for read and write operations. Create it if the file does not "
"exist and truncate if it exists."
msgstr ""
-#: doc/classes/File.xml:439
+#: doc/classes/File.xml:443
msgid "Uses the [url=http://fastlz.org/]FastLZ[/url] compression method."
msgstr ""
-#: doc/classes/File.xml:442
+#: doc/classes/File.xml:446
msgid ""
"Uses the [url=https://en.wikipedia.org/wiki/DEFLATE]DEFLATE[/url] "
"compression method."
msgstr ""
-#: doc/classes/File.xml:445
+#: doc/classes/File.xml:449
msgid ""
"Uses the [url=https://facebook.github.io/zstd/]Zstandard[/url] compression "
"method."
msgstr ""
-#: doc/classes/File.xml:448
+#: doc/classes/File.xml:452
msgid "Uses the [url=https://www.gzip.org/]gzip[/url] compression method."
msgstr ""
@@ -20708,7 +20524,7 @@ msgstr ""
msgid ""
"A GDNative library can implement [NativeScript]s, global functions to call "
"with the [GDNative] class, or low-level engine extensions through interfaces "
-"such as [ARVRInterfaceGDNative]. The library must be compiled for each "
+"such as [XRInterfaceGDNative]. The library must be compiled for each "
"platform and architecture that the project will run on."
msgstr ""
@@ -21663,99 +21479,99 @@ msgid ""
"object."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:27
+#: doc/classes/GeometryInstance3D.xml:35
msgid ""
"Overrides the bounding box of this node with a custom one. To remove it, set "
"an [AABB] with all fields set to zero."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:38
+#: doc/classes/GeometryInstance3D.xml:46
msgid ""
"Sets the [enum GeometryInstance3D.Flags] specified. See [enum "
"GeometryInstance3D.Flags] for options."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:44
+#: doc/classes/GeometryInstance3D.xml:62
msgid ""
"The selected shadow casting flag. See [enum ShadowCastingSetting] for "
"possible values."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:47
+#: doc/classes/GeometryInstance3D.xml:65
msgid ""
"The extra distance added to the GeometryInstance3D's bounding box ([AABB]) "
"to increase its cull box."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:50
+#: doc/classes/GeometryInstance3D.xml:68
msgid ""
"The GeometryInstance3D's max LOD distance.\n"
"[b]Note:[/b] This property currently has no effect."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:54
+#: doc/classes/GeometryInstance3D.xml:72
msgid ""
"The GeometryInstance3D's max LOD margin.\n"
"[b]Note:[/b] This property currently has no effect."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:58
+#: doc/classes/GeometryInstance3D.xml:76
msgid ""
"The GeometryInstance3D's min LOD distance.\n"
"[b]Note:[/b] This property currently has no effect."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:62
+#: doc/classes/GeometryInstance3D.xml:80
msgid ""
"The GeometryInstance3D's min LOD margin.\n"
"[b]Note:[/b] This property currently has no effect."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:66
+#: doc/classes/GeometryInstance3D.xml:84
msgid ""
"The material override for the whole geometry.\n"
"If a material is assigned to this property, it will be used instead of any "
"material set in any material slot of the mesh."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:72
+#: doc/classes/GeometryInstance3D.xml:90
msgid ""
"If [code]true[/code], this GeometryInstance3D will be used when baking "
"lights using a [GIProbe]."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:77
+#: doc/classes/GeometryInstance3D.xml:95
msgid "Will not cast any shadows."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:80
+#: doc/classes/GeometryInstance3D.xml:98
msgid ""
"Will cast shadows from all visible faces in the GeometryInstance3D.\n"
"Will take culling into account, so faces not being rendered will not be "
"taken into account when shadow casting."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:84
+#: doc/classes/GeometryInstance3D.xml:102
msgid ""
"Will cast shadows from all visible faces in the GeometryInstance3D.\n"
"Will not take culling into account, so all faces will be taken into account "
"when shadow casting."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:88
+#: doc/classes/GeometryInstance3D.xml:106
msgid ""
"Will only show the shadows casted from this object.\n"
"In other words, the actual mesh will not be visible, only the shadows casted "
"from the mesh will be."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:92
+#: doc/classes/GeometryInstance3D.xml:110
msgid ""
"Will allow the GeometryInstance3D to be used when baking lights using a "
"[GIProbe]."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:97
+#: doc/classes/GeometryInstance3D.xml:115
msgid ""
"Unused in this class, exposed for consistency with [enum RenderingServer."
"InstanceFlags]."
@@ -22225,7 +22041,7 @@ msgid ""
msgstr ""
#: doc/classes/GraphEdit.xml:243
-msgid "Emitted when the user presses [code]Ctrl + C[/code]."
+msgid "Emitted when the user presses [kbd]Ctrl + C[/kbd]."
msgstr ""
#: doc/classes/GraphEdit.xml:248
@@ -22248,65 +22064,65 @@ msgstr ""
msgid "Emitted when a GraphNode is selected."
msgstr ""
-#: doc/classes/GraphEdit.xml:278
-msgid "Emitted when the user presses [code]Ctrl + V[/code]."
+#: doc/classes/GraphEdit.xml:284
+msgid "Emitted when the user presses [kbd]Ctrl + V[/kbd]."
msgstr ""
-#: doc/classes/GraphEdit.xml:285
+#: doc/classes/GraphEdit.xml:291
msgid ""
"Emitted when a popup is requested. Happens on right-clicking in the "
"GraphEdit. [code]position[/code] is the position of the mouse pointer when "
"the signal is sent."
msgstr ""
-#: doc/classes/GraphEdit.xml:292
+#: doc/classes/GraphEdit.xml:298
msgid ""
"Emitted when the scroll offset is changed by the user. It will not be "
"emitted when changed in code."
msgstr ""
-#: doc/classes/GraphEdit.xml:306
+#: doc/classes/GraphEdit.xml:312
msgid "The background drawn under the grid."
msgstr ""
-#: doc/classes/GraphEdit.xml:309
+#: doc/classes/GraphEdit.xml:315
msgid "Color of major grid lines."
msgstr ""
-#: doc/classes/GraphEdit.xml:312
+#: doc/classes/GraphEdit.xml:318
msgid "Color of minor grid lines."
msgstr ""
-#: doc/classes/GraphEdit.xml:315
+#: doc/classes/GraphEdit.xml:321
msgid "The icon for the zoom out button."
msgstr ""
-#: doc/classes/GraphEdit.xml:318
+#: doc/classes/GraphEdit.xml:324
msgid "The icon for the zoom in button."
msgstr ""
-#: doc/classes/GraphEdit.xml:321
+#: doc/classes/GraphEdit.xml:327
msgid ""
"The horizontal range within which a port can be grabbed (on both sides)."
msgstr ""
-#: doc/classes/GraphEdit.xml:324
+#: doc/classes/GraphEdit.xml:330
msgid "The vertical range within which a port can be grabbed (on both sides)."
msgstr ""
-#: doc/classes/GraphEdit.xml:327
+#: doc/classes/GraphEdit.xml:333
msgid "The icon for the zoom reset button."
msgstr ""
-#: doc/classes/GraphEdit.xml:330
+#: doc/classes/GraphEdit.xml:336
msgid "The fill color of the selection rectangle."
msgstr ""
-#: doc/classes/GraphEdit.xml:333
+#: doc/classes/GraphEdit.xml:339
msgid "The outline color of the selection rectangle."
msgstr ""
-#: doc/classes/GraphEdit.xml:336
+#: doc/classes/GraphEdit.xml:342
msgid "The icon for the snap toggle button."
msgstr ""
@@ -23039,21 +22855,21 @@ msgstr ""
msgid "The background of the area to the left of the grabber."
msgstr ""
-#: doc/classes/HSlider.xml:23 doc/classes/VSlider.xml:27
+#: doc/classes/HSlider.xml:25 doc/classes/VSlider.xml:29
msgid "The texture for the grabber when it's disabled."
msgstr ""
-#: doc/classes/HSlider.xml:26 doc/classes/VSlider.xml:30
+#: doc/classes/HSlider.xml:28 doc/classes/VSlider.xml:32
msgid "The texture for the grabber when it's focused."
msgstr ""
-#: doc/classes/HSlider.xml:29
+#: doc/classes/HSlider.xml:31
msgid ""
"The background for the whole slider. Determines the height of the "
"[code]grabber_area[/code]."
msgstr ""
-#: doc/classes/HSlider.xml:32 doc/classes/VSlider.xml:36
+#: doc/classes/HSlider.xml:34 doc/classes/VSlider.xml:38
msgid ""
"The texture for the ticks, visible when [member Slider.tick_count] is "
"greater than 0."
@@ -23996,16 +23812,19 @@ msgstr ""
msgid ""
"Native image datatype. Contains image data, which can be converted to a "
"[Texture2D], and several functions to interact with it. The maximum width "
-"and height for an [Image] are [constant MAX_WIDTH] and [constant MAX_HEIGHT]."
+"and height for an [Image] are [constant MAX_WIDTH] and [constant "
+"MAX_HEIGHT].\n"
+"[b]Note:[/b] The maximum image size is 16384×16384 pixels due to graphics "
+"hardware limitations. Larger images will fail to import."
msgstr ""
-#: doc/classes/Image.xml:22
+#: doc/classes/Image.xml:23
msgid ""
"Alpha-blends [code]src_rect[/code] from [code]src[/code] image to this image "
"at coordinates [code]dest[/code]."
msgstr ""
-#: doc/classes/Image.xml:37
+#: doc/classes/Image.xml:38
msgid ""
"Alpha-blends [code]src_rect[/code] from [code]src[/code] image to this image "
"using [code]mask[/code] image at coordinates [code]dst[/code]. Alpha "
@@ -24016,13 +23835,13 @@ msgid ""
"but they can have different formats."
msgstr ""
-#: doc/classes/Image.xml:50
+#: doc/classes/Image.xml:51
msgid ""
"Copies [code]src_rect[/code] from [code]src[/code] image to this image at "
"coordinates [code]dst[/code]."
msgstr ""
-#: doc/classes/Image.xml:65
+#: doc/classes/Image.xml:66
msgid ""
"Blits [code]src_rect[/code] area from [code]src[/code] image to this image "
"at the coordinates given by [code]dst[/code]. [code]src[/code] pixel is "
@@ -24032,17 +23851,17 @@ msgid ""
"different formats."
msgstr ""
-#: doc/classes/Image.xml:74
+#: doc/classes/Image.xml:75
msgid ""
"Converts a bumpmap to a normalmap. A bumpmap provides a height offset per-"
"pixel, while a normalmap provides a normal direction per pixel."
msgstr ""
-#: doc/classes/Image.xml:81
+#: doc/classes/Image.xml:82
msgid "Removes the image's mipmaps."
msgstr ""
-#: doc/classes/Image.xml:94
+#: doc/classes/Image.xml:95
msgid ""
"Compresses the image to use less memory. Can not directly access pixel data "
"while the image is compressed. Returns error if the chosen compression mode "
@@ -24050,22 +23869,22 @@ msgid ""
"constants."
msgstr ""
-#: doc/classes/Image.xml:115
+#: doc/classes/Image.xml:116
msgid "Converts the image's format. See [enum Format] constants."
msgstr ""
-#: doc/classes/Image.xml:124
+#: doc/classes/Image.xml:125
msgid "Copies [code]src[/code] image to this image."
msgstr ""
-#: doc/classes/Image.xml:139
+#: doc/classes/Image.xml:140
msgid ""
"Creates an empty image of given size and format. See [enum Format] "
"constants. If [code]use_mipmaps[/code] is [code]true[/code] then generate "
"mipmaps for this image. See the [method generate_mipmaps]."
msgstr ""
-#: doc/classes/Image.xml:156
+#: doc/classes/Image.xml:157
msgid ""
"Creates a new image of given size and format. See [enum Format] constants. "
"Fills the image with the given raw data. If [code]use_mipmaps[/code] is "
@@ -24073,49 +23892,49 @@ msgid ""
"generate_mipmaps]."
msgstr ""
-#: doc/classes/Image.xml:167
+#: doc/classes/Image.xml:168
msgid ""
"Crops the image to the given [code]width[/code] and [code]height[/code]. If "
"the specified size is larger than the current size, the extra area is filled "
"with black pixels."
msgstr ""
-#: doc/classes/Image.xml:174
+#: doc/classes/Image.xml:175
msgid ""
"Decompresses the image if it is compressed. Returns an error if decompress "
"function is not available."
msgstr ""
-#: doc/classes/Image.xml:181
+#: doc/classes/Image.xml:182
msgid ""
"Returns [constant ALPHA_BLEND] if the image has data for alpha values. "
"Returns [constant ALPHA_BIT] if all the alpha values are stored in a single "
"bit. Returns [constant ALPHA_NONE] if no data for alpha values is found."
msgstr ""
-#: doc/classes/Image.xml:196
+#: doc/classes/Image.xml:197
msgid ""
"Stretches the image and enlarges it by a factor of 2. No interpolation is "
"done."
msgstr ""
-#: doc/classes/Image.xml:205
+#: doc/classes/Image.xml:206
msgid "Fills the image with a given [Color]."
msgstr ""
-#: doc/classes/Image.xml:212
+#: doc/classes/Image.xml:213
msgid "Blends low-alpha pixels with nearby pixels."
msgstr ""
-#: doc/classes/Image.xml:219
+#: doc/classes/Image.xml:220
msgid "Flips the image horizontally."
msgstr ""
-#: doc/classes/Image.xml:226
+#: doc/classes/Image.xml:227
msgid "Flips the image vertically."
msgstr ""
-#: doc/classes/Image.xml:235
+#: doc/classes/Image.xml:236
msgid ""
"Generates mipmaps for the image. Mipmaps are pre-calculated and lower "
"resolution copies of the image. Mipmaps are automatically used if the image "
@@ -24124,125 +23943,129 @@ msgid ""
"in a custom format or if the image's width/height is 0."
msgstr ""
-#: doc/classes/Image.xml:242
+#: doc/classes/Image.xml:243
msgid "Returns the image's raw data."
msgstr ""
-#: doc/classes/Image.xml:249
+#: doc/classes/Image.xml:250
msgid "Returns the image's format. See [enum Format] constants."
msgstr ""
-#: doc/classes/Image.xml:256
+#: doc/classes/Image.xml:257
msgid "Returns the image's height."
msgstr ""
-#: doc/classes/Image.xml:265
+#: doc/classes/Image.xml:266
msgid ""
"Returns the offset where the image's mipmap with index [code]mipmap[/code] "
"is stored in the [code]data[/code] dictionary."
msgstr ""
-#: doc/classes/Image.xml:276
+#: doc/classes/Image.xml:277
msgid ""
"Returns the color of the pixel at [code](x, y)[/code]. This is the same as "
"[method get_pixelv], but with two integer arguments instead of a [Vector2] "
"argument."
msgstr ""
-#: doc/classes/Image.xml:285
+#: doc/classes/Image.xml:286
msgid ""
"Returns the color of the pixel at [code]src[/code]. This is the same as "
"[method get_pixel], but with a [Vector2] argument instead of two integer "
"arguments."
msgstr ""
-#: doc/classes/Image.xml:294
+#: doc/classes/Image.xml:295
msgid ""
"Returns a new image that is a copy of the image's area specified with "
"[code]rect[/code]."
msgstr ""
-#: doc/classes/Image.xml:301
+#: doc/classes/Image.xml:302
msgid "Returns the image's size (width and height)."
msgstr ""
-#: doc/classes/Image.xml:308
+#: doc/classes/Image.xml:309
msgid ""
"Returns a [Rect2] enclosing the visible portion of the image, considering "
"each pixel with a non-zero alpha channel as visible."
msgstr ""
-#: doc/classes/Image.xml:315
+#: doc/classes/Image.xml:316
msgid "Returns the image's width."
msgstr ""
-#: doc/classes/Image.xml:322
+#: doc/classes/Image.xml:323
msgid "Returns [code]true[/code] if the image has generated mipmaps."
msgstr ""
-#: doc/classes/Image.xml:329
+#: doc/classes/Image.xml:330
msgid "Returns [code]true[/code] if the image is compressed."
msgstr ""
-#: doc/classes/Image.xml:336
+#: doc/classes/Image.xml:337
msgid "Returns [code]true[/code] if the image has no data."
msgstr ""
-#: doc/classes/Image.xml:343
+#: doc/classes/Image.xml:344
msgid ""
"Returns [code]true[/code] if all the image's pixels have an alpha value of "
"0. Returns [code]false[/code] if any pixel has an alpha value higher than 0."
msgstr ""
-#: doc/classes/Image.xml:352
-msgid "Loads an image from file [code]path[/code]."
+#: doc/classes/Image.xml:353
+msgid ""
+"Loads an image from file [code]path[/code]. See [url=https://docs."
+"godotengine.org/en/latest/getting_started/workflow/assets/importing_images."
+"html#supported-image-formats]Supported image formats[/url] for a list of "
+"supported image formats and limitations."
msgstr ""
-#: doc/classes/Image.xml:361
+#: doc/classes/Image.xml:362
msgid "Loads an image from the binary contents of a JPEG file."
msgstr ""
-#: doc/classes/Image.xml:370
+#: doc/classes/Image.xml:371
msgid "Loads an image from the binary contents of a PNG file."
msgstr ""
-#: doc/classes/Image.xml:379
+#: doc/classes/Image.xml:380
msgid "Loads an image from the binary contents of a WebP file."
msgstr ""
-#: doc/classes/Image.xml:386
+#: doc/classes/Image.xml:387
msgid ""
"Converts the image's data to represent coordinates on a 3D plane. This is "
"used when the image represents a normalmap. A normalmap can add lots of "
"detail to a 3D surface without increasing the polygon count."
msgstr ""
-#: doc/classes/Image.xml:393
+#: doc/classes/Image.xml:394
msgid ""
"Multiplies color values with alpha values. Resulting color values for a "
"pixel are [code](color * alpha)/256[/code]."
msgstr ""
-#: doc/classes/Image.xml:406
+#: doc/classes/Image.xml:407
msgid ""
"Resizes the image to the given [code]width[/code] and [code]height[/code]. "
"New pixels are calculated using [code]interpolation[/code]. See "
"[code]interpolation[/code] constants."
msgstr ""
-#: doc/classes/Image.xml:415
+#: doc/classes/Image.xml:416
msgid ""
"Resizes the image to the nearest power of 2 for the width and height. If "
"[code]square[/code] is [code]true[/code] then set width and height to be the "
"same."
msgstr ""
-#: doc/classes/Image.xml:422
+#: doc/classes/Image.xml:423
msgid ""
"Converts a standard RGBE (Red Green Blue Exponent) image to an sRGB image."
msgstr ""
-#: doc/classes/Image.xml:433
+#: doc/classes/Image.xml:434
msgid ""
"Saves the image as an EXR file to [code]path[/code]. If [code]grayscale[/"
"code] is [code]true[/code] and the image has only one channel, it will be "
@@ -24251,11 +24074,11 @@ msgid ""
"TinyEXR module."
msgstr ""
-#: doc/classes/Image.xml:442
+#: doc/classes/Image.xml:443
msgid "Saves the image as a PNG file to [code]path[/code]."
msgstr ""
-#: doc/classes/Image.xml:455
+#: doc/classes/Image.xml:456
msgid ""
"Sets the [Color] of the pixel at [code](x, y)[/code]. Example:\n"
"[codeblock]\n"
@@ -24265,7 +24088,7 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/Image.xml:471
+#: doc/classes/Image.xml:472
msgid ""
"Sets the [Color] of the pixel at [code](dst.x, dst.y)[/code]. Note that the "
"[code]dst[/code] values must be integers. Example:\n"
@@ -24276,51 +24099,51 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/Image.xml:483
+#: doc/classes/Image.xml:484
msgid "Shrinks the image by a factor of 2."
msgstr ""
-#: doc/classes/Image.xml:490
+#: doc/classes/Image.xml:491
msgid "Converts the raw data from the sRGB colorspace to a linear scale."
msgstr ""
-#: doc/classes/Image.xml:496
+#: doc/classes/Image.xml:497
msgid ""
"Holds all of the image's color data in a given format. See [enum Format] "
"constants."
msgstr ""
-#: doc/classes/Image.xml:501
+#: doc/classes/Image.xml:502
msgid "The maximal width allowed for [Image] resources."
msgstr ""
-#: doc/classes/Image.xml:504
+#: doc/classes/Image.xml:505
msgid "The maximal height allowed for [Image] resources."
msgstr ""
-#: doc/classes/Image.xml:507
+#: doc/classes/Image.xml:508
msgid "Texture format with a single 8-bit depth representing luminance."
msgstr ""
-#: doc/classes/Image.xml:510
+#: doc/classes/Image.xml:511
msgid ""
"OpenGL texture format with two values, luminance and alpha each stored with "
"8 bits."
msgstr ""
-#: doc/classes/Image.xml:513
+#: doc/classes/Image.xml:514
msgid ""
"OpenGL texture format [code]RED[/code] with a single component and a "
"bitdepth of 8."
msgstr ""
-#: doc/classes/Image.xml:516
+#: doc/classes/Image.xml:517
msgid ""
"OpenGL texture format [code]RG[/code] with two components and a bitdepth of "
"8 for each."
msgstr ""
-#: doc/classes/Image.xml:519
+#: doc/classes/Image.xml:520
msgid ""
"OpenGL texture format [code]RGB[/code] with three components, each with a "
"bitdepth of 8.\n"
@@ -24328,7 +24151,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:523
+#: doc/classes/Image.xml:524
msgid ""
"OpenGL texture format [code]RGBA[/code] with four components, each with a "
"bitdepth of 8.\n"
@@ -24336,67 +24159,67 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:527
+#: doc/classes/Image.xml:528
msgid ""
"OpenGL texture format [code]RGBA[/code] with four components, each with a "
"bitdepth of 4."
msgstr ""
-#: doc/classes/Image.xml:532
+#: doc/classes/Image.xml:533
msgid ""
"OpenGL texture format [code]GL_R32F[/code] where there's one component, a 32-"
"bit floating-point value."
msgstr ""
-#: doc/classes/Image.xml:535
+#: doc/classes/Image.xml:536
msgid ""
"OpenGL texture format [code]GL_RG32F[/code] where there are two components, "
"each a 32-bit floating-point values."
msgstr ""
-#: doc/classes/Image.xml:538
+#: doc/classes/Image.xml:539
msgid ""
"OpenGL texture format [code]GL_RGB32F[/code] where there are three "
"components, each a 32-bit floating-point values."
msgstr ""
-#: doc/classes/Image.xml:541
+#: doc/classes/Image.xml:542
msgid ""
"OpenGL texture format [code]GL_RGBA32F[/code] where there are four "
"components, each a 32-bit floating-point values."
msgstr ""
-#: doc/classes/Image.xml:544
+#: doc/classes/Image.xml:545
msgid ""
"OpenGL texture format [code]GL_R32F[/code] where there's one component, a 16-"
"bit \"half-precision\" floating-point value."
msgstr ""
-#: doc/classes/Image.xml:547
+#: doc/classes/Image.xml:548
msgid ""
"OpenGL texture format [code]GL_RG32F[/code] where there are two components, "
"each a 16-bit \"half-precision\" floating-point value."
msgstr ""
-#: doc/classes/Image.xml:550
+#: doc/classes/Image.xml:551
msgid ""
"OpenGL texture format [code]GL_RGB32F[/code] where there are three "
"components, each a 16-bit \"half-precision\" floating-point value."
msgstr ""
-#: doc/classes/Image.xml:553
+#: doc/classes/Image.xml:554
msgid ""
"OpenGL texture format [code]GL_RGBA32F[/code] where there are four "
"components, each a 16-bit \"half-precision\" floating-point value."
msgstr ""
-#: doc/classes/Image.xml:556
+#: doc/classes/Image.xml:557
msgid ""
"A special OpenGL texture format where the three color components have 9 bits "
"of precision and all three share a single 5-bit exponent."
msgstr ""
-#: doc/classes/Image.xml:559
+#: doc/classes/Image.xml:560
msgid ""
"The [url=https://en.wikipedia.org/wiki/S3_Texture_Compression]S3TC[/url] "
"texture format that uses Block Compression 1, and is the smallest variation "
@@ -24406,7 +24229,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:563
+#: doc/classes/Image.xml:564
msgid ""
"The [url=https://en.wikipedia.org/wiki/S3_Texture_Compression]S3TC[/url] "
"texture format that uses Block Compression 2, and color data is interpreted "
@@ -24416,7 +24239,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:567
+#: doc/classes/Image.xml:568
msgid ""
"The [url=https://en.wikipedia.org/wiki/S3_Texture_Compression]S3TC[/url] "
"texture format also known as Block Compression 3 or BC3 that contains 64 "
@@ -24427,7 +24250,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:571
+#: doc/classes/Image.xml:572
msgid ""
"Texture format that uses [url=https://www.khronos.org/opengl/wiki/"
"Red_Green_Texture_Compression]Red Green Texture Compression[/url], "
@@ -24435,7 +24258,7 @@ msgid ""
"DXT5 uses for the alpha channel."
msgstr ""
-#: doc/classes/Image.xml:574
+#: doc/classes/Image.xml:575
msgid ""
"Texture format that uses [url=https://www.khronos.org/opengl/wiki/"
"Red_Green_Texture_Compression]Red Green Texture Compression[/url], "
@@ -24443,7 +24266,7 @@ msgid ""
"algorithm that DXT5 uses for the alpha channel."
msgstr ""
-#: doc/classes/Image.xml:577
+#: doc/classes/Image.xml:578
msgid ""
"Texture format that uses [url=https://www.khronos.org/opengl/wiki/"
"BPTC_Texture_Compression]BPTC[/url] compression with unsigned normalized "
@@ -24452,21 +24275,21 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:581
+#: doc/classes/Image.xml:582
msgid ""
"Texture format that uses [url=https://www.khronos.org/opengl/wiki/"
"BPTC_Texture_Compression]BPTC[/url] compression with signed floating-point "
"RGB components."
msgstr ""
-#: doc/classes/Image.xml:584
+#: doc/classes/Image.xml:585
msgid ""
"Texture format that uses [url=https://www.khronos.org/opengl/wiki/"
"BPTC_Texture_Compression]BPTC[/url] compression with unsigned floating-point "
"RGB components."
msgstr ""
-#: doc/classes/Image.xml:587
+#: doc/classes/Image.xml:588
msgid ""
"Texture format used on PowerVR-supported mobile platforms, uses 2-bit color "
"depth with no alpha. More information can be found [url=https://en.wikipedia."
@@ -24475,25 +24298,25 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:591
+#: doc/classes/Image.xml:592
msgid ""
"Same as [url=https://en.wikipedia.org/wiki/PVRTC]PVRTC2[/url], but with an "
"alpha component."
msgstr ""
-#: doc/classes/Image.xml:594
+#: doc/classes/Image.xml:595
msgid ""
"Similar to [url=https://en.wikipedia.org/wiki/PVRTC]PVRTC2[/url], but with 4-"
"bit color depth and no alpha."
msgstr ""
-#: doc/classes/Image.xml:597
+#: doc/classes/Image.xml:598
msgid ""
"Same as [url=https://en.wikipedia.org/wiki/PVRTC]PVRTC4[/url], but with an "
"alpha component."
msgstr ""
-#: doc/classes/Image.xml:600
+#: doc/classes/Image.xml:601
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC1]Ericsson Texture Compression format 1[/"
@@ -24501,7 +24324,7 @@ msgid ""
"standard. This format cannot store an alpha channel."
msgstr ""
-#: doc/classes/Image.xml:603
+#: doc/classes/Image.xml:604
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24509,7 +24332,7 @@ msgid ""
"unsigned data."
msgstr ""
-#: doc/classes/Image.xml:606
+#: doc/classes/Image.xml:607
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24517,7 +24340,7 @@ msgid ""
"channel of signed data."
msgstr ""
-#: doc/classes/Image.xml:609
+#: doc/classes/Image.xml:610
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24525,7 +24348,7 @@ msgid ""
"of unsigned data."
msgstr ""
-#: doc/classes/Image.xml:612
+#: doc/classes/Image.xml:613
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24533,7 +24356,7 @@ msgid ""
"channels of signed data."
msgstr ""
-#: doc/classes/Image.xml:615
+#: doc/classes/Image.xml:616
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24543,7 +24366,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:619
+#: doc/classes/Image.xml:620
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24553,7 +24376,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:623
+#: doc/classes/Image.xml:624
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24564,31 +24387,31 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:631
+#: doc/classes/Image.xml:632
msgid "Represents the size of the [enum Format] enum."
msgstr ""
-#: doc/classes/Image.xml:634
+#: doc/classes/Image.xml:635
msgid ""
"Performs nearest-neighbor interpolation. If the image is resized, it will be "
"pixelated."
msgstr ""
-#: doc/classes/Image.xml:637
+#: doc/classes/Image.xml:638
msgid ""
"Performs bilinear interpolation. If the image is resized, it will be blurry. "
"This mode is faster than [constant INTERPOLATE_CUBIC], but it results in "
"lower quality."
msgstr ""
-#: doc/classes/Image.xml:640
+#: doc/classes/Image.xml:641
msgid ""
"Performs cubic interpolation. If the image is resized, it will be blurry. "
"This mode often gives better results compared to [constant "
"INTERPOLATE_BILINEAR], at the cost of being slower."
msgstr ""
-#: doc/classes/Image.xml:643
+#: doc/classes/Image.xml:644
msgid ""
"Performs bilinear separately on the two most-suited mipmap levels, then "
"linearly interpolates between them.\n"
@@ -24603,55 +24426,55 @@ msgid ""
"a new set will be generated for the resulting image."
msgstr ""
-#: doc/classes/Image.xml:650
+#: doc/classes/Image.xml:651
msgid ""
"Performs Lanczos interpolation. This is the slowest image resizing mode, but "
"it typically gives the best results, especially when downscalng images."
msgstr ""
-#: doc/classes/Image.xml:653
+#: doc/classes/Image.xml:654
msgid "Image does not have alpha."
msgstr ""
-#: doc/classes/Image.xml:656
+#: doc/classes/Image.xml:657
msgid "Image stores alpha in a single bit."
msgstr ""
-#: doc/classes/Image.xml:659
+#: doc/classes/Image.xml:660
msgid "Image uses alpha."
msgstr ""
-#: doc/classes/Image.xml:662
+#: doc/classes/Image.xml:663
msgid "Use S3TC compression."
msgstr ""
-#: doc/classes/Image.xml:665
+#: doc/classes/Image.xml:666
msgid "Use PVRTC2 compression."
msgstr ""
-#: doc/classes/Image.xml:668
+#: doc/classes/Image.xml:669
msgid "Use PVRTC4 compression."
msgstr ""
-#: doc/classes/Image.xml:671
+#: doc/classes/Image.xml:672
msgid "Use ETC compression."
msgstr ""
-#: doc/classes/Image.xml:674
+#: doc/classes/Image.xml:675
msgid "Use ETC2 compression."
msgstr ""
-#: doc/classes/Image.xml:689
+#: doc/classes/Image.xml:690
msgid ""
"Source texture (before compression) is a regular texture. Default for all "
"textures."
msgstr ""
-#: doc/classes/Image.xml:692
+#: doc/classes/Image.xml:693
msgid "Source texture (before compression) is in sRGB space."
msgstr ""
-#: doc/classes/Image.xml:695
+#: doc/classes/Image.xml:696
msgid ""
"Source texture (before compression) is a normal texture (e.g. it can be "
"compressed into two channels)."
@@ -24664,22 +24487,24 @@ msgstr ""
#: doc/classes/ImageTexture.xml:7
msgid ""
"A [Texture2D] based on an [Image]. Can be created from an [Image] with "
-"[method create_from_image]."
+"[method create_from_image].\n"
+"[b]Note:[/b] The maximum image size is 16384×16384 pixels due to graphics "
+"hardware limitations. Larger images will fail to import."
msgstr ""
-#: doc/classes/ImageTexture.xml:18
+#: doc/classes/ImageTexture.xml:19
msgid "Create a new [ImageTexture] from an [Image]."
msgstr ""
-#: doc/classes/ImageTexture.xml:25
+#: doc/classes/ImageTexture.xml:26
msgid "Returns the format of the [ImageTexture], one of [enum Image.Format]."
msgstr ""
-#: doc/classes/ImageTexture.xml:34
+#: doc/classes/ImageTexture.xml:35
msgid "Resizes the [ImageTexture] to the specified dimensions."
msgstr ""
-#: doc/classes/ImageTexture.xml:45
+#: doc/classes/ImageTexture.xml:46
msgid ""
"Replaces the texture's data with a new [code]image[/code]. If "
"[code]immediate[/code] is [code]true[/code], it will take effect immediately "
@@ -24692,20 +24517,29 @@ msgstr ""
#: doc/classes/ImmediateGeometry3D.xml:7
msgid ""
-"Draws simple geometry from code. Uses a drawing mode similar to OpenGL 1.x."
+"Draws simple geometry from code. Uses a drawing mode similar to OpenGL 1.x.\n"
+"See also [ArrayMesh], [MeshDataTool] and [SurfaceTool] for procedural "
+"geometry generation.\n"
+"[b]Note:[/b] ImmediateGeometry3D is best suited to small amounts of mesh "
+"data that change every frame. It will be slow when handling large amounts of "
+"mesh data. If mesh data doesn't change often, use [ArrayMesh], "
+"[MeshDataTool] or [SurfaceTool] instead.\n"
+"[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-"
+"OpenGL/Face-culling]winding order[/url] for front faces of triangle "
+"primitive modes."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:24
+#: doc/classes/ImmediateGeometry3D.xml:27
msgid ""
"Simple helper to draw an UV sphere with given latitude, longitude and radius."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:33
+#: doc/classes/ImmediateGeometry3D.xml:36
msgid ""
"Adds a vertex in local coordinate space with the currently set color/uv/etc."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:44
+#: doc/classes/ImmediateGeometry3D.xml:47
msgid ""
"Begin drawing (and optionally pass a texture override). When done call "
"[method end]. For more information on how this works, search for "
@@ -24713,34 +24547,453 @@ msgid ""
"For the type of primitive, see the [enum Mesh.PrimitiveType] enum."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:52
+#: doc/classes/ImmediateGeometry3D.xml:55
msgid "Clears everything that was drawn using begin/end."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:59
+#: doc/classes/ImmediateGeometry3D.xml:62
msgid "Ends a drawing context and displays the results."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:68
+#: doc/classes/ImmediateGeometry3D.xml:71
msgid "The current drawing color."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:77
+#: doc/classes/ImmediateGeometry3D.xml:80
msgid "The next vertex's normal."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:86
+#: doc/classes/ImmediateGeometry3D.xml:89
msgid "The next vertex's tangent (and binormal facing)."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:95
+#: doc/classes/ImmediateGeometry3D.xml:98
msgid "The next vertex's UV."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:104
+#: doc/classes/ImmediateGeometry3D.xml:107
msgid "The next vertex's second layer UV."
msgstr ""
+#: doc/classes/Input.xml:4
+msgid "A singleton that deals with inputs."
+msgstr ""
+
+#: doc/classes/Input.xml:7
+msgid ""
+"A singleton that deals with inputs. This includes key presses, mouse buttons "
+"and movement, joypads, and input actions. Actions and their events can be "
+"set in the [b]Input Map[/b] tab in the [b]Project > Project Settings[/b], or "
+"with the [InputMap] class."
+msgstr ""
+
+#: doc/classes/Input.xml:10
+msgid "https://docs.godotengine.org/en/latest/tutorials/inputs/index.html"
+msgstr ""
+
+#: doc/classes/Input.xml:21
+msgid ""
+"This will simulate pressing the specified action.\n"
+"The strength can be used for non-boolean actions, it's ranged between 0 and "
+"1 representing the intensity of the given action.\n"
+"[b]Note:[/b] This method will not cause any [method Node._input] calls. It "
+"is intended to be used with [method is_action_pressed] and [method "
+"is_action_just_pressed]. If you want to simulate [code]_input[/code], use "
+"[method parse_input_event] instead."
+msgstr ""
+
+#: doc/classes/Input.xml:32
+msgid "If the specified action is already pressed, this will release it."
+msgstr ""
+
+#: doc/classes/Input.xml:43
+msgid ""
+"Adds a new mapping entry (in SDL2 format) to the mapping database. "
+"Optionally update already connected devices."
+msgstr ""
+
+#: doc/classes/Input.xml:50
+msgid ""
+"If the device has an accelerometer, this will return the acceleration. "
+"Otherwise, it returns an empty [Vector3].\n"
+"Note this method returns an empty [Vector3] when running from the editor "
+"even when your device has an accelerometer. You must export your project to "
+"a supported device to read values from the accelerometer."
+msgstr ""
+
+#: doc/classes/Input.xml:60
+msgid ""
+"Returns a value between 0 and 1 representing the intensity of the given "
+"action. In a joypad, for example, the further away the axis (analog sticks "
+"or L2, R2 triggers) is from the dead zone, the closer the value will be to "
+"1. If the action is mapped to a control that has no axis as the keyboard, "
+"the value returned will be 0 or 1."
+msgstr ""
+
+#: doc/classes/Input.xml:67
+msgid ""
+"Returns an [Array] containing the device IDs of all currently connected "
+"joypads."
+msgstr ""
+
+#: doc/classes/Input.xml:74
+msgid "Returns the currently assigned cursor shape (see [enum CursorShape])."
+msgstr ""
+
+#: doc/classes/Input.xml:81
+msgid ""
+"If the device has an accelerometer, this will return the gravity. Otherwise, "
+"it returns an empty [Vector3]."
+msgstr ""
+
+#: doc/classes/Input.xml:88
+msgid ""
+"If the device has a gyroscope, this will return the rate of rotation in rad/"
+"s around a device's X, Y, and Z axes. Otherwise, it returns an empty "
+"[Vector3]."
+msgstr ""
+
+#: doc/classes/Input.xml:99
+msgid ""
+"Returns the current value of the joypad axis at given index (see [enum "
+"JoyAxisList])."
+msgstr ""
+
+#: doc/classes/Input.xml:108
+msgid "Returns the index of the provided axis name."
+msgstr ""
+
+#: doc/classes/Input.xml:117
+msgid ""
+"Receives a [enum JoyAxisList] axis and returns its equivalent name as a "
+"string."
+msgstr ""
+
+#: doc/classes/Input.xml:126
+msgid "Returns the index of the provided button name."
+msgstr ""
+
+#: doc/classes/Input.xml:135
+msgid ""
+"Receives a gamepad button from [enum JoyButtonList] and returns its "
+"equivalent name as a string."
+msgstr ""
+
+#: doc/classes/Input.xml:144
+msgid ""
+"Returns a SDL2-compatible device GUID on platforms that use gamepad "
+"remapping. Returns [code]\"Default Gamepad\"[/code] otherwise."
+msgstr ""
+
+#: doc/classes/Input.xml:153
+msgid "Returns the name of the joypad at the specified device index."
+msgstr ""
+
+#: doc/classes/Input.xml:162
+msgid "Returns the duration of the current vibration effect in seconds."
+msgstr ""
+
+#: doc/classes/Input.xml:171
+msgid ""
+"Returns the strength of the joypad vibration: x is the strength of the weak "
+"motor, and y is the strength of the strong motor."
+msgstr ""
+
+#: doc/classes/Input.xml:178
+msgid ""
+"Returns the mouse speed for the last time the cursor was moved, and this "
+"until the next frame where the mouse moves. This means that even if the "
+"mouse is not moving, this function will still return the value of the last "
+"motion."
+msgstr ""
+
+#: doc/classes/Input.xml:185
+msgid ""
+"If the device has a magnetometer, this will return the magnetic field "
+"strength in micro-Tesla for all axes."
+msgstr ""
+
+#: doc/classes/Input.xml:192
+msgid ""
+"Returns mouse buttons as a bitmask. If multiple mouse buttons are pressed at "
+"the same time, the bits are added together."
+msgstr ""
+
+#: doc/classes/Input.xml:199
+msgid "Returns the mouse mode. See the constants for more information."
+msgstr ""
+
+#: doc/classes/Input.xml:208
+msgid ""
+"Returns [code]true[/code] when the user starts pressing the action event, "
+"meaning it's [code]true[/code] only on the frame that the user pressed down "
+"the button.\n"
+"This is useful for code that needs to run only once when an action is "
+"pressed, instead of every frame while it's pressed."
+msgstr ""
+
+#: doc/classes/Input.xml:218
+msgid ""
+"Returns [code]true[/code] when the user stops pressing the action event, "
+"meaning it's [code]true[/code] only on the frame that the user released the "
+"button."
+msgstr ""
+
+#: doc/classes/Input.xml:227
+msgid ""
+"Returns [code]true[/code] if you are pressing the action event. Note that if "
+"an action has multiple buttons assigned and more than one of them is "
+"pressed, releasing one button will release the action, even if some other "
+"button assigned to this action is still pressed."
+msgstr ""
+
+#: doc/classes/Input.xml:238
+msgid ""
+"Returns [code]true[/code] if you are pressing the joypad button (see [enum "
+"JoyButtonList])."
+msgstr ""
+
+#: doc/classes/Input.xml:247
+msgid ""
+"Returns [code]true[/code] if the system knows the specified device. This "
+"means that it sets all button and axis indices. Unknown joypads are not "
+"expected to match these constants, but you can still retrieve events from them."
+msgstr ""
+
+#: doc/classes/Input.xml:256
+msgid ""
+"Returns [code]true[/code] if you are pressing the key in the current "
+"keyboard layout. You can pass a [enum KeyList] constant."
+msgstr ""
+
+#: doc/classes/Input.xml:265
+msgid ""
+"Returns [code]true[/code] if you are pressing the mouse button specified "
+"with [enum ButtonList]."
+msgstr ""
+
+#: doc/classes/Input.xml:280
+msgid ""
+"Notifies the [Input] singleton that a connection has changed, to update the "
+"state for the [code]device[/code] index.\n"
+"This is used internally and should not have to be called from user scripts. "
+"See [signal joy_connection_changed] for the signal emitted when this is "
+"triggered internally."
+msgstr ""
+
+#: doc/classes/Input.xml:290
+msgid ""
+"Feeds an [InputEvent] to the game. Can be used to artificially trigger input "
+"events from code. Also generates [method Node._input] calls.\n"
+"Example:\n"
+"[codeblock]\n"
+"var a = InputEventAction.new()\n"
+"a.action = \"ui_cancel\"\n"
+"a.pressed = true\n"
+"Input.parse_input_event(a)\n"
+"[/codeblock]"
+msgstr ""
+
+#: doc/classes/Input.xml:306
+msgid ""
+"Removes all mappings from the internal database that match the given GUID."
+msgstr ""
+
+#: doc/classes/Input.xml:319
+msgid ""
+"Sets a custom mouse cursor image, which is only visible inside the game "
+"window. The hotspot can also be specified. Passing [code]null[/code] to the "
+"image parameter resets to the system cursor. See [enum CursorShape] for the "
+"list of shapes.\n"
+"[code]image[/code]'s size must be lower than 256×256.\n"
+"[code]hotspot[/code] must be within [code]image[/code]'s size.\n"
+"[b]Note:[/b] [AnimatedTexture]s aren't supported as custom mouse cursors. If "
+"using an [AnimatedTexture], only the first frame will be displayed.\n"
+"[b]Note:[/b] Only images imported with the [b]Lossless[/b], [b]Lossy[/b] or "
+"[b]Uncompressed[/b] compression modes are supported. The [b]Video RAM[/b] "
+"compression mode can't be used for custom cursors."
+msgstr ""
+
+#: doc/classes/Input.xml:332
+msgid ""
+"Sets the default cursor shape to be used in the viewport instead of "
+"[constant CURSOR_ARROW].\n"
+"[b]Note:[/b] If you want to change the default cursor shape for [Control]'s "
+"nodes, use [member Control.mouse_default_cursor_shape] instead.\n"
+"[b]Note:[/b] This method generates an [InputEventMouseMotion] to update "
+"cursor immediately."
+msgstr ""
+
+#: doc/classes/Input.xml:343
+msgid "Sets the mouse mode. See the constants for more information."
+msgstr ""
+
+#: doc/classes/Input.xml:352
+msgid ""
+"Enables or disables the accumulation of similar input events sent by the "
+"operating system. When input accumulation is enabled, all input events "
+"generated during a frame will be merged and emitted when the frame is done "
+"rendering. Therefore, this limits the number of input method calls per "
+"second to the rendering FPS.\n"
+"Input accumulation is enabled by default. It can be disabled to get slightly "
+"more precise/reactive input at the cost of increased CPU usage. In "
+"applications where drawing freehand lines is required, input accumulation "
+"should generally be disabled while the user is drawing the line to get "
+"results that closely follow the actual input."
+msgstr ""
+
+#: doc/classes/Input.xml:368
+msgid ""
+"Starts to vibrate the joypad. Joypads usually come with two rumble motors, a "
+"strong and a weak one. [code]weak_magnitude[/code] is the strength of the "
+"weak motor (between 0 and 1) and [code]strong_magnitude[/code] is the "
+"strength of the strong motor (between 0 and 1). [code]duration[/code] is the "
+"duration of the effect in seconds (a duration of 0 will try to play the "
+"vibration indefinitely).\n"
+"[b]Note:[/b] Not every hardware is compatible with long effect durations; it "
+"is recommended to restart an effect if it has to be played for more than a "
+"few seconds."
+msgstr ""
+
+#: doc/classes/Input.xml:378
+msgid "Stops the vibration of the joypad."
+msgstr ""
+
+#: doc/classes/Input.xml:387
+msgid ""
+"Vibrate Android and iOS devices.\n"
+"[b]Note:[/b] It needs VIBRATE permission for Android at export settings. iOS "
+"does not support duration."
+msgstr ""
+
+#: doc/classes/Input.xml:397
+msgid "Sets the mouse position to the specified vector."
+msgstr ""
+
+#: doc/classes/Input.xml:408
+msgid "Emitted when a joypad device has been connected or disconnected."
+msgstr ""
+
+#: doc/classes/Input.xml:414
+msgid "Makes the mouse cursor visible if it is hidden."
+msgstr ""
+
+#: doc/classes/Input.xml:417
+msgid "Makes the mouse cursor hidden if it is visible."
+msgstr ""
+
+#: doc/classes/Input.xml:420
+msgid ""
+"Captures the mouse. The mouse will be hidden and unable to leave the game "
+"window, but it will still register movement and mouse button presses. On "
+"Windows and Linux, the mouse will use raw input mode, which means the "
+"reported movement will be unaffected by the OS' mouse acceleration settings."
+msgstr ""
+
+#: doc/classes/Input.xml:423
+msgid "Makes the mouse cursor visible but confines it to the game window."
+msgstr ""
+
+#: doc/classes/Input.xml:426
+msgid "Arrow cursor. Standard, default pointing cursor."
+msgstr ""
+
+#: doc/classes/Input.xml:429
+msgid ""
+"I-beam cursor. Usually used to show where the text cursor will appear when "
+"the mouse is clicked."
+msgstr ""
+
+#: doc/classes/Input.xml:432
+msgid ""
+"Pointing hand cursor. Usually used to indicate the pointer is over a link or "
+"other interactable item."
+msgstr ""
+
+#: doc/classes/Input.xml:435
+msgid ""
+"Cross cursor. Typically appears over regions in which a drawing operation "
+"can be performed or for selections."
+msgstr ""
+
+#: doc/classes/Input.xml:438
+msgid ""
+"Wait cursor. Indicates that the application is busy performing an operation. "
+"This cursor shape denotes that the application is still usable during the "
+"operation."
+msgstr ""
+
+#: doc/classes/Input.xml:441
+msgid ""
+"Busy cursor. Indicates that the application is busy performing an operation. "
+"This cursor shape denotes that the application isn't usable during the "
+"operation (e.g. something is blocking its main thread)."
+msgstr ""
+
+#: doc/classes/Input.xml:444
+msgid "Drag cursor. Usually displayed when dragging something."
+msgstr ""
+
+#: doc/classes/Input.xml:447
+msgid ""
+"Can drop cursor. Usually displayed when dragging something to indicate that "
+"it can be dropped at the current position."
+msgstr ""
+
+#: doc/classes/Input.xml:450
+msgid ""
+"Forbidden cursor. Indicates that the current action is forbidden (for "
+"example, when dragging something) or that the control at a position is "
+"disabled."
+msgstr ""
+
+#: doc/classes/Input.xml:453
+msgid ""
+"Vertical resize mouse cursor. A double-headed vertical arrow. It tells the "
+"user they can resize the window or the panel vertically."
+msgstr ""
+
+#: doc/classes/Input.xml:456
+msgid ""
+"Horizontal resize mouse cursor. A double-headed horizontal arrow. It tells "
+"the user they can resize the window or the panel horizontally."
+msgstr ""
+
+#: doc/classes/Input.xml:459
+msgid ""
+"Window resize mouse cursor. The cursor is a double-headed arrow that goes "
+"from the bottom left to the top right. It tells the user they can resize the "
+"window or the panel both horizontally and vertically."
+msgstr ""
+
+#: doc/classes/Input.xml:462
+msgid ""
+"Window resize mouse cursor. The cursor is a double-headed arrow that goes "
+"from the top left to the bottom right, the opposite of [constant "
+"CURSOR_BDIAGSIZE]. It tells the user they can resize the window or the panel "
+"both horizontally and vertically."
+msgstr ""
+
+#: doc/classes/Input.xml:465
+msgid "Move cursor. Indicates that something can be moved."
+msgstr ""
+
+#: doc/classes/Input.xml:468
+msgid ""
+"Vertical split mouse cursor. On Windows, it's the same as [constant "
+"CURSOR_VSIZE]."
+msgstr ""
+
+#: doc/classes/Input.xml:471
+msgid ""
+"Horizontal split mouse cursor. On Windows, it's the same as [constant "
+"CURSOR_HSIZE]."
+msgstr ""
+
+#: doc/classes/Input.xml:474
+msgid "Help cursor. Usually a question mark."
+msgstr ""
+
#: doc/classes/InputEvent.xml:4
msgid "Generic input event."
msgstr ""
@@ -24896,7 +25149,7 @@ msgid ""
msgstr ""
#: doc/classes/InputEventJoypadButton.xml:16
-msgid "Button identifier. One of the [enum JoystickList] button constants."
+msgid "Button identifier. One of the [enum JoyButtonList] button constants."
msgstr ""
#: doc/classes/InputEventJoypadButton.xml:19
@@ -24924,7 +25177,7 @@ msgid ""
msgstr ""
#: doc/classes/InputEventJoypadMotion.xml:16
-msgid "Axis identifier. Use one of the [enum JoystickList] axis constants."
+msgid "Axis identifier. Use one of the [enum JoyAxisList] axis constants."
msgstr ""
#: doc/classes/InputEventJoypadMotion.xml:19
@@ -24946,8 +25199,8 @@ msgstr ""
#: doc/classes/InputEventKey.xml:17
msgid ""
-"Returns the keycode combined with modifier keys such as [code]Shift[/code] "
-"or [code]Alt[/code]. See also [InputEventWithModifiers].\n"
+"Returns the keycode combined with modifier keys such as [kbd]Shift[/kbd] or "
+"[kbd]Alt[/kbd]. See also [InputEventWithModifiers].\n"
"To get a human-readable representation of the [InputEventKey] with "
"modifiers, use [code]OS.get_keycode_string(event."
"get_keycode_with_modifiers())[/code] where [code]event[/code] is the "
@@ -24956,8 +25209,8 @@ msgstr ""
#: doc/classes/InputEventKey.xml:25
msgid ""
-"Returns the physical keycode combined with modifier keys such as "
-"[code]Shift[/code] or [code]Alt[/code]. See also [InputEventWithModifiers].\n"
+"Returns the physical keycode combined with modifier keys such as [kbd]Shift[/"
+"kbd] or [kbd]Alt[/kbd]. See also [InputEventWithModifiers].\n"
"To get a human-readable representation of the [InputEventKey] with "
"modifiers, use [code]OS.get_keycode_string(event."
"get_physical_keycode_with_modifiers())[/code] where [code]event[/code] is "
@@ -25164,448 +25417,28 @@ msgstr ""
#: doc/classes/InputEventWithModifiers.xml:7
msgid ""
-"Contains keys events information with modifiers support like [code]Shift[/"
-"code] or [code]Alt[/code]. See [method Node._input]."
+"Contains keys events information with modifiers support like [kbd]Shift[/"
+"kbd] or [kbd]Alt[/kbd]. See [method Node._input]."
msgstr ""
#: doc/classes/InputEventWithModifiers.xml:16
-msgid "State of the [code]Alt[/code] modifier."
+msgid "State of the [kbd]Alt[/kbd] modifier."
msgstr ""
#: doc/classes/InputEventWithModifiers.xml:19
-msgid "State of the [code]Command[/code] modifier."
+msgid "State of the [kbd]Cmd[/kbd] modifier."
msgstr ""
#: doc/classes/InputEventWithModifiers.xml:22
-msgid "State of the [code]Ctrl[/code] modifier."
+msgid "State of the [kbd]Ctrl[/kbd] modifier."
msgstr ""
#: doc/classes/InputEventWithModifiers.xml:25
-msgid "State of the [code]Meta[/code] modifier."
+msgid "State of the [kbd]Meta[/kbd] modifier."
msgstr ""
#: doc/classes/InputEventWithModifiers.xml:28
-msgid "State of the [code]Shift[/code] modifier."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:4
-msgid "A singleton that deals with inputs."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:7
-msgid ""
-"A singleton that deals with inputs. This includes key presses, mouse buttons "
-"and movement, joypads, and input actions. Actions and their events can be "
-"set in the [b]Input Map[/b] tab in the [b]Project > Project Settings[/b], or "
-"with the [InputMap] class."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:10
-msgid "https://docs.godotengine.org/en/latest/tutorials/inputs/index.html"
-msgstr ""
-
-#: doc/classes/InputFilter.xml:21
-msgid ""
-"This will simulate pressing the specified action.\n"
-"The strength can be used for non-boolean actions, it's ranged between 0 and "
-"1 representing the intensity of the given action.\n"
-"[b]Note:[/b] This method will not cause any [method Node._input] calls. It "
-"is intended to be used with [method is_action_pressed] and [method "
-"is_action_just_pressed]. If you want to simulate [code]_input[/code], use "
-"[method parse_input_event] instead."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:32
-msgid "If the specified action is already pressed, this will release it."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:43
-msgid ""
-"Adds a new mapping entry (in SDL2 format) to the mapping database. "
-"Optionally update already connected devices."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:50
-msgid ""
-"If the device has an accelerometer, this will return the acceleration. "
-"Otherwise, it returns an empty [Vector3].\n"
-"Note this method returns an empty [Vector3] when running from the editor "
-"even when your device has an accelerometer. You must export your project to "
-"a supported device to read values from the accelerometer."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:60
-msgid ""
-"Returns a value between 0 and 1 representing the intensity of the given "
-"action. In a joypad, for example, the further away the axis (analog sticks "
-"or L2, R2 triggers) is from the dead zone, the closer the value will be to "
-"1. If the action is mapped to a control that has no axis as the keyboard, "
-"the value returned will be 0 or 1."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:67
-msgid ""
-"Returns an [Array] containing the device IDs of all currently connected "
-"joypads."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:74
-msgid "Returns the currently assigned cursor shape (see [enum CursorShape])."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:81
-msgid ""
-"If the device has an accelerometer, this will return the gravity. Otherwise, "
-"it returns an empty [Vector3]."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:88
-msgid ""
-"If the device has a gyroscope, this will return the rate of rotation in rad/"
-"s around a device's X, Y, and Z axes. Otherwise, it returns an empty "
-"[Vector3]."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:99
-msgid ""
-"Returns the current value of the joypad axis at given index (see [enum "
-"JoystickList])."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:108
-msgid "Returns the index of the provided axis name."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:117
-msgid ""
-"Receives a [enum JoystickList] axis and returns its equivalent name as a "
-"string."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:126
-msgid "Returns the index of the provided button name."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:135
-msgid ""
-"Receives a gamepad button from [enum JoystickList] and returns its "
-"equivalent name as a string."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:144
-msgid ""
-"Returns a SDL2-compatible device GUID on platforms that use gamepad "
-"remapping. Returns [code]\"Default Gamepad\"[/code] otherwise."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:153
-msgid "Returns the name of the joypad at the specified device index."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:162
-msgid "Returns the duration of the current vibration effect in seconds."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:171
-msgid ""
-"Returns the strength of the joypad vibration: x is the strength of the weak "
-"motor, and y is the strength of the strong motor."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:178
-msgid ""
-"Returns the mouse speed for the last time the cursor was moved, and this "
-"until the next frame where the mouse moves. This means that even if the "
-"mouse is not moving, this function will still return the value of the last "
-"motion."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:185
-msgid ""
-"If the device has a magnetometer, this will return the magnetic field "
-"strength in micro-Tesla for all axes."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:192
-msgid ""
-"Returns mouse buttons as a bitmask. If multiple mouse buttons are pressed at "
-"the same time, the bits are added together."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:199
-msgid "Returns the mouse mode. See the constants for more information."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:208
-msgid ""
-"Returns [code]true[/code] when the user starts pressing the action event, "
-"meaning it's [code]true[/code] only on the frame that the user pressed down "
-"the button.\n"
-"This is useful for code that needs to run only once when an action is "
-"pressed, instead of every frame while it's pressed."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:218
-msgid ""
-"Returns [code]true[/code] when the user stops pressing the action event, "
-"meaning it's [code]true[/code] only on the frame that the user released the "
-"button."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:227
-msgid ""
-"Returns [code]true[/code] if you are pressing the action event. Note that if "
-"an action has multiple buttons assigned and more than one of them is "
-"pressed, releasing one button will release the action, even if some other "
-"button assigned to this action is still pressed."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:238
-msgid ""
-"Returns [code]true[/code] if you are pressing the joypad button (see [enum "
-"JoystickList])."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:247
-msgid ""
-"Returns [code]true[/code] if the system knows the specified device. This "
-"means that it sets all button and axis indices exactly as defined in [enum "
-"JoystickList]. Unknown joypads are not expected to match these constants, "
-"but you can still retrieve events from them."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:256
-msgid ""
-"Returns [code]true[/code] if you are pressing the key in the current "
-"keyboard layout. You can pass a [enum KeyList] constant."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:265
-msgid ""
-"Returns [code]true[/code] if you are pressing the mouse button specified "
-"with [enum ButtonList]."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:280
-msgid ""
-"Notifies the [InputFilter] singleton that a connection has changed, to "
-"update the state for the [code]device[/code] index.\n"
-"This is used internally and should not have to be called from user scripts. "
-"See [signal joy_connection_changed] for the signal emitted when this is "
-"triggered internally."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:290
-msgid ""
-"Feeds an [InputEvent] to the game. Can be used to artificially trigger input "
-"events from code. Also generates [method Node._input] calls.\n"
-"Example:\n"
-"[codeblock]\n"
-"var a = InputEventAction.new()\n"
-"a.action = \"ui_cancel\"\n"
-"a.pressed = true\n"
-"InputFilter.parse_input_event(a)\n"
-"[/codeblock]"
-msgstr ""
-
-#: doc/classes/InputFilter.xml:306
-msgid ""
-"Removes all mappings from the internal database that match the given GUID."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:319
-msgid ""
-"Sets a custom mouse cursor image, which is only visible inside the game "
-"window. The hotspot can also be specified. Passing [code]null[/code] to the "
-"image parameter resets to the system cursor. See [enum CursorShape] for the "
-"list of shapes.\n"
-"[code]image[/code]'s size must be lower than 256×256.\n"
-"[code]hotspot[/code] must be within [code]image[/code]'s size.\n"
-"[b]Note:[/b] [AnimatedTexture]s aren't supported as custom mouse cursors. If "
-"using an [AnimatedTexture], only the first frame will be displayed.\n"
-"[b]Note:[/b] Only images imported with the [b]Lossless[/b], [b]Lossy[/b] or "
-"[b]Uncompressed[/b] compression modes are supported. The [b]Video RAM[/b] "
-"compression mode can't be used for custom cursors."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:332
-msgid ""
-"Sets the default cursor shape to be used in the viewport instead of "
-"[constant CURSOR_ARROW].\n"
-"[b]Note:[/b] If you want to change the default cursor shape for [Control]'s "
-"nodes, use [member Control.mouse_default_cursor_shape] instead.\n"
-"[b]Note:[/b] This method generates an [InputEventMouseMotion] to update "
-"cursor immediately."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:343
-msgid "Sets the mouse mode. See the constants for more information."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:352
-msgid ""
-"Enables or disables the accumulation of similar input events sent by the "
-"operating system. When input accumulation is enabled, all input events "
-"generated during a frame will be merged and emitted when the frame is done "
-"rendering. Therefore, this limits the number of input method calls per "
-"second to the rendering FPS.\n"
-"Input accumulation is enabled by default. It can be disabled to get slightly "
-"more precise/reactive input at the cost of increased CPU usage. In "
-"applications where drawing freehand lines is required, input accumulation "
-"should generally be disabled while the user is drawing the line to get "
-"results that closely follow the actual input."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:368
-msgid ""
-"Starts to vibrate the joypad. Joypads usually come with two rumble motors, a "
-"strong and a weak one. [code]weak_magnitude[/code] is the strength of the "
-"weak motor (between 0 and 1) and [code]strong_magnitude[/code] is the "
-"strength of the strong motor (between 0 and 1). [code]duration[/code] is the "
-"duration of the effect in seconds (a duration of 0 will try to play the "
-"vibration indefinitely).\n"
-"[b]Note:[/b] Not every hardware is compatible with long effect durations; it "
-"is recommended to restart an effect if it has to be played for more than a "
-"few seconds."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:378
-msgid "Stops the vibration of the joypad."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:387
-msgid ""
-"Vibrate Android and iOS devices.\n"
-"[b]Note:[/b] It needs VIBRATE permission for Android at export settings. iOS "
-"does not support duration."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:397
-msgid "Sets the mouse position to the specified vector."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:408
-msgid "Emitted when a joypad device has been connected or disconnected."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:414
-msgid "Makes the mouse cursor visible if it is hidden."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:417
-msgid "Makes the mouse cursor hidden if it is visible."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:420
-msgid ""
-"Captures the mouse. The mouse will be hidden and unable to leave the game "
-"window, but it will still register movement and mouse button presses. On "
-"Windows and Linux, the mouse will use raw input mode, which means the "
-"reported movement will be unaffected by the OS' mouse acceleration settings."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:423
-msgid "Makes the mouse cursor visible but confines it to the game window."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:426
-msgid "Arrow cursor. Standard, default pointing cursor."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:429
-msgid ""
-"I-beam cursor. Usually used to show where the text cursor will appear when "
-"the mouse is clicked."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:432
-msgid ""
-"Pointing hand cursor. Usually used to indicate the pointer is over a link or "
-"other interactable item."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:435
-msgid ""
-"Cross cursor. Typically appears over regions in which a drawing operation "
-"can be performed or for selections."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:438
-msgid ""
-"Wait cursor. Indicates that the application is busy performing an operation. "
-"This cursor shape denotes that the application is still usable during the "
-"operation."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:441
-msgid ""
-"Busy cursor. Indicates that the application is busy performing an operation. "
-"This cursor shape denotes that the application isn't usable during the "
-"operation (e.g. something is blocking its main thread)."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:444
-msgid "Drag cursor. Usually displayed when dragging something."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:447
-msgid ""
-"Can drop cursor. Usually displayed when dragging something to indicate that "
-"it can be dropped at the current position."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:450
-msgid ""
-"Forbidden cursor. Indicates that the current action is forbidden (for "
-"example, when dragging something) or that the control at a position is "
-"disabled."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:453
-msgid ""
-"Vertical resize mouse cursor. A double-headed vertical arrow. It tells the "
-"user they can resize the window or the panel vertically."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:456
-msgid ""
-"Horizontal resize mouse cursor. A double-headed horizontal arrow. It tells "
-"the user they can resize the window or the panel horizontally."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:459
-msgid ""
-"Window resize mouse cursor. The cursor is a double-headed arrow that goes "
-"from the bottom left to the top right. It tells the user they can resize the "
-"window or the panel both horizontally and vertically."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:462
-msgid ""
-"Window resize mouse cursor. The cursor is a double-headed arrow that goes "
-"from the top left to the bottom right, the opposite of [constant "
-"CURSOR_BDIAGSIZE]. It tells the user they can resize the window or the panel "
-"both horizontally and vertically."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:465
-msgid "Move cursor. Indicates that something can be moved."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:468
-msgid ""
-"Vertical split mouse cursor. On Windows, it's the same as [constant "
-"CURSOR_VSIZE]."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:471
-msgid ""
-"Horizontal split mouse cursor. On Windows, it's the same as [constant "
-"CURSOR_HSIZE]."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:474
-msgid "Help cursor. Usually a question mark."
+msgid "State of the [kbd]Shift[/kbd] modifier."
msgstr ""
#: doc/classes/InputMap.xml:4
@@ -25876,14 +25709,6 @@ msgstr ""
msgid "Address type: Any."
msgstr ""
-#: doc/classes/IP_Unix.xml:4
-msgid "UNIX IP support. See [IP]."
-msgstr ""
-
-#: doc/classes/IP_Unix.xml:7
-msgid "UNIX-specific implementation of IP support functions. See [IP]."
-msgstr ""
-
#: doc/classes/ItemList.xml:4
msgid ""
"Control that provides a list of selectable items (and/or icons) in a single "
@@ -25898,7 +25723,7 @@ msgid ""
"Selectable items in the list may be selected or deselected and multiple "
"selection may be enabled. Selection with right mouse button may also be "
"enabled to allow use of popup context menus. Items may also be \"activated\" "
-"by double-clicking them or by pressing Enter.\n"
+"by double-clicking them or by pressing [kbd]Enter[/kbd].\n"
"Item text only supports single-line strings, newline characters (e.g. "
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
@@ -26057,7 +25882,7 @@ msgstr ""
msgid ""
"Disables (or enables) the item at the specified index.\n"
"Disabled items cannot be selected and do not trigger activation signals "
-"(when double-clicking or pressing Enter)."
+"(when double-clicking or pressing [kbd]Enter[/kbd])."
msgstr ""
#: doc/classes/ItemList.xml:292
@@ -26192,7 +26017,7 @@ msgstr ""
#: doc/classes/ItemList.xml:455
msgid ""
"Triggered when specified list item is activated via double-clicking or by "
-"pressing Enter."
+"pressing [kbd]Enter[/kbd]."
msgstr ""
#: doc/classes/ItemList.xml:464
@@ -26242,7 +26067,9 @@ msgid "Only allow selecting a single item."
msgstr ""
#: doc/classes/ItemList.xml:511
-msgid "Allows selecting multiple items by holding Ctrl or Shift."
+msgid ""
+"Allows selecting multiple items by holding [kbd]Ctrl[/kbd] or [kbd]Shift[/"
+"kbd]."
msgstr ""
#: doc/classes/ItemList.xml:516
@@ -27233,59 +27060,91 @@ msgid ""
msgstr ""
#: doc/classes/Light3D.xml:39
-msgid "The light's bake mode. See [enum BakeMode]."
+msgid ""
+"Angular size of the light in degrees. Only available for "
+"[DirectionalLight3D]s. For reference, the sun from earth is approximately "
+"[code]0.5[/code]."
msgstr ""
#: doc/classes/Light3D.xml:42
-msgid "The light's color."
+msgid "The light's bake mode. See [enum BakeMode]."
msgstr ""
#: doc/classes/Light3D.xml:45
-msgid "The light will affect objects in the selected layers."
+msgid "The light's color."
msgstr ""
#: doc/classes/Light3D.xml:48
-msgid "The light's strength multiplier."
+msgid "The light will affect objects in the selected layers."
msgstr ""
#: doc/classes/Light3D.xml:51
+msgid "The light's strength multiplier."
+msgstr ""
+
+#: doc/classes/Light3D.xml:54
msgid ""
"Secondary multiplier used with indirect light (light bounces). Used with "
"[GIProbe]."
msgstr ""
-#: doc/classes/Light3D.xml:54
+#: doc/classes/Light3D.xml:57
msgid ""
"If [code]true[/code], the light's effect is reversed, darkening areas and "
"casting bright shadows."
msgstr ""
-#: doc/classes/Light3D.xml:57
+#: doc/classes/Light3D.xml:60
+msgid ""
+"[Texture2D] projected by light. [member shadow_enabled] must be on for the "
+"projector to work. Light projectors make the light appear as if it is "
+"shining through a colored but transparent object, almost like light shining "
+"through stained glass."
+msgstr ""
+
+#: doc/classes/Light3D.xml:63
+msgid ""
+"The size of the light in Godot units. Only available for [OmniLight3D]s and "
+"[SpotLight3D]s."
+msgstr ""
+
+#: doc/classes/Light3D.xml:66
msgid ""
"The intensity of the specular blob in objects affected by the light. At "
"[code]0[/code] the light becomes a pure diffuse light."
msgstr ""
-#: doc/classes/Light3D.xml:60
+#: doc/classes/Light3D.xml:69
msgid ""
"Used to adjust shadow appearance. Too small a value results in self-"
"shadowing, while too large a value causes shadows to separate from casters. "
"Adjust as needed."
msgstr ""
-#: doc/classes/Light3D.xml:63
-msgid "The color of shadows cast by this light."
+#: doc/classes/Light3D.xml:72 doc/classes/RenderingServer.xml:3374
+msgid ""
+"Blurs the edges of the shadow. Can be used to hide pixel artifacts in low "
+"resolution shadow maps. A high value can make shadows appear grainy and can "
+"cause other unwanted artifacts. Try to keep as near default as possible."
msgstr ""
-#: doc/classes/Light3D.xml:66
-msgid "Attempts to reduce [member shadow_bias] gap."
+#: doc/classes/Light3D.xml:75
+msgid "The color of shadows cast by this light."
msgstr ""
-#: doc/classes/Light3D.xml:69
+#: doc/classes/Light3D.xml:78
msgid "If [code]true[/code], the light will cast shadows."
msgstr ""
-#: doc/classes/Light3D.xml:72
+#: doc/classes/Light3D.xml:81
+msgid ""
+"Offsets the lookup into the shadow map by the objects normal. This can be "
+"used reduce self-shadowing artifacts without using [member shadow_bias]. In "
+"practice, this value should be tweaked along with [member shadow_bias] to "
+"reduce artifacts as much as possible."
+msgstr ""
+
+#: doc/classes/Light3D.xml:84
msgid ""
"If [code]true[/code], reverses the backface culling of the mesh. This can be "
"useful when you have a flat mesh that has a light behind it. If you need to "
@@ -27294,93 +27153,105 @@ msgid ""
"SHADOW_CASTING_SETTING_DOUBLE_SIDED]."
msgstr ""
-#: doc/classes/Light3D.xml:77
+#: doc/classes/Light3D.xml:91
msgid "Constant for accessing [member light_energy]."
msgstr ""
-#: doc/classes/Light3D.xml:80
+#: doc/classes/Light3D.xml:94
msgid "Constant for accessing [member light_indirect_energy]."
msgstr ""
-#: doc/classes/Light3D.xml:83
+#: doc/classes/Light3D.xml:97
msgid "Constant for accessing [member light_specular]."
msgstr ""
-#: doc/classes/Light3D.xml:86
+#: doc/classes/Light3D.xml:100
msgid ""
"Constant for accessing [member OmniLight3D.omni_range] or [member "
"SpotLight3D.spot_range]."
msgstr ""
-#: doc/classes/Light3D.xml:89
+#: doc/classes/Light3D.xml:103
+msgid "Constant for accessing [member light_size]."
+msgstr ""
+
+#: doc/classes/Light3D.xml:106
msgid ""
"Constant for accessing [member OmniLight3D.omni_attenuation] or [member "
"SpotLight3D.spot_attenuation]."
msgstr ""
-#: doc/classes/Light3D.xml:92
+#: doc/classes/Light3D.xml:109
msgid "Constant for accessing [member SpotLight3D.spot_angle]."
msgstr ""
-#: doc/classes/Light3D.xml:95
+#: doc/classes/Light3D.xml:112
msgid "Constant for accessing [member SpotLight3D.spot_angle_attenuation]."
msgstr ""
-#: doc/classes/Light3D.xml:98
-msgid "Constant for accessing [member shadow_contact]."
-msgstr ""
-
-#: doc/classes/Light3D.xml:101
+#: doc/classes/Light3D.xml:115
msgid ""
"Constant for accessing [member DirectionalLight3D."
"directional_shadow_max_distance]."
msgstr ""
-#: doc/classes/Light3D.xml:104
+#: doc/classes/Light3D.xml:118
msgid ""
"Constant for accessing [member DirectionalLight3D."
"directional_shadow_split_1]."
msgstr ""
-#: doc/classes/Light3D.xml:107
+#: doc/classes/Light3D.xml:121
msgid ""
"Constant for accessing [member DirectionalLight3D."
"directional_shadow_split_2]."
msgstr ""
-#: doc/classes/Light3D.xml:110
+#: doc/classes/Light3D.xml:124
msgid ""
"Constant for accessing [member DirectionalLight3D."
"directional_shadow_split_3]."
msgstr ""
-#: doc/classes/Light3D.xml:115
+#: doc/classes/Light3D.xml:127
msgid ""
"Constant for accessing [member DirectionalLight3D."
-"directional_shadow_normal_bias]."
+"directional_shadow_fade_start]."
msgstr ""
-#: doc/classes/Light3D.xml:118
+#: doc/classes/Light3D.xml:130
+msgid "Constant for accessing [member shadow_normal_bias]."
+msgstr ""
+
+#: doc/classes/Light3D.xml:133
msgid "Constant for accessing [member shadow_bias]."
msgstr ""
-#: doc/classes/Light3D.xml:121
+#: doc/classes/Light3D.xml:136
msgid ""
"Constant for accessing [member DirectionalLight3D."
-"directional_shadow_bias_split_scale]."
+"directional_shadow_pancake_size]."
msgstr ""
-#: doc/classes/Light3D.xml:127
+#: doc/classes/Light3D.xml:139
+msgid "Constant for accessing [member shadow_blur]."
+msgstr ""
+
+#: doc/classes/Light3D.xml:142
+msgid "Constant for accessing [member shadow_transmittance_bias]."
+msgstr ""
+
+#: doc/classes/Light3D.xml:148
msgid ""
"Light is ignored when baking.\n"
"[b]Note:[/b] Hiding a light does [i]not[/i] affect baking."
msgstr ""
-#: doc/classes/Light3D.xml:131
+#: doc/classes/Light3D.xml:152
msgid "Only indirect lighting will be baked (default)."
msgstr ""
-#: doc/classes/Light3D.xml:134
+#: doc/classes/Light3D.xml:155
msgid ""
"Both direct and indirect light will be baked.\n"
"[b]Note:[/b] You should hide the light if you don't want it to appear twice "
@@ -27571,32 +27442,40 @@ msgstr ""
msgid ""
"LineEdit provides a single-line string editor, used for text fields.\n"
"It features many built-in shortcuts which will always be available "
-"([code]Ctrl[/code] here maps to [code]Command[/code] on macOS):\n"
-"- Ctrl + C: Copy\n"
-"- Ctrl + X: Cut\n"
-"- Ctrl + V or Ctrl + Y: Paste/\"yank\"\n"
-"- Ctrl + Z: Undo\n"
-"- Ctrl + Shift + Z: Redo\n"
-"- Ctrl + U: Delete text from the cursor position to the beginning of the "
-"line\n"
-"- Ctrl + K: Delete text from the cursor position to the end of the line\n"
-"- Ctrl + A: Select all text\n"
-"- Up/Down arrow: Move the cursor to the beginning/end of the line\n"
-"On macOS, some extra keyboard shortcuts are available:\n"
-"- Ctrl + F: Like the right arrow key, move the cursor one character right\n"
-"- Ctrl + B: Like the left arrow key, move the cursor one character left\n"
-"- Ctrl + P: Like the up arrow key, move the cursor to the previous line\n"
-"- Ctrl + N: Like the down arrow key, move the cursor to the next line\n"
-"- Ctrl + D: Like the Delete key, delete the character on the right side of "
-"cursor\n"
-"- Ctrl + H: Like the Backspace key, delete the character on the left side of "
-"the cursor\n"
-"- Ctrl + A: Like the Home key, move the cursor to the beginning of the line\n"
-"- Ctrl + E: Like the End key, move the cursor to the end of the line\n"
-"- Command + Left arrow: Like the Home key, move the cursor to the beginning "
+"([kbd]Ctrl[/kbd] here maps to [kbd]Cmd[/kbd] on macOS):\n"
+"- [kbd]Ctrl + C[/kbd]: Copy\n"
+"- [kbd]Ctrl + X[/kbd]: Cut\n"
+"- [kbd]Ctrl + V[/kbd] or [kbd]Ctrl + Y[/kbd]: Paste/\"yank\"\n"
+"- [kbd]Ctrl + Z[/kbd]: Undo\n"
+"- [kbd]Ctrl + Shift + Z[/kbd]: Redo\n"
+"- [kbd]Ctrl + U[/kbd]: Delete text from the cursor position to the beginning "
"of the line\n"
-"- Command + Right arrow: Like the End key, move the cursor to the end of the "
-"line"
+"- [kbd]Ctrl + K[/kbd]: Delete text from the cursor position to the end of "
+"the line\n"
+"- [kbd]Ctrl + A[/kbd]: Select all text\n"
+"- [kbd]Up Arrow[/kbd]/[kbd]Down Arrow[/kbd]: Move the cursor to the "
+"beginning/end of the line\n"
+"On macOS, some extra keyboard shortcuts are available:\n"
+"- [kbd]Ctrl + F[/kbd]: Same as [kbd]Right Arrow[/kbd], move the cursor one "
+"character right\n"
+"- [kbd]Ctrl + B[/kbd]: Same as [kbd]Left Arrow[/kbd], move the cursor one "
+"character left\n"
+"- [kbd]Ctrl + P[/kbd]: Same as [kbd]Up Arrow[/kbd], move the cursor to the "
+"previous line\n"
+"- [kbd]Ctrl + N[/kbd]: Same as [kbd]Down Arrow[/kbd], move the cursor to the "
+"next line\n"
+"- [kbd]Ctrl + D[/kbd]: Same as [kbd]Delete[/kbd], delete the character on "
+"the right side of cursor\n"
+"- [kbd]Ctrl + H[/kbd]: Same as [kbd]Backspace[/kbd], delete the character on "
+"the left side of the cursor\n"
+"- [kbd]Ctrl + A[/kbd]: Same as [kbd]Home[/kbd], move the cursor to the "
+"beginning of the line\n"
+"- [kbd]Ctrl + E[/kbd]: Same as [kbd]End[/kbd], move the cursor to the end of "
+"the line\n"
+"- [kbd]Cmd + Left Arrow[/kbd]: Same as [kbd]Home[/kbd], move the cursor to "
+"the beginning of the line\n"
+"- [kbd]Cmd + Right Arrow[/kbd]: Same as [kbd]End[/kbd], move the cursor to "
+"the end of the line"
msgstr ""
#: doc/classes/LineEdit.xml:39
@@ -27741,7 +27620,7 @@ msgid ""
"max_length]."
msgstr ""
-#: doc/classes/LineEdit.xml:163 doc/classes/TextEdit.xml:513
+#: doc/classes/LineEdit.xml:163 doc/classes/TextEdit.xml:514
msgid "Emitted when the text changes."
msgstr ""
@@ -27765,11 +27644,11 @@ msgstr ""
msgid "Stretches whitespaces to fit the [LineEdit]'s width."
msgstr ""
-#: doc/classes/LineEdit.xml:188 doc/classes/TextEdit.xml:534
+#: doc/classes/LineEdit.xml:188 doc/classes/TextEdit.xml:535
msgid "Cuts (copies and clears) the selected text."
msgstr ""
-#: doc/classes/LineEdit.xml:191 doc/classes/TextEdit.xml:537
+#: doc/classes/LineEdit.xml:191 doc/classes/TextEdit.xml:538
msgid "Copies the selected text."
msgstr ""
@@ -27789,7 +27668,7 @@ msgstr ""
msgid "Selects the whole [LineEdit] text."
msgstr ""
-#: doc/classes/LineEdit.xml:204 doc/classes/TextEdit.xml:549
+#: doc/classes/LineEdit.xml:204 doc/classes/TextEdit.xml:550
msgid "Undoes the previous action."
msgstr ""
@@ -27797,7 +27676,7 @@ msgstr ""
msgid "Reverse the last undo action."
msgstr ""
-#: doc/classes/LineEdit.xml:210 doc/classes/TextEdit.xml:555
+#: doc/classes/LineEdit.xml:210 doc/classes/TextEdit.xml:556
msgid "Represents the size of the [enum MenuItems] enum."
msgstr ""
@@ -28427,11 +28306,11 @@ msgstr ""
msgid "Render array as triangle strips."
msgstr ""
-#: doc/classes/Mesh.xml:126 doc/classes/RenderingServer.xml:3254
+#: doc/classes/Mesh.xml:126 doc/classes/RenderingServer.xml:3306
msgid "Blend shapes are normalized."
msgstr ""
-#: doc/classes/Mesh.xml:129 doc/classes/RenderingServer.xml:3257
+#: doc/classes/Mesh.xml:129 doc/classes/RenderingServer.xml:3309
msgid "Blend shapes are relative to base weight."
msgstr ""
@@ -28473,37 +28352,37 @@ msgstr ""
msgid "Mesh array uses indices."
msgstr ""
-#: doc/classes/Mesh.xml:159 doc/classes/RenderingServer.xml:3210
+#: doc/classes/Mesh.xml:159 doc/classes/RenderingServer.xml:3262
msgid "Flag used to mark a compressed (half float) normal array."
msgstr ""
-#: doc/classes/Mesh.xml:162 doc/classes/RenderingServer.xml:3213
+#: doc/classes/Mesh.xml:162 doc/classes/RenderingServer.xml:3265
msgid "Flag used to mark a compressed (half float) tangent array."
msgstr ""
-#: doc/classes/Mesh.xml:165 doc/classes/RenderingServer.xml:3216
+#: doc/classes/Mesh.xml:165 doc/classes/RenderingServer.xml:3268
msgid "Flag used to mark a compressed (half float) color array."
msgstr ""
-#: doc/classes/Mesh.xml:168 doc/classes/RenderingServer.xml:3219
+#: doc/classes/Mesh.xml:168 doc/classes/RenderingServer.xml:3271
msgid "Flag used to mark a compressed (half float) UV coordinates array."
msgstr ""
-#: doc/classes/Mesh.xml:171 doc/classes/RenderingServer.xml:3222
+#: doc/classes/Mesh.xml:171 doc/classes/RenderingServer.xml:3274
msgid ""
"Flag used to mark a compressed (half float) UV coordinates array for the "
"second UV coordinates."
msgstr ""
-#: doc/classes/Mesh.xml:174 doc/classes/RenderingServer.xml:3225
+#: doc/classes/Mesh.xml:174 doc/classes/RenderingServer.xml:3277
msgid "Flag used to mark a compressed index array."
msgstr ""
-#: doc/classes/Mesh.xml:177 doc/classes/RenderingServer.xml:3228
+#: doc/classes/Mesh.xml:177 doc/classes/RenderingServer.xml:3283
msgid "Flag used to mark that the array contains 2D vertices."
msgstr ""
-#: doc/classes/Mesh.xml:180 doc/classes/RenderingServer.xml:3233
+#: doc/classes/Mesh.xml:180 doc/classes/RenderingServer.xml:3280
msgid ""
"Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant "
"ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant "
@@ -28568,67 +28447,72 @@ msgid ""
" mdt.set_vertex(i, vertex)\n"
"mesh.surface_remove(0)\n"
"mdt.commit_to_surface(mesh)\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"See also [ArrayMesh], [ImmediateGeometry3D] and [SurfaceTool] for procedural "
+"geometry generation.\n"
+"[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-"
+"OpenGL/Face-culling]winding order[/url] for front faces of triangle "
+"primitive modes."
msgstr ""
-#: doc/classes/MeshDataTool.xml:28
+#: doc/classes/MeshDataTool.xml:30
msgid "Clears all data currently in MeshDataTool."
msgstr ""
-#: doc/classes/MeshDataTool.xml:37
+#: doc/classes/MeshDataTool.xml:39
msgid "Adds a new surface to specified [Mesh] with edited data."
msgstr ""
-#: doc/classes/MeshDataTool.xml:48
+#: doc/classes/MeshDataTool.xml:50
msgid ""
"Uses specified surface of given [Mesh] to populate data for MeshDataTool.\n"
"Requires [Mesh] with primitive type [constant Mesh.PRIMITIVE_TRIANGLES]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:56
+#: doc/classes/MeshDataTool.xml:58
msgid "Returns the number of edges in this [Mesh]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:65
+#: doc/classes/MeshDataTool.xml:67
msgid "Returns array of faces that touch given edge."
msgstr ""
-#: doc/classes/MeshDataTool.xml:74
+#: doc/classes/MeshDataTool.xml:76
msgid "Returns meta information assigned to given edge."
msgstr ""
-#: doc/classes/MeshDataTool.xml:85
+#: doc/classes/MeshDataTool.xml:87
msgid ""
"Returns index of specified vertex connected to given edge.\n"
"Vertex argument can only be 0 or 1 because edges are comprised of two "
"vertices."
msgstr ""
-#: doc/classes/MeshDataTool.xml:93
+#: doc/classes/MeshDataTool.xml:95
msgid "Returns the number of faces in this [Mesh]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:104
+#: doc/classes/MeshDataTool.xml:106
msgid ""
"Returns specified edge associated with given face.\n"
"Edge argument must 2 or less because a face only has three edges."
msgstr ""
-#: doc/classes/MeshDataTool.xml:114
+#: doc/classes/MeshDataTool.xml:116
msgid "Returns the metadata associated with the given face."
msgstr ""
-#: doc/classes/MeshDataTool.xml:123
+#: doc/classes/MeshDataTool.xml:125
msgid "Calculates and returns the face normal of the given face."
msgstr ""
-#: doc/classes/MeshDataTool.xml:134
+#: doc/classes/MeshDataTool.xml:136
msgid ""
"Returns the specified vertex of the given face.\n"
"Vertex argument must be 2 or less because faces contain three vertices."
msgstr ""
-#: doc/classes/MeshDataTool.xml:142
+#: doc/classes/MeshDataTool.xml:144
msgid ""
"Returns the [Mesh]'s format. Format is an integer made up of [Mesh] format "
"flags combined together. For example, a mesh containing both vertices and "
@@ -28638,103 +28522,103 @@ msgid ""
"See [enum ArrayMesh.ArrayFormat] for a list of format flags."
msgstr ""
-#: doc/classes/MeshDataTool.xml:150
+#: doc/classes/MeshDataTool.xml:152
msgid "Returns the material assigned to the [Mesh]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:159
+#: doc/classes/MeshDataTool.xml:161
msgid "Returns the vertex at given index."
msgstr ""
-#: doc/classes/MeshDataTool.xml:168
+#: doc/classes/MeshDataTool.xml:170
msgid "Returns the bones of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:177
+#: doc/classes/MeshDataTool.xml:179
msgid "Returns the color of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:184
+#: doc/classes/MeshDataTool.xml:186
msgid "Returns the total number of vertices in [Mesh]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:193
+#: doc/classes/MeshDataTool.xml:195
msgid "Returns an array of edges that share the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:202
+#: doc/classes/MeshDataTool.xml:204
msgid "Returns an array of faces that share the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:211
+#: doc/classes/MeshDataTool.xml:213
msgid "Returns the metadata associated with the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:220
+#: doc/classes/MeshDataTool.xml:222
msgid "Returns the normal of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:229
+#: doc/classes/MeshDataTool.xml:231
msgid "Returns the tangent of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:238
+#: doc/classes/MeshDataTool.xml:240
msgid "Returns the UV of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:247
+#: doc/classes/MeshDataTool.xml:249
msgid "Returns the UV2 of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:256
+#: doc/classes/MeshDataTool.xml:258
msgid "Returns bone weights of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:267
+#: doc/classes/MeshDataTool.xml:269
msgid "Sets the metadata of the given edge."
msgstr ""
-#: doc/classes/MeshDataTool.xml:278
+#: doc/classes/MeshDataTool.xml:280
msgid "Sets the metadata of the given face."
msgstr ""
-#: doc/classes/MeshDataTool.xml:287
+#: doc/classes/MeshDataTool.xml:289
msgid "Sets the material to be used by newly-constructed [Mesh]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:298
+#: doc/classes/MeshDataTool.xml:300
msgid "Sets the position of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:309
+#: doc/classes/MeshDataTool.xml:311
msgid "Sets the bones of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:320
+#: doc/classes/MeshDataTool.xml:322
msgid "Sets the color of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:331
+#: doc/classes/MeshDataTool.xml:333
msgid "Sets the metadata associated with the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:342
+#: doc/classes/MeshDataTool.xml:344
msgid "Sets the normal of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:353
+#: doc/classes/MeshDataTool.xml:355
msgid "Sets the tangent of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:364
+#: doc/classes/MeshDataTool.xml:366
msgid "Sets the UV of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:375
+#: doc/classes/MeshDataTool.xml:377
msgid "Sets the UV2 of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:386
+#: doc/classes/MeshDataTool.xml:388
msgid "Sets the bone weights of the given vertex."
msgstr ""
@@ -28980,9 +28864,9 @@ msgid ""
"setting [member eye_height].\n"
"You can initialise this interface as follows:\n"
"[codeblock]\n"
-"var interface = ARVRServer.find_interface(\"Native mobile\")\n"
+"var interface = XRServer.find_interface(\"Native mobile\")\n"
"if interface and interface.initialize():\n"
-" get_viewport().arvr = true\n"
+" get_viewport().xr = true\n"
"[/codeblock]"
msgstr ""
@@ -28999,7 +28883,7 @@ msgstr ""
#: modules/mobile_vr/doc_classes/MobileVRInterface.xml:28
msgid ""
"The height at which the camera is placed in relation to the ground (i.e. "
-"[ARVROrigin] node)."
+"[XROrigin3D] node)."
msgstr ""
#: modules/mobile_vr/doc_classes/MobileVRInterface.xml:31
@@ -31479,7 +31363,7 @@ msgstr ""
#: doc/classes/Node.xml:935
msgid ""
"Notification received from the OS when a close request is sent (e.g. closing "
-"the window with a \"Close\" button or Alt+F4).\n"
+"the window with a \"Close\" button or [kbd]Alt + F4[/kbd]).\n"
"Implemented on desktop platforms."
msgstr ""
@@ -31581,11 +31465,21 @@ msgid ""
msgstr ""
#: doc/classes/Node2D.xml:95
-msgid "Converts a local point's coordinates to global coordinates."
+msgid ""
+"Transforms the provided local position into a position in global coordinate "
+"space. The input is expected to be local relative to the [Node2D] it is "
+"called on. e.g. Applying this method to the positions of child nodes will "
+"correctly transform their positions into the global coordinate space, but "
+"applying it to a node's own position will give an incorrect result, as it "
+"will incorporate the node's own transformation into its global position."
msgstr ""
#: doc/classes/Node2D.xml:104
-msgid "Converts a global point's coordinates to local coordinates."
+msgid ""
+"Transforms the provided global position into a position in local coordinate "
+"space. The output will be local relative to the [Node2D] it is called on. e."
+"g. It is appropriate for determining the positions of child nodes, but it is "
+"not appropriate for determining its own position relative to its parent."
msgstr ""
#: doc/classes/Node2D.xml:113
@@ -31660,80 +31554,83 @@ msgid ""
"operations in this coordinate system correspond to direct affine operations "
"on the [Node3D]'s transform. The word local below refers to this coordinate "
"system. The coordinate system that is attached to the [Node3D] object itself "
-"is referred to as object-local coordinate system."
+"is referred to as object-local coordinate system.\n"
+"[b]Note:[/b] Unless otherwise specified, all methods that have angle "
+"parameters must have angles specified as [i]radians[/i]. To convert degrees "
+"to radians, use [method @GDScript.deg2rad]."
msgstr ""
-#: doc/classes/Node3D.xml:11
+#: doc/classes/Node3D.xml:12
msgid ""
"https://docs.godotengine.org/en/latest/tutorials/3d/introduction_to_3d.html"
msgstr ""
-#: doc/classes/Node3D.xml:25
+#: doc/classes/Node3D.xml:26
msgid ""
"Returns the parent [Node3D], or an empty [Object] if no parent exists or "
"parent is not of type [Node3D]."
msgstr ""
-#: doc/classes/Node3D.xml:32
+#: doc/classes/Node3D.xml:33
msgid ""
"Returns the current [World3D] resource this [Node3D] node is registered to."
msgstr ""
-#: doc/classes/Node3D.xml:43
+#: doc/classes/Node3D.xml:44
msgid ""
"Rotates the global (world) transformation around axis, a unit [Vector3], by "
"specified angle in radians. The rotation axis is in global coordinate system."
msgstr ""
-#: doc/classes/Node3D.xml:52
+#: doc/classes/Node3D.xml:53
msgid ""
"Scales the global (world) transformation by the given [Vector3] scale "
"factors."
msgstr ""
-#: doc/classes/Node3D.xml:61
+#: doc/classes/Node3D.xml:62
msgid ""
"Moves the global (world) transformation by [Vector3] offset. The offset is "
"in global coordinate system."
msgstr ""
-#: doc/classes/Node3D.xml:68
+#: doc/classes/Node3D.xml:69
msgid ""
"Disables rendering of this node. Changes [member visible] to [code]false[/"
"code]."
msgstr ""
-#: doc/classes/Node3D.xml:75
+#: doc/classes/Node3D.xml:76
msgid ""
"Returns whether node notifies about its local transformation changes. "
"[Node3D] will not propagate this by default."
msgstr ""
-#: doc/classes/Node3D.xml:82
+#: doc/classes/Node3D.xml:83
msgid ""
"Returns whether this node uses a scale of [code](1, 1, 1)[/code] or its "
"local transformation scale."
msgstr ""
-#: doc/classes/Node3D.xml:89
+#: doc/classes/Node3D.xml:90
msgid ""
"Returns whether this node is set as Toplevel, that is whether it ignores its "
"parent nodes transformations."
msgstr ""
-#: doc/classes/Node3D.xml:96
+#: doc/classes/Node3D.xml:97
msgid ""
"Returns whether the node notifies about its global and local transformation "
"changes. [Node3D] will not propagate this by default."
msgstr ""
-#: doc/classes/Node3D.xml:103
+#: doc/classes/Node3D.xml:104
msgid ""
"Returns whether the node is visible, taking into consideration that its "
"parents visibility."
msgstr ""
-#: doc/classes/Node3D.xml:114
+#: doc/classes/Node3D.xml:115
msgid ""
"Rotates itself so that the local -Z axis points towards the [code]target[/"
"code] position.\n"
@@ -31743,106 +31640,106 @@ msgid ""
"Operations take place in global space."
msgstr ""
-#: doc/classes/Node3D.xml:129
+#: doc/classes/Node3D.xml:130
msgid ""
"Moves the node to the specified [code]position[/code], and then rotates "
"itself to point toward the [code]target[/code] as per [method look_at]. "
"Operations take place in global space."
msgstr ""
-#: doc/classes/Node3D.xml:136
+#: doc/classes/Node3D.xml:137
msgid ""
"Resets this node's transformations (like scale, skew and taper) preserving "
"its rotation and translation by performing Gram-Schmidt orthonormalization "
"on this node's [Transform]."
msgstr ""
-#: doc/classes/Node3D.xml:147
+#: doc/classes/Node3D.xml:148
msgid ""
"Rotates the local transformation around axis, a unit [Vector3], by specified "
"angle in radians."
msgstr ""
-#: doc/classes/Node3D.xml:158
+#: doc/classes/Node3D.xml:159
msgid ""
"Rotates the local transformation around axis, a unit [Vector3], by specified "
"angle in radians. The rotation axis is in object-local coordinate system."
msgstr ""
-#: doc/classes/Node3D.xml:167
+#: doc/classes/Node3D.xml:168
msgid "Rotates the local transformation around the X axis by angle in radians."
msgstr ""
-#: doc/classes/Node3D.xml:176
+#: doc/classes/Node3D.xml:177
msgid "Rotates the local transformation around the Y axis by angle in radians."
msgstr ""
-#: doc/classes/Node3D.xml:185
+#: doc/classes/Node3D.xml:186
msgid "Rotates the local transformation around the Z axis by angle in radians."
msgstr ""
-#: doc/classes/Node3D.xml:194
+#: doc/classes/Node3D.xml:195
msgid ""
"Scales the local transformation by given 3D scale factors in object-local "
"coordinate system."
msgstr ""
-#: doc/classes/Node3D.xml:203
+#: doc/classes/Node3D.xml:204
msgid ""
"Makes the node ignore its parents transformations. Node transformations are "
"only in global space."
msgstr ""
-#: doc/classes/Node3D.xml:212
+#: doc/classes/Node3D.xml:213
msgid ""
"Sets whether the node uses a scale of [code](1, 1, 1)[/code] or its local "
"transformation scale. Changes to the local transformation scale are "
"preserved."
msgstr ""
-#: doc/classes/Node3D.xml:219
+#: doc/classes/Node3D.xml:220
msgid ""
"Reset all transformations for this node (sets its [Transform] to the "
"identity matrix)."
msgstr ""
-#: doc/classes/Node3D.xml:228
+#: doc/classes/Node3D.xml:229
msgid ""
"Sets whether the node ignores notification that its transformation (global "
"or local) changed."
msgstr ""
-#: doc/classes/Node3D.xml:237
+#: doc/classes/Node3D.xml:238
msgid ""
"Sets whether the node notifies about its local transformation changes. "
"[Node3D] will not propagate this by default."
msgstr ""
-#: doc/classes/Node3D.xml:246
+#: doc/classes/Node3D.xml:247
msgid ""
"Sets whether the node notifies about its global and local transformation "
"changes. [Node3D] will not propagate this by default."
msgstr ""
-#: doc/classes/Node3D.xml:253
+#: doc/classes/Node3D.xml:254
msgid ""
"Enables rendering of this node. Changes [member visible] to [code]true[/"
"code]."
msgstr ""
-#: doc/classes/Node3D.xml:262
+#: doc/classes/Node3D.xml:263
msgid ""
"Transforms [code]local_point[/code] from this node's local space to world "
"space."
msgstr ""
-#: doc/classes/Node3D.xml:271
+#: doc/classes/Node3D.xml:272
msgid ""
"Transforms [code]global_point[/code] from world space to this node's local "
"space."
msgstr ""
-#: doc/classes/Node3D.xml:280
+#: doc/classes/Node3D.xml:281
msgid ""
"Changes the node's position by the given offset [Vector3].\n"
"Note that the translation [code]offset[/code] is affected by the node's "
@@ -31851,26 +31748,26 @@ msgid ""
"to the X coordinate."
msgstr ""
-#: doc/classes/Node3D.xml:290
+#: doc/classes/Node3D.xml:291
msgid ""
"Changes the node's position by the given offset [Vector3] in local space."
msgstr ""
-#: doc/classes/Node3D.xml:297
+#: doc/classes/Node3D.xml:298
msgid "Updates the [Node3DGizmo] of this node."
msgstr ""
-#: doc/classes/Node3D.xml:303
+#: doc/classes/Node3D.xml:304
msgid ""
"The [Node3DGizmo] for this node. Used for example in [EditorNode3DGizmo] as "
"custom visualization and editing handles in Editor."
msgstr ""
-#: doc/classes/Node3D.xml:306
+#: doc/classes/Node3D.xml:307
msgid "World3D space (global) [Transform] of this node."
msgstr ""
-#: doc/classes/Node3D.xml:309
+#: doc/classes/Node3D.xml:310
msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
@@ -31883,33 +31780,33 @@ msgid ""
"\" is not meaningful."
msgstr ""
-#: doc/classes/Node3D.xml:313
+#: doc/classes/Node3D.xml:314
msgid ""
"Rotation part of the local transformation in degrees, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle)."
msgstr ""
-#: doc/classes/Node3D.xml:316
+#: doc/classes/Node3D.xml:317
msgid "Scale part of the local transformation."
msgstr ""
-#: doc/classes/Node3D.xml:319
+#: doc/classes/Node3D.xml:320
msgid "Local space [Transform] of this node, with respect to the parent node."
msgstr ""
-#: doc/classes/Node3D.xml:322
+#: doc/classes/Node3D.xml:323
msgid "Local translation of this node."
msgstr ""
-#: doc/classes/Node3D.xml:325
+#: doc/classes/Node3D.xml:326
msgid "If [code]true[/code], this node is drawn."
msgstr ""
-#: doc/classes/Node3D.xml:331
+#: doc/classes/Node3D.xml:332
msgid "Emitted when node visibility changes."
msgstr ""
-#: doc/classes/Node3D.xml:337
+#: doc/classes/Node3D.xml:338
msgid ""
"Node3D nodes receives this notification when their global transform changes. "
"This means that either the current or a parent node changed its transform.\n"
@@ -31917,19 +31814,19 @@ msgid ""
"need to ask for it, with [method set_notify_transform]."
msgstr ""
-#: doc/classes/Node3D.xml:341
+#: doc/classes/Node3D.xml:342
msgid ""
"Node3D nodes receives this notification when they are registered to new "
"[World3D] resource."
msgstr ""
-#: doc/classes/Node3D.xml:344
+#: doc/classes/Node3D.xml:345
msgid ""
"Node3D nodes receives this notification when they are unregistered from "
"current [World3D] resource."
msgstr ""
-#: doc/classes/Node3D.xml:347
+#: doc/classes/Node3D.xml:348
msgid "Node3D nodes receives this notification when their visibility changes."
msgstr ""
@@ -33305,11 +33202,13 @@ msgid ""
"code]. See [url=https://blog.escapecreative.com/customizing-mailto-"
"links/]Customizing [code]mailto:[/code] Links[/url] for a list of fields "
"that can be added.\n"
+"Use [method ProjectSettings.globalize_path] to convert a [code]res://[/code] "
+"or [code]user://[/code] path into a system path for use with this method.\n"
"[b]Note:[/b] This method is implemented on Android, iOS, HTML5, Linux, macOS "
"and Windows."
msgstr ""
-#: doc/classes/OS.xml:493
+#: doc/classes/OS.xml:494
msgid ""
"The exit code passed to the OS when the main loop exits. By convention, an "
"exit code of [code]0[/code] indicates success whereas a non-zero exit code "
@@ -33319,133 +33218,133 @@ msgid ""
"with an [code]exit_code[/code] argument passed."
msgstr ""
-#: doc/classes/OS.xml:497
+#: doc/classes/OS.xml:498
msgid ""
"If [code]true[/code], the engine optimizes for low processor usage by only "
"refreshing the screen if needed. Can improve battery consumption on mobile."
msgstr ""
-#: doc/classes/OS.xml:500
+#: doc/classes/OS.xml:501
msgid ""
"The amount of sleeping between frames when the low-processor usage mode is "
"enabled (in microseconds). Higher values will result in lower CPU usage."
msgstr ""
-#: doc/classes/OS.xml:505
+#: doc/classes/OS.xml:506
msgid ""
"The GLES2 rendering backend. It uses OpenGL ES 2.0 on mobile devices, OpenGL "
"2.1 on desktop platforms and WebGL 1.0 on the web."
msgstr ""
-#: doc/classes/OS.xml:508
+#: doc/classes/OS.xml:509
msgid "The Vulkan rendering backend."
msgstr ""
-#: doc/classes/OS.xml:511
+#: doc/classes/OS.xml:512
msgid "Sunday."
msgstr ""
-#: doc/classes/OS.xml:514
+#: doc/classes/OS.xml:515
msgid "Monday."
msgstr ""
-#: doc/classes/OS.xml:517
+#: doc/classes/OS.xml:518
msgid "Tuesday."
msgstr ""
-#: doc/classes/OS.xml:520
+#: doc/classes/OS.xml:521
msgid "Wednesday."
msgstr ""
-#: doc/classes/OS.xml:523
+#: doc/classes/OS.xml:524
msgid "Thursday."
msgstr ""
-#: doc/classes/OS.xml:526
+#: doc/classes/OS.xml:527
msgid "Friday."
msgstr ""
-#: doc/classes/OS.xml:529
+#: doc/classes/OS.xml:530
msgid "Saturday."
msgstr ""
-#: doc/classes/OS.xml:532
+#: doc/classes/OS.xml:533
msgid "January."
msgstr ""
-#: doc/classes/OS.xml:535
+#: doc/classes/OS.xml:536
msgid "February."
msgstr ""
-#: doc/classes/OS.xml:538
+#: doc/classes/OS.xml:539
msgid "March."
msgstr ""
-#: doc/classes/OS.xml:541
+#: doc/classes/OS.xml:542
msgid "April."
msgstr ""
-#: doc/classes/OS.xml:544
+#: doc/classes/OS.xml:545
msgid "May."
msgstr ""
-#: doc/classes/OS.xml:547
+#: doc/classes/OS.xml:548
msgid "June."
msgstr ""
-#: doc/classes/OS.xml:550
+#: doc/classes/OS.xml:551
msgid "July."
msgstr ""
-#: doc/classes/OS.xml:553
+#: doc/classes/OS.xml:554
msgid "August."
msgstr ""
-#: doc/classes/OS.xml:556
+#: doc/classes/OS.xml:557
msgid "September."
msgstr ""
-#: doc/classes/OS.xml:559
+#: doc/classes/OS.xml:560
msgid "October."
msgstr ""
-#: doc/classes/OS.xml:562
+#: doc/classes/OS.xml:563
msgid "November."
msgstr ""
-#: doc/classes/OS.xml:565
+#: doc/classes/OS.xml:566
msgid "December."
msgstr ""
-#: doc/classes/OS.xml:568
+#: doc/classes/OS.xml:569
msgid "Desktop directory path."
msgstr ""
-#: doc/classes/OS.xml:571
+#: doc/classes/OS.xml:572
msgid "DCIM (Digital Camera Images) directory path."
msgstr ""
-#: doc/classes/OS.xml:574
+#: doc/classes/OS.xml:575
msgid "Documents directory path."
msgstr ""
-#: doc/classes/OS.xml:577
+#: doc/classes/OS.xml:578
msgid "Downloads directory path."
msgstr ""
-#: doc/classes/OS.xml:580
+#: doc/classes/OS.xml:581
msgid "Movies directory path."
msgstr ""
-#: doc/classes/OS.xml:583
+#: doc/classes/OS.xml:584
msgid "Music directory path."
msgstr ""
-#: doc/classes/OS.xml:586
+#: doc/classes/OS.xml:587
msgid "Pictures directory path."
msgstr ""
-#: doc/classes/OS.xml:589
+#: doc/classes/OS.xml:590
msgid "Ringtones directory path."
msgstr ""
@@ -33717,49 +33616,52 @@ msgid ""
"code] is owned by [code]node[/code] and [code]pack[/code] will therefore "
"only save those two nodes, but not [code]collision[/code].\n"
"[codeblock]\n"
-"# Create the objects\n"
+"# Create the objects.\n"
"var node = Node2D.new()\n"
"var rigid = RigidBody2D.new()\n"
"var collision = CollisionShape2D.new()\n"
"\n"
-"# Create the object hierarchy\n"
+"# Create the object hierarchy.\n"
"rigid.add_child(collision)\n"
"node.add_child(rigid)\n"
"\n"
-"# Change owner of rigid, but not of collision\n"
+"# Change owner of `rigid`, but not of `collision`.\n"
"rigid.owner = node\n"
"\n"
"var scene = PackedScene.new()\n"
-"# Only node and rigid are now packed\n"
+"# Only `node` and `rigid` are now packed.\n"
"var result = scene.pack(node)\n"
"if result == OK:\n"
-" ResourceSaver.save(\"res://path/name.scn\", scene) # Or \"user://...\"\n"
+" var error = ResourceSaver.save(\"res://path/name.scn\", scene) # Or "
+"\"user://...\"\n"
+" if error != OK:\n"
+" push_error(\"An error occurred while saving the scene to disk.\")\n"
"[/codeblock]"
msgstr ""
-#: doc/classes/PackedScene.xml:38
+#: doc/classes/PackedScene.xml:40
msgid "Returns [code]true[/code] if the scene file has nodes."
msgstr ""
-#: doc/classes/PackedScene.xml:45
+#: doc/classes/PackedScene.xml:47
msgid ""
"Returns the [code]SceneState[/code] representing the scene file contents."
msgstr ""
-#: doc/classes/PackedScene.xml:54
+#: doc/classes/PackedScene.xml:56
msgid ""
"Instantiates the scene's node hierarchy. Triggers child scene "
"instantiation(s). Triggers a [constant Node.NOTIFICATION_INSTANCED] "
"notification on the root node."
msgstr ""
-#: doc/classes/PackedScene.xml:63
+#: doc/classes/PackedScene.xml:65
msgid ""
"Pack will ignore any sub-nodes not owned by given node. See [member Node."
"owner]."
msgstr ""
-#: doc/classes/PackedScene.xml:69
+#: doc/classes/PackedScene.xml:71
msgid ""
"A dictionary representation of the scene contents.\n"
"Available keys include \"rnames\" and \"variants\" for resources, "
@@ -33768,18 +33670,18 @@ msgid ""
"connections, and \"version\" for the format style of the PackedScene."
msgstr ""
-#: doc/classes/PackedScene.xml:75
+#: doc/classes/PackedScene.xml:77
msgid "If passed to [method instance], blocks edits to the scene state."
msgstr ""
-#: doc/classes/PackedScene.xml:78
+#: doc/classes/PackedScene.xml:80
msgid ""
"If passed to [method instance], provides local scene resources to the local "
"scene.\n"
"[b]Note:[/b] Only available in editor builds."
msgstr ""
-#: doc/classes/PackedScene.xml:82
+#: doc/classes/PackedScene.xml:84
msgid ""
"If passed to [method instance], provides local scene resources to the local "
"scene. Only the main scene should receive the main edit state.\n"
@@ -34847,20 +34749,20 @@ msgstr ""
msgid "Draw calls per frame. 3D only."
msgstr ""
-#: doc/classes/Performance.xml:77 doc/classes/RenderingServer.xml:3711
+#: doc/classes/Performance.xml:77 doc/classes/RenderingServer.xml:3922
msgid ""
"The amount of video memory used, i.e. texture and vertex memory combined."
msgstr ""
-#: doc/classes/Performance.xml:80 doc/classes/RenderingServer.xml:3714
+#: doc/classes/Performance.xml:80 doc/classes/RenderingServer.xml:3925
msgid "The amount of texture memory used."
msgstr ""
-#: doc/classes/Performance.xml:83 doc/classes/RenderingServer.xml:3717
+#: doc/classes/Performance.xml:83 doc/classes/RenderingServer.xml:3928
msgid "The amount of vertex memory used."
msgstr ""
-#: doc/classes/Performance.xml:86 doc/classes/RenderingServer.xml:3708
+#: doc/classes/Performance.xml:86 doc/classes/RenderingServer.xml:3919
msgid "Unimplemented in the GLES2 rendering backend, always returns 0."
msgstr ""
@@ -34912,6 +34814,96 @@ msgid ""
"resource."
msgstr ""
+#: doc/classes/PhysicalBone3D.xml:67
+msgid "Damps the body's rotation if greater than [code]0[/code]."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:70 doc/classes/RigidBody3D.xml:132
+msgid "Lock the body's rotation in the X axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:73 doc/classes/RigidBody3D.xml:135
+msgid "Lock the body's rotation in the Y axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:76 doc/classes/RigidBody3D.xml:138
+msgid "Lock the body's rotation in the Z axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:79 doc/classes/RigidBody3D.xml:141
+msgid "Lock the body's movement in the X axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:82 doc/classes/RigidBody3D.xml:144
+msgid "Lock the body's movement in the Y axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:85 doc/classes/RigidBody3D.xml:147
+msgid "Lock the body's movement in the Z axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:88
+msgid "Sets the body's transform."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:91 doc/classes/PhysicsMaterial.xml:17
+msgid ""
+"The body's bounciness. Values range from [code]0[/code] (no bounce) to "
+"[code]1[/code] (full bounciness)."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:94 doc/classes/RigidBody3D.xml:150
+msgid ""
+"If [code]true[/code], the body is deactivated when there is no movement, so "
+"it will not take part in the simulation until it is awaken by an external "
+"force."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:97
+msgid ""
+"The body's friction, from [code]0[/code] (frictionless) to [code]1[/code] "
+"(max friction)."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:100
+msgid ""
+"This is multiplied by the global 3D gravity setting found in [b]Project > "
+"Project Settings > Physics > 3d[/b] to produce the body's gravity. For "
+"example, a value of 1 will be normal gravity, 2 will apply double gravity, "
+"and 0.5 will apply half gravity to this object."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:103
+msgid "Sets the joint's transform."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:106
+msgid "Sets the joint's rotation in radians."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:109
+msgid "Sets the joint's rotation in degrees."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:112
+msgid "Sets the joint type. See [enum JointType] for possible values."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:115
+msgid "Damps the body's movement if greater than [code]0[/code]."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:118 doc/classes/RigidBody2D.xml:158
+#: doc/classes/RigidBody3D.xml:175
+msgid "The body's mass."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:121 doc/classes/RigidBody3D.xml:188
+msgid ""
+"The body's weight based on its mass and the global 3D gravity. Global values "
+"are set in [b]Project > Project Settings > Physics > 3d[/b]."
+msgstr ""
+
#: doc/classes/PhysicalSkyMaterial.xml:4
msgid "[Sky] [Material] used for a physically based sky."
msgstr ""
@@ -35245,17 +35237,6 @@ msgstr ""
msgid "The body's transformation matrix."
msgstr ""
-#: doc/classes/PhysicsDirectBodyState2DSW.xml:4
-msgid "Software implementation of [PhysicsDirectBodyState2D]."
-msgstr ""
-
-#: doc/classes/PhysicsDirectBodyState2DSW.xml:7
-msgid ""
-"Software implementation of [PhysicsDirectBodyState2D]. This object exposes "
-"no new methods or properties and should not be used, as "
-"[PhysicsDirectBodyState2D] selects the best implementation available."
-msgstr ""
-
#: doc/classes/PhysicsDirectBodyState3D.xml:4
msgid "Direct access object to a physics body in the [PhysicsServer3D]."
msgstr ""
@@ -35268,7 +35249,7 @@ msgid ""
"direct state of that body. See [method RigidBody3D._integrate_forces]."
msgstr ""
-#: doc/classes/PhysicsDirectBodyState3D.xml:18 doc/classes/RigidBody3D.xml:31
+#: doc/classes/PhysicsDirectBodyState3D.xml:18
msgid ""
"Adds a constant directional force without affecting rotation.\n"
"This is equivalent to [code]add_force(force, Vector3(0,0,0))[/code]."
@@ -35445,7 +35426,7 @@ msgid ""
"will occur. If no collision is detected, the returned array will be [code]"
"[1, 1][/code].\n"
"If the shape can not move, the returned array will be [code][0, 0][/code] "
-"under Bullet, and empty under GodotPhysics."
+"under Bullet, and empty under GodotPhysics3D."
msgstr ""
#: doc/classes/PhysicsDirectSpaceState3D.xml:33
@@ -35516,12 +35497,6 @@ msgid ""
"Provides a means of modifying the collision properties of a [PhysicsBody3D]."
msgstr ""
-#: doc/classes/PhysicsMaterial.xml:17
-msgid ""
-"The body's bounciness. Values range from [code]0[/code] (no bounce) to "
-"[code]1[/code] (full bounciness)."
-msgstr ""
-
#: doc/classes/PhysicsMaterial.xml:20
msgid ""
"The body's friction. Values range from [code]0[/code] (frictionless) to "
@@ -35762,7 +35737,7 @@ msgid ""
msgstr ""
#: doc/classes/PhysicsServer2D.xml:620 doc/classes/PhysicsServer3D.xml:637
-#: doc/classes/RigidBody3D.xml:119
+#: doc/classes/RigidBody3D.xml:120
msgid ""
"Sets an axis velocity. The velocity in the given vector axis will be set as "
"the given vector length. This is useful for jumping behavior."
@@ -36278,16 +36253,6 @@ msgid ""
"Constant to get the number of space regions where a collision could occur."
msgstr ""
-#: doc/classes/PhysicsServer2DSW.xml:4
-msgid "Software implementation of [PhysicsServer2D]."
-msgstr ""
-
-#: doc/classes/PhysicsServer2DSW.xml:7
-msgid ""
-"This class exposes no new methods or properties and should not be used, as "
-"[PhysicsServer2D] automatically selects the best implementation available."
-msgstr ""
-
#: doc/classes/PhysicsServer3D.xml:4
msgid "Server interface for low-level physics access."
msgstr ""
@@ -37949,12 +37914,8 @@ msgid "Distance from center of sun where it fades out completely."
msgstr ""
#: doc/classes/ProceduralSkyMaterial.xml:44
-msgid "Distance from sun where it goes from solid to starting to fade."
-msgstr ""
-
-#: doc/classes/ProceduralSkyMaterial.xml:47
msgid ""
-"How quickly the sun fades away between [member sun_angle_min] and [member "
+"How quickly the sun fades away between the edge of the sun disk and [member "
"sun_angle_max]."
msgstr ""
@@ -38289,28 +38250,42 @@ msgstr ""
#: doc/classes/ProjectSettings.xml:263
msgid ""
-"Default compression level for gzip. Affects compressed scenes and resources."
+"The default compression level for gzip. Affects compressed scenes and "
+"resources. Higher levels result in smaller files at the cost of compression "
+"speed. Decompression speed is mostly unaffected by the compression level. "
+"[code]-1[/code] uses the default gzip compression level, which is identical "
+"to [code]6[/code] but could change in the future due to underlying zlib "
+"updates."
msgstr ""
#: doc/classes/ProjectSettings.xml:266
msgid ""
-"Default compression level for Zlib. Affects compressed scenes and resources."
+"The default compression level for Zlib. Affects compressed scenes and "
+"resources. Higher levels result in smaller files at the cost of compression "
+"speed. Decompression speed is mostly unaffected by the compression level. "
+"[code]-1[/code] uses the default gzip compression level, which is identical "
+"to [code]6[/code] but could change in the future due to underlying zlib "
+"updates."
msgstr ""
#: doc/classes/ProjectSettings.xml:269
msgid ""
-"Default compression level for Zstandard. Affects compressed scenes and "
-"resources."
+"The default compression level for Zstandard. Affects compressed scenes and "
+"resources. Higher levels result in smaller files at the cost of compression "
+"speed. Decompression speed is mostly unaffected by the compression level."
msgstr ""
#: doc/classes/ProjectSettings.xml:272
-msgid "Enables long-distance matching in Zstandard."
+msgid ""
+"Enables [url=https://github.com/facebook/zstd/releases/tag/v1.3.2]long-"
+"distance matching[/url] in Zstandard."
msgstr ""
#: doc/classes/ProjectSettings.xml:275
msgid ""
"Largest size limit (in power of 2) allowed when compressing using long-"
-"distance matching with Zstandard."
+"distance matching with Zstandard. Higher values can result in better "
+"compression, but will require more memory when compressing and decompressing."
msgstr ""
#: doc/classes/ProjectSettings.xml:278
@@ -38691,37 +38666,37 @@ msgid ""
"UWP to follow interface conventions."
msgstr ""
-#: doc/classes/ProjectSettings.xml:473
+#: doc/classes/ProjectSettings.xml:475
msgid ""
"Path to a custom [Theme] resource file to use for the project ([code]theme[/"
"code] or generic [code]tres[/code]/[code]res[/code] extension)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:476
+#: doc/classes/ProjectSettings.xml:478
msgid ""
"Path to a custom [Font] resource to use as default for all GUI elements of "
"the project."
msgstr ""
-#: doc/classes/ProjectSettings.xml:479
+#: doc/classes/ProjectSettings.xml:481
msgid "If [code]true[/code], makes sure the theme used works with HiDPI."
msgstr ""
-#: doc/classes/ProjectSettings.xml:482
+#: doc/classes/ProjectSettings.xml:484
msgid ""
"Timer setting for incremental search in [Tree], [ItemList], etc. controls "
"(in milliseconds)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:485
+#: doc/classes/ProjectSettings.xml:487
msgid "Timer for detecting idle in [TextEdit] (in seconds)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:488
+#: doc/classes/ProjectSettings.xml:490
msgid "Default delay for tooltips (in seconds)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:491
+#: doc/classes/ProjectSettings.xml:493
msgid ""
"Default [InputEventAction] to confirm a focused button, menu or list item, "
"or validate input.\n"
@@ -38730,7 +38705,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:495
+#: doc/classes/ProjectSettings.xml:497
msgid ""
"Default [InputEventAction] to discard a modal or pending input.\n"
"[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are "
@@ -38738,7 +38713,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:499
+#: doc/classes/ProjectSettings.xml:501
msgid ""
"Default [InputEventAction] to move down in the UI.\n"
"[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are "
@@ -38746,7 +38721,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:503
+#: doc/classes/ProjectSettings.xml:505
msgid ""
"Default [InputEventAction] to go to the end position of a [Control] (e.g. "
"last item in an [ItemList] or a [Tree]), matching the behavior of [constant "
@@ -38756,7 +38731,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:507
+#: doc/classes/ProjectSettings.xml:509
msgid ""
"Default [InputEventAction] to focus the next [Control] in the scene. The "
"focus behavior can be configured via [member Control.focus_next].\n"
@@ -38765,7 +38740,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:511
+#: doc/classes/ProjectSettings.xml:513
msgid ""
"Default [InputEventAction] to focus the previous [Control] in the scene. The "
"focus behavior can be configured via [member Control.focus_previous].\n"
@@ -38774,7 +38749,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:515
+#: doc/classes/ProjectSettings.xml:517
msgid ""
"Default [InputEventAction] to go to the start position of a [Control] (e.g. "
"first item in an [ItemList] or a [Tree]), matching the behavior of [constant "
@@ -38784,7 +38759,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:519
+#: doc/classes/ProjectSettings.xml:521
msgid ""
"Default [InputEventAction] to move left in the UI.\n"
"[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are "
@@ -38792,7 +38767,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:523
+#: doc/classes/ProjectSettings.xml:525
msgid ""
"Default [InputEventAction] to go down a page in a [Control] (e.g. in an "
"[ItemList] or a [Tree]), matching the behavior of [constant KEY_PAGEDOWN] on "
@@ -38802,7 +38777,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:527
+#: doc/classes/ProjectSettings.xml:529
msgid ""
"Default [InputEventAction] to go up a page in a [Control] (e.g. in an "
"[ItemList] or a [Tree]), matching the behavior of [constant KEY_PAGEUP] on "
@@ -38812,7 +38787,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:531
+#: doc/classes/ProjectSettings.xml:533
msgid ""
"Default [InputEventAction] to move right in the UI.\n"
"[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are "
@@ -38820,7 +38795,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:535
+#: doc/classes/ProjectSettings.xml:537
msgid ""
"Default [InputEventAction] to select an item in a [Control] (e.g. in an "
"[ItemList] or a [Tree]).\n"
@@ -38829,7 +38804,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:539
+#: doc/classes/ProjectSettings.xml:541
msgid ""
"Default [InputEventAction] to move up in the UI.\n"
"[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are "
@@ -38837,371 +38812,371 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:543
+#: doc/classes/ProjectSettings.xml:545
msgid ""
"If [code]true[/code], sends mouse input events when tapping or swiping on "
"the touchscreen."
msgstr ""
-#: doc/classes/ProjectSettings.xml:546
+#: doc/classes/ProjectSettings.xml:548
msgid ""
"If [code]true[/code], sends touch input events when clicking or dragging the "
"mouse."
msgstr ""
-#: doc/classes/ProjectSettings.xml:549
+#: doc/classes/ProjectSettings.xml:551
msgid "Optional name for the 2D physics layer 1."
msgstr ""
-#: doc/classes/ProjectSettings.xml:552
+#: doc/classes/ProjectSettings.xml:554
msgid "Optional name for the 2D physics layer 10."
msgstr ""
-#: doc/classes/ProjectSettings.xml:555
+#: doc/classes/ProjectSettings.xml:557
msgid "Optional name for the 2D physics layer 11."
msgstr ""
-#: doc/classes/ProjectSettings.xml:558
+#: doc/classes/ProjectSettings.xml:560
msgid "Optional name for the 2D physics layer 12."
msgstr ""
-#: doc/classes/ProjectSettings.xml:561
+#: doc/classes/ProjectSettings.xml:563
msgid "Optional name for the 2D physics layer 13."
msgstr ""
-#: doc/classes/ProjectSettings.xml:564
+#: doc/classes/ProjectSettings.xml:566
msgid "Optional name for the 2D physics layer 14."
msgstr ""
-#: doc/classes/ProjectSettings.xml:567
+#: doc/classes/ProjectSettings.xml:569
msgid "Optional name for the 2D physics layer 15."
msgstr ""
-#: doc/classes/ProjectSettings.xml:570
+#: doc/classes/ProjectSettings.xml:572
msgid "Optional name for the 2D physics layer 16."
msgstr ""
-#: doc/classes/ProjectSettings.xml:573
+#: doc/classes/ProjectSettings.xml:575
msgid "Optional name for the 2D physics layer 17."
msgstr ""
-#: doc/classes/ProjectSettings.xml:576
+#: doc/classes/ProjectSettings.xml:578
msgid "Optional name for the 2D physics layer 18."
msgstr ""
-#: doc/classes/ProjectSettings.xml:579
+#: doc/classes/ProjectSettings.xml:581
msgid "Optional name for the 2D physics layer 19."
msgstr ""
-#: doc/classes/ProjectSettings.xml:582
+#: doc/classes/ProjectSettings.xml:584
msgid "Optional name for the 2D physics layer 2."
msgstr ""
-#: doc/classes/ProjectSettings.xml:585
+#: doc/classes/ProjectSettings.xml:587
msgid "Optional name for the 2D physics layer 20."
msgstr ""
-#: doc/classes/ProjectSettings.xml:588
+#: doc/classes/ProjectSettings.xml:590
msgid "Optional name for the 2D physics layer 3."
msgstr ""
-#: doc/classes/ProjectSettings.xml:591
+#: doc/classes/ProjectSettings.xml:593
msgid "Optional name for the 2D physics layer 4."
msgstr ""
-#: doc/classes/ProjectSettings.xml:594
+#: doc/classes/ProjectSettings.xml:596
msgid "Optional name for the 2D physics layer 5."
msgstr ""
-#: doc/classes/ProjectSettings.xml:597
+#: doc/classes/ProjectSettings.xml:599
msgid "Optional name for the 2D physics layer 6."
msgstr ""
-#: doc/classes/ProjectSettings.xml:600
+#: doc/classes/ProjectSettings.xml:602
msgid "Optional name for the 2D physics layer 7."
msgstr ""
-#: doc/classes/ProjectSettings.xml:603
+#: doc/classes/ProjectSettings.xml:605
msgid "Optional name for the 2D physics layer 8."
msgstr ""
-#: doc/classes/ProjectSettings.xml:606
+#: doc/classes/ProjectSettings.xml:608
msgid "Optional name for the 2D physics layer 9."
msgstr ""
-#: doc/classes/ProjectSettings.xml:609
+#: doc/classes/ProjectSettings.xml:611
msgid "Optional name for the 2D render layer 1."
msgstr ""
-#: doc/classes/ProjectSettings.xml:612
+#: doc/classes/ProjectSettings.xml:614
msgid "Optional name for the 2D render layer 10."
msgstr ""
-#: doc/classes/ProjectSettings.xml:615
+#: doc/classes/ProjectSettings.xml:617
msgid "Optional name for the 2D render layer 11."
msgstr ""
-#: doc/classes/ProjectSettings.xml:618
+#: doc/classes/ProjectSettings.xml:620
msgid "Optional name for the 2D render layer 12."
msgstr ""
-#: doc/classes/ProjectSettings.xml:621
+#: doc/classes/ProjectSettings.xml:623
msgid "Optional name for the 2D render layer 13."
msgstr ""
-#: doc/classes/ProjectSettings.xml:624
+#: doc/classes/ProjectSettings.xml:626
msgid "Optional name for the 2D render layer 14."
msgstr ""
-#: doc/classes/ProjectSettings.xml:627
+#: doc/classes/ProjectSettings.xml:629
msgid "Optional name for the 2D render layer 15."
msgstr ""
-#: doc/classes/ProjectSettings.xml:630
+#: doc/classes/ProjectSettings.xml:632
msgid "Optional name for the 2D render layer 16."
msgstr ""
-#: doc/classes/ProjectSettings.xml:633
+#: doc/classes/ProjectSettings.xml:635
msgid "Optional name for the 2D render layer 17."
msgstr ""
-#: doc/classes/ProjectSettings.xml:636
+#: doc/classes/ProjectSettings.xml:638
msgid "Optional name for the 2D render layer 18."
msgstr ""
-#: doc/classes/ProjectSettings.xml:639
+#: doc/classes/ProjectSettings.xml:641
msgid "Optional name for the 2D render layer 19."
msgstr ""
-#: doc/classes/ProjectSettings.xml:642
+#: doc/classes/ProjectSettings.xml:644
msgid "Optional name for the 2D render layer 2."
msgstr ""
-#: doc/classes/ProjectSettings.xml:645
+#: doc/classes/ProjectSettings.xml:647
msgid "Optional name for the 2D render layer 20."
msgstr ""
-#: doc/classes/ProjectSettings.xml:648
+#: doc/classes/ProjectSettings.xml:650
msgid "Optional name for the 2D render layer 3."
msgstr ""
-#: doc/classes/ProjectSettings.xml:651
+#: doc/classes/ProjectSettings.xml:653
msgid "Optional name for the 2D render layer 4."
msgstr ""
-#: doc/classes/ProjectSettings.xml:654
+#: doc/classes/ProjectSettings.xml:656
msgid "Optional name for the 2D render layer 5."
msgstr ""
-#: doc/classes/ProjectSettings.xml:657
+#: doc/classes/ProjectSettings.xml:659
msgid "Optional name for the 2D render layer 6."
msgstr ""
-#: doc/classes/ProjectSettings.xml:660
+#: doc/classes/ProjectSettings.xml:662
msgid "Optional name for the 2D render layer 7."
msgstr ""
-#: doc/classes/ProjectSettings.xml:663
+#: doc/classes/ProjectSettings.xml:665
msgid "Optional name for the 2D render layer 8."
msgstr ""
-#: doc/classes/ProjectSettings.xml:666
+#: doc/classes/ProjectSettings.xml:668
msgid "Optional name for the 2D render layer 9."
msgstr ""
-#: doc/classes/ProjectSettings.xml:669
+#: doc/classes/ProjectSettings.xml:671
msgid "Optional name for the 3D physics layer 1."
msgstr ""
-#: doc/classes/ProjectSettings.xml:672
+#: doc/classes/ProjectSettings.xml:674
msgid "Optional name for the 3D physics layer 10."
msgstr ""
-#: doc/classes/ProjectSettings.xml:675
+#: doc/classes/ProjectSettings.xml:677
msgid "Optional name for the 3D physics layer 11."
msgstr ""
-#: doc/classes/ProjectSettings.xml:678
+#: doc/classes/ProjectSettings.xml:680
msgid "Optional name for the 3D physics layer 12."
msgstr ""
-#: doc/classes/ProjectSettings.xml:681
+#: doc/classes/ProjectSettings.xml:683
msgid "Optional name for the 3D physics layer 13."
msgstr ""
-#: doc/classes/ProjectSettings.xml:684
+#: doc/classes/ProjectSettings.xml:686
msgid "Optional name for the 3D physics layer 14."
msgstr ""
-#: doc/classes/ProjectSettings.xml:687
+#: doc/classes/ProjectSettings.xml:689
msgid "Optional name for the 3D physics layer 15."
msgstr ""
-#: doc/classes/ProjectSettings.xml:690
+#: doc/classes/ProjectSettings.xml:692
msgid "Optional name for the 3D physics layer 16."
msgstr ""
-#: doc/classes/ProjectSettings.xml:693
+#: doc/classes/ProjectSettings.xml:695
msgid "Optional name for the 3D physics layer 17."
msgstr ""
-#: doc/classes/ProjectSettings.xml:696
+#: doc/classes/ProjectSettings.xml:698
msgid "Optional name for the 3D physics layer 18."
msgstr ""
-#: doc/classes/ProjectSettings.xml:699
+#: doc/classes/ProjectSettings.xml:701
msgid "Optional name for the 3D physics layer 19."
msgstr ""
-#: doc/classes/ProjectSettings.xml:702
+#: doc/classes/ProjectSettings.xml:704
msgid "Optional name for the 3D physics layer 2."
msgstr ""
-#: doc/classes/ProjectSettings.xml:705
+#: doc/classes/ProjectSettings.xml:707
msgid "Optional name for the 3D physics layer 20."
msgstr ""
-#: doc/classes/ProjectSettings.xml:708
+#: doc/classes/ProjectSettings.xml:710
msgid "Optional name for the 3D physics layer 3."
msgstr ""
-#: doc/classes/ProjectSettings.xml:711
+#: doc/classes/ProjectSettings.xml:713
msgid "Optional name for the 3D physics layer 4."
msgstr ""
-#: doc/classes/ProjectSettings.xml:714
+#: doc/classes/ProjectSettings.xml:716
msgid "Optional name for the 3D physics layer 5."
msgstr ""
-#: doc/classes/ProjectSettings.xml:717
+#: doc/classes/ProjectSettings.xml:719
msgid "Optional name for the 3D physics layer 6."
msgstr ""
-#: doc/classes/ProjectSettings.xml:720
+#: doc/classes/ProjectSettings.xml:722
msgid "Optional name for the 3D physics layer 7."
msgstr ""
-#: doc/classes/ProjectSettings.xml:723
+#: doc/classes/ProjectSettings.xml:725
msgid "Optional name for the 3D physics layer 8."
msgstr ""
-#: doc/classes/ProjectSettings.xml:726
+#: doc/classes/ProjectSettings.xml:728
msgid "Optional name for the 3D physics layer 9."
msgstr ""
-#: doc/classes/ProjectSettings.xml:729
+#: doc/classes/ProjectSettings.xml:731
msgid "Optional name for the 3D render layer 1."
msgstr ""
-#: doc/classes/ProjectSettings.xml:732
+#: doc/classes/ProjectSettings.xml:734
msgid "Optional name for the 3D render layer 10."
msgstr ""
-#: doc/classes/ProjectSettings.xml:735
+#: doc/classes/ProjectSettings.xml:737
msgid "Optional name for the 3D render layer 11."
msgstr ""
-#: doc/classes/ProjectSettings.xml:738
+#: doc/classes/ProjectSettings.xml:740
msgid "Optional name for the 3D render layer 12."
msgstr ""
-#: doc/classes/ProjectSettings.xml:741
+#: doc/classes/ProjectSettings.xml:743
msgid "Optional name for the 3D render layer 13."
msgstr ""
-#: doc/classes/ProjectSettings.xml:744
+#: doc/classes/ProjectSettings.xml:746
msgid "Optional name for the 3D render layer 14"
msgstr ""
-#: doc/classes/ProjectSettings.xml:747
+#: doc/classes/ProjectSettings.xml:749
msgid "Optional name for the 3D render layer 15."
msgstr ""
-#: doc/classes/ProjectSettings.xml:750
+#: doc/classes/ProjectSettings.xml:752
msgid "Optional name for the 3D render layer 16."
msgstr ""
-#: doc/classes/ProjectSettings.xml:753
+#: doc/classes/ProjectSettings.xml:755
msgid "Optional name for the 3D render layer 17."
msgstr ""
-#: doc/classes/ProjectSettings.xml:756
+#: doc/classes/ProjectSettings.xml:758
msgid "Optional name for the 3D render layer 18."
msgstr ""
-#: doc/classes/ProjectSettings.xml:759
+#: doc/classes/ProjectSettings.xml:761
msgid "Optional name for the 3D render layer 19."
msgstr ""
-#: doc/classes/ProjectSettings.xml:762
+#: doc/classes/ProjectSettings.xml:764
msgid "Optional name for the 3D render layer 2."
msgstr ""
-#: doc/classes/ProjectSettings.xml:765
+#: doc/classes/ProjectSettings.xml:767
msgid "Optional name for the 3D render layer 20."
msgstr ""
-#: doc/classes/ProjectSettings.xml:768
+#: doc/classes/ProjectSettings.xml:770
msgid "Optional name for the 3D render layer 3."
msgstr ""
-#: doc/classes/ProjectSettings.xml:771
+#: doc/classes/ProjectSettings.xml:773
msgid "Optional name for the 3D render layer 4."
msgstr ""
-#: doc/classes/ProjectSettings.xml:774
+#: doc/classes/ProjectSettings.xml:776
msgid "Optional name for the 3D render layer 5."
msgstr ""
-#: doc/classes/ProjectSettings.xml:777
+#: doc/classes/ProjectSettings.xml:779
msgid "Optional name for the 3D render layer 6."
msgstr ""
-#: doc/classes/ProjectSettings.xml:780
+#: doc/classes/ProjectSettings.xml:782
msgid "Optional name for the 3D render layer 7."
msgstr ""
-#: doc/classes/ProjectSettings.xml:783
+#: doc/classes/ProjectSettings.xml:785
msgid "Optional name for the 3D render layer 8."
msgstr ""
-#: doc/classes/ProjectSettings.xml:786
+#: doc/classes/ProjectSettings.xml:788
msgid "Optional name for the 3D render layer 9."
msgstr ""
-#: doc/classes/ProjectSettings.xml:789
+#: doc/classes/ProjectSettings.xml:791
msgid ""
"The locale to fall back to if a translation isn't available in a given "
"language. If left empty, [code]en[/code] (English) will be used."
msgstr ""
-#: doc/classes/ProjectSettings.xml:792
+#: doc/classes/ProjectSettings.xml:794
msgid ""
"If non-empty, this locale will be used when running the project from the "
"editor."
msgstr ""
-#: doc/classes/ProjectSettings.xml:795
+#: doc/classes/ProjectSettings.xml:797
msgid "If [code]true[/code], logs all output to files."
msgstr ""
-#: doc/classes/ProjectSettings.xml:798
+#: doc/classes/ProjectSettings.xml:800
msgid ""
"Path to logs within the project. Using an [code]user://[/code] path is "
"recommended."
msgstr ""
-#: doc/classes/ProjectSettings.xml:801
+#: doc/classes/ProjectSettings.xml:803
msgid "Specifies the maximum amount of log files allowed (used for rotation)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:804
+#: doc/classes/ProjectSettings.xml:806
msgid ""
"Godot uses a message queue to defer some function calls. If you run out of "
"space on it (you will see an error), you can increase the size here."
msgstr ""
-#: doc/classes/ProjectSettings.xml:807
+#: doc/classes/ProjectSettings.xml:809
msgid ""
"This is used by servers when used in multi-threading mode (servers and "
"visual). RIDs are preallocated to avoid stalling the server requesting them "
@@ -39209,118 +39184,118 @@ msgid ""
"thread, increase this number."
msgstr ""
-#: doc/classes/ProjectSettings.xml:822
+#: doc/classes/ProjectSettings.xml:824
msgid ""
"Maximum amount of characters allowed to send as output from the debugger. "
"Over this value, content is dropped. This helps not to stall the debugger "
"connection."
msgstr ""
-#: doc/classes/ProjectSettings.xml:825
+#: doc/classes/ProjectSettings.xml:827
msgid ""
"Maximum number of errors allowed to be sent from the debugger. Over this "
"value, content is dropped. This helps not to stall the debugger connection."
msgstr ""
-#: doc/classes/ProjectSettings.xml:828
+#: doc/classes/ProjectSettings.xml:830
msgid ""
"Maximum amount of messages in the debugger queue. Over this value, content "
"is dropped. This helps to limit the debugger memory usage."
msgstr ""
-#: doc/classes/ProjectSettings.xml:831
+#: doc/classes/ProjectSettings.xml:833
msgid ""
"Maximum number of warnings allowed to be sent from the debugger. Over this "
"value, content is dropped. This helps not to stall the debugger connection."
msgstr ""
-#: doc/classes/ProjectSettings.xml:834
+#: doc/classes/ProjectSettings.xml:836
msgid ""
"Default size of packet peer stream for deserializing Godot data. Over this "
"size, data is dropped."
msgstr ""
-#: doc/classes/ProjectSettings.xml:837
+#: doc/classes/ProjectSettings.xml:839
msgid "Timeout (in seconds) for connection attempts using TCP."
msgstr ""
-#: doc/classes/ProjectSettings.xml:840
+#: doc/classes/ProjectSettings.xml:842
msgid "Maximum size (in kiB) for the [WebRTCDataChannel] input buffer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:843
+#: doc/classes/ProjectSettings.xml:845
msgid "Maximum size (in kiB) for the [WebSocketClient] input buffer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:846
+#: doc/classes/ProjectSettings.xml:848
msgid "Maximum number of concurrent input packets for [WebSocketClient]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:849
+#: doc/classes/ProjectSettings.xml:851
msgid "Maximum size (in kiB) for the [WebSocketClient] output buffer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:852
+#: doc/classes/ProjectSettings.xml:854
msgid "Maximum number of concurrent output packets for [WebSocketClient]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:855
+#: doc/classes/ProjectSettings.xml:857
msgid "Maximum size (in kiB) for the [WebSocketServer] input buffer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:858
+#: doc/classes/ProjectSettings.xml:860
msgid "Maximum number of concurrent input packets for [WebSocketServer]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:861
+#: doc/classes/ProjectSettings.xml:863
msgid "Maximum size (in kiB) for the [WebSocketServer] output buffer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:864
+#: doc/classes/ProjectSettings.xml:866
msgid "Maximum number of concurrent output packets for [WebSocketServer]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:867
+#: doc/classes/ProjectSettings.xml:869
msgid ""
"Amount of read ahead used by remote filesystem. Higher values decrease the "
"effects of latency at the cost of higher bandwidth usage."
msgstr ""
-#: doc/classes/ProjectSettings.xml:870
+#: doc/classes/ProjectSettings.xml:872
msgid "Page size used by remote filesystem (in bytes)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:873
+#: doc/classes/ProjectSettings.xml:875
msgid ""
"CA certificates bundle to use for SSL connections. If not defined, Godot's "
"internal CA certificates are used."
msgstr ""
-#: doc/classes/ProjectSettings.xml:876
+#: doc/classes/ProjectSettings.xml:878
msgid ""
"When creating node names automatically, set the type of casing in this "
"project. This is mostly an editor setting."
msgstr ""
-#: doc/classes/ProjectSettings.xml:879
+#: doc/classes/ProjectSettings.xml:881
msgid ""
"What to use to separate node name from number. This is mostly an editor "
"setting."
msgstr ""
-#: doc/classes/ProjectSettings.xml:882
+#: doc/classes/ProjectSettings.xml:884
msgid "Size of the hash table used for the broad-phase 2D hash grid algorithm."
msgstr ""
-#: doc/classes/ProjectSettings.xml:885
+#: doc/classes/ProjectSettings.xml:887
msgid "Cell size used for the broad-phase 2D hash grid algorithm."
msgstr ""
-#: doc/classes/ProjectSettings.xml:888
+#: doc/classes/ProjectSettings.xml:890
msgid "The default angular damp in 2D."
msgstr ""
-#: doc/classes/ProjectSettings.xml:891
+#: doc/classes/ProjectSettings.xml:893
msgid ""
"The default gravity strength in 2D.\n"
"[b]Note:[/b] This property is only read when the project starts. To change "
@@ -39332,7 +39307,7 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/ProjectSettings.xml:899
+#: doc/classes/ProjectSettings.xml:901
msgid ""
"The default gravity direction in 2D.\n"
"[b]Note:[/b] This property is only read when the project starts. To change "
@@ -39344,38 +39319,38 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/ProjectSettings.xml:907
+#: doc/classes/ProjectSettings.xml:909
msgid "The default linear damp in 2D."
msgstr ""
-#: doc/classes/ProjectSettings.xml:910
+#: doc/classes/ProjectSettings.xml:912
msgid ""
"Threshold defining the surface size that constitutes a large object with "
"regard to cells in the broad-phase 2D hash grid algorithm."
msgstr ""
-#: doc/classes/ProjectSettings.xml:913
+#: doc/classes/ProjectSettings.xml:915
msgid ""
"Sets which physics engine to use for 2D physics.\n"
-"\"DEFAULT\" and \"GodotPhysics\" are the same, as there is currently no "
+"\"DEFAULT\" and \"GodotPhysics2D\" are the same, as there is currently no "
"alternative 2D physics server implemented."
msgstr ""
-#: doc/classes/ProjectSettings.xml:917
+#: doc/classes/ProjectSettings.xml:919
msgid ""
"Threshold angular velocity under which a 2D physics body will be considered "
"inactive. See [constant PhysicsServer2D."
"SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:920
+#: doc/classes/ProjectSettings.xml:922
msgid ""
"Threshold linear velocity under which a 2D physics body will be considered "
"inactive. See [constant PhysicsServer2D."
"SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:923
+#: doc/classes/ProjectSettings.xml:925
msgid ""
"Sets whether physics is run on the main thread or a separate one. Running "
"the server on a thread increases performance, but restricts API access to "
@@ -39385,23 +39360,23 @@ msgid ""
"give you extra performance and no regressions when using it."
msgstr ""
-#: doc/classes/ProjectSettings.xml:927
+#: doc/classes/ProjectSettings.xml:929
msgid ""
"Time (in seconds) of inactivity before which a 2D physics body will put to "
"sleep. See [constant PhysicsServer2D.SPACE_PARAM_BODY_TIME_TO_SLEEP]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:930
+#: doc/classes/ProjectSettings.xml:932
msgid ""
"Sets whether the 3D physics world will be created with support for "
"[SoftBody3D] physics. Only applies to the Bullet physics engine."
msgstr ""
-#: doc/classes/ProjectSettings.xml:933
+#: doc/classes/ProjectSettings.xml:935
msgid "The default angular damp in 3D."
msgstr ""
-#: doc/classes/ProjectSettings.xml:936
+#: doc/classes/ProjectSettings.xml:938
msgid ""
"The default gravity strength in 3D.\n"
"[b]Note:[/b] This property is only read when the project starts. To change "
@@ -39413,7 +39388,7 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/ProjectSettings.xml:944
+#: doc/classes/ProjectSettings.xml:946
msgid ""
"The default gravity direction in 3D.\n"
"[b]Note:[/b] This property is only read when the project starts. To change "
@@ -39425,23 +39400,23 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/ProjectSettings.xml:952
+#: doc/classes/ProjectSettings.xml:954
msgid "The default linear damp in 3D."
msgstr ""
-#: doc/classes/ProjectSettings.xml:955
+#: doc/classes/ProjectSettings.xml:957
msgid ""
"Sets which physics engine to use for 3D physics.\n"
"\"DEFAULT\" is currently the [url=https://bulletphysics.org]Bullet[/url] "
-"physics engine. The \"GodotPhysics\" engine is still supported as an "
+"physics engine. The \"GodotPhysics3D\" engine is still supported as an "
"alternative."
msgstr ""
-#: doc/classes/ProjectSettings.xml:959
+#: doc/classes/ProjectSettings.xml:961
msgid "Enables [member Viewport.physics_object_picking] on the root viewport."
msgstr ""
-#: doc/classes/ProjectSettings.xml:962
+#: doc/classes/ProjectSettings.xml:964
msgid ""
"The number of fixed iterations per second. This controls how often physics "
"simulation and [method Node._physics_process] methods are run.\n"
@@ -39450,7 +39425,7 @@ msgid ""
"instead."
msgstr ""
-#: doc/classes/ProjectSettings.xml:966
+#: doc/classes/ProjectSettings.xml:968
msgid ""
"Fix to improve physics jitter, specially on monitors where refresh rate is "
"different than the physics FPS.\n"
@@ -39458,7 +39433,7 @@ msgid ""
"the physics FPS at runtime, set [member Engine.physics_jitter_fix] instead."
msgstr ""
-#: doc/classes/ProjectSettings.xml:970
+#: doc/classes/ProjectSettings.xml:972
msgid ""
"Default background clear color. Overridable per [Viewport] using its "
"[Environment]. See [member Environment.background_mode] and [member "
@@ -39466,7 +39441,7 @@ msgid ""
"programmatically, use [method RenderingServer.set_default_clear_color]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:973
+#: doc/classes/ProjectSettings.xml:975
msgid ""
"[Environment] that will be used as a fallback environment in case a scene "
"does not specify its own environment. The default environment is loaded in "
@@ -39476,14 +39451,14 @@ msgid ""
"here."
msgstr ""
-#: doc/classes/ProjectSettings.xml:976
+#: doc/classes/ProjectSettings.xml:980
msgid ""
"Max amount of elements renderable in a frame. If more than this are visible "
"per frame, they will be dropped. Keep in mind elements refer to mesh "
"surfaces and not meshes themselves."
msgstr ""
-#: doc/classes/ProjectSettings.xml:979
+#: doc/classes/ProjectSettings.xml:985
msgid ""
"Some NVIDIA GPU drivers have a bug which produces flickering issues for the "
"[code]draw_rect[/code] method, especially as used in [TileMap]. Refer to "
@@ -39495,39 +39470,73 @@ msgid ""
"using the Vulkan backend."
msgstr ""
-#: doc/classes/ProjectSettings.xml:983
+#: doc/classes/ProjectSettings.xml:989
msgid ""
"If [code]true[/code], forces snapping of polygons to pixels in 2D rendering. "
"May help in some pixel art styles."
msgstr ""
-#: doc/classes/ProjectSettings.xml:986
+#: doc/classes/ProjectSettings.xml:992
+msgid ""
+"Sets the quality of the depth of field effect. Higher quality takes more "
+"samples, which is slower but looks smoother."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:995
+msgid ""
+"Sets the depth of field shape. Can be Box, Hexagon, or Circle. Box is the "
+"fastest. Circle is the most realistic, but also the most expensive to "
+"compute."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:998
+msgid ""
+"If [code]true[/code], jitters DOF samples to make effect slightly blurrier "
+"and hide lines created from low sample rates. This can result in a slightly "
+"grainy appearance when used with a low number of samples."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1001
msgid ""
"Disables depth pre-pass for some GPU vendors (usually mobile), as their "
"architecture already does this."
msgstr ""
-#: doc/classes/ProjectSettings.xml:989
+#: doc/classes/ProjectSettings.xml:1004
msgid ""
"If [code]true[/code], performs a previous depth pass before rendering "
"materials. This increases performance in scenes with high overdraw, when "
"complex materials and lighting are used."
msgstr ""
-#: doc/classes/ProjectSettings.xml:992
+#: doc/classes/ProjectSettings.xml:1007
msgid ""
"The directional shadow's size in pixels. Higher values will result in "
"sharper shadows, at the cost of performance. The value will be rounded up to "
"the nearest power of 2."
msgstr ""
-#: doc/classes/ProjectSettings.xml:995
+#: doc/classes/ProjectSettings.xml:1010
msgid ""
"Lower-end override for [member rendering/quality/directional_shadow/size] on "
"mobile devices, due to performance concerns or driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:998
+#: doc/classes/ProjectSettings.xml:1013
+msgid ""
+"Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality "
+"settings use more samples when reading from shadow maps and are thus slower. "
+"Low quality settings may result in shadows looking grainy."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1016
+msgid ""
+"Lower-end override for [member rendering/quality/directional_shadow/"
+"soft_shadow_quality] on mobile devices, due to performance concerns or "
+"driver support."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1019
msgid ""
"The video driver to use (\"GLES2\" or \"Vulkan\").\n"
"[b]Note:[/b] The backend in use can be overridden at runtime via the [code]--"
@@ -39537,25 +39546,33 @@ msgid ""
"get_current_video_driver[/code] to query it at run-time."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1012
+#: doc/classes/ProjectSettings.xml:1025
msgid ""
-"Sets the number of MSAA samples to use. MSAA is used to reduce aliasing "
-"around the edges of polygons. A higher MSAA value results in smoother edges "
-"but can be significantly slower on some hardware.\n"
-"[b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend."
+"If [code]true[/code], take additional samples when rendering objects "
+"affected by a [GIProbe] to reduce artifacts from only sampling in one "
+"direction."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1020
+#: doc/classes/ProjectSettings.xml:1028
msgid ""
-"If [code]true[/code], uses nearest-neighbor mipmap filtering when using "
-"mipmaps (also called \"bilinear filtering\"), which will result in visible "
-"seams appearing between mipmap stages. This may increase performance in "
-"mobile as less memory bandwidth is used. If [code]false[/code], linear "
-"mipmap filtering (also called \"trilinear filtering\") is used."
+"Sets the number of cone samples taken when rendering objects affected by "
+"[GIProbe]s."
msgstr ""
#: doc/classes/ProjectSettings.xml:1031
msgid ""
+"Sets how the glow effect is upscaled before being copied onto the screen. "
+"Linear is faster, but looks blocky. Bicubic is slower but looks smooth."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1034
+msgid ""
+"Lower-end override for [member rendering/quality/glow/upscale_mode] on "
+"mobile devices, due to performance concerns or driver support."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1037
+msgid ""
"Strategy used for framebuffer allocation. The simpler it is, the less "
"resources it uses (but the less features it supports). If set to \"2D "
"Without Sampling\" or \"3D Without Effects\", sample buffers will not be "
@@ -39564,41 +39581,41 @@ msgid ""
"be available in the [Environment]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1034
+#: doc/classes/ProjectSettings.xml:1040
msgid ""
"Lower-end override for [member rendering/quality/intended_usage/"
"framebuffer_allocation] on mobile devices, due to performance concerns or "
"driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1037
+#: doc/classes/ProjectSettings.xml:1043
msgid ""
"Number of cubemaps to store in the reflection atlas. The number of "
"[ReflectionProbe]s in a scene will be limited by this amount. A higher "
"number requires more VRAM."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1040
+#: doc/classes/ProjectSettings.xml:1046
msgid ""
"Size of cubemap faces for [ReflectionProbe]s. A higher number requires more "
"VRAM and may make reflection probe updating slower."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1043
+#: doc/classes/ProjectSettings.xml:1049
msgid ""
"Lower-end override for [member rendering/quality/reflection_atlas/"
"reflection_size] on mobile devices, due to performance concerns or driver "
"support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1046
+#: doc/classes/ProjectSettings.xml:1052
msgid ""
"Use a higher quality variant of the fast filtering algorithm. Significantly "
"slower than using default quality, but results in smoother reflections. "
"Should only be used when the scene is especially detailed."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1049
+#: doc/classes/ProjectSettings.xml:1055
msgid ""
"Sets the number of samples to take when using importance sampling for [Sky]s "
"and [ReflectionProbe]s. A higher value will result in smoother, higher "
@@ -39608,19 +39625,19 @@ msgid ""
"environments with a high level of detail."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1052
+#: doc/classes/ProjectSettings.xml:1058
msgid ""
"Lower-end override for [member rendering/quality/reflections/ggx_samples] on "
"mobile devices, due to performance concerns or driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1055
+#: doc/classes/ProjectSettings.xml:1061
msgid ""
"Limits the number of layers to use in radiance maps when using importance "
"sampling. A lower number will be slightly faster and take up less VRAM."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1058
+#: doc/classes/ProjectSettings.xml:1064
msgid ""
"If [code]true[/code], uses texture arrays instead of mipmaps for reflection "
"probes and panorama backgrounds (sky). This reduces jitter noise and "
@@ -39629,128 +39646,229 @@ msgid ""
"memory."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1061
+#: doc/classes/ProjectSettings.xml:1067
msgid ""
"Lower-end override for [member rendering/quality/reflections/"
"texture_array_reflections] on mobile devices, due to performance concerns or "
"driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1066
+#: doc/classes/ProjectSettings.xml:1070
+msgid ""
+"Sets the number of MSAA samples to use. MSAA is used to reduce aliasing "
+"around the edges of polygons. A higher MSAA value results in smoother edges "
+"but can be significantly slower on some hardware.\n"
+"[b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1074
+msgid ""
+"Sets the screen-space antialiasing mode for the default screen [Viewport]. "
+"Screen-space antialiasing works by selectively blurring edges in a post-"
+"process shader. It differs from MSAA which takes multiple coverage samples "
+"while rendering objects. Screen-space AA methods are typically faster than "
+"MSAA and will smooth out specular aliasing, but tend to make scenes appear "
+"blurry.\n"
+"Another way to combat specular aliasing is to enable [member rendering/"
+"quality/screen_filters/screen_space_roughness_limiter]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1078
+msgid ""
+"Enables the screen-space roughness limiter which increases material "
+"roughness in areas with a high normal frequency (i.e. when normals change a "
+"lot from pixel to pixel). This helps to reduce the amount of specular "
+"aliasing in a scene. Specular aliasing looks like random bright pixels that "
+"occur in reflections."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1081
+msgid ""
+"Curves the amount of the roughness limited effect. A higher value limits the "
+"effect to very sharply curved surfaces, while a lower threshold extends the "
+"effect to smoother surfaces."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1084
+msgid ""
+"Sets the quality for rough screen-space reflections. Turning off will make "
+"all screen space reflections sharp, while higher values make rough "
+"reflections look better."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1087
msgid ""
"If [code]true[/code], uses faster but lower-quality Blinn model to generate "
"blurred reflections instead of the GGX model."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1069
+#: doc/classes/ProjectSettings.xml:1090
msgid ""
"Lower-end override for [member rendering/quality/shading/"
"force_blinn_over_ggx] on mobile devices, due to performance concerns or "
"driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1072
+#: doc/classes/ProjectSettings.xml:1093
msgid ""
"If [code]true[/code], uses faster but lower-quality Lambert material "
"lighting model instead of Burley."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1075
+#: doc/classes/ProjectSettings.xml:1096
msgid ""
"Lower-end override for [member rendering/quality/shading/"
"force_lambert_over_burley] on mobile devices, due to performance concerns or "
"driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1078
+#: doc/classes/ProjectSettings.xml:1099
msgid ""
"If [code]true[/code], forces vertex shading for all rendering. This can "
"increase performance a lot, but also reduces quality immensely. Can be used "
"to optimize performance on low-end mobile devices."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1081
+#: doc/classes/ProjectSettings.xml:1102
msgid ""
"Lower-end override for [member rendering/quality/shading/"
"force_vertex_shading] on mobile devices, due to performance concerns or "
"driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1084 doc/classes/ProjectSettings.xml:1087
-#: doc/classes/ProjectSettings.xml:1090 doc/classes/ProjectSettings.xml:1093
+#: doc/classes/ProjectSettings.xml:1105 doc/classes/ProjectSettings.xml:1108
+#: doc/classes/ProjectSettings.xml:1111 doc/classes/ProjectSettings.xml:1114
msgid ""
"Subdivision quadrant size for shadow mapping. See shadow mapping "
"documentation."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1096
+#: doc/classes/ProjectSettings.xml:1117
msgid ""
"Size for shadow atlas (used for OmniLights and SpotLights). See "
"documentation."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1099
+#: doc/classes/ProjectSettings.xml:1120
msgid ""
"Lower-end override for [member rendering/quality/shadow_atlas/size] on "
"mobile devices, due to performance concerns or driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1102
+#: doc/classes/ProjectSettings.xml:1123
msgid ""
-"Shadow filter mode. Higher-quality settings result in smoother shadows that "
-"flicker less when moving. \"Disabled\" is the fastest option, but also has "
-"the lowest quality. \"PCF5\" is smoother but is also slower. \"PCF13\" is "
-"the smoothest option, but is also the slowest."
+"Quality setting for shadows cast by [OmniLight3D]s and [SpotLight3D]s. "
+"Higher quality settings use more samples when reading from shadow maps and "
+"are thus slower. Low quality settings may result in shadows looking grainy."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1105
+#: doc/classes/ProjectSettings.xml:1126
msgid ""
-"Lower-end override for [member rendering/quality/shadows/filter_mode] on "
-"mobile devices, due to performance concerns or driver support."
+"Lower-end override for [member rendering/quality/shadows/"
+"soft_shadow_quality] on mobile devices, due to performance concerns or "
+"driver support."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1129
+msgid ""
+"If [code]true[/code], screen-space ambient occlusion will be rendered at "
+"half size and then upscaled before being added to the scene. This is "
+"significantly faster but may miss small details."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1132
+msgid ""
+"Sets the quality of the screen-space ambient occlusion effect. Higher values "
+"take more samples and so will result in better quality, at the cost of "
+"performance."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1135
+msgid ""
+"Scales the depth over which the subsurface scattering effect is applied. A "
+"high value may allow light to scatter into a part of the mesh or another "
+"mesh that is close in screen space but far in depth."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1138
+msgid ""
+"Sets the quality of the subsurface scattering effect. Higher values are "
+"slower but look nicer."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1141
+msgid ""
+"Scales the distance over which samples are taken for subsurface scattering "
+"effect. Changing this does not impact performance, but higher values will "
+"result in significant artifacts as the samples will become obviously spread "
+"out. A lower value results in a smaller spread of scattered light."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1118
+#: doc/classes/ProjectSettings.xml:1144
+msgid ""
+"Sets the maximum number of samples to take when using anisotropic filtering "
+"on textures. A higher sample count will result in sharper textures at "
+"oblique angles, but is more expensive to compute.\n"
+"Only power of two values are valid ([code]1[/code], [code]2[/code], [code]4[/"
+"code], [code]8[/code], [code]16[/code]). A value of [code]1[/code] forcibly "
+"disables anisotropic filtering, even on materials where it is enabled."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1148
+msgid ""
+"If [code]true[/code], uses nearest-neighbor mipmap filtering when using "
+"mipmaps (also called \"bilinear filtering\"), which will result in visible "
+"seams appearing between mipmap stages. This may increase performance in "
+"mobile as less memory bandwidth is used. If [code]false[/code], linear "
+"mipmap filtering (also called \"trilinear filtering\") is used."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1151
msgid ""
"Thread model for rendering. Rendering on a thread can vastly improve "
"performance, but synchronizing to the main thread can cause a bit more "
"jitter."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1121
+#: doc/classes/ProjectSettings.xml:1154
msgid ""
"If [code]true[/code], the texture importer will import VRAM-compressed "
"textures using the BPTC algorithm. This texture compression algorithm is "
"only supported on desktop platforms, and only when using the Vulkan renderer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1124
+#: doc/classes/ProjectSettings.xml:1157
msgid ""
"If [code]true[/code], the texture importer will import VRAM-compressed "
"textures using the Ericsson Texture Compression algorithm. This algorithm "
"doesn't support alpha channels in textures."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1127
+#: doc/classes/ProjectSettings.xml:1160
msgid ""
"If [code]true[/code], the texture importer will import VRAM-compressed "
"textures using the Ericsson Texture Compression 2 algorithm. This texture "
"compression algorithm is only supported when using the Vulkan renderer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1130
+#: doc/classes/ProjectSettings.xml:1163
msgid ""
"If [code]true[/code], the texture importer will import VRAM-compressed "
"textures using the PowerVR Texture Compression algorithm. This texture "
"compression algorithm is only supported on iOS."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1133
+#: doc/classes/ProjectSettings.xml:1166
msgid ""
"If [code]true[/code], the texture importer will import VRAM-compressed "
"textures using the S3 Texture Compression algorithm. This algorithm is only "
"supported on desktop platforms and consoles."
msgstr ""
+#: doc/classes/ProjectSettings.xml:1177
+msgid "Cell size used for the 2D hash grid that [VisibilityNotifier2D] uses."
+msgstr ""
+
#: doc/classes/ProximityGroup3D.xml:4 doc/classes/ProximityGroup3D.xml:7
msgid "General-purpose proximity detection node."
msgstr ""
@@ -40851,11 +40969,11 @@ msgstr ""
#: doc/classes/RenderingServer.xml:7
msgid ""
-"Server for anything visible. The visual server is the API backend for "
+"Server for anything visible. The rendering server is the API backend for "
"everything visible. The whole scene system mounts on it to display.\n"
-"The visual server is completely opaque, the internals are entirely "
+"The rendering server is completely opaque, the internals are entirely "
"implementation specific and cannot be accessed.\n"
-"The visual server can be used to bypass the scene system entirely.\n"
+"The rendering server can be used to bypass the scene system entirely.\n"
"Resources are created using the [code]*_create[/code] functions.\n"
"All objects are drawn to a viewport. You can use the [Viewport] attached to "
"the [SceneTree] or you can create one yourself with [method "
@@ -40863,10 +40981,10 @@ msgid ""
"canvas needs to be attached to the viewport using [method "
"viewport_set_scenario] or [method viewport_attach_canvas].\n"
"In 3D, all visual objects must be associated with a scenario. The scenario "
-"is a visual representation of the world. If accessing the visual server from "
-"a running game, the scenario can be accessed from the scene tree from any "
-"[Node3D] node with [method Node3D.get_world]. Otherwise, a scenario can be "
-"created with [method scenario_create].\n"
+"is a visual representation of the world. If accessing the rendering server "
+"from a running game, the scenario can be accessed from the scene tree from "
+"any [Node3D] node with [method Node3D.get_world]. Otherwise, a scenario can "
+"be created with [method scenario_create].\n"
"Similarly in 2D, a canvas is needed to draw all canvas items.\n"
"In 3D, all visible objects are comprised of a resource and an instance. A "
"resource can be a mesh, a particle system, a light, or any other 3D object. "
@@ -41292,42 +41410,42 @@ msgstr ""
msgid "Returns the id of a white texture. Creates one if none exists."
msgstr ""
-#: doc/classes/RenderingServer.xml:954
+#: doc/classes/RenderingServer.xml:1006
msgid ""
"Returns [code]true[/code] if changes have been made to the RenderingServer's "
"data. [method force_draw] is usually called if this happens."
msgstr ""
-#: doc/classes/RenderingServer.xml:963
+#: doc/classes/RenderingServer.xml:1015
msgid "Not yet implemented. Always returns [code]false[/code]."
msgstr ""
-#: doc/classes/RenderingServer.xml:972
+#: doc/classes/RenderingServer.xml:1024
msgid ""
"Returns [code]true[/code] if the OS supports a certain feature. Features "
"might be [code]s3tc[/code], [code]etc[/code], [code]etc2[/code] and "
"[code]pvrtc[/code]."
msgstr ""
-#: doc/classes/RenderingServer.xml:985
+#: doc/classes/RenderingServer.xml:1037
msgid ""
"Sets up [ImmediateGeometry3D] internals to prepare for drawing. Equivalent "
"to [method ImmediateGeometry3D.begin]."
msgstr ""
-#: doc/classes/RenderingServer.xml:994
+#: doc/classes/RenderingServer.xml:1046
msgid ""
"Clears everything that was set up between [method immediate_begin] and "
"[method immediate_end]. Equivalent to [method ImmediateGeometry3D.clear]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1005
+#: doc/classes/RenderingServer.xml:1057
msgid ""
"Sets the color to be used with next vertex. Equivalent to [method "
"ImmediateGeometry3D.set_color]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1012
+#: doc/classes/RenderingServer.xml:1064
msgid ""
"Creates an immediate geometry and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -41338,78 +41456,78 @@ msgid ""
"[method instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:1023
+#: doc/classes/RenderingServer.xml:1075
msgid ""
"Ends drawing the [ImmediateGeometry3D] and displays it. Equivalent to "
"[method ImmediateGeometry3D.end]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1032
+#: doc/classes/RenderingServer.xml:1084
msgid "Returns the material assigned to the [ImmediateGeometry3D]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1043
+#: doc/classes/RenderingServer.xml:1095
msgid ""
"Sets the normal to be used with next vertex. Equivalent to [method "
"ImmediateGeometry3D.set_normal]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1054
+#: doc/classes/RenderingServer.xml:1106
msgid "Sets the material to be used to draw the [ImmediateGeometry3D]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1065
+#: doc/classes/RenderingServer.xml:1117
msgid ""
"Sets the tangent to be used with next vertex. Equivalent to [method "
"ImmediateGeometry3D.set_tangent]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1076
+#: doc/classes/RenderingServer.xml:1128
msgid ""
"Sets the UV to be used with next vertex. Equivalent to [method "
"ImmediateGeometry3D.set_uv]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1087
+#: doc/classes/RenderingServer.xml:1139
msgid ""
"Sets the UV2 to be used with next vertex. Equivalent to [method "
"ImmediateGeometry3D.set_uv2]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1098
+#: doc/classes/RenderingServer.xml:1150
msgid ""
"Adds the next vertex using the information provided in advance. Equivalent "
"to [method ImmediateGeometry3D.add_vertex]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1109
+#: doc/classes/RenderingServer.xml:1161
msgid ""
"Adds the next vertex using the information provided in advance. This is a "
"helper class that calls [method immediate_vertex] under the hood. Equivalent "
"to [method ImmediateGeometry3D.add_vertex]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1116
+#: doc/classes/RenderingServer.xml:1168
msgid ""
-"Initializes the visual server. This function is called internally by "
+"Initializes the rendering server. This function is called internally by "
"platform-dependent code during engine initialization. If called from a "
"running game, it will not do anything."
msgstr ""
-#: doc/classes/RenderingServer.xml:1127
+#: doc/classes/RenderingServer.xml:1179
msgid ""
"Attaches a unique Object ID to instance. Object ID must be attached to "
"instance for proper culling with [method instances_cull_aabb], [method "
"instances_cull_convex], and [method instances_cull_ray]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1138
+#: doc/classes/RenderingServer.xml:1190
msgid ""
"Attaches a skeleton to an instance. Removes the previous skeleton from the "
"instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:1145
+#: doc/classes/RenderingServer.xml:1197
msgid ""
"Creates a visual instance and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -41421,7 +41539,7 @@ msgid ""
"instance to be visible in the scenario using [method instance_set_base]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1158
+#: doc/classes/RenderingServer.xml:1210
msgid ""
"Creates a visual instance, adds it to the RenderingServer, and sets both "
"base and scenario. It can be accessed with the RID that is returned. This "
@@ -41430,31 +41548,31 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:1170 doc/classes/RenderingServer.xml:1198
-#: doc/classes/RenderingServer.xml:1488
+#: doc/classes/RenderingServer.xml:1222 doc/classes/RenderingServer.xml:1250
+#: doc/classes/RenderingServer.xml:1540
msgid "Not implemented in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:1181
+#: doc/classes/RenderingServer.xml:1233
msgid ""
"Sets the shadow casting setting to one of [enum ShadowCastingSetting]. "
"Equivalent to [member GeometryInstance3D.cast_shadow]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1211
+#: doc/classes/RenderingServer.xml:1263
msgid ""
"Sets the flag for a given [enum InstanceFlags]. See [enum InstanceFlags] for "
"more details."
msgstr ""
-#: doc/classes/RenderingServer.xml:1222
+#: doc/classes/RenderingServer.xml:1274
msgid ""
"Sets a material that will override the material for all surfaces on the mesh "
"associated with this instance. Equivalent to [member GeometryInstance3D."
"material_override]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1233
+#: doc/classes/RenderingServer.xml:1285
msgid ""
"Sets the base of the instance. A base can be any of the 3D objects that are "
"created in the RenderingServer that can be displayed. For example, any of "
@@ -41463,62 +41581,62 @@ msgid ""
"be set as the base of an instance in order to be displayed in the scenario."
msgstr ""
-#: doc/classes/RenderingServer.xml:1246
+#: doc/classes/RenderingServer.xml:1298
msgid "Sets the weight for a given blend shape associated with this instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:1257
+#: doc/classes/RenderingServer.xml:1309
msgid ""
"Sets a custom AABB to use when culling objects from the view frustum. "
"Equivalent to [method GeometryInstance3D.set_custom_aabb]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1268
+#: doc/classes/RenderingServer.xml:1320
msgid "Function not implemented in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:1279
+#: doc/classes/RenderingServer.xml:1331
msgid ""
"Sets a margin to increase the size of the AABB when culling objects from the "
"view frustum. This allows you avoid culling objects that fall outside the "
"view frustum. Equivalent to [member GeometryInstance3D.extra_cull_margin]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1290
+#: doc/classes/RenderingServer.xml:1342
msgid ""
"Sets the render layers that this instance will be drawn to. Equivalent to "
"[member VisualInstance3D.layers]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1301
+#: doc/classes/RenderingServer.xml:1353
msgid ""
"Sets the scenario that the instance is in. The scenario is the 3D world that "
"the objects will be displayed in."
msgstr ""
-#: doc/classes/RenderingServer.xml:1314
+#: doc/classes/RenderingServer.xml:1366
msgid ""
"Sets the material of a specific surface. Equivalent to [method "
"MeshInstance3D.set_surface_material]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1325
+#: doc/classes/RenderingServer.xml:1377
msgid ""
"Sets the world space transform of the instance. Equivalent to [member Node3D."
"transform]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1338
+#: doc/classes/RenderingServer.xml:1390
msgid "Sets the lightmap to use with this instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:1349
+#: doc/classes/RenderingServer.xml:1401
msgid ""
"Sets whether an instance is drawn or not. Equivalent to [member Node3D."
"visible]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1360
+#: doc/classes/RenderingServer.xml:1412
msgid ""
"Returns an array of object IDs intersecting with the provided AABB. Only "
"visual 3D nodes are considered, such as [MeshInstance3D] or "
@@ -41530,7 +41648,7 @@ msgid ""
"game use cases, prefer physics collision."
msgstr ""
-#: doc/classes/RenderingServer.xml:1372
+#: doc/classes/RenderingServer.xml:1424
msgid ""
"Returns an array of object IDs intersecting with the provided convex shape. "
"Only visual 3D nodes are considered, such as [MeshInstance3D] or "
@@ -41542,7 +41660,7 @@ msgid ""
"game use cases, prefer physics collision."
msgstr ""
-#: doc/classes/RenderingServer.xml:1386
+#: doc/classes/RenderingServer.xml:1438
msgid ""
"Returns an array of object IDs intersecting with the provided 3D ray. Only "
"visual 3D nodes are considered, such as [MeshInstance3D] or "
@@ -41554,58 +41672,58 @@ msgid ""
"game use cases, prefer physics collision."
msgstr ""
-#: doc/classes/RenderingServer.xml:1398
+#: doc/classes/RenderingServer.xml:1450
msgid ""
"If [code]true[/code], this directional light will blend between shadow map "
"splits resulting in a smoother transition between them. Equivalent to "
"[member DirectionalLight3D.directional_shadow_blend_splits]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1409
+#: doc/classes/RenderingServer.xml:1461
msgid ""
"Sets the shadow depth range mode for this directional light. Equivalent to "
"[member DirectionalLight3D.directional_shadow_depth_range]. See [enum "
"LightDirectionalShadowDepthRangeMode] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:1420
+#: doc/classes/RenderingServer.xml:1472
msgid ""
"Sets the shadow mode for this directional light. Equivalent to [member "
"DirectionalLight3D.directional_shadow_mode]. See [enum "
"LightDirectionalShadowMode] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:1431
+#: doc/classes/RenderingServer.xml:1483
msgid ""
"Sets whether to use a dual paraboloid or a cubemap for the shadow map. Dual "
"paraboloid is faster but may suffer from artifacts. Equivalent to [member "
"OmniLight3D.omni_shadow_mode]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1442
+#: doc/classes/RenderingServer.xml:1494
msgid ""
"Sets the color of the light. Equivalent to [member Light3D.light_color]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1453
+#: doc/classes/RenderingServer.xml:1505
msgid ""
"Sets the cull mask for this Light3D. Lights only affect objects in the "
"selected layers. Equivalent to [member Light3D.light_cull_mask]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1464
+#: doc/classes/RenderingServer.xml:1516
msgid ""
"If [code]true[/code], light will subtract light instead of adding light. "
"Equivalent to [member Light3D.light_negative]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1477
+#: doc/classes/RenderingServer.xml:1529
msgid ""
"Sets the specified light parameter. See [enum LightParam] for options. "
"Equivalent to [method Light3D.set_param]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1499
+#: doc/classes/RenderingServer.xml:1551
msgid ""
"If [code]true[/code], reverses the backface culling of the mesh. This can be "
"useful when you have a flat mesh that has a light behind it. If you need to "
@@ -41614,23 +41732,23 @@ msgid ""
"to [member Light3D.shadow_reverse_cull_face]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1510
+#: doc/classes/RenderingServer.xml:1562
msgid ""
"If [code]true[/code], light will cast shadows. Equivalent to [member Light3D."
"shadow_enabled]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1521
+#: doc/classes/RenderingServer.xml:1573
msgid ""
"Sets the color of the shadow cast by the light. Equivalent to [member "
"Light3D.shadow_color]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1532
+#: doc/classes/RenderingServer.xml:1584
msgid "Sets whether GI probes capture light information from this light."
msgstr ""
-#: doc/classes/RenderingServer.xml:1539
+#: doc/classes/RenderingServer.xml:1591
msgid ""
"Creates a lightmap capture and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -41641,54 +41759,54 @@ msgid ""
"[method instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:1550
+#: doc/classes/RenderingServer.xml:1602
msgid "Returns the size of the lightmap capture area."
msgstr ""
-#: doc/classes/RenderingServer.xml:1559
+#: doc/classes/RenderingServer.xml:1611
msgid "Returns the energy multiplier used by the lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:1568
+#: doc/classes/RenderingServer.xml:1620
msgid "Returns the octree used by the lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:1577
+#: doc/classes/RenderingServer.xml:1629
msgid ""
"Returns the cell subdivision amount used by this lightmap capture's octree."
msgstr ""
-#: doc/classes/RenderingServer.xml:1586
+#: doc/classes/RenderingServer.xml:1638
msgid "Returns the cell transform for this lightmap capture's octree."
msgstr ""
-#: doc/classes/RenderingServer.xml:1597
+#: doc/classes/RenderingServer.xml:1649
msgid "Sets the size of the area covered by the lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:1608
+#: doc/classes/RenderingServer.xml:1660
msgid "Sets the energy multiplier for this lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:1619
+#: doc/classes/RenderingServer.xml:1671
msgid "Sets the octree to be used by this lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:1630
+#: doc/classes/RenderingServer.xml:1682
msgid "Sets the subdivision level of this lightmap capture's octree."
msgstr ""
-#: doc/classes/RenderingServer.xml:1641
+#: doc/classes/RenderingServer.xml:1693
msgid "Sets the octree cell transform for this lightmap capture's octree."
msgstr ""
-#: doc/classes/RenderingServer.xml:1654
+#: doc/classes/RenderingServer.xml:1706
msgid ""
"Returns a mesh of a sphere with the given amount of horizontal and vertical "
"subdivisions."
msgstr ""
-#: doc/classes/RenderingServer.xml:1661
+#: doc/classes/RenderingServer.xml:1713
msgid ""
"Creates an empty material and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -41697,31 +41815,31 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:1673
+#: doc/classes/RenderingServer.xml:1725
msgid "Returns the value of a certain material's parameter."
msgstr ""
-#: doc/classes/RenderingServer.xml:1684
+#: doc/classes/RenderingServer.xml:1736
msgid "Sets an object's next material."
msgstr ""
-#: doc/classes/RenderingServer.xml:1697
+#: doc/classes/RenderingServer.xml:1749
msgid "Sets a material's parameter."
msgstr ""
-#: doc/classes/RenderingServer.xml:1708
+#: doc/classes/RenderingServer.xml:1760
msgid "Sets a material's render priority."
msgstr ""
-#: doc/classes/RenderingServer.xml:1719
+#: doc/classes/RenderingServer.xml:1771
msgid "Sets a shader material's shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:1748
+#: doc/classes/RenderingServer.xml:1800
msgid "Removes all surfaces from a mesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1755
+#: doc/classes/RenderingServer.xml:1807
msgid ""
"Creates a new mesh and adds it to the RenderingServer. It can be accessed "
"with the RID that is returned. This RID will be used in all [code]mesh_*[/"
@@ -41732,58 +41850,58 @@ msgid ""
"instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:1766
+#: doc/classes/RenderingServer.xml:1818
msgid "Returns a mesh's blend shape count."
msgstr ""
-#: doc/classes/RenderingServer.xml:1775
+#: doc/classes/RenderingServer.xml:1827
msgid "Returns a mesh's blend shape mode."
msgstr ""
-#: doc/classes/RenderingServer.xml:1784
+#: doc/classes/RenderingServer.xml:1836
msgid "Returns a mesh's custom aabb."
msgstr ""
-#: doc/classes/RenderingServer.xml:1793
+#: doc/classes/RenderingServer.xml:1845
msgid "Returns a mesh's number of surfaces."
msgstr ""
-#: doc/classes/RenderingServer.xml:1804
+#: doc/classes/RenderingServer.xml:1856
msgid "Sets a mesh's blend shape mode."
msgstr ""
-#: doc/classes/RenderingServer.xml:1815
+#: doc/classes/RenderingServer.xml:1867
msgid "Sets a mesh's custom aabb."
msgstr ""
-#: doc/classes/RenderingServer.xml:1826
+#: doc/classes/RenderingServer.xml:1878
msgid "Returns a mesh's surface's buffer arrays."
msgstr ""
-#: doc/classes/RenderingServer.xml:1837
+#: doc/classes/RenderingServer.xml:1889
msgid "Returns a mesh's surface's arrays for blend shapes."
msgstr ""
-#: doc/classes/RenderingServer.xml:1852 doc/classes/RenderingServer.xml:1865
+#: doc/classes/RenderingServer.xml:1904 doc/classes/RenderingServer.xml:1917
msgid "Function is unused in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:1876
+#: doc/classes/RenderingServer.xml:1928
msgid "Returns a mesh's surface's material."
msgstr ""
-#: doc/classes/RenderingServer.xml:1889
+#: doc/classes/RenderingServer.xml:1941
msgid "Sets a mesh's surface's material."
msgstr ""
-#: doc/classes/RenderingServer.xml:1904
+#: doc/classes/RenderingServer.xml:1956
msgid ""
"Updates a specific region of a vertex buffer for the specified surface. "
"Warning: this function alters the vertex buffer directly with no safety "
"mechanisms, you can easily corrupt your mesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1927
+#: doc/classes/RenderingServer.xml:1979
msgid ""
"Creates a new multimesh on the RenderingServer and returns an [RID] handle. "
"This RID will be used in all [code]multimesh_*[/code] RenderingServer "
@@ -41794,82 +41912,82 @@ msgid ""
"instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:1938
+#: doc/classes/RenderingServer.xml:1990
msgid ""
"Calculates and returns the axis-aligned bounding box that encloses all "
"instances within the multimesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1955
+#: doc/classes/RenderingServer.xml:2007
msgid "Returns the number of instances allocated for this multimesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1964
+#: doc/classes/RenderingServer.xml:2016
msgid ""
"Returns the RID of the mesh that will be used in drawing this multimesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1973
+#: doc/classes/RenderingServer.xml:2025
msgid "Returns the number of visible instances for this multimesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1984
+#: doc/classes/RenderingServer.xml:2036
msgid "Returns the color by which the specified instance will be modulated."
msgstr ""
-#: doc/classes/RenderingServer.xml:1995
+#: doc/classes/RenderingServer.xml:2047
msgid "Returns the custom data associated with the specified instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:2006
+#: doc/classes/RenderingServer.xml:2058
msgid "Returns the [Transform] of the specified instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:2017
+#: doc/classes/RenderingServer.xml:2069
msgid ""
"Returns the [Transform2D] of the specified instance. For use when the "
"multimesh is set to use 2D transforms."
msgstr ""
-#: doc/classes/RenderingServer.xml:2030
+#: doc/classes/RenderingServer.xml:2082
msgid ""
"Sets the color by which this instance will be modulated. Equivalent to "
"[method MultiMesh.set_instance_color]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2043
+#: doc/classes/RenderingServer.xml:2095
msgid ""
"Sets the custom data for this instance. Custom data is passed as a [Color], "
"but is interpreted as a [code]vec4[/code] in the shader. Equivalent to "
"[method MultiMesh.set_instance_custom_data]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2056
+#: doc/classes/RenderingServer.xml:2108
msgid ""
"Sets the [Transform] for this instance. Equivalent to [method MultiMesh."
"set_instance_transform]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2069
+#: doc/classes/RenderingServer.xml:2121
msgid ""
"Sets the [Transform2D] for this instance. For use when multimesh is used in "
"2D. Equivalent to [method MultiMesh.set_instance_transform_2d]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2090
+#: doc/classes/RenderingServer.xml:2142
msgid ""
"Sets the mesh to be drawn by the multimesh. Equivalent to [member MultiMesh."
"mesh]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2101
+#: doc/classes/RenderingServer.xml:2153
msgid ""
"Sets the number of instances visible at a given time. If -1, all instances "
"that have been allocated are drawn. Equivalent to [member MultiMesh."
"visible_instance_count]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2108
+#: doc/classes/RenderingServer.xml:2160
msgid ""
"Creates a new omni light and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID can be used in most "
@@ -41880,7 +41998,7 @@ msgid ""
"instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:2117
+#: doc/classes/RenderingServer.xml:2169
msgid ""
"Creates a particle system and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -41891,23 +42009,23 @@ msgid ""
"instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:2128
+#: doc/classes/RenderingServer.xml:2180
msgid ""
"Calculates and returns the axis-aligned bounding box that contains all the "
"particles. Equivalent to [method GPUParticles3D.capture_aabb]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2137
+#: doc/classes/RenderingServer.xml:2189
msgid "Returns [code]true[/code] if particles are currently set to emitting."
msgstr ""
-#: doc/classes/RenderingServer.xml:2146
+#: doc/classes/RenderingServer.xml:2198
msgid ""
"Returns [code]true[/code] if particles are not emitting and particles are "
"set to inactive."
msgstr ""
-#: doc/classes/RenderingServer.xml:2155
+#: doc/classes/RenderingServer.xml:2207
msgid ""
"Add particle system to list of particle systems that need to be updated. "
"Update will take place on the next frame, or on the next call to [method "
@@ -41915,121 +42033,121 @@ msgid ""
"instances_cull_ray]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2164
+#: doc/classes/RenderingServer.xml:2216
msgid ""
"Reset the particles on the next update. Equivalent to [method GPUParticles3D."
"restart]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2175
+#: doc/classes/RenderingServer.xml:2227
msgid ""
"Sets the number of particles to be drawn and allocates the memory for them. "
"Equivalent to [member GPUParticles3D.amount]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2186
+#: doc/classes/RenderingServer.xml:2238
msgid ""
"Sets a custom axis-aligned bounding box for the particle system. Equivalent "
"to [member GPUParticles3D.visibility_aabb]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2197
+#: doc/classes/RenderingServer.xml:2249
msgid ""
"Sets the draw order of the particles to one of the named enums from [enum "
"ParticlesDrawOrder]. See [enum ParticlesDrawOrder] for options. Equivalent "
"to [member GPUParticles3D.draw_order]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2210
+#: doc/classes/RenderingServer.xml:2262
msgid ""
"Sets the mesh to be used for the specified draw pass. Equivalent to [member "
"GPUParticles3D.draw_pass_1], [member GPUParticles3D.draw_pass_2], [member "
"GPUParticles3D.draw_pass_3], and [member GPUParticles3D.draw_pass_4]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2221
+#: doc/classes/RenderingServer.xml:2273
msgid ""
"Sets the number of draw passes to use. Equivalent to [member GPUParticles3D."
"draw_passes]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2232
+#: doc/classes/RenderingServer.xml:2284
msgid ""
"Sets the [Transform] that will be used by the particles when they first emit."
msgstr ""
-#: doc/classes/RenderingServer.xml:2243
+#: doc/classes/RenderingServer.xml:2295
msgid ""
"If [code]true[/code], particles will emit over time. Setting to false does "
"not reset the particles, but only stops their emission. Equivalent to "
"[member GPUParticles3D.emitting]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2254
+#: doc/classes/RenderingServer.xml:2306
msgid ""
"Sets the explosiveness ratio. Equivalent to [member GPUParticles3D."
"explosiveness]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2265
+#: doc/classes/RenderingServer.xml:2317
msgid ""
"Sets the frame rate that the particle system rendering will be fixed to. "
"Equivalent to [member GPUParticles3D.fixed_fps]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2276
+#: doc/classes/RenderingServer.xml:2328
msgid ""
"If [code]true[/code], uses fractional delta which smooths the movement of "
"the particles. Equivalent to [member GPUParticles3D.fract_delta]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2287
+#: doc/classes/RenderingServer.xml:2339
msgid ""
"Sets the lifetime of each particle in the system. Equivalent to [member "
"GPUParticles3D.lifetime]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2298
+#: doc/classes/RenderingServer.xml:2350
msgid ""
"If [code]true[/code], particles will emit once and then stop. Equivalent to "
"[member GPUParticles3D.one_shot]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2309
+#: doc/classes/RenderingServer.xml:2361
msgid ""
"Sets the preprocess time for the particles animation. This lets you delay "
"starting an animation until after the particles have begun emitting. "
"Equivalent to [member GPUParticles3D.preprocess]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2320
+#: doc/classes/RenderingServer.xml:2372
msgid ""
"Sets the material for processing the particles. Note: this is not the "
"material used to draw the materials. Equivalent to [member GPUParticles3D."
"process_material]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2331
+#: doc/classes/RenderingServer.xml:2383
msgid ""
"Sets the emission randomness ratio. This randomizes the emission of "
"particles within their phase. Equivalent to [member GPUParticles3D."
"randomness]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2342
+#: doc/classes/RenderingServer.xml:2394
msgid ""
"Sets the speed scale of the particle system. Equivalent to [member "
"GPUParticles3D.speed_scale]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2353
+#: doc/classes/RenderingServer.xml:2405
msgid ""
"If [code]true[/code], particles use local coordinates. If [code]false[/code] "
"they use global coordinates. Equivalent to [member GPUParticles3D."
"local_coords]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2360
+#: doc/classes/RenderingServer.xml:2412
msgid ""
"Creates a reflection probe and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -42040,59 +42158,59 @@ msgid ""
"[method instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:2373
+#: doc/classes/RenderingServer.xml:2425
msgid ""
"If [code]true[/code], reflections will ignore sky contribution. Equivalent "
"to [member ReflectionProbe.interior_enable]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2384
+#: doc/classes/RenderingServer.xml:2436
msgid ""
"Sets the render cull mask for this reflection probe. Only instances with a "
"matching cull mask will be rendered by this probe. Equivalent to [member "
"ReflectionProbe.cull_mask]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2395
+#: doc/classes/RenderingServer.xml:2447
msgid ""
"If [code]true[/code], uses box projection. This can make reflections look "
"more correct in certain situations. Equivalent to [member ReflectionProbe."
"box_projection]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2406
+#: doc/classes/RenderingServer.xml:2458
msgid ""
"If [code]true[/code], computes shadows in the reflection probe. This makes "
"the reflection much slower to compute. Equivalent to [member ReflectionProbe."
"enable_shadows]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2417
+#: doc/classes/RenderingServer.xml:2469
msgid ""
"Sets the size of the area that the reflection probe will capture. Equivalent "
"to [member ReflectionProbe.extents]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2428
+#: doc/classes/RenderingServer.xml:2480
msgid ""
"Sets the intensity of the reflection probe. Intensity modulates the strength "
"of the reflection. Equivalent to [member ReflectionProbe.intensity]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2439
+#: doc/classes/RenderingServer.xml:2491
msgid ""
"Sets the ambient light color for this reflection probe when set to interior "
"mode. Equivalent to [member ReflectionProbe.interior_ambient_color]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2450
+#: doc/classes/RenderingServer.xml:2502
msgid ""
"Sets the energy multiplier for this reflection probes ambient light "
"contribution when set to interior mode. Equivalent to [member "
"ReflectionProbe.interior_ambient_energy]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2461
+#: doc/classes/RenderingServer.xml:2513
msgid ""
"Sets the contribution value for how much the reflection affects the ambient "
"light for this reflection probe when set to interior mode. Useful so that "
@@ -42100,25 +42218,25 @@ msgid ""
"ReflectionProbe.interior_ambient_contrib]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2472
+#: doc/classes/RenderingServer.xml:2524
msgid ""
"Sets the max distance away from the probe an object can be before it is "
"culled. Equivalent to [member ReflectionProbe.max_distance]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2483
+#: doc/classes/RenderingServer.xml:2535
msgid ""
"Sets the origin offset to be used when this reflection probe is in box "
"project mode. Equivalent to [member ReflectionProbe.origin_offset]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2494
+#: doc/classes/RenderingServer.xml:2546
msgid ""
"Sets how often the reflection probe updates. Can either be once or every "
"frame. See [enum ReflectionProbeUpdateMode] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:2507
+#: doc/classes/RenderingServer.xml:2559
msgid ""
"Schedules a callback to the corresponding named [code]method[/code] on "
"[code]where[/code] after a frame has been drawn.\n"
@@ -42126,7 +42244,7 @@ msgid ""
"[code]userdata[/code]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2515
+#: doc/classes/RenderingServer.xml:2567
msgid ""
"Creates a scenario and adds it to the RenderingServer. It can be accessed "
"with the RID that is returned. This RID will be used in all "
@@ -42136,24 +42254,24 @@ msgid ""
"The scenario is the 3D world that all the visual instances exist in."
msgstr ""
-#: doc/classes/RenderingServer.xml:2528
+#: doc/classes/RenderingServer.xml:2580
msgid ""
"Sets the [enum ScenarioDebugMode] for this scenario. See [enum "
"ScenarioDebugMode] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:2539
+#: doc/classes/RenderingServer.xml:2591
msgid "Sets the environment that will be used with this scenario."
msgstr ""
-#: doc/classes/RenderingServer.xml:2550
+#: doc/classes/RenderingServer.xml:2602
msgid ""
"Sets the fallback environment to be used by this scenario. The fallback "
"environment is used if no environment is set. Internally, this is used by "
"the editor to provide a default environment."
msgstr ""
-#: doc/classes/RenderingServer.xml:2565
+#: doc/classes/RenderingServer.xml:2617
msgid ""
"Sets a boot image. The color defines the background color. If [code]scale[/"
"code] is [code]true[/code], the image will be scaled to fit the screen size. "
@@ -42162,19 +42280,19 @@ msgid ""
"the image will be scaled with nearest-neighbor interpolation."
msgstr ""
-#: doc/classes/RenderingServer.xml:2574
+#: doc/classes/RenderingServer.xml:2626
msgid ""
"If [code]true[/code], the engine will generate wireframes for use with the "
"wireframe debug mode."
msgstr ""
-#: doc/classes/RenderingServer.xml:2583
+#: doc/classes/RenderingServer.xml:2635
msgid ""
"Sets the default clear color which is used when a specific clear color has "
"not been selected."
msgstr ""
-#: doc/classes/RenderingServer.xml:2590
+#: doc/classes/RenderingServer.xml:2642
msgid ""
"Creates an empty shader and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -42183,47 +42301,47 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:2600
+#: doc/classes/RenderingServer.xml:2652
msgid "Returns a shader's code."
msgstr ""
-#: doc/classes/RenderingServer.xml:2611
+#: doc/classes/RenderingServer.xml:2663
msgid "Returns a default texture from a shader searched by name."
msgstr ""
-#: doc/classes/RenderingServer.xml:2630
+#: doc/classes/RenderingServer.xml:2682
msgid "Returns the parameters of a shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:2641
+#: doc/classes/RenderingServer.xml:2693
msgid "Sets a shader's code."
msgstr ""
-#: doc/classes/RenderingServer.xml:2654
+#: doc/classes/RenderingServer.xml:2706
msgid "Sets a shader's default texture. Overwrites the texture given by name."
msgstr ""
-#: doc/classes/RenderingServer.xml:2667
+#: doc/classes/RenderingServer.xml:2719
msgid "Allocates the GPU buffers for this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2678
+#: doc/classes/RenderingServer.xml:2730
msgid "Returns the [Transform] set for a specific bone of this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2689
+#: doc/classes/RenderingServer.xml:2741
msgid "Returns the [Transform2D] set for a specific bone of this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2702
+#: doc/classes/RenderingServer.xml:2754
msgid "Sets the [Transform] for a specific bone of this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2715
+#: doc/classes/RenderingServer.xml:2767
msgid "Sets the [Transform2D] for a specific bone of this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2722
+#: doc/classes/RenderingServer.xml:2774
msgid ""
"Creates a skeleton and adds it to the RenderingServer. It can be accessed "
"with the RID that is returned. This RID will be used in all "
@@ -42232,11 +42350,11 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:2732
+#: doc/classes/RenderingServer.xml:2784
msgid "Returns the number of bones allocated for this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2739
+#: doc/classes/RenderingServer.xml:2791
msgid ""
"Creates an empty sky and adds it to the RenderingServer. It can be accessed "
"with the RID that is returned. This RID will be used in all [code]sky_*[/"
@@ -42245,13 +42363,13 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:2751
+#: doc/classes/RenderingServer.xml:2803
msgid ""
"Sets the material that the sky uses to render the background and reflection "
"maps."
msgstr ""
-#: doc/classes/RenderingServer.xml:2758
+#: doc/classes/RenderingServer.xml:2810
msgid ""
"Creates a spot light and adds it to the RenderingServer. It can be accessed "
"with the RID that is returned. This RID can be used in most [code]light_*[/"
@@ -42262,15 +42380,15 @@ msgid ""
"instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:2787
+#: doc/classes/RenderingServer.xml:2839
msgid "Sets a viewport's camera."
msgstr ""
-#: doc/classes/RenderingServer.xml:2798
+#: doc/classes/RenderingServer.xml:2850
msgid "Sets a viewport's canvas."
msgstr ""
-#: doc/classes/RenderingServer.xml:2811
+#: doc/classes/RenderingServer.xml:2863
msgid ""
"Copies the viewport to a region of the screen specified by [code]rect[/"
"code]. If [method viewport_set_render_direct_to_screen] is [code]true[/"
@@ -42292,7 +42410,7 @@ msgid ""
"viewport_set_render_direct_to_screen]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2825
+#: doc/classes/RenderingServer.xml:2877
msgid ""
"Creates an empty viewport and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -42301,72 +42419,72 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:2837
+#: doc/classes/RenderingServer.xml:2889
msgid ""
"Returns a viewport's render information. For options, see the [enum "
"ViewportRenderInfo] constants."
msgstr ""
-#: doc/classes/RenderingServer.xml:2846
+#: doc/classes/RenderingServer.xml:2898
msgid "Returns the viewport's last rendered frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:2857
+#: doc/classes/RenderingServer.xml:2909
msgid "Detaches a viewport from a canvas and vice versa."
msgstr ""
-#: doc/classes/RenderingServer.xml:2868
+#: doc/classes/RenderingServer.xml:2920
msgid "If [code]true[/code], sets the viewport active, else sets it inactive."
msgstr ""
-#: doc/classes/RenderingServer.xml:2883
+#: doc/classes/RenderingServer.xml:2935
msgid ""
"Sets the stacking order for a viewport's canvas.\n"
"[code]layer[/code] is the actual canvas layer, while [code]sublayer[/code] "
"specifies the stacking order of the canvas among those in the same layer."
msgstr ""
-#: doc/classes/RenderingServer.xml:2897
+#: doc/classes/RenderingServer.xml:2949
msgid "Sets the transformation of a viewport's canvas."
msgstr ""
-#: doc/classes/RenderingServer.xml:2908
+#: doc/classes/RenderingServer.xml:2960
msgid ""
"Sets the clear mode of a viewport. See [enum ViewportClearMode] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:2919
+#: doc/classes/RenderingServer.xml:2971
msgid ""
"Sets the debug draw mode of a viewport. See [enum ViewportDebugDraw] for "
"options."
msgstr ""
-#: doc/classes/RenderingServer.xml:2930
+#: doc/classes/RenderingServer.xml:2982
msgid ""
"If [code]true[/code], rendering of a viewport's environment is disabled."
msgstr ""
-#: doc/classes/RenderingServer.xml:2941
+#: doc/classes/RenderingServer.xml:2993
msgid "Sets the viewport's global transformation matrix."
msgstr ""
-#: doc/classes/RenderingServer.xml:2952
+#: doc/classes/RenderingServer.xml:3004
msgid "If [code]true[/code], the viewport's canvas is not rendered."
msgstr ""
-#: doc/classes/RenderingServer.xml:2963
+#: doc/classes/RenderingServer.xml:3015
msgid "Currently unimplemented in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:2974
+#: doc/classes/RenderingServer.xml:3026
msgid "Sets the anti-aliasing mode. See [enum ViewportMSAA] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:2985
+#: doc/classes/RenderingServer.xml:3037
msgid "Sets the viewport's parent to another viewport."
msgstr ""
-#: doc/classes/RenderingServer.xml:2996
+#: doc/classes/RenderingServer.xml:3048
msgid ""
"If [code]true[/code], render the contents of the viewport directly to "
"screen. This allows a low-level optimization where you can skip drawing a "
@@ -42382,708 +42500,864 @@ msgid ""
"significantly larger than the window size."
msgstr ""
-#: doc/classes/RenderingServer.xml:3007
+#: doc/classes/RenderingServer.xml:3059
msgid ""
"Sets a viewport's scenario.\n"
"The scenario contains information about the [enum ScenarioDebugMode], "
"environment information, reflection atlas etc."
msgstr ""
-#: doc/classes/RenderingServer.xml:3021
+#: doc/classes/RenderingServer.xml:3073
msgid "Sets the shadow atlas quadrant's subdivision."
msgstr ""
-#: doc/classes/RenderingServer.xml:3032
+#: doc/classes/RenderingServer.xml:3084
msgid ""
"Sets the size of the shadow atlas's images (used for omni and spot lights). "
"The value will be rounded up to the nearest power of 2."
msgstr ""
-#: doc/classes/RenderingServer.xml:3045
+#: doc/classes/RenderingServer.xml:3097
msgid "Sets the viewport's width and height."
msgstr ""
-#: doc/classes/RenderingServer.xml:3056
+#: doc/classes/RenderingServer.xml:3108
msgid ""
"If [code]true[/code], the viewport renders its background as transparent."
msgstr ""
-#: doc/classes/RenderingServer.xml:3067
+#: doc/classes/RenderingServer.xml:3119
msgid ""
"Sets when the viewport should be updated. See [enum ViewportUpdateMode] "
"constants for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:3078
+#: doc/classes/RenderingServer.xml:3130
msgid ""
"If [code]true[/code], the viewport uses augmented or virtual reality "
-"technologies. See [ARVRInterface]."
+"technologies. See [XRInterface]."
msgstr ""
-#: doc/classes/RenderingServer.xml:3085
+#: doc/classes/RenderingServer.xml:3137
msgid ""
"Emitted at the end of the frame, after the RenderingServer has finished "
"updating all the Viewports."
msgstr ""
-#: doc/classes/RenderingServer.xml:3090
+#: doc/classes/RenderingServer.xml:3142
msgid ""
"Emitted at the beginning of the frame, before the RenderingServer updates "
"all the Viewports."
msgstr ""
-#: doc/classes/RenderingServer.xml:3096
+#: doc/classes/RenderingServer.xml:3148
msgid "Marks an error that shows that the index array is empty."
msgstr ""
-#: doc/classes/RenderingServer.xml:3099
+#: doc/classes/RenderingServer.xml:3151
msgid "Number of weights/bones per vertex."
msgstr ""
-#: doc/classes/RenderingServer.xml:3102
+#: doc/classes/RenderingServer.xml:3154
msgid "The minimum Z-layer for canvas items."
msgstr ""
-#: doc/classes/RenderingServer.xml:3105
+#: doc/classes/RenderingServer.xml:3157
msgid "The maximum Z-layer for canvas items."
msgstr ""
-#: doc/classes/RenderingServer.xml:3108
+#: doc/classes/RenderingServer.xml:3160
msgid ""
"Max number of glow levels that can be used with glow post-process effect."
msgstr ""
-#: doc/classes/RenderingServer.xml:3111
+#: doc/classes/RenderingServer.xml:3163
msgid "Unused enum in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:3114
-msgid "The minimum renderpriority of all materials."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3117
-msgid "The maximum renderpriority of all materials."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3138
+#: doc/classes/RenderingServer.xml:3184
msgid "Shader is a 3D shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:3141
+#: doc/classes/RenderingServer.xml:3187
msgid "Shader is a 2D shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:3144
+#: doc/classes/RenderingServer.xml:3190
msgid "Shader is a particle shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:3147
+#: doc/classes/RenderingServer.xml:3193
msgid "Shader is a sky shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:3150
+#: doc/classes/RenderingServer.xml:3196
msgid "Represents the size of the [enum ShaderMode] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3153
+#: doc/classes/RenderingServer.xml:3199
+msgid "The minimum renderpriority of all materials."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3202
+msgid "The maximum renderpriority of all materials."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3205
msgid "Array is a vertex array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3156
+#: doc/classes/RenderingServer.xml:3208
msgid "Array is a normal array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3159
+#: doc/classes/RenderingServer.xml:3211
msgid "Array is a tangent array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3162
+#: doc/classes/RenderingServer.xml:3214
msgid "Array is a color array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3165
+#: doc/classes/RenderingServer.xml:3217
msgid "Array is an UV coordinates array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3168
+#: doc/classes/RenderingServer.xml:3220
msgid "Array is an UV coordinates array for the second UV coordinates."
msgstr ""
-#: doc/classes/RenderingServer.xml:3171
+#: doc/classes/RenderingServer.xml:3223
msgid "Array contains bone information."
msgstr ""
-#: doc/classes/RenderingServer.xml:3174
+#: doc/classes/RenderingServer.xml:3226
msgid "Array is weight information."
msgstr ""
-#: doc/classes/RenderingServer.xml:3177
+#: doc/classes/RenderingServer.xml:3229
msgid "Array is index array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3183
+#: doc/classes/RenderingServer.xml:3235
msgid "Flag used to mark a vertex array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3186
+#: doc/classes/RenderingServer.xml:3238
msgid "Flag used to mark a normal array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3189
+#: doc/classes/RenderingServer.xml:3241
msgid "Flag used to mark a tangent array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3192
+#: doc/classes/RenderingServer.xml:3244
msgid "Flag used to mark a color array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3195
+#: doc/classes/RenderingServer.xml:3247
msgid "Flag used to mark an UV coordinates array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3198
+#: doc/classes/RenderingServer.xml:3250
msgid ""
"Flag used to mark an UV coordinates array for the second UV coordinates."
msgstr ""
-#: doc/classes/RenderingServer.xml:3201
+#: doc/classes/RenderingServer.xml:3253
msgid "Flag used to mark a bone information array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3204
+#: doc/classes/RenderingServer.xml:3256
msgid "Flag used to mark a weights array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3207
+#: doc/classes/RenderingServer.xml:3259
msgid "Flag used to mark an index array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3236
+#: doc/classes/RenderingServer.xml:3288
msgid "Primitive to draw consists of points."
msgstr ""
-#: doc/classes/RenderingServer.xml:3239
+#: doc/classes/RenderingServer.xml:3291
msgid "Primitive to draw consists of lines."
msgstr ""
-#: doc/classes/RenderingServer.xml:3242
+#: doc/classes/RenderingServer.xml:3294
msgid "Primitive to draw consists of a line strip from start to end."
msgstr ""
-#: doc/classes/RenderingServer.xml:3245
+#: doc/classes/RenderingServer.xml:3297
msgid "Primitive to draw consists of triangles."
msgstr ""
-#: doc/classes/RenderingServer.xml:3248
+#: doc/classes/RenderingServer.xml:3300
msgid ""
"Primitive to draw consists of a triangle strip (the last 3 vertices are "
"always combined to make a triangle)."
msgstr ""
-#: doc/classes/RenderingServer.xml:3251
+#: doc/classes/RenderingServer.xml:3303
msgid "Represents the size of the [enum PrimitiveType] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3260
+#: doc/classes/RenderingServer.xml:3312
msgid "Use [Transform2D] to store MultiMesh transform."
msgstr ""
-#: doc/classes/RenderingServer.xml:3263
+#: doc/classes/RenderingServer.xml:3315
msgid "Use [Transform] to store MultiMesh transform."
msgstr ""
-#: doc/classes/RenderingServer.xml:3266
+#: doc/classes/RenderingServer.xml:3318
msgid "Is a directional (sun) light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3269
+#: doc/classes/RenderingServer.xml:3321
msgid "Is an omni light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3272
+#: doc/classes/RenderingServer.xml:3324
msgid "Is a spot light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3275
+#: doc/classes/RenderingServer.xml:3327
msgid "The light's energy."
msgstr ""
-#: doc/classes/RenderingServer.xml:3280
+#: doc/classes/RenderingServer.xml:3332
msgid "The light's influence on specularity."
msgstr ""
-#: doc/classes/RenderingServer.xml:3283
+#: doc/classes/RenderingServer.xml:3335
msgid "The light's range."
msgstr ""
-#: doc/classes/RenderingServer.xml:3286
+#: doc/classes/RenderingServer.xml:3338
+msgid ""
+"The size of the light when using spot light or omni light. The angular size "
+"of the light when using directional light."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3341
msgid "The light's attenuation."
msgstr ""
-#: doc/classes/RenderingServer.xml:3289
+#: doc/classes/RenderingServer.xml:3344
msgid "The spotlight's angle."
msgstr ""
-#: doc/classes/RenderingServer.xml:3292
+#: doc/classes/RenderingServer.xml:3347
msgid "The spotlight's attenuation."
msgstr ""
-#: doc/classes/RenderingServer.xml:3295
-msgid "Scales the shadow color."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3298
+#: doc/classes/RenderingServer.xml:3350
msgid "Max distance that shadows will be rendered."
msgstr ""
-#: doc/classes/RenderingServer.xml:3301
+#: doc/classes/RenderingServer.xml:3353
msgid "Proportion of shadow atlas occupied by the first split."
msgstr ""
-#: doc/classes/RenderingServer.xml:3304
+#: doc/classes/RenderingServer.xml:3356
msgid "Proportion of shadow atlas occupied by the second split."
msgstr ""
-#: doc/classes/RenderingServer.xml:3307
+#: doc/classes/RenderingServer.xml:3359
msgid ""
"Proportion of shadow atlas occupied by the third split. The fourth split "
"occupies the rest."
msgstr ""
-#: doc/classes/RenderingServer.xml:3312
+#: doc/classes/RenderingServer.xml:3362
+msgid ""
+"Proportion of shadow max distance where the shadow will start to fade out."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3365
msgid ""
"Normal bias used to offset shadow lookup by object normal. Can be used to "
"fix self-shadowing artifacts."
msgstr ""
-#: doc/classes/RenderingServer.xml:3315
+#: doc/classes/RenderingServer.xml:3368
msgid "Bias the shadow lookup to fix self-shadowing artifacts."
msgstr ""
-#: doc/classes/RenderingServer.xml:3318
-msgid ""
-"Increases bias on further splits to fix self-shadowing that only occurs far "
-"away from the camera."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3321
+#: doc/classes/RenderingServer.xml:3379
msgid "Represents the size of the [enum LightParam] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3324
+#: doc/classes/RenderingServer.xml:3382
msgid "Use a dual paraboloid shadow map for omni lights."
msgstr ""
-#: doc/classes/RenderingServer.xml:3327
+#: doc/classes/RenderingServer.xml:3385
msgid ""
"Use a cubemap shadow map for omni lights. Slower but better quality than "
"dual paraboloid."
msgstr ""
-#: doc/classes/RenderingServer.xml:3330
+#: doc/classes/RenderingServer.xml:3388
msgid "Use orthogonal shadow projection for directional light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3333
+#: doc/classes/RenderingServer.xml:3391
msgid "Use 2 splits for shadow projection when using directional light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3336
+#: doc/classes/RenderingServer.xml:3394
msgid "Use 4 splits for shadow projection when using directional light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3339
+#: doc/classes/RenderingServer.xml:3397
msgid ""
"Keeps shadows stable as camera moves but has lower effective resolution."
msgstr ""
-#: doc/classes/RenderingServer.xml:3342
+#: doc/classes/RenderingServer.xml:3400
msgid ""
"Optimize use of shadow maps, increasing the effective resolution. But may "
"result in shadows moving or flickering slightly."
msgstr ""
-#: doc/classes/RenderingServer.xml:3345
+#: doc/classes/RenderingServer.xml:3403
msgid "Reflection probe will update reflections once and then stop."
msgstr ""
-#: doc/classes/RenderingServer.xml:3348
+#: doc/classes/RenderingServer.xml:3406
msgid ""
"Reflection probe will update each frame. This mode is necessary to capture "
"moving objects."
msgstr ""
-#: doc/classes/RenderingServer.xml:3351
+#: doc/classes/RenderingServer.xml:3419
msgid "Draw particles in the order that they appear in the particles array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3354
+#: doc/classes/RenderingServer.xml:3422
msgid "Sort particles based on their lifetime."
msgstr ""
-#: doc/classes/RenderingServer.xml:3357
+#: doc/classes/RenderingServer.xml:3425
msgid "Sort particles based on their distance to the camera."
msgstr ""
-#: doc/classes/RenderingServer.xml:3360
+#: doc/classes/RenderingServer.xml:3428
msgid "Do not update the viewport."
msgstr ""
-#: doc/classes/RenderingServer.xml:3363
+#: doc/classes/RenderingServer.xml:3431
msgid "Update the viewport once then set to disabled."
msgstr ""
-#: doc/classes/RenderingServer.xml:3366
+#: doc/classes/RenderingServer.xml:3434
msgid "Update the viewport whenever it is visible."
msgstr ""
-#: doc/classes/RenderingServer.xml:3371
+#: doc/classes/RenderingServer.xml:3439
msgid "Always update the viewport."
msgstr ""
-#: doc/classes/RenderingServer.xml:3374
+#: doc/classes/RenderingServer.xml:3442
msgid "The viewport is always cleared before drawing."
msgstr ""
-#: doc/classes/RenderingServer.xml:3377
+#: doc/classes/RenderingServer.xml:3445
msgid "The viewport is never cleared before drawing."
msgstr ""
-#: doc/classes/RenderingServer.xml:3380
+#: doc/classes/RenderingServer.xml:3448
msgid ""
"The viewport is cleared once, then the clear mode is set to [constant "
"VIEWPORT_CLEAR_NEVER]."
msgstr ""
-#: doc/classes/RenderingServer.xml:3383
+#: doc/classes/RenderingServer.xml:3451
msgid "Multisample antialiasing is disabled."
msgstr ""
-#: doc/classes/RenderingServer.xml:3386
-msgid "Multisample antialiasing is set to 2×."
+#: doc/classes/RenderingServer.xml:3454
+msgid "Multisample antialiasing uses 2 samples per pixel."
msgstr ""
-#: doc/classes/RenderingServer.xml:3389
-msgid "Multisample antialiasing is set to 4×."
+#: doc/classes/RenderingServer.xml:3457
+msgid "Multisample antialiasing uses 4 samples per pixel."
msgstr ""
-#: doc/classes/RenderingServer.xml:3392
-msgid "Multisample antialiasing is set to 8×."
+#: doc/classes/RenderingServer.xml:3460
+msgid "Multisample antialiasing uses 8 samples per pixel."
msgstr ""
-#: doc/classes/RenderingServer.xml:3395
-msgid "Multisample antialiasing is set to 16×."
+#: doc/classes/RenderingServer.xml:3463
+msgid "Multisample antialiasing uses 16 samples per pixel."
msgstr ""
-#: doc/classes/RenderingServer.xml:3398
-msgid ""
-"Multisample antialiasing is set to 2× on external texture. Special mode for "
-"GLES2 Android VR (Oculus Quest and Go)."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3401
-msgid ""
-"Multisample antialiasing is set to 4× on external texture. Special mode for "
-"GLES2 Android VR (Oculus Quest and Go)."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3404
+#: doc/classes/RenderingServer.xml:3474
msgid "Number of objects drawn in a single frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3407
+#: doc/classes/RenderingServer.xml:3477
msgid "Number of vertices drawn in a single frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3410
+#: doc/classes/RenderingServer.xml:3480
msgid "Number of material changes during this frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3413
+#: doc/classes/RenderingServer.xml:3483
msgid "Number of shader changes during this frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3416
+#: doc/classes/RenderingServer.xml:3486
msgid "Number of surface changes during this frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3419
+#: doc/classes/RenderingServer.xml:3489
msgid "Number of draw calls during this frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3422
+#: doc/classes/RenderingServer.xml:3492
msgid "Represents the size of the [enum ViewportRenderInfo] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3425
+#: doc/classes/RenderingServer.xml:3495
msgid "Debug draw is disabled. Default setting."
msgstr ""
-#: doc/classes/RenderingServer.xml:3428
-msgid "Debug draw sets objects to unshaded."
+#: doc/classes/RenderingServer.xml:3498 doc/classes/Viewport.xml:348
+msgid "Objects are displayed without light information."
msgstr ""
-#: doc/classes/RenderingServer.xml:3433
-msgid "Overwrites clear color to [code](0,0,0,0)[/code]."
+#: doc/classes/RenderingServer.xml:3501
+msgid "Objects are displayed with only light information."
msgstr ""
-#: doc/classes/RenderingServer.xml:3436
+#: doc/classes/RenderingServer.xml:3504 doc/classes/Viewport.xml:353
+msgid ""
+"Objects are displayed semi-transparent with additive blending so you can see "
+"where they are drawing over top of one another. A higher overdraw means you "
+"are wasting performance on drawing pixels that are being hidden behind "
+"others."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3507
msgid "Debug draw draws objects in wireframe."
msgstr ""
-#: doc/classes/RenderingServer.xml:3461
+#: doc/classes/RenderingServer.xml:3510
+msgid ""
+"Normal buffer is drawn instead of regular scene so you can see the per-pixel "
+"normals that will be used by post-processing effects."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3513 doc/classes/Viewport.xml:361
+msgid "Objects are displayed with only the albedo value from [GIProbe]s."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3516 doc/classes/Viewport.xml:364
+msgid "Objects are displayed with only the lighting value from [GIProbe]s."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3519 doc/classes/Viewport.xml:367
+msgid "Objects are displayed with only the emission color from [GIProbe]s."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3522 doc/classes/Viewport.xml:370
+msgid ""
+"Draws the shadow atlas that stores shadows from [OmniLight3D]s and "
+"[SpotLight3D]s in the upper left quadrant of the [Viewport]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3525 doc/classes/Viewport.xml:373
+msgid ""
+"Draws the shadow atlas that stores shadows from [DirectionalLight3D]s in the "
+"upper left quadrant of the [Viewport]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3530
+msgid ""
+"Draws the screen space ambient occlusion texture instead of the scene so "
+"that you can clearly see how it is affecting objects. In order for this "
+"display mode to work, you must have [member Environment.ssao_enabled] set in "
+"your [WorldEnvironment]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3533 doc/classes/Viewport.xml:381
+msgid ""
+"Draws the roughness limiter post process over the Viewport so you can see "
+"where it has an effect. It must be enabled in [member ProjectSettings."
+"rendering/quality/screen_filters/screen_space_roughness_limiter] to work."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3536
+msgid ""
+"Colors each PSSM split for the [DirectionalLight3D]s in the scene a "
+"different color so you can see where the splits are. In order they will be "
+"colored red, green, blue, yellow."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3541
+msgid ""
+"Uses high quality importance sampling to process the radiance map. In "
+"general, this results in much higher quality than [constant Sky."
+"PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be "
+"used if you plan on changing the sky at runtime. If you are finding that the "
+"reflection is not blurry enough and is showing sparkles or fireflies, try "
+"increasing [member ProjectSettings.rendering/quality/reflections/"
+"ggx_samples]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3544
+msgid ""
+"Uses the fast filtering algorithm to process the radiance map. In general "
+"this results in lower quality, but substantially faster run times.\n"
+"[b]Note:[/b] The fast filtering algorithm is limited to 256x256 cubemaps, so "
+"[member Sky.radiance_size] must be set to [constant Sky.RADIANCE_SIZE_256]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3548
msgid "Use the clear color as background."
msgstr ""
-#: doc/classes/RenderingServer.xml:3464
+#: doc/classes/RenderingServer.xml:3551
msgid "Use a specified color as the background."
msgstr ""
-#: doc/classes/RenderingServer.xml:3467
+#: doc/classes/RenderingServer.xml:3554
msgid "Use a sky resource for the background."
msgstr ""
-#: doc/classes/RenderingServer.xml:3470
+#: doc/classes/RenderingServer.xml:3557
msgid ""
"Use a specified canvas layer as the background. This can be useful for "
"instantiating a 2D scene in a 3D world."
msgstr ""
-#: doc/classes/RenderingServer.xml:3473
+#: doc/classes/RenderingServer.xml:3560
msgid ""
"Do not clear the background, use whatever was rendered last frame as the "
"background."
msgstr ""
-#: doc/classes/RenderingServer.xml:3479
+#: doc/classes/RenderingServer.xml:3566
msgid "Represents the size of the [enum EnvironmentBG] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3506
+#: doc/classes/RenderingServer.xml:3605
msgid "Output color as they came in."
msgstr ""
-#: doc/classes/RenderingServer.xml:3509
+#: doc/classes/RenderingServer.xml:3608
msgid "Use the Reinhard tonemapper."
msgstr ""
-#: doc/classes/RenderingServer.xml:3512
+#: doc/classes/RenderingServer.xml:3611
msgid "Use the filmic tonemapper."
msgstr ""
-#: doc/classes/RenderingServer.xml:3515
+#: doc/classes/RenderingServer.xml:3614
msgid "Use the ACES tonemapper."
msgstr ""
-#: doc/classes/RenderingServer.xml:3518
+#: doc/classes/RenderingServer.xml:3625
msgid "Disables the blur set for SSAO. Will make SSAO look noisier."
msgstr ""
-#: doc/classes/RenderingServer.xml:3521
+#: doc/classes/RenderingServer.xml:3628
msgid "Perform a 1x1 blur on the SSAO output."
msgstr ""
-#: doc/classes/RenderingServer.xml:3524
+#: doc/classes/RenderingServer.xml:3631
msgid "Performs a 2x2 blur on the SSAO output."
msgstr ""
-#: doc/classes/RenderingServer.xml:3527
+#: doc/classes/RenderingServer.xml:3634
msgid "Performs a 3x3 blur on the SSAO output. Use this for smoothest SSAO."
msgstr ""
-#: doc/classes/RenderingServer.xml:3530
+#: doc/classes/RenderingServer.xml:3637
msgid "Lowest quality of screen space ambient occlusion."
msgstr ""
-#: doc/classes/RenderingServer.xml:3533
+#: doc/classes/RenderingServer.xml:3640
msgid "Medium quality screen space ambient occlusion."
msgstr ""
-#: doc/classes/RenderingServer.xml:3536
+#: doc/classes/RenderingServer.xml:3643
+msgid "High quality screen space ambient occlusion."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3646
msgid "Highest quality screen space ambient occlusion."
msgstr ""
-#: doc/classes/RenderingServer.xml:3555
+#: doc/classes/RenderingServer.xml:3657
+msgid ""
+"Lowest quality DOF blur. This is the fastest setting, but you may be able to "
+"see filtering artifacts."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3660
+msgid "Low quality DOF blur."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3663
+msgid "Medium quality DOF blur."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3666
+msgid ""
+"Highest quality DOF blur. Results in the smoothest looking blur by taking "
+"the most samples, but is also significantly slower."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3669
+msgid ""
+"Calculate the DOF blur using a box filter. The fastest option, but results "
+"in obvious lines in blur pattern."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3672
+msgid "Calculates DOF blur using a hexagon shaped filter."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3675
+msgid ""
+"Calculates DOF blur using a circle shaped filter. Best quality and most "
+"realistic, but slowest. Use only for areas where a lot of performance can be "
+"dedicated to post-processing (e.g. cutscenes)."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3690
msgid "Do not use a debug mode."
msgstr ""
-#: doc/classes/RenderingServer.xml:3558
+#: doc/classes/RenderingServer.xml:3693
msgid "Draw all objects as wireframe models."
msgstr ""
-#: doc/classes/RenderingServer.xml:3561
+#: doc/classes/RenderingServer.xml:3696
msgid ""
"Draw all objects in a way that displays how much overdraw is occurring. "
"Overdraw occurs when a section of pixels is drawn and shaded and then "
"another object covers it up. To optimize a scene, you should reduce overdraw."
msgstr ""
-#: doc/classes/RenderingServer.xml:3564
+#: doc/classes/RenderingServer.xml:3699
msgid ""
"Draw all objects without shading. Equivalent to setting all objects shaders "
"to [code]unshaded[/code]."
msgstr ""
-#: doc/classes/RenderingServer.xml:3567
+#: doc/classes/RenderingServer.xml:3702
msgid "The instance does not have a type."
msgstr ""
-#: doc/classes/RenderingServer.xml:3570
+#: doc/classes/RenderingServer.xml:3705
msgid "The instance is a mesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:3573
+#: doc/classes/RenderingServer.xml:3708
msgid "The instance is a multimesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:3576
+#: doc/classes/RenderingServer.xml:3711
msgid "The instance is an immediate geometry."
msgstr ""
-#: doc/classes/RenderingServer.xml:3579
+#: doc/classes/RenderingServer.xml:3714
msgid "The instance is a particle emitter."
msgstr ""
-#: doc/classes/RenderingServer.xml:3582
+#: doc/classes/RenderingServer.xml:3717
msgid "The instance is a light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3585
+#: doc/classes/RenderingServer.xml:3720
msgid "The instance is a reflection probe."
msgstr ""
-#: doc/classes/RenderingServer.xml:3588
+#: doc/classes/RenderingServer.xml:3723
+msgid "The instance is a decal."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3726
msgid "The instance is a GI probe."
msgstr ""
-#: doc/classes/RenderingServer.xml:3591
+#: doc/classes/RenderingServer.xml:3729
msgid "The instance is a lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:3594
+#: doc/classes/RenderingServer.xml:3732
msgid "Represents the size of the [enum InstanceType] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3597
+#: doc/classes/RenderingServer.xml:3735
msgid ""
"A combination of the flags of geometry instances (mesh, multimesh, immediate "
"and particles)."
msgstr ""
-#: doc/classes/RenderingServer.xml:3600
+#: doc/classes/RenderingServer.xml:3738
msgid "Allows the instance to be used in baked lighting."
msgstr ""
-#: doc/classes/RenderingServer.xml:3605
+#: doc/classes/RenderingServer.xml:3741
+msgid "Allows the instance to be used with dynamic global illumination."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3744
msgid "When set, manually requests to draw geometry on next frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3608
+#: doc/classes/RenderingServer.xml:3747
msgid "Represents the size of the [enum InstanceFlags] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3611
+#: doc/classes/RenderingServer.xml:3750
msgid "Disable shadows from this instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:3614
+#: doc/classes/RenderingServer.xml:3753
msgid "Cast shadows from this instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:3617
+#: doc/classes/RenderingServer.xml:3756
msgid ""
"Disable backface culling when rendering the shadow of the object. This is "
"slightly slower but may result in more correct shadows."
msgstr ""
-#: doc/classes/RenderingServer.xml:3620
+#: doc/classes/RenderingServer.xml:3759
msgid ""
"Only render the shadows from the object. The object itself will not be drawn."
msgstr ""
-#: doc/classes/RenderingServer.xml:3623
+#: doc/classes/RenderingServer.xml:3762
msgid "The nine patch gets stretched where needed."
msgstr ""
-#: doc/classes/RenderingServer.xml:3626
+#: doc/classes/RenderingServer.xml:3765
msgid "The nine patch gets filled with tiles where needed."
msgstr ""
-#: doc/classes/RenderingServer.xml:3629
+#: doc/classes/RenderingServer.xml:3768
msgid ""
"The nine patch gets filled with tiles where needed and stretches them a bit "
"if needed."
msgstr ""
-#: doc/classes/RenderingServer.xml:3658
+#: doc/classes/RenderingServer.xml:3771
+msgid "Uses the default filter mode for this [Viewport]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3783 doc/classes/Viewport.xml:399
+msgid ""
+"The texture filter blends between the nearest 4 pixels and between the "
+"nearest 2 mipmaps."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3792
+msgid "Max value for [enum CanvasItemTextureFilter] enum."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3795
+msgid "Uses the default repeat mode for this [Viewport]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3798 doc/classes/Viewport.xml:405
+msgid ""
+"Disables textures repeating. Instead, when reading UVs outside the 0-1 "
+"range, the value will be clamped to the edge of the texture, resulting in a "
+"stretched out look at the borders of the texture."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3804 doc/classes/Viewport.xml:411
+msgid ""
+"Flip the texture when repeating so that the edge lines up instead of "
+"abruptly changing."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3807
+msgid "Max value for [enum CanvasItemTextureRepeat] enum."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3810
msgid "Adds light color additive to the canvas."
msgstr ""
-#: doc/classes/RenderingServer.xml:3661
+#: doc/classes/RenderingServer.xml:3813
msgid "Adds light color subtractive to the canvas."
msgstr ""
-#: doc/classes/RenderingServer.xml:3664
+#: doc/classes/RenderingServer.xml:3816
msgid "The light adds color depending on transparency."
msgstr ""
-#: doc/classes/RenderingServer.xml:3667
+#: doc/classes/RenderingServer.xml:3819
msgid "The light adds color depending on mask."
msgstr ""
-#: doc/classes/RenderingServer.xml:3670
+#: doc/classes/RenderingServer.xml:3822
msgid "Do not apply a filter to canvas light shadows."
msgstr ""
-#: doc/classes/RenderingServer.xml:3673
+#: doc/classes/RenderingServer.xml:3825
msgid "Use PCF5 filtering to filter canvas light shadows."
msgstr ""
-#: doc/classes/RenderingServer.xml:3676
+#: doc/classes/RenderingServer.xml:3828
msgid "Use PCF13 filtering to filter canvas light shadows."
msgstr ""
-#: doc/classes/RenderingServer.xml:3681
+#: doc/classes/RenderingServer.xml:3831
+msgid "Max value of the [enum CanvasLightShadowFilter] enum."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3834
msgid "Culling of the canvas occluder is disabled."
msgstr ""
-#: doc/classes/RenderingServer.xml:3684
+#: doc/classes/RenderingServer.xml:3837
msgid "Culling of the canvas occluder is clockwise."
msgstr ""
-#: doc/classes/RenderingServer.xml:3687
+#: doc/classes/RenderingServer.xml:3840
msgid "Culling of the canvas occluder is counterclockwise."
msgstr ""
-#: doc/classes/RenderingServer.xml:3690
+#: doc/classes/RenderingServer.xml:3901
msgid "The amount of objects in the frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3693
+#: doc/classes/RenderingServer.xml:3904
msgid "The amount of vertices in the frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3696
+#: doc/classes/RenderingServer.xml:3907
msgid "The amount of modified materials in the frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3699
+#: doc/classes/RenderingServer.xml:3910
msgid "The amount of shader rebinds in the frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3702
+#: doc/classes/RenderingServer.xml:3913
msgid "The amount of surface changes in the frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3705
+#: doc/classes/RenderingServer.xml:3916
msgid "The amount of draw calls in frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3720
+#: doc/classes/RenderingServer.xml:3931
msgid "Hardware supports shaders. This enum is currently unused in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:3723
+#: doc/classes/RenderingServer.xml:3934
msgid ""
"Hardware supports multithreading. This enum is currently unused in Godot 3.x."
msgstr ""
@@ -44081,15 +44355,11 @@ msgid ""
"Physics > 2d[/b]."
msgstr ""
-#: doc/classes/RigidBody2D.xml:158 doc/classes/RigidBody3D.xml:174
-msgid "The body's mass."
-msgstr ""
-
#: doc/classes/RigidBody2D.xml:161
msgid "The body's mode. See [enum Mode] for possible values."
msgstr ""
-#: doc/classes/RigidBody2D.xml:164 doc/classes/RigidBody3D.xml:180
+#: doc/classes/RigidBody2D.xml:164 doc/classes/RigidBody3D.xml:181
#: doc/classes/StaticBody2D.xml:22 doc/classes/StaticBody3D.xml:22
msgid ""
"The physics material override for the body.\n"
@@ -44218,22 +44488,32 @@ msgid ""
"for a body."
msgstr ""
+#: doc/classes/RigidBody3D.xml:31
+msgid ""
+"Adds a constant directional force (i.e. acceleration) without affecting "
+"rotation.\n"
+"This is equivalent to [code]add_force(force, Vector3(0,0,0))[/code]."
+msgstr ""
+
#: doc/classes/RigidBody3D.xml:43
-msgid "Adds a constant force (i.e. acceleration)."
+msgid ""
+"Adds a constant directional force (i.e. acceleration).\n"
+"The position uses the rotation of the global coordinate system, but is "
+"centered at the object's origin."
msgstr ""
-#: doc/classes/RigidBody3D.xml:52
+#: doc/classes/RigidBody3D.xml:53
msgid ""
"Adds a constant rotational force (i.e. a motor) without affecting position."
msgstr ""
-#: doc/classes/RigidBody3D.xml:61
+#: doc/classes/RigidBody3D.xml:62
msgid ""
"Applies a directional impulse without affecting rotation.\n"
"This is equivalent to [code]apply_impulse(Vector3(0,0,0), impulse)[/code]."
msgstr ""
-#: doc/classes/RigidBody3D.xml:73
+#: doc/classes/RigidBody3D.xml:74
msgid ""
"Applies a positioned impulse to the body. An impulse is time independent! "
"Applying an impulse every frame would result in a framerate-dependent force. "
@@ -44242,19 +44522,19 @@ msgid ""
"at the object's origin."
msgstr ""
-#: doc/classes/RigidBody3D.xml:82
+#: doc/classes/RigidBody3D.xml:83
msgid ""
"Applies a torque impulse which will be affected by the body mass and shape. "
"This will rotate the body around the [code]impulse[/code] vector passed."
msgstr ""
-#: doc/classes/RigidBody3D.xml:91
+#: doc/classes/RigidBody3D.xml:92
msgid ""
"Returns [code]true[/code] if the specified linear or rotational axis is "
"locked."
msgstr ""
-#: doc/classes/RigidBody3D.xml:98
+#: doc/classes/RigidBody3D.xml:99
msgid ""
"Returns a list of the bodies colliding with this one. By default, number of "
"max contacts reported is at 0, see the [member contacts_reported] property "
@@ -44264,64 +44544,32 @@ msgid ""
"physics step. Consider using signals instead."
msgstr ""
-#: doc/classes/RigidBody3D.xml:110
+#: doc/classes/RigidBody3D.xml:111
msgid "Locks the specified linear or rotational axis."
msgstr ""
-#: doc/classes/RigidBody3D.xml:125
+#: doc/classes/RigidBody3D.xml:126
msgid "Damps RigidBody3D's rotational forces."
msgstr ""
-#: doc/classes/RigidBody3D.xml:128
+#: doc/classes/RigidBody3D.xml:129
msgid "RigidBody3D's rotational velocity."
msgstr ""
-#: doc/classes/RigidBody3D.xml:131
-msgid "Lock the body's rotation in the X axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:134
-msgid "Lock the body's rotation in the Y axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:137
-msgid "Lock the body's rotation in the Z axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:140
-msgid "Lock the body's movement in the X axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:143
-msgid "Lock the body's movement in the Y axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:146
-msgid "Lock the body's movement in the Z axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:149
-msgid ""
-"If [code]true[/code], the RigidBody3D will not calculate forces and will act "
-"as a static body while there is no movement. It will wake up when forces are "
-"applied through other collisions or when the [code]apply_impulse[/code] "
-"method is used."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:152
+#: doc/classes/RigidBody3D.xml:153
msgid ""
"If [code]true[/code], the RigidBody3D will emit signals when it collides "
"with another RigidBody3D."
msgstr ""
-#: doc/classes/RigidBody3D.xml:155
+#: doc/classes/RigidBody3D.xml:156
msgid ""
"The maximum contacts to report. Bodies can keep a log of the contacts with "
"other bodies, this is enabled by setting the maximum amount of contacts "
"reported to a number greater than 0."
msgstr ""
-#: doc/classes/RigidBody3D.xml:158
+#: doc/classes/RigidBody3D.xml:159
msgid ""
"If [code]true[/code], continuous collision detection is used.\n"
"Continuous collision detection tries to predict where a moving body will "
@@ -44331,7 +44579,7 @@ msgid ""
"faster to compute, but can miss small, fast-moving objects."
msgstr ""
-#: doc/classes/RigidBody3D.xml:162
+#: doc/classes/RigidBody3D.xml:163
msgid ""
"If [code]true[/code], internal force integration will be disabled (like "
"gravity or air friction) for this body. Other than collision response, the "
@@ -44339,7 +44587,7 @@ msgid ""
"function, if defined."
msgstr ""
-#: doc/classes/RigidBody3D.xml:165
+#: doc/classes/RigidBody3D.xml:166
msgid ""
"This is multiplied by the global 3D gravity setting found in [b]Project > "
"Project Settings > Physics > 3d[/b] to produce RigidBody3D's gravity. For "
@@ -44347,14 +44595,14 @@ msgid ""
"and 0.5 will apply half gravity to this object."
msgstr ""
-#: doc/classes/RigidBody3D.xml:168
+#: doc/classes/RigidBody3D.xml:169
msgid ""
"The body's linear damp. Cannot be less than -1.0. If this value is different "
"from -1.0, any linear damp derived from the world or areas will be "
"overridden."
msgstr ""
-#: doc/classes/RigidBody3D.xml:171
+#: doc/classes/RigidBody3D.xml:172
msgid ""
"The body's linear velocity. Can be used sporadically, but [b]don't set this "
"every frame[/b], because physics may run in another thread and runs at a "
@@ -44362,35 +44610,29 @@ msgid ""
"for precise control of the body state."
msgstr ""
-#: doc/classes/RigidBody3D.xml:177
+#: doc/classes/RigidBody3D.xml:178
msgid "The body mode. See [enum Mode] for possible values."
msgstr ""
-#: doc/classes/RigidBody3D.xml:184
+#: doc/classes/RigidBody3D.xml:185
msgid ""
"If [code]true[/code], the body is sleeping and will not calculate forces "
"until woken up by a collision or the [code]apply_impulse[/code] method."
msgstr ""
-#: doc/classes/RigidBody3D.xml:187
-msgid ""
-"The body's weight based on its mass and the global 3D gravity. Global values "
-"are set in [b]Project > Project Settings > Physics > 3d[/b]."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:195
+#: doc/classes/RigidBody3D.xml:196
msgid ""
"Emitted when a body enters into contact with this one. Contact monitor and "
"contacts reported must be enabled for this to work."
msgstr ""
-#: doc/classes/RigidBody3D.xml:202
+#: doc/classes/RigidBody3D.xml:203
msgid ""
"Emitted when a body shape exits contact with this one. Contact monitor and "
"contacts reported must be enabled for this to work."
msgstr ""
-#: doc/classes/RigidBody3D.xml:215
+#: doc/classes/RigidBody3D.xml:216
msgid ""
"Emitted when a body enters into contact with this one. Contact monitor and "
"contacts reported must be enabled for this to work.\n"
@@ -44400,7 +44642,7 @@ msgid ""
"([code]local_shape[/code]) the other body collided with."
msgstr ""
-#: doc/classes/RigidBody3D.xml:229
+#: doc/classes/RigidBody3D.xml:230
msgid ""
"Emitted when a body shape exits contact with this one. Contact monitor and "
"contacts reported must be enabled for this to work.\n"
@@ -44410,30 +44652,30 @@ msgid ""
"([code]local_shape[/code]) the other body stopped colliding with."
msgstr ""
-#: doc/classes/RigidBody3D.xml:235
+#: doc/classes/RigidBody3D.xml:236
msgid ""
"Emitted when the body changes its sleeping state. Either by sleeping or "
"waking up."
msgstr ""
-#: doc/classes/RigidBody3D.xml:241
+#: doc/classes/RigidBody3D.xml:242
msgid ""
"Rigid body mode. This is the \"natural\" state of a rigid body. It is "
"affected by forces, and can move, rotate, and be affected by user code."
msgstr ""
-#: doc/classes/RigidBody3D.xml:244
+#: doc/classes/RigidBody3D.xml:245
msgid ""
"Static mode. The body behaves like a [StaticBody3D], and can only move by "
"user code."
msgstr ""
-#: doc/classes/RigidBody3D.xml:247
+#: doc/classes/RigidBody3D.xml:248
msgid ""
"Character body mode. This behaves like a rigid body, but can not rotate."
msgstr ""
-#: doc/classes/RigidBody3D.xml:250
+#: doc/classes/RigidBody3D.xml:251
msgid ""
"Kinematic body mode. The body behaves like a [KinematicBody3D], and can only "
"move by user code."
@@ -45057,27 +45299,33 @@ msgstr ""
msgid "Godot editor's script editor."
msgstr ""
-#: doc/classes/ScriptEditor.xml:39
+#: doc/classes/ScriptEditor.xml:7
+msgid ""
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_script_editor]."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml:40
msgid "Returns a [Script] that is currently active in editor."
msgstr ""
-#: doc/classes/ScriptEditor.xml:56
+#: doc/classes/ScriptEditor.xml:57
msgid ""
"Returns an array with all [Script] objects which are currently open in "
"editor."
msgstr ""
-#: doc/classes/ScriptEditor.xml:65
+#: doc/classes/ScriptEditor.xml:66
msgid "Goes to the specified line in the current script."
msgstr ""
-#: doc/classes/ScriptEditor.xml:84
+#: doc/classes/ScriptEditor.xml:85
msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
-#: doc/classes/ScriptEditor.xml:91
+#: doc/classes/ScriptEditor.xml:92
msgid ""
"Emitted when editor is about to close the active script. Argument is a "
"[Script] that is going to be closed."
@@ -45139,7 +45387,7 @@ msgid ""
"visible."
msgstr ""
-#: doc/classes/ScrollContainer.xml:37 doc/classes/TextEdit.xml:441
+#: doc/classes/ScrollContainer.xml:37 doc/classes/TextEdit.xml:442
msgid "The current horizontal scroll value."
msgstr ""
@@ -45147,7 +45395,7 @@ msgstr ""
msgid "If [code]true[/code], enables horizontal scrolling."
msgstr ""
-#: doc/classes/ScrollContainer.xml:43 doc/classes/TextEdit.xml:444
+#: doc/classes/ScrollContainer.xml:43 doc/classes/TextEdit.xml:445
msgid "The current vertical scroll value."
msgstr ""
@@ -45677,7 +45925,10 @@ msgid ""
"Uses high quality importance sampling to process the radiance map. In "
"general, this results in much higher quality than [constant "
"PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be "
-"used if you plan on changing the sky at runtime."
+"used if you plan on changing the sky at runtime. If you are finding that the "
+"reflection is not blurry enough and is showing sparkles or fireflies, try "
+"increasing [member ProjectSettings.rendering/quality/reflections/"
+"ggx_samples]."
msgstr ""
#: doc/classes/Sky.xml:55
@@ -47871,65 +48122,65 @@ msgid ""
msgstr ""
#: doc/classes/SubViewport.xml:13
-msgid "If [code]true[/code], the sub-viewport will be used in AR/VR process."
-msgstr ""
-
-#: doc/classes/SubViewport.xml:16
msgid "The clear mode when the sub-viewport is used as a render target."
msgstr ""
-#: doc/classes/SubViewport.xml:19
+#: doc/classes/SubViewport.xml:16
msgid "The update mode when the sub-viewport is used as a render target."
msgstr ""
-#: doc/classes/SubViewport.xml:22
+#: doc/classes/SubViewport.xml:19
msgid "The width and height of the sub-viewport."
msgstr ""
-#: doc/classes/SubViewport.xml:25
+#: doc/classes/SubViewport.xml:22
msgid ""
"The 2D size override of the sub-viewport. If either the width or height is "
"[code]0[/code], the override is disabled."
msgstr ""
-#: doc/classes/SubViewport.xml:28
+#: doc/classes/SubViewport.xml:25
msgid "If [code]true[/code], the 2D size override affects stretch as well."
msgstr ""
+#: doc/classes/SubViewport.xml:28
+msgid "If [code]true[/code], the sub-viewport will be used in AR/VR process."
+msgstr ""
+
#: doc/classes/SubViewport.xml:33
-msgid "Do not update the render target."
+msgid "Always clear the render target before drawing."
msgstr ""
#: doc/classes/SubViewport.xml:36
-msgid ""
-"Update the render target once, then switch to [constant UPDATE_DISABLED]."
+msgid "Never clear the render target."
msgstr ""
#: doc/classes/SubViewport.xml:39
msgid ""
-"Update the render target only when it is visible. This is the default value."
+"Clear the render target next frame, then switch to [constant "
+"CLEAR_MODE_NEVER]."
msgstr ""
#: doc/classes/SubViewport.xml:42
-msgid "Update the render target only when the its parent is visible."
+msgid "Do not update the render target."
msgstr ""
#: doc/classes/SubViewport.xml:45
-msgid "Always update the render target."
+msgid ""
+"Update the render target once, then switch to [constant UPDATE_DISABLED]."
msgstr ""
#: doc/classes/SubViewport.xml:48
-msgid "Always clear the render target before drawing."
+msgid ""
+"Update the render target only when it is visible. This is the default value."
msgstr ""
#: doc/classes/SubViewport.xml:51
-msgid "Never clear the render target."
+msgid "Update the render target only when the its parent is visible."
msgstr ""
#: doc/classes/SubViewport.xml:54
-msgid ""
-"Clear the render target next frame, then switch to [constant "
-"CLEAR_MODE_NEVER]."
+msgid "Always update the render target."
msgstr ""
#: doc/classes/SubViewportContainer.xml:4
@@ -47984,85 +48235,90 @@ msgid ""
"information to a mesh.\n"
"Additionally, the attributes used before the first vertex is added determine "
"the format of the mesh. For example, if you only add UVs to the first "
-"vertex, you cannot add color to any of the subsequent vertices."
+"vertex, you cannot add color to any of the subsequent vertices.\n"
+"See also [ArrayMesh], [ImmediateGeometry3D] and [MeshDataTool] for "
+"procedural geometry generation.\n"
+"[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-"
+"OpenGL/Face-culling]winding order[/url] for front faces of triangle "
+"primitive modes."
msgstr ""
-#: doc/classes/SurfaceTool.xml:28
+#: doc/classes/SurfaceTool.xml:30
msgid ""
"Adds an array of bones for the next vertex to use. [code]bones[/code] must "
"contain 4 integers."
msgstr ""
-#: doc/classes/SurfaceTool.xml:37
+#: doc/classes/SurfaceTool.xml:39
msgid "Specifies a [Color] for the next vertex to use."
msgstr ""
-#: doc/classes/SurfaceTool.xml:46
+#: doc/classes/SurfaceTool.xml:48
msgid ""
"Adds an index to index array if you are using indexed vertices. Does not "
"need to be called before adding vertices."
msgstr ""
-#: doc/classes/SurfaceTool.xml:55
+#: doc/classes/SurfaceTool.xml:57
msgid "Specifies a normal for the next vertex to use."
msgstr ""
-#: doc/classes/SurfaceTool.xml:64
+#: doc/classes/SurfaceTool.xml:66
msgid ""
"Specifies whether the current vertex (if using only vertex arrays) or "
"current index (if also using index arrays) should use smooth normals for "
"normal calculation."
msgstr ""
-#: doc/classes/SurfaceTool.xml:73
+#: doc/classes/SurfaceTool.xml:75
msgid "Specifies a tangent for the next vertex to use."
msgstr ""
-#: doc/classes/SurfaceTool.xml:92
+#: doc/classes/SurfaceTool.xml:94
msgid ""
"Inserts a triangle fan made of array data into [Mesh] being constructed.\n"
"Requires the primitive type be set to [constant Mesh.PRIMITIVE_TRIANGLES]."
msgstr ""
-#: doc/classes/SurfaceTool.xml:102
+#: doc/classes/SurfaceTool.xml:104
msgid "Specifies a set of UV coordinates to use for the next vertex."
msgstr ""
-#: doc/classes/SurfaceTool.xml:111
+#: doc/classes/SurfaceTool.xml:113
msgid ""
"Specifies an optional second set of UV coordinates to use for the next "
"vertex."
msgstr ""
-#: doc/classes/SurfaceTool.xml:120
+#: doc/classes/SurfaceTool.xml:122
msgid ""
"Specifies the position of current vertex. Should be called after specifying "
"other vertex properties (e.g. Color, UV)."
msgstr ""
-#: doc/classes/SurfaceTool.xml:129
+#: doc/classes/SurfaceTool.xml:131
msgid ""
"Specifies weight values for next vertex to use. [code]weights[/code] must "
"contain 4 values."
msgstr ""
-#: doc/classes/SurfaceTool.xml:142
+#: doc/classes/SurfaceTool.xml:144
msgid ""
"Append vertices from a given [Mesh] surface onto the current vertex array "
"with specified [Transform]."
msgstr ""
-#: doc/classes/SurfaceTool.xml:151
+#: doc/classes/SurfaceTool.xml:153
msgid ""
"Called before adding any vertices. Takes the primitive type as an argument "
"(e.g. [constant Mesh.PRIMITIVE_TRIANGLES])."
msgstr ""
-#: doc/classes/SurfaceTool.xml:158
+#: doc/classes/SurfaceTool.xml:160
msgid "Clear all information passed into the surface tool so far."
msgstr ""
-#: doc/classes/SurfaceTool.xml:169
+#: doc/classes/SurfaceTool.xml:171
msgid ""
"Returns a constructed [ArrayMesh] from current information passed in. If an "
"existing [ArrayMesh] is passed in as an argument, will add an extra surface "
@@ -48072,28 +48328,28 @@ msgid ""
"flags."
msgstr ""
-#: doc/classes/SurfaceTool.xml:177
+#: doc/classes/SurfaceTool.xml:179
msgid ""
"Commits the data to the same format used by [method ArrayMesh."
"add_surface_from_arrays]. This way you can further process the mesh data "
"using the [ArrayMesh] API."
msgstr ""
-#: doc/classes/SurfaceTool.xml:188
+#: doc/classes/SurfaceTool.xml:190
msgid "Creates a vertex array from an existing [Mesh]."
msgstr ""
-#: doc/classes/SurfaceTool.xml:201
+#: doc/classes/SurfaceTool.xml:203
msgid ""
"Creates a vertex array from the specified blend shape of an existing [Mesh]. "
"This can be used to extract a specific pose from a blend shape."
msgstr ""
-#: doc/classes/SurfaceTool.xml:208
+#: doc/classes/SurfaceTool.xml:210
msgid "Removes the index array by expanding the vertex array."
msgstr ""
-#: doc/classes/SurfaceTool.xml:217
+#: doc/classes/SurfaceTool.xml:219
msgid ""
"Generates normals from vertices so you do not have to do it manually. If "
"[code]flip[/code] is [code]true[/code], the resulting normals will be "
@@ -48101,19 +48357,19 @@ msgid ""
"Requires the primitive type to be set to [constant Mesh.PRIMITIVE_TRIANGLES]."
msgstr ""
-#: doc/classes/SurfaceTool.xml:225
+#: doc/classes/SurfaceTool.xml:227
msgid ""
"Generates a tangent vector for each vertex. Requires that each vertex have "
"UVs and normals set already."
msgstr ""
-#: doc/classes/SurfaceTool.xml:232
+#: doc/classes/SurfaceTool.xml:234
msgid ""
"Shrinks the vertex array by creating an index array (avoids reusing "
"vertices)."
msgstr ""
-#: doc/classes/SurfaceTool.xml:241
+#: doc/classes/SurfaceTool.xml:243
msgid "Sets [Material] to be used by the [Mesh] you are constructing."
msgstr ""
@@ -48147,7 +48403,7 @@ msgid "Returns the previously active tab index."
msgstr ""
#: doc/classes/TabContainer.xml:42
-msgid "Returns the currently visible tab's [Control] node."
+msgid "Returns the [Control] node from the tab at index [code]tab_idx[/code]."
msgstr ""
#: doc/classes/TabContainer.xml:49 doc/classes/Tabs.xml:50
@@ -48816,151 +49072,163 @@ msgstr ""
msgid "If [code]true[/code], the line containing the cursor is highlighted."
msgstr ""
-#: doc/classes/TextEdit.xml:438
+#: doc/classes/TextEdit.xml:436
+msgid ""
+"If [code]true[/code], custom [code]font_color_selected[/code] will be used "
+"for selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml:439
msgid ""
"If [code]true[/code], read-only mode is enabled. Existing text cannot be "
"modified and new text cannot be added."
msgstr ""
-#: doc/classes/TextEdit.xml:451
+#: doc/classes/TextEdit.xml:452
msgid ""
"If [code]true[/code], line numbers are displayed to the left of the text."
msgstr ""
-#: doc/classes/TextEdit.xml:454
+#: doc/classes/TextEdit.xml:455
msgid ""
"If [code]true[/code], sets the [code]step[/code] of the scrollbars to "
"[code]0.25[/code] which results in smoother scrolling."
msgstr ""
-#: doc/classes/TextEdit.xml:457
+#: doc/classes/TextEdit.xml:458
msgid ""
"If [code]true[/code], any custom color properties that have been set for "
"this [TextEdit] will be visible."
msgstr ""
-#: doc/classes/TextEdit.xml:460
+#: doc/classes/TextEdit.xml:461
msgid "String value of the [TextEdit]."
msgstr ""
-#: doc/classes/TextEdit.xml:463
+#: doc/classes/TextEdit.xml:464
msgid "Vertical scroll sensitivity."
msgstr ""
-#: doc/classes/TextEdit.xml:466
+#: doc/classes/TextEdit.xml:467
msgid ""
"If [code]true[/code], enables text wrapping when it goes beyond the edge of "
"what is visible."
msgstr ""
-#: doc/classes/TextEdit.xml:474
+#: doc/classes/TextEdit.xml:475
msgid "Emitted when a breakpoint is placed via the breakpoint gutter."
msgstr ""
-#: doc/classes/TextEdit.xml:479
+#: doc/classes/TextEdit.xml:480
msgid "Emitted when the cursor changes."
msgstr ""
-#: doc/classes/TextEdit.xml:488
+#: doc/classes/TextEdit.xml:489
msgid "Emitted when the info icon is clicked."
msgstr ""
-#: doc/classes/TextEdit.xml:519
+#: doc/classes/TextEdit.xml:520
msgid "Match case when searching."
msgstr ""
-#: doc/classes/TextEdit.xml:522
+#: doc/classes/TextEdit.xml:523
msgid "Match whole words when searching."
msgstr ""
-#: doc/classes/TextEdit.xml:525
+#: doc/classes/TextEdit.xml:526
msgid "Search from end to beginning."
msgstr ""
-#: doc/classes/TextEdit.xml:528
+#: doc/classes/TextEdit.xml:529
msgid "Used to access the result column from [method search]."
msgstr ""
-#: doc/classes/TextEdit.xml:531
+#: doc/classes/TextEdit.xml:532
msgid "Used to access the result line from [method search]."
msgstr ""
-#: doc/classes/TextEdit.xml:540
+#: doc/classes/TextEdit.xml:541
msgid ""
"Pastes the clipboard text over the selected text (or at the cursor's "
"position)."
msgstr ""
-#: doc/classes/TextEdit.xml:543
+#: doc/classes/TextEdit.xml:544
msgid "Erases the whole [TextEdit] text."
msgstr ""
-#: doc/classes/TextEdit.xml:546
+#: doc/classes/TextEdit.xml:547
msgid "Selects the whole [TextEdit] text."
msgstr ""
-#: doc/classes/TextEdit.xml:552
+#: doc/classes/TextEdit.xml:553
msgid "Redoes the previous action."
msgstr ""
-#: doc/classes/TextEdit.xml:560
+#: doc/classes/TextEdit.xml:561
msgid ""
"Sets the background [Color] of this [TextEdit]. [member syntax_highlighting] "
"has to be enabled."
msgstr ""
-#: doc/classes/TextEdit.xml:563
+#: doc/classes/TextEdit.xml:564
msgid ""
"Sets the [Color] of the bookmark marker. [member syntax_highlighting] has to "
"be enabled."
msgstr ""
-#: doc/classes/TextEdit.xml:568 doc/classes/TextEdit.xml:595
+#: doc/classes/TextEdit.xml:569 doc/classes/TextEdit.xml:596
msgid ""
"Sets the [Color] of the breakpoints. [member breakpoint_gutter] has to be "
"enabled."
msgstr ""
-#: doc/classes/TextEdit.xml:606
+#: doc/classes/TextEdit.xml:607
msgid "Sets the default [Font]."
msgstr ""
-#: doc/classes/TextEdit.xml:609
+#: doc/classes/TextEdit.xml:610
msgid "Sets the font [Color]."
msgstr ""
-#: doc/classes/TextEdit.xml:618
+#: doc/classes/TextEdit.xml:615
+msgid ""
+"Sets the [Color] of the selected text. [member override_selected_font_color] "
+"has to be enabled."
+msgstr ""
+
+#: doc/classes/TextEdit.xml:620
msgid ""
"Sets the [Color] of the line numbers. [member show_line_numbers] has to be "
"enabled."
msgstr ""
-#: doc/classes/TextEdit.xml:621
+#: doc/classes/TextEdit.xml:623
msgid "Sets the spacing between the lines."
msgstr ""
-#: doc/classes/TextEdit.xml:624
+#: doc/classes/TextEdit.xml:626
msgid "Sets the [Color] of marked text."
msgstr ""
-#: doc/classes/TextEdit.xml:629
+#: doc/classes/TextEdit.xml:631
msgid "Sets the [StyleBox] of this [TextEdit]."
msgstr ""
-#: doc/classes/TextEdit.xml:634
+#: doc/classes/TextEdit.xml:636
msgid ""
"Sets the [StyleBox] of this [TextEdit] when [member readonly] is enabled."
msgstr ""
-#: doc/classes/TextEdit.xml:639
+#: doc/classes/TextEdit.xml:641
msgid "Sets the highlight [Color] of text selections."
msgstr ""
-#: doc/classes/TextEdit.xml:646
+#: doc/classes/TextEdit.xml:648
msgid "Sets a custom [Texture2D] for tab text characters."
msgstr ""
-#: doc/classes/TextEdit.xml:649
+#: doc/classes/TextEdit.xml:651
msgid ""
"Sets the highlight [Color] of multiple occurrences. [member "
"highlight_all_occurrences] has to be enabled."
@@ -49632,8 +49900,8 @@ msgstr ""
#: doc/classes/TileMap.xml:46
msgid ""
-"Returns the coordinate of the autotile variation in the tileset. Returns a "
-"zero vector if the cell doesn't have autotiling."
+"Returns the coordinate (subtile column and row) of the autotile variation in "
+"the tileset. Returns a zero vector if the cell doesn't have autotiling."
msgstr ""
#: doc/classes/TileMap.xml:55
@@ -49690,7 +49958,8 @@ msgid ""
"Sets the tile index for the cell given by a Vector2.\n"
"An index of [code]-1[/code] clears the cell.\n"
"Optionally, the tile can also be flipped, transposed, or given autotile "
-"coordinates.\n"
+"coordinates. The autotile coordinate refers to the column and row of the "
+"subtile.\n"
"[b]Note:[/b] Data such as navigation polygons and collision shapes are not "
"immediately updated for performance reasons.\n"
"If you need these to be immediately updated, you can call [method "
@@ -50497,9 +50766,10 @@ msgid ""
"using matrix multiplication. The axis must be a normalized vector."
msgstr ""
-#: doc/classes/Transform.xml:138 doc/classes/Transform2D.xml:140
+#: doc/classes/Transform.xml:138
msgid ""
-"Scales the transform by the given scale factor, using matrix multiplication."
+"Scales basis and origin of the transform by the given scale factor, using "
+"matrix multiplication."
msgstr ""
#: doc/classes/Transform.xml:147 doc/classes/Transform2D.xml:149
@@ -50609,6 +50879,11 @@ msgid ""
"multiplication."
msgstr ""
+#: doc/classes/Transform2D.xml:140
+msgid ""
+"Scales the transform by the given scale factor, using matrix multiplication."
+msgstr ""
+
#: doc/classes/Transform2D.xml:159
msgid ""
"Transforms the given [Vector2], [Rect2], or [PackedVector2Array] by this "
@@ -50766,7 +51041,8 @@ msgid ""
"[/codeblock]\n"
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
-"through [method get_root]."
+"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
+"to remove it from the [Tree]."
msgstr ""
#: doc/classes/Tree.xml:28
@@ -51252,10 +51528,11 @@ msgstr ""
#: doc/classes/TreeItem.xml:7
msgid ""
"Control for a single item inside a [Tree]. May have child [TreeItem]s and be "
-"styled as well as contain buttons."
+"styled as well as contain buttons.\n"
+"You can remove a [TreeItem] by using [method Object.free]."
msgstr ""
-#: doc/classes/TreeItem.xml:26
+#: doc/classes/TreeItem.xml:27
msgid ""
"Adds a button with [Texture2D] [code]button[/code] at column [code]column[/"
"code]. The [code]button_idx[/code] index is used to identify the button when "
@@ -51265,89 +51542,89 @@ msgid ""
"have a [code]tooltip[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:35
+#: doc/classes/TreeItem.xml:36
msgid ""
"Calls the [code]method[/code] on the actual TreeItem and its children "
"recursively. Pass parameters as a comma separated list."
msgstr ""
-#: doc/classes/TreeItem.xml:44
+#: doc/classes/TreeItem.xml:45
msgid "Resets the background color for the given column to default."
msgstr ""
-#: doc/classes/TreeItem.xml:53
+#: doc/classes/TreeItem.xml:54
msgid "Resets the color for the given column to default."
msgstr ""
-#: doc/classes/TreeItem.xml:62
+#: doc/classes/TreeItem.xml:63
msgid "Deselects the given column."
msgstr ""
-#: doc/classes/TreeItem.xml:73
+#: doc/classes/TreeItem.xml:74
msgid ""
"Removes the button at index [code]button_idx[/code] in column [code]column[/"
"code]."
msgstr ""
-#: doc/classes/TreeItem.xml:84
+#: doc/classes/TreeItem.xml:85
msgid ""
"Returns the [Texture2D] of the button at index [code]button_idx[/code] in "
"column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:93
+#: doc/classes/TreeItem.xml:94
msgid ""
"Returns the number of buttons in column [code]column[/code]. May be used to "
"get the most recently added button's index, if no index was specified."
msgstr ""
-#: doc/classes/TreeItem.xml:104
+#: doc/classes/TreeItem.xml:105
msgid ""
"Returns the tooltip string for the button at index [code]button_idx[/code] "
"in column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:113
+#: doc/classes/TreeItem.xml:114
msgid "Returns the column's cell mode."
msgstr ""
-#: doc/classes/TreeItem.xml:120
+#: doc/classes/TreeItem.xml:121
msgid "Returns the TreeItem's child items."
msgstr ""
-#: doc/classes/TreeItem.xml:129
+#: doc/classes/TreeItem.xml:130
msgid "Returns the custom background color of column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:138
+#: doc/classes/TreeItem.xml:139
msgid "Returns the custom color of column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:147
+#: doc/classes/TreeItem.xml:148
msgid "Returns [code]true[/code] if [code]expand_right[/code] is set."
msgstr ""
-#: doc/classes/TreeItem.xml:156
+#: doc/classes/TreeItem.xml:157
msgid "Returns the given column's icon [Texture2D]. Error if no icon is set."
msgstr ""
-#: doc/classes/TreeItem.xml:165
+#: doc/classes/TreeItem.xml:166
msgid "Returns the column's icon's maximum width."
msgstr ""
-#: doc/classes/TreeItem.xml:174
+#: doc/classes/TreeItem.xml:175
msgid "Returns the [Color] modulating the column's icon."
msgstr ""
-#: doc/classes/TreeItem.xml:183
+#: doc/classes/TreeItem.xml:184
msgid "Returns the icon [Texture2D] region as [Rect2]."
msgstr ""
-#: doc/classes/TreeItem.xml:198
+#: doc/classes/TreeItem.xml:199
msgid "Returns the next TreeItem in the tree."
msgstr ""
-#: doc/classes/TreeItem.xml:207
+#: doc/classes/TreeItem.xml:208
msgid ""
"Returns the next visible TreeItem in the tree.\n"
"If [code]wrap[/code] is enabled, the method will wrap around to the first "
@@ -51355,15 +51632,15 @@ msgid ""
"otherwise it returns [code]null[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:215
+#: doc/classes/TreeItem.xml:216
msgid "Returns the parent TreeItem."
msgstr ""
-#: doc/classes/TreeItem.xml:222
+#: doc/classes/TreeItem.xml:223
msgid "Returns the previous TreeItem in the tree."
msgstr ""
-#: doc/classes/TreeItem.xml:231
+#: doc/classes/TreeItem.xml:232
msgid ""
"Returns the previous visible TreeItem in the tree.\n"
"If [code]wrap[/code] is enabled, the method will wrap around to the last "
@@ -51371,89 +51648,92 @@ msgid ""
"otherwise it returns [code]null[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:257
+#: doc/classes/TreeItem.xml:258
msgid "Returns the given column's text."
msgstr ""
-#: doc/classes/TreeItem.xml:266
+#: doc/classes/TreeItem.xml:267
msgid "Returns the given column's text alignment."
msgstr ""
-#: doc/classes/TreeItem.xml:275
+#: doc/classes/TreeItem.xml:276
msgid "Returns the given column's tooltip."
msgstr ""
-#: doc/classes/TreeItem.xml:286
+#: doc/classes/TreeItem.xml:287
msgid ""
"Returns [code]true[/code] if the button at index [code]button_idx[/code] for "
"the given column is disabled."
msgstr ""
-#: doc/classes/TreeItem.xml:295
+#: doc/classes/TreeItem.xml:296
msgid "Returns [code]true[/code] if the given column is checked."
msgstr ""
-#: doc/classes/TreeItem.xml:312
+#: doc/classes/TreeItem.xml:313
msgid "Returns [code]true[/code] if column [code]column[/code] is editable."
msgstr ""
-#: doc/classes/TreeItem.xml:321
+#: doc/classes/TreeItem.xml:322
msgid "Returns [code]true[/code] if column [code]column[/code] is selectable."
msgstr ""
-#: doc/classes/TreeItem.xml:330
+#: doc/classes/TreeItem.xml:331
msgid "Returns [code]true[/code] if column [code]column[/code] is selected."
msgstr ""
-#: doc/classes/TreeItem.xml:337
+#: doc/classes/TreeItem.xml:338
msgid "Moves this TreeItem to the bottom in the [Tree] hierarchy."
msgstr ""
-#: doc/classes/TreeItem.xml:344
+#: doc/classes/TreeItem.xml:345
msgid "Moves this TreeItem to the top in the [Tree] hierarchy."
msgstr ""
-#: doc/classes/TreeItem.xml:353
-msgid "Removes the given child TreeItem."
+#: doc/classes/TreeItem.xml:354
+msgid ""
+"Removes the given child [TreeItem] and all its children from the [Tree]. "
+"Note that it doesn't free the item from memory, so it can be reused later. "
+"To completely remove a [TreeItem] use [method Object.free]."
msgstr ""
-#: doc/classes/TreeItem.xml:362
+#: doc/classes/TreeItem.xml:363
msgid "Selects the column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:375
+#: doc/classes/TreeItem.xml:376
msgid ""
"Sets the given column's button [Texture2D] at index [code]button_idx[/code] "
"to [code]button[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:388
+#: doc/classes/TreeItem.xml:389
msgid ""
"If [code]true[/code], disables the button at index [code]button_idx[/code] "
"in column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:399
+#: doc/classes/TreeItem.xml:400
msgid ""
"Sets the given column's cell mode to [code]mode[/code]. See [enum "
"TreeCellMode] constants."
msgstr ""
-#: doc/classes/TreeItem.xml:410
+#: doc/classes/TreeItem.xml:411
msgid "If [code]true[/code], the column [code]column[/code] is checked."
msgstr ""
-#: doc/classes/TreeItem.xml:433
+#: doc/classes/TreeItem.xml:434
msgid ""
"Sets the given column's custom background color and whether to just use it "
"as an outline."
msgstr ""
-#: doc/classes/TreeItem.xml:444
+#: doc/classes/TreeItem.xml:445
msgid "Sets the given column's custom color."
msgstr ""
-#: doc/classes/TreeItem.xml:457
+#: doc/classes/TreeItem.xml:458
msgid ""
"Sets the given column's custom draw callback to [code]callback[/code] method "
"on [code]object[/code].\n"
@@ -51461,82 +51741,82 @@ msgid ""
"is drawn and its position and size as a [Rect2]."
msgstr ""
-#: doc/classes/TreeItem.xml:469
+#: doc/classes/TreeItem.xml:470
msgid "If [code]true[/code], column [code]column[/code] is editable."
msgstr ""
-#: doc/classes/TreeItem.xml:480
+#: doc/classes/TreeItem.xml:481
msgid ""
"If [code]true[/code], column [code]column[/code] is expanded to the right."
msgstr ""
-#: doc/classes/TreeItem.xml:491
+#: doc/classes/TreeItem.xml:492
msgid "Sets the given column's icon [Texture2D]."
msgstr ""
-#: doc/classes/TreeItem.xml:502
+#: doc/classes/TreeItem.xml:503
msgid "Sets the given column's icon's maximum width."
msgstr ""
-#: doc/classes/TreeItem.xml:513
+#: doc/classes/TreeItem.xml:514
msgid "Modulates the given column's icon with [code]modulate[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:524
+#: doc/classes/TreeItem.xml:525
msgid "Sets the given column's icon's texture region."
msgstr ""
-#: doc/classes/TreeItem.xml:571
+#: doc/classes/TreeItem.xml:572
msgid "If [code]true[/code], the given column is selectable."
msgstr ""
-#: doc/classes/TreeItem.xml:592
+#: doc/classes/TreeItem.xml:593
msgid ""
"Sets the given column's text alignment. See [enum TextAlign] for possible "
"values."
msgstr ""
-#: doc/classes/TreeItem.xml:603
+#: doc/classes/TreeItem.xml:604
msgid "Sets the given column's tooltip text."
msgstr ""
-#: doc/classes/TreeItem.xml:609
+#: doc/classes/TreeItem.xml:610
msgid "If [code]true[/code], the TreeItem is collapsed."
msgstr ""
-#: doc/classes/TreeItem.xml:612
+#: doc/classes/TreeItem.xml:613
msgid "The custom minimum height."
msgstr ""
-#: doc/classes/TreeItem.xml:615
+#: doc/classes/TreeItem.xml:616
msgid "If [code]true[/code], folding is disabled for this TreeItem."
msgstr ""
-#: doc/classes/TreeItem.xml:620
+#: doc/classes/TreeItem.xml:621
msgid "Cell contains a string."
msgstr ""
-#: doc/classes/TreeItem.xml:623
+#: doc/classes/TreeItem.xml:624
msgid "Cell can be checked."
msgstr ""
-#: doc/classes/TreeItem.xml:626
+#: doc/classes/TreeItem.xml:627
msgid "Cell contains a range."
msgstr ""
-#: doc/classes/TreeItem.xml:629
+#: doc/classes/TreeItem.xml:630
msgid "Cell contains an icon."
msgstr ""
-#: doc/classes/TreeItem.xml:634
+#: doc/classes/TreeItem.xml:635
msgid "Align text to the left. See [code]set_text_align()[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:637
+#: doc/classes/TreeItem.xml:638
msgid "Center text. See [code]set_text_align()[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:640
+#: doc/classes/TreeItem.xml:641
msgid "Align text to the right. See [code]set_text_align()[/code]."
msgstr ""
@@ -51562,8 +51842,8 @@ msgid ""
"know the final values in advance. For example, interpolating a dynamically-"
"chosen camera zoom value is best done with a [Tween] node; it would be "
"difficult to do the same thing with an [AnimationPlayer] node.\n"
-"Here is a brief usage example that causes a 2D node to move smoothly between "
-"two positions:\n"
+"Here is a brief usage example that makes a 2D node move smoothly between two "
+"positions:\n"
"[codeblock]\n"
"var tween = get_node(\"Tween\")\n"
"tween.interpolate_property($Node2D, \"position\",\n"
@@ -51578,15 +51858,18 @@ msgid ""
"where it would only apply to that particular component.\n"
"Many of the methods accept [code]trans_type[/code] and [code]ease_type[/"
"code]. The first accepts an [enum TransitionType] constant, and refers to "
-"the way the timing of the animation is handled (see [code]http://easings.net/"
-"[/code] for some examples). The second accepts an [enum EaseType] constant, "
-"and controls the where [code]trans_type[/code] is applied to the "
-"interpolation (in the beginning, the end, or both). If you don't know which "
-"transition and easing to pick, you can try different [enum TransitionType] "
-"constants with [constant EASE_IN_OUT], and use the one that looks best."
+"the way the timing of the animation is handled (see [url=https://easings."
+"net/]easings.net[/url] for some examples). The second accepts an [enum "
+"EaseType] constant, and controls the where [code]trans_type[/code] is "
+"applied to the interpolation (in the beginning, the end, or both). If you "
+"don't know which transition and easing to pick, you can try different [enum "
+"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
+"looks best.\n"
+"[b][url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url][/b]"
msgstr ""
-#: doc/classes/Tween.xml:45
+#: doc/classes/Tween.xml:46
msgid ""
"Follows [code]method[/code] of [code]object[/code] and applies the returned "
"value on [code]target_method[/code] of [code]target[/code], beginning from "
@@ -51598,7 +51881,7 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:71
+#: doc/classes/Tween.xml:72
msgid ""
"Follows [code]property[/code] of [code]object[/code] and applies it on "
"[code]target_property[/code] of [code]target[/code], beginning from "
@@ -51610,21 +51893,21 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:79
+#: doc/classes/Tween.xml:80
msgid ""
"Returns the total time needed for all tweens to end. If you have two tweens, "
"one lasting 10 seconds and the other 20 seconds, it would return 20 seconds, "
"as by that time all tweens would have finished."
msgstr ""
-#: doc/classes/Tween.xml:102
+#: doc/classes/Tween.xml:103
msgid ""
"Calls [code]callback[/code] of [code]object[/code] after [code]duration[/"
"code]. [code]arg1[/code]-[code]arg5[/code] are arguments to be passed to the "
"callback."
msgstr ""
-#: doc/classes/Tween.xml:125
+#: doc/classes/Tween.xml:126
msgid ""
"Calls [code]callback[/code] of [code]object[/code] after [code]duration[/"
"code] on the main thread (similar to [method Object.call_deferred]). "
@@ -51632,7 +51915,7 @@ msgid ""
"callback."
msgstr ""
-#: doc/classes/Tween.xml:148
+#: doc/classes/Tween.xml:149
msgid ""
"Animates [code]method[/code] of [code]object[/code] from [code]initial_val[/"
"code] to [code]final_val[/code] for [code]duration[/code] seconds, "
@@ -51644,7 +51927,7 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:172
+#: doc/classes/Tween.xml:173
msgid ""
"Animates [code]property[/code] of [code]object[/code] from "
"[code]initial_val[/code] to [code]final_val[/code] for [code]duration[/code] "
@@ -51656,72 +51939,72 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:180
+#: doc/classes/Tween.xml:181
msgid ""
"Returns [code]true[/code] if any tweens are currently running.\n"
"[b]Note:[/b] This method doesn't consider tweens that have ended."
msgstr ""
-#: doc/classes/Tween.xml:192
+#: doc/classes/Tween.xml:193
msgid ""
"Stops animation and removes a tween, given its object and property/method "
"pair. By default, all tweens are removed, unless [code]key[/code] is "
"specified."
msgstr ""
-#: doc/classes/Tween.xml:199
+#: doc/classes/Tween.xml:200
msgid "Stops animation and removes all tweens."
msgstr ""
-#: doc/classes/Tween.xml:210
+#: doc/classes/Tween.xml:211
msgid ""
"Resets a tween to its initial value (the one given, not the one before the "
"tween), given its object and property/method pair. By default, all tweens "
"are removed, unless [code]key[/code] is specified."
msgstr ""
-#: doc/classes/Tween.xml:217
+#: doc/classes/Tween.xml:218
msgid ""
"Resets all tweens to their initial values (the ones given, not those before "
"the tween)."
msgstr ""
-#: doc/classes/Tween.xml:228
+#: doc/classes/Tween.xml:229
msgid ""
"Continues animating a stopped tween, given its object and property/method "
"pair. By default, all tweens are resumed, unless [code]key[/code] is "
"specified."
msgstr ""
-#: doc/classes/Tween.xml:235
+#: doc/classes/Tween.xml:236
msgid "Continues animating all stopped tweens."
msgstr ""
-#: doc/classes/Tween.xml:244
+#: doc/classes/Tween.xml:245
msgid "Sets the interpolation to the given [code]time[/code] in seconds."
msgstr ""
-#: doc/classes/Tween.xml:253
+#: doc/classes/Tween.xml:254
msgid ""
"Activates/deactivates the tween. See also [method stop_all] and [method "
"resume_all]."
msgstr ""
-#: doc/classes/Tween.xml:260
+#: doc/classes/Tween.xml:261
msgid "Starts the tween. You can define animations both before and after this."
msgstr ""
-#: doc/classes/Tween.xml:271
+#: doc/classes/Tween.xml:272
msgid ""
"Stops a tween, given its object and property/method pair. By default, all "
"tweens are stopped, unless [code]key[/code] is specified."
msgstr ""
-#: doc/classes/Tween.xml:278
+#: doc/classes/Tween.xml:279
msgid "Stops animating all tweens."
msgstr ""
-#: doc/classes/Tween.xml:303
+#: doc/classes/Tween.xml:304
msgid ""
"Animates [code]method[/code] of [code]object[/code] from the value returned "
"by [code]initial_method[/code] to [code]final_val[/code] for [code]duration[/"
@@ -51733,7 +52016,7 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:329
+#: doc/classes/Tween.xml:330
msgid ""
"Animates [code]property[/code] of [code]object[/code] from the current value "
"of the [code]initial_val[/code] property of [code]initial[/code] to "
@@ -51745,15 +52028,15 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:337
+#: doc/classes/Tween.xml:338
msgid "Returns the current time of the tween."
msgstr ""
-#: doc/classes/Tween.xml:343
+#: doc/classes/Tween.xml:344
msgid "The tween's animation process thread. See [enum TweenProcessMode]."
msgstr ""
-#: doc/classes/Tween.xml:346
+#: doc/classes/Tween.xml:347
msgid ""
"The tween's speed multiplier. For example, set it to [code]1.0[/code] for "
"normal speed, [code]2.0[/code] for two times normal speed, or [code]0.5[/"
@@ -51761,100 +52044,100 @@ msgid ""
"animation, but see also [method set_active] or [method stop_all] for this."
msgstr ""
-#: doc/classes/Tween.xml:349
+#: doc/classes/Tween.xml:350
msgid "If [code]true[/code], the tween loops."
msgstr ""
-#: doc/classes/Tween.xml:355
+#: doc/classes/Tween.xml:356
msgid "Emitted when all processes in a tween end."
msgstr ""
-#: doc/classes/Tween.xml:364
+#: doc/classes/Tween.xml:365
msgid "Emitted when a tween ends."
msgstr ""
-#: doc/classes/Tween.xml:373
+#: doc/classes/Tween.xml:374
msgid "Emitted when a tween starts."
msgstr ""
-#: doc/classes/Tween.xml:386
+#: doc/classes/Tween.xml:387
msgid "Emitted at each step of the animation."
msgstr ""
-#: doc/classes/Tween.xml:392
+#: doc/classes/Tween.xml:393
msgid "The tween updates with the [code]_physics_process[/code] callback."
msgstr ""
-#: doc/classes/Tween.xml:395
+#: doc/classes/Tween.xml:396
msgid "The tween updates with the [code]_process[/code] callback."
msgstr ""
-#: doc/classes/Tween.xml:398
+#: doc/classes/Tween.xml:399
msgid "The animation is interpolated linearly."
msgstr ""
-#: doc/classes/Tween.xml:401
+#: doc/classes/Tween.xml:402
msgid "The animation is interpolated using a sine function."
msgstr ""
-#: doc/classes/Tween.xml:404
+#: doc/classes/Tween.xml:405
msgid ""
"The animation is interpolated with a quintic (to the power of 5) function."
msgstr ""
-#: doc/classes/Tween.xml:407
+#: doc/classes/Tween.xml:408
msgid ""
"The animation is interpolated with a quartic (to the power of 4) function."
msgstr ""
-#: doc/classes/Tween.xml:410
+#: doc/classes/Tween.xml:411
msgid ""
"The animation is interpolated with a quadratic (to the power of 2) function."
msgstr ""
-#: doc/classes/Tween.xml:413
+#: doc/classes/Tween.xml:414
msgid ""
"The animation is interpolated with an exponential (to the power of x) "
"function."
msgstr ""
-#: doc/classes/Tween.xml:416
+#: doc/classes/Tween.xml:417
msgid ""
"The animation is interpolated with elasticity, wiggling around the edges."
msgstr ""
-#: doc/classes/Tween.xml:419
+#: doc/classes/Tween.xml:420
msgid ""
"The animation is interpolated with a cubic (to the power of 3) function."
msgstr ""
-#: doc/classes/Tween.xml:422
+#: doc/classes/Tween.xml:423
msgid "The animation is interpolated with a function using square roots."
msgstr ""
-#: doc/classes/Tween.xml:425
+#: doc/classes/Tween.xml:426
msgid "The animation is interpolated by bouncing at the end."
msgstr ""
-#: doc/classes/Tween.xml:428
+#: doc/classes/Tween.xml:429
msgid "The animation is interpolated backing out at ends."
msgstr ""
-#: doc/classes/Tween.xml:431
+#: doc/classes/Tween.xml:432
msgid "The interpolation starts slowly and speeds up towards the end."
msgstr ""
-#: doc/classes/Tween.xml:434
+#: doc/classes/Tween.xml:435
msgid "The interpolation starts quickly and slows down towards the end."
msgstr ""
-#: doc/classes/Tween.xml:437
+#: doc/classes/Tween.xml:438
msgid ""
"A combination of [constant EASE_IN] and [constant EASE_OUT]. The "
"interpolation is slowest at both ends."
msgstr ""
-#: doc/classes/Tween.xml:440
+#: doc/classes/Tween.xml:441
msgid ""
"A combination of [constant EASE_IN] and [constant EASE_OUT]. The "
"interpolation is fastest at both ends."
@@ -53458,69 +53741,90 @@ msgstr ""
msgid "If [code]true[/code], the viewport will process 3D audio streams."
msgstr ""
-#: doc/classes/Viewport.xml:199
+#: doc/classes/Viewport.xml:195
+msgid ""
+"Sets the default filter mode used by [CanvasItem]s in this Viewport. See "
+"[enum DefaultCanvasItemTextureFilter] for options."
+msgstr ""
+
+#: doc/classes/Viewport.xml:198
+msgid ""
+"Sets the default repeat mode used by [CanvasItem]s in this Viewport. See "
+"[enum DefaultCanvasItemTextureRepeat] for options."
+msgstr ""
+
+#: doc/classes/Viewport.xml:201
msgid ""
"The canvas transform of the viewport, useful for changing the on-screen "
"positions of all child [CanvasItem]s. This is relative to the global canvas "
"transform of the viewport."
msgstr ""
-#: doc/classes/Viewport.xml:202
+#: doc/classes/Viewport.xml:204
msgid "The overlay mode for test rendered geometry in debug purposes."
msgstr ""
-#: doc/classes/Viewport.xml:205
+#: doc/classes/Viewport.xml:207
msgid ""
"The global canvas transform of the viewport. The canvas transform is "
"relative to this."
msgstr ""
-#: doc/classes/Viewport.xml:208
+#: doc/classes/Viewport.xml:210
msgid "If [code]true[/code], the viewport will not receive input event."
msgstr ""
-#: doc/classes/Viewport.xml:213
+#: doc/classes/Viewport.xml:215
msgid ""
"If [code]true[/code], the GUI controls on the viewport will lay pixel "
"perfectly."
msgstr ""
-#: doc/classes/Viewport.xml:218
+#: doc/classes/Viewport.xml:220
msgid ""
"The multisample anti-aliasing mode. A higher number results in smoother "
"edges at the cost of significantly worse performance. A value of 4 is best "
"unless targeting very high-end systems."
msgstr ""
-#: doc/classes/Viewport.xml:221
+#: doc/classes/Viewport.xml:223
msgid ""
"If [code]true[/code], the viewport will use [World3D] defined in "
"[code]world[/code] property."
msgstr ""
-#: doc/classes/Viewport.xml:224
+#: doc/classes/Viewport.xml:226
msgid ""
"If [code]true[/code], the objects rendered by viewport become subjects of "
"mouse picking process."
msgstr ""
-#: doc/classes/Viewport.xml:227
+#: doc/classes/Viewport.xml:229
+msgid ""
+"Sets the screen-space antialiasing method used. Screen-space antialiasing "
+"works by selectively blurring edges in a post-process shader. It differs "
+"from MSAA which takes multiple coverage samples while rendering objects. "
+"Screen-space AA methods are typically faster than MSAA and will smooth out "
+"specular aliasing, but tend to make scenes appear blurry."
+msgstr ""
+
+#: doc/classes/Viewport.xml:232
msgid "The subdivision amount of the first quadrant on the shadow atlas."
msgstr ""
-#: doc/classes/Viewport.xml:230
+#: doc/classes/Viewport.xml:235
msgid "The subdivision amount of the second quadrant on the shadow atlas."
msgstr ""
-#: doc/classes/Viewport.xml:233
+#: doc/classes/Viewport.xml:238
msgid "The subdivision amount of the third quadrant on the shadow atlas."
msgstr ""
-#: doc/classes/Viewport.xml:236
+#: doc/classes/Viewport.xml:241
msgid "The subdivision amount of the fourth quadrant on the shadow atlas."
msgstr ""
-#: doc/classes/Viewport.xml:239
+#: doc/classes/Viewport.xml:244
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
@@ -53529,136 +53833,177 @@ msgid ""
"manually."
msgstr ""
-#: doc/classes/Viewport.xml:243
+#: doc/classes/Viewport.xml:248
msgid ""
"If [code]true[/code], the viewport should render its background as "
"transparent."
msgstr ""
-#: doc/classes/Viewport.xml:246
+#: doc/classes/Viewport.xml:251
msgid "The custom [World3D] which can be used as 3D environment source."
msgstr ""
-#: doc/classes/Viewport.xml:249
+#: doc/classes/Viewport.xml:254
msgid "The custom [World2D] which can be used as 2D environment source."
msgstr ""
-#: doc/classes/Viewport.xml:257
+#: doc/classes/Viewport.xml:262
msgid "Emitted when a Control node grabs keyboard focus."
msgstr ""
-#: doc/classes/Viewport.xml:262
+#: doc/classes/Viewport.xml:267
msgid ""
"Emitted when the size of the viewport is changed, whether by resizing of "
"window, or some other means."
msgstr ""
-#: doc/classes/Viewport.xml:268
+#: doc/classes/Viewport.xml:273
msgid "This quadrant will not be used."
msgstr ""
-#: doc/classes/Viewport.xml:271
+#: doc/classes/Viewport.xml:276
msgid "This quadrant will only be used by one shadow map."
msgstr ""
-#: doc/classes/Viewport.xml:274
+#: doc/classes/Viewport.xml:279
msgid "This quadrant will be split in 4 and used by up to 4 shadow maps."
msgstr ""
-#: doc/classes/Viewport.xml:277
+#: doc/classes/Viewport.xml:282
msgid "This quadrant will be split 16 ways and used by up to 16 shadow maps."
msgstr ""
-#: doc/classes/Viewport.xml:280
+#: doc/classes/Viewport.xml:285
msgid "This quadrant will be split 64 ways and used by up to 64 shadow maps."
msgstr ""
-#: doc/classes/Viewport.xml:283
+#: doc/classes/Viewport.xml:288
msgid ""
"This quadrant will be split 256 ways and used by up to 256 shadow maps. "
"Unless the [member shadow_atlas_size] is very high, the shadows in this "
"quadrant will be very low resolution."
msgstr ""
-#: doc/classes/Viewport.xml:286
+#: doc/classes/Viewport.xml:291
msgid ""
"This quadrant will be split 1024 ways and used by up to 1024 shadow maps. "
"Unless the [member shadow_atlas_size] is very high, the shadows in this "
"quadrant will be very low resolution."
msgstr ""
-#: doc/classes/Viewport.xml:289
+#: doc/classes/Viewport.xml:294
msgid "Represents the size of the [enum ShadowAtlasQuadrantSubdiv] enum."
msgstr ""
-#: doc/classes/Viewport.xml:292
-msgid "Amount of objects in frame."
+#: doc/classes/Viewport.xml:297
+msgid ""
+"Multisample antialiasing mode disabled. This is the default value, and also "
+"the fastest setting."
msgstr ""
-#: doc/classes/Viewport.xml:295
-msgid "Amount of vertices in frame."
+#: doc/classes/Viewport.xml:300
+msgid "Use 2x Multisample Antialiasing."
msgstr ""
-#: doc/classes/Viewport.xml:298
-msgid "Amount of material changes in frame."
+#: doc/classes/Viewport.xml:303
+msgid "Use 4x Multisample Antialiasing."
msgstr ""
-#: doc/classes/Viewport.xml:301
-msgid "Amount of shader changes in frame."
+#: doc/classes/Viewport.xml:306
+msgid ""
+"Use 8x Multisample Antialiasing. Likely unsupported on low-end and older "
+"hardware."
msgstr ""
-#: doc/classes/Viewport.xml:304
-msgid "Amount of surface changes in frame."
+#: doc/classes/Viewport.xml:309
+msgid ""
+"Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end "
+"hardware."
msgstr ""
-#: doc/classes/Viewport.xml:307
-msgid "Amount of draw calls in frame."
+#: doc/classes/Viewport.xml:312
+msgid "Represents the size of the [enum MSAA] enum."
msgstr ""
-#: doc/classes/Viewport.xml:310
-msgid "Represents the size of the [enum RenderInfo] enum."
+#: doc/classes/Viewport.xml:315
+msgid "Do not perform any antialiasing in the full screen post-process."
msgstr ""
-#: doc/classes/Viewport.xml:313
-msgid "Objects are displayed normally."
+#: doc/classes/Viewport.xml:318
+msgid ""
+"Use fast approximate antialiasing. FXAA is a popular screen-space "
+"antialising method, which is fast but will make the image look blurry, "
+"especially at lower resolutions. It can still work relatively well at large "
+"resolutions such as 1440p and 4K."
msgstr ""
-#: doc/classes/Viewport.xml:316
-msgid "Objects are displayed without light information."
+#: doc/classes/Viewport.xml:321
+msgid "Represents the size of the [enum ScreenSpaceAA] enum."
msgstr ""
-#: doc/classes/Viewport.xml:319
-msgid ""
-"Objected are displayed semi-transparent with additive blending so you can "
-"see where they intersect."
+#: doc/classes/Viewport.xml:324
+msgid "Amount of objects in frame."
msgstr ""
-#: doc/classes/Viewport.xml:322
-msgid "Objects are displayed in wireframe style."
+#: doc/classes/Viewport.xml:327
+msgid "Amount of vertices in frame."
+msgstr ""
+
+#: doc/classes/Viewport.xml:330
+msgid "Amount of material changes in frame."
+msgstr ""
+
+#: doc/classes/Viewport.xml:333
+msgid "Amount of shader changes in frame."
+msgstr ""
+
+#: doc/classes/Viewport.xml:336
+msgid "Amount of surface changes in frame."
msgstr ""
#: doc/classes/Viewport.xml:339
-msgid "Multisample anti-aliasing mode disabled. This is the default value."
+msgid "Amount of draw calls in frame."
msgstr ""
#: doc/classes/Viewport.xml:342
-msgid "Use 2x Multisample Antialiasing."
+msgid "Represents the size of the [enum RenderInfo] enum."
msgstr ""
#: doc/classes/Viewport.xml:345
-msgid "Use 4x Multisample Antialiasing."
+msgid "Objects are displayed normally."
msgstr ""
-#: doc/classes/Viewport.xml:348
+#: doc/classes/Viewport.xml:356
+msgid "Objects are displayed in wireframe style."
+msgstr ""
+
+#: doc/classes/Viewport.xml:378
msgid ""
-"Use 8x Multisample Antialiasing. Likely unsupported on low-end and older "
-"hardware."
+"Draws the screen-space ambient occlusion texture instead of the scene so "
+"that you can clearly see how it is affecting objects. In order for this "
+"display mode to work, you must have [member Environment.ssao_enabled] set in "
+"your [WorldEnvironment]."
msgstr ""
-#: doc/classes/Viewport.xml:351
+#: doc/classes/Viewport.xml:384
msgid ""
-"Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end "
-"hardware."
+"Colors each PSSM split for the [DirectionalLight3D]s in the scene a "
+"different color so you can see where the splits are. In order, they will be "
+"colored red, green, blue, and yellow."
+msgstr ""
+
+#: doc/classes/Viewport.xml:387
+msgid ""
+"Draws the decal atlas used by [Decal]s and light projector textures in the "
+"upper left quadrant of the [Viewport]."
+msgstr ""
+
+#: doc/classes/Viewport.xml:402
+msgid "Max value for [enum DefaultCanvasItemTextureFilter] enum."
+msgstr ""
+
+#: doc/classes/Viewport.xml:414
+msgid "Max value for [enum DefaultCanvasItemTextureRepeat] enum."
msgstr ""
#: doc/classes/ViewportTexture.xml:4
@@ -53680,7 +54025,7 @@ msgid ""
msgstr ""
#: doc/classes/VisibilityEnabler2D.xml:4 doc/classes/VisibilityEnabler3D.xml:4
-msgid "Enables certain nodes only when visible."
+msgid "Enables certain nodes only when approximately visible."
msgstr ""
#: doc/classes/VisibilityEnabler2D.xml:7
@@ -53688,78 +54033,82 @@ msgid ""
"The VisibilityEnabler2D will disable [RigidBody2D], [AnimationPlayer], and "
"other nodes when they are not visible. It will only affect nodes with the "
"same root node as the VisibilityEnabler2D, and the root node itself.\n"
-"Note that VisibilityEnabler2D will not affect nodes added after scene "
+"[b]Note:[/b] For performance reasons, VisibilityEnabler2D uses an "
+"approximate heuristic with precision determined by [member ProjectSettings."
+"world/2d/cell_size]. If you need exact visibility checking, use another "
+"method such as adding an [Area2D] node as a child of a [Camera2D] node.\n"
+"[b]Note:[/b] VisibilityEnabler2D will not affect nodes added after scene "
"initialization."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:19
-#: doc/classes/VisibilityEnabler3D.xml:19
+#: doc/classes/VisibilityEnabler2D.xml:20
+#: doc/classes/VisibilityEnabler3D.xml:20
msgid ""
"Returns whether the enabler identified by given [enum Enabler] constant is "
"active."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:30
-#: doc/classes/VisibilityEnabler3D.xml:30
+#: doc/classes/VisibilityEnabler2D.xml:31
+#: doc/classes/VisibilityEnabler3D.xml:31
msgid ""
"Sets active state of the enabler identified by given [enum Enabler] constant."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:36
+#: doc/classes/VisibilityEnabler2D.xml:37
msgid "If [code]true[/code], [RigidBody2D] nodes will be paused."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:39
+#: doc/classes/VisibilityEnabler2D.xml:40
msgid "If [code]true[/code], [AnimatedSprite2D] nodes will be paused."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:42
-#: doc/classes/VisibilityEnabler3D.xml:39
+#: doc/classes/VisibilityEnabler2D.xml:43
+#: doc/classes/VisibilityEnabler3D.xml:40
msgid "If [code]true[/code], [AnimationPlayer] nodes will be paused."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:45
+#: doc/classes/VisibilityEnabler2D.xml:46
msgid "If [code]true[/code], [GPUParticles2D] nodes will be paused."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:48
+#: doc/classes/VisibilityEnabler2D.xml:49
msgid ""
"If [code]true[/code], the parent's [method Node._physics_process] will be "
"stopped."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:51
+#: doc/classes/VisibilityEnabler2D.xml:52
msgid ""
"If [code]true[/code], the parent's [method Node._process] will be stopped."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:56
-#: doc/classes/VisibilityEnabler3D.xml:44
+#: doc/classes/VisibilityEnabler2D.xml:57
+#: doc/classes/VisibilityEnabler3D.xml:45
msgid "This enabler will pause [AnimationPlayer] nodes."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:59
+#: doc/classes/VisibilityEnabler2D.xml:60
msgid "This enabler will freeze [RigidBody2D] nodes."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:62
+#: doc/classes/VisibilityEnabler2D.xml:63
msgid "This enabler will stop [GPUParticles2D] nodes."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:65
+#: doc/classes/VisibilityEnabler2D.xml:66
msgid "This enabler will stop the parent's _process function."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:68
+#: doc/classes/VisibilityEnabler2D.xml:69
msgid "This enabler will stop the parent's _physics_process function."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:71
+#: doc/classes/VisibilityEnabler2D.xml:72
msgid "This enabler will stop [AnimatedSprite2D] nodes animations."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:74
-#: doc/classes/VisibilityEnabler3D.xml:50
+#: doc/classes/VisibilityEnabler2D.xml:75
+#: doc/classes/VisibilityEnabler3D.xml:51
msgid "Represents the size of the [enum Enabler] enum."
msgstr ""
@@ -53768,31 +54117,39 @@ msgid ""
"The VisibilityEnabler3D will disable [RigidBody3D] and [AnimationPlayer] "
"nodes when they are not visible. It will only affect other nodes within the "
"same scene as the VisibilityEnabler3D itself.\n"
-"Note that VisibilityEnabler3D will not affect nodes added after scene "
+"[b]Note:[/b] VisibilityEnabler3D uses an approximate heuristic for "
+"performance reasons. It doesn't take walls and other occlusion into account. "
+"If you need exact visibility checking, use another method such as adding an "
+"[Area3D] node as a child of a [Camera3D] node.\n"
+"[b]Note:[/b] VisibilityEnabler3D will not affect nodes added after scene "
"initialization."
msgstr ""
-#: doc/classes/VisibilityEnabler3D.xml:36
+#: doc/classes/VisibilityEnabler3D.xml:37
msgid "If [code]true[/code], [RigidBody3D] nodes will be paused."
msgstr ""
-#: doc/classes/VisibilityEnabler3D.xml:47
+#: doc/classes/VisibilityEnabler3D.xml:48
msgid "This enabler will freeze [RigidBody3D] nodes."
msgstr ""
#: doc/classes/VisibilityNotifier2D.xml:4
#: doc/classes/VisibilityNotifier3D.xml:4
-msgid "Detects when the node is visible on screen."
+msgid "Detects approximately when the node is visible on screen."
msgstr ""
#: doc/classes/VisibilityNotifier2D.xml:7
msgid ""
"The VisibilityNotifier2D detects when it is visible on the screen. It also "
"notifies when its bounding rectangle enters or exits the screen or a "
-"viewport."
+"viewport.\n"
+"[b]Note:[/b] For performance reasons, VisibilityNotifier2D uses an "
+"approximate heuristic with precision determined by [member ProjectSettings."
+"world/2d/cell_size]. If you need exact visibility checking, use another "
+"method such as adding an [Area2D] node as a child of a [Camera2D] node."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:16
+#: doc/classes/VisibilityNotifier2D.xml:17
msgid ""
"If [code]true[/code], the bounding rectangle is on the screen.\n"
"[b]Note:[/b] It takes one frame for the node's visibility to be assessed "
@@ -53801,23 +54158,23 @@ msgid ""
"pass."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:23
+#: doc/classes/VisibilityNotifier2D.xml:24
msgid "The VisibilityNotifier2D's bounding rectangle."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:29
+#: doc/classes/VisibilityNotifier2D.xml:30
msgid "Emitted when the VisibilityNotifier2D enters the screen."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:34
+#: doc/classes/VisibilityNotifier2D.xml:35
msgid "Emitted when the VisibilityNotifier2D exits the screen."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:41
+#: doc/classes/VisibilityNotifier2D.xml:42
msgid "Emitted when the VisibilityNotifier2D enters a [Viewport]'s view."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:48
+#: doc/classes/VisibilityNotifier2D.xml:49
msgid "Emitted when the VisibilityNotifier2D exits a [Viewport]'s view."
msgstr ""
@@ -53825,10 +54182,14 @@ msgstr ""
msgid ""
"The VisibilityNotifier3D detects when it is visible on the screen. It also "
"notifies when its bounding rectangle enters or exits the screen or a "
-"[Camera3D]'s view."
+"[Camera3D]'s view.\n"
+"[b]Note:[/b] VisibilityNotifier3D uses an approximate heuristic for "
+"performance reasons. It doesn't take walls and other occlusion into account. "
+"If you need exact visibility checking, use another method such as adding an "
+"[Area3D] node as a child of a [Camera3D] node."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:16
+#: doc/classes/VisibilityNotifier3D.xml:17
msgid ""
"If [code]true[/code], the bounding box is on the screen.\n"
"[b]Note:[/b] It takes one frame for the node's visibility to be assessed "
@@ -53837,23 +54198,23 @@ msgid ""
"pass."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:23
+#: doc/classes/VisibilityNotifier3D.xml:24
msgid "The VisibilityNotifier3D's bounding box."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:31
+#: doc/classes/VisibilityNotifier3D.xml:32
msgid "Emitted when the VisibilityNotifier3D enters a [Camera3D]'s view."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:38
+#: doc/classes/VisibilityNotifier3D.xml:39
msgid "Emitted when the VisibilityNotifier3D exits a [Camera3D]'s view."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:43
+#: doc/classes/VisibilityNotifier3D.xml:44
msgid "Emitted when the VisibilityNotifier3D enters the screen."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:48
+#: doc/classes/VisibilityNotifier3D.xml:49
msgid "Emitted when the VisibilityNotifier3D exits the screen."
msgstr ""
@@ -56445,7 +56806,7 @@ msgstr ""
msgid "The background of the area below the grabber."
msgstr ""
-#: doc/classes/VSlider.xml:33
+#: doc/classes/VSlider.xml:35
msgid ""
"The background for the whole slider. Determines the width of the "
"[code]grabber_area[/code]."
@@ -57427,6 +57788,666 @@ msgstr ""
msgid "Unknown node."
msgstr ""
+#: doc/classes/XRAnchor3D.xml:4
+msgid "An anchor point in AR space."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:7
+msgid ""
+"The [XRAnchor3D] point is a spatial node that maps a real world location "
+"identified by the AR platform to a position within the game world. For "
+"example, as long as plane detection in ARKit is on, ARKit will identify and "
+"update the position of planes (tables, floors, etc) and create anchors for "
+"them.\n"
+"This node is mapped to one of the anchors through its unique ID. When you "
+"receive a signal that a new anchor is available, you should add this node to "
+"your scene for that anchor. You can predefine nodes and set the ID; the "
+"nodes will simply remain on 0,0,0 until a plane is recognized.\n"
+"Keep in mind that, as long as plane detection is enabled, the size, placing "
+"and orientation of an anchor will be updated as the detection logic learns "
+"more about the real world out there especially if only part of the surface "
+"is in view."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:18
+msgid "Returns the name given to this anchor."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:25
+msgid ""
+"Returns [code]true[/code] if the anchor is being tracked and [code]false[/"
+"code] if no anchor with this ID is currently known."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:32
+msgid ""
+"If provided by the [XRInterface], this returns a mesh object for the anchor. "
+"For an anchor, this can be a shape related to the object being tracked or it "
+"can be a mesh that provides topology related to the anchor and can be used "
+"to create shadows/reflections on surfaces or for generating collision shapes."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:39
+msgid ""
+"Returns a plane aligned with our anchor; handy for intersection testing."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:46
+msgid ""
+"Returns the estimated size of the plane that was detected. Say when the "
+"anchor relates to a table in the real world, this is the estimated size of "
+"the surface of that table."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:52
+msgid ""
+"The anchor's ID. You can set this before the anchor itself exists. The first "
+"anchor gets an ID of [code]1[/code], the second an ID of [code]2[/code], "
+"etc. When anchors get removed, the engine can then assign the corresponding "
+"ID to new anchors. The most common situation where anchors \"disappear\" is "
+"when the AR server identifies that two anchors represent different parts of "
+"the same plane and merges them."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:60
+msgid ""
+"Emitted when the mesh associated with the anchor changes or when one becomes "
+"available. This is especially important for topology that is constantly "
+"being [code]mesh_updated[/code]."
+msgstr ""
+
+#: doc/classes/XRCamera3D.xml:4
+msgid ""
+"A camera node with a few overrules for AR/VR applied, such as location "
+"tracking."
+msgstr ""
+
+#: doc/classes/XRCamera3D.xml:7
+msgid ""
+"This is a helper spatial node for our camera; note that, if stereoscopic "
+"rendering is applicable (VR-HMD), most of the camera properties are ignored, "
+"as the HMD information overrides them. The only properties that can be "
+"trusted are the near and far planes.\n"
+"The position and orientation of this node is automatically updated by the XR "
+"Server to represent the location of the HMD if such tracking is available "
+"and can thus be used by game logic. Note that, in contrast to the XR "
+"Controller, the render thread has access to the most up-to-date tracking "
+"data of the HMD and the location of the XRCamera3D can lag a few "
+"milliseconds behind what is used for rendering as a result."
+msgstr ""
+
+#: doc/classes/XRCamera3D.xml:11 doc/classes/XRController3D.xml:12
+#: doc/classes/XRInterface.xml:11 doc/classes/XROrigin3D.xml:13
+#: doc/classes/XRPositionalTracker.xml:12 doc/classes/XRServer.xml:10
+msgid "https://docs.godotengine.org/en/latest/tutorials/vr/index.html"
+msgstr ""
+
+#: doc/classes/XRController3D.xml:4
+msgid "A spatial node representing a spatially-tracked controller."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:7
+msgid ""
+"This is a helper spatial node that is linked to the tracking of controllers. "
+"It also offers several handy passthroughs to the state of buttons and such "
+"on the controllers.\n"
+"Controllers are linked by their ID. You can create controller nodes before "
+"the controllers are available. If your game always uses two controllers (one "
+"for each hand), you can predefine the controllers with ID 1 and 2; they will "
+"become active as soon as the controllers are identified. If you expect "
+"additional controllers to be used, you should react to the signals and add "
+"XRController3D nodes to your scene.\n"
+"The position of the controller node is automatically updated by the "
+"[XRServer]. This makes this node ideal to add child nodes to visualize the "
+"controller."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:19
+msgid ""
+"If active, returns the name of the associated controller if provided by the "
+"AR/VR SDK used."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:26
+msgid ""
+"Returns the hand holding this controller, if known. See [enum "
+"XRPositionalTracker.TrackerHand]."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:33
+msgid ""
+"Returns [code]true[/code] if the bound controller is active. XR systems "
+"attempt to track active controllers."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:42
+msgid ""
+"Returns the value of the given axis for things like triggers, touchpads, "
+"etc. that are embedded into the controller."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:49
+msgid ""
+"Returns the ID of the joystick object bound to this. Every controller "
+"tracked by the [XRServer] that has buttons and axis will also be registered "
+"as a joystick within Godot. This means that all the normal joystick tracking "
+"and input mapping will work for buttons and axis found on the AR/VR "
+"controllers. This ID is purely offered as information so you can link up the "
+"controller with its joystick entry."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:56
+msgid ""
+"If provided by the [XRInterface], this returns a mesh associated with the "
+"controller. This can be used to visualize the controller."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:65
+msgid ""
+"Returns [code]true[/code] if the button at index [code]button[/code] is "
+"pressed. See [enum JoyButtonList]."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:71
+msgid ""
+"The controller's ID.\n"
+"A controller ID of 0 is unbound and will always result in an inactive node. "
+"Controller ID 1 is reserved for the first controller that identifies itself "
+"as the left-hand controller and ID 2 is reserved for the first controller "
+"that identifies itself as the right-hand controller.\n"
+"For any other controller that the [XRServer] detects, we continue with "
+"controller ID 3.\n"
+"When a controller is turned off, its slot is freed. This ensures controllers "
+"will keep the same ID even when controllers with lower IDs are turned off."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:77
+msgid ""
+"The degree to which the controller vibrates. Ranges from [code]0.0[/code] to "
+"[code]1.0[/code] with precision [code].01[/code]. If changed, updates "
+"[member XRPositionalTracker.rumble] accordingly.\n"
+"This is a useful property to animate if you want the controller to vibrate "
+"for a limited duration."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:86
+msgid "Emitted when a button on this controller is pressed."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:93
+msgid "Emitted when a button on this controller is released."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:100
+msgid ""
+"Emitted when the mesh associated with the controller changes or when one "
+"becomes available. Generally speaking this will be a static mesh after "
+"becoming available."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:4
+msgid "Base class for an AR/VR interface implementation."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:7
+msgid ""
+"This class needs to be implemented to make an AR or VR platform available to "
+"Godot and these should be implemented as C++ modules or GDNative modules "
+"(note that for GDNative the subclass XRScriptInterface should be used). Part "
+"of the interface is exposed to GDScript so you can detect, enable and "
+"configure an AR or VR platform.\n"
+"Interfaces should be written in such a way that simply enabling them will "
+"give us a working setup. You can query the available interfaces through "
+"[XRServer]."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:18
+msgid ""
+"If this is an AR interface that requires displaying a camera feed as the "
+"background, this method returns the feed ID in the [CameraServer] for this "
+"interface."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:25
+msgid ""
+"Returns a combination of [enum Capabilities] flags providing information "
+"about the capabilities of this interface."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:32
+msgid "Returns the name of this interface (OpenVR, OpenHMD, ARKit, etc)."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:39
+msgid ""
+"Returns the resolution at which we should render our intermediate results "
+"before things like lens distortion are applied by the VR platform."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:46
+msgid ""
+"If supported, returns the status of our tracking. This will allow you to "
+"provide feedback to the user whether there are issues with positional "
+"tracking."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:53
+msgid ""
+"Call this to initialize this interface. The first interface that is "
+"initialized is identified as the primary interface and it will be used for "
+"rendering output.\n"
+"After initializing the interface you want to use you then need to enable the "
+"AR/VR mode of a viewport and rendering should commence.\n"
+"[b]Note:[/b] You must enable the AR/VR mode on the main viewport for any "
+"device that uses the main output of Godot, such as for mobile VR.\n"
+"If you do this for a platform that handles its own output (such as OpenVR) "
+"Godot will show just one eye without distortion on screen. Alternatively, "
+"you can add a separate viewport node to your scene and enable AR/VR on that "
+"viewport. It will be used to output to the HMD, leaving you free to do "
+"anything you like in the main window, such as using a separate camera as a "
+"spectator camera or rendering something completely different.\n"
+"While currently not used, you can activate additional interfaces. You may "
+"wish to do this if you want to track controllers from other platforms. "
+"However, at this point in time only one interface can render to an HMD."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:64
+msgid ""
+"Returns [code]true[/code] if the current output of this interface is in "
+"stereo."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:71
+msgid "Turns the interface off."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:77
+msgid "On an AR interface, [code]true[/code] if anchor detection is enabled."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:80
+msgid "[code]true[/code] if this interface been initialized."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:83
+msgid "[code]true[/code] if this is the primary interface."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:88
+msgid "No XR capabilities."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:91
+msgid ""
+"This interface can work with normal rendering output (non-HMD based AR)."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:94
+msgid "This interface supports stereoscopic rendering."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:97
+msgid "This interface supports AR (video background and real world tracking)."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:100
+msgid ""
+"This interface outputs to an external device. If the main viewport is used, "
+"the on screen output is an unmodified buffer of either the left or right eye "
+"(stretched if the viewport size is not changed to the same aspect ratio of "
+"[method get_render_targetsize]). Using a separate viewport node frees up the "
+"main viewport for other purposes."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:103
+msgid ""
+"Mono output, this is mostly used internally when retrieving positioning "
+"information for our camera node or when stereo scopic rendering is not "
+"supported."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:106
+msgid ""
+"Left eye output, this is mostly used internally when rendering the image for "
+"the left eye and obtaining positioning and projection information."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:109
+msgid ""
+"Right eye output, this is mostly used internally when rendering the image "
+"for the right eye and obtaining positioning and projection information."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:112
+msgid "Tracking is behaving as expected."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:115
+msgid ""
+"Tracking is hindered by excessive motion (the player is moving faster than "
+"tracking can keep up)."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:118
+msgid ""
+"Tracking is hindered by insufficient features, it's too dark (for camera-"
+"based tracking), player is blocked, etc."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:121
+msgid ""
+"We don't know the status of the tracking or this interface does not provide "
+"feedback."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:124
+msgid ""
+"Tracking is not functional (camera not plugged in or obscured, lighthouses "
+"turned off, etc.)."
+msgstr ""
+
+#: modules/gdnative/doc_classes/XRInterfaceGDNative.xml:4
+msgid "GDNative wrapper for an XR interface."
+msgstr ""
+
+#: modules/gdnative/doc_classes/XRInterfaceGDNative.xml:7
+msgid ""
+"This is a wrapper class for GDNative implementations of the XR interface. To "
+"use a GDNative XR interface, simply instantiate this object and set your "
+"GDNative library containing the XR interface implementation."
+msgstr ""
+
+#: doc/classes/XROrigin3D.xml:4
+msgid "The origin point in AR/VR."
+msgstr ""
+
+#: doc/classes/XROrigin3D.xml:7
+msgid ""
+"This is a special node within the AR/VR system that maps the physical "
+"location of the center of our tracking space to the virtual location within "
+"our game world.\n"
+"There should be only one of these nodes in your scene and you must have one. "
+"All the XRCamera3D, XRController3D and XRAnchor3D nodes should be direct "
+"children of this node for spatial tracking to work correctly.\n"
+"It is the position of this node that you update when your character needs to "
+"move through your game world while we're not moving in the real world. "
+"Movement in the real world is always in relation to this origin point.\n"
+"For example, if your character is driving a car, the XROrigin3D node should "
+"be a child node of this car. Or, if you're implementing a teleport system to "
+"move your character, you should change the position of this node."
+msgstr ""
+
+#: doc/classes/XROrigin3D.xml:19
+msgid ""
+"Allows you to adjust the scale to your game's units. Most AR/VR platforms "
+"assume a scale of 1 game world unit = 1 real world meter.\n"
+"[b]Note:[/b] This method is a passthrough to the [XRServer] itself."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:4
+msgid "A tracked object."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:7
+msgid ""
+"An instance of this object represents a device that is tracked, such as a "
+"controller or anchor point. HMDs aren't represented here as they are handled "
+"internally.\n"
+"As controllers are turned on and the AR/VR interface detects them, instances "
+"of this object are automatically added to this list of active tracking "
+"objects accessible through the [XRServer].\n"
+"The [XRController3D] and [XRAnchor3D] both consume objects of this type and "
+"should be used in your project. The positional trackers are just under-the-"
+"hood objects that make this all work. These are mostly exposed so that "
+"GDNative-based interfaces can interact with them."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:19
+msgid ""
+"Returns the hand holding this tracker, if known. See [enum TrackerHand] "
+"constants."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:26
+msgid ""
+"If this is a controller that is being tracked, the controller will also be "
+"represented by a joystick entry with this ID."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:33
+msgid ""
+"Returns the mesh related to a controller or anchor point if one is available."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:40
+msgid "Returns the controller or anchor point's name if available."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:47
+msgid "Returns the controller's orientation matrix."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:54
+msgid "Returns the world-space controller position."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:61
+msgid ""
+"Returns the internal tracker ID. This uniquely identifies the tracker per "
+"tracker type and matches the ID you need to specify for nodes such as the "
+"[XRController3D] and [XRAnchor3D] nodes."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:68
+msgid "Returns [code]true[/code] if this device tracks orientation."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:75
+msgid "Returns [code]true[/code] if this device tracks position."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:84
+msgid "Returns the transform combining this device's orientation and position."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:91
+msgid "Returns the tracker's type."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:97
+msgid ""
+"The degree to which the tracker rumbles. Ranges from [code]0.0[/code] to "
+"[code]1.0[/code] with precision [code].01[/code]."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:102
+msgid "The hand this tracker is held in is unknown or not applicable."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:105
+msgid "This tracker is the left hand controller."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:108
+msgid "This tracker is the right hand controller."
+msgstr ""
+
+#: doc/classes/XRServer.xml:4
+msgid "Server for AR and VR features."
+msgstr ""
+
+#: doc/classes/XRServer.xml:7
+msgid ""
+"The AR/VR server is the heart of our Advanced and Virtual Reality solution "
+"and handles all the processing."
+msgstr ""
+
+#: doc/classes/XRServer.xml:21
+msgid ""
+"This is an important function to understand correctly. AR and VR platforms "
+"all handle positioning slightly differently.\n"
+"For platforms that do not offer spatial tracking, our origin point (0,0,0) "
+"is the location of our HMD, but you have little control over the direction "
+"the player is facing in the real world.\n"
+"For platforms that do offer spatial tracking, our origin point depends very "
+"much on the system. For OpenVR, our origin point is usually the center of "
+"the tracking space, on the ground. For other platforms, it's often the "
+"location of the tracking camera.\n"
+"This method allows you to center your tracker on the location of the HMD. It "
+"will take the current location of the HMD and use that to adjust all your "
+"tracking data; in essence, realigning the real world to your player's "
+"current position in the game world.\n"
+"For this method to produce usable results, tracking information must be "
+"available. This often takes a few frames after starting your game.\n"
+"You should call this method after a few seconds have passed. For instance, "
+"when the user requests a realignment of the display holding a designated "
+"button on a controller for a short period of time, or when implementing a "
+"teleport mechanism."
+msgstr ""
+
+#: doc/classes/XRServer.xml:35
+msgid ""
+"Finds an interface by its name. For instance, if your project uses "
+"capabilities of an AR/VR platform, you can find the interface for that "
+"platform by name and initialize it."
+msgstr ""
+
+#: doc/classes/XRServer.xml:42
+msgid "Returns the primary interface's transformation."
+msgstr ""
+
+#: doc/classes/XRServer.xml:51
+msgid ""
+"Returns the interface registered at a given index in our list of interfaces."
+msgstr ""
+
+#: doc/classes/XRServer.xml:58
+msgid ""
+"Returns the number of interfaces currently registered with the AR/VR server. "
+"If your project supports multiple AR/VR platforms, you can look through the "
+"available interface, and either present the user with a selection or simply "
+"try to initialize each interface and use the first one that returns "
+"[code]true[/code]."
+msgstr ""
+
+#: doc/classes/XRServer.xml:65
+msgid ""
+"Returns a list of available interfaces the ID and name of each interface."
+msgstr ""
+
+#: doc/classes/XRServer.xml:72
+msgid ""
+"Returns the absolute timestamp (in μs) of the last [XRServer] commit of the "
+"AR/VR eyes to [RenderingServer]. The value comes from an internal call to "
+"[method OS.get_ticks_usec]."
+msgstr ""
+
+#: doc/classes/XRServer.xml:79
+msgid ""
+"Returns the duration (in μs) of the last frame. This is computed as the "
+"difference between [method get_last_commit_usec] and [method "
+"get_last_process_usec] when committing."
+msgstr ""
+
+#: doc/classes/XRServer.xml:86
+msgid ""
+"Returns the absolute timestamp (in μs) of the last [XRServer] process "
+"callback. The value comes from an internal call to [method OS."
+"get_ticks_usec]."
+msgstr ""
+
+#: doc/classes/XRServer.xml:93
+msgid ""
+"Returns the reference frame transform. Mostly used internally and exposed "
+"for GDNative build interfaces."
+msgstr ""
+
+#: doc/classes/XRServer.xml:102
+msgid "Returns the positional tracker at the given ID."
+msgstr ""
+
+#: doc/classes/XRServer.xml:109
+msgid "Returns the number of trackers currently registered."
+msgstr ""
+
+#: doc/classes/XRServer.xml:115
+msgid "The primary [XRInterface] currently bound to the [XRServer]."
+msgstr ""
+
+#: doc/classes/XRServer.xml:118
+msgid ""
+"Allows you to adjust the scale to your game's units. Most AR/VR platforms "
+"assume a scale of 1 game world unit = 1 real world meter."
+msgstr ""
+
+#: doc/classes/XRServer.xml:126
+msgid "Emitted when a new interface has been added."
+msgstr ""
+
+#: doc/classes/XRServer.xml:133
+msgid "Emitted when an interface is removed."
+msgstr ""
+
+#: doc/classes/XRServer.xml:144
+msgid ""
+"Emitted when a new tracker has been added. If you don't use a fixed number "
+"of controllers or if you're using [XRAnchor3D]s for an AR solution, it is "
+"important to react to this signal to add the appropriate [XRController3D] or "
+"[XRAnchor3D] nodes related to this new tracker."
+msgstr ""
+
+#: doc/classes/XRServer.xml:155
+msgid ""
+"Emitted when a tracker is removed. You should remove any [XRController3D] or "
+"[XRAnchor3D] points if applicable. This is not mandatory, the nodes simply "
+"become inactive and will be made active again when a new tracker becomes "
+"available (i.e. a new controller is switched on that takes the place of the "
+"previous one)."
+msgstr ""
+
+#: doc/classes/XRServer.xml:161
+msgid "The tracker tracks the location of a controller."
+msgstr ""
+
+#: doc/classes/XRServer.xml:164
+msgid "The tracker tracks the location of a base station."
+msgstr ""
+
+#: doc/classes/XRServer.xml:167
+msgid "The tracker tracks the location and size of an AR anchor."
+msgstr ""
+
+#: doc/classes/XRServer.xml:170
+msgid "Used internally to filter trackers of any known type."
+msgstr ""
+
+#: doc/classes/XRServer.xml:173
+msgid "Used internally if we haven't set the tracker type yet."
+msgstr ""
+
+#: doc/classes/XRServer.xml:176
+msgid "Used internally to select all trackers."
+msgstr ""
+
+#: doc/classes/XRServer.xml:179
+msgid ""
+"Fully reset the orientation of the HMD. Regardless of what direction the "
+"user is looking to in the real world. The user will look dead ahead in the "
+"virtual world."
+msgstr ""
+
+#: doc/classes/XRServer.xml:182
+msgid ""
+"Resets the orientation but keeps the tilt of the device. So if we're looking "
+"down, we keep looking down but heading will be reset."
+msgstr ""
+
+#: doc/classes/XRServer.xml:185
+msgid ""
+"Does not reset the orientation of the HMD, only the position of the player "
+"gets centered."
+msgstr ""
+
#: doc/classes/YSort.xml:4
msgid "Sort all child nodes based on their Y positions."
msgstr ""
diff --git a/doc/translations/fr.po b/doc/translations/fr.po
index 6926376c05..57466d0b04 100644
--- a/doc/translations/fr.po
+++ b/doc/translations/fr.po
@@ -9,15 +9,15 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine class reference\n"
"Report-Msgid-Bugs-To: https://github.com/godotengine/godot\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
"POT-Creation-Date: \n"
"PO-Revision-Date: \n"
"Last-Translator: Rémi Verschelde <remi@godotengine.org>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot-classes/fr/>\n"
"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.3\n"
#: doc/tools/makerst.py
@@ -490,7 +490,7 @@ msgid ""
"[float], the return value is a [float].\n"
"If both are of the same vector type ([Vector2], [Vector3] or [Color]), the "
"return value will be of the same type ([code]lerp[/code] then calls the "
-"vector type's [code]linear_interpolate[/code] method).\n"
+"vector type's [code]lerp[/code] method).\n"
"[codeblock]\n"
"lerp(0, 4, 0.75) # Returns 3.0\n"
"lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Returns Vector2(2, 3.5)\n"
@@ -1214,19 +1214,19 @@ msgid ""
msgstr ""
#: doc/classes/@GlobalScope.xml:16
-msgid "The [ARVRServer] singleton."
+msgid "The [AudioServer] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:19
-msgid "The [AudioServer] singleton."
+msgid "The [CameraServer] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:22
-msgid "The [CameraServer] singleton."
+msgid "The [ClassDB] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:25
-msgid "The [ClassDB] singleton."
+msgid "The [DisplayServer] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:28
@@ -1238,90 +1238,89 @@ msgid "The [Geometry] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:34
-msgid ""
-"The [GodotSharp] singleton. Only available when using Godot's Mono build."
+msgid "The [IP] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:37
-msgid "The [IP] singleton."
+msgid "The [Input] singleton."
msgstr ""
#: doc/classes/@GlobalScope.xml:40
-msgid "The [InputFilter] singleton."
-msgstr ""
-
-#: doc/classes/@GlobalScope.xml:43
msgid "The [InputMap] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:46
+#: doc/classes/@GlobalScope.xml:43
msgid "The [JSON] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:49
+#: doc/classes/@GlobalScope.xml:46
msgid ""
"The [JavaClassWrapper] singleton.\n"
"[b]Note:[/b] Only implemented on Android."
msgstr ""
-#: doc/classes/@GlobalScope.xml:53
+#: doc/classes/@GlobalScope.xml:50
msgid ""
"The [JavaScript] singleton.\n"
"[b]Note:[/b] Only implemented on HTML5."
msgstr ""
-#: doc/classes/@GlobalScope.xml:57
+#: doc/classes/@GlobalScope.xml:54
msgid "The [Marshalls] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:60
+#: doc/classes/@GlobalScope.xml:57
msgid "The [NavigationMeshGenerator] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:63 doc/classes/@GlobalScope.xml:66
+#: doc/classes/@GlobalScope.xml:60 doc/classes/@GlobalScope.xml:63
msgid "The [NavigationServer2D] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:69
+#: doc/classes/@GlobalScope.xml:66
msgid "The [OS] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:72
+#: doc/classes/@GlobalScope.xml:69
msgid "The [Performance] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:75
+#: doc/classes/@GlobalScope.xml:72
msgid "The [PhysicsServer2D] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:78
+#: doc/classes/@GlobalScope.xml:75
msgid "The [PhysicsServer3D] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:81
+#: doc/classes/@GlobalScope.xml:78
msgid "The [ProjectSettings] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:84
+#: doc/classes/@GlobalScope.xml:81
msgid "The [RenderingServer] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:87
+#: doc/classes/@GlobalScope.xml:84
msgid "The [ResourceLoader] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:90
+#: doc/classes/@GlobalScope.xml:87
msgid "The [ResourceSaver] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:93
+#: doc/classes/@GlobalScope.xml:90
msgid "The [TranslationServer] singleton."
msgstr ""
-#: doc/classes/@GlobalScope.xml:96
+#: doc/classes/@GlobalScope.xml:93
msgid "The [VisualScriptEditor] singleton."
msgstr ""
+#: doc/classes/@GlobalScope.xml:96
+msgid "The [XRServer] singleton."
+msgstr ""
+
#: doc/classes/@GlobalScope.xml:101
msgid "Left margin, usually used for [Control] or [StyleBox]-derived classes."
msgstr ""
@@ -1404,7 +1403,7 @@ msgid "Tab key."
msgstr ""
#: doc/classes/@GlobalScope.xml:158
-msgid "Shift+Tab key."
+msgid "Shift + Tab key."
msgstr ""
#: doc/classes/@GlobalScope.xml:161
@@ -3134,305 +3133,311 @@ msgid "Used to categorize properties together in the editor."
msgstr ""
#: doc/classes/@GlobalScope.xml:1424
-msgid "The property does not save its state in [PackedScene]."
+msgid ""
+"Used to group properties together in the editor in a subgroup (under a "
+"group)."
msgstr ""
#: doc/classes/@GlobalScope.xml:1427
-msgid "Editing the property prompts the user for restarting the editor."
+msgid "The property does not save its state in [PackedScene]."
msgstr ""
#: doc/classes/@GlobalScope.xml:1430
+msgid "Editing the property prompts the user for restarting the editor."
+msgstr ""
+
+#: doc/classes/@GlobalScope.xml:1433
msgid ""
"The property is a script variable which should be serialized and saved in "
"the scene file."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1433
+#: doc/classes/@GlobalScope.xml:1436
msgid "Default usage (storage, editor and network)."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1436
+#: doc/classes/@GlobalScope.xml:1439
msgid ""
"Default usage for translatable strings (storage, editor, network and "
"internationalized)."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1439
+#: doc/classes/@GlobalScope.xml:1442
msgid ""
"Default usage but without showing the property in the editor (storage, "
"network)."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1442
+#: doc/classes/@GlobalScope.xml:1445
msgid "Flag for a normal method."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1445
+#: doc/classes/@GlobalScope.xml:1448
msgid "Flag for an editor method."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1448 doc/classes/@GlobalScope.xml:1454
-#: doc/classes/@GlobalScope.xml:1460
+#: doc/classes/@GlobalScope.xml:1451 doc/classes/@GlobalScope.xml:1457
+#: doc/classes/@GlobalScope.xml:1463
msgid "Deprecated method flag, unused."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1451
+#: doc/classes/@GlobalScope.xml:1454
msgid "Flag for a constant method."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1457
+#: doc/classes/@GlobalScope.xml:1460
msgid "Flag for a virtual method."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1463
+#: doc/classes/@GlobalScope.xml:1466
msgid "Default method flags."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1466
+#: doc/classes/@GlobalScope.xml:1469
msgid "Variable is [code]null[/code]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1469
+#: doc/classes/@GlobalScope.xml:1472
msgid "Variable is of type [bool]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1472
+#: doc/classes/@GlobalScope.xml:1475
msgid "Variable is of type [int]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1475
+#: doc/classes/@GlobalScope.xml:1478
msgid "Variable is of type [float] (real)."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1478
+#: doc/classes/@GlobalScope.xml:1481
msgid "Variable is of type [String]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1481
+#: doc/classes/@GlobalScope.xml:1484
msgid "Variable is of type [Vector2]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1484
+#: doc/classes/@GlobalScope.xml:1487
msgid "Variable is of type [Vector2i]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1487
+#: doc/classes/@GlobalScope.xml:1490
msgid "Variable is of type [Rect2]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1490
+#: doc/classes/@GlobalScope.xml:1493
msgid "Variable is of type [Rect2i]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1493
+#: doc/classes/@GlobalScope.xml:1496
msgid "Variable is of type [Vector3]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1496
+#: doc/classes/@GlobalScope.xml:1499
msgid "Variable is of type [Vector3i]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1499
+#: doc/classes/@GlobalScope.xml:1502
msgid "Variable is of type [Transform2D]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1502
+#: doc/classes/@GlobalScope.xml:1505
msgid "Variable is of type [Plane]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1505
+#: doc/classes/@GlobalScope.xml:1508
msgid "Variable is of type [Quat]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1508
+#: doc/classes/@GlobalScope.xml:1511
msgid "Variable is of type [AABB]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1511
+#: doc/classes/@GlobalScope.xml:1514
msgid "Variable is of type [Basis]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1514
+#: doc/classes/@GlobalScope.xml:1517
msgid "Variable is of type [Transform]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1517
+#: doc/classes/@GlobalScope.xml:1520
msgid "Variable is of type [Color]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1520
+#: doc/classes/@GlobalScope.xml:1523
msgid "Variable is of type [StringName]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1523
+#: doc/classes/@GlobalScope.xml:1526
msgid "Variable is of type [NodePath]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1526
+#: doc/classes/@GlobalScope.xml:1529
msgid "Variable is of type [RID]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1529
+#: doc/classes/@GlobalScope.xml:1532
msgid "Variable is of type [Object]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1532
+#: doc/classes/@GlobalScope.xml:1535
msgid "Variable is of type [Callable]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1535
+#: doc/classes/@GlobalScope.xml:1538
msgid "Variable is of type [Signal]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1538
+#: doc/classes/@GlobalScope.xml:1541
msgid "Variable is of type [Dictionary]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1541
+#: doc/classes/@GlobalScope.xml:1544
msgid "Variable is of type [Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1544
+#: doc/classes/@GlobalScope.xml:1547
msgid "Variable is of type [PackedByteArray]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1547
+#: doc/classes/@GlobalScope.xml:1550
msgid "Variable is of type [PackedInt32Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1550
+#: doc/classes/@GlobalScope.xml:1553
msgid "Variable is of type [PackedInt64Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1553
+#: doc/classes/@GlobalScope.xml:1556
msgid "Variable is of type [PackedFloat32Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1556
+#: doc/classes/@GlobalScope.xml:1559
msgid "Variable is of type [PackedFloat64Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1559
+#: doc/classes/@GlobalScope.xml:1562
msgid "Variable is of type [PackedStringArray]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1562
+#: doc/classes/@GlobalScope.xml:1565
msgid "Variable is of type [PackedVector2Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1565
+#: doc/classes/@GlobalScope.xml:1568
msgid "Variable is of type [PackedVector3Array]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1568
+#: doc/classes/@GlobalScope.xml:1571
msgid "Variable is of type [PackedColorArray]."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1571
+#: doc/classes/@GlobalScope.xml:1574
msgid "Represents the size of the [enum Variant.Type] enum."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1574
+#: doc/classes/@GlobalScope.xml:1577
msgid "Equality operator ([code]==[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1577
+#: doc/classes/@GlobalScope.xml:1580
msgid "Inequality operator ([code]!=[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1580
+#: doc/classes/@GlobalScope.xml:1583
msgid "Less than operator ([code]<[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1583
+#: doc/classes/@GlobalScope.xml:1586
msgid "Less than or equal operator ([code]<=[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1586
+#: doc/classes/@GlobalScope.xml:1589
msgid "Greater than operator ([code]>[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1589
+#: doc/classes/@GlobalScope.xml:1592
msgid "Greater than or equal operator ([code]>=[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1592
+#: doc/classes/@GlobalScope.xml:1595
msgid "Addition operator ([code]+[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1595
+#: doc/classes/@GlobalScope.xml:1598
msgid "Subtraction operator ([code]-[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1598
+#: doc/classes/@GlobalScope.xml:1601
msgid "Multiplication operator ([code]*[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1601
+#: doc/classes/@GlobalScope.xml:1604
msgid "Division operator ([code]/[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1604
+#: doc/classes/@GlobalScope.xml:1607
msgid "Unary negation operator ([code]-[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1607
+#: doc/classes/@GlobalScope.xml:1610
msgid "Unary plus operator ([code]+[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1610
+#: doc/classes/@GlobalScope.xml:1613
msgid "Remainder/modulo operator ([code]%[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1613
+#: doc/classes/@GlobalScope.xml:1616
msgid "String concatenation operator ([code]+[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1616
+#: doc/classes/@GlobalScope.xml:1619
msgid "Left shift operator ([code]<<[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1619
+#: doc/classes/@GlobalScope.xml:1622
msgid "Right shift operator ([code]>>[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1622
+#: doc/classes/@GlobalScope.xml:1625
msgid "Bitwise AND operator ([code]&[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1625
+#: doc/classes/@GlobalScope.xml:1628
msgid "Bitwise OR operator ([code]|[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1628
+#: doc/classes/@GlobalScope.xml:1631
msgid "Bitwise XOR operator ([code]^[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1631
+#: doc/classes/@GlobalScope.xml:1634
msgid "Bitwise NOT operator ([code]~[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1634
+#: doc/classes/@GlobalScope.xml:1637
msgid "Logical AND operator ([code]and[/code] or [code]&&[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1637
+#: doc/classes/@GlobalScope.xml:1640
msgid "Logical OR operator ([code]or[/code] or [code]||[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1640
+#: doc/classes/@GlobalScope.xml:1643
msgid "Logical XOR operator (not implemented in GDScript)."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1643
+#: doc/classes/@GlobalScope.xml:1646
msgid "Logical NOT operator ([code]not[/code] or [code]![/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1646
+#: doc/classes/@GlobalScope.xml:1649
msgid "Logical IN operator ([code]in[/code])."
msgstr ""
-#: doc/classes/@GlobalScope.xml:1649
+#: doc/classes/@GlobalScope.xml:1652
msgid "Represents the size of the [enum Variant.Operator] enum."
msgstr ""
@@ -3804,6 +3809,10 @@ msgid ""
msgstr ""
#: doc/classes/AnimatedTexture.xml:65
+msgid "Sets the currently visible frame of the texture."
+msgstr ""
+
+#: doc/classes/AnimatedTexture.xml:68
msgid ""
"Animation speed in frames per second. This value defines the default time "
"interval between two frames of the animation, and thus the overall duration "
@@ -3814,7 +3823,7 @@ msgid ""
"code] value of 2 will run for 4 seconds, with each frame lasting 0.5 seconds."
msgstr ""
-#: doc/classes/AnimatedTexture.xml:69
+#: doc/classes/AnimatedTexture.xml:72
msgid ""
"Number of frames to use in the animation. While you can create the frames "
"independently with [method set_frame_texture], you need to set this value "
@@ -3822,7 +3831,21 @@ msgid ""
"frames is [constant MAX_FRAMES]."
msgstr ""
-#: doc/classes/AnimatedTexture.xml:74
+#: doc/classes/AnimatedTexture.xml:75
+msgid ""
+"If [code]true[/code], the animation will only play once and will not loop "
+"back to the first frame after reaching the end. Note that reaching the end "
+"will not set [member pause] to [code]true[/code]."
+msgstr ""
+
+#: doc/classes/AnimatedTexture.xml:78
+msgid ""
+"If [code]true[/code], the animation will pause where it currently is (i.e. "
+"at [member current_frame]). The animation will continue from where it was "
+"paused when changing this property to [code]false[/code]."
+msgstr ""
+
+#: doc/classes/AnimatedTexture.xml:83
msgid ""
"The maximum number of frames supported by [AnimatedTexture]. If you need "
"more frames in your animation, use [AnimationPlayer] or [AnimatedSprite2D]."
@@ -6102,22 +6125,27 @@ msgid ""
"var m = MeshInstance3D.new()\n"
"m.mesh = arr_mesh\n"
"[/codeblock]\n"
-"The [MeshInstance3D] is ready to be added to the [SceneTree] to be shown."
+"The [MeshInstance3D] is ready to be added to the [SceneTree] to be shown.\n"
+"See also [ImmediateGeometry3D], [MeshDataTool] and [SurfaceTool] for "
+"procedural geometry generation.\n"
+"[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-"
+"OpenGL/Face-culling]winding order[/url] for front faces of triangle "
+"primitive modes."
msgstr ""
-#: doc/classes/ArrayMesh.xml:27
+#: doc/classes/ArrayMesh.xml:29
msgid ""
"https://docs.godotengine.org/en/latest/tutorials/content/procedural_geometry/"
"arraymesh.html"
msgstr ""
-#: doc/classes/ArrayMesh.xml:36
+#: doc/classes/ArrayMesh.xml:38
msgid ""
"Adds name for a blend shape that will be added with [method "
"add_surface_from_arrays]. Must be called before surface is added."
msgstr ""
-#: doc/classes/ArrayMesh.xml:55
+#: doc/classes/ArrayMesh.xml:57
msgid ""
"Creates a new surface.\n"
"Surfaces are created to be rendered using a [code]primitive[/code], which "
@@ -6135,141 +6163,139 @@ msgid ""
"it is used.\n"
"Adding an index array puts this function into \"index mode\" where the "
"vertex and other arrays become the sources of data, and the index array "
-"defines the order of the vertices.\n"
-"Godot uses clockwise winding order for front faces of triangle primitive "
-"modes."
+"defines the order of the vertices."
msgstr ""
-#: doc/classes/ArrayMesh.xml:66
+#: doc/classes/ArrayMesh.xml:67
msgid "Removes all blend shapes from this [ArrayMesh]."
msgstr ""
-#: doc/classes/ArrayMesh.xml:73
+#: doc/classes/ArrayMesh.xml:74
msgid "Removes all surfaces from this [ArrayMesh]."
msgstr ""
-#: doc/classes/ArrayMesh.xml:80
+#: doc/classes/ArrayMesh.xml:81
msgid "Returns the number of blend shapes that the [ArrayMesh] holds."
msgstr ""
-#: doc/classes/ArrayMesh.xml:89
+#: doc/classes/ArrayMesh.xml:90
msgid "Returns the name of the blend shape at this index."
msgstr ""
-#: doc/classes/ArrayMesh.xml:100
+#: doc/classes/ArrayMesh.xml:101
msgid ""
"Will perform a UV unwrap on the [ArrayMesh] to prepare the mesh for "
"lightmapping."
msgstr ""
-#: doc/classes/ArrayMesh.xml:107
+#: doc/classes/ArrayMesh.xml:108
msgid "Will regenerate normal maps for the [ArrayMesh]."
msgstr ""
-#: doc/classes/ArrayMesh.xml:116
+#: doc/classes/ArrayMesh.xml:117
msgid ""
"Returns the index of the first surface with this name held within this "
"[ArrayMesh]. If none are found, -1 is returned."
msgstr ""
-#: doc/classes/ArrayMesh.xml:125
+#: doc/classes/ArrayMesh.xml:126
msgid ""
"Returns the length in indices of the index array in the requested surface "
"(see [method add_surface_from_arrays])."
msgstr ""
-#: doc/classes/ArrayMesh.xml:134
+#: doc/classes/ArrayMesh.xml:135
msgid ""
"Returns the length in vertices of the vertex array in the requested surface "
"(see [method add_surface_from_arrays])."
msgstr ""
-#: doc/classes/ArrayMesh.xml:143
+#: doc/classes/ArrayMesh.xml:144
msgid ""
"Returns the format mask of the requested surface (see [method "
"add_surface_from_arrays])."
msgstr ""
-#: doc/classes/ArrayMesh.xml:152
+#: doc/classes/ArrayMesh.xml:153
msgid "Gets the name assigned to this surface."
msgstr ""
-#: doc/classes/ArrayMesh.xml:161
+#: doc/classes/ArrayMesh.xml:162
msgid ""
"Returns the primitive type of the requested surface (see [method "
"add_surface_from_arrays])."
msgstr ""
-#: doc/classes/ArrayMesh.xml:172
+#: doc/classes/ArrayMesh.xml:173
msgid "Sets a name for a given surface."
msgstr ""
-#: doc/classes/ArrayMesh.xml:185
+#: doc/classes/ArrayMesh.xml:186
msgid ""
"Updates a specified region of mesh arrays on the GPU.\n"
"[b]Warning:[/b] Only use if you know what you are doing. You can easily "
"cause crashes by calling this function with improper arguments."
msgstr ""
-#: doc/classes/ArrayMesh.xml:192
+#: doc/classes/ArrayMesh.xml:193
msgid "Sets the blend shape mode to one of [enum Mesh.BlendShapeMode]."
msgstr ""
-#: doc/classes/ArrayMesh.xml:195
+#: doc/classes/ArrayMesh.xml:196
msgid ""
"Overrides the [AABB] with one defined by user for use with frustum culling. "
"Especially useful to avoid unexpected culling when using a shader to offset "
"vertices."
msgstr ""
-#: doc/classes/ArrayMesh.xml:200
+#: doc/classes/ArrayMesh.xml:201
msgid "Default value used for index_array_len when no indices are present."
msgstr ""
-#: doc/classes/ArrayMesh.xml:203
+#: doc/classes/ArrayMesh.xml:204
msgid "Amount of weights/bone indices per vertex (always 4)."
msgstr ""
-#: doc/classes/ArrayMesh.xml:206
+#: doc/classes/ArrayMesh.xml:207
msgid ""
"[PackedVector3Array], [PackedVector2Array], or [Array] of vertex positions."
msgstr ""
-#: doc/classes/ArrayMesh.xml:209
+#: doc/classes/ArrayMesh.xml:210
msgid "[PackedVector3Array] of vertex normals."
msgstr ""
-#: doc/classes/ArrayMesh.xml:212
+#: doc/classes/ArrayMesh.xml:213
msgid ""
"[PackedFloat32Array] of vertex tangents. Each element in groups of 4 floats, "
"first 3 floats determine the tangent, and the last the binormal direction as "
"-1 or 1."
msgstr ""
-#: doc/classes/ArrayMesh.xml:215
+#: doc/classes/ArrayMesh.xml:216
msgid "[PackedColorArray] of vertex colors."
msgstr ""
-#: doc/classes/ArrayMesh.xml:218
+#: doc/classes/ArrayMesh.xml:219
msgid "[PackedVector2Array] for UV coordinates."
msgstr ""
-#: doc/classes/ArrayMesh.xml:221
+#: doc/classes/ArrayMesh.xml:222
msgid "[PackedVector2Array] for second UV coordinates."
msgstr ""
-#: doc/classes/ArrayMesh.xml:224
+#: doc/classes/ArrayMesh.xml:225
msgid ""
"[PackedFloat32Array] or [PackedInt32Array] of bone indices. Each element in "
"groups of 4 floats."
msgstr ""
-#: doc/classes/ArrayMesh.xml:227
+#: doc/classes/ArrayMesh.xml:228
msgid ""
"[PackedFloat32Array] of bone weights. Each element in groups of 4 floats."
msgstr ""
-#: doc/classes/ArrayMesh.xml:230
+#: doc/classes/ArrayMesh.xml:231
msgid ""
"[PackedInt32Array] of integers used as indices referencing vertices, colors, "
"normals, tangents, and textures. All of those arrays must have the same "
@@ -6283,709 +6309,47 @@ msgid ""
"the start and end of each line."
msgstr ""
-#: doc/classes/ArrayMesh.xml:234 doc/classes/Mesh.xml:210
-#: doc/classes/RenderingServer.xml:3180
+#: doc/classes/ArrayMesh.xml:235 doc/classes/Mesh.xml:210
+#: doc/classes/RenderingServer.xml:3232
msgid "Represents the size of the [enum ArrayType] enum."
msgstr ""
-#: doc/classes/ArrayMesh.xml:237
+#: doc/classes/ArrayMesh.xml:238
msgid "Array format will include vertices (mandatory)."
msgstr ""
-#: doc/classes/ArrayMesh.xml:240
+#: doc/classes/ArrayMesh.xml:241
msgid "Array format will include normals."
msgstr ""
-#: doc/classes/ArrayMesh.xml:243
+#: doc/classes/ArrayMesh.xml:244
msgid "Array format will include tangents."
msgstr ""
-#: doc/classes/ArrayMesh.xml:246
+#: doc/classes/ArrayMesh.xml:247
msgid "Array format will include a color array."
msgstr ""
-#: doc/classes/ArrayMesh.xml:249
+#: doc/classes/ArrayMesh.xml:250
msgid "Array format will include UVs."
msgstr ""
-#: doc/classes/ArrayMesh.xml:252
+#: doc/classes/ArrayMesh.xml:253
msgid "Array format will include another set of UVs."
msgstr ""
-#: doc/classes/ArrayMesh.xml:255
+#: doc/classes/ArrayMesh.xml:256
msgid "Array format will include bone indices."
msgstr ""
-#: doc/classes/ArrayMesh.xml:258
+#: doc/classes/ArrayMesh.xml:259
msgid "Array format will include bone weights."
msgstr ""
-#: doc/classes/ArrayMesh.xml:261
+#: doc/classes/ArrayMesh.xml:262
msgid "Index array will be used."
msgstr ""
-#: doc/classes/ARVRAnchor.xml:4
-msgid "An anchor point in AR space."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:7
-msgid ""
-"The [ARVRAnchor] point is a spatial node that maps a real world location "
-"identified by the AR platform to a position within the game world. For "
-"example, as long as plane detection in ARKit is on, ARKit will identify and "
-"update the position of planes (tables, floors, etc) and create anchors for "
-"them.\n"
-"This node is mapped to one of the anchors through its unique ID. When you "
-"receive a signal that a new anchor is available, you should add this node to "
-"your scene for that anchor. You can predefine nodes and set the ID; the "
-"nodes will simply remain on 0,0,0 until a plane is recognized.\n"
-"Keep in mind that, as long as plane detection is enabled, the size, placing "
-"and orientation of an anchor will be updated as the detection logic learns "
-"more about the real world out there especially if only part of the surface "
-"is in view."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:18
-msgid "Returns the name given to this anchor."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:25
-msgid ""
-"Returns [code]true[/code] if the anchor is being tracked and [code]false[/"
-"code] if no anchor with this ID is currently known."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:32
-msgid ""
-"If provided by the [ARVRInterface], this returns a mesh object for the "
-"anchor. For an anchor, this can be a shape related to the object being "
-"tracked or it can be a mesh that provides topology related to the anchor and "
-"can be used to create shadows/reflections on surfaces or for generating "
-"collision shapes."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:39
-msgid ""
-"Returns a plane aligned with our anchor; handy for intersection testing."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:46
-msgid ""
-"Returns the estimated size of the plane that was detected. Say when the "
-"anchor relates to a table in the real world, this is the estimated size of "
-"the surface of that table."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:52
-msgid ""
-"The anchor's ID. You can set this before the anchor itself exists. The first "
-"anchor gets an ID of [code]1[/code], the second an ID of [code]2[/code], "
-"etc. When anchors get removed, the engine can then assign the corresponding "
-"ID to new anchors. The most common situation where anchors \"disappear\" is "
-"when the AR server identifies that two anchors represent different parts of "
-"the same plane and merges them."
-msgstr ""
-
-#: doc/classes/ARVRAnchor.xml:60
-msgid ""
-"Emitted when the mesh associated with the anchor changes or when one becomes "
-"available. This is especially important for topology that is constantly "
-"being [code]mesh_updated[/code]."
-msgstr ""
-
-#: doc/classes/ARVRCamera.xml:4
-msgid ""
-"A camera node with a few overrules for AR/VR applied, such as location "
-"tracking."
-msgstr ""
-
-#: doc/classes/ARVRCamera.xml:7
-msgid ""
-"This is a helper spatial node for our camera; note that, if stereoscopic "
-"rendering is applicable (VR-HMD), most of the camera properties are ignored, "
-"as the HMD information overrides them. The only properties that can be "
-"trusted are the near and far planes.\n"
-"The position and orientation of this node is automatically updated by the "
-"ARVR Server to represent the location of the HMD if such tracking is "
-"available and can thus be used by game logic. Note that, in contrast to the "
-"ARVR Controller, the render thread has access to the most up-to-date "
-"tracking data of the HMD and the location of the ARVRCamera can lag a few "
-"milliseconds behind what is used for rendering as a result."
-msgstr ""
-
-#: doc/classes/ARVRCamera.xml:11 doc/classes/ARVRController.xml:12
-#: doc/classes/ARVRInterface.xml:11 doc/classes/ARVROrigin.xml:13
-#: doc/classes/ARVRPositionalTracker.xml:12 doc/classes/ARVRServer.xml:10
-msgid "https://docs.godotengine.org/en/latest/tutorials/vr/index.html"
-msgstr ""
-
-#: doc/classes/ARVRController.xml:4
-msgid "A spatial node representing a spatially-tracked controller."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:7
-msgid ""
-"This is a helper spatial node that is linked to the tracking of controllers. "
-"It also offers several handy passthroughs to the state of buttons and such "
-"on the controllers.\n"
-"Controllers are linked by their ID. You can create controller nodes before "
-"the controllers are available. If your game always uses two controllers (one "
-"for each hand), you can predefine the controllers with ID 1 and 2; they will "
-"become active as soon as the controllers are identified. If you expect "
-"additional controllers to be used, you should react to the signals and add "
-"ARVRController nodes to your scene.\n"
-"The position of the controller node is automatically updated by the "
-"[ARVRServer]. This makes this node ideal to add child nodes to visualize the "
-"controller."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:19
-msgid ""
-"If active, returns the name of the associated controller if provided by the "
-"AR/VR SDK used."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:26
-msgid ""
-"Returns the hand holding this controller, if known. See [enum "
-"ARVRPositionalTracker.TrackerHand]."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:33
-msgid ""
-"Returns [code]true[/code] if the bound controller is active. ARVR systems "
-"attempt to track active controllers."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:42
-msgid ""
-"Returns the value of the given axis for things like triggers, touchpads, "
-"etc. that are embedded into the controller."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:49
-msgid ""
-"Returns the ID of the joystick object bound to this. Every controller "
-"tracked by the [ARVRServer] that has buttons and axis will also be "
-"registered as a joystick within Godot. This means that all the normal "
-"joystick tracking and input mapping will work for buttons and axis found on "
-"the AR/VR controllers. This ID is purely offered as information so you can "
-"link up the controller with its joystick entry."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:56
-msgid ""
-"If provided by the [ARVRInterface], this returns a mesh associated with the "
-"controller. This can be used to visualize the controller."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:65
-msgid ""
-"Returns [code]true[/code] if the button at index [code]button[/code] is "
-"pressed. See [enum JoystickList], in particular the [code]JOY_VR_*[/code] "
-"constants."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:71
-msgid ""
-"The controller's ID.\n"
-"A controller ID of 0 is unbound and will always result in an inactive node. "
-"Controller ID 1 is reserved for the first controller that identifies itself "
-"as the left-hand controller and ID 2 is reserved for the first controller "
-"that identifies itself as the right-hand controller.\n"
-"For any other controller that the [ARVRServer] detects, we continue with "
-"controller ID 3.\n"
-"When a controller is turned off, its slot is freed. This ensures controllers "
-"will keep the same ID even when controllers with lower IDs are turned off."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:77
-msgid ""
-"The degree to which the controller vibrates. Ranges from [code]0.0[/code] to "
-"[code]1.0[/code] with precision [code].01[/code]. If changed, updates "
-"[member ARVRPositionalTracker.rumble] accordingly.\n"
-"This is a useful property to animate if you want the controller to vibrate "
-"for a limited duration."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:86
-msgid "Emitted when a button on this controller is pressed."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:93
-msgid "Emitted when a button on this controller is released."
-msgstr ""
-
-#: doc/classes/ARVRController.xml:100
-msgid ""
-"Emitted when the mesh associated with the controller changes or when one "
-"becomes available. Generally speaking this will be a static mesh after "
-"becoming available."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:4
-msgid "Base class for an AR/VR interface implementation."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:7
-msgid ""
-"This class needs to be implemented to make an AR or VR platform available to "
-"Godot and these should be implemented as C++ modules or GDNative modules "
-"(note that for GDNative the subclass ARVRScriptInterface should be used). "
-"Part of the interface is exposed to GDScript so you can detect, enable and "
-"configure an AR or VR platform.\n"
-"Interfaces should be written in such a way that simply enabling them will "
-"give us a working setup. You can query the available interfaces through "
-"[ARVRServer]."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:18
-msgid ""
-"If this is an AR interface that requires displaying a camera feed as the "
-"background, this method returns the feed ID in the [CameraServer] for this "
-"interface."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:25
-msgid ""
-"Returns a combination of [enum Capabilities] flags providing information "
-"about the capabilities of this interface."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:32
-msgid "Returns the name of this interface (OpenVR, OpenHMD, ARKit, etc)."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:39
-msgid ""
-"Returns the resolution at which we should render our intermediate results "
-"before things like lens distortion are applied by the VR platform."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:46
-msgid ""
-"If supported, returns the status of our tracking. This will allow you to "
-"provide feedback to the user whether there are issues with positional "
-"tracking."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:53
-msgid ""
-"Call this to initialize this interface. The first interface that is "
-"initialized is identified as the primary interface and it will be used for "
-"rendering output.\n"
-"After initializing the interface you want to use you then need to enable the "
-"AR/VR mode of a viewport and rendering should commence.\n"
-"[b]Note:[/b] You must enable the AR/VR mode on the main viewport for any "
-"device that uses the main output of Godot, such as for mobile VR.\n"
-"If you do this for a platform that handles its own output (such as OpenVR) "
-"Godot will show just one eye without distortion on screen. Alternatively, "
-"you can add a separate viewport node to your scene and enable AR/VR on that "
-"viewport. It will be used to output to the HMD, leaving you free to do "
-"anything you like in the main window, such as using a separate camera as a "
-"spectator camera or rendering something completely different.\n"
-"While currently not used, you can activate additional interfaces. You may "
-"wish to do this if you want to track controllers from other platforms. "
-"However, at this point in time only one interface can render to an HMD."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:64
-msgid ""
-"Returns [code]true[/code] if the current output of this interface is in "
-"stereo."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:71
-msgid "Turns the interface off."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:77
-msgid "On an AR interface, [code]true[/code] if anchor detection is enabled."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:80
-msgid "[code]true[/code] if this interface been initialized."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:83
-msgid "[code]true[/code] if this is the primary interface."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:88
-msgid "No ARVR capabilities."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:91
-msgid ""
-"This interface can work with normal rendering output (non-HMD based AR)."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:94
-msgid "This interface supports stereoscopic rendering."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:97
-msgid "This interface supports AR (video background and real world tracking)."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:100
-msgid ""
-"This interface outputs to an external device. If the main viewport is used, "
-"the on screen output is an unmodified buffer of either the left or right eye "
-"(stretched if the viewport size is not changed to the same aspect ratio of "
-"[method get_render_targetsize]). Using a separate viewport node frees up the "
-"main viewport for other purposes."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:103
-msgid ""
-"Mono output, this is mostly used internally when retrieving positioning "
-"information for our camera node or when stereo scopic rendering is not "
-"supported."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:106
-msgid ""
-"Left eye output, this is mostly used internally when rendering the image for "
-"the left eye and obtaining positioning and projection information."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:109
-msgid ""
-"Right eye output, this is mostly used internally when rendering the image "
-"for the right eye and obtaining positioning and projection information."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:112
-msgid "Tracking is behaving as expected."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:115
-msgid ""
-"Tracking is hindered by excessive motion (the player is moving faster than "
-"tracking can keep up)."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:118
-msgid ""
-"Tracking is hindered by insufficient features, it's too dark (for camera-"
-"based tracking), player is blocked, etc."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:121
-msgid ""
-"We don't know the status of the tracking or this interface does not provide "
-"feedback."
-msgstr ""
-
-#: doc/classes/ARVRInterface.xml:124
-msgid ""
-"Tracking is not functional (camera not plugged in or obscured, lighthouses "
-"turned off, etc.)."
-msgstr ""
-
-#: modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml:4
-msgid "GDNative wrapper for an ARVR interface."
-msgstr ""
-
-#: modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml:7
-msgid ""
-"This is a wrapper class for GDNative implementations of the ARVR interface. "
-"To use a GDNative ARVR interface, simply instantiate this object and set "
-"your GDNative library containing the ARVR interface implementation."
-msgstr ""
-
-#: doc/classes/ARVROrigin.xml:4
-msgid "The origin point in AR/VR."
-msgstr ""
-
-#: doc/classes/ARVROrigin.xml:7
-msgid ""
-"This is a special node within the AR/VR system that maps the physical "
-"location of the center of our tracking space to the virtual location within "
-"our game world.\n"
-"There should be only one of these nodes in your scene and you must have one. "
-"All the ARVRCamera, ARVRController and ARVRAnchor nodes should be direct "
-"children of this node for spatial tracking to work correctly.\n"
-"It is the position of this node that you update when your character needs to "
-"move through your game world while we're not moving in the real world. "
-"Movement in the real world is always in relation to this origin point.\n"
-"For example, if your character is driving a car, the ARVROrigin node should "
-"be a child node of this car. Or, if you're implementing a teleport system to "
-"move your character, you should change the position of this node."
-msgstr ""
-
-#: doc/classes/ARVROrigin.xml:19
-msgid ""
-"Allows you to adjust the scale to your game's units. Most AR/VR platforms "
-"assume a scale of 1 game world unit = 1 real world meter.\n"
-"[b]Note:[/b] This method is a passthrough to the [ARVRServer] itself."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:4
-msgid "A tracked object."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:7
-msgid ""
-"An instance of this object represents a device that is tracked, such as a "
-"controller or anchor point. HMDs aren't represented here as they are handled "
-"internally.\n"
-"As controllers are turned on and the AR/VR interface detects them, instances "
-"of this object are automatically added to this list of active tracking "
-"objects accessible through the [ARVRServer].\n"
-"The [ARVRController] and [ARVRAnchor] both consume objects of this type and "
-"should be used in your project. The positional trackers are just under-the-"
-"hood objects that make this all work. These are mostly exposed so that "
-"GDNative-based interfaces can interact with them."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:19
-msgid ""
-"Returns the hand holding this tracker, if known. See [enum TrackerHand] "
-"constants."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:26
-msgid ""
-"If this is a controller that is being tracked, the controller will also be "
-"represented by a joystick entry with this ID."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:33
-msgid ""
-"Returns the mesh related to a controller or anchor point if one is available."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:40
-msgid "Returns the controller or anchor point's name if available."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:47
-msgid "Returns the controller's orientation matrix."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:54
-msgid "Returns the world-space controller position."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:61
-msgid ""
-"Returns the internal tracker ID. This uniquely identifies the tracker per "
-"tracker type and matches the ID you need to specify for nodes such as the "
-"[ARVRController] and [ARVRAnchor] nodes."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:68
-msgid "Returns [code]true[/code] if this device tracks orientation."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:75
-msgid "Returns [code]true[/code] if this device tracks position."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:84
-msgid "Returns the transform combining this device's orientation and position."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:91
-msgid "Returns the tracker's type."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:97
-msgid ""
-"The degree to which the tracker rumbles. Ranges from [code]0.0[/code] to "
-"[code]1.0[/code] with precision [code].01[/code]."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:102
-msgid "The hand this tracker is held in is unknown or not applicable."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:105
-msgid "This tracker is the left hand controller."
-msgstr ""
-
-#: doc/classes/ARVRPositionalTracker.xml:108
-msgid "This tracker is the right hand controller."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:4
-msgid "Server for AR and VR features."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:7
-msgid ""
-"The AR/VR server is the heart of our Advanced and Virtual Reality solution "
-"and handles all the processing."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:21
-msgid ""
-"This is an important function to understand correctly. AR and VR platforms "
-"all handle positioning slightly differently.\n"
-"For platforms that do not offer spatial tracking, our origin point (0,0,0) "
-"is the location of our HMD, but you have little control over the direction "
-"the player is facing in the real world.\n"
-"For platforms that do offer spatial tracking, our origin point depends very "
-"much on the system. For OpenVR, our origin point is usually the center of "
-"the tracking space, on the ground. For other platforms, it's often the "
-"location of the tracking camera.\n"
-"This method allows you to center your tracker on the location of the HMD. It "
-"will take the current location of the HMD and use that to adjust all your "
-"tracking data; in essence, realigning the real world to your player's "
-"current position in the game world.\n"
-"For this method to produce usable results, tracking information must be "
-"available. This often takes a few frames after starting your game.\n"
-"You should call this method after a few seconds have passed. For instance, "
-"when the user requests a realignment of the display holding a designated "
-"button on a controller for a short period of time, or when implementing a "
-"teleport mechanism."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:35
-msgid ""
-"Finds an interface by its name. For instance, if your project uses "
-"capabilities of an AR/VR platform, you can find the interface for that "
-"platform by name and initialize it."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:42
-msgid "Returns the primary interface's transformation."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:51
-msgid ""
-"Returns the interface registered at a given index in our list of interfaces."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:58
-msgid ""
-"Returns the number of interfaces currently registered with the AR/VR server. "
-"If your project supports multiple AR/VR platforms, you can look through the "
-"available interface, and either present the user with a selection or simply "
-"try to initialize each interface and use the first one that returns "
-"[code]true[/code]."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:65
-msgid ""
-"Returns a list of available interfaces the ID and name of each interface."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:72
-msgid ""
-"Returns the absolute timestamp (in μs) of the last [ARVRServer] commit of "
-"the AR/VR eyes to [RenderingServer]. The value comes from an internal call "
-"to [method OS.get_ticks_usec]."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:79
-msgid ""
-"Returns the duration (in μs) of the last frame. This is computed as the "
-"difference between [method get_last_commit_usec] and [method "
-"get_last_process_usec] when committing."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:86
-msgid ""
-"Returns the absolute timestamp (in μs) of the last [ARVRServer] process "
-"callback. The value comes from an internal call to [method OS."
-"get_ticks_usec]."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:93
-msgid ""
-"Returns the reference frame transform. Mostly used internally and exposed "
-"for GDNative build interfaces."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:102
-msgid "Returns the positional tracker at the given ID."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:109
-msgid "Returns the number of trackers currently registered."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:115
-msgid "The primary [ARVRInterface] currently bound to the [ARVRServer]."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:118
-msgid ""
-"Allows you to adjust the scale to your game's units. Most AR/VR platforms "
-"assume a scale of 1 game world unit = 1 real world meter."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:126
-msgid "Emitted when a new interface has been added."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:133
-msgid "Emitted when an interface is removed."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:144
-msgid ""
-"Emitted when a new tracker has been added. If you don't use a fixed number "
-"of controllers or if you're using [ARVRAnchor]s for an AR solution, it is "
-"important to react to this signal to add the appropriate [ARVRController] or "
-"[ARVRAnchor] nodes related to this new tracker."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:155
-msgid ""
-"Emitted when a tracker is removed. You should remove any [ARVRController] or "
-"[ARVRAnchor] points if applicable. This is not mandatory, the nodes simply "
-"become inactive and will be made active again when a new tracker becomes "
-"available (i.e. a new controller is switched on that takes the place of the "
-"previous one)."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:161
-msgid "The tracker tracks the location of a controller."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:164
-msgid "The tracker tracks the location of a base station."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:167
-msgid "The tracker tracks the location and size of an AR anchor."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:170
-msgid "Used internally to filter trackers of any known type."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:173
-msgid "Used internally if we haven't set the tracker type yet."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:176
-msgid "Used internally to select all trackers."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:179
-msgid ""
-"Fully reset the orientation of the HMD. Regardless of what direction the "
-"user is looking to in the real world. The user will look dead ahead in the "
-"virtual world."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:182
-msgid ""
-"Resets the orientation but keeps the tilt of the device. So if we're looking "
-"down, we keep looking down but heading will be reset."
-msgstr ""
-
-#: doc/classes/ARVRServer.xml:185
-msgid ""
-"Does not reset the orientation of the HMD, only the position of the player "
-"gets centered."
-msgstr ""
-
#: doc/classes/AStar.xml:4
msgid ""
"An implementation of A* to find shortest paths among connected points in "
@@ -8387,7 +7751,9 @@ msgstr ""
#: doc/classes/AudioStreamPlayer.xml:64 doc/classes/AudioStreamPlayer2D.xml:70
#: doc/classes/AudioStreamPlayer3D.xml:94
-msgid "Changes the pitch and the tempo of the audio."
+msgid ""
+"The pitch and the tempo of the audio, as a multiplier of the audio sample's "
+"sample rate."
msgstr ""
#: doc/classes/AudioStreamPlayer.xml:67 doc/classes/AudioStreamPlayer2D.xml:73
@@ -8632,15 +7998,23 @@ msgid "Audio format. See [enum Format] constants for values."
msgstr ""
#: doc/classes/AudioStreamSample.xml:33
-msgid "Loop start in bytes."
+msgid ""
+"The loop start point (in number of samples, relative to the beginning of the "
+"sample). This information will be imported automatically from the WAV file "
+"if present."
msgstr ""
#: doc/classes/AudioStreamSample.xml:36
-msgid "Loop end in bytes."
+msgid ""
+"The loop end point (in number of samples, relative to the beginning of the "
+"sample). This information will be imported automatically from the WAV file "
+"if present."
msgstr ""
#: doc/classes/AudioStreamSample.xml:39
-msgid "Loop mode. See [enum LoopMode] constants for values."
+msgid ""
+"The loop mode. This information will be imported automatically from the WAV "
+"file if present. See [enum LoopMode] constants for values."
msgstr ""
#: doc/classes/AudioStreamSample.xml:42
@@ -8669,19 +8043,19 @@ msgstr ""
#: doc/classes/AudioStreamSample.xml:62
msgid ""
-"Audio loops the data between [member loop_begin] and [member loop_end] "
+"Audio loops the data between [member loop_begin] and [member loop_end], "
"playing forward only."
msgstr ""
#: doc/classes/AudioStreamSample.xml:65
msgid ""
-"Audio loops the data between [member loop_begin] and [member loop_end] "
+"Audio loops the data between [member loop_begin] and [member loop_end], "
"playing back and forth."
msgstr ""
#: doc/classes/AudioStreamSample.xml:68
msgid ""
-"Audio loops the data between [member loop_begin] and [member loop_end] "
+"Audio loops the data between [member loop_begin] and [member loop_end], "
"playing backward only."
msgstr ""
@@ -8698,30 +8072,35 @@ msgid ""
"in the BackBufferCopy node is bufferized with the content of the screen it "
"covers, or the entire screen according to the copy mode set. Use the "
"[code]texture(SCREEN_TEXTURE, ...)[/code] function in your shader scripts to "
-"access the buffer."
+"access the buffer.\n"
+"[b]Note:[/b] Since this node inherits from [Node2D] (and not [Control]), "
+"anchors and margins won't apply to child [Control]-derived nodes. This can "
+"be problematic when resizing the window. To avoid this, add [Control]-"
+"derived nodes as [i]siblings[/i] to the BackBufferCopy node instead of "
+"adding them as children."
msgstr ""
-#: doc/classes/BackBufferCopy.xml:15
+#: doc/classes/BackBufferCopy.xml:16
msgid "Buffer mode. See [enum CopyMode] constants."
msgstr ""
-#: doc/classes/BackBufferCopy.xml:18
+#: doc/classes/BackBufferCopy.xml:19
msgid ""
"The area covered by the BackBufferCopy. Only used if [member copy_mode] is "
"[constant COPY_MODE_RECT]."
msgstr ""
-#: doc/classes/BackBufferCopy.xml:23
+#: doc/classes/BackBufferCopy.xml:24
msgid ""
"Disables the buffering mode. This means the BackBufferCopy node will "
"directly use the portion of screen it covers."
msgstr ""
-#: doc/classes/BackBufferCopy.xml:26
+#: doc/classes/BackBufferCopy.xml:27
msgid "BackBufferCopy buffers a rectangular region."
msgstr ""
-#: doc/classes/BackBufferCopy.xml:29
+#: doc/classes/BackBufferCopy.xml:30
msgid "BackBufferCopy buffers the entire screen."
msgstr ""
@@ -8791,80 +8170,83 @@ msgstr ""
#: doc/classes/BaseButton.xml:62
msgid ""
"If [code]true[/code], the button stays pressed when moving the cursor "
-"outside the button while pressing it."
+"outside the button while pressing it.\n"
+"[b]Note:[/b] This property only affects the button's visual appearance. "
+"Signals will be emitted at the same moment regardless of this property's "
+"value."
msgstr ""
-#: doc/classes/BaseButton.xml:65
+#: doc/classes/BaseButton.xml:66
msgid ""
"If [code]true[/code], the button's state is pressed. Means the button is "
"pressed down or toggled (if [member toggle_mode] is active)."
msgstr ""
-#: doc/classes/BaseButton.xml:68
+#: doc/classes/BaseButton.xml:69
msgid "[ShortCut] associated to the button."
msgstr ""
-#: doc/classes/BaseButton.xml:71
+#: doc/classes/BaseButton.xml:72
msgid ""
"If [code]true[/code], the button will add information about its shortcut in "
"the tooltip."
msgstr ""
-#: doc/classes/BaseButton.xml:74
+#: doc/classes/BaseButton.xml:75
msgid ""
"If [code]true[/code], the button is in toggle mode. Makes the button flip "
"state between pressed and unpressed each time its area is clicked."
msgstr ""
-#: doc/classes/BaseButton.xml:80
+#: doc/classes/BaseButton.xml:81
msgid "Emitted when the button starts being held down."
msgstr ""
-#: doc/classes/BaseButton.xml:85
+#: doc/classes/BaseButton.xml:86
msgid "Emitted when the button stops being held down."
msgstr ""
-#: doc/classes/BaseButton.xml:90
+#: doc/classes/BaseButton.xml:91
msgid ""
"Emitted when the button is toggled or pressed. This is on [signal "
"button_down] if [member action_mode] is [constant ACTION_MODE_BUTTON_PRESS] "
"and on [signal button_up] otherwise."
msgstr ""
-#: doc/classes/BaseButton.xml:97
+#: doc/classes/BaseButton.xml:98
msgid ""
"Emitted when the button was just toggled between pressed and normal states "
"(only if [member toggle_mode] is active). The new state is contained in the "
"[code]button_pressed[/code] argument."
msgstr ""
-#: doc/classes/BaseButton.xml:103
+#: doc/classes/BaseButton.xml:104
msgid ""
"The normal state (i.e. not pressed, not hovered, not toggled and enabled) of "
"buttons."
msgstr ""
-#: doc/classes/BaseButton.xml:106
+#: doc/classes/BaseButton.xml:107
msgid "The state of buttons are pressed."
msgstr ""
-#: doc/classes/BaseButton.xml:109
+#: doc/classes/BaseButton.xml:110
msgid "The state of buttons are hovered."
msgstr ""
-#: doc/classes/BaseButton.xml:112
+#: doc/classes/BaseButton.xml:113
msgid "The state of buttons are disabled."
msgstr ""
-#: doc/classes/BaseButton.xml:115
+#: doc/classes/BaseButton.xml:116
msgid "The state of buttons are both hovered and pressed."
msgstr ""
-#: doc/classes/BaseButton.xml:118
+#: doc/classes/BaseButton.xml:119
msgid "Require just a press to consider the button clicked."
msgstr ""
-#: doc/classes/BaseButton.xml:121
+#: doc/classes/BaseButton.xml:122
msgid ""
"Require a press and a subsequent release before considering the button "
"clicked."
@@ -8988,8 +8370,8 @@ msgid ""
"the object."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:109 doc/classes/BaseMaterial3D.xml:275
-#: doc/classes/BaseMaterial3D.xml:296
+#: doc/classes/BaseMaterial3D.xml:109 doc/classes/BaseMaterial3D.xml:284
+#: doc/classes/BaseMaterial3D.xml:305
msgid ""
"Specifies the channel of the [member ao_texture] in which the ambient "
"occlusion information is stored. This is useful when you store the "
@@ -9000,29 +8382,45 @@ msgstr ""
#: doc/classes/BaseMaterial3D.xml:112
msgid ""
+"The color used by the backlight effect. Represents the light passing through "
+"an object."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:115
+msgid "If [code]true[/code], the backlight effect is enabled."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:118
+msgid ""
+"Texture used to control the backlight effect per-pixel. Added to [member "
+"backlight]."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:121
+msgid ""
"If [code]true[/code], the shader will keep the scale set for the mesh. "
"Otherwise the scale is lost when billboarding. Only applies when [member "
"billboard_mode] is [constant BILLBOARD_ENABLED]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:115
+#: doc/classes/BaseMaterial3D.xml:124
msgid "Controls how the object faces the camera. See [enum BillboardMode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:118
+#: doc/classes/BaseMaterial3D.xml:127
msgid ""
"The material's blend mode.\n"
"[b]Note:[/b] Values other than [code]Mix[/code] force the object into the "
"transparent pipeline. See [enum BlendMode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:122
+#: doc/classes/BaseMaterial3D.xml:131
msgid ""
"Sets the strength of the clearcoat effect. Setting to [code]0[/code] looks "
"the same as disabling the clearcoat effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:125
+#: doc/classes/BaseMaterial3D.xml:134
msgid ""
"If [code]true[/code], clearcoat rendering is enabled. Adds a secondary "
"transparent pass to the lighting calculation resulting in an added specular "
@@ -9030,42 +8428,42 @@ msgid ""
"can be either glossy or rough."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:128
+#: doc/classes/BaseMaterial3D.xml:137
msgid ""
"Sets the roughness of the clearcoat pass. A higher value results in a "
"smoother clearcoat while a lower value results in a rougher clearcoat."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:131
+#: doc/classes/BaseMaterial3D.xml:140
msgid ""
"Texture that defines the strength of the clearcoat effect and the glossiness "
"of the clearcoat. Strength is specified in the red channel while glossiness "
"is specified in the green channel."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:134
+#: doc/classes/BaseMaterial3D.xml:143
msgid ""
"Which side of the object is not drawn when backfaces are rendered. See [enum "
"CullMode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:137
+#: doc/classes/BaseMaterial3D.xml:146
msgid ""
"Determines when depth rendering takes place. See [enum DepthDrawMode]. See "
"also [member transparency]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:140
+#: doc/classes/BaseMaterial3D.xml:149
msgid "Texture that specifies the color of the detail overlay."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:143
+#: doc/classes/BaseMaterial3D.xml:152
msgid ""
"Specifies how the [member detail_albedo] should blend with the current "
"[code]ALBEDO[/code]. See [enum BlendMode] for options."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:146
+#: doc/classes/BaseMaterial3D.xml:155
msgid ""
"If [code]true[/code], enables the detail overlay. Detail is a second texture "
"that gets mixed over the surface of the object based on [member "
@@ -9073,99 +8471,99 @@ msgid ""
"between two different albedo/normal textures."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:149
+#: doc/classes/BaseMaterial3D.xml:158
msgid ""
"Texture used to specify how the detail textures get blended with the base "
"textures."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:152
+#: doc/classes/BaseMaterial3D.xml:161
msgid "Texture that specifies the per-pixel normal of the detail overlay."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:155
+#: doc/classes/BaseMaterial3D.xml:164
msgid ""
"Specifies whether to use [code]UV[/code] or [code]UV2[/code] for the detail "
"layer. See [enum DetailUV] for options."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:158
+#: doc/classes/BaseMaterial3D.xml:167
msgid ""
"The algorithm used for diffuse light scattering. See [enum DiffuseMode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:161
+#: doc/classes/BaseMaterial3D.xml:170
msgid "If [code]true[/code], the object receives no ambient light."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:164
+#: doc/classes/BaseMaterial3D.xml:173
msgid ""
"If [code]true[/code], the object receives no shadow that would otherwise be "
"cast onto it."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:167
+#: doc/classes/BaseMaterial3D.xml:176
msgid "Distance at which the object fades fully and is no longer visible."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:170
+#: doc/classes/BaseMaterial3D.xml:179
msgid ""
"Distance at which the object starts to fade. If the object is less than this "
"distance away it will appear normal."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:173
+#: doc/classes/BaseMaterial3D.xml:182
msgid ""
"Specifies which type of fade to use. Can be any of the [enum "
"DistanceFadeMode]s."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:176
+#: doc/classes/BaseMaterial3D.xml:185
msgid "The emitted light's color. See [member emission_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:179
+#: doc/classes/BaseMaterial3D.xml:188
msgid ""
"If [code]true[/code], the body emits light. Emitting light makes the object "
"appear brighter. The object can also cast light on other objects if a "
"[GIProbe] is used and this object is used in baked lighting."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:182
+#: doc/classes/BaseMaterial3D.xml:191
msgid "The emitted light's strength. See [member emission_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:185
+#: doc/classes/BaseMaterial3D.xml:194
msgid "Use [code]UV2[/code] to read from the [member emission_texture]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:188
+#: doc/classes/BaseMaterial3D.xml:197
msgid ""
"Sets how [member emission] interacts with [member emission_texture]. Can "
"either add or multiply. See [enum EmissionOperator] for options."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:191
+#: doc/classes/BaseMaterial3D.xml:200
msgid "Texture that specifies how much surface emits light at a given point."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:194
+#: doc/classes/BaseMaterial3D.xml:203
msgid ""
"If [code]true[/code], the object is rendered at the same size regardless of "
"distance."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:197
+#: doc/classes/BaseMaterial3D.xml:206
msgid ""
"If [code]true[/code], enables the vertex grow setting. See [member "
"grow_amount]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:200
+#: doc/classes/BaseMaterial3D.xml:209
msgid "Grows object vertices in the direction of their normals."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:221
+#: doc/classes/BaseMaterial3D.xml:230
msgid ""
"A high value makes the material appear more like a metal. Non-metals use "
"their albedo as the diffuse color and add diffuse to the specular "
@@ -9178,7 +8576,7 @@ msgid ""
"roughness]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:224
+#: doc/classes/BaseMaterial3D.xml:233
msgid ""
"Sets the size of the specular lobe. The specular lobe is the bright spot "
"that is reflected from light sources.\n"
@@ -9187,13 +8585,13 @@ msgid ""
"roughness]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:228
+#: doc/classes/BaseMaterial3D.xml:237
msgid ""
"Texture used to specify metallic for an object. This is multiplied by "
"[member metallic]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:231
+#: doc/classes/BaseMaterial3D.xml:240
msgid ""
"Specifies the channel of the [member metallic_texture] in which the metallic "
"information is stored. This is useful when you store the information for "
@@ -9202,21 +8600,21 @@ msgid ""
"you could reduce the number of textures you use."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:234
+#: doc/classes/BaseMaterial3D.xml:243
msgid ""
"If [code]true[/code], depth testing is disabled and the object will be drawn "
"in render order."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:237
+#: doc/classes/BaseMaterial3D.xml:246
msgid "If [code]true[/code], normal mapping is enabled."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:240
+#: doc/classes/BaseMaterial3D.xml:249
msgid "The strength of the normal map's effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:243
+#: doc/classes/BaseMaterial3D.xml:252
msgid ""
"Texture used to specify the normal at a given pixel. The "
"[code]normal_texture[/code] only uses the red and green channels. The normal "
@@ -9224,93 +8622,100 @@ msgid ""
"provided by the [Mesh]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:248
+#: doc/classes/BaseMaterial3D.xml:257
msgid ""
"The number of horizontal frames in the particle sprite sheet. Only enabled "
"when using [constant BILLBOARD_PARTICLES]. See [member billboard_mode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:251
+#: doc/classes/BaseMaterial3D.xml:260
msgid ""
"If [code]true[/code], particle animations are looped. Only enabled when "
"using [constant BILLBOARD_PARTICLES]. See [member billboard_mode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:254
+#: doc/classes/BaseMaterial3D.xml:263
msgid ""
"The number of vertical frames in the particle sprite sheet. Only enabled "
"when using [constant BILLBOARD_PARTICLES]. See [member billboard_mode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:257
+#: doc/classes/BaseMaterial3D.xml:266
msgid "The point size in pixels. See [member use_point_size]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:260
+#: doc/classes/BaseMaterial3D.xml:269
msgid ""
"Distance over which the fade effect takes place. The larger the distance the "
"longer it takes for an object to fade."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:263
+#: doc/classes/BaseMaterial3D.xml:272
msgid ""
"If [code]true[/code], the proximity fade effect is enabled. The proximity "
"fade effect fades out each pixel based on its distance to another object."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:266
+#: doc/classes/BaseMaterial3D.xml:275
msgid ""
"If [code]true[/code], the refraction effect is enabled. Distorts "
"transparency based on light from behind the object."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:269
+#: doc/classes/BaseMaterial3D.xml:278
msgid "The strength of the refraction effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:272
+#: doc/classes/BaseMaterial3D.xml:281
msgid ""
"Texture that controls the strength of the refraction per-pixel. Multiplied "
"by [member refraction_scale]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:278
+#: doc/classes/BaseMaterial3D.xml:287
msgid "Sets the strength of the rim lighting effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:281
+#: doc/classes/BaseMaterial3D.xml:290
msgid ""
"If [code]true[/code], rim effect is enabled. Rim lighting increases the "
"brightness at glancing angles on an object."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:284
+#: doc/classes/BaseMaterial3D.xml:293
msgid ""
"Texture used to set the strength of the rim lighting effect per-pixel. "
"Multiplied by [member rim]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:287
+#: doc/classes/BaseMaterial3D.xml:296
msgid ""
"The amount of to blend light and albedo color when rendering rim effect. If "
"[code]0[/code] the light color is used, while [code]1[/code] means albedo "
"color is used. An intermediate value generally works best."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:290
+#: doc/classes/BaseMaterial3D.xml:299
msgid ""
"Surface reflection. A value of [code]0[/code] represents a perfect mirror "
"while a value of [code]1[/code] completely blurs the reflection. See also "
"[member metallic]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:293
+#: doc/classes/BaseMaterial3D.xml:302
msgid ""
"Texture used to control the roughness per-pixel. Multiplied by [member "
"roughness]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:301
+#: doc/classes/BaseMaterial3D.xml:308
+msgid ""
+"Sets whether the shading takes place per-pixel or per-vertex. Per-vertex "
+"lighting is faster, making it the best choice for mobile applications, "
+"however it looks considerably worse than per-pixel."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:311
msgid ""
"If [code]true[/code], enables the \"shadow to opacity\" render mode where "
"lighting modifies the alpha so shadowed areas are opaque and non-shadowed "
@@ -9318,77 +8723,67 @@ msgid ""
"AR."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:304
+#: doc/classes/BaseMaterial3D.xml:314
msgid "The method for rendering the specular blob. See [enum SpecularMode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:307
+#: doc/classes/BaseMaterial3D.xml:317
msgid ""
"If [code]true[/code], subsurface scattering is enabled. Emulates light that "
"penetrates an object's surface, is scattered, and then emerges."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:312
+#: doc/classes/BaseMaterial3D.xml:320
+msgid ""
+"If [code]true[/code], subsurface scattering will use a special mode "
+"optimized for the color and density of human skin."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:323
msgid "The strength of the subsurface scattering effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:315
+#: doc/classes/BaseMaterial3D.xml:326
msgid ""
"Texture used to control the subsurface scattering strength. Stored in the "
"red texture channel. Multiplied by [member subsurf_scatter_strength]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:318
+#: doc/classes/BaseMaterial3D.xml:341
msgid "Filter flags for the texture. See [enum TextureFilter] for options."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:321
+#: doc/classes/BaseMaterial3D.xml:344
msgid "Repeat flags for the texture. See [enum TextureFilter] for options."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:324
-msgid ""
-"The color used by the transmission effect. Represents the light passing "
-"through an object."
-msgstr ""
-
-#: doc/classes/BaseMaterial3D.xml:327
-msgid "If [code]true[/code], the transmission effect is enabled."
-msgstr ""
-
-#: doc/classes/BaseMaterial3D.xml:330
-msgid ""
-"Texture used to control the transmission effect per-pixel. Added to [member "
-"transmission]."
-msgstr ""
-
-#: doc/classes/BaseMaterial3D.xml:333
+#: doc/classes/BaseMaterial3D.xml:347
msgid ""
"If [code]true[/code], transparency is enabled on the body. See also [member "
"blend_mode]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:336
+#: doc/classes/BaseMaterial3D.xml:350
msgid ""
"If [code]true[/code], render point size can be changed.\n"
"[b]Note:[/b] this is only effective for objects whose geometry is point-"
"based rather than triangle-based. See also [member point_size]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:340
+#: doc/classes/BaseMaterial3D.xml:354
msgid ""
"How much to offset the [code]UV[/code] coordinates. This amount will be "
"added to [code]UV[/code] in the vertex function. This can be used to offset "
"a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:343
+#: doc/classes/BaseMaterial3D.xml:357
msgid ""
"How much to scale the [code]UV[/code] coordinates. This is multiplied by "
"[code]UV[/code] in the vertex function."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:346
+#: doc/classes/BaseMaterial3D.xml:360
msgid ""
"If [code]true[/code], instead of using [code]UV[/code] textures will use a "
"triplanar texture lookup to determine how to apply textures. Triplanar uses "
@@ -9402,32 +8797,32 @@ msgid ""
"when you are trying to achieve crisp texturing."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:349 doc/classes/BaseMaterial3D.xml:364
+#: doc/classes/BaseMaterial3D.xml:363 doc/classes/BaseMaterial3D.xml:378
msgid ""
"A lower number blends the texture more softly while a higher number blends "
"the texture more sharply."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:352
+#: doc/classes/BaseMaterial3D.xml:366
msgid ""
"If [code]true[/code], triplanar mapping for [code]UV[/code] is calculated in "
"world space rather than object local space. See also [member uv1_triplanar]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:355
+#: doc/classes/BaseMaterial3D.xml:369
msgid ""
"How much to offset the [code]UV2[/code] coordinates. This amount will be "
"added to [code]UV2[/code] in the vertex function. This can be used to offset "
"a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:358
+#: doc/classes/BaseMaterial3D.xml:372
msgid ""
"How much to scale the [code]UV2[/code] coordinates. This is multiplied by "
"[code]UV2[/code] in the vertex function."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:361
+#: doc/classes/BaseMaterial3D.xml:375
msgid ""
"If [code]true[/code], instead of using [code]UV2[/code] textures will use a "
"triplanar texture lookup to determine how to apply textures. Triplanar uses "
@@ -9441,368 +8836,443 @@ msgid ""
"when you are trying to achieve crisp texturing."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:367
+#: doc/classes/BaseMaterial3D.xml:381
msgid ""
"If [code]true[/code], triplanar mapping for [code]UV2[/code] is calculated "
"in world space rather than object local space. See also [member "
"uv2_triplanar]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:370
+#: doc/classes/BaseMaterial3D.xml:384
msgid ""
"If [code]true[/code], the model's vertex colors are processed as sRGB mode."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:373
+#: doc/classes/BaseMaterial3D.xml:387
msgid "If [code]true[/code], the vertex color is used as albedo color."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:378
+#: doc/classes/BaseMaterial3D.xml:392
msgid "Texture specifying per-pixel color."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:381
+#: doc/classes/BaseMaterial3D.xml:395
msgid "Texture specifying per-pixel metallic value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:384
+#: doc/classes/BaseMaterial3D.xml:398
msgid "Texture specifying per-pixel roughness value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:387
+#: doc/classes/BaseMaterial3D.xml:401
msgid "Texture specifying per-pixel emission color."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:390
+#: doc/classes/BaseMaterial3D.xml:404
msgid "Texture specifying per-pixel normal vector."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:393
+#: doc/classes/BaseMaterial3D.xml:407
msgid "Texture specifying per-pixel rim value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:396
+#: doc/classes/BaseMaterial3D.xml:410
msgid "Texture specifying per-pixel clearcoat value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:399
+#: doc/classes/BaseMaterial3D.xml:413
msgid ""
"Texture specifying per-pixel flowmap direction for use with [member "
"anisotropy]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:402
+#: doc/classes/BaseMaterial3D.xml:416
msgid "Texture specifying per-pixel ambient occlusion value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:405
+#: doc/classes/BaseMaterial3D.xml:419
msgid "Texture specifying per-pixel height."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:408
+#: doc/classes/BaseMaterial3D.xml:422
msgid "Texture specifying per-pixel subsurface scattering."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:411
-msgid "Texture specifying per-pixel transmission color."
+#: doc/classes/BaseMaterial3D.xml:425
+msgid "Texture specifying per-pixel transmittance for subsurface scattering."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:414
+#: doc/classes/BaseMaterial3D.xml:428
+msgid "Texture specifying per-pixel backlight color."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:431
msgid "Texture specifying per-pixel refraction strength."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:417
+#: doc/classes/BaseMaterial3D.xml:434
msgid "Texture specifying per-pixel detail mask blending value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:420
+#: doc/classes/BaseMaterial3D.xml:437
msgid "Texture specifying per-pixel detail color."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:423
+#: doc/classes/BaseMaterial3D.xml:440
msgid "Texture specifying per-pixel detail normal."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:428
+#: doc/classes/BaseMaterial3D.xml:443
+msgid "Texture holding ambient occlusion, roughness, and metallic."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:446
msgid "Represents the size of the [enum TextureParam] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:431
+#: doc/classes/BaseMaterial3D.xml:449 doc/classes/RenderingServer.xml:3774
+#: doc/classes/Viewport.xml:390
msgid ""
"The texture filter reads from the nearest pixel only. The simplest and "
"fastest method of filtering, but the texture will look pixelized."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:434 doc/classes/CanvasItem.xml:665
+#: doc/classes/BaseMaterial3D.xml:452 doc/classes/RenderingServer.xml:3777
+#: doc/classes/Viewport.xml:393
msgid ""
-"The texture filter blends between the nearest four pixels. Use this for most "
-"cases where you want to avoid a pixelated style."
+"The texture filter blends between the nearest 4 pixels. Use this when you "
+"want to avoid a pixelated style, but do not want mipmaps."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:445 doc/classes/CanvasItem.xml:676
+#: doc/classes/BaseMaterial3D.xml:455 doc/classes/RenderingServer.xml:3780
+#: doc/classes/Viewport.xml:396
+msgid ""
+"The texture filter reads from the nearest pixel in the nearest mipmap. The "
+"fastest way to read from textures with mipmaps."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:458
+msgid ""
+"The texture filter blends between the nearest 4 pixels and between the "
+"nearest 2 mipmaps. Use this for most cases as mipmaps are important to "
+"smooth out pixels that are far from the camera."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:461 doc/classes/RenderingServer.xml:3786
+msgid ""
+"The texture filter reads from the nearest pixel, but selects a mipmap based "
+"on the angle between the surface and the camera view. This reduces artifacts "
+"on surfaces that are almost in line with the camera."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:464 doc/classes/RenderingServer.xml:3789
+msgid ""
+"The texture filter blends between the nearest 4 pixels and selects a mipmap "
+"based on the angle between the surface and the camera view. This reduces "
+"artifacts on surfaces that are almost in line with the camera. This is the "
+"slowest of the filtering options, but results in the highest quality "
+"texturing."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:467 doc/classes/CanvasItem.xml:677
msgid "Represents the size of the [enum TextureFilter] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:448
+#: doc/classes/BaseMaterial3D.xml:470
msgid "Use [code]UV[/code] with the detail texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:451
+#: doc/classes/BaseMaterial3D.xml:473
msgid "Use [code]UV2[/code] with the detail texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:454
+#: doc/classes/BaseMaterial3D.xml:476
msgid "The material will not use transparency."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:457
+#: doc/classes/BaseMaterial3D.xml:479
msgid "The material will use the texture's alpha values for transparency."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:464
+#: doc/classes/BaseMaterial3D.xml:482
+msgid ""
+"The material will cut off all values below a threshold, the rest will remain "
+"opaque."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:485
+msgid ""
+"The material will use the texture's alpha value for transparency, but will "
+"still be rendered in the pre-pass."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:488
msgid "Represents the size of the [enum Transparency] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:467
+#: doc/classes/BaseMaterial3D.xml:491
msgid "The object will not receive shadows."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:470
+#: doc/classes/BaseMaterial3D.xml:494
msgid ""
"The object will be shaded per pixel. Useful for realistic shading effect."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:473
+#: doc/classes/BaseMaterial3D.xml:497
msgid ""
"The object will be shaded per vertex. Useful when you want cheaper shaders "
"and do not care about visual quality."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:476
+#: doc/classes/BaseMaterial3D.xml:500
msgid "Represents the size of the [enum ShadingMode] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:479
+#: doc/classes/BaseMaterial3D.xml:503
msgid "Constant for setting [member emission_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:482
+#: doc/classes/BaseMaterial3D.xml:506
msgid "Constant for setting [member normal_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:485
+#: doc/classes/BaseMaterial3D.xml:509
msgid "Constant for setting [member rim_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:488
+#: doc/classes/BaseMaterial3D.xml:512
msgid "Constant for setting [member clearcoat_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:491
+#: doc/classes/BaseMaterial3D.xml:515
msgid "Constant for setting [member anisotropy_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:494
+#: doc/classes/BaseMaterial3D.xml:518
msgid "Constant for setting [member ao_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:499
+#: doc/classes/BaseMaterial3D.xml:521
+msgid "Constant for setting [member heightmap_enabled]."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:524
msgid "Constant for setting [member subsurf_scatter_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:502
-msgid "Constant for setting [member transmission_enabled]."
+#: doc/classes/BaseMaterial3D.xml:527
+msgid "Constant for setting [member subsurf_scatter_transmittance_enabled]."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:530
+msgid "Constant for setting [member backlight_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:505
+#: doc/classes/BaseMaterial3D.xml:533
msgid "Constant for setting [member refraction_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:508
+#: doc/classes/BaseMaterial3D.xml:536
msgid "Constant for setting [member detail_enabled]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:511 doc/classes/EditorFeatureProfile.xml:148
+#: doc/classes/BaseMaterial3D.xml:539 doc/classes/EditorFeatureProfile.xml:148
msgid "Represents the size of the [enum Feature] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:514
+#: doc/classes/BaseMaterial3D.xml:542
msgid ""
"Default blend mode. The color of the object is blended over the background "
"based on the object's alpha value."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:517
+#: doc/classes/BaseMaterial3D.xml:545
msgid "The color of the object is added to the background."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:520
+#: doc/classes/BaseMaterial3D.xml:548
msgid "The color of the object is subtracted from the background."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:523
+#: doc/classes/BaseMaterial3D.xml:551
msgid "The color of the object is multiplied by the background."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:526
+#: doc/classes/BaseMaterial3D.xml:554
msgid "Default depth draw mode. Depth is drawn only for opaque objects."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:529
+#: doc/classes/BaseMaterial3D.xml:557
msgid "Depth draw is calculated for both opaque and transparent objects."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:532
+#: doc/classes/BaseMaterial3D.xml:560
msgid "No depth draw."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:535
+#: doc/classes/BaseMaterial3D.xml:563
msgid "Default cull mode. The back of the object is culled when not visible."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:538
+#: doc/classes/BaseMaterial3D.xml:566
msgid "The front of the object is culled when not visible."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:541
+#: doc/classes/BaseMaterial3D.xml:569
msgid "No culling is performed."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:544
+#: doc/classes/BaseMaterial3D.xml:572
msgid ""
"Disables the depth test, so this object is drawn on top of all others. "
"However, objects drawn after it in the draw order may cover it."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:547
+#: doc/classes/BaseMaterial3D.xml:575
msgid "Set [code]ALBEDO[/code] to the per-vertex color specified in the mesh."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:550
+#: doc/classes/BaseMaterial3D.xml:578
msgid ""
"Vertex color is in sRGB space and needs to be converted to linear. Only "
"applies in the Vulkan renderer."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:553
+#: doc/classes/BaseMaterial3D.xml:581
msgid ""
"Uses point size to alter the size of primitive points. Also changes the "
"albedo texture lookup to use [code]POINT_COORD[/code] instead of [code]UV[/"
"code]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:556
+#: doc/classes/BaseMaterial3D.xml:584
msgid ""
"Object is scaled by depth so that it always appears the same size on screen."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:559
+#: doc/classes/BaseMaterial3D.xml:587
msgid ""
"Shader will keep the scale set for the mesh. Otherwise the scale is lost "
"when billboarding. Only applies when [member billboard_mode] is [constant "
"BILLBOARD_ENABLED]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:562 doc/classes/BaseMaterial3D.xml:568
+#: doc/classes/BaseMaterial3D.xml:590 doc/classes/BaseMaterial3D.xml:596
msgid ""
"Use triplanar texture lookup for all texture lookups that would normally use "
"[code]UV[/code]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:565 doc/classes/BaseMaterial3D.xml:571
+#: doc/classes/BaseMaterial3D.xml:593 doc/classes/BaseMaterial3D.xml:599
msgid ""
"Use triplanar texture lookup for all texture lookups that would normally use "
"[code]UV2[/code]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:574
+#: doc/classes/BaseMaterial3D.xml:602
msgid ""
"Use [code]UV2[/code] coordinates to look up from the [member ao_texture]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:577
+#: doc/classes/BaseMaterial3D.xml:605
msgid ""
"Use [code]UV2[/code] coordinates to look up from the [member "
"emission_texture]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:580
+#: doc/classes/BaseMaterial3D.xml:608
msgid "Forces the shader to convert albedo from sRGB space to linear space."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:583
+#: doc/classes/BaseMaterial3D.xml:611
msgid "Disables receiving shadows from other objects."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:586
+#: doc/classes/BaseMaterial3D.xml:614
msgid "Disables receiving ambient light."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:589
+#: doc/classes/BaseMaterial3D.xml:617
msgid "Enables the shadow to opacity feature."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:594
+#: doc/classes/BaseMaterial3D.xml:620 doc/classes/RenderingServer.xml:3801
+#: doc/classes/Viewport.xml:408
+msgid ""
+"Enables the texture to repeat when UV coordinates are outside the 0-1 range. "
+"If using one of the linear filtering modes, this can result in artifacts at "
+"the edges of a texture when the sampler filters across the edges of the "
+"texture."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:623
msgid ""
"Invert values read from a depth texture to convert them to height values "
"(heightmap)."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:599 doc/classes/CPUParticles2D.xml:355
-#: doc/classes/CPUParticles3D.xml:364 doc/classes/GeometryInstance3D.xml:100
+#: doc/classes/BaseMaterial3D.xml:626
+msgid ""
+"Enables the skin mode for subsurface scattering which is used to improve the "
+"look of subsurface scattering when used for human skin."
+msgstr ""
+
+#: doc/classes/BaseMaterial3D.xml:629 doc/classes/CPUParticles2D.xml:355
+#: doc/classes/CPUParticles3D.xml:364 doc/classes/GeometryInstance3D.xml:118
#: doc/classes/ParticlesMaterial.xml:315
msgid "Represents the size of the [enum Flags] enum."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:602
+#: doc/classes/BaseMaterial3D.xml:632
msgid "Default diffuse scattering algorithm."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:605
+#: doc/classes/BaseMaterial3D.xml:635
msgid "Diffuse scattering ignores roughness."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:608
+#: doc/classes/BaseMaterial3D.xml:638
msgid "Extends Lambert to cover more than 90 degrees when roughness increases."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:611
+#: doc/classes/BaseMaterial3D.xml:641
msgid "Attempts to use roughness to emulate microsurfacing."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:614
+#: doc/classes/BaseMaterial3D.xml:644
msgid "Uses a hard cut for lighting, with smoothing affected by roughness."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:617
+#: doc/classes/BaseMaterial3D.xml:647
msgid "Default specular blob."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:620 doc/classes/BaseMaterial3D.xml:623
+#: doc/classes/BaseMaterial3D.xml:650 doc/classes/BaseMaterial3D.xml:653
msgid "Older specular algorithm, included for compatibility."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:626
+#: doc/classes/BaseMaterial3D.xml:656
msgid "Toon blob which changes size based on roughness."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:629
+#: doc/classes/BaseMaterial3D.xml:659
msgid "No specular blob."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:632
+#: doc/classes/BaseMaterial3D.xml:662
msgid "Billboard mode is disabled."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:635
+#: doc/classes/BaseMaterial3D.xml:665
msgid "The object's Z axis will always face the camera."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:638
+#: doc/classes/BaseMaterial3D.xml:668
msgid "The object's X axis will always face the camera."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:641
+#: doc/classes/BaseMaterial3D.xml:671
msgid ""
"Used for particle systems when assigned to [GPUParticles3D] and "
"[CPUParticles3D] nodes. Enables [code]particles_anim_*[/code] properties.\n"
@@ -9810,45 +9280,45 @@ msgid ""
"anim_speed] should also be set to a positive value for the animation to play."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:645
+#: doc/classes/BaseMaterial3D.xml:675
msgid "Used to read from the red channel of a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:648
+#: doc/classes/BaseMaterial3D.xml:678
msgid "Used to read from the green channel of a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:651
+#: doc/classes/BaseMaterial3D.xml:681
msgid "Used to read from the blue channel of a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:654
+#: doc/classes/BaseMaterial3D.xml:684
msgid "Used to read from the alpha channel of a texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:657
+#: doc/classes/BaseMaterial3D.xml:687
msgid "Currently unused."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:660
+#: doc/classes/BaseMaterial3D.xml:690
msgid "Adds the emission color to the color from the emission texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:663
+#: doc/classes/BaseMaterial3D.xml:693
msgid "Multiplies the emission color by the color from the emission texture."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:666
+#: doc/classes/BaseMaterial3D.xml:696
msgid "Do not use distance fade."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:669
+#: doc/classes/BaseMaterial3D.xml:699
msgid ""
"Smoothly fades the object out based on each pixel's distance from the camera "
"using the alpha channel."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:672
+#: doc/classes/BaseMaterial3D.xml:702
msgid ""
"Smoothly fades the object out based on each pixel's distance from the camera "
"using a dither approach. Dithering discards pixels based on a set pattern to "
@@ -9856,7 +9326,7 @@ msgid ""
"faster than [constant DISTANCE_FADE_PIXEL_ALPHA]."
msgstr ""
-#: doc/classes/BaseMaterial3D.xml:675
+#: doc/classes/BaseMaterial3D.xml:705
msgid ""
"Smoothly fades the object out based on the object's distance from the camera "
"using a dither approach. Dithering discards pixels based on a set pattern to "
@@ -10530,176 +10000,181 @@ msgid ""
"scenes than manually changing the position of [CanvasItem]-based nodes.\n"
"This node is intended to be a simple helper to get things going quickly and "
"it may happen that more functionality is desired to change how the camera "
-"works. To make your own custom camera node, simply inherit from [Node2D] and "
-"change the transform of the canvas by calling get_viewport()."
-"set_canvas_transform(m) in [Viewport]."
+"works. To make your own custom camera node, inherit from [Node2D] and change "
+"the transform of the canvas by setting [member Viewport.canvas_transform] in "
+"[Viewport] (you can obtain the current [Viewport] by using [method Node."
+"get_viewport]).\n"
+"Note that the [Camera2D] node's [code]position[/code] doesn't represent the "
+"actual position of the screen, which may differ due to applied smoothing or "
+"limits. You can use [method get_camera_screen_center] to get the real "
+"position."
msgstr ""
-#: doc/classes/Camera2D.xml:17
+#: doc/classes/Camera2D.xml:18
msgid "Aligns the camera to the tracked node."
msgstr ""
-#: doc/classes/Camera2D.xml:24
+#: doc/classes/Camera2D.xml:25
msgid ""
"Removes any [Camera2D] from the ancestor [Viewport]'s internal currently-"
"assigned camera."
msgstr ""
-#: doc/classes/Camera2D.xml:31
+#: doc/classes/Camera2D.xml:32
msgid "Forces the camera to update scroll immediately."
msgstr ""
-#: doc/classes/Camera2D.xml:38
+#: doc/classes/Camera2D.xml:39
msgid "Returns the camera position."
msgstr ""
-#: doc/classes/Camera2D.xml:45
+#: doc/classes/Camera2D.xml:46
msgid ""
"Returns the location of the [Camera2D]'s screen-center, relative to the "
"origin."
msgstr ""
-#: doc/classes/Camera2D.xml:54
+#: doc/classes/Camera2D.xml:55
msgid ""
"Returns the specified margin. See also [member drag_margin_bottom], [member "
"drag_margin_top], [member drag_margin_left], and [member drag_margin_right]."
msgstr ""
-#: doc/classes/Camera2D.xml:63
+#: doc/classes/Camera2D.xml:64
msgid ""
"Returns the specified camera limit. See also [member limit_bottom], [member "
"limit_top], [member limit_left], and [member limit_right]."
msgstr ""
-#: doc/classes/Camera2D.xml:70
+#: doc/classes/Camera2D.xml:71
msgid ""
"Make this the current 2D camera for the scene (viewport and layer), in case "
"there are many cameras in the scene."
msgstr ""
-#: doc/classes/Camera2D.xml:77
+#: doc/classes/Camera2D.xml:78
msgid ""
"Sets the camera's position immediately to its current smoothing "
"destination.\n"
"This has no effect if smoothing is disabled."
msgstr ""
-#: doc/classes/Camera2D.xml:89
+#: doc/classes/Camera2D.xml:90
msgid ""
"Sets the specified margin. See also [member drag_margin_bottom], [member "
"drag_margin_top], [member drag_margin_left], and [member drag_margin_right]."
msgstr ""
-#: doc/classes/Camera2D.xml:100
+#: doc/classes/Camera2D.xml:101
msgid ""
"Sets the specified camera limit. See also [member limit_bottom], [member "
"limit_top], [member limit_left], and [member limit_right]."
msgstr ""
-#: doc/classes/Camera2D.xml:106
+#: doc/classes/Camera2D.xml:107
msgid "The Camera2D's anchor point. See [enum AnchorMode] constants."
msgstr ""
-#: doc/classes/Camera2D.xml:109
+#: doc/classes/Camera2D.xml:110
msgid ""
"If [code]true[/code], the camera is the active camera for the current scene. "
"Only one camera can be current, so setting a different camera [code]current[/"
"code] will disable this one."
msgstr ""
-#: doc/classes/Camera2D.xml:112
+#: doc/classes/Camera2D.xml:113
msgid ""
"The custom [Viewport] node attached to the [Camera2D]. If [code]null[/code] "
"or not a [Viewport], uses the default viewport instead."
msgstr ""
-#: doc/classes/Camera2D.xml:115
+#: doc/classes/Camera2D.xml:116
msgid ""
"Bottom margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-#: doc/classes/Camera2D.xml:118
+#: doc/classes/Camera2D.xml:119
msgid ""
"If [code]true[/code], the camera only moves when reaching the horizontal "
"drag margins. If [code]false[/code], the camera moves horizontally "
"regardless of margins."
msgstr ""
-#: doc/classes/Camera2D.xml:121
+#: doc/classes/Camera2D.xml:122
msgid ""
"Left margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-#: doc/classes/Camera2D.xml:124
+#: doc/classes/Camera2D.xml:125
msgid ""
"Right margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-#: doc/classes/Camera2D.xml:127
+#: doc/classes/Camera2D.xml:128
msgid ""
"Top margin needed to drag the camera. A value of [code]1[/code] makes the "
"camera move only when reaching the edge of the screen."
msgstr ""
-#: doc/classes/Camera2D.xml:130
+#: doc/classes/Camera2D.xml:131
msgid ""
"If [code]true[/code], the camera only moves when reaching the vertical drag "
"margins. If [code]false[/code], the camera moves vertically regardless of "
"margins."
msgstr ""
-#: doc/classes/Camera2D.xml:133
+#: doc/classes/Camera2D.xml:134
msgid ""
"If [code]true[/code], draws the camera's drag margin rectangle in the editor."
msgstr ""
-#: doc/classes/Camera2D.xml:136
+#: doc/classes/Camera2D.xml:137
msgid ""
"If [code]true[/code], draws the camera's limits rectangle in the editor."
msgstr ""
-#: doc/classes/Camera2D.xml:139
+#: doc/classes/Camera2D.xml:140
msgid ""
"If [code]true[/code], draws the camera's screen rectangle in the editor."
msgstr ""
-#: doc/classes/Camera2D.xml:142
+#: doc/classes/Camera2D.xml:143
msgid ""
"Bottom scroll limit in pixels. The camera stops moving when reaching this "
"value."
msgstr ""
-#: doc/classes/Camera2D.xml:145
+#: doc/classes/Camera2D.xml:146
msgid ""
"Left scroll limit in pixels. The camera stops moving when reaching this "
"value."
msgstr ""
-#: doc/classes/Camera2D.xml:148
+#: doc/classes/Camera2D.xml:149
msgid ""
"Right scroll limit in pixels. The camera stops moving when reaching this "
"value."
msgstr ""
-#: doc/classes/Camera2D.xml:151
+#: doc/classes/Camera2D.xml:152
msgid ""
"If [code]true[/code], the camera smoothly stops when reaches its limits."
msgstr ""
-#: doc/classes/Camera2D.xml:154
+#: doc/classes/Camera2D.xml:155
msgid ""
"Top scroll limit in pixels. The camera stops moving when reaching this value."
msgstr ""
-#: doc/classes/Camera2D.xml:157
+#: doc/classes/Camera2D.xml:158
msgid ""
"The camera's offset, useful for looking around or camera shake animations."
msgstr ""
-#: doc/classes/Camera2D.xml:160
+#: doc/classes/Camera2D.xml:161
msgid ""
"The horizontal offset of the camera, relative to the drag margins.\n"
"[b]Note:[/b] Offset H is used only to force offset relative to margins. It's "
@@ -10707,33 +10182,33 @@ msgid ""
"initial offset."
msgstr ""
-#: doc/classes/Camera2D.xml:164
+#: doc/classes/Camera2D.xml:165
msgid ""
"The vertical offset of the camera, relative to the drag margins.\n"
"[b]Note:[/b] Used the same as [member offset_h]."
msgstr ""
-#: doc/classes/Camera2D.xml:168
+#: doc/classes/Camera2D.xml:169
msgid "The camera's process callback. See [enum Camera2DProcessMode]."
msgstr ""
-#: doc/classes/Camera2D.xml:171
+#: doc/classes/Camera2D.xml:172
msgid "If [code]true[/code], the camera rotates with the target."
msgstr ""
-#: doc/classes/Camera2D.xml:174
+#: doc/classes/Camera2D.xml:175
msgid ""
"If [code]true[/code], the camera smoothly moves towards the target at "
"[member smoothing_speed]."
msgstr ""
-#: doc/classes/Camera2D.xml:177
+#: doc/classes/Camera2D.xml:178
msgid ""
"Speed in pixels per second of the camera's smoothing effect when [member "
"smoothing_enabled] is [code]true[/code]."
msgstr ""
-#: doc/classes/Camera2D.xml:180
+#: doc/classes/Camera2D.xml:181
msgid ""
"The camera's zoom relative to the viewport. Values larger than "
"[code]Vector2(1, 1)[/code] zoom out and smaller values zoom in. For an "
@@ -10741,23 +10216,23 @@ msgid ""
"[code]Vector2(4, 4)[/code] for a 4× zoom-out."
msgstr ""
-#: doc/classes/Camera2D.xml:185
+#: doc/classes/Camera2D.xml:186
msgid ""
"The camera's position is fixed so that the top-left corner is always at the "
"origin."
msgstr ""
-#: doc/classes/Camera2D.xml:188
+#: doc/classes/Camera2D.xml:189
msgid ""
"The camera's position takes into account vertical/horizontal offsets and the "
"screen size."
msgstr ""
-#: doc/classes/Camera2D.xml:191 doc/classes/ClippedCamera3D.xml:104
+#: doc/classes/Camera2D.xml:192 doc/classes/ClippedCamera3D.xml:104
msgid "The camera updates with the [code]_physics_process[/code] callback."
msgstr ""
-#: doc/classes/Camera2D.xml:194 doc/classes/ClippedCamera3D.xml:107
+#: doc/classes/Camera2D.xml:195 doc/classes/ClippedCamera3D.xml:107
msgid "The camera updates with the [code]_process[/code] callback."
msgstr ""
@@ -11019,6 +10494,72 @@ msgid ""
"Audio's [code]pitch shift[/code])."
msgstr ""
+#: doc/classes/CameraEffects.xml:4
+msgid ""
+"Contains camera-specific effects such as depth of field and exposure "
+"override."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:7
+msgid ""
+"Contains camera-specific effects such as depth of field and exposure "
+"override.\n"
+"See also [Environment] for general 3D environment settings."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:16
+msgid ""
+"The amount of blur for both near and far depth-of-field effects. The amount "
+"of blur increases the radius of the blur effect, making the affected area "
+"blurrier. However, If the amount is too high, you might start to see lines "
+"appearing, especially when using a low quality blur."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:19
+msgid ""
+"The distance from the camera where the far blur effect affects the rendering."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:22
+msgid ""
+"If [code]true[/code], enables the depth-of-field far blur effect. This has a "
+"significant performance cost. Consider disabling it in scenes where there "
+"are no far away objects."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:25
+msgid "The length of the transition between the no-blur area and far blur."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:28
+msgid ""
+"Distance from the camera where the near blur effect affects the rendering."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:31
+msgid ""
+"If [code]true[/code], enables the depth-of-field near blur effect. This has "
+"a significant performance cost. Consider disabling it in scenes where there "
+"are no nearby objects."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:34
+msgid "The length of the transition between the near blur and no-blur area."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:37
+msgid ""
+"The exposure override value to use. Higher values will result in a brighter "
+"scene. Only effective if [member override_exposure_enable] is [code]true[/"
+"code]."
+msgstr ""
+
+#: doc/classes/CameraEffects.xml:40
+msgid ""
+"If [code]true[/code], overrides the manual or automatic exposure defined in "
+"the [Environment] with the value in [member override_exposure]."
+msgstr ""
+
#: doc/classes/CameraFeed.xml:4
msgid ""
"A camera feed gives you access to a single physical camera attached to your "
@@ -11029,7 +10570,7 @@ msgstr ""
msgid ""
"A camera feed gives you access to a single physical camera attached to your "
"device. When enabled, Godot will start capturing frames from the camera "
-"which can then be used.\n"
+"which can then be used. See also [CameraServer].\n"
"[b]Note:[/b] Many cameras will return YCbCr images which are split into two "
"textures and need to be combined in a shader. Godot does this automatically "
"for you if you set the environment to show the camera image in the "
@@ -11044,50 +10585,54 @@ msgstr ""
msgid ""
"The [CameraServer] keeps track of different cameras accessible in Godot. "
"These are external cameras such as webcams or the cameras on your phone.\n"
-"It is notably used to provide AR modules with a video feed from the camera."
+"It is notably used to provide AR modules with a video feed from the camera.\n"
+"[b]Note:[/b] This class is currently only implemented on macOS and iOS. On "
+"other platforms, no [CameraFeed]s will be available."
msgstr ""
-#: doc/classes/CameraServer.xml:19
-msgid "Adds a camera feed to the camera server."
+#: doc/classes/CameraServer.xml:20
+msgid "Adds the camera [code]feed[/code] to the camera server."
msgstr ""
-#: doc/classes/CameraServer.xml:26
+#: doc/classes/CameraServer.xml:27
msgid "Returns an array of [CameraFeed]s."
msgstr ""
-#: doc/classes/CameraServer.xml:35
-msgid "Returns the [CameraFeed] with this id."
+#: doc/classes/CameraServer.xml:36
+msgid ""
+"Returns the [CameraFeed] corresponding to the camera with the given "
+"[code]index[/code]."
msgstr ""
-#: doc/classes/CameraServer.xml:42
+#: doc/classes/CameraServer.xml:43
msgid "Returns the number of [CameraFeed]s registered."
msgstr ""
-#: doc/classes/CameraServer.xml:51
-msgid "Removes a [CameraFeed]."
+#: doc/classes/CameraServer.xml:52
+msgid "Removes the specified camera [code]feed[/code]."
msgstr ""
-#: doc/classes/CameraServer.xml:60
-msgid "Emitted when a [CameraFeed] is added (e.g. webcam is plugged in)."
+#: doc/classes/CameraServer.xml:61
+msgid "Emitted when a [CameraFeed] is added (e.g. a webcam is plugged in)."
msgstr ""
-#: doc/classes/CameraServer.xml:67
-msgid "Emitted when a [CameraFeed] is removed (e.g. webcam is unplugged)."
+#: doc/classes/CameraServer.xml:68
+msgid "Emitted when a [CameraFeed] is removed (e.g. a webcam is unplugged)."
msgstr ""
-#: doc/classes/CameraServer.xml:73
+#: doc/classes/CameraServer.xml:74
msgid "The RGBA camera image."
msgstr ""
-#: doc/classes/CameraServer.xml:76
-msgid "The YCbCr camera image."
+#: doc/classes/CameraServer.xml:77
+msgid "The [url=https://en.wikipedia.org/wiki/YCbCr]YCbCr[/url] camera image."
msgstr ""
-#: doc/classes/CameraServer.xml:79
+#: doc/classes/CameraServer.xml:80
msgid "The Y component camera image."
msgstr ""
-#: doc/classes/CameraServer.xml:82
+#: doc/classes/CameraServer.xml:83
msgid "The CbCr component camera image."
msgstr ""
@@ -11143,97 +10688,100 @@ msgid ""
"its children) and self modulation (only for itself), as well as its blend "
"mode.\n"
"Ultimately, a transform notification can be requested, which will notify the "
-"node that its global position changed in case the parent tree changed."
+"node that its global position changed in case the parent tree changed.\n"
+"[b]Note:[/b] Unless otherwise specified, all methods that have angle "
+"parameters must have angles specified as [i]radians[/i]. To convert degrees "
+"to radians, use [method @GDScript.deg2rad]."
msgstr ""
-#: doc/classes/CanvasItem.xml:14 doc/classes/CanvasLayer.xml:10
+#: doc/classes/CanvasItem.xml:15 doc/classes/CanvasLayer.xml:10
#: doc/classes/InputEvent.xml:11 doc/classes/Viewport.xml:15
msgid "https://docs.godotengine.org/en/latest/tutorials/2d/2d_transforms.html"
msgstr ""
-#: doc/classes/CanvasItem.xml:15 doc/classes/Control.xml:19
+#: doc/classes/CanvasItem.xml:16 doc/classes/Control.xml:19
#: doc/classes/Node2D.xml:10
msgid ""
"https://docs.godotengine.org/en/latest/tutorials/2d/custom_drawing_in_2d.html"
msgstr ""
-#: doc/classes/CanvasItem.xml:22
+#: doc/classes/CanvasItem.xml:23
msgid ""
"Overridable function called by the engine (if defined) to draw the canvas "
"item."
msgstr ""
-#: doc/classes/CanvasItem.xml:43
+#: doc/classes/CanvasItem.xml:44
msgid ""
"Draws an arc between the given angles. The larger the value of "
"[code]point_count[/code], the smoother the curve."
msgstr ""
-#: doc/classes/CanvasItem.xml:60
+#: doc/classes/CanvasItem.xml:61
msgid ""
"Draws a string character using a custom font. Returns the advance, depending "
"on the character width and kerning with an optional next character."
msgstr ""
-#: doc/classes/CanvasItem.xml:73
+#: doc/classes/CanvasItem.xml:74
msgid "Draws a colored circle."
msgstr ""
-#: doc/classes/CanvasItem.xml:98
+#: doc/classes/CanvasItem.xml:99
msgid "Draws a colored polygon of any amount of points, convex or concave."
msgstr ""
-#: doc/classes/CanvasItem.xml:113
+#: doc/classes/CanvasItem.xml:114
msgid "Draws a line from a 2D point to another, with a given color and width."
msgstr ""
-#: doc/classes/CanvasItem.xml:138
+#: doc/classes/CanvasItem.xml:139
msgid ""
"Draws a [Mesh] in 2D, using the provided texture. See [MeshInstance2D] for "
"related documentation."
msgstr ""
-#: doc/classes/CanvasItem.xml:151
+#: doc/classes/CanvasItem.xml:152
msgid "Draws multiple, parallel lines with a uniform [code]color[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:164
+#: doc/classes/CanvasItem.xml:165
msgid ""
"Draws multiple, parallel lines with a uniform [code]width[/code] and segment-"
"by-segment coloring. Colors assigned to line segments match by index between "
"[code]points[/code] and [code]colors[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:185
+#: doc/classes/CanvasItem.xml:186
msgid ""
"Draws a [MultiMesh] in 2D with the provided texture. See "
"[MultiMeshInstance2D] for related documentation."
msgstr ""
-#: doc/classes/CanvasItem.xml:210
+#: doc/classes/CanvasItem.xml:211
msgid "Draws a polygon of any amount of points, convex or concave."
msgstr ""
-#: doc/classes/CanvasItem.xml:223
+#: doc/classes/CanvasItem.xml:224
msgid ""
"Draws interconnected line segments with a uniform [code]color[/code] and "
"[code]width[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:236
+#: doc/classes/CanvasItem.xml:237
msgid ""
"Draws interconnected line segments with a uniform [code]width[/code] and "
"segment-by-segment coloring. Colors assigned to line segments match by index "
"between [code]points[/code] and [code]colors[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:263
+#: doc/classes/CanvasItem.xml:264
msgid ""
"Draws a custom primitive. 1 point for a point, 2 points for a line, 3 points "
"for a triangle, and 4 points for a quad."
msgstr ""
-#: doc/classes/CanvasItem.xml:278
+#: doc/classes/CanvasItem.xml:279
msgid ""
"Draws a rectangle. If [code]filled[/code] is [code]true[/code], the "
"rectangle will be filled with the [code]color[/code] specified. If "
@@ -11243,272 +10791,278 @@ msgid ""
"[code]false[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:292
+#: doc/classes/CanvasItem.xml:293
msgid ""
"Sets a custom transform for drawing via components. Anything drawn "
"afterwards will be transformed by this."
msgstr ""
-#: doc/classes/CanvasItem.xml:301
+#: doc/classes/CanvasItem.xml:302
msgid ""
"Sets a custom transform for drawing via matrix. Anything drawn afterwards "
"will be transformed by this."
msgstr ""
-#: doc/classes/CanvasItem.xml:318
+#: doc/classes/CanvasItem.xml:319
msgid "Draws a string using a custom font."
msgstr ""
-#: doc/classes/CanvasItem.xml:329
+#: doc/classes/CanvasItem.xml:330
msgid "Draws a styled rectangle."
msgstr ""
-#: doc/classes/CanvasItem.xml:352
+#: doc/classes/CanvasItem.xml:353
msgid "Draws a texture at a given position."
msgstr ""
-#: doc/classes/CanvasItem.xml:379
+#: doc/classes/CanvasItem.xml:380
msgid ""
"Draws a textured rectangle at a given position, optionally modulated by a "
"color. If [code]transpose[/code] is [code]true[/code], the texture will have "
"its X and Y coordinates swapped."
msgstr ""
-#: doc/classes/CanvasItem.xml:408
+#: doc/classes/CanvasItem.xml:409
msgid ""
"Draws a textured rectangle region at a given position, optionally modulated "
"by a color. If [code]transpose[/code] is [code]true[/code], the texture will "
"have its X and Y coordinates swapped."
msgstr ""
-#: doc/classes/CanvasItem.xml:415 doc/classes/Node3D.xml:18
+#: doc/classes/CanvasItem.xml:416 doc/classes/Node3D.xml:19
msgid ""
"Forces the transform to update. Transform changes in physics are not instant "
"for performance reasons. Transforms are accumulated and then set. Use this "
"if you need an up-to-date transform when doing physics operations."
msgstr ""
-#: doc/classes/CanvasItem.xml:422
+#: doc/classes/CanvasItem.xml:423
msgid "Returns the [RID] of the [World2D] canvas where this item is in."
msgstr ""
-#: doc/classes/CanvasItem.xml:429
+#: doc/classes/CanvasItem.xml:430
msgid "Returns the canvas item RID used by [RenderingServer] for this item."
msgstr ""
-#: doc/classes/CanvasItem.xml:436
+#: doc/classes/CanvasItem.xml:437
msgid "Returns the transform matrix of this item's canvas."
msgstr ""
-#: doc/classes/CanvasItem.xml:443
+#: doc/classes/CanvasItem.xml:444
msgid "Returns the global position of the mouse."
msgstr ""
-#: doc/classes/CanvasItem.xml:450
+#: doc/classes/CanvasItem.xml:451
msgid "Returns the global transform matrix of this item."
msgstr ""
-#: doc/classes/CanvasItem.xml:457
+#: doc/classes/CanvasItem.xml:458
msgid ""
"Returns the global transform matrix of this item in relation to the canvas."
msgstr ""
-#: doc/classes/CanvasItem.xml:464
+#: doc/classes/CanvasItem.xml:465
msgid "Returns the mouse position relative to this item's position."
msgstr ""
-#: doc/classes/CanvasItem.xml:471
+#: doc/classes/CanvasItem.xml:472
msgid "Returns the transform matrix of this item."
msgstr ""
-#: doc/classes/CanvasItem.xml:478
+#: doc/classes/CanvasItem.xml:479
msgid "Returns the viewport's boundaries as a [Rect2]."
msgstr ""
-#: doc/classes/CanvasItem.xml:485
+#: doc/classes/CanvasItem.xml:486
msgid "Returns this item's transform in relation to the viewport."
msgstr ""
-#: doc/classes/CanvasItem.xml:492
+#: doc/classes/CanvasItem.xml:493
msgid "Returns the [World2D] where this item is in."
msgstr ""
-#: doc/classes/CanvasItem.xml:499
+#: doc/classes/CanvasItem.xml:500
msgid "Hide the [CanvasItem] if it's currently visible."
msgstr ""
-#: doc/classes/CanvasItem.xml:506
+#: doc/classes/CanvasItem.xml:507
msgid ""
"Returns [code]true[/code] if local transform notifications are communicated "
"to children."
msgstr ""
-#: doc/classes/CanvasItem.xml:513
+#: doc/classes/CanvasItem.xml:514
msgid ""
"Returns [code]true[/code] if the node is set as top-level. See [method "
"set_as_toplevel]."
msgstr ""
-#: doc/classes/CanvasItem.xml:520
+#: doc/classes/CanvasItem.xml:521
msgid ""
"Returns [code]true[/code] if global transform notifications are communicated "
"to children."
msgstr ""
-#: doc/classes/CanvasItem.xml:527
+#: doc/classes/CanvasItem.xml:528
msgid ""
"Returns [code]true[/code] if the node is present in the [SceneTree], its "
"[member visible] property is [code]true[/code] and its inherited visibility "
"is also [code]true[/code]."
msgstr ""
-#: doc/classes/CanvasItem.xml:536
+#: doc/classes/CanvasItem.xml:537
msgid "Assigns [code]screen_point[/code] as this node's new local transform."
msgstr ""
-#: doc/classes/CanvasItem.xml:545
+#: doc/classes/CanvasItem.xml:546
msgid ""
"Transformations issued by [code]event[/code]'s inputs are applied in local "
"space instead of global space."
msgstr ""
-#: doc/classes/CanvasItem.xml:554
+#: doc/classes/CanvasItem.xml:555
msgid ""
"If [code]enable[/code] is [code]true[/code], the node won't inherit its "
"transform from parent canvas items."
msgstr ""
-#: doc/classes/CanvasItem.xml:563
+#: doc/classes/CanvasItem.xml:564
msgid ""
"If [code]enable[/code] is [code]true[/code], children will be updated with "
"local transform data."
msgstr ""
-#: doc/classes/CanvasItem.xml:572
+#: doc/classes/CanvasItem.xml:573
msgid ""
"If [code]enable[/code] is [code]true[/code], children will be updated with "
"global transform data."
msgstr ""
-#: doc/classes/CanvasItem.xml:579
+#: doc/classes/CanvasItem.xml:580
msgid ""
"Show the [CanvasItem] if it's currently hidden. For controls that inherit "
"[Popup], the correct way to make them visible is to call one of the multiple "
"[code]popup*()[/code] functions instead."
msgstr ""
-#: doc/classes/CanvasItem.xml:586
+#: doc/classes/CanvasItem.xml:587
msgid ""
"Queue the [CanvasItem] for update. [constant NOTIFICATION_DRAW] will be "
"called on idle time to request redraw."
msgstr ""
-#: doc/classes/CanvasItem.xml:592
+#: doc/classes/CanvasItem.xml:593
msgid ""
"The rendering layers in which this [CanvasItem] responds to [Light2D] nodes."
msgstr ""
-#: doc/classes/CanvasItem.xml:595
+#: doc/classes/CanvasItem.xml:596
msgid "The material applied to textures on this [CanvasItem]."
msgstr ""
-#: doc/classes/CanvasItem.xml:598
+#: doc/classes/CanvasItem.xml:599
msgid "The color applied to textures on this [CanvasItem]."
msgstr ""
-#: doc/classes/CanvasItem.xml:601
+#: doc/classes/CanvasItem.xml:602
msgid ""
"The color applied to textures on this [CanvasItem]. This is not inherited by "
"children [CanvasItem]s."
msgstr ""
-#: doc/classes/CanvasItem.xml:604
+#: doc/classes/CanvasItem.xml:605
msgid "If [code]true[/code], the object draws behind its parent."
msgstr ""
-#: doc/classes/CanvasItem.xml:607
+#: doc/classes/CanvasItem.xml:608
msgid "If [code]true[/code], the object draws on top of its parent."
msgstr ""
-#: doc/classes/CanvasItem.xml:614
+#: doc/classes/CanvasItem.xml:615
msgid ""
"If [code]true[/code], the parent [CanvasItem]'s [member material] property "
"is used as this one's material."
msgstr ""
-#: doc/classes/CanvasItem.xml:617
+#: doc/classes/CanvasItem.xml:618
msgid ""
"If [code]true[/code], this [CanvasItem] is drawn. For controls that inherit "
"[Popup], the correct way to make them visible is to call one of the multiple "
"[code]popup*()[/code] functions instead."
msgstr ""
-#: doc/classes/CanvasItem.xml:623
+#: doc/classes/CanvasItem.xml:624
msgid ""
"Emitted when the [CanvasItem] must redraw. This can only be connected "
"realtime, as deferred will not allow drawing."
msgstr ""
-#: doc/classes/CanvasItem.xml:628
+#: doc/classes/CanvasItem.xml:629
msgid "Emitted when becoming hidden."
msgstr ""
-#: doc/classes/CanvasItem.xml:633
+#: doc/classes/CanvasItem.xml:634
msgid "Emitted when the item rect has changed."
msgstr ""
-#: doc/classes/CanvasItem.xml:638
+#: doc/classes/CanvasItem.xml:639
msgid "Emitted when the visibility (hidden/visible) changes."
msgstr ""
-#: doc/classes/CanvasItem.xml:644
+#: doc/classes/CanvasItem.xml:645
msgid ""
"The [CanvasItem]'s transform has changed. This notification is only received "
"if enabled by [method set_notify_transform] or [method "
"set_notify_local_transform]."
msgstr ""
-#: doc/classes/CanvasItem.xml:647
+#: doc/classes/CanvasItem.xml:648
msgid "The [CanvasItem] is requested to draw."
msgstr ""
-#: doc/classes/CanvasItem.xml:650
+#: doc/classes/CanvasItem.xml:651
msgid "The [CanvasItem]'s visibility has changed."
msgstr ""
-#: doc/classes/CanvasItem.xml:653
+#: doc/classes/CanvasItem.xml:654
msgid "The [CanvasItem] has entered the canvas."
msgstr ""
-#: doc/classes/CanvasItem.xml:656
+#: doc/classes/CanvasItem.xml:657
msgid "The [CanvasItem] has exited the canvas."
msgstr ""
-#: doc/classes/CanvasItem.xml:659 doc/classes/CanvasItem.xml:679
+#: doc/classes/CanvasItem.xml:660 doc/classes/CanvasItem.xml:680
msgid "The [CanvasItem] will inherit the filter from its parent."
msgstr ""
-#: doc/classes/CanvasItem.xml:662
+#: doc/classes/CanvasItem.xml:663
msgid ""
"The texture filter reads from the nearest pixel only. The simplest and "
"fastest method of filtering. Useful for pixel art."
msgstr ""
-#: doc/classes/CanvasItem.xml:682
+#: doc/classes/CanvasItem.xml:666
+msgid ""
+"The texture filter blends between the nearest four pixels. Use this for most "
+"cases where you want to avoid a pixelated style."
+msgstr ""
+
+#: doc/classes/CanvasItem.xml:683
msgid "Texture will not repeat."
msgstr ""
-#: doc/classes/CanvasItem.xml:685
+#: doc/classes/CanvasItem.xml:686
msgid "Texture will repeat normally."
msgstr ""
-#: doc/classes/CanvasItem.xml:688
+#: doc/classes/CanvasItem.xml:689
msgid ""
"Texture will repeat in a 2x2 tiled mode, where elements at even positions "
"are mirrored."
msgstr ""
-#: doc/classes/CanvasItem.xml:691
+#: doc/classes/CanvasItem.xml:692
msgid "Represents the size of the [enum TextureRepeat] enum."
msgstr ""
@@ -12696,25 +12250,24 @@ msgid ""
"component."
msgstr ""
-#: doc/classes/Color.xml:158
+#: doc/classes/Color.xml:160
msgid ""
-"Returns a new color resulting from making this color lighter by the "
-"specified percentage (ratio from 0 to 1).\n"
+"Returns the linear interpolation with another color. The interpolation "
+"factor [code]t[/code] is between 0 and 1.\n"
"[codeblock]\n"
-"var green = Color(0.0, 1.0, 0.0)\n"
-"var lightgreen = green.lightened(0.2) # 20% lighter than regular green\n"
+"var c1 = Color(1.0, 0.0, 0.0)\n"
+"var c2 = Color(0.0, 1.0, 0.0)\n"
+"var li_c = c1.lerp(c2, 0.5) # A color of an RGBA(128, 128, 0, 255)\n"
"[/codeblock]"
msgstr ""
-#: doc/classes/Color.xml:173
+#: doc/classes/Color.xml:174
msgid ""
-"Returns the linear interpolation with another color. The interpolation "
-"factor [code]t[/code] is between 0 and 1.\n"
+"Returns a new color resulting from making this color lighter by the "
+"specified percentage (ratio from 0 to 1).\n"
"[codeblock]\n"
-"var c1 = Color(1.0, 0.0, 0.0)\n"
-"var c2 = Color(0.0, 1.0, 0.0)\n"
-"var li_c = c1.linear_interpolate(c2, 0.5) # A color of an RGBA(128, 128, 0, "
-"255)\n"
+"var green = Color(0.0, 1.0, 0.0)\n"
+"var lightgreen = green.lightened(0.2) # 20% lighter than regular green\n"
"[/codeblock]"
msgstr ""
@@ -13736,7 +13289,7 @@ msgid ""
msgstr ""
#: doc/classes/ConeTwistJoint3D.xml:77 doc/classes/Generic6DOFJoint3D.xml:404
-#: doc/classes/HingeJoint3D.xml:109 doc/classes/Light3D.xml:124
+#: doc/classes/HingeJoint3D.xml:109 doc/classes/Light3D.xml:145
#: doc/classes/SliderJoint3D.xml:170
msgid "Represents the size of the [enum Param] enum."
msgstr ""
@@ -14620,8 +14173,8 @@ msgstr ""
#: doc/classes/Control.xml:801
msgid ""
"Tells Godot which node it should give keyboard focus to if the user presses "
-"Tab on a keyboard by default. You can change the key by editing the "
-"[code]ui_focus_next[/code] input action.\n"
+"[kbd]Tab[/kbd] on a keyboard by default. You can change the key by editing "
+"the [code]ui_focus_next[/code] input action.\n"
"If this property is not set, Godot will select a \"best guess\" based on "
"surrounding nodes in the scene tree."
msgstr ""
@@ -14629,8 +14182,8 @@ msgstr ""
#: doc/classes/Control.xml:805
msgid ""
"Tells Godot which node it should give keyboard focus to if the user presses "
-"Shift+Tab on a keyboard by default. You can change the key by editing the "
-"[code]ui_focus_prev[/code] input action.\n"
+"[kbd]Shift + Tab[/kbd] on a keyboard by default. You can change the key by "
+"editing the [code]ui_focus_prev[/code] input action.\n"
"If this property is not set, Godot will select a \"best guess\" based on "
"surrounding nodes in the scene tree."
msgstr ""
@@ -14712,9 +14265,9 @@ msgstr ""
#: doc/classes/Control.xml:841
msgid ""
-"Enables whether rendering of children should be clipped to this control's "
-"rectangle. If [code]true[/code], parts of a child which would be visibly "
-"outside of this control's rectangle will not be rendered."
+"Enables whether rendering of [CanvasItem] based children should be clipped "
+"to this control's rectangle. If [code]true[/code], parts of a child which "
+"would be visibly outside of this control's rectangle will not be rendered."
msgstr ""
#: doc/classes/Control.xml:844
@@ -16870,6 +16423,172 @@ msgid ""
"stiffness multiplied by the size difference from its resting length."
msgstr ""
+#: doc/classes/Decal.xml:4
+msgid "Node that projects a texture onto a [MeshInstance3D]."
+msgstr ""
+
+#: doc/classes/Decal.xml:7
+msgid ""
+"[Decal]s are used to project a texture onto a [Mesh] in the scene. Use "
+"Decals to add detail to a scene without affecting the underlying [Mesh]. "
+"They are often used to add weathering to building, add dirt or mud to the "
+"ground, or add variety to props. Decals can be moved at any time, making "
+"them suitable for things like blob shadows or laser sight dots.\n"
+"They are made of an [AABB] and a group of [Texture2D]s specifying [Color], "
+"normal, ORM (ambient occlusion, roughness, metallic), and emission. Decals "
+"are projected within their [AABB] so altering the orientation of the Decal "
+"affects the direction in which they are projected. By default, Decals are "
+"projected down (i.e. from positive Y to negative Y).\n"
+"The [Texture2D]s associated with the Decal are automatically stored in a "
+"texture atlas which is used for drawing the decals so all decals can be "
+"drawn at once. Godot uses clustered decals, meaning they are stored in "
+"cluster data and drawn when the mesh is drawn, they are not drawn as a "
+"postprocessing effect after."
+msgstr ""
+
+#: doc/classes/Decal.xml:20
+msgid ""
+"Returns the [Texture2D] associated with the specified [enum DecalTexture]. "
+"This is a convenience method, in most cases you should access the texture "
+"directly. \n"
+"For example, instead of [code]albedo_tex = $Decal.get_texture(Decal."
+"TEXTURE_ALBEDO)[/code], use [code]albedo_tex = $Decal.texture_albedo[/"
+"code].\n"
+"One case where this is better than accessing the texture directly is when "
+"you want to copy one Decal's textures to another. For example:\n"
+"[codeblock]\n"
+"for i in Decal.TEXTURE_MAX:\n"
+" $NewDecal.set_texture(i, $OldDecal.get_texture(i))\n"
+"[/codeblock]"
+msgstr ""
+
+#: doc/classes/Decal.xml:37
+msgid ""
+"Sets the [Texture2D] associated with the specified [enum DecalTexture]. This "
+"is a convenience method, in most cases you should access the texture "
+"directly. \n"
+"For example, instead of [code]$Decal.set_texture(Decal.TEXTURE_ALBEDO, "
+"albedo_tex)[/code], use [code]$Decal.texture_albedo = albedo_tex[/code].\n"
+"One case where this is better than accessing the texture directly is when "
+"you want to copy one Decal's textures to another. For example:\n"
+"[codeblock]\n"
+"for i in Decal.TEXTURE_MAX:\n"
+" $NewDecal.set_texture(i, $OldDecal.get_texture(i))\n"
+"[/codeblock]"
+msgstr ""
+
+#: doc/classes/Decal.xml:49
+msgid ""
+"Blends the albedo [Color] of the decal with albedo [Color] of the underlying "
+"mesh."
+msgstr ""
+
+#: doc/classes/Decal.xml:52
+msgid ""
+"Specifies which [member VisualInstance3D.layers] this decal will project on. "
+"By default, Decals affect all layers. This is used so you can specify which "
+"types of objects receive the Decal and which do not. This is especially "
+"useful so you an ensure that dynamic objects don't accidentally receive a "
+"Decal intended for the terrain under them."
+msgstr ""
+
+#: doc/classes/Decal.xml:55
+msgid "Distance from the camera at which the Decal begins to fade away."
+msgstr ""
+
+#: doc/classes/Decal.xml:58
+msgid ""
+"If [code]true[/code], decals will smoothly fade away when far from the "
+"active [Camera3D] starting at [member distance_fade_begin]. The Decal will "
+"fade out over [member distance_fade_length], after which it will be culled "
+"and not sent to the shader at all. Use this to reduce the number of active "
+"Decals in a scene and thus improve performance."
+msgstr ""
+
+#: doc/classes/Decal.xml:61
+msgid ""
+"Distance over which the Decal fades. The Decal becomes slowly more "
+"transparent over this distance and is completely invisible at the end."
+msgstr ""
+
+#: doc/classes/Decal.xml:64
+msgid ""
+"Energy multiplier for the emission texture. This will make the decal emit "
+"light at a higher intensity."
+msgstr ""
+
+#: doc/classes/Decal.xml:67
+msgid ""
+"Sets the size of the [AABB] used by the decal. The AABB goes from [code]-"
+"extents[/code] to [code]extents[/code]."
+msgstr ""
+
+#: doc/classes/Decal.xml:70 doc/classes/Decal.xml:91
+msgid ""
+"Sets the curve over which the decal will fade as the surface gets further "
+"from the center of the [AABB]."
+msgstr ""
+
+#: doc/classes/Decal.xml:73
+msgid "Changes the [Color] of the Decal by multiplying it with this value."
+msgstr ""
+
+#: doc/classes/Decal.xml:76
+msgid ""
+"Fades the Decal if the angle between the Decal's [AABB] and the target "
+"surface becomes too large. A value of [code]0[/code] projects the Decal "
+"regardless of angle, a value of [code]1[/code] limits the Decal to surfaces "
+"that are nearly perpendicular."
+msgstr ""
+
+#: doc/classes/Decal.xml:79
+msgid ""
+"[Texture2D] with the base [Color] of the Decal. Either this or the [member "
+"texture_emission] must be set for the Decal to be visible. Use the alpha "
+"channel like a mask to smoothly blend the edges of the decal with the "
+"underlying object."
+msgstr ""
+
+#: doc/classes/Decal.xml:82
+msgid ""
+"[Texture2D] with the emission [Color] of the Decal. Either this or the "
+"[member texture_emission] must be set for the Decal to be visible. Use the "
+"alpha channel like a mask to smoothly blend the edges of the decal with the "
+"underlying object."
+msgstr ""
+
+#: doc/classes/Decal.xml:85
+msgid ""
+"[Texture2D] with the per-pixel normalmap for the decal. Use this to add "
+"extra detail to decals."
+msgstr ""
+
+#: doc/classes/Decal.xml:88
+msgid ""
+"[Texture2D] storing ambient occlusion, roughness, and metallic for the "
+"decal. Use this to add extra detail to decals."
+msgstr ""
+
+#: doc/classes/Decal.xml:96
+msgid "[Texture2D] corresponding to [member texture_albedo]."
+msgstr ""
+
+#: doc/classes/Decal.xml:99
+msgid "[Texture2D] corresponding to [member texture_normal]."
+msgstr ""
+
+#: doc/classes/Decal.xml:102
+msgid "[Texture2D] corresponding to [member texture_orm]."
+msgstr ""
+
+#: doc/classes/Decal.xml:105
+msgid "[Texture2D] corresponding to [member texture_emission]."
+msgstr ""
+
+#: doc/classes/Decal.xml:108
+msgid "Max size of [enum DecalTexture] enum."
+msgstr ""
+
#: doc/classes/Dictionary.xml:4
msgid "Dictionary type."
msgstr ""
@@ -16877,30 +16596,40 @@ msgstr ""
#: doc/classes/Dictionary.xml:7
msgid ""
"Dictionary type. Associative container which contains values referenced by "
-"unique keys. Dictionary are composed of pairs of keys (which must be unique) "
-"and values. You can define a dictionary by placing a comma separated list of "
-"[code]key: value[/code] pairs in curly braces [code]{}[/code].\n"
-"Erasing elements while iterating over them [b]is not supported[/b].\n"
+"unique keys. Dictionaries are composed of pairs of keys (which must be "
+"unique) and values. Dictionaries will preserve the insertion order when "
+"adding elements, even though this may not be reflected when printing the "
+"dictionary. In other programming languages, this data structure is sometimes "
+"referred to as an hash map or associative array.\n"
+"You can define a dictionary by placing a comma-separated list of [code]key: "
+"value[/code] pairs in curly braces [code]{}[/code].\n"
+"Erasing elements while iterating over them [b]is not supported[/b] and will "
+"result in undefined behavior.\n"
"Creating a dictionary:\n"
"[codeblock]\n"
"var my_dir = {} # Creates an empty dictionary.\n"
"var points_dir = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
-"var my_dir = {\n"
+"var another_dir = {\n"
" key1: value1,\n"
" key2: value2,\n"
" key3: value3,\n"
"}\n"
"[/codeblock]\n"
-"You can access values of a dictionary by referencing appropriate key in "
-"above example [code]points_dir[\"White\"][/code] would return value of 50.\n"
+"You can access a dictionary's values by referencing the appropriate key. In "
+"the above example, [code]points_dir[\"White\"][/code] will return [code]50[/"
+"code]. You can also write [code]points_dir.White[/code], which is "
+"equivalent. However, you'll have to use the bracket syntax if the key you're "
+"accessing the dictionary with isn't a fixed string (such as a number or "
+"variable).\n"
"[codeblock]\n"
"export(String, \"White\", \"Yellow\", \"Orange\") var my_color\n"
"var points_dir = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
"\n"
"func _ready():\n"
+" # We can't use dot syntax here as `my_color` is a variable.\n"
" var points = points_dir[my_color]\n"
"[/codeblock]\n"
-"In the above code [code]points[/code] will be assigned the value that is "
+"In the above code, [code]points[/code] will be assigned the value that is "
"paired with the appropriate color selected in [code]my_color[/code].\n"
"Dictionaries can contain more complex data:\n"
"[codeblock]\n"
@@ -16911,16 +16640,24 @@ msgid ""
"assign to it:\n"
"[codeblock]\n"
"var points_dir = {\"White\": 50, \"Yellow\": 75, \"Orange\": 100}\n"
-"var points_dir[\"Blue\"] = 150 # Add \"Blue\" as a key and assign 150 as its "
+"points_dir[\"Blue\"] = 150 # Add \"Blue\" as a key and assign 150 as its "
"value.\n"
"[/codeblock]\n"
"Finally, dictionaries can contain different types of keys and values in the "
"same dictionary:\n"
"[codeblock]\n"
-"var my_dir = {\"String Key\": 5, 4: [1, 2, 3], 7: \"Hello\"} # This is a "
-"valid dictionary.\n"
+"# This is a valid dictionary.\n"
+"# To access the string \"Nested value\" below, use `my_dir.sub_dir.sub_key` "
+"or `my_dir[\"sub_dir\"][\"sub_key\"]`.\n"
+"# Indexing styles can be mixed and matched depending on your needs.\n"
+"var my_dir = {\n"
+" \"String Key\": 5,\n"
+" 4: [1, 2, 3],\n"
+" 7: \"Hello\",\n"
+" \"sub_dir\": {\"sub_key\": \"Nested value\"},\n"
+"}\n"
"[/codeblock]\n"
-"[b]Note:[/b] Unlike [Array]s you can't compare dictionaries directly:\n"
+"[b]Note:[/b] Unlike [Array]s, you can't compare dictionaries directly:\n"
"[codeblock]\n"
"array1 = [1, 2, 3]\n"
"array2 = [1, 2, 3]\n"
@@ -16945,49 +16682,52 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/Dictionary.xml:65
+#: doc/classes/Dictionary.xml:75
msgid ""
"https://docs.godotengine.org/en/latest/getting_started/scripting/gdscript/"
"gdscript_basics.html#dictionary"
msgstr ""
-#: doc/classes/Dictionary.xml:72
+#: doc/classes/Dictionary.xml:82
msgid "Clear the dictionary, removing all key/value pairs."
msgstr ""
-#: doc/classes/Dictionary.xml:81
-msgid "Creates a copy of the dictionary, and returns it."
+#: doc/classes/Dictionary.xml:91
+msgid ""
+"Creates a copy of the dictionary, and returns it. The [code]deep[/code] "
+"parameter causes inner dictionaries and arrays to be copied recursively, but "
+"does not apply to objects."
msgstr ""
-#: doc/classes/Dictionary.xml:88
+#: doc/classes/Dictionary.xml:98
msgid "Returns [code]true[/code] if the dictionary is empty."
msgstr ""
-#: doc/classes/Dictionary.xml:97
+#: doc/classes/Dictionary.xml:107
msgid ""
"Erase a dictionary key/value pair by key. Returns [code]true[/code] if the "
"given key was present in the dictionary, [code]false[/code] otherwise. Does "
"not erase elements while iterating over the dictionary."
msgstr ""
-#: doc/classes/Dictionary.xml:108
+#: doc/classes/Dictionary.xml:118
msgid ""
"Returns the current value for the specified key in the [Dictionary]. If the "
"key does not exist, the method returns the value of the optional default "
"argument, or [code]null[/code] if it is omitted."
msgstr ""
-#: doc/classes/Dictionary.xml:117
+#: doc/classes/Dictionary.xml:127
msgid "Returns [code]true[/code] if the dictionary has a given key."
msgstr ""
-#: doc/classes/Dictionary.xml:126
+#: doc/classes/Dictionary.xml:136
msgid ""
"Returns [code]true[/code] if the dictionary has all of the keys in the given "
"array."
msgstr ""
-#: doc/classes/Dictionary.xml:133
+#: doc/classes/Dictionary.xml:143
msgid ""
"Returns a hashed integer value representing the dictionary contents. This "
"can be used to compare dictionaries by value:\n"
@@ -17000,15 +16740,15 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/Dictionary.xml:146
+#: doc/classes/Dictionary.xml:156
msgid "Returns the list of keys in the [Dictionary]."
msgstr ""
-#: doc/classes/Dictionary.xml:153
+#: doc/classes/Dictionary.xml:163
msgid "Returns the size of the dictionary (in pairs)."
msgstr ""
-#: doc/classes/Dictionary.xml:160
+#: doc/classes/Dictionary.xml:170
msgid "Returns the list of values in the [Dictionary]."
msgstr ""
@@ -17034,37 +16774,42 @@ msgstr ""
#: doc/classes/DirectionalLight3D.xml:16
msgid ""
-"Amount of extra bias for shadow splits that are far away. If self-shadowing "
-"occurs only on the splits far away, increasing this value can fix them."
+"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
+"transitions between splits."
msgstr ""
#: doc/classes/DirectionalLight3D.xml:19
msgid ""
-"If [code]true[/code], shadow detail is sacrificed in exchange for smoother "
-"transitions between splits."
+"Optimizes shadow rendering for detail versus movement. See [enum "
+"ShadowDepthRange]."
msgstr ""
#: doc/classes/DirectionalLight3D.xml:22
msgid ""
-"Optimizes shadow rendering for detail versus movement. See [enum "
-"ShadowDepthRange]."
+"Proportion of [member directional_shadow_max_distance] at which point the "
+"shadow starts to fade. At [member directional_shadow_max_distance] the "
+"shadow will disappear."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:27
+#: doc/classes/DirectionalLight3D.xml:25
msgid "The maximum distance for shadow splits."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:30
+#: doc/classes/DirectionalLight3D.xml:28
msgid "The light's shadow rendering algorithm. See [enum ShadowMode]."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:33
+#: doc/classes/DirectionalLight3D.xml:31 doc/classes/RenderingServer.xml:3371
msgid ""
-"Can be used to fix special cases of self shadowing when objects are "
-"perpendicular to the light."
+"Sets the size of the directional shadow pancake. The pancake offsets the "
+"start of the shadow's camera frustum to provide a higher effective depth "
+"resolution for the shadow. However, a high pancake size can cause artifacts "
+"in the shadows of large objects that are close to the edge of the frustum. "
+"Reducing the pancake size can help. Setting the size to [code]0[/code] turns "
+"off the pancaking effect."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:36
+#: doc/classes/DirectionalLight3D.xml:34
msgid ""
"The distance from camera to shadow split 1. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
@@ -17072,7 +16817,7 @@ msgid ""
"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:39
+#: doc/classes/DirectionalLight3D.xml:37
msgid ""
"The distance from shadow split 1 to split 2. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
@@ -17080,34 +16825,34 @@ msgid ""
"[code]SHADOW_PARALLEL_4_SPLITS[/code]."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:42
+#: doc/classes/DirectionalLight3D.xml:40
msgid ""
"The distance from shadow split 2 to split 3. Relative to [member "
"directional_shadow_max_distance]. Only used when [member "
"directional_shadow_mode] is [code]SHADOW_PARALLEL_4_SPLITS[/code]."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:48
+#: doc/classes/DirectionalLight3D.xml:45
msgid ""
"Renders the entire scene's shadow map from an orthogonal point of view. May "
"result in blockier shadows on close objects."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:51
+#: doc/classes/DirectionalLight3D.xml:48
msgid "Splits the view frustum in 2 areas, each with its own shadow map."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:54
+#: doc/classes/DirectionalLight3D.xml:51
msgid "Splits the view frustum in 4 areas, each with its own shadow map."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:57
+#: doc/classes/DirectionalLight3D.xml:54
msgid ""
"Keeps the shadow stable when the camera moves, at the cost of lower "
"effective shadow resolution."
msgstr ""
-#: doc/classes/DirectionalLight3D.xml:60
+#: doc/classes/DirectionalLight3D.xml:57
msgid ""
"Tries to achieve maximum shadow resolution. May result in saw effect on "
"shadow edges."
@@ -17397,61 +17142,67 @@ msgid ""
"dynamic_font.font_data = load(\"res://BarlowCondensed-Bold.ttf\")\n"
"dynamic_font.size = 64\n"
"$\"Label\".set(\"custom_fonts/font\", dynamic_font)\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"[b]Note:[/b] DynamicFont doesn't support features such as right-to-left "
+"typesetting, ligatures, text shaping, variable fonts and optional font "
+"features yet. If you wish to \"bake\" an optional font feature into a TTF "
+"font file, you can use [url=https://fontforge.org/]FontForge[/url] to do so. "
+"In FontForge, use [b]File > Generate Fonts[/b], click [b]Options[/b], choose "
+"the desired features then generate the font."
msgstr ""
-#: doc/classes/DynamicFont.xml:25
+#: doc/classes/DynamicFont.xml:26
msgid "Adds a fallback font."
msgstr ""
-#: doc/classes/DynamicFont.xml:34
+#: doc/classes/DynamicFont.xml:35
msgid "Returns the fallback font at index [code]idx[/code]."
msgstr ""
-#: doc/classes/DynamicFont.xml:41
+#: doc/classes/DynamicFont.xml:42
msgid "Returns the number of fallback fonts."
msgstr ""
-#: doc/classes/DynamicFont.xml:50
+#: doc/classes/DynamicFont.xml:51
msgid ""
"Returns the spacing for the given [code]type[/code] (see [enum SpacingType])."
msgstr ""
-#: doc/classes/DynamicFont.xml:59
+#: doc/classes/DynamicFont.xml:60
msgid "Removes the fallback font at index [code]idx[/code]."
msgstr ""
-#: doc/classes/DynamicFont.xml:70
+#: doc/classes/DynamicFont.xml:71
msgid "Sets the fallback font at index [code]idx[/code]."
msgstr ""
-#: doc/classes/DynamicFont.xml:81
+#: doc/classes/DynamicFont.xml:82
msgid ""
"Sets the spacing for [code]type[/code] (see [enum SpacingType]) to "
"[code]value[/code] in pixels (not relative to the font size)."
msgstr ""
-#: doc/classes/DynamicFont.xml:87
+#: doc/classes/DynamicFont.xml:88
msgid "Extra spacing at the bottom in pixels."
msgstr ""
-#: doc/classes/DynamicFont.xml:90
+#: doc/classes/DynamicFont.xml:91
msgid "Extra character spacing in pixels."
msgstr ""
-#: doc/classes/DynamicFont.xml:93
+#: doc/classes/DynamicFont.xml:94
msgid "Extra space spacing in pixels."
msgstr ""
-#: doc/classes/DynamicFont.xml:96
+#: doc/classes/DynamicFont.xml:97
msgid "Extra spacing at the top in pixels."
msgstr ""
-#: doc/classes/DynamicFont.xml:99
+#: doc/classes/DynamicFont.xml:100
msgid "The font data."
msgstr ""
-#: doc/classes/DynamicFont.xml:102
+#: doc/classes/DynamicFont.xml:103
msgid ""
"The font outline's color.\n"
"[b]Note:[/b] It's recommended to leave this at the default value so that you "
@@ -17460,27 +17211,27 @@ msgid ""
"outline modulate theme item."
msgstr ""
-#: doc/classes/DynamicFont.xml:106
+#: doc/classes/DynamicFont.xml:107
msgid "The font outline's thickness in pixels (not relative to the font size)."
msgstr ""
-#: doc/classes/DynamicFont.xml:109
+#: doc/classes/DynamicFont.xml:110
msgid "The font size in pixels."
msgstr ""
-#: doc/classes/DynamicFont.xml:114
+#: doc/classes/DynamicFont.xml:115
msgid "Spacing at the top."
msgstr ""
-#: doc/classes/DynamicFont.xml:117
+#: doc/classes/DynamicFont.xml:118
msgid "Spacing at the bottom."
msgstr ""
-#: doc/classes/DynamicFont.xml:120
+#: doc/classes/DynamicFont.xml:121
msgid "Character spacing."
msgstr ""
-#: doc/classes/DynamicFont.xml:123
+#: doc/classes/DynamicFont.xml:124
msgid "Space spacing."
msgstr ""
@@ -17595,7 +17346,7 @@ msgstr ""
msgid ""
"Saves the editor feature profile to a file in JSON format. It can then be "
"imported using the feature profile manager's [b]Import[/b] button or the "
-"[method load_from_file] button."
+"[method load_from_file] button."
msgstr ""
#: doc/classes/EditorFeatureProfile.xml:86
@@ -17809,56 +17560,58 @@ msgstr ""
#: doc/classes/EditorFileSystem.xml:7
msgid ""
"This object holds information of all resources in the filesystem, their "
-"types, etc."
+"types, etc.\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_resource_filesystem]."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:18
+#: doc/classes/EditorFileSystem.xml:19
msgid "Gets the type of the file, given the full path."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:25
+#: doc/classes/EditorFileSystem.xml:26
msgid "Gets the root directory object."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:34
+#: doc/classes/EditorFileSystem.xml:35
msgid "Returns a view into the filesystem at [code]path[/code]."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:41
+#: doc/classes/EditorFileSystem.xml:42
msgid "Returns the scan progress for 0 to 1 if the FS is being scanned."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:48
+#: doc/classes/EditorFileSystem.xml:49
msgid "Returns [code]true[/code] of the filesystem is being scanned."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:55
+#: doc/classes/EditorFileSystem.xml:56
msgid "Scan the filesystem for changes."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:62
+#: doc/classes/EditorFileSystem.xml:63
msgid "Check if the source of any imported resource changed."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:71
+#: doc/classes/EditorFileSystem.xml:72
msgid ""
"Update a file information. Call this if an external program (not Godot) "
"modified the file."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:78
+#: doc/classes/EditorFileSystem.xml:79
msgid "Scans the script files and updates the list of custom class names."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:85
+#: doc/classes/EditorFileSystem.xml:86
msgid "Emitted if the filesystem changed."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:92
+#: doc/classes/EditorFileSystem.xml:93
msgid "Remitted if a resource is reimported."
msgstr ""
-#: doc/classes/EditorFileSystem.xml:105
+#: doc/classes/EditorFileSystem.xml:106
msgid "Emitted if the source of any imported file changed."
msgstr ""
@@ -18062,7 +17815,9 @@ msgid ""
"editor. It's used to edit the properties of the selected node. For example, "
"you can select a node such as the Sprite2D then edit its transform through "
"the inspector tool. The editor inspector is an essential tool in the game "
-"development workflow."
+"development workflow.\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_inspector]."
msgstr ""
#: doc/classes/EditorInspectorPlugin.xml:4
@@ -18132,95 +17887,97 @@ msgid ""
"customizing the window, saving and (re-)loading scenes, rendering mesh "
"previews, inspecting and editing resources and objects, and provides access "
"to [EditorSettings], [EditorFileSystem], [EditorResourcePreview], "
-"[ScriptEditor], the editor viewport, and information about scenes."
+"[ScriptEditor], the editor viewport, and information about scenes.\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorPlugin.get_editor_interface]."
msgstr ""
-#: doc/classes/EditorInterface.xml:18
+#: doc/classes/EditorInterface.xml:19
msgid "Edits the given [Resource]."
msgstr ""
-#: doc/classes/EditorInterface.xml:25
+#: doc/classes/EditorInterface.xml:26
msgid ""
"Returns the main container of Godot editor's window. You can use it, for "
"example, to retrieve the size of the container and place your controls "
"accordingly."
msgstr ""
-#: doc/classes/EditorInterface.xml:38
+#: doc/classes/EditorInterface.xml:39
msgid "Returns the edited (current) scene's root [Node]."
msgstr ""
-#: doc/classes/EditorInterface.xml:45
+#: doc/classes/EditorInterface.xml:46
msgid "Returns the [EditorSettings]."
msgstr ""
-#: doc/classes/EditorInterface.xml:52
+#: doc/classes/EditorInterface.xml:53
msgid "Returns the editor [Viewport]."
msgstr ""
-#: doc/classes/EditorInterface.xml:71
+#: doc/classes/EditorInterface.xml:72
msgid "Returns an [Array] with the file paths of the currently opened scenes."
msgstr ""
-#: doc/classes/EditorInterface.xml:78
+#: doc/classes/EditorInterface.xml:79
msgid "Returns the [EditorFileSystem]."
msgstr ""
-#: doc/classes/EditorInterface.xml:85
+#: doc/classes/EditorInterface.xml:86
msgid "Returns the [EditorResourcePreview]."
msgstr ""
-#: doc/classes/EditorInterface.xml:92
+#: doc/classes/EditorInterface.xml:93
msgid "Returns the [ScriptEditor]."
msgstr ""
-#: doc/classes/EditorInterface.xml:105
+#: doc/classes/EditorInterface.xml:106
msgid "Returns the [EditorSelection]."
msgstr ""
-#: doc/classes/EditorInterface.xml:116
+#: doc/classes/EditorInterface.xml:117
msgid ""
"Shows the given property on the given [code]object[/code] in the Editor's "
"Inspector dock."
msgstr ""
-#: doc/classes/EditorInterface.xml:125
+#: doc/classes/EditorInterface.xml:126
msgid ""
"Returns the enabled status of a plugin. The plugin name is the same as its "
"directory name."
msgstr ""
-#: doc/classes/EditorInterface.xml:136
+#: doc/classes/EditorInterface.xml:137
msgid ""
"Returns mesh previews rendered at the given size as an [Array] of "
"[Texture2D]s."
msgstr ""
-#: doc/classes/EditorInterface.xml:145
+#: doc/classes/EditorInterface.xml:146
msgid "Opens the scene at the given path."
msgstr ""
-#: doc/classes/EditorInterface.xml:154
+#: doc/classes/EditorInterface.xml:155
msgid "Reloads the scene at the given path."
msgstr ""
-#: doc/classes/EditorInterface.xml:161
+#: doc/classes/EditorInterface.xml:162
msgid ""
"Saves the scene. Returns either [code]OK[/code] or [code]ERR_CANT_CREATE[/"
"code] (see [@GlobalScope] constants)."
msgstr ""
-#: doc/classes/EditorInterface.xml:172
+#: doc/classes/EditorInterface.xml:173
msgid "Saves the scene as a file at [code]path[/code]."
msgstr ""
-#: doc/classes/EditorInterface.xml:181
+#: doc/classes/EditorInterface.xml:182
msgid ""
"Selects the file, with the path provided by [code]file[/code], in the "
"FileSystem dock."
msgstr ""
-#: doc/classes/EditorInterface.xml:208
+#: doc/classes/EditorInterface.xml:209
msgid ""
"Sets the enabled status of a plugin. The plugin name is the same as its "
"directory name."
@@ -18833,57 +18590,57 @@ msgstr ""
msgid "Used by the inspector, when the property is checked."
msgstr ""
-#: doc/classes/EditorProperty.xml:82
+#: doc/classes/EditorProperty.xml:84
msgid "Used by the inspector, when the property must draw with error color."
msgstr ""
-#: doc/classes/EditorProperty.xml:85
+#: doc/classes/EditorProperty.xml:87
msgid "Used by the inspector, when the property can add keys for animation."
msgstr ""
-#: doc/classes/EditorProperty.xml:88
+#: doc/classes/EditorProperty.xml:90
msgid "Sets this property to change the label (if you want to show one)."
msgstr ""
-#: doc/classes/EditorProperty.xml:91
+#: doc/classes/EditorProperty.xml:93
msgid "Used by the inspector, when the property is read-only."
msgstr ""
-#: doc/classes/EditorProperty.xml:101
+#: doc/classes/EditorProperty.xml:103
msgid ""
"Emit it if you want multiple properties modified at the same time. Do not "
"use if added via [method EditorInspectorPlugin.parse_property]."
msgstr ""
-#: doc/classes/EditorProperty.xml:110
+#: doc/classes/EditorProperty.xml:112
msgid "Used by sub-inspectors. Emit it if what was selected was an Object ID."
msgstr ""
-#: doc/classes/EditorProperty.xml:119
+#: doc/classes/EditorProperty.xml:121
msgid ""
"Do not emit this manually, use the [method emit_changed] method instead."
msgstr ""
-#: doc/classes/EditorProperty.xml:128
+#: doc/classes/EditorProperty.xml:130
msgid "Emitted when a property was checked. Used internally."
msgstr ""
-#: doc/classes/EditorProperty.xml:135
+#: doc/classes/EditorProperty.xml:143
msgid ""
"Emit it if you want to add this value as an animation key (check for keying "
"being enabled first)."
msgstr ""
-#: doc/classes/EditorProperty.xml:144
+#: doc/classes/EditorProperty.xml:152
msgid "Emit it if you want to key a property with a single value."
msgstr ""
-#: doc/classes/EditorProperty.xml:153
+#: doc/classes/EditorProperty.xml:161
msgid ""
"If you want a sub-resource to be edited, emit this signal with the resource."
msgstr ""
-#: doc/classes/EditorProperty.xml:162
+#: doc/classes/EditorProperty.xml:170
msgid "Emitted when selected. Used internally."
msgstr ""
@@ -18892,20 +18649,23 @@ msgid "Helper to generate previews of resources or files."
msgstr ""
#: doc/classes/EditorResourcePreview.xml:7
-msgid "This object is used to generate previews for resources of files."
+msgid ""
+"This object is used to generate previews for resources of files.\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_resource_previewer]."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:18
+#: doc/classes/EditorResourcePreview.xml:19
msgid "Create an own, custom preview generator."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:27
+#: doc/classes/EditorResourcePreview.xml:28
msgid ""
"Check if the resource changed, if so, it will be invalidated and the "
"corresponding signal emitted."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:42
+#: doc/classes/EditorResourcePreview.xml:43
msgid ""
"Queue a resource being edited for preview (using an instance). Once the "
"preview is ready, your receiver.receiver_func will be called either "
@@ -18914,7 +18674,7 @@ msgid ""
"can be anything."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:57
+#: doc/classes/EditorResourcePreview.xml:58
msgid ""
"Queue a resource file for preview (using a path). Once the preview is ready, "
"your receiver.receiver_func will be called either containing the preview "
@@ -18922,11 +18682,11 @@ msgid ""
"the format: (path,texture,userdata). Userdata can be anything."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:66
+#: doc/classes/EditorResourcePreview.xml:67
msgid "Removes a custom preview generator."
msgstr ""
-#: doc/classes/EditorResourcePreview.xml:75
+#: doc/classes/EditorResourcePreview.xml:76
msgid ""
"Emitted if a preview was invalidated (changed). [code]path[/code] "
"corresponds to the path of the preview."
@@ -19084,7 +18844,7 @@ msgstr ""
msgid ""
"Scripts extending this class and implementing its [method _run] method can "
"be executed from the Script Editor's [b]File > Run[/b] menu option (or by "
-"pressing [code]Ctrl+Shift+X[/code]) while the editor is running. This is "
+"pressing [kbd]Ctrl + Shift + X[/kbd]) while the editor is running. This is "
"useful for adding custom in-editor functionality to Godot. For more complex "
"additions, consider using [EditorPlugin]s instead.\n"
"[b]Note:[/b] Extending scripts need to have [code]tool[/code] mode enabled.\n"
@@ -19124,33 +18884,36 @@ msgid "Manages the SceneTree selection in the editor."
msgstr ""
#: doc/classes/EditorSelection.xml:7
-msgid "This object manages the SceneTree selection in the editor."
+msgid ""
+"This object manages the SceneTree selection in the editor.\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_selection]."
msgstr ""
-#: doc/classes/EditorSelection.xml:18
+#: doc/classes/EditorSelection.xml:19
msgid "Adds a node to the selection."
msgstr ""
-#: doc/classes/EditorSelection.xml:25
+#: doc/classes/EditorSelection.xml:26
msgid "Clear the selection."
msgstr ""
-#: doc/classes/EditorSelection.xml:32
+#: doc/classes/EditorSelection.xml:33
msgid "Gets the list of selected nodes."
msgstr ""
-#: doc/classes/EditorSelection.xml:39
+#: doc/classes/EditorSelection.xml:40
msgid ""
"Gets the list of selected nodes, optimized for transform operations (i.e. "
"moving them, rotating, etc). This list avoids situations where a node is "
"selected and also child/grandchild."
msgstr ""
-#: doc/classes/EditorSelection.xml:48
+#: doc/classes/EditorSelection.xml:49
msgid "Removes a node from the selection."
msgstr ""
-#: doc/classes/EditorSelection.xml:55
+#: doc/classes/EditorSelection.xml:56
msgid "Emitted when the selection changes."
msgstr ""
@@ -19167,10 +18930,12 @@ msgid ""
"settings.set(prop,value)\n"
"settings.get(prop)\n"
"list_of_settings = settings.get_property_list()\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_editor_settings]."
msgstr ""
-#: doc/classes/EditorSettings.xml:24
+#: doc/classes/EditorSettings.xml:25
msgid ""
"Adds a custom property info to a property. The dictionary must contain:\n"
"- [code]name[/code]: [String] (the name of the property)\n"
@@ -19192,27 +18957,27 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/EditorSettings.xml:49
+#: doc/classes/EditorSettings.xml:50
msgid "Erase a given setting (pass full property path)."
msgstr ""
-#: doc/classes/EditorSettings.xml:56
+#: doc/classes/EditorSettings.xml:57
msgid "Gets the list of favorite files and directories for this project."
msgstr ""
-#: doc/classes/EditorSettings.xml:75
+#: doc/classes/EditorSettings.xml:76
msgid ""
"Gets the specific project settings path. Projects all have a unique sub-"
"directory inside the settings path where project specific settings are saved."
msgstr ""
-#: doc/classes/EditorSettings.xml:82
+#: doc/classes/EditorSettings.xml:83
msgid ""
"Gets the list of recently visited folders in the file dialog for this "
"project."
msgstr ""
-#: doc/classes/EditorSettings.xml:97
+#: doc/classes/EditorSettings.xml:98
msgid ""
"Gets the global settings path for the engine. Inside this path, you can find "
"some standard paths such as:\n"
@@ -19220,21 +18985,21 @@ msgid ""
"[code]settings/templates[/code] - Where export templates are located"
msgstr ""
-#: doc/classes/EditorSettings.xml:132
+#: doc/classes/EditorSettings.xml:133
msgid "Sets the list of favorite files and directories for this project."
msgstr ""
-#: doc/classes/EditorSettings.xml:165
+#: doc/classes/EditorSettings.xml:166
msgid ""
"Sets the list of recently visited folders in the file dialog for this "
"project."
msgstr ""
-#: doc/classes/EditorSettings.xml:182
+#: doc/classes/EditorSettings.xml:183
msgid "Emitted when editor settings change."
msgstr ""
-#: doc/classes/EditorSettings.xml:188
+#: doc/classes/EditorSettings.xml:189
msgid ""
"Emitted when editor settings change. It used by various editor plugins to "
"update their visuals on theme changes or logic on configuration changes."
@@ -19977,7 +19742,7 @@ msgid ""
"is visible, \"ghost trail\" artifacts will be visible when moving the camera."
msgstr ""
-#: doc/classes/Environment.xml:262 doc/classes/RenderingServer.xml:3476
+#: doc/classes/Environment.xml:262 doc/classes/RenderingServer.xml:3563
msgid "Displays a camera feed in the background."
msgstr ""
@@ -19985,64 +19750,103 @@ msgstr ""
msgid "Represents the size of the [enum BGMode] enum."
msgstr ""
-#: doc/classes/Environment.xml:282
+#: doc/classes/Environment.xml:268 doc/classes/RenderingServer.xml:3569
+msgid ""
+"Gather ambient light from whichever source is specified as the background."
+msgstr ""
+
+#: doc/classes/Environment.xml:271 doc/classes/RenderingServer.xml:3572
+msgid "Disable ambient light."
+msgstr ""
+
+#: doc/classes/Environment.xml:274 doc/classes/RenderingServer.xml:3575
+msgid "Specify a specific [Color] for ambient light."
+msgstr ""
+
+#: doc/classes/Environment.xml:277 doc/classes/RenderingServer.xml:3578
+msgid ""
+"Gather ambient light from the [Sky] regardless of what the background is."
+msgstr ""
+
+#: doc/classes/Environment.xml:280 doc/classes/RenderingServer.xml:3581
+msgid "Use the background for reflections."
+msgstr ""
+
+#: doc/classes/Environment.xml:283 doc/classes/RenderingServer.xml:3584
+msgid "Disable reflections."
+msgstr ""
+
+#: doc/classes/Environment.xml:286 doc/classes/RenderingServer.xml:3587
+msgid "Use the [Sky] for reflections regardless of what the background is."
+msgstr ""
+
+#: doc/classes/Environment.xml:289 doc/classes/RenderingServer.xml:3590
msgid ""
"Additive glow blending mode. Mostly used for particles, glows (bloom), lens "
"flare, bright sources."
msgstr ""
-#: doc/classes/Environment.xml:285
+#: doc/classes/Environment.xml:292 doc/classes/RenderingServer.xml:3593
msgid ""
"Screen glow blending mode. Increases brightness, used frequently with bloom."
msgstr ""
-#: doc/classes/Environment.xml:288
+#: doc/classes/Environment.xml:295 doc/classes/RenderingServer.xml:3596
msgid ""
"Soft light glow blending mode. Modifies contrast, exposes shadows and "
"highlights (vivid bloom)."
msgstr ""
-#: doc/classes/Environment.xml:291
+#: doc/classes/Environment.xml:298 doc/classes/RenderingServer.xml:3599
msgid ""
"Replace glow blending mode. Replaces all pixels' color by the glow value. "
"This can be used to simulate a full-screen blur effect by tweaking the glow "
"parameters to match the original image's brightness."
msgstr ""
-#: doc/classes/Environment.xml:296
+#: doc/classes/Environment.xml:301 doc/classes/RenderingServer.xml:3602
+msgid ""
+"Mixes the glow with the underlying color to avoid increasing brightness as "
+"much while still maintaining a glow effect."
+msgstr ""
+
+#: doc/classes/Environment.xml:304
msgid ""
"Linear tonemapper operator. Reads the linear data and passes it on "
"unmodified."
msgstr ""
-#: doc/classes/Environment.xml:299
+#: doc/classes/Environment.xml:307
msgid ""
"Reinhardt tonemapper operator. Performs a variation on rendered pixels' "
"colors by this formula: [code]color = color / (1 + color)[/code]."
msgstr ""
-#: doc/classes/Environment.xml:302
+#: doc/classes/Environment.xml:310
msgid "Filmic tonemapper operator."
msgstr ""
-#: doc/classes/Environment.xml:305
+#: doc/classes/Environment.xml:313
msgid "Academy Color Encoding System tonemapper operator."
msgstr ""
-#: doc/classes/Environment.xml:308
+#: doc/classes/Environment.xml:316
msgid "No blur for the screen-space ambient occlusion effect (fastest)."
msgstr ""
-#: doc/classes/Environment.xml:311
+#: doc/classes/Environment.xml:319
msgid "1×1 blur for the screen-space ambient occlusion effect."
msgstr ""
-#: doc/classes/Environment.xml:314
+#: doc/classes/Environment.xml:322
msgid "2×2 blur for the screen-space ambient occlusion effect."
msgstr ""
-#: doc/classes/Environment.xml:317
-msgid "3×3 blur for the screen-space ambient occlusion effect (slowest)."
+#: doc/classes/Environment.xml:325
+msgid ""
+"3×3 blur for the screen-space ambient occlusion effect. Increases the radius "
+"of the blur for a smoother look, but can result in checkerboard-like "
+"artifacts."
msgstr ""
#: doc/classes/Expression.xml:4
@@ -20303,26 +20107,38 @@ msgid ""
msgstr ""
#: doc/classes/File.xml:299
-msgid "Stores an integer as 16 bits in the file."
+msgid ""
+"Stores an integer as 16 bits in the file.\n"
+"[b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, "
+"2^16 - 1][/code]."
msgstr ""
-#: doc/classes/File.xml:308
-msgid "Stores an integer as 32 bits in the file."
+#: doc/classes/File.xml:309
+msgid ""
+"Stores an integer as 32 bits in the file.\n"
+"[b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, "
+"2^32 - 1][/code]."
msgstr ""
-#: doc/classes/File.xml:317
-msgid "Stores an integer as 64 bits in the file."
+#: doc/classes/File.xml:319
+msgid ""
+"Stores an integer as 64 bits in the file.\n"
+"[b]Note:[/b] The [code]value[/code] must lie in the interval [code][-2^63, "
+"2^63 - 1][/code] (i.e. be a valid [int] value)."
msgstr ""
-#: doc/classes/File.xml:326
-msgid "Stores an integer as 8 bits in the file."
+#: doc/classes/File.xml:329
+msgid ""
+"Stores an integer as 8 bits in the file.\n"
+"[b]Note:[/b] The [code]value[/code] should lie in the interval [code][0, 255]"
+"[/code]."
msgstr ""
-#: doc/classes/File.xml:335
+#: doc/classes/File.xml:339
msgid "Stores the given array of bytes in the file."
msgstr ""
-#: doc/classes/File.xml:346
+#: doc/classes/File.xml:350
msgid ""
"Store the given [PackedStringArray] in the file as a line formatted in the "
"CSV (Comma-Separated Values) format. You can pass a different delimiter "
@@ -20331,45 +20147,45 @@ msgid ""
"Text will be encoded as UTF-8."
msgstr ""
-#: doc/classes/File.xml:356
+#: doc/classes/File.xml:360
msgid "Stores a floating-point number as 64 bits in the file."
msgstr ""
-#: doc/classes/File.xml:365
+#: doc/classes/File.xml:369
msgid "Stores a floating-point number as 32 bits in the file."
msgstr ""
-#: doc/classes/File.xml:374
+#: doc/classes/File.xml:378
msgid ""
"Stores the given [String] as a line in the file.\n"
"Text will be encoded as UTF-8."
msgstr ""
-#: doc/classes/File.xml:384
+#: doc/classes/File.xml:388
msgid ""
"Stores the given [String] as a line in the file in Pascal format (i.e. also "
"store the length of the string).\n"
"Text will be encoded as UTF-8."
msgstr ""
-#: doc/classes/File.xml:394
+#: doc/classes/File.xml:398
msgid "Stores a floating-point number in the file."
msgstr ""
-#: doc/classes/File.xml:403
+#: doc/classes/File.xml:407
msgid ""
"Stores the given [String] in the file.\n"
"Text will be encoded as UTF-8."
msgstr ""
-#: doc/classes/File.xml:415
+#: doc/classes/File.xml:419
msgid ""
"Stores any Variant value in the file. If [code]full_objects[/code] is "
"[code]true[/code], encoding objects is allowed (and can potentially include "
"code)."
msgstr ""
-#: doc/classes/File.xml:421
+#: doc/classes/File.xml:425
msgid ""
"If [code]true[/code], the file's endianness is swapped. Use this if you're "
"dealing with files written on big-endian machines.\n"
@@ -20377,44 +20193,44 @@ msgid ""
"reset to [code]false[/code] whenever you open the file."
msgstr ""
-#: doc/classes/File.xml:427
+#: doc/classes/File.xml:431
msgid "Opens the file for read operations."
msgstr ""
-#: doc/classes/File.xml:430
+#: doc/classes/File.xml:434
msgid ""
"Opens the file for write operations. Create it if the file does not exist "
"and truncate if it exists."
msgstr ""
-#: doc/classes/File.xml:433
+#: doc/classes/File.xml:437
msgid ""
"Opens the file for read and write operations. Does not truncate the file."
msgstr ""
-#: doc/classes/File.xml:436
+#: doc/classes/File.xml:440
msgid ""
"Opens the file for read and write operations. Create it if the file does not "
"exist and truncate if it exists."
msgstr ""
-#: doc/classes/File.xml:439
+#: doc/classes/File.xml:443
msgid "Uses the [url=http://fastlz.org/]FastLZ[/url] compression method."
msgstr ""
-#: doc/classes/File.xml:442
+#: doc/classes/File.xml:446
msgid ""
"Uses the [url=https://en.wikipedia.org/wiki/DEFLATE]DEFLATE[/url] "
"compression method."
msgstr ""
-#: doc/classes/File.xml:445
+#: doc/classes/File.xml:449
msgid ""
"Uses the [url=https://facebook.github.io/zstd/]Zstandard[/url] compression "
"method."
msgstr ""
-#: doc/classes/File.xml:448
+#: doc/classes/File.xml:452
msgid "Uses the [url=https://www.gzip.org/]gzip[/url] compression method."
msgstr ""
@@ -20718,7 +20534,7 @@ msgstr ""
msgid ""
"A GDNative library can implement [NativeScript]s, global functions to call "
"with the [GDNative] class, or low-level engine extensions through interfaces "
-"such as [ARVRInterfaceGDNative]. The library must be compiled for each "
+"such as [XRInterfaceGDNative]. The library must be compiled for each "
"platform and architecture that the project will run on."
msgstr ""
@@ -21673,99 +21489,99 @@ msgid ""
"object."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:27
+#: doc/classes/GeometryInstance3D.xml:35
msgid ""
"Overrides the bounding box of this node with a custom one. To remove it, set "
"an [AABB] with all fields set to zero."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:38
+#: doc/classes/GeometryInstance3D.xml:46
msgid ""
"Sets the [enum GeometryInstance3D.Flags] specified. See [enum "
"GeometryInstance3D.Flags] for options."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:44
+#: doc/classes/GeometryInstance3D.xml:62
msgid ""
"The selected shadow casting flag. See [enum ShadowCastingSetting] for "
"possible values."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:47
+#: doc/classes/GeometryInstance3D.xml:65
msgid ""
"The extra distance added to the GeometryInstance3D's bounding box ([AABB]) "
"to increase its cull box."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:50
+#: doc/classes/GeometryInstance3D.xml:68
msgid ""
"The GeometryInstance3D's max LOD distance.\n"
"[b]Note:[/b] This property currently has no effect."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:54
+#: doc/classes/GeometryInstance3D.xml:72
msgid ""
"The GeometryInstance3D's max LOD margin.\n"
"[b]Note:[/b] This property currently has no effect."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:58
+#: doc/classes/GeometryInstance3D.xml:76
msgid ""
"The GeometryInstance3D's min LOD distance.\n"
"[b]Note:[/b] This property currently has no effect."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:62
+#: doc/classes/GeometryInstance3D.xml:80
msgid ""
"The GeometryInstance3D's min LOD margin.\n"
"[b]Note:[/b] This property currently has no effect."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:66
+#: doc/classes/GeometryInstance3D.xml:84
msgid ""
"The material override for the whole geometry.\n"
"If a material is assigned to this property, it will be used instead of any "
"material set in any material slot of the mesh."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:72
+#: doc/classes/GeometryInstance3D.xml:90
msgid ""
"If [code]true[/code], this GeometryInstance3D will be used when baking "
"lights using a [GIProbe]."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:77
+#: doc/classes/GeometryInstance3D.xml:95
msgid "Will not cast any shadows."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:80
+#: doc/classes/GeometryInstance3D.xml:98
msgid ""
"Will cast shadows from all visible faces in the GeometryInstance3D.\n"
"Will take culling into account, so faces not being rendered will not be "
"taken into account when shadow casting."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:84
+#: doc/classes/GeometryInstance3D.xml:102
msgid ""
"Will cast shadows from all visible faces in the GeometryInstance3D.\n"
"Will not take culling into account, so all faces will be taken into account "
"when shadow casting."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:88
+#: doc/classes/GeometryInstance3D.xml:106
msgid ""
"Will only show the shadows casted from this object.\n"
"In other words, the actual mesh will not be visible, only the shadows casted "
"from the mesh will be."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:92
+#: doc/classes/GeometryInstance3D.xml:110
msgid ""
"Will allow the GeometryInstance3D to be used when baking lights using a "
"[GIProbe]."
msgstr ""
-#: doc/classes/GeometryInstance3D.xml:97
+#: doc/classes/GeometryInstance3D.xml:115
msgid ""
"Unused in this class, exposed for consistency with [enum RenderingServer."
"InstanceFlags]."
@@ -22235,7 +22051,7 @@ msgid ""
msgstr ""
#: doc/classes/GraphEdit.xml:243
-msgid "Emitted when the user presses [code]Ctrl + C[/code]."
+msgid "Emitted when the user presses [kbd]Ctrl + C[/kbd]."
msgstr ""
#: doc/classes/GraphEdit.xml:248
@@ -22258,65 +22074,65 @@ msgstr ""
msgid "Emitted when a GraphNode is selected."
msgstr ""
-#: doc/classes/GraphEdit.xml:278
-msgid "Emitted when the user presses [code]Ctrl + V[/code]."
+#: doc/classes/GraphEdit.xml:284
+msgid "Emitted when the user presses [kbd]Ctrl + V[/kbd]."
msgstr ""
-#: doc/classes/GraphEdit.xml:285
+#: doc/classes/GraphEdit.xml:291
msgid ""
"Emitted when a popup is requested. Happens on right-clicking in the "
"GraphEdit. [code]position[/code] is the position of the mouse pointer when "
"the signal is sent."
msgstr ""
-#: doc/classes/GraphEdit.xml:292
+#: doc/classes/GraphEdit.xml:298
msgid ""
"Emitted when the scroll offset is changed by the user. It will not be "
"emitted when changed in code."
msgstr ""
-#: doc/classes/GraphEdit.xml:306
+#: doc/classes/GraphEdit.xml:312
msgid "The background drawn under the grid."
msgstr ""
-#: doc/classes/GraphEdit.xml:309
+#: doc/classes/GraphEdit.xml:315
msgid "Color of major grid lines."
msgstr ""
-#: doc/classes/GraphEdit.xml:312
+#: doc/classes/GraphEdit.xml:318
msgid "Color of minor grid lines."
msgstr ""
-#: doc/classes/GraphEdit.xml:315
+#: doc/classes/GraphEdit.xml:321
msgid "The icon for the zoom out button."
msgstr ""
-#: doc/classes/GraphEdit.xml:318
+#: doc/classes/GraphEdit.xml:324
msgid "The icon for the zoom in button."
msgstr ""
-#: doc/classes/GraphEdit.xml:321
+#: doc/classes/GraphEdit.xml:327
msgid ""
"The horizontal range within which a port can be grabbed (on both sides)."
msgstr ""
-#: doc/classes/GraphEdit.xml:324
+#: doc/classes/GraphEdit.xml:330
msgid "The vertical range within which a port can be grabbed (on both sides)."
msgstr ""
-#: doc/classes/GraphEdit.xml:327
+#: doc/classes/GraphEdit.xml:333
msgid "The icon for the zoom reset button."
msgstr ""
-#: doc/classes/GraphEdit.xml:330
+#: doc/classes/GraphEdit.xml:336
msgid "The fill color of the selection rectangle."
msgstr ""
-#: doc/classes/GraphEdit.xml:333
+#: doc/classes/GraphEdit.xml:339
msgid "The outline color of the selection rectangle."
msgstr ""
-#: doc/classes/GraphEdit.xml:336
+#: doc/classes/GraphEdit.xml:342
msgid "The icon for the snap toggle button."
msgstr ""
@@ -23049,21 +22865,21 @@ msgstr ""
msgid "The background of the area to the left of the grabber."
msgstr ""
-#: doc/classes/HSlider.xml:23 doc/classes/VSlider.xml:27
+#: doc/classes/HSlider.xml:25 doc/classes/VSlider.xml:29
msgid "The texture for the grabber when it's disabled."
msgstr ""
-#: doc/classes/HSlider.xml:26 doc/classes/VSlider.xml:30
+#: doc/classes/HSlider.xml:28 doc/classes/VSlider.xml:32
msgid "The texture for the grabber when it's focused."
msgstr ""
-#: doc/classes/HSlider.xml:29
+#: doc/classes/HSlider.xml:31
msgid ""
"The background for the whole slider. Determines the height of the "
"[code]grabber_area[/code]."
msgstr ""
-#: doc/classes/HSlider.xml:32 doc/classes/VSlider.xml:36
+#: doc/classes/HSlider.xml:34 doc/classes/VSlider.xml:38
msgid ""
"The texture for the ticks, visible when [member Slider.tick_count] is "
"greater than 0."
@@ -24006,16 +23822,19 @@ msgstr ""
msgid ""
"Native image datatype. Contains image data, which can be converted to a "
"[Texture2D], and several functions to interact with it. The maximum width "
-"and height for an [Image] are [constant MAX_WIDTH] and [constant MAX_HEIGHT]."
+"and height for an [Image] are [constant MAX_WIDTH] and [constant "
+"MAX_HEIGHT].\n"
+"[b]Note:[/b] The maximum image size is 16384×16384 pixels due to graphics "
+"hardware limitations. Larger images will fail to import."
msgstr ""
-#: doc/classes/Image.xml:22
+#: doc/classes/Image.xml:23
msgid ""
"Alpha-blends [code]src_rect[/code] from [code]src[/code] image to this image "
"at coordinates [code]dest[/code]."
msgstr ""
-#: doc/classes/Image.xml:37
+#: doc/classes/Image.xml:38
msgid ""
"Alpha-blends [code]src_rect[/code] from [code]src[/code] image to this image "
"using [code]mask[/code] image at coordinates [code]dst[/code]. Alpha "
@@ -24026,13 +23845,13 @@ msgid ""
"but they can have different formats."
msgstr ""
-#: doc/classes/Image.xml:50
+#: doc/classes/Image.xml:51
msgid ""
"Copies [code]src_rect[/code] from [code]src[/code] image to this image at "
"coordinates [code]dst[/code]."
msgstr ""
-#: doc/classes/Image.xml:65
+#: doc/classes/Image.xml:66
msgid ""
"Blits [code]src_rect[/code] area from [code]src[/code] image to this image "
"at the coordinates given by [code]dst[/code]. [code]src[/code] pixel is "
@@ -24042,17 +23861,17 @@ msgid ""
"different formats."
msgstr ""
-#: doc/classes/Image.xml:74
+#: doc/classes/Image.xml:75
msgid ""
"Converts a bumpmap to a normalmap. A bumpmap provides a height offset per-"
"pixel, while a normalmap provides a normal direction per pixel."
msgstr ""
-#: doc/classes/Image.xml:81
+#: doc/classes/Image.xml:82
msgid "Removes the image's mipmaps."
msgstr ""
-#: doc/classes/Image.xml:94
+#: doc/classes/Image.xml:95
msgid ""
"Compresses the image to use less memory. Can not directly access pixel data "
"while the image is compressed. Returns error if the chosen compression mode "
@@ -24060,22 +23879,22 @@ msgid ""
"constants."
msgstr ""
-#: doc/classes/Image.xml:115
+#: doc/classes/Image.xml:116
msgid "Converts the image's format. See [enum Format] constants."
msgstr ""
-#: doc/classes/Image.xml:124
+#: doc/classes/Image.xml:125
msgid "Copies [code]src[/code] image to this image."
msgstr ""
-#: doc/classes/Image.xml:139
+#: doc/classes/Image.xml:140
msgid ""
"Creates an empty image of given size and format. See [enum Format] "
"constants. If [code]use_mipmaps[/code] is [code]true[/code] then generate "
"mipmaps for this image. See the [method generate_mipmaps]."
msgstr ""
-#: doc/classes/Image.xml:156
+#: doc/classes/Image.xml:157
msgid ""
"Creates a new image of given size and format. See [enum Format] constants. "
"Fills the image with the given raw data. If [code]use_mipmaps[/code] is "
@@ -24083,49 +23902,49 @@ msgid ""
"generate_mipmaps]."
msgstr ""
-#: doc/classes/Image.xml:167
+#: doc/classes/Image.xml:168
msgid ""
"Crops the image to the given [code]width[/code] and [code]height[/code]. If "
"the specified size is larger than the current size, the extra area is filled "
"with black pixels."
msgstr ""
-#: doc/classes/Image.xml:174
+#: doc/classes/Image.xml:175
msgid ""
"Decompresses the image if it is compressed. Returns an error if decompress "
"function is not available."
msgstr ""
-#: doc/classes/Image.xml:181
+#: doc/classes/Image.xml:182
msgid ""
"Returns [constant ALPHA_BLEND] if the image has data for alpha values. "
"Returns [constant ALPHA_BIT] if all the alpha values are stored in a single "
"bit. Returns [constant ALPHA_NONE] if no data for alpha values is found."
msgstr ""
-#: doc/classes/Image.xml:196
+#: doc/classes/Image.xml:197
msgid ""
"Stretches the image and enlarges it by a factor of 2. No interpolation is "
"done."
msgstr ""
-#: doc/classes/Image.xml:205
+#: doc/classes/Image.xml:206
msgid "Fills the image with a given [Color]."
msgstr ""
-#: doc/classes/Image.xml:212
+#: doc/classes/Image.xml:213
msgid "Blends low-alpha pixels with nearby pixels."
msgstr ""
-#: doc/classes/Image.xml:219
+#: doc/classes/Image.xml:220
msgid "Flips the image horizontally."
msgstr ""
-#: doc/classes/Image.xml:226
+#: doc/classes/Image.xml:227
msgid "Flips the image vertically."
msgstr ""
-#: doc/classes/Image.xml:235
+#: doc/classes/Image.xml:236
msgid ""
"Generates mipmaps for the image. Mipmaps are pre-calculated and lower "
"resolution copies of the image. Mipmaps are automatically used if the image "
@@ -24134,125 +23953,129 @@ msgid ""
"in a custom format or if the image's width/height is 0."
msgstr ""
-#: doc/classes/Image.xml:242
+#: doc/classes/Image.xml:243
msgid "Returns the image's raw data."
msgstr ""
-#: doc/classes/Image.xml:249
+#: doc/classes/Image.xml:250
msgid "Returns the image's format. See [enum Format] constants."
msgstr ""
-#: doc/classes/Image.xml:256
+#: doc/classes/Image.xml:257
msgid "Returns the image's height."
msgstr ""
-#: doc/classes/Image.xml:265
+#: doc/classes/Image.xml:266
msgid ""
"Returns the offset where the image's mipmap with index [code]mipmap[/code] "
"is stored in the [code]data[/code] dictionary."
msgstr ""
-#: doc/classes/Image.xml:276
+#: doc/classes/Image.xml:277
msgid ""
"Returns the color of the pixel at [code](x, y)[/code]. This is the same as "
"[method get_pixelv], but with two integer arguments instead of a [Vector2] "
"argument."
msgstr ""
-#: doc/classes/Image.xml:285
+#: doc/classes/Image.xml:286
msgid ""
"Returns the color of the pixel at [code]src[/code]. This is the same as "
"[method get_pixel], but with a [Vector2] argument instead of two integer "
"arguments."
msgstr ""
-#: doc/classes/Image.xml:294
+#: doc/classes/Image.xml:295
msgid ""
"Returns a new image that is a copy of the image's area specified with "
"[code]rect[/code]."
msgstr ""
-#: doc/classes/Image.xml:301
+#: doc/classes/Image.xml:302
msgid "Returns the image's size (width and height)."
msgstr ""
-#: doc/classes/Image.xml:308
+#: doc/classes/Image.xml:309
msgid ""
"Returns a [Rect2] enclosing the visible portion of the image, considering "
"each pixel with a non-zero alpha channel as visible."
msgstr ""
-#: doc/classes/Image.xml:315
+#: doc/classes/Image.xml:316
msgid "Returns the image's width."
msgstr ""
-#: doc/classes/Image.xml:322
+#: doc/classes/Image.xml:323
msgid "Returns [code]true[/code] if the image has generated mipmaps."
msgstr ""
-#: doc/classes/Image.xml:329
+#: doc/classes/Image.xml:330
msgid "Returns [code]true[/code] if the image is compressed."
msgstr ""
-#: doc/classes/Image.xml:336
+#: doc/classes/Image.xml:337
msgid "Returns [code]true[/code] if the image has no data."
msgstr ""
-#: doc/classes/Image.xml:343
+#: doc/classes/Image.xml:344
msgid ""
"Returns [code]true[/code] if all the image's pixels have an alpha value of "
"0. Returns [code]false[/code] if any pixel has an alpha value higher than 0."
msgstr ""
-#: doc/classes/Image.xml:352
-msgid "Loads an image from file [code]path[/code]."
+#: doc/classes/Image.xml:353
+msgid ""
+"Loads an image from file [code]path[/code]. See [url=https://docs."
+"godotengine.org/en/latest/getting_started/workflow/assets/importing_images."
+"html#supported-image-formats]Supported image formats[/url] for a list of "
+"supported image formats and limitations."
msgstr ""
-#: doc/classes/Image.xml:361
+#: doc/classes/Image.xml:362
msgid "Loads an image from the binary contents of a JPEG file."
msgstr ""
-#: doc/classes/Image.xml:370
+#: doc/classes/Image.xml:371
msgid "Loads an image from the binary contents of a PNG file."
msgstr ""
-#: doc/classes/Image.xml:379
+#: doc/classes/Image.xml:380
msgid "Loads an image from the binary contents of a WebP file."
msgstr ""
-#: doc/classes/Image.xml:386
+#: doc/classes/Image.xml:387
msgid ""
"Converts the image's data to represent coordinates on a 3D plane. This is "
"used when the image represents a normalmap. A normalmap can add lots of "
"detail to a 3D surface without increasing the polygon count."
msgstr ""
-#: doc/classes/Image.xml:393
+#: doc/classes/Image.xml:394
msgid ""
"Multiplies color values with alpha values. Resulting color values for a "
"pixel are [code](color * alpha)/256[/code]."
msgstr ""
-#: doc/classes/Image.xml:406
+#: doc/classes/Image.xml:407
msgid ""
"Resizes the image to the given [code]width[/code] and [code]height[/code]. "
"New pixels are calculated using [code]interpolation[/code]. See "
"[code]interpolation[/code] constants."
msgstr ""
-#: doc/classes/Image.xml:415
+#: doc/classes/Image.xml:416
msgid ""
"Resizes the image to the nearest power of 2 for the width and height. If "
"[code]square[/code] is [code]true[/code] then set width and height to be the "
"same."
msgstr ""
-#: doc/classes/Image.xml:422
+#: doc/classes/Image.xml:423
msgid ""
"Converts a standard RGBE (Red Green Blue Exponent) image to an sRGB image."
msgstr ""
-#: doc/classes/Image.xml:433
+#: doc/classes/Image.xml:434
msgid ""
"Saves the image as an EXR file to [code]path[/code]. If [code]grayscale[/"
"code] is [code]true[/code] and the image has only one channel, it will be "
@@ -24261,11 +24084,11 @@ msgid ""
"TinyEXR module."
msgstr ""
-#: doc/classes/Image.xml:442
+#: doc/classes/Image.xml:443
msgid "Saves the image as a PNG file to [code]path[/code]."
msgstr ""
-#: doc/classes/Image.xml:455
+#: doc/classes/Image.xml:456
msgid ""
"Sets the [Color] of the pixel at [code](x, y)[/code]. Example:\n"
"[codeblock]\n"
@@ -24275,7 +24098,7 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/Image.xml:471
+#: doc/classes/Image.xml:472
msgid ""
"Sets the [Color] of the pixel at [code](dst.x, dst.y)[/code]. Note that the "
"[code]dst[/code] values must be integers. Example:\n"
@@ -24286,51 +24109,51 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/Image.xml:483
+#: doc/classes/Image.xml:484
msgid "Shrinks the image by a factor of 2."
msgstr ""
-#: doc/classes/Image.xml:490
+#: doc/classes/Image.xml:491
msgid "Converts the raw data from the sRGB colorspace to a linear scale."
msgstr ""
-#: doc/classes/Image.xml:496
+#: doc/classes/Image.xml:497
msgid ""
"Holds all of the image's color data in a given format. See [enum Format] "
"constants."
msgstr ""
-#: doc/classes/Image.xml:501
+#: doc/classes/Image.xml:502
msgid "The maximal width allowed for [Image] resources."
msgstr ""
-#: doc/classes/Image.xml:504
+#: doc/classes/Image.xml:505
msgid "The maximal height allowed for [Image] resources."
msgstr ""
-#: doc/classes/Image.xml:507
+#: doc/classes/Image.xml:508
msgid "Texture format with a single 8-bit depth representing luminance."
msgstr ""
-#: doc/classes/Image.xml:510
+#: doc/classes/Image.xml:511
msgid ""
"OpenGL texture format with two values, luminance and alpha each stored with "
"8 bits."
msgstr ""
-#: doc/classes/Image.xml:513
+#: doc/classes/Image.xml:514
msgid ""
"OpenGL texture format [code]RED[/code] with a single component and a "
"bitdepth of 8."
msgstr ""
-#: doc/classes/Image.xml:516
+#: doc/classes/Image.xml:517
msgid ""
"OpenGL texture format [code]RG[/code] with two components and a bitdepth of "
"8 for each."
msgstr ""
-#: doc/classes/Image.xml:519
+#: doc/classes/Image.xml:520
msgid ""
"OpenGL texture format [code]RGB[/code] with three components, each with a "
"bitdepth of 8.\n"
@@ -24338,7 +24161,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:523
+#: doc/classes/Image.xml:524
msgid ""
"OpenGL texture format [code]RGBA[/code] with four components, each with a "
"bitdepth of 8.\n"
@@ -24346,67 +24169,67 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:527
+#: doc/classes/Image.xml:528
msgid ""
"OpenGL texture format [code]RGBA[/code] with four components, each with a "
"bitdepth of 4."
msgstr ""
-#: doc/classes/Image.xml:532
+#: doc/classes/Image.xml:533
msgid ""
"OpenGL texture format [code]GL_R32F[/code] where there's one component, a 32-"
"bit floating-point value."
msgstr ""
-#: doc/classes/Image.xml:535
+#: doc/classes/Image.xml:536
msgid ""
"OpenGL texture format [code]GL_RG32F[/code] where there are two components, "
"each a 32-bit floating-point values."
msgstr ""
-#: doc/classes/Image.xml:538
+#: doc/classes/Image.xml:539
msgid ""
"OpenGL texture format [code]GL_RGB32F[/code] where there are three "
"components, each a 32-bit floating-point values."
msgstr ""
-#: doc/classes/Image.xml:541
+#: doc/classes/Image.xml:542
msgid ""
"OpenGL texture format [code]GL_RGBA32F[/code] where there are four "
"components, each a 32-bit floating-point values."
msgstr ""
-#: doc/classes/Image.xml:544
+#: doc/classes/Image.xml:545
msgid ""
"OpenGL texture format [code]GL_R32F[/code] where there's one component, a 16-"
"bit \"half-precision\" floating-point value."
msgstr ""
-#: doc/classes/Image.xml:547
+#: doc/classes/Image.xml:548
msgid ""
"OpenGL texture format [code]GL_RG32F[/code] where there are two components, "
"each a 16-bit \"half-precision\" floating-point value."
msgstr ""
-#: doc/classes/Image.xml:550
+#: doc/classes/Image.xml:551
msgid ""
"OpenGL texture format [code]GL_RGB32F[/code] where there are three "
"components, each a 16-bit \"half-precision\" floating-point value."
msgstr ""
-#: doc/classes/Image.xml:553
+#: doc/classes/Image.xml:554
msgid ""
"OpenGL texture format [code]GL_RGBA32F[/code] where there are four "
"components, each a 16-bit \"half-precision\" floating-point value."
msgstr ""
-#: doc/classes/Image.xml:556
+#: doc/classes/Image.xml:557
msgid ""
"A special OpenGL texture format where the three color components have 9 bits "
"of precision and all three share a single 5-bit exponent."
msgstr ""
-#: doc/classes/Image.xml:559
+#: doc/classes/Image.xml:560
msgid ""
"The [url=https://en.wikipedia.org/wiki/S3_Texture_Compression]S3TC[/url] "
"texture format that uses Block Compression 1, and is the smallest variation "
@@ -24416,7 +24239,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:563
+#: doc/classes/Image.xml:564
msgid ""
"The [url=https://en.wikipedia.org/wiki/S3_Texture_Compression]S3TC[/url] "
"texture format that uses Block Compression 2, and color data is interpreted "
@@ -24426,7 +24249,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:567
+#: doc/classes/Image.xml:568
msgid ""
"The [url=https://en.wikipedia.org/wiki/S3_Texture_Compression]S3TC[/url] "
"texture format also known as Block Compression 3 or BC3 that contains 64 "
@@ -24437,7 +24260,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:571
+#: doc/classes/Image.xml:572
msgid ""
"Texture format that uses [url=https://www.khronos.org/opengl/wiki/"
"Red_Green_Texture_Compression]Red Green Texture Compression[/url], "
@@ -24445,7 +24268,7 @@ msgid ""
"DXT5 uses for the alpha channel."
msgstr ""
-#: doc/classes/Image.xml:574
+#: doc/classes/Image.xml:575
msgid ""
"Texture format that uses [url=https://www.khronos.org/opengl/wiki/"
"Red_Green_Texture_Compression]Red Green Texture Compression[/url], "
@@ -24453,7 +24276,7 @@ msgid ""
"algorithm that DXT5 uses for the alpha channel."
msgstr ""
-#: doc/classes/Image.xml:577
+#: doc/classes/Image.xml:578
msgid ""
"Texture format that uses [url=https://www.khronos.org/opengl/wiki/"
"BPTC_Texture_Compression]BPTC[/url] compression with unsigned normalized "
@@ -24462,21 +24285,21 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:581
+#: doc/classes/Image.xml:582
msgid ""
"Texture format that uses [url=https://www.khronos.org/opengl/wiki/"
"BPTC_Texture_Compression]BPTC[/url] compression with signed floating-point "
"RGB components."
msgstr ""
-#: doc/classes/Image.xml:584
+#: doc/classes/Image.xml:585
msgid ""
"Texture format that uses [url=https://www.khronos.org/opengl/wiki/"
"BPTC_Texture_Compression]BPTC[/url] compression with unsigned floating-point "
"RGB components."
msgstr ""
-#: doc/classes/Image.xml:587
+#: doc/classes/Image.xml:588
msgid ""
"Texture format used on PowerVR-supported mobile platforms, uses 2-bit color "
"depth with no alpha. More information can be found [url=https://en.wikipedia."
@@ -24485,25 +24308,25 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:591
+#: doc/classes/Image.xml:592
msgid ""
"Same as [url=https://en.wikipedia.org/wiki/PVRTC]PVRTC2[/url], but with an "
"alpha component."
msgstr ""
-#: doc/classes/Image.xml:594
+#: doc/classes/Image.xml:595
msgid ""
"Similar to [url=https://en.wikipedia.org/wiki/PVRTC]PVRTC2[/url], but with 4-"
"bit color depth and no alpha."
msgstr ""
-#: doc/classes/Image.xml:597
+#: doc/classes/Image.xml:598
msgid ""
"Same as [url=https://en.wikipedia.org/wiki/PVRTC]PVRTC4[/url], but with an "
"alpha component."
msgstr ""
-#: doc/classes/Image.xml:600
+#: doc/classes/Image.xml:601
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC1]Ericsson Texture Compression format 1[/"
@@ -24511,7 +24334,7 @@ msgid ""
"standard. This format cannot store an alpha channel."
msgstr ""
-#: doc/classes/Image.xml:603
+#: doc/classes/Image.xml:604
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24519,7 +24342,7 @@ msgid ""
"unsigned data."
msgstr ""
-#: doc/classes/Image.xml:606
+#: doc/classes/Image.xml:607
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24527,7 +24350,7 @@ msgid ""
"channel of signed data."
msgstr ""
-#: doc/classes/Image.xml:609
+#: doc/classes/Image.xml:610
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24535,7 +24358,7 @@ msgid ""
"of unsigned data."
msgstr ""
-#: doc/classes/Image.xml:612
+#: doc/classes/Image.xml:613
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24543,7 +24366,7 @@ msgid ""
"channels of signed data."
msgstr ""
-#: doc/classes/Image.xml:615
+#: doc/classes/Image.xml:616
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24553,7 +24376,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:619
+#: doc/classes/Image.xml:620
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24563,7 +24386,7 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:623
+#: doc/classes/Image.xml:624
msgid ""
"[url=https://en.wikipedia.org/wiki/"
"Ericsson_Texture_Compression#ETC2_and_EAC]Ericsson Texture Compression "
@@ -24574,31 +24397,31 @@ msgid ""
"conversion is performed."
msgstr ""
-#: doc/classes/Image.xml:631
+#: doc/classes/Image.xml:632
msgid "Represents the size of the [enum Format] enum."
msgstr ""
-#: doc/classes/Image.xml:634
+#: doc/classes/Image.xml:635
msgid ""
"Performs nearest-neighbor interpolation. If the image is resized, it will be "
"pixelated."
msgstr ""
-#: doc/classes/Image.xml:637
+#: doc/classes/Image.xml:638
msgid ""
"Performs bilinear interpolation. If the image is resized, it will be blurry. "
"This mode is faster than [constant INTERPOLATE_CUBIC], but it results in "
"lower quality."
msgstr ""
-#: doc/classes/Image.xml:640
+#: doc/classes/Image.xml:641
msgid ""
"Performs cubic interpolation. If the image is resized, it will be blurry. "
"This mode often gives better results compared to [constant "
"INTERPOLATE_BILINEAR], at the cost of being slower."
msgstr ""
-#: doc/classes/Image.xml:643
+#: doc/classes/Image.xml:644
msgid ""
"Performs bilinear separately on the two most-suited mipmap levels, then "
"linearly interpolates between them.\n"
@@ -24613,55 +24436,55 @@ msgid ""
"a new set will be generated for the resulting image."
msgstr ""
-#: doc/classes/Image.xml:650
+#: doc/classes/Image.xml:651
msgid ""
"Performs Lanczos interpolation. This is the slowest image resizing mode, but "
"it typically gives the best results, especially when downscalng images."
msgstr ""
-#: doc/classes/Image.xml:653
+#: doc/classes/Image.xml:654
msgid "Image does not have alpha."
msgstr ""
-#: doc/classes/Image.xml:656
+#: doc/classes/Image.xml:657
msgid "Image stores alpha in a single bit."
msgstr ""
-#: doc/classes/Image.xml:659
+#: doc/classes/Image.xml:660
msgid "Image uses alpha."
msgstr ""
-#: doc/classes/Image.xml:662
+#: doc/classes/Image.xml:663
msgid "Use S3TC compression."
msgstr ""
-#: doc/classes/Image.xml:665
+#: doc/classes/Image.xml:666
msgid "Use PVRTC2 compression."
msgstr ""
-#: doc/classes/Image.xml:668
+#: doc/classes/Image.xml:669
msgid "Use PVRTC4 compression."
msgstr ""
-#: doc/classes/Image.xml:671
+#: doc/classes/Image.xml:672
msgid "Use ETC compression."
msgstr ""
-#: doc/classes/Image.xml:674
+#: doc/classes/Image.xml:675
msgid "Use ETC2 compression."
msgstr ""
-#: doc/classes/Image.xml:689
+#: doc/classes/Image.xml:690
msgid ""
"Source texture (before compression) is a regular texture. Default for all "
"textures."
msgstr ""
-#: doc/classes/Image.xml:692
+#: doc/classes/Image.xml:693
msgid "Source texture (before compression) is in sRGB space."
msgstr ""
-#: doc/classes/Image.xml:695
+#: doc/classes/Image.xml:696
msgid ""
"Source texture (before compression) is a normal texture (e.g. it can be "
"compressed into two channels)."
@@ -24674,22 +24497,24 @@ msgstr ""
#: doc/classes/ImageTexture.xml:7
msgid ""
"A [Texture2D] based on an [Image]. Can be created from an [Image] with "
-"[method create_from_image]."
+"[method create_from_image].\n"
+"[b]Note:[/b] The maximum image size is 16384×16384 pixels due to graphics "
+"hardware limitations. Larger images will fail to import."
msgstr ""
-#: doc/classes/ImageTexture.xml:18
+#: doc/classes/ImageTexture.xml:19
msgid "Create a new [ImageTexture] from an [Image]."
msgstr ""
-#: doc/classes/ImageTexture.xml:25
+#: doc/classes/ImageTexture.xml:26
msgid "Returns the format of the [ImageTexture], one of [enum Image.Format]."
msgstr ""
-#: doc/classes/ImageTexture.xml:34
+#: doc/classes/ImageTexture.xml:35
msgid "Resizes the [ImageTexture] to the specified dimensions."
msgstr ""
-#: doc/classes/ImageTexture.xml:45
+#: doc/classes/ImageTexture.xml:46
msgid ""
"Replaces the texture's data with a new [code]image[/code]. If "
"[code]immediate[/code] is [code]true[/code], it will take effect immediately "
@@ -24702,20 +24527,29 @@ msgstr ""
#: doc/classes/ImmediateGeometry3D.xml:7
msgid ""
-"Draws simple geometry from code. Uses a drawing mode similar to OpenGL 1.x."
+"Draws simple geometry from code. Uses a drawing mode similar to OpenGL 1.x.\n"
+"See also [ArrayMesh], [MeshDataTool] and [SurfaceTool] for procedural "
+"geometry generation.\n"
+"[b]Note:[/b] ImmediateGeometry3D is best suited to small amounts of mesh "
+"data that change every frame. It will be slow when handling large amounts of "
+"mesh data. If mesh data doesn't change often, use [ArrayMesh], "
+"[MeshDataTool] or [SurfaceTool] instead.\n"
+"[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-"
+"OpenGL/Face-culling]winding order[/url] for front faces of triangle "
+"primitive modes."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:24
+#: doc/classes/ImmediateGeometry3D.xml:27
msgid ""
"Simple helper to draw an UV sphere with given latitude, longitude and radius."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:33
+#: doc/classes/ImmediateGeometry3D.xml:36
msgid ""
"Adds a vertex in local coordinate space with the currently set color/uv/etc."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:44
+#: doc/classes/ImmediateGeometry3D.xml:47
msgid ""
"Begin drawing (and optionally pass a texture override). When done call "
"[method end]. For more information on how this works, search for "
@@ -24723,34 +24557,453 @@ msgid ""
"For the type of primitive, see the [enum Mesh.PrimitiveType] enum."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:52
+#: doc/classes/ImmediateGeometry3D.xml:55
msgid "Clears everything that was drawn using begin/end."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:59
+#: doc/classes/ImmediateGeometry3D.xml:62
msgid "Ends a drawing context and displays the results."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:68
+#: doc/classes/ImmediateGeometry3D.xml:71
msgid "The current drawing color."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:77
+#: doc/classes/ImmediateGeometry3D.xml:80
msgid "The next vertex's normal."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:86
+#: doc/classes/ImmediateGeometry3D.xml:89
msgid "The next vertex's tangent (and binormal facing)."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:95
+#: doc/classes/ImmediateGeometry3D.xml:98
msgid "The next vertex's UV."
msgstr ""
-#: doc/classes/ImmediateGeometry3D.xml:104
+#: doc/classes/ImmediateGeometry3D.xml:107
msgid "The next vertex's second layer UV."
msgstr ""
+#: doc/classes/Input.xml:4
+msgid "A singleton that deals with inputs."
+msgstr ""
+
+#: doc/classes/Input.xml:7
+msgid ""
+"A singleton that deals with inputs. This includes key presses, mouse buttons "
+"and movement, joypads, and input actions. Actions and their events can be "
+"set in the [b]Input Map[/b] tab in the [b]Project > Project Settings[/b], or "
+"with the [InputMap] class."
+msgstr ""
+
+#: doc/classes/Input.xml:10
+msgid "https://docs.godotengine.org/en/latest/tutorials/inputs/index.html"
+msgstr ""
+
+#: doc/classes/Input.xml:21
+msgid ""
+"This will simulate pressing the specified action.\n"
+"The strength can be used for non-boolean actions, it's ranged between 0 and "
+"1 representing the intensity of the given action.\n"
+"[b]Note:[/b] This method will not cause any [method Node._input] calls. It "
+"is intended to be used with [method is_action_pressed] and [method "
+"is_action_just_pressed]. If you want to simulate [code]_input[/code], use "
+"[method parse_input_event] instead."
+msgstr ""
+
+#: doc/classes/Input.xml:32
+msgid "If the specified action is already pressed, this will release it."
+msgstr ""
+
+#: doc/classes/Input.xml:43
+msgid ""
+"Adds a new mapping entry (in SDL2 format) to the mapping database. "
+"Optionally update already connected devices."
+msgstr ""
+
+#: doc/classes/Input.xml:50
+msgid ""
+"If the device has an accelerometer, this will return the acceleration. "
+"Otherwise, it returns an empty [Vector3].\n"
+"Note this method returns an empty [Vector3] when running from the editor "
+"even when your device has an accelerometer. You must export your project to "
+"a supported device to read values from the accelerometer."
+msgstr ""
+
+#: doc/classes/Input.xml:60
+msgid ""
+"Returns a value between 0 and 1 representing the intensity of the given "
+"action. In a joypad, for example, the further away the axis (analog sticks "
+"or L2, R2 triggers) is from the dead zone, the closer the value will be to "
+"1. If the action is mapped to a control that has no axis as the keyboard, "
+"the value returned will be 0 or 1."
+msgstr ""
+
+#: doc/classes/Input.xml:67
+msgid ""
+"Returns an [Array] containing the device IDs of all currently connected "
+"joypads."
+msgstr ""
+
+#: doc/classes/Input.xml:74
+msgid "Returns the currently assigned cursor shape (see [enum CursorShape])."
+msgstr ""
+
+#: doc/classes/Input.xml:81
+msgid ""
+"If the device has an accelerometer, this will return the gravity. Otherwise, "
+"it returns an empty [Vector3]."
+msgstr ""
+
+#: doc/classes/Input.xml:88
+msgid ""
+"If the device has a gyroscope, this will return the rate of rotation in rad/"
+"s around a device's X, Y, and Z axes. Otherwise, it returns an empty "
+"[Vector3]."
+msgstr ""
+
+#: doc/classes/Input.xml:99
+msgid ""
+"Returns the current value of the joypad axis at given index (see [enum "
+"JoyAxisList])."
+msgstr ""
+
+#: doc/classes/Input.xml:108
+msgid "Returns the index of the provided axis name."
+msgstr ""
+
+#: doc/classes/Input.xml:117
+msgid ""
+"Receives a [enum JoyAxisList] axis and returns its equivalent name as a "
+"string."
+msgstr ""
+
+#: doc/classes/Input.xml:126
+msgid "Returns the index of the provided button name."
+msgstr ""
+
+#: doc/classes/Input.xml:135
+msgid ""
+"Receives a gamepad button from [enum JoyButtonList] and returns its "
+"equivalent name as a string."
+msgstr ""
+
+#: doc/classes/Input.xml:144
+msgid ""
+"Returns a SDL2-compatible device GUID on platforms that use gamepad "
+"remapping. Returns [code]\"Default Gamepad\"[/code] otherwise."
+msgstr ""
+
+#: doc/classes/Input.xml:153
+msgid "Returns the name of the joypad at the specified device index."
+msgstr ""
+
+#: doc/classes/Input.xml:162
+msgid "Returns the duration of the current vibration effect in seconds."
+msgstr ""
+
+#: doc/classes/Input.xml:171
+msgid ""
+"Returns the strength of the joypad vibration: x is the strength of the weak "
+"motor, and y is the strength of the strong motor."
+msgstr ""
+
+#: doc/classes/Input.xml:178
+msgid ""
+"Returns the mouse speed for the last time the cursor was moved, and this "
+"until the next frame where the mouse moves. This means that even if the "
+"mouse is not moving, this function will still return the value of the last "
+"motion."
+msgstr ""
+
+#: doc/classes/Input.xml:185
+msgid ""
+"If the device has a magnetometer, this will return the magnetic field "
+"strength in micro-Tesla for all axes."
+msgstr ""
+
+#: doc/classes/Input.xml:192
+msgid ""
+"Returns mouse buttons as a bitmask. If multiple mouse buttons are pressed at "
+"the same time, the bits are added together."
+msgstr ""
+
+#: doc/classes/Input.xml:199
+msgid "Returns the mouse mode. See the constants for more information."
+msgstr ""
+
+#: doc/classes/Input.xml:208
+msgid ""
+"Returns [code]true[/code] when the user starts pressing the action event, "
+"meaning it's [code]true[/code] only on the frame that the user pressed down "
+"the button.\n"
+"This is useful for code that needs to run only once when an action is "
+"pressed, instead of every frame while it's pressed."
+msgstr ""
+
+#: doc/classes/Input.xml:218
+msgid ""
+"Returns [code]true[/code] when the user stops pressing the action event, "
+"meaning it's [code]true[/code] only on the frame that the user released the "
+"button."
+msgstr ""
+
+#: doc/classes/Input.xml:227
+msgid ""
+"Returns [code]true[/code] if you are pressing the action event. Note that if "
+"an action has multiple buttons assigned and more than one of them is "
+"pressed, releasing one button will release the action, even if some other "
+"button assigned to this action is still pressed."
+msgstr ""
+
+#: doc/classes/Input.xml:238
+msgid ""
+"Returns [code]true[/code] if you are pressing the joypad button (see [enum "
+"JoyButtonList])."
+msgstr ""
+
+#: doc/classes/Input.xml:247
+msgid ""
+"Returns [code]true[/code] if the system knows the specified device. This "
+"means that it sets all button and axis indices. Unknown joypads are not "
+"expected to match these constants, but you can still retrieve events from them."
+msgstr ""
+
+#: doc/classes/Input.xml:256
+msgid ""
+"Returns [code]true[/code] if you are pressing the key in the current "
+"keyboard layout. You can pass a [enum KeyList] constant."
+msgstr ""
+
+#: doc/classes/Input.xml:265
+msgid ""
+"Returns [code]true[/code] if you are pressing the mouse button specified "
+"with [enum ButtonList]."
+msgstr ""
+
+#: doc/classes/Input.xml:280
+msgid ""
+"Notifies the [Input] singleton that a connection has changed, to update the "
+"state for the [code]device[/code] index.\n"
+"This is used internally and should not have to be called from user scripts. "
+"See [signal joy_connection_changed] for the signal emitted when this is "
+"triggered internally."
+msgstr ""
+
+#: doc/classes/Input.xml:290
+msgid ""
+"Feeds an [InputEvent] to the game. Can be used to artificially trigger input "
+"events from code. Also generates [method Node._input] calls.\n"
+"Example:\n"
+"[codeblock]\n"
+"var a = InputEventAction.new()\n"
+"a.action = \"ui_cancel\"\n"
+"a.pressed = true\n"
+"Input.parse_input_event(a)\n"
+"[/codeblock]"
+msgstr ""
+
+#: doc/classes/Input.xml:306
+msgid ""
+"Removes all mappings from the internal database that match the given GUID."
+msgstr ""
+
+#: doc/classes/Input.xml:319
+msgid ""
+"Sets a custom mouse cursor image, which is only visible inside the game "
+"window. The hotspot can also be specified. Passing [code]null[/code] to the "
+"image parameter resets to the system cursor. See [enum CursorShape] for the "
+"list of shapes.\n"
+"[code]image[/code]'s size must be lower than 256×256.\n"
+"[code]hotspot[/code] must be within [code]image[/code]'s size.\n"
+"[b]Note:[/b] [AnimatedTexture]s aren't supported as custom mouse cursors. If "
+"using an [AnimatedTexture], only the first frame will be displayed.\n"
+"[b]Note:[/b] Only images imported with the [b]Lossless[/b], [b]Lossy[/b] or "
+"[b]Uncompressed[/b] compression modes are supported. The [b]Video RAM[/b] "
+"compression mode can't be used for custom cursors."
+msgstr ""
+
+#: doc/classes/Input.xml:332
+msgid ""
+"Sets the default cursor shape to be used in the viewport instead of "
+"[constant CURSOR_ARROW].\n"
+"[b]Note:[/b] If you want to change the default cursor shape for [Control]'s "
+"nodes, use [member Control.mouse_default_cursor_shape] instead.\n"
+"[b]Note:[/b] This method generates an [InputEventMouseMotion] to update "
+"cursor immediately."
+msgstr ""
+
+#: doc/classes/Input.xml:343
+msgid "Sets the mouse mode. See the constants for more information."
+msgstr ""
+
+#: doc/classes/Input.xml:352
+msgid ""
+"Enables or disables the accumulation of similar input events sent by the "
+"operating system. When input accumulation is enabled, all input events "
+"generated during a frame will be merged and emitted when the frame is done "
+"rendering. Therefore, this limits the number of input method calls per "
+"second to the rendering FPS.\n"
+"Input accumulation is enabled by default. It can be disabled to get slightly "
+"more precise/reactive input at the cost of increased CPU usage. In "
+"applications where drawing freehand lines is required, input accumulation "
+"should generally be disabled while the user is drawing the line to get "
+"results that closely follow the actual input."
+msgstr ""
+
+#: doc/classes/Input.xml:368
+msgid ""
+"Starts to vibrate the joypad. Joypads usually come with two rumble motors, a "
+"strong and a weak one. [code]weak_magnitude[/code] is the strength of the "
+"weak motor (between 0 and 1) and [code]strong_magnitude[/code] is the "
+"strength of the strong motor (between 0 and 1). [code]duration[/code] is the "
+"duration of the effect in seconds (a duration of 0 will try to play the "
+"vibration indefinitely).\n"
+"[b]Note:[/b] Not every hardware is compatible with long effect durations; it "
+"is recommended to restart an effect if it has to be played for more than a "
+"few seconds."
+msgstr ""
+
+#: doc/classes/Input.xml:378
+msgid "Stops the vibration of the joypad."
+msgstr ""
+
+#: doc/classes/Input.xml:387
+msgid ""
+"Vibrate Android and iOS devices.\n"
+"[b]Note:[/b] It needs VIBRATE permission for Android at export settings. iOS "
+"does not support duration."
+msgstr ""
+
+#: doc/classes/Input.xml:397
+msgid "Sets the mouse position to the specified vector."
+msgstr ""
+
+#: doc/classes/Input.xml:408
+msgid "Emitted when a joypad device has been connected or disconnected."
+msgstr ""
+
+#: doc/classes/Input.xml:414
+msgid "Makes the mouse cursor visible if it is hidden."
+msgstr ""
+
+#: doc/classes/Input.xml:417
+msgid "Makes the mouse cursor hidden if it is visible."
+msgstr ""
+
+#: doc/classes/Input.xml:420
+msgid ""
+"Captures the mouse. The mouse will be hidden and unable to leave the game "
+"window, but it will still register movement and mouse button presses. On "
+"Windows and Linux, the mouse will use raw input mode, which means the "
+"reported movement will be unaffected by the OS' mouse acceleration settings."
+msgstr ""
+
+#: doc/classes/Input.xml:423
+msgid "Makes the mouse cursor visible but confines it to the game window."
+msgstr ""
+
+#: doc/classes/Input.xml:426
+msgid "Arrow cursor. Standard, default pointing cursor."
+msgstr ""
+
+#: doc/classes/Input.xml:429
+msgid ""
+"I-beam cursor. Usually used to show where the text cursor will appear when "
+"the mouse is clicked."
+msgstr ""
+
+#: doc/classes/Input.xml:432
+msgid ""
+"Pointing hand cursor. Usually used to indicate the pointer is over a link or "
+"other interactable item."
+msgstr ""
+
+#: doc/classes/Input.xml:435
+msgid ""
+"Cross cursor. Typically appears over regions in which a drawing operation "
+"can be performed or for selections."
+msgstr ""
+
+#: doc/classes/Input.xml:438
+msgid ""
+"Wait cursor. Indicates that the application is busy performing an operation. "
+"This cursor shape denotes that the application is still usable during the "
+"operation."
+msgstr ""
+
+#: doc/classes/Input.xml:441
+msgid ""
+"Busy cursor. Indicates that the application is busy performing an operation. "
+"This cursor shape denotes that the application isn't usable during the "
+"operation (e.g. something is blocking its main thread)."
+msgstr ""
+
+#: doc/classes/Input.xml:444
+msgid "Drag cursor. Usually displayed when dragging something."
+msgstr ""
+
+#: doc/classes/Input.xml:447
+msgid ""
+"Can drop cursor. Usually displayed when dragging something to indicate that "
+"it can be dropped at the current position."
+msgstr ""
+
+#: doc/classes/Input.xml:450
+msgid ""
+"Forbidden cursor. Indicates that the current action is forbidden (for "
+"example, when dragging something) or that the control at a position is "
+"disabled."
+msgstr ""
+
+#: doc/classes/Input.xml:453
+msgid ""
+"Vertical resize mouse cursor. A double-headed vertical arrow. It tells the "
+"user they can resize the window or the panel vertically."
+msgstr ""
+
+#: doc/classes/Input.xml:456
+msgid ""
+"Horizontal resize mouse cursor. A double-headed horizontal arrow. It tells "
+"the user they can resize the window or the panel horizontally."
+msgstr ""
+
+#: doc/classes/Input.xml:459
+msgid ""
+"Window resize mouse cursor. The cursor is a double-headed arrow that goes "
+"from the bottom left to the top right. It tells the user they can resize the "
+"window or the panel both horizontally and vertically."
+msgstr ""
+
+#: doc/classes/Input.xml:462
+msgid ""
+"Window resize mouse cursor. The cursor is a double-headed arrow that goes "
+"from the top left to the bottom right, the opposite of [constant "
+"CURSOR_BDIAGSIZE]. It tells the user they can resize the window or the panel "
+"both horizontally and vertically."
+msgstr ""
+
+#: doc/classes/Input.xml:465
+msgid "Move cursor. Indicates that something can be moved."
+msgstr ""
+
+#: doc/classes/Input.xml:468
+msgid ""
+"Vertical split mouse cursor. On Windows, it's the same as [constant "
+"CURSOR_VSIZE]."
+msgstr ""
+
+#: doc/classes/Input.xml:471
+msgid ""
+"Horizontal split mouse cursor. On Windows, it's the same as [constant "
+"CURSOR_HSIZE]."
+msgstr ""
+
+#: doc/classes/Input.xml:474
+msgid "Help cursor. Usually a question mark."
+msgstr ""
+
#: doc/classes/InputEvent.xml:4
msgid "Generic input event."
msgstr ""
@@ -24906,7 +25159,7 @@ msgid ""
msgstr ""
#: doc/classes/InputEventJoypadButton.xml:16
-msgid "Button identifier. One of the [enum JoystickList] button constants."
+msgid "Button identifier. One of the [enum JoyButtonList] button constants."
msgstr ""
#: doc/classes/InputEventJoypadButton.xml:19
@@ -24934,7 +25187,7 @@ msgid ""
msgstr ""
#: doc/classes/InputEventJoypadMotion.xml:16
-msgid "Axis identifier. Use one of the [enum JoystickList] axis constants."
+msgid "Axis identifier. Use one of the [enum JoyAxisList] axis constants."
msgstr ""
#: doc/classes/InputEventJoypadMotion.xml:19
@@ -24956,8 +25209,8 @@ msgstr ""
#: doc/classes/InputEventKey.xml:17
msgid ""
-"Returns the keycode combined with modifier keys such as [code]Shift[/code] "
-"or [code]Alt[/code]. See also [InputEventWithModifiers].\n"
+"Returns the keycode combined with modifier keys such as [kbd]Shift[/kbd] or "
+"[kbd]Alt[/kbd]. See also [InputEventWithModifiers].\n"
"To get a human-readable representation of the [InputEventKey] with "
"modifiers, use [code]OS.get_keycode_string(event."
"get_keycode_with_modifiers())[/code] where [code]event[/code] is the "
@@ -24966,8 +25219,8 @@ msgstr ""
#: doc/classes/InputEventKey.xml:25
msgid ""
-"Returns the physical keycode combined with modifier keys such as "
-"[code]Shift[/code] or [code]Alt[/code]. See also [InputEventWithModifiers].\n"
+"Returns the physical keycode combined with modifier keys such as [kbd]Shift[/"
+"kbd] or [kbd]Alt[/kbd]. See also [InputEventWithModifiers].\n"
"To get a human-readable representation of the [InputEventKey] with "
"modifiers, use [code]OS.get_keycode_string(event."
"get_physical_keycode_with_modifiers())[/code] where [code]event[/code] is "
@@ -25174,448 +25427,28 @@ msgstr ""
#: doc/classes/InputEventWithModifiers.xml:7
msgid ""
-"Contains keys events information with modifiers support like [code]Shift[/"
-"code] or [code]Alt[/code]. See [method Node._input]."
+"Contains keys events information with modifiers support like [kbd]Shift[/"
+"kbd] or [kbd]Alt[/kbd]. See [method Node._input]."
msgstr ""
#: doc/classes/InputEventWithModifiers.xml:16
-msgid "State of the [code]Alt[/code] modifier."
+msgid "State of the [kbd]Alt[/kbd] modifier."
msgstr ""
#: doc/classes/InputEventWithModifiers.xml:19
-msgid "State of the [code]Command[/code] modifier."
+msgid "State of the [kbd]Cmd[/kbd] modifier."
msgstr ""
#: doc/classes/InputEventWithModifiers.xml:22
-msgid "State of the [code]Ctrl[/code] modifier."
+msgid "State of the [kbd]Ctrl[/kbd] modifier."
msgstr ""
#: doc/classes/InputEventWithModifiers.xml:25
-msgid "State of the [code]Meta[/code] modifier."
+msgid "State of the [kbd]Meta[/kbd] modifier."
msgstr ""
#: doc/classes/InputEventWithModifiers.xml:28
-msgid "State of the [code]Shift[/code] modifier."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:4
-msgid "A singleton that deals with inputs."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:7
-msgid ""
-"A singleton that deals with inputs. This includes key presses, mouse buttons "
-"and movement, joypads, and input actions. Actions and their events can be "
-"set in the [b]Input Map[/b] tab in the [b]Project > Project Settings[/b], or "
-"with the [InputMap] class."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:10
-msgid "https://docs.godotengine.org/en/latest/tutorials/inputs/index.html"
-msgstr ""
-
-#: doc/classes/InputFilter.xml:21
-msgid ""
-"This will simulate pressing the specified action.\n"
-"The strength can be used for non-boolean actions, it's ranged between 0 and "
-"1 representing the intensity of the given action.\n"
-"[b]Note:[/b] This method will not cause any [method Node._input] calls. It "
-"is intended to be used with [method is_action_pressed] and [method "
-"is_action_just_pressed]. If you want to simulate [code]_input[/code], use "
-"[method parse_input_event] instead."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:32
-msgid "If the specified action is already pressed, this will release it."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:43
-msgid ""
-"Adds a new mapping entry (in SDL2 format) to the mapping database. "
-"Optionally update already connected devices."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:50
-msgid ""
-"If the device has an accelerometer, this will return the acceleration. "
-"Otherwise, it returns an empty [Vector3].\n"
-"Note this method returns an empty [Vector3] when running from the editor "
-"even when your device has an accelerometer. You must export your project to "
-"a supported device to read values from the accelerometer."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:60
-msgid ""
-"Returns a value between 0 and 1 representing the intensity of the given "
-"action. In a joypad, for example, the further away the axis (analog sticks "
-"or L2, R2 triggers) is from the dead zone, the closer the value will be to "
-"1. If the action is mapped to a control that has no axis as the keyboard, "
-"the value returned will be 0 or 1."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:67
-msgid ""
-"Returns an [Array] containing the device IDs of all currently connected "
-"joypads."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:74
-msgid "Returns the currently assigned cursor shape (see [enum CursorShape])."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:81
-msgid ""
-"If the device has an accelerometer, this will return the gravity. Otherwise, "
-"it returns an empty [Vector3]."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:88
-msgid ""
-"If the device has a gyroscope, this will return the rate of rotation in rad/"
-"s around a device's X, Y, and Z axes. Otherwise, it returns an empty "
-"[Vector3]."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:99
-msgid ""
-"Returns the current value of the joypad axis at given index (see [enum "
-"JoystickList])."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:108
-msgid "Returns the index of the provided axis name."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:117
-msgid ""
-"Receives a [enum JoystickList] axis and returns its equivalent name as a "
-"string."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:126
-msgid "Returns the index of the provided button name."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:135
-msgid ""
-"Receives a gamepad button from [enum JoystickList] and returns its "
-"equivalent name as a string."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:144
-msgid ""
-"Returns a SDL2-compatible device GUID on platforms that use gamepad "
-"remapping. Returns [code]\"Default Gamepad\"[/code] otherwise."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:153
-msgid "Returns the name of the joypad at the specified device index."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:162
-msgid "Returns the duration of the current vibration effect in seconds."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:171
-msgid ""
-"Returns the strength of the joypad vibration: x is the strength of the weak "
-"motor, and y is the strength of the strong motor."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:178
-msgid ""
-"Returns the mouse speed for the last time the cursor was moved, and this "
-"until the next frame where the mouse moves. This means that even if the "
-"mouse is not moving, this function will still return the value of the last "
-"motion."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:185
-msgid ""
-"If the device has a magnetometer, this will return the magnetic field "
-"strength in micro-Tesla for all axes."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:192
-msgid ""
-"Returns mouse buttons as a bitmask. If multiple mouse buttons are pressed at "
-"the same time, the bits are added together."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:199
-msgid "Returns the mouse mode. See the constants for more information."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:208
-msgid ""
-"Returns [code]true[/code] when the user starts pressing the action event, "
-"meaning it's [code]true[/code] only on the frame that the user pressed down "
-"the button.\n"
-"This is useful for code that needs to run only once when an action is "
-"pressed, instead of every frame while it's pressed."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:218
-msgid ""
-"Returns [code]true[/code] when the user stops pressing the action event, "
-"meaning it's [code]true[/code] only on the frame that the user released the "
-"button."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:227
-msgid ""
-"Returns [code]true[/code] if you are pressing the action event. Note that if "
-"an action has multiple buttons assigned and more than one of them is "
-"pressed, releasing one button will release the action, even if some other "
-"button assigned to this action is still pressed."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:238
-msgid ""
-"Returns [code]true[/code] if you are pressing the joypad button (see [enum "
-"JoystickList])."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:247
-msgid ""
-"Returns [code]true[/code] if the system knows the specified device. This "
-"means that it sets all button and axis indices exactly as defined in [enum "
-"JoystickList]. Unknown joypads are not expected to match these constants, "
-"but you can still retrieve events from them."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:256
-msgid ""
-"Returns [code]true[/code] if you are pressing the key in the current "
-"keyboard layout. You can pass a [enum KeyList] constant."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:265
-msgid ""
-"Returns [code]true[/code] if you are pressing the mouse button specified "
-"with [enum ButtonList]."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:280
-msgid ""
-"Notifies the [InputFilter] singleton that a connection has changed, to "
-"update the state for the [code]device[/code] index.\n"
-"This is used internally and should not have to be called from user scripts. "
-"See [signal joy_connection_changed] for the signal emitted when this is "
-"triggered internally."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:290
-msgid ""
-"Feeds an [InputEvent] to the game. Can be used to artificially trigger input "
-"events from code. Also generates [method Node._input] calls.\n"
-"Example:\n"
-"[codeblock]\n"
-"var a = InputEventAction.new()\n"
-"a.action = \"ui_cancel\"\n"
-"a.pressed = true\n"
-"InputFilter.parse_input_event(a)\n"
-"[/codeblock]"
-msgstr ""
-
-#: doc/classes/InputFilter.xml:306
-msgid ""
-"Removes all mappings from the internal database that match the given GUID."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:319
-msgid ""
-"Sets a custom mouse cursor image, which is only visible inside the game "
-"window. The hotspot can also be specified. Passing [code]null[/code] to the "
-"image parameter resets to the system cursor. See [enum CursorShape] for the "
-"list of shapes.\n"
-"[code]image[/code]'s size must be lower than 256×256.\n"
-"[code]hotspot[/code] must be within [code]image[/code]'s size.\n"
-"[b]Note:[/b] [AnimatedTexture]s aren't supported as custom mouse cursors. If "
-"using an [AnimatedTexture], only the first frame will be displayed.\n"
-"[b]Note:[/b] Only images imported with the [b]Lossless[/b], [b]Lossy[/b] or "
-"[b]Uncompressed[/b] compression modes are supported. The [b]Video RAM[/b] "
-"compression mode can't be used for custom cursors."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:332
-msgid ""
-"Sets the default cursor shape to be used in the viewport instead of "
-"[constant CURSOR_ARROW].\n"
-"[b]Note:[/b] If you want to change the default cursor shape for [Control]'s "
-"nodes, use [member Control.mouse_default_cursor_shape] instead.\n"
-"[b]Note:[/b] This method generates an [InputEventMouseMotion] to update "
-"cursor immediately."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:343
-msgid "Sets the mouse mode. See the constants for more information."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:352
-msgid ""
-"Enables or disables the accumulation of similar input events sent by the "
-"operating system. When input accumulation is enabled, all input events "
-"generated during a frame will be merged and emitted when the frame is done "
-"rendering. Therefore, this limits the number of input method calls per "
-"second to the rendering FPS.\n"
-"Input accumulation is enabled by default. It can be disabled to get slightly "
-"more precise/reactive input at the cost of increased CPU usage. In "
-"applications where drawing freehand lines is required, input accumulation "
-"should generally be disabled while the user is drawing the line to get "
-"results that closely follow the actual input."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:368
-msgid ""
-"Starts to vibrate the joypad. Joypads usually come with two rumble motors, a "
-"strong and a weak one. [code]weak_magnitude[/code] is the strength of the "
-"weak motor (between 0 and 1) and [code]strong_magnitude[/code] is the "
-"strength of the strong motor (between 0 and 1). [code]duration[/code] is the "
-"duration of the effect in seconds (a duration of 0 will try to play the "
-"vibration indefinitely).\n"
-"[b]Note:[/b] Not every hardware is compatible with long effect durations; it "
-"is recommended to restart an effect if it has to be played for more than a "
-"few seconds."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:378
-msgid "Stops the vibration of the joypad."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:387
-msgid ""
-"Vibrate Android and iOS devices.\n"
-"[b]Note:[/b] It needs VIBRATE permission for Android at export settings. iOS "
-"does not support duration."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:397
-msgid "Sets the mouse position to the specified vector."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:408
-msgid "Emitted when a joypad device has been connected or disconnected."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:414
-msgid "Makes the mouse cursor visible if it is hidden."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:417
-msgid "Makes the mouse cursor hidden if it is visible."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:420
-msgid ""
-"Captures the mouse. The mouse will be hidden and unable to leave the game "
-"window, but it will still register movement and mouse button presses. On "
-"Windows and Linux, the mouse will use raw input mode, which means the "
-"reported movement will be unaffected by the OS' mouse acceleration settings."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:423
-msgid "Makes the mouse cursor visible but confines it to the game window."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:426
-msgid "Arrow cursor. Standard, default pointing cursor."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:429
-msgid ""
-"I-beam cursor. Usually used to show where the text cursor will appear when "
-"the mouse is clicked."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:432
-msgid ""
-"Pointing hand cursor. Usually used to indicate the pointer is over a link or "
-"other interactable item."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:435
-msgid ""
-"Cross cursor. Typically appears over regions in which a drawing operation "
-"can be performed or for selections."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:438
-msgid ""
-"Wait cursor. Indicates that the application is busy performing an operation. "
-"This cursor shape denotes that the application is still usable during the "
-"operation."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:441
-msgid ""
-"Busy cursor. Indicates that the application is busy performing an operation. "
-"This cursor shape denotes that the application isn't usable during the "
-"operation (e.g. something is blocking its main thread)."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:444
-msgid "Drag cursor. Usually displayed when dragging something."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:447
-msgid ""
-"Can drop cursor. Usually displayed when dragging something to indicate that "
-"it can be dropped at the current position."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:450
-msgid ""
-"Forbidden cursor. Indicates that the current action is forbidden (for "
-"example, when dragging something) or that the control at a position is "
-"disabled."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:453
-msgid ""
-"Vertical resize mouse cursor. A double-headed vertical arrow. It tells the "
-"user they can resize the window or the panel vertically."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:456
-msgid ""
-"Horizontal resize mouse cursor. A double-headed horizontal arrow. It tells "
-"the user they can resize the window or the panel horizontally."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:459
-msgid ""
-"Window resize mouse cursor. The cursor is a double-headed arrow that goes "
-"from the bottom left to the top right. It tells the user they can resize the "
-"window or the panel both horizontally and vertically."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:462
-msgid ""
-"Window resize mouse cursor. The cursor is a double-headed arrow that goes "
-"from the top left to the bottom right, the opposite of [constant "
-"CURSOR_BDIAGSIZE]. It tells the user they can resize the window or the panel "
-"both horizontally and vertically."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:465
-msgid "Move cursor. Indicates that something can be moved."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:468
-msgid ""
-"Vertical split mouse cursor. On Windows, it's the same as [constant "
-"CURSOR_VSIZE]."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:471
-msgid ""
-"Horizontal split mouse cursor. On Windows, it's the same as [constant "
-"CURSOR_HSIZE]."
-msgstr ""
-
-#: doc/classes/InputFilter.xml:474
-msgid "Help cursor. Usually a question mark."
+msgid "State of the [kbd]Shift[/kbd] modifier."
msgstr ""
#: doc/classes/InputMap.xml:4
@@ -25886,14 +25719,6 @@ msgstr ""
msgid "Address type: Any."
msgstr ""
-#: doc/classes/IP_Unix.xml:4
-msgid "UNIX IP support. See [IP]."
-msgstr ""
-
-#: doc/classes/IP_Unix.xml:7
-msgid "UNIX-specific implementation of IP support functions. See [IP]."
-msgstr ""
-
#: doc/classes/ItemList.xml:4
msgid ""
"Control that provides a list of selectable items (and/or icons) in a single "
@@ -25908,7 +25733,7 @@ msgid ""
"Selectable items in the list may be selected or deselected and multiple "
"selection may be enabled. Selection with right mouse button may also be "
"enabled to allow use of popup context menus. Items may also be \"activated\" "
-"by double-clicking them or by pressing Enter.\n"
+"by double-clicking them or by pressing [kbd]Enter[/kbd].\n"
"Item text only supports single-line strings, newline characters (e.g. "
"[code]\\n[/code]) in the string won't produce a newline. Text wrapping is "
"enabled in [constant ICON_MODE_TOP] mode, but column's width is adjusted to "
@@ -26067,7 +25892,7 @@ msgstr ""
msgid ""
"Disables (or enables) the item at the specified index.\n"
"Disabled items cannot be selected and do not trigger activation signals "
-"(when double-clicking or pressing Enter)."
+"(when double-clicking or pressing [kbd]Enter[/kbd])."
msgstr ""
#: doc/classes/ItemList.xml:292
@@ -26202,7 +26027,7 @@ msgstr ""
#: doc/classes/ItemList.xml:455
msgid ""
"Triggered when specified list item is activated via double-clicking or by "
-"pressing Enter."
+"pressing [kbd]Enter[/kbd]."
msgstr ""
#: doc/classes/ItemList.xml:464
@@ -26252,7 +26077,9 @@ msgid "Only allow selecting a single item."
msgstr ""
#: doc/classes/ItemList.xml:511
-msgid "Allows selecting multiple items by holding Ctrl or Shift."
+msgid ""
+"Allows selecting multiple items by holding [kbd]Ctrl[/kbd] or [kbd]Shift[/"
+"kbd]."
msgstr ""
#: doc/classes/ItemList.xml:516
@@ -27243,59 +27070,91 @@ msgid ""
msgstr ""
#: doc/classes/Light3D.xml:39
-msgid "The light's bake mode. See [enum BakeMode]."
+msgid ""
+"Angular size of the light in degrees. Only available for "
+"[DirectionalLight3D]s. For reference, the sun from earth is approximately "
+"[code]0.5[/code]."
msgstr ""
#: doc/classes/Light3D.xml:42
-msgid "The light's color."
+msgid "The light's bake mode. See [enum BakeMode]."
msgstr ""
#: doc/classes/Light3D.xml:45
-msgid "The light will affect objects in the selected layers."
+msgid "The light's color."
msgstr ""
#: doc/classes/Light3D.xml:48
-msgid "The light's strength multiplier."
+msgid "The light will affect objects in the selected layers."
msgstr ""
#: doc/classes/Light3D.xml:51
+msgid "The light's strength multiplier."
+msgstr ""
+
+#: doc/classes/Light3D.xml:54
msgid ""
"Secondary multiplier used with indirect light (light bounces). Used with "
"[GIProbe]."
msgstr ""
-#: doc/classes/Light3D.xml:54
+#: doc/classes/Light3D.xml:57
msgid ""
"If [code]true[/code], the light's effect is reversed, darkening areas and "
"casting bright shadows."
msgstr ""
-#: doc/classes/Light3D.xml:57
+#: doc/classes/Light3D.xml:60
+msgid ""
+"[Texture2D] projected by light. [member shadow_enabled] must be on for the "
+"projector to work. Light projectors make the light appear as if it is "
+"shining through a colored but transparent object, almost like light shining "
+"through stained glass."
+msgstr ""
+
+#: doc/classes/Light3D.xml:63
+msgid ""
+"The size of the light in Godot units. Only available for [OmniLight3D]s and "
+"[SpotLight3D]s."
+msgstr ""
+
+#: doc/classes/Light3D.xml:66
msgid ""
"The intensity of the specular blob in objects affected by the light. At "
"[code]0[/code] the light becomes a pure diffuse light."
msgstr ""
-#: doc/classes/Light3D.xml:60
+#: doc/classes/Light3D.xml:69
msgid ""
"Used to adjust shadow appearance. Too small a value results in self-"
"shadowing, while too large a value causes shadows to separate from casters. "
"Adjust as needed."
msgstr ""
-#: doc/classes/Light3D.xml:63
-msgid "The color of shadows cast by this light."
+#: doc/classes/Light3D.xml:72 doc/classes/RenderingServer.xml:3374
+msgid ""
+"Blurs the edges of the shadow. Can be used to hide pixel artifacts in low "
+"resolution shadow maps. A high value can make shadows appear grainy and can "
+"cause other unwanted artifacts. Try to keep as near default as possible."
msgstr ""
-#: doc/classes/Light3D.xml:66
-msgid "Attempts to reduce [member shadow_bias] gap."
+#: doc/classes/Light3D.xml:75
+msgid "The color of shadows cast by this light."
msgstr ""
-#: doc/classes/Light3D.xml:69
+#: doc/classes/Light3D.xml:78
msgid "If [code]true[/code], the light will cast shadows."
msgstr ""
-#: doc/classes/Light3D.xml:72
+#: doc/classes/Light3D.xml:81
+msgid ""
+"Offsets the lookup into the shadow map by the objects normal. This can be "
+"used reduce self-shadowing artifacts without using [member shadow_bias]. In "
+"practice, this value should be tweaked along with [member shadow_bias] to "
+"reduce artifacts as much as possible."
+msgstr ""
+
+#: doc/classes/Light3D.xml:84
msgid ""
"If [code]true[/code], reverses the backface culling of the mesh. This can be "
"useful when you have a flat mesh that has a light behind it. If you need to "
@@ -27304,93 +27163,105 @@ msgid ""
"SHADOW_CASTING_SETTING_DOUBLE_SIDED]."
msgstr ""
-#: doc/classes/Light3D.xml:77
+#: doc/classes/Light3D.xml:91
msgid "Constant for accessing [member light_energy]."
msgstr ""
-#: doc/classes/Light3D.xml:80
+#: doc/classes/Light3D.xml:94
msgid "Constant for accessing [member light_indirect_energy]."
msgstr ""
-#: doc/classes/Light3D.xml:83
+#: doc/classes/Light3D.xml:97
msgid "Constant for accessing [member light_specular]."
msgstr ""
-#: doc/classes/Light3D.xml:86
+#: doc/classes/Light3D.xml:100
msgid ""
"Constant for accessing [member OmniLight3D.omni_range] or [member "
"SpotLight3D.spot_range]."
msgstr ""
-#: doc/classes/Light3D.xml:89
+#: doc/classes/Light3D.xml:103
+msgid "Constant for accessing [member light_size]."
+msgstr ""
+
+#: doc/classes/Light3D.xml:106
msgid ""
"Constant for accessing [member OmniLight3D.omni_attenuation] or [member "
"SpotLight3D.spot_attenuation]."
msgstr ""
-#: doc/classes/Light3D.xml:92
+#: doc/classes/Light3D.xml:109
msgid "Constant for accessing [member SpotLight3D.spot_angle]."
msgstr ""
-#: doc/classes/Light3D.xml:95
+#: doc/classes/Light3D.xml:112
msgid "Constant for accessing [member SpotLight3D.spot_angle_attenuation]."
msgstr ""
-#: doc/classes/Light3D.xml:98
-msgid "Constant for accessing [member shadow_contact]."
-msgstr ""
-
-#: doc/classes/Light3D.xml:101
+#: doc/classes/Light3D.xml:115
msgid ""
"Constant for accessing [member DirectionalLight3D."
"directional_shadow_max_distance]."
msgstr ""
-#: doc/classes/Light3D.xml:104
+#: doc/classes/Light3D.xml:118
msgid ""
"Constant for accessing [member DirectionalLight3D."
"directional_shadow_split_1]."
msgstr ""
-#: doc/classes/Light3D.xml:107
+#: doc/classes/Light3D.xml:121
msgid ""
"Constant for accessing [member DirectionalLight3D."
"directional_shadow_split_2]."
msgstr ""
-#: doc/classes/Light3D.xml:110
+#: doc/classes/Light3D.xml:124
msgid ""
"Constant for accessing [member DirectionalLight3D."
"directional_shadow_split_3]."
msgstr ""
-#: doc/classes/Light3D.xml:115
+#: doc/classes/Light3D.xml:127
msgid ""
"Constant for accessing [member DirectionalLight3D."
-"directional_shadow_normal_bias]."
+"directional_shadow_fade_start]."
msgstr ""
-#: doc/classes/Light3D.xml:118
+#: doc/classes/Light3D.xml:130
+msgid "Constant for accessing [member shadow_normal_bias]."
+msgstr ""
+
+#: doc/classes/Light3D.xml:133
msgid "Constant for accessing [member shadow_bias]."
msgstr ""
-#: doc/classes/Light3D.xml:121
+#: doc/classes/Light3D.xml:136
msgid ""
"Constant for accessing [member DirectionalLight3D."
-"directional_shadow_bias_split_scale]."
+"directional_shadow_pancake_size]."
msgstr ""
-#: doc/classes/Light3D.xml:127
+#: doc/classes/Light3D.xml:139
+msgid "Constant for accessing [member shadow_blur]."
+msgstr ""
+
+#: doc/classes/Light3D.xml:142
+msgid "Constant for accessing [member shadow_transmittance_bias]."
+msgstr ""
+
+#: doc/classes/Light3D.xml:148
msgid ""
"Light is ignored when baking.\n"
"[b]Note:[/b] Hiding a light does [i]not[/i] affect baking."
msgstr ""
-#: doc/classes/Light3D.xml:131
+#: doc/classes/Light3D.xml:152
msgid "Only indirect lighting will be baked (default)."
msgstr ""
-#: doc/classes/Light3D.xml:134
+#: doc/classes/Light3D.xml:155
msgid ""
"Both direct and indirect light will be baked.\n"
"[b]Note:[/b] You should hide the light if you don't want it to appear twice "
@@ -27581,32 +27452,40 @@ msgstr ""
msgid ""
"LineEdit provides a single-line string editor, used for text fields.\n"
"It features many built-in shortcuts which will always be available "
-"([code]Ctrl[/code] here maps to [code]Command[/code] on macOS):\n"
-"- Ctrl + C: Copy\n"
-"- Ctrl + X: Cut\n"
-"- Ctrl + V or Ctrl + Y: Paste/\"yank\"\n"
-"- Ctrl + Z: Undo\n"
-"- Ctrl + Shift + Z: Redo\n"
-"- Ctrl + U: Delete text from the cursor position to the beginning of the "
-"line\n"
-"- Ctrl + K: Delete text from the cursor position to the end of the line\n"
-"- Ctrl + A: Select all text\n"
-"- Up/Down arrow: Move the cursor to the beginning/end of the line\n"
-"On macOS, some extra keyboard shortcuts are available:\n"
-"- Ctrl + F: Like the right arrow key, move the cursor one character right\n"
-"- Ctrl + B: Like the left arrow key, move the cursor one character left\n"
-"- Ctrl + P: Like the up arrow key, move the cursor to the previous line\n"
-"- Ctrl + N: Like the down arrow key, move the cursor to the next line\n"
-"- Ctrl + D: Like the Delete key, delete the character on the right side of "
-"cursor\n"
-"- Ctrl + H: Like the Backspace key, delete the character on the left side of "
-"the cursor\n"
-"- Ctrl + A: Like the Home key, move the cursor to the beginning of the line\n"
-"- Ctrl + E: Like the End key, move the cursor to the end of the line\n"
-"- Command + Left arrow: Like the Home key, move the cursor to the beginning "
+"([kbd]Ctrl[/kbd] here maps to [kbd]Cmd[/kbd] on macOS):\n"
+"- [kbd]Ctrl + C[/kbd]: Copy\n"
+"- [kbd]Ctrl + X[/kbd]: Cut\n"
+"- [kbd]Ctrl + V[/kbd] or [kbd]Ctrl + Y[/kbd]: Paste/\"yank\"\n"
+"- [kbd]Ctrl + Z[/kbd]: Undo\n"
+"- [kbd]Ctrl + Shift + Z[/kbd]: Redo\n"
+"- [kbd]Ctrl + U[/kbd]: Delete text from the cursor position to the beginning "
"of the line\n"
-"- Command + Right arrow: Like the End key, move the cursor to the end of the "
-"line"
+"- [kbd]Ctrl + K[/kbd]: Delete text from the cursor position to the end of "
+"the line\n"
+"- [kbd]Ctrl + A[/kbd]: Select all text\n"
+"- [kbd]Up Arrow[/kbd]/[kbd]Down Arrow[/kbd]: Move the cursor to the "
+"beginning/end of the line\n"
+"On macOS, some extra keyboard shortcuts are available:\n"
+"- [kbd]Ctrl + F[/kbd]: Same as [kbd]Right Arrow[/kbd], move the cursor one "
+"character right\n"
+"- [kbd]Ctrl + B[/kbd]: Same as [kbd]Left Arrow[/kbd], move the cursor one "
+"character left\n"
+"- [kbd]Ctrl + P[/kbd]: Same as [kbd]Up Arrow[/kbd], move the cursor to the "
+"previous line\n"
+"- [kbd]Ctrl + N[/kbd]: Same as [kbd]Down Arrow[/kbd], move the cursor to the "
+"next line\n"
+"- [kbd]Ctrl + D[/kbd]: Same as [kbd]Delete[/kbd], delete the character on "
+"the right side of cursor\n"
+"- [kbd]Ctrl + H[/kbd]: Same as [kbd]Backspace[/kbd], delete the character on "
+"the left side of the cursor\n"
+"- [kbd]Ctrl + A[/kbd]: Same as [kbd]Home[/kbd], move the cursor to the "
+"beginning of the line\n"
+"- [kbd]Ctrl + E[/kbd]: Same as [kbd]End[/kbd], move the cursor to the end of "
+"the line\n"
+"- [kbd]Cmd + Left Arrow[/kbd]: Same as [kbd]Home[/kbd], move the cursor to "
+"the beginning of the line\n"
+"- [kbd]Cmd + Right Arrow[/kbd]: Same as [kbd]End[/kbd], move the cursor to "
+"the end of the line"
msgstr ""
#: doc/classes/LineEdit.xml:39
@@ -27751,7 +27630,7 @@ msgid ""
"max_length]."
msgstr ""
-#: doc/classes/LineEdit.xml:163 doc/classes/TextEdit.xml:513
+#: doc/classes/LineEdit.xml:163 doc/classes/TextEdit.xml:514
msgid "Emitted when the text changes."
msgstr ""
@@ -27775,11 +27654,11 @@ msgstr ""
msgid "Stretches whitespaces to fit the [LineEdit]'s width."
msgstr ""
-#: doc/classes/LineEdit.xml:188 doc/classes/TextEdit.xml:534
+#: doc/classes/LineEdit.xml:188 doc/classes/TextEdit.xml:535
msgid "Cuts (copies and clears) the selected text."
msgstr ""
-#: doc/classes/LineEdit.xml:191 doc/classes/TextEdit.xml:537
+#: doc/classes/LineEdit.xml:191 doc/classes/TextEdit.xml:538
msgid "Copies the selected text."
msgstr ""
@@ -27799,7 +27678,7 @@ msgstr ""
msgid "Selects the whole [LineEdit] text."
msgstr ""
-#: doc/classes/LineEdit.xml:204 doc/classes/TextEdit.xml:549
+#: doc/classes/LineEdit.xml:204 doc/classes/TextEdit.xml:550
msgid "Undoes the previous action."
msgstr ""
@@ -27807,7 +27686,7 @@ msgstr ""
msgid "Reverse the last undo action."
msgstr ""
-#: doc/classes/LineEdit.xml:210 doc/classes/TextEdit.xml:555
+#: doc/classes/LineEdit.xml:210 doc/classes/TextEdit.xml:556
msgid "Represents the size of the [enum MenuItems] enum."
msgstr ""
@@ -28437,11 +28316,11 @@ msgstr ""
msgid "Render array as triangle strips."
msgstr ""
-#: doc/classes/Mesh.xml:126 doc/classes/RenderingServer.xml:3254
+#: doc/classes/Mesh.xml:126 doc/classes/RenderingServer.xml:3306
msgid "Blend shapes are normalized."
msgstr ""
-#: doc/classes/Mesh.xml:129 doc/classes/RenderingServer.xml:3257
+#: doc/classes/Mesh.xml:129 doc/classes/RenderingServer.xml:3309
msgid "Blend shapes are relative to base weight."
msgstr ""
@@ -28483,37 +28362,37 @@ msgstr ""
msgid "Mesh array uses indices."
msgstr ""
-#: doc/classes/Mesh.xml:159 doc/classes/RenderingServer.xml:3210
+#: doc/classes/Mesh.xml:159 doc/classes/RenderingServer.xml:3262
msgid "Flag used to mark a compressed (half float) normal array."
msgstr ""
-#: doc/classes/Mesh.xml:162 doc/classes/RenderingServer.xml:3213
+#: doc/classes/Mesh.xml:162 doc/classes/RenderingServer.xml:3265
msgid "Flag used to mark a compressed (half float) tangent array."
msgstr ""
-#: doc/classes/Mesh.xml:165 doc/classes/RenderingServer.xml:3216
+#: doc/classes/Mesh.xml:165 doc/classes/RenderingServer.xml:3268
msgid "Flag used to mark a compressed (half float) color array."
msgstr ""
-#: doc/classes/Mesh.xml:168 doc/classes/RenderingServer.xml:3219
+#: doc/classes/Mesh.xml:168 doc/classes/RenderingServer.xml:3271
msgid "Flag used to mark a compressed (half float) UV coordinates array."
msgstr ""
-#: doc/classes/Mesh.xml:171 doc/classes/RenderingServer.xml:3222
+#: doc/classes/Mesh.xml:171 doc/classes/RenderingServer.xml:3274
msgid ""
"Flag used to mark a compressed (half float) UV coordinates array for the "
"second UV coordinates."
msgstr ""
-#: doc/classes/Mesh.xml:174 doc/classes/RenderingServer.xml:3225
+#: doc/classes/Mesh.xml:174 doc/classes/RenderingServer.xml:3277
msgid "Flag used to mark a compressed index array."
msgstr ""
-#: doc/classes/Mesh.xml:177 doc/classes/RenderingServer.xml:3228
+#: doc/classes/Mesh.xml:177 doc/classes/RenderingServer.xml:3283
msgid "Flag used to mark that the array contains 2D vertices."
msgstr ""
-#: doc/classes/Mesh.xml:180 doc/classes/RenderingServer.xml:3233
+#: doc/classes/Mesh.xml:180 doc/classes/RenderingServer.xml:3280
msgid ""
"Used to set flags [constant ARRAY_COMPRESS_NORMAL], [constant "
"ARRAY_COMPRESS_TANGENT], [constant ARRAY_COMPRESS_COLOR], [constant "
@@ -28578,67 +28457,72 @@ msgid ""
" mdt.set_vertex(i, vertex)\n"
"mesh.surface_remove(0)\n"
"mdt.commit_to_surface(mesh)\n"
-"[/codeblock]"
+"[/codeblock]\n"
+"See also [ArrayMesh], [ImmediateGeometry3D] and [SurfaceTool] for procedural "
+"geometry generation.\n"
+"[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-"
+"OpenGL/Face-culling]winding order[/url] for front faces of triangle "
+"primitive modes."
msgstr ""
-#: doc/classes/MeshDataTool.xml:28
+#: doc/classes/MeshDataTool.xml:30
msgid "Clears all data currently in MeshDataTool."
msgstr ""
-#: doc/classes/MeshDataTool.xml:37
+#: doc/classes/MeshDataTool.xml:39
msgid "Adds a new surface to specified [Mesh] with edited data."
msgstr ""
-#: doc/classes/MeshDataTool.xml:48
+#: doc/classes/MeshDataTool.xml:50
msgid ""
"Uses specified surface of given [Mesh] to populate data for MeshDataTool.\n"
"Requires [Mesh] with primitive type [constant Mesh.PRIMITIVE_TRIANGLES]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:56
+#: doc/classes/MeshDataTool.xml:58
msgid "Returns the number of edges in this [Mesh]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:65
+#: doc/classes/MeshDataTool.xml:67
msgid "Returns array of faces that touch given edge."
msgstr ""
-#: doc/classes/MeshDataTool.xml:74
+#: doc/classes/MeshDataTool.xml:76
msgid "Returns meta information assigned to given edge."
msgstr ""
-#: doc/classes/MeshDataTool.xml:85
+#: doc/classes/MeshDataTool.xml:87
msgid ""
"Returns index of specified vertex connected to given edge.\n"
"Vertex argument can only be 0 or 1 because edges are comprised of two "
"vertices."
msgstr ""
-#: doc/classes/MeshDataTool.xml:93
+#: doc/classes/MeshDataTool.xml:95
msgid "Returns the number of faces in this [Mesh]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:104
+#: doc/classes/MeshDataTool.xml:106
msgid ""
"Returns specified edge associated with given face.\n"
"Edge argument must 2 or less because a face only has three edges."
msgstr ""
-#: doc/classes/MeshDataTool.xml:114
+#: doc/classes/MeshDataTool.xml:116
msgid "Returns the metadata associated with the given face."
msgstr ""
-#: doc/classes/MeshDataTool.xml:123
+#: doc/classes/MeshDataTool.xml:125
msgid "Calculates and returns the face normal of the given face."
msgstr ""
-#: doc/classes/MeshDataTool.xml:134
+#: doc/classes/MeshDataTool.xml:136
msgid ""
"Returns the specified vertex of the given face.\n"
"Vertex argument must be 2 or less because faces contain three vertices."
msgstr ""
-#: doc/classes/MeshDataTool.xml:142
+#: doc/classes/MeshDataTool.xml:144
msgid ""
"Returns the [Mesh]'s format. Format is an integer made up of [Mesh] format "
"flags combined together. For example, a mesh containing both vertices and "
@@ -28648,103 +28532,103 @@ msgid ""
"See [enum ArrayMesh.ArrayFormat] for a list of format flags."
msgstr ""
-#: doc/classes/MeshDataTool.xml:150
+#: doc/classes/MeshDataTool.xml:152
msgid "Returns the material assigned to the [Mesh]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:159
+#: doc/classes/MeshDataTool.xml:161
msgid "Returns the vertex at given index."
msgstr ""
-#: doc/classes/MeshDataTool.xml:168
+#: doc/classes/MeshDataTool.xml:170
msgid "Returns the bones of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:177
+#: doc/classes/MeshDataTool.xml:179
msgid "Returns the color of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:184
+#: doc/classes/MeshDataTool.xml:186
msgid "Returns the total number of vertices in [Mesh]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:193
+#: doc/classes/MeshDataTool.xml:195
msgid "Returns an array of edges that share the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:202
+#: doc/classes/MeshDataTool.xml:204
msgid "Returns an array of faces that share the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:211
+#: doc/classes/MeshDataTool.xml:213
msgid "Returns the metadata associated with the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:220
+#: doc/classes/MeshDataTool.xml:222
msgid "Returns the normal of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:229
+#: doc/classes/MeshDataTool.xml:231
msgid "Returns the tangent of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:238
+#: doc/classes/MeshDataTool.xml:240
msgid "Returns the UV of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:247
+#: doc/classes/MeshDataTool.xml:249
msgid "Returns the UV2 of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:256
+#: doc/classes/MeshDataTool.xml:258
msgid "Returns bone weights of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:267
+#: doc/classes/MeshDataTool.xml:269
msgid "Sets the metadata of the given edge."
msgstr ""
-#: doc/classes/MeshDataTool.xml:278
+#: doc/classes/MeshDataTool.xml:280
msgid "Sets the metadata of the given face."
msgstr ""
-#: doc/classes/MeshDataTool.xml:287
+#: doc/classes/MeshDataTool.xml:289
msgid "Sets the material to be used by newly-constructed [Mesh]."
msgstr ""
-#: doc/classes/MeshDataTool.xml:298
+#: doc/classes/MeshDataTool.xml:300
msgid "Sets the position of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:309
+#: doc/classes/MeshDataTool.xml:311
msgid "Sets the bones of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:320
+#: doc/classes/MeshDataTool.xml:322
msgid "Sets the color of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:331
+#: doc/classes/MeshDataTool.xml:333
msgid "Sets the metadata associated with the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:342
+#: doc/classes/MeshDataTool.xml:344
msgid "Sets the normal of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:353
+#: doc/classes/MeshDataTool.xml:355
msgid "Sets the tangent of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:364
+#: doc/classes/MeshDataTool.xml:366
msgid "Sets the UV of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:375
+#: doc/classes/MeshDataTool.xml:377
msgid "Sets the UV2 of the given vertex."
msgstr ""
-#: doc/classes/MeshDataTool.xml:386
+#: doc/classes/MeshDataTool.xml:388
msgid "Sets the bone weights of the given vertex."
msgstr ""
@@ -28990,9 +28874,9 @@ msgid ""
"setting [member eye_height].\n"
"You can initialise this interface as follows:\n"
"[codeblock]\n"
-"var interface = ARVRServer.find_interface(\"Native mobile\")\n"
+"var interface = XRServer.find_interface(\"Native mobile\")\n"
"if interface and interface.initialize():\n"
-" get_viewport().arvr = true\n"
+" get_viewport().xr = true\n"
"[/codeblock]"
msgstr ""
@@ -29009,7 +28893,7 @@ msgstr ""
#: modules/mobile_vr/doc_classes/MobileVRInterface.xml:28
msgid ""
"The height at which the camera is placed in relation to the ground (i.e. "
-"[ARVROrigin] node)."
+"[XROrigin3D] node)."
msgstr ""
#: modules/mobile_vr/doc_classes/MobileVRInterface.xml:31
@@ -31489,7 +31373,7 @@ msgstr ""
#: doc/classes/Node.xml:935
msgid ""
"Notification received from the OS when a close request is sent (e.g. closing "
-"the window with a \"Close\" button or Alt+F4).\n"
+"the window with a \"Close\" button or [kbd]Alt + F4[/kbd]).\n"
"Implemented on desktop platforms."
msgstr ""
@@ -31591,11 +31475,21 @@ msgid ""
msgstr ""
#: doc/classes/Node2D.xml:95
-msgid "Converts a local point's coordinates to global coordinates."
+msgid ""
+"Transforms the provided local position into a position in global coordinate "
+"space. The input is expected to be local relative to the [Node2D] it is "
+"called on. e.g. Applying this method to the positions of child nodes will "
+"correctly transform their positions into the global coordinate space, but "
+"applying it to a node's own position will give an incorrect result, as it "
+"will incorporate the node's own transformation into its global position."
msgstr ""
#: doc/classes/Node2D.xml:104
-msgid "Converts a global point's coordinates to local coordinates."
+msgid ""
+"Transforms the provided global position into a position in local coordinate "
+"space. The output will be local relative to the [Node2D] it is called on. e."
+"g. It is appropriate for determining the positions of child nodes, but it is "
+"not appropriate for determining its own position relative to its parent."
msgstr ""
#: doc/classes/Node2D.xml:113
@@ -31670,80 +31564,83 @@ msgid ""
"operations in this coordinate system correspond to direct affine operations "
"on the [Node3D]'s transform. The word local below refers to this coordinate "
"system. The coordinate system that is attached to the [Node3D] object itself "
-"is referred to as object-local coordinate system."
+"is referred to as object-local coordinate system.\n"
+"[b]Note:[/b] Unless otherwise specified, all methods that have angle "
+"parameters must have angles specified as [i]radians[/i]. To convert degrees "
+"to radians, use [method @GDScript.deg2rad]."
msgstr ""
-#: doc/classes/Node3D.xml:11
+#: doc/classes/Node3D.xml:12
msgid ""
"https://docs.godotengine.org/en/latest/tutorials/3d/introduction_to_3d.html"
msgstr ""
-#: doc/classes/Node3D.xml:25
+#: doc/classes/Node3D.xml:26
msgid ""
"Returns the parent [Node3D], or an empty [Object] if no parent exists or "
"parent is not of type [Node3D]."
msgstr ""
-#: doc/classes/Node3D.xml:32
+#: doc/classes/Node3D.xml:33
msgid ""
"Returns the current [World3D] resource this [Node3D] node is registered to."
msgstr ""
-#: doc/classes/Node3D.xml:43
+#: doc/classes/Node3D.xml:44
msgid ""
"Rotates the global (world) transformation around axis, a unit [Vector3], by "
"specified angle in radians. The rotation axis is in global coordinate system."
msgstr ""
-#: doc/classes/Node3D.xml:52
+#: doc/classes/Node3D.xml:53
msgid ""
"Scales the global (world) transformation by the given [Vector3] scale "
"factors."
msgstr ""
-#: doc/classes/Node3D.xml:61
+#: doc/classes/Node3D.xml:62
msgid ""
"Moves the global (world) transformation by [Vector3] offset. The offset is "
"in global coordinate system."
msgstr ""
-#: doc/classes/Node3D.xml:68
+#: doc/classes/Node3D.xml:69
msgid ""
"Disables rendering of this node. Changes [member visible] to [code]false[/"
"code]."
msgstr ""
-#: doc/classes/Node3D.xml:75
+#: doc/classes/Node3D.xml:76
msgid ""
"Returns whether node notifies about its local transformation changes. "
"[Node3D] will not propagate this by default."
msgstr ""
-#: doc/classes/Node3D.xml:82
+#: doc/classes/Node3D.xml:83
msgid ""
"Returns whether this node uses a scale of [code](1, 1, 1)[/code] or its "
"local transformation scale."
msgstr ""
-#: doc/classes/Node3D.xml:89
+#: doc/classes/Node3D.xml:90
msgid ""
"Returns whether this node is set as Toplevel, that is whether it ignores its "
"parent nodes transformations."
msgstr ""
-#: doc/classes/Node3D.xml:96
+#: doc/classes/Node3D.xml:97
msgid ""
"Returns whether the node notifies about its global and local transformation "
"changes. [Node3D] will not propagate this by default."
msgstr ""
-#: doc/classes/Node3D.xml:103
+#: doc/classes/Node3D.xml:104
msgid ""
"Returns whether the node is visible, taking into consideration that its "
"parents visibility."
msgstr ""
-#: doc/classes/Node3D.xml:114
+#: doc/classes/Node3D.xml:115
msgid ""
"Rotates itself so that the local -Z axis points towards the [code]target[/"
"code] position.\n"
@@ -31753,106 +31650,106 @@ msgid ""
"Operations take place in global space."
msgstr ""
-#: doc/classes/Node3D.xml:129
+#: doc/classes/Node3D.xml:130
msgid ""
"Moves the node to the specified [code]position[/code], and then rotates "
"itself to point toward the [code]target[/code] as per [method look_at]. "
"Operations take place in global space."
msgstr ""
-#: doc/classes/Node3D.xml:136
+#: doc/classes/Node3D.xml:137
msgid ""
"Resets this node's transformations (like scale, skew and taper) preserving "
"its rotation and translation by performing Gram-Schmidt orthonormalization "
"on this node's [Transform]."
msgstr ""
-#: doc/classes/Node3D.xml:147
+#: doc/classes/Node3D.xml:148
msgid ""
"Rotates the local transformation around axis, a unit [Vector3], by specified "
"angle in radians."
msgstr ""
-#: doc/classes/Node3D.xml:158
+#: doc/classes/Node3D.xml:159
msgid ""
"Rotates the local transformation around axis, a unit [Vector3], by specified "
"angle in radians. The rotation axis is in object-local coordinate system."
msgstr ""
-#: doc/classes/Node3D.xml:167
+#: doc/classes/Node3D.xml:168
msgid "Rotates the local transformation around the X axis by angle in radians."
msgstr ""
-#: doc/classes/Node3D.xml:176
+#: doc/classes/Node3D.xml:177
msgid "Rotates the local transformation around the Y axis by angle in radians."
msgstr ""
-#: doc/classes/Node3D.xml:185
+#: doc/classes/Node3D.xml:186
msgid "Rotates the local transformation around the Z axis by angle in radians."
msgstr ""
-#: doc/classes/Node3D.xml:194
+#: doc/classes/Node3D.xml:195
msgid ""
"Scales the local transformation by given 3D scale factors in object-local "
"coordinate system."
msgstr ""
-#: doc/classes/Node3D.xml:203
+#: doc/classes/Node3D.xml:204
msgid ""
"Makes the node ignore its parents transformations. Node transformations are "
"only in global space."
msgstr ""
-#: doc/classes/Node3D.xml:212
+#: doc/classes/Node3D.xml:213
msgid ""
"Sets whether the node uses a scale of [code](1, 1, 1)[/code] or its local "
"transformation scale. Changes to the local transformation scale are "
"preserved."
msgstr ""
-#: doc/classes/Node3D.xml:219
+#: doc/classes/Node3D.xml:220
msgid ""
"Reset all transformations for this node (sets its [Transform] to the "
"identity matrix)."
msgstr ""
-#: doc/classes/Node3D.xml:228
+#: doc/classes/Node3D.xml:229
msgid ""
"Sets whether the node ignores notification that its transformation (global "
"or local) changed."
msgstr ""
-#: doc/classes/Node3D.xml:237
+#: doc/classes/Node3D.xml:238
msgid ""
"Sets whether the node notifies about its local transformation changes. "
"[Node3D] will not propagate this by default."
msgstr ""
-#: doc/classes/Node3D.xml:246
+#: doc/classes/Node3D.xml:247
msgid ""
"Sets whether the node notifies about its global and local transformation "
"changes. [Node3D] will not propagate this by default."
msgstr ""
-#: doc/classes/Node3D.xml:253
+#: doc/classes/Node3D.xml:254
msgid ""
"Enables rendering of this node. Changes [member visible] to [code]true[/"
"code]."
msgstr ""
-#: doc/classes/Node3D.xml:262
+#: doc/classes/Node3D.xml:263
msgid ""
"Transforms [code]local_point[/code] from this node's local space to world "
"space."
msgstr ""
-#: doc/classes/Node3D.xml:271
+#: doc/classes/Node3D.xml:272
msgid ""
"Transforms [code]global_point[/code] from world space to this node's local "
"space."
msgstr ""
-#: doc/classes/Node3D.xml:280
+#: doc/classes/Node3D.xml:281
msgid ""
"Changes the node's position by the given offset [Vector3].\n"
"Note that the translation [code]offset[/code] is affected by the node's "
@@ -31861,26 +31758,26 @@ msgid ""
"to the X coordinate."
msgstr ""
-#: doc/classes/Node3D.xml:290
+#: doc/classes/Node3D.xml:291
msgid ""
"Changes the node's position by the given offset [Vector3] in local space."
msgstr ""
-#: doc/classes/Node3D.xml:297
+#: doc/classes/Node3D.xml:298
msgid "Updates the [Node3DGizmo] of this node."
msgstr ""
-#: doc/classes/Node3D.xml:303
+#: doc/classes/Node3D.xml:304
msgid ""
"The [Node3DGizmo] for this node. Used for example in [EditorNode3DGizmo] as "
"custom visualization and editing handles in Editor."
msgstr ""
-#: doc/classes/Node3D.xml:306
+#: doc/classes/Node3D.xml:307
msgid "World3D space (global) [Transform] of this node."
msgstr ""
-#: doc/classes/Node3D.xml:309
+#: doc/classes/Node3D.xml:310
msgid ""
"Rotation part of the local transformation in radians, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle).\n"
@@ -31893,33 +31790,33 @@ msgid ""
"\" is not meaningful."
msgstr ""
-#: doc/classes/Node3D.xml:313
+#: doc/classes/Node3D.xml:314
msgid ""
"Rotation part of the local transformation in degrees, specified in terms of "
"YXZ-Euler angles in the format (X angle, Y angle, Z angle)."
msgstr ""
-#: doc/classes/Node3D.xml:316
+#: doc/classes/Node3D.xml:317
msgid "Scale part of the local transformation."
msgstr ""
-#: doc/classes/Node3D.xml:319
+#: doc/classes/Node3D.xml:320
msgid "Local space [Transform] of this node, with respect to the parent node."
msgstr ""
-#: doc/classes/Node3D.xml:322
+#: doc/classes/Node3D.xml:323
msgid "Local translation of this node."
msgstr ""
-#: doc/classes/Node3D.xml:325
+#: doc/classes/Node3D.xml:326
msgid "If [code]true[/code], this node is drawn."
msgstr ""
-#: doc/classes/Node3D.xml:331
+#: doc/classes/Node3D.xml:332
msgid "Emitted when node visibility changes."
msgstr ""
-#: doc/classes/Node3D.xml:337
+#: doc/classes/Node3D.xml:338
msgid ""
"Node3D nodes receives this notification when their global transform changes. "
"This means that either the current or a parent node changed its transform.\n"
@@ -31927,19 +31824,19 @@ msgid ""
"need to ask for it, with [method set_notify_transform]."
msgstr ""
-#: doc/classes/Node3D.xml:341
+#: doc/classes/Node3D.xml:342
msgid ""
"Node3D nodes receives this notification when they are registered to new "
"[World3D] resource."
msgstr ""
-#: doc/classes/Node3D.xml:344
+#: doc/classes/Node3D.xml:345
msgid ""
"Node3D nodes receives this notification when they are unregistered from "
"current [World3D] resource."
msgstr ""
-#: doc/classes/Node3D.xml:347
+#: doc/classes/Node3D.xml:348
msgid "Node3D nodes receives this notification when their visibility changes."
msgstr ""
@@ -33315,11 +33212,13 @@ msgid ""
"code]. See [url=https://blog.escapecreative.com/customizing-mailto-"
"links/]Customizing [code]mailto:[/code] Links[/url] for a list of fields "
"that can be added.\n"
+"Use [method ProjectSettings.globalize_path] to convert a [code]res://[/code] "
+"or [code]user://[/code] path into a system path for use with this method.\n"
"[b]Note:[/b] This method is implemented on Android, iOS, HTML5, Linux, macOS "
"and Windows."
msgstr ""
-#: doc/classes/OS.xml:493
+#: doc/classes/OS.xml:494
msgid ""
"The exit code passed to the OS when the main loop exits. By convention, an "
"exit code of [code]0[/code] indicates success whereas a non-zero exit code "
@@ -33329,133 +33228,133 @@ msgid ""
"with an [code]exit_code[/code] argument passed."
msgstr ""
-#: doc/classes/OS.xml:497
+#: doc/classes/OS.xml:498
msgid ""
"If [code]true[/code], the engine optimizes for low processor usage by only "
"refreshing the screen if needed. Can improve battery consumption on mobile."
msgstr ""
-#: doc/classes/OS.xml:500
+#: doc/classes/OS.xml:501
msgid ""
"The amount of sleeping between frames when the low-processor usage mode is "
"enabled (in microseconds). Higher values will result in lower CPU usage."
msgstr ""
-#: doc/classes/OS.xml:505
+#: doc/classes/OS.xml:506
msgid ""
"The GLES2 rendering backend. It uses OpenGL ES 2.0 on mobile devices, OpenGL "
"2.1 on desktop platforms and WebGL 1.0 on the web."
msgstr ""
-#: doc/classes/OS.xml:508
+#: doc/classes/OS.xml:509
msgid "The Vulkan rendering backend."
msgstr ""
-#: doc/classes/OS.xml:511
+#: doc/classes/OS.xml:512
msgid "Sunday."
msgstr ""
-#: doc/classes/OS.xml:514
+#: doc/classes/OS.xml:515
msgid "Monday."
msgstr ""
-#: doc/classes/OS.xml:517
+#: doc/classes/OS.xml:518
msgid "Tuesday."
msgstr ""
-#: doc/classes/OS.xml:520
+#: doc/classes/OS.xml:521
msgid "Wednesday."
msgstr ""
-#: doc/classes/OS.xml:523
+#: doc/classes/OS.xml:524
msgid "Thursday."
msgstr ""
-#: doc/classes/OS.xml:526
+#: doc/classes/OS.xml:527
msgid "Friday."
msgstr ""
-#: doc/classes/OS.xml:529
+#: doc/classes/OS.xml:530
msgid "Saturday."
msgstr ""
-#: doc/classes/OS.xml:532
+#: doc/classes/OS.xml:533
msgid "January."
msgstr ""
-#: doc/classes/OS.xml:535
+#: doc/classes/OS.xml:536
msgid "February."
msgstr ""
-#: doc/classes/OS.xml:538
+#: doc/classes/OS.xml:539
msgid "March."
msgstr ""
-#: doc/classes/OS.xml:541
+#: doc/classes/OS.xml:542
msgid "April."
msgstr ""
-#: doc/classes/OS.xml:544
+#: doc/classes/OS.xml:545
msgid "May."
msgstr ""
-#: doc/classes/OS.xml:547
+#: doc/classes/OS.xml:548
msgid "June."
msgstr ""
-#: doc/classes/OS.xml:550
+#: doc/classes/OS.xml:551
msgid "July."
msgstr ""
-#: doc/classes/OS.xml:553
+#: doc/classes/OS.xml:554
msgid "August."
msgstr ""
-#: doc/classes/OS.xml:556
+#: doc/classes/OS.xml:557
msgid "September."
msgstr ""
-#: doc/classes/OS.xml:559
+#: doc/classes/OS.xml:560
msgid "October."
msgstr ""
-#: doc/classes/OS.xml:562
+#: doc/classes/OS.xml:563
msgid "November."
msgstr ""
-#: doc/classes/OS.xml:565
+#: doc/classes/OS.xml:566
msgid "December."
msgstr ""
-#: doc/classes/OS.xml:568
+#: doc/classes/OS.xml:569
msgid "Desktop directory path."
msgstr ""
-#: doc/classes/OS.xml:571
+#: doc/classes/OS.xml:572
msgid "DCIM (Digital Camera Images) directory path."
msgstr ""
-#: doc/classes/OS.xml:574
+#: doc/classes/OS.xml:575
msgid "Documents directory path."
msgstr ""
-#: doc/classes/OS.xml:577
+#: doc/classes/OS.xml:578
msgid "Downloads directory path."
msgstr ""
-#: doc/classes/OS.xml:580
+#: doc/classes/OS.xml:581
msgid "Movies directory path."
msgstr ""
-#: doc/classes/OS.xml:583
+#: doc/classes/OS.xml:584
msgid "Music directory path."
msgstr ""
-#: doc/classes/OS.xml:586
+#: doc/classes/OS.xml:587
msgid "Pictures directory path."
msgstr ""
-#: doc/classes/OS.xml:589
+#: doc/classes/OS.xml:590
msgid "Ringtones directory path."
msgstr ""
@@ -33727,49 +33626,52 @@ msgid ""
"code] is owned by [code]node[/code] and [code]pack[/code] will therefore "
"only save those two nodes, but not [code]collision[/code].\n"
"[codeblock]\n"
-"# Create the objects\n"
+"# Create the objects.\n"
"var node = Node2D.new()\n"
"var rigid = RigidBody2D.new()\n"
"var collision = CollisionShape2D.new()\n"
"\n"
-"# Create the object hierarchy\n"
+"# Create the object hierarchy.\n"
"rigid.add_child(collision)\n"
"node.add_child(rigid)\n"
"\n"
-"# Change owner of rigid, but not of collision\n"
+"# Change owner of `rigid`, but not of `collision`.\n"
"rigid.owner = node\n"
"\n"
"var scene = PackedScene.new()\n"
-"# Only node and rigid are now packed\n"
+"# Only `node` and `rigid` are now packed.\n"
"var result = scene.pack(node)\n"
"if result == OK:\n"
-" ResourceSaver.save(\"res://path/name.scn\", scene) # Or \"user://...\"\n"
+" var error = ResourceSaver.save(\"res://path/name.scn\", scene) # Or "
+"\"user://...\"\n"
+" if error != OK:\n"
+" push_error(\"An error occurred while saving the scene to disk.\")\n"
"[/codeblock]"
msgstr ""
-#: doc/classes/PackedScene.xml:38
+#: doc/classes/PackedScene.xml:40
msgid "Returns [code]true[/code] if the scene file has nodes."
msgstr ""
-#: doc/classes/PackedScene.xml:45
+#: doc/classes/PackedScene.xml:47
msgid ""
"Returns the [code]SceneState[/code] representing the scene file contents."
msgstr ""
-#: doc/classes/PackedScene.xml:54
+#: doc/classes/PackedScene.xml:56
msgid ""
"Instantiates the scene's node hierarchy. Triggers child scene "
"instantiation(s). Triggers a [constant Node.NOTIFICATION_INSTANCED] "
"notification on the root node."
msgstr ""
-#: doc/classes/PackedScene.xml:63
+#: doc/classes/PackedScene.xml:65
msgid ""
"Pack will ignore any sub-nodes not owned by given node. See [member Node."
"owner]."
msgstr ""
-#: doc/classes/PackedScene.xml:69
+#: doc/classes/PackedScene.xml:71
msgid ""
"A dictionary representation of the scene contents.\n"
"Available keys include \"rnames\" and \"variants\" for resources, "
@@ -33778,18 +33680,18 @@ msgid ""
"connections, and \"version\" for the format style of the PackedScene."
msgstr ""
-#: doc/classes/PackedScene.xml:75
+#: doc/classes/PackedScene.xml:77
msgid "If passed to [method instance], blocks edits to the scene state."
msgstr ""
-#: doc/classes/PackedScene.xml:78
+#: doc/classes/PackedScene.xml:80
msgid ""
"If passed to [method instance], provides local scene resources to the local "
"scene.\n"
"[b]Note:[/b] Only available in editor builds."
msgstr ""
-#: doc/classes/PackedScene.xml:82
+#: doc/classes/PackedScene.xml:84
msgid ""
"If passed to [method instance], provides local scene resources to the local "
"scene. Only the main scene should receive the main edit state.\n"
@@ -34857,20 +34759,20 @@ msgstr ""
msgid "Draw calls per frame. 3D only."
msgstr ""
-#: doc/classes/Performance.xml:77 doc/classes/RenderingServer.xml:3711
+#: doc/classes/Performance.xml:77 doc/classes/RenderingServer.xml:3922
msgid ""
"The amount of video memory used, i.e. texture and vertex memory combined."
msgstr ""
-#: doc/classes/Performance.xml:80 doc/classes/RenderingServer.xml:3714
+#: doc/classes/Performance.xml:80 doc/classes/RenderingServer.xml:3925
msgid "The amount of texture memory used."
msgstr ""
-#: doc/classes/Performance.xml:83 doc/classes/RenderingServer.xml:3717
+#: doc/classes/Performance.xml:83 doc/classes/RenderingServer.xml:3928
msgid "The amount of vertex memory used."
msgstr ""
-#: doc/classes/Performance.xml:86 doc/classes/RenderingServer.xml:3708
+#: doc/classes/Performance.xml:86 doc/classes/RenderingServer.xml:3919
msgid "Unimplemented in the GLES2 rendering backend, always returns 0."
msgstr ""
@@ -34922,6 +34824,96 @@ msgid ""
"resource."
msgstr ""
+#: doc/classes/PhysicalBone3D.xml:67
+msgid "Damps the body's rotation if greater than [code]0[/code]."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:70 doc/classes/RigidBody3D.xml:132
+msgid "Lock the body's rotation in the X axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:73 doc/classes/RigidBody3D.xml:135
+msgid "Lock the body's rotation in the Y axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:76 doc/classes/RigidBody3D.xml:138
+msgid "Lock the body's rotation in the Z axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:79 doc/classes/RigidBody3D.xml:141
+msgid "Lock the body's movement in the X axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:82 doc/classes/RigidBody3D.xml:144
+msgid "Lock the body's movement in the Y axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:85 doc/classes/RigidBody3D.xml:147
+msgid "Lock the body's movement in the Z axis."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:88
+msgid "Sets the body's transform."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:91 doc/classes/PhysicsMaterial.xml:17
+msgid ""
+"The body's bounciness. Values range from [code]0[/code] (no bounce) to "
+"[code]1[/code] (full bounciness)."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:94 doc/classes/RigidBody3D.xml:150
+msgid ""
+"If [code]true[/code], the body is deactivated when there is no movement, so "
+"it will not take part in the simulation until it is awaken by an external "
+"force."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:97
+msgid ""
+"The body's friction, from [code]0[/code] (frictionless) to [code]1[/code] "
+"(max friction)."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:100
+msgid ""
+"This is multiplied by the global 3D gravity setting found in [b]Project > "
+"Project Settings > Physics > 3d[/b] to produce the body's gravity. For "
+"example, a value of 1 will be normal gravity, 2 will apply double gravity, "
+"and 0.5 will apply half gravity to this object."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:103
+msgid "Sets the joint's transform."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:106
+msgid "Sets the joint's rotation in radians."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:109
+msgid "Sets the joint's rotation in degrees."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:112
+msgid "Sets the joint type. See [enum JointType] for possible values."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:115
+msgid "Damps the body's movement if greater than [code]0[/code]."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:118 doc/classes/RigidBody2D.xml:158
+#: doc/classes/RigidBody3D.xml:175
+msgid "The body's mass."
+msgstr ""
+
+#: doc/classes/PhysicalBone3D.xml:121 doc/classes/RigidBody3D.xml:188
+msgid ""
+"The body's weight based on its mass and the global 3D gravity. Global values "
+"are set in [b]Project > Project Settings > Physics > 3d[/b]."
+msgstr ""
+
#: doc/classes/PhysicalSkyMaterial.xml:4
msgid "[Sky] [Material] used for a physically based sky."
msgstr ""
@@ -35255,17 +35247,6 @@ msgstr ""
msgid "The body's transformation matrix."
msgstr ""
-#: doc/classes/PhysicsDirectBodyState2DSW.xml:4
-msgid "Software implementation of [PhysicsDirectBodyState2D]."
-msgstr ""
-
-#: doc/classes/PhysicsDirectBodyState2DSW.xml:7
-msgid ""
-"Software implementation of [PhysicsDirectBodyState2D]. This object exposes "
-"no new methods or properties and should not be used, as "
-"[PhysicsDirectBodyState2D] selects the best implementation available."
-msgstr ""
-
#: doc/classes/PhysicsDirectBodyState3D.xml:4
msgid "Direct access object to a physics body in the [PhysicsServer3D]."
msgstr ""
@@ -35278,7 +35259,7 @@ msgid ""
"direct state of that body. See [method RigidBody3D._integrate_forces]."
msgstr ""
-#: doc/classes/PhysicsDirectBodyState3D.xml:18 doc/classes/RigidBody3D.xml:31
+#: doc/classes/PhysicsDirectBodyState3D.xml:18
msgid ""
"Adds a constant directional force without affecting rotation.\n"
"This is equivalent to [code]add_force(force, Vector3(0,0,0))[/code]."
@@ -35455,7 +35436,7 @@ msgid ""
"will occur. If no collision is detected, the returned array will be [code]"
"[1, 1][/code].\n"
"If the shape can not move, the returned array will be [code][0, 0][/code] "
-"under Bullet, and empty under GodotPhysics."
+"under Bullet, and empty under GodotPhysics3D."
msgstr ""
#: doc/classes/PhysicsDirectSpaceState3D.xml:33
@@ -35526,12 +35507,6 @@ msgid ""
"Provides a means of modifying the collision properties of a [PhysicsBody3D]."
msgstr ""
-#: doc/classes/PhysicsMaterial.xml:17
-msgid ""
-"The body's bounciness. Values range from [code]0[/code] (no bounce) to "
-"[code]1[/code] (full bounciness)."
-msgstr ""
-
#: doc/classes/PhysicsMaterial.xml:20
msgid ""
"The body's friction. Values range from [code]0[/code] (frictionless) to "
@@ -35772,7 +35747,7 @@ msgid ""
msgstr ""
#: doc/classes/PhysicsServer2D.xml:620 doc/classes/PhysicsServer3D.xml:637
-#: doc/classes/RigidBody3D.xml:119
+#: doc/classes/RigidBody3D.xml:120
msgid ""
"Sets an axis velocity. The velocity in the given vector axis will be set as "
"the given vector length. This is useful for jumping behavior."
@@ -36288,16 +36263,6 @@ msgid ""
"Constant to get the number of space regions where a collision could occur."
msgstr ""
-#: doc/classes/PhysicsServer2DSW.xml:4
-msgid "Software implementation of [PhysicsServer2D]."
-msgstr ""
-
-#: doc/classes/PhysicsServer2DSW.xml:7
-msgid ""
-"This class exposes no new methods or properties and should not be used, as "
-"[PhysicsServer2D] automatically selects the best implementation available."
-msgstr ""
-
#: doc/classes/PhysicsServer3D.xml:4
msgid "Server interface for low-level physics access."
msgstr ""
@@ -37959,12 +37924,8 @@ msgid "Distance from center of sun where it fades out completely."
msgstr ""
#: doc/classes/ProceduralSkyMaterial.xml:44
-msgid "Distance from sun where it goes from solid to starting to fade."
-msgstr ""
-
-#: doc/classes/ProceduralSkyMaterial.xml:47
msgid ""
-"How quickly the sun fades away between [member sun_angle_min] and [member "
+"How quickly the sun fades away between the edge of the sun disk and [member "
"sun_angle_max]."
msgstr ""
@@ -38299,28 +38260,42 @@ msgstr ""
#: doc/classes/ProjectSettings.xml:263
msgid ""
-"Default compression level for gzip. Affects compressed scenes and resources."
+"The default compression level for gzip. Affects compressed scenes and "
+"resources. Higher levels result in smaller files at the cost of compression "
+"speed. Decompression speed is mostly unaffected by the compression level. "
+"[code]-1[/code] uses the default gzip compression level, which is identical "
+"to [code]6[/code] but could change in the future due to underlying zlib "
+"updates."
msgstr ""
#: doc/classes/ProjectSettings.xml:266
msgid ""
-"Default compression level for Zlib. Affects compressed scenes and resources."
+"The default compression level for Zlib. Affects compressed scenes and "
+"resources. Higher levels result in smaller files at the cost of compression "
+"speed. Decompression speed is mostly unaffected by the compression level. "
+"[code]-1[/code] uses the default gzip compression level, which is identical "
+"to [code]6[/code] but could change in the future due to underlying zlib "
+"updates."
msgstr ""
#: doc/classes/ProjectSettings.xml:269
msgid ""
-"Default compression level for Zstandard. Affects compressed scenes and "
-"resources."
+"The default compression level for Zstandard. Affects compressed scenes and "
+"resources. Higher levels result in smaller files at the cost of compression "
+"speed. Decompression speed is mostly unaffected by the compression level."
msgstr ""
#: doc/classes/ProjectSettings.xml:272
-msgid "Enables long-distance matching in Zstandard."
+msgid ""
+"Enables [url=https://github.com/facebook/zstd/releases/tag/v1.3.2]long-"
+"distance matching[/url] in Zstandard."
msgstr ""
#: doc/classes/ProjectSettings.xml:275
msgid ""
"Largest size limit (in power of 2) allowed when compressing using long-"
-"distance matching with Zstandard."
+"distance matching with Zstandard. Higher values can result in better "
+"compression, but will require more memory when compressing and decompressing."
msgstr ""
#: doc/classes/ProjectSettings.xml:278
@@ -38701,37 +38676,37 @@ msgid ""
"UWP to follow interface conventions."
msgstr ""
-#: doc/classes/ProjectSettings.xml:473
+#: doc/classes/ProjectSettings.xml:475
msgid ""
"Path to a custom [Theme] resource file to use for the project ([code]theme[/"
"code] or generic [code]tres[/code]/[code]res[/code] extension)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:476
+#: doc/classes/ProjectSettings.xml:478
msgid ""
"Path to a custom [Font] resource to use as default for all GUI elements of "
"the project."
msgstr ""
-#: doc/classes/ProjectSettings.xml:479
+#: doc/classes/ProjectSettings.xml:481
msgid "If [code]true[/code], makes sure the theme used works with HiDPI."
msgstr ""
-#: doc/classes/ProjectSettings.xml:482
+#: doc/classes/ProjectSettings.xml:484
msgid ""
"Timer setting for incremental search in [Tree], [ItemList], etc. controls "
"(in milliseconds)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:485
+#: doc/classes/ProjectSettings.xml:487
msgid "Timer for detecting idle in [TextEdit] (in seconds)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:488
+#: doc/classes/ProjectSettings.xml:490
msgid "Default delay for tooltips (in seconds)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:491
+#: doc/classes/ProjectSettings.xml:493
msgid ""
"Default [InputEventAction] to confirm a focused button, menu or list item, "
"or validate input.\n"
@@ -38740,7 +38715,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:495
+#: doc/classes/ProjectSettings.xml:497
msgid ""
"Default [InputEventAction] to discard a modal or pending input.\n"
"[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are "
@@ -38748,7 +38723,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:499
+#: doc/classes/ProjectSettings.xml:501
msgid ""
"Default [InputEventAction] to move down in the UI.\n"
"[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are "
@@ -38756,7 +38731,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:503
+#: doc/classes/ProjectSettings.xml:505
msgid ""
"Default [InputEventAction] to go to the end position of a [Control] (e.g. "
"last item in an [ItemList] or a [Tree]), matching the behavior of [constant "
@@ -38766,7 +38741,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:507
+#: doc/classes/ProjectSettings.xml:509
msgid ""
"Default [InputEventAction] to focus the next [Control] in the scene. The "
"focus behavior can be configured via [member Control.focus_next].\n"
@@ -38775,7 +38750,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:511
+#: doc/classes/ProjectSettings.xml:513
msgid ""
"Default [InputEventAction] to focus the previous [Control] in the scene. The "
"focus behavior can be configured via [member Control.focus_previous].\n"
@@ -38784,7 +38759,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:515
+#: doc/classes/ProjectSettings.xml:517
msgid ""
"Default [InputEventAction] to go to the start position of a [Control] (e.g. "
"first item in an [ItemList] or a [Tree]), matching the behavior of [constant "
@@ -38794,7 +38769,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:519
+#: doc/classes/ProjectSettings.xml:521
msgid ""
"Default [InputEventAction] to move left in the UI.\n"
"[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are "
@@ -38802,7 +38777,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:523
+#: doc/classes/ProjectSettings.xml:525
msgid ""
"Default [InputEventAction] to go down a page in a [Control] (e.g. in an "
"[ItemList] or a [Tree]), matching the behavior of [constant KEY_PAGEDOWN] on "
@@ -38812,7 +38787,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:527
+#: doc/classes/ProjectSettings.xml:529
msgid ""
"Default [InputEventAction] to go up a page in a [Control] (e.g. in an "
"[ItemList] or a [Tree]), matching the behavior of [constant KEY_PAGEUP] on "
@@ -38822,7 +38797,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:531
+#: doc/classes/ProjectSettings.xml:533
msgid ""
"Default [InputEventAction] to move right in the UI.\n"
"[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are "
@@ -38830,7 +38805,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:535
+#: doc/classes/ProjectSettings.xml:537
msgid ""
"Default [InputEventAction] to select an item in a [Control] (e.g. in an "
"[ItemList] or a [Tree]).\n"
@@ -38839,7 +38814,7 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:539
+#: doc/classes/ProjectSettings.xml:541
msgid ""
"Default [InputEventAction] to move up in the UI.\n"
"[b]Note:[/b] Default [code]ui_*[/code] actions cannot be removed as they are "
@@ -38847,371 +38822,371 @@ msgid ""
"to the action can however be modified."
msgstr ""
-#: doc/classes/ProjectSettings.xml:543
+#: doc/classes/ProjectSettings.xml:545
msgid ""
"If [code]true[/code], sends mouse input events when tapping or swiping on "
"the touchscreen."
msgstr ""
-#: doc/classes/ProjectSettings.xml:546
+#: doc/classes/ProjectSettings.xml:548
msgid ""
"If [code]true[/code], sends touch input events when clicking or dragging the "
"mouse."
msgstr ""
-#: doc/classes/ProjectSettings.xml:549
+#: doc/classes/ProjectSettings.xml:551
msgid "Optional name for the 2D physics layer 1."
msgstr ""
-#: doc/classes/ProjectSettings.xml:552
+#: doc/classes/ProjectSettings.xml:554
msgid "Optional name for the 2D physics layer 10."
msgstr ""
-#: doc/classes/ProjectSettings.xml:555
+#: doc/classes/ProjectSettings.xml:557
msgid "Optional name for the 2D physics layer 11."
msgstr ""
-#: doc/classes/ProjectSettings.xml:558
+#: doc/classes/ProjectSettings.xml:560
msgid "Optional name for the 2D physics layer 12."
msgstr ""
-#: doc/classes/ProjectSettings.xml:561
+#: doc/classes/ProjectSettings.xml:563
msgid "Optional name for the 2D physics layer 13."
msgstr ""
-#: doc/classes/ProjectSettings.xml:564
+#: doc/classes/ProjectSettings.xml:566
msgid "Optional name for the 2D physics layer 14."
msgstr ""
-#: doc/classes/ProjectSettings.xml:567
+#: doc/classes/ProjectSettings.xml:569
msgid "Optional name for the 2D physics layer 15."
msgstr ""
-#: doc/classes/ProjectSettings.xml:570
+#: doc/classes/ProjectSettings.xml:572
msgid "Optional name for the 2D physics layer 16."
msgstr ""
-#: doc/classes/ProjectSettings.xml:573
+#: doc/classes/ProjectSettings.xml:575
msgid "Optional name for the 2D physics layer 17."
msgstr ""
-#: doc/classes/ProjectSettings.xml:576
+#: doc/classes/ProjectSettings.xml:578
msgid "Optional name for the 2D physics layer 18."
msgstr ""
-#: doc/classes/ProjectSettings.xml:579
+#: doc/classes/ProjectSettings.xml:581
msgid "Optional name for the 2D physics layer 19."
msgstr ""
-#: doc/classes/ProjectSettings.xml:582
+#: doc/classes/ProjectSettings.xml:584
msgid "Optional name for the 2D physics layer 2."
msgstr ""
-#: doc/classes/ProjectSettings.xml:585
+#: doc/classes/ProjectSettings.xml:587
msgid "Optional name for the 2D physics layer 20."
msgstr ""
-#: doc/classes/ProjectSettings.xml:588
+#: doc/classes/ProjectSettings.xml:590
msgid "Optional name for the 2D physics layer 3."
msgstr ""
-#: doc/classes/ProjectSettings.xml:591
+#: doc/classes/ProjectSettings.xml:593
msgid "Optional name for the 2D physics layer 4."
msgstr ""
-#: doc/classes/ProjectSettings.xml:594
+#: doc/classes/ProjectSettings.xml:596
msgid "Optional name for the 2D physics layer 5."
msgstr ""
-#: doc/classes/ProjectSettings.xml:597
+#: doc/classes/ProjectSettings.xml:599
msgid "Optional name for the 2D physics layer 6."
msgstr ""
-#: doc/classes/ProjectSettings.xml:600
+#: doc/classes/ProjectSettings.xml:602
msgid "Optional name for the 2D physics layer 7."
msgstr ""
-#: doc/classes/ProjectSettings.xml:603
+#: doc/classes/ProjectSettings.xml:605
msgid "Optional name for the 2D physics layer 8."
msgstr ""
-#: doc/classes/ProjectSettings.xml:606
+#: doc/classes/ProjectSettings.xml:608
msgid "Optional name for the 2D physics layer 9."
msgstr ""
-#: doc/classes/ProjectSettings.xml:609
+#: doc/classes/ProjectSettings.xml:611
msgid "Optional name for the 2D render layer 1."
msgstr ""
-#: doc/classes/ProjectSettings.xml:612
+#: doc/classes/ProjectSettings.xml:614
msgid "Optional name for the 2D render layer 10."
msgstr ""
-#: doc/classes/ProjectSettings.xml:615
+#: doc/classes/ProjectSettings.xml:617
msgid "Optional name for the 2D render layer 11."
msgstr ""
-#: doc/classes/ProjectSettings.xml:618
+#: doc/classes/ProjectSettings.xml:620
msgid "Optional name for the 2D render layer 12."
msgstr ""
-#: doc/classes/ProjectSettings.xml:621
+#: doc/classes/ProjectSettings.xml:623
msgid "Optional name for the 2D render layer 13."
msgstr ""
-#: doc/classes/ProjectSettings.xml:624
+#: doc/classes/ProjectSettings.xml:626
msgid "Optional name for the 2D render layer 14."
msgstr ""
-#: doc/classes/ProjectSettings.xml:627
+#: doc/classes/ProjectSettings.xml:629
msgid "Optional name for the 2D render layer 15."
msgstr ""
-#: doc/classes/ProjectSettings.xml:630
+#: doc/classes/ProjectSettings.xml:632
msgid "Optional name for the 2D render layer 16."
msgstr ""
-#: doc/classes/ProjectSettings.xml:633
+#: doc/classes/ProjectSettings.xml:635
msgid "Optional name for the 2D render layer 17."
msgstr ""
-#: doc/classes/ProjectSettings.xml:636
+#: doc/classes/ProjectSettings.xml:638
msgid "Optional name for the 2D render layer 18."
msgstr ""
-#: doc/classes/ProjectSettings.xml:639
+#: doc/classes/ProjectSettings.xml:641
msgid "Optional name for the 2D render layer 19."
msgstr ""
-#: doc/classes/ProjectSettings.xml:642
+#: doc/classes/ProjectSettings.xml:644
msgid "Optional name for the 2D render layer 2."
msgstr ""
-#: doc/classes/ProjectSettings.xml:645
+#: doc/classes/ProjectSettings.xml:647
msgid "Optional name for the 2D render layer 20."
msgstr ""
-#: doc/classes/ProjectSettings.xml:648
+#: doc/classes/ProjectSettings.xml:650
msgid "Optional name for the 2D render layer 3."
msgstr ""
-#: doc/classes/ProjectSettings.xml:651
+#: doc/classes/ProjectSettings.xml:653
msgid "Optional name for the 2D render layer 4."
msgstr ""
-#: doc/classes/ProjectSettings.xml:654
+#: doc/classes/ProjectSettings.xml:656
msgid "Optional name for the 2D render layer 5."
msgstr ""
-#: doc/classes/ProjectSettings.xml:657
+#: doc/classes/ProjectSettings.xml:659
msgid "Optional name for the 2D render layer 6."
msgstr ""
-#: doc/classes/ProjectSettings.xml:660
+#: doc/classes/ProjectSettings.xml:662
msgid "Optional name for the 2D render layer 7."
msgstr ""
-#: doc/classes/ProjectSettings.xml:663
+#: doc/classes/ProjectSettings.xml:665
msgid "Optional name for the 2D render layer 8."
msgstr ""
-#: doc/classes/ProjectSettings.xml:666
+#: doc/classes/ProjectSettings.xml:668
msgid "Optional name for the 2D render layer 9."
msgstr ""
-#: doc/classes/ProjectSettings.xml:669
+#: doc/classes/ProjectSettings.xml:671
msgid "Optional name for the 3D physics layer 1."
msgstr ""
-#: doc/classes/ProjectSettings.xml:672
+#: doc/classes/ProjectSettings.xml:674
msgid "Optional name for the 3D physics layer 10."
msgstr ""
-#: doc/classes/ProjectSettings.xml:675
+#: doc/classes/ProjectSettings.xml:677
msgid "Optional name for the 3D physics layer 11."
msgstr ""
-#: doc/classes/ProjectSettings.xml:678
+#: doc/classes/ProjectSettings.xml:680
msgid "Optional name for the 3D physics layer 12."
msgstr ""
-#: doc/classes/ProjectSettings.xml:681
+#: doc/classes/ProjectSettings.xml:683
msgid "Optional name for the 3D physics layer 13."
msgstr ""
-#: doc/classes/ProjectSettings.xml:684
+#: doc/classes/ProjectSettings.xml:686
msgid "Optional name for the 3D physics layer 14."
msgstr ""
-#: doc/classes/ProjectSettings.xml:687
+#: doc/classes/ProjectSettings.xml:689
msgid "Optional name for the 3D physics layer 15."
msgstr ""
-#: doc/classes/ProjectSettings.xml:690
+#: doc/classes/ProjectSettings.xml:692
msgid "Optional name for the 3D physics layer 16."
msgstr ""
-#: doc/classes/ProjectSettings.xml:693
+#: doc/classes/ProjectSettings.xml:695
msgid "Optional name for the 3D physics layer 17."
msgstr ""
-#: doc/classes/ProjectSettings.xml:696
+#: doc/classes/ProjectSettings.xml:698
msgid "Optional name for the 3D physics layer 18."
msgstr ""
-#: doc/classes/ProjectSettings.xml:699
+#: doc/classes/ProjectSettings.xml:701
msgid "Optional name for the 3D physics layer 19."
msgstr ""
-#: doc/classes/ProjectSettings.xml:702
+#: doc/classes/ProjectSettings.xml:704
msgid "Optional name for the 3D physics layer 2."
msgstr ""
-#: doc/classes/ProjectSettings.xml:705
+#: doc/classes/ProjectSettings.xml:707
msgid "Optional name for the 3D physics layer 20."
msgstr ""
-#: doc/classes/ProjectSettings.xml:708
+#: doc/classes/ProjectSettings.xml:710
msgid "Optional name for the 3D physics layer 3."
msgstr ""
-#: doc/classes/ProjectSettings.xml:711
+#: doc/classes/ProjectSettings.xml:713
msgid "Optional name for the 3D physics layer 4."
msgstr ""
-#: doc/classes/ProjectSettings.xml:714
+#: doc/classes/ProjectSettings.xml:716
msgid "Optional name for the 3D physics layer 5."
msgstr ""
-#: doc/classes/ProjectSettings.xml:717
+#: doc/classes/ProjectSettings.xml:719
msgid "Optional name for the 3D physics layer 6."
msgstr ""
-#: doc/classes/ProjectSettings.xml:720
+#: doc/classes/ProjectSettings.xml:722
msgid "Optional name for the 3D physics layer 7."
msgstr ""
-#: doc/classes/ProjectSettings.xml:723
+#: doc/classes/ProjectSettings.xml:725
msgid "Optional name for the 3D physics layer 8."
msgstr ""
-#: doc/classes/ProjectSettings.xml:726
+#: doc/classes/ProjectSettings.xml:728
msgid "Optional name for the 3D physics layer 9."
msgstr ""
-#: doc/classes/ProjectSettings.xml:729
+#: doc/classes/ProjectSettings.xml:731
msgid "Optional name for the 3D render layer 1."
msgstr ""
-#: doc/classes/ProjectSettings.xml:732
+#: doc/classes/ProjectSettings.xml:734
msgid "Optional name for the 3D render layer 10."
msgstr ""
-#: doc/classes/ProjectSettings.xml:735
+#: doc/classes/ProjectSettings.xml:737
msgid "Optional name for the 3D render layer 11."
msgstr ""
-#: doc/classes/ProjectSettings.xml:738
+#: doc/classes/ProjectSettings.xml:740
msgid "Optional name for the 3D render layer 12."
msgstr ""
-#: doc/classes/ProjectSettings.xml:741
+#: doc/classes/ProjectSettings.xml:743
msgid "Optional name for the 3D render layer 13."
msgstr ""
-#: doc/classes/ProjectSettings.xml:744
+#: doc/classes/ProjectSettings.xml:746
msgid "Optional name for the 3D render layer 14"
msgstr ""
-#: doc/classes/ProjectSettings.xml:747
+#: doc/classes/ProjectSettings.xml:749
msgid "Optional name for the 3D render layer 15."
msgstr ""
-#: doc/classes/ProjectSettings.xml:750
+#: doc/classes/ProjectSettings.xml:752
msgid "Optional name for the 3D render layer 16."
msgstr ""
-#: doc/classes/ProjectSettings.xml:753
+#: doc/classes/ProjectSettings.xml:755
msgid "Optional name for the 3D render layer 17."
msgstr ""
-#: doc/classes/ProjectSettings.xml:756
+#: doc/classes/ProjectSettings.xml:758
msgid "Optional name for the 3D render layer 18."
msgstr ""
-#: doc/classes/ProjectSettings.xml:759
+#: doc/classes/ProjectSettings.xml:761
msgid "Optional name for the 3D render layer 19."
msgstr ""
-#: doc/classes/ProjectSettings.xml:762
+#: doc/classes/ProjectSettings.xml:764
msgid "Optional name for the 3D render layer 2."
msgstr ""
-#: doc/classes/ProjectSettings.xml:765
+#: doc/classes/ProjectSettings.xml:767
msgid "Optional name for the 3D render layer 20."
msgstr ""
-#: doc/classes/ProjectSettings.xml:768
+#: doc/classes/ProjectSettings.xml:770
msgid "Optional name for the 3D render layer 3."
msgstr ""
-#: doc/classes/ProjectSettings.xml:771
+#: doc/classes/ProjectSettings.xml:773
msgid "Optional name for the 3D render layer 4."
msgstr ""
-#: doc/classes/ProjectSettings.xml:774
+#: doc/classes/ProjectSettings.xml:776
msgid "Optional name for the 3D render layer 5."
msgstr ""
-#: doc/classes/ProjectSettings.xml:777
+#: doc/classes/ProjectSettings.xml:779
msgid "Optional name for the 3D render layer 6."
msgstr ""
-#: doc/classes/ProjectSettings.xml:780
+#: doc/classes/ProjectSettings.xml:782
msgid "Optional name for the 3D render layer 7."
msgstr ""
-#: doc/classes/ProjectSettings.xml:783
+#: doc/classes/ProjectSettings.xml:785
msgid "Optional name for the 3D render layer 8."
msgstr ""
-#: doc/classes/ProjectSettings.xml:786
+#: doc/classes/ProjectSettings.xml:788
msgid "Optional name for the 3D render layer 9."
msgstr ""
-#: doc/classes/ProjectSettings.xml:789
+#: doc/classes/ProjectSettings.xml:791
msgid ""
"The locale to fall back to if a translation isn't available in a given "
"language. If left empty, [code]en[/code] (English) will be used."
msgstr ""
-#: doc/classes/ProjectSettings.xml:792
+#: doc/classes/ProjectSettings.xml:794
msgid ""
"If non-empty, this locale will be used when running the project from the "
"editor."
msgstr ""
-#: doc/classes/ProjectSettings.xml:795
+#: doc/classes/ProjectSettings.xml:797
msgid "If [code]true[/code], logs all output to files."
msgstr ""
-#: doc/classes/ProjectSettings.xml:798
+#: doc/classes/ProjectSettings.xml:800
msgid ""
"Path to logs within the project. Using an [code]user://[/code] path is "
"recommended."
msgstr ""
-#: doc/classes/ProjectSettings.xml:801
+#: doc/classes/ProjectSettings.xml:803
msgid "Specifies the maximum amount of log files allowed (used for rotation)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:804
+#: doc/classes/ProjectSettings.xml:806
msgid ""
"Godot uses a message queue to defer some function calls. If you run out of "
"space on it (you will see an error), you can increase the size here."
msgstr ""
-#: doc/classes/ProjectSettings.xml:807
+#: doc/classes/ProjectSettings.xml:809
msgid ""
"This is used by servers when used in multi-threading mode (servers and "
"visual). RIDs are preallocated to avoid stalling the server requesting them "
@@ -39219,118 +39194,118 @@ msgid ""
"thread, increase this number."
msgstr ""
-#: doc/classes/ProjectSettings.xml:822
+#: doc/classes/ProjectSettings.xml:824
msgid ""
"Maximum amount of characters allowed to send as output from the debugger. "
"Over this value, content is dropped. This helps not to stall the debugger "
"connection."
msgstr ""
-#: doc/classes/ProjectSettings.xml:825
+#: doc/classes/ProjectSettings.xml:827
msgid ""
"Maximum number of errors allowed to be sent from the debugger. Over this "
"value, content is dropped. This helps not to stall the debugger connection."
msgstr ""
-#: doc/classes/ProjectSettings.xml:828
+#: doc/classes/ProjectSettings.xml:830
msgid ""
"Maximum amount of messages in the debugger queue. Over this value, content "
"is dropped. This helps to limit the debugger memory usage."
msgstr ""
-#: doc/classes/ProjectSettings.xml:831
+#: doc/classes/ProjectSettings.xml:833
msgid ""
"Maximum number of warnings allowed to be sent from the debugger. Over this "
"value, content is dropped. This helps not to stall the debugger connection."
msgstr ""
-#: doc/classes/ProjectSettings.xml:834
+#: doc/classes/ProjectSettings.xml:836
msgid ""
"Default size of packet peer stream for deserializing Godot data. Over this "
"size, data is dropped."
msgstr ""
-#: doc/classes/ProjectSettings.xml:837
+#: doc/classes/ProjectSettings.xml:839
msgid "Timeout (in seconds) for connection attempts using TCP."
msgstr ""
-#: doc/classes/ProjectSettings.xml:840
+#: doc/classes/ProjectSettings.xml:842
msgid "Maximum size (in kiB) for the [WebRTCDataChannel] input buffer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:843
+#: doc/classes/ProjectSettings.xml:845
msgid "Maximum size (in kiB) for the [WebSocketClient] input buffer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:846
+#: doc/classes/ProjectSettings.xml:848
msgid "Maximum number of concurrent input packets for [WebSocketClient]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:849
+#: doc/classes/ProjectSettings.xml:851
msgid "Maximum size (in kiB) for the [WebSocketClient] output buffer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:852
+#: doc/classes/ProjectSettings.xml:854
msgid "Maximum number of concurrent output packets for [WebSocketClient]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:855
+#: doc/classes/ProjectSettings.xml:857
msgid "Maximum size (in kiB) for the [WebSocketServer] input buffer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:858
+#: doc/classes/ProjectSettings.xml:860
msgid "Maximum number of concurrent input packets for [WebSocketServer]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:861
+#: doc/classes/ProjectSettings.xml:863
msgid "Maximum size (in kiB) for the [WebSocketServer] output buffer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:864
+#: doc/classes/ProjectSettings.xml:866
msgid "Maximum number of concurrent output packets for [WebSocketServer]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:867
+#: doc/classes/ProjectSettings.xml:869
msgid ""
"Amount of read ahead used by remote filesystem. Higher values decrease the "
"effects of latency at the cost of higher bandwidth usage."
msgstr ""
-#: doc/classes/ProjectSettings.xml:870
+#: doc/classes/ProjectSettings.xml:872
msgid "Page size used by remote filesystem (in bytes)."
msgstr ""
-#: doc/classes/ProjectSettings.xml:873
+#: doc/classes/ProjectSettings.xml:875
msgid ""
"CA certificates bundle to use for SSL connections. If not defined, Godot's "
"internal CA certificates are used."
msgstr ""
-#: doc/classes/ProjectSettings.xml:876
+#: doc/classes/ProjectSettings.xml:878
msgid ""
"When creating node names automatically, set the type of casing in this "
"project. This is mostly an editor setting."
msgstr ""
-#: doc/classes/ProjectSettings.xml:879
+#: doc/classes/ProjectSettings.xml:881
msgid ""
"What to use to separate node name from number. This is mostly an editor "
"setting."
msgstr ""
-#: doc/classes/ProjectSettings.xml:882
+#: doc/classes/ProjectSettings.xml:884
msgid "Size of the hash table used for the broad-phase 2D hash grid algorithm."
msgstr ""
-#: doc/classes/ProjectSettings.xml:885
+#: doc/classes/ProjectSettings.xml:887
msgid "Cell size used for the broad-phase 2D hash grid algorithm."
msgstr ""
-#: doc/classes/ProjectSettings.xml:888
+#: doc/classes/ProjectSettings.xml:890
msgid "The default angular damp in 2D."
msgstr ""
-#: doc/classes/ProjectSettings.xml:891
+#: doc/classes/ProjectSettings.xml:893
msgid ""
"The default gravity strength in 2D.\n"
"[b]Note:[/b] This property is only read when the project starts. To change "
@@ -39342,7 +39317,7 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/ProjectSettings.xml:899
+#: doc/classes/ProjectSettings.xml:901
msgid ""
"The default gravity direction in 2D.\n"
"[b]Note:[/b] This property is only read when the project starts. To change "
@@ -39354,38 +39329,38 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/ProjectSettings.xml:907
+#: doc/classes/ProjectSettings.xml:909
msgid "The default linear damp in 2D."
msgstr ""
-#: doc/classes/ProjectSettings.xml:910
+#: doc/classes/ProjectSettings.xml:912
msgid ""
"Threshold defining the surface size that constitutes a large object with "
"regard to cells in the broad-phase 2D hash grid algorithm."
msgstr ""
-#: doc/classes/ProjectSettings.xml:913
+#: doc/classes/ProjectSettings.xml:915
msgid ""
"Sets which physics engine to use for 2D physics.\n"
-"\"DEFAULT\" and \"GodotPhysics\" are the same, as there is currently no "
+"\"DEFAULT\" and \"GodotPhysics2D\" are the same, as there is currently no "
"alternative 2D physics server implemented."
msgstr ""
-#: doc/classes/ProjectSettings.xml:917
+#: doc/classes/ProjectSettings.xml:919
msgid ""
"Threshold angular velocity under which a 2D physics body will be considered "
"inactive. See [constant PhysicsServer2D."
"SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:920
+#: doc/classes/ProjectSettings.xml:922
msgid ""
"Threshold linear velocity under which a 2D physics body will be considered "
"inactive. See [constant PhysicsServer2D."
"SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:923
+#: doc/classes/ProjectSettings.xml:925
msgid ""
"Sets whether physics is run on the main thread or a separate one. Running "
"the server on a thread increases performance, but restricts API access to "
@@ -39395,23 +39370,23 @@ msgid ""
"give you extra performance and no regressions when using it."
msgstr ""
-#: doc/classes/ProjectSettings.xml:927
+#: doc/classes/ProjectSettings.xml:929
msgid ""
"Time (in seconds) of inactivity before which a 2D physics body will put to "
"sleep. See [constant PhysicsServer2D.SPACE_PARAM_BODY_TIME_TO_SLEEP]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:930
+#: doc/classes/ProjectSettings.xml:932
msgid ""
"Sets whether the 3D physics world will be created with support for "
"[SoftBody3D] physics. Only applies to the Bullet physics engine."
msgstr ""
-#: doc/classes/ProjectSettings.xml:933
+#: doc/classes/ProjectSettings.xml:935
msgid "The default angular damp in 3D."
msgstr ""
-#: doc/classes/ProjectSettings.xml:936
+#: doc/classes/ProjectSettings.xml:938
msgid ""
"The default gravity strength in 3D.\n"
"[b]Note:[/b] This property is only read when the project starts. To change "
@@ -39423,7 +39398,7 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/ProjectSettings.xml:944
+#: doc/classes/ProjectSettings.xml:946
msgid ""
"The default gravity direction in 3D.\n"
"[b]Note:[/b] This property is only read when the project starts. To change "
@@ -39435,23 +39410,23 @@ msgid ""
"[/codeblock]"
msgstr ""
-#: doc/classes/ProjectSettings.xml:952
+#: doc/classes/ProjectSettings.xml:954
msgid "The default linear damp in 3D."
msgstr ""
-#: doc/classes/ProjectSettings.xml:955
+#: doc/classes/ProjectSettings.xml:957
msgid ""
"Sets which physics engine to use for 3D physics.\n"
"\"DEFAULT\" is currently the [url=https://bulletphysics.org]Bullet[/url] "
-"physics engine. The \"GodotPhysics\" engine is still supported as an "
+"physics engine. The \"GodotPhysics3D\" engine is still supported as an "
"alternative."
msgstr ""
-#: doc/classes/ProjectSettings.xml:959
+#: doc/classes/ProjectSettings.xml:961
msgid "Enables [member Viewport.physics_object_picking] on the root viewport."
msgstr ""
-#: doc/classes/ProjectSettings.xml:962
+#: doc/classes/ProjectSettings.xml:964
msgid ""
"The number of fixed iterations per second. This controls how often physics "
"simulation and [method Node._physics_process] methods are run.\n"
@@ -39460,7 +39435,7 @@ msgid ""
"instead."
msgstr ""
-#: doc/classes/ProjectSettings.xml:966
+#: doc/classes/ProjectSettings.xml:968
msgid ""
"Fix to improve physics jitter, specially on monitors where refresh rate is "
"different than the physics FPS.\n"
@@ -39468,7 +39443,7 @@ msgid ""
"the physics FPS at runtime, set [member Engine.physics_jitter_fix] instead."
msgstr ""
-#: doc/classes/ProjectSettings.xml:970
+#: doc/classes/ProjectSettings.xml:972
msgid ""
"Default background clear color. Overridable per [Viewport] using its "
"[Environment]. See [member Environment.background_mode] and [member "
@@ -39476,7 +39451,7 @@ msgid ""
"programmatically, use [method RenderingServer.set_default_clear_color]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:973
+#: doc/classes/ProjectSettings.xml:975
msgid ""
"[Environment] that will be used as a fallback environment in case a scene "
"does not specify its own environment. The default environment is loaded in "
@@ -39486,14 +39461,14 @@ msgid ""
"here."
msgstr ""
-#: doc/classes/ProjectSettings.xml:976
+#: doc/classes/ProjectSettings.xml:980
msgid ""
"Max amount of elements renderable in a frame. If more than this are visible "
"per frame, they will be dropped. Keep in mind elements refer to mesh "
"surfaces and not meshes themselves."
msgstr ""
-#: doc/classes/ProjectSettings.xml:979
+#: doc/classes/ProjectSettings.xml:985
msgid ""
"Some NVIDIA GPU drivers have a bug which produces flickering issues for the "
"[code]draw_rect[/code] method, especially as used in [TileMap]. Refer to "
@@ -39505,39 +39480,73 @@ msgid ""
"using the Vulkan backend."
msgstr ""
-#: doc/classes/ProjectSettings.xml:983
+#: doc/classes/ProjectSettings.xml:989
msgid ""
"If [code]true[/code], forces snapping of polygons to pixels in 2D rendering. "
"May help in some pixel art styles."
msgstr ""
-#: doc/classes/ProjectSettings.xml:986
+#: doc/classes/ProjectSettings.xml:992
+msgid ""
+"Sets the quality of the depth of field effect. Higher quality takes more "
+"samples, which is slower but looks smoother."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:995
+msgid ""
+"Sets the depth of field shape. Can be Box, Hexagon, or Circle. Box is the "
+"fastest. Circle is the most realistic, but also the most expensive to "
+"compute."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:998
+msgid ""
+"If [code]true[/code], jitters DOF samples to make effect slightly blurrier "
+"and hide lines created from low sample rates. This can result in a slightly "
+"grainy appearance when used with a low number of samples."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1001
msgid ""
"Disables depth pre-pass for some GPU vendors (usually mobile), as their "
"architecture already does this."
msgstr ""
-#: doc/classes/ProjectSettings.xml:989
+#: doc/classes/ProjectSettings.xml:1004
msgid ""
"If [code]true[/code], performs a previous depth pass before rendering "
"materials. This increases performance in scenes with high overdraw, when "
"complex materials and lighting are used."
msgstr ""
-#: doc/classes/ProjectSettings.xml:992
+#: doc/classes/ProjectSettings.xml:1007
msgid ""
"The directional shadow's size in pixels. Higher values will result in "
"sharper shadows, at the cost of performance. The value will be rounded up to "
"the nearest power of 2."
msgstr ""
-#: doc/classes/ProjectSettings.xml:995
+#: doc/classes/ProjectSettings.xml:1010
msgid ""
"Lower-end override for [member rendering/quality/directional_shadow/size] on "
"mobile devices, due to performance concerns or driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:998
+#: doc/classes/ProjectSettings.xml:1013
+msgid ""
+"Quality setting for shadows cast by [DirectionalLight3D]s. Higher quality "
+"settings use more samples when reading from shadow maps and are thus slower. "
+"Low quality settings may result in shadows looking grainy."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1016
+msgid ""
+"Lower-end override for [member rendering/quality/directional_shadow/"
+"soft_shadow_quality] on mobile devices, due to performance concerns or "
+"driver support."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1019
msgid ""
"The video driver to use (\"GLES2\" or \"Vulkan\").\n"
"[b]Note:[/b] The backend in use can be overridden at runtime via the [code]--"
@@ -39547,25 +39556,33 @@ msgid ""
"get_current_video_driver[/code] to query it at run-time."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1012
+#: doc/classes/ProjectSettings.xml:1025
msgid ""
-"Sets the number of MSAA samples to use. MSAA is used to reduce aliasing "
-"around the edges of polygons. A higher MSAA value results in smoother edges "
-"but can be significantly slower on some hardware.\n"
-"[b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend."
+"If [code]true[/code], take additional samples when rendering objects "
+"affected by a [GIProbe] to reduce artifacts from only sampling in one "
+"direction."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1020
+#: doc/classes/ProjectSettings.xml:1028
msgid ""
-"If [code]true[/code], uses nearest-neighbor mipmap filtering when using "
-"mipmaps (also called \"bilinear filtering\"), which will result in visible "
-"seams appearing between mipmap stages. This may increase performance in "
-"mobile as less memory bandwidth is used. If [code]false[/code], linear "
-"mipmap filtering (also called \"trilinear filtering\") is used."
+"Sets the number of cone samples taken when rendering objects affected by "
+"[GIProbe]s."
msgstr ""
#: doc/classes/ProjectSettings.xml:1031
msgid ""
+"Sets how the glow effect is upscaled before being copied onto the screen. "
+"Linear is faster, but looks blocky. Bicubic is slower but looks smooth."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1034
+msgid ""
+"Lower-end override for [member rendering/quality/glow/upscale_mode] on "
+"mobile devices, due to performance concerns or driver support."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1037
+msgid ""
"Strategy used for framebuffer allocation. The simpler it is, the less "
"resources it uses (but the less features it supports). If set to \"2D "
"Without Sampling\" or \"3D Without Effects\", sample buffers will not be "
@@ -39574,41 +39591,41 @@ msgid ""
"be available in the [Environment]."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1034
+#: doc/classes/ProjectSettings.xml:1040
msgid ""
"Lower-end override for [member rendering/quality/intended_usage/"
"framebuffer_allocation] on mobile devices, due to performance concerns or "
"driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1037
+#: doc/classes/ProjectSettings.xml:1043
msgid ""
"Number of cubemaps to store in the reflection atlas. The number of "
"[ReflectionProbe]s in a scene will be limited by this amount. A higher "
"number requires more VRAM."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1040
+#: doc/classes/ProjectSettings.xml:1046
msgid ""
"Size of cubemap faces for [ReflectionProbe]s. A higher number requires more "
"VRAM and may make reflection probe updating slower."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1043
+#: doc/classes/ProjectSettings.xml:1049
msgid ""
"Lower-end override for [member rendering/quality/reflection_atlas/"
"reflection_size] on mobile devices, due to performance concerns or driver "
"support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1046
+#: doc/classes/ProjectSettings.xml:1052
msgid ""
"Use a higher quality variant of the fast filtering algorithm. Significantly "
"slower than using default quality, but results in smoother reflections. "
"Should only be used when the scene is especially detailed."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1049
+#: doc/classes/ProjectSettings.xml:1055
msgid ""
"Sets the number of samples to take when using importance sampling for [Sky]s "
"and [ReflectionProbe]s. A higher value will result in smoother, higher "
@@ -39618,19 +39635,19 @@ msgid ""
"environments with a high level of detail."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1052
+#: doc/classes/ProjectSettings.xml:1058
msgid ""
"Lower-end override for [member rendering/quality/reflections/ggx_samples] on "
"mobile devices, due to performance concerns or driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1055
+#: doc/classes/ProjectSettings.xml:1061
msgid ""
"Limits the number of layers to use in radiance maps when using importance "
"sampling. A lower number will be slightly faster and take up less VRAM."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1058
+#: doc/classes/ProjectSettings.xml:1064
msgid ""
"If [code]true[/code], uses texture arrays instead of mipmaps for reflection "
"probes and panorama backgrounds (sky). This reduces jitter noise and "
@@ -39639,128 +39656,229 @@ msgid ""
"memory."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1061
+#: doc/classes/ProjectSettings.xml:1067
msgid ""
"Lower-end override for [member rendering/quality/reflections/"
"texture_array_reflections] on mobile devices, due to performance concerns or "
"driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1066
+#: doc/classes/ProjectSettings.xml:1070
+msgid ""
+"Sets the number of MSAA samples to use. MSAA is used to reduce aliasing "
+"around the edges of polygons. A higher MSAA value results in smoother edges "
+"but can be significantly slower on some hardware.\n"
+"[b]Note:[/b] MSAA is not available on HTML5 export using the GLES2 backend."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1074
+msgid ""
+"Sets the screen-space antialiasing mode for the default screen [Viewport]. "
+"Screen-space antialiasing works by selectively blurring edges in a post-"
+"process shader. It differs from MSAA which takes multiple coverage samples "
+"while rendering objects. Screen-space AA methods are typically faster than "
+"MSAA and will smooth out specular aliasing, but tend to make scenes appear "
+"blurry.\n"
+"Another way to combat specular aliasing is to enable [member rendering/"
+"quality/screen_filters/screen_space_roughness_limiter]."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1078
+msgid ""
+"Enables the screen-space roughness limiter which increases material "
+"roughness in areas with a high normal frequency (i.e. when normals change a "
+"lot from pixel to pixel). This helps to reduce the amount of specular "
+"aliasing in a scene. Specular aliasing looks like random bright pixels that "
+"occur in reflections."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1081
+msgid ""
+"Curves the amount of the roughness limited effect. A higher value limits the "
+"effect to very sharply curved surfaces, while a lower threshold extends the "
+"effect to smoother surfaces."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1084
+msgid ""
+"Sets the quality for rough screen-space reflections. Turning off will make "
+"all screen space reflections sharp, while higher values make rough "
+"reflections look better."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1087
msgid ""
"If [code]true[/code], uses faster but lower-quality Blinn model to generate "
"blurred reflections instead of the GGX model."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1069
+#: doc/classes/ProjectSettings.xml:1090
msgid ""
"Lower-end override for [member rendering/quality/shading/"
"force_blinn_over_ggx] on mobile devices, due to performance concerns or "
"driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1072
+#: doc/classes/ProjectSettings.xml:1093
msgid ""
"If [code]true[/code], uses faster but lower-quality Lambert material "
"lighting model instead of Burley."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1075
+#: doc/classes/ProjectSettings.xml:1096
msgid ""
"Lower-end override for [member rendering/quality/shading/"
"force_lambert_over_burley] on mobile devices, due to performance concerns or "
"driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1078
+#: doc/classes/ProjectSettings.xml:1099
msgid ""
"If [code]true[/code], forces vertex shading for all rendering. This can "
"increase performance a lot, but also reduces quality immensely. Can be used "
"to optimize performance on low-end mobile devices."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1081
+#: doc/classes/ProjectSettings.xml:1102
msgid ""
"Lower-end override for [member rendering/quality/shading/"
"force_vertex_shading] on mobile devices, due to performance concerns or "
"driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1084 doc/classes/ProjectSettings.xml:1087
-#: doc/classes/ProjectSettings.xml:1090 doc/classes/ProjectSettings.xml:1093
+#: doc/classes/ProjectSettings.xml:1105 doc/classes/ProjectSettings.xml:1108
+#: doc/classes/ProjectSettings.xml:1111 doc/classes/ProjectSettings.xml:1114
msgid ""
"Subdivision quadrant size for shadow mapping. See shadow mapping "
"documentation."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1096
+#: doc/classes/ProjectSettings.xml:1117
msgid ""
"Size for shadow atlas (used for OmniLights and SpotLights). See "
"documentation."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1099
+#: doc/classes/ProjectSettings.xml:1120
msgid ""
"Lower-end override for [member rendering/quality/shadow_atlas/size] on "
"mobile devices, due to performance concerns or driver support."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1102
+#: doc/classes/ProjectSettings.xml:1123
msgid ""
-"Shadow filter mode. Higher-quality settings result in smoother shadows that "
-"flicker less when moving. \"Disabled\" is the fastest option, but also has "
-"the lowest quality. \"PCF5\" is smoother but is also slower. \"PCF13\" is "
-"the smoothest option, but is also the slowest."
+"Quality setting for shadows cast by [OmniLight3D]s and [SpotLight3D]s. "
+"Higher quality settings use more samples when reading from shadow maps and "
+"are thus slower. Low quality settings may result in shadows looking grainy."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1105
+#: doc/classes/ProjectSettings.xml:1126
msgid ""
-"Lower-end override for [member rendering/quality/shadows/filter_mode] on "
-"mobile devices, due to performance concerns or driver support."
+"Lower-end override for [member rendering/quality/shadows/"
+"soft_shadow_quality] on mobile devices, due to performance concerns or "
+"driver support."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1129
+msgid ""
+"If [code]true[/code], screen-space ambient occlusion will be rendered at "
+"half size and then upscaled before being added to the scene. This is "
+"significantly faster but may miss small details."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1132
+msgid ""
+"Sets the quality of the screen-space ambient occlusion effect. Higher values "
+"take more samples and so will result in better quality, at the cost of "
+"performance."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1135
+msgid ""
+"Scales the depth over which the subsurface scattering effect is applied. A "
+"high value may allow light to scatter into a part of the mesh or another "
+"mesh that is close in screen space but far in depth."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1138
+msgid ""
+"Sets the quality of the subsurface scattering effect. Higher values are "
+"slower but look nicer."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1141
+msgid ""
+"Scales the distance over which samples are taken for subsurface scattering "
+"effect. Changing this does not impact performance, but higher values will "
+"result in significant artifacts as the samples will become obviously spread "
+"out. A lower value results in a smaller spread of scattered light."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1144
+msgid ""
+"Sets the maximum number of samples to take when using anisotropic filtering "
+"on textures. A higher sample count will result in sharper textures at "
+"oblique angles, but is more expensive to compute.\n"
+"Only power of two values are valid ([code]1[/code], [code]2[/code], [code]4[/"
+"code], [code]8[/code], [code]16[/code]). A value of [code]1[/code] forcibly "
+"disables anisotropic filtering, even on materials where it is enabled."
+msgstr ""
+
+#: doc/classes/ProjectSettings.xml:1148
+msgid ""
+"If [code]true[/code], uses nearest-neighbor mipmap filtering when using "
+"mipmaps (also called \"bilinear filtering\"), which will result in visible "
+"seams appearing between mipmap stages. This may increase performance in "
+"mobile as less memory bandwidth is used. If [code]false[/code], linear "
+"mipmap filtering (also called \"trilinear filtering\") is used."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1118
+#: doc/classes/ProjectSettings.xml:1151
msgid ""
"Thread model for rendering. Rendering on a thread can vastly improve "
"performance, but synchronizing to the main thread can cause a bit more "
"jitter."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1121
+#: doc/classes/ProjectSettings.xml:1154
msgid ""
"If [code]true[/code], the texture importer will import VRAM-compressed "
"textures using the BPTC algorithm. This texture compression algorithm is "
"only supported on desktop platforms, and only when using the Vulkan renderer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1124
+#: doc/classes/ProjectSettings.xml:1157
msgid ""
"If [code]true[/code], the texture importer will import VRAM-compressed "
"textures using the Ericsson Texture Compression algorithm. This algorithm "
"doesn't support alpha channels in textures."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1127
+#: doc/classes/ProjectSettings.xml:1160
msgid ""
"If [code]true[/code], the texture importer will import VRAM-compressed "
"textures using the Ericsson Texture Compression 2 algorithm. This texture "
"compression algorithm is only supported when using the Vulkan renderer."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1130
+#: doc/classes/ProjectSettings.xml:1163
msgid ""
"If [code]true[/code], the texture importer will import VRAM-compressed "
"textures using the PowerVR Texture Compression algorithm. This texture "
"compression algorithm is only supported on iOS."
msgstr ""
-#: doc/classes/ProjectSettings.xml:1133
+#: doc/classes/ProjectSettings.xml:1166
msgid ""
"If [code]true[/code], the texture importer will import VRAM-compressed "
"textures using the S3 Texture Compression algorithm. This algorithm is only "
"supported on desktop platforms and consoles."
msgstr ""
+#: doc/classes/ProjectSettings.xml:1177
+msgid "Cell size used for the 2D hash grid that [VisibilityNotifier2D] uses."
+msgstr ""
+
#: doc/classes/ProximityGroup3D.xml:4 doc/classes/ProximityGroup3D.xml:7
msgid "General-purpose proximity detection node."
msgstr ""
@@ -40861,11 +40979,11 @@ msgstr ""
#: doc/classes/RenderingServer.xml:7
msgid ""
-"Server for anything visible. The visual server is the API backend for "
+"Server for anything visible. The rendering server is the API backend for "
"everything visible. The whole scene system mounts on it to display.\n"
-"The visual server is completely opaque, the internals are entirely "
+"The rendering server is completely opaque, the internals are entirely "
"implementation specific and cannot be accessed.\n"
-"The visual server can be used to bypass the scene system entirely.\n"
+"The rendering server can be used to bypass the scene system entirely.\n"
"Resources are created using the [code]*_create[/code] functions.\n"
"All objects are drawn to a viewport. You can use the [Viewport] attached to "
"the [SceneTree] or you can create one yourself with [method "
@@ -40873,10 +40991,10 @@ msgid ""
"canvas needs to be attached to the viewport using [method "
"viewport_set_scenario] or [method viewport_attach_canvas].\n"
"In 3D, all visual objects must be associated with a scenario. The scenario "
-"is a visual representation of the world. If accessing the visual server from "
-"a running game, the scenario can be accessed from the scene tree from any "
-"[Node3D] node with [method Node3D.get_world]. Otherwise, a scenario can be "
-"created with [method scenario_create].\n"
+"is a visual representation of the world. If accessing the rendering server "
+"from a running game, the scenario can be accessed from the scene tree from "
+"any [Node3D] node with [method Node3D.get_world]. Otherwise, a scenario can "
+"be created with [method scenario_create].\n"
"Similarly in 2D, a canvas is needed to draw all canvas items.\n"
"In 3D, all visible objects are comprised of a resource and an instance. A "
"resource can be a mesh, a particle system, a light, or any other 3D object. "
@@ -41302,42 +41420,42 @@ msgstr ""
msgid "Returns the id of a white texture. Creates one if none exists."
msgstr ""
-#: doc/classes/RenderingServer.xml:954
+#: doc/classes/RenderingServer.xml:1006
msgid ""
"Returns [code]true[/code] if changes have been made to the RenderingServer's "
"data. [method force_draw] is usually called if this happens."
msgstr ""
-#: doc/classes/RenderingServer.xml:963
+#: doc/classes/RenderingServer.xml:1015
msgid "Not yet implemented. Always returns [code]false[/code]."
msgstr ""
-#: doc/classes/RenderingServer.xml:972
+#: doc/classes/RenderingServer.xml:1024
msgid ""
"Returns [code]true[/code] if the OS supports a certain feature. Features "
"might be [code]s3tc[/code], [code]etc[/code], [code]etc2[/code] and "
"[code]pvrtc[/code]."
msgstr ""
-#: doc/classes/RenderingServer.xml:985
+#: doc/classes/RenderingServer.xml:1037
msgid ""
"Sets up [ImmediateGeometry3D] internals to prepare for drawing. Equivalent "
"to [method ImmediateGeometry3D.begin]."
msgstr ""
-#: doc/classes/RenderingServer.xml:994
+#: doc/classes/RenderingServer.xml:1046
msgid ""
"Clears everything that was set up between [method immediate_begin] and "
"[method immediate_end]. Equivalent to [method ImmediateGeometry3D.clear]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1005
+#: doc/classes/RenderingServer.xml:1057
msgid ""
"Sets the color to be used with next vertex. Equivalent to [method "
"ImmediateGeometry3D.set_color]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1012
+#: doc/classes/RenderingServer.xml:1064
msgid ""
"Creates an immediate geometry and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -41348,78 +41466,78 @@ msgid ""
"[method instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:1023
+#: doc/classes/RenderingServer.xml:1075
msgid ""
"Ends drawing the [ImmediateGeometry3D] and displays it. Equivalent to "
"[method ImmediateGeometry3D.end]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1032
+#: doc/classes/RenderingServer.xml:1084
msgid "Returns the material assigned to the [ImmediateGeometry3D]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1043
+#: doc/classes/RenderingServer.xml:1095
msgid ""
"Sets the normal to be used with next vertex. Equivalent to [method "
"ImmediateGeometry3D.set_normal]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1054
+#: doc/classes/RenderingServer.xml:1106
msgid "Sets the material to be used to draw the [ImmediateGeometry3D]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1065
+#: doc/classes/RenderingServer.xml:1117
msgid ""
"Sets the tangent to be used with next vertex. Equivalent to [method "
"ImmediateGeometry3D.set_tangent]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1076
+#: doc/classes/RenderingServer.xml:1128
msgid ""
"Sets the UV to be used with next vertex. Equivalent to [method "
"ImmediateGeometry3D.set_uv]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1087
+#: doc/classes/RenderingServer.xml:1139
msgid ""
"Sets the UV2 to be used with next vertex. Equivalent to [method "
"ImmediateGeometry3D.set_uv2]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1098
+#: doc/classes/RenderingServer.xml:1150
msgid ""
"Adds the next vertex using the information provided in advance. Equivalent "
"to [method ImmediateGeometry3D.add_vertex]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1109
+#: doc/classes/RenderingServer.xml:1161
msgid ""
"Adds the next vertex using the information provided in advance. This is a "
"helper class that calls [method immediate_vertex] under the hood. Equivalent "
"to [method ImmediateGeometry3D.add_vertex]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1116
+#: doc/classes/RenderingServer.xml:1168
msgid ""
-"Initializes the visual server. This function is called internally by "
+"Initializes the rendering server. This function is called internally by "
"platform-dependent code during engine initialization. If called from a "
"running game, it will not do anything."
msgstr ""
-#: doc/classes/RenderingServer.xml:1127
+#: doc/classes/RenderingServer.xml:1179
msgid ""
"Attaches a unique Object ID to instance. Object ID must be attached to "
"instance for proper culling with [method instances_cull_aabb], [method "
"instances_cull_convex], and [method instances_cull_ray]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1138
+#: doc/classes/RenderingServer.xml:1190
msgid ""
"Attaches a skeleton to an instance. Removes the previous skeleton from the "
"instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:1145
+#: doc/classes/RenderingServer.xml:1197
msgid ""
"Creates a visual instance and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -41431,7 +41549,7 @@ msgid ""
"instance to be visible in the scenario using [method instance_set_base]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1158
+#: doc/classes/RenderingServer.xml:1210
msgid ""
"Creates a visual instance, adds it to the RenderingServer, and sets both "
"base and scenario. It can be accessed with the RID that is returned. This "
@@ -41440,31 +41558,31 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:1170 doc/classes/RenderingServer.xml:1198
-#: doc/classes/RenderingServer.xml:1488
+#: doc/classes/RenderingServer.xml:1222 doc/classes/RenderingServer.xml:1250
+#: doc/classes/RenderingServer.xml:1540
msgid "Not implemented in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:1181
+#: doc/classes/RenderingServer.xml:1233
msgid ""
"Sets the shadow casting setting to one of [enum ShadowCastingSetting]. "
"Equivalent to [member GeometryInstance3D.cast_shadow]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1211
+#: doc/classes/RenderingServer.xml:1263
msgid ""
"Sets the flag for a given [enum InstanceFlags]. See [enum InstanceFlags] for "
"more details."
msgstr ""
-#: doc/classes/RenderingServer.xml:1222
+#: doc/classes/RenderingServer.xml:1274
msgid ""
"Sets a material that will override the material for all surfaces on the mesh "
"associated with this instance. Equivalent to [member GeometryInstance3D."
"material_override]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1233
+#: doc/classes/RenderingServer.xml:1285
msgid ""
"Sets the base of the instance. A base can be any of the 3D objects that are "
"created in the RenderingServer that can be displayed. For example, any of "
@@ -41473,62 +41591,62 @@ msgid ""
"be set as the base of an instance in order to be displayed in the scenario."
msgstr ""
-#: doc/classes/RenderingServer.xml:1246
+#: doc/classes/RenderingServer.xml:1298
msgid "Sets the weight for a given blend shape associated with this instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:1257
+#: doc/classes/RenderingServer.xml:1309
msgid ""
"Sets a custom AABB to use when culling objects from the view frustum. "
"Equivalent to [method GeometryInstance3D.set_custom_aabb]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1268
+#: doc/classes/RenderingServer.xml:1320
msgid "Function not implemented in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:1279
+#: doc/classes/RenderingServer.xml:1331
msgid ""
"Sets a margin to increase the size of the AABB when culling objects from the "
"view frustum. This allows you avoid culling objects that fall outside the "
"view frustum. Equivalent to [member GeometryInstance3D.extra_cull_margin]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1290
+#: doc/classes/RenderingServer.xml:1342
msgid ""
"Sets the render layers that this instance will be drawn to. Equivalent to "
"[member VisualInstance3D.layers]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1301
+#: doc/classes/RenderingServer.xml:1353
msgid ""
"Sets the scenario that the instance is in. The scenario is the 3D world that "
"the objects will be displayed in."
msgstr ""
-#: doc/classes/RenderingServer.xml:1314
+#: doc/classes/RenderingServer.xml:1366
msgid ""
"Sets the material of a specific surface. Equivalent to [method "
"MeshInstance3D.set_surface_material]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1325
+#: doc/classes/RenderingServer.xml:1377
msgid ""
"Sets the world space transform of the instance. Equivalent to [member Node3D."
"transform]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1338
+#: doc/classes/RenderingServer.xml:1390
msgid "Sets the lightmap to use with this instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:1349
+#: doc/classes/RenderingServer.xml:1401
msgid ""
"Sets whether an instance is drawn or not. Equivalent to [member Node3D."
"visible]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1360
+#: doc/classes/RenderingServer.xml:1412
msgid ""
"Returns an array of object IDs intersecting with the provided AABB. Only "
"visual 3D nodes are considered, such as [MeshInstance3D] or "
@@ -41540,7 +41658,7 @@ msgid ""
"game use cases, prefer physics collision."
msgstr ""
-#: doc/classes/RenderingServer.xml:1372
+#: doc/classes/RenderingServer.xml:1424
msgid ""
"Returns an array of object IDs intersecting with the provided convex shape. "
"Only visual 3D nodes are considered, such as [MeshInstance3D] or "
@@ -41552,7 +41670,7 @@ msgid ""
"game use cases, prefer physics collision."
msgstr ""
-#: doc/classes/RenderingServer.xml:1386
+#: doc/classes/RenderingServer.xml:1438
msgid ""
"Returns an array of object IDs intersecting with the provided 3D ray. Only "
"visual 3D nodes are considered, such as [MeshInstance3D] or "
@@ -41564,58 +41682,58 @@ msgid ""
"game use cases, prefer physics collision."
msgstr ""
-#: doc/classes/RenderingServer.xml:1398
+#: doc/classes/RenderingServer.xml:1450
msgid ""
"If [code]true[/code], this directional light will blend between shadow map "
"splits resulting in a smoother transition between them. Equivalent to "
"[member DirectionalLight3D.directional_shadow_blend_splits]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1409
+#: doc/classes/RenderingServer.xml:1461
msgid ""
"Sets the shadow depth range mode for this directional light. Equivalent to "
"[member DirectionalLight3D.directional_shadow_depth_range]. See [enum "
"LightDirectionalShadowDepthRangeMode] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:1420
+#: doc/classes/RenderingServer.xml:1472
msgid ""
"Sets the shadow mode for this directional light. Equivalent to [member "
"DirectionalLight3D.directional_shadow_mode]. See [enum "
"LightDirectionalShadowMode] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:1431
+#: doc/classes/RenderingServer.xml:1483
msgid ""
"Sets whether to use a dual paraboloid or a cubemap for the shadow map. Dual "
"paraboloid is faster but may suffer from artifacts. Equivalent to [member "
"OmniLight3D.omni_shadow_mode]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1442
+#: doc/classes/RenderingServer.xml:1494
msgid ""
"Sets the color of the light. Equivalent to [member Light3D.light_color]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1453
+#: doc/classes/RenderingServer.xml:1505
msgid ""
"Sets the cull mask for this Light3D. Lights only affect objects in the "
"selected layers. Equivalent to [member Light3D.light_cull_mask]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1464
+#: doc/classes/RenderingServer.xml:1516
msgid ""
"If [code]true[/code], light will subtract light instead of adding light. "
"Equivalent to [member Light3D.light_negative]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1477
+#: doc/classes/RenderingServer.xml:1529
msgid ""
"Sets the specified light parameter. See [enum LightParam] for options. "
"Equivalent to [method Light3D.set_param]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1499
+#: doc/classes/RenderingServer.xml:1551
msgid ""
"If [code]true[/code], reverses the backface culling of the mesh. This can be "
"useful when you have a flat mesh that has a light behind it. If you need to "
@@ -41624,23 +41742,23 @@ msgid ""
"to [member Light3D.shadow_reverse_cull_face]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1510
+#: doc/classes/RenderingServer.xml:1562
msgid ""
"If [code]true[/code], light will cast shadows. Equivalent to [member Light3D."
"shadow_enabled]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1521
+#: doc/classes/RenderingServer.xml:1573
msgid ""
"Sets the color of the shadow cast by the light. Equivalent to [member "
"Light3D.shadow_color]."
msgstr ""
-#: doc/classes/RenderingServer.xml:1532
+#: doc/classes/RenderingServer.xml:1584
msgid "Sets whether GI probes capture light information from this light."
msgstr ""
-#: doc/classes/RenderingServer.xml:1539
+#: doc/classes/RenderingServer.xml:1591
msgid ""
"Creates a lightmap capture and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -41651,54 +41769,54 @@ msgid ""
"[method instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:1550
+#: doc/classes/RenderingServer.xml:1602
msgid "Returns the size of the lightmap capture area."
msgstr ""
-#: doc/classes/RenderingServer.xml:1559
+#: doc/classes/RenderingServer.xml:1611
msgid "Returns the energy multiplier used by the lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:1568
+#: doc/classes/RenderingServer.xml:1620
msgid "Returns the octree used by the lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:1577
+#: doc/classes/RenderingServer.xml:1629
msgid ""
"Returns the cell subdivision amount used by this lightmap capture's octree."
msgstr ""
-#: doc/classes/RenderingServer.xml:1586
+#: doc/classes/RenderingServer.xml:1638
msgid "Returns the cell transform for this lightmap capture's octree."
msgstr ""
-#: doc/classes/RenderingServer.xml:1597
+#: doc/classes/RenderingServer.xml:1649
msgid "Sets the size of the area covered by the lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:1608
+#: doc/classes/RenderingServer.xml:1660
msgid "Sets the energy multiplier for this lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:1619
+#: doc/classes/RenderingServer.xml:1671
msgid "Sets the octree to be used by this lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:1630
+#: doc/classes/RenderingServer.xml:1682
msgid "Sets the subdivision level of this lightmap capture's octree."
msgstr ""
-#: doc/classes/RenderingServer.xml:1641
+#: doc/classes/RenderingServer.xml:1693
msgid "Sets the octree cell transform for this lightmap capture's octree."
msgstr ""
-#: doc/classes/RenderingServer.xml:1654
+#: doc/classes/RenderingServer.xml:1706
msgid ""
"Returns a mesh of a sphere with the given amount of horizontal and vertical "
"subdivisions."
msgstr ""
-#: doc/classes/RenderingServer.xml:1661
+#: doc/classes/RenderingServer.xml:1713
msgid ""
"Creates an empty material and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -41707,31 +41825,31 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:1673
+#: doc/classes/RenderingServer.xml:1725
msgid "Returns the value of a certain material's parameter."
msgstr ""
-#: doc/classes/RenderingServer.xml:1684
+#: doc/classes/RenderingServer.xml:1736
msgid "Sets an object's next material."
msgstr ""
-#: doc/classes/RenderingServer.xml:1697
+#: doc/classes/RenderingServer.xml:1749
msgid "Sets a material's parameter."
msgstr ""
-#: doc/classes/RenderingServer.xml:1708
+#: doc/classes/RenderingServer.xml:1760
msgid "Sets a material's render priority."
msgstr ""
-#: doc/classes/RenderingServer.xml:1719
+#: doc/classes/RenderingServer.xml:1771
msgid "Sets a shader material's shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:1748
+#: doc/classes/RenderingServer.xml:1800
msgid "Removes all surfaces from a mesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1755
+#: doc/classes/RenderingServer.xml:1807
msgid ""
"Creates a new mesh and adds it to the RenderingServer. It can be accessed "
"with the RID that is returned. This RID will be used in all [code]mesh_*[/"
@@ -41742,58 +41860,58 @@ msgid ""
"instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:1766
+#: doc/classes/RenderingServer.xml:1818
msgid "Returns a mesh's blend shape count."
msgstr ""
-#: doc/classes/RenderingServer.xml:1775
+#: doc/classes/RenderingServer.xml:1827
msgid "Returns a mesh's blend shape mode."
msgstr ""
-#: doc/classes/RenderingServer.xml:1784
+#: doc/classes/RenderingServer.xml:1836
msgid "Returns a mesh's custom aabb."
msgstr ""
-#: doc/classes/RenderingServer.xml:1793
+#: doc/classes/RenderingServer.xml:1845
msgid "Returns a mesh's number of surfaces."
msgstr ""
-#: doc/classes/RenderingServer.xml:1804
+#: doc/classes/RenderingServer.xml:1856
msgid "Sets a mesh's blend shape mode."
msgstr ""
-#: doc/classes/RenderingServer.xml:1815
+#: doc/classes/RenderingServer.xml:1867
msgid "Sets a mesh's custom aabb."
msgstr ""
-#: doc/classes/RenderingServer.xml:1826
+#: doc/classes/RenderingServer.xml:1878
msgid "Returns a mesh's surface's buffer arrays."
msgstr ""
-#: doc/classes/RenderingServer.xml:1837
+#: doc/classes/RenderingServer.xml:1889
msgid "Returns a mesh's surface's arrays for blend shapes."
msgstr ""
-#: doc/classes/RenderingServer.xml:1852 doc/classes/RenderingServer.xml:1865
+#: doc/classes/RenderingServer.xml:1904 doc/classes/RenderingServer.xml:1917
msgid "Function is unused in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:1876
+#: doc/classes/RenderingServer.xml:1928
msgid "Returns a mesh's surface's material."
msgstr ""
-#: doc/classes/RenderingServer.xml:1889
+#: doc/classes/RenderingServer.xml:1941
msgid "Sets a mesh's surface's material."
msgstr ""
-#: doc/classes/RenderingServer.xml:1904
+#: doc/classes/RenderingServer.xml:1956
msgid ""
"Updates a specific region of a vertex buffer for the specified surface. "
"Warning: this function alters the vertex buffer directly with no safety "
"mechanisms, you can easily corrupt your mesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1927
+#: doc/classes/RenderingServer.xml:1979
msgid ""
"Creates a new multimesh on the RenderingServer and returns an [RID] handle. "
"This RID will be used in all [code]multimesh_*[/code] RenderingServer "
@@ -41804,82 +41922,82 @@ msgid ""
"instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:1938
+#: doc/classes/RenderingServer.xml:1990
msgid ""
"Calculates and returns the axis-aligned bounding box that encloses all "
"instances within the multimesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1955
+#: doc/classes/RenderingServer.xml:2007
msgid "Returns the number of instances allocated for this multimesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1964
+#: doc/classes/RenderingServer.xml:2016
msgid ""
"Returns the RID of the mesh that will be used in drawing this multimesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1973
+#: doc/classes/RenderingServer.xml:2025
msgid "Returns the number of visible instances for this multimesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:1984
+#: doc/classes/RenderingServer.xml:2036
msgid "Returns the color by which the specified instance will be modulated."
msgstr ""
-#: doc/classes/RenderingServer.xml:1995
+#: doc/classes/RenderingServer.xml:2047
msgid "Returns the custom data associated with the specified instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:2006
+#: doc/classes/RenderingServer.xml:2058
msgid "Returns the [Transform] of the specified instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:2017
+#: doc/classes/RenderingServer.xml:2069
msgid ""
"Returns the [Transform2D] of the specified instance. For use when the "
"multimesh is set to use 2D transforms."
msgstr ""
-#: doc/classes/RenderingServer.xml:2030
+#: doc/classes/RenderingServer.xml:2082
msgid ""
"Sets the color by which this instance will be modulated. Equivalent to "
"[method MultiMesh.set_instance_color]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2043
+#: doc/classes/RenderingServer.xml:2095
msgid ""
"Sets the custom data for this instance. Custom data is passed as a [Color], "
"but is interpreted as a [code]vec4[/code] in the shader. Equivalent to "
"[method MultiMesh.set_instance_custom_data]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2056
+#: doc/classes/RenderingServer.xml:2108
msgid ""
"Sets the [Transform] for this instance. Equivalent to [method MultiMesh."
"set_instance_transform]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2069
+#: doc/classes/RenderingServer.xml:2121
msgid ""
"Sets the [Transform2D] for this instance. For use when multimesh is used in "
"2D. Equivalent to [method MultiMesh.set_instance_transform_2d]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2090
+#: doc/classes/RenderingServer.xml:2142
msgid ""
"Sets the mesh to be drawn by the multimesh. Equivalent to [member MultiMesh."
"mesh]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2101
+#: doc/classes/RenderingServer.xml:2153
msgid ""
"Sets the number of instances visible at a given time. If -1, all instances "
"that have been allocated are drawn. Equivalent to [member MultiMesh."
"visible_instance_count]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2108
+#: doc/classes/RenderingServer.xml:2160
msgid ""
"Creates a new omni light and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID can be used in most "
@@ -41890,7 +42008,7 @@ msgid ""
"instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:2117
+#: doc/classes/RenderingServer.xml:2169
msgid ""
"Creates a particle system and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -41901,23 +42019,23 @@ msgid ""
"instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:2128
+#: doc/classes/RenderingServer.xml:2180
msgid ""
"Calculates and returns the axis-aligned bounding box that contains all the "
"particles. Equivalent to [method GPUParticles3D.capture_aabb]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2137
+#: doc/classes/RenderingServer.xml:2189
msgid "Returns [code]true[/code] if particles are currently set to emitting."
msgstr ""
-#: doc/classes/RenderingServer.xml:2146
+#: doc/classes/RenderingServer.xml:2198
msgid ""
"Returns [code]true[/code] if particles are not emitting and particles are "
"set to inactive."
msgstr ""
-#: doc/classes/RenderingServer.xml:2155
+#: doc/classes/RenderingServer.xml:2207
msgid ""
"Add particle system to list of particle systems that need to be updated. "
"Update will take place on the next frame, or on the next call to [method "
@@ -41925,121 +42043,121 @@ msgid ""
"instances_cull_ray]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2164
+#: doc/classes/RenderingServer.xml:2216
msgid ""
"Reset the particles on the next update. Equivalent to [method GPUParticles3D."
"restart]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2175
+#: doc/classes/RenderingServer.xml:2227
msgid ""
"Sets the number of particles to be drawn and allocates the memory for them. "
"Equivalent to [member GPUParticles3D.amount]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2186
+#: doc/classes/RenderingServer.xml:2238
msgid ""
"Sets a custom axis-aligned bounding box for the particle system. Equivalent "
"to [member GPUParticles3D.visibility_aabb]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2197
+#: doc/classes/RenderingServer.xml:2249
msgid ""
"Sets the draw order of the particles to one of the named enums from [enum "
"ParticlesDrawOrder]. See [enum ParticlesDrawOrder] for options. Equivalent "
"to [member GPUParticles3D.draw_order]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2210
+#: doc/classes/RenderingServer.xml:2262
msgid ""
"Sets the mesh to be used for the specified draw pass. Equivalent to [member "
"GPUParticles3D.draw_pass_1], [member GPUParticles3D.draw_pass_2], [member "
"GPUParticles3D.draw_pass_3], and [member GPUParticles3D.draw_pass_4]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2221
+#: doc/classes/RenderingServer.xml:2273
msgid ""
"Sets the number of draw passes to use. Equivalent to [member GPUParticles3D."
"draw_passes]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2232
+#: doc/classes/RenderingServer.xml:2284
msgid ""
"Sets the [Transform] that will be used by the particles when they first emit."
msgstr ""
-#: doc/classes/RenderingServer.xml:2243
+#: doc/classes/RenderingServer.xml:2295
msgid ""
"If [code]true[/code], particles will emit over time. Setting to false does "
"not reset the particles, but only stops their emission. Equivalent to "
"[member GPUParticles3D.emitting]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2254
+#: doc/classes/RenderingServer.xml:2306
msgid ""
"Sets the explosiveness ratio. Equivalent to [member GPUParticles3D."
"explosiveness]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2265
+#: doc/classes/RenderingServer.xml:2317
msgid ""
"Sets the frame rate that the particle system rendering will be fixed to. "
"Equivalent to [member GPUParticles3D.fixed_fps]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2276
+#: doc/classes/RenderingServer.xml:2328
msgid ""
"If [code]true[/code], uses fractional delta which smooths the movement of "
"the particles. Equivalent to [member GPUParticles3D.fract_delta]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2287
+#: doc/classes/RenderingServer.xml:2339
msgid ""
"Sets the lifetime of each particle in the system. Equivalent to [member "
"GPUParticles3D.lifetime]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2298
+#: doc/classes/RenderingServer.xml:2350
msgid ""
"If [code]true[/code], particles will emit once and then stop. Equivalent to "
"[member GPUParticles3D.one_shot]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2309
+#: doc/classes/RenderingServer.xml:2361
msgid ""
"Sets the preprocess time for the particles animation. This lets you delay "
"starting an animation until after the particles have begun emitting. "
"Equivalent to [member GPUParticles3D.preprocess]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2320
+#: doc/classes/RenderingServer.xml:2372
msgid ""
"Sets the material for processing the particles. Note: this is not the "
"material used to draw the materials. Equivalent to [member GPUParticles3D."
"process_material]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2331
+#: doc/classes/RenderingServer.xml:2383
msgid ""
"Sets the emission randomness ratio. This randomizes the emission of "
"particles within their phase. Equivalent to [member GPUParticles3D."
"randomness]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2342
+#: doc/classes/RenderingServer.xml:2394
msgid ""
"Sets the speed scale of the particle system. Equivalent to [member "
"GPUParticles3D.speed_scale]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2353
+#: doc/classes/RenderingServer.xml:2405
msgid ""
"If [code]true[/code], particles use local coordinates. If [code]false[/code] "
"they use global coordinates. Equivalent to [member GPUParticles3D."
"local_coords]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2360
+#: doc/classes/RenderingServer.xml:2412
msgid ""
"Creates a reflection probe and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -42050,59 +42168,59 @@ msgid ""
"[method instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:2373
+#: doc/classes/RenderingServer.xml:2425
msgid ""
"If [code]true[/code], reflections will ignore sky contribution. Equivalent "
"to [member ReflectionProbe.interior_enable]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2384
+#: doc/classes/RenderingServer.xml:2436
msgid ""
"Sets the render cull mask for this reflection probe. Only instances with a "
"matching cull mask will be rendered by this probe. Equivalent to [member "
"ReflectionProbe.cull_mask]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2395
+#: doc/classes/RenderingServer.xml:2447
msgid ""
"If [code]true[/code], uses box projection. This can make reflections look "
"more correct in certain situations. Equivalent to [member ReflectionProbe."
"box_projection]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2406
+#: doc/classes/RenderingServer.xml:2458
msgid ""
"If [code]true[/code], computes shadows in the reflection probe. This makes "
"the reflection much slower to compute. Equivalent to [member ReflectionProbe."
"enable_shadows]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2417
+#: doc/classes/RenderingServer.xml:2469
msgid ""
"Sets the size of the area that the reflection probe will capture. Equivalent "
"to [member ReflectionProbe.extents]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2428
+#: doc/classes/RenderingServer.xml:2480
msgid ""
"Sets the intensity of the reflection probe. Intensity modulates the strength "
"of the reflection. Equivalent to [member ReflectionProbe.intensity]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2439
+#: doc/classes/RenderingServer.xml:2491
msgid ""
"Sets the ambient light color for this reflection probe when set to interior "
"mode. Equivalent to [member ReflectionProbe.interior_ambient_color]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2450
+#: doc/classes/RenderingServer.xml:2502
msgid ""
"Sets the energy multiplier for this reflection probes ambient light "
"contribution when set to interior mode. Equivalent to [member "
"ReflectionProbe.interior_ambient_energy]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2461
+#: doc/classes/RenderingServer.xml:2513
msgid ""
"Sets the contribution value for how much the reflection affects the ambient "
"light for this reflection probe when set to interior mode. Useful so that "
@@ -42110,25 +42228,25 @@ msgid ""
"ReflectionProbe.interior_ambient_contrib]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2472
+#: doc/classes/RenderingServer.xml:2524
msgid ""
"Sets the max distance away from the probe an object can be before it is "
"culled. Equivalent to [member ReflectionProbe.max_distance]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2483
+#: doc/classes/RenderingServer.xml:2535
msgid ""
"Sets the origin offset to be used when this reflection probe is in box "
"project mode. Equivalent to [member ReflectionProbe.origin_offset]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2494
+#: doc/classes/RenderingServer.xml:2546
msgid ""
"Sets how often the reflection probe updates. Can either be once or every "
"frame. See [enum ReflectionProbeUpdateMode] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:2507
+#: doc/classes/RenderingServer.xml:2559
msgid ""
"Schedules a callback to the corresponding named [code]method[/code] on "
"[code]where[/code] after a frame has been drawn.\n"
@@ -42136,7 +42254,7 @@ msgid ""
"[code]userdata[/code]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2515
+#: doc/classes/RenderingServer.xml:2567
msgid ""
"Creates a scenario and adds it to the RenderingServer. It can be accessed "
"with the RID that is returned. This RID will be used in all "
@@ -42146,24 +42264,24 @@ msgid ""
"The scenario is the 3D world that all the visual instances exist in."
msgstr ""
-#: doc/classes/RenderingServer.xml:2528
+#: doc/classes/RenderingServer.xml:2580
msgid ""
"Sets the [enum ScenarioDebugMode] for this scenario. See [enum "
"ScenarioDebugMode] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:2539
+#: doc/classes/RenderingServer.xml:2591
msgid "Sets the environment that will be used with this scenario."
msgstr ""
-#: doc/classes/RenderingServer.xml:2550
+#: doc/classes/RenderingServer.xml:2602
msgid ""
"Sets the fallback environment to be used by this scenario. The fallback "
"environment is used if no environment is set. Internally, this is used by "
"the editor to provide a default environment."
msgstr ""
-#: doc/classes/RenderingServer.xml:2565
+#: doc/classes/RenderingServer.xml:2617
msgid ""
"Sets a boot image. The color defines the background color. If [code]scale[/"
"code] is [code]true[/code], the image will be scaled to fit the screen size. "
@@ -42172,19 +42290,19 @@ msgid ""
"the image will be scaled with nearest-neighbor interpolation."
msgstr ""
-#: doc/classes/RenderingServer.xml:2574
+#: doc/classes/RenderingServer.xml:2626
msgid ""
"If [code]true[/code], the engine will generate wireframes for use with the "
"wireframe debug mode."
msgstr ""
-#: doc/classes/RenderingServer.xml:2583
+#: doc/classes/RenderingServer.xml:2635
msgid ""
"Sets the default clear color which is used when a specific clear color has "
"not been selected."
msgstr ""
-#: doc/classes/RenderingServer.xml:2590
+#: doc/classes/RenderingServer.xml:2642
msgid ""
"Creates an empty shader and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -42193,47 +42311,47 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:2600
+#: doc/classes/RenderingServer.xml:2652
msgid "Returns a shader's code."
msgstr ""
-#: doc/classes/RenderingServer.xml:2611
+#: doc/classes/RenderingServer.xml:2663
msgid "Returns a default texture from a shader searched by name."
msgstr ""
-#: doc/classes/RenderingServer.xml:2630
+#: doc/classes/RenderingServer.xml:2682
msgid "Returns the parameters of a shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:2641
+#: doc/classes/RenderingServer.xml:2693
msgid "Sets a shader's code."
msgstr ""
-#: doc/classes/RenderingServer.xml:2654
+#: doc/classes/RenderingServer.xml:2706
msgid "Sets a shader's default texture. Overwrites the texture given by name."
msgstr ""
-#: doc/classes/RenderingServer.xml:2667
+#: doc/classes/RenderingServer.xml:2719
msgid "Allocates the GPU buffers for this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2678
+#: doc/classes/RenderingServer.xml:2730
msgid "Returns the [Transform] set for a specific bone of this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2689
+#: doc/classes/RenderingServer.xml:2741
msgid "Returns the [Transform2D] set for a specific bone of this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2702
+#: doc/classes/RenderingServer.xml:2754
msgid "Sets the [Transform] for a specific bone of this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2715
+#: doc/classes/RenderingServer.xml:2767
msgid "Sets the [Transform2D] for a specific bone of this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2722
+#: doc/classes/RenderingServer.xml:2774
msgid ""
"Creates a skeleton and adds it to the RenderingServer. It can be accessed "
"with the RID that is returned. This RID will be used in all "
@@ -42242,11 +42360,11 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:2732
+#: doc/classes/RenderingServer.xml:2784
msgid "Returns the number of bones allocated for this skeleton."
msgstr ""
-#: doc/classes/RenderingServer.xml:2739
+#: doc/classes/RenderingServer.xml:2791
msgid ""
"Creates an empty sky and adds it to the RenderingServer. It can be accessed "
"with the RID that is returned. This RID will be used in all [code]sky_*[/"
@@ -42255,13 +42373,13 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:2751
+#: doc/classes/RenderingServer.xml:2803
msgid ""
"Sets the material that the sky uses to render the background and reflection "
"maps."
msgstr ""
-#: doc/classes/RenderingServer.xml:2758
+#: doc/classes/RenderingServer.xml:2810
msgid ""
"Creates a spot light and adds it to the RenderingServer. It can be accessed "
"with the RID that is returned. This RID can be used in most [code]light_*[/"
@@ -42272,15 +42390,15 @@ msgid ""
"instance_set_base] using the returned RID."
msgstr ""
-#: doc/classes/RenderingServer.xml:2787
+#: doc/classes/RenderingServer.xml:2839
msgid "Sets a viewport's camera."
msgstr ""
-#: doc/classes/RenderingServer.xml:2798
+#: doc/classes/RenderingServer.xml:2850
msgid "Sets a viewport's canvas."
msgstr ""
-#: doc/classes/RenderingServer.xml:2811
+#: doc/classes/RenderingServer.xml:2863
msgid ""
"Copies the viewport to a region of the screen specified by [code]rect[/"
"code]. If [method viewport_set_render_direct_to_screen] is [code]true[/"
@@ -42302,7 +42420,7 @@ msgid ""
"viewport_set_render_direct_to_screen]."
msgstr ""
-#: doc/classes/RenderingServer.xml:2825
+#: doc/classes/RenderingServer.xml:2877
msgid ""
"Creates an empty viewport and adds it to the RenderingServer. It can be "
"accessed with the RID that is returned. This RID will be used in all "
@@ -42311,72 +42429,72 @@ msgid ""
"RenderingServer's [method free_rid] static method."
msgstr ""
-#: doc/classes/RenderingServer.xml:2837
+#: doc/classes/RenderingServer.xml:2889
msgid ""
"Returns a viewport's render information. For options, see the [enum "
"ViewportRenderInfo] constants."
msgstr ""
-#: doc/classes/RenderingServer.xml:2846
+#: doc/classes/RenderingServer.xml:2898
msgid "Returns the viewport's last rendered frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:2857
+#: doc/classes/RenderingServer.xml:2909
msgid "Detaches a viewport from a canvas and vice versa."
msgstr ""
-#: doc/classes/RenderingServer.xml:2868
+#: doc/classes/RenderingServer.xml:2920
msgid "If [code]true[/code], sets the viewport active, else sets it inactive."
msgstr ""
-#: doc/classes/RenderingServer.xml:2883
+#: doc/classes/RenderingServer.xml:2935
msgid ""
"Sets the stacking order for a viewport's canvas.\n"
"[code]layer[/code] is the actual canvas layer, while [code]sublayer[/code] "
"specifies the stacking order of the canvas among those in the same layer."
msgstr ""
-#: doc/classes/RenderingServer.xml:2897
+#: doc/classes/RenderingServer.xml:2949
msgid "Sets the transformation of a viewport's canvas."
msgstr ""
-#: doc/classes/RenderingServer.xml:2908
+#: doc/classes/RenderingServer.xml:2960
msgid ""
"Sets the clear mode of a viewport. See [enum ViewportClearMode] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:2919
+#: doc/classes/RenderingServer.xml:2971
msgid ""
"Sets the debug draw mode of a viewport. See [enum ViewportDebugDraw] for "
"options."
msgstr ""
-#: doc/classes/RenderingServer.xml:2930
+#: doc/classes/RenderingServer.xml:2982
msgid ""
"If [code]true[/code], rendering of a viewport's environment is disabled."
msgstr ""
-#: doc/classes/RenderingServer.xml:2941
+#: doc/classes/RenderingServer.xml:2993
msgid "Sets the viewport's global transformation matrix."
msgstr ""
-#: doc/classes/RenderingServer.xml:2952
+#: doc/classes/RenderingServer.xml:3004
msgid "If [code]true[/code], the viewport's canvas is not rendered."
msgstr ""
-#: doc/classes/RenderingServer.xml:2963
+#: doc/classes/RenderingServer.xml:3015
msgid "Currently unimplemented in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:2974
+#: doc/classes/RenderingServer.xml:3026
msgid "Sets the anti-aliasing mode. See [enum ViewportMSAA] for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:2985
+#: doc/classes/RenderingServer.xml:3037
msgid "Sets the viewport's parent to another viewport."
msgstr ""
-#: doc/classes/RenderingServer.xml:2996
+#: doc/classes/RenderingServer.xml:3048
msgid ""
"If [code]true[/code], render the contents of the viewport directly to "
"screen. This allows a low-level optimization where you can skip drawing a "
@@ -42392,708 +42510,864 @@ msgid ""
"significantly larger than the window size."
msgstr ""
-#: doc/classes/RenderingServer.xml:3007
+#: doc/classes/RenderingServer.xml:3059
msgid ""
"Sets a viewport's scenario.\n"
"The scenario contains information about the [enum ScenarioDebugMode], "
"environment information, reflection atlas etc."
msgstr ""
-#: doc/classes/RenderingServer.xml:3021
+#: doc/classes/RenderingServer.xml:3073
msgid "Sets the shadow atlas quadrant's subdivision."
msgstr ""
-#: doc/classes/RenderingServer.xml:3032
+#: doc/classes/RenderingServer.xml:3084
msgid ""
"Sets the size of the shadow atlas's images (used for omni and spot lights). "
"The value will be rounded up to the nearest power of 2."
msgstr ""
-#: doc/classes/RenderingServer.xml:3045
+#: doc/classes/RenderingServer.xml:3097
msgid "Sets the viewport's width and height."
msgstr ""
-#: doc/classes/RenderingServer.xml:3056
+#: doc/classes/RenderingServer.xml:3108
msgid ""
"If [code]true[/code], the viewport renders its background as transparent."
msgstr ""
-#: doc/classes/RenderingServer.xml:3067
+#: doc/classes/RenderingServer.xml:3119
msgid ""
"Sets when the viewport should be updated. See [enum ViewportUpdateMode] "
"constants for options."
msgstr ""
-#: doc/classes/RenderingServer.xml:3078
+#: doc/classes/RenderingServer.xml:3130
msgid ""
"If [code]true[/code], the viewport uses augmented or virtual reality "
-"technologies. See [ARVRInterface]."
+"technologies. See [XRInterface]."
msgstr ""
-#: doc/classes/RenderingServer.xml:3085
+#: doc/classes/RenderingServer.xml:3137
msgid ""
"Emitted at the end of the frame, after the RenderingServer has finished "
"updating all the Viewports."
msgstr ""
-#: doc/classes/RenderingServer.xml:3090
+#: doc/classes/RenderingServer.xml:3142
msgid ""
"Emitted at the beginning of the frame, before the RenderingServer updates "
"all the Viewports."
msgstr ""
-#: doc/classes/RenderingServer.xml:3096
+#: doc/classes/RenderingServer.xml:3148
msgid "Marks an error that shows that the index array is empty."
msgstr ""
-#: doc/classes/RenderingServer.xml:3099
+#: doc/classes/RenderingServer.xml:3151
msgid "Number of weights/bones per vertex."
msgstr ""
-#: doc/classes/RenderingServer.xml:3102
+#: doc/classes/RenderingServer.xml:3154
msgid "The minimum Z-layer for canvas items."
msgstr ""
-#: doc/classes/RenderingServer.xml:3105
+#: doc/classes/RenderingServer.xml:3157
msgid "The maximum Z-layer for canvas items."
msgstr ""
-#: doc/classes/RenderingServer.xml:3108
+#: doc/classes/RenderingServer.xml:3160
msgid ""
"Max number of glow levels that can be used with glow post-process effect."
msgstr ""
-#: doc/classes/RenderingServer.xml:3111
+#: doc/classes/RenderingServer.xml:3163
msgid "Unused enum in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:3114
-msgid "The minimum renderpriority of all materials."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3117
-msgid "The maximum renderpriority of all materials."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3138
+#: doc/classes/RenderingServer.xml:3184
msgid "Shader is a 3D shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:3141
+#: doc/classes/RenderingServer.xml:3187
msgid "Shader is a 2D shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:3144
+#: doc/classes/RenderingServer.xml:3190
msgid "Shader is a particle shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:3147
+#: doc/classes/RenderingServer.xml:3193
msgid "Shader is a sky shader."
msgstr ""
-#: doc/classes/RenderingServer.xml:3150
+#: doc/classes/RenderingServer.xml:3196
msgid "Represents the size of the [enum ShaderMode] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3153
+#: doc/classes/RenderingServer.xml:3199
+msgid "The minimum renderpriority of all materials."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3202
+msgid "The maximum renderpriority of all materials."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3205
msgid "Array is a vertex array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3156
+#: doc/classes/RenderingServer.xml:3208
msgid "Array is a normal array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3159
+#: doc/classes/RenderingServer.xml:3211
msgid "Array is a tangent array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3162
+#: doc/classes/RenderingServer.xml:3214
msgid "Array is a color array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3165
+#: doc/classes/RenderingServer.xml:3217
msgid "Array is an UV coordinates array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3168
+#: doc/classes/RenderingServer.xml:3220
msgid "Array is an UV coordinates array for the second UV coordinates."
msgstr ""
-#: doc/classes/RenderingServer.xml:3171
+#: doc/classes/RenderingServer.xml:3223
msgid "Array contains bone information."
msgstr ""
-#: doc/classes/RenderingServer.xml:3174
+#: doc/classes/RenderingServer.xml:3226
msgid "Array is weight information."
msgstr ""
-#: doc/classes/RenderingServer.xml:3177
+#: doc/classes/RenderingServer.xml:3229
msgid "Array is index array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3183
+#: doc/classes/RenderingServer.xml:3235
msgid "Flag used to mark a vertex array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3186
+#: doc/classes/RenderingServer.xml:3238
msgid "Flag used to mark a normal array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3189
+#: doc/classes/RenderingServer.xml:3241
msgid "Flag used to mark a tangent array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3192
+#: doc/classes/RenderingServer.xml:3244
msgid "Flag used to mark a color array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3195
+#: doc/classes/RenderingServer.xml:3247
msgid "Flag used to mark an UV coordinates array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3198
+#: doc/classes/RenderingServer.xml:3250
msgid ""
"Flag used to mark an UV coordinates array for the second UV coordinates."
msgstr ""
-#: doc/classes/RenderingServer.xml:3201
+#: doc/classes/RenderingServer.xml:3253
msgid "Flag used to mark a bone information array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3204
+#: doc/classes/RenderingServer.xml:3256
msgid "Flag used to mark a weights array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3207
+#: doc/classes/RenderingServer.xml:3259
msgid "Flag used to mark an index array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3236
+#: doc/classes/RenderingServer.xml:3288
msgid "Primitive to draw consists of points."
msgstr ""
-#: doc/classes/RenderingServer.xml:3239
+#: doc/classes/RenderingServer.xml:3291
msgid "Primitive to draw consists of lines."
msgstr ""
-#: doc/classes/RenderingServer.xml:3242
+#: doc/classes/RenderingServer.xml:3294
msgid "Primitive to draw consists of a line strip from start to end."
msgstr ""
-#: doc/classes/RenderingServer.xml:3245
+#: doc/classes/RenderingServer.xml:3297
msgid "Primitive to draw consists of triangles."
msgstr ""
-#: doc/classes/RenderingServer.xml:3248
+#: doc/classes/RenderingServer.xml:3300
msgid ""
"Primitive to draw consists of a triangle strip (the last 3 vertices are "
"always combined to make a triangle)."
msgstr ""
-#: doc/classes/RenderingServer.xml:3251
+#: doc/classes/RenderingServer.xml:3303
msgid "Represents the size of the [enum PrimitiveType] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3260
+#: doc/classes/RenderingServer.xml:3312
msgid "Use [Transform2D] to store MultiMesh transform."
msgstr ""
-#: doc/classes/RenderingServer.xml:3263
+#: doc/classes/RenderingServer.xml:3315
msgid "Use [Transform] to store MultiMesh transform."
msgstr ""
-#: doc/classes/RenderingServer.xml:3266
+#: doc/classes/RenderingServer.xml:3318
msgid "Is a directional (sun) light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3269
+#: doc/classes/RenderingServer.xml:3321
msgid "Is an omni light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3272
+#: doc/classes/RenderingServer.xml:3324
msgid "Is a spot light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3275
+#: doc/classes/RenderingServer.xml:3327
msgid "The light's energy."
msgstr ""
-#: doc/classes/RenderingServer.xml:3280
+#: doc/classes/RenderingServer.xml:3332
msgid "The light's influence on specularity."
msgstr ""
-#: doc/classes/RenderingServer.xml:3283
+#: doc/classes/RenderingServer.xml:3335
msgid "The light's range."
msgstr ""
-#: doc/classes/RenderingServer.xml:3286
+#: doc/classes/RenderingServer.xml:3338
+msgid ""
+"The size of the light when using spot light or omni light. The angular size "
+"of the light when using directional light."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3341
msgid "The light's attenuation."
msgstr ""
-#: doc/classes/RenderingServer.xml:3289
+#: doc/classes/RenderingServer.xml:3344
msgid "The spotlight's angle."
msgstr ""
-#: doc/classes/RenderingServer.xml:3292
+#: doc/classes/RenderingServer.xml:3347
msgid "The spotlight's attenuation."
msgstr ""
-#: doc/classes/RenderingServer.xml:3295
-msgid "Scales the shadow color."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3298
+#: doc/classes/RenderingServer.xml:3350
msgid "Max distance that shadows will be rendered."
msgstr ""
-#: doc/classes/RenderingServer.xml:3301
+#: doc/classes/RenderingServer.xml:3353
msgid "Proportion of shadow atlas occupied by the first split."
msgstr ""
-#: doc/classes/RenderingServer.xml:3304
+#: doc/classes/RenderingServer.xml:3356
msgid "Proportion of shadow atlas occupied by the second split."
msgstr ""
-#: doc/classes/RenderingServer.xml:3307
+#: doc/classes/RenderingServer.xml:3359
msgid ""
"Proportion of shadow atlas occupied by the third split. The fourth split "
"occupies the rest."
msgstr ""
-#: doc/classes/RenderingServer.xml:3312
+#: doc/classes/RenderingServer.xml:3362
+msgid ""
+"Proportion of shadow max distance where the shadow will start to fade out."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3365
msgid ""
"Normal bias used to offset shadow lookup by object normal. Can be used to "
"fix self-shadowing artifacts."
msgstr ""
-#: doc/classes/RenderingServer.xml:3315
+#: doc/classes/RenderingServer.xml:3368
msgid "Bias the shadow lookup to fix self-shadowing artifacts."
msgstr ""
-#: doc/classes/RenderingServer.xml:3318
-msgid ""
-"Increases bias on further splits to fix self-shadowing that only occurs far "
-"away from the camera."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3321
+#: doc/classes/RenderingServer.xml:3379
msgid "Represents the size of the [enum LightParam] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3324
+#: doc/classes/RenderingServer.xml:3382
msgid "Use a dual paraboloid shadow map for omni lights."
msgstr ""
-#: doc/classes/RenderingServer.xml:3327
+#: doc/classes/RenderingServer.xml:3385
msgid ""
"Use a cubemap shadow map for omni lights. Slower but better quality than "
"dual paraboloid."
msgstr ""
-#: doc/classes/RenderingServer.xml:3330
+#: doc/classes/RenderingServer.xml:3388
msgid "Use orthogonal shadow projection for directional light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3333
+#: doc/classes/RenderingServer.xml:3391
msgid "Use 2 splits for shadow projection when using directional light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3336
+#: doc/classes/RenderingServer.xml:3394
msgid "Use 4 splits for shadow projection when using directional light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3339
+#: doc/classes/RenderingServer.xml:3397
msgid ""
"Keeps shadows stable as camera moves but has lower effective resolution."
msgstr ""
-#: doc/classes/RenderingServer.xml:3342
+#: doc/classes/RenderingServer.xml:3400
msgid ""
"Optimize use of shadow maps, increasing the effective resolution. But may "
"result in shadows moving or flickering slightly."
msgstr ""
-#: doc/classes/RenderingServer.xml:3345
+#: doc/classes/RenderingServer.xml:3403
msgid "Reflection probe will update reflections once and then stop."
msgstr ""
-#: doc/classes/RenderingServer.xml:3348
+#: doc/classes/RenderingServer.xml:3406
msgid ""
"Reflection probe will update each frame. This mode is necessary to capture "
"moving objects."
msgstr ""
-#: doc/classes/RenderingServer.xml:3351
+#: doc/classes/RenderingServer.xml:3419
msgid "Draw particles in the order that they appear in the particles array."
msgstr ""
-#: doc/classes/RenderingServer.xml:3354
+#: doc/classes/RenderingServer.xml:3422
msgid "Sort particles based on their lifetime."
msgstr ""
-#: doc/classes/RenderingServer.xml:3357
+#: doc/classes/RenderingServer.xml:3425
msgid "Sort particles based on their distance to the camera."
msgstr ""
-#: doc/classes/RenderingServer.xml:3360
+#: doc/classes/RenderingServer.xml:3428
msgid "Do not update the viewport."
msgstr ""
-#: doc/classes/RenderingServer.xml:3363
+#: doc/classes/RenderingServer.xml:3431
msgid "Update the viewport once then set to disabled."
msgstr ""
-#: doc/classes/RenderingServer.xml:3366
+#: doc/classes/RenderingServer.xml:3434
msgid "Update the viewport whenever it is visible."
msgstr ""
-#: doc/classes/RenderingServer.xml:3371
+#: doc/classes/RenderingServer.xml:3439
msgid "Always update the viewport."
msgstr ""
-#: doc/classes/RenderingServer.xml:3374
+#: doc/classes/RenderingServer.xml:3442
msgid "The viewport is always cleared before drawing."
msgstr ""
-#: doc/classes/RenderingServer.xml:3377
+#: doc/classes/RenderingServer.xml:3445
msgid "The viewport is never cleared before drawing."
msgstr ""
-#: doc/classes/RenderingServer.xml:3380
+#: doc/classes/RenderingServer.xml:3448
msgid ""
"The viewport is cleared once, then the clear mode is set to [constant "
"VIEWPORT_CLEAR_NEVER]."
msgstr ""
-#: doc/classes/RenderingServer.xml:3383
+#: doc/classes/RenderingServer.xml:3451
msgid "Multisample antialiasing is disabled."
msgstr ""
-#: doc/classes/RenderingServer.xml:3386
-msgid "Multisample antialiasing is set to 2×."
+#: doc/classes/RenderingServer.xml:3454
+msgid "Multisample antialiasing uses 2 samples per pixel."
msgstr ""
-#: doc/classes/RenderingServer.xml:3389
-msgid "Multisample antialiasing is set to 4×."
+#: doc/classes/RenderingServer.xml:3457
+msgid "Multisample antialiasing uses 4 samples per pixel."
msgstr ""
-#: doc/classes/RenderingServer.xml:3392
-msgid "Multisample antialiasing is set to 8×."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3395
-msgid "Multisample antialiasing is set to 16×."
-msgstr ""
-
-#: doc/classes/RenderingServer.xml:3398
-msgid ""
-"Multisample antialiasing is set to 2× on external texture. Special mode for "
-"GLES2 Android VR (Oculus Quest and Go)."
+#: doc/classes/RenderingServer.xml:3460
+msgid "Multisample antialiasing uses 8 samples per pixel."
msgstr ""
-#: doc/classes/RenderingServer.xml:3401
-msgid ""
-"Multisample antialiasing is set to 4× on external texture. Special mode for "
-"GLES2 Android VR (Oculus Quest and Go)."
+#: doc/classes/RenderingServer.xml:3463
+msgid "Multisample antialiasing uses 16 samples per pixel."
msgstr ""
-#: doc/classes/RenderingServer.xml:3404
+#: doc/classes/RenderingServer.xml:3474
msgid "Number of objects drawn in a single frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3407
+#: doc/classes/RenderingServer.xml:3477
msgid "Number of vertices drawn in a single frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3410
+#: doc/classes/RenderingServer.xml:3480
msgid "Number of material changes during this frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3413
+#: doc/classes/RenderingServer.xml:3483
msgid "Number of shader changes during this frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3416
+#: doc/classes/RenderingServer.xml:3486
msgid "Number of surface changes during this frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3419
+#: doc/classes/RenderingServer.xml:3489
msgid "Number of draw calls during this frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3422
+#: doc/classes/RenderingServer.xml:3492
msgid "Represents the size of the [enum ViewportRenderInfo] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3425
+#: doc/classes/RenderingServer.xml:3495
msgid "Debug draw is disabled. Default setting."
msgstr ""
-#: doc/classes/RenderingServer.xml:3428
-msgid "Debug draw sets objects to unshaded."
+#: doc/classes/RenderingServer.xml:3498 doc/classes/Viewport.xml:348
+msgid "Objects are displayed without light information."
msgstr ""
-#: doc/classes/RenderingServer.xml:3433
-msgid "Overwrites clear color to [code](0,0,0,0)[/code]."
+#: doc/classes/RenderingServer.xml:3501
+msgid "Objects are displayed with only light information."
msgstr ""
-#: doc/classes/RenderingServer.xml:3436
+#: doc/classes/RenderingServer.xml:3504 doc/classes/Viewport.xml:353
+msgid ""
+"Objects are displayed semi-transparent with additive blending so you can see "
+"where they are drawing over top of one another. A higher overdraw means you "
+"are wasting performance on drawing pixels that are being hidden behind "
+"others."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3507
msgid "Debug draw draws objects in wireframe."
msgstr ""
-#: doc/classes/RenderingServer.xml:3461
+#: doc/classes/RenderingServer.xml:3510
+msgid ""
+"Normal buffer is drawn instead of regular scene so you can see the per-pixel "
+"normals that will be used by post-processing effects."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3513 doc/classes/Viewport.xml:361
+msgid "Objects are displayed with only the albedo value from [GIProbe]s."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3516 doc/classes/Viewport.xml:364
+msgid "Objects are displayed with only the lighting value from [GIProbe]s."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3519 doc/classes/Viewport.xml:367
+msgid "Objects are displayed with only the emission color from [GIProbe]s."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3522 doc/classes/Viewport.xml:370
+msgid ""
+"Draws the shadow atlas that stores shadows from [OmniLight3D]s and "
+"[SpotLight3D]s in the upper left quadrant of the [Viewport]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3525 doc/classes/Viewport.xml:373
+msgid ""
+"Draws the shadow atlas that stores shadows from [DirectionalLight3D]s in the "
+"upper left quadrant of the [Viewport]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3530
+msgid ""
+"Draws the screen space ambient occlusion texture instead of the scene so "
+"that you can clearly see how it is affecting objects. In order for this "
+"display mode to work, you must have [member Environment.ssao_enabled] set in "
+"your [WorldEnvironment]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3533 doc/classes/Viewport.xml:381
+msgid ""
+"Draws the roughness limiter post process over the Viewport so you can see "
+"where it has an effect. It must be enabled in [member ProjectSettings."
+"rendering/quality/screen_filters/screen_space_roughness_limiter] to work."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3536
+msgid ""
+"Colors each PSSM split for the [DirectionalLight3D]s in the scene a "
+"different color so you can see where the splits are. In order they will be "
+"colored red, green, blue, yellow."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3541
+msgid ""
+"Uses high quality importance sampling to process the radiance map. In "
+"general, this results in much higher quality than [constant Sky."
+"PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be "
+"used if you plan on changing the sky at runtime. If you are finding that the "
+"reflection is not blurry enough and is showing sparkles or fireflies, try "
+"increasing [member ProjectSettings.rendering/quality/reflections/"
+"ggx_samples]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3544
+msgid ""
+"Uses the fast filtering algorithm to process the radiance map. In general "
+"this results in lower quality, but substantially faster run times.\n"
+"[b]Note:[/b] The fast filtering algorithm is limited to 256x256 cubemaps, so "
+"[member Sky.radiance_size] must be set to [constant Sky.RADIANCE_SIZE_256]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3548
msgid "Use the clear color as background."
msgstr ""
-#: doc/classes/RenderingServer.xml:3464
+#: doc/classes/RenderingServer.xml:3551
msgid "Use a specified color as the background."
msgstr ""
-#: doc/classes/RenderingServer.xml:3467
+#: doc/classes/RenderingServer.xml:3554
msgid "Use a sky resource for the background."
msgstr ""
-#: doc/classes/RenderingServer.xml:3470
+#: doc/classes/RenderingServer.xml:3557
msgid ""
"Use a specified canvas layer as the background. This can be useful for "
"instantiating a 2D scene in a 3D world."
msgstr ""
-#: doc/classes/RenderingServer.xml:3473
+#: doc/classes/RenderingServer.xml:3560
msgid ""
"Do not clear the background, use whatever was rendered last frame as the "
"background."
msgstr ""
-#: doc/classes/RenderingServer.xml:3479
+#: doc/classes/RenderingServer.xml:3566
msgid "Represents the size of the [enum EnvironmentBG] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3506
+#: doc/classes/RenderingServer.xml:3605
msgid "Output color as they came in."
msgstr ""
-#: doc/classes/RenderingServer.xml:3509
+#: doc/classes/RenderingServer.xml:3608
msgid "Use the Reinhard tonemapper."
msgstr ""
-#: doc/classes/RenderingServer.xml:3512
+#: doc/classes/RenderingServer.xml:3611
msgid "Use the filmic tonemapper."
msgstr ""
-#: doc/classes/RenderingServer.xml:3515
+#: doc/classes/RenderingServer.xml:3614
msgid "Use the ACES tonemapper."
msgstr ""
-#: doc/classes/RenderingServer.xml:3518
+#: doc/classes/RenderingServer.xml:3625
msgid "Disables the blur set for SSAO. Will make SSAO look noisier."
msgstr ""
-#: doc/classes/RenderingServer.xml:3521
+#: doc/classes/RenderingServer.xml:3628
msgid "Perform a 1x1 blur on the SSAO output."
msgstr ""
-#: doc/classes/RenderingServer.xml:3524
+#: doc/classes/RenderingServer.xml:3631
msgid "Performs a 2x2 blur on the SSAO output."
msgstr ""
-#: doc/classes/RenderingServer.xml:3527
+#: doc/classes/RenderingServer.xml:3634
msgid "Performs a 3x3 blur on the SSAO output. Use this for smoothest SSAO."
msgstr ""
-#: doc/classes/RenderingServer.xml:3530
+#: doc/classes/RenderingServer.xml:3637
msgid "Lowest quality of screen space ambient occlusion."
msgstr ""
-#: doc/classes/RenderingServer.xml:3533
+#: doc/classes/RenderingServer.xml:3640
msgid "Medium quality screen space ambient occlusion."
msgstr ""
-#: doc/classes/RenderingServer.xml:3536
+#: doc/classes/RenderingServer.xml:3643
+msgid "High quality screen space ambient occlusion."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3646
msgid "Highest quality screen space ambient occlusion."
msgstr ""
-#: doc/classes/RenderingServer.xml:3555
+#: doc/classes/RenderingServer.xml:3657
+msgid ""
+"Lowest quality DOF blur. This is the fastest setting, but you may be able to "
+"see filtering artifacts."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3660
+msgid "Low quality DOF blur."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3663
+msgid "Medium quality DOF blur."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3666
+msgid ""
+"Highest quality DOF blur. Results in the smoothest looking blur by taking "
+"the most samples, but is also significantly slower."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3669
+msgid ""
+"Calculate the DOF blur using a box filter. The fastest option, but results "
+"in obvious lines in blur pattern."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3672
+msgid "Calculates DOF blur using a hexagon shaped filter."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3675
+msgid ""
+"Calculates DOF blur using a circle shaped filter. Best quality and most "
+"realistic, but slowest. Use only for areas where a lot of performance can be "
+"dedicated to post-processing (e.g. cutscenes)."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3690
msgid "Do not use a debug mode."
msgstr ""
-#: doc/classes/RenderingServer.xml:3558
+#: doc/classes/RenderingServer.xml:3693
msgid "Draw all objects as wireframe models."
msgstr ""
-#: doc/classes/RenderingServer.xml:3561
+#: doc/classes/RenderingServer.xml:3696
msgid ""
"Draw all objects in a way that displays how much overdraw is occurring. "
"Overdraw occurs when a section of pixels is drawn and shaded and then "
"another object covers it up. To optimize a scene, you should reduce overdraw."
msgstr ""
-#: doc/classes/RenderingServer.xml:3564
+#: doc/classes/RenderingServer.xml:3699
msgid ""
"Draw all objects without shading. Equivalent to setting all objects shaders "
"to [code]unshaded[/code]."
msgstr ""
-#: doc/classes/RenderingServer.xml:3567
+#: doc/classes/RenderingServer.xml:3702
msgid "The instance does not have a type."
msgstr ""
-#: doc/classes/RenderingServer.xml:3570
+#: doc/classes/RenderingServer.xml:3705
msgid "The instance is a mesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:3573
+#: doc/classes/RenderingServer.xml:3708
msgid "The instance is a multimesh."
msgstr ""
-#: doc/classes/RenderingServer.xml:3576
+#: doc/classes/RenderingServer.xml:3711
msgid "The instance is an immediate geometry."
msgstr ""
-#: doc/classes/RenderingServer.xml:3579
+#: doc/classes/RenderingServer.xml:3714
msgid "The instance is a particle emitter."
msgstr ""
-#: doc/classes/RenderingServer.xml:3582
+#: doc/classes/RenderingServer.xml:3717
msgid "The instance is a light."
msgstr ""
-#: doc/classes/RenderingServer.xml:3585
+#: doc/classes/RenderingServer.xml:3720
msgid "The instance is a reflection probe."
msgstr ""
-#: doc/classes/RenderingServer.xml:3588
+#: doc/classes/RenderingServer.xml:3723
+msgid "The instance is a decal."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3726
msgid "The instance is a GI probe."
msgstr ""
-#: doc/classes/RenderingServer.xml:3591
+#: doc/classes/RenderingServer.xml:3729
msgid "The instance is a lightmap capture."
msgstr ""
-#: doc/classes/RenderingServer.xml:3594
+#: doc/classes/RenderingServer.xml:3732
msgid "Represents the size of the [enum InstanceType] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3597
+#: doc/classes/RenderingServer.xml:3735
msgid ""
"A combination of the flags of geometry instances (mesh, multimesh, immediate "
"and particles)."
msgstr ""
-#: doc/classes/RenderingServer.xml:3600
+#: doc/classes/RenderingServer.xml:3738
msgid "Allows the instance to be used in baked lighting."
msgstr ""
-#: doc/classes/RenderingServer.xml:3605
+#: doc/classes/RenderingServer.xml:3741
+msgid "Allows the instance to be used with dynamic global illumination."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3744
msgid "When set, manually requests to draw geometry on next frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3608
+#: doc/classes/RenderingServer.xml:3747
msgid "Represents the size of the [enum InstanceFlags] enum."
msgstr ""
-#: doc/classes/RenderingServer.xml:3611
+#: doc/classes/RenderingServer.xml:3750
msgid "Disable shadows from this instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:3614
+#: doc/classes/RenderingServer.xml:3753
msgid "Cast shadows from this instance."
msgstr ""
-#: doc/classes/RenderingServer.xml:3617
+#: doc/classes/RenderingServer.xml:3756
msgid ""
"Disable backface culling when rendering the shadow of the object. This is "
"slightly slower but may result in more correct shadows."
msgstr ""
-#: doc/classes/RenderingServer.xml:3620
+#: doc/classes/RenderingServer.xml:3759
msgid ""
"Only render the shadows from the object. The object itself will not be drawn."
msgstr ""
-#: doc/classes/RenderingServer.xml:3623
+#: doc/classes/RenderingServer.xml:3762
msgid "The nine patch gets stretched where needed."
msgstr ""
-#: doc/classes/RenderingServer.xml:3626
+#: doc/classes/RenderingServer.xml:3765
msgid "The nine patch gets filled with tiles where needed."
msgstr ""
-#: doc/classes/RenderingServer.xml:3629
+#: doc/classes/RenderingServer.xml:3768
msgid ""
"The nine patch gets filled with tiles where needed and stretches them a bit "
"if needed."
msgstr ""
-#: doc/classes/RenderingServer.xml:3658
+#: doc/classes/RenderingServer.xml:3771
+msgid "Uses the default filter mode for this [Viewport]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3783 doc/classes/Viewport.xml:399
+msgid ""
+"The texture filter blends between the nearest 4 pixels and between the "
+"nearest 2 mipmaps."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3792
+msgid "Max value for [enum CanvasItemTextureFilter] enum."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3795
+msgid "Uses the default repeat mode for this [Viewport]."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3798 doc/classes/Viewport.xml:405
+msgid ""
+"Disables textures repeating. Instead, when reading UVs outside the 0-1 "
+"range, the value will be clamped to the edge of the texture, resulting in a "
+"stretched out look at the borders of the texture."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3804 doc/classes/Viewport.xml:411
+msgid ""
+"Flip the texture when repeating so that the edge lines up instead of "
+"abruptly changing."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3807
+msgid "Max value for [enum CanvasItemTextureRepeat] enum."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3810
msgid "Adds light color additive to the canvas."
msgstr ""
-#: doc/classes/RenderingServer.xml:3661
+#: doc/classes/RenderingServer.xml:3813
msgid "Adds light color subtractive to the canvas."
msgstr ""
-#: doc/classes/RenderingServer.xml:3664
+#: doc/classes/RenderingServer.xml:3816
msgid "The light adds color depending on transparency."
msgstr ""
-#: doc/classes/RenderingServer.xml:3667
+#: doc/classes/RenderingServer.xml:3819
msgid "The light adds color depending on mask."
msgstr ""
-#: doc/classes/RenderingServer.xml:3670
+#: doc/classes/RenderingServer.xml:3822
msgid "Do not apply a filter to canvas light shadows."
msgstr ""
-#: doc/classes/RenderingServer.xml:3673
+#: doc/classes/RenderingServer.xml:3825
msgid "Use PCF5 filtering to filter canvas light shadows."
msgstr ""
-#: doc/classes/RenderingServer.xml:3676
+#: doc/classes/RenderingServer.xml:3828
msgid "Use PCF13 filtering to filter canvas light shadows."
msgstr ""
-#: doc/classes/RenderingServer.xml:3681
+#: doc/classes/RenderingServer.xml:3831
+msgid "Max value of the [enum CanvasLightShadowFilter] enum."
+msgstr ""
+
+#: doc/classes/RenderingServer.xml:3834
msgid "Culling of the canvas occluder is disabled."
msgstr ""
-#: doc/classes/RenderingServer.xml:3684
+#: doc/classes/RenderingServer.xml:3837
msgid "Culling of the canvas occluder is clockwise."
msgstr ""
-#: doc/classes/RenderingServer.xml:3687
+#: doc/classes/RenderingServer.xml:3840
msgid "Culling of the canvas occluder is counterclockwise."
msgstr ""
-#: doc/classes/RenderingServer.xml:3690
+#: doc/classes/RenderingServer.xml:3901
msgid "The amount of objects in the frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3693
+#: doc/classes/RenderingServer.xml:3904
msgid "The amount of vertices in the frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3696
+#: doc/classes/RenderingServer.xml:3907
msgid "The amount of modified materials in the frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3699
+#: doc/classes/RenderingServer.xml:3910
msgid "The amount of shader rebinds in the frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3702
+#: doc/classes/RenderingServer.xml:3913
msgid "The amount of surface changes in the frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3705
+#: doc/classes/RenderingServer.xml:3916
msgid "The amount of draw calls in frame."
msgstr ""
-#: doc/classes/RenderingServer.xml:3720
+#: doc/classes/RenderingServer.xml:3931
msgid "Hardware supports shaders. This enum is currently unused in Godot 3.x."
msgstr ""
-#: doc/classes/RenderingServer.xml:3723
+#: doc/classes/RenderingServer.xml:3934
msgid ""
"Hardware supports multithreading. This enum is currently unused in Godot 3.x."
msgstr ""
@@ -44091,15 +44365,11 @@ msgid ""
"Physics > 2d[/b]."
msgstr ""
-#: doc/classes/RigidBody2D.xml:158 doc/classes/RigidBody3D.xml:174
-msgid "The body's mass."
-msgstr ""
-
#: doc/classes/RigidBody2D.xml:161
msgid "The body's mode. See [enum Mode] for possible values."
msgstr ""
-#: doc/classes/RigidBody2D.xml:164 doc/classes/RigidBody3D.xml:180
+#: doc/classes/RigidBody2D.xml:164 doc/classes/RigidBody3D.xml:181
#: doc/classes/StaticBody2D.xml:22 doc/classes/StaticBody3D.xml:22
msgid ""
"The physics material override for the body.\n"
@@ -44228,22 +44498,32 @@ msgid ""
"for a body."
msgstr ""
+#: doc/classes/RigidBody3D.xml:31
+msgid ""
+"Adds a constant directional force (i.e. acceleration) without affecting "
+"rotation.\n"
+"This is equivalent to [code]add_force(force, Vector3(0,0,0))[/code]."
+msgstr ""
+
#: doc/classes/RigidBody3D.xml:43
-msgid "Adds a constant force (i.e. acceleration)."
+msgid ""
+"Adds a constant directional force (i.e. acceleration).\n"
+"The position uses the rotation of the global coordinate system, but is "
+"centered at the object's origin."
msgstr ""
-#: doc/classes/RigidBody3D.xml:52
+#: doc/classes/RigidBody3D.xml:53
msgid ""
"Adds a constant rotational force (i.e. a motor) without affecting position."
msgstr ""
-#: doc/classes/RigidBody3D.xml:61
+#: doc/classes/RigidBody3D.xml:62
msgid ""
"Applies a directional impulse without affecting rotation.\n"
"This is equivalent to [code]apply_impulse(Vector3(0,0,0), impulse)[/code]."
msgstr ""
-#: doc/classes/RigidBody3D.xml:73
+#: doc/classes/RigidBody3D.xml:74
msgid ""
"Applies a positioned impulse to the body. An impulse is time independent! "
"Applying an impulse every frame would result in a framerate-dependent force. "
@@ -44252,19 +44532,19 @@ msgid ""
"at the object's origin."
msgstr ""
-#: doc/classes/RigidBody3D.xml:82
+#: doc/classes/RigidBody3D.xml:83
msgid ""
"Applies a torque impulse which will be affected by the body mass and shape. "
"This will rotate the body around the [code]impulse[/code] vector passed."
msgstr ""
-#: doc/classes/RigidBody3D.xml:91
+#: doc/classes/RigidBody3D.xml:92
msgid ""
"Returns [code]true[/code] if the specified linear or rotational axis is "
"locked."
msgstr ""
-#: doc/classes/RigidBody3D.xml:98
+#: doc/classes/RigidBody3D.xml:99
msgid ""
"Returns a list of the bodies colliding with this one. By default, number of "
"max contacts reported is at 0, see the [member contacts_reported] property "
@@ -44274,64 +44554,32 @@ msgid ""
"physics step. Consider using signals instead."
msgstr ""
-#: doc/classes/RigidBody3D.xml:110
+#: doc/classes/RigidBody3D.xml:111
msgid "Locks the specified linear or rotational axis."
msgstr ""
-#: doc/classes/RigidBody3D.xml:125
+#: doc/classes/RigidBody3D.xml:126
msgid "Damps RigidBody3D's rotational forces."
msgstr ""
-#: doc/classes/RigidBody3D.xml:128
+#: doc/classes/RigidBody3D.xml:129
msgid "RigidBody3D's rotational velocity."
msgstr ""
-#: doc/classes/RigidBody3D.xml:131
-msgid "Lock the body's rotation in the X axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:134
-msgid "Lock the body's rotation in the Y axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:137
-msgid "Lock the body's rotation in the Z axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:140
-msgid "Lock the body's movement in the X axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:143
-msgid "Lock the body's movement in the Y axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:146
-msgid "Lock the body's movement in the Z axis."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:149
-msgid ""
-"If [code]true[/code], the RigidBody3D will not calculate forces and will act "
-"as a static body while there is no movement. It will wake up when forces are "
-"applied through other collisions or when the [code]apply_impulse[/code] "
-"method is used."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:152
+#: doc/classes/RigidBody3D.xml:153
msgid ""
"If [code]true[/code], the RigidBody3D will emit signals when it collides "
"with another RigidBody3D."
msgstr ""
-#: doc/classes/RigidBody3D.xml:155
+#: doc/classes/RigidBody3D.xml:156
msgid ""
"The maximum contacts to report. Bodies can keep a log of the contacts with "
"other bodies, this is enabled by setting the maximum amount of contacts "
"reported to a number greater than 0."
msgstr ""
-#: doc/classes/RigidBody3D.xml:158
+#: doc/classes/RigidBody3D.xml:159
msgid ""
"If [code]true[/code], continuous collision detection is used.\n"
"Continuous collision detection tries to predict where a moving body will "
@@ -44341,7 +44589,7 @@ msgid ""
"faster to compute, but can miss small, fast-moving objects."
msgstr ""
-#: doc/classes/RigidBody3D.xml:162
+#: doc/classes/RigidBody3D.xml:163
msgid ""
"If [code]true[/code], internal force integration will be disabled (like "
"gravity or air friction) for this body. Other than collision response, the "
@@ -44349,7 +44597,7 @@ msgid ""
"function, if defined."
msgstr ""
-#: doc/classes/RigidBody3D.xml:165
+#: doc/classes/RigidBody3D.xml:166
msgid ""
"This is multiplied by the global 3D gravity setting found in [b]Project > "
"Project Settings > Physics > 3d[/b] to produce RigidBody3D's gravity. For "
@@ -44357,14 +44605,14 @@ msgid ""
"and 0.5 will apply half gravity to this object."
msgstr ""
-#: doc/classes/RigidBody3D.xml:168
+#: doc/classes/RigidBody3D.xml:169
msgid ""
"The body's linear damp. Cannot be less than -1.0. If this value is different "
"from -1.0, any linear damp derived from the world or areas will be "
"overridden."
msgstr ""
-#: doc/classes/RigidBody3D.xml:171
+#: doc/classes/RigidBody3D.xml:172
msgid ""
"The body's linear velocity. Can be used sporadically, but [b]don't set this "
"every frame[/b], because physics may run in another thread and runs at a "
@@ -44372,35 +44620,29 @@ msgid ""
"for precise control of the body state."
msgstr ""
-#: doc/classes/RigidBody3D.xml:177
+#: doc/classes/RigidBody3D.xml:178
msgid "The body mode. See [enum Mode] for possible values."
msgstr ""
-#: doc/classes/RigidBody3D.xml:184
+#: doc/classes/RigidBody3D.xml:185
msgid ""
"If [code]true[/code], the body is sleeping and will not calculate forces "
"until woken up by a collision or the [code]apply_impulse[/code] method."
msgstr ""
-#: doc/classes/RigidBody3D.xml:187
-msgid ""
-"The body's weight based on its mass and the global 3D gravity. Global values "
-"are set in [b]Project > Project Settings > Physics > 3d[/b]."
-msgstr ""
-
-#: doc/classes/RigidBody3D.xml:195
+#: doc/classes/RigidBody3D.xml:196
msgid ""
"Emitted when a body enters into contact with this one. Contact monitor and "
"contacts reported must be enabled for this to work."
msgstr ""
-#: doc/classes/RigidBody3D.xml:202
+#: doc/classes/RigidBody3D.xml:203
msgid ""
"Emitted when a body shape exits contact with this one. Contact monitor and "
"contacts reported must be enabled for this to work."
msgstr ""
-#: doc/classes/RigidBody3D.xml:215
+#: doc/classes/RigidBody3D.xml:216
msgid ""
"Emitted when a body enters into contact with this one. Contact monitor and "
"contacts reported must be enabled for this to work.\n"
@@ -44410,7 +44652,7 @@ msgid ""
"([code]local_shape[/code]) the other body collided with."
msgstr ""
-#: doc/classes/RigidBody3D.xml:229
+#: doc/classes/RigidBody3D.xml:230
msgid ""
"Emitted when a body shape exits contact with this one. Contact monitor and "
"contacts reported must be enabled for this to work.\n"
@@ -44420,30 +44662,30 @@ msgid ""
"([code]local_shape[/code]) the other body stopped colliding with."
msgstr ""
-#: doc/classes/RigidBody3D.xml:235
+#: doc/classes/RigidBody3D.xml:236
msgid ""
"Emitted when the body changes its sleeping state. Either by sleeping or "
"waking up."
msgstr ""
-#: doc/classes/RigidBody3D.xml:241
+#: doc/classes/RigidBody3D.xml:242
msgid ""
"Rigid body mode. This is the \"natural\" state of a rigid body. It is "
"affected by forces, and can move, rotate, and be affected by user code."
msgstr ""
-#: doc/classes/RigidBody3D.xml:244
+#: doc/classes/RigidBody3D.xml:245
msgid ""
"Static mode. The body behaves like a [StaticBody3D], and can only move by "
"user code."
msgstr ""
-#: doc/classes/RigidBody3D.xml:247
+#: doc/classes/RigidBody3D.xml:248
msgid ""
"Character body mode. This behaves like a rigid body, but can not rotate."
msgstr ""
-#: doc/classes/RigidBody3D.xml:250
+#: doc/classes/RigidBody3D.xml:251
msgid ""
"Kinematic body mode. The body behaves like a [KinematicBody3D], and can only "
"move by user code."
@@ -45067,27 +45309,33 @@ msgstr ""
msgid "Godot editor's script editor."
msgstr ""
-#: doc/classes/ScriptEditor.xml:39
+#: doc/classes/ScriptEditor.xml:7
+msgid ""
+"[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access "
+"the singleton using [method EditorInterface.get_script_editor]."
+msgstr ""
+
+#: doc/classes/ScriptEditor.xml:40
msgid "Returns a [Script] that is currently active in editor."
msgstr ""
-#: doc/classes/ScriptEditor.xml:56
+#: doc/classes/ScriptEditor.xml:57
msgid ""
"Returns an array with all [Script] objects which are currently open in "
"editor."
msgstr ""
-#: doc/classes/ScriptEditor.xml:65
+#: doc/classes/ScriptEditor.xml:66
msgid "Goes to the specified line in the current script."
msgstr ""
-#: doc/classes/ScriptEditor.xml:84
+#: doc/classes/ScriptEditor.xml:85
msgid ""
"Emitted when user changed active script. Argument is a freshly activated "
"[Script]."
msgstr ""
-#: doc/classes/ScriptEditor.xml:91
+#: doc/classes/ScriptEditor.xml:92
msgid ""
"Emitted when editor is about to close the active script. Argument is a "
"[Script] that is going to be closed."
@@ -45149,7 +45397,7 @@ msgid ""
"visible."
msgstr ""
-#: doc/classes/ScrollContainer.xml:37 doc/classes/TextEdit.xml:441
+#: doc/classes/ScrollContainer.xml:37 doc/classes/TextEdit.xml:442
msgid "The current horizontal scroll value."
msgstr ""
@@ -45157,7 +45405,7 @@ msgstr ""
msgid "If [code]true[/code], enables horizontal scrolling."
msgstr ""
-#: doc/classes/ScrollContainer.xml:43 doc/classes/TextEdit.xml:444
+#: doc/classes/ScrollContainer.xml:43 doc/classes/TextEdit.xml:445
msgid "The current vertical scroll value."
msgstr ""
@@ -45687,7 +45935,10 @@ msgid ""
"Uses high quality importance sampling to process the radiance map. In "
"general, this results in much higher quality than [constant "
"PROCESS_MODE_REALTIME] but takes much longer to generate. This should not be "
-"used if you plan on changing the sky at runtime."
+"used if you plan on changing the sky at runtime. If you are finding that the "
+"reflection is not blurry enough and is showing sparkles or fireflies, try "
+"increasing [member ProjectSettings.rendering/quality/reflections/"
+"ggx_samples]."
msgstr ""
#: doc/classes/Sky.xml:55
@@ -47881,65 +48132,65 @@ msgid ""
msgstr ""
#: doc/classes/SubViewport.xml:13
-msgid "If [code]true[/code], the sub-viewport will be used in AR/VR process."
-msgstr ""
-
-#: doc/classes/SubViewport.xml:16
msgid "The clear mode when the sub-viewport is used as a render target."
msgstr ""
-#: doc/classes/SubViewport.xml:19
+#: doc/classes/SubViewport.xml:16
msgid "The update mode when the sub-viewport is used as a render target."
msgstr ""
-#: doc/classes/SubViewport.xml:22
+#: doc/classes/SubViewport.xml:19
msgid "The width and height of the sub-viewport."
msgstr ""
-#: doc/classes/SubViewport.xml:25
+#: doc/classes/SubViewport.xml:22
msgid ""
"The 2D size override of the sub-viewport. If either the width or height is "
"[code]0[/code], the override is disabled."
msgstr ""
-#: doc/classes/SubViewport.xml:28
+#: doc/classes/SubViewport.xml:25
msgid "If [code]true[/code], the 2D size override affects stretch as well."
msgstr ""
+#: doc/classes/SubViewport.xml:28
+msgid "If [code]true[/code], the sub-viewport will be used in AR/VR process."
+msgstr ""
+
#: doc/classes/SubViewport.xml:33
-msgid "Do not update the render target."
+msgid "Always clear the render target before drawing."
msgstr ""
#: doc/classes/SubViewport.xml:36
-msgid ""
-"Update the render target once, then switch to [constant UPDATE_DISABLED]."
+msgid "Never clear the render target."
msgstr ""
#: doc/classes/SubViewport.xml:39
msgid ""
-"Update the render target only when it is visible. This is the default value."
+"Clear the render target next frame, then switch to [constant "
+"CLEAR_MODE_NEVER]."
msgstr ""
#: doc/classes/SubViewport.xml:42
-msgid "Update the render target only when the its parent is visible."
+msgid "Do not update the render target."
msgstr ""
#: doc/classes/SubViewport.xml:45
-msgid "Always update the render target."
+msgid ""
+"Update the render target once, then switch to [constant UPDATE_DISABLED]."
msgstr ""
#: doc/classes/SubViewport.xml:48
-msgid "Always clear the render target before drawing."
+msgid ""
+"Update the render target only when it is visible. This is the default value."
msgstr ""
#: doc/classes/SubViewport.xml:51
-msgid "Never clear the render target."
+msgid "Update the render target only when the its parent is visible."
msgstr ""
#: doc/classes/SubViewport.xml:54
-msgid ""
-"Clear the render target next frame, then switch to [constant "
-"CLEAR_MODE_NEVER]."
+msgid "Always update the render target."
msgstr ""
#: doc/classes/SubViewportContainer.xml:4
@@ -47994,85 +48245,90 @@ msgid ""
"information to a mesh.\n"
"Additionally, the attributes used before the first vertex is added determine "
"the format of the mesh. For example, if you only add UVs to the first "
-"vertex, you cannot add color to any of the subsequent vertices."
+"vertex, you cannot add color to any of the subsequent vertices.\n"
+"See also [ArrayMesh], [ImmediateGeometry3D] and [MeshDataTool] for "
+"procedural geometry generation.\n"
+"[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-"
+"OpenGL/Face-culling]winding order[/url] for front faces of triangle "
+"primitive modes."
msgstr ""
-#: doc/classes/SurfaceTool.xml:28
+#: doc/classes/SurfaceTool.xml:30
msgid ""
"Adds an array of bones for the next vertex to use. [code]bones[/code] must "
"contain 4 integers."
msgstr ""
-#: doc/classes/SurfaceTool.xml:37
+#: doc/classes/SurfaceTool.xml:39
msgid "Specifies a [Color] for the next vertex to use."
msgstr ""
-#: doc/classes/SurfaceTool.xml:46
+#: doc/classes/SurfaceTool.xml:48
msgid ""
"Adds an index to index array if you are using indexed vertices. Does not "
"need to be called before adding vertices."
msgstr ""
-#: doc/classes/SurfaceTool.xml:55
+#: doc/classes/SurfaceTool.xml:57
msgid "Specifies a normal for the next vertex to use."
msgstr ""
-#: doc/classes/SurfaceTool.xml:64
+#: doc/classes/SurfaceTool.xml:66
msgid ""
"Specifies whether the current vertex (if using only vertex arrays) or "
"current index (if also using index arrays) should use smooth normals for "
"normal calculation."
msgstr ""
-#: doc/classes/SurfaceTool.xml:73
+#: doc/classes/SurfaceTool.xml:75
msgid "Specifies a tangent for the next vertex to use."
msgstr ""
-#: doc/classes/SurfaceTool.xml:92
+#: doc/classes/SurfaceTool.xml:94
msgid ""
"Inserts a triangle fan made of array data into [Mesh] being constructed.\n"
"Requires the primitive type be set to [constant Mesh.PRIMITIVE_TRIANGLES]."
msgstr ""
-#: doc/classes/SurfaceTool.xml:102
+#: doc/classes/SurfaceTool.xml:104
msgid "Specifies a set of UV coordinates to use for the next vertex."
msgstr ""
-#: doc/classes/SurfaceTool.xml:111
+#: doc/classes/SurfaceTool.xml:113
msgid ""
"Specifies an optional second set of UV coordinates to use for the next "
"vertex."
msgstr ""
-#: doc/classes/SurfaceTool.xml:120
+#: doc/classes/SurfaceTool.xml:122
msgid ""
"Specifies the position of current vertex. Should be called after specifying "
"other vertex properties (e.g. Color, UV)."
msgstr ""
-#: doc/classes/SurfaceTool.xml:129
+#: doc/classes/SurfaceTool.xml:131
msgid ""
"Specifies weight values for next vertex to use. [code]weights[/code] must "
"contain 4 values."
msgstr ""
-#: doc/classes/SurfaceTool.xml:142
+#: doc/classes/SurfaceTool.xml:144
msgid ""
"Append vertices from a given [Mesh] surface onto the current vertex array "
"with specified [Transform]."
msgstr ""
-#: doc/classes/SurfaceTool.xml:151
+#: doc/classes/SurfaceTool.xml:153
msgid ""
"Called before adding any vertices. Takes the primitive type as an argument "
"(e.g. [constant Mesh.PRIMITIVE_TRIANGLES])."
msgstr ""
-#: doc/classes/SurfaceTool.xml:158
+#: doc/classes/SurfaceTool.xml:160
msgid "Clear all information passed into the surface tool so far."
msgstr ""
-#: doc/classes/SurfaceTool.xml:169
+#: doc/classes/SurfaceTool.xml:171
msgid ""
"Returns a constructed [ArrayMesh] from current information passed in. If an "
"existing [ArrayMesh] is passed in as an argument, will add an extra surface "
@@ -48082,28 +48338,28 @@ msgid ""
"flags."
msgstr ""
-#: doc/classes/SurfaceTool.xml:177
+#: doc/classes/SurfaceTool.xml:179
msgid ""
"Commits the data to the same format used by [method ArrayMesh."
"add_surface_from_arrays]. This way you can further process the mesh data "
"using the [ArrayMesh] API."
msgstr ""
-#: doc/classes/SurfaceTool.xml:188
+#: doc/classes/SurfaceTool.xml:190
msgid "Creates a vertex array from an existing [Mesh]."
msgstr ""
-#: doc/classes/SurfaceTool.xml:201
+#: doc/classes/SurfaceTool.xml:203
msgid ""
"Creates a vertex array from the specified blend shape of an existing [Mesh]. "
"This can be used to extract a specific pose from a blend shape."
msgstr ""
-#: doc/classes/SurfaceTool.xml:208
+#: doc/classes/SurfaceTool.xml:210
msgid "Removes the index array by expanding the vertex array."
msgstr ""
-#: doc/classes/SurfaceTool.xml:217
+#: doc/classes/SurfaceTool.xml:219
msgid ""
"Generates normals from vertices so you do not have to do it manually. If "
"[code]flip[/code] is [code]true[/code], the resulting normals will be "
@@ -48111,19 +48367,19 @@ msgid ""
"Requires the primitive type to be set to [constant Mesh.PRIMITIVE_TRIANGLES]."
msgstr ""
-#: doc/classes/SurfaceTool.xml:225
+#: doc/classes/SurfaceTool.xml:227
msgid ""
"Generates a tangent vector for each vertex. Requires that each vertex have "
"UVs and normals set already."
msgstr ""
-#: doc/classes/SurfaceTool.xml:232
+#: doc/classes/SurfaceTool.xml:234
msgid ""
"Shrinks the vertex array by creating an index array (avoids reusing "
"vertices)."
msgstr ""
-#: doc/classes/SurfaceTool.xml:241
+#: doc/classes/SurfaceTool.xml:243
msgid "Sets [Material] to be used by the [Mesh] you are constructing."
msgstr ""
@@ -48157,7 +48413,7 @@ msgid "Returns the previously active tab index."
msgstr ""
#: doc/classes/TabContainer.xml:42
-msgid "Returns the currently visible tab's [Control] node."
+msgid "Returns the [Control] node from the tab at index [code]tab_idx[/code]."
msgstr ""
#: doc/classes/TabContainer.xml:49 doc/classes/Tabs.xml:50
@@ -48826,151 +49082,163 @@ msgstr ""
msgid "If [code]true[/code], the line containing the cursor is highlighted."
msgstr ""
-#: doc/classes/TextEdit.xml:438
+#: doc/classes/TextEdit.xml:436
+msgid ""
+"If [code]true[/code], custom [code]font_color_selected[/code] will be used "
+"for selected text."
+msgstr ""
+
+#: doc/classes/TextEdit.xml:439
msgid ""
"If [code]true[/code], read-only mode is enabled. Existing text cannot be "
"modified and new text cannot be added."
msgstr ""
-#: doc/classes/TextEdit.xml:451
+#: doc/classes/TextEdit.xml:452
msgid ""
"If [code]true[/code], line numbers are displayed to the left of the text."
msgstr ""
-#: doc/classes/TextEdit.xml:454
+#: doc/classes/TextEdit.xml:455
msgid ""
"If [code]true[/code], sets the [code]step[/code] of the scrollbars to "
"[code]0.25[/code] which results in smoother scrolling."
msgstr ""
-#: doc/classes/TextEdit.xml:457
+#: doc/classes/TextEdit.xml:458
msgid ""
"If [code]true[/code], any custom color properties that have been set for "
"this [TextEdit] will be visible."
msgstr ""
-#: doc/classes/TextEdit.xml:460
+#: doc/classes/TextEdit.xml:461
msgid "String value of the [TextEdit]."
msgstr ""
-#: doc/classes/TextEdit.xml:463
+#: doc/classes/TextEdit.xml:464
msgid "Vertical scroll sensitivity."
msgstr ""
-#: doc/classes/TextEdit.xml:466
+#: doc/classes/TextEdit.xml:467
msgid ""
"If [code]true[/code], enables text wrapping when it goes beyond the edge of "
"what is visible."
msgstr ""
-#: doc/classes/TextEdit.xml:474
+#: doc/classes/TextEdit.xml:475
msgid "Emitted when a breakpoint is placed via the breakpoint gutter."
msgstr ""
-#: doc/classes/TextEdit.xml:479
+#: doc/classes/TextEdit.xml:480
msgid "Emitted when the cursor changes."
msgstr ""
-#: doc/classes/TextEdit.xml:488
+#: doc/classes/TextEdit.xml:489
msgid "Emitted when the info icon is clicked."
msgstr ""
-#: doc/classes/TextEdit.xml:519
+#: doc/classes/TextEdit.xml:520
msgid "Match case when searching."
msgstr ""
-#: doc/classes/TextEdit.xml:522
+#: doc/classes/TextEdit.xml:523
msgid "Match whole words when searching."
msgstr ""
-#: doc/classes/TextEdit.xml:525
+#: doc/classes/TextEdit.xml:526
msgid "Search from end to beginning."
msgstr ""
-#: doc/classes/TextEdit.xml:528
+#: doc/classes/TextEdit.xml:529
msgid "Used to access the result column from [method search]."
msgstr ""
-#: doc/classes/TextEdit.xml:531
+#: doc/classes/TextEdit.xml:532
msgid "Used to access the result line from [method search]."
msgstr ""
-#: doc/classes/TextEdit.xml:540
+#: doc/classes/TextEdit.xml:541
msgid ""
"Pastes the clipboard text over the selected text (or at the cursor's "
"position)."
msgstr ""
-#: doc/classes/TextEdit.xml:543
+#: doc/classes/TextEdit.xml:544
msgid "Erases the whole [TextEdit] text."
msgstr ""
-#: doc/classes/TextEdit.xml:546
+#: doc/classes/TextEdit.xml:547
msgid "Selects the whole [TextEdit] text."
msgstr ""
-#: doc/classes/TextEdit.xml:552
+#: doc/classes/TextEdit.xml:553
msgid "Redoes the previous action."
msgstr ""
-#: doc/classes/TextEdit.xml:560
+#: doc/classes/TextEdit.xml:561
msgid ""
"Sets the background [Color] of this [TextEdit]. [member syntax_highlighting] "
"has to be enabled."
msgstr ""
-#: doc/classes/TextEdit.xml:563
+#: doc/classes/TextEdit.xml:564
msgid ""
"Sets the [Color] of the bookmark marker. [member syntax_highlighting] has to "
"be enabled."
msgstr ""
-#: doc/classes/TextEdit.xml:568 doc/classes/TextEdit.xml:595
+#: doc/classes/TextEdit.xml:569 doc/classes/TextEdit.xml:596
msgid ""
"Sets the [Color] of the breakpoints. [member breakpoint_gutter] has to be "
"enabled."
msgstr ""
-#: doc/classes/TextEdit.xml:606
+#: doc/classes/TextEdit.xml:607
msgid "Sets the default [Font]."
msgstr ""
-#: doc/classes/TextEdit.xml:609
+#: doc/classes/TextEdit.xml:610
msgid "Sets the font [Color]."
msgstr ""
-#: doc/classes/TextEdit.xml:618
+#: doc/classes/TextEdit.xml:615
+msgid ""
+"Sets the [Color] of the selected text. [member override_selected_font_color] "
+"has to be enabled."
+msgstr ""
+
+#: doc/classes/TextEdit.xml:620
msgid ""
"Sets the [Color] of the line numbers. [member show_line_numbers] has to be "
"enabled."
msgstr ""
-#: doc/classes/TextEdit.xml:621
+#: doc/classes/TextEdit.xml:623
msgid "Sets the spacing between the lines."
msgstr ""
-#: doc/classes/TextEdit.xml:624
+#: doc/classes/TextEdit.xml:626
msgid "Sets the [Color] of marked text."
msgstr ""
-#: doc/classes/TextEdit.xml:629
+#: doc/classes/TextEdit.xml:631
msgid "Sets the [StyleBox] of this [TextEdit]."
msgstr ""
-#: doc/classes/TextEdit.xml:634
+#: doc/classes/TextEdit.xml:636
msgid ""
"Sets the [StyleBox] of this [TextEdit] when [member readonly] is enabled."
msgstr ""
-#: doc/classes/TextEdit.xml:639
+#: doc/classes/TextEdit.xml:641
msgid "Sets the highlight [Color] of text selections."
msgstr ""
-#: doc/classes/TextEdit.xml:646
+#: doc/classes/TextEdit.xml:648
msgid "Sets a custom [Texture2D] for tab text characters."
msgstr ""
-#: doc/classes/TextEdit.xml:649
+#: doc/classes/TextEdit.xml:651
msgid ""
"Sets the highlight [Color] of multiple occurrences. [member "
"highlight_all_occurrences] has to be enabled."
@@ -49642,8 +49910,8 @@ msgstr ""
#: doc/classes/TileMap.xml:46
msgid ""
-"Returns the coordinate of the autotile variation in the tileset. Returns a "
-"zero vector if the cell doesn't have autotiling."
+"Returns the coordinate (subtile column and row) of the autotile variation in "
+"the tileset. Returns a zero vector if the cell doesn't have autotiling."
msgstr ""
#: doc/classes/TileMap.xml:55
@@ -49700,7 +49968,8 @@ msgid ""
"Sets the tile index for the cell given by a Vector2.\n"
"An index of [code]-1[/code] clears the cell.\n"
"Optionally, the tile can also be flipped, transposed, or given autotile "
-"coordinates.\n"
+"coordinates. The autotile coordinate refers to the column and row of the "
+"subtile.\n"
"[b]Note:[/b] Data such as navigation polygons and collision shapes are not "
"immediately updated for performance reasons.\n"
"If you need these to be immediately updated, you can call [method "
@@ -50507,9 +50776,10 @@ msgid ""
"using matrix multiplication. The axis must be a normalized vector."
msgstr ""
-#: doc/classes/Transform.xml:138 doc/classes/Transform2D.xml:140
+#: doc/classes/Transform.xml:138
msgid ""
-"Scales the transform by the given scale factor, using matrix multiplication."
+"Scales basis and origin of the transform by the given scale factor, using "
+"matrix multiplication."
msgstr ""
#: doc/classes/Transform.xml:147 doc/classes/Transform2D.xml:149
@@ -50619,6 +50889,11 @@ msgid ""
"multiplication."
msgstr ""
+#: doc/classes/Transform2D.xml:140
+msgid ""
+"Scales the transform by the given scale factor, using matrix multiplication."
+msgstr ""
+
#: doc/classes/Transform2D.xml:159
msgid ""
"Transforms the given [Vector2], [Rect2], or [PackedVector2Array] by this "
@@ -50776,7 +51051,8 @@ msgid ""
"[/codeblock]\n"
"To iterate over all the [TreeItem] objects in a [Tree] object, use [method "
"TreeItem.get_next] and [method TreeItem.get_children] after getting the root "
-"through [method get_root]."
+"through [method get_root]. You can use [method Object.free] on a [TreeItem] "
+"to remove it from the [Tree]."
msgstr ""
#: doc/classes/Tree.xml:28
@@ -51262,10 +51538,11 @@ msgstr ""
#: doc/classes/TreeItem.xml:7
msgid ""
"Control for a single item inside a [Tree]. May have child [TreeItem]s and be "
-"styled as well as contain buttons."
+"styled as well as contain buttons.\n"
+"You can remove a [TreeItem] by using [method Object.free]."
msgstr ""
-#: doc/classes/TreeItem.xml:26
+#: doc/classes/TreeItem.xml:27
msgid ""
"Adds a button with [Texture2D] [code]button[/code] at column [code]column[/"
"code]. The [code]button_idx[/code] index is used to identify the button when "
@@ -51275,89 +51552,89 @@ msgid ""
"have a [code]tooltip[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:35
+#: doc/classes/TreeItem.xml:36
msgid ""
"Calls the [code]method[/code] on the actual TreeItem and its children "
"recursively. Pass parameters as a comma separated list."
msgstr ""
-#: doc/classes/TreeItem.xml:44
+#: doc/classes/TreeItem.xml:45
msgid "Resets the background color for the given column to default."
msgstr ""
-#: doc/classes/TreeItem.xml:53
+#: doc/classes/TreeItem.xml:54
msgid "Resets the color for the given column to default."
msgstr ""
-#: doc/classes/TreeItem.xml:62
+#: doc/classes/TreeItem.xml:63
msgid "Deselects the given column."
msgstr ""
-#: doc/classes/TreeItem.xml:73
+#: doc/classes/TreeItem.xml:74
msgid ""
"Removes the button at index [code]button_idx[/code] in column [code]column[/"
"code]."
msgstr ""
-#: doc/classes/TreeItem.xml:84
+#: doc/classes/TreeItem.xml:85
msgid ""
"Returns the [Texture2D] of the button at index [code]button_idx[/code] in "
"column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:93
+#: doc/classes/TreeItem.xml:94
msgid ""
"Returns the number of buttons in column [code]column[/code]. May be used to "
"get the most recently added button's index, if no index was specified."
msgstr ""
-#: doc/classes/TreeItem.xml:104
+#: doc/classes/TreeItem.xml:105
msgid ""
"Returns the tooltip string for the button at index [code]button_idx[/code] "
"in column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:113
+#: doc/classes/TreeItem.xml:114
msgid "Returns the column's cell mode."
msgstr ""
-#: doc/classes/TreeItem.xml:120
+#: doc/classes/TreeItem.xml:121
msgid "Returns the TreeItem's child items."
msgstr ""
-#: doc/classes/TreeItem.xml:129
+#: doc/classes/TreeItem.xml:130
msgid "Returns the custom background color of column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:138
+#: doc/classes/TreeItem.xml:139
msgid "Returns the custom color of column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:147
+#: doc/classes/TreeItem.xml:148
msgid "Returns [code]true[/code] if [code]expand_right[/code] is set."
msgstr ""
-#: doc/classes/TreeItem.xml:156
+#: doc/classes/TreeItem.xml:157
msgid "Returns the given column's icon [Texture2D]. Error if no icon is set."
msgstr ""
-#: doc/classes/TreeItem.xml:165
+#: doc/classes/TreeItem.xml:166
msgid "Returns the column's icon's maximum width."
msgstr ""
-#: doc/classes/TreeItem.xml:174
+#: doc/classes/TreeItem.xml:175
msgid "Returns the [Color] modulating the column's icon."
msgstr ""
-#: doc/classes/TreeItem.xml:183
+#: doc/classes/TreeItem.xml:184
msgid "Returns the icon [Texture2D] region as [Rect2]."
msgstr ""
-#: doc/classes/TreeItem.xml:198
+#: doc/classes/TreeItem.xml:199
msgid "Returns the next TreeItem in the tree."
msgstr ""
-#: doc/classes/TreeItem.xml:207
+#: doc/classes/TreeItem.xml:208
msgid ""
"Returns the next visible TreeItem in the tree.\n"
"If [code]wrap[/code] is enabled, the method will wrap around to the first "
@@ -51365,15 +51642,15 @@ msgid ""
"otherwise it returns [code]null[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:215
+#: doc/classes/TreeItem.xml:216
msgid "Returns the parent TreeItem."
msgstr ""
-#: doc/classes/TreeItem.xml:222
+#: doc/classes/TreeItem.xml:223
msgid "Returns the previous TreeItem in the tree."
msgstr ""
-#: doc/classes/TreeItem.xml:231
+#: doc/classes/TreeItem.xml:232
msgid ""
"Returns the previous visible TreeItem in the tree.\n"
"If [code]wrap[/code] is enabled, the method will wrap around to the last "
@@ -51381,89 +51658,92 @@ msgid ""
"otherwise it returns [code]null[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:257
+#: doc/classes/TreeItem.xml:258
msgid "Returns the given column's text."
msgstr ""
-#: doc/classes/TreeItem.xml:266
+#: doc/classes/TreeItem.xml:267
msgid "Returns the given column's text alignment."
msgstr ""
-#: doc/classes/TreeItem.xml:275
+#: doc/classes/TreeItem.xml:276
msgid "Returns the given column's tooltip."
msgstr ""
-#: doc/classes/TreeItem.xml:286
+#: doc/classes/TreeItem.xml:287
msgid ""
"Returns [code]true[/code] if the button at index [code]button_idx[/code] for "
"the given column is disabled."
msgstr ""
-#: doc/classes/TreeItem.xml:295
+#: doc/classes/TreeItem.xml:296
msgid "Returns [code]true[/code] if the given column is checked."
msgstr ""
-#: doc/classes/TreeItem.xml:312
+#: doc/classes/TreeItem.xml:313
msgid "Returns [code]true[/code] if column [code]column[/code] is editable."
msgstr ""
-#: doc/classes/TreeItem.xml:321
+#: doc/classes/TreeItem.xml:322
msgid "Returns [code]true[/code] if column [code]column[/code] is selectable."
msgstr ""
-#: doc/classes/TreeItem.xml:330
+#: doc/classes/TreeItem.xml:331
msgid "Returns [code]true[/code] if column [code]column[/code] is selected."
msgstr ""
-#: doc/classes/TreeItem.xml:337
+#: doc/classes/TreeItem.xml:338
msgid "Moves this TreeItem to the bottom in the [Tree] hierarchy."
msgstr ""
-#: doc/classes/TreeItem.xml:344
+#: doc/classes/TreeItem.xml:345
msgid "Moves this TreeItem to the top in the [Tree] hierarchy."
msgstr ""
-#: doc/classes/TreeItem.xml:353
-msgid "Removes the given child TreeItem."
+#: doc/classes/TreeItem.xml:354
+msgid ""
+"Removes the given child [TreeItem] and all its children from the [Tree]. "
+"Note that it doesn't free the item from memory, so it can be reused later. "
+"To completely remove a [TreeItem] use [method Object.free]."
msgstr ""
-#: doc/classes/TreeItem.xml:362
+#: doc/classes/TreeItem.xml:363
msgid "Selects the column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:375
+#: doc/classes/TreeItem.xml:376
msgid ""
"Sets the given column's button [Texture2D] at index [code]button_idx[/code] "
"to [code]button[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:388
+#: doc/classes/TreeItem.xml:389
msgid ""
"If [code]true[/code], disables the button at index [code]button_idx[/code] "
"in column [code]column[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:399
+#: doc/classes/TreeItem.xml:400
msgid ""
"Sets the given column's cell mode to [code]mode[/code]. See [enum "
"TreeCellMode] constants."
msgstr ""
-#: doc/classes/TreeItem.xml:410
+#: doc/classes/TreeItem.xml:411
msgid "If [code]true[/code], the column [code]column[/code] is checked."
msgstr ""
-#: doc/classes/TreeItem.xml:433
+#: doc/classes/TreeItem.xml:434
msgid ""
"Sets the given column's custom background color and whether to just use it "
"as an outline."
msgstr ""
-#: doc/classes/TreeItem.xml:444
+#: doc/classes/TreeItem.xml:445
msgid "Sets the given column's custom color."
msgstr ""
-#: doc/classes/TreeItem.xml:457
+#: doc/classes/TreeItem.xml:458
msgid ""
"Sets the given column's custom draw callback to [code]callback[/code] method "
"on [code]object[/code].\n"
@@ -51471,82 +51751,82 @@ msgid ""
"is drawn and its position and size as a [Rect2]."
msgstr ""
-#: doc/classes/TreeItem.xml:469
+#: doc/classes/TreeItem.xml:470
msgid "If [code]true[/code], column [code]column[/code] is editable."
msgstr ""
-#: doc/classes/TreeItem.xml:480
+#: doc/classes/TreeItem.xml:481
msgid ""
"If [code]true[/code], column [code]column[/code] is expanded to the right."
msgstr ""
-#: doc/classes/TreeItem.xml:491
+#: doc/classes/TreeItem.xml:492
msgid "Sets the given column's icon [Texture2D]."
msgstr ""
-#: doc/classes/TreeItem.xml:502
+#: doc/classes/TreeItem.xml:503
msgid "Sets the given column's icon's maximum width."
msgstr ""
-#: doc/classes/TreeItem.xml:513
+#: doc/classes/TreeItem.xml:514
msgid "Modulates the given column's icon with [code]modulate[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:524
+#: doc/classes/TreeItem.xml:525
msgid "Sets the given column's icon's texture region."
msgstr ""
-#: doc/classes/TreeItem.xml:571
+#: doc/classes/TreeItem.xml:572
msgid "If [code]true[/code], the given column is selectable."
msgstr ""
-#: doc/classes/TreeItem.xml:592
+#: doc/classes/TreeItem.xml:593
msgid ""
"Sets the given column's text alignment. See [enum TextAlign] for possible "
"values."
msgstr ""
-#: doc/classes/TreeItem.xml:603
+#: doc/classes/TreeItem.xml:604
msgid "Sets the given column's tooltip text."
msgstr ""
-#: doc/classes/TreeItem.xml:609
+#: doc/classes/TreeItem.xml:610
msgid "If [code]true[/code], the TreeItem is collapsed."
msgstr ""
-#: doc/classes/TreeItem.xml:612
+#: doc/classes/TreeItem.xml:613
msgid "The custom minimum height."
msgstr ""
-#: doc/classes/TreeItem.xml:615
+#: doc/classes/TreeItem.xml:616
msgid "If [code]true[/code], folding is disabled for this TreeItem."
msgstr ""
-#: doc/classes/TreeItem.xml:620
+#: doc/classes/TreeItem.xml:621
msgid "Cell contains a string."
msgstr ""
-#: doc/classes/TreeItem.xml:623
+#: doc/classes/TreeItem.xml:624
msgid "Cell can be checked."
msgstr ""
-#: doc/classes/TreeItem.xml:626
+#: doc/classes/TreeItem.xml:627
msgid "Cell contains a range."
msgstr ""
-#: doc/classes/TreeItem.xml:629
+#: doc/classes/TreeItem.xml:630
msgid "Cell contains an icon."
msgstr ""
-#: doc/classes/TreeItem.xml:634
+#: doc/classes/TreeItem.xml:635
msgid "Align text to the left. See [code]set_text_align()[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:637
+#: doc/classes/TreeItem.xml:638
msgid "Center text. See [code]set_text_align()[/code]."
msgstr ""
-#: doc/classes/TreeItem.xml:640
+#: doc/classes/TreeItem.xml:641
msgid "Align text to the right. See [code]set_text_align()[/code]."
msgstr ""
@@ -51572,8 +51852,8 @@ msgid ""
"know the final values in advance. For example, interpolating a dynamically-"
"chosen camera zoom value is best done with a [Tween] node; it would be "
"difficult to do the same thing with an [AnimationPlayer] node.\n"
-"Here is a brief usage example that causes a 2D node to move smoothly between "
-"two positions:\n"
+"Here is a brief usage example that makes a 2D node move smoothly between two "
+"positions:\n"
"[codeblock]\n"
"var tween = get_node(\"Tween\")\n"
"tween.interpolate_property($Node2D, \"position\",\n"
@@ -51588,15 +51868,18 @@ msgid ""
"where it would only apply to that particular component.\n"
"Many of the methods accept [code]trans_type[/code] and [code]ease_type[/"
"code]. The first accepts an [enum TransitionType] constant, and refers to "
-"the way the timing of the animation is handled (see [code]http://easings.net/"
-"[/code] for some examples). The second accepts an [enum EaseType] constant, "
-"and controls the where [code]trans_type[/code] is applied to the "
-"interpolation (in the beginning, the end, or both). If you don't know which "
-"transition and easing to pick, you can try different [enum TransitionType] "
-"constants with [constant EASE_IN_OUT], and use the one that looks best."
+"the way the timing of the animation is handled (see [url=https://easings."
+"net/]easings.net[/url] for some examples). The second accepts an [enum "
+"EaseType] constant, and controls the where [code]trans_type[/code] is "
+"applied to the interpolation (in the beginning, the end, or both). If you "
+"don't know which transition and easing to pick, you can try different [enum "
+"TransitionType] constants with [constant EASE_IN_OUT], and use the one that "
+"looks best.\n"
+"[b][url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/"
+"tween_cheatsheet.png]Tween easing and transition types cheatsheet[/url][/b]"
msgstr ""
-#: doc/classes/Tween.xml:45
+#: doc/classes/Tween.xml:46
msgid ""
"Follows [code]method[/code] of [code]object[/code] and applies the returned "
"value on [code]target_method[/code] of [code]target[/code], beginning from "
@@ -51608,7 +51891,7 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:71
+#: doc/classes/Tween.xml:72
msgid ""
"Follows [code]property[/code] of [code]object[/code] and applies it on "
"[code]target_property[/code] of [code]target[/code], beginning from "
@@ -51620,21 +51903,21 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:79
+#: doc/classes/Tween.xml:80
msgid ""
"Returns the total time needed for all tweens to end. If you have two tweens, "
"one lasting 10 seconds and the other 20 seconds, it would return 20 seconds, "
"as by that time all tweens would have finished."
msgstr ""
-#: doc/classes/Tween.xml:102
+#: doc/classes/Tween.xml:103
msgid ""
"Calls [code]callback[/code] of [code]object[/code] after [code]duration[/"
"code]. [code]arg1[/code]-[code]arg5[/code] are arguments to be passed to the "
"callback."
msgstr ""
-#: doc/classes/Tween.xml:125
+#: doc/classes/Tween.xml:126
msgid ""
"Calls [code]callback[/code] of [code]object[/code] after [code]duration[/"
"code] on the main thread (similar to [method Object.call_deferred]). "
@@ -51642,7 +51925,7 @@ msgid ""
"callback."
msgstr ""
-#: doc/classes/Tween.xml:148
+#: doc/classes/Tween.xml:149
msgid ""
"Animates [code]method[/code] of [code]object[/code] from [code]initial_val[/"
"code] to [code]final_val[/code] for [code]duration[/code] seconds, "
@@ -51654,7 +51937,7 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:172
+#: doc/classes/Tween.xml:173
msgid ""
"Animates [code]property[/code] of [code]object[/code] from "
"[code]initial_val[/code] to [code]final_val[/code] for [code]duration[/code] "
@@ -51666,72 +51949,72 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:180
+#: doc/classes/Tween.xml:181
msgid ""
"Returns [code]true[/code] if any tweens are currently running.\n"
"[b]Note:[/b] This method doesn't consider tweens that have ended."
msgstr ""
-#: doc/classes/Tween.xml:192
+#: doc/classes/Tween.xml:193
msgid ""
"Stops animation and removes a tween, given its object and property/method "
"pair. By default, all tweens are removed, unless [code]key[/code] is "
"specified."
msgstr ""
-#: doc/classes/Tween.xml:199
+#: doc/classes/Tween.xml:200
msgid "Stops animation and removes all tweens."
msgstr ""
-#: doc/classes/Tween.xml:210
+#: doc/classes/Tween.xml:211
msgid ""
"Resets a tween to its initial value (the one given, not the one before the "
"tween), given its object and property/method pair. By default, all tweens "
"are removed, unless [code]key[/code] is specified."
msgstr ""
-#: doc/classes/Tween.xml:217
+#: doc/classes/Tween.xml:218
msgid ""
"Resets all tweens to their initial values (the ones given, not those before "
"the tween)."
msgstr ""
-#: doc/classes/Tween.xml:228
+#: doc/classes/Tween.xml:229
msgid ""
"Continues animating a stopped tween, given its object and property/method "
"pair. By default, all tweens are resumed, unless [code]key[/code] is "
"specified."
msgstr ""
-#: doc/classes/Tween.xml:235
+#: doc/classes/Tween.xml:236
msgid "Continues animating all stopped tweens."
msgstr ""
-#: doc/classes/Tween.xml:244
+#: doc/classes/Tween.xml:245
msgid "Sets the interpolation to the given [code]time[/code] in seconds."
msgstr ""
-#: doc/classes/Tween.xml:253
+#: doc/classes/Tween.xml:254
msgid ""
"Activates/deactivates the tween. See also [method stop_all] and [method "
"resume_all]."
msgstr ""
-#: doc/classes/Tween.xml:260
+#: doc/classes/Tween.xml:261
msgid "Starts the tween. You can define animations both before and after this."
msgstr ""
-#: doc/classes/Tween.xml:271
+#: doc/classes/Tween.xml:272
msgid ""
"Stops a tween, given its object and property/method pair. By default, all "
"tweens are stopped, unless [code]key[/code] is specified."
msgstr ""
-#: doc/classes/Tween.xml:278
+#: doc/classes/Tween.xml:279
msgid "Stops animating all tweens."
msgstr ""
-#: doc/classes/Tween.xml:303
+#: doc/classes/Tween.xml:304
msgid ""
"Animates [code]method[/code] of [code]object[/code] from the value returned "
"by [code]initial_method[/code] to [code]final_val[/code] for [code]duration[/"
@@ -51743,7 +52026,7 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:329
+#: doc/classes/Tween.xml:330
msgid ""
"Animates [code]property[/code] of [code]object[/code] from the current value "
"of the [code]initial_val[/code] property of [code]initial[/code] to "
@@ -51755,15 +52038,15 @@ msgid ""
"information."
msgstr ""
-#: doc/classes/Tween.xml:337
+#: doc/classes/Tween.xml:338
msgid "Returns the current time of the tween."
msgstr ""
-#: doc/classes/Tween.xml:343
+#: doc/classes/Tween.xml:344
msgid "The tween's animation process thread. See [enum TweenProcessMode]."
msgstr ""
-#: doc/classes/Tween.xml:346
+#: doc/classes/Tween.xml:347
msgid ""
"The tween's speed multiplier. For example, set it to [code]1.0[/code] for "
"normal speed, [code]2.0[/code] for two times normal speed, or [code]0.5[/"
@@ -51771,100 +52054,100 @@ msgid ""
"animation, but see also [method set_active] or [method stop_all] for this."
msgstr ""
-#: doc/classes/Tween.xml:349
+#: doc/classes/Tween.xml:350
msgid "If [code]true[/code], the tween loops."
msgstr ""
-#: doc/classes/Tween.xml:355
+#: doc/classes/Tween.xml:356
msgid "Emitted when all processes in a tween end."
msgstr ""
-#: doc/classes/Tween.xml:364
+#: doc/classes/Tween.xml:365
msgid "Emitted when a tween ends."
msgstr ""
-#: doc/classes/Tween.xml:373
+#: doc/classes/Tween.xml:374
msgid "Emitted when a tween starts."
msgstr ""
-#: doc/classes/Tween.xml:386
+#: doc/classes/Tween.xml:387
msgid "Emitted at each step of the animation."
msgstr ""
-#: doc/classes/Tween.xml:392
+#: doc/classes/Tween.xml:393
msgid "The tween updates with the [code]_physics_process[/code] callback."
msgstr ""
-#: doc/classes/Tween.xml:395
+#: doc/classes/Tween.xml:396
msgid "The tween updates with the [code]_process[/code] callback."
msgstr ""
-#: doc/classes/Tween.xml:398
+#: doc/classes/Tween.xml:399
msgid "The animation is interpolated linearly."
msgstr ""
-#: doc/classes/Tween.xml:401
+#: doc/classes/Tween.xml:402
msgid "The animation is interpolated using a sine function."
msgstr ""
-#: doc/classes/Tween.xml:404
+#: doc/classes/Tween.xml:405
msgid ""
"The animation is interpolated with a quintic (to the power of 5) function."
msgstr ""
-#: doc/classes/Tween.xml:407
+#: doc/classes/Tween.xml:408
msgid ""
"The animation is interpolated with a quartic (to the power of 4) function."
msgstr ""
-#: doc/classes/Tween.xml:410
+#: doc/classes/Tween.xml:411
msgid ""
"The animation is interpolated with a quadratic (to the power of 2) function."
msgstr ""
-#: doc/classes/Tween.xml:413
+#: doc/classes/Tween.xml:414
msgid ""
"The animation is interpolated with an exponential (to the power of x) "
"function."
msgstr ""
-#: doc/classes/Tween.xml:416
+#: doc/classes/Tween.xml:417
msgid ""
"The animation is interpolated with elasticity, wiggling around the edges."
msgstr ""
-#: doc/classes/Tween.xml:419
+#: doc/classes/Tween.xml:420
msgid ""
"The animation is interpolated with a cubic (to the power of 3) function."
msgstr ""
-#: doc/classes/Tween.xml:422
+#: doc/classes/Tween.xml:423
msgid "The animation is interpolated with a function using square roots."
msgstr ""
-#: doc/classes/Tween.xml:425
+#: doc/classes/Tween.xml:426
msgid "The animation is interpolated by bouncing at the end."
msgstr ""
-#: doc/classes/Tween.xml:428
+#: doc/classes/Tween.xml:429
msgid "The animation is interpolated backing out at ends."
msgstr ""
-#: doc/classes/Tween.xml:431
+#: doc/classes/Tween.xml:432
msgid "The interpolation starts slowly and speeds up towards the end."
msgstr ""
-#: doc/classes/Tween.xml:434
+#: doc/classes/Tween.xml:435
msgid "The interpolation starts quickly and slows down towards the end."
msgstr ""
-#: doc/classes/Tween.xml:437
+#: doc/classes/Tween.xml:438
msgid ""
"A combination of [constant EASE_IN] and [constant EASE_OUT]. The "
"interpolation is slowest at both ends."
msgstr ""
-#: doc/classes/Tween.xml:440
+#: doc/classes/Tween.xml:441
msgid ""
"A combination of [constant EASE_IN] and [constant EASE_OUT]. The "
"interpolation is fastest at both ends."
@@ -53468,69 +53751,90 @@ msgstr ""
msgid "If [code]true[/code], the viewport will process 3D audio streams."
msgstr ""
-#: doc/classes/Viewport.xml:199
+#: doc/classes/Viewport.xml:195
+msgid ""
+"Sets the default filter mode used by [CanvasItem]s in this Viewport. See "
+"[enum DefaultCanvasItemTextureFilter] for options."
+msgstr ""
+
+#: doc/classes/Viewport.xml:198
+msgid ""
+"Sets the default repeat mode used by [CanvasItem]s in this Viewport. See "
+"[enum DefaultCanvasItemTextureRepeat] for options."
+msgstr ""
+
+#: doc/classes/Viewport.xml:201
msgid ""
"The canvas transform of the viewport, useful for changing the on-screen "
"positions of all child [CanvasItem]s. This is relative to the global canvas "
"transform of the viewport."
msgstr ""
-#: doc/classes/Viewport.xml:202
+#: doc/classes/Viewport.xml:204
msgid "The overlay mode for test rendered geometry in debug purposes."
msgstr ""
-#: doc/classes/Viewport.xml:205
+#: doc/classes/Viewport.xml:207
msgid ""
"The global canvas transform of the viewport. The canvas transform is "
"relative to this."
msgstr ""
-#: doc/classes/Viewport.xml:208
+#: doc/classes/Viewport.xml:210
msgid "If [code]true[/code], the viewport will not receive input event."
msgstr ""
-#: doc/classes/Viewport.xml:213
+#: doc/classes/Viewport.xml:215
msgid ""
"If [code]true[/code], the GUI controls on the viewport will lay pixel "
"perfectly."
msgstr ""
-#: doc/classes/Viewport.xml:218
+#: doc/classes/Viewport.xml:220
msgid ""
"The multisample anti-aliasing mode. A higher number results in smoother "
"edges at the cost of significantly worse performance. A value of 4 is best "
"unless targeting very high-end systems."
msgstr ""
-#: doc/classes/Viewport.xml:221
+#: doc/classes/Viewport.xml:223
msgid ""
"If [code]true[/code], the viewport will use [World3D] defined in "
"[code]world[/code] property."
msgstr ""
-#: doc/classes/Viewport.xml:224
+#: doc/classes/Viewport.xml:226
msgid ""
"If [code]true[/code], the objects rendered by viewport become subjects of "
"mouse picking process."
msgstr ""
-#: doc/classes/Viewport.xml:227
+#: doc/classes/Viewport.xml:229
+msgid ""
+"Sets the screen-space antialiasing method used. Screen-space antialiasing "
+"works by selectively blurring edges in a post-process shader. It differs "
+"from MSAA which takes multiple coverage samples while rendering objects. "
+"Screen-space AA methods are typically faster than MSAA and will smooth out "
+"specular aliasing, but tend to make scenes appear blurry."
+msgstr ""
+
+#: doc/classes/Viewport.xml:232
msgid "The subdivision amount of the first quadrant on the shadow atlas."
msgstr ""
-#: doc/classes/Viewport.xml:230
+#: doc/classes/Viewport.xml:235
msgid "The subdivision amount of the second quadrant on the shadow atlas."
msgstr ""
-#: doc/classes/Viewport.xml:233
+#: doc/classes/Viewport.xml:238
msgid "The subdivision amount of the third quadrant on the shadow atlas."
msgstr ""
-#: doc/classes/Viewport.xml:236
+#: doc/classes/Viewport.xml:241
msgid "The subdivision amount of the fourth quadrant on the shadow atlas."
msgstr ""
-#: doc/classes/Viewport.xml:239
+#: doc/classes/Viewport.xml:244
msgid ""
"The shadow atlas' resolution (used for omni and spot lights). The value will "
"be rounded up to the nearest power of 2.\n"
@@ -53539,136 +53843,177 @@ msgid ""
"manually."
msgstr ""
-#: doc/classes/Viewport.xml:243
+#: doc/classes/Viewport.xml:248
msgid ""
"If [code]true[/code], the viewport should render its background as "
"transparent."
msgstr ""
-#: doc/classes/Viewport.xml:246
+#: doc/classes/Viewport.xml:251
msgid "The custom [World3D] which can be used as 3D environment source."
msgstr ""
-#: doc/classes/Viewport.xml:249
+#: doc/classes/Viewport.xml:254
msgid "The custom [World2D] which can be used as 2D environment source."
msgstr ""
-#: doc/classes/Viewport.xml:257
+#: doc/classes/Viewport.xml:262
msgid "Emitted when a Control node grabs keyboard focus."
msgstr ""
-#: doc/classes/Viewport.xml:262
+#: doc/classes/Viewport.xml:267
msgid ""
"Emitted when the size of the viewport is changed, whether by resizing of "
"window, or some other means."
msgstr ""
-#: doc/classes/Viewport.xml:268
+#: doc/classes/Viewport.xml:273
msgid "This quadrant will not be used."
msgstr ""
-#: doc/classes/Viewport.xml:271
+#: doc/classes/Viewport.xml:276
msgid "This quadrant will only be used by one shadow map."
msgstr ""
-#: doc/classes/Viewport.xml:274
+#: doc/classes/Viewport.xml:279
msgid "This quadrant will be split in 4 and used by up to 4 shadow maps."
msgstr ""
-#: doc/classes/Viewport.xml:277
+#: doc/classes/Viewport.xml:282
msgid "This quadrant will be split 16 ways and used by up to 16 shadow maps."
msgstr ""
-#: doc/classes/Viewport.xml:280
+#: doc/classes/Viewport.xml:285
msgid "This quadrant will be split 64 ways and used by up to 64 shadow maps."
msgstr ""
-#: doc/classes/Viewport.xml:283
+#: doc/classes/Viewport.xml:288
msgid ""
"This quadrant will be split 256 ways and used by up to 256 shadow maps. "
"Unless the [member shadow_atlas_size] is very high, the shadows in this "
"quadrant will be very low resolution."
msgstr ""
-#: doc/classes/Viewport.xml:286
+#: doc/classes/Viewport.xml:291
msgid ""
"This quadrant will be split 1024 ways and used by up to 1024 shadow maps. "
"Unless the [member shadow_atlas_size] is very high, the shadows in this "
"quadrant will be very low resolution."
msgstr ""
-#: doc/classes/Viewport.xml:289
+#: doc/classes/Viewport.xml:294
msgid "Represents the size of the [enum ShadowAtlasQuadrantSubdiv] enum."
msgstr ""
-#: doc/classes/Viewport.xml:292
-msgid "Amount of objects in frame."
+#: doc/classes/Viewport.xml:297
+msgid ""
+"Multisample antialiasing mode disabled. This is the default value, and also "
+"the fastest setting."
msgstr ""
-#: doc/classes/Viewport.xml:295
-msgid "Amount of vertices in frame."
+#: doc/classes/Viewport.xml:300
+msgid "Use 2x Multisample Antialiasing."
msgstr ""
-#: doc/classes/Viewport.xml:298
-msgid "Amount of material changes in frame."
+#: doc/classes/Viewport.xml:303
+msgid "Use 4x Multisample Antialiasing."
msgstr ""
-#: doc/classes/Viewport.xml:301
-msgid "Amount of shader changes in frame."
+#: doc/classes/Viewport.xml:306
+msgid ""
+"Use 8x Multisample Antialiasing. Likely unsupported on low-end and older "
+"hardware."
msgstr ""
-#: doc/classes/Viewport.xml:304
-msgid "Amount of surface changes in frame."
+#: doc/classes/Viewport.xml:309
+msgid ""
+"Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end "
+"hardware."
msgstr ""
-#: doc/classes/Viewport.xml:307
-msgid "Amount of draw calls in frame."
+#: doc/classes/Viewport.xml:312
+msgid "Represents the size of the [enum MSAA] enum."
msgstr ""
-#: doc/classes/Viewport.xml:310
-msgid "Represents the size of the [enum RenderInfo] enum."
+#: doc/classes/Viewport.xml:315
+msgid "Do not perform any antialiasing in the full screen post-process."
msgstr ""
-#: doc/classes/Viewport.xml:313
-msgid "Objects are displayed normally."
+#: doc/classes/Viewport.xml:318
+msgid ""
+"Use fast approximate antialiasing. FXAA is a popular screen-space "
+"antialising method, which is fast but will make the image look blurry, "
+"especially at lower resolutions. It can still work relatively well at large "
+"resolutions such as 1440p and 4K."
msgstr ""
-#: doc/classes/Viewport.xml:316
-msgid "Objects are displayed without light information."
+#: doc/classes/Viewport.xml:321
+msgid "Represents the size of the [enum ScreenSpaceAA] enum."
msgstr ""
-#: doc/classes/Viewport.xml:319
-msgid ""
-"Objected are displayed semi-transparent with additive blending so you can "
-"see where they intersect."
+#: doc/classes/Viewport.xml:324
+msgid "Amount of objects in frame."
msgstr ""
-#: doc/classes/Viewport.xml:322
-msgid "Objects are displayed in wireframe style."
+#: doc/classes/Viewport.xml:327
+msgid "Amount of vertices in frame."
+msgstr ""
+
+#: doc/classes/Viewport.xml:330
+msgid "Amount of material changes in frame."
+msgstr ""
+
+#: doc/classes/Viewport.xml:333
+msgid "Amount of shader changes in frame."
+msgstr ""
+
+#: doc/classes/Viewport.xml:336
+msgid "Amount of surface changes in frame."
msgstr ""
#: doc/classes/Viewport.xml:339
-msgid "Multisample anti-aliasing mode disabled. This is the default value."
+msgid "Amount of draw calls in frame."
msgstr ""
#: doc/classes/Viewport.xml:342
-msgid "Use 2x Multisample Antialiasing."
+msgid "Represents the size of the [enum RenderInfo] enum."
msgstr ""
#: doc/classes/Viewport.xml:345
-msgid "Use 4x Multisample Antialiasing."
+msgid "Objects are displayed normally."
msgstr ""
-#: doc/classes/Viewport.xml:348
+#: doc/classes/Viewport.xml:356
+msgid "Objects are displayed in wireframe style."
+msgstr ""
+
+#: doc/classes/Viewport.xml:378
msgid ""
-"Use 8x Multisample Antialiasing. Likely unsupported on low-end and older "
-"hardware."
+"Draws the screen-space ambient occlusion texture instead of the scene so "
+"that you can clearly see how it is affecting objects. In order for this "
+"display mode to work, you must have [member Environment.ssao_enabled] set in "
+"your [WorldEnvironment]."
msgstr ""
-#: doc/classes/Viewport.xml:351
+#: doc/classes/Viewport.xml:384
msgid ""
-"Use 16x Multisample Antialiasing. Likely unsupported on medium and low-end "
-"hardware."
+"Colors each PSSM split for the [DirectionalLight3D]s in the scene a "
+"different color so you can see where the splits are. In order, they will be "
+"colored red, green, blue, and yellow."
+msgstr ""
+
+#: doc/classes/Viewport.xml:387
+msgid ""
+"Draws the decal atlas used by [Decal]s and light projector textures in the "
+"upper left quadrant of the [Viewport]."
+msgstr ""
+
+#: doc/classes/Viewport.xml:402
+msgid "Max value for [enum DefaultCanvasItemTextureFilter] enum."
+msgstr ""
+
+#: doc/classes/Viewport.xml:414
+msgid "Max value for [enum DefaultCanvasItemTextureRepeat] enum."
msgstr ""
#: doc/classes/ViewportTexture.xml:4
@@ -53690,7 +54035,7 @@ msgid ""
msgstr ""
#: doc/classes/VisibilityEnabler2D.xml:4 doc/classes/VisibilityEnabler3D.xml:4
-msgid "Enables certain nodes only when visible."
+msgid "Enables certain nodes only when approximately visible."
msgstr ""
#: doc/classes/VisibilityEnabler2D.xml:7
@@ -53698,78 +54043,82 @@ msgid ""
"The VisibilityEnabler2D will disable [RigidBody2D], [AnimationPlayer], and "
"other nodes when they are not visible. It will only affect nodes with the "
"same root node as the VisibilityEnabler2D, and the root node itself.\n"
-"Note that VisibilityEnabler2D will not affect nodes added after scene "
+"[b]Note:[/b] For performance reasons, VisibilityEnabler2D uses an "
+"approximate heuristic with precision determined by [member ProjectSettings."
+"world/2d/cell_size]. If you need exact visibility checking, use another "
+"method such as adding an [Area2D] node as a child of a [Camera2D] node.\n"
+"[b]Note:[/b] VisibilityEnabler2D will not affect nodes added after scene "
"initialization."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:19
-#: doc/classes/VisibilityEnabler3D.xml:19
+#: doc/classes/VisibilityEnabler2D.xml:20
+#: doc/classes/VisibilityEnabler3D.xml:20
msgid ""
"Returns whether the enabler identified by given [enum Enabler] constant is "
"active."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:30
-#: doc/classes/VisibilityEnabler3D.xml:30
+#: doc/classes/VisibilityEnabler2D.xml:31
+#: doc/classes/VisibilityEnabler3D.xml:31
msgid ""
"Sets active state of the enabler identified by given [enum Enabler] constant."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:36
+#: doc/classes/VisibilityEnabler2D.xml:37
msgid "If [code]true[/code], [RigidBody2D] nodes will be paused."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:39
+#: doc/classes/VisibilityEnabler2D.xml:40
msgid "If [code]true[/code], [AnimatedSprite2D] nodes will be paused."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:42
-#: doc/classes/VisibilityEnabler3D.xml:39
+#: doc/classes/VisibilityEnabler2D.xml:43
+#: doc/classes/VisibilityEnabler3D.xml:40
msgid "If [code]true[/code], [AnimationPlayer] nodes will be paused."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:45
+#: doc/classes/VisibilityEnabler2D.xml:46
msgid "If [code]true[/code], [GPUParticles2D] nodes will be paused."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:48
+#: doc/classes/VisibilityEnabler2D.xml:49
msgid ""
"If [code]true[/code], the parent's [method Node._physics_process] will be "
"stopped."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:51
+#: doc/classes/VisibilityEnabler2D.xml:52
msgid ""
"If [code]true[/code], the parent's [method Node._process] will be stopped."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:56
-#: doc/classes/VisibilityEnabler3D.xml:44
+#: doc/classes/VisibilityEnabler2D.xml:57
+#: doc/classes/VisibilityEnabler3D.xml:45
msgid "This enabler will pause [AnimationPlayer] nodes."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:59
+#: doc/classes/VisibilityEnabler2D.xml:60
msgid "This enabler will freeze [RigidBody2D] nodes."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:62
+#: doc/classes/VisibilityEnabler2D.xml:63
msgid "This enabler will stop [GPUParticles2D] nodes."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:65
+#: doc/classes/VisibilityEnabler2D.xml:66
msgid "This enabler will stop the parent's _process function."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:68
+#: doc/classes/VisibilityEnabler2D.xml:69
msgid "This enabler will stop the parent's _physics_process function."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:71
+#: doc/classes/VisibilityEnabler2D.xml:72
msgid "This enabler will stop [AnimatedSprite2D] nodes animations."
msgstr ""
-#: doc/classes/VisibilityEnabler2D.xml:74
-#: doc/classes/VisibilityEnabler3D.xml:50
+#: doc/classes/VisibilityEnabler2D.xml:75
+#: doc/classes/VisibilityEnabler3D.xml:51
msgid "Represents the size of the [enum Enabler] enum."
msgstr ""
@@ -53778,31 +54127,39 @@ msgid ""
"The VisibilityEnabler3D will disable [RigidBody3D] and [AnimationPlayer] "
"nodes when they are not visible. It will only affect other nodes within the "
"same scene as the VisibilityEnabler3D itself.\n"
-"Note that VisibilityEnabler3D will not affect nodes added after scene "
+"[b]Note:[/b] VisibilityEnabler3D uses an approximate heuristic for "
+"performance reasons. It doesn't take walls and other occlusion into account. "
+"If you need exact visibility checking, use another method such as adding an "
+"[Area3D] node as a child of a [Camera3D] node.\n"
+"[b]Note:[/b] VisibilityEnabler3D will not affect nodes added after scene "
"initialization."
msgstr ""
-#: doc/classes/VisibilityEnabler3D.xml:36
+#: doc/classes/VisibilityEnabler3D.xml:37
msgid "If [code]true[/code], [RigidBody3D] nodes will be paused."
msgstr ""
-#: doc/classes/VisibilityEnabler3D.xml:47
+#: doc/classes/VisibilityEnabler3D.xml:48
msgid "This enabler will freeze [RigidBody3D] nodes."
msgstr ""
#: doc/classes/VisibilityNotifier2D.xml:4
#: doc/classes/VisibilityNotifier3D.xml:4
-msgid "Detects when the node is visible on screen."
+msgid "Detects approximately when the node is visible on screen."
msgstr ""
#: doc/classes/VisibilityNotifier2D.xml:7
msgid ""
"The VisibilityNotifier2D detects when it is visible on the screen. It also "
"notifies when its bounding rectangle enters or exits the screen or a "
-"viewport."
+"viewport.\n"
+"[b]Note:[/b] For performance reasons, VisibilityNotifier2D uses an "
+"approximate heuristic with precision determined by [member ProjectSettings."
+"world/2d/cell_size]. If you need exact visibility checking, use another "
+"method such as adding an [Area2D] node as a child of a [Camera2D] node."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:16
+#: doc/classes/VisibilityNotifier2D.xml:17
msgid ""
"If [code]true[/code], the bounding rectangle is on the screen.\n"
"[b]Note:[/b] It takes one frame for the node's visibility to be assessed "
@@ -53811,23 +54168,23 @@ msgid ""
"pass."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:23
+#: doc/classes/VisibilityNotifier2D.xml:24
msgid "The VisibilityNotifier2D's bounding rectangle."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:29
+#: doc/classes/VisibilityNotifier2D.xml:30
msgid "Emitted when the VisibilityNotifier2D enters the screen."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:34
+#: doc/classes/VisibilityNotifier2D.xml:35
msgid "Emitted when the VisibilityNotifier2D exits the screen."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:41
+#: doc/classes/VisibilityNotifier2D.xml:42
msgid "Emitted when the VisibilityNotifier2D enters a [Viewport]'s view."
msgstr ""
-#: doc/classes/VisibilityNotifier2D.xml:48
+#: doc/classes/VisibilityNotifier2D.xml:49
msgid "Emitted when the VisibilityNotifier2D exits a [Viewport]'s view."
msgstr ""
@@ -53835,10 +54192,14 @@ msgstr ""
msgid ""
"The VisibilityNotifier3D detects when it is visible on the screen. It also "
"notifies when its bounding rectangle enters or exits the screen or a "
-"[Camera3D]'s view."
+"[Camera3D]'s view.\n"
+"[b]Note:[/b] VisibilityNotifier3D uses an approximate heuristic for "
+"performance reasons. It doesn't take walls and other occlusion into account. "
+"If you need exact visibility checking, use another method such as adding an "
+"[Area3D] node as a child of a [Camera3D] node."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:16
+#: doc/classes/VisibilityNotifier3D.xml:17
msgid ""
"If [code]true[/code], the bounding box is on the screen.\n"
"[b]Note:[/b] It takes one frame for the node's visibility to be assessed "
@@ -53847,23 +54208,23 @@ msgid ""
"pass."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:23
+#: doc/classes/VisibilityNotifier3D.xml:24
msgid "The VisibilityNotifier3D's bounding box."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:31
+#: doc/classes/VisibilityNotifier3D.xml:32
msgid "Emitted when the VisibilityNotifier3D enters a [Camera3D]'s view."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:38
+#: doc/classes/VisibilityNotifier3D.xml:39
msgid "Emitted when the VisibilityNotifier3D exits a [Camera3D]'s view."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:43
+#: doc/classes/VisibilityNotifier3D.xml:44
msgid "Emitted when the VisibilityNotifier3D enters the screen."
msgstr ""
-#: doc/classes/VisibilityNotifier3D.xml:48
+#: doc/classes/VisibilityNotifier3D.xml:49
msgid "Emitted when the VisibilityNotifier3D exits the screen."
msgstr ""
@@ -56455,7 +56816,7 @@ msgstr ""
msgid "The background of the area below the grabber."
msgstr ""
-#: doc/classes/VSlider.xml:33
+#: doc/classes/VSlider.xml:35
msgid ""
"The background for the whole slider. Determines the width of the "
"[code]grabber_area[/code]."
@@ -57437,6 +57798,666 @@ msgstr ""
msgid "Unknown node."
msgstr ""
+#: doc/classes/XRAnchor3D.xml:4
+msgid "An anchor point in AR space."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:7
+msgid ""
+"The [XRAnchor3D] point is a spatial node that maps a real world location "
+"identified by the AR platform to a position within the game world. For "
+"example, as long as plane detection in ARKit is on, ARKit will identify and "
+"update the position of planes (tables, floors, etc) and create anchors for "
+"them.\n"
+"This node is mapped to one of the anchors through its unique ID. When you "
+"receive a signal that a new anchor is available, you should add this node to "
+"your scene for that anchor. You can predefine nodes and set the ID; the "
+"nodes will simply remain on 0,0,0 until a plane is recognized.\n"
+"Keep in mind that, as long as plane detection is enabled, the size, placing "
+"and orientation of an anchor will be updated as the detection logic learns "
+"more about the real world out there especially if only part of the surface "
+"is in view."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:18
+msgid "Returns the name given to this anchor."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:25
+msgid ""
+"Returns [code]true[/code] if the anchor is being tracked and [code]false[/"
+"code] if no anchor with this ID is currently known."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:32
+msgid ""
+"If provided by the [XRInterface], this returns a mesh object for the anchor. "
+"For an anchor, this can be a shape related to the object being tracked or it "
+"can be a mesh that provides topology related to the anchor and can be used "
+"to create shadows/reflections on surfaces or for generating collision shapes."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:39
+msgid ""
+"Returns a plane aligned with our anchor; handy for intersection testing."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:46
+msgid ""
+"Returns the estimated size of the plane that was detected. Say when the "
+"anchor relates to a table in the real world, this is the estimated size of "
+"the surface of that table."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:52
+msgid ""
+"The anchor's ID. You can set this before the anchor itself exists. The first "
+"anchor gets an ID of [code]1[/code], the second an ID of [code]2[/code], "
+"etc. When anchors get removed, the engine can then assign the corresponding "
+"ID to new anchors. The most common situation where anchors \"disappear\" is "
+"when the AR server identifies that two anchors represent different parts of "
+"the same plane and merges them."
+msgstr ""
+
+#: doc/classes/XRAnchor3D.xml:60
+msgid ""
+"Emitted when the mesh associated with the anchor changes or when one becomes "
+"available. This is especially important for topology that is constantly "
+"being [code]mesh_updated[/code]."
+msgstr ""
+
+#: doc/classes/XRCamera3D.xml:4
+msgid ""
+"A camera node with a few overrules for AR/VR applied, such as location "
+"tracking."
+msgstr ""
+
+#: doc/classes/XRCamera3D.xml:7
+msgid ""
+"This is a helper spatial node for our camera; note that, if stereoscopic "
+"rendering is applicable (VR-HMD), most of the camera properties are ignored, "
+"as the HMD information overrides them. The only properties that can be "
+"trusted are the near and far planes.\n"
+"The position and orientation of this node is automatically updated by the XR "
+"Server to represent the location of the HMD if such tracking is available "
+"and can thus be used by game logic. Note that, in contrast to the XR "
+"Controller, the render thread has access to the most up-to-date tracking "
+"data of the HMD and the location of the XRCamera3D can lag a few "
+"milliseconds behind what is used for rendering as a result."
+msgstr ""
+
+#: doc/classes/XRCamera3D.xml:11 doc/classes/XRController3D.xml:12
+#: doc/classes/XRInterface.xml:11 doc/classes/XROrigin3D.xml:13
+#: doc/classes/XRPositionalTracker.xml:12 doc/classes/XRServer.xml:10
+msgid "https://docs.godotengine.org/en/latest/tutorials/vr/index.html"
+msgstr ""
+
+#: doc/classes/XRController3D.xml:4
+msgid "A spatial node representing a spatially-tracked controller."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:7
+msgid ""
+"This is a helper spatial node that is linked to the tracking of controllers. "
+"It also offers several handy passthroughs to the state of buttons and such "
+"on the controllers.\n"
+"Controllers are linked by their ID. You can create controller nodes before "
+"the controllers are available. If your game always uses two controllers (one "
+"for each hand), you can predefine the controllers with ID 1 and 2; they will "
+"become active as soon as the controllers are identified. If you expect "
+"additional controllers to be used, you should react to the signals and add "
+"XRController3D nodes to your scene.\n"
+"The position of the controller node is automatically updated by the "
+"[XRServer]. This makes this node ideal to add child nodes to visualize the "
+"controller."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:19
+msgid ""
+"If active, returns the name of the associated controller if provided by the "
+"AR/VR SDK used."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:26
+msgid ""
+"Returns the hand holding this controller, if known. See [enum "
+"XRPositionalTracker.TrackerHand]."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:33
+msgid ""
+"Returns [code]true[/code] if the bound controller is active. XR systems "
+"attempt to track active controllers."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:42
+msgid ""
+"Returns the value of the given axis for things like triggers, touchpads, "
+"etc. that are embedded into the controller."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:49
+msgid ""
+"Returns the ID of the joystick object bound to this. Every controller "
+"tracked by the [XRServer] that has buttons and axis will also be registered "
+"as a joystick within Godot. This means that all the normal joystick tracking "
+"and input mapping will work for buttons and axis found on the AR/VR "
+"controllers. This ID is purely offered as information so you can link up the "
+"controller with its joystick entry."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:56
+msgid ""
+"If provided by the [XRInterface], this returns a mesh associated with the "
+"controller. This can be used to visualize the controller."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:65
+msgid ""
+"Returns [code]true[/code] if the button at index [code]button[/code] is "
+"pressed. See [enum JoyButtonList]."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:71
+msgid ""
+"The controller's ID.\n"
+"A controller ID of 0 is unbound and will always result in an inactive node. "
+"Controller ID 1 is reserved for the first controller that identifies itself "
+"as the left-hand controller and ID 2 is reserved for the first controller "
+"that identifies itself as the right-hand controller.\n"
+"For any other controller that the [XRServer] detects, we continue with "
+"controller ID 3.\n"
+"When a controller is turned off, its slot is freed. This ensures controllers "
+"will keep the same ID even when controllers with lower IDs are turned off."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:77
+msgid ""
+"The degree to which the controller vibrates. Ranges from [code]0.0[/code] to "
+"[code]1.0[/code] with precision [code].01[/code]. If changed, updates "
+"[member XRPositionalTracker.rumble] accordingly.\n"
+"This is a useful property to animate if you want the controller to vibrate "
+"for a limited duration."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:86
+msgid "Emitted when a button on this controller is pressed."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:93
+msgid "Emitted when a button on this controller is released."
+msgstr ""
+
+#: doc/classes/XRController3D.xml:100
+msgid ""
+"Emitted when the mesh associated with the controller changes or when one "
+"becomes available. Generally speaking this will be a static mesh after "
+"becoming available."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:4
+msgid "Base class for an AR/VR interface implementation."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:7
+msgid ""
+"This class needs to be implemented to make an AR or VR platform available to "
+"Godot and these should be implemented as C++ modules or GDNative modules "
+"(note that for GDNative the subclass XRScriptInterface should be used). Part "
+"of the interface is exposed to GDScript so you can detect, enable and "
+"configure an AR or VR platform.\n"
+"Interfaces should be written in such a way that simply enabling them will "
+"give us a working setup. You can query the available interfaces through "
+"[XRServer]."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:18
+msgid ""
+"If this is an AR interface that requires displaying a camera feed as the "
+"background, this method returns the feed ID in the [CameraServer] for this "
+"interface."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:25
+msgid ""
+"Returns a combination of [enum Capabilities] flags providing information "
+"about the capabilities of this interface."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:32
+msgid "Returns the name of this interface (OpenVR, OpenHMD, ARKit, etc)."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:39
+msgid ""
+"Returns the resolution at which we should render our intermediate results "
+"before things like lens distortion are applied by the VR platform."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:46
+msgid ""
+"If supported, returns the status of our tracking. This will allow you to "
+"provide feedback to the user whether there are issues with positional "
+"tracking."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:53
+msgid ""
+"Call this to initialize this interface. The first interface that is "
+"initialized is identified as the primary interface and it will be used for "
+"rendering output.\n"
+"After initializing the interface you want to use you then need to enable the "
+"AR/VR mode of a viewport and rendering should commence.\n"
+"[b]Note:[/b] You must enable the AR/VR mode on the main viewport for any "
+"device that uses the main output of Godot, such as for mobile VR.\n"
+"If you do this for a platform that handles its own output (such as OpenVR) "
+"Godot will show just one eye without distortion on screen. Alternatively, "
+"you can add a separate viewport node to your scene and enable AR/VR on that "
+"viewport. It will be used to output to the HMD, leaving you free to do "
+"anything you like in the main window, such as using a separate camera as a "
+"spectator camera or rendering something completely different.\n"
+"While currently not used, you can activate additional interfaces. You may "
+"wish to do this if you want to track controllers from other platforms. "
+"However, at this point in time only one interface can render to an HMD."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:64
+msgid ""
+"Returns [code]true[/code] if the current output of this interface is in "
+"stereo."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:71
+msgid "Turns the interface off."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:77
+msgid "On an AR interface, [code]true[/code] if anchor detection is enabled."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:80
+msgid "[code]true[/code] if this interface been initialized."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:83
+msgid "[code]true[/code] if this is the primary interface."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:88
+msgid "No XR capabilities."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:91
+msgid ""
+"This interface can work with normal rendering output (non-HMD based AR)."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:94
+msgid "This interface supports stereoscopic rendering."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:97
+msgid "This interface supports AR (video background and real world tracking)."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:100
+msgid ""
+"This interface outputs to an external device. If the main viewport is used, "
+"the on screen output is an unmodified buffer of either the left or right eye "
+"(stretched if the viewport size is not changed to the same aspect ratio of "
+"[method get_render_targetsize]). Using a separate viewport node frees up the "
+"main viewport for other purposes."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:103
+msgid ""
+"Mono output, this is mostly used internally when retrieving positioning "
+"information for our camera node or when stereo scopic rendering is not "
+"supported."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:106
+msgid ""
+"Left eye output, this is mostly used internally when rendering the image for "
+"the left eye and obtaining positioning and projection information."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:109
+msgid ""
+"Right eye output, this is mostly used internally when rendering the image "
+"for the right eye and obtaining positioning and projection information."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:112
+msgid "Tracking is behaving as expected."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:115
+msgid ""
+"Tracking is hindered by excessive motion (the player is moving faster than "
+"tracking can keep up)."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:118
+msgid ""
+"Tracking is hindered by insufficient features, it's too dark (for camera-"
+"based tracking), player is blocked, etc."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:121
+msgid ""
+"We don't know the status of the tracking or this interface does not provide "
+"feedback."
+msgstr ""
+
+#: doc/classes/XRInterface.xml:124
+msgid ""
+"Tracking is not functional (camera not plugged in or obscured, lighthouses "
+"turned off, etc.)."
+msgstr ""
+
+#: modules/gdnative/doc_classes/XRInterfaceGDNative.xml:4
+msgid "GDNative wrapper for an XR interface."
+msgstr ""
+
+#: modules/gdnative/doc_classes/XRInterfaceGDNative.xml:7
+msgid ""
+"This is a wrapper class for GDNative implementations of the XR interface. To "
+"use a GDNative XR interface, simply instantiate this object and set your "
+"GDNative library containing the XR interface implementation."
+msgstr ""
+
+#: doc/classes/XROrigin3D.xml:4
+msgid "The origin point in AR/VR."
+msgstr ""
+
+#: doc/classes/XROrigin3D.xml:7
+msgid ""
+"This is a special node within the AR/VR system that maps the physical "
+"location of the center of our tracking space to the virtual location within "
+"our game world.\n"
+"There should be only one of these nodes in your scene and you must have one. "
+"All the XRCamera3D, XRController3D and XRAnchor3D nodes should be direct "
+"children of this node for spatial tracking to work correctly.\n"
+"It is the position of this node that you update when your character needs to "
+"move through your game world while we're not moving in the real world. "
+"Movement in the real world is always in relation to this origin point.\n"
+"For example, if your character is driving a car, the XROrigin3D node should "
+"be a child node of this car. Or, if you're implementing a teleport system to "
+"move your character, you should change the position of this node."
+msgstr ""
+
+#: doc/classes/XROrigin3D.xml:19
+msgid ""
+"Allows you to adjust the scale to your game's units. Most AR/VR platforms "
+"assume a scale of 1 game world unit = 1 real world meter.\n"
+"[b]Note:[/b] This method is a passthrough to the [XRServer] itself."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:4
+msgid "A tracked object."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:7
+msgid ""
+"An instance of this object represents a device that is tracked, such as a "
+"controller or anchor point. HMDs aren't represented here as they are handled "
+"internally.\n"
+"As controllers are turned on and the AR/VR interface detects them, instances "
+"of this object are automatically added to this list of active tracking "
+"objects accessible through the [XRServer].\n"
+"The [XRController3D] and [XRAnchor3D] both consume objects of this type and "
+"should be used in your project. The positional trackers are just under-the-"
+"hood objects that make this all work. These are mostly exposed so that "
+"GDNative-based interfaces can interact with them."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:19
+msgid ""
+"Returns the hand holding this tracker, if known. See [enum TrackerHand] "
+"constants."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:26
+msgid ""
+"If this is a controller that is being tracked, the controller will also be "
+"represented by a joystick entry with this ID."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:33
+msgid ""
+"Returns the mesh related to a controller or anchor point if one is available."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:40
+msgid "Returns the controller or anchor point's name if available."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:47
+msgid "Returns the controller's orientation matrix."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:54
+msgid "Returns the world-space controller position."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:61
+msgid ""
+"Returns the internal tracker ID. This uniquely identifies the tracker per "
+"tracker type and matches the ID you need to specify for nodes such as the "
+"[XRController3D] and [XRAnchor3D] nodes."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:68
+msgid "Returns [code]true[/code] if this device tracks orientation."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:75
+msgid "Returns [code]true[/code] if this device tracks position."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:84
+msgid "Returns the transform combining this device's orientation and position."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:91
+msgid "Returns the tracker's type."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:97
+msgid ""
+"The degree to which the tracker rumbles. Ranges from [code]0.0[/code] to "
+"[code]1.0[/code] with precision [code].01[/code]."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:102
+msgid "The hand this tracker is held in is unknown or not applicable."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:105
+msgid "This tracker is the left hand controller."
+msgstr ""
+
+#: doc/classes/XRPositionalTracker.xml:108
+msgid "This tracker is the right hand controller."
+msgstr ""
+
+#: doc/classes/XRServer.xml:4
+msgid "Server for AR and VR features."
+msgstr ""
+
+#: doc/classes/XRServer.xml:7
+msgid ""
+"The AR/VR server is the heart of our Advanced and Virtual Reality solution "
+"and handles all the processing."
+msgstr ""
+
+#: doc/classes/XRServer.xml:21
+msgid ""
+"This is an important function to understand correctly. AR and VR platforms "
+"all handle positioning slightly differently.\n"
+"For platforms that do not offer spatial tracking, our origin point (0,0,0) "
+"is the location of our HMD, but you have little control over the direction "
+"the player is facing in the real world.\n"
+"For platforms that do offer spatial tracking, our origin point depends very "
+"much on the system. For OpenVR, our origin point is usually the center of "
+"the tracking space, on the ground. For other platforms, it's often the "
+"location of the tracking camera.\n"
+"This method allows you to center your tracker on the location of the HMD. It "
+"will take the current location of the HMD and use that to adjust all your "
+"tracking data; in essence, realigning the real world to your player's "
+"current position in the game world.\n"
+"For this method to produce usable results, tracking information must be "
+"available. This often takes a few frames after starting your game.\n"
+"You should call this method after a few seconds have passed. For instance, "
+"when the user requests a realignment of the display holding a designated "
+"button on a controller for a short period of time, or when implementing a "
+"teleport mechanism."
+msgstr ""
+
+#: doc/classes/XRServer.xml:35
+msgid ""
+"Finds an interface by its name. For instance, if your project uses "
+"capabilities of an AR/VR platform, you can find the interface for that "
+"platform by name and initialize it."
+msgstr ""
+
+#: doc/classes/XRServer.xml:42
+msgid "Returns the primary interface's transformation."
+msgstr ""
+
+#: doc/classes/XRServer.xml:51
+msgid ""
+"Returns the interface registered at a given index in our list of interfaces."
+msgstr ""
+
+#: doc/classes/XRServer.xml:58
+msgid ""
+"Returns the number of interfaces currently registered with the AR/VR server. "
+"If your project supports multiple AR/VR platforms, you can look through the "
+"available interface, and either present the user with a selection or simply "
+"try to initialize each interface and use the first one that returns "
+"[code]true[/code]."
+msgstr ""
+
+#: doc/classes/XRServer.xml:65
+msgid ""
+"Returns a list of available interfaces the ID and name of each interface."
+msgstr ""
+
+#: doc/classes/XRServer.xml:72
+msgid ""
+"Returns the absolute timestamp (in μs) of the last [XRServer] commit of the "
+"AR/VR eyes to [RenderingServer]. The value comes from an internal call to "
+"[method OS.get_ticks_usec]."
+msgstr ""
+
+#: doc/classes/XRServer.xml:79
+msgid ""
+"Returns the duration (in μs) of the last frame. This is computed as the "
+"difference between [method get_last_commit_usec] and [method "
+"get_last_process_usec] when committing."
+msgstr ""
+
+#: doc/classes/XRServer.xml:86
+msgid ""
+"Returns the absolute timestamp (in μs) of the last [XRServer] process "
+"callback. The value comes from an internal call to [method OS."
+"get_ticks_usec]."
+msgstr ""
+
+#: doc/classes/XRServer.xml:93
+msgid ""
+"Returns the reference frame transform. Mostly used internally and exposed "
+"for GDNative build interfaces."
+msgstr ""
+
+#: doc/classes/XRServer.xml:102
+msgid "Returns the positional tracker at the given ID."
+msgstr ""
+
+#: doc/classes/XRServer.xml:109
+msgid "Returns the number of trackers currently registered."
+msgstr ""
+
+#: doc/classes/XRServer.xml:115
+msgid "The primary [XRInterface] currently bound to the [XRServer]."
+msgstr ""
+
+#: doc/classes/XRServer.xml:118
+msgid ""
+"Allows you to adjust the scale to your game's units. Most AR/VR platforms "
+"assume a scale of 1 game world unit = 1 real world meter."
+msgstr ""
+
+#: doc/classes/XRServer.xml:126
+msgid "Emitted when a new interface has been added."
+msgstr ""
+
+#: doc/classes/XRServer.xml:133
+msgid "Emitted when an interface is removed."
+msgstr ""
+
+#: doc/classes/XRServer.xml:144
+msgid ""
+"Emitted when a new tracker has been added. If you don't use a fixed number "
+"of controllers or if you're using [XRAnchor3D]s for an AR solution, it is "
+"important to react to this signal to add the appropriate [XRController3D] or "
+"[XRAnchor3D] nodes related to this new tracker."
+msgstr ""
+
+#: doc/classes/XRServer.xml:155
+msgid ""
+"Emitted when a tracker is removed. You should remove any [XRController3D] or "
+"[XRAnchor3D] points if applicable. This is not mandatory, the nodes simply "
+"become inactive and will be made active again when a new tracker becomes "
+"available (i.e. a new controller is switched on that takes the place of the "
+"previous one)."
+msgstr ""
+
+#: doc/classes/XRServer.xml:161
+msgid "The tracker tracks the location of a controller."
+msgstr ""
+
+#: doc/classes/XRServer.xml:164
+msgid "The tracker tracks the location of a base station."
+msgstr ""
+
+#: doc/classes/XRServer.xml:167
+msgid "The tracker tracks the location and size of an AR anchor."
+msgstr ""
+
+#: doc/classes/XRServer.xml:170
+msgid "Used internally to filter trackers of any known type."
+msgstr ""
+
+#: doc/classes/XRServer.xml:173
+msgid "Used internally if we haven't set the tracker type yet."
+msgstr ""
+
+#: doc/classes/XRServer.xml:176
+msgid "Used internally to select all trackers."
+msgstr ""
+
+#: doc/classes/XRServer.xml:179
+msgid ""
+"Fully reset the orientation of the HMD. Regardless of what direction the "
+"user is looking to in the real world. The user will look dead ahead in the "
+"virtual world."
+msgstr ""
+
+#: doc/classes/XRServer.xml:182
+msgid ""
+"Resets the orientation but keeps the tilt of the device. So if we're looking "
+"down, we keep looking down but heading will be reset."
+msgstr ""
+
+#: doc/classes/XRServer.xml:185
+msgid ""
+"Does not reset the orientation of the HMD, only the position of the player "
+"gets centered."
+msgstr ""
+
#: doc/classes/YSort.xml:4
msgid "Sort all child nodes based on their Y positions."
msgstr ""
diff --git a/drivers/alsa/audio_driver_alsa.cpp b/drivers/alsa/audio_driver_alsa.cpp
index 48e694dd3a..90c3d3af83 100644
--- a/drivers/alsa/audio_driver_alsa.cpp
+++ b/drivers/alsa/audio_driver_alsa.cpp
@@ -38,7 +38,7 @@
#include <errno.h>
Error AudioDriverALSA::init_device() {
- mix_rate = GLOBAL_DEF("audio/mix_rate", DEFAULT_MIX_RATE);
+ mix_rate = GLOBAL_GET("audio/mix_rate");
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
@@ -104,7 +104,7 @@ Error AudioDriverALSA::init_device() {
// In ALSA the period size seems to be the one that will determine the actual latency
// Ref: https://www.alsa-project.org/main/index.php/FramesPeriods
unsigned int periods = 2;
- int latency = GLOBAL_DEF("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ int latency = GLOBAL_GET("audio/output_latency");
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
buffer_size = buffer_frames * periods;
period_size = buffer_frames;
@@ -147,7 +147,6 @@ Error AudioDriverALSA::init_device() {
}
Error AudioDriverALSA::init() {
-
active = false;
thread_exited = false;
exit_thread = false;
@@ -161,11 +160,9 @@ Error AudioDriverALSA::init() {
}
void AudioDriverALSA::thread_func(void *p_udata) {
-
AudioDriverALSA *ad = (AudioDriverALSA *)p_udata;
while (!ad->exit_thread) {
-
ad->lock();
ad->start_counting_ticks();
@@ -237,30 +234,27 @@ void AudioDriverALSA::thread_func(void *p_udata) {
}
void AudioDriverALSA::start() {
-
active = true;
}
int AudioDriverALSA::get_mix_rate() const {
-
return mix_rate;
}
AudioDriver::SpeakerMode AudioDriverALSA::get_speaker_mode() const {
-
return speaker_mode;
}
Array AudioDriverALSA::get_device_list() {
-
Array list;
list.push_back("Default");
void **hints;
- if (snd_device_name_hint(-1, "pcm", &hints) < 0)
+ if (snd_device_name_hint(-1, "pcm", &hints) < 0) {
return list;
+ }
for (void **n = hints; *n != nullptr; n++) {
char *name = snd_device_name_get_hint(*n, "NAME");
@@ -274,10 +268,12 @@ Array AudioDriverALSA::get_device_list() {
}
}
- if (desc != nullptr)
+ if (desc != nullptr) {
free(desc);
- if (name != nullptr)
+ }
+ if (name != nullptr) {
free(name);
+ }
}
snd_device_name_free_hint(hints);
@@ -285,33 +281,30 @@ Array AudioDriverALSA::get_device_list() {
}
String AudioDriverALSA::get_device() {
-
return device_name;
}
void AudioDriverALSA::set_device(String device) {
-
lock();
new_device = device;
unlock();
}
void AudioDriverALSA::lock() {
-
- if (!thread)
+ if (!thread) {
return;
+ }
mutex.lock();
}
void AudioDriverALSA::unlock() {
-
- if (!thread)
+ if (!thread) {
return;
+ }
mutex.unlock();
}
void AudioDriverALSA::finish_device() {
-
if (pcm_handle) {
snd_pcm_close(pcm_handle);
pcm_handle = nullptr;
@@ -319,7 +312,6 @@ void AudioDriverALSA::finish_device() {
}
void AudioDriverALSA::finish() {
-
if (thread) {
exit_thread = true;
Thread::wait_to_finish(thread);
@@ -331,14 +323,4 @@ void AudioDriverALSA::finish() {
finish_device();
}
-AudioDriverALSA::AudioDriverALSA() :
- thread(nullptr),
- pcm_handle(nullptr),
- device_name("Default"),
- new_device("Default") {
-}
-
-AudioDriverALSA::~AudioDriverALSA() {
-}
-
-#endif
+#endif // ALSA_ENABLED
diff --git a/drivers/alsa/audio_driver_alsa.h b/drivers/alsa/audio_driver_alsa.h
index 50bd9e853d..7aec0c4071 100644
--- a/drivers/alsa/audio_driver_alsa.h
+++ b/drivers/alsa/audio_driver_alsa.h
@@ -40,14 +40,13 @@
#include <alsa/asoundlib.h>
class AudioDriverALSA : public AudioDriver {
-
- Thread *thread;
+ Thread *thread = nullptr;
Mutex mutex;
- snd_pcm_t *pcm_handle;
+ snd_pcm_t *pcm_handle = nullptr;
- String device_name;
- String new_device;
+ String device_name = "Default";
+ String new_device = "Default";
Vector<int32_t> samples_in;
Vector<int16_t> samples_out;
@@ -85,8 +84,8 @@ public:
virtual void unlock();
virtual void finish();
- AudioDriverALSA();
- ~AudioDriverALSA();
+ AudioDriverALSA() {}
+ ~AudioDriverALSA() {}
};
#endif // AUDIO_DRIVER_ALSA_H
diff --git a/drivers/alsamidi/midi_driver_alsamidi.cpp b/drivers/alsamidi/midi_driver_alsamidi.cpp
index e3e54ea267..69a6956c2b 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.cpp
+++ b/drivers/alsamidi/midi_driver_alsamidi.cpp
@@ -125,11 +125,11 @@ void MIDIDriverALSAMidi::thread_func(void *p_udata) {
}
Error MIDIDriverALSAMidi::open() {
-
void **hints;
- if (snd_device_name_hint(-1, "rawmidi", &hints) < 0)
+ if (snd_device_name_hint(-1, "rawmidi", &hints) < 0) {
return ERR_CANT_OPEN;
+ }
int i = 0;
for (void **n = hints; *n != nullptr; n++) {
@@ -143,8 +143,9 @@ Error MIDIDriverALSAMidi::open() {
}
}
- if (name != nullptr)
+ if (name != nullptr) {
free(name);
+ }
}
snd_device_name_free_hint(hints);
@@ -155,7 +156,6 @@ Error MIDIDriverALSAMidi::open() {
}
void MIDIDriverALSAMidi::close() {
-
if (thread) {
exit_thread = true;
Thread::wait_to_finish(thread);
@@ -172,17 +172,14 @@ void MIDIDriverALSAMidi::close() {
}
void MIDIDriverALSAMidi::lock() const {
-
mutex.lock();
}
void MIDIDriverALSAMidi::unlock() const {
-
mutex.unlock();
}
PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() {
-
PackedStringArray list;
lock();
@@ -201,14 +198,12 @@ PackedStringArray MIDIDriverALSAMidi::get_connected_inputs() {
}
MIDIDriverALSAMidi::MIDIDriverALSAMidi() {
-
thread = nullptr;
exit_thread = false;
}
MIDIDriverALSAMidi::~MIDIDriverALSAMidi() {
-
close();
}
diff --git a/drivers/alsamidi/midi_driver_alsamidi.h b/drivers/alsamidi/midi_driver_alsamidi.h
index 6797c7c138..e8ed6df5b0 100644
--- a/drivers/alsamidi/midi_driver_alsamidi.h
+++ b/drivers/alsamidi/midi_driver_alsamidi.h
@@ -42,7 +42,6 @@
#include <stdio.h>
class MIDIDriverALSAMidi : public MIDIDriver {
-
Thread *thread;
Mutex mutex;
diff --git a/drivers/coreaudio/audio_driver_coreaudio.cpp b/drivers/coreaudio/audio_driver_coreaudio.cpp
index 21c3649445..48d0a29516 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.cpp
+++ b/drivers/coreaudio/audio_driver_coreaudio.cpp
@@ -116,7 +116,7 @@ Error AudioDriverCoreAudio::init() {
break;
}
- mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+ mix_rate = GLOBAL_GET("audio/mix_rate");
zeromem(&strdesc, sizeof(strdesc));
strdesc.mFormatID = kAudioFormatLinearPCM;
@@ -131,7 +131,7 @@ Error AudioDriverCoreAudio::init() {
result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &strdesc, sizeof(strdesc));
ERR_FAIL_COND_V(result != noErr, FAILED);
- int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ int latency = GLOBAL_GET("audio/output_latency");
// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
@@ -168,7 +168,6 @@ OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData) {
-
AudioDriverCoreAudio *ad = (AudioDriverCoreAudio *)inRefCon;
if (!ad->active || !ad->try_lock()) {
@@ -182,18 +181,15 @@ OSStatus AudioDriverCoreAudio::output_callback(void *inRefCon,
ad->start_counting_ticks();
for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
-
AudioBuffer *abuf = &ioData->mBuffers[i];
unsigned int frames_left = inNumberFrames;
int16_t *out = (int16_t *)abuf->mData;
while (frames_left) {
-
unsigned int frames = MIN(frames_left, ad->buffer_frames);
ad->audio_server_process(frames, ad->samples_in.ptrw());
for (unsigned int j = 0; j < frames * ad->channels; j++) {
-
out[j] = ad->samples_in[j] >> 16;
}
@@ -213,7 +209,6 @@ OSStatus AudioDriverCoreAudio::input_callback(void *inRefCon,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData) {
-
AudioDriverCoreAudio *ad = (AudioDriverCoreAudio *)inRefCon;
if (!ad->active) {
return 0;
@@ -408,7 +403,7 @@ Error AudioDriverCoreAudio::capture_init() {
break;
}
- mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+ mix_rate = GLOBAL_GET("audio/mix_rate");
zeromem(&strdesc, sizeof(strdesc));
strdesc.mFormatID = kAudioFormatLinearPCM;
@@ -475,7 +470,6 @@ void AudioDriverCoreAudio::capture_finish() {
}
Error AudioDriverCoreAudio::capture_start() {
-
input_buffer_init(buffer_frames);
OSStatus result = AudioOutputUnitStart(input_unit);
@@ -487,7 +481,6 @@ Error AudioDriverCoreAudio::capture_start() {
}
Error AudioDriverCoreAudio::capture_stop() {
-
if (input_unit) {
OSStatus result = AudioOutputUnitStop(input_unit);
if (result != noErr) {
@@ -501,7 +494,6 @@ Error AudioDriverCoreAudio::capture_stop() {
#ifdef OSX_ENABLED
Array AudioDriverCoreAudio::_get_device_list(bool capture) {
-
Array list;
list.push_back("Default");
@@ -558,7 +550,6 @@ Array AudioDriverCoreAudio::_get_device_list(bool capture) {
}
void AudioDriverCoreAudio::_set_device(const String &device, bool capture) {
-
AudioDeviceID deviceId;
bool found = false;
if (device != "Default") {
@@ -639,17 +630,14 @@ void AudioDriverCoreAudio::_set_device(const String &device, bool capture) {
}
Array AudioDriverCoreAudio::get_device_list() {
-
return _get_device_list();
}
String AudioDriverCoreAudio::get_device() {
-
return device_name;
}
void AudioDriverCoreAudio::set_device(String device) {
-
device_name = device;
if (active) {
_set_device(device_name);
@@ -657,7 +645,6 @@ void AudioDriverCoreAudio::set_device(String device) {
}
void AudioDriverCoreAudio::capture_set_device(const String &p_name) {
-
capture_device_name = p_name;
if (active) {
_set_device(capture_device_name, true);
@@ -665,30 +652,17 @@ void AudioDriverCoreAudio::capture_set_device(const String &p_name) {
}
Array AudioDriverCoreAudio::capture_get_device_list() {
-
return _get_device_list(true);
}
String AudioDriverCoreAudio::capture_get_device() {
-
return capture_device_name;
}
#endif
-AudioDriverCoreAudio::AudioDriverCoreAudio() :
- audio_unit(nullptr),
- input_unit(nullptr),
- active(false),
- device_name("Default"),
- capture_device_name("Default"),
- mix_rate(0),
- channels(2),
- capture_channels(2),
- buffer_frames(0) {
+AudioDriverCoreAudio::AudioDriverCoreAudio() {
samples_in.clear();
}
-AudioDriverCoreAudio::~AudioDriverCoreAudio(){};
-
-#endif
+#endif // COREAUDIO_ENABLED
diff --git a/drivers/coreaudio/audio_driver_coreaudio.h b/drivers/coreaudio/audio_driver_coreaudio.h
index fb9473e230..6b7a35588f 100644
--- a/drivers/coreaudio/audio_driver_coreaudio.h
+++ b/drivers/coreaudio/audio_driver_coreaudio.h
@@ -41,20 +41,19 @@
#endif
class AudioDriverCoreAudio : public AudioDriver {
+ AudioComponentInstance audio_unit = nullptr;
+ AudioComponentInstance input_unit = nullptr;
- AudioComponentInstance audio_unit;
- AudioComponentInstance input_unit;
-
- bool active;
+ bool active = false;
Mutex mutex;
- String device_name;
- String capture_device_name;
+ String device_name = "Default";
+ String capture_device_name = "Default";
- int mix_rate;
- unsigned int channels;
- unsigned int capture_channels;
- unsigned int buffer_frames;
+ int mix_rate = 0;
+ unsigned int channels = 2;
+ unsigned int capture_channels = 2;
+ unsigned int buffer_frames = 0;
Vector<int32_t> samples_in;
Vector<int16_t> input_buf;
@@ -118,7 +117,7 @@ public:
#endif
AudioDriverCoreAudio();
- ~AudioDriverCoreAudio();
+ ~AudioDriverCoreAudio() {}
};
#endif
diff --git a/drivers/coremidi/midi_driver_coremidi.cpp b/drivers/coremidi/midi_driver_coremidi.cpp
index 2cd322813b..004c594e17 100644
--- a/drivers/coremidi/midi_driver_coremidi.cpp
+++ b/drivers/coremidi/midi_driver_coremidi.cpp
@@ -46,7 +46,6 @@ void MIDIDriverCoreMidi::read(const MIDIPacketList *packet_list, void *read_proc
}
Error MIDIDriverCoreMidi::open() {
-
CFStringRef name = CFStringCreateWithCString(nullptr, "Godot", kCFStringEncodingASCII);
OSStatus result = MIDIClientCreate(name, nullptr, nullptr, &client);
CFRelease(name);
@@ -63,7 +62,6 @@ Error MIDIDriverCoreMidi::open() {
int sources = MIDIGetNumberOfSources();
for (int i = 0; i < sources; i++) {
-
MIDIEndpointRef source = MIDIGetSource(i);
if (source) {
MIDIPortConnectSource(port_in, source, (void *)this);
@@ -75,7 +73,6 @@ Error MIDIDriverCoreMidi::open() {
}
void MIDIDriverCoreMidi::close() {
-
for (int i = 0; i < connected_sources.size(); i++) {
MIDIEndpointRef source = connected_sources[i];
MIDIPortDisconnectSource(port_in, source);
@@ -94,7 +91,6 @@ void MIDIDriverCoreMidi::close() {
}
PackedStringArray MIDIDriverCoreMidi::get_connected_inputs() {
-
PackedStringArray list;
for (int i = 0; i < connected_sources.size(); i++) {
@@ -112,9 +108,7 @@ PackedStringArray MIDIDriverCoreMidi::get_connected_inputs() {
return list;
}
-MIDIDriverCoreMidi::MIDIDriverCoreMidi() :
- client(0) {
-}
+MIDIDriverCoreMidi::MIDIDriverCoreMidi() {}
MIDIDriverCoreMidi::~MIDIDriverCoreMidi() {
close();
diff --git a/drivers/coremidi/midi_driver_coremidi.h b/drivers/coremidi/midi_driver_coremidi.h
index e8b4481c20..0459544f75 100644
--- a/drivers/coremidi/midi_driver_coremidi.h
+++ b/drivers/coremidi/midi_driver_coremidi.h
@@ -40,8 +40,7 @@
#include <stdio.h>
class MIDIDriverCoreMidi : public MIDIDriver {
-
- MIDIClientRef client;
+ MIDIClientRef client = 0;
MIDIPortRef port_in;
Vector<MIDIEndpointRef> connected_sources;
diff --git a/drivers/dummy/rasterizer_dummy.h b/drivers/dummy/rasterizer_dummy.h
index 0bcfed2dcf..7af7678f63 100644
--- a/drivers/dummy/rasterizer_dummy.h
+++ b/drivers/dummy/rasterizer_dummy.h
@@ -59,6 +59,7 @@ public:
void sky_set_texture(RID p_sky, RID p_panorama) {}
void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) {}
void sky_set_material(RID p_sky, RID p_material) {}
+ virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) { return Ref<Image>(); }
/* ENVIRONMENT API */
@@ -78,10 +79,11 @@ public:
#endif
void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {}
-
+ virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) {}
void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {}
- void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance, bool p_roughness) {}
+ void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) {}
+ virtual void environment_set_ssr_roughness_quality(RS::EnvironmentSSRRoughnessQuality p_quality) {}
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {}
virtual void environment_set_ssao_quality(RS::EnvironmentSSAOQuality p_quality, bool p_half_size) {}
@@ -93,6 +95,8 @@ public:
void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {}
void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {}
+ virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) { return Ref<Image>(); }
+
bool is_environment(RID p_env) const { return false; }
RS::EnvironmentBG environment_get_background(RID p_env) const { return RS::ENV_BG_KEEP; }
int environment_get_canvas_max_layer(RID p_env) const { return 0; }
@@ -105,9 +109,12 @@ public:
virtual void camera_effects_set_dof_blur(RID p_camera_effects, bool p_far_enable, float p_far_distance, float p_far_transition, bool p_near_enable, float p_near_distance, float p_near_transition, float p_amount) {}
virtual void camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) {}
+ virtual void shadows_quality_set(RS::ShadowQuality p_quality) {}
+ virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) {}
+
RID light_instance_create(RID p_light) { return RID(); }
void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {}
- void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) {}
+ void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) {}
void light_instance_mark_visible(RID p_light_instance) {}
RID reflection_atlas_create() { return RID(); }
@@ -121,13 +128,16 @@ public:
bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) { return false; }
bool reflection_probe_instance_postprocess_step(RID p_instance) { return true; }
+ virtual RID decal_instance_create(RID p_decal) { return RID(); }
+ virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) {}
+
virtual RID gi_probe_instance_create(RID p_gi_probe) { return RID(); }
void gi_probe_instance_set_light_data(RID p_probe, RID p_base, RID p_data) {}
void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) {}
virtual bool gi_probe_needs_update(RID p_probe) const { return false; }
virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) {}
- virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {}
+ virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {}
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {}
virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {}
@@ -136,11 +146,16 @@ public:
void set_debug_draw_mode(RS::ViewportDebugDraw p_debug_draw) {}
virtual RID render_buffers_create() { return RID(); }
- virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa) {}
+ virtual void render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RS::ViewportScreenSpaceAA p_screen_space_aa) {}
virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve) {}
virtual bool screen_space_roughness_limiter_is_active() const { return false; }
+ virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) {}
+ virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) {}
+
+ virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) { return TypedArray<Image>(); }
+
bool free(RID p_rid) { return true; }
virtual void update() {}
@@ -192,7 +207,7 @@ public:
virtual void texture_proxy_update(RID p_proxy, RID p_base) {}
virtual RID texture_2d_placeholder_create() { return RID(); }
- virtual RID texture_2d_layered_placeholder_create() { return RID(); }
+ virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) { return RID(); }
virtual RID texture_3d_placeholder_create() { return RID(); }
virtual Ref<Image> texture_2d_get(RID p_texture) const { return Ref<Image>(); }
@@ -217,6 +232,9 @@ public:
virtual void texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {}
virtual Size2 texture_size_with_proxy(RID p_proxy) { return Size2(); }
+ virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) {}
+ virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) {}
+
#if 0
RID texture_create() {
@@ -345,6 +363,7 @@ public:
bool material_is_animated(RID p_material) { return false; }
bool material_casts_shadows(RID p_material) { return false; }
+ virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) {}
void material_update_dependency(RID p_material, RasterizerScene::InstanceBase *p_instance) {}
/* MESH API */
@@ -608,6 +627,21 @@ public:
virtual void base_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) {}
virtual void skeleton_update_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) {}
+ /* DECAL API */
+
+ virtual RID decal_create() { return RID(); }
+ virtual void decal_set_extents(RID p_decal, const Vector3 &p_extents) {}
+ virtual void decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {}
+ virtual void decal_set_emission_energy(RID p_decal, float p_energy) {}
+ virtual void decal_set_albedo_mix(RID p_decal, float p_mix) {}
+ virtual void decal_set_modulate(RID p_decal, const Color &p_modulate) {}
+ virtual void decal_set_cull_mask(RID p_decal, uint32_t p_layers) {}
+ virtual void decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {}
+ virtual void decal_set_fade(RID p_decal, float p_above, float p_below) {}
+ virtual void decal_set_normal_fade(RID p_decal, float p_fade) {}
+
+ virtual AABB decal_get_aabb(RID p_decal) const { return AABB(); }
+
/* GI PROBE API */
RID gi_probe_create() { return RID(); }
@@ -656,6 +690,7 @@ public:
uint32_t gi_probe_get_version(RID p_gi_probe) { return 0; }
/* LIGHTMAP CAPTURE */
+#if 0
struct Instantiable {
SelfList<RasterizerScene::InstanceBase>::List instance_list;
@@ -722,6 +757,23 @@ public:
ERR_FAIL_COND_V(!capture, nullptr);
return &capture->octree;
}
+#endif
+
+ virtual RID lightmap_create() { return RID(); }
+
+ virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {}
+ virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) {}
+ virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) {}
+ virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {}
+ virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const { return PackedVector3Array(); }
+ virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const { return PackedColorArray(); }
+ virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const { return PackedInt32Array(); }
+ virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const { return PackedInt32Array(); }
+ virtual AABB lightmap_get_aabb(RID p_lightmap) const { return AABB(); }
+ virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) {}
+ virtual bool lightmap_is_interior(RID p_lightmap) const { return false; }
+ virtual void lightmap_set_probe_capture_update_speed(float p_speed) {}
+ virtual float lightmap_get_probe_capture_update_speed() const { return 0; }
/* PARTICLES */
@@ -757,6 +809,24 @@ public:
int particles_get_draw_passes(RID p_particles) const { return 0; }
RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const { return RID(); }
+ /* GLOBAL VARIABLES */
+
+ virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) {}
+ virtual void global_variable_remove(const StringName &p_name) {}
+ virtual Vector<StringName> global_variable_get_list() const { return Vector<StringName>(); }
+
+ virtual void global_variable_set(const StringName &p_name, const Variant &p_value) {}
+ virtual void global_variable_set_override(const StringName &p_name, const Variant &p_value) {}
+ virtual Variant global_variable_get(const StringName &p_name) const { return Variant(); }
+ virtual RS::GlobalVariableType global_variable_get_type(const StringName &p_name) const { return RS::GLOBAL_VAR_TYPE_MAX; }
+
+ virtual void global_variables_load_settings(bool p_load_textures = true) {}
+ virtual void global_variables_clear() {}
+
+ virtual int32_t global_variables_instance_allocate(RID p_instance) { return 0; }
+ virtual void global_variables_instance_free(RID p_instance) {}
+ virtual void global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {}
+
virtual bool particles_is_inactive(RID p_particles) const { return false; }
/* RENDER TARGET */
@@ -785,13 +855,19 @@ public:
}
bool free(RID p_rid) {
-
if (texture_owner.owns(p_rid)) {
// delete the texture
DummyTexture *texture = texture_owner.getornull(p_rid);
texture_owner.free(p_rid);
memdelete(texture);
}
+
+ if (mesh_owner.owns(p_rid)) {
+ // delete the mesh
+ DummyMesh *mesh = mesh_owner.getornull(p_rid);
+ mesh_owner.free(p_rid);
+ memdelete(mesh);
+ }
return true;
}
@@ -853,6 +929,10 @@ public:
};
class RasterizerDummy : public Rasterizer {
+private:
+ uint64_t frame = 1;
+ float delta = 0;
+
protected:
RasterizerCanvasDummy canvas;
RasterizerStorageDummy storage;
@@ -866,12 +946,20 @@ public:
void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter = true) {}
void initialize() {}
- void begin_frame(double frame_step) {}
+ void begin_frame(double frame_step) {
+ frame++;
+ delta = frame_step;
+ }
virtual void prepare_for_blitting_render_targets() {}
virtual void blit_render_targets_to_screen(int p_screen, const BlitToScreen *p_render_targets, int p_amount) {}
- void end_frame(bool p_swap_buffers) { OS::get_singleton()->swap_buffers(); }
+ void end_frame(bool p_swap_buffers) {
+ if (p_swap_buffers) {
+ DisplayServer::get_singleton()->swap_buffers();
+ }
+ }
+
void finalize() {}
static Error is_viable() {
@@ -887,6 +975,8 @@ public:
}
virtual bool is_low_end() const { return true; }
+ virtual uint64_t get_frame_number() const { return frame; }
+ virtual float get_frame_delta_time() const { return delta; }
RasterizerDummy() {}
~RasterizerDummy() {}
diff --git a/drivers/dummy/texture_loader_dummy.cpp b/drivers/dummy/texture_loader_dummy.cpp
index 95876f5c7d..ddd2943720 100644
--- a/drivers/dummy/texture_loader_dummy.cpp
+++ b/drivers/dummy/texture_loader_dummy.cpp
@@ -35,7 +35,7 @@
#include <string.h>
-RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
unsigned int width = 8;
unsigned int height = 8;
@@ -67,10 +67,19 @@ RES ResourceFormatDummyTexture::load(const String &p_path, const String &p_origi
}
void ResourceFormatDummyTexture::get_recognized_extensions(List<String> *p_extensions) const {
- p_extensions->push_back("png");
- p_extensions->push_back("hdr");
+ p_extensions->push_back("bmp");
+ p_extensions->push_back("dds");
+ p_extensions->push_back("exr");
+ p_extensions->push_back("jpeg");
p_extensions->push_back("jpg");
+ p_extensions->push_back("hdr");
+ p_extensions->push_back("pkm");
+ p_extensions->push_back("png");
+ p_extensions->push_back("pvr");
+ p_extensions->push_back("svg");
+ p_extensions->push_back("svgz");
p_extensions->push_back("tga");
+ p_extensions->push_back("webp");
}
bool ResourceFormatDummyTexture::handles_type(const String &p_type) const {
@@ -79,7 +88,22 @@ bool ResourceFormatDummyTexture::handles_type(const String &p_type) const {
String ResourceFormatDummyTexture::get_resource_type(const String &p_path) const {
String extension = p_path.get_extension().to_lower();
- if (extension == "png" || extension == "hdr" || extension == "jpg" || extension == "tga")
+ if (
+ extension == "bmp" ||
+ extension == "dds" ||
+ extension == "exr" ||
+ extension == "jpeg" ||
+ extension == "jpg" ||
+ extension == "hdr" ||
+ extension == "pkm" ||
+ extension == "png" ||
+ extension == "pvr" ||
+ extension == "svg" ||
+ extension == "svgz" ||
+ extension == "tga" ||
+ extension == "webp") {
return "ImageTexture";
+ }
+
return "";
}
diff --git a/drivers/dummy/texture_loader_dummy.h b/drivers/dummy/texture_loader_dummy.h
index 2a7d01dd78..ef9f3b13b6 100644
--- a/drivers/dummy/texture_loader_dummy.h
+++ b/drivers/dummy/texture_loader_dummy.h
@@ -36,7 +36,7 @@
class ResourceFormatDummyTexture : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index 069eeaba6c..c92eb4cd11 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -40,7 +40,6 @@
#endif
RID RasterizerCanvasGLES2::light_internal_create() {
-
return RID();
}
@@ -51,7 +50,6 @@ void RasterizerCanvasGLES2::light_internal_free(RID p_rid) {
}
void RasterizerCanvasGLES2::_set_uniforms() {
-
state.canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX, state.uniforms.projection_matrix);
state.canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX, state.uniforms.modelview_matrix);
state.canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX, state.uniforms.extra_matrix);
@@ -75,7 +73,6 @@ void RasterizerCanvasGLES2::_set_uniforms() {
}
if (state.using_light) {
-
Light *light = state.using_light;
state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_MATRIX, light->light_shader_xform);
Transform2D basis_inverse = light->light_shader_xform.affine_inverse().orthonormalized();
@@ -110,7 +107,6 @@ void RasterizerCanvasGLES2::_set_uniforms() {
}
void RasterizerCanvasGLES2::canvas_begin() {
-
state.canvas_shader.bind();
state.using_transparent_rt = false;
int viewport_x, viewport_y, viewport_width, viewport_height;
@@ -160,7 +156,6 @@ void RasterizerCanvasGLES2::canvas_begin() {
Transform canvas_transform;
if (storage->frame.current_rt) {
-
float csy = 1.0;
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
csy = -1.0;
@@ -185,7 +180,6 @@ void RasterizerCanvasGLES2::canvas_begin() {
}
void RasterizerCanvasGLES2::canvas_end() {
-
glBindBuffer(GL_ARRAY_BUFFER, 0);
for (int i = 0; i < RS::ARRAY_MAX; i++) {
@@ -207,11 +201,9 @@ void RasterizerCanvasGLES2::canvas_end() {
}
RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map) {
-
RasterizerStorageGLES2::Texture *tex_return = nullptr;
if (p_texture.is_valid()) {
-
RasterizerStorageGLES2::Texture *texture = storage->texture_owner.getornull(p_texture);
if (!texture) {
@@ -222,7 +214,6 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
} else {
-
if (texture->redraw_if_visible) {
RenderingServerRaster::redraw_request();
}
@@ -254,7 +245,6 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, state.current_normal.is_valid());
} else if (p_normal_map.is_valid()) {
-
RasterizerStorageGLES2::Texture *normal_map = storage->texture_owner.getornull(p_normal_map);
if (!normal_map) {
@@ -264,7 +254,6 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, false);
} else {
-
if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies
RenderingServerRaster::redraw_request();
}
@@ -278,7 +267,6 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
}
} else {
-
state.current_normal = RID();
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
@@ -289,7 +277,6 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
}
void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights, const int *p_bones) {
-
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
#ifndef GLES_OVER_GL
// Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
@@ -365,7 +352,6 @@ void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_coun
}
void RasterizerCanvasGLES2::_draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) {
-
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
#ifndef GLES_OVER_GL
// Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
@@ -407,7 +393,6 @@ void RasterizerCanvasGLES2::_draw_generic(GLuint p_primitive, int p_vertex_count
}
void RasterizerCanvasGLES2::_draw_generic_indices(GLuint p_primitive, const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) {
-
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
#ifndef GLES_OVER_GL
// Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
@@ -467,7 +452,6 @@ void RasterizerCanvasGLES2::_draw_generic_indices(GLuint p_primitive, const int
}
void RasterizerCanvasGLES2::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs) {
-
static const GLenum prim[5] = { GL_POINTS, GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN };
int color_offset = 0;
@@ -542,18 +526,14 @@ static const GLenum gl_primitive[] = {
};
void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip, RasterizerStorageGLES2::Material *p_material) {
-
int command_count = p_item->commands.size();
Item::Command **commands = p_item->commands.ptrw();
for (int i = 0; i < command_count; i++) {
-
Item::Command *command = commands[i];
switch (command->type) {
-
case Item::Command::TYPE_LINE: {
-
Item::CommandLine *line = static_cast<Item::CommandLine *>(command);
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
@@ -613,7 +593,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
} break;
case Item::Command::TYPE_RECT: {
-
Item::CommandRect *r = static_cast<Item::CommandRect *>(command);
glDisableVertexAttribArray(RS::ARRAY_COLOR);
@@ -626,7 +605,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
RasterizerStorageGLES2::Texture *texture = storage->texture_owner.getornull(r->texture);
if (texture) {
-
texture = texture->get_ptr();
if (next_power_of_2(texture->alloc_width) != (unsigned int)texture->alloc_width && next_power_of_2(texture->alloc_height) != (unsigned int)texture->alloc_height) {
@@ -750,7 +728,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
} else {
-
bool untile = false;
if (can_tile && r->flags & CANVAS_RECT_TILE && !(tex->flags & RS::TEXTURE_FLAG_REPEAT)) {
@@ -807,7 +784,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
} break;
case Item::Command::TYPE_NINEPATCH: {
-
Item::CommandNinePatch *np = static_cast<Item::CommandNinePatch *>(command);
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
@@ -845,7 +821,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
float screen_scale = 1.0;
if (source.size.x != 0 && source.size.y != 0) {
-
screen_scale = MIN(np->rect.size.x / source.size.x, np->rect.size.y / source.size.y);
screen_scale = MIN(1.0, screen_scale);
}
@@ -857,7 +832,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
float buffer[16 * 2 + 16 * 2];
{
-
// first row
buffer[(0 * 4 * 4) + 0] = np->rect.position.x;
@@ -982,7 +956,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
} break;
case Item::Command::TYPE_CIRCLE: {
-
Item::CommandCircle *circle = static_cast<Item::CommandCircle *>(command);
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
@@ -1012,7 +985,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
} break;
case Item::Command::TYPE_POLYGON: {
-
Item::CommandPolygon *polygon = static_cast<Item::CommandPolygon *>(command);
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
@@ -1043,7 +1015,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
#endif
} break;
case Item::Command::TYPE_MESH: {
-
Item::CommandMesh *mesh = static_cast<Item::CommandMesh *>(command);
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
@@ -1061,7 +1032,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
RasterizerStorageGLES2::Mesh *mesh_data = storage->mesh_owner.getornull(mesh->mesh);
if (mesh_data) {
-
for (int j = 0; j < mesh_data->surfaces.size(); j++) {
RasterizerStorageGLES2::Surface *s = mesh_data->surfaces[j];
// materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing
@@ -1186,7 +1156,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
const float *buffer = base_buffer + k * stride;
{
-
glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 0, &buffer[0]);
glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 1, &buffer[4]);
if (multi_mesh->transform_format == RS::MULTIMESH_TRANSFORM_3D) {
@@ -1252,7 +1221,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
glDisable(GL_LINE_SMOOTH);
#endif
} else {
-
#ifdef GLES_OVER_GL
if (pline->antialiased)
glEnable(GL_LINE_SMOOTH);
@@ -1281,7 +1249,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
} break;
case Item::Command::TYPE_PRIMITIVE: {
-
Item::CommandPrimitive *primitive = static_cast<Item::CommandPrimitive *>(command);
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
@@ -1316,11 +1283,9 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
} break;
case Item::Command::TYPE_PARTICLES: {
-
} break;
case Item::Command::TYPE_CLIP_IGNORE: {
-
Item::CommandClipIgnore *ci = static_cast<Item::CommandClipIgnore *>(command);
if (current_clip) {
if (ci->ignore != reclip) {
@@ -1356,7 +1321,6 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
}
void RasterizerCanvasGLES2::_copy_screen(const Rect2 &p_rect) {
-
if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
ERR_PRINT_ONCE("Cannot use screen texture copying in render target set to render direct to screen.");
return;
@@ -1412,7 +1376,6 @@ void RasterizerCanvasGLES2::_copy_screen(const Rect2 &p_rect) {
}
void RasterizerCanvasGLES2::_copy_texscreen(const Rect2 &p_rect) {
-
state.canvas_texscreen_used = true;
_copy_screen(p_rect);
@@ -1425,7 +1388,6 @@ void RasterizerCanvasGLES2::_copy_texscreen(const Rect2 &p_rect) {
}
void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) {
-
Item *current_clip = nullptr;
RasterizerStorageGLES2::Shader *shader_cache = nullptr;
@@ -1447,11 +1409,9 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
RID canvas_last_material = RID();
while (p_item_list) {
-
Item *ci = p_item_list;
if (current_clip != ci->final_clip_owner) {
-
current_clip = ci->final_clip_owner;
if (current_clip) {
@@ -1512,7 +1472,6 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
RasterizerStorageGLES2::Material *material_ptr = storage->material_owner.getornull(material);
if (material != canvas_last_material || rebind_shader) {
-
RasterizerStorageGLES2::Shader *shader_ptr = nullptr;
if (material_ptr) {
@@ -1540,7 +1499,6 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
}
if (shader_ptr != shader_cache) {
-
if (shader_ptr->canvas_item.uses_time) {
RenderingServerRaster::redraw_request();
}
@@ -1555,13 +1513,11 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = shader_ptr->texture_hints.ptrw();
for (int i = 0; i < tc; i++) {
-
glActiveTexture(GL_TEXTURE0 + i);
RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(textures[i].second);
if (!t) {
-
switch (texture_hints[i]) {
case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO:
case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
@@ -1616,9 +1572,7 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
bool reclip = false;
if (last_blend_mode != blend_mode) {
-
switch (blend_mode) {
-
case RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX: {
glBlendEquation(GL_FUNC_ADD);
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
@@ -1629,7 +1583,6 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
} break;
case RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_ADD: {
-
glBlendEquation(GL_FUNC_ADD);
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE);
@@ -1639,7 +1592,6 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
} break;
case RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_SUB: {
-
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_SRC_ALPHA, GL_ONE);
@@ -1679,24 +1631,19 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
rebind_shader = true; // hacked in for now.
if ((blend_mode == RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX || blend_mode == RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_PMALPHA) && p_light && !unshaded) {
-
Light *light = p_light;
bool light_used = false;
RS::CanvasLightMode mode = RS::CANVAS_LIGHT_MODE_ADD;
state.uniforms.final_modulate = ci->final_modulate; // remove the canvas modulate
while (light) {
-
if (ci->light_mask & light->item_mask && p_z >= light->z_min && p_z <= light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) {
-
//intersects this light
if (!light_used || mode != light->mode) {
-
mode = light->mode;
switch (mode) {
-
case RS::CANVAS_LIGHT_MODE_ADD: {
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
@@ -1716,7 +1663,6 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
}
if (!light_used) {
-
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING, true);
light_used = true;
}
@@ -1762,7 +1708,6 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
}
if (light_used) {
-
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING, false);
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS, false);
state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_NEAREST, false);
@@ -1824,7 +1769,6 @@ void RasterizerCanvasGLES2::canvas_debug_viewport_shadows(Light *p_lights_with_s
}
void RasterizerCanvasGLES2::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) {
-
RasterizerStorageGLES2::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.getornull(p_buffer);
ERR_FAIL_COND(!cls);
@@ -1849,7 +1793,6 @@ void RasterizerCanvasGLES2::canvas_light_shadow_buffer_update(RID p_buffer, cons
RS::CanvasOccluderPolygonCullMode cull = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
for (int i = 0; i < 4; i++) {
-
//make sure it remains orthogonal, makes easy to read angle later
Transform light;
@@ -1893,10 +1836,8 @@ void RasterizerCanvasGLES2::canvas_light_shadow_buffer_update(RID p_buffer, cons
LightOccluderInstance *instance = p_occluders;
while (instance) {
-
RasterizerStorageGLES2::CanvasOccluder *cc = storage->canvas_occluder_owner.getornull(instance->polygon_buffer);
if (!cc || cc->len == 0 || !(p_light_mask & instance->light_mask)) {
-
instance = instance->next;
continue;
}
@@ -1914,21 +1855,17 @@ void RasterizerCanvasGLES2::canvas_light_shadow_buffer_update(RID p_buffer, cons
}
if (cull != transformed_cull_cache) {
-
cull = transformed_cull_cache;
switch (cull) {
case RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED: {
-
glDisable(GL_CULL_FACE);
} break;
case RS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE: {
-
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
} break;
case RS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE: {
-
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
@@ -1950,8 +1887,8 @@ void RasterizerCanvasGLES2::canvas_light_shadow_buffer_update(RID p_buffer, cons
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
-void RasterizerCanvasGLES2::reset_canvas() {
+void RasterizerCanvasGLES2::reset_canvas() {
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
@@ -1982,8 +1919,8 @@ void RasterizerCanvasGLES2::_bind_quad_buffer() {
glEnableVertexAttribArray(RS::ARRAY_VERTEX);
glVertexAttribPointer(RS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
}
-void RasterizerCanvasGLES2::draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src) {
+void RasterizerCanvasGLES2::draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src) {
state.canvas_shader.set_uniform(CanvasShaderGLES2::DST_RECT, Color(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y));
state.canvas_shader.set_uniform(CanvasShaderGLES2::SRC_RECT, Color(p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y));
@@ -2028,7 +1965,6 @@ void RasterizerCanvasGLES2::draw_lens_distortion_rect(const Rect2 &p_rect, float
}
void RasterizerCanvasGLES2::draw_window_margins(int *black_margin, RID *black_image) {
-
Vector2 window_size = DisplayServer::get_singleton()->window_get_size();
int window_h = window_size.height;
int window_w = window_size.width;
@@ -2073,14 +2009,12 @@ void RasterizerCanvasGLES2::draw_window_margins(int *black_margin, RID *black_im
}
if (black_image[MARGIN_BOTTOM].is_valid()) {
-
_bind_canvas_texture(black_image[MARGIN_BOTTOM], RID());
Size2 sz(storage->texture_get_width(black_image[MARGIN_BOTTOM]), storage->texture_get_height(black_image[MARGIN_BOTTOM]));
draw_generic_textured_rect(Rect2(0, window_h - black_margin[MARGIN_BOTTOM], window_w, black_margin[MARGIN_BOTTOM]), Rect2(0, 0, sz.x, sz.y));
} else if (black_margin[MARGIN_BOTTOM]) {
-
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.black_tex);
@@ -2091,7 +2025,6 @@ void RasterizerCanvasGLES2::draw_window_margins(int *black_margin, RID *black_im
}
void RasterizerCanvasGLES2::initialize() {
-
// quad buffer
{
glGenBuffers(1, &data.canvas_quad_vertices);
diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h
index 2d6355e948..84452fe220 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.h
+++ b/drivers/gles2/rasterizer_canvas_gles2.h
@@ -59,7 +59,6 @@ public:
};
struct Data {
-
GLuint canvas_quad_vertices;
GLuint polygon_buffer;
GLuint polygon_index_buffer;
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 37b729d568..fc9f3c67e6 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -86,7 +86,6 @@
#ifdef CAN_DEBUG
static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) {
-
if (type == _EXT_DEBUG_TYPE_OTHER_ARB)
return;
@@ -145,22 +144,18 @@ typedef void (*DEBUGPROCARB)(GLenum source,
typedef void (*DebugMessageCallbackARB)(DEBUGPROCARB callback, const void *userParam);
RasterizerStorage *RasterizerGLES2::get_storage() {
-
return storage;
}
RasterizerCanvas *RasterizerGLES2::get_canvas() {
-
return canvas;
}
RasterizerScene *RasterizerGLES2::get_scene() {
-
return scene;
}
Error RasterizerGLES2::is_viable() {
-
#ifdef GLAD_ENABLED
if (!gladLoadGL()) {
ERR_PRINT("Error initializing GLAD");
@@ -214,7 +209,6 @@ Error RasterizerGLES2::is_viable() {
}
void RasterizerGLES2::initialize() {
-
print_verbose("Using GLES2 video driver");
#ifdef GLAD_ENABLED
@@ -253,7 +247,6 @@ void RasterizerGLES2::initialize() {
}
if (callback) {
-
print_line("godot: ENABLING GL DEBUG");
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
callback(_gl_debug_print, nullptr);
@@ -277,9 +270,8 @@ void RasterizerGLES2::begin_frame(double frame_step) {
frame_step = 0.001;
}
- // double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
- // if (time_total > time_roll_over)
- // time_total = 0; //roll over every day (should be customz
+ double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
+ time_total = Math::fmod(time_total, time_roll_over);
storage->frame.time[0] = time_total;
storage->frame.time[1] = Math::fmod(time_total, 3600);
@@ -297,7 +289,6 @@ void RasterizerGLES2::begin_frame(double frame_step) {
}
void RasterizerGLES2::set_current_render_target(RID p_render_target) {
-
if (!p_render_target.is_valid() && storage->frame.current_rt && storage->frame.clear_request) {
// pending clear request. Do that first.
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
@@ -338,7 +329,6 @@ void RasterizerGLES2::clear_render_target(const Color &p_color) {
}
void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {
-
if (p_image.is_null() || p_image->empty())
return;
@@ -365,7 +355,6 @@ void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_c
Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height());
Rect2 screenrect;
if (p_scale) {
-
if (window_w > window_h) {
//scale horizontally
screenrect.size.y = window_h;
@@ -379,7 +368,6 @@ void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_c
screenrect.position.y = (window_h - screenrect.size.y) / 2;
}
} else {
-
screenrect = imgrect;
screenrect.position += ((Size2(window_w, window_h) - screenrect.size) / 2.0).floor();
}
@@ -397,7 +385,6 @@ void RasterizerGLES2::set_boot_image(const Ref<Image> &p_image, const Color &p_c
}
void RasterizerGLES2::blit_render_target_to_screen(RID p_render_target, const Rect2 &p_screen_rect, int p_screen) {
-
ERR_FAIL_COND(storage->frame.current_rt);
RasterizerStorageGLES2::RenderTarget *rt = storage->render_target_owner.getornull(p_render_target);
@@ -447,7 +434,6 @@ void RasterizerGLES2::output_lens_distorted_to_screen(RID p_render_target, const
}
void RasterizerGLES2::end_frame(bool p_swap_buffers) {
-
if (OS::get_singleton()->is_layered_allowed()) {
if (OS::get_singleton()->get_window_per_pixel_transparency_enabled()) {
#if (defined WINDOWS_ENABLED) && !(defined UWP_ENABLED)
@@ -479,7 +465,6 @@ void RasterizerGLES2::finalize() {
}
Rasterizer *RasterizerGLES2::_create_current() {
-
return memnew(RasterizerGLES2);
}
@@ -491,7 +476,6 @@ void RasterizerGLES2::register_config() {
}
RasterizerGLES2::RasterizerGLES2() {
-
storage = memnew(RasterizerStorageGLES2);
canvas = memnew(RasterizerCanvasGLES2);
scene = memnew(RasterizerSceneGLES2);
@@ -505,7 +489,6 @@ RasterizerGLES2::RasterizerGLES2() {
}
RasterizerGLES2::~RasterizerGLES2() {
-
memdelete(storage);
memdelete(canvas);
}
diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h
index 027a634ae8..e9bef31d1e 100644
--- a/drivers/gles2/rasterizer_gles2.h
+++ b/drivers/gles2/rasterizer_gles2.h
@@ -37,7 +37,6 @@
#include "servers/rendering/rasterizer.h"
class RasterizerGLES2 : public Rasterizer {
-
static Rasterizer *_create_current();
RasterizerStorageGLES2 *storage;
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 2ba2147de9..c66506f182 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -72,7 +72,6 @@ static const GLenum _cube_side_enum[6] = {
/* SHADOW ATLAS API */
RID RasterizerSceneGLES2::shadow_atlas_create() {
-
ShadowAtlas *shadow_atlas = memnew(ShadowAtlas);
shadow_atlas->fbo = 0;
shadow_atlas->depth = 0;
@@ -133,7 +132,6 @@ void RasterizerSceneGLES2::shadow_atlas_set_size(RID p_atlas, int p_size) {
glActiveTexture(GL_TEXTURE0);
if (storage->config.use_rgba_3d_shadows) {
-
//maximum compatibility, renderbuffer and RGBA shadow
glGenRenderbuffers(1, &shadow_atlas->depth);
glBindRenderbuffer(GL_RENDERBUFFER, shadow_atlas->depth);
@@ -234,7 +232,6 @@ void RasterizerSceneGLES2::shadow_atlas_set_quadrant_subdivision(RID p_atlas, in
}
bool RasterizerSceneGLES2::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) {
-
for (int i = p_quadrant_count - 1; i >= 0; i--) {
int qidx = p_in_quadrants[i];
@@ -262,7 +259,6 @@ bool RasterizerSceneGLES2::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas,
ERR_CONTINUE(!sli);
if (sli->last_scene_pass != scene_pass) {
-
// was just allocated, don't kill it so soon, wait a bit...
if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec) {
@@ -294,7 +290,6 @@ bool RasterizerSceneGLES2::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas,
}
bool RasterizerSceneGLES2::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) {
-
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
ERR_FAIL_COND_V(!shadow_atlas, false);
@@ -441,7 +436,6 @@ void RasterizerSceneGLES2::set_directional_shadow_count(int p_count) {
}
int RasterizerSceneGLES2::get_directional_light_shadow_size(RID p_light_intance) {
-
ERR_FAIL_COND_V(directional_shadow.light_count == 0, 0);
int shadow_size;
@@ -466,6 +460,7 @@ int RasterizerSceneGLES2::get_directional_light_shadow_size(RID p_light_intance)
return shadow_size;
}
+
//////////////////////////////////////////////////////
RID RasterizerSceneGLES2::reflection_atlas_create() {
@@ -481,7 +476,6 @@ void RasterizerSceneGLES2::reflection_atlas_set_subdivision(RID p_ref_atlas, int
////////////////////////////////////////////////////
RID RasterizerSceneGLES2::reflection_probe_instance_create(RID p_probe) {
-
RasterizerStorageGLES2::ReflectionProbe *probe = storage->reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!probe, RID());
@@ -512,7 +506,6 @@ RID RasterizerSceneGLES2::reflection_probe_instance_create(RID p_probe) {
}
void RasterizerSceneGLES2::reflection_probe_instance_set_transform(RID p_instance, const Transform &p_transform) {
-
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND(!rpi);
rpi->transform = p_transform;
@@ -535,14 +528,12 @@ bool RasterizerSceneGLES2::reflection_probe_instance_has_reflection(RID p_instan
}
bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) {
-
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, false);
rpi->render_step = 0;
if (rpi->probe_ptr->resolution != rpi->current_resolution) {
-
//update cubemap if resolution changed
int size = rpi->probe_ptr->resolution;
rpi->current_resolution = size;
@@ -594,7 +585,6 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
}
bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_instance) {
-
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, false);
ERR_FAIL_COND_V(rpi->current_resolution == 0, false);
@@ -643,7 +633,6 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
//blur
while (size >= 1) {
-
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, storage->resources.mipmap_blur_color);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size, size, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
@@ -652,7 +641,6 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
glActiveTexture(GL_TEXTURE0);
for (int i = 0; i < 6; i++) {
-
storage->bind_quad_array();
storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::FACE_ID, i);
float roughness = CLAMP(lod / (float)(mipmaps - 1), 0, 1);
@@ -684,14 +672,12 @@ bool RasterizerSceneGLES2::reflection_probe_instance_postprocess_step(RID p_inst
/* ENVIRONMENT API */
RID RasterizerSceneGLES2::environment_create() {
-
Environment *env = memnew(Environment);
return environment_owner.make_rid(env);
}
void RasterizerSceneGLES2::environment_set_background(RID p_env, RS::EnvironmentBG p_bg) {
-
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->bg_mode = p_bg;
@@ -756,7 +742,6 @@ void RasterizerSceneGLES2::environment_set_camera_feed_id(RID p_env, int p_camer
}
void RasterizerSceneGLES2::environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, RS::EnvironmentDOFBlurQuality p_quality) {
-
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -768,7 +753,6 @@ void RasterizerSceneGLES2::environment_set_dof_blur_far(RID p_env, bool p_enable
}
void RasterizerSceneGLES2::environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, RS::EnvironmentDOFBlurQuality p_quality) {
-
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -780,7 +764,6 @@ void RasterizerSceneGLES2::environment_set_dof_blur_near(RID p_env, bool p_enabl
}
void RasterizerSceneGLES2::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap, bool p_bicubic_upscale) {
-
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -817,7 +800,6 @@ void RasterizerSceneGLES2::environment_set_tonemap(RID p_env, RS::EnvironmentTon
}
void RasterizerSceneGLES2::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {
-
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -829,7 +811,6 @@ void RasterizerSceneGLES2::environment_set_adjustment(RID p_env, bool p_enable,
}
void RasterizerSceneGLES2::environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {
-
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -840,7 +821,6 @@ void RasterizerSceneGLES2::environment_set_fog(RID p_env, bool p_enable, const C
}
void RasterizerSceneGLES2::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
-
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -853,7 +833,6 @@ void RasterizerSceneGLES2::environment_set_fog_depth(RID p_env, bool p_enable, f
}
void RasterizerSceneGLES2::environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {
-
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -862,6 +841,7 @@ void RasterizerSceneGLES2::environment_set_fog_height(RID p_env, bool p_enable,
env->fog_height_max = p_max_height;
env->fog_height_curve = p_height_curve;
}
+
bool RasterizerSceneGLES2::is_environment(RID p_env) {
return environment_owner.owns(p_env);
}
@@ -881,7 +861,6 @@ int RasterizerSceneGLES2::environment_get_canvas_max_layer(RID p_env) {
}
RID RasterizerSceneGLES2::light_instance_create(RID p_light) {
-
LightInstance *light_instance = memnew(LightInstance);
light_instance->last_scene_pass = 0;
@@ -902,7 +881,6 @@ RID RasterizerSceneGLES2::light_instance_create(RID p_light) {
}
void RasterizerSceneGLES2::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {
-
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
@@ -910,7 +888,6 @@ void RasterizerSceneGLES2::light_instance_set_transform(RID p_light_instance, co
}
void RasterizerSceneGLES2::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale) {
-
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
@@ -928,7 +905,6 @@ void RasterizerSceneGLES2::light_instance_set_shadow_transform(RID p_light_insta
}
void RasterizerSceneGLES2::light_instance_mark_visible(RID p_light_instance) {
-
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
@@ -938,12 +914,12 @@ void RasterizerSceneGLES2::light_instance_mark_visible(RID p_light_instance) {
//////////////////////
RID RasterizerSceneGLES2::gi_probe_instance_create() {
-
return RID();
}
void RasterizerSceneGLES2::gi_probe_instance_set_light_data(RID p_probe, RID p_base, RID p_data) {
}
+
void RasterizerSceneGLES2::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) {
}
@@ -955,7 +931,6 @@ void RasterizerSceneGLES2::gi_probe_instance_set_bounds(RID p_probe, const Vecto
////////////////////////////
void RasterizerSceneGLES2::_add_geometry(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, int p_material, bool p_depth_pass, bool p_shadow_pass) {
-
RasterizerStorageGLES2::Material *material = nullptr;
RID material_src;
@@ -993,8 +968,8 @@ void RasterizerSceneGLES2::_add_geometry(RasterizerStorageGLES2::Geometry *p_geo
_add_geometry_with_material(p_geometry, p_instance, p_owner, material, p_depth_pass, p_shadow_pass);
}
}
-void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, RasterizerStorageGLES2::Material *p_material, bool p_depth_pass, bool p_shadow_pass) {
+void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, RasterizerStorageGLES2::Material *p_material, bool p_depth_pass, bool p_shadow_pass) {
bool has_base_alpha = (p_material->shader->spatial.uses_alpha && !p_material->shader->spatial.uses_alpha_scissor) || p_material->shader->spatial.uses_screen_texture || p_material->shader->spatial.uses_depth_texture;
bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_MIX;
bool has_alpha = has_base_alpha || has_blend_alpha;
@@ -1016,7 +991,6 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
}
if (p_depth_pass) {
-
if (has_blend_alpha || p_material->shader->spatial.uses_depth_texture || (has_base_alpha && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))
return; //bye
@@ -1077,7 +1051,6 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
e->refprobe_1_index = RenderList::MAX_REFLECTION_PROBES; //refprobe disabled by default
if (!p_depth_pass) {
-
e->depth_layer = e->instance->depth_layer;
e->priority = p_material->render_priority;
@@ -1119,11 +1092,9 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
if (p_material->shader->spatial.unshaded) {
e->light_mode = LIGHTMODE_UNSHADED;
} else {
-
bool copy = false;
for (int i = 0; i < render_directional_lights; i++) {
-
if (copy) {
RenderList::Element *e2 = has_alpha ? render_list.add_alpha_element() : render_list.add_element();
if (!e2) {
@@ -1144,7 +1115,6 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
//add omni / spots
for (int i = 0; i < e->instance->light_instances.size(); i++) {
-
LightInstance *li = light_instance_owner.getornull(e->instance->light_instances[i]);
if (!li || li->light_index >= render_light_instance_count || render_light_instances[li->light_index] != li) {
@@ -1186,7 +1156,6 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
}
void RasterizerSceneGLES2::_copy_texture_to_buffer(GLuint p_texture, GLuint p_buffer) {
-
//copy to front buffer
glBindFramebuffer(GL_FRAMEBUFFER, p_buffer);
@@ -1210,7 +1179,6 @@ void RasterizerSceneGLES2::_copy_texture_to_buffer(GLuint p_texture, GLuint p_bu
}
void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass) {
-
render_pass++;
current_material_index = 0;
current_geometry_index = 0;
@@ -1219,13 +1187,10 @@ void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p
current_shader_index = 0;
for (int i = 0; i < p_cull_count; i++) {
-
InstanceBase *instance = p_cull_result[i];
switch (instance->base_type) {
-
case RS::INSTANCE_MESH: {
-
RasterizerStorageGLES2::Mesh *mesh = storage->mesh_owner.getornull(instance->base);
ERR_CONTINUE(!mesh);
@@ -1285,7 +1250,6 @@ static const GLenum gl_primitive[] = {
};
void RasterizerSceneGLES2::_set_cull(bool p_front, bool p_disabled, bool p_reverse_cull) {
-
bool front = p_front;
if (p_reverse_cull)
front = !front;
@@ -1300,14 +1264,12 @@ void RasterizerSceneGLES2::_set_cull(bool p_front, bool p_disabled, bool p_rever
}
if (front != state.cull_front) {
-
glCullFace(front ? GL_FRONT : GL_BACK);
state.cull_front = front;
}
}
bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_material, bool p_alpha_pass, Size2i p_skeleton_tex_size) {
-
// material parameters
state.scene_shader.set_custom_shader(p_material->shader->custom_code_id);
@@ -1333,7 +1295,6 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
switch (p_material->shader->spatial.depth_draw_mode) {
case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS:
case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_OPAQUE: {
-
glDepthMask(!p_alpha_pass && !p_material->shader->spatial.uses_depth_texture);
} break;
case RasterizerStorageGLES2::Shader::Spatial::DEPTH_DRAW_ALWAYS: {
@@ -1355,20 +1316,17 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
state.current_main_tex = 0;
for (int i = 0; i < tc; i++) {
-
glActiveTexture(GL_TEXTURE0 + i);
RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(textures[i].second);
if (!t) {
-
GLenum target = GL_TEXTURE_2D;
GLuint tex = 0;
switch (texture_types[i]) {
case ShaderLanguage::TYPE_ISAMPLER2D:
case ShaderLanguage::TYPE_USAMPLER2D:
case ShaderLanguage::TYPE_SAMPLER2D: {
-
switch (texture_hints[i]) {
case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK_ALBEDO:
case ShaderLanguage::ShaderNode::Uniform::HINT_BLACK: {
@@ -1394,7 +1352,6 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
case ShaderLanguage::TYPE_ISAMPLER3D:
case ShaderLanguage::TYPE_USAMPLER3D:
case ShaderLanguage::TYPE_SAMPLER3D: {
-
target = GL_TEXTURE_3D;
tex = storage->resources.white_tex_3d;
@@ -1407,7 +1364,6 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
case ShaderLanguage::TYPE_USAMPLER2DARRAY:
case ShaderLanguage::TYPE_SAMPLER2DARRAY: {
-
target = GL_TEXTURE_2D_ARRAY;
tex = storage->resources.white_tex_array;
@@ -1456,9 +1412,7 @@ bool RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
}
void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton) {
-
switch (p_element->instance->base_type) {
-
case RS::INSTANCE_MESH: {
RasterizerStorageGLES2::Surface *s = static_cast<RasterizerStorageGLES2::Surface *>(p_element->geometry);
@@ -1491,7 +1445,6 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste
bool clear_skeleton_buffer = storage->config.use_skeleton_software;
if (p_skeleton) {
-
if (!storage->config.use_skeleton_software) {
//use float texture workflow
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
@@ -1524,7 +1477,6 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste
const uint8_t *vertex_data = vertex_array_read.ptr();
for (int i = 0; i < s->array_len; i++) {
-
// do magic
size_t bones[4];
@@ -1613,7 +1565,6 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste
}
if (clear_skeleton_buffer) {
-
glDisableVertexAttribArray(INSTANCE_BONE_BASE + 0);
glDisableVertexAttribArray(INSTANCE_BONE_BASE + 1);
glDisableVertexAttribArray(INSTANCE_BONE_BASE + 2);
@@ -1671,11 +1622,8 @@ void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, Raste
}
void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
-
switch (p_element->instance->base_type) {
-
case RS::INSTANCE_MESH: {
-
RasterizerStorageGLES2::Surface *s = static_cast<RasterizerStorageGLES2::Surface *>(p_element->geometry);
// drawing
@@ -1704,7 +1652,6 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
} break;
case RS::INSTANCE_MULTIMESH: {
-
RasterizerStorageGLES2::MultiMesh *multi_mesh = static_cast<RasterizerStorageGLES2::MultiMesh *>(p_element->owner);
RasterizerStorageGLES2::Surface *s = static_cast<RasterizerStorageGLES2::Surface *>(p_element->geometry);
@@ -1727,7 +1674,6 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
const float *buffer = base_buffer + i * stride;
{
-
glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 0, &buffer[0]);
glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 1, &buffer[4]);
glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 2, &buffer[8]);
@@ -1809,7 +1755,6 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
glBindTexture(t->target, t->tex_id);
restore_tex = true;
} else if (restore_tex) {
-
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, state.current_main_tex);
restore_tex = false;
@@ -1880,7 +1825,6 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
}
void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas *shadow_atlas) {
-
//turn off all by default
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTING, false);
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, false);
@@ -1902,7 +1846,6 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
switch (p_light->light_ptr->type) {
case RS::LIGHT_DIRECTIONAL: {
-
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_MODE_DIRECTIONAL, true);
switch (p_light->light_ptr->directional_shadow_mode) {
case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: {
@@ -1932,7 +1875,6 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
} break;
case RS::LIGHT_OMNI: {
-
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_MODE_OMNI, true);
if (!state.render_no_shadows && shadow_atlas && p_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, true);
@@ -1947,7 +1889,6 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
}
} break;
case RS::LIGHT_SPOT: {
-
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_MODE_SPOT, true);
if (!state.render_no_shadows && shadow_atlas && p_light->light_ptr->shadow) {
state.scene_shader.set_conditional(SceneShaderGLES2::USE_SHADOW, true);
@@ -1965,7 +1906,6 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
}
void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform, bool accum_pass) {
-
RasterizerStorageGLES2::Light *light_ptr = light->light_ptr;
//common parameters
@@ -1990,7 +1930,6 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
CameraMatrix matrices[4];
if (!state.render_no_shadows && light_ptr->shadow && directional_shadow.depth) {
-
int shadow_count = 0;
Color split_offsets;
@@ -2009,14 +1948,12 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
}
for (int k = 0; k < shadow_count; k++) {
-
uint32_t x = light->directional_rect.position.x;
uint32_t y = light->directional_rect.position.y;
uint32_t width = light->directional_rect.size.x;
uint32_t height = light->directional_rect.size.y;
if (light_ptr->directional_shadow_mode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
-
width /= 2;
height /= 2;
@@ -2030,7 +1967,6 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
}
} else if (light_ptr->directional_shadow_mode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
-
height /= 2;
if (k != 0) {
@@ -2068,7 +2004,6 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
}
} break;
case RS::LIGHT_OMNI: {
-
Vector3 position = p_view_transform.xform_inv(light->transform.origin);
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_POSITION, position);
@@ -2080,7 +2015,6 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_ATTENUATION, attenuation);
if (!state.render_no_shadows && light_ptr->shadow && shadow_atlas && shadow_atlas->shadow_owners.has(light->self)) {
-
uint32_t key = shadow_atlas->shadow_owners[light->self];
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x03;
@@ -2122,7 +2056,6 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
} break;
case RS::LIGHT_SPOT: {
-
Vector3 position = p_view_transform.xform_inv(light->transform.origin);
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_POSITION, position);
@@ -2191,7 +2124,6 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado
}
void RasterizerSceneGLES2::_setup_refprobes(ReflectionProbeInstance *p_refprobe1, ReflectionProbeInstance *p_refprobe2, const Transform &p_view_transform, Environment *p_env) {
-
if (p_refprobe1) {
state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE1_USE_BOX_PROJECT, p_refprobe1->probe_ptr->box_projection);
state.scene_shader.set_uniform(SceneShaderGLES2::REFPROBE1_BOX_EXTENTS, p_refprobe1->probe_ptr->extents);
@@ -2240,7 +2172,6 @@ void RasterizerSceneGLES2::_setup_refprobes(ReflectionProbeInstance *p_refprobe1
}
void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, RID p_shadow_atlas, Environment *p_env, GLuint p_base_env, float p_shadow_bias, float p_shadow_normal_bias, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow) {
-
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
Vector2 viewport_size = state.viewport_size;
@@ -2323,7 +2254,6 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
bool rebind_lightmap = false;
if (!p_shadow && material->shader) {
-
bool unshaded = material->shader->spatial.unshaded;
if (unshaded != prev_unshaded) {
@@ -2353,7 +2283,6 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
}
if (light != prev_light) {
-
_setup_light_type(light, shadow_atlas);
rebind = true;
rebind_light = true;
@@ -2369,7 +2298,6 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
}
if (prev_blend_mode != blend_mode) {
-
if (prev_blend_mode == -1 && blend_mode != -1) {
//does blend
glEnable(GL_BLEND);
@@ -2390,13 +2318,11 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
} break;
case RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_ADD: {
-
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(p_alpha_pass ? GL_SRC_ALPHA : GL_ONE, GL_ONE);
} break;
case RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_SUB: {
-
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
} break;
@@ -2449,13 +2375,11 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
use_lightmap_capture = !unshaded && !accum_pass && !e->instance->lightmap_capture_data.empty();
if (use_lightmap_capture != prev_use_lightmap_capture) {
-
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP_CAPTURE, use_lightmap_capture);
rebind = true;
}
if (!unshaded && !accum_pass && e->instance->lightmap.is_valid()) {
-
lightmap = storage->texture_owner.getornull(e->instance->lightmap);
lightmap_energy = 1.0;
if (lightmap) {
@@ -2484,7 +2408,6 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
}
if (depth_prepass != prev_depth_prepass) {
-
state.scene_shader.set_conditional(SceneShaderGLES2::USE_DEPTH_PREPASS, depth_prepass);
prev_depth_prepass = depth_prepass;
rebind = true;
@@ -2493,7 +2416,6 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
bool instancing = e->instance->base_type == RS::INSTANCE_MULTIMESH;
if (instancing != prev_instancing) {
-
state.scene_shader.set_conditional(SceneShaderGLES2::USE_INSTANCING, instancing);
rebind = true;
}
@@ -2520,7 +2442,6 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
bool shader_rebind = false;
if (rebind || material != prev_material) {
-
storage->info.render.material_switch_count++;
shader_rebind = _setup_material(material, p_alpha_pass, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
if (shader_rebind) {
@@ -2572,7 +2493,6 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
rebind_lightmap = true;
if (using_fog) {
-
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_COLOR_BASE, p_env->fog_color);
Color sun_color_amount = p_env->fog_sun_color;
sun_color_amount.a = p_env->fog_sun_amount;
@@ -2679,7 +2599,6 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
CameraMatrix camera;
if (p_custom_fov) {
-
float near_plane = p_projection.get_z_near();
float far_plane = p_projection.get_z_far();
float aspect = p_projection.get_aspect();
@@ -2763,7 +2682,6 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
}
void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p_cam_projection) {
-
//copy to front buffer
glDepthMask(GL_FALSE);
@@ -2839,7 +2757,6 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
// DOF Blur
if (env->dof_blur_far_enabled) {
-
int vp_h = storage->frame.current_rt->height;
int vp_w = storage->frame.current_rt->width;
@@ -2896,7 +2813,6 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
}
if (env->dof_blur_near_enabled) {
-
//convert texture to RGBA format if not already
if (!storage->frame.current_rt->used_dof_blur_near) {
glActiveTexture(GL_TEXTURE0);
@@ -3002,10 +2918,8 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
int glow_mask = 0;
if (env->glow_enabled) {
-
for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) {
if (env->glow_levels & (1 << i)) {
-
if (i >= storage->frame.current_rt->mip_maps[1].sizes.size()) {
max_glow_level = storage->frame.current_rt->mip_maps[1].sizes.size() - 1;
glow_mask |= 1 << max_glow_level;
@@ -3018,7 +2932,6 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
}
for (int i = 0; i < (max_glow_level + 1); i++) {
-
int vp_w = storage->frame.current_rt->mip_maps[1].sizes[i].width;
int vp_h = storage->frame.current_rt->mip_maps[1].sizes[i].height;
glViewport(0, 0, vp_w, vp_h);
@@ -3043,7 +2956,6 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
}
if (i == 0) {
-
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES2::GLOW_BLOOM, env->glow_bloom);
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES2::GLOW_HDR_THRESHOLD, env->glow_hdr_bleed_threshold);
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES2::GLOW_HDR_SCALE, env->glow_hdr_bleed_scale);
@@ -3094,7 +3006,6 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
if (max_glow_level >= 0) {
if (storage->frame.current_rt->mip_maps[0].color) {
for (int i = 0; i < (max_glow_level + 1); i++) {
-
if (glow_mask & (1 << i)) {
if (i == 0) {
state.tonemap_shader.set_conditional(TonemapShaderGLES2::USE_GLOW_LEVEL1, true);
@@ -3122,11 +3033,9 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->mip_maps[0].color);
} else {
-
state.tonemap_shader.set_conditional(TonemapShaderGLES2::USE_MULTI_TEXTURE_GLOW, true);
int active_glow_level = 0;
for (int i = 0; i < (max_glow_level + 1); i++) {
-
if (glow_mask & (1 << i)) {
active_glow_level++;
glActiveTexture(GL_TEXTURE0 + active_glow_level);
@@ -3163,7 +3072,6 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
//Adjustments
if (env->adjustments_enabled) {
-
state.tonemap_shader.set_conditional(TonemapShaderGLES2::USE_BCS, true);
RasterizerStorageGLES2::Texture *tex = storage->texture_owner.getornull(env->color_correction);
if (tex) {
@@ -3176,7 +3084,6 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.bind();
if (max_glow_level >= 0) {
-
state.tonemap_shader.set_uniform(TonemapShaderGLES2::GLOW_INTENSITY, env->glow_intensity);
int ss[2] = {
storage->frame.current_rt->width,
@@ -3186,7 +3093,6 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
}
if (env->adjustments_enabled) {
-
state.tonemap_shader.set_uniform(TonemapShaderGLES2::BCS, Vector3(env->adjustments_brightness, env->adjustments_contrast, env->adjustments_saturation));
}
@@ -3210,7 +3116,6 @@ void RasterizerSceneGLES2::_post_process(Environment *env, const CameraMatrix &p
}
void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
-
Transform cam_transform = p_cam_transform;
storage->info.render.object_count += p_cull_count;
@@ -3306,7 +3211,6 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
}
if (p_reflection_probe_cull_count) {
-
reflection_probe_instances = (ReflectionProbeInstance **)alloca(sizeof(ReflectionProbeInstance *) * p_reflection_probe_cull_count);
reflection_probe_count = p_reflection_probe_cull_count;
for (int i = 0; i < p_reflection_probe_cull_count; i++) {
@@ -3339,7 +3243,6 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
glViewport(viewport_x, viewport_y, viewport_width, viewport_height);
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_DIRECT_TO_SCREEN]) {
-
glScissor(viewport_x, viewport_y, viewport_width, viewport_height);
glEnable(GL_SCISSOR_TEST);
}
@@ -3395,7 +3298,6 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
GLuint env_radiance_tex = 0;
if (env) {
switch (env->bg_mode) {
-
case RS::ENV_BG_COLOR_SKY:
case RS::ENV_BG_SKY: {
sky = storage->sky_owner.getornull(env->sky);
@@ -3485,7 +3387,6 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
// then draw the sky after
if (env && env->bg_mode == RS::ENV_BG_SKY && (!storage->frame.current_rt || !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT])) {
-
if (sky && sky->panorama.is_valid()) {
_draw_sky(sky, p_cam_projection, cam_transform, false, env->sky_custom_fov, env->bg_energy, env->sky_orientation);
}
@@ -3586,7 +3487,6 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
}
void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {
-
state.render_no_shadows = false;
LightInstance *light_instance = light_instance_owner.getornull(p_light);
@@ -3652,7 +3552,6 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
height = light_instance->directional_rect.size.height;
if (light->directional_shadow_mode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
-
width /= 2;
height /= 2;
@@ -3666,11 +3565,9 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
}
} else if (light->directional_shadow_mode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
-
height /= 2;
if (p_pass == 0) {
-
} else {
y += height;
}
@@ -3737,7 +3634,6 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
light_transform = light_instance->shadow_transform[0].transform;
if (light->omni_shadow_detail == RS::LIGHT_OMNI_SHADOW_DETAIL_HORIZONTAL) {
-
height /= 2;
y += p_pass * height;
} else {
@@ -3871,9 +3767,7 @@ void RasterizerSceneGLES2::set_scene_pass(uint64_t p_pass) {
}
bool RasterizerSceneGLES2::free(RID p_rid) {
-
if (light_instance_owner.owns(p_rid)) {
-
LightInstance *light_instance = light_instance_owner.getornull(p_rid);
//remove from shadow atlases..
@@ -3892,13 +3786,11 @@ bool RasterizerSceneGLES2::free(RID p_rid) {
memdelete(light_instance);
} else if (shadow_atlas_owner.owns(p_rid)) {
-
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_rid);
shadow_atlas_set_size(p_rid, 0);
shadow_atlas_owner.free(p_rid);
memdelete(shadow_atlas);
} else if (reflection_probe_instance_owner.owns(p_rid)) {
-
ReflectionProbeInstance *reflection_instance = reflection_probe_instance_owner.getornull(p_rid);
for (int i = 0; i < 6; i++) {
@@ -4000,7 +3892,6 @@ void RasterizerSceneGLES2::initialize() {
glActiveTexture(GL_TEXTURE0);
while (cube_size >= 32) {
-
ShadowCubeMap cube;
cube.size = cube_size;
@@ -4009,7 +3900,6 @@ void RasterizerSceneGLES2::initialize() {
glBindTexture(GL_TEXTURE_CUBE_MAP, cube.cubemap);
for (int i = 0; i < 6; i++) {
-
glTexImage2D(_cube_side_enum[i], 0, storage->config.depth_internalformat, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, storage->config.depth_type, nullptr);
}
@@ -4021,7 +3911,6 @@ void RasterizerSceneGLES2::initialize() {
glGenFramebuffers(6, cube.fbo);
for (int i = 0; i < 6; i++) {
-
glBindFramebuffer(GL_FRAMEBUFFER, cube.fbo[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, _cube_side_enum[i], cube.cubemap, 0);
}
@@ -4045,7 +3934,7 @@ void RasterizerSceneGLES2::initialize() {
//maximum compatibility, renderbuffer and RGBA shadow
glGenRenderbuffers(1, &directional_shadow.depth);
glBindRenderbuffer(GL_RENDERBUFFER, directional_shadow.depth);
- glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_internalformat, directional_shadow.size, directional_shadow.size);
+ glRenderbufferStorage(GL_RENDERBUFFER, storage->config.depth_buffer_internalformat, directional_shadow.size, directional_shadow.size);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, directional_shadow.depth);
glGenTextures(1, &directional_shadow.color);
diff --git a/drivers/gles2/rasterizer_scene_gles2.h b/drivers/gles2/rasterizer_scene_gles2.h
index 56c0e632c2..d017fc49a2 100644
--- a/drivers/gles2/rasterizer_scene_gles2.h
+++ b/drivers/gles2/rasterizer_scene_gles2.h
@@ -77,7 +77,6 @@ public:
RasterizerStorageGLES2 *storage;
struct State {
-
bool texscreen_copied;
int current_blend_mode;
float current_line_width;
@@ -195,7 +194,6 @@ public:
/* REFLECTION PROBE INSTANCE */
struct ReflectionProbeInstance {
-
RasterizerStorageGLES2::ReflectionProbe *probe_ptr;
RID probe;
RID self;
@@ -387,7 +385,6 @@ public:
/* LIGHT INSTANCE */
struct LightInstance {
-
struct ShadowTransform {
CameraMatrix camera;
Transform transform;
@@ -449,7 +446,6 @@ public:
};
struct RenderList {
-
enum {
MAX_LIGHTS = 255,
MAX_REFLECTION_PROBES = 255,
@@ -534,7 +530,6 @@ public:
}
struct SortByDepth {
-
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
return A->instance->depth < B->instance->depth;
}
@@ -551,7 +546,6 @@ public:
}
struct SortByReverseDepthAndPriority {
-
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
if (A->priority == B->priority) {
return A->instance->depth > B->instance->depth;
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index b8c7815f6a..6eef04b87f 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -135,7 +135,6 @@ void RasterizerStorageGLES2::bind_quad_array() const {
}
Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, Image::Format &r_real_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool p_force_decompress) const {
-
r_gl_format = 0;
Ref<Image> image = p_image;
r_compressed = false;
@@ -144,9 +143,7 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
bool need_decompress = false;
switch (p_format) {
-
case Image::FORMAT_L8: {
-
r_gl_internal_format = GL_LUMINANCE;
r_gl_format = GL_LUMINANCE;
r_gl_type = GL_UNSIGNED_BYTE;
@@ -157,7 +154,6 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
r_gl_type = GL_UNSIGNED_BYTE;
} break;
case Image::FORMAT_R8: {
-
r_gl_internal_format = GL_ALPHA;
r_gl_format = GL_ALPHA;
r_gl_type = GL_UNSIGNED_BYTE;
@@ -174,28 +170,24 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
} break;
case Image::FORMAT_RGB8: {
-
r_gl_internal_format = GL_RGB;
r_gl_format = GL_RGB;
r_gl_type = GL_UNSIGNED_BYTE;
} break;
case Image::FORMAT_RGBA8: {
-
r_gl_format = GL_RGBA;
r_gl_internal_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
} break;
case Image::FORMAT_RGBA4444: {
-
r_gl_internal_format = GL_RGBA;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_SHORT_4_4_4_4;
} break;
case Image::FORMAT_RGB565: {
-
r_gl_internal_format = GL_RGB5_A1;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_SHORT_5_5_5_1;
@@ -280,7 +272,6 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
} break;
case Image::FORMAT_DXT1: {
-
if (config.s3tc_supported) {
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
r_gl_format = GL_RGBA;
@@ -292,7 +283,6 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
} break;
case Image::FORMAT_DXT3: {
-
if (config.s3tc_supported) {
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
r_gl_format = GL_RGBA;
@@ -304,7 +294,6 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
} break;
case Image::FORMAT_DXT5: {
-
if (config.s3tc_supported) {
r_gl_internal_format = _EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
r_gl_format = GL_RGBA;
@@ -316,134 +305,107 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
} break;
case Image::FORMAT_RGTC_R: {
-
if (config.rgtc_supported) {
-
r_gl_internal_format = _EXT_COMPRESSED_RED_RGTC1_EXT;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
-
need_decompress = true;
}
} break;
case Image::FORMAT_RGTC_RG: {
-
if (config.rgtc_supported) {
-
r_gl_internal_format = _EXT_COMPRESSED_RED_GREEN_RGTC2_EXT;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
-
need_decompress = true;
}
} break;
case Image::FORMAT_BPTC_RGBA: {
-
if (config.bptc_supported) {
-
r_gl_internal_format = _EXT_COMPRESSED_RGBA_BPTC_UNORM;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
-
need_decompress = true;
}
} break;
case Image::FORMAT_BPTC_RGBF: {
-
if (config.bptc_supported) {
-
r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;
r_gl_format = GL_RGB;
r_gl_type = GL_FLOAT;
r_compressed = true;
} else {
-
need_decompress = true;
}
} break;
case Image::FORMAT_BPTC_RGBFU: {
if (config.bptc_supported) {
-
r_gl_internal_format = _EXT_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
r_gl_format = GL_RGB;
r_gl_type = GL_FLOAT;
r_compressed = true;
} else {
-
need_decompress = true;
}
} break;
case Image::FORMAT_PVRTC2: {
-
if (config.pvrtc_supported) {
-
r_gl_internal_format = _EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
-
need_decompress = true;
}
} break;
case Image::FORMAT_PVRTC2A: {
-
if (config.pvrtc_supported) {
-
r_gl_internal_format = _EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
-
need_decompress = true;
}
} break;
case Image::FORMAT_PVRTC4: {
-
if (config.pvrtc_supported) {
-
r_gl_internal_format = _EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
-
need_decompress = true;
}
} break;
case Image::FORMAT_PVRTC4A: {
-
if (config.pvrtc_supported) {
-
r_gl_internal_format = _EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
} else {
-
need_decompress = true;
}
} break;
case Image::FORMAT_ETC: {
-
if (config.etc1_supported) {
r_gl_internal_format = _EXT_ETC1_RGB8_OES;
r_gl_format = GL_RGBA;
@@ -454,43 +416,33 @@ Ref<Image> RasterizerStorageGLES2::_get_gl_image_and_format(const Ref<Image> &p_
}
} break;
case Image::FORMAT_ETC2_R11: {
-
need_decompress = true;
} break;
case Image::FORMAT_ETC2_R11S: {
-
need_decompress = true;
} break;
case Image::FORMAT_ETC2_RG11: {
-
need_decompress = true;
} break;
case Image::FORMAT_ETC2_RG11S: {
-
need_decompress = true;
} break;
case Image::FORMAT_ETC2_RGB8: {
-
need_decompress = true;
} break;
case Image::FORMAT_ETC2_RGBA8: {
-
need_decompress = true;
} break;
case Image::FORMAT_ETC2_RGB8A1: {
-
need_decompress = true;
} break;
default: {
-
ERR_FAIL_V(Ref<Image>());
}
}
if (need_decompress || p_force_decompress) {
-
if (!image.is_null()) {
-
image = image->duplicate();
image->decompress();
ERR_FAIL_COND_V(image->is_compressed(), image);
@@ -539,7 +491,6 @@ static const GLenum _cube_side_enum[6] = {
};
RID RasterizerStorageGLES2::texture_create() {
-
Texture *texture = memnew(Texture);
ERR_FAIL_COND_V(!texture, RID());
glGenTextures(1, &texture->tex_id);
@@ -612,7 +563,6 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
bool is_po2 = p_width == po2_width && p_height == po2_height;
if (!is_po2 && (p_flags & RS::TEXTURE_FLAG_REPEAT || p_flags & RS::TEXTURE_FLAG_MIPMAPS)) {
-
if (p_flags & RS::TEXTURE_FLAG_USED_FOR_STREAMING) {
//not supported
ERR_PRINT("Streaming texture for non power of 2 or has mipmaps on this hardware: " + texture->path + "'. Mipmaps and repeat disabled.");
@@ -641,7 +591,6 @@ void RasterizerStorageGLES2::texture_allocate(RID p_texture, int p_width, int p_
#if defined(GLES_OVER_GL) || defined(ANDROID_ENABLED)
if ((p_type == RS::TEXTURE_TYPE_3D && config.texture_3d_supported) || (p_type == RS::TEXTURE_TYPE_2D_ARRAY && config.texture_array_supported)) {
-
int width = p_width;
int height = p_height;
int depth = p_depth_3d;
@@ -718,15 +667,12 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
}
if (config.shrink_textures_x2 && (p_image->has_mipmaps() || !p_image->is_compressed()) && !(texture->flags & RS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
-
texture->alloc_height = MAX(1, texture->alloc_height / 2);
texture->alloc_width = MAX(1, texture->alloc_width / 2);
if (texture->alloc_width == img->get_width() / 2 && texture->alloc_height == img->get_height() / 2) {
-
img->shrink_x2();
} else if (img->get_format() <= Image::FORMAT_RGBA8) {
-
img->resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR);
}
}
@@ -769,16 +715,13 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
}
if (texture->flags & RS::TEXTURE_FLAG_FILTER) {
-
glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
} else {
-
glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering
}
if (((texture->flags & RS::TEXTURE_FLAG_REPEAT) || (texture->flags & RS::TEXTURE_FLAG_MIRRORED_REPEAT)) && texture->target != GL_TEXTURE_CUBE_MAP) {
-
if (texture->flags & RS::TEXTURE_FLAG_MIRRORED_REPEAT) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
@@ -787,7 +730,6 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
} else {
-
//glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@@ -801,11 +743,9 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
int tsize = 0;
for (int i = 0; i < mipmaps; i++) {
-
int size, ofs;
img->get_mipmap_offset_and_size(i, ofs, size);
if (texture->type == RS::TEXTURE_TYPE_2D || texture->type == RS::TEXTURE_TYPE_CUBEMAP) {
-
if (compressed) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
@@ -814,7 +754,6 @@ void RasterizerStorageGLES2::texture_set_data(RID p_texture, const Ref<Image> &p
glCompressedTexImage2D(blit_target, i, internal_format, bw, bh, 0, size, &read[ofs]);
} else {
-
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
if (texture->flags & RS::TEXTURE_FLAG_USED_FOR_STREAMING) {
glTexSubImage2D(blit_target, i, 0, 0, w, h, format, type, &read[ofs]);
@@ -868,7 +807,6 @@ void RasterizerStorageGLES2::texture_set_data_partial(RID p_texture, const Ref<I
}
Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer) const {
-
Texture *texture = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!texture, Ref<Image>());
@@ -902,7 +840,6 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
for (int i = 0; i < texture->mipmaps; i++) {
-
int ofs = Image::get_image_mipmap_offset(texture->alloc_width, texture->alloc_height, real_format, i);
if (texture->compressed) {
@@ -993,7 +930,6 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
}
void RasterizerStorageGLES2::texture_set_flags(RID p_texture, uint32_t p_flags) {
-
Texture *texture = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!texture);
@@ -1005,7 +941,6 @@ void RasterizerStorageGLES2::texture_set_flags(RID p_texture, uint32_t p_flags)
glBindTexture(texture->target, texture->tex_id);
if (((texture->flags & RS::TEXTURE_FLAG_REPEAT) || (texture->flags & RS::TEXTURE_FLAG_MIRRORED_REPEAT)) && texture->target != GL_TEXTURE_CUBE_MAP) {
-
if (texture->flags & RS::TEXTURE_FLAG_MIRRORED_REPEAT) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
@@ -1034,11 +969,9 @@ void RasterizerStorageGLES2::texture_set_flags(RID p_texture, uint32_t p_flags)
}
if (texture->flags & RS::TEXTURE_FLAG_FILTER) {
-
glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
} else {
-
glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // raw Filtering
}
}
@@ -1140,7 +1073,6 @@ void RasterizerStorageGLES2::texture_debug_usage(List<RS::TextureInfo> *r_info)
texture_owner.get_owned_list(&textures);
for (List<RID>::Element *E = textures.front(); E; E = E->next()) {
-
Texture *t = texture_owner.getornull(E->get());
if (!t)
continue;
@@ -1164,7 +1096,6 @@ void RasterizerStorageGLES2::textures_keep_original(bool p_enable) {
}
Size2 RasterizerStorageGLES2::texture_size_with_proxy(RID p_texture) const {
-
const Texture *texture = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!texture, Size2());
if (texture->proxy) {
@@ -1193,7 +1124,6 @@ void RasterizerStorageGLES2::texture_set_proxy(RID p_texture, RID p_proxy) {
}
void RasterizerStorageGLES2::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {
-
Texture *texture = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!texture);
@@ -1225,7 +1155,6 @@ void RasterizerStorageGLES2::texture_set_detect_normal_callback(RID p_texture, R
}
RID RasterizerStorageGLES2::texture_create_radiance_cubemap(RID p_source, int p_resolution) const {
-
return RID();
}
@@ -1326,7 +1255,6 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
// third, render to the framebuffer using separate textures, then copy to mipmaps
while (size >= 1) {
-
//make framebuffer size the texture size, need to use a separate texture for compatibility
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, resources.mipmap_blur_color);
@@ -1348,7 +1276,6 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glActiveTexture(GL_TEXTURE2); //back to panorama
for (int i = 0; i < 6; i++) {
-
shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES2::FACE_ID, i);
float roughness = mm_level >= 0 ? lod / (float)(mipmaps - 1) : 1;
@@ -1395,7 +1322,6 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
/* SHADER API */
RID RasterizerStorageGLES2::shader_create() {
-
Shader *shader = memnew(Shader);
shader->mode = RS::SHADER_SPATIAL;
shader->shader = &scene->state.scene_shader;
@@ -1414,7 +1340,6 @@ void RasterizerStorageGLES2::_shader_make_dirty(Shader *p_shader) {
}
void RasterizerStorageGLES2::shader_set_code(RID p_shader, const String &p_code) {
-
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND(!shader);
@@ -1457,7 +1382,6 @@ void RasterizerStorageGLES2::shader_set_code(RID p_shader, const String &p_code)
}
String RasterizerStorageGLES2::shader_get_code(RID p_shader) const {
-
const Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND_V(!shader, "");
@@ -1465,7 +1389,6 @@ String RasterizerStorageGLES2::shader_get_code(RID p_shader) const {
}
void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
-
_shader_dirty_list.remove(&p_shader->dirty_list);
p_shader->valid = false;
@@ -1480,9 +1403,7 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
ShaderCompilerGLES2::IdentifierActions *actions = nullptr;
switch (p_shader->mode) {
-
case RS::SHADER_CANVAS_ITEM: {
-
p_shader->canvas_item.light_mode = Shader::CanvasItem::LIGHT_MODE_NORMAL;
p_shader->canvas_item.blend_mode = Shader::CanvasItem::BLEND_MODE_MIX;
@@ -1611,7 +1532,6 @@ void RasterizerStorageGLES2::update_dirty_shaders() {
}
void RasterizerStorageGLES2::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
-
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND(!shader);
@@ -1622,7 +1542,6 @@ void RasterizerStorageGLES2::shader_get_param_list(RID p_shader, List<PropertyIn
Map<int, StringName> order;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
-
if (E->get().texture_order >= 0) {
order[E->get().texture_order + 100000] = E->key();
} else {
@@ -1631,7 +1550,6 @@ void RasterizerStorageGLES2::shader_get_param_list(RID p_shader, List<PropertyIn
}
for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
-
PropertyInfo pi;
ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[E->get()];
@@ -1738,7 +1656,6 @@ void RasterizerStorageGLES2::shader_get_param_list(RID p_shader, List<PropertyIn
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
case ShaderLanguage::TYPE_USAMPLER2DARRAY: {
-
pi.type = Variant::OBJECT;
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
pi.hint_string = "TextureArray";
@@ -1758,7 +1675,6 @@ void RasterizerStorageGLES2::shader_get_param_list(RID p_shader, List<PropertyIn
}
void RasterizerStorageGLES2::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) {
-
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND(!shader);
ERR_FAIL_COND(p_texture.is_valid() && !texture_owner.owns(p_texture));
@@ -1773,7 +1689,6 @@ void RasterizerStorageGLES2::shader_set_default_texture_param(RID p_shader, cons
}
RID RasterizerStorageGLES2::shader_get_default_texture_param(RID p_shader, const StringName &p_name) const {
-
const Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND_V(!shader, RID());
@@ -1789,7 +1704,6 @@ RID RasterizerStorageGLES2::shader_get_default_texture_param(RID p_shader, const
/* COMMON MATERIAL API */
void RasterizerStorageGLES2::_material_make_dirty(Material *p_material) const {
-
if (p_material->dirty_list.in_list())
return;
@@ -1797,14 +1711,12 @@ void RasterizerStorageGLES2::_material_make_dirty(Material *p_material) const {
}
RID RasterizerStorageGLES2::material_create() {
-
Material *material = memnew(Material);
return material_owner.make_rid(material);
}
void RasterizerStorageGLES2::material_set_shader(RID p_material, RID p_shader) {
-
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -1825,7 +1737,6 @@ void RasterizerStorageGLES2::material_set_shader(RID p_material, RID p_shader) {
}
RID RasterizerStorageGLES2::material_get_shader(RID p_material) const {
-
const Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND_V(!material, RID());
@@ -1837,7 +1748,6 @@ RID RasterizerStorageGLES2::material_get_shader(RID p_material) const {
}
void RasterizerStorageGLES2::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
-
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -1851,7 +1761,6 @@ void RasterizerStorageGLES2::material_set_param(RID p_material, const StringName
}
Variant RasterizerStorageGLES2::material_get_param(RID p_material, const StringName &p_param) const {
-
const Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND_V(!material, RID());
@@ -1921,7 +1830,6 @@ bool RasterizerStorageGLES2::material_casts_shadows(RID p_material) {
}
void RasterizerStorageGLES2::material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance) {
-
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -1934,7 +1842,6 @@ void RasterizerStorageGLES2::material_add_instance_owner(RID p_material, Rasteri
}
void RasterizerStorageGLES2::material_remove_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance) {
-
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -1976,7 +1883,6 @@ void RasterizerStorageGLES2::_update_material(Material *p_material) {
bool is_animated = false;
if (p_material->shader && p_material->shader->mode == RS::SHADER_SPATIAL) {
-
if (p_material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX &&
(!p_material->shader->spatial.uses_alpha || p_material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS)) {
can_cast_shadow = true;
@@ -2008,7 +1914,6 @@ void RasterizerStorageGLES2::_update_material(Material *p_material) {
// uniforms and other things will be set in the use_material method in ShaderGLES2
if (p_material->shader && p_material->shader->texture_count > 0) {
-
p_material->textures.resize(p_material->shader->texture_count);
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_material->shader->uniforms.front(); E; E = E->next()) {
@@ -2052,7 +1957,6 @@ void RasterizerStorageGLES2::_material_add_geometry(RID p_material, Geometry *p_
}
void RasterizerStorageGLES2::_material_remove_geometry(RID p_material, Geometry *p_geometry) {
-
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -2068,7 +1972,6 @@ void RasterizerStorageGLES2::_material_remove_geometry(RID p_material, Geometry
void RasterizerStorageGLES2::update_dirty_materials() {
while (_material_dirty_list.first()) {
-
Material *material = _material_dirty_list.first()->self();
_update_material(material);
}
@@ -2077,14 +1980,12 @@ void RasterizerStorageGLES2::update_dirty_materials() {
/* MESH API */
RID RasterizerStorageGLES2::mesh_create() {
-
Mesh *mesh = memnew(Mesh);
return mesh_owner.make_rid(mesh);
}
static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_t &format, int p_vertices) {
-
uint32_t p_format = format;
static int src_size[RS::ARRAY_MAX];
@@ -2095,7 +1996,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
int dst_stride = 0;
for (int i = 0; i < RS::ARRAY_MAX; i++) {
-
to_convert[i] = 0;
if (!(p_format & (1 << i))) {
src_size[i] = 0;
@@ -2104,11 +2004,8 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
}
switch (i) {
-
case RS::ARRAY_VERTEX: {
-
if (p_format & RS::ARRAY_COMPRESS_VERTEX) {
-
if (p_format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
src_size[i] = 4;
dst_size[i] = 8;
@@ -2121,7 +2018,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
format &= ~RS::ARRAY_COMPRESS_VERTEX;
} else {
-
if (p_format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
src_size[i] = 8;
dst_size[i] = 8;
@@ -2133,7 +2029,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
} break;
case RS::ARRAY_NORMAL: {
-
if (p_format & RS::ARRAY_COMPRESS_NORMAL) {
src_size[i] = 4;
dst_size[i] = 4;
@@ -2144,7 +2039,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
} break;
case RS::ARRAY_TANGENT: {
-
if (p_format & RS::ARRAY_COMPRESS_TANGENT) {
src_size[i] = 4;
dst_size[i] = 4;
@@ -2155,7 +2049,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
} break;
case RS::ARRAY_COLOR: {
-
if (p_format & RS::ARRAY_COMPRESS_COLOR) {
src_size[i] = 4;
dst_size[i] = 4;
@@ -2166,7 +2059,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
} break;
case RS::ARRAY_TEX_UV: {
-
if (p_format & RS::ARRAY_COMPRESS_TEX_UV) {
src_size[i] = 4;
to_convert[i] = 2;
@@ -2179,7 +2071,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
} break;
case RS::ARRAY_TEX_UV2: {
-
if (p_format & RS::ARRAY_COMPRESS_TEX_UV2) {
src_size[i] = 4;
to_convert[i] = 2;
@@ -2192,7 +2083,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
} break;
case RS::ARRAY_BONES: {
-
if (p_format & RS::ARRAY_FLAG_USE_16_BIT_BONES) {
src_size[i] = 8;
dst_size[i] = 8;
@@ -2203,7 +2093,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
} break;
case RS::ARRAY_WEIGHTS: {
-
if (p_format & RS::ARRAY_COMPRESS_WEIGHTS) {
src_size[i] = 8;
dst_size[i] = 8;
@@ -2214,7 +2103,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
} break;
case RS::ARRAY_INDEX: {
-
src_size[i] = 0;
dst_size[i] = 0;
@@ -2235,7 +2123,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
int dst_offset = 0;
for (int i = 0; i < RS::ARRAY_MAX; i++) {
-
if (src_size[i] == 0) {
continue; //no go
}
@@ -2248,7 +2135,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
float *dst = (float *)&wptr[dst_stride * j + dst_offset];
for (int k = 0; k < to_convert[i]; k++) {
-
dst[k] = Math::half_to_float(src[k]);
}
}
@@ -2273,7 +2159,6 @@ static Vector<uint8_t> _unpack_half_floats(const Vector<uint8_t> &array, uint32_
}
void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS::PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes, const Vector<AABB> &p_bone_aabbs) {
-
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
@@ -2293,7 +2178,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
bool uses_half_float = false;
for (int i = 0; i < RS::ARRAY_MAX; i++) {
-
attribs[i].index = i;
if (!(p_format & (1 << i))) {
@@ -2307,9 +2191,7 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
attribs[i].integer = false;
switch (i) {
-
case RS::ARRAY_VERTEX: {
-
if (p_format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
attribs[i].size = 2;
} else {
@@ -2329,7 +2211,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
} break;
case RS::ARRAY_NORMAL: {
-
attribs[i].size = 3;
if (p_format & RS::ARRAY_COMPRESS_NORMAL) {
@@ -2344,7 +2225,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
} break;
case RS::ARRAY_TANGENT: {
-
attribs[i].size = 4;
if (p_format & RS::ARRAY_COMPRESS_TANGENT) {
@@ -2359,7 +2239,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
} break;
case RS::ARRAY_COLOR: {
-
attribs[i].size = 4;
if (p_format & RS::ARRAY_COMPRESS_COLOR) {
@@ -2374,7 +2253,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
} break;
case RS::ARRAY_TEX_UV: {
-
attribs[i].size = 2;
if (p_format & RS::ARRAY_COMPRESS_TEX_UV) {
@@ -2390,7 +2268,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
} break;
case RS::ARRAY_TEX_UV2: {
-
attribs[i].size = 2;
if (p_format & RS::ARRAY_COMPRESS_TEX_UV2) {
@@ -2405,7 +2282,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
} break;
case RS::ARRAY_BONES: {
-
attribs[i].size = 4;
if (p_format & RS::ARRAY_FLAG_USE_16_BIT_BONES) {
@@ -2421,11 +2297,9 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
} break;
case RS::ARRAY_WEIGHTS: {
-
attribs[i].size = 4;
if (p_format & RS::ARRAY_COMPRESS_WEIGHTS) {
-
attribs[i].type = GL_UNSIGNED_SHORT;
stride += 8;
attribs[i].normalized = GL_TRUE;
@@ -2437,7 +2311,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
} break;
case RS::ARRAY_INDEX: {
-
attribs[i].size = 1;
if (p_vertex_count >= (1 << 16)) {
@@ -2478,7 +2351,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
uint16_t one = Math::make_half_float(1);
for (int i = 0; i < p_vertex_count; i++) {
-
*w16++ = *r16++;
*w16++ = *r16++;
*w16++ = *r16++;
@@ -2492,7 +2364,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
ERR_FAIL_COND(array.size() != array_size);
if (!config.support_half_float_vertices && uses_half_float) {
-
uint32_t new_format = p_format;
Vector<uint8_t> unpacked_array = _unpack_half_floats(array, new_format, p_vertex_count);
@@ -2501,7 +2372,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
}
if (p_format & RS::ARRAY_FORMAT_INDEX) {
-
index_array_size = attribs[RS::ARRAY_INDEX].stride * p_index_count;
}
@@ -2577,7 +2447,6 @@ void RasterizerStorageGLES2::mesh_add_surface(RID p_mesh, uint32_t p_format, RS:
// blend shapes
for (int i = 0; i < p_blend_shapes.size(); i++) {
-
Surface::BlendShape mt;
const uint8_t *vr = p_blend_shapes[i].ptr();
@@ -2692,7 +2561,6 @@ int RasterizerStorageGLES2::mesh_surface_get_array_index_len(RID p_mesh, int p_s
}
Vector<uint8_t> RasterizerStorageGLES2::mesh_surface_get_array(RID p_mesh, int p_surface) const {
-
const Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, Vector<uint8_t>());
ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), Vector<uint8_t>());
@@ -2749,6 +2617,7 @@ Vector<Vector<uint8_t>> RasterizerStorageGLES2::mesh_surface_get_blend_shapes(RI
return mesh->surfaces[p_surface]->blend_shape_data;
}
+
Vector<AABB> RasterizerStorageGLES2::mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const {
const Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, Vector<AABB>());
@@ -2758,7 +2627,6 @@ Vector<AABB> RasterizerStorageGLES2::mesh_surface_get_skeleton_aabb(RID p_mesh,
}
void RasterizerStorageGLES2::mesh_remove_surface(RID p_mesh, int p_surface) {
-
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
ERR_FAIL_INDEX(p_surface, mesh->surfaces.size());
@@ -2823,12 +2691,9 @@ AABB RasterizerStorageGLES2::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
AABB aabb;
if (sk && sk->size != 0) {
-
for (int i = 0; i < mesh->surfaces.size(); i++) {
-
AABB laabb;
if ((mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES) && mesh->surfaces[i]->skeleton_bone_aabb.size()) {
-
int bs = mesh->surfaces[i]->skeleton_bone_aabb.size();
const AABB *skbones = mesh->surfaces[i]->skeleton_bone_aabb.ptr();
const bool *skused = mesh->surfaces[i]->skeleton_bone_used.ptr();
@@ -2840,7 +2705,6 @@ AABB RasterizerStorageGLES2::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
bool first = true;
if (sk->use_2d) {
for (int j = 0; j < bs; j++) {
-
if (!skused[j])
continue;
@@ -2867,7 +2731,6 @@ AABB RasterizerStorageGLES2::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
}
} else {
for (int j = 0; j < bs; j++) {
-
if (!skused[j])
continue;
@@ -2901,7 +2764,6 @@ AABB RasterizerStorageGLES2::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
}
} else {
-
laabb = mesh->surfaces[i]->aabb;
}
@@ -2911,9 +2773,7 @@ AABB RasterizerStorageGLES2::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
aabb.merge_with(laabb);
}
} else {
-
for (int i = 0; i < mesh->surfaces.size(); i++) {
-
if (i == 0)
aabb = mesh->surfaces[i]->aabb;
else
@@ -2923,6 +2783,7 @@ AABB RasterizerStorageGLES2::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
return aabb;
}
+
void RasterizerStorageGLES2::mesh_clear(RID p_mesh) {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
@@ -3158,7 +3019,6 @@ void RasterizerStorageGLES2::multimesh_instance_set_color(RID p_multimesh, int p
float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats];
if (multimesh->color_format == RS::MULTIMESH_COLOR_8BIT) {
-
uint8_t *data8 = (uint8_t *)dataptr;
data8[0] = CLAMP(p_color.r * 255.0, 0, 255);
data8[1] = CLAMP(p_color.g * 255.0, 0, 255);
@@ -3191,7 +3051,6 @@ void RasterizerStorageGLES2::multimesh_instance_set_custom_data(RID p_multimesh,
float *dataptr = &multimesh->data.write[stride * p_index + multimesh->xform_floats + multimesh->color_floats];
if (multimesh->custom_data_format == RS::MULTIMESH_CUSTOM_DATA_8BIT) {
-
uint8_t *data8 = (uint8_t *)dataptr;
data8[0] = CLAMP(p_custom_data.r * 255.0, 0, 255);
data8[1] = CLAMP(p_custom_data.g * 255.0, 0, 255);
@@ -3379,13 +3238,10 @@ AABB RasterizerStorageGLES2::multimesh_get_aabb(RID p_multimesh) const {
}
void RasterizerStorageGLES2::update_dirty_multimeshes() {
-
while (multimesh_update_list.first()) {
-
MultiMesh *multimesh = multimesh_update_list.first()->self();
if (multimesh->size && multimesh->dirty_aabb) {
-
AABB mesh_aabb;
if (multimesh->mesh.is_valid()) {
@@ -3401,9 +3257,7 @@ void RasterizerStorageGLES2::update_dirty_multimeshes() {
AABB aabb;
if (multimesh->transform_format == RS::MULTIMESH_TRANSFORM_2D) {
-
for (int i = 0; i < count; i += stride) {
-
float *dataptr = &data[i];
Transform xform;
@@ -3424,9 +3278,7 @@ void RasterizerStorageGLES2::update_dirty_multimeshes() {
}
} else {
-
for (int i = 0; i < count; i += stride) {
-
float *dataptr = &data[i];
Transform xform;
@@ -3599,7 +3451,6 @@ RID RasterizerStorageGLES2::immediate_get_material(RID p_immediate) const {
/* SKELETON API */
RID RasterizerStorageGLES2::skeleton_create() {
-
Skeleton *skeleton = memnew(Skeleton);
glGenTextures(1, &skeleton->tex_id);
@@ -3608,7 +3459,6 @@ RID RasterizerStorageGLES2::skeleton_create() {
}
void RasterizerStorageGLES2::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) {
-
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
ERR_FAIL_COND(p_bones < 0);
@@ -3621,7 +3471,6 @@ void RasterizerStorageGLES2::skeleton_allocate(RID p_skeleton, int p_bones, bool
skeleton->use_2d = p_2d_skeleton;
if (!config.use_skeleton_software) {
-
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
@@ -3713,6 +3562,7 @@ Transform RasterizerStorageGLES2::skeleton_bone_get_transform(RID p_skeleton, in
return ret;
}
+
void RasterizerStorageGLES2::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
@@ -3762,7 +3612,6 @@ Transform2D RasterizerStorageGLES2::skeleton_bone_get_transform_2d(RID p_skeleto
}
void RasterizerStorageGLES2::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {
-
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
@@ -3770,7 +3619,6 @@ void RasterizerStorageGLES2::skeleton_set_base_transform_2d(RID p_skeleton, cons
}
void RasterizerStorageGLES2::_update_skeleton_transform_buffer(const Vector<float> &p_data, size_t p_size) {
-
glBindBuffer(GL_ARRAY_BUFFER, resources.skeleton_transform_buffer);
if (p_size > resources.skeleton_transform_buffer_size) {
@@ -3787,7 +3635,6 @@ void RasterizerStorageGLES2::_update_skeleton_transform_buffer(const Vector<floa
}
void RasterizerStorageGLES2::update_dirty_skeletons() {
-
if (config.use_skeleton_software)
return;
@@ -3813,7 +3660,6 @@ void RasterizerStorageGLES2::update_dirty_skeletons() {
/* Light API */
RID RasterizerStorageGLES2::light_create(RS::LightType p_type) {
-
Light *light = memnew(Light);
light->type = p_type;
@@ -4060,7 +3906,6 @@ AABB RasterizerStorageGLES2::light_get_aabb(RID p_light) const {
ERR_FAIL_COND_V(!light, AABB());
switch (light->type) {
-
case RS::LIGHT_SPOT: {
float len = light->param[RS::LIGHT_PARAM_RANGE];
float size = Math::tan(Math::deg2rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE])) * len;
@@ -4083,7 +3928,6 @@ AABB RasterizerStorageGLES2::light_get_aabb(RID p_light) const {
/* PROBE API */
RID RasterizerStorageGLES2::reflection_probe_create() {
-
ReflectionProbe *reflection_probe = memnew(ReflectionProbe);
reflection_probe->intensity = 1.0;
@@ -4104,7 +3948,6 @@ RID RasterizerStorageGLES2::reflection_probe_create() {
}
void RasterizerStorageGLES2::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -4113,7 +3956,6 @@ void RasterizerStorageGLES2::reflection_probe_set_update_mode(RID p_probe, RS::R
}
void RasterizerStorageGLES2::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -4121,7 +3963,6 @@ void RasterizerStorageGLES2::reflection_probe_set_intensity(RID p_probe, float p
}
void RasterizerStorageGLES2::reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -4129,7 +3970,6 @@ void RasterizerStorageGLES2::reflection_probe_set_interior_ambient(RID p_probe,
}
void RasterizerStorageGLES2::reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -4137,7 +3977,6 @@ void RasterizerStorageGLES2::reflection_probe_set_interior_ambient_energy(RID p_
}
void RasterizerStorageGLES2::reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -4145,23 +3984,22 @@ void RasterizerStorageGLES2::reflection_probe_set_interior_ambient_probe_contrib
}
void RasterizerStorageGLES2::reflection_probe_set_max_distance(RID p_probe, float p_distance) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->max_distance = p_distance;
reflection_probe->instance_change_notify(true, false);
}
-void RasterizerStorageGLES2::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
+void RasterizerStorageGLES2::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->extents = p_extents;
reflection_probe->instance_change_notify(true, false);
}
-void RasterizerStorageGLES2::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
+void RasterizerStorageGLES2::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -4170,15 +4008,14 @@ void RasterizerStorageGLES2::reflection_probe_set_origin_offset(RID p_probe, con
}
void RasterizerStorageGLES2::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->interior = p_enable;
reflection_probe->instance_change_notify(true, false);
}
-void RasterizerStorageGLES2::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
+void RasterizerStorageGLES2::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -4186,15 +4023,14 @@ void RasterizerStorageGLES2::reflection_probe_set_enable_box_projection(RID p_pr
}
void RasterizerStorageGLES2::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->enable_shadows = p_enable;
reflection_probe->instance_change_notify(true, false);
}
-void RasterizerStorageGLES2::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
+void RasterizerStorageGLES2::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -4203,7 +4039,6 @@ void RasterizerStorageGLES2::reflection_probe_set_cull_mask(RID p_probe, uint32_
}
void RasterizerStorageGLES2::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -4220,8 +4055,8 @@ AABB RasterizerStorageGLES2::reflection_probe_get_aabb(RID p_probe) const {
return aabb;
}
-RS::ReflectionProbeUpdateMode RasterizerStorageGLES2::reflection_probe_get_update_mode(RID p_probe) const {
+RS::ReflectionProbeUpdateMode RasterizerStorageGLES2::reflection_probe_get_update_mode(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_UPDATE_ALWAYS);
@@ -4229,7 +4064,6 @@ RS::ReflectionProbeUpdateMode RasterizerStorageGLES2::reflection_probe_get_updat
}
uint32_t RasterizerStorageGLES2::reflection_probe_get_cull_mask(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
@@ -4237,14 +4071,13 @@ uint32_t RasterizerStorageGLES2::reflection_probe_get_cull_mask(RID p_probe) con
}
Vector3 RasterizerStorageGLES2::reflection_probe_get_extents(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, Vector3());
return reflection_probe->extents;
}
-Vector3 RasterizerStorageGLES2::reflection_probe_get_origin_offset(RID p_probe) const {
+Vector3 RasterizerStorageGLES2::reflection_probe_get_origin_offset(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, Vector3());
@@ -4252,7 +4085,6 @@ Vector3 RasterizerStorageGLES2::reflection_probe_get_origin_offset(RID p_probe)
}
bool RasterizerStorageGLES2::reflection_probe_renders_shadows(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, false);
@@ -4260,7 +4092,6 @@ bool RasterizerStorageGLES2::reflection_probe_renders_shadows(RID p_probe) const
}
float RasterizerStorageGLES2::reflection_probe_get_origin_max_distance(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
@@ -4268,7 +4099,6 @@ float RasterizerStorageGLES2::reflection_probe_get_origin_max_distance(RID p_pro
}
int RasterizerStorageGLES2::reflection_probe_get_resolution(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
@@ -4339,6 +4169,7 @@ void RasterizerStorageGLES2::gi_probe_set_compress(RID p_probe, bool p_enable) {
bool RasterizerStorageGLES2::gi_probe_is_compressed(RID p_probe) const {
return false;
}
+
float RasterizerStorageGLES2::gi_probe_get_energy(RID p_probe) const {
return 0;
}
@@ -4373,26 +4204,24 @@ void RasterizerStorageGLES2::gi_probe_dynamic_data_update(RID p_gi_probe_data, i
///////
RID RasterizerStorageGLES2::lightmap_capture_create() {
-
LightmapCapture *capture = memnew(LightmapCapture);
return lightmap_capture_data_owner.make_rid(capture);
}
void RasterizerStorageGLES2::lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) {
-
LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
ERR_FAIL_COND(!capture);
capture->bounds = p_bounds;
capture->instance_change_notify(true, false);
}
-AABB RasterizerStorageGLES2::lightmap_capture_get_bounds(RID p_capture) const {
+AABB RasterizerStorageGLES2::lightmap_capture_get_bounds(RID p_capture) const {
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
ERR_FAIL_COND_V(!capture, AABB());
return capture->bounds;
}
-void RasterizerStorageGLES2::lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) {
+void RasterizerStorageGLES2::lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) {
LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
ERR_FAIL_COND(!capture);
@@ -4406,8 +4235,8 @@ void RasterizerStorageGLES2::lightmap_capture_set_octree(RID p_capture, const Ve
}
capture->instance_change_notify(true, false);
}
-Vector<uint8_t> RasterizerStorageGLES2::lightmap_capture_get_octree(RID p_capture) const {
+Vector<uint8_t> RasterizerStorageGLES2::lightmap_capture_get_octree(RID p_capture) const {
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
ERR_FAIL_COND_V(!capture, Vector<uint8_t>());
@@ -4450,14 +4279,12 @@ int RasterizerStorageGLES2::lightmap_capture_get_octree_cell_subdiv(RID p_captur
}
void RasterizerStorageGLES2::lightmap_capture_set_energy(RID p_capture, float p_energy) {
-
LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
ERR_FAIL_COND(!capture);
capture->energy = p_energy;
}
float RasterizerStorageGLES2::lightmap_capture_get_energy(RID p_capture) const {
-
const LightmapCapture *capture = lightmap_capture_data_owner.getornull(p_capture);
ERR_FAIL_COND_V(!capture, 0);
return capture->energy;
@@ -4562,7 +4389,6 @@ bool RasterizerStorageGLES2::particles_is_inactive(RID p_particles) const {
////////
void RasterizerStorageGLES2::instance_add_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) {
-
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
@@ -4570,7 +4396,6 @@ void RasterizerStorageGLES2::instance_add_skeleton(RID p_skeleton, RasterizerSce
}
void RasterizerStorageGLES2::instance_remove_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) {
-
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
@@ -4578,7 +4403,6 @@ void RasterizerStorageGLES2::instance_remove_skeleton(RID p_skeleton, Rasterizer
}
void RasterizerStorageGLES2::instance_add_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) {
-
Instantiable *inst = nullptr;
switch (p_instance->base_type) {
case RS::INSTANCE_MESH: {
@@ -4622,7 +4446,6 @@ void RasterizerStorageGLES2::instance_add_dependency(RID p_base, RasterizerScene
}
void RasterizerStorageGLES2::instance_remove_dependency(RID p_base, RasterizerScene::InstanceBase *p_instance) {
-
Instantiable *inst = nullptr;
switch (p_instance->base_type) {
@@ -4669,7 +4492,6 @@ void RasterizerStorageGLES2::instance_remove_dependency(RID p_base, RasterizerSc
/* RENDER TARGET */
void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
-
// do not allocate a render target with no size
if (rt->width <= 0 || rt->height <= 0)
return;
@@ -4707,7 +4529,6 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
rt->mip_maps_allocated = false;
{
-
/* Front FBO */
Texture *texture = texture_owner.getornull(rt->texture);
@@ -4724,11 +4545,9 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, nullptr);
if (texture->flags & RS::TEXTURE_FLAG_FILTER) {
-
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
} else {
-
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
@@ -4741,7 +4560,6 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
// depth
if (config.support_depth_texture) {
-
glGenTextures(1, &rt->depth);
glBindTexture(GL_TEXTURE_2D, rt->depth);
glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config.depth_type, nullptr);
@@ -4753,7 +4571,6 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
} else {
-
glGenRenderbuffers(1, &rt->depth);
glBindRenderbuffer(GL_RENDERBUFFER, rt->depth);
@@ -4765,13 +4582,10 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
-
glDeleteFramebuffers(1, &rt->fbo);
if (config.support_depth_texture) {
-
glDeleteTextures(1, &rt->depth);
} else {
-
glDeleteRenderbuffers(1, &rt->depth);
}
@@ -4806,7 +4620,6 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
#ifndef JAVASCRIPT_ENABLED
if (rt->msaa >= RS::VIEWPORT_MSAA_2X && rt->msaa <= RS::VIEWPORT_MSAA_16X && config.multisample_supported) {
-
rt->multisample_active = true;
static const int msaa_value[] = { 0, 2, 4, 8, 16 };
@@ -4889,7 +4702,6 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
// copy texscreen buffers
if (!(rt->flags[RasterizerStorage::RENDER_TARGET_NO_SAMPLING])) {
-
glGenTextures(1, &rt->copy_screen_effect.color);
glBindTexture(GL_TEXTURE_2D, rt->copy_screen_effect.color);
@@ -4920,9 +4732,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
// Allocate mipmap chains for post_process effects
if (!rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D] && rt->width >= 2 && rt->height >= 2) {
-
for (int i = 0; i < 2; i++) {
-
ERR_FAIL_COND(rt->mip_maps[i].sizes.size());
int w = rt->width;
int h = rt->height;
@@ -4937,7 +4747,6 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
int fb_h = h;
while (true) {
-
RenderTarget::MipMaps::Size mm;
mm.width = w;
mm.height = h;
@@ -4956,7 +4765,6 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
GLsizei height = fb_h;
if (config.render_to_mipmap_supported) {
-
glGenTextures(1, &rt->mip_maps[i].color);
glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].color);
@@ -4970,7 +4778,6 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
#endif
} else {
-
// Can't render to specific levels of a mipmap in ES 2.0 or Webgl so create a texture for each level
for (int l = 0; l < level + 1; l++) {
glGenTextures(1, &rt->mip_maps[i].sizes.write[l].color);
@@ -4990,17 +4797,14 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
glDepthMask(GL_TRUE);
for (int j = 0; j < rt->mip_maps[i].sizes.size(); j++) {
-
RenderTarget::MipMaps::Size &mm = rt->mip_maps[i].sizes.write[j];
glGenFramebuffers(1, &mm.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo);
if (config.render_to_mipmap_supported) {
-
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].color, j);
} else {
-
glBindTexture(GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->mip_maps[i].sizes[j].color, 0);
}
@@ -5046,7 +4850,6 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
}
void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) {
-
// there is nothing to clear when DIRECT_TO_SCREEN is used
if (rt->flags[RENDER_TARGET_DIRECT_TO_SCREEN])
return;
@@ -5129,7 +4932,6 @@ void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) {
}
RID RasterizerStorageGLES2::render_target_create() {
-
RenderTarget *rt = memnew(RenderTarget);
Texture *t = memnew(Texture);
@@ -5160,7 +4962,6 @@ RID RasterizerStorageGLES2::render_target_create() {
}
void RasterizerStorageGLES2::render_target_set_position(RID p_render_target, int p_x, int p_y) {
-
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
@@ -5169,7 +4970,6 @@ void RasterizerStorageGLES2::render_target_set_position(RID p_render_target, int
}
void RasterizerStorageGLES2::render_target_set_size(RID p_render_target, int p_width, int p_height) {
-
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
@@ -5185,7 +4985,6 @@ void RasterizerStorageGLES2::render_target_set_size(RID p_render_target, int p_w
}
RID RasterizerStorageGLES2::render_target_get_texture(RID p_render_target) const {
-
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
@@ -5390,7 +5189,6 @@ void RasterizerStorageGLES2::render_target_set_msaa(RID p_render_target, RS::Vie
/* CANVAS SHADOW */
RID RasterizerStorageGLES2::canvas_light_shadow_buffer_create(int p_width) {
-
CanvasLightShadow *cls = memnew(CanvasLightShadow);
if (p_width > config.max_texture_size)
@@ -5442,7 +5240,6 @@ RID RasterizerStorageGLES2::canvas_light_shadow_buffer_create(int p_width) {
/* LIGHT SHADOW MAPPING */
RID RasterizerStorageGLES2::canvas_light_occluder_create() {
-
CanvasOccluder *co = memnew(CanvasOccluder);
co->index_id = 0;
co->vertex_id = 0;
@@ -5452,14 +5249,12 @@ RID RasterizerStorageGLES2::canvas_light_occluder_create() {
}
void RasterizerStorageGLES2::canvas_light_occluder_set_polylines(RID p_occluder, const Vector<Vector2> &p_lines) {
-
CanvasOccluder *co = canvas_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!co);
co->lines = p_lines;
if (p_lines.size() != co->len) {
-
if (co->index_id)
glDeleteBuffers(1, &co->index_id);
if (co->vertex_id)
@@ -5471,7 +5266,6 @@ void RasterizerStorageGLES2::canvas_light_occluder_set_polylines(RID p_occluder,
}
if (p_lines.size()) {
-
Vector<float> geometry;
Vector<uint16_t> indices;
int lc = p_lines.size();
@@ -5487,7 +5281,6 @@ void RasterizerStorageGLES2::canvas_light_occluder_set_polylines(RID p_occluder,
const int POLY_HEIGHT = 16384;
for (int i = 0; i < lc / 2; i++) {
-
vw[i * 12 + 0] = lr[i * 2 + 0].x;
vw[i * 12 + 1] = lr[i * 2 + 0].y;
vw[i * 12 + 2] = POLY_HEIGHT;
@@ -5520,7 +5313,6 @@ void RasterizerStorageGLES2::canvas_light_occluder_set_polylines(RID p_occluder,
glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_STATIC_DRAW);
} else {
-
glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
glBufferSubData(GL_ARRAY_BUFFER, 0, lc * 6 * sizeof(real_t), vw.ptr());
}
@@ -5528,12 +5320,10 @@ void RasterizerStorageGLES2::canvas_light_occluder_set_polylines(RID p_occluder,
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
if (!co->index_id) {
-
glGenBuffers(1, &co->index_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_DYNAMIC_DRAW);
} else {
-
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, lc * 3 * sizeof(uint16_t), iw.ptr());
}
@@ -5545,7 +5335,6 @@ void RasterizerStorageGLES2::canvas_light_occluder_set_polylines(RID p_occluder,
}
RS::InstanceType RasterizerStorageGLES2::get_base_type(RID p_rid) const {
-
if (mesh_owner.owns(p_rid)) {
return RS::INSTANCE_MESH;
} else if (light_owner.owns(p_rid)) {
@@ -5564,9 +5353,7 @@ RS::InstanceType RasterizerStorageGLES2::get_base_type(RID p_rid) const {
}
bool RasterizerStorageGLES2::free(RID p_rid) {
-
if (render_target_owner.owns(p_rid)) {
-
RenderTarget *rt = render_target_owner.getornull(p_rid);
_render_target_clear(rt);
@@ -5578,7 +5365,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (texture_owner.owns(p_rid)) {
-
Texture *t = texture_owner.getornull(p_rid);
// can't free a render target texture
ERR_FAIL_COND_V(t->render_target, true);
@@ -5589,7 +5375,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (sky_owner.owns(p_rid)) {
-
Sky *sky = sky_owner.getornull(p_rid);
sky_set_texture(p_rid, RID(), 256);
sky_owner.free(p_rid);
@@ -5597,7 +5382,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (shader_owner.owns(p_rid)) {
-
Shader *shader = shader_owner.getornull(p_rid);
if (shader->shader && shader->custom_code_id) {
@@ -5622,7 +5406,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (material_owner.owns(p_rid)) {
-
Material *m = material_owner.getornull(p_rid);
if (m->shader) {
@@ -5635,7 +5418,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
}
for (Map<RasterizerScene::InstanceBase *, int>::Element *E = m->instance_owners.front(); E; E = E->next()) {
-
RasterizerScene::InstanceBase *ins = E->key();
if (ins->material_override == p_rid) {
@@ -5654,7 +5436,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (skeleton_owner.owns(p_rid)) {
-
Skeleton *s = skeleton_owner.getornull(p_rid);
if (s->update_list.in_list()) {
@@ -5676,7 +5457,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (mesh_owner.owns(p_rid)) {
-
Mesh *mesh = mesh_owner.getornull(p_rid);
mesh->instance_remove_deps();
@@ -5699,7 +5479,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (multimesh_owner.owns(p_rid)) {
-
MultiMesh *multimesh = multimesh_owner.getornull(p_rid);
multimesh->instance_remove_deps();
@@ -5727,7 +5506,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (light_owner.owns(p_rid)) {
-
Light *light = light_owner.getornull(p_rid);
light->instance_remove_deps();
@@ -5736,7 +5514,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (reflection_probe_owner.owns(p_rid)) {
-
// delete the texture
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_rid);
reflection_probe->instance_remove_deps();
@@ -5746,7 +5523,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (lightmap_capture_data_owner.owns(p_rid)) {
-
// delete the texture
LightmapCapture *lightmap_capture = lightmap_capture_data_owner.getornull(p_rid);
lightmap_capture->instance_remove_deps();
@@ -5756,7 +5532,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (canvas_occluder_owner.owns(p_rid)) {
-
CanvasOccluder *co = canvas_occluder_owner.getornull(p_rid);
if (co->index_id)
glDeleteBuffers(1, &co->index_id);
@@ -5769,7 +5544,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
return true;
} else if (canvas_light_shadow_owner.owns(p_rid)) {
-
CanvasLightShadow *cls = canvas_light_shadow_owner.getornull(p_rid);
glDeleteFramebuffers(1, &cls->fbo);
glDeleteRenderbuffers(1, &cls->depth);
@@ -5784,7 +5558,6 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
}
bool RasterizerStorageGLES2::has_os_feature(const String &p_feature) const {
-
if (p_feature == "pvrtc")
return config.pvrtc_supported;
@@ -5803,12 +5576,10 @@ void RasterizerStorageGLES2::set_debug_generate_wireframes(bool p_generate) {
}
void RasterizerStorageGLES2::render_info_begin_capture() {
-
info.snap = info.render;
}
void RasterizerStorageGLES2::render_info_end_capture() {
-
info.snap.object_count = info.render.object_count - info.snap.object_count;
info.snap.draw_call_count = info.render.draw_call_count - info.snap.draw_call_count;
info.snap.material_switch_count = info.render.material_switch_count - info.snap.material_switch_count;
@@ -5818,7 +5589,6 @@ void RasterizerStorageGLES2::render_info_end_capture() {
}
int RasterizerStorageGLES2::get_captured_render_info(RS::RenderInfo p_info) {
-
switch (p_info) {
case RS::INFO_OBJECTS_IN_FRAME: {
return info.snap.object_count;
@@ -5872,12 +5642,10 @@ int RasterizerStorageGLES2::get_render_info(RS::RenderInfo p_info) {
}
String RasterizerStorageGLES2::get_video_adapter_name() const {
-
return (const char *)glGetString(GL_RENDERER);
}
String RasterizerStorageGLES2::get_video_adapter_vendor() const {
-
return (const char *)glGetString(GL_VENDOR);
}
@@ -5885,7 +5653,6 @@ void RasterizerStorageGLES2::initialize() {
RasterizerStorageGLES2::system_fbo = 0;
{
-
const GLubyte *extension_string = glGetString(GL_EXTENSIONS);
Vector<String> extensions = String((const char *)extension_string).split(" ");
@@ -6236,7 +6003,6 @@ void RasterizerStorageGLES2::initialize() {
}
{
-
glGenFramebuffers(1, &resources.mipmap_blur_fbo);
glGenTextures(1, &resources.mipmap_blur_color);
}
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index 29651936fb..15761e4efd 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -57,7 +57,6 @@ public:
static GLuint system_fbo;
struct Config {
-
bool shrink_textures_x2;
bool use_fast_texture_filter;
bool use_skeleton_software;
@@ -106,7 +105,6 @@ public:
} config;
struct Resources {
-
GLuint white_tex;
GLuint black_tex;
GLuint normal_tex;
@@ -129,7 +127,6 @@ public:
} resources;
mutable struct Shaders {
-
ShaderCompilerGLES2 compiler;
CopyShaderGLES2 copy;
@@ -142,7 +139,6 @@ public:
} shaders;
struct Info {
-
uint64_t texture_mem;
uint64_t vertex_mem;
@@ -183,10 +179,8 @@ public:
SelfList<RasterizerScene::InstanceBase>::List instance_list;
_FORCE_INLINE_ void instance_change_notify(bool p_aabb, bool p_materials) {
-
SelfList<RasterizerScene::InstanceBase> *instances = instance_list.first();
while (instances) {
-
instances->self()->base_changed(p_aabb, p_materials);
instances = instances->next();
}
@@ -210,7 +204,6 @@ public:
};
struct Geometry : public Instantiable {
-
enum Type {
GEOMETRY_INVALID,
GEOMETRY_SURFACE,
@@ -240,7 +233,6 @@ public:
struct RenderTarget;
struct Texture {
-
Texture *proxy;
Set<Texture *> proxy_owners;
@@ -383,7 +375,6 @@ public:
/* SKY API */
struct Sky {
-
RID panorama;
GLuint radiance;
int radiance_size;
@@ -399,7 +390,6 @@ public:
struct Material;
struct Shader {
-
RID self;
RS::ShaderMode mode;
@@ -429,7 +419,6 @@ public:
uint64_t last_pass;
struct CanvasItem {
-
enum BlendMode {
BLEND_MODE_MIX,
BLEND_MODE_ADD,
@@ -455,7 +444,6 @@ public:
} canvas_item;
struct Spatial {
-
enum BlendMode {
BLEND_MODE_MIX,
BLEND_MODE_ADD,
@@ -499,7 +487,6 @@ public:
} spatial;
struct Particles {
-
} particles;
bool uses_vertex_time;
@@ -507,7 +494,6 @@ public:
Shader() :
dirty_list(this) {
-
shader = nullptr;
valid = false;
custom_code_id = 0;
@@ -536,7 +522,6 @@ public:
/* COMMON MATERIAL API */
struct Material {
-
Shader *shader;
Map<StringName, Variant> params;
SelfList<Material> list;
@@ -605,7 +590,6 @@ public:
struct Mesh;
struct Surface : public Geometry {
-
struct Attrib {
bool enabled;
bool integer;
@@ -669,7 +653,6 @@ public:
struct MultiMesh;
struct Mesh : public GeometryOwner {
-
bool active;
Vector<Surface *> surfaces;
@@ -740,7 +723,6 @@ public:
/* MULTIMESH API */
struct MultiMesh : public GeometryOwner {
-
RID mesh;
int size;
@@ -814,7 +796,6 @@ public:
/* IMMEDIATE API */
struct Immediate : public Geometry {
-
struct Chunk {
RID texture;
RS::PrimitiveType primitive;
@@ -862,7 +843,6 @@ public:
/* SKELETON API */
struct Skeleton {
-
bool use_2d;
int size;
@@ -972,7 +952,6 @@ public:
/* PROBE API */
struct ReflectionProbe : Instantiable {
-
RS::ReflectionProbeUpdateMode update_mode;
float intensity;
Color interior_ambient;
@@ -1062,7 +1041,6 @@ public:
/* LIGHTMAP */
struct LightmapCapture : public Instantiable {
-
Vector<LightmapCaptureOctree> octree;
AABB bounds;
Transform cell_xform;
@@ -1165,7 +1143,6 @@ public:
Effect copy_screen_effect;
struct MipMaps {
-
struct Size {
GLuint fbo;
GLuint color;
@@ -1252,7 +1229,6 @@ public:
/* CANVAS SHADOW */
struct CanvasLightShadow {
-
int size;
int height;
GLuint fbo;
@@ -1267,7 +1243,6 @@ public:
/* LIGHT SHADOW MAPPING */
struct CanvasOccluder {
-
GLuint vertex_id; // 0 means, unconfigured
GLuint index_id; // 0 means, unconfigured
Vector<Vector2> lines;
@@ -1284,7 +1259,6 @@ public:
virtual bool free(RID p_rid);
struct Frame {
-
RenderTarget *current_rt;
bool clear_request;
diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp
index 699d6e1484..9b57f417cb 100644
--- a/drivers/gles2/shader_compiler_gles2.cpp
+++ b/drivers/gles2/shader_compiler_gles2.cpp
@@ -38,7 +38,6 @@
#define SL ShaderLanguage
static String _mktab(int p_level) {
-
String tb;
for (int i = 0; i < p_level; i++) {
tb += "\t";
@@ -48,44 +47,45 @@ static String _mktab(int p_level) {
}
static String _typestr(SL::DataType p_type) {
-
return ShaderLanguage::get_datatype_name(p_type);
}
static String _prestr(SL::DataPrecision p_pres) {
-
switch (p_pres) {
- case SL::PRECISION_LOWP: return "lowp ";
- case SL::PRECISION_MEDIUMP: return "mediump ";
- case SL::PRECISION_HIGHP: return "highp ";
- case SL::PRECISION_DEFAULT: return "";
+ case SL::PRECISION_LOWP:
+ return "lowp ";
+ case SL::PRECISION_MEDIUMP:
+ return "mediump ";
+ case SL::PRECISION_HIGHP:
+ return "highp ";
+ case SL::PRECISION_DEFAULT:
+ return "";
}
return "";
}
static String _qualstr(SL::ArgumentQualifier p_qual) {
-
switch (p_qual) {
- case SL::ARGUMENT_QUALIFIER_IN: return "in ";
- case SL::ARGUMENT_QUALIFIER_OUT: return "out ";
- case SL::ARGUMENT_QUALIFIER_INOUT: return "inout ";
+ case SL::ARGUMENT_QUALIFIER_IN:
+ return "in ";
+ case SL::ARGUMENT_QUALIFIER_OUT:
+ return "out ";
+ case SL::ARGUMENT_QUALIFIER_INOUT:
+ return "inout ";
}
return "";
}
static String _opstr(SL::Operator p_op) {
-
return SL::get_operator_text(p_op);
}
static String _mkid(const String &p_id) {
-
String id = "m_" + p_id.replace("__", "_dus_");
return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl
}
static String f2sp0(float p_float) {
-
String num = rtoss(p_float);
if (num.find(".") == -1 && num.find("e") == -1) {
num += ".0";
@@ -94,13 +94,12 @@ static String f2sp0(float p_float) {
}
static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value> &p_values) {
-
switch (p_type) {
- case SL::TYPE_BOOL: return p_values[0].boolean ? "true" : "false";
+ case SL::TYPE_BOOL:
+ return p_values[0].boolean ? "true" : "false";
case SL::TYPE_BVEC2:
case SL::TYPE_BVEC3:
case SL::TYPE_BVEC4: {
-
StringBuffer<> text;
text += "bvec";
@@ -118,11 +117,11 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
}
// GLSL ES 2 doesn't support uints, so we just use signed ints instead...
- case SL::TYPE_UINT: return itos(p_values[0].uint);
+ case SL::TYPE_UINT:
+ return itos(p_values[0].uint);
case SL::TYPE_UVEC2:
case SL::TYPE_UVEC3:
case SL::TYPE_UVEC4: {
-
StringBuffer<> text;
text += "ivec";
@@ -140,11 +139,11 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
} break;
- case SL::TYPE_INT: return itos(p_values[0].sint);
+ case SL::TYPE_INT:
+ return itos(p_values[0].sint);
case SL::TYPE_IVEC2:
case SL::TYPE_IVEC3:
case SL::TYPE_IVEC4: {
-
StringBuffer<> text;
text += "ivec";
@@ -161,11 +160,11 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
return text.as_string();
} break;
- case SL::TYPE_FLOAT: return f2sp0(p_values[0].real);
+ case SL::TYPE_FLOAT:
+ return f2sp0(p_values[0].real);
case SL::TYPE_VEC2:
case SL::TYPE_VEC3:
case SL::TYPE_VEC4: {
-
StringBuffer<> text;
text += "vec";
@@ -185,7 +184,6 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
case SL::TYPE_MAT2:
case SL::TYPE_MAT3:
case SL::TYPE_MAT4: {
-
StringBuffer<> text;
text += "mat";
@@ -202,7 +200,8 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
return text.as_string();
} break;
- default: ERR_FAIL_V(String());
+ default:
+ ERR_FAIL_V(String());
}
}
@@ -219,7 +218,6 @@ void ShaderCompilerGLES2::_dump_function_deps(SL::ShaderNode *p_node, const Stri
ERR_FAIL_COND(fidx == -1);
for (Set<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) {
-
if (r_added.has(E->get())) {
continue;
}
@@ -265,19 +263,14 @@ void ShaderCompilerGLES2::_dump_function_deps(SL::ShaderNode *p_node, const Stri
}
String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning) {
-
StringBuilder code;
switch (p_node->type) {
-
case SL::Node::TYPE_SHADER: {
-
SL::ShaderNode *snode = (SL::ShaderNode *)p_node;
for (int i = 0; i < snode->render_modes.size(); i++) {
-
if (p_default_actions.render_mode_defines.has(snode->render_modes[i]) && !used_rmode_defines.has(snode->render_modes[i])) {
-
r_gen_code.custom_defines.push_back(p_default_actions.render_mode_defines[snode->render_modes[i]].utf8());
used_rmode_defines.insert(snode->render_modes[i]);
}
@@ -314,7 +307,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
// structs
for (int i = 0; i < snode->vstructs.size(); i++) {
-
SL::StructNode *st = snode->vstructs[i].shader_struct;
String struct_code;
@@ -381,7 +373,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
// varyings
for (Map<StringName, SL::ShaderNode::Varying>::Element *E = snode->varyings.front(); E; E = E->next()) {
-
StringBuffer<> varying_code;
varying_code += "varying ";
@@ -404,18 +395,19 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
// constants
- for (Map<StringName, SL::ShaderNode::Constant>::Element *E = snode->constants.front(); E; E = E->next()) {
+ for (int i = 0; i < snode->vconstants.size(); i++) {
+ const SL::ShaderNode::Constant &cnode = snode->vconstants[i];
String gcode;
gcode += "const ";
- gcode += _prestr(E->get().precision);
- if (E->get().type == SL::TYPE_STRUCT) {
- gcode += _mkid(E->get().type_str);
+ gcode += _prestr(cnode.precision);
+ if (cnode.type == SL::TYPE_STRUCT) {
+ gcode += _mkid(cnode.type_str);
} else {
- gcode += _typestr(E->get().type);
+ gcode += _typestr(cnode.type);
}
- gcode += " " + _mkid(E->key());
+ gcode += " " + _mkid(String(cnode.name));
gcode += "=";
- gcode += _dump_node_code(E->get().initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ gcode += _dump_node_code(cnode.initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
gcode += ";\n";
vertex_global += gcode;
fragment_global += gcode;
@@ -435,7 +427,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
Set<StringName> added_fragment;
for (int i = 0; i < snode->functions.size(); i++) {
-
SL::FunctionNode *fnode = snode->functions[i].function;
current_func_name = fnode->name;
@@ -459,14 +450,11 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break;
case SL::Node::TYPE_STRUCT: {
-
} break;
case SL::Node::TYPE_FUNCTION: {
-
} break;
case SL::Node::TYPE_BLOCK: {
-
SL::BlockNode *bnode = (SL::BlockNode *)p_node;
if (!bnode->single_statement) {
@@ -507,7 +495,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
for (int i = 0; i < var_dec_node->declarations.size(); i++) {
-
if (i > 0) {
declaration += ",";
}
@@ -584,7 +571,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += ")";
} break;
case SL::Node::TYPE_ARRAY_DECLARATION: {
-
SL::ArrayDeclarationNode *arr_dec_node = (SL::ArrayDeclarationNode *)p_node;
StringBuffer<> declaration;
@@ -595,7 +581,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
declaration += _typestr(arr_dec_node->datatype);
}
for (int i = 0; i < arr_dec_node->declarations.size(); i++) {
-
if (i > 0) {
declaration += ",";
}
@@ -723,7 +708,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
} else if (op_node->op == SL::OP_CONSTRUCT) {
code += var_node->name;
} else {
-
if (var_node->name == "texture") {
// emit texture call
@@ -751,9 +735,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
} else if (var_node->name == "mix") {
-
switch (op_node->arguments[3]->get_datatype()) {
-
case SL::TYPE_BVEC2: {
code += "select2";
} break;
@@ -770,7 +752,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
case SL::TYPE_VEC3:
case SL::TYPE_VEC4:
case SL::TYPE_FLOAT: {
-
code += "mix";
} break;
@@ -833,7 +814,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
} break;
case SL::OP_MOD: {
-
code += "mod(float(";
code += _dump_node_code(op_node->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += "), float(";
@@ -857,7 +837,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
SL::ControlFlowNode *cf_node = (SL::ControlFlowNode *)p_node;
if (cf_node->flow_op == SL::FLOW_OP_IF) {
-
code += _mktab(p_level);
code += "if (";
code += _dump_node_code(cf_node->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
@@ -884,7 +863,6 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += ")\n";
code += _dump_node_code(cf_node->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
} else if (cf_node->flow_op == SL::FLOW_OP_FOR) {
-
code += _mktab(p_level);
code += "for (";
code += _dump_node_code(cf_node->blocks[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
@@ -935,11 +913,9 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener
}
Error ShaderCompilerGLES2::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
-
Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types());
if (err != OK) {
-
Vector<String> shader = p_code.split("\n");
for (int i = 0; i < shader.size(); i++) {
print_line(itos(i + 1) + " " + shader[i]);
@@ -972,7 +948,6 @@ Error ShaderCompilerGLES2::compile(RS::ShaderMode p_mode, const String &p_code,
}
ShaderCompilerGLES2::ShaderCompilerGLES2() {
-
/** CANVAS ITEM SHADER **/
actions[RS::SHADER_CANVAS_ITEM].renames["VERTEX"] = "outvec.xy";
diff --git a/drivers/gles2/shader_compiler_gles2.h b/drivers/gles2/shader_compiler_gles2.h
index 757dcdd4f2..369bf7877b 100644
--- a/drivers/gles2/shader_compiler_gles2.h
+++ b/drivers/gles2/shader_compiler_gles2.h
@@ -40,7 +40,6 @@
class ShaderCompilerGLES2 {
public:
struct IdentifierActions {
-
Map<StringName, Pair<int *, int>> render_mode_values;
Map<StringName, bool *> render_mode_flags;
Map<StringName, bool *> usage_flag_pointers;
@@ -50,7 +49,6 @@ public:
};
struct GeneratedCode {
-
Vector<CharString> custom_defines;
Vector<StringName> uniforms;
Vector<StringName> texture_uniforms;
@@ -71,7 +69,6 @@ private:
ShaderLanguage parser;
struct DefaultIdentifierActions {
-
Map<StringName, String> renames;
Map<StringName, String> render_mode_defines;
Map<StringName, String> usage_defines;
diff --git a/drivers/gles2/shader_gles2.cpp b/drivers/gles2/shader_gles2.cpp
index 2c335c6c5a..48b98435c4 100644
--- a/drivers/gles2/shader_gles2.cpp
+++ b/drivers/gles2/shader_gles2.cpp
@@ -70,14 +70,12 @@ ShaderGLES2 *ShaderGLES2::active = nullptr;
#endif
GLint ShaderGLES2::get_uniform_location(int p_index) const {
-
ERR_FAIL_COND_V(!version, -1);
return version->uniform_location[p_index];
}
bool ShaderGLES2::bind() {
-
if (active != this || !version || new_conditional_version.key != conditional_version.key) {
conditional_version = new_conditional_version;
version = get_current_version();
@@ -110,7 +108,6 @@ void ShaderGLES2::unbind() {
}
static void _display_error_with_code(const String &p_error, const Vector<const char *> &p_code) {
-
int line = 1;
String total_code;
@@ -121,7 +118,6 @@ static void _display_error_with_code(const String &p_error, const Vector<const c
Vector<String> lines = String(total_code).split("\n");
for (int j = 0; j < lines.size(); j++) {
-
print_line(itos(line) + ": " + lines[j]);
line++;
}
@@ -130,13 +126,11 @@ static void _display_error_with_code(const String &p_error, const Vector<const c
}
static String _mkid(const String &p_id) {
-
String id = "m_" + p_id;
return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl
}
ShaderGLES2::Version *ShaderGLES2::get_current_version() {
-
Version *_v = version_map.getptr(conditional_version);
if (_v) {
@@ -457,7 +451,6 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
}
GLint ShaderGLES2::get_uniform_location(const String &p_name) const {
-
ERR_FAIL_COND_V(!version, -1);
return glGetUniformLocation(version->id, p_name.ascii().get_data());
}
@@ -475,7 +468,6 @@ void ShaderGLES2::setup(
const char *p_fragment_code,
int p_vertex_code_start,
int p_fragment_code_start) {
-
ERR_FAIL_COND(version);
conditional_version.key = 0;
@@ -532,7 +524,6 @@ void ShaderGLES2::setup(
String code2;
if (cpos != -1) {
-
fragment_code1 = code.substr(0, cpos).ascii();
code2 = code.substr(cpos + light_code_tag.length(), code.length());
} else {
@@ -617,7 +608,6 @@ void ShaderGLES2::set_custom_shader(uint32_t p_code_id) {
}
void ShaderGLES2::free_custom_shader(uint32_t p_code_id) {
-
ERR_FAIL_COND(!custom_code_map.has(p_code_id));
if (conditional_version.code_version == p_code_id) {
conditional_version.code_version = 0; //do not keep using a version that is going away
@@ -658,7 +648,6 @@ void ShaderGLES2::use_material(void *p_material) {
// bind uniforms
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = material->shader->uniforms.front(); E; E = E->next()) {
-
if (E->get().texture_order >= 0)
continue; // this is a texture, doesn't go here
@@ -673,7 +662,6 @@ void ShaderGLES2::use_material(void *p_material) {
if (V) {
switch (E->get().type) {
case ShaderLanguage::TYPE_BOOL: {
-
bool boolean = V->get();
glUniform1i(location, boolean ? 1 : 0);
} break;
@@ -684,7 +672,6 @@ void ShaderGLES2::use_material(void *p_material) {
} break;
case ShaderLanguage::TYPE_BVEC3: {
-
int flags = V->get();
glUniform3i(location, (flags & 1) ? 1 : 0, (flags & 2) ? 1 : 0, (flags & 4) ? 1 : 0);
@@ -704,7 +691,6 @@ void ShaderGLES2::use_material(void *p_material) {
case ShaderLanguage::TYPE_IVEC2:
case ShaderLanguage::TYPE_UVEC2: {
-
Array r = V->get();
const int count = 2;
if (r.size() == count) {
@@ -776,7 +762,6 @@ void ShaderGLES2::use_material(void *p_material) {
} break;
case ShaderLanguage::TYPE_MAT2: {
-
Transform2D tr = V->get();
GLfloat matrix[4] = {
/* build a 16x16 matrix */
@@ -809,7 +794,6 @@ void ShaderGLES2::use_material(void *p_material) {
} break;
case ShaderLanguage::TYPE_MAT4: {
-
Transform2D tr = V->get();
GLfloat matrix[16] = { /* build a 16x16 matrix */
tr.elements[0][0],
@@ -938,19 +922,15 @@ void ShaderGLES2::use_material(void *p_material) {
} break;
case ShaderLanguage::TYPE_SAMPLER2D: {
-
} break;
case ShaderLanguage::TYPE_ISAMPLER2D: {
-
} break;
case ShaderLanguage::TYPE_USAMPLER2D: {
-
} break;
case ShaderLanguage::TYPE_SAMPLERCUBE: {
-
} break;
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
@@ -1057,19 +1037,15 @@ void ShaderGLES2::use_material(void *p_material) {
} break;
case ShaderLanguage::TYPE_SAMPLER2D: {
-
} break;
case ShaderLanguage::TYPE_ISAMPLER2D: {
-
} break;
case ShaderLanguage::TYPE_USAMPLER2D: {
-
} break;
case ShaderLanguage::TYPE_SAMPLERCUBE: {
-
} break;
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
diff --git a/drivers/gles2/shader_gles2.h b/drivers/gles2/shader_gles2.h
index d20d5bc585..3096c1e258 100644
--- a/drivers/gles2/shader_gles2.h
+++ b/drivers/gles2/shader_gles2.h
@@ -53,20 +53,17 @@ class RasterizerStorageGLES2;
class ShaderGLES2 {
protected:
struct Enum {
-
uint64_t mask;
uint64_t shift;
const char *defines[16];
};
struct EnumValue {
-
uint64_t set_mask;
uint64_t clear_mask;
};
struct AttributePair {
-
const char *name;
int index;
};
@@ -77,7 +74,6 @@ protected:
};
struct TexUnitPair {
-
const char *name;
int index;
};
@@ -94,7 +90,6 @@ private:
int attribute_pair_count;
struct CustomCode {
-
String vertex;
String vertex_globals;
String fragment;
@@ -108,7 +103,6 @@ private:
};
struct Version {
-
GLuint id;
GLuint vert_id;
GLuint frag_id;
@@ -130,7 +124,6 @@ private:
Version *version;
union VersionKey {
-
struct {
uint32_t version;
uint32_t code_version;
@@ -141,7 +134,6 @@ private:
};
struct VersionKeyHash {
-
static _FORCE_INLINE_ uint32_t hash(const VersionKey &p_key) { return HashMapHasherDefault::hash(p_key.key); }
};
@@ -252,14 +244,12 @@ public:
// called a lot, made inline
int ShaderGLES2::_get_uniform(int p_which) const {
-
ERR_FAIL_INDEX_V(p_which, uniform_count, -1);
ERR_FAIL_COND_V(!version, -1);
return version->uniform_location[p_which];
}
void ShaderGLES2::_set_conditional(int p_which, bool p_value) {
-
ERR_FAIL_INDEX(p_which, conditional_count);
if (p_value)
new_conditional_version.version |= (1 << p_which);
diff --git a/drivers/gles2/shaders/blend_shape.glsl b/drivers/gles2/shaders/blend_shape.glsl
index 0d0b3e24e4..e229da6f18 100644
--- a/drivers/gles2/shaders/blend_shape.glsl
+++ b/drivers/gles2/shaders/blend_shape.glsl
@@ -110,7 +110,6 @@ out vec4 weight_out; //tfb:ENABLE_SKELETON
uniform float blend_amount;
void main() {
-
#ifdef ENABLE_BLEND
vertex_out = vertex_attrib_blend + vertex_attrib * blend_amount;
@@ -191,4 +190,5 @@ void main() {
void main() {
}
+
/* clang-format on */
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index 3b685b3f0b..1fadf44d97 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -111,7 +111,6 @@ vec2 select(vec2 a, vec2 b, bvec2 c) {
}
void main() {
-
vec4 color = color_attrib;
vec2 uv;
@@ -186,7 +185,6 @@ VERTEX_SHADER_CODE
// look up transform from the "pose texture"
if (bone_weights != vec4(0.0)) {
-
highp mat4 bone_transform = mat4(0.0);
for (int i = 0; i < 4; i++) {
@@ -367,7 +365,6 @@ LIGHT_SHADER_CODE
}
void main() {
-
vec4 color = color_interp;
vec2 uv = uv_interp;
#ifdef USE_FORCE_REPEAT
@@ -499,11 +496,9 @@ FRAGMENT_SHADER_CODE
point = -shadow_vec;
sh = 0.5 + (1.0 / 8.0);
} else if (angle_to_light > 0.0) {
-
point = vec2(shadow_vec.y, -shadow_vec.x);
sh = 0.25 + (1.0 / 8.0);
} else {
-
point = vec2(-shadow_vec.y, shadow_vec.x);
sh = 0.75 + (1.0 / 8.0);
}
diff --git a/drivers/gles2/shaders/canvas_shadow.glsl b/drivers/gles2/shaders/canvas_shadow.glsl
index 7a5ba4f571..2abcd5e67c 100644
--- a/drivers/gles2/shaders/canvas_shadow.glsl
+++ b/drivers/gles2/shaders/canvas_shadow.glsl
@@ -21,7 +21,6 @@ uniform highp float distance_norm;
varying highp vec4 position_interp;
void main() {
-
gl_Position = projection_matrix * (light_matrix * (world_matrix * vec4(vertex, 1.0)));
position_interp = gl_Position;
}
@@ -47,7 +46,6 @@ varying highp vec4 position_interp;
/* clang-format on */
void main() {
-
highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0; // bias
#ifdef USE_RGBA_SHADOWS
diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl
index aa967115da..e833722ac3 100644
--- a/drivers/gles2/shaders/copy.glsl
+++ b/drivers/gles2/shaders/copy.glsl
@@ -40,7 +40,6 @@ uniform highp mat4 display_transform;
#endif
void main() {
-
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
cube_interp = cube_in;
#elif defined(USE_ASYM_PANO)
@@ -115,7 +114,6 @@ uniform float custom_alpha;
uniform highp mat4 sky_transform;
vec4 texturePanorama(sampler2D pano, vec3 normal) {
-
vec2 st = vec2(
atan(normal.x, normal.z),
acos(normal.y));
@@ -131,7 +129,6 @@ vec4 texturePanorama(sampler2D pano, vec3 normal) {
#endif
void main() {
-
#ifdef USE_PANORAMA
vec3 cube_normal = normalize(cube_interp);
diff --git a/drivers/gles2/shaders/cube_to_dp.glsl b/drivers/gles2/shaders/cube_to_dp.glsl
index 769908c3b4..1612ec3d5a 100644
--- a/drivers/gles2/shaders/cube_to_dp.glsl
+++ b/drivers/gles2/shaders/cube_to_dp.glsl
@@ -17,7 +17,6 @@ attribute vec2 uv_in; // attrib:4
varying vec2 uv_interp;
void main() {
-
uv_interp = uv_in;
gl_Position = vertex_attrib;
}
@@ -49,7 +48,6 @@ uniform highp float z_near;
uniform highp float bias;
void main() {
-
highp vec3 normal = vec3(uv_interp * 2.0 - 1.0, 0.0);
/*
if (z_flip) {
diff --git a/drivers/gles2/shaders/cubemap_filter.glsl b/drivers/gles2/shaders/cubemap_filter.glsl
index db3d8b3a1b..f5c91cc707 100644
--- a/drivers/gles2/shaders/cubemap_filter.glsl
+++ b/drivers/gles2/shaders/cubemap_filter.glsl
@@ -17,7 +17,6 @@ attribute highp vec2 uv; // attrib:4
varying highp vec2 uv_interp;
void main() {
-
uv_interp = uv;
gl_Position = vec4(vertex, 0, 1);
}
@@ -87,7 +86,6 @@ uniform sampler2D radical_inverse_vdc_cache; // texunit:1
#ifdef USE_SOURCE_PANORAMA
vec4 texturePanorama(sampler2D pano, vec3 normal) {
-
vec2 st = vec2(
atan(normal.x, normal.z),
acos(normal.y));
@@ -179,7 +177,6 @@ vec2 Hammersley(int i, int N) {
uniform bool z_flip;
void main() {
-
vec3 color = vec3(0.0);
vec2 uv = (uv_interp * 2.0) - 1.0;
@@ -200,7 +197,6 @@ void main() {
vec4 sum = vec4(0.0);
for (int sample_num = 0; sample_num < SAMPLE_COUNT; sample_num++) {
-
vec2 xi = Hammersley(sample_num, SAMPLE_COUNT);
vec3 H = ImportanceSampleGGX(xi, roughness, N);
diff --git a/drivers/gles2/shaders/effect_blur.glsl b/drivers/gles2/shaders/effect_blur.glsl
index b28d78a6ca..7b607dd76a 100644
--- a/drivers/gles2/shaders/effect_blur.glsl
+++ b/drivers/gles2/shaders/effect_blur.glsl
@@ -23,7 +23,6 @@ uniform vec4 blur_section;
#endif
void main() {
-
uv_interp = uv_in;
gl_Position = vec4(vertex_attrib, 0.0, 1.0);
#ifdef USE_BLUR_SECTION
@@ -127,7 +126,6 @@ uniform float camera_z_far;
uniform float camera_z_near;
void main() {
-
#ifdef GLOW_GAUSSIAN_HORIZONTAL
vec2 pix_size = pixel_size;
pix_size *= 0.5; //reading from larger buffer, so use more samples
@@ -228,7 +226,6 @@ void main() {
float k_accum = 0.0;
for (int i = 0; i < dof_kernel_size; i++) {
-
int int_ofs = i - dof_kernel_from;
vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * amount * dof_radius;
@@ -265,7 +262,6 @@ void main() {
float max_accum = 0.0;
for (int i = 0; i < dof_kernel_size; i++) {
-
int int_ofs = i - dof_kernel_from;
vec2 tap_uv = uv_interp + dof_dir * float(int_ofs) * dof_radius;
float ofs_influence = max(0.0, 1.0 - abs(float(int_ofs)) / float(dof_kernel_from));
diff --git a/drivers/gles2/shaders/exposure.glsl b/drivers/gles2/shaders/exposure.glsl
index 759adcda06..c20812bfa3 100644
--- a/drivers/gles2/shaders/exposure.glsl
+++ b/drivers/gles2/shaders/exposure.glsl
@@ -5,7 +5,6 @@ layout(location = 0) in highp vec4 vertex_attrib;
/* clang-format on */
void main() {
-
gl_Position = vertex_attrib;
}
@@ -34,7 +33,6 @@ uniform highp float max_luminance;
layout(location = 0) out highp float exposure;
void main() {
-
#ifdef EXPOSURE_BEGIN
ivec2 src_pos = ivec2(gl_FragCoord.xy) * source_render_size / target_size;
diff --git a/drivers/gles2/shaders/lens_distorted.glsl b/drivers/gles2/shaders/lens_distorted.glsl
index f4ff80ba9a..d568006ccc 100644
--- a/drivers/gles2/shaders/lens_distorted.glsl
+++ b/drivers/gles2/shaders/lens_distorted.glsl
@@ -19,7 +19,6 @@ uniform vec2 scale;
varying vec2 uv_interp;
void main() {
-
uv_interp = vertex.xy * 2.0 - 1.0;
vec2 v = vertex.xy * scale + offset;
diff --git a/drivers/gles2/shaders/particles.glsl b/drivers/gles2/shaders/particles.glsl
index 5974050fc1..d762dade2f 100644
--- a/drivers/gles2/shaders/particles.glsl
+++ b/drivers/gles2/shaders/particles.glsl
@@ -10,7 +10,6 @@ layout(location = 4) in highp vec4 xform_2;
layout(location = 5) in highp vec4 xform_3;
struct Attractor {
-
vec3 pos;
vec3 dir;
float radius;
@@ -64,7 +63,6 @@ VERTEX_SHADER_GLOBALS
/* clang-format on */
uint hash(uint x) {
-
x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b);
x = ((x >> uint(16)) ^ x) * uint(0x45d9f3b);
x = (x >> uint(16)) ^ x;
@@ -72,7 +70,6 @@ uint hash(uint x) {
}
void main() {
-
#ifdef PARTICLES_COPY
out_color = color;
@@ -183,10 +180,8 @@ VERTEX_SHADER_CODE
#if !defined(DISABLE_FORCE)
if (false) {
-
vec3 force = vec3(0.0);
for (int i = 0; i < attractor_count; i++) {
-
vec3 rel_vec = xform[3].xyz - attractors[i].pos;
float dist = length(rel_vec);
if (attractors[i].radius < dist)
@@ -214,7 +209,6 @@ VERTEX_SHADER_CODE
#if !defined(DISABLE_VELOCITY)
if (true) {
-
xform[3].xyz += out_velocity_active.xyz * local_delta;
}
#endif
@@ -263,4 +257,5 @@ FRAGMENT_SHADER_CODE
}
}
+
/* clang-format on */
diff --git a/drivers/gles2/shaders/resolve.glsl b/drivers/gles2/shaders/resolve.glsl
index 5c6f5d6561..071cb37a99 100644
--- a/drivers/gles2/shaders/resolve.glsl
+++ b/drivers/gles2/shaders/resolve.glsl
@@ -8,7 +8,6 @@ layout(location = 4) in vec2 uv_in;
out vec2 uv_interp;
void main() {
-
uv_interp = uv_in;
gl_Position = vertex_attrib;
}
@@ -32,7 +31,6 @@ in vec2 uv2_interp;
layout(location = 0) out vec4 frag_color;
void main() {
-
vec4 specular = texture(source_specular, uv_interp);
#ifdef USE_SSR
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 84aadcbbc3..0311dc4742 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -194,7 +194,6 @@ void light_compute(
vec3 light_color,
vec3 attenuation,
float roughness) {
-
//this makes lights behave closer to linear, but then addition of lights looks bad
//better left disabled
@@ -249,7 +248,6 @@ void light_compute(
diffuse_interp += light_color * diffuse_brdf_NL * attenuation;
if (roughness > 0.0) {
-
// D
float specular_brdf_NL = 0.0;
@@ -325,7 +323,6 @@ uniform mediump float fog_height_curve;
#endif //fog
void main() {
-
highp vec4 vertex = vertex_attrib;
mat4 world_matrix = world_transform;
@@ -394,7 +391,6 @@ void main() {
#else
// look up transform from the "pose texture"
{
-
for (int i = 0; i < 4; i++) {
ivec2 tex_ofs = ivec2(int(bone_ids[i]) * 3, 0);
@@ -512,7 +508,6 @@ VERTEX_SHADER_CODE
float normalized_distance = light_length / light_range;
if (normalized_distance < 1.0) {
-
float omni_attenuation = pow(1.0 - normalized_distance, light_attenuation);
vec3 attenuation = vec3(omni_attenuation);
@@ -532,7 +527,6 @@ VERTEX_SHADER_CODE
float normalized_distance = light_length / light_range;
if (normalized_distance < 1.0) {
-
float spot_attenuation = pow(1.0 - normalized_distance, light_attenuation);
vec3 spot_dir = light_direction;
@@ -541,7 +535,6 @@ VERTEX_SHADER_CODE
float angle = dot(-normalize(light_rel_vec), spot_dir);
if (angle > spot_cutoff) {
-
float scos = max(angle, spot_cutoff);
float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_cutoff));
@@ -645,7 +638,6 @@ VERTEX_SHADER_CODE
#ifdef FOG_DEPTH_ENABLED
{
-
float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
fog_amount = pow(fog_z, fog_depth_curve) * fog_color_base.a;
@@ -1073,6 +1065,7 @@ float G_GGX_2cos(float cos_theta_m, float alpha) {
// float sin2 = (1.0 - cos2);
// return 1.0 / (cos_theta_m + sqrt(cos2 + alpha * alpha * sin2));
}
+
*/
// This approximates G_GGX_2cos(cos_theta_l, alpha) * G_GGX_2cos(cos_theta_v, alpha)
@@ -1095,6 +1088,7 @@ float G_GGX_anisotropic_2cos(float cos_theta_m, float alpha_x, float alpha_y, fl
float s_y = alpha_y * sin_phi;
return 1.0 / max(cos_theta_m + sqrt(cos2 + (s_x * s_x + s_y * s_y) * sin2), 0.001);
}
+
*/
// This approximates G_GGX_anisotropic_2cos(cos_theta_l, ...) * G_GGX_anisotropic_2cos(cos_theta_v, ...)
@@ -1128,7 +1122,8 @@ float SchlickFresnel(float u) {
}
float GTR1(float NdotH, float a) {
- if (a >= 1.0) return 1.0 / M_PI;
+ if (a >= 1.0)
+ return 1.0 / M_PI;
float a2 = a * a;
float t = 1.0 + (a2 - 1.0) * NdotH * NdotH;
return (a2 - 1.0) / (M_PI * log(a2) * t);
@@ -1156,7 +1151,6 @@ void light_compute(
inout vec3 diffuse_light,
inout vec3 specular_light,
inout float alpha) {
-
//this makes lights behave closer to linear, but then addition of lights looks bad
//better left disabled
@@ -1380,7 +1374,6 @@ LIGHT_SHADER_CODE
#define SAMPLE_SHADOW_TEXEL_PROJ(p_shadow, p_pos) step(p_pos.z, SHADOW_DEPTH(texture2DProj(p_shadow, p_pos)))
float sample_shadow(highp sampler2D shadow, highp vec4 spos) {
-
#ifdef SHADOW_MODE_PCF_13
spos.xyz /= spos.w;
@@ -1457,7 +1450,6 @@ uniform mediump float fog_height_curve;
#endif //fog
void main() {
-
#ifdef RENDER_DEPTH_DUAL_PARABOLOID
if (dp_clip > 0.0)
@@ -1652,7 +1644,6 @@ FRAGMENT_SHADER_CODE
// environment BRDF approximation
{
-
#if defined(DIFFUSE_TOON)
//simplify for toon, as
specular_light *= specular * metallic * albedo * 2.0;
@@ -1731,7 +1722,6 @@ FRAGMENT_SHADER_CODE
float normalized_distance = light_length / light_range;
if (normalized_distance < 1.0) {
-
float omni_attenuation = pow(1.0 - normalized_distance, light_attenuation);
light_att = vec3(omni_attenuation);
@@ -1828,7 +1818,6 @@ FRAGMENT_SHADER_CODE
}
} else {
if (depth_z < light_split_offsets.z) {
-
shadow_att = shadow3;
#if defined(LIGHT_USE_PSSM_BLEND)
@@ -1837,7 +1826,6 @@ FRAGMENT_SHADER_CODE
#endif
} else {
-
shadow_att = shadow4;
pssm_fade = smoothstep(light_split_offsets.z, light_split_offsets.w, depth_z);
@@ -1880,7 +1868,6 @@ FRAGMENT_SHADER_CODE
pssm_blend = smoothstep(0.0, light_split_offsets.x, depth_z);
#endif
} else {
-
shadow_att = shadow2;
pssm_fade = smoothstep(light_split_offsets.x, light_split_offsets.y, depth_z);
#ifdef LIGHT_USE_PSSM_BLEND
@@ -1944,7 +1931,6 @@ FRAGMENT_SHADER_CODE
}
} else {
if (depth_z < light_split_offsets.z) {
-
pssm_coord = shadow_coord3;
#if defined(LIGHT_USE_PSSM_BLEND)
@@ -1953,7 +1939,6 @@ FRAGMENT_SHADER_CODE
#endif
} else {
-
pssm_coord = shadow_coord4;
pssm_fade = smoothstep(light_split_offsets.z, light_split_offsets.w, depth_z);
@@ -1967,7 +1952,6 @@ FRAGMENT_SHADER_CODE
#ifdef LIGHT_USE_PSSM2
if (depth_z < light_split_offsets.x) {
-
pssm_coord = shadow_coord;
#ifdef LIGHT_USE_PSSM_BLEND
@@ -1975,7 +1959,6 @@ FRAGMENT_SHADER_CODE
pssm_blend = smoothstep(0.0, light_split_offsets.x, depth_z);
#endif
} else {
-
pssm_coord = shadow_coord2;
pssm_fade = smoothstep(light_split_offsets.x, light_split_offsets.y, depth_z);
#ifdef LIGHT_USE_PSSM_BLEND
@@ -2164,7 +2147,6 @@ FRAGMENT_SHADER_CODE
#ifdef FOG_DEPTH_ENABLED
{
-
float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
fog_amount = pow(fog_z, fog_depth_curve) * fog_color_base.a;
diff --git a/drivers/gles2/shaders/screen_space_reflection.glsl b/drivers/gles2/shaders/screen_space_reflection.glsl
index a11da10b61..6b5b7c885c 100644
--- a/drivers/gles2/shaders/screen_space_reflection.glsl
+++ b/drivers/gles2/shaders/screen_space_reflection.glsl
@@ -9,7 +9,6 @@ out vec2 uv_interp;
out vec2 pos_interp;
void main() {
-
uv_interp = uv_in;
gl_Position = vertex_attrib;
pos_interp.xy = gl_Position.xy;
@@ -55,7 +54,6 @@ vec2 view_to_screen(vec3 view_pos, out float w) {
#define M_PI 3.14159265359
void main() {
-
vec4 diffuse = texture(source_diffuse, uv_interp);
vec4 normal_roughness = texture(source_normal_roughness, uv_interp);
@@ -142,7 +140,6 @@ void main() {
float steps_taken = 0.0;
for (int i = 0; i < num_steps; i++) {
-
pos += line_advance;
z += z_advance;
w += w_advance;
@@ -174,7 +171,6 @@ void main() {
}
if (found) {
-
float margin_blend = 1.0;
vec2 margin = vec2((viewport_size.x + viewport_size.y) * 0.5 * 0.05); //make a uniform margin
@@ -218,7 +214,6 @@ void main() {
final_color = vec4(0.0);
for (int i = 0; i < 7; i++) {
-
float op_len = 2.0 * tan(cone_angle) * cone_len; //opposite side of iso triangle
float radius;
{
diff --git a/drivers/gles2/shaders/ssao.glsl b/drivers/gles2/shaders/ssao.glsl
index 82eea8f274..0fd29e8dcc 100644
--- a/drivers/gles2/shaders/ssao.glsl
+++ b/drivers/gles2/shaders/ssao.glsl
@@ -5,7 +5,6 @@ layout(location = 0) in highp vec4 vertex_attrib;
/* clang-format on */
void main() {
-
gl_Position = vertex_attrib;
gl_Position.z = 1.0;
}
@@ -207,7 +206,6 @@ float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius, in f
}
void main() {
-
// Pixel being shaded
ivec2 ssC = ivec2(gl_FragCoord.xy);
diff --git a/drivers/gles2/shaders/ssao_blur.glsl b/drivers/gles2/shaders/ssao_blur.glsl
index e4133ad534..f065cd74eb 100644
--- a/drivers/gles2/shaders/ssao_blur.glsl
+++ b/drivers/gles2/shaders/ssao_blur.glsl
@@ -5,7 +5,6 @@ layout(location = 0) in highp vec4 vertex_attrib;
/* clang-format on */
void main() {
-
gl_Position = vertex_attrib;
gl_Position.z = 1.0;
}
@@ -58,7 +57,6 @@ uniform float camera_z_near;
uniform ivec2 screen_size;
void main() {
-
ivec2 ssC = ivec2(gl_FragCoord.xy);
float depth = texelFetch(source_depth, ssC, 0).r;
@@ -91,7 +89,6 @@ void main() {
// We already handled the zero case above. This loop should be unrolled and the static branch optimized out,
// so the IF statement has no runtime cost
if (r != 0) {
-
ivec2 ppos = ssC + axis * (r * filter_scale);
float value = texelFetch(source_ssao, clamp(ppos, ivec2(0), clamp_limit), 0).r;
ivec2 rpos = clamp(ppos, ivec2(0), clamp_limit);
diff --git a/drivers/gles2/shaders/ssao_minify.glsl b/drivers/gles2/shaders/ssao_minify.glsl
index 272f3e236e..f654e00a4f 100644
--- a/drivers/gles2/shaders/ssao_minify.glsl
+++ b/drivers/gles2/shaders/ssao_minify.glsl
@@ -5,7 +5,6 @@ layout(location = 0) in highp vec4 vertex_attrib;
/* clang-format on */
void main() {
-
gl_Position = vertex_attrib;
}
@@ -33,7 +32,6 @@ uniform int source_mipmap;
layout(location = 0) out mediump uint depth;
void main() {
-
ivec2 ssP = ivec2(gl_FragCoord.xy);
// Rotated grid subsampling to avoid XY directional bias or Z precision bias while downsampling.
diff --git a/drivers/gles2/shaders/subsurf_scattering.glsl b/drivers/gles2/shaders/subsurf_scattering.glsl
index f40fb3a244..d0c34cf1b0 100644
--- a/drivers/gles2/shaders/subsurf_scattering.glsl
+++ b/drivers/gles2/shaders/subsurf_scattering.glsl
@@ -8,7 +8,6 @@ layout(location = 4) in vec2 uv_in;
out vec2 uv_interp;
void main() {
-
uv_interp = uv_in;
gl_Position = vertex_attrib;
}
@@ -102,7 +101,6 @@ uniform sampler2D source_depth; //texunit:2
layout(location = 0) out vec4 frag_color;
void main() {
-
float strength = texture(source_sss, uv_interp).r;
strength *= strength; //stored as sqrt
@@ -110,7 +108,6 @@ void main() {
vec4 base_color = texture(source_diffuse, uv_interp);
if (strength > 0.0) {
-
// Fetch linear depth of current pixel:
float depth = texture(source_depth, uv_interp).r * 2.0 - 1.0;
#ifdef USE_ORTHOGONAL_PROJECTION
diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp
index 4cb93a821c..8af58a7ed7 100644
--- a/drivers/png/image_loader_png.cpp
+++ b/drivers/png/image_loader_png.cpp
@@ -37,7 +37,6 @@
#include <string.h>
Error ImageLoaderPNG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
-
const size_t buffer_size = f->get_len();
Vector<uint8_t> file_buffer;
Error err = file_buffer.resize(buffer_size);
@@ -55,12 +54,10 @@ Error ImageLoaderPNG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
}
void ImageLoaderPNG::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("png");
}
Ref<Image> ImageLoaderPNG::load_mem_png(const uint8_t *p_png, int p_size) {
-
Ref<Image> img;
img.instance();
@@ -71,7 +68,6 @@ Ref<Image> ImageLoaderPNG::load_mem_png(const uint8_t *p_png, int p_size) {
}
Ref<Image> ImageLoaderPNG::lossless_unpack_png(const Vector<uint8_t> &p_data) {
-
const int len = p_data.size();
ERR_FAIL_COND_V(len < 4, Ref<Image>());
const uint8_t *r = p_data.ptr();
@@ -80,7 +76,6 @@ Ref<Image> ImageLoaderPNG::lossless_unpack_png(const Vector<uint8_t> &p_data) {
}
Vector<uint8_t> ImageLoaderPNG::lossless_pack_png(const Ref<Image> &p_image) {
-
Vector<uint8_t> out_buffer;
// add Godot's own "PNG " prefix
@@ -104,7 +99,6 @@ Vector<uint8_t> ImageLoaderPNG::lossless_pack_png(const Ref<Image> &p_image) {
}
ImageLoaderPNG::ImageLoaderPNG() {
-
Image::_png_mem_loader_func = load_mem_png;
Image::lossless_unpacker = lossless_unpack_png;
Image::lossless_packer = lossless_pack_png;
diff --git a/drivers/png/png_driver_common.cpp b/drivers/png/png_driver_common.cpp
index f17abcb54c..77d5e68826 100644
--- a/drivers/png/png_driver_common.cpp
+++ b/drivers/png/png_driver_common.cpp
@@ -59,7 +59,6 @@ static bool check_error(const png_image &image) {
}
Error png_to_image(const uint8_t *p_source, size_t p_size, Ref<Image> p_image) {
-
png_image png_img;
zeromem(&png_img, sizeof(png_img));
png_img.version = PNG_IMAGE_VERSION;
@@ -115,17 +114,17 @@ Error png_to_image(const uint8_t *p_source, size_t p_size, Ref<Image> p_image) {
ERR_FAIL_COND_V(!success, ERR_FILE_CORRUPT);
//print_line("png width: "+itos(png_img.width)+" height: "+itos(png_img.height));
- p_image->create(png_img.width, png_img.height, 0, dest_format, buffer);
+ p_image->create(png_img.width, png_img.height, false, dest_format, buffer);
return OK;
}
Error image_to_png(const Ref<Image> &p_image, Vector<uint8_t> &p_buffer) {
-
Ref<Image> source_image = p_image->duplicate();
- if (source_image->is_compressed())
+ if (source_image->is_compressed()) {
source_image->decompress();
+ }
ERR_FAIL_COND_V(source_image->is_compressed(), FAILED);
@@ -179,7 +178,6 @@ Error image_to_png(const Ref<Image> &p_image, Vector<uint8_t> &p_buffer) {
ERR_FAIL_COND_V_MSG(check_error(png_img), FAILED, png_img.message);
}
if (!success) {
-
// buffer was big enough, must be some other error
ERR_FAIL_COND_V(compressed_size <= png_size_estimate, FAILED);
diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp
index 2380c2685f..3a0b319a45 100644
--- a/drivers/png/resource_saver_png.cpp
+++ b/drivers/png/resource_saver_png.cpp
@@ -36,7 +36,6 @@
#include "scene/resources/texture.h"
Error ResourceSaverPNG::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
Ref<ImageTexture> texture = p_resource;
ERR_FAIL_COND_V_MSG(!texture.is_valid(), ERR_INVALID_PARAMETER, "Can't save invalid texture as PNG.");
@@ -50,7 +49,6 @@ Error ResourceSaverPNG::save(const String &p_path, const RES &p_resource, uint32
};
Error ResourceSaverPNG::save_image(const String &p_path, const Ref<Image> &p_img) {
-
Vector<uint8_t> buffer;
Error err = PNGDriverCommon::image_to_png(p_img, buffer);
ERR_FAIL_COND_V_MSG(err, err, "Can't convert image to PNG.");
@@ -72,7 +70,6 @@ Error ResourceSaverPNG::save_image(const String &p_path, const Ref<Image> &p_img
}
Vector<uint8_t> ResourceSaverPNG::save_image_to_buffer(const Ref<Image> &p_img) {
-
Vector<uint8_t> buffer;
Error err = PNGDriverCommon::image_to_png(p_img, buffer);
ERR_FAIL_COND_V_MSG(err, Vector<uint8_t>(), "Can't convert image to PNG.");
@@ -80,19 +77,16 @@ Vector<uint8_t> ResourceSaverPNG::save_image_to_buffer(const Ref<Image> &p_img)
}
bool ResourceSaverPNG::recognize(const RES &p_resource) const {
-
return (p_resource.is_valid() && p_resource->is_class("ImageTexture"));
}
void ResourceSaverPNG::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
-
if (Object::cast_to<ImageTexture>(*p_resource)) {
p_extensions->push_back("png");
}
}
ResourceSaverPNG::ResourceSaverPNG() {
-
Image::save_png_func = &save_image;
Image::save_png_buffer_func = &save_image_to_buffer;
};
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
index 8a47f6cf96..a6bc4f3b2c 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp
@@ -78,7 +78,6 @@ void AudioDriverPulseAudio::pa_source_info_cb(pa_context *c, const pa_source_inf
}
void AudioDriverPulseAudio::pa_server_info_cb(pa_context *c, const pa_server_info *i, void *userdata) {
-
ERR_FAIL_COND_MSG(!i, "PulseAudio server info is null.");
AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)userdata;
@@ -88,7 +87,6 @@ void AudioDriverPulseAudio::pa_server_info_cb(pa_context *c, const pa_server_inf
}
void AudioDriverPulseAudio::detect_channels(bool capture) {
-
pa_channel_map_init_stereo(capture ? &pa_rec_map : &pa_map);
String device = capture ? capture_device_name : device_name;
@@ -145,7 +143,6 @@ void AudioDriverPulseAudio::detect_channels(bool capture) {
}
Error AudioDriverPulseAudio::init_device() {
-
// If there is a specified device check that it is really present
if (device_name != "Default") {
Array list = get_device_list();
@@ -182,7 +179,7 @@ Error AudioDriverPulseAudio::init_device() {
break;
}
- int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ int latency = GLOBAL_GET("audio/output_latency");
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
pa_buffer_size = buffer_frames * pa_map.channels;
@@ -236,12 +233,11 @@ Error AudioDriverPulseAudio::init_device() {
}
Error AudioDriverPulseAudio::init() {
-
active = false;
thread_exited = false;
exit_thread = false;
- mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+ mix_rate = GLOBAL_GET("audio/mix_rate");
pa_ml = pa_mainloop_new();
ERR_FAIL_COND_V(pa_ml == nullptr, ERR_CANT_OPEN);
@@ -298,7 +294,6 @@ Error AudioDriverPulseAudio::init() {
}
float AudioDriverPulseAudio::get_latency() {
-
if (latency == 0) { //only do this once since it's approximate anyway
lock();
@@ -324,14 +319,12 @@ float AudioDriverPulseAudio::get_latency() {
}
void AudioDriverPulseAudio::thread_func(void *p_udata) {
-
AudioDriverPulseAudio *ad = (AudioDriverPulseAudio *)p_udata;
unsigned int write_ofs = 0;
size_t avail_bytes = 0;
uint32_t default_device_msec = OS::get_singleton()->get_ticks_msec();
while (!ad->exit_thread) {
-
size_t read_bytes = 0;
size_t written_bytes = 0;
@@ -421,7 +414,6 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
// If we're using the default device check that the current device is still the default
if (ad->device_name == "Default") {
-
uint32_t msec = OS::get_singleton()->get_ticks_msec();
if (msec > (default_device_msec + 1000)) {
String old_default_device = ad->default_device;
@@ -524,17 +516,14 @@ void AudioDriverPulseAudio::thread_func(void *p_udata) {
}
void AudioDriverPulseAudio::start() {
-
active = true;
}
int AudioDriverPulseAudio::get_mix_rate() const {
-
return mix_rate;
}
AudioDriver::SpeakerMode AudioDriverPulseAudio::get_speaker_mode() const {
-
return get_speaker_mode_by_total_channels(channels);
}
@@ -551,7 +540,6 @@ void AudioDriverPulseAudio::pa_sinklist_cb(pa_context *c, const pa_sink_info *l,
}
Array AudioDriverPulseAudio::get_device_list() {
-
pa_devices.clear();
pa_devices.push_back("Default");
@@ -583,33 +571,30 @@ Array AudioDriverPulseAudio::get_device_list() {
}
String AudioDriverPulseAudio::get_device() {
-
return device_name;
}
void AudioDriverPulseAudio::set_device(String device) {
-
lock();
new_device = device;
unlock();
}
void AudioDriverPulseAudio::lock() {
-
- if (!thread)
+ if (!thread) {
return;
+ }
mutex.lock();
}
void AudioDriverPulseAudio::unlock() {
-
- if (!thread)
+ if (!thread) {
return;
+ }
mutex.unlock();
}
void AudioDriverPulseAudio::finish_device() {
-
if (pa_str) {
pa_stream_disconnect(pa_str);
pa_stream_unref(pa_str);
@@ -618,9 +603,9 @@ void AudioDriverPulseAudio::finish_device() {
}
void AudioDriverPulseAudio::finish() {
-
- if (!thread)
+ if (!thread) {
return;
+ }
exit_thread = true;
Thread::wait_to_finish(thread);
@@ -644,7 +629,6 @@ void AudioDriverPulseAudio::finish() {
}
Error AudioDriverPulseAudio::capture_init_device() {
-
// If there is a specified device check that it is really present
if (capture_device_name != "Default") {
Array list = capture_get_device_list();
@@ -702,7 +686,6 @@ Error AudioDriverPulseAudio::capture_init_device() {
}
void AudioDriverPulseAudio::capture_finish_device() {
-
if (pa_rec_str) {
int ret = pa_stream_disconnect(pa_rec_str);
if (ret != 0) {
@@ -714,7 +697,6 @@ void AudioDriverPulseAudio::capture_finish_device() {
}
Error AudioDriverPulseAudio::capture_start() {
-
lock();
Error err = capture_init_device();
unlock();
@@ -731,7 +713,6 @@ Error AudioDriverPulseAudio::capture_stop() {
}
void AudioDriverPulseAudio::capture_set_device(const String &p_name) {
-
lock();
capture_new_device = p_name;
unlock();
@@ -753,7 +734,6 @@ void AudioDriverPulseAudio::pa_sourcelist_cb(pa_context *c, const pa_source_info
}
Array AudioDriverPulseAudio::capture_get_device_list() {
-
pa_rec_devices.clear();
pa_rec_devices.push_back("Default");
@@ -785,7 +765,6 @@ Array AudioDriverPulseAudio::capture_get_device_list() {
}
String AudioDriverPulseAudio::capture_get_device() {
-
lock();
String name = capture_device_name;
unlock();
@@ -793,30 +772,9 @@ String AudioDriverPulseAudio::capture_get_device() {
return name;
}
-AudioDriverPulseAudio::AudioDriverPulseAudio() :
- thread(nullptr),
- pa_ml(nullptr),
- pa_ctx(nullptr),
- pa_str(nullptr),
- pa_rec_str(nullptr),
- device_name("Default"),
- new_device("Default"),
- default_device(""),
- mix_rate(0),
- buffer_frames(0),
- pa_buffer_size(0),
- channels(0),
- pa_ready(0),
- pa_status(0),
- active(false),
- thread_exited(false),
- exit_thread(false),
- latency(0) {
+AudioDriverPulseAudio::AudioDriverPulseAudio() {
samples_in.clear();
samples_out.clear();
}
-AudioDriverPulseAudio::~AudioDriverPulseAudio() {
-}
-
-#endif
+#endif // PULSEAUDIO_ENABLED
diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.h b/drivers/pulseaudio/audio_driver_pulseaudio.h
index 1ece332a8a..2f2ad0fc38 100644
--- a/drivers/pulseaudio/audio_driver_pulseaudio.h
+++ b/drivers/pulseaudio/audio_driver_pulseaudio.h
@@ -40,19 +40,18 @@
#include <pulse/pulseaudio.h>
class AudioDriverPulseAudio : public AudioDriver {
-
- Thread *thread;
+ Thread *thread = nullptr;
Mutex mutex;
- pa_mainloop *pa_ml;
- pa_context *pa_ctx;
- pa_stream *pa_str;
- pa_stream *pa_rec_str;
+ pa_mainloop *pa_ml = nullptr;
+ pa_context *pa_ctx = nullptr;
+ pa_stream *pa_str = nullptr;
+ pa_stream *pa_rec_str = nullptr;
pa_channel_map pa_map;
pa_channel_map pa_rec_map;
- String device_name;
- String new_device;
+ String device_name = "Default";
+ String new_device = "Default";
String default_device;
String capture_device_name;
@@ -62,20 +61,20 @@ class AudioDriverPulseAudio : public AudioDriver {
Vector<int32_t> samples_in;
Vector<int16_t> samples_out;
- unsigned int mix_rate;
- unsigned int buffer_frames;
- unsigned int pa_buffer_size;
- int channels;
- int pa_ready;
- int pa_status;
+ unsigned int mix_rate = 0;
+ unsigned int buffer_frames = 0;
+ unsigned int pa_buffer_size = 0;
+ int channels = 0;
+ int pa_ready = 0;
+ int pa_status = 0;
Array pa_devices;
Array pa_rec_devices;
- bool active;
- bool thread_exited;
- mutable bool exit_thread;
+ bool active = false;
+ bool thread_exited = false;
+ mutable bool exit_thread = false;
- float latency;
+ float latency = 0;
static void pa_state_cb(pa_context *c, void *userdata);
static void pa_sink_info_cb(pa_context *c, const pa_sink_info *l, int eol, void *userdata);
@@ -122,7 +121,7 @@ public:
virtual Error capture_stop();
AudioDriverPulseAudio();
- ~AudioDriverPulseAudio();
+ ~AudioDriverPulseAudio() {}
};
#endif // AUDIO_DRIVER_PULSEAUDIO_H
diff --git a/drivers/register_driver_types.cpp b/drivers/register_driver_types.cpp
index dcc7a5c14d..f0deabec21 100644
--- a/drivers/register_driver_types.cpp
+++ b/drivers/register_driver_types.cpp
@@ -37,7 +37,6 @@ static ImageLoaderPNG *image_loader_png;
static Ref<ResourceSaverPNG> resource_saver_png;
void register_core_driver_types() {
-
image_loader_png = memnew(ImageLoaderPNG);
ImageLoader::add_image_format_loader(image_loader_png);
@@ -46,9 +45,9 @@ void register_core_driver_types() {
}
void unregister_core_driver_types() {
-
- if (image_loader_png)
+ if (image_loader_png) {
memdelete(image_loader_png);
+ }
ResourceSaver::remove_resource_format_saver(resource_saver_png);
resource_saver_png.unref();
diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp
index 00103684c7..325a88b573 100644
--- a/drivers/unix/dir_access_unix.cpp
+++ b/drivers/unix/dir_access_unix.cpp
@@ -50,12 +50,10 @@
#endif
DirAccess *DirAccessUnix::create_fs() {
-
return memnew(DirAccessUnix);
}
Error DirAccessUnix::list_dir_begin() {
-
list_dir_end(); //close any previous dir opening!
//char real_current_dir_name[2048]; //is this enough?!
@@ -63,18 +61,19 @@ Error DirAccessUnix::list_dir_begin() {
//chdir(current_path.utf8().get_data());
dir_stream = opendir(current_dir.utf8().get_data());
//chdir(real_current_dir_name);
- if (!dir_stream)
+ if (!dir_stream) {
return ERR_CANT_OPEN; //error!
+ }
return OK;
}
bool DirAccessUnix::file_exists(String p_file) {
-
GLOBAL_LOCK_FUNCTION
- if (p_file.is_rel_path())
+ if (p_file.is_rel_path()) {
p_file = current_dir.plus_file(p_file);
+ }
p_file = fix_path(p_file);
@@ -89,11 +88,11 @@ bool DirAccessUnix::file_exists(String p_file) {
}
bool DirAccessUnix::dir_exists(String p_dir) {
-
GLOBAL_LOCK_FUNCTION
- if (p_dir.is_rel_path())
+ if (p_dir.is_rel_path()) {
p_dir = get_current_dir().plus_file(p_dir);
+ }
p_dir = fix_path(p_dir);
@@ -104,9 +103,9 @@ bool DirAccessUnix::dir_exists(String p_dir) {
}
uint64_t DirAccessUnix::get_modified_time(String p_file) {
-
- if (p_file.is_rel_path())
+ if (p_file.is_rel_path()) {
p_file = current_dir.plus_file(p_file);
+ }
p_file = fix_path(p_file);
@@ -116,16 +115,15 @@ uint64_t DirAccessUnix::get_modified_time(String p_file) {
if (success) {
return flags.st_mtime;
} else {
-
ERR_FAIL_V(0);
};
return 0;
};
String DirAccessUnix::get_next() {
-
- if (!dir_stream)
+ if (!dir_stream) {
return "";
+ }
dirent *entry = readdir(dir_stream);
@@ -160,19 +158,17 @@ String DirAccessUnix::get_next() {
}
bool DirAccessUnix::current_is_dir() const {
-
return _cisdir;
}
bool DirAccessUnix::current_is_hidden() const {
-
return _cishidden;
}
void DirAccessUnix::list_dir_end() {
-
- if (dir_stream)
+ if (dir_stream) {
closedir(dir_stream);
+ }
dir_stream = nullptr;
_cisdir = false;
}
@@ -198,7 +194,6 @@ static bool _filter_drive(struct mntent *mnt) {
#endif
static void _get_drives(List<String> *list) {
-
#if defined(HAVE_MNTENT) && defined(X11_ENABLED)
// Check /etc/mtab for the list of mounted partitions
FILE *mtab = setmntent("/etc/mtab", "r");
@@ -252,7 +247,6 @@ static void _get_drives(List<String> *list) {
}
int DirAccessUnix::get_drive_count() {
-
List<String> list;
_get_drives(&list);
@@ -260,7 +254,6 @@ int DirAccessUnix::get_drive_count() {
}
String DirAccessUnix::get_drive(int p_drive) {
-
List<String> list;
_get_drives(&list);
@@ -270,16 +263,15 @@ String DirAccessUnix::get_drive(int p_drive) {
}
bool DirAccessUnix::drives_are_shortcuts() {
-
return true;
}
Error DirAccessUnix::make_dir(String p_dir) {
-
GLOBAL_LOCK_FUNCTION
- if (p_dir.is_rel_path())
+ if (p_dir.is_rel_path()) {
p_dir = get_current_dir().plus_file(p_dir);
+ }
p_dir = fix_path(p_dir);
@@ -298,7 +290,6 @@ Error DirAccessUnix::make_dir(String p_dir) {
}
Error DirAccessUnix::change_dir(String p_dir) {
-
GLOBAL_LOCK_FUNCTION
p_dir = fix_path(p_dir);
@@ -307,8 +298,9 @@ Error DirAccessUnix::change_dir(String p_dir) {
String prev_dir;
char real_current_dir_name[2048];
ERR_FAIL_COND_V(getcwd(real_current_dir_name, 2048) == nullptr, ERR_BUG);
- if (prev_dir.parse_utf8(real_current_dir_name))
+ if (prev_dir.parse_utf8(real_current_dir_name)) {
prev_dir = real_current_dir_name; //no utf8, maybe latin?
+ }
// try_dir is the directory we are trying to change into
String try_dir = "";
@@ -343,28 +335,28 @@ Error DirAccessUnix::change_dir(String p_dir) {
}
String DirAccessUnix::get_current_dir(bool p_include_drive) {
-
String base = _get_root_path();
if (base != "") {
-
String bd = current_dir.replace_first(base, "");
- if (bd.begins_with("/"))
+ if (bd.begins_with("/")) {
return _get_root_string() + bd.substr(1, bd.length());
- else
+ } else {
return _get_root_string() + bd;
+ }
}
return current_dir;
}
Error DirAccessUnix::rename(String p_path, String p_new_path) {
-
- if (p_path.is_rel_path())
+ if (p_path.is_rel_path()) {
p_path = get_current_dir().plus_file(p_path);
+ }
p_path = fix_path(p_path);
- if (p_new_path.is_rel_path())
+ if (p_new_path.is_rel_path()) {
p_new_path = get_current_dir().plus_file(p_new_path);
+ }
p_new_path = fix_path(p_new_path);
@@ -372,28 +364,28 @@ Error DirAccessUnix::rename(String p_path, String p_new_path) {
}
Error DirAccessUnix::remove(String p_path) {
-
- if (p_path.is_rel_path())
+ if (p_path.is_rel_path()) {
p_path = get_current_dir().plus_file(p_path);
+ }
p_path = fix_path(p_path);
struct stat flags;
- if ((stat(p_path.utf8().get_data(), &flags) != 0))
+ if ((stat(p_path.utf8().get_data(), &flags) != 0)) {
return FAILED;
+ }
- if (S_ISDIR(flags.st_mode))
+ if (S_ISDIR(flags.st_mode)) {
return ::rmdir(p_path.utf8().get_data()) == 0 ? OK : FAILED;
- else
+ } else {
return ::unlink(p_path.utf8().get_data()) == 0 ? OK : FAILED;
+ }
}
size_t DirAccessUnix::get_space_left() {
-
#ifndef NO_STATVFS
struct statvfs vfs;
if (statvfs(current_dir.utf8().get_data(), &vfs) != 0) {
-
return 0;
};
@@ -409,7 +401,6 @@ String DirAccessUnix::get_filesystem_type() const {
}
DirAccessUnix::DirAccessUnix() {
-
dir_stream = nullptr;
_cisdir = false;
@@ -418,14 +409,14 @@ DirAccessUnix::DirAccessUnix() {
// set current directory to an absolute path of the current directory
char real_current_dir_name[2048];
ERR_FAIL_COND(getcwd(real_current_dir_name, 2048) == nullptr);
- if (current_dir.parse_utf8(real_current_dir_name))
+ if (current_dir.parse_utf8(real_current_dir_name)) {
current_dir = real_current_dir_name;
+ }
change_dir(current_dir);
}
DirAccessUnix::~DirAccessUnix() {
-
list_dir_end();
}
diff --git a/drivers/unix/dir_access_unix.h b/drivers/unix/dir_access_unix.h
index b403d8e356..b897efcafc 100644
--- a/drivers/unix/dir_access_unix.h
+++ b/drivers/unix/dir_access_unix.h
@@ -41,7 +41,6 @@
#include <unistd.h>
class DirAccessUnix : public DirAccess {
-
DIR *dir_stream;
static DirAccess *create_fs();
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index 4aa408a1f0..06bad9f385 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -63,19 +63,17 @@
#endif
void FileAccessUnix::check_errors() const {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
if (feof(f)) {
-
last_error = ERR_FILE_EOF;
}
}
Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
-
- if (f)
+ if (f) {
fclose(f);
+ }
f = nullptr;
path_src = p_path;
@@ -85,16 +83,17 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
ERR_FAIL_COND_V_MSG(f, ERR_ALREADY_IN_USE, "File is already in use.");
const char *mode_string;
- if (p_mode_flags == READ)
+ if (p_mode_flags == READ) {
mode_string = "rb";
- else if (p_mode_flags == WRITE)
+ } else if (p_mode_flags == WRITE) {
mode_string = "wb";
- else if (p_mode_flags == READ_WRITE)
+ } else if (p_mode_flags == READ_WRITE) {
mode_string = "rb+";
- else if (p_mode_flags == WRITE_READ)
+ } else if (p_mode_flags == WRITE_READ) {
mode_string = "wb+";
- else
+ } else {
return ERR_INVALID_PARAMETER;
+ }
/* pretty much every implementation that uses fopen as primary
backend (unix-compatible mostly) supports utf8 encoding */
@@ -150,9 +149,9 @@ Error FileAccessUnix::_open(const String &p_path, int p_mode_flags) {
}
void FileAccessUnix::close() {
-
- if (!f)
+ if (!f) {
return;
+ }
fclose(f);
f = nullptr;
@@ -174,39 +173,35 @@ void FileAccessUnix::close() {
}
bool FileAccessUnix::is_open() const {
-
return (f != nullptr);
}
String FileAccessUnix::get_path() const {
-
return path_src;
}
String FileAccessUnix::get_path_absolute() const {
-
return path;
}
void FileAccessUnix::seek(size_t p_position) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
last_error = OK;
- if (fseek(f, p_position, SEEK_SET))
+ if (fseek(f, p_position, SEEK_SET)) {
check_errors();
+ }
}
void FileAccessUnix::seek_end(int64_t p_position) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
- if (fseek(f, p_position, SEEK_END))
+ if (fseek(f, p_position, SEEK_END)) {
check_errors();
+ }
}
size_t FileAccessUnix::get_position() const {
-
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
long pos = ftell(f);
@@ -218,7 +213,6 @@ size_t FileAccessUnix::get_position() const {
}
size_t FileAccessUnix::get_len() const {
-
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
long pos = ftell(f);
@@ -232,12 +226,10 @@ size_t FileAccessUnix::get_len() const {
}
bool FileAccessUnix::eof_reached() const {
-
return last_error == ERR_FILE_EOF;
}
uint8_t FileAccessUnix::get_8() const {
-
ERR_FAIL_COND_V_MSG(!f, 0, "File must be opened before use.");
uint8_t b;
if (fread(&b, 1, 1, f) == 0) {
@@ -248,7 +240,6 @@ uint8_t FileAccessUnix::get_8() const {
}
int FileAccessUnix::get_buffer(uint8_t *p_dst, int p_length) const {
-
ERR_FAIL_COND_V_MSG(!f, -1, "File must be opened before use.");
int read = fread(p_dst, 1, p_length, f);
check_errors();
@@ -256,44 +247,41 @@ int FileAccessUnix::get_buffer(uint8_t *p_dst, int p_length) const {
};
Error FileAccessUnix::get_error() const {
-
return last_error;
}
void FileAccessUnix::flush() {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
fflush(f);
}
void FileAccessUnix::store_8(uint8_t p_dest) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
ERR_FAIL_COND(fwrite(&p_dest, 1, 1, f) != 1);
}
void FileAccessUnix::store_buffer(const uint8_t *p_src, int p_length) {
-
ERR_FAIL_COND_MSG(!f, "File must be opened before use.");
ERR_FAIL_COND(!p_src);
ERR_FAIL_COND((int)fwrite(p_src, 1, p_length, f) != p_length);
}
bool FileAccessUnix::file_exists(const String &p_path) {
-
int err;
struct stat st;
String filename = fix_path(p_path);
// Does the name exist at all?
err = stat(filename.utf8().get_data(), &st);
- if (err)
+ if (err) {
return false;
+ }
#ifdef UNIX_ENABLED
// See if we have access to the file
- if (access(filename.utf8().get_data(), F_OK))
+ if (access(filename.utf8().get_data(), F_OK)) {
return false;
+ }
#else
if (_access(filename.utf8().get_data(), 4) == -1)
return false;
@@ -310,7 +298,6 @@ bool FileAccessUnix::file_exists(const String &p_path) {
}
uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
-
String file = fix_path(p_file);
struct stat flags;
int err = stat(file.utf8().get_data(), &flags);
@@ -323,7 +310,6 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
}
uint32_t FileAccessUnix::_get_unix_permissions(const String &p_file) {
-
String file = fix_path(p_file);
struct stat flags;
int err = stat(file.utf8().get_data(), &flags);
@@ -336,7 +322,6 @@ uint32_t FileAccessUnix::_get_unix_permissions(const String &p_file) {
}
Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_permissions) {
-
String file = fix_path(p_file);
int err = chmod(file.utf8().get_data(), p_permissions);
@@ -348,20 +333,12 @@ Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_per
}
FileAccess *FileAccessUnix::create_libc() {
-
return memnew(FileAccessUnix);
}
CloseNotificationFunc FileAccessUnix::close_notification_func = nullptr;
-FileAccessUnix::FileAccessUnix() :
- f(nullptr),
- flags(0),
- last_error(OK) {
-}
-
FileAccessUnix::~FileAccessUnix() {
-
close();
}
diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h
index 8116f72345..9fe43a2554 100644
--- a/drivers/unix/file_access_unix.h
+++ b/drivers/unix/file_access_unix.h
@@ -41,11 +41,10 @@
typedef void (*CloseNotificationFunc)(const String &p_file, int p_flags);
class FileAccessUnix : public FileAccess {
-
- FILE *f;
- int flags;
+ FILE *f = nullptr;
+ int flags = 0;
void check_errors() const;
- mutable Error last_error;
+ mutable Error last_error = OK;
String save_path;
String path;
String path_src;
@@ -84,7 +83,7 @@ public:
virtual uint32_t _get_unix_permissions(const String &p_file);
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
- FileAccessUnix();
+ FileAccessUnix() {}
virtual ~FileAccessUnix();
};
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index 5e3dedfc2f..05eedccc1d 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -76,7 +76,6 @@
#endif
static IP_Address _sockaddr2ip(struct sockaddr *p_addr) {
-
IP_Address ip;
if (p_addr->sa_family == AF_INET) {
@@ -91,7 +90,6 @@ static IP_Address _sockaddr2ip(struct sockaddr *p_addr) {
};
IP_Address IP_Unix::_resolve_hostname(const String &p_hostname, Type p_type) {
-
struct addrinfo hints;
struct addrinfo *result;
@@ -115,8 +113,9 @@ IP_Address IP_Unix::_resolve_hostname(const String &p_hostname, Type p_type) {
if (result == nullptr || result->ai_addr == nullptr) {
ERR_PRINT("Invalid response from getaddrinfo");
- if (result)
+ if (result) {
freeaddrinfo(result);
+ }
return IP_Address();
};
@@ -132,7 +131,6 @@ IP_Address IP_Unix::_resolve_hostname(const String &p_hostname, Type p_type) {
#if defined(UWP_ENABLED)
void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const {
-
using namespace Windows::Networking;
using namespace Windows::Networking::Connectivity;
@@ -140,7 +138,6 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
auto hostnames = NetworkInformation::GetHostNames();
for (int i = 0; i < hostnames->Size; i++) {
-
auto hostname = hostnames->GetAt(i);
if (hostname->Type != HostNameType::Ipv4 && hostname->Type != HostNameType::Ipv6)
@@ -167,12 +164,10 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
#else
void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const {
-
ULONG buf_size = 1024;
IP_ADAPTER_ADDRESSES *addrs;
while (true) {
-
addrs = (IP_ADAPTER_ADDRESSES *)memalloc(buf_size);
int err = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME,
nullptr, addrs, &buf_size);
@@ -190,7 +185,6 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
IP_ADAPTER_ADDRESSES *adapter = addrs;
while (adapter != nullptr) {
-
Interface_Info info;
info.name = adapter->AdapterName;
info.name_friendly = adapter->FriendlyName;
@@ -218,7 +212,6 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
#else // UNIX
void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) const {
-
struct ifaddrs *ifAddrStruct = nullptr;
struct ifaddrs *ifa = nullptr;
int family;
@@ -226,13 +219,15 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
getifaddrs(&ifAddrStruct);
for (ifa = ifAddrStruct; ifa != nullptr; ifa = ifa->ifa_next) {
- if (!ifa->ifa_addr)
+ if (!ifa->ifa_addr) {
continue;
+ }
family = ifa->ifa_addr->sa_family;
- if (family != AF_INET && family != AF_INET6)
+ if (family != AF_INET && family != AF_INET6) {
continue;
+ }
Map<String, Interface_Info>::Element *E = r_interfaces->find(ifa->ifa_name);
if (!E) {
@@ -248,17 +243,17 @@ void IP_Unix::get_local_interfaces(Map<String, Interface_Info> *r_interfaces) co
info.ip_addresses.push_front(_sockaddr2ip(ifa->ifa_addr));
}
- if (ifAddrStruct != nullptr) freeifaddrs(ifAddrStruct);
+ if (ifAddrStruct != nullptr) {
+ freeifaddrs(ifAddrStruct);
+ }
}
#endif
void IP_Unix::make_default() {
-
_create = _create_unix;
}
IP *IP_Unix::_create_unix() {
-
return memnew(IP_Unix);
}
diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp
index 7c6543c3a2..15ad187ab4 100644
--- a/drivers/unix/net_socket_posix.cpp
+++ b/drivers/unix/net_socket_posix.cpp
@@ -96,7 +96,6 @@
#endif
size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const IP_Address &p_ip, uint16_t p_port, IP::Type p_ip_type) {
-
memset(p_addr, 0, sizeof(struct sockaddr_storage));
if (p_ip_type == IP::TYPE_IPV6 || p_ip_type == IP::TYPE_ANY) { // IPv6 socket
@@ -132,16 +131,13 @@ size_t NetSocketPosix::_set_addr_storage(struct sockaddr_storage *p_addr, const
}
void NetSocketPosix::_set_ip_port(struct sockaddr_storage *p_addr, IP_Address &r_ip, uint16_t &r_port) {
-
if (p_addr->ss_family == AF_INET) {
-
struct sockaddr_in *addr4 = (struct sockaddr_in *)p_addr;
r_ip.set_ipv4((uint8_t *)&(addr4->sin_addr.s_addr));
r_port = ntohs(addr4->sin_port);
} else if (p_addr->ss_family == AF_INET6) {
-
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr;
r_ip.set_ipv6(addr6->sin6_addr.s6_addr);
@@ -173,9 +169,7 @@ void NetSocketPosix::cleanup() {
}
NetSocketPosix::NetSocketPosix() :
- _sock(SOCK_EMPTY),
- _ip_type(IP::TYPE_NONE),
- _is_stream(false) {
+ _sock(SOCK_EMPTY) {
}
NetSocketPosix::~NetSocketPosix() {
@@ -202,12 +196,15 @@ NetSocketPosix::NetError NetSocketPosix::_get_socket_error() const {
print_verbose("Socket error: " + itos(err));
return ERR_NET_OTHER;
#else
- if (errno == EISCONN)
+ if (errno == EISCONN) {
return ERR_NET_IS_CONNECTED;
- if (errno == EINPROGRESS || errno == EALREADY)
+ }
+ if (errno == EINPROGRESS || errno == EALREADY) {
return ERR_NET_IN_PROGRESS;
- if (errno == EAGAIN || errno == EWOULDBLOCK)
+ }
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
return ERR_NET_WOULD_BLOCK;
+ }
print_verbose("Socket error: " + itos(errno));
return ERR_NET_OTHER;
#endif
@@ -218,7 +215,6 @@ NetSocketPosix::NetError NetSocketPosix::_get_socket_error() const {
#endif
bool NetSocketPosix::_can_use_ip(const IP_Address &p_ip, const bool p_for_bind) const {
-
if (p_for_bind && !(p_ip.is_valid() || p_ip.is_wildcard())) {
return false;
} else if (!p_for_bind && !p_ip.is_valid()) {
@@ -230,7 +226,6 @@ bool NetSocketPosix::_can_use_ip(const IP_Address &p_ip, const bool p_for_bind)
}
_FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IP_Address p_ip, String p_if_name, bool p_add) {
-
ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!_can_use_ip(p_ip, false), ERR_INVALID_PARAMETER);
@@ -246,16 +241,19 @@ _FORCE_INLINE_ Error NetSocketPosix::_change_multicast_group(IP_Address p_ip, St
IP::get_singleton()->get_local_interfaces(&if_info);
for (Map<String, IP::Interface_Info>::Element *E = if_info.front(); E; E = E->next()) {
IP::Interface_Info &c = E->get();
- if (c.name != p_if_name)
+ if (c.name != p_if_name) {
continue;
+ }
if_v6id = (uint32_t)c.index.to_int64();
- if (type == IP::TYPE_IPV6)
+ if (type == IP::TYPE_IPV6) {
break; // IPv6 uses index.
+ }
for (List<IP_Address>::Element *F = c.ip_addresses.front(); F; F = F->next()) {
- if (!F->get().is_ipv4())
+ if (!F->get().is_ipv4()) {
continue; // Wrong IP type
+ }
if_ip = F->get();
break;
}
@@ -369,9 +367,9 @@ Error NetSocketPosix::open(Type p_sock_type, IP::Type &ip_type) {
}
void NetSocketPosix::close() {
-
- if (_sock != SOCK_EMPTY)
+ if (_sock != SOCK_EMPTY) {
SOCK_CLOSE(_sock);
+ }
_sock = SOCK_EMPTY;
_ip_type = IP::TYPE_NONE;
@@ -379,7 +377,6 @@ void NetSocketPosix::close() {
}
Error NetSocketPosix::bind(IP_Address p_addr, uint16_t p_port) {
-
ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!_can_use_ip(p_addr, true), ERR_INVALID_PARAMETER);
@@ -410,7 +407,6 @@ Error NetSocketPosix::listen(int p_max_pending) {
}
Error NetSocketPosix::connect_to_host(IP_Address p_host, uint16_t p_port) {
-
ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V(!_can_use_ip(p_host, false), ERR_INVALID_PARAMETER);
@@ -418,7 +414,6 @@ Error NetSocketPosix::connect_to_host(IP_Address p_host, uint16_t p_port) {
size_t addr_size = _set_addr_storage(&addr, p_host, p_port, _ip_type);
if (SOCK_CONNECT(_sock, (struct sockaddr *)&addr, addr_size) != 0) {
-
NetError err = _get_socket_error();
switch (err) {
@@ -440,7 +435,6 @@ Error NetSocketPosix::connect_to_host(IP_Address p_host, uint16_t p_port) {
}
Error NetSocketPosix::poll(PollType p_type, int p_timeout) const {
-
ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED);
#if defined(WINDOWS_ENABLED)
@@ -521,8 +515,9 @@ Error NetSocketPosix::poll(PollType p_type, int p_timeout) const {
return FAILED;
}
- if (ret == 0)
+ if (ret == 0) {
return ERR_BUSY;
+ }
return OK;
#endif
@@ -535,8 +530,9 @@ Error NetSocketPosix::recv(uint8_t *p_buffer, int p_len, int &r_read) {
if (r_read < 0) {
NetError err = _get_socket_error();
- if (err == ERR_NET_WOULD_BLOCK)
+ if (err == ERR_NET_WOULD_BLOCK) {
return ERR_BUSY;
+ }
return FAILED;
}
@@ -555,8 +551,9 @@ Error NetSocketPosix::recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Add
if (r_read < 0) {
NetError err = _get_socket_error();
- if (err == ERR_NET_WOULD_BLOCK)
+ if (err == ERR_NET_WOULD_BLOCK) {
return ERR_BUSY;
+ }
return FAILED;
}
@@ -582,15 +579,17 @@ Error NetSocketPosix::send(const uint8_t *p_buffer, int p_len, int &r_sent) {
int flags = 0;
#ifdef MSG_NOSIGNAL
- if (_is_stream)
+ if (_is_stream) {
flags = MSG_NOSIGNAL;
+ }
#endif
r_sent = ::send(_sock, SOCK_CBUF(p_buffer), p_len, flags);
if (r_sent < 0) {
NetError err = _get_socket_error();
- if (err == ERR_NET_WOULD_BLOCK)
+ if (err == ERR_NET_WOULD_BLOCK) {
return ERR_BUSY;
+ }
return FAILED;
}
@@ -607,8 +606,9 @@ Error NetSocketPosix::sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP
if (r_sent < 0) {
NetError err = _get_socket_error();
- if (err == ERR_NET_WOULD_BLOCK)
+ if (err == ERR_NET_WOULD_BLOCK) {
return ERR_BUSY;
+ }
return FAILED;
}
@@ -619,8 +619,9 @@ Error NetSocketPosix::sendto(const uint8_t *p_buffer, int p_len, int &r_sent, IP
Error NetSocketPosix::set_broadcasting_enabled(bool p_enabled) {
ERR_FAIL_COND_V(!is_open(), ERR_UNCONFIGURED);
// IPv6 has no broadcast support.
- if (_ip_type == IP::TYPE_IPV6)
+ if (_ip_type == IP::TYPE_IPV6) {
return ERR_UNAVAILABLE;
+ }
int par = p_enabled ? 1 : 0;
if (setsockopt(_sock, SOL_SOCKET, SO_BROADCAST, SOCK_CBUF(&par), sizeof(int)) != 0) {
@@ -639,14 +640,16 @@ void NetSocketPosix::set_blocking_enabled(bool p_enabled) {
ret = SOCK_IOCTL(_sock, FIONBIO, &par);
#else
int opts = fcntl(_sock, F_GETFL);
- if (p_enabled)
+ if (p_enabled) {
ret = fcntl(_sock, F_SETFL, opts & ~O_NONBLOCK);
- else
+ } else {
ret = fcntl(_sock, F_SETFL, opts | O_NONBLOCK);
+ }
#endif
- if (ret != 0)
+ if (ret != 0) {
WARN_PRINT("Unable to change non-block mode");
+ }
}
void NetSocketPosix::set_ipv6_only_enabled(bool p_enabled) {
@@ -701,7 +704,6 @@ bool NetSocketPosix::is_open() const {
}
int NetSocketPosix::get_available_bytes() const {
-
ERR_FAIL_COND_V(!is_open(), -1);
unsigned long len;
@@ -715,7 +717,6 @@ int NetSocketPosix::get_available_bytes() const {
}
Ref<NetSocket> NetSocketPosix::accept(IP_Address &r_ip, uint16_t &r_port) {
-
Ref<NetSocket> out;
ERR_FAIL_COND_V(!is_open(), out);
diff --git a/drivers/unix/net_socket_posix.h b/drivers/unix/net_socket_posix.h
index 0a19967265..8cefb6544e 100644
--- a/drivers/unix/net_socket_posix.h
+++ b/drivers/unix/net_socket_posix.h
@@ -45,11 +45,10 @@
#endif
class NetSocketPosix : public NetSocket {
-
private:
- SOCKET_TYPE _sock;
- IP::Type _ip_type;
- bool _is_stream;
+ SOCKET_TYPE _sock; // NOLINT - the default value is defined in the .cpp
+ IP::Type _ip_type = IP::TYPE_NONE;
+ bool _is_stream = false;
enum NetError {
ERR_NET_WOULD_BLOCK,
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 53c60951b7..083cd64116 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -91,20 +91,19 @@ static void _setup_clock() {
#endif
void OS_Unix::debug_break() {
-
assert(false);
};
static void handle_interrupt(int sig) {
- if (!EngineDebugger::is_active())
+ if (!EngineDebugger::is_active()) {
return;
+ }
EngineDebugger::get_script_debugger()->set_depth(-1);
EngineDebugger::get_script_debugger()->set_lines_left(1);
}
void OS_Unix::initialize_debugging() {
-
if (EngineDebugger::is_active()) {
struct sigaction action;
memset(&action, 0, sizeof(action));
@@ -114,12 +113,10 @@ void OS_Unix::initialize_debugging() {
}
int OS_Unix::unix_initialize_audio(int p_audio_driver) {
-
return 0;
}
void OS_Unix::initialize_core() {
-
#ifdef NO_THREADS
ThreadDummy::make_default();
RWLockDummy::make_default();
@@ -144,17 +141,14 @@ void OS_Unix::initialize_core() {
}
void OS_Unix::finalize_core() {
-
NetSocketPosix::cleanup();
}
void OS_Unix::alert(const String &p_alert, const String &p_title) {
-
fprintf(stderr, "ERROR: %s\n", p_alert.utf8().get_data());
}
String OS_Unix::get_stdin_string(bool p_block) {
-
if (p_block) {
char buff[1024];
String ret = stdin_buf + fgets(buff, 1024, stdin);
@@ -166,12 +160,10 @@ String OS_Unix::get_stdin_string(bool p_block) {
}
String OS_Unix::get_name() const {
-
return "Unix";
}
uint64_t OS_Unix::get_unix_time() const {
-
return time(nullptr);
};
@@ -188,13 +180,13 @@ uint64_t OS_Unix::get_system_time_msecs() const {
}
OS::Date OS_Unix::get_date(bool utc) const {
-
time_t t = time(nullptr);
struct tm *lt;
- if (utc)
+ if (utc) {
lt = gmtime(&t);
- else
+ } else {
lt = localtime(&t);
+ }
Date ret;
ret.year = 1900 + lt->tm_year;
// Index starting at 1 to match OS_Unix::get_date
@@ -211,10 +203,11 @@ OS::Date OS_Unix::get_date(bool utc) const {
OS::Time OS_Unix::get_time(bool utc) const {
time_t t = time(nullptr);
struct tm *lt;
- if (utc)
+ if (utc) {
lt = gmtime(&t);
- else
+ } else {
lt = localtime(&t);
+ }
Time ret;
ret.hour = lt->tm_hour;
ret.min = lt->tm_min;
@@ -241,22 +234,22 @@ OS::TimeZoneInfo OS_Unix::get_time_zone_info() const {
// convert from ISO 8601 (1 minute=1, 1 hour=100) to minutes
int hour = (int)bias / 100;
int minutes = bias % 100;
- if (bias < 0)
+ if (bias < 0) {
ret.bias = hour * 60 - minutes;
- else
+ } else {
ret.bias = hour * 60 + minutes;
+ }
return ret;
}
void OS_Unix::delay_usec(uint32_t p_usec) const {
-
struct timespec rem = { static_cast<time_t>(p_usec / 1000000), (static_cast<long>(p_usec) % 1000000) * 1000 };
while (nanosleep(&rem, &rem) == EINTR) {
}
}
-uint64_t OS_Unix::get_ticks_usec() const {
+uint64_t OS_Unix::get_ticks_usec() const {
#if defined(__APPLE__)
uint64_t longtime = mach_absolute_time() * _clock_scale;
#else
@@ -272,19 +265,16 @@ uint64_t OS_Unix::get_ticks_usec() const {
}
Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
-
#ifdef __EMSCRIPTEN__
// Don't compile this code at all to avoid undefined references.
// Actual virtual call goes to OS_JavaScript.
ERR_FAIL_V(ERR_BUG);
#else
if (p_blocking && r_pipe) {
-
String argss;
argss = "\"" + p_path + "\"";
for (int i = 0; i < p_arguments.size(); i++) {
-
argss += String(" \"") + p_arguments[i] + "\"";
}
@@ -300,7 +290,6 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
char buf[65535];
while (fgets(buf, 65535, f)) {
-
if (p_pipe_mutex) {
p_pipe_mutex->lock();
}
@@ -310,8 +299,9 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
}
}
int rv = pclose(f);
- if (r_exitcode)
+ if (r_exitcode) {
*r_exitcode = WEXITSTATUS(rv);
+ }
return OK;
}
@@ -330,12 +320,14 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
Vector<CharString> cs;
cs.push_back(p_path.utf8());
- for (int i = 0; i < p_arguments.size(); i++)
+ for (int i = 0; i < p_arguments.size(); i++) {
cs.push_back(p_arguments[i].utf8());
+ }
Vector<char *> args;
- for (int i = 0; i < cs.size(); i++)
+ for (int i = 0; i < cs.size(); i++) {
args.push_back((char *)cs[i].get_data());
+ }
args.push_back(0);
execvp(p_path.utf8().get_data(), &args[0]);
@@ -345,16 +337,16 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
}
if (p_blocking) {
-
int status;
waitpid(pid, &status, 0);
- if (r_exitcode)
+ if (r_exitcode) {
*r_exitcode = WEXITSTATUS(status);
+ }
} else {
-
- if (r_child_id)
+ if (r_child_id) {
*r_child_id = pid;
+ }
}
return OK;
@@ -362,7 +354,6 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
}
Error OS_Unix::kill(const ProcessID &p_pid) {
-
int ret = ::kill(p_pid, SIGKILL);
if (!ret) {
//avoid zombie process
@@ -373,29 +364,27 @@ Error OS_Unix::kill(const ProcessID &p_pid) {
}
int OS_Unix::get_process_id() const {
-
return getpid();
};
bool OS_Unix::has_environment(const String &p_var) const {
-
return getenv(p_var.utf8().get_data()) != nullptr;
}
String OS_Unix::get_locale() const {
-
- if (!has_environment("LANG"))
+ if (!has_environment("LANG")) {
return "en";
+ }
String locale = get_environment("LANG");
int tp = locale.find(".");
- if (tp != -1)
+ if (tp != -1) {
locale = locale.substr(0, tp);
+ }
return locale;
}
Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
-
String path = p_path;
if (FileAccess::exists(path) && path.is_rel_path()) {
@@ -442,32 +431,29 @@ Error OS_Unix::get_dynamic_library_symbol_handle(void *p_library_handle, const S
}
Error OS_Unix::set_cwd(const String &p_cwd) {
-
- if (chdir(p_cwd.utf8().get_data()) != 0)
+ if (chdir(p_cwd.utf8().get_data()) != 0) {
return ERR_CANT_OPEN;
+ }
return OK;
}
String OS_Unix::get_environment(const String &p_var) const {
-
- if (getenv(p_var.utf8().get_data()))
+ if (getenv(p_var.utf8().get_data())) {
return getenv(p_var.utf8().get_data());
+ }
return "";
}
bool OS_Unix::set_environment(const String &p_var, const String &p_value) const {
-
return setenv(p_var.utf8().get_data(), p_value.utf8().get_data(), /* overwrite: */ true) == 0;
}
int OS_Unix::get_processor_count() const {
-
return sysconf(_SC_NPROCESSORS_CONF);
}
String OS_Unix::get_user_data_dir() const {
-
String appname = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name"));
if (appname != "") {
bool use_custom_dir = ProjectSettings::get_singleton()->get("application/config/use_custom_user_dir");
@@ -486,7 +472,6 @@ String OS_Unix::get_user_data_dir() const {
}
String OS_Unix::get_executable_path() const {
-
#ifdef __linux__
//fix for running from a symlink
char buf[256];
@@ -544,10 +529,11 @@ void UnixTerminalLogger::log_error(const char *p_function, const char *p_file, i
}
const char *err_details;
- if (p_rationale && p_rationale[0])
+ if (p_rationale && p_rationale[0]) {
err_details = p_rationale;
- else
+ } else {
err_details = p_code;
+ }
// Disable color codes if stdout is not a TTY.
// This prevents Godot from writing ANSI escape codes when redirecting
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index 90679ddf1d..7d235803dc 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -37,7 +37,6 @@
#include "drivers/unix/ip_unix.h"
class OS_Unix : public OS {
-
protected:
// UNIX only handles the core functions.
// inheriting platforms under unix (eg. X11) should handle the rest
diff --git a/drivers/unix/rw_lock_posix.cpp b/drivers/unix/rw_lock_posix.cpp
index f219a0905c..50b74e84f7 100644
--- a/drivers/unix/rw_lock_posix.cpp
+++ b/drivers/unix/rw_lock_posix.cpp
@@ -37,7 +37,6 @@
#include <stdio.h>
void RWLockPosix::read_lock() {
-
int err = pthread_rwlock_rdlock(&rwlock);
if (err != 0) {
perror("Acquiring lock failed");
@@ -46,12 +45,10 @@ void RWLockPosix::read_lock() {
}
void RWLockPosix::read_unlock() {
-
pthread_rwlock_unlock(&rwlock);
}
Error RWLockPosix::read_try_lock() {
-
if (pthread_rwlock_tryrdlock(&rwlock) != 0) {
return ERR_BUSY;
} else {
@@ -60,13 +57,11 @@ Error RWLockPosix::read_try_lock() {
}
void RWLockPosix::write_lock() {
-
int err = pthread_rwlock_wrlock(&rwlock);
ERR_FAIL_COND(err != 0);
}
void RWLockPosix::write_unlock() {
-
pthread_rwlock_unlock(&rwlock);
}
@@ -79,23 +74,19 @@ Error RWLockPosix::write_try_lock() {
}
RWLock *RWLockPosix::create_func_posix() {
-
return memnew(RWLockPosix);
}
void RWLockPosix::make_default() {
-
create_func = create_func_posix;
}
RWLockPosix::RWLockPosix() {
-
//rwlock=PTHREAD_RWLOCK_INITIALIZER; fails on OSX
pthread_rwlock_init(&rwlock, nullptr);
}
RWLockPosix::~RWLockPosix() {
-
pthread_rwlock_destroy(&rwlock);
}
diff --git a/drivers/unix/rw_lock_posix.h b/drivers/unix/rw_lock_posix.h
index b12d373db5..056fcaea1c 100644
--- a/drivers/unix/rw_lock_posix.h
+++ b/drivers/unix/rw_lock_posix.h
@@ -37,7 +37,6 @@
#include <pthread.h>
class RWLockPosix : public RWLock {
-
pthread_rwlock_t rwlock;
static RWLock *create_func_posix();
diff --git a/drivers/unix/syslog_logger.cpp b/drivers/unix/syslog_logger.cpp
index dc9112bf14..a4c7070f0e 100644
--- a/drivers/unix/syslog_logger.cpp
+++ b/drivers/unix/syslog_logger.cpp
@@ -49,18 +49,29 @@ void SyslogLogger::print_error(const char *p_function, const char *p_file, int p
const char *err_type = "**ERROR**";
switch (p_type) {
- case ERR_ERROR: err_type = "**ERROR**"; break;
- case ERR_WARNING: err_type = "**WARNING**"; break;
- case ERR_SCRIPT: err_type = "**SCRIPT ERROR**"; break;
- case ERR_SHADER: err_type = "**SHADER ERROR**"; break;
- default: ERR_PRINT("Unknown error type"); break;
+ case ERR_ERROR:
+ err_type = "**ERROR**";
+ break;
+ case ERR_WARNING:
+ err_type = "**WARNING**";
+ break;
+ case ERR_SCRIPT:
+ err_type = "**SCRIPT ERROR**";
+ break;
+ case ERR_SHADER:
+ err_type = "**SHADER ERROR**";
+ break;
+ default:
+ ERR_PRINT("Unknown error type");
+ break;
}
const char *err_details;
- if (p_rationale && *p_rationale)
+ if (p_rationale && *p_rationale) {
err_details = p_rationale;
- else
+ } else {
err_details = p_code;
+ }
syslog(p_type == ERR_WARNING ? LOG_WARNING : LOG_ERR, "%s: %s\n At: %s:%i:%s() - %s", err_type, err_details, p_file, p_line, p_function, p_code);
}
diff --git a/drivers/unix/thread_posix.cpp b/drivers/unix/thread_posix.cpp
index c227aec6d6..aa1b5019ca 100644
--- a/drivers/unix/thread_posix.cpp
+++ b/drivers/unix/thread_posix.cpp
@@ -54,17 +54,14 @@ pthread_key_t ThreadPosix::thread_id_key = _create_thread_id_key();
Thread::ID ThreadPosix::next_thread_id = 0;
Thread::ID ThreadPosix::get_id() const {
-
return id;
}
Thread *ThreadPosix::create_thread_posix() {
-
return memnew(ThreadPosix);
}
void *ThreadPosix::thread_callback(void *userdata) {
-
ThreadPosix *t = reinterpret_cast<ThreadPosix *>(userdata);
t->id = atomic_increment(&next_thread_id);
pthread_setspecific(thread_id_key, (void *)memnew(ID(t->id)));
@@ -79,7 +76,6 @@ void *ThreadPosix::thread_callback(void *userdata) {
}
Thread *ThreadPosix::create_func_posix(ThreadCreateCallback p_callback, void *p_user, const Settings &) {
-
ThreadPosix *tr = memnew(ThreadPosix);
tr->callback = p_callback;
tr->user = p_user;
@@ -91,19 +87,20 @@ Thread *ThreadPosix::create_func_posix(ThreadCreateCallback p_callback, void *p_
return tr;
}
-Thread::ID ThreadPosix::get_thread_id_func_posix() {
+Thread::ID ThreadPosix::get_thread_id_func_posix() {
void *value = pthread_getspecific(thread_id_key);
- if (value)
+ if (value) {
return *static_cast<ID *>(value);
+ }
ID new_id = atomic_increment(&next_thread_id);
pthread_setspecific(thread_id_key, (void *)memnew(ID(new_id)));
return new_id;
}
-void ThreadPosix::wait_to_finish_func_posix(Thread *p_thread) {
+void ThreadPosix::wait_to_finish_func_posix(Thread *p_thread) {
ThreadPosix *tp = static_cast<ThreadPosix *>(p_thread);
ERR_FAIL_COND(!tp);
ERR_FAIL_COND(tp->pthread == 0);
@@ -113,7 +110,6 @@ void ThreadPosix::wait_to_finish_func_posix(Thread *p_thread) {
}
Error ThreadPosix::set_name_func_posix(const String &p_name) {
-
#ifdef PTHREAD_NO_RENAME
return ERR_UNAVAILABLE;
@@ -142,7 +138,6 @@ Error ThreadPosix::set_name_func_posix(const String &p_name) {
};
void ThreadPosix::make_default() {
-
create_func = create_func_posix;
get_thread_id_func = get_thread_id_func_posix;
wait_to_finish_func = wait_to_finish_func_posix;
@@ -150,7 +145,6 @@ void ThreadPosix::make_default() {
}
ThreadPosix::ThreadPosix() {
-
pthread = 0;
}
diff --git a/drivers/unix/thread_posix.h b/drivers/unix/thread_posix.h
index e852dcf3d5..6607dbd111 100644
--- a/drivers/unix/thread_posix.h
+++ b/drivers/unix/thread_posix.h
@@ -38,7 +38,6 @@
#include <sys/types.h>
class ThreadPosix : public Thread {
-
static pthread_key_t thread_id_key;
static ID next_thread_id;
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 385edf3705..efd4f057fd 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -40,7 +40,6 @@
//#define FORCE_FULL_BARRIER
void RenderingDeviceVulkan::_add_dependency(RID p_id, RID p_depends_on) {
-
if (!dependency_map.has(p_depends_on)) {
dependency_map[p_depends_on] = Set<RID>();
}
@@ -55,12 +54,10 @@ void RenderingDeviceVulkan::_add_dependency(RID p_id, RID p_depends_on) {
}
void RenderingDeviceVulkan::_free_dependencies(RID p_id) {
-
//direct dependencies must be freed
Map<RID, Set<RID>>::Element *E = dependency_map.find(p_id);
if (E) {
-
while (E->get().size()) {
free(E->get().front()->get());
}
@@ -71,7 +68,6 @@ void RenderingDeviceVulkan::_free_dependencies(RID p_id) {
E = reverse_dependency_map.find(p_id);
if (E) {
-
for (Set<RID>::Element *F = E->get().front(); F; F = F->next()) {
Map<RID, Set<RID>>::Element *G = dependency_map.find(F->get());
ERR_CONTINUE(!G);
@@ -566,81 +562,97 @@ int RenderingDeviceVulkan::get_format_vertex_size(DataFormat p_format) {
case DATA_FORMAT_B8G8R8A8_UNORM:
case DATA_FORMAT_B8G8R8A8_SNORM:
case DATA_FORMAT_B8G8R8A8_UINT:
- case DATA_FORMAT_B8G8R8A8_SINT: return 4;
+ case DATA_FORMAT_B8G8R8A8_SINT:
+ return 4;
case DATA_FORMAT_R16_UNORM:
case DATA_FORMAT_R16_SNORM:
case DATA_FORMAT_R16_UINT:
case DATA_FORMAT_R16_SINT:
- case DATA_FORMAT_R16_SFLOAT: return 4;
+ case DATA_FORMAT_R16_SFLOAT:
+ return 4;
case DATA_FORMAT_R16G16_UNORM:
case DATA_FORMAT_R16G16_SNORM:
case DATA_FORMAT_R16G16_UINT:
case DATA_FORMAT_R16G16_SINT:
- case DATA_FORMAT_R16G16_SFLOAT: return 4;
+ case DATA_FORMAT_R16G16_SFLOAT:
+ return 4;
case DATA_FORMAT_R16G16B16_UNORM:
case DATA_FORMAT_R16G16B16_SNORM:
case DATA_FORMAT_R16G16B16_UINT:
case DATA_FORMAT_R16G16B16_SINT:
- case DATA_FORMAT_R16G16B16_SFLOAT: return 8;
+ case DATA_FORMAT_R16G16B16_SFLOAT:
+ return 8;
case DATA_FORMAT_R16G16B16A16_UNORM:
case DATA_FORMAT_R16G16B16A16_SNORM:
case DATA_FORMAT_R16G16B16A16_UINT:
case DATA_FORMAT_R16G16B16A16_SINT:
- case DATA_FORMAT_R16G16B16A16_SFLOAT: return 8;
+ case DATA_FORMAT_R16G16B16A16_SFLOAT:
+ return 8;
case DATA_FORMAT_R32_UINT:
case DATA_FORMAT_R32_SINT:
- case DATA_FORMAT_R32_SFLOAT: return 4;
+ case DATA_FORMAT_R32_SFLOAT:
+ return 4;
case DATA_FORMAT_R32G32_UINT:
case DATA_FORMAT_R32G32_SINT:
- case DATA_FORMAT_R32G32_SFLOAT: return 8;
+ case DATA_FORMAT_R32G32_SFLOAT:
+ return 8;
case DATA_FORMAT_R32G32B32_UINT:
case DATA_FORMAT_R32G32B32_SINT:
- case DATA_FORMAT_R32G32B32_SFLOAT: return 12;
+ case DATA_FORMAT_R32G32B32_SFLOAT:
+ return 12;
case DATA_FORMAT_R32G32B32A32_UINT:
case DATA_FORMAT_R32G32B32A32_SINT:
- case DATA_FORMAT_R32G32B32A32_SFLOAT: return 16;
+ case DATA_FORMAT_R32G32B32A32_SFLOAT:
+ return 16;
case DATA_FORMAT_R64_UINT:
case DATA_FORMAT_R64_SINT:
- case DATA_FORMAT_R64_SFLOAT: return 8;
+ case DATA_FORMAT_R64_SFLOAT:
+ return 8;
case DATA_FORMAT_R64G64_UINT:
case DATA_FORMAT_R64G64_SINT:
- case DATA_FORMAT_R64G64_SFLOAT: return 16;
+ case DATA_FORMAT_R64G64_SFLOAT:
+ return 16;
case DATA_FORMAT_R64G64B64_UINT:
case DATA_FORMAT_R64G64B64_SINT:
- case DATA_FORMAT_R64G64B64_SFLOAT: return 24;
+ case DATA_FORMAT_R64G64B64_SFLOAT:
+ return 24;
case DATA_FORMAT_R64G64B64A64_UINT:
case DATA_FORMAT_R64G64B64A64_SINT:
- case DATA_FORMAT_R64G64B64A64_SFLOAT: return 32;
- default: return 0;
+ case DATA_FORMAT_R64G64B64A64_SFLOAT:
+ return 32;
+ default:
+ return 0;
}
}
uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format) {
-
switch (p_format) {
-
- case DATA_FORMAT_R4G4_UNORM_PACK8: return 1;
+ case DATA_FORMAT_R4G4_UNORM_PACK8:
+ return 1;
case DATA_FORMAT_R4G4B4A4_UNORM_PACK16:
case DATA_FORMAT_B4G4R4A4_UNORM_PACK16:
case DATA_FORMAT_R5G6B5_UNORM_PACK16:
case DATA_FORMAT_B5G6R5_UNORM_PACK16:
case DATA_FORMAT_R5G5B5A1_UNORM_PACK16:
case DATA_FORMAT_B5G5R5A1_UNORM_PACK16:
- case DATA_FORMAT_A1R5G5B5_UNORM_PACK16: return 2;
+ case DATA_FORMAT_A1R5G5B5_UNORM_PACK16:
+ return 2;
case DATA_FORMAT_R8_UNORM:
case DATA_FORMAT_R8_SNORM:
case DATA_FORMAT_R8_USCALED:
case DATA_FORMAT_R8_SSCALED:
case DATA_FORMAT_R8_UINT:
case DATA_FORMAT_R8_SINT:
- case DATA_FORMAT_R8_SRGB: return 1;
+ case DATA_FORMAT_R8_SRGB:
+ return 1;
case DATA_FORMAT_R8G8_UNORM:
case DATA_FORMAT_R8G8_SNORM:
case DATA_FORMAT_R8G8_USCALED:
case DATA_FORMAT_R8G8_SSCALED:
case DATA_FORMAT_R8G8_UINT:
case DATA_FORMAT_R8G8_SINT:
- case DATA_FORMAT_R8G8_SRGB: return 2;
+ case DATA_FORMAT_R8G8_SRGB:
+ return 2;
case DATA_FORMAT_R8G8B8_UNORM:
case DATA_FORMAT_R8G8B8_SNORM:
case DATA_FORMAT_R8G8B8_USCALED:
@@ -654,7 +666,8 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format)
case DATA_FORMAT_B8G8R8_SSCALED:
case DATA_FORMAT_B8G8R8_UINT:
case DATA_FORMAT_B8G8R8_SINT:
- case DATA_FORMAT_B8G8R8_SRGB: return 3;
+ case DATA_FORMAT_B8G8R8_SRGB:
+ return 3;
case DATA_FORMAT_R8G8B8A8_UNORM:
case DATA_FORMAT_R8G8B8A8_SNORM:
case DATA_FORMAT_R8G8B8A8_USCALED:
@@ -668,7 +681,8 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format)
case DATA_FORMAT_B8G8R8A8_SSCALED:
case DATA_FORMAT_B8G8R8A8_UINT:
case DATA_FORMAT_B8G8R8A8_SINT:
- case DATA_FORMAT_B8G8R8A8_SRGB: return 4;
+ case DATA_FORMAT_B8G8R8A8_SRGB:
+ return 4;
case DATA_FORMAT_A8B8G8R8_UNORM_PACK32:
case DATA_FORMAT_A8B8G8R8_SNORM_PACK32:
case DATA_FORMAT_A8B8G8R8_USCALED_PACK32:
@@ -687,67 +701,87 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format)
case DATA_FORMAT_A2B10G10R10_USCALED_PACK32:
case DATA_FORMAT_A2B10G10R10_SSCALED_PACK32:
case DATA_FORMAT_A2B10G10R10_UINT_PACK32:
- case DATA_FORMAT_A2B10G10R10_SINT_PACK32: return 4;
+ case DATA_FORMAT_A2B10G10R10_SINT_PACK32:
+ return 4;
case DATA_FORMAT_R16_UNORM:
case DATA_FORMAT_R16_SNORM:
case DATA_FORMAT_R16_USCALED:
case DATA_FORMAT_R16_SSCALED:
case DATA_FORMAT_R16_UINT:
case DATA_FORMAT_R16_SINT:
- case DATA_FORMAT_R16_SFLOAT: return 2;
+ case DATA_FORMAT_R16_SFLOAT:
+ return 2;
case DATA_FORMAT_R16G16_UNORM:
case DATA_FORMAT_R16G16_SNORM:
case DATA_FORMAT_R16G16_USCALED:
case DATA_FORMAT_R16G16_SSCALED:
case DATA_FORMAT_R16G16_UINT:
case DATA_FORMAT_R16G16_SINT:
- case DATA_FORMAT_R16G16_SFLOAT: return 4;
+ case DATA_FORMAT_R16G16_SFLOAT:
+ return 4;
case DATA_FORMAT_R16G16B16_UNORM:
case DATA_FORMAT_R16G16B16_SNORM:
case DATA_FORMAT_R16G16B16_USCALED:
case DATA_FORMAT_R16G16B16_SSCALED:
case DATA_FORMAT_R16G16B16_UINT:
case DATA_FORMAT_R16G16B16_SINT:
- case DATA_FORMAT_R16G16B16_SFLOAT: return 6;
+ case DATA_FORMAT_R16G16B16_SFLOAT:
+ return 6;
case DATA_FORMAT_R16G16B16A16_UNORM:
case DATA_FORMAT_R16G16B16A16_SNORM:
case DATA_FORMAT_R16G16B16A16_USCALED:
case DATA_FORMAT_R16G16B16A16_SSCALED:
case DATA_FORMAT_R16G16B16A16_UINT:
case DATA_FORMAT_R16G16B16A16_SINT:
- case DATA_FORMAT_R16G16B16A16_SFLOAT: return 8;
+ case DATA_FORMAT_R16G16B16A16_SFLOAT:
+ return 8;
case DATA_FORMAT_R32_UINT:
case DATA_FORMAT_R32_SINT:
- case DATA_FORMAT_R32_SFLOAT: return 4;
+ case DATA_FORMAT_R32_SFLOAT:
+ return 4;
case DATA_FORMAT_R32G32_UINT:
case DATA_FORMAT_R32G32_SINT:
- case DATA_FORMAT_R32G32_SFLOAT: return 8;
+ case DATA_FORMAT_R32G32_SFLOAT:
+ return 8;
case DATA_FORMAT_R32G32B32_UINT:
case DATA_FORMAT_R32G32B32_SINT:
- case DATA_FORMAT_R32G32B32_SFLOAT: return 12;
+ case DATA_FORMAT_R32G32B32_SFLOAT:
+ return 12;
case DATA_FORMAT_R32G32B32A32_UINT:
case DATA_FORMAT_R32G32B32A32_SINT:
- case DATA_FORMAT_R32G32B32A32_SFLOAT: return 16;
+ case DATA_FORMAT_R32G32B32A32_SFLOAT:
+ return 16;
case DATA_FORMAT_R64_UINT:
case DATA_FORMAT_R64_SINT:
- case DATA_FORMAT_R64_SFLOAT: return 8;
+ case DATA_FORMAT_R64_SFLOAT:
+ return 8;
case DATA_FORMAT_R64G64_UINT:
case DATA_FORMAT_R64G64_SINT:
- case DATA_FORMAT_R64G64_SFLOAT: return 16;
+ case DATA_FORMAT_R64G64_SFLOAT:
+ return 16;
case DATA_FORMAT_R64G64B64_UINT:
case DATA_FORMAT_R64G64B64_SINT:
- case DATA_FORMAT_R64G64B64_SFLOAT: return 24;
+ case DATA_FORMAT_R64G64B64_SFLOAT:
+ return 24;
case DATA_FORMAT_R64G64B64A64_UINT:
case DATA_FORMAT_R64G64B64A64_SINT:
- case DATA_FORMAT_R64G64B64A64_SFLOAT: return 32;
+ case DATA_FORMAT_R64G64B64A64_SFLOAT:
+ return 32;
case DATA_FORMAT_B10G11R11_UFLOAT_PACK32:
- case DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32: return 4;
- case DATA_FORMAT_D16_UNORM: return 2;
- case DATA_FORMAT_X8_D24_UNORM_PACK32: return 4;
- case DATA_FORMAT_D32_SFLOAT: return 4;
- case DATA_FORMAT_S8_UINT: return 1;
- case DATA_FORMAT_D16_UNORM_S8_UINT: return 4;
- case DATA_FORMAT_D24_UNORM_S8_UINT: return 4;
+ case DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32:
+ return 4;
+ case DATA_FORMAT_D16_UNORM:
+ return 2;
+ case DATA_FORMAT_X8_D24_UNORM_PACK32:
+ return 4;
+ case DATA_FORMAT_D32_SFLOAT:
+ return 4;
+ case DATA_FORMAT_S8_UINT:
+ return 1;
+ case DATA_FORMAT_D16_UNORM_S8_UINT:
+ return 4;
+ case DATA_FORMAT_D24_UNORM_S8_UINT:
+ return 4;
case DATA_FORMAT_D32_SFLOAT_S8_UINT:
return 5; //?
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:
@@ -765,17 +799,20 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format)
case DATA_FORMAT_BC6H_UFLOAT_BLOCK:
case DATA_FORMAT_BC6H_SFLOAT_BLOCK:
case DATA_FORMAT_BC7_UNORM_BLOCK:
- case DATA_FORMAT_BC7_SRGB_BLOCK: return 1;
+ case DATA_FORMAT_BC7_SRGB_BLOCK:
+ return 1;
case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
- case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: return 1;
+ case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
+ return 1;
case DATA_FORMAT_EAC_R11_UNORM_BLOCK:
case DATA_FORMAT_EAC_R11_SNORM_BLOCK:
case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK:
- case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK: return 1;
+ case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK:
+ return 1;
case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK:
case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK:
case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK:
@@ -803,14 +840,17 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format)
case DATA_FORMAT_ASTC_12x10_UNORM_BLOCK:
case DATA_FORMAT_ASTC_12x10_SRGB_BLOCK:
case DATA_FORMAT_ASTC_12x12_UNORM_BLOCK:
- case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK: return 1;
+ case DATA_FORMAT_ASTC_12x12_SRGB_BLOCK:
+ return 1;
case DATA_FORMAT_G8B8G8R8_422_UNORM:
- case DATA_FORMAT_B8G8R8G8_422_UNORM: return 4;
+ case DATA_FORMAT_B8G8R8G8_422_UNORM:
+ return 4;
case DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM:
case DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM:
case DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM:
- case DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM: return 4;
+ case DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM:
+ return 4;
case DATA_FORMAT_R10X6_UNORM_PACK16:
case DATA_FORMAT_R10X6G10X6_UNORM_2PACK16:
case DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16:
@@ -830,14 +870,16 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format)
case DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16:
case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16:
case DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16:
- case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: return 2;
+ case DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16:
+ return 2;
case DATA_FORMAT_G16B16G16R16_422_UNORM:
case DATA_FORMAT_B16G16R16G16_422_UNORM:
case DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM:
case DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM:
case DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM:
case DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM:
- case DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM: return 8;
+ case DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM:
+ return 8;
case DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG:
case DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
case DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
@@ -845,7 +887,8 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format)
case DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
case DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
case DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
- case DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: return 1;
+ case DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
+ return 1;
default: {
ERR_PRINT("Format not handled, bug");
}
@@ -857,7 +900,6 @@ uint32_t RenderingDeviceVulkan::get_image_format_pixel_size(DataFormat p_format)
// https://www.khronos.org/registry/DataFormat/specs/1.1/dataformat.1.1.pdf
void RenderingDeviceVulkan::get_compressed_image_format_block_dimensions(DataFormat p_format, uint32_t &r_w, uint32_t &r_h) {
-
switch (p_format) {
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
@@ -938,34 +980,45 @@ void RenderingDeviceVulkan::get_compressed_image_format_block_dimensions(DataFor
}
uint32_t RenderingDeviceVulkan::get_compressed_image_format_block_byte_size(DataFormat p_format) {
-
switch (p_format) {
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK:
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
case DATA_FORMAT_BC1_RGBA_UNORM_BLOCK:
- case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK: return 8;
+ case DATA_FORMAT_BC1_RGBA_SRGB_BLOCK:
+ return 8;
case DATA_FORMAT_BC2_UNORM_BLOCK:
- case DATA_FORMAT_BC2_SRGB_BLOCK: return 16;
+ case DATA_FORMAT_BC2_SRGB_BLOCK:
+ return 16;
case DATA_FORMAT_BC3_UNORM_BLOCK:
- case DATA_FORMAT_BC3_SRGB_BLOCK: return 16;
+ case DATA_FORMAT_BC3_SRGB_BLOCK:
+ return 16;
case DATA_FORMAT_BC4_UNORM_BLOCK:
- case DATA_FORMAT_BC4_SNORM_BLOCK: return 8;
+ case DATA_FORMAT_BC4_SNORM_BLOCK:
+ return 8;
case DATA_FORMAT_BC5_UNORM_BLOCK:
- case DATA_FORMAT_BC5_SNORM_BLOCK: return 16;
+ case DATA_FORMAT_BC5_SNORM_BLOCK:
+ return 16;
case DATA_FORMAT_BC6H_UFLOAT_BLOCK:
- case DATA_FORMAT_BC6H_SFLOAT_BLOCK: return 16;
+ case DATA_FORMAT_BC6H_SFLOAT_BLOCK:
+ return 16;
case DATA_FORMAT_BC7_UNORM_BLOCK:
- case DATA_FORMAT_BC7_SRGB_BLOCK: return 16;
+ case DATA_FORMAT_BC7_SRGB_BLOCK:
+ return 16;
case DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
- case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: return 8;
+ case DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
+ return 8;
case DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
- case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: return 8;
+ case DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
+ return 8;
case DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
- case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: return 16;
+ case DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
+ return 16;
case DATA_FORMAT_EAC_R11_UNORM_BLOCK:
- case DATA_FORMAT_EAC_R11_SNORM_BLOCK: return 8;
+ case DATA_FORMAT_EAC_R11_SNORM_BLOCK:
+ return 8;
case DATA_FORMAT_EAC_R11G11_UNORM_BLOCK:
- case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK: return 16;
+ case DATA_FORMAT_EAC_R11G11_SNORM_BLOCK:
+ return 16;
case DATA_FORMAT_ASTC_4x4_UNORM_BLOCK: //again, not sure about astc
case DATA_FORMAT_ASTC_4x4_SRGB_BLOCK:
case DATA_FORMAT_ASTC_5x4_UNORM_BLOCK:
@@ -1011,7 +1064,6 @@ uint32_t RenderingDeviceVulkan::get_compressed_image_format_block_byte_size(Data
}
uint32_t RenderingDeviceVulkan::get_compressed_image_format_pixel_rshift(DataFormat p_format) {
-
switch (p_format) {
case DATA_FORMAT_BC1_RGB_UNORM_BLOCK: //these formats are half byte size, so rshift is 1
case DATA_FORMAT_BC1_RGB_SRGB_BLOCK:
@@ -1028,11 +1080,13 @@ uint32_t RenderingDeviceVulkan::get_compressed_image_format_pixel_rshift(DataFor
case DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG:
case DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG:
case DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG:
- case DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: return 1;
+ case DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
+ return 1;
case DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: //these formats are quarter byte size, so rshift is 1
case DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG:
case DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG:
- case DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: return 2;
+ case DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG:
+ return 2;
default: {
}
}
@@ -1055,7 +1109,6 @@ bool RenderingDeviceVulkan::format_has_stencil(DataFormat p_format) {
}
uint32_t RenderingDeviceVulkan::get_image_format_required_size(DataFormat p_format, uint32_t p_width, uint32_t p_height, uint32_t p_depth, uint32_t p_mipmaps, uint32_t *r_blockw, uint32_t *r_blockh, uint32_t *r_depth) {
-
ERR_FAIL_COND_V(p_mipmaps == 0, 0);
uint32_t w = p_width;
uint32_t h = p_height;
@@ -1095,7 +1148,6 @@ uint32_t RenderingDeviceVulkan::get_image_format_required_size(DataFormat p_form
}
uint32_t RenderingDeviceVulkan::get_image_required_mipmaps(uint32_t p_width, uint32_t p_height, uint32_t p_depth) {
-
//formats and block size don't really matter here since they can all go down to 1px (even if block is larger)
int w = p_width;
int h = p_height;
@@ -1104,7 +1156,6 @@ uint32_t RenderingDeviceVulkan::get_image_required_mipmaps(uint32_t p_width, uin
int mipmaps = 1;
while (true) {
-
if (w == 1 && h == 1 && d == 1) {
break;
}
@@ -1274,7 +1325,6 @@ Error RenderingDeviceVulkan::_buffer_free(Buffer *p_buffer) {
}
Error RenderingDeviceVulkan::_insert_staging_block() {
-
VkBufferCreateInfo bufferInfo;
bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferInfo.pNext = nullptr;
@@ -1312,7 +1362,6 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_
r_alloc_size = p_amount;
while (true) {
-
r_alloc_offset = 0;
//see if we can use current block
@@ -1368,7 +1417,6 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_
//block_until_next_frame()
continue;
} else {
-
//flush EVERYTHING including setup commands. IF not immediate, also need to flush the draw commands
_flush(true);
@@ -1413,7 +1461,6 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_
//block_until_next_frame()
continue; //and try again
} else {
-
_flush(false);
for (int i = 0; i < staging_buffer_blocks.size(); i++) {
@@ -1443,13 +1490,11 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_
}
Error RenderingDeviceVulkan::_buffer_update(Buffer *p_buffer, size_t p_offset, const uint8_t *p_data, size_t p_data_size, bool p_use_draw_command_buffer, uint32_t p_required_align) {
-
//submitting may get chunked for various reasons, so convert this to a task
size_t to_submit = p_data_size;
size_t submit_from = 0;
while (to_submit > 0) {
-
uint32_t block_write_offset;
uint32_t block_write_amount;
@@ -1490,7 +1535,6 @@ Error RenderingDeviceVulkan::_buffer_update(Buffer *p_buffer, size_t p_offset, c
}
void RenderingDeviceVulkan::_memory_barrier(VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw) {
-
VkMemoryBarrier mem_barrier;
mem_barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
mem_barrier.pNext = nullptr;
@@ -1537,7 +1581,6 @@ void RenderingDeviceVulkan::_full_barrier(bool p_sync_with_draw) {
}
void RenderingDeviceVulkan::_buffer_memory_barrier(VkBuffer buffer, uint64_t p_from, uint64_t p_size, VkPipelineStageFlags p_src_stage_mask, VkPipelineStageFlags p_dst_stage_mask, VkAccessFlags p_src_access, VkAccessFlags p_dst_sccess, bool p_sync_with_draw) {
-
VkBufferMemoryBarrier buffer_mem_barrier;
buffer_mem_barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
buffer_mem_barrier.pNext = nullptr;
@@ -1557,7 +1600,6 @@ void RenderingDeviceVulkan::_buffer_memory_barrier(VkBuffer buffer, uint64_t p_f
/*****************/
RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const TextureView &p_view, const Vector<Vector<uint8_t>> &p_data) {
-
_THREAD_SAFE_METHOD_
VkImageCreateInfo image_create_info;
@@ -1687,7 +1729,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
"Too many mipmaps requested for texture format and dimensions (" + itos(image_create_info.mipLevels) + "), maximum allowed: (" + itos(required_mipmaps) + ").");
if (p_data.size()) {
-
ERR_FAIL_COND_V_MSG(!(p_format.usage_bits & TEXTURE_USAGE_CAN_UPDATE_BIT), RID(),
"Texture needs the TEXTURE_USAGE_CAN_UPDATE_BIT usage flag in order to be updated at initialization or later");
@@ -1795,7 +1836,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
texture.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
} else if (p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
-
texture.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
} else {
@@ -1803,7 +1843,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
}
if (p_format.usage_bits & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
-
texture.read_aspect_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
texture.barrier_aspect_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
@@ -1898,7 +1937,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
RID id = texture_owner.make_rid(texture);
if (p_data.size()) {
-
for (uint32_t i = 0; i < image_create_info.arrayLayers; i++) {
texture_update(id, i, p_data[i]);
}
@@ -1907,7 +1945,6 @@ RID RenderingDeviceVulkan::texture_create(const TextureFormat &p_format, const T
}
RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID p_with_texture) {
-
_THREAD_SAFE_METHOD_
Texture *src_texture = texture_owner.getornull(p_with_texture);
@@ -1987,7 +2024,6 @@ RID RenderingDeviceVulkan::texture_create_shared(const TextureView &p_view, RID
}
RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) {
-
_THREAD_SAFE_METHOD_
Texture *src_texture = texture_owner.getornull(p_with_texture);
@@ -2087,7 +2123,6 @@ RID RenderingDeviceVulkan::texture_create_shared_from_slice(const TextureView &p
}
Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, const Vector<uint8_t> &p_data, bool p_sync_with_draw) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V_MSG(draw_list && p_sync_with_draw, ERR_INVALID_PARAMETER,
@@ -2158,7 +2193,6 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
uint32_t mipmap_offset = 0;
for (uint32_t mm_i = 0; mm_i < texture->mipmaps; mm_i++) {
-
uint32_t depth;
uint32_t image_total = get_image_format_required_size(texture->format, texture->width, texture->height, texture->depth, mm_i + 1, &width, &height, &depth);
@@ -2171,7 +2205,6 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
for (uint32_t x = 0; x < width; x += region_size) {
for (uint32_t y = 0; y < height; y += region_size) {
-
uint32_t region_w = MIN(region_size, width - x);
uint32_t region_h = MIN(region_size, height - y);
@@ -2232,7 +2265,6 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
uint32_t dst_offset = (yr * region_w + xr) * pixel_size;
//copy block
for (uint32_t i = 0; i < pixel_size; i++) {
-
write_ptr[dst_offset + i] = read_ptr[src_offset + i];
}
}
@@ -2296,7 +2328,6 @@ Error RenderingDeviceVulkan::texture_update(RID p_texture, uint32_t p_layer, con
}
Vector<uint8_t> RenderingDeviceVulkan::_texture_get_data_from_image(Texture *tex, VkImage p_image, VmaAllocation p_allocation, uint32_t p_layer, bool p_2d) {
-
uint32_t width, height, depth;
uint32_t image_size = get_image_format_required_size(tex->format, tex->width, tex->height, p_2d ? 1 : tex->depth, tex->mipmaps, &width, &height, &depth);
@@ -2316,7 +2347,6 @@ Vector<uint8_t> RenderingDeviceVulkan::_texture_get_data_from_image(Texture *tex
uint32_t mipmap_offset = 0;
for (uint32_t mm_i = 0; mm_i < tex->mipmaps; mm_i++) {
-
uint32_t image_total = get_image_format_required_size(tex->format, tex->width, tex->height, p_2d ? 1 : tex->depth, mm_i + 1, &width, &height, &depth);
uint8_t *write_ptr_mipmap = w + mipmap_offset;
@@ -2363,7 +2393,6 @@ Vector<uint8_t> RenderingDeviceVulkan::_texture_get_data_from_image(Texture *tex
}
Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t p_layer) {
-
_THREAD_SAFE_METHOD_
Texture *tex = texture_owner.getornull(p_texture);
@@ -2384,13 +2413,12 @@ Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t
//does not need anything fancy, map and read.
return _texture_get_data_from_image(tex, tex->image, tex->allocation, p_layer);
} else {
-
//compute total image size
uint32_t width, height, depth;
uint32_t buffer_size = get_image_format_required_size(tex->format, tex->width, tex->height, tex->depth, tex->mipmaps, &width, &height, &depth);
//allocate buffer
- VkCommandBuffer command_buffer = frames[frame].setup_command_buffer;
+ VkCommandBuffer command_buffer = frames[frame].draw_command_buffer; //makes more sense to retrieve
Buffer tmp_buffer;
_buffer_allocate(&tmp_buffer, buffer_size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, VMA_MEMORY_USAGE_CPU_ONLY);
@@ -2422,7 +2450,6 @@ Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t
uint32_t prev_size = 0;
uint32_t offset = 0;
for (uint32_t i = 0; i < tex->mipmaps; i++) {
-
VkBufferImageCopy buffer_image_copy;
uint32_t image_size = get_image_format_required_size(tex->format, tex->width, tex->height, tex->depth, i + 1);
@@ -2479,7 +2506,6 @@ Vector<uint8_t> RenderingDeviceVulkan::texture_get_data(RID p_texture, uint32_t
Vector<uint8_t> buffer_data;
{
-
buffer_data.resize(buffer_size);
uint8_t *w = buffer_data.ptrw();
copymem(w, buffer_mem, buffer_size);
@@ -2506,7 +2532,6 @@ bool RenderingDeviceVulkan::texture_is_valid(RID p_texture) {
}
Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture, const Vector3 &p_from, const Vector3 &p_to, const Vector3 &p_size, uint32_t p_src_mipmap, uint32_t p_dst_mipmap, uint32_t p_src_layer, uint32_t p_dst_layer, bool p_sync_with_draw) {
-
_THREAD_SAFE_METHOD_
Texture *src_tex = texture_owner.getornull(p_from_texture);
@@ -2557,7 +2582,6 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
{
-
//PRE Copy the image
{ //Source
@@ -2604,7 +2628,6 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
//COPY
{
-
VkImageCopy image_copy_region;
image_copy_region.srcSubresource.aspectMask = src_tex->read_aspect_mask;
image_copy_region.srcSubresource.baseArrayLayer = p_src_layer;
@@ -2676,6 +2699,7 @@ Error RenderingDeviceVulkan::texture_copy(RID p_from_texture, RID p_to_texture,
return OK;
}
+
Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID p_to_texture, bool p_sync_with_draw) {
_THREAD_SAFE_METHOD_
@@ -2710,7 +2734,6 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
VkCommandBuffer command_buffer = p_sync_with_draw ? frames[frame].draw_command_buffer : frames[frame].setup_command_buffer;
{
-
//PRE Copy the image
{ //Source
@@ -2757,7 +2780,6 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
//COPY
{
-
VkImageResolve image_copy_region;
image_copy_region.srcSubresource.aspectMask = src_tex->read_aspect_mask;
image_copy_region.srcSubresource.baseArrayLayer = src_tex->base_layer;
@@ -2831,7 +2853,6 @@ Error RenderingDeviceVulkan::texture_resolve_multisample(RID p_from_texture, RID
}
Error RenderingDeviceVulkan::texture_clear(RID p_texture, const Color &p_color, uint32_t p_base_mipmap, uint32_t p_mipmaps, uint32_t p_base_layer, uint32_t p_layers, bool p_sync_with_draw) {
-
_THREAD_SAFE_METHOD_
Texture *src_tex = texture_owner.getornull(p_texture);
@@ -2964,14 +2985,12 @@ bool RenderingDeviceVulkan::texture_is_format_supported_for_usage(DataFormat p_f
/********************/
VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentFormat> &p_format, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, int *r_color_attachment_count) {
-
Vector<VkAttachmentDescription> attachments;
Vector<VkAttachmentReference> color_references;
Vector<VkAttachmentReference> depth_stencil_references;
Vector<VkAttachmentReference> resolve_references;
for (int i = 0; i < p_format.size(); i++) {
-
VkAttachmentDescription description;
description.flags = 0;
@@ -2988,7 +3007,6 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
bool is_storage = p_format[i].usage_flags & TEXTURE_USAGE_STORAGE_BIT;
switch (is_depth_stencil ? p_initial_depth_action : p_initial_color_action) {
-
case INITIAL_ACTION_CLEAR: {
description.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
description.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
@@ -3046,13 +3064,11 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
switch (is_depth_stencil ? p_final_depth_action : p_final_color_action) {
case FINAL_ACTION_READ: {
-
if (p_format[i].usage_flags & TEXTURE_USAGE_COLOR_ATTACHMENT_BIT) {
description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
-
description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
@@ -3068,7 +3084,6 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
-
description.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
description.finalLayout = is_sampled ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : (is_storage ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
@@ -3084,7 +3099,6 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
description.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
} else if (p_format[i].usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
-
description.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
description.stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
description.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
@@ -3159,7 +3173,6 @@ VkRenderPass RenderingDeviceVulkan::_render_pass_create(const Vector<AttachmentF
}
RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_format_create(const Vector<AttachmentFormat> &p_format) {
-
_THREAD_SAFE_METHOD_
FramebufferFormatKey key;
@@ -3201,7 +3214,6 @@ RenderingDevice::TextureSamples RenderingDeviceVulkan::framebuffer_format_get_te
/***********************/
RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attachments, FramebufferFormatID p_format_check) {
-
_THREAD_SAFE_METHOD_
Vector<AttachmentFormat> attachments;
@@ -3249,7 +3261,6 @@ RID RenderingDeviceVulkan::framebuffer_create(const Vector<RID> &p_texture_attac
}
RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_get_format(RID p_framebuffer) {
-
_THREAD_SAFE_METHOD_
Framebuffer *framebuffer = framebuffer_owner.getornull(p_framebuffer);
@@ -3263,7 +3274,6 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::framebuffer_get_form
/*****************/
RID RenderingDeviceVulkan::sampler_create(const SamplerState &p_state) {
-
_THREAD_SAFE_METHOD_
VkSamplerCreateInfo sampler_create_info;
@@ -3309,7 +3319,6 @@ RID RenderingDeviceVulkan::sampler_create(const SamplerState &p_state) {
/**********************/
RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID());
@@ -3327,8 +3336,7 @@ RID RenderingDeviceVulkan::vertex_buffer_create(uint32_t p_size_bytes, const Vec
}
// Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated
-RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) {
-
+RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) {
_THREAD_SAFE_METHOD_
VertexDescriptionKey key;
@@ -3380,7 +3388,6 @@ RenderingDevice::VertexFormatID RenderingDeviceVulkan::vertex_format_create(cons
}
RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!vertex_formats.has(p_vertex_format), RID());
@@ -3402,7 +3409,7 @@ RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFo
//validate with buffer
{
- const VertexDescription &atf = vd.vertex_formats[i];
+ const VertexAttribute &atf = vd.vertex_formats[i];
uint32_t element_size = get_format_vertex_size(atf.format);
ERR_FAIL_COND_V(element_size == 0, RID()); //should never happens since this was prevalidated
@@ -3437,7 +3444,6 @@ RID RenderingDeviceVulkan::vertex_array_create(uint32_t p_vertex_count, VertexFo
}
RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBufferFormat p_format, const Vector<uint8_t> &p_data, bool p_use_restart_indices) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(p_index_count == 0, RID());
@@ -3487,7 +3493,6 @@ RID RenderingDeviceVulkan::index_buffer_create(uint32_t p_index_count, IndexBuff
}
RID RenderingDeviceVulkan::index_array_create(RID p_index_buffer, uint32_t p_index_offset, uint32_t p_index_count) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!index_buffer_owner.owns(p_index_buffer), RID());
@@ -3751,7 +3756,6 @@ bool RenderingDeviceVulkan::_uniform_add_binding(Vector<Vector<VkDescriptorSetLa
#endif
RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages) {
-
//descriptor layouts
Vector<Vector<VkDescriptorSetLayoutBinding>> set_bindings;
Vector<Vector<UniformInfo>> uniform_info;
@@ -3768,7 +3772,6 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
bool is_compute = false;
for (int i = 0; i < p_stages.size(); i++) {
-
if (p_stages[i].shader_stage == SHADER_STAGE_COMPUTE) {
is_compute = true;
ERR_FAIL_COND_V_MSG(p_stages.size() != 1, RID(),
@@ -3792,7 +3795,6 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
uint32_t stage = p_stages[i].shader_stage;
if (binding_count > 0) {
-
//Parse bindings
Vector<SpvReflectDescriptorBinding *> bindings;
@@ -3943,7 +3945,6 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
}
if (stage == SHADER_STAGE_VERTEX) {
-
uint32_t iv_count = 0;
result = spvReflectEnumerateInputVariables(&module, &iv_count, nullptr);
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(),
@@ -3966,7 +3967,6 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
}
if (stage == SHADER_STAGE_FRAGMENT) {
-
uint32_t ov_count = 0;
result = spvReflectEnumerateOutputVariables(&module, &ov_count, nullptr);
ERR_FAIL_COND_V_MSG(result != SPV_REFLECT_RESULT_SUCCESS, RID(),
@@ -4079,9 +4079,7 @@ RID RenderingDeviceVulkan::shader_create(const Vector<ShaderStageData> &p_stages
//proceed to create descriptor sets
if (success) {
-
for (int i = 0; i < set_bindings.size(); i++) {
-
//empty ones are fine if they were not used according to spec (binding count will be 0)
VkDescriptorSetLayoutCreateInfo layout_create_info;
layout_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
@@ -4190,7 +4188,6 @@ uint32_t RenderingDeviceVulkan::shader_get_vertex_input_attribute_mask(RID p_sha
/******************/
RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID());
@@ -4208,7 +4205,6 @@ RID RenderingDeviceVulkan::uniform_buffer_create(uint32_t p_size_bytes, const Ve
}
RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(p_data.size() && (uint32_t)p_data.size() != p_size_bytes, RID());
@@ -4227,7 +4223,6 @@ RID RenderingDeviceVulkan::storage_buffer_create(uint32_t p_size_bytes, const Ve
}
RID RenderingDeviceVulkan::texture_buffer_create(uint32_t p_size_elements, DataFormat p_format, const Vector<uint8_t> &p_data) {
-
_THREAD_SAFE_METHOD_
uint32_t element_size = get_format_vertex_size(p_format);
@@ -4384,7 +4379,6 @@ void RenderingDeviceVulkan::_descriptor_pool_free(const DescriptorPoolKey &p_key
}
RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms, RID p_shader, uint32_t p_shader_set) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(p_uniforms.size() == 0, RID());
@@ -4437,6 +4431,12 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
write.pNext = nullptr;
write.dstSet = VK_NULL_HANDLE; //will assign afterwards when everything is valid
write.dstBinding = set_uniform.binding;
+ write.dstArrayElement = 0;
+ write.descriptorCount = 0;
+ write.descriptorType = VK_DESCRIPTOR_TYPE_MAX_ENUM; //Invalid value.
+ write.pImageInfo = nullptr;
+ write.pBufferInfo = nullptr;
+ write.pTexelBufferView = nullptr;
uint32_t type_size = 1;
switch (uniform.type) {
@@ -4474,7 +4474,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
} break;
case UNIFORM_TYPE_SAMPLER_WITH_TEXTURE: {
-
if (uniform.ids.size() != set_uniform.length * 2) {
if (set_uniform.length > 1) {
ERR_FAIL_V_MSG(RID(), "SamplerTexture (binding: " + itos(uniform.binding) + ") is an array of (" + itos(set_uniform.length) + ") sampler&texture elements, so it should provided twice the amount of IDs (sampler,texture pairs) to satisfy it (IDs provided: " + itos(uniform.ids.size()) + ").");
@@ -4528,7 +4527,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
} break;
case UNIFORM_TYPE_TEXTURE: {
-
if (uniform.ids.size() != set_uniform.length) {
if (set_uniform.length > 1) {
ERR_FAIL_V_MSG(RID(), "Texture (binding: " + itos(uniform.binding) + ") is an array of (" + itos(set_uniform.length) + ") textures, so it should be provided equal number of texture IDs to satisfy it (IDs provided: " + itos(uniform.ids.size()) + ").");
@@ -4579,7 +4577,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
type_size = uniform.ids.size();
} break;
case UNIFORM_TYPE_IMAGE: {
-
if (uniform.ids.size() != set_uniform.length) {
if (set_uniform.length > 1) {
ERR_FAIL_V_MSG(RID(), "Image (binding: " + itos(uniform.binding) + ") is an array of (" + itos(set_uniform.length) + ") textures, so it should be provided equal number of texture IDs to satisfy it (IDs provided: " + itos(uniform.ids.size()) + ").");
@@ -4659,7 +4656,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
} break;
case UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER: {
-
if (uniform.ids.size() != set_uniform.length * 2) {
if (set_uniform.length > 1) {
ERR_FAIL_V_MSG(RID(), "SamplerBuffer (binding: " + itos(uniform.binding) + ") is an array of (" + itos(set_uniform.length) + ") sampler buffer elements, so it should provided twice the amount of IDs (sampler,buffer pairs) to satisfy it (IDs provided: " + itos(uniform.ids.size()) + ").");
@@ -4741,7 +4737,6 @@ RID RenderingDeviceVulkan::uniform_set_create(const Vector<Uniform> &p_uniforms,
write.pTexelBufferView = nullptr;
} break;
case UNIFORM_TYPE_INPUT_ATTACHMENT: {
-
} break;
default: {
}
@@ -4865,7 +4860,6 @@ Error RenderingDeviceVulkan::buffer_update(RID p_buffer, uint32_t p_offset, uint
}
Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
-
_THREAD_SAFE_METHOD_
Buffer *buffer = nullptr;
@@ -4898,7 +4892,6 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
Vector<uint8_t> buffer_data;
{
-
buffer_data.resize(buffer->size);
uint8_t *w = buffer_data.ptrw();
copymem(w, buffer_mem, buffer->size);
@@ -4916,7 +4909,6 @@ Vector<uint8_t> RenderingDeviceVulkan::buffer_get_data(RID p_buffer) {
/*************************/
RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags) {
-
_THREAD_SAFE_METHOD_
//needs a shader
@@ -5085,29 +5077,29 @@ RID RenderingDeviceVulkan::render_pipeline_create(RID p_shader, FramebufferForma
depth_stencil_state_create_info.depthBoundsTestEnable = p_depth_stencil_state.enable_depth_range;
depth_stencil_state_create_info.stencilTestEnable = p_depth_stencil_state.enable_stencil;
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.fail, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.front.failOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.fail];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.pass, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.front.passOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.pass];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.depth_fail, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.front.depthFailOp = stencil_operations[p_depth_stencil_state.stencil_operation_front.depth_fail];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_front.compare, COMPARE_OP_MAX, RID());
- depth_stencil_state_create_info.front.compareOp = compare_operators[p_depth_stencil_state.stencil_operation_front.compare];
- depth_stencil_state_create_info.front.compareMask = p_depth_stencil_state.stencil_operation_front.compare_mask;
- depth_stencil_state_create_info.front.writeMask = p_depth_stencil_state.stencil_operation_front.write_mask;
- depth_stencil_state_create_info.front.reference = p_depth_stencil_state.stencil_operation_front.reference;
-
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.fail, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.back.failOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.fail];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.pass, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.back.passOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.pass];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.depth_fail, STENCIL_OP_MAX, RID());
- depth_stencil_state_create_info.back.depthFailOp = stencil_operations[p_depth_stencil_state.stencil_operation_back.depth_fail];
- ERR_FAIL_INDEX_V(p_depth_stencil_state.stencil_operation_back.compare, COMPARE_OP_MAX, RID());
- depth_stencil_state_create_info.back.compareOp = compare_operators[p_depth_stencil_state.stencil_operation_back.compare];
- depth_stencil_state_create_info.back.compareMask = p_depth_stencil_state.stencil_operation_back.compare_mask;
- depth_stencil_state_create_info.back.writeMask = p_depth_stencil_state.stencil_operation_back.write_mask;
- depth_stencil_state_create_info.back.reference = p_depth_stencil_state.stencil_operation_back.reference;
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.fail, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.front.failOp = stencil_operations[p_depth_stencil_state.front_op.fail];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.pass, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.front.passOp = stencil_operations[p_depth_stencil_state.front_op.pass];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.depth_fail, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.front.depthFailOp = stencil_operations[p_depth_stencil_state.front_op.depth_fail];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.front_op.compare, COMPARE_OP_MAX, RID());
+ depth_stencil_state_create_info.front.compareOp = compare_operators[p_depth_stencil_state.front_op.compare];
+ depth_stencil_state_create_info.front.compareMask = p_depth_stencil_state.front_op.compare_mask;
+ depth_stencil_state_create_info.front.writeMask = p_depth_stencil_state.front_op.write_mask;
+ depth_stencil_state_create_info.front.reference = p_depth_stencil_state.front_op.reference;
+
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.fail, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.back.failOp = stencil_operations[p_depth_stencil_state.back_op.fail];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.pass, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.back.passOp = stencil_operations[p_depth_stencil_state.back_op.pass];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.depth_fail, STENCIL_OP_MAX, RID());
+ depth_stencil_state_create_info.back.depthFailOp = stencil_operations[p_depth_stencil_state.back_op.depth_fail];
+ ERR_FAIL_INDEX_V(p_depth_stencil_state.back_op.compare, COMPARE_OP_MAX, RID());
+ depth_stencil_state_create_info.back.compareOp = compare_operators[p_depth_stencil_state.back_op.compare];
+ depth_stencil_state_create_info.back.compareMask = p_depth_stencil_state.back_op.compare_mask;
+ depth_stencil_state_create_info.back.writeMask = p_depth_stencil_state.back_op.write_mask;
+ depth_stencil_state_create_info.back.reference = p_depth_stencil_state.back_op.reference;
depth_stencil_state_create_info.minDepthBounds = p_depth_stencil_state.depth_range_min;
depth_stencil_state_create_info.maxDepthBounds = p_depth_stencil_state.depth_range_max;
@@ -5326,7 +5318,6 @@ RID RenderingDeviceVulkan::compute_pipeline_create(RID p_shader) {
}
bool RenderingDeviceVulkan::compute_pipeline_is_valid(RID p_pipeline) {
-
return compute_pipeline_owner.owns(p_pipeline);
}
@@ -5339,14 +5330,15 @@ int RenderingDeviceVulkan::screen_get_width(DisplayServer::WindowID p_screen) co
ERR_FAIL_COND_V_MSG(local_device.is_valid(), -1, "Local devices have no screen");
return context->window_get_width(p_screen);
}
+
int RenderingDeviceVulkan::screen_get_height(DisplayServer::WindowID p_screen) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V_MSG(local_device.is_valid(), -1, "Local devices have no screen");
return context->window_get_height(p_screen);
}
-RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuffer_format() const {
+RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuffer_format() const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V_MSG(local_device.is_valid(), INVALID_ID, "Local devices have no screen");
@@ -5376,7 +5368,6 @@ RenderingDevice::FramebufferFormatID RenderingDeviceVulkan::screen_get_framebuff
/*******************/
RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(DisplayServer::WindowID p_screen, const Color &p_clear_color) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V_MSG(local_device.is_valid(), INVALID_ID, "Local devices have no screen");
@@ -5440,7 +5431,6 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin_for_screen(Di
}
Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, VkFramebuffer *r_framebuffer, VkRenderPass *r_render_pass) {
-
Framebuffer::VersionKey vk;
vk.initial_color_action = p_initial_color_action;
vk.final_color_action = p_final_color_action;
@@ -5485,7 +5475,6 @@ Error RenderingDeviceVulkan::_draw_list_setup_framebuffer(Framebuffer *p_framebu
}
Error RenderingDeviceVulkan::_draw_list_render_pass_begin(Framebuffer *framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_colors, float p_clear_depth, uint32_t p_clear_stencil, Point2i viewport_offset, Point2i viewport_size, VkFramebuffer vkframebuffer, VkRenderPass render_pass, VkCommandBuffer command_buffer, VkSubpassContents subpass_contents) {
-
VkRenderPassBeginInfo render_pass_begin;
render_pass_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
render_pass_begin.pNext = nullptr;
@@ -5562,7 +5551,6 @@ void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list,
clear_at.colorAttachment = color_index++;
clear_at.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
} else if (p_clear_depth && texture->usage_flags & TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
-
clear_at.clearValue.depthStencil.depth = p_depth;
clear_at.clearValue.depthStencil.stencil = p_stencil;
clear_at.colorAttachment = 0;
@@ -5588,7 +5576,6 @@ void RenderingDeviceVulkan::_draw_list_insert_clear_region(DrawList *draw_list,
}
RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebuffer, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time.");
@@ -5679,7 +5666,6 @@ RenderingDevice::DrawListID RenderingDeviceVulkan::draw_list_begin(RID p_framebu
}
Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, DrawListID *r_split_ids, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(p_splits < 1, ERR_INVALID_DECLARATION);
@@ -5726,7 +5712,6 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
uint32_t from = split_draw_list_allocators.size();
split_draw_list_allocators.resize(p_splits);
for (uint32_t i = from; i < p_splits; i++) {
-
VkCommandPoolCreateInfo cmd_pool_info;
cmd_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
cmd_pool_info.pNext = nullptr;
@@ -5737,7 +5722,6 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
ERR_FAIL_COND_V_MSG(res, ERR_CANT_CREATE, "vkCreateCommandPool failed with error " + itos(res) + ".");
for (int j = 0; j < frame_count; j++) {
-
VkCommandBuffer command_buffer;
VkCommandBufferAllocateInfo cmdbuf;
@@ -5774,7 +5758,6 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
draw_list_split = true;
for (uint32_t i = 0; i < p_splits; i++) {
-
//take a command buffer and initialize it
VkCommandBuffer command_buffer = split_draw_list_allocators[p_splits].command_buffers[frame];
@@ -5843,7 +5826,6 @@ Error RenderingDeviceVulkan::draw_list_begin_split(RID p_framebuffer, uint32_t p
}
RenderingDeviceVulkan::DrawList *RenderingDeviceVulkan::_get_draw_list_ptr(DrawListID p_id) {
-
if (p_id < 0) {
return nullptr;
}
@@ -5873,7 +5855,6 @@ RenderingDeviceVulkan::DrawList *RenderingDeviceVulkan::_get_draw_list_ptr(DrawL
}
void RenderingDeviceVulkan::draw_list_bind_render_pipeline(DrawListID p_list, RID p_render_pipeline) {
-
DrawList *dl = _get_draw_list_ptr(p_list);
ERR_FAIL_COND(!dl);
#ifdef DEBUG_ENABLED
@@ -5944,7 +5925,6 @@ void RenderingDeviceVulkan::draw_list_bind_render_pipeline(DrawListID p_list, RI
}
void RenderingDeviceVulkan::draw_list_bind_uniform_set(DrawListID p_list, RID p_uniform_set, uint32_t p_index) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_MSG(p_index >= limits.maxBoundDescriptorSets || p_index > MAX_UNIFORM_SETS,
"Attempting to bind a descriptor set (" + itos(p_index) + ") greater than what the hardware supports (" + itos(limits.maxBoundDescriptorSets) + ").");
@@ -6007,8 +5987,8 @@ void RenderingDeviceVulkan::draw_list_bind_vertex_array(DrawListID p_list, RID p
dl->validation.vertex_array_size = vertex_array->vertex_count;
vkCmdBindVertexBuffers(dl->command_buffer, 0, vertex_array->buffers.size(), vertex_array->buffers.ptr(), vertex_array->offsets.ptr());
}
-void RenderingDeviceVulkan::draw_list_bind_index_array(DrawListID p_list, RID p_index_array) {
+void RenderingDeviceVulkan::draw_list_bind_index_array(DrawListID p_list, RID p_index_array) {
DrawList *dl = _get_draw_list_ptr(p_list);
ERR_FAIL_COND(!dl);
#ifdef DEBUG_ENABLED
@@ -6033,7 +6013,6 @@ void RenderingDeviceVulkan::draw_list_bind_index_array(DrawListID p_list, RID p_
}
void RenderingDeviceVulkan::draw_list_set_line_width(DrawListID p_list, float p_width) {
-
DrawList *dl = _get_draw_list_ptr(p_list);
ERR_FAIL_COND(!dl);
#ifdef DEBUG_ENABLED
@@ -6043,7 +6022,7 @@ void RenderingDeviceVulkan::draw_list_set_line_width(DrawListID p_list, float p_
vkCmdSetLineWidth(dl->command_buffer, p_width);
}
-void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size) {
+void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size) {
DrawList *dl = _get_draw_list_ptr(p_list);
ERR_FAIL_COND(!dl);
@@ -6062,7 +6041,6 @@ void RenderingDeviceVulkan::draw_list_set_push_constant(DrawListID p_list, void
}
void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances, uint32_t p_procedural_vertices) {
-
DrawList *dl = _get_draw_list_ptr(p_list);
ERR_FAIL_COND(!dl);
#ifdef DEBUG_ENABLED
@@ -6095,13 +6073,11 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices
//Bind descriptor sets
for (uint32_t i = 0; i < dl->state.set_count; i++) {
-
if (dl->state.sets[i].pipeline_expected_format == 0) {
continue; //nothing expected by this pipeline
}
#ifdef DEBUG_ENABLED
if (dl->state.sets[i].pipeline_expected_format != dl->state.sets[i].uniform_set_format) {
-
if (dl->state.sets[i].uniform_set_format == 0) {
ERR_FAIL_MSG("Uniforms were never supplied for set (" + itos(i) + ") at the time of drawing, which are required by the pipeline");
} else if (uniform_set_owner.owns(dl->state.sets[i].uniform_set)) {
@@ -6120,7 +6096,6 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices
}
if (p_use_indices) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_MSG(p_procedural_vertices > 0,
"Procedural vertices can't be used together with indices.");
@@ -6148,7 +6123,6 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices
#endif
vkCmdDrawIndexed(dl->command_buffer, to_draw, p_instances, dl->validation.index_array_offset, 0, 0);
} else {
-
uint32_t to_draw;
if (p_procedural_vertices > 0) {
@@ -6158,7 +6132,6 @@ void RenderingDeviceVulkan::draw_list_draw(DrawListID p_list, bool p_use_indices
#endif
to_draw = p_procedural_vertices;
} else {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_MSG(dl->validation.pipeline_vertex_format == INVALID_ID,
"Draw command lacks indices, but pipeline format does not use vertices.");
@@ -6201,6 +6174,7 @@ void RenderingDeviceVulkan::draw_list_enable_scissor(DrawListID p_list, const Re
vkCmdSetScissor(dl->command_buffer, 0, 1, &scissor);
}
+
void RenderingDeviceVulkan::draw_list_disable_scissor(DrawListID p_list) {
DrawList *dl = _get_draw_list_ptr(p_list);
ERR_FAIL_COND(!dl);
@@ -6217,7 +6191,6 @@ void RenderingDeviceVulkan::draw_list_disable_scissor(DrawListID p_list) {
}
void RenderingDeviceVulkan::draw_list_end() {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_MSG(!draw_list, "Immediate draw list is already inactive.");
@@ -6271,7 +6244,6 @@ void RenderingDeviceVulkan::draw_list_end() {
/***********************/
RenderingDevice::ComputeListID RenderingDeviceVulkan::compute_list_begin() {
-
ERR_FAIL_COND_V_MSG(draw_list != nullptr, INVALID_ID, "Only one draw list can be active at the same time.");
ERR_FAIL_COND_V_MSG(compute_list != nullptr, INVALID_ID, "Only one draw/compute list can be active at the same time.");
@@ -6341,6 +6313,7 @@ void RenderingDeviceVulkan::compute_list_bind_compute_pipeline(ComputeListID p_l
cl->validation.pipeline_push_constant_size = pipeline->push_constant_size;
#endif
}
+
void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index) {
ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST);
ERR_FAIL_COND(!compute_list);
@@ -6373,7 +6346,6 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
for (uint32_t i = 0; i < textures_to_sampled_count; i++) {
if (textures_to_sampled[i]->layout != VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
-
VkImageMemoryBarrier image_memory_barrier;
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
@@ -6404,7 +6376,6 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
for (uint32_t i = 0; i < textures_to_storage_count; i++) {
if (textures_to_storage[i]->layout != VK_IMAGE_LAYOUT_GENERAL) {
-
VkImageMemoryBarrier image_memory_barrier;
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
@@ -6446,7 +6417,7 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
#endif
}
-void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size) {
+void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) {
ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST);
ERR_FAIL_COND(!compute_list);
@@ -6465,6 +6436,7 @@ void RenderingDeviceVulkan::compute_list_set_push_constant(ComputeListID p_list,
cl->validation.pipeline_push_constant_suppplied = true;
#endif
}
+
void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) {
ERR_FAIL_COND(p_list != ID_TYPE_COMPUTE_LIST);
ERR_FAIL_COND(!compute_list);
@@ -6497,13 +6469,11 @@ void RenderingDeviceVulkan::compute_list_dispatch(ComputeListID p_list, uint32_t
//Bind descriptor sets
for (uint32_t i = 0; i < cl->state.set_count; i++) {
-
if (cl->state.sets[i].pipeline_expected_format == 0) {
continue; //nothing expected by this pipeline
}
#ifdef DEBUG_ENABLED
if (cl->state.sets[i].pipeline_expected_format != cl->state.sets[i].uniform_set_format) {
-
if (cl->state.sets[i].uniform_set_format == 0) {
ERR_FAIL_MSG("Uniforms were never supplied for set (" + itos(i) + ") at the time of drawing, which are required by the pipeline");
} else if (uniform_set_owner.owns(cl->state.sets[i].uniform_set)) {
@@ -6536,7 +6506,6 @@ void RenderingDeviceVulkan::compute_list_end() {
ERR_FAIL_COND(!compute_list);
for (Set<Texture *>::Element *E = compute_list->state.textures_to_sampled_layout.front(); E; E = E->next()) {
-
VkImageMemoryBarrier image_memory_barrier;
image_memory_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
image_memory_barrier.pNext = nullptr;
@@ -6628,7 +6597,6 @@ void RenderingDeviceVulkan::draw_list_render_secondary_to_framebuffer(ID p_frame
#endif
void RenderingDeviceVulkan::_free_internal(RID p_id) {
-
//push everything so it's disposed of next time this frame index is processed (means, it's safe to do it)
if (texture_owner.owns(p_id)) {
Texture *texture = texture_owner.getornull(p_id);
@@ -6691,8 +6659,8 @@ void RenderingDeviceVulkan::_free_internal(RID p_id) {
ERR_PRINT("Attempted to free invalid ID: " + itos(p_id.get_id()));
}
}
-void RenderingDeviceVulkan::free(RID p_id) {
+void RenderingDeviceVulkan::free(RID p_id) {
_THREAD_SAFE_METHOD_
_free_dependencies(p_id); //recursively erase dependencies first, to avoid potential API problems
@@ -6700,7 +6668,6 @@ void RenderingDeviceVulkan::free(RID p_id) {
}
void RenderingDeviceVulkan::_finalize_command_bufers() {
-
if (draw_list) {
ERR_PRINT("Found open draw list at the end of the frame, this should never happen (further drawing will likely not work).");
}
@@ -6716,7 +6683,6 @@ void RenderingDeviceVulkan::_finalize_command_bufers() {
}
void RenderingDeviceVulkan::_begin_frame() {
-
//erase pending resources
_free_pending_resources(frame);
@@ -6763,7 +6729,6 @@ void RenderingDeviceVulkan::_begin_frame() {
}
void RenderingDeviceVulkan::swap_buffers() {
-
ERR_FAIL_COND_MSG(local_device.is_valid(), "Local devices can't swap buffers.");
_THREAD_SAFE_METHOD_
@@ -6790,12 +6755,12 @@ void RenderingDeviceVulkan::submit() {
}
void RenderingDeviceVulkan::sync() {
-
ERR_FAIL_COND_MSG(local_device.is_null(), "Only local devices can submit and sync.");
ERR_FAIL_COND_MSG(!local_device_processing, "sync can only be called after a submit");
context->local_device_sync(local_device);
_begin_frame();
+ local_device_processing = false;
}
void RenderingDeviceVulkan::_free_pending_resources(int p_frame) {
@@ -6895,7 +6860,6 @@ void RenderingDeviceVulkan::_free_pending_resources(int p_frame) {
//buffers
while (frames[p_frame].buffers_to_dispose_of.front()) {
-
_buffer_free(&frames[p_frame].buffers_to_dispose_of.front()->get());
frames[p_frame].buffers_to_dispose_of.pop_front();
@@ -6912,8 +6876,13 @@ uint32_t RenderingDeviceVulkan::get_frame_delay() const {
return frame_count;
}
-void RenderingDeviceVulkan::_flush(bool p_current_frame) {
+uint64_t RenderingDeviceVulkan::get_memory_usage() const {
+ VmaStats stats;
+ vmaCalculateStats(allocator, &stats);
+ return stats.total.usedBytes;
+}
+void RenderingDeviceVulkan::_flush(bool p_current_frame) {
if (local_device.is_valid() && !p_current_frame) {
return; //flushign previous frames has no effect with local device
}
@@ -6924,7 +6893,6 @@ void RenderingDeviceVulkan::_flush(bool p_current_frame) {
}
if (local_device.is_valid()) {
-
VkCommandBuffer command_buffers[2] = { frames[frame].setup_command_buffer, frames[frame].draw_command_buffer };
context->local_device_push_command_buffers(local_device, command_buffers, 2);
context->local_device_sync(local_device);
@@ -6970,12 +6938,12 @@ void RenderingDeviceVulkan::_flush(bool p_current_frame) {
}
void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_device) {
-
context = p_context;
device = p_context->get_device();
if (p_local_device) {
frame_count = 1;
local_device = p_context->local_device_create();
+ device = p_context->local_device_get_vk_device(local_device);
} else {
frame_count = p_context->get_swapchain_image_count() + 1; //always need one extra to ensure it's unused at any time, without having to use a fence for this.
}
@@ -6995,7 +6963,6 @@ void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_de
frame = 0;
//create setup and frame buffers
for (int i = 0; i < frame_count; i++) {
-
frames[i].index = 0;
{ //create command pool, one per frame is recommended
@@ -7119,7 +7086,6 @@ void RenderingDeviceVulkan::_free_rids(T &p_owner, const char *p_type) {
}
void RenderingDeviceVulkan::capture_timestamp(const String &p_name, bool p_sync_to_draw) {
-
ERR_FAIL_COND(frames[frame].timestamp_count >= max_timestamp_query_elements);
{
@@ -7211,10 +7177,12 @@ uint64_t RenderingDeviceVulkan::get_captured_timestamp_gpu_time(uint32_t p_index
return l;
}
+
uint64_t RenderingDeviceVulkan::get_captured_timestamp_cpu_time(uint32_t p_index) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_index, frames[frame].timestamp_result_count, 0);
return frames[frame].timestamp_cpu_result_values[p_index];
}
+
String RenderingDeviceVulkan::get_captured_timestamp_name(uint32_t p_index) const {
ERR_FAIL_UNSIGNED_INDEX_V(p_index, frames[frame].timestamp_result_count, String());
return frames[frame].timestamp_result_names[p_index];
@@ -7222,49 +7190,83 @@ String RenderingDeviceVulkan::get_captured_timestamp_name(uint32_t p_index) cons
int RenderingDeviceVulkan::limit_get(Limit p_limit) {
switch (p_limit) {
- case LIMIT_MAX_BOUND_UNIFORM_SETS: return limits.maxBoundDescriptorSets;
- case LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS: return limits.maxColorAttachments;
- case LIMIT_MAX_TEXTURES_PER_UNIFORM_SET: return limits.maxDescriptorSetSampledImages;
- case LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET: return limits.maxDescriptorSetSamplers;
- case LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET: return limits.maxDescriptorSetStorageBuffers;
- case LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET: return limits.maxDescriptorSetStorageImages;
- case LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET: return limits.maxDescriptorSetUniformBuffers;
- case LIMIT_MAX_DRAW_INDEXED_INDEX: return limits.maxDrawIndexedIndexValue;
- case LIMIT_MAX_FRAMEBUFFER_HEIGHT: return limits.maxFramebufferHeight;
- case LIMIT_MAX_FRAMEBUFFER_WIDTH: return limits.maxFramebufferWidth;
- case LIMIT_MAX_TEXTURE_ARRAY_LAYERS: return limits.maxImageArrayLayers;
- case LIMIT_MAX_TEXTURE_SIZE_1D: return limits.maxImageDimension1D;
- case LIMIT_MAX_TEXTURE_SIZE_2D: return limits.maxImageDimension2D;
- case LIMIT_MAX_TEXTURE_SIZE_3D: return limits.maxImageDimension3D;
- case LIMIT_MAX_TEXTURE_SIZE_CUBE: return limits.maxImageDimensionCube;
- case LIMIT_MAX_TEXTURES_PER_SHADER_STAGE: return limits.maxPerStageDescriptorSampledImages;
- case LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorSamplers;
- case LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorStorageBuffers;
- case LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE: return limits.maxPerStageDescriptorStorageImages;
- case LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE: return limits.maxPerStageDescriptorUniformBuffers;
- case LIMIT_MAX_PUSH_CONSTANT_SIZE: return limits.maxPushConstantsSize;
- case LIMIT_MAX_UNIFORM_BUFFER_SIZE: return limits.maxUniformBufferRange;
- case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET: return limits.maxVertexInputAttributeOffset;
- case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES: return limits.maxVertexInputAttributes;
- case LIMIT_MAX_VERTEX_INPUT_BINDINGS: return limits.maxVertexInputBindings;
- case LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE: return limits.maxVertexInputBindingStride;
- case LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT: return limits.minUniformBufferOffsetAlignment;
- case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X: return limits.maxComputeWorkGroupCount[0];
- case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y: return limits.maxComputeWorkGroupCount[1];
- case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z: return limits.maxComputeWorkGroupCount[2];
- case LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS: return limits.maxComputeWorkGroupInvocations;
- case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X: return limits.maxComputeWorkGroupSize[0];
- case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y: return limits.maxComputeWorkGroupSize[1];
- case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z: return limits.maxComputeWorkGroupSize[2];
-
- default: ERR_FAIL_V(0);
+ case LIMIT_MAX_BOUND_UNIFORM_SETS:
+ return limits.maxBoundDescriptorSets;
+ case LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS:
+ return limits.maxColorAttachments;
+ case LIMIT_MAX_TEXTURES_PER_UNIFORM_SET:
+ return limits.maxDescriptorSetSampledImages;
+ case LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET:
+ return limits.maxDescriptorSetSamplers;
+ case LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET:
+ return limits.maxDescriptorSetStorageBuffers;
+ case LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET:
+ return limits.maxDescriptorSetStorageImages;
+ case LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET:
+ return limits.maxDescriptorSetUniformBuffers;
+ case LIMIT_MAX_DRAW_INDEXED_INDEX:
+ return limits.maxDrawIndexedIndexValue;
+ case LIMIT_MAX_FRAMEBUFFER_HEIGHT:
+ return limits.maxFramebufferHeight;
+ case LIMIT_MAX_FRAMEBUFFER_WIDTH:
+ return limits.maxFramebufferWidth;
+ case LIMIT_MAX_TEXTURE_ARRAY_LAYERS:
+ return limits.maxImageArrayLayers;
+ case LIMIT_MAX_TEXTURE_SIZE_1D:
+ return limits.maxImageDimension1D;
+ case LIMIT_MAX_TEXTURE_SIZE_2D:
+ return limits.maxImageDimension2D;
+ case LIMIT_MAX_TEXTURE_SIZE_3D:
+ return limits.maxImageDimension3D;
+ case LIMIT_MAX_TEXTURE_SIZE_CUBE:
+ return limits.maxImageDimensionCube;
+ case LIMIT_MAX_TEXTURES_PER_SHADER_STAGE:
+ return limits.maxPerStageDescriptorSampledImages;
+ case LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE:
+ return limits.maxPerStageDescriptorSamplers;
+ case LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE:
+ return limits.maxPerStageDescriptorStorageBuffers;
+ case LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE:
+ return limits.maxPerStageDescriptorStorageImages;
+ case LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE:
+ return limits.maxPerStageDescriptorUniformBuffers;
+ case LIMIT_MAX_PUSH_CONSTANT_SIZE:
+ return limits.maxPushConstantsSize;
+ case LIMIT_MAX_UNIFORM_BUFFER_SIZE:
+ return limits.maxUniformBufferRange;
+ case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET:
+ return limits.maxVertexInputAttributeOffset;
+ case LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES:
+ return limits.maxVertexInputAttributes;
+ case LIMIT_MAX_VERTEX_INPUT_BINDINGS:
+ return limits.maxVertexInputBindings;
+ case LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE:
+ return limits.maxVertexInputBindingStride;
+ case LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
+ return limits.minUniformBufferOffsetAlignment;
+ case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X:
+ return limits.maxComputeWorkGroupCount[0];
+ case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y:
+ return limits.maxComputeWorkGroupCount[1];
+ case LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z:
+ return limits.maxComputeWorkGroupCount[2];
+ case LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS:
+ return limits.maxComputeWorkGroupInvocations;
+ case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X:
+ return limits.maxComputeWorkGroupSize[0];
+ case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y:
+ return limits.maxComputeWorkGroupSize[1];
+ case LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z:
+ return limits.maxComputeWorkGroupSize[2];
+
+ default:
+ ERR_FAIL_V(0);
}
return 0;
}
void RenderingDeviceVulkan::finalize() {
-
//free all resources
_flush(false);
@@ -7290,7 +7292,6 @@ void RenderingDeviceVulkan::finalize() {
WARN_PRINT(itos(owned.size()) + " RIDs of type 'Texture' were leaked.");
//free shared first
for (List<RID>::Element *E = owned.front(); E;) {
-
List<RID>::Element *N = E->next();
if (texture_is_shared(E->get())) {
free(E->get());
diff --git a/drivers/vulkan/rendering_device_vulkan.h b/drivers/vulkan/rendering_device_vulkan.h
index 404455afb3..6b75154a8d 100644
--- a/drivers/vulkan/rendering_device_vulkan.h
+++ b/drivers/vulkan/rendering_device_vulkan.h
@@ -51,7 +51,6 @@
class VulkanContext;
class RenderingDeviceVulkan : public RenderingDevice {
-
_THREAD_SAFE_CLASS_
// Miscellaneous tables that map
@@ -123,7 +122,6 @@ class RenderingDeviceVulkan : public RenderingDevice {
// for a framebuffer to render into it.
struct Texture {
-
VkImage image;
VmaAllocation allocation;
VmaAllocationInfo allocation_info;
@@ -204,7 +202,6 @@ class RenderingDeviceVulkan : public RenderingDevice {
Error _insert_staging_block();
struct Buffer {
-
uint32_t size;
VkBuffer buffer;
VmaAllocation allocation;
@@ -237,7 +234,6 @@ class RenderingDeviceVulkan : public RenderingDevice {
struct FramebufferFormatKey {
Vector<AttachmentFormat> attachments;
bool operator<(const FramebufferFormatKey &p_key) const {
-
int as = attachments.size();
int bs = p_key.attachments.size();
if (as != bs) {
@@ -332,7 +328,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
RID_Owner<Buffer, true> vertex_buffer_owner;
struct VertexDescriptionKey {
- Vector<VertexDescription> vertex_formats;
+ Vector<VertexAttribute> vertex_formats;
bool operator==(const VertexDescriptionKey &p_key) const {
int vdc = vertex_formats.size();
int vdck = p_key.vertex_formats.size();
@@ -340,11 +336,11 @@ class RenderingDeviceVulkan : public RenderingDevice {
if (vdc != vdck) {
return false;
} else {
- const VertexDescription *a_ptr = vertex_formats.ptr();
- const VertexDescription *b_ptr = p_key.vertex_formats.ptr();
+ const VertexAttribute *a_ptr = vertex_formats.ptr();
+ const VertexAttribute *b_ptr = p_key.vertex_formats.ptr();
for (int i = 0; i < vdc; i++) {
- const VertexDescription &a = a_ptr[i];
- const VertexDescription &b = b_ptr[i];
+ const VertexAttribute &a = a_ptr[i];
+ const VertexAttribute &b = b_ptr[i];
if (a.location != b.location) {
return false;
@@ -369,9 +365,9 @@ class RenderingDeviceVulkan : public RenderingDevice {
uint32_t hash() const {
int vdc = vertex_formats.size();
uint32_t h = hash_djb2_one_32(vdc);
- const VertexDescription *ptr = vertex_formats.ptr();
+ const VertexAttribute *ptr = vertex_formats.ptr();
for (int i = 0; i < vdc; i++) {
- const VertexDescription &vd = ptr[i];
+ const VertexAttribute &vd = ptr[i];
h = hash_djb2_one_32(vd.location, h);
h = hash_djb2_one_32(vd.offset, h);
h = hash_djb2_one_32(vd.format, h);
@@ -393,7 +389,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
HashMap<VertexDescriptionKey, VertexFormatID, VertexDescriptionHash> vertex_format_cache;
struct VertexDescriptionCache {
- Vector<VertexDescription> vertex_formats;
+ Vector<VertexAttribute> vertex_formats;
VkVertexInputBindingDescription *bindings;
VkVertexInputAttributeDescription *attributes;
VkPipelineVertexInputStateCreateInfo create_info;
@@ -521,9 +517,7 @@ class RenderingDeviceVulkan : public RenderingDevice {
// does not submit something invalid.
struct Shader {
-
struct Set {
-
Vector<UniformInfo> uniform_info;
VkDescriptorSetLayout descriptor_set_layout;
};
@@ -685,7 +679,6 @@ class RenderingDeviceVulkan : public RenderingDevice {
RID_Owner<RenderPipeline, true> render_pipeline_owner;
struct ComputePipeline {
-
RID shader;
Vector<uint32_t> set_formats;
VkPipelineLayout pipeline_layout; // not owned, needed for push constants
@@ -719,7 +712,6 @@ class RenderingDeviceVulkan : public RenderingDevice {
Vector<SplitDrawListAllocator> split_draw_list_allocators;
struct DrawList {
-
VkCommandBuffer command_buffer; //if persistent, this is owned, otherwise it's shared with the ringbuffer
Rect2i viewport;
@@ -836,7 +828,6 @@ class RenderingDeviceVulkan : public RenderingDevice {
/**********************/
struct ComputeList {
-
VkCommandBuffer command_buffer; //if persistent, this is owned, otherwise it's shared with the ringbuffer
struct SetState {
@@ -1016,7 +1007,7 @@ public:
virtual RID vertex_buffer_create(uint32_t p_size_bytes, const Vector<uint8_t> &p_data = Vector<uint8_t>());
// Internally reference counted, this ID is warranted to be unique for the same description, but needs to be freed as many times as it was allocated
- virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats);
+ virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats);
virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers);
virtual RID index_buffer_create(uint32_t p_size_indices, IndexBufferFormat p_format, const Vector<uint8_t> &p_data = Vector<uint8_t>(), bool p_use_restart_indices = false);
@@ -1080,7 +1071,7 @@ public:
virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array);
virtual void draw_list_bind_index_array(DrawListID p_list, RID p_index_array);
virtual void draw_list_set_line_width(DrawListID p_list, float p_width);
- virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size);
+ virtual void draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size);
virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0);
@@ -1096,7 +1087,7 @@ public:
virtual ComputeListID compute_list_begin();
virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline);
virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index);
- virtual void compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size);
+ virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size);
virtual void compute_list_add_barrier(ComputeListID p_list);
virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups);
@@ -1138,6 +1129,8 @@ public:
virtual RenderingDevice *create_local_device();
+ virtual uint64_t get_memory_usage() const;
+
RenderingDeviceVulkan();
~RenderingDeviceVulkan();
};
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 083b822676..a8a29aaeea 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -49,7 +49,6 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
void *pUserData) {
-
// This error needs to be ignored because the AMD allocator will mix up memory types on IGP processors.
if (strstr(pCallbackData->pMessage, "Mapping an image with layout") != nullptr &&
strstr(pCallbackData->pMessage, "can result in undefined behavior if this memory is used by the device") != nullptr) {
@@ -163,18 +162,18 @@ VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char **check_n
}
Error VulkanContext::_create_validation_layers() {
-
VkResult err;
+ const char *instance_validation_layers_alt1[] = { "VK_LAYER_KHRONOS_validation" };
+ const char *instance_validation_layers_alt2[] = { "VK_LAYER_LUNARG_standard_validation" };
+ const char *instance_validation_layers_alt3[] = { "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation", "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation", "VK_LAYER_GOOGLE_unique_objects" };
+
uint32_t instance_layer_count = 0;
- uint32_t validation_layer_count = 0;
- const char *instance_validation_layers_alt1[] = { "VK_LAYER_LUNARG_standard_validation" };
- const char *instance_validation_layers_alt2[] = { "VK_LAYER_GOOGLE_threading", "VK_LAYER_LUNARG_parameter_validation",
- "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation",
- "VK_LAYER_GOOGLE_unique_objects" };
- VkBool32 validation_found = 0;
err = vkEnumerateInstanceLayerProperties(&instance_layer_count, nullptr);
ERR_FAIL_COND_V(err, ERR_CANT_CREATE);
- const char **instance_validation_layers = instance_validation_layers_alt1;
+
+ VkBool32 validation_found = 0;
+ uint32_t validation_layer_count = 0;
+ const char **instance_validation_layers = nullptr;
if (instance_layer_count > 0) {
VkLayerProperties *instance_layers = (VkLayerProperties *)malloc(sizeof(VkLayerProperties) * instance_layer_count);
err = vkEnumerateInstanceLayerProperties(&instance_layer_count, instance_layers);
@@ -183,27 +182,33 @@ Error VulkanContext::_create_validation_layers() {
ERR_FAIL_V(ERR_CANT_CREATE);
}
- validation_found = _check_layers(ARRAY_SIZE(instance_validation_layers_alt1), instance_validation_layers,
- instance_layer_count, instance_layers);
- if (validation_found) {
- enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt1);
- enabled_layers[0] = "VK_LAYER_LUNARG_standard_validation";
- validation_layer_count = 1;
- } else {
- // use alternative set of validation layers
- instance_validation_layers = instance_validation_layers_alt2;
- enabled_layer_count = ARRAY_SIZE(instance_validation_layers_alt2);
- validation_found = _check_layers(ARRAY_SIZE(instance_validation_layers_alt2), instance_validation_layers,
- instance_layer_count, instance_layers);
+ validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt1);
+ instance_validation_layers = instance_validation_layers_alt1;
+ validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers);
+
+ // use alternative (deprecated, removed in SDK 1.1.126.0) set of validation layers
+ if (!validation_found) {
validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt2);
- for (uint32_t i = 0; i < validation_layer_count; i++) {
- enabled_layers[i] = instance_validation_layers[i];
- }
+ instance_validation_layers = instance_validation_layers_alt2;
+ validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers);
+ }
+
+ // use alternative (deprecated, removed in SDK 1.1.121.1) set of validation layers
+ if (!validation_found) {
+ validation_layer_count = ARRAY_SIZE(instance_validation_layers_alt3);
+ instance_validation_layers = instance_validation_layers_alt3;
+ validation_found = _check_layers(validation_layer_count, instance_validation_layers, instance_layer_count, instance_layers);
}
+
free(instance_layers);
}
- if (!validation_found) {
+ if (validation_found) {
+ enabled_layer_count = validation_layer_count;
+ for (uint32_t i = 0; i < validation_layer_count; i++) {
+ enabled_layers[i] = instance_validation_layers[i];
+ }
+ } else {
return ERR_CANT_CREATE;
}
@@ -211,7 +216,6 @@ Error VulkanContext::_create_validation_layers() {
}
Error VulkanContext::_initialize_extensions() {
-
VkResult err;
uint32_t instance_extension_count = 0;
@@ -268,7 +272,6 @@ Error VulkanContext::_initialize_extensions() {
}
Error VulkanContext::_create_physical_device() {
-
/* Look for validation layers */
if (use_validation_layers) {
_create_validation_layers();
@@ -506,7 +509,6 @@ Error VulkanContext::_create_physical_device() {
}
Error VulkanContext::_create_device() {
-
VkResult err;
float queue_priorities[1] = { 0.0 };
VkDeviceQueueCreateInfo queues[2];
@@ -545,7 +547,6 @@ Error VulkanContext::_create_device() {
}
Error VulkanContext::_initialize_queues(VkSurfaceKHR surface) {
-
// Iterate over each queue to learn whether it supports presenting:
VkBool32 *supportsPresent = (VkBool32 *)malloc(queue_family_count * sizeof(VkBool32));
for (uint32_t i = 0; i < queue_family_count; i++) {
@@ -594,12 +595,13 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR surface) {
_create_device();
static PFN_vkGetDeviceProcAddr g_gdpa = nullptr;
-#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \
- { \
- if (!g_gdpa) g_gdpa = (PFN_vkGetDeviceProcAddr)vkGetInstanceProcAddr(inst, "vkGetDeviceProcAddr"); \
- fp##entrypoint = (PFN_vk##entrypoint)g_gdpa(dev, "vk" #entrypoint); \
- ERR_FAIL_COND_V_MSG(fp##entrypoint == nullptr, ERR_CANT_CREATE, \
- "vkGetDeviceProcAddr failed to find vk" #entrypoint); \
+#define GET_DEVICE_PROC_ADDR(dev, entrypoint) \
+ { \
+ if (!g_gdpa) \
+ g_gdpa = (PFN_vkGetDeviceProcAddr)vkGetInstanceProcAddr(inst, "vkGetDeviceProcAddr"); \
+ fp##entrypoint = (PFN_vk##entrypoint)g_gdpa(dev, "vk" #entrypoint); \
+ ERR_FAIL_COND_V_MSG(fp##entrypoint == nullptr, ERR_CANT_CREATE, \
+ "vkGetDeviceProcAddr failed to find vk" #entrypoint); \
}
GET_DEVICE_PROC_ADDR(device, CreateSwapchainKHR);
@@ -697,7 +699,6 @@ Error VulkanContext::_create_semaphores() {
}
Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, VkSurfaceKHR p_surface, int p_width, int p_height) {
-
ERR_FAIL_COND_V(windows.has(p_window_id), ERR_INVALID_PARAMETER);
if (!queues_initialized) {
@@ -758,7 +759,6 @@ void VulkanContext::window_destroy(DisplayServer::WindowID p_window_id) {
}
Error VulkanContext::_clean_up_swap_chain(Window *window) {
-
if (!window->swapchain) {
return OK;
}
@@ -1128,7 +1128,6 @@ Error VulkanContext::_update_swap_chain(Window *window) {
}
Error VulkanContext::initialize() {
-
Error err = _create_physical_device();
if (err) {
return err;
@@ -1142,7 +1141,6 @@ void VulkanContext::set_setup_buffer(const VkCommandBuffer &pCommandBuffer) {
}
void VulkanContext::append_command_buffer(const VkCommandBuffer &pCommandBuffer) {
-
if (command_buffer_queue.size() <= command_buffer_count) {
command_buffer_queue.resize(command_buffer_count + 1);
}
@@ -1152,14 +1150,12 @@ void VulkanContext::append_command_buffer(const VkCommandBuffer &pCommandBuffer)
}
void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
-
// ensure everything else pending is executed
vkDeviceWaitIdle(device);
//flush the pending setup buffer
if (p_flush_setup && command_buffer_queue[0]) {
-
//use a fence to wait for everything done
VkSubmitInfo submit_info;
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
@@ -1178,7 +1174,6 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
}
if (p_flush_pending && command_buffer_count > 1) {
-
//use a fence to wait for everything done
VkSubmitInfo submit_info;
@@ -1200,7 +1195,6 @@ void VulkanContext::flush(bool p_flush_setup, bool p_flush_pending) {
}
Error VulkanContext::prepare_buffers() {
-
if (!queues_initialized) {
return OK;
}
@@ -1212,7 +1206,6 @@ Error VulkanContext::prepare_buffers() {
vkResetFences(device, 1, &fences[frame_index]);
for (Map<int, Window>::Element *E = windows.front(); E; E = E->next()) {
-
Window *w = &E->get();
if (w->swapchain == VK_NULL_HANDLE) {
@@ -1248,7 +1241,6 @@ Error VulkanContext::prepare_buffers() {
}
Error VulkanContext::swap_buffers() {
-
if (!queues_initialized) {
return OK;
}
@@ -1467,9 +1459,11 @@ VkDevice VulkanContext::get_device() {
VkPhysicalDevice VulkanContext::get_physical_device() {
return gpu;
}
+
int VulkanContext::get_swapchain_image_count() const {
return swapchainImageCount;
}
+
uint32_t VulkanContext::get_graphics_queue() const {
return graphics_queue_family_index;
}
@@ -1543,7 +1537,6 @@ VkDevice VulkanContext::local_device_get_vk_device(RID p_local_device) {
}
void VulkanContext::local_device_push_command_buffers(RID p_local_device, const VkCommandBuffer *p_buffers, int p_count) {
-
LocalDevice *ld = local_device_owner.getornull(p_local_device);
ERR_FAIL_COND(ld->waiting);
@@ -1559,13 +1552,21 @@ void VulkanContext::local_device_push_command_buffers(RID p_local_device, const
submit_info.pSignalSemaphores = nullptr;
VkResult err = vkQueueSubmit(ld->queue, 1, &submit_info, VK_NULL_HANDLE);
+ if (err == VK_ERROR_OUT_OF_HOST_MEMORY) {
+ print_line("out of host memory");
+ }
+ if (err == VK_ERROR_OUT_OF_DEVICE_MEMORY) {
+ print_line("out of device memory");
+ }
+ if (err == VK_ERROR_DEVICE_LOST) {
+ print_line("device lost");
+ }
ERR_FAIL_COND(err);
ld->waiting = true;
}
void VulkanContext::local_device_sync(RID p_local_device) {
-
LocalDevice *ld = local_device_owner.getornull(p_local_device);
ERR_FAIL_COND(!ld->waiting);
@@ -1574,7 +1575,6 @@ void VulkanContext::local_device_sync(RID p_local_device) {
}
void VulkanContext::local_device_free(RID p_local_device) {
-
LocalDevice *ld = local_device_owner.getornull(p_local_device);
vkDestroyDevice(ld->device, nullptr);
local_device_owner.free(p_local_device);
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index 51c3febb47..ff1215ff5d 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -40,7 +40,6 @@
#include <vulkan/vulkan.h>
class VulkanContext {
-
enum {
MAX_EXTENSIONS = 128,
MAX_LAYERS = 64,
@@ -81,7 +80,6 @@ class VulkanContext {
} SwapchainImageResources;
struct Window {
-
bool is_minimzed;
VkSurfaceKHR surface;
VkSwapchainKHR swapchain;
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index ab2976f02c..cd1c08b717 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -69,13 +69,11 @@ static bool default_render_device_changed = false;
static bool default_capture_device_changed = false;
class CMMNotificationClient : public IMMNotificationClient {
- LONG _cRef;
- IMMDeviceEnumerator *_pEnumerator;
+ LONG _cRef = 1;
+ IMMDeviceEnumerator *_pEnumerator = nullptr;
public:
- CMMNotificationClient() :
- _cRef(1),
- _pEnumerator(nullptr) {}
+ CMMNotificationClient() {}
virtual ~CMMNotificationClient() {
if ((_pEnumerator) != nullptr) {
(_pEnumerator)->Release();
@@ -141,7 +139,6 @@ public:
static CMMNotificationClient notif_client;
Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_capture, bool reinit) {
-
WAVEFORMATEX *pwfex;
IMMDeviceEnumerator *enumerator = nullptr;
IMMDevice *device = nullptr;
@@ -313,7 +310,6 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
}
Error AudioDriverWASAPI::init_render_device(bool reinit) {
-
Error err = audio_device_init(&audio_output, false, reinit);
if (err != OK)
return err;
@@ -352,7 +348,6 @@ Error AudioDriverWASAPI::init_render_device(bool reinit) {
}
Error AudioDriverWASAPI::init_capture_device(bool reinit) {
-
Error err = audio_device_init(&audio_input, true, reinit);
if (err != OK)
return err;
@@ -368,7 +363,6 @@ Error AudioDriverWASAPI::init_capture_device(bool reinit) {
}
Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) {
-
if (p_device->active) {
if (p_device->audio_client) {
p_device->audio_client->Stop();
@@ -385,18 +379,15 @@ Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) {
}
Error AudioDriverWASAPI::finish_render_device() {
-
return audio_device_finish(&audio_output);
}
Error AudioDriverWASAPI::finish_capture_device() {
-
return audio_device_finish(&audio_input);
}
Error AudioDriverWASAPI::init() {
-
- mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+ mix_rate = GLOBAL_GET("audio/mix_rate");
Error err = init_render_device();
if (err != OK) {
@@ -412,17 +403,14 @@ Error AudioDriverWASAPI::init() {
}
int AudioDriverWASAPI::get_mix_rate() const {
-
return mix_rate;
}
AudioDriver::SpeakerMode AudioDriverWASAPI::get_speaker_mode() const {
-
return get_speaker_mode_by_total_channels(channels);
}
Array AudioDriverWASAPI::audio_device_get_list(bool p_capture) {
-
Array list;
IMMDeviceCollection *devices = nullptr;
IMMDeviceEnumerator *enumerator = nullptr;
@@ -470,12 +458,10 @@ Array AudioDriverWASAPI::audio_device_get_list(bool p_capture) {
}
Array AudioDriverWASAPI::get_device_list() {
-
return audio_device_get_list(false);
}
String AudioDriverWASAPI::get_device() {
-
lock();
String name = audio_output.device_name;
unlock();
@@ -484,7 +470,6 @@ String AudioDriverWASAPI::get_device() {
}
void AudioDriverWASAPI::set_device(String device) {
-
lock();
audio_output.new_device = device;
unlock();
@@ -552,13 +537,11 @@ void AudioDriverWASAPI::write_sample(WORD format_tag, int bits_per_sample, BYTE
}
void AudioDriverWASAPI::thread_func(void *p_udata) {
-
AudioDriverWASAPI *ad = (AudioDriverWASAPI *)p_udata;
uint32_t avail_frames = 0;
uint32_t write_ofs = 0;
while (!ad->exit_thread) {
-
uint32_t read_frames = 0;
uint32_t written_frames = 0;
@@ -585,19 +568,16 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
ad->start_counting_ticks();
if (avail_frames > 0 && ad->audio_output.audio_client) {
-
UINT32 cur_frames;
bool invalidated = false;
HRESULT hr = ad->audio_output.audio_client->GetCurrentPadding(&cur_frames);
if (hr == S_OK) {
-
// Check how much frames are available on the WASAPI buffer
UINT32 write_frames = MIN(ad->buffer_frames - cur_frames, avail_frames);
if (write_frames > 0) {
BYTE *buffer = nullptr;
hr = ad->audio_output.render_client->GetBuffer(write_frames, &buffer);
if (hr == S_OK) {
-
// We're using WASAPI Shared Mode so we must convert the buffer
if (ad->channels == ad->audio_output.channels) {
for (unsigned int i = 0; i < write_frames * ad->channels; i++) {
@@ -768,7 +748,6 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
}
void AudioDriverWASAPI::start() {
-
if (audio_output.audio_client) {
HRESULT hr = audio_output.audio_client->Start();
if (hr != S_OK) {
@@ -780,17 +759,14 @@ void AudioDriverWASAPI::start() {
}
void AudioDriverWASAPI::lock() {
-
mutex.lock();
}
void AudioDriverWASAPI::unlock() {
-
mutex.unlock();
}
void AudioDriverWASAPI::finish() {
-
if (thread) {
exit_thread = true;
Thread::wait_to_finish(thread);
@@ -804,7 +780,6 @@ void AudioDriverWASAPI::finish() {
}
Error AudioDriverWASAPI::capture_start() {
-
Error err = init_capture_device();
if (err != OK) {
ERR_PRINT("WASAPI: init_capture_device error");
@@ -821,7 +796,6 @@ Error AudioDriverWASAPI::capture_start() {
}
Error AudioDriverWASAPI::capture_stop() {
-
if (audio_input.active) {
audio_input.audio_client->Stop();
audio_input.active = false;
@@ -833,19 +807,16 @@ Error AudioDriverWASAPI::capture_stop() {
}
void AudioDriverWASAPI::capture_set_device(const String &p_name) {
-
lock();
audio_input.new_device = p_name;
unlock();
}
Array AudioDriverWASAPI::capture_get_device_list() {
-
return audio_device_get_list(true);
}
String AudioDriverWASAPI::capture_get_device() {
-
lock();
String name = audio_input.device_name;
unlock();
@@ -854,17 +825,7 @@ String AudioDriverWASAPI::capture_get_device() {
}
AudioDriverWASAPI::AudioDriverWASAPI() {
-
- thread = nullptr;
-
samples_in.clear();
-
- channels = 0;
- mix_rate = 0;
- buffer_frames = 0;
-
- thread_exited = false;
- exit_thread = false;
}
-#endif
+#endif // WASAPI_ENABLED
diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h
index 01a4666812..41ff7c9895 100644
--- a/drivers/wasapi/audio_driver_wasapi.h
+++ b/drivers/wasapi/audio_driver_wasapi.h
@@ -42,50 +42,38 @@
#include <windows.h>
class AudioDriverWASAPI : public AudioDriver {
-
class AudioDeviceWASAPI {
public:
- IAudioClient *audio_client;
- IAudioRenderClient *render_client;
- IAudioCaptureClient *capture_client;
- bool active;
-
- WORD format_tag;
- WORD bits_per_sample;
- unsigned int channels;
- unsigned int frame_size;
-
- String device_name;
- String new_device;
-
- AudioDeviceWASAPI() :
- audio_client(nullptr),
- render_client(nullptr),
- capture_client(nullptr),
- active(false),
- format_tag(0),
- bits_per_sample(0),
- channels(0),
- frame_size(0),
- device_name("Default"),
- new_device("Default") {
- }
+ IAudioClient *audio_client = nullptr;
+ IAudioRenderClient *render_client = nullptr;
+ IAudioCaptureClient *capture_client = nullptr;
+ bool active = false;
+
+ WORD format_tag = 0;
+ WORD bits_per_sample = 0;
+ unsigned int channels = 0;
+ unsigned int frame_size = 0;
+
+ String device_name = "Default";
+ String new_device = "Default";
+
+ AudioDeviceWASAPI() {}
};
AudioDeviceWASAPI audio_input;
AudioDeviceWASAPI audio_output;
Mutex mutex;
- Thread *thread;
+ Thread *thread = nullptr;
Vector<int32_t> samples_in;
- unsigned int channels;
- int mix_rate;
- int buffer_frames;
+ unsigned int channels = 0;
+ int mix_rate = 0;
+ int buffer_frames = 0;
- bool thread_exited;
- mutable bool exit_thread;
+ bool thread_exited = false;
+ mutable bool exit_thread = false;
static _FORCE_INLINE_ void write_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i, int32_t sample);
static _FORCE_INLINE_ int32_t read_sample(WORD format_tag, int bits_per_sample, BYTE *buffer, int i);
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index a8618b05d7..d0f06ae4c4 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -53,7 +53,6 @@
*/
struct DirAccessWindowsPrivate {
-
HANDLE h; //handle for findfirstfile
WIN32_FIND_DATA f;
WIN32_FIND_DATAW fu; //unicode version
@@ -62,7 +61,6 @@ struct DirAccessWindowsPrivate {
// CreateFolderAsync
Error DirAccessWindows::list_dir_begin() {
-
_cisdir = false;
_cishidden = false;
@@ -73,7 +71,6 @@ Error DirAccessWindows::list_dir_begin() {
}
String DirAccessWindows::get_next() {
-
if (p->h == INVALID_HANDLE_VALUE)
return "";
@@ -83,7 +80,6 @@ String DirAccessWindows::get_next() {
String name = p->fu.cFileName;
if (FindNextFileW(p->h, &p->fu) == 0) {
-
FindClose(p->h);
p->h = INVALID_HANDLE_VALUE;
}
@@ -92,29 +88,25 @@ String DirAccessWindows::get_next() {
}
bool DirAccessWindows::current_is_dir() const {
-
return _cisdir;
}
bool DirAccessWindows::current_is_hidden() const {
-
return _cishidden;
}
void DirAccessWindows::list_dir_end() {
-
if (p->h != INVALID_HANDLE_VALUE) {
-
FindClose(p->h);
p->h = INVALID_HANDLE_VALUE;
}
}
-int DirAccessWindows::get_drive_count() {
+int DirAccessWindows::get_drive_count() {
return drive_count;
}
-String DirAccessWindows::get_drive(int p_drive) {
+String DirAccessWindows::get_drive(int p_drive) {
if (p_drive < 0 || p_drive >= drive_count)
return "";
@@ -122,7 +114,6 @@ String DirAccessWindows::get_drive(int p_drive) {
}
Error DirAccessWindows::change_dir(String p_dir) {
-
GLOBAL_LOCK_FUNCTION
p_dir = fix_path(p_dir);
@@ -136,7 +127,6 @@ Error DirAccessWindows::change_dir(String p_dir) {
String base = _get_root_path();
if (base != "") {
-
GetCurrentDirectoryW(2048, real_current_dir_name);
String new_dir;
new_dir = String(real_current_dir_name).replace("\\", "/");
@@ -146,7 +136,6 @@ Error DirAccessWindows::change_dir(String p_dir) {
}
if (worked) {
-
GetCurrentDirectoryW(2048, real_current_dir_name);
current_dir = real_current_dir_name; // TODO, utf8 parser
current_dir = current_dir.replace("\\", "/");
@@ -160,7 +149,6 @@ Error DirAccessWindows::change_dir(String p_dir) {
}
Error DirAccessWindows::make_dir(String p_dir) {
-
GLOBAL_LOCK_FUNCTION
p_dir = fix_path(p_dir);
@@ -190,10 +178,8 @@ Error DirAccessWindows::make_dir(String p_dir) {
}
String DirAccessWindows::get_current_dir(bool p_include_drive) {
-
String base = _get_root_path();
if (base != "") {
-
String bd = current_dir.replace("\\", "/").replace_first(base, "");
if (bd.begins_with("/"))
return _get_root_string() + bd.substr(1, bd.length());
@@ -217,7 +203,6 @@ String DirAccessWindows::get_current_dir(bool p_include_drive) {
}
bool DirAccessWindows::file_exists(String p_file) {
-
GLOBAL_LOCK_FUNCTION
if (!p_file.is_abs_path())
@@ -239,7 +224,6 @@ bool DirAccessWindows::file_exists(String p_file) {
}
bool DirAccessWindows::dir_exists(String p_dir) {
-
GLOBAL_LOCK_FUNCTION
if (p_dir.is_rel_path())
@@ -260,7 +244,6 @@ bool DirAccessWindows::dir_exists(String p_dir) {
}
Error DirAccessWindows::rename(String p_path, String p_new_path) {
-
if (p_path.is_rel_path())
p_path = get_current_dir().plus_file(p_path);
@@ -298,7 +281,6 @@ Error DirAccessWindows::rename(String p_path, String p_new_path) {
}
Error DirAccessWindows::remove(String p_path) {
-
if (p_path.is_rel_path())
p_path = get_current_dir().plus_file(p_path);
@@ -318,6 +300,7 @@ Error DirAccessWindows::remove(String p_path) {
else
return ::_wunlink(p_path.c_str()) == 0 ? OK : FAILED;
}
+
/*
FileType DirAccessWindows::get_file_type(const String& p_file) const {
@@ -345,9 +328,9 @@ FileType DirAccessWindows::get_file_type(const String& p_file) const {
return (attr&FILE_ATTRIBUTE_DIRECTORY)?FILE_TYPE_
}
+
*/
size_t DirAccessWindows::get_space_left() {
-
uint64_t bytes = 0;
if (!GetDiskFreeSpaceEx(nullptr, (PULARGE_INTEGER)&bytes, nullptr, nullptr))
return 0;
@@ -377,7 +360,6 @@ String DirAccessWindows::get_filesystem_type() const {
&dwFileSystemFlags,
szFileSystemName,
sizeof(szFileSystemName)) == TRUE) {
-
return String(szFileSystemName);
}
@@ -385,7 +367,6 @@ String DirAccessWindows::get_filesystem_type() const {
}
DirAccessWindows::DirAccessWindows() {
-
p = memnew(DirAccessWindowsPrivate);
p->h = INVALID_HANDLE_VALUE;
current_dir = ".";
@@ -401,7 +382,6 @@ DirAccessWindows::DirAccessWindows() {
DWORD mask = GetLogicalDrives();
for (int i = 0; i < MAX_DRIVES; i++) {
-
if (mask & (1 << i)) { //DRIVE EXISTS
drives[drive_count] = 'A' + i;
@@ -414,7 +394,6 @@ DirAccessWindows::DirAccessWindows() {
}
DirAccessWindows::~DirAccessWindows() {
-
memdelete(p);
}
diff --git a/drivers/windows/dir_access_windows.h b/drivers/windows/dir_access_windows.h
index f59e4d7030..47aedfecf5 100644
--- a/drivers/windows/dir_access_windows.h
+++ b/drivers/windows/dir_access_windows.h
@@ -42,7 +42,6 @@
struct DirAccessWindowsPrivate;
class DirAccessWindows : public DirAccess {
-
enum {
MAX_DRIVES = 26
};
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index 69078b3326..50366d0b2d 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -49,17 +49,14 @@
#endif
void FileAccessWindows::check_errors() const {
-
ERR_FAIL_COND(!f);
if (feof(f)) {
-
last_error = ERR_FILE_EOF;
}
}
Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
-
path_src = p_path;
path = fix_path(p_path);
if (f)
@@ -83,7 +80,6 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
struct _stat st;
if (_wstat(path.c_str(), &st) == 0) {
-
if (!S_ISREG(st.st_mode))
return ERR_FILE_CANT_OPEN;
};
@@ -99,7 +95,6 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
if (f != INVALID_HANDLE_VALUE) {
String fname = d.cFileName;
if (fname != String()) {
-
String base_file = path.get_file();
if (base_file != fname && base_file.findn(fname) == 0) {
WARN_PRINT("Case mismatch opening requested file '" + base_file + "', stored as '" + fname + "' in the filesystem. This file will not open when exported to other case-sensitive platforms.");
@@ -135,7 +130,6 @@ Error FileAccessWindows::_open(const String &p_path, int p_mode_flags) {
}
void FileAccessWindows::close() {
-
if (!f)
return;
@@ -143,7 +137,6 @@ void FileAccessWindows::close() {
f = nullptr;
if (save_path != "") {
-
bool rename_error = true;
int attempts = 4;
while (rename_error && attempts) {
@@ -185,36 +178,33 @@ void FileAccessWindows::close() {
}
String FileAccessWindows::get_path() const {
-
return path_src;
}
String FileAccessWindows::get_path_absolute() const {
-
return path;
}
bool FileAccessWindows::is_open() const {
-
return (f != nullptr);
}
-void FileAccessWindows::seek(size_t p_position) {
+void FileAccessWindows::seek(size_t p_position) {
ERR_FAIL_COND(!f);
last_error = OK;
if (fseek(f, p_position, SEEK_SET))
check_errors();
prev_op = 0;
}
-void FileAccessWindows::seek_end(int64_t p_position) {
+void FileAccessWindows::seek_end(int64_t p_position) {
ERR_FAIL_COND(!f);
if (fseek(f, p_position, SEEK_END))
check_errors();
prev_op = 0;
}
-size_t FileAccessWindows::get_position() const {
+size_t FileAccessWindows::get_position() const {
size_t aux_position = 0;
aux_position = ftell(f);
if (!aux_position) {
@@ -222,8 +212,8 @@ size_t FileAccessWindows::get_position() const {
};
return aux_position;
}
-size_t FileAccessWindows::get_len() const {
+size_t FileAccessWindows::get_len() const {
ERR_FAIL_COND_V(!f, 0);
size_t pos = get_position();
@@ -235,13 +225,11 @@ size_t FileAccessWindows::get_len() const {
}
bool FileAccessWindows::eof_reached() const {
-
check_errors();
return last_error == ERR_FILE_EOF;
}
uint8_t FileAccessWindows::get_8() const {
-
ERR_FAIL_COND_V(!f, 0);
if (flags == READ_WRITE || flags == WRITE_READ) {
if (prev_op == WRITE) {
@@ -259,7 +247,6 @@ uint8_t FileAccessWindows::get_8() const {
}
int FileAccessWindows::get_buffer(uint8_t *p_dst, int p_length) const {
-
ERR_FAIL_COND_V(!f, -1);
if (flags == READ_WRITE || flags == WRITE_READ) {
if (prev_op == WRITE) {
@@ -273,12 +260,10 @@ int FileAccessWindows::get_buffer(uint8_t *p_dst, int p_length) const {
};
Error FileAccessWindows::get_error() const {
-
return last_error;
}
void FileAccessWindows::flush() {
-
ERR_FAIL_COND(!f);
fflush(f);
if (prev_op == WRITE)
@@ -286,7 +271,6 @@ void FileAccessWindows::flush() {
}
void FileAccessWindows::store_8(uint8_t p_dest) {
-
ERR_FAIL_COND(!f);
if (flags == READ_WRITE || flags == WRITE_READ) {
if (prev_op == READ) {
@@ -313,23 +297,19 @@ void FileAccessWindows::store_buffer(const uint8_t *p_src, int p_length) {
}
bool FileAccessWindows::file_exists(const String &p_name) {
-
FILE *g;
//printf("opening file %s\n", p_fname.c_str());
String filename = fix_path(p_name);
_wfopen_s(&g, filename.c_str(), L"rb");
if (g == nullptr) {
-
return false;
} else {
-
fclose(g);
return true;
}
}
uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
-
String file = fix_path(p_file);
if (file.ends_with("/") && file != "/")
file = file.substr(0, file.length() - 1);
@@ -338,7 +318,6 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
int rv = _wstat(file.c_str(), &st);
if (rv == 0) {
-
return st.st_mtime;
} else {
ERR_FAIL_V_MSG(0, "Failed to get modified time for: " + file + ".");
@@ -353,15 +332,8 @@ Error FileAccessWindows::_set_unix_permissions(const String &p_file, uint32_t p_
return ERR_UNAVAILABLE;
}
-FileAccessWindows::FileAccessWindows() :
- f(nullptr),
- flags(0),
- prev_op(0),
- last_error(OK) {
-}
FileAccessWindows::~FileAccessWindows() {
-
close();
}
-#endif
+#endif // WINDOWS_ENABLED
diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h
index 28d4375878..98c0efe576 100644
--- a/drivers/windows/file_access_windows.h
+++ b/drivers/windows/file_access_windows.h
@@ -39,12 +39,11 @@
#include <stdio.h>
class FileAccessWindows : public FileAccess {
-
- FILE *f;
- int flags;
+ FILE *f = nullptr;
+ int flags = 0;
void check_errors() const;
- mutable int prev_op;
- mutable Error last_error;
+ mutable int prev_op = 0;
+ mutable Error last_error = OK;
String path;
String path_src;
String save_path;
@@ -79,9 +78,10 @@ public:
virtual uint32_t _get_unix_permissions(const String &p_file);
virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions);
- FileAccessWindows();
+ FileAccessWindows() {}
virtual ~FileAccessWindows();
};
-#endif
-#endif
+#endif // WINDOWS_ENABLED
+
+#endif // FILE_ACCESS_WINDOWS_H
diff --git a/drivers/windows/rw_lock_windows.cpp b/drivers/windows/rw_lock_windows.cpp
index 438f4bf10d..757c7661f5 100644
--- a/drivers/windows/rw_lock_windows.cpp
+++ b/drivers/windows/rw_lock_windows.cpp
@@ -38,17 +38,14 @@
#include <stdio.h>
void RWLockWindows::read_lock() {
-
AcquireSRWLockShared(&lock);
}
void RWLockWindows::read_unlock() {
-
ReleaseSRWLockShared(&lock);
}
Error RWLockWindows::read_try_lock() {
-
if (TryAcquireSRWLockShared(&lock) == 0) {
return ERR_BUSY;
} else {
@@ -57,12 +54,10 @@ Error RWLockWindows::read_try_lock() {
}
void RWLockWindows::write_lock() {
-
AcquireSRWLockExclusive(&lock);
}
void RWLockWindows::write_unlock() {
-
ReleaseSRWLockExclusive(&lock);
}
@@ -75,17 +70,14 @@ Error RWLockWindows::write_try_lock() {
}
RWLock *RWLockWindows::create_func_windows() {
-
return memnew(RWLockWindows);
}
void RWLockWindows::make_default() {
-
create_func = create_func_windows;
}
RWLockWindows::RWLockWindows() {
-
InitializeSRWLock(&lock);
}
diff --git a/drivers/windows/rw_lock_windows.h b/drivers/windows/rw_lock_windows.h
index 3705c1eb38..61dd679d32 100644
--- a/drivers/windows/rw_lock_windows.h
+++ b/drivers/windows/rw_lock_windows.h
@@ -38,7 +38,6 @@
#include <windows.h>
class RWLockWindows : public RWLock {
-
SRWLOCK lock;
static RWLock *create_func_windows();
diff --git a/drivers/windows/thread_windows.cpp b/drivers/windows/thread_windows.cpp
index aea2db2603..ca7d936fac 100644
--- a/drivers/windows/thread_windows.cpp
+++ b/drivers/windows/thread_windows.cpp
@@ -35,17 +35,14 @@
#include "core/os/memory.h"
Thread::ID ThreadWindows::get_id() const {
-
return id;
}
Thread *ThreadWindows::create_thread_windows() {
-
return memnew(ThreadWindows);
}
DWORD ThreadWindows::thread_callback(LPVOID userdata) {
-
ThreadWindows *t = reinterpret_cast<ThreadWindows *>(userdata);
ScriptServer::thread_enter(); //scripts may need to attach a stack
@@ -60,7 +57,6 @@ DWORD ThreadWindows::thread_callback(LPVOID userdata) {
}
Thread *ThreadWindows::create_func_windows(ThreadCreateCallback p_callback, void *p_user, const Settings &) {
-
ThreadWindows *tr = memnew(ThreadWindows);
tr->callback = p_callback;
tr->user = p_user;
@@ -70,12 +66,12 @@ Thread *ThreadWindows::create_func_windows(ThreadCreateCallback p_callback, void
return tr;
}
-Thread::ID ThreadWindows::get_thread_id_func_windows() {
+Thread::ID ThreadWindows::get_thread_id_func_windows() {
return (ID)GetCurrentThreadId(); //must implement
}
-void ThreadWindows::wait_to_finish_func_windows(Thread *p_thread) {
+void ThreadWindows::wait_to_finish_func_windows(Thread *p_thread) {
ThreadWindows *tp = static_cast<ThreadWindows *>(p_thread);
ERR_FAIL_COND(!tp);
WaitForSingleObject(tp->handle, INFINITE);
@@ -84,17 +80,9 @@ void ThreadWindows::wait_to_finish_func_windows(Thread *p_thread) {
}
void ThreadWindows::make_default() {
-
create_func = create_func_windows;
get_thread_id_func = get_thread_id_func_windows;
wait_to_finish_func = wait_to_finish_func_windows;
}
-ThreadWindows::ThreadWindows() :
- handle(nullptr) {
-}
-
-ThreadWindows::~ThreadWindows() {
-}
-
#endif
diff --git a/drivers/windows/thread_windows.h b/drivers/windows/thread_windows.h
index 669956cd32..502c418ce0 100644
--- a/drivers/windows/thread_windows.h
+++ b/drivers/windows/thread_windows.h
@@ -39,11 +39,10 @@
#include <windows.h>
class ThreadWindows : public Thread {
-
ThreadCreateCallback callback;
void *user;
ID id;
- HANDLE handle;
+ HANDLE handle = nullptr;
static Thread *create_thread_windows();
@@ -53,14 +52,14 @@ class ThreadWindows : public Thread {
static ID get_thread_id_func_windows();
static void wait_to_finish_func_windows(Thread *p_thread);
- ThreadWindows();
+ ThreadWindows() {}
public:
virtual ID get_id() const;
static void make_default();
- ~ThreadWindows();
+ ~ThreadWindows() {}
};
#endif
diff --git a/drivers/winmidi/midi_driver_winmidi.cpp b/drivers/winmidi/midi_driver_winmidi.cpp
index 57fb9b0e57..9cbc7f43e2 100644
--- a/drivers/winmidi/midi_driver_winmidi.cpp
+++ b/drivers/winmidi/midi_driver_winmidi.cpp
@@ -35,14 +35,12 @@
#include "core/print_string.h"
void MIDIDriverWinMidi::read(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2) {
-
if (wMsg == MIM_DATA) {
receive_input_packet((uint64_t)dwParam2, (uint8_t *)&dwParam1, 3);
}
}
Error MIDIDriverWinMidi::open() {
-
for (UINT i = 0; i < midiInGetNumDevs(); i++) {
HMIDIIN midi_in;
@@ -67,7 +65,6 @@ Error MIDIDriverWinMidi::open() {
}
PackedStringArray MIDIDriverWinMidi::get_connected_inputs() {
-
PackedStringArray list;
for (int i = 0; i < connected_sources.size(); i++) {
@@ -87,7 +84,6 @@ PackedStringArray MIDIDriverWinMidi::get_connected_inputs() {
}
void MIDIDriverWinMidi::close() {
-
for (int i = 0; i < connected_sources.size(); i++) {
HMIDIIN midi_in = connected_sources[i];
midiInStop(midi_in);
@@ -100,7 +96,6 @@ MIDIDriverWinMidi::MIDIDriverWinMidi() {
}
MIDIDriverWinMidi::~MIDIDriverWinMidi() {
-
close();
}
diff --git a/drivers/winmidi/midi_driver_winmidi.h b/drivers/winmidi/midi_driver_winmidi.h
index c240c8c7aa..934eb5a493 100644
--- a/drivers/winmidi/midi_driver_winmidi.h
+++ b/drivers/winmidi/midi_driver_winmidi.h
@@ -42,7 +42,6 @@
#include <mmsystem.h>
class MIDIDriverWinMidi : public MIDIDriver {
-
Vector<HMIDIIN> connected_sources;
static void CALLBACK read(HMIDIIN hMidiIn, UINT wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
diff --git a/drivers/xaudio2/audio_driver_xaudio2.cpp b/drivers/xaudio2/audio_driver_xaudio2.cpp
index 120bfa2b36..421cf6a8cf 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.cpp
+++ b/drivers/xaudio2/audio_driver_xaudio2.cpp
@@ -38,19 +38,18 @@ const char *AudioDriverXAudio2::get_name() const {
}
Error AudioDriverXAudio2::init() {
-
active = false;
thread_exited = false;
exit_thread = false;
pcm_open = false;
samples_in = nullptr;
- mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+ mix_rate = GLOBAL_GET("audio/mix_rate");
// FIXME: speaker_mode seems unused in the Xaudio2 driver so far
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
- int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ int latency = GLOBAL_GET("audio/output_latency");
buffer_size = closest_power_of_2(latency * mix_rate / 1000);
samples_in = memnew_arr(int32_t, buffer_size * channels);
@@ -85,19 +84,15 @@ Error AudioDriverXAudio2::init() {
}
void AudioDriverXAudio2::thread_func(void *p_udata) {
-
AudioDriverXAudio2 *ad = (AudioDriverXAudio2 *)p_udata;
while (!ad->exit_thread) {
-
if (!ad->active) {
-
for (int i = 0; i < AUDIO_BUFFERS; i++) {
ad->xaudio_buffer[i].Flags = XAUDIO2_END_OF_STREAM;
}
} else {
-
ad->lock();
ad->audio_server_process(ad->buffer_size, ad->samples_in);
@@ -105,7 +100,6 @@ void AudioDriverXAudio2::thread_func(void *p_udata) {
ad->unlock();
for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) {
-
ad->samples_out[ad->current_buffer][i] = ad->samples_in[i] >> 16;
}
@@ -128,24 +122,20 @@ void AudioDriverXAudio2::thread_func(void *p_udata) {
}
void AudioDriverXAudio2::start() {
-
active = true;
HRESULT hr = source_voice->Start(0);
ERR_FAIL_COND_MSG(hr != S_OK, "Error starting XAudio2 driver. Error code: " + itos(hr) + ".");
}
int AudioDriverXAudio2::get_mix_rate() const {
-
return mix_rate;
}
AudioDriver::SpeakerMode AudioDriverXAudio2::get_speaker_mode() const {
-
return speaker_mode;
}
float AudioDriverXAudio2::get_latency() {
-
XAUDIO2_PERFORMANCE_DATA perf_data;
xaudio->GetPerformanceData(&perf_data);
if (perf_data.CurrentLatencyInSamples) {
@@ -156,20 +146,18 @@ float AudioDriverXAudio2::get_latency() {
}
void AudioDriverXAudio2::lock() {
-
if (!thread)
return;
mutex.lock();
}
-void AudioDriverXAudio2::unlock() {
+void AudioDriverXAudio2::unlock() {
if (!thread)
return;
mutex.unlock();
}
void AudioDriverXAudio2::finish() {
-
if (!thread)
return;
@@ -196,15 +184,9 @@ void AudioDriverXAudio2::finish() {
thread = nullptr;
}
-AudioDriverXAudio2::AudioDriverXAudio2() :
- thread(nullptr),
- current_buffer(0) {
- wave_format = { 0 };
+AudioDriverXAudio2::AudioDriverXAudio2() {
for (int i = 0; i < AUDIO_BUFFERS; i++) {
xaudio_buffer[i] = { 0 };
samples_out[i] = 0;
}
}
-
-AudioDriverXAudio2::~AudioDriverXAudio2() {
-}
diff --git a/drivers/xaudio2/audio_driver_xaudio2.h b/drivers/xaudio2/audio_driver_xaudio2.h
index eb4a6d6e95..7fc1bb428d 100644
--- a/drivers/xaudio2/audio_driver_xaudio2.h
+++ b/drivers/xaudio2/audio_driver_xaudio2.h
@@ -41,13 +41,11 @@
#include <xaudio2.h>
class AudioDriverXAudio2 : public AudioDriver {
-
enum {
AUDIO_BUFFERS = 2
};
struct XAudio2DriverVoiceCallback : public IXAudio2VoiceCallback {
-
HANDLE buffer_end_event;
XAudio2DriverVoiceCallback() :
buffer_end_event(CreateEvent(nullptr, FALSE, FALSE, nullptr)) {}
@@ -64,7 +62,7 @@ class AudioDriverXAudio2 : public AudioDriver {
void STDMETHODCALLTYPE OnVoiceError(void *pBufferContext, HRESULT Error) {}
};
- Thread *thread;
+ Thread *thread = nullptr;
Mutex mutex;
int32_t *samples_in;
@@ -83,9 +81,9 @@ class AudioDriverXAudio2 : public AudioDriver {
mutable bool exit_thread;
bool pcm_open;
- WAVEFORMATEX wave_format;
+ WAVEFORMATEX wave_format = { 0 };
Microsoft::WRL::ComPtr<IXAudio2> xaudio;
- int current_buffer;
+ int current_buffer = 0;
IXAudio2MasteringVoice *mastering_voice;
XAUDIO2_BUFFER xaudio_buffer[AUDIO_BUFFERS];
IXAudio2SourceVoice *source_voice;
@@ -104,7 +102,7 @@ public:
virtual void finish();
AudioDriverXAudio2();
- ~AudioDriverXAudio2();
+ ~AudioDriverXAudio2() {}
};
#endif
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index e6a020bf41..f880ece88b 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -51,7 +51,6 @@ static _FORCE_INLINE_ Vector2 _bezier_interp(real_t t, const Vector2 &start, con
}
void AnimationBezierTrackEdit::_draw_track(int p_track, const Color &p_color) {
-
float scale = timeline->get_zoom_scale();
int limit = timeline->get_name_limit();
int right_limit = get_size().width - timeline->get_buttons_width();
@@ -69,11 +68,11 @@ void AnimationBezierTrackEdit::_draw_track(int p_track, const Color &p_color) {
}
for (Map<float, int>::Element *E = key_order.front(); E; E = E->next()) {
-
int i = E->get();
- if (!E->next())
+ if (!E->next()) {
break;
+ }
int i_n = E->next()->get();
@@ -113,11 +112,13 @@ void AnimationBezierTrackEdit::_draw_track(int p_track, const Color &p_color) {
int to_x = (offset_n - timeline->get_value()) * scale + limit;
int point_end = to_x;
- if (from_x > right_limit) //not visible
+ if (from_x > right_limit) { //not visible
continue;
+ }
- if (to_x < limit) //not visible
+ if (to_x < limit) { //not visible
continue;
+ }
from_x = MAX(from_x, limit);
to_x = MIN(to_x, right_limit);
@@ -127,7 +128,6 @@ void AnimationBezierTrackEdit::_draw_track(int p_track, const Color &p_color) {
Vector2 prev_pos;
for (int j = from_x; j <= to_x; j++) {
-
float t = (j - limit) / scale + timeline->get_value();
float h;
@@ -144,7 +144,6 @@ void AnimationBezierTrackEdit::_draw_track(int p_track, const Color &p_color) {
//narrow high and low as much as possible
for (int k = 0; k < iterations; k++) {
-
middle = (low + high) / 2;
Vector2 interp = _bezier_interp(middle, start, out_handle, in_handle, end);
@@ -162,7 +161,7 @@ void AnimationBezierTrackEdit::_draw_track(int p_track, const Color &p_color) {
float c = (t - low_pos.x) / (high_pos.x - low_pos.x);
- h = low_pos.linear_interpolate(high_pos, c).y;
+ h = low_pos.lerp(high_pos, c).y;
}
h = _bezier_h_to_pixel(h);
@@ -183,37 +182,38 @@ void AnimationBezierTrackEdit::_draw_track(int p_track, const Color &p_color) {
}
void AnimationBezierTrackEdit::_draw_line_clipped(const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, int p_clip_left, int p_clip_right) {
-
Vector2 from = p_from;
Vector2 to = p_to;
- if (from.x == to.x)
+ if (from.x == to.x) {
return;
+ }
if (to.x < from.x) {
SWAP(to, from);
}
- if (to.x < p_clip_left)
+ if (to.x < p_clip_left) {
return;
+ }
- if (from.x > p_clip_right)
+ if (from.x > p_clip_right) {
return;
+ }
if (to.x > p_clip_right) {
float c = (p_clip_right - from.x) / (to.x - from.x);
- to = from.linear_interpolate(to, c);
+ to = from.lerp(to, c);
}
if (from.x < p_clip_left) {
float c = (p_clip_left - from.x) / (to.x - from.x);
- from = from.linear_interpolate(to, c);
+ from = from.lerp(to, c);
}
draw_line(from, to, p_color);
}
void AnimationBezierTrackEdit::_notification(int p_what) {
-
if (p_what == NOTIFICATION_THEME_CHANGED || p_what == NOTIFICATION_ENTER_TREE) {
bezier_icon = get_theme_icon("KeyBezierPoint", "EditorIcons");
bezier_handle_icon = get_theme_icon("KeyBezierHandle", "EditorIcons");
@@ -225,7 +225,6 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
}
}
if (p_what == NOTIFICATION_RESIZED) {
-
int right_limit = get_size().width - timeline->get_buttons_width();
int hsep = get_theme_constant("hseparation", "ItemList");
int vsep = get_theme_constant("vseparation", "ItemList");
@@ -234,8 +233,9 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
handle_mode_option->set_size(Vector2(timeline->get_buttons_width() - hsep * 2, handle_mode_option->get_combined_minimum_size().height));
}
if (p_what == NOTIFICATION_DRAW) {
- if (animation.is_null())
+ if (animation.is_null()) {
return;
+ }
int limit = timeline->get_name_limit();
@@ -316,11 +316,13 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
subtracks.clear();
for (int i = 0; i < animation->get_track_count(); i++) {
- if (animation->track_get_type(i) != Animation::TYPE_BEZIER)
+ if (animation->track_get_type(i) != Animation::TYPE_BEZIER) {
continue;
+ }
String path = animation->track_get_path(i);
- if (!path.begins_with(base_path))
+ if (!path.begins_with(base_path)) {
continue; //another node
+ }
path = path.replace_first(base_path, "");
Color cc = color;
@@ -365,16 +367,15 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
bool first = true;
int prev_iv = 0;
for (int i = font->get_height(); i < get_size().height; i++) {
-
float ofs = get_size().height / 2 - i;
ofs *= v_zoom;
ofs += v_scroll;
int iv = int(ofs / scale);
- if (ofs < 0)
+ if (ofs < 0) {
iv -= 1;
+ }
if (!first && iv != prev_iv) {
-
Color lc = linecolor;
lc.a *= 0.5;
draw_line(Point2(limit, i), Point2(right_limit, i), lc);
@@ -393,11 +394,9 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
float scale = timeline->get_zoom_scale();
Ref<Texture2D> point = get_theme_icon("KeyValue", "EditorIcons");
for (Map<int, Color>::Element *E = subtrack_colors.front(); E; E = E->next()) {
-
_draw_track(E->key(), E->get());
for (int i = 0; i < animation->track_get_key_count(E->key()); i++) {
-
float offset = animation->track_get_key_time(E->key(), i);
float value = animation->bezier_track_get_key_value(E->key(), i);
@@ -416,12 +415,10 @@ void AnimationBezierTrackEdit::_notification(int p_what) {
//draw editor handles
{
-
float scale = timeline->get_zoom_scale();
edit_points.clear();
for (int i = 0; i < animation->track_get_key_count(track); i++) {
-
float offset = animation->track_get_key_time(track, i);
float value = animation->bezier_track_get_key_value(track, i);
@@ -499,20 +496,20 @@ Ref<Animation> AnimationBezierTrackEdit::get_animation() const {
}
void AnimationBezierTrackEdit::set_animation_and_track(const Ref<Animation> &p_animation, int p_track) {
-
animation = p_animation;
track = p_track;
- if (is_connected_compat("select_key", editor, "_key_selected"))
+ if (is_connected_compat("select_key", editor, "_key_selected")) {
disconnect_compat("select_key", editor, "_key_selected");
- if (is_connected_compat("deselect_key", editor, "_key_deselected"))
+ }
+ if (is_connected_compat("deselect_key", editor, "_key_deselected")) {
disconnect_compat("deselect_key", editor, "_key_deselected");
+ }
connect_compat("select_key", editor, "_key_selected", varray(p_track), CONNECT_DEFERRED);
connect_compat("deselect_key", editor, "_key_deselected", varray(p_track), CONNECT_DEFERRED);
update();
}
Size2 AnimationBezierTrackEdit::get_minimum_size() const {
-
return Vector2(1, 1);
}
@@ -524,15 +521,16 @@ void AnimationBezierTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) {
timeline = p_timeline;
timeline->connect("zoom_changed", callable_mp(this, &AnimationBezierTrackEdit::_zoom_changed));
}
+
void AnimationBezierTrackEdit::set_editor(AnimationTrackEditor *p_editor) {
editor = p_editor;
connect_compat("clear_selection", editor, "_clear_selection", varray(false));
}
void AnimationBezierTrackEdit::_play_position_draw() {
-
- if (!animation.is_valid() || play_position_pos < 0)
+ if (!animation.is_valid() || play_position_pos < 0) {
return;
+ }
float scale = timeline->get_zoom_scale();
int h = get_size().height;
@@ -546,7 +544,6 @@ void AnimationBezierTrackEdit::_play_position_draw() {
}
void AnimationBezierTrackEdit::set_play_position(float p_pos) {
-
play_position_pos = p_pos;
play_position->update();
}
@@ -558,12 +555,12 @@ void AnimationBezierTrackEdit::update_play_position() {
void AnimationBezierTrackEdit::set_root(Node *p_root) {
root = p_root;
}
+
void AnimationBezierTrackEdit::_zoom_changed() {
update();
}
String AnimationBezierTrackEdit::get_tooltip(const Point2 &p_pos) const {
-
return Control::get_tooltip(p_pos);
}
@@ -574,17 +571,17 @@ void AnimationBezierTrackEdit::_clear_selection() {
}
void AnimationBezierTrackEdit::_clear_selection_for_anim(const Ref<Animation> &p_anim) {
-
- if (!(animation == p_anim))
+ if (!(animation == p_anim)) {
return;
+ }
//selection.clear();
_clear_selection();
}
void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int p_track, float p_pos) {
-
- if (!(animation == p_anim))
+ if (!(animation == p_anim)) {
return;
+ }
int idx = animation->track_find_key(p_track, p_pos, true);
ERR_FAIL_COND(idx < 0);
@@ -595,7 +592,6 @@ void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int
}
void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
-
if (p_event->is_pressed()) {
if (ED_GET_SHORTCUT("animation_editor/duplicate_selection")->is_shortcut(p_event)) {
duplicate_selection();
@@ -636,7 +632,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (mb.is_valid() && mb->get_button_index() == BUTTON_MIDDLE) {
-
if (mb->is_pressed()) {
int x = mb->get_position().x - timeline->get_name_limit();
panning_timeline_from = x / timeline->get_zoom_scale();
@@ -648,7 +643,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (mb.is_valid() && mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
-
menu_insert_key = mb->get_position();
if (menu_insert_key.x >= timeline->get_name_limit() && menu_insert_key.x <= get_size().width - timeline->get_buttons_width()) {
Vector2 popup_pos = get_global_transform().xform(mb->get_position());
@@ -669,7 +663,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
if (close_icon_rect.has_point(mb->get_position())) {
emit_signal("close_request");
return;
@@ -683,7 +676,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
for (int i = 0; i < edit_points.size(); i++) {
-
//first check point
//command makes it ignore the main point, so control point editors can be force-edited
//path 2D editing in the 3D and 2D editors works the same way
@@ -706,7 +698,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
select_single_attempt = i;
update();
} else {
-
moving_selection_attempt = true;
moving_selection = true;
moving_selection_from_key = i;
@@ -741,7 +732,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
//insert new point
if (mb->get_command() && mb->get_position().x >= timeline->get_name_limit() && mb->get_position().x < get_size().width - timeline->get_buttons_width()) {
-
Array new_point;
new_point.resize(5);
@@ -790,7 +780,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (box_selecting_attempt && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
if (box_selecting) {
//do actual select
if (!box_selecting_add) {
@@ -808,7 +797,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
Rect2 selection_rect(bs_from, bs_to - bs_from);
for (int i = 0; i < edit_points.size(); i++) {
-
if (edit_points[i].point_rect.intersects(selection_rect)) {
selection.insert(i);
}
@@ -822,7 +810,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (moving_handle != 0 && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
undo_redo->create_action(TTR("Move Bezier Points"));
undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_in_handle", track, moving_handle_key, moving_handle_left);
undo_redo->add_do_method(animation.ptr(), "bezier_track_set_key_out_handle", track, moving_handle_key, moving_handle_right);
@@ -835,7 +822,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (moving_selection_attempt && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
if (moving_selection) {
//combit it
@@ -844,20 +830,20 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
List<AnimMoveRestore> to_restore;
// 1-remove the keys
for (Set<int>::Element *E = selection.back(); E; E = E->prev()) {
-
undo_redo->add_do_method(animation.ptr(), "track_remove_key", track, E->get());
}
// 2- remove overlapped keys
for (Set<int>::Element *E = selection.back(); E; E = E->prev()) {
-
float newtime = editor->snap_time(animation->track_get_key_time(track, E->get()) + moving_selection_offset.x);
int idx = animation->track_find_key(track, newtime, true);
- if (idx == -1)
+ if (idx == -1) {
continue;
+ }
- if (selection.has(idx))
+ if (selection.has(idx)) {
continue; //already in selection, don't save
+ }
undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_position", track, newtime);
AnimMoveRestore amr;
@@ -871,7 +857,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
// 3-move the keys (re insert them)
for (Set<int>::Element *E = selection.back(); E; E = E->prev()) {
-
float newpos = editor->snap_time(animation->track_get_key_time(track, E->get()) + moving_selection_offset.x);
/*
if (newpos<0)
@@ -886,7 +871,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
// 4-(undo) remove inserted keys
for (Set<int>::Element *E = selection.back(); E; E = E->prev()) {
-
float newpos = editor->snap_time(animation->track_get_key_time(track, E->get()) + moving_selection_offset.x);
/*
if (newpos<0)
@@ -897,14 +881,12 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
// 5-(undo) reinsert keys
for (Set<int>::Element *E = selection.back(); E; E = E->prev()) {
-
float oldpos = animation->track_get_key_time(track, E->get());
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, oldpos, animation->track_get_key_value(track, E->get()), 1);
}
// 6-(undo) reinsert overlapped keys
for (List<AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) {
-
AnimMoveRestore &amr = E->get();
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, 1);
}
@@ -915,7 +897,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
// 7-reselect
for (Set<int>::Element *E = selection.back(); E; E = E->prev()) {
-
float oldpos = animation->track_get_key_time(track, E->get());
float newpos = editor->snap_time(oldpos + moving_selection_offset.x);
@@ -938,10 +919,12 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_MIDDLE) {
v_scroll += mm->get_relative().y * v_zoom;
- if (v_scroll > 100000)
+ if (v_scroll > 100000) {
v_scroll = 100000;
- if (v_scroll < -100000)
+ }
+ if (v_scroll < -100000) {
v_scroll = -100000;
+ }
int x = mm->get_position().x - timeline->get_name_limit();
float ofs = x / timeline->get_zoom_scale();
@@ -951,7 +934,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
update();
}
if (moving_selection_attempt && mm.is_valid()) {
-
if (!moving_selection) {
moving_selection = true;
select_single_attempt = -1;
@@ -965,7 +947,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (box_selecting_attempt && mm.is_valid()) {
-
if (!box_selecting) {
box_selecting = true;
box_selecting_add = mm->get_shift();
@@ -981,7 +962,6 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (moving_handle != 0 && mm.is_valid()) {
-
float y = (get_size().height / 2 - mm->get_position().y) * v_zoom + v_scroll;
float x = ((mm->get_position().x - timeline->get_name_limit()) / timeline->get_zoom_scale()) + timeline->get_value();
@@ -1026,10 +1006,8 @@ void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
void AnimationBezierTrackEdit::_menu_selected(int p_index) {
-
switch (p_index) {
case MENU_KEY_INSERT: {
-
Array new_point;
new_point.resize(5);
@@ -1062,16 +1040,16 @@ void AnimationBezierTrackEdit::_menu_selected(int p_index) {
}
void AnimationBezierTrackEdit::duplicate_selection() {
-
- if (selection.size() == 0)
+ if (selection.size() == 0) {
return;
+ }
float top_time = 1e10;
for (Set<int>::Element *E = selection.back(); E; E = E->prev()) {
-
float t = animation->track_get_key_time(track, E->get());
- if (t < top_time)
+ if (t < top_time) {
top_time = t;
+ }
}
undo_redo->create_action(TTR("Anim Duplicate Keys"));
@@ -1079,7 +1057,6 @@ void AnimationBezierTrackEdit::duplicate_selection() {
List<Pair<int, float>> new_selection_values;
for (Set<int>::Element *E = selection.back(); E; E = E->prev()) {
-
float t = animation->track_get_key_time(track, E->get());
float dst_time = t + (timeline->get_play_position() - top_time);
int existing_idx = animation->track_find_key(track, dst_time, true);
@@ -1093,7 +1070,6 @@ void AnimationBezierTrackEdit::duplicate_selection() {
new_selection_values.push_back(p);
if (existing_idx != -1) {
-
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, dst_time, animation->track_get_key_value(track, existing_idx), animation->track_get_key_transition(track, existing_idx));
}
}
@@ -1104,14 +1080,14 @@ void AnimationBezierTrackEdit::duplicate_selection() {
selection.clear();
for (List<Pair<int, float>>::Element *E = new_selection_values.front(); E; E = E->next()) {
-
int track = E->get().first;
float time = E->get().second;
int existing_idx = animation->track_find_key(track, time, true);
- if (existing_idx == -1)
+ if (existing_idx == -1) {
continue;
+ }
selection.insert(existing_idx);
}
@@ -1124,7 +1100,6 @@ void AnimationBezierTrackEdit::delete_selection() {
undo_redo->create_action(TTR("Anim Delete Keys"));
for (Set<int>::Element *E = selection.back(); E; E = E->prev()) {
-
undo_redo->add_do_method(animation.ptr(), "track_remove_key", track, E->get());
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, animation->track_get_key_time(track, E->get()), animation->track_get_key_value(track, E->get()), 1);
}
@@ -1140,7 +1115,6 @@ void AnimationBezierTrackEdit::set_block_animation_update_ptr(bool *p_block_ptr)
}
void AnimationBezierTrackEdit::_bind_methods() {
-
ClassDB::bind_method("_gui_input", &AnimationBezierTrackEdit::_gui_input);
ClassDB::bind_method("_clear_selection", &AnimationBezierTrackEdit::_clear_selection);
diff --git a/editor/animation_bezier_editor.h b/editor/animation_bezier_editor.h
index 2be388fd57..1c1cde47b4 100644
--- a/editor/animation_bezier_editor.h
+++ b/editor/animation_bezier_editor.h
@@ -34,7 +34,6 @@
#include "animation_track_editor.h"
class AnimationBezierTrackEdit : public Control {
-
GDCLASS(AnimationBezierTrackEdit, Control);
enum HandleMode {
@@ -112,7 +111,6 @@ class AnimationBezierTrackEdit : public Control {
Vector2 menu_insert_key;
struct AnimMoveRestore {
-
int track;
float time;
Variant key;
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index f10e439f10..2a8e0d856e 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -31,7 +31,7 @@
#include "animation_track_editor.h"
#include "animation_track_editor_plugins.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/keyboard.h"
#include "editor/animation_bezier_editor.h"
#include "editor/plugins/animation_player_editor_plugin.h"
@@ -41,7 +41,6 @@
#include "servers/audio/audio_stream.h"
class AnimationTrackKeyEdit : public Object {
-
GDCLASS(AnimationTrackKeyEdit, Object);
public:
@@ -56,7 +55,6 @@ public:
}
static void _bind_methods() {
-
ClassDB::bind_method("_update_obj", &AnimationTrackKeyEdit::_update_obj);
ClassDB::bind_method("_key_ofs_changed", &AnimationTrackKeyEdit::_key_ofs_changed);
ClassDB::bind_method("_hide_script_from_inspector", &AnimationTrackKeyEdit::_hide_script_from_inspector);
@@ -65,11 +63,11 @@ public:
}
void _fix_node_path(Variant &value) {
-
NodePath np = value;
- if (np == NodePath())
+ if (np == NodePath()) {
return;
+ }
Node *root = EditorNode::get_singleton()->get_tree()->get_root();
@@ -83,34 +81,33 @@ public:
}
void _update_obj(const Ref<Animation> &p_anim) {
-
- if (setting || animation != p_anim)
+ if (setting || animation != p_anim) {
return;
+ }
notify_change();
}
void _key_ofs_changed(const Ref<Animation> &p_anim, float from, float to) {
-
- if (animation != p_anim || from != key_ofs)
+ if (animation != p_anim || from != key_ofs) {
return;
+ }
key_ofs = to;
- if (setting)
+ if (setting) {
return;
+ }
notify_change();
}
bool _set(const StringName &p_name, const Variant &p_value) {
-
int key = animation->track_find_key(track, key_ofs, true);
ERR_FAIL_COND_V(key == -1, false);
String name = p_name;
if (name == "time" || name == "frame") {
-
float new_time = p_value;
if (name == "frame") {
@@ -121,8 +118,9 @@ public:
new_time /= fps;
}
- if (new_time == key_ofs)
+ if (new_time == key_ofs) {
return true;
+ }
int existing = animation->track_find_key(track, new_time, true);
@@ -151,7 +149,6 @@ public:
}
if (name == "easing") {
-
float val = p_value;
float prev_val = animation->track_get_key_transition(track, key);
setting = true;
@@ -167,9 +164,7 @@ public:
}
switch (animation->track_get_type(track)) {
-
case Animation::TYPE_TRANSFORM: {
-
Dictionary d_old = animation->track_get_key_value(track, key);
Dictionary d_new = d_old.duplicate();
d_new[p_name] = p_value;
@@ -185,9 +180,7 @@ public:
return true;
} break;
case Animation::TYPE_VALUE: {
-
if (name == "value") {
-
Variant value = p_value;
if (value.get_type() == Variant::NODE_PATH) {
@@ -208,7 +201,6 @@ public:
}
} break;
case Animation::TYPE_METHOD: {
-
Dictionary d_old = animation->track_get_key_value(track, key);
Dictionary d_new = d_old.duplicate();
@@ -216,16 +208,13 @@ public:
bool mergeable = false;
if (name == "name") {
-
d_new["method"] = p_value;
} else if (name == "arg_count") {
-
Vector<Variant> args = d_old["args"];
args.resize(p_value);
d_new["args"] = args;
change_notify_deserved = true;
} else if (name.begins_with("args/")) {
-
Vector<Variant> args = d_old["args"];
int idx = name.get_slice("/", 1).to_int();
ERR_FAIL_INDEX_V(idx, args.size(), false);
@@ -241,17 +230,14 @@ public:
Variant *ptrs[1] = { &old };
args.write[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err);
} else {
-
args.write[idx] = Variant::construct(t, nullptr, 0, err);
}
change_notify_deserved = true;
d_new["args"] = args;
}
} else if (what == "value") {
-
Variant value = p_value;
if (value.get_type() == Variant::NODE_PATH) {
-
_fix_node_path(value);
}
@@ -261,10 +247,11 @@ public:
}
}
- if (mergeable)
+ if (mergeable) {
undo_redo->create_action(TTR("Anim Change Call"), UndoRedo::MERGE_ENDS);
- else
+ } else {
undo_redo->create_action(TTR("Anim Change Call"));
+ }
setting = true;
undo_redo->add_do_method(animation.ptr(), "track_set_key_value", track, key, d_new);
@@ -274,14 +261,13 @@ public:
undo_redo->commit_action();
setting = false;
- if (change_notify_deserved)
+ if (change_notify_deserved) {
notify_change();
+ }
return true;
} break;
case Animation::TYPE_BEZIER: {
-
if (name == "value") {
-
const Variant &value = p_value;
setting = true;
@@ -298,7 +284,6 @@ public:
}
if (name == "in_handle") {
-
const Variant &value = p_value;
setting = true;
@@ -315,7 +300,6 @@ public:
}
if (name == "out_handle") {
-
const Variant &value = p_value;
setting = true;
@@ -332,9 +316,7 @@ public:
}
} break;
case Animation::TYPE_AUDIO: {
-
if (name == "stream") {
-
Ref<AudioStream> stream = p_value;
setting = true;
@@ -351,7 +333,6 @@ public:
}
if (name == "start_offset") {
-
float value = p_value;
setting = true;
@@ -368,7 +349,6 @@ public:
}
if (name == "end_offset") {
-
float value = p_value;
setting = true;
@@ -385,9 +365,7 @@ public:
}
} break;
case Animation::TYPE_ANIMATION: {
-
if (name == "animation") {
-
StringName anim_name = p_value;
setting = true;
@@ -409,7 +387,6 @@ public:
}
bool _get(const StringName &p_name, Variant &r_ret) const {
-
int key = animation->track_find_key(track, key_ofs, true);
ERR_FAIL_COND_V(key == -1, false);
@@ -420,7 +397,6 @@ public:
}
if (name == "frame") {
-
float fps = animation->get_step();
if (fps > 0) {
fps = 1.0 / fps;
@@ -436,7 +412,6 @@ public:
switch (animation->track_get_type(track)) {
case Animation::TYPE_TRANSFORM: {
-
Dictionary d = animation->track_get_key_value(track, key);
ERR_FAIL_COND_V(!d.has(name), false);
r_ret = d[p_name];
@@ -444,7 +419,6 @@ public:
} break;
case Animation::TYPE_VALUE: {
-
if (name == "value") {
r_ret = animation->track_get_key_value(track, key);
return true;
@@ -452,11 +426,9 @@ public:
} break;
case Animation::TYPE_METHOD: {
-
Dictionary d = animation->track_get_key_value(track, key);
if (name == "name") {
-
ERR_FAIL_COND_V(!d.has("method"), false);
r_ret = d["method"];
return true;
@@ -472,7 +444,6 @@ public:
}
if (name.begins_with("args/")) {
-
int idx = name.get_slice("/", 1).to_int();
ERR_FAIL_INDEX_V(idx, args.size(), false);
@@ -490,7 +461,6 @@ public:
} break;
case Animation::TYPE_BEZIER: {
-
if (name == "value") {
r_ret = animation->bezier_track_get_key_value(track, key);
return true;
@@ -508,7 +478,6 @@ public:
} break;
case Animation::TYPE_AUDIO: {
-
if (name == "stream") {
r_ret = animation->audio_track_get_key_stream(track, key);
return true;
@@ -526,7 +495,6 @@ public:
} break;
case Animation::TYPE_ANIMATION: {
-
if (name == "animation") {
r_ret = animation->animation_track_get_key_animation(track, key);
return true;
@@ -538,9 +506,9 @@ public:
return false;
}
void _get_property_list(List<PropertyInfo> *p_list) const {
-
- if (animation.is_null())
+ if (animation.is_null()) {
return;
+ }
ERR_FAIL_INDEX(track, animation->get_track_count());
int key = animation->track_find_key(track, key_ofs, true);
@@ -554,25 +522,20 @@ public:
}
switch (animation->track_get_type(track)) {
-
case Animation::TYPE_TRANSFORM: {
-
p_list->push_back(PropertyInfo(Variant::VECTOR3, "location"));
p_list->push_back(PropertyInfo(Variant::QUAT, "rotation"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "scale"));
} break;
case Animation::TYPE_VALUE: {
-
Variant v = animation->track_get_key_value(track, key);
if (hint.type != Variant::NIL) {
-
PropertyInfo pi = hint;
pi.name = "value";
p_list->push_back(pi);
} else {
-
PropertyHint hint = PROPERTY_HINT_NONE;
String hint_string;
@@ -580,19 +543,18 @@ public:
//could actually check the object property if exists..? yes i will!
Ref<Resource> res = v;
if (res.is_valid()) {
-
hint = PROPERTY_HINT_RESOURCE_TYPE;
hint_string = res->get_class();
}
}
- if (v.get_type() != Variant::NIL)
+ if (v.get_type() != Variant::NIL) {
p_list->push_back(PropertyInfo(v.get_type(), "value", hint, hint_string));
+ }
}
} break;
case Animation::TYPE_METHOD: {
-
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "name"));
p_list->push_back(PropertyInfo(Variant::INT, "arg_count", PROPERTY_HINT_RANGE, "0,5,1"));
@@ -601,40 +563,36 @@ public:
Vector<Variant> args = d["args"];
String vtypes;
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
-
- if (i > 0)
+ if (i > 0) {
vtypes += ",";
+ }
vtypes += Variant::get_type_name(Variant::Type(i));
}
for (int i = 0; i < args.size(); i++) {
-
p_list->push_back(PropertyInfo(Variant::INT, "args/" + itos(i) + "/type", PROPERTY_HINT_ENUM, vtypes));
- if (args[i].get_type() != Variant::NIL)
+ if (args[i].get_type() != Variant::NIL) {
p_list->push_back(PropertyInfo(args[i].get_type(), "args/" + itos(i) + "/value"));
+ }
}
} break;
case Animation::TYPE_BEZIER: {
-
p_list->push_back(PropertyInfo(Variant::FLOAT, "value"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "in_handle"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "out_handle"));
} break;
case Animation::TYPE_AUDIO: {
-
p_list->push_back(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"));
p_list->push_back(PropertyInfo(Variant::FLOAT, "start_offset", PROPERTY_HINT_RANGE, "0,3600,0.01,or_greater"));
p_list->push_back(PropertyInfo(Variant::FLOAT, "end_offset", PROPERTY_HINT_RANGE, "0,3600,0.01,or_greater"));
} break;
case Animation::TYPE_ANIMATION: {
-
String animations;
if (root_path && root_path->has_node(animation->track_get_path(track))) {
-
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(root_path->get_node(animation->track_get_path(track)));
if (ap) {
List<StringName> anims;
@@ -675,7 +633,6 @@ public:
bool use_fps;
void notify_change() {
-
_change_notify();
}
@@ -698,7 +655,6 @@ public:
};
class AnimationMultiTrackKeyEdit : public Object {
-
GDCLASS(AnimationMultiTrackKeyEdit, Object);
public:
@@ -713,7 +669,6 @@ public:
}
static void _bind_methods() {
-
ClassDB::bind_method("_update_obj", &AnimationMultiTrackKeyEdit::_update_obj);
ClassDB::bind_method("_key_ofs_changed", &AnimationMultiTrackKeyEdit::_key_ofs_changed);
ClassDB::bind_method("_hide_script_from_inspector", &AnimationMultiTrackKeyEdit::_hide_script_from_inspector);
@@ -722,11 +677,11 @@ public:
}
void _fix_node_path(Variant &value, NodePath &base) {
-
NodePath np = value;
- if (np == NodePath())
+ if (np == NodePath()) {
return;
+ }
Node *root = EditorNode::get_singleton()->get_tree()->get_root();
@@ -740,31 +695,33 @@ public:
}
void _update_obj(const Ref<Animation> &p_anim) {
-
- if (setting || animation != p_anim)
+ if (setting || animation != p_anim) {
return;
+ }
notify_change();
}
void _key_ofs_changed(const Ref<Animation> &p_anim, float from, float to) {
-
- if (animation != p_anim)
+ if (animation != p_anim) {
return;
+ }
for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) {
-
+ int key = 0;
for (List<float>::Element *F = E->value().front(); F; F = F->next()) {
-
float key_ofs = F->get();
- if (from != key_ofs)
+ if (from != key_ofs) {
+ key++;
continue;
+ }
int track = E->key();
- key_ofs_map[track][key_ofs] = to;
+ key_ofs_map[track][key] = to;
- if (setting)
+ if (setting) {
return;
+ }
notify_change();
@@ -774,21 +731,17 @@ public:
}
bool _set(const StringName &p_name, const Variant &p_value) {
-
bool update_obj = false;
bool change_notify_deserved = false;
for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) {
-
int track = E->key();
for (List<float>::Element *F = E->value().front(); F; F = F->next()) {
-
float key_ofs = F->get();
int key = animation->track_find_key(track, key_ofs, true);
ERR_FAIL_COND_V(key == -1, false);
String name = p_name;
if (name == "time" || name == "frame") {
-
float new_time = p_value;
if (name == "frame") {
@@ -822,7 +775,6 @@ public:
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", track, new_time, v, trans);
}
} else if (name == "easing") {
-
float val = p_value;
float prev_val = animation->track_get_key_transition(track, key);
@@ -836,9 +788,7 @@ public:
}
switch (animation->track_get_type(track)) {
-
case Animation::TYPE_TRANSFORM: {
-
Dictionary d_old = animation->track_get_key_value(track, key);
Dictionary d_new = d_old.duplicate();
d_new[p_name] = p_value;
@@ -852,9 +802,7 @@ public:
update_obj = true;
} break;
case Animation::TYPE_VALUE: {
-
if (name == "value") {
-
Variant value = p_value;
if (value.get_type() == Variant::NODE_PATH) {
@@ -872,23 +820,19 @@ public:
}
} break;
case Animation::TYPE_METHOD: {
-
Dictionary d_old = animation->track_get_key_value(track, key);
Dictionary d_new = d_old.duplicate();
bool mergeable = false;
if (name == "name") {
-
d_new["method"] = p_value;
} else if (name == "arg_count") {
-
Vector<Variant> args = d_old["args"];
args.resize(p_value);
d_new["args"] = args;
change_notify_deserved = true;
} else if (name.begins_with("args/")) {
-
Vector<Variant> args = d_old["args"];
int idx = name.get_slice("/", 1).to_int();
ERR_FAIL_INDEX_V(idx, args.size(), false);
@@ -904,17 +848,14 @@ public:
Variant *ptrs[1] = { &old };
args.write[idx] = Variant::construct(t, (const Variant **)ptrs, 1, err);
} else {
-
args.write[idx] = Variant::construct(t, nullptr, 0, err);
}
change_notify_deserved = true;
d_new["args"] = args;
}
} else if (what == "value") {
-
Variant value = p_value;
if (value.get_type() == Variant::NODE_PATH) {
-
_fix_node_path(value, base_map[track]);
}
@@ -927,10 +868,11 @@ public:
Variant prev = animation->track_get_key_value(track, key);
if (!setting) {
- if (mergeable)
+ if (mergeable) {
undo_redo->create_action(TTR("Anim Multi Change Call"), UndoRedo::MERGE_ENDS);
- else
+ } else {
undo_redo->create_action(TTR("Anim Multi Change Call"));
+ }
setting = true;
}
@@ -940,9 +882,7 @@ public:
update_obj = true;
} break;
case Animation::TYPE_BEZIER: {
-
if (name == "value") {
-
const Variant &value = p_value;
if (!setting) {
@@ -954,7 +894,6 @@ public:
undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_value", track, key, prev);
update_obj = true;
} else if (name == "in_handle") {
-
const Variant &value = p_value;
if (!setting) {
@@ -966,7 +905,6 @@ public:
undo_redo->add_undo_method(animation.ptr(), "bezier_track_set_key_in_handle", track, key, prev);
update_obj = true;
} else if (name == "out_handle") {
-
const Variant &value = p_value;
if (!setting) {
@@ -980,9 +918,7 @@ public:
}
} break;
case Animation::TYPE_AUDIO: {
-
if (name == "stream") {
-
Ref<AudioStream> stream = p_value;
if (!setting) {
@@ -994,7 +930,6 @@ public:
undo_redo->add_undo_method(animation.ptr(), "audio_track_set_key_stream", track, key, prev);
update_obj = true;
} else if (name == "start_offset") {
-
float value = p_value;
if (!setting) {
@@ -1006,7 +941,6 @@ public:
undo_redo->add_undo_method(animation.ptr(), "audio_track_set_key_start_offset", track, key, prev);
update_obj = true;
} else if (name == "end_offset") {
-
float value = p_value;
if (!setting) {
@@ -1020,9 +954,7 @@ public:
}
} break;
case Animation::TYPE_ANIMATION: {
-
if (name == "animation") {
-
StringName anim_name = p_value;
if (!setting) {
@@ -1040,7 +972,6 @@ public:
}
if (setting) {
-
if (update_obj) {
undo_redo->add_do_method(this, "_update_obj", animation);
undo_redo->add_undo_method(this, "_update_obj", animation);
@@ -1049,8 +980,9 @@ public:
undo_redo->commit_action();
setting = false;
- if (change_notify_deserved)
+ if (change_notify_deserved) {
notify_change();
+ }
return true;
}
@@ -1059,12 +991,9 @@ public:
}
bool _get(const StringName &p_name, Variant &r_ret) const {
-
for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) {
-
int track = E->key();
for (List<float>::Element *F = E->value().front(); F; F = F->next()) {
-
float key_ofs = F->get();
int key = animation->track_find_key(track, key_ofs, true);
ERR_CONTINUE(key == -1);
@@ -1076,7 +1005,6 @@ public:
}
if (name == "frame") {
-
float fps = animation->get_step();
if (fps > 0) {
fps = 1.0 / fps;
@@ -1091,9 +1019,7 @@ public:
}
switch (animation->track_get_type(track)) {
-
case Animation::TYPE_TRANSFORM: {
-
Dictionary d = animation->track_get_key_value(track, key);
ERR_FAIL_COND_V(!d.has(name), false);
r_ret = d[p_name];
@@ -1101,7 +1027,6 @@ public:
} break;
case Animation::TYPE_VALUE: {
-
if (name == "value") {
r_ret = animation->track_get_key_value(track, key);
return true;
@@ -1109,11 +1034,9 @@ public:
} break;
case Animation::TYPE_METHOD: {
-
Dictionary d = animation->track_get_key_value(track, key);
if (name == "name") {
-
ERR_FAIL_COND_V(!d.has("method"), false);
r_ret = d["method"];
return true;
@@ -1124,13 +1047,11 @@ public:
Vector<Variant> args = d["args"];
if (name == "arg_count") {
-
r_ret = args.size();
return true;
}
if (name.begins_with("args/")) {
-
int idx = name.get_slice("/", 1).to_int();
ERR_FAIL_INDEX_V(idx, args.size(), false);
@@ -1148,7 +1069,6 @@ public:
} break;
case Animation::TYPE_BEZIER: {
-
if (name == "value") {
r_ret = animation->bezier_track_get_key_value(track, key);
return true;
@@ -1166,7 +1086,6 @@ public:
} break;
case Animation::TYPE_AUDIO: {
-
if (name == "stream") {
r_ret = animation->audio_track_get_key_stream(track, key);
return true;
@@ -1184,7 +1103,6 @@ public:
} break;
case Animation::TYPE_ANIMATION: {
-
if (name == "animation") {
r_ret = animation->animation_track_get_key_animation(track, key);
return true;
@@ -1198,9 +1116,9 @@ public:
return false;
}
void _get_property_list(List<PropertyInfo> *p_list) const {
-
- if (animation.is_null())
+ if (animation.is_null()) {
return;
+ }
int first_track = -1;
float first_key = -1.0;
@@ -1209,38 +1127,38 @@ public:
bool same_track_type = true;
bool same_key_type = true;
for (Map<int, List<float>>::Element *E = key_ofs_map.front(); E; E = E->next()) {
-
int track = E->key();
ERR_FAIL_INDEX(track, animation->get_track_count());
- if (first_track < 0)
+ if (first_track < 0) {
first_track = track;
+ }
- if (show_time && E->value().size() > 1)
+ if (show_time && E->value().size() > 1) {
show_time = false;
+ }
if (same_track_type) {
-
if (animation->track_get_type(first_track) != animation->track_get_type(track)) {
same_track_type = false;
same_key_type = false;
}
for (List<float>::Element *F = E->value().front(); F; F = F->next()) {
-
int key = animation->track_find_key(track, F->get(), true);
ERR_FAIL_COND(key == -1);
- if (first_key < 0)
+ if (first_key < 0) {
first_key = key;
+ }
- if (animation->track_get_key_value(first_track, first_key).get_type() != animation->track_get_key_value(track, key).get_type())
+ if (animation->track_get_key_value(first_track, first_key).get_type() != animation->track_get_key_value(track, key).get_type()) {
same_key_type = false;
+ }
}
}
}
if (show_time) {
-
if (use_fps && animation->get_step() > 0) {
float max_frame = animation->get_length() / animation->get_step();
p_list->push_back(PropertyInfo(Variant::FLOAT, "frame", PROPERTY_HINT_RANGE, "0," + rtos(max_frame) + ",1"));
@@ -1251,27 +1169,23 @@ public:
if (same_track_type) {
switch (animation->track_get_type(first_track)) {
-
case Animation::TYPE_TRANSFORM: {
-
p_list->push_back(PropertyInfo(Variant::VECTOR3, "location"));
p_list->push_back(PropertyInfo(Variant::QUAT, "rotation"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "scale"));
} break;
case Animation::TYPE_VALUE: {
-
- if (!same_key_type)
+ if (!same_key_type) {
break;
+ }
Variant v = animation->track_get_key_value(first_track, first_key);
if (hint.type != Variant::NIL) {
-
PropertyInfo pi = hint;
pi.name = "value";
p_list->push_back(pi);
} else {
-
PropertyHint hint = PROPERTY_HINT_NONE;
String hint_string;
@@ -1279,20 +1193,19 @@ public:
//could actually check the object property if exists..? yes i will!
Ref<Resource> res = v;
if (res.is_valid()) {
-
hint = PROPERTY_HINT_RESOURCE_TYPE;
hint_string = res->get_class();
}
}
- if (v.get_type() != Variant::NIL)
+ if (v.get_type() != Variant::NIL) {
p_list->push_back(PropertyInfo(v.get_type(), "value", hint, hint_string));
+ }
}
p_list->push_back(PropertyInfo(Variant::FLOAT, "easing", PROPERTY_HINT_EXP_EASING));
} break;
case Animation::TYPE_METHOD: {
-
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "name"));
p_list->push_back(PropertyInfo(Variant::INT, "arg_count", PROPERTY_HINT_RANGE, "0,5,1"));
@@ -1301,40 +1214,37 @@ public:
Vector<Variant> args = d["args"];
String vtypes;
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
-
- if (i > 0)
+ if (i > 0) {
vtypes += ",";
+ }
vtypes += Variant::get_type_name(Variant::Type(i));
}
for (int i = 0; i < args.size(); i++) {
-
p_list->push_back(PropertyInfo(Variant::INT, "args/" + itos(i) + "/type", PROPERTY_HINT_ENUM, vtypes));
- if (args[i].get_type() != Variant::NIL)
+ if (args[i].get_type() != Variant::NIL) {
p_list->push_back(PropertyInfo(args[i].get_type(), "args/" + itos(i) + "/value"));
+ }
}
} break;
case Animation::TYPE_BEZIER: {
-
p_list->push_back(PropertyInfo(Variant::FLOAT, "value"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "in_handle"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "out_handle"));
} break;
case Animation::TYPE_AUDIO: {
-
p_list->push_back(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"));
p_list->push_back(PropertyInfo(Variant::FLOAT, "start_offset", PROPERTY_HINT_RANGE, "0,3600,0.01,or_greater"));
p_list->push_back(PropertyInfo(Variant::FLOAT, "end_offset", PROPERTY_HINT_RANGE, "0,3600,0.01,or_greater"));
} break;
case Animation::TYPE_ANIMATION: {
-
- if (key_ofs_map.size() > 1)
+ if (key_ofs_map.size() > 1) {
break;
+ }
String animations;
if (root_path && root_path->has_node(animation->track_get_path(first_track))) {
-
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(root_path->get_node(animation->track_get_path(first_track)));
if (ap) {
List<StringName> anims;
@@ -1373,7 +1283,6 @@ public:
UndoRedo *undo_redo;
void notify_change() {
-
_change_notify();
}
@@ -1394,14 +1303,12 @@ public:
};
void AnimationTimelineEdit::_zoom_changed(double) {
-
update();
play_position->update();
emit_signal("zoom_changed");
}
float AnimationTimelineEdit::get_zoom_scale() const {
-
float zv = zoom->get_max() - zoom->get_value();
if (zv < 1) {
zv = 1.0 - zv;
@@ -1412,9 +1319,9 @@ float AnimationTimelineEdit::get_zoom_scale() const {
}
void AnimationTimelineEdit::_anim_length_changed(double p_new_len) {
-
- if (editing)
+ if (editing) {
return;
+ }
p_new_len = MAX(0.001, p_new_len);
if (use_fps && animation->get_step() > 0) {
@@ -1433,7 +1340,6 @@ void AnimationTimelineEdit::_anim_length_changed(double p_new_len) {
}
void AnimationTimelineEdit::_anim_loop_pressed() {
-
undo_redo->create_action(TTR("Change Animation Loop"));
undo_redo->add_do_method(animation.ptr(), "set_loop", loop->is_pressed());
undo_redo->add_undo_method(animation.ptr(), "set_loop", animation->has_loop());
@@ -1441,7 +1347,6 @@ void AnimationTimelineEdit::_anim_loop_pressed() {
}
int AnimationTimelineEdit::get_buttons_width() const {
-
Ref<Texture2D> interp_mode = get_theme_icon("TrackContinuous", "EditorIcons");
Ref<Texture2D> interp_type = get_theme_icon("InterpRaw", "EditorIcons");
Ref<Texture2D> loop_type = get_theme_icon("InterpWrapClamp", "EditorIcons");
@@ -1455,7 +1360,6 @@ int AnimationTimelineEdit::get_buttons_width() const {
}
int AnimationTimelineEdit::get_name_limit() const {
-
Ref<Texture2D> hsize_icon = get_theme_icon("Hsize", "EditorIcons");
int limit = MAX(name_limit, add_track->get_minimum_size().width + hsize_icon->get_width());
@@ -1466,7 +1370,6 @@ int AnimationTimelineEdit::get_name_limit() const {
}
void AnimationTimelineEdit::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
add_track->set_icon(get_theme_icon("Add", "EditorIcons"));
loop->set_icon(get_theme_icon("Loop", "EditorIcons"));
@@ -1487,11 +1390,11 @@ void AnimationTimelineEdit::_notification(int p_what) {
}
if (p_what == NOTIFICATION_DRAW) {
-
int key_range = get_size().width - get_buttons_width() - get_name_limit();
- if (!animation.is_valid())
+ if (!animation.is_valid()) {
return;
+ }
Ref<Font> font = get_theme_font("font", "Label");
Color color = get_theme_color("font_color", "Label");
@@ -1501,8 +1404,9 @@ void AnimationTimelineEdit::_notification(int p_what) {
int h = get_size().height;
float l = animation->get_length();
- if (l <= 0)
+ if (l <= 0) {
l = 0.001; //avoid crashor
+ }
Ref<Texture2D> hsize_icon = get_theme_icon("Hsize", "EditorIcons");
hsize_rect = Rect2(get_name_limit() - hsize_icon->get_width() - 2 * EDSCALE, (get_size().height - hsize_icon->get_height()) / 2, hsize_icon->get_width(), hsize_icon->get_height());
@@ -1512,24 +1416,24 @@ void AnimationTimelineEdit::_notification(int p_what) {
float time_min = 0;
float time_max = animation->get_length();
for (int i = 0; i < animation->get_track_count(); i++) {
-
if (animation->track_get_key_count(i) > 0) {
-
float beg = animation->track_get_key_time(i, 0);
/*if (animation->track_get_type(i) == Animation::TYPE_BEZIER) {
beg += animation->bezier_track_get_key_in_handle(i, 0).x;
}* not worth it since they have no use */
- if (beg < time_min)
+ if (beg < time_min) {
time_min = beg;
+ }
float end = animation->track_get_key_time(i, animation->track_get_key_count(i) - 1);
/*if (animation->track_get_type(i) == Animation::TYPE_BEZIER) {
end += animation->bezier_track_get_key_out_handle(i, animation->track_get_key_count(i) - 1).x;
} not worth it since they have no use */
- if (end > time_max)
+ if (end > time_max) {
time_max = end;
+ }
}
}
@@ -1545,7 +1449,6 @@ void AnimationTimelineEdit::_notification(int p_what) {
hscroll->show();
} else {
-
hscroll->hide();
}
}
@@ -1561,15 +1464,15 @@ void AnimationTimelineEdit::_notification(int p_what) {
linecolor.a = 0.2;
{
-
draw_rect(Rect2(Point2(get_name_limit(), 0), Point2(zoomw - 1, h)), notimecol);
if (begin_px < zoomw && end_px > 0) {
-
- if (begin_px < 0)
+ if (begin_px < 0) {
begin_px = 0;
- if (end_px > zoomw)
+ }
+ if (end_px > zoomw) {
end_px = zoomw;
+ }
draw_rect(Rect2(Point2(get_name_limit() + begin_px, 0), Point2(end_px - begin_px - 1, h)), timecolor);
}
@@ -1595,37 +1498,35 @@ void AnimationTimelineEdit::_notification(int p_what) {
const int max_sc_width = String::num(max_sc).length() * max_digit_width;
while (!step_found) {
-
min = max_sc_width;
- if (decimals > 0)
+ if (decimals > 0) {
min += period_width + max_digit_width * decimals;
+ }
static const int _multp[3] = { 1, 2, 5 };
for (int i = 0; i < 3; i++) {
-
step = (_multp[i] * dec);
if (step * scale / SC_ADJ > min) {
step_found = true;
break;
}
}
- if (step_found)
+ if (step_found) {
break;
+ }
dec *= 10;
decimals--;
- if (decimals < 0)
+ if (decimals < 0) {
decimals = 0;
+ }
}
if (use_fps) {
-
float step_size = animation->get_step();
if (step_size > 0) {
-
int prev_frame_ofs = -10000000;
for (int i = 0; i < zoomw; i++) {
-
float pos = get_value() + double(i) / scale;
float prev = get_value() + (double(i) - 1.0) / scale;
@@ -1635,7 +1536,6 @@ void AnimationTimelineEdit::_notification(int p_what) {
bool sub = Math::floor(prev) == Math::floor(pos);
if (frame != prev_frame && i >= prev_frame_ofs) {
-
draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE));
draw_string(font, Point2(get_name_limit() + i + 3 * EDSCALE, (h - font->get_height()) / 2 + font->get_ascent()).floor(), itos(frame), sub ? color_time_dec : color_time_sec, zoomw - i);
@@ -1646,7 +1546,6 @@ void AnimationTimelineEdit::_notification(int p_what) {
} else {
for (int i = 0; i < zoomw; i++) {
-
float pos = get_value() + double(i) / scale;
float prev = get_value() + (double(i) - 1.0) / scale;
@@ -1655,7 +1554,6 @@ void AnimationTimelineEdit::_notification(int p_what) {
bool sub = (sc % SC_ADJ);
if ((sc / step) != (prev_sc / step) || (prev_sc < 0 && sc >= 0)) {
-
int scd = sc < 0 ? prev_sc : sc;
draw_line(Point2(get_name_limit() + i, 0), Point2(get_name_limit() + i, h), linecolor, Math::round(EDSCALE));
draw_string(font, Point2(get_name_limit() + i + 3, (h - font->get_height()) / 2 + font->get_ascent()).floor(), String::num((scd - (scd % step)) / double(SC_ADJ), decimals), sub ? color_time_dec : color_time_sec, zoomw - i);
@@ -1683,7 +1581,6 @@ void AnimationTimelineEdit::set_animation(const Ref<Animation> &p_animation) {
}
Size2 AnimationTimelineEdit::get_minimum_size() const {
-
Size2 ms = add_track->get_minimum_size();
Ref<Font> font = get_theme_font("font", "Label");
ms.height = MAX(ms.height, font->get_height());
@@ -1701,7 +1598,6 @@ void AnimationTimelineEdit::set_zoom(Range *p_zoom) {
}
void AnimationTimelineEdit::set_play_position(float p_pos) {
-
play_position_pos = p_pos;
play_position->update();
}
@@ -1715,9 +1611,9 @@ void AnimationTimelineEdit::update_play_position() {
}
void AnimationTimelineEdit::update_values() {
-
- if (!animation.is_valid() || editing)
+ if (!animation.is_valid() || editing) {
return;
+ }
editing = true;
if (use_fps && animation->get_step() > 0) {
@@ -1736,9 +1632,9 @@ void AnimationTimelineEdit::update_values() {
}
void AnimationTimelineEdit::_play_position_draw() {
-
- if (!animation.is_valid() || play_position_pos < 0)
+ if (!animation.is_valid() || play_position_pos < 0) {
return;
+ }
float scale = get_zoom_scale();
int h = play_position->get_size().height;
@@ -1756,11 +1652,9 @@ void AnimationTimelineEdit::_play_position_draw() {
}
void AnimationTimelineEdit::_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && hsize_rect.has_point(mb->get_position())) {
-
dragging_hsize = true;
dragging_hsize_from = mb->get_position().x;
dragging_hsize_at = name_limit;
@@ -1770,7 +1664,6 @@ void AnimationTimelineEdit::_gui_input(const Ref<InputEvent> &p_event) {
dragging_hsize = false;
}
if (mb.is_valid() && mb->get_position().x > get_name_limit() && mb->get_position().x < (get_size().width - get_buttons_width())) {
-
if (!panning_timeline && mb->get_button_index() == BUTTON_LEFT) {
int x = mb->get_position().x - get_name_limit();
@@ -1797,7 +1690,6 @@ void AnimationTimelineEdit::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
if (hsize_rect.has_point(mm->get_position())) {
// Change the cursor to indicate that the track name column's width can be adjusted
set_default_cursor_shape(Control::CURSOR_HSIZE);
@@ -1831,12 +1723,12 @@ void AnimationTimelineEdit::set_use_fps(bool p_use_fps) {
update_values();
update();
}
+
bool AnimationTimelineEdit::is_using_fps() const {
return use_fps;
}
void AnimationTimelineEdit::set_hscroll(HScrollBar *p_hscroll) {
-
hscroll = p_hscroll;
}
@@ -1855,7 +1747,6 @@ void AnimationTimelineEdit::_bind_methods() {
}
AnimationTimelineEdit::AnimationTimelineEdit() {
-
use_fps = false;
editing = false;
name_limit = 150 * EDSCALE;
@@ -1911,11 +1802,10 @@ AnimationTimelineEdit::AnimationTimelineEdit() {
////////////////////////////////////
void AnimationTrackEdit::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
-
- if (animation.is_null())
+ if (animation.is_null()) {
return;
+ }
ERR_FAIL_INDEX(track, animation->get_track_count());
int limit = timeline->get_name_limit();
@@ -1944,7 +1834,6 @@ void AnimationTrackEdit::_notification(int p_what) {
// NAMES AND ICONS //
{
-
Ref<Texture2D> check = animation->track_is_enabled(track) ? get_theme_icon("checked", "CheckBox") : get_theme_icon("unchecked", "CheckBox");
int ofs = in_group ? check->get_width() : 0; //not the best reference for margin but..
@@ -1970,7 +1859,6 @@ void AnimationTrackEdit::_notification(int p_what) {
}
if (in_group) {
-
if (animation->track_get_type(track) == Animation::TYPE_METHOD) {
text = TTR("Functions:");
} else if (animation->track_get_type(track) == Animation::TYPE_AUDIO) {
@@ -2017,14 +1905,12 @@ void AnimationTrackEdit::_notification(int p_what) {
int limit_end = get_size().width - timeline->get_buttons_width();
for (int i = 0; i < animation->track_get_key_count(track); i++) {
-
float offset = animation->track_get_key_time(track, i) - timeline->get_value();
if (editor->is_key_selected(track, i) && editor->is_moving_selection()) {
offset = editor->snap_time(offset + editor->get_moving_selection_offset(), true);
}
offset = offset * scale + limit;
if (i < animation->track_get_key_count(track) - 1) {
-
float offset_n = animation->track_get_key_time(track, i + 1) - timeline->get_value();
if (editor->is_key_selected(track, i + 1) && editor->is_moving_selection()) {
offset_n = editor->snap_time(offset_n + editor->get_moving_selection_offset());
@@ -2043,7 +1929,6 @@ void AnimationTrackEdit::_notification(int p_what) {
// BUTTONS //
{
-
Ref<Texture2D> wrap_icon[2] = {
get_theme_icon("InterpWrapClamp", "EditorIcons"),
get_theme_icon("InterpWrapLoop", "EditorIcons"),
@@ -2217,15 +2102,17 @@ void AnimationTrackEdit::_notification(int p_what) {
}
int AnimationTrackEdit::get_key_height() const {
- if (!animation.is_valid())
+ if (!animation.is_valid()) {
return 0;
+ }
return type_icon->get_height();
}
-Rect2 AnimationTrackEdit::get_key_rect(int p_index, float p_pixels_sec) {
- if (!animation.is_valid())
+Rect2 AnimationTrackEdit::get_key_rect(int p_index, float p_pixels_sec) {
+ if (!animation.is_valid()) {
return Rect2();
+ }
Rect2 rect = Rect2(-type_icon->get_width() / 2, 0, type_icon->get_width(), get_size().height);
//make it a big easier to click
@@ -2239,15 +2126,18 @@ bool AnimationTrackEdit::is_key_selectable_by_distance() const {
}
void AnimationTrackEdit::draw_key_link(int p_index, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) {
- if (p_next_x < p_clip_left)
+ if (p_next_x < p_clip_left) {
return;
- if (p_x > p_clip_right)
+ }
+ if (p_x > p_clip_right) {
return;
+ }
Variant current = animation->track_get_key_value(get_track(), p_index);
Variant next = animation->track_get_key_value(get_track(), p_index + 1);
- if (current != next)
+ if (current != next) {
return;
+ }
Color color = get_theme_color("font_color", "Label");
color.a = 0.5;
@@ -2259,12 +2149,13 @@ void AnimationTrackEdit::draw_key_link(int p_index, float p_pixels_sec, int p_x,
}
void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
-
- if (!animation.is_valid())
+ if (!animation.is_valid()) {
return;
+ }
- if (p_x < p_clip_left || p_x > p_clip_right)
+ if (p_x < p_clip_left || p_x > p_clip_right) {
return;
+ }
Ref<Texture2D> icon_to_draw = p_selected ? selected_icon : type_icon;
@@ -2287,16 +2178,18 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool
Dictionary d = animation->track_get_key_value(track, p_index);
String text;
- if (d.has("method"))
+ if (d.has("method")) {
text += String(d["method"]);
+ }
text += "(";
Vector<Variant> args;
- if (d.has("args"))
+ if (d.has("args")) {
args = d["args"];
+ }
for (int i = 0; i < args.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += String(args[i]);
}
text += ")";
@@ -2312,14 +2205,15 @@ void AnimationTrackEdit::draw_key(int p_index, float p_pixels_sec, int p_x, bool
//helper
void AnimationTrackEdit::draw_rect_clipped(const Rect2 &p_rect, const Color &p_color, bool p_filled) {
-
int clip_left = timeline->get_name_limit();
int clip_right = get_size().width - timeline->get_buttons_width();
- if (p_rect.position.x > clip_right)
+ if (p_rect.position.x > clip_right) {
return;
- if (p_rect.position.x + p_rect.size.x < clip_left)
+ }
+ if (p_rect.position.x + p_rect.size.x < clip_left) {
return;
+ }
Rect2 clip = Rect2(clip_left, 0, clip_right - clip_left, get_size().height);
draw_rect(clip.clip(p_rect), p_color, p_filled);
}
@@ -2331,20 +2225,20 @@ void AnimationTrackEdit::draw_fg(int p_clip_left, int p_clip_right) {
}
void AnimationTrackEdit::draw_texture_clipped(const Ref<Texture2D> &p_texture, const Vector2 &p_pos) {
-
draw_texture_region_clipped(p_texture, Rect2(p_pos, p_texture->get_size()), Rect2(Point2(), p_texture->get_size()));
}
void AnimationTrackEdit::draw_texture_region_clipped(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, const Rect2 &p_region) {
-
int clip_left = timeline->get_name_limit();
int clip_right = get_size().width - timeline->get_buttons_width();
//clip left and right
- if (clip_left > p_rect.position.x + p_rect.size.x)
+ if (clip_left > p_rect.position.x + p_rect.size.x) {
return;
- if (clip_right < p_rect.position.x)
+ }
+ if (clip_right < p_rect.position.x) {
return;
+ }
Rect2 rect = p_rect;
Rect2 region = p_region;
@@ -2361,7 +2255,6 @@ void AnimationTrackEdit::draw_texture_region_clipped(const Ref<Texture2D> &p_tex
}
if (clip_right < rect.position.x + rect.size.x) {
-
int rect_pixels = rect.position.x + rect.size.x - clip_right;
int region_pixels = rect_pixels * region.size.x / rect.size.x;
@@ -2381,7 +2274,6 @@ Ref<Animation> AnimationTrackEdit::get_animation() const {
}
void AnimationTrackEdit::set_animation_and_track(const Ref<Animation> &p_animation, int p_track) {
-
animation = p_animation;
track = p_track;
update();
@@ -2407,7 +2299,6 @@ NodePath AnimationTrackEdit::get_path() const {
}
Size2 AnimationTrackEdit::get_minimum_size() const {
-
Ref<Texture2D> texture = get_theme_icon("Object", "EditorIcons");
Ref<Font> font = get_theme_font("font", "Label");
int separation = get_theme_constant("vseparation", "ItemList");
@@ -2427,14 +2318,15 @@ void AnimationTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) {
timeline->connect("zoom_changed", callable_mp(this, &AnimationTrackEdit::_zoom_changed));
timeline->connect("name_limit_changed", callable_mp(this, &AnimationTrackEdit::_zoom_changed));
}
+
void AnimationTrackEdit::set_editor(AnimationTrackEditor *p_editor) {
editor = p_editor;
}
void AnimationTrackEdit::_play_position_draw() {
-
- if (!animation.is_valid() || play_position_pos < 0)
+ if (!animation.is_valid() || play_position_pos < 0) {
return;
+ }
float scale = timeline->get_zoom_scale();
int h = get_size().height;
@@ -2448,7 +2340,6 @@ void AnimationTrackEdit::_play_position_draw() {
}
void AnimationTrackEdit::set_play_position(float p_pos) {
-
play_position_pos = p_pos;
play_position->update();
}
@@ -2475,9 +2366,9 @@ void AnimationTrackEdit::_path_entered(const String &p_text) {
}
bool AnimationTrackEdit::_is_value_key_valid(const Variant &p_key_value, Variant::Type &r_valid_type) const {
-
- if (root == nullptr)
+ if (root == nullptr) {
return false;
+ }
RES res;
Vector<StringName> leftover_path;
@@ -2499,7 +2390,6 @@ bool AnimationTrackEdit::_is_value_key_valid(const Variant &p_key_value, Variant
}
String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
-
if (check_rect.has_point(p_pos)) {
return TTR("Toggle this track on/off.");
}
@@ -2531,20 +2421,17 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
int limit_start_hitbox = limit - type_icon->get_width();
if (p_pos.x >= limit_start_hitbox && p_pos.x <= limit_end) {
-
int key_idx = -1;
float key_distance = 1e20;
// Select should happen in the opposite order of drawing for more accurate overlap select.
for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) {
-
Rect2 rect = const_cast<AnimationTrackEdit *>(this)->get_key_rect(i, timeline->get_zoom_scale());
float offset = animation->track_get_key_time(track, i) - timeline->get_value();
offset = offset * timeline->get_zoom_scale() + limit;
rect.position.x += offset;
if (rect.has_point(p_pos)) {
-
if (const_cast<AnimationTrackEdit *>(this)->is_key_selectable_by_distance()) {
float distance = ABS(offset - p_pos.x);
if (key_idx == -1 || distance < key_distance) {
@@ -2559,22 +2446,21 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
}
if (key_idx != -1) {
-
String text = TTR("Time (s): ") + rtos(animation->track_get_key_time(track, key_idx)) + "\n";
switch (animation->track_get_type(track)) {
-
case Animation::TYPE_TRANSFORM: {
-
Dictionary d = animation->track_get_key_value(track, key_idx);
- if (d.has("location"))
+ if (d.has("location")) {
text += "Pos: " + String(d["location"]) + "\n";
- if (d.has("rotation"))
+ }
+ if (d.has("rotation")) {
text += "Rot: " + String(d["rotation"]) + "\n";
- if (d.has("scale"))
+ }
+ if (d.has("scale")) {
text += "Scale: " + String(d["scale"]) + "\n";
+ }
} break;
case Animation::TYPE_VALUE: {
-
const Variant &v = animation->track_get_key_value(track, key_idx);
text += "Type: " + Variant::get_type_name(v.get_type()) + "\n";
Variant::Type valid_type = Variant::NIL;
@@ -2587,25 +2473,25 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
} break;
case Animation::TYPE_METHOD: {
-
Dictionary d = animation->track_get_key_value(track, key_idx);
- if (d.has("method"))
+ if (d.has("method")) {
text += String(d["method"]);
+ }
text += "(";
Vector<Variant> args;
- if (d.has("args"))
+ if (d.has("args")) {
args = d["args"];
+ }
for (int i = 0; i < args.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += String(args[i]);
}
text += ")\n";
} break;
case Animation::TYPE_BEZIER: {
-
float h = animation->bezier_track_get_key_value(track, key_idx);
text += "Value: " + rtos(h) + "\n";
Vector2 ih = animation->bezier_track_get_key_in_handle(track, key_idx);
@@ -2614,7 +2500,6 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
text += "Out-Handle: " + oh + "\n";
} break;
case Animation::TYPE_AUDIO: {
-
String stream_name = "null";
RES stream = animation->audio_track_get_key_stream(track, key_idx);
if (stream.is_valid()) {
@@ -2634,7 +2519,6 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
text += "End (s): " + rtos(eo) + "\n";
} break;
case Animation::TYPE_ANIMATION: {
-
String name = animation->animation_track_get_key_animation(track, key_idx);
text += "Animation Clip: " + name + "\n";
} break;
@@ -2757,20 +2641,17 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
int limit_start_hitbox = limit - type_icon->get_width();
if (pos.x >= limit_start_hitbox && pos.x <= limit_end) {
-
int key_idx = -1;
float key_distance = 1e20;
// Select should happen in the opposite order of drawing for more accurate overlap select.
for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) {
-
Rect2 rect = get_key_rect(i, scale);
float offset = animation->track_get_key_time(track, i) - timeline->get_value();
offset = offset * scale + limit;
rect.position.x += offset;
if (rect.has_point(pos)) {
-
if (is_key_selectable_by_distance()) {
float distance = ABS(offset - pos.x);
if (key_idx == -1 || distance < key_distance) {
@@ -2842,7 +2723,6 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && clicking_on_name) {
-
if (!path) {
path_popup = memnew(Popup);
path_popup->set_wrap_controls(true);
@@ -2864,7 +2744,6 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (mb.is_valid() && moving_selection_attempt) {
-
if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
moving_selection_attempt = false;
if (moving_selection) {
@@ -2877,7 +2756,6 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (moving_selection && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) {
-
moving_selection_attempt = false;
moving_selection = false;
emit_signal("move_selection_cancel");
@@ -2886,7 +2764,6 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT && moving_selection_attempt) {
-
if (!moving_selection) {
moving_selection = true;
emit_signal("move_selection_begin");
@@ -2898,9 +2775,9 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
Variant AnimationTrackEdit::get_drag_data(const Point2 &p_point) {
-
- if (!clicking_on_name)
+ if (!clicking_on_name) {
return Variant();
+ }
Dictionary drag_data;
drag_data["type"] = "animation_track";
@@ -2920,7 +2797,6 @@ Variant AnimationTrackEdit::get_drag_data(const Point2 &p_point) {
}
bool AnimationTrackEdit::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
-
Dictionary d = p_data;
if (!d.has("type")) {
return false;
@@ -2951,8 +2827,8 @@ bool AnimationTrackEdit::can_drop_data(const Point2 &p_point, const Variant &p_d
return true;
}
-void AnimationTrackEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
+void AnimationTrackEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
Dictionary d = p_data;
if (!d.has("type")) {
return;
@@ -2982,13 +2858,11 @@ void AnimationTrackEdit::drop_data(const Point2 &p_point, const Variant &p_data)
}
void AnimationTrackEdit::_menu_selected(int p_index) {
-
switch (p_index) {
case MENU_CALL_MODE_CONTINUOUS:
case MENU_CALL_MODE_DISCRETE:
case MENU_CALL_MODE_TRIGGER:
case MENU_CALL_MODE_CAPTURE: {
-
Animation::UpdateMode update_mode = Animation::UpdateMode(p_index);
undo_redo->create_action(TTR("Change Animation Update Mode"));
undo_redo->add_do_method(animation.ptr(), "value_track_set_update_mode", track, update_mode);
@@ -3000,7 +2874,6 @@ void AnimationTrackEdit::_menu_selected(int p_index) {
case MENU_INTERPOLATION_NEAREST:
case MENU_INTERPOLATION_LINEAR:
case MENU_INTERPOLATION_CUBIC: {
-
Animation::InterpolationType interp_mode = Animation::InterpolationType(p_index - MENU_INTERPOLATION_NEAREST);
undo_redo->create_action(TTR("Change Animation Interpolation Mode"));
undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_type", track, interp_mode);
@@ -3010,7 +2883,6 @@ void AnimationTrackEdit::_menu_selected(int p_index) {
} break;
case MENU_LOOP_WRAP:
case MENU_LOOP_CLAMP: {
-
bool loop_wrap = p_index == MENU_LOOP_WRAP;
undo_redo->create_action(TTR("Change Animation Loop Mode"));
undo_redo->add_do_method(animation.ptr(), "track_set_interpolation_loop_wrap", track, loop_wrap);
@@ -3039,6 +2911,7 @@ void AnimationTrackEdit::cancel_drop() {
update();
}
}
+
void AnimationTrackEdit::set_in_group(bool p_enable) {
in_group = p_enable;
update();
@@ -3052,23 +2925,22 @@ void AnimationTrackEdit::append_to_selection(const Rect2 &p_box, bool p_deselect
// Select should happen in the opposite order of drawing for more accurate overlap select.
for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) {
-
Rect2 rect = const_cast<AnimationTrackEdit *>(this)->get_key_rect(i, timeline->get_zoom_scale());
float offset = animation->track_get_key_time(track, i) - timeline->get_value();
offset = offset * timeline->get_zoom_scale() + timeline->get_name_limit();
rect.position.x += offset;
if (select_rect.intersects(rect)) {
- if (p_deselection)
+ if (p_deselection) {
emit_signal("deselect_key", i);
- else
+ } else {
emit_signal("select_key", i, false);
+ }
}
}
}
void AnimationTrackEdit::_bind_methods() {
-
ClassDB::bind_method("_gui_input", &AnimationTrackEdit::_gui_input);
ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::FLOAT, "position"), PropertyInfo(Variant::BOOL, "drag")));
@@ -3144,7 +3016,6 @@ AnimationTrackEdit *AnimationTrackEditPlugin::create_value_track_edit(Object *p_
}
AnimationTrackEdit *AnimationTrackEditPlugin::create_audio_track_edit() {
-
if (get_script_instance()) {
return Object::cast_to<AnimationTrackEdit>(get_script_instance()->call("create_audio_track_edit").operator Object *());
}
@@ -3161,7 +3032,6 @@ AnimationTrackEdit *AnimationTrackEditPlugin::create_animation_track_edit(Object
///////////////////////////////////////
void AnimationTrackEditGroup::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
Ref<Font> font = get_theme_font("font", "Label");
int separation = get_theme_constant("hseparation", "ItemList");
@@ -3207,7 +3077,6 @@ void AnimationTrackEditGroup::set_type_and_name(const Ref<Texture2D> &p_type, co
}
Size2 AnimationTrackEditGroup::get_minimum_size() const {
-
Ref<Font> font = get_theme_font("font", "Label");
int separation = get_theme_constant("vseparation", "ItemList");
@@ -3239,19 +3108,17 @@ AnimationTrackEditGroup::AnimationTrackEditGroup() {
//////////////////////////////////////
void AnimationTrackEditor::add_track_edit_plugin(const Ref<AnimationTrackEditPlugin> &p_plugin) {
-
- if (track_edit_plugins.find(p_plugin) != -1)
+ if (track_edit_plugins.find(p_plugin) != -1) {
return;
+ }
track_edit_plugins.push_back(p_plugin);
}
void AnimationTrackEditor::remove_track_edit_plugin(const Ref<AnimationTrackEditPlugin> &p_plugin) {
-
track_edit_plugins.erase(p_plugin);
}
void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim) {
-
if (animation != p_anim && _get_track_selected() >= 0) {
track_edits[_get_track_selected()]->release_focus();
}
@@ -3299,7 +3166,6 @@ void AnimationTrackEditor::set_animation(const Ref<Animation> &p_anim) {
}
Ref<Animation> AnimationTrackEditor::get_current_animation() const {
-
return animation;
}
@@ -3322,15 +3188,15 @@ void AnimationTrackEditor::set_root(Node *p_root) {
}
Node *AnimationTrackEditor::get_root() const {
-
return root;
}
void AnimationTrackEditor::update_keying() {
bool keying_enabled = is_visible_in_tree() && animation.is_valid();
- if (keying_enabled == keying)
+ if (keying_enabled == keying) {
return;
+ }
keying = keying_enabled;
//_update_menu();
@@ -3340,6 +3206,7 @@ void AnimationTrackEditor::update_keying() {
bool AnimationTrackEditor::has_keying() const {
return keying;
}
+
Dictionary AnimationTrackEditor::get_state() const {
Dictionary state;
state["fps_mode"] = timeline->is_using_fps();
@@ -3348,6 +3215,7 @@ Dictionary AnimationTrackEditor::get_state() const {
state["v_scroll"] = scroll->get_v_scrollbar()->get_value();
return state;
}
+
void AnimationTrackEditor::set_state(const Dictionary &p_state) {
if (p_state.has("fps_mode")) {
bool fps_mode = p_state["fps_mode"];
@@ -3383,22 +3251,18 @@ void AnimationTrackEditor::cleanup() {
}
void AnimationTrackEditor::_name_limit_changed() {
-
for (int i = 0; i < track_edits.size(); i++) {
track_edits[i]->update();
}
}
void AnimationTrackEditor::_timeline_changed(float p_new_pos, bool p_drag) {
-
emit_signal("timeline_changed", p_new_pos, p_drag);
}
void AnimationTrackEditor::_track_remove_request(int p_track) {
-
int idx = p_track;
if (idx >= 0 && idx < animation->get_track_count()) {
-
undo_redo->create_action(TTR("Remove Anim Track"));
undo_redo->add_do_method(this, "_clear_selection", false);
undo_redo->add_do_method(animation.ptr(), "remove_track", idx);
@@ -3407,7 +3271,6 @@ void AnimationTrackEditor::_track_remove_request(int p_track) {
// TODO interpolation.
for (int i = 0; i < animation->track_get_key_count(idx); i++) {
-
Variant v = animation->track_get_key_value(idx, i);
float time = animation->track_get_key_time(idx, i);
float trans = animation->track_get_key_transition(idx, i);
@@ -3426,14 +3289,13 @@ void AnimationTrackEditor::_track_remove_request(int p_track) {
}
void AnimationTrackEditor::_track_grab_focus(int p_track) {
-
// Don't steal focus if not working with the track editor.
- if (Object::cast_to<AnimationTrackEdit>(get_focus_owner()))
+ if (Object::cast_to<AnimationTrackEdit>(get_focus_owner())) {
track_edits[p_track]->grab_focus();
+ }
}
void AnimationTrackEditor::set_anim_pos(float p_pos) {
-
timeline->set_play_position(p_pos);
for (int i = 0; i < track_edits.size(); i++) {
track_edits[i]->set_play_position(p_pos);
@@ -3445,11 +3307,11 @@ void AnimationTrackEditor::set_anim_pos(float p_pos) {
}
void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
-
if (insert_frame != Engine::get_singleton()->get_frames_drawn()) {
//clear insert list for the frame if frame changed
- if (insert_confirm->is_visible())
+ if (insert_confirm->is_visible()) {
return; //do nothing
+ }
insert_data.clear();
insert_query = false;
}
@@ -3457,8 +3319,9 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
for (List<InsertData>::Element *E = insert_data.front(); E; E = E->next()) {
//prevent insertion of multiple tracks
- if (E->get().path == p_id.path)
+ if (E->get().path == p_id.path) {
return; //already inserted a track for this on this frame
+ }
}
insert_data.push_back(p_id);
@@ -3469,14 +3332,17 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
int num_tracks = 0;
bool all_bezier = true;
for (int i = 0; i < insert_data.size(); i++) {
- if (insert_data[i].type != Animation::TYPE_VALUE && insert_data[i].type != Animation::TYPE_BEZIER)
+ if (insert_data[i].type != Animation::TYPE_VALUE && insert_data[i].type != Animation::TYPE_BEZIER) {
all_bezier = false;
+ }
- if (insert_data[i].track_idx == -1)
+ if (insert_data[i].track_idx == -1) {
++num_tracks;
+ }
- if (insert_data[i].type != Animation::TYPE_VALUE)
+ if (insert_data[i].type != Animation::TYPE_VALUE) {
continue;
+ }
switch (insert_data[i].value.get_type()) {
case Variant::INT:
@@ -3494,10 +3360,11 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
}
}
- if (num_tracks == 1)
+ if (num_tracks == 1) {
insert_confirm_text->set_text(vformat(TTR("Create NEW track for %s and insert key?"), p_id.query));
- else
+ } else {
insert_confirm_text->set_text(vformat(TTR("Create %d NEW tracks and insert keys?"), num_tracks));
+ }
insert_confirm_bezier->set_visible(all_bezier);
insert_confirm->get_ok()->set_text(TTR("Create"));
@@ -3517,7 +3384,6 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
}
void AnimationTrackEditor::_insert_delay() {
-
if (insert_query) {
//discard since it's entered into query mode
insert_queue = false;
@@ -3529,9 +3395,9 @@ void AnimationTrackEditor::_insert_delay() {
int last_track = animation->get_track_count();
bool advance = false;
while (insert_data.size()) {
-
- if (insert_data.front()->get().advance)
+ if (insert_data.front()->get().advance) {
advance = true;
+ }
last_track = _confirm_insert(insert_data.front()->get(), last_track);
insert_data.pop_front();
}
@@ -3540,14 +3406,16 @@ void AnimationTrackEditor::_insert_delay() {
if (advance) {
float step = animation->get_step();
- if (step == 0)
+ if (step == 0) {
step = 1;
+ }
float pos = timeline->get_play_position();
pos = Math::stepify(pos + step, step);
- if (pos > animation->get_length())
+ if (pos > animation->get_length()) {
pos = animation->get_length();
+ }
set_anim_pos(pos);
emit_signal("timeline_changed", pos, true);
}
@@ -3555,28 +3423,31 @@ void AnimationTrackEditor::_insert_delay() {
}
void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_sub, const Transform &p_xform) {
-
- if (!keying)
+ if (!keying) {
return;
- if (!animation.is_valid())
+ }
+ if (!animation.is_valid()) {
return;
+ }
ERR_FAIL_COND(!root);
//let's build a node path
String path = root->get_path_to(p_node);
- if (p_sub != "")
+ if (p_sub != "") {
path += ":" + p_sub;
+ }
NodePath np = path;
int track_idx = -1;
for (int i = 0; i < animation->get_track_count(); i++) {
-
- if (animation->track_get_type(i) != Animation::TYPE_TRANSFORM)
+ if (animation->track_get_type(i) != Animation::TYPE_TRANSFORM) {
continue;
- if (animation->track_get_path(i) != np)
+ }
+ if (animation->track_get_path(i) != np) {
continue;
+ }
track_idx = i;
break;
@@ -3598,12 +3469,10 @@ void AnimationTrackEditor::insert_transform_key(Node3D *p_node, const String &p_
}
void AnimationTrackEditor::_insert_animation_key(NodePath p_path, const Variant &p_value) {
-
String path = p_path;
//animation property is a special case, always creates an animation track
for (int i = 0; i < animation->get_track_count(); i++) {
-
String np = animation->track_get_path(i);
if (path == np && animation->track_get_type(i) == Animation::TYPE_ANIMATION) {
@@ -3633,7 +3502,6 @@ void AnimationTrackEditor::_insert_animation_key(NodePath p_path, const Variant
}
void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_property, const Variant &p_value, bool p_only_if_exists) {
-
ERR_FAIL_COND(!root);
//let's build a node path
@@ -3652,7 +3520,6 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
EditorHistory *history = EditorNode::get_singleton()->get_editor_history();
for (int i = 1; i < history->get_path_size(); i++) {
-
String prop = history->get_path_property(i);
ERR_FAIL_COND(prop == "");
path += ":" + prop;
@@ -3667,10 +3534,10 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
bool inserted = false;
for (int i = 0; i < animation->get_track_count(); i++) {
-
if (animation->track_get_type(i) == Animation::TYPE_VALUE) {
- if (animation->track_get_path(i) != np)
+ if (animation->track_get_path(i) != np) {
continue;
+ }
InsertData id;
id.path = np;
@@ -3683,7 +3550,6 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
_query_insert(id);
inserted = true;
} else if (animation->track_get_type(i) == Animation::TYPE_BEZIER) {
-
Variant value;
String track_path = animation->track_get_path(i);
if (track_path == np) {
@@ -3695,10 +3561,12 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
if (base_path == np) {
String value_name = track_path.substr(sep + 1);
value = p_value.get(value_name);
- } else
+ } else {
continue;
- } else
+ }
+ } else {
continue;
+ }
}
InsertData id;
@@ -3714,8 +3582,9 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
}
}
- if (inserted || p_only_if_exists)
+ if (inserted || p_only_if_exists) {
return;
+ }
InsertData id;
id.path = np;
id.track_idx = -1;
@@ -3728,7 +3597,6 @@ void AnimationTrackEditor::insert_node_value_key(Node *p_node, const String &p_p
}
void AnimationTrackEditor::insert_value_key(const String &p_property, const Variant &p_value, bool p_advance) {
-
EditorHistory *history = EditorNode::get_singleton()->get_editor_history();
ERR_FAIL_COND(!root);
@@ -3751,7 +3619,6 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
}
for (int i = 1; i < history->get_path_size(); i++) {
-
String prop = history->get_path_property(i);
ERR_FAIL_COND(prop == "");
path += ":" + prop;
@@ -3766,10 +3633,10 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
bool inserted = false;
for (int i = 0; i < animation->get_track_count(); i++) {
-
if (animation->track_get_type(i) == Animation::TYPE_VALUE) {
- if (animation->track_get_path(i) != np)
+ if (animation->track_get_path(i) != np) {
continue;
+ }
InsertData id;
id.path = np;
@@ -3782,7 +3649,6 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
_query_insert(id);
inserted = true;
} else if (animation->track_get_type(i) == Animation::TYPE_BEZIER) {
-
Variant value;
if (animation->track_get_path(i) == np) {
value = p_value; //all good
@@ -3824,12 +3690,10 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari
}
void AnimationTrackEditor::_confirm_insert_list() {
-
undo_redo->create_action(TTR("Anim Create & Insert"));
int last_track = animation->get_track_count();
while (insert_data.size()) {
-
last_track = _confirm_insert(insert_data.front()->get(), last_track, insert_confirm_bezier->is_pressed());
insert_data.pop_front();
}
@@ -3838,7 +3702,6 @@ void AnimationTrackEditor::_confirm_insert_list() {
}
PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_base_path, Variant *r_current_val) {
-
r_base_path = NodePath();
ERR_FAIL_COND_V(!animation.is_valid(), PropertyInfo());
ERR_FAIL_INDEX_V(p_idx, animation->get_track_count(), PropertyInfo());
@@ -3893,7 +3756,6 @@ PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_b
property_info_base.get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
if (E->get().name == leftover_path[leftover_path.size() - 1]) {
return E->get();
}
@@ -3952,13 +3814,12 @@ static Vector<String> _get_bezier_subindices_for_type(Variant::Type p_type, bool
}
int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, bool p_create_beziers) {
-
- if (p_last_track == -1)
+ if (p_last_track == -1) {
p_last_track = animation->get_track_count();
+ }
bool created = false;
if (p_id.track_idx < 0) {
-
if (p_create_beziers) {
bool valid;
Vector<String> subindices = _get_bezier_subindices_for_type(p_id.value.get_type(), &valid);
@@ -3999,7 +3860,6 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
h.type == Variant::PLANE ||
h.type == Variant::TRANSFORM2D ||
h.type == Variant::TRANSFORM) {
-
update_mode = Animation::UPDATE_CONTINUOUS;
}
@@ -4013,8 +3873,9 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
undo_redo->add_do_method(animation.ptr(), "add_track", p_id.type);
undo_redo->add_do_method(animation.ptr(), "track_set_path", p_id.track_idx, p_id.path);
- if (p_id.type == Animation::TYPE_VALUE)
+ if (p_id.type == Animation::TYPE_VALUE) {
undo_redo->add_do_method(animation.ptr(), "value_track_set_update_mode", p_id.track_idx, update_mode);
+ }
} else {
undo_redo->create_action(TTR("Anim Insert Key"));
@@ -4024,14 +3885,11 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
Variant value;
switch (p_id.type) {
-
case Animation::TYPE_VALUE: {
-
value = p_id.value;
} break;
case Animation::TYPE_TRANSFORM: {
-
Transform tr = p_id.value;
Dictionary d;
d["location"] = tr.origin;
@@ -4060,13 +3918,11 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
undo_redo->add_do_method(animation.ptr(), "track_insert_key", p_id.track_idx, time, value);
if (created) {
-
// Just remove the track.
undo_redo->add_undo_method(this, "_clear_selection", false);
undo_redo->add_undo_method(animation.ptr(), "remove_track", animation->get_track_count());
p_last_track++;
} else {
-
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_position", p_id.track_idx, time);
int existing = animation->track_find_key(p_id.track_idx, time, true);
if (existing != -1) {
@@ -4082,12 +3938,10 @@ int AnimationTrackEditor::_confirm_insert(InsertData p_id, int p_last_track, boo
}
void AnimationTrackEditor::show_select_node_warning(bool p_show) {
-
info_message->set_visible(p_show);
}
bool AnimationTrackEditor::is_key_selected(int p_track, int p_key) const {
-
SelectedKey sk;
sk.key = p_key;
sk.track = p_track;
@@ -4100,11 +3954,10 @@ bool AnimationTrackEditor::is_selection_active() const {
}
bool AnimationTrackEditor::is_snap_enabled() const {
- return snap->is_pressed() ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
+ return snap->is_pressed() ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL);
}
void AnimationTrackEditor::_update_tracks() {
-
int selected = _get_track_selected();
while (track_vbox->get_child_count()) {
@@ -4114,8 +3967,9 @@ void AnimationTrackEditor::_update_tracks() {
track_edits.clear();
groups.clear();
- if (animation.is_null())
+ if (animation.is_null()) {
return;
+ }
Map<String, VBoxContainer *> group_sort;
@@ -4142,7 +3996,6 @@ void AnimationTrackEditor::_update_tracks() {
}
if (animation->track_get_type(i) == Animation::TYPE_VALUE) {
-
NodePath path = animation->track_get_path(i);
if (root && root->has_node_and_resource(path)) {
@@ -4172,7 +4025,6 @@ void AnimationTrackEditor::_update_tracks() {
}
}
if (animation->track_get_type(i) == Animation::TYPE_AUDIO) {
-
for (int j = 0; j < track_edit_plugins.size(); j++) {
track_edit = track_edit_plugins.write[j]->create_audio_track_edit();
if (track_edit) {
@@ -4274,7 +4126,6 @@ void AnimationTrackEditor::_update_tracks() {
}
void AnimationTrackEditor::_animation_changed() {
-
if (animation_changing_awaiting_update) {
return; //all will be updated, don't bother with anything
}
@@ -4282,10 +4133,11 @@ void AnimationTrackEditor::_animation_changed() {
if (key_edit && key_edit->setting) {
//if editing a key, just update the edited track, makes refresh less costly
if (key_edit->track < track_edits.size()) {
- if (animation->track_get_type(key_edit->track) == Animation::TYPE_BEZIER)
+ if (animation->track_get_type(key_edit->track) == Animation::TYPE_BEZIER) {
bezier_edit->update();
- else
+ } else {
track_edits[key_edit->track]->update();
+ }
}
return;
}
@@ -4295,7 +4147,6 @@ void AnimationTrackEditor::_animation_changed() {
}
void AnimationTrackEditor::_snap_mode_changed(int p_mode) {
-
timeline->set_use_fps(p_mode == 1);
if (key_edit) {
key_edit->set_use_fps(p_mode == 1);
@@ -4322,8 +4173,8 @@ void AnimationTrackEditor::_update_step_spinbox() {
step->set_block_signals(false);
}
-void AnimationTrackEditor::_animation_update() {
+void AnimationTrackEditor::_animation_update() {
timeline->update();
timeline->update_values();
@@ -4402,7 +4253,6 @@ void AnimationTrackEditor::_update_scroll(double) {
}
void AnimationTrackEditor::_update_step(double p_new_step) {
-
undo_redo->create_action(TTR("Change Animation Step"));
float step_value = p_new_step;
if (timeline->is_using_fps()) {
@@ -4419,7 +4269,6 @@ void AnimationTrackEditor::_update_step(double p_new_step) {
}
void AnimationTrackEditor::_update_length(double p_new_len) {
-
emit_signal("animation_len_changed", p_new_len);
}
@@ -4440,7 +4289,6 @@ void AnimationTrackEditor::_dropped_track(int p_from_track, int p_to_track) {
}
void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) {
-
ERR_FAIL_COND(!root);
Node *node = get_node(p_path);
ERR_FAIL_COND(!node);
@@ -4459,7 +4307,6 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) {
} break;
case Animation::TYPE_TRANSFORM:
case Animation::TYPE_METHOD: {
-
undo_redo->create_action(TTR("Add Track"));
undo_redo->add_do_method(animation.ptr(), "add_track", adding_track_type);
undo_redo->add_do_method(animation.ptr(), "track_set_path", animation->get_track_count(), path_to);
@@ -4468,7 +4315,6 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) {
} break;
case Animation::TYPE_BEZIER: {
-
Vector<Variant::Type> filter;
filter.push_back(Variant::INT);
filter.push_back(Variant::FLOAT);
@@ -4483,7 +4329,6 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) {
prop_selector->select_property_from_instance(node);
} break;
case Animation::TYPE_AUDIO: {
-
if (!node->is_class("AudioStreamPlayer") && !node->is_class("AudioStreamPlayer2D") && !node->is_class("AudioStreamPlayer3D")) {
EditorNode::get_singleton()->show_warning(TTR("Audio tracks can only point to nodes of type:\n-AudioStreamPlayer\n-AudioStreamPlayer2D\n-AudioStreamPlayer3D"));
return;
@@ -4497,7 +4342,6 @@ void AnimationTrackEditor::_new_track_node_selected(NodePath p_path) {
} break;
case Animation::TYPE_ANIMATION: {
-
if (!node->is_class("AnimationPlayer")) {
EditorNode::get_singleton()->show_warning(TTR("Animation tracks can only point to AnimationPlayer nodes."));
return;
@@ -4528,11 +4372,9 @@ void AnimationTrackEditor::_add_track(int p_type) {
}
void AnimationTrackEditor::_new_track_property_selected(String p_name) {
-
String full_path = String(adding_track_path) + ":" + p_name;
if (adding_track_type == Animation::TYPE_VALUE) {
-
Animation::UpdateMode update_mode = Animation::UPDATE_DISCRETE;
{
//hack
@@ -4551,7 +4393,6 @@ void AnimationTrackEditor::_new_track_property_selected(String p_name) {
h.type == Variant::PLANE ||
h.type == Variant::TRANSFORM2D ||
h.type == Variant::TRANSFORM) {
-
update_mode = Animation::UPDATE_CONTINUOUS;
}
@@ -4595,7 +4436,6 @@ void AnimationTrackEditor::_new_track_property_selected(String p_name) {
}
void AnimationTrackEditor::_timeline_value_changed(double) {
-
timeline->update_play_position();
for (int i = 0; i < track_edits.size(); i++) {
@@ -4612,17 +4452,16 @@ void AnimationTrackEditor::_timeline_value_changed(double) {
}
int AnimationTrackEditor::_get_track_selected() {
-
for (int i = 0; i < track_edits.size(); i++) {
- if (track_edits[i]->has_focus())
+ if (track_edits[i]->has_focus()) {
return i;
+ }
}
return -1;
}
void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) {
-
ERR_FAIL_INDEX(p_track, animation->get_track_count());
if (snap->is_pressed() && step->get_value() != 0) {
@@ -4658,7 +4497,6 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) {
} break;
case Animation::TYPE_VALUE: {
-
NodePath bp;
Variant value;
_find_hint_for_track(p_track, bp, &value);
@@ -4684,7 +4522,6 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) {
} break;
case Animation::TYPE_BEZIER: {
-
NodePath bp;
Variant value;
_find_hint_for_track(p_track, bp, &value);
@@ -4703,7 +4540,6 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) {
} break;
case Animation::TYPE_AUDIO: {
-
Dictionary ak;
ak["stream"] = RES();
ak["start_offset"] = 0;
@@ -4715,7 +4551,6 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) {
undo_redo->commit_action();
} break;
case Animation::TYPE_ANIMATION: {
-
StringName anim = "[stop]";
undo_redo->create_action(TTR("Add Track Key"));
@@ -4727,7 +4562,6 @@ void AnimationTrackEditor::_insert_key_from_track(float p_ofs, int p_track) {
}
void AnimationTrackEditor::_add_method_key(const String &p_method) {
-
if (!root->has_node(animation->track_get_path(insert_key_from_track_call_track))) {
EditorNode::get_singleton()->show_warning(TTR("Track path is invalid, so can't add a method key."));
return;
@@ -4739,14 +4573,12 @@ void AnimationTrackEditor::_add_method_key(const String &p_method) {
for (List<MethodInfo>::Element *E = minfo.front(); E; E = E->next()) {
if (E->get().name == p_method) {
-
Dictionary d;
d["method"] = p_method;
Array params;
int first_defarg = E->get().arguments.size() - E->get().default_arguments.size();
for (int i = 0; i < E->get().arguments.size(); i++) {
-
if (i >= first_defarg) {
Variant arg = E->get().default_arguments[i - first_defarg];
params.push_back(arg);
@@ -4771,7 +4603,6 @@ void AnimationTrackEditor::_add_method_key(const String &p_method) {
}
void AnimationTrackEditor::_key_selected(int p_key, bool p_single, int p_track) {
-
ERR_FAIL_INDEX(p_track, animation->get_track_count());
ERR_FAIL_INDEX(p_key, animation->track_get_key_count(p_track));
@@ -4795,7 +4626,6 @@ void AnimationTrackEditor::_key_selected(int p_key, bool p_single, int p_track)
}
void AnimationTrackEditor::_key_deselected(int p_key, int p_track) {
-
ERR_FAIL_INDEX(p_track, animation->get_track_count());
ERR_FAIL_INDEX(p_key, animation->track_get_key_count(p_track));
@@ -4826,7 +4656,6 @@ void AnimationTrackEditor::_move_selection(float p_offset) {
}
struct _AnimMoveRestore {
-
int track;
float time;
Variant key;
@@ -4857,7 +4686,6 @@ void AnimationTrackEditor::_clear_key_edit() {
}
void AnimationTrackEditor::_clear_selection(bool p_update) {
-
selection.clear();
if (p_update) {
@@ -4870,13 +4698,12 @@ void AnimationTrackEditor::_clear_selection(bool p_update) {
}
void AnimationTrackEditor::_update_key_edit() {
-
_clear_key_edit();
- if (!animation.is_valid())
+ if (!animation.is_valid()) {
return;
+ }
if (selection.size() == 1) {
-
key_edit = memnew(AnimationTrackKeyEdit);
key_edit->animation = animation;
key_edit->track = selection.front()->key().track;
@@ -4893,7 +4720,6 @@ void AnimationTrackEditor::_update_key_edit() {
EditorNode::get_singleton()->push_item(key_edit);
} else if (selection.size() > 1) {
-
multi_key_edit = memnew(AnimationMultiTrackKeyEdit);
multi_key_edit->animation = animation;
@@ -4901,10 +4727,10 @@ void AnimationTrackEditor::_update_key_edit() {
Map<int, NodePath> base_map;
int first_track = -1;
for (Map<SelectedKey, KeyInfo>::Element *E = selection.front(); E; E = E->next()) {
-
int track = E->key().track;
- if (first_track < 0)
+ if (first_track < 0) {
first_track = track;
+ }
if (!key_ofs_map.has(track)) {
key_ofs_map[track] = List<float>();
@@ -4928,17 +4754,17 @@ void AnimationTrackEditor::_update_key_edit() {
}
void AnimationTrackEditor::_clear_selection_for_anim(const Ref<Animation> &p_anim) {
-
- if (animation != p_anim)
+ if (animation != p_anim) {
return;
+ }
_clear_selection();
}
void AnimationTrackEditor::_select_at_anim(const Ref<Animation> &p_anim, int p_track, float p_pos) {
-
- if (animation != p_anim)
+ if (animation != p_anim) {
return;
+ }
int idx = animation->track_find_key(p_track, p_pos, true);
ERR_FAIL_COND(idx < 0);
@@ -4953,7 +4779,6 @@ void AnimationTrackEditor::_select_at_anim(const Ref<Animation> &p_anim, int p_t
}
void AnimationTrackEditor::_move_selection_commit() {
-
undo_redo->create_action(TTR("Anim Move Keys"));
List<_AnimMoveRestore> to_restore;
@@ -4961,21 +4786,21 @@ void AnimationTrackEditor::_move_selection_commit() {
float motion = moving_selection_offset;
// 1 - remove the keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->key().track, E->key().key);
}
// 2 - remove overlapped keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
float newtime = snap_time(E->get().pos + motion);
int idx = animation->track_find_key(E->key().track, newtime, true);
- if (idx == -1)
+ if (idx == -1) {
continue;
+ }
SelectedKey sk;
sk.key = idx;
sk.track = E->key().track;
- if (selection.has(sk))
+ if (selection.has(sk)) {
continue; //already in selection, don't save
+ }
undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_position", E->key().track, newtime);
_AnimMoveRestore amr;
@@ -4990,27 +4815,23 @@ void AnimationTrackEditor::_move_selection_commit() {
// 3 - move the keys (re insert them)
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
float newpos = snap_time(E->get().pos + motion);
undo_redo->add_do_method(animation.ptr(), "track_insert_key", E->key().track, newpos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
// 4 - (undo) remove inserted keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
float newpos = snap_time(E->get().pos + motion);
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_position", E->key().track, newpos);
}
// 5 - (undo) reinsert keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", E->key().track, E->get().pos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
// 6 - (undo) reinsert overlapped keys
for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) {
-
_AnimMoveRestore &amr = E->get();
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition);
}
@@ -5020,7 +4841,6 @@ void AnimationTrackEditor::_move_selection_commit() {
// 7 - reselect
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
float oldpos = E->get().pos;
float newpos = snap_time(oldpos + motion);
@@ -5037,8 +4857,8 @@ void AnimationTrackEditor::_move_selection_commit() {
_update_key_edit();
}
-void AnimationTrackEditor::_move_selection_cancel() {
+void AnimationTrackEditor::_move_selection_cancel() {
moving_selection = false;
for (int i = 0; i < track_edits.size(); i++) {
track_edits[i]->update();
@@ -5048,29 +4868,26 @@ void AnimationTrackEditor::_move_selection_cancel() {
bool AnimationTrackEditor::is_moving_selection() const {
return moving_selection;
}
+
float AnimationTrackEditor::get_moving_selection_offset() const {
return moving_selection_offset;
}
void AnimationTrackEditor::_box_selection_draw() {
-
const Rect2 selection_rect = Rect2(Point2(), box_selection->get_size());
box_selection->draw_rect(selection_rect, get_theme_color("box_selection_fill_color", "Editor"));
box_selection->draw_rect(selection_rect, get_theme_color("box_selection_stroke_color", "Editor"), false, Math::round(EDSCALE));
}
void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_command() && mb->get_button_index() == BUTTON_WHEEL_DOWN) {
-
timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() * 1.05);
scroll->accept_event();
}
if (mb.is_valid() && mb->is_pressed() && mb->get_command() && mb->get_button_index() == BUTTON_WHEEL_UP) {
-
timeline->get_zoom()->set_value(timeline->get_zoom()->get_value() / 1.05);
scroll->accept_event();
}
@@ -5081,11 +4898,9 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
box_selecting_from = scroll->get_global_transform().xform(mb->get_position());
box_select_rect = Rect2();
} else if (box_selecting) {
-
if (box_selection->is_visible_in_tree()) {
//only if moved
for (int i = 0; i < track_edits.size(); i++) {
-
Rect2 local_rect = box_select_rect;
local_rect.position -= track_edits[i]->get_global_position();
track_edits[i]->append_to_selection(local_rect, mb->get_command());
@@ -5106,12 +4921,10 @@ void AnimationTrackEditor::_scroll_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_MIDDLE) {
-
timeline->set_value(timeline->get_value() - mm->get_relative().x / timeline->get_zoom_scale());
}
if (mm.is_valid() && box_selecting) {
-
if (!(mm->get_button_mask() & BUTTON_MASK_LEFT)) {
//no longer
box_selection->hide();
@@ -5158,7 +4971,6 @@ void AnimationTrackEditor::_cancel_bezier_edit() {
}
void AnimationTrackEditor::_bezier_edit(int p_for_track) {
-
_clear_selection(); //bezier probably wants to use a separate selection mode
bezier_edit->set_root(root);
bezier_edit->set_animation_and_track(animation, p_for_track);
@@ -5170,18 +4982,18 @@ void AnimationTrackEditor::_bezier_edit(int p_for_track) {
void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
//duplicait!
if (selection.size() && animation.is_valid() && (!transpose || (_get_track_selected() >= 0 && _get_track_selected() < animation->get_track_count()))) {
-
int top_track = 0x7FFFFFFF;
float top_time = 1e10;
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
const SelectedKey &sk = E->key();
float t = animation->track_get_key_time(sk.track, sk.key);
- if (t < top_time)
+ if (t < top_time) {
top_time = t;
- if (sk.track < top_track)
+ }
+ if (sk.track < top_track) {
top_track = sk.track;
+ }
}
ERR_FAIL_COND(top_track == 0x7FFFFFFF || top_time == 1e10);
@@ -5194,7 +5006,6 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
List<Pair<int, float>> new_selection_values;
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
const SelectedKey &sk = E->key();
float t = animation->track_get_key_time(sk.track, sk.key);
@@ -5202,11 +5013,13 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
float dst_time = t + (timeline->get_play_position() - top_time);
int dst_track = sk.track + (start_track - top_track);
- if (dst_track < 0 || dst_track >= animation->get_track_count())
+ if (dst_track < 0 || dst_track >= animation->get_track_count()) {
continue;
+ }
- if (animation->track_get_type(dst_track) != animation->track_get_type(sk.track))
+ if (animation->track_get_type(dst_track) != animation->track_get_type(sk.track)) {
continue;
+ }
int existing_idx = animation->track_find_key(dst_track, dst_time, true);
@@ -5219,7 +5032,6 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
new_selection_values.push_back(p);
if (existing_idx != -1) {
-
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", dst_track, dst_time, animation->track_get_key_value(dst_track, existing_idx), animation->track_get_key_transition(dst_track, existing_idx));
}
}
@@ -5230,14 +5042,14 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
Map<SelectedKey, KeyInfo> new_selection;
for (List<Pair<int, float>>::Element *E = new_selection_values.front(); E; E = E->next()) {
-
int track = E->get().first;
float time = E->get().second;
int existing_idx = animation->track_find_key(track, time, true);
- if (existing_idx == -1)
+ if (existing_idx == -1) {
continue;
+ }
SelectedKey sk2;
sk2.track = track;
sk2.key = existing_idx;
@@ -5253,8 +5065,8 @@ void AnimationTrackEditor::_anim_duplicate_keys(bool transpose) {
_update_key_edit();
}
}
-void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
+void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
last_menu_track_opt = p_option;
switch (p_option) {
case EDIT_COPY_TRACKS: {
@@ -5262,7 +5074,6 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
TreeItem *troot = track_copy_select->create_item();
for (int i = 0; i < animation->get_track_count(); i++) {
-
NodePath path = animation->track_get_path(i);
Node *node = nullptr;
@@ -5294,10 +5105,18 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
}
switch (animation->track_get_type(i)) {
- case Animation::TYPE_TRANSFORM: text += " (Transform)"; break;
- case Animation::TYPE_METHOD: text += " (Methods)"; break;
- case Animation::TYPE_BEZIER: text += " (Bezier)"; break;
- case Animation::TYPE_AUDIO: text += " (Audio)"; break;
+ case Animation::TYPE_TRANSFORM:
+ text += " (Transform)";
+ break;
+ case Animation::TYPE_METHOD:
+ text += " (Methods)";
+ break;
+ case Animation::TYPE_BEZIER:
+ text += " (Bezier)";
+ break;
+ case Animation::TYPE_AUDIO:
+ text += " (Audio)";
+ break;
default: {
};
}
@@ -5317,11 +5136,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
track_copy_dialog->popup_centered(Size2(350, 500) * EDSCALE);
} break;
case EDIT_COPY_TRACKS_CONFIRM: {
-
track_clipboard.clear();
TreeItem *root = track_copy_select->get_root();
if (root) {
-
TreeItem *it = root->get_children();
while (it) {
Dictionary md = it->get_metadata(0);
@@ -5351,7 +5168,6 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
}
} break;
case EDIT_PASTE_TRACKS: {
-
if (track_clipboard.size() == 0) {
EditorNode::get_singleton()->show_warning(TTR("Clipboard is empty"));
break;
@@ -5397,8 +5213,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
scale_dialog->popup_centered(Size2(200, 100) * EDSCALE);
} break;
case EDIT_SCALE_CONFIRM: {
- if (selection.empty())
+ if (selection.empty()) {
return;
+ }
float from_t = 1e20;
float to_t = -1e20;
@@ -5407,10 +5224,12 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
for (Map<SelectedKey, KeyInfo>::Element *E = selection.front(); E; E = E->next()) {
float t = animation->track_get_key_time(E->key().track, E->key().key);
- if (t < from_t)
+ if (t < from_t) {
from_t = t;
- if (t > to_t)
+ }
+ if (t > to_t) {
to_t = t;
+ }
}
len = to_t - from_t;
@@ -5418,7 +5237,6 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
pivot = timeline->get_play_position();
} else {
-
pivot = from_t;
}
@@ -5433,21 +5251,21 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
// 1-remove the keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->key().track, E->key().key);
}
// 2- remove overlapped keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
float newtime = (E->get().pos - from_t) * s + from_t;
int idx = animation->track_find_key(E->key().track, newtime, true);
- if (idx == -1)
+ if (idx == -1) {
continue;
+ }
SelectedKey sk;
sk.key = idx;
sk.track = E->key().track;
- if (selection.has(sk))
+ if (selection.has(sk)) {
continue; //already in selection, don't save
+ }
undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_position", E->key().track, newtime);
_AnimMoveRestore amr;
@@ -5463,27 +5281,23 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
#define _NEW_POS(m_ofs) (((s > 0) ? m_ofs : from_t + (len - (m_ofs - from_t))) - pivot) * ABS(s) + from_t
// 3-move the keys (re insert them)
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
float newpos = _NEW_POS(E->get().pos);
undo_redo->add_do_method(animation.ptr(), "track_insert_key", E->key().track, newpos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
// 4-(undo) remove inserted keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
float newpos = _NEW_POS(E->get().pos);
undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_position", E->key().track, newpos);
}
// 5-(undo) reinsert keys
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", E->key().track, E->get().pos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
// 6-(undo) reinsert overlapped keys
for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) {
-
_AnimMoveRestore &amr = E->get();
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition);
}
@@ -5493,18 +5307,17 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
// 7-reselect
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
float oldpos = E->get().pos;
float newpos = _NEW_POS(oldpos);
- if (newpos >= 0)
+ if (newpos >= 0) {
undo_redo->add_do_method(this, "_select_at_anim", animation, E->key().track, newpos);
+ }
undo_redo->add_undo_method(this, "_select_at_anim", animation, E->key().track, oldpos);
}
#undef _NEW_POS
undo_redo->commit_action();
} break;
case EDIT_DUPLICATE_SELECTION: {
-
if (bezier_edit->is_visible()) {
bezier_edit->duplicate_selection();
break;
@@ -5519,7 +5332,6 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
_anim_duplicate_keys(true);
} break;
case EDIT_DELETE_SELECTION: {
-
if (bezier_edit->is_visible()) {
bezier_edit->delete_selection();
break;
@@ -5529,7 +5341,6 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
undo_redo->create_action(TTR("Anim Delete Keys"));
for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
-
undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->key().track, E->key().key);
undo_redo->add_undo_method(animation.ptr(), "track_insert_key", E->key().track, E->get().pos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
}
@@ -5540,34 +5351,39 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
}
} break;
case EDIT_GOTO_NEXT_STEP: {
-
- if (animation.is_null())
+ if (animation.is_null()) {
break;
+ }
float step = animation->get_step();
- if (step == 0)
+ if (step == 0) {
step = 1;
+ }
float pos = timeline->get_play_position();
pos = Math::stepify(pos + step, step);
- if (pos > animation->get_length())
+ if (pos > animation->get_length()) {
pos = animation->get_length();
+ }
set_anim_pos(pos);
emit_signal("timeline_changed", pos, true);
} break;
case EDIT_GOTO_PREV_STEP: {
- if (animation.is_null())
+ if (animation.is_null()) {
break;
+ }
float step = animation->get_step();
- if (step == 0)
+ if (step == 0) {
step = 1;
+ }
float pos = timeline->get_play_position();
pos = Math::stepify(pos - step, step);
- if (pos < 0)
+ if (pos < 0) {
pos = 0;
+ }
set_anim_pos(pos);
emit_signal("timeline_changed", pos, true);
@@ -5602,9 +5418,7 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
}
void AnimationTrackEditor::_cleanup_animation(Ref<Animation> p_animation) {
-
for (int i = 0; i < p_animation->get_track_count(); i++) {
-
bool prop_exists = false;
Variant::Type valid_type = Variant::NIL;
Object *obj = nullptr;
@@ -5625,17 +5439,16 @@ void AnimationTrackEditor::_cleanup_animation(Ref<Animation> p_animation) {
}
if (!obj && cleanup_tracks->is_pressed()) {
-
p_animation->remove_track(i);
i--;
continue;
}
- if (!prop_exists || p_animation->track_get_type(i) != Animation::TYPE_VALUE || !cleanup_keys->is_pressed())
+ if (!prop_exists || p_animation->track_get_type(i) != Animation::TYPE_VALUE || !cleanup_keys->is_pressed()) {
continue;
+ }
for (int j = 0; j < p_animation->track_get_key_count(i); j++) {
-
Variant v = p_animation->track_get_key_value(i, j);
if (!Variant::can_convert(v.get_type(), valid_type)) {
@@ -5655,13 +5468,11 @@ void AnimationTrackEditor::_cleanup_animation(Ref<Animation> p_animation) {
}
void AnimationTrackEditor::_view_group_toggle() {
-
_update_tracks();
view_group->set_icon(get_theme_icon(view_group->is_pressed() ? "AnimationTrackList" : "AnimationTrackGroup", "EditorIcons"));
}
bool AnimationTrackEditor::is_grouping_tracks() {
-
if (!view_group) {
return false;
}
@@ -5670,7 +5481,6 @@ bool AnimationTrackEditor::is_grouping_tracks() {
}
void AnimationTrackEditor::_selection_changed() {
-
if (selected_filter->is_pressed()) {
_update_tracks(); //needs updatin
} else {
@@ -5685,14 +5495,13 @@ void AnimationTrackEditor::_selection_changed() {
}
float AnimationTrackEditor::snap_time(float p_value, bool p_relative) {
-
if (is_snap_enabled()) {
-
double snap_increment;
- if (timeline->is_using_fps() && step->get_value() > 0)
+ if (timeline->is_using_fps() && step->get_value() > 0) {
snap_increment = 1.0 / step->get_value();
- else
+ } else {
snap_increment = step->get_value();
+ }
if (p_relative) {
double rel = Math::fmod(timeline->get_value(), snap_increment);
@@ -5706,22 +5515,22 @@ float AnimationTrackEditor::snap_time(float p_value, bool p_relative) {
}
void AnimationTrackEditor::_show_imported_anim_warning() {
-
// It looks terrible on a single line but the TTR extractor doesn't support line breaks yet.
EditorNode::get_singleton()->show_warning(TTR("This animation belongs to an imported scene, so changes to imported tracks will not be saved.\n\nTo enable the ability to add custom tracks, navigate to the scene's import settings and set\n\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks\", then re-import.\nAlternatively, use an import preset that imports animations to separate files."),
TTR("Warning: Editing imported animation"));
}
void AnimationTrackEditor::_select_all_tracks_for_copy() {
-
TreeItem *track = track_copy_select->get_root()->get_children();
- if (!track)
+ if (!track) {
return;
+ }
bool all_selected = true;
while (track) {
- if (!track->is_checked(0))
+ if (!track->is_checked(0)) {
all_selected = false;
+ }
track = track->get_next();
}
@@ -5734,7 +5543,6 @@ void AnimationTrackEditor::_select_all_tracks_for_copy() {
}
void AnimationTrackEditor::_bind_methods() {
-
ClassDB::bind_method("_animation_update", &AnimationTrackEditor::_animation_update);
ClassDB::bind_method("_track_grab_focus", &AnimationTrackEditor::_track_grab_focus);
ClassDB::bind_method("_update_tracks", &AnimationTrackEditor::_update_tracks);
@@ -5944,7 +5752,7 @@ AnimationTrackEditor::AnimationTrackEditor() {
insert_confirm_bezier->set_text(TTR("Use Bezier Curves"));
icvb->add_child(insert_confirm_bezier);
keying = false;
- moving_selection = 0;
+ moving_selection = false;
key_edit = nullptr;
multi_key_edit = nullptr;
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 96a60cc135..6a46a1e3ff 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -121,7 +121,6 @@ public:
class AnimationTrackEditor;
class AnimationTrackEdit : public Control {
-
GDCLASS(AnimationTrackEdit, Control);
enum {
@@ -354,7 +353,6 @@ class AnimationTrackEditor : public VBoxContainer {
bool keying;
struct InsertData {
-
Animation::TrackType type;
NodePath path;
int track_idx;
@@ -395,14 +393,12 @@ class AnimationTrackEditor : public VBoxContainer {
//selection
struct SelectedKey {
-
int track;
int key;
bool operator<(const SelectedKey &p_key) const { return track == p_key.track ? key < p_key.key : track < p_key.track; };
};
struct KeyInfo {
-
float pos;
};
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index 695c294ad2..9fc67000f9 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -41,32 +41,32 @@
/// BOOL ///
int AnimationTrackEditBool::get_key_height() const {
-
Ref<Texture2D> checked = get_theme_icon("checked", "CheckBox");
return checked->get_height();
}
-Rect2 AnimationTrackEditBool::get_key_rect(int p_index, float p_pixels_sec) {
+Rect2 AnimationTrackEditBool::get_key_rect(int p_index, float p_pixels_sec) {
Ref<Texture2D> checked = get_theme_icon("checked", "CheckBox");
return Rect2(-checked->get_width() / 2, 0, checked->get_width(), get_size().height);
}
bool AnimationTrackEditBool::is_key_selectable_by_distance() const {
-
return false;
}
-void AnimationTrackEditBool::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
+void AnimationTrackEditBool::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
bool checked = get_animation()->track_get_key_value(get_track(), p_index);
Ref<Texture2D> icon = get_theme_icon(checked ? "checked" : "unchecked", "CheckBox");
Vector2 ofs(p_x - icon->get_width() / 2, int(get_size().height - icon->get_height()) / 2);
- if (ofs.x + icon->get_width() / 2 < p_clip_left)
+ if (ofs.x + icon->get_width() / 2 < p_clip_left) {
return;
+ }
- if (ofs.x + icon->get_width() / 2 > p_clip_right)
+ if (ofs.x + icon->get_width() / 2 > p_clip_right) {
return;
+ }
draw_texture(icon, ofs);
@@ -79,24 +79,21 @@ void AnimationTrackEditBool::draw_key(int p_index, float p_pixels_sec, int p_x,
/// COLOR ///
int AnimationTrackEditColor::get_key_height() const {
-
Ref<Font> font = get_theme_font("font", "Label");
return font->get_height() * 0.8;
}
-Rect2 AnimationTrackEditColor::get_key_rect(int p_index, float p_pixels_sec) {
+Rect2 AnimationTrackEditColor::get_key_rect(int p_index, float p_pixels_sec) {
Ref<Font> font = get_theme_font("font", "Label");
int fh = font->get_height() * 0.8;
return Rect2(-fh / 2, 0, fh, get_size().height);
}
bool AnimationTrackEditColor::is_key_selectable_by_distance() const {
-
return false;
}
void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) {
-
Ref<Font> font = get_theme_font("font", "Label");
int fh = (font->get_height() * 0.8);
@@ -104,21 +101,22 @@ void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int
int x_to = p_next_x - fh / 2 + 1;
fh /= 3;
- if (x_from > p_clip_right || x_to < p_clip_left)
+ if (x_from > p_clip_right || x_to < p_clip_left) {
return;
+ }
Color color = get_animation()->track_get_key_value(get_track(), p_index);
Color color_next = get_animation()->track_get_key_value(get_track(), p_index + 1);
if (x_from < p_clip_left) {
float c = float(p_clip_left - x_from) / (x_to - x_from);
- color = color.linear_interpolate(color_next, c);
+ color = color.lerp(color_next, c);
x_from = p_clip_left;
}
if (x_to > p_clip_right) {
float c = float(p_clip_right - x_from) / (x_to - x_from);
- color_next = color.linear_interpolate(color_next, c);
+ color_next = color.lerp(color_next, c);
x_to = p_clip_right;
}
@@ -143,7 +141,6 @@ void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int
}
void AnimationTrackEditColor::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
-
Color color = get_animation()->track_get_key_value(get_track(), p_index);
Ref<Font> font = get_theme_font("font", "Label");
@@ -166,11 +163,11 @@ void AnimationTrackEditColor::draw_key(int p_index, float p_pixels_sec, int p_x,
/// AUDIO ///
void AnimationTrackEditAudio::_preview_changed(ObjectID p_which) {
-
Object *object = ObjectDB::get_instance(id);
- if (!object)
+ if (!object) {
return;
+ }
Ref<AudioStream> stream = object->call("get_stream");
@@ -180,7 +177,6 @@ void AnimationTrackEditAudio::_preview_changed(ObjectID p_which) {
}
int AnimationTrackEditAudio::get_key_height() const {
-
if (!ObjectDB::get_instance(id)) {
return AnimationTrackEdit::get_key_height();
}
@@ -188,8 +184,8 @@ int AnimationTrackEditAudio::get_key_height() const {
Ref<Font> font = get_theme_font("font", "Label");
return int(font->get_height() * 1.5);
}
-Rect2 AnimationTrackEditAudio::get_key_rect(int p_index, float p_pixels_sec) {
+Rect2 AnimationTrackEditAudio::get_key_rect(int p_index, float p_pixels_sec) {
Object *object = ObjectDB::get_instance(id);
if (!object) {
@@ -207,7 +203,6 @@ Rect2 AnimationTrackEditAudio::get_key_rect(int p_index, float p_pixels_sec) {
float len = stream->get_length();
if (len == 0) {
-
Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(stream);
len = preview->get_length();
}
@@ -225,11 +220,10 @@ Rect2 AnimationTrackEditAudio::get_key_rect(int p_index, float p_pixels_sec) {
}
bool AnimationTrackEditAudio::is_key_selectable_by_distance() const {
-
return false;
}
-void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
+void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
Object *object = ObjectDB::get_instance(id);
if (!object) {
@@ -261,11 +255,13 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x,
int pixel_begin = p_x;
int pixel_end = p_x + pixel_len;
- if (pixel_end < p_clip_left)
+ if (pixel_end < p_clip_left) {
return;
+ }
- if (pixel_begin > p_clip_right)
+ if (pixel_begin > p_clip_right) {
return;
+ }
int from_x = MAX(pixel_begin, p_clip_left);
int to_x = MIN(pixel_end, p_clip_right);
@@ -276,8 +272,9 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x,
to_x = MIN(limit_x, to_x);
}
- if (to_x <= from_x)
+ if (to_x <= from_x) {
return;
+ }
Ref<Font> font = get_theme_font("font", "Label");
float fh = int(font->get_height() * 1.5);
@@ -289,7 +286,6 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x,
preview_len = preview->get_length();
for (int i = from_x; i < to_x; i++) {
-
float ofs = (i - pixel_begin) * preview_len / pixel_len;
float ofs_n = ((i + 1) - pixel_begin) * preview_len / pixel_len;
float max = preview->get_max(ofs, ofs_n) * 0.5 + 0.5;
@@ -325,7 +321,6 @@ void AnimationTrackEditAudio::draw_key(int p_index, float p_pixels_sec, int p_x,
}
void AnimationTrackEditAudio::set_node(Object *p_object) {
-
id = p_object->get_instance_id();
}
@@ -339,7 +334,6 @@ AnimationTrackEditAudio::AnimationTrackEditAudio() {
/// SPRITE FRAME / FRAME_COORDS ///
int AnimationTrackEditSpriteFrame::get_key_height() const {
-
if (!ObjectDB::get_instance(id)) {
return AnimationTrackEdit::get_key_height();
}
@@ -347,8 +341,8 @@ int AnimationTrackEditSpriteFrame::get_key_height() const {
Ref<Font> font = get_theme_font("font", "Label");
return int(font->get_height() * 2);
}
-Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_sec) {
+Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_sec) {
Object *object = ObjectDB::get_instance(id);
if (!object) {
@@ -358,7 +352,6 @@ Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_se
Size2 size;
if (Object::cast_to<Sprite2D>(object) || Object::cast_to<Sprite3D>(object)) {
-
Ref<Texture2D> texture = object->call("get_texture");
if (!texture.is_valid()) {
return AnimationTrackEdit::get_key_rect(p_index, p_pixels_sec);
@@ -380,7 +373,6 @@ Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_se
size.y /= vframes;
}
} else if (Object::cast_to<AnimatedSprite2D>(object) || Object::cast_to<AnimatedSprite3D>(object)) {
-
Ref<SpriteFrames> sf = object->call("get_sprite_frames");
if (sf.is_null()) {
return AnimationTrackEdit::get_key_rect(p_index, p_pixels_sec);
@@ -421,11 +413,10 @@ Rect2 AnimationTrackEditSpriteFrame::get_key_rect(int p_index, float p_pixels_se
}
bool AnimationTrackEditSpriteFrame::is_key_selectable_by_distance() const {
-
return false;
}
-void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
+void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
Object *object = ObjectDB::get_instance(id);
if (!object) {
@@ -437,7 +428,6 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in
Rect2 region;
if (Object::cast_to<Sprite2D>(object) || Object::cast_to<Sprite3D>(object)) {
-
texture = object->call("get_texture");
if (!texture.is_valid()) {
AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right);
@@ -459,7 +449,6 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in
region.size = texture->get_size();
if (bool(object->call("is_region"))) {
-
region = Rect2(object->call("get_region_rect"));
}
@@ -474,7 +463,6 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in
region.position.y += region.size.y * coords.y;
} else if (Object::cast_to<AnimatedSprite2D>(object) || Object::cast_to<AnimatedSprite3D>(object)) {
-
Ref<SpriteFrames> sf = object->call("get_sprite_frames");
if (sf.is_null()) {
AnimationTrackEdit::draw_key(p_index, p_pixels_sec, p_x, p_selected, p_clip_left, p_clip_right);
@@ -514,11 +502,13 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in
Rect2 rect(p_x, int(get_size().height - height) / 2, width, height);
- if (rect.position.x + rect.size.x < p_clip_left)
+ if (rect.position.x + rect.size.x < p_clip_left) {
return;
+ }
- if (rect.position.x > p_clip_right)
+ if (rect.position.x > p_clip_right) {
return;
+ }
Color accent = get_theme_color("accent_color", "Editor");
Color bg = accent;
@@ -534,19 +524,16 @@ void AnimationTrackEditSpriteFrame::draw_key(int p_index, float p_pixels_sec, in
}
void AnimationTrackEditSpriteFrame::set_node(Object *p_object) {
-
id = p_object->get_instance_id();
}
void AnimationTrackEditSpriteFrame::set_as_coords() {
-
is_coords = true;
}
/// SUB ANIMATION ///
int AnimationTrackEditSubAnim::get_key_height() const {
-
if (!ObjectDB::get_instance(id)) {
return AnimationTrackEdit::get_key_height();
}
@@ -554,8 +541,8 @@ int AnimationTrackEditSubAnim::get_key_height() const {
Ref<Font> font = get_theme_font("font", "Label");
return int(font->get_height() * 1.5);
}
-Rect2 AnimationTrackEditSubAnim::get_key_rect(int p_index, float p_pixels_sec) {
+Rect2 AnimationTrackEditSubAnim::get_key_rect(int p_index, float p_pixels_sec) {
Object *object = ObjectDB::get_instance(id);
if (!object) {
@@ -571,7 +558,6 @@ Rect2 AnimationTrackEditSubAnim::get_key_rect(int p_index, float p_pixels_sec) {
String anim = get_animation()->track_get_key_value(get_track(), p_index);
if (anim != "[stop]" && ap->has_animation(anim)) {
-
float len = ap->get_animation(anim)->get_length();
if (get_animation()->track_get_key_count(get_track()) > p_index + 1) {
@@ -587,11 +573,10 @@ Rect2 AnimationTrackEditSubAnim::get_key_rect(int p_index, float p_pixels_sec) {
}
bool AnimationTrackEditSubAnim::is_key_selectable_by_distance() const {
-
return false;
}
-void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
+void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
Object *object = ObjectDB::get_instance(id);
if (!object) {
@@ -609,7 +594,6 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_
String anim = get_animation()->track_get_key_value(get_track(), p_index);
if (anim != "[stop]" && ap->has_animation(anim)) {
-
float len = ap->get_animation(anim)->get_length();
if (get_animation()->track_get_key_count(get_track()) > p_index + 1) {
@@ -621,17 +605,20 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_
int pixel_begin = p_x;
int pixel_end = p_x + pixel_len;
- if (pixel_end < p_clip_left)
+ if (pixel_end < p_clip_left) {
return;
+ }
- if (pixel_begin > p_clip_right)
+ if (pixel_begin > p_clip_right) {
return;
+ }
int from_x = MAX(pixel_begin, p_clip_left);
int to_x = MIN(pixel_end, p_clip_right);
- if (to_x <= from_x)
+ if (to_x <= from_x) {
return;
+ }
Ref<Font> font = get_theme_font("font", "Label");
int fh = font->get_height() * 1.5;
@@ -651,18 +638,17 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_
Ref<Animation> animation = ap->get_animation(anim);
for (int i = 0; i < animation->get_track_count(); i++) {
-
float h = (rect.size.height - 2) / animation->get_track_count();
int y = 2 + h * i + h / 2;
for (int j = 0; j < animation->track_get_key_count(i); j++) {
-
float ofs = animation->track_get_key_time(i, j);
int x = p_x + ofs * p_pixels_sec + 2;
- if (x < from_x || x >= (to_x - 4))
+ if (x < from_x || x >= (to_x - 4)) {
continue;
+ }
lines.push_back(Point2(x, y));
lines.push_back(Point2(x + 1, y));
@@ -701,20 +687,17 @@ void AnimationTrackEditSubAnim::draw_key(int p_index, float p_pixels_sec, int p_
}
void AnimationTrackEditSubAnim::set_node(Object *p_object) {
-
id = p_object->get_instance_id();
}
//// VOLUME DB ////
int AnimationTrackEditVolumeDB::get_key_height() const {
-
Ref<Texture2D> volume_texture = get_theme_icon("ColorTrackVu", "EditorIcons");
return volume_texture->get_height() * 1.2;
}
void AnimationTrackEditVolumeDB::draw_bg(int p_clip_left, int p_clip_right) {
-
Ref<Texture2D> volume_texture = get_theme_icon("ColorTrackVu", "EditorIcons");
int tex_h = volume_texture->get_height();
@@ -726,7 +709,6 @@ void AnimationTrackEditVolumeDB::draw_bg(int p_clip_left, int p_clip_right) {
}
void AnimationTrackEditVolumeDB::draw_fg(int p_clip_left, int p_clip_right) {
-
Ref<Texture2D> volume_texture = get_theme_icon("ColorTrackVu", "EditorIcons");
int tex_h = volume_texture->get_height();
int y_from = (get_size().height - tex_h) / 2;
@@ -736,9 +718,9 @@ void AnimationTrackEditVolumeDB::draw_fg(int p_clip_left, int p_clip_right) {
}
void AnimationTrackEditVolumeDB::draw_key_link(int p_index, float p_pixels_sec, int p_x, int p_next_x, int p_clip_left, int p_clip_right) {
-
- if (p_x > p_clip_right || p_next_x < p_clip_left)
+ if (p_x > p_clip_right || p_next_x < p_clip_left) {
return;
+ }
float db = get_animation()->track_get_key_value(get_track(), p_index);
float db_n = get_animation()->track_get_key_value(get_track(), p_index + 1);
@@ -778,7 +760,6 @@ void AnimationTrackEditVolumeDB::draw_key_link(int p_index, float p_pixels_sec,
/// AUDIO ///
void AnimationTrackEditTypeAudio::_preview_changed(ObjectID p_which) {
-
for (int i = 0; i < get_animation()->track_get_key_count(get_track()); i++) {
Ref<AudioStream> stream = get_animation()->audio_track_get_key_stream(get_track(), i);
if (stream.is_valid() && stream->get_instance_id() == p_which) {
@@ -789,12 +770,11 @@ void AnimationTrackEditTypeAudio::_preview_changed(ObjectID p_which) {
}
int AnimationTrackEditTypeAudio::get_key_height() const {
-
Ref<Font> font = get_theme_font("font", "Label");
return int(font->get_height() * 1.5);
}
-Rect2 AnimationTrackEditTypeAudio::get_key_rect(int p_index, float p_pixels_sec) {
+Rect2 AnimationTrackEditTypeAudio::get_key_rect(int p_index, float p_pixels_sec) {
Ref<AudioStream> stream = get_animation()->audio_track_get_key_stream(get_track(), p_index);
if (!stream.is_valid()) {
@@ -807,7 +787,6 @@ Rect2 AnimationTrackEditTypeAudio::get_key_rect(int p_index, float p_pixels_sec)
float len = stream->get_length();
if (len == 0) {
-
Ref<AudioStreamPreview> preview = AudioStreamPreviewGenerator::get_singleton()->generate_preview(stream);
len = preview->get_length();
}
@@ -826,11 +805,10 @@ Rect2 AnimationTrackEditTypeAudio::get_key_rect(int p_index, float p_pixels_sec)
}
bool AnimationTrackEditTypeAudio::is_key_selectable_by_distance() const {
-
return false;
}
-void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
+void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
Ref<AudioStream> stream = get_animation()->audio_track_get_key_stream(get_track(), p_index);
if (!stream.is_valid()) {
@@ -845,12 +823,14 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int
float ofs_local = -len_resizing_rel / get_timeline()->get_zoom_scale();
if (len_resizing_start) {
start_ofs += ofs_local;
- if (start_ofs < 0)
+ if (start_ofs < 0) {
start_ofs = 0;
+ }
} else {
end_ofs += ofs_local;
- if (end_ofs < 0)
+ if (end_ofs < 0) {
end_ofs = 0;
+ }
}
}
@@ -881,11 +861,13 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int
int pixel_begin = p_x;
int pixel_end = p_x + pixel_len;
- if (pixel_end < p_clip_left)
+ if (pixel_end < p_clip_left) {
return;
+ }
- if (pixel_begin > p_clip_right)
+ if (pixel_begin > p_clip_right) {
return;
+ }
int from_x = MAX(pixel_begin, p_clip_left);
int to_x = MIN(pixel_end, p_clip_right);
@@ -909,7 +891,6 @@ void AnimationTrackEditTypeAudio::draw_key(int p_index, float p_pixels_sec, int
preview_len = preview->get_length();
for (int i = from_x; i < to_x; i++) {
-
float ofs = (i - pixel_begin) * preview_len / pixel_total_len;
float ofs_n = ((i + 1) - pixel_begin) * preview_len / pixel_total_len;
ofs += start_ofs;
@@ -952,9 +933,7 @@ AnimationTrackEditTypeAudio::AnimationTrackEditTypeAudio() {
}
bool AnimationTrackEditTypeAudio::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
-
if (p_point.x > get_timeline()->get_name_limit() && p_point.x < get_size().width - get_timeline()->get_buttons_width()) {
-
Dictionary drag_data = p_data;
if (drag_data.has("type") && String(drag_data["type"]) == "resource") {
Ref<AudioStream> res = drag_data["resource"];
@@ -964,7 +943,6 @@ bool AnimationTrackEditTypeAudio::can_drop_data(const Point2 &p_point, const Var
}
if (drag_data.has("type") && String(drag_data["type"]) == "files") {
-
Vector<String> files = drag_data["files"];
if (files.size() == 1) {
@@ -979,16 +957,14 @@ bool AnimationTrackEditTypeAudio::can_drop_data(const Point2 &p_point, const Var
return AnimationTrackEdit::can_drop_data(p_point, p_data);
}
-void AnimationTrackEditTypeAudio::drop_data(const Point2 &p_point, const Variant &p_data) {
+void AnimationTrackEditTypeAudio::drop_data(const Point2 &p_point, const Variant &p_data) {
if (p_point.x > get_timeline()->get_name_limit() && p_point.x < get_size().width - get_timeline()->get_buttons_width()) {
-
Ref<AudioStream> stream;
Dictionary drag_data = p_data;
if (drag_data.has("type") && String(drag_data["type"]) == "resource") {
stream = drag_data["resource"];
} else if (drag_data.has("type") && String(drag_data["type"]) == "files") {
-
Vector<String> files = drag_data["files"];
if (files.size() == 1) {
@@ -998,7 +974,6 @@ void AnimationTrackEditTypeAudio::drop_data(const Point2 &p_point, const Variant
}
if (stream.is_valid()) {
-
int x = p_point.x - get_timeline()->get_name_limit();
float ofs = x / get_timeline()->get_zoom_scale();
ofs += get_timeline()->get_value();
@@ -1023,12 +998,10 @@ void AnimationTrackEditTypeAudio::drop_data(const Point2 &p_point, const Variant
}
void AnimationTrackEditTypeAudio::_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseMotion> mm = p_event;
if (!len_resizing && mm.is_valid()) {
bool use_hsize_cursor = false;
for (int i = 0; i < get_animation()->track_get_key_count(get_track()); i++) {
-
Ref<AudioStream> stream = get_animation()->audio_track_get_key_stream(get_track(), i);
if (!stream.is_valid()) {
@@ -1086,7 +1059,6 @@ void AnimationTrackEditTypeAudio::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && get_default_cursor_shape() == CURSOR_HSIZE) {
-
len_resizing = true;
len_resizing_start = mb->get_shift();
len_resizing_from_px = mb->get_position().x;
@@ -1097,7 +1069,6 @@ void AnimationTrackEditTypeAudio::_gui_input(const Ref<InputEvent> &p_event) {
}
if (len_resizing && mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
float ofs_local = -len_resizing_rel / get_timeline()->get_zoom_scale();
if (len_resizing_start) {
float prev_ofs = get_animation()->audio_track_get_key_start_offset(get_track(), len_resizing_index);
@@ -1128,7 +1099,6 @@ void AnimationTrackEditTypeAudio::_gui_input(const Ref<InputEvent> &p_event) {
/// SUB ANIMATION ///
int AnimationTrackEditTypeAnimation::get_key_height() const {
-
if (!ObjectDB::get_instance(id)) {
return AnimationTrackEdit::get_key_height();
}
@@ -1136,8 +1106,8 @@ int AnimationTrackEditTypeAnimation::get_key_height() const {
Ref<Font> font = get_theme_font("font", "Label");
return int(font->get_height() * 1.5);
}
-Rect2 AnimationTrackEditTypeAnimation::get_key_rect(int p_index, float p_pixels_sec) {
+Rect2 AnimationTrackEditTypeAnimation::get_key_rect(int p_index, float p_pixels_sec) {
Object *object = ObjectDB::get_instance(id);
if (!object) {
@@ -1153,7 +1123,6 @@ Rect2 AnimationTrackEditTypeAnimation::get_key_rect(int p_index, float p_pixels_
String anim = get_animation()->animation_track_get_key_animation(get_track(), p_index);
if (anim != "[stop]" && ap->has_animation(anim)) {
-
float len = ap->get_animation(anim)->get_length();
if (get_animation()->track_get_key_count(get_track()) > p_index + 1) {
@@ -1169,11 +1138,10 @@ Rect2 AnimationTrackEditTypeAnimation::get_key_rect(int p_index, float p_pixels_
}
bool AnimationTrackEditTypeAnimation::is_key_selectable_by_distance() const {
-
return false;
}
-void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
+void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
Object *object = ObjectDB::get_instance(id);
if (!object) {
@@ -1191,7 +1159,6 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec,
String anim = get_animation()->animation_track_get_key_animation(get_track(), p_index);
if (anim != "[stop]" && ap->has_animation(anim)) {
-
float len = ap->get_animation(anim)->get_length();
if (get_animation()->track_get_key_count(get_track()) > p_index + 1) {
@@ -1203,17 +1170,20 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec,
int pixel_begin = p_x;
int pixel_end = p_x + pixel_len;
- if (pixel_end < p_clip_left)
+ if (pixel_end < p_clip_left) {
return;
+ }
- if (pixel_begin > p_clip_right)
+ if (pixel_begin > p_clip_right) {
return;
+ }
int from_x = MAX(pixel_begin, p_clip_left);
int to_x = MIN(pixel_end, p_clip_right);
- if (to_x <= from_x)
+ if (to_x <= from_x) {
return;
+ }
Ref<Font> font = get_theme_font("font", "Label");
int fh = font->get_height() * 1.5;
@@ -1233,18 +1203,17 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec,
Ref<Animation> animation = ap->get_animation(anim);
for (int i = 0; i < animation->get_track_count(); i++) {
-
float h = (rect.size.height - 2) / animation->get_track_count();
int y = 2 + h * i + h / 2;
for (int j = 0; j < animation->track_get_key_count(i); j++) {
-
float ofs = animation->track_get_key_time(i, j);
int x = p_x + ofs * p_pixels_sec + 2;
- if (x < from_x || x >= (to_x - 4))
+ if (x < from_x || x >= (to_x - 4)) {
continue;
+ }
lines.push_back(Point2(x, y));
lines.push_back(Point2(x + 1, y));
@@ -1283,7 +1252,6 @@ void AnimationTrackEditTypeAnimation::draw_key(int p_index, float p_pixels_sec,
}
void AnimationTrackEditTypeAnimation::set_node(Object *p_object) {
-
id = p_object->get_instance_id();
}
@@ -1292,23 +1260,19 @@ AnimationTrackEditTypeAnimation::AnimationTrackEditTypeAnimation() {
/////////
AnimationTrackEdit *AnimationTrackEditDefaultPlugin::create_value_track_edit(Object *p_object, Variant::Type p_type, const String &p_property, PropertyHint p_hint, const String &p_hint_string, int p_usage) {
-
if (p_property == "playing" && (p_object->is_class("AudioStreamPlayer") || p_object->is_class("AudioStreamPlayer2D") || p_object->is_class("AudioStreamPlayer3D"))) {
-
AnimationTrackEditAudio *audio = memnew(AnimationTrackEditAudio);
audio->set_node(p_object);
return audio;
}
if (p_property == "frame" && (p_object->is_class("Sprite2D") || p_object->is_class("Sprite3D") || p_object->is_class("AnimatedSprite2D") || p_object->is_class("AnimatedSprite3D"))) {
-
AnimationTrackEditSpriteFrame *sprite = memnew(AnimationTrackEditSpriteFrame);
sprite->set_node(p_object);
return sprite;
}
if (p_property == "frame_coords" && (p_object->is_class("Sprite2D") || p_object->is_class("Sprite3D"))) {
-
AnimationTrackEditSpriteFrame *sprite = memnew(AnimationTrackEditSpriteFrame);
sprite->set_as_coords();
sprite->set_node(p_object);
@@ -1316,14 +1280,12 @@ AnimationTrackEdit *AnimationTrackEditDefaultPlugin::create_value_track_edit(Obj
}
if (p_property == "current_animation" && (p_object->is_class("AnimationPlayer"))) {
-
AnimationTrackEditSubAnim *player = memnew(AnimationTrackEditSubAnim);
player->set_node(p_object);
return player;
}
if (p_property == "volume_db") {
-
AnimationTrackEditVolumeDB *vu = memnew(AnimationTrackEditVolumeDB);
return vu;
}
@@ -1339,12 +1301,10 @@ AnimationTrackEdit *AnimationTrackEditDefaultPlugin::create_value_track_edit(Obj
}
AnimationTrackEdit *AnimationTrackEditDefaultPlugin::create_audio_track_edit() {
-
return memnew(AnimationTrackEditTypeAudio);
}
AnimationTrackEdit *AnimationTrackEditDefaultPlugin::create_animation_track_edit(Object *p_object) {
-
AnimationTrackEditTypeAnimation *an = memnew(AnimationTrackEditTypeAnimation);
an->set_node(p_object);
return an;
diff --git a/editor/array_property_edit.cpp b/editor/array_property_edit.cpp
index 9f6785ec06..20f947e707 100644
--- a/editor/array_property_edit.cpp
+++ b/editor/array_property_edit.cpp
@@ -36,10 +36,10 @@
#define ITEMS_PER_PAGE 100
Variant ArrayPropertyEdit::get_array() const {
-
Object *o = ObjectDB::get_instance(obj);
- if (!o)
+ if (!o) {
return Array();
+ }
Variant arr = o->get(property);
if (!arr.is_array()) {
Callable::CallError ce;
@@ -51,47 +51,45 @@ Variant ArrayPropertyEdit::get_array() const {
void ArrayPropertyEdit::_notif_change() {
_change_notify();
}
-void ArrayPropertyEdit::_notif_changev(const String &p_v) {
+void ArrayPropertyEdit::_notif_changev(const String &p_v) {
_change_notify(p_v.utf8().get_data());
}
void ArrayPropertyEdit::_set_size(int p_size) {
-
Variant arr = get_array();
arr.call("resize", p_size);
Object *o = ObjectDB::get_instance(obj);
- if (!o)
+ if (!o) {
return;
+ }
o->set(property, arr);
}
void ArrayPropertyEdit::_set_value(int p_idx, const Variant &p_value) {
-
Variant arr = get_array();
arr.set(p_idx, p_value);
Object *o = ObjectDB::get_instance(obj);
- if (!o)
+ if (!o) {
return;
+ }
o->set(property, arr);
}
bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
-
String pn = p_name;
if (pn.begins_with("array/")) {
-
if (pn == "array/size") {
-
Variant arr = get_array();
int size = arr.call("size");
int newsize = p_value;
- if (newsize == size)
+ if (newsize == size) {
return true;
+ }
UndoRedo *ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Resize Array"));
@@ -102,7 +100,6 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
ur->add_undo_method(this, "_set_value", i, arr.get(i));
}
} else if (newsize > size) {
-
Variant init;
Callable::CallError ce;
Variant::Type new_type = subtype;
@@ -128,7 +125,6 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
}
} else if (pn.begins_with("indices")) {
-
if (pn.find("_") != -1) {
//type
int idx = pn.get_slicec('/', 1).get_slicec('_', 0).to_int();
@@ -173,13 +169,11 @@ bool ArrayPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
}
bool ArrayPropertyEdit::_get(const StringName &p_name, Variant &r_ret) const {
-
Variant arr = get_array();
//int size = arr.call("size");
String pn = p_name;
if (pn.begins_with("array/")) {
-
if (pn == "array/size") {
r_ret = arr.call("size");
return true;
@@ -189,14 +183,14 @@ bool ArrayPropertyEdit::_get(const StringName &p_name, Variant &r_ret) const {
return true;
}
} else if (pn.begins_with("indices")) {
-
if (pn.find("_") != -1) {
//type
int idx = pn.get_slicec('/', 1).get_slicec('_', 0).to_int();
bool valid;
r_ret = arr.get(idx, &valid);
- if (valid)
+ if (valid) {
r_ret = r_ret.get_type();
+ }
return valid;
} else {
@@ -216,21 +210,20 @@ bool ArrayPropertyEdit::_get(const StringName &p_name, Variant &r_ret) const {
}
void ArrayPropertyEdit::_get_property_list(List<PropertyInfo> *p_list) const {
-
Variant arr = get_array();
int size = arr.call("size");
p_list->push_back(PropertyInfo(Variant::INT, "array/size", PROPERTY_HINT_RANGE, "0,100000,1"));
int pages = size / ITEMS_PER_PAGE;
- if (pages > 0)
+ if (pages > 0) {
p_list->push_back(PropertyInfo(Variant::INT, "array/page", PROPERTY_HINT_RANGE, "0," + itos(pages) + ",1"));
+ }
int offset = page * ITEMS_PER_PAGE;
int items = MIN(size - offset, ITEMS_PER_PAGE);
for (int i = 0; i < items; i++) {
-
Variant v = arr.get(i + offset);
bool is_typed = arr.get_type() != Variant::ARRAY || subtype != Variant::NIL;
@@ -260,7 +253,6 @@ void ArrayPropertyEdit::_get_property_list(List<PropertyInfo> *p_list) const {
}
void ArrayPropertyEdit::edit(Object *p_obj, const StringName &p_prop, const String &p_hint_string, Variant::Type p_deftype) {
-
page = 0;
property = p_prop;
obj = p_obj->get_instance_id();
@@ -284,7 +276,6 @@ void ArrayPropertyEdit::edit(Object *p_obj, const StringName &p_prop, const Stri
}
Node *ArrayPropertyEdit::get_node() {
-
return Object::cast_to<Node>(ObjectDB::get_instance(obj));
}
@@ -293,7 +284,6 @@ bool ArrayPropertyEdit::_dont_undo_redo() {
}
void ArrayPropertyEdit::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_set_size"), &ArrayPropertyEdit::_set_size);
ClassDB::bind_method(D_METHOD("_set_value"), &ArrayPropertyEdit::_set_value);
ClassDB::bind_method(D_METHOD("_notif_change"), &ArrayPropertyEdit::_notif_change);
@@ -304,9 +294,9 @@ void ArrayPropertyEdit::_bind_methods() {
ArrayPropertyEdit::ArrayPropertyEdit() {
page = 0;
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
-
- if (i > 0)
+ if (i > 0) {
vtypes += ",";
+ }
vtypes += Variant::get_type_name(Variant::Type(i));
}
default_type = Variant::NIL;
diff --git a/editor/array_property_edit.h b/editor/array_property_edit.h
index 675b842128..d91701ccaf 100644
--- a/editor/array_property_edit.h
+++ b/editor/array_property_edit.h
@@ -34,7 +34,6 @@
#include "scene/main/node.h"
class ArrayPropertyEdit : public Reference {
-
GDCLASS(ArrayPropertyEdit, Reference);
int page;
diff --git a/editor/audio_stream_preview.cpp b/editor/audio_stream_preview.cpp
index fe28c913a7..9e4e157c96 100644
--- a/editor/audio_stream_preview.cpp
+++ b/editor/audio_stream_preview.cpp
@@ -35,10 +35,11 @@
float AudioStreamPreview::get_length() const {
return length;
}
-float AudioStreamPreview::get_max(float p_time, float p_time_next) const {
- if (length == 0)
+float AudioStreamPreview::get_max(float p_time, float p_time_next) const {
+ if (length == 0) {
return 0;
+ }
int max = preview.size() / 2;
int time_from = p_time / length * max;
@@ -53,7 +54,6 @@ float AudioStreamPreview::get_max(float p_time, float p_time_next) const {
uint8_t vmax = 0;
for (int i = time_from; i < time_to; i++) {
-
uint8_t v = preview[i * 2 + 1];
if (i == 0 || v > vmax) {
vmax = v;
@@ -62,10 +62,11 @@ float AudioStreamPreview::get_max(float p_time, float p_time_next) const {
return (vmax / 255.0) * 2.0 - 1.0;
}
-float AudioStreamPreview::get_min(float p_time, float p_time_next) const {
- if (length == 0)
+float AudioStreamPreview::get_min(float p_time, float p_time_next) const {
+ if (length == 0) {
return 0;
+ }
int max = preview.size() / 2;
int time_from = p_time / length * max;
@@ -80,7 +81,6 @@ float AudioStreamPreview::get_min(float p_time, float p_time_next) const {
uint8_t vmin = 255;
for (int i = time_from; i < time_to; i++) {
-
uint8_t v = preview[i * 2];
if (i == 0 || v < vmin) {
vmin = v;
@@ -101,7 +101,6 @@ void AudioStreamPreviewGenerator::_update_emit(ObjectID p_id) {
}
void AudioStreamPreviewGenerator::_preview_thread(void *p_preview) {
-
Preview *preview = (Preview *)p_preview;
float muxbuff_chunk_s = 0.25;
@@ -117,7 +116,6 @@ void AudioStreamPreviewGenerator::_preview_thread(void *p_preview) {
preview->playback->start();
while (frames_todo) {
-
int ofs_write = uint64_t(frames_total - frames_todo) * uint64_t(preview->preview->preview.size() / 2) / uint64_t(frames_total);
int to_read = MIN(frames_todo, mixbuff_chunk_frames);
int to_write = uint64_t(to_read) * uint64_t(preview->preview->preview.size() / 2) / uint64_t(frames_total);
@@ -137,7 +135,6 @@ void AudioStreamPreviewGenerator::_preview_thread(void *p_preview) {
}
for (int j = from; j < to; j++) {
-
max = MAX(max, mix_chunk[j].l);
max = MAX(max, mix_chunk[j].r);
@@ -199,8 +196,9 @@ Ref<AudioStreamPreview> AudioStreamPreviewGenerator::generate_preview(const Ref<
preview->preview->preview = maxmin;
preview->preview->length = len_s;
- if (preview->playback.is_valid())
+ if (preview->playback.is_valid()) {
preview->thread = Thread::create(_preview_thread, preview);
+ }
return preview->preview;
}
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 77e20b971c..3ea970a0f0 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -30,7 +30,7 @@
#include "code_editor.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/keyboard.h"
#include "core/string_builder.h"
#include "editor/editor_scale.h"
@@ -41,7 +41,6 @@
#include "scene/resources/dynamic_font.h"
void GotoLineDialog::popup_find_line(TextEdit *p_edit) {
-
text_editor = p_edit;
line->set_text(itos(text_editor->cursor_get_line()));
@@ -51,21 +50,19 @@ void GotoLineDialog::popup_find_line(TextEdit *p_edit) {
}
int GotoLineDialog::get_line() const {
-
return line->get_text().to_int();
}
void GotoLineDialog::ok_pressed() {
-
- if (get_line() < 1 || get_line() > text_editor->get_line_count())
+ if (get_line() < 1 || get_line() > text_editor->get_line_count()) {
return;
+ }
text_editor->unfold_line(get_line() - 1);
text_editor->cursor_set_line(get_line() - 1);
hide();
}
GotoLineDialog::GotoLineDialog() {
-
set_title(TTR("Go to Line"));
VBoxContainer *vbc = memnew(VBoxContainer);
@@ -88,9 +85,7 @@ GotoLineDialog::GotoLineDialog() {
}
void FindReplaceBar::_notification(int p_what) {
-
if (p_what == NOTIFICATION_READY) {
-
find_prev->set_icon(get_theme_icon("MoveUp", "EditorIcons"));
find_next->set_icon(get_theme_icon("MoveDown", "EditorIcons"));
hide_button->set_normal_texture(get_theme_icon("Close", "EditorIcons"));
@@ -98,10 +93,8 @@ void FindReplaceBar::_notification(int p_what) {
hide_button->set_pressed_texture(get_theme_icon("Close", "EditorIcons"));
hide_button->set_custom_minimum_size(hide_button->get_normal_texture()->get_size());
} else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
set_process_unhandled_input(is_visible_in_tree());
} else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
-
find_prev->set_icon(get_theme_icon("MoveUp", "EditorIcons"));
find_next->set_icon(get_theme_icon("MoveDown", "EditorIcons"));
hide_button->set_normal_texture(get_theme_icon("Close", "EditorIcons"));
@@ -114,22 +107,16 @@ void FindReplaceBar::_notification(int p_what) {
}
void FindReplaceBar::_unhandled_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
-
if (k->is_pressed() && (text_edit->has_focus() || vbc_lineedit->is_a_parent_of(get_focus_owner()))) {
-
bool accepted = true;
switch (k->get_keycode()) {
-
case KEY_ESCAPE: {
-
_hide_bar();
} break;
default: {
-
accepted = false;
} break;
}
@@ -142,7 +129,6 @@ void FindReplaceBar::_unhandled_input(const Ref<InputEvent> &p_event) {
}
bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col) {
-
int line, col;
String text = get_search_text();
@@ -180,7 +166,6 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
}
void FindReplaceBar::_replace() {
-
if (result_line != -1 && result_col != -1) {
text_edit->begin_complex_operation();
@@ -199,7 +184,6 @@ void FindReplaceBar::_replace() {
}
void FindReplaceBar::_replace_all() {
-
text_edit->disconnect("text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed));
// Line as x so it gets priority in comparison, column as y.
Point2i orig_cursor(text_edit->cursor_get_line(), text_edit->cursor_get_column());
@@ -289,7 +273,6 @@ void FindReplaceBar::_replace_all() {
}
void FindReplaceBar::_get_search_from(int &r_line, int &r_col) {
-
r_line = text_edit->cursor_get_line();
r_col = text_edit->cursor_get_column();
@@ -303,13 +286,16 @@ void FindReplaceBar::_get_search_from(int &r_line, int &r_col) {
}
void FindReplaceBar::_update_results_count() {
- if (results_count != -1)
+ if (results_count != -1) {
return;
+ }
results_count = 0;
String searched = get_search_text();
- if (searched.empty()) return;
+ if (searched.empty()) {
+ return;
+ }
String full_text = text_edit->get_text();
@@ -317,14 +303,18 @@ void FindReplaceBar::_update_results_count() {
while (true) {
int pos = is_case_sensitive() ? full_text.find(searched, from_pos) : full_text.findn(searched, from_pos);
- if (pos == -1) break;
+ if (pos == -1) {
+ break;
+ }
if (is_whole_words()) {
from_pos++; // Making sure we won't hit the same match next time, if we get out via a continue.
- if (pos > 0 && !is_symbol(full_text[pos - 1]))
+ if (pos > 0 && !is_symbol(full_text[pos - 1])) {
continue;
- if (pos + searched.length() < full_text.length() && !is_symbol(full_text[pos + searched.length()]))
+ }
+ if (pos + searched.length() < full_text.length() && !is_symbol(full_text[pos + searched.length()])) {
continue;
+ }
}
results_count++;
@@ -333,7 +323,6 @@ void FindReplaceBar::_update_results_count() {
}
void FindReplaceBar::_update_matches_label() {
-
if (search_text->get_text().empty() || results_count == -1) {
matches_label->hide();
} else {
@@ -345,13 +334,14 @@ void FindReplaceBar::_update_matches_label() {
}
bool FindReplaceBar::search_current() {
-
uint32_t flags = 0;
- if (is_whole_words())
+ if (is_whole_words()) {
flags |= TextEdit::SEARCH_WHOLE_WORDS;
- if (is_case_sensitive())
+ }
+ if (is_case_sensitive()) {
flags |= TextEdit::SEARCH_MATCH_CASE;
+ }
int line, col;
_get_search_from(line, col);
@@ -360,30 +350,34 @@ bool FindReplaceBar::search_current() {
}
bool FindReplaceBar::search_prev() {
-
- if (!is_visible())
+ if (!is_visible()) {
popup_search(true);
+ }
uint32_t flags = 0;
String text = get_search_text();
- if (is_whole_words())
+ if (is_whole_words()) {
flags |= TextEdit::SEARCH_WHOLE_WORDS;
- if (is_case_sensitive())
+ }
+ if (is_case_sensitive()) {
flags |= TextEdit::SEARCH_MATCH_CASE;
+ }
flags |= TextEdit::SEARCH_BACKWARDS;
int line, col;
_get_search_from(line, col);
- if (text_edit->is_selection_active())
+ if (text_edit->is_selection_active()) {
col--; // Skip currently selected word.
+ }
col -= text.length();
if (col < 0) {
line -= 1;
- if (line < 0)
+ if (line < 0) {
line = text_edit->get_line_count() - 1;
+ }
col = text_edit->get_line(line).length();
}
@@ -391,21 +385,24 @@ bool FindReplaceBar::search_prev() {
}
bool FindReplaceBar::search_next() {
-
- if (!is_visible())
+ if (!is_visible()) {
popup_search(true);
+ }
uint32_t flags = 0;
String text;
- if (replace_all_mode)
+ if (replace_all_mode) {
text = get_replace_text();
- else
+ } else {
text = get_search_text();
+ }
- if (is_whole_words())
+ if (is_whole_words()) {
flags |= TextEdit::SEARCH_WHOLE_WORDS;
- if (is_case_sensitive())
+ }
+ if (is_case_sensitive()) {
flags |= TextEdit::SEARCH_MATCH_CASE;
+ }
int line, col;
_get_search_from(line, col);
@@ -414,8 +411,9 @@ bool FindReplaceBar::search_next() {
col += text.length();
if (col > text_edit->get_line(line).length()) {
line += 1;
- if (line >= text_edit->get_line_count())
+ if (line >= text_edit->get_line_count()) {
line = 0;
+ }
col = 0;
}
}
@@ -424,9 +422,9 @@ bool FindReplaceBar::search_next() {
}
void FindReplaceBar::_hide_bar() {
-
- if (replace_text->has_focus() || search_text->has_focus())
+ if (replace_text->has_focus() || search_text->has_focus()) {
text_edit->grab_focus();
+ }
text_edit->set_search_text("");
result_line = -1;
@@ -435,10 +433,10 @@ void FindReplaceBar::_hide_bar() {
}
void FindReplaceBar::_show_search(bool p_focus_replace, bool p_show_only) {
-
show();
- if (p_show_only)
+ if (p_show_only) {
return;
+ }
if (p_focus_replace) {
search_text->deselect();
@@ -468,7 +466,6 @@ void FindReplaceBar::_show_search(bool p_focus_replace, bool p_show_only) {
}
void FindReplaceBar::popup_search(bool p_show_only) {
-
replace_text->hide();
hbc_button_replace->hide();
hbc_option_replace->hide();
@@ -477,7 +474,6 @@ void FindReplaceBar::popup_search(bool p_show_only) {
}
void FindReplaceBar::popup_replace() {
-
if (!replace_text->is_visible_in_tree()) {
replace_text->show();
hbc_button_replace->show();
@@ -490,13 +486,11 @@ void FindReplaceBar::popup_replace() {
}
void FindReplaceBar::_search_options_changed(bool p_pressed) {
-
results_count = -1;
search_current();
}
void FindReplaceBar::_editor_text_changed() {
-
results_count = -1;
if (is_visible_in_tree()) {
preserve_cursor = true;
@@ -506,14 +500,12 @@ void FindReplaceBar::_editor_text_changed() {
}
void FindReplaceBar::_search_text_changed(const String &p_text) {
-
results_count = -1;
search_current();
}
void FindReplaceBar::_search_text_entered(const String &p_text) {
-
- if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
search_prev();
} else {
search_next();
@@ -521,11 +513,10 @@ void FindReplaceBar::_search_text_entered(const String &p_text) {
}
void FindReplaceBar::_replace_text_entered(const String &p_text) {
-
if (selection_only->is_pressed() && text_edit->is_selection_active()) {
_replace_all();
_hide_bar();
- } else if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ } else if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
_replace();
search_prev();
} else {
@@ -534,44 +525,36 @@ void FindReplaceBar::_replace_text_entered(const String &p_text) {
}
String FindReplaceBar::get_search_text() const {
-
return search_text->get_text();
}
String FindReplaceBar::get_replace_text() const {
-
return replace_text->get_text();
}
bool FindReplaceBar::is_case_sensitive() const {
-
return case_sensitive->is_pressed();
}
bool FindReplaceBar::is_whole_words() const {
-
return whole_words->is_pressed();
}
bool FindReplaceBar::is_selection_only() const {
-
return selection_only->is_pressed();
}
void FindReplaceBar::set_error(const String &p_label) {
-
emit_signal("error", p_label);
}
void FindReplaceBar::set_text_edit(TextEdit *p_text_edit) {
-
results_count = -1;
text_edit = p_text_edit;
text_edit->connect("text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed));
}
void FindReplaceBar::_bind_methods() {
-
ClassDB::bind_method("_unhandled_input", &FindReplaceBar::_unhandled_input);
ClassDB::bind_method("_search_current", &FindReplaceBar::search_current);
@@ -581,7 +564,6 @@ void FindReplaceBar::_bind_methods() {
}
FindReplaceBar::FindReplaceBar() {
-
results_count = -1;
replace_all_mode = false;
preserve_cursor = false;
@@ -674,10 +656,10 @@ FindReplaceBar::FindReplaceBar() {
// This function should be used to handle shortcuts that could otherwise
// be handled too late if they weren't handled here.
void CodeTextEditor::_input(const Ref<InputEvent> &event) {
-
const Ref<InputEventKey> key_event = event;
- if (!key_event.is_valid() || !key_event->is_pressed())
+ if (!key_event.is_valid() || !key_event->is_pressed()) {
return;
+ }
if (ED_IS_SHORTCUT("script_text_editor/move_up", key_event)) {
move_lines_up();
@@ -702,13 +684,10 @@ void CodeTextEditor::_input(const Ref<InputEvent> &event) {
}
void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
-
if (mb->is_pressed() && mb->get_command()) {
-
if (mb->get_button_index() == BUTTON_WHEEL_UP) {
_zoom_in();
} else if (mb->get_button_index() == BUTTON_WHEEL_DOWN) {
@@ -719,7 +698,6 @@ void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMagnifyGesture> magnify_gesture = p_event;
if (magnify_gesture.is_valid()) {
-
Ref<DynamicFont> font = text_editor->get_theme_font("font");
if (font.is_valid()) {
@@ -737,7 +715,6 @@ void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
-
if (k->is_pressed()) {
if (ED_IS_SHORTCUT("script_editor/zoom_in", p_event)) {
_zoom_in();
@@ -763,8 +740,9 @@ void CodeTextEditor::_zoom_out() {
}
void CodeTextEditor::_zoom_changed() {
- if (font_resize_timer->get_time_left() == 0)
+ if (font_resize_timer->get_time_left() == 0) {
font_resize_timer->start();
+ }
}
void CodeTextEditor::_reset_zoom() {
@@ -777,7 +755,6 @@ void CodeTextEditor::_reset_zoom() {
}
void CodeTextEditor::_line_col_changed() {
-
String line = text_editor->get_line(text_editor->cursor_get_line());
int positional_column = 0;
@@ -800,7 +777,6 @@ void CodeTextEditor::_line_col_changed() {
}
void CodeTextEditor::_text_changed() {
-
if (text_editor->is_insert_text_operation()) {
code_complete_timer->start();
}
@@ -809,13 +785,13 @@ void CodeTextEditor::_text_changed() {
}
void CodeTextEditor::_code_complete_timer_timeout() {
- if (!is_visible_in_tree())
+ if (!is_visible_in_tree()) {
return;
+ }
text_editor->query_code_comple();
}
void CodeTextEditor::_complete_request() {
-
List<ScriptCodeCompletionOption> entries;
String ctext = text_editor->get_text_for_completion();
_code_complete_script(ctext, &entries);
@@ -823,8 +799,9 @@ void CodeTextEditor::_complete_request() {
if (code_complete_func) {
code_complete_func(code_complete_ud, ctext, &entries, forced);
}
- if (entries.size() == 0)
+ if (entries.size() == 0) {
return;
+ }
for (List<ScriptCodeCompletionOption>::Element *E = entries.front(); E; E = E->next()) {
E->get().icon = _get_completion_icon(E->get());
@@ -877,14 +854,12 @@ Ref<Texture2D> CodeTextEditor::_get_completion_icon(const ScriptCodeCompletionOp
}
void CodeTextEditor::_font_resize_timeout() {
-
if (_add_font_size(font_resize_val)) {
font_resize_val = 0;
}
}
bool CodeTextEditor::_add_font_size(int p_delta) {
-
Ref<DynamicFont> font = text_editor->get_theme_font("font");
if (font.is_valid()) {
@@ -902,7 +877,6 @@ bool CodeTextEditor::_add_font_size(int p_delta) {
}
void CodeTextEditor::update_editor_settings() {
-
text_editor->set_syntax_coloring(EditorSettings::get_singleton()->get("text_editor/highlighting/syntax_highlighting"));
text_editor->set_highlight_all_occurrences(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_all_occurrences"));
text_editor->set_highlight_current_line(EditorSettings::get_singleton()->get("text_editor/highlighting/highlight_current_line"));
@@ -938,7 +912,6 @@ void CodeTextEditor::trim_trailing_whitespace() {
for (int i = 0; i < text_editor->get_line_count(); i++) {
String line = text_editor->get_line(i);
if (line.ends_with(" ") || line.ends_with("\t")) {
-
if (!trimed_whitespace) {
text_editor->begin_complex_operation();
trimed_whitespace = true;
@@ -1086,10 +1059,12 @@ void CodeTextEditor::convert_case(CaseStyle p_case) {
for (int i = begin; i <= end; i++) {
int len = text_editor->get_line(i).length();
- if (i == end)
+ if (i == end) {
len = end_col;
- if (i == begin)
+ }
+ if (i == begin) {
len -= begin_col;
+ }
String new_line = text_editor->get_line(i).substr(i == begin ? begin_col : 0, len);
switch (p_case) {
@@ -1127,8 +1102,9 @@ void CodeTextEditor::move_lines_up() {
int line_id = i;
int next_id = i - 1;
- if (line_id == 0 || next_id < 0)
+ if (line_id == 0 || next_id < 0) {
return;
+ }
text_editor->unfold_line(line_id);
text_editor->unfold_line(next_id);
@@ -1143,8 +1119,9 @@ void CodeTextEditor::move_lines_up() {
int line_id = text_editor->cursor_get_line();
int next_id = line_id - 1;
- if (line_id == 0 || next_id < 0)
+ if (line_id == 0 || next_id < 0) {
return;
+ }
text_editor->unfold_line(line_id);
text_editor->unfold_line(next_id);
@@ -1168,8 +1145,9 @@ void CodeTextEditor::move_lines_down() {
int line_id = i;
int next_id = i + 1;
- if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count())
+ if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count()) {
return;
+ }
text_editor->unfold_line(line_id);
text_editor->unfold_line(next_id);
@@ -1184,8 +1162,9 @@ void CodeTextEditor::move_lines_down() {
int line_id = text_editor->cursor_get_line();
int next_id = line_id + 1;
- if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count())
+ if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count()) {
return;
+ }
text_editor->unfold_line(line_id);
text_editor->unfold_line(next_id);
@@ -1279,8 +1258,9 @@ void CodeTextEditor::toggle_inline_comment(const String &delimiter) {
int end = text_editor->get_selection_to_line();
// End of selection ends on the first column of the last line, ignore it.
- if (text_editor->get_selection_to_column() == 0)
+ if (text_editor->get_selection_to_column() == 0) {
end -= 1;
+ }
int col_to = text_editor->get_selection_to_column();
int cursor_pos = text_editor->cursor_get_column();
@@ -1312,14 +1292,17 @@ void CodeTextEditor::toggle_inline_comment(const String &delimiter) {
int offset = (is_commented ? -1 : 1) * delimiter.length();
int col_from = text_editor->get_selection_from_column() > 0 ? text_editor->get_selection_from_column() + offset : 0;
- if (is_commented && text_editor->cursor_get_column() == text_editor->get_line(text_editor->cursor_get_line()).length() + 1)
+ if (is_commented && text_editor->cursor_get_column() == text_editor->get_line(text_editor->cursor_get_line()).length() + 1) {
cursor_pos += 1;
+ }
- if (text_editor->get_selection_to_column() != 0 && col_to != text_editor->get_line(text_editor->get_selection_to_line()).length() + 1)
+ if (text_editor->get_selection_to_column() != 0 && col_to != text_editor->get_line(text_editor->get_selection_to_line()).length() + 1) {
col_to += offset;
+ }
- if (text_editor->cursor_get_column() != 0)
+ if (text_editor->cursor_get_column() != 0) {
cursor_pos += offset;
+ }
text_editor->select(begin, col_from, text_editor->get_selection_to_line(), col_to);
text_editor->cursor_set_column(cursor_pos);
@@ -1438,7 +1421,6 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) {
}
void CodeTextEditor::set_error(const String &p_error) {
-
error->set_text(p_error);
if (p_error != "") {
error->set_default_cursor_shape(CURSOR_POINTING_HAND);
@@ -1461,7 +1443,6 @@ void CodeTextEditor::goto_error() {
}
void CodeTextEditor::_update_font() {
-
text_editor->add_theme_font_override("font", get_theme_font("source", "EditorFonts"));
error->add_theme_font_override("font", get_theme_font("status_source", "EditorFonts"));
@@ -1472,13 +1453,13 @@ void CodeTextEditor::_update_font() {
int count = status_bar->get_child_count();
for (int i = 0; i < count; i++) {
Control *n = Object::cast_to<Control>(status_bar->get_child(i));
- if (n)
+ if (n) {
n->add_theme_font_override("font", status_bar_font);
+ }
}
}
void CodeTextEditor::_on_settings_change() {
-
_update_font();
font_size = EditorSettings::get_singleton()->get("interface/editor/code_font_size");
@@ -1535,7 +1516,6 @@ void CodeTextEditor::_error_pressed(const Ref<InputEvent> &p_event) {
}
void CodeTextEditor::_notification(int p_what) {
-
switch (p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
_load_theme_settings();
@@ -1566,18 +1546,17 @@ void CodeTextEditor::set_warning_nb(int p_warning_nb) {
warning_count_label->set_text(itos(p_warning_nb));
warning_count_label->set_visible(p_warning_nb > 0);
warning_button->set_visible(p_warning_nb > 0);
- if (!p_warning_nb)
+ if (!p_warning_nb) {
_set_show_warnings_panel(false);
+ }
}
void CodeTextEditor::toggle_bookmark() {
-
int line = text_editor->cursor_get_line();
text_editor->set_line_as_bookmark(line, !text_editor->is_line_set_as_bookmark(line));
}
void CodeTextEditor::goto_next_bookmark() {
-
List<int> bmarks;
text_editor->get_bookmarks(&bmarks);
if (bmarks.size() <= 0) {
@@ -1603,7 +1582,6 @@ void CodeTextEditor::goto_next_bookmark() {
}
void CodeTextEditor::goto_prev_bookmark() {
-
List<int> bmarks;
text_editor->get_bookmarks(&bmarks);
if (bmarks.size() <= 0) {
@@ -1629,7 +1607,6 @@ void CodeTextEditor::goto_prev_bookmark() {
}
void CodeTextEditor::remove_all_bookmarks() {
-
List<int> bmarks;
text_editor->get_bookmarks(&bmarks);
@@ -1639,7 +1616,6 @@ void CodeTextEditor::remove_all_bookmarks() {
}
void CodeTextEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_input"), &CodeTextEditor::_input);
ADD_SIGNAL(MethodInfo("validate_script"));
@@ -1663,7 +1639,6 @@ void CodeTextEditor::update_toggle_scripts_button() {
}
CodeTextEditor::CodeTextEditor() {
-
code_complete_func = nullptr;
ED_SHORTCUT("script_editor/zoom_in", TTR("Zoom In"), KEY_MASK_CMD | KEY_EQUAL);
ED_SHORTCUT("script_editor/zoom_out", TTR("Zoom Out"), KEY_MASK_CMD | KEY_MINUS);
diff --git a/editor/code_editor.h b/editor/code_editor.h
index 6b733a2b3c..d806be885f 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -41,7 +41,6 @@
#include "scene/main/timer.h"
class GotoLineDialog : public ConfirmationDialog {
-
GDCLASS(GotoLineDialog, ConfirmationDialog);
Label *line_label;
@@ -60,7 +59,6 @@ public:
};
class FindReplaceBar : public HBoxContainer {
-
GDCLASS(FindReplaceBar, HBoxContainer);
LineEdit *search_text;
@@ -138,7 +136,6 @@ public:
typedef void (*CodeTextEditorCodeCompleteFunc)(void *p_ud, const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_forced);
class CodeTextEditor : public VBoxContainer {
-
GDCLASS(CodeTextEditor, VBoxContainer);
TextEdit *text_editor;
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index bef5c3c2b0..62b5911ac1 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -47,7 +47,6 @@ static Node *_find_first_script(Node *p_root, Node *p_node) {
}
for (int i = 0; i < p_node->get_child_count(); i++) {
-
Node *ret = _find_first_script(p_root, p_node->get_child(i));
if (ret) {
return ret;
@@ -58,49 +57,46 @@ static Node *_find_first_script(Node *p_root, Node *p_node) {
}
class ConnectDialogBinds : public Object {
-
GDCLASS(ConnectDialogBinds, Object);
public:
Vector<Variant> params;
bool _set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name.begins_with("bind/")) {
int which = name.get_slice("/", 1).to_int() - 1;
ERR_FAIL_INDEX_V(which, params.size(), false);
params.write[which] = p_value;
- } else
+ } else {
return false;
+ }
return true;
}
bool _get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name.begins_with("bind/")) {
int which = name.get_slice("/", 1).to_int() - 1;
ERR_FAIL_INDEX_V(which, params.size(), false);
r_ret = params[which];
- } else
+ } else {
return false;
+ }
return true;
}
void _get_property_list(List<PropertyInfo> *p_list) const {
-
for (int i = 0; i < params.size(); i++) {
p_list->push_back(PropertyInfo(params[i].get_type(), "bind/" + itos(i + 1)));
}
}
void notify_changed() {
-
_change_notify();
}
@@ -112,7 +108,6 @@ public:
* Signal automatically called by parent dialog.
*/
void ConnectDialog::ok_pressed() {
-
if (dst_method->get_text() == "") {
error->set_text(TTR("Method in target node must be specified."));
error->popup_centered();
@@ -149,11 +144,11 @@ void ConnectDialog::_text_entered(const String &p_text) {
* Called each time a target node is selected within the target node tree.
*/
void ConnectDialog::_tree_node_selected() {
-
Node *current = tree->get_selected();
- if (!current)
+ if (!current) {
return;
+ }
dst_path = source->get_path_to(current);
_update_ok_enabled();
@@ -163,28 +158,56 @@ void ConnectDialog::_tree_node_selected() {
* Adds a new parameter bind to connection.
*/
void ConnectDialog::_add_bind() {
-
- if (cdbinds->params.size() >= VARIANT_ARG_MAX)
+ if (cdbinds->params.size() >= VARIANT_ARG_MAX) {
return;
+ }
Variant::Type vt = (Variant::Type)type_list->get_item_id(type_list->get_selected());
Variant value;
switch (vt) {
- case Variant::BOOL: value = false; break;
- case Variant::INT: value = 0; break;
- case Variant::FLOAT: value = 0.0; break;
- case Variant::STRING: value = ""; break;
- case Variant::STRING_NAME: value = ""; break;
- case Variant::VECTOR2: value = Vector2(); break;
- case Variant::RECT2: value = Rect2(); break;
- case Variant::VECTOR3: value = Vector3(); break;
- case Variant::PLANE: value = Plane(); break;
- case Variant::QUAT: value = Quat(); break;
- case Variant::AABB: value = AABB(); break;
- case Variant::BASIS: value = Basis(); break;
- case Variant::TRANSFORM: value = Transform(); break;
- case Variant::COLOR: value = Color(); break;
+ case Variant::BOOL:
+ value = false;
+ break;
+ case Variant::INT:
+ value = 0;
+ break;
+ case Variant::FLOAT:
+ value = 0.0;
+ break;
+ case Variant::STRING:
+ value = "";
+ break;
+ case Variant::STRING_NAME:
+ value = "";
+ break;
+ case Variant::VECTOR2:
+ value = Vector2();
+ break;
+ case Variant::RECT2:
+ value = Rect2();
+ break;
+ case Variant::VECTOR3:
+ value = Vector3();
+ break;
+ case Variant::PLANE:
+ value = Plane();
+ break;
+ case Variant::QUAT:
+ value = Quat();
+ break;
+ case Variant::AABB:
+ value = AABB();
+ break;
+ case Variant::BASIS:
+ value = Basis();
+ break;
+ case Variant::TRANSFORM:
+ value = Transform();
+ break;
+ case Variant::COLOR:
+ value = Color();
+ break;
default: {
ERR_FAIL();
} break;
@@ -200,10 +223,10 @@ void ConnectDialog::_add_bind() {
* Remove parameter bind from connection.
*/
void ConnectDialog::_remove_bind() {
-
String st = bind_editor->get_selected_path();
- if (st == "")
+ if (st == "") {
return;
+ }
int idx = st.get_slice("/", 1).to_int() - 1;
ERR_FAIL_INDEX(idx, cdbinds->params.size());
@@ -216,7 +239,6 @@ void ConnectDialog::_remove_bind() {
* node is selected and valid in the selected mode.
*/
void ConnectDialog::_update_ok_enabled() {
-
Node *target = tree->get_selected();
if (target == nullptr) {
@@ -233,14 +255,12 @@ void ConnectDialog::_update_ok_enabled() {
}
void ConnectDialog::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
bind_editor->edit(cdbinds);
}
}
void ConnectDialog::_bind_methods() {
-
ClassDB::bind_method("_cancel", &ConnectDialog::_cancel_pressed);
ClassDB::bind_method("_update_ok_enabled", &ConnectDialog::_update_ok_enabled);
@@ -248,50 +268,42 @@ void ConnectDialog::_bind_methods() {
}
Node *ConnectDialog::get_source() const {
-
return source;
}
StringName ConnectDialog::get_signal_name() const {
-
return signal;
}
NodePath ConnectDialog::get_dst_path() const {
-
return dst_path;
}
void ConnectDialog::set_dst_node(Node *p_node) {
-
tree->set_selected(p_node);
}
StringName ConnectDialog::get_dst_method_name() const {
-
String txt = dst_method->get_text();
- if (txt.find("(") != -1)
+ if (txt.find("(") != -1) {
txt = txt.left(txt.find("(")).strip_edges();
+ }
return txt;
}
void ConnectDialog::set_dst_method(const StringName &p_method) {
-
dst_method->set_text(p_method);
}
Vector<Variant> ConnectDialog::get_binds() const {
-
return cdbinds->params;
}
bool ConnectDialog::get_deferred() const {
-
return deferred->is_pressed();
}
bool ConnectDialog::get_oneshot() const {
-
return oneshot->is_pressed();
}
@@ -299,7 +311,6 @@ bool ConnectDialog::get_oneshot() const {
* Returns true if ConnectDialog is being used to edit an existing connection.
*/
bool ConnectDialog::is_editing() const {
-
return bEditMode;
}
@@ -309,7 +320,6 @@ bool ConnectDialog::is_editing() const {
* If editing an existing connection, previous data is retained.
*/
void ConnectDialog::init(ConnectionData c, bool bEdit) {
-
set_hide_on_ok(false);
source = static_cast<Node *>(c.source);
@@ -339,17 +349,16 @@ void ConnectDialog::init(ConnectionData c, bool bEdit) {
}
void ConnectDialog::popup_dialog(const String &p_for_signal) {
-
from_signal->set_text(p_for_signal);
error_label->add_theme_color_override("font_color", error_label->get_theme_color("error_color", "Editor"));
- if (!advanced->is_pressed())
+ if (!advanced->is_pressed()) {
error_label->set_visible(!_find_first_script(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root()));
+ }
popup_centered();
}
void ConnectDialog::_advanced_pressed() {
-
if (advanced->is_pressed()) {
set_min_size(Size2(900, 500) * EDSCALE);
connect_to_label->set_text(TTR("Connect to Node:"));
@@ -373,7 +382,6 @@ void ConnectDialog::_advanced_pressed() {
}
ConnectDialog::ConnectDialog() {
-
set_min_size(Size2(600, 500) * EDSCALE);
VBoxContainer *vbc = memnew(VBoxContainer);
@@ -487,7 +495,6 @@ ConnectDialog::ConnectDialog() {
}
ConnectDialog::~ConnectDialog() {
-
memdelete(cdbinds);
}
@@ -495,7 +502,6 @@ ConnectDialog::~ConnectDialog() {
// Originally copied and adapted from EditorProperty, try to keep style in sync.
Control *ConnectionsDockTree::make_custom_tooltip(const String &p_text) const {
-
EditorHelpBit *help_bit = memnew(EditorHelpBit);
help_bit->add_theme_style_override("panel", get_theme_stylebox("panel", "TooltipPanel"));
help_bit->get_rich_text()->set_fixed_size_to_width(360 * EDSCALE);
@@ -508,7 +514,6 @@ Control *ConnectionsDockTree::make_custom_tooltip(const String &p_text) const {
}
struct _ConnectionsDockMethodInfoSort {
-
_FORCE_INLINE_ bool operator()(const MethodInfo &a, const MethodInfo &b) const {
return a.name < b.name;
}
@@ -519,7 +524,6 @@ struct _ConnectionsDockMethodInfoSort {
* Creates or edits connections based on state of the ConnectDialog when "Connect" is pressed.
*/
void ConnectionsDock::_make_or_edit_connection() {
-
TreeItem *it = tree->get_selected();
ERR_FAIL_COND(!it);
@@ -588,12 +592,12 @@ void ConnectionsDock::_make_or_edit_connection() {
* Creates single connection w/ undo-redo functionality.
*/
void ConnectionsDock::_connect(ConnectDialog::ConnectionData cToMake) {
-
Node *source = static_cast<Node *>(cToMake.source);
Node *target = static_cast<Node *>(cToMake.target);
- if (!source || !target)
+ if (!source || !target) {
return;
+ }
undo_redo->create_action(vformat(TTR("Connect '%s' to '%s'"), String(cToMake.signal), String(cToMake.method)));
@@ -613,7 +617,6 @@ void ConnectionsDock::_connect(ConnectDialog::ConnectionData cToMake) {
* Break single connection w/ undo-redo functionality.
*/
void ConnectionsDock::_disconnect(TreeItem &item) {
-
Connection cd = item.get_metadata(0);
ConnectDialog::ConnectionData c = cd;
@@ -636,11 +639,11 @@ void ConnectionsDock::_disconnect(TreeItem &item) {
* Can undo-redo as a single action.
*/
void ConnectionsDock::_disconnect_all() {
-
TreeItem *item = tree->get_selected();
- if (!_is_item_signal(*item))
+ if (!_is_item_signal(*item)) {
return;
+ }
TreeItem *child = item->get_children();
String signalName = item->get_metadata(0).operator Dictionary()["name"];
@@ -663,7 +666,6 @@ void ConnectionsDock::_disconnect_all() {
}
void ConnectionsDock::_tree_item_selected() {
-
TreeItem *item = tree->get_selected();
if (!item) { // Unlikely. Disable button just in case.
connect_button->set_text(TTR("Connect..."));
@@ -681,8 +683,9 @@ void ConnectionsDock::_tree_item_activated() { // "Activation" on double-click.
TreeItem *item = tree->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
if (_is_item_signal(*item)) {
_open_connection_dialog(*item);
@@ -692,7 +695,6 @@ void ConnectionsDock::_tree_item_activated() { // "Activation" on double-click.
}
bool ConnectionsDock::_is_item_signal(TreeItem &item) {
-
return (item.get_parent() == tree->get_root() || item.get_parent()->get_parent() == tree->get_root());
}
@@ -700,7 +702,6 @@ bool ConnectionsDock::_is_item_signal(TreeItem &item) {
* Open connection dialog with TreeItem data to CREATE a brand-new connection.
*/
void ConnectionsDock::_open_connection_dialog(TreeItem &item) {
-
String signal = item.get_metadata(0).operator Dictionary()["name"];
const String &signalname = signal;
String midname = selectedNode->get_name();
@@ -741,7 +742,6 @@ void ConnectionsDock::_open_connection_dialog(TreeItem &item) {
* Open connection dialog with Connection data to EDIT an existing connection.
*/
void ConnectionsDock::_open_connection_dialog(ConnectDialog::ConnectionData cToEdit) {
-
Node *src = static_cast<Node *>(cToEdit.source);
Node *dst = static_cast<Node *>(cToEdit.target);
@@ -756,21 +756,23 @@ void ConnectionsDock::_open_connection_dialog(ConnectDialog::ConnectionData cToE
* Open slot method location in script editor.
*/
void ConnectionsDock::_go_to_script(TreeItem &item) {
-
- if (_is_item_signal(item))
+ if (_is_item_signal(item)) {
return;
+ }
Connection cd = item.get_metadata(0);
ConnectDialog::ConnectionData c = cd;
ERR_FAIL_COND(c.source != selectedNode); //shouldn't happen but...bugcheck
- if (!c.target)
+ if (!c.target) {
return;
+ }
Ref<Script> script = c.target->get_script();
- if (script.is_null())
+ if (script.is_null()) {
return;
+ }
if (script.is_valid() && ScriptEditor::get_singleton()->script_goto_method(script, c.method)) {
editor->call("_editor_select", EditorNode::EDITOR_SCRIPT);
@@ -778,11 +780,11 @@ void ConnectionsDock::_go_to_script(TreeItem &item) {
}
void ConnectionsDock::_handle_signal_menu_option(int option) {
-
TreeItem *item = tree->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
switch (option) {
case CONNECT: {
@@ -797,11 +799,11 @@ void ConnectionsDock::_handle_signal_menu_option(int option) {
}
void ConnectionsDock::_handle_slot_menu_option(int option) {
-
TreeItem *item = tree->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
switch (option) {
case EDIT: {
@@ -819,11 +821,11 @@ void ConnectionsDock::_handle_slot_menu_option(int option) {
}
void ConnectionsDock::_rmb_pressed(Vector2 position) {
-
TreeItem *item = tree->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
Vector2 global_position = tree->get_global_position() + position;
@@ -837,12 +839,10 @@ void ConnectionsDock::_rmb_pressed(Vector2 position) {
}
void ConnectionsDock::_close() {
-
hide();
}
void ConnectionsDock::_connect_pressed() {
-
TreeItem *item = tree->get_selected();
if (!item) {
connect_button->set_disabled(true);
@@ -858,29 +858,26 @@ void ConnectionsDock::_connect_pressed() {
}
void ConnectionsDock::_notification(int p_what) {
-
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
update_tree();
}
}
void ConnectionsDock::_bind_methods() {
-
ClassDB::bind_method("update_tree", &ConnectionsDock::update_tree);
}
void ConnectionsDock::set_node(Node *p_node) {
-
selectedNode = p_node;
update_tree();
}
void ConnectionsDock::update_tree() {
-
tree->clear();
- if (!selectedNode)
+ if (!selectedNode) {
return;
+ }
TreeItem *root = tree->create_item();
@@ -892,27 +889,25 @@ void ConnectionsDock::update_tree() {
StringName base = selectedNode->get_class();
while (base) {
-
List<MethodInfo> node_signals2;
Ref<Texture2D> icon;
String name;
if (!did_script) {
-
Ref<Script> scr = selectedNode->get_script();
if (scr.is_valid()) {
scr->get_script_signal_list(&node_signals2);
- if (scr->get_path().is_resource_file())
+ if (scr->get_path().is_resource_file()) {
name = scr->get_path().get_file();
- else
+ } else {
name = scr->get_class();
+ }
if (has_theme_icon(scr->get_class(), "EditorIcons")) {
icon = get_theme_icon(scr->get_class(), "EditorIcons");
}
}
} else {
-
ClassDB::get_signal_list(base, &node_signals2, true);
if (has_theme_icon(base, "EditorIcons")) {
icon = get_theme_icon(base, "EditorIcons");
@@ -937,7 +932,6 @@ void ConnectionsDock::update_tree() {
}
for (List<MethodInfo>::Element *E = node_signals2.front(); E; E = E->next()) {
-
MethodInfo &mi = E->get();
StringName signal_name = mi.name;
@@ -945,11 +939,11 @@ void ConnectionsDock::update_tree() {
PackedStringArray argnames;
if (mi.arguments.size()) {
for (int i = 0; i < mi.arguments.size(); i++) {
-
PropertyInfo &pi = mi.arguments[i];
- if (i > 0)
+ if (i > 0) {
signaldesc += ", ";
+ }
String tname = "var";
if (pi.type == Variant::OBJECT && pi.class_name != StringName()) {
tname = pi.class_name.operator String();
@@ -1012,28 +1006,30 @@ void ConnectionsDock::update_tree() {
selectedNode->get_signal_connection_list(signal_name, &connections);
for (List<Object::Connection>::Element *F = connections.front(); F; F = F->next()) {
-
Connection cn = F->get();
- if (!(cn.flags & CONNECT_PERSIST))
+ if (!(cn.flags & CONNECT_PERSIST)) {
continue;
+ }
ConnectDialog::ConnectionData c = cn;
Node *target = Object::cast_to<Node>(c.target);
- if (!target)
+ if (!target) {
continue;
+ }
String path = String(selectedNode->get_path_to(target)) + " :: " + c.method + "()";
- if (c.flags & CONNECT_DEFERRED)
+ if (c.flags & CONNECT_DEFERRED) {
path += " (deferred)";
- if (c.flags & CONNECT_ONESHOT)
+ }
+ if (c.flags & CONNECT_ONESHOT) {
path += " (oneshot)";
+ }
if (c.binds.size()) {
-
path += " binds(";
for (int i = 0; i < c.binds.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
path += ", ";
+ }
path += c.binds[i].operator String();
}
path += ")";
@@ -1059,7 +1055,6 @@ void ConnectionsDock::update_tree() {
}
ConnectionsDock::ConnectionsDock(EditorNode *p_editor) {
-
editor = p_editor;
set_name(TTR("Signals"));
diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h
index 91d0d5c32c..d0c8d939cf 100644
--- a/editor/connections_dialog.h
+++ b/editor/connections_dialog.h
@@ -50,7 +50,6 @@ class PopupMenu;
class ConnectDialogBinds;
class ConnectDialog : public ConfirmationDialog {
-
GDCLASS(ConnectDialog, ConfirmationDialog);
public:
@@ -142,12 +141,10 @@ public:
// Custom Tree needed to use a RichTextLabel as tooltip control
// when display signal documentation.
class ConnectionsDockTree : public Tree {
-
virtual Control *make_custom_tooltip(const String &p_text) const;
};
class ConnectionsDock : public VBoxContainer {
-
GDCLASS(ConnectionsDock, VBoxContainer);
//Right-click Pop-up Menu Options.
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 6cbb1b1791..75fff03297 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -41,7 +41,6 @@
#include "scene/gui/box_container.h"
void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const String &p_select_type) {
-
type_list.clear();
ClassDB::get_class_list(&type_list);
ScriptServer::get_global_class_list(&type_list);
@@ -52,7 +51,6 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const St
FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::READ);
if (f) {
-
TreeItem *root = recent->create_item();
while (!f->eof_reached()) {
@@ -75,7 +73,6 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const St
favorite_list.clear();
if (f) {
-
while (!f->eof_reached()) {
String l = f->get_line().strip_edges();
@@ -120,49 +117,50 @@ void CreateDialog::popup_create(bool p_dont_clear, bool p_replace_mode, const St
}
void CreateDialog::_text_changed(const String &p_newtext) {
-
_update_search();
}
void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {
-
Ref<InputEventKey> k = p_ie;
if (k.is_valid() && (k->get_keycode() == KEY_UP ||
k->get_keycode() == KEY_DOWN ||
k->get_keycode() == KEY_PAGEUP ||
k->get_keycode() == KEY_PAGEDOWN)) {
-
search_options->call("_gui_input", k);
search_box->accept_event();
}
}
void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p_types, TreeItem *p_root, TreeItem **to_select) {
-
- if (p_types.has(p_type))
+ if (p_types.has(p_type)) {
return;
+ }
bool cpp_type = ClassDB::class_exists(p_type);
EditorData &ed = EditorNode::get_editor_data();
- if (p_type == base_type)
+ if (p_type == base_type) {
return;
+ }
if (cpp_type) {
- if (!ClassDB::is_parent_class(p_type, base_type))
+ if (!ClassDB::is_parent_class(p_type, base_type)) {
return;
+ }
} else {
if (!search_loaded_scripts.has(p_type)) {
search_loaded_scripts[p_type] = ed.script_class_load_script(p_type);
}
- if (!ScriptServer::is_global_class(p_type) || !ed.script_class_is_parent(p_type, base_type))
+ if (!ScriptServer::is_global_class(p_type) || !ed.script_class_is_parent(p_type, base_type)) {
return;
+ }
String script_path = ScriptServer::get_global_class_path(p_type);
if (script_path.find("res://addons/", 0) != -1) {
- if (!EditorNode::get_singleton()->is_addon_plugin_enabled(script_path.get_slicec('/', 3)))
+ if (!EditorNode::get_singleton()->is_addon_plugin_enabled(script_path.get_slicec('/', 3))) {
return;
+ }
}
}
@@ -171,16 +169,15 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p
TreeItem *parent = p_root;
if (inherits.length()) {
-
if (!p_types.has(inherits)) {
-
add_type(inherits, p_types, p_root, to_select);
}
- if (p_types.has(inherits))
+ if (p_types.has(inherits)) {
parent = p_types[inherits];
- else if (ScriptServer::is_global_class(inherits))
+ } else if (ScriptServer::is_global_class(inherits)) {
return;
+ }
}
bool can_instance = (cpp_type && ClassDB::can_instance(p_type)) || ScriptServer::is_global_class(p_type);
@@ -267,7 +264,6 @@ bool CreateDialog::_is_type_prefered(const String &type) {
}
bool CreateDialog::_is_class_disabled_by_feature_profile(const StringName &p_class) {
-
Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile();
if (profile.is_null()) {
return false;
@@ -277,7 +273,6 @@ bool CreateDialog::_is_class_disabled_by_feature_profile(const StringName &p_cla
}
void CreateDialog::select_type(const String &p_type) {
-
TreeItem *to_select;
if (search_options_types.has(p_type)) {
to_select = search_options_types[p_type];
@@ -317,7 +312,6 @@ void CreateDialog::_update_search() {
TreeItem *to_select = search_box->get_text() == base_type ? root : nullptr;
for (List<StringName>::Element *I = type_list.front(); I; I = I->next()) {
-
String type = I->get();
if (_is_class_disabled_by_feature_profile(type)) {
@@ -325,27 +319,30 @@ void CreateDialog::_update_search() {
}
bool cpp_type = ClassDB::class_exists(type);
- if (base_type == "Node" && type.begins_with("Editor"))
+ if (base_type == "Node" && type.begins_with("Editor")) {
continue; // do not show editor nodes
+ }
- if (cpp_type && !ClassDB::can_instance(type))
+ if (cpp_type && !ClassDB::can_instance(type)) {
continue; // can't create what can't be instanced
+ }
if (cpp_type) {
bool skip = false;
for (Set<StringName>::Element *E = type_blacklist.front(); E && !skip; E = E->next()) {
- if (ClassDB::is_parent_class(type, E->get()))
+ if (ClassDB::is_parent_class(type, E->get())) {
skip = true;
+ }
}
- if (skip)
+ if (skip) {
continue;
+ }
}
if (search_box->get_text() == "") {
add_type(type, search_options_types, root, &to_select);
} else {
-
bool found = false;
String type2 = type;
@@ -355,7 +352,6 @@ void CreateDialog::_update_search() {
while (type2 != "" && (cpp_type ? ClassDB::is_parent_class(type2, base_type) : ed.script_class_is_parent(type2, base_type)) && type2 != base_type) {
if (search_box->get_text().is_subsequence_ofi(type2)) {
-
found = true;
break;
}
@@ -377,20 +373,22 @@ void CreateDialog::_update_search() {
const Vector<EditorData::CustomType> &ct = EditorNode::get_editor_data().get_custom_types()[type];
for (int i = 0; i < ct.size(); i++) {
-
bool show = search_box->get_text().is_subsequence_ofi(ct[i].name);
- if (!show)
+ if (!show) {
continue;
+ }
- if (!search_options_types.has(type))
+ if (!search_options_types.has(type)) {
add_type(type, search_options_types, root, &to_select);
+ }
TreeItem *ti;
- if (search_options_types.has(type))
+ if (search_options_types.has(type)) {
ti = search_options_types[type];
- else
+ } else {
ti = search_options->get_root();
+ }
TreeItem *item = search_options->create_item(ti);
item->set_metadata(0, type);
@@ -421,22 +419,22 @@ void CreateDialog::_update_search() {
}
void CreateDialog::_confirmed() {
-
TreeItem *ti = search_options->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("create_recent." + base_type), FileAccess::WRITE);
if (f) {
f->store_line(get_selected_type());
TreeItem *t = recent->get_root();
- if (t)
+ if (t) {
t = t->get_children();
+ }
int count = 0;
while (t) {
if (t->get_text(0) != get_selected_type()) {
-
f->store_line(t->get_text(0));
}
@@ -456,7 +454,6 @@ void CreateDialog::_confirmed() {
}
void CreateDialog::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
connect("confirmed", callable_mp(this, &CreateDialog::_confirmed));
@@ -480,18 +477,17 @@ void CreateDialog::_notification(int p_what) {
}
void CreateDialog::set_base_type(const String &p_base) {
-
base_type = p_base;
- if (is_replace_mode)
+ if (is_replace_mode) {
set_title(vformat(TTR("Change %s Type"), p_base));
- else
+ } else {
set_title(vformat(TTR("Create New %s"), p_base));
+ }
_update_search();
}
String CreateDialog::get_base_type() const {
-
return base_type;
}
@@ -500,36 +496,36 @@ void CreateDialog::set_preferred_search_result_type(const String &p_preferred_ty
}
String CreateDialog::get_preferred_search_result_type() {
-
return preferred_search_result_type;
}
-String CreateDialog::get_selected_type() {
+String CreateDialog::get_selected_type() {
TreeItem *selected = search_options->get_selected();
- if (selected)
+ if (selected) {
return selected->get_text(0);
- else
+ } else {
return String();
+ }
}
Object *CreateDialog::instance_selected() {
-
TreeItem *selected = search_options->get_selected();
if (selected) {
-
Variant md = selected->get_metadata(0);
String custom;
- if (md.get_type() != Variant::NIL)
+ if (md.get_type() != Variant::NIL) {
custom = md;
+ }
if (custom != String()) {
if (ScriptServer::is_global_class(custom)) {
Object *obj = EditorNode::get_editor_data().script_class_instance(custom);
Node *n = Object::cast_to<Node>(obj);
- if (n)
+ if (n) {
n->set_name(custom);
+ }
return obj;
}
return EditorNode::get_editor_data().instance_custom_type(selected->get_text(0), custom);
@@ -542,18 +538,19 @@ Object *CreateDialog::instance_selected() {
}
void CreateDialog::_item_selected() {
-
TreeItem *item = search_options->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
String name = item->get_text(0);
favorite->set_disabled(false);
favorite->set_pressed(favorite_list.find(name) != -1);
- if (!EditorHelp::get_doc_data()->class_list.has(name))
+ if (!EditorHelp::get_doc_data()->class_list.has(name)) {
return;
+ }
help_bit->set_text(DTR(EditorHelp::get_doc_data()->class_list[name].brief_description));
@@ -565,10 +562,10 @@ void CreateDialog::_hide_requested() {
}
void CreateDialog::_favorite_toggled() {
-
TreeItem *item = search_options->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
String name = item->get_text(0);
@@ -584,16 +581,15 @@ void CreateDialog::_favorite_toggled() {
}
void CreateDialog::_save_favorite_list() {
-
FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites." + base_type), FileAccess::WRITE);
if (f) {
-
for (int i = 0; i < favorite_list.size(); i++) {
String l = favorite_list[i];
String name = l.split(" ")[0];
- if (!(ClassDB::class_exists(name) || ScriptServer::is_global_class(name)))
+ if (!(ClassDB::class_exists(name) || ScriptServer::is_global_class(name))) {
continue;
+ }
f->store_line(l);
}
memdelete(f);
@@ -601,14 +597,14 @@ void CreateDialog::_save_favorite_list() {
}
void CreateDialog::_update_favorite_list() {
-
favorites->clear();
TreeItem *root = favorites->create_item();
for (int i = 0; i < favorite_list.size(); i++) {
String l = favorite_list[i];
String name = l.split(" ")[0];
- if (!((ClassDB::class_exists(name) || ScriptServer::is_global_class(name)) && !_is_class_disabled_by_feature_profile(name)))
+ if (!((ClassDB::class_exists(name) || ScriptServer::is_global_class(name)) && !_is_class_disabled_by_feature_profile(name))) {
continue;
+ }
TreeItem *ti = favorites->create_item(root);
ti->set_text(0, l);
ti->set_icon(0, EditorNode::get_singleton()->get_class_icon(l, base_type));
@@ -617,10 +613,10 @@ void CreateDialog::_update_favorite_list() {
}
void CreateDialog::_history_selected() {
-
TreeItem *item = recent->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
search_box->set_text(item->get_text(0).get_slicec(' ', 0));
favorites->deselect_all();
@@ -628,10 +624,10 @@ void CreateDialog::_history_selected() {
}
void CreateDialog::_favorite_selected() {
-
TreeItem *item = favorites->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
search_box->set_text(item->get_text(0).get_slicec(' ', 0));
recent->deselect_all();
@@ -639,19 +635,16 @@ void CreateDialog::_favorite_selected() {
}
void CreateDialog::_history_activated() {
-
_history_selected();
_confirmed();
}
void CreateDialog::_favorite_activated() {
-
_favorite_selected();
_confirmed();
}
Variant CreateDialog::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
TreeItem *ti = favorites->get_item_at_position(p_point);
if (ti) {
Dictionary d;
@@ -670,7 +663,6 @@ Variant CreateDialog::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
}
bool CreateDialog::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
Dictionary d = p_data;
if (d.has("type") && String(d["type"]) == "create_favorite_drag") {
favorites->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN);
@@ -679,26 +671,29 @@ bool CreateDialog::can_drop_data_fw(const Point2 &p_point, const Variant &p_data
return false;
}
-void CreateDialog::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
+void CreateDialog::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
Dictionary d = p_data;
TreeItem *ti = favorites->get_item_at_position(p_point);
- if (!ti)
+ if (!ti) {
return;
+ }
String drop_at = ti->get_text(0);
int ds = favorites->get_drop_section_at_position(p_point);
int drop_idx = favorite_list.find(drop_at);
- if (drop_idx < 0)
+ if (drop_idx < 0) {
return;
+ }
String type = d["class"];
int from_idx = favorite_list.find(type);
- if (from_idx < 0)
+ if (from_idx < 0) {
return;
+ }
if (drop_idx == from_idx) {
ds = -1; //cause it will be gone
@@ -727,7 +722,6 @@ void CreateDialog::_save_and_update_favorite_list() {
}
void CreateDialog::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_save_and_update_favorite_list"), &CreateDialog::_save_and_update_favorite_list);
ClassDB::bind_method("get_drag_data_fw", &CreateDialog::get_drag_data_fw);
@@ -739,7 +733,6 @@ void CreateDialog::_bind_methods() {
}
CreateDialog::CreateDialog() {
-
is_replace_mode = false;
HSplitContainer *hsc = memnew(HSplitContainer);
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index f2e2eb1b04..cdc91ae535 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -40,7 +40,6 @@
#include "scene/gui/tree.h"
class CreateDialog : public ConfirmationDialog {
-
GDCLASS(CreateDialog, ConfirmationDialog);
Vector<String> favorite_list;
diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp
index 00ed2bbc4c..125439d09b 100644
--- a/editor/debugger/editor_debugger_inspector.cpp
+++ b/editor/debugger/editor_debugger_inspector.cpp
@@ -36,9 +36,9 @@
#include "scene/debugger/scene_debugger.h"
bool EditorDebuggerRemoteObject::_set(const StringName &p_name, const Variant &p_value) {
-
- if (!editable || !prop_values.has(p_name) || String(p_name).begins_with("Constants/"))
+ if (!editable || !prop_values.has(p_name) || String(p_name).begins_with("Constants/")) {
return false;
+ }
prop_values[p_name] = p_value;
emit_signal("value_edited", remote_object_id, p_name, p_value);
@@ -46,16 +46,15 @@ bool EditorDebuggerRemoteObject::_set(const StringName &p_name, const Variant &p
}
bool EditorDebuggerRemoteObject::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (!prop_values.has(p_name))
+ if (!prop_values.has(p_name)) {
return false;
+ }
r_ret = prop_values[p_name];
return true;
}
void EditorDebuggerRemoteObject::_get_property_list(List<PropertyInfo> *p_list) const {
-
p_list->clear(); //sorry, no want category
for (const List<PropertyInfo>::Element *E = prop_list.front(); E; E = E->next()) {
p_list->push_back(E->get());
@@ -63,10 +62,11 @@ void EditorDebuggerRemoteObject::_get_property_list(List<PropertyInfo> *p_list)
}
String EditorDebuggerRemoteObject::get_title() {
- if (remote_object_id.is_valid())
+ if (remote_object_id.is_valid()) {
return TTR("Remote ") + String(type_name) + ": " + itos(remote_object_id);
- else
+ } else {
return "<null>";
+ }
}
Variant EditorDebuggerRemoteObject::get_variant(const StringName &p_name) {
@@ -76,7 +76,6 @@ Variant EditorDebuggerRemoteObject::get_variant(const StringName &p_name) {
}
void EditorDebuggerRemoteObject::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_title"), &EditorDebuggerRemoteObject::get_title);
ClassDB::bind_method(D_METHOD("get_variant"), &EditorDebuggerRemoteObject::get_variant);
ClassDB::bind_method(D_METHOD("clear"), &EditorDebuggerRemoteObject::clear);
@@ -115,12 +114,10 @@ void EditorDebuggerInspector::_notification(int p_what) {
}
void EditorDebuggerInspector::_object_edited(ObjectID p_id, const String &p_prop, const Variant &p_value) {
-
emit_signal("object_edited", p_id, p_prop, p_value);
}
void EditorDebuggerInspector::_object_selected(ObjectID p_object) {
-
emit_signal("object_selected", p_object);
}
@@ -147,7 +144,6 @@ ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) {
int new_props_added = 0;
Set<String> changed;
for (int i = 0; i < obj.properties.size(); i++) {
-
PropertyInfo &pinfo = obj.properties[i].first;
Variant &var = obj.properties[i].second;
@@ -187,7 +183,6 @@ ObjectID EditorDebuggerInspector::add_object(const Array &p_arr) {
new_props_added++;
debugObj->prop_values[pinfo.name] = var;
} else {
-
if (bool(Variant::evaluate(Variant::OP_NOT_EQUAL, debugObj->prop_values[pinfo.name], var))) {
debugObj->prop_values[pinfo.name] = var;
changed.insert(pinfo.name);
@@ -219,13 +214,13 @@ void EditorDebuggerInspector::clear_cache() {
}
Object *EditorDebuggerInspector::get_object(ObjectID p_id) {
- if (remote_objects.has(p_id))
+ if (remote_objects.has(p_id)) {
return remote_objects[p_id];
+ }
return nullptr;
}
void EditorDebuggerInspector::add_stack_variable(const Array &p_array) {
-
DebuggerMarshalls::ScriptStackVariable var;
var.deserialize(p_array);
String n = var.name;
diff --git a/editor/debugger/editor_debugger_inspector.h b/editor/debugger/editor_debugger_inspector.h
index e1dfbefcf3..638dee3c3f 100644
--- a/editor/debugger/editor_debugger_inspector.h
+++ b/editor/debugger/editor_debugger_inspector.h
@@ -33,7 +33,6 @@
#include "editor/editor_inspector.h"
class EditorDebuggerRemoteObject : public Object {
-
GDCLASS(EditorDebuggerRemoteObject, Object);
protected:
@@ -61,11 +60,10 @@ public:
void update() { _change_notify(); }
- EditorDebuggerRemoteObject(){};
+ EditorDebuggerRemoteObject() {}
};
class EditorDebuggerInspector : public EditorInspector {
-
GDCLASS(EditorDebuggerInspector, EditorInspector);
private:
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp
index 3302b50103..a9c18138d8 100644
--- a/editor/debugger/editor_debugger_node.cpp
+++ b/editor/debugger/editor_debugger_node.cpp
@@ -50,8 +50,9 @@ void _for_all(TabContainer *p_node, const Func &p_func) {
EditorDebuggerNode *EditorDebuggerNode::singleton = nullptr;
EditorDebuggerNode::EditorDebuggerNode() {
- if (!singleton)
+ if (!singleton) {
singleton = this;
+ }
add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_LEFT));
add_theme_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_RIGHT));
@@ -119,8 +120,9 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() {
void EditorDebuggerNode::_stack_frame_selected(int p_debugger) {
const ScriptEditorDebugger *dbg = get_debugger(p_debugger);
ERR_FAIL_COND(!dbg);
- if (dbg != get_current_debugger())
+ if (dbg != get_current_debugger()) {
return;
+ }
_text_editor_stack_goto(dbg);
}
@@ -131,8 +133,9 @@ void EditorDebuggerNode::_error_selected(const String &p_file, int p_line, int p
void EditorDebuggerNode::_text_editor_stack_goto(const ScriptEditorDebugger *p_debugger) {
const String file = p_debugger->get_stack_script_file();
- if (file.empty())
+ if (file.empty()) {
return;
+ }
stack_script = ResourceLoader::load(file);
const int line = p_debugger->get_stack_script_line() - 1;
emit_signal("goto_script_line", stack_script, line);
@@ -141,7 +144,6 @@ void EditorDebuggerNode::_text_editor_stack_goto(const ScriptEditorDebugger *p_d
}
void EditorDebuggerNode::_bind_methods() {
-
// LiveDebug.
ClassDB::bind_method("live_debug_create_node", &EditorDebuggerNode::live_debug_create_node);
ClassDB::bind_method("live_debug_instance_node", &EditorDebuggerNode::live_debug_instance_node);
@@ -173,7 +175,7 @@ ScriptEditorDebugger *EditorDebuggerNode::get_default_debugger() const {
return Object::cast_to<ScriptEditorDebugger>(tabs->get_tab_control(0));
}
-Error EditorDebuggerNode::start() {
+Error EditorDebuggerNode::start(const String &p_protocol) {
stop();
if (EDITOR_GET("run/output/always_open_output_on_play")) {
EditorNode::get_singleton()->make_bottom_panel_item_visible(EditorNode::get_log());
@@ -181,7 +183,7 @@ Error EditorDebuggerNode::start() {
EditorNode::get_singleton()->make_bottom_panel_item_visible(this);
}
- server = Ref<EditorDebuggerServer>(EditorDebuggerServer::create_default());
+ server = Ref<EditorDebuggerServer>(EditorDebuggerServer::create(p_protocol));
const Error err = server->start();
if (err != OK) {
return err;
@@ -199,13 +201,15 @@ void EditorDebuggerNode::stop() {
}
// Also close all debugging sessions.
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
- if (dbg->is_session_active())
+ if (dbg->is_session_active()) {
dbg->stop();
+ }
});
_break_state_changed();
if (hide_on_stop) {
- if (is_visible_in_tree())
+ if (is_visible_in_tree()) {
EditorNode::get_singleton()->hide_bottom_panel();
+ }
}
breakpoints.clear();
set_process(false);
@@ -213,14 +217,6 @@ void EditorDebuggerNode::stop() {
void EditorDebuggerNode::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
- EditorNode::get_singleton()->connect("play_pressed", callable_mp(this, &EditorDebuggerNode::start));
- EditorNode::get_singleton()->connect("stop_pressed", callable_mp(this, &EditorDebuggerNode::stop));
- } break;
- case NOTIFICATION_EXIT_TREE: {
- EditorNode::get_singleton()->disconnect("play_pressed", callable_mp(this, &EditorDebuggerNode::start));
- EditorNode::get_singleton()->disconnect("stop_pressed", callable_mp(this, &EditorDebuggerNode::stop));
- } break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
if (tabs->get_tab_count() > 1) {
add_theme_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_LEFT));
@@ -233,8 +229,9 @@ void EditorDebuggerNode::_notification(int p_what) {
break;
}
- if (p_what != NOTIFICATION_PROCESS || !server.is_valid())
+ if (p_what != NOTIFICATION_PROCESS || !server.is_valid()) {
return;
+ }
if (!server.is_valid() || !server->is_active()) {
stop();
@@ -251,7 +248,6 @@ void EditorDebuggerNode::_notification(int p_what) {
});
if (error_count != last_error_count || warning_count != last_warning_count) {
-
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
dbg->update_tabs();
});
@@ -261,10 +257,12 @@ void EditorDebuggerNode::_notification(int p_what) {
debugger_button->set_icon(Ref<Texture2D>());
} else {
debugger_button->set_text(TTR("Debugger") + " (" + itos(error_count + warning_count) + ")");
- if (error_count == 0) {
- debugger_button->set_icon(get_theme_icon("Warning", "EditorIcons"));
- } else {
+ if (error_count >= 1 && warning_count >= 1) {
+ debugger_button->set_icon(get_theme_icon("ErrorWarning", "EditorIcons"));
+ } else if (error_count >= 1) {
debugger_button->set_icon(get_theme_icon("Error", "EditorIcons"));
+ } else {
+ debugger_button->set_icon(get_theme_icon("Warning", "EditorIcons"));
}
}
last_error_count = error_count;
@@ -293,8 +291,9 @@ void EditorDebuggerNode::_notification(int p_what) {
if (server->is_connection_available()) {
ScriptEditorDebugger *debugger = nullptr;
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
- if (debugger || dbg->is_session_active())
+ if (debugger || dbg->is_session_active()) {
return;
+ }
debugger = dbg;
});
if (debugger == nullptr) {
@@ -333,8 +332,9 @@ void EditorDebuggerNode::_debugger_stopped(int p_id) {
bool found = false;
_for_all(tabs, [&](ScriptEditorDebugger *p_debugger) {
- if (p_debugger->is_session_active())
+ if (p_debugger->is_session_active()) {
found = true;
+ }
});
if (!found) {
EditorNode::get_singleton()->get_pause_button()->set_pressed(false);
@@ -348,8 +348,9 @@ void EditorDebuggerNode::_debugger_stopped(int p_id) {
void EditorDebuggerNode::_debugger_wants_stop(int p_id) {
// Ask editor to kill PID.
int pid = get_debugger(p_id)->get_remote_pid();
- if (pid)
+ if (pid) {
EditorNode::get_singleton()->call_deferred("stop_child_process", pid);
+ }
}
void EditorDebuggerNode::_debugger_changed(int p_tab) {
@@ -388,12 +389,14 @@ void EditorDebuggerNode::set_script_debug_button(MenuButton *p_button) {
void EditorDebuggerNode::_break_state_changed() {
const bool breaked = get_current_debugger()->is_breaked();
const bool can_debug = get_current_debugger()->is_debuggable();
- if (breaked) // Show debugger.
+ if (breaked) { // Show debugger.
EditorNode::get_singleton()->make_bottom_panel_item_visible(this);
+ }
// Update script menu.
- if (!script_menu)
+ if (!script_menu) {
return;
+ }
PopupMenu *p = script_menu->get_popup();
p->set_item_disabled(p->get_item_index(DEBUG_NEXT), !(breaked && can_debug));
p->set_item_disabled(p->get_item_index(DEBUG_STEP), !(breaked && can_debug));
@@ -442,8 +445,9 @@ void EditorDebuggerNode::_paused() {
void EditorDebuggerNode::_breaked(bool p_breaked, bool p_can_debug, int p_debugger) {
if (get_current_debugger() != get_debugger(p_debugger)) {
- if (!p_breaked)
+ if (!p_breaked) {
return;
+ }
tabs->set_current_tab(p_debugger);
}
_break_state_changed();
@@ -494,58 +498,67 @@ void EditorDebuggerNode::request_remote_tree() {
}
void EditorDebuggerNode::_remote_tree_updated(int p_debugger) {
- if (p_debugger != tabs->get_current_tab())
+ if (p_debugger != tabs->get_current_tab()) {
return;
+ }
remote_scene_tree->clear();
remote_scene_tree->update_scene_tree(get_current_debugger()->get_remote_tree(), p_debugger);
}
void EditorDebuggerNode::_remote_object_updated(ObjectID p_id, int p_debugger) {
- if (p_debugger != tabs->get_current_tab())
+ if (p_debugger != tabs->get_current_tab()) {
return;
+ }
if (EditorDebuggerRemoteObject *obj = get_inspected_remote_object()) {
- if (obj->remote_object_id == p_id)
+ if (obj->remote_object_id == p_id) {
return; // Already being edited
+ }
}
EditorNode::get_singleton()->push_item(get_current_debugger()->get_remote_object(p_id));
}
void EditorDebuggerNode::_remote_object_property_updated(ObjectID p_id, const String &p_property, int p_debugger) {
- if (p_debugger != tabs->get_current_tab())
+ if (p_debugger != tabs->get_current_tab()) {
return;
+ }
if (EditorDebuggerRemoteObject *obj = get_inspected_remote_object()) {
- if (obj->remote_object_id != p_id)
+ if (obj->remote_object_id != p_id) {
return;
+ }
EditorNode::get_singleton()->get_inspector()->update_property(p_property);
}
}
void EditorDebuggerNode::_remote_object_requested(ObjectID p_id, int p_debugger) {
- if (p_debugger != tabs->get_current_tab())
+ if (p_debugger != tabs->get_current_tab()) {
return;
+ }
inspect_edited_object_timeout = 0.7; // Temporarily disable timeout to avoid multiple requests.
get_current_debugger()->request_remote_object(p_id);
}
void EditorDebuggerNode::_save_node_requested(ObjectID p_id, const String &p_file, int p_debugger) {
- if (p_debugger != tabs->get_current_tab())
+ if (p_debugger != tabs->get_current_tab()) {
return;
+ }
get_current_debugger()->save_node(p_id, p_file);
}
// Remote inspector/edit.
void EditorDebuggerNode::_method_changeds(void *p_ud, Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE) {
- if (!singleton)
+ if (!singleton) {
return;
+ }
_for_all(singleton->tabs, [&](ScriptEditorDebugger *dbg) {
dbg->_method_changed(p_base, p_name, VARIANT_ARG_PASS);
});
}
void EditorDebuggerNode::_property_changeds(void *p_ud, Object *p_base, const StringName &p_property, const Variant &p_value) {
- if (!singleton)
+ if (!singleton) {
return;
+ }
_for_all(singleton->tabs, [&](ScriptEditorDebugger *dbg) {
dbg->_property_changed(p_base, p_property, p_value);
});
@@ -553,46 +566,53 @@ void EditorDebuggerNode::_property_changeds(void *p_ud, Object *p_base, const St
// LiveDebug
void EditorDebuggerNode::set_live_debugging(bool p_enabled) {
-
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
dbg->set_live_debugging(p_enabled);
});
}
+
void EditorDebuggerNode::update_live_edit_root() {
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
dbg->update_live_edit_root();
});
}
+
void EditorDebuggerNode::live_debug_create_node(const NodePath &p_parent, const String &p_type, const String &p_name) {
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
dbg->live_debug_create_node(p_parent, p_type, p_name);
});
}
+
void EditorDebuggerNode::live_debug_instance_node(const NodePath &p_parent, const String &p_path, const String &p_name) {
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
dbg->live_debug_instance_node(p_parent, p_path, p_name);
});
}
+
void EditorDebuggerNode::live_debug_remove_node(const NodePath &p_at) {
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
dbg->live_debug_remove_node(p_at);
});
}
+
void EditorDebuggerNode::live_debug_remove_and_keep_node(const NodePath &p_at, ObjectID p_keep_id) {
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
dbg->live_debug_remove_and_keep_node(p_at, p_keep_id);
});
}
+
void EditorDebuggerNode::live_debug_restore_node(ObjectID p_id, const NodePath &p_at, int p_at_pos) {
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
dbg->live_debug_restore_node(p_id, p_at, p_at_pos);
});
}
+
void EditorDebuggerNode::live_debug_duplicate_node(const NodePath &p_at, const String &p_new_name) {
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
dbg->live_debug_duplicate_node(p_at, p_new_name);
});
}
+
void EditorDebuggerNode::live_debug_reparent_node(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos) {
_for_all(tabs, [&](ScriptEditorDebugger *dbg) {
dbg->live_debug_reparent_node(p_at, p_new_place, p_new_name, p_at_pos);
diff --git a/editor/debugger/editor_debugger_node.h b/editor/debugger/editor_debugger_node.h
index 9467442c9a..ff9601c026 100644
--- a/editor/debugger/editor_debugger_node.h
+++ b/editor/debugger/editor_debugger_node.h
@@ -42,7 +42,6 @@ class ScriptEditorDebugger;
class TabContainer;
class EditorDebuggerNode : public MarginContainer {
-
GDCLASS(EditorDebuggerNode, MarginContainer);
public:
@@ -71,12 +70,13 @@ private:
int line = 0;
bool operator<(const Breakpoint &p_b) const {
- if (line == p_b.line)
+ if (line == p_b.line) {
return source < p_b.source;
+ }
return line < p_b.line;
}
- Breakpoint(){};
+ Breakpoint() {}
Breakpoint(const String &p_source, int p_line) {
line = p_line;
@@ -183,7 +183,7 @@ public:
void set_camera_override(CameraOverride p_override) { camera_override = p_override; }
CameraOverride get_camera_override() { return camera_override; }
- Error start();
+ Error start(const String &p_protocol = "tcp://");
void stop();
};
diff --git a/editor/debugger/editor_debugger_server.cpp b/editor/debugger/editor_debugger_server.cpp
index c80988a662..0b655044a8 100644
--- a/editor/debugger/editor_debugger_server.cpp
+++ b/editor/debugger/editor_debugger_server.cpp
@@ -39,11 +39,11 @@
#include "editor/editor_settings.h"
class EditorDebuggerServerTCP : public EditorDebuggerServer {
-
private:
Ref<TCP_Server> server;
public:
+ static EditorDebuggerServer *create(const String &p_protocol);
virtual void poll() {}
virtual Error start();
virtual void stop();
@@ -54,6 +54,11 @@ public:
EditorDebuggerServerTCP();
};
+EditorDebuggerServer *EditorDebuggerServerTCP::create(const String &p_protocol) {
+ ERR_FAIL_COND_V(p_protocol != "tcp://", nullptr);
+ return memnew(EditorDebuggerServerTCP);
+}
+
EditorDebuggerServerTCP::EditorDebuggerServerTCP() {
server.instance();
}
@@ -85,6 +90,23 @@ Ref<RemoteDebuggerPeer> EditorDebuggerServerTCP::take_connection() {
return memnew(RemoteDebuggerPeerTCP(server->take_connection()));
}
-EditorDebuggerServer *EditorDebuggerServer::create_default() {
- return memnew(EditorDebuggerServerTCP);
+/// EditorDebuggerServer
+Map<StringName, EditorDebuggerServer::CreateServerFunc> EditorDebuggerServer::protocols;
+
+EditorDebuggerServer *EditorDebuggerServer::create(const String &p_protocol) {
+ ERR_FAIL_COND_V(!protocols.has(p_protocol), nullptr);
+ return protocols[p_protocol](p_protocol);
+}
+
+void EditorDebuggerServer::register_protocol_handler(const String &p_protocol, CreateServerFunc p_func) {
+ ERR_FAIL_COND(protocols.has(p_protocol));
+ protocols[p_protocol] = p_func;
+}
+
+void EditorDebuggerServer::initialize() {
+ register_protocol_handler("tcp://", EditorDebuggerServerTCP::create);
+}
+
+void EditorDebuggerServer::deinitialize() {
+ protocols.clear();
}
diff --git a/editor/debugger/editor_debugger_server.h b/editor/debugger/editor_debugger_server.h
index e9798c90b3..10a9a232ab 100644
--- a/editor/debugger/editor_debugger_server.h
+++ b/editor/debugger/editor_debugger_server.h
@@ -35,9 +35,18 @@
#include "core/reference.h"
class EditorDebuggerServer : public Reference {
+public:
+ typedef EditorDebuggerServer *(*CreateServerFunc)(const String &p_uri);
+
+private:
+ static Map<StringName, CreateServerFunc> protocols;
public:
- static EditorDebuggerServer *create_default();
+ static void initialize();
+ static void deinitialize();
+
+ static void register_protocol_handler(const String &p_protocol, CreateServerFunc p_func);
+ static EditorDebuggerServer *create(const String &p_protocol);
virtual void poll() = 0;
virtual Error start() = 0;
virtual void stop() = 0;
diff --git a/editor/debugger/editor_debugger_tree.cpp b/editor/debugger/editor_debugger_tree.cpp
index c2b94c79bb..0b5f865a98 100644
--- a/editor/debugger/editor_debugger_tree.cpp
+++ b/editor/debugger/editor_debugger_tree.cpp
@@ -64,7 +64,6 @@ void EditorDebuggerTree::_bind_methods() {
}
void EditorDebuggerTree::_scene_tree_selected() {
-
if (updating_scene_tree) {
return;
}
@@ -80,15 +79,14 @@ void EditorDebuggerTree::_scene_tree_selected() {
}
void EditorDebuggerTree::_scene_tree_folded(Object *p_obj) {
-
if (updating_scene_tree) {
-
return;
}
TreeItem *item = Object::cast_to<TreeItem>(p_obj);
- if (!item)
+ if (!item) {
return;
+ }
ObjectID id = ObjectID(uint64_t(item->get_metadata(0)));
if (unfold_cache.has(id)) {
@@ -99,10 +97,10 @@ void EditorDebuggerTree::_scene_tree_folded(Object *p_obj) {
}
void EditorDebuggerTree::_scene_tree_rmb_selected(const Vector2 &p_position) {
-
TreeItem *item = get_item_at_position(p_position);
- if (!item)
+ if (!item) {
return;
+ }
item->select(0);
@@ -180,12 +178,14 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
// Apply filters.
while (parent) {
const bool had_siblings = item->get_prev() || item->get_next();
- if (filter.is_subsequence_ofi(item->get_text(0)))
+ if (filter.is_subsequence_ofi(item->get_text(0))) {
break; // Filter matches, must survive.
+ }
parent->remove_child(item);
memdelete(item);
- if (had_siblings)
+ if (had_siblings) {
break; // Parent must survive.
+ }
item = parent;
parent = item->get_parent();
// Check if parent expects more children.
@@ -203,8 +203,9 @@ void EditorDebuggerTree::update_scene_tree(const SceneDebuggerTree *p_tree, int
}
String EditorDebuggerTree::get_selected_path() {
- if (!get_selected())
+ if (!get_selected()) {
return "";
+ }
return _get_path(get_selected());
}
@@ -224,11 +225,8 @@ String EditorDebuggerTree::_get_path(TreeItem *p_item) {
}
void EditorDebuggerTree::_item_menu_id_pressed(int p_option) {
-
switch (p_option) {
-
case ITEM_MENU_SAVE_REMOTE_NODE: {
-
file_dialog->set_access(EditorFileDialog::ACCESS_RESOURCES);
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
@@ -243,7 +241,6 @@ void EditorDebuggerTree::_item_menu_id_pressed(int p_option) {
file_dialog->popup_centered_ratio();
} break;
case ITEM_MENU_COPY_NODE_PATH: {
-
String text = get_selected_path();
if (text.empty()) {
return;
@@ -264,7 +261,8 @@ void EditorDebuggerTree::_item_menu_id_pressed(int p_option) {
}
void EditorDebuggerTree::_file_selected(const String &p_file) {
- if (inspected_object_id.is_null())
+ if (inspected_object_id.is_null()) {
return;
+ }
emit_signal("save_node", inspected_object_id, p_file, debugger_id);
}
diff --git a/editor/debugger/editor_debugger_tree.h b/editor/debugger/editor_debugger_tree.h
index 342eb23194..5ec1423c07 100644
--- a/editor/debugger/editor_debugger_tree.h
+++ b/editor/debugger/editor_debugger_tree.h
@@ -37,7 +37,6 @@ class SceneDebuggerTree;
class EditorFileDialog;
class EditorDebuggerTree : public Tree {
-
GDCLASS(EditorDebuggerTree, Tree);
private:
diff --git a/editor/debugger/editor_network_profiler.cpp b/editor/debugger/editor_network_profiler.cpp
index b8c795d9ca..baa88bcdbc 100644
--- a/editor/debugger/editor_network_profiler.cpp
+++ b/editor/debugger/editor_network_profiler.cpp
@@ -39,7 +39,6 @@ void EditorNetworkProfiler::_bind_methods() {
}
void EditorNetworkProfiler::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
activate->set_icon(get_theme_icon("Play", "EditorIcons"));
clear_button->set_icon(get_theme_icon("Clear", "EditorIcons"));
@@ -53,13 +52,11 @@ void EditorNetworkProfiler::_notification(int p_what) {
}
void EditorNetworkProfiler::_update_frame() {
-
counters_display->clear();
TreeItem *root = counters_display->create_item();
for (Map<ObjectID, DebuggerMarshalls::MultiplayerNodeInfo>::Element *E = nodes_data.front(); E; E = E->next()) {
-
TreeItem *node = counters_display->create_item(root);
for (int j = 0; j < counters_display->get_columns(); ++j) {
@@ -75,7 +72,6 @@ void EditorNetworkProfiler::_update_frame() {
}
void EditorNetworkProfiler::_activate_pressed() {
-
if (activate->is_pressed()) {
activate->set_icon(get_theme_icon("Stop", "EditorIcons"));
activate->set_text(TTR("Stop"));
@@ -96,7 +92,6 @@ void EditorNetworkProfiler::_clear_pressed() {
}
void EditorNetworkProfiler::add_node_frame_data(const DebuggerMarshalls::MultiplayerNodeInfo p_frame) {
-
if (!nodes_data.has(p_frame.node)) {
nodes_data.insert(p_frame.node, p_frame);
} else {
@@ -113,7 +108,6 @@ void EditorNetworkProfiler::add_node_frame_data(const DebuggerMarshalls::Multipl
}
void EditorNetworkProfiler::set_bandwidth(int p_incoming, int p_outgoing) {
-
incoming_bandwidth_text->set_text(vformat(TTR("%s/s"), String::humanize_size(p_incoming)));
outgoing_bandwidth_text->set_text(vformat(TTR("%s/s"), String::humanize_size(p_outgoing)));
@@ -131,7 +125,6 @@ bool EditorNetworkProfiler::is_profiling() {
}
EditorNetworkProfiler::EditorNetworkProfiler() {
-
HBoxContainer *hb = memnew(HBoxContainer);
hb->add_theme_constant_override("separation", 8 * EDSCALE);
add_child(hb);
diff --git a/editor/debugger/editor_network_profiler.h b/editor/debugger/editor_network_profiler.h
index f532dc5dd0..cf65fb5316 100644
--- a/editor/debugger/editor_network_profiler.h
+++ b/editor/debugger/editor_network_profiler.h
@@ -39,7 +39,6 @@
#include "scene/gui/tree.h"
class EditorNetworkProfiler : public VBoxContainer {
-
GDCLASS(EditorNetworkProfiler, VBoxContainer)
private:
diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp
index 1577e24ac0..8bd21fff5c 100644
--- a/editor/debugger/editor_profiler.cpp
+++ b/editor/debugger/editor_profiler.cpp
@@ -35,7 +35,6 @@
#include "editor/editor_settings.h"
void EditorProfiler::_make_metric_ptrs(Metric &m) {
-
for (int i = 0; i < m.categories.size(); i++) {
m.category_ptrs[m.categories[i].signature] = &m.categories.write[i];
for (int j = 0; j < m.categories[i].items.size(); j++) {
@@ -45,10 +44,10 @@ void EditorProfiler::_make_metric_ptrs(Metric &m) {
}
void EditorProfiler::add_frame_metric(const Metric &p_metric, bool p_final) {
-
++last_metric;
- if (last_metric >= frame_metrics.size())
+ if (last_metric >= frame_metrics.size()) {
last_metric = 0;
+ }
frame_metrics.write[last_metric] = p_metric;
_make_metric_ptrs(frame_metrics.write[last_metric]);
@@ -69,7 +68,6 @@ void EditorProfiler::add_frame_metric(const Metric &p_metric, bool p_final) {
updating_frame = false;
if (frame_delay->is_stopped()) {
-
frame_delay->set_wait_time(p_final ? 0.1 : 1);
frame_delay->start();
}
@@ -81,7 +79,6 @@ void EditorProfiler::add_frame_metric(const Metric &p_metric, bool p_final) {
}
void EditorProfiler::clear() {
-
int metric_size = EditorSettings::get_singleton()->get("debugger/profiler_frame_history_size");
metric_size = CLAMP(metric_size, 60, 1024);
frame_metrics.clear();
@@ -110,7 +107,6 @@ static String _get_percent_txt(float p_value, float p_total) {
}
String EditorProfiler::_get_time_as_text(const Metric &m, float p_time, int p_calls) {
-
const int dmode = display_mode->get_selected();
if (dmode == DISPLAY_FRAME_TIME) {
@@ -131,29 +127,30 @@ String EditorProfiler::_get_time_as_text(const Metric &m, float p_time, int p_ca
}
Color EditorProfiler::_get_color_from_signature(const StringName &p_signature) const {
-
Color bc = get_theme_color("error_color", "Editor");
double rot = ABS(double(p_signature.hash()) / double(0x7FFFFFFF));
Color c;
c.set_hsv(rot, bc.get_s(), bc.get_v());
- return c.linear_interpolate(get_theme_color("base_color", "Editor"), 0.07);
+ return c.lerp(get_theme_color("base_color", "Editor"), 0.07);
}
void EditorProfiler::_item_edited() {
-
- if (updating_frame)
+ if (updating_frame) {
return;
+ }
TreeItem *item = variables->get_edited();
- if (!item)
+ if (!item) {
return;
+ }
StringName signature = item->get_metadata(0);
bool checked = item->is_checked(0);
- if (checked)
+ if (checked) {
plot_sigs.insert(signature);
- else
+ } else {
plot_sigs.erase(signature);
+ }
if (!frame_delay->is_processing()) {
frame_delay->set_wait_time(0.1);
@@ -164,7 +161,6 @@ void EditorProfiler::_item_edited() {
}
void EditorProfiler::_update_plot() {
-
const int w = graph->get_size().width;
const int h = graph->get_size().height;
bool reset_texture = false;
@@ -193,11 +189,11 @@ void EditorProfiler::_update_plot() {
for (int i = 0; i < frame_metrics.size(); i++) {
const Metric &m = frame_metrics[i];
- if (!m.valid)
+ if (!m.valid) {
continue;
+ }
for (Set<StringName>::Element *E = plot_sigs.front(); E; E = E->next()) {
-
const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
if (F) {
highest = MAX(F->get()->total_time, highest);
@@ -228,7 +224,6 @@ void EditorProfiler::_update_plot() {
//Map<StringName,int> plot_max;
for (int i = 0; i < w; i++) {
-
for (int j = 0; j < h * 4; j++) {
column[j] = 0;
}
@@ -238,15 +233,14 @@ void EditorProfiler::_update_plot() {
if (next > frame_metrics.size()) {
next = frame_metrics.size();
}
- if (next == current)
+ if (next == current) {
next = current + 1; //just because for loop must work
+ }
for (Set<StringName>::Element *E = plot_sigs.front(); E; E = E->next()) {
-
int plot_pos = -1;
for (int j = current; j < next; j++) {
-
//wrap
int idx = last_metric + 1 + j;
while (idx >= frame_metrics.size()) {
@@ -255,8 +249,9 @@ void EditorProfiler::_update_plot() {
//get
const Metric &m = frame_metrics[idx];
- if (!m.valid)
+ if (!m.valid) {
continue; //skip because invalid
+ }
float value = 0;
@@ -292,7 +287,6 @@ void EditorProfiler::_update_plot() {
}
if (prev_plot != -1 && plot_pos == -1) {
-
plot_pos = prev_plot;
}
@@ -310,7 +304,6 @@ void EditorProfiler::_update_plot() {
Color col = _get_color_from_signature(E->get());
for (int j = prev_plot; j <= plot_pos; j++) {
-
column[j * 4 + 0] += Math::fast_ftoi(CLAMP(col.r * 255, 0, 255));
column[j * 4 + 1] += Math::fast_ftoi(CLAMP(col.g * 255, 0, 255));
column[j * 4 + 2] += Math::fast_ftoi(CLAMP(col.b * 255, 0, 255));
@@ -319,7 +312,6 @@ void EditorProfiler::_update_plot() {
}
for (int j = 0; j < h * 4; j += 4) {
-
const int a = column[j + 3];
if (a > 0) {
column[j + 0] /= a;
@@ -344,10 +336,9 @@ void EditorProfiler::_update_plot() {
Ref<Image> img;
img.instance();
- img->create(w, h, 0, Image::FORMAT_RGBA8, graph_image);
+ img->create(w, h, false, Image::FORMAT_RGBA8, graph_image);
if (reset_texture) {
-
if (graph_texture.is_null()) {
graph_texture.instance();
}
@@ -361,7 +352,6 @@ void EditorProfiler::_update_plot() {
}
void EditorProfiler::_update_frame() {
-
int cursor_metric = _get_cursor_index();
ERR_FAIL_INDEX(cursor_metric, frame_metrics.size());
@@ -375,7 +365,6 @@ void EditorProfiler::_update_frame() {
int dtime = display_time->get_selected();
for (int i = 0; i < m.categories.size(); i++) {
-
TreeItem *category = variables->create_item(root);
category->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
category->set_editable(0, true);
@@ -418,7 +407,6 @@ void EditorProfiler::_update_frame() {
}
void EditorProfiler::_activate_pressed() {
-
if (activate->is_pressed()) {
activate->set_icon(get_theme_icon("Stop", "EditorIcons"));
activate->set_text(TTR("Stop"));
@@ -430,13 +418,11 @@ void EditorProfiler::_activate_pressed() {
}
void EditorProfiler::_clear_pressed() {
-
clear();
_update_plot();
}
void EditorProfiler::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
activate->set_icon(get_theme_icon("Play", "EditorIcons"));
clear_button->set_icon(get_theme_icon("Clear", "EditorIcons"));
@@ -444,15 +430,15 @@ void EditorProfiler::_notification(int p_what) {
}
void EditorProfiler::_graph_tex_draw() {
-
- if (last_metric < 0)
+ if (last_metric < 0) {
return;
+ }
if (seeking) {
-
int max_frames = frame_metrics.size();
int frame = cursor_metric_edit->get_value() - (frame_metrics[last_metric].frame_number - max_frames + 1);
- if (frame < 0)
+ if (frame < 0) {
frame = 0;
+ }
int cur_x = frame * graph->get_size().x / max_frames;
@@ -460,11 +446,11 @@ void EditorProfiler::_graph_tex_draw() {
}
if (hover_metric != -1 && frame_metrics[hover_metric].valid) {
-
int max_frames = frame_metrics.size();
int frame = frame_metrics[hover_metric].frame_number - (frame_metrics[last_metric].frame_number - max_frames + 1);
- if (frame < 0)
+ if (frame < 0) {
frame = 0;
+ }
int cur_x = frame * graph->get_size().x / max_frames;
@@ -473,23 +459,23 @@ void EditorProfiler::_graph_tex_draw() {
}
void EditorProfiler::_graph_tex_mouse_exit() {
-
hover_metric = -1;
graph->update();
}
void EditorProfiler::_cursor_metric_changed(double) {
- if (updating_frame)
+ if (updating_frame) {
return;
+ }
graph->update();
_update_frame();
}
void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
-
- if (last_metric < 0)
+ if (last_metric < 0) {
return;
+ }
Ref<InputEventMouse> me = p_ev;
Ref<InputEventMouseButton> mb = p_ev;
@@ -498,7 +484,6 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
if (
(mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) ||
(mm.is_valid())) {
-
int x = me->get_position().x;
x = x * frame_metrics.size() / graph->get_size().width;
@@ -519,7 +504,6 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
}
if (show_hover) {
-
hover_metric = metric;
} else {
@@ -533,19 +517,20 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
//metric may be invalid, so look for closest metric that is valid, this makes snap feel better
bool valid = false;
for (int i = 0; i < frame_metrics.size(); i++) {
-
if (frame_metrics[metric].valid) {
valid = true;
break;
}
metric++;
- if (metric >= frame_metrics.size())
+ if (metric >= frame_metrics.size()) {
metric = 0;
+ }
}
- if (valid)
+ if (valid) {
cursor_metric_edit->set_value(frame_metrics[metric].frame_number);
+ }
updating_frame = false;
@@ -568,11 +553,12 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
}
int EditorProfiler::_get_cursor_index() const {
-
- if (last_metric < 0)
+ if (last_metric < 0) {
return 0;
- if (!frame_metrics[last_metric].valid)
+ }
+ if (!frame_metrics[last_metric].valid) {
return 0;
+ }
int diff = (frame_metrics[last_metric].frame_number - cursor_metric_edit->get_value());
@@ -585,25 +571,21 @@ int EditorProfiler::_get_cursor_index() const {
}
void EditorProfiler::disable_seeking() {
-
seeking = false;
graph->update();
}
void EditorProfiler::_combo_changed(int) {
-
_update_frame();
_update_plot();
}
void EditorProfiler::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("enable_profiling", PropertyInfo(Variant::BOOL, "enable")));
ADD_SIGNAL(MethodInfo("break_request"));
}
void EditorProfiler::set_enabled(bool p_enable) {
-
activate->set_disabled(!p_enable);
}
@@ -623,7 +605,6 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const {
const Vector<EditorProfiler::Metric::Category> &categories = frame_metrics[0].categories;
for (int j = 0; j < categories.size(); j++) {
-
const EditorProfiler::Metric::Category &c = categories[j];
signatures.push_back(c.signature);
@@ -640,7 +621,6 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const {
int index = last_metric;
for (int i = 0; i < frame_metrics.size(); i++) {
-
++index;
if (index >= frame_metrics.size()) {
@@ -654,7 +634,6 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const {
const Vector<EditorProfiler::Metric::Category> &frame_cat = frame_metrics[index].categories;
for (int j = 0; j < frame_cat.size(); j++) {
-
const EditorProfiler::Metric::Category &c = frame_cat[j];
values.write[it++] = String::num_real(c.total_time);
@@ -669,7 +648,6 @@ Vector<Vector<String>> EditorProfiler::get_data_as_csv() const {
}
EditorProfiler::EditorProfiler() {
-
HBoxContainer *hb = memnew(HBoxContainer);
add_child(hb);
activate = memnew(Button);
diff --git a/editor/debugger/editor_profiler.h b/editor/debugger/editor_profiler.h
index 4afd2c8302..aa2ef58db4 100644
--- a/editor/debugger/editor_profiler.h
+++ b/editor/debugger/editor_profiler.h
@@ -41,12 +41,10 @@
#include "scene/gui/tree.h"
class EditorProfiler : public VBoxContainer {
-
GDCLASS(EditorProfiler, VBoxContainer);
public:
struct Metric {
-
bool valid;
int frame_number;
@@ -56,13 +54,11 @@ public:
float physics_frame_time;
struct Category {
-
StringName signature;
String name;
float total_time; //total for category
struct Item {
-
StringName signature;
String name;
String script;
diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp
index d2edba5970..81b42da08e 100644
--- a/editor/debugger/editor_visual_profiler.cpp
+++ b/editor/debugger/editor_visual_profiler.cpp
@@ -35,10 +35,10 @@
#include "editor/editor_settings.h"
void EditorVisualProfiler::add_frame_metric(const Metric &p_metric) {
-
++last_metric;
- if (last_metric >= frame_metrics.size())
+ if (last_metric >= frame_metrics.size()) {
last_metric = 0;
+ }
frame_metrics.write[last_metric] = p_metric;
// _make_metric_ptrs(frame_metrics.write[last_metric]);
@@ -60,7 +60,6 @@ void EditorVisualProfiler::add_frame_metric(const Metric &p_metric) {
}
if (name[0] == '>') {
-
stack.push_back(full_name + "/");
}
@@ -83,7 +82,6 @@ void EditorVisualProfiler::add_frame_metric(const Metric &p_metric) {
updating_frame = false;
if (frame_delay->is_stopped()) {
-
frame_delay->set_wait_time(0.1);
frame_delay->start();
}
@@ -95,7 +93,6 @@ void EditorVisualProfiler::add_frame_metric(const Metric &p_metric) {
}
void EditorVisualProfiler::clear() {
-
int metric_size = EditorSettings::get_singleton()->get("debugger/profiler_frame_history_size");
metric_size = CLAMP(metric_size, 60, 1024);
frame_metrics.clear();
@@ -114,7 +111,6 @@ void EditorVisualProfiler::clear() {
}
String EditorVisualProfiler::_get_time_as_text(float p_time) {
-
int dmode = display_mode->get_selected();
if (dmode == DISPLAY_FRAME_TIME) {
@@ -127,28 +123,27 @@ String EditorVisualProfiler::_get_time_as_text(float p_time) {
}
Color EditorVisualProfiler::_get_color_from_signature(const StringName &p_signature) const {
-
Color bc = get_theme_color("error_color", "Editor");
double rot = ABS(double(p_signature.hash()) / double(0x7FFFFFFF));
Color c;
c.set_hsv(rot, bc.get_s(), bc.get_v());
- return c.linear_interpolate(get_theme_color("base_color", "Editor"), 0.07);
+ return c.lerp(get_theme_color("base_color", "Editor"), 0.07);
}
void EditorVisualProfiler::_item_selected() {
-
- if (updating_frame)
+ if (updating_frame) {
return;
+ }
TreeItem *item = variables->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
selected_area = item->get_metadata(0);
_update_plot();
}
void EditorVisualProfiler::_update_plot() {
-
int w = graph->get_size().width;
int h = graph->get_size().height;
@@ -178,8 +173,9 @@ void EditorVisualProfiler::_update_plot() {
for (int i = 0; i < frame_metrics.size(); i++) {
const Metric &m = frame_metrics[i];
- if (!m.valid)
+ if (!m.valid) {
continue;
+ }
if (m.areas.size()) {
highest_cpu = MAX(highest_cpu, m.areas[m.areas.size() - 1].cpu_time);
@@ -188,7 +184,6 @@ void EditorVisualProfiler::_update_plot() {
}
if (highest_cpu > 0 || highest_gpu > 0) {
-
if (frame_relative->is_pressed()) {
highest_cpu = MAX(graph_limit, highest_cpu);
highest_gpu = MAX(graph_limit, highest_gpu);
@@ -225,11 +220,11 @@ void EditorVisualProfiler::_update_plot() {
if (next > frame_metrics.size()) {
next = frame_metrics.size();
}
- if (next == current)
+ if (next == current) {
next = current + 1; //just because for loop must work
+ }
for (int j = current; j < next; j++) {
-
//wrap
int idx = last_metric + 1 + j;
while (idx >= frame_metrics.size()) {
@@ -262,7 +257,6 @@ void EditorVisualProfiler::_update_plot() {
//plot CPU
for (int j = 0; j < h; j++) {
-
uint8_t r, g, b;
if (column_cpu[j].a == 0) {
@@ -283,7 +277,6 @@ void EditorVisualProfiler::_update_plot() {
}
//plot GPU
for (int j = 0; j < h; j++) {
-
uint8_t r, g, b;
if (column_gpu[j].a == 0) {
@@ -307,10 +300,9 @@ void EditorVisualProfiler::_update_plot() {
Ref<Image> img;
img.instance();
- img->create(w, h, 0, Image::FORMAT_RGBA8, graph_image);
+ img->create(w, h, false, Image::FORMAT_RGBA8, graph_image);
if (reset_texture) {
-
if (graph_texture.is_null()) {
graph_texture.instance();
}
@@ -324,7 +316,6 @@ void EditorVisualProfiler::_update_plot() {
}
void EditorVisualProfiler::_update_frame(bool p_focus_selected) {
-
int cursor_metric = _get_cursor_index();
Ref<Texture> track_icon = get_theme_icon("TrackColor", "EditorIcons");
@@ -343,7 +334,6 @@ void EditorVisualProfiler::_update_frame(bool p_focus_selected) {
TreeItem *ensure_selected = nullptr;
for (int i = 1; i < m.areas.size() - 1; i++) {
-
TreeItem *parent = stack.size() ? stack.back()->get() : root;
String name = m.areas[i].name;
@@ -416,7 +406,6 @@ void EditorVisualProfiler::_update_frame(bool p_focus_selected) {
}
void EditorVisualProfiler::_activate_pressed() {
-
if (activate->is_pressed()) {
activate->set_icon(get_theme_icon("Stop", "EditorIcons"));
activate->set_text(TTR("Stop"));
@@ -429,13 +418,11 @@ void EditorVisualProfiler::_activate_pressed() {
}
void EditorVisualProfiler::_clear_pressed() {
-
clear();
_update_plot();
}
void EditorVisualProfiler::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
activate->set_icon(get_theme_icon("Play", "EditorIcons"));
clear_button->set_icon(get_theme_icon("Clear", "EditorIcons"));
@@ -443,16 +430,16 @@ void EditorVisualProfiler::_notification(int p_what) {
}
void EditorVisualProfiler::_graph_tex_draw() {
-
- if (last_metric < 0)
+ if (last_metric < 0) {
return;
+ }
Ref<Font> font = get_theme_font("font", "Label");
if (seeking) {
-
int max_frames = frame_metrics.size();
int frame = cursor_metric_edit->get_value() - (frame_metrics[last_metric].frame_number - max_frames + 1);
- if (frame < 0)
+ if (frame < 0) {
frame = 0;
+ }
int half_width = graph->get_size().x / 2;
int cur_x = frame * half_width / max_frames;
@@ -503,23 +490,23 @@ void EditorVisualProfiler::_graph_tex_draw() {
}
void EditorVisualProfiler::_graph_tex_mouse_exit() {
-
hover_metric = -1;
graph->update();
}
void EditorVisualProfiler::_cursor_metric_changed(double) {
- if (updating_frame)
+ if (updating_frame) {
return;
+ }
graph->update();
_update_frame();
}
void EditorVisualProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
-
- if (last_metric < 0)
+ if (last_metric < 0) {
return;
+ }
Ref<InputEventMouse> me = p_ev;
Ref<InputEventMouseButton> mb = p_ev;
@@ -528,7 +515,6 @@ void EditorVisualProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
if (
(mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) ||
(mm.is_valid())) {
-
int half_w = graph->get_size().width / 2;
int x = me->get_position().x;
if (x > half_w) {
@@ -553,7 +539,6 @@ void EditorVisualProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
}
if (show_hover) {
-
hover_metric = metric;
} else {
@@ -567,15 +552,15 @@ void EditorVisualProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
//metric may be invalid, so look for closest metric that is valid, this makes snap feel better
bool valid = false;
for (int i = 0; i < frame_metrics.size(); i++) {
-
if (frame_metrics[metric].valid) {
valid = true;
break;
}
metric++;
- if (metric >= frame_metrics.size())
+ if (metric >= frame_metrics.size()) {
metric = 0;
+ }
}
if (!valid) {
@@ -607,7 +592,6 @@ void EditorVisualProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
int last_valid = -1;
bool found = false;
for (int i = 0; i < area_count - 1; i++) {
-
if (areas[i].name[0] != '<' && areas[i].name[0] != '>') {
last_valid = i;
}
@@ -636,11 +620,12 @@ void EditorVisualProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
}
int EditorVisualProfiler::_get_cursor_index() const {
-
- if (last_metric < 0)
+ if (last_metric < 0) {
return 0;
- if (!frame_metrics[last_metric].valid)
+ }
+ if (!frame_metrics[last_metric].valid) {
return 0;
+ }
int diff = (frame_metrics[last_metric].frame_number - cursor_metric_edit->get_value());
@@ -653,24 +638,20 @@ int EditorVisualProfiler::_get_cursor_index() const {
}
void EditorVisualProfiler::disable_seeking() {
-
seeking = false;
graph->update();
}
void EditorVisualProfiler::_combo_changed(int) {
-
_update_frame();
_update_plot();
}
void EditorVisualProfiler::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("enable_profiling", PropertyInfo(Variant::BOOL, "enable")));
}
void EditorVisualProfiler::set_enabled(bool p_enable) {
-
activate->set_disabled(!p_enable);
}
@@ -736,7 +717,6 @@ Vector<Vector<String>> EditorVisualProfiler::get_data_as_csv() const {
}
EditorVisualProfiler::EditorVisualProfiler() {
-
HBoxContainer *hb = memnew(HBoxContainer);
add_child(hb);
activate = memnew(Button);
diff --git a/editor/debugger/editor_visual_profiler.h b/editor/debugger/editor_visual_profiler.h
index d3a758557c..3c1a55dc38 100644
--- a/editor/debugger/editor_visual_profiler.h
+++ b/editor/debugger/editor_visual_profiler.h
@@ -42,12 +42,10 @@
#include "scene/gui/tree.h"
class EditorVisualProfiler : public VBoxContainer {
-
GDCLASS(EditorVisualProfiler, VBoxContainer);
public:
struct Metric {
-
bool valid;
uint64_t frame_number;
diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp
index 1971abadc4..49137f76fa 100644
--- a/editor/debugger/script_editor_debugger.cpp
+++ b/editor/debugger/script_editor_debugger.cpp
@@ -31,6 +31,7 @@
#include "script_editor_debugger.h"
#include "core/debugger/debugger_marshalls.h"
+#include "core/debugger/remote_debugger.h"
#include "core/io/marshalls.h"
#include "core/project_settings.h"
#include "core/ustring.h"
@@ -73,16 +74,19 @@ void ScriptEditorDebugger::_put_msg(String p_message, Array p_data) {
void ScriptEditorDebugger::debug_copy() {
String msg = reason->get_text();
- if (msg == "") return;
+ if (msg == "") {
+ return;
+ }
DisplayServer::get_singleton()->clipboard_set(msg);
}
void ScriptEditorDebugger::debug_skip_breakpoints() {
skip_breakpoints_value = !skip_breakpoints_value;
- if (skip_breakpoints_value)
+ if (skip_breakpoints_value) {
skip_breakpoints->set_icon(get_theme_icon("DebugSkipBreakpointsOn", "EditorIcons"));
- else
+ } else {
skip_breakpoints->set_icon(get_theme_icon("DebugSkipBreakpointsOff", "EditorIcons"));
+ }
Array msg;
msg.push_back(skip_breakpoints_value);
@@ -90,14 +94,13 @@ void ScriptEditorDebugger::debug_skip_breakpoints() {
}
void ScriptEditorDebugger::debug_next() {
-
ERR_FAIL_COND(!breaked);
_put_msg("next", Array());
_clear_execution();
}
-void ScriptEditorDebugger::debug_step() {
+void ScriptEditorDebugger::debug_step() {
ERR_FAIL_COND(!breaked);
_put_msg("step", Array());
@@ -105,19 +108,18 @@ void ScriptEditorDebugger::debug_step() {
}
void ScriptEditorDebugger::debug_break() {
-
ERR_FAIL_COND(breaked);
_put_msg("break", Array());
}
void ScriptEditorDebugger::debug_continue() {
-
ERR_FAIL_COND(!breaked);
// Allow focus stealing only if we actually run this client for security.
- if (remote_pid && EditorNode::get_singleton()->has_child_process(remote_pid))
+ if (remote_pid && EditorNode::get_singleton()->has_child_process(remote_pid)) {
DisplayServer::get_singleton()->enable_for_stealing_focus(remote_pid);
+ }
_clear_execution();
_put_msg("continue", Array());
@@ -129,10 +131,12 @@ void ScriptEditorDebugger::update_tabs() {
tabs->set_tab_icon(errors_tab->get_index(), Ref<Texture2D>());
} else {
errors_tab->set_name(TTR("Errors") + " (" + itos(error_count + warning_count) + ")");
- if (error_count == 0) {
- tabs->set_tab_icon(errors_tab->get_index(), get_theme_icon("Warning", "EditorIcons"));
- } else {
+ if (error_count >= 1 && warning_count >= 1) {
+ tabs->set_tab_icon(errors_tab->get_index(), get_theme_icon("ErrorWarning", "EditorIcons"));
+ } else if (error_count >= 1) {
tabs->set_tab_icon(errors_tab->get_index(), get_theme_icon("Error", "EditorIcons"));
+ } else {
+ tabs->set_tab_icon(errors_tab->get_index(), get_theme_icon("Warning", "EditorIcons"));
}
}
}
@@ -149,44 +153,75 @@ void ScriptEditorDebugger::save_node(ObjectID p_id, const String &p_file) {
}
void ScriptEditorDebugger::_file_selected(const String &p_file) {
- Error err;
- FileAccessRef file = FileAccess::open(p_file, FileAccess::WRITE, &err);
-
- if (err != OK) {
- ERR_PRINT("Failed to open " + p_file);
- return;
- }
- Vector<String> line;
- line.resize(Performance::MONITOR_MAX);
+ switch (file_dialog_purpose) {
+ case SAVE_MONITORS_CSV: {
+ Error err;
+ FileAccessRef file = FileAccess::open(p_file, FileAccess::WRITE, &err);
+
+ if (err != OK) {
+ ERR_PRINT("Failed to open " + p_file);
+ return;
+ }
+ Vector<String> line;
+ line.resize(Performance::MONITOR_MAX);
- // signatures
- for (int i = 0; i < Performance::MONITOR_MAX; i++) {
- line.write[i] = Performance::get_singleton()->get_monitor_name(Performance::Monitor(i));
- }
- file->store_csv_line(line);
+ // signatures
+ for (int i = 0; i < Performance::MONITOR_MAX; i++) {
+ line.write[i] = Performance::get_singleton()->get_monitor_name(Performance::Monitor(i));
+ }
+ file->store_csv_line(line);
+
+ // values
+ List<Vector<float>>::Element *E = perf_history.back();
+ while (E) {
+ Vector<float> &perf_data = E->get();
+ for (int i = 0; i < perf_data.size(); i++) {
+ line.write[i] = String::num_real(perf_data[i]);
+ }
+ file->store_csv_line(line);
+ E = E->prev();
+ }
+ file->store_string("\n");
- // values
- List<Vector<float>>::Element *E = perf_history.back();
- while (E) {
+ Vector<Vector<String>> profiler_data = profiler->get_data_as_csv();
+ for (int i = 0; i < profiler_data.size(); i++) {
+ file->store_csv_line(profiler_data[i]);
+ }
+ } break;
+ case SAVE_VRAM_CSV: {
+ Error err;
+ FileAccessRef file = FileAccess::open(p_file, FileAccess::WRITE, &err);
- Vector<float> &perf_data = E->get();
- for (int i = 0; i < perf_data.size(); i++) {
+ if (err != OK) {
+ ERR_PRINT("Failed to open " + p_file);
+ return;
+ }
- line.write[i] = String::num_real(perf_data[i]);
- }
- file->store_csv_line(line);
- E = E->prev();
- }
- file->store_string("\n");
+ Vector<String> headers;
+ headers.resize(vmem_tree->get_columns());
+ for (int i = 0; i < vmem_tree->get_columns(); ++i) {
+ headers.write[i] = vmem_tree->get_column_title(i);
+ }
+ file->store_csv_line(headers);
+
+ if (vmem_tree->get_root()) {
+ TreeItem *ti = vmem_tree->get_root()->get_children();
+ while (ti) {
+ Vector<String> values;
+ values.resize(vmem_tree->get_columns());
+ for (int i = 0; i < vmem_tree->get_columns(); ++i) {
+ values.write[i] = ti->get_text(i);
+ }
+ file->store_csv_line(values);
- Vector<Vector<String>> profiler_data = profiler->get_data_as_csv();
- for (int i = 0; i < profiler_data.size(); i++) {
- file->store_csv_line(profiler_data[i]);
+ ti = ti->get_next();
+ }
+ }
+ } break;
}
}
void ScriptEditorDebugger::request_remote_tree() {
-
_put_msg("scene:request_scene_tree", Array());
}
@@ -195,7 +230,6 @@ const SceneDebuggerTree *ScriptEditorDebugger::get_remote_tree() {
}
void ScriptEditorDebugger::update_remote_object(ObjectID p_obj_id, const String &p_prop, const Variant &p_value) {
-
Array msg;
msg.push_back(p_obj_id);
msg.push_back(p_prop);
@@ -204,7 +238,6 @@ void ScriptEditorDebugger::update_remote_object(ObjectID p_obj_id, const String
}
void ScriptEditorDebugger::request_remote_object(ObjectID p_obj_id) {
-
ERR_FAIL_COND(p_obj_id.is_null());
Array msg;
msg.push_back(p_obj_id);
@@ -229,21 +262,25 @@ void ScriptEditorDebugger::_remote_object_property_updated(ObjectID p_id, const
}
void ScriptEditorDebugger::_video_mem_request() {
-
_put_msg("core:memory", Array());
}
-Size2 ScriptEditorDebugger::get_minimum_size() const {
+void ScriptEditorDebugger::_video_mem_export() {
+ file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
+ file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+ file_dialog->clear_filters();
+ file_dialog_purpose = SAVE_VRAM_CSV;
+ file_dialog->popup_centered_ratio();
+}
+Size2 ScriptEditorDebugger::get_minimum_size() const {
Size2 ms = MarginContainer::get_minimum_size();
ms.y = MAX(ms.y, 250 * EDSCALE);
return ms;
}
void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_data) {
-
if (p_msg == "debug_enter") {
-
_put_msg("get_stack_dump", Array());
ERR_FAIL_COND(p_data.size() != 2);
@@ -262,7 +299,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
inspector->clear_cache(); // Take a chance to force remote objects update.
} else if (p_msg == "debug_exit") {
-
breaked = false;
can_debug = false;
_clear_execution();
@@ -272,27 +308,23 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
profiler->set_enabled(true);
profiler->disable_seeking();
} else if (p_msg == "set_pid") {
-
ERR_FAIL_COND(p_data.size() < 1);
remote_pid = p_data[0];
} else if (p_msg == "scene:click_ctrl") {
-
ERR_FAIL_COND(p_data.size() < 2);
clicked_ctrl->set_text(p_data[0]);
clicked_ctrl_type->set_text(p_data[1]);
} else if (p_msg == "scene:scene_tree") {
-
scene_tree->nodes.clear();
scene_tree->deserialize(p_data);
emit_signal("remote_tree_updated");
_update_buttons_state();
} else if (p_msg == "scene:inspect_object") {
-
ObjectID id = inspector->add_object(p_data);
- if (id.is_valid())
+ if (id.is_valid()) {
emit_signal("remote_object_updated", id);
+ }
} else if (p_msg == "memory:usage") {
-
vmem_tree->clear();
TreeItem *root = vmem_tree->create_item();
DebuggerMarshalls::ResourceUsage usage;
@@ -301,7 +333,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
int total = 0;
for (List<DebuggerMarshalls::ResourceInfo>::Element *E = usage.infos.front(); E; E = E->next()) {
-
TreeItem *it = vmem_tree->create_item(root);
String type = E->get().type;
int bytes = E->get().vram;
@@ -311,15 +342,15 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
it->set_text(3, String::humanize_size(bytes));
total += bytes;
- if (has_theme_icon(type, "EditorIcons"))
+ if (has_theme_icon(type, "EditorIcons")) {
it->set_icon(0, get_theme_icon(type, "EditorIcons"));
+ }
}
vmem_total->set_tooltip(TTR("Bytes:") + " " + itos(total));
vmem_total->set_text(String::humanize_size(total));
} else if (p_msg == "stack_dump") {
-
DebuggerMarshalls::ScriptStackDump stack;
stack.deserialize(p_data);
@@ -328,7 +359,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
TreeItem *r = stack_dump->create_item();
for (int i = 0; i < stack.frames.size(); i++) {
-
TreeItem *s = stack_dump->create_item(r);
Dictionary d;
d["frame"] = i;
@@ -340,29 +370,50 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
String line = itos(i) + " - " + String(d["file"]) + ":" + itos(d["line"]) + " - at function: " + d["function"];
s->set_text(0, line);
- if (i == 0)
+ if (i == 0) {
s->select(0);
+ }
}
} else if (p_msg == "stack_frame_vars") {
-
inspector->clear_stack_variables();
} else if (p_msg == "stack_frame_var") {
-
inspector->add_stack_variable(p_data);
} else if (p_msg == "output") {
- ERR_FAIL_COND(p_data.size() < 1);
+ ERR_FAIL_COND(p_data.size() != 2);
+
ERR_FAIL_COND(p_data[0].get_type() != Variant::PACKED_STRING_ARRAY);
- Vector<String> strings = p_data[0];
- EditorNode::get_log()->add_message(String("\n").join(strings));
+ Vector<String> output_strings = p_data[0];
+
+ ERR_FAIL_COND(p_data[1].get_type() != Variant::PACKED_INT32_ARRAY);
+ Vector<int> output_types = p_data[1];
+
+ ERR_FAIL_COND(output_strings.size() != output_types.size());
+
+ for (int i = 0; i < output_strings.size(); i++) {
+ RemoteDebugger::MessageType type = (RemoteDebugger::MessageType)(int)(output_types[i]);
+ EditorLog::MessageType msg_type;
+ switch (type) {
+ case RemoteDebugger::MESSAGE_TYPE_LOG: {
+ msg_type = EditorLog::MSG_TYPE_STD;
+ } break;
+ case RemoteDebugger::MESSAGE_TYPE_ERROR: {
+ msg_type = EditorLog::MSG_TYPE_ERROR;
+ } break;
+ default: {
+ WARN_PRINT("Unhandled script debugger message type: " + itos(type));
+ msg_type = EditorLog::MSG_TYPE_STD;
+ } break;
+ }
+ EditorNode::get_log()->add_message(output_strings[i], msg_type);
+ }
} else if (p_msg == "performance:profile_frame") {
Vector<float> p;
p.resize(p_data.size());
for (int i = 0; i < p_data.size(); i++) {
p.write[i] = p_data[i];
if (i < perf_items.size()) {
-
const float value = p[i];
String label = rtos(value);
String tooltip = label;
@@ -382,8 +433,9 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
perf_items[i]->set_text(1, label);
perf_items[i]->set_tooltip(1, tooltip);
- if (p[i] > perf_max[i])
+ if (p[i] > perf_max[i]) {
perf_max.write[i] = p[i];
+ }
}
}
perf_history.push_front(p);
@@ -409,7 +461,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
visual_profiler->add_frame_metric(metric);
} else if (p_msg == "error") {
-
DebuggerMarshalls::OutputError oe;
ERR_FAIL_COND_MSG(oe.deserialize(p_data) == false, "Failed to deserialize error message");
@@ -449,8 +500,9 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
String error_title;
// Include method name, when given, in error title.
- if (!oe.source_func.empty())
+ if (!oe.source_func.empty()) {
error_title += oe.source_func + ": ";
+ }
// If we have a (custom) error message, use it as title, and add a C++ Error
// item with the original error condition.
error_title += oe.error_descr.empty() ? oe.error : oe.error_descr;
@@ -464,16 +516,18 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
cpp_cond->set_text(1, oe.error);
cpp_cond->set_text_align(0, TreeItem::ALIGN_LEFT);
tooltip += TTR("C++ Error:") + " " + oe.error + "\n";
- if (source_is_project_file)
+ if (source_is_project_file) {
cpp_cond->set_metadata(0, source_meta);
+ }
}
Vector<uint8_t> v;
v.resize(100);
// Source of the error.
String source_txt = (source_is_project_file ? oe.source_file.get_file() : oe.source_file) + ":" + itos(oe.source_line);
- if (!oe.source_func.empty())
+ if (!oe.source_func.empty()) {
source_txt += " @ " + oe.source_func + "()";
+ }
TreeItem *cpp_source = error_tree->create_item(error);
cpp_source->set_text(0, "<" + (source_is_project_file ? TTR("Source") : TTR("C++ Source")) + ">");
@@ -495,7 +549,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
// of the stack trace (script, method, line).
const ScriptLanguage::StackInfo *infos = oe.callstack.ptr();
for (unsigned int i = 0; i < (unsigned int)oe.callstack.size(); i++) {
-
TreeItem *stack_trace = error_tree->create_item(error);
Array meta;
@@ -511,10 +564,11 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
stack_trace->set_text(1, infos[i].file.get_file() + ":" + itos(infos[i].line) + " @ " + infos[i].func + "()");
}
- if (oe.warning)
+ if (oe.warning) {
warning_count++;
- else
+ } else {
error_count++;
+ }
} else if (p_msg == "servers:function_signature") {
// Cache a profiler signature.
@@ -568,7 +622,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
}
for (int i = 0; i < frame.servers.size(); i++) {
-
const DebuggerMarshalls::ServerInfo &srv = frame.servers[i];
EditorProfiler::Metric::Category c;
const String name = srv.name;
@@ -577,7 +630,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
c.total_time = 0;
c.signature = "categ::" + name;
for (int j = 0; j < srv.functions.size(); j++) {
-
EditorProfiler::Metric::Category::Item item;
item.calls = 1;
item.line = 0;
@@ -598,7 +650,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
funcs.name = "Script Functions";
funcs.signature = "script_functions";
for (int i = 0; i < frame.script_functions.size(); i++) {
-
int signature = frame.script_functions[i].sig_id;
int calls = frame.script_functions[i].call_count;
float total = frame.script_functions[i].total_time;
@@ -606,7 +657,6 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
EditorProfiler::Metric::Category::Item item;
if (profiler_signature.has(signature)) {
-
item.signature = profiler_signature[signature];
String name = profiler_signature[signature];
@@ -633,10 +683,11 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
metric.categories.push_back(funcs);
- if (p_msg == "servers:profile_frame")
+ if (p_msg == "servers:profile_frame") {
profiler->add_frame_metric(metric, false);
- else
+ } else {
profiler->add_frame_metric(metric, true);
+ }
} else if (p_msg == "network:profile_frame") {
DebuggerMarshalls::NetworkProfilerFrame frame;
@@ -674,17 +725,15 @@ void ScriptEditorDebugger::_set_reason_text(const String &p_reason, MessageType
}
void ScriptEditorDebugger::_performance_select() {
-
perf_draw->update();
}
void ScriptEditorDebugger::_performance_draw() {
-
Vector<int> which;
for (int i = 0; i < perf_items.size(); i++) {
-
- if (perf_items[i]->is_checked(0))
+ if (perf_items[i]->is_checked(0)) {
which.push_back(i);
+ }
}
if (which.empty()) {
@@ -699,14 +748,14 @@ void ScriptEditorDebugger::_performance_draw() {
int cols = Math::ceil(Math::sqrt((float)which.size()));
int rows = Math::ceil((float)which.size() / cols);
- if (which.size() == 1)
+ if (which.size() == 1) {
rows = 1;
+ }
int margin = 3;
int point_sep = 5;
Size2i s = Size2i(perf_draw->get_size()) / Size2i(cols, rows);
for (int i = 0; i < which.size(); i++) {
-
Point2i p(i % cols, i / cols);
Rect2i r(p * s, s);
r.position += Point2(margin, margin);
@@ -732,15 +781,16 @@ void ScriptEditorDebugger::_performance_draw() {
List<Vector<float>>::Element *E = perf_history.front();
float prev = -1;
while (from >= 0 && E) {
-
float m = perf_max[pi];
- if (m == 0)
+ if (m == 0) {
m = 0.00001;
+ }
float h2 = E->get()[pi] / m;
h2 = (1.0 - h2) * r.size.y;
- if (E != perf_history.front())
+ if (E != perf_history.front()) {
perf_draw->draw_line(r.position + Point2(from, h2), r.position + Point2(from + spacing, prev), c, Math::round(EDSCALE));
+ }
prev = h2;
E = E->next();
from -= spacing;
@@ -749,11 +799,8 @@ void ScriptEditorDebugger::_performance_draw() {
}
void ScriptEditorDebugger::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
skip_breakpoints->set_icon(get_theme_icon("DebugSkipBreakpointsOff", "EditorIcons"));
copy->set_icon(get_theme_icon("ActionCopy", "EditorIcons"));
@@ -766,13 +813,14 @@ void ScriptEditorDebugger::_notification(int p_what) {
error_tree->connect("item_selected", callable_mp(this, &ScriptEditorDebugger::_error_selected));
error_tree->connect("item_activated", callable_mp(this, &ScriptEditorDebugger::_error_activated));
vmem_refresh->set_icon(get_theme_icon("Reload", "EditorIcons"));
+ vmem_export->set_icon(get_theme_icon("Save", "EditorIcons"));
reason->add_theme_color_override("font_color", get_theme_color("error_color", "Editor"));
} break;
case NOTIFICATION_PROCESS: {
-
if (is_session_active()) {
+ peer->poll();
if (camera_override == CameraOverride::OVERRIDE_2D) {
CanvasItemEditor *editor = CanvasItemEditor::get_singleton();
@@ -812,7 +860,6 @@ void ScriptEditorDebugger::_notification(int p_what) {
const uint64_t until = OS::get_singleton()->get_ticks_msec() + 20;
while (peer.is_valid() && peer->has_message()) {
-
Array arr = peer->get_message();
if (arr.size() != 2 || arr[0].get_type() != Variant::STRING || arr[1].get_type() != Variant::ARRAY) {
_stop_and_notify();
@@ -820,8 +867,9 @@ void ScriptEditorDebugger::_notification(int p_what) {
}
_parse_message(arr[0], arr[1]);
- if (OS::get_singleton()->get_ticks_msec() > until)
+ if (OS::get_singleton()->get_ticks_msec() > until) {
break;
+ }
}
if (!is_session_active()) {
_stop_and_notify();
@@ -829,7 +877,6 @@ void ScriptEditorDebugger::_notification(int p_what) {
};
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
-
if (tabs->has_theme_stylebox_override("panel")) {
tabs->add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox("DebuggerPanel", "EditorStyles"));
}
@@ -840,14 +887,16 @@ void ScriptEditorDebugger::_notification(int p_what) {
dobreak->set_icon(get_theme_icon("Pause", "EditorIcons"));
docontinue->set_icon(get_theme_icon("DebugContinue", "EditorIcons"));
vmem_refresh->set_icon(get_theme_icon("Reload", "EditorIcons"));
+ vmem_export->set_icon(get_theme_icon("Save", "EditorIcons"));
} break;
}
}
void ScriptEditorDebugger::_clear_execution() {
TreeItem *ti = stack_dump->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
Dictionary d = ti->get_metadata(0);
@@ -859,7 +908,6 @@ void ScriptEditorDebugger::_clear_execution() {
}
void ScriptEditorDebugger::start(Ref<RemoteDebuggerPeer> p_peer) {
-
error_count = 0;
warning_count = 0;
stop();
@@ -869,7 +917,6 @@ void ScriptEditorDebugger::start(Ref<RemoteDebuggerPeer> p_peer) {
perf_history.clear();
for (int i = 0; i < Performance::MONITOR_MAX; i++) {
-
perf_max.write[i] = 0;
}
@@ -903,7 +950,6 @@ void ScriptEditorDebugger::_stop_and_notify() {
}
void ScriptEditorDebugger::stop() {
-
set_process(false);
breaked = false;
can_debug = false;
@@ -928,7 +974,6 @@ void ScriptEditorDebugger::stop() {
}
void ScriptEditorDebugger::_profiler_activate(bool p_enable, int p_type) {
-
Array data;
data.push_back(p_enable);
switch (p_type) {
@@ -956,14 +1001,13 @@ void ScriptEditorDebugger::_profiler_activate(bool p_enable, int p_type) {
}
void ScriptEditorDebugger::_profiler_seeked() {
-
- if (breaked)
+ if (breaked) {
return;
+ }
debug_break();
}
void ScriptEditorDebugger::_stack_dump_frame_selected() {
-
emit_signal("stack_frame_selected");
int frame = get_stack_script_frame();
@@ -978,23 +1022,24 @@ void ScriptEditorDebugger::_stack_dump_frame_selected() {
}
void ScriptEditorDebugger::_export_csv() {
-
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
file_dialog->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+ file_dialog_purpose = SAVE_MONITORS_CSV;
file_dialog->popup_centered_ratio();
}
String ScriptEditorDebugger::get_var_value(const String &p_var) const {
- if (!breaked)
+ if (!breaked) {
return String();
+ }
return inspector->get_stack_variable(p_var);
}
int ScriptEditorDebugger::_get_node_path_cache(const NodePath &p_path) {
-
const int *r = node_path_cache.getptr(p_path);
- if (r)
+ if (r) {
return *r;
+ }
last_path_id++;
@@ -1008,11 +1053,11 @@ int ScriptEditorDebugger::_get_node_path_cache(const NodePath &p_path) {
}
int ScriptEditorDebugger::_get_res_path_cache(const String &p_path) {
-
Map<String, int>::Element *E = res_path_cache.find(p_path);
- if (E)
+ if (E) {
return E->get();
+ }
last_path_id++;
@@ -1026,9 +1071,9 @@ int ScriptEditorDebugger::_get_res_path_cache(const String &p_path) {
}
void ScriptEditorDebugger::_method_changed(Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE) {
-
- if (!p_base || !live_debug || !is_session_active() || !editor->get_edited_scene())
+ if (!p_base || !live_debug || !is_session_active() || !editor->get_edited_scene()) {
return;
+ }
Node *node = Object::cast_to<Node>(p_base);
@@ -1036,12 +1081,12 @@ void ScriptEditorDebugger::_method_changed(Object *p_base, const StringName &p_n
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
//no pointers, sorry
- if (argptr[i] && (argptr[i]->get_type() == Variant::OBJECT || argptr[i]->get_type() == Variant::_RID))
+ if (argptr[i] && (argptr[i]->get_type() == Variant::OBJECT || argptr[i]->get_type() == Variant::_RID)) {
return;
+ }
}
if (node) {
-
NodePath path = editor->get_edited_scene()->get_path_to(node);
int pathid = _get_node_path_cache(path);
@@ -1060,7 +1105,6 @@ void ScriptEditorDebugger::_method_changed(Object *p_base, const StringName &p_n
Resource *res = Object::cast_to<Resource>(p_base);
if (res && res->get_path() != String()) {
-
String respath = res->get_path();
int pathid = _get_res_path_cache(respath);
@@ -1078,21 +1122,19 @@ void ScriptEditorDebugger::_method_changed(Object *p_base, const StringName &p_n
}
void ScriptEditorDebugger::_property_changed(Object *p_base, const StringName &p_property, const Variant &p_value) {
-
- if (!p_base || !live_debug || !editor->get_edited_scene())
+ if (!p_base || !live_debug || !editor->get_edited_scene()) {
return;
+ }
Node *node = Object::cast_to<Node>(p_base);
if (node) {
-
NodePath path = editor->get_edited_scene()->get_path_to(node);
int pathid = _get_node_path_cache(path);
if (p_value.is_ref()) {
Ref<Resource> res = p_value;
if (res.is_valid() && res->get_path() != String()) {
-
Array msg;
msg.push_back(pathid);
msg.push_back(p_property);
@@ -1100,7 +1142,6 @@ void ScriptEditorDebugger::_property_changed(Object *p_base, const StringName &p
_put_msg("scene:live_node_prop_res", msg);
}
} else {
-
Array msg;
msg.push_back(pathid);
msg.push_back(p_property);
@@ -1114,14 +1155,12 @@ void ScriptEditorDebugger::_property_changed(Object *p_base, const StringName &p
Resource *res = Object::cast_to<Resource>(p_base);
if (res && res->get_path() != String()) {
-
String respath = res->get_path();
int pathid = _get_res_path_cache(respath);
if (p_value.is_ref()) {
Ref<Resource> res2 = p_value;
if (res2.is_valid() && res2->get_path() != String()) {
-
Array msg;
msg.push_back(pathid);
msg.push_back(p_property);
@@ -1129,7 +1168,6 @@ void ScriptEditorDebugger::_property_changed(Object *p_base, const StringName &p
_put_msg("scene:live_res_prop_res", msg);
}
} else {
-
Array msg;
msg.push_back(pathid);
msg.push_back(p_property);
@@ -1143,41 +1181,44 @@ void ScriptEditorDebugger::_property_changed(Object *p_base, const StringName &p
String ScriptEditorDebugger::get_stack_script_file() const {
TreeItem *ti = stack_dump->get_selected();
- if (!ti)
+ if (!ti) {
return "";
+ }
Dictionary d = ti->get_metadata(0);
return d["file"];
}
int ScriptEditorDebugger::get_stack_script_line() const {
TreeItem *ti = stack_dump->get_selected();
- if (!ti)
+ if (!ti) {
return -1;
+ }
Dictionary d = ti->get_metadata(0);
return d["line"];
}
int ScriptEditorDebugger::get_stack_script_frame() const {
TreeItem *ti = stack_dump->get_selected();
- if (!ti)
+ if (!ti) {
return -1;
+ }
Dictionary d = ti->get_metadata(0);
return d["frame"];
}
void ScriptEditorDebugger::set_live_debugging(bool p_enable) {
-
live_debug = p_enable;
}
void ScriptEditorDebugger::_live_edit_set() {
-
- if (!is_session_active() || !editor_remote_tree)
+ if (!is_session_active() || !editor_remote_tree) {
return;
+ }
TreeItem *ti = editor_remote_tree->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
String path;
@@ -1195,7 +1236,6 @@ void ScriptEditorDebugger::_live_edit_set() {
}
void ScriptEditorDebugger::_live_edit_clear() {
-
NodePath np = NodePath("/root");
editor->get_editor_data().set_edited_scene_live_edit_root(np);
@@ -1203,21 +1243,20 @@ void ScriptEditorDebugger::_live_edit_clear() {
}
void ScriptEditorDebugger::update_live_edit_root() {
-
NodePath np = editor->get_editor_data().get_edited_scene_live_edit_root();
Array msg;
msg.push_back(np);
- if (editor->get_edited_scene())
+ if (editor->get_edited_scene()) {
msg.push_back(editor->get_edited_scene()->get_filename());
- else
+ } else {
msg.push_back("");
+ }
_put_msg("scene:live_set_root", msg);
live_edit_root->set_text(np);
}
void ScriptEditorDebugger::live_debug_create_node(const NodePath &p_parent, const String &p_type, const String &p_name) {
-
if (live_debug) {
Array msg;
msg.push_back(p_parent);
@@ -1228,7 +1267,6 @@ void ScriptEditorDebugger::live_debug_create_node(const NodePath &p_parent, cons
}
void ScriptEditorDebugger::live_debug_instance_node(const NodePath &p_parent, const String &p_path, const String &p_name) {
-
if (live_debug) {
Array msg;
msg.push_back(p_parent);
@@ -1237,16 +1275,16 @@ void ScriptEditorDebugger::live_debug_instance_node(const NodePath &p_parent, co
_put_msg("scene:live_instance_node", msg);
}
}
-void ScriptEditorDebugger::live_debug_remove_node(const NodePath &p_at) {
+void ScriptEditorDebugger::live_debug_remove_node(const NodePath &p_at) {
if (live_debug) {
Array msg;
msg.push_back(p_at);
_put_msg("scene:live_remove_node", msg);
}
}
-void ScriptEditorDebugger::live_debug_remove_and_keep_node(const NodePath &p_at, ObjectID p_keep_id) {
+void ScriptEditorDebugger::live_debug_remove_and_keep_node(const NodePath &p_at, ObjectID p_keep_id) {
if (live_debug) {
Array msg;
msg.push_back(p_at);
@@ -1254,8 +1292,8 @@ void ScriptEditorDebugger::live_debug_remove_and_keep_node(const NodePath &p_at,
_put_msg("scene:live_remove_and_keep_node", msg);
}
}
-void ScriptEditorDebugger::live_debug_restore_node(ObjectID p_id, const NodePath &p_at, int p_at_pos) {
+void ScriptEditorDebugger::live_debug_restore_node(ObjectID p_id, const NodePath &p_at, int p_at_pos) {
if (live_debug) {
Array msg;
msg.push_back(p_id);
@@ -1264,8 +1302,8 @@ void ScriptEditorDebugger::live_debug_restore_node(ObjectID p_id, const NodePath
_put_msg("scene:live_restore_node", msg);
}
}
-void ScriptEditorDebugger::live_debug_duplicate_node(const NodePath &p_at, const String &p_new_name) {
+void ScriptEditorDebugger::live_debug_duplicate_node(const NodePath &p_at, const String &p_new_name) {
if (live_debug) {
Array msg;
msg.push_back(p_at);
@@ -1273,8 +1311,8 @@ void ScriptEditorDebugger::live_debug_duplicate_node(const NodePath &p_at, const
_put_msg("scene:live_duplicate_node", msg);
}
}
-void ScriptEditorDebugger::live_debug_reparent_node(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos) {
+void ScriptEditorDebugger::live_debug_reparent_node(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos) {
if (live_debug) {
Array msg;
msg.push_back(p_at);
@@ -1290,7 +1328,6 @@ CameraOverride ScriptEditorDebugger::get_camera_override() const {
}
void ScriptEditorDebugger::set_camera_override(CameraOverride p_override) {
-
if (p_override == CameraOverride::OVERRIDE_2D && camera_override != CameraOverride::OVERRIDE_2D) {
Array msg;
msg.push_back(true);
@@ -1313,7 +1350,6 @@ void ScriptEditorDebugger::set_camera_override(CameraOverride p_override) {
}
void ScriptEditorDebugger::set_breakpoint(const String &p_path, int p_line, bool p_enabled) {
-
Array msg;
msg.push_back(p_path);
msg.push_back(p_line);
@@ -1322,7 +1358,6 @@ void ScriptEditorDebugger::set_breakpoint(const String &p_path, int p_line, bool
}
void ScriptEditorDebugger::reload_scripts() {
-
_put_msg("reload_scripts", Array());
}
@@ -1350,10 +1385,10 @@ void ScriptEditorDebugger::_error_selected() {
}
void ScriptEditorDebugger::_expand_errors_list() {
-
TreeItem *root = error_tree->get_root();
- if (!root)
+ if (!root) {
return;
+ }
TreeItem *item = root->get_children();
while (item) {
@@ -1363,10 +1398,10 @@ void ScriptEditorDebugger::_expand_errors_list() {
}
void ScriptEditorDebugger::_collapse_errors_list() {
-
TreeItem *root = error_tree->get_root();
- if (!root)
+ if (!root) {
return;
+ }
TreeItem *item = root->get_children();
while (item) {
@@ -1376,7 +1411,6 @@ void ScriptEditorDebugger::_collapse_errors_list() {
}
void ScriptEditorDebugger::_clear_errors_list() {
-
error_tree->clear();
error_count = 0;
warning_count = 0;
@@ -1384,7 +1418,6 @@ void ScriptEditorDebugger::_clear_errors_list() {
// Right click on specific file(s) or folder(s).
void ScriptEditorDebugger::_error_tree_item_rmb_selected(const Vector2 &p_pos) {
-
item_menu->clear();
item_menu->set_size(Size2(1, 1));
@@ -1400,8 +1433,9 @@ void ScriptEditorDebugger::_error_tree_item_rmb_selected(const Vector2 &p_pos) {
void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) {
TreeItem *ti = error_tree->get_selected();
- while (ti->get_parent() != error_tree->get_root())
+ while (ti->get_parent() != error_tree->get_root()) {
ti = ti->get_parent();
+ }
String type;
@@ -1432,7 +1466,6 @@ void ScriptEditorDebugger::_tab_changed(int p_tab) {
}
void ScriptEditorDebugger::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("live_debug_create_node"), &ScriptEditorDebugger::live_debug_create_node);
ClassDB::bind_method(D_METHOD("live_debug_instance_node"), &ScriptEditorDebugger::live_debug_instance_node);
ClassDB::bind_method(D_METHOD("live_debug_remove_node"), &ScriptEditorDebugger::live_debug_remove_node);
@@ -1457,7 +1490,6 @@ void ScriptEditorDebugger::_bind_methods() {
}
ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
-
editor = p_editor;
tabs = memnew(TabContainer);
@@ -1653,7 +1685,6 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
TreeItem *root = perf_monitors->create_item();
perf_monitors->set_hide_root(true);
for (int i = 0; i < Performance::MONITOR_MAX; i++) {
-
String n = Performance::get_singleton()->get_monitor_name(Performance::Monitor(i));
Performance::MonitorType mtype = Performance::get_singleton()->get_monitor_type(Performance::Monitor(i));
String base = n.get_slice("/", 0);
@@ -1701,8 +1732,12 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
vmem_hb->add_child(vmem_total);
vmem_refresh = memnew(ToolButton);
vmem_hb->add_child(vmem_refresh);
+ vmem_export = memnew(ToolButton);
+ vmem_export->set_tooltip(TTR("Export list to a CSV file"));
+ vmem_hb->add_child(vmem_export);
vmem_vb->add_child(vmem_hb);
vmem_refresh->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_video_mem_request));
+ vmem_export->connect("pressed", callable_mp(this, &ScriptEditorDebugger::_video_mem_export));
VBoxContainer *vmmc = memnew(VBoxContainer);
vmem_tree = memnew(Tree);
@@ -1786,7 +1821,6 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
}
ScriptEditorDebugger::~ScriptEditorDebugger() {
-
if (peer.is_valid()) {
peer->close();
peer.unref();
diff --git a/editor/debugger/script_editor_debugger.h b/editor/debugger/script_editor_debugger.h
index 9cb7dc2edf..2984051aa1 100644
--- a/editor/debugger/script_editor_debugger.h
+++ b/editor/debugger/script_editor_debugger.h
@@ -55,7 +55,6 @@ class EditorNetworkProfiler;
class SceneDebuggerTree;
class ScriptEditorDebugger : public MarginContainer {
-
GDCLASS(ScriptEditorDebugger, MarginContainer);
friend class EditorDebuggerNode;
@@ -88,6 +87,11 @@ private:
PopupMenu *item_menu;
EditorFileDialog *file_dialog;
+ enum FileDialogPurpose {
+ SAVE_MONITORS_CSV,
+ SAVE_VRAM_CSV,
+ };
+ FileDialogPurpose file_dialog_purpose;
int error_count;
int warning_count;
@@ -121,6 +125,7 @@ private:
Tree *vmem_tree;
Button *vmem_refresh;
+ Button *vmem_export;
LineEdit *vmem_total;
Tree *stack_dump;
@@ -160,6 +165,7 @@ private:
void _remote_object_property_updated(ObjectID p_id, const String &p_property);
void _video_mem_request();
+ void _video_mem_export();
int _get_node_path_cache(const NodePath &p_path);
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index 2302fb0780..c6977779bd 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -37,7 +37,6 @@
#include "scene/gui/margin_container.h"
void DependencyEditor::_searched(const String &p_path) {
-
Map<String, String> dep_rename;
dep_rename[replacing] = p_path;
@@ -48,7 +47,6 @@ void DependencyEditor::_searched(const String &p_path) {
}
void DependencyEditor::_load_pressed(Object *p_item, int p_cell, int p_button) {
-
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
replacing = ti->get_text(1);
@@ -64,21 +62,19 @@ void DependencyEditor::_load_pressed(Object *p_item, int p_cell, int p_button) {
}
void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String, Map<String, String>> &candidates) {
-
for (int i = 0; i < efsd->get_subdir_count(); i++) {
_fix_and_find(efsd->get_subdir(i), candidates);
}
for (int i = 0; i < efsd->get_file_count(); i++) {
-
String file = efsd->get_file(i);
- if (!candidates.has(file))
+ if (!candidates.has(file)) {
continue;
+ }
String path = efsd->get_file_path(i);
for (Map<String, String>::Element *E = candidates[file].front(); E; E = E->next()) {
-
if (E->get() == String()) {
E->get() = path;
continue;
@@ -100,7 +96,6 @@ void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String
int current_score = 0;
for (int j = 0; j < lostv.size(); j++) {
-
if (j < existingv.size() && lostv[j] == existingv[j]) {
existing_score++;
}
@@ -110,7 +105,6 @@ void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String
}
if (current_score > existing_score) {
-
//if it was the same, could track distance to new path but..
E->get() = path; //replace by more accurate
@@ -120,14 +114,13 @@ void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String
}
void DependencyEditor::_fix_all() {
-
- if (!EditorFileSystem::get_singleton()->get_filesystem())
+ if (!EditorFileSystem::get_singleton()->get_filesystem()) {
return;
+ }
Map<String, Map<String, String>> candidates;
for (List<String>::Element *E = missing.front(); E; E = E->next()) {
-
String base = E->get().get_file();
if (!candidates.has(base)) {
candidates[base] = Map<String, String>();
@@ -141,9 +134,7 @@ void DependencyEditor::_fix_all() {
Map<String, String> remaps;
for (Map<String, Map<String, String>>::Element *E = candidates.front(); E; E = E->next()) {
-
for (Map<String, String>::Element *F = E->get().front(); F; F = F->next()) {
-
if (F->get() != String()) {
remaps[F->key()] = F->get();
}
@@ -151,7 +142,6 @@ void DependencyEditor::_fix_all() {
}
if (remaps.size()) {
-
ResourceLoader::rename_dependencies(editing, remaps);
_update_list();
@@ -160,12 +150,10 @@ void DependencyEditor::_fix_all() {
}
void DependencyEditor::_update_file() {
-
EditorFileSystem::get_singleton()->update_file(editing);
}
void DependencyEditor::_update_list() {
-
List<String> deps;
ResourceLoader::get_dependencies(editing, &deps, true);
@@ -179,7 +167,6 @@ void DependencyEditor::_update_list() {
bool broken = false;
for (List<String>::Element *E = deps.front(); E; E = E->next()) {
-
TreeItem *item = tree->create_item(root);
String n = E->get();
@@ -214,7 +201,6 @@ void DependencyEditor::_update_list() {
}
void DependencyEditor::edit(const String &p_path) {
-
editing = p_path;
set_title(TTR("Dependencies For:") + " " + p_path.get_file());
@@ -232,7 +218,6 @@ void DependencyEditor::_bind_methods() {
}
DependencyEditor::DependencyEditor() {
-
VBoxContainer *vb = memnew(VBoxContainer);
vb->set_name(TTR("Dependencies"));
add_child(vb);
@@ -271,7 +256,6 @@ DependencyEditor::DependencyEditor() {
/////////////////////////////////////
void DependencyEditorOwners::_list_rmb_select(int p_item, const Vector2 &p_pos) {
-
file_options->clear();
file_options->set_size(Size2(1, 1));
if (p_item >= 0) {
@@ -283,7 +267,6 @@ void DependencyEditorOwners::_list_rmb_select(int p_item, const Vector2 &p_pos)
}
void DependencyEditorOwners::_select_file(int p_idx) {
-
String fpath = owners->get_item_text(p_idx);
if (ResourceLoader::get_resource_type(fpath) == "PackedScene") {
@@ -294,12 +277,12 @@ void DependencyEditorOwners::_select_file(int p_idx) {
}
void DependencyEditorOwners::_file_option(int p_option) {
-
switch (p_option) {
case FILE_OPEN: {
int idx = owners->get_current();
- if (idx < 0 || idx >= owners->get_item_count())
+ if (idx < 0 || idx >= owners->get_item_count()) {
break;
+ }
_select_file(idx);
} break;
}
@@ -309,16 +292,15 @@ void DependencyEditorOwners::_bind_methods() {
}
void DependencyEditorOwners::_fill_owners(EditorFileSystemDirectory *efsd) {
-
- if (!efsd)
+ if (!efsd) {
return;
+ }
for (int i = 0; i < efsd->get_subdir_count(); i++) {
_fill_owners(efsd->get_subdir(i));
}
for (int i = 0; i < efsd->get_file_count(); i++) {
-
Vector<String> deps = efsd->get_file_deps(i);
bool found = false;
for (int j = 0; j < deps.size(); j++) {
@@ -327,8 +309,9 @@ void DependencyEditorOwners::_fill_owners(EditorFileSystemDirectory *efsd) {
break;
}
}
- if (!found)
+ if (!found) {
continue;
+ }
Ref<Texture2D> icon = EditorNode::get_singleton()->get_class_icon(efsd->get_file_type(i));
@@ -337,7 +320,6 @@ void DependencyEditorOwners::_fill_owners(EditorFileSystemDirectory *efsd) {
}
void DependencyEditorOwners::show(const String &p_path) {
-
editing = p_path;
owners->clear();
_fill_owners(EditorFileSystem::get_singleton()->get_filesystem());
@@ -347,7 +329,6 @@ void DependencyEditorOwners::show(const String &p_path) {
}
DependencyEditorOwners::DependencyEditorOwners(EditorNode *p_editor) {
-
editor = p_editor;
file_options = memnew(PopupMenu);
@@ -365,8 +346,9 @@ DependencyEditorOwners::DependencyEditorOwners(EditorNode *p_editor) {
///////////////////////
void DependencyRemoveDialog::_find_files_in_removed_folder(EditorFileSystemDirectory *efsd, const String &p_folder) {
- if (!efsd)
+ if (!efsd) {
return;
+ }
for (int i = 0; i < efsd->get_subdir_count(); ++i) {
_find_files_in_removed_folder(efsd->get_subdir(i), p_folder);
@@ -379,8 +361,9 @@ void DependencyRemoveDialog::_find_files_in_removed_folder(EditorFileSystemDirec
}
void DependencyRemoveDialog::_find_all_removed_dependencies(EditorFileSystemDirectory *efsd, Vector<RemovedDependency> &p_removed) {
- if (!efsd)
+ if (!efsd) {
return;
+ }
for (int i = 0; i < efsd->get_subdir_count(); i++) {
_find_all_removed_dependencies(efsd->get_subdir(i), p_removed);
@@ -390,8 +373,9 @@ void DependencyRemoveDialog::_find_all_removed_dependencies(EditorFileSystemDire
const String path = efsd->get_file_path(i);
//It doesn't matter if a file we are about to delete will have some of its dependencies removed too
- if (all_remove_files.has(path))
+ if (all_remove_files.has(path)) {
continue;
+ }
Vector<String> all_deps = efsd->get_file_deps(i);
for (int j = 0; j < all_deps.size(); ++j) {
@@ -479,7 +463,6 @@ void DependencyRemoveDialog::show(const Vector<String> &p_folders, const Vector<
}
void DependencyRemoveDialog::ok_pressed() {
-
for (int i = 0; i < files_to_delete.size(); ++i) {
if (ResourceCache::has(files_to_delete[i])) {
Resource *res = ResourceCache::get(files_to_delete[i]);
@@ -525,10 +508,10 @@ void DependencyRemoveDialog::ok_pressed() {
if (dirs_to_delete.size() == 0) {
// If we only deleted files we should only need to tell the file system about the files we touched.
- for (int i = 0; i < files_to_delete.size(); ++i)
+ for (int i = 0; i < files_to_delete.size(); ++i) {
EditorFileSystem::get_singleton()->update_file(files_to_delete[i]);
+ }
} else {
-
for (int i = 0; i < dirs_to_delete.size(); ++i) {
String path = OS::get_singleton()->get_resource_dir() + dirs_to_delete[i].replace_first("res://", "/");
print_verbose("Moving to trash: " + path);
@@ -549,11 +532,13 @@ void DependencyRemoveDialog::ok_pressed() {
for (int i = 0; i < previous_favorites.size(); ++i) {
if (previous_favorites[i].ends_with("/")) {
- if (dirs_to_delete.find(previous_favorites[i]) < 0)
+ if (dirs_to_delete.find(previous_favorites[i]) < 0) {
new_favorites.push_back(previous_favorites[i]);
+ }
} else {
- if (files_to_delete.find(previous_favorites[i]) < 0)
+ if (files_to_delete.find(previous_favorites[i]) < 0) {
new_favorites.push_back(previous_favorites[i]);
+ }
}
}
@@ -568,7 +553,6 @@ void DependencyRemoveDialog::_bind_methods() {
}
DependencyRemoveDialog::DependencyRemoveDialog() {
-
get_ok()->set_text(TTR("Remove"));
VBoxContainer *vb = memnew(VBoxContainer);
@@ -586,7 +570,6 @@ DependencyRemoveDialog::DependencyRemoveDialog() {
//////////////
void DependencyErrorDialog::show(Mode p_mode, const String &p_for_file, const Vector<String> &report) {
-
mode = p_mode;
for_file = p_for_file;
set_title(TTR("Error loading:") + " " + p_for_file.get_file());
@@ -594,12 +577,12 @@ void DependencyErrorDialog::show(Mode p_mode, const String &p_for_file, const Ve
TreeItem *root = files->create_item(nullptr);
for (int i = 0; i < report.size(); i++) {
-
String dep;
String type = "Object";
dep = report[i].get_slice("::", 0);
- if (report[i].get_slice_count("::") > 0)
+ if (report[i].get_slice_count("::") > 0) {
type = report[i].get_slice("::", 1);
+ }
Ref<Texture2D> icon = EditorNode::get_singleton()->get_class_icon(type);
@@ -612,7 +595,6 @@ void DependencyErrorDialog::show(Mode p_mode, const String &p_for_file, const Ve
}
void DependencyErrorDialog::ok_pressed() {
-
switch (mode) {
case MODE_SCENE:
EditorNode::get_singleton()->load_scene(for_file, true);
@@ -624,12 +606,10 @@ void DependencyErrorDialog::ok_pressed() {
}
void DependencyErrorDialog::custom_action(const String &) {
-
EditorNode::get_singleton()->fix_dependencies(for_file);
}
DependencyErrorDialog::DependencyErrorDialog() {
-
VBoxContainer *vb = memnew(VBoxContainer);
add_child(vb);
@@ -654,26 +634,25 @@ DependencyErrorDialog::DependencyErrorDialog() {
//////////////////////////////////////////////////////////////////////
void OrphanResourcesDialog::ok_pressed() {
-
paths.clear();
_find_to_delete(files->get_root(), paths);
- if (paths.empty())
+ if (paths.empty()) {
return;
+ }
delete_confirm->set_text(vformat(TTR("Permanently delete %d item(s)? (No undo!)"), paths.size()));
delete_confirm->popup_centered();
}
bool OrphanResourcesDialog::_fill_owners(EditorFileSystemDirectory *efsd, HashMap<String, int> &refs, TreeItem *p_parent) {
-
- if (!efsd)
+ if (!efsd) {
return false;
+ }
bool has_children = false;
for (int i = 0; i < efsd->get_subdir_count(); i++) {
-
TreeItem *dir_item = nullptr;
if (p_parent) {
dir_item = files->create_item(p_parent);
@@ -692,17 +671,14 @@ bool OrphanResourcesDialog::_fill_owners(EditorFileSystemDirectory *efsd, HashMa
}
for (int i = 0; i < efsd->get_file_count(); i++) {
-
if (!p_parent) {
Vector<String> deps = efsd->get_file_deps(i);
for (int j = 0; j < deps.size(); j++) {
-
if (!refs.has(deps[j])) {
refs[deps[j]] = 1;
}
}
} else {
-
String path = efsd->get_file_path(i);
if (!refs.has(path)) {
TreeItem *ti = files->create_item(p_parent);
@@ -737,15 +713,12 @@ void OrphanResourcesDialog::refresh() {
}
void OrphanResourcesDialog::show() {
-
refresh();
popup_centered_ratio();
}
void OrphanResourcesDialog::_find_to_delete(TreeItem *p_item, List<String> &paths) {
-
while (p_item) {
-
if (p_item->get_cell_mode(0) == TreeItem::CELL_MODE_CHECK && p_item->is_checked(0)) {
paths.push_back(p_item->get_metadata(0));
}
@@ -759,10 +732,8 @@ void OrphanResourcesDialog::_find_to_delete(TreeItem *p_item, List<String> &path
}
void OrphanResourcesDialog::_delete_confirm() {
-
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
for (List<String>::Element *E = paths.front(); E; E = E->next()) {
-
da->remove(E->get());
EditorFileSystem::get_singleton()->update_file(E->get());
}
@@ -771,7 +742,6 @@ void OrphanResourcesDialog::_delete_confirm() {
}
void OrphanResourcesDialog::_button_pressed(Object *p_item, int p_column, int p_id) {
-
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
String path = ti->get_metadata(0);
@@ -782,7 +752,6 @@ void OrphanResourcesDialog::_bind_methods() {
}
OrphanResourcesDialog::OrphanResourcesDialog() {
-
set_title(TTR("Orphan Resource Explorer"));
delete_confirm = memnew(ConfirmationDialog);
get_ok()->set_text(TTR("Delete"));
diff --git a/editor/dictionary_property_edit.cpp b/editor/dictionary_property_edit.cpp
index 7169986b14..276cd12ded 100644
--- a/editor/dictionary_property_edit.cpp
+++ b/editor/dictionary_property_edit.cpp
@@ -40,34 +40,33 @@ void DictionaryPropertyEdit::_notif_changev(const String &p_v) {
}
void DictionaryPropertyEdit::_set_key(const Variant &p_old_key, const Variant &p_new_key) {
-
// TODO: Set key of a dictionary is not allowed yet
}
void DictionaryPropertyEdit::_set_value(const Variant &p_key, const Variant &p_value) {
-
Dictionary dict = get_dictionary();
dict[p_key] = p_value;
Object *o = ObjectDB::get_instance(obj);
- if (!o)
+ if (!o) {
return;
+ }
o->set(property, dict);
}
Variant DictionaryPropertyEdit::get_dictionary() const {
-
Object *o = ObjectDB::get_instance(obj);
- if (!o)
+ if (!o) {
return Dictionary();
+ }
Variant dict = o->get(property);
- if (dict.get_type() != Variant::DICTIONARY)
+ if (dict.get_type() != Variant::DICTIONARY) {
return Dictionary();
+ }
return dict;
}
void DictionaryPropertyEdit::_get_property_list(List<PropertyInfo> *p_list) const {
-
Dictionary dict = get_dictionary();
Array keys = dict.keys();
@@ -87,16 +86,15 @@ void DictionaryPropertyEdit::_get_property_list(List<PropertyInfo> *p_list) cons
}
void DictionaryPropertyEdit::edit(Object *p_obj, const StringName &p_prop) {
-
property = p_prop;
obj = p_obj->get_instance_id();
}
Node *DictionaryPropertyEdit::get_node() {
-
Object *o = ObjectDB::get_instance(obj);
- if (!o)
+ if (!o) {
return nullptr;
+ }
return cast_to<Node>(o);
}
@@ -106,7 +104,6 @@ bool DictionaryPropertyEdit::_dont_undo_redo() {
}
void DictionaryPropertyEdit::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_set_key"), &DictionaryPropertyEdit::_set_key);
ClassDB::bind_method(D_METHOD("_set_value"), &DictionaryPropertyEdit::_set_value);
ClassDB::bind_method(D_METHOD("_notif_change"), &DictionaryPropertyEdit::_notif_change);
@@ -115,7 +112,6 @@ void DictionaryPropertyEdit::_bind_methods() {
}
bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_value) {
-
Dictionary dict = get_dictionary();
Array keys = dict.keys();
keys.sort();
@@ -126,7 +122,6 @@ bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_val
String type = pn.substr(slash + 2, pn.length());
int index = pn.substr(0, slash).to_int();
if (type == "key" && index < keys.size()) {
-
const Variant &key = keys[index];
UndoRedo *ur = EditorNode::get_undo_redo();
@@ -141,7 +136,6 @@ bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_val
} else if (type == "value" && index < keys.size()) {
const Variant &key = keys[index];
if (dict.has(key)) {
-
Variant value = dict[key];
UndoRedo *ur = EditorNode::get_undo_redo();
@@ -161,7 +155,6 @@ bool DictionaryPropertyEdit::_set(const StringName &p_name, const Variant &p_val
}
bool DictionaryPropertyEdit::_get(const StringName &p_name, Variant &r_ret) const {
-
Dictionary dict = get_dictionary();
Array keys = dict.keys();
keys.sort();
@@ -170,7 +163,6 @@ bool DictionaryPropertyEdit::_get(const StringName &p_name, Variant &r_ret) cons
int slash = pn.find(": ");
if (slash != -1 && pn.length() > slash) {
-
String type = pn.substr(slash + 2, pn.length());
int index = pn.substr(0, slash).to_int();
diff --git a/editor/doc_data.cpp b/editor/doc_data.cpp
index 096be1fe4b..53641da0e9 100644
--- a/editor/doc_data.cpp
+++ b/editor/doc_data.cpp
@@ -40,14 +40,16 @@
#include "core/version.h"
#include "scene/resources/theme.h"
-void DocData::merge_from(const DocData &p_data) {
+// Used for a hack preserving Mono properties on non-Mono builds.
+#include "modules/modules_enabled.gen.h"
+void DocData::merge_from(const DocData &p_data) {
for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) {
-
ClassDoc &c = E->get();
- if (!p_data.class_list.has(c.name))
+ if (!p_data.class_list.has(c.name)) {
continue;
+ }
const ClassDoc &cf = p_data.class_list[c.name];
@@ -56,37 +58,42 @@ void DocData::merge_from(const DocData &p_data) {
c.tutorials = cf.tutorials;
for (int i = 0; i < c.methods.size(); i++) {
-
MethodDoc &m = c.methods.write[i];
for (int j = 0; j < cf.methods.size(); j++) {
-
- if (cf.methods[j].name != m.name)
+ if (cf.methods[j].name != m.name) {
continue;
- if (cf.methods[j].arguments.size() != m.arguments.size())
+ }
+ if (cf.methods[j].arguments.size() != m.arguments.size()) {
continue;
+ }
// since polymorphic functions are allowed we need to check the type of
// the arguments so we make sure they are different.
int arg_count = cf.methods[j].arguments.size();
Vector<bool> arg_used;
arg_used.resize(arg_count);
- for (int l = 0; l < arg_count; ++l)
+ for (int l = 0; l < arg_count; ++l) {
arg_used.write[l] = false;
+ }
// also there is no guarantee that argument ordering will match, so we
// have to check one by one so we make sure we have an exact match
for (int k = 0; k < arg_count; ++k) {
- for (int l = 0; l < arg_count; ++l)
+ for (int l = 0; l < arg_count; ++l) {
if (cf.methods[j].arguments[k].type == m.arguments[l].type && !arg_used[l]) {
arg_used.write[l] = true;
break;
}
+ }
}
bool not_the_same = false;
- for (int l = 0; l < arg_count; ++l)
- if (!arg_used[l]) // at least one of the arguments was different
+ for (int l = 0; l < arg_count; ++l) {
+ if (!arg_used[l]) { // at least one of the arguments was different
not_the_same = true;
- if (not_the_same)
+ }
+ }
+ if (not_the_same) {
continue;
+ }
const MethodDoc &mf = cf.methods[j];
@@ -96,13 +103,12 @@ void DocData::merge_from(const DocData &p_data) {
}
for (int i = 0; i < c.signals.size(); i++) {
-
MethodDoc &m = c.signals.write[i];
for (int j = 0; j < cf.signals.size(); j++) {
-
- if (cf.signals[j].name != m.name)
+ if (cf.signals[j].name != m.name) {
continue;
+ }
const MethodDoc &mf = cf.signals[j];
m.description = mf.description;
@@ -111,13 +117,12 @@ void DocData::merge_from(const DocData &p_data) {
}
for (int i = 0; i < c.constants.size(); i++) {
-
ConstantDoc &m = c.constants.write[i];
for (int j = 0; j < cf.constants.size(); j++) {
-
- if (cf.constants[j].name != m.name)
+ if (cf.constants[j].name != m.name) {
continue;
+ }
const ConstantDoc &mf = cf.constants[j];
m.description = mf.description;
@@ -126,13 +131,12 @@ void DocData::merge_from(const DocData &p_data) {
}
for (int i = 0; i < c.properties.size(); i++) {
-
PropertyDoc &p = c.properties.write[i];
for (int j = 0; j < cf.properties.size(); j++) {
-
- if (cf.properties[j].name != p.name)
+ if (cf.properties[j].name != p.name) {
continue;
+ }
const PropertyDoc &pf = cf.properties[j];
p.description = pf.description;
@@ -141,38 +145,57 @@ void DocData::merge_from(const DocData &p_data) {
}
for (int i = 0; i < c.theme_properties.size(); i++) {
-
PropertyDoc &p = c.theme_properties.write[i];
for (int j = 0; j < cf.theme_properties.size(); j++) {
-
- if (cf.theme_properties[j].name != p.name)
+ if (cf.theme_properties[j].name != p.name) {
continue;
+ }
const PropertyDoc &pf = cf.theme_properties[j];
p.description = pf.description;
break;
}
}
+
+#ifndef MODULE_MONO_ENABLED
+ // The Mono module defines some properties that we want to keep when
+ // re-generating docs with a non-Mono build, to prevent pointless diffs
+ // (and loss of descriptions) depending on the config of the doc writer.
+ // We use a horrible hack to force keeping the relevant properties,
+ // hardcoded below. At least it's an ad hoc hack... ¯\_(ツ)_/¯
+ // Don't show this to your kids.
+ if (c.name == "@GlobalScope") {
+ // Retrieve GodotSharp singleton.
+ for (int j = 0; j < cf.properties.size(); j++) {
+ if (cf.properties[j].name == "GodotSharp") {
+ c.properties.push_back(cf.properties[j]);
+ }
+ }
+ }
+#endif
}
}
void DocData::remove_from(const DocData &p_data) {
for (Map<String, ClassDoc>::Element *E = p_data.class_list.front(); E; E = E->next()) {
- if (class_list.has(E->key()))
+ if (class_list.has(E->key())) {
class_list.erase(E->key());
+ }
}
}
static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo) {
-
if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
p_method.return_enum = p_retinfo.class_name;
- if (p_method.return_enum.begins_with("_")) //proxy class
+ 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_type = "int";
} else if (p_retinfo.class_name != StringName()) {
p_method.return_type = p_retinfo.class_name;
+ } else if (p_retinfo.type == Variant::ARRAY && p_retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) {
+ p_method.return_type = p_retinfo.hint_string + "[]";
} else if (p_retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
p_method.return_type = p_retinfo.hint_string;
} else if (p_retinfo.type == Variant::NIL && p_retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
@@ -185,16 +208,18 @@ static void return_doc_from_retinfo(DocData::MethodDoc &p_method, const Property
}
static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo) {
-
p_argument.name = p_arginfo.name;
if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
p_argument.enumeration = p_arginfo.class_name;
- if (p_argument.enumeration.begins_with("_")) //proxy class
+ if (p_argument.enumeration.begins_with("_")) { //proxy class
p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length());
+ }
p_argument.type = "int";
} else if (p_arginfo.class_name != StringName()) {
p_argument.type = p_arginfo.class_name;
+ } else if (p_arginfo.type == Variant::ARRAY && p_arginfo.hint == PROPERTY_HINT_ARRAY_TYPE) {
+ p_argument.type = p_arginfo.hint_string + "[]";
} else if (p_arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
p_argument.type = p_arginfo.hint_string;
} else if (p_arginfo.type == Variant::NIL) {
@@ -206,7 +231,6 @@ static void argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const Pr
}
static Variant get_documentation_default_value(const StringName &p_class_name, const StringName &p_property_name, bool &r_default_value_valid) {
-
Variant default_value = Variant();
r_default_value_valid = false;
@@ -219,8 +243,9 @@ static Variant get_documentation_default_value(const StringName &p_class_name, c
for (List<StringName>::Element *E2 = inheriting_classes.front(); E2; E2 = E2->next()) {
if (ClassDB::can_instance(E2->get())) {
default_value = ClassDB::class_get_default_property_value(E2->get(), p_property_name, &r_default_value_valid);
- if (r_default_value_valid)
+ if (r_default_value_valid) {
break;
+ }
}
}
}
@@ -229,7 +254,6 @@ static Variant get_documentation_default_value(const StringName &p_class_name, c
}
void DocData::generate(bool p_basic_types) {
-
List<StringName> classes;
ClassDB::get_class_list(&classes);
classes.sort_custom<StringName::AlphCompare>();
@@ -239,13 +263,19 @@ void DocData::generate(bool p_basic_types) {
bool skip_setter_getter_methods = true;
while (classes.size()) {
-
Set<StringName> setters_getters;
String name = classes.front()->get();
+ if (!ClassDB::is_class_exposed(name)) {
+ print_verbose(vformat("Class '%s' is not exposed, skipping.", name));
+ classes.pop_front();
+ continue;
+ }
+
String cname = name;
- if (cname.begins_with("_")) //proxy class
+ if (cname.begins_with("_")) { //proxy class
cname = cname.substr(1, name.length());
+ }
class_list[cname] = ClassDoc();
ClassDoc &c = class_list[cname];
@@ -271,8 +301,9 @@ void DocData::generate(bool p_basic_types) {
EO = EO->next();
}
- if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL)
+ if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL) {
continue;
+ }
PropertyDoc prop;
@@ -299,8 +330,9 @@ void DocData::generate(bool p_basic_types) {
if (inherited) {
bool base_default_value_valid = false;
Variant base_default_value = get_documentation_default_value(ClassDB::get_parent_class(name), E->get().name, base_default_value_valid);
- if (!default_value_valid || !base_default_value_valid || default_value == base_default_value)
+ if (!default_value_valid || !base_default_value_valid || default_value == base_default_value) {
continue;
+ }
}
}
@@ -328,11 +360,11 @@ void DocData::generate(bool p_basic_types) {
prop.type = "int";
} else if (retinfo.class_name != StringName()) {
prop.type = retinfo.class_name;
+ } else if (retinfo.type == Variant::ARRAY && retinfo.hint == PROPERTY_HINT_ARRAY_TYPE) {
+ prop.type = retinfo.hint_string + "[]";
} else if (retinfo.hint == PROPERTY_HINT_RESOURCE_TYPE) {
-
prop.type = retinfo.hint_string;
} else if (retinfo.type == Variant::NIL && retinfo.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
-
prop.type = "Variant";
} else if (retinfo.type == Variant::NIL) {
prop.type = "void";
@@ -345,16 +377,15 @@ void DocData::generate(bool p_basic_types) {
}
if (setter != StringName()) {
-
setters_getters.insert(setter);
}
if (!found_type) {
-
- if (E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE)
+ if (E->get().type == Variant::OBJECT && E->get().hint == PROPERTY_HINT_RESOURCE_TYPE) {
prop.type = E->get().hint_string;
- else
+ } else {
prop.type = Variant::get_type_name(E->get().type);
+ }
}
c.properties.push_back(prop);
@@ -365,9 +396,9 @@ void DocData::generate(bool p_basic_types) {
method_list.sort();
for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) {
-
- if (E->get().name == "" || (E->get().name[0] == '_' && !(E->get().flags & METHOD_FLAG_VIRTUAL)))
+ if (E->get().name == "" || (E->get().name[0] == '_' && !(E->get().flags & METHOD_FLAG_VIRTUAL))) {
continue; //hidden, don't count
+ }
if (skip_setter_getter_methods && setters_getters.has(E->get().name)) {
// Don't skip parametric setters and getters, i.e. method which require
@@ -382,27 +413,28 @@ void DocData::generate(bool p_basic_types) {
method.name = E->get().name;
- if (E->get().flags & METHOD_FLAG_VIRTUAL)
+ if (E->get().flags & METHOD_FLAG_VIRTUAL) {
method.qualifiers = "virtual";
+ }
if (E->get().flags & METHOD_FLAG_CONST) {
- if (method.qualifiers != "")
+ if (method.qualifiers != "") {
method.qualifiers += " ";
+ }
method.qualifiers += "const";
} else if (E->get().flags & METHOD_FLAG_VARARG) {
- if (method.qualifiers != "")
+ if (method.qualifiers != "") {
method.qualifiers += " ";
+ }
method.qualifiers += "vararg";
}
for (int i = -1; i < E->get().arguments.size(); i++) {
-
if (i == -1) {
#ifdef DEBUG_METHODS_ENABLED
return_doc_from_retinfo(method, E->get().return_val);
#endif
} else {
-
const PropertyInfo &arginfo = E->get().arguments[i];
ArgumentDoc argument;
argument_doc_from_arginfo(argument, arginfo);
@@ -424,13 +456,10 @@ void DocData::generate(bool p_basic_types) {
ClassDB::get_signal_list(name, &signal_list, true);
if (signal_list.size()) {
-
for (List<MethodInfo>::Element *EV = signal_list.front(); EV; EV = EV->next()) {
-
MethodDoc signal;
signal.name = EV->get().name;
for (int i = 0; i < EV->get().arguments.size(); i++) {
-
const PropertyInfo &arginfo = EV->get().arguments[i];
ArgumentDoc argument;
argument_doc_from_arginfo(argument, arginfo);
@@ -446,7 +475,6 @@ void DocData::generate(bool p_basic_types) {
ClassDB::get_integer_constant_list(name, &constant_list, true);
for (List<String>::Element *E = constant_list.front(); E; E = E->next()) {
-
ConstantDoc constant;
constant.name = E->get();
constant.value = itos(ClassDB::get_integer_constant(name, E->get()));
@@ -460,7 +488,6 @@ void DocData::generate(bool p_basic_types) {
List<StringName> l;
Theme::get_default()->get_constant_list(cname, &l);
for (List<StringName>::Element *E = l.front(); E; E = E->next()) {
-
PropertyDoc pd;
pd.name = E->get();
pd.type = "int";
@@ -471,7 +498,6 @@ void DocData::generate(bool p_basic_types) {
l.clear();
Theme::get_default()->get_color_list(cname, &l);
for (List<StringName>::Element *E = l.front(); E; E = E->next()) {
-
PropertyDoc pd;
pd.name = E->get();
pd.type = "Color";
@@ -482,7 +508,6 @@ void DocData::generate(bool p_basic_types) {
l.clear();
Theme::get_default()->get_icon_list(cname, &l);
for (List<StringName>::Element *E = l.front(); E; E = E->next()) {
-
PropertyDoc pd;
pd.name = E->get();
pd.type = "Texture2D";
@@ -491,7 +516,6 @@ void DocData::generate(bool p_basic_types) {
l.clear();
Theme::get_default()->get_font_list(cname, &l);
for (List<StringName>::Element *E = l.front(); E; E = E->next()) {
-
PropertyDoc pd;
pd.name = E->get();
pd.type = "Font";
@@ -500,7 +524,6 @@ void DocData::generate(bool p_basic_types) {
l.clear();
Theme::get_default()->get_stylebox_list(cname, &l);
for (List<StringName>::Element *E = l.front(); E; E = E->next()) {
-
PropertyDoc pd;
pd.name = E->get();
pd.type = "StyleBox";
@@ -517,15 +540,18 @@ void DocData::generate(bool p_basic_types) {
class_list["Variant"].name = "Variant";
}
- if (!p_basic_types)
+ if (!p_basic_types) {
return;
+ }
// Add Variant types.
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
- if (i == Variant::NIL)
+ if (i == Variant::NIL) {
continue; // Not exposed outside of 'null', should not be in class list.
- if (i == Variant::OBJECT)
+ }
+ if (i == Variant::OBJECT) {
continue; // Use the core type instead.
+ }
String cname = Variant::get_type_name(Variant::Type(i));
@@ -542,14 +568,12 @@ void DocData::generate(bool p_basic_types) {
Variant::get_constructor_list(Variant::Type(i), &method_list);
for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) {
-
MethodInfo &mi = E->get();
MethodDoc method;
method.name = mi.name;
for (int j = 0; j < mi.arguments.size(); j++) {
-
PropertyInfo arginfo = mi.arguments[j];
ArgumentDoc ad;
argument_doc_from_arginfo(ad, mi.arguments[j]);
@@ -567,8 +591,9 @@ void DocData::generate(bool p_basic_types) {
return_doc_from_retinfo(method, mi.return_val);
if (mi.flags & METHOD_FLAG_VARARG) {
- if (method.qualifiers != "")
+ if (method.qualifiers != "") {
method.qualifiers += " ";
+ }
method.qualifiers += "vararg";
}
@@ -578,7 +603,6 @@ void DocData::generate(bool p_basic_types) {
List<PropertyInfo> properties;
v.get_property_list(&properties);
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
-
PropertyInfo pi = E->get();
PropertyDoc property;
property.name = pi.name;
@@ -592,7 +616,6 @@ void DocData::generate(bool p_basic_types) {
Variant::get_constants_for_type(Variant::Type(i), &constants);
for (List<StringName>::Element *E = constants.front(); E; E = E->next()) {
-
ConstantDoc constant;
constant.name = E->get();
Variant value = Variant::get_constant_value(Variant::Type(i), E->get());
@@ -604,14 +627,12 @@ void DocData::generate(bool p_basic_types) {
//built in constants and functions
{
-
String cname = "@GlobalScope";
class_list[cname] = ClassDoc();
ClassDoc &c = class_list[cname];
c.name = cname;
for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) {
-
ConstantDoc cd;
cd.name = GlobalConstants::get_global_constant_name(i);
cd.value = itos(GlobalConstants::get_global_constant_value(i));
@@ -624,7 +645,6 @@ void DocData::generate(bool p_basic_types) {
//servers (this is kind of hackish)
for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
-
PropertyDoc pd;
Engine::Singleton &s = E->get();
if (!s.ptr) {
@@ -632,10 +652,12 @@ void DocData::generate(bool p_basic_types) {
}
pd.name = s.name;
pd.type = s.ptr->get_class();
- while (String(ClassDB::get_parent_class(pd.type)) != "Object")
+ while (String(ClassDB::get_parent_class(pd.type)) != "Object") {
pd.type = ClassDB::get_parent_class(pd.type);
- if (pd.type.begins_with("_"))
+ }
+ if (pd.type.begins_with("_")) {
pd.type = pd.type.substr(1, pd.type.length());
+ }
c.properties.push_back(pd);
}
}
@@ -643,9 +665,7 @@ void DocData::generate(bool p_basic_types) {
//built in script reference
{
-
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
-
ScriptLanguage *lang = ScriptServer::get_language(i);
String cname = "@" + lang->get_name();
class_list[cname] = ClassDoc();
@@ -657,21 +677,20 @@ void DocData::generate(bool p_basic_types) {
lang->get_public_functions(&minfo);
for (List<MethodInfo>::Element *E = minfo.front(); E; E = E->next()) {
-
MethodInfo &mi = E->get();
MethodDoc md;
md.name = mi.name;
if (mi.flags & METHOD_FLAG_VARARG) {
- if (md.qualifiers != "")
+ if (md.qualifiers != "") {
md.qualifiers += " ";
+ }
md.qualifiers += "vararg";
}
return_doc_from_retinfo(md, mi.return_val);
for (int j = 0; j < mi.arguments.size(); j++) {
-
ArgumentDoc ad;
argument_doc_from_arginfo(ad, mi.arguments[j]);
@@ -691,7 +710,6 @@ void DocData::generate(bool p_basic_types) {
lang->get_public_constants(&cinfo);
for (List<Pair<String, Variant>>::Element *E = cinfo.front(); E; E = E->next()) {
-
ConstantDoc cd;
cd.name = E->get().first;
cd.value = E->get().second;
@@ -702,36 +720,29 @@ void DocData::generate(bool p_basic_types) {
}
static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &methods) {
-
String section = parser->get_node_name();
String element = section.substr(0, section.length() - 1);
while (parser->read() == OK) {
-
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser->get_node_name() == element) {
-
DocData::MethodDoc method;
ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT);
method.name = parser->get_attribute_value("name");
- if (parser->has_attribute("qualifiers"))
+ if (parser->has_attribute("qualifiers")) {
method.qualifiers = parser->get_attribute_value("qualifiers");
+ }
while (parser->read() == OK) {
-
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name = parser->get_node_name();
if (name == "return") {
-
ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT);
method.return_type = parser->get_attribute_value("type");
if (parser->has_attribute("enum")) {
method.return_enum = parser->get_attribute_value("enum");
}
} else if (name == "argument") {
-
DocData::ArgumentDoc argument;
ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT);
argument.name = parser->get_attribute_value("name");
@@ -744,14 +755,15 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &
method.arguments.push_back(argument);
} else if (name == "description") {
-
parser->read();
- if (parser->get_node_type() == XMLParser::NODE_TEXT)
+ if (parser->get_node_type() == XMLParser::NODE_TEXT) {
method.description = parser->get_node_data();
+ }
}
- } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == element)
+ } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == element) {
break;
+ }
}
methods.push_back(method);
@@ -760,15 +772,15 @@ static Error _parse_methods(Ref<XMLParser> &parser, Vector<DocData::MethodDoc> &
ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + parser->get_node_name() + ".");
}
- } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == section)
+ } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == section) {
break;
+ }
}
return OK;
}
Error DocData::load_classes(const String &p_dir) {
-
Error err;
DirAccessRef da = DirAccess::open(p_dir, &err);
if (!da) {
@@ -782,8 +794,9 @@ Error DocData::load_classes(const String &p_dir) {
if (!da->current_is_dir() && path.ends_with("xml")) {
Ref<XMLParser> parser = memnew(XMLParser);
Error err2 = parser->open(p_dir.plus_file(path));
- if (err2)
+ if (err2) {
return err2;
+ }
_load(parser);
}
@@ -794,8 +807,8 @@ Error DocData::load_classes(const String &p_dir) {
return OK;
}
-Error DocData::erase_classes(const String &p_dir) {
+Error DocData::erase_classes(const String &p_dir) {
Error err;
DirAccessRef da = DirAccess::open(p_dir, &err);
if (!da) {
@@ -822,18 +835,18 @@ Error DocData::erase_classes(const String &p_dir) {
return OK;
}
-Error DocData::_load(Ref<XMLParser> parser) {
+Error DocData::_load(Ref<XMLParser> parser) {
Error err = OK;
while ((err = parser->read()) == OK) {
-
if (parser->get_node_type() == XMLParser::NODE_ELEMENT && parser->get_node_name() == "?xml") {
parser->skip_section();
}
- if (parser->get_node_type() != XMLParser::NODE_ELEMENT)
+ if (parser->get_node_type() != XMLParser::NODE_ELEMENT) {
continue; //no idea what this may be, but skipping anyway
+ }
ERR_FAIL_COND_V(parser->get_node_name() != "class", ERR_FILE_CORRUPT);
@@ -843,98 +856,92 @@ Error DocData::_load(Ref<XMLParser> parser) {
ClassDoc &c = class_list[name];
c.name = name;
- if (parser->has_attribute("inherits"))
+ if (parser->has_attribute("inherits")) {
c.inherits = parser->get_attribute_value("inherits");
+ }
while (parser->read() == OK) {
-
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name2 = parser->get_node_name();
if (name2 == "brief_description") {
-
parser->read();
- if (parser->get_node_type() == XMLParser::NODE_TEXT)
+ if (parser->get_node_type() == XMLParser::NODE_TEXT) {
c.brief_description = parser->get_node_data();
+ }
} else if (name2 == "description") {
parser->read();
- if (parser->get_node_type() == XMLParser::NODE_TEXT)
+ if (parser->get_node_type() == XMLParser::NODE_TEXT) {
c.description = parser->get_node_data();
+ }
} else if (name2 == "tutorials") {
while (parser->read() == OK) {
-
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name3 = parser->get_node_name();
if (name3 == "link") {
-
parser->read();
- if (parser->get_node_type() == XMLParser::NODE_TEXT)
+ if (parser->get_node_type() == XMLParser::NODE_TEXT) {
c.tutorials.push_back(parser->get_node_data().strip_edges());
+ }
} else {
ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + ".");
}
- } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "tutorials")
+ } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "tutorials") {
break; // End of <tutorials>.
+ }
}
} else if (name2 == "methods") {
-
Error err2 = _parse_methods(parser, c.methods);
ERR_FAIL_COND_V(err2, err2);
} else if (name2 == "signals") {
-
Error err2 = _parse_methods(parser, c.signals);
ERR_FAIL_COND_V(err2, err2);
} else if (name2 == "members") {
-
while (parser->read() == OK) {
-
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name3 = parser->get_node_name();
if (name3 == "member") {
-
PropertyDoc prop2;
ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT);
prop2.name = parser->get_attribute_value("name");
ERR_FAIL_COND_V(!parser->has_attribute("type"), ERR_FILE_CORRUPT);
prop2.type = parser->get_attribute_value("type");
- if (parser->has_attribute("setter"))
+ if (parser->has_attribute("setter")) {
prop2.setter = parser->get_attribute_value("setter");
- if (parser->has_attribute("getter"))
+ }
+ if (parser->has_attribute("getter")) {
prop2.getter = parser->get_attribute_value("getter");
- if (parser->has_attribute("enum"))
+ }
+ if (parser->has_attribute("enum")) {
prop2.enumeration = parser->get_attribute_value("enum");
+ }
if (!parser->is_empty()) {
parser->read();
- if (parser->get_node_type() == XMLParser::NODE_TEXT)
+ if (parser->get_node_type() == XMLParser::NODE_TEXT) {
prop2.description = parser->get_node_data();
+ }
}
c.properties.push_back(prop2);
} else {
ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + ".");
}
- } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "members")
+ } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "members") {
break; // End of <members>.
+ }
}
} else if (name2 == "theme_items") {
-
while (parser->read() == OK) {
-
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name3 = parser->get_node_name();
if (name3 == "theme_item") {
-
PropertyDoc prop2;
ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT);
@@ -943,28 +950,26 @@ Error DocData::_load(Ref<XMLParser> parser) {
prop2.type = parser->get_attribute_value("type");
if (!parser->is_empty()) {
parser->read();
- if (parser->get_node_type() == XMLParser::NODE_TEXT)
+ if (parser->get_node_type() == XMLParser::NODE_TEXT) {
prop2.description = parser->get_node_data();
+ }
}
c.theme_properties.push_back(prop2);
} else {
ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + ".");
}
- } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "theme_items")
+ } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "theme_items") {
break; // End of <theme_items>.
+ }
}
} else if (name2 == "constants") {
-
while (parser->read() == OK) {
-
if (parser->get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name3 = parser->get_node_name();
if (name3 == "constant") {
-
ConstantDoc constant2;
ERR_FAIL_COND_V(!parser->has_attribute("name"), ERR_FILE_CORRUPT);
constant2.name = parser->get_attribute_value("name");
@@ -975,25 +980,27 @@ Error DocData::_load(Ref<XMLParser> parser) {
}
if (!parser->is_empty()) {
parser->read();
- if (parser->get_node_type() == XMLParser::NODE_TEXT)
+ if (parser->get_node_type() == XMLParser::NODE_TEXT) {
constant2.description = parser->get_node_data();
+ }
}
c.constants.push_back(constant2);
} else {
ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name3 + ".");
}
- } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "constants")
+ } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "constants") {
break; // End of <constants>.
+ }
}
} else {
-
ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Invalid tag in doc file: " + name2 + ".");
}
- } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "class")
+ } else if (parser->get_node_type() == XMLParser::NODE_ELEMENT_END && parser->get_node_name() == "class") {
break; // End of <class>.
+ }
}
}
@@ -1001,19 +1008,18 @@ Error DocData::_load(Ref<XMLParser> parser) {
}
static void _write_string(FileAccess *f, int p_tablevel, const String &p_string) {
-
- if (p_string == "")
+ if (p_string == "") {
return;
+ }
String tab;
- for (int i = 0; i < p_tablevel; i++)
+ for (int i = 0; i < p_tablevel; i++) {
tab += "\t";
+ }
f->store_string(tab + p_string + "\n");
}
Error DocData::save_classes(const String &p_default_path, const Map<String, String> &p_class_path) {
-
for (Map<String, ClassDoc>::Element *E = class_list.front(); E; E = E->next()) {
-
ClassDoc &c = E->get();
String save_path;
@@ -1032,8 +1038,9 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
_write_string(f, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
String header = "<class name=\"" + c.name + "\"";
- if (c.inherits != "")
+ if (c.inherits != "") {
header += " inherits=\"" + c.inherits + "\"";
+ }
header += String(" version=\"") + VERSION_BRANCH + "\"";
header += ">";
_write_string(f, 0, header);
@@ -1057,17 +1064,16 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
c.methods.sort();
for (int i = 0; i < c.methods.size(); i++) {
-
const MethodDoc &m = c.methods[i];
String qualifiers;
- if (m.qualifiers != "")
+ if (m.qualifiers != "") {
qualifiers += " qualifiers=\"" + m.qualifiers.xml_escape() + "\"";
+ }
_write_string(f, 2, "<method name=\"" + m.name + "\"" + qualifiers + ">");
if (m.return_type != "") {
-
String enum_text;
if (m.return_enum != String()) {
enum_text = " enum=\"" + m.return_enum + "\"";
@@ -1077,7 +1083,6 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
}
for (int j = 0; j < m.arguments.size(); j++) {
-
const ArgumentDoc &a = m.arguments[j];
String enum_text;
@@ -1085,10 +1090,11 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
enum_text = " enum=\"" + a.enumeration + "\"";
}
- if (a.default_value != "")
+ if (a.default_value != "") {
_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\"" + enum_text + " default=\"" + a.default_value.xml_escape(true) + "\">");
- else
+ } else {
_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\"" + enum_text + ">");
+ }
_write_string(f, 3, "</argument>");
}
@@ -1108,7 +1114,6 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
c.properties.sort();
for (int i = 0; i < c.properties.size(); i++) {
-
String additional_attributes;
if (c.properties[i].enumeration != String()) {
additional_attributes += " enum=\"" + c.properties[i].enumeration + "\"";
@@ -1131,16 +1136,13 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
}
if (c.signals.size()) {
-
c.signals.sort();
_write_string(f, 1, "<signals>");
for (int i = 0; i < c.signals.size(); i++) {
-
const MethodDoc &m = c.signals[i];
_write_string(f, 2, "<signal name=\"" + m.name + "\">");
for (int j = 0; j < m.arguments.size(); j++) {
-
const ArgumentDoc &a = m.arguments[j];
_write_string(f, 3, "<argument index=\"" + itos(j) + "\" name=\"" + a.name.xml_escape() + "\" type=\"" + a.type.xml_escape() + "\">");
_write_string(f, 3, "</argument>");
@@ -1159,7 +1161,6 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
_write_string(f, 1, "<constants>");
for (int i = 0; i < c.constants.size(); i++) {
-
const ConstantDoc &k = c.constants[i];
if (k.enumeration != String()) {
_write_string(f, 2, "<constant name=\"" + k.name + "\" value=\"" + k.value + "\" enum=\"" + k.enumeration + "\">");
@@ -1173,18 +1174,17 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
_write_string(f, 1, "</constants>");
if (c.theme_properties.size()) {
-
c.theme_properties.sort();
_write_string(f, 1, "<theme_items>");
for (int i = 0; i < c.theme_properties.size(); i++) {
-
const PropertyDoc &p = c.theme_properties[i];
- if (p.default_value != "")
+ if (p.default_value != "") {
_write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\" default=\"" + p.default_value.xml_escape(true) + "\">");
- else
+ } else {
_write_string(f, 2, "<theme_item name=\"" + p.name + "\" type=\"" + p.type + "\">");
+ }
_write_string(f, 3, p.description.strip_edges().xml_escape());
@@ -1200,7 +1200,6 @@ Error DocData::save_classes(const String &p_default_path, const Map<String, Stri
}
Error DocData::load_compressed(const uint8_t *p_data, int p_compressed_size, int p_uncompressed_size) {
-
Vector<uint8_t> data;
data.resize(p_uncompressed_size);
Compression::decompress(data.ptrw(), p_uncompressed_size, p_data, p_compressed_size, Compression::MODE_DEFLATE);
@@ -1208,8 +1207,9 @@ Error DocData::load_compressed(const uint8_t *p_data, int p_compressed_size, int
Ref<XMLParser> parser = memnew(XMLParser);
Error err = parser->open_buffer(data);
- if (err)
+ if (err) {
return err;
+ }
_load(parser);
diff --git a/editor/doc_data.h b/editor/doc_data.h
index 073705f0b1..8c93bfa597 100644
--- a/editor/doc_data.h
+++ b/editor/doc_data.h
@@ -38,53 +38,51 @@
class DocData {
public:
struct ArgumentDoc {
-
String name;
String type;
String enumeration;
String default_value;
+ bool operator<(const ArgumentDoc &p_arg) const {
+ return name < p_arg.name;
+ }
};
struct MethodDoc {
-
String name;
String return_type;
String return_enum;
String qualifiers;
String description;
Vector<ArgumentDoc> arguments;
- bool operator<(const MethodDoc &p_md) const {
- return name < p_md.name;
+ bool operator<(const MethodDoc &p_method) const {
+ return name < p_method.name;
}
};
struct ConstantDoc {
-
String name;
String value;
String enumeration;
String description;
+ bool operator<(const ConstantDoc &p_const) const {
+ return name < p_const.name;
+ }
};
struct PropertyDoc {
-
String name;
String type;
String enumeration;
String description;
String setter, getter;
String default_value;
- bool overridden;
+ bool overridden = false;
bool operator<(const PropertyDoc &p_prop) const {
return name < p_prop.name;
}
- PropertyDoc() {
- overridden = false;
- }
};
struct ClassDoc {
-
String name;
String inherits;
String category;
@@ -96,6 +94,9 @@ public:
Vector<ConstantDoc> constants;
Vector<PropertyDoc> properties;
Vector<PropertyDoc> theme_properties;
+ bool operator<(const ClassDoc &p_class) const {
+ return name < p_class.name;
+ }
};
String version;
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index b0bcc2b448..d99726c57c 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -38,7 +38,6 @@
#include "core/version_hash.gen.h"
void EditorAbout::_theme_changed() {
-
Control *base = EditorNode::get_singleton()->get_gui_base();
Ref<Font> font = base->get_theme_font("source", "EditorFonts");
_tpl_text->add_theme_font_override("normal_font", font);
@@ -49,9 +48,7 @@ void EditorAbout::_theme_changed() {
}
void EditorAbout::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
_theme_changed();
} break;
@@ -59,7 +56,6 @@ void EditorAbout::_notification(int p_what) {
}
void EditorAbout::_license_tree_selected() {
-
TreeItem *selected = _tpl_tree->get_selected();
_tpl_text->scroll_to_line(0);
_tpl_text->set_text(selected->get_metadata(0));
@@ -69,12 +65,10 @@ void EditorAbout::_bind_methods() {
}
TextureRect *EditorAbout::get_logo() const {
-
return _logo;
}
ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<String> &p_sections, const char *const *const p_src[], const int p_flag_single_column) {
-
ScrollContainer *sc = memnew(ScrollContainer);
sc->set_name(p_name);
sc->set_v_size_flags(Control::SIZE_EXPAND);
@@ -84,11 +78,9 @@ ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<St
sc->add_child(vbc);
for (int i = 0; i < p_sections.size(); i++) {
-
bool single_column = p_flag_single_column & 1 << i;
const char *const *names_ptr = p_src[i];
if (*names_ptr) {
-
Label *lbl = memnew(Label);
lbl->set_text(p_sections[i]);
vbc->add_child(lbl);
@@ -115,7 +107,6 @@ ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<St
}
EditorAbout::EditorAbout() {
-
set_title(TTR("Thanks from the Godot community!"));
set_hide_on_ok(true);
@@ -132,8 +123,9 @@ EditorAbout::EditorAbout() {
hbc->add_child(_logo);
String hash = String(VERSION_HASH);
- if (hash.length() != 0)
+ if (hash.length() != 0) {
hash = "." + hash.left(9);
+ }
Label *about_text = memnew(Label);
about_text->set_v_size_flags(Control::SIZE_SHRINK_CENTER);
@@ -213,7 +205,6 @@ EditorAbout::EditorAbout() {
tpl_ti_lc->set_selectable(0, false);
String long_text = "";
for (int component_index = 0; component_index < COPYRIGHT_INFO_COUNT; component_index++) {
-
const ComponentCopyright &component = COPYRIGHT_INFO[component_index];
TreeItem *ti = _tpl_tree->create_item(tpl_ti_tp);
String component_name = component.name;
@@ -239,7 +230,6 @@ EditorAbout::EditorAbout() {
ti->set_metadata(0, text);
}
for (int i = 0; i < LICENSE_COUNT; i++) {
-
TreeItem *ti = _tpl_tree->create_item(tpl_ti_lc);
String licensename = String(LICENSE_NAMES[i]);
ti->set_text(0, licensename);
diff --git a/editor/editor_about.h b/editor/editor_about.h
index 83e9e9f490..ae4d9c73bf 100644
--- a/editor/editor_about.h
+++ b/editor/editor_about.h
@@ -45,7 +45,6 @@
#include "editor_scale.h"
class EditorAbout : public AcceptDialog {
-
GDCLASS(EditorAbout, AcceptDialog);
private:
diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp
index 74c4102003..b43ee0e245 100644
--- a/editor/editor_asset_installer.cpp
+++ b/editor/editor_asset_installer.cpp
@@ -37,7 +37,6 @@
#include "progress_dialog.h"
void EditorAssetInstaller::_update_subitems(TreeItem *p_item, bool p_check, bool p_first) {
-
if (p_check) {
if (p_item->get_custom_color(0) == Color()) {
p_item->set_checked(0, true);
@@ -56,13 +55,14 @@ void EditorAssetInstaller::_update_subitems(TreeItem *p_item, bool p_check, bool
}
void EditorAssetInstaller::_item_edited() {
-
- if (updating)
+ if (updating) {
return;
+ }
TreeItem *item = tree->get_edited();
- if (!item)
+ if (!item) {
return;
+ }
String path = item->get_metadata(0);
@@ -81,7 +81,6 @@ void EditorAssetInstaller::_item_edited() {
}
void EditorAssetInstaller::open(const String &p_path, int p_depth) {
-
package_path = p_path;
Set<String> files_sorted;
@@ -90,7 +89,6 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
unzFile pkg = unzOpen2(p_path.utf8().get_data(), &io);
if (!pkg) {
-
error->set_text(TTR("Error opening package file, not in ZIP format."));
return;
}
@@ -98,7 +96,6 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
int ret = unzGoToFirstFile(pkg);
while (ret == UNZ_OK) {
-
//get filename
unz_file_info info;
char fname[16384];
@@ -137,7 +134,6 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
Map<String, TreeItem *> dir_map;
for (Set<String>::Element *E = files_sorted.front(); E; E = E->next()) {
-
String path = E->get();
int depth = p_depth;
bool skip = false;
@@ -151,8 +147,9 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
depth--;
}
- if (skip || path == String())
+ if (skip || path == String()) {
continue;
+ }
bool isdir = false;
@@ -211,13 +208,11 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
}
void EditorAssetInstaller::ok_pressed() {
-
FileAccess *src_f = nullptr;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
unzFile pkg = unzOpen2(package_path.utf8().get_data(), &io);
if (!pkg) {
-
error->set_text(TTR("Error opening package file, not in ZIP format."));
return;
}
@@ -230,7 +225,6 @@ void EditorAssetInstaller::ok_pressed() {
int idx = 0;
while (ret == UNZ_OK) {
-
//get filename
unz_file_info info;
char fname[16384];
@@ -239,7 +233,6 @@ void EditorAssetInstaller::ok_pressed() {
String name = fname;
if (status_map.has(name) && status_map[name]->is_checked(0)) {
-
String path = status_map[name]->get_metadata(0);
if (path == String()) { // a dir
@@ -259,7 +252,6 @@ void EditorAssetInstaller::ok_pressed() {
memdelete(da);
} else {
-
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
@@ -290,18 +282,19 @@ void EditorAssetInstaller::ok_pressed() {
if (failed_files.size()) {
String msg = TTR("The following files failed extraction from package:") + "\n\n";
for (int i = 0; i < failed_files.size(); i++) {
-
if (i > 15) {
msg += "\n" + vformat(TTR("And %s more files."), itos(failed_files.size() - i));
break;
}
msg += failed_files[i];
}
- if (EditorNode::get_singleton() != nullptr)
+ if (EditorNode::get_singleton() != nullptr) {
EditorNode::get_singleton()->show_warning(msg);
+ }
} else {
- if (EditorNode::get_singleton() != nullptr)
+ if (EditorNode::get_singleton() != nullptr) {
EditorNode::get_singleton()->show_warning(TTR("Package installed successfully!"), TTR("Success!"));
+ }
}
EditorFileSystem::get_singleton()->scan_changes();
}
@@ -310,7 +303,6 @@ void EditorAssetInstaller::_bind_methods() {
}
EditorAssetInstaller::EditorAssetInstaller() {
-
VBoxContainer *vb = memnew(VBoxContainer);
add_child(vb);
diff --git a/editor/editor_asset_installer.h b/editor/editor_asset_installer.h
index 840e780264..7f3d00994f 100644
--- a/editor/editor_asset_installer.h
+++ b/editor/editor_asset_installer.h
@@ -34,7 +34,6 @@
#include "scene/gui/dialogs.h"
#include "scene/gui/tree.h"
class EditorAssetInstaller : public ConfirmationDialog {
-
GDCLASS(EditorAssetInstaller, ConfirmationDialog);
Tree *tree;
diff --git a/editor/editor_atlas_packer.cpp b/editor/editor_atlas_packer.cpp
index d17b3bba4f..68abeb2cda 100644
--- a/editor/editor_atlas_packer.cpp
+++ b/editor/editor_atlas_packer.cpp
@@ -31,14 +31,12 @@
#include "editor_atlas_packer.h"
void EditorAtlasPacker::_plot_triangle(Ref<BitMap> p_bitmap, Vector2i *vertices) {
-
int width = p_bitmap->get_size().width;
int height = p_bitmap->get_size().height;
int x[3];
int y[3];
for (int j = 0; j < 3; j++) {
-
x[j] = vertices[j].x;
y[j] = vertices[j].y;
}
@@ -71,26 +69,25 @@ void EditorAtlasPacker::_plot_triangle(Ref<BitMap> p_bitmap, Vector2i *vertices)
}
for (int xi = (xf < width ? int(xf) : width - 1); xi >= (xt > 0 ? xt : 0); xi--) {
-
p_bitmap->set_bit(Point2(xi, yi), true);
}
}
xf += dx_far;
- if (yi < y[1])
+ if (yi < y[1]) {
xt += dx_upper;
- else
+ } else {
xt += dx_low;
+ }
}
}
-void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_height, int p_atlas_max_size, int p_cell_resolution) {
+void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_height, int p_atlas_max_size, int p_cell_resolution) {
int divide_by = MIN(64, p_cell_resolution);
Vector<PlottedBitmap> bitmaps;
int max_w = 0;
for (int i = 0; i < charts.size(); i++) {
-
const Chart &chart = charts[i];
//generate aabb
@@ -100,7 +97,6 @@ void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_h
const Vector2 *vertices = chart.vertices.ptr();
for (int j = 0; j < vertex_count; j++) {
-
if (j == 0) {
aabb.position = vertices[j];
} else {
@@ -118,7 +114,6 @@ void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_h
//plot triangles, using divisor
for (int j = 0; j < chart.faces.size(); j++) {
-
Vector2i v[3];
for (int k = 0; k < 3; k++) {
Vector2 vtx = chart.vertices[chart.faces[j].vertex[k]];
@@ -163,13 +158,14 @@ void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_h
bool found_pixel = false;
for (int lx = x - 1; lx < x + 2 && !found_pixel; lx++) {
for (int ly = y - 1; ly < y + 2 && !found_pixel; ly++) {
-
int px = lx - 1;
- if (px < 0 || px >= w)
+ if (px < 0 || px >= w) {
continue;
+ }
int py = ly - 1;
- if (py < 0 || py >= h)
+ if (py < 0 || py >= h) {
continue;
+ }
if (src_bitmap->get_bit(Vector2(px, py))) {
found_pixel = true;
@@ -177,7 +173,6 @@ void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_h
}
}
if (found_pixel) {
-
if (transpose) {
if (x > top_heights[y]) {
top_heights.write[y] = x;
@@ -231,7 +226,6 @@ void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_h
int *atlas_ptr = heights.ptrw();
for (int i = 0; i < bitmaps.size(); i++) {
-
int best_height = 0x7FFFFFFF;
int best_height_offset = -1;
int w = bitmaps[i].top_heights.size();
@@ -240,11 +234,9 @@ void EditorAtlasPacker::chart_pack(Vector<Chart> &charts, int &r_width, int &r_h
const int *bottom_heights = bitmaps[i].bottom_heights.ptr();
for (int j = 0; j < atlas_w - w; j++) {
-
int height = 0;
for (int k = 0; k < w; k++) {
-
int pixmap_h = bottom_heights[k];
if (pixmap_h == -1) {
continue; //no pixel here, anything is fine
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 7e499facd5..f8dec13a5c 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -30,7 +30,7 @@
#include "editor_audio_buses.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/resource_saver.h"
#include "core/os/keyboard.h"
#include "editor_node.h"
@@ -40,10 +40,8 @@
#include "servers/audio_server.h"
void EditorAudioBus::_update_visible_channels() {
-
int i = 0;
for (; i < cc; i++) {
-
if (!channel[i].vu_l->is_visible()) {
channel[i].vu_l->show();
}
@@ -53,7 +51,6 @@ void EditorAudioBus::_update_visible_channels() {
}
for (; i < CHANNELS_MAX; i++) {
-
if (channel[i].vu_l->is_visible()) {
channel[i].vu_l->hide();
}
@@ -64,10 +61,8 @@ void EditorAudioBus::_update_visible_channels() {
}
void EditorAudioBus::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_READY: {
-
for (int i = 0; i < CHANNELS_MAX; i++) {
channel[i].vu_l->set_under_texture(get_theme_icon("BusVuEmpty", "EditorIcons"));
channel[i].vu_l->set_progress_texture(get_theme_icon("BusVuFull", "EditorIcons"));
@@ -95,7 +90,6 @@ void EditorAudioBus::_notification(int p_what) {
set_process(true);
} break;
case NOTIFICATION_DRAW: {
-
if (is_master) {
draw_style_box(get_theme_stylebox("disabled", "Button"), Rect2(Vector2(), get_size()));
} else if (has_focus()) {
@@ -111,7 +105,6 @@ void EditorAudioBus::_notification(int p_what) {
}
} break;
case NOTIFICATION_PROCESS: {
-
if (cc != AudioServer::get_singleton()->get_bus_channels(get_index())) {
cc = AudioServer::get_singleton()->get_bus_channels(get_index());
_update_visible_channels();
@@ -156,7 +149,6 @@ void EditorAudioBus::_notification(int p_what) {
}
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
for (int i = 0; i < CHANNELS_MAX; i++) {
channel[i].peak_l = -100;
channel[i].peak_r = -100;
@@ -166,7 +158,6 @@ void EditorAudioBus::_notification(int p_what) {
set_process(is_visible_in_tree());
} break;
case NOTIFICATION_THEME_CHANGED: {
-
for (int i = 0; i < CHANNELS_MAX; i++) {
channel[i].vu_l->set_under_texture(get_theme_icon("BusVuEmpty", "EditorIcons"));
channel[i].vu_l->set_progress_texture(get_theme_icon("BusVuFull", "EditorIcons"));
@@ -185,7 +176,6 @@ void EditorAudioBus::_notification(int p_what) {
} break;
case NOTIFICATION_MOUSE_EXIT:
case NOTIFICATION_DRAG_END: {
-
if (hovering_drop) {
hovering_drop = false;
update();
@@ -195,7 +185,6 @@ void EditorAudioBus::_notification(int p_what) {
}
void EditorAudioBus::update_send() {
-
send->clear();
if (is_master) {
send->set_disabled(true);
@@ -218,9 +207,9 @@ void EditorAudioBus::update_send() {
}
void EditorAudioBus::update_bus() {
-
- if (updating_bus)
+ if (updating_bus) {
return;
+ }
updating_bus = true;
@@ -229,8 +218,9 @@ void EditorAudioBus::update_bus() {
float db_value = AudioServer::get_singleton()->get_bus_volume_db(index);
slider->set_value(_scaled_db_to_normalized_volume(db_value));
track_name->set_text(AudioServer::get_singleton()->get_bus_name(index));
- if (is_master)
+ if (is_master) {
track_name->set_editable(false);
+ }
solo->set_pressed(AudioServer::get_singleton()->is_bus_solo(index));
mute->set_pressed(AudioServer::get_singleton()->is_bus_mute(index));
@@ -240,7 +230,6 @@ void EditorAudioBus::update_bus() {
TreeItem *root = effects->create_item();
for (int i = 0; i < AudioServer::get_singleton()->get_bus_effect_count(index); i++) {
-
Ref<AudioEffect> afx = AudioServer::get_singleton()->get_bus_effect(index, i);
TreeItem *fx = effects->create_item(root);
@@ -263,18 +252,16 @@ void EditorAudioBus::update_bus() {
}
void EditorAudioBus::_name_changed(const String &p_new_name) {
-
- if (p_new_name == AudioServer::get_singleton()->get_bus_name(get_index()))
+ if (p_new_name == AudioServer::get_singleton()->get_bus_name(get_index())) {
return;
+ }
String attempt = p_new_name;
int attempts = 1;
while (true) {
-
bool name_free = true;
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
-
if (AudioServer::get_singleton()->get_bus_name(i) == attempt) {
name_free = false;
break;
@@ -317,15 +304,15 @@ void EditorAudioBus::_name_changed(const String &p_new_name) {
}
void EditorAudioBus::_volume_changed(float p_normalized) {
-
- if (updating_bus)
+ if (updating_bus) {
return;
+ }
updating_bus = true;
const float p_db = this->_normalized_volume_to_scaled_db(p_normalized);
- if (InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+ if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
// Snap the value when holding Ctrl for easier editing.
// To do so, it needs to be converted back to normalized volume (as the slider uses that unit).
slider->set_value(_scaled_db_to_normalized_volume(Math::round(p_db)));
@@ -384,9 +371,8 @@ float EditorAudioBus::_scaled_db_to_normalized_volume(float db) {
}
void EditorAudioBus::_show_value(float slider_value) {
-
float db;
- if (InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+ if (Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
// Display the correct (snapped) value when holding Ctrl
db = Math::round(_normalized_volume_to_scaled_db(slider_value));
} else {
@@ -415,7 +401,6 @@ void EditorAudioBus::_hide_value_preview() {
}
void EditorAudioBus::_solo_toggled() {
-
updating_bus = true;
UndoRedo *ur = EditorNode::get_undo_redo();
@@ -428,8 +413,8 @@ void EditorAudioBus::_solo_toggled() {
updating_bus = false;
}
-void EditorAudioBus::_mute_toggled() {
+void EditorAudioBus::_mute_toggled() {
updating_bus = true;
UndoRedo *ur = EditorNode::get_undo_redo();
@@ -442,8 +427,8 @@ void EditorAudioBus::_mute_toggled() {
updating_bus = false;
}
-void EditorAudioBus::_bypass_toggled() {
+void EditorAudioBus::_bypass_toggled() {
updating_bus = true;
UndoRedo *ur = EditorNode::get_undo_redo();
@@ -458,7 +443,6 @@ void EditorAudioBus::_bypass_toggled() {
}
void EditorAudioBus::_send_selected(int p_which) {
-
updating_bus = true;
UndoRedo *ur = EditorNode::get_undo_redo();
@@ -473,14 +457,13 @@ void EditorAudioBus::_send_selected(int p_which) {
}
void EditorAudioBus::_effect_selected() {
-
TreeItem *effect = effects->get_selected();
- if (!effect)
+ if (!effect) {
return;
+ }
updating_bus = true;
if (effect->get_metadata(0) != Variant()) {
-
int index = effect->get_metadata(0);
Ref<AudioEffect> effect2 = AudioServer::get_singleton()->get_bus_effect(get_index(), index);
if (effect2.is_valid()) {
@@ -492,13 +475,14 @@ void EditorAudioBus::_effect_selected() {
}
void EditorAudioBus::_effect_edited() {
-
- if (updating_bus)
+ if (updating_bus) {
return;
+ }
TreeItem *effect = effects->get_edited();
- if (!effect)
+ if (!effect) {
return;
+ }
if (effect->get_metadata(0) == Variant()) {
Rect2 area = effects->get_item_rect(effect);
@@ -523,9 +507,9 @@ void EditorAudioBus::_effect_edited() {
}
void EditorAudioBus::_effect_add(int p_which) {
-
- if (updating_bus)
+ if (updating_bus) {
return;
+ }
StringName name = effect_options->get_item_metadata(p_which);
@@ -547,7 +531,6 @@ void EditorAudioBus::_effect_add(int p_which) {
}
void EditorAudioBus::_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed() && k->get_keycode() == KEY_DELETE && !k->is_echo()) {
accept_event();
@@ -556,7 +539,6 @@ void EditorAudioBus::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->get_button_index() == 2 && mb->is_pressed()) {
-
Vector2 pos = Vector2(mb->get_position().x, mb->get_position().y);
bus_popup->set_position(get_global_position() + pos);
bus_popup->popup();
@@ -564,7 +546,6 @@ void EditorAudioBus::_gui_input(const Ref<InputEvent> &p_event) {
}
void EditorAudioBus::_bus_popup_pressed(int p_option) {
-
if (p_option == 2) {
// Reset volume
emit_signal("vol_reset_request");
@@ -577,7 +558,6 @@ void EditorAudioBus::_bus_popup_pressed(int p_option) {
}
Variant EditorAudioBus::get_drag_data(const Point2 &p_point) {
-
if (get_index() == 0) {
return Variant();
}
@@ -602,7 +582,6 @@ Variant EditorAudioBus::get_drag_data(const Point2 &p_point) {
}
bool EditorAudioBus::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
-
if (get_index() == 0) {
return false;
}
@@ -617,13 +596,11 @@ bool EditorAudioBus::can_drop_data(const Point2 &p_point, const Variant &p_data)
}
void EditorAudioBus::drop_data(const Point2 &p_point, const Variant &p_data) {
-
Dictionary d = p_data;
emit_signal("dropped", d["index"], get_index());
}
Variant EditorAudioBus::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
TreeItem *item = effects->get_item_at_position(p_point);
if (!item) {
return Variant();
@@ -647,14 +624,15 @@ Variant EditorAudioBus::get_drag_data_fw(const Point2 &p_point, Control *p_from)
}
bool EditorAudioBus::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
Dictionary d = p_data;
- if (!d.has("type") || String(d["type"]) != "audio_bus_effect")
+ if (!d.has("type") || String(d["type"]) != "audio_bus_effect") {
return false;
+ }
TreeItem *item = effects->get_item_at_position(p_point);
- if (!item)
+ if (!item) {
return false;
+ }
effects->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN);
@@ -662,12 +640,12 @@ bool EditorAudioBus::can_drop_data_fw(const Point2 &p_point, const Variant &p_da
}
void EditorAudioBus::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
-
Dictionary d = p_data;
TreeItem *item = effects->get_item_at_position(p_point);
- if (!item)
+ if (!item) {
return;
+ }
int pos = effects->get_drop_section_at_position(p_point);
Variant md = item->get_metadata(0);
@@ -677,8 +655,9 @@ void EditorAudioBus::drop_data_fw(const Point2 &p_point, const Variant &p_data,
if (md.get_type() == Variant::INT) {
paste_at = md;
- if (pos > 0)
+ if (pos > 0) {
paste_at++;
+ }
if (bus == get_index() && paste_at > effect) {
paste_at--;
@@ -720,13 +699,14 @@ void EditorAudioBus::drop_data_fw(const Point2 &p_point, const Variant &p_data,
}
void EditorAudioBus::_delete_effect_pressed(int p_option) {
-
TreeItem *item = effects->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
- if (item->get_metadata(0).get_type() != Variant::INT)
+ if (item->get_metadata(0).get_type() != Variant::INT) {
return;
+ }
int index = item->get_metadata(0);
@@ -741,20 +721,20 @@ void EditorAudioBus::_delete_effect_pressed(int p_option) {
}
void EditorAudioBus::_effect_rmb(const Vector2 &p_pos) {
-
TreeItem *item = effects->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
- if (item->get_metadata(0).get_type() != Variant::INT)
+ if (item->get_metadata(0).get_type() != Variant::INT) {
return;
+ }
delete_effect_popup->set_position(get_global_mouse_position());
delete_effect_popup->popup();
}
void EditorAudioBus::_bind_methods() {
-
ClassDB::bind_method("update_bus", &EditorAudioBus::update_bus);
ClassDB::bind_method("update_send", &EditorAudioBus::update_send);
ClassDB::bind_method("_gui_input", &EditorAudioBus::_gui_input);
@@ -770,7 +750,6 @@ void EditorAudioBus::_bind_methods() {
}
EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
-
buses = p_buses;
updating_bus = false;
is_master = p_is_master;
@@ -926,8 +905,9 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
ClassDB::get_inheriters_from_class("AudioEffect", &effects);
effects.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *E = effects.front(); E; E = E->next()) {
- if (!ClassDB::can_instance(E->get()))
+ if (!ClassDB::can_instance(E->get())) {
continue;
+ }
Ref<Texture2D> icon = EditorNode::get_singleton()->get_class_icon(E->get());
String name = E->get().operator String().replace("AudioEffect", "");
@@ -950,7 +930,6 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses, bool p_is_master) {
}
void EditorAudioBusDrop::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_DRAW: {
draw_style_box(get_theme_stylebox("normal", "Button"), Rect2(Vector2(), get_size()));
@@ -962,7 +941,6 @@ void EditorAudioBusDrop::_notification(int p_what) {
}
} break;
case NOTIFICATION_MOUSE_ENTER: {
-
if (!hovering_drop) {
hovering_drop = true;
update();
@@ -970,7 +948,6 @@ void EditorAudioBusDrop::_notification(int p_what) {
} break;
case NOTIFICATION_MOUSE_EXIT:
case NOTIFICATION_DRAG_END: {
-
if (hovering_drop) {
hovering_drop = false;
update();
@@ -980,29 +957,24 @@ void EditorAudioBusDrop::_notification(int p_what) {
}
bool EditorAudioBusDrop::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
-
Dictionary d = p_data;
return (d.has("type") && String(d["type"]) == "move_audio_bus");
}
void EditorAudioBusDrop::drop_data(const Point2 &p_point, const Variant &p_data) {
-
Dictionary d = p_data;
emit_signal("dropped", d["index"], AudioServer::get_singleton()->get_bus_count());
}
void EditorAudioBusDrop::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("dropped"));
}
EditorAudioBusDrop::EditorAudioBusDrop() {
-
hovering_drop = false;
}
void EditorAudioBuses::_update_buses() {
-
while (bus_hb->get_child_count() > 0) {
memdelete(bus_hb->get_child(0));
}
@@ -1010,7 +982,6 @@ void EditorAudioBuses::_update_buses() {
drop_end = nullptr;
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
-
bool is_master = (i == 0);
EditorAudioBus *audio_bus = memnew(EditorAudioBus(this, is_master));
bus_hb->add_child(audio_bus);
@@ -1023,33 +994,27 @@ void EditorAudioBuses::_update_buses() {
}
EditorAudioBuses *EditorAudioBuses::register_editor() {
-
EditorAudioBuses *audio_buses = memnew(EditorAudioBuses);
EditorNode::get_singleton()->add_bottom_panel_item(TTR("Audio"), audio_buses);
return audio_buses;
}
void EditorAudioBuses::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
-
bus_scroll->add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
} break;
case NOTIFICATION_READY: {
-
_update_buses();
} break;
case NOTIFICATION_DRAG_END: {
-
if (drop_end) {
drop_end->queue_delete();
drop_end = nullptr;
}
} break;
case NOTIFICATION_PROCESS: {
-
// Check if anything was edited.
bool edited = AudioServer::get_singleton()->is_edited();
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
@@ -1072,7 +1037,6 @@ void EditorAudioBuses::_notification(int p_what) {
}
void EditorAudioBuses::_add_bus() {
-
UndoRedo *ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Add Audio Bus"));
@@ -1084,22 +1048,20 @@ void EditorAudioBuses::_add_bus() {
}
void EditorAudioBuses::_update_bus(int p_index) {
-
- if (p_index >= bus_hb->get_child_count())
+ if (p_index >= bus_hb->get_child_count()) {
return;
+ }
bus_hb->get_child(p_index)->call("update_bus");
}
void EditorAudioBuses::_update_sends() {
-
for (int i = 0; i < bus_hb->get_child_count(); i++) {
bus_hb->get_child(i)->call("update_send");
}
}
void EditorAudioBuses::_delete_bus(Object *p_which) {
-
EditorAudioBus *bus = Object::cast_to<EditorAudioBus>(p_which);
int index = bus->get_index();
if (index == 0) {
@@ -1119,7 +1081,6 @@ void EditorAudioBuses::_delete_bus(Object *p_which) {
ur->add_undo_method(AudioServer::get_singleton(), "set_bus_mute", index, AudioServer::get_singleton()->is_bus_mute(index));
ur->add_undo_method(AudioServer::get_singleton(), "set_bus_bypass_effects", index, AudioServer::get_singleton()->is_bus_bypassing_effects(index));
for (int i = 0; i < AudioServer::get_singleton()->get_bus_effect_count(index); i++) {
-
ur->add_undo_method(AudioServer::get_singleton(), "add_bus_effect", index, AudioServer::get_singleton()->get_bus_effect(index, i));
ur->add_undo_method(AudioServer::get_singleton(), "set_bus_effect_enabled", index, i, AudioServer::get_singleton()->is_bus_effect_enabled(index, i));
}
@@ -1129,7 +1090,6 @@ void EditorAudioBuses::_delete_bus(Object *p_which) {
}
void EditorAudioBuses::_duplicate_bus(int p_which) {
-
int add_at_pos = p_which + 1;
UndoRedo *ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Duplicate Audio Bus"));
@@ -1141,7 +1101,6 @@ void EditorAudioBuses::_duplicate_bus(int p_which) {
ur->add_do_method(AudioServer::get_singleton(), "set_bus_mute", add_at_pos, AudioServer::get_singleton()->is_bus_mute(p_which));
ur->add_do_method(AudioServer::get_singleton(), "set_bus_bypass_effects", add_at_pos, AudioServer::get_singleton()->is_bus_bypassing_effects(p_which));
for (int i = 0; i < AudioServer::get_singleton()->get_bus_effect_count(p_which); i++) {
-
ur->add_do_method(AudioServer::get_singleton(), "add_bus_effect", add_at_pos, AudioServer::get_singleton()->get_bus_effect(p_which, i));
ur->add_do_method(AudioServer::get_singleton(), "set_bus_effect_enabled", add_at_pos, i, AudioServer::get_singleton()->is_bus_effect_enabled(p_which, i));
}
@@ -1152,7 +1111,6 @@ void EditorAudioBuses::_duplicate_bus(int p_which) {
}
void EditorAudioBuses::_reset_bus_volume(Object *p_which) {
-
EditorAudioBus *bus = Object::cast_to<EditorAudioBus>(p_which);
int index = bus->get_index();
@@ -1166,7 +1124,6 @@ void EditorAudioBuses::_reset_bus_volume(Object *p_which) {
}
void EditorAudioBuses::_request_drop_end() {
-
if (!drop_end && bus_hb->get_child_count()) {
drop_end = memnew(EditorAudioBusDrop);
@@ -1177,7 +1134,6 @@ void EditorAudioBuses::_request_drop_end() {
}
void EditorAudioBuses::_drop_at_index(int p_bus, int p_index) {
-
UndoRedo *ur = EditorNode::get_undo_redo();
ur->create_action(TTR("Move Audio Bus"));
@@ -1192,18 +1148,15 @@ void EditorAudioBuses::_drop_at_index(int p_bus, int p_index) {
}
void EditorAudioBuses::_server_save() {
-
Ref<AudioBusLayout> state = AudioServer::get_singleton()->generate_bus_layout();
ResourceSaver::save(edited_path, state);
}
void EditorAudioBuses::_select_layout() {
-
EditorNode::get_singleton()->get_filesystem_dock()->select_file(edited_path);
}
void EditorAudioBuses::_save_as_layout() {
-
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
file_dialog->set_title(TTR("Save Audio Bus Layout As..."));
file_dialog->set_current_path(edited_path);
@@ -1212,7 +1165,6 @@ void EditorAudioBuses::_save_as_layout() {
}
void EditorAudioBuses::_new_layout() {
-
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
file_dialog->set_title(TTR("Location for New Layout..."));
file_dialog->set_current_path(edited_path);
@@ -1221,7 +1173,6 @@ void EditorAudioBuses::_new_layout() {
}
void EditorAudioBuses::_load_layout() {
-
file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
file_dialog->set_title(TTR("Open Audio Bus Layout"));
file_dialog->set_current_path(edited_path);
@@ -1230,7 +1181,6 @@ void EditorAudioBuses::_load_layout() {
}
void EditorAudioBuses::_load_default_layout() {
-
String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout");
Ref<AudioBusLayout> state = ResourceLoader::load(layout_path, "", true);
@@ -1248,7 +1198,6 @@ void EditorAudioBuses::_load_default_layout() {
}
void EditorAudioBuses::_file_dialog_callback(const String &p_string) {
-
if (file_dialog->get_file_mode() == EditorFileDialog::FILE_MODE_OPEN_FILE) {
Ref<AudioBusLayout> state = ResourceLoader::load(p_string, "", true);
if (state.is_null()) {
@@ -1264,7 +1213,6 @@ void EditorAudioBuses::_file_dialog_callback(const String &p_string) {
call_deferred("_select_layout");
} else if (file_dialog->get_file_mode() == EditorFileDialog::FILE_MODE_SAVE_FILE) {
-
if (new_layout) {
Ref<AudioBusLayout> empty_state;
empty_state.instance();
@@ -1287,7 +1235,6 @@ void EditorAudioBuses::_file_dialog_callback(const String &p_string) {
}
void EditorAudioBuses::_bind_methods() {
-
ClassDB::bind_method("_update_buses", &EditorAudioBuses::_update_buses);
ClassDB::bind_method("_update_bus", &EditorAudioBuses::_update_bus);
ClassDB::bind_method("_update_sends", &EditorAudioBuses::_update_sends);
@@ -1295,7 +1242,6 @@ void EditorAudioBuses::_bind_methods() {
}
EditorAudioBuses::EditorAudioBuses() {
-
drop_end = nullptr;
top_hb = memnew(HBoxContainer);
add_child(top_hb);
@@ -1372,7 +1318,6 @@ EditorAudioBuses::EditorAudioBuses() {
}
void EditorAudioBuses::open_layout(const String &p_path) {
-
EditorNode::get_singleton()->make_bottom_panel_item_visible(this);
Ref<AudioBusLayout> state = ResourceLoader::load(p_path, "", true);
@@ -1390,9 +1335,7 @@ void EditorAudioBuses::open_layout(const String &p_path) {
}
void AudioBusesEditorPlugin::edit(Object *p_node) {
-
if (Object::cast_to<AudioBusLayout>(p_node)) {
-
String path = Object::cast_to<AudioBusLayout>(p_node)->get_path();
if (path.is_resource_file()) {
audio_bus_editor->open_layout(path);
@@ -1401,7 +1344,6 @@ void AudioBusesEditorPlugin::edit(Object *p_node) {
}
bool AudioBusesEditorPlugin::handles(Object *p_node) const {
-
return (Object::cast_to<AudioBusLayout>(p_node) != nullptr);
}
@@ -1409,7 +1351,6 @@ void AudioBusesEditorPlugin::make_visible(bool p_visible) {
}
AudioBusesEditorPlugin::AudioBusesEditorPlugin(EditorAudioBuses *p_node) {
-
audio_bus_editor = p_node;
}
@@ -1417,12 +1358,10 @@ AudioBusesEditorPlugin::~AudioBusesEditorPlugin() {
}
void EditorAudioMeterNotches::add_notch(float p_normalized_offset, float p_db_value, bool p_render_value) {
-
notches.push_back(AudioNotch(p_normalized_offset, p_db_value, p_render_value));
}
Size2 EditorAudioMeterNotches::get_minimum_size() const {
-
Ref<Font> font = get_theme_font("font", "Label");
float font_height = font->get_height();
@@ -1441,13 +1380,11 @@ Size2 EditorAudioMeterNotches::get_minimum_size() const {
}
void EditorAudioMeterNotches::_bind_methods() {
-
ClassDB::bind_method("add_notch", &EditorAudioMeterNotches::add_notch);
ClassDB::bind_method("_draw_audio_notches", &EditorAudioMeterNotches::_draw_audio_notches);
}
void EditorAudioMeterNotches::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
notch_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(0, 0, 0);
@@ -1459,7 +1396,6 @@ void EditorAudioMeterNotches::_notification(int p_what) {
}
void EditorAudioMeterNotches::_draw_audio_notches() {
-
Ref<Font> font = get_theme_font("font", "Label");
float font_height = font->get_height();
@@ -1480,11 +1416,6 @@ void EditorAudioMeterNotches::_draw_audio_notches() {
}
}
-EditorAudioMeterNotches::EditorAudioMeterNotches() :
- line_length(5.0f),
- label_space(2.0f),
- btm_padding(9.0f),
- top_padding(5.0f) {
-
+EditorAudioMeterNotches::EditorAudioMeterNotches() {
notch_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1, 1, 1) : Color(0, 0, 0);
}
diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h
index be1551629d..6b2d9e4436 100644
--- a/editor/editor_audio_buses.h
+++ b/editor/editor_audio_buses.h
@@ -51,7 +51,6 @@
class EditorAudioBuses;
class EditorAudioBus : public PanelContainer {
-
GDCLASS(EditorAudioBus, PanelContainer);
Ref<Texture2D> disabled_vu;
@@ -137,7 +136,6 @@ public:
};
class EditorAudioBusDrop : public Control {
-
GDCLASS(EditorAudioBusDrop, Control);
virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const;
@@ -154,7 +152,6 @@ public:
};
class EditorAudioBuses : public VBoxContainer {
-
GDCLASS(EditorAudioBuses, VBoxContainer);
HBoxContainer *top_hb;
@@ -246,10 +243,10 @@ private:
List<AudioNotch> notches;
public:
- float line_length;
- float label_space;
- float btm_padding;
- float top_padding;
+ float line_length = 5.0f;
+ float label_space = 2.0f;
+ float btm_padding = 9.0f;
+ float top_padding = 5.0f;
Color notch_color;
void add_notch(float p_normalized_offset, float p_db_value, bool p_render_value = false);
@@ -265,7 +262,6 @@ public:
};
class AudioBusesEditorPlugin : public EditorPlugin {
-
GDCLASS(AudioBusesEditorPlugin, EditorPlugin);
EditorAudioBuses *audio_bus_editor;
diff --git a/editor/editor_autoload_settings.cpp b/editor/editor_autoload_settings.cpp
index 6917b2b775..200ae7045f 100644
--- a/editor/editor_autoload_settings.cpp
+++ b/editor/editor_autoload_settings.cpp
@@ -41,15 +41,12 @@
#define PREVIEW_LIST_MAX_SIZE 10
void EditorAutoloadSettings::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
List<String> afn;
ResourceLoader::get_recognized_extensions_for_type("Script", &afn);
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &afn);
for (List<String>::Element *E = afn.front(); E; E = E->next()) {
-
file_dialog->add_filter("*." + E->get());
}
@@ -66,25 +63,27 @@ void EditorAutoloadSettings::_notification(int p_what) {
}
bool EditorAutoloadSettings::_autoload_name_is_valid(const String &p_name, String *r_error) {
-
if (!p_name.is_valid_identifier()) {
- if (r_error)
+ if (r_error) {
*r_error = TTR("Invalid name.") + "\n" + TTR("Valid characters:") + " a-z, A-Z, 0-9 or _";
+ }
return false;
}
if (ClassDB::class_exists(p_name)) {
- if (r_error)
+ if (r_error) {
*r_error = TTR("Invalid name.") + "\n" + TTR("Must not collide with an existing engine class name.");
+ }
return false;
}
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
if (Variant::get_type_name(Variant::Type(i)) == p_name) {
- if (r_error)
+ if (r_error) {
*r_error = TTR("Invalid name.") + "\n" + TTR("Must not collide with an existing built-in type name.");
+ }
return false;
}
@@ -92,8 +91,9 @@ bool EditorAutoloadSettings::_autoload_name_is_valid(const String &p_name, Strin
for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) {
if (GlobalConstants::get_global_constant_name(i) == p_name) {
- if (r_error)
+ if (r_error) {
*r_error = TTR("Invalid name.") + "\n" + TTR("Must not collide with an existing global constant name.");
+ }
return false;
}
@@ -104,8 +104,9 @@ bool EditorAutoloadSettings::_autoload_name_is_valid(const String &p_name, Strin
ScriptServer::get_language(i)->get_reserved_words(&keywords);
for (List<String>::Element *E = keywords.front(); E; E = E->next()) {
if (E->get() == p_name) {
- if (r_error)
+ if (r_error) {
*r_error = TTR("Invalid name.") + "\n" + TTR("Keyword cannot be used as an autoload name.");
+ }
return false;
}
@@ -116,28 +117,28 @@ bool EditorAutoloadSettings::_autoload_name_is_valid(const String &p_name, Strin
}
void EditorAutoloadSettings::_autoload_add() {
-
- if (autoload_add(autoload_add_name->get_text(), autoload_add_path->get_text()))
+ if (autoload_add(autoload_add_name->get_text(), autoload_add_path->get_text())) {
autoload_add_path->set_text("");
+ }
autoload_add_name->set_text("");
add_autoload->set_disabled(true);
}
void EditorAutoloadSettings::_autoload_selected() {
-
TreeItem *ti = tree->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
selected_autoload = "autoload/" + ti->get_text(0);
}
void EditorAutoloadSettings::_autoload_edited() {
-
- if (updating_autoload)
+ if (updating_autoload) {
return;
+ }
TreeItem *ti = tree->get_edited();
int column = tree->get_edited_column();
@@ -148,8 +149,9 @@ void EditorAutoloadSettings::_autoload_edited() {
String name = ti->get_text(0);
String old_name = selected_autoload.get_slice("/", 1);
- if (name == old_name)
+ if (name == old_name) {
return;
+ }
String error;
if (!_autoload_name_is_valid(name, &error)) {
@@ -199,12 +201,14 @@ void EditorAutoloadSettings::_autoload_edited() {
int order = ProjectSettings::get_singleton()->get_order(base);
String path = ProjectSettings::get_singleton()->get(base);
- if (path.begins_with("*"))
+ if (path.begins_with("*")) {
path = path.substr(1, path.length());
+ }
// Singleton autoloads are represented with a leading "*" in their path.
- if (checked)
+ if (checked) {
path = "*" + path;
+ }
undo_redo->create_action(TTR("Toggle AutoLoad Globals"));
@@ -227,7 +231,6 @@ void EditorAutoloadSettings::_autoload_edited() {
}
void EditorAutoloadSettings::_autoload_button_pressed(Object *p_item, int p_column, int p_button) {
-
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
String name = "autoload/" + ti->get_text(0);
@@ -240,7 +243,6 @@ void EditorAutoloadSettings::_autoload_button_pressed(Object *p_item, int p_colu
} break;
case BUTTON_MOVE_UP:
case BUTTON_MOVE_DOWN: {
-
TreeItem *swap = nullptr;
if (p_button == BUTTON_MOVE_UP) {
@@ -249,8 +251,9 @@ void EditorAutoloadSettings::_autoload_button_pressed(Object *p_item, int p_colu
swap = ti->get_next();
}
- if (!swap)
+ if (!swap) {
return;
+ }
String swap_name = "autoload/" + swap->get_text(0);
@@ -274,7 +277,6 @@ void EditorAutoloadSettings::_autoload_button_pressed(Object *p_item, int p_colu
undo_redo->commit_action();
} break;
case BUTTON_DELETE: {
-
int order = ProjectSettings::get_singleton()->get_order(name);
undo_redo->create_action(TTR("Remove Autoload"));
@@ -298,8 +300,9 @@ void EditorAutoloadSettings::_autoload_button_pressed(Object *p_item, int p_colu
void EditorAutoloadSettings::_autoload_activated() {
TreeItem *ti = tree->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
_autoload_open(ti->get_text(1));
}
@@ -313,7 +316,6 @@ void EditorAutoloadSettings::_autoload_open(const String &fpath) {
}
void EditorAutoloadSettings::_autoload_file_callback(const String &p_path) {
-
// Convert the file name to PascalCase, which is the convention for classes in GDScript.
const String class_name = p_path.get_file().get_basename().capitalize().replace(" ", "");
@@ -326,20 +328,17 @@ void EditorAutoloadSettings::_autoload_file_callback(const String &p_path) {
}
void EditorAutoloadSettings::_autoload_text_entered(const String p_name) {
-
if (autoload_add_path->get_text() != "" && _autoload_name_is_valid(p_name, nullptr)) {
_autoload_add();
}
}
void EditorAutoloadSettings::_autoload_path_text_changed(const String p_path) {
-
add_autoload->set_disabled(
p_path == "" || !_autoload_name_is_valid(autoload_add_name->get_text(), nullptr));
}
void EditorAutoloadSettings::_autoload_text_changed(const String p_name) {
-
add_autoload->set_disabled(
autoload_add_path->get_text() == "" || !_autoload_name_is_valid(p_name, nullptr));
}
@@ -371,9 +370,9 @@ Node *EditorAutoloadSettings::_create_autoload(const String &p_path) {
}
void EditorAutoloadSettings::update_autoload() {
-
- if (updating_autoload)
+ if (updating_autoload) {
return;
+ }
updating_autoload = true;
@@ -394,17 +393,18 @@ void EditorAutoloadSettings::update_autoload() {
ProjectSettings::get_singleton()->get_property_list(&props);
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
const PropertyInfo &pi = E->get();
- if (!pi.name.begins_with("autoload/"))
+ if (!pi.name.begins_with("autoload/")) {
continue;
+ }
String name = pi.name.get_slice("/", 1);
String path = ProjectSettings::get_singleton()->get(pi.name);
- if (name.empty())
+ if (name.empty()) {
continue;
+ }
AutoLoadInfo info;
info.is_singleton = path.begins_with("*");
@@ -518,9 +518,9 @@ void EditorAutoloadSettings::update_autoload() {
}
Variant EditorAutoloadSettings::get_drag_data_fw(const Point2 &p_point, Control *p_control) {
-
- if (autoload_cache.size() <= 1)
+ if (autoload_cache.size() <= 1) {
return false;
+ }
PackedStringArray autoloads;
@@ -531,8 +531,9 @@ Variant EditorAutoloadSettings::get_drag_data_fw(const Point2 &p_point, Control
next = tree->get_next_selected(next);
}
- if (autoloads.size() == 0 || autoloads.size() == autoload_cache.size())
+ if (autoloads.size() == 0 || autoloads.size() == autoload_cache.size()) {
return Variant();
+ }
VBoxContainer *preview = memnew(VBoxContainer);
@@ -556,19 +557,22 @@ Variant EditorAutoloadSettings::get_drag_data_fw(const Point2 &p_point, Control
}
bool EditorAutoloadSettings::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_control) const {
- if (updating_autoload)
+ if (updating_autoload) {
return false;
+ }
Dictionary drop_data = p_data;
- if (!drop_data.has("type"))
+ if (!drop_data.has("type")) {
return false;
+ }
if (drop_data.has("type")) {
TreeItem *ti = tree->get_item_at_position(p_point);
- if (!ti)
+ if (!ti) {
return false;
+ }
int section = tree->get_drop_section_at_position(p_point);
@@ -579,16 +583,17 @@ bool EditorAutoloadSettings::can_drop_data_fw(const Point2 &p_point, const Varia
}
void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_control) {
-
TreeItem *ti = tree->get_item_at_position(p_point);
- if (!ti)
+ if (!ti) {
return;
+ }
int section = tree->get_drop_section_at_position(p_point);
- if (section < -1)
+ if (section < -1) {
return;
+ }
String name;
bool move_to_back = false;
@@ -665,7 +670,6 @@ void EditorAutoloadSettings::drop_data_fw(const Point2 &p_point, const Variant &
}
bool EditorAutoloadSettings::autoload_add(const String &p_name, const String &p_path) {
-
String name = p_name;
String error;
@@ -711,7 +715,6 @@ bool EditorAutoloadSettings::autoload_add(const String &p_name, const String &p_
}
void EditorAutoloadSettings::autoload_remove(const String &p_name) {
-
String name = "autoload/" + p_name;
UndoRedo *undo_redo = EditorNode::get_undo_redo();
@@ -736,7 +739,6 @@ void EditorAutoloadSettings::autoload_remove(const String &p_name) {
}
void EditorAutoloadSettings::_bind_methods() {
-
ClassDB::bind_method("_autoload_open", &EditorAutoloadSettings::_autoload_open);
ClassDB::bind_method("get_drag_data_fw", &EditorAutoloadSettings::get_drag_data_fw);
@@ -751,22 +753,22 @@ void EditorAutoloadSettings::_bind_methods() {
}
EditorAutoloadSettings::EditorAutoloadSettings() {
-
// Make first cache
List<PropertyInfo> props;
ProjectSettings::get_singleton()->get_property_list(&props);
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
const PropertyInfo &pi = E->get();
- if (!pi.name.begins_with("autoload/"))
+ if (!pi.name.begins_with("autoload/")) {
continue;
+ }
String name = pi.name.get_slice("/", 1);
String path = ProjectSettings::get_singleton()->get(pi.name);
- if (name.empty())
+ if (name.empty()) {
continue;
+ }
AutoLoadInfo info;
info.is_singleton = path.begins_with("*");
@@ -904,12 +906,10 @@ EditorAutoloadSettings::~EditorAutoloadSettings() {
}
void EditorAutoloadSettings::_set_autoload_add_path(const String &p_text) {
-
autoload_add_path->set_text(p_text);
autoload_add_path->emit_signal("text_entered", p_text);
}
void EditorAutoloadSettings::_browse_autoload_add_path() {
-
file_dialog->popup_centered_ratio();
} \ No newline at end of file
diff --git a/editor/editor_autoload_settings.h b/editor/editor_autoload_settings.h
index 94a581401c..646fe3992c 100644
--- a/editor/editor_autoload_settings.h
+++ b/editor/editor_autoload_settings.h
@@ -36,7 +36,6 @@
#include "editor_file_dialog.h"
class EditorAutoloadSettings : public VBoxContainer {
-
GDCLASS(EditorAutoloadSettings, VBoxContainer);
enum {
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 942b4a8ee6..130c330f5a 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -39,22 +39,23 @@
#include "scene/resources/packed_scene.h"
void EditorHistory::cleanup_history() {
-
for (int i = 0; i < history.size(); i++) {
-
bool fail = false;
for (int j = 0; j < history[i].path.size(); j++) {
- if (!history[i].path[j].ref.is_null())
+ if (!history[i].path[j].ref.is_null()) {
continue;
+ }
Object *obj = ObjectDB::get_instance(history[i].path[j].object);
if (obj) {
Node *n = Object::cast_to<Node>(obj);
- if (n && n->is_inside_tree())
+ if (n && n->is_inside_tree()) {
continue;
- if (!n) // Possibly still alive
+ }
+ if (!n) { // Possibly still alive
continue;
+ }
}
if (j <= history[i].level) {
@@ -74,18 +75,19 @@ void EditorHistory::cleanup_history() {
}
}
- if (current >= history.size())
+ if (current >= history.size()) {
current = history.size() - 1;
+ }
}
void EditorHistory::_add_object(ObjectID p_object, const String &p_property, int p_level_change, bool p_inspector_only) {
-
Object *obj = ObjectDB::get_instance(p_object);
ERR_FAIL_COND(!obj);
Reference *r = Object::cast_to<Reference>(obj);
Obj o;
- if (r)
+ if (r) {
o.ref = REF(r);
+ }
o.object = p_object;
o.property = p_property;
o.inspector_only = p_inspector_only;
@@ -122,34 +124,30 @@ void EditorHistory::_add_object(ObjectID p_object, const String &p_property, int
}
void EditorHistory::add_object_inspector_only(ObjectID p_object) {
-
_add_object(p_object, "", -1, true);
}
void EditorHistory::add_object(ObjectID p_object) {
-
_add_object(p_object, "", -1);
}
void EditorHistory::add_object(ObjectID p_object, const String &p_subprop) {
-
_add_object(p_object, p_subprop, -1);
}
void EditorHistory::add_object(ObjectID p_object, int p_relevel) {
-
_add_object(p_object, "", p_relevel);
}
int EditorHistory::get_history_len() {
return history.size();
}
+
int EditorHistory::get_history_pos() {
return current;
}
bool EditorHistory::is_history_obj_inspector_only(int p_obj) const {
-
ERR_FAIL_INDEX_V(p_obj, history.size(), false);
ERR_FAIL_INDEX_V(history[p_obj].level, history[p_obj].path.size(), false);
return history[p_obj].path[history[p_obj].level].inspector_only;
@@ -164,85 +162,88 @@ ObjectID EditorHistory::get_history_obj(int p_obj) const {
bool EditorHistory::is_at_beginning() const {
return current <= 0;
}
-bool EditorHistory::is_at_end() const {
+bool EditorHistory::is_at_end() const {
return ((current + 1) >= history.size());
}
bool EditorHistory::next() {
-
cleanup_history();
- if ((current + 1) < history.size())
+ if ((current + 1) < history.size()) {
current++;
- else
+ } else {
return false;
+ }
return true;
}
bool EditorHistory::previous() {
-
cleanup_history();
- if (current > 0)
+ if (current > 0) {
current--;
- else
+ } else {
return false;
+ }
return true;
}
bool EditorHistory::is_current_inspector_only() const {
-
- if (current < 0 || current >= history.size())
+ if (current < 0 || current >= history.size()) {
return false;
+ }
const History &h = history[current];
return h.path[h.level].inspector_only;
}
-ObjectID EditorHistory::get_current() {
- if (current < 0 || current >= history.size())
+ObjectID EditorHistory::get_current() {
+ if (current < 0 || current >= history.size()) {
return ObjectID();
+ }
History &h = history.write[current];
Object *obj = ObjectDB::get_instance(h.path[h.level].object);
- if (!obj)
+ if (!obj) {
return ObjectID();
+ }
return obj->get_instance_id();
}
int EditorHistory::get_path_size() const {
-
- if (current < 0 || current >= history.size())
+ if (current < 0 || current >= history.size()) {
return 0;
+ }
const History &h = history[current];
return h.path.size();
}
ObjectID EditorHistory::get_path_object(int p_index) const {
-
- if (current < 0 || current >= history.size())
+ if (current < 0 || current >= history.size()) {
return ObjectID();
+ }
const History &h = history[current];
ERR_FAIL_INDEX_V(p_index, h.path.size(), ObjectID());
Object *obj = ObjectDB::get_instance(h.path[p_index].object);
- if (!obj)
+ if (!obj) {
return ObjectID();
+ }
return obj->get_instance_id();
}
String EditorHistory::get_path_property(int p_index) const {
-
- if (current < 0 || current >= history.size())
+ if (current < 0 || current >= history.size()) {
return "";
+ }
const History &h = history[current];
@@ -252,33 +253,29 @@ String EditorHistory::get_path_property(int p_index) const {
}
void EditorHistory::clear() {
-
history.clear();
current = -1;
}
EditorHistory::EditorHistory() {
-
current = -1;
}
EditorPlugin *EditorData::get_editor(Object *p_object) {
-
for (int i = 0; i < editor_plugins.size(); i++) {
-
- if (editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object))
+ if (editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object)) {
return editor_plugins[i];
+ }
}
return nullptr;
}
EditorPlugin *EditorData::get_subeditor(Object *p_object) {
-
for (int i = 0; i < editor_plugins.size(); i++) {
-
- if (!editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object))
+ if (!editor_plugins[i]->has_main_screen() && editor_plugins[i]->handles(p_object)) {
return editor_plugins[i];
+ }
}
return nullptr;
@@ -295,27 +292,25 @@ Vector<EditorPlugin *> EditorData::get_subeditors(Object *p_object) {
}
EditorPlugin *EditorData::get_editor(String p_name) {
-
for (int i = 0; i < editor_plugins.size(); i++) {
-
- if (editor_plugins[i]->get_name() == p_name)
+ if (editor_plugins[i]->get_name() == p_name) {
return editor_plugins[i];
+ }
}
return nullptr;
}
void EditorData::copy_object_params(Object *p_object) {
-
clipboard.clear();
List<PropertyInfo> pinfo;
p_object->get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_EDITOR) || E->get().name == "script" || E->get().name == "scripts")
+ if (!(E->get().usage & PROPERTY_USAGE_EDITOR) || E->get().name == "script" || E->get().name == "scripts") {
continue;
+ }
PropertyData pd;
pd.name = E->get().name;
@@ -325,21 +320,18 @@ void EditorData::copy_object_params(Object *p_object) {
}
void EditorData::get_editor_breakpoints(List<String> *p_breakpoints) {
-
for (int i = 0; i < editor_plugins.size(); i++) {
-
editor_plugins[i]->get_breakpoints(p_breakpoints);
}
}
Dictionary EditorData::get_editor_states() const {
-
Dictionary metadata;
for (int i = 0; i < editor_plugins.size(); i++) {
-
Dictionary state = editor_plugins[i]->get_state();
- if (state.empty())
+ if (state.empty()) {
continue;
+ }
metadata[editor_plugins[i]->get_name()] = state;
}
@@ -353,88 +345,71 @@ Dictionary EditorData::get_scene_editor_states(int p_idx) const {
}
void EditorData::set_editor_states(const Dictionary &p_states) {
-
List<Variant> keys;
p_states.get_key_list(&keys);
List<Variant>::Element *E = keys.front();
for (; E; E = E->next()) {
-
String name = E->get();
int idx = -1;
for (int i = 0; i < editor_plugins.size(); i++) {
-
if (editor_plugins[i]->get_name() == name) {
idx = i;
break;
}
}
- if (idx == -1)
+ if (idx == -1) {
continue;
+ }
editor_plugins[idx]->set_state(p_states[name]);
}
}
void EditorData::notify_edited_scene_changed() {
-
for (int i = 0; i < editor_plugins.size(); i++) {
-
editor_plugins[i]->edited_scene_changed();
editor_plugins[i]->notify_scene_changed(get_edited_scene_root());
}
}
void EditorData::notify_resource_saved(const Ref<Resource> &p_resource) {
-
for (int i = 0; i < editor_plugins.size(); i++) {
-
editor_plugins[i]->notify_resource_saved(p_resource);
}
}
void EditorData::clear_editor_states() {
-
for (int i = 0; i < editor_plugins.size(); i++) {
-
editor_plugins[i]->clear();
}
}
void EditorData::save_editor_external_data() {
-
for (int i = 0; i < editor_plugins.size(); i++) {
-
editor_plugins[i]->save_external_data();
}
}
void EditorData::apply_changes_in_editors() {
-
for (int i = 0; i < editor_plugins.size(); i++) {
-
editor_plugins[i]->apply_changes();
}
}
void EditorData::save_editor_global_states() {
-
for (int i = 0; i < editor_plugins.size(); i++) {
-
editor_plugins[i]->save_global_state();
}
}
void EditorData::restore_editor_global_states() {
-
for (int i = 0; i < editor_plugins.size(); i++) {
-
editor_plugins[i]->restore_global_state();
}
}
void EditorData::paste_object_params(Object *p_object) {
-
ERR_FAIL_NULL(p_object);
undo_redo.create_action(TTR("Paste Params"));
for (List<PropertyData>::Element *E = clipboard.front(); E; E = E->next()) {
@@ -446,11 +421,9 @@ void EditorData::paste_object_params(Object *p_object) {
}
bool EditorData::call_build() {
-
bool result = true;
for (int i = 0; i < editor_plugins.size() && result; i++) {
-
result &= editor_plugins[i]->build();
}
@@ -458,18 +431,15 @@ bool EditorData::call_build() {
}
UndoRedo &EditorData::get_undo_redo() {
-
return undo_redo;
}
void EditorData::remove_editor_plugin(EditorPlugin *p_plugin) {
-
p_plugin->undo_redo = nullptr;
editor_plugins.erase(p_plugin);
}
void EditorData::add_editor_plugin(EditorPlugin *p_plugin) {
-
p_plugin->undo_redo = &undo_redo;
editor_plugins.push_back(p_plugin);
}
@@ -477,14 +447,13 @@ void EditorData::add_editor_plugin(EditorPlugin *p_plugin) {
int EditorData::get_editor_plugin_count() const {
return editor_plugins.size();
}
-EditorPlugin *EditorData::get_editor_plugin(int p_idx) {
+EditorPlugin *EditorData::get_editor_plugin(int p_idx) {
ERR_FAIL_INDEX_V(p_idx, editor_plugins.size(), nullptr);
return editor_plugins[p_idx];
}
void EditorData::add_custom_type(const String &p_type, const String &p_inherits, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon) {
-
ERR_FAIL_COND_MSG(p_script.is_null(), "It's not a reference to a valid Script object.");
CustomType ct;
ct.name = p_type;
@@ -498,9 +467,7 @@ void EditorData::add_custom_type(const String &p_type, const String &p_inherits,
}
Object *EditorData::instance_custom_type(const String &p_type, const String &p_inherits) {
-
if (get_custom_types().has(p_inherits)) {
-
for (int i = 0; i < get_custom_types()[p_inherits].size(); i++) {
if (get_custom_types()[p_inherits][i].name == p_type) {
Ref<Script> script = get_custom_types()[p_inherits][i].script;
@@ -520,9 +487,7 @@ Object *EditorData::instance_custom_type(const String &p_type, const String &p_i
}
void EditorData::remove_custom_type(const String &p_type) {
-
for (Map<String, Vector<CustomType>>::Element *E = custom_types.front(); E; E = E->next()) {
-
for (int i = 0; i < E->get().size(); i++) {
if (E->get()[i].name == p_type) {
E->get().remove(i);
@@ -536,9 +501,9 @@ void EditorData::remove_custom_type(const String &p_type) {
}
int EditorData::add_edited_scene(int p_at_pos) {
-
- if (p_at_pos < 0)
+ if (p_at_pos < 0) {
p_at_pos = edited_scene.size();
+ }
EditedScene es;
es.root = nullptr;
es.path = String();
@@ -546,18 +511,19 @@ int EditorData::add_edited_scene(int p_at_pos) {
es.version = 0;
es.live_edit_root = NodePath(String("/root"));
- if (p_at_pos == edited_scene.size())
+ if (p_at_pos == edited_scene.size()) {
edited_scene.push_back(es);
- else
+ } else {
edited_scene.insert(p_at_pos, es);
+ }
- if (current_edited_scene < 0)
+ if (current_edited_scene < 0) {
current_edited_scene = 0;
+ }
return p_at_pos;
}
void EditorData::move_edited_scene_index(int p_idx, int p_to_idx) {
-
ERR_FAIL_INDEX(p_idx, edited_scene.size());
ERR_FAIL_INDEX(p_to_idx, edited_scene.size());
SWAP(edited_scene.write[p_idx], edited_scene.write[p_to_idx]);
@@ -566,7 +532,6 @@ void EditorData::move_edited_scene_index(int p_idx, int p_to_idx) {
void EditorData::remove_scene(int p_idx) {
ERR_FAIL_INDEX(p_idx, edited_scene.size());
if (edited_scene[p_idx].root) {
-
for (int i = 0; i < editor_plugins.size(); i++) {
editor_plugins[i]->notify_scene_closed(edited_scene[p_idx].root->get_filename());
}
@@ -574,9 +539,9 @@ void EditorData::remove_scene(int p_idx) {
memdelete(edited_scene[p_idx].root);
}
- if (current_edited_scene > p_idx)
+ if (current_edited_scene > p_idx) {
current_edited_scene--;
- else if (current_edited_scene == p_idx && current_edited_scene > 0) {
+ } else if (current_edited_scene == p_idx && current_edited_scene > 0) {
current_edited_scene--;
}
@@ -584,7 +549,6 @@ void EditorData::remove_scene(int p_idx) {
}
bool EditorData::_find_updated_instances(Node *p_root, Node *p_node, Set<String> &checked_paths) {
-
/*
if (p_root!=p_node && p_node->get_owner()!=p_root && !p_root->is_editable_instance(p_node->get_owner()))
return false;
@@ -602,7 +566,6 @@ bool EditorData::_find_updated_instances(Node *p_root, Node *p_node, Set<String>
String path = ss->get_path();
if (!checked_paths.has(path)) {
-
uint64_t modified_time = FileAccess::get_modified_time(path);
if (modified_time != ss->get_last_modified_time()) {
return true; //external scene changed
@@ -613,20 +576,20 @@ bool EditorData::_find_updated_instances(Node *p_root, Node *p_node, Set<String>
}
for (int i = 0; i < p_node->get_child_count(); i++) {
-
bool found = _find_updated_instances(p_root, p_node->get_child(i), checked_paths);
- if (found)
+ if (found) {
return true;
+ }
}
return false;
}
bool EditorData::check_and_update_scene(int p_idx) {
-
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), false);
- if (!edited_scene[p_idx].root)
+ if (!edited_scene[p_idx].root) {
return false;
+ }
Set<String> checked_scenes;
@@ -650,16 +613,18 @@ bool EditorData::check_and_update_scene(int p_idx) {
for (List<Node *>::Element *E = edited_scene.write[p_idx].selection.front(); E; E = E->next()) {
NodePath p = edited_scene[p_idx].root->get_path_to(E->get());
Node *new_node = new_scene->get_node(p);
- if (new_node)
+ if (new_node) {
new_selection.push_back(new_node);
+ }
}
new_scene->set_filename(edited_scene[p_idx].root->get_filename());
memdelete(edited_scene[p_idx].root);
edited_scene.write[p_idx].root = new_scene;
- if (new_scene->get_filename() != "")
+ if (new_scene->get_filename() != "") {
edited_scene.write[p_idx].path = new_scene->get_filename();
+ }
edited_scene.write[p_idx].selection = new_selection;
return true;
@@ -669,15 +634,15 @@ bool EditorData::check_and_update_scene(int p_idx) {
}
int EditorData::get_edited_scene() const {
-
return current_edited_scene;
}
-void EditorData::set_edited_scene(int p_idx) {
+void EditorData::set_edited_scene(int p_idx) {
ERR_FAIL_INDEX(p_idx, edited_scene.size());
current_edited_scene = p_idx;
//swap
}
+
Node *EditorData::get_edited_scene_root(int p_idx) {
if (p_idx < 0) {
ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), nullptr);
@@ -687,25 +652,24 @@ Node *EditorData::get_edited_scene_root(int p_idx) {
return edited_scene[p_idx].root;
}
}
-void EditorData::set_edited_scene_root(Node *p_root) {
+void EditorData::set_edited_scene_root(Node *p_root) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
edited_scene.write[current_edited_scene].root = p_root;
if (p_root) {
- if (p_root->get_filename() != "")
+ if (p_root->get_filename() != "") {
edited_scene.write[current_edited_scene].path = p_root->get_filename();
- else
+ } else {
p_root->set_filename(edited_scene[current_edited_scene].path);
+ }
}
}
int EditorData::get_edited_scene_count() const {
-
return edited_scene.size();
}
Vector<EditorData::EditedScene> EditorData::get_edited_scenes() const {
-
Vector<EditedScene> out_edited_scenes_list = Vector<EditedScene>();
for (int i = 0; i < edited_scene.size(); i++) {
@@ -726,24 +690,24 @@ void EditorData::set_edited_scene_version(uint64_t version, int p_scene_idx) {
}
uint64_t EditorData::get_edited_scene_version() const {
-
ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), 0);
return edited_scene[current_edited_scene].version;
}
+
uint64_t EditorData::get_scene_version(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), 0);
return edited_scene[p_idx].version;
}
String EditorData::get_scene_type(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String());
- if (!edited_scene[p_idx].root)
+ if (!edited_scene[p_idx].root) {
return "";
+ }
return edited_scene[p_idx].root->get_class();
}
-void EditorData::move_edited_scene_to_index(int p_idx) {
+void EditorData::move_edited_scene_to_index(int p_idx) {
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
ERR_FAIL_INDEX(p_idx, edited_scene.size());
@@ -754,10 +718,10 @@ void EditorData::move_edited_scene_to_index(int p_idx) {
}
Ref<Script> EditorData::get_scene_root_script(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), Ref<Script>());
- if (!edited_scene[p_idx].root)
+ if (!edited_scene[p_idx].root) {
return Ref<Script>();
+ }
Ref<Script> s = edited_scene[p_idx].root->get_script();
if (!s.is_valid() && edited_scene[p_idx].root->get_child_count()) {
Node *n = edited_scene[p_idx].root->get_child(0);
@@ -771,10 +735,12 @@ Ref<Script> EditorData::get_scene_root_script(int p_idx) const {
String EditorData::get_scene_title(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String());
- if (!edited_scene[p_idx].root)
+ if (!edited_scene[p_idx].root) {
return TTR("[empty]");
- if (edited_scene[p_idx].root->get_filename() == "")
+ }
+ if (edited_scene[p_idx].root->get_filename() == "") {
return TTR("[unsaved]");
+ }
bool show_ext = EDITOR_DEF("interface/scene_tabs/show_extension", false);
String name = edited_scene[p_idx].root->get_filename().get_file();
if (!show_ext) {
@@ -784,24 +750,24 @@ String EditorData::get_scene_title(int p_idx) const {
}
void EditorData::set_scene_path(int p_idx, const String &p_path) {
-
ERR_FAIL_INDEX(p_idx, edited_scene.size());
edited_scene.write[p_idx].path = p_path;
- if (!edited_scene[p_idx].root)
+ if (!edited_scene[p_idx].root) {
return;
+ }
edited_scene[p_idx].root->set_filename(p_path);
}
String EditorData::get_scene_path(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String());
if (edited_scene[p_idx].root) {
- if (edited_scene[p_idx].root->get_filename() == "")
+ if (edited_scene[p_idx].root->get_filename() == "") {
edited_scene[p_idx].root->set_filename(edited_scene[p_idx].path);
- else
+ } else {
return edited_scene[p_idx].root->get_filename();
+ }
}
return edited_scene[p_idx].path;
@@ -812,15 +778,14 @@ void EditorData::set_edited_scene_live_edit_root(const NodePath &p_root) {
edited_scene.write[current_edited_scene].live_edit_root = p_root;
}
-NodePath EditorData::get_edited_scene_live_edit_root() {
+NodePath EditorData::get_edited_scene_live_edit_root() {
ERR_FAIL_INDEX_V(current_edited_scene, edited_scene.size(), String());
return edited_scene[current_edited_scene].live_edit_root;
}
void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history, const Dictionary &p_custom) {
-
ERR_FAIL_INDEX(current_edited_scene, edited_scene.size());
EditedScene &es = edited_scene.write[current_edited_scene];
@@ -849,7 +814,6 @@ Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection,
}
void EditorData::clear_edited_scenes() {
-
for (int i = 0; i < edited_scene.size(); i++) {
if (edited_scene[i].root) {
memdelete(edited_scene[i].root);
@@ -871,8 +835,9 @@ void EditorData::get_plugin_window_layout(Ref<ConfigFile> p_layout) {
}
bool EditorData::script_class_is_parent(const String &p_class, const String &p_inherits) {
- if (!ScriptServer::is_global_class(p_class))
+ if (!ScriptServer::is_global_class(p_class)) {
return false;
+ }
String base = script_class_get_base(p_class);
Ref<Script> script = script_class_load_script(p_class);
Ref<Script> base_script = script->get_base_script();
@@ -892,10 +857,10 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i
}
StringName EditorData::script_class_get_base(const String &p_class) const {
-
Ref<Script> script = script_class_load_script(p_class);
- if (script.is_null())
+ if (script.is_null()) {
return StringName();
+ }
Ref<Script> base_script = script->get_base_script();
if (base_script.is_null()) {
@@ -910,8 +875,9 @@ Object *EditorData::script_class_instance(const String &p_class) {
Object *obj = ClassDB::instance(ScriptServer::get_global_class_native_base(p_class));
if (obj) {
Ref<Script> script = script_class_load_script(p_class);
- if (script.is_valid())
+ if (script.is_valid()) {
obj->set_script(script);
+ }
return obj;
}
}
@@ -919,9 +885,9 @@ Object *EditorData::script_class_instance(const String &p_class) {
}
Ref<Script> EditorData::script_class_load_script(const String &p_class) const {
-
- if (!ScriptServer::is_global_class(p_class))
+ if (!ScriptServer::is_global_class(p_class)) {
return Ref<Script>();
+ }
String path = ScriptServer::get_global_class_path(p_class);
return ResourceLoader::load(path, "Script");
@@ -932,15 +898,17 @@ void EditorData::script_class_set_icon_path(const String &p_class, const String
}
String EditorData::script_class_get_icon_path(const String &p_class) const {
- if (!ScriptServer::is_global_class(p_class))
+ if (!ScriptServer::is_global_class(p_class)) {
return String();
+ }
String current = p_class;
String ret = _script_class_icon_paths[current];
while (ret.empty()) {
current = script_class_get_base(current);
- if (!ScriptServer::is_global_class(current))
+ if (!ScriptServer::is_global_class(current)) {
return String();
+ }
ret = _script_class_icon_paths.has(current) ? _script_class_icon_paths[current] : String();
}
@@ -961,8 +929,9 @@ void EditorData::script_class_save_icon_paths() {
Dictionary d;
for (List<StringName>::Element *E = keys.front(); E; E = E->next()) {
- if (ScriptServer::is_global_class(E->get()))
+ if (ScriptServer::is_global_class(E->get())) {
d[E->get()] = _script_class_icon_paths[E->get()];
+ }
}
ProjectSettings::get_singleton()->set("_global_script_class_icons", d);
@@ -988,7 +957,6 @@ void EditorData::script_class_load_icon_paths() {
}
EditorData::EditorData() {
-
current_edited_scene = -1;
//load_imported_scenes_from_globals();
@@ -997,30 +965,30 @@ EditorData::EditorData() {
///////////
void EditorSelection::_node_removed(Node *p_node) {
-
- if (!selection.has(p_node))
+ if (!selection.has(p_node)) {
return;
+ }
Object *meta = selection[p_node];
- if (meta)
+ if (meta) {
memdelete(meta);
+ }
selection.erase(p_node);
changed = true;
nl_changed = true;
}
void EditorSelection::add_node(Node *p_node) {
-
ERR_FAIL_NULL(p_node);
ERR_FAIL_COND(!p_node->is_inside_tree());
- if (selection.has(p_node))
+ if (selection.has(p_node)) {
return;
+ }
changed = true;
nl_changed = true;
Object *meta = nullptr;
for (List<Object *>::Element *E = editor_plugins.front(); E; E = E->next()) {
-
meta = E->get()->call("_get_editor_data", p_node);
if (meta) {
break;
@@ -1034,44 +1002,41 @@ void EditorSelection::add_node(Node *p_node) {
}
void EditorSelection::remove_node(Node *p_node) {
-
ERR_FAIL_NULL(p_node);
- if (!selection.has(p_node))
+ if (!selection.has(p_node)) {
return;
+ }
changed = true;
nl_changed = true;
Object *meta = selection[p_node];
- if (meta)
+ if (meta) {
memdelete(meta);
+ }
selection.erase(p_node);
p_node->disconnect("tree_exiting", callable_mp(this, &EditorSelection::_node_removed));
//emit_signal("selection_changed");
}
-bool EditorSelection::is_selected(Node *p_node) const {
+bool EditorSelection::is_selected(Node *p_node) const {
return selection.has(p_node);
}
Array EditorSelection::_get_transformable_selected_nodes() {
-
Array ret;
for (List<Node *>::Element *E = selected_node_list.front(); E; E = E->next()) {
-
ret.push_back(E->get());
}
return ret;
}
-Array EditorSelection::get_selected_nodes() {
-
- Array ret;
+TypedArray<Node> EditorSelection::get_selected_nodes() {
+ TypedArray<Node> ret;
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
-
ret.push_back(E->key());
}
@@ -1079,7 +1044,6 @@ Array EditorSelection::get_selected_nodes() {
}
void EditorSelection::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("clear"), &EditorSelection::clear);
ClassDB::bind_method(D_METHOD("add_node", "node"), &EditorSelection::add_node);
ClassDB::bind_method(D_METHOD("remove_node", "node"), &EditorSelection::remove_node);
@@ -1090,19 +1054,17 @@ void EditorSelection::_bind_methods() {
}
void EditorSelection::add_editor_plugin(Object *p_object) {
-
editor_plugins.push_back(p_object);
}
void EditorSelection::_update_nl() {
-
- if (!nl_changed)
+ if (!nl_changed) {
return;
+ }
selected_node_list.clear();
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
-
Node *parent = E->key();
parent = parent->get_parent();
bool skip = false;
@@ -1114,8 +1076,9 @@ void EditorSelection::_update_nl() {
parent = parent->get_parent();
}
- if (skip)
+ if (skip) {
continue;
+ }
selected_node_list.push_back(E->key());
}
@@ -1123,11 +1086,11 @@ void EditorSelection::_update_nl() {
}
void EditorSelection::update() {
-
_update_nl();
- if (!changed)
+ if (!changed) {
return;
+ }
changed = false;
if (!emitted) {
emitted = true;
@@ -1141,16 +1104,15 @@ void EditorSelection::_emit_change() {
}
List<Node *> &EditorSelection::get_selected_node_list() {
-
- if (changed)
+ if (changed) {
update();
- else
+ } else {
_update_nl();
+ }
return selected_node_list;
}
List<Node *> EditorSelection::get_full_selected_node_list() {
-
List<Node *> node_list;
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
node_list.push_back(E->key());
@@ -1160,23 +1122,20 @@ List<Node *> EditorSelection::get_full_selected_node_list() {
}
void EditorSelection::clear() {
-
while (!selection.empty()) {
-
remove_node(selection.front()->key());
}
changed = true;
nl_changed = true;
}
-EditorSelection::EditorSelection() {
+EditorSelection::EditorSelection() {
emitted = false;
changed = false;
nl_changed = false;
}
EditorSelection::~EditorSelection() {
-
clear();
}
diff --git a/editor/editor_data.h b/editor/editor_data.h
index 4f5d68bfed..8083dde09c 100644
--- a/editor/editor_data.h
+++ b/editor/editor_data.h
@@ -39,14 +39,12 @@
#include "scene/resources/texture.h"
class EditorHistory {
-
enum {
HISTORY_MAX = 64
};
struct Obj {
-
REF ref;
ObjectID object;
String property;
@@ -54,7 +52,6 @@ class EditorHistory {
};
struct History {
-
Vector<Obj> path;
int level;
};
@@ -66,7 +63,6 @@ class EditorHistory {
//Vector<EditorPlugin*> editor_plugins;
struct PropertyData {
-
String name;
Variant value;
};
@@ -106,10 +102,8 @@ public:
class EditorSelection;
class EditorData {
-
public:
struct CustomType {
-
String name;
Ref<Script> script;
Ref<Texture2D> icon;
@@ -131,7 +125,6 @@ private:
Vector<EditorPlugin *> editor_plugins;
struct PropertyData {
-
String name;
Variant value;
};
@@ -234,7 +227,6 @@ public:
};
class EditorSelection : public Object {
-
GDCLASS(EditorSelection, Object);
private:
@@ -257,15 +249,16 @@ protected:
static void _bind_methods();
public:
- Array get_selected_nodes();
+ TypedArray<Node> get_selected_nodes();
void add_node(Node *p_node);
void remove_node(Node *p_node);
bool is_selected(Node *) const;
template <class T>
T *get_node_editor_data(Node *p_node) {
- if (!selection.has(p_node))
+ if (!selection.has(p_node)) {
return nullptr;
+ }
return Object::cast_to<T>(selection[p_node]);
}
diff --git a/editor/editor_dir_dialog.cpp b/editor/editor_dir_dialog.cpp
index cb87656382..3c1c3c8a86 100644
--- a/editor/editor_dir_dialog.cpp
+++ b/editor/editor_dir_dialog.cpp
@@ -38,7 +38,6 @@
#include "servers/display_server.h"
void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p_dir, const String &p_select_path) {
-
updating = true;
String path = p_dir->get_path();
@@ -49,7 +48,6 @@ void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p
if (!p_item->get_parent()) {
p_item->set_text(0, "res://");
} else {
-
if (!opened_paths.has(path) && (p_select_path == String() || !p_select_path.begins_with(path))) {
p_item->set_collapsed(true);
}
@@ -61,14 +59,12 @@ void EditorDirDialog::_update_dir(TreeItem *p_item, EditorFileSystemDirectory *p
//bool show_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files");
updating = false;
for (int i = 0; i < p_dir->get_subdir_count(); i++) {
-
TreeItem *ti = tree->create_item(p_item);
_update_dir(ti, p_dir->get_subdir(i));
}
}
void EditorDirDialog::reload(const String &p_path) {
-
if (!is_visible()) {
must_reload = true;
return;
@@ -82,7 +78,6 @@ void EditorDirDialog::reload(const String &p_path) {
}
void EditorDirDialog::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &EditorDirDialog::reload), make_binds(""));
reload();
@@ -110,16 +105,17 @@ void EditorDirDialog::_notification(int p_what) {
}
void EditorDirDialog::_item_collapsed(Object *p_item) {
-
TreeItem *item = Object::cast_to<TreeItem>(p_item);
- if (updating)
+ if (updating) {
return;
+ }
- if (item->is_collapsed())
+ if (item->is_collapsed()) {
opened_paths.erase(item->get_metadata(0));
- else
+ } else {
opened_paths.insert(item->get_metadata(0));
+ }
}
void EditorDirDialog::_item_activated() {
@@ -127,10 +123,10 @@ void EditorDirDialog::_item_activated() {
}
void EditorDirDialog::ok_pressed() {
-
TreeItem *ti = tree->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
String dir = ti->get_metadata(0);
emit_signal("dir_selected", dir);
@@ -138,7 +134,6 @@ void EditorDirDialog::ok_pressed() {
}
void EditorDirDialog::_make_dir() {
-
TreeItem *ti = tree->get_selected();
if (!ti) {
mkdirerr->set_text(TTR("Please select a base directory first."));
@@ -151,10 +146,10 @@ void EditorDirDialog::_make_dir() {
}
void EditorDirDialog::_make_dir_confirm() {
-
TreeItem *ti = tree->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
String dir = ti->get_metadata(0);
@@ -173,12 +168,10 @@ void EditorDirDialog::_make_dir_confirm() {
}
void EditorDirDialog::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("dir_selected", PropertyInfo(Variant::STRING, "dir")));
}
EditorDirDialog::EditorDirDialog() {
-
updating = false;
set_title(TTR("Choose a Directory"));
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index e8167070d4..716ead9afc 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -48,7 +48,6 @@
#include "scene/resources/resource_format_text.h"
static int _get_pad(int p_alignment, int p_n) {
-
int rest = p_n % p_alignment;
int pad = 0;
if (rest > 0) {
@@ -61,7 +60,6 @@ static int _get_pad(int p_alignment, int p_n) {
#define PCK_PADDING 16
bool EditorExportPreset::_set(const StringName &p_name, const Variant &p_value) {
-
if (values.has(p_name)) {
values[p_name] = p_value;
EditorExport::singleton->save_presets();
@@ -72,7 +70,6 @@ bool EditorExportPreset::_set(const StringName &p_name, const Variant &p_value)
}
bool EditorExportPreset::_get(const StringName &p_name, Variant &r_ret) const {
-
if (values.has(p_name)) {
r_ret = values[p_name];
return true;
@@ -82,9 +79,7 @@ bool EditorExportPreset::_get(const StringName &p_name, Variant &r_ret) const {
}
void EditorExportPreset::_get_property_list(List<PropertyInfo> *p_list) const {
-
for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
-
if (platform->get_option_visibility(E->get().name, values)) {
p_list->push_back(E->get());
}
@@ -92,12 +87,10 @@ void EditorExportPreset::_get_property_list(List<PropertyInfo> *p_list) const {
}
Ref<EditorExportPlatform> EditorExportPreset::get_platform() const {
-
return platform;
}
Vector<String> EditorExportPreset::get_files_to_export() const {
-
Vector<String> files;
for (Set<String>::Element *E = selected_files.front(); E; E = E->next()) {
files.push_back(E->get());
@@ -115,18 +108,15 @@ String EditorExportPreset::get_name() const {
}
void EditorExportPreset::set_runnable(bool p_enable) {
-
runnable = p_enable;
EditorExport::singleton->save_presets();
}
bool EditorExportPreset::is_runnable() const {
-
return runnable;
}
void EditorExportPreset::set_export_filter(ExportFilter p_filter) {
-
export_filter = p_filter;
EditorExport::singleton->save_presets();
}
@@ -136,18 +126,15 @@ EditorExportPreset::ExportFilter EditorExportPreset::get_export_filter() const {
}
void EditorExportPreset::set_include_filter(const String &p_include) {
-
include_filter = p_include;
EditorExport::singleton->save_presets();
}
String EditorExportPreset::get_include_filter() const {
-
return include_filter;
}
void EditorExportPreset::set_export_path(const String &p_path) {
-
export_path = p_path;
/* NOTE(SonerSound): if there is a need to implement a PropertyHint that specifically indicates a relative path,
* this should be removed. */
@@ -159,23 +146,19 @@ void EditorExportPreset::set_export_path(const String &p_path) {
}
String EditorExportPreset::get_export_path() const {
-
return export_path;
}
void EditorExportPreset::set_exclude_filter(const String &p_exclude) {
-
exclude_filter = p_exclude;
EditorExport::singleton->save_presets();
}
String EditorExportPreset::get_exclude_filter() const {
-
return exclude_filter;
}
void EditorExportPreset::add_export_file(const String &p_path) {
-
selected_files.insert(p_path);
EditorExport::singleton->save_presets();
}
@@ -186,16 +169,15 @@ void EditorExportPreset::remove_export_file(const String &p_path) {
}
bool EditorExportPreset::has_export_file(const String &p_path) {
-
return selected_files.has(p_path);
}
void EditorExportPreset::add_patch(const String &p_path, int p_at_pos) {
-
- if (p_at_pos < 0)
+ if (p_at_pos < 0) {
patches.push_back(p_path);
- else
+ } else {
patches.insert(p_at_pos, p_path);
+ }
EditorExport::singleton->save_presets();
}
@@ -209,8 +191,8 @@ void EditorExportPreset::set_patch(int p_index, const String &p_path) {
patches.write[p_index] = p_path;
EditorExport::singleton->save_presets();
}
-String EditorExportPreset::get_patch(int p_index) {
+String EditorExportPreset::get_patch(int p_index) {
ERR_FAIL_INDEX_V(p_index, patches.size(), String());
return patches[p_index];
}
@@ -220,54 +202,41 @@ Vector<String> EditorExportPreset::get_patches() const {
}
void EditorExportPreset::set_custom_features(const String &p_custom_features) {
-
custom_features = p_custom_features;
EditorExport::singleton->save_presets();
}
String EditorExportPreset::get_custom_features() const {
-
return custom_features;
}
void EditorExportPreset::set_script_export_mode(int p_mode) {
-
script_mode = p_mode;
EditorExport::singleton->save_presets();
}
int EditorExportPreset::get_script_export_mode() const {
-
return script_mode;
}
void EditorExportPreset::set_script_encryption_key(const String &p_key) {
-
script_key = p_key;
EditorExport::singleton->save_presets();
}
String EditorExportPreset::get_script_encryption_key() const {
-
return script_key;
}
-EditorExportPreset::EditorExportPreset() :
- export_filter(EXPORT_ALL_RESOURCES),
- export_path(""),
- runnable(false),
- script_mode(MODE_SCRIPT_COMPILED) {
-}
-
///////////////////////////////////
void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags) {
-
String host = EditorSettings::get_singleton()->get("network/debug/remote_host");
int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
- if (p_flags & DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST)
+ if (p_flags & DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST) {
host = "localhost";
+ }
if (p_flags & DEBUG_FLAG_DUMB_CLIENT) {
int port = EditorSettings::get_singleton()->get("filesystem/file_server/port");
@@ -281,23 +250,21 @@ void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags)
}
if (p_flags & DEBUG_FLAG_REMOTE_DEBUG) {
-
r_flags.push_back("--remote-debug");
- r_flags.push_back(host + ":" + String::num(remote_port));
+ r_flags.push_back(get_debug_protocol() + host + ":" + String::num(remote_port));
List<String> breakpoints;
ScriptEditor::get_singleton()->get_breakpoints(&breakpoints);
if (breakpoints.size()) {
-
r_flags.push_back("--breakpoints");
String bpoints;
for (const List<String>::Element *E = breakpoints.front(); E; E = E->next()) {
-
bpoints += E->get().replace(" ", "%20");
- if (E->next())
+ if (E->next()) {
bpoints += ",";
+ }
}
r_flags.push_back(bpoints);
@@ -305,18 +272,15 @@ void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags)
}
if (p_flags & DEBUG_FLAG_VIEW_COLLISONS) {
-
r_flags.push_back("--debug-collisions");
}
if (p_flags & DEBUG_FLAG_VIEW_NAVIGATION) {
-
r_flags.push_back("--debug-navigation");
}
}
Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
-
PackData *pd = (PackData *)p_userdata;
SavedData sd;
@@ -349,7 +313,6 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa
}
Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
-
String path = p_path.replace_first("res://", "");
ZipData *zd = (ZipData *)p_userdata;
@@ -384,7 +347,6 @@ Ref<ImageTexture> EditorExportPlatform::get_option_icon(int p_index) const {
}
String EditorExportPlatform::find_export_template(String template_file_name, String *err) const {
-
String current_version = VERSION_FULL_CONFIG;
String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(current_version).plus_file(template_file_name);
@@ -404,7 +366,6 @@ bool EditorExportPlatform::exists_export_template(String template_file_name, Str
}
Ref<EditorExportPreset> EditorExportPlatform::create_preset() {
-
Ref<EditorExportPreset> preset;
preset.instance();
preset->platform = Ref<EditorExportPlatform>(this);
@@ -413,7 +374,6 @@ Ref<EditorExportPreset> EditorExportPlatform::create_preset() {
get_export_options(&options);
for (List<ExportOption>::Element *E = options.front(); E; E = E->next()) {
-
preset->properties.push_back(E->get().option);
preset->values[E->get().option.name] = E->get().default_value;
}
@@ -422,7 +382,6 @@ Ref<EditorExportPreset> EditorExportPlatform::create_preset() {
}
void EditorExportPlatform::_export_find_resources(EditorFileSystemDirectory *p_dir, Set<String> &p_paths) {
-
for (int i = 0; i < p_dir->get_subdir_count(); i++) {
_export_find_resources(p_dir->get_subdir(i), p_paths);
}
@@ -433,40 +392,40 @@ void EditorExportPlatform::_export_find_resources(EditorFileSystemDirectory *p_d
}
void EditorExportPlatform::_export_find_dependencies(const String &p_path, Set<String> &p_paths) {
-
- if (p_paths.has(p_path))
+ if (p_paths.has(p_path)) {
return;
+ }
p_paths.insert(p_path);
EditorFileSystemDirectory *dir;
int file_idx;
dir = EditorFileSystem::get_singleton()->find_file(p_path, &file_idx);
- if (!dir)
+ if (!dir) {
return;
+ }
Vector<String> deps = dir->get_file_deps(file_idx);
for (int i = 0; i < deps.size(); i++) {
-
_export_find_dependencies(deps[i], p_paths);
}
}
void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<String> &p_filters, Set<String> &r_list, bool exclude) {
-
da->list_dir_begin();
String cur_dir = da->get_current_dir().replace("\\", "/");
- if (!cur_dir.ends_with("/"))
+ if (!cur_dir.ends_with("/")) {
cur_dir += "/";
+ }
String cur_dir_no_prefix = cur_dir.replace("res://", "");
Vector<String> dirs;
String f;
while ((f = da->get_next()) != "") {
- if (da->current_is_dir())
+ if (da->current_is_dir()) {
dirs.push_back(f);
- else {
+ } else {
String fullpath = cur_dir + f;
// Test also against path without res:// so that filters like `file.txt` can work.
String fullpath_no_prefix = cur_dir_no_prefix + f;
@@ -486,8 +445,9 @@ void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<S
for (int i = 0; i < dirs.size(); ++i) {
String dir = dirs[i];
- if (dir.begins_with("."))
+ if (dir.begins_with(".")) {
continue;
+ }
da->change_dir(dir);
_edit_files_with_filter(da, p_filters, r_list, exclude);
da->change_dir("..");
@@ -495,15 +455,16 @@ void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<S
}
void EditorExportPlatform::_edit_filter_list(Set<String> &r_list, const String &p_filter, bool exclude) {
-
- if (p_filter == "")
+ if (p_filter == "") {
return;
+ }
Vector<String> split = p_filter.split(",");
Vector<String> filters;
for (int i = 0; i < split.size(); i++) {
String f = split[i].strip_edges();
- if (f.empty())
+ if (f.empty()) {
continue;
+ }
filters.push_back(f);
}
@@ -514,19 +475,16 @@ void EditorExportPlatform::_edit_filter_list(Set<String> &r_list, const String &
}
void EditorExportPlugin::set_export_preset(const Ref<EditorExportPreset> &p_preset) {
-
if (p_preset.is_valid()) {
export_preset = p_preset;
}
}
Ref<EditorExportPreset> EditorExportPlugin::get_export_preset() const {
-
return export_preset;
}
void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap) {
-
ExtraFile ef;
ef.data = p_file;
ef.path = p_path;
@@ -535,7 +493,6 @@ void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &p
}
void EditorExportPlugin::add_shared_object(const String &p_path, const Vector<String> &tags) {
-
shared_objects.push_back(SharedObject(p_path, tags));
}
@@ -591,21 +548,18 @@ Vector<String> EditorExportPlugin::get_ios_project_static_libs() const {
}
void EditorExportPlugin::_export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features) {
-
if (get_script_instance()) {
get_script_instance()->call("_export_file", p_path, p_type, p_features);
}
}
void EditorExportPlugin::_export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags) {
-
if (get_script_instance()) {
get_script_instance()->call("_export_begin", p_features, p_debug, p_path, p_flags);
}
}
void EditorExportPlugin::_export_end_script() {
-
if (get_script_instance()) {
get_script_instance()->call("_export_end");
}
@@ -618,12 +572,10 @@ void EditorExportPlugin::_export_begin(const Set<String> &p_features, bool p_deb
}
void EditorExportPlugin::skip() {
-
skipped = true;
}
void EditorExportPlugin::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags"), &EditorExportPlugin::add_shared_object);
ClassDB::bind_method(D_METHOD("add_ios_project_static_lib", "path"), &EditorExportPlugin::add_ios_project_static_lib);
ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file);
@@ -656,7 +608,6 @@ EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_contai
}
if (p_preset->get_custom_features() != String()) {
-
Vector<String> tmp_custom_list = p_preset->get_custom_features().split(",");
for (int i = 0; i < tmp_custom_list.size(); i++) {
@@ -707,8 +658,9 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
Vector<String> files = p_preset->get_files_to_export();
for (int i = 0; i < files.size(); i++) {
- if (scenes_only && ResourceLoader::get_resource_type(files[i]) != "PackedScene")
+ if (scenes_only && ResourceLoader::get_resource_type(files[i]) != "PackedScene") {
continue;
+ }
_export_find_dependencies(files[i], paths);
}
@@ -723,7 +675,6 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
for (int i = 0; i < export_plugins.size(); i++) {
-
export_plugins.write[i]->set_export_preset(p_preset);
if (p_so_func) {
@@ -747,7 +698,6 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
int total = paths.size();
for (Set<String>::Element *E = paths.front(); E; E = E->next()) {
-
String path = E->get();
String type = ResourceLoader::get_resource_type(path);
@@ -767,7 +717,6 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
Set<String> remap_features;
for (List<String>::Element *F = remaps.front(); F; F = F->next()) {
-
String remap = F->get();
String feature = remap.get_slice(".", 1);
if (features.has(feature)) {
@@ -782,7 +731,6 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
err = OK;
for (List<String>::Element *F = remaps.front(); F; F = F->next()) {
-
String remap = F->get();
if (remap == "path") {
String remapped_path = config->get_value("remap", remap);
@@ -812,7 +760,6 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
}
} else {
-
bool do_export = true;
for (int i = 0; i < export_plugins.size(); i++) {
if (export_plugins[i]->get_script_instance()) { //script based
@@ -840,8 +787,9 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
}
export_plugins.write[i]->_clear();
- if (!do_export)
+ if (!do_export) {
break; //apologies, not exporting
+ }
}
//just store it as it comes
if (do_export) {
@@ -858,7 +806,6 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
Vector<String> custom_list;
if (p_preset->get_custom_features() != String()) {
-
Vector<String> tmp_custom_list = p_preset->get_custom_features().split(",");
for (int i = 0; i < tmp_custom_list.size(); i++) {
@@ -871,7 +818,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
ProjectSettings::CustomMap custom_map;
if (path_remaps.size()) {
- if (1) { //new remap mode, use always as it's friendlier with multiple .pck exports
+ if (true) { //new remap mode, use always as it's friendlier with multiple .pck exports
for (int i = 0; i < path_remaps.size(); i += 2) {
String from = path_remaps[i];
String to = path_remaps[i + 1];
@@ -924,7 +871,6 @@ Error EditorExportPlatform::_add_shared_object(void *p_userdata, const SharedObj
}
Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files, bool p_embed, int64_t *r_embedded_start, int64_t *r_embedded_size) {
-
EditorProgress ep("savepack", TTR("Packing"), 102, true);
String tmppath = EditorSettings::get_singleton()->get_cache_dir().plus_file("packtmp");
@@ -1009,7 +955,6 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
int header_padding = _get_pad(PCK_PADDING, header_size);
for (int i = 0; i < pd.file_ofs.size(); i++) {
-
int string_len = pd.file_ofs[i].path_utf8.length();
int pad = _get_pad(4, string_len);
@@ -1041,10 +986,10 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
uint8_t buf[bufsize];
while (true) {
-
int got = ftmp->get_buffer(buf, bufsize);
- if (got <= 0)
+ if (got <= 0) {
break;
+ }
f->store_buffer(buf, got);
}
@@ -1074,7 +1019,6 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
}
Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
-
EditorProgress ep("savezip", TTR("Packing"), 102, true);
FileAccess *src_f;
@@ -1086,8 +1030,9 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co
zd.zip = zip;
Error err = export_project_files(p_preset, _save_zip_file, &zd);
- if (err != OK && err != ERR_SKIP)
+ if (err != OK && err != ERR_SKIP) {
ERR_PRINT("Failed to export project files");
+ }
zipClose(zip, nullptr);
@@ -1105,12 +1050,12 @@ Error EditorExportPlatform::export_zip(const Ref<EditorExportPreset> &p_preset,
}
void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags) {
-
String host = EditorSettings::get_singleton()->get("network/debug/remote_host");
int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
- if (p_flags & DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST)
+ if (p_flags & DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST) {
host = "localhost";
+ }
if (p_flags & DEBUG_FLAG_DUMB_CLIENT) {
int port = EditorSettings::get_singleton()->get("filesystem/file_server/port");
@@ -1124,23 +1069,21 @@ void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags
}
if (p_flags & DEBUG_FLAG_REMOTE_DEBUG) {
-
r_flags.push_back("--remote-debug");
- r_flags.push_back(host + ":" + String::num(remote_port));
+ r_flags.push_back(get_debug_protocol() + host + ":" + String::num(remote_port));
List<String> breakpoints;
ScriptEditor::get_singleton()->get_breakpoints(&breakpoints);
if (breakpoints.size()) {
-
r_flags.push_back("--breakpoints");
String bpoints;
for (const List<String>::Element *E = breakpoints.front(); E; E = E->next()) {
-
bpoints += E->get().replace(" ", "%20");
- if (E->next())
+ if (E->next()) {
bpoints += ",";
+ }
}
r_flags.push_back(bpoints);
@@ -1148,15 +1091,14 @@ void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags
}
if (p_flags & DEBUG_FLAG_VIEW_COLLISONS) {
-
r_flags.push_back("--debug-collisions");
}
if (p_flags & DEBUG_FLAG_VIEW_NAVIGATION) {
-
r_flags.push_back("--debug-navigation");
}
}
+
EditorExportPlatform::EditorExportPlatform() {
}
@@ -1165,11 +1107,9 @@ EditorExportPlatform::EditorExportPlatform() {
EditorExport *EditorExport::singleton = nullptr;
void EditorExport::_save() {
-
Ref<ConfigFile> config;
config.instance();
for (int i = 0; i < export_presets.size(); i++) {
-
Ref<EditorExportPreset> preset = export_presets[i];
String section = "preset." + itos(i);
@@ -1215,42 +1155,39 @@ void EditorExport::_save() {
}
void EditorExport::save_presets() {
-
- if (block_save)
+ if (block_save) {
return;
+ }
save_timer->start();
}
void EditorExport::_bind_methods() {
+ ADD_SIGNAL(MethodInfo("export_presets_updated"));
}
void EditorExport::add_export_platform(const Ref<EditorExportPlatform> &p_platform) {
-
export_platforms.push_back(p_platform);
}
int EditorExport::get_export_platform_count() {
-
return export_platforms.size();
}
Ref<EditorExportPlatform> EditorExport::get_export_platform(int p_idx) {
-
ERR_FAIL_INDEX_V(p_idx, export_platforms.size(), Ref<EditorExportPlatform>());
return export_platforms[p_idx];
}
void EditorExport::add_export_preset(const Ref<EditorExportPreset> &p_preset, int p_at_pos) {
-
- if (p_at_pos < 0)
+ if (p_at_pos < 0) {
export_presets.push_back(p_preset);
- else
+ } else {
export_presets.insert(p_at_pos, p_preset);
+ }
}
String EditorExportPlatform::test_etc2() const {
-
String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
bool etc_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc");
bool etc2_supported = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2");
@@ -1265,62 +1202,60 @@ String EditorExportPlatform::test_etc2() const {
}
int EditorExport::get_export_preset_count() const {
-
return export_presets.size();
}
Ref<EditorExportPreset> EditorExport::get_export_preset(int p_idx) {
-
ERR_FAIL_INDEX_V(p_idx, export_presets.size(), Ref<EditorExportPreset>());
return export_presets[p_idx];
}
void EditorExport::remove_export_preset(int p_idx) {
-
export_presets.remove(p_idx);
save_presets();
}
void EditorExport::add_export_plugin(const Ref<EditorExportPlugin> &p_plugin) {
-
if (export_plugins.find(p_plugin) == -1) {
export_plugins.push_back(p_plugin);
}
}
void EditorExport::remove_export_plugin(const Ref<EditorExportPlugin> &p_plugin) {
-
export_plugins.erase(p_plugin);
}
Vector<Ref<EditorExportPlugin>> EditorExport::get_export_plugins() {
-
return export_plugins;
}
void EditorExport::_notification(int p_what) {
-
- if (p_what == NOTIFICATION_ENTER_TREE) {
- load_config();
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ load_config();
+ } break;
+ case NOTIFICATION_PROCESS: {
+ update_export_presets();
+ } break;
}
}
void EditorExport::load_config() {
-
Ref<ConfigFile> config;
config.instance();
Error err = config->load("res://export_presets.cfg");
- if (err != OK)
+ if (err != OK) {
return;
+ }
block_save = true;
int index = 0;
while (true) {
-
String section = "preset." + itos(index);
- if (!config->has_section(section))
+ if (!config->has_section(section)) {
break;
+ }
String platform = config->get_value(section, "platform");
@@ -1360,7 +1295,6 @@ void EditorExport::load_config() {
}
if (get_files) {
-
Vector<String> files = config->get_value(section, "export_files");
for (int i = 0; i < files.size(); i++) {
@@ -1392,7 +1326,6 @@ void EditorExport::load_config() {
config->get_section_keys(option_section, &options);
for (List<String>::Element *E = options.front(); E; E = E->next()) {
-
Variant value = config->get_value(option_section, E->get());
preset->set(E->get(), value);
@@ -1405,8 +1338,50 @@ void EditorExport::load_config() {
block_save = false;
}
-bool EditorExport::poll_export_platforms() {
+void EditorExport::update_export_presets() {
+ Map<StringName, List<EditorExportPlatform::ExportOption>> platform_options;
+
+ for (int i = 0; i < export_platforms.size(); i++) {
+ Ref<EditorExportPlatform> platform = export_platforms[i];
+
+ if (platform->should_update_export_options()) {
+ List<EditorExportPlatform::ExportOption> options;
+ platform->get_export_options(&options);
+
+ platform_options[platform->get_name()] = options;
+ }
+ }
+
+ bool export_presets_updated = false;
+ for (int i = 0; i < export_presets.size(); i++) {
+ Ref<EditorExportPreset> preset = export_presets[i];
+ if (platform_options.has(preset->get_platform()->get_name())) {
+ export_presets_updated = true;
+
+ List<EditorExportPlatform::ExportOption> options = platform_options[preset->get_platform()->get_name()];
+
+ // Copy the previous preset values
+ Map<StringName, Variant> previous_values = preset->values;
+ // Clear the preset properties and values prior to reloading
+ preset->properties.clear();
+ preset->values.clear();
+
+ for (List<EditorExportPlatform::ExportOption>::Element *E = options.front(); E; E = E->next()) {
+ preset->properties.push_back(E->get().option);
+
+ StringName option_name = E->get().option.name;
+ preset->values[option_name] = previous_values.has(option_name) ? previous_values[option_name] : E->get().default_value;
+ }
+ }
+ }
+
+ if (export_presets_updated) {
+ emit_signal(_export_presets_updated);
+ }
+}
+
+bool EditorExport::poll_export_platforms() {
bool changed = false;
for (int i = 0; i < export_platforms.size(); i++) {
if (export_platforms.write[i]->poll_export()) {
@@ -1418,7 +1393,6 @@ bool EditorExport::poll_export_platforms() {
}
EditorExport::EditorExport() {
-
save_timer = memnew(Timer);
add_child(save_timer);
save_timer->set_wait_time(0.8);
@@ -1426,7 +1400,10 @@ EditorExport::EditorExport() {
save_timer->connect("timeout", callable_mp(this, &EditorExport::_save));
block_save = false;
+ _export_presets_updated = "export_presets_updated";
+
singleton = this;
+ set_process(true);
}
EditorExport::~EditorExport() {
@@ -1435,7 +1412,6 @@ EditorExport::~EditorExport() {
//////////
void EditorExportPlatformPC::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
-
if (p_preset->get("texture_format/s3tc")) {
r_features->push_back("s3tc");
}
@@ -1454,7 +1430,6 @@ void EditorExportPlatformPC::get_preset_features(const Ref<EditorExportPreset> &
}
void EditorExportPlatformPC::get_export_options(List<ExportOption> *r_options) {
-
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/bptc"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), false));
@@ -1467,21 +1442,18 @@ void EditorExportPlatformPC::get_export_options(List<ExportOption> *r_options) {
}
String EditorExportPlatformPC::get_name() const {
-
return name;
}
String EditorExportPlatformPC::get_os_name() const {
-
return os_name;
}
-Ref<Texture2D> EditorExportPlatformPC::get_logo() const {
+Ref<Texture2D> EditorExportPlatformPC::get_logo() const {
return logo;
}
bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
-
String err;
bool valid = false;
@@ -1507,8 +1479,9 @@ bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset,
valid = dvalid || rvalid;
r_missing_templates = !valid;
- if (!err.empty())
+ if (!err.empty()) {
r_error = err;
+ }
return valid;
}
@@ -1544,7 +1517,6 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
template_path = template_path.strip_edges();
if (template_path == String()) {
-
if (p_preset->get("binary_format/64_bits")) {
if (p_debug) {
template_path = find_export_template(debug_file_64);
@@ -1583,7 +1555,6 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
int64_t embedded_size;
err = save_pack(p_preset, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size);
if (err == OK && p_preset->get("binary_format/embed_pck")) {
-
if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) {
EditorNode::get_singleton()->show_warning(TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."));
return ERR_INVALID_PARAMETER;
@@ -1632,25 +1603,22 @@ void EditorExportPlatformPC::set_logo(const Ref<Texture2D> &p_logo) {
}
void EditorExportPlatformPC::set_release_64(const String &p_file) {
-
release_file_64 = p_file;
}
void EditorExportPlatformPC::set_release_32(const String &p_file) {
-
release_file_32 = p_file;
}
-void EditorExportPlatformPC::set_debug_64(const String &p_file) {
+void EditorExportPlatformPC::set_debug_64(const String &p_file) {
debug_file_64 = p_file;
}
-void EditorExportPlatformPC::set_debug_32(const String &p_file) {
+void EditorExportPlatformPC::set_debug_32(const String &p_file) {
debug_file_32 = p_file;
}
void EditorExportPlatformPC::add_platform_feature(const String &p_feature) {
-
extra_features.insert(p_feature);
}
@@ -1664,7 +1632,6 @@ void EditorExportPlatformPC::get_platform_features(List<String> *r_features) {
}
void EditorExportPlatformPC::resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, Set<String> &p_features) {
-
if (p_features.has("bptc")) {
if (p_preset->has("texture_format/no_bptc_fallbacks")) {
p_features.erase("s3tc");
@@ -1673,27 +1640,22 @@ void EditorExportPlatformPC::resolve_platform_feature_priorities(const Ref<Edito
}
int EditorExportPlatformPC::get_chmod_flags() const {
-
return chmod_flags;
}
void EditorExportPlatformPC::set_chmod_flags(int p_flags) {
-
chmod_flags = p_flags;
}
EditorExportPlatformPC::FixUpEmbeddedPckFunc EditorExportPlatformPC::get_fixup_embedded_pck_func() const {
-
return fixup_embedded_pck_func;
}
void EditorExportPlatformPC::set_fixup_embedded_pck_func(FixUpEmbeddedPckFunc p_fixup_embedded_pck_func) {
-
fixup_embedded_pck_func = p_fixup_embedded_pck_func;
}
EditorExportPlatformPC::EditorExportPlatformPC() {
-
chmod_flags = -1;
fixup_embedded_pck_func = nullptr;
}
@@ -1701,15 +1663,15 @@ EditorExportPlatformPC::EditorExportPlatformPC() {
///////////////////////
void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, const String &p_type, const Set<String> &p_features) {
-
String extension = p_path.get_extension().to_lower();
if (extension != "tres" && extension != "tscn") {
return;
}
bool convert = GLOBAL_GET("editor/convert_text_resources_to_binary_on_export");
- if (!convert)
+ if (!convert) {
return;
+ }
String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpfile.res");
Error err = ResourceFormatLoaderText::convert_file_to_binary(p_path, tmp_path);
if (err != OK) {
@@ -1726,6 +1688,5 @@ void EditorExportTextSceneToBinaryPlugin::_export_file(const String &p_path, con
}
EditorExportTextSceneToBinaryPlugin::EditorExportTextSceneToBinaryPlugin() {
-
GLOBAL_DEF("editor/convert_text_resources_to_binary_on_export", false);
}
diff --git a/editor/editor_export.h b/editor/editor_export.h
index f47fe9c95e..4978b39248 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -43,7 +43,6 @@ class EditorFileSystemDirectory;
struct EditorProgress;
class EditorExportPreset : public Reference {
-
GDCLASS(EditorExportPreset, Reference);
public:
@@ -61,14 +60,14 @@ public:
private:
Ref<EditorExportPlatform> platform;
- ExportFilter export_filter;
+ ExportFilter export_filter = EXPORT_ALL_RESOURCES;
String include_filter;
String exclude_filter;
String export_path;
String exporter;
Set<String> selected_files;
- bool runnable;
+ bool runnable = false;
Vector<String> patches;
@@ -82,7 +81,7 @@ private:
String custom_features;
- int script_mode;
+ int script_mode = MODE_SCRIPT_COMPILED;
String script_key;
protected:
@@ -136,7 +135,7 @@ public:
const List<PropertyInfo> &get_properties() const { return properties; }
- EditorExportPreset();
+ EditorExportPreset() {}
};
struct SharedObject {
@@ -152,7 +151,6 @@ struct SharedObject {
};
class EditorExportPlatform : public Reference {
-
GDCLASS(EditorExportPlatform, Reference);
public:
@@ -161,7 +159,6 @@ public:
private:
struct SavedData {
-
uint64_t ofs;
uint64_t size;
Vector<uint8_t> md5;
@@ -173,7 +170,6 @@ private:
};
struct PackData {
-
FileAccess *f;
Vector<SavedData> file_ofs;
EditorProgress *ep;
@@ -181,7 +177,6 @@ private:
};
struct ZipData {
-
void *zip;
EditorProgress *ep;
};
@@ -232,6 +227,7 @@ public:
virtual Ref<EditorExportPreset> create_preset();
virtual void get_export_options(List<ExportOption> *r_options) = 0;
+ virtual bool should_update_export_options() { return false; }
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { return true; }
virtual String get_os_name() const = 0;
@@ -270,6 +266,7 @@ public:
virtual Error export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
virtual void get_platform_features(List<String> *r_features) = 0;
virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, Set<String> &p_features) = 0;
+ virtual String get_debug_protocol() const { return "tcp://"; }
EditorExportPlatform();
};
@@ -354,6 +351,8 @@ class EditorExport : public Node {
Vector<Ref<EditorExportPreset>> export_presets;
Vector<Ref<EditorExportPlugin>> export_plugins;
+ StringName _export_presets_updated;
+
Timer *save_timer;
bool block_save;
@@ -385,7 +384,7 @@ public:
Vector<Ref<EditorExportPlugin>> get_export_plugins();
void load_config();
-
+ void update_export_presets();
bool poll_export_platforms();
EditorExport();
@@ -393,7 +392,6 @@ public:
};
class EditorExportPlatformPC : public EditorExportPlatform {
-
GDCLASS(EditorExportPlatformPC, EditorExportPlatform);
public:
@@ -455,7 +453,6 @@ public:
};
class EditorExportTextSceneToBinaryPlugin : public EditorExportPlugin {
-
GDCLASS(EditorExportTextSceneToBinaryPlugin, EditorExportPlugin);
public:
diff --git a/editor/editor_feature_profile.cpp b/editor/editor_feature_profile.cpp
index e2b79efb43..d3749477cc 100644
--- a/editor/editor_feature_profile.cpp
+++ b/editor/editor_feature_profile.cpp
@@ -86,7 +86,6 @@ bool EditorFeatureProfile::is_class_editor_disabled(const StringName &p_class) c
}
void EditorFeatureProfile::set_disable_class_property(const StringName &p_class, const StringName &p_property, bool p_disabled) {
-
if (p_disabled) {
if (!disabled_properties.has(p_class)) {
disabled_properties[p_class] = Set<StringName>();
@@ -101,8 +100,8 @@ void EditorFeatureProfile::set_disable_class_property(const StringName &p_class,
}
}
}
-bool EditorFeatureProfile::is_class_property_disabled(const StringName &p_class, const StringName &p_property) const {
+bool EditorFeatureProfile::is_class_property_disabled(const StringName &p_class, const StringName &p_property) const {
if (!disabled_properties.has(p_class)) {
return false;
}
@@ -119,10 +118,10 @@ bool EditorFeatureProfile::has_class_properties_disabled(const StringName &p_cla
}
void EditorFeatureProfile::set_disable_feature(Feature p_feature, bool p_disable) {
-
ERR_FAIL_INDEX(p_feature, FEATURE_MAX);
features_disabled[p_feature] = p_disable;
}
+
bool EditorFeatureProfile::is_feature_disabled(Feature p_feature) const {
ERR_FAIL_INDEX_V(p_feature, FEATURE_MAX, false);
return features_disabled[p_feature];
@@ -134,7 +133,6 @@ String EditorFeatureProfile::get_feature_name(Feature p_feature) {
}
Error EditorFeatureProfile::save_to_file(const String &p_path) {
-
Dictionary json;
json["type"] = "feature_profile";
Array dis_classes;
@@ -180,7 +178,6 @@ Error EditorFeatureProfile::save_to_file(const String &p_path) {
}
Error EditorFeatureProfile::load_from_file(const String &p_path) {
-
Error err;
String text = FileAccess::get_file_as_string(p_path, &err);
if (err != OK) {
@@ -232,7 +229,6 @@ Error EditorFeatureProfile::load_from_file(const String &p_path) {
}
if (json.has("disabled_features")) {
-
Array disabled_features_arr = json["disabled_features"];
for (int i = 0; i < FEATURE_MAX; i++) {
bool found = false;
@@ -253,7 +249,6 @@ Error EditorFeatureProfile::load_from_file(const String &p_path) {
}
void EditorFeatureProfile::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_disable_class", "class_name", "disable"), &EditorFeatureProfile::set_disable_class);
ClassDB::bind_method(D_METHOD("is_class_disabled", "class_name"), &EditorFeatureProfile::is_class_disabled);
@@ -282,7 +277,6 @@ void EditorFeatureProfile::_bind_methods() {
}
EditorFeatureProfile::EditorFeatureProfile() {
-
for (int i = 0; i < FEATURE_MAX; i++) {
features_disabled[i] = false;
}
@@ -292,7 +286,6 @@ EditorFeatureProfile::EditorFeatureProfile() {
void EditorFeatureProfileManager::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
-
current_profile = EDITOR_GET("_default_feature_profile");
if (current_profile != String()) {
current.instance();
@@ -317,7 +310,6 @@ String EditorFeatureProfileManager::_get_selected_profile() {
}
void EditorFeatureProfileManager::_update_profile_list(const String &p_select_profile) {
-
String selected_profile;
if (p_select_profile == String()) { //default, keep
if (profile_list->get_selected() >= 0) {
@@ -382,10 +374,8 @@ void EditorFeatureProfileManager::_update_profile_list(const String &p_select_pr
}
void EditorFeatureProfileManager::_profile_action(int p_action) {
-
switch (p_action) {
case PROFILE_CLEAR: {
-
EditorSettings::get_singleton()->set("_default_feature_profile", "");
EditorSettings::get_singleton()->save();
current_profile = "";
@@ -395,7 +385,6 @@ void EditorFeatureProfileManager::_profile_action(int p_action) {
_emit_current_profile_changed();
} break;
case PROFILE_SET: {
-
String selected = _get_selected_profile();
ERR_FAIL_COND(selected == String());
if (selected == current_profile) {
@@ -410,22 +399,18 @@ void EditorFeatureProfileManager::_profile_action(int p_action) {
_emit_current_profile_changed();
} break;
case PROFILE_IMPORT: {
-
import_profiles->popup_centered_ratio();
} break;
case PROFILE_EXPORT: {
-
export_profile->popup_centered_ratio();
export_profile->set_current_file(_get_selected_profile() + ".profile");
} break;
case PROFILE_NEW: {
-
new_profile_dialog->popup_centered();
new_profile_name->clear();
new_profile_name->grab_focus();
} break;
case PROFILE_ERASE: {
-
String selected = _get_selected_profile();
ERR_FAIL_COND(selected == String());
@@ -436,7 +421,6 @@ void EditorFeatureProfileManager::_profile_action(int p_action) {
}
void EditorFeatureProfileManager::_erase_selected_profile() {
-
String selected = _get_selected_profile();
ERR_FAIL_COND(selected == String());
DirAccessRef da = DirAccess::open(EditorSettings::get_singleton()->get_feature_profiles_dir());
@@ -470,12 +454,10 @@ void EditorFeatureProfileManager::_create_new_profile() {
}
void EditorFeatureProfileManager::_profile_selected(int p_what) {
-
_update_selected_profile();
}
void EditorFeatureProfileManager::_fill_classes_from(TreeItem *p_parent, const String &p_class, const String &p_selected) {
-
TreeItem *class_item = class_list->create_item(p_parent);
class_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
class_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_class, "Node"));
@@ -522,9 +504,9 @@ void EditorFeatureProfileManager::_fill_classes_from(TreeItem *p_parent, const S
}
void EditorFeatureProfileManager::_class_list_item_selected() {
-
- if (updating_features)
+ if (updating_features) {
return;
+ }
property_list->clear();
@@ -567,10 +549,10 @@ void EditorFeatureProfileManager::_class_list_item_selected() {
ClassDB::get_property_list(class_name, &props, true);
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
String name = E->get().name;
- if (!(E->get().usage & PROPERTY_USAGE_EDITOR))
+ if (!(E->get().usage & PROPERTY_USAGE_EDITOR)) {
continue;
+ }
TreeItem *property = property_list->create_item(properties);
property->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
property->set_editable(0, true);
@@ -586,9 +568,9 @@ void EditorFeatureProfileManager::_class_list_item_selected() {
}
void EditorFeatureProfileManager::_class_list_item_edited() {
-
- if (updating_features)
+ if (updating_features) {
return;
+ }
TreeItem *item = class_list->get_edited();
if (!item) {
@@ -611,8 +593,9 @@ void EditorFeatureProfileManager::_class_list_item_edited() {
}
void EditorFeatureProfileManager::_property_item_edited() {
- if (updating_features)
+ if (updating_features) {
return;
+ }
TreeItem *class_item = class_list->get_selected();
if (!class_item) {
@@ -651,7 +634,6 @@ void EditorFeatureProfileManager::_property_item_edited() {
}
void EditorFeatureProfileManager::_update_selected_profile() {
-
String class_selected;
int feature_selected = -1;
@@ -690,7 +672,6 @@ void EditorFeatureProfileManager::_update_selected_profile() {
TreeItem *features = class_list->create_item(root);
features->set_text(0, TTR("Enabled Features:"));
for (int i = 0; i < EditorFeatureProfile::FEATURE_MAX; i++) {
-
TreeItem *feature = class_list->create_item(features);
feature->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
feature->set_text(0, TTRGET(EditorFeatureProfile::get_feature_name(EditorFeatureProfile::Feature(i))));
@@ -718,7 +699,6 @@ void EditorFeatureProfileManager::_update_selected_profile() {
}
void EditorFeatureProfileManager::_import_profiles(const Vector<String> &p_paths) {
-
//test it first
for (int i = 0; i < p_paths.size(); i++) {
Ref<EditorFeatureProfile> profile;
@@ -753,7 +733,6 @@ void EditorFeatureProfileManager::_import_profiles(const Vector<String> &p_paths
}
void EditorFeatureProfileManager::_export_profile(const String &p_path) {
-
ERR_FAIL_COND(edited.is_null());
Error err = edited->save_to_file(p_path);
if (err != OK) {
@@ -762,7 +741,6 @@ void EditorFeatureProfileManager::_export_profile(const String &p_path) {
}
void EditorFeatureProfileManager::_save_and_update() {
-
String edited_path = _get_selected_profile();
ERR_FAIL_COND(edited_path == String());
ERR_FAIL_COND(edited.is_null());
@@ -775,7 +753,6 @@ void EditorFeatureProfileManager::_save_and_update() {
}
void EditorFeatureProfileManager::_emit_current_profile_changed() {
-
emit_signal("current_feature_profile_changed");
}
@@ -790,14 +767,12 @@ Ref<EditorFeatureProfile> EditorFeatureProfileManager::get_current_profile() {
EditorFeatureProfileManager *EditorFeatureProfileManager::singleton = nullptr;
void EditorFeatureProfileManager::_bind_methods() {
-
ClassDB::bind_method("_update_selected_profile", &EditorFeatureProfileManager::_update_selected_profile);
ADD_SIGNAL(MethodInfo("current_feature_profile_changed"));
}
EditorFeatureProfileManager::EditorFeatureProfileManager() {
-
VBoxContainer *main_vbc = memnew(VBoxContainer);
add_child(main_vbc);
diff --git a/editor/editor_feature_profile.h b/editor/editor_feature_profile.h
index 5ae2398027..4036ec7ec6 100644
--- a/editor/editor_feature_profile.h
+++ b/editor/editor_feature_profile.h
@@ -94,7 +94,6 @@ public:
VARIANT_ENUM_CAST(EditorFeatureProfile::Feature)
class EditorFeatureProfileManager : public AcceptDialog {
-
GDCLASS(EditorFeatureProfileManager, AcceptDialog);
enum Action {
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 6a06c6657e..5ae5d1cb31 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -55,9 +55,7 @@ VBoxContainer *EditorFileDialog::get_vbox() {
}
void EditorFileDialog::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
// update icons
mode_thumbnails->set_icon(item_list->get_theme_icon("FileThumbnail", "EditorIcons"));
mode_list->set_icon(item_list->get_theme_icon("FileList", "EditorIcons"));
@@ -72,13 +70,13 @@ void EditorFileDialog::_notification(int p_what) {
fav_down->set_icon(item_list->get_theme_icon("MoveDown", "EditorIcons"));
} else if (p_what == NOTIFICATION_PROCESS) {
-
if (preview_waiting) {
preview_wheel_timeout -= get_process_delta_time();
if (preview_wheel_timeout <= 0) {
preview_wheel_index++;
- if (preview_wheel_index >= 8)
+ if (preview_wheel_index >= 8) {
preview_wheel_index = 0;
+ }
Ref<Texture2D> frame = item_list->get_theme_icon("Progress" + itos(preview_wheel_index + 1), "EditorIcons");
preview->set_texture(frame);
preview_wheel_timeout = 0.1;
@@ -86,10 +84,10 @@ void EditorFileDialog::_notification(int p_what) {
}
} else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
-
bool is_showing_hidden = EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files");
- if (show_hidden_files != is_showing_hidden)
+ if (show_hidden_files != is_showing_hidden) {
set_show_hidden_files(is_showing_hidden);
+ }
set_display_mode((DisplayMode)EditorSettings::get_singleton()->get("filesystem/file_dialog/display_mode").operator int());
// update icons
@@ -106,7 +104,6 @@ void EditorFileDialog::_notification(int p_what) {
// DO NOT CALL UPDATE FILE LIST HERE, ALL HUNDREDS OF HIDDEN DIALOGS WILL RESPOND, CALL INVALIDATE INSTEAD
invalidate();
} else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
if (!is_visible()) {
set_process_unhandled_input(false);
}
@@ -114,13 +111,10 @@ void EditorFileDialog::_notification(int p_what) {
}
void EditorFileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
-
if (k->is_pressed()) {
-
bool handled = false;
if (ED_IS_SHORTCUT("file_dialog/go_back", p_event)) {
@@ -186,22 +180,20 @@ void EditorFileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
}
void EditorFileDialog::set_enable_multiple_selection(bool p_enable) {
-
item_list->set_select_mode(p_enable ? ItemList::SELECT_MULTI : ItemList::SELECT_SINGLE);
};
Vector<String> EditorFileDialog::get_selected_files() const {
-
Vector<String> list;
for (int i = 0; i < item_list->get_item_count(); i++) {
- if (item_list->is_selected(i))
+ if (item_list->is_selected(i)) {
list.push_back(item_list->get_item_text(i));
+ }
}
return list;
};
void EditorFileDialog::update_dir() {
-
if (drives->is_visible()) {
drives->select(dir_access->get_current_drive());
}
@@ -210,7 +202,6 @@ void EditorFileDialog::update_dir() {
// Disable "Open" button only when selecting file(s) mode.
get_ok()->set_disabled(_is_open_should_be_disabled());
switch (mode) {
-
case FILE_MODE_OPEN_FILE:
case FILE_MODE_OPEN_FILES:
get_ok()->set_text(TTR("Open"));
@@ -226,7 +217,6 @@ void EditorFileDialog::update_dir() {
}
void EditorFileDialog::_dir_entered(String p_dir) {
-
dir_access->change_dir(p_dir);
file->set_text("");
invalidate();
@@ -235,12 +225,10 @@ void EditorFileDialog::_dir_entered(String p_dir) {
}
void EditorFileDialog::_file_entered(const String &p_file) {
-
_action_pressed();
}
void EditorFileDialog::_save_confirm_pressed() {
-
String f = dir_access->get_current_dir().plus_file(file->get_text());
_save_to_recent();
hide();
@@ -248,16 +236,16 @@ void EditorFileDialog::_save_confirm_pressed() {
}
void EditorFileDialog::_post_popup() {
-
ConfirmationDialog::_post_popup();
if (invalidated) {
update_file_list();
invalidated = false;
}
- if (mode == FILE_MODE_SAVE_FILE)
+ if (mode == FILE_MODE_SAVE_FILE) {
file->grab_focus();
- else
+ } else {
item_list->grab_focus();
+ }
if (mode == FILE_MODE_OPEN_DIR) {
file_box->set_visible(false);
@@ -265,8 +253,9 @@ void EditorFileDialog::_post_popup() {
file_box->set_visible(true);
}
- if (is_visible() && get_current_file() != "")
+ if (is_visible() && get_current_file() != "") {
_request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
+ }
if (is_visible()) {
Ref<Texture2D> folder = item_list->get_theme_icon("folder", "FileDialog");
@@ -277,8 +266,9 @@ void EditorFileDialog::_post_popup() {
Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs();
for (int i = 0; i < recentd.size(); i++) {
bool cres = recentd[i].begins_with("res://");
- if (cres != res)
+ if (cres != res) {
continue;
+ }
String name = recentd[i];
if (res && name == "res://") {
name = "/";
@@ -302,9 +292,9 @@ void EditorFileDialog::_post_popup() {
}
void EditorFileDialog::_thumbnail_result(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, const Variant &p_udata) {
-
- if (display_mode == DISPLAY_LIST || p_preview.is_null())
+ if (display_mode == DISPLAY_LIST || p_preview.is_null()) {
return;
+ }
for (int i = 0; i < item_list->get_item_count(); i++) {
Dictionary d = item_list->get_item_metadata(i);
@@ -317,12 +307,10 @@ void EditorFileDialog::_thumbnail_result(const String &p_path, const Ref<Texture
}
void EditorFileDialog::_thumbnail_done(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, const Variant &p_udata) {
-
set_process(false);
preview_waiting = false;
if (p_preview.is_valid() && get_current_path() == p_path) {
-
preview->set_texture(p_preview);
if (display_mode == DISPLAY_THUMBNAILS) {
preview_vb->hide();
@@ -337,9 +325,9 @@ void EditorFileDialog::_thumbnail_done(const String &p_path, const Ref<Texture2D
}
void EditorFileDialog::_request_single_thumbnail(const String &p_path) {
-
- if (!FileAccess::exists(p_path))
+ if (!FileAccess::exists(p_path)) {
return;
+ }
set_process(true);
preview_waiting = true;
@@ -348,15 +336,14 @@ void EditorFileDialog::_request_single_thumbnail(const String &p_path) {
}
void EditorFileDialog::_action_pressed() {
-
if (mode == FILE_MODE_OPEN_FILES) {
-
String fbase = dir_access->get_current_dir();
Vector<String> files;
for (int i = 0; i < item_list->get_item_count(); i++) {
- if (item_list->is_selected(i))
+ if (item_list->is_selected(i)) {
files.push_back(fbase.plus_file(item_list->get_item_text(i)));
+ }
}
if (files.size()) {
@@ -375,7 +362,6 @@ void EditorFileDialog::_action_pressed() {
hide();
emit_signal("file_selected", f);
} else if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_OPEN_DIR) {
-
String path = dir_access->get_current_dir();
path = path.replace("\\", "/");
@@ -397,7 +383,6 @@ void EditorFileDialog::_action_pressed() {
}
if (mode == FILE_MODE_SAVE_FILE) {
-
bool valid = false;
if (filter->get_selected() == filter->get_item_count() - 1) {
@@ -405,29 +390,27 @@ void EditorFileDialog::_action_pressed() {
} else if (filters.size() > 1 && filter->get_selected() == 0) {
// match all filters
for (int i = 0; i < filters.size(); i++) {
-
String flt = filters[i].get_slice(";", 0);
for (int j = 0; j < flt.get_slice_count(","); j++) {
-
String str = flt.get_slice(",", j).strip_edges();
if (f.match(str)) {
valid = true;
break;
}
}
- if (valid)
+ if (valid) {
break;
+ }
}
} else {
int idx = filter->get_selected();
- if (filters.size() > 1)
+ if (filters.size() > 1) {
idx--;
+ }
if (idx >= 0 && idx < filters.size()) {
-
String flt = filters[idx].get_slice(";", 0);
int filterSliceCount = flt.get_slice_count(",");
for (int j = 0; j < filterSliceCount; j++) {
-
String str = (flt.get_slice(",", j).strip_edges());
if (f.match(str)) {
valid = true;
@@ -448,7 +431,6 @@ void EditorFileDialog::_action_pressed() {
}
if (!valid) {
-
exterr->popup_centered(Size2(250, 80) * EDSCALE);
return;
}
@@ -457,7 +439,6 @@ void EditorFileDialog::_action_pressed() {
confirm_save->set_text(TTR("File Exists, Overwrite?"));
confirm_save->popup_centered(Size2(200, 80));
} else {
-
_save_to_recent();
hide();
emit_signal("file_selected", f);
@@ -466,22 +447,20 @@ void EditorFileDialog::_action_pressed() {
}
void EditorFileDialog::_cancel_pressed() {
-
file->set_text("");
invalidate();
hide();
}
void EditorFileDialog::_item_selected(int p_item) {
-
int current = p_item;
- if (current < 0 || current >= item_list->get_item_count())
+ if (current < 0 || current >= item_list->get_item_count()) {
return;
+ }
Dictionary d = item_list->get_item_metadata(current);
if (!d["dir"]) {
-
file->set_text(d["name"]);
_request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
} else if (mode == FILE_MODE_OPEN_DIR) {
@@ -492,15 +471,14 @@ void EditorFileDialog::_item_selected(int p_item) {
}
void EditorFileDialog::_multi_selected(int p_item, bool p_selected) {
-
int current = p_item;
- if (current < 0 || current >= item_list->get_item_count())
+ if (current < 0 || current >= item_list->get_item_count()) {
return;
+ }
Dictionary d = item_list->get_item_metadata(current);
if (!d["dir"] && p_selected) {
-
file->set_text(d["name"]);
_request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
}
@@ -509,12 +487,10 @@ void EditorFileDialog::_multi_selected(int p_item, bool p_selected) {
}
void EditorFileDialog::_items_clear_selection() {
-
item_list->unselect_all();
// If nothing is selected, then block Open button.
switch (mode) {
-
case FILE_MODE_OPEN_FILE:
case FILE_MODE_OPEN_FILES:
get_ok()->set_text(TTR("Open"));
@@ -534,7 +510,6 @@ void EditorFileDialog::_items_clear_selection() {
}
void EditorFileDialog::_push_history() {
-
local_history.resize(local_history_pos + 1);
String new_path = dir_access->get_current_dir();
if (local_history.size() == 0 || new_path != local_history[local_history_pos]) {
@@ -544,16 +519,16 @@ void EditorFileDialog::_push_history() {
dir_next->set_disabled(true);
}
}
-void EditorFileDialog::_item_dc_selected(int p_item) {
+void EditorFileDialog::_item_dc_selected(int p_item) {
int current = p_item;
- if (current < 0 || current >= item_list->get_item_count())
+ if (current < 0 || current >= item_list->get_item_count()) {
return;
+ }
Dictionary d = item_list->get_item_metadata(current);
if (d["dir"]) {
-
dir_access->change_dir(d["name"]);
call_deferred("_update_file_list");
call_deferred("_update_dir");
@@ -561,13 +536,11 @@ void EditorFileDialog::_item_dc_selected(int p_item) {
_push_history();
} else {
-
_action_pressed();
}
}
void EditorFileDialog::_item_list_item_rmb_selected(int p_item, const Vector2 &p_pos) {
-
// Right click on specific file(s) or folder(s).
item_menu->clear();
item_menu->set_size(Size2(1, 1));
@@ -608,7 +581,6 @@ void EditorFileDialog::_item_list_item_rmb_selected(int p_item, const Vector2 &p
}
void EditorFileDialog::_item_list_rmb_clicked(const Vector2 &p_pos) {
-
// Right click on folder background. Deselect all files so that actions are applied on the current folder.
for (int i = 0; i < item_list->get_item_count(); i++) {
item_list->unselect(i);
@@ -629,9 +601,7 @@ void EditorFileDialog::_item_list_rmb_clicked(const Vector2 &p_pos) {
}
void EditorFileDialog::_item_menu_id_pressed(int p_option) {
-
switch (p_option) {
-
case ITEM_MENU_COPY_PATH: {
Dictionary item_meta = item_list->get_item_metadata(item_list->get_current());
DisplayServer::get_singleton()->clipboard_set(item_meta["path"]);
@@ -669,20 +639,21 @@ void EditorFileDialog::_item_menu_id_pressed(int p_option) {
}
bool EditorFileDialog::_is_open_should_be_disabled() {
-
- if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_SAVE_FILE)
+ if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_SAVE_FILE) {
return false;
+ }
Vector<int> items = item_list->get_selected_items();
- if (items.size() == 0)
+ if (items.size() == 0) {
return mode != FILE_MODE_OPEN_DIR; // In "Open folder" mode, having nothing selected picks the current folder.
+ }
for (int i = 0; i < items.size(); i++) {
-
Dictionary d = item_list->get_item_metadata(items.get(i));
- if (((mode == FILE_MODE_OPEN_FILE || mode == FILE_MODE_OPEN_FILES) && d["dir"]) || (mode == FILE_MODE_OPEN_DIR && !d["dir"]))
+ if (((mode == FILE_MODE_OPEN_FILE || mode == FILE_MODE_OPEN_FILES) && d["dir"]) || (mode == FILE_MODE_OPEN_DIR && !d["dir"])) {
return true;
+ }
}
return false;
@@ -691,7 +662,9 @@ bool EditorFileDialog::_is_open_should_be_disabled() {
void EditorFileDialog::update_file_name() {
int idx = filter->get_selected() - 1;
if ((idx == -1 && filter->get_item_count() == 2) || (filter->get_item_count() > 2 && idx >= 0 && idx < filter->get_item_count() - 2)) {
- if (idx == -1) idx += 1;
+ if (idx == -1) {
+ idx += 1;
+ }
String filter_str = filters[idx];
String file_str = file->get_text();
String base_name = file_str.get_basename();
@@ -707,7 +680,6 @@ void EditorFileDialog::update_file_name() {
// DO NOT USE THIS FUNCTION UNLESS NEEDED, CALL INVALIDATE() INSTEAD.
void EditorFileDialog::update_file_list() {
-
int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
thumbnail_size *= EDSCALE;
Ref<Texture2D> folder_thumbnail;
@@ -719,7 +691,6 @@ void EditorFileDialog::update_file_list() {
item_list->get_v_scroll()->set_value(0);
if (display_mode == DISPLAY_THUMBNAILS) {
-
item_list->set_max_columns(0);
item_list->set_icon_mode(ItemList::ICON_MODE_TOP);
item_list->set_fixed_column_width(thumbnail_size * 3 / 2);
@@ -737,14 +708,14 @@ void EditorFileDialog::update_file_list() {
preview_vb->hide();
} else {
-
item_list->set_icon_mode(ItemList::ICON_MODE_LEFT);
item_list->set_max_columns(1);
item_list->set_max_text_lines(1);
item_list->set_fixed_column_width(0);
item_list->set_fixed_icon_size(Size2());
- if (preview->get_texture().is_valid())
+ if (preview->get_texture().is_valid()) {
preview_vb->show();
+ }
}
String cdir = dir_access->get_current_dir();
@@ -759,15 +730,16 @@ void EditorFileDialog::update_file_list() {
String item;
while ((item = dir_access->get_next()) != "") {
-
- if (item == "." || item == "..")
+ if (item == "." || item == "..") {
continue;
+ }
if (show_hidden_files || !dir_access->current_is_hidden()) {
- if (!dir_access->current_is_dir())
+ if (!dir_access->current_is_dir()) {
files.push_back(item);
- else
+ } else {
dirs.push_back(item);
+ }
}
}
@@ -780,10 +752,8 @@ void EditorFileDialog::update_file_list() {
item_list->add_item(dir_name);
if (display_mode == DISPLAY_THUMBNAILS) {
-
item_list->set_item_icon(item_list->get_item_count() - 1, folder_thumbnail);
} else {
-
item_list->set_item_icon(item_list->get_item_count() - 1, folder);
}
@@ -801,55 +771,45 @@ void EditorFileDialog::update_file_list() {
List<String> patterns;
// build filter
if (filter->get_selected() == filter->get_item_count() - 1) {
-
// match all
} else if (filters.size() > 1 && filter->get_selected() == 0) {
// match all filters
for (int i = 0; i < filters.size(); i++) {
-
String f = filters[i].get_slice(";", 0);
for (int j = 0; j < f.get_slice_count(","); j++) {
-
patterns.push_back(f.get_slice(",", j).strip_edges());
}
}
} else {
int idx = filter->get_selected();
- if (filters.size() > 1)
+ if (filters.size() > 1) {
idx--;
+ }
if (idx >= 0 && idx < filters.size()) {
-
String f = filters[idx].get_slice(";", 0);
for (int j = 0; j < f.get_slice_count(","); j++) {
-
patterns.push_back(f.get_slice(",", j).strip_edges());
}
}
}
while (!files.empty()) {
-
bool match = patterns.empty();
for (List<String>::Element *E = patterns.front(); E; E = E->next()) {
-
if (files.front()->get().matchn(E->get())) {
-
match = true;
break;
}
}
if (match) {
-
item_list->add_item(files.front()->get());
if (get_icon_func) {
-
Ref<Texture2D> icon = get_icon_func(cdir.plus_file(files.front()->get()));
if (display_mode == DISPLAY_THUMBNAILS) {
-
item_list->set_item_icon(item_list->get_item_count() - 1, file_thumbnail);
item_list->set_item_tag_icon(item_list->get_item_count() - 1, icon);
} else {
@@ -868,8 +828,9 @@ void EditorFileDialog::update_file_list() {
EditorResourcePreview::get_singleton()->queue_resource_preview(fullpath, this, "_thumbnail_result", fullpath);
}
- if (file->get_text() == files.front()->get())
+ if (file->get_text() == files.front()->get()) {
item_list->set_current(item_list->get_item_count() - 1);
+ }
}
files.pop_front();
@@ -904,7 +865,6 @@ void EditorFileDialog::_filter_selected(int) {
}
void EditorFileDialog::update_filters() {
-
filter->clear();
if (filters.size() > 1) {
@@ -914,64 +874,65 @@ void EditorFileDialog::update_filters() {
for (int i = 0; i < MIN(max_filters, filters.size()); i++) {
String flt = filters[i].get_slice(";", 0).strip_edges();
- if (i > 0)
+ if (i > 0) {
all_filters += ", ";
+ }
all_filters += flt;
}
- if (max_filters < filters.size())
+ if (max_filters < filters.size()) {
all_filters += ", ...";
+ }
filter->add_item(TTR("All Recognized") + " (" + all_filters + ")");
}
for (int i = 0; i < filters.size(); i++) {
-
String flt = filters[i].get_slice(";", 0).strip_edges();
String desc = filters[i].get_slice(";", 1).strip_edges();
- if (desc.length())
+ if (desc.length()) {
filter->add_item(desc + " (" + flt + ")");
- else
+ } else {
filter->add_item("(" + flt + ")");
+ }
}
filter->add_item(TTR("All Files (*)"));
}
void EditorFileDialog::clear_filters() {
-
filters.clear();
update_filters();
invalidate();
}
-void EditorFileDialog::add_filter(const String &p_filter) {
+void EditorFileDialog::add_filter(const String &p_filter) {
filters.push_back(p_filter);
update_filters();
invalidate();
}
String EditorFileDialog::get_current_dir() const {
-
return dir_access->get_current_dir();
}
-String EditorFileDialog::get_current_file() const {
+String EditorFileDialog::get_current_file() const {
return file->get_text();
}
-String EditorFileDialog::get_current_path() const {
+String EditorFileDialog::get_current_path() const {
return dir_access->get_current_dir().plus_file(file->get_text());
}
-void EditorFileDialog::set_current_dir(const String &p_dir) {
- if (p_dir.is_rel_path())
+void EditorFileDialog::set_current_dir(const String &p_dir) {
+ if (p_dir.is_rel_path()) {
dir_access->change_dir(OS::get_singleton()->get_resource_dir());
+ }
dir_access->change_dir(p_dir);
update_dir();
invalidate();
}
-void EditorFileDialog::set_current_file(const String &p_file) {
+void EditorFileDialog::set_current_file(const String &p_file) {
file->set_text(p_file);
update_dir();
invalidate();
@@ -981,19 +942,19 @@ void EditorFileDialog::set_current_file(const String &p_file) {
file->grab_focus();
}
- if (is_visible())
+ if (is_visible()) {
_request_single_thumbnail(get_current_dir().plus_file(get_current_file()));
+ }
}
-void EditorFileDialog::set_current_path(const String &p_path) {
- if (!p_path.size())
+void EditorFileDialog::set_current_path(const String &p_path) {
+ if (!p_path.size()) {
return;
+ }
int pos = MAX(p_path.find_last("/"), p_path.find_last("\\"));
if (pos == -1) {
-
set_current_file(p_path);
} else {
-
String dir = p_path.substr(0, pos);
String file = p_path.substr(pos + 1, p_path.length());
set_current_dir(dir);
@@ -1002,10 +963,8 @@ void EditorFileDialog::set_current_path(const String &p_path) {
}
void EditorFileDialog::set_file_mode(FileMode p_mode) {
-
mode = p_mode;
switch (mode) {
-
case FILE_MODE_OPEN_FILE:
get_ok()->set_text(TTR("Open"));
set_title(TTR("Open a File"));
@@ -1047,27 +1006,23 @@ void EditorFileDialog::set_file_mode(FileMode p_mode) {
}
EditorFileDialog::FileMode EditorFileDialog::get_file_mode() const {
-
return mode;
}
void EditorFileDialog::set_access(Access p_access) {
-
ERR_FAIL_INDEX(p_access, 3);
- if (access == p_access)
+ if (access == p_access) {
return;
+ }
memdelete(dir_access);
switch (p_access) {
case ACCESS_FILESYSTEM: {
-
dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
} break;
case ACCESS_RESOURCES: {
-
dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
} break;
case ACCESS_USERDATA: {
-
dir_access = DirAccess::create(DirAccess::ACCESS_USERDATA);
} break;
}
@@ -1079,7 +1034,6 @@ void EditorFileDialog::set_access(Access p_access) {
}
void EditorFileDialog::invalidate() {
-
if (is_visible()) {
update_file_list();
_update_favorites();
@@ -1090,12 +1044,10 @@ void EditorFileDialog::invalidate() {
}
EditorFileDialog::Access EditorFileDialog::get_access() const {
-
return access;
}
void EditorFileDialog::_make_dir_confirm() {
-
Error err = dir_access->make_dir(makedirname->get_text());
if (err == OK) {
dir_access->change_dir(makedirname->get_text());
@@ -1111,13 +1063,11 @@ void EditorFileDialog::_make_dir_confirm() {
}
void EditorFileDialog::_make_dir() {
-
makedialog->popup_centered(Size2(250, 80) * EDSCALE);
makedirname->grab_focus();
}
void EditorFileDialog::_delete_items() {
-
// Collect the selected folders and files to delete and check them in the deletion dependency dialog.
Vector<String> folders;
Vector<String> files;
@@ -1139,7 +1089,6 @@ void EditorFileDialog::_delete_items() {
}
void EditorFileDialog::_select_drive(int p_idx) {
-
String d = drives->get_item_text(p_idx);
dir_access->change_dir(d);
file->set_text("");
@@ -1149,7 +1098,6 @@ void EditorFileDialog::_select_drive(int p_idx) {
}
void EditorFileDialog::_update_drives() {
-
int dc = dir_access->get_drive_count();
if (dc == 0 || access != ACCESS_FILESYSTEM) {
drives->hide();
@@ -1173,7 +1121,6 @@ void EditorFileDialog::_update_drives() {
}
void EditorFileDialog::_favorite_selected(int p_idx) {
-
dir_access->change_dir(favorites->get_item_metadata(p_idx));
file->set_text("");
update_dir();
@@ -1182,7 +1129,6 @@ void EditorFileDialog::_favorite_selected(int p_idx) {
}
void EditorFileDialog::_favorite_move_up() {
-
int current = favorites->get_current();
if (current > 0 && current < favorites->get_item_count()) {
@@ -1191,8 +1137,9 @@ void EditorFileDialog::_favorite_move_up() {
int a_idx = favorited.find(String(favorites->get_item_metadata(current - 1)));
int b_idx = favorited.find(String(favorites->get_item_metadata(current)));
- if (a_idx == -1 || b_idx == -1)
+ if (a_idx == -1 || b_idx == -1) {
return;
+ }
SWAP(favorited.write[a_idx], favorited.write[b_idx]);
EditorSettings::get_singleton()->set_favorites(favorited);
@@ -1201,8 +1148,8 @@ void EditorFileDialog::_favorite_move_up() {
update_file_list();
}
}
-void EditorFileDialog::_favorite_move_down() {
+void EditorFileDialog::_favorite_move_down() {
int current = favorites->get_current();
if (current >= 0 && current < favorites->get_item_count() - 1) {
@@ -1211,8 +1158,9 @@ void EditorFileDialog::_favorite_move_down() {
int a_idx = favorited.find(String(favorites->get_item_metadata(current + 1)));
int b_idx = favorited.find(String(favorites->get_item_metadata(current)));
- if (a_idx == -1 || b_idx == -1)
+ if (a_idx == -1 || b_idx == -1) {
return;
+ }
SWAP(favorited.write[a_idx], favorited.write[b_idx]);
EditorSettings::get_singleton()->set_favorites(favorited);
@@ -1223,7 +1171,6 @@ void EditorFileDialog::_favorite_move_down() {
}
void EditorFileDialog::_update_favorites() {
-
bool res = access == ACCESS_RESOURCES;
String current = get_current_dir();
@@ -1236,20 +1183,23 @@ void EditorFileDialog::_update_favorites() {
Vector<String> favorited = EditorSettings::get_singleton()->get_favorites();
for (int i = 0; i < favorited.size(); i++) {
bool cres = favorited[i].begins_with("res://");
- if (cres != res)
+ if (cres != res) {
continue;
+ }
String name = favorited[i];
bool setthis = false;
if (res && name == "res://") {
- if (name == current)
+ if (name == current) {
setthis = true;
+ }
name = "/";
favorites->add_item(name, folder_icon);
} else if (name.ends_with("/")) {
- if (name == current || name == current + "/")
+ if (name == current || name == current + "/") {
setthis = true;
+ }
name = name.substr(0, name.length() - 1);
name = name.get_file();
@@ -1273,16 +1223,18 @@ void EditorFileDialog::_favorite_pressed() {
bool res = access == ACCESS_RESOURCES;
String cd = get_current_dir();
- if (!cd.ends_with("/"))
+ if (!cd.ends_with("/")) {
cd += "/";
+ }
Vector<String> favorited = EditorSettings::get_singleton()->get_favorites();
bool found = false;
for (int i = 0; i < favorited.size(); i++) {
bool cres = favorited[i].begins_with("res://");
- if (cres != res)
+ if (cres != res) {
continue;
+ }
if (favorited[i] == cd) {
found = true;
@@ -1290,10 +1242,11 @@ void EditorFileDialog::_favorite_pressed() {
}
}
- if (found)
+ if (found) {
favorited.erase(cd);
- else
+ } else {
favorited.push_back(cd);
+ }
EditorSettings::get_singleton()->set_favorites(favorited);
@@ -1301,7 +1254,6 @@ void EditorFileDialog::_favorite_pressed() {
}
void EditorFileDialog::_recent_selected(int p_idx) {
-
Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs();
ERR_FAIL_INDEX(p_idx, recentd.size());
@@ -1312,7 +1264,6 @@ void EditorFileDialog::_recent_selected(int p_idx) {
}
void EditorFileDialog::_go_up() {
-
dir_access->change_dir("..");
update_file_list();
update_dir();
@@ -1320,7 +1271,6 @@ void EditorFileDialog::_go_up() {
}
void EditorFileDialog::_go_back() {
-
if (local_history_pos <= 0) {
return;
}
@@ -1333,8 +1283,8 @@ void EditorFileDialog::_go_back() {
dir_prev->set_disabled(local_history_pos == 0);
dir_next->set_disabled(local_history_pos == local_history.size() - 1);
}
-void EditorFileDialog::_go_forward() {
+void EditorFileDialog::_go_forward() {
if (local_history_pos == local_history.size() - 1) {
return;
}
@@ -1353,9 +1303,9 @@ bool EditorFileDialog::default_show_hidden_files = false;
EditorFileDialog::DisplayMode EditorFileDialog::default_display_mode = DISPLAY_THUMBNAILS;
void EditorFileDialog::set_display_mode(DisplayMode p_mode) {
-
- if (display_mode == p_mode)
+ if (display_mode == p_mode) {
return;
+ }
if (p_mode == DISPLAY_THUMBNAILS) {
mode_list->set_pressed(false);
mode_thumbnails->set_pressed(true);
@@ -1368,12 +1318,10 @@ void EditorFileDialog::set_display_mode(DisplayMode p_mode) {
}
EditorFileDialog::DisplayMode EditorFileDialog::get_display_mode() const {
-
return display_mode;
}
void EditorFileDialog::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_unhandled_input"), &EditorFileDialog::_unhandled_input);
ClassDB::bind_method(D_METHOD("_cancel_pressed"), &EditorFileDialog::_cancel_pressed);
@@ -1451,7 +1399,6 @@ void EditorFileDialog::set_default_display_mode(DisplayMode p_mode) {
}
void EditorFileDialog::_save_to_recent() {
-
String dir = get_current_dir();
Vector<String> recent = EditorSettings::get_singleton()->get_recent_dirs();
@@ -1475,17 +1422,14 @@ void EditorFileDialog::_save_to_recent() {
}
void EditorFileDialog::set_disable_overwrite_warning(bool p_disable) {
-
disable_overwrite_warning = p_disable;
}
bool EditorFileDialog::is_overwrite_warning_disabled() const {
-
return disable_overwrite_warning;
}
EditorFileDialog::EditorFileDialog() {
-
show_hidden_files = default_show_hidden_files;
display_mode = default_display_mode;
local_history_pos = 0;
@@ -1720,8 +1664,9 @@ EditorFileDialog::EditorFileDialog() {
vbox = vbc;
invalidated = true;
- if (register_func)
+ if (register_func) {
register_func(this);
+ }
preview_wheel_timeout = 0;
preview_wheel_index = 0;
@@ -1729,8 +1674,8 @@ EditorFileDialog::EditorFileDialog() {
}
EditorFileDialog::~EditorFileDialog() {
-
- if (unregister_func)
+ if (unregister_func) {
unregister_func(this);
+ }
memdelete(dir_access);
}
diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h
index 8efb8f5368..cbedfc72a6 100644
--- a/editor/editor_file_dialog.h
+++ b/editor/editor_file_dialog.h
@@ -45,7 +45,6 @@
class DependencyRemoveDialog;
class EditorFileDialog : public ConfirmationDialog {
-
GDCLASS(EditorFileDialog, ConfirmationDialog);
public:
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index c211d5852a..d88c61d7b2 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -46,53 +46,48 @@ EditorFileSystem *EditorFileSystem::singleton = nullptr;
#define CACHE_FILE_NAME "filesystem_cache6"
void EditorFileSystemDirectory::sort_files() {
-
files.sort_custom<FileInfoSort>();
}
int EditorFileSystemDirectory::find_file_index(const String &p_file) const {
-
for (int i = 0; i < files.size(); i++) {
- if (files[i]->file == p_file)
+ if (files[i]->file == p_file) {
return i;
+ }
}
return -1;
}
-int EditorFileSystemDirectory::find_dir_index(const String &p_dir) const {
+int EditorFileSystemDirectory::find_dir_index(const String &p_dir) const {
for (int i = 0; i < subdirs.size(); i++) {
- if (subdirs[i]->name == p_dir)
+ if (subdirs[i]->name == p_dir) {
return i;
+ }
}
return -1;
}
int EditorFileSystemDirectory::get_subdir_count() const {
-
return subdirs.size();
}
EditorFileSystemDirectory *EditorFileSystemDirectory::get_subdir(int p_idx) {
-
ERR_FAIL_INDEX_V(p_idx, subdirs.size(), nullptr);
return subdirs[p_idx];
}
int EditorFileSystemDirectory::get_file_count() const {
-
return files.size();
}
String EditorFileSystemDirectory::get_file(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, files.size(), "");
return files[p_idx]->file;
}
String EditorFileSystemDirectory::get_path() const {
-
String p;
const EditorFileSystemDirectory *d = this;
while (d->parent) {
@@ -104,7 +99,6 @@ String EditorFileSystemDirectory::get_path() const {
}
String EditorFileSystemDirectory::get_file_path(int p_idx) const {
-
String file = get_file(p_idx);
const EditorFileSystemDirectory *d = this;
while (d->parent) {
@@ -116,13 +110,11 @@ String EditorFileSystemDirectory::get_file_path(int p_idx) const {
}
Vector<String> EditorFileSystemDirectory::get_file_deps(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, files.size(), Vector<String>());
return files[p_idx]->deps;
}
bool EditorFileSystemDirectory::get_file_import_is_valid(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, files.size(), false);
return files[p_idx]->import_valid;
}
@@ -140,23 +132,19 @@ String EditorFileSystemDirectory::get_file_script_class_icon_path(int p_idx) con
}
StringName EditorFileSystemDirectory::get_file_type(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, files.size(), "");
return files[p_idx]->type;
}
String EditorFileSystemDirectory::get_name() {
-
return name;
}
EditorFileSystemDirectory *EditorFileSystemDirectory::get_parent() {
-
return parent;
}
void EditorFileSystemDirectory::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_subdir_count"), &EditorFileSystemDirectory::get_subdir_count);
ClassDB::bind_method(D_METHOD("get_subdir", "idx"), &EditorFileSystemDirectory::get_subdir);
ClassDB::bind_method(D_METHOD("get_file_count"), &EditorFileSystemDirectory::get_file_count);
@@ -174,27 +162,22 @@ void EditorFileSystemDirectory::_bind_methods() {
}
EditorFileSystemDirectory::EditorFileSystemDirectory() {
-
modified_time = 0;
parent = nullptr;
verified = false;
}
EditorFileSystemDirectory::~EditorFileSystemDirectory() {
-
for (int i = 0; i < files.size(); i++) {
-
memdelete(files[i]);
}
for (int i = 0; i < subdirs.size(); i++) {
-
memdelete(subdirs[i]);
}
}
void EditorFileSystem::_scan_filesystem() {
-
ERR_FAIL_COND(!scanning || new_filesystem);
//read .fscache
@@ -212,7 +195,6 @@ void EditorFileSystem::_scan_filesystem() {
if (f) {
//read the disk cache
while (!f->eof_reached()) {
-
String l = f->get_line().strip_edges();
if (first) {
if (first_scan) {
@@ -229,8 +211,9 @@ void EditorFileSystem::_scan_filesystem() {
first = false;
continue;
}
- if (l == String())
+ if (l == String()) {
continue;
+ }
if (l.begins_with("::")) {
Vector<String> split = l.split("::");
@@ -282,7 +265,6 @@ void EditorFileSystem::_scan_filesystem() {
FileAccessRef f2 = FileAccess::open(update_cache, FileAccess::READ);
String l = f2->get_line().strip_edges();
while (l != String()) {
-
file_cache.erase(l); //erase cache for this, so it gets updated
l = f2->get_line().strip_edges();
}
@@ -319,7 +301,6 @@ void EditorFileSystem::_scan_filesystem() {
}
void EditorFileSystem::_save_filesystem_cache() {
-
group_file_cache.clear();
String fscache = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(CACHE_FILE_NAME);
@@ -334,15 +315,14 @@ void EditorFileSystem::_save_filesystem_cache() {
}
void EditorFileSystem::_thread_func(void *_userdata) {
-
EditorFileSystem *sd = (EditorFileSystem *)_userdata;
sd->_scan_filesystem();
}
bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_imported_files) {
-
- if (!reimport_on_missing_imported_files && p_only_imported_files)
+ if (!reimport_on_missing_imported_files && p_only_imported_files) {
return false;
+ }
if (!FileAccess::exists(p_path + ".import")) {
return true;
@@ -378,7 +358,6 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo
String dest_md5 = "";
while (true) {
-
assign = Variant();
next_tag.fields.clear();
next_tag.name = String();
@@ -460,7 +439,6 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo
//check source md5 matching
if (!p_only_imported_files) {
-
if (source_file != String() && source_file != p_path) {
return true; //file was moved, reimport
}
@@ -486,7 +464,6 @@ bool EditorFileSystem::_test_for_reimport(const String &p_path, bool p_only_impo
}
bool EditorFileSystem::_update_scan_actions() {
-
sources_changed.clear();
bool fs_changed = false;
@@ -495,20 +472,17 @@ bool EditorFileSystem::_update_scan_actions() {
Vector<String> reloads;
for (List<ItemAction>::Element *E = scan_actions.front(); E; E = E->next()) {
-
ItemAction &ia = E->get();
switch (ia.action) {
case ItemAction::ACTION_NONE: {
-
} break;
case ItemAction::ACTION_DIR_ADD: {
-
int idx = 0;
for (int i = 0; i < ia.dir->subdirs.size(); i++) {
-
- if (ia.new_dir->name < ia.dir->subdirs[i]->name)
+ if (ia.new_dir->name < ia.dir->subdirs[i]->name) {
break;
+ }
idx++;
}
if (idx == ia.dir->subdirs.size()) {
@@ -520,19 +494,17 @@ bool EditorFileSystem::_update_scan_actions() {
fs_changed = true;
} break;
case ItemAction::ACTION_DIR_REMOVE: {
-
ERR_CONTINUE(!ia.dir->parent);
ia.dir->parent->subdirs.erase(ia.dir);
memdelete(ia.dir);
fs_changed = true;
} break;
case ItemAction::ACTION_FILE_ADD: {
-
int idx = 0;
for (int i = 0; i < ia.dir->files.size(); i++) {
-
- if (ia.new_file->file < ia.dir->files[i]->file)
+ if (ia.new_file->file < ia.dir->files[i]->file) {
break;
+ }
idx++;
}
if (idx == ia.dir->files.size()) {
@@ -545,7 +517,6 @@ bool EditorFileSystem::_update_scan_actions() {
} break;
case ItemAction::ACTION_FILE_REMOVE: {
-
int idx = ia.dir->find_file_index(ia.file);
ERR_CONTINUE(idx == -1);
_delete_internal_files(ia.dir->files[idx]->file);
@@ -556,7 +527,6 @@ bool EditorFileSystem::_update_scan_actions() {
} break;
case ItemAction::ACTION_FILE_TEST_REIMPORT: {
-
int idx = ia.dir->find_file_index(ia.file);
ERR_CONTINUE(idx == -1);
String full_path = ia.dir->get_file_path(idx);
@@ -573,7 +543,6 @@ bool EditorFileSystem::_update_scan_actions() {
fs_changed = true;
} break;
case ItemAction::ACTION_FILE_RELOAD: {
-
int idx = ia.dir->find_file_index(ia.file);
ERR_CONTINUE(idx == -1);
String full_path = ia.dir->get_file_path(idx);
@@ -604,12 +573,13 @@ bool EditorFileSystem::_update_scan_actions() {
}
void EditorFileSystem::scan() {
-
- if (false /*&& bool(Globals::get_singleton()->get("debug/disable_scan"))*/)
+ if (false /*&& bool(Globals::get_singleton()->get("debug/disable_scan"))*/) {
return;
+ }
- if (scanning || scanning_changes || thread)
+ if (scanning || scanning_changes || thread) {
return;
+ }
_update_extensions();
@@ -618,8 +588,9 @@ void EditorFileSystem::scan() {
scanning = true;
scan_total = 0;
_scan_filesystem();
- if (filesystem)
+ if (filesystem) {
memdelete(filesystem);
+ }
//file_type_cache.clear();
filesystem = new_filesystem;
new_filesystem = nullptr;
@@ -630,7 +601,6 @@ void EditorFileSystem::scan() {
_queue_update_script_classes();
first_scan = false;
} else {
-
ERR_FAIL_COND(thread);
set_process(true);
Thread::Settings s;
@@ -644,14 +614,12 @@ void EditorFileSystem::scan() {
}
void EditorFileSystem::ScanProgress::update(int p_current, int p_total) const {
-
float ratio = low + ((hi - low) / p_total) * p_current;
progress->step(ratio * 1000);
EditorFileSystem::singleton->scan_total = ratio;
}
EditorFileSystem::ScanProgress EditorFileSystem::ScanProgress::get_sub(int p_current, int p_total) const {
-
ScanProgress sp = *this;
float slice = (sp.hi - sp.low) / p_total;
sp.low += slice * p_current;
@@ -660,7 +628,6 @@ EditorFileSystem::ScanProgress EditorFileSystem::ScanProgress::get_sub(int p_cur
}
void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess *da, const ScanProgress &p_progress) {
-
List<String> dirs;
List<String> files;
@@ -670,28 +637,30 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
da->list_dir_begin();
while (true) {
-
String f = da->get_next();
- if (f == "")
+ if (f == "") {
break;
+ }
- if (da->current_is_hidden())
+ if (da->current_is_hidden()) {
continue;
+ }
if (da->current_is_dir()) {
-
- if (f.begins_with(".")) // Ignore special and . / ..
+ if (f.begins_with(".")) { // Ignore special and . / ..
continue;
+ }
- if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) // skip if another project inside this
+ if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) { // skip if another project inside this
continue;
- if (FileAccess::exists(cd.plus_file(f).plus_file(".gdignore"))) // skip if another project inside this
+ }
+ if (FileAccess::exists(cd.plus_file(f).plus_file(".gdignore"))) { // skip if another project inside this
continue;
+ }
dirs.push_back(f);
} else {
-
files.push_back(f);
}
}
@@ -705,15 +674,12 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
int idx = 0;
for (List<String>::Element *E = dirs.front(); E; E = E->next(), idx++) {
-
if (da->change_dir(E->get()) == OK) {
-
String d = da->get_current_dir();
if (d == cd || !d.begins_with(cd)) {
da->change_dir(cd); //avoid recursion
} else {
-
EditorFileSystemDirectory *efd = memnew(EditorFileSystemDirectory);
efd->parent = p_dir;
@@ -723,9 +689,9 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
int idx2 = 0;
for (int i = 0; i < p_dir->subdirs.size(); i++) {
-
- if (efd->name < p_dir->subdirs[i]->name)
+ if (efd->name < p_dir->subdirs[i]->name) {
break;
+ }
idx2++;
}
if (idx2 == p_dir->subdirs.size()) {
@@ -744,7 +710,6 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
}
for (List<String>::Element *E = files.front(); E; E = E->next(), idx++) {
-
String ext = E->get().get_extension().to_lower();
if (!valid_extensions.has(ext)) {
continue; //invalid
@@ -759,7 +724,6 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
uint64_t mt = FileAccess::get_modified_time(path);
if (import_extensions.has(ext)) {
-
//is imported
uint64_t import_mt = 0;
if (FileAccess::exists(path + ".import")) {
@@ -767,7 +731,6 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
}
if (fc && fc->modification_time == mt && fc->import_modification_time == import_mt && !_test_for_reimport(path, true)) {
-
fi->type = fc->type;
fi->deps = fc->deps;
fi->modified_time = fc->modification_time;
@@ -795,7 +758,6 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
}
} else {
-
fi->type = ResourceFormatImporter::get_singleton()->get_resource_type(path);
fi->import_group_file = ResourceFormatImporter::get_singleton()->get_import_group_file(path);
fi->script_class_name = _get_global_script_class(fi->type, path, &fi->script_class_extends, &fi->script_class_icon_path);
@@ -810,7 +772,6 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
scan_actions.push_back(ia);
}
} else {
-
if (fc && fc->modification_time == mt) {
//not imported, so just update type if changed
fi->type = fc->type;
@@ -838,14 +799,12 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
}
void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const ScanProgress &p_progress) {
-
uint64_t current_mtime = FileAccess::get_modified_time(p_dir->get_path());
bool updated_dir = false;
String cd = p_dir->get_path();
if (current_mtime != p_dir->modified_time || using_fat32_or_exfat) {
-
updated_dir = true;
p_dir->modified_time = current_mtime;
//ooooops, dir changed, see what's going on
@@ -853,12 +812,10 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
//first mark everything as veryfied
for (int i = 0; i < p_dir->files.size(); i++) {
-
p_dir->files[i]->verified = false;
}
for (int i = 0; i < p_dir->subdirs.size(); i++) {
-
p_dir->get_subdir(i)->verified = false;
}
@@ -869,26 +826,28 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
da->change_dir(cd);
da->list_dir_begin();
while (true) {
-
String f = da->get_next();
- if (f == "")
+ if (f == "") {
break;
+ }
- if (da->current_is_hidden())
+ if (da->current_is_hidden()) {
continue;
+ }
if (da->current_is_dir()) {
-
- if (f.begins_with(".")) // Ignore special and . / ..
+ if (f.begins_with(".")) { // Ignore special and . / ..
continue;
+ }
int idx = p_dir->find_dir_index(f);
if (idx == -1) {
-
- if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) // skip if another project inside this
+ if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) { // skip if another project inside this
continue;
- if (FileAccess::exists(cd.plus_file(f).plus_file(".gdignore"))) // skip if another project inside this
+ }
+ if (FileAccess::exists(cd.plus_file(f).plus_file(".gdignore"))) { // skip if another project inside this
continue;
+ }
EditorFileSystemDirectory *efd = memnew(EditorFileSystemDirectory);
@@ -911,8 +870,9 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
} else {
String ext = f.get_extension().to_lower();
- if (!valid_extensions.has(ext))
+ if (!valid_extensions.has(ext)) {
continue; //invalid
+ }
int idx = p_dir->find_file_index(f);
@@ -958,7 +918,6 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
}
for (int i = 0; i < p_dir->files.size(); i++) {
-
if (updated_dir && !p_dir->files[i]->verified) {
//this file was removed, add action to remove it
ItemAction ia;
@@ -983,7 +942,6 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
} else if (!FileAccess::exists(path + ".import")) {
reimport = true; //no .import file, obviously reimport
} else {
-
uint64_t import_mt = FileAccess::get_modified_time(path + ".import");
if (import_mt != p_dir->files[i]->import_modified_time) {
reimport = true;
@@ -993,7 +951,6 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
}
if (reimport) {
-
ItemAction ia;
ia.action = ItemAction::ACTION_FILE_TEST_REIMPORT;
ia.dir = p_dir;
@@ -1005,7 +962,6 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
uint64_t mt = FileAccess::get_modified_time(path);
if (mt != p_dir->files[i]->modified_time) {
-
p_dir->files[i]->modified_time = mt; //save new time, but test for reload
ItemAction ia;
@@ -1018,7 +974,6 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir, const
}
for (int i = 0; i < p_dir->subdirs.size(); i++) {
-
if (updated_dir && !p_dir->subdirs[i]->verified) {
//this directory was removed, add action to remove it
ItemAction ia;
@@ -1045,7 +1000,6 @@ void EditorFileSystem::_delete_internal_files(String p_file) {
}
void EditorFileSystem::_thread_func_sources(void *_userdata) {
-
EditorFileSystem *efs = (EditorFileSystem *)_userdata;
if (efs->filesystem) {
EditorProgressBG pr("sources", TTR("ScanSources"), 1000);
@@ -1059,12 +1013,10 @@ void EditorFileSystem::_thread_func_sources(void *_userdata) {
}
void EditorFileSystem::get_changed_sources(List<String> *r_changed) {
-
*r_changed = sources_changed;
}
void EditorFileSystem::scan_changes() {
-
if (first_scan || // Prevent a premature changes scan from inhibiting the first full scan
scanning || scanning_changes || thread) {
scan_changes_pending = true;
@@ -1088,14 +1040,14 @@ void EditorFileSystem::scan_changes() {
sp.low = 0;
scan_total = 0;
_scan_fs_changes(filesystem, sp);
- if (_update_scan_actions())
+ if (_update_scan_actions()) {
emit_signal("filesystem_changed");
+ }
}
scanning_changes = false;
scanning_changes_done = true;
emit_signal("sources_changed", sources_changed.size() > 0);
} else {
-
ERR_FAIL_COND(thread_sources);
set_process(true);
scan_total = 0;
@@ -1106,11 +1058,8 @@ void EditorFileSystem::scan_changes() {
}
void EditorFileSystem::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
call_deferred("scan"); //this should happen after every editor node entered the tree
} break;
@@ -1130,22 +1079,20 @@ void EditorFileSystem::_notification(int p_what) {
set_process(false);
}
- if (filesystem)
+ if (filesystem) {
memdelete(filesystem);
- if (new_filesystem)
+ }
+ if (new_filesystem) {
memdelete(new_filesystem);
+ }
filesystem = nullptr;
new_filesystem = nullptr;
} break;
case NOTIFICATION_PROCESS: {
-
if (use_threads) {
-
if (scanning_changes) {
-
if (scanning_changes_done) {
-
scanning_changes = false;
set_process(false);
@@ -1153,18 +1100,19 @@ void EditorFileSystem::_notification(int p_what) {
Thread::wait_to_finish(thread_sources);
memdelete(thread_sources);
thread_sources = nullptr;
- if (_update_scan_actions())
+ if (_update_scan_actions()) {
emit_signal("filesystem_changed");
+ }
emit_signal("sources_changed", sources_changed.size() > 0);
_queue_update_script_classes();
first_scan = false;
}
} else if (!scanning) {
-
set_process(false);
- if (filesystem)
+ if (filesystem) {
memdelete(filesystem);
+ }
filesystem = new_filesystem;
new_filesystem = nullptr;
Thread::wait_to_finish(thread);
@@ -1187,36 +1135,33 @@ void EditorFileSystem::_notification(int p_what) {
}
bool EditorFileSystem::is_scanning() const {
-
return scanning || scanning_changes;
}
-float EditorFileSystem::get_scanning_progress() const {
+float EditorFileSystem::get_scanning_progress() const {
return scan_total;
}
EditorFileSystemDirectory *EditorFileSystem::get_filesystem() {
-
return filesystem;
}
void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory *p_dir, FileAccess *p_file) {
-
- if (!p_dir)
+ if (!p_dir) {
return; //none
+ }
p_file->store_line("::" + p_dir->get_path() + "::" + String::num(p_dir->modified_time));
for (int i = 0; i < p_dir->files.size(); i++) {
-
if (p_dir->files[i]->import_group_file != String()) {
group_file_cache.insert(p_dir->files[i]->import_group_file);
}
String s = p_dir->files[i]->file + "::" + p_dir->files[i]->type + "::" + itos(p_dir->files[i]->modified_time) + "::" + itos(p_dir->files[i]->import_modified_time) + "::" + itos(p_dir->files[i]->import_valid) + "::" + p_dir->files[i]->import_group_file + "::" + p_dir->files[i]->script_class_name + "<>" + p_dir->files[i]->script_class_extends + "<>" + p_dir->files[i]->script_class_icon_path;
s += "::";
for (int j = 0; j < p_dir->files[i]->deps.size(); j++) {
-
- if (j > 0)
+ if (j > 0) {
s += "<>";
+ }
s += p_dir->files[i]->deps[j];
}
@@ -1224,7 +1169,6 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory *p_dir,
}
for (int i = 0; i < p_dir->subdirs.size(); i++) {
-
_save_filesystem_cache(p_dir->subdirs[i], p_file);
}
}
@@ -1232,33 +1176,35 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory *p_dir,
bool EditorFileSystem::_find_file(const String &p_file, EditorFileSystemDirectory **r_d, int &r_file_pos) const {
//todo make faster
- if (!filesystem || scanning)
+ if (!filesystem || scanning) {
return false;
+ }
String f = ProjectSettings::get_singleton()->localize_path(p_file);
- if (!f.begins_with("res://"))
+ if (!f.begins_with("res://")) {
return false;
+ }
f = f.substr(6, f.length());
f = f.replace("\\", "/");
Vector<String> path = f.split("/");
- if (path.size() == 0)
+ if (path.size() == 0) {
return false;
+ }
String file = path[path.size() - 1];
path.resize(path.size() - 1);
EditorFileSystemDirectory *fs = filesystem;
for (int i = 0; i < path.size(); i++) {
-
- if (path[i].begins_with("."))
+ if (path[i].begins_with(".")) {
return false;
+ }
int idx = -1;
for (int j = 0; j < fs->get_subdir_count(); j++) {
-
if (fs->get_subdir(j)->get_name() == path[i]) {
idx = j;
break;
@@ -1274,26 +1220,25 @@ bool EditorFileSystem::_find_file(const String &p_file, EditorFileSystemDirector
int idx2 = 0;
for (int j = 0; j < fs->get_subdir_count(); j++) {
-
- if (efsd->name < fs->get_subdir(j)->get_name())
+ if (efsd->name < fs->get_subdir(j)->get_name()) {
break;
+ }
idx2++;
}
- if (idx2 == fs->get_subdir_count())
+ if (idx2 == fs->get_subdir_count()) {
fs->subdirs.push_back(efsd);
- else
+ } else {
fs->subdirs.insert(idx2, efsd);
+ }
fs = efsd;
} else {
-
fs = fs->get_subdir(idx);
}
}
int cpos = -1;
for (int i = 0; i < fs->files.size(); i++) {
-
if (fs->files[i]->file == file) {
cpos = i;
break;
@@ -1307,12 +1252,10 @@ bool EditorFileSystem::_find_file(const String &p_file, EditorFileSystemDirector
}
String EditorFileSystem::get_file_type(const String &p_file) const {
-
EditorFileSystemDirectory *fs = nullptr;
int cpos = -1;
if (!_find_file(p_file, &fs, cpos)) {
-
return "";
}
@@ -1320,53 +1263,55 @@ String EditorFileSystem::get_file_type(const String &p_file) const {
}
EditorFileSystemDirectory *EditorFileSystem::find_file(const String &p_file, int *r_index) const {
-
- if (!filesystem || scanning)
+ if (!filesystem || scanning) {
return nullptr;
+ }
EditorFileSystemDirectory *fs = nullptr;
int cpos = -1;
if (!_find_file(p_file, &fs, cpos)) {
-
return nullptr;
}
- if (r_index)
+ if (r_index) {
*r_index = cpos;
+ }
return fs;
}
EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p_path) {
-
- if (!filesystem || scanning)
+ if (!filesystem || scanning) {
return nullptr;
+ }
String f = ProjectSettings::get_singleton()->localize_path(p_path);
- if (!f.begins_with("res://"))
+ if (!f.begins_with("res://")) {
return nullptr;
+ }
f = f.substr(6, f.length());
f = f.replace("\\", "/");
- if (f == String())
+ if (f == String()) {
return filesystem;
+ }
- if (f.ends_with("/"))
+ if (f.ends_with("/")) {
f = f.substr(0, f.length() - 1);
+ }
Vector<String> path = f.split("/");
- if (path.size() == 0)
+ if (path.size() == 0) {
return nullptr;
+ }
EditorFileSystemDirectory *fs = filesystem;
for (int i = 0; i < path.size(); i++) {
-
int idx = -1;
for (int j = 0; j < fs->get_subdir_count(); j++) {
-
if (fs->get_subdir(j)->get_name() == path[i]) {
idx = j;
break;
@@ -1376,7 +1321,6 @@ EditorFileSystemDirectory *EditorFileSystem::get_filesystem_path(const String &p
if (idx == -1) {
return nullptr;
} else {
-
fs = fs->get_subdir(idx);
}
}
@@ -1395,7 +1339,6 @@ void EditorFileSystem::_save_late_updated_files() {
}
Vector<String> EditorFileSystem::_get_dependencies(const String &p_path) {
-
List<String> deps;
ResourceLoader::get_dependencies(p_path, &deps);
@@ -1408,7 +1351,6 @@ Vector<String> EditorFileSystem::_get_dependencies(const String &p_path) {
}
String EditorFileSystem::_get_global_script_class(const String &p_type, const String &p_path, String *r_extends, String *r_icon_path) const {
-
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
if (ScriptServer::get_language(i)->handles_global_class_type(p_type)) {
String global_name;
@@ -1450,9 +1392,9 @@ void EditorFileSystem::_scan_script_classes(EditorFileSystemDirectory *p_dir) {
}
void EditorFileSystem::update_script_classes() {
-
- if (!update_script_classes_queued)
+ if (!update_script_classes_queued) {
return;
+ }
update_script_classes_queued = false;
ScriptServer::global_classes_clear();
@@ -1482,14 +1424,13 @@ void EditorFileSystem::_queue_update_script_classes() {
}
void EditorFileSystem::update_file(const String &p_file) {
-
EditorFileSystemDirectory *fs = nullptr;
int cpos = -1;
if (!_find_file(p_file, &fs, cpos)) {
-
- if (!fs)
+ if (!fs) {
return;
+ }
}
if (!FileAccess::exists(p_file)) {
@@ -1508,15 +1449,15 @@ void EditorFileSystem::update_file(const String &p_file) {
String type = ResourceLoader::get_resource_type(p_file);
if (cpos == -1) {
-
//the file did not exist, it was added
late_added_files.insert(p_file); //remember that it was added. This mean it will be scanned and imported on editor restart
int idx = 0;
for (int i = 0; i < fs->files.size(); i++) {
- if (p_file < fs->files[i]->file)
+ if (p_file < fs->files[i]->file) {
break;
+ }
idx++;
}
@@ -1528,12 +1469,10 @@ void EditorFileSystem::update_file(const String &p_file) {
if (idx == fs->files.size()) {
fs->files.push_back(fi);
} else {
-
fs->files.insert(idx, fi);
}
cpos = idx;
} else {
-
//the file exists and it was updated, and was not added in this step.
//this means we must force upon next restart to scan it again, to get proper type and dependencies
late_update_files.insert(p_file);
@@ -1555,13 +1494,11 @@ void EditorFileSystem::update_file(const String &p_file) {
}
Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector<String> &p_files) {
-
String importer_name;
Map<String, Map<StringName, Variant>> source_file_options;
Map<String, String> base_paths;
for (int i = 0; i < p_files.size(); i++) {
-
Ref<ConfigFile> config;
config.instance();
Error err = config->load(p_files[i] + ".import");
@@ -1585,7 +1522,6 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
importer->get_import_options(&options);
//set default values
for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
-
source_file_options[p_files[i]][E->get().option.name] = E->get().default_value;
}
@@ -1611,7 +1547,6 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
//all went well, overwrite config files with proper remaps and md5s
for (Map<String, Map<StringName, Variant>>::Element *E = source_file_options.front(); E; E = E->next()) {
-
const String &file = E->key();
String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(file);
FileAccessRef f = FileAccess::open(file + ".import", FileAccess::WRITE);
@@ -1661,7 +1596,6 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
importer->get_import_options(&options);
//set default values
for (List<ResourceImporter::ImportOption>::Element *F = options.front(); F; F = F->next()) {
-
String base = F->get().option.name;
Variant v = F->get().default_value;
if (source_file_options[file].has(base)) {
@@ -1699,11 +1633,9 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
//if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it
//to reload properly
if (ResourceCache::has(file)) {
-
Resource *r = ResourceCache::get(file);
if (r->get_import_path() != String()) {
-
String dst_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(file);
r->set_import_path(dst_path);
r->set_import_last_modified_time(0);
@@ -1717,7 +1649,6 @@ Error EditorFileSystem::_reimport_group(const String &p_group_file, const Vector
}
void EditorFileSystem::_reimport_file(const String &p_file) {
-
EditorFileSystemDirectory *fs = nullptr;
int cpos = -1;
bool found = _find_file(p_file, &fs, cpos);
@@ -1816,13 +1747,11 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
Vector<String> dest_paths;
if (err == OK) {
-
if (importer->get_save_extension() == "") {
//no path
} else if (import_variants.size()) {
//import with variants
for (List<String>::Element *E = import_variants.front(); E; E = E->next()) {
-
String path = base_path.c_escape() + "." + E->get() + "." + importer->get_save_extension();
f->store_line("path." + E->get() + "=\"" + path + "\"");
@@ -1835,7 +1764,6 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
}
} else {
-
f->store_line("valid=false");
}
@@ -1876,7 +1804,6 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
//store options in provided order, to avoid file changing. Order is also important because first match is accepted first.
for (List<ResourceImporter::ImportOption>::Element *E = opts.front(); E; E = E->next()) {
-
String base = E->get().option.name;
String value;
VariantWriter::write_to_string(params[base], value);
@@ -1907,11 +1834,9 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
//if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it
//to reload properly
if (ResourceCache::has(p_file)) {
-
Resource *r = ResourceCache::get(p_file);
if (r->get_import_path() != String()) {
-
String dst_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(p_file);
r->set_import_path(dst_path);
r->set_import_last_modified_time(0);
@@ -1922,7 +1847,6 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
}
void EditorFileSystem::_find_group_files(EditorFileSystemDirectory *efd, Map<String, Vector<String>> &group_files, Set<String> &groups_to_reimport) {
-
int fc = efd->files.size();
const EditorFileSystemDirectory::FileInfo *const *files = efd->files.ptr();
for (int i = 0; i < fc; i++) {
@@ -1940,7 +1864,6 @@ void EditorFileSystem::_find_group_files(EditorFileSystemDirectory *efd, Map<Str
}
void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
-
{ //check that .import folder exists
DirAccess *da = DirAccess::open("res://");
if (da->change_dir(".import") != OK) {
@@ -1960,7 +1883,6 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
Set<String> groups_to_reimport;
for (int i = 0; i < p_files.size(); i++) {
-
String group_file = ResourceFormatImporter::get_singleton()->get_import_group_file(p_files[i]);
if (group_file_cache.has(p_files[i])) {
@@ -1983,7 +1905,6 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
EditorFileSystemDirectory *fs = nullptr;
int cpos = -1;
if (_find_file(p_files[i], &fs, cpos)) {
-
fs->files.write[cpos]->import_group_file = group_file;
}
}
@@ -2001,7 +1922,6 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
Map<String, Vector<String>> group_files;
_find_group_files(filesystem, group_files, groups_to_reimport);
for (Map<String, Vector<String>>::Element *E = group_files.front(); E; E = E->next()) {
-
Error err = _reimport_group(E->key(), E->get());
if (err == OK) {
_reimport_file(E->key());
@@ -2019,7 +1939,6 @@ void EditorFileSystem::reimport_files(const Vector<String> &p_files) {
}
Error EditorFileSystem::_resource_import(const String &p_path) {
-
Vector<String> files;
files.push_back(p_path);
@@ -2034,13 +1953,10 @@ bool EditorFileSystem::is_group_file(const String &p_path) const {
}
void EditorFileSystem::_move_group_files(EditorFileSystemDirectory *efd, const String &p_group_file, const String &p_new_location) {
-
int fc = efd->files.size();
EditorFileSystemDirectory::FileInfo *const *files = efd->files.ptrw();
for (int i = 0; i < fc; i++) {
-
if (files[i]->import_group_file == p_group_file) {
-
files[i]->import_group_file = p_new_location;
Ref<ConfigFile> config;
@@ -2051,7 +1967,6 @@ void EditorFileSystem::_move_group_files(EditorFileSystemDirectory *efd, const S
continue;
}
if (config->has_section_key("remap", "group_file")) {
-
config->set_value("remap", "group_file", p_new_location);
}
@@ -2076,7 +1991,6 @@ void EditorFileSystem::_move_group_files(EditorFileSystemDirectory *efd, const S
}
void EditorFileSystem::move_group_file(const String &p_path, const String &p_new_path) {
-
if (get_filesystem()) {
_move_group_files(get_filesystem(), p_path, p_new_path);
if (group_file_cache.has(p_path)) {
@@ -2087,7 +2001,6 @@ void EditorFileSystem::move_group_file(const String &p_path, const String &p_new
}
void EditorFileSystem::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_filesystem"), &EditorFileSystem::get_filesystem);
ClassDB::bind_method(D_METHOD("is_scanning"), &EditorFileSystem::is_scanning);
ClassDB::bind_method(D_METHOD("get_scanning_progress"), &EditorFileSystem::get_scanning_progress);
@@ -2105,27 +2018,23 @@ void EditorFileSystem::_bind_methods() {
}
void EditorFileSystem::_update_extensions() {
-
valid_extensions.clear();
import_extensions.clear();
List<String> extensionsl;
ResourceLoader::get_recognized_extensions_for_type("", &extensionsl);
for (List<String>::Element *E = extensionsl.front(); E; E = E->next()) {
-
valid_extensions.insert(E->get());
}
extensionsl.clear();
ResourceFormatImporter::get_singleton()->get_recognized_extensions(&extensionsl);
for (List<String>::Element *E = extensionsl.front(); E; E = E->next()) {
-
import_extensions.insert(E->get());
}
}
EditorFileSystem::EditorFileSystem() {
-
ResourceLoader::import = _resource_import;
reimport_on_missing_imported_files = GLOBAL_DEF("editor/reimport_missing_imported_files", true);
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index 55a2ed3d09..da27a63c64 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -40,7 +40,6 @@ class FileAccess;
struct EditorProgressBG;
class EditorFileSystemDirectory : public Object {
-
GDCLASS(EditorFileSystemDirectory, Object);
String name;
@@ -104,13 +103,11 @@ public:
};
class EditorFileSystem : public Node {
-
GDCLASS(EditorFileSystem, Node);
_THREAD_SAFE_CLASS_
struct ItemAction {
-
enum Action {
ACTION_NONE,
ACTION_DIR_ADD,
@@ -163,7 +160,6 @@ class EditorFileSystem : public Node {
/* Used for reading the filesystem cache file */
struct FileCache {
-
String type;
uint64_t modification_time;
uint64_t import_modification_time;
@@ -178,7 +174,6 @@ class EditorFileSystem : public Node {
HashMap<String, FileCache> file_cache;
struct ScanProgress {
-
float low;
float hi;
mutable EditorProgressBG *progress;
diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp
index 507a77e641..f0e6e3a799 100644
--- a/editor/editor_folding.cpp
+++ b/editor/editor_folding.cpp
@@ -35,7 +35,6 @@
#include "editor_settings.h"
Vector<String> EditorFolding::_get_unfolds(const Object *p_object) {
-
Vector<String> sections;
sections.resize(p_object->editor_get_section_folding().size());
if (sections.size()) {
@@ -61,7 +60,6 @@ void EditorFolding::save_resource_folding(const RES &p_resource, const String &p
}
void EditorFolding::_set_unfolds(Object *p_object, const Vector<String> &p_unfolds) {
-
int uc = p_unfolds.size();
const String *r = p_unfolds.ptr();
p_object->editor_clear_section_folding();
@@ -71,7 +69,6 @@ void EditorFolding::_set_unfolds(Object *p_object, const Vector<String> &p_unfol
}
void EditorFolding::load_resource_folding(RES p_resource, const String &p_path) {
-
Ref<ConfigFile> config;
config.instance();
@@ -117,7 +114,6 @@ void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p
if (E->get().type == Variant::OBJECT) {
RES res = p_node->get(E->get().name);
if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) {
-
Vector<String> res_unfolds = _get_unfolds(res.ptr());
resource_folds.push_back(res->get_path());
resource_folds.push_back(res_unfolds);
@@ -131,13 +127,14 @@ void EditorFolding::_fill_folds(const Node *p_root, const Node *p_node, Array &p
_fill_folds(p_root, p_node->get_child(i), p_folds, resource_folds, nodes_folded, resources);
}
}
-void EditorFolding::save_scene_folding(const Node *p_scene, const String &p_path) {
+void EditorFolding::save_scene_folding(const Node *p_scene, const String &p_path) {
ERR_FAIL_NULL(p_scene);
FileAccessRef file_check = FileAccess::create(FileAccess::ACCESS_RESOURCES);
- if (!file_check->file_exists(p_path)) //This can happen when creating scene from FilesystemDock. It has path, but no file.
+ if (!file_check->file_exists(p_path)) { //This can happen when creating scene from FilesystemDock. It has path, but no file.
return;
+ }
Ref<ConfigFile> config;
config.instance();
@@ -155,8 +152,8 @@ void EditorFolding::save_scene_folding(const Node *p_scene, const String &p_path
file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
config->save(file);
}
-void EditorFolding::load_scene_folding(Node *p_scene, const String &p_path) {
+void EditorFolding::load_scene_folding(Node *p_scene, const String &p_path) {
Ref<ConfigFile> config;
config.instance();
@@ -218,14 +215,12 @@ void EditorFolding::load_scene_folding(Node *p_scene, const String &p_path) {
}
bool EditorFolding::has_folding_data(const String &p_path) {
-
String file = p_path.get_file() + "-folding-" + p_path.md5_text() + ".cfg";
file = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(file);
return FileAccess::exists(file);
}
void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) {
-
List<PropertyInfo> plist;
p_object->get_property_list(&plist);
String group_base;
@@ -234,7 +229,6 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) {
Set<String> unfold_group;
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
if (E->get().usage & PROPERTY_USAGE_CATEGORY) {
group = "";
group_base = "";
@@ -249,7 +243,6 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) {
//can unfold
if (E->get().usage & PROPERTY_USAGE_EDITOR) {
-
if (group != "") { //group
if (group_base == String() || E->get().name.begins_with(group_base)) {
bool can_revert = EditorPropertyRevert::can_property_revert(p_object, E->get().name);
@@ -271,7 +264,6 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) {
if (E->get().type == Variant::OBJECT) {
RES res = p_object->get(E->get().name);
if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) {
-
resources.insert(res);
_do_object_unfolds(res.ptr(), resources);
}
@@ -301,7 +293,6 @@ void EditorFolding::_do_node_unfolds(Node *p_root, Node *p_node, Set<RES> &resou
}
void EditorFolding::unfold_scene(Node *p_scene) {
-
Set<RES> resources;
_do_node_unfolds(p_scene, p_scene, resources);
}
diff --git a/editor/editor_folding.h b/editor/editor_folding.h
index 5220907fe7..13f07b99b0 100644
--- a/editor/editor_folding.h
+++ b/editor/editor_folding.h
@@ -34,7 +34,6 @@
#include "scene/main/node.h"
class EditorFolding {
-
Vector<String> _get_unfolds(const Object *p_object);
void _set_unfolds(Object *p_object, const Vector<String> &p_unfolds);
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index 8aadf02ea6..cf00c536a7 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -247,10 +247,12 @@ void editor_register_fonts(Ref<Theme> p_theme) {
MAKE_BOLD_FONT(df_doc_bold, int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE);
MAKE_BOLD_FONT(df_doc_title, int(EDITOR_GET("text_editor/help/help_title_font_size")) * EDSCALE);
MAKE_SOURCE_FONT(df_doc_code, int(EDITOR_GET("text_editor/help/help_source_font_size")) * EDSCALE);
+ MAKE_SOURCE_FONT(df_doc_kbd, (int(EDITOR_GET("text_editor/help/help_source_font_size")) - 1) * EDSCALE);
p_theme->set_font("doc", "EditorFonts", df_doc);
p_theme->set_font("doc_bold", "EditorFonts", df_doc_bold);
p_theme->set_font("doc_title", "EditorFonts", df_doc_title);
p_theme->set_font("doc_source", "EditorFonts", df_doc_code);
+ p_theme->set_font("doc_keyboard", "EditorFonts", df_doc_kbd);
// Ruler font
MAKE_DEFAULT_FONT(df_rulers, 8 * EDSCALE);
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index a36e2f360e..30cf7d1e7a 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -30,7 +30,7 @@
#include "editor_help.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/keyboard.h"
#include "doc_data_compressed.gen.h"
#include "editor/plugins/script_editor_plugin.h"
@@ -43,49 +43,45 @@
DocData *EditorHelp::doc = nullptr;
void EditorHelp::_init_colors() {
-
title_color = get_theme_color("accent_color", "Editor");
text_color = get_theme_color("default_color", "RichTextLabel");
headline_color = get_theme_color("headline_color", "EditorHelp");
- base_type_color = title_color.linear_interpolate(text_color, 0.5);
+ base_type_color = title_color.lerp(text_color, 0.5);
comment_color = text_color * Color(1, 1, 1, 0.6);
symbol_color = comment_color;
value_color = text_color * Color(1, 1, 1, 0.6);
qualifier_color = text_color * Color(1, 1, 1, 0.8);
- type_color = get_theme_color("accent_color", "Editor").linear_interpolate(text_color, 0.5);
+ type_color = get_theme_color("accent_color", "Editor").lerp(text_color, 0.5);
class_desc->add_theme_color_override("selection_color", get_theme_color("accent_color", "Editor") * Color(1, 1, 1, 0.4));
class_desc->add_theme_constant_override("line_separation", Math::round(5 * EDSCALE));
}
void EditorHelp::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
-
- if (!is_visible_in_tree())
+ if (!is_visible_in_tree()) {
return;
+ }
Ref<InputEventKey> k = p_ev;
if (k.is_valid() && k->get_control() && k->get_keycode() == KEY_F) {
-
search->grab_focus();
search->select_all();
}
}
void EditorHelp::_search(bool p_search_previous) {
-
- if (p_search_previous)
+ if (p_search_previous) {
find_bar->search_prev();
- else
+ } else {
find_bar->search_next();
+ }
}
void EditorHelp::_class_list_select(const String &p_select) {
-
_goto_desc(p_select);
}
void EditorHelp::_class_desc_select(const String &p_select) {
-
if (p_select.begins_with("$")) { //enum
String select = p_select.substr(1, p_select.length());
String class_name;
@@ -182,10 +178,10 @@ void EditorHelp::_class_desc_resized() {
}
void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
-
String t = p_type;
- if (t.empty())
+ if (t.empty()) {
t = "void";
+ }
bool can_ref = (t != "void") || !p_enum.empty();
if (!p_enum.empty()) {
@@ -196,9 +192,14 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
}
}
const Color text_color = get_theme_color("default_color", "RichTextLabel");
- const Color type_color = get_theme_color("accent_color", "Editor").linear_interpolate(text_color, 0.5);
+ const Color type_color = get_theme_color("accent_color", "Editor").lerp(text_color, 0.5);
class_desc->push_color(type_color);
+ bool add_array = false;
if (can_ref) {
+ if (t.ends_with("[]")) {
+ add_array = true;
+ t = t.replace("[]", "");
+ }
if (p_enum.empty()) {
class_desc->push_meta("#" + t); //class
} else {
@@ -206,13 +207,19 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
}
}
class_desc->add_text(t);
- if (can_ref)
+ if (can_ref) {
class_desc->pop();
+ if (add_array) {
+ class_desc->add_text(" ");
+ class_desc->push_meta("#Array"); //class
+ class_desc->add_text("[]");
+ class_desc->pop();
+ }
+ }
class_desc->pop();
}
String EditorHelp::_fix_constant(const String &p_constant) const {
-
if (p_constant.strip_edges() == "4294967295") {
return "0xFFFFFFFF";
}
@@ -229,7 +236,6 @@ String EditorHelp::_fix_constant(const String &p_constant) const {
}
void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview) {
-
method_line[p_method.name] = class_desc->get_line_count() - 2; //gets overridden if description
const bool is_vararg = p_method.qualifiers.find("vararg") != -1;
@@ -267,14 +273,14 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
for (int j = 0; j < p_method.arguments.size(); j++) {
class_desc->push_color(text_color);
- if (j > 0)
+ if (j > 0) {
class_desc->add_text(", ");
+ }
_add_text(p_method.arguments[j].name);
class_desc->add_text(": ");
_add_type(p_method.arguments[j].type, p_method.arguments[j].enumeration);
if (p_method.arguments[j].default_value != "") {
-
class_desc->push_color(symbol_color);
class_desc->add_text(" = ");
class_desc->pop();
@@ -288,8 +294,9 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
if (is_vararg) {
class_desc->push_color(text_color);
- if (p_method.arguments.size())
+ if (p_method.arguments.size()) {
class_desc->add_text(", ");
+ }
class_desc->push_color(symbol_color);
class_desc->add_text("...");
class_desc->pop();
@@ -300,21 +307,21 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview
class_desc->add_text(")");
class_desc->pop();
if (p_method.qualifiers != "") {
-
class_desc->push_color(qualifier_color);
class_desc->add_text(" ");
_add_text(p_method.qualifiers);
class_desc->pop();
}
- if (p_overview)
+ if (p_overview) {
class_desc->pop(); //cell
+ }
}
Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
-
- if (!doc->class_list.has(p_class))
+ if (!doc->class_list.has(p_class)) {
return ERR_DOES_NOT_EXIST;
+ }
select_locked = true;
@@ -322,8 +329,9 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
description_line = 0;
- if (p_class == edited_class)
+ if (p_class == edited_class) {
return OK; //already there
+ }
edited_class = p_class;
_update_doc();
@@ -331,8 +339,9 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
}
void EditorHelp::_update_doc() {
- if (!doc->class_list.has(edited_class))
+ if (!doc->class_list.has(edited_class)) {
return;
+ }
scroll_locked = true;
@@ -366,7 +375,6 @@ void EditorHelp::_update_doc() {
// Ascendents
if (cd.inherits != "") {
-
class_desc->push_color(title_color);
class_desc->push_font(doc_font);
class_desc->add_text(TTR("Inherits:") + " ");
@@ -390,14 +398,11 @@ void EditorHelp::_update_doc() {
// Descendents
if (ClassDB::class_exists(cd.name)) {
-
bool found = false;
bool prev = false;
for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) {
-
if (E->get().inherits == cd.name) {
-
if (!found) {
class_desc->push_color(title_color);
class_desc->push_font(doc_font);
@@ -407,7 +412,6 @@ void EditorHelp::_update_doc() {
}
if (prev) {
-
class_desc->add_text(" , ");
}
@@ -427,7 +431,6 @@ void EditorHelp::_update_doc() {
// Brief description
if (cd.brief_description != "") {
-
class_desc->push_color(text_color);
class_desc->push_font(doc_bold_font);
class_desc->push_indent(1);
@@ -442,7 +445,6 @@ void EditorHelp::_update_doc() {
// Class description
if (cd.description != "") {
-
section_line.push_back(Pair<String, int>(TTR("Description"), class_desc->get_line_count() - 2));
description_line = class_desc->get_line_count() - 2;
class_desc->push_color(title_color);
@@ -502,7 +504,6 @@ void EditorHelp::_update_doc() {
bool property_descr = false;
if (cd.properties.size()) {
-
section_line.push_back(Pair<String, int>(TTR("Properties"), class_desc->get_line_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
@@ -514,7 +515,7 @@ void EditorHelp::_update_doc() {
class_desc->push_font(doc_code_font);
class_desc->push_indent(1);
class_desc->push_table(2);
- class_desc->set_table_column_expand(1, 1);
+ class_desc->set_table_column_expand(1, true);
for (int i = 0; i < cd.properties.size(); i++) {
property_line[cd.properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
@@ -602,9 +603,9 @@ void EditorHelp::_update_doc() {
}
if (methods.size()) {
-
- if (sort_methods)
+ if (sort_methods) {
methods.sort();
+ }
section_line.push_back(Pair<String, int>(TTR("Methods"), class_desc->get_line_count() - 2));
class_desc->push_color(title_color);
@@ -617,7 +618,7 @@ void EditorHelp::_update_doc() {
class_desc->push_font(doc_code_font);
class_desc->push_indent(1);
class_desc->push_table(2);
- class_desc->set_table_column_expand(1, 1);
+ class_desc->set_table_column_expand(1, true);
bool any_previous = false;
for (int pass = 0; pass < 2; pass++) {
@@ -676,7 +677,6 @@ void EditorHelp::_update_doc() {
// Theme properties
if (cd.theme_properties.size()) {
-
section_line.push_back(Pair<String, int>(TTR("Theme Properties"), class_desc->get_line_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
@@ -686,10 +686,9 @@ void EditorHelp::_update_doc() {
class_desc->push_indent(1);
class_desc->push_table(2);
- class_desc->set_table_column_expand(1, 1);
+ class_desc->set_table_column_expand(1, true);
for (int i = 0; i < cd.theme_properties.size(); i++) {
-
theme_property_line[cd.theme_properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
class_desc->push_cell();
@@ -739,7 +738,6 @@ void EditorHelp::_update_doc() {
// Signals
if (cd.signals.size()) {
-
if (sort_methods) {
cd.signals.sort();
}
@@ -757,7 +755,6 @@ void EditorHelp::_update_doc() {
class_desc->push_indent(1);
for (int i = 0; i < cd.signals.size(); i++) {
-
signal_line[cd.signals[i].name] = class_desc->get_line_count() - 2; //gets overridden if description
class_desc->push_font(doc_code_font); // monofont
class_desc->push_color(headline_color);
@@ -768,14 +765,14 @@ void EditorHelp::_update_doc() {
class_desc->pop();
for (int j = 0; j < cd.signals[i].arguments.size(); j++) {
class_desc->push_color(text_color);
- if (j > 0)
+ if (j > 0) {
class_desc->add_text(", ");
+ }
_add_text(cd.signals[i].arguments[j].name);
class_desc->add_text(": ");
_add_type(cd.signals[i].arguments[j].type);
if (cd.signals[i].arguments[j].default_value != "") {
-
class_desc->push_color(symbol_color);
class_desc->add_text(" = ");
class_desc->pop();
@@ -790,7 +787,6 @@ void EditorHelp::_update_doc() {
class_desc->pop();
class_desc->pop(); // end monofont
if (cd.signals[i].description != "") {
-
class_desc->push_font(doc_font);
class_desc->push_color(comment_color);
class_desc->push_indent(1);
@@ -809,12 +805,10 @@ void EditorHelp::_update_doc() {
// Constants and enums
if (cd.constants.size()) {
-
Map<String, Vector<DocData::ConstantDoc>> enums;
Vector<DocData::ConstantDoc> constants;
for (int i = 0; i < cd.constants.size(); i++) {
-
if (cd.constants[i].enumeration != String()) {
if (!enums.has(cd.constants[i].enumeration)) {
enums[cd.constants[i].enumeration] = Vector<DocData::ConstantDoc>();
@@ -822,14 +816,12 @@ void EditorHelp::_update_doc() {
enums[cd.constants[i].enumeration].push_back(cd.constants[i]);
} else {
-
constants.push_back(cd.constants[i]);
}
}
// Enums
if (enums.size()) {
-
section_line.push_back(Pair<String, int>(TTR("Enumerations"), class_desc->get_line_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
@@ -841,7 +833,6 @@ void EditorHelp::_update_doc() {
class_desc->add_newline();
for (Map<String, Vector<DocData::ConstantDoc>>::Element *E = enums.front(); E; E = E->next()) {
-
enum_line[E->key()] = class_desc->get_line_count() - 2;
class_desc->push_color(title_color);
@@ -869,8 +860,9 @@ void EditorHelp::_update_doc() {
int enumStartingLine = enum_line[E->key()];
for (int i = 0; i < enum_list.size(); i++) {
- if (cd.name == "@GlobalScope")
+ if (cd.name == "@GlobalScope") {
enumValuesContainer[enum_list[i].name] = enumStartingLine;
+ }
// Add the enum constant line to the constant_line map so we can locate it as a constant
constant_line[enum_list[i].name] = class_desc->get_line_count() - 2;
@@ -901,8 +893,9 @@ void EditorHelp::_update_doc() {
class_desc->add_newline();
}
- if (cd.name == "@GlobalScope")
+ if (cd.name == "@GlobalScope") {
enum_values_line[E->key()] = enumValuesContainer;
+ }
class_desc->pop();
@@ -915,7 +908,6 @@ void EditorHelp::_update_doc() {
// Constants
if (constants.size()) {
-
section_line.push_back(Pair<String, int>(TTR("Constants"), class_desc->get_line_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
@@ -927,7 +919,6 @@ void EditorHelp::_update_doc() {
class_desc->add_newline();
for (int i = 0; i < constants.size(); i++) {
-
constant_line[constants[i].name] = class_desc->get_line_count() - 2;
class_desc->push_font(doc_code_font);
@@ -974,7 +965,6 @@ void EditorHelp::_update_doc() {
// Property descriptions
if (property_descr) {
-
section_line.push_back(Pair<String, int>(TTR("Property Descriptions"), class_desc->get_line_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
@@ -986,14 +976,14 @@ void EditorHelp::_update_doc() {
class_desc->add_newline();
for (int i = 0; i < cd.properties.size(); i++) {
-
- if (cd.properties[i].overridden)
+ if (cd.properties[i].overridden) {
continue;
+ }
property_line[cd.properties[i].name] = class_desc->get_line_count() - 2;
class_desc->push_table(2);
- class_desc->set_table_column_expand(1, 1);
+ class_desc->set_table_column_expand(1, true);
class_desc->push_cell();
class_desc->push_font(doc_code_font);
@@ -1026,7 +1016,6 @@ void EditorHelp::_update_doc() {
class_desc->pop(); // cell
if (cd.properties[i].setter != "") {
-
class_desc->push_cell();
class_desc->pop(); // cell
@@ -1040,10 +1029,10 @@ void EditorHelp::_update_doc() {
class_desc->pop(); // color
class_desc->pop(); // font
class_desc->pop(); // cell
+ method_line[cd.properties[i].setter] = property_line[cd.properties[i].name];
}
if (cd.properties[i].getter != "") {
-
class_desc->push_cell();
class_desc->pop(); // cell
@@ -1057,6 +1046,7 @@ void EditorHelp::_update_doc() {
class_desc->pop(); //color
class_desc->pop(); //font
class_desc->pop(); //cell
+ method_line[cd.properties[i].getter] = property_line[cd.properties[i].name];
}
class_desc->pop(); // table
@@ -1087,7 +1077,6 @@ void EditorHelp::_update_doc() {
// Method descriptions
if (method_descr) {
-
section_line.push_back(Pair<String, int>(TTR("Method Descriptions"), class_desc->get_line_count() - 2));
class_desc->push_color(title_color);
class_desc->push_font(doc_title_font);
@@ -1109,7 +1098,6 @@ void EditorHelp::_update_doc() {
}
for (int i = 0; i < methods_filtered.size(); i++) {
-
class_desc->push_font(doc_code_font);
_add_method(methods_filtered[i], false);
class_desc->pop();
@@ -1151,12 +1139,12 @@ void EditorHelp::_request_help(const String &p_string) {
}
void EditorHelp::_help_callback(const String &p_topic) {
-
String what = p_topic.get_slice(":", 0);
String clss = p_topic.get_slice(":", 1);
String name;
- if (p_topic.get_slice_count(":") == 3)
+ if (p_topic.get_slice_count(":") == 3) {
name = p_topic.get_slice(":", 2);
+ }
_request_help(clss); //first go to class
@@ -1165,36 +1153,43 @@ void EditorHelp::_help_callback(const String &p_topic) {
if (what == "class_desc") {
line = description_line;
} else if (what == "class_signal") {
- if (signal_line.has(name))
+ if (signal_line.has(name)) {
line = signal_line[name];
+ }
} else if (what == "class_method" || what == "class_method_desc") {
- if (method_line.has(name))
+ if (method_line.has(name)) {
line = method_line[name];
+ }
} else if (what == "class_property") {
- if (property_line.has(name))
+ if (property_line.has(name)) {
line = property_line[name];
+ }
} else if (what == "class_enum") {
- if (enum_line.has(name))
+ if (enum_line.has(name)) {
line = enum_line[name];
+ }
} else if (what == "class_theme_item") {
- if (theme_property_line.has(name))
+ if (theme_property_line.has(name)) {
line = theme_property_line[name];
+ }
} else if (what == "class_constant") {
- if (constant_line.has(name))
+ if (constant_line.has(name)) {
line = constant_line[name];
+ }
} else if (what == "class_global") {
- if (constant_line.has(name))
+ if (constant_line.has(name)) {
line = constant_line[name];
- else {
+ } else {
Map<String, Map<String, int>>::Element *iter = enum_values_line.front();
while (true) {
if (iter->value().has(name)) {
line = iter->value()[name];
break;
- } else if (iter == enum_values_line.back())
+ } else if (iter == enum_values_line.back()) {
break;
- else
+ } else {
iter = iter->next();
+ }
}
}
}
@@ -1203,18 +1198,20 @@ void EditorHelp::_help_callback(const String &p_topic) {
}
static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
-
DocData *doc = EditorHelp::get_doc_data();
String base_path;
Ref<Font> doc_font = p_rt->get_theme_font("doc", "EditorFonts");
Ref<Font> doc_bold_font = p_rt->get_theme_font("doc_bold", "EditorFonts");
Ref<Font> doc_code_font = p_rt->get_theme_font("doc_source", "EditorFonts");
+ Ref<Font> doc_kbd_font = p_rt->get_theme_font("doc_keyboard", "EditorFonts");
Color font_color_hl = p_rt->get_theme_color("headline_color", "EditorHelp");
Color accent_color = p_rt->get_theme_color("accent_color", "Editor");
- Color link_color = accent_color.linear_interpolate(font_color_hl, 0.8);
- Color code_color = accent_color.linear_interpolate(font_color_hl, 0.6);
+ Color property_color = p_rt->get_theme_color("property_color", "Editor");
+ Color link_color = accent_color.lerp(font_color_hl, 0.8);
+ Color code_color = accent_color.lerp(font_color_hl, 0.6);
+ Color kbd_color = accent_color.lerp(property_color, 0.6);
String bbcode = p_bbcode.dedent().replace("\t", "").replace("\r", "").strip_edges();
@@ -1227,29 +1224,31 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
int pos = 0;
while (pos < bbcode.length()) {
-
int brk_pos = bbcode.find("[", pos);
- if (brk_pos < 0)
+ if (brk_pos < 0) {
brk_pos = bbcode.length();
+ }
if (brk_pos > pos) {
String text = bbcode.substr(pos, brk_pos - pos);
- if (!code_tag)
+ if (!code_tag) {
text = text.replace("\n", "\n\n");
+ }
p_rt->add_text(text);
}
- if (brk_pos == bbcode.length())
+ if (brk_pos == bbcode.length()) {
break; //nothing else to add
+ }
int brk_end = bbcode.find("]", brk_pos + 1);
if (brk_end == -1) {
-
String text = bbcode.substr(brk_pos, bbcode.length() - brk_pos);
- if (!code_tag)
+ if (!code_tag) {
text = text.replace("\n", "\n\n");
+ }
p_rt->add_text(text);
break;
@@ -1261,7 +1260,6 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length());
if (!tag_ok) {
-
p_rt->add_text("[");
pos = brk_pos + 1;
continue;
@@ -1278,12 +1276,10 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
code_tag = false;
} else if (code_tag) {
-
p_rt->add_text("[");
pos = brk_pos + 1;
} else if (tag.begins_with("method ") || tag.begins_with("member ") || tag.begins_with("signal ") || tag.begins_with("enum ") || tag.begins_with("constant ")) {
-
int tag_end = tag.find(" ");
String link_tag = tag.substr(0, tag_end);
@@ -1297,7 +1293,6 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
pos = brk_end + 1;
} else if (doc->class_list.has(tag)) {
-
p_rt->push_color(link_color);
p_rt->push_meta("#" + tag);
p_rt->add_text(tag);
@@ -1306,132 +1301,131 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
pos = brk_end + 1;
} else if (tag == "b") {
-
//use bold font
p_rt->push_font(doc_bold_font);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "i") {
-
//use italics font
p_rt->push_color(font_color_hl);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "code" || tag == "codeblock") {
-
//use monospace font
p_rt->push_font(doc_code_font);
p_rt->push_color(code_color);
code_tag = true;
pos = brk_end + 1;
tag_stack.push_front(tag);
+ } else if (tag == "kbd") {
+ //use keyboard font with custom color
+ p_rt->push_font(doc_kbd_font);
+ p_rt->push_color(kbd_color);
+ code_tag = true; // though not strictly a code tag, logic is similar
+ pos = brk_end + 1;
+ tag_stack.push_front(tag);
} else if (tag == "center") {
-
//align to center
p_rt->push_align(RichTextLabel::ALIGN_CENTER);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "br") {
-
//force a line break
p_rt->add_newline();
pos = brk_end + 1;
} else if (tag == "u") {
-
//use underline
p_rt->push_underline();
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "s") {
-
//use strikethrough
p_rt->push_strikethrough();
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "url") {
-
int end = bbcode.find("[", brk_end);
- if (end == -1)
+ if (end == -1) {
end = bbcode.length();
+ }
String url = bbcode.substr(brk_end + 1, end - brk_end - 1);
p_rt->push_meta(url);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag.begins_with("url=")) {
-
String url = tag.substr(4, tag.length());
p_rt->push_meta(url);
pos = brk_end + 1;
tag_stack.push_front("url");
} else if (tag == "img") {
-
int end = bbcode.find("[", brk_end);
- if (end == -1)
+ if (end == -1) {
end = bbcode.length();
+ }
String image = bbcode.substr(brk_end + 1, end - brk_end - 1);
Ref<Texture2D> texture = ResourceLoader::load(base_path.plus_file(image), "Texture2D");
- if (texture.is_valid())
+ if (texture.is_valid()) {
p_rt->add_image(texture);
+ }
pos = end;
tag_stack.push_front(tag);
} else if (tag.begins_with("color=")) {
-
String col = tag.substr(6, tag.length());
Color color;
- if (col.begins_with("#"))
+ if (col.begins_with("#")) {
color = Color::html(col);
- else if (col == "aqua")
+ } else if (col == "aqua") {
color = Color(0, 1, 1);
- else if (col == "black")
+ } else if (col == "black") {
color = Color(0, 0, 0);
- else if (col == "blue")
+ } else if (col == "blue") {
color = Color(0, 0, 1);
- else if (col == "fuchsia")
+ } else if (col == "fuchsia") {
color = Color(1, 0, 1);
- else if (col == "gray" || col == "grey")
+ } else if (col == "gray" || col == "grey") {
color = Color(0.5, 0.5, 0.5);
- else if (col == "green")
+ } else if (col == "green") {
color = Color(0, 0.5, 0);
- else if (col == "lime")
+ } else if (col == "lime") {
color = Color(0, 1, 0);
- else if (col == "maroon")
+ } else if (col == "maroon") {
color = Color(0.5, 0, 0);
- else if (col == "navy")
+ } else if (col == "navy") {
color = Color(0, 0, 0.5);
- else if (col == "olive")
+ } else if (col == "olive") {
color = Color(0.5, 0.5, 0);
- else if (col == "purple")
+ } else if (col == "purple") {
color = Color(0.5, 0, 0.5);
- else if (col == "red")
+ } else if (col == "red") {
color = Color(1, 0, 0);
- else if (col == "silver")
+ } else if (col == "silver") {
color = Color(0.75, 0.75, 0.75);
- else if (col == "teal")
+ } else if (col == "teal") {
color = Color(0, 0.5, 0.5);
- else if (col == "white")
+ } else if (col == "white") {
color = Color(1, 1, 1);
- else if (col == "yellow")
+ } else if (col == "yellow") {
color = Color(1, 1, 0);
- else
+ } else {
color = Color(0, 0, 0); //base_color;
+ }
p_rt->push_color(color);
pos = brk_end + 1;
tag_stack.push_front("color");
} else if (tag.begins_with("font=")) {
-
String fnt = tag.substr(5, tag.length());
Ref<Font> font = ResourceLoader::load(base_path.plus_file(fnt), "Font");
- if (font.is_valid())
+ if (font.is_valid()) {
p_rt->push_font(font);
- else {
+ } else {
p_rt->push_font(doc_font);
}
@@ -1439,7 +1433,6 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) {
tag_stack.push_front("font");
} else {
-
p_rt->add_text("["); //ignore
pos = brk_pos + 1;
}
@@ -1451,7 +1444,6 @@ void EditorHelp::_add_text(const String &p_bbcode) {
}
void EditorHelp::generate_doc() {
-
doc = memnew(DocData);
doc->generate(true);
DocData compdoc;
@@ -1460,11 +1452,9 @@ void EditorHelp::generate_doc() {
}
void EditorHelp::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_READY:
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
-
_update_doc();
} break;
case NOTIFICATION_THEME_CHANGED: {
@@ -1472,17 +1462,16 @@ void EditorHelp::_notification(int p_what) {
_class_desc_resized();
}
} break;
- default: break;
+ default:
+ break;
}
}
void EditorHelp::go_to_help(const String &p_help) {
-
_help_callback(p_help);
}
void EditorHelp::go_to_class(const String &p_class, int p_scroll) {
-
_goto_desc(p_class, p_scroll);
}
@@ -1501,12 +1490,10 @@ void EditorHelp::scroll_to_section(int p_section_index) {
}
void EditorHelp::popup_search() {
-
find_bar->popup_search();
}
String EditorHelp::get_class() {
-
return edited_class;
}
@@ -1515,16 +1502,14 @@ void EditorHelp::search_again(bool p_search_previous) {
}
int EditorHelp::get_scroll() const {
-
return class_desc->get_v_scroll()->get_value();
}
-void EditorHelp::set_scroll(int p_scroll) {
+void EditorHelp::set_scroll(int p_scroll) {
class_desc->get_v_scroll()->set_value(p_scroll);
}
void EditorHelp::_bind_methods() {
-
ClassDB::bind_method("_class_list_select", &EditorHelp::_class_list_select);
ClassDB::bind_method("_request_help", &EditorHelp::_request_help);
ClassDB::bind_method("_unhandled_key_input", &EditorHelp::_unhandled_key_input);
@@ -1535,7 +1520,6 @@ void EditorHelp::_bind_methods() {
}
EditorHelp::EditorHelp() {
-
set_custom_minimum_size(Size2(150 * EDSCALE, 0));
EDITOR_DEF("text_editor/help/sort_functions_alphabetically", true);
@@ -1567,14 +1551,12 @@ EditorHelp::~EditorHelp() {
}
void EditorHelpBit::_go_to_help(String p_what) {
-
EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
ScriptEditor::get_singleton()->goto_help(p_what);
emit_signal("request_hide");
}
void EditorHelpBit::_meta_clicked(String p_select) {
-
if (p_select.begins_with("$")) { //enum
String select = p_select.substr(1, p_select.length());
@@ -1587,26 +1569,23 @@ void EditorHelpBit::_meta_clicked(String p_select) {
_go_to_help("class_enum:" + class_name + ":" + select);
return;
} else if (p_select.begins_with("#")) {
-
_go_to_help("class_name:" + p_select.substr(1, p_select.length()));
return;
} else if (p_select.begins_with("@")) {
-
String m = p_select.substr(1, p_select.length());
- if (m.find(".") != -1)
+ if (m.find(".") != -1) {
_go_to_help("class_method:" + m.get_slice(".", 0) + ":" + m.get_slice(".", 0)); //must go somewhere else
+ }
}
}
void EditorHelpBit::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_text", "text"), &EditorHelpBit::set_text);
ADD_SIGNAL(MethodInfo("request_hide"));
}
void EditorHelpBit::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_READY: {
rich_text->clear();
@@ -1614,22 +1593,20 @@ void EditorHelpBit::_notification(int p_what) {
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
-
rich_text->add_theme_color_override("selection_color", get_theme_color("accent_color", "Editor") * Color(1, 1, 1, 0.4));
} break;
- default: break;
+ default:
+ break;
}
}
void EditorHelpBit::set_text(const String &p_text) {
-
text = p_text;
rich_text->clear();
_add_text_to_rt(text, rich_text);
}
EditorHelpBit::EditorHelpBit() {
-
rich_text = memnew(RichTextLabel);
add_child(rich_text);
rich_text->connect("meta_clicked", callable_mp(this, &EditorHelpBit::_meta_clicked));
@@ -1639,7 +1616,6 @@ EditorHelpBit::EditorHelpBit() {
}
FindBar::FindBar() {
-
search_text = memnew(LineEdit);
add_child(search_text);
search_text->set_custom_minimum_size(Size2(100 * EDSCALE, 0));
@@ -1674,7 +1650,6 @@ FindBar::FindBar() {
}
void FindBar::popup_search() {
-
show();
bool grabbed_focus = false;
if (!search_text->has_focus()) {
@@ -1692,11 +1667,9 @@ void FindBar::popup_search() {
}
void FindBar::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
-
find_prev->set_icon(get_theme_icon("MoveUp", "EditorIcons"));
find_next->set_icon(get_theme_icon("MoveDown", "EditorIcons"));
hide_button->set_normal_texture(get_theme_icon("Close", "EditorIcons"));
@@ -1706,36 +1679,30 @@ void FindBar::_notification(int p_what) {
matches_label->add_theme_color_override("font_color", results_count > 0 ? get_theme_color("font_color", "Label") : get_theme_color("error_color", "Editor"));
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
set_process_unhandled_input(is_visible_in_tree());
} break;
}
}
void FindBar::_bind_methods() {
-
ClassDB::bind_method("_unhandled_input", &FindBar::_unhandled_input);
ADD_SIGNAL(MethodInfo("search"));
}
void FindBar::set_rich_text_label(RichTextLabel *p_rich_text_label) {
-
rich_text_label = p_rich_text_label;
}
bool FindBar::search_next() {
-
return _search();
}
bool FindBar::search_prev() {
-
return _search(true);
}
bool FindBar::_search(bool p_search_previous) {
-
String stext = search_text->get_text();
bool keep = prev_search == stext;
@@ -1757,11 +1724,12 @@ bool FindBar::_search(bool p_search_previous) {
}
void FindBar::_update_results_count() {
-
results_count = 0;
String searched = search_text->get_text();
- if (searched.empty()) return;
+ if (searched.empty()) {
+ return;
+ }
String full_text = rich_text_label->get_text();
@@ -1769,8 +1737,9 @@ void FindBar::_update_results_count() {
while (true) {
int pos = full_text.find(searched, from_pos);
- if (pos == -1)
+ if (pos == -1) {
break;
+ }
results_count++;
from_pos = pos + searched.length();
@@ -1778,7 +1747,6 @@ void FindBar::_update_results_count() {
}
void FindBar::_update_matches_label() {
-
if (search_text->get_text().empty() || results_count == -1) {
matches_label->hide();
} else {
@@ -1790,30 +1758,24 @@ void FindBar::_update_matches_label() {
}
void FindBar::_hide_bar() {
-
- if (search_text->has_focus())
+ if (search_text->has_focus()) {
rich_text_label->grab_focus();
+ }
hide();
}
void FindBar::_unhandled_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
-
if (k->is_pressed() && (rich_text_label->has_focus() || is_a_parent_of(get_focus_owner()))) {
-
bool accepted = true;
switch (k->get_keycode()) {
-
case KEY_ESCAPE: {
-
_hide_bar();
} break;
default: {
-
accepted = false;
} break;
}
@@ -1826,13 +1788,11 @@ void FindBar::_unhandled_input(const Ref<InputEvent> &p_event) {
}
void FindBar::_search_text_changed(const String &p_text) {
-
search_next();
}
void FindBar::_search_text_entered(const String &p_text) {
-
- if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
search_prev();
} else {
search_next();
diff --git a/editor/editor_help.h b/editor/editor_help.h
index 2e053e674f..4d42c1d38a 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -88,7 +88,6 @@ public:
};
class EditorHelp : public VBoxContainer {
-
GDCLASS(EditorHelp, VBoxContainer);
enum Page {
@@ -193,7 +192,6 @@ public:
};
class EditorHelpBit : public MarginContainer {
-
GDCLASS(EditorHelpBit, MarginContainer);
RichTextLabel *rich_text;
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index 01a50cad2c..5bfcbf06fc 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -36,33 +36,33 @@
#include "editor_scale.h"
void EditorHelpSearch::_update_icons() {
-
search_box->set_right_icon(results_tree->get_theme_icon("Search", "EditorIcons"));
search_box->set_clear_button_enabled(true);
search_box->add_theme_icon_override("right_icon", results_tree->get_theme_icon("Search", "EditorIcons"));
case_sensitive_button->set_icon(results_tree->get_theme_icon("MatchCase", "EditorIcons"));
hierarchy_button->set_icon(results_tree->get_theme_icon("ClassList", "EditorIcons"));
- if (is_visible())
+ if (is_visible()) {
_update_results();
+ }
}
void EditorHelpSearch::_update_results() {
-
String term = search_box->get_text();
int search_flags = filter_combo->get_selected_id();
- if (case_sensitive_button->is_pressed())
+ if (case_sensitive_button->is_pressed()) {
search_flags |= SEARCH_CASE_SENSITIVE;
- if (hierarchy_button->is_pressed())
+ }
+ if (hierarchy_button->is_pressed()) {
search_flags |= SEARCH_SHOW_HIERARCHY;
+ }
search = Ref<Runner>(memnew(Runner(results_tree, results_tree, term, search_flags)));
set_process(true);
}
void EditorHelpSearch::_search_box_gui_input(const Ref<InputEvent> &p_event) {
-
// Redirect up and down navigational key events to the results list.
Ref<InputEventKey> key = p_event;
if (key.is_valid()) {
@@ -79,20 +79,18 @@ void EditorHelpSearch::_search_box_gui_input(const Ref<InputEvent> &p_event) {
}
void EditorHelpSearch::_search_box_text_changed(const String &p_text) {
-
_update_results();
}
void EditorHelpSearch::_filter_combo_item_selected(int p_option) {
-
_update_results();
}
void EditorHelpSearch::_confirmed() {
-
TreeItem *item = results_tree->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
// Activate the script editor and emit the signal with the documentation link to display.
EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
@@ -103,7 +101,6 @@ void EditorHelpSearch::_confirmed() {
}
void EditorHelpSearch::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (!is_visible()) {
@@ -113,27 +110,25 @@ void EditorHelpSearch::_notification(int p_what) {
}
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
-
_update_icons();
} break;
case NOTIFICATION_ENTER_TREE: {
-
connect("confirmed", callable_mp(this, &EditorHelpSearch::_confirmed));
_update_icons();
} break;
case NOTIFICATION_PROCESS: {
-
// Update background search.
if (search.is_valid()) {
if (search->work()) {
// Search done.
// Only point to the perfect match if it's a new search, and not just reopening a old one.
- if (!old_search)
+ if (!old_search) {
results_tree->ensure_cursor_is_visible();
- else
+ } else {
old_search = false;
+ }
get_ok()->set_disabled(!results_tree->get_selected());
@@ -148,31 +143,30 @@ void EditorHelpSearch::_notification(int p_what) {
}
void EditorHelpSearch::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("go_to_help"));
}
void EditorHelpSearch::popup_dialog() {
-
popup_dialog(search_box->get_text());
}
void EditorHelpSearch::popup_dialog(const String &p_term) {
-
// Restore valid window bounds or pop up at default size.
Rect2 saved_size = EditorSettings::get_singleton()->get_project_metadata("dialog_bounds", "search_help", Rect2());
- if (saved_size != Rect2())
+ if (saved_size != Rect2()) {
popup(saved_size);
- else
+ } else {
popup_centered_ratio(0.5F);
+ }
if (p_term == "") {
search_box->clear();
} else {
- if (old_term == p_term)
+ if (old_term == p_term) {
old_search = true;
- else
+ } else {
old_term = p_term;
+ }
search_box->set_text(p_term);
search_box->select_all();
@@ -182,7 +176,6 @@ void EditorHelpSearch::popup_dialog(const String &p_term) {
}
EditorHelpSearch::EditorHelpSearch() {
-
old_search = false;
set_hide_on_ok(false);
@@ -254,7 +247,6 @@ EditorHelpSearch::EditorHelpSearch() {
}
bool EditorHelpSearch::Runner::_is_class_disabled_by_feature_profile(const StringName &p_class) {
-
Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile();
if (profile.is_null()) {
return false;
@@ -262,7 +254,6 @@ bool EditorHelpSearch::Runner::_is_class_disabled_by_feature_profile(const Strin
StringName class_name = p_class;
while (class_name != StringName()) {
-
if (!ClassDB::class_exists(class_name)) {
return false;
}
@@ -277,7 +268,6 @@ bool EditorHelpSearch::Runner::_is_class_disabled_by_feature_profile(const Strin
}
bool EditorHelpSearch::Runner::_slice() {
-
bool phase_done = false;
switch (phase) {
case PHASE_MATCH_CLASSES_INIT:
@@ -308,13 +298,13 @@ bool EditorHelpSearch::Runner::_slice() {
return true;
};
- if (phase_done)
+ if (phase_done) {
phase++;
+ }
return false;
}
bool EditorHelpSearch::Runner::_phase_match_classes_init() {
-
iterator_doc = EditorHelp::get_doc_data()->class_list.front();
matches.clear();
matched_item = nullptr;
@@ -323,51 +313,66 @@ bool EditorHelpSearch::Runner::_phase_match_classes_init() {
}
bool EditorHelpSearch::Runner::_phase_match_classes() {
-
DocData::ClassDoc &class_doc = iterator_doc->value();
if (!_is_class_disabled_by_feature_profile(class_doc.name)) {
-
matches[class_doc.name] = ClassMatch();
ClassMatch &match = matches[class_doc.name];
match.doc = &class_doc;
// Match class name.
- if (search_flags & SEARCH_CLASSES)
+ if (search_flags & SEARCH_CLASSES) {
match.name = term == "" || _match_string(term, class_doc.name);
+ }
// Match members if the term is long enough.
if (term.length() > 1) {
- if (search_flags & SEARCH_METHODS)
+ if (search_flags & SEARCH_METHODS) {
for (int i = 0; i < class_doc.methods.size(); i++) {
String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.methods[i].name : class_doc.methods[i].name.to_lower();
String aux_term = (search_flags & SEARCH_CASE_SENSITIVE) ? term : term.to_lower();
- if (aux_term.begins_with("."))
+ if (aux_term.begins_with(".")) {
aux_term = aux_term.right(1);
+ }
- if (aux_term.ends_with("("))
+ if (aux_term.ends_with("(")) {
aux_term = aux_term.left(aux_term.length() - 1).strip_edges();
+ }
- if (aux_term.is_subsequence_of(method_name))
+ if (aux_term.is_subsequence_of(method_name)) {
match.methods.push_back(const_cast<DocData::MethodDoc *>(&class_doc.methods[i]));
+ }
}
- if (search_flags & SEARCH_SIGNALS)
- for (int i = 0; i < class_doc.signals.size(); i++)
- if (_match_string(term, class_doc.signals[i].name))
+ }
+ if (search_flags & SEARCH_SIGNALS) {
+ for (int i = 0; i < class_doc.signals.size(); i++) {
+ if (_match_string(term, class_doc.signals[i].name)) {
match.signals.push_back(const_cast<DocData::MethodDoc *>(&class_doc.signals[i]));
- if (search_flags & SEARCH_CONSTANTS)
- for (int i = 0; i < class_doc.constants.size(); i++)
- if (_match_string(term, class_doc.constants[i].name))
+ }
+ }
+ }
+ if (search_flags & SEARCH_CONSTANTS) {
+ for (int i = 0; i < class_doc.constants.size(); i++) {
+ if (_match_string(term, class_doc.constants[i].name)) {
match.constants.push_back(const_cast<DocData::ConstantDoc *>(&class_doc.constants[i]));
- if (search_flags & SEARCH_PROPERTIES)
- for (int i = 0; i < class_doc.properties.size(); i++)
- if (_match_string(term, class_doc.properties[i].name) || _match_string(term, class_doc.properties[i].getter) || _match_string(term, class_doc.properties[i].setter))
+ }
+ }
+ }
+ if (search_flags & SEARCH_PROPERTIES) {
+ for (int i = 0; i < class_doc.properties.size(); i++) {
+ if (_match_string(term, class_doc.properties[i].name) || _match_string(term, class_doc.properties[i].getter) || _match_string(term, class_doc.properties[i].setter)) {
match.properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc.properties[i]));
- if (search_flags & SEARCH_THEME_ITEMS)
- for (int i = 0; i < class_doc.theme_properties.size(); i++)
- if (_match_string(term, class_doc.theme_properties[i].name))
+ }
+ }
+ }
+ if (search_flags & SEARCH_THEME_ITEMS) {
+ for (int i = 0; i < class_doc.theme_properties.size(); i++) {
+ if (_match_string(term, class_doc.theme_properties[i].name)) {
match.theme_properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc.theme_properties[i]));
+ }
+ }
+ }
}
}
@@ -376,7 +381,6 @@ bool EditorHelpSearch::Runner::_phase_match_classes() {
}
bool EditorHelpSearch::Runner::_phase_class_items_init() {
-
iterator_match = matches.front();
results_tree->clear();
@@ -387,15 +391,16 @@ bool EditorHelpSearch::Runner::_phase_class_items_init() {
}
bool EditorHelpSearch::Runner::_phase_class_items() {
-
ClassMatch &match = iterator_match->value();
if (search_flags & SEARCH_SHOW_HIERARCHY) {
- if (match.required())
+ if (match.required()) {
_create_class_hierarchy(match);
+ }
} else {
- if (match.name)
+ if (match.name) {
_create_class_item(root_item, match.doc, false);
+ }
}
iterator_match = iterator_match->next();
@@ -403,64 +408,68 @@ bool EditorHelpSearch::Runner::_phase_class_items() {
}
bool EditorHelpSearch::Runner::_phase_member_items_init() {
-
iterator_match = matches.front();
return true;
}
bool EditorHelpSearch::Runner::_phase_member_items() {
-
ClassMatch &match = iterator_match->value();
TreeItem *parent = (search_flags & SEARCH_SHOW_HIERARCHY) ? class_items[match.doc->name] : root_item;
- for (int i = 0; i < match.methods.size(); i++)
+ for (int i = 0; i < match.methods.size(); i++) {
_create_method_item(parent, match.doc, match.methods[i]);
- for (int i = 0; i < match.signals.size(); i++)
+ }
+ for (int i = 0; i < match.signals.size(); i++) {
_create_signal_item(parent, match.doc, match.signals[i]);
- for (int i = 0; i < match.constants.size(); i++)
+ }
+ for (int i = 0; i < match.constants.size(); i++) {
_create_constant_item(parent, match.doc, match.constants[i]);
- for (int i = 0; i < match.properties.size(); i++)
+ }
+ for (int i = 0; i < match.properties.size(); i++) {
_create_property_item(parent, match.doc, match.properties[i]);
- for (int i = 0; i < match.theme_properties.size(); i++)
+ }
+ for (int i = 0; i < match.theme_properties.size(); i++) {
_create_theme_property_item(parent, match.doc, match.theme_properties[i]);
+ }
iterator_match = iterator_match->next();
return !iterator_match;
}
bool EditorHelpSearch::Runner::_phase_select_match() {
-
- if (matched_item)
+ if (matched_item) {
matched_item->select(0);
+ }
return true;
}
bool EditorHelpSearch::Runner::_match_string(const String &p_term, const String &p_string) const {
-
- if (search_flags & SEARCH_CASE_SENSITIVE)
+ if (search_flags & SEARCH_CASE_SENSITIVE) {
return p_term.is_subsequence_of(p_string);
- else
+ } else {
return p_term.is_subsequence_ofi(p_string);
+ }
}
void EditorHelpSearch::Runner::_match_item(TreeItem *p_item, const String &p_text) {
-
if (!matched_item) {
if (search_flags & SEARCH_CASE_SENSITIVE) {
- if (p_text.casecmp_to(term) == 0)
+ if (p_text.casecmp_to(term) == 0) {
matched_item = p_item;
+ }
} else {
- if (p_text.nocasecmp_to(term) == 0)
+ if (p_text.nocasecmp_to(term) == 0) {
matched_item = p_item;
+ }
}
}
}
TreeItem *EditorHelpSearch::Runner::_create_class_hierarchy(const ClassMatch &p_match) {
-
- if (class_items.has(p_match.doc->name))
+ if (class_items.has(p_match.doc->name)) {
return class_items[p_match.doc->name];
+ }
// Ensure parent nodes are created first.
TreeItem *parent = root_item;
@@ -479,12 +488,12 @@ TreeItem *EditorHelpSearch::Runner::_create_class_hierarchy(const ClassMatch &p_
}
TreeItem *EditorHelpSearch::Runner::_create_class_item(TreeItem *p_parent, const DocData::ClassDoc *p_doc, bool p_gray) {
-
Ref<Texture2D> icon = empty_icon;
- if (ui_service->has_theme_icon(p_doc->name, "EditorIcons"))
+ if (ui_service->has_theme_icon(p_doc->name, "EditorIcons")) {
icon = ui_service->get_theme_icon(p_doc->name, "EditorIcons");
- else if (ClassDB::class_exists(p_doc->name) && ClassDB::is_parent_class(p_doc->name, "Object"))
+ } else if (ClassDB::class_exists(p_doc->name) && ClassDB::is_parent_class(p_doc->name, "Object")) {
icon = ui_service->get_theme_icon("Object", "EditorIcons");
+ }
String tooltip = p_doc->brief_description.strip_edges();
TreeItem *item = results_tree->create_item(p_parent);
@@ -505,43 +514,43 @@ TreeItem *EditorHelpSearch::Runner::_create_class_item(TreeItem *p_parent, const
}
TreeItem *EditorHelpSearch::Runner::_create_method_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::MethodDoc *p_doc) {
-
String tooltip = p_doc->return_type + " " + p_class_doc->name + "." + p_doc->name + "(";
for (int i = 0; i < p_doc->arguments.size(); i++) {
const DocData::ArgumentDoc &arg = p_doc->arguments[i];
tooltip += arg.type + " " + arg.name;
- if (arg.default_value != "")
+ if (arg.default_value != "") {
tooltip += " = " + arg.default_value;
- if (i < p_doc->arguments.size() - 1)
+ }
+ if (i < p_doc->arguments.size() - 1) {
tooltip += ", ";
+ }
}
tooltip += ")";
return _create_member_item(p_parent, p_class_doc->name, "MemberMethod", p_doc->name, TTRC("Method"), "method", tooltip);
}
TreeItem *EditorHelpSearch::Runner::_create_signal_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::MethodDoc *p_doc) {
-
String tooltip = p_doc->return_type + " " + p_class_doc->name + "." + p_doc->name + "(";
for (int i = 0; i < p_doc->arguments.size(); i++) {
const DocData::ArgumentDoc &arg = p_doc->arguments[i];
tooltip += arg.type + " " + arg.name;
- if (arg.default_value != "")
+ if (arg.default_value != "") {
tooltip += " = " + arg.default_value;
- if (i < p_doc->arguments.size() - 1)
+ }
+ if (i < p_doc->arguments.size() - 1) {
tooltip += ", ";
+ }
}
tooltip += ")";
return _create_member_item(p_parent, p_class_doc->name, "MemberSignal", p_doc->name, TTRC("Signal"), "signal", tooltip);
}
TreeItem *EditorHelpSearch::Runner::_create_constant_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::ConstantDoc *p_doc) {
-
String tooltip = p_class_doc->name + "." + p_doc->name;
return _create_member_item(p_parent, p_class_doc->name, "MemberConstant", p_doc->name, TTRC("Constant"), "constant", tooltip);
}
TreeItem *EditorHelpSearch::Runner::_create_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::PropertyDoc *p_doc) {
-
String tooltip = p_doc->type + " " + p_class_doc->name + "." + p_doc->name;
tooltip += "\n " + p_class_doc->name + "." + p_doc->setter + "(value) setter";
tooltip += "\n " + p_class_doc->name + "." + p_doc->getter + "() getter";
@@ -549,13 +558,11 @@ TreeItem *EditorHelpSearch::Runner::_create_property_item(TreeItem *p_parent, co
}
TreeItem *EditorHelpSearch::Runner::_create_theme_property_item(TreeItem *p_parent, const DocData::ClassDoc *p_class_doc, const DocData::PropertyDoc *p_doc) {
-
String tooltip = p_doc->type + " " + p_class_doc->name + "." + p_doc->name;
return _create_member_item(p_parent, p_class_doc->name, "MemberTheme", p_doc->name, TTRC("Theme Property"), "theme_item", tooltip);
}
TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, const String &p_class_name, const String &p_icon, const String &p_name, const String &p_type, const String &p_metatype, const String &p_tooltip) {
-
Ref<Texture2D> icon;
String text;
if (search_flags & SEARCH_SHOW_HIERARCHY) {
@@ -564,10 +571,10 @@ TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, cons
} else {
icon = ui_service->get_theme_icon(p_icon, "EditorIcons");
/*// In flat mode, show the class icon.
- if (ui_service->has_icon(p_class_name, "EditorIcons"))
- icon = ui_service->get_icon(p_class_name, "EditorIcons");
- else if (ClassDB::is_parent_class(p_class_name, "Object"))
- icon = ui_service->get_icon("Object", "EditorIcons");*/
+if (ui_service->has_icon(p_class_name, "EditorIcons"))
+icon = ui_service->get_icon(p_class_name, "EditorIcons");
+else if (ClassDB::is_parent_class(p_class_name, "Object"))
+icon = ui_service->get_icon("Object", "EditorIcons");*/
text = p_class_name + "." + p_name;
}
@@ -585,17 +592,17 @@ TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, cons
}
bool EditorHelpSearch::Runner::work(uint64_t slot) {
-
// Return true when the search has been completed, otherwise false.
const uint64_t until = OS::get_singleton()->get_ticks_usec() + slot;
- while (!_slice())
- if (OS::get_singleton()->get_ticks_usec() > until)
+ while (!_slice()) {
+ if (OS::get_singleton()->get_ticks_usec() > until) {
return false;
+ }
+ }
return true;
}
EditorHelpSearch::Runner::Runner(Control *p_icon_service, Tree *p_results_tree, const String &p_term, int p_search_flags) :
- phase(0),
ui_service(p_icon_service),
results_tree(p_results_tree),
term((p_search_flags & SEARCH_CASE_SENSITIVE) == 0 ? p_term.strip_edges().to_lower() : p_term.strip_edges()),
diff --git a/editor/editor_help_search.h b/editor/editor_help_search.h
index feff96d2e5..f7dbc5c3ad 100644
--- a/editor/editor_help_search.h
+++ b/editor/editor_help_search.h
@@ -84,7 +84,6 @@ public:
};
class EditorHelpSearch::Runner : public Reference {
-
enum Phase {
PHASE_MATCH_CLASSES_INIT,
PHASE_MATCH_CLASSES,
@@ -95,7 +94,7 @@ class EditorHelpSearch::Runner : public Reference {
PHASE_SELECT_MATCH,
PHASE_MAX
};
- int phase;
+ int phase = 0;
struct ClassMatch {
DocData::ClassDoc *doc;
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 8fcd5bacb6..1b423f69b7 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -39,22 +39,24 @@
#include "scene/resources/packed_scene.h"
Size2 EditorProperty::get_minimum_size() const {
-
Size2 ms;
Ref<Font> font = get_theme_font("font", "Tree");
ms.height = font->get_height();
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
- if (!c->is_visible())
+ }
+ if (!c->is_visible()) {
continue;
- if (c == bottom_editor)
+ }
+ if (c == bottom_editor) {
continue;
+ }
Size2 minsize = c->get_combined_minimum_size();
ms.width = MAX(ms.width, minsize.width);
@@ -88,7 +90,6 @@ Size2 EditorProperty::get_minimum_size() const {
}
void EditorProperty::emit_changed(const StringName &p_property, const Variant &p_value, const StringName &p_field, bool p_changing) {
-
Variant args[4] = { p_property, p_value, p_field, p_changing };
const Variant *argptrs[4] = { &args[0], &args[1], &args[2], &args[3] };
@@ -96,9 +97,7 @@ void EditorProperty::emit_changed(const StringName &p_property, const Variant &p
}
void EditorProperty::_notification(int p_what) {
-
if (p_what == NOTIFICATION_SORT_CHILDREN) {
-
Size2 size = get_size();
Rect2 rect;
Rect2 bottom_rect;
@@ -114,14 +113,16 @@ void EditorProperty::_notification(int p_what) {
//compute room needed
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
- if (c == bottom_editor)
+ }
+ if (c == bottom_editor) {
continue;
+ }
Size2 minsize = c->get_combined_minimum_size();
child_room = MAX(child_room, minsize.width);
@@ -138,7 +139,6 @@ void EditorProperty::_notification(int p_what) {
}
if (bottom_editor) {
-
int m = 0; //get_constant("item_margin", "Tree");
bottom_rect = Rect2(m, rect.size.height + get_theme_constant("vseparation", "Tree"), size.width - m, bottom_editor->get_combined_minimum_size().height);
@@ -175,14 +175,16 @@ void EditorProperty::_notification(int p_what) {
//set children
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
- if (c == bottom_editor)
+ }
+ if (c == bottom_editor) {
continue;
+ }
fit_child_in_rect(c, rect);
right_child_rect = rect;
@@ -234,10 +236,11 @@ void EditorProperty::_notification(int p_what) {
if (checkable) {
Ref<Texture2D> checkbox;
- if (checked)
+ if (checked) {
checkbox = get_theme_icon("GuiChecked", "EditorIcons");
- else
+ } else {
checkbox = get_theme_icon("GuiUnchecked", "EditorIcons");
+ }
Color color2(1, 1, 1);
if (check_hover) {
@@ -335,8 +338,9 @@ StringName EditorProperty::get_edited_property() {
}
void EditorProperty::update_property() {
- if (get_script_instance())
+ if (get_script_instance()) {
get_script_instance()->call("update_property");
+ }
}
void EditorProperty::set_read_only(bool p_read_only) {
@@ -348,14 +352,12 @@ bool EditorProperty::is_read_only() const {
}
bool EditorPropertyRevert::may_node_be_in_instance(Node *p_node) {
-
Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
bool might_be = false;
Node *node = p_node;
while (node) {
-
if (node->get_scene_instance_state().is_valid()) {
might_be = true;
break;
@@ -375,7 +377,6 @@ bool EditorPropertyRevert::may_node_be_in_instance(Node *p_node) {
}
bool EditorPropertyRevert::get_instanced_node_original_property(Node *p_node, const StringName &p_prop, Variant &value) {
-
Node *node = p_node;
Node *orig = node;
@@ -384,7 +385,6 @@ bool EditorPropertyRevert::get_instanced_node_original_property(Node *p_node, co
bool found = false;
while (node) {
-
Ref<SceneState> ss;
if (node == edited_scene) {
@@ -395,7 +395,6 @@ bool EditorPropertyRevert::get_instanced_node_original_property(Node *p_node, co
}
if (ss.is_valid()) {
-
NodePath np = node->get_path_to(orig);
int node_idx = ss->find_node_by_path(np);
if (node_idx >= 0) {
@@ -403,7 +402,6 @@ bool EditorPropertyRevert::get_instanced_node_original_property(Node *p_node, co
Variant lvar;
lvar = ss->get_property_value(node_idx, p_prop, lfound);
if (lfound) {
-
found = true;
value = lvar;
}
@@ -429,21 +427,20 @@ bool EditorPropertyRevert::get_instanced_node_original_property(Node *p_node, co
}
bool EditorPropertyRevert::is_node_property_different(Node *p_node, const Variant &p_current, const Variant &p_orig) {
-
// this is a pretty difficult function, because a property may not be saved but may have
// the flag to not save if one or if zero
//make sure there is an actual state
{
Node *node = p_node;
- if (!node)
+ if (!node) {
return false;
+ }
Node *edited_scene = EditorNode::get_singleton()->get_edited_scene();
bool found_state = false;
while (node) {
-
Ref<SceneState> ss;
if (node == edited_scene) {
@@ -463,8 +460,9 @@ bool EditorPropertyRevert::is_node_property_different(Node *p_node, const Varian
node = node->get_owner();
}
- if (!found_state)
+ if (!found_state) {
return false; //pointless to check if we are not comparing against anything.
+ }
}
if (p_current.get_type() == Variant::FLOAT && p_orig.get_type() == Variant::FLOAT) {
@@ -478,7 +476,6 @@ bool EditorPropertyRevert::is_node_property_different(Node *p_node, const Varian
}
bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringName &p_property) {
-
bool has_revert = false;
Node *node = Object::cast_to<Node>(p_object);
@@ -501,18 +498,20 @@ bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringNam
}
}
- if (p_object->call("property_can_revert", p_property).operator bool()) {
-
- has_revert = true;
- }
-
- if (!has_revert && !p_object->get_script().is_null()) {
- Ref<Script> scr = p_object->get_script();
- if (scr.is_valid()) {
- Variant orig_value;
- if (scr->get_property_default_value(p_property, orig_value)) {
- if (orig_value != p_object->get(p_property)) {
- has_revert = true;
+ // If the object implements property_can_revert, rely on that completely
+ // (i.e. don't then try to revert to default value - the property_get_revert implementation
+ // can do that if so desired)
+ if (p_object->has_method("property_can_revert")) {
+ has_revert = p_object->call("property_can_revert", p_property).operator bool();
+ } else {
+ if (!has_revert && !p_object->get_script().is_null()) {
+ Ref<Script> scr = p_object->get_script();
+ if (scr.is_valid()) {
+ Variant orig_value;
+ if (scr->get_property_default_value(p_property, orig_value)) {
+ if (orig_value != p_object->get(p_property)) {
+ has_revert = true;
+ }
}
}
}
@@ -522,9 +521,9 @@ bool EditorPropertyRevert::can_property_revert(Object *p_object, const StringNam
}
void EditorProperty::update_reload_status() {
-
- if (property == StringName())
+ if (property == StringName()) {
return; //no property, so nothing to do
+ }
bool has_reload = EditorPropertyRevert::can_property_revert(object, property);
@@ -548,31 +547,27 @@ bool EditorProperty::use_keying_next() const {
return false;
}
-void EditorProperty::set_checkable(bool p_checkable) {
+void EditorProperty::set_checkable(bool p_checkable) {
checkable = p_checkable;
update();
queue_sort();
}
bool EditorProperty::is_checkable() const {
-
return checkable;
}
void EditorProperty::set_checked(bool p_checked) {
-
checked = p_checked;
update();
}
bool EditorProperty::is_checked() const {
-
return checked;
}
void EditorProperty::set_draw_red(bool p_draw_red) {
-
draw_red = p_draw_red;
update();
}
@@ -598,14 +593,13 @@ bool EditorProperty::is_keying() const {
}
bool EditorProperty::is_draw_red() const {
-
return draw_red;
}
void EditorProperty::_focusable_focused(int p_index) {
-
- if (!selectable)
+ if (!selectable) {
return;
+ }
bool already_selected = selected;
selected = true;
selected_focusable = p_index;
@@ -616,13 +610,11 @@ void EditorProperty::_focusable_focused(int p_index) {
}
void EditorProperty::add_focusable(Control *p_control) {
-
p_control->connect("focus_entered", callable_mp(this, &EditorProperty::_focusable_focused), varray(focusables.size()));
focusables.push_back(p_control);
}
void EditorProperty::select(int p_focusable) {
-
bool already_selected = selected;
if (p_focusable >= 0) {
@@ -649,14 +641,13 @@ bool EditorProperty::is_selected() const {
}
void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
-
- if (property == StringName())
+ if (property == StringName()) {
return;
+ }
Ref<InputEventMouse> me = p_event;
if (me.is_valid()) {
-
bool button_left = me->get_button_mask() & BUTTON_MASK_LEFT;
bool new_keying_hover = keying_rect.has_point(me->get_position()) && !button_left;
@@ -687,7 +678,6 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
if (!selected && selectable) {
selected = true;
emit_signal("selected", property, -1);
@@ -719,12 +709,10 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
}
if (revert_rect.has_point(mb->get_position())) {
-
Variant vorig;
Node *node = Object::cast_to<Node>(object);
if (node && EditorPropertyRevert::may_node_be_in_instance(node) && EditorPropertyRevert::get_instanced_node_original_property(node, property, vorig)) {
-
emit_changed(property, vorig.duplicate(true));
update_property();
return;
@@ -765,17 +753,17 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
}
void EditorProperty::set_label_reference(Control *p_control) {
-
label_reference = p_control;
}
-void EditorProperty::set_bottom_editor(Control *p_control) {
+void EditorProperty::set_bottom_editor(Control *p_control) {
bottom_editor = p_control;
}
-Variant EditorProperty::get_drag_data(const Point2 &p_point) {
- if (property == StringName())
+Variant EditorProperty::get_drag_data(const Point2 &p_point) {
+ if (property == StringName()) {
return Variant();
+ }
Dictionary dp;
dp["type"] = "obj_property";
@@ -790,12 +778,10 @@ Variant EditorProperty::get_drag_data(const Point2 &p_point) {
}
void EditorProperty::set_use_folding(bool p_use_folding) {
-
use_folding = p_use_folding;
}
bool EditorProperty::is_using_folding() const {
-
return use_folding;
}
@@ -818,7 +804,6 @@ void EditorProperty::set_name_split_ratio(float p_ratio) {
}
float EditorProperty::get_name_split_ratio() const {
-
return split_ratio;
}
@@ -828,7 +813,6 @@ void EditorProperty::set_object_and_property(Object *p_object, const StringName
}
Control *EditorProperty::make_custom_tooltip(const String &p_text) const {
-
tooltip_text = p_text;
EditorHelpBit *help_bit = memnew(EditorHelpBit);
//help_bit->add_theme_style_override("panel", get_theme_stylebox("panel", "TooltipPanel"));
@@ -857,7 +841,6 @@ String EditorProperty::get_tooltip_text() const {
}
void EditorProperty::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_label", "text"), &EditorProperty::set_label);
ClassDB::bind_method(D_METHOD("get_label"), &EditorProperty::get_label);
@@ -914,7 +897,6 @@ void EditorProperty::_bind_methods() {
}
EditorProperty::EditorProperty() {
-
draw_top_bg = true;
object = nullptr;
split_ratio = 0.5;
@@ -937,18 +919,17 @@ EditorProperty::EditorProperty() {
label_reference = nullptr;
bottom_editor = nullptr;
}
+
////////////////////////////////////////////////
////////////////////////////////////////////////
void EditorInspectorPlugin::add_custom_control(Control *control) {
-
AddedEditor ae;
ae.property_editor = control;
added_editors.push_back(ae);
}
void EditorInspectorPlugin::add_property_editor(const String &p_for_property, Control *p_prop) {
-
ERR_FAIL_COND(Object::cast_to<EditorProperty>(p_prop) == nullptr);
AddedEditor ae;
@@ -958,7 +939,6 @@ void EditorInspectorPlugin::add_property_editor(const String &p_for_property, Co
}
void EditorInspectorPlugin::add_property_editor_for_multiple_properties(const String &p_label, const Vector<String> &p_properties, Control *p_prop) {
-
AddedEditor ae;
ae.properties = p_properties;
ae.property_editor = p_prop;
@@ -967,28 +947,25 @@ void EditorInspectorPlugin::add_property_editor_for_multiple_properties(const St
}
bool EditorInspectorPlugin::can_handle(Object *p_object) {
-
if (get_script_instance()) {
return get_script_instance()->call("can_handle", p_object);
}
return false;
}
-void EditorInspectorPlugin::parse_begin(Object *p_object) {
+void EditorInspectorPlugin::parse_begin(Object *p_object) {
if (get_script_instance()) {
get_script_instance()->call("parse_begin", p_object);
}
}
void EditorInspectorPlugin::parse_category(Object *p_object, const String &p_parse_category) {
-
if (get_script_instance()) {
get_script_instance()->call("parse_category", p_object, p_parse_category);
}
}
bool EditorInspectorPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
-
if (get_script_instance()) {
Variant arg[6] = {
p_object, p_type, p_path, p_hint, p_hint_text, p_usage
@@ -1002,15 +979,14 @@ bool EditorInspectorPlugin::parse_property(Object *p_object, Variant::Type p_typ
}
return false;
}
-void EditorInspectorPlugin::parse_end() {
+void EditorInspectorPlugin::parse_end() {
if (get_script_instance()) {
get_script_instance()->call("parse_end");
}
}
void EditorInspectorPlugin::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_custom_control", "control"), &EditorInspectorPlugin::add_custom_control);
ClassDB::bind_method(D_METHOD("add_property_editor", "property", "editor"), &EditorInspectorPlugin::add_property_editor);
ClassDB::bind_method(D_METHOD("add_property_editor_for_multiple_properties", "label", "properties", "editor"), &EditorInspectorPlugin::add_property_editor_for_multiple_properties);
@@ -1045,9 +1021,7 @@ void EditorInspectorPlugin::_bind_methods() {
////////////////////////////////////////////////
void EditorInspectorCategory::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
-
draw_rect(Rect2(Vector2(), get_size()), bg_color);
Ref<Font> font = get_theme_font("font", "Tree");
@@ -1071,7 +1045,6 @@ void EditorInspectorCategory::_notification(int p_what) {
}
Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) const {
-
tooltip_text = p_text;
EditorHelpBit *help_bit = memnew(EditorHelpBit);
help_bit->add_theme_style_override("panel", get_theme_stylebox("panel", "TooltipPanel"));
@@ -1095,7 +1068,6 @@ Control *EditorInspectorCategory::make_custom_tooltip(const String &p_text) cons
}
Size2 EditorInspectorCategory::get_minimum_size() const {
-
Ref<Font> font = get_theme_font("font", "Tree");
Size2 ms;
@@ -1114,7 +1086,6 @@ void EditorInspectorCategory::_bind_methods() {
}
String EditorInspectorCategory::get_tooltip_text() const {
-
return tooltip_text;
}
@@ -1125,7 +1096,6 @@ EditorInspectorCategory::EditorInspectorCategory() {
////////////////////////////////////////////////
void EditorInspectorSection::_test_unfold() {
-
if (!vbox_added) {
add_child(vbox);
vbox_added = true;
@@ -1133,9 +1103,7 @@ void EditorInspectorSection::_test_unfold() {
}
void EditorInspectorSection::_notification(int p_what) {
-
if (p_what == NOTIFICATION_SORT_CHILDREN) {
-
Ref<Font> font = get_theme_font("font", "Tree");
Ref<Texture2D> arrow;
@@ -1161,14 +1129,16 @@ void EditorInspectorSection::_notification(int p_what) {
//set children
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
- if (!c->is_visible_in_tree())
+ }
+ if (!c->is_visible_in_tree()) {
continue;
+ }
fit_child_in_rect(c, rect);
}
@@ -1177,7 +1147,6 @@ void EditorInspectorSection::_notification(int p_what) {
}
if (p_what == NOTIFICATION_DRAW) {
-
Ref<Texture2D> arrow;
if (foldable) {
@@ -1209,17 +1178,18 @@ void EditorInspectorSection::_notification(int p_what) {
}
Size2 EditorInspectorSection::get_minimum_size() const {
-
Size2 ms;
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
- if (!c->is_visible())
+ }
+ if (!c->is_visible()) {
continue;
+ }
Size2 minsize = c->get_combined_minimum_size();
ms.width = MAX(ms.width, minsize.width);
ms.height = MAX(ms.height, minsize.height);
@@ -1233,7 +1203,6 @@ Size2 EditorInspectorSection::get_minimum_size() const {
}
void EditorInspectorSection::setup(const String &p_section, const String &p_label, Object *p_object, const Color &p_bg_color, bool p_foldable) {
-
section = p_section;
label = p_label;
object = p_object;
@@ -1256,13 +1225,12 @@ void EditorInspectorSection::setup(const String &p_section, const String &p_labe
}
void EditorInspectorSection::_gui_input(const Ref<InputEvent> &p_event) {
-
- if (!foldable)
+ if (!foldable) {
return;
+ }
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
Ref<Font> font = get_theme_font("font", "Tree");
if (mb->get_position().y > font->get_height()) { //clicked outside
return;
@@ -1285,9 +1253,9 @@ VBoxContainer *EditorInspectorSection::get_vbox() {
}
void EditorInspectorSection::unfold() {
-
- if (!foldable)
+ if (!foldable) {
return;
+ }
_test_unfold();
@@ -1297,11 +1265,13 @@ void EditorInspectorSection::unfold() {
}
void EditorInspectorSection::fold() {
- if (!foldable)
+ if (!foldable) {
return;
+ }
- if (!vbox_added)
+ if (!vbox_added) {
return; //kinda pointless
+ }
object->editor_set_section_unfold(section, false);
vbox->hide();
@@ -1309,7 +1279,6 @@ void EditorInspectorSection::fold() {
}
void EditorInspectorSection::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("setup", "section", "label", "object", "bg_color", "foldable"), &EditorInspectorSection::setup);
ClassDB::bind_method(D_METHOD("get_vbox"), &EditorInspectorSection::get_vbox);
ClassDB::bind_method(D_METHOD("unfold"), &EditorInspectorSection::unfold);
@@ -1325,7 +1294,6 @@ EditorInspectorSection::EditorInspectorSection() {
}
EditorInspectorSection::~EditorInspectorSection() {
-
if (!vbox_added) {
memdelete(vbox);
}
@@ -1338,9 +1306,7 @@ Ref<EditorInspectorPlugin> EditorInspector::inspector_plugins[MAX_PLUGINS];
int EditorInspector::inspector_plugin_count = 0;
EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
-
for (int i = inspector_plugin_count - 1; i >= 0; i--) {
-
inspector_plugins[i]->parse_property(p_object, p_type, p_path, p_hint, p_hint_text, p_usage, p_wide);
if (inspector_plugins[i]->added_editors.size()) {
for (int j = 1; j < inspector_plugins[i]->added_editors.size(); j++) { //only keep first one
@@ -1349,7 +1315,6 @@ EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, V
EditorProperty *prop = Object::cast_to<EditorProperty>(inspector_plugins[i]->added_editors[0].property_editor);
if (prop) {
-
inspector_plugins[i]->added_editors.clear();
return prop;
} else {
@@ -1362,18 +1327,17 @@ EditorProperty *EditorInspector::instantiate_property_editor(Object *p_object, V
}
void EditorInspector::add_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin) {
-
ERR_FAIL_COND(inspector_plugin_count == MAX_PLUGINS);
for (int i = 0; i < inspector_plugin_count; i++) {
- if (inspector_plugins[i] == p_plugin)
+ if (inspector_plugins[i] == p_plugin) {
return; //already exists
+ }
}
inspector_plugins[inspector_plugin_count++] = p_plugin;
}
void EditorInspector::remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin) {
-
ERR_FAIL_COND(inspector_plugin_count == MAX_PLUGINS);
int idx = -1;
@@ -1389,8 +1353,9 @@ void EditorInspector::remove_inspector_plugin(const Ref<EditorInspectorPlugin> &
inspector_plugins[i] = inspector_plugins[i + 1];
}
- if (idx == inspector_plugin_count - 1)
+ if (idx == inspector_plugin_count - 1) {
inspector_plugins[idx] = Ref<EditorInspectorPlugin>();
+ }
inspector_plugin_count--;
}
@@ -1407,19 +1372,15 @@ void EditorInspector::set_undo_redo(UndoRedo *p_undo_redo) {
}
String EditorInspector::get_selected_path() const {
-
return property_selected;
}
void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<EditorInspectorPlugin> ped) {
-
for (List<EditorInspectorPlugin::AddedEditor>::Element *F = ped->added_editors.front(); F; F = F->next()) {
-
EditorProperty *ep = Object::cast_to<EditorProperty>(F->get().property_editor);
current_vbox->add_child(F->get().property_editor);
if (ep) {
-
ep->object = object;
ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed));
ep->connect("property_keyed", callable_mp(this, &EditorInspector::_property_keyed));
@@ -1432,7 +1393,6 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
ep->connect("object_id_selected", callable_mp(this, &EditorInspector::_object_id_selected), varray(), CONNECT_DEFERRED);
if (F->get().properties.size()) {
-
if (F->get().properties.size() == 1) {
//since it's one, associate:
ep->property = F->get().properties[0];
@@ -1463,7 +1423,6 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit
}
bool EditorInspector::_is_property_disabled_by_feature_profile(const StringName &p_property) {
-
Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile();
if (profile.is_null()) {
return false;
@@ -1472,7 +1431,6 @@ bool EditorInspector::_is_property_disabled_by_feature_profile(const StringName
StringName class_name = object->get_class();
while (class_name != StringName()) {
-
if (profile->is_class_property_disabled(class_name, p_property)) {
return true;
}
@@ -1487,7 +1445,6 @@ bool EditorInspector::_is_property_disabled_by_feature_profile(const StringName
}
void EditorInspector::update_tree() {
-
//to update properly if all is refreshed
StringName current_selected = property_selected;
int current_focusable = -1;
@@ -1515,14 +1472,16 @@ void EditorInspector::update_tree() {
_clear();
- if (!object)
+ if (!object) {
return;
+ }
List<Ref<EditorInspectorPlugin>> valid_plugins;
for (int i = inspector_plugin_count - 1; i >= 0; i--) { //start by last, so lastly added can override newly added
- if (!inspector_plugins[i]->can_handle(object))
+ if (!inspector_plugins[i]->can_handle(object)) {
continue;
+ }
valid_plugins.push_back(inspector_plugins[i]);
}
@@ -1563,20 +1522,17 @@ void EditorInspector::update_tree() {
}
for (List<PropertyInfo>::Element *I = plist.front(); I; I = I->next()) {
-
PropertyInfo &p = I->get();
//make sure the property can be edited
if (p.usage & PROPERTY_USAGE_SUBGROUP) {
-
subgroup = p.name;
subgroup_base = p.hint_string;
continue;
} else if (p.usage & PROPERTY_USAGE_GROUP) {
-
group = p.name;
group_base = p.hint_string;
subgroup = "";
@@ -1585,29 +1541,31 @@ void EditorInspector::update_tree() {
continue;
} else if (p.usage & PROPERTY_USAGE_CATEGORY) {
-
group = "";
group_base = "";
subgroup = "";
subgroup_base = "";
- if (!show_categories)
+ if (!show_categories) {
continue;
+ }
List<PropertyInfo>::Element *N = I->next();
bool valid = true;
//if no properties in category, skip
while (N) {
- if (N->get().usage & PROPERTY_USAGE_EDITOR)
+ if (N->get().usage & PROPERTY_USAGE_EDITOR) {
break;
+ }
if (N->get().usage & PROPERTY_USAGE_CATEGORY) {
valid = false;
break;
}
N = N->next();
}
- if (!valid)
+ if (!valid) {
continue; //empty, ignore
+ }
EditorInspectorCategory *category = memnew(EditorInspectorCategory);
main_vbox->add_child(category);
@@ -1621,7 +1579,6 @@ void EditorInspector::update_tree() {
if (use_doc_hints) {
StringName type2 = p.name;
if (!class_descr_cache.has(type2)) {
-
String descr;
DocData *dd = EditorHelp::get_doc_data();
Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(type2);
@@ -1642,11 +1599,13 @@ void EditorInspector::update_tree() {
continue;
- } else if (!(p.usage & PROPERTY_USAGE_EDITOR) || _is_property_disabled_by_feature_profile(p.name))
+ } else if (!(p.usage & PROPERTY_USAGE_EDITOR) || _is_property_disabled_by_feature_profile(p.name)) {
continue;
+ }
- if (p.usage & PROPERTY_USAGE_HIGH_END_GFX && RS::get_singleton()->is_low_end())
+ if (p.usage & PROPERTY_USAGE_HIGH_END_GFX && RS::get_singleton()->is_low_end()) {
continue; //do not show this property in low end gfx
+ }
if (p.name == "script" && (hide_script || bool(object->call("_hide_script_from_inspector")))) {
continue;
@@ -1702,14 +1661,15 @@ void EditorInspector::update_tree() {
String path = basename.left(basename.find_last("/"));
if (use_filter && filter != "") {
-
String cat = path;
- if (capitalize_paths)
+ if (capitalize_paths) {
cat = cat.capitalize();
+ }
- if (!filter.is_subsequence_ofi(cat) && !filter.is_subsequence_ofi(name) && property_prefix.to_lower().find(filter.to_lower()) == -1)
+ if (!filter.is_subsequence_ofi(cat) && !filter.is_subsequence_ofi(name) && property_prefix.to_lower().find(filter.to_lower()) == -1) {
continue;
+ }
}
if (category_vbox == nullptr) {
@@ -1720,21 +1680,22 @@ void EditorInspector::update_tree() {
VBoxContainer *current_vbox = main_vbox;
{
-
String acc_path = "";
int level = 1;
for (int i = 0; i < path.get_slice_count("/"); i++) {
String path_name = path.get_slice("/", i);
- if (i > 0)
+ if (i > 0) {
acc_path += "/";
+ }
acc_path += path_name;
if (!item_path.has(acc_path)) {
EditorInspectorSection *section = memnew(EditorInspectorSection);
current_vbox->add_child(section);
sections.push_back(section);
- if (capitalize_paths)
+ if (capitalize_paths) {
path_name = path_name.capitalize();
+ }
Color c = sscolor;
c.a /= level;
@@ -1771,7 +1732,6 @@ void EditorInspector::update_tree() {
String doc_hint;
if (use_doc_hints) {
-
StringName classname = object->get_class_name();
if (object_class != String()) {
classname = object_class;
@@ -1831,7 +1791,6 @@ void EditorInspector::update_tree() {
ped->added_editors.clear();
for (List<EditorInspectorPlugin::AddedEditor>::Element *F = editors.front(); F; F = F->next()) {
-
EditorProperty *ep = Object::cast_to<EditorProperty>(F->get().property_editor);
if (ep) {
@@ -1839,7 +1798,6 @@ void EditorInspector::update_tree() {
ep->object = object;
if (F->get().properties.size()) {
-
if (F->get().properties.size() == 1) {
//since it's one, associate:
ep->property = F->get().properties[0];
@@ -1875,7 +1833,6 @@ void EditorInspector::update_tree() {
current_vbox->add_child(F->get().property_editor);
if (ep) {
-
ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed));
if (p.usage & PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED) {
ep->connect("property_changed", callable_mp(this, &EditorInspector::_property_changed_update_all), varray(), CONNECT_DEFERRED);
@@ -1916,9 +1873,11 @@ void EditorInspector::update_tree() {
//see if this property exists and should be kept
}
+
void EditorInspector::update_property(const String &p_prop) {
- if (!editor_property_map.has(p_prop))
+ if (!editor_property_map.has(p_prop)) {
return;
+ }
for (List<EditorProperty *>::Element *E = editor_property_map[p_prop].front(); E; E = E->next()) {
E->get()->update_property();
@@ -1927,7 +1886,6 @@ void EditorInspector::update_property(const String &p_prop) {
}
void EditorInspector::_clear() {
-
while (main_vbox->get_child_count()) {
memdelete(main_vbox->get_child(0));
}
@@ -1940,9 +1898,9 @@ void EditorInspector::_clear() {
}
void EditorInspector::refresh() {
-
- if (refresh_countdown > 0 || changing)
+ if (refresh_countdown > 0 || changing) {
return;
+ }
refresh_countdown = EditorSettings::get_singleton()->get("docks/property_editor/auto_refresh_interval");
}
@@ -1951,10 +1909,10 @@ Object *EditorInspector::get_edited_object() {
}
void EditorInspector::edit(Object *p_object) {
- if (object == p_object)
+ if (object == p_object) {
return;
+ }
if (object) {
-
_clear();
object->remove_change_receptor(this);
}
@@ -1972,20 +1930,22 @@ void EditorInspector::edit(Object *p_object) {
}
void EditorInspector::set_keying(bool p_active) {
- if (keying == p_active)
+ if (keying == p_active) {
return;
+ }
keying = p_active;
update_tree();
}
+
void EditorInspector::set_read_only(bool p_read_only) {
read_only = p_read_only;
update_tree();
}
bool EditorInspector::is_capitalize_paths_enabled() const {
-
return capitalize_paths;
}
+
void EditorInspector::set_enable_capitalize_paths(bool p_capitalize) {
capitalize_paths = p_capitalize;
update_tree();
@@ -2004,22 +1964,25 @@ void EditorInspector::set_use_doc_hints(bool p_enable) {
use_doc_hints = p_enable;
update_tree();
}
+
void EditorInspector::set_hide_script(bool p_hide) {
hide_script = p_hide;
update_tree();
}
+
void EditorInspector::set_use_filter(bool p_use) {
use_filter = p_use;
update_tree();
}
+
void EditorInspector::register_text_enter(Node *p_line_edit) {
search_box = Object::cast_to<LineEdit>(p_line_edit);
- if (search_box)
+ if (search_box) {
search_box->connect("text_changed", callable_mp(this, &EditorInspector::_filter_changed));
+ }
}
void EditorInspector::_filter_changed(const String &p_text) {
-
_clear();
update_tree();
}
@@ -2034,7 +1997,6 @@ bool EditorInspector::is_using_folding() {
}
void EditorInspector::collapse_all_folding() {
-
for (List<EditorInspectorSection *>::Element *E = sections.front(); E; E = E->next()) {
E->get()->fold();
}
@@ -2070,10 +2032,10 @@ void EditorInspector::set_use_wide_editors(bool p_enable) {
}
void EditorInspector::set_sub_inspector(bool p_enable) {
-
sub_inspector = p_enable;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
if (sub_inspector) {
add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor"));
@@ -2087,22 +2049,22 @@ void EditorInspector::set_use_deletable_properties(bool p_enabled) {
}
void EditorInspector::_edit_request_change(Object *p_object, const String &p_property) {
-
- if (object != p_object) //may be undoing/redoing for a non edited object, so ignore
+ if (object != p_object) { //may be undoing/redoing for a non edited object, so ignore
return;
+ }
- if (changing)
+ if (changing) {
return;
+ }
- if (p_property == String())
+ if (p_property == String()) {
update_tree_pending = true;
- else {
+ } else {
pending.insert(p_property);
}
}
void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bool p_refresh_all, const String &p_changed_field) {
-
if (autoclear && editor_property_map.has(p_name)) {
for (List<EditorProperty *>::Element *E = editor_property_map[p_name].front(); E; E = E->next()) {
if (E->get()->is_checkable()) {
@@ -2112,22 +2074,20 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
}
if (!undo_redo || bool(object->call("_dont_undo_redo"))) {
-
object->set(p_name, p_value);
- if (p_refresh_all)
+ if (p_refresh_all) {
_edit_request_change(object, "");
- else
+ } else {
_edit_request_change(object, p_name);
+ }
emit_signal(_prop_edited, p_name);
} else if (Object::cast_to<MultiNodeEdit>(object)) {
-
Object::cast_to<MultiNodeEdit>(object)->set_property_field(p_name, p_value, p_changed_field);
_edit_request_change(object, p_name);
emit_signal(_prop_edited, p_name);
} else {
-
undo_redo->create_action(TTR("Set") + " " + p_name, UndoRedo::MERGE_ENDS);
undo_redo->add_do_property(object, p_name, p_value);
undo_redo->add_undo_property(object, p_name, object->get(p_name));
@@ -2136,14 +2096,12 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
undo_redo->add_do_method(this, "_edit_request_change", object, "");
undo_redo->add_undo_method(this, "_edit_request_change", object, "");
} else {
-
undo_redo->add_do_method(this, "_edit_request_change", object, p_name);
undo_redo->add_undo_method(this, "_edit_request_change", object, p_name);
}
Resource *r = Object::cast_to<Resource>(object);
if (r) {
-
if (String(p_name) == "resource_local_to_scene") {
bool prev = object->get(p_name);
bool next = p_value;
@@ -2168,16 +2126,17 @@ void EditorInspector::_edit_set(const String &p_name, const Variant &p_value, bo
}
void EditorInspector::_property_changed(const String &p_path, const Variant &p_value, const String &p_name, bool p_changing) {
-
// The "changing" variable must be true for properties that trigger events as typing occurs,
// like "text_changed" signal. E.g. text property of Label, Button, RichTextLabel, etc.
- if (p_changing)
+ if (p_changing) {
this->changing++;
+ }
_edit_set(p_path, p_value, false, p_name);
- if (p_changing)
+ if (p_changing) {
this->changing--;
+ }
if (restart_request_props.has(p_path)) {
emit_signal("restart_requested");
@@ -2189,13 +2148,13 @@ void EditorInspector::_property_changed_update_all(const String &p_path, const V
}
void EditorInspector::_multiple_properties_changed(Vector<String> p_paths, Array p_values) {
-
ERR_FAIL_COND(p_paths.size() == 0 || p_values.size() == 0);
ERR_FAIL_COND(p_paths.size() != p_values.size());
String names;
for (int i = 0; i < p_paths.size(); i++) {
- if (i > 0)
+ if (i > 0) {
names += ",";
+ }
names += p_paths[i];
}
undo_redo->create_action(TTR("Set Multiple:") + " " + names, UndoRedo::MERGE_ENDS);
@@ -2211,42 +2170,40 @@ void EditorInspector::_multiple_properties_changed(Vector<String> p_paths, Array
}
void EditorInspector::_property_keyed(const String &p_path, bool p_advance) {
-
- if (!object)
+ if (!object) {
return;
+ }
emit_signal("property_keyed", p_path, object->get(p_path), p_advance); //second param is deprecated
}
void EditorInspector::_property_deleted(const String &p_path) {
-
print_line("deleted pressed?");
- if (!object)
+ if (!object) {
return;
+ }
emit_signal("property_deleted", p_path); //second param is deprecated
}
void EditorInspector::_property_keyed_with_value(const String &p_path, const Variant &p_value, bool p_advance) {
-
- if (!object)
+ if (!object) {
return;
+ }
emit_signal("property_keyed", p_path, p_value, p_advance); //second param is deprecated
}
void EditorInspector::_property_checked(const String &p_path, bool p_checked) {
-
- if (!object)
+ if (!object) {
return;
+ }
//property checked
if (autoclear) {
-
if (!p_checked) {
object->set(p_path, Variant());
} else {
-
Variant to_create;
List<PropertyInfo> pinfo;
object->get_property_list(&pinfo);
@@ -2273,16 +2230,17 @@ void EditorInspector::_property_checked(const String &p_path, bool p_checked) {
}
void EditorInspector::_property_selected(const String &p_path, int p_focusable) {
-
property_selected = p_path;
property_focusable = p_focusable;
//deselect the others
for (Map<StringName, List<EditorProperty *>>::Element *F = editor_property_map.front(); F; F = F->next()) {
- if (F->key() == property_selected)
+ if (F->key() == property_selected) {
continue;
+ }
for (List<EditorProperty *>::Element *E = F->get().front(); E; E = E->next()) {
- if (E->get()->is_selected())
+ if (E->get()->is_selected()) {
E->get()->deselect();
+ }
}
}
@@ -2290,7 +2248,6 @@ void EditorInspector::_property_selected(const String &p_path, int p_focusable)
}
void EditorInspector::_object_id_selected(const String &p_path, ObjectID p_id) {
-
emit_signal("object_id_selected", p_id);
}
@@ -2299,20 +2256,17 @@ void EditorInspector::_resource_selected(const String &p_path, RES p_resource) {
}
void EditorInspector::_node_removed(Node *p_node) {
-
if (p_node == object) {
edit(nullptr);
}
}
void EditorInspector::_notification(int p_what) {
-
if (p_what == NOTIFICATION_READY) {
EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &EditorInspector::_feature_profile_changed));
}
if (p_what == NOTIFICATION_ENTER_TREE) {
-
if (sub_inspector) {
add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor"));
} else {
@@ -2324,7 +2278,6 @@ void EditorInspector::_notification(int p_what) {
edit(nullptr); //just in case
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
if (!sub_inspector) {
get_tree()->disconnect("node_removed", callable_mp(this, &EditorInspector::_node_removed));
}
@@ -2332,7 +2285,6 @@ void EditorInspector::_notification(int p_what) {
}
if (p_what == NOTIFICATION_PROCESS) {
-
if (update_scroll_request >= 0) {
get_v_scrollbar()->call_deferred("set_value", update_scroll_request);
update_scroll_request = -1;
@@ -2352,13 +2304,11 @@ void EditorInspector::_notification(int p_what) {
changing++;
if (update_tree_pending) {
-
update_tree();
update_tree_pending = false;
pending.clear();
} else {
-
while (pending.size()) {
StringName prop = pending.front()->get();
if (editor_property_map.has(prop)) {
@@ -2375,7 +2325,6 @@ void EditorInspector::_notification(int p_what) {
}
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
-
if (sub_inspector) {
add_theme_style_override("bg", get_theme_stylebox("sub_inspector_bg", "Editor"));
} else if (is_inside_tree()) {
@@ -2392,9 +2341,9 @@ void EditorInspector::_changed_callback(Object *p_changed, const char *p_prop) {
}
void EditorInspector::_vscroll_changed(double p_offset) {
-
- if (update_scroll_request >= 0) //waiting, do nothing
+ if (update_scroll_request >= 0) { //waiting, do nothing
return;
+ }
if (object) {
scroll_cache[object->get_instance_id()] = p_offset;
@@ -2418,12 +2367,10 @@ String EditorInspector::get_object_class() const {
}
void EditorInspector::_feature_profile_changed() {
-
update_tree();
}
void EditorInspector::_bind_methods() {
-
ClassDB::bind_method("_edit_request_change", &EditorInspector::_edit_request_change);
ClassDB::bind_method("refresh", &EditorInspector::refresh);
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index c8c1ecc49a..90d995e36d 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -47,7 +47,6 @@ public:
};
class EditorProperty : public Container {
-
GDCLASS(EditorProperty, Container);
private:
diff --git a/editor/editor_layouts_dialog.cpp b/editor/editor_layouts_dialog.cpp
index dbd043c494..14478b1386 100644
--- a/editor/editor_layouts_dialog.cpp
+++ b/editor/editor_layouts_dialog.cpp
@@ -41,21 +41,20 @@ void EditorLayoutsDialog::_line_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
-
- if (!k->is_pressed())
+ if (!k->is_pressed()) {
return;
+ }
switch (k->get_keycode()) {
case KEY_KP_ENTER:
case KEY_ENTER: {
-
- if (get_hide_on_ok())
+ if (get_hide_on_ok()) {
hide();
+ }
ok_pressed();
set_input_as_handled();
} break;
case KEY_ESCAPE: {
-
hide();
set_input_as_handled();
} break;
@@ -64,27 +63,21 @@ void EditorLayoutsDialog::_line_gui_input(const Ref<InputEvent> &p_event) {
}
void EditorLayoutsDialog::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("name_confirmed", PropertyInfo(Variant::STRING, "name")));
}
void EditorLayoutsDialog::ok_pressed() {
-
if (layout_names->is_anything_selected()) {
-
Vector<int> const selected_items = layout_names->get_selected_items();
for (int i = 0; i < selected_items.size(); ++i) {
-
emit_signal("name_confirmed", layout_names->get_item_text(selected_items[i]));
}
} else if (name->is_visible() && name->get_text() != "") {
-
emit_signal("name_confirmed", name->get_text());
}
}
void EditorLayoutsDialog::_post_popup() {
-
ConfirmationDialog::_post_popup();
name->clear();
layout_names->clear();
@@ -93,7 +86,6 @@ void EditorLayoutsDialog::_post_popup() {
config.instance();
Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config());
if (err != OK) {
-
return;
}
@@ -101,13 +93,11 @@ void EditorLayoutsDialog::_post_popup() {
config.ptr()->get_sections(&layouts);
for (List<String>::Element *E = layouts.front(); E; E = E->next()) {
-
layout_names->add_item(**E);
}
}
EditorLayoutsDialog::EditorLayoutsDialog() {
-
makevb = memnew(VBoxContainer);
add_child(makevb);
makevb->set_anchor_and_margin(MARGIN_LEFT, Control::ANCHOR_BEGIN, 5);
@@ -133,6 +123,5 @@ EditorLayoutsDialog::EditorLayoutsDialog() {
}
void EditorLayoutsDialog::set_name_line_enabled(bool p_enabled) {
-
name->set_visible(p_enabled);
}
diff --git a/editor/editor_layouts_dialog.h b/editor/editor_layouts_dialog.h
index d18c2bce17..39f0f4163d 100644
--- a/editor/editor_layouts_dialog.h
+++ b/editor/editor_layouts_dialog.h
@@ -37,7 +37,6 @@ class LineEdit;
class ItemList;
class EditorLayoutsDialog : public ConfirmationDialog {
-
GDCLASS(EditorLayoutsDialog, ConfirmationDialog);
LineEdit *name;
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index c89a7bcf23..ea5f73acd1 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -38,10 +38,10 @@
#include "scene/resources/dynamic_font.h"
void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type) {
-
EditorLog *self = (EditorLog *)p_self;
- if (self->current != Thread::get_caller_id())
+ if (self->current != Thread::get_caller_id()) {
return;
+ }
String err_str;
if (p_errorexp && p_errorexp[0]) {
@@ -58,29 +58,27 @@ void EditorLog::_error_handler(void *p_self, const char *p_func, const char *p_f
}
void EditorLog::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
//button->set_icon(get_icon("Console","EditorIcons"));
log->add_theme_font_override("normal_font", get_theme_font("output_source", "EditorFonts"));
+ log->add_theme_color_override("selection_color", get_theme_color("accent_color", "Editor") * Color(1, 1, 1, 0.4));
} else if (p_what == NOTIFICATION_THEME_CHANGED) {
Ref<DynamicFont> df_output_code = get_theme_font("output_source", "EditorFonts");
if (df_output_code.is_valid()) {
if (log != nullptr) {
log->add_theme_font_override("normal_font", get_theme_font("output_source", "EditorFonts"));
+ log->add_theme_color_override("selection_color", get_theme_color("accent_color", "Editor") * Color(1, 1, 1, 0.4));
}
}
}
}
void EditorLog::_clear_request() {
-
log->clear();
tool_button->set_icon(Ref<Texture2D>());
}
void EditorLog::_copy_request() {
-
log->selection_copy();
}
@@ -93,7 +91,6 @@ void EditorLog::copy() {
}
void EditorLog::add_message(const String &p_msg, MessageType p_type) {
-
log->add_newline();
bool restore = p_type != MSG_TYPE_STD;
@@ -122,8 +119,9 @@ void EditorLog::add_message(const String &p_msg, MessageType p_type) {
log->add_text(p_msg);
- if (restore)
+ if (restore) {
log->pop();
+ }
}
void EditorLog::set_tool_button(ToolButton *p_tool_button) {
@@ -131,19 +129,16 @@ void EditorLog::set_tool_button(ToolButton *p_tool_button) {
}
void EditorLog::_undo_redo_cbk(void *p_self, const String &p_name) {
-
EditorLog *self = (EditorLog *)p_self;
self->add_message(p_name, EditorLog::MSG_TYPE_EDITOR);
}
void EditorLog::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("clear_request"));
ADD_SIGNAL(MethodInfo("copy_request"));
}
EditorLog::EditorLog() {
-
VBoxContainer *vb = this;
HBoxContainer *hb = memnew(HBoxContainer);
@@ -187,7 +182,6 @@ EditorLog::EditorLog() {
}
void EditorLog::deinit() {
-
remove_error_handler(&eh);
}
diff --git a/editor/editor_log.h b/editor/editor_log.h
index e3980690b2..1c9a2d4062 100644
--- a/editor/editor_log.h
+++ b/editor/editor_log.h
@@ -44,7 +44,6 @@
#include "scene/gui/tool_button.h"
class EditorLog : public VBoxContainer {
-
GDCLASS(EditorLog, VBoxContainer);
Button *clearbutton;
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 849908c132..8b7014fabe 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -32,7 +32,7 @@
#include "core/bind/core_bind.h"
#include "core/class_db.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/config_file.h"
#include "core/io/image_loader.h"
#include "core/io/resource_loader.h"
@@ -42,7 +42,6 @@
#include "core/os/file_access.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
-#include "core/path_remap.h"
#include "core/print_string.h"
#include "core/project_settings.h"
#include "core/translation.h"
@@ -98,6 +97,7 @@
#include "editor/import/resource_importer_layered_texture.h"
#include "editor/import/resource_importer_obj.h"
#include "editor/import/resource_importer_scene.h"
+#include "editor/import/resource_importer_shader_file.h"
#include "editor/import/resource_importer_texture.h"
#include "editor/import/resource_importer_texture_atlas.h"
#include "editor/import/resource_importer_wav.h"
@@ -148,6 +148,7 @@
#include "editor/plugins/script_editor_plugin.h"
#include "editor/plugins/script_text_editor.h"
#include "editor/plugins/shader_editor_plugin.h"
+#include "editor/plugins/shader_file_editor_plugin.h"
#include "editor/plugins/skeleton_2d_editor_plugin.h"
#include "editor/plugins/skeleton_3d_editor_plugin.h"
#include "editor/plugins/skeleton_ik_3d_editor_plugin.h"
@@ -156,6 +157,7 @@
#include "editor/plugins/style_box_editor_plugin.h"
#include "editor/plugins/text_editor.h"
#include "editor/plugins/texture_editor_plugin.h"
+#include "editor/plugins/texture_layered_editor_plugin.h"
#include "editor/plugins/texture_region_editor_plugin.h"
#include "editor/plugins/theme_editor_plugin.h"
#include "editor/plugins/tile_map_editor_plugin.h"
@@ -178,7 +180,6 @@
EditorNode *EditorNode::singleton = nullptr;
void EditorNode::_update_scene_tabs() {
-
bool show_rb = EditorSettings::get_singleton()->get("interface/scene_tabs/show_script_button");
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
@@ -188,7 +189,6 @@ void EditorNode::_update_scene_tabs() {
scene_tabs->clear_tabs();
Ref<Texture2D> script_icon = gui_base->get_theme_icon("Script", "EditorIcons");
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
-
Node *type_node = editor_data.get_edited_scene_root(i);
Ref<Texture2D> icon;
if (type_node) {
@@ -230,44 +230,41 @@ void EditorNode::_update_scene_tabs() {
scene_tabs->add_child(scene_tab_add);
}
Rect2 last_tab = Rect2();
- if (scene_tabs->get_tab_count() != 0)
+ if (scene_tabs->get_tab_count() != 0) {
last_tab = scene_tabs->get_tab_rect(scene_tabs->get_tab_count() - 1);
+ }
scene_tab_add->set_position(Point2(last_tab.get_position().x + last_tab.get_size().x + 3, last_tab.get_position().y));
}
}
void EditorNode::_version_control_menu_option(int p_idx) {
-
switch (vcs_actions_menu->get_item_id(p_idx)) {
case RUN_VCS_SETTINGS: {
-
VersionControlEditorPlugin::get_singleton()->popup_vcs_set_up_dialog(gui_base);
} break;
case RUN_VCS_SHUT_DOWN: {
-
VersionControlEditorPlugin::get_singleton()->shut_down();
} break;
}
}
void EditorNode::_update_title() {
-
String appname = ProjectSettings::get_singleton()->get("application/config/name");
String title = appname.empty() ? String(VERSION_FULL_NAME) : String(VERSION_NAME + String(" - ") + appname);
String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_filename() : String();
- if (!edited.empty())
+ if (!edited.empty()) {
title += " - " + String(edited.get_file());
- if (unsaved_cache)
+ }
+ if (unsaved_cache) {
title += " (*)";
+ }
DisplayServer::get_singleton()->window_set_title(title);
}
void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed() && !k->is_echo()) {
-
EditorPlugin *old_editor = editor_plugin_screen;
if (ED_IS_SHORTCUT("editor/next_tab", p_event)) {
@@ -307,14 +304,13 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
}
void EditorNode::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_PROCESS: {
- if (opening_prev && !confirmation->is_visible())
+ if (opening_prev && !confirmation->is_visible()) {
opening_prev = false;
+ }
if (unsaved_cache != (saved_version != editor_data.get_undo_redo().get_version())) {
-
unsaved_cache = (saved_version != editor_data.get_undo_redo().get_version());
_update_title();
}
@@ -329,10 +325,10 @@ void EditorNode::_notification(int p_what) {
uint32_t tick = OS::get_singleton()->get_ticks_msec();
if (frame != update_spinner_step_frame && (tick - update_spinner_step_msec) > (1000 / 8)) {
-
update_spinner_step++;
- if (update_spinner_step >= 8)
+ if (update_spinner_step >= 8) {
update_spinner_step = 0;
+ }
update_spinner_step_msec = tick;
update_spinner_step_frame = frame + 1;
@@ -379,6 +375,8 @@ void EditorNode::_notification(int p_what) {
RS::get_singleton()->shadows_quality_set(shadows_quality);
RS::ShadowQuality directional_shadow_quality = RS::ShadowQuality(int(GLOBAL_GET("rendering/quality/directional_shadow/soft_shadow_quality")));
RS::get_singleton()->directional_shadow_quality_set(directional_shadow_quality);
+ float probe_update_speed = GLOBAL_GET("rendering/lightmapper/probe_capture_update_speed");
+ RS::get_singleton()->lightmap_set_probe_capture_update_speed(probe_update_speed);
}
ResourceImporterTexture::get_singleton()->update_imports();
@@ -404,7 +402,6 @@ void EditorNode::_notification(int p_what) {
} break;
case NOTIFICATION_READY: {
-
{
_initializing_addons = true;
Vector<String> addons;
@@ -434,7 +431,6 @@ void EditorNode::_notification(int p_what) {
} break;
case NOTIFICATION_WM_FOCUS_IN: {
-
// Restore the original FPS cap after focusing back on the editor
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec")));
@@ -442,18 +438,15 @@ void EditorNode::_notification(int p_what) {
} break;
case NOTIFICATION_WM_FOCUS_OUT: {
-
// Set a low FPS cap to decrease CPU/GPU usage while the editor is unfocused
OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec")));
} break;
case NOTIFICATION_WM_ABOUT: {
-
show_about();
} break;
case NOTIFICATION_WM_CLOSE_REQUEST: {
-
_menu_option_confirm(FILE_QUIT, false);
} break;
@@ -486,12 +479,12 @@ void EditorNode::_notification(int p_what) {
recent_scenes->set_as_minsize();
// debugger area
- if (EditorDebuggerNode::get_singleton()->is_visible())
+ if (EditorDebuggerNode::get_singleton()->is_visible()) {
bottom_panel->add_theme_style_override("panel", gui_base->get_theme_stylebox("BottomPanelDebuggerOverride", "EditorStyles"));
+ }
// update_icons
for (int i = 0; i < singleton->main_editor_buttons.size(); i++) {
-
ToolButton *tb = singleton->main_editor_buttons[i];
EditorPlugin *p_editor = singleton->editor_table[i];
Ref<Texture2D> icon = p_editor->get_icon();
@@ -553,8 +546,9 @@ void EditorNode::_update_update_spinner() {
void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_name) {
Ref<Script> script = Object::cast_to<Script>(p_script);
- if (script.is_null())
+ if (script.is_null()) {
return;
+ }
if (p_activate_name.length()) {
set_addon_plugin_enabled(p_activate_name, true);
}
@@ -564,23 +558,24 @@ void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_nam
}
void EditorNode::_resources_changed(const Vector<String> &p_resources) {
-
List<Ref<Resource>> changed;
int rc = p_resources.size();
for (int i = 0; i < rc; i++) {
-
Ref<Resource> res(ResourceCache::get(p_resources.get(i)));
if (res.is_null()) {
continue;
}
- if (!res->editor_can_reload_from_file())
+ if (!res->editor_can_reload_from_file()) {
continue;
- if (!res->get_path().is_resource_file() && !res->get_path().is_abs_path())
+ }
+ if (!res->get_path().is_resource_file() && !res->get_path().is_abs_path()) {
continue;
- if (!FileAccess::exists(res->get_path()))
+ }
+ if (!FileAccess::exists(res->get_path())) {
continue;
+ }
if (res->get_import_path() != String()) {
//this is an imported resource, will be reloaded if reimported via the _resources_reimported() callback
@@ -598,14 +593,11 @@ void EditorNode::_resources_changed(const Vector<String> &p_resources) {
}
void EditorNode::_fs_changed() {
-
for (Set<FileDialog *>::Element *E = file_dialogs.front(); E; E = E->next()) {
-
E->get()->invalidate();
}
for (Set<EditorFileDialog *>::Element *E = editor_file_dialogs.front(); E; E = E->next()) {
-
E->get()->invalidate();
}
@@ -675,7 +667,6 @@ void EditorNode::_fs_changed() {
}
void EditorNode::_resources_reimported(const Vector<String> &p_resources) {
-
List<String> scenes; //will load later
int current_tab = scene_tabs->get_current_tab();
@@ -705,13 +696,11 @@ void EditorNode::_resources_reimported(const Vector<String> &p_resources) {
}
void EditorNode::_sources_changed(bool p_exist) {
-
if (waiting_for_first_scan) {
waiting_for_first_scan = false;
// Reload the global shader variables, but this time
// loading texures, as they are now properly imported.
- print_line("done scanning, reload textures");
RenderingServer::get_singleton()->global_variables_load_settings(true);
// Start preview thread now that it's safe.
@@ -732,13 +721,12 @@ void EditorNode::_vp_resized() {
}
void EditorNode::_node_renamed() {
-
- if (get_inspector())
+ if (get_inspector()) {
get_inspector()->update_tree();
+ }
}
void EditorNode::_editor_select_next() {
-
int editor = _get_current_main_editor();
do {
@@ -753,7 +741,6 @@ void EditorNode::_editor_select_next() {
}
void EditorNode::_editor_select_prev() {
-
int editor = _get_current_main_editor();
do {
@@ -768,7 +755,6 @@ void EditorNode::_editor_select_prev() {
}
Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_deps) {
-
dependency_errors.clear();
Error err;
@@ -776,11 +762,9 @@ Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_d
ERR_FAIL_COND_V(!res.is_valid(), ERR_CANT_OPEN);
if (!p_ignore_broken_deps && dependency_errors.has(p_resource)) {
-
//current_option = -1;
Vector<String> errors;
for (Set<String>::Element *E = dependency_errors[p_resource].front(); E; E = E->next()) {
-
errors.push_back(E->get());
}
dependency_error->show(DependencyErrorDialog::MODE_RESOURCE, p_resource, errors);
@@ -794,16 +778,15 @@ Error EditorNode::load_resource(const String &p_resource, bool p_ignore_broken_d
}
void EditorNode::edit_node(Node *p_node) {
-
push_item(p_node);
}
void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const String &p_path) {
-
editor_data.apply_changes_in_editors();
int flg = 0;
- if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources"))
+ if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) {
flg |= ResourceSaver::FLAG_COMPRESS;
+ }
String path = ProjectSettings::get_singleton()->localize_path(p_path);
Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS);
@@ -823,7 +806,6 @@ void EditorNode::save_resource_in_path(const Ref<Resource> &p_resource, const St
}
void EditorNode::save_resource(const Ref<Resource> &p_resource) {
-
if (p_resource->get_path().is_resource_file()) {
save_resource_in_path(p_resource, p_resource->get_path());
} else {
@@ -832,7 +814,6 @@ void EditorNode::save_resource(const Ref<Resource> &p_resource) {
}
void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String &p_at_path) {
-
{
String path = p_resource->get_path();
int srpos = path.find("::");
@@ -856,7 +837,6 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String
List<String> preferred;
for (int i = 0; i < extensions.size(); i++) {
-
if (p_resource->is_class("Script") && (extensions[i] == "tres" || extensions[i] == "res" || extensions[i] == "xml")) {
//this serves no purpose and confused people
continue;
@@ -866,7 +846,6 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String
}
if (p_at_path != String()) {
-
file->set_current_dir(p_at_path);
if (p_resource->get_path().is_resource_file()) {
file->set_current_file(p_resource->get_path().get_file());
@@ -878,7 +857,6 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String
}
}
} else if (p_resource->get_path() != "") {
-
file->set_current_path(p_resource->get_path());
if (extensions.size()) {
String ext = p_resource->get_path().get_extension().to_lower();
@@ -887,7 +865,6 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String
}
}
} else if (preferred.size()) {
-
String existing;
if (extensions.size()) {
existing = "new_" + p_resource->get_class().to_lower() + "." + preferred.front()->get().to_lower();
@@ -899,31 +876,23 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String
}
void EditorNode::_menu_option(int p_option) {
-
_menu_option_confirm(p_option, false);
}
void EditorNode::_menu_confirm_current() {
-
_menu_option_confirm(current_option, true);
}
void EditorNode::_dialog_display_save_error(String p_file, Error p_error) {
-
if (p_error) {
-
switch (p_error) {
-
case ERR_FILE_CANT_WRITE: {
-
show_accept(TTR("Can't open file for writing:") + " " + p_file.get_extension(), TTR("OK"));
} break;
case ERR_FILE_UNRECOGNIZED: {
-
show_accept(TTR("Requested file format unknown:") + " " + p_file.get_extension(), TTR("OK"));
} break;
default: {
-
show_accept(TTR("Error while saving."), TTR("OK"));
} break;
}
@@ -931,29 +900,21 @@ void EditorNode::_dialog_display_save_error(String p_file, Error p_error) {
}
void EditorNode::_dialog_display_load_error(String p_file, Error p_error) {
-
if (p_error) {
-
switch (p_error) {
-
case ERR_CANT_OPEN: {
-
show_accept(vformat(TTR("Can't open '%s'. The file could have been moved or deleted."), p_file.get_file()), TTR("OK"));
} break;
case ERR_PARSE_ERROR: {
-
show_accept(vformat(TTR("Error while parsing '%s'."), p_file.get_file()), TTR("OK"));
} break;
case ERR_FILE_CORRUPT: {
-
show_accept(vformat(TTR("Unexpected end of file '%s'."), p_file.get_file()), TTR("OK"));
} break;
case ERR_FILE_NOT_FOUND: {
-
show_accept(vformat(TTR("Missing '%s' or its dependencies."), p_file.get_file()), TTR("OK"));
} break;
default: {
-
show_accept(vformat(TTR("Error while loading '%s'."), p_file.get_file()), TTR("OK"));
} break;
}
@@ -961,11 +922,11 @@ void EditorNode::_dialog_display_load_error(String p_file, Error p_error) {
}
void EditorNode::_get_scene_metadata(const String &p_file) {
-
Node *scene = editor_data.get_edited_scene_root();
- if (!scene)
+ if (!scene) {
return;
+ }
String path = EditorSettings::get_singleton()->get_project_settings_dir().plus_file(p_file.get_file() + "-editstate-" + p_file.md5_text() + ".cfg");
@@ -973,15 +934,15 @@ void EditorNode::_get_scene_metadata(const String &p_file) {
cf.instance();
Error err = cf->load(path);
- if (err != OK || !cf->has_section("editor_states"))
+ if (err != OK || !cf->has_section("editor_states")) {
return; //must not exist
+ }
List<String> esl;
cf->get_section_keys("editor_states", &esl);
Dictionary md;
for (List<String>::Element *E = esl.front(); E; E = E->next()) {
-
Variant st = cf->get_value("editor_states", E->get());
if (st.get_type() != Variant::NIL) {
md[E->get()] = st;
@@ -992,11 +953,11 @@ void EditorNode::_get_scene_metadata(const String &p_file) {
}
void EditorNode::_set_scene_metadata(const String &p_file, int p_idx) {
-
Node *scene = editor_data.get_edited_scene_root(p_idx);
- if (!scene)
+ if (!scene) {
return;
+ }
scene->set_meta("__editor_run_settings__", Variant()); //clear it (no point in keeping it)
scene->set_meta("__editor_plugin_states__", Variant());
@@ -1018,7 +979,6 @@ void EditorNode::_set_scene_metadata(const String &p_file, int p_idx) {
md.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
cf->set_value("editor_states", E->get(), md[E->get()]);
}
@@ -1027,12 +987,11 @@ void EditorNode::_set_scene_metadata(const String &p_file, int p_idx) {
}
bool EditorNode::_find_and_save_resource(RES p_res, Map<RES, bool> &processed, int32_t flags) {
-
- if (p_res.is_null())
+ if (p_res.is_null()) {
return false;
+ }
if (processed.has(p_res)) {
-
return processed[p_res];
}
@@ -1049,55 +1008,51 @@ bool EditorNode::_find_and_save_resource(RES p_res, Map<RES, bool> &processed, i
processed[p_res] = false; //because it's a file
return false;
} else {
-
processed[p_res] = changed;
return changed;
}
}
bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<RES, bool> &processed, int32_t flags) {
-
bool ret_changed = false;
List<PropertyInfo> pi;
obj->get_property_list(&pi);
for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
switch (E->get().type) {
case Variant::OBJECT: {
-
RES res = obj->get(E->get().name);
- if (_find_and_save_resource(res, processed, flags))
+ if (_find_and_save_resource(res, processed, flags)) {
ret_changed = true;
+ }
} break;
case Variant::ARRAY: {
-
Array varray = obj->get(E->get().name);
int len = varray.size();
for (int i = 0; i < len; i++) {
-
const Variant &v = varray.get(i);
RES res = v;
- if (_find_and_save_resource(res, processed, flags))
+ if (_find_and_save_resource(res, processed, flags)) {
ret_changed = true;
+ }
}
} break;
case Variant::DICTIONARY: {
-
Dictionary d = obj->get(E->get().name);
List<Variant> keys;
d.get_key_list(&keys);
for (List<Variant>::Element *F = keys.front(); F; F = F->next()) {
-
Variant v = d[F->get()];
RES res = v;
- if (_find_and_save_resource(res, processed, flags))
+ if (_find_and_save_resource(res, processed, flags)) {
ret_changed = true;
+ }
}
} break;
default: {
@@ -1109,34 +1064,34 @@ bool EditorNode::_find_and_save_edited_subresources(Object *obj, Map<RES, bool>
}
void EditorNode::_save_edited_subresources(Node *scene, Map<RES, bool> &processed, int32_t flags) {
-
_find_and_save_edited_subresources(scene, processed, flags);
for (int i = 0; i < scene->get_child_count(); i++) {
-
Node *n = scene->get_child(i);
- if (n->get_owner() != editor_data.get_edited_scene_root())
+ if (n->get_owner() != editor_data.get_edited_scene_root()) {
continue;
+ }
_save_edited_subresources(n, processed, flags);
}
}
void EditorNode::_find_node_types(Node *p_node, int &count_2d, int &count_3d) {
-
- if (p_node->is_class("Viewport") || (p_node != editor_data.get_edited_scene_root() && p_node->get_owner() != editor_data.get_edited_scene_root()))
+ if (p_node->is_class("Viewport") || (p_node != editor_data.get_edited_scene_root() && p_node->get_owner() != editor_data.get_edited_scene_root())) {
return;
+ }
- if (p_node->is_class("CanvasItem"))
+ if (p_node->is_class("CanvasItem")) {
count_2d++;
- else if (p_node->is_class("Node3D"))
+ } else if (p_node->is_class("Node3D")) {
count_3d++;
+ }
- for (int i = 0; i < p_node->get_child_count(); i++)
+ for (int i = 0; i < p_node->get_child_count(); i++) {
_find_node_types(p_node->get_child(i), count_2d, count_3d);
+ }
}
void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
-
EditorProgress save("save", TTR("Saving Scene"), 4);
if (editor_data.get_edited_scene_root() != nullptr) {
@@ -1164,7 +1119,6 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
}
if (img.is_valid()) {
-
img = img->duplicate();
save.step(TTR("Creating Thumbnail"), 2);
@@ -1193,8 +1147,6 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
}
img->convert(Image::FORMAT_RGB8);
- img->flip_y();
-
//save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5
String temp_path = EditorSettings::get_singleton()->get_cache_dir();
String cache_base = ProjectSettings::get_singleton()->globalize_path(p_file).md5_text();
@@ -1218,7 +1170,6 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
}
bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_node) {
-
for (int i = 0; i < p_node->get_child_count(); i++) {
Node *child = p_node->get_child(i);
if (child->get_filename() == p_filename) {
@@ -1234,7 +1185,6 @@ bool EditorNode::_validate_scene_recursive(const String &p_filename, Node *p_nod
}
static bool _find_edited_resources(const Ref<Resource> &p_resource, Set<Ref<Resource>> &edited_resources) {
-
if (p_resource->is_edited()) {
edited_resources.insert(p_resource);
return true;
@@ -1266,8 +1216,9 @@ int EditorNode::_save_external_resources() {
//save external resources and its subresources if any was modified
int flg = 0;
- if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources"))
+ if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) {
flg |= ResourceSaver::FLAG_COMPRESS;
+ }
flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
Set<Ref<Resource>> edited_subresources;
@@ -1275,10 +1226,10 @@ int EditorNode::_save_external_resources() {
List<Ref<Resource>> cached;
ResourceCache::get_cached_resources(&cached);
for (List<Ref<Resource>>::Element *E = cached.front(); E; E = E->next()) {
-
Ref<Resource> res = E->get();
- if (!res->get_path().is_resource_file())
+ if (!res->get_path().is_resource_file()) {
continue;
+ }
//not only check if this resourec is edited, check contained subresources too
if (_find_edited_resources(res, edited_subresources)) {
ResourceSaver::save(res->get_path(), res, flg);
@@ -1298,11 +1249,9 @@ int EditorNode::_save_external_resources() {
}
void EditorNode::_save_scene(String p_file, int idx) {
-
Node *scene = editor_data.get_edited_scene_root(idx);
if (!scene) {
-
show_accept(TTR("This operation can't be done without a tree root."), TTR("OK"));
return;
}
@@ -1325,17 +1274,17 @@ void EditorNode::_save_scene(String p_file, int idx) {
// old version still work for referencing changes in instanced or inherited scenes
sdata = Ref<PackedScene>(Object::cast_to<PackedScene>(ResourceCache::get(p_file)));
- if (sdata.is_valid())
+ if (sdata.is_valid()) {
sdata->recreate_state();
- else
+ } else {
sdata.instance();
+ }
} else {
sdata.instance();
}
Error err = sdata->pack(scene);
if (err != OK) {
-
show_accept(TTR("Couldn't save scene. Likely dependencies (instances or inheritance) couldn't be satisfied."), TTR("OK"));
return;
}
@@ -1350,8 +1299,9 @@ void EditorNode::_save_scene(String p_file, int idx) {
memdelete(dummy_scene);
int flg = 0;
- if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources"))
+ if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) {
flg |= ResourceSaver::FLAG_COMPRESS;
+ }
flg |= ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS;
err = ResourceSaver::save(p_file, sdata, flg);
@@ -1361,29 +1311,27 @@ void EditorNode::_save_scene(String p_file, int idx) {
editor_data.save_editor_external_data();
if (err == OK) {
scene->set_filename(ProjectSettings::get_singleton()->localize_path(p_file));
- if (idx < 0 || idx == editor_data.get_edited_scene())
+ if (idx < 0 || idx == editor_data.get_edited_scene()) {
set_current_version(editor_data.get_undo_redo().get_version());
- else
+ } else {
editor_data.set_edited_scene_version(0, idx);
+ }
editor_folding.save_scene_folding(scene, p_file);
_update_title();
_update_scene_tabs();
} else {
-
_dialog_display_save_error(p_file, err);
}
}
void EditorNode::save_all_scenes() {
-
_menu_option_confirm(RUN_STOP, true);
_save_all_scenes();
}
void EditorNode::save_scene_list(Vector<String> p_scene_filenames) {
-
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
Node *scene = editor_data.get_edited_scene_root(i);
@@ -1394,7 +1342,6 @@ void EditorNode::save_scene_list(Vector<String> p_scene_filenames) {
}
void EditorNode::restart_editor() {
-
exiting = true;
String to_reopen;
@@ -1416,14 +1363,14 @@ void EditorNode::restart_editor() {
}
void EditorNode::_save_all_scenes() {
-
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
Node *scene = editor_data.get_edited_scene_root(i);
if (scene && scene->get_filename() != "") {
- if (i != editor_data.get_edited_scene())
+ if (i != editor_data.get_edited_scene()) {
_save_scene(scene->get_filename(), i);
- else
+ } else {
_save_scene_with_preview(scene->get_filename());
+ }
} // else: ignore new scenes
}
@@ -1431,20 +1378,19 @@ void EditorNode::_save_all_scenes() {
}
void EditorNode::_mark_unsaved_scenes() {
-
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
-
Node *node = editor_data.get_edited_scene_root(i);
- if (!node)
+ if (!node) {
continue;
+ }
String path = node->get_filename();
if (!(path == String() || FileAccess::exists(path))) {
-
- if (i == editor_data.get_edited_scene())
+ if (i == editor_data.get_edited_scene()) {
set_current_version(-1);
- else
+ } else {
editor_data.set_edited_scene_version(-1, i);
+ }
}
}
@@ -1453,23 +1399,20 @@ void EditorNode::_mark_unsaved_scenes() {
}
void EditorNode::_dialog_action(String p_file) {
-
switch (current_option) {
case FILE_NEW_INHERITED_SCENE: {
-
Node *scene = editor_data.get_edited_scene_root();
// If the previous scene is rootless, just close it in favor of the new one.
- if (!scene)
+ if (!scene) {
_menu_option_confirm(FILE_CLOSE, true);
+ }
load_scene(p_file, false, true);
} break;
case FILE_OPEN_SCENE: {
-
load_scene(p_file);
} break;
case SETTINGS_PICK_MAIN_SCENE: {
-
ProjectSettings::get_singleton()->set("application/run/main_scene", p_file);
ProjectSettings::get_singleton()->save();
//would be nice to show the project manager opened with the highlighted field..
@@ -1486,14 +1429,14 @@ void EditorNode::_dialog_action(String p_file) {
case SCENE_TAB_CLOSE:
case FILE_SAVE_SCENE:
case FILE_SAVE_AS_SCENE: {
-
int scene_idx = (current_option == FILE_SAVE_SCENE || current_option == FILE_SAVE_AS_SCENE) ? -1 : tab_closing;
if (file->get_file_mode() == EditorFileDialog::FILE_MODE_SAVE_FILE) {
bool same_open_scene = false;
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
- if (editor_data.get_scene_path(i) == p_file && i != scene_idx)
+ if (editor_data.get_scene_path(i) == p_file && i != scene_idx) {
same_open_scene = true;
+ }
}
if (same_open_scene) {
@@ -1506,15 +1449,15 @@ void EditorNode::_dialog_action(String p_file) {
_add_to_recent_scenes(p_file);
save_layout();
- if (scene_idx != -1)
+ if (scene_idx != -1) {
_discard_changes();
+ }
}
} break;
case FILE_SAVE_AND_RUN: {
if (file->get_file_mode() == EditorFileDialog::FILE_MODE_SAVE_FILE) {
-
_save_default_environment();
_save_scene_with_preview(p_file);
_run(false, p_file);
@@ -1522,7 +1465,6 @@ void EditorNode::_dialog_action(String p_file) {
} break;
case FILE_EXPORT_MESH_LIBRARY: {
-
Ref<MeshLibrary> ml;
if (file_export_lib_merge->is_pressed() && FileAccess::exists(p_file)) {
ml = ResourceLoader::load(p_file, "MeshLibrary");
@@ -1547,7 +1489,6 @@ void EditorNode::_dialog_action(String p_file) {
} break;
case FILE_EXPORT_TILESET: {
-
Ref<TileSet> tileset;
if (FileAccess::exists(p_file) && file_export_lib_merge->is_pressed()) {
tileset = ResourceLoader::load(p_file, "TileSet");
@@ -1565,7 +1506,6 @@ void EditorNode::_dialog_action(String p_file) {
Error err = ResourceSaver::save(p_file, tileset);
if (err) {
-
show_accept(TTR("Error saving TileSet!"), TTR("OK"));
return;
}
@@ -1573,7 +1513,6 @@ void EditorNode::_dialog_action(String p_file) {
case RESOURCE_SAVE:
case RESOURCE_SAVE_AS: {
-
ERR_FAIL_COND(saving_resource.is_null());
save_resource_in_path(saving_resource, p_file);
saving_resource = Ref<Resource>();
@@ -1583,9 +1522,9 @@ void EditorNode::_dialog_action(String p_file) {
current_obj->_change_notify();
} break;
case SETTINGS_LAYOUT_SAVE: {
-
- if (p_file.empty())
+ if (p_file.empty()) {
return;
+ }
Ref<ConfigFile> config;
config.instance();
@@ -1611,9 +1550,9 @@ void EditorNode::_dialog_action(String p_file) {
} break;
case SETTINGS_LAYOUT_DELETE: {
-
- if (p_file.empty())
+ if (p_file.empty()) {
return;
+ }
Ref<ConfigFile> config;
config.instance();
@@ -1652,7 +1591,6 @@ void EditorNode::_dialog_action(String p_file) {
}
bool EditorNode::item_has_editor(Object *p_object) {
-
if (_is_class_editor_disabled_by_feature_profile(p_object->get_class())) {
return false;
}
@@ -1665,7 +1603,6 @@ void EditorNode::edit_item_resource(RES p_resource) {
}
bool EditorNode::_is_class_editor_disabled_by_feature_profile(const StringName &p_class) {
-
Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile();
if (profile.is_null()) {
return false;
@@ -1674,7 +1611,6 @@ bool EditorNode::_is_class_editor_disabled_by_feature_profile(const StringName &
StringName class_name = p_class;
while (class_name != StringName()) {
-
if (profile->is_class_disabled(class_name)) {
return true;
}
@@ -1688,7 +1624,6 @@ bool EditorNode::_is_class_editor_disabled_by_feature_profile(const StringName &
}
void EditorNode::edit_item(Object *p_object) {
-
Vector<EditorPlugin *> sub_plugins;
if (p_object) {
@@ -1699,7 +1634,6 @@ void EditorNode::edit_item(Object *p_object) {
}
if (!sub_plugins.empty()) {
-
bool same = true;
if (sub_plugins.size() == editor_plugins_over->get_plugins_list().size()) {
for (int i = 0; i < sub_plugins.size(); i++) {
@@ -1722,7 +1656,6 @@ void EditorNode::edit_item(Object *p_object) {
}
void EditorNode::push_item(Object *p_object, const String &p_property, bool p_inspector_only) {
-
if (!p_object) {
get_inspector()->edit(nullptr);
node_dock->set_node(nullptr);
@@ -1733,21 +1666,20 @@ void EditorNode::push_item(Object *p_object, const String &p_property, bool p_in
ObjectID id = p_object->get_instance_id();
if (id != editor_history.get_current()) {
-
if (p_inspector_only) {
editor_history.add_object_inspector_only(id);
- } else if (p_property == "")
+ } else if (p_property == "") {
editor_history.add_object(id);
- else
+ } else {
editor_history.add_object(id, p_property);
+ }
}
_edit_current();
}
void EditorNode::_save_default_environment() {
-
- Ref<Environment> fallback = get_tree()->get_root()->get_world()->get_fallback_environment();
+ Ref<Environment> fallback = get_tree()->get_root()->get_world_3d()->get_fallback_environment();
if (fallback.is_valid() && fallback->get_path().is_resource_file()) {
Map<RES, bool> processed;
@@ -1757,7 +1689,6 @@ void EditorNode::_save_default_environment() {
}
void EditorNode::hide_top_editors() {
-
_display_top_editors(false);
editor_plugins_over->clear();
@@ -1776,17 +1707,16 @@ void EditorNode::_set_editing_top_editors(Object *p_current_object) {
}
static bool overrides_external_editor(Object *p_object) {
-
Script *script = Object::cast_to<Script>(p_object);
- if (!script)
+ if (!script) {
return false;
+ }
return script->get_language()->overrides_external_editor();
}
void EditorNode::_edit_current() {
-
ObjectID current = editor_history.get_current();
Object *current_obj = current.is_valid() ? ObjectDB::get_instance(current) : nullptr;
bool inspector_only = editor_history.is_current_inspector_only();
@@ -1794,7 +1724,6 @@ void EditorNode::_edit_current() {
this->current = current_obj;
if (!current_obj) {
-
scene_tree_dock->set_selected(nullptr);
get_inspector()->edit(nullptr);
node_dock->set_node(nullptr);
@@ -1815,7 +1744,6 @@ void EditorNode::_edit_current() {
String editable_warning; //none by default
if (is_resource) {
-
Resource *current_res = Object::cast_to<Resource>(current_obj);
ERR_FAIL_COND(!current_res);
get_inspector()->edit(current_res);
@@ -1840,7 +1768,6 @@ void EditorNode::_edit_current() {
}
}
} else if (is_node) {
-
Node *current_node = Object::cast_to<Node>(current_obj);
ERR_FAIL_COND(!current_node);
@@ -1863,7 +1790,6 @@ void EditorNode::_edit_current() {
}
} else {
-
Node *selected_node = nullptr;
if (current_obj->is_class("EditorDebuggerRemoteObject")) {
@@ -1916,7 +1842,6 @@ void EditorNode::_edit_current() {
/* Take care of PLUGIN EDITOR */
if (!inspector_only) {
-
EditorPlugin *main_plugin = editor_data.get_editor(current_obj);
for (int i = 0; i < editor_table.size(); i++) {
@@ -1926,20 +1851,20 @@ void EditorNode::_edit_current() {
}
if (main_plugin) {
-
// special case if use of external editor is true
if (main_plugin->get_name() == "Script" && current_obj->get_class_name() != StringName("VisualScript") && (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")) || overrides_external_editor(current_obj))) {
- if (!changing_scene)
+ if (!changing_scene) {
main_plugin->edit(current_obj);
+ }
}
else if (main_plugin != editor_plugin_screen && (!ScriptEditor::get_singleton() || !ScriptEditor::get_singleton()->is_visible_in_tree() || ScriptEditor::get_singleton()->can_take_away_focus())) {
// update screen main_plugin
if (!changing_scene) {
-
- if (editor_plugin_screen)
+ if (editor_plugin_screen) {
editor_plugin_screen->make_visible(false);
+ }
editor_plugin_screen = main_plugin;
editor_plugin_screen->edit(current_obj);
@@ -1951,13 +1876,11 @@ void EditorNode::_edit_current() {
}
for (int i = 0; i < editor_table.size(); i++) {
-
main_editor_buttons[i]->set_pressed(editor_table[i] == main_plugin);
}
}
} else {
-
editor_plugin_screen->edit(current_obj);
}
}
@@ -1975,7 +1898,6 @@ void EditorNode::_edit_current() {
_set_editing_top_editors(current_obj);
_display_top_editors(true);
} else if (!editor_plugins_over->get_plugins_list().empty()) {
-
hide_top_editors();
}
}
@@ -1985,7 +1907,6 @@ void EditorNode::_edit_current() {
}
void EditorNode::_run(bool p_current, const String &p_custom) {
-
if (editor_run.get_status() == EditorRun::STATUS_PLAY) {
play_button->set_pressed(!_playing_edited);
play_scene_button->set_pressed(_playing_edited);
@@ -2005,7 +1926,6 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
bool skip_breakpoints;
if (p_current || (editor_data.get_edited_scene_root() && p_custom == editor_data.get_edited_scene_root()->get_filename())) {
-
Node *scene = editor_data.get_edited_scene_root();
if (!scene) {
@@ -2025,7 +1945,6 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
}
if (run_filename == "") {
-
//evidently, run the scene
if (!ensure_main_scene(false)) {
return;
@@ -2033,15 +1952,12 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
}
if (bool(EDITOR_GET("run/auto_save/save_before_running"))) {
-
if (unsaved_cache) {
-
Node *scene = editor_data.get_edited_scene_root();
if (scene) { //only autosave if there is a scene obviously
if (scene->get_filename() == "") {
-
show_accept(TTR("Current scene was never saved, please save it prior to running."), TTR("OK"));
return;
}
@@ -2053,8 +1969,9 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
editor_data.save_editor_external_data();
}
- if (!call_build())
+ if (!call_build()) {
return;
+ }
if (bool(EDITOR_GET("run/output/always_clear_output_on_play"))) {
log->clear();
@@ -2070,9 +1987,10 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
args = ProjectSettings::get_singleton()->get("editor/main_run_args");
skip_breakpoints = EditorDebuggerNode::get_singleton()->is_skip_breakpoints();
+ EditorDebuggerNode::get_singleton()->start();
Error error = editor_run.run(run_filename, args, breakpoints, skip_breakpoints);
if (error != OK) {
-
+ EditorDebuggerNode::get_singleton()->stop();
show_accept(TTR("Could not start subprocess!"), TTR("OK"));
return;
}
@@ -2094,26 +2012,41 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
_playing_edited = p_current;
}
-void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
+void EditorNode::_run_native(const Ref<EditorExportPreset> &p_preset) {
+ bool autosave = EDITOR_GET("run/auto_save/save_before_running");
+ if (autosave) {
+ _menu_option_confirm(FILE_SAVE_ALL_SCENES, false);
+ }
+ if (run_native->is_deploy_debug_remote_enabled()) {
+ _menu_option_confirm(RUN_STOP, true);
+
+ if (!call_build()) {
+ return; // build failed
+ }
- if (!p_confirmed) //this may be a hack..
+ EditorDebuggerNode::get_singleton()->start(p_preset->get_platform()->get_debug_protocol());
+ emit_signal("play_pressed");
+ editor_run.run_native_notify();
+ }
+}
+
+void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
+ if (!p_confirmed) { //this may be a hack..
current_option = (MenuOptions)p_option;
+ }
switch (p_option) {
case FILE_NEW_SCENE: {
-
new_scene();
} break;
case FILE_NEW_INHERITED_SCENE:
case FILE_OPEN_SCENE: {
-
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &extensions);
file->clear_filters();
for (int i = 0; i < extensions.size(); i++) {
-
file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
}
@@ -2126,27 +2059,24 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case FILE_QUICK_OPEN: {
-
quick_open->popup_dialog("Resource", true);
quick_open->set_title(TTR("Quick Open..."));
} break;
case FILE_QUICK_OPEN_SCENE: {
-
quick_open->popup_dialog("PackedScene", true);
quick_open->set_title(TTR("Quick Open Scene..."));
} break;
case FILE_QUICK_OPEN_SCRIPT: {
-
quick_open->popup_dialog("Script", true);
quick_open->set_title(TTR("Quick Open Script..."));
} break;
case FILE_OPEN_PREV: {
-
- if (previous_scenes.empty())
+ if (previous_scenes.empty()) {
break;
+ }
opening_prev = true;
open_request(previous_scenes.back()->get());
previous_scenes.pop_back();
@@ -2160,20 +2090,21 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
next_tab %= editor_data.get_edited_scene_count();
_scene_tab_closed(next_tab, current_option);
} else {
- if (current_option != FILE_CLOSE_ALL)
+ if (current_option != FILE_CLOSE_ALL) {
current_option = -1;
- else
+ } else {
_scene_tab_closed(editor_data.get_edited_scene());
+ }
}
- if (p_confirmed)
+ if (p_confirmed) {
_menu_option_confirm(SCENE_TAB_CLOSE, true);
+ }
} break;
case FILE_CLOSE_ALL_AND_QUIT:
case FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER:
case FILE_CLOSE: {
-
if (!p_confirmed) {
tab_closing = p_option == FILE_CLOSE ? editor_data.get_edited_scene() : _next_unsaved_scene(false);
@@ -2197,19 +2128,19 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
case SCENE_TAB_CLOSE:
case FILE_SAVE_SCENE: {
-
int scene_idx = (p_option == FILE_SAVE_SCENE) ? -1 : tab_closing;
Node *scene = editor_data.get_edited_scene_root(scene_idx);
if (scene && scene->get_filename() != "") {
-
- if (scene_idx != editor_data.get_edited_scene())
+ if (scene_idx != editor_data.get_edited_scene()) {
_save_scene_with_preview(scene->get_filename(), scene_idx);
- else
+ } else {
_save_scene_with_preview(scene->get_filename());
+ }
- if (scene_idx != -1)
+ if (scene_idx != -1) {
_discard_changes();
+ }
save_layout();
break;
@@ -2222,7 +2153,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
Node *scene = editor_data.get_edited_scene_root(scene_idx);
if (!scene) {
-
int saved = _save_external_resources();
String err_text;
if (saved > 0) {
@@ -2242,7 +2172,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
ResourceSaver::get_recognized_extensions(sd, &extensions);
file->clear_filters();
for (int i = 0; i < extensions.size(); i++) {
-
file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
}
@@ -2255,7 +2184,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
}
} else {
-
String existing;
if (extensions.size()) {
String root_name(scene->get_name());
@@ -2269,7 +2197,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case FILE_SAVE_ALL_SCENES: {
-
_save_all_scenes();
} break;
case FILE_SAVE_BEFORE_RUN: {
@@ -2286,14 +2213,11 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case FILE_EXPORT_PROJECT: {
-
project_export->popup_export();
} break;
case FILE_EXPORT_MESH_LIBRARY: {
-
if (!editor_data.get_edited_scene_root()) {
-
show_accept(TTR("This operation can't be done without a scene."), TTR("OK"));
break;
}
@@ -2311,7 +2235,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case FILE_EXPORT_TILESET: {
-
//Make sure that the scene has a root before trying to convert to tileset
if (!editor_data.get_edited_scene_root()) {
show_accept(TTR("This operation can't be done without a root node."), TTR("OK"));
@@ -2332,9 +2255,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case FILE_IMPORT_SUBSCENE: {
-
if (!editor_data.get_edited_scene_root()) {
-
show_accept(TTR("This operation can't be done without a selected node."), TTR("OK"));
break;
}
@@ -2344,9 +2265,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case FILE_EXTERNAL_OPEN_SCENE: {
-
if (unsaved_cache && !p_confirmed) {
-
confirmation->get_ok()->set_text(TTR("Open"));
confirmation->set_text(TTR("Current scene not saved. Open anyway?"));
confirmation->popup_centered();
@@ -2363,8 +2282,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case EDIT_UNDO: {
-
- if (InputFilter::get_singleton()->get_mouse_button_mask() & 0x7) {
+ if (Input::get_singleton()->get_mouse_button_mask() & 0x7) {
log->add_message("Can't undo while mouse buttons are pressed.", EditorLog::MSG_TYPE_EDITOR);
} else {
String action = editor_data.get_undo_redo().get_current_action_name();
@@ -2377,8 +2295,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
} break;
case EDIT_REDO: {
-
- if (InputFilter::get_singleton()->get_mouse_button_mask() & 0x7) {
+ if (Input::get_singleton()->get_mouse_button_mask() & 0x7) {
log->add_message("Can't redo while mouse buttons are pressed.", EditorLog::MSG_TYPE_EDITOR);
} else {
if (!editor_data.get_undo_redo().redo()) {
@@ -2390,12 +2307,12 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
} break;
- case EDIT_REVERT: {
-
+ case EDIT_RELOAD_SAVED_SCENE: {
Node *scene = get_edited_scene();
- if (!scene)
+ if (!scene) {
break;
+ }
String filename = scene->get_filename();
@@ -2405,8 +2322,9 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
if (unsaved_cache && !p_confirmed) {
- confirmation->get_ok()->set_text(TTR("Revert"));
- confirmation->set_text(TTR("This action cannot be undone. Revert anyway?"));
+ confirmation->get_ok()->set_text(TTR("Reload Saved Scene"));
+ confirmation->set_text(
+ TTR("The current scene has unsaved changes.\nReload the saved scene anyway? This action cannot be undone."));
confirmation->popup_centered();
break;
}
@@ -2414,8 +2332,9 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
int cur_idx = editor_data.get_edited_scene();
_remove_edited_scene();
Error err = load_scene(filename);
- if (err != OK)
+ if (err != OK) {
ERR_PRINT("Failed to load scene");
+ }
editor_data.move_edited_scene_to_index(cur_idx);
get_undo_redo()->clear_history(false);
scene_tabs->set_current_tab(cur_idx);
@@ -2440,9 +2359,9 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case RUN_STOP: {
-
- if (editor_run.get_status() == EditorRun::STATUS_STOP)
+ if (editor_run.get_status() == EditorRun::STATUS_STOP) {
break;
+ }
editor_run.stop();
run_custom_filename.clear();
@@ -2462,6 +2381,7 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
}
}
+ EditorDebuggerNode::get_singleton()->stop();
emit_signal("stop_pressed");
} break;
@@ -2474,38 +2394,18 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case RUN_PLAY_SCENE: {
-
_save_default_environment();
_menu_option_confirm(RUN_STOP, true);
_run(true);
} break;
- case RUN_PLAY_NATIVE: {
-
- bool autosave = EDITOR_GET("run/auto_save/save_before_running");
- if (autosave) {
- _menu_option_confirm(FILE_SAVE_ALL_SCENES, false);
- }
- if (run_native->is_deploy_debug_remote_enabled()) {
- _menu_option_confirm(RUN_STOP, true);
-
- if (!call_build())
- break; // build failed
-
- emit_signal("play_pressed");
- editor_run.run_native_notify();
- }
- } break;
case RUN_SCENE_SETTINGS: {
-
run_settings_dialog->popup_run_settings();
} break;
case RUN_SETTINGS: {
-
project_settings->popup_project_settings();
} break;
case FILE_INSTALL_ANDROID_SOURCE: {
-
if (p_confirmed) {
export_template_manager->install_android_template();
} else {
@@ -2526,14 +2426,11 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case FILE_QUIT:
case RUN_PROJECT_MANAGER: {
-
if (!p_confirmed) {
bool save_each = EDITOR_GET("interface/editor/save_each_scene_on_quit");
if (_next_unsaved_scene(!save_each) == -1) {
-
bool confirm = EDITOR_GET("interface/editor/quit_confirmation");
if (confirm) {
-
confirmation->get_ok()->set_text(p_option == FILE_QUIT ? TTR("Quit") : TTR("Yes"));
confirmation->set_text(p_option == FILE_QUIT ? TTR("Exit the editor?") : TTR("Open Project Manager?"));
confirmation->popup_centered();
@@ -2542,12 +2439,9 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
break;
}
} else {
-
if (save_each) {
-
_menu_option_confirm(p_option == FILE_QUIT ? FILE_CLOSE_ALL_AND_QUIT : FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER, false);
} else {
-
String unsaved_scenes;
int i = _next_unsaved_scene(true, 0);
while (i != -1) {
@@ -2571,65 +2465,52 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
_discard_changes();
} break;
case SETTINGS_UPDATE_CONTINUOUSLY: {
-
EditorSettings::get_singleton()->set("interface/editor/update_continuously", true);
_update_update_spinner();
show_accept(TTR("This option is deprecated. Situations where refresh must be forced are now considered a bug. Please report."), TTR("OK"));
} break;
case SETTINGS_UPDATE_WHEN_CHANGED: {
-
EditorSettings::get_singleton()->set("interface/editor/update_continuously", false);
_update_update_spinner();
} break;
case SETTINGS_UPDATE_SPINNER_HIDE: {
-
EditorSettings::get_singleton()->set("interface/editor/show_update_spinner", false);
_update_update_spinner();
} break;
case SETTINGS_PREFERENCES: {
-
settings_config_dialog->popup_edit_settings();
} break;
case SETTINGS_EDITOR_DATA_FOLDER: {
-
OS::get_singleton()->shell_open(String("file://") + EditorSettings::get_singleton()->get_data_dir());
} break;
case SETTINGS_EDITOR_CONFIG_FOLDER: {
-
OS::get_singleton()->shell_open(String("file://") + EditorSettings::get_singleton()->get_settings_dir());
} break;
case SETTINGS_MANAGE_EXPORT_TEMPLATES: {
-
export_template_manager->popup_manager();
} break;
case SETTINGS_MANAGE_FEATURE_PROFILES: {
-
feature_profile_manager->popup_centered_clamped(Size2(900, 800) * EDSCALE, 0.8);
} break;
case SETTINGS_TOGGLE_FULLSCREEN: {
-
DisplayServer::get_singleton()->window_set_mode(DisplayServer::get_singleton()->window_get_mode() == DisplayServer::WINDOW_MODE_FULLSCREEN ? DisplayServer::WINDOW_MODE_WINDOWED : DisplayServer::WINDOW_MODE_FULLSCREEN);
} break;
case SETTINGS_TOGGLE_CONSOLE: {
-
bool was_visible = DisplayServer::get_singleton()->is_console_visible();
DisplayServer::get_singleton()->console_set_visible(!was_visible);
EditorSettings::get_singleton()->set_setting("interface/editor/hide_console_window", was_visible);
} break;
case EDITOR_SCREENSHOT: {
-
screenshot_timer->start();
} break;
case SETTINGS_PICK_MAIN_SCENE: {
-
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &extensions);
file->clear_filters();
for (int i = 0; i < extensions.size(); i++) {
-
file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
}
@@ -2664,7 +2545,6 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case SET_VIDEO_DRIVER_SAVE_AND_RESTART: {
-
ProjectSettings::get_singleton()->set("rendering/quality/driver/driver_name", video_driver_request);
ProjectSettings::get_singleton()->save();
@@ -2688,7 +2568,6 @@ void EditorNode::_screenshot(bool p_use_utc) {
}
void EditorNode::_save_screenshot(NodePath p_path) {
-
SubViewport *viewport = Object::cast_to<SubViewport>(EditorInterface::get_singleton()->get_editor_viewport()->get_viewport());
viewport->set_clear_mode(SubViewport::CLEAR_MODE_ONLY_NEXT_FRAME);
Ref<Image> img = viewport->get_texture()->get_data();
@@ -2722,17 +2601,17 @@ void EditorNode::_tool_menu_option(int p_idx) {
}
int EditorNode::_next_unsaved_scene(bool p_valid_filename, int p_start) {
-
for (int i = p_start; i < editor_data.get_edited_scene_count(); i++) {
-
- if (!editor_data.get_edited_scene_root(i))
+ if (!editor_data.get_edited_scene_root(i)) {
continue;
+ }
int current = editor_data.get_edited_scene();
bool unsaved = (i == current) ? saved_version != editor_data.get_undo_redo().get_version() : editor_data.get_scene_version(i) != 0;
if (unsaved) {
String scene_filename = editor_data.get_edited_scene_root(i)->get_filename();
- if (p_valid_filename && scene_filename.length() == 0)
+ if (p_valid_filename && scene_filename.length() == 0) {
continue;
+ }
return i;
}
}
@@ -2751,9 +2630,7 @@ void EditorNode::_exit_editor() {
}
void EditorNode::_discard_changes(const String &p_str) {
-
switch (current_option) {
-
case FILE_CLOSE_ALL_AND_QUIT:
case FILE_CLOSE_ALL_AND_RUN_PROJECT_MANAGER:
case FILE_CLOSE:
@@ -2761,7 +2638,6 @@ void EditorNode::_discard_changes(const String &p_str) {
case FILE_CLOSE_RIGHT:
case FILE_CLOSE_ALL:
case SCENE_TAB_CLOSE: {
-
Node *scene = editor_data.get_edited_scene_root(tab_closing);
if (scene != nullptr) {
String scene_filename = scene->get_filename();
@@ -2795,13 +2671,11 @@ void EditorNode::_discard_changes(const String &p_str) {
}
} break;
case FILE_QUIT: {
-
_menu_option_confirm(RUN_STOP, true);
_exit_editor();
} break;
case RUN_PROJECT_MANAGER: {
-
_menu_option_confirm(RUN_STOP, true);
_exit_editor();
String exec = OS::get_singleton()->get_executable_path();
@@ -2819,7 +2693,6 @@ void EditorNode::_discard_changes(const String &p_str) {
}
void EditorNode::_update_file_menu_opened() {
-
Ref<ShortCut> close_scene_sc = ED_GET_SHORTCUT("editor/close_scene");
close_scene_sc->set_name(TTR("Close Scene"));
Ref<ShortCut> reopen_closed_scene_sc = ED_GET_SHORTCUT("editor/reopen_closed_scene");
@@ -2834,20 +2707,20 @@ void EditorNode::_update_file_menu_closed() {
}
Control *EditorNode::get_viewport() {
-
return viewport;
}
void EditorNode::_editor_select(int p_which) {
-
static bool selecting = false;
- if (selecting || changing_scene)
+ if (selecting || changing_scene) {
return;
+ }
ERR_FAIL_INDEX(p_which, editor_table.size());
- if (!main_editor_buttons[p_which]->is_visible()) //button hidden, no editor
+ if (!main_editor_buttons[p_which]->is_visible()) { //button hidden, no editor
return;
+ }
selecting = true;
@@ -2860,8 +2733,9 @@ void EditorNode::_editor_select(int p_which) {
EditorPlugin *new_editor = editor_table[p_which];
ERR_FAIL_COND(!new_editor);
- if (editor_plugin_screen == new_editor)
+ if (editor_plugin_screen == new_editor) {
return;
+ }
if (editor_plugin_screen) {
editor_plugin_screen->make_visible(false);
@@ -2899,9 +2773,7 @@ void EditorNode::select_editor_by_name(const String &p_name) {
}
void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed) {
-
if (p_editor->has_main_screen()) {
-
ToolButton *tb = memnew(ToolButton);
tb->set_toggle_mode(true);
tb->connect("pressed", callable_mp(singleton, &EditorNode::_editor_select), varray(singleton->main_editor_buttons.size()));
@@ -2923,18 +2795,15 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed
}
singleton->editor_data.add_editor_plugin(p_editor);
singleton->add_child(p_editor);
- if (p_config_changed)
+ if (p_config_changed) {
p_editor->enable_plugin();
+ }
}
void EditorNode::remove_editor_plugin(EditorPlugin *p_editor, bool p_config_changed) {
-
if (p_editor->has_main_screen()) {
-
for (int i = 0; i < singleton->main_editor_buttons.size(); i++) {
-
if (p_editor->get_name() == singleton->main_editor_buttons[i]->get_text()) {
-
if (singleton->main_editor_buttons[i]->is_pressed()) {
singleton->_editor_select(EDITOR_SCRIPT);
}
@@ -2950,8 +2819,9 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor, bool p_config_chan
}
p_editor->make_visible(false);
p_editor->clear();
- if (p_config_changed)
+ if (p_config_changed) {
p_editor->disable_plugin();
+ }
singleton->editor_plugins_over->get_plugins_list().erase(p_editor);
singleton->remove_child(p_editor);
singleton->editor_data.remove_editor_plugin(p_editor);
@@ -2959,9 +2829,9 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor, bool p_config_chan
}
void EditorNode::_update_addon_config() {
-
- if (_initializing_addons)
+ if (_initializing_addons) {
return;
+ }
Vector<String> enabled_addons;
@@ -2979,12 +2849,10 @@ void EditorNode::_update_addon_config() {
}
void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled, bool p_config_changed) {
-
ERR_FAIL_COND(p_enabled && plugin_addons.has(p_addon));
ERR_FAIL_COND(!p_enabled && !plugin_addons.has(p_addon));
if (!p_enabled) {
-
EditorPlugin *addon = plugin_addons[p_addon];
remove_editor_plugin(addon, p_config_changed);
memdelete(addon); //bye
@@ -3061,7 +2929,6 @@ void EditorNode::set_addon_plugin_enabled(const String &p_addon, bool p_enabled,
}
bool EditorNode::is_addon_plugin_enabled(const String &p_addon) const {
-
return plugin_addons.has(p_addon);
}
@@ -3082,7 +2949,9 @@ void EditorNode::_remove_edited_scene(bool p_change_tab) {
ScriptEditor::get_singleton()->close_builtin_scripts_from_scene(editor_data.get_scene_path(old_index));
}
- if (p_change_tab) _scene_tab_changed(new_index);
+ if (p_change_tab) {
+ _scene_tab_changed(new_index);
+ }
editor_data.remove_scene(old_index);
editor_data.get_undo_redo().clear_history(false);
_update_title();
@@ -3090,7 +2959,6 @@ void EditorNode::_remove_edited_scene(bool p_change_tab) {
}
void EditorNode::_remove_scene(int index, bool p_change_tab) {
-
if (editor_data.get_edited_scene() == index) {
//Scene to remove is current scene
_remove_edited_scene(p_change_tab);
@@ -3101,37 +2969,39 @@ void EditorNode::_remove_scene(int index, bool p_change_tab) {
}
void EditorNode::set_edited_scene(Node *p_scene) {
-
if (get_editor_data().get_edited_scene_root()) {
- if (get_editor_data().get_edited_scene_root()->get_parent() == scene_root)
+ if (get_editor_data().get_edited_scene_root()->get_parent() == scene_root) {
scene_root->remove_child(get_editor_data().get_edited_scene_root());
+ }
}
get_editor_data().set_edited_scene_root(p_scene);
- if (Object::cast_to<Popup>(p_scene))
+ if (Object::cast_to<Popup>(p_scene)) {
Object::cast_to<Popup>(p_scene)->show(); //show popups
+ }
scene_tree_dock->set_edited_scene(p_scene);
- if (get_tree())
+ if (get_tree()) {
get_tree()->set_edited_scene_root(p_scene);
+ }
if (p_scene) {
- if (p_scene->get_parent() != scene_root)
+ if (p_scene->get_parent() != scene_root) {
scene_root->add_child(p_scene);
+ }
}
}
int EditorNode::_get_current_main_editor() {
-
for (int i = 0; i < editor_table.size(); i++) {
- if (editor_table[i] == editor_plugin_screen)
+ if (editor_table[i] == editor_plugin_screen) {
return i;
+ }
}
return 0;
}
Dictionary EditorNode::_get_main_scene_state() {
-
Dictionary state;
state["main_tab"] = _get_current_main_editor();
state["scene_tree_offset"] = scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->get_value();
@@ -3142,9 +3012,9 @@ Dictionary EditorNode::_get_main_scene_state() {
}
void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) {
-
- if (get_edited_scene() != p_for_scene && p_for_scene != nullptr)
+ if (get_edited_scene() != p_for_scene && p_for_scene != nullptr) {
return; //not for this scene
+ }
changing_scene = false;
@@ -3178,13 +3048,16 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) {
}
}
- if (p_state.has("scene_tree_offset"))
+ if (p_state.has("scene_tree_offset")) {
scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->set_value(p_state["scene_tree_offset"]);
- if (p_state.has("property_edit_offset"))
+ }
+ if (p_state.has("property_edit_offset")) {
get_inspector()->set_scroll_offset(p_state["property_edit_offset"]);
+ }
- if (p_state.has("node_filter"))
+ if (p_state.has("node_filter")) {
scene_tree_dock->set_filter(p_state["node_filter"]);
+ }
//this should only happen at the very end
@@ -3194,7 +3067,6 @@ void EditorNode::_set_main_scene_state(Dictionary p_state, Node *p_for_scene) {
}
void EditorNode::set_current_version(uint64_t p_version) {
-
saved_version = p_version;
editor_data.set_edited_scene_version(p_version);
}
@@ -3204,19 +3076,19 @@ bool EditorNode::is_changing_scene() const {
}
void EditorNode::_clear_undo_history() {
-
get_undo_redo()->clear_history(false);
}
void EditorNode::set_current_scene(int p_idx) {
-
//Save the folding in case the scene gets reloaded.
- if (editor_data.get_scene_path(p_idx) != "" && editor_data.get_edited_scene_root(p_idx))
+ if (editor_data.get_scene_path(p_idx) != "" && editor_data.get_edited_scene_root(p_idx)) {
editor_folding.save_scene_folding(editor_data.get_edited_scene_root(p_idx), editor_data.get_scene_path(p_idx));
+ }
if (editor_data.check_and_update_scene(p_idx)) {
- if (editor_data.get_scene_path(p_idx) != "")
+ if (editor_data.get_scene_path(p_idx) != "") {
editor_folding.load_scene_folding(editor_data.get_edited_scene_root(p_idx), editor_data.get_scene_path(p_idx));
+ }
call_deferred("_clear_undo_history");
}
@@ -3225,8 +3097,9 @@ void EditorNode::set_current_scene(int p_idx) {
editor_data.save_edited_scene_state(editor_selection, &editor_history, _get_main_scene_state());
if (get_editor_data().get_edited_scene_root()) {
- if (get_editor_data().get_edited_scene_root()->get_parent() == scene_root)
+ if (get_editor_data().get_edited_scene_root()->get_parent() == scene_root) {
scene_root->remove_child(get_editor_data().get_edited_scene_root());
+ }
}
editor_selection->clear();
@@ -3234,16 +3107,19 @@ void EditorNode::set_current_scene(int p_idx) {
Node *new_scene = editor_data.get_edited_scene_root();
- if (Object::cast_to<Popup>(new_scene))
+ if (Object::cast_to<Popup>(new_scene)) {
Object::cast_to<Popup>(new_scene)->show(); //show popups
+ }
scene_tree_dock->set_edited_scene(new_scene);
- if (get_tree())
+ if (get_tree()) {
get_tree()->set_edited_scene_root(new_scene);
+ }
if (new_scene) {
- if (new_scene->get_parent() != scene_root)
+ if (new_scene->get_parent() != scene_root) {
scene_root->add_child(new_scene);
+ }
}
Dictionary state = editor_data.restore_edited_scene_state(editor_selection, &editor_history);
@@ -3255,10 +3131,10 @@ void EditorNode::set_current_scene(int p_idx) {
}
bool EditorNode::is_scene_open(const String &p_path) {
-
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
- if (editor_data.get_scene_path(i) == p_path)
+ if (editor_data.get_scene_path(i) == p_path) {
return true;
+ }
}
return false;
@@ -3277,16 +3153,13 @@ int EditorNode::new_scene() {
}
Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, bool p_set_inherited, bool p_clear_errors, bool p_force_open_imported) {
-
if (!is_inside_tree()) {
defer_load_scene = p_scene;
return OK;
}
if (!p_set_inherited) {
-
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
-
if (editor_data.get_scene_path(i) == p_scene) {
_scene_tab_changed(i);
return OK;
@@ -3302,13 +3175,13 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
}
}
- if (p_clear_errors)
+ if (p_clear_errors) {
load_errors->clear();
+ }
String lpath = ProjectSettings::get_singleton()->localize_path(p_scene);
if (!lpath.begins_with("res://")) {
-
show_accept(TTR("Error loading scene, it must be inside the project path. Use 'Import' to open the scene, then save it inside the project path."), TTR("OK"));
opening_prev = false;
return ERR_FILE_NOT_FOUND;
@@ -3328,7 +3201,6 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
Error err;
Ref<PackedScene> sdata = ResourceLoader::load(lpath, "", true, &err);
if (!sdata.is_valid()) {
-
_dialog_display_load_error(lpath, err);
opening_prev = false;
@@ -3340,11 +3212,9 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
}
if (!p_ignore_broken_deps && dependency_errors.has(lpath)) {
-
current_option = -1;
Vector<String> errors;
for (Set<String>::Element *E = dependency_errors[lpath].front(); E; E = E->next()) {
-
errors.push_back(E->get());
}
dependency_error->show(DependencyErrorDialog::MODE_SCENE, lpath, errors);
@@ -3360,7 +3230,6 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
dependency_errors.erase(lpath); //at least not self path
for (Map<String, Set<String>>::Element *E = dependency_errors.front(); E; E = E->next()) {
-
String txt = vformat(TTR("Scene '%s' has broken dependencies:"), E->key()) + "\n";
for (Set<String>::Element *F = E->get().front(); F; F = F->next()) {
txt += "\t" + F->get() + "\n";
@@ -3384,7 +3253,6 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
Node *new_scene = sdata->instance(PackedScene::GEN_EDIT_STATE_MAIN);
if (!new_scene) {
-
sdata.unref();
_dialog_display_load_error(lpath, ERR_FILE_NOT_FOUND);
opening_prev = false;
@@ -3435,7 +3303,6 @@ Error EditorNode::load_scene(const String &p_scene, bool p_ignore_broken_deps, b
}
void EditorNode::open_request(const String &p_path) {
-
if (!opening_prev) {
List<String>::Element *prev_scene = previous_scenes.find(p_path);
if (prev_scene != nullptr) {
@@ -3447,12 +3314,10 @@ void EditorNode::open_request(const String &p_path) {
}
void EditorNode::request_instance_scene(const String &p_path) {
-
scene_tree_dock->instance(p_path);
}
void EditorNode::request_instance_scenes(const Vector<String> &p_files) {
-
scene_tree_dock->instance_scenes(p_files);
}
@@ -3461,66 +3326,58 @@ ImportDock *EditorNode::get_import_dock() {
}
FileSystemDock *EditorNode::get_filesystem_dock() {
-
return filesystem_dock;
}
-SceneTreeDock *EditorNode::get_scene_tree_dock() {
+SceneTreeDock *EditorNode::get_scene_tree_dock() {
return scene_tree_dock;
}
-InspectorDock *EditorNode::get_inspector_dock() {
+InspectorDock *EditorNode::get_inspector_dock() {
return inspector_dock;
}
void EditorNode::_inherit_request(String p_file) {
-
current_option = FILE_NEW_INHERITED_SCENE;
_dialog_action(p_file);
}
void EditorNode::_instance_request(const Vector<String> &p_files) {
-
request_instance_scenes(p_files);
}
void EditorNode::_close_messages() {
-
old_split_ofs = center_split->get_split_offset();
center_split->set_split_offset(0);
}
void EditorNode::_show_messages() {
-
center_split->set_split_offset(old_split_ofs);
}
void EditorNode::_add_to_recent_scenes(const String &p_scene) {
-
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scenes", Array());
- if (rc.find(p_scene) != -1)
+ if (rc.find(p_scene) != -1) {
rc.erase(p_scene);
+ }
rc.push_front(p_scene);
- if (rc.size() > 10)
+ if (rc.size() > 10) {
rc.resize(10);
+ }
EditorSettings::get_singleton()->set_project_metadata("recent_files", "scenes", rc);
_update_recent_scenes();
}
void EditorNode::_open_recent_scene(int p_idx) {
-
if (p_idx == recent_scenes->get_item_count() - 1) {
-
EditorSettings::get_singleton()->set_project_metadata("recent_files", "scenes", Array());
call_deferred("_update_recent_scenes");
} else {
-
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scenes", Array());
ERR_FAIL_INDEX(p_idx, rc.size());
if (load_scene(rc[p_idx]) != OK) {
-
rc.remove(p_idx);
EditorSettings::get_singleton()->set_project_metadata("recent_files", "scenes", rc);
_update_recent_scenes();
@@ -3529,13 +3386,11 @@ void EditorNode::_open_recent_scene(int p_idx) {
}
void EditorNode::_update_recent_scenes() {
-
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scenes", Array());
recent_scenes->clear();
String path;
for (int i = 0; i < rc.size(); i++) {
-
path = rc[i];
recent_scenes->add_item(path.replace("res://", ""), i);
}
@@ -3546,7 +3401,6 @@ void EditorNode::_update_recent_scenes() {
}
void EditorNode::_quick_opened() {
-
Vector<String> files = quick_open->get_selected_files();
for (int i = 0; i < files.size(); i++) {
@@ -3561,12 +3415,10 @@ void EditorNode::_quick_opened() {
}
void EditorNode::_quick_run() {
-
_run(false, quick_run->get_selected());
}
void EditorNode::notify_all_debug_sessions_exited() {
-
_menu_option_confirm(RUN_STOP, false);
stop_button->set_pressed(false);
editor_run.stop();
@@ -3577,7 +3429,6 @@ void EditorNode::add_io_error(const String &p_error) {
}
void EditorNode::_load_error_notify(void *p_ud, const String &p_text) {
-
EditorNode *en = (EditorNode *)p_ud;
en->load_errors->add_image(en->gui_base->get_theme_icon("Error", "EditorIcons"));
en->load_errors->add_text(p_text + "\n");
@@ -3585,13 +3436,11 @@ void EditorNode::_load_error_notify(void *p_ud, const String &p_text) {
}
bool EditorNode::_find_scene_in_use(Node *p_node, const String &p_path) const {
-
if (p_node->get_filename() == p_path) {
return true;
}
for (int i = 0; i < p_node->get_child_count(); i++) {
-
if (_find_scene_in_use(p_node->get_child(i), p_path)) {
return true;
}
@@ -3601,15 +3450,14 @@ bool EditorNode::_find_scene_in_use(Node *p_node, const String &p_path) const {
}
bool EditorNode::is_scene_in_use(const String &p_path) {
-
Node *es = get_edited_scene();
- if (es)
+ if (es) {
return _find_scene_in_use(es, p_path);
+ }
return false;
}
void EditorNode::register_editor_types() {
-
ResourceLoader::set_timestamp_on_load(true);
ResourceSaver::set_timestamp_on_save(true);
@@ -3646,16 +3494,15 @@ void EditorNode::register_editor_types() {
}
void EditorNode::unregister_editor_types() {
-
_init_callbacks.clear();
}
void EditorNode::stop_child_process(OS::ProcessID p_pid) {
-
if (has_child_process(p_pid)) {
editor_run.stop_child_process(p_pid);
- if (!editor_run.get_child_process_count()) // All children stopped. Closing.
+ if (!editor_run.get_child_process_count()) { // All children stopped. Closing.
_menu_option_confirm(RUN_STOP, false);
+ }
}
}
@@ -3702,8 +3549,9 @@ StringName EditorNode::get_object_custom_type_name(const Object *p_object) const
Ref<Script> base_script = script;
while (base_script.is_valid()) {
StringName name = EditorNode::get_editor_data().script_class_get_name(base_script->get_path());
- if (name != StringName())
+ if (name != StringName()) {
return name;
+ }
// should probably be deprecated in 4.x
StringName base = base_script->get_instance_base_type();
@@ -3769,14 +3617,17 @@ Ref<Texture2D> EditorNode::get_object_icon(const Object *p_object, const String
}
// should probably be deprecated in 4.x
- if (p_object->has_meta("_editor_icon"))
+ if (p_object->has_meta("_editor_icon")) {
return p_object->get_meta("_editor_icon");
+ }
- if (gui_base->has_theme_icon(p_object->get_class(), "EditorIcons"))
+ if (gui_base->has_theme_icon(p_object->get_class(), "EditorIcons")) {
return gui_base->get_theme_icon(p_object->get_class(), "EditorIcons");
+ }
- if (p_fallback.length())
+ if (p_fallback.length()) {
return gui_base->get_theme_icon(p_fallback, "EditorIcons");
+ }
return nullptr;
}
@@ -3826,14 +3677,14 @@ Ref<Texture2D> EditorNode::get_class_icon(const String &p_class, const String &p
}
}
- if (p_fallback.length() && gui_base->has_theme_icon(p_fallback, "EditorIcons"))
+ if (p_fallback.length() && gui_base->has_theme_icon(p_fallback, "EditorIcons")) {
return gui_base->get_theme_icon(p_fallback, "EditorIcons");
+ }
return nullptr;
}
void EditorNode::progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) {
-
if (singleton->cmdline_export_mode) {
print_line(p_task + ": begin: " + p_label + " steps: " + itos(p_steps));
} else {
@@ -3842,18 +3693,15 @@ void EditorNode::progress_add_task(const String &p_task, const String &p_label,
}
bool EditorNode::progress_task_step(const String &p_task, const String &p_state, int p_step, bool p_force_refresh) {
-
if (singleton->cmdline_export_mode) {
print_line("\t" + p_task + ": step " + itos(p_step) + ": " + p_state);
return false;
} else {
-
return singleton->progress_dialog->task_step(p_task, p_state, p_step, p_force_refresh);
}
}
void EditorNode::progress_end_task(const String &p_task) {
-
if (singleton->cmdline_export_mode) {
print_line(p_task + ": end");
} else {
@@ -3862,29 +3710,23 @@ void EditorNode::progress_end_task(const String &p_task) {
}
void EditorNode::progress_add_task_bg(const String &p_task, const String &p_label, int p_steps) {
-
singleton->progress_hb->add_task(p_task, p_label, p_steps);
}
void EditorNode::progress_task_step_bg(const String &p_task, int p_step) {
-
singleton->progress_hb->task_step(p_task, p_step);
}
void EditorNode::progress_end_task_bg(const String &p_task) {
-
singleton->progress_hb->end_task(p_task);
}
Ref<Texture2D> EditorNode::_file_dialog_get_icon(const String &p_path) {
-
EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->get_filesystem_path(p_path.get_base_dir());
if (efsd) {
-
String file = p_path.get_file();
for (int i = 0; i < efsd->get_file_count(); i++) {
if (efsd->get_file(i) == file) {
-
String type = efsd->get_file_type(i);
if (singleton->icon_type_cache.has(type)) {
@@ -3900,42 +3742,36 @@ Ref<Texture2D> EditorNode::_file_dialog_get_icon(const String &p_path) {
}
void EditorNode::_build_icon_type_cache() {
-
List<StringName> tl;
StringName ei = "EditorIcons";
theme_base->get_theme()->get_icon_list(ei, &tl);
for (List<StringName>::Element *E = tl.front(); E; E = E->next()) {
-
- if (!ClassDB::class_exists(E->get()))
+ if (!ClassDB::class_exists(E->get())) {
continue;
+ }
icon_type_cache[E->get()] = theme_base->get_theme()->get_icon(E->get(), ei);
}
}
void EditorNode::_file_dialog_register(FileDialog *p_dialog) {
-
singleton->file_dialogs.insert(p_dialog);
}
void EditorNode::_file_dialog_unregister(FileDialog *p_dialog) {
-
singleton->file_dialogs.erase(p_dialog);
}
void EditorNode::_editor_file_dialog_register(EditorFileDialog *p_dialog) {
-
singleton->editor_file_dialogs.insert(p_dialog);
}
void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog) {
-
singleton->editor_file_dialogs.erase(p_dialog);
}
Vector<EditorNodeInitCallback> EditorNode::_init_callbacks;
Error EditorNode::export_preset(const String &p_preset, const String &p_path, bool p_debug, bool p_pack_only) {
-
export_defer.preset = p_preset;
export_defer.path = p_path;
export_defer.debug = p_debug;
@@ -3952,7 +3788,6 @@ void EditorNode::show_accept(const String &p_text, const String &p_title) {
}
void EditorNode::show_warning(const String &p_text, const String &p_title) {
-
if (warning->is_inside_tree()) {
warning->set_text(p_text);
warning->set_title(p_title);
@@ -3963,7 +3798,6 @@ void EditorNode::show_warning(const String &p_text, const String &p_title) {
}
void EditorNode::_copy_warning(const String &p_str) {
-
DisplayServer::get_singleton()->clipboard_set(warning->get_text());
}
@@ -4028,7 +3862,6 @@ void EditorNode::_dock_make_float() {
}
void EditorNode::_update_dock_containers() {
-
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
if (dock_slot[i]->get_tab_count() == 0 && dock_slot[i]->is_visible()) {
dock_slot[i]->hide();
@@ -4039,24 +3872,24 @@ void EditorNode::_update_dock_containers() {
}
for (int i = 0; i < vsplits.size(); i++) {
bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count();
- if (in_use)
+ if (in_use) {
vsplits[i]->show();
- else
+ } else {
vsplits[i]->hide();
+ }
}
- if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible())
+ if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible()) {
right_hsplit->show();
- else
+ } else {
right_hsplit->hide();
+ }
}
void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) {
-
Ref<InputEventMouse> me = p_input;
if (me.is_valid()) {
-
Vector2 point = me->get_position();
int nrect = -1;
@@ -4072,8 +3905,9 @@ void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) {
dock_select_rect_over = nrect;
}
- if (nrect == -1)
+ if (nrect == -1) {
return;
+ }
Ref<InputEventMouseButton> mb = me;
@@ -4086,7 +3920,6 @@ void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) {
dock_slot[dock_popup_selected]->hide();
} else {
-
dock_slot[dock_popup_selected]->set_current_tab(0);
}
@@ -4105,24 +3938,23 @@ void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) {
}
void EditorNode::_dock_popup_exit() {
-
dock_select_rect_over = -1;
dock_select->update();
}
void EditorNode::_dock_pre_popup(int p_which) {
-
dock_popup_selected = p_which;
}
void EditorNode::_dock_move_left() {
-
- if (dock_popup_selected < 0 || dock_popup_selected >= DOCK_SLOT_MAX)
+ if (dock_popup_selected < 0 || dock_popup_selected >= DOCK_SLOT_MAX) {
return;
+ }
Control *current = dock_slot[dock_popup_selected]->get_tab_control(dock_slot[dock_popup_selected]->get_current_tab());
Control *prev = dock_slot[dock_popup_selected]->get_tab_control(dock_slot[dock_popup_selected]->get_current_tab() - 1);
- if (!current || !prev)
+ if (!current || !prev) {
return;
+ }
dock_slot[dock_popup_selected]->move_child(current, prev->get_index());
dock_slot[dock_popup_selected]->set_current_tab(dock_slot[dock_popup_selected]->get_current_tab() - 1);
dock_select->update();
@@ -4131,11 +3963,11 @@ void EditorNode::_dock_move_left() {
}
void EditorNode::_dock_move_right() {
-
Control *current = dock_slot[dock_popup_selected]->get_tab_control(dock_slot[dock_popup_selected]->get_current_tab());
Control *next = dock_slot[dock_popup_selected]->get_tab_control(dock_slot[dock_popup_selected]->get_current_tab() + 1);
- if (!current || !next)
+ if (!current || !next) {
return;
+ }
dock_slot[dock_popup_selected]->move_child(next, current->get_index());
dock_slot[dock_popup_selected]->set_current_tab(dock_slot[dock_popup_selected]->get_current_tab() + 1);
dock_select->update();
@@ -4166,18 +3998,15 @@ void EditorNode::_dock_select_draw() {
dock_tab_move_right->set_disabled(true);
if (dock_popup_selected != -1 && dock_slot[dock_popup_selected]->get_tab_count()) {
-
dock_tab_move_left->set_disabled(dock_slot[dock_popup_selected]->get_current_tab() == 0);
dock_tab_move_right->set_disabled(dock_slot[dock_popup_selected]->get_current_tab() >= dock_slot[dock_popup_selected]->get_tab_count() - 1);
}
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
-
Vector2 ofs;
switch (i) {
case DOCK_SLOT_LEFT_UL: {
-
} break;
case DOCK_SLOT_LEFT_BL: {
ofs.y += s.y;
@@ -4218,22 +4047,21 @@ void EditorNode::_dock_select_draw() {
} else if (dock_slot[i]->get_child_count() == 0) {
dock_select->draw_rect(r, unused);
} else {
-
dock_select->draw_rect(r, used);
}
for (int j = 0; j < MIN(3, dock_slot[i]->get_child_count()); j++) {
int xofs = (r.size.width / 3) * j;
Color c = used;
- if (i == dock_popup_selected && (dock_slot[i]->get_current_tab() > 3 || dock_slot[i]->get_current_tab() == j))
+ if (i == dock_popup_selected && (dock_slot[i]->get_current_tab() > 3 || dock_slot[i]->get_current_tab() == j)) {
c = tab_selected;
+ }
dock_select->draw_rect(Rect2(2 + ofs.x + xofs, ofs.y, r.size.width / 3 - 1, 3), c);
}
}
}
void EditorNode::_save_docks() {
-
if (waiting_for_first_scan) {
return; //scanning, do not touch docks
}
@@ -4248,13 +4076,13 @@ void EditorNode::_save_docks() {
}
void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String &p_section) {
-
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
String names;
for (int j = 0; j < dock_slot[i]->get_tab_count(); j++) {
String name = dock_slot[i]->get_tab_control(j)->get_name();
- if (names != "")
+ if (names != "") {
names += ",";
+ }
names += name;
}
@@ -4268,14 +4096,12 @@ void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String &p
p_layout->set_value(p_section, "dock_filesystem_file_list_display_mode", filesystem_dock->get_file_list_display_mode());
for (int i = 0; i < vsplits.size(); i++) {
-
if (vsplits[i]->is_visible_in_tree()) {
p_layout->set_value(p_section, "dock_split_" + itos(i + 1), vsplits[i]->get_split_offset());
}
}
for (int i = 0; i < hsplits.size(); i++) {
-
p_layout->set_value(p_section, "dock_hsplit_" + itos(i + 1), hsplits[i]->get_split_offset());
}
}
@@ -4293,17 +4119,14 @@ void EditorNode::_save_open_scenes_to_config(Ref<ConfigFile> p_layout, const Str
}
void EditorNode::save_layout() {
-
dock_drag_timer->start();
}
void EditorNode::_dock_split_dragged(int ofs) {
-
dock_drag_timer->start();
}
void EditorNode::_load_docks() {
-
Ref<ConfigFile> config;
config.instance();
Error err = config->load(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("editor_layout.cfg"));
@@ -4322,9 +4145,7 @@ void EditorNode::_load_docks() {
}
void EditorNode::_update_dock_slots_visibility() {
-
if (!docks_visible) {
-
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
dock_slot[i]->hide();
}
@@ -4337,48 +4158,47 @@ void EditorNode::_update_dock_slots_visibility() {
bottom_panel->hide();
} else {
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
-
int tabs_visible = 0;
for (int j = 0; j < dock_slot[i]->get_tab_count(); j++) {
if (!dock_slot[i]->get_tab_hidden(j)) {
tabs_visible++;
}
}
- if (tabs_visible)
+ if (tabs_visible) {
dock_slot[i]->show();
- else
+ } else {
dock_slot[i]->hide();
+ }
}
for (int i = 0; i < vsplits.size(); i++) {
bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count();
- if (in_use)
+ if (in_use) {
vsplits[i]->show();
- else
+ } else {
vsplits[i]->hide();
+ }
}
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
-
if (dock_slot[i]->is_visible() && dock_slot[i]->get_tab_count()) {
dock_slot[i]->set_current_tab(0);
}
}
bottom_panel->show();
- if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible())
+ if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible()) {
right_hsplit->show();
- else
+ } else {
right_hsplit->hide();
+ }
}
}
void EditorNode::_dock_tab_changed(int p_tab) {
-
// update visibility but don't set current tab
if (!docks_visible) {
-
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
dock_slot[i]->hide();
}
@@ -4391,55 +4211,58 @@ void EditorNode::_dock_tab_changed(int p_tab) {
bottom_panel->hide();
} else {
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
-
- if (dock_slot[i]->get_tab_count())
+ if (dock_slot[i]->get_tab_count()) {
dock_slot[i]->show();
- else
+ } else {
dock_slot[i]->hide();
+ }
}
for (int i = 0; i < vsplits.size(); i++) {
bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count();
- if (in_use)
+ if (in_use) {
vsplits[i]->show();
- else
+ } else {
vsplits[i]->hide();
+ }
}
bottom_panel->show();
- if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible())
+ if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible()) {
right_hsplit->show();
- else
+ } else {
right_hsplit->hide();
+ }
}
}
void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String &p_section) {
-
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
-
- if (!p_layout->has_section_key(p_section, "dock_" + itos(i + 1)))
+ if (!p_layout->has_section_key(p_section, "dock_" + itos(i + 1))) {
continue;
+ }
Vector<String> names = String(p_layout->get_value(p_section, "dock_" + itos(i + 1))).split(",");
for (int j = 0; j < names.size(); j++) {
-
String name = names[j];
//find it, in a horribly inefficient way
int atidx = -1;
Control *node = nullptr;
for (int k = 0; k < DOCK_SLOT_MAX; k++) {
- if (!dock_slot[k]->has_node(name))
+ if (!dock_slot[k]->has_node(name)) {
continue;
+ }
node = Object::cast_to<Control>(dock_slot[k]->get_node(name));
- if (!node)
+ if (!node) {
continue;
+ }
atidx = k;
break;
}
- if (atidx == -1) //well, it's not anywhere
+ if (atidx == -1) { //well, it's not anywhere
continue;
+ }
if (atidx == i) {
node->raise();
@@ -4472,36 +4295,38 @@ void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String
}
for (int i = 0; i < vsplits.size(); i++) {
-
- if (!p_layout->has_section_key(p_section, "dock_split_" + itos(i + 1)))
+ if (!p_layout->has_section_key(p_section, "dock_split_" + itos(i + 1))) {
continue;
+ }
int ofs = p_layout->get_value(p_section, "dock_split_" + itos(i + 1));
vsplits[i]->set_split_offset(ofs);
}
for (int i = 0; i < hsplits.size(); i++) {
- if (!p_layout->has_section_key(p_section, "dock_hsplit_" + itos(i + 1)))
+ if (!p_layout->has_section_key(p_section, "dock_hsplit_" + itos(i + 1))) {
continue;
+ }
int ofs = p_layout->get_value(p_section, "dock_hsplit_" + itos(i + 1));
hsplits[i]->set_split_offset(ofs);
}
for (int i = 0; i < vsplits.size(); i++) {
bool in_use = dock_slot[i * 2 + 0]->get_tab_count() || dock_slot[i * 2 + 1]->get_tab_count();
- if (in_use)
+ if (in_use) {
vsplits[i]->show();
- else
+ } else {
vsplits[i]->hide();
+ }
}
- if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible())
+ if (right_l_vsplit->is_visible() || right_r_vsplit->is_visible()) {
right_hsplit->show();
- else
+ } else {
right_hsplit->hide();
+ }
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
-
if (dock_slot[i]->is_visible() && dock_slot[i]->get_tab_count()) {
dock_slot[i]->set_current_tab(0);
}
@@ -4550,7 +4375,6 @@ bool EditorNode::ensure_main_scene(bool p_from_native) {
String main_scene = GLOBAL_DEF("application/run/main_scene", "");
if (main_scene == "") {
-
current_option = -1;
pick_main_scene->set_text(TTR("No main scene has ever been defined, select one?\nYou can change it later in \"Project Settings\" under the 'application' category."));
pick_main_scene->popup_centered();
@@ -4558,7 +4382,6 @@ bool EditorNode::ensure_main_scene(bool p_from_native) {
}
if (!FileAccess::exists(main_scene)) {
-
current_option = -1;
pick_main_scene->set_text(vformat(TTR("Selected scene '%s' does not exist, select a valid one?\nYou can change it later in \"Project Settings\" under the 'application' category."), main_scene));
pick_main_scene->popup_centered();
@@ -4566,7 +4389,6 @@ bool EditorNode::ensure_main_scene(bool p_from_native) {
}
if (ResourceLoader::get_resource_type(main_scene) != "PackedScene") {
-
current_option = -1;
pick_main_scene->set_text(vformat(TTR("Selected scene '%s' is not a scene file, select a valid one?\nYou can change it later in \"Project Settings\" under the 'application' category."), main_scene));
pick_main_scene->popup_centered();
@@ -4594,7 +4416,6 @@ void EditorNode::set_current_tab(int p_tab) {
}
void EditorNode::_update_layouts_menu() {
-
editor_layouts->clear();
overridden_default_layout = -1;
@@ -4615,7 +4436,6 @@ void EditorNode::_update_layouts_menu() {
config.ptr()->get_sections(&layouts);
for (List<String>::Element *E = layouts.front(); E; E = E->next()) {
-
String layout = E->get();
if (layout == TTR("Default")) {
@@ -4628,11 +4448,8 @@ void EditorNode::_update_layouts_menu() {
}
void EditorNode::_layout_menu_option(int p_id) {
-
switch (p_id) {
-
case SETTINGS_LAYOUT_SAVE: {
-
current_option = p_id;
layout_dialog->set_title(TTR("Save Layout"));
layout_dialog->get_ok()->set_text(TTR("Save"));
@@ -4640,7 +4457,6 @@ void EditorNode::_layout_menu_option(int p_id) {
layout_dialog->set_name_line_enabled(true);
} break;
case SETTINGS_LAYOUT_DELETE: {
-
current_option = p_id;
layout_dialog->set_title(TTR("Delete Layout"));
layout_dialog->get_ok()->set_text(TTR("Delete"));
@@ -4648,12 +4464,10 @@ void EditorNode::_layout_menu_option(int p_id) {
layout_dialog->set_name_line_enabled(false);
} break;
case SETTINGS_LAYOUT_DEFAULT: {
-
_load_docks_from_config(default_layout, "docks");
_save_docks();
} break;
default: {
-
Ref<ConfigFile> config;
config.instance();
Error err = config->load(EditorSettings::get_singleton()->get_editor_layouts_config());
@@ -4668,10 +4482,10 @@ void EditorNode::_layout_menu_option(int p_id) {
}
void EditorNode::_scene_tab_script_edited(int p_tab) {
-
Ref<Script> script = editor_data.get_scene_root_script(p_tab);
- if (script.is_valid())
+ if (script.is_valid()) {
inspector_dock->edit_resource(script);
+ }
}
void EditorNode::_scene_tab_closed(int p_tab, int option) {
@@ -4722,7 +4536,6 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
Ref<InputEventMouseButton> mb = p_input;
if (mb.is_valid()) {
-
if (scene_tabs->get_hovered_tab() >= 0) {
if (mb->get_button_index() == BUTTON_MIDDLE && mb->is_pressed()) {
_scene_tab_closed(scene_tabs->get_hovered_tab());
@@ -4733,7 +4546,6 @@ void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
}
}
if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
-
// context menu
scene_tabs_context_menu->clear();
scene_tabs_context_menu->set_size(Size2(1, 1));
@@ -4790,8 +4602,9 @@ void EditorNode::_scene_tab_changed(int p_tab) {
bool unsaved = (saved_version != editor_data.get_undo_redo().get_version());
- if (p_tab == editor_data.get_edited_scene())
+ if (p_tab == editor_data.get_edited_scene()) {
return; //pointless
+ }
uint64_t next_scene_version = editor_data.get_scene_version(p_tab);
@@ -4807,7 +4620,6 @@ void EditorNode::_scene_tab_changed(int p_tab) {
}
ToolButton *EditorNode::add_bottom_panel_item(String p_text, Control *p_item) {
-
ToolButton *tb = memnew(ToolButton);
tb->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch), varray(bottom_panel_items.size()));
tb->set_text(p_text);
@@ -4828,19 +4640,17 @@ ToolButton *EditorNode::add_bottom_panel_item(String p_text, Control *p_item) {
}
bool EditorNode::are_bottom_panels_hidden() const {
-
for (int i = 0; i < bottom_panel_items.size(); i++) {
- if (bottom_panel_items[i].button->is_pressed())
+ if (bottom_panel_items[i].button->is_pressed()) {
return false;
+ }
}
return true;
}
void EditorNode::hide_bottom_panel() {
-
for (int i = 0; i < bottom_panel_items.size(); i++) {
-
if (bottom_panel_items[i].control->is_visible()) {
_bottom_panel_switch(false, i);
break;
@@ -4849,9 +4659,7 @@ void EditorNode::hide_bottom_panel() {
}
void EditorNode::make_bottom_panel_item_visible(Control *p_item) {
-
for (int i = 0; i < bottom_panel_items.size(); i++) {
-
if (bottom_panel_items[i].control == p_item) {
_bottom_panel_switch(true, i);
break;
@@ -4860,9 +4668,7 @@ void EditorNode::make_bottom_panel_item_visible(Control *p_item) {
}
void EditorNode::raise_bottom_panel_item(Control *p_item) {
-
for (int i = 0; i < bottom_panel_items.size(); i++) {
-
if (bottom_panel_items[i].control == p_item) {
bottom_panel_items[i].button->raise();
SWAP(bottom_panel_items.write[i], bottom_panel_items.write[bottom_panel_items.size() - 1]);
@@ -4877,9 +4683,7 @@ void EditorNode::raise_bottom_panel_item(Control *p_item) {
}
void EditorNode::remove_bottom_panel_item(Control *p_item) {
-
for (int i = 0; i < bottom_panel_items.size(); i++) {
-
if (bottom_panel_items[i].control == p_item) {
if (p_item->is_visible_in_tree()) {
_bottom_panel_switch(false, i);
@@ -4899,7 +4703,6 @@ void EditorNode::remove_bottom_panel_item(Control *p_item) {
}
void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) {
-
ERR_FAIL_INDEX(p_idx, bottom_panel_items.size());
if (bottom_panel_items[p_idx].control->is_visible() == p_enable) {
@@ -4908,7 +4711,6 @@ void EditorNode::_bottom_panel_switch(bool p_enable, int p_idx) {
if (p_enable) {
for (int i = 0; i < bottom_panel_items.size(); i++) {
-
bottom_panel_items[i].button->set_pressed(i == p_idx);
bottom_panel_items[i].control->set_visible(i == p_idx);
}
@@ -4947,7 +4749,6 @@ bool EditorNode::get_docks_visible() const {
}
void EditorNode::_toggle_distraction_free_mode() {
-
if (EditorSettings::get_singleton()->get("interface/editor/separate_distraction_mode")) {
int screen = -1;
for (int i = 0; i < editor_table.size(); i++) {
@@ -4970,7 +4771,6 @@ void EditorNode::_toggle_distraction_free_mode() {
}
void EditorNode::set_distraction_free_mode(bool p_enter) {
-
distraction_free->set_pressed(p_enter);
if (p_enter) {
@@ -4993,7 +4793,6 @@ void EditorNode::add_control_to_dock(DockSlot p_slot, Control *p_control) {
}
void EditorNode::remove_control_from_dock(Control *p_control) {
-
Control *dock = nullptr;
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
if (p_control->get_parent() == dock_slot[i]) {
@@ -5009,7 +4808,6 @@ void EditorNode::remove_control_from_dock(Control *p_control) {
}
Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) {
-
Control *drag_control = memnew(Control);
TextureRect *drag_preview = memnew(TextureRect);
Label *label = memnew(Label);
@@ -5125,8 +4923,9 @@ void EditorNode::add_tool_submenu_item(const String &p_name, PopupMenu *p_submen
void EditorNode::remove_tool_menu_item(const String &p_name) {
for (int i = 0; i < tool_menu->get_item_count(); i++) {
- if (tool_menu->get_item_id(i) != TOOLS_CUSTOM)
+ if (tool_menu->get_item_id(i) != TOOLS_CUSTOM) {
continue;
+ }
if (tool_menu->get_item_text(i) == p_name) {
if (tool_menu->get_item_submenu(i) != "") {
@@ -5158,7 +4957,6 @@ void EditorNode::_global_menu_new_window(const Variant &p_tag) {
}
void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) {
-
String to_path = ProjectSettings::get_singleton()->globalize_path(get_filesystem_dock()->get_selected_path());
_add_dropped_files_recursive(p_files, to_path);
@@ -5167,17 +4965,14 @@ void EditorNode::_dropped_files(const Vector<String> &p_files, int p_screen) {
}
void EditorNode::_add_dropped_files_recursive(const Vector<String> &p_files, String to_path) {
-
DirAccessRef dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
Vector<String> just_copy = String("ttf,otf").split(",");
for (int i = 0; i < p_files.size(); i++) {
-
String from = p_files[i];
String to = to_path.plus_file(from.get_file());
if (dir->dir_exists(from)) {
-
Vector<String> sub_files;
DirAccessRef sub_dir = DirAccess::open(from);
@@ -5210,19 +5005,16 @@ void EditorNode::_add_dropped_files_recursive(const Vector<String> &p_files, Str
}
void EditorNode::_file_access_close_error_notify(const String &p_str) {
-
add_io_error("Unable to write to file '" + p_str + "', file in use, locked or lacking permissions.");
}
void EditorNode::reload_scene(const String &p_path) {
-
//first of all, reload internal textures, materials, meshes, etc. as they might have changed on disk
List<Ref<Resource>> cached;
ResourceCache::get_cached_resources(&cached);
List<Ref<Resource>> to_clear; //clear internal resources from previous scene from being used
for (List<Ref<Resource>>::Element *E = cached.front(); E; E = E->next()) {
-
if (E->get()->get_path().begins_with(p_path + "::")) { //subresources of existing scene
to_clear.push_back(E->get());
}
@@ -5236,7 +5028,6 @@ void EditorNode::reload_scene(const String &p_path) {
int scene_idx = -1;
for (int i = 0; i < editor_data.get_edited_scene_count(); i++) {
-
if (editor_data.get_scene_path(i) == p_path) {
scene_idx = i;
break;
@@ -5275,7 +5066,6 @@ void EditorNode::reload_scene(const String &p_path) {
int EditorNode::plugin_init_callback_count = 0;
void EditorNode::add_plugin_init_callback(EditorPluginInitializeCallback p_callback) {
-
ERR_FAIL_COND(plugin_init_callback_count == MAX_INIT_CALLBACKS);
plugin_init_callbacks[plugin_init_callback_count++] = p_callback;
@@ -5286,7 +5076,6 @@ EditorPluginInitializeCallback EditorNode::plugin_init_callbacks[EditorNode::MAX
int EditorNode::build_callback_count = 0;
void EditorNode::add_build_callback(EditorBuildCallback p_callback) {
-
ERR_FAIL_COND(build_callback_count == MAX_INIT_CALLBACKS);
build_callbacks[build_callback_count++] = p_callback;
@@ -5295,7 +5084,6 @@ void EditorNode::add_build_callback(EditorBuildCallback p_callback) {
EditorBuildCallback EditorNode::build_callbacks[EditorNode::MAX_BUILD_CALLBACKS];
bool EditorNode::call_build() {
-
bool builds_successful = true;
for (int i = 0; i < build_callback_count && builds_successful; i++) {
@@ -5314,13 +5102,11 @@ bool EditorNode::call_build() {
}
void EditorNode::_inherit_imported(const String &p_action) {
-
open_imported->hide();
load_scene(open_import_request, true, true);
}
void EditorNode::_open_imported() {
-
load_scene(open_import_request, true, false, true, true);
}
@@ -5340,7 +5126,6 @@ bool EditorNode::is_editor_dimmed() const {
}
void EditorNode::open_export_template_manager() {
-
export_template_manager->popup_manager();
}
@@ -5353,7 +5138,6 @@ void EditorNode::remove_resource_conversion_plugin(const Ref<EditorResourceConve
}
Vector<Ref<EditorResourceConversionPlugin>> EditorNode::find_resource_conversion_plugin(const Ref<Resource> &p_for_resource) {
-
Vector<Ref<EditorResourceConversionPlugin>> ret;
for (int i = 0; i < resource_conversion_plugins.size(); i++) {
@@ -5366,12 +5150,10 @@ Vector<Ref<EditorResourceConversionPlugin>> EditorNode::find_resource_conversion
}
void EditorNode::_bottom_panel_raise_toggled(bool p_pressed) {
-
top_split->set_visible(!p_pressed);
}
void EditorNode::_update_video_driver_color() {
-
// TODO: Probably should de-hardcode this and add to editor settings.
if (video_driver->get_text() == "GLES2") {
video_driver->add_theme_color_override("font_color", Color::hex(0x5586a4ff));
@@ -5381,7 +5163,6 @@ void EditorNode::_update_video_driver_color() {
}
void EditorNode::_video_driver_selected(int p_which) {
-
String driver = video_driver->get_item_metadata(p_which);
String current = ""; //OS::get_singleton()->get_video_driver_name(OS::get_singleton()->get_current_video_driver());
@@ -5405,33 +5186,30 @@ void EditorNode::_resource_saved(RES p_resource, const String &p_path) {
}
void EditorNode::_resource_loaded(RES p_resource, const String &p_path) {
-
singleton->editor_folding.load_resource_folding(p_resource, p_path);
}
void EditorNode::_feature_profile_changed() {
-
Ref<EditorFeatureProfile> profile = feature_profile_manager->get_current_profile();
TabContainer *import_tabs = cast_to<TabContainer>(import_dock->get_parent());
TabContainer *node_tabs = cast_to<TabContainer>(node_dock->get_parent());
TabContainer *fs_tabs = cast_to<TabContainer>(filesystem_dock->get_parent());
if (profile.is_valid()) {
-
import_tabs->set_tab_hidden(import_dock->get_index(), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_IMPORT_DOCK));
node_tabs->set_tab_hidden(node_dock->get_index(), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_NODE_DOCK));
fs_tabs->set_tab_hidden(filesystem_dock->get_index(), profile->is_feature_disabled(EditorFeatureProfile::FEATURE_FILESYSTEM_DOCK));
main_editor_buttons[EDITOR_3D]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D));
main_editor_buttons[EDITOR_SCRIPT]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT));
- if (StreamPeerSSL::is_available())
+ if (StreamPeerSSL::is_available()) {
main_editor_buttons[EDITOR_ASSETLIB]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB));
+ }
if ((profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D) && singleton->main_editor_buttons[EDITOR_3D]->is_pressed()) ||
(profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT) && singleton->main_editor_buttons[EDITOR_SCRIPT]->is_pressed()) ||
(StreamPeerSSL::is_available() && profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB) && singleton->main_editor_buttons[EDITOR_ASSETLIB]->is_pressed())) {
_editor_select(EDITOR_2D);
}
} else {
-
import_tabs->set_tab_hidden(import_dock->get_index(), false);
node_tabs->set_tab_hidden(node_dock->get_index(), false);
fs_tabs->set_tab_hidden(filesystem_dock->get_index(), false);
@@ -5440,15 +5218,15 @@ void EditorNode::_feature_profile_changed() {
filesystem_dock->set_visible(true);
main_editor_buttons[EDITOR_3D]->set_visible(true);
main_editor_buttons[EDITOR_SCRIPT]->set_visible(true);
- if (StreamPeerSSL::is_available())
+ if (StreamPeerSSL::is_available()) {
main_editor_buttons[EDITOR_ASSETLIB]->set_visible(true);
+ }
}
_update_dock_slots_visibility();
}
void EditorNode::_bind_methods() {
-
ClassDB::bind_method("_editor_select", &EditorNode::_editor_select);
ClassDB::bind_method("_node_renamed", &EditorNode::_node_renamed);
ClassDB::bind_method("edit_node", &EditorNode::edit_node);
@@ -5492,7 +5270,6 @@ void EditorNode::_bind_methods() {
}
static Node *_resource_get_edited_scene() {
-
return EditorNode::get_singleton()->get_edited_scene();
}
@@ -5502,7 +5279,6 @@ void EditorNode::_print_handler(void *p_this, const String &p_string, bool p_err
}
static void _execute_thread(void *p_ud) {
-
EditorNode::ExecuteThreadArgs *eta = (EditorNode::ExecuteThreadArgs *)p_ud;
Error err = OS::get_singleton()->execute(eta->path, eta->args, true, nullptr, &eta->output, &eta->exitcode, true, &eta->execute_output_mutex);
print_verbose("Thread exit status: " + itos(eta->exitcode));
@@ -5514,7 +5290,6 @@ static void _execute_thread(void *p_ud) {
}
int EditorNode::execute_and_show_output(const String &p_title, const String &p_path, const List<String> &p_arguments, bool p_close_on_ok, bool p_close_on_errors) {
-
execute_output_dialog->set_title(p_title);
execute_output_dialog->get_ok()->set_disabled(true);
execute_outputs->clear();
@@ -5563,8 +5338,7 @@ int EditorNode::execute_and_show_output(const String &p_title, const String &p_p
}
EditorNode::EditorNode() {
-
- InputFilter::get_singleton()->set_use_accumulated_input(true);
+ Input::get_singleton()->set_use_accumulated_input(true);
Resource::_get_local_scene_func = _resource_get_edited_scene;
RenderingServer::get_singleton()->set_debug_generate_wireframes(true);
@@ -5580,10 +5354,9 @@ EditorNode::EditorNode() {
ResourceLoader::clear_translation_remaps(); //no remaps using during editor
ResourceLoader::clear_path_remaps();
- InputFilter *id = InputFilter::get_singleton();
+ Input *id = Input::get_singleton();
if (id) {
-
bool found_touchscreen = false;
for (int i = 0; i < DisplayServer::get_singleton()->get_screen_count(); i++) {
if (DisplayServer::get_singleton()->screen_is_touchscreen(i)) {
@@ -5591,7 +5364,7 @@ EditorNode::EditorNode() {
}
}
- if (!found_touchscreen && InputFilter::get_singleton()) {
+ if (!found_touchscreen && Input::get_singleton()) {
//only if no touchscreen ui hint, set emulation
id->set_emulate_touch_from_mouse(false); //just disable just in case
}
@@ -5612,8 +5385,9 @@ EditorNode::EditorNode() {
TranslationServer::get_singleton()->set_enabled(false);
// load settings
- if (!EditorSettings::get_singleton())
+ if (!EditorSettings::get_singleton()) {
EditorSettings::create();
+ }
FileAccess::set_backup_save(EDITOR_GET("filesystem/on_save/safe_save_on_backup_then_rename"));
@@ -5677,7 +5451,7 @@ EditorNode::EditorNode() {
import_texture.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_texture);
- /* Ref<ResourceImporterLayeredTexture> import_cubemap;
+ Ref<ResourceImporterLayeredTexture> import_cubemap;
import_cubemap.instance();
import_cubemap->set_mode(ResourceImporterLayeredTexture::MODE_CUBEMAP);
ResourceFormatImporter::get_singleton()->add_importer(import_cubemap);
@@ -5691,7 +5465,12 @@ EditorNode::EditorNode() {
import_cubemap_array.instance();
import_cubemap_array->set_mode(ResourceImporterLayeredTexture::MODE_CUBEMAP_ARRAY);
ResourceFormatImporter::get_singleton()->add_importer(import_cubemap_array);
-*/
+
+ /*Ref<ResourceImporterLayeredTexture> import_3d;
+ import_3d.instance();
+ import_3d->set_mode(ResourceImporterLayeredTexture::MODE_3D);
+ ResourceFormatImporter::get_singleton()->add_importer(import_3d);*/
+
Ref<ResourceImporterImage> import_image;
import_image.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_image);
@@ -5716,6 +5495,10 @@ EditorNode::EditorNode() {
import_obj.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_obj);
+ Ref<ResourceImporterShaderFile> import_shader_file;
+ import_shader_file.instance();
+ ResourceFormatImporter::get_singleton()->add_importer(import_shader_file);
+
Ref<ResourceImporterScene> import_scene;
import_scene.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_scene);
@@ -6152,7 +5935,7 @@ EditorNode::EditorNode() {
p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_Z), EDIT_REDO, true);
p->add_separator();
- p->add_shortcut(ED_SHORTCUT("editor/revert_scene", TTR("Revert Scene")), EDIT_REVERT);
+ p->add_shortcut(ED_SHORTCUT("editor/reload_saved_scene", TTR("Reload Saved Scene")), EDIT_RELOAD_SAVED_SCENE);
p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_W), FILE_CLOSE);
recent_scenes = memnew(PopupMenu);
@@ -6231,8 +6014,11 @@ EditorNode::EditorNode() {
left_menu_hb->add_child(settings_menu);
p = settings_menu->get_popup();
-
+#ifdef OSX_ENABLED
+ p->add_shortcut(ED_SHORTCUT("editor/editor_settings", TTR("Editor Settings..."), KEY_MASK_CMD + KEY_COMMA), SETTINGS_PREFERENCES);
+#else
p->add_shortcut(ED_SHORTCUT("editor/editor_settings", TTR("Editor Settings...")), SETTINGS_PREFERENCES);
+#endif
p->add_separator();
editor_layouts = memnew(PopupMenu);
@@ -6334,7 +6120,7 @@ EditorNode::EditorNode() {
run_native = memnew(EditorRunNative);
play_hb->add_child(run_native);
- run_native->connect("native_run", callable_mp(this, &EditorNode::_menu_option), varray(RUN_PLAY_NATIVE));
+ run_native->connect("native_run", callable_mp(this, &EditorNode::_run_native));
play_scene_button = memnew(ToolButton);
play_hb->add_child(play_scene_button);
@@ -6476,8 +6262,9 @@ EditorNode::EditorNode() {
default_layout->set_value(docks_section, "dock_4", "FileSystem");
default_layout->set_value(docks_section, "dock_5", "Inspector,Node");
- for (int i = 0; i < vsplits.size(); i++)
+ for (int i = 0; i < vsplits.size(); i++) {
default_layout->set_value(docks_section, "dock_split_" + itos(i + 1), 0);
+ }
default_layout->set_value(docks_section, "dock_hsplit_1", 0);
default_layout->set_value(docks_section, "dock_hsplit_2", 70 * EDSCALE);
default_layout->set_value(docks_section, "dock_hsplit_3", -70 * EDSCALE);
@@ -6633,6 +6420,7 @@ EditorNode::EditorNode() {
add_editor_plugin(VersionControlEditorPlugin::get_singleton());
add_editor_plugin(memnew(ShaderEditorPlugin(this)));
+ add_editor_plugin(memnew(ShaderFileEditorPlugin(this)));
add_editor_plugin(memnew(VisualShaderEditorPlugin(this)));
add_editor_plugin(memnew(Camera3DEditorPlugin(this)));
@@ -6657,7 +6445,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(SpriteFramesEditorPlugin(this)));
add_editor_plugin(memnew(TextureRegionEditorPlugin(this)));
add_editor_plugin(memnew(GIProbeEditorPlugin(this)));
- //add_editor_plugin(memnew(BakedLightmapEditorPlugin(this)));
+ add_editor_plugin(memnew(BakedLightmapEditorPlugin(this)));
add_editor_plugin(memnew(Path2DEditorPlugin(this)));
add_editor_plugin(memnew(Path3DEditorPlugin(this)));
add_editor_plugin(memnew(Line2DEditorPlugin(this)));
@@ -6668,6 +6456,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(CollisionShape2DEditorPlugin(this)));
add_editor_plugin(memnew(CurveEditorPlugin(this)));
add_editor_plugin(memnew(TextureEditorPlugin(this)));
+ add_editor_plugin(memnew(TextureLayeredEditorPlugin(this)));
add_editor_plugin(memnew(AudioStreamEditorPlugin(this)));
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
add_editor_plugin(memnew(Skeleton3DEditorPlugin(this)));
@@ -6676,8 +6465,9 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(MeshEditorPlugin(this)));
add_editor_plugin(memnew(MaterialEditorPlugin(this)));
- for (int i = 0; i < EditorPlugins::get_plugin_count(); i++)
+ for (int i = 0; i < EditorPlugins::get_plugin_count(); i++) {
add_editor_plugin(EditorPlugins::create(i, this));
+ }
for (int i = 0; i < plugin_init_callback_count; i++) {
plugin_init_callbacks[i]();
@@ -6797,8 +6587,9 @@ EditorNode::EditorNode() {
pick_main_scene->get_ok()->set_text(TTR("Select"));
pick_main_scene->connect("confirmed", callable_mp(this, &EditorNode::_menu_option), varray(SETTINGS_PICK_MAIN_SCENE));
- for (int i = 0; i < _init_callbacks.size(); i++)
+ for (int i = 0; i < _init_callbacks.size(); i++) {
_init_callbacks[i]();
+ }
editor_data.add_edited_scene(-1);
editor_data.set_edited_scene(0);
@@ -6844,7 +6635,6 @@ EditorNode::EditorNode() {
}
EditorNode::~EditorNode() {
-
EditorInspector::cleanup_plugins();
remove_print_handler(&print_handler);
@@ -6863,21 +6653,18 @@ EditorNode::~EditorNode() {
*/
void EditorPluginList::make_visible(bool p_visible) {
-
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->make_visible(p_visible);
}
}
void EditorPluginList::edit(Object *p_object) {
-
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->edit(p_object);
}
}
bool EditorPluginList::forward_gui_input(const Ref<InputEvent> &p_event) {
-
bool discard = false;
for (int i = 0; i < plugins_list.size(); i++) {
@@ -6906,28 +6693,24 @@ bool EditorPluginList::forward_spatial_gui_input(Camera3D *p_camera, const Ref<I
}
void EditorPluginList::forward_canvas_draw_over_viewport(Control *p_overlay) {
-
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->forward_canvas_draw_over_viewport(p_overlay);
}
}
void EditorPluginList::forward_canvas_force_draw_over_viewport(Control *p_overlay) {
-
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->forward_canvas_force_draw_over_viewport(p_overlay);
}
}
void EditorPluginList::forward_spatial_draw_over_viewport(Control *p_overlay) {
-
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->forward_spatial_draw_over_viewport(p_overlay);
}
}
void EditorPluginList::forward_spatial_force_draw_over_viewport(Control *p_overlay) {
-
for (int i = 0; i < plugins_list.size(); i++) {
plugins_list[i]->forward_spatial_force_draw_over_viewport(p_overlay);
}
diff --git a/editor/editor_node.h b/editor/editor_node.h
index c6f04b0749..dfe3d91c07 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -32,6 +32,7 @@
#define EDITOR_NODE_H
#include "editor/editor_data.h"
+#include "editor/editor_export.h"
#include "editor/editor_folding.h"
#include "editor/editor_run.h"
#include "editor/inspector_dock.h"
@@ -88,7 +89,6 @@ class Window;
class SubViewport;
class EditorNode : public Node {
-
GDCLASS(EditorNode, Node);
public:
@@ -152,7 +152,7 @@ private:
FILE_EXTERNAL_OPEN_SCENE,
EDIT_UNDO,
EDIT_REDO,
- EDIT_REVERT,
+ EDIT_RELOAD_SAVED_SCENE,
TOOLS_ORPHAN_RESOURCES,
TOOLS_CUSTOM,
RESOURCE_SAVE,
@@ -161,7 +161,6 @@ private:
RUN_STOP,
RUN_PLAY_SCENE,
- RUN_PLAY_NATIVE,
RUN_PLAY_CUSTOM_SCENE,
RUN_SCENE_SETTINGS,
RUN_SETTINGS,
@@ -492,6 +491,7 @@ private:
void _quick_run();
void _run(bool p_current = false, const String &p_custom = "");
+ void _run_native(const Ref<EditorExportPreset> &p_preset);
void _save_optimized();
void _import_action(const String &p_action);
@@ -547,8 +547,9 @@ private:
static void _dependency_error_report(void *ud, const String &p_path, const String &p_dep, const String &p_type) {
EditorNode *en = (EditorNode *)ud;
- if (!en->dependency_errors.has(p_path))
+ if (!en->dependency_errors.has(p_path)) {
en->dependency_errors[p_path] = Set<String>();
+ }
en->dependency_errors[p_path].insert(p_dep + "::" + p_type);
}
@@ -801,10 +802,11 @@ public:
static void progress_end_task_bg(const String &p_task);
void save_scene_to_path(String p_file, bool p_with_preview = true) {
- if (p_with_preview)
+ if (p_with_preview) {
_save_scene_with_preview(p_file);
- else
+ } else {
_save_scene(p_file);
+ }
}
bool is_scene_in_use(const String &p_path);
@@ -867,7 +869,6 @@ public:
};
struct EditorProgress {
-
String task;
bool step(const String &p_state, int p_step = -1, bool p_force_refresh = true) { return EditorNode::progress_task_step(task, p_state, p_step, p_force_refresh); }
EditorProgress(const String &p_task, const String &p_label, int p_amount, bool p_can_cancel = false) {
@@ -908,7 +909,6 @@ public:
};
struct EditorProgressBG {
-
String task;
void step(int p_step = -1) { EditorNode::progress_task_step_bg(task, p_step); }
EditorProgressBG(const String &p_task, const String &p_label, int p_amount) {
diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp
index 804ad62bbb..c249974f99 100644
--- a/editor/editor_path.cpp
+++ b/editor/editor_path.cpp
@@ -34,25 +34,28 @@
#include "editor_scale.h"
void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) {
-
- if (p_depth > 8)
+ if (p_depth > 8) {
return;
+ }
List<PropertyInfo> pinfo;
p_obj->get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_EDITOR))
+ if (!(E->get().usage & PROPERTY_USAGE_EDITOR)) {
continue;
- if (E->get().hint != PROPERTY_HINT_RESOURCE_TYPE)
+ }
+ if (E->get().hint != PROPERTY_HINT_RESOURCE_TYPE) {
continue;
+ }
Variant value = p_obj->get(E->get().name);
- if (value.get_type() != Variant::OBJECT)
+ if (value.get_type() != Variant::OBJECT) {
continue;
+ }
Object *obj = value;
- if (!obj)
+ if (!obj) {
continue;
+ }
Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(obj);
@@ -66,10 +69,10 @@ void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) {
}
void EditorPath::_about_to_show() {
-
Object *obj = ObjectDB::get_instance(history->get_path_object(history->get_path_size() - 1));
- if (!obj)
+ if (!obj) {
return;
+ }
objects.clear();
get_popup()->clear();
@@ -83,37 +86,39 @@ void EditorPath::_about_to_show() {
}
void EditorPath::update_path() {
-
for (int i = 0; i < history->get_path_size(); i++) {
-
Object *obj = ObjectDB::get_instance(history->get_path_object(i));
- if (!obj)
+ if (!obj) {
continue;
+ }
Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(obj);
- if (icon.is_valid())
+ if (icon.is_valid()) {
set_icon(icon);
+ }
if (i == history->get_path_size() - 1) {
String name;
if (Object::cast_to<Resource>(obj)) {
-
Resource *r = Object::cast_to<Resource>(obj);
- if (r->get_path().is_resource_file())
+ if (r->get_path().is_resource_file()) {
name = r->get_path().get_file();
- else
+ } else {
name = r->get_name();
+ }
- if (name == "")
+ if (name == "") {
name = r->get_class();
- } else if (obj->is_class("EditorDebuggerRemoteObject"))
+ }
+ } else if (obj->is_class("EditorDebuggerRemoteObject")) {
name = obj->call("get_title");
- else if (Object::cast_to<Node>(obj))
+ } else if (Object::cast_to<Node>(obj)) {
name = Object::cast_to<Node>(obj)->get_name();
- else if (Object::cast_to<Resource>(obj) && Object::cast_to<Resource>(obj)->get_name() != "")
+ } else if (Object::cast_to<Resource>(obj) && Object::cast_to<Resource>(obj)->get_name() != "") {
name = Object::cast_to<Resource>(obj)->get_name();
- else
+ } else {
name = obj->get_class();
+ }
set_text(" " + name); // An extra space so the text is not too close of the icon.
set_tooltip(obj->get_class());
@@ -122,18 +127,17 @@ void EditorPath::update_path() {
}
void EditorPath::_id_pressed(int p_idx) {
-
ERR_FAIL_INDEX(p_idx, objects.size());
Object *obj = ObjectDB::get_instance(objects[p_idx]);
- if (!obj)
+ if (!obj) {
return;
+ }
EditorNode::get_singleton()->push_item(obj);
}
void EditorPath::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
update_path();
@@ -145,7 +149,6 @@ void EditorPath::_bind_methods() {
}
EditorPath::EditorPath(EditorHistory *p_history) {
-
history = p_history;
set_clip_text(true);
set_text_align(ALIGN_LEFT);
diff --git a/editor/editor_path.h b/editor/editor_path.h
index b0ffc487ac..01ba25ab69 100644
--- a/editor/editor_path.h
+++ b/editor/editor_path.h
@@ -35,7 +35,6 @@
#include "scene/gui/menu_button.h"
class EditorPath : public MenuButton {
-
GDCLASS(EditorPath, MenuButton);
EditorHistory *history;
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 746ebc8292..2365090f03 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -44,7 +44,6 @@
#include "servers/rendering_server.h"
Array EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_size) {
-
Vector<Ref<Mesh>> meshes;
for (int i = 0; i < p_meshes.size(); i++) {
@@ -61,7 +60,6 @@ Array EditorInterface::_make_mesh_previews(const Array &p_meshes, int p_preview_
}
Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh>> &p_meshes, Vector<Transform> *p_transforms, int p_preview_size) {
-
int size = p_preview_size;
RID scenario = RS::get_singleton()->scenario_create();
@@ -89,7 +87,6 @@ Vector<Ref<Texture2D>> EditorInterface::make_mesh_previews(const Vector<Ref<Mesh
Vector<Ref<Texture2D>> textures;
for (int i = 0; i < p_meshes.size(); i++) {
-
Ref<Mesh> mesh = p_meshes[i];
if (!mesh.is_valid()) {
textures.push_back(Ref<Texture2D>());
@@ -156,17 +153,14 @@ void EditorInterface::set_main_screen_editor(const String &p_name) {
}
Control *EditorInterface::get_editor_viewport() {
-
return EditorNode::get_singleton()->get_viewport();
}
void EditorInterface::edit_resource(const Ref<Resource> &p_resource) {
-
EditorNode::get_singleton()->edit_resource(p_resource);
}
void EditorInterface::open_scene_from_path(const String &scene_path) {
-
if (EditorNode::get_singleton()->is_changing_scene()) {
return;
}
@@ -175,7 +169,6 @@ void EditorInterface::open_scene_from_path(const String &scene_path) {
}
void EditorInterface::reload_scene_from_path(const String &scene_path) {
-
if (EditorNode::get_singleton()->is_changing_scene()) {
return;
}
@@ -188,14 +181,14 @@ Node *EditorInterface::get_edited_scene_root() {
}
Array EditorInterface::get_open_scenes() const {
-
Array ret;
Vector<EditorData::EditedScene> scenes = EditorNode::get_editor_data().get_edited_scenes();
int scns_amount = scenes.size();
for (int idx_scn = 0; idx_scn < scns_amount; idx_scn++) {
- if (scenes[idx_scn].root == nullptr)
+ if (scenes[idx_scn].root == nullptr) {
continue;
+ }
ret.push_back(scenes[idx_scn].root->get_filename());
}
return ret;
@@ -218,7 +211,6 @@ String EditorInterface::get_current_path() const {
}
void EditorInterface::inspect_object(Object *p_obj, const String &p_for_property) {
-
EditorNode::get_singleton()->push_item(p_obj, p_for_property);
}
@@ -243,7 +235,6 @@ EditorResourcePreview *EditorInterface::get_resource_previewer() {
}
Control *EditorInterface::get_base_control() {
-
return EditorNode::get_singleton()->get_gui_base();
}
@@ -260,17 +251,18 @@ EditorInspector *EditorInterface::get_inspector() const {
}
Error EditorInterface::save_scene() {
- if (!get_edited_scene_root())
+ if (!get_edited_scene_root()) {
return ERR_CANT_CREATE;
- if (get_edited_scene_root()->get_filename() == String())
+ }
+ if (get_edited_scene_root()->get_filename() == String()) {
return ERR_CANT_CREATE;
+ }
save_scene_as(get_edited_scene_root()->get_filename());
return OK;
}
void EditorInterface::save_scene_as(const String &p_scene, bool p_with_preview) {
-
EditorNode::get_singleton()->save_scene_to_path(p_scene, p_with_preview);
}
@@ -281,7 +273,6 @@ void EditorInterface::set_distraction_free_mode(bool p_enter) {
EditorInterface *EditorInterface::singleton = nullptr;
void EditorInterface::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("inspect_object", "object", "for_property"), &EditorInterface::inspect_object, DEFVAL(String()));
ClassDB::bind_method(D_METHOD("get_selection"), &EditorInterface::get_selection);
ClassDB::bind_method(D_METHOD("get_editor_settings"), &EditorInterface::get_editor_settings);
@@ -319,12 +310,10 @@ EditorInterface::EditorInterface() {
///////////////////////////////////////////
void EditorPlugin::add_custom_type(const String &p_type, const String &p_base, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon) {
-
EditorNode::get_editor_data().add_custom_type(p_type, p_base, p_script, p_icon);
}
void EditorPlugin::remove_custom_type(const String &p_type) {
-
EditorNode::get_editor_data().remove_custom_type(p_type);
}
@@ -342,19 +331,16 @@ ToolButton *EditorPlugin::add_control_to_bottom_panel(Control *p_control, const
}
void EditorPlugin::add_control_to_dock(DockSlot p_slot, Control *p_control) {
-
ERR_FAIL_NULL(p_control);
EditorNode::get_singleton()->add_control_to_dock(EditorNode::DockSlot(p_slot), p_control);
}
void EditorPlugin::remove_control_from_docks(Control *p_control) {
-
ERR_FAIL_NULL(p_control);
EditorNode::get_singleton()->remove_control_from_dock(p_control);
}
void EditorPlugin::remove_control_from_bottom_panel(Control *p_control) {
-
ERR_FAIL_NULL(p_control);
EditorNode::get_singleton()->remove_bottom_panel_item(p_control);
}
@@ -363,69 +349,56 @@ void EditorPlugin::add_control_to_container(CustomControlContainer p_location, C
ERR_FAIL_NULL(p_control);
switch (p_location) {
-
case CONTAINER_TOOLBAR: {
-
EditorNode::get_menu_hb()->add_child(p_control);
} break;
case CONTAINER_SPATIAL_EDITOR_MENU: {
-
Node3DEditor::get_singleton()->add_control_to_menu_panel(p_control);
} break;
case CONTAINER_SPATIAL_EDITOR_SIDE_LEFT: {
-
Node3DEditor::get_singleton()->get_palette_split()->add_child(p_control);
Node3DEditor::get_singleton()->get_palette_split()->move_child(p_control, 0);
} break;
case CONTAINER_SPATIAL_EDITOR_SIDE_RIGHT: {
-
Node3DEditor::get_singleton()->get_palette_split()->add_child(p_control);
Node3DEditor::get_singleton()->get_palette_split()->move_child(p_control, 1);
} break;
case CONTAINER_SPATIAL_EDITOR_BOTTOM: {
-
Node3DEditor::get_singleton()->get_shader_split()->add_child(p_control);
} break;
case CONTAINER_CANVAS_EDITOR_MENU: {
-
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(p_control);
} break;
case CONTAINER_CANVAS_EDITOR_SIDE_LEFT: {
-
CanvasItemEditor::get_singleton()->get_palette_split()->add_child(p_control);
CanvasItemEditor::get_singleton()->get_palette_split()->move_child(p_control, 0);
} break;
case CONTAINER_CANVAS_EDITOR_SIDE_RIGHT: {
-
CanvasItemEditor::get_singleton()->get_palette_split()->add_child(p_control);
CanvasItemEditor::get_singleton()->get_palette_split()->move_child(p_control, 1);
} break;
case CONTAINER_CANVAS_EDITOR_BOTTOM: {
-
CanvasItemEditor::get_singleton()->get_bottom_split()->add_child(p_control);
} break;
case CONTAINER_PROPERTY_EDITOR_BOTTOM: {
-
EditorNode::get_singleton()->get_inspector_dock_addon_area()->add_child(p_control);
} break;
case CONTAINER_PROJECT_SETTING_TAB_LEFT: {
-
ProjectSettingsEditor::get_singleton()->get_tabs()->add_child(p_control);
ProjectSettingsEditor::get_singleton()->get_tabs()->move_child(p_control, 0);
} break;
case CONTAINER_PROJECT_SETTING_TAB_RIGHT: {
-
ProjectSettingsEditor::get_singleton()->get_tabs()->add_child(p_control);
ProjectSettingsEditor::get_singleton()->get_tabs()->move_child(p_control, 1);
@@ -437,52 +410,42 @@ void EditorPlugin::remove_control_from_container(CustomControlContainer p_locati
ERR_FAIL_NULL(p_control);
switch (p_location) {
-
case CONTAINER_TOOLBAR: {
-
EditorNode::get_menu_hb()->remove_child(p_control);
} break;
case CONTAINER_SPATIAL_EDITOR_MENU: {
-
Node3DEditor::get_singleton()->remove_control_from_menu_panel(p_control);
} break;
case CONTAINER_SPATIAL_EDITOR_SIDE_LEFT:
case CONTAINER_SPATIAL_EDITOR_SIDE_RIGHT: {
-
Node3DEditor::get_singleton()->get_palette_split()->remove_child(p_control);
} break;
case CONTAINER_SPATIAL_EDITOR_BOTTOM: {
-
Node3DEditor::get_singleton()->get_shader_split()->remove_child(p_control);
} break;
case CONTAINER_CANVAS_EDITOR_MENU: {
-
CanvasItemEditor::get_singleton()->remove_control_from_menu_panel(p_control);
} break;
case CONTAINER_CANVAS_EDITOR_SIDE_LEFT:
case CONTAINER_CANVAS_EDITOR_SIDE_RIGHT: {
-
CanvasItemEditor::get_singleton()->get_palette_split()->remove_child(p_control);
} break;
case CONTAINER_CANVAS_EDITOR_BOTTOM: {
-
CanvasItemEditor::get_singleton()->get_bottom_split()->remove_child(p_control);
} break;
case CONTAINER_PROPERTY_EDITOR_BOTTOM: {
-
EditorNode::get_singleton()->get_inspector_dock_addon_area()->remove_child(p_control);
} break;
case CONTAINER_PROJECT_SETTING_TAB_LEFT:
case CONTAINER_PROJECT_SETTING_TAB_RIGHT: {
-
ProjectSettingsEditor::get_singleton()->get_tabs()->remove_child(p_control);
} break;
@@ -521,9 +484,9 @@ void EditorPlugin::notify_scene_changed(const Node *scn_root) {
}
void EditorPlugin::notify_main_screen_changed(const String &screen_name) {
-
- if (screen_name == last_main_screen_name)
+ if (screen_name == last_main_screen_name) {
return;
+ }
emit_signal("main_screen_changed", screen_name);
last_main_screen_name = screen_name;
@@ -538,7 +501,6 @@ void EditorPlugin::notify_resource_saved(const Ref<Resource> &p_resource) {
}
bool EditorPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
-
if (get_script_instance() && get_script_instance()->has_method("forward_canvas_gui_input")) {
return get_script_instance()->call("forward_canvas_gui_input", p_event);
}
@@ -546,14 +508,12 @@ bool EditorPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
}
void EditorPlugin::forward_canvas_draw_over_viewport(Control *p_overlay) {
-
if (get_script_instance() && get_script_instance()->has_method("forward_canvas_draw_over_viewport")) {
get_script_instance()->call("forward_canvas_draw_over_viewport", p_overlay);
}
}
void EditorPlugin::forward_canvas_force_draw_over_viewport(Control *p_overlay) {
-
if (get_script_instance() && get_script_instance()->has_method("forward_canvas_force_draw_over_viewport")) {
get_script_instance()->call("forward_canvas_force_draw_over_viewport", p_overlay);
}
@@ -561,7 +521,6 @@ void EditorPlugin::forward_canvas_force_draw_over_viewport(Control *p_overlay) {
// Updates the overlays of the 2D viewport or, if in 3D mode, of every 3D viewport.
int EditorPlugin::update_overlays() const {
-
if (Node3DEditor::get_singleton()->is_visible()) {
int count = 0;
for (uint32_t i = 0; i < Node3DEditor::VIEWPORTS_COUNT; i++) {
@@ -580,7 +539,6 @@ int EditorPlugin::update_overlays() const {
}
bool EditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
-
if (get_script_instance() && get_script_instance()->has_method("forward_spatial_gui_input")) {
return get_script_instance()->call("forward_spatial_gui_input", p_camera, p_event);
}
@@ -589,51 +547,48 @@ bool EditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<Input
}
void EditorPlugin::forward_spatial_draw_over_viewport(Control *p_overlay) {
-
if (get_script_instance() && get_script_instance()->has_method("forward_spatial_draw_over_viewport")) {
get_script_instance()->call("forward_spatial_draw_over_viewport", p_overlay);
}
}
void EditorPlugin::forward_spatial_force_draw_over_viewport(Control *p_overlay) {
-
if (get_script_instance() && get_script_instance()->has_method("forward_spatial_force_draw_over_viewport")) {
get_script_instance()->call("forward_spatial_force_draw_over_viewport", p_overlay);
}
}
-String EditorPlugin::get_name() const {
+String EditorPlugin::get_name() const {
if (get_script_instance() && get_script_instance()->has_method("get_plugin_name")) {
return get_script_instance()->call("get_plugin_name");
}
return String();
}
-const Ref<Texture2D> EditorPlugin::get_icon() const {
+const Ref<Texture2D> EditorPlugin::get_icon() const {
if (get_script_instance() && get_script_instance()->has_method("get_plugin_icon")) {
return get_script_instance()->call("get_plugin_icon");
}
return Ref<Texture2D>();
}
-bool EditorPlugin::has_main_screen() const {
+bool EditorPlugin::has_main_screen() const {
if (get_script_instance() && get_script_instance()->has_method("has_main_screen")) {
return get_script_instance()->call("has_main_screen");
}
return false;
}
-void EditorPlugin::make_visible(bool p_visible) {
+void EditorPlugin::make_visible(bool p_visible) {
if (get_script_instance() && get_script_instance()->has_method("make_visible")) {
get_script_instance()->call("make_visible", p_visible);
}
}
void EditorPlugin::edit(Object *p_object) {
-
if (get_script_instance() && get_script_instance()->has_method("edit")) {
if (p_object->is_class("Resource")) {
get_script_instance()->call("edit", Ref<Resource>(Object::cast_to<Resource>(p_object)));
@@ -644,15 +599,14 @@ void EditorPlugin::edit(Object *p_object) {
}
bool EditorPlugin::handles(Object *p_object) const {
-
if (get_script_instance() && get_script_instance()->has_method("handles")) {
return get_script_instance()->call("handles", p_object);
}
return false;
}
-Dictionary EditorPlugin::get_state() const {
+Dictionary EditorPlugin::get_state() const {
if (get_script_instance() && get_script_instance()->has_method("get_state")) {
return get_script_instance()->call("get_state");
}
@@ -661,14 +615,12 @@ Dictionary EditorPlugin::get_state() const {
}
void EditorPlugin::set_state(const Dictionary &p_state) {
-
if (get_script_instance() && get_script_instance()->has_method("set_state")) {
get_script_instance()->call("set_state", p_state);
}
}
void EditorPlugin::clear() {
-
if (get_script_instance() && get_script_instance()->has_method("clear")) {
get_script_instance()->call("clear");
}
@@ -676,7 +628,6 @@ void EditorPlugin::clear() {
// if editor references external resources/scenes, save them
void EditorPlugin::save_external_data() {
-
if (get_script_instance() && get_script_instance()->has_method("save_external_data")) {
get_script_instance()->call("save_external_data");
}
@@ -684,22 +635,21 @@ void EditorPlugin::save_external_data() {
// if changes are pending in editor, apply them
void EditorPlugin::apply_changes() {
-
if (get_script_instance() && get_script_instance()->has_method("apply_changes")) {
get_script_instance()->call("apply_changes");
}
}
void EditorPlugin::get_breakpoints(List<String> *p_breakpoints) {
-
if (get_script_instance() && get_script_instance()->has_method("get_breakpoints")) {
PackedStringArray arr = get_script_instance()->call("get_breakpoints");
- for (int i = 0; i < arr.size(); i++)
+ for (int i = 0; i < arr.size(); i++) {
p_breakpoints->push_back(arr[i]);
+ }
}
}
-bool EditorPlugin::get_remove_list(List<Node *> *p_list) {
+bool EditorPlugin::get_remove_list(List<Node *> *p_list) {
return false;
}
@@ -777,21 +727,18 @@ void EditorPlugin::disable_plugin() {
}
void EditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) {
-
if (get_script_instance() && get_script_instance()->has_method("set_window_layout")) {
get_script_instance()->call("set_window_layout", p_layout);
}
}
void EditorPlugin::get_window_layout(Ref<ConfigFile> p_layout) {
-
if (get_script_instance() && get_script_instance()->has_method("get_window_layout")) {
get_script_instance()->call("get_window_layout", p_layout);
}
}
bool EditorPlugin::build() {
-
if (get_script_instance() && get_script_instance()->has_method("build")) {
return get_script_instance()->call("build");
}
@@ -800,17 +747,14 @@ bool EditorPlugin::build() {
}
void EditorPlugin::queue_save_layout() const {
-
EditorNode::get_singleton()->save_layout();
}
void EditorPlugin::make_bottom_panel_item_visible(Control *p_item) {
-
EditorNode::get_singleton()->make_bottom_panel_item_visible(p_item);
}
void EditorPlugin::hide_bottom_panel() {
-
EditorNode::get_singleton()->hide_bottom_panel();
}
@@ -823,7 +767,6 @@ ScriptCreateDialog *EditorPlugin::get_script_create_dialog() {
}
void EditorPlugin::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_control_to_container", "container", "control"), &EditorPlugin::add_control_to_container);
ClassDB::bind_method(D_METHOD("add_control_to_bottom_panel", "control", "title"), &EditorPlugin::add_control_to_bottom_panel);
ClassDB::bind_method(D_METHOD("add_control_to_dock", "slot", "control"), &EditorPlugin::add_control_to_dock);
@@ -913,16 +856,6 @@ void EditorPlugin::_bind_methods() {
BIND_ENUM_CONSTANT(DOCK_SLOT_MAX);
}
-EditorPlugin::EditorPlugin() :
- undo_redo(nullptr),
- input_event_forwarding_always_enabled(false),
- force_draw_over_forwarding_enabled(false),
- last_main_screen_name("") {
-}
-
-EditorPlugin::~EditorPlugin() {
-}
-
EditorPluginCreateFunc EditorPlugins::creation_funcs[MAX_CREATE_FUNCS];
int EditorPlugins::creation_func_count = 0;
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 2ca96ceed2..2792c8bf19 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -110,15 +110,14 @@ public:
};
class EditorPlugin : public Node {
-
GDCLASS(EditorPlugin, Node);
friend class EditorData;
- UndoRedo *undo_redo;
+ UndoRedo *undo_redo = nullptr;
UndoRedo *_get_undo_redo() { return undo_redo; }
- bool input_event_forwarding_always_enabled;
- bool force_draw_over_forwarding_enabled;
+ bool input_event_forwarding_always_enabled = false;
+ bool force_draw_over_forwarding_enabled = false;
String last_main_screen_name;
@@ -242,8 +241,8 @@ public:
void enable_plugin();
void disable_plugin();
- EditorPlugin();
- virtual ~EditorPlugin();
+ EditorPlugin() {}
+ virtual ~EditorPlugin() {}
};
VARIANT_ENUM_CAST(EditorPlugin::CustomControlContainer);
@@ -252,7 +251,6 @@ VARIANT_ENUM_CAST(EditorPlugin::DockSlot);
typedef EditorPlugin *(*EditorPluginCreateFunc)(EditorNode *);
class EditorPlugins {
-
enum {
MAX_CREATE_FUNCS = 64
};
@@ -278,7 +276,6 @@ public:
}
static void add_create_func(EditorPluginCreateFunc p_func) {
-
ERR_FAIL_COND(creation_func_count >= MAX_CREATE_FUNCS);
creation_funcs[creation_func_count++] = p_func;
}
diff --git a/editor/editor_plugin_settings.cpp b/editor/editor_plugin_settings.cpp
index 62a76786ae..b5f1133a9e 100644
--- a/editor/editor_plugin_settings.cpp
+++ b/editor/editor_plugin_settings.cpp
@@ -39,7 +39,6 @@
#include "scene/gui/margin_container.h"
void EditorPluginSettings::_notification(int p_what) {
-
if (p_what == NOTIFICATION_WM_FOCUS_IN) {
update_plugins();
} else if (p_what == Node::NOTIFICATION_READY) {
@@ -49,7 +48,6 @@ void EditorPluginSettings::_notification(int p_what) {
}
void EditorPluginSettings::update_plugins() {
-
plugin_list->clear();
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
@@ -70,12 +68,10 @@ void EditorPluginSettings::update_plugins() {
Vector<String> plugins;
while (d != String()) {
-
bool dir = da->current_is_dir();
String path = "res://addons/" + d + "/plugin.cfg";
if (dir && FileAccess::exists(path)) {
-
plugins.push_back(d);
}
@@ -88,7 +84,6 @@ void EditorPluginSettings::update_plugins() {
plugins.sort();
for (int i = 0; i < plugins.size(); i++) {
-
Ref<ConfigFile> cf;
cf.instance();
String path = "res://addons/" + plugins[i] + "/plugin.cfg";
@@ -151,9 +146,9 @@ void EditorPluginSettings::update_plugins() {
}
void EditorPluginSettings::_plugin_activity_changed() {
-
- if (updating)
+ if (updating) {
return;
+ }
TreeItem *ti = plugin_list->get_edited();
ERR_FAIL_COND(!ti);
@@ -178,8 +173,9 @@ void EditorPluginSettings::_create_clicked() {
void EditorPluginSettings::_cell_button_pressed(Object *p_item, int p_column, int p_id) {
TreeItem *item = Object::cast_to<TreeItem>(p_item);
- if (!item)
+ if (!item) {
return;
+ }
if (p_id == BUTTON_PLUGIN_EDIT) {
if (p_column == 4) {
String dir = item->get_metadata(0);
@@ -193,7 +189,6 @@ void EditorPluginSettings::_bind_methods() {
}
EditorPluginSettings::EditorPluginSettings() {
-
plugin_config_dialog = memnew(PluginConfigDialog);
plugin_config_dialog->config("");
add_child(plugin_config_dialog);
diff --git a/editor/editor_plugin_settings.h b/editor/editor_plugin_settings.h
index 63a8395805..ceb00eb12f 100644
--- a/editor/editor_plugin_settings.h
+++ b/editor/editor_plugin_settings.h
@@ -38,7 +38,6 @@
#include "scene/gui/dialogs.h"
class EditorPluginSettings : public VBoxContainer {
-
GDCLASS(EditorPluginSettings, VBoxContainer);
enum {
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 5213d7ec15..81c4e48974 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -51,8 +51,9 @@ EditorPropertyNil::EditorPropertyNil() {
///////////////////// TEXT /////////////////////////
void EditorPropertyText::_text_entered(const String &p_string) {
- if (updating)
+ if (updating) {
return;
+ }
if (text->has_focus()) {
text->release_focus();
@@ -61,8 +62,9 @@ void EditorPropertyText::_text_entered(const String &p_string) {
}
void EditorPropertyText::_text_changed(const String &p_string) {
- if (updating)
+ if (updating) {
return;
+ }
if (string_name) {
emit_changed(get_edited_property(), StringName(p_string), "", true);
@@ -82,6 +84,7 @@ void EditorPropertyText::update_property() {
void EditorPropertyText::set_string_name(bool p_enabled) {
string_name = p_enabled;
}
+
void EditorPropertyText::set_placeholder(const String &p_string) {
text->set_placeholder(p_string);
}
@@ -112,7 +115,6 @@ void EditorPropertyMultilineText::_text_changed() {
}
void EditorPropertyMultilineText::_open_big_text() {
-
if (!big_text_dialog) {
big_text = memnew(TextEdit);
big_text->connect("text_changed", callable_mp(this, &EditorPropertyMultilineText::_big_text_changed));
@@ -172,9 +174,7 @@ EditorPropertyMultilineText::EditorPropertyMultilineText() {
///////////////////// TEXT ENUM /////////////////////////
void EditorPropertyTextEnum::_option_selected(int p_which) {
-
if (string_name) {
-
emit_changed(get_edited_property(), StringName(options->get_item_text(p_which)));
} else {
emit_changed(get_edited_property(), options->get_item_text(p_which));
@@ -182,7 +182,6 @@ void EditorPropertyTextEnum::_option_selected(int p_which) {
}
void EditorPropertyTextEnum::update_property() {
-
String which = get_edited_object()->get(get_edited_property());
for (int i = 0; i < options->get_item_count(); i++) {
String t = options->get_item_text(i);
@@ -213,15 +212,15 @@ EditorPropertyTextEnum::EditorPropertyTextEnum() {
add_focusable(options);
options->connect("item_selected", callable_mp(this, &EditorPropertyTextEnum::_option_selected));
}
+
///////////////////// PATH /////////////////////////
void EditorPropertyPath::_path_selected(const String &p_path) {
-
emit_changed(get_edited_property(), p_path);
update_property();
}
-void EditorPropertyPath::_path_pressed() {
+void EditorPropertyPath::_path_pressed() {
if (!dialog) {
dialog = memnew(EditorFileDialog);
dialog->connect("file_selected", callable_mp(this, &EditorPropertyPath::_path_selected));
@@ -257,33 +256,28 @@ void EditorPropertyPath::_path_pressed() {
}
void EditorPropertyPath::update_property() {
-
String full_path = get_edited_object()->get(get_edited_property());
path->set_text(full_path);
path->set_tooltip(full_path);
}
void EditorPropertyPath::setup(const Vector<String> &p_extensions, bool p_folder, bool p_global) {
-
extensions = p_extensions;
folder = p_folder;
global = p_global;
}
void EditorPropertyPath::set_save_mode() {
-
save_mode = true;
}
void EditorPropertyPath::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
path_edit->set_icon(get_theme_icon("Folder", "EditorIcons"));
}
}
void EditorPropertyPath::_path_focus_exited() {
-
_path_selected(path->get_text());
}
@@ -313,7 +307,6 @@ EditorPropertyPath::EditorPropertyPath() {
///////////////////// CLASS NAME /////////////////////////
void EditorPropertyClassName::setup(const String &p_base_type, const String &p_selected_type) {
-
base_type = p_base_type;
dialog->set_base_type(base_type);
selected_type = p_selected_type;
@@ -321,7 +314,6 @@ void EditorPropertyClassName::setup(const String &p_base_type, const String &p_s
}
void EditorPropertyClassName::update_property() {
-
String s = get_edited_object()->get(get_edited_property());
property->set_text(s);
selected_type = s;
@@ -356,13 +348,11 @@ EditorPropertyClassName::EditorPropertyClassName() {
///////////////////// MEMBER /////////////////////////
void EditorPropertyMember::_property_selected(const String &p_selected) {
-
emit_changed(get_edited_property(), p_selected);
update_property();
}
void EditorPropertyMember::_property_select() {
-
if (!selector) {
selector = memnew(PropertySelector);
selector->connect("selected", callable_mp(this, &EditorPropertyMember::_property_selected));
@@ -372,60 +362,57 @@ void EditorPropertyMember::_property_select() {
String current = get_edited_object()->get(get_edited_property());
if (hint == MEMBER_METHOD_OF_VARIANT_TYPE) {
-
Variant::Type type = Variant::NIL;
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
if (hint_text == Variant::get_type_name(Variant::Type(i))) {
type = Variant::Type(i);
}
}
- if (type != Variant::NIL)
+ if (type != Variant::NIL) {
selector->select_method_from_basic_type(type, current);
+ }
} else if (hint == MEMBER_METHOD_OF_BASE_TYPE) {
-
selector->select_method_from_base_type(hint_text, current);
} else if (hint == MEMBER_METHOD_OF_INSTANCE) {
-
Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
- if (instance)
+ if (instance) {
selector->select_method_from_instance(instance, current);
+ }
} else if (hint == MEMBER_METHOD_OF_SCRIPT) {
-
Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
if (Object::cast_to<Script>(obj)) {
selector->select_method_from_script(Object::cast_to<Script>(obj), current);
}
} else if (hint == MEMBER_PROPERTY_OF_VARIANT_TYPE) {
-
Variant::Type type = Variant::NIL;
String tname = hint_text;
- if (tname.find(".") != -1)
+ if (tname.find(".") != -1) {
tname = tname.get_slice(".", 0);
+ }
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
if (tname == Variant::get_type_name(Variant::Type(i))) {
type = Variant::Type(Variant::Type(i));
}
}
- if (type != Variant::NIL)
+ if (type != Variant::NIL) {
selector->select_property_from_basic_type(type, current);
+ }
} else if (hint == MEMBER_PROPERTY_OF_BASE_TYPE) {
-
selector->select_property_from_base_type(hint_text, current);
} else if (hint == MEMBER_PROPERTY_OF_INSTANCE) {
-
Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
- if (instance)
+ if (instance) {
selector->select_property_from_instance(instance, current);
+ }
} else if (hint == MEMBER_PROPERTY_OF_SCRIPT) {
-
Object *obj = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
if (Object::cast_to<Script>(obj)) {
selector->select_property_from_script(Object::cast_to<Script>(obj), current);
@@ -439,7 +426,6 @@ void EditorPropertyMember::setup(Type p_hint, const String &p_hint_text) {
}
void EditorPropertyMember::update_property() {
-
String full_path = get_edited_object()->get(get_edited_property());
property->set_text(full_path);
}
@@ -458,7 +444,6 @@ EditorPropertyMember::EditorPropertyMember() {
///////////////////// CHECK /////////////////////////
void EditorPropertyCheck::_checkbox_pressed() {
-
emit_changed(get_edited_property(), checkbox->is_pressed());
}
@@ -482,13 +467,11 @@ EditorPropertyCheck::EditorPropertyCheck() {
///////////////////// ENUM /////////////////////////
void EditorPropertyEnum::_option_selected(int p_which) {
-
int64_t val = options->get_item_metadata(p_which);
emit_changed(get_edited_property(), val);
}
void EditorPropertyEnum::update_property() {
-
int64_t which = get_edited_object()->get(get_edited_property());
for (int i = 0; i < options->get_item_count(); i++) {
@@ -500,12 +483,12 @@ void EditorPropertyEnum::update_property() {
}
void EditorPropertyEnum::setup(const Vector<String> &p_options) {
-
int64_t current_val = 0;
for (int i = 0; i < p_options.size(); i++) {
Vector<String> text_split = p_options[i].split(":");
- if (text_split.size() != 1)
+ if (text_split.size() != 1) {
current_val = text_split[1].to_int64();
+ }
options->add_item(text_split[0]);
options->set_item_metadata(i, current_val);
current_val += 1;
@@ -531,7 +514,6 @@ EditorPropertyEnum::EditorPropertyEnum() {
///////////////////// FLAGS /////////////////////////
void EditorPropertyFlags::_flag_toggled() {
-
uint32_t value = 0;
for (int i = 0; i < flags.size(); i++) {
if (flags[i]->is_pressed()) {
@@ -545,14 +527,12 @@ void EditorPropertyFlags::_flag_toggled() {
}
void EditorPropertyFlags::update_property() {
-
uint32_t value = get_edited_object()->get(get_edited_property());
for (int i = 0; i < flags.size(); i++) {
uint32_t val = 1;
val <<= flag_indices[i];
if (value & val) {
-
flags[i]->set_pressed(true);
} else {
flags[i]->set_pressed(false);
@@ -587,7 +567,6 @@ void EditorPropertyFlags::_bind_methods() {
}
EditorPropertyFlags::EditorPropertyFlags() {
-
vbox = memnew(VBoxContainer);
add_child(vbox);
}
@@ -636,7 +615,6 @@ public:
void _notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) {
-
Rect2 rect;
rect.size = get_size();
flag_rects.clear();
@@ -648,17 +626,17 @@ public:
Color color = get_theme_color("highlight_color", "Editor");
for (int i = 0; i < 2; i++) {
-
Point2 ofs(4, vofs);
- if (i == 1)
+ if (i == 1) {
ofs.y += bsize + 1;
+ }
ofs += rect.position;
for (int j = 0; j < 10; j++) {
-
Point2 o = ofs + Point2(j * (bsize + 1), 0);
- if (j >= 5)
+ if (j >= 5) {
o.x += 1;
+ }
uint32_t idx = i * 10 + j;
bool on = value & (1 << idx);
@@ -677,7 +655,6 @@ public:
}
static void _bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &EditorPropertyLayersGrid::_gui_input);
ADD_SIGNAL(MethodInfo("flag_changed", PropertyInfo(Variant::INT, "flag")));
}
@@ -687,19 +664,16 @@ public:
}
};
void EditorPropertyLayers::_grid_changed(uint32_t p_grid) {
-
emit_changed(get_edited_property(), p_grid);
}
void EditorPropertyLayers::update_property() {
-
uint32_t value = get_edited_object()->get(get_edited_property());
grid->set_flag(value);
}
void EditorPropertyLayers::setup(LayerType p_layer_type) {
-
String basename;
switch (p_layer_type) {
case LAYER_RENDER_2D:
@@ -738,7 +712,6 @@ void EditorPropertyLayers::setup(LayerType p_layer_type) {
}
void EditorPropertyLayers::_button_pressed() {
-
layers->clear();
for (int i = 0; i < 20; i++) {
if (i == 5 || i == 10 || i == 15) {
@@ -771,7 +744,6 @@ void EditorPropertyLayers::_bind_methods() {
}
EditorPropertyLayers::EditorPropertyLayers() {
-
HBoxContainer *hb = memnew(HBoxContainer);
add_child(hb);
grid = memnew(EditorPropertyLayersGrid);
@@ -794,8 +766,9 @@ EditorPropertyLayers::EditorPropertyLayers() {
///////////////////// INT /////////////////////////
void EditorPropertyInteger::_value_changed(int64_t val) {
- if (setting)
+ if (setting) {
return;
+ }
emit_changed(get_edited_property(), val);
}
@@ -835,14 +808,14 @@ EditorPropertyInteger::EditorPropertyInteger() {
///////////////////// OBJECT ID /////////////////////////
void EditorPropertyObjectID::_edit_pressed() {
-
emit_signal("object_id_selected", get_edited_property(), get_edited_object()->get(get_edited_property()));
}
void EditorPropertyObjectID::update_property() {
String type = base_type;
- if (type == "")
+ if (type == "") {
type = "Object";
+ }
ObjectID id = get_edited_object()->get(get_edited_property());
if (id.is_valid()) {
@@ -873,8 +846,9 @@ EditorPropertyObjectID::EditorPropertyObjectID() {
///////////////////// FLOAT /////////////////////////
void EditorPropertyFloat::_value_changed(double val) {
- if (setting)
+ if (setting) {
return;
+ }
emit_changed(get_edited_property(), val);
}
@@ -890,7 +864,6 @@ void EditorPropertyFloat::_bind_methods() {
}
void EditorPropertyFloat::setup(double p_min, double p_max, double p_step, bool p_no_slider, bool p_exp_range, bool p_greater, bool p_lesser) {
-
spin->set_min(p_min);
spin->set_max(p_max);
spin->set_step(p_step);
@@ -912,7 +885,6 @@ EditorPropertyFloat::EditorPropertyFloat() {
///////////////////// EASING /////////////////////////
void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) {
-
const Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid()) {
if (mb->is_doubleclick() && mb->get_button_index() == BUTTON_LEFT) {
@@ -938,17 +910,19 @@ void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) {
const Ref<InputEventMouseMotion> mm = p_ev;
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
-
float rel = mm->get_relative().x;
- if (rel == 0)
+ if (rel == 0) {
return;
+ }
- if (flip)
+ if (flip) {
rel = -rel;
+ }
float val = get_edited_object()->get(get_edited_property());
- if (val == 0)
+ if (val == 0) {
return;
+ }
bool sg = val < 0;
val = Math::absf(val);
@@ -957,8 +931,9 @@ void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) {
val += rel * 0.05;
val = Math::pow(2.0f, val);
- if (sg)
+ if (sg) {
val = -val;
+ }
emit_changed(get_edited_property(), val);
easing_draw->update();
@@ -966,7 +941,6 @@ void EditorPropertyEasing::_drag_easing(const Ref<InputEvent> &p_ev) {
}
void EditorPropertyEasing::_draw_easing() {
-
RID ci = easing_draw->get_canvas_item();
Size2 s = easing_draw->get_size();
@@ -987,7 +961,6 @@ void EditorPropertyEasing::_draw_easing() {
Vector<Point2> lines;
for (int i = 1; i <= points; i++) {
-
float ifl = i / float(points);
float iflp = (i - 1) / float(points);
@@ -1027,8 +1000,9 @@ void EditorPropertyEasing::_setup_spin() {
}
void EditorPropertyEasing::_spin_value_changed(double p_value) {
- if (setting)
+ if (setting) {
return;
+ }
// 0 is a singularity, but both positive and negative values
// are otherwise allowed. Enforce 0+ as workaround.
@@ -1047,13 +1021,11 @@ void EditorPropertyEasing::_spin_focus_exited() {
}
void EditorPropertyEasing::setup(bool p_full, bool p_flip) {
-
flip = p_flip;
full = p_full;
}
void EditorPropertyEasing::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_THEME_CHANGED:
case NOTIFICATION_ENTER_TREE: {
@@ -1075,7 +1047,6 @@ void EditorPropertyEasing::_bind_methods() {
}
EditorPropertyEasing::EditorPropertyEasing() {
-
easing_draw = memnew(Control);
easing_draw->connect("draw", callable_mp(this, &EditorPropertyEasing::_draw_easing));
easing_draw->connect("gui_input", callable_mp(this, &EditorPropertyEasing::_drag_easing));
@@ -1107,8 +1078,9 @@ EditorPropertyEasing::EditorPropertyEasing() {
///////////////////// VECTOR2 /////////////////////////
void EditorPropertyVector2::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
Vector2 v2;
v2.x = spin[0]->get_value();
@@ -1128,7 +1100,6 @@ void EditorPropertyVector2::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 2; i++) {
-
Color c = base;
c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
@@ -1189,8 +1160,9 @@ EditorPropertyVector2::EditorPropertyVector2(bool p_force_wide) {
///////////////////// RECT2 /////////////////////////
void EditorPropertyRect2::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
Rect2 r2;
r2.position.x = spin[0]->get_value();
@@ -1209,17 +1181,18 @@ void EditorPropertyRect2::update_property() {
spin[3]->set_value(val.size.y);
setting = false;
}
+
void EditorPropertyRect2::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 4; i++) {
-
Color c = base;
c.set_hsv(float(i % 2) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
}
}
}
+
void EditorPropertyRect2::_bind_methods() {
}
@@ -1235,7 +1208,6 @@ void EditorPropertyRect2::setup(double p_min, double p_max, double p_step, bool
}
EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) {
-
bool horizontal = !p_force_wide && bool(EDITOR_GET("interface/inspector/horizontal_vector_types_editing"));
BoxContainer *bc;
@@ -1274,8 +1246,9 @@ EditorPropertyRect2::EditorPropertyRect2(bool p_force_wide) {
///////////////////// VECTOR3 /////////////////////////
void EditorPropertyVector3::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
Vector3 v3;
v3.x = spin[0]->get_value();
@@ -1292,17 +1265,18 @@ void EditorPropertyVector3::update_property() {
spin[2]->set_value(val.z);
setting = false;
}
+
void EditorPropertyVector3::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 3; i++) {
-
Color c = base;
c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
}
}
}
+
void EditorPropertyVector3::_bind_methods() {
}
@@ -1356,8 +1330,9 @@ EditorPropertyVector3::EditorPropertyVector3(bool p_force_wide) {
///////////////////// VECTOR2i /////////////////////////
void EditorPropertyVector2i::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
Vector2i v2;
v2.x = spin[0]->get_value();
@@ -1377,7 +1352,6 @@ void EditorPropertyVector2i::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 2; i++) {
-
Color c = base;
c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
@@ -1438,8 +1412,9 @@ EditorPropertyVector2i::EditorPropertyVector2i(bool p_force_wide) {
///////////////////// RECT2 /////////////////////////
void EditorPropertyRect2i::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
Rect2i r2;
r2.position.x = spin[0]->get_value();
@@ -1458,17 +1433,18 @@ void EditorPropertyRect2i::update_property() {
spin[3]->set_value(val.size.y);
setting = false;
}
+
void EditorPropertyRect2i::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 4; i++) {
-
Color c = base;
c.set_hsv(float(i % 2) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
}
}
}
+
void EditorPropertyRect2i::_bind_methods() {
}
@@ -1484,7 +1460,6 @@ void EditorPropertyRect2i::setup(int p_min, int p_max, bool p_no_slider) {
}
EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) {
-
bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing");
BoxContainer *bc;
@@ -1523,8 +1498,9 @@ EditorPropertyRect2i::EditorPropertyRect2i(bool p_force_wide) {
///////////////////// VECTOR3 /////////////////////////
void EditorPropertyVector3i::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
Vector3i v3;
v3.x = spin[0]->get_value();
@@ -1541,17 +1517,18 @@ void EditorPropertyVector3i::update_property() {
spin[2]->set_value(val.z);
setting = false;
}
+
void EditorPropertyVector3i::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 3; i++) {
-
Color c = base;
c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
}
}
}
+
void EditorPropertyVector3i::_bind_methods() {
}
@@ -1604,8 +1581,9 @@ EditorPropertyVector3i::EditorPropertyVector3i(bool p_force_wide) {
///////////////////// PLANE /////////////////////////
void EditorPropertyPlane::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
Plane p;
p.normal.x = spin[0]->get_value();
@@ -1624,17 +1602,18 @@ void EditorPropertyPlane::update_property() {
spin[3]->set_value(val.d);
setting = false;
}
+
void EditorPropertyPlane::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 3; i++) {
-
Color c = base;
c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
}
}
}
+
void EditorPropertyPlane::_bind_methods() {
}
@@ -1650,7 +1629,6 @@ void EditorPropertyPlane::setup(double p_min, double p_max, double p_step, bool
}
EditorPropertyPlane::EditorPropertyPlane(bool p_force_wide) {
-
bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing");
BoxContainer *bc;
@@ -1689,8 +1667,9 @@ EditorPropertyPlane::EditorPropertyPlane(bool p_force_wide) {
///////////////////// QUAT /////////////////////////
void EditorPropertyQuat::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
Quat p;
p.x = spin[0]->get_value();
@@ -1709,17 +1688,18 @@ void EditorPropertyQuat::update_property() {
spin[3]->set_value(val.w);
setting = false;
}
+
void EditorPropertyQuat::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 3; i++) {
-
Color c = base;
c.set_hsv(float(i) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
}
}
}
+
void EditorPropertyQuat::_bind_methods() {
}
@@ -1770,8 +1750,9 @@ EditorPropertyQuat::EditorPropertyQuat() {
///////////////////// AABB /////////////////////////
void EditorPropertyAABB::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
AABB p;
p.position.x = spin[0]->get_value();
@@ -1796,17 +1777,18 @@ void EditorPropertyAABB::update_property() {
setting = false;
}
+
void EditorPropertyAABB::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 6; i++) {
-
Color c = base;
c.set_hsv(float(i % 3) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
}
}
}
+
void EditorPropertyAABB::_bind_methods() {
}
@@ -1844,8 +1826,9 @@ EditorPropertyAABB::EditorPropertyAABB() {
///////////////////// TRANSFORM2D /////////////////////////
void EditorPropertyTransform2D::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
Transform2D p;
p[0][0] = spin[0]->get_value();
@@ -1870,17 +1853,18 @@ void EditorPropertyTransform2D::update_property() {
setting = false;
}
+
void EditorPropertyTransform2D::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 6; i++) {
-
Color c = base;
c.set_hsv(float(i % 2) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
}
}
}
+
void EditorPropertyTransform2D::_bind_methods() {
}
@@ -1917,8 +1901,9 @@ EditorPropertyTransform2D::EditorPropertyTransform2D() {
///////////////////// BASIS /////////////////////////
void EditorPropertyBasis::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
Basis p;
p[0][0] = spin[0]->get_value();
@@ -1949,17 +1934,18 @@ void EditorPropertyBasis::update_property() {
setting = false;
}
+
void EditorPropertyBasis::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 9; i++) {
-
Color c = base;
c.set_hsv(float(i % 3) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
}
}
}
+
void EditorPropertyBasis::_bind_methods() {
}
@@ -1996,8 +1982,9 @@ EditorPropertyBasis::EditorPropertyBasis() {
///////////////////// TRANSFORM /////////////////////////
void EditorPropertyTransform::_value_changed(double val, const String &p_name) {
- if (setting)
+ if (setting) {
return;
+ }
Transform p;
p.basis[0][0] = spin[0]->get_value();
@@ -2034,17 +2021,18 @@ void EditorPropertyTransform::update_property() {
setting = false;
}
+
void EditorPropertyTransform::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Color base = get_theme_color("accent_color", "Editor");
for (int i = 0; i < 12; i++) {
-
Color c = base;
c.set_hsv(float(i % 3) / 3.0 + 0.05, c.get_s() * 0.75, c.get_v());
spin[i]->set_custom_label_color(true, c);
}
}
}
+
void EditorPropertyTransform::_bind_methods() {
}
@@ -2081,29 +2069,27 @@ EditorPropertyTransform::EditorPropertyTransform() {
////////////// COLOR PICKER //////////////////////
void EditorPropertyColor::_color_changed(const Color &p_color) {
-
emit_changed(get_edited_property(), p_color, "", true);
}
void EditorPropertyColor::_popup_closed() {
-
emit_changed(get_edited_property(), picker->get_pick_color(), "", false);
}
void EditorPropertyColor::_picker_created() {
// get default color picker mode from editor settings
int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode");
- if (default_color_mode == 1)
+ if (default_color_mode == 1) {
picker->get_picker()->set_hsv_mode(true);
- else if (default_color_mode == 2)
+ } else if (default_color_mode == 2) {
picker->get_picker()->set_raw_mode(true);
+ }
}
void EditorPropertyColor::_bind_methods() {
}
void EditorPropertyColor::update_property() {
-
picker->set_pick_color(get_edited_object()->get(get_edited_property()));
const Color color = picker->get_pick_color();
@@ -2129,7 +2115,6 @@ void EditorPropertyColor::setup(bool p_show_alpha) {
}
EditorPropertyColor::EditorPropertyColor() {
-
picker = memnew(ColorPickerButton);
add_child(picker);
picker->set_flat(true);
@@ -2141,7 +2126,6 @@ EditorPropertyColor::EditorPropertyColor() {
////////////// NODE PATH //////////////////////
void EditorPropertyNodePath::_node_selected(const NodePath &p_path) {
-
NodePath path = p_path;
Node *base_node = nullptr;
@@ -2188,13 +2172,11 @@ void EditorPropertyNodePath::_node_assign() {
}
void EditorPropertyNodePath::_node_clear() {
-
emit_changed(get_edited_property(), NodePath());
update_property();
}
void EditorPropertyNodePath::update_property() {
-
NodePath p = get_edited_object()->get(get_edited_property());
assign->set_tooltip(p);
@@ -2235,14 +2217,12 @@ void EditorPropertyNodePath::update_property() {
}
void EditorPropertyNodePath::setup(const NodePath &p_base_hint, Vector<StringName> p_valid_types, bool p_use_path_from_scene_root) {
-
base_hint = p_base_hint;
valid_types = p_valid_types;
use_path_from_scene_root = p_use_path_from_scene_root;
}
void EditorPropertyNodePath::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Ref<Texture2D> t = get_theme_icon("Clear", "EditorIcons");
clear->set_icon(t);
@@ -2253,7 +2233,6 @@ void EditorPropertyNodePath::_bind_methods() {
}
EditorPropertyNodePath::EditorPropertyNodePath() {
-
HBoxContainer *hbc = memnew(HBoxContainer);
add_child(hbc);
assign = memnew(Button);
@@ -2292,7 +2271,6 @@ EditorPropertyRID::EditorPropertyRID() {
////////////// RESOURCE //////////////////////
void EditorPropertyResource::_file_selected(const String &p_path) {
-
RES res = ResourceLoader::load(p_path);
ERR_FAIL_COND_MSG(res.is_null(), "Cannot load resource from path '" + p_path + "'.");
@@ -2316,8 +2294,9 @@ void EditorPropertyResource::_file_selected(const String &p_path) {
}
}
- if (!any_type_matches)
+ if (!any_type_matches) {
EditorNode::get_singleton()->show_warning(vformat(TTR("The selected resource (%s) does not match any type expected for this property (%s)."), res->get_class(), property_types));
+ }
}
emit_changed(get_edited_property(), res);
@@ -2325,11 +2304,9 @@ void EditorPropertyResource::_file_selected(const String &p_path) {
}
void EditorPropertyResource::_menu_option(int p_which) {
-
// scene_tree->popup_centered_ratio();
switch (p_which) {
case OBJ_MENU_LOAD: {
-
if (!file) {
file = memnew(EditorFileDialog);
file->connect("file_selected", callable_mp(this, &EditorPropertyResource::_file_selected));
@@ -2340,7 +2317,6 @@ void EditorPropertyResource::_menu_option(int p_which) {
List<String> extensions;
for (int i = 0; i < type.get_slice_count(","); i++) {
-
ResourceLoader::get_recognized_extensions_for_type(type.get_slice(",", i), &extensions);
}
@@ -2351,7 +2327,6 @@ void EditorPropertyResource::_menu_option(int p_which) {
file->clear_filters();
for (Set<String>::Element *E = valid_extensions.front(); E; E = E->next()) {
-
file->add_filter("*." + E->get() + " ; " + E->get().to_upper());
}
@@ -2359,37 +2334,32 @@ void EditorPropertyResource::_menu_option(int p_which) {
} break;
case OBJ_MENU_EDIT: {
-
RES res = get_edited_object()->get(get_edited_property());
if (!res.is_null()) {
-
emit_signal("resource_selected", get_edited_property(), res);
}
} break;
case OBJ_MENU_CLEAR: {
-
emit_changed(get_edited_property(), RES());
update_property();
} break;
case OBJ_MENU_MAKE_UNIQUE: {
-
RES res_orig = get_edited_object()->get(get_edited_property());
- if (res_orig.is_null())
+ if (res_orig.is_null()) {
return;
+ }
List<PropertyInfo> property_list;
res_orig->get_property_list(&property_list);
List<Pair<String, Variant>> propvalues;
for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
-
Pair<String, Variant> p;
PropertyInfo &pi = E->get();
if (pi.usage & PROPERTY_USAGE_STORAGE) {
-
p.first = pi.name;
p.second = res_orig->get(pi.name);
}
@@ -2406,7 +2376,6 @@ void EditorPropertyResource::_menu_option(int p_which) {
ERR_FAIL_COND(res.is_null());
for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) {
-
Pair<String, Variant> &p = E->get();
res->set(p.first, p.second);
}
@@ -2418,8 +2387,9 @@ void EditorPropertyResource::_menu_option(int p_which) {
case OBJ_MENU_SAVE: {
RES res = get_edited_object()->get(get_edited_property());
- if (res.is_null())
+ if (res.is_null()) {
return;
+ }
EditorNode::get_singleton()->save_resource(res);
} break;
@@ -2430,21 +2400,18 @@ void EditorPropertyResource::_menu_option(int p_which) {
} break;
case OBJ_MENU_PASTE: {
-
RES res = EditorSettings::get_singleton()->get_resource_clipboard();
emit_changed(get_edited_property(), res);
update_property();
} break;
case OBJ_MENU_NEW_SCRIPT: {
-
if (Object::cast_to<Node>(get_edited_object())) {
EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(get_edited_object()), false);
}
} break;
case OBJ_MENU_EXTEND_SCRIPT: {
-
if (Object::cast_to<Node>(get_edited_object())) {
EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(get_edited_object()), true);
}
@@ -2460,11 +2427,9 @@ void EditorPropertyResource::_menu_option(int p_which) {
tab_container->set_current_tab(file_system_dock->get_index());
} break;
default: {
-
RES res = get_edited_object()->get(get_edited_property());
if (p_which >= CONVERT_BASE_ID) {
-
int to_type = p_which - CONVERT_BASE_ID;
Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(res);
@@ -2482,7 +2447,6 @@ void EditorPropertyResource::_menu_option(int p_which) {
String intype = inheritors_array[p_which - TYPE_BASE_ID];
if (intype == "ViewportTexture") {
-
Resource *r = Object::cast_to<Resource>(get_edited_object());
if (r && r->get_path().is_resource_file()) {
EditorNode::get_singleton()->show_warning(TTR("Can't create a ViewportTexture on resources saved as a file.\nResource needs to belong to a scene."));
@@ -2544,7 +2508,6 @@ void EditorPropertyResource::_menu_option(int p_which) {
}
void EditorPropertyResource::_resource_preview(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, ObjectID p_obj) {
-
RES p = get_edited_object()->get(get_edited_property());
if (p.is_valid() && p->get_instance_id() == p_obj) {
String type = p->get_class_name();
@@ -2572,7 +2535,6 @@ void EditorPropertyResource::_resource_preview(const String &p_path, const Ref<T
}
void EditorPropertyResource::_update_menu_items() {
-
//////////////////// UPDATE MENU //////////////////////////
RES res = get_edited_object()->get(get_edited_property());
@@ -2592,7 +2554,6 @@ void EditorPropertyResource::_update_menu_items() {
}
for (int i = 0; i < base_type.get_slice_count(","); i++) {
-
String base = base_type.get_slice(",", i);
Set<String> valid_inheritors;
@@ -2629,20 +2590,23 @@ void EditorPropertyResource::_update_menu_items() {
for (int j = 0; j < custom_resources.size(); j++) {
if (custom_resources[j].name == t) {
is_custom_resource = true;
- if (custom_resources[j].icon.is_valid())
+ if (custom_resources[j].icon.is_valid()) {
icon = custom_resources[j].icon;
+ }
break;
}
}
}
- if (!is_custom_resource && !(ScriptServer::is_global_class(t) || ClassDB::can_instance(t)))
+ if (!is_custom_resource && !(ScriptServer::is_global_class(t) || ClassDB::can_instance(t))) {
continue;
+ }
inheritors_array.push_back(t);
- if (!icon.is_valid())
+ if (!icon.is_valid()) {
icon = get_theme_icon(has_theme_icon(t, "EditorIcons") ? t : "Object", "EditorIcons");
+ }
int id = TYPE_BASE_ID + idx;
menu->add_icon_item(icon, vformat(TTR("New %s"), t), id);
@@ -2651,14 +2615,14 @@ void EditorPropertyResource::_update_menu_items() {
}
}
- if (menu->get_item_count())
+ if (menu->get_item_count()) {
menu->add_separator();
+ }
}
menu->add_icon_item(get_theme_icon("Load", "EditorIcons"), TTR("Load"), OBJ_MENU_LOAD);
if (!res.is_null()) {
-
menu->add_icon_item(get_theme_icon("Edit", "EditorIcons"), TTR("Edit"), OBJ_MENU_EDIT);
menu->add_icon_item(get_theme_icon("Clear", "EditorIcons"), TTR("Clear"), OBJ_MENU_CLEAR);
menu->add_icon_item(get_theme_icon("Duplicate", "EditorIcons"), TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE);
@@ -2673,32 +2637,31 @@ void EditorPropertyResource::_update_menu_items() {
RES cb = EditorSettings::get_singleton()->get_resource_clipboard();
bool paste_valid = false;
if (cb.is_valid()) {
- if (base_type == "")
+ if (base_type == "") {
paste_valid = true;
- else
- for (int i = 0; i < base_type.get_slice_count(","); i++)
+ } else {
+ for (int i = 0; i < base_type.get_slice_count(","); i++) {
if (ClassDB::is_parent_class(cb->get_class(), base_type.get_slice(",", i))) {
paste_valid = true;
break;
}
+ }
+ }
}
if (!res.is_null() || paste_valid) {
menu->add_separator();
if (!res.is_null()) {
-
menu->add_item(TTR("Copy"), OBJ_MENU_COPY);
}
if (paste_valid) {
-
menu->add_item(TTR("Paste"), OBJ_MENU_PASTE);
}
}
if (!res.is_null()) {
-
Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(res);
if (conversions.size()) {
menu->add_separator();
@@ -2707,10 +2670,8 @@ void EditorPropertyResource::_update_menu_items() {
String what = conversions[i]->converts_to();
Ref<Texture2D> icon;
if (has_theme_icon(what, "EditorIcons")) {
-
icon = get_theme_icon(what, "EditorIcons");
} else {
-
icon = get_theme_icon(what, "Resource");
}
@@ -2720,7 +2681,6 @@ void EditorPropertyResource::_update_menu_items() {
}
void EditorPropertyResource::_update_menu() {
-
_update_menu_items();
Rect2 gt = edit->get_screen_rect();
@@ -2732,17 +2692,14 @@ void EditorPropertyResource::_update_menu() {
}
void EditorPropertyResource::_sub_inspector_property_keyed(const String &p_property, const Variant &p_value, bool) {
-
emit_signal("property_keyed_with_value", String(get_edited_property()) + ":" + p_property, p_value, false);
}
void EditorPropertyResource::_sub_inspector_resource_selected(const RES &p_resource, const String &p_property) {
-
emit_signal("resource_selected", String(get_edited_property()) + ":" + p_property, p_resource);
}
void EditorPropertyResource::_sub_inspector_object_id_selected(int p_id) {
-
emit_signal("object_id_selected", get_edited_property(), p_id);
}
@@ -2768,15 +2725,15 @@ void EditorPropertyResource::_open_editor_pressed() {
}
void EditorPropertyResource::_fold_other_editors(Object *p_self) {
-
if (this == p_self) {
return;
}
RES res = get_edited_object()->get(get_edited_property());
- if (!res.is_valid())
+ if (!res.is_valid()) {
return;
+ }
bool use_editor = false;
for (int i = 0; i < EditorNode::get_editor_data().get_editor_plugin_count(); i++) {
EditorPlugin *ep = EditorNode::get_editor_data().get_editor_plugin(i);
@@ -2785,8 +2742,9 @@ void EditorPropertyResource::_fold_other_editors(Object *p_self) {
}
}
- if (!use_editor)
+ if (!use_editor) {
return;
+ }
bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
opened_editor = false;
@@ -2800,17 +2758,14 @@ void EditorPropertyResource::_fold_other_editors(Object *p_self) {
}
void EditorPropertyResource::update_property() {
-
RES res = get_edited_object()->get(get_edited_property());
if (use_sub_inspector) {
-
if (res.is_valid() != assign->is_toggle_mode()) {
assign->set_toggle_mode(res.is_valid());
}
if (res.is_valid() && get_edited_object()->editor_is_section_unfolded(get_edited_property())) {
-
if (!sub_inspector) {
sub_inspector = memnew(EditorInspector);
sub_inspector->set_enable_v_scroll(false);
@@ -2876,7 +2831,6 @@ void EditorPropertyResource::update_property() {
assign->set_icon(Ref<Texture2D>());
assign->set_text(TTR("[empty]"));
} else {
-
assign->set_icon(EditorNode::get_singleton()->get_object_icon(res.operator->(), "Object"));
if (res->get_name() != String()) {
@@ -2907,12 +2861,10 @@ void EditorPropertyResource::_resource_selected() {
}
if (use_sub_inspector) {
-
bool unfold = !get_edited_object()->editor_is_section_unfolded(get_edited_property());
get_edited_object()->editor_set_section_unfold(get_edited_property(), unfold);
update_property();
} else {
-
emit_signal("resource_selected", get_edited_property(), res);
}
}
@@ -2922,14 +2874,12 @@ void EditorPropertyResource::setup(const String &p_base_type) {
}
void EditorPropertyResource::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Ref<Texture2D> t = get_theme_icon("select_arrow", "Tree");
edit->set_icon(t);
}
if (p_what == NOTIFICATION_DRAG_BEGIN) {
-
if (is_visible_in_tree()) {
if (_is_drop_valid(get_viewport()->gui_get_drag_data())) {
dropping = true;
@@ -2947,7 +2897,6 @@ void EditorPropertyResource::_notification(int p_what) {
}
void EditorPropertyResource::_viewport_selected(const NodePath &p_path) {
-
Node *to_node = get_node(p_path);
if (!Object::cast_to<Viewport>(to_node)) {
EditorNode::get_singleton()->show_warning(TTR("Selected node is not a Viewport!"));
@@ -2970,14 +2919,12 @@ void EditorPropertyResource::collapse_all_folding() {
}
void EditorPropertyResource::expand_all_folding() {
-
if (sub_inspector) {
sub_inspector->expand_all_folding();
}
}
void EditorPropertyResource::_button_draw() {
-
if (dropping) {
Color color = get_theme_color("accent_color", "Editor");
assign->draw_rect(Rect2(Point2(), assign->get_size()), color, false);
@@ -2985,10 +2932,8 @@ void EditorPropertyResource::_button_draw() {
}
Variant EditorPropertyResource::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
RES res = get_edited_object()->get(get_edited_property());
if (res.is_valid()) {
-
return EditorNode::get_singleton()->drag_resource(res, p_from);
}
@@ -2996,7 +2941,6 @@ Variant EditorPropertyResource::get_drag_data_fw(const Point2 &p_point, Control
}
bool EditorPropertyResource::_is_drop_valid(const Dictionary &p_drag_data) const {
-
String allowed_type = base_type;
Dictionary drag_data = p_drag_data;
@@ -3011,7 +2955,6 @@ bool EditorPropertyResource::_is_drop_valid(const Dictionary &p_drag_data) const
}
if (drag_data.has("type") && String(drag_data["type"]) == "files") {
-
Vector<String> files = drag_data["files"];
if (files.size() == 1) {
@@ -3019,7 +2962,6 @@ bool EditorPropertyResource::_is_drop_valid(const Dictionary &p_drag_data) const
String ftype = EditorFileSystem::get_singleton()->get_file_type(file);
if (ftype != "") {
-
for (int i = 0; i < allowed_type.get_slice_count(","); i++) {
String at = allowed_type.get_slice(",", i).strip_edges();
if (ClassDB::is_parent_class(ftype, at)) {
@@ -3034,11 +2976,10 @@ bool EditorPropertyResource::_is_drop_valid(const Dictionary &p_drag_data) const
}
bool EditorPropertyResource::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
return _is_drop_valid(p_data);
}
-void EditorPropertyResource::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
+void EditorPropertyResource::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
ERR_FAIL_COND(!_is_drop_valid(p_data));
Dictionary drag_data = p_data;
@@ -3052,7 +2993,6 @@ void EditorPropertyResource::drop_data_fw(const Point2 &p_point, const Variant &
}
if (drag_data.has("type") && String(drag_data["type"]) == "files") {
-
Vector<String> files = drag_data["files"];
if (files.size() == 1) {
@@ -3072,7 +3012,6 @@ void EditorPropertyResource::set_use_sub_inspector(bool p_enable) {
}
void EditorPropertyResource::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_resource_preview"), &EditorPropertyResource::_resource_preview);
ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &EditorPropertyResource::get_drag_data_fw);
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &EditorPropertyResource::can_drop_data_fw);
@@ -3082,7 +3021,6 @@ void EditorPropertyResource::_bind_methods() {
}
EditorPropertyResource::EditorPropertyResource() {
-
opened_editor = false;
sub_inspector = nullptr;
sub_inspector_vbox = nullptr;
@@ -3139,11 +3077,9 @@ void EditorInspectorDefaultPlugin::parse_begin(Object *p_object) {
}
bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
-
float default_float_step = EDITOR_GET("interface/inspector/default_float_step");
switch (p_type) {
-
// atomic types
case Variant::NIL: {
EditorPropertyNil *editor = memnew(EditorPropertyNil);
@@ -3154,7 +3090,6 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
add_property_editor(p_path, editor);
} break;
case Variant::INT: {
-
if (p_hint == PROPERTY_HINT_ENUM) {
EditorPropertyEnum *editor = memnew(EditorPropertyEnum);
Vector<String> options = p_hint_text.split(",");
@@ -3168,7 +3103,6 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
add_property_editor(p_path, editor);
} else if (p_hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || p_hint == PROPERTY_HINT_LAYERS_2D_RENDER || p_hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || p_hint == PROPERTY_HINT_LAYERS_3D_RENDER) {
-
EditorPropertyLayers::LayerType lt = EditorPropertyLayers::LAYER_RENDER_2D;
switch (p_hint) {
case PROPERTY_HINT_LAYERS_2D_RENDER:
@@ -3190,7 +3124,6 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
editor->setup(lt);
add_property_editor(p_path, editor);
} else if (p_hint == PROPERTY_HINT_OBJECT_ID) {
-
EditorPropertyObjectID *editor = memnew(EditorPropertyObjectID);
editor->setup(p_hint_text);
add_property_editor(p_path, editor);
@@ -3227,7 +3160,6 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
}
} break;
case Variant::FLOAT: {
-
if (p_hint == PROPERTY_HINT_EXP_EASING) {
EditorPropertyEasing *editor = memnew(EditorPropertyEasing);
bool full = true;
@@ -3280,7 +3212,6 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
}
} break;
case Variant::STRING: {
-
if (p_hint == PROPERTY_HINT_ENUM) {
EditorPropertyTextEnum *editor = memnew(EditorPropertyTextEnum);
Vector<String> options = p_hint_text.split(",");
@@ -3294,7 +3225,6 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
editor->setup("Object", p_hint_text);
add_property_editor(p_path, editor);
} else if (p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_FILE || p_hint == PROPERTY_HINT_SAVE_FILE || p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE) {
-
Vector<String> extensions = p_hint_text.split(",");
bool global = p_hint == PROPERTY_HINT_GLOBAL_DIR || p_hint == PROPERTY_HINT_GLOBAL_FILE;
bool folder = p_hint == PROPERTY_HINT_DIR || p_hint == PROPERTY_HINT_GLOBAL_DIR;
@@ -3313,18 +3243,31 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
p_hint == PROPERTY_HINT_PROPERTY_OF_BASE_TYPE ||
p_hint == PROPERTY_HINT_PROPERTY_OF_INSTANCE ||
p_hint == PROPERTY_HINT_PROPERTY_OF_SCRIPT) {
-
EditorPropertyMember *editor = memnew(EditorPropertyMember);
EditorPropertyMember::Type type = EditorPropertyMember::MEMBER_METHOD_OF_BASE_TYPE;
switch (p_hint) {
- case PROPERTY_HINT_METHOD_OF_BASE_TYPE: type = EditorPropertyMember::MEMBER_METHOD_OF_BASE_TYPE; break;
- case PROPERTY_HINT_METHOD_OF_INSTANCE: type = EditorPropertyMember::MEMBER_METHOD_OF_INSTANCE; break;
- case PROPERTY_HINT_METHOD_OF_SCRIPT: type = EditorPropertyMember::MEMBER_METHOD_OF_SCRIPT; break;
- case PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE: type = EditorPropertyMember::MEMBER_PROPERTY_OF_VARIANT_TYPE; break;
- case PROPERTY_HINT_PROPERTY_OF_BASE_TYPE: type = EditorPropertyMember::MEMBER_PROPERTY_OF_BASE_TYPE; break;
- case PROPERTY_HINT_PROPERTY_OF_INSTANCE: type = EditorPropertyMember::MEMBER_PROPERTY_OF_INSTANCE; break;
- case PROPERTY_HINT_PROPERTY_OF_SCRIPT: type = EditorPropertyMember::MEMBER_PROPERTY_OF_SCRIPT; break;
+ case PROPERTY_HINT_METHOD_OF_BASE_TYPE:
+ type = EditorPropertyMember::MEMBER_METHOD_OF_BASE_TYPE;
+ break;
+ case PROPERTY_HINT_METHOD_OF_INSTANCE:
+ type = EditorPropertyMember::MEMBER_METHOD_OF_INSTANCE;
+ break;
+ case PROPERTY_HINT_METHOD_OF_SCRIPT:
+ type = EditorPropertyMember::MEMBER_METHOD_OF_SCRIPT;
+ break;
+ case PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE:
+ type = EditorPropertyMember::MEMBER_PROPERTY_OF_VARIANT_TYPE;
+ break;
+ case PROPERTY_HINT_PROPERTY_OF_BASE_TYPE:
+ type = EditorPropertyMember::MEMBER_PROPERTY_OF_BASE_TYPE;
+ break;
+ case PROPERTY_HINT_PROPERTY_OF_INSTANCE:
+ type = EditorPropertyMember::MEMBER_PROPERTY_OF_INSTANCE;
+ break;
+ case PROPERTY_HINT_PROPERTY_OF_SCRIPT:
+ type = EditorPropertyMember::MEMBER_PROPERTY_OF_SCRIPT;
+ break;
default: {
}
}
@@ -3332,7 +3275,6 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
add_property_editor(p_path, editor);
} else {
-
EditorPropertyText *editor = memnew(EditorPropertyText);
if (p_hint == PROPERTY_HINT_PLACEHOLDER_TEXT) {
editor->set_placeholder(p_hint_text);
@@ -3553,7 +3495,6 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
add_property_editor(p_path, editor);
} break;
case Variant::STRING_NAME: {
-
if (p_hint == PROPERTY_HINT_ENUM) {
EditorPropertyTextEnum *editor = memnew(EditorPropertyTextEnum);
Vector<String> options = p_hint_text.split(",");
@@ -3569,7 +3510,6 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
}
} break;
case Variant::NODE_PATH: {
-
EditorPropertyNodePath *editor = memnew(EditorPropertyNodePath);
if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && p_hint_text != String()) {
editor->setup(p_hint_text, Vector<StringName>(), (p_usage & PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT));
@@ -3597,7 +3537,6 @@ bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Typ
for (int j = 0; j < p_hint_text.get_slice_count(","); j++) {
String inherits = p_hint_text.get_slicec(',', j);
if (ClassDB::is_parent_class(inherits, type)) {
-
editor->set_use_sub_inspector(false);
}
}
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index fdd5bd8db6..51fac6acec 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -35,7 +35,6 @@
#include "editor_properties.h"
bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_value) {
-
String pn = p_name;
if (pn.begins_with("indices")) {
@@ -48,11 +47,9 @@ bool EditorPropertyArrayObject::_set(const StringName &p_name, const Variant &p_
}
bool EditorPropertyArrayObject::_get(const StringName &p_name, Variant &r_ret) const {
-
String pn = p_name;
if (pn.begins_with("indices")) {
-
int idx = pn.get_slicec('/', 1).to_int();
bool valid;
r_ret = array.get(idx, &valid);
@@ -80,17 +77,14 @@ EditorPropertyArrayObject::EditorPropertyArrayObject() {
///////////////////
bool EditorPropertyDictionaryObject::_set(const StringName &p_name, const Variant &p_value) {
-
String pn = p_name;
if (pn == "new_item_key") {
-
new_item_key = p_value;
return true;
}
if (pn == "new_item_value") {
-
new_item_value = p_value;
return true;
}
@@ -106,23 +100,19 @@ bool EditorPropertyDictionaryObject::_set(const StringName &p_name, const Varian
}
bool EditorPropertyDictionaryObject::_get(const StringName &p_name, Variant &r_ret) const {
-
String pn = p_name;
if (pn == "new_item_key") {
-
r_ret = new_item_key;
return true;
}
if (pn == "new_item_value") {
-
r_ret = new_item_value;
return true;
}
if (pn.begins_with("indices")) {
-
int idx = pn.get_slicec('/', 1).to_int();
Variant key = dict.get_key_at_index(idx);
r_ret = dict[key];
@@ -166,7 +156,6 @@ EditorPropertyDictionaryObject::EditorPropertyDictionaryObject() {
///////////////////// ARRAY ///////////////////////////
void EditorPropertyArray::_property_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
-
if (p_property.begins_with("indices")) {
int idx = p_property.get_slice("/", 1).to_int();
Variant array = object->get_array();
@@ -181,7 +170,6 @@ void EditorPropertyArray::_property_changed(const String &p_property, Variant p_
}
void EditorPropertyArray::_change_type(Object *p_button, int p_index) {
-
Button *button = Object::cast_to<Button>(p_button);
changing_type_idx = p_index;
Rect2 rect = button->get_screen_rect();
@@ -191,7 +179,6 @@ void EditorPropertyArray::_change_type(Object *p_button, int p_index) {
}
void EditorPropertyArray::_change_type_menu(int p_index) {
-
if (p_index == Variant::VARIANT_MAX) {
_remove_pressed(changing_type_idx);
return;
@@ -218,7 +205,6 @@ void EditorPropertyArray::_object_id_selected(const StringName &p_property, Obje
}
void EditorPropertyArray::update_property() {
-
Variant array = get_edited_object()->get(get_edited_property());
String arrtype = "";
@@ -278,11 +264,9 @@ void EditorPropertyArray::update_property() {
}
if (unfolded) {
-
updating = true;
if (!vbox) {
-
vbox = memnew(VBoxContainer);
add_child(vbox);
set_bottom_editor(vbox);
@@ -371,13 +355,11 @@ void EditorPropertyArray::update_property() {
bool is_untyped_array = array.get_type() == Variant::ARRAY && subtype == Variant::NIL;
if (is_untyped_array) {
-
Button *edit = memnew(Button);
edit->set_icon(get_theme_icon("Edit", "EditorIcons"));
hb->add_child(edit);
edit->connect("pressed", callable_mp(this, &EditorPropertyArray::_change_type), varray(edit, i + offset));
} else {
-
Button *remove = memnew(Button);
remove->set_icon(get_theme_icon("Remove", "EditorIcons"));
remove->connect("pressed", callable_mp(this, &EditorPropertyArray::_remove_pressed), varray(i + offset));
@@ -399,7 +381,6 @@ void EditorPropertyArray::update_property() {
}
void EditorPropertyArray::_remove_pressed(int p_index) {
-
Variant array = object->get_array();
array.call("remove", p_index);
@@ -412,10 +393,101 @@ void EditorPropertyArray::_remove_pressed(int p_index) {
update_property();
}
+void EditorPropertyArray::_button_draw() {
+ if (dropping) {
+ Color color = get_theme_color("accent_color", "Editor");
+ edit->draw_rect(Rect2(Point2(), edit->get_size()), color, false);
+ }
+}
+
+bool EditorPropertyArray::_is_drop_valid(const Dictionary &p_drag_data) const {
+ String allowed_type = Variant::get_type_name(subtype);
+
+ Dictionary drag_data = p_drag_data;
+
+ if (drag_data.has("type") && String(drag_data["type"]) == "files") {
+ Vector<String> files = drag_data["files"];
+
+ for (int i = 0; i < files.size(); i++) {
+ String file = files[i];
+ String ftype = EditorFileSystem::get_singleton()->get_file_type(file);
+
+ for (int j = 0; j < allowed_type.get_slice_count(","); j++) {
+ String at = allowed_type.get_slice(",", j).strip_edges();
+ // Fail if one of the files is not of allowed type
+ if (!ClassDB::is_parent_class(ftype, at)) {
+ return false;
+ }
+ }
+ }
+
+ // If no files fail, drop is valid
+ return true;
+ }
+
+ return false;
+}
+
+bool EditorPropertyArray::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
+ return _is_drop_valid(p_data);
+}
+
+void EditorPropertyArray::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
+ ERR_FAIL_COND(!_is_drop_valid(p_data));
+
+ Dictionary drag_data = p_data;
+
+ if (drag_data.has("type") && String(drag_data["type"]) == "files") {
+ Vector<String> files = drag_data["files"];
+
+ Variant array = object->get_array();
+
+ // Handle the case where array is not initialised yet
+ if (!array.is_array()) {
+ Callable::CallError ce;
+ array = Variant::construct(array_type, nullptr, 0, ce);
+ }
+
+ // Loop the file array and add to existing array
+ for (int i = 0; i < files.size(); i++) {
+ String file = files[i];
+
+ RES res = ResourceLoader::load(file);
+ if (res.is_valid()) {
+ array.call("push_back", res);
+ }
+ }
+
+ if (array.get_type() == Variant::ARRAY) {
+ array = array.call("duplicate");
+ }
+
+ emit_changed(get_edited_property(), array, "", false);
+ object->set_array(array);
+
+ update_property();
+ }
+}
+
void EditorPropertyArray::_notification(int p_what) {
+ if (p_what == NOTIFICATION_DRAG_BEGIN) {
+ if (is_visible_in_tree()) {
+ if (_is_drop_valid(get_viewport()->gui_get_drag_data())) {
+ dropping = true;
+ edit->update();
+ }
+ }
+ }
+
+ if (p_what == NOTIFICATION_DRAG_END) {
+ if (dropping) {
+ dropping = false;
+ edit->update();
+ }
+ }
}
-void EditorPropertyArray::_edit_pressed() {
+void EditorPropertyArray::_edit_pressed() {
Variant array = get_edited_object()->get(get_edited_property());
if (!array.is_array()) {
Callable::CallError ce;
@@ -429,15 +501,17 @@ void EditorPropertyArray::_edit_pressed() {
}
void EditorPropertyArray::_page_changed(double p_page) {
- if (updating)
+ if (updating) {
return;
+ }
page_idx = p_page;
update_property();
}
void EditorPropertyArray::_length_changed(double p_page) {
- if (updating)
+ if (updating) {
return;
+ }
Variant array = object->get_array();
int previous_size = array.call("size");
@@ -470,7 +544,6 @@ void EditorPropertyArray::_length_changed(double p_page) {
}
void EditorPropertyArray::setup(Variant::Type p_array_type, const String &p_hint_string) {
-
array_type = p_array_type;
if (array_type == Variant::ARRAY && !p_hint_string.empty()) {
@@ -490,10 +563,11 @@ void EditorPropertyArray::setup(Variant::Type p_array_type, const String &p_hint
}
void EditorPropertyArray::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &EditorPropertyArray::can_drop_data_fw);
+ ClassDB::bind_method(D_METHOD("drop_data_fw"), &EditorPropertyArray::drop_data_fw);
}
EditorPropertyArray::EditorPropertyArray() {
-
object.instance();
page_idx = 0;
page_len = 10;
@@ -503,6 +577,8 @@ EditorPropertyArray::EditorPropertyArray() {
edit->set_clip_text(true);
edit->connect("pressed", callable_mp(this, &EditorPropertyArray::_edit_pressed));
edit->set_toggle_mode(true);
+ edit->set_drag_forwarding(this);
+ edit->connect("draw", callable_mp(this, &EditorPropertyArray::_button_draw));
add_child(edit);
add_focusable(edit);
vbox = nullptr;
@@ -524,17 +600,16 @@ EditorPropertyArray::EditorPropertyArray() {
subtype = Variant::NIL;
subtype_hint = PROPERTY_HINT_NONE;
subtype_hint_string = "";
+
+ dropping = false;
}
///////////////////// DICTIONARY ///////////////////////////
void EditorPropertyDictionary::_property_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
-
if (p_property == "new_item_key") {
-
object->set_new_item_key(p_value);
} else if (p_property == "new_item_value") {
-
object->set_new_item_value(p_value);
} else if (p_property.begins_with("indices")) {
int idx = p_property.get_slice("/", 1).to_int();
@@ -550,7 +625,6 @@ void EditorPropertyDictionary::_property_changed(const String &p_property, Varia
}
void EditorPropertyDictionary::_change_type(Object *p_button, int p_index) {
-
Button *button = Object::cast_to<Button>(p_button);
Rect2 rect = button->get_screen_rect();
@@ -561,7 +635,6 @@ void EditorPropertyDictionary::_change_type(Object *p_button, int p_index) {
}
void EditorPropertyDictionary::_add_key_value() {
-
// Do not allow nil as valid key. I experienced errors with this
if (object->get_new_item_key().get_type() == Variant::NIL) {
return;
@@ -581,7 +654,6 @@ void EditorPropertyDictionary::_add_key_value() {
}
void EditorPropertyDictionary::_change_type_menu(int p_index) {
-
if (changing_type_idx < 0) {
Variant value;
Callable::CallError ce;
@@ -598,7 +670,6 @@ void EditorPropertyDictionary::_change_type_menu(int p_index) {
Dictionary dict = object->get_dict();
if (p_index < Variant::VARIANT_MAX) {
-
Variant value;
Callable::CallError ce;
value = Variant::construct(Variant::Type(p_index), nullptr, 0, ce);
@@ -617,7 +688,6 @@ void EditorPropertyDictionary::_change_type_menu(int p_index) {
}
void EditorPropertyDictionary::update_property() {
-
Variant updated_val = get_edited_object()->get(get_edited_property());
if (updated_val.get_type() == Variant::NIL) {
@@ -641,11 +711,9 @@ void EditorPropertyDictionary::update_property() {
}
if (unfolded) {
-
updating = true;
if (!vbox) {
-
vbox = memnew(VBoxContainer);
add_child(vbox);
set_bottom_editor(vbox);
@@ -712,7 +780,6 @@ void EditorPropertyDictionary::update_property() {
// atomic types
case Variant::BOOL: {
-
prop = memnew(EditorPropertyCheck);
} break;
@@ -723,83 +790,71 @@ void EditorPropertyDictionary::update_property() {
} break;
case Variant::FLOAT: {
-
EditorPropertyFloat *editor = memnew(EditorPropertyFloat);
editor->setup(-100000, 100000, 0.001, true, false, true, true);
prop = editor;
} break;
case Variant::STRING: {
-
prop = memnew(EditorPropertyText);
} break;
// math types
case Variant::VECTOR2: {
-
EditorPropertyVector2 *editor = memnew(EditorPropertyVector2);
editor->setup(-100000, 100000, 0.001, true);
prop = editor;
} break;
case Variant::VECTOR2I: {
-
EditorPropertyVector2i *editor = memnew(EditorPropertyVector2i);
editor->setup(-100000, 100000, true);
prop = editor;
} break;
case Variant::RECT2: {
-
EditorPropertyRect2 *editor = memnew(EditorPropertyRect2);
editor->setup(-100000, 100000, 0.001, true);
prop = editor;
} break;
case Variant::RECT2I: {
-
EditorPropertyRect2i *editor = memnew(EditorPropertyRect2i);
editor->setup(-100000, 100000, true);
prop = editor;
} break;
case Variant::VECTOR3: {
-
EditorPropertyVector3 *editor = memnew(EditorPropertyVector3);
editor->setup(-100000, 100000, 0.001, true);
prop = editor;
} break;
case Variant::VECTOR3I: {
-
EditorPropertyVector3i *editor = memnew(EditorPropertyVector3i);
editor->setup(-100000, 100000, true);
prop = editor;
} break;
case Variant::TRANSFORM2D: {
-
EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D);
editor->setup(-100000, 100000, 0.001, true);
prop = editor;
} break;
case Variant::PLANE: {
-
EditorPropertyPlane *editor = memnew(EditorPropertyPlane);
editor->setup(-100000, 100000, 0.001, true);
prop = editor;
} break;
case Variant::QUAT: {
-
EditorPropertyQuat *editor = memnew(EditorPropertyQuat);
editor->setup(-100000, 100000, 0.001, true);
prop = editor;
} break;
case Variant::AABB: {
-
EditorPropertyAABB *editor = memnew(EditorPropertyAABB);
editor->setup(-100000, 100000, 0.001, true);
prop = editor;
@@ -838,15 +893,12 @@ void EditorPropertyDictionary::update_property() {
} break;
case Variant::OBJECT: {
-
if (Object::cast_to<EncodedObjectAsID>(value)) {
-
EditorPropertyObjectID *editor = memnew(EditorPropertyObjectID);
editor->setup("Object");
prop = editor;
} else {
-
EditorPropertyResource *editor = memnew(EditorPropertyResource);
editor->setup("Resource");
prop = editor;
@@ -865,55 +917,46 @@ void EditorPropertyDictionary::update_property() {
// arrays
case Variant::PACKED_BYTE_ARRAY: {
-
EditorPropertyArray *editor = memnew(EditorPropertyArray);
editor->setup(Variant::PACKED_BYTE_ARRAY);
prop = editor;
} break;
case Variant::PACKED_INT32_ARRAY: {
-
EditorPropertyArray *editor = memnew(EditorPropertyArray);
editor->setup(Variant::PACKED_INT32_ARRAY);
prop = editor;
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
-
EditorPropertyArray *editor = memnew(EditorPropertyArray);
editor->setup(Variant::PACKED_FLOAT32_ARRAY);
prop = editor;
} break;
case Variant::PACKED_INT64_ARRAY: {
-
EditorPropertyArray *editor = memnew(EditorPropertyArray);
editor->setup(Variant::PACKED_INT64_ARRAY);
prop = editor;
} break;
case Variant::PACKED_FLOAT64_ARRAY: {
-
EditorPropertyArray *editor = memnew(EditorPropertyArray);
editor->setup(Variant::PACKED_FLOAT64_ARRAY);
prop = editor;
} break;
case Variant::PACKED_STRING_ARRAY: {
-
EditorPropertyArray *editor = memnew(EditorPropertyArray);
editor->setup(Variant::PACKED_STRING_ARRAY);
prop = editor;
} break;
case Variant::PACKED_VECTOR2_ARRAY: {
-
EditorPropertyArray *editor = memnew(EditorPropertyArray);
editor->setup(Variant::PACKED_VECTOR2_ARRAY);
prop = editor;
} break;
case Variant::PACKED_VECTOR3_ARRAY: {
-
EditorPropertyArray *editor = memnew(EditorPropertyArray);
editor->setup(Variant::PACKED_VECTOR3_ARRAY);
prop = editor;
} break;
case Variant::PACKED_COLOR_ARRAY: {
-
EditorPropertyArray *editor = memnew(EditorPropertyArray);
editor->setup(Variant::PACKED_COLOR_ARRAY);
prop = editor;
@@ -998,7 +1041,6 @@ void EditorPropertyDictionary::_notification(int p_what) {
}
void EditorPropertyDictionary::_edit_pressed() {
-
Variant prop_val = get_edited_object()->get(get_edited_property());
if (prop_val.get_type() == Variant::NIL) {
Callable::CallError ce;
@@ -1011,8 +1053,9 @@ void EditorPropertyDictionary::_edit_pressed() {
}
void EditorPropertyDictionary::_page_changed(double p_page) {
- if (updating)
+ if (updating) {
return;
+ }
page_idx = p_page;
update_property();
}
@@ -1021,7 +1064,6 @@ void EditorPropertyDictionary::_bind_methods() {
}
EditorPropertyDictionary::EditorPropertyDictionary() {
-
object.instance();
page_idx = 0;
page_len = 10;
diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h
index 51a4be1b3a..7eed9b4fa7 100644
--- a/editor/editor_properties_array_dict.h
+++ b/editor/editor_properties_array_dict.h
@@ -33,10 +33,10 @@
#include "editor/editor_inspector.h"
#include "editor/editor_spin_slider.h"
+#include "editor/filesystem_dock.h"
#include "scene/gui/button.h"
class EditorPropertyArrayObject : public Reference {
-
GDCLASS(EditorPropertyArrayObject, Reference);
Variant array;
@@ -53,7 +53,6 @@ public:
};
class EditorPropertyDictionaryObject : public Reference {
-
GDCLASS(EditorPropertyDictionaryObject, Reference);
Variant new_item_key;
@@ -82,6 +81,7 @@ class EditorPropertyArray : public EditorProperty {
PopupMenu *change_type;
bool updating;
+ bool dropping;
Ref<EditorPropertyArrayObject> object;
int page_len;
@@ -107,6 +107,11 @@ class EditorPropertyArray : public EditorProperty {
void _object_id_selected(const StringName &p_property, ObjectID p_id);
void _remove_pressed(int p_index);
+ void _button_draw();
+ bool _is_drop_valid(const Dictionary &p_drag_data) const;
+ bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
+ void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
+
protected:
static void _bind_methods();
void _notification(int p_what);
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index 2a4300f833..7ac8fae156 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -42,7 +42,6 @@
#include "editor_settings.h"
bool EditorResourcePreviewGenerator::handles(const String &p_type) const {
-
if (get_script_instance() && get_script_instance()->has_method("handles")) {
return get_script_instance()->call("handles", p_type);
}
@@ -50,7 +49,6 @@ bool EditorResourcePreviewGenerator::handles(const String &p_type) const {
}
Ref<Texture2D> EditorResourcePreviewGenerator::generate(const RES &p_from, const Size2 &p_size) const {
-
if (get_script_instance() && get_script_instance()->has_method("generate")) {
return get_script_instance()->call("generate", p_from, p_size);
}
@@ -58,19 +56,18 @@ Ref<Texture2D> EditorResourcePreviewGenerator::generate(const RES &p_from, const
}
Ref<Texture2D> EditorResourcePreviewGenerator::generate_from_path(const String &p_path, const Size2 &p_size) const {
-
if (get_script_instance() && get_script_instance()->has_method("generate_from_path")) {
return get_script_instance()->call("generate_from_path", p_path, p_size);
}
RES res = ResourceLoader::load(p_path);
- if (!res.is_valid())
+ if (!res.is_valid()) {
return res;
+ }
return generate(res, p_size);
}
bool EditorResourcePreviewGenerator::generate_small_preview_automatically() const {
-
if (get_script_instance() && get_script_instance()->has_method("generate_small_preview_automatically")) {
return get_script_instance()->call("generate_small_preview_automatically");
}
@@ -79,7 +76,6 @@ bool EditorResourcePreviewGenerator::generate_small_preview_automatically() cons
}
bool EditorResourcePreviewGenerator::can_generate_small_preview() const {
-
if (get_script_instance() && get_script_instance()->has_method("can_generate_small_preview")) {
return get_script_instance()->call("can_generate_small_preview");
}
@@ -88,7 +84,6 @@ bool EditorResourcePreviewGenerator::can_generate_small_preview() const {
}
void EditorResourcePreviewGenerator::_bind_methods() {
-
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "handles", PropertyInfo(Variant::STRING, "type")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture2D), "generate", PropertyInfo(Variant::OBJECT, "from", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::VECTOR2, "size")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(CLASS_INFO(Texture2D), "generate_from_path", PropertyInfo(Variant::STRING, "path", PROPERTY_HINT_FILE), PropertyInfo(Variant::VECTOR2, "size")));
@@ -102,13 +97,11 @@ EditorResourcePreviewGenerator::EditorResourcePreviewGenerator() {
EditorResourcePreview *EditorResourcePreview::singleton = nullptr;
void EditorResourcePreview::_thread_func(void *ud) {
-
EditorResourcePreview *erp = (EditorResourcePreview *)ud;
erp->_thread();
}
void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_small_texture, ObjectID id, const StringName &p_func, const Variant &p_ud) {
-
String path = p_str;
{
MutexLock lock(preview_mutex);
@@ -139,10 +132,11 @@ void EditorResourcePreview::_preview_ready(const String &p_str, const Ref<Textur
void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<ImageTexture> &r_small_texture, const QueueItem &p_item, const String &cache_base) {
String type;
- if (p_item.resource.is_valid())
+ if (p_item.resource.is_valid()) {
type = p_item.resource->get_class();
- else
+ } else {
type = ResourceLoader::get_resource_type(p_item.path);
+ }
if (type == "") {
r_texture = Ref<ImageTexture>();
@@ -157,8 +151,9 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<
r_small_texture = Ref<ImageTexture>();
for (int i = 0; i < preview_generators.size(); i++) {
- if (!preview_generators[i]->handles(type))
+ if (!preview_generators[i]->handles(type)) {
continue;
+ }
Ref<Texture2D> generated;
if (p_item.resource.is_valid()) {
@@ -214,15 +209,12 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<
}
void EditorResourcePreview::_thread() {
-
exited = false;
while (!exit) {
-
preview_sem.wait();
preview_mutex.lock();
if (queue.size()) {
-
QueueItem item = queue.front()->get();
queue.pop_front();
@@ -237,7 +229,6 @@ void EditorResourcePreview::_thread() {
preview_mutex.unlock();
} else {
-
preview_mutex.unlock();
Ref<ImageTexture> texture;
@@ -247,14 +238,12 @@ void EditorResourcePreview::_thread() {
thumbnail_size *= EDSCALE;
if (item.resource.is_valid()) {
-
_generate_preview(texture, small_texture, item, String());
//adding hash to the end of path (should be ID:<objid>:<hash>) because of 5 argument limit to call_deferred
_preview_ready(item.path + ":" + itos(item.resource->hash_edited_version()), texture, small_texture, item.id, item.function, item.userdata);
} else {
-
String temp_path = EditorSettings::get_singleton()->get_cache_dir();
String cache_base = ProjectSettings::get_singleton()->globalize_path(item.path).md5_text();
cache_base = temp_path.plus_file("resthumb-" + cache_base);
@@ -264,11 +253,9 @@ void EditorResourcePreview::_thread() {
String file = cache_base + ".txt";
FileAccess *f = FileAccess::open(file, FileAccess::READ);
if (!f) {
-
// No cache found, generate
_generate_preview(texture, small_texture, item, cache_base);
} else {
-
uint64_t modtime = FileAccess::get_modified_time(item.path);
int tsize = f->get_line().to_int64();
bool has_small_texture = f->get_line().to_int();
@@ -277,17 +264,14 @@ void EditorResourcePreview::_thread() {
bool cache_valid = true;
if (tsize != thumbnail_size) {
-
cache_valid = false;
memdelete(f);
} else if (last_modtime != modtime) {
-
String last_md5 = f->get_line();
String md5 = FileAccess::get_md5(item.path);
memdelete(f);
if (last_md5 != md5) {
-
cache_valid = false;
} else {
@@ -311,7 +295,6 @@ void EditorResourcePreview::_thread() {
}
if (cache_valid) {
-
Ref<Image> img;
img.instance();
Ref<Image> small_img;
@@ -320,7 +303,6 @@ void EditorResourcePreview::_thread() {
if (img->load(cache_base + ".png") != OK) {
cache_valid = false;
} else {
-
texture.instance();
texture->create_from_image(img);
@@ -336,7 +318,6 @@ void EditorResourcePreview::_thread() {
}
if (!cache_valid) {
-
_generate_preview(texture, small_texture, item, cache_base);
}
}
@@ -352,7 +333,6 @@ void EditorResourcePreview::_thread() {
}
void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p_res, Object *p_receiver, const StringName &p_receiver_func, const Variant &p_userdata) {
-
ERR_FAIL_NULL(p_receiver);
ERR_FAIL_COND(!p_res.is_valid());
@@ -362,7 +342,6 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p
String path_id = "ID:" + itos(p_res->get_instance_id());
if (cache.has(path_id) && cache[path_id].last_hash == p_res->hash_edited_version()) {
-
cache[path_id].order = order++;
p_receiver->call(p_receiver_func, path_id, cache[path_id].preview, cache[path_id].small_preview, p_userdata);
return;
@@ -383,7 +362,6 @@ void EditorResourcePreview::queue_edited_resource_preview(const Ref<Resource> &p
}
void EditorResourcePreview::queue_resource_preview(const String &p_path, Object *p_receiver, const StringName &p_receiver_func, const Variant &p_userdata) {
-
ERR_FAIL_NULL(p_receiver);
{
MutexLock lock(preview_mutex);
@@ -406,22 +384,18 @@ void EditorResourcePreview::queue_resource_preview(const String &p_path, Object
}
void EditorResourcePreview::add_preview_generator(const Ref<EditorResourcePreviewGenerator> &p_generator) {
-
preview_generators.push_back(p_generator);
}
void EditorResourcePreview::remove_preview_generator(const Ref<EditorResourcePreviewGenerator> &p_generator) {
-
preview_generators.erase(p_generator);
}
EditorResourcePreview *EditorResourcePreview::get_singleton() {
-
return singleton;
}
void EditorResourcePreview::_bind_methods() {
-
ClassDB::bind_method("_preview_ready", &EditorResourcePreview::_preview_ready);
ClassDB::bind_method(D_METHOD("queue_resource_preview", "path", "receiver", "receiver_func", "userdata"), &EditorResourcePreview::queue_resource_preview);
@@ -434,13 +408,11 @@ void EditorResourcePreview::_bind_methods() {
}
void EditorResourcePreview::check_for_invalidation(const String &p_path) {
-
bool call_invalidated = false;
{
MutexLock lock(preview_mutex);
if (cache.has(p_path)) {
-
uint64_t modified_time = FileAccess::get_modified_time(p_path);
if (modified_time != cache[p_path].modified_time) {
cache.erase(p_path);
@@ -482,6 +454,5 @@ EditorResourcePreview::EditorResourcePreview() {
}
EditorResourcePreview::~EditorResourcePreview() {
-
stop();
}
diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h
index dc5a3b9c93..2f4bc65de9 100644
--- a/editor/editor_resource_preview.h
+++ b/editor/editor_resource_preview.h
@@ -37,7 +37,6 @@
#include "scene/resources/texture.h"
class EditorResourcePreviewGenerator : public Reference {
-
GDCLASS(EditorResourcePreviewGenerator, Reference);
protected:
@@ -55,7 +54,6 @@ public:
};
class EditorResourcePreview : public Node {
-
GDCLASS(EditorResourcePreview, Node);
static EditorResourcePreview *singleton;
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index b4ddb7ebfa..1148a6c7ec 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -35,12 +35,10 @@
#include "servers/display_server.h"
EditorRun::Status EditorRun::get_status() const {
-
return status;
}
Error EditorRun::run(const String &p_scene, const String &p_custom_args, const List<String> &p_breakpoints, const bool &p_skip_breakpoints) {
-
List<String> args;
String resource_path = ProjectSettings::get_singleton()->get_resource_path();
@@ -53,7 +51,7 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
}
args.push_back("--remote-debug");
- args.push_back(remote_host + ":" + String::num(remote_port));
+ args.push_back("tcp://" + remote_host + ":" + String::num(remote_port));
args.push_back("--allow_focus_steal_pid");
args.push_back(itos(OS::get_singleton()->get_process_id()));
@@ -106,7 +104,6 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
test_size.x = ProjectSettings::get_singleton()->get("display/window/size/test_width");
test_size.y = ProjectSettings::get_singleton()->get("display/window/size/test_height");
if (test_size.x > 0 && test_size.y > 0) {
-
desired_size = test_size;
}
@@ -155,14 +152,13 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
}
if (p_breakpoints.size()) {
-
args.push_back("--breakpoints");
String bpoints;
for (const List<String>::Element *E = p_breakpoints.front(); E; E = E->next()) {
-
bpoints += E->get().replace(" ", "%20");
- if (E->next())
+ if (E->next()) {
bpoints += ",";
+ }
}
args.push_back(bpoints);
@@ -187,7 +183,6 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
printf("Running: %ls", exec.c_str());
for (List<String>::Element *E = args.front(); E; E = E->next()) {
-
printf(" %ls", E->get().c_str());
};
printf("\n");
@@ -207,8 +202,9 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L
bool EditorRun::has_child_process(OS::ProcessID p_pid) const {
for (const List<OS::ProcessID>::Element *E = pids.front(); E; E = E->next()) {
- if (E->get() == p_pid)
+ if (E->get() == p_pid) {
return true;
+ }
}
return false;
}
@@ -221,9 +217,7 @@ void EditorRun::stop_child_process(OS::ProcessID p_pid) {
}
void EditorRun::stop() {
-
if (status != STATUS_STOP && pids.size() > 0) {
-
for (List<OS::ProcessID>::Element *E = pids.front(); E; E = E->next()) {
OS::get_singleton()->kill(E->get());
}
@@ -233,6 +227,5 @@ void EditorRun::stop() {
}
EditorRun::EditorRun() {
-
status = STATUS_STOP;
}
diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp
index 464666ac6a..9a834977fd 100644
--- a/editor/editor_run_native.cpp
+++ b/editor/editor_run_native.cpp
@@ -35,21 +35,18 @@
#include "editor_scale.h"
void EditorRunNative::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
for (int i = 0; i < EditorExport::get_singleton()->get_export_platform_count(); i++) {
-
Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(i);
- if (eep.is_null())
+ if (eep.is_null()) {
continue;
+ }
Ref<ImageTexture> icon = eep->get_run_icon();
if (!icon.is_null()) {
Ref<Image> im = icon->get_data();
im = im->duplicate();
im->clear_mipmaps();
if (!im->empty()) {
-
im->resize(16 * EDSCALE, 16 * EDSCALE);
Ref<ImageTexture> small_icon;
small_icon.instance();
@@ -66,13 +63,10 @@ void EditorRunNative::_notification(int p_what) {
}
if (p_what == NOTIFICATION_PROCESS) {
-
bool changed = EditorExport::get_singleton()->poll_export_platforms() || first;
if (changed) {
-
for (Map<int, MenuButton *>::Element *E = menus.front(); E; E = E->next()) {
-
Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(E->key());
MenuButton *mb = E->get();
int dc = eep->get_options_count();
@@ -98,7 +92,6 @@ void EditorRunNative::_notification(int p_what) {
}
void EditorRunNative::_run_native(int p_idx, int p_platform) {
-
if (!EditorNode::get_singleton()->ensure_main_scene(true)) {
resume_idx = p_idx;
resume_platform = p_platform;
@@ -120,7 +113,6 @@ void EditorRunNative::_run_native(int p_idx, int p_platform) {
Ref<EditorExportPreset> preset;
for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
-
Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i);
if (ep->is_runnable() && ep->get_platform() == eep) {
preset = ep;
@@ -133,7 +125,7 @@ void EditorRunNative::_run_native(int p_idx, int p_platform) {
return;
}
- emit_signal("native_run");
+ emit_signal("native_run", preset);
int flags = 0;
@@ -142,14 +134,18 @@ void EditorRunNative::_run_native(int p_idx, int p_platform) {
bool debug_collisions = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_collisons", false);
bool debug_navigation = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_navigation", false);
- if (deploy_debug_remote)
+ if (deploy_debug_remote) {
flags |= EditorExportPlatform::DEBUG_FLAG_REMOTE_DEBUG;
- if (deploy_dumb)
+ }
+ if (deploy_dumb) {
flags |= EditorExportPlatform::DEBUG_FLAG_DUMB_CLIENT;
- if (debug_collisions)
+ }
+ if (debug_collisions) {
flags |= EditorExportPlatform::DEBUG_FLAG_VIEW_COLLISONS;
- if (debug_navigation)
+ }
+ if (debug_navigation) {
flags |= EditorExportPlatform::DEBUG_FLAG_VIEW_NAVIGATION;
+ }
eep->run(preset, p_idx, flags);
}
@@ -159,12 +155,10 @@ void EditorRunNative::resume_run_native() {
}
void EditorRunNative::_bind_methods() {
-
- ADD_SIGNAL(MethodInfo("native_run"));
+ ADD_SIGNAL(MethodInfo("native_run", PropertyInfo(Variant::OBJECT, "preset", PROPERTY_HINT_RESOURCE_TYPE, "EditorExportPreset")));
}
bool EditorRunNative::is_deploy_debug_remote_enabled() const {
-
return EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_deploy_remote_debug", false);
}
diff --git a/editor/editor_run_native.h b/editor/editor_run_native.h
index 5f2236b88c..df6714cb53 100644
--- a/editor/editor_run_native.h
+++ b/editor/editor_run_native.h
@@ -35,7 +35,6 @@
#include "scene/gui/menu_button.h"
class EditorRunNative : public HBoxContainer {
-
GDCLASS(EditorRunNative, HBoxContainer);
Map<int, MenuButton *> menus;
diff --git a/editor/editor_run_script.cpp b/editor/editor_run_script.cpp
index c03fd4f6f5..e2446e92be 100644
--- a/editor/editor_run_script.cpp
+++ b/editor/editor_run_script.cpp
@@ -33,7 +33,6 @@
#include "editor_node.h"
void EditorScript::add_root_node(Node *p_node) {
-
if (!editor) {
EditorNode::add_io_error("EditorScript::add_root_node: " + TTR("Write your logic in the _run() method."));
return;
@@ -48,12 +47,10 @@ void EditorScript::add_root_node(Node *p_node) {
}
EditorInterface *EditorScript::get_editor_interface() {
-
return EditorInterface::get_singleton();
}
Node *EditorScript::get_scene() {
-
if (!editor) {
EditorNode::add_io_error("EditorScript::get_scene: " + TTR("Write your logic in the _run() method."));
return nullptr;
@@ -63,7 +60,6 @@ Node *EditorScript::get_scene() {
}
void EditorScript::_run() {
-
Ref<Script> s = get_script();
ERR_FAIL_COND(!s.is_valid());
if (!get_script_instance()) {
@@ -75,18 +71,15 @@ void EditorScript::_run() {
ce.error = Callable::CallError::CALL_OK;
get_script_instance()->call("_run", nullptr, 0, ce);
if (ce.error != Callable::CallError::CALL_OK) {
-
EditorNode::add_io_error(TTR("Couldn't run script:") + "\n " + s->get_path() + "\n" + TTR("Did you forget the '_run' method?"));
}
}
void EditorScript::set_editor(EditorNode *p_editor) {
-
editor = p_editor;
}
void EditorScript::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_root_node", "node"), &EditorScript::add_root_node);
ClassDB::bind_method(D_METHOD("get_scene"), &EditorScript::get_scene);
ClassDB::bind_method(D_METHOD("get_editor_interface"), &EditorScript::get_editor_interface);
@@ -94,6 +87,5 @@ void EditorScript::_bind_methods() {
}
EditorScript::EditorScript() {
-
editor = nullptr;
}
diff --git a/editor/editor_run_script.h b/editor/editor_run_script.h
index edf75b9e73..261e2a7e41 100644
--- a/editor/editor_run_script.h
+++ b/editor/editor_run_script.h
@@ -35,7 +35,6 @@
#include "editor_plugin.h"
class EditorNode;
class EditorScript : public Reference {
-
GDCLASS(EditorScript, Reference);
EditorNode *editor;
diff --git a/editor/editor_scale.cpp b/editor/editor_scale.cpp
index 358241cbcc..450de75328 100644
--- a/editor/editor_scale.cpp
+++ b/editor/editor_scale.cpp
@@ -35,10 +35,9 @@
static float scale = 1.0;
void editor_set_scale(float p_scale) {
-
scale = p_scale;
}
-float editor_get_scale() {
+float editor_get_scale() {
return scale;
}
diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp
index bccc38ca1b..eabbf6b0d8 100644
--- a/editor/editor_sectioned_inspector.cpp
+++ b/editor/editor_sectioned_inspector.cpp
@@ -29,9 +29,10 @@
/*************************************************************************/
#include "editor_sectioned_inspector.h"
+
#include "editor_scale.h"
-class SectionedInspectorFilter : public Object {
+class SectionedInspectorFilter : public Object {
GDCLASS(SectionedInspectorFilter, Object);
Object *edited;
@@ -39,9 +40,9 @@ class SectionedInspectorFilter : public Object {
bool allow_sub;
bool _set(const StringName &p_name, const Variant &p_value) {
-
- if (!edited)
+ if (!edited) {
return false;
+ }
String name = p_name;
if (section != "") {
@@ -54,9 +55,9 @@ class SectionedInspectorFilter : public Object {
}
bool _get(const StringName &p_name, Variant &r_ret) const {
-
- if (!edited)
+ if (!edited) {
return false;
+ }
String name = p_name;
if (section != "") {
@@ -69,19 +70,19 @@ class SectionedInspectorFilter : public Object {
return valid;
}
void _get_property_list(List<PropertyInfo> *p_list) const {
-
- if (!edited)
+ if (!edited) {
return;
+ }
List<PropertyInfo> pinfo;
edited->get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
PropertyInfo pi = E->get();
int sp = pi.name.find("/");
- if (pi.name == "resource_path" || pi.name == "resource_name" || pi.name == "resource_local_to_scene" || pi.name.begins_with("script/") || pi.name.begins_with("_global_script")) //skip resource stuff
+ if (pi.name == "resource_path" || pi.name == "resource_name" || pi.name == "resource_local_to_scene" || pi.name.begins_with("script/") || pi.name.begins_with("_global_script")) { //skip resource stuff
continue;
+ }
if (sp == -1) {
pi.name = "global/" + pi.name;
@@ -89,33 +90,30 @@ class SectionedInspectorFilter : public Object {
if (pi.name.begins_with(section + "/")) {
pi.name = pi.name.replace_first(section + "/", "");
- if (!allow_sub && pi.name.find("/") != -1)
+ if (!allow_sub && pi.name.find("/") != -1) {
continue;
+ }
p_list->push_back(pi);
}
}
}
bool property_can_revert(const String &p_name) {
-
return edited->call("property_can_revert", section + "/" + p_name);
}
Variant property_get_revert(const String &p_name) {
-
return edited->call("property_get_revert", section + "/" + p_name);
}
protected:
static void _bind_methods() {
-
ClassDB::bind_method("property_can_revert", &SectionedInspectorFilter::property_can_revert);
ClassDB::bind_method("property_get_revert", &SectionedInspectorFilter::property_get_revert);
}
public:
void set_section(const String &p_section, bool p_allow_sub) {
-
section = p_section;
allow_sub = p_allow_sub;
_change_notify();
@@ -132,14 +130,13 @@ public:
};
void SectionedInspector::_bind_methods() {
-
ClassDB::bind_method("update_category_list", &SectionedInspector::update_category_list);
}
void SectionedInspector::_section_selected() {
-
- if (!sections->get_selected())
+ if (!sections->get_selected()) {
return;
+ }
selected_category = sections->get_selected()->get_metadata(0);
filter->set_section(selected_category, sections->get_selected()->get_children() == nullptr);
@@ -147,32 +144,30 @@ void SectionedInspector::_section_selected() {
}
void SectionedInspector::set_current_section(const String &p_section) {
-
if (section_map.has(p_section)) {
section_map[p_section]->select(0);
}
}
String SectionedInspector::get_current_section() const {
-
- if (sections->get_selected())
+ if (sections->get_selected()) {
return sections->get_selected()->get_metadata(0);
- else
+ } else {
return "";
+ }
}
String SectionedInspector::get_full_item_path(const String &p_item) {
-
String base = get_current_section();
- if (base != "")
+ if (base != "") {
return base + "/" + p_item;
- else
+ } else {
return p_item;
+ }
}
void SectionedInspector::edit(Object *p_object) {
-
if (!p_object) {
obj = ObjectID();
sections->clear();
@@ -188,7 +183,6 @@ void SectionedInspector::edit(Object *p_object) {
inspector->set_object_class(p_object->get_class());
if (obj != id) {
-
obj = id;
update_category_list();
@@ -197,26 +191,26 @@ void SectionedInspector::edit(Object *p_object) {
TreeItem *first_item = sections->get_root();
if (first_item) {
- while (first_item->get_children())
+ while (first_item->get_children()) {
first_item = first_item->get_children();
+ }
first_item->select(0);
selected_category = first_item->get_metadata(0);
}
} else {
-
update_category_list();
}
}
void SectionedInspector::update_category_list() {
-
sections->clear();
Object *o = ObjectDB::get_instance(obj);
- if (!o)
+ if (!o) {
return;
+ }
List<PropertyInfo> pinfo;
o->get_property_list(&pinfo);
@@ -227,27 +221,31 @@ void SectionedInspector::update_category_list() {
section_map[""] = root;
String filter;
- if (search_box)
+ if (search_box) {
filter = search_box->get_text();
+ }
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
PropertyInfo pi = E->get();
- if (pi.usage & PROPERTY_USAGE_CATEGORY)
+ if (pi.usage & PROPERTY_USAGE_CATEGORY) {
continue;
- else if (!(pi.usage & PROPERTY_USAGE_EDITOR))
+ } else if (!(pi.usage & PROPERTY_USAGE_EDITOR)) {
continue;
+ }
- if (pi.name.find(":") != -1 || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene" || pi.name.begins_with("_global_script"))
+ if (pi.name.find(":") != -1 || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene" || pi.name.begins_with("_global_script")) {
continue;
+ }
- if (!filter.empty() && !filter.is_subsequence_ofi(pi.name) && !filter.is_subsequence_ofi(pi.name.replace("/", " ").capitalize()))
+ if (!filter.empty() && !filter.is_subsequence_ofi(pi.name) && !filter.is_subsequence_ofi(pi.name.replace("/", " ").capitalize())) {
continue;
+ }
int sp = pi.name.find("/");
- if (sp == -1)
+ if (sp == -1) {
pi.name = "global/" + pi.name;
+ }
Vector<String> sectionarr = pi.name.split("/");
String metasection;
@@ -255,7 +253,6 @@ void SectionedInspector::update_category_list() {
int sc = MIN(2, sectionarr.size() - 1);
for (int i = 0; i < sc; i++) {
-
TreeItem *parent = section_map[metasection];
parent->set_custom_bg_color(0, get_theme_color("prop_subsection", "Editor"));
@@ -288,27 +285,23 @@ void SectionedInspector::update_category_list() {
}
void SectionedInspector::register_search_box(LineEdit *p_box) {
-
search_box = p_box;
inspector->register_text_enter(p_box);
search_box->connect("text_changed", callable_mp(this, &SectionedInspector::_search_changed));
}
void SectionedInspector::_search_changed(const String &p_what) {
-
update_category_list();
}
EditorInspector *SectionedInspector::get_inspector() {
-
return inspector;
}
SectionedInspector::SectionedInspector() :
sections(memnew(Tree)),
filter(memnew(SectionedInspectorFilter)),
- inspector(memnew(EditorInspector)),
- search_box(nullptr) {
+ inspector(memnew(EditorInspector)) {
add_theme_constant_override("autohide", 1); // Fixes the dragger always showing up
VBoxContainer *left_vb = memnew(VBoxContainer);
@@ -333,6 +326,5 @@ SectionedInspector::SectionedInspector() :
}
SectionedInspector::~SectionedInspector() {
-
memdelete(filter);
}
diff --git a/editor/editor_sectioned_inspector.h b/editor/editor_sectioned_inspector.h
index 7073b73751..dfc521302a 100644
--- a/editor/editor_sectioned_inspector.h
+++ b/editor/editor_sectioned_inspector.h
@@ -38,7 +38,6 @@
class SectionedInspectorFilter;
class SectionedInspector : public HSplitContainer {
-
GDCLASS(SectionedInspector, HSplitContainer);
ObjectID obj;
@@ -48,7 +47,7 @@ class SectionedInspector : public HSplitContainer {
Map<String, TreeItem *> section_map;
EditorInspector *inspector;
- LineEdit *search_box;
+ LineEdit *search_box = nullptr;
String selected_category;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 5d5bb1242d..a16605ab44 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -58,7 +58,6 @@ Ref<EditorSettings> EditorSettings::singleton = nullptr;
// Properties
bool EditorSettings::_set(const StringName &p_name, const Variant &p_value) {
-
_THREAD_SAFE_METHOD_
bool changed = _set_only(p_name, p_value);
@@ -69,15 +68,12 @@ bool EditorSettings::_set(const StringName &p_name, const Variant &p_value) {
}
bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value) {
-
_THREAD_SAFE_METHOD_
if (p_name.operator String() == "shortcuts") {
-
Array arr = p_value;
ERR_FAIL_COND_V(arr.size() && arr.size() & 1, true);
for (int i = 0; i < arr.size(); i += 2) {
-
String name = arr[i];
Ref<InputEvent> shortcut = arr[i + 1];
@@ -120,14 +116,11 @@ bool EditorSettings::_set_only(const StringName &p_name, const Variant &p_value)
}
bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const {
-
_THREAD_SAFE_METHOD_
if (p_name.operator String() == "shortcuts") {
-
Array arr;
for (const Map<String, Ref<ShortCut>>::Element *E = shortcuts.front(); E; E = E->next()) {
-
Ref<ShortCut> sc = E->get();
if (optimize_save) {
@@ -136,8 +129,9 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const {
}
Ref<InputEvent> original = sc->get_meta("original");
- if (sc->is_shortcut(original) || (original.is_null() && sc->get_shortcut().is_null()))
+ if (sc->is_shortcut(original) || (original.is_null() && sc->get_shortcut().is_null())) {
continue; //not changed from default, don't save
+ }
}
arr.push_back(E->key());
@@ -163,7 +157,6 @@ void EditorSettings::_initial_set(const StringName &p_name, const Variant &p_val
}
struct _EVCSort {
-
String name;
Variant::Type type;
int order;
@@ -174,18 +167,17 @@ struct _EVCSort {
};
void EditorSettings::_get_property_list(List<PropertyInfo> *p_list) const {
-
_THREAD_SAFE_METHOD_
const String *k = nullptr;
Set<_EVCSort> vclist;
while ((k = props.next(k))) {
-
const VariantContainer *v = props.getptr(*k);
- if (v->hide_from_editor)
+ if (v->hide_from_editor) {
continue;
+ }
_EVCSort vc;
vc.name = *k;
@@ -203,7 +195,6 @@ void EditorSettings::_get_property_list(List<PropertyInfo> *p_list) const {
}
for (Set<_EVCSort>::Element *E = vclist.front(); E; E = E->next()) {
-
int pinfo = 0;
if (E->get().save || !optimize_save) {
pinfo |= PROPERTY_USAGE_STORAGE;
@@ -217,8 +208,9 @@ void EditorSettings::_get_property_list(List<PropertyInfo> *p_list) const {
PropertyInfo pi(E->get().type, E->get().name);
pi.usage = pinfo;
- if (hints.has(E->get().name))
+ if (hints.has(E->get().name)) {
pi = hints[E->get().name];
+ }
if (E->get().restart_if_changed) {
pi.usage |= PROPERTY_USAGE_RESTART_IF_CHANGED;
@@ -231,7 +223,6 @@ void EditorSettings::_get_property_list(List<PropertyInfo> *p_list) const {
}
void EditorSettings::_add_property_info_bind(const Dictionary &p_info) {
-
ERR_FAIL_COND(!p_info.has("name"));
ERR_FAIL_COND(!p_info.has("type"));
@@ -241,26 +232,27 @@ void EditorSettings::_add_property_info_bind(const Dictionary &p_info) {
pinfo.type = Variant::Type(p_info["type"].operator int());
ERR_FAIL_INDEX(pinfo.type, Variant::VARIANT_MAX);
- if (p_info.has("hint"))
+ if (p_info.has("hint")) {
pinfo.hint = PropertyHint(p_info["hint"].operator int());
- if (p_info.has("hint_string"))
+ }
+ if (p_info.has("hint_string")) {
pinfo.hint_string = p_info["hint_string"];
+ }
add_property_hint(pinfo);
}
// Default configs
bool EditorSettings::has_default_value(const String &p_setting) const {
-
_THREAD_SAFE_METHOD_
- if (!props.has(p_setting))
+ if (!props.has(p_setting)) {
return false;
+ }
return props[p_setting].has_default_value;
}
void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
-
_THREAD_SAFE_METHOD_
/* Languages */
@@ -280,7 +272,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
EditorTranslationList *etl = _editor_translations;
while (etl->data) {
-
const String &locale = etl->lang;
// Skip locales which we can't render properly (see above comment).
@@ -559,6 +550,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["editors/3d/navigation_feel/manipulation_translation_inertia"] = PropertyInfo(Variant::FLOAT, "editors/3d/navigation_feel/manipulation_translation_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01");
// 3D: Freelook
+ _initial_set("editors/3d/freelook/freelook_navigation_scheme", false);
+ hints["editors/3d/freelook/freelook_navigation_scheme"] = PropertyInfo(Variant::INT, "editors/3d/freelook/freelook_navigation_scheme", PROPERTY_HINT_ENUM, "Default,Partially Axis-Locked (id Tech),Fully Axis-Locked (Minecraft)");
+ _initial_set("editors/3d/freelook/freelook_sensitivity", 0.4);
+ hints["editors/3d/freelook/freelook_sensitivity"] = PropertyInfo(Variant::FLOAT, "editors/3d/freelook/freelook_sensitivity", PROPERTY_HINT_RANGE, "0.0, 2, 0.01");
_initial_set("editors/3d/freelook/freelook_inertia", 0.1);
hints["editors/3d/freelook/freelook_inertia"] = PropertyInfo(Variant::FLOAT, "editors/3d/freelook/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01");
_initial_set("editors/3d/freelook/freelook_base_speed", 5.0);
@@ -636,24 +631,19 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["project_manager/sorting_order"] = PropertyInfo(Variant::INT, "project_manager/sorting_order", PROPERTY_HINT_ENUM, "Name,Path,Last Edited");
if (p_extra_config.is_valid()) {
-
if (p_extra_config->has_section("init_projects") && p_extra_config->has_section_key("init_projects", "list")) {
-
Vector<String> list = p_extra_config->get_value("init_projects", "list");
for (int i = 0; i < list.size(); i++) {
-
String name = list[i].replace("/", "::");
set("projects/" + name, list[i]);
};
};
if (p_extra_config->has_section("presets")) {
-
List<String> keys;
p_extra_config->get_section_keys("presets", &keys);
for (List<String>::Element *E = keys.front(); E; E = E->next()) {
-
String key = E->get();
Variant val = p_extra_config->get_value("presets", key);
set(key, val);
@@ -663,7 +653,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
}
void EditorSettings::_load_default_text_editor_theme() {
-
bool dark_theme = is_dark_theme();
_initial_set("text_editor/highlighting/symbol_color", Color(0.73, 0.87, 1.0));
@@ -747,7 +736,6 @@ static Dictionary _get_builtin_script_templates() {
}
static void _create_script_templates(const String &p_path) {
-
Dictionary templates = _get_builtin_script_templates();
List<Variant> keys;
templates.get_key_list(&keys);
@@ -771,14 +759,13 @@ static void _create_script_templates(const String &p_path) {
// PUBLIC METHODS
EditorSettings *EditorSettings::get_singleton() {
-
return singleton.ptr();
}
void EditorSettings::create() {
-
- if (singleton.ptr())
+ if (singleton.ptr()) {
return; //pointless
+ }
DirAccess *dir = nullptr;
@@ -811,7 +798,6 @@ void EditorSettings::create() {
memdelete(d);
if (self_contained) {
-
// editor is self contained, all in same folder
data_path = exe_path;
data_dir = data_path.plus_file("editor_data");
@@ -820,7 +806,6 @@ void EditorSettings::create() {
cache_path = exe_path;
cache_dir = data_dir.plus_file("cache");
} else {
-
// Typically XDG_DATA_HOME or %APPDATA%
data_path = OS::get_singleton()->get_data_path();
data_dir = data_path.plus_file(OS::get_singleton()->get_godot_dir_name());
@@ -841,7 +826,6 @@ void EditorSettings::create() {
String config_file_path;
if (data_path != "" && config_path != "" && cache_path != "") {
-
// Validate/create data dir and subdirectories
dir = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
@@ -912,8 +896,9 @@ void EditorSettings::create() {
dir->change_dir("projects");
String project_config_dir = ProjectSettings::get_singleton()->get_resource_path();
- if (project_config_dir.ends_with("/"))
+ if (project_config_dir.ends_with("/")) {
project_config_dir = config_path.substr(0, project_config_dir.size() - 1);
+ }
project_config_dir = project_config_dir.get_file() + "-" + project_config_dir.md5_text();
if (dir->change_dir(project_config_dir) != OK) {
@@ -963,7 +948,6 @@ fail:
if (extra_config->has_section("init_projects")) {
Vector<String> list = extra_config->get_value("init_projects", "list");
for (int i = 0; i < list.size(); i++) {
-
list.write[i] = exe_path.plus_file(list[i]);
};
extra_config->set_value("init_projects", "list", list);
@@ -982,10 +966,10 @@ fail:
}
void EditorSettings::setup_language() {
-
String lang = get("interface/editor/editor_language");
- if (lang == "en")
+ if (lang == "en") {
return; // Default, nothing to do.
+ }
// Load editor translation for configured/detected locale.
EditorTranslationList *etl = _editor_translations;
@@ -1035,7 +1019,6 @@ void EditorSettings::setup_language() {
}
void EditorSettings::setup_network() {
-
List<IP_Address> local_ip;
IP::get_singleton()->get_local_addresses(&local_ip);
String hint;
@@ -1044,20 +1027,23 @@ void EditorSettings::setup_network() {
// Check that current remote_host is a valid interface address and populate hints.
for (List<IP_Address>::Element *E = local_ip.front(); E; E = E->next()) {
-
String ip = E->get();
// link-local IPv6 addresses don't work, skipping them
- if (ip.begins_with("fe80:0:0:0:")) // fe80::/64
+ if (ip.begins_with("fe80:0:0:0:")) { // fe80::/64
continue;
+ }
// Same goes for IPv4 link-local (APIPA) addresses.
- if (ip.begins_with("169.254.")) // 169.254.0.0/16
+ if (ip.begins_with("169.254.")) { // 169.254.0.0/16
continue;
+ }
// Select current IP (found)
- if (ip == current)
+ if (ip == current) {
selected = ip;
- if (hint != "")
+ }
+ if (hint != "") {
hint += ",";
+ }
hint += ip;
}
@@ -1068,11 +1054,11 @@ void EditorSettings::setup_network() {
}
void EditorSettings::save() {
-
//_THREAD_SAFE_METHOD_
- if (!singleton.ptr())
+ if (!singleton.ptr()) {
return;
+ }
if (singleton->config_file_path == "") {
ERR_PRINT("Cannot save EditorSettings config, no valid path");
@@ -1089,15 +1075,14 @@ void EditorSettings::save() {
}
void EditorSettings::destroy() {
-
- if (!singleton.ptr())
+ if (!singleton.ptr()) {
return;
+ }
save();
singleton = Ref<EditorSettings>();
}
void EditorSettings::set_optimize_save(bool p_optimize) {
-
optimize_save = p_optimize;
}
@@ -1114,14 +1099,12 @@ Variant EditorSettings::get_setting(const String &p_setting) const {
}
bool EditorSettings::has_setting(const String &p_setting) const {
-
_THREAD_SAFE_METHOD_
return props.has(p_setting);
}
void EditorSettings::erase(const String &p_setting) {
-
_THREAD_SAFE_METHOD_
props.erase(p_setting);
@@ -1137,17 +1120,18 @@ void EditorSettings::raise_order(const String &p_setting) {
void EditorSettings::set_restart_if_changed(const StringName &p_setting, bool p_restart) {
_THREAD_SAFE_METHOD_
- if (!props.has(p_setting))
+ if (!props.has(p_setting)) {
return;
+ }
props[p_setting].restart_if_changed = p_restart;
}
void EditorSettings::set_initial_value(const StringName &p_setting, const Variant &p_value, bool p_update_current) {
-
_THREAD_SAFE_METHOD_
- if (!props.has(p_setting))
+ if (!props.has(p_setting)) {
return;
+ }
props[p_setting].initial = p_value;
props[p_setting].has_default_value = true;
if (p_update_current) {
@@ -1156,7 +1140,6 @@ void EditorSettings::set_initial_value(const StringName &p_setting, const Varian
}
Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default, bool p_restart_if_changed) {
-
Variant ret = p_default;
if (EditorSettings::get_singleton()->has_setting(p_setting)) {
ret = EditorSettings::get_singleton()->get(p_setting);
@@ -1173,32 +1156,31 @@ Variant _EDITOR_DEF(const String &p_setting, const Variant &p_default, bool p_re
}
Variant _EDITOR_GET(const String &p_setting) {
-
ERR_FAIL_COND_V(!EditorSettings::get_singleton()->has_setting(p_setting), Variant());
return EditorSettings::get_singleton()->get(p_setting);
}
bool EditorSettings::property_can_revert(const String &p_setting) {
-
- if (!props.has(p_setting))
+ if (!props.has(p_setting)) {
return false;
+ }
- if (!props[p_setting].has_default_value)
+ if (!props[p_setting].has_default_value) {
return false;
+ }
return props[p_setting].initial != props[p_setting].variant;
}
Variant EditorSettings::property_get_revert(const String &p_setting) {
-
- if (!props.has(p_setting) || !props[p_setting].has_default_value)
+ if (!props.has(p_setting) || !props[p_setting].has_default_value) {
return Variant();
+ }
return props[p_setting].initial;
}
void EditorSettings::add_property_hint(const PropertyInfo &p_hint) {
-
_THREAD_SAFE_METHOD_
hints[p_hint.name] = p_hint;
@@ -1207,51 +1189,42 @@ void EditorSettings::add_property_hint(const PropertyInfo &p_hint) {
// Data directories
String EditorSettings::get_data_dir() const {
-
return data_dir;
}
String EditorSettings::get_templates_dir() const {
-
return get_data_dir().plus_file("templates");
}
// Config directories
String EditorSettings::get_settings_dir() const {
-
return settings_dir;
}
String EditorSettings::get_project_settings_dir() const {
-
return get_settings_dir().plus_file("projects").plus_file(project_config_dir);
}
String EditorSettings::get_text_editor_themes_dir() const {
-
return get_settings_dir().plus_file("text_editor_themes");
}
String EditorSettings::get_script_templates_dir() const {
-
return get_settings_dir().plus_file("script_templates");
}
String EditorSettings::get_project_script_templates_dir() const {
-
return ProjectSettings::get_singleton()->get("editor/script_templates_search_path");
}
// Cache directory
String EditorSettings::get_cache_dir() const {
-
return cache_dir;
}
String EditorSettings::get_feature_profiles_dir() const {
-
return get_settings_dir().plus_file("feature_profiles");
}
@@ -1279,39 +1252,36 @@ Variant EditorSettings::get_project_metadata(const String &p_section, const Stri
}
void EditorSettings::set_favorites(const Vector<String> &p_favorites) {
-
favorites = p_favorites;
FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorites"), FileAccess::WRITE);
if (f) {
- for (int i = 0; i < favorites.size(); i++)
+ for (int i = 0; i < favorites.size(); i++) {
f->store_line(favorites[i]);
+ }
memdelete(f);
}
}
Vector<String> EditorSettings::get_favorites() const {
-
return favorites;
}
void EditorSettings::set_recent_dirs(const Vector<String> &p_recent_dirs) {
-
recent_dirs = p_recent_dirs;
FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("recent_dirs"), FileAccess::WRITE);
if (f) {
- for (int i = 0; i < recent_dirs.size(); i++)
+ for (int i = 0; i < recent_dirs.size(); i++) {
f->store_line(recent_dirs[i]);
+ }
memdelete(f);
}
}
Vector<String> EditorSettings::get_recent_dirs() const {
-
return recent_dirs;
}
void EditorSettings::load_favorites() {
-
FileAccess *f = FileAccess::open(get_project_settings_dir().plus_file("favorites"), FileAccess::READ);
if (f) {
String line = f->get_line().strip_edges();
@@ -1394,7 +1364,6 @@ void EditorSettings::load_text_editor_theme() {
// don't load if it's not already there!
if (has_setting("text_editor/highlighting/" + key)) {
-
// make sure it is actually a color
if (val.is_valid_html_color() && key.find("color") >= 0) {
props["text_editor/highlighting/" + key].variant = Color::html(val); // change manually to prevent "Settings changed" console spam
@@ -1406,7 +1375,6 @@ void EditorSettings::load_text_editor_theme() {
}
bool EditorSettings::import_text_editor_theme(String p_file) {
-
if (!p_file.ends_with(".tet")) {
return false;
} else {
@@ -1425,7 +1393,6 @@ bool EditorSettings::import_text_editor_theme(String p_file) {
}
bool EditorSettings::save_text_editor_theme() {
-
String p_file = get("text_editor/theme/color_theme");
if (_is_default_text_editor_theme(p_file.get_file().to_lower())) {
@@ -1444,7 +1411,6 @@ bool EditorSettings::save_text_editor_theme_as(String p_file) {
return false;
}
if (_save_text_editor_theme(p_file)) {
-
// switch to theme is saved in the theme directory
list_text_editor_themes();
String theme_name = p_file.substr(0, p_file.length() - 4).get_file();
@@ -1464,7 +1430,6 @@ bool EditorSettings::is_default_text_editor_theme() {
}
Vector<String> EditorSettings::get_script_templates(const String &p_extension, const String &p_custom_path) {
-
Vector<String> templates;
String template_dir = get_script_templates_dir();
if (!p_custom_path.empty()) {
@@ -1487,19 +1452,16 @@ Vector<String> EditorSettings::get_script_templates(const String &p_extension, c
}
String EditorSettings::get_editor_layouts_config() const {
-
return get_settings_dir().plus_file("editor_layouts.cfg");
}
// Shortcuts
void EditorSettings::add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut) {
-
shortcuts[p_name] = p_shortcut;
}
bool EditorSettings::is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const {
-
const Map<String, Ref<ShortCut>>::Element *E = shortcuts.find(p_name);
ERR_FAIL_COND_V_MSG(!E, false, "Unknown Shortcut: " + p_name + ".");
@@ -1507,24 +1469,21 @@ bool EditorSettings::is_shortcut(const String &p_name, const Ref<InputEvent> &p_
}
Ref<ShortCut> EditorSettings::get_shortcut(const String &p_name) const {
-
const Map<String, Ref<ShortCut>>::Element *E = shortcuts.find(p_name);
- if (!E)
+ if (!E) {
return Ref<ShortCut>();
+ }
return E->get();
}
void EditorSettings::get_shortcut_list(List<String> *r_shortcuts) {
-
for (const Map<String, Ref<ShortCut>>::Element *E = shortcuts.front(); E; E = E->next()) {
-
r_shortcuts->push_back(E->key());
}
}
Ref<ShortCut> ED_GET_SHORTCUT(const String &p_path) {
-
if (!EditorSettings::get_singleton()) {
return nullptr;
}
@@ -1542,7 +1501,6 @@ struct ShortCutMapping {
};
Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode) {
-
#ifdef OSX_ENABLED
// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
if (p_keycode == KEY_DELETE) {
@@ -1573,7 +1531,6 @@ Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p
Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
if (sc.is_valid()) {
-
sc->set_name(p_name); //keep name (the ones that come from disk have no name)
sc->set_meta("original", ie); //to compare against changes
return sc;
@@ -1589,7 +1546,6 @@ Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p
}
void EditorSettings::notify_changes() {
-
_THREAD_SAFE_METHOD_
SceneTree *sml = Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop());
@@ -1607,7 +1563,6 @@ void EditorSettings::notify_changes() {
}
void EditorSettings::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("has_setting", "name"), &EditorSettings::has_setting);
ClassDB::bind_method(D_METHOD("set_setting", "name", "value"), &EditorSettings::set_setting);
ClassDB::bind_method(D_METHOD("get_setting", "name"), &EditorSettings::get_setting);
@@ -1634,7 +1589,6 @@ void EditorSettings::_bind_methods() {
}
EditorSettings::EditorSettings() {
-
last_order = 0;
optimize_save = true;
save_changed_setting = true;
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index 29b89ef1a8..13aebb7ea6 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -42,7 +42,6 @@
class EditorPlugin;
class EditorSettings : public Resource {
-
GDCLASS(EditorSettings, Resource);
private:
@@ -50,7 +49,6 @@ private:
public:
struct Plugin {
-
EditorPlugin *instance;
String path;
String name;
@@ -64,27 +62,19 @@ public:
private:
struct VariantContainer {
- int order;
+ int order = 0;
Variant variant;
Variant initial;
- bool has_default_value;
- bool hide_from_editor;
- bool save;
- bool restart_if_changed;
- VariantContainer() :
- order(0),
- has_default_value(false),
- hide_from_editor(false),
- save(false),
- restart_if_changed(false) {
- }
+ bool has_default_value = false;
+ bool hide_from_editor = false;
+ bool save = false;
+ bool restart_if_changed = false;
+
+ VariantContainer() {}
+
VariantContainer(const Variant &p_variant, int p_order) :
order(p_order),
- variant(p_variant),
- has_default_value(false),
- hide_from_editor(false),
- save(false),
- restart_if_changed(false) {
+ variant(p_variant) {
}
};
@@ -148,10 +138,11 @@ public:
void set_initial_value(const StringName &p_setting, const Variant &p_value, bool p_update_current = false);
void set_restart_if_changed(const StringName &p_setting, bool p_restart);
void set_manually(const StringName &p_setting, const Variant &p_value, bool p_emit_signal = false) {
- if (p_emit_signal)
+ if (p_emit_signal) {
_set(p_setting, p_value);
- else
+ } else {
_set_only(p_setting, p_value);
+ }
}
bool property_can_revert(const String &p_setting);
Variant property_get_revert(const String &p_setting);
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index 4eefe844d2..67d92c4839 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -30,12 +30,15 @@
#include "editor_spin_slider.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/math/expression.h"
#include "editor_node.h"
#include "editor_scale.h"
String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const {
+ if (grabber->is_visible()) {
+ return rtos(get_value()) + "\n\n" + TTR("Hold Ctrl to round to integers. Hold Shift for more precise changes.");
+ }
return rtos(get_value());
}
@@ -44,16 +47,14 @@ String EditorSpinSlider::get_text_value() const {
}
void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
-
- if (read_only)
+ if (read_only) {
return;
+ }
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
-
if (mb->get_button_index() == BUTTON_LEFT) {
if (mb->is_pressed()) {
-
if (updown_offset != -1 && mb->get_position().x > updown_offset) {
//there is an updown, so use it.
if (mb->get_position().y < get_size().height / 2) {
@@ -63,21 +64,17 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
}
return;
} else {
-
grabbing_spinner_attempt = true;
grabbing_spinner_dist_cache = 0;
pre_grab_value = get_value();
grabbing_spinner = false;
- grabbing_spinner_mouse_pos = InputFilter::get_singleton()->get_mouse_position();
+ grabbing_spinner_mouse_pos = Input::get_singleton()->get_mouse_position();
}
} else {
-
if (grabbing_spinner_attempt) {
-
if (grabbing_spinner) {
-
- InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
- InputFilter::get_singleton()->warp_mouse_position(grabbing_spinner_mouse_pos);
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ Input::get_singleton()->warp_mouse_position(grabbing_spinner_mouse_pos);
update();
} else {
_focus_entered();
@@ -88,17 +85,15 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
}
}
} else if (mb->get_button_index() == BUTTON_WHEEL_UP || mb->get_button_index() == BUTTON_WHEEL_DOWN) {
-
- if (grabber->is_visible())
+ if (grabber->is_visible()) {
call_deferred("update");
+ }
}
}
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
if (grabbing_spinner_attempt) {
-
double diff_x = mm->get_relative().x;
if (mm->get_shift() && grabbing_spinner) {
diff_x *= 0.1;
@@ -106,12 +101,26 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
grabbing_spinner_dist_cache += diff_x;
if (!grabbing_spinner && ABS(grabbing_spinner_dist_cache) > 4 * EDSCALE) {
- InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_CAPTURED);
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
grabbing_spinner = true;
}
if (grabbing_spinner) {
+ // Don't make the user scroll all the way back to 'in range' if they went off the end.
+ if (pre_grab_value < get_min() && !is_lesser_allowed()) {
+ pre_grab_value = get_min();
+ }
+ if (pre_grab_value > get_max() && !is_greater_allowed()) {
+ pre_grab_value = get_max();
+ }
+
if (mm->get_control()) {
+ // If control was just pressed, don't make the value do a huge jump in magnitude.
+ if (grabbing_spinner_dist_cache != 0) {
+ pre_grab_value += grabbing_spinner_dist_cache * get_step();
+ grabbing_spinner_dist_cache = 0;
+ }
+
set_value(Math::round(pre_grab_value + get_step() * grabbing_spinner_dist_cache * 10));
} else {
set_value(pre_grab_value + get_step() * grabbing_spinner_dist_cache);
@@ -133,12 +142,10 @@ void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
}
void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> mb = p_event;
if (grabbing_grabber) {
if (mb.is_valid()) {
-
if (mb->get_button_index() == BUTTON_WHEEL_UP) {
set_value(get_value() + get_step());
mousewheel_over_grabber = true;
@@ -150,9 +157,7 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
}
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) {
-
if (mb->is_pressed()) {
-
grabbing_grabber = true;
if (!mousewheel_over_grabber) {
grabbing_ratio = get_as_ratio();
@@ -166,8 +171,9 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && grabbing_grabber) {
- if (mousewheel_over_grabber)
+ if (mousewheel_over_grabber) {
return;
+ }
float grabbing_ofs = (grabber->get_transform().xform(mm->get_position()).x - grabbing_from) / float(grabber_range);
set_as_ratio(grabbing_ratio + grabbing_ofs);
@@ -176,12 +182,12 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
}
void EditorSpinSlider::_notification(int p_what) {
-
if (p_what == NOTIFICATION_WM_FOCUS_OUT ||
p_what == NOTIFICATION_WM_FOCUS_IN ||
p_what == NOTIFICATION_EXIT_TREE) {
if (grabbing_spinner) {
- InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
+ grabber->hide();
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
grabbing_spinner = false;
grabbing_spinner_attempt = false;
}
@@ -201,7 +207,6 @@ void EditorSpinSlider::_notification(int p_what) {
}
if (p_what == NOTIFICATION_DRAW) {
-
updown_offset = -1;
Ref<StyleBox> sb = get_theme_stylebox("normal", "LineEdit");
@@ -298,7 +303,7 @@ void EditorSpinSlider::_notification(int p_what) {
grabber->set_position(get_global_position() + grabber_rect.position + grabber_rect.size * 0.5 - grabber->get_size() * 0.5);
if (mousewheel_over_grabber) {
- InputFilter::get_singleton()->warp_mouse_position(grabber->get_position() + grabber_rect.size);
+ Input::get_singleton()->warp_mouse_position(grabber->get_position() + grabber_rect.size);
}
grabber_range = width;
@@ -307,17 +312,15 @@ void EditorSpinSlider::_notification(int p_what) {
}
if (p_what == NOTIFICATION_MOUSE_ENTER) {
-
mouse_over_spin = true;
update();
}
if (p_what == NOTIFICATION_MOUSE_EXIT) {
-
mouse_over_spin = false;
update();
}
if (p_what == NOTIFICATION_FOCUS_ENTER) {
- if ((InputFilter::get_singleton()->is_action_pressed("ui_focus_next") || InputFilter::get_singleton()->is_action_pressed("ui_focus_prev")) && !value_input_just_closed) {
+ if ((Input::get_singleton()->is_action_pressed("ui_focus_next") || Input::get_singleton()->is_action_pressed("ui_focus_prev")) && !value_input_just_closed) {
_focus_entered();
}
value_input_just_closed = false;
@@ -325,7 +328,6 @@ void EditorSpinSlider::_notification(int p_what) {
}
Size2 EditorSpinSlider::get_minimum_size() const {
-
Ref<StyleBox> sb = get_theme_stylebox("normal", "LineEdit");
Ref<Font> font = get_theme_font("font", "LineEdit");
@@ -363,8 +365,9 @@ void EditorSpinSlider::_evaluate_input_text() {
}
Variant v = expr->execute(Array(), nullptr, false);
- if (v.get_type() == Variant::NIL)
+ if (v.get_type() == Variant::NIL) {
return;
+ }
set_value(v);
}
@@ -382,10 +385,10 @@ void EditorSpinSlider::_value_input_closed() {
//focus_exited signal
void EditorSpinSlider::_value_focus_exited() {
-
// discontinue because the focus_exit was caused by right-click context menu
- if (value_input->get_menu()->is_visible())
+ if (value_input->get_menu()->is_visible()) {
return;
+ }
_evaluate_input_text();
// focus is not on the same element after the vlalue_input was exited
@@ -412,7 +415,6 @@ void EditorSpinSlider::_grabber_mouse_exited() {
}
void EditorSpinSlider::set_read_only(bool p_enable) {
-
read_only = p_enable;
update();
}
@@ -422,7 +424,6 @@ bool EditorSpinSlider::is_read_only() const {
}
void EditorSpinSlider::set_flat(bool p_enable) {
-
flat = p_enable;
update();
}
@@ -466,7 +467,6 @@ void EditorSpinSlider::_bind_methods() {
}
EditorSpinSlider::EditorSpinSlider() {
-
flat = false;
grabbing_spinner_attempt = false;
grabbing_spinner = false;
diff --git a/editor/editor_sub_scene.cpp b/editor/editor_sub_scene.cpp
index 1205e0b37c..a9b1a28092 100644
--- a/editor/editor_sub_scene.cpp
+++ b/editor/editor_sub_scene.cpp
@@ -35,13 +35,11 @@
#include "scene/resources/packed_scene.h"
void EditorSubScene::_path_selected(const String &p_path) {
-
path->set_text(p_path);
_path_changed(p_path);
}
void EditorSubScene::_path_changed(const String &p_path) {
-
tree->clear();
if (scene) {
@@ -49,29 +47,30 @@ void EditorSubScene::_path_changed(const String &p_path) {
scene = nullptr;
}
- if (p_path == "")
+ if (p_path == "") {
return;
+ }
Ref<PackedScene> ps = ResourceLoader::load(p_path, "PackedScene");
- if (ps.is_null())
+ if (ps.is_null()) {
return;
+ }
scene = ps->instance();
- if (!scene)
+ if (!scene) {
return;
+ }
_fill_tree(scene, nullptr);
}
void EditorSubScene::_path_browse() {
-
file_dialog->popup_centered_ratio();
}
void EditorSubScene::_notification(int p_what) {
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
if (is_visible() && scene == nullptr) {
_path_browse();
}
@@ -79,7 +78,6 @@ void EditorSubScene::_notification(int p_what) {
}
void EditorSubScene::_fill_tree(Node *p_node, TreeItem *p_parent) {
-
TreeItem *it = tree->create_item(p_parent);
it->set_metadata(0, p_node);
it->set_text(0, p_node->get_name());
@@ -88,10 +86,10 @@ void EditorSubScene::_fill_tree(Node *p_node, TreeItem *p_parent) {
it->set_icon(0, EditorNode::get_singleton()->get_object_icon(p_node, "Node"));
for (int i = 0; i < p_node->get_child_count(); i++) {
-
Node *c = p_node->get_child(i);
- if (c->get_owner() != scene)
+ if (c->get_owner() != scene) {
continue;
+ }
_fill_tree(c, it);
}
}
@@ -114,8 +112,9 @@ void EditorSubScene::_item_multi_selected(Object *p_object, int p_cell, bool p_s
Node *n = item->get_metadata(0);
- if (!n)
+ if (!n) {
return;
+ }
if (p_selected) {
if (n == scene) {
is_root = true;
@@ -125,8 +124,9 @@ void EditorSubScene::_item_multi_selected(Object *p_object, int p_cell, bool p_s
} else {
List<Node *>::Element *E = selection.find(n);
- if (E)
+ if (E) {
selection.erase(E);
+ }
}
}
}
@@ -165,13 +165,10 @@ void EditorSubScene::ok_pressed() {
}
void EditorSubScene::_reown(Node *p_node, List<Node *> *p_to_reown) {
-
if (p_node == scene) {
-
scene->set_filename("");
p_to_reown->push_back(p_node);
} else if (p_node->get_owner() == scene) {
-
p_to_reown->push_back(p_node);
}
@@ -214,18 +211,15 @@ void EditorSubScene::move(Node *p_new_parent, Node *p_new_owner) {
}
void EditorSubScene::clear() {
-
path->set_text("");
_path_changed("");
}
void EditorSubScene::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("subscene_selected"));
}
EditorSubScene::EditorSubScene() {
-
scene = nullptr;
is_root = false;
@@ -262,7 +256,6 @@ EditorSubScene::EditorSubScene() {
ResourceLoader::get_recognized_extensions_for_type("PackedScene", &extensions);
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
-
file_dialog->add_filter("*." + E->get());
}
diff --git a/editor/editor_sub_scene.h b/editor/editor_sub_scene.h
index 5c3b4377d4..cd88805254 100644
--- a/editor/editor_sub_scene.h
+++ b/editor/editor_sub_scene.h
@@ -36,7 +36,6 @@
#include "scene/gui/tree.h"
class EditorSubScene : public ConfirmationDialog {
-
GDCLASS(EditorSubScene, ConfirmationDialog);
List<Node *> selection;
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 576ee436de..ace106cd3e 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -86,7 +86,6 @@ static Ref<StyleBoxLine> make_line_stylebox(Color p_color, int p_thickness = 1,
}
Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float p_scale = EDSCALE, bool p_force_filter = false) {
-
Ref<ImageTexture> icon = memnew(ImageTexture);
Ref<Image> img = memnew(Image);
@@ -106,7 +105,6 @@ Ref<ImageTexture> editor_generate_icon(int p_index, bool p_convert_color, float
#endif
void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme = true, int p_thumb_size = 32, bool p_only_thumbs = false) {
-
#ifdef MODULE_SVG_ENABLED
// The default icon theme is designed to be used for a dark theme.
// This dictionary stores color codes to convert to other colors
@@ -255,7 +253,6 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool p_dark_theme =
}
Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
-
Ref<Theme> theme = Ref<Theme>(memnew(Theme));
const float default_contrast = 0.25;
@@ -337,24 +334,24 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
//Colors
bool dark_theme = EditorSettings::get_singleton()->is_dark_theme();
- const Color dark_color_1 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast);
- const Color dark_color_2 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 1.5);
- const Color dark_color_3 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 2);
+ const Color dark_color_1 = base_color.lerp(Color(0, 0, 0, 1), contrast);
+ const Color dark_color_2 = base_color.lerp(Color(0, 0, 0, 1), contrast * 1.5);
+ const Color dark_color_3 = base_color.lerp(Color(0, 0, 0, 1), contrast * 2);
const Color background_color = dark_color_2;
// white (dark theme) or black (light theme), will be used to generate the rest of the colors
const Color mono_color = dark_theme ? Color(1, 1, 1) : Color(0, 0, 0);
- const Color contrast_color_1 = base_color.linear_interpolate(mono_color, MAX(contrast, default_contrast));
- const Color contrast_color_2 = base_color.linear_interpolate(mono_color, MAX(contrast * 1.5, default_contrast * 1.5));
+ const Color contrast_color_1 = base_color.lerp(mono_color, MAX(contrast, default_contrast));
+ const Color contrast_color_2 = base_color.lerp(mono_color, MAX(contrast * 1.5, default_contrast * 1.5));
- const Color font_color = mono_color.linear_interpolate(base_color, 0.25);
- const Color font_color_hl = mono_color.linear_interpolate(base_color, 0.15);
+ const Color font_color = mono_color.lerp(base_color, 0.25);
+ const Color font_color_hl = mono_color.lerp(base_color, 0.15);
const Color font_color_disabled = Color(mono_color.r, mono_color.g, mono_color.b, 0.3);
const Color font_color_selection = accent_color * Color(1, 1, 1, 0.4);
- const Color color_disabled = mono_color.inverted().linear_interpolate(base_color, 0.7);
- const Color color_disabled_bg = mono_color.inverted().linear_interpolate(base_color, 0.9);
+ const Color color_disabled = mono_color.inverted().lerp(base_color, 0.7);
+ const Color color_disabled_bg = mono_color.inverted().lerp(base_color, 0.9);
Color icon_color_hover = Color(1, 1, 1) * (dark_theme ? 1.15 : 1.45);
icon_color_hover.a = 1.0;
@@ -391,13 +388,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
Color success_color = Color(0.45, 0.95, 0.5);
Color warning_color = Color(1, 0.87, 0.4);
Color error_color = Color(1, 0.47, 0.42);
- Color property_color = font_color.linear_interpolate(Color(0.5, 0.5, 0.5), 0.5);
+ Color property_color = font_color.lerp(Color(0.5, 0.5, 0.5), 0.5);
if (!dark_theme) {
// Darken some colors to be readable on a light background
- success_color = success_color.linear_interpolate(mono_color, 0.35);
- warning_color = warning_color.linear_interpolate(mono_color, 0.35);
- error_color = error_color.linear_interpolate(mono_color, 0.25);
+ success_color = success_color.lerp(mono_color, 0.35);
+ warning_color = warning_color.lerp(mono_color, 0.35);
+ error_color = error_color.lerp(mono_color, 0.25);
}
theme->set_color("success_color", "Editor", success_color);
@@ -434,7 +431,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
editor_register_fonts(theme);
// Highlighted tabs and border width
- Color tab_color = highlight_tabs ? base_color.linear_interpolate(font_color, contrast) : base_color;
+ Color tab_color = highlight_tabs ? base_color.lerp(font_color, contrast) : base_color;
const int border_width = CLAMP(border_size, 0, 3) * EDSCALE;
const int default_margin_size = 4;
@@ -686,7 +683,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("visibility_xray", "PopupMenu", theme->get_icon("GuiVisibilityXray", "EditorIcons"));
theme->set_constant("vseparation", "PopupMenu", (extra_spacing + default_margin_size + 1) * EDSCALE);
- Ref<StyleBoxFlat> sub_inspector_bg = make_flat_stylebox(dark_color_1.linear_interpolate(accent_color, 0.08), 2, 0, 2, 2);
+ Ref<StyleBoxFlat> sub_inspector_bg = make_flat_stylebox(dark_color_1.lerp(accent_color, 0.08), 2, 0, 2, 2);
sub_inspector_bg->set_border_width(MARGIN_LEFT, 2);
sub_inspector_bg->set_border_width(MARGIN_RIGHT, 2);
sub_inspector_bg->set_border_width(MARGIN_BOTTOM, 2);
@@ -763,9 +760,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("title_button_hover", "Tree", style_tree_title);
theme->set_stylebox("title_button_pressed", "Tree", style_tree_title);
- Color prop_category_color = dark_color_1.linear_interpolate(mono_color, 0.12);
- Color prop_section_color = dark_color_1.linear_interpolate(mono_color, 0.09);
- Color prop_subsection_color = dark_color_1.linear_interpolate(mono_color, 0.06);
+ Color prop_category_color = dark_color_1.lerp(mono_color, 0.12);
+ Color prop_section_color = dark_color_1.lerp(mono_color, 0.09);
+ Color prop_subsection_color = dark_color_1.lerp(mono_color, 0.06);
theme->set_color("prop_category", "Editor", prop_category_color);
theme->set_color("prop_section", "Editor", prop_section_color);
theme->set_color("prop_subsection", "Editor", prop_subsection_color);
@@ -1124,7 +1121,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("toggle_hidden", "FileDialog", theme->get_icon("GuiVisibilityVisible", "EditorIcons"));
// Use a different color for folder icons to make them easier to distinguish from files.
// On a light theme, the icon will be dark, so we need to lighten it before blending it with the accent color.
- theme->set_color("folder_icon_modulate", "FileDialog", (dark_theme ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).linear_interpolate(accent_color, 0.7));
+ theme->set_color("folder_icon_modulate", "FileDialog", (dark_theme ? Color(1, 1, 1) : Color(4.25, 4.25, 4.25)).lerp(accent_color, 0.7));
theme->set_color("files_disabled", "FileDialog", font_color_disabled);
// color picker
@@ -1158,13 +1155,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// editor main color
const Color main_color = dark_theme ? Color(0.34, 0.7, 1.0) : Color(0.02, 0.5, 1.0);
- const Color symbol_color = Color(0.34, 0.57, 1.0).linear_interpolate(mono_color, dark_theme ? 0.5 : 0.3);
+ const Color symbol_color = Color(0.34, 0.57, 1.0).lerp(mono_color, dark_theme ? 0.5 : 0.3);
const Color keyword_color = Color(1.0, 0.44, 0.52);
const Color basetype_color = dark_theme ? Color(0.26, 1.0, 0.76) : Color(0.0, 0.76, 0.38);
- const Color type_color = basetype_color.linear_interpolate(mono_color, dark_theme ? 0.4 : 0.3);
- const Color usertype_color = basetype_color.linear_interpolate(mono_color, dark_theme ? 0.7 : 0.5);
+ const Color type_color = basetype_color.lerp(mono_color, dark_theme ? 0.4 : 0.3);
+ const Color usertype_color = basetype_color.lerp(mono_color, dark_theme ? 0.7 : 0.5);
const Color comment_color = dim_color;
- const Color string_color = (dark_theme ? Color(1.0, 0.85, 0.26) : Color(1.0, 0.82, 0.09)).linear_interpolate(mono_color, dark_theme ? 0.5 : 0.3);
+ const Color string_color = (dark_theme ? Color(1.0, 0.85, 0.26) : Color(1.0, 0.82, 0.09)).lerp(mono_color, dark_theme ? 0.5 : 0.3);
const Color te_background_color = dark_theme ? background_color : base_color;
const Color completion_background_color = dark_theme ? base_color : background_color;
@@ -1183,9 +1180,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color current_line_color = alpha1;
const Color line_length_guideline_color = dark_theme ? base_color : background_color;
const Color word_highlighted_color = alpha1;
- const Color number_color = basetype_color.linear_interpolate(mono_color, dark_theme ? 0.5 : 0.3);
+ const Color number_color = basetype_color.lerp(mono_color, dark_theme ? 0.5 : 0.3);
const Color function_color = main_color;
- const Color member_variable_color = main_color.linear_interpolate(mono_color, 0.6);
+ const Color member_variable_color = main_color.lerp(mono_color, 0.6);
const Color mark_color = Color(error_color.r, error_color.g, error_color.b, 0.3);
const Color bookmark_color = Color(0.08, 0.49, 0.98);
const Color breakpoint_color = error_color;
diff --git a/editor/editor_vcs_interface.cpp b/editor/editor_vcs_interface.cpp
index 6f3a8d9ea7..4b13a5dd89 100644
--- a/editor/editor_vcs_interface.cpp
+++ b/editor/editor_vcs_interface.cpp
@@ -33,7 +33,6 @@
EditorVCSInterface *EditorVCSInterface::singleton = nullptr;
void EditorVCSInterface::_bind_methods() {
-
// Proxy end points that act as fallbacks to unavailability of a function in the VCS addon
ClassDB::bind_method(D_METHOD("_initialize", "project_root_path"), &EditorVCSInterface::_initialize);
ClassDB::bind_method(D_METHOD("_is_vcs_initialized"), &EditorVCSInterface::_is_vcs_initialized);
@@ -62,18 +61,15 @@ void EditorVCSInterface::_bind_methods() {
}
bool EditorVCSInterface::_initialize(String p_project_root_path) {
-
WARN_PRINT("Selected VCS addon does not implement an initialization function. This warning will be suppressed.");
return true;
}
bool EditorVCSInterface::_is_vcs_initialized() {
-
return false;
}
Dictionary EditorVCSInterface::_get_modified_files_data() {
-
return Dictionary();
}
@@ -87,96 +83,76 @@ void EditorVCSInterface::_commit(String p_msg) {
}
Array EditorVCSInterface::_get_file_diff(String p_file_path) {
-
return Array();
}
bool EditorVCSInterface::_shut_down() {
-
return false;
}
String EditorVCSInterface::_get_project_name() {
-
return String();
}
String EditorVCSInterface::_get_vcs_name() {
-
return "";
}
bool EditorVCSInterface::initialize(String p_project_root_path) {
-
is_initialized = call("_initialize", p_project_root_path);
return is_initialized;
}
bool EditorVCSInterface::is_vcs_initialized() {
-
return call("_is_vcs_initialized");
}
Dictionary EditorVCSInterface::get_modified_files_data() {
-
return call("_get_modified_files_data");
}
void EditorVCSInterface::stage_file(String p_file_path) {
-
if (is_addon_ready()) {
-
call("_stage_file", p_file_path);
}
}
void EditorVCSInterface::unstage_file(String p_file_path) {
-
if (is_addon_ready()) {
-
call("_unstage_file", p_file_path);
}
}
bool EditorVCSInterface::is_addon_ready() {
-
return is_initialized;
}
void EditorVCSInterface::commit(String p_msg) {
-
if (is_addon_ready()) {
-
call("_commit", p_msg);
}
}
Array EditorVCSInterface::get_file_diff(String p_file_path) {
-
if (is_addon_ready()) {
-
return call("_get_file_diff", p_file_path);
}
return Array();
}
bool EditorVCSInterface::shut_down() {
-
return call("_shut_down");
}
String EditorVCSInterface::get_project_name() {
-
return call("_get_project_name");
}
String EditorVCSInterface::get_vcs_name() {
-
return call("_get_vcs_name");
}
EditorVCSInterface::EditorVCSInterface() {
-
is_initialized = false;
}
@@ -184,11 +160,9 @@ EditorVCSInterface::~EditorVCSInterface() {
}
EditorVCSInterface *EditorVCSInterface::get_singleton() {
-
return singleton;
}
void EditorVCSInterface::set_singleton(EditorVCSInterface *p_singleton) {
-
singleton = p_singleton;
}
diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h
index 85d5e30367..ee9e51441d 100644
--- a/editor/editor_vcs_interface.h
+++ b/editor/editor_vcs_interface.h
@@ -36,7 +36,6 @@
#include "scene/gui/panel_container.h"
class EditorVCSInterface : public Object {
-
GDCLASS(EditorVCSInterface, Object)
bool is_initialized;
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index 7cb18432a7..fb12c15913 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -30,7 +30,7 @@
#include "export_template_manager.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/json.h"
#include "core/io/zip_io.h"
#include "core/os/dir_access.h"
@@ -42,7 +42,6 @@
#include "scene/gui/link_button.h"
void ExportTemplateManager::_update_template_list() {
-
while (current_hb->get_child_count()) {
memdelete(current_hb->get_child(0));
}
@@ -57,7 +56,6 @@ void ExportTemplateManager::_update_template_list() {
Set<String> templates;
d->list_dir_begin();
if (err == OK) {
-
String c = d->get_next();
while (c != String()) {
if (d->current_is_dir() && !c.begins_with(".")) {
@@ -118,7 +116,6 @@ void ExportTemplateManager::_update_template_list() {
}
for (Set<String>::Element *E = templates.back(); E; E = E->prev()) {
-
HBoxContainer *hbc = memnew(HBoxContainer);
Label *version = memnew(Label);
version->set_modulate(current->get_theme_color("disabled_font_color", "Editor"));
@@ -141,7 +138,6 @@ void ExportTemplateManager::_update_template_list() {
}
void ExportTemplateManager::_download_template(const String &p_version) {
-
while (template_list->get_child_count()) {
memdelete(template_list->get_child(0));
}
@@ -155,14 +151,12 @@ void ExportTemplateManager::_download_template(const String &p_version) {
}
void ExportTemplateManager::_uninstall_template(const String &p_version) {
-
remove_confirm->set_text(vformat(TTR("Remove template version '%s'?"), p_version));
remove_confirm->popup_centered();
to_remove = p_version;
}
void ExportTemplateManager::_uninstall_template_confirm() {
-
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
const String &templates_dir = EditorSettings::get_singleton()->get_templates_dir();
Error err = da->change_dir(templates_dir);
@@ -181,7 +175,6 @@ void ExportTemplateManager::_uninstall_template_confirm() {
}
bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_progress) {
-
// unzClose() will take care of closing the file stored in the unzFile,
// so we don't need to `memdelete(fa)` in this method.
FileAccess *fa = nullptr;
@@ -189,7 +182,6 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
unzFile pkg = unzOpen2(p_file.utf8().get_data(), &io);
if (!pkg) {
-
EditorNode::get_singleton()->show_warning(TTR("Can't open export templates zip."));
return false;
}
@@ -200,7 +192,6 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
String contents_dir;
while (ret == UNZ_OK) {
-
unz_file_info info;
char fname[16384];
ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
@@ -208,7 +199,6 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
String file = fname;
if (file.ends_with("version.txt")) {
-
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
@@ -266,7 +256,6 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
fc = 0;
while (ret == UNZ_OK) {
-
//get filename
unz_file_info info;
char fname[16384];
@@ -340,18 +329,15 @@ bool ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_
}
void ExportTemplateManager::popup_manager() {
-
_update_template_list();
popup_centered(Size2(400, 400) * EDSCALE);
}
void ExportTemplateManager::ok_pressed() {
-
template_open->popup_centered_ratio();
}
void ExportTemplateManager::_http_download_mirror_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) {
-
if (p_status != HTTPRequest::RESULT_SUCCESS || p_code != 200) {
EditorNode::get_singleton()->show_warning(TTR("Error getting the list of mirrors."));
return;
@@ -396,10 +382,9 @@ void ExportTemplateManager::_http_download_mirror_completed(int p_status, int p_
return;
}
}
-void ExportTemplateManager::_http_download_templates_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) {
+void ExportTemplateManager::_http_download_templates_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) {
switch (p_status) {
-
case HTTPRequest::RESULT_CANT_RESOLVE: {
template_list_state->set_text(TTR("Can't resolve."));
} break;
@@ -445,8 +430,7 @@ void ExportTemplateManager::_http_download_templates_completed(int p_status, int
}
void ExportTemplateManager::_begin_template_download(const String &p_url) {
-
- if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
OS::get_singleton()->shell_open(p_url);
return;
}
@@ -482,14 +466,12 @@ void ExportTemplateManager::_window_template_downloader_closed() {
}
void ExportTemplateManager::_notification(int p_what) {
-
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
if (!is_visible()) {
set_process(false);
}
}
if (p_what == NOTIFICATION_PROCESS) {
-
update_countdown -= get_process_delta_time();
if (update_countdown > 0) {
@@ -504,18 +486,26 @@ void ExportTemplateManager::_notification(int p_what) {
status = TTR("Disconnected");
errored = true;
break;
- case HTTPClient::STATUS_RESOLVING: status = TTR("Resolving"); break;
+ case HTTPClient::STATUS_RESOLVING:
+ status = TTR("Resolving");
+ break;
case HTTPClient::STATUS_CANT_RESOLVE:
status = TTR("Can't Resolve");
errored = true;
break;
- case HTTPClient::STATUS_CONNECTING: status = TTR("Connecting..."); break;
+ case HTTPClient::STATUS_CONNECTING:
+ status = TTR("Connecting...");
+ break;
case HTTPClient::STATUS_CANT_CONNECT:
status = TTR("Can't Connect");
errored = true;
break;
- case HTTPClient::STATUS_CONNECTED: status = TTR("Connected"); break;
- case HTTPClient::STATUS_REQUESTING: status = TTR("Requesting..."); break;
+ case HTTPClient::STATUS_CONNECTED:
+ status = TTR("Connected");
+ break;
+ case HTTPClient::STATUS_REQUESTING:
+ status = TTR("Requesting...");
+ break;
case HTTPClient::STATUS_BODY:
status = TTR("Downloading");
if (download_templates->get_body_size() > 0) {
@@ -544,13 +534,11 @@ void ExportTemplateManager::_notification(int p_what) {
}
bool ExportTemplateManager::can_install_android_template() {
-
const String templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG);
return FileAccess::exists(templates_dir.plus_file("android_source.zip"));
}
Error ExportTemplateManager::install_android_template() {
-
// To support custom Android builds, we install the Java source code and buildsystem
// from android_source.zip to the project's res://android folder.
@@ -607,7 +595,6 @@ Error ExportTemplateManager::install_android_template() {
Set<String> dirs_tested;
int idx = 0;
while (ret == UNZ_OK) {
-
// Get file path.
unz_file_info info;
char fpath[16384];
@@ -659,7 +646,6 @@ void ExportTemplateManager::_bind_methods() {
}
ExportTemplateManager::ExportTemplateManager() {
-
VBoxContainer *main_vb = memnew(VBoxContainer);
add_child(main_vb);
diff --git a/editor/fileserver/editor_file_server.cpp b/editor/fileserver/editor_file_server.cpp
index fb44c145b2..7e05bc5d88 100644
--- a/editor/fileserver/editor_file_server.cpp
+++ b/editor/fileserver/editor_file_server.cpp
@@ -40,7 +40,6 @@
#define DEBUG_TIME(m_what)
void EditorFileServer::_close_client(ClientData *cd) {
-
cd->connection->disconnect_from_host();
{
MutexLock lock(cd->efs->wait_mutex);
@@ -54,7 +53,6 @@ void EditorFileServer::_close_client(ClientData *cd) {
}
void EditorFileServer::_subthread_start(void *s) {
-
ClientData *cd = (ClientData *)s;
cd->connection->set_no_delay(true);
@@ -68,11 +66,9 @@ void EditorFileServer::_subthread_start(void *s) {
int passlen = decode_uint32(buf4);
if (passlen > 512) {
-
_close_client(cd);
ERR_FAIL_COND(passlen > 512);
} else if (passlen > 0) {
-
Vector<char> passutf8;
passutf8.resize(passlen + 1);
err = cd->connection->get_data((uint8_t *)passutf8.ptr(), passlen);
@@ -106,7 +102,6 @@ void EditorFileServer::_subthread_start(void *s) {
cd->connection->put_data(buf4, 4);
while (!cd->quit) {
-
//wait for ID
err = cd->connection->get_data(buf4, 4);
DEBUG_TIME("get_data")
@@ -126,11 +121,9 @@ void EditorFileServer::_subthread_start(void *s) {
int cmd = decode_uint32(buf4);
switch (cmd) {
-
case FileAccessNetwork::COMMAND_FILE_EXISTS:
case FileAccessNetwork::COMMAND_GET_MODTIME:
case FileAccessNetwork::COMMAND_OPEN_FILE: {
-
DEBUG_TIME("open_file")
err = cd->connection->get_data(buf4, 4);
if (err != OK) {
@@ -161,14 +154,12 @@ void EditorFileServer::_subthread_start(void *s) {
}
if (!s2.begins_with("res://")) {
-
_close_client(cd);
ERR_FAIL_COND(!s2.begins_with("res://"));
}
ERR_CONTINUE(cd->files.has(id));
if (cmd == FileAccessNetwork::COMMAND_FILE_EXISTS) {
-
encode_uint32(id, buf4);
cd->connection->put_data(buf4, 4);
encode_uint32(FileAccessNetwork::RESPONSE_FILE_EXISTS, buf4);
@@ -180,7 +171,6 @@ void EditorFileServer::_subthread_start(void *s) {
}
if (cmd == FileAccessNetwork::COMMAND_GET_MODTIME) {
-
encode_uint32(id, buf4);
cd->connection->put_data(buf4, 4);
encode_uint32(FileAccessNetwork::RESPONSE_GET_MODTIME, buf4);
@@ -218,7 +208,6 @@ void EditorFileServer::_subthread_start(void *s) {
} break;
case FileAccessNetwork::COMMAND_READ_BLOCK: {
-
err = cd->connection->get_data(buf4, 8);
if (err != OK) {
_close_client(cd);
@@ -259,7 +248,6 @@ void EditorFileServer::_subthread_start(void *s) {
} break;
case FileAccessNetwork::COMMAND_CLOSE: {
-
print_verbose("CLOSED");
ERR_CONTINUE(!cd->files.has(id));
memdelete(cd->files[id]);
@@ -272,10 +260,8 @@ void EditorFileServer::_subthread_start(void *s) {
}
void EditorFileServer::_thread_start(void *s) {
-
EditorFileServer *self = (EditorFileServer *)s;
while (!self->quit) {
-
if (self->cmd == CMD_ACTIVATE) {
self->server->listen(self->port);
self->active = true;
@@ -312,7 +298,6 @@ void EditorFileServer::_thread_start(void *s) {
}
void EditorFileServer::start() {
-
stop();
port = EDITOR_DEF("filesystem/file_server/port", 6010);
password = EDITOR_DEF("filesystem/file_server/password", "");
@@ -320,17 +305,14 @@ void EditorFileServer::start() {
}
bool EditorFileServer::is_active() const {
-
return active;
}
void EditorFileServer::stop() {
-
cmd = CMD_STOP;
}
EditorFileServer::EditorFileServer() {
-
server.instance();
quit = false;
active = false;
@@ -342,7 +324,6 @@ EditorFileServer::EditorFileServer() {
}
EditorFileServer::~EditorFileServer() {
-
quit = true;
Thread::wait_to_finish(thread);
memdelete(thread);
diff --git a/editor/fileserver/editor_file_server.h b/editor/fileserver/editor_file_server.h
index cc3cb44566..9645fbf39e 100644
--- a/editor/fileserver/editor_file_server.h
+++ b/editor/fileserver/editor_file_server.h
@@ -38,7 +38,6 @@
#include "core/os/thread.h"
class EditorFileServer : public Object {
-
GDCLASS(EditorFileServer, Object);
enum Command {
@@ -48,7 +47,6 @@ class EditorFileServer : public Object {
};
struct ClientData {
-
Thread *thread;
Ref<StreamPeerTCP> connection;
Map<int, FileAccess *> files;
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index 236ae16ccf..4fdc3dc080 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -63,8 +63,9 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
// Create a tree item for the subdirectory.
TreeItem *subdirectory_item = tree->create_item(p_parent);
String dname = p_dir->get_name();
- if (dname == "")
+ if (dname == "") {
dname = "res://";
+ }
subdirectory_item->set_text(0, dname);
subdirectory_item->set_icon(0, get_theme_icon("Folder", "EditorIcons"));
@@ -86,14 +87,14 @@ bool FileSystemDock::_create_tree(TreeItem *p_parent, EditorFileSystemDirectory
}
// Create items for all subdirectories.
- for (int i = 0; i < p_dir->get_subdir_count(); i++)
+ for (int i = 0; i < p_dir->get_subdir_count(); i++) {
parent_should_expand = (_create_tree(subdirectory_item, p_dir->get_subdir(i), uncollapsed_paths, p_select_in_favorites, p_unfold_path) || parent_should_expand);
+ }
// Create all items for the files in the subdirectory.
if (display_mode == DISPLAY_MODE_TREE_ONLY) {
String main_scene = ProjectSettings::get_singleton()->get("application/run/main_scene");
for (int i = 0; i < p_dir->get_file_count(); i++) {
-
String file_type = p_dir->get_file_type(i);
if (_is_file_type_disabled_by_feature_profile(file_type)) {
@@ -196,8 +197,9 @@ void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, boo
Vector<String> favorite_paths = EditorSettings::get_singleton()->get_favorites();
for (int i = 0; i < favorite_paths.size(); i++) {
String fave = favorite_paths[i];
- if (!fave.begins_with("res://"))
+ if (!fave.begins_with("res://")) {
continue;
+ }
Ref<Texture2D> folder_icon = get_theme_icon("Folder", "EditorIcons");
const Color folder_color = get_theme_color("folder_icon_modulate", "FileDialog");
@@ -298,8 +300,9 @@ void FileSystemDock::_update_display_mode(bool p_force) {
void FileSystemDock::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
- if (initialized)
+ if (initialized) {
return;
+ }
initialized = true;
EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &FileSystemDock::_feature_profile_changed));
@@ -350,8 +353,9 @@ void FileSystemDock::_notification(int p_what) {
Dictionary dd = get_viewport()->gui_get_drag_data();
if (tree->is_visible_in_tree() && dd.has("type")) {
if (dd.has("favorite")) {
- if ((String(dd["favorite"]) == "all"))
+ if ((String(dd["favorite"]) == "all")) {
tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN);
+ }
} else if ((String(dd["type"]) == "files") || (String(dd["type"]) == "files_and_dirs") || (String(dd["type"]) == "resource")) {
tree->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM | Tree::DROP_MODE_INBETWEEN);
}
@@ -405,13 +409,15 @@ void FileSystemDock::_tree_multi_selected(Object *p_item, int p_column, bool p_s
call_deferred("_update_import_dock");
// Return if we don't select something new.
- if (!p_selected)
+ if (!p_selected) {
return;
+ }
// Tree item selected.
TreeItem *selected = tree->get_selected();
- if (!selected)
+ if (!selected) {
return;
+ }
TreeItem *favorites_item = tree->get_root()->get_children();
if (selected->get_parent() == favorites_item && !String(selected->get_metadata(0)).ends_with("/")) {
@@ -433,10 +439,11 @@ void FileSystemDock::_tree_multi_selected(Object *p_item, int p_column, bool p_s
}
String FileSystemDock::get_selected_path() const {
- if (path.ends_with("/"))
+ if (path.ends_with("/")) {
return path;
- else
+ } else {
return path.get_base_dir();
+ }
}
String FileSystemDock::get_current_path() const {
@@ -505,8 +512,9 @@ void FileSystemDock::_file_list_thumbnail_done(const String &p_path, const Ref<T
String file = uarr[1];
if (idx < files->get_item_count() && files->get_item_text(idx) == file && files->get_item_metadata(idx) == p_path) {
if (file_list_display_mode == FILE_LIST_DISPLAY_LIST) {
- if (p_small_preview.is_valid())
+ if (p_small_preview.is_valid()) {
files->set_item_icon(idx, p_small_preview);
+ }
} else {
files->set_item_icon(idx, p_preview);
}
@@ -554,7 +562,6 @@ bool FileSystemDock::_is_file_type_disabled_by_feature_profile(const StringName
StringName class_name = p_class;
while (class_name != StringName()) {
-
if (profile->is_class_disabled(class_name)) {
return true;
}
@@ -565,8 +572,9 @@ bool FileSystemDock::_is_file_type_disabled_by_feature_profile(const StringName
}
void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> *matches, int p_max_items) {
- if (matches->size() > p_max_items)
+ if (matches->size() > p_max_items) {
return;
+ }
for (int i = 0; i < p_path->get_subdir_count(); i++) {
_search(p_path->get_subdir(i), matches, p_max_items);
@@ -576,7 +584,6 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> *
String file = p_path->get_file(i);
if (file.to_lower().find(searched_string) != -1) {
-
FileInfo fi;
fi.name = file;
fi.type = p_path->get_file_type(i);
@@ -589,8 +596,9 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path, List<FileInfo> *
}
matches->push_back(fi);
- if (matches->size() > p_max_items)
+ if (matches->size() > p_max_items) {
return;
+ }
}
}
}
@@ -600,8 +608,9 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
Set<String> cselection;
if (p_keep_selection) {
for (int i = 0; i < files->get_item_count(); i++) {
- if (files->is_selected(i))
+ if (files->is_selected(i)) {
cselection.insert(files->get_item_text(i));
+ }
}
}
@@ -704,8 +713,9 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
file = path.get_file();
efd = EditorFileSystem::get_singleton()->get_filesystem_path(directory);
}
- if (!efd)
+ if (!efd) {
return;
+ }
if (searched_string.length() > 0) {
// Display the search results.
@@ -717,8 +727,9 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
files->add_item("..", folder_icon, true);
String bd = directory.get_base_dir();
- if (bd != "res://" && !bd.ends_with("/"))
+ if (bd != "res://" && !bd.ends_with("/")) {
bd += "/";
+ }
files->set_item_metadata(files->get_item_count() - 1, bd);
files->set_item_selectable(files->get_item_count() - 1, false);
@@ -804,8 +815,9 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) {
}
// Select the items.
- if (cselection.has(fname))
+ if (cselection.has(fname)) {
files->select(item_index, false);
+ }
if (!p_keep_selection && file != "" && fname == file) {
files->select(item_index, true);
@@ -860,9 +872,7 @@ void FileSystemDock::_file_list_activate_file(int p_idx) {
void FileSystemDock::_preview_invalidated(const String &p_path) {
if (file_list_display_mode == FILE_LIST_DISPLAY_THUMBNAILS && p_path.get_base_dir() == path && searched_string.length() == 0 && file_list_vb->is_visible_in_tree()) {
-
for (int i = 0; i < files->get_item_count(); i++) {
-
if (files->get_item_metadata(i) == p_path) {
// Re-request preview.
Array udata;
@@ -907,15 +917,17 @@ void FileSystemDock::_set_scanning_mode() {
}
void FileSystemDock::_fw_history() {
- if (history_pos < history.size() - 1)
+ if (history_pos < history.size() - 1) {
history_pos++;
+ }
_update_history();
}
void FileSystemDock::_bw_history() {
- if (history_pos > 0)
+ if (history_pos > 0) {
history_pos--;
+ }
_update_history();
}
@@ -955,8 +967,9 @@ void FileSystemDock::_push_to_history() {
}
void FileSystemDock::_get_all_items_in_dir(EditorFileSystemDirectory *efsd, Vector<String> &files, Vector<String> &folders) const {
- if (efsd == nullptr)
+ if (efsd == nullptr) {
return;
+ }
for (int i = 0; i < efsd->get_subdir_count(); i++) {
folders.push_back(efsd->get_subdir(i)->get_path());
@@ -1111,8 +1124,9 @@ void FileSystemDock::_update_resource_paths_after_move(const Map<String, String>
for (int i = 0; i < EditorNode::get_editor_data().get_edited_scene_count(); i++) {
String path;
if (i == EditorNode::get_editor_data().get_edited_scene()) {
- if (!get_tree()->get_edited_scene_root())
+ if (!get_tree()->get_edited_scene_root()) {
continue;
+ }
path = get_tree()->get_edited_scene_root()->get_filename();
} else {
@@ -1143,8 +1157,9 @@ void FileSystemDock::_update_dependencies_after_move(const Map<String, String> &
print_verbose("Remapping dependencies for: " + file);
Error err = ResourceLoader::rename_dependencies(file, p_renames);
if (err == OK) {
- if (ResourceLoader::get_resource_type(file) == "PackedScene")
+ if (ResourceLoader::get_resource_type(file) == "PackedScene") {
editor->reload_scene(file);
+ }
} else {
EditorNode::get_singleton()->add_io_error(TTR("Unable to update dependencies:") + "\n" + remaps[i] + "\n");
}
@@ -1272,8 +1287,9 @@ void FileSystemDock::_make_scene_confirm() {
break;
}
}
- if (!extension_correct)
+ if (!extension_correct) {
scene_name = scene_name.get_basename() + ".tscn";
+ }
scene_name = directory.plus_file(scene_name);
@@ -1626,8 +1642,9 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
}
EditorSettings::get_singleton()->set_favorites(favorites);
_update_tree(_compute_uncollapsed_paths());
- if (path == "Favorites")
+ if (path == "Favorites") {
_update_file_list(true);
+ }
} break;
case FILE_DEPENDENCIES: {
@@ -1728,7 +1745,6 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected
} break;
case FILE_INFO: {
-
} break;
case FILE_REIMPORT: {
@@ -1813,10 +1829,11 @@ void FileSystemDock::_search_changed(const String &p_text, const Control *p_from
searched_string = p_text.to_lower();
- if (p_from == tree_search_box)
+ if (p_from == tree_search_box) {
file_list_search_box->set_text(searched_string);
- else // File_list_search_box.
+ } else { // File_list_search_box.
tree_search_box->set_text(searched_string);
+ }
bool unfold_path = (p_text == String() && path != String());
switch (display_mode) {
@@ -1849,8 +1866,9 @@ void FileSystemDock::focus_on_filter() {
}
void FileSystemDock::set_file_list_display_mode(FileListDisplayMode p_mode) {
- if (p_mode == file_list_display_mode)
+ if (p_mode == file_list_display_mode) {
return;
+ }
_toggle_file_display();
}
@@ -1891,8 +1909,9 @@ Variant FileSystemDock::get_drag_data_fw(const Point2 &p_point, Control *p_from)
all_not_favorites = true;
}
- if (paths.empty())
+ if (paths.empty()) {
return Variant();
+ }
Dictionary drag_data = EditorNode::get_singleton()->drag_files_and_dirs(paths, p_from);
if (!all_not_favorites) {
@@ -1905,15 +1924,15 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da
Dictionary drag_data = p_data;
if (drag_data.has("favorite")) {
-
if (String(drag_data["favorite"]) != "all") {
return false;
}
// Moving favorite around.
TreeItem *ti = tree->get_item_at_position(p_point);
- if (!ti)
+ if (!ti) {
return false;
+ }
int drop_section = tree->get_drop_section_at_position(p_point);
TreeItem *favorites_item = tree->get_root()->get_children();
@@ -1947,19 +1966,22 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da
bool favorite;
_get_drag_target_folder(to_dir, favorite, p_point, p_from);
- if (favorite)
+ if (favorite) {
return true;
+ }
- if (to_dir.empty())
+ if (to_dir.empty()) {
return false;
+ }
// Attempting to move a folder into itself will fail later,
// rather than bring up a message don't try to do it in the first place.
to_dir = to_dir.ends_with("/") ? to_dir : (to_dir + "/");
Vector<String> fnames = drag_data["files"];
for (int i = 0; i < fnames.size(); ++i) {
- if (fnames[i].ends_with("/") && to_dir.begins_with(fnames[i]))
+ if (fnames[i].ends_with("/") && to_dir.begins_with(fnames[i])) {
return false;
+ }
}
return true;
@@ -1969,21 +1991,22 @@ bool FileSystemDock::can_drop_data_fw(const Point2 &p_point, const Variant &p_da
}
void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
- if (!can_drop_data_fw(p_point, p_data, p_from))
+ if (!can_drop_data_fw(p_point, p_data, p_from)) {
return;
+ }
Dictionary drag_data = p_data;
Vector<String> dirs = EditorSettings::get_singleton()->get_favorites();
if (drag_data.has("favorite")) {
-
if (String(drag_data["favorite"]) != "all") {
return;
}
// Moving favorite around.
TreeItem *ti = tree->get_item_at_position(p_point);
- if (!ti)
+ if (!ti) {
return;
+ }
int drop_section = tree->get_drop_section_at_position(p_point);
int drop_position;
@@ -2030,8 +2053,9 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
EditorSettings::get_singleton()->set_favorites(dirs);
_update_tree(_compute_uncollapsed_paths());
- if (display_mode == DISPLAY_MODE_SPLIT && path == "Favorites")
+ if (display_mode == DISPLAY_MODE_SPLIT && path == "Favorites") {
_update_file_list(true);
+ }
return;
}
@@ -2290,8 +2314,9 @@ void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) {
// Right click is pressed in the file list.
Vector<String> paths;
for (int i = 0; i < files->get_item_count(); i++) {
- if (!files->is_selected(i))
+ if (!files->is_selected(i)) {
continue;
+ }
if (files->get_item_text(p_item) == "..") {
files->unselect(i);
continue;
@@ -2311,8 +2336,9 @@ void FileSystemDock::_file_list_rmb_select(int p_item, const Vector2 &p_pos) {
void FileSystemDock::_file_list_rmb_pressed(const Vector2 &p_pos) {
// Right click on empty space for file list.
- if (searched_string.length() > 0)
+ if (searched_string.length() > 0) {
return;
+ }
file_list_popup->clear();
file_list_popup->set_size(Size2(1, 1));
@@ -2350,7 +2376,6 @@ void FileSystemDock::_file_multi_selected(int p_index, bool p_selected) {
}
void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) {
-
Ref<InputEventKey> key = p_event;
if (key.is_valid() && key->is_pressed() && !key->is_echo()) {
if (ED_IS_SHORTCUT("filesystem_dock/duplicate", p_event)) {
@@ -2366,7 +2391,6 @@ void FileSystemDock::_tree_gui_input(Ref<InputEvent> p_event) {
}
void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) {
-
Ref<InputEventKey> key = p_event;
if (key.is_valid() && key->is_pressed() && !key->is_echo()) {
if (ED_IS_SHORTCUT("filesystem_dock/duplicate", p_event)) {
@@ -2382,8 +2406,9 @@ void FileSystemDock::_file_list_gui_input(Ref<InputEvent> p_event) {
}
void FileSystemDock::_update_import_dock() {
- if (!import_dock_needs_update)
+ if (!import_dock_needs_update) {
return;
+ }
// List selected.
Vector<String> selected;
@@ -2394,8 +2419,9 @@ void FileSystemDock::_update_import_dock() {
} else {
// Use the file list.
for (int i = 0; i < files->get_item_count(); i++) {
- if (!files->is_selected(i))
+ if (!files->is_selected(i)) {
continue;
+ }
selected.push_back(files->get_item_metadata(i));
}
@@ -2451,7 +2477,6 @@ void FileSystemDock::_feature_profile_changed() {
}
void FileSystemDock::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_update_tree"), &FileSystemDock::_update_tree);
ClassDB::bind_method(D_METHOD("_file_list_thumbnail_done"), &FileSystemDock::_file_list_thumbnail_done);
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index 6d2d8510d1..08c2124ae8 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -148,11 +148,9 @@ private:
class FileOrFolder {
public:
String path;
- bool is_file;
+ bool is_file = false;
- FileOrFolder() :
- path(""),
- is_file(false) {}
+ FileOrFolder() {}
FileOrFolder(const String &p_path, bool p_is_file) :
path(p_path),
is_file(p_is_file) {}
diff --git a/editor/find_in_files.cpp b/editor/find_in_files.cpp
index d73180c831..1bc0de1ab0 100644
--- a/editor/find_in_files.cpp
+++ b/editor/find_in_files.cpp
@@ -59,14 +59,14 @@ static bool is_text_char(CharType c) {
}
static bool find_next(const String &line, String pattern, int from, bool match_case, bool whole_words, int &out_begin, int &out_end) {
-
int end = from;
while (true) {
int begin = match_case ? line.find(pattern, end) : line.findn(pattern, end);
- if (begin == -1)
+ if (begin == -1) {
return false;
+ }
end = begin + pattern.length();
out_begin = begin;
@@ -157,15 +157,14 @@ void FindInFiles::_process() {
while (is_processing()) {
_iterate();
float elapsed = (os.get_ticks_msec() - time_before);
- if (elapsed > 1000.0 / 120.0)
+ if (elapsed > 1000.0 / 120.0) {
break;
+ }
}
}
void FindInFiles::_iterate() {
-
if (_folders_stack.size() != 0) {
-
// Scan folders first so we can build a list of files and have progress info later
PackedStringArray &folders_to_scan = _folders_stack.write[_folders_stack.size() - 1];
@@ -196,7 +195,6 @@ void FindInFiles::_iterate() {
}
} else if (_files_to_scan.size() != 0) {
-
// Then scan files
String fpath = _files_to_scan[_files_to_scan.size() - 1];
@@ -220,7 +218,6 @@ float FindInFiles::get_progress() const {
}
void FindInFiles::_scan_dir(String path, PackedStringArray &out_folders) {
-
DirAccessRef dir = DirAccess::open(path);
if (!dir) {
print_verbose("Cannot open directory! " + path);
@@ -232,19 +229,22 @@ void FindInFiles::_scan_dir(String path, PackedStringArray &out_folders) {
for (int i = 0; i < 1000; ++i) {
String file = dir->get_next();
- if (file == "")
+ if (file == "") {
break;
+ }
// Ignore special dirs (such as .git and .import)
- if (file == "." || file == ".." || file.begins_with("."))
+ if (file == "." || file == ".." || file.begins_with(".")) {
continue;
- if (dir->current_is_hidden())
+ }
+ if (dir->current_is_hidden()) {
continue;
+ }
- if (dir->current_is_dir())
+ if (dir->current_is_dir()) {
out_folders.push_back(file);
- else {
+ } else {
String file_ext = file.get_extension();
if (_extension_filter.has(file_ext)) {
_files_to_scan.push_back(path.plus_file(file));
@@ -254,7 +254,6 @@ void FindInFiles::_scan_dir(String path, PackedStringArray &out_folders) {
}
void FindInFiles::_scan_file(String fpath) {
-
FileAccessRef f = FileAccess::open(fpath, FileAccess::READ);
if (!f) {
print_verbose(String("Cannot open file ") + fpath);
@@ -264,7 +263,6 @@ void FindInFiles::_scan_file(String fpath) {
int line_number = 0;
while (!f->eof_reached()) {
-
// line number starts at 1
++line_number;
@@ -282,7 +280,6 @@ void FindInFiles::_scan_file(String fpath) {
}
void FindInFiles::_bind_methods() {
-
ADD_SIGNAL(MethodInfo(SIGNAL_RESULT_FOUND,
PropertyInfo(Variant::STRING, "path"),
PropertyInfo(Variant::INT, "line_number"),
@@ -298,7 +295,6 @@ const char *FindInFilesDialog::SIGNAL_FIND_REQUESTED = "find_requested";
const char *FindInFilesDialog::SIGNAL_REPLACE_REQUESTED = "replace_requested";
FindInFilesDialog::FindInFilesDialog() {
-
set_min_size(Size2(500 * EDSCALE, 0));
set_title(TTR("Find in Files"));
@@ -408,9 +404,9 @@ void FindInFilesDialog::set_replace_text(String text) {
}
void FindInFilesDialog::set_find_in_files_mode(FindInFilesMode p_mode) {
-
- if (_mode == p_mode)
+ if (_mode == p_mode) {
return;
+ }
_mode = p_mode;
@@ -464,7 +460,6 @@ Set<String> FindInFilesDialog::get_filter() const {
void FindInFilesDialog::_notification(int p_what) {
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
if (is_visible()) {
// Doesn't work more than once if not deferred...
_search_text_line_edit->call_deferred("grab_focus");
@@ -506,7 +501,6 @@ void FindInFilesDialog::custom_action(const String &p_action) {
}
void FindInFilesDialog::_on_search_text_modified(String text) {
-
ERR_FAIL_COND(!_find_button);
ERR_FAIL_COND(!_replace_button);
@@ -540,13 +534,13 @@ void FindInFilesDialog::_on_replace_text_entered(String text) {
void FindInFilesDialog::_on_folder_selected(String path) {
int i = path.find("://");
- if (i != -1)
+ if (i != -1) {
path = path.right(i + 3);
+ }
_folder_line_edit->set_text(path);
}
void FindInFilesDialog::_bind_methods() {
-
ADD_SIGNAL(MethodInfo(SIGNAL_FIND_REQUESTED));
ADD_SIGNAL(MethodInfo(SIGNAL_REPLACE_REQUESTED));
}
@@ -556,7 +550,6 @@ const char *FindInFilesPanel::SIGNAL_RESULT_SELECTED = "result_selected";
const char *FindInFilesPanel::SIGNAL_FILES_MODIFIED = "files_modified";
FindInFilesPanel::FindInFilesPanel() {
-
_finder = memnew(FindInFiles);
_finder->connect(FindInFiles::SIGNAL_RESULT_FOUND, callable_mp(this, &FindInFilesPanel::_on_result_found));
_finder->connect(FindInFiles::SIGNAL_FINISHED, callable_mp(this, &FindInFilesPanel::_on_finished));
@@ -641,7 +634,6 @@ FindInFilesPanel::FindInFilesPanel() {
}
void FindInFilesPanel::set_with_replace(bool with_replace) {
-
_with_replace = with_replace;
_replace_container->set_visible(with_replace);
@@ -670,7 +662,6 @@ void FindInFilesPanel::clear() {
}
void FindInFilesPanel::start_search() {
-
clear();
_status_label->set_text(TTR("Searching..."));
@@ -687,7 +678,6 @@ void FindInFilesPanel::start_search() {
}
void FindInFilesPanel::stop_search() {
-
_finder->stop();
_status_label->set_text("");
@@ -704,7 +694,6 @@ void FindInFilesPanel::_notification(int p_what) {
}
void FindInFilesPanel::_on_result_found(String fpath, int line_number, int begin, int end, String text) {
-
TreeItem *file_item;
Map<String, TreeItem *>::Element *E = _file_items.find(fpath);
@@ -756,14 +745,15 @@ void FindInFilesPanel::_on_result_found(String fpath, int line_number, int begin
}
void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) {
-
TreeItem *item = Object::cast_to<TreeItem>(item_obj);
- if (!item)
+ if (!item) {
return;
+ }
Map<TreeItem *, Result>::Element *E = _result_items.find(item);
- if (!E)
+ if (!E) {
return;
+ }
Result r = E->value();
Rect2 match_rect = rect;
@@ -777,7 +767,6 @@ void FindInFilesPanel::draw_result_text(Object *item_obj, Rect2 rect) {
}
void FindInFilesPanel::_on_item_edited() {
-
TreeItem *item = _results_display->get_selected();
if (item->is_checked(0)) {
@@ -792,7 +781,6 @@ void FindInFilesPanel::_on_item_edited() {
}
void FindInFilesPanel::_on_finished() {
-
_status_label->set_text(TTR("Search complete"));
update_replace_buttons();
set_progress_visible(false);
@@ -809,12 +797,12 @@ void FindInFilesPanel::_on_cancel_button_clicked() {
}
void FindInFilesPanel::_on_result_selected() {
-
TreeItem *item = _results_display->get_selected();
Map<TreeItem *, Result>::Element *E = _result_items.find(item);
- if (E == nullptr)
+ if (E == nullptr) {
return;
+ }
Result r = E->value();
TreeItem *file_item = item->get_parent();
@@ -828,21 +816,19 @@ void FindInFilesPanel::_on_replace_text_changed(String text) {
}
void FindInFilesPanel::_on_replace_all_clicked() {
-
String replace_text = get_replace_text();
PackedStringArray modified_files;
for (Map<String, TreeItem *>::Element *E = _file_items.front(); E; E = E->next()) {
-
TreeItem *file_item = E->value();
String fpath = file_item->get_metadata(0);
Vector<Result> locations;
for (TreeItem *item = file_item->get_children(); item; item = item->get_next()) {
-
- if (!item->is_checked(0))
+ if (!item->is_checked(0)) {
continue;
+ }
Map<TreeItem *, Result>::Element *F = _result_items.find(item);
ERR_FAIL_COND(F == nullptr);
@@ -866,13 +852,11 @@ void FindInFilesPanel::_on_replace_all_clicked() {
class ConservativeGetLine {
public:
String get_line(FileAccess *f) {
-
_line_buffer.clear();
CharType c = f->get_8();
while (!f->eof_reached()) {
-
if (c == '\n') {
_line_buffer.push_back(c);
_line_buffer.push_back(0);
@@ -898,7 +882,6 @@ private:
};
void FindInFilesPanel::apply_replaces_in_file(String fpath, const Vector<Result> &locations, String new_text) {
-
// If the file is already open, I assume the editor will reload it.
// If there are unsaved changes, the user will be asked on focus,
// however that means either losing changes or losing replaces.
@@ -917,7 +900,6 @@ void FindInFilesPanel::apply_replaces_in_file(String fpath, const Vector<Result>
int offset = 0;
for (int i = 0; i < locations.size(); ++i) {
-
int repl_line_number = locations[i].line_number;
while (current_line < repl_line_number) {
@@ -963,7 +945,6 @@ String FindInFilesPanel::get_replace_text() {
}
void FindInFilesPanel::update_replace_buttons() {
-
bool disabled = _finder->is_searching();
_replace_all_button->set_disabled(disabled);
@@ -974,7 +955,6 @@ void FindInFilesPanel::set_progress_visible(bool visible) {
}
void FindInFilesPanel::_bind_methods() {
-
ClassDB::bind_method("_on_result_found", &FindInFilesPanel::_on_result_found);
ClassDB::bind_method("_on_finished", &FindInFilesPanel::_on_finished);
ClassDB::bind_method("_draw_result_text", &FindInFilesPanel::draw_result_text);
diff --git a/editor/groups_editor.cpp b/editor/groups_editor.cpp
index 7e5d2e87d6..98b216acda 100644
--- a/editor/groups_editor.cpp
+++ b/editor/groups_editor.cpp
@@ -300,8 +300,9 @@ void GroupDialog::_load_groups(Node *p_current) {
void GroupDialog::_delete_group_pressed(Object *p_item, int p_column, int p_id) {
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
- if (!ti)
+ if (!ti) {
return;
+ }
String name = ti->get_text(0);
@@ -536,16 +537,18 @@ GroupDialog::GroupDialog() {
////////////////////////////////////////////////////////////////////////////////
void GroupsEditor::_add_group(const String &p_group) {
-
- if (!node)
+ if (!node) {
return;
+ }
const String name = group_name->get_text().strip_edges();
- if (name.empty())
+ if (name.empty()) {
return;
+ }
- if (node->is_in_group(name))
+ if (node->is_in_group(name)) {
return;
+ }
undo_redo->create_action(TTR("Add to Group"));
@@ -564,13 +567,14 @@ void GroupsEditor::_add_group(const String &p_group) {
}
void GroupsEditor::_remove_group(Object *p_item, int p_column, int p_id) {
-
- if (!node)
+ if (!node) {
return;
+ }
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
- if (!ti)
+ if (!ti) {
return;
+ }
String name = ti->get_text(0);
@@ -589,18 +593,17 @@ void GroupsEditor::_remove_group(Object *p_item, int p_column, int p_id) {
}
struct _GroupInfoComparator {
-
bool operator()(const Node::GroupInfo &p_a, const Node::GroupInfo &p_b) const {
return p_a.name.operator String() < p_b.name.operator String();
}
};
void GroupsEditor::update_tree() {
-
tree->clear();
- if (!node)
+ if (!node) {
return;
+ }
List<Node::GroupInfo> groups;
node->get_groups(&groups);
@@ -609,20 +612,18 @@ void GroupsEditor::update_tree() {
TreeItem *root = tree->create_item();
for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) {
-
Node::GroupInfo gi = E->get();
- if (!gi.persistent)
+ if (!gi.persistent) {
continue;
+ }
Node *n = node;
bool can_be_deleted = true;
while (n) {
-
Ref<SceneState> ss = (n == EditorNode::get_singleton()->get_edited_scene()) ? n->get_scene_inherited_state() : n->get_scene_instance_state();
if (ss.is_valid()) {
-
int path = ss->find_node_by_path(n->get_path_to(node));
if (path != -1) {
if (ss->is_node_in_group(path, gi.name)) {
@@ -645,13 +646,11 @@ void GroupsEditor::update_tree() {
}
void GroupsEditor::set_current(Node *p_node) {
-
node = p_node;
update_tree();
}
void GroupsEditor::_show_group_dialog() {
-
group_dialog->edit();
group_dialog->set_undo_redo(undo_redo);
}
@@ -661,7 +660,6 @@ void GroupsEditor::_bind_methods() {
}
GroupsEditor::GroupsEditor() {
-
node = nullptr;
VBoxContainer *vbc = this;
diff --git a/editor/groups_editor.h b/editor/groups_editor.h
index 40c7b3c75a..911c82e7f0 100644
--- a/editor/groups_editor.h
+++ b/editor/groups_editor.h
@@ -42,7 +42,6 @@
#include "scene/gui/tree.h"
class GroupDialog : public AcceptDialog {
-
GDCLASS(GroupDialog, AcceptDialog);
ConfirmationDialog *error;
@@ -104,7 +103,6 @@ public:
};
class GroupsEditor : public VBoxContainer {
-
GDCLASS(GroupsEditor, VBoxContainer);
Node *node;
diff --git a/editor/icons/CameraEffects.svg b/editor/icons/CameraEffects.svg
new file mode 100644
index 0000000000..2f6dad5fd8
--- /dev/null
+++ b/editor/icons/CameraEffects.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m5.9492188 2a3 3 0 0 0 -2.9492188 3 3 3 0 0 0 1 2.2304688v1.7695312l-3-2v6l3-2v1c0 .554.44599 1 1 1h3c.0076117-.045309.0115938-.096059.0214844-.134766.0773621-.302758.1860981-.478282.2832031-.625.1397097-.211089.2814954-.338835.4257813-.480468-.1445165-.141692-.2879205-.269839-.4277344-.480469-.0971224-.146315-.2052562-.321748-.2832032-.623047-.0777157-.300405-.1044198-.8152648.1640626-1.2910156.2700589-.4775976.7340166-.7239536 1.0371093-.8105469.3037241-.0867737.5108695-.0808838.6875-.0703125.2608449.0156115.4500479.0763383.6503909.1328125.049596-.1859081.086921-.3641449.195312-.5800781.078477-.1563394.174637-.3364783.396485-.5527344.221847-.2162561.652628-.4930277 1.195312-.4980469a1.6124973 1.6124973 0 0 1 .033203 0c.542861.0056205.97185.2837448 1.19336.5.146452.1429781.230167.265896.298828.3808594a3 3 0 0 0 .128906-.8671875 3 3 0 0 0 -3-3 3 3 0 0 0 -2.0117188.7773438 3 3 0 0 0 -2.9882812-2.7773438 3 3 0 0 0 -.0507812 0z" fill="#e0e0e0"/><path d="m12.36062 8.59795a.53334 3.2001 0 0 0 -.50976 2.2754 3.2001.53334 30 0 0 -2.2656-.71484 3.2001.53334 30 0 0 1.75 1.6016.53334 3.2001 60 0 0 -1.7461 1.5996.53334 3.2001 60 0 0 2.2578-.71094.53334 3.2001 0 0 0 .51367 2.3496.53334 3.2001 0 0 0 .51367-2.3516 3.2001.53334 30 0 0 2.2539.71094 3.2001.53334 30 0 0 -1.7441-1.5977.53334 3.2001 60 0 0 1.748-1.5996.53334 3.2001 60 0 0 -2.2617.71484.53334 3.2001 0 0 0 -.50977-2.2773z" fill="#cea4f1" stroke-width="1.0667"/></svg> \ No newline at end of file
diff --git a/editor/icons/CubeMap.svg b/editor/icons/Cubemap.svg
index c9e6f1fa7d..c9e6f1fa7d 100644
--- a/editor/icons/CubeMap.svg
+++ b/editor/icons/Cubemap.svg
diff --git a/editor/icons/CubemapArray.svg b/editor/icons/CubemapArray.svg
new file mode 100644
index 0000000000..350a64f9c2
--- /dev/null
+++ b/editor/icons/CubemapArray.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 6v4h2v-4zm6 0v4h4v-4z" fill="#84ffb1"/><path d="m4 6v4h4v-4zm8 0v4h2v-4z" fill="#ff8484"/><path d="m4 2v4h4v-4zm0 8v4h4v-4z" fill="#84c2ff"/><path d="m-.00000002 2v12h4.00000002v-2h-2v-8h2v-2h-2zm12.00000002 0v2h2.000001v8h-2.000001v2h4.000001v-12h-2z" fill="#e0e0e0"/></svg> \ No newline at end of file
diff --git a/editor/icons/Decal.svg b/editor/icons/Decal.svg
new file mode 100644
index 0000000000..fc7bfb8e2c
--- /dev/null
+++ b/editor/icons/Decal.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2c-3.3137085 0-6 2.6862915-6 6 0 2.220299 1.2092804 4.153789 3.0019531 5.191406l8.9082029-6.1894529c-.476307-2.8374399-2.937354-5.0019531-5.910156-5.0019531z" fill="#fc9c9c"/><path d="m5.001954 13.191406 8.908202-6.1894529c-.882819-.510985-1.904638-.808594-2.998046-.808594-3.3137079 0-6 2.686292-6 5.9999999 0 .340906.03522.672663.08984.998047z" fill="#ff5d5d"/><path d="m13.910156 7.0019531-8.908202 6.1894529c.882819.510985 1.904638.808594 2.998046.808594 3.313708 0 6-2.686292 6-5.9999999 0-.340906-.03522-.672663-.08984-.998047z" fill="#fc9c9c" fill-opacity=".392157"/></svg> \ No newline at end of file
diff --git a/editor/icons/ErrorWarning.svg b/editor/icons/ErrorWarning.svg
new file mode 100644
index 0000000000..72b5037e50
--- /dev/null
+++ b/editor/icons/ErrorWarning.svg
@@ -0,0 +1 @@
+<svg height="8" viewBox="0 0 8 8" width="8" xmlns="http://www.w3.org/2000/svg"><path d="m4 0c-2.216 0-4 1.784-4 4s1.784 4 4 4z" fill="#ff5d5d"/><path d="m4 .00000003c2.216 0 4 1.78399997 4 3.99999997s-1.784 4-4 4z" fill="#ffdd65"/></svg> \ No newline at end of file
diff --git a/editor/icons/LightmapProbe.svg b/editor/icons/LightmapProbe.svg
new file mode 100644
index 0000000000..0972220fda
--- /dev/null
+++ b/editor/icons/LightmapProbe.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 9h3v-2h-3zm2.050781 2.535156 1.414063 1.414063 1.414062-1.414063-1.414062-1.414062zm0-7.070312 1.414063 1.414062 1.414062-1.414062-1.414062-1.414063zm1.949219 3.535156c0 1.6569 1.3432 3 3 3s3-1.3431 3-3-1.3432-3-3-3-3 1.3431-3 3zm3 7c3.865993 0 7-3.134007 7-7s-3.134007-7-7-7v2.333984c2.577329 0 4.666016 2.088687 4.666016 4.666016s-2.088687 4.666016-4.666016 4.666016z" fill="#fc9c9c" fill-opacity=".996078" stroke-width="1.16667"/></svg> \ No newline at end of file
diff --git a/editor/icons/PanoramaSky.svg b/editor/icons/PanoramaSky.svg
deleted file mode 100644
index bfff6840bd..0000000000
--- a/editor/icons/PanoramaSky.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(1.0096 0 0 1.0227 -.009615 -22.593)" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1038.4" y2="1050.4"><stop offset="0" stop-color="#1ec3ff"/><stop offset="1" stop-color="#b2e1ff"/></linearGradient><g transform="translate(0 -1037.4)"><path d="m1 1039.4c4.2749 2.6091 10.765 2.7449 14 0v12c-3.5849-2.6849-9.7929-2.6544-14 0z" fill="url(#a)" stroke-width="15.242"/><path d="m11 6c-.554 0-1 .446-1 1h-1c-.554 0-1 .446-1 1s.446 1 1 1h2c.554 0 1-.446 1-1h1c.554 0 1-.446 1-1s-.446-1-1-1zm-8 3c-.554 0-1 .446-1 1s.446 1 1 1h1c.554 0 1-.446 1-1s-.446-1-1-1z" fill="#fff" transform="translate(0 1037.4)"/></g></svg> \ No newline at end of file
diff --git a/editor/icons/PanoramaSkyMaterial.svg b/editor/icons/PanoramaSkyMaterial.svg
new file mode 100644
index 0000000000..9f40ffb63c
--- /dev/null
+++ b/editor/icons/PanoramaSkyMaterial.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 5v2h8 1c0-.554.446-1 1-1h2c.554 0 1 .446 1 1h1v-2z" fill="#9dff70"/><path d="m1 3v2h14v-2h-1.589844c-2.86436 1.357608-6.9481434 1.30996-10.347656 0z" fill="#ffeb70"/><path d="m1 2v1h2.0625c-.7241713-.2790504-1.419865-.6077805-2.0625-1zm14 0c-.465784.3952185-1.005424.7230054-1.589844 1h1.589844z" fill="#ff7070"/><path d="m1 7v2h2 1 5c-.554 0-1-.446-1-1s.446-1 1-1zm13 0c0 .554-.446 1-1 1h-1c0 .554-.446 1-1 1h4v-2z" fill="#70ffb9"/><path d="m1 9v2h2c-.554 0-1-.446-1-1s.446-1 1-1zm3 0c.554 0 1 .446 1 1s-.446 1-1 1h11v-2h-4-2z" fill="#70deff"/><path d="m1 13v-2h14v2h-1.589844c-2.86436-1.357608-6.9481434-1.30996-10.347656 0z" fill="#9f70ff"/><path d="m1 14v-1h2.0625c-.7241713.27905-1.419865.60778-2.0625 1zm14 0c-.465784-.395219-1.005424-.723005-1.589844-1h1.589844z" fill="#ff70ac"/></svg> \ No newline at end of file
diff --git a/editor/icons/PhysicalSkyMaterial.svg b/editor/icons/PhysicalSkyMaterial.svg
new file mode 100644
index 0000000000..5831cb2c63
--- /dev/null
+++ b/editor/icons/PhysicalSkyMaterial.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 5v2h8 1c0-.554.446-1 1-1h2c.554 0 1 .446 1 1h1v-2z" fill="#9dff70"/><path d="m1 7v2h2 1 5c-.554 0-1-.446-1-1s.446-1 1-1zm13 0c0 .554-.446 1-1 1h-1c0 .554-.446 1-1 1h4v-2z" fill="#70ffb9"/><path d="m1 9v2h2c-.554 0-1-.446-1-1s.446-1 1-1zm3 0c.554 0 1 .446 1 1s-.446 1-1 1h11v-2h-4-2z" fill="#70deff"/><path d="m1 3v2h14v-2z" fill="#ffeb70"/><path d="m1 11v2h14v-2z" fill="#9f70ff"/></svg> \ No newline at end of file
diff --git a/editor/icons/ProceduralSky.svg b/editor/icons/ProceduralSky.svg
deleted file mode 100644
index 356a966fe9..0000000000
--- a/editor/icons/ProceduralSky.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="8" x2="8" y1="1040.4" y2="1050.4"><stop offset="0" stop-color="#1ec3ff"/><stop offset="1" stop-color="#b2e1ff"/></linearGradient><g transform="translate(0 -1037.4)"><path d="m8 1040.4a7 7 0 0 0 -7 7 7 7 0 0 0 .68555 3h12.631a7 7 0 0 0 .68359-3 7 7 0 0 0 -7-7z" fill="url(#a)"/><path d="m10 7c-.554 0-1 .446-1 1h-1c-.554 0-1 .446-1 1s.446 1 1 1h2c.554 0 1-.446 1-1h1c.554 0 1-.446 1-1s-.446-1-1-1zm-7 3c-.554 0-1 .446-1 1s.446 1 1 1h1c.554 0 1-.446 1-1s-.446-1-1-1z" fill="#fff" transform="translate(0 1037.4)"/></g></svg> \ No newline at end of file
diff --git a/editor/icons/ProceduralSkyMaterial.svg b/editor/icons/ProceduralSkyMaterial.svg
new file mode 100644
index 0000000000..f7a3944671
--- /dev/null
+++ b/editor/icons/ProceduralSkyMaterial.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.0761719 11a7 7 0 0 0 .609375 2h12.6308591a7 7 0 0 0 .609375-2h-9.925781c0 .554-.446 1-1 1h-1c-.554 0-1-.446-1-1z" fill="#9f70ff"/><path d="m1.0722656 9a7 7 0 0 0 -.0722656 1 7 7 0 0 0 .0761719 1h.9238281c0-.554.446-1 1-1h1c.554 0 1 .446 1 1h9.925781a7 7 0 0 0 .074219-1 7 7 0 0 0 -.072266-1h-2.927734-1c0 .554-.446 1-1 1h-2c-.554 0-1-.446-1-1z" fill="#70deff"/><path d="m1.6757812 7a7 7 0 0 0 -.6035156 2h5.9277344c0-.554.446-1 1-1h1c0-.554.446-1 1-1zm10.3242188 0c.554 0 1 .446 1 1s-.446 1-1 1h2.927734a7 7 0 0 0 -.603515-2z" fill="#70ffb9"/><path d="m3.1035156 5a7 7 0 0 0 -1.4277344 2h12.6484378a7 7 0 0 0 -1.425781-2z" fill="#9dff70"/><path d="m8 3a7 7 0 0 0 -4.8964844 2h9.7949224a7 7 0 0 0 -4.898438-2z" fill="#ffeb70"/></svg> \ No newline at end of file
diff --git a/editor/icons/README.md b/editor/icons/README.md
index 5f652e47ab..3159565180 100644
--- a/editor/icons/README.md
+++ b/editor/icons/README.md
@@ -1,12 +1,7 @@
-The icons here are optimized SVGs, because the editor renders the svgs at runtime, they need
-to be small in size, so they can be efficiently parsed.
+# Editor icons
-The original icons can be found at:
-https://github.com/godotengine/godot-design/tree/master/engine/icons
+This folder contains all the icons used by Godot editor (except for platform
+icons which are located in their respective platform folder).
-There you can find the optimizer script.
-
-If you add a new icon, please make a pull request to this repo:
-https://github.com/godotengine/godot-design/
-
-and store the optimized SVG version here.
+See [Editor icons](https://docs.godotengine.org/en/latest/development/editor/creating_icons.html)
+in the documentation for details on creating icons for the Godot editor.
diff --git a/editor/icons/RootMotionView.svg b/editor/icons/RootMotionView.svg
new file mode 100644
index 0000000000..4d33420383
--- /dev/null
+++ b/editor/icons/RootMotionView.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><radialGradient id="a" cx="8" cy="8" gradientTransform="matrix(.85714281 -.00000007 .00000004 .85714284 1.142858 1.142858)" gradientUnits="userSpaceOnUse" r="7"><stop offset="0" stop-color="#fc9c9c"/><stop offset=".83333331" stop-color="#fc9c9c" stop-opacity=".701961"/><stop offset="1" stop-color="#fc9c9c" stop-opacity="0"/></radialGradient><path d="m5 2v3h-3v2h3v2h-3v2h3v3h2v-3h2v3h2v-3h3v-2h-3v-2h3v-2h-3v-3h-2v3h-2v-3zm2 5h2v2h-2z" fill="url(#a)"/></svg> \ No newline at end of file
diff --git a/editor/icons/ShaderGlobalsOverride.svg b/editor/icons/ShaderGlobalsOverride.svg
new file mode 100644
index 0000000000..2fe76ed777
--- /dev/null
+++ b/editor/icons/ShaderGlobalsOverride.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m2 1c-.55226.0001-.99994.4477-1 1v12c.0000552.5523.44774.9999 1 1h12c.55226-.0001.99994-.4477 1-1v-8l-5-5zm1 2h6v3c0 .554.44599 1 1 1h3v6h-10zm1 1v1h3v-1zm0 2v1h2v-1zm3 0v1h1v-1zm-2 3 3 3 3-3z" fill="#e0e0e0"/></svg> \ No newline at end of file
diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp
index 9e49fa9066..41e71248a9 100644
--- a/editor/import/collada.cpp
+++ b/editor/import/collada.cpp
@@ -45,14 +45,12 @@
/* HELPERS */
String Collada::Effect::get_texture_path(const String &p_source, Collada &state) const {
-
const String &image = p_source;
ERR_FAIL_COND_V(!state.state.image_map.has(image), "");
return state.state.image_map[image].path;
}
Transform Collada::get_root_transform() const {
-
Transform unit_scale_transform;
#ifndef COLLADA_IMPORT_SCALE_SCENE
unit_scale_transform.scale(Vector3(state.unit_scale, state.unit_scale, state.unit_scale));
@@ -67,27 +65,27 @@ void Collada::Vertex::fix_unit_scale(Collada &state) {
}
static String _uri_to_id(const String &p_uri) {
-
- if (p_uri.begins_with("#"))
+ if (p_uri.begins_with("#")) {
return p_uri.substr(1, p_uri.size() - 1);
- else
+ } else {
return p_uri;
+ }
}
/** HELPER FUNCTIONS **/
Transform Collada::fix_transform(const Transform &p_transform) {
-
Transform tr = p_transform;
#ifndef NO_UP_AXIS_SWAP
if (state.up_axis != Vector3::AXIS_Y) {
-
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++) {
SWAP(tr.basis[1][i], tr.basis[state.up_axis][i]);
- for (int i = 0; i < 3; i++)
+ }
+ for (int i = 0; i < 3; i++) {
SWAP(tr.basis[i][1], tr.basis[i][state.up_axis]);
+ }
SWAP(tr.origin[1], tr.origin[state.up_axis]);
@@ -105,7 +103,6 @@ Transform Collada::fix_transform(const Transform &p_transform) {
}
static Transform _read_transform_from_array(const Vector<float> &array, int ofs = 0) {
-
Transform tr;
// i wonder why collada matrices are transposed, given that's opposed to opengl..
tr.basis.elements[0][0] = array[0 + ofs];
@@ -126,39 +123,30 @@ static Transform _read_transform_from_array(const Vector<float> &array, int ofs
/* STRUCTURES */
Transform Collada::Node::compute_transform(Collada &state) const {
-
Transform xform;
for (int i = 0; i < xform_list.size(); i++) {
-
Transform xform_step;
const XForm &xf = xform_list[i];
switch (xf.op) {
-
case XForm::OP_ROTATE: {
if (xf.data.size() >= 4) {
-
xform_step.rotate(Vector3(xf.data[0], xf.data[1], xf.data[2]), Math::deg2rad(xf.data[3]));
}
} break;
case XForm::OP_SCALE: {
-
if (xf.data.size() >= 3) {
-
xform_step.scale(Vector3(xf.data[0], xf.data[1], xf.data[2]));
}
} break;
case XForm::OP_TRANSLATE: {
-
if (xf.data.size() >= 3) {
-
xform_step.origin = Vector3(xf.data[0], xf.data[1], xf.data[2]);
}
} break;
case XForm::OP_MATRIX: {
-
if (xf.data.size() >= 16) {
xform_step = _read_transform_from_array(xf.data, 0);
}
@@ -178,39 +166,37 @@ Transform Collada::Node::compute_transform(Collada &state) const {
}
Transform Collada::Node::get_transform() const {
-
return default_transform;
}
Transform Collada::Node::get_global_transform() const {
-
- if (parent)
+ if (parent) {
return parent->get_global_transform() * default_transform;
- else
+ } else {
return default_transform;
+ }
}
Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) const {
-
ERR_FAIL_COND_V(keys.size() == 0, Vector<float>());
int i = 0;
for (i = 0; i < keys.size(); i++) {
-
- if (keys[i].time > p_time)
+ if (keys[i].time > p_time) {
break;
+ }
}
- if (i == 0)
+ if (i == 0) {
return keys[0].data;
- if (i == keys.size())
+ }
+ if (i == keys.size()) {
return keys[keys.size() - 1].data;
+ }
switch (keys[i].interp_type) {
-
case INTERP_BEZIER: //wait for bezier
case INTERP_LINEAR: {
-
float c = (p_time - keys[i - 1].time) / (keys[i].time - keys[i - 1].time);
if (keys[i].data.size() == 16) {
@@ -243,11 +229,9 @@ Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) const {
return ret;
} else {
-
Vector<float> dest;
dest.resize(keys[i].data.size());
for (int j = 0; j < dest.size(); j++) {
-
dest.write[j] = keys[i].data[j] * c + keys[i - 1].data[j] * (1.0 - c);
}
return dest;
@@ -260,42 +244,41 @@ Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) const {
}
void Collada::_parse_asset(XMLParser &parser) {
-
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name = parser.get_node_name();
if (name == "up_axis") {
-
parser.read();
- if (parser.get_node_data() == "X_UP")
+ if (parser.get_node_data() == "X_UP") {
state.up_axis = Vector3::AXIS_X;
- if (parser.get_node_data() == "Y_UP")
+ }
+ if (parser.get_node_data() == "Y_UP") {
state.up_axis = Vector3::AXIS_Y;
- if (parser.get_node_data() == "Z_UP")
+ }
+ if (parser.get_node_data() == "Z_UP") {
state.up_axis = Vector3::AXIS_Z;
+ }
COLLADA_PRINT("up axis: " + parser.get_node_data());
} else if (name == "unit") {
-
state.unit_scale = parser.get_attribute_value("meter").to_double();
COLLADA_PRINT("unit scale: " + rtos(state.unit_scale));
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "asset")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "asset") {
break; //end of <asset>
+ }
}
}
void Collada::_parse_image(XMLParser &parser) {
-
String id = parser.get_attribute_value("id");
if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
- if (!parser.is_empty())
+ if (!parser.is_empty()) {
parser.skip_section();
+ }
return;
}
@@ -309,15 +292,11 @@ void Collada::_parse_image(XMLParser &parser) {
image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().plus_file(path.percent_decode()));
}
} else {
-
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name = parser.get_node_name();
if (name == "init_from") {
-
parser.read();
String path = parser.get_node_data().strip_edges().percent_decode();
@@ -333,14 +312,15 @@ void Collada::_parse_image(XMLParser &parser) {
image.path = path;
} else if (name == "data") {
-
ERR_PRINT("COLLADA Embedded image data not supported!");
- } else if (name == "extra" && !parser.is_empty())
+ } else if (name == "extra" && !parser.is_empty()) {
parser.skip_section();
+ }
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "image")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "image") {
break; //end of <asset>
+ }
}
}
@@ -348,31 +328,30 @@ void Collada::_parse_image(XMLParser &parser) {
}
void Collada::_parse_material(XMLParser &parser) {
-
if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
- if (!parser.is_empty())
+ if (!parser.is_empty()) {
parser.skip_section();
+ }
return;
}
Material material;
String id = parser.get_attribute_value("id");
- if (parser.has_attribute("name"))
+ if (parser.has_attribute("name")) {
material.name = parser.get_attribute_value("name");
+ }
if (state.version < State::Version(1, 4, 0)) {
/* <1.4 */
ERR_PRINT("Collada Materials < 1.4 are not supported (yet)");
} else {
-
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT && parser.get_node_name() == "instance_effect") {
-
material.instance_effect = _uri_to_id(parser.get_attribute_value("url"));
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "material")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "material") {
break; //end of <asset>
+ }
}
}
@@ -381,9 +360,9 @@ void Collada::_parse_material(XMLParser &parser) {
//! reads floats from inside of xml element until end of xml element
Vector<float> Collada::_read_float_array(XMLParser &parser) {
-
- if (parser.is_empty())
+ if (parser.is_empty()) {
return Vector<float>();
+ }
Vector<String> splitters;
splitters.push_back(" ");
@@ -401,17 +380,18 @@ Vector<float> Collada::_read_float_array(XMLParser &parser) {
String str = parser.get_node_data();
array = str.split_floats_mk(splitters, false);
//array=str.split_floats(" ",false);
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END) {
break; // end parsing text
+ }
}
return array;
}
Vector<String> Collada::_read_string_array(XMLParser &parser) {
-
- if (parser.is_empty())
+ if (parser.is_empty()) {
return Vector<String>();
+ }
Vector<String> array;
while (parser.read() == OK) {
@@ -422,17 +402,18 @@ Vector<String> Collada::_read_string_array(XMLParser &parser) {
// parse String data
String str = parser.get_node_data();
array = str.split_spaces();
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END) {
break; // end parsing text
+ }
}
return array;
}
Transform Collada::_read_transform(XMLParser &parser) {
-
- if (parser.is_empty())
+ if (parser.is_empty()) {
return Transform();
+ }
Vector<String> array;
while (parser.read() == OK) {
@@ -443,8 +424,9 @@ Transform Collada::_read_transform(XMLParser &parser) {
// parse float data
String str = parser.get_node_data();
array = str.split_spaces();
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END) {
break; // end parsing text
+ }
}
ERR_FAIL_COND_V(array.size() != 16, Transform());
@@ -458,103 +440,88 @@ Transform Collada::_read_transform(XMLParser &parser) {
}
String Collada::_read_empty_draw_type(XMLParser &parser) {
-
String empty_draw_type = "";
- if (parser.is_empty())
+ if (parser.is_empty()) {
return empty_draw_type;
+ }
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_TEXT) {
empty_draw_type = parser.get_node_data();
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END) {
break; // end parsing text
+ }
}
return empty_draw_type;
}
Variant Collada::_parse_param(XMLParser &parser) {
-
- if (parser.is_empty())
+ if (parser.is_empty()) {
return Variant();
+ }
String from = parser.get_node_name();
Variant data;
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "float") {
-
parser.read();
if (parser.get_node_type() == XMLParser::NODE_TEXT) {
-
data = parser.get_node_data().to_double();
}
} else if (parser.get_node_name() == "float2") {
-
Vector<float> v2 = _read_float_array(parser);
if (v2.size() >= 2) {
-
data = Vector2(v2[0], v2[1]);
}
} else if (parser.get_node_name() == "float3") {
-
Vector<float> v3 = _read_float_array(parser);
if (v3.size() >= 3) {
-
data = Vector3(v3[0], v3[1], v3[2]);
}
} else if (parser.get_node_name() == "float4") {
-
Vector<float> v4 = _read_float_array(parser);
if (v4.size() >= 4) {
-
data = Color(v4[0], v4[1], v4[2], v4[3]);
}
} else if (parser.get_node_name() == "sampler2D") {
-
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "source") {
-
parser.read();
if (parser.get_node_type() == XMLParser::NODE_TEXT) {
-
data = parser.get_node_data();
}
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "sampler2D")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "sampler2D") {
break;
+ }
}
} else if (parser.get_node_name() == "surface") {
-
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "init_from") {
-
parser.read();
if (parser.get_node_type() == XMLParser::NODE_TEXT) {
-
data = parser.get_node_data();
}
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "surface")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "surface") {
break;
+ }
}
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == from)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == from) {
break;
+ }
}
COLLADA_PRINT("newparam ending " + parser.get_node_name());
@@ -562,23 +529,20 @@ Variant Collada::_parse_param(XMLParser &parser) {
}
void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &id) {
-
if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
- if (!parser.is_empty())
+ if (!parser.is_empty()) {
parser.skip_section();
+ }
return;
}
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
// first come the tags we descend, but ignore the top-levels
COLLADA_PRINT("node name: " + parser.get_node_name());
if (!parser.is_empty() && (parser.get_node_name() == "profile_COMMON" || parser.get_node_name() == "technique" || parser.get_node_name() == "extra")) {
-
_parse_effect_material(parser, effect, id); // try again
} else if (parser.get_node_name() == "newparam") {
@@ -591,45 +555,39 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
parser.get_node_name() == "lambert" ||
parser.get_node_name() == "phong" ||
parser.get_node_name() == "blinn") {
-
COLLADA_PRINT("shade model: " + parser.get_node_name());
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String what = parser.get_node_name();
if (what == "emission" ||
what == "diffuse" ||
what == "specular" ||
what == "reflective") {
-
// color or texture types
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "color") {
-
Vector<float> colorarr = _read_float_array(parser);
COLLADA_PRINT("colorarr size: " + rtos(colorarr.size()));
if (colorarr.size() >= 3) {
-
// alpha strangely not alright? maybe it needs to be multiplied by value as a channel intensity
Color color(colorarr[0], colorarr[1], colorarr[2], 1.0);
- if (what == "diffuse")
+ if (what == "diffuse") {
effect.diffuse.color = color;
- if (what == "specular")
+ }
+ if (what == "specular") {
effect.specular.color = color;
- if (what == "emission")
+ }
+ if (what == "emission") {
effect.emission.color = color;
+ }
COLLADA_PRINT(what + " color: " + color);
}
} else if (parser.get_node_name() == "texture") {
-
String sampler = parser.get_attribute_value("texture");
if (!effect.params.has(sampler)) {
ERR_PRINT(String("Couldn't find sampler: " + sampler + " in material:" + id).utf8().get_data());
@@ -658,11 +616,13 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
COLLADA_PRINT(what + " texture: " + uri);
}
}
- } else if (!parser.is_empty())
+ } else if (!parser.is_empty()) {
parser.skip_section();
+ }
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == what)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == what) {
break;
+ }
}
} else if (what == "shininess") {
@@ -671,8 +631,9 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
} else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && (parser.get_node_name() == "constant" ||
parser.get_node_name() == "lambert" ||
parser.get_node_name() == "phong" ||
- parser.get_node_name() == "blinn"))
+ parser.get_node_name() == "blinn")) {
break;
+ }
}
} else if (parser.get_node_name() == "double_sided" || parser.get_node_name() == "show_double_sided") { // colladamax / google earth
@@ -685,14 +646,10 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
parser.read();
effect.unshaded = parser.get_node_data().to_int();
} else if (parser.get_node_name() == "bump") {
-
// color or texture types
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "texture") {
-
String sampler = parser.get_attribute_value("texture");
if (!effect.params.has(sampler)) {
ERR_PRINT(String("Couldn't find sampler: " + sampler + " in material:" + id).utf8().get_data());
@@ -712,37 +669,42 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
COLLADA_PRINT(" bump: " + uri);
}
}
- } else if (!parser.is_empty())
+ } else if (!parser.is_empty()) {
parser.skip_section();
+ }
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "bump")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "bump") {
break;
+ }
}
- } else if (!parser.is_empty())
+ } else if (!parser.is_empty()) {
parser.skip_section();
+ }
} else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END &&
(parser.get_node_name() == "effect" ||
parser.get_node_name() == "profile_COMMON" ||
parser.get_node_name() == "technique" ||
- parser.get_node_name() == "extra"))
+ parser.get_node_name() == "extra")) {
break;
+ }
}
}
void Collada::_parse_effect(XMLParser &parser) {
-
if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
- if (!parser.is_empty())
+ if (!parser.is_empty()) {
parser.skip_section();
+ }
return;
}
String id = parser.get_attribute_value("id");
Effect effect;
- if (parser.has_attribute("name"))
+ if (parser.has_attribute("name")) {
effect.name = parser.get_attribute_value("name");
+ }
_parse_effect_material(parser, effect, id);
state.effect_map[id] = effect;
@@ -751,10 +713,10 @@ void Collada::_parse_effect(XMLParser &parser) {
}
void Collada::_parse_camera(XMLParser &parser) {
-
if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
- if (!parser.is_empty())
+ if (!parser.is_empty()) {
parser.skip_section();
+ }
return;
}
@@ -764,63 +726,53 @@ void Collada::_parse_camera(XMLParser &parser) {
CameraData &camera = state.camera_data_map[id];
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name = parser.get_node_name();
if (name == "perspective") {
-
camera.mode = CameraData::MODE_PERSPECTIVE;
} else if (name == "orthographic") {
-
camera.mode = CameraData::MODE_ORTHOGONAL;
} else if (name == "xfov") {
-
parser.read();
camera.perspective.x_fov = parser.get_node_data().to_double();
} else if (name == "yfov") {
-
parser.read();
camera.perspective.y_fov = parser.get_node_data().to_double();
} else if (name == "xmag") {
-
parser.read();
camera.orthogonal.x_mag = parser.get_node_data().to_double();
} else if (name == "ymag") {
-
parser.read();
camera.orthogonal.y_mag = parser.get_node_data().to_double();
} else if (name == "aspect_ratio") {
-
parser.read();
camera.aspect = parser.get_node_data().to_double();
} else if (name == "znear") {
-
parser.read();
camera.z_near = parser.get_node_data().to_double();
} else if (name == "zfar") {
-
parser.read();
camera.z_far = parser.get_node_data().to_double();
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "camera")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "camera") {
break; //end of <asset>
+ }
}
COLLADA_PRINT("Camera ID:" + id);
}
void Collada::_parse_light(XMLParser &parser) {
-
if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
- if (!parser.is_empty())
+ if (!parser.is_empty()) {
parser.skip_section();
+ }
return;
}
@@ -830,25 +782,18 @@ void Collada::_parse_light(XMLParser &parser) {
LightData &light = state.light_data_map[id];
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name = parser.get_node_name();
if (name == "ambient") {
-
light.mode = LightData::MODE_AMBIENT;
} else if (name == "directional") {
-
light.mode = LightData::MODE_DIRECTIONAL;
} else if (name == "point") {
-
light.mode = LightData::MODE_OMNI;
} else if (name == "spot") {
-
light.mode = LightData::MODE_SPOT;
} else if (name == "color") {
-
parser.read();
Vector<float> colorarr = _read_float_array(parser);
COLLADA_PRINT("colorarr size: " + rtos(colorarr.size()));
@@ -860,40 +805,36 @@ void Collada::_parse_light(XMLParser &parser) {
}
} else if (name == "constant_attenuation") {
-
parser.read();
light.constant_att = parser.get_node_data().to_double();
} else if (name == "linear_attenuation") {
-
parser.read();
light.linear_att = parser.get_node_data().to_double();
} else if (name == "quadratic_attenuation") {
-
parser.read();
light.quad_att = parser.get_node_data().to_double();
} else if (name == "falloff_angle") {
-
parser.read();
light.spot_angle = parser.get_node_data().to_double();
} else if (name == "falloff_exponent") {
-
parser.read();
light.spot_exp = parser.get_node_data().to_double();
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "light")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "light") {
break; //end of <asset>
+ }
}
COLLADA_PRINT("Light ID:" + id);
}
void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_name) {
-
if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
- if (!parser.is_empty())
+ if (!parser.is_empty()) {
parser.skip_section();
+ }
return;
}
@@ -914,13 +855,10 @@ void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_nam
}
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String section = parser.get_node_name();
if (section == "source") {
-
String id = parser.get_attribute_value("id");
curvedata.sources[id] = CurveData::Source();
current_source = id;
@@ -929,14 +867,12 @@ void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_nam
} else if (section == "float_array" || section == "array") {
// create a new array and read it.
if (curvedata.sources.has(current_source)) {
-
curvedata.sources[current_source].array = _read_float_array(parser);
COLLADA_PRINT("section: " + current_source + " read " + itos(curvedata.sources[current_source].array.size()) + " values.");
}
} else if (section == "Name_array") {
// create a new array and read it.
if (curvedata.sources.has(current_source)) {
-
curvedata.sources[current_source].sarray = _read_string_array(parser);
COLLADA_PRINT("section: " + current_source + " read " + itos(curvedata.sources[current_source].array.size()) + " values.");
}
@@ -950,13 +886,9 @@ void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_nam
COLLADA_PRINT("section: " + current_source + " stride " + itos(curvedata.sources[current_source].stride));
}
} else if (section == "control_vertices") {
-
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "input") {
-
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
@@ -964,24 +896,25 @@ void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_nam
COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section) {
break;
+ }
}
} else if (!parser.is_empty()) {
-
parser.skip_section();
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "spline")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "spline") {
break;
+ }
}
}
void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name) {
-
if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
- if (!parser.is_empty())
+ if (!parser.is_empty()) {
parser.skip_section();
+ }
return;
}
@@ -1002,13 +935,10 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
}
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String section = parser.get_node_name();
if (section == "source") {
-
String id = parser.get_attribute_value("id");
meshdata.sources[id] = MeshData::Source();
current_source = id;
@@ -1017,7 +947,6 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
} else if (section == "float_array" || section == "array") {
// create a new array and read it.
if (meshdata.sources.has(current_source)) {
-
meshdata.sources[current_source].array = _read_float_array(parser);
COLLADA_PRINT("section: " + current_source + " read " + itos(meshdata.sources[current_source].array.size()) + " values.");
}
@@ -1030,16 +959,12 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
COLLADA_PRINT("section: " + current_source + " stride " + itos(meshdata.sources[current_source].stride));
}
} else if (section == "vertices") {
-
MeshData::Vertices vert;
String id = parser.get_attribute_value("id");
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "input") {
-
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
@@ -1047,32 +972,30 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section) {
break;
+ }
}
meshdata.vertices[id] = vert;
} else if (section == "triangles" || section == "polylist" || section == "polygons") {
-
bool polygons = (section == "polygons");
if (polygons) {
WARN_PRINT("Primitive type \"polygons\" is not well supported (concave shapes may fail). To ensure that the geometry is properly imported, please re-export using \"triangles\" or \"polylist\".");
}
MeshData::Primitives prim;
- if (parser.has_attribute("material"))
+ if (parser.has_attribute("material")) {
prim.material = parser.get_attribute_value("material");
+ }
prim.count = parser.get_attribute_value("count").to_int();
prim.vertex_size = 0;
int last_ref = 0;
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "input") {
-
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
@@ -1098,13 +1021,13 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
Vector<float> values = _read_float_array(parser);
if (polygons) {
-
ERR_CONTINUE(prim.vertex_size == 0);
prim.polygons.push_back(values.size() / prim.vertex_size);
int from = prim.indices.size();
prim.indices.resize(from + values.size());
- for (int i = 0; i < values.size(); i++)
+ for (int i = 0; i < values.size(); i++) {
prim.indices.write[from + i] = values[i];
+ }
} else if (prim.vertex_size > 0) {
prim.indices = values;
@@ -1118,14 +1041,14 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
prim.polygons = values;
COLLADA_PRINT("read " + itos(values.size()) + " polygon values");
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section) {
break;
+ }
}
meshdata.primitives.push_back(prim);
} else if (parser.get_node_name() == "double_sided") {
-
parser.read();
meshdata.found_double_sided = true;
meshdata.double_sided = parser.get_node_data().to_int();
@@ -1133,16 +1056,15 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
} else if (parser.get_node_name() == "polygons") {
ERR_PRINT("Primitive type \"polygons\" not supported, re-export using \"polylist\" or \"triangles\".");
} else if (!parser.is_empty()) {
-
parser.skip_section();
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "mesh")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "mesh") {
break;
+ }
}
}
void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
-
state.skin_controller_data_map[p_id] = SkinControllerData();
SkinControllerData &skindata = state.skin_controller_data_map[p_id];
@@ -1151,13 +1073,10 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
String current_source;
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String section = parser.get_node_name();
if (section == "bind_shape_matrix") {
-
skindata.bind_shape = _read_transform(parser);
#ifdef COLLADA_IMPORT_SCALE_SCENE
skindata.bind_shape.origin *= state.unit_scale;
@@ -1166,7 +1085,6 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
COLLADA_PRINT("skeleton bind shape transform: " + skindata.bind_shape);
} else if (section == "source") {
-
String id = parser.get_attribute_value("id");
skindata.sources[id] = SkinControllerData::Source();
current_source = id;
@@ -1175,22 +1093,22 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
} else if (section == "float_array" || section == "array") {
// create a new array and read it.
if (skindata.sources.has(current_source)) {
-
skindata.sources[current_source].array = _read_float_array(parser);
COLLADA_PRINT("section: " + current_source + " read " + itos(skindata.sources[current_source].array.size()) + " values.");
}
} else if (section == "Name_array" || section == "IDREF_array") {
// create a new array and read it.
- if (section == "IDREF_array")
+ if (section == "IDREF_array") {
skindata.use_idrefs = true;
+ }
if (skindata.sources.has(current_source)) {
-
skindata.sources[current_source].sarray = _read_string_array(parser);
if (section == "IDREF_array") {
Vector<String> sa = skindata.sources[current_source].sarray;
- for (int i = 0; i < sa.size(); i++)
+ for (int i = 0; i < sa.size(); i++) {
state.idref_joints.insert(sa[i]);
+ }
}
COLLADA_PRINT("section: " + current_source + " read " + itos(skindata.sources[current_source].array.size()) + " values.");
}
@@ -1199,25 +1117,21 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
} else if (section == "accessor") { // child of source (below a technique tag)
if (skindata.sources.has(current_source)) {
-
int stride = 1;
- if (parser.has_attribute("stride"))
+ if (parser.has_attribute("stride")) {
stride = parser.get_attribute_value("stride").to_int();
+ }
skindata.sources[current_source].stride = stride;
COLLADA_PRINT("section: " + current_source + " stride " + itos(skindata.sources[current_source].stride));
}
} else if (section == "joints") {
-
SkinControllerData::Joints joint;
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "input") {
-
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
@@ -1225,24 +1139,21 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section) {
break;
+ }
}
skindata.joints = joint;
} else if (section == "vertex_weights") {
-
SkinControllerData::Weights weights;
weights.count = parser.get_attribute_value("count").to_int();
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "input") {
-
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
@@ -1267,8 +1178,9 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
weights.sets = values;
COLLADA_PRINT("read " + itos(values.size()) + " polygon values");
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section) {
break;
+ }
}
skindata.weights = weights;
@@ -1278,8 +1190,9 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
parser.skip_section();
*/
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "skin")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "skin") {
break;
+ }
}
/* STORE REST MATRICES */
@@ -1300,7 +1213,6 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
ERR_FAIL_COND(joint_source.sarray.size() != ibm_source.array.size() / 16);
for (int i = 0; i < joint_source.sarray.size(); i++) {
-
String name = joint_source.sarray[i];
Transform xform = _read_transform_from_array(ibm_source.array, i * 16); //<- this is a mistake, it must be applied to vertices
xform.affine_invert(); // inverse for rest, because it's an inverse
@@ -1312,7 +1224,6 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
}
void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
-
state.morph_controller_data_map[p_id] = MorphControllerData();
MorphControllerData &morphdata = state.morph_controller_data_map[p_id];
@@ -1321,13 +1232,10 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
String current_source;
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String section = parser.get_node_name();
if (section == "source") {
-
String id = parser.get_attribute_value("id");
morphdata.sources[id] = MorphControllerData::Source();
current_source = id;
@@ -1336,7 +1244,6 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
} else if (section == "float_array" || section == "array") {
// create a new array and read it.
if (morphdata.sources.has(current_source)) {
-
morphdata.sources[current_source].array = _read_float_array(parser);
COLLADA_PRINT("section: " + current_source + " read " + itos(morphdata.sources[current_source].array.size()) + " values.");
}
@@ -1348,7 +1255,6 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
morphdata.use_idrefs=true;
*/
if (morphdata.sources.has(current_source)) {
-
morphdata.sources[current_source].sarray = _read_string_array(parser);
/*
if (section=="IDREF_array") {
@@ -1363,23 +1269,19 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
} else if (section == "accessor") { // child of source (below a technique tag)
if (morphdata.sources.has(current_source)) {
-
int stride = 1;
- if (parser.has_attribute("stride"))
+ if (parser.has_attribute("stride")) {
stride = parser.get_attribute_value("stride").to_int();
+ }
morphdata.sources[current_source].stride = stride;
COLLADA_PRINT("section: " + current_source + " stride " + itos(morphdata.sources[current_source].stride));
}
} else if (section == "targets") {
-
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "input") {
-
String semantic = parser.get_attribute_value("semantic");
String source = _uri_to_id(parser.get_attribute_value("source"));
@@ -1387,8 +1289,9 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section) {
break;
+ }
}
}
/*
@@ -1396,18 +1299,17 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
parser.skip_section();
*/
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "morph")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "morph") {
break;
+ }
}
if (morphdata.targets.has("MORPH_WEIGHT")) {
-
state.morph_name_map[morphdata.targets["MORPH_WEIGHT"]] = p_id;
}
}
void Collada::_parse_controller(XMLParser &parser) {
-
String id = parser.get_attribute_value("id");
if (parser.is_empty()) {
@@ -1415,9 +1317,7 @@ void Collada::_parse_controller(XMLParser &parser) {
}
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String section = parser.get_node_name();
if (section == "skin") {
@@ -1425,27 +1325,25 @@ void Collada::_parse_controller(XMLParser &parser) {
} else if (section == "morph") {
_parse_morph_controller(parser, id);
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "controller")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "controller") {
break;
+ }
}
}
Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
-
String type = parser.get_node_name();
NodeGeometry *geom = memnew(NodeGeometry);
geom->controller = type == "instance_controller";
geom->source = _uri_to_id(parser.get_attribute_value_safe("url"));
- if (parser.is_empty()) //nothing else to parse...
+ if (parser.is_empty()) { //nothing else to parse...
return geom;
+ }
// try to find also many materials and skeletons!
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "instance_material") {
-
String symbol = parser.get_attribute_value("symbol");
String target = _uri_to_id(parser.get_attribute_value("target"));
@@ -1454,7 +1352,6 @@ Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
geom->material_map[symbol] = mat;
COLLADA_PRINT("uses material: '" + target + "' on primitive'" + symbol + "'");
} else if (parser.get_node_name() == "skeleton") {
-
parser.read();
String uri = _uri_to_id(parser.get_node_data());
if (uri != "") {
@@ -1462,12 +1359,12 @@ Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
}
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == type)
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == type) {
break;
+ }
}
if (geom->controller) {
-
if (geom->skeletons.empty()) {
//XSI style
@@ -1487,72 +1384,72 @@ Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
}
Collada::Node *Collada::_parse_visual_instance_camera(XMLParser &parser) {
-
NodeCamera *cam = memnew(NodeCamera);
cam->camera = _uri_to_id(parser.get_attribute_value_safe("url"));
- if (state.up_axis == Vector3::AXIS_Z) //collada weirdness
+ if (state.up_axis == Vector3::AXIS_Z) { //collada weirdness
cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math_PI * 0.5);
+ }
- if (parser.is_empty()) //nothing else to parse...
+ if (parser.is_empty()) { //nothing else to parse...
return cam;
+ }
while (parser.read() == OK) {
-
- if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "instance_camera")
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "instance_camera") {
break;
+ }
}
return cam;
}
Collada::Node *Collada::_parse_visual_instance_light(XMLParser &parser) {
-
NodeLight *cam = memnew(NodeLight);
cam->light = _uri_to_id(parser.get_attribute_value_safe("url"));
- if (state.up_axis == Vector3::AXIS_Z) //collada weirdness
+ if (state.up_axis == Vector3::AXIS_Z) { //collada weirdness
cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math_PI * 0.5);
+ }
- if (parser.is_empty()) //nothing else to parse...
+ if (parser.is_empty()) { //nothing else to parse...
return cam;
+ }
while (parser.read() == OK) {
-
- if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "instance_light")
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "instance_light") {
break;
+ }
}
return cam;
}
Collada::Node *Collada::_parse_visual_node_instance_data(XMLParser &parser) {
-
String instance_type = parser.get_node_name();
if (instance_type == "instance_geometry" || instance_type == "instance_controller") {
return _parse_visual_instance_geometry(parser);
} else if (instance_type == "instance_camera") {
-
return _parse_visual_instance_camera(parser);
} else if (instance_type == "instance_light") {
return _parse_visual_instance_light(parser);
}
- if (parser.is_empty()) //nothing else to parse...
+ if (parser.is_empty()) { //nothing else to parse...
return nullptr;
+ }
while (parser.read() == OK) {
-
- if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == instance_type)
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == instance_type) {
break;
+ }
}
return nullptr;
}
Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
-
String name;
String id = parser.get_attribute_value_safe("id");
@@ -1560,7 +1457,6 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
bool found_name = false;
if (id == "") {
-
id = "%NODEID%" + itos(Math::rand());
} else {
@@ -1576,7 +1472,6 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
name = parser.has_attribute("name") ? parser.get_attribute_value_safe("name") : parser.get_attribute_value_safe("id");
if (name == "") {
-
name = id;
} else {
found_name = true;
@@ -1604,9 +1499,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
}
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String section = parser.get_node_name();
if (section == "translate") {
@@ -1657,8 +1550,9 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
xf.data = matrix;
String mtx;
- for (int i = 0; i < matrix.size(); i++)
+ for (int i = 0; i < matrix.size(); i++) {
mtx += " " + rtos(matrix[i]);
+ }
xform_list.push_back(xf);
@@ -1678,13 +1572,10 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
} else if (section == "empty_draw_type") {
empty_draw_type = _read_empty_draw_type(parser);
} else if (section == "technique" || section == "extra") {
-
} else if (section != "node") {
//usually what defines the type of node
if (section.begins_with("instance_")) {
-
if (!node) {
-
node = _parse_visual_node_instance_data(parser);
} else {
@@ -1693,19 +1584,18 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
}
} else {
-
/* Found a child node!! what to do..*/
Node *child = _parse_visual_scene_node(parser);
children.push_back(child);
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "node")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "node") {
break;
+ }
}
if (!node) {
-
node = memnew(Node); //generic node, nothing of relevance found
}
@@ -1734,7 +1624,6 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
}
void Collada::_parse_visual_scene(XMLParser &parser) {
-
String id = parser.get_attribute_value("id");
if (parser.is_empty()) {
@@ -1744,31 +1633,31 @@ void Collada::_parse_visual_scene(XMLParser &parser) {
state.visual_scene_map[id] = VisualScene();
VisualScene &vscene = state.visual_scene_map[id];
- if (parser.has_attribute("name"))
+ if (parser.has_attribute("name")) {
vscene.name = parser.get_attribute_value("name");
+ }
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String section = parser.get_node_name();
if (section == "node") {
vscene.root_nodes.push_back(_parse_visual_scene_node(parser));
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "visual_scene")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "visual_scene") {
break;
+ }
}
COLLADA_PRINT("Scene ID:" + id);
}
void Collada::_parse_animation(XMLParser &parser) {
-
if (!(state.import_flags & IMPORT_FLAG_ANIMATION)) {
- if (!parser.is_empty())
+ if (!parser.is_empty()) {
parser.skip_section();
+ }
return;
}
@@ -1781,8 +1670,9 @@ void Collada::_parse_animation(XMLParser &parser) {
Map<String, Vector<String>> source_param_types;
String id = "";
- if (parser.has_attribute("id"))
+ if (parser.has_attribute("id")) {
id = parser.get_attribute_value("id");
+ }
String current_source;
String current_sampler;
@@ -1790,67 +1680,58 @@ void Collada::_parse_animation(XMLParser &parser) {
Vector<String> channel_targets;
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name = parser.get_node_name();
if (name == "source") {
-
current_source = parser.get_attribute_value("id");
source_param_names[current_source] = Vector<String>();
source_param_types[current_source] = Vector<String>();
} else if (name == "float_array") {
-
if (current_source != "") {
float_sources[current_source] = _read_float_array(parser);
}
} else if (name == "Name_array") {
-
if (current_source != "") {
string_sources[current_source] = _read_string_array(parser);
}
} else if (name == "accessor") {
-
if (current_source != "" && parser.has_attribute("stride")) {
source_strides[current_source] = parser.get_attribute_value("stride").to_int();
}
} else if (name == "sampler") {
-
current_sampler = parser.get_attribute_value("id");
samplers[current_sampler] = Map<String, String>();
} else if (name == "param") {
-
- if (parser.has_attribute("name"))
+ if (parser.has_attribute("name")) {
source_param_names[current_source].push_back(parser.get_attribute_value("name"));
- else
+ } else {
source_param_names[current_source].push_back("");
+ }
- if (parser.has_attribute("type"))
+ if (parser.has_attribute("type")) {
source_param_types[current_source].push_back(parser.get_attribute_value("type"));
- else
+ } else {
source_param_types[current_source].push_back("");
+ }
} else if (name == "input") {
-
if (current_sampler != "") {
-
samplers[current_sampler][parser.get_attribute_value("semantic")] = parser.get_attribute_value("source");
}
} else if (name == "channel") {
-
channel_sources.push_back(parser.get_attribute_value("source"));
channel_targets.push_back(parser.get_attribute_value("target"));
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "animation")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "animation") {
break; //end of <asset>
+ }
}
for (int i = 0; i < channel_sources.size(); i++) {
-
String source = _uri_to_id(channel_sources[i]);
String target = channel_targets[i];
ERR_CONTINUE(!samplers.has(source));
@@ -1870,7 +1751,6 @@ void Collada::_parse_animation(XMLParser &parser) {
Vector<String> &names = source_param_names[output_id];
for (int l = 0; l < names.size(); l++) {
-
String name = names[l];
Vector<float> &time_keys = float_sources[input_id];
@@ -1890,8 +1770,9 @@ void Collada::_parse_animation(XMLParser &parser) {
int stride = 1;
- if (source_strides.has(output_id))
+ if (source_strides.has(output_id)) {
stride = source_strides[output_id];
+ }
int output_len = stride / names.size();
ERR_CONTINUE(output_len == 0);
@@ -1903,22 +1784,23 @@ void Collada::_parse_animation(XMLParser &parser) {
for (int j = 0; j < key_count; j++) {
track.keys.write[j].data.resize(output_len);
- for (int k = 0; k < output_len; k++)
+ for (int k = 0; k < output_len; k++) {
track.keys.write[j].data.write[k] = output[l + j * stride + k]; //super weird but should work:
+ }
}
if (sampler.has("INTERPOLATION")) {
-
String interp_id = _uri_to_id(sampler["INTERPOLATION"]);
ERR_CONTINUE(!string_sources.has(interp_id));
Vector<String> &interps = string_sources[interp_id];
ERR_CONTINUE(interps.size() != key_count);
for (int j = 0; j < key_count; j++) {
- if (interps[j] == "BEZIER")
+ if (interps[j] == "BEZIER") {
track.keys.write[j].interp_type = AnimationTrack::INTERP_BEZIER;
- else
+ } else {
track.keys.write[j].interp_type = AnimationTrack::INTERP_LINEAR;
+ }
}
}
@@ -1944,8 +1826,9 @@ void Collada::_parse_animation(XMLParser &parser) {
if (target.find("/") != -1) { //transform component
track.target = target.get_slicec('/', 0);
track.param = target.get_slicec('/', 1);
- if (track.param.find(".") != -1)
+ if (track.param.find(".") != -1) {
track.component = track.param.get_slice(".", 1).to_upper();
+ }
track.param = track.param.get_slice(".", 0);
if (names.size() > 1 && track.component == "") {
//this is a guess because the collada spec is ambiguous here...
@@ -1958,14 +1841,16 @@ void Collada::_parse_animation(XMLParser &parser) {
state.animation_tracks.push_back(track);
- if (!state.referenced_tracks.has(target))
+ if (!state.referenced_tracks.has(target)) {
state.referenced_tracks[target] = Vector<int>();
+ }
state.referenced_tracks[target].push_back(state.animation_tracks.size() - 1);
if (id != "") {
- if (!state.by_id_tracks.has(id))
+ if (!state.by_id_tracks.has(id)) {
state.by_id_tracks[id] = Vector<int>();
+ }
state.by_id_tracks[id].push_back(state.animation_tracks.size() - 1);
}
@@ -1976,158 +1861,138 @@ void Collada::_parse_animation(XMLParser &parser) {
}
void Collada::_parse_animation_clip(XMLParser &parser) {
-
if (!(state.import_flags & IMPORT_FLAG_ANIMATION)) {
- if (!parser.is_empty())
+ if (!parser.is_empty()) {
parser.skip_section();
+ }
return;
}
AnimationClip clip;
- if (parser.has_attribute("name"))
+ if (parser.has_attribute("name")) {
clip.name = parser.get_attribute_value("name");
- else if (parser.has_attribute("id"))
+ } else if (parser.has_attribute("id")) {
clip.name = parser.get_attribute_value("id");
- if (parser.has_attribute("start"))
+ }
+ if (parser.has_attribute("start")) {
clip.begin = parser.get_attribute_value("start").to_double();
- if (parser.has_attribute("end"))
+ }
+ if (parser.has_attribute("end")) {
clip.end = parser.get_attribute_value("end").to_double();
+ }
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name = parser.get_node_name();
if (name == "instance_animation") {
-
String url = _uri_to_id(parser.get_attribute_value("url"));
clip.tracks.push_back(url);
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "animation_clip")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "animation_clip") {
break; //end of <asset>
+ }
}
state.animation_clips.push_back(clip);
}
void Collada::_parse_scene(XMLParser &parser) {
-
if (parser.is_empty()) {
return;
}
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name = parser.get_node_name();
if (name == "instance_visual_scene") {
-
state.root_visual_scene = _uri_to_id(parser.get_attribute_value("url"));
} else if (name == "instance_physics_scene") {
-
state.root_physics_scene = _uri_to_id(parser.get_attribute_value("url"));
}
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "scene")
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "scene") {
break; //end of <asset>
+ }
}
}
void Collada::_parse_library(XMLParser &parser) {
-
if (parser.is_empty()) {
return;
}
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
String name = parser.get_node_name();
COLLADA_PRINT("library name is: " + name);
if (name == "image") {
-
_parse_image(parser);
} else if (name == "material") {
-
_parse_material(parser);
} else if (name == "effect") {
-
_parse_effect(parser);
} else if (name == "camera") {
-
_parse_camera(parser);
} else if (name == "light") {
-
_parse_light(parser);
} else if (name == "geometry") {
-
String id = parser.get_attribute_value("id");
String name2 = parser.get_attribute_value_safe("name");
while (parser.read() == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "mesh") {
state.mesh_name_map[id] = (name2 != "") ? name2 : id;
_parse_mesh_geometry(parser, id, name2);
} else if (parser.get_node_name() == "spline") {
state.mesh_name_map[id] = (name2 != "") ? name2 : id;
_parse_curve_geometry(parser, id, name2);
- } else if (!parser.is_empty())
+ } else if (!parser.is_empty()) {
parser.skip_section();
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "geometry")
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "geometry") {
break;
+ }
}
} else if (name == "controller") {
-
_parse_controller(parser);
} else if (name == "animation") {
-
_parse_animation(parser);
} else if (name == "animation_clip") {
-
_parse_animation_clip(parser);
} else if (name == "visual_scene") {
-
COLLADA_PRINT("visual scene");
_parse_visual_scene(parser);
- } else if (!parser.is_empty())
+ } else if (!parser.is_empty()) {
parser.skip_section();
+ }
- } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name().begins_with("library_"))
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name().begins_with("library_")) {
break; //end of <asset>
+ }
}
}
void Collada::_joint_set_owner(Collada::Node *p_node, NodeSkeleton *p_owner) {
-
if (p_node->type == Node::TYPE_JOINT) {
-
NodeJoint *nj = static_cast<NodeJoint *>(p_node);
nj->owner = p_owner;
for (int i = 0; i < nj->children.size(); i++) {
-
_joint_set_owner(nj->children.write[i], p_owner);
}
}
}
void Collada::_create_skeletons(Collada::Node **p_node, NodeSkeleton *p_skeleton) {
-
Node *node = *p_node;
if (node->type == Node::TYPE_JOINT) {
-
if (!p_skeleton) {
-
// ohohohoohoo it's a joint node, time to work!
NodeSkeleton *sk = memnew(NodeSkeleton);
*p_node = sk;
@@ -2149,47 +2014,41 @@ void Collada::_create_skeletons(Collada::Node **p_node, NodeSkeleton *p_skeleton
}
bool Collada::_remove_node(Node *p_parent, Node *p_node) {
-
for (int i = 0; i < p_parent->children.size(); i++) {
-
if (p_parent->children[i] == p_node) {
p_parent->children.remove(i);
return true;
}
- if (_remove_node(p_parent->children[i], p_node))
+ if (_remove_node(p_parent->children[i], p_node)) {
return true;
+ }
}
return false;
}
void Collada::_remove_node(VisualScene *p_vscene, Node *p_node) {
-
for (int i = 0; i < p_vscene->root_nodes.size(); i++) {
if (p_vscene->root_nodes[i] == p_node) {
-
p_vscene->root_nodes.remove(i);
return;
}
- if (_remove_node(p_vscene->root_nodes[i], p_node))
+ if (_remove_node(p_vscene->root_nodes[i], p_node)) {
return;
+ }
}
ERR_PRINT("ERROR: Not found node to remove?");
}
void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) {
-
if (p_node->type == Node::TYPE_GEOMETRY) {
-
NodeGeometry *gnode = static_cast<NodeGeometry *>(p_node);
if (gnode->controller) {
-
// recount skeletons used
Set<NodeSkeleton *> skeletons;
for (int i = 0; i < gnode->skeletons.size(); i++) {
-
String nodeid = gnode->skeletons[i];
ERR_CONTINUE(!state.scene_map.has(nodeid)); //weird, it should have it...
@@ -2206,17 +2065,14 @@ void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) {
}
if (skeletons.size() > 1) {
-
//do the merger!!
Set<NodeSkeleton *>::Element *E = skeletons.front();
NodeSkeleton *base = E->get();
for (E = E->next(); E; E = E->next()) {
-
NodeSkeleton *merged = E->get();
_remove_node(p_vscene, merged);
for (int i = 0; i < merged->children.size(); i++) {
-
_joint_set_owner(merged->children[i], base);
base->children.push_back(merged->children[i]);
merged->children[i]->parent = base;
@@ -2235,15 +2091,12 @@ void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) {
}
void Collada::_merge_skeletons2(VisualScene *p_vscene) {
-
for (Map<String, SkinControllerData>::Element *E = state.skin_controller_data_map.front(); E; E = E->next()) {
-
SkinControllerData &cd = E->get();
NodeSkeleton *skeleton = nullptr;
for (Map<String, Transform>::Element *F = cd.bone_rest_map.front(); F; F = F->next()) {
-
String name;
if (!state.sid_to_node_map.has(F->key())) {
@@ -2260,7 +2113,6 @@ void Collada::_merge_skeletons2(VisualScene *p_vscene) {
NodeSkeleton *sk = nullptr;
while (node && !sk) {
-
if (node->type == Node::TYPE_SKELETON) {
sk = static_cast<NodeSkeleton *>(node);
}
@@ -2278,7 +2130,6 @@ void Collada::_merge_skeletons2(VisualScene *p_vscene) {
//whoa.. wtf, merge.
_remove_node(p_vscene, sk);
for (int i = 0; i < sk->children.size(); i++) {
-
_joint_set_owner(sk->children[i], skeleton);
skeleton->children.push_back(sk->children[i]);
sk->children[i]->parent = skeleton;
@@ -2292,7 +2143,6 @@ void Collada::_merge_skeletons2(VisualScene *p_vscene) {
}
bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
-
Node *node = p_node;
if (node->type == Node::TYPE_SKELETON && node->parent && node->parent->type == Node::TYPE_NODE && node->parent->children.size() == 1) {
@@ -2312,7 +2162,6 @@ bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
Node *gp = parent->parent;
bool found = false;
for (int i = 0; i < gp->children.size(); i++) {
-
if (gp->children[i] == parent) {
gp->children.write[i] = node;
found = true;
@@ -2323,13 +2172,10 @@ bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
ERR_PRINT("BUG");
}
} else {
-
bool found = false;
for (int i = 0; i < p_vscene->root_nodes.size(); i++) {
-
if (p_vscene->root_nodes[i] == parent) {
-
p_vscene->root_nodes.write[i] = node;
found = true;
break;
@@ -2346,27 +2192,25 @@ bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
}
for (int i = 0; i < node->children.size(); i++) {
-
- if (_optimize_skeletons(p_vscene, node->children[i]))
+ if (_optimize_skeletons(p_vscene, node->children[i])) {
return false; //stop processing, go up
+ }
}
return false;
}
bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, List<Node *> *p_mgeom) {
-
// Bind Shape Matrix scales the bones and makes them gigantic, so the matrix then shrinks the model?
// Solution: apply the Bind Shape Matrix to the VERTICES, and if the object comes scaled, it seems to be left alone!
if (p_node->type == Node::TYPE_GEOMETRY) {
-
NodeGeometry *ng = static_cast<NodeGeometry *>(p_node);
- if (ng->ignore_anim)
+ if (ng->ignore_anim) {
return false; //already made child of skeleton and processeg
+ }
if (ng->controller && ng->skeletons.size()) {
-
String nodeid = ng->skeletons[0];
ERR_FAIL_COND_V(!state.scene_map.has(nodeid), false); //weird, it should have it...
@@ -2401,7 +2245,6 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, L
//make rests relative to the skeleton (they seem to be always relative to world)
for (Map<String, Transform>::Element *E = skin.bone_rest_map.front(); E; E = E->next()) {
-
E->get() = skel_inv * E->get(); //make the bone rest local to the skeleton
state.bone_rest_map[E->key()] = E->get(); // make it remember where the bone is globally, now that it's relative
}
@@ -2419,7 +2262,6 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, L
}
for (int i = 0; i < p_node->children.size(); i++) {
-
if (_move_geometry_to_skeletons(p_vscene, p_node->children[i], p_mgeom)) {
p_node->children.remove(i);
i--;
@@ -2430,23 +2272,17 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, L
}
void Collada::_find_morph_nodes(VisualScene *p_vscene, Node *p_node) {
-
if (p_node->type == Node::TYPE_GEOMETRY) {
-
NodeGeometry *nj = static_cast<NodeGeometry *>(p_node);
if (nj->controller) {
-
String base = nj->source;
while (base != "" && !state.mesh_data_map.has(base)) {
-
if (state.skin_controller_data_map.has(base)) {
-
SkinControllerData &sk = state.skin_controller_data_map[base];
base = sk.base;
} else if (state.morph_controller_data_map.has(base)) {
-
state.morph_ownership_map[base] = nj->id;
break;
} else {
@@ -2457,15 +2293,12 @@ void Collada::_find_morph_nodes(VisualScene *p_vscene, Node *p_node) {
}
for (int i = 0; i < p_node->children.size(); i++) {
-
_find_morph_nodes(p_vscene, p_node->children[i]);
}
}
void Collada::_optimize() {
-
for (Map<String, VisualScene>::Element *E = state.visual_scene_map.front(); E; E = E->next()) {
-
VisualScene &vs = E->get();
for (int i = 0; i < vs.root_nodes.size(); i++) {
_create_skeletons(&vs.root_nodes.write[i]);
@@ -2482,7 +2315,6 @@ void Collada::_optimize() {
}
for (int i = 0; i < vs.root_nodes.size(); i++) {
-
List<Node *> mgeom;
if (_move_geometry_to_skeletons(&vs, vs.root_nodes[i], &mgeom)) {
vs.root_nodes.remove(i);
@@ -2490,7 +2322,6 @@ void Collada::_optimize() {
}
while (!mgeom.empty()) {
-
Node *n = mgeom.front()->get();
n->parent->children.push_back(n);
mgeom.pop_front();
@@ -2504,9 +2335,7 @@ void Collada::_optimize() {
}
int Collada::get_uv_channel(String p_name) {
-
if (!channel_map.has(p_name)) {
-
ERR_FAIL_COND_V(channel_map.size() == 2, 0);
channel_map[p_name] = channel_map.size();
@@ -2516,7 +2345,6 @@ int Collada::get_uv_channel(String p_name) {
}
Error Collada::load(const String &p_path, int p_flags) {
-
Ref<XMLParser> parserr = memnew(XMLParser);
XMLParser &parser = *parserr.ptr();
Error err = parser.open(p_path);
@@ -2526,13 +2354,12 @@ Error Collada::load(const String &p_path, int p_flags) {
state.import_flags = p_flags;
/* Skip headers */
while ((err = parser.read()) == OK) {
-
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
-
if (parser.get_node_name() == "COLLADA") {
break;
- } else if (!parser.is_empty())
+ } else if (!parser.is_empty()) {
parser.skip_section(); // unknown section, likely headers
+ }
}
}
@@ -2550,11 +2377,11 @@ Error Collada::load(const String &p_path, int p_flags) {
}
while ((err = parser.read()) == OK) {
-
/* Read all the main sections.. */
- if (parser.get_node_type() != XMLParser::NODE_ELEMENT)
+ if (parser.get_node_type() != XMLParser::NODE_ELEMENT) {
continue; //no idea what this may be, but skipping anyway
+ }
String section = parser.get_node_name();
@@ -2564,10 +2391,8 @@ Error Collada::load(const String &p_path, int p_flags) {
_parse_asset(parser);
} else if (section.begins_with("library_")) {
-
_parse_library(parser);
} else if (section == "scene") {
-
_parse_scene(parser);
} else if (!parser.is_empty()) {
parser.skip_section(); // unknown section, likely headers
diff --git a/editor/import/collada.h b/editor/import/collada.h
index b74332fb22..90c6c47e0b 100644
--- a/editor/import/collada.h
+++ b/editor/import/collada.h
@@ -44,82 +44,65 @@ public:
};
struct Image {
-
String path;
};
struct Material {
-
String name;
String instance_effect;
};
struct Effect {
-
String name;
Map<String, Variant> params;
struct Channel {
-
- int uv_idx;
+ int uv_idx = 0;
String texture;
Color color;
- Channel() { uv_idx = 0; }
+ Channel() {}
};
Channel diffuse, specular, emission, bump;
- float shininess;
- bool found_double_sided;
- bool double_sided;
- bool unshaded;
+ float shininess = 40;
+ bool found_double_sided = false;
+ bool double_sided = true;
+ bool unshaded = false;
String get_texture_path(const String &p_source, Collada &state) const;
Effect() {
diffuse.color = Color(1, 1, 1, 1);
- double_sided = true;
- found_double_sided = false;
- shininess = 40;
- unshaded = false;
}
};
struct CameraData {
-
enum Mode {
MODE_PERSPECTIVE,
MODE_ORTHOGONAL
};
- Mode mode;
+ Mode mode = MODE_PERSPECTIVE;
union {
struct {
- float x_fov;
- float y_fov;
+ float x_fov = 0;
+ float y_fov = 0;
} perspective;
struct {
- float x_mag;
- float y_mag;
+ float x_mag = 0;
+ float y_mag = 0;
} orthogonal;
};
- float aspect;
- float z_near;
- float z_far;
-
- CameraData() :
- mode(MODE_PERSPECTIVE),
- aspect(1),
- z_near(0.1),
- z_far(100) {
- perspective.x_fov = 0;
- perspective.y_fov = 0;
- }
+ float aspect = 1;
+ float z_near = 0.1;
+ float z_far = 100;
+
+ CameraData() {}
};
struct LightData {
-
enum Mode {
MODE_AMBIENT,
MODE_DIRECTIONAL,
@@ -127,33 +110,23 @@ public:
MODE_SPOT
};
- Mode mode;
+ Mode mode = MODE_AMBIENT;
- Color color;
+ Color color = Color(1, 1, 1, 1);
- float constant_att;
- float linear_att;
- float quad_att;
-
- float spot_angle;
- float spot_exp;
-
- LightData() :
- mode(MODE_AMBIENT),
- color(Color(1, 1, 1, 1)),
- constant_att(0),
- linear_att(0),
- quad_att(0),
- spot_angle(45),
- spot_exp(1) {
- }
+ float constant_att = 0;
+ float linear_att = 0;
+ float quad_att = 0;
+
+ float spot_angle = 45;
+ float spot_exp = 1;
+
+ LightData() {}
};
struct MeshData {
-
String name;
struct Source {
-
Vector<float> array;
int stride;
};
@@ -161,16 +134,13 @@ public:
Map<String, Source> sources;
struct Vertices {
-
Map<String, String> sources;
};
Map<String, Vertices> vertices;
struct Primitives {
-
struct SourceRef {
-
String source;
int offset;
};
@@ -185,22 +155,17 @@ public:
Vector<Primitives> primitives;
- bool found_double_sided;
- bool double_sided;
+ bool found_double_sided = false;
+ bool double_sided = true;
- MeshData() {
- found_double_sided = false;
- double_sided = true;
- }
+ MeshData() {}
};
struct CurveData {
-
String name;
- bool closed;
+ bool closed = false;
struct Source {
-
Vector<String> sarray;
Vector<float> array;
int stride;
@@ -210,39 +175,30 @@ public:
Map<String, String> control_vertices;
- CurveData() {
-
- closed = false;
- }
+ CurveData() {}
};
- struct SkinControllerData {
+ struct SkinControllerData {
String base;
- bool use_idrefs;
+ bool use_idrefs = false;
Transform bind_shape;
struct Source {
-
Vector<String> sarray; //maybe for names
Vector<float> array;
- int stride;
- Source() {
- stride = 1;
- }
+ int stride = 1;
+ Source() {}
};
Map<String, Source> sources;
struct Joints {
-
Map<String, String> sources;
} joints;
struct Weights {
-
struct SourceRef {
-
String source;
int offset;
};
@@ -256,20 +212,18 @@ public:
Map<String, Transform> bone_rest_map;
- SkinControllerData() { use_idrefs = false; }
+ SkinControllerData() {}
};
struct MorphControllerData {
-
String mesh;
String mode;
struct Source {
-
- int stride;
+ int stride = 1;
Vector<String> sarray; //maybe for names
Vector<float> array;
- Source() { stride = 1; }
+ Source() {}
};
Map<String, Source> sources;
@@ -279,15 +233,14 @@ public:
};
struct Vertex {
-
- int idx;
+ int idx = 0;
Vector3 vertex;
Vector3 normal;
Vector3 uv;
Vector3 uv2;
Plane tangent;
Color color;
- int uid;
+ int uid = 0;
struct Weight {
int bone_idx;
float weight;
@@ -297,40 +250,40 @@ public:
Vector<Weight> weights;
void fix_weights() {
-
weights.sort();
if (weights.size() > 4) {
//cap to 4 and make weights add up 1
weights.resize(4);
float total = 0;
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++) {
total += weights[i].weight;
- if (total)
- for (int i = 0; i < 4; i++)
+ }
+ if (total) {
+ for (int i = 0; i < 4; i++) {
weights.write[i].weight /= total;
+ }
+ }
}
}
void fix_unit_scale(Collada &state);
bool operator<(const Vertex &p_vert) const {
-
if (uid == p_vert.uid) {
if (vertex == p_vert.vertex) {
if (normal == p_vert.normal) {
if (uv == p_vert.uv) {
if (uv2 == p_vert.uv2) {
-
if (!weights.empty() || !p_vert.weights.empty()) {
-
if (weights.size() == p_vert.weights.size()) {
-
for (int i = 0; i < weights.size(); i++) {
- if (weights[i].bone_idx != p_vert.weights[i].bone_idx)
+ if (weights[i].bone_idx != p_vert.weights[i].bone_idx) {
return weights[i].bone_idx < p_vert.weights[i].bone_idx;
+ }
- if (weights[i].weight != p_vert.weights[i].weight)
+ if (weights[i].weight != p_vert.weights[i].weight) {
return weights[i].weight < p_vert.weights[i].weight;
+ }
}
} else {
return weights.size() < p_vert.weights.size();
@@ -338,25 +291,27 @@ public:
}
return (color < p_vert.color);
- } else
+ } else {
return (uv2 < p_vert.uv2);
- } else
+ }
+ } else {
return (uv < p_vert.uv);
- } else
+ }
+ } else {
return (normal < p_vert.normal);
- } else
+ }
+ } else {
return vertex < p_vert.vertex;
- } else
+ }
+ } else {
return uid < p_vert.uid;
+ }
}
- Vertex() {
- uid = 0;
- idx = 0;
- }
+ Vertex() {}
};
- struct Node {
+ struct Node {
enum Type {
TYPE_NODE,
@@ -368,7 +323,6 @@ public:
};
struct XForm {
-
enum Op {
OP_ROTATE,
OP_SCALE,
@@ -382,54 +336,46 @@ public:
Vector<float> data;
};
- Type type;
+ Type type = TYPE_NODE;
String name;
String id;
String empty_draw_type;
- bool noname;
+ bool noname = false;
Vector<XForm> xform_list;
Transform default_transform;
Transform post_transform;
Vector<Node *> children;
- Node *parent;
+ Node *parent = nullptr;
Transform compute_transform(Collada &state) const;
Transform get_global_transform() const;
Transform get_transform() const;
- bool ignore_anim;
+ bool ignore_anim = false;
- Node() {
- noname = false;
- type = TYPE_NODE;
- parent = nullptr;
- ignore_anim = false;
- }
+ Node() {}
virtual ~Node() {
- for (int i = 0; i < children.size(); i++)
+ for (int i = 0; i < children.size(); i++) {
memdelete(children[i]);
+ }
};
};
struct NodeSkeleton : public Node {
-
NodeSkeleton() { type = TYPE_SKELETON; }
};
struct NodeJoint : public Node {
-
- NodeSkeleton *owner;
+ NodeSkeleton *owner = nullptr;
String sid;
NodeJoint() {
type = TYPE_JOINT;
- owner = nullptr;
}
};
struct NodeGeometry : public Node {
-
bool controller;
String source;
@@ -444,50 +390,43 @@ public:
};
struct NodeCamera : public Node {
-
String camera;
NodeCamera() { type = TYPE_CAMERA; }
};
struct NodeLight : public Node {
-
String light;
NodeLight() { type = TYPE_LIGHT; }
};
struct VisualScene {
-
String name;
Vector<Node *> root_nodes;
~VisualScene() {
- for (int i = 0; i < root_nodes.size(); i++)
+ for (int i = 0; i < root_nodes.size(); i++) {
memdelete(root_nodes[i]);
+ }
}
};
struct AnimationClip {
-
String name;
- float begin;
- float end;
+ float begin = 0;
+ float end = 1;
Vector<String> tracks;
- AnimationClip() {
- begin = 0;
- end = 1;
- }
+ AnimationClip() {}
};
struct AnimationTrack {
-
String id;
String target;
String param;
String component;
- bool property;
+ bool property = false;
enum InterpolationType {
INTERP_LINEAR,
@@ -495,7 +434,6 @@ public:
};
struct Key {
-
enum Type {
TYPE_FLOAT,
TYPE_MATRIX
@@ -505,16 +443,16 @@ public:
Vector<float> data;
Point2 in_tangent;
Point2 out_tangent;
- InterpolationType interp_type;
+ InterpolationType interp_type = INTERP_LINEAR;
- Key() { interp_type = INTERP_LINEAR; }
+ Key() {}
};
Vector<float> get_value_at_time(float p_time) const;
Vector<Key> keys;
- AnimationTrack() { property = false; }
+ AnimationTrack() {}
};
/****************/
@@ -522,15 +460,13 @@ public:
/****************/
struct State {
+ int import_flags = 0;
- int import_flags;
-
- float unit_scale;
- Vector3::Axis up_axis;
+ float unit_scale = 1.0;
+ Vector3::Axis up_axis = Vector3::AXIS_Y;
bool z_up;
struct Version {
-
int major, minor, rev;
bool operator<(const Version &p_ver) const { return (major == p_ver.major) ? ((minor == p_ver.minor) ? (rev < p_ver.rev) : minor < p_ver.minor) : major < p_ver.major; }
@@ -573,14 +509,9 @@ public:
Map<String, Vector<int>> referenced_tracks;
Map<String, Vector<int>> by_id_tracks;
- float animation_length;
+ float animation_length = 0;
- State() :
- import_flags(0),
- unit_scale(1.0),
- up_axis(Vector3::AXIS_Y),
- animation_length(0) {
- }
+ State() {}
} state;
Error load(const String &p_path, int p_flags = 0);
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 697ddfba96..12cbaaa885 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -45,7 +45,6 @@
#include "scene/resources/surface_tool.h"
struct ColladaImport {
-
Collada collada;
Node3D *scene;
@@ -101,7 +100,6 @@ struct ColladaImport {
void _pre_process_lights(Collada::Node *p_node);
ColladaImport() {
-
found_ambient = false;
found_directional = false;
force_make_tangents = false;
@@ -111,15 +109,16 @@ struct ColladaImport {
};
Error ColladaImport::_populate_skeleton(Skeleton3D *p_skeleton, Collada::Node *p_node, int &r_bone, int p_parent) {
-
- if (p_node->type != Collada::Node::TYPE_JOINT)
+ if (p_node->type != Collada::Node::TYPE_JOINT) {
return OK;
+ }
Collada::NodeJoint *joint = static_cast<Collada::NodeJoint *>(p_node);
p_skeleton->add_bone(p_node->name);
- if (p_parent >= 0)
+ if (p_parent >= 0) {
p_skeleton->set_bone_parent(r_bone, p_parent);
+ }
NodeMap nm;
nm.node = p_skeleton;
@@ -130,7 +129,6 @@ Error ColladaImport::_populate_skeleton(Skeleton3D *p_skeleton, Collada::Node *p
skeleton_bone_map[p_skeleton][joint->sid] = r_bone;
if (collada.state.bone_rest_map.has(joint->sid)) {
-
p_skeleton->set_bone_rest(r_bone, collada.fix_transform(collada.state.bone_rest_map[joint->sid]));
//should map this bone to something for animation?
} else {
@@ -139,22 +137,19 @@ Error ColladaImport::_populate_skeleton(Skeleton3D *p_skeleton, Collada::Node *p
int id = r_bone++;
for (int i = 0; i < p_node->children.size(); i++) {
-
Error err = _populate_skeleton(p_skeleton, p_node->children[i], r_bone, id);
- if (err)
+ if (err) {
return err;
+ }
}
return OK;
}
void ColladaImport::_pre_process_lights(Collada::Node *p_node) {
-
if (p_node->type == Collada::Node::TYPE_LIGHT) {
-
Collada::NodeLight *light = static_cast<Collada::NodeLight *>(p_node);
if (collada.state.light_data_map.has(light->light)) {
-
Collada::LightData &ld = collada.state.light_data_map[light->light];
if (ld.mode == Collada::LightData::MODE_AMBIENT) {
found_ambient = true;
@@ -166,18 +161,16 @@ void ColladaImport::_pre_process_lights(Collada::Node *p_node) {
}
}
- for (int i = 0; i < p_node->children.size(); i++)
+ for (int i = 0; i < p_node->children.size(); i++) {
_pre_process_lights(p_node->children[i]);
+ }
}
Error ColladaImport::_create_scene_skeletons(Collada::Node *p_node) {
-
if (p_node->type == Collada::Node::TYPE_SKELETON) {
-
Skeleton3D *sk = memnew(Skeleton3D);
int bone = 0;
for (int i = 0; i < p_node->children.size(); i++) {
-
_populate_skeleton(sk, p_node->children[i], bone, -1);
}
sk->localize_rests(); //after creating skeleton, rests must be localized...!
@@ -185,43 +178,38 @@ Error ColladaImport::_create_scene_skeletons(Collada::Node *p_node) {
}
for (int i = 0; i < p_node->children.size(); i++) {
-
Error err = _create_scene_skeletons(p_node->children[i]);
- if (err)
+ if (err) {
return err;
+ }
}
return OK;
}
Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
-
Node3D *node = nullptr;
switch (p_node->type) {
-
case Collada::Node::TYPE_NODE: {
-
node = memnew(Node3D);
} break;
case Collada::Node::TYPE_JOINT: {
-
return OK; // do nothing
} break;
case Collada::Node::TYPE_LIGHT: {
-
//node = memnew( Light)
Collada::NodeLight *light = static_cast<Collada::NodeLight *>(p_node);
if (collada.state.light_data_map.has(light->light)) {
-
Collada::LightData &ld = collada.state.light_data_map[light->light];
if (ld.mode == Collada::LightData::MODE_AMBIENT) {
-
- if (found_directional)
+ if (found_directional) {
return OK; //do nothing not needed
+ }
- if (!bool(GLOBAL_DEF("collada/use_ambient", false)))
+ if (!bool(GLOBAL_DEF("collada/use_ambient", false))) {
return OK;
+ }
//well, it's an ambient light..
Light3D *l = memnew(DirectionalLight3D);
//l->set_color(Light::COLOR_AMBIENT,ld.color);
@@ -230,7 +218,6 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
node = l;
} else if (ld.mode == Collada::LightData::MODE_DIRECTIONAL) {
-
//well, it's an ambient light..
Light3D *l = memnew(DirectionalLight3D);
/*
@@ -242,12 +229,11 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
*/
node = l;
} else {
-
Light3D *l;
- if (ld.mode == Collada::LightData::MODE_OMNI)
+ if (ld.mode == Collada::LightData::MODE_OMNI) {
l = memnew(OmniLight3D);
- else {
+ } else {
l = memnew(SpotLight3D);
//l->set_parameter(Light::PARAM_SPOT_ANGLE,ld.spot_angle);
//l->set_parameter(Light::PARAM_SPOT_ATTENUATION,ld.spot_exp);
@@ -261,43 +247,33 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
}
} else {
-
node = memnew(Node3D);
}
} break;
case Collada::Node::TYPE_CAMERA: {
-
Collada::NodeCamera *cam = static_cast<Collada::NodeCamera *>(p_node);
Camera3D *camera = memnew(Camera3D);
if (collada.state.camera_data_map.has(cam->camera)) {
-
const Collada::CameraData &cd = collada.state.camera_data_map[cam->camera];
switch (cd.mode) {
-
case Collada::CameraData::MODE_ORTHOGONAL: {
-
if (cd.orthogonal.y_mag) {
-
camera->set_keep_aspect_mode(Camera3D::KEEP_HEIGHT);
camera->set_orthogonal(cd.orthogonal.y_mag * 2.0, cd.z_near, cd.z_far);
} else if (!cd.orthogonal.y_mag && cd.orthogonal.x_mag) {
-
camera->set_keep_aspect_mode(Camera3D::KEEP_WIDTH);
camera->set_orthogonal(cd.orthogonal.x_mag * 2.0, cd.z_near, cd.z_far);
}
} break;
case Collada::CameraData::MODE_PERSPECTIVE: {
-
if (cd.perspective.y_fov) {
-
camera->set_perspective(cd.perspective.y_fov, cd.z_near, cd.z_far);
} else if (!cd.perspective.y_fov && cd.perspective.x_fov) {
-
camera->set_perspective(cd.perspective.x_fov / cd.aspect, cd.z_near, cd.z_far);
}
@@ -309,11 +285,9 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
} break;
case Collada::Node::TYPE_GEOMETRY: {
-
Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry *>(p_node);
if (collada.state.curve_data_map.has(ng->source)) {
-
node = memnew(Path3D);
} else {
//mesh since nothing else
@@ -322,15 +296,15 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
}
} break;
case Collada::Node::TYPE_SKELETON: {
-
ERR_FAIL_COND_V(!skeleton_map.has(p_node), ERR_CANT_CREATE);
Skeleton3D *sk = skeleton_map[p_node];
node = sk;
} break;
}
- if (p_node->name != "")
+ if (p_node->name != "") {
node->set_name(p_node->name);
+ }
NodeMap nm;
nm.node = node;
node_map[p_node->id] = nm;
@@ -347,16 +321,15 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
}
for (int i = 0; i < p_node->children.size(); i++) {
-
Error err = _create_scene(p_node->children[i], node);
- if (err)
+ if (err) {
return err;
+ }
}
return OK;
}
Error ColladaImport::_create_material(const String &p_target) {
-
ERR_FAIL_COND_V(material_cache.has(p_target), ERR_ALREADY_EXISTS);
ERR_FAIL_COND_V(!collada.state.material_map.has(p_target), ERR_INVALID_PARAMETER);
Collada::Material &src_mat = collada.state.material_map[p_target];
@@ -365,24 +338,22 @@ Error ColladaImport::_create_material(const String &p_target) {
Ref<StandardMaterial3D> material = memnew(StandardMaterial3D);
- if (src_mat.name != "")
+ if (src_mat.name != "") {
material->set_name(src_mat.name);
- else if (effect.name != "")
+ } else if (effect.name != "") {
material->set_name(effect.name);
+ }
// DIFFUSE
if (effect.diffuse.texture != "") {
-
String texfile = effect.get_texture_path(effect.diffuse.texture, collada);
if (texfile != "") {
-
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
Ref<Texture2D> texture = ResourceLoader::load(texfile, "Texture2D");
if (texture.is_valid()) {
-
material->set_texture(StandardMaterial3D::TEXTURE_ALBEDO, texture);
material->set_albedo(Color(1, 1, 1, 1));
//material->set_parameter(StandardMaterial3D::PARAM_DIFFUSE,Color(1,1,1,1));
@@ -397,10 +368,8 @@ Error ColladaImport::_create_material(const String &p_target) {
// SPECULAR
if (effect.specular.texture != "") {
-
String texfile = effect.get_texture_path(effect.specular.texture, collada);
if (texfile != "") {
-
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
@@ -424,17 +393,14 @@ Error ColladaImport::_create_material(const String &p_target) {
// EMISSION
if (effect.emission.texture != "") {
-
String texfile = effect.get_texture_path(effect.emission.texture, collada);
if (texfile != "") {
-
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
Ref<Texture2D> texture = ResourceLoader::load(texfile, "Texture2D");
if (texture.is_valid()) {
-
material->set_feature(StandardMaterial3D::FEATURE_EMISSION, true);
material->set_texture(StandardMaterial3D::TEXTURE_EMISSION, texture);
material->set_emission(Color(1, 1, 1, 1));
@@ -454,10 +420,8 @@ Error ColladaImport::_create_material(const String &p_target) {
// NORMAL
if (effect.bump.texture != "") {
-
String texfile = effect.get_texture_path(effect.bump.texture, collada);
if (texfile != "") {
-
if (texfile.begins_with("/")) {
texfile = texfile.replace_first("/", "res://");
}
@@ -490,33 +454,30 @@ Error ColladaImport::_create_material(const String &p_target) {
}
Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh>> p_morph_meshes, bool p_use_compression, bool p_use_mesh_material) {
-
bool local_xform_mirror = p_local_xform.basis.determinant() < 0;
if (p_morph_data) {
-
//add morphie target
ERR_FAIL_COND_V(!p_morph_data->targets.has("MORPH_TARGET"), ERR_INVALID_DATA);
String mt = p_morph_data->targets["MORPH_TARGET"];
ERR_FAIL_COND_V(!p_morph_data->sources.has(mt), ERR_INVALID_DATA);
int morph_targets = p_morph_data->sources[mt].sarray.size();
for (int i = 0; i < morph_targets; i++) {
-
String target = p_morph_data->sources[mt].sarray[i];
ERR_FAIL_COND_V(!collada.state.mesh_data_map.has(target), ERR_INVALID_DATA);
String name = collada.state.mesh_data_map[target].name;
p_mesh->add_blend_shape(name);
}
- if (p_morph_data->mode == "RELATIVE")
+ if (p_morph_data->mode == "RELATIVE") {
p_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_RELATIVE);
- else if (p_morph_data->mode == "NORMALIZED")
+ } else if (p_morph_data->mode == "NORMALIZED") {
p_mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED);
+ }
}
int surface = 0;
for (int p_i = 0; p_i < meshdata.primitives.size(); p_i++) {
-
const Collada::MeshData::Primitives &p = meshdata.primitives[p_i];
/* VERTEX SOURCE */
@@ -540,7 +501,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
int normal_ofs = 0;
if (p.sources.has("NORMAL")) {
-
String normal_source_id = p.sources["NORMAL"].source;
normal_ofs = p.sources["NORMAL"].offset;
ERR_FAIL_COND_V(!meshdata.sources.has(normal_source_id), ERR_INVALID_DATA);
@@ -551,7 +511,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
int binormal_ofs = 0;
if (p.sources.has("TEXBINORMAL")) {
-
String binormal_source_id = p.sources["TEXBINORMAL"].source;
binormal_ofs = p.sources["TEXBINORMAL"].offset;
ERR_FAIL_COND_V(!meshdata.sources.has(binormal_source_id), ERR_INVALID_DATA);
@@ -562,7 +521,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
int tangent_ofs = 0;
if (p.sources.has("TEXTANGENT")) {
-
String tangent_source_id = p.sources["TEXTANGENT"].source;
tangent_ofs = p.sources["TEXTANGENT"].offset;
ERR_FAIL_COND_V(!meshdata.sources.has(tangent_source_id), ERR_INVALID_DATA);
@@ -573,7 +531,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
int uv_ofs = 0;
if (p.sources.has("TEXCOORD0")) {
-
String uv_source_id = p.sources["TEXCOORD0"].source;
uv_ofs = p.sources["TEXCOORD0"].offset;
ERR_FAIL_COND_V(!meshdata.sources.has(uv_source_id), ERR_INVALID_DATA);
@@ -584,7 +541,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
int uv2_ofs = 0;
if (p.sources.has("TEXCOORD1")) {
-
String uv2_source_id = p.sources["TEXCOORD1"].source;
uv2_ofs = p.sources["TEXCOORD1"].offset;
ERR_FAIL_COND_V(!meshdata.sources.has(uv2_source_id), ERR_INVALID_DATA);
@@ -595,7 +551,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
int color_ofs = 0;
if (p.sources.has("COLOR")) {
-
String color_source_id = p.sources["COLOR"].source;
color_ofs = p.sources["COLOR"].offset;
ERR_FAIL_COND_V(!meshdata.sources.has(color_source_id), ERR_INVALID_DATA);
@@ -613,16 +568,13 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
bool has_weights = false;
if (p_skin_controller) {
-
const Collada::SkinControllerData::Source *weight_src = nullptr;
int weight_ofs = 0;
if (p_skin_controller->weights.sources.has("WEIGHT")) {
-
String weight_id = p_skin_controller->weights.sources["WEIGHT"].source;
weight_ofs = p_skin_controller->weights.sources["WEIGHT"].offset;
if (p_skin_controller->sources.has(weight_id)) {
-
weight_src = &p_skin_controller->sources[weight_id];
}
}
@@ -630,7 +582,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
int joint_ofs = 0;
if (p_skin_controller->weights.sources.has("JOINT")) {
-
joint_ofs = p_skin_controller->weights.sources["JOINT"].offset;
}
@@ -639,13 +590,11 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
int index_ofs = 0;
int wstride = p_skin_controller->weights.sources.size();
for (int w_i = 0; w_i < p_skin_controller->weights.sets.size(); w_i++) {
-
int amount = p_skin_controller->weights.sets[w_i];
Vector<Collada::Vertex::Weight> weights;
for (int a_i = 0; a_i < amount; a_i++) {
-
Collada::Vertex::Weight w;
int read_from = index_ofs + a_i * wstride;
@@ -656,8 +605,9 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
w.weight = weight_src->array[weight_index];
int bone_index = p_skin_controller->weights.indices[read_from + joint_ofs];
- if (bone_index == -1)
+ if (bone_index == -1) {
continue; //ignore this weight (refers to bind shape)
+ }
ERR_FAIL_INDEX_V(bone_index, bone_remap.size(), ERR_INVALID_DATA);
w.bone_idx = bone_remap[bone_index];
@@ -676,11 +626,14 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
//make sure weights always add up to 1
float total = 0;
- for (int i = 0; i < weights.size(); i++)
+ for (int i = 0; i < weights.size(); i++) {
total += weights[i].weight;
- if (total)
- for (int i = 0; i < weights.size(); i++)
+ }
+ if (total) {
+ for (int i = 0; i < weights.size(); i++) {
weights.write[i].weight /= total;
+ }
+ }
if (weights.size() == 0 || total == 0) { //if nothing, add a weight to bone 0
//no weights assigned
@@ -715,10 +668,8 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
int _prim_ofs = 0;
int vertidx = 0;
for (int p_j = 0; p_j < p.count; p_j++) {
-
int amount;
if (p.polygons.size()) {
-
ERR_FAIL_INDEX_V(p_j, p.polygons.size(), ERR_INVALID_DATA);
amount = p.polygons[p_j];
} else {
@@ -730,15 +681,15 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
int prev2[2] = { 0, 0 };
for (int j = 0; j < amount; j++) {
-
int src = _prim_ofs;
//_prim_ofs+=p.sources.size()
ERR_FAIL_INDEX_V(src, p.indices.size(), ERR_INVALID_DATA);
Collada::Vertex vertex;
- if (!p_optimize)
+ if (!p_optimize) {
vertex.uid = vertidx++;
+ }
int vertex_index = p.indices[src + vertex_ofs]; //used for index field (later used by controllers)
int vertex_pos = (vertex_src->stride ? vertex_src->stride : 3) * vertex_index;
@@ -750,13 +701,11 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
}
if (normal_src) {
-
int normal_pos = (normal_src->stride ? normal_src->stride : 3) * p.indices[src + normal_ofs];
ERR_FAIL_INDEX_V(normal_pos, normal_src->array.size(), ERR_INVALID_DATA);
vertex.normal = Vector3(normal_src->array[normal_pos + 0], normal_src->array[normal_pos + 1], normal_src->array[normal_pos + 2]);
if (tangent_src && binormal_src) {
-
int binormal_pos = (binormal_src->stride ? binormal_src->stride : 3) * p.indices[src + binormal_ofs];
ERR_FAIL_INDEX_V(binormal_pos, binormal_src->array.size(), ERR_INVALID_DATA);
Vector3 binormal = Vector3(binormal_src->array[binormal_pos + 0], binormal_src->array[binormal_pos + 1], binormal_src->array[binormal_pos + 2]);
@@ -771,21 +720,18 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
}
if (uv_src) {
-
int uv_pos = (uv_src->stride ? uv_src->stride : 2) * p.indices[src + uv_ofs];
ERR_FAIL_INDEX_V(uv_pos, uv_src->array.size(), ERR_INVALID_DATA);
vertex.uv = Vector3(uv_src->array[uv_pos + 0], 1.0 - uv_src->array[uv_pos + 1], 0);
}
if (uv2_src) {
-
int uv2_pos = (uv2_src->stride ? uv2_src->stride : 2) * p.indices[src + uv2_ofs];
ERR_FAIL_INDEX_V(uv2_pos, uv2_src->array.size(), ERR_INVALID_DATA);
vertex.uv2 = Vector3(uv2_src->array[uv2_pos + 0], 1.0 - uv2_src->array[uv2_pos + 1], 0);
}
if (color_src) {
-
int color_pos = (color_src->stride ? color_src->stride : 3) * p.indices[src + color_ofs]; // colors are RGB in collada..
ERR_FAIL_INDEX_V(color_pos, color_src->array.size(), ERR_INVALID_DATA);
vertex.color = Color(color_src->array[color_pos + 0], color_src->array[color_pos + 1], color_src->array[color_pos + 2], (color_src->stride > 3) ? color_src->array[color_pos + 3] : 1.0);
@@ -793,7 +739,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
#ifndef NO_UP_AXIS_SWAP
if (collada.state.up_axis == Vector3::AXIS_Z) {
-
Vector3 bn = vertex.normal.cross(vertex.tangent.normal) * vertex.tangent.d;
SWAP(vertex.vertex.z, vertex.vertex.y);
@@ -815,23 +760,21 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
//COLLADA_PRINT("vertex: "+vertex.vertex);
if (vertex_set.has(vertex)) {
-
index = vertex_set.find(vertex)->get().idx;
} else {
-
index = vertex_set.size();
vertex.idx = index;
vertex_set.insert(vertex);
}
//build triangles if needed
- if (j == 0)
+ if (j == 0) {
prev2[0] = index;
+ }
if (j >= 2) {
//insert indices in reverse order (collada uses CCW as frontface)
if (local_xform_mirror) {
-
indices_list.push_back(prev2[0]);
indices_list.push_back(prev2[1]);
indices_list.push_back(index);
@@ -852,16 +795,13 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
vertex_array.resize(vertex_set.size());
for (Set<Collada::Vertex>::Element *F = vertex_set.front(); F; F = F->next()) {
-
vertex_array.write[F->get().idx] = F->get();
}
if (has_weights) {
-
//if skeleton, localize
Transform local_xform = p_local_xform;
for (int i = 0; i < vertex_array.size(); i++) {
-
vertex_array.write[i].vertex = local_xform.xform(vertex_array[i].vertex);
vertex_array.write[i].normal = local_xform.basis.xform(vertex_array[i].normal).normalized();
vertex_array.write[i].tangent.normal = local_xform.basis.xform(vertex_array[i].tangent.normal).normalized();
@@ -878,20 +818,20 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
/*****************/
{
-
Ref<StandardMaterial3D> material;
{
-
if (p_material_map.has(p.material)) {
String target = p_material_map[p.material].target;
if (!material_cache.has(target)) {
Error err = _create_material(target);
- if (!err)
+ if (!err) {
material = material_cache[target];
- } else
+ }
+ } else {
material = material_cache[target];
+ }
} else if (p.material != "") {
WARN_PRINT("Collada: Unreferenced material in geometry instance: " + p.material);
@@ -931,7 +871,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
bones.write[l] = vertex_array[k].weights[l].bone_idx;
//sum += vertex_array[k].weights[l].weight;
} else {
-
weights.write[l] = 0;
bones.write[l] = 0;
}
@@ -954,7 +893,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
}
if ((!binormal_src || !tangent_src) && normal_src && uv_src && force_make_tangents) {
-
surftool->generate_tangents();
}
@@ -972,7 +910,6 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
////////////////////////////
for (int mi = 0; mi < p_morph_meshes.size(); mi++) {
-
Array a = p_morph_meshes[mi]->surface_get_arrays(surface);
//add valid weight and bone arrays if they exist, TODO check if they are unique to shape (generally not)
@@ -1007,21 +944,16 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
}
Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compression) {
-
if (p_node->type == Collada::Node::TYPE_GEOMETRY && node_map.has(p_node->id)) {
-
Node3D *node = node_map[p_node->id].node;
Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry *>(p_node);
if (Object::cast_to<Path3D>(node)) {
-
Path3D *path = Object::cast_to<Path3D>(node);
if (curve_cache.has(ng->source)) {
-
path->set_curve(curve_cache[ng->source]);
} else {
-
Ref<Curve3D> c = memnew(Curve3D);
const Collada::CurveData &cd = collada.state.curve_data_map[ng->source];
@@ -1048,19 +980,18 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
ERR_FAIL_COND_V(interps.stride != 1, ERR_INVALID_DATA);
const Collada::CurveData::Source *tilts = nullptr;
- if (cd.control_vertices.has("TILT") && cd.sources.has(cd.control_vertices["TILT"]))
+ if (cd.control_vertices.has("TILT") && cd.sources.has(cd.control_vertices["TILT"])) {
tilts = &cd.sources[cd.control_vertices["TILT"]];
+ }
int pc = vertices.array.size() / 3;
for (int i = 0; i < pc; i++) {
-
Vector3 pos(vertices.array[i * 3 + 0], vertices.array[i * 3 + 1], vertices.array[i * 3 + 2]);
Vector3 in(in_tangents.array[i * 3 + 0], in_tangents.array[i * 3 + 1], in_tangents.array[i * 3 + 2]);
Vector3 out(out_tangents.array[i * 3 + 0], out_tangents.array[i * 3 + 1], out_tangents.array[i * 3 + 2]);
#ifndef NO_UP_AXIS_SWAP
if (collada.state.up_axis == Vector3::AXIS_Z) {
-
SWAP(pos.y, pos.z);
pos.z = -pos.z;
SWAP(in.y, in.z);
@@ -1074,8 +1005,9 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
out *= collada.state.unit_scale;
c->add_point(pos, in - pos, out - pos);
- if (tilts)
+ if (tilts) {
c->set_point_tilt(i, tilts->array[i]);
+ }
}
curve_cache[ng->source] = c;
@@ -1084,7 +1016,6 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
}
if (Object::cast_to<MeshInstance3D>(node)) {
-
Collada::NodeGeometry *ng2 = static_cast<Collada::NodeGeometry *>(p_node);
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(node);
@@ -1099,11 +1030,9 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
Vector<Ref<ArrayMesh>> morphs;
if (ng2->controller) {
-
String ngsource = ng2->source;
if (collada.state.skin_controller_data_map.has(ngsource)) {
-
ERR_FAIL_COND_V(!collada.state.skin_controller_data_map.has(ngsource), ERR_INVALID_DATA);
skin = &collada.state.skin_controller_data_map[ngsource];
@@ -1147,7 +1076,6 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
bone_remap.resize(joint_src->sarray.size());
for (int i = 0; i < bone_remap.size(); i++) {
-
String str = joint_src->sarray[i];
ERR_FAIL_COND_V(!bone_remap_map.has(str), ERR_INVALID_DATA);
bone_remap.write[i] = bone_remap_map[str];
@@ -1155,7 +1083,6 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
}
if (collada.state.morph_controller_data_map.has(ngsource)) {
-
//it's a morph!!
morph = &collada.state.morph_controller_data_map[ngsource];
meshid = morph->mesh;
@@ -1167,7 +1094,6 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
valid = true;
Vector<String> names = morph->sources[target].sarray;
for (int i = 0; i < names.size(); i++) {
-
String meshid2 = names[i];
if (collada.state.mesh_data_map.has(meshid2)) {
Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
@@ -1183,8 +1109,9 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
}
}
- if (!valid)
+ if (!valid) {
morphs.clear();
+ }
ngsource = "";
}
}
@@ -1211,19 +1138,16 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
mesh_cache[meshid] = mesh;
} else {
-
WARN_PRINT("Collada: Will not import geometry: " + meshid);
}
}
if (!mesh.is_null()) {
-
mi->set_mesh(mesh);
if (!use_mesh_builtin_materials) {
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
for (int i = 0; i < meshdata.primitives.size(); i++) {
-
String matname = meshdata.primitives[i].material;
if (ng2->material_map.has(matname)) {
@@ -1232,10 +1156,12 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
Ref<Material> material;
if (!material_cache.has(target)) {
Error err = _create_material(target);
- if (!err)
+ if (!err) {
material = material_cache[target];
- } else
+ }
+ } else {
material = material_cache[target];
+ }
mi->set_surface_material(i, material);
} else if (matname != "") {
@@ -1248,16 +1174,15 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
}
for (int i = 0; i < p_node->children.size(); i++) {
-
Error err = _create_resources(p_node->children[i], p_use_compression);
- if (err)
+ if (err) {
return err;
+ }
}
return OK;
}
Error ColladaImport::load(const String &p_path, int p_flags, bool p_force_make_tangents, bool p_use_compression) {
-
Error err = collada.load(p_path, p_flags);
ERR_FAIL_COND_V_MSG(err, err, "Cannot load file '" + p_path + "'.");
@@ -1269,13 +1194,11 @@ Error ColladaImport::load(const String &p_path, int p_flags, bool p_force_make_t
//determine what's going on with the lights
for (int i = 0; i < vs.root_nodes.size(); i++) {
-
_pre_process_lights(vs.root_nodes[i]);
}
//import scene
for (int i = 0; i < vs.root_nodes.size(); i++) {
-
Error err2 = _create_scene_skeletons(vs.root_nodes[i]);
if (err2 != OK) {
memdelete(scene);
@@ -1284,7 +1207,6 @@ Error ColladaImport::load(const String &p_path, int p_flags, bool p_force_make_t
}
for (int i = 0; i < vs.root_nodes.size(); i++) {
-
Error err2 = _create_scene(vs.root_nodes[i], scene);
if (err2 != OK) {
memdelete(scene);
@@ -1305,48 +1227,36 @@ Error ColladaImport::load(const String &p_path, int p_flags, bool p_force_make_t
}
void ColladaImport::_fix_param_animation_tracks() {
-
for (Map<String, Collada::Node *>::Element *E = collada.state.scene_map.front(); E; E = E->next()) {
-
Collada::Node *n = E->get();
switch (n->type) {
-
case Collada::Node::TYPE_NODE: {
// ? do nothing
} break;
case Collada::Node::TYPE_JOINT: {
-
} break;
case Collada::Node::TYPE_SKELETON: {
-
} break;
case Collada::Node::TYPE_LIGHT: {
-
} break;
case Collada::Node::TYPE_CAMERA: {
-
} break;
case Collada::Node::TYPE_GEOMETRY: {
-
Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry *>(n);
// test source(s)
String source = ng->source;
while (source != "") {
-
if (collada.state.skin_controller_data_map.has(source)) {
-
const Collada::SkinControllerData &skin = collada.state.skin_controller_data_map[source];
//nothing to animate here i think
source = skin.base;
} else if (collada.state.morph_controller_data_map.has(source)) {
-
const Collada::MorphControllerData &morph = collada.state.morph_controller_data_map[source];
if (morph.targets.has("MORPH_WEIGHT") && morph.targets.has("MORPH_TARGET")) {
-
String weights = morph.targets["MORPH_WEIGHT"];
String targets = morph.targets["MORPH_TARGET"];
//fails here
@@ -1358,11 +1268,9 @@ void ColladaImport::_fix_param_animation_tracks() {
ERR_FAIL_COND(weight_src.array.size() != target_src.sarray.size());
for (int i = 0; i < weight_src.array.size(); i++) {
-
String track_name = weights + "(" + itos(i) + ")";
String mesh_name = target_src.sarray[i];
if (collada.state.mesh_name_map.has(mesh_name) && collada.state.referenced_tracks.has(track_name)) {
-
const Vector<int> &rt = collada.state.referenced_tracks[track_name];
for (int rti = 0; rti < rt.size(); rti++) {
@@ -1379,7 +1287,6 @@ void ColladaImport::_fix_param_animation_tracks() {
}
source = morph.mesh;
} else {
-
source = ""; // for now nothing else supported
}
}
@@ -1390,24 +1297,20 @@ void ColladaImport::_fix_param_animation_tracks() {
}
void ColladaImport::create_animations(bool p_make_tracks_in_all_bones, bool p_import_value_tracks) {
-
_fix_param_animation_tracks();
for (int i = 0; i < collada.state.animation_clips.size(); i++) {
-
- for (int j = 0; j < collada.state.animation_clips[i].tracks.size(); j++)
+ for (int j = 0; j < collada.state.animation_clips[i].tracks.size(); j++) {
tracks_in_clips.insert(collada.state.animation_clips[i].tracks[j]);
+ }
}
for (int i = 0; i < collada.state.animation_tracks.size(); i++) {
-
const Collada::AnimationTrack &at = collada.state.animation_tracks[i];
String node;
if (!node_map.has(at.target)) {
-
if (node_name_map.has(at.target)) {
-
node = node_name_map[at.target];
} else {
WARN_PRINT("Collada: Couldn't find node: " + at.target);
@@ -1418,23 +1321,21 @@ void ColladaImport::create_animations(bool p_make_tracks_in_all_bones, bool p_im
}
if (at.property) {
-
valid_animated_properties.push_back(i);
} else {
-
node_map[node].anim_tracks.push_back(i);
valid_animated_nodes.insert(node);
}
}
create_animation(-1, p_make_tracks_in_all_bones, p_import_value_tracks);
- for (int i = 0; i < collada.state.animation_clips.size(); i++)
+ for (int i = 0; i < collada.state.animation_clips.size(); i++) {
create_animation(i, p_make_tracks_in_all_bones, p_import_value_tracks);
+ }
}
void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones, bool p_import_value_tracks) {
-
Ref<Animation> animation = Ref<Animation>(memnew(Animation));
if (p_clip == -1) {
@@ -1444,9 +1345,9 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
}
for (Map<String, NodeMap>::Element *E = node_map.front(); E; E = E->next()) {
-
- if (E->get().bone < 0)
+ if (E->get().bone < 0) {
continue;
+ }
bones_with_animation[E->key()] = false;
}
//store and validate tracks
@@ -1458,15 +1359,11 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
Set<int> track_filter;
if (p_clip == -1) {
-
for (int i = 0; i < collada.state.animation_clips.size(); i++) {
-
int tc = collada.state.animation_clips[i].tracks.size();
for (int j = 0; j < tc; j++) {
-
String n = collada.state.animation_clips[i].tracks[j];
if (collada.state.by_id_tracks.has(n)) {
-
const Vector<int> &ti = collada.state.by_id_tracks[n];
for (int k = 0; k < ti.size(); k++) {
track_filter.insert(ti[k]);
@@ -1475,13 +1372,10 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
}
}
} else {
-
int tc = collada.state.animation_clips[p_clip].tracks.size();
for (int j = 0; j < tc; j++) {
-
String n = collada.state.animation_clips[p_clip].tracks[j];
if (collada.state.by_id_tracks.has(n)) {
-
const Vector<int> &ti = collada.state.by_id_tracks[n];
for (int k = 0; k < ti.size(); k++) {
track_filter.insert(ti[k]);
@@ -1499,11 +1393,11 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
float snapshot_interval = 1.0 / bake_fps; //should be customizable somewhere...
float anim_length = collada.state.animation_length;
- if (p_clip >= 0 && collada.state.animation_clips[p_clip].end)
+ if (p_clip >= 0 && collada.state.animation_clips[p_clip].end) {
anim_length = collada.state.animation_clips[p_clip].end;
+ }
while (f < anim_length) {
-
base_snapshots.push_back(f);
f += snapshot_interval;
@@ -1518,11 +1412,9 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
bool tracks_found = false;
for (Set<String>::Element *E = valid_animated_nodes.front(); E; E = E->next()) {
-
// take snapshots
if (!collada.state.scene_map.has(E->get())) {
-
continue;
}
@@ -1539,7 +1431,6 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
Collada::Node *cn = collada.state.scene_map[E->get()];
if (cn->ignore_anim) {
-
continue;
}
@@ -1554,25 +1445,23 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
//use snapshot keys from anim track instead, because this was most likely exported baked
const Collada::AnimationTrack &at = collada.state.animation_tracks[nm.anim_tracks.front()->get()];
snapshots.clear();
- for (int i = 0; i < at.keys.size(); i++)
+ for (int i = 0; i < at.keys.size(); i++) {
snapshots.push_back(at.keys[i].time);
+ }
}
for (int i = 0; i < snapshots.size(); i++) {
-
for (List<int>::Element *ET = nm.anim_tracks.front(); ET; ET = ET->next()) {
//apply tracks
if (p_clip == -1) {
-
if (track_filter.has(ET->get())) {
-
continue;
}
} else {
-
- if (!track_filter.has(ET->get()))
+ if (!track_filter.has(ET->get())) {
continue;
+ }
}
found_anim = true;
@@ -1581,9 +1470,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
int xform_idx = -1;
for (int j = 0; j < cn->xform_list.size(); j++) {
-
if (cn->xform_list[j].id == at.param) {
-
xform_idx = j;
break;
}
@@ -1623,10 +1510,8 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
//make bone transform relative to rest (in case of skeleton)
Skeleton3D *sk = Object::cast_to<Skeleton3D>(nm.node);
if (sk) {
-
xform = sk->get_bone_rest(nm.bone).affine_inverse() * xform;
} else {
-
ERR_PRINT("Collada: Invalid skeleton");
}
}
@@ -1640,24 +1525,24 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
}
if (nm.bone >= 0) {
- if (found_anim)
+ if (found_anim) {
bones_with_animation[E->get()] = true;
+ }
}
- if (found_anim)
+ if (found_anim) {
tracks_found = true;
- else {
+ } else {
animation->remove_track(track);
}
}
if (p_make_tracks_in_all_bones) {
-
//some bones may lack animation, but since we don't store pose as a property, we must add keyframes!
for (Map<String, bool>::Element *E = bones_with_animation.front(); E; E = E->next()) {
-
- if (E->get())
+ if (E->get()) {
continue;
+ }
NodeMap &nm = node_map[E->key()];
String path = scene->get_path_to(nm.node);
@@ -1695,24 +1580,24 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
if (p_import_value_tracks) {
for (int i = 0; i < valid_animated_properties.size(); i++) {
-
int ti = valid_animated_properties[i];
if (p_clip == -1) {
-
- if (track_filter.has(ti))
+ if (track_filter.has(ti)) {
continue;
+ }
} else {
-
- if (!track_filter.has(ti))
+ if (!track_filter.has(ti)) {
continue;
+ }
}
const Collada::AnimationTrack &at = collada.state.animation_tracks[ti];
// take snapshots
- if (!collada.state.scene_map.has(at.target))
+ if (!collada.state.scene_map.has(at.target)) {
continue;
+ }
NodeMap &nm = node_map[at.target];
String path = scene->get_path_to(nm.node);
@@ -1725,7 +1610,6 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
animation->track_set_imported(track, true); //helps merging later
for (int j = 0; j < at.keys.size(); j++) {
-
float time = at.keys[j].time;
Variant value;
Vector<float> data = at.keys[j].data;
@@ -1748,7 +1632,6 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
}
if (tracks_found) {
-
animations.push_back(animation);
}
}
@@ -1758,19 +1641,19 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
/*********************************************************************************/
uint32_t EditorSceneImporterCollada::get_import_flags() const {
-
return IMPORT_SCENE | IMPORT_ANIMATION;
}
-void EditorSceneImporterCollada::get_extensions(List<String> *r_extensions) const {
+void EditorSceneImporterCollada::get_extensions(List<String> *r_extensions) const {
r_extensions->push_back("dae");
}
-Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
ColladaImport state;
uint32_t flags = Collada::IMPORT_FLAG_SCENE;
- if (p_flags & IMPORT_ANIMATION)
+ if (p_flags & IMPORT_ANIMATION) {
flags |= Collada::IMPORT_FLAG_ANIMATION;
+ }
state.use_mesh_builtin_materials = !(p_flags & IMPORT_MATERIALS_IN_INSTANCES);
state.bake_fps = p_bake_fps;
@@ -1780,15 +1663,13 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
ERR_FAIL_COND_V_MSG(err != OK, nullptr, "Cannot load scene from file '" + p_path + "'.");
if (state.missing_textures.size()) {
-
/*
- for(int i=0;i<state.missing_textures.size();i++) {
- EditorNode::add_io_error("Texture Not Found: "+state.missing_textures[i]);
- }
- */
+ for(int i=0;i<state.missing_textures.size();i++) {
+ EditorNode::add_io_error("Texture Not Found: "+state.missing_textures[i]);
+ }
+ */
if (r_missing_deps) {
-
for (int i = 0; i < state.missing_textures.size(); i++) {
//EditorNode::add_io_error("Texture Not Found: "+state.missing_textures[i]);
r_missing_deps->push_back(state.missing_textures[i]);
@@ -1797,18 +1678,17 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
}
if (p_flags & IMPORT_ANIMATION) {
-
state.create_animations(p_flags & IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS, p_flags & EditorSceneImporter::IMPORT_ANIMATION_KEEP_VALUE_TRACKS);
AnimationPlayer *ap = memnew(AnimationPlayer);
for (int i = 0; i < state.animations.size(); i++) {
String name;
- if (state.animations[i]->get_name() == "")
+ if (state.animations[i]->get_name() == "") {
name = "default";
- else
+ } else {
name = state.animations[i]->get_name();
+ }
if (p_flags & IMPORT_ANIMATION_DETECT_LOOP) {
-
if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) {
state.animations.write[i]->set_loop(true);
}
@@ -1824,7 +1704,6 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
}
Ref<Animation> EditorSceneImporterCollada::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
-
ColladaImport state;
state.use_mesh_builtin_materials = false;
@@ -1833,15 +1712,16 @@ Ref<Animation> EditorSceneImporterCollada::import_animation(const String &p_path
ERR_FAIL_COND_V_MSG(err != OK, RES(), "Cannot load animation from file '" + p_path + "'.");
state.create_animations(p_flags & EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS, p_flags & EditorSceneImporter::IMPORT_ANIMATION_KEEP_VALUE_TRACKS);
- if (state.scene)
+ if (state.scene) {
memdelete(state.scene);
+ }
- if (state.animations.size() == 0)
+ if (state.animations.size() == 0) {
return Ref<Animation>();
+ }
Ref<Animation> anim = state.animations[0];
String base = p_path.get_basename().to_lower();
if (p_flags & IMPORT_ANIMATION_DETECT_LOOP) {
-
if (base.begins_with("loop") || base.ends_with("loop") || base.begins_with("cycle") || base.ends_with("cycle")) {
anim->set_loop(true);
}
diff --git a/editor/import/editor_import_collada.h b/editor/import/editor_import_collada.h
index 932a064e76..57c694b698 100644
--- a/editor/import/editor_import_collada.h
+++ b/editor/import/editor_import_collada.h
@@ -34,7 +34,6 @@
#include "editor/import/resource_importer_scene.h"
class EditorSceneImporterCollada : public EditorSceneImporter {
-
GDCLASS(EditorSceneImporterCollada, EditorSceneImporter);
public:
diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp
index aad378c94f..6d46d4d2e9 100644
--- a/editor/import/editor_import_plugin.cpp
+++ b/editor/import/editor_import_plugin.cpp
@@ -87,7 +87,6 @@ int EditorImportPlugin::get_import_order() const {
}
void EditorImportPlugin::get_import_options(List<ResourceImporter::ImportOption> *r_options, int p_preset) const {
-
ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("get_import_options")));
Array needed;
needed.push_back("name");
@@ -131,7 +130,6 @@ bool EditorImportPlugin::get_option_visibility(const String &p_option, const Map
}
Error EditorImportPlugin::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
-
ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("import")), ERR_UNAVAILABLE);
Dictionary options;
Array platform_variants, gen_files;
@@ -153,7 +151,6 @@ Error EditorImportPlugin::import(const String &p_source_file, const String &p_sa
}
void EditorImportPlugin::_bind_methods() {
-
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_importer_name"));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_visible_name"));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "get_preset_count"));
diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp
index 6ad2aa4142..6ffff09ce5 100644
--- a/editor/import/editor_scene_importer_gltf.cpp
+++ b/editor/import/editor_scene_importer_gltf.cpp
@@ -44,17 +44,15 @@
#include "scene/resources/surface_tool.h"
uint32_t EditorSceneImporterGLTF::get_import_flags() const {
-
return IMPORT_SCENE | IMPORT_ANIMATION;
}
-void EditorSceneImporterGLTF::get_extensions(List<String> *r_extensions) const {
+void EditorSceneImporterGLTF::get_extensions(List<String> *r_extensions) const {
r_extensions->push_back("gltf");
r_extensions->push_back("glb");
}
Error EditorSceneImporterGLTF::_parse_json(const String &p_path, GLTFState &state) {
-
Error err;
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err);
if (!f) {
@@ -81,7 +79,6 @@ Error EditorSceneImporterGLTF::_parse_json(const String &p_path, GLTFState &stat
}
Error EditorSceneImporterGLTF::_parse_glb(const String &p_path, GLTFState &state) {
-
Error err;
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err);
if (!f) {
@@ -163,7 +160,6 @@ String EditorSceneImporterGLTF::_sanitize_scene_name(const String &name) {
}
String EditorSceneImporterGLTF::_gen_unique_name(GLTFState &state, const String &p_name) {
-
const String s_name = _sanitize_scene_name(p_name);
String name;
@@ -204,7 +200,6 @@ String EditorSceneImporterGLTF::_sanitize_bone_name(const String &name) {
}
String EditorSceneImporterGLTF::_gen_unique_bone_name(GLTFState &state, const GLTFSkeletonIndex skel_i, const String &p_name) {
-
const String s_name = _sanitize_bone_name(p_name);
String name;
@@ -227,7 +222,6 @@ String EditorSceneImporterGLTF::_gen_unique_bone_name(GLTFState &state, const GL
}
Error EditorSceneImporterGLTF::_parse_scenes(GLTFState &state) {
-
ERR_FAIL_COND_V(!state.json.has("scenes"), ERR_FILE_CORRUPT);
const Array &scenes = state.json["scenes"];
int loaded_scene = 0;
@@ -257,11 +251,9 @@ Error EditorSceneImporterGLTF::_parse_scenes(GLTFState &state) {
}
Error EditorSceneImporterGLTF::_parse_nodes(GLTFState &state) {
-
ERR_FAIL_COND_V(!state.json.has("nodes"), ERR_FILE_CORRUPT);
const Array &nodes = state.json["nodes"];
for (int i = 0; i < nodes.size(); i++) {
-
GLTFNode *node = memnew(GLTFNode);
const Dictionary &n = nodes[i];
@@ -281,7 +273,6 @@ Error EditorSceneImporterGLTF::_parse_nodes(GLTFState &state) {
node->xform = _arr_to_xform(n["matrix"]);
} else {
-
if (n.has("translation")) {
node->translation = _arr_to_vec3(n["translation"]);
}
@@ -308,7 +299,6 @@ Error EditorSceneImporterGLTF::_parse_nodes(GLTFState &state) {
// build the hierarchy
for (GLTFNodeIndex node_i = 0; node_i < state.nodes.size(); node_i++) {
-
for (int j = 0; j < state.nodes[node_i]->children.size(); j++) {
GLTFNodeIndex child_i = state.nodes[node_i]->children[j];
@@ -325,7 +315,6 @@ Error EditorSceneImporterGLTF::_parse_nodes(GLTFState &state) {
}
void EditorSceneImporterGLTF::_compute_node_heights(GLTFState &state) {
-
state.root_nodes.clear();
for (GLTFNodeIndex node_i = 0; node_i < state.nodes.size(); ++node_i) {
GLTFNode *node = state.nodes[node_i];
@@ -347,7 +336,6 @@ void EditorSceneImporterGLTF::_compute_node_heights(GLTFState &state) {
}
static Vector<uint8_t> _parse_base64_uri(const String &uri) {
-
int start = uri.find(",");
ERR_FAIL_COND_V(start == -1, Vector<uint8_t>());
@@ -367,20 +355,18 @@ static Vector<uint8_t> _parse_base64_uri(const String &uri) {
}
Error EditorSceneImporterGLTF::_parse_buffers(GLTFState &state, const String &p_base_path) {
-
- if (!state.json.has("buffers"))
+ if (!state.json.has("buffers")) {
return OK;
+ }
const Array &buffers = state.json["buffers"];
for (GLTFBufferIndex i = 0; i < buffers.size(); i++) {
-
if (i == 0 && state.glb_data.size()) {
state.buffers.push_back(state.glb_data);
} else {
const Dictionary &buffer = buffers[i];
if (buffer.has("uri")) {
-
Vector<uint8_t> buffer_data;
String uri = buffer["uri"];
@@ -388,7 +374,6 @@ Error EditorSceneImporterGLTF::_parse_buffers(GLTFState &state, const String &p_
//embedded data
buffer_data = _parse_base64_uri(uri);
} else {
-
uri = p_base_path.plus_file(uri).replace("\\", "/"); //fix for windows
buffer_data = FileAccess::get_file_as_array(uri);
ERR_FAIL_COND_V(buffer.size() == 0, ERR_PARSE_ERROR);
@@ -408,11 +393,9 @@ Error EditorSceneImporterGLTF::_parse_buffers(GLTFState &state, const String &p_
}
Error EditorSceneImporterGLTF::_parse_buffer_views(GLTFState &state) {
-
ERR_FAIL_COND_V(!state.json.has("bufferViews"), ERR_FILE_CORRUPT);
const Array &buffers = state.json["bufferViews"];
for (GLTFBufferViewIndex i = 0; i < buffers.size(); i++) {
-
const Dictionary &d = buffers[i];
GLTFBufferView buffer_view;
@@ -444,33 +427,37 @@ Error EditorSceneImporterGLTF::_parse_buffer_views(GLTFState &state) {
}
EditorSceneImporterGLTF::GLTFType EditorSceneImporterGLTF::_get_type_from_str(const String &p_string) {
-
- if (p_string == "SCALAR")
+ if (p_string == "SCALAR") {
return TYPE_SCALAR;
+ }
- if (p_string == "VEC2")
+ if (p_string == "VEC2") {
return TYPE_VEC2;
- if (p_string == "VEC3")
+ }
+ if (p_string == "VEC3") {
return TYPE_VEC3;
- if (p_string == "VEC4")
+ }
+ if (p_string == "VEC4") {
return TYPE_VEC4;
+ }
- if (p_string == "MAT2")
+ if (p_string == "MAT2") {
return TYPE_MAT2;
- if (p_string == "MAT3")
+ }
+ if (p_string == "MAT3") {
return TYPE_MAT3;
- if (p_string == "MAT4")
+ }
+ if (p_string == "MAT4") {
return TYPE_MAT4;
+ }
ERR_FAIL_V(TYPE_SCALAR);
}
Error EditorSceneImporterGLTF::_parse_accessors(GLTFState &state) {
-
ERR_FAIL_COND_V(!state.json.has("accessors"), ERR_FILE_CORRUPT);
const Array &accessors = state.json["accessors"];
for (GLTFAccessorIndex i = 0; i < accessors.size(); i++) {
-
const Dictionary &d = accessors[i];
GLTFAccessor accessor;
@@ -536,21 +523,25 @@ Error EditorSceneImporterGLTF::_parse_accessors(GLTFState &state) {
}
String EditorSceneImporterGLTF::_get_component_type_name(const uint32_t p_component) {
-
switch (p_component) {
- case COMPONENT_TYPE_BYTE: return "Byte";
- case COMPONENT_TYPE_UNSIGNED_BYTE: return "UByte";
- case COMPONENT_TYPE_SHORT: return "Short";
- case COMPONENT_TYPE_UNSIGNED_SHORT: return "UShort";
- case COMPONENT_TYPE_INT: return "Int";
- case COMPONENT_TYPE_FLOAT: return "Float";
+ case COMPONENT_TYPE_BYTE:
+ return "Byte";
+ case COMPONENT_TYPE_UNSIGNED_BYTE:
+ return "UByte";
+ case COMPONENT_TYPE_SHORT:
+ return "Short";
+ case COMPONENT_TYPE_UNSIGNED_SHORT:
+ return "UShort";
+ case COMPONENT_TYPE_INT:
+ return "Int";
+ case COMPONENT_TYPE_FLOAT:
+ return "Float";
}
return "<Error>";
}
String EditorSceneImporterGLTF::_get_type_name(const GLTFType p_component) {
-
static const char *names[] = {
"float",
"vec2",
@@ -565,7 +556,6 @@ String EditorSceneImporterGLTF::_get_type_name(const GLTFType p_component) {
}
Error EditorSceneImporterGLTF::_decode_buffer_view(GLTFState &state, double *dst, const GLTFBufferViewIndex p_buffer_view, const int skip_every, const int skip_bytes, const int element_size, const int count, const GLTFType type, const int component_count, const int component_type, const int component_size, const bool normalized, const int byte_offset, const bool for_vertex) {
-
const GLTFBufferView &bv = state.buffer_views[p_buffer_view];
int stride = bv.byte_stride ? bv.byte_stride : element_size;
@@ -591,11 +581,9 @@ Error EditorSceneImporterGLTF::_decode_buffer_view(GLTFState &state, double *dst
//fill everything as doubles
for (int i = 0; i < count; i++) {
-
const uint8_t *src = &bufptr[offset + i * stride];
for (int j = 0; j < component_count; j++) {
-
if (skip_every && j > 0 && (j % skip_every) == 0) {
src += skip_bytes;
}
@@ -653,14 +641,25 @@ Error EditorSceneImporterGLTF::_decode_buffer_view(GLTFState &state, double *dst
}
int EditorSceneImporterGLTF::_get_component_type_size(const int component_type) {
-
switch (component_type) {
- case COMPONENT_TYPE_BYTE: return 1; break;
- case COMPONENT_TYPE_UNSIGNED_BYTE: return 1; break;
- case COMPONENT_TYPE_SHORT: return 2; break;
- case COMPONENT_TYPE_UNSIGNED_SHORT: return 2; break;
- case COMPONENT_TYPE_INT: return 4; break;
- case COMPONENT_TYPE_FLOAT: return 4; break;
+ case COMPONENT_TYPE_BYTE:
+ return 1;
+ break;
+ case COMPONENT_TYPE_UNSIGNED_BYTE:
+ return 1;
+ break;
+ case COMPONENT_TYPE_SHORT:
+ return 2;
+ break;
+ case COMPONENT_TYPE_UNSIGNED_SHORT:
+ return 2;
+ break;
+ case COMPONENT_TYPE_INT:
+ return 4;
+ break;
+ case COMPONENT_TYPE_FLOAT:
+ return 4;
+ break;
default: {
ERR_FAIL_V(0);
}
@@ -669,7 +668,6 @@ int EditorSceneImporterGLTF::_get_component_type_size(const int component_type)
}
Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
//spec, for reference:
//https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#data-alignment
@@ -692,7 +690,6 @@ Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, const
switch (a.component_type) {
case COMPONENT_TYPE_BYTE:
case COMPONENT_TYPE_UNSIGNED_BYTE: {
-
if (a.type == TYPE_MAT2) {
skip_every = 2;
skip_bytes = 2;
@@ -722,12 +719,12 @@ Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, const
double *dst = dst_buffer.ptrw();
if (a.buffer_view >= 0) {
-
ERR_FAIL_INDEX_V(a.buffer_view, state.buffer_views.size(), Vector<double>());
const Error err = _decode_buffer_view(state, dst, a.buffer_view, skip_every, skip_bytes, element_size, a.count, a.type, component_count, a.component_type, component_size, a.normalized, a.byte_offset, p_for_vertex);
- if (err != OK)
+ if (err != OK) {
return Vector<double>();
+ }
} else {
//fill with zeros, as bufferview is not defined.
@@ -743,14 +740,16 @@ Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, const
const int indices_component_size = _get_component_type_size(a.sparse_indices_component_type);
Error err = _decode_buffer_view(state, indices.ptrw(), a.sparse_indices_buffer_view, 0, 0, indices_component_size, a.sparse_count, TYPE_SCALAR, 1, a.sparse_indices_component_type, indices_component_size, false, a.sparse_indices_byte_offset, false);
- if (err != OK)
+ if (err != OK) {
return Vector<double>();
+ }
Vector<double> data;
data.resize(component_count * a.sparse_count);
err = _decode_buffer_view(state, data.ptrw(), a.sparse_values_buffer_view, skip_every, skip_bytes, element_size, a.sparse_count, a.type, component_count, a.component_type, component_size, a.normalized, a.sparse_values_byte_offset, p_for_vertex);
- if (err != OK)
+ if (err != OK) {
return Vector<double>();
+ }
for (int i = 0; i < indices.size(); i++) {
const int write_offset = int(indices[i]) * component_count;
@@ -765,12 +764,12 @@ Vector<double> EditorSceneImporterGLTF::_decode_accessor(GLTFState &state, const
}
Vector<int> EditorSceneImporterGLTF::_decode_accessor_as_ints(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<int> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
const double *attribs_ptr = attribs.ptr();
const int ret_size = attribs.size();
@@ -785,12 +784,12 @@ Vector<int> EditorSceneImporterGLTF::_decode_accessor_as_ints(GLTFState &state,
}
Vector<float> EditorSceneImporterGLTF::_decode_accessor_as_floats(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<float> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
const double *attribs_ptr = attribs.ptr();
const int ret_size = attribs.size();
@@ -805,12 +804,12 @@ Vector<float> EditorSceneImporterGLTF::_decode_accessor_as_floats(GLTFState &sta
}
Vector<Vector2> EditorSceneImporterGLTF::_decode_accessor_as_vec2(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Vector2> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 2 != 0, ret);
const double *attribs_ptr = attribs.ptr();
@@ -826,12 +825,12 @@ Vector<Vector2> EditorSceneImporterGLTF::_decode_accessor_as_vec2(GLTFState &sta
}
Vector<Vector3> EditorSceneImporterGLTF::_decode_accessor_as_vec3(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Vector3> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 3 != 0, ret);
const double *attribs_ptr = attribs.ptr();
@@ -847,12 +846,12 @@ Vector<Vector3> EditorSceneImporterGLTF::_decode_accessor_as_vec3(GLTFState &sta
}
Vector<Color> EditorSceneImporterGLTF::_decode_accessor_as_color(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Color> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
const int type = state.accessors[p_accessor].type;
ERR_FAIL_COND_V(!(type == TYPE_VEC3 || type == TYPE_VEC4), ret);
@@ -875,12 +874,12 @@ Vector<Color> EditorSceneImporterGLTF::_decode_accessor_as_color(GLTFState &stat
}
Vector<Quat> EditorSceneImporterGLTF::_decode_accessor_as_quat(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Quat> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
const double *attribs_ptr = attribs.ptr();
@@ -893,13 +892,14 @@ Vector<Quat> EditorSceneImporterGLTF::_decode_accessor_as_quat(GLTFState &state,
}
return ret;
}
-Vector<Transform2D> EditorSceneImporterGLTF::_decode_accessor_as_xform2d(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
+Vector<Transform2D> EditorSceneImporterGLTF::_decode_accessor_as_xform2d(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Transform2D> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
ret.resize(attribs.size() / 4);
@@ -911,12 +911,12 @@ Vector<Transform2D> EditorSceneImporterGLTF::_decode_accessor_as_xform2d(GLTFSta
}
Vector<Basis> EditorSceneImporterGLTF::_decode_accessor_as_basis(GLTFState &state, const GLTFAccessorIndex p_accessor, bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Basis> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 9 != 0, ret);
ret.resize(attribs.size() / 9);
@@ -929,12 +929,12 @@ Vector<Basis> EditorSceneImporterGLTF::_decode_accessor_as_basis(GLTFState &stat
}
Vector<Transform> EditorSceneImporterGLTF::_decode_accessor_as_xform(GLTFState &state, const GLTFAccessorIndex p_accessor, const bool p_for_vertex) {
-
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Transform> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 16 != 0, ret);
ret.resize(attribs.size() / 16);
@@ -948,13 +948,12 @@ Vector<Transform> EditorSceneImporterGLTF::_decode_accessor_as_xform(GLTFState &
}
Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
-
- if (!state.json.has("meshes"))
+ if (!state.json.has("meshes")) {
return OK;
+ }
Array meshes = state.json["meshes"];
for (GLTFMeshIndex i = 0; i < meshes.size(); i++) {
-
print_verbose("glTF: Parsing mesh: " + itos(i));
Dictionary d = meshes[i];
@@ -967,7 +966,6 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
const Dictionary &extras = d.has("extras") ? (Dictionary)d["extras"] : Dictionary();
for (int j = 0; j < primitives.size(); j++) {
-
Dictionary p = primitives[j];
Array array;
@@ -1075,24 +1073,15 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
array[Mesh::ARRAY_INDEX] = indices;
}
- bool generated_tangents = false;
- Variant erased_indices;
+ bool generate_tangents = (primitive == Mesh::PRIMITIVE_TRIANGLES && !a.has("TANGENT") && a.has("TEXCOORD_0") && a.has("NORMAL"));
- if (primitive == Mesh::PRIMITIVE_TRIANGLES && !a.has("TANGENT") && a.has("TEXCOORD_0") && a.has("NORMAL")) {
+ if (generate_tangents) {
//must generate mikktspace tangents.. ergh..
Ref<SurfaceTool> st;
st.instance();
st->create_from_triangle_arrays(array);
- if (!p.has("targets")) {
- //morph targets should not be reindexed, as array size might differ
- //removing indices is the best bet here
- st->deindex();
- erased_indices = a[Mesh::ARRAY_INDEX];
- a[Mesh::ARRAY_INDEX] = Variant();
- }
st->generate_tangents();
array = st->commit_to_arrays();
- generated_tangents = true;
}
Array morphs;
@@ -1114,7 +1103,6 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
}
for (int k = 0; k < targets.size(); k++) {
-
const Dictionary &t = targets[k];
Array array_copy;
@@ -1132,7 +1120,6 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
const int size = src_varr.size();
ERR_FAIL_COND_V(size == 0, ERR_PARSE_ERROR);
{
-
const int max_idx = varr.size();
varr.resize(size);
@@ -1179,7 +1166,6 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
Vector<float> tangents_v4;
{
-
int max_idx = tangents_v3.size();
int size4 = src_tangents.size();
@@ -1190,7 +1176,6 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
const float *r4 = src_tangents.ptr();
for (int l = 0; l < size4 / 4; l++) {
-
if (l < max_idx) {
w4[l * 4 + 0] = r3[l].x + r4[l * 4 + 0];
w4[l * 4 + 1] = r3[l].y + r4[l * 4 + 1];
@@ -1207,10 +1192,9 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
array_copy[Mesh::ARRAY_TANGENT] = tangents_v4;
}
- if (generated_tangents) {
+ if (generate_tangents) {
Ref<SurfaceTool> st;
st.instance();
- array_copy[Mesh::ARRAY_INDEX] = erased_indices; //needed for tangent generation, erased by deindex
st->create_from_triangle_arrays(array_copy);
st->deindex();
st->generate_tangents();
@@ -1251,13 +1235,12 @@ Error EditorSceneImporterGLTF::_parse_meshes(GLTFState &state) {
}
Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_base_path) {
-
- if (!state.json.has("images"))
+ if (!state.json.has("images")) {
return OK;
+ }
const Array &images = state.json["images"];
for (int i = 0; i < images.size(); i++) {
-
const Dictionary &d = images[i];
String mimetype;
@@ -1279,7 +1262,6 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
data_ptr = data.ptr();
data_size = data.size();
} else {
-
uri = p_base_path.plus_file(uri).replace("\\", "/"); //fix for windows
Ref<Texture2D> texture = ResourceLoader::load(uri);
state.images.push_back(texture);
@@ -1347,13 +1329,12 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
}
Error EditorSceneImporterGLTF::_parse_textures(GLTFState &state) {
-
- if (!state.json.has("textures"))
+ if (!state.json.has("textures")) {
return OK;
+ }
const Array &textures = state.json["textures"];
for (GLTFTextureIndex i = 0; i < textures.size(); i++) {
-
const Dictionary &d = textures[i];
ERR_FAIL_COND_V(!d.has("source"), ERR_PARSE_ERROR);
@@ -1376,13 +1357,12 @@ Ref<Texture2D> EditorSceneImporterGLTF::_get_texture(GLTFState &state, const GLT
}
Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) {
-
- if (!state.json.has("materials"))
+ if (!state.json.has("materials")) {
return OK;
+ }
const Array &materials = state.json["materials"];
for (GLTFMaterialIndex i = 0; i < materials.size(); i++) {
-
const Dictionary &d = materials[i];
Ref<StandardMaterial3D> material;
@@ -1392,7 +1372,6 @@ Error EditorSceneImporterGLTF::_parse_materials(GLTFState &state) {
}
if (d.has("pbrMetallicRoughness")) {
-
const Dictionary &mr = d["pbrMetallicRoughness"];
if (mr.has("baseColorFactor")) {
const Array &arr = mr["baseColorFactor"];
@@ -1526,7 +1505,6 @@ EditorSceneImporterGLTF::GLTFNodeIndex EditorSceneImporterGLTF::_find_highest_no
}
bool EditorSceneImporterGLTF::_capture_nodes_in_skin(GLTFState &state, GLTFSkin &skin, const GLTFNodeIndex node_index) {
-
bool found_joint = false;
for (int i = 0; i < state.nodes[node_index]->children.size(); ++i) {
@@ -1550,7 +1528,6 @@ bool EditorSceneImporterGLTF::_capture_nodes_in_skin(GLTFState &state, GLTFSkin
}
void EditorSceneImporterGLTF::_capture_nodes_for_multirooted_skin(GLTFState &state, GLTFSkin &skin) {
-
DisjointSet<GLTFNodeIndex> disjoint_set;
for (int i = 0; i < skin.joints.size(); ++i) {
@@ -1584,7 +1561,6 @@ void EditorSceneImporterGLTF::_capture_nodes_for_multirooted_skin(GLTFState &sta
// Go up the tree till all of the multiple roots of the skin are at the same hierarchy level.
// This sucks, but 99% of all game engines (not just Godot) would have this same issue.
for (int i = 0; i < roots.size(); ++i) {
-
GLTFNodeIndex current_node = roots[i];
while (state.nodes[current_node]->height > maxHeight) {
GLTFNodeIndex parent = state.nodes[current_node]->parent;
@@ -1632,7 +1608,6 @@ void EditorSceneImporterGLTF::_capture_nodes_for_multirooted_skin(GLTFState &sta
}
Error EditorSceneImporterGLTF::_expand_skin(GLTFState &state, GLTFSkin &skin) {
-
_capture_nodes_for_multirooted_skin(state, skin);
// Grab all nodes that lay in between skin joints/nodes
@@ -1678,7 +1653,6 @@ Error EditorSceneImporterGLTF::_expand_skin(GLTFState &state, GLTFSkin &skin) {
}
Error EditorSceneImporterGLTF::_verify_skin(GLTFState &state, GLTFSkin &skin) {
-
// This may seem duplicated from expand_skins, but this is really a sanity check! (so it kinda is)
// In case additional interpolating logic is added to the skins, this will help ensure that you
// do not cause it to self implode into a fiery blaze
@@ -1744,15 +1718,14 @@ Error EditorSceneImporterGLTF::_verify_skin(GLTFState &state, GLTFSkin &skin) {
}
Error EditorSceneImporterGLTF::_parse_skins(GLTFState &state) {
-
- if (!state.json.has("skins"))
+ if (!state.json.has("skins")) {
return OK;
+ }
const Array &skins = state.json["skins"];
// Create the base skins, and mark nodes that are joints
for (int i = 0; i < skins.size(); i++) {
-
const Dictionary &d = skins[i];
GLTFSkin skin;
@@ -1802,7 +1775,6 @@ Error EditorSceneImporterGLTF::_parse_skins(GLTFState &state) {
}
Error EditorSceneImporterGLTF::_determine_skeletons(GLTFState &state) {
-
// Using a disjoint set, we are going to potentially combine all skins that are actually branches
// of a main skeleton, or treat skins defining the same set of nodes as ONE skeleton.
// This is another unclear issue caused by the current glTF specification.
@@ -1880,7 +1852,6 @@ Error EditorSceneImporterGLTF::_determine_skeletons(GLTFState &state) {
// Mark all the skins actual skeletons, after we have merged them
for (GLTFSkeletonIndex skel_i = 0; skel_i < skeleton_owners.size(); ++skel_i) {
-
const GLTFNodeIndex skeleton_owner = skeleton_owners[skel_i];
GLTFSkeleton skeleton;
@@ -1935,7 +1906,6 @@ Error EditorSceneImporterGLTF::_determine_skeletons(GLTFState &state) {
}
Error EditorSceneImporterGLTF::_reparent_non_joint_skeleton_subtrees(GLTFState &state, GLTFSkeleton &skeleton, const Vector<GLTFNodeIndex> &non_joints) {
-
DisjointSet<GLTFNodeIndex> subtree_set;
// Populate the disjoint set with ONLY non joints that are in the skeleton hierarchy (non_joints vector)
@@ -1995,8 +1965,9 @@ Error EditorSceneImporterGLTF::_reparent_to_fake_joint(GLTFState &state, GLTFSke
state.nodes.push_back(fake_joint);
// We better not be a joint, or we messed up in our logic
- if (node->joint)
+ if (node->joint) {
return FAILED;
+ }
fake_joint->translation = node->translation;
fake_joint->rotation = node->rotation;
@@ -2050,7 +2021,6 @@ Error EditorSceneImporterGLTF::_reparent_to_fake_joint(GLTFState &state, GLTFSke
}
Error EditorSceneImporterGLTF::_determine_skeleton_roots(GLTFState &state, const GLTFSkeletonIndex skel_i) {
-
DisjointSet<GLTFNodeIndex> disjoint_set;
for (GLTFNodeIndex i = 0; i < state.nodes.size(); ++i) {
@@ -2105,7 +2075,6 @@ Error EditorSceneImporterGLTF::_determine_skeleton_roots(GLTFState &state, const
Error EditorSceneImporterGLTF::_create_skeletons(GLTFState &state) {
for (GLTFSkeletonIndex skel_i = 0; skel_i < state.skeletons.size(); ++skel_i) {
-
GLTFSkeleton &gltf_skeleton = state.skeletons.write[skel_i];
Skeleton3D *skeleton = memnew(Skeleton3D);
@@ -2206,7 +2175,6 @@ Error EditorSceneImporterGLTF::_create_skins(GLTFState &state) {
const bool has_ibms = !gltf_skin.inverse_binds.empty();
for (int joint_i = 0; joint_i < gltf_skin.joints_original.size(); ++joint_i) {
-
Transform xform;
if (has_ibms) {
xform = gltf_skin.inverse_binds[joint_i];
@@ -2245,7 +2213,6 @@ bool EditorSceneImporterGLTF::_skins_are_same(const Ref<Skin> &skin_a, const Ref
}
for (int i = 0; i < skin_a->get_bind_count(); ++i) {
-
if (skin_a->get_bind_bone(i) != skin_b->get_bind_bone(i)) {
return false;
}
@@ -2276,21 +2243,19 @@ void EditorSceneImporterGLTF::_remove_duplicate_skins(GLTFState &state) {
}
Error EditorSceneImporterGLTF::_parse_cameras(GLTFState &state) {
-
- if (!state.json.has("cameras"))
+ if (!state.json.has("cameras")) {
return OK;
+ }
const Array &cameras = state.json["cameras"];
for (GLTFCameraIndex i = 0; i < cameras.size(); i++) {
-
const Dictionary &d = cameras[i];
GLTFCamera camera;
ERR_FAIL_COND_V(!d.has("type"), ERR_PARSE_ERROR);
const String &type = d["type"];
if (type == "orthographic") {
-
camera.perspective = false;
if (d.has("orthographic")) {
const Dictionary &og = d["orthographic"];
@@ -2302,7 +2267,6 @@ Error EditorSceneImporterGLTF::_parse_cameras(GLTFState &state) {
}
} else if (type == "perspective") {
-
camera.perspective = true;
if (d.has("perspective")) {
const Dictionary &ppt = d["perspective"];
@@ -2326,20 +2290,20 @@ Error EditorSceneImporterGLTF::_parse_cameras(GLTFState &state) {
}
Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
-
- if (!state.json.has("animations"))
+ if (!state.json.has("animations")) {
return OK;
+ }
const Array &animations = state.json["animations"];
for (GLTFAnimationIndex i = 0; i < animations.size(); i++) {
-
const Dictionary &d = animations[i];
GLTFAnimation animation;
- if (!d.has("channels") || !d.has("samplers"))
+ if (!d.has("channels") || !d.has("samplers")) {
continue;
+ }
Array channels = d["channels"];
Array samplers = d["samplers"];
@@ -2353,10 +2317,10 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
}
for (int j = 0; j < channels.size(); j++) {
-
const Dictionary &c = channels[j];
- if (!c.has("target"))
+ if (!c.has("target")) {
continue;
+ }
const Dictionary &t = c["target"];
if (!t.has("node") || !t.has("path")) {
@@ -2463,13 +2427,13 @@ Error EditorSceneImporterGLTF::_parse_animations(GLTFState &state) {
}
void EditorSceneImporterGLTF::_assign_scene_names(GLTFState &state) {
-
for (int i = 0; i < state.nodes.size(); i++) {
GLTFNode *n = state.nodes[i];
// Any joints get unique names generated when the skeleton is made, unique to the skeleton
- if (n->skeleton >= 0)
+ if (n->skeleton >= 0) {
continue;
+ }
if (n->name.empty()) {
if (n->mesh >= 0) {
@@ -2486,7 +2450,6 @@ void EditorSceneImporterGLTF::_assign_scene_names(GLTFState &state) {
}
BoneAttachment3D *EditorSceneImporterGLTF::_generate_bone_attachment(GLTFState &state, Skeleton3D *skeleton, const GLTFNodeIndex node_index) {
-
const GLTFNode *gltf_node = state.nodes[node_index];
const GLTFNode *bone_node = state.nodes[gltf_node->parent];
@@ -2550,7 +2513,6 @@ Node3D *EditorSceneImporterGLTF::_generate_spatial(GLTFState &state, Node *scene
}
void EditorSceneImporterGLTF::_generate_scene_node(GLTFState &state, Node *scene_parent, Node3D *scene_root, const GLTFNodeIndex node_index) {
-
const GLTFNode *gltf_node = state.nodes[node_index];
Node3D *current_node = nullptr;
@@ -2615,14 +2577,11 @@ void EditorSceneImporterGLTF::_generate_scene_node(GLTFState &state, Node *scene
template <class T>
struct EditorSceneImporterGLTFInterpolate {
-
T lerp(const T &a, const T &b, float c) const {
-
return a + (b - a) * c;
}
T catmull_rom(const T &p0, const T &p1, const T &p2, const T &p3, float t) {
-
const float t2 = t * t;
const float t3 = t2 * t;
@@ -2644,7 +2603,6 @@ struct EditorSceneImporterGLTFInterpolate {
// thank you for existing, partial specialization
template <>
struct EditorSceneImporterGLTFInterpolate<Quat> {
-
Quat lerp(const Quat &a, const Quat &b, const float c) const {
ERR_FAIL_COND_V_MSG(!a.is_normalized(), Quat(), "The quaternion \"a\" must be normalized.");
ERR_FAIL_COND_V_MSG(!b.is_normalized(), Quat(), "The quaternion \"b\" must be normalized.");
@@ -2669,12 +2627,12 @@ struct EditorSceneImporterGLTFInterpolate<Quat> {
template <class T>
T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, const float p_time, const GLTFAnimation::Interpolation p_interp) {
-
//could use binary search, worth it?
int idx = -1;
for (int i = 0; i < p_times.size(); i++) {
- if (p_times[i] > p_time)
+ if (p_times[i] > p_time) {
break;
+ }
idx++;
}
@@ -2682,7 +2640,6 @@ T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, cons
switch (p_interp) {
case GLTFAnimation::INTERP_LINEAR: {
-
if (idx == -1) {
return p_values[0];
} else if (idx >= p_times.size() - 1) {
@@ -2695,7 +2652,6 @@ T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, cons
} break;
case GLTFAnimation::INTERP_STEP: {
-
if (idx == -1) {
return p_values[0];
} else if (idx >= p_times.size() - 1) {
@@ -2706,7 +2662,6 @@ T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, cons
} break;
case GLTFAnimation::INTERP_CATMULLROMSPLINE: {
-
if (idx == -1) {
return p_values[1];
} else if (idx >= p_times.size() - 1) {
@@ -2719,7 +2674,6 @@ T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, cons
} break;
case GLTFAnimation::INTERP_CUBIC_SPLINE: {
-
if (idx == -1) {
return p_values[1];
} else if (idx >= p_times.size() - 1) {
@@ -2742,7 +2696,6 @@ T EditorSceneImporterGLTF::_interpolate_track(const Vector<float> &p_times, cons
}
void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlayer *ap, const GLTFAnimationIndex index, const int bake_fps) {
-
const GLTFAnimation &anim = state.animations[index];
String name = anim.name;
@@ -2762,7 +2715,6 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
float length = 0;
for (Map<int, GLTFAnimation::Track>::Element *E = anim.tracks.front(); E; E = E->next()) {
-
const GLTFAnimation::Track &track = E->get();
//need to find the path
NodePath node_path;
@@ -2830,7 +2782,6 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
bool last = false;
while (true) {
-
Vector3 pos = base_pos;
Quat rot = base_rot;
Vector3 scale = base_scale;
@@ -2848,7 +2799,6 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
}
if (node->skeleton >= 0) {
-
Transform xform;
xform.basis.set_quat_scale(rot, scale);
xform.origin = pos;
@@ -2950,7 +2900,6 @@ void EditorSceneImporterGLTF::_process_mesh_instances(GLTFState &state, Node3D *
}
Node3D *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, const int p_bake_fps) {
-
Node3D *root = memnew(Node3D);
// scene_name is already unique
@@ -2977,20 +2926,21 @@ Node3D *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, const int p_b
}
Node *EditorSceneImporterGLTF::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
-
GLTFState state;
if (p_path.to_lower().ends_with("glb")) {
//binary file
//text file
Error err = _parse_glb(p_path, state);
- if (err)
+ if (err) {
return nullptr;
+ }
} else {
//text file
Error err = _parse_json(p_path, state);
- if (err)
+ if (err) {
return nullptr;
+ }
}
ERR_FAIL_COND_V(!state.json.has("asset"), nullptr);
@@ -3007,78 +2957,93 @@ Node *EditorSceneImporterGLTF::import_scene(const String &p_path, uint32_t p_fla
/* STEP 0 PARSE SCENE */
Error err = _parse_scenes(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 1 PARSE NODES */
err = _parse_nodes(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 2 PARSE BUFFERS */
err = _parse_buffers(state, p_path.get_base_dir());
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 3 PARSE BUFFER VIEWS */
err = _parse_buffer_views(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 4 PARSE ACCESSORS */
err = _parse_accessors(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 5 PARSE IMAGES */
err = _parse_images(state, p_path.get_base_dir());
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 6 PARSE TEXTURES */
err = _parse_textures(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 7 PARSE TEXTURES */
err = _parse_materials(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 9 PARSE SKINS */
err = _parse_skins(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 10 DETERMINE SKELETONS */
err = _determine_skeletons(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 11 CREATE SKELETONS */
err = _create_skeletons(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 12 CREATE SKINS */
err = _create_skins(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 13 PARSE MESHES (we have enough info now) */
err = _parse_meshes(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 14 PARSE CAMERAS */
err = _parse_cameras(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 15 PARSE ANIMATIONS */
err = _parse_animations(state);
- if (err != OK)
+ if (err != OK) {
return nullptr;
+ }
/* STEP 16 ASSIGN SCENE NAMES */
_assign_scene_names(state);
@@ -3090,7 +3055,6 @@ Node *EditorSceneImporterGLTF::import_scene(const String &p_path, uint32_t p_fla
}
Ref<Animation> EditorSceneImporterGLTF::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
-
return Ref<Animation>();
}
diff --git a/editor/import/editor_scene_importer_gltf.h b/editor/import/editor_scene_importer_gltf.h
index d127a87782..eee978ce16 100644
--- a/editor/import/editor_scene_importer_gltf.h
+++ b/editor/import/editor_scene_importer_gltf.h
@@ -40,7 +40,6 @@ class BoneAttachment3D;
class MeshInstance3D;
class EditorSceneImporterGLTF : public EditorSceneImporter {
-
GDCLASS(EditorSceneImporterGLTF, EditorSceneImporter);
typedef int GLTFAccessorIndex;
@@ -92,92 +91,59 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
String _get_type_name(const GLTFType p_component);
struct GLTFNode {
-
//matrices need to be transformed to this
- GLTFNodeIndex parent;
- int height;
+ GLTFNodeIndex parent = -1;
+ int height = -1;
Transform xform;
String name;
- GLTFMeshIndex mesh;
- GLTFCameraIndex camera;
- GLTFSkinIndex skin;
+ GLTFMeshIndex mesh = -1;
+ GLTFCameraIndex camera = -1;
+ GLTFSkinIndex skin = -1;
- GLTFSkeletonIndex skeleton;
- bool joint;
+ GLTFSkeletonIndex skeleton = -1;
+ bool joint = false;
Vector3 translation;
Quat rotation;
- Vector3 scale;
+ Vector3 scale = Vector3(1, 1, 1);
Vector<int> children;
- GLTFNodeIndex fake_joint_parent;
-
- GLTFNode() :
- parent(-1),
- height(-1),
- mesh(-1),
- camera(-1),
- skin(-1),
- skeleton(-1),
- joint(false),
- translation(0, 0, 0),
- scale(Vector3(1, 1, 1)),
- fake_joint_parent(-1) {}
+ GLTFNodeIndex fake_joint_parent = -1;
+
+ GLTFNode() {}
};
struct GLTFBufferView {
-
- GLTFBufferIndex buffer;
- int byte_offset;
- int byte_length;
- int byte_stride;
- bool indices;
+ GLTFBufferIndex buffer = -1;
+ int byte_offset = 0;
+ int byte_length = 0;
+ int byte_stride = 0;
+ bool indices = false;
//matrices need to be transformed to this
- GLTFBufferView() :
- buffer(-1),
- byte_offset(0),
- byte_length(0),
- byte_stride(0),
- indices(false) {
- }
+ GLTFBufferView() {}
};
struct GLTFAccessor {
-
- GLTFBufferViewIndex buffer_view;
- int byte_offset;
- int component_type;
- bool normalized;
- int count;
+ GLTFBufferViewIndex buffer_view = 0;
+ int byte_offset = 0;
+ int component_type = 0;
+ bool normalized = false;
+ int count = 0;
GLTFType type;
- float min;
- float max;
- int sparse_count;
- int sparse_indices_buffer_view;
- int sparse_indices_byte_offset;
- int sparse_indices_component_type;
- int sparse_values_buffer_view;
- int sparse_values_byte_offset;
-
- GLTFAccessor() {
- buffer_view = 0;
- byte_offset = 0;
- component_type = 0;
- normalized = false;
- count = 0;
- min = 0;
- max = 0;
- sparse_count = 0;
- sparse_indices_buffer_view = 0;
- sparse_indices_byte_offset = 0;
- sparse_indices_component_type = 0;
- sparse_values_buffer_view = 0;
- sparse_values_byte_offset = 0;
- }
+ float min = 0;
+ float max = 0;
+ int sparse_count = 0;
+ int sparse_indices_buffer_view = 0;
+ int sparse_indices_byte_offset = 0;
+ int sparse_indices_component_type = 0;
+ int sparse_values_buffer_view = 0;
+ int sparse_values_byte_offset = 0;
+
+ GLTFAccessor() {}
};
struct GLTFTexture {
GLTFImageIndex src_image;
@@ -192,21 +158,19 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
Vector<GLTFNodeIndex> roots;
// The created Skeleton for the scene
- Skeleton3D *godot_skeleton;
+ Skeleton3D *godot_skeleton = nullptr;
// Set of unique bone names for the skeleton
Set<String> unique_names;
- GLTFSkeleton() :
- godot_skeleton(nullptr) {
- }
+ GLTFSkeleton() {}
};
struct GLTFSkin {
String name;
// The "skeleton" property defined in the gltf spec. -1 = Scene Root
- GLTFNodeIndex skin_root;
+ GLTFNodeIndex skin_root = -1;
Vector<GLTFNodeIndex> joints_original;
Vector<Transform> inverse_binds;
@@ -226,7 +190,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
Vector<GLTFNodeIndex> roots;
// The GLTF Skeleton this Skin points to (after we determine skeletons)
- GLTFSkeletonIndex skeleton;
+ GLTFSkeletonIndex skeleton = -1;
// A mapping from the joint indices (in the order of joints_original) to the
// Godot Skeleton's bone_indices
@@ -237,9 +201,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
// to the generated skeleton for the mesh instances.
Ref<Skin> godot_skin;
- GLTFSkin() :
- skin_root(-1),
- skeleton(-1) {}
+ GLTFSkin() {}
};
struct GLTFMesh {
@@ -248,18 +210,12 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
};
struct GLTFCamera {
+ bool perspective = true;
+ float fov_size = 64;
+ float zfar = 500;
+ float znear = 0.1;
- bool perspective;
- float fov_size;
- float zfar;
- float znear;
-
- GLTFCamera() {
- perspective = true;
- fov_size = 65;
- zfar = 500;
- znear = 0.1;
- }
+ GLTFCamera() {}
};
struct GLTFAnimation {
@@ -280,7 +236,6 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
};
struct Track {
-
Channel<Vector3> translation_track;
Channel<Quat> rotation_track;
Channel<Vector3> scale_track;
@@ -293,7 +248,6 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
};
struct GLTFState {
-
Dictionary json;
int major_version;
int minor_version;
diff --git a/editor/import/resource_importer_bitmask.cpp b/editor/import/resource_importer_bitmask.cpp
index 252af9050b..da2d1c9bdf 100644
--- a/editor/import/resource_importer_bitmask.cpp
+++ b/editor/import/resource_importer_bitmask.cpp
@@ -38,55 +38,51 @@
#include "scene/resources/texture.h"
String ResourceImporterBitMap::get_importer_name() const {
-
return "bitmap";
}
String ResourceImporterBitMap::get_visible_name() const {
-
return "BitMap";
}
-void ResourceImporterBitMap::get_recognized_extensions(List<String> *p_extensions) const {
+void ResourceImporterBitMap::get_recognized_extensions(List<String> *p_extensions) const {
ImageLoader::get_recognized_extensions(p_extensions);
}
+
String ResourceImporterBitMap::get_save_extension() const {
return "res";
}
String ResourceImporterBitMap::get_resource_type() const {
-
return "BitMap";
}
bool ResourceImporterBitMap::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
-
return true;
}
int ResourceImporterBitMap::get_preset_count() const {
return 0;
}
-String ResourceImporterBitMap::get_preset_name(int p_idx) const {
+String ResourceImporterBitMap::get_preset_name(int p_idx) const {
return String();
}
void ResourceImporterBitMap::get_import_options(List<ImportOption> *r_options, int p_preset) const {
-
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "create_from", PROPERTY_HINT_ENUM, "Black & White,Alpha"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "threshold", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.5));
}
Error ResourceImporterBitMap::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
-
int create_from = p_options["create_from"];
float threshold = p_options["threshold"];
Ref<Image> image;
image.instance();
Error err = ImageLoader::load_image(p_source_file, image);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
int w = image->get_width();
int h = image->get_height();
@@ -97,7 +93,6 @@ Error ResourceImporterBitMap::import(const String &p_source_file, const String &
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
-
bool bit;
Color c = image->get_pixel(j, i);
if (create_from == 0) { //b&W
diff --git a/editor/import/resource_importer_csv.cpp b/editor/import/resource_importer_csv.cpp
index 424f90bd54..d29ba28a96 100644
--- a/editor/import/resource_importer_csv.cpp
+++ b/editor/import/resource_importer_csv.cpp
@@ -34,16 +34,14 @@
#include "core/os/file_access.h"
String ResourceImporterCSV::get_importer_name() const {
-
return "csv";
}
String ResourceImporterCSV::get_visible_name() const {
-
return "CSV";
}
-void ResourceImporterCSV::get_recognized_extensions(List<String> *p_extensions) const {
+void ResourceImporterCSV::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("csv");
}
@@ -52,20 +50,18 @@ String ResourceImporterCSV::get_save_extension() const {
}
String ResourceImporterCSV::get_resource_type() const {
-
return "TextFile";
}
bool ResourceImporterCSV::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
-
return true;
}
int ResourceImporterCSV::get_preset_count() const {
return 0;
}
-String ResourceImporterCSV::get_preset_name(int p_idx) const {
+String ResourceImporterCSV::get_preset_name(int p_idx) const {
return "";
}
diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp
index 1d7bed3975..04e20dee86 100644
--- a/editor/import/resource_importer_csv_translation.cpp
+++ b/editor/import/resource_importer_csv_translation.cpp
@@ -36,16 +36,14 @@
#include "core/translation.h"
String ResourceImporterCSVTranslation::get_importer_name() const {
-
return "csv_translation";
}
String ResourceImporterCSVTranslation::get_visible_name() const {
-
return "CSV Translation";
}
-void ResourceImporterCSVTranslation::get_recognized_extensions(List<String> *p_extensions) const {
+void ResourceImporterCSVTranslation::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("csv");
}
@@ -54,38 +52,40 @@ String ResourceImporterCSVTranslation::get_save_extension() const {
}
String ResourceImporterCSVTranslation::get_resource_type() const {
-
return "Translation";
}
bool ResourceImporterCSVTranslation::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
-
return true;
}
int ResourceImporterCSVTranslation::get_preset_count() const {
return 0;
}
-String ResourceImporterCSVTranslation::get_preset_name(int p_idx) const {
+String ResourceImporterCSVTranslation::get_preset_name(int p_idx) const {
return "";
}
void ResourceImporterCSVTranslation::get_import_options(List<ImportOption> *r_options, int p_preset) const {
-
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "delimiter", PROPERTY_HINT_ENUM, "Comma,Semicolon,Tab"), 0));
}
Error ResourceImporterCSVTranslation::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
-
bool compress = p_options["compress"];
String delimiter;
switch ((int)p_options["delimiter"]) {
- case 0: delimiter = ","; break;
- case 1: delimiter = ";"; break;
- case 2: delimiter = "\t"; break;
+ case 0:
+ delimiter = ",";
+ break;
+ case 1:
+ delimiter = ";";
+ break;
+ case 2:
+ delimiter = "\t";
+ break;
}
FileAccessRef f = FileAccess::open(p_source_file, FileAccess::READ);
@@ -99,7 +99,6 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const
Vector<Ref<Translation>> translations;
for (int i = 1; i < line.size(); i++) {
-
String locale = line[i];
ERR_FAIL_COND_V_MSG(!TranslationServer::is_locale_valid(locale), ERR_PARSE_ERROR, "Error importing CSV translation: '" + locale + "' is not a valid locale.");
@@ -113,10 +112,8 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const
line = f->get_csv_line(delimiter);
while (line.size() == locales.size() + 1) {
-
String key = line[0];
if (key != "") {
-
for (int i = 1; i < line.size(); i++) {
translations.write[i - 1]->add_message(key, line[i].c_unescape());
}
diff --git a/editor/import/resource_importer_image.cpp b/editor/import/resource_importer_image.cpp
index a1f5a79b00..885b00865b 100644
--- a/editor/import/resource_importer_image.cpp
+++ b/editor/import/resource_importer_image.cpp
@@ -36,16 +36,14 @@
#include "scene/resources/texture.h"
String ResourceImporterImage::get_importer_name() const {
-
return "image";
}
String ResourceImporterImage::get_visible_name() const {
-
return "Image";
}
-void ResourceImporterImage::get_recognized_extensions(List<String> *p_extensions) const {
+void ResourceImporterImage::get_recognized_extensions(List<String> *p_extensions) const {
ImageLoader::get_recognized_extensions(p_extensions);
}
@@ -54,20 +52,18 @@ String ResourceImporterImage::get_save_extension() const {
}
String ResourceImporterImage::get_resource_type() const {
-
return "Image";
}
bool ResourceImporterImage::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
-
return true;
}
int ResourceImporterImage::get_preset_count() const {
return 0;
}
-String ResourceImporterImage::get_preset_name(int p_idx) const {
+String ResourceImporterImage::get_preset_name(int p_idx) const {
return String();
}
@@ -75,7 +71,6 @@ void ResourceImporterImage::get_import_options(List<ImportOption> *r_options, in
}
Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
-
FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ);
ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, "Cannot open file from path '" + p_source_file + "'.");
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
index a4cbc81b26..1f39a12c25 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -36,11 +36,10 @@
#include "core/io/image_loader.h"
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
+#include "resource_importer_texture.h"
#include "scene/resources/texture.h"
-#if 0
String ResourceImporterLayeredTexture::get_importer_name() const {
-
switch (mode) {
case MODE_CUBEMAP: {
return "cubemap_texture";
@@ -51,13 +50,15 @@ String ResourceImporterLayeredTexture::get_importer_name() const {
case MODE_CUBEMAP_ARRAY: {
return "cubemap_array_texture";
} break;
+ case MODE_3D: {
+ return "cubemap_3d_texture";
+ } break;
}
ERR_FAIL_V("");
}
String ResourceImporterLayeredTexture::get_visible_name() const {
-
switch (mode) {
case MODE_CUBEMAP: {
return "Cubemap";
@@ -68,24 +69,31 @@ String ResourceImporterLayeredTexture::get_visible_name() const {
case MODE_CUBEMAP_ARRAY: {
return "CubemapArray";
} break;
+ case MODE_3D: {
+ return "3D";
+ } break;
}
ERR_FAIL_V("");
}
-void ResourceImporterLayeredTexture::get_recognized_extensions(List<String> *p_extensions) const {
+void ResourceImporterLayeredTexture::get_recognized_extensions(List<String> *p_extensions) const {
ImageLoader::get_recognized_extensions(p_extensions);
}
+
String ResourceImporterLayeredTexture::get_save_extension() const {
switch (mode) {
case MODE_CUBEMAP: {
- return "cube";
+ return "scube";
} break;
case MODE_2D_ARRAY: {
- return "tex2darr";
+ return "stexarray";
} break;
case MODE_CUBEMAP_ARRAY: {
- return "cubearr";
+ return "scubearray";
+ } break;
+ case MODE_3D: {
+ return "stex3d";
} break;
}
@@ -93,198 +101,182 @@ String ResourceImporterLayeredTexture::get_save_extension() const {
}
String ResourceImporterLayeredTexture::get_resource_type() const {
-
switch (mode) {
case MODE_CUBEMAP: {
- return "Cubemap";
+ return "StreamCubemap";
} break;
case MODE_2D_ARRAY: {
- return "Texture2DArray";
+ return "StreamTexture2DArray";
} break;
case MODE_CUBEMAP_ARRAY: {
- return "CubemapArray";
+ return "StreamCubemapArray";
+ } break;
+ case MODE_3D: {
+ return "StreamTexture3D";
} break;
}
ERR_FAIL_V(String());
}
bool ResourceImporterLayeredTexture::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
-
+ if (p_option == "compress/lossy_quality" && p_options.has("compress/mode")) {
+ return int(p_options["compress/mode"]) == COMPRESS_LOSSY;
+ }
return true;
}
int ResourceImporterLayeredTexture::get_preset_count() const {
return 0;
}
-String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const {
+String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const {
return "";
}
void ResourceImporterLayeredTexture::get_import_options(List<ImportOption> *r_options, int p_preset) const {
-
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Video RAM,Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress/no_bptc_if_rgb"), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,Video RAM,Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_compression", PROPERTY_HINT_ENUM, "Disabled,Opaque Only,Always"), 1));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Disabled,Enabled,RGBA Only"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/channel_pack", PROPERTY_HINT_ENUM, "sRGB Friendly,Optimized"), 0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/mipmaps"), true));
- if (mode == MODE_2D_ARRAY) {
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "mipmaps/generate"), true));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mipmaps/limit", PROPERTY_HINT_RANGE, "-1,256"), -1));
+
+ if (mode == MODE_2D_ARRAY || mode == MODE_3D) {
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/horizontal", PROPERTY_HINT_RANGE, "1,256,1"), 8));
- }
- if (mode == MODE_2D_ARRAY || mode == MODE_CUBEMAP_ARRAY) {
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/vertical", PROPERTY_HINT_RANGE, "1,256,1"), 8));
}
+ if (mode == MODE_CUBEMAP || mode == MODE_CUBEMAP_ARRAY) {
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/arrangement", PROPERTY_HINT_ENUM, "1x6,2x3,3x2,6x1"), 1));
+ if (mode == MODE_CUBEMAP_ARRAY) {
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/layout", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "slices/amount", PROPERTY_HINT_RANGE, "1,1024,1,or_greater"), 1));
+ }
+ }
}
-void ResourceImporterLayeredTexture::_save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps) {
+void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2) {
+ for (int i = 0; i < p_images.size(); i++) {
+ if (p_force_po2) {
+ p_images.write[i]->resize_to_po2();
+ }
- FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE);
- f->store_8('G');
- f->store_8('D');
- switch (mode) {
- case MODE_2D_ARRAY: f->store_8('A'); break;
- case MODE_CUBEMAP: f->store_8('C'); break;
- case MODE_CUBEMAP_ARRAY: f->store_8('X'); break;
+ if (p_mipmaps) {
+ p_images.write[i]->generate_mipmaps();
+ } else {
+ p_images.write[i]->clear_mipmaps();
+ }
}
- f->store_8('T'); //godot streamable texture
+ FileAccessRef f = FileAccess::open(p_to_path, FileAccess::WRITE);
+ f->store_8('G');
+ f->store_8('S');
+ f->store_8('T');
+ f->store_8('L');
- f->store_32(p_images[0]->get_width());
- f->store_32(p_images[0]->get_height());
- f->store_32(p_images.size()); //depth
- uint32_t flags = 0;
- if (p_mipmaps) {
- flags |= TEXTURE_FLAGS_MIPMAPS;
- }
- f->store_32(flags);
- if (p_compress_mode != COMPRESS_VIDEO_RAM) {
- //vram needs to do a first compression to tell what the format is, for the rest its ok
- f->store_32(p_images[0]->get_format());
- f->store_32(p_compress_mode); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
- }
+ f->store_32(StreamTextureLayered::FORMAT_VERSION);
+ f->store_32(p_images.size());
+ f->store_32(mode);
+ f->store_32(0); //dataformat
+ f->store_32(0); //mipmap limit
- if ((p_compress_mode == COMPRESS_LOSSLESS) && p_images[0]->get_format() > Image::FORMAT_RGBA8) {
- p_compress_mode = COMPRESS_UNCOMPRESSED; //these can't go as lossy
- }
+ //reserverd
+ f->store_32(0);
+ f->store_32(0);
+ f->store_32(0);
for (int i = 0; i < p_images.size(); i++) {
-
- switch (p_compress_mode) {
- case COMPRESS_LOSSLESS: {
-
- Ref<Image> image = p_images[i]->duplicate();
- if (p_mipmaps) {
- image->generate_mipmaps();
- } else {
- image->clear_mipmaps();
- }
-
- int mmc = image->get_mipmap_count() + 1;
- f->store_32(mmc);
-
- for (int j = 0; j < mmc; j++) {
-
- if (j > 0) {
- image->shrink_x2();
- }
-
- Vector<uint8_t> data = Image::lossless_packer(image);
- int data_len = data.size();
- f->store_32(data_len);
-
- const uint8_t* r = data.ptr();
- f->store_buffer(r.ptr(), data_len);
- }
-
- } break;
- case COMPRESS_VIDEO_RAM: {
-
- Ref<Image> image = p_images[i]->duplicate();
- image->generate_mipmaps(false);
-
- Image::CompressSource csource = Image::COMPRESS_SOURCE_LAYERED;
- image->compress(p_vram_compression, csource, 0.7);
-
- if (i == 0) {
- //hack so we can properly tell the format
- f->store_32(image->get_format());
- f->store_32(p_compress_mode); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
- }
-
- Vector<uint8_t> data = image->get_data();
- int dl = data.size();
-
- const uint8_t* r = data.ptr();
- f->store_buffer(r.ptr(), dl);
- } break;
- case COMPRESS_UNCOMPRESSED: {
-
- Ref<Image> image = p_images[i]->duplicate();
-
- if (p_mipmaps) {
- image->generate_mipmaps();
- } else {
- image->clear_mipmaps();
- }
-
- Vector<uint8_t> data = image->get_data();
- int dl = data.size();
-
- const uint8_t* r = data.ptr();
-
- f->store_buffer(r.ptr(), dl);
-
- } break;
- }
+ ResourceImporterTexture::save_to_stex_format(f, p_images[i], ResourceImporterTexture::CompressMode(p_compress_mode), used_channels, p_vram_compression, p_lossy);
}
- memdelete(f);
+ f->close();
}
Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
-
int compress_mode = p_options["compress/mode"];
- int no_bptc_if_rgb = p_options["compress/no_bptc_if_rgb"];
- bool mipmaps = p_options["flags/mipmaps"];
+ float lossy = p_options["compress/lossy_quality"];
+ int hdr_compression = p_options["compress/hdr_compression"];
+ int bptc_ldr = p_options["compress/bptc_ldr"];
+ bool mipmaps = p_options["mipmaps/generate"];
+ //bool mipmap_limit = p_options["mipmaps/limit"];
+
int channel_pack = p_options["compress/channel_pack"];
int hslices = (p_options.has("slices/horizontal")) ? int(p_options["slices/horizontal"]) : 0;
int vslices = (p_options.has("slices/vertical")) ? int(p_options["slices/vertical"]) : 0;
+ int arrangement = (p_options.has("slices/arrangement")) ? int(p_options["slices/arrangement"]) : 0;
+ int layout = (p_options.has("slices/layout")) ? int(p_options["slices/layout"]) : 0;
+ int amount = (p_options.has("slices/amount")) ? int(p_options["slices/amount"]) : 0;
+
+ if (mode == MODE_CUBEMAP || mode == MODE_CUBEMAP_ARRAY) {
+ switch (arrangement) {
+ case CUBEMAP_FORMAT_1X6: {
+ hslices = 1;
+ vslices = 6;
+ } break;
+ case CUBEMAP_FORMAT_2X3: {
+ hslices = 2;
+ vslices = 3;
+ } break;
+ case CUBEMAP_FORMAT_3X2: {
+ hslices = 3;
+ vslices = 2;
+ } break;
+ case CUBEMAP_FORMAT_6X1: {
+ hslices = 6;
+ vslices = 1;
+ } break;
+ }
- if (mode == MODE_CUBEMAP) {
- hslices = 3;
- vslices = 2;
- } else if (mode == MODE_CUBEMAP_ARRAY) {
- hslices = 3;
- vslices *= 2; //put cubemaps vertically
+ if (mode == MODE_CUBEMAP_ARRAY) {
+ if (layout == 0) {
+ hslices *= amount;
+ } else {
+ vslices *= amount;
+ }
+ }
}
Ref<Image> image;
image.instance();
Error err = ImageLoader::load_image(p_source_file, image, nullptr, false, 1.0);
- if (err != OK)
+ if (err != OK) {
return err;
-
- if (compress_mode == COMPRESS_VIDEO_RAM) {
- mipmaps = true;
}
- Vector<Ref<Image> > slices;
+ if (compress_mode == COMPRESS_BASIS_UNIVERSAL && image->get_format() >= Image::FORMAT_RF) {
+ //basis universal does not support float formats, fall back
+ compress_mode = COMPRESS_VRAM_COMPRESSED;
+ }
- int slice_w = image->get_width() / hslices;
- int slice_h = image->get_height() / vslices;
+ if (compress_mode == COMPRESS_VRAM_COMPRESSED) {
+ mipmaps = true;
+ }
//optimize
- if (compress_mode == COMPRESS_VIDEO_RAM) {
+ if (compress_mode == COMPRESS_VRAM_COMPRESSED) {
//if using video ram, optimize
if (channel_pack == 0) {
//remove alpha if not needed, so compression is more efficient
if (image->get_format() == Image::FORMAT_RGBA8 && !image->detect_alpha()) {
image->convert(Image::FORMAT_RGB8);
}
- } else {
+ } else if (image->get_format() < Image::FORMAT_RGBA8) {
image->optimize_channels();
}
}
+ Image::CompressSource csource = Image::COMPRESS_SOURCE_GENERIC;
+ if (channel_pack == 0) {
+ csource = Image::COMPRESS_SOURCE_SRGB;
+ }
+
+ Image::UsedChannels used_channels = image->detect_used_channels(csource);
+
+ Vector<Ref<Image>> slices;
+
+ int slice_w = image->get_width() / hslices;
+ int slice_h = image->get_height() / vslices;
+
for (int i = 0; i < vslices; i++) {
for (int j = 0; j < hslices; j++) {
int x = slice_w * j;
@@ -301,58 +293,77 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
String extension = get_save_extension();
Array formats_imported;
- if (compress_mode == COMPRESS_VIDEO_RAM) {
+ if (compress_mode == COMPRESS_VRAM_COMPRESSED) {
//must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc).
//Android, GLES 2.x
bool ok_on_pc = false;
- bool encode_bptc = false;
-
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc")) {
+ bool is_hdr = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995);
+ bool is_ldr = (image->get_format() >= Image::FORMAT_L8 && image->get_format() <= Image::FORMAT_RGB565);
+ bool can_bptc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_bptc");
+ bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc");
- encode_bptc = true;
-
- if (no_bptc_if_rgb) {
- Image::UsedChannels channels = image->detect_used_channels();
- if (channels != Image::USED_CHANNELS_LA && channels != Image::USED_CHANNELS_RGBA) {
- encode_bptc = false;
+ if (can_bptc) {
+ formats_imported.push_back("bptc"); //needs to be aded anyway
+ }
+ bool can_compress_hdr = hdr_compression > 0;
+
+ if (is_hdr && can_compress_hdr) {
+ if (used_channels == Image::USED_CHANNELS_LA || used_channels == Image::USED_CHANNELS_RGBA) {
+ //can compress hdr, but hdr with alpha is not compressible
+
+ if (hdr_compression == 2) {
+ //but user selected to compress hdr anyway, so force an alpha-less format.
+ if (image->get_format() == Image::FORMAT_RGBAF) {
+ for (int i = 0; i < slices.size(); i++) {
+ slices.write[i]->convert(Image::FORMAT_RGBF);
+ }
+
+ } else if (image->get_format() == Image::FORMAT_RGBAH) {
+ for (int i = 0; i < slices.size(); i++) {
+ slices.write[i]->convert(Image::FORMAT_RGBH);
+ }
+ }
+ } else {
+ can_compress_hdr = false;
}
}
- formats_imported.push_back("bptc");
+ if (can_compress_hdr) {
+ if (!can_bptc) {
+ //default to rgbe
+ if (image->get_format() != Image::FORMAT_RGBE9995) {
+ for (int i = 0; i < slices.size(); i++) {
+ slices.write[i]->convert(Image::FORMAT_RGBE9995);
+ }
+ }
+ }
+ } else {
+ can_bptc = false;
+ }
}
- if (encode_bptc) {
-
- _save_tex(slices, p_save_path + ".bptc." + extension, compress_mode, Image::COMPRESS_BPTC, mipmaps);
- r_platform_variants->push_back("bptc");
- ok_on_pc = true;
+ if (is_ldr && can_bptc) {
+ if (bptc_ldr == 0 || (bptc_ldr == 1 && !(used_channels == Image::USED_CHANNELS_LA || used_channels == Image::USED_CHANNELS_RGBA))) {
+ can_bptc = false;
+ }
}
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc")) {
-
- _save_tex(slices, p_save_path + ".s3tc." + extension, compress_mode, Image::COMPRESS_S3TC, mipmaps);
+ if (can_bptc || can_s3tc) {
+ _save_tex(slices, p_save_path + ".s3tc." + extension, compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, csource, used_channels, mipmaps, false);
r_platform_variants->push_back("s3tc");
- ok_on_pc = true;
formats_imported.push_back("s3tc");
+ ok_on_pc = true;
}
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
-
- _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, Image::COMPRESS_ETC2, mipmaps);
+ _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, lossy, Image::COMPRESS_ETC2, csource, used_channels, mipmaps, true);
r_platform_variants->push_back("etc2");
formats_imported.push_back("etc2");
}
- if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) {
- _save_tex(slices, p_save_path + ".etc." + extension, compress_mode, Image::COMPRESS_ETC, mipmaps);
- r_platform_variants->push_back("etc");
- formats_imported.push_back("etc");
- }
-
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
-
- _save_tex(slices, p_save_path + ".pvrtc." + extension, compress_mode, Image::COMPRESS_PVRTC4, mipmaps);
+ _save_tex(slices, p_save_path + ".etc2." + extension, compress_mode, lossy, Image::COMPRESS_ETC2, csource, used_channels, mipmaps, true);
r_platform_variants->push_back("pvrtc");
formats_imported.push_back("pvrtc");
}
@@ -362,12 +373,12 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
}
} else {
//import normally
- _save_tex(slices, p_save_path + "." + extension, compress_mode, Image::COMPRESS_S3TC /*this is ignored */, mipmaps);
+ _save_tex(slices, p_save_path + "." + extension, compress_mode, lossy, Image::COMPRESS_S3TC /* IGNORED */, csource, used_channels, mipmaps, false);
}
if (r_metadata) {
Dictionary metadata;
- metadata["vram_texture"] = compress_mode == COMPRESS_VIDEO_RAM;
+ metadata["vram_texture"] = compress_mode == COMPRESS_VRAM_COMPRESSED;
if (formats_imported.size()) {
metadata["imported_formats"] = formats_imported;
}
@@ -386,7 +397,6 @@ const char *ResourceImporterLayeredTexture::compression_formats[] = {
nullptr
};
String ResourceImporterLayeredTexture::get_import_settings_string() const {
-
String s;
int index = 0;
@@ -403,7 +413,6 @@ String ResourceImporterLayeredTexture::get_import_settings_string() const {
}
bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_path) const {
-
//will become invalid if formats are missing to import
Dictionary metadata = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path);
@@ -441,11 +450,9 @@ bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_p
ResourceImporterLayeredTexture *ResourceImporterLayeredTexture::singleton = nullptr;
ResourceImporterLayeredTexture::ResourceImporterLayeredTexture() {
-
singleton = this;
mode = MODE_CUBEMAP;
}
ResourceImporterLayeredTexture::~ResourceImporterLayeredTexture() {
}
-#endif
diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h
index 40e5c9023e..18eaf31f6b 100644
--- a/editor/import/resource_importer_layered_texture.h
+++ b/editor/import/resource_importer_layered_texture.h
@@ -28,7 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if 0
/*************************************************************************/
/* resource_importer_layered_texture.h */
/*************************************************************************/
@@ -65,16 +64,24 @@
#include "core/image.h"
#include "core/io/resource_importer.h"
-
-class StreamTexture;
+class StreamTexture2D;
class ResourceImporterLayeredTexture : public ResourceImporter {
GDCLASS(ResourceImporterLayeredTexture, ResourceImporter);
+
public:
enum Mode {
- MODE_CUBEMAP,
MODE_2D_ARRAY,
- MODE_CUBEMAP_ARRAY
+ MODE_CUBEMAP,
+ MODE_CUBEMAP_ARRAY,
+ MODE_3D,
+ };
+
+ enum CubemapFormat {
+ CUBEMAP_FORMAT_1X6,
+ CUBEMAP_FORMAT_2X3,
+ CUBEMAP_FORMAT_3X2,
+ CUBEMAP_FORMAT_6X1,
};
enum TextureFlags {
@@ -86,9 +93,9 @@ private:
static const char *compression_formats[];
protected:
- static void _texture_reimport_srgb(const Ref<StreamTexture> &p_tex);
- static void _texture_reimport_3d(const Ref<StreamTexture> &p_tex);
- static void _texture_reimport_normal(const Ref<StreamTexture> &p_tex);
+ static void _texture_reimport_srgb(const Ref<StreamTexture2D> &p_tex);
+ static void _texture_reimport_3d(const Ref<StreamTexture2D> &p_tex);
+ static void _texture_reimport_normal(const Ref<StreamTexture2D> &p_tex);
static ResourceImporterLayeredTexture *singleton;
@@ -102,8 +109,10 @@ public:
enum CompressMode {
COMPRESS_LOSSLESS,
- COMPRESS_VIDEO_RAM,
- COMPRESS_UNCOMPRESSED
+ COMPRESS_LOSSY,
+ COMPRESS_VRAM_COMPRESSED,
+ COMPRESS_VRAM_UNCOMPRESSED,
+ COMPRESS_BASIS_UNIVERSAL
};
virtual int get_preset_count() const;
@@ -112,7 +121,7 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- void _save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps);
+ void _save_tex(Vector<Ref<Image>> p_images, const String &p_to_path, int p_compress_mode, float p_lossy, Image::CompressMode p_vram_compression, Image::CompressSource p_csource, Image::UsedChannels used_channels, bool p_mipmaps, bool p_force_po2);
virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
@@ -126,6 +135,5 @@ public:
ResourceImporterLayeredTexture();
~ResourceImporterLayeredTexture();
};
-#endif // RESOURCE_IMPORTER_LAYERED_TEXTURE_H
-#endif
+#endif // RESOURCE_IMPORTER_LAYERED_TEXTURE_H
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index 6a6eadfa5c..49b47bf4be 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -38,12 +38,10 @@
#include "scene/resources/surface_tool.h"
uint32_t EditorOBJImporter::get_import_flags() const {
-
return IMPORT_SCENE;
}
static Error _parse_material_library(const String &p_path, Map<String, Ref<StandardMaterial3D>> &material_map, List<String> *r_missing_deps) {
-
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, vformat("Couldn't open MTL file '%s', it may not exist or not be readable.", p_path));
@@ -51,7 +49,6 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Stand
String current_name;
String base_path = p_path.get_base_dir();
while (true) {
-
String l = f->get_line().strip_edges();
if (l.begins_with("newmtl ")) {
@@ -204,7 +201,6 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Stand
}
static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_single_mesh, bool p_generate_tangents, bool p_optimize, Vector3 p_scale_mesh, Vector3 p_offset_mesh, List<String> *r_missing_deps) {
-
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V_MSG(!f, ERR_CANT_OPEN, vformat("Couldn't open OBJ file '%s', it may not exist or not be readable.", p_path));
@@ -231,7 +227,6 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
String current_group;
while (true) {
-
String l = f->get_line().strip_edges();
while (l.length() && l[l.length() - 1] == '\\') {
String add = f->get_line().strip_edges();
@@ -283,12 +278,10 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
ERR_FAIL_COND_V(face[0].size() != face[1].size(), ERR_FILE_CORRUPT);
for (int i = 2; i < v.size() - 1; i++) {
-
face[2] = v[i + 1].split("/");
ERR_FAIL_COND_V(face[0].size() != face[2].size(), ERR_FILE_CORRUPT);
for (int j = 0; j < 3; j++) {
-
int idx = j;
if (idx < 2) {
@@ -297,23 +290,26 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
if (face[idx].size() == 3) {
int norm = face[idx][2].to_int() - 1;
- if (norm < 0)
+ if (norm < 0) {
norm += normals.size() + 1;
+ }
ERR_FAIL_INDEX_V(norm, normals.size(), ERR_FILE_CORRUPT);
surf_tool->add_normal(normals[norm]);
}
if (face[idx].size() >= 2 && face[idx][1] != String()) {
int uv = face[idx][1].to_int() - 1;
- if (uv < 0)
+ if (uv < 0) {
uv += uvs.size() + 1;
+ }
ERR_FAIL_INDEX_V(uv, uvs.size(), ERR_FILE_CORRUPT);
surf_tool->add_uv(uvs[uv]);
}
int vtx = face[idx][0].to_int() - 1;
- if (vtx < 0)
+ if (vtx < 0) {
vtx += vertices.size() + 1;
+ }
ERR_FAIL_INDEX_V(vtx, vertices.size(), ERR_FILE_CORRUPT);
Vector3 vertex = vertices[vtx];
@@ -326,10 +322,11 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
}
} else if (l.begins_with("s ")) { //smoothing
String what = l.substr(2, l.length()).strip_edges();
- if (what == "off")
+ if (what == "off") {
surf_tool->add_smooth_group(false);
- else
+ } else {
surf_tool->add_smooth_group(true);
+ }
} else if (/*l.begins_with("g ") ||*/ l.begins_with("usemtl ") || (l.begins_with("o ") || f->eof_reached())) { //commit group to mesh
//groups are too annoying
if (surf_tool->get_vertex_array().size()) {
@@ -365,7 +362,6 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
}
if (l.begins_with("o ") || f->eof_reached()) {
-
if (!p_single_mesh) {
mesh->set_name(name);
r_meshes.push_back(mesh);
@@ -384,12 +380,10 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
}
if (l.begins_with("usemtl ")) {
-
current_material = l.replace("usemtl", "").strip_edges();
}
if (l.begins_with("g ")) {
-
current_group = l.substr(2, l.length()).strip_edges();
}
@@ -411,7 +405,6 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
}
if (p_single_mesh) {
-
r_meshes.push_back(mesh);
}
@@ -419,7 +412,6 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
}
Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
-
List<Ref<Mesh>> meshes;
Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, p_flags & IMPORT_USE_COMPRESSION, Vector3(1, 1, 1), Vector3(0, 0, 0), r_missing_deps);
@@ -434,7 +426,6 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in
Node3D *scene = memnew(Node3D);
for (List<Ref<Mesh>>::Element *E = meshes.front(); E; E = E->next()) {
-
MeshInstance3D *mi = memnew(MeshInstance3D);
mi->set_mesh(E->get());
mi->set_name(E->get()->get_name());
@@ -448,33 +439,36 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in
return scene;
}
-Ref<Animation> EditorOBJImporter::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
+Ref<Animation> EditorOBJImporter::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
return Ref<Animation>();
}
void EditorOBJImporter::get_extensions(List<String> *r_extensions) const {
-
r_extensions->push_back("obj");
}
EditorOBJImporter::EditorOBJImporter() {
}
+
////////////////////////////////////////////////////
String ResourceImporterOBJ::get_importer_name() const {
return "wavefront_obj";
}
+
String ResourceImporterOBJ::get_visible_name() const {
return "OBJ As Mesh";
}
-void ResourceImporterOBJ::get_recognized_extensions(List<String> *p_extensions) const {
+void ResourceImporterOBJ::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("obj");
}
+
String ResourceImporterOBJ::get_save_extension() const {
return "mesh";
}
+
String ResourceImporterOBJ::get_resource_type() const {
return "Mesh";
}
@@ -482,24 +476,23 @@ String ResourceImporterOBJ::get_resource_type() const {
int ResourceImporterOBJ::get_preset_count() const {
return 0;
}
+
String ResourceImporterOBJ::get_preset_name(int p_idx) const {
return "";
}
void ResourceImporterOBJ::get_import_options(List<ImportOption> *r_options, int p_preset) const {
-
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "generate_tangents"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "scale_mesh"), Vector3(1, 1, 1)));
r_options->push_back(ImportOption(PropertyInfo(Variant::VECTOR3, "offset_mesh"), Vector3(0, 0, 0)));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "optimize_mesh"), true));
}
-bool ResourceImporterOBJ::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+bool ResourceImporterOBJ::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
return true;
}
Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
-
List<Ref<Mesh>> meshes;
Error err = _parse_obj(p_source_file, meshes, true, p_options["generate_tangents"], p_options["optimize_mesh"], p_options["scale_mesh"], p_options["offset_mesh"], nullptr);
diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h
index 7485e60f7b..aec5de3dcc 100644
--- a/editor/import/resource_importer_obj.h
+++ b/editor/import/resource_importer_obj.h
@@ -34,7 +34,6 @@
#include "resource_importer_scene.h"
class EditorOBJImporter : public EditorSceneImporter {
-
GDCLASS(EditorOBJImporter, EditorSceneImporter);
public:
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index b5766a48a0..ec82f78e75 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -47,15 +47,14 @@
#include "scene/resources/world_margin_shape_3d.h"
uint32_t EditorSceneImporter::get_import_flags() const {
-
if (get_script_instance()) {
return get_script_instance()->call("_get_import_flags");
}
ERR_FAIL_V(0);
}
-void EditorSceneImporter::get_extensions(List<String> *r_extensions) const {
+void EditorSceneImporter::get_extensions(List<String> *r_extensions) const {
if (get_script_instance()) {
Array arr = get_script_instance()->call("_get_extensions");
for (int i = 0; i < arr.size(); i++) {
@@ -66,8 +65,8 @@ void EditorSceneImporter::get_extensions(List<String> *r_extensions) const {
ERR_FAIL();
}
-Node *EditorSceneImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+Node *EditorSceneImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
if (get_script_instance()) {
return get_script_instance()->call("_import_scene", p_path, p_flags, p_bake_fps);
}
@@ -76,7 +75,6 @@ Node *EditorSceneImporter::import_scene(const String &p_path, uint32_t p_flags,
}
Ref<Animation> EditorSceneImporter::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
-
if (get_script_instance()) {
return get_script_instance()->call("_import_animation", p_path, p_flags);
}
@@ -88,17 +86,14 @@ Ref<Animation> EditorSceneImporter::import_animation(const String &p_path, uint3
//and you want to load the resulting file
Node *EditorSceneImporter::import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) {
-
return ResourceImporterScene::get_singleton()->import_scene_from_other_importer(this, p_path, p_flags, p_bake_fps);
}
Ref<Animation> EditorSceneImporter::import_animation_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps) {
-
return ResourceImporterScene::get_singleton()->import_animation_from_other_importer(this, p_path, p_flags, p_bake_fps);
}
void EditorSceneImporter::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("import_scene_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneImporter::import_scene_from_other_importer);
ClassDB::bind_method(D_METHOD("import_animation_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneImporter::import_animation_from_other_importer);
@@ -126,27 +121,24 @@ void EditorSceneImporter::_bind_methods() {
/////////////////////////////////
void EditorScenePostImport::_bind_methods() {
-
BIND_VMETHOD(MethodInfo(Variant::OBJECT, "post_import", PropertyInfo(Variant::OBJECT, "scene")));
ClassDB::bind_method(D_METHOD("get_source_folder"), &EditorScenePostImport::get_source_folder);
ClassDB::bind_method(D_METHOD("get_source_file"), &EditorScenePostImport::get_source_file);
}
Node *EditorScenePostImport::post_import(Node *p_scene) {
-
- if (get_script_instance())
+ if (get_script_instance()) {
return get_script_instance()->call("post_import", p_scene);
+ }
return p_scene;
}
String EditorScenePostImport::get_source_folder() const {
-
return source_folder;
}
String EditorScenePostImport::get_source_file() const {
-
return source_file;
}
@@ -159,17 +151,14 @@ EditorScenePostImport::EditorScenePostImport() {
}
String ResourceImporterScene::get_importer_name() const {
-
return "scene";
}
String ResourceImporterScene::get_visible_name() const {
-
return "Scene";
}
void ResourceImporterScene::get_recognized_extensions(List<String> *p_extensions) const {
-
for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) {
E->get()->get_extensions(p_extensions);
}
@@ -180,27 +169,29 @@ String ResourceImporterScene::get_save_extension() const {
}
String ResourceImporterScene::get_resource_type() const {
-
return "PackedScene";
}
bool ResourceImporterScene::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
-
if (p_option.begins_with("animation/")) {
- if (p_option != "animation/import" && !bool(p_options["animation/import"]))
+ if (p_option != "animation/import" && !bool(p_options["animation/import"])) {
return false;
+ }
- if (p_option == "animation/keep_custom_tracks" && int(p_options["animation/storage"]) == 0)
+ if (p_option == "animation/keep_custom_tracks" && int(p_options["animation/storage"]) == 0) {
return false;
+ }
- if (p_option.begins_with("animation/optimizer/") && p_option != "animation/optimizer/enabled" && !bool(p_options["animation/optimizer/enabled"]))
+ if (p_option.begins_with("animation/optimizer/") && p_option != "animation/optimizer/enabled" && !bool(p_options["animation/optimizer/enabled"])) {
return false;
+ }
if (p_option.begins_with("animation/clip_")) {
int max_clip = p_options["animation/clips/amount"];
int clip = p_option.get_slice("/", 1).get_slice("_", 1).to_int() - 1;
- if (clip >= max_clip)
+ if (clip >= max_clip) {
return false;
+ }
}
}
@@ -218,72 +209,81 @@ bool ResourceImporterScene::get_option_visibility(const String &p_option, const
int ResourceImporterScene::get_preset_count() const {
return PRESET_MAX;
}
-String ResourceImporterScene::get_preset_name(int p_idx) const {
+String ResourceImporterScene::get_preset_name(int p_idx) const {
switch (p_idx) {
- case PRESET_SINGLE_SCENE: return TTR("Import as Single Scene");
- case PRESET_SEPARATE_ANIMATIONS: return TTR("Import with Separate Animations");
- case PRESET_SEPARATE_MATERIALS: return TTR("Import with Separate Materials");
- case PRESET_SEPARATE_MESHES: return TTR("Import with Separate Objects");
- case PRESET_SEPARATE_MESHES_AND_MATERIALS: return TTR("Import with Separate Objects+Materials");
- case PRESET_SEPARATE_MESHES_AND_ANIMATIONS: return TTR("Import with Separate Objects+Animations");
- case PRESET_SEPARATE_MATERIALS_AND_ANIMATIONS: return TTR("Import with Separate Materials+Animations");
- case PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS: return TTR("Import with Separate Objects+Materials+Animations");
- case PRESET_MULTIPLE_SCENES: return TTR("Import as Multiple Scenes");
- case PRESET_MULTIPLE_SCENES_AND_MATERIALS: return TTR("Import as Multiple Scenes+Materials");
+ case PRESET_SINGLE_SCENE:
+ return TTR("Import as Single Scene");
+ case PRESET_SEPARATE_ANIMATIONS:
+ return TTR("Import with Separate Animations");
+ case PRESET_SEPARATE_MATERIALS:
+ return TTR("Import with Separate Materials");
+ case PRESET_SEPARATE_MESHES:
+ return TTR("Import with Separate Objects");
+ case PRESET_SEPARATE_MESHES_AND_MATERIALS:
+ return TTR("Import with Separate Objects+Materials");
+ case PRESET_SEPARATE_MESHES_AND_ANIMATIONS:
+ return TTR("Import with Separate Objects+Animations");
+ case PRESET_SEPARATE_MATERIALS_AND_ANIMATIONS:
+ return TTR("Import with Separate Materials+Animations");
+ case PRESET_SEPARATE_MESHES_MATERIALS_AND_ANIMATIONS:
+ return TTR("Import with Separate Objects+Materials+Animations");
+ case PRESET_MULTIPLE_SCENES:
+ return TTR("Import as Multiple Scenes");
+ case PRESET_MULTIPLE_SCENES_AND_MATERIALS:
+ return TTR("Import as Multiple Scenes+Materials");
}
return "";
}
static bool _teststr(const String &p_what, const String &p_str) {
-
String what = p_what;
//remove trailing spaces and numbers, some apps like blender add ".number" to duplicates so also compensate for this
while (what.length() && ((what[what.length() - 1] >= '0' && what[what.length() - 1] <= '9') || what[what.length() - 1] <= 32 || what[what.length() - 1] == '.')) {
-
what = what.substr(0, what.length() - 1);
}
- if (what.findn("$" + p_str) != -1) //blender and other stuff
+ if (what.findn("$" + p_str) != -1) { //blender and other stuff
return true;
- if (what.to_lower().ends_with("-" + p_str)) //collada only supports "_" and "-" besides letters
+ }
+ if (what.to_lower().ends_with("-" + p_str)) { //collada only supports "_" and "-" besides letters
return true;
- if (what.to_lower().ends_with("_" + p_str)) //collada only supports "_" and "-" besides letters
+ }
+ if (what.to_lower().ends_with("_" + p_str)) { //collada only supports "_" and "-" besides letters
return true;
+ }
return false;
}
static String _fixstr(const String &p_what, const String &p_str) {
-
String what = p_what;
//remove trailing spaces and numbers, some apps like blender add ".number" to duplicates so also compensate for this
while (what.length() && ((what[what.length() - 1] >= '0' && what[what.length() - 1] <= '9') || what[what.length() - 1] <= 32 || what[what.length() - 1] == '.')) {
-
what = what.substr(0, what.length() - 1);
}
String end = p_what.substr(what.length(), p_what.length() - what.length());
- if (what.findn("$" + p_str) != -1) //blender and other stuff
+ if (what.findn("$" + p_str) != -1) { //blender and other stuff
return what.replace("$" + p_str, "") + end;
- if (what.to_lower().ends_with("-" + p_str)) //collada only supports "_" and "-" besides letters
+ }
+ if (what.to_lower().ends_with("-" + p_str)) { //collada only supports "_" and "-" besides letters
return what.substr(0, what.length() - (p_str.length() + 1)) + end;
- if (what.to_lower().ends_with("_" + p_str)) //collada only supports "_" and "-" besides letters
+ }
+ if (what.to_lower().ends_with("_" + p_str)) { //collada only supports "_" and "-" besides letters
return what.substr(0, what.length() - (p_str.length() + 1)) + end;
+ }
return what;
}
static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape3D>> &r_shape_list, bool p_convex) {
-
if (!p_convex) {
-
Ref<Shape3D> shape = mesh->create_trimesh_shape();
r_shape_list.push_back(shape);
} else {
-
Vector<Ref<Shape3D>> cd = mesh->convex_decompose();
if (cd.size()) {
for (int i = 0; i < cd.size(); i++) {
@@ -294,10 +294,8 @@ static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape3D>> &r_shape_l
}
Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape3D>>> &collision_map, LightBakeMode p_light_bake_mode) {
-
// children first
for (int i = 0; i < p_node->get_child_count(); i++) {
-
Node *r = _fix_node(p_node->get_child(i), p_root, collision_map, p_light_bake_mode);
if (!r) {
i--; //was erased
@@ -309,32 +307,27 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
bool isroot = p_node == p_root;
if (!isroot && _teststr(name, "noimp")) {
-
memdelete(p_node);
return nullptr;
}
if (Object::cast_to<MeshInstance3D>(p_node)) {
-
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
Ref<ArrayMesh> m = mi->get_mesh();
if (m.is_valid()) {
-
for (int i = 0; i < m->get_surface_count(); i++) {
-
Ref<StandardMaterial3D> mat = m->surface_get_material(i);
- if (!mat.is_valid())
+ if (!mat.is_valid()) {
continue;
+ }
if (_teststr(mat->get_name(), "alpha")) {
-
mat->set_transparency(StandardMaterial3D::TRANSPARENCY_ALPHA);
mat->set_name(_fixstr(mat->get_name(), "alpha"));
}
if (_teststr(mat->get_name(), "vcol")) {
-
mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, true);
mat->set_name(_fixstr(mat->get_name(), "vcol"));
@@ -343,8 +336,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
if (p_light_bake_mode != LIGHT_BAKE_DISABLED) {
-
- mi->set_flag(GeometryInstance3D::FLAG_USE_BAKED_LIGHT, true);
+ mi->set_gi_mode(GeometryInstance3D::GI_MODE_BAKED);
}
}
@@ -355,7 +347,6 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
List<StringName> anims;
ap->get_animation_list(&anims);
for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
-
Ref<Animation> anim = ap->get_animation(E->get());
ERR_CONTINUE(anim.is_null());
for (int i = 0; i < anim->get_track_count(); i++) {
@@ -374,9 +365,9 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
if (_teststr(name, "colonly") || _teststr(name, "convcolonly")) {
-
- if (isroot)
+ if (isroot) {
return p_node;
+ }
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
if (mi) {
Ref<Mesh> mesh = mi->get_mesh();
@@ -403,7 +394,6 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
ERR_FAIL_COND_V(fixed_name == String(), nullptr);
if (shapes.size()) {
-
StaticBody3D *col = memnew(StaticBody3D);
col->set_transform(mi->get_transform());
col->set_name(fixed_name);
@@ -413,7 +403,6 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
int idx = 0;
for (List<Ref<Shape3D>>::Element *E = shapes.front(); E; E = E->next()) {
-
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E->get());
col->add_child(cshape);
@@ -460,9 +449,9 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
} else if (_teststr(name, "rigid") && Object::cast_to<MeshInstance3D>(p_node)) {
-
- if (isroot)
+ if (isroot) {
return p_node;
+ }
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
Ref<Mesh> mesh = mi->get_mesh();
@@ -487,7 +476,6 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
int idx = 0;
for (List<Ref<Shape3D>>::Element *E = shapes.front(); E; E = E->next()) {
-
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E->get());
rigid_body->add_child(cshape);
@@ -499,7 +487,6 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
} else if ((_teststr(name, "col") || (_teststr(name, "convcol"))) && Object::cast_to<MeshInstance3D>(p_node)) {
-
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
Ref<Mesh> mesh = mi->get_mesh();
@@ -537,7 +524,6 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
int idx = 0;
for (List<Ref<Shape3D>>::Element *E = shapes.front(); E; E = E->next()) {
-
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E->get());
col->add_child(cshape);
@@ -551,9 +537,9 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
} else if (_teststr(name, "navmesh") && Object::cast_to<MeshInstance3D>(p_node)) {
-
- if (isroot)
+ if (isroot) {
return p_node;
+ }
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
@@ -570,9 +556,9 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
memdelete(p_node);
p_node = nmi;
} else if (_teststr(name, "vehicle")) {
-
- if (isroot)
+ if (isroot) {
return p_node;
+ }
Node *owner = p_node->get_owner();
Node3D *s = Object::cast_to<Node3D>(p_node);
@@ -590,9 +576,9 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
p_node = bv;
} else if (_teststr(name, "wheel")) {
-
- if (isroot)
+ if (isroot) {
return p_node;
+ }
Node *owner = p_node->get_owner();
Node3D *s = Object::cast_to<Node3D>(p_node);
@@ -610,14 +596,12 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
p_node = bv;
} else if (Object::cast_to<MeshInstance3D>(p_node)) {
-
//last attempt, maybe collision inside the mesh data
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
Ref<ArrayMesh> mesh = mi->get_mesh();
if (!mesh.is_null()) {
-
List<Ref<Shape3D>> shapes;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
@@ -639,7 +623,6 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
int idx = 0;
for (List<Ref<Shape3D>>::Element *E = shapes.front(); E; E = E->next()) {
-
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E->get());
col->add_child(cshape);
@@ -656,41 +639,39 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
void ResourceImporterScene::_create_clips(Node *scene, const Array &p_clips, bool p_bake_all) {
-
- if (!scene->has_node(String("AnimationPlayer")))
+ if (!scene->has_node(String("AnimationPlayer"))) {
return;
+ }
Node *n = scene->get_node(String("AnimationPlayer"));
ERR_FAIL_COND(!n);
AnimationPlayer *anim = Object::cast_to<AnimationPlayer>(n);
ERR_FAIL_COND(!anim);
- if (!anim->has_animation("default"))
+ if (!anim->has_animation("default")) {
return;
+ }
Ref<Animation> default_anim = anim->get_animation("default");
for (int i = 0; i < p_clips.size(); i += 4) {
-
String name = p_clips[i];
float from = p_clips[i + 1];
float to = p_clips[i + 2];
bool loop = p_clips[i + 3];
- if (from >= to)
+ if (from >= to) {
continue;
+ }
Ref<Animation> new_anim = memnew(Animation);
for (int j = 0; j < default_anim->get_track_count(); j++) {
-
List<float> keys;
int kc = default_anim->track_get_key_count(j);
int dtrack = -1;
for (int k = 0; k < kc; k++) {
-
float kt = default_anim->track_get_key_time(j, k);
if (kt >= from && kt < to) {
-
//found a key within range, so create track
if (dtrack == -1) {
new_anim->add_track(default_anim->track_get_type(j));
@@ -698,7 +679,6 @@ void ResourceImporterScene::_create_clips(Node *scene, const Array &p_clips, boo
new_anim->track_set_path(dtrack, default_anim->track_get_path(j));
if (kt > (from + 0.01) && k > 0) {
-
if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM) {
Quat q;
Vector3 p;
@@ -727,7 +707,6 @@ void ResourceImporterScene::_create_clips(Node *scene, const Array &p_clips, boo
}
if (dtrack != -1 && kt >= to) {
-
if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM) {
Quat q;
Vector3 p;
@@ -747,7 +726,6 @@ void ResourceImporterScene::_create_clips(Node *scene, const Array &p_clips, boo
dtrack = new_anim->get_track_count() - 1;
new_anim->track_set_path(dtrack, default_anim->track_get_path(j));
if (default_anim->track_get_type(j) == Animation::TYPE_TRANSFORM) {
-
Quat q;
Vector3 p;
Vector3 s;
@@ -774,12 +752,10 @@ void ResourceImporterScene::_create_clips(Node *scene, const Array &p_clips, boo
}
void ResourceImporterScene::_filter_anim_tracks(Ref<Animation> anim, Set<String> &keep) {
-
Ref<Animation> a = anim;
ERR_FAIL_COND(!a.is_valid());
for (int j = 0; j < a->get_track_count(); j++) {
-
String path = a->track_get_path(j);
if (!keep.has(path)) {
@@ -790,9 +766,9 @@ void ResourceImporterScene::_filter_anim_tracks(Ref<Animation> anim, Set<String>
}
void ResourceImporterScene::_filter_tracks(Node *scene, const String &p_text) {
-
- if (!scene->has_node(String("AnimationPlayer")))
+ if (!scene->has_node(String("AnimationPlayer"))) {
return;
+ }
Node *n = scene->get_node(String("AnimationPlayer"));
ERR_FAIL_COND(!n);
AnimationPlayer *anim = Object::cast_to<AnimationPlayer>(n);
@@ -800,14 +776,12 @@ void ResourceImporterScene::_filter_tracks(Node *scene, const String &p_text) {
Vector<String> strings = p_text.split("\n");
for (int i = 0; i < strings.size(); i++) {
-
strings.write[i] = strings[i].strip_edges();
}
List<StringName> anim_names;
anim->get_animation_list(&anim_names);
for (List<StringName>::Element *E = anim_names.front(); E; E = E->next()) {
-
String name = E->get();
bool valid_for_this = false;
bool valid = false;
@@ -816,9 +790,7 @@ void ResourceImporterScene::_filter_tracks(Node *scene, const String &p_text) {
Set<String> keep_local;
for (int i = 0; i < strings.size(); i++) {
-
if (strings[i].begins_with("@")) {
-
valid_for_this = false;
for (Set<String>::Element *F = keep_local.front(); F; F = F->next()) {
keep.insert(F->get());
@@ -827,59 +799,64 @@ void ResourceImporterScene::_filter_tracks(Node *scene, const String &p_text) {
Vector<String> filters = strings[i].substr(1, strings[i].length()).split(",");
for (int j = 0; j < filters.size(); j++) {
-
String fname = filters[j].strip_edges();
- if (fname == "")
+ if (fname == "") {
continue;
+ }
int fc = fname[0];
bool plus;
- if (fc == '+')
+ if (fc == '+') {
plus = true;
- else if (fc == '-')
+ } else if (fc == '-') {
plus = false;
- else
+ } else {
continue;
+ }
String filter = fname.substr(1, fname.length()).strip_edges();
- if (!name.matchn(filter))
+ if (!name.matchn(filter)) {
continue;
+ }
valid_for_this = plus;
}
- if (valid_for_this)
+ if (valid_for_this) {
valid = true;
+ }
} else if (valid_for_this) {
-
Ref<Animation> a = anim->get_animation(name);
- if (!a.is_valid())
+ if (!a.is_valid()) {
continue;
+ }
for (int j = 0; j < a->get_track_count(); j++) {
-
String path = a->track_get_path(j);
String tname = strings[i];
- if (tname == "")
+ if (tname == "") {
continue;
+ }
int fc = tname[0];
bool plus;
- if (fc == '+')
+ if (fc == '+') {
plus = true;
- else if (fc == '-')
+ } else if (fc == '-') {
plus = false;
- else
+ } else {
continue;
+ }
String filter = tname.substr(1, tname.length()).strip_edges();
- if (!path.matchn(filter))
+ if (!path.matchn(filter)) {
continue;
+ }
- if (plus)
+ if (plus) {
keep_local.insert(path);
- else if (!keep.has(path)) {
+ } else if (!keep.has(path)) {
keep_local.erase(path);
}
}
@@ -896,9 +873,9 @@ void ResourceImporterScene::_filter_tracks(Node *scene, const String &p_text) {
}
void ResourceImporterScene::_optimize_animations(Node *scene, float p_max_lin_error, float p_max_ang_error, float p_max_angle) {
-
- if (!scene->has_node(String("AnimationPlayer")))
+ if (!scene->has_node(String("AnimationPlayer"))) {
return;
+ }
Node *n = scene->get_node(String("AnimationPlayer"));
ERR_FAIL_COND(!n);
AnimationPlayer *anim = Object::cast_to<AnimationPlayer>(n);
@@ -907,14 +884,12 @@ void ResourceImporterScene::_optimize_animations(Node *scene, float p_max_lin_er
List<StringName> anim_names;
anim->get_animation_list(&anim_names);
for (List<StringName>::Element *E = anim_names.front(); E; E = E->next()) {
-
Ref<Animation> a = anim->get_animation(E->get());
a->optimize(p_max_lin_error, p_max_ang_error, Math::deg2rad(p_max_angle));
}
}
static String _make_extname(const String &p_str) {
-
String ext_name = p_str.replace(".", "_");
ext_name = ext_name.replace(":", "_");
ext_name = ext_name.replace("\"", "_");
@@ -930,14 +905,12 @@ static String _make_extname(const String &p_str) {
}
void ResourceImporterScene::_find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Transform> &meshes) {
-
List<PropertyInfo> pi;
p_node->get_property_list(&pi);
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
if (mi) {
-
Ref<ArrayMesh> mesh = mi->get_mesh();
if (mesh.is_valid() && !meshes.has(mesh)) {
@@ -945,20 +918,18 @@ void ResourceImporterScene::_find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Trans
Transform transform;
while (s) {
transform = transform * s->get_transform();
- s = s->get_parent_spatial();
+ s = Object::cast_to<Node3D>(s->get_parent());
}
meshes[mesh] = transform;
}
}
for (int i = 0; i < p_node->get_child_count(); i++) {
-
_find_meshes(p_node->get_child(i), meshes);
}
}
void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_animations_as_text, bool p_keep_animations, bool p_make_materials, bool p_materials_as_text, bool p_keep_materials, bool p_make_meshes, bool p_meshes_as_text, Map<Ref<Animation>, Ref<Animation>> &p_animations, Map<Ref<Material>, Ref<Material>> &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh>> &p_meshes) {
-
List<PropertyInfo> pi;
if (p_make_animations) {
@@ -968,12 +939,10 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
List<StringName> anims;
ap->get_animation_list(&anims);
for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
-
Ref<Animation> anim = ap->get_animation(E->get());
ERR_CONTINUE(anim.is_null());
if (!p_animations.has(anim)) {
-
//mark what comes from the file first, this helps eventually keep user data
for (int i = 0; i < anim->get_track_count(); i++) {
anim->track_set_imported(i, true);
@@ -1012,15 +981,11 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
p_node->get_property_list(&pi);
for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
-
if (E->get().type == Variant::OBJECT) {
-
Ref<Material> mat = p_node->get(E->get().name);
if (p_make_materials && mat.is_valid() && mat->get_name() != "") {
-
if (!p_materials.has(mat)) {
-
String ext_name;
if (p_materials_as_text) {
@@ -1033,28 +998,22 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
//if exists, use it
p_materials[mat] = ResourceLoader::load(ext_name);
} else {
-
ResourceSaver::save(ext_name, mat, ResourceSaver::FLAG_CHANGE_PATH);
p_materials[mat] = ResourceLoader::load(ext_name, "", true); // disable loading from the cache.
}
}
if (p_materials[mat] != mat) {
-
p_node->set(E->get().name, p_materials[mat]);
}
} else {
-
Ref<ArrayMesh> mesh = p_node->get(E->get().name);
if (mesh.is_valid()) {
-
bool mesh_just_added = false;
if (p_make_meshes) {
-
if (!p_meshes.has(mesh)) {
-
//meshes are always overwritten, keeping them is not practical
String ext_name;
@@ -1072,16 +1031,16 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
}
if (p_make_materials) {
-
if (mesh_just_added || !p_meshes.has(mesh)) {
-
for (int i = 0; i < mesh->get_surface_count(); i++) {
mat = mesh->surface_get_material(i);
- if (!mat.is_valid())
+ if (!mat.is_valid()) {
continue;
- if (mat->get_name() == "")
+ }
+ if (mat->get_name() == "") {
continue;
+ }
if (!p_materials.has(mat)) {
String ext_name;
@@ -1096,19 +1055,16 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
//if exists, use it
p_materials[mat] = ResourceLoader::load(ext_name);
} else {
-
ResourceSaver::save(ext_name, mat, ResourceSaver::FLAG_CHANGE_PATH);
p_materials[mat] = ResourceLoader::load(ext_name, "", true); // disable loading from the cache.
}
}
if (p_materials[mat] != mat) {
-
mesh->surface_set_material(i, p_materials[mat]);
//re-save the mesh since a material is now assigned
if (p_make_meshes) {
-
String ext_name;
if (p_meshes_as_text) {
@@ -1134,13 +1090,11 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
}
for (int i = 0; i < p_node->get_child_count(); i++) {
-
_make_external_resources(p_node->get_child(i), p_base_path, p_make_animations, p_animations_as_text, p_keep_animations, p_make_materials, p_materials_as_text, p_keep_materials, p_make_meshes, p_meshes_as_text, p_animations, p_materials, p_meshes);
}
}
void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, int p_preset) const {
-
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_type", PROPERTY_HINT_TYPE_STRING, "Node"), "Node3D"));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_name"), "Scene Root"));
@@ -1150,8 +1104,9 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
String script_ext_hint;
for (List<String>::Element *E = script_extentions.front(); E; E = E->next()) {
- if (script_ext_hint != "")
+ if (script_ext_hint != "") {
script_ext_hint += ",";
+ }
script_ext_hint += "*." + E->get();
}
@@ -1193,7 +1148,6 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
}
void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner) {
-
if (p_node != p_new_owner && p_node->get_owner() == p_scene) {
p_node->set_owner(p_new_owner);
}
@@ -1205,28 +1159,26 @@ void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_
}
Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) {
-
Ref<EditorSceneImporter> importer;
String ext = p_path.get_extension().to_lower();
for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) {
-
- if (E->get().ptr() == p_exception)
+ if (E->get().ptr() == p_exception) {
continue;
+ }
List<String> extensions;
E->get()->get_extensions(&extensions);
for (List<String>::Element *F = extensions.front(); F; F = F->next()) {
-
if (F->get().to_lower() == ext) {
-
importer = E->get();
break;
}
}
- if (importer.is_valid())
+ if (importer.is_valid()) {
break;
+ }
}
ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
@@ -1237,28 +1189,26 @@ Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporte
}
Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps) {
-
Ref<EditorSceneImporter> importer;
String ext = p_path.get_extension().to_lower();
for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) {
-
- if (E->get().ptr() == p_exception)
+ if (E->get().ptr() == p_exception) {
continue;
+ }
List<String> extensions;
E->get()->get_extensions(&extensions);
for (List<String>::Element *F = extensions.front(); F; F = F->next()) {
-
if (F->get().to_lower() == ext) {
-
importer = E->get();
break;
}
}
- if (importer.is_valid())
+ if (importer.is_valid()) {
break;
+ }
}
ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
@@ -1267,7 +1217,6 @@ Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(Edito
}
Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
-
const String &src_path = p_source_file;
Ref<EditorSceneImporter> importer;
@@ -1277,21 +1226,19 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
progress.step(TTR("Importing Scene..."), 0);
for (Set<Ref<EditorSceneImporter>>::Element *E = importers.front(); E; E = E->next()) {
-
List<String> extensions;
E->get()->get_extensions(&extensions);
for (List<String>::Element *F = extensions.front(); F; F = F->next()) {
-
if (F->get().to_lower() == ext) {
-
importer = E->get();
break;
}
}
- if (importer.is_valid())
+ if (importer.is_valid()) {
break;
+ }
}
ERR_FAIL_COND_V(!importer.is_valid(), ERR_FILE_UNRECOGNIZED);
@@ -1299,23 +1246,29 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
float fps = p_options["animation/fps"];
int import_flags = EditorSceneImporter::IMPORT_ANIMATION_DETECT_LOOP;
- if (!bool(p_options["animation/optimizer/remove_unused_tracks"]))
+ if (!bool(p_options["animation/optimizer/remove_unused_tracks"])) {
import_flags |= EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS;
+ }
- if (bool(p_options["animation/import"]))
+ if (bool(p_options["animation/import"])) {
import_flags |= EditorSceneImporter::IMPORT_ANIMATION;
+ }
- if (int(p_options["meshes/compress"]))
+ if (int(p_options["meshes/compress"])) {
import_flags |= EditorSceneImporter::IMPORT_USE_COMPRESSION;
+ }
- if (bool(p_options["meshes/ensure_tangents"]))
+ if (bool(p_options["meshes/ensure_tangents"])) {
import_flags |= EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS;
+ }
- if (int(p_options["materials/location"]) == 0)
+ if (int(p_options["materials/location"]) == 0) {
import_flags |= EditorSceneImporter::IMPORT_MATERIALS_IN_INSTANCES;
+ }
- if (bool(p_options["skins/use_named_skins"]))
+ if (bool(p_options["skins/use_named_skins"])) {
import_flags |= EditorSceneImporter::IMPORT_USE_NAMED_SKIN_BINDS;
+ }
Error err = OK;
List<String> missing_deps; // for now, not much will be done with this
@@ -1337,7 +1290,6 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
Node *base_node = Object::cast_to<Node>(ClassDB::instance(root_type));
if (base_node) {
-
scene->replace_by(base_node);
memdelete(scene);
scene = base_node;
@@ -1348,15 +1300,17 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
scene->set_script(Variant(root_script));
}
+ float root_scale = 1.0;
if (Object::cast_to<Node3D>(scene)) {
- float root_scale = p_options["nodes/root_scale"];
+ root_scale = p_options["nodes/root_scale"];
Object::cast_to<Node3D>(scene)->scale(Vector3(root_scale, root_scale, root_scale));
}
- if (p_options["nodes/root_name"] != "Scene Root")
+ if (p_options["nodes/root_name"] != "Scene Root") {
scene->set_name(p_options["nodes/root_name"]);
- else
+ } else {
scene->set_name(p_save_path.get_file().get_basename());
+ }
err = OK;
@@ -1378,7 +1332,6 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
Array animation_clips;
{
-
int clip_count = p_options["animation/clips/amount"];
for (int i = 0; i < clip_count; i++) {
@@ -1413,7 +1366,6 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
String base_path = p_source_file.get_base_dir();
if (external_animations || external_materials || external_meshes || external_scenes) {
-
if (bool(p_options["external_files/store_in_subdir"])) {
String subdir_name = p_source_file.get_file().get_basename();
DirAccess *da = DirAccess::open(base_path);
@@ -1425,33 +1377,112 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
}
if (light_bake_mode == 2 /* || generate LOD */) {
-
Map<Ref<ArrayMesh>, Transform> meshes;
_find_meshes(scene, meshes);
- if (light_bake_mode == 2) {
+ String file_id = src_path.get_file();
+ String cache_file_path = base_path.plus_file(file_id + ".unwrap_cache");
- float texel_size = p_options["meshes/lightmap_texel_size"];
- texel_size = MAX(0.001, texel_size);
+ Vector<unsigned char> cache_data;
- EditorProgress progress2("gen_lightmaps", TTR("Generating Lightmaps"), meshes.size());
- int step = 0;
- for (Map<Ref<ArrayMesh>, Transform>::Element *E = meshes.front(); E; E = E->next()) {
+ if (FileAccess::exists(cache_file_path)) {
+ Error err2;
+ FileAccess *file = FileAccess::open(cache_file_path, FileAccess::READ, &err2);
- Ref<ArrayMesh> mesh = E->key();
- String name = mesh->get_name();
- if (name == "") { //should not happen but..
- name = "Mesh " + itos(step);
+ if (err2) {
+ if (file) {
+ memdelete(file);
}
+ } else {
+ int cache_size = file->get_len();
+ cache_data.resize(cache_size);
+ file->get_buffer(cache_data.ptrw(), cache_size);
+ }
+ }
- progress2.step(TTR("Generating for Mesh: ") + name + " (" + itos(step) + "/" + itos(meshes.size()) + ")", step);
+ float texel_size = p_options["meshes/lightmap_texel_size"];
+ texel_size = MAX(0.001, texel_size);
+
+ Map<String, unsigned int> used_unwraps;
+
+ EditorProgress progress2("gen_lightmaps", TTR("Generating Lightmaps"), meshes.size());
+ int step = 0;
+ for (Map<Ref<ArrayMesh>, Transform>::Element *E = meshes.front(); E; E = E->next()) {
+ Ref<ArrayMesh> mesh = E->key();
+ String name = mesh->get_name();
+ if (name == "") { //should not happen but..
+ name = "Mesh " + itos(step);
+ }
- Error err2 = mesh->lightmap_unwrap(E->get(), texel_size);
- if (err2 != OK) {
- EditorNode::add_io_error("Mesh '" + name + "' failed lightmap generation. Please fix geometry.");
+ progress2.step(TTR("Generating for Mesh: ") + name + " (" + itos(step) + "/" + itos(meshes.size()) + ")", step);
+
+ int *ret_cache_data = (int *)cache_data.ptrw();
+ unsigned int ret_cache_size = cache_data.size();
+ bool ret_used_cache = true; // Tell the unwrapper to use the cache
+ Error err2 = mesh->lightmap_unwrap_cached(ret_cache_data, ret_cache_size, ret_used_cache, E->get(), texel_size);
+
+ if (err2 != OK) {
+ EditorNode::add_io_error("Mesh '" + name + "' failed lightmap generation. Please fix geometry.");
+ } else {
+ String hash = String::md5((unsigned char *)ret_cache_data);
+ used_unwraps.insert(hash, ret_cache_size);
+
+ if (!ret_used_cache) {
+ // Cache was not used, add the generated entry to the current cache
+ if (cache_data.empty()) {
+ cache_data.resize(4 + ret_cache_size);
+ int *data = (int *)cache_data.ptrw();
+ data[0] = 1;
+ memcpy(&data[1], ret_cache_data, ret_cache_size);
+ } else {
+ int current_size = cache_data.size();
+ cache_data.resize(cache_data.size() + ret_cache_size);
+ unsigned char *ptrw = cache_data.ptrw();
+ memcpy(&ptrw[current_size], ret_cache_data, ret_cache_size);
+ int *data = (int *)ptrw;
+ data[0] += 1;
+ }
}
- step++;
}
+ step++;
+ }
+
+ Error err2;
+ FileAccess *file = FileAccess::open(cache_file_path, FileAccess::WRITE, &err2);
+
+ if (err2) {
+ if (file) {
+ memdelete(file);
+ }
+ } else {
+ // Store number of entries
+ file->store_32(used_unwraps.size());
+
+ // Store cache entries
+ const int *cache = (int *)cache_data.ptr();
+ unsigned int r_idx = 1;
+ for (int i = 0; i < cache[0]; ++i) {
+ unsigned char *entry_start = (unsigned char *)&cache[r_idx];
+ String entry_hash = String::md5(entry_start);
+ if (used_unwraps.has(entry_hash)) {
+ unsigned int entry_size = used_unwraps[entry_hash];
+ file->store_buffer(entry_start, entry_size);
+ }
+
+ r_idx += 4; // hash
+ r_idx += 2; // size hint
+
+ int vertex_count = cache[r_idx];
+ r_idx += 1; // vertex count
+ r_idx += vertex_count; // vertex
+ r_idx += vertex_count * 2; // uvs
+
+ int index_count = cache[r_idx];
+ r_idx += 1; // index count
+ r_idx += index_count; // indices
+ }
+
+ file->close();
}
}
@@ -1475,7 +1506,6 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
if (!scr.is_valid()) {
EditorNode::add_io_error(TTR("Couldn't load post-import script:") + " " + post_import_script_path);
} else {
-
post_import_script = Ref<EditorScenePostImport>(memnew(EditorScenePostImport));
post_import_script->set_script(scr);
if (!post_import_script->get_script_instance()) {
@@ -1490,7 +1520,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
post_import_script->init(base_path, p_source_file);
scene = post_import_script->post_import(scene);
if (!scene) {
- EditorNode::add_io_error(TTR("Error running post-import script:") + " " + post_import_script_path);
+ EditorNode::add_io_error(
+ TTR("Error running post-import script:") + " " + post_import_script_path + "\n" +
+ TTR("Did you return a Node-derived object in the `post_import()` method?"));
return err;
}
}
@@ -1501,8 +1533,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
//save sub-scenes as instances!
for (int i = 0; i < scene->get_child_count(); i++) {
Node *child = scene->get_child(i);
- if (child->get_owner() != scene)
+ if (child->get_owner() != scene) {
continue; //not a real child probably created by scene type (ig, a scrollbar)
+ }
_replace_owner(child, scene, child);
String cn = String(child->get_name()).strip_edges().replace(".", "_").replace(":", "_");
@@ -1538,16 +1571,18 @@ ResourceImporterScene *ResourceImporterScene::singleton = nullptr;
ResourceImporterScene::ResourceImporterScene() {
singleton = this;
}
+
///////////////////////////////////////
uint32_t EditorSceneImporterESCN::get_import_flags() const {
return IMPORT_SCENE;
}
+
void EditorSceneImporterESCN::get_extensions(List<String> *r_extensions) const {
r_extensions->push_back("escn");
}
-Node *EditorSceneImporterESCN::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
+Node *EditorSceneImporterESCN::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
Error error;
Ref<PackedScene> ps = ResourceFormatLoaderText::singleton->load(p_path, p_path, &error);
ERR_FAIL_COND_V_MSG(!ps.is_valid(), nullptr, "Cannot load scene as text resource from path '" + p_path + "'.");
@@ -1557,6 +1592,7 @@ Node *EditorSceneImporterESCN::import_scene(const String &p_path, uint32_t p_fla
return scene;
}
+
Ref<Animation> EditorSceneImporterESCN::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
ERR_FAIL_V(Ref<Animation>());
}
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index f48f181951..34d96bbc44 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -39,7 +39,6 @@
class Material;
class EditorSceneImporter : public Reference {
-
GDCLASS(EditorSceneImporter, Reference);
protected:
@@ -73,7 +72,6 @@ public:
};
class EditorScenePostImport : public Reference {
-
GDCLASS(EditorScenePostImport, Reference);
String source_folder;
diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp
new file mode 100644
index 0000000000..a2e80dfa18
--- /dev/null
+++ b/editor/import/resource_importer_shader_file.cpp
@@ -0,0 +1,118 @@
+/*************************************************************************/
+/* resource_importer_shader_file.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "resource_importer_shader_file.h"
+
+#include "core/io/marshalls.h"
+#include "core/io/resource_saver.h"
+#include "core/os/file_access.h"
+#include "editor/editor_node.h"
+#include "editor/plugins/shader_file_editor_plugin.h"
+#include "servers/rendering/rendering_device_binds.h"
+
+String ResourceImporterShaderFile::get_importer_name() const {
+ return "glsl";
+}
+
+String ResourceImporterShaderFile::get_visible_name() const {
+ return "GLSL Shader File";
+}
+
+void ResourceImporterShaderFile::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("glsl");
+}
+
+String ResourceImporterShaderFile::get_save_extension() const {
+ return "res";
+}
+
+String ResourceImporterShaderFile::get_resource_type() const {
+ return "RDShaderFile";
+}
+
+int ResourceImporterShaderFile::get_preset_count() const {
+ return 0;
+}
+
+String ResourceImporterShaderFile::get_preset_name(int p_idx) const {
+ return String();
+}
+
+void ResourceImporterShaderFile::get_import_options(List<ImportOption> *r_options, int p_preset) const {
+}
+
+bool ResourceImporterShaderFile::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+ return true;
+}
+
+static String _include_function(const String &p_path, void *userpointer) {
+ Error err;
+
+ String *base_path = (String *)userpointer;
+
+ String include = p_path;
+ if (include.is_rel_path()) {
+ include = base_path->plus_file(include);
+ }
+
+ FileAccessRef file_inc = FileAccess::open(include, FileAccess::READ, &err);
+ if (err != OK) {
+ return String();
+ }
+ return file_inc->get_as_utf8_string();
+}
+
+Error ResourceImporterShaderFile::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
+ /* STEP 1, Read shader code */
+
+ Error err;
+ FileAccessRef file = FileAccess::open(p_source_file, FileAccess::READ, &err);
+ ERR_FAIL_COND_V(err != OK, ERR_CANT_OPEN);
+ ERR_FAIL_COND_V(!file.operator->(), ERR_CANT_OPEN);
+
+ String file_txt = file->get_as_utf8_string();
+ Ref<RDShaderFile> shader_file;
+ shader_file.instance();
+ String base_path = p_source_file.get_base_dir();
+ err = shader_file->parse_versions_from_text(file_txt, "", _include_function, &base_path);
+
+ if (err != OK) {
+ if (!ShaderFileEditor::singleton->is_visible_in_tree()) {
+ EditorNode::get_singleton()->add_io_error(vformat(TTR("Error importing GLSL shader file: '%s'. Open the file in the filesystem dock in order to see the reason."), p_source_file));
+ }
+ }
+
+ ResourceSaver::save(p_save_path + ".res", shader_file);
+
+ return OK;
+}
+
+ResourceImporterShaderFile::ResourceImporterShaderFile() {
+}
diff --git a/editor/import/resource_importer_shader_file.h b/editor/import/resource_importer_shader_file.h
new file mode 100644
index 0000000000..fa95ceecc1
--- /dev/null
+++ b/editor/import/resource_importer_shader_file.h
@@ -0,0 +1,57 @@
+/*************************************************************************/
+/* resource_importer_shader_file.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RESOURCE_IMPORTER_SHADER_FILE_H
+#define RESOURCE_IMPORTER_SHADER_FILE_H
+
+#include "core/io/resource_importer.h"
+
+class ResourceImporterShaderFile : public ResourceImporter {
+ GDCLASS(ResourceImporterShaderFile, ResourceImporter);
+
+public:
+ virtual String get_importer_name() const;
+ virtual String get_visible_name() const;
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual String get_save_extension() const;
+ virtual String get_resource_type() const;
+
+ virtual int get_preset_count() const;
+ virtual String get_preset_name(int p_idx) const;
+
+ virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
+ virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
+
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
+
+ ResourceImporterShaderFile();
+};
+
+#endif // RESOURCE_IMPORTER_SHADER_FILE_H
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index f8ed9304b6..a13324f0fc 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -36,8 +36,7 @@
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
-void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTexture> &p_tex, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_channel) {
-
+void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTexture2D> &p_tex, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_channel) {
MutexLock lock(singleton->mutex);
StringName path = p_tex->get_path();
@@ -51,8 +50,7 @@ void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTextur
singleton->make_flags[path].normal_path_for_roughness = p_normal_path;
}
-void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_tex) {
-
+void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture2D> &p_tex) {
MutexLock lock(singleton->mutex);
StringName path = p_tex->get_path();
@@ -64,8 +62,7 @@ void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_t
singleton->make_flags[path].flags |= MAKE_3D_FLAG;
}
-void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture> &p_tex) {
-
+void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture2D> &p_tex) {
MutexLock lock(singleton->mutex);
StringName path = p_tex->get_path();
@@ -78,7 +75,6 @@ void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture>
}
void ResourceImporterTexture::update_imports() {
-
if (EditorFileSystem::get_singleton()->is_scanning() || EditorFileSystem::get_singleton()->is_importing()) {
return; // do nothing for now
}
@@ -91,7 +87,6 @@ void ResourceImporterTexture::update_imports() {
}
for (Map<StringName, MakeInfo>::Element *E = make_flags.front(); E; E = E->next()) {
-
Ref<ConfigFile> cf;
cf.instance();
String src_path = String(E->key()) + ".import";
@@ -139,29 +134,26 @@ void ResourceImporterTexture::update_imports() {
}
String ResourceImporterTexture::get_importer_name() const {
-
return "texture";
}
String ResourceImporterTexture::get_visible_name() const {
-
return "Texture2D";
}
-void ResourceImporterTexture::get_recognized_extensions(List<String> *p_extensions) const {
+void ResourceImporterTexture::get_recognized_extensions(List<String> *p_extensions) const {
ImageLoader::get_recognized_extensions(p_extensions);
}
+
String ResourceImporterTexture::get_save_extension() const {
return "stex";
}
String ResourceImporterTexture::get_resource_type() const {
-
- return "StreamTexture";
+ return "StreamTexture2D";
}
bool ResourceImporterTexture::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
-
if (p_option == "compress/lossy_quality") {
int compress_mode = int(p_options["compress/mode"]);
if (compress_mode != COMPRESS_LOSSY && compress_mode != COMPRESS_VRAM_COMPRESSED) {
@@ -191,8 +183,8 @@ bool ResourceImporterTexture::get_option_visibility(const String &p_option, cons
int ResourceImporterTexture::get_preset_count() const {
return 4;
}
-String ResourceImporterTexture::get_preset_name(int p_idx) const {
+String ResourceImporterTexture::get_preset_name(int p_idx) const {
static const char *preset_names[] = {
"2D, Detect 3D",
"2D",
@@ -204,11 +196,10 @@ String ResourceImporterTexture::get_preset_name(int p_idx) const {
}
void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options, int p_preset) const {
-
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,VRAM Compressed,VRAM Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 2 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_mode", PROPERTY_HINT_ENUM, "Enabled,Force RGBE"), 0));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Enabled,RGBA Only"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_compression", PROPERTY_HINT_ENUM, "Disabled,Opaque Only,Always"), 1));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Disabled,Enabled,RGBA Only"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/normal_map", PROPERTY_HINT_ENUM, "Detect,Enable,Disabled"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/channel_pack", PROPERTY_HINT_ENUM, "sRGB Friendly,Optimized"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/streamed"), false));
@@ -225,19 +216,16 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "svg/scale", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 1.0));
}
-void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality, bool p_force_rgbe) {
-
+void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality) {
switch (p_compress_mode) {
case COMPRESS_LOSSLESS: {
-
- f->store_32(StreamTexture::DATA_FORMAT_LOSSLESS);
+ f->store_32(StreamTexture2D::DATA_FORMAT_LOSSLESS);
f->store_16(p_image->get_width());
f->store_16(p_image->get_height());
f->store_32(p_image->get_mipmap_count());
f->store_32(p_image->get_format());
for (int i = 0; i < p_image->get_mipmap_count() + 1; i++) {
-
Vector<uint8_t> data = Image::lossless_packer(p_image->get_image_from_mipmap(i));
int data_len = data.size();
f->store_32(data_len);
@@ -248,15 +236,13 @@ void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image
} break;
case COMPRESS_LOSSY: {
-
- f->store_32(StreamTexture::DATA_FORMAT_LOSSY);
+ f->store_32(StreamTexture2D::DATA_FORMAT_LOSSY);
f->store_16(p_image->get_width());
f->store_16(p_image->get_height());
f->store_32(p_image->get_mipmap_count());
f->store_32(p_image->get_format());
for (int i = 0; i < p_image->get_mipmap_count() + 1; i++) {
-
Vector<uint8_t> data = Image::lossy_packer(p_image->get_image_from_mipmap(i), p_lossy_quality);
int data_len = data.size();
f->store_32(data_len);
@@ -266,16 +252,11 @@ void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image
}
} break;
case COMPRESS_VRAM_COMPRESSED: {
-
Ref<Image> image = p_image->duplicate();
- if (p_force_rgbe && image->get_format() >= Image::FORMAT_RF && image->get_format() < Image::FORMAT_RGBE9995) {
- image->convert(Image::FORMAT_RGBE9995);
- } else {
- image->compress_from_channels(p_compress_format, p_channels, p_lossy_quality);
- }
+ image->compress_from_channels(p_compress_format, p_channels, p_lossy_quality);
- f->store_32(StreamTexture::DATA_FORMAT_IMAGE);
+ f->store_32(StreamTexture2D::DATA_FORMAT_IMAGE);
f->store_16(image->get_width());
f->store_16(image->get_height());
f->store_32(image->get_mipmap_count());
@@ -287,8 +268,7 @@ void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image
f->store_buffer(r, dl);
} break;
case COMPRESS_VRAM_UNCOMPRESSED: {
-
- f->store_32(StreamTexture::DATA_FORMAT_IMAGE);
+ f->store_32(StreamTexture2D::DATA_FORMAT_IMAGE);
f->store_16(p_image->get_width());
f->store_16(p_image->get_height());
f->store_32(p_image->get_mipmap_count());
@@ -302,15 +282,13 @@ void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image
} break;
case COMPRESS_BASIS_UNIVERSAL: {
-
- f->store_32(StreamTexture::DATA_FORMAT_BASIS_UNIVERSAL);
+ f->store_32(StreamTexture2D::DATA_FORMAT_BASIS_UNIVERSAL);
f->store_16(p_image->get_width());
f->store_16(p_image->get_height());
f->store_32(p_image->get_mipmap_count());
f->store_32(p_image->get_format());
for (int i = 0; i < p_image->get_mipmap_count() + 1; i++) {
-
Vector<uint8_t> data = Image::basis_universal_packer(p_image->get_image_from_mipmap(i), p_channels);
int data_len = data.size();
f->store_32(data_len);
@@ -322,8 +300,7 @@ void ResourceImporterTexture::save_to_stex_format(FileAccess *f, const Ref<Image
}
}
-void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String &p_to_path, CompressMode p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, bool p_streamable, bool p_detect_3d, bool p_detect_roughness, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal, bool p_srgb_friendly, bool p_force_po2_for_compressed, uint32_t p_limit_mipmap, const Ref<Image> &p_normal, Image::RoughnessChannel p_roughness_channel) {
-
+void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String &p_to_path, CompressMode p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, bool p_streamable, bool p_detect_3d, bool p_detect_roughness, bool p_detect_normal, bool p_force_normal, bool p_srgb_friendly, bool p_force_po2_for_compressed, uint32_t p_limit_mipmap, const Ref<Image> &p_normal, Image::RoughnessChannel p_roughness_channel) {
FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE);
f->store_8('G');
f->store_8('S');
@@ -331,22 +308,27 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String
f->store_8('2'); //godot streamable texture 2D
//format version
- f->store_32(StreamTexture::FORMAT_VERSION);
+ f->store_32(StreamTexture2D::FORMAT_VERSION);
//texture may be resized later, so original size must be saved first
f->store_32(p_image->get_width());
f->store_32(p_image->get_height());
uint32_t flags = 0;
- if (p_streamable)
- flags |= StreamTexture::FORMAT_BIT_STREAM;
- if (p_mipmaps)
- flags |= StreamTexture::FORMAT_BIT_HAS_MIPMAPS; //mipmaps bit
- if (p_detect_3d)
- flags |= StreamTexture::FORMAT_BIT_DETECT_3D;
- if (p_detect_roughness)
- flags |= StreamTexture::FORMAT_BIT_DETECT_ROUGNESS;
- if (p_detect_normal)
- flags |= StreamTexture::FORMAT_BIT_DETECT_NORMAL;
+ if (p_streamable) {
+ flags |= StreamTexture2D::FORMAT_BIT_STREAM;
+ }
+ if (p_mipmaps) {
+ flags |= StreamTexture2D::FORMAT_BIT_HAS_MIPMAPS; //mipmaps bit
+ }
+ if (p_detect_3d) {
+ flags |= StreamTexture2D::FORMAT_BIT_DETECT_3D;
+ }
+ if (p_detect_roughness) {
+ flags |= StreamTexture2D::FORMAT_BIT_DETECT_ROUGNESS;
+ }
+ if (p_detect_normal) {
+ flags |= StreamTexture2D::FORMAT_BIT_DETECT_NORMAL;
+ }
f->store_32(flags);
f->store_32(p_limit_mipmap);
@@ -385,10 +367,6 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String
image->generate_mipmap_roughness(p_roughness_channel, p_normal);
}
- if (p_force_rgbe && image->get_format() >= Image::FORMAT_RF && image->get_format() < Image::FORMAT_RGBE9995) {
- image->convert(Image::FORMAT_RGBE9995);
- }
-
Image::CompressSource csource = Image::COMPRESS_SOURCE_GENERIC;
if (p_force_normal) {
csource = Image::COMPRESS_SOURCE_NORMAL;
@@ -398,13 +376,12 @@ void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String
Image::UsedChannels used_channels = image->detect_used_channels(csource);
- save_to_stex_format(f, image, p_compress_mode, used_channels, p_vram_compression, p_lossy_quality, p_force_rgbe);
+ save_to_stex_format(f, image, p_compress_mode, used_channels, p_vram_compression, p_lossy_quality);
memdelete(f);
}
Error ResourceImporterTexture::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
-
CompressMode compress_mode = CompressMode(int(p_options["compress/mode"]));
float lossy = p_options["compress/lossy_quality"];
int pack_channels = p_options["compress/channel_pack"];
@@ -418,7 +395,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
bool hdr_as_srgb = p_options["process/HDR_as_SRGB"];
int normal = p_options["compress/normal_map"];
float scale = p_options["svg/scale"];
- bool force_rgbe = int(p_options["compress/hdr_mode"]) == 1;
+ int hdr_compression = p_options["compress/hdr_compression"];
int bptc_ldr = p_options["compress/bptc_ldr"];
int roughness = p_options["roughness/mode"];
String normal_map = p_options["roughness/src_normal"];
@@ -435,8 +412,9 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
Ref<Image> image;
image.instance();
Error err = ImageLoader::load_image(p_source_file, image, nullptr, hdr_as_srgb, scale);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
Array formats_imported;
@@ -448,7 +426,6 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
image->resize(new_width, new_height, Image::INTERPOLATE_CUBIC);
} else {
-
int new_height = size_limit;
int new_width = image->get_width() * new_height / image->get_height();
@@ -501,51 +478,67 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
bool can_s3tc = ProjectSettings::get_singleton()->get("rendering/vram_compression/import_s3tc");
if (can_bptc) {
- Image::UsedChannels channels = image->detect_used_channels();
- if (is_hdr) {
+ //add to the list anyway
+ formats_imported.push_back("bptc");
+ }
- if (channels == Image::USED_CHANNELS_LA || channels == Image::USED_CHANNELS_RGBA) {
- can_bptc = false;
+ bool can_compress_hdr = hdr_compression > 0;
+ bool has_alpha = image->detect_alpha() != Image::ALPHA_NONE;
+
+ if (is_hdr && can_compress_hdr) {
+ if (has_alpha) {
+ //can compress hdr, but hdr with alpha is not compressible
+ if (hdr_compression == 2) {
+ //but user selected to compress hdr anyway, so force an alpha-less format.
+ if (image->get_format() == Image::FORMAT_RGBAF) {
+ image->convert(Image::FORMAT_RGBF);
+ } else if (image->get_format() == Image::FORMAT_RGBAH) {
+ image->convert(Image::FORMAT_RGBH);
+ }
+ } else {
+ can_compress_hdr = false;
}
- } else if (is_ldr) {
+ }
- //handle "RGBA Only" setting
- if (bptc_ldr == 1 && channels != Image::USED_CHANNELS_LA && channels != Image::USED_CHANNELS_RGBA) {
- can_bptc = false;
+ if (can_compress_hdr) {
+ if (!can_bptc) {
+ //fallback to RGBE99995
+ if (image->get_format() != Image::FORMAT_RGBE9995) {
+ image->convert(Image::FORMAT_RGBE9995);
+ }
}
+ } else {
+ can_bptc = false;
}
-
- formats_imported.push_back("bptc");
}
- if (!can_bptc && is_hdr && !force_rgbe) {
- //convert to ldr if this can't be stored hdr
- image->convert(Image::FORMAT_RGBA8);
+ if (is_ldr && can_bptc) {
+ if (bptc_ldr == 0 || (bptc_ldr == 1 && !has_alpha)) {
+ can_bptc = false;
+ }
}
if (can_bptc || can_s3tc) {
- _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, mipmaps, stream, detect_3d, detect_roughness, force_rgbe, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel);
+ _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel);
r_platform_variants->push_back("s3tc");
formats_imported.push_back("s3tc");
ok_on_pc = true;
}
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc2")) {
-
- _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, stream, detect_3d, detect_roughness, force_rgbe, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
+ _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
r_platform_variants->push_back("etc2");
formats_imported.push_back("etc2");
}
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_etc")) {
- _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, stream, detect_3d, detect_roughness, force_rgbe, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
+ _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
r_platform_variants->push_back("etc");
formats_imported.push_back("etc");
}
if (ProjectSettings::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
-
- _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, stream, detect_3d, detect_roughness, force_rgbe, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
+ _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
r_platform_variants->push_back("pvrtc");
formats_imported.push_back("pvrtc");
}
@@ -555,7 +548,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
}
} else {
//import normally
- _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, stream, detect_3d, detect_roughness, force_rgbe, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel);
+ _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel);
}
if (r_metadata) {
@@ -578,7 +571,6 @@ const char *ResourceImporterTexture::compression_formats[] = {
nullptr
};
String ResourceImporterTexture::get_import_settings_string() const {
-
String s;
int index = 0;
@@ -595,7 +587,6 @@ String ResourceImporterTexture::get_import_settings_string() const {
}
bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) const {
-
//will become invalid if formats are missing to import
Dictionary metadata = ResourceFormatImporter::get_singleton()->get_resource_metadata(p_path);
@@ -633,11 +624,10 @@ bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) co
ResourceImporterTexture *ResourceImporterTexture::singleton = nullptr;
ResourceImporterTexture::ResourceImporterTexture() {
-
singleton = this;
- StreamTexture::request_3d_callback = _texture_reimport_3d;
- StreamTexture::request_roughness_callback = _texture_reimport_roughness;
- StreamTexture::request_normal_callback = _texture_reimport_normal;
+ StreamTexture2D::request_3d_callback = _texture_reimport_3d;
+ StreamTexture2D::request_roughness_callback = _texture_reimport_roughness;
+ StreamTexture2D::request_normal_callback = _texture_reimport_normal;
}
ResourceImporterTexture::~ResourceImporterTexture() {
diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h
index e1c71ff1b8..b770d240eb 100644
--- a/editor/import/resource_importer_texture.h
+++ b/editor/import/resource_importer_texture.h
@@ -37,7 +37,7 @@
#include "scene/resources/texture.h"
#include "servers/rendering_server.h"
-class StreamTexture;
+class StreamTexture2D;
class ResourceImporterTexture : public ResourceImporter {
GDCLASS(ResourceImporterTexture, ResourceImporter);
@@ -60,7 +60,6 @@ protected:
Mutex mutex;
struct MakeInfo {
-
int flags;
String normal_path_for_roughness;
RS::TextureDetectRoughnessChannel channel_for_roughness;
@@ -72,17 +71,17 @@ protected:
Map<StringName, MakeInfo> make_flags;
- static void _texture_reimport_roughness(const Ref<StreamTexture> &p_tex, const String &p_normal_path, RenderingServer::TextureDetectRoughnessChannel p_channel);
- static void _texture_reimport_3d(const Ref<StreamTexture> &p_tex);
- static void _texture_reimport_normal(const Ref<StreamTexture> &p_tex);
+ static void _texture_reimport_roughness(const Ref<StreamTexture2D> &p_tex, const String &p_normal_path, RenderingServer::TextureDetectRoughnessChannel p_channel);
+ static void _texture_reimport_3d(const Ref<StreamTexture2D> &p_tex);
+ static void _texture_reimport_normal(const Ref<StreamTexture2D> &p_tex);
static ResourceImporterTexture *singleton;
static const char *compression_formats[];
- void _save_stex(const Ref<Image> &p_image, const String &p_to_path, CompressMode p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, bool p_streamable, bool p_detect_3d, bool p_detect_srgb, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal, bool p_srgb_friendly, bool p_force_po2_for_compressed, uint32_t p_limit_mipmap, const Ref<Image> &p_normal, Image::RoughnessChannel p_roughness_channel);
+ void _save_stex(const Ref<Image> &p_image, const String &p_to_path, CompressMode p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, bool p_streamable, bool p_detect_3d, bool p_detect_srgb, bool p_detect_normal, bool p_force_normal, bool p_srgb_friendly, bool p_force_po2_for_compressed, uint32_t p_limit_mipmap, const Ref<Image> &p_normal, Image::RoughnessChannel p_roughness_channel);
public:
- void save_to_stex_format(FileAccess *f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality, bool p_force_rgbe);
+ static void save_to_stex_format(FileAccess *f, const Ref<Image> &p_image, CompressMode p_compress_mode, Image::UsedChannels p_channels, Image::CompressMode p_compress_format, float p_lossy_quality);
static ResourceImporterTexture *get_singleton() { return singleton; }
virtual String get_importer_name() const;
diff --git a/editor/import/resource_importer_texture_atlas.cpp b/editor/import/resource_importer_texture_atlas.cpp
index 2765bb7fae..0818655c4c 100644
--- a/editor/import/resource_importer_texture_atlas.cpp
+++ b/editor/import/resource_importer_texture_atlas.cpp
@@ -39,16 +39,14 @@
#include "scene/resources/texture.h"
String ResourceImporterTextureAtlas::get_importer_name() const {
-
return "texture_atlas";
}
String ResourceImporterTextureAtlas::get_visible_name() const {
-
return "TextureAtlas";
}
-void ResourceImporterTextureAtlas::get_recognized_extensions(List<String> *p_extensions) const {
+void ResourceImporterTextureAtlas::get_recognized_extensions(List<String> *p_extensions) const {
ImageLoader::get_recognized_extensions(p_extensions);
}
@@ -57,25 +55,22 @@ String ResourceImporterTextureAtlas::get_save_extension() const {
}
String ResourceImporterTextureAtlas::get_resource_type() const {
-
return "Texture2D";
}
bool ResourceImporterTextureAtlas::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
-
return true;
}
int ResourceImporterTextureAtlas::get_preset_count() const {
return 0;
}
-String ResourceImporterTextureAtlas::get_preset_name(int p_idx) const {
+String ResourceImporterTextureAtlas::get_preset_name(int p_idx) const {
return String();
}
void ResourceImporterTextureAtlas::get_import_options(List<ImportOption> *r_options, int p_preset) const {
-
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "atlas_file", PROPERTY_HINT_SAVE_FILE, "*.png"), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "import_mode", PROPERTY_HINT_ENUM, "Region,Mesh2D"), 0));
}
@@ -85,7 +80,6 @@ String ResourceImporterTextureAtlas::get_option_group_file() const {
}
Error ResourceImporterTextureAtlas::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
-
/* If this happens, it's because the atlas_file field was not filled, so just import a broken texture */
//use an xpm because it's size independent, the editor images are vector and size dependent
@@ -103,7 +97,6 @@ Error ResourceImporterTextureAtlas::import(const String &p_source_file, const St
}
static void _plot_triangle(Vector2 *vertices, const Vector2 &p_offset, bool p_transposed, Ref<Image> p_image, const Ref<Image> &p_src_image) {
-
int width = p_image->get_width();
int height = p_image->get_height();
int src_width = p_src_image->get_width();
@@ -113,7 +106,6 @@ static void _plot_triangle(Vector2 *vertices, const Vector2 &p_offset, bool p_tr
int y[3];
for (int j = 0; j < 3; j++) {
-
x[j] = vertices[j].x;
y[j] = vertices[j].y;
}
@@ -140,7 +132,6 @@ static void _plot_triangle(Vector2 *vertices, const Vector2 &p_offset, bool p_tr
for (int yi = y[0]; yi <= (y[2] > height - 1 ? height - 1 : y[2]); yi++) {
if (yi >= 0) {
for (int xi = (xf > 0 ? int(xf) : 0); xi <= (xt < width ? xt : width - 1); xi++) {
-
int px = xi, py = yi;
int sx = px, sy = py;
sx = CLAMP(sx, 0, src_width - 1);
@@ -185,15 +176,15 @@ static void _plot_triangle(Vector2 *vertices, const Vector2 &p_offset, bool p_tr
}
}
xf += dx_far;
- if (yi < y[1])
+ if (yi < y[1]) {
xt += dx_upper;
- else
+ } else {
xt += dx_low;
+ }
}
}
Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant>> &p_source_file_options, const Map<String, String> &p_base_paths) {
-
ERR_FAIL_COND_V(p_source_file_options.size() == 0, ERR_BUG); //should never happen
Vector<EditorAtlasPacker::Chart> charts;
@@ -203,7 +194,6 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
int idx = 0;
for (const Map<String, Map<StringName, Variant>>::Element *E = p_source_file_options.front(); E; E = E->next(), idx++) {
-
PackData &pack_data = pack_data_files.write[idx];
const String &source = E->key();
const Map<StringName, Variant> &options = E->get();
@@ -218,7 +208,6 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
int mode = options["import_mode"];
if (mode == IMPORT_MODE_REGION) {
-
pack_data.is_mesh = false;
EditorAtlasPacker::Chart chart;
@@ -254,14 +243,12 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
Vector<Vector<Vector2>> polygons = bit_map->clip_opaque_to_polygons(Rect2(0, 0, image->get_width(), image->get_height()));
for (int j = 0; j < polygons.size(); j++) {
-
EditorAtlasPacker::Chart chart;
chart.vertices = polygons[j];
chart.can_transpose = true;
Vector<int> poly = Geometry::triangulate_polygon(polygons[j]);
for (int i = 0; i < poly.size(); i += 3) {
-
EditorAtlasPacker::Chart::Face f;
f.vertex[0] = poly[i + 0];
f.vertex[1] = poly[i + 1];
@@ -287,7 +274,6 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
new_atlas->create(atlas_width, atlas_height, false, Image::FORMAT_RGBA8);
for (int i = 0; i < pack_data_files.size(); i++) {
-
PackData &pack_data = pack_data_files.write[i];
for (int j = 0; j < pack_data.chart_pieces.size(); j++) {
@@ -324,7 +310,6 @@ Error ResourceImporterTextureAtlas::import_group_file(const String &p_group_file
//save the images
idx = 0;
for (const Map<String, Map<StringName, Variant>>::Element *E = p_source_file_options.front(); E; E = E->next(), idx++) {
-
PackData &pack_data = pack_data_files.write[idx];
Ref<Texture2D> texture;
diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index 71f81051bc..cb669b4c89 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -39,29 +39,26 @@ const float TRIM_DB_LIMIT = -50;
const int TRIM_FADE_OUT_FRAMES = 500;
String ResourceImporterWAV::get_importer_name() const {
-
return "wav";
}
String ResourceImporterWAV::get_visible_name() const {
-
return "Microsoft WAV";
}
-void ResourceImporterWAV::get_recognized_extensions(List<String> *p_extensions) const {
+void ResourceImporterWAV::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("wav");
}
+
String ResourceImporterWAV::get_save_extension() const {
return "sample";
}
String ResourceImporterWAV::get_resource_type() const {
-
return "AudioStreamSample";
}
bool ResourceImporterWAV::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
-
if (p_option == "force/max_rate_hz" && !bool(p_options["force/max_rate"])) {
return false;
}
@@ -72,13 +69,12 @@ bool ResourceImporterWAV::get_option_visibility(const String &p_option, const Ma
int ResourceImporterWAV::get_preset_count() const {
return 0;
}
-String ResourceImporterWAV::get_preset_name(int p_idx) const {
+String ResourceImporterWAV::get_preset_name(int p_idx) const {
return String();
}
void ResourceImporterWAV::get_import_options(List<ImportOption> *r_options, int p_preset) const {
-
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/8_bit"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/mono"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/max_rate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
@@ -90,7 +86,6 @@ void ResourceImporterWAV::get_import_options(List<ImportOption> *r_options, int
}
Error ResourceImporterWAV::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
-
/* STEP 1, READ WAVE FILE */
Error err;
@@ -104,7 +99,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
file->get_buffer((uint8_t *)&riff, 4); //RIFF
if (riff[0] != 'R' || riff[1] != 'I' || riff[2] != 'F' || riff[3] != 'F') {
-
file->close();
memdelete(file);
ERR_FAIL_V(ERR_FILE_UNRECOGNIZED);
@@ -120,7 +114,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
file->get_buffer((uint8_t *)&wave, 4); //RIFF
if (wave[0] != 'W' || wave[1] != 'A' || wave[2] != 'V' || wave[3] != 'E') {
-
file->close();
memdelete(file);
ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Not a WAV file (no WAVE RIFF header).");
@@ -141,7 +134,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
Vector<float> data;
while (!file->eof_reached()) {
-
/* chunk */
char chunkID[4];
file->get_buffer((uint8_t *)&chunkID, 4); //RIFF
@@ -151,7 +143,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
uint32_t file_pos = file->get_position(); //save file pos, so we can skip to next chunk safely
if (file->eof_reached()) {
-
//ERR_PRINT("EOF REACH");
break;
}
@@ -242,7 +233,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
uint32_t s = 0;
for (int b = 0; b < (format_bits >> 3); b++) {
-
s |= ((uint32_t)file->get_8()) << (b * 8);
}
s <<= (32 - format_bits);
@@ -270,8 +260,9 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
* 22:38 06.07.2017 GMT
**/
- for (int i = 0; i < 10; i++)
+ for (int i = 0; i < 10; i++) {
file->get_32(); // i wish to know why should i do this... no doc!
+ }
// only read 0x00 (loop forward), 0x01 (loop ping-pong) and 0x02 (loop backward)
// Skip anything else because it's not supported, reserved for future uses or sampler specific
@@ -322,12 +313,10 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
Vector<float> new_data;
new_data.resize(new_data_frames * format_channels);
for (int c = 0; c < format_channels; c++) {
-
float frac = .0f;
int ipos = 0;
for (int i = 0; i < new_data_frames; i++) {
-
//simple cubic interpolation should be enough.
float mu = frac;
@@ -370,20 +359,17 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
bool normalize = p_options["edit/normalize"];
if (normalize) {
-
float max = 0;
for (int i = 0; i < data.size(); i++) {
-
float amp = Math::abs(data[i]);
- if (amp > max)
+ if (amp > max) {
max = amp;
+ }
}
if (max > 0) {
-
float mult = 1.0 / max;
for (int i = 0; i < data.size(); i++) {
-
data.write[i] *= mult;
}
}
@@ -392,7 +378,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
bool trim = p_options["edit/trim"];
if (trim && !loop && format_channels > 0) {
-
int first = 0;
int last = (frames / format_channels) - 1;
bool found = false;
@@ -420,7 +405,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
Vector<float> new_data;
new_data.resize((last - first) * format_channels);
for (int i = first; i < last; i++) {
-
float fadeOutMult = 1;
if (last - i < TRIM_FADE_OUT_FRAMES) {
@@ -440,7 +424,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
bool make_loop = p_options["edit/loop"];
if (make_loop && !loop) {
-
loop = AudioStreamSample::LOOP_FORWARD;
loop_begin = 0;
loop_end = frames;
@@ -450,7 +433,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
bool force_mono = p_options["force/mono"];
if (force_mono && format_channels == 2) {
-
Vector<float> new_data;
new_data.resize(data.size() / 2);
for (int i = 0; i < frames; i++) {
@@ -463,7 +445,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
bool force_8_bit = p_options["force/8_bit"];
if (force_8_bit) {
-
is16 = false;
}
@@ -471,12 +452,10 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
AudioStreamSample::Format dst_format;
if (compression == 1) {
-
dst_format = AudioStreamSample::FORMAT_IMA_ADPCM;
if (format_channels == 1) {
_compress_ima_adpcm(data, dst_data);
} else {
-
//byte interleave
Vector<float> left;
Vector<float> right;
@@ -510,7 +489,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
}
} else {
-
dst_format = is16 ? AudioStreamSample::FORMAT_16_BITS : AudioStreamSample::FORMAT_8_BITS;
dst_data.resize(data.size() * (is16 ? 2 : 1));
{
@@ -518,7 +496,6 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
int ds = data.size();
for (int i = 0; i < ds; i++) {
-
if (is16) {
int16_t v = CLAMP(data[i] * 32768, -32768, 32767);
encode_uint16(v, &w[i * 2]);
diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h
index bc2f023e6b..3ff3aea9f4 100644
--- a/editor/import/resource_importer_wav.h
+++ b/editor/import/resource_importer_wav.h
@@ -72,8 +72,9 @@ public:
int datalen = p_data.size();
int datamax = datalen;
- if (datalen & 1)
+ if (datalen & 1) {
datalen++;
+ }
dst_data.resize(datalen / 2 + 4);
uint8_t *w = dst_data.ptrw();
@@ -96,10 +97,9 @@ public:
uint8_t nibble;
int16_t xm_sample;
- if (i >= datamax)
+ if (i >= datamax) {
xm_sample = 0;
- else {
-
+ } else {
xm_sample = CLAMP(in[i] * 32767.0, -32768, 32767);
/*
if (xm_sample==32767 || xm_sample==-32768)
@@ -121,9 +121,7 @@ public:
}
mask = 4;
while (mask) {
-
if (diff >= step) {
-
nibble |= mask;
diff -= step;
vpdiff += step;
@@ -133,10 +131,11 @@ public:
mask >>= 1;
};
- if (nibble & 8)
+ if (nibble & 8) {
prev -= vpdiff;
- else
+ } else {
prev += vpdiff;
+ }
if (prev > 32767) {
//printf("%i,xms %i, prev %i,diff %i, vpdiff %i, clip up %i\n",i,xm_sample,prev,diff,vpdiff,prev);
@@ -147,10 +146,11 @@ public:
}
step_idx += _ima_adpcm_index_table[nibble];
- if (step_idx < 0)
+ if (step_idx < 0) {
step_idx = 0;
- else if (step_idx > 88)
+ } else if (step_idx > 88) {
step_idx = 88;
+ }
if (i & 1) {
*out |= nibble << 4;
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 22f6aedeaa..8ab2e0aef1 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -44,7 +44,6 @@ public:
bool checking;
bool _set(const StringName &p_name, const Variant &p_value) {
-
if (values.has(p_name)) {
values[p_name] = p_value;
if (checking) {
@@ -58,7 +57,6 @@ public:
}
bool _get(const StringName &p_name, Variant &r_ret) const {
-
if (values.has(p_name)) {
r_ret = values[p_name];
return true;
@@ -67,10 +65,10 @@ public:
return false;
}
void _get_property_list(List<PropertyInfo> *p_list) const {
-
for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- if (!importer->get_option_visibility(E->get().name, values))
+ if (!importer->get_option_visibility(E->get().name, values)) {
continue;
+ }
PropertyInfo pi = E->get();
if (checking) {
pi.usage |= PROPERTY_USAGE_CHECKABLE;
@@ -92,7 +90,6 @@ public:
};
void ImportDock::set_edit_path(const String &p_path) {
-
Ref<ConfigFile> config;
config.instance();
Error err = config->load(p_path + ".import");
@@ -140,7 +137,6 @@ void ImportDock::set_edit_path(const String &p_path) {
}
void ImportDock::_update_options(const Ref<ConfigFile> &p_config) {
-
List<ResourceImporter::ImportOption> options;
params->importer->get_import_options(&options);
@@ -150,7 +146,6 @@ void ImportDock::_update_options(const Ref<ConfigFile> &p_config) {
params->checked.clear();
for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
-
params->properties.push_back(E->get().option);
if (p_config.is_valid() && p_config->has_section_key("params", E->get().option.name)) {
params->values[E->get().option.name] = p_config->get_value("params", E->get().option.name);
@@ -164,14 +159,12 @@ void ImportDock::_update_options(const Ref<ConfigFile> &p_config) {
}
void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) {
-
clear();
// Use the value that is repeated the most.
Map<String, Dictionary> value_frequency;
for (int i = 0; i < p_paths.size(); i++) {
-
Ref<ConfigFile> config;
config.instance();
Error err = config->load(p_paths[i] + ".import");
@@ -189,7 +182,6 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) {
config->get_section_keys("params", &keys);
for (List<String>::Element *E = keys.front(); E; E = E->next()) {
-
if (!value_frequency.has(E->get())) {
value_frequency[E->get()] = Dictionary();
}
@@ -215,11 +207,9 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) {
params->checked.clear();
for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
-
params->properties.push_back(E->get().option);
if (value_frequency.has(E->get().option.name)) {
-
Dictionary d = value_frequency[E->get().option.name];
int freq = 0;
List<Variant> v;
@@ -309,7 +299,6 @@ void ImportDock::_importer_selected(int i_idx) {
}
void ImportDock::_preset_selected(int p_idx) {
-
int item_id = preset->get_popup()->get_item_id(p_idx);
switch (item_id) {
@@ -325,7 +314,6 @@ void ImportDock::_preset_selected(int p_idx) {
_update_preset_menu();
} break;
case ITEM_LOAD_DEFAULT: {
-
ERR_FAIL_COND(!ProjectSettings::get_singleton()->has_setting("importer_defaults/" + params->importer->get_importer_name()));
Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + params->importer->get_importer_name());
@@ -344,13 +332,11 @@ void ImportDock::_preset_selected(int p_idx) {
params->update();
} break;
case ITEM_CLEAR_DEFAULT: {
-
ProjectSettings::get_singleton()->set("importer_defaults/" + params->importer->get_importer_name(), Variant());
ProjectSettings::get_singleton()->save();
_update_preset_menu();
} break;
default: {
-
List<ResourceImporter::ImportOption> options;
params->importer->get_import_options(&options, p_idx);
@@ -370,7 +356,6 @@ void ImportDock::_preset_selected(int p_idx) {
}
void ImportDock::clear() {
-
imported->set_text("");
import->set_disabled(true);
import_as->clear();
@@ -383,28 +368,27 @@ void ImportDock::clear() {
}
static bool _find_owners(EditorFileSystemDirectory *efsd, const String &p_path) {
-
- if (!efsd)
+ if (!efsd) {
return false;
+ }
for (int i = 0; i < efsd->get_subdir_count(); i++) {
-
if (_find_owners(efsd->get_subdir(i), p_path)) {
return true;
}
}
for (int i = 0; i < efsd->get_file_count(); i++) {
-
Vector<String> deps = efsd->get_file_deps(i);
- if (deps.find(p_path) != -1)
+ if (deps.find(p_path) != -1) {
return true;
+ }
}
return false;
}
-void ImportDock::_reimport_attempt() {
+void ImportDock::_reimport_attempt() {
bool need_restart = false;
bool used_in_resources = false;
for (int i = 0; i < params->paths.size(); i++) {
@@ -432,7 +416,6 @@ void ImportDock::_reimport_attempt() {
}
void ImportDock::_reimport_and_restart() {
-
EditorNode::get_singleton()->save_all_scenes();
EditorResourcePreview::get_singleton()->stop(); //don't try to re-create previews after import
_reimport();
@@ -440,9 +423,7 @@ void ImportDock::_reimport_and_restart() {
}
void ImportDock::_reimport() {
-
for (int i = 0; i < params->paths.size(); i++) {
-
Ref<ConfigFile> config;
config.instance();
Error err = config->load(params->paths[i] + ".import");
@@ -460,7 +441,9 @@ void ImportDock::_reimport() {
} else {
//override entirely
config->set_value("remap", "importer", importer_name);
- config->erase_section("params");
+ if (config->has_section("params")) {
+ config->erase_section("params");
+ }
for (List<PropertyInfo>::Element *E = params->properties.front(); E; E = E->next()) {
config->set_value("params", E->get().name, params->values[E->get().name]);
@@ -489,14 +472,11 @@ void ImportDock::_reimport() {
void ImportDock::_notification(int p_what) {
switch (p_what) {
-
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
-
imported->add_theme_style_override("normal", get_theme_stylebox("normal", "LineEdit"));
} break;
case NOTIFICATION_ENTER_TREE: {
-
import_opts->edit(params);
label_warning->add_theme_color_override("font_color", get_theme_color("warning_color", "Editor"));
} break;
@@ -510,20 +490,18 @@ void ImportDock::_property_toggled(const StringName &p_prop, bool p_checked) {
params->checked.erase(p_prop);
}
}
-void ImportDock::_bind_methods() {
+void ImportDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_reimport"), &ImportDock::_reimport);
}
void ImportDock::initialize_import_options() const {
-
ERR_FAIL_COND(!import_opts || !params);
import_opts->edit(params);
}
ImportDock::ImportDock() {
-
set_name("Import");
imported = memnew(Label);
imported->add_theme_style_override("normal", EditorNode::get_singleton()->get_gui_base()->get_theme_stylebox("normal", "LineEdit"));
@@ -572,6 +550,5 @@ ImportDock::ImportDock() {
}
ImportDock::~ImportDock() {
-
memdelete(params);
}
diff --git a/editor/inspector_dock.cpp b/editor/inspector_dock.cpp
index 3715547bdc..2b26851140 100644
--- a/editor/inspector_dock.cpp
+++ b/editor/inspector_dock.cpp
@@ -68,14 +68,16 @@ void InspectorDock::_menu_option(int p_option) {
case OBJECT_COPY_PARAMS: {
editor_data->apply_changes_in_editors();
- if (current)
+ if (current) {
editor_data->copy_object_params(current);
+ }
} break;
case OBJECT_PASTE_PARAMS: {
editor_data->apply_changes_in_editors();
- if (current)
+ if (current) {
editor_data->paste_object_params(current);
+ }
} break;
case OBJECT_UNIQUE_RESOURCES: {
@@ -85,18 +87,16 @@ void InspectorDock::_menu_option(int p_option) {
current->get_property_list(&props);
Map<RES, RES> duplicates;
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
Variant v = current->get(E->get().name);
if (v.is_ref()) {
REF ref = v;
if (ref.is_valid()) {
-
RES res = ref;
if (res.is_valid()) {
-
if (!duplicates.has(res)) {
duplicates[res] = res->duplicate();
}
@@ -172,10 +172,11 @@ void InspectorDock::_save_resource(bool save_as) const {
RES current_res = RES(Object::cast_to<Resource>(current_obj));
- if (save_as)
+ if (save_as) {
editor->save_resource_as(current_res);
- else
+ } else {
editor->save_resource(current_res);
+ }
}
void InspectorDock::_unref_resource() const {
@@ -217,7 +218,6 @@ void InspectorDock::_prepare_history() {
Ref<Texture2D> base_icon = get_theme_icon("Object", "EditorIcons");
Set<ObjectID> already;
for (int i = editor_history->get_history_len() - 1; i >= history_to; i--) {
-
ObjectID id = editor_history->get_history_obj(i);
Object *obj = ObjectDB::get_instance(id);
if (!obj || already.has(id)) {
@@ -237,9 +237,9 @@ void InspectorDock::_prepare_history() {
String text;
if (Object::cast_to<Resource>(obj)) {
Resource *r = Object::cast_to<Resource>(obj);
- if (r->get_path().is_resource_file())
+ if (r->get_path().is_resource_file()) {
text = r->get_path().get_file();
- else if (r->get_name() != String()) {
+ } else if (r->get_name() != String()) {
text = r->get_name();
} else {
text = r->get_class();
@@ -263,8 +263,9 @@ void InspectorDock::_select_history(int p_idx) {
//push it to the top, it is not correct, but it's more useful
ObjectID id = EditorNode::get_singleton()->get_editor_history()->get_history_obj(p_idx);
Object *obj = ObjectDB::get_instance(id);
- if (!obj)
+ if (!obj) {
return;
+ }
editor->push_item(obj);
}
@@ -280,21 +281,25 @@ void InspectorDock::_resource_created() {
}
void InspectorDock::_resource_selected(const RES &p_res, const String &p_property) {
- if (p_res.is_null())
+ if (p_res.is_null()) {
return;
+ }
RES r = p_res;
editor->push_item(r.operator->(), p_property);
}
void InspectorDock::_edit_forward() {
- if (EditorNode::get_singleton()->get_editor_history()->next())
+ if (EditorNode::get_singleton()->get_editor_history()->next()) {
editor->edit_current();
+ }
}
+
void InspectorDock::_edit_back() {
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history();
- if ((current && editor_history->previous()) || editor_history->get_path_size() == 1)
+ if ((current && editor_history->previous()) || editor_history->get_path_size() == 1) {
editor->edit_current();
+ }
}
void InspectorDock::_menu_collapseall() {
@@ -311,8 +316,9 @@ void InspectorDock::_property_keyed(const String &p_keyed, const Variant &p_valu
void InspectorDock::_transform_keyed(Object *sp, const String &p_sub, const Transform &p_key) {
Node3D *s = Object::cast_to<Node3D>(sp);
- if (!s)
+ if (!s) {
return;
+ }
AnimationPlayerEditor::singleton->get_track_editor()->insert_transform_key(s, p_sub, p_key);
}
@@ -342,7 +348,6 @@ void InspectorDock::_notification(int p_what) {
}
void InspectorDock::_bind_methods() {
-
ClassDB::bind_method("update_keying", &InspectorDock::update_keying);
ClassDB::bind_method("_transform_keyed", &InspectorDock::_transform_keyed); // Still used by some connect_compat.
@@ -376,7 +381,6 @@ void InspectorDock::clear() {
}
void InspectorDock::update(Object *p_object) {
-
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history();
backward_button->set_disabled(editor_history->is_at_beginning());
forward_button->set_disabled(editor_history->is_at_end());
@@ -442,12 +446,10 @@ void InspectorDock::update(Object *p_object) {
p_object->get_method_list(&methods);
if (!methods.empty()) {
-
bool found = false;
List<MethodInfo>::Element *I = methods.front();
int i = 0;
while (I) {
-
if (I->get().flags & METHOD_FLAG_EDITOR) {
if (!found) {
p->add_separator();
@@ -469,13 +471,10 @@ void InspectorDock::update_keying() {
bool valid = false;
if (AnimationPlayerEditor::singleton->get_track_editor()->has_keying()) {
-
EditorHistory *editor_history = EditorNode::get_singleton()->get_editor_history();
if (editor_history->get_path_size() >= 1) {
-
Object *obj = ObjectDB::get_instance(editor_history->get_path_object(0));
if (Object::cast_to<Node>(obj)) {
-
valid = true;
}
}
diff --git a/editor/inspector_dock.h b/editor/inspector_dock.h
index 61b3239169..2a99a7db45 100644
--- a/editor/inspector_dock.h
+++ b/editor/inspector_dock.h
@@ -47,7 +47,6 @@
class EditorNode;
class InspectorDock : public VBoxContainer {
-
GDCLASS(InspectorDock, VBoxContainer);
enum MenuOptions {
diff --git a/editor/multi_node_edit.cpp b/editor/multi_node_edit.cpp
index 7bc67b54c1..1077aca7b3 100644
--- a/editor/multi_node_edit.cpp
+++ b/editor/multi_node_edit.cpp
@@ -39,8 +39,9 @@ bool MultiNodeEdit::_set(const StringName &p_name, const Variant &p_value) {
bool MultiNodeEdit::_set_impl(const StringName &p_name, const Variant &p_value, const String &p_field) {
Node *es = EditorNode::get_singleton()->get_edited_scene();
- if (!es)
+ if (!es) {
return false;
+ }
String name = p_name;
@@ -52,13 +53,14 @@ bool MultiNodeEdit::_set_impl(const StringName &p_name, const Variant &p_value,
ur->create_action(TTR("MultiNode Set") + " " + String(name), UndoRedo::MERGE_ENDS);
for (const List<NodePath>::Element *E = nodes.front(); E; E = E->next()) {
-
- if (!es->has_node(E->get()))
+ if (!es->has_node(E->get())) {
continue;
+ }
Node *n = es->get_node(E->get());
- if (!n)
+ if (!n) {
continue;
+ }
if (p_value.get_type() == Variant::NODE_PATH) {
Node *tonode = n->get_node(p_value);
@@ -87,8 +89,9 @@ bool MultiNodeEdit::_set_impl(const StringName &p_name, const Variant &p_value,
bool MultiNodeEdit::_get(const StringName &p_name, Variant &r_ret) const {
Node *es = EditorNode::get_singleton()->get_edited_scene();
- if (!es)
+ if (!es) {
return false;
+ }
String name = p_name;
if (name == "scripts") { // script set is intercepted at object level (check Variant Object::get() ) ,so use a different name
@@ -96,18 +99,20 @@ bool MultiNodeEdit::_get(const StringName &p_name, Variant &r_ret) const {
}
for (const List<NodePath>::Element *E = nodes.front(); E; E = E->next()) {
-
- if (!es->has_node(E->get()))
+ if (!es->has_node(E->get())) {
continue;
+ }
const Node *n = es->get_node(E->get());
- if (!n)
+ if (!n) {
continue;
+ }
bool found;
r_ret = n->get(name, &found);
- if (found)
+ if (found) {
return true;
+ }
}
return false;
@@ -117,29 +122,31 @@ void MultiNodeEdit::_get_property_list(List<PropertyInfo> *p_list) const {
HashMap<String, PLData> usage;
Node *es = EditorNode::get_singleton()->get_edited_scene();
- if (!es)
+ if (!es) {
return;
+ }
int nc = 0;
List<PLData *> data_list;
for (const List<NodePath>::Element *E = nodes.front(); E; E = E->next()) {
-
- if (!es->has_node(E->get()))
+ if (!es->has_node(E->get())) {
continue;
+ }
Node *n = es->get_node(E->get());
- if (!n)
+ if (!n) {
continue;
+ }
List<PropertyInfo> plist;
n->get_property_list(&plist, true);
for (List<PropertyInfo>::Element *F = plist.front(); F; F = F->next()) {
-
- if (F->get().name == "script")
+ if (F->get().name == "script") {
continue; //added later manually, since this is intercepted before being set (check Variant Object::get() )
+ }
if (!usage.has(F->get().name)) {
PLData pld;
pld.uses = 0;
@@ -149,15 +156,15 @@ void MultiNodeEdit::_get_property_list(List<PropertyInfo> *p_list) const {
}
// Make sure only properties with the same exact PropertyInfo data will appear
- if (usage[F->get().name].info == F->get())
+ if (usage[F->get().name].info == F->get()) {
usage[F->get().name].uses++;
+ }
}
nc++;
}
for (List<PLData *>::Element *E = data_list.front(); E; E = E->next()) {
-
if (nc == E->get()->uses) {
p_list->push_back(E->get()->info);
}
diff --git a/editor/multi_node_edit.h b/editor/multi_node_edit.h
index d3eefafcec..694dad76f1 100644
--- a/editor/multi_node_edit.h
+++ b/editor/multi_node_edit.h
@@ -34,7 +34,6 @@
#include "scene/main/node.h"
class MultiNodeEdit : public Reference {
-
GDCLASS(MultiNodeEdit, Reference);
List<NodePath> nodes;
diff --git a/editor/node_3d_editor_gizmos.cpp b/editor/node_3d_editor_gizmos.cpp
index 724782ac44..0eb4e6036a 100644
--- a/editor/node_3d_editor_gizmos.cpp
+++ b/editor/node_3d_editor_gizmos.cpp
@@ -41,6 +41,7 @@
#include "scene/3d/gi_probe.h"
#include "scene/3d/gpu_particles_3d.h"
#include "scene/3d/light_3d.h"
+#include "scene/3d/lightmap_probe.h"
#include "scene/3d/listener_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/navigation_region_3d.h"
@@ -68,26 +69,27 @@
#define HANDLE_HALF_SIZE 9.5
bool EditorNode3DGizmo::is_editable() const {
-
ERR_FAIL_COND_V(!spatial_node, false);
Node *edited_root = spatial_node->get_tree()->get_edited_scene_root();
- if (spatial_node == edited_root)
+ if (spatial_node == edited_root) {
return true;
- if (spatial_node->get_owner() == edited_root)
+ }
+ if (spatial_node->get_owner() == edited_root) {
return true;
+ }
- if (edited_root->is_editable_instance(spatial_node->get_owner()))
+ if (edited_root->is_editable_instance(spatial_node->get_owner())) {
return true;
+ }
return false;
}
void EditorNode3DGizmo::clear() {
-
for (int i = 0; i < instances.size(); i++) {
-
- if (instances[i].instance.is_valid())
+ if (instances[i].instance.is_valid()) {
RS::get_singleton()->free(instances[i].instance);
+ }
}
billboard_handle = false;
@@ -99,7 +101,6 @@ void EditorNode3DGizmo::clear() {
}
void EditorNode3DGizmo::redraw() {
-
if (get_script_instance() && get_script_instance()->has_method("redraw")) {
get_script_instance()->call("redraw");
return;
@@ -110,7 +111,6 @@ void EditorNode3DGizmo::redraw() {
}
String EditorNode3DGizmo::get_handle_name(int p_idx) const {
-
if (get_script_instance() && get_script_instance()->has_method("get_handle_name")) {
return get_script_instance()->call("get_handle_name", p_idx);
}
@@ -120,7 +120,6 @@ String EditorNode3DGizmo::get_handle_name(int p_idx) const {
}
bool EditorNode3DGizmo::is_handle_highlighted(int p_idx) const {
-
if (get_script_instance() && get_script_instance()->has_method("is_handle_highlighted")) {
return get_script_instance()->call("is_handle_highlighted", p_idx);
}
@@ -130,7 +129,6 @@ bool EditorNode3DGizmo::is_handle_highlighted(int p_idx) const {
}
Variant EditorNode3DGizmo::get_handle_value(int p_idx) {
-
if (get_script_instance() && get_script_instance()->has_method("get_handle_value")) {
return get_script_instance()->call("get_handle_value", p_idx);
}
@@ -140,7 +138,6 @@ Variant EditorNode3DGizmo::get_handle_value(int p_idx) {
}
void EditorNode3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_point) {
-
if (get_script_instance() && get_script_instance()->has_method("set_handle")) {
get_script_instance()->call("set_handle", p_idx, p_camera, p_point);
return;
@@ -151,7 +148,6 @@ void EditorNode3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &
}
void EditorNode3DGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
-
if (get_script_instance() && get_script_instance()->has_method("commit_handle")) {
get_script_instance()->call("commit_handle", p_idx, p_restore, p_cancel);
return;
@@ -162,27 +158,25 @@ void EditorNode3DGizmo::commit_handle(int p_idx, const Variant &p_restore, bool
}
void EditorNode3DGizmo::set_spatial_node(Node3D *p_node) {
-
ERR_FAIL_NULL(p_node);
spatial_node = p_node;
}
void EditorNode3DGizmo::Instance::create_instance(Node3D *p_base, bool p_hidden) {
-
- instance = RS::get_singleton()->instance_create2(mesh->get_rid(), p_base->get_world()->get_scenario());
+ instance = RS::get_singleton()->instance_create2(mesh->get_rid(), p_base->get_world_3d()->get_scenario());
RS::get_singleton()->instance_attach_object_instance_id(instance, p_base->get_instance_id());
if (skin_reference.is_valid()) {
RS::get_singleton()->instance_attach_skeleton(instance, skin_reference->get_skeleton());
}
- if (extra_margin)
+ if (extra_margin) {
RS::get_singleton()->instance_set_extra_visibility_margin(instance, 1);
+ }
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(instance, RS::SHADOW_CASTING_SETTING_OFF);
int layer = p_hidden ? 0 : 1 << Node3DEditorViewport::GIZMO_EDIT_LAYER;
RS::get_singleton()->instance_set_layer_mask(instance, layer); //gizmos are 26
}
void EditorNode3DGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard, const Ref<SkinReference> &p_skin_reference, const Ref<Material> &p_material) {
-
ERR_FAIL_COND(!spatial_node);
Instance ins;
@@ -220,10 +214,11 @@ void EditorNode3DGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Mate
{
Color *w = color.ptrw();
for (int i = 0; i < p_lines.size(); i++) {
- if (is_selected())
+ if (is_selected()) {
w[i] = Color(1, 1, 1, 0.8) * p_modulate;
- else
+ } else {
w[i] = Color(1, 1, 1, 0.2) * p_modulate;
+ }
}
}
@@ -235,7 +230,6 @@ void EditorNode3DGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Mate
if (p_billboard) {
float md = 0;
for (int i = 0; i < p_lines.size(); i++) {
-
md = MAX(0, p_lines[i].length());
}
if (md) {
@@ -254,7 +248,6 @@ void EditorNode3DGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Mate
}
void EditorNode3DGizmo::add_unscaled_billboard(const Ref<Material> &p_material, float p_scale, const Color &p_modulate) {
-
ERR_FAIL_COND(!spatial_node);
Instance ins;
@@ -296,7 +289,6 @@ void EditorNode3DGizmo::add_unscaled_billboard(const Ref<Material> &p_material,
float md = 0;
for (int i = 0; i < vs.size(); i++) {
-
md = MAX(0, vs[i].length());
}
if (md) {
@@ -324,21 +316,19 @@ void EditorNode3DGizmo::add_collision_triangles(const Ref<TriangleMesh> &p_tmesh
}
void EditorNode3DGizmo::add_collision_segments(const Vector<Vector3> &p_lines) {
-
int from = collision_segments.size();
collision_segments.resize(from + p_lines.size());
for (int i = 0; i < p_lines.size(); i++) {
-
collision_segments.write[from + i] = p_lines[i];
}
}
void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<Material> &p_material, bool p_billboard, bool p_secondary) {
-
billboard_handle = p_billboard;
- if (!is_selected() || !is_editable())
+ if (!is_selected() || !is_editable()) {
return;
+ }
ERR_FAIL_COND(!spatial_node);
@@ -354,13 +344,14 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<
colors.resize(p_handles.size());
Color *w = colors.ptrw();
for (int i = 0; i < p_handles.size(); i++) {
-
Color col(1, 1, 1, 1);
- if (is_handle_highlighted(i))
+ if (is_handle_highlighted(i)) {
col = Color(0, 0, 1, 0.9);
+ }
- if (Node3DEditor::get_singleton()->get_over_gizmo_handle() != i)
+ if (Node3DEditor::get_singleton()->get_over_gizmo_handle() != i) {
col.a = 0.8;
+ }
w[i] = col;
}
@@ -372,7 +363,6 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<
if (p_billboard) {
float md = 0;
for (int i = 0; i < p_handles.size(); i++) {
-
md = MAX(0, p_handles[i].length());
}
if (md) {
@@ -395,7 +385,6 @@ void EditorNode3DGizmo::add_handles(const Vector<Vector3> &p_handles, const Ref<
handles.write[i + chs] = p_handles[i];
}
} else {
-
int chs = secondary_handles.size();
secondary_handles.resize(chs + p_handles.size());
for (int i = 0; i < p_handles.size(); i++) {
@@ -427,11 +416,12 @@ void EditorNode3DGizmo::add_solid_box(Ref<Material> &p_material, Vector3 p_size,
}
bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum) {
-
ERR_FAIL_COND_V(!spatial_node, false);
ERR_FAIL_COND_V(!valid, false);
- if (hidden && !gizmo_plugin->is_selectable_when_hidden()) return false;
+ if (hidden && !gizmo_plugin->is_selectable_when_hidden()) {
+ return false;
+ }
if (selectable_icon_size > 0.0f) {
Vector3 origin = spatial_node->get_global_transform().get_origin();
@@ -442,7 +432,6 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector
bool any_out = false;
for (int j = 0; j < fc; j++) {
-
if (p[j].is_point_over(origin)) {
any_out = true;
break;
@@ -453,7 +442,6 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector
}
if (collision_segments.size()) {
-
const Plane *p = p_frustum.ptr();
int fc = p_frustum.size();
@@ -470,10 +458,14 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector
break;
}
}
- if (any_out) break;
+ if (any_out) {
+ break;
+ }
}
- if (!any_out) return true;
+ if (!any_out) {
+ return true;
+ }
}
if (collision_mesh.is_valid()) {
@@ -486,11 +478,12 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector
Vector<Plane> transformed_frustum;
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < p_frustum.size(); i++) {
transformed_frustum.push_back(it.xform(p_frustum[i]));
}
- if (collision_mesh->inside_convex_shape(transformed_frustum.ptr(), transformed_frustum.size(), mesh_scale)) {
+ Vector<Vector3> convex_points = Geometry::compute_convex_mesh_points(p_frustum.ptr(), p_frustum.size());
+ if (collision_mesh->inside_convex_shape(transformed_frustum.ptr(), transformed_frustum.size(), convex_points.ptr(), convex_points.size(), mesh_scale)) {
return true;
}
}
@@ -499,14 +492,14 @@ bool EditorNode3DGizmo::intersect_frustum(const Camera3D *p_camera, const Vector
}
bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle, bool p_sec_first) {
-
ERR_FAIL_COND_V(!spatial_node, false);
ERR_FAIL_COND_V(!valid, false);
- if (hidden && !gizmo_plugin->is_selectable_when_hidden()) return false;
+ if (hidden && !gizmo_plugin->is_selectable_when_hidden()) {
+ return false;
+ }
if (r_gizmo_handle && !hidden) {
-
Transform t = spatial_node->get_global_transform();
if (billboard_handle) {
t.set_look_at(t.origin, t.origin - p_camera->get_transform().basis.get_axis(2), p_camera->get_transform().basis.get_axis(1));
@@ -516,15 +509,12 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
int idx = -1;
for (int i = 0; i < secondary_handles.size(); i++) {
-
Vector3 hpos = t.xform(secondary_handles[i]);
Vector2 p = p_camera->unproject_position(hpos);
if (p.distance_to(p_point) < HANDLE_HALF_SIZE) {
-
real_t dp = p_camera->get_transform().origin.distance_to(hpos);
if (dp < min_d) {
-
r_pos = t.xform(hpos);
r_normal = p_camera->get_transform().basis.get_axis(2);
min_d = dp;
@@ -534,7 +524,6 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
}
if (p_sec_first && idx != -1) {
-
*r_gizmo_handle = idx;
return true;
}
@@ -542,15 +531,12 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
min_d = 1e20;
for (int i = 0; i < handles.size(); i++) {
-
Vector3 hpos = t.xform(handles[i]);
Vector2 p = p_camera->unproject_position(hpos);
if (p.distance_to(p_point) < HANDLE_HALF_SIZE) {
-
real_t dp = p_camera->get_transform().origin.distance_to(hpos);
if (dp < min_d) {
-
r_pos = t.xform(hpos);
r_normal = p_camera->get_transform().basis.get_axis(2);
min_d = dp;
@@ -566,7 +552,6 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
}
if (selectable_icon_size > 0.0f) {
-
Transform t = spatial_node->get_global_transform();
Vector3 camera_position = p_camera->get_camera_transform().origin;
if (camera_position.distance_squared_to(t.origin) > 0.01) {
@@ -612,7 +597,6 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
}
if (collision_segments.size()) {
-
Plane camp(p_camera->get_transform().origin, (-p_camera->get_transform().basis.get_axis(2)).normalized());
int vc = collision_segments.size();
@@ -626,7 +610,6 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
float cpd = 1e20;
for (int i = 0; i < vc / 2; i++) {
-
Vector3 a = t.xform(vptr[i * 2 + 0]);
Vector3 b = t.xform(vptr[i * 2 + 1]);
Vector2 s[2];
@@ -638,11 +621,9 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
float pd = p.distance_to(p_point);
if (pd < cpd) {
-
float d = s[0].distance_to(s[1]);
Vector3 tcp;
if (d > 0) {
-
float d2 = s[0].distance_to(p) / d;
tcp = a + (b - a) * d2;
@@ -650,15 +631,15 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
tcp = a;
}
- if (camp.distance_to(tcp) < p_camera->get_znear())
+ if (camp.distance_to(tcp) < p_camera->get_znear()) {
continue;
+ }
cp = tcp;
cpd = pd;
}
}
if (cpd < 8) {
-
r_pos = cp;
r_normal = -p_camera->project_ray_normal(p_point);
return true;
@@ -680,7 +661,6 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
Vector3 rpos, rnorm;
if (collision_mesh->intersect_ray(ray_from, ray_dir, rpos, rnorm)) {
-
r_pos = gt.xform(rpos);
r_normal = gt.basis.xform(rnorm).normalized();
return true;
@@ -691,13 +671,11 @@ bool EditorNode3DGizmo::intersect_ray(Camera3D *p_camera, const Point2 &p_point,
}
void EditorNode3DGizmo::create() {
-
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(valid);
valid = true;
for (int i = 0; i < instances.size(); i++) {
-
instances.write[i].create_instance(spatial_node, hidden);
}
@@ -705,7 +683,6 @@ void EditorNode3DGizmo::create() {
}
void EditorNode3DGizmo::transform() {
-
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(!valid);
for (int i = 0; i < instances.size(); i++) {
@@ -714,14 +691,13 @@ void EditorNode3DGizmo::transform() {
}
void EditorNode3DGizmo::free() {
-
ERR_FAIL_COND(!spatial_node);
ERR_FAIL_COND(!valid);
for (int i = 0; i < instances.size(); i++) {
-
- if (instances[i].instance.is_valid())
+ if (instances[i].instance.is_valid()) {
RS::get_singleton()->free(instances[i].instance);
+ }
instances.write[i].instance = RID();
}
@@ -743,7 +719,6 @@ void EditorNode3DGizmo::set_plugin(EditorNode3DGizmoPlugin *p_plugin) {
}
void EditorNode3DGizmo::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_lines", "lines", "material", "billboard", "modulate"), &EditorNode3DGizmo::add_lines, DEFVAL(false), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("add_mesh", "mesh", "billboard", "skeleton", "material"), &EditorNode3DGizmo::add_mesh, DEFVAL(false), DEFVAL(Ref<SkinReference>()), DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("add_collision_segments", "segments"), &EditorNode3DGizmo::add_collision_segments);
@@ -783,13 +758,13 @@ EditorNode3DGizmo::EditorNode3DGizmo() {
}
EditorNode3DGizmo::~EditorNode3DGizmo() {
-
- if (gizmo_plugin != nullptr) gizmo_plugin->unregister_gizmo(this);
+ if (gizmo_plugin != nullptr) {
+ gizmo_plugin->unregister_gizmo(this);
+ }
clear();
}
Vector3 EditorNode3DGizmo::get_handle_pos(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, handles.size(), Vector3());
return handles[p_idx];
@@ -798,7 +773,6 @@ Vector3 EditorNode3DGizmo::get_handle_pos(int p_idx) const {
//// light gizmo
Light3DGizmoPlugin::Light3DGizmoPlugin() {
-
// Enable vertex colors for the materials below as the gizmo color depends on the light color.
create_material("lines_primary", Color(1, 1, 1), false, false, true);
create_material("lines_secondary", Color(1, 1, 1, 0.35), false, false, true);
@@ -825,33 +799,32 @@ int Light3DGizmoPlugin::get_priority() const {
}
String Light3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
- if (p_idx == 0)
+ if (p_idx == 0) {
return "Radius";
- else
+ } else {
return "Aperture";
+ }
}
Variant Light3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node());
- if (p_idx == 0)
+ if (p_idx == 0) {
return light->get_param(Light3D::PARAM_RANGE);
- if (p_idx == 1)
+ }
+ if (p_idx == 1) {
return light->get_param(Light3D::PARAM_SPOT_ANGLE);
+ }
return Variant();
}
static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vector3 &p_to, float p_arc_radius, const Transform &p_arc_xform) {
-
//bleh, discrete is simpler
static const int arc_test_points = 64;
float min_d = 1e20;
Vector3 min_p;
for (int i = 0; i < arc_test_points; i++) {
-
float a = i * Math_PI * 0.5 / arc_test_points;
float an = (i + 1) * Math_PI * 0.5 / arc_test_points;
Vector3 p = Vector3(Math::cos(a), 0, -Math::sin(a)) * p_arc_radius;
@@ -873,7 +846,6 @@ static float _find_closest_angle_to_half_pi_arc(const Vector3 &p_from, const Vec
}
void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
-
Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node());
Transform gt = light->get_global_transform();
Transform gi = gt.affine_inverse();
@@ -883,7 +855,6 @@ void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer
Vector3 s[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
if (p_idx == 0) {
-
if (Object::cast_to<SpotLight3D>(light)) {
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), Vector3(0, 0, -4096), s[0], s[1], ra, rb);
@@ -893,17 +864,16 @@ void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d <= 0) // Equal is here for negative zero.
+ if (d <= 0) { // Equal is here for negative zero.
d = 0;
+ }
light->set_param(Light3D::PARAM_RANGE, d);
} else if (Object::cast_to<OmniLight3D>(light)) {
-
Plane cp = Plane(gt.origin, p_camera->get_transform().basis.get_axis(2));
Vector3 inters;
if (cp.intersects_ray(ray_from, ray_dir, &inters)) {
-
float r = inters.distance_to(gt.origin);
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
r = Math::stepify(r, Node3DEditor::get_singleton()->get_translate_snap());
@@ -914,28 +884,23 @@ void Light3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer
}
} else if (p_idx == 1) {
-
float a = _find_closest_angle_to_half_pi_arc(s[0], s[1], light->get_param(Light3D::PARAM_RANGE), gt);
light->set_param(Light3D::PARAM_SPOT_ANGLE, CLAMP(a, 0.01, 89.99));
}
}
void Light3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
-
Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
-
light->set_param(p_idx == 0 ? Light3D::PARAM_RANGE : Light3D::PARAM_SPOT_ANGLE, p_restore);
} else if (p_idx == 0) {
-
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
ur->create_action(TTR("Change Light Radius"));
ur->add_do_method(light, "set_param", Light3D::PARAM_RANGE, light->get_param(Light3D::PARAM_RANGE));
ur->add_undo_method(light, "set_param", Light3D::PARAM_RANGE, p_restore);
ur->commit_action();
} else if (p_idx == 1) {
-
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
ur->create_action(TTR("Change Light Radius"));
ur->add_do_method(light, "set_param", Light3D::PARAM_SPOT_ANGLE, light->get_param(Light3D::PARAM_SPOT_ANGLE));
@@ -945,7 +910,6 @@ void Light3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, co
}
void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
Light3D *light = Object::cast_to<Light3D>(p_gizmo->get_spatial_node());
Color color = light->get_color();
@@ -955,7 +919,6 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->clear();
if (Object::cast_to<DirectionalLight3D>(light)) {
-
Ref<Material> material = get_material("lines_primary", p_gizmo);
Ref<Material> icon = get_material("light_directional_icon", p_gizmo);
@@ -993,7 +956,6 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
if (Object::cast_to<OmniLight3D>(light)) {
-
// Use both a billboard circle and 3 non-billboard circles for a better sphere-like representation
const Ref<Material> lines_material = get_material("lines_secondary", p_gizmo);
const Ref<Material> lines_billboard_material = get_material("lines_billboard", p_gizmo);
@@ -1005,7 +967,6 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> points_billboard;
for (int i = 0; i < 120; i++) {
-
// Create a circle
const float ra = Math::deg2rad((float)(i * 3));
const float rb = Math::deg2rad((float)((i + 1) * 3));
@@ -1035,7 +996,6 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
if (Object::cast_to<SpotLight3D>(light)) {
-
const Ref<Material> material_primary = get_material("lines_primary", p_gizmo);
const Ref<Material> material_secondary = get_material("lines_secondary", p_gizmo);
const Ref<Material> icon = get_material("light_spot_icon", p_gizmo);
@@ -1049,7 +1009,6 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
float d = r * Math::cos(Math::deg2rad(sl->get_param(Light3D::PARAM_SPOT_ANGLE)));
for (int i = 0; i < 120; i++) {
-
// Draw a circle
const float ra = Math::deg2rad((float)(i * 3));
const float rb = Math::deg2rad((float)((i + 1) * 3));
@@ -1088,7 +1047,6 @@ void Light3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
//// player gizmo
AudioStreamPlayer3DGizmoPlugin::AudioStreamPlayer3DGizmoPlugin() {
-
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/stream_player_3d", Color(0.4, 0.8, 1));
create_icon_material("stream_player_3d_icon", Node3DEditor::get_singleton()->get_theme_icon("Gizmo3DSamplePlayer", "EditorIcons"));
@@ -1110,7 +1068,6 @@ int AudioStreamPlayer3DGizmoPlugin::get_priority() const {
}
String AudioStreamPlayer3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
return "Emission Radius";
}
@@ -1120,7 +1077,6 @@ Variant AudioStreamPlayer3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gi
}
void AudioStreamPlayer3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
-
AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
Transform gt = player->get_global_transform();
@@ -1137,7 +1093,6 @@ void AudioStreamPlayer3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int
float closest_angle = 1e20;
for (int i = 0; i < 180; i++) {
-
float a = i * Math_PI / 180.0;
float an = (i + 1) * Math_PI / 180.0;
@@ -1159,15 +1114,12 @@ void AudioStreamPlayer3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int
}
void AudioStreamPlayer3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
-
AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
-
player->set_emission_angle(p_restore);
} else {
-
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
ur->create_action(TTR("Change AudioStreamPlayer3D Emission Angle"));
ur->add_do_method(player, "set_emission_angle", player->get_emission_angle());
@@ -1177,7 +1129,6 @@ void AudioStreamPlayer3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, i
}
void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
const AudioStreamPlayer3D *player = Object::cast_to<AudioStreamPlayer3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -1185,7 +1136,6 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
const Ref<Material> icon = get_material("stream_player_3d_icon", p_gizmo);
if (player->is_emission_angle_enabled()) {
-
const float pc = player->get_emission_angle();
const float ofs = -Math::cos(Math::deg2rad(pc));
const float radius = Math::sin(Math::deg2rad(pc));
@@ -1194,7 +1144,6 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
points_primary.resize(200);
for (int i = 0; i < 100; i++) {
-
const float a = i * 2.0 * Math_PI / 100.0;
const float an = (i + 1) * 2.0 * Math_PI / 100.0;
@@ -1212,7 +1161,6 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
points_secondary.resize(16);
for (int i = 0; i < 8; i++) {
-
const float a = i * 2.0 * Math_PI / 8.0;
const Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
@@ -1235,7 +1183,6 @@ void AudioStreamPlayer3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
//////
Camera3DGizmoPlugin::Camera3DGizmoPlugin() {
-
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/camera", Color(0.8, 0.4, 0.8));
create_material("camera_material", gizmo_color);
@@ -1255,7 +1202,6 @@ int Camera3DGizmoPlugin::get_priority() const {
}
String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node());
if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) {
@@ -1266,19 +1212,16 @@ String Camera3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, in
}
Variant Camera3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node());
if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) {
return camera->get_fov();
} else {
-
return camera->get_size();
}
}
void Camera3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
-
Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node());
Transform gt = camera->get_global_transform();
@@ -1294,7 +1237,6 @@ void Camera3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Came
float a = _find_closest_angle_to_half_pi_arc(s[0], s[1], 1.0, gt2);
camera->set("fov", CLAMP(a * 2.0, 1, 179));
} else {
-
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(0, 0, -1), Vector3(4096, 0, -1), s[0], s[1], ra, rb);
float d = ra.x * 2.0;
@@ -1309,13 +1251,10 @@ void Camera3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Came
}
void Camera3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
-
Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node());
if (camera->get_projection() == Camera3D::PROJECTION_PERSPECTIVE) {
-
if (p_cancel) {
-
camera->set("fov", p_restore);
} else {
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
@@ -1326,9 +1265,7 @@ void Camera3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, c
}
} else {
-
if (p_cancel) {
-
camera->set("size", p_restore);
} else {
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
@@ -1341,7 +1278,6 @@ void Camera3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, c
}
void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
Camera3D *camera = Object::cast_to<Camera3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -1374,9 +1310,7 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
switch (camera->get_projection()) {
-
case Camera3D::PROJECTION_PERSPECTIVE: {
-
// The real FOV is halved for accurate representation
float fov = camera->get_fov() / 2.0;
@@ -1398,7 +1332,6 @@ void Camera3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
} break;
case Camera3D::PROJECTION_ORTHOGONAL: {
-
float size = camera->get_size();
float hsize = size * 0.5;
@@ -1510,15 +1443,15 @@ bool MeshInstance3DGizmoPlugin::can_be_hidden() const {
}
void MeshInstance3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
MeshInstance3D *mesh = Object::cast_to<MeshInstance3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
Ref<Mesh> m = mesh->get_mesh();
- if (!m.is_valid())
+ if (!m.is_valid()) {
return; //none
+ }
Ref<TriangleMesh> tm = m->generate_triangle_mesh();
if (tm.is_valid()) {
@@ -1547,7 +1480,6 @@ bool Sprite3DGizmoPlugin::can_be_hidden() const {
}
void Sprite3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
Sprite3D *sprite = Object::cast_to<Sprite3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -1606,7 +1538,6 @@ int Position3DGizmoPlugin::get_priority() const {
}
void Position3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
p_gizmo->clear();
p_gizmo->add_mesh(pos3d_mesh);
p_gizmo->add_collision_segments(cursor_points);
@@ -1615,7 +1546,6 @@ void Position3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
/////
Skeleton3DGizmoPlugin::Skeleton3DGizmoPlugin() {
-
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/skeleton", Color(1, 0.8, 0.4));
create_material("skeleton_material", gizmo_color);
}
@@ -1633,7 +1563,6 @@ int Skeleton3DGizmoPlugin::get_priority() const {
}
void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
Skeleton3D *skel = Object::cast_to<Skeleton3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -1665,7 +1594,6 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Color rootcolor = Color(0.4, 1.0, 0.4, 0.1);
for (int i_bone = 0; i_bone < skel->get_bone_count(); i_bone++) {
-
int i = skel->get_process_order(i_bone);
int parent = skel->get_bone_parent(i);
@@ -1684,8 +1612,9 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
for (int j = 0; j < 3; j++) {
float dp = Math::abs(grests[parent].basis[j].normalized().dot(d));
- if (j == 0 || dp > closest_d)
+ if (j == 0 || dp > closest_d) {
closest = j;
+ }
}
//find closest other
@@ -1693,7 +1622,6 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector3 points[4];
int pointidx = 0;
for (int j = 0; j < 3; j++) {
-
bones.write[0] = parent;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
@@ -1704,8 +1632,9 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
surface_tool->add_color(rootcolor);
surface_tool->add_vertex(v0 + grests[parent].basis[j].normalized() * dist * 0.05);
- if (j == closest)
+ if (j == closest) {
continue;
+ }
Vector3 axis;
if (first == Vector3()) {
@@ -1716,9 +1645,9 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
for (int k = 0; k < 2; k++) {
-
- if (k == 1)
+ if (k == 1) {
axis = -axis;
+ }
Vector3 point = v0 + d * dist * 0.2;
point += axis * dist * 0.1;
@@ -1748,7 +1677,6 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
SWAP(points[1], points[2]);
for (int j = 0; j < 4; j++) {
-
bones.write[0] = parent;
surface_tool->add_bones(bones);
surface_tool->add_weights(weights);
@@ -1773,7 +1701,6 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
surface_tool->add_vertex(v1);
*/
} else {
-
grests.write[i] = skel->get_bone_rest(i);
bones.write[0] = i;
}
@@ -1840,35 +1767,36 @@ int PhysicalBone3DGizmoPlugin::get_priority() const {
}
void PhysicalBone3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
p_gizmo->clear();
PhysicalBone3D *physical_bone = Object::cast_to<PhysicalBone3D>(p_gizmo->get_spatial_node());
- if (!physical_bone)
+ if (!physical_bone) {
return;
+ }
Skeleton3D *sk(physical_bone->find_skeleton_parent());
- if (!sk)
+ if (!sk) {
return;
+ }
PhysicalBone3D *pb(sk->get_physical_bone(physical_bone->get_bone_id()));
- if (!pb)
+ if (!pb) {
return;
+ }
PhysicalBone3D *pbp(sk->get_physical_bone_parent(physical_bone->get_bone_id()));
- if (!pbp)
+ if (!pbp) {
return;
+ }
Vector<Vector3> points;
switch (physical_bone->get_joint_type()) {
case PhysicalBone3D::JOINT_TYPE_PIN: {
-
Joint3DGizmoPlugin::CreatePinJointGizmo(physical_bone->get_joint_offset(), points);
} break;
case PhysicalBone3D::JOINT_TYPE_CONE: {
-
const PhysicalBone3D::ConeJointData *cjd(static_cast<const PhysicalBone3D::ConeJointData *>(physical_bone->get_joint_data()));
Joint3DGizmoPlugin::CreateConeTwistJointGizmo(
physical_bone->get_joint_offset(),
@@ -1881,7 +1809,6 @@ void PhysicalBone3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
&points);
} break;
case PhysicalBone3D::JOINT_TYPE_HINGE: {
-
const PhysicalBone3D::HingeJointData *hjd(static_cast<const PhysicalBone3D::HingeJointData *>(physical_bone->get_joint_data()));
Joint3DGizmoPlugin::CreateHingeJointGizmo(
physical_bone->get_joint_offset(),
@@ -1896,7 +1823,6 @@ void PhysicalBone3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
&points);
} break;
case PhysicalBone3D::JOINT_TYPE_SLIDER: {
-
const PhysicalBone3D::SliderJointData *sjd(static_cast<const PhysicalBone3D::SliderJointData *>(physical_bone->get_joint_data()));
Joint3DGizmoPlugin::CreateSliderJointGizmo(
physical_bone->get_joint_offset(),
@@ -1912,7 +1838,6 @@ void PhysicalBone3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
&points);
} break;
case PhysicalBone3D::JOINT_TYPE_6DOF: {
-
const PhysicalBone3D::SixDOFJointData *sdofjd(static_cast<const PhysicalBone3D::SixDOFJointData *>(physical_bone->get_joint_data()));
Joint3DGizmoPlugin::CreateGeneric6DOFJointGizmo(
physical_bone->get_joint_offset(),
@@ -1959,7 +1884,6 @@ void PhysicalBone3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
/////
RayCast3DGizmoPlugin::RayCast3DGizmoPlugin() {
-
const Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
create_material("shape_material", gizmo_color);
const float gizmo_value = gizmo_color.get_v();
@@ -1980,7 +1904,6 @@ int RayCast3DGizmoPlugin::get_priority() const {
}
void RayCast3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
RayCast3D *raycast = Object::cast_to<RayCast3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -2000,7 +1923,6 @@ void RayCast3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
/////
void SpringArm3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
SpringArm3D *spring_arm = Object::cast_to<SpringArm3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -2036,7 +1958,6 @@ int SpringArm3DGizmoPlugin::get_priority() const {
/////
VehicleWheel3DGizmoPlugin::VehicleWheel3DGizmoPlugin() {
-
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/shape", Color(0.5, 0.7, 1));
create_material("shape_material", gizmo_color);
}
@@ -2054,7 +1975,6 @@ int VehicleWheel3DGizmoPlugin::get_priority() const {
}
void VehicleWheel3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
VehicleWheel3D *car_wheel = Object::cast_to<VehicleWheel3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -2064,7 +1984,6 @@ void VehicleWheel3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
float r = car_wheel->get_radius();
const int skip = 10;
for (int i = 0; i <= 360; i += skip) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + skip);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
@@ -2204,26 +2123,30 @@ int VisibilityNotifier3DGizmoPlugin::get_priority() const {
}
String VisibilityNotifier3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
switch (p_idx) {
- case 0: return "Size X";
- case 1: return "Size Y";
- case 2: return "Size Z";
- case 3: return "Pos X";
- case 4: return "Pos Y";
- case 5: return "Pos Z";
+ case 0:
+ return "Size X";
+ case 1:
+ return "Size Y";
+ case 2:
+ return "Size Z";
+ case 3:
+ return "Pos X";
+ case 4:
+ return "Pos Y";
+ case 5:
+ return "Pos Z";
}
return "";
}
Variant VisibilityNotifier3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
VisibilityNotifier3D *notifier = Object::cast_to<VisibilityNotifier3D>(p_gizmo->get_spatial_node());
return notifier->get_aabb();
}
-void VisibilityNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
+void VisibilityNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
VisibilityNotifier3D *notifier = Object::cast_to<VisibilityNotifier3D>(p_gizmo->get_spatial_node());
Transform gt = notifier->get_global_transform();
@@ -2245,7 +2168,6 @@ void VisibilityNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int
axis[p_idx] = 1.0;
if (move) {
-
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb);
@@ -2266,8 +2188,9 @@ void VisibilityNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
//resize
aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d;
aabb.size[p_idx] = d * 2;
@@ -2276,7 +2199,6 @@ void VisibilityNotifier3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int
}
void VisibilityNotifier3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
-
VisibilityNotifier3D *notifier = Object::cast_to<VisibilityNotifier3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
@@ -2292,7 +2214,6 @@ void VisibilityNotifier3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo,
}
void VisibilityNotifier3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
VisibilityNotifier3D *notifier = Object::cast_to<VisibilityNotifier3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -2310,7 +2231,6 @@ void VisibilityNotifier3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> handles;
for (int i = 0; i < 3; i++) {
-
Vector3 ax;
ax[i] = aabb.position[i] + aabb.size[i];
ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
@@ -2320,7 +2240,6 @@ void VisibilityNotifier3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector3 center = aabb.position + aabb.size * 0.5;
for (int i = 0; i < 3; i++) {
-
Vector3 ax;
ax[i] = 1.0;
handles.push_back(center + ax);
@@ -2396,25 +2315,30 @@ bool GPUParticles3DGizmoPlugin::is_selectable_when_hidden() const {
}
String GPUParticles3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
switch (p_idx) {
- case 0: return "Size X";
- case 1: return "Size Y";
- case 2: return "Size Z";
- case 3: return "Pos X";
- case 4: return "Pos Y";
- case 5: return "Pos Z";
+ case 0:
+ return "Size X";
+ case 1:
+ return "Size Y";
+ case 2:
+ return "Size Z";
+ case 3:
+ return "Pos X";
+ case 4:
+ return "Pos Y";
+ case 5:
+ return "Pos Z";
}
return "";
}
-Variant GPUParticles3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
+Variant GPUParticles3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node());
return particles->get_visibility_aabb();
}
-void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
+void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node());
Transform gt = particles->get_global_transform();
@@ -2435,7 +2359,6 @@ void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx
axis[p_idx] = 1.0;
if (move) {
-
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb);
@@ -2456,8 +2379,9 @@ void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
//resize
aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d;
aabb.size[p_idx] = d * 2;
@@ -2466,7 +2390,6 @@ void GPUParticles3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx
}
void GPUParticles3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
-
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node());
if (p_cancel) {
@@ -2482,7 +2405,6 @@ void GPUParticles3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_
}
void GPUParticles3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -2500,7 +2422,6 @@ void GPUParticles3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> handles;
for (int i = 0; i < 3; i++) {
-
Vector3 ax;
ax[i] = aabb.position[i] + aabb.size[i];
ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
@@ -2510,7 +2431,6 @@ void GPUParticles3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector3 center = aabb.position + aabb.size * 0.5;
for (int i = 0; i < 3; i++) {
-
Vector3 ax;
ax[i] = 1.0;
handles.push_back(center + ax);
@@ -2531,6 +2451,7 @@ void GPUParticles3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_handles(handles, get_material("handles"));
p_gizmo->add_unscaled_billboard(icon, 0.05);
}
+
////
ReflectionProbeGizmoPlugin::ReflectionProbeGizmoPlugin() {
@@ -2561,25 +2482,30 @@ int ReflectionProbeGizmoPlugin::get_priority() const {
}
String ReflectionProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
switch (p_idx) {
- case 0: return "Extents X";
- case 1: return "Extents Y";
- case 2: return "Extents Z";
- case 3: return "Origin X";
- case 4: return "Origin Y";
- case 5: return "Origin Z";
+ case 0:
+ return "Extents X";
+ case 1:
+ return "Extents Y";
+ case 2:
+ return "Extents Z";
+ case 3:
+ return "Origin X";
+ case 4:
+ return "Origin Y";
+ case 5:
+ return "Origin Z";
}
return "";
}
-Variant ReflectionProbeGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
+Variant ReflectionProbeGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
return AABB(probe->get_extents(), probe->get_origin_offset());
}
-void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
+void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
Transform gt = probe->get_global_transform();
@@ -2603,13 +2529,13 @@ void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_id
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
extents[p_idx] = d;
probe->set_extents(extents);
} else {
-
p_idx -= 3;
Vector3 origin = probe->get_origin_offset();
@@ -2637,7 +2563,6 @@ void ReflectionProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_id
}
void ReflectionProbeGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
-
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
AABB restore = p_restore;
@@ -2658,7 +2583,6 @@ void ReflectionProbeGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p
}
void ReflectionProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
ReflectionProbe *probe = Object::cast_to<ReflectionProbe>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -2687,14 +2611,12 @@ void ReflectionProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> handles;
for (int i = 0; i < 3; i++) {
-
Vector3 ax;
ax[i] = aabb.position[i] + aabb.size[i];
handles.push_back(ax);
}
for (int i = 0; i < 3; i++) {
-
Vector3 orig_handle = probe->get_origin_offset();
orig_handle[i] -= 0.25;
lines.push_back(orig_handle);
@@ -2719,6 +2641,7 @@ void ReflectionProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->add_unscaled_billboard(icon, 0.05);
p_gizmo->add_handles(handles, get_material("handles"));
}
+
///////////////////////////////
////
@@ -2744,22 +2667,24 @@ int DecalGizmoPlugin::get_priority() const {
}
String DecalGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
switch (p_idx) {
- case 0: return "Extents X";
- case 1: return "Extents Y";
- case 2: return "Extents Z";
+ case 0:
+ return "Extents X";
+ case 1:
+ return "Extents Y";
+ case 2:
+ return "Extents Z";
}
return "";
}
-Variant DecalGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
+Variant DecalGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
return decal->get_extents();
}
-void DecalGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
+void DecalGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
Transform gt = decal->get_global_transform();
@@ -2782,15 +2707,15 @@ void DecalGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
extents[p_idx] = d;
decal->set_extents(extents);
}
void DecalGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
-
Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
Vector3 restore = p_restore;
@@ -2808,7 +2733,6 @@ void DecalGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, cons
}
void DecalGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
Decal *decal = Object::cast_to<Decal>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -2827,10 +2751,10 @@ void DecalGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
lines.push_back(a);
lines.push_back(b);
} else {
- Vector3 ah = a.linear_interpolate(b, 0.2);
+ Vector3 ah = a.lerp(b, 0.2);
lines.push_back(a);
lines.push_back(ah);
- Vector3 bh = b.linear_interpolate(a, 0.2);
+ Vector3 bh = b.lerp(a, 0.2);
lines.push_back(b);
lines.push_back(bh);
}
@@ -2842,7 +2766,6 @@ void DecalGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> handles;
for (int i = 0; i < 3; i++) {
-
Vector3 ax;
ax[i] = aabb.position[i] + aabb.size[i];
handles.push_back(ax);
@@ -2885,22 +2808,24 @@ int GIProbeGizmoPlugin::get_priority() const {
}
String GIProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
switch (p_idx) {
- case 0: return "Extents X";
- case 1: return "Extents Y";
- case 2: return "Extents Z";
+ case 0:
+ return "Extents X";
+ case 1:
+ return "Extents Y";
+ case 2:
+ return "Extents Z";
}
return "";
}
-Variant GIProbeGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
+Variant GIProbeGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node());
return probe->get_extents();
}
-void GIProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
+void GIProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node());
Transform gt = probe->get_global_transform();
@@ -2923,15 +2848,15 @@ void GIProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camer
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
extents[p_idx] = d;
probe->set_extents(extents);
}
void GIProbeGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
-
GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node());
Vector3 restore = p_restore;
@@ -2949,7 +2874,6 @@ void GIProbeGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, co
}
void GIProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node());
Ref<Material> material = get_material("gi_probe_material", p_gizmo);
@@ -2979,9 +2903,7 @@ void GIProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
lines.clear();
for (int i = 1; i < subdiv; i++) {
-
for (int j = 0; j < 3; j++) {
-
if (cell_size * i > aabb.size[j]) {
continue;
}
@@ -2995,7 +2917,6 @@ void GIProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
tb[j_n2] = 1.0;
for (int k = 0; k < 4; k++) {
-
Vector3 from = aabb.position, to = aabb.position;
from[j] += cell_size * i;
to[j] += cell_size * i;
@@ -3003,7 +2924,6 @@ void GIProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
if (k & 1) {
to[j_n1] += aabb.size[j_n1];
} else {
-
to[j_n2] += aabb.size[j_n2];
}
@@ -3023,7 +2943,6 @@ void GIProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> handles;
for (int i = 0; i < 3; i++) {
-
Vector3 ax;
ax[i] = aabb.position[i] + aabb.size[i];
handles.push_back(ax);
@@ -3039,136 +2958,293 @@ void GIProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
////
-#if 0
-BakedIndirectLightGizmoPlugin::BakedIndirectLightGizmoPlugin() {
- Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/baked_indirect_light", Color(0.5, 0.6, 1));
- create_material("baked_indirect_light_material", gizmo_color);
+BakedLightmapGizmoPlugin::BakedLightmapGizmoPlugin() {
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/lightmap_lines", Color(0.5, 0.6, 1));
gizmo_color.a = 0.1;
- create_material("baked_indirect_light_internal_material", gizmo_color);
+ create_material("lightmap_lines", gizmo_color);
- create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_icon("GizmoBakedLightmap", "EditorIcons"));
- create_handle_material("handles");
-}
+ Ref<StandardMaterial3D> mat = memnew(StandardMaterial3D);
+ mat->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ mat->set_cull_mode(StandardMaterial3D::CULL_DISABLED);
+ mat->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ mat->set_flag(StandardMaterial3D::FLAG_SRGB_VERTEX_COLOR, false);
-String BakedIndirectLightGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
+ add_material("lightmap_probe_material", mat);
- switch (p_idx) {
- case 0: return "Extents X";
- case 1: return "Extents Y";
- case 2: return "Extents Z";
- }
+ create_icon_material("baked_indirect_light_icon", Node3DEditor::get_singleton()->get_theme_icon("GizmoBakedLightmap", "EditorIcons"));
+}
+String BakedLightmapGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
return "";
}
-Variant BakedIndirectLightGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
- BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node());
- return baker->get_extents();
+Variant BakedLightmapGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
+ return Variant();
+}
+
+void BakedLightmapGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
+}
+
+void BakedLightmapGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+}
+
+bool BakedLightmapGizmoPlugin::has_gizmo(Node3D *p_spatial) {
+ return Object::cast_to<BakedLightmap>(p_spatial) != nullptr;
+}
+
+String BakedLightmapGizmoPlugin::get_name() const {
+ return "BakedLightmap";
}
-void BakedIndirectLightGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+int BakedLightmapGizmoPlugin::get_priority() const {
+ return -1;
+}
+
+void BakedLightmapGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
+ Ref<Material> icon = get_material("baked_indirect_light_icon", p_gizmo);
BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node());
+ Ref<BakedLightmapData> data = baker->get_light_data();
- Transform gt = baker->get_global_transform();
- Transform gi = gt.affine_inverse();
+ p_gizmo->add_unscaled_billboard(icon, 0.05);
- Vector3 extents = baker->get_extents();
+ if (data.is_null()) {
+ return;
+ }
- Vector3 ray_from = p_camera->project_ray_origin(p_point);
- Vector3 ray_dir = p_camera->project_ray_normal(p_point);
+ Ref<Material> material_lines = get_material("lightmap_lines", p_gizmo);
+ Ref<Material> material_probes = get_material("lightmap_probe_material", p_gizmo);
- Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
+ p_gizmo->clear();
- Vector3 axis;
- axis[p_idx] = 1.0;
+ Vector<Vector3> lines;
+ Set<Vector2i> lines_found;
- Vector3 ra, rb;
- Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb);
- float d = ra[p_idx];
- if (Node3DEditor::get_singleton()->is_snap_enabled()) {
- d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
+ Vector<Vector3> points = data->get_capture_points();
+ if (points.size() == 0) {
+ return;
+ }
+ Vector<Color> sh = data->get_capture_sh();
+ if (sh.size() != points.size() * 9) {
+ return;
}
- if (d < 0.001)
- d = 0.001;
+ Vector<int> tetrahedrons = data->get_capture_tetrahedra();
- extents[p_idx] = d;
- baker->set_extents(extents);
-}
+ for (int i = 0; i < tetrahedrons.size(); i += 4) {
+ for (int j = 0; j < 4; j++) {
+ for (int k = j + 1; k < 4; k++) {
+ Vector2i pair;
+ pair.x = tetrahedrons[i + j];
+ pair.y = tetrahedrons[i + k];
-void BakedIndirectLightGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+ if (pair.y < pair.x) {
+ SWAP(pair.x, pair.y);
+ }
+ if (lines_found.has(pair)) {
+ continue;
+ }
+ lines_found.insert(pair);
+ lines.push_back(points[pair.x]);
+ lines.push_back(points[pair.y]);
+ }
+ }
+ }
- BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node());
+ p_gizmo->add_lines(lines, material_lines);
- Vector3 restore = p_restore;
+ int stack_count = 8;
+ int sector_count = 16;
- if (p_cancel) {
- baker->set_extents(restore);
- return;
+ float sector_step = 2 * Math_PI / sector_count;
+ float stack_step = Math_PI / stack_count;
+
+ Vector<Vector3> vertices;
+ Vector<Color> colors;
+ Vector<int> indices;
+ float radius = 0.3;
+
+ for (int p = 0; p < points.size(); p++) {
+ int vertex_base = vertices.size();
+ Vector3 sh_col[9];
+ for (int i = 0; i < 9; i++) {
+ sh_col[i].x = sh[p * 9 + i].r;
+ sh_col[i].y = sh[p * 9 + i].g;
+ sh_col[i].z = sh[p * 9 + i].b;
+ }
+
+ for (int i = 0; i <= stack_count; ++i) {
+ float stack_angle = Math_PI / 2 - i * stack_step; // starting from pi/2 to -pi/2
+ float xy = radius * Math::cos(stack_angle); // r * cos(u)
+ float z = radius * Math::sin(stack_angle); // r * sin(u)
+
+ // add (sector_count+1) vertices per stack
+ // the first and last vertices have same position and normal, but different tex coords
+ for (int j = 0; j <= sector_count; ++j) {
+ float sector_angle = j * sector_step; // starting from 0 to 2pi
+
+ // vertex position (x, y, z)
+ float x = xy * Math::cos(sector_angle); // r * cos(u) * cos(v)
+ float y = xy * Math::sin(sector_angle); // r * cos(u) * sin(v)
+
+ Vector3 n = Vector3(x, z, y);
+ vertices.push_back(points[p] + n);
+ n.normalize();
+
+ const float c1 = 0.429043;
+ const float c2 = 0.511664;
+ const float c3 = 0.743125;
+ const float c4 = 0.886227;
+ const float c5 = 0.247708;
+ Vector3 light = (c1 * sh_col[8] * (n.x * n.x - n.y * n.y) +
+ c3 * sh_col[6] * n.z * n.z +
+ c4 * sh_col[0] -
+ c5 * sh_col[6] +
+ 2.0 * c1 * sh_col[4] * n.x * n.y +
+ 2.0 * c1 * sh_col[7] * n.x * n.z +
+ 2.0 * c1 * sh_col[5] * n.y * n.z +
+ 2.0 * c2 * sh_col[3] * n.x +
+ 2.0 * c2 * sh_col[1] * n.y +
+ 2.0 * c2 * sh_col[2] * n.z);
+
+ colors.push_back(Color(light.x, light.y, light.z, 1));
+ }
+ }
+
+ for (int i = 0; i < stack_count; ++i) {
+ int k1 = i * (sector_count + 1); // beginning of current stack
+ int k2 = k1 + sector_count + 1; // beginning of next stack
+
+ for (int j = 0; j < sector_count; ++j, ++k1, ++k2) {
+ // 2 triangles per sector excluding first and last stacks
+ // k1 => k2 => k1+1
+ if (i != 0) {
+ indices.push_back(vertex_base + k1);
+ indices.push_back(vertex_base + k2);
+ indices.push_back(vertex_base + k1 + 1);
+ }
+
+ // k1+1 => k2 => k2+1
+ if (i != (stack_count - 1)) {
+ indices.push_back(vertex_base + k1 + 1);
+ indices.push_back(vertex_base + k2);
+ indices.push_back(vertex_base + k2 + 1);
+ }
+ }
+ }
}
- UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Change Probe Extents"));
- ur->add_do_method(baker, "set_extents", baker->get_extents());
- ur->add_undo_method(baker, "set_extents", restore);
- ur->commit_action();
+ Array array;
+ array.resize(RS::ARRAY_MAX);
+ array[RS::ARRAY_VERTEX] = vertices;
+ array[RS::ARRAY_INDEX] = indices;
+ array[RS::ARRAY_COLOR] = colors;
+
+ Ref<ArrayMesh> mesh;
+ mesh.instance();
+ mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, array, Array(), Dictionary(), 0); //no compression
+ mesh->surface_set_material(0, material_probes);
+
+ p_gizmo->add_mesh(mesh);
}
-bool BakedIndirectLightGizmoPlugin::has_gizmo(Spatial *p_spatial) {
- return Object::cast_to<BakedLightmap>(p_spatial) != nullptr;
+/////////
+
+LightmapProbeGizmoPlugin::LightmapProbeGizmoPlugin() {
+ Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/lightprobe_lines", Color(0.5, 0.6, 1));
+
+ gizmo_color.a = 0.3;
+ create_material("lightprobe_lines", gizmo_color);
}
-String BakedIndirectLightGizmoPlugin::get_name() const {
- return "BakedLightmap";
+String LightmapProbeGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
+ return "";
}
-int BakedIndirectLightGizmoPlugin::get_priority() const {
- return -1;
+Variant LightmapProbeGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
+ return Variant();
+}
+
+void LightmapProbeGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
}
-void BakedIndirectLightGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
+void LightmapProbeGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+}
- BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node());
+bool LightmapProbeGizmoPlugin::has_gizmo(Node3D *p_spatial) {
+ return Object::cast_to<LightmapProbe>(p_spatial) != nullptr;
+}
- Ref<Material> material = get_material("baked_indirect_light_material", p_gizmo);
- Ref<Material> icon = get_material("baked_indirect_light_icon", p_gizmo);
- Ref<Material> material_internal = get_material("baked_indirect_light_internal_material", p_gizmo);
+String LightmapProbeGizmoPlugin::get_name() const {
+ return "LightmapProbe";
+}
+
+int LightmapProbeGizmoPlugin::get_priority() const {
+ return -1;
+}
+
+void LightmapProbeGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
+ Ref<Material> material_lines = get_material("lightprobe_lines", p_gizmo);
p_gizmo->clear();
Vector<Vector3> lines;
- Vector3 extents = baker->get_extents();
- AABB aabb = AABB(-extents, extents * 2);
+ int stack_count = 8;
+ int sector_count = 16;
- for (int i = 0; i < 12; i++) {
- Vector3 a, b;
- aabb.get_edge(i, a, b);
- lines.push_back(a);
- lines.push_back(b);
- }
+ float sector_step = 2 * Math_PI / sector_count;
+ float stack_step = Math_PI / stack_count;
- p_gizmo->add_lines(lines, material);
+ Vector<Vector3> vertices;
+ float radius = 0.2;
- Vector<Vector3> handles;
+ for (int i = 0; i <= stack_count; ++i) {
+ float stack_angle = Math_PI / 2 - i * stack_step; // starting from pi/2 to -pi/2
+ float xy = radius * Math::cos(stack_angle); // r * cos(u)
+ float z = radius * Math::sin(stack_angle); // r * sin(u)
- for (int i = 0; i < 3; i++) {
+ // add (sector_count+1) vertices per stack
+ // the first and last vertices have same position and normal, but different tex coords
+ for (int j = 0; j <= sector_count; ++j) {
+ float sector_angle = j * sector_step; // starting from 0 to 2pi
- Vector3 ax;
- ax[i] = aabb.position[i] + aabb.size[i];
- handles.push_back(ax);
+ // vertex position (x, y, z)
+ float x = xy * Math::cos(sector_angle); // r * cos(u) * cos(v)
+ float y = xy * Math::sin(sector_angle); // r * cos(u) * sin(v)
+
+ Vector3 n = Vector3(x, z, y);
+ vertices.push_back(n);
+ }
}
- if (p_gizmo->is_selected()) {
- p_gizmo->add_solid_box(material_internal, aabb.get_size());
+ for (int i = 0; i < stack_count; ++i) {
+ int k1 = i * (sector_count + 1); // beginning of current stack
+ int k2 = k1 + sector_count + 1; // beginning of next stack
+
+ for (int j = 0; j < sector_count; ++j, ++k1, ++k2) {
+ // 2 triangles per sector excluding first and last stacks
+ // k1 => k2 => k1+1
+ if (i != 0) {
+ lines.push_back(vertices[k1]);
+ lines.push_back(vertices[k2]);
+ lines.push_back(vertices[k1]);
+ lines.push_back(vertices[k1 + 1]);
+ }
+
+ if (i != (stack_count - 1)) {
+ lines.push_back(vertices[k1 + 1]);
+ lines.push_back(vertices[k2]);
+ lines.push_back(vertices[k2]);
+ lines.push_back(vertices[k2 + 1]);
+ }
+ }
}
- p_gizmo->add_unscaled_billboard(icon, 0.05);
- p_gizmo->add_handles(handles, get_material("handles"));
+ p_gizmo->add_lines(lines, material_lines);
}
-#endif
+
////
CollisionShape3DGizmoPlugin::CollisionShape3DGizmoPlugin() {
@@ -3193,35 +3269,30 @@ int CollisionShape3DGizmoPlugin::get_priority() const {
}
String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
const CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node());
Ref<Shape3D> s = cs->get_shape();
- if (s.is_null())
+ if (s.is_null()) {
return "";
+ }
if (Object::cast_to<SphereShape3D>(*s)) {
-
return "Radius";
}
if (Object::cast_to<BoxShape3D>(*s)) {
-
return "Extents";
}
if (Object::cast_to<CapsuleShape3D>(*s)) {
-
return p_idx == 0 ? "Radius" : "Height";
}
if (Object::cast_to<CylinderShape3D>(*s)) {
-
return p_idx == 0 ? "Radius" : "Height";
}
if (Object::cast_to<RayShape3D>(*s)) {
-
return "Length";
}
@@ -3229,52 +3300,48 @@ String CollisionShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_g
}
Variant CollisionShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node());
Ref<Shape3D> s = cs->get_shape();
- if (s.is_null())
+ if (s.is_null()) {
return Variant();
+ }
if (Object::cast_to<SphereShape3D>(*s)) {
-
Ref<SphereShape3D> ss = s;
return ss->get_radius();
}
if (Object::cast_to<BoxShape3D>(*s)) {
-
Ref<BoxShape3D> bs = s;
return bs->get_extents();
}
if (Object::cast_to<CapsuleShape3D>(*s)) {
-
Ref<CapsuleShape3D> cs2 = s;
return p_idx == 0 ? cs2->get_radius() : cs2->get_height();
}
if (Object::cast_to<CylinderShape3D>(*s)) {
-
Ref<CylinderShape3D> cs2 = s;
return p_idx == 0 ? cs2->get_radius() : cs2->get_height();
}
if (Object::cast_to<RayShape3D>(*s)) {
-
Ref<RayShape3D> cs2 = s;
return cs2->get_length();
}
return Variant();
}
-void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
+void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node());
Ref<Shape3D> s = cs->get_shape();
- if (s.is_null())
+ if (s.is_null()) {
return;
+ }
Transform gt = cs->get_global_transform();
Transform gi = gt.affine_inverse();
@@ -3285,7 +3352,6 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i
Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
if (Object::cast_to<SphereShape3D>(*s)) {
-
Ref<SphereShape3D> ss = s;
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb);
@@ -3294,14 +3360,14 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
ss->set_radius(d);
}
if (Object::cast_to<RayShape3D>(*s)) {
-
Ref<RayShape3D> rs = s;
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), Vector3(0, 0, 4096), sg[0], sg[1], ra, rb);
@@ -3310,14 +3376,14 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
rs->set_length(d);
}
if (Object::cast_to<BoxShape3D>(*s)) {
-
Vector3 axis;
axis[p_idx] = 1.0;
Ref<BoxShape3D> bs = s;
@@ -3328,8 +3394,9 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
Vector3 he = bs->get_extents();
he[p_idx] = d;
@@ -3337,31 +3404,32 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i
}
if (Object::cast_to<CapsuleShape3D>(*s)) {
-
Vector3 axis;
axis[p_idx == 0 ? 0 : 2] = 1.0;
Ref<CapsuleShape3D> cs2 = s;
Vector3 ra, rb;
Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb);
float d = axis.dot(ra);
- if (p_idx == 1)
+ if (p_idx == 1) {
d -= cs2->get_radius();
+ }
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
- if (p_idx == 0)
+ if (p_idx == 0) {
cs2->set_radius(d);
- else if (p_idx == 1)
+ } else if (p_idx == 1) {
cs2->set_height(d * 2.0);
+ }
}
if (Object::cast_to<CylinderShape3D>(*s)) {
-
Vector3 axis;
axis[p_idx == 0 ? 0 : 1] = 1.0;
Ref<CylinderShape3D> cs2 = s;
@@ -3372,25 +3440,27 @@ void CollisionShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_i
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
- if (p_idx == 0)
+ if (p_idx == 0) {
cs2->set_radius(d);
- else if (p_idx == 1)
+ } else if (p_idx == 1) {
cs2->set_height(d * 2.0);
+ }
}
}
-void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node());
Ref<Shape3D> s = cs->get_shape();
- if (s.is_null())
+ if (s.is_null()) {
return;
+ }
if (Object::cast_to<SphereShape3D>(*s)) {
-
Ref<SphereShape3D> ss = s;
if (p_cancel) {
ss->set_radius(p_restore);
@@ -3405,7 +3475,6 @@ void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int
}
if (Object::cast_to<BoxShape3D>(*s)) {
-
Ref<BoxShape3D> ss = s;
if (p_cancel) {
ss->set_extents(p_restore);
@@ -3420,13 +3489,13 @@ void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int
}
if (Object::cast_to<CapsuleShape3D>(*s)) {
-
Ref<CapsuleShape3D> ss = s;
if (p_cancel) {
- if (p_idx == 0)
+ if (p_idx == 0) {
ss->set_radius(p_restore);
- else
+ } else {
ss->set_height(p_restore);
+ }
return;
}
@@ -3445,13 +3514,13 @@ void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int
}
if (Object::cast_to<CylinderShape3D>(*s)) {
-
Ref<CylinderShape3D> ss = s;
if (p_cancel) {
- if (p_idx == 0)
+ if (p_idx == 0) {
ss->set_radius(p_restore);
- else
+ } else {
ss->set_height(p_restore);
+ }
return;
}
@@ -3474,7 +3543,6 @@ void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int
}
if (Object::cast_to<RayShape3D>(*s)) {
-
Ref<RayShape3D> ss = s;
if (p_cancel) {
ss->set_length(p_restore);
@@ -3488,29 +3556,28 @@ void CollisionShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int
ur->commit_action();
}
}
-void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
+void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
CollisionShape3D *cs = Object::cast_to<CollisionShape3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
Ref<Shape3D> s = cs->get_shape();
- if (s.is_null())
+ if (s.is_null()) {
return;
+ }
const Ref<Material> material =
get_material(!cs->is_disabled() ? "shape_material" : "shape_material_disabled", p_gizmo);
Ref<Material> handles_material = get_material("handles");
if (Object::cast_to<SphereShape3D>(*s)) {
-
Ref<SphereShape3D> sp = s;
float r = sp->get_radius();
Vector<Vector3> points;
for (int i = 0; i <= 360; i++) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + 1);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
@@ -3527,7 +3594,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> collision_segments;
for (int i = 0; i < 64; i++) {
-
float ra = i * Math_PI * 2.0 / 64.0;
float rb = (i + 1) * Math_PI * 2.0 / 64.0;
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
@@ -3549,7 +3615,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
if (Object::cast_to<BoxShape3D>(*s)) {
-
Ref<BoxShape3D> bs = s;
Vector<Vector3> lines;
AABB aabb;
@@ -3566,7 +3631,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> handles;
for (int i = 0; i < 3; i++) {
-
Vector3 ax;
ax[i] = bs->get_extents()[i];
handles.push_back(ax);
@@ -3578,7 +3642,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
if (Object::cast_to<CapsuleShape3D>(*s)) {
-
Ref<CapsuleShape3D> cs2 = s;
float radius = cs2->get_radius();
float height = cs2->get_height();
@@ -3587,7 +3650,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector3 d(0, height * 0.5, 0);
for (int i = 0; i < 360; i++) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + 1);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
@@ -3600,7 +3662,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
points.push_back(Vector3(b.x, 0, b.y) - d);
if (i % 90 == 0) {
-
points.push_back(Vector3(a.x, 0, a.y) + d);
points.push_back(Vector3(a.x, 0, a.y) - d);
}
@@ -3618,7 +3679,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> collision_segments;
for (int i = 0; i < 64; i++) {
-
float ra = i * Math_PI * 2.0 / 64.0;
float rb = (i + 1) * Math_PI * 2.0 / 64.0;
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
@@ -3631,7 +3691,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
collision_segments.push_back(Vector3(b.x, 0, b.y) - d);
if (i % 16 == 0) {
-
collision_segments.push_back(Vector3(a.x, 0, a.y) + d);
collision_segments.push_back(Vector3(a.x, 0, a.y) - d);
}
@@ -3653,7 +3712,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
if (Object::cast_to<CylinderShape3D>(*s)) {
-
Ref<CylinderShape3D> cs2 = s;
float radius = cs2->get_radius();
float height = cs2->get_height();
@@ -3662,7 +3720,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector3 d(0, height * 0.5, 0);
for (int i = 0; i < 360; i++) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + 1);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
@@ -3675,7 +3732,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
points.push_back(Vector3(b.x, 0, b.y) - d);
if (i % 90 == 0) {
-
points.push_back(Vector3(a.x, 0, a.y) + d);
points.push_back(Vector3(a.x, 0, a.y) - d);
}
@@ -3686,7 +3742,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> collision_segments;
for (int i = 0; i < 64; i++) {
-
float ra = i * Math_PI * 2.0 / 64.0;
float rb = (i + 1) * Math_PI * 2.0 / 64.0;
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
@@ -3699,7 +3754,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
collision_segments.push_back(Vector3(b.x, 0, b.y) - d);
if (i % 16 == 0) {
-
collision_segments.push_back(Vector3(a.x, 0, a.y) + d);
collision_segments.push_back(Vector3(a.x, 0, a.y) - d);
}
@@ -3714,7 +3768,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
if (Object::cast_to<WorldMarginShape3D>(*s)) {
-
Ref<WorldMarginShape3D> ps = s;
Plane p = ps->get_plane();
Vector<Vector3> points;
@@ -3745,11 +3798,9 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
if (Object::cast_to<ConvexPolygonShape3D>(*s)) {
-
Vector<Vector3> points = Object::cast_to<ConvexPolygonShape3D>(*s)->get_points();
if (points.size() > 3) {
-
Vector<Vector3> varr = Variant(points);
Geometry::MeshData md;
Error err = QuickHull::build(varr, md);
@@ -3768,7 +3819,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
if (Object::cast_to<ConcavePolygonShape3D>(*s)) {
-
Ref<ConcavePolygonShape3D> cs2 = s;
Ref<ArrayMesh> mesh = cs2->get_debug_mesh();
p_gizmo->add_mesh(mesh, false, Ref<SkinReference>(), material);
@@ -3776,7 +3826,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
if (Object::cast_to<RayShape3D>(*s)) {
-
Ref<RayShape3D> rs = s;
Vector<Vector3> points;
@@ -3790,7 +3839,6 @@ void CollisionShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
if (Object::cast_to<HeightMapShape3D>(*s)) {
-
Ref<HeightMapShape3D> hms = s;
Ref<ArrayMesh> mesh = hms->get_debug_mesh();
@@ -3821,7 +3869,6 @@ int CollisionPolygon3DGizmoPlugin::get_priority() const {
}
void CollisionPolygon3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
CollisionPolygon3D *polygon = Object::cast_to<CollisionPolygon3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
@@ -3831,7 +3878,6 @@ void CollisionPolygon3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> lines;
for (int i = 0; i < points.size(); i++) {
-
int n = (i + 1) % points.size();
lines.push_back(Vector3(points[i].x, points[i].y, depth));
lines.push_back(Vector3(points[n].x, points[n].y, depth));
@@ -3870,7 +3916,6 @@ int NavigationRegion3DGizmoPlugin::get_priority() const {
}
void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
NavigationRegion3D *navmesh = Object::cast_to<NavigationRegion3D>(p_gizmo->get_spatial_node());
Ref<Material> edge_material = get_material("navigation_edge_material", p_gizmo);
@@ -3880,8 +3925,9 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
p_gizmo->clear();
Ref<NavigationMesh> navmeshie = navmesh->get_navigation_mesh();
- if (navmeshie.is_null())
+ if (navmeshie.is_null()) {
return;
+ }
Vector<Vector3> vertices = navmeshie->get_vertices();
const Vector3 *vr = vertices.ptr();
@@ -3899,8 +3945,9 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
}
}
- if (faces.empty())
+ if (faces.empty()) {
return;
+ }
Map<_EdgeKey, bool> edge_map;
Vector<Vector3> tmeshfaces;
@@ -3911,26 +3958,23 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
int tidx = 0;
for (List<Face3>::Element *E = faces.front(); E; E = E->next()) {
-
const Face3 &f = E->get();
for (int j = 0; j < 3; j++) {
-
tw[tidx++] = f.vertex[j];
_EdgeKey ek;
ek.from = f.vertex[j].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
ek.to = f.vertex[(j + 1) % 3].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
- if (ek.from < ek.to)
+ if (ek.from < ek.to) {
SWAP(ek.from, ek.to);
+ }
Map<_EdgeKey, bool>::Element *F = edge_map.find(ek);
if (F) {
-
F->get() = false;
} else {
-
edge_map[ek] = true;
}
}
@@ -3939,7 +3983,6 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Vector<Vector3> lines;
for (Map<_EdgeKey, bool>::Element *E = edge_map.front(); E; E = E->next()) {
-
if (E->get()) {
lines.push_back(E->key().from);
lines.push_back(E->key().to);
@@ -3949,8 +3992,9 @@ void NavigationRegion3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Ref<TriangleMesh> tmesh = memnew(TriangleMesh);
tmesh->create(tmeshfaces);
- if (lines.size())
+ if (lines.size()) {
p_gizmo->add_lines(lines, navmesh->is_enabled() ? edge_material : edge_material_disabled);
+ }
p_gizmo->add_collision_triangles(tmesh);
Ref<ArrayMesh> m = memnew(ArrayMesh);
Array a;
@@ -3993,7 +4037,6 @@ Basis JointGizmosDrawer::look_body(const Transform &p_joint_transform, const Tra
}
Basis JointGizmosDrawer::look_body_toward(Vector3::Axis p_axis, const Transform &joint_transform, const Transform &body_transform) {
-
switch (p_axis) {
case Vector3::AXIS_X:
return look_body_toward_x(joint_transform, body_transform);
@@ -4007,7 +4050,6 @@ Basis JointGizmosDrawer::look_body_toward(Vector3::Axis p_axis, const Transform
}
Basis JointGizmosDrawer::look_body_toward_x(const Transform &p_joint_transform, const Transform &p_body_transform) {
-
const Vector3 &p_eye(p_joint_transform.origin);
const Vector3 &p_target(p_body_transform.origin);
@@ -4039,7 +4081,6 @@ Basis JointGizmosDrawer::look_body_toward_x(const Transform &p_joint_transform,
}
Basis JointGizmosDrawer::look_body_toward_y(const Transform &p_joint_transform, const Transform &p_body_transform) {
-
const Vector3 &p_eye(p_joint_transform.origin);
const Vector3 &p_target(p_body_transform.origin);
@@ -4071,7 +4112,6 @@ Basis JointGizmosDrawer::look_body_toward_y(const Transform &p_joint_transform,
}
Basis JointGizmosDrawer::look_body_toward_z(const Transform &p_joint_transform, const Transform &p_body_transform) {
-
const Vector3 &p_eye(p_joint_transform.origin);
const Vector3 &p_target(p_body_transform.origin);
@@ -4103,14 +4143,11 @@ Basis JointGizmosDrawer::look_body_toward_z(const Transform &p_joint_transform,
}
void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const Transform &p_offset, const Basis &p_base, real_t p_limit_lower, real_t p_limit_upper, Vector<Vector3> &r_points, bool p_inverse) {
-
if (p_limit_lower == p_limit_upper) {
-
r_points.push_back(p_offset.translated(Vector3()).origin);
r_points.push_back(p_offset.translated(p_base.xform(Vector3(0.5, 0, 0))).origin);
} else {
-
if (p_limit_lower > p_limit_upper) {
p_limit_lower = -Math_PI;
p_limit_upper = Math_PI;
@@ -4119,7 +4156,6 @@ void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const
const int points = 32;
for (int i = 0; i < points; i++) {
-
real_t s = p_limit_lower + i * (p_limit_upper - p_limit_lower) / points;
real_t n = p_limit_lower + (i + 1) * (p_limit_upper - p_limit_lower) / points;
@@ -4169,14 +4205,12 @@ void JointGizmosDrawer::draw_circle(Vector3::Axis p_axis, real_t p_radius, const
}
void JointGizmosDrawer::draw_cone(const Transform &p_offset, const Basis &p_base, real_t p_swing, real_t p_twist, Vector<Vector3> &r_points) {
-
float r = 1.0;
float w = r * Math::sin(p_swing);
float d = r * Math::cos(p_swing);
//swing
for (int i = 0; i < 360; i += 10) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + 10);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * w;
@@ -4186,7 +4220,6 @@ void JointGizmosDrawer::draw_cone(const Transform &p_offset, const Basis &p_base
r_points.push_back(p_offset.translated(p_base.xform(Vector3(d, b.x, b.y))).origin);
if (i % 90 == 0) {
-
r_points.push_back(p_offset.translated(p_base.xform(Vector3(d, a.x, a.y))).origin);
r_points.push_back(p_offset.translated(p_base.xform(Vector3())).origin);
}
@@ -4200,7 +4233,6 @@ void JointGizmosDrawer::draw_cone(const Transform &p_offset, const Basis &p_base
ts = MIN(ts, 720);
for (int i = 0; i < int(ts); i += 5) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + 5);
float c = i / 720.0;
@@ -4219,6 +4251,21 @@ Joint3DGizmoPlugin::Joint3DGizmoPlugin() {
create_material("joint_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint", Color(0.5, 0.8, 1)));
create_material("joint_body_a_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_a", Color(0.6, 0.8, 1)));
create_material("joint_body_b_material", EDITOR_DEF("editors/3d_gizmos/gizmo_colors/joint_body_b", Color(0.6, 0.9, 1)));
+
+ update_timer = memnew(Timer);
+ update_timer->set_name("JointGizmoUpdateTimer");
+ update_timer->set_wait_time(1.0 / 120.0);
+ update_timer->connect("timeout", callable_mp(this, &Joint3DGizmoPlugin::incremental_update_gizmos));
+ update_timer->set_autostart(true);
+ EditorNode::get_singleton()->call_deferred("add_child", update_timer);
+}
+
+void Joint3DGizmoPlugin::incremental_update_gizmos() {
+ if (!current_gizmos.empty()) {
+ update_idx++;
+ update_idx = update_idx % current_gizmos.size();
+ redraw(current_gizmos[update_idx]);
+ }
}
bool Joint3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
@@ -4268,7 +4315,6 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
HingeJoint3D *hinge = Object::cast_to<HingeJoint3D>(joint);
if (hinge) {
-
CreateHingeJointGizmo(
Transform(),
hinge->get_global_transform(),
@@ -4292,7 +4338,6 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
SliderJoint3D *slider = Object::cast_to<SliderJoint3D>(joint);
if (slider) {
-
CreateSliderJointGizmo(
Transform(),
slider->get_global_transform(),
@@ -4317,7 +4362,6 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
ConeTwistJoint3D *cone = Object::cast_to<ConeTwistJoint3D>(joint);
if (cone) {
-
CreateConeTwistJointGizmo(
Transform(),
cone->get_global_transform(),
@@ -4337,7 +4381,6 @@ void Joint3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
Generic6DOFJoint3D *gen = Object::cast_to<Generic6DOFJoint3D>(joint);
if (gen) {
-
CreateGeneric6DOFJointGizmo(
Transform(),
gen->get_global_transform(),
@@ -4391,7 +4434,6 @@ void Joint3DGizmoPlugin::CreatePinJointGizmo(const Transform &p_offset, Vector<V
}
void Joint3DGizmoPlugin::CreateHingeJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_limit_lower, real_t p_limit_upper, bool p_use_limit, Vector<Vector3> &r_common_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) {
-
r_common_points.push_back(p_offset.translated(Vector3(0, 0, 0.5)).origin);
r_common_points.push_back(p_offset.translated(Vector3(0, 0, -0.5)).origin);
@@ -4401,7 +4443,6 @@ void Joint3DGizmoPlugin::CreateHingeJointGizmo(const Transform &p_offset, const
}
if (r_body_a_points) {
-
JointGizmosDrawer::draw_circle(Vector3::AXIS_Z,
BODY_A_RADIUS,
p_offset,
@@ -4423,7 +4464,6 @@ void Joint3DGizmoPlugin::CreateHingeJointGizmo(const Transform &p_offset, const
}
void Joint3DGizmoPlugin::CreateSliderJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_angular_limit_lower, real_t p_angular_limit_upper, real_t p_linear_limit_lower, real_t p_linear_limit_upper, Vector<Vector3> &r_points, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) {
-
p_linear_limit_lower = -p_linear_limit_lower;
p_linear_limit_upper = -p_linear_limit_upper;
@@ -4432,7 +4472,6 @@ void Joint3DGizmoPlugin::CreateSliderJointGizmo(const Transform &p_offset, const
r_points.push_back(p_offset.translated(Vector3(0, 0, -0.5)).origin);
if (p_linear_limit_lower >= p_linear_limit_upper) {
-
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_upper, 0, 0)).origin);
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, 0, 0)).origin);
@@ -4455,12 +4494,11 @@ void Joint3DGizmoPlugin::CreateSliderJointGizmo(const Transform &p_offset, const
r_points.push_back(p_offset.translated(Vector3(p_linear_limit_lower, -cs, -cs)).origin);
} else {
-
r_points.push_back(p_offset.translated(Vector3(+cs * 2, 0, 0)).origin);
r_points.push_back(p_offset.translated(Vector3(-cs * 2, 0, 0)).origin);
}
- if (r_body_a_points)
+ if (r_body_a_points) {
JointGizmosDrawer::draw_circle(
Vector3::AXIS_X,
BODY_A_RADIUS,
@@ -4469,8 +4507,9 @@ void Joint3DGizmoPlugin::CreateSliderJointGizmo(const Transform &p_offset, const
p_angular_limit_lower,
p_angular_limit_upper,
*r_body_a_points);
+ }
- if (r_body_b_points)
+ if (r_body_b_points) {
JointGizmosDrawer::draw_circle(
Vector3::AXIS_X,
BODY_B_RADIUS,
@@ -4480,25 +4519,27 @@ void Joint3DGizmoPlugin::CreateSliderJointGizmo(const Transform &p_offset, const
p_angular_limit_upper,
*r_body_b_points,
true);
+ }
}
void Joint3DGizmoPlugin::CreateConeTwistJointGizmo(const Transform &p_offset, const Transform &p_trs_joint, const Transform &p_trs_body_a, const Transform &p_trs_body_b, real_t p_swing, real_t p_twist, Vector<Vector3> *r_body_a_points, Vector<Vector3> *r_body_b_points) {
-
- if (r_body_a_points)
+ if (r_body_a_points) {
JointGizmosDrawer::draw_cone(
p_offset,
JointGizmosDrawer::look_body(p_trs_joint, p_trs_body_a),
p_swing,
p_twist,
*r_body_a_points);
+ }
- if (r_body_b_points)
+ if (r_body_b_points) {
JointGizmosDrawer::draw_cone(
p_offset,
JointGizmosDrawer::look_body(p_trs_joint, p_trs_body_b),
p_swing,
p_twist,
*r_body_b_points);
+ }
}
void Joint3DGizmoPlugin::CreateGeneric6DOFJointGizmo(
@@ -4527,7 +4568,6 @@ void Joint3DGizmoPlugin::CreateGeneric6DOFJointGizmo(
Vector<Vector3> &r_points,
Vector<Vector3> *r_body_a_points,
Vector<Vector3> *r_body_b_points) {
-
float cs = 0.25;
for (int ax = 0; ax < 3; ax++) {
@@ -4588,7 +4628,6 @@ void Joint3DGizmoPlugin::CreateGeneric6DOFJointGizmo(
}
if (enable_lin && lll >= lul) {
-
ADD_VTX(lul, 0, 0);
ADD_VTX(lll, 0, 0);
@@ -4611,7 +4650,6 @@ void Joint3DGizmoPlugin::CreateGeneric6DOFJointGizmo(
ADD_VTX(lll, -cs, -cs);
} else {
-
ADD_VTX(+cs * 2, 0, 0);
ADD_VTX(-cs * 2, 0, 0);
}
@@ -4621,7 +4659,7 @@ void Joint3DGizmoPlugin::CreateGeneric6DOFJointGizmo(
ul = -1;
}
- if (r_body_a_points)
+ if (r_body_a_points) {
JointGizmosDrawer::draw_circle(
static_cast<Vector3::Axis>(ax),
BODY_A_RADIUS,
@@ -4631,8 +4669,9 @@ void Joint3DGizmoPlugin::CreateGeneric6DOFJointGizmo(
ul,
*r_body_a_points,
true);
+ }
- if (r_body_b_points)
+ if (r_body_b_points) {
JointGizmosDrawer::draw_circle(
static_cast<Vector3::Axis>(ax),
BODY_B_RADIUS,
@@ -4641,6 +4680,7 @@ void Joint3DGizmoPlugin::CreateGeneric6DOFJointGizmo(
ll,
ul,
*r_body_b_points);
+ }
}
#undef ADD_VTX
diff --git a/editor/node_3d_editor_gizmos.h b/editor/node_3d_editor_gizmos.h
index 8bc52b6ba9..8154dc7a6d 100644
--- a/editor/node_3d_editor_gizmos.h
+++ b/editor/node_3d_editor_gizmos.h
@@ -37,7 +37,6 @@
class Camera3D;
class Light3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(Light3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -55,7 +54,6 @@ public:
};
class AudioStreamPlayer3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(AudioStreamPlayer3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -73,7 +71,6 @@ public:
};
class Camera3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(Camera3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -91,7 +88,6 @@ public:
};
class MeshInstance3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(MeshInstance3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -105,7 +101,6 @@ public:
};
class Sprite3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(Sprite3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -119,7 +114,6 @@ public:
};
class Position3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(Position3DGizmoPlugin, EditorNode3DGizmoPlugin);
Ref<ArrayMesh> pos3d_mesh;
@@ -135,7 +129,6 @@ public:
};
class Skeleton3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(Skeleton3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -148,7 +141,6 @@ public:
};
class PhysicalBone3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(PhysicalBone3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -161,7 +153,6 @@ public:
};
class RayCast3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(RayCast3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -174,7 +165,6 @@ public:
};
class SpringArm3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(SpringArm3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -187,7 +177,6 @@ public:
};
class VehicleWheel3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(VehicleWheel3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -200,7 +189,6 @@ public:
};
class SoftBody3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(SoftBody3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -219,7 +207,6 @@ public:
};
class VisibilityNotifier3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(VisibilityNotifier3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -249,7 +236,6 @@ public:
};
class GPUParticles3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(GPUParticles3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -268,7 +254,6 @@ public:
};
class ReflectionProbeGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(ReflectionProbeGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -286,7 +271,6 @@ public:
};
class DecalGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(DecalGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -304,7 +288,6 @@ public:
};
class GIProbeGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(GIProbeGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -321,27 +304,41 @@ public:
GIProbeGizmoPlugin();
};
-#if 0
-class BakedIndirectLightGizmoPlugin : public EditorNode3DGizmoPlugin {
+class BakedLightmapGizmoPlugin : public EditorNode3DGizmoPlugin {
+ GDCLASS(BakedLightmapGizmoPlugin, EditorNode3DGizmoPlugin);
- GDCLASS(BakedIndirectLightGizmoPlugin, EditorNode3DGizmoPlugin);
+public:
+ bool has_gizmo(Node3D *p_spatial);
+ String get_name() const;
+ int get_priority() const;
+ void redraw(EditorNode3DGizmo *p_gizmo);
+
+ String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const;
+ Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const;
+ void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point);
+ void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
+
+ BakedLightmapGizmoPlugin();
+};
+
+class LightmapProbeGizmoPlugin : public EditorNode3DGizmoPlugin {
+ GDCLASS(LightmapProbeGizmoPlugin, EditorNode3DGizmoPlugin);
public:
- bool has_gizmo(Spatial *p_spatial);
+ bool has_gizmo(Node3D *p_spatial);
String get_name() const;
int get_priority() const;
void redraw(EditorNode3DGizmo *p_gizmo);
String get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const;
Variant get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const;
- void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
+ void set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point);
void commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
- BakedIndirectLightGizmoPlugin();
+ LightmapProbeGizmoPlugin();
};
-#endif
-class CollisionShape3DGizmoPlugin : public EditorNode3DGizmoPlugin {
+class CollisionShape3DGizmoPlugin : public EditorNode3DGizmoPlugin {
GDCLASS(CollisionShape3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
@@ -370,11 +367,9 @@ public:
};
class NavigationRegion3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(NavigationRegion3DGizmoPlugin, EditorNode3DGizmoPlugin);
struct _EdgeKey {
-
Vector3 from;
Vector3 to;
@@ -406,9 +401,13 @@ public:
};
class Joint3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(Joint3DGizmoPlugin, EditorNode3DGizmoPlugin);
+ Timer *update_timer;
+ uint64_t update_idx = 0;
+
+ void incremental_update_gizmos();
+
public:
bool has_gizmo(Node3D *p_spatial);
String get_name() const;
diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp
index a076b1eecc..9b9cfad9eb 100644
--- a/editor/node_dock.cpp
+++ b/editor/node_dock.cpp
@@ -34,7 +34,6 @@
#include "editor_scale.h"
void NodeDock::show_groups() {
-
groups_button->set_pressed(true);
connections_button->set_pressed(false);
groups->show();
@@ -42,7 +41,6 @@ void NodeDock::show_groups() {
}
void NodeDock::show_connections() {
-
groups_button->set_pressed(false);
connections_button->set_pressed(true);
groups->hide();
@@ -53,7 +51,6 @@ void NodeDock::_bind_methods() {
}
void NodeDock::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
connections_button->set_icon(get_theme_icon("Signals", "EditorIcons"));
groups_button->set_icon(get_theme_icon("Groups", "EditorIcons"));
@@ -63,20 +60,19 @@ void NodeDock::_notification(int p_what) {
NodeDock *NodeDock::singleton = nullptr;
void NodeDock::update_lists() {
-
connections->update_tree();
}
void NodeDock::set_node(Node *p_node) {
-
connections->set_node(p_node);
groups->set_current(p_node);
if (p_node) {
- if (connections_button->is_pressed())
+ if (connections_button->is_pressed()) {
connections->show();
- else
+ } else {
groups->show();
+ }
mode_hb->show();
select_a_node->hide();
@@ -89,7 +85,6 @@ void NodeDock::set_node(Node *p_node) {
}
NodeDock::NodeDock() {
-
singleton = this;
set_name("Node");
diff --git a/editor/node_dock.h b/editor/node_dock.h
index ae33c5b9a5..c165974678 100644
--- a/editor/node_dock.h
+++ b/editor/node_dock.h
@@ -35,7 +35,6 @@
#include "groups_editor.h"
class NodeDock : public VBoxContainer {
-
GDCLASS(NodeDock, VBoxContainer);
ToolButton *connections_button;
diff --git a/editor/pane_drag.cpp b/editor/pane_drag.cpp
index ce90fa94dc..09f2b90b90 100644
--- a/editor/pane_drag.cpp
+++ b/editor/pane_drag.cpp
@@ -31,23 +31,19 @@
#include "pane_drag.h"
void PaneDrag::_gui_input(const Ref<InputEvent> &p_input) {
-
Ref<InputEventMouseMotion> mm = p_input;
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
-
emit_signal("dragged", Point2(mm->get_relative().x, mm->get_relative().y));
}
}
void PaneDrag::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_DRAW: {
-
Ref<Texture2D> icon = mouse_over ? get_theme_icon("PaneDragHover", "EditorIcons") : get_theme_icon("PaneDrag", "EditorIcons");
- if (!icon.is_null())
+ if (!icon.is_null()) {
icon->draw(get_canvas_item(), Point2(0, 0));
+ }
} break;
case NOTIFICATION_MOUSE_ENTER:
@@ -60,21 +56,20 @@ void PaneDrag::_notification(int p_what) {
break;
}
}
-Size2 PaneDrag::get_minimum_size() const {
+Size2 PaneDrag::get_minimum_size() const {
Ref<Texture2D> icon = get_theme_icon("PaneDrag", "EditorIcons");
- if (!icon.is_null())
+ if (!icon.is_null()) {
return icon->get_size();
+ }
return Size2();
}
void PaneDrag::_bind_methods() {
-
ClassDB::bind_method("_gui_input", &PaneDrag::_gui_input);
ADD_SIGNAL(MethodInfo("dragged", PropertyInfo(Variant::VECTOR2, "amount")));
}
PaneDrag::PaneDrag() {
-
mouse_over = false;
}
diff --git a/editor/pane_drag.h b/editor/pane_drag.h
index 7e66bb429f..81aff4b2a8 100644
--- a/editor/pane_drag.h
+++ b/editor/pane_drag.h
@@ -34,7 +34,6 @@
#include "scene/gui/control.h"
class PaneDrag : public Control {
-
GDCLASS(PaneDrag, Control);
bool mouse_over;
diff --git a/editor/plugin_config_dialog.cpp b/editor/plugin_config_dialog.cpp
index 4317a5e80f..3ad6938498 100644
--- a/editor/plugin_config_dialog.cpp
+++ b/editor/plugin_config_dialog.cpp
@@ -52,13 +52,13 @@ void PluginConfigDialog::_clear_fields() {
}
void PluginConfigDialog::_on_confirmed() {
-
String path = "res://addons/" + subfolder_edit->get_text();
if (!_edit_mode) {
DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- if (!d || d->make_dir_recursive(path) != OK)
+ if (!d || d->make_dir_recursive(path) != OK) {
return;
+ }
}
Ref<ConfigFile> cf = memnew(ConfigFile);
diff --git a/editor/plugin_config_dialog.h b/editor/plugin_config_dialog.h
index fa148125bc..93c8c01c70 100644
--- a/editor/plugin_config_dialog.h
+++ b/editor/plugin_config_dialog.h
@@ -38,7 +38,6 @@
#include "scene/gui/text_edit.h"
class PluginConfigDialog : public ConfirmationDialog {
-
GDCLASS(PluginConfigDialog, ConfirmationDialog);
LineEdit *name_edit;
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index c26daa3857..1abba45f9e 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -34,132 +34,85 @@
#include "core/os/keyboard.h"
#include "editor/editor_scale.h"
-AbstractPolygon2DEditor::Vertex::Vertex() :
- polygon(-1),
- vertex(-1) {
- // invalid vertex
-}
-
-AbstractPolygon2DEditor::Vertex::Vertex(int p_vertex) :
- polygon(-1),
- vertex(p_vertex) {
- // vertex p_vertex of current wip polygon
-}
-
-AbstractPolygon2DEditor::Vertex::Vertex(int p_polygon, int p_vertex) :
- polygon(p_polygon),
- vertex(p_vertex) {
- // vertex p_vertex of polygon p_polygon
-}
-
bool AbstractPolygon2DEditor::Vertex::operator==(const AbstractPolygon2DEditor::Vertex &p_vertex) const {
-
return polygon == p_vertex.polygon && vertex == p_vertex.vertex;
}
bool AbstractPolygon2DEditor::Vertex::operator!=(const AbstractPolygon2DEditor::Vertex &p_vertex) const {
-
return !(*this == p_vertex);
}
bool AbstractPolygon2DEditor::Vertex::valid() const {
-
return vertex >= 0;
}
-AbstractPolygon2DEditor::PosVertex::PosVertex() {
- // invalid vertex
-}
-
-AbstractPolygon2DEditor::PosVertex::PosVertex(const Vertex &p_vertex, const Vector2 &p_pos) :
- Vertex(p_vertex.polygon, p_vertex.vertex),
- pos(p_pos) {
-}
-
-AbstractPolygon2DEditor::PosVertex::PosVertex(int p_polygon, int p_vertex, const Vector2 &p_pos) :
- Vertex(p_polygon, p_vertex),
- pos(p_pos) {
-}
-
bool AbstractPolygon2DEditor::_is_empty() const {
-
- if (!_get_node())
+ if (!_get_node()) {
return true;
+ }
const int n = _get_polygon_count();
for (int i = 0; i < n; i++) {
-
Vector<Vector2> vertices = _get_polygon(i);
- if (vertices.size() != 0)
+ if (vertices.size() != 0) {
return false;
+ }
}
return true;
}
bool AbstractPolygon2DEditor::_is_line() const {
-
return false;
}
bool AbstractPolygon2DEditor::_has_uv() const {
-
return false;
}
int AbstractPolygon2DEditor::_get_polygon_count() const {
-
return 1;
}
Variant AbstractPolygon2DEditor::_get_polygon(int p_idx) const {
-
return _get_node()->get("polygon");
}
void AbstractPolygon2DEditor::_set_polygon(int p_idx, const Variant &p_polygon) const {
-
_get_node()->set("polygon", p_polygon);
}
void AbstractPolygon2DEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) {
-
Node2D *node = _get_node();
undo_redo->add_do_method(node, "set_polygon", p_polygon);
undo_redo->add_undo_method(node, "set_polygon", p_previous);
}
Vector2 AbstractPolygon2DEditor::_get_offset(int p_idx) const {
-
return Vector2(0, 0);
}
void AbstractPolygon2DEditor::_commit_action() {
-
undo_redo->add_do_method(canvas_item_editor, "update_viewport");
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
undo_redo->commit_action();
}
void AbstractPolygon2DEditor::_action_add_polygon(const Variant &p_polygon) {
-
_action_set_polygon(0, p_polygon);
}
void AbstractPolygon2DEditor::_action_remove_polygon(int p_idx) {
-
_action_set_polygon(p_idx, _get_polygon(p_idx), Vector<Vector2>());
}
void AbstractPolygon2DEditor::_action_set_polygon(int p_idx, const Variant &p_polygon) {
-
_action_set_polygon(p_idx, _get_polygon(p_idx), p_polygon);
}
bool AbstractPolygon2DEditor::_has_resource() const {
-
return true;
}
@@ -167,18 +120,14 @@ void AbstractPolygon2DEditor::_create_resource() {
}
void AbstractPolygon2DEditor::_menu_option(int p_option) {
-
switch (p_option) {
-
case MODE_CREATE: {
-
mode = MODE_CREATE;
button_create->set_pressed(true);
button_edit->set_pressed(false);
button_delete->set_pressed(false);
} break;
case MODE_EDIT: {
-
_wip_close();
mode = MODE_EDIT;
button_create->set_pressed(false);
@@ -186,7 +135,6 @@ void AbstractPolygon2DEditor::_menu_option(int p_option) {
button_delete->set_pressed(false);
} break;
case MODE_DELETE: {
-
_wip_close();
mode = MODE_DELETE;
button_create->set_pressed(false);
@@ -197,11 +145,8 @@ void AbstractPolygon2DEditor::_menu_option(int p_option) {
}
void AbstractPolygon2DEditor::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_READY: {
-
disable_polygon_editing(false, String());
button_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("CurveCreate", "EditorIcons"));
@@ -216,7 +161,6 @@ void AbstractPolygon2DEditor::_notification(int p_what) {
}
void AbstractPolygon2DEditor::_node_removed(Node *p_node) {
-
if (p_node == _get_node()) {
edit(nullptr);
hide();
@@ -226,14 +170,12 @@ void AbstractPolygon2DEditor::_node_removed(Node *p_node) {
}
void AbstractPolygon2DEditor::_wip_changed() {
-
if (wip_active && _is_line()) {
_set_polygon(0, wip);
}
}
void AbstractPolygon2DEditor::_wip_cancel() {
-
wip.clear();
wip_active = false;
@@ -245,14 +187,13 @@ void AbstractPolygon2DEditor::_wip_cancel() {
}
void AbstractPolygon2DEditor::_wip_close() {
- if (!wip_active)
+ if (!wip_active) {
return;
+ }
if (_is_line()) {
-
_set_polygon(0, wip);
} else if (wip.size() >= (_is_line() ? 2 : 3)) {
-
undo_redo->create_action(TTR("Create Polygon"));
_action_add_polygon(wip);
if (_has_uv()) {
@@ -261,7 +202,6 @@ void AbstractPolygon2DEditor::_wip_close() {
}
_commit_action();
} else {
-
return;
}
@@ -279,7 +219,6 @@ void AbstractPolygon2DEditor::_wip_close() {
}
void AbstractPolygon2DEditor::disable_polygon_editing(bool p_disable, String p_reason) {
-
_polygon_editing_enabled = !p_disable;
button_create->set_disabled(p_disable);
@@ -287,12 +226,10 @@ void AbstractPolygon2DEditor::disable_polygon_editing(bool p_disable, String p_r
button_delete->set_disabled(p_disable);
if (p_disable) {
-
button_create->set_tooltip(p_reason);
button_edit->set_tooltip(p_reason);
button_delete->set_tooltip(p_reason);
} else {
-
button_create->set_tooltip(TTR("Create points."));
button_edit->set_tooltip(TTR("Edit points.\nLMB: Move Point\nRMB: Erase Point"));
button_delete->set_tooltip(TTR("Erase points."));
@@ -300,14 +237,13 @@ void AbstractPolygon2DEditor::disable_polygon_editing(bool p_disable, String p_r
}
bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
-
- if (!_get_node() || !_polygon_editing_enabled)
+ if (!_get_node() || !_polygon_editing_enabled) {
return false;
+ }
Ref<InputEventMouseButton> mb = p_event;
if (!_has_resource()) {
-
if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
create_resource->set_text(String("No polygon resource on this node.\nCreate and assign one?"));
create_resource->popup_centered();
@@ -316,11 +252,11 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
}
CanvasItemEditor::Tool tool = CanvasItemEditor::get_singleton()->get_current_tool();
- if (tool != CanvasItemEditor::TOOL_SELECT)
+ if (tool != CanvasItemEditor::TOOL_SELECT) {
return false;
+ }
if (mb.is_valid()) {
-
Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
Vector2 gpoint = mb->get_position();
@@ -329,17 +265,16 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
if (mode == MODE_EDIT || (_is_line() && mode == MODE_CREATE)) {
if (mb->get_button_index() == BUTTON_LEFT) {
if (mb->is_pressed()) {
- if (mb->get_control() || mb->get_shift() || mb->get_alt())
+ if (mb->get_control() || mb->get_shift() || mb->get_alt()) {
return false;
+ }
const PosVertex insert = closest_edge_point(gpoint);
if (insert.valid()) {
-
Vector<Vector2> vertices = _get_polygon(insert.polygon);
if (vertices.size() < (_is_line() ? 2 : 3)) {
-
vertices.push_back(cpoint);
undo_redo->create_action(TTR("Edit Polygon"));
selected_point = Vertex(insert.polygon, vertices.size());
@@ -347,7 +282,6 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
_commit_action();
return true;
} else {
-
Vector<Vector2> vertices2 = _get_polygon(insert.polygon);
pre_move_edit = vertices2;
edited_point = PosVertex(insert.polygon, insert.vertex + 1, xform.affine_inverse().xform(insert.pos));
@@ -361,12 +295,10 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
return true;
}
} else {
-
//look for points to move
const PosVertex closest = closest_point(gpoint);
if (closest.valid()) {
-
pre_move_edit = _get_polygon(closest.polygon);
edited_point = PosVertex(closest, xform.affine_inverse().xform(closest.pos));
selected_point = closest;
@@ -374,14 +306,11 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
canvas_item_editor->update_viewport();
return true;
} else {
-
selected_point = Vertex();
}
}
} else {
-
if (edited_point.valid()) {
-
//apply
Vector<Vector2> vertices = _get_polygon(edited_point.polygon);
@@ -397,23 +326,18 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
}
}
} else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && !edited_point.valid()) {
-
const PosVertex closest = closest_point(gpoint);
if (closest.valid()) {
-
remove_point(closest);
return true;
}
}
} else if (mode == MODE_DELETE) {
-
if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
-
const PosVertex closest = closest_point(gpoint);
if (closest.valid()) {
-
remove_point(closest);
return true;
}
@@ -421,11 +345,8 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
}
if (mode == MODE_CREATE) {
-
if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
-
if (_is_line()) {
-
// for lines, we don't have a wip mode, and we can undo each single add point.
Vector<Vector2> vertices = _get_polygon(0);
vertices.push_back(cpoint);
@@ -434,7 +355,6 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
_commit_action();
return true;
} else if (!wip_active) {
-
wip.clear();
wip.push_back(cpoint);
wip_active = true;
@@ -446,7 +366,6 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
edge_point = PosVertex();
return true;
} else {
-
const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
if (!_is_line() && wip.size() > 1 && xform.xform(wip[0]).distance_to(gpoint) < grab_threshold) {
@@ -455,7 +374,6 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
return true;
} else {
-
//add wip point
wip.push_back(cpoint);
_wip_changed();
@@ -474,11 +392,9 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
Vector2 gpoint = mm->get_position();
if (edited_point.valid() && (wip_active || (mm->get_button_mask() & BUTTON_MASK_LEFT))) {
-
Vector2 cpoint = _get_node()->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)));
//Move the point in a single axis. Should only work when editing a polygon and while holding shift.
@@ -494,7 +410,6 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
edited_point = PosVertex(edited_point, cpoint);
if (!wip_active) {
-
Vector<Vector2> vertices = _get_polygon(edited_point.polygon);
ERR_FAIL_INDEX_V(edited_point.vertex, vertices.size(), false);
vertices.write[edited_point.vertex] = cpoint - _get_offset(edited_point.polygon);
@@ -503,25 +418,20 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
canvas_item_editor->update_viewport();
} else if (mode == MODE_EDIT || (_is_line() && mode == MODE_CREATE)) {
-
const PosVertex onEdgeVertex = closest_edge_point(gpoint);
if (onEdgeVertex.valid()) {
-
hover_point = Vertex();
edge_point = onEdgeVertex;
canvas_item_editor->update_viewport();
} else {
-
if (edge_point.valid()) {
-
edge_point = PosVertex();
canvas_item_editor->update_viewport();
}
const PosVertex new_hover_point = closest_point(gpoint);
if (hover_point != new_hover_point) {
-
hover_point = new_hover_point;
canvas_item_editor->update_viewport();
}
@@ -532,13 +442,9 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed()) {
-
if (k->get_keycode() == KEY_DELETE || k->get_keycode() == KEY_BACKSPACE) {
-
if (wip_active && selected_point.polygon == -1) {
-
if (wip.size() > selected_point.vertex) {
-
wip.remove(selected_point.vertex);
_wip_changed();
selected_point = wip.size() - 1;
@@ -546,17 +452,14 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
return true;
}
} else {
-
const Vertex active_point = get_active_point();
if (active_point.valid()) {
-
remove_point(active_point);
return true;
}
}
} else if (wip_active && k->get_keycode() == KEY_ENTER) {
-
_wip_close();
} else if (wip_active && k->get_keycode() == KEY_ESCAPE) {
_wip_cancel();
@@ -567,9 +470,9 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
}
void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
-
- if (!_get_node())
+ if (!_get_node()) {
return;
+ }
Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
// All polygon points are sharp, so use the sharp handle icon
@@ -580,31 +483,28 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
const bool is_closed = !_is_line();
for (int j = -1; j < n_polygons; j++) {
-
- if (wip_active && wip_destructive && j != -1)
+ if (wip_active && wip_destructive && j != -1) {
continue;
+ }
Vector<Vector2> points;
Vector2 offset;
if (wip_active && j == edited_point.polygon) {
-
points = Variant(wip);
offset = Vector2(0, 0);
} else {
-
- if (j == -1)
+ if (j == -1) {
continue;
+ }
points = _get_polygon(j);
offset = _get_offset(j);
}
if (!wip_active && j == edited_point.polygon && EDITOR_GET("editors/poly_editor/show_previous_outline")) {
-
const Color col = Color(0.5, 0.5, 0.5); // FIXME polygon->get_outline_color();
const int n = pre_move_edit.size();
for (int i = 0; i < n - (is_closed ? 0 : 1); i++) {
-
Vector2 p, p2;
p = pre_move_edit[i] + offset;
p2 = pre_move_edit[(i + 1) % n] + offset;
@@ -620,20 +520,19 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
const Color col = Color(1, 0.3, 0.1, 0.8);
for (int i = 0; i < n_points; i++) {
-
const Vertex vertex(j, i);
const Vector2 p = (vertex == edited_point) ? edited_point.pos : (points[i] + offset);
const Vector2 point = xform.xform(p);
if (is_closed || i < n_points - 1) {
-
Vector2 p2;
if (j == edited_point.polygon &&
- ((wip_active && i == n_points - 1) || (((i + 1) % n_points) == edited_point.vertex)))
+ ((wip_active && i == n_points - 1) || (((i + 1) % n_points) == edited_point.vertex))) {
p2 = edited_point.pos;
- else
+ } else {
p2 = points[(i + 1) % n_points] + offset;
+ }
const Vector2 next_point = xform.xform(p2);
p_overlay->draw_line(point, next_point, col, Math::round(2 * EDSCALE));
@@ -641,7 +540,6 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
}
for (int i = 0; i < n_points; i++) {
-
const Vertex vertex(j, i);
const Vector2 p = (vertex == edited_point) ? edited_point.pos : (points[i] + offset);
@@ -660,26 +558,25 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
}
if (edge_point.valid()) {
-
Ref<Texture2D> add_handle = get_theme_icon("EditorHandleAdd", "EditorIcons");
p_overlay->draw_texture(add_handle, edge_point.pos - add_handle->get_size() * 0.5);
}
}
void AbstractPolygon2DEditor::edit(Node *p_polygon) {
-
- if (!canvas_item_editor)
+ if (!canvas_item_editor) {
canvas_item_editor = CanvasItemEditor::get_singleton();
+ }
if (p_polygon) {
-
_set_node(p_polygon);
// Enable the pencil tool if the polygon is empty.
- if (_is_empty())
+ if (_is_empty()) {
_menu_option(MODE_CREATE);
- else
+ } else {
_menu_option(MODE_EDIT);
+ }
wip.clear();
wip_active = false;
@@ -689,7 +586,6 @@ void AbstractPolygon2DEditor::edit(Node *p_polygon) {
canvas_item_editor->update_viewport();
} else {
-
_set_node(nullptr);
}
}
@@ -698,38 +594,35 @@ void AbstractPolygon2DEditor::_bind_methods() {
}
void AbstractPolygon2DEditor::remove_point(const Vertex &p_vertex) {
-
Vector<Vector2> vertices = _get_polygon(p_vertex.polygon);
if (vertices.size() > (_is_line() ? 2 : 3)) {
-
vertices.remove(p_vertex.vertex);
undo_redo->create_action(TTR("Edit Polygon (Remove Point)"));
_action_set_polygon(p_vertex.polygon, vertices);
_commit_action();
} else {
-
undo_redo->create_action(TTR("Remove Polygon And Point"));
_action_remove_polygon(p_vertex.polygon);
_commit_action();
}
- if (_is_empty())
+ if (_is_empty()) {
_menu_option(MODE_CREATE);
+ }
hover_point = Vertex();
- if (selected_point == p_vertex)
+ if (selected_point == p_vertex) {
selected_point = Vertex();
+ }
}
AbstractPolygon2DEditor::Vertex AbstractPolygon2DEditor::get_active_point() const {
-
return hover_point.valid() ? hover_point : selected_point;
}
AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_point(const Vector2 &p_pos) const {
-
const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
const int n_polygons = _get_polygon_count();
@@ -739,13 +632,11 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_point(const
real_t closest_dist = 1e10;
for (int j = 0; j < n_polygons; j++) {
-
Vector<Vector2> points = _get_polygon(j);
const Vector2 offset = _get_offset(j);
const int n_points = points.size();
for (int i = 0; i < n_points; i++) {
-
Vector2 cp = xform.xform(points[i] + offset);
real_t d = cp.distance_to(p_pos);
@@ -760,7 +651,6 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_point(const
}
AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(const Vector2 &p_pos) const {
-
const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
const real_t eps = grab_threshold * 2;
const real_t eps2 = eps * eps;
@@ -772,21 +662,20 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(c
real_t closest_dist = 1e10;
for (int j = 0; j < n_polygons; j++) {
-
Vector<Vector2> points = _get_polygon(j);
const Vector2 offset = _get_offset(j);
const int n_points = points.size();
const int n_segments = n_points - (_is_line() ? 1 : 0);
for (int i = 0; i < n_segments; i++) {
-
Vector2 segment[2] = { xform.xform(points[i] + offset),
xform.xform(points[(i + 1) % n_points] + offset) };
Vector2 cp = Geometry::get_closest_point_to_segment_2d(p_pos, segment);
- if (cp.distance_squared_to(segment[0]) < eps2 || cp.distance_squared_to(segment[1]) < eps2)
+ if (cp.distance_squared_to(segment[0]) < eps2 || cp.distance_squared_to(segment[1]) < eps2) {
continue; //not valid to reuse point
+ }
real_t d = cp.distance_to(p_pos);
if (d < closest_dist && d < grab_threshold) {
@@ -800,7 +689,6 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(c
}
AbstractPolygon2DEditor::AbstractPolygon2DEditor(EditorNode *p_editor, bool p_wip_destructive) {
-
canvas_item_editor = nullptr;
editor = p_editor;
undo_redo = EditorNode::get_undo_redo();
@@ -837,22 +725,17 @@ AbstractPolygon2DEditor::AbstractPolygon2DEditor(EditorNode *p_editor, bool p_wi
}
void AbstractPolygon2DEditorPlugin::edit(Object *p_object) {
-
polygon_editor->edit(Object::cast_to<Node>(p_object));
}
bool AbstractPolygon2DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class(klass);
}
void AbstractPolygon2DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
-
polygon_editor->show();
} else {
-
polygon_editor->hide();
polygon_editor->edit(nullptr);
}
diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h
index 6ed6d0a257..d5b3a916d1 100644
--- a/editor/plugins/abstract_polygon_2d_editor.h
+++ b/editor/plugins/abstract_polygon_2d_editor.h
@@ -39,7 +39,6 @@
class CanvasItemEditor;
class AbstractPolygon2DEditor : public HBoxContainer {
-
GDCLASS(AbstractPolygon2DEditor, HBoxContainer);
ToolButton *button_create;
@@ -47,23 +46,30 @@ class AbstractPolygon2DEditor : public HBoxContainer {
ToolButton *button_delete;
struct Vertex {
- Vertex();
- Vertex(int p_vertex);
- Vertex(int p_polygon, int p_vertex);
+ Vertex() {}
+ Vertex(int p_vertex) :
+ vertex(p_vertex) {}
+ Vertex(int p_polygon, int p_vertex) :
+ polygon(p_polygon),
+ vertex(p_vertex) {}
bool operator==(const Vertex &p_vertex) const;
bool operator!=(const Vertex &p_vertex) const;
bool valid() const;
- int polygon;
- int vertex;
+ int polygon = -1;
+ int vertex = -1;
};
struct PosVertex : public Vertex {
- PosVertex();
- PosVertex(const Vertex &p_vertex, const Vector2 &p_pos);
- PosVertex(int p_polygon, int p_vertex, const Vector2 &p_pos);
+ PosVertex() {}
+ PosVertex(const Vertex &p_vertex, const Vector2 &p_pos) :
+ Vertex(p_vertex.polygon, p_vertex.vertex),
+ pos(p_pos) {}
+ PosVertex(int p_polygon, int p_vertex, const Vector2 &p_pos) :
+ Vertex(p_polygon, p_vertex),
+ pos(p_pos) {}
Vector2 pos;
};
@@ -144,7 +150,6 @@ public:
};
class AbstractPolygon2DEditorPlugin : public EditorPlugin {
-
GDCLASS(AbstractPolygon2DEditorPlugin, EditorPlugin);
AbstractPolygon2DEditor *polygon_editor;
diff --git a/editor/plugins/animation_blend_space_1d_editor.cpp b/editor/plugins/animation_blend_space_1d_editor.cpp
index eb50df2166..75eacf56ec 100644
--- a/editor/plugins/animation_blend_space_1d_editor.cpp
+++ b/editor/plugins/animation_blend_space_1d_editor.cpp
@@ -81,8 +81,9 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
for (List<StringName>::Element *E = classes.front(); E; E = E->next()) {
String name = String(E->get()).replace_first("AnimationNode", "");
- if (name == "Animation")
+ if (name == "Animation") {
continue;
+ }
int idx = menu->get_item_count();
menu->add_item(vformat("Add %s", name), idx);
@@ -117,7 +118,6 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
_update_tool_erase();
for (int i = 0; i < points.size(); i++) {
-
if (Math::abs(float(points[i] - mb->get_position().x)) < 10 * EDSCALE) {
selected_point = i;
@@ -196,7 +196,6 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_gui_input(const Ref<InputEven
}
void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
-
Color linecolor = get_theme_color("font_color", "Label");
Color linecolor_soft = linecolor;
linecolor_soft.a *= 0.5;
@@ -227,7 +226,6 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
}
if (snap->is_pressed()) {
-
linecolor_soft.a = linecolor.a * 0.1;
if (blend_space->get_snap() > 0) {
@@ -303,9 +301,9 @@ void AnimationNodeBlendSpace1DEditor::_blend_space_draw() {
}
void AnimationNodeBlendSpace1DEditor::_update_space() {
-
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
@@ -322,8 +320,9 @@ void AnimationNodeBlendSpace1DEditor::_update_space() {
}
void AnimationNodeBlendSpace1DEditor::_config_changed(double) {
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
undo_redo->create_action(TTR("Change BlendSpace1D Limits"));
@@ -342,8 +341,9 @@ void AnimationNodeBlendSpace1DEditor::_config_changed(double) {
}
void AnimationNodeBlendSpace1DEditor::_labels_changed(String) {
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
undo_redo->create_action(TTR("Change BlendSpace1D Labels"), UndoRedo::MERGE_ENDS);
@@ -360,7 +360,6 @@ void AnimationNodeBlendSpace1DEditor::_snap_toggled() {
}
void AnimationNodeBlendSpace1DEditor::_file_opened(const String &p_file) {
-
file_loaded = ResourceLoader::load(p_file);
if (file_loaded.is_valid()) {
_add_menu_type(MENU_LOAD_FILE_CONFIRM);
@@ -370,7 +369,6 @@ void AnimationNodeBlendSpace1DEditor::_file_opened(const String &p_file) {
void AnimationNodeBlendSpace1DEditor::_add_menu_type(int p_index) {
Ref<AnimationRootNode> node;
if (p_index == MENU_LOAD_FILE) {
-
open_file->clear_filters();
List<String> filters;
ResourceLoader::get_recognized_extensions_for_type("AnimationRootNode", &filters);
@@ -383,7 +381,6 @@ void AnimationNodeBlendSpace1DEditor::_add_menu_type(int p_index) {
node = file_loaded;
file_loaded.unref();
} else if (p_index == MENU_PASTE) {
-
node = EditorSettings::get_singleton()->get_resource_clipboard();
} else {
String type = menu->get_item_metadata(p_index);
@@ -432,7 +429,6 @@ void AnimationNodeBlendSpace1DEditor::_add_animation_type(int p_index) {
}
void AnimationNodeBlendSpace1DEditor::_tool_switch(int p_tool) {
-
if (p_tool == 0) {
tool_erase->show();
tool_erase_sep->show();
@@ -446,8 +442,9 @@ void AnimationNodeBlendSpace1DEditor::_tool_switch(int p_tool) {
}
void AnimationNodeBlendSpace1DEditor::_update_edited_point_pos() {
- if (updating)
+ if (updating) {
return;
+ }
if (selected_point >= 0 && selected_point < blend_space->get_blend_point_count()) {
float pos = blend_space->get_blend_point_position(selected_point);
@@ -467,7 +464,6 @@ void AnimationNodeBlendSpace1DEditor::_update_edited_point_pos() {
}
void AnimationNodeBlendSpace1DEditor::_update_tool_erase() {
-
bool point_valid = selected_point >= 0 && selected_point < blend_space->get_blend_point_count();
tool_erase->set_disabled(!point_valid);
@@ -504,8 +500,9 @@ void AnimationNodeBlendSpace1DEditor::_erase_selected() {
}
void AnimationNodeBlendSpace1DEditor::_edit_point_pos(double) {
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
undo_redo->create_action(TTR("Move BlendSpace1D Node Point"));
@@ -522,7 +519,6 @@ void AnimationNodeBlendSpace1DEditor::_edit_point_pos(double) {
}
void AnimationNodeBlendSpace1DEditor::_open_editor() {
-
if (selected_point >= 0 && selected_point < blend_space->get_blend_point_count()) {
Ref<AnimationNode> an = blend_space->get_blend_point_node(selected_point);
ERR_FAIL_COND(an.is_null());
@@ -575,13 +571,11 @@ void AnimationNodeBlendSpace1DEditor::_bind_methods() {
}
bool AnimationNodeBlendSpace1DEditor::can_edit(const Ref<AnimationNode> &p_node) {
-
Ref<AnimationNodeBlendSpace1D> b1d = p_node;
return b1d.is_valid();
}
void AnimationNodeBlendSpace1DEditor::edit(const Ref<AnimationNode> &p_node) {
-
blend_space = p_node;
if (!blend_space.is_null()) {
diff --git a/editor/plugins/animation_blend_space_1d_editor.h b/editor/plugins/animation_blend_space_1d_editor.h
index 346ad36cff..8cfd6714ad 100644
--- a/editor/plugins/animation_blend_space_1d_editor.h
+++ b/editor/plugins/animation_blend_space_1d_editor.h
@@ -42,7 +42,6 @@
#include "scene/gui/tree.h"
class AnimationNodeBlendSpace1DEditor : public AnimationTreeNodeEditorPlugin {
-
GDCLASS(AnimationNodeBlendSpace1DEditor, AnimationTreeNodeEditorPlugin);
Ref<AnimationNodeBlendSpace1D> blend_space;
diff --git a/editor/plugins/animation_blend_space_2d_editor.cpp b/editor/plugins/animation_blend_space_2d_editor.cpp
index 4343535eb6..df67482dfb 100644
--- a/editor/plugins/animation_blend_space_2d_editor.cpp
+++ b/editor/plugins/animation_blend_space_2d_editor.cpp
@@ -30,9 +30,9 @@
#include "animation_blend_space_2d_editor.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/resource_loader.h"
-#include "core/math/delaunay.h"
+#include "core/math/delaunay_2d.h"
#include "core/os/keyboard.h"
#include "core/project_settings.h"
#include "editor/editor_scale.h"
@@ -43,7 +43,6 @@
#include "scene/main/window.h"
bool AnimationNodeBlendSpace2DEditor::can_edit(const Ref<AnimationNode> &p_node) {
-
Ref<AnimationNodeBlendSpace2D> bs2d = p_node;
return bs2d.is_valid();
}
@@ -53,7 +52,6 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_changed() {
}
void AnimationNodeBlendSpace2DEditor::edit(const Ref<AnimationNode> &p_node) {
-
if (blend_space.is_valid()) {
blend_space->disconnect("triangles_updated", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_blend_space_changed));
}
@@ -71,7 +69,6 @@ StringName AnimationNodeBlendSpace2DEditor::get_blend_position_path() const {
}
void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventKey> k = p_event;
if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->get_keycode() == KEY_DELETE && !k->is_echo()) {
if (selected_point != -1 || selected_triangle != -1) {
@@ -107,10 +104,10 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
}
for (List<StringName>::Element *E = classes.front(); E; E = E->next()) {
-
String name = String(E->get()).replace_first("AnimationNode", "");
- if (name == "Animation")
+ if (name == "Animation") {
continue; // nope
+ }
int idx = menu->get_item_count();
menu->add_item(vformat("Add %s", name), idx);
menu->set_item_metadata(idx, E->get());
@@ -138,7 +135,6 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
}
if (mb.is_valid() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
blend_space_draw->update(); //update anyway
//try to see if a point can be selected
selected_point = -1;
@@ -146,7 +142,6 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
_update_tool_erase();
for (int i = 0; i < points.size(); i++) {
-
if (points[i].distance_to(mb->get_position()) < 10 * EDSCALE) {
selected_point = i;
Ref<AnimationNode> node = blend_space->get_blend_point_node(i);
@@ -180,15 +175,14 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
}
if (mb.is_valid() && mb->is_pressed() && tool_triangle->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
blend_space_draw->update(); //update anyway
//try to see if a point can be selected
selected_point = -1;
for (int i = 0; i < points.size(); i++) {
-
- if (making_triangle.find(i) != -1)
+ if (making_triangle.find(i) != -1) {
continue;
+ }
if (points[i].distance_to(mb->get_position()) < 10 * EDSCALE) {
making_triangle.push_back(i);
@@ -243,7 +237,6 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
}
if (mb.is_valid() && mb->is_pressed() && tool_blend->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
Vector2 blend_pos = (mb->get_position() / blend_space_draw->get_size());
blend_pos.y = 1.0 - blend_pos.y;
blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space());
@@ -278,7 +271,6 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
}
if (mm.is_valid() && tool_blend->is_pressed() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
-
Vector2 blend_pos = (mm->get_position() / blend_space_draw->get_size());
blend_pos.y = 1.0 - blend_pos.y;
blend_pos *= (blend_space->get_max_space() - blend_space->get_min_space());
@@ -291,7 +283,6 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_gui_input(const Ref<InputEven
}
void AnimationNodeBlendSpace2DEditor::_file_opened(const String &p_file) {
-
file_loaded = ResourceLoader::load(p_file);
if (file_loaded.is_valid()) {
_add_menu_type(MENU_LOAD_FILE_CONFIRM);
@@ -299,10 +290,8 @@ void AnimationNodeBlendSpace2DEditor::_file_opened(const String &p_file) {
}
void AnimationNodeBlendSpace2DEditor::_add_menu_type(int p_index) {
-
Ref<AnimationRootNode> node;
if (p_index == MENU_LOAD_FILE) {
-
open_file->clear_filters();
List<String> filters;
ResourceLoader::get_recognized_extensions_for_type("AnimationRootNode", &filters);
@@ -315,7 +304,6 @@ void AnimationNodeBlendSpace2DEditor::_add_menu_type(int p_index) {
node = file_loaded;
file_loaded.unref();
} else if (p_index == MENU_PASTE) {
-
node = EditorSettings::get_singleton()->get_resource_clipboard();
} else {
String type = menu->get_item_metadata(p_index);
@@ -346,7 +334,6 @@ void AnimationNodeBlendSpace2DEditor::_add_menu_type(int p_index) {
}
void AnimationNodeBlendSpace2DEditor::_add_animation_type(int p_index) {
-
Ref<AnimationNodeAnimation> anim;
anim.instance();
@@ -405,7 +392,6 @@ void AnimationNodeBlendSpace2DEditor::_tool_switch(int p_tool) {
}
void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
-
Color linecolor = get_theme_color("font_color", "Label");
Color linecolor_soft = linecolor;
linecolor_soft.a *= 0.5;
@@ -438,14 +424,11 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
}
if (snap->is_pressed()) {
-
linecolor_soft.a = linecolor.a * 0.1;
if (blend_space->get_snap().x > 0) {
-
int prev_idx = 0;
for (int i = 0; i < s.x; i++) {
-
float v = blend_space->get_min_space().x + i * (blend_space->get_max_space().x - blend_space->get_min_space().x) / s.x;
int idx = int(v / blend_space->get_snap().x);
@@ -458,10 +441,8 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
}
if (blend_space->get_snap().y > 0) {
-
int prev_idx = 0;
for (int i = 0; i < s.y; i++) {
-
float v = blend_space->get_max_space().y - i * (blend_space->get_max_space().y - blend_space->get_min_space().y) / s.y;
int idx = int(v / blend_space->get_snap().y);
@@ -476,7 +457,6 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
//triangles first
for (int i = 0; i < blend_space->get_triangle_count(); i++) {
-
Vector<Vector2> points;
points.resize(3);
@@ -518,7 +498,6 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
points.clear();
for (int i = 0; i < blend_space->get_blend_point_count(); i++) {
-
Vector2 point = blend_space->get_blend_point_position(i);
if (dragging_selected && selected_point == i) {
point += drag_ofs;
@@ -597,14 +576,13 @@ void AnimationNodeBlendSpace2DEditor::_blend_space_draw() {
}
void AnimationNodeBlendSpace2DEditor::_snap_toggled() {
-
blend_space_draw->update();
}
void AnimationNodeBlendSpace2DEditor::_update_space() {
-
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
@@ -636,8 +614,9 @@ void AnimationNodeBlendSpace2DEditor::_update_space() {
}
void AnimationNodeBlendSpace2DEditor::_config_changed(double) {
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
undo_redo->create_action(TTR("Change BlendSpace2D Limits"));
@@ -658,8 +637,9 @@ void AnimationNodeBlendSpace2DEditor::_config_changed(double) {
}
void AnimationNodeBlendSpace2DEditor::_labels_changed(String) {
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
undo_redo->create_action(TTR("Change BlendSpace2D Labels"), UndoRedo::MERGE_ENDS);
@@ -674,9 +654,7 @@ void AnimationNodeBlendSpace2DEditor::_labels_changed(String) {
}
void AnimationNodeBlendSpace2DEditor::_erase_selected() {
-
if (selected_point != -1) {
-
updating = true;
undo_redo->create_action(TTR("Remove BlendSpace2D Point"));
undo_redo->add_do_method(blend_space.ptr(), "remove_blend_point", selected_point);
@@ -699,7 +677,6 @@ void AnimationNodeBlendSpace2DEditor::_erase_selected() {
blend_space_draw->update();
} else if (selected_triangle != -1) {
-
updating = true;
undo_redo->create_action(TTR("Remove BlendSpace2D Triangle"));
undo_redo->add_do_method(blend_space.ptr(), "remove_triangle", selected_triangle);
@@ -715,8 +692,9 @@ void AnimationNodeBlendSpace2DEditor::_erase_selected() {
}
void AnimationNodeBlendSpace2DEditor::_update_edited_point_pos() {
- if (updating)
+ if (updating) {
return;
+ }
if (selected_point >= 0 && selected_point < blend_space->get_blend_point_count()) {
Vector2 pos = blend_space->get_blend_point_position(selected_point);
@@ -735,8 +713,9 @@ void AnimationNodeBlendSpace2DEditor::_update_edited_point_pos() {
}
void AnimationNodeBlendSpace2DEditor::_edit_point_pos(double) {
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
undo_redo->create_action(TTR("Move Node Point"));
undo_redo->add_do_method(blend_space.ptr(), "set_blend_point_position", selected_point, Vector2(edit_x->get_value(), edit_y->get_value()));
@@ -752,7 +731,6 @@ void AnimationNodeBlendSpace2DEditor::_edit_point_pos(double) {
}
void AnimationNodeBlendSpace2DEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
error_panel->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree"));
error_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor"));
@@ -772,7 +750,6 @@ void AnimationNodeBlendSpace2DEditor::_notification(int p_what) {
}
if (p_what == NOTIFICATION_PROCESS) {
-
String error;
if (!AnimationTreeEditor::get_singleton()->get_tree()) {
@@ -801,7 +778,6 @@ void AnimationNodeBlendSpace2DEditor::_notification(int p_what) {
}
void AnimationNodeBlendSpace2DEditor::_open_editor() {
-
if (selected_point >= 0 && selected_point < blend_space->get_blend_point_count()) {
Ref<AnimationNode> an = blend_space->get_blend_point_node(selected_point);
ERR_FAIL_COND(an.is_null());
@@ -814,7 +790,6 @@ void AnimationNodeBlendSpace2DEditor::_removed_from_graph() {
}
void AnimationNodeBlendSpace2DEditor::_auto_triangles_toggled() {
-
undo_redo->create_action(TTR("Toggle Auto Triangles"));
undo_redo->add_do_method(blend_space.ptr(), "set_auto_triangles", auto_triangles->is_pressed());
undo_redo->add_undo_method(blend_space.ptr(), "set_auto_triangles", blend_space->get_auto_triangles());
@@ -824,7 +799,6 @@ void AnimationNodeBlendSpace2DEditor::_auto_triangles_toggled() {
}
void AnimationNodeBlendSpace2DEditor::_bind_methods() {
-
ClassDB::bind_method("_update_space", &AnimationNodeBlendSpace2DEditor::_update_space);
ClassDB::bind_method("_update_tool_erase", &AnimationNodeBlendSpace2DEditor::_update_tool_erase);
@@ -836,7 +810,6 @@ void AnimationNodeBlendSpace2DEditor::_bind_methods() {
AnimationNodeBlendSpace2DEditor *AnimationNodeBlendSpace2DEditor::singleton = nullptr;
AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
-
singleton = this;
updating = false;
diff --git a/editor/plugins/animation_blend_space_2d_editor.h b/editor/plugins/animation_blend_space_2d_editor.h
index 50b0d9a06c..b430a12297 100644
--- a/editor/plugins/animation_blend_space_2d_editor.h
+++ b/editor/plugins/animation_blend_space_2d_editor.h
@@ -42,7 +42,6 @@
#include "scene/gui/tree.h"
class AnimationNodeBlendSpace2DEditor : public AnimationTreeNodeEditorPlugin {
-
GDCLASS(AnimationNodeBlendSpace2DEditor, AnimationTreeNodeEditorPlugin);
Ref<AnimationNodeBlendSpace2D> blend_space;
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 54c60aba71..82d942821f 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -30,7 +30,7 @@
#include "animation_blend_tree_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/resource_loader.h"
#include "core/os/keyboard.h"
#include "core/project_settings.h"
@@ -43,7 +43,6 @@
#include "scene/main/window.h"
void AnimationNodeBlendTreeEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script) {
-
for (int i = 0; i < add_options.size(); i++) {
ERR_FAIL_COND(add_options[i].script == p_script);
}
@@ -57,7 +56,6 @@ void AnimationNodeBlendTreeEditor::add_custom_type(const String &p_name, const R
}
void AnimationNodeBlendTreeEditor::remove_custom_type(const Ref<Script> &p_script) {
-
for (int i = 0; i < add_options.size(); i++) {
if (add_options[i].script == p_script) {
add_options.remove(i);
@@ -69,7 +67,6 @@ void AnimationNodeBlendTreeEditor::remove_custom_type(const Ref<Script> &p_scrip
}
void AnimationNodeBlendTreeEditor::_update_options_menu() {
-
add_node->get_popup()->clear();
for (int i = 0; i < add_options.size(); i++) {
add_node->get_popup()->add_item(add_options[i].name, i);
@@ -86,12 +83,10 @@ void AnimationNodeBlendTreeEditor::_update_options_menu() {
}
Size2 AnimationNodeBlendTreeEditor::get_minimum_size() const {
-
return Size2(10, 200);
}
void AnimationNodeBlendTreeEditor::_property_changed(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing) {
-
AnimationTree *tree = AnimationTreeEditor::get_singleton()->get_tree();
updating = true;
undo_redo->create_action(TTR("Parameter Changed") + ": " + String(p_property), UndoRedo::MERGE_ENDS);
@@ -104,9 +99,9 @@ void AnimationNodeBlendTreeEditor::_property_changed(const StringName &p_propert
}
void AnimationNodeBlendTreeEditor::_update_graph() {
-
- if (updating)
+ if (updating) {
return;
+ }
visible_properties.clear();
@@ -115,7 +110,6 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
graph->clear_connections();
//erase all nodes
for (int i = 0; i < graph->get_child_count(); i++) {
-
if (Object::cast_to<GraphNode>(graph->get_child(i))) {
memdelete(graph->get_child(i));
i--;
@@ -128,7 +122,6 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
blend_tree->get_node_list(&nodes);
for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) {
-
GraphNode *node = memnew(GraphNode);
graph->add_child(node);
@@ -163,7 +156,6 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
List<PropertyInfo> pinfo;
agnode->get_parameter_list(&pinfo);
for (List<PropertyInfo>::Element *F = pinfo.front(); F; F = F->next()) {
-
if (!(F->get().usage & PROPERTY_USAGE_EDITOR)) {
continue;
}
@@ -192,7 +184,6 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
}
if (agnode->has_filter()) {
-
node->add_child(memnew(HSeparator));
Button *edit_filters = memnew(Button);
edit_filters->set_text(TTR("Edit Filters"));
@@ -204,7 +195,6 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
Ref<AnimationNodeAnimation> anim = agnode;
if (anim.is_valid()) {
-
MenuButton *mb = memnew(MenuButton);
mb->set_text(anim->get_animation());
mb->set_icon(get_theme_icon("Animation", "EditorIcons"));
@@ -259,7 +249,6 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
blend_tree->get_node_connections(&connections);
for (List<AnimationNodeBlendTree::NodeConnection>::Element *E = connections.front(); E; E = E->next()) {
-
StringName from = E->get().output_node;
StringName to = E->get().input_node;
int to_idx = E->get().input_index;
@@ -269,7 +258,6 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
}
void AnimationNodeBlendTreeEditor::_file_opened(const String &p_file) {
-
file_loaded = ResourceLoader::load(p_file);
if (file_loaded.is_valid()) {
_add_node(MENU_LOAD_FILE_CONFIRM);
@@ -277,13 +265,11 @@ void AnimationNodeBlendTreeEditor::_file_opened(const String &p_file) {
}
void AnimationNodeBlendTreeEditor::_add_node(int p_idx) {
-
Ref<AnimationNode> anode;
String base_name;
if (p_idx == MENU_LOAD_FILE) {
-
open_file->clear_filters();
List<String> filters;
ResourceLoader::get_recognized_extensions_for_type("AnimationNode", &filters);
@@ -297,7 +283,6 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) {
file_loaded.unref();
base_name = anode->get_class();
} else if (p_idx == MENU_PASTE) {
-
anode = EditorSettings::get_singleton()->get_resource_clipboard();
ERR_FAIL_COND(!anode.is_valid());
base_name = anode->get_class();
@@ -347,7 +332,6 @@ void AnimationNodeBlendTreeEditor::_add_node(int p_idx) {
}
void AnimationNodeBlendTreeEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, const StringName &p_which) {
-
updating = true;
undo_redo->create_action(TTR("Node Moved"));
undo_redo->add_do_method(blend_tree.ptr(), "set_node_position", p_which, p_to / EDSCALE);
@@ -359,7 +343,6 @@ void AnimationNodeBlendTreeEditor::_node_dragged(const Vector2 &p_from, const Ve
}
void AnimationNodeBlendTreeEditor::_connection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index) {
-
AnimationNodeBlendTree::ConnectionError err = blend_tree->can_connect_node(p_to, p_to_index, p_from);
if (err != AnimationNodeBlendTree::CONNECTION_OK) {
@@ -376,7 +359,6 @@ void AnimationNodeBlendTreeEditor::_connection_request(const String &p_from, int
}
void AnimationNodeBlendTreeEditor::_disconnection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index) {
-
graph->disconnect_node(p_from, p_from_index, p_to, p_to_index);
updating = true;
@@ -390,7 +372,6 @@ void AnimationNodeBlendTreeEditor::_disconnection_request(const String &p_from,
}
void AnimationNodeBlendTreeEditor::_anim_selected(int p_index, Array p_options, const String &p_node) {
-
String option = p_options[p_index];
Ref<AnimationNodeAnimation> anim = blend_tree->get_node(p_node);
@@ -405,7 +386,6 @@ void AnimationNodeBlendTreeEditor::_anim_selected(int p_index, Array p_options,
}
void AnimationNodeBlendTreeEditor::_delete_request(const String &p_which) {
-
undo_redo->create_action(TTR("Delete Node"));
undo_redo->add_do_method(blend_tree.ptr(), "remove_node", p_which);
undo_redo->add_undo_method(blend_tree.ptr(), "add_node", p_which, blend_tree->get_node(p_which), blend_tree.ptr()->get_node_position(p_which));
@@ -425,7 +405,6 @@ void AnimationNodeBlendTreeEditor::_delete_request(const String &p_which) {
}
void AnimationNodeBlendTreeEditor::_delete_nodes_request() {
-
List<StringName> to_erase;
for (int i = 0; i < graph->get_child_count(); i++) {
@@ -437,8 +416,9 @@ void AnimationNodeBlendTreeEditor::_delete_nodes_request() {
}
}
- if (to_erase.empty())
+ if (to_erase.empty()) {
return;
+ }
undo_redo->create_action(TTR("Delete Node(s)"));
@@ -450,7 +430,6 @@ void AnimationNodeBlendTreeEditor::_delete_nodes_request() {
}
void AnimationNodeBlendTreeEditor::_popup_request(const Vector2 &p_position) {
-
_update_options_menu();
use_popup_menu_position = true;
popup_menu_position = graph->get_local_mouse_position();
@@ -459,7 +438,6 @@ void AnimationNodeBlendTreeEditor::_popup_request(const Vector2 &p_position) {
}
void AnimationNodeBlendTreeEditor::_node_selected(Object *p_node) {
-
GraphNode *gn = Object::cast_to<GraphNode>(p_node);
ERR_FAIL_COND(!gn);
@@ -472,14 +450,12 @@ void AnimationNodeBlendTreeEditor::_node_selected(Object *p_node) {
}
void AnimationNodeBlendTreeEditor::_open_in_editor(const String &p_which) {
-
Ref<AnimationNode> an = blend_tree->get_node(p_which);
ERR_FAIL_COND(!an.is_valid());
AnimationTreeEditor::get_singleton()->enter_editor(p_which);
}
void AnimationNodeBlendTreeEditor::_filter_toggled() {
-
updating = true;
undo_redo->create_action(TTR("Toggle Filter On/Off"));
undo_redo->add_do_method(_filter_edit.ptr(), "set_filter_enabled", filter_enabled->is_pressed());
@@ -491,7 +467,6 @@ void AnimationNodeBlendTreeEditor::_filter_toggled() {
}
void AnimationNodeBlendTreeEditor::_filter_edited() {
-
TreeItem *edited = filters->get_edited();
ERR_FAIL_COND(!edited);
@@ -509,9 +484,9 @@ void AnimationNodeBlendTreeEditor::_filter_edited() {
}
bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &anode) {
-
- if (updating || _filter_edit != anode)
+ if (updating || _filter_edit != anode) {
return false;
+ }
NodePath player_path = AnimationTreeEditor::get_singleton()->get_tree()->get_animation_player();
@@ -542,7 +517,6 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
player->get_animation_list(&animations);
for (List<StringName>::Element *E = animations.front(); E; E = E->next()) {
-
Ref<Animation> anim = player->get_animation(E->get());
for (int i = 0; i < anim->get_track_count(); i++) {
String track_path = anim->track_get_path(i);
@@ -577,7 +551,6 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
Map<String, TreeItem *> parenthood;
for (Set<String>::Element *E = paths.front(); E; E = E->next()) {
-
NodePath path = E->get();
TreeItem *ti = nullptr;
String accum;
@@ -612,11 +585,11 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
if (base->has_node(accum)) {
node = base->get_node(accum);
}
- if (!node)
+ if (!node) {
continue; //no node, can't edit
+ }
if (path.get_subname_count()) {
-
String concat = path.get_concatenated_subnames();
Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node);
@@ -697,13 +670,13 @@ bool AnimationNodeBlendTreeEditor::_update_filters(const Ref<AnimationNode> &ano
}
void AnimationNodeBlendTreeEditor::_edit_filters(const String &p_which) {
-
Ref<AnimationNode> anode = blend_tree->get_node(p_which);
ERR_FAIL_COND(!anode.is_valid());
_filter_edit = anode;
- if (!_update_filters(anode))
+ if (!_update_filters(anode)) {
return;
+ }
filter_dialog->popup_centered(Size2(500, 500) * EDSCALE);
}
@@ -715,18 +688,16 @@ void AnimationNodeBlendTreeEditor::_removed_from_graph() {
}
void AnimationNodeBlendTreeEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
-
error_panel->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree"));
error_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor"));
- if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree())
+ if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree()) {
_update_graph();
+ }
}
if (p_what == NOTIFICATION_PROCESS) {
-
String error;
if (!AnimationTreeEditor::get_singleton()->get_tree()->is_active()) {
@@ -789,15 +760,15 @@ void AnimationNodeBlendTreeEditor::_notification(int p_what) {
}
void AnimationNodeBlendTreeEditor::_scroll_changed(const Vector2 &p_scroll) {
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
blend_tree->set_graph_offset(p_scroll / EDSCALE);
updating = false;
}
void AnimationNodeBlendTreeEditor::_bind_methods() {
-
ClassDB::bind_method("_update_graph", &AnimationNodeBlendTreeEditor::_update_graph);
ClassDB::bind_method("_update_filters", &AnimationNodeBlendTreeEditor::_update_filters);
}
@@ -805,7 +776,6 @@ void AnimationNodeBlendTreeEditor::_bind_methods() {
AnimationNodeBlendTreeEditor *AnimationNodeBlendTreeEditor::singleton = nullptr;
void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<AnimationNode> p_node) {
-
String prev_name = blend_tree->get_node_name(p_node);
ERR_FAIL_COND(prev_name == String());
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_node(prev_name));
@@ -858,7 +828,6 @@ void AnimationNodeBlendTreeEditor::_node_renamed(const String &p_text, Ref<Anima
blend_tree->get_node_connections(&connections);
for (List<AnimationNodeBlendTree::NodeConnection>::Element *E = connections.front(); E; E = E->next()) {
-
StringName from = E->get().output_node;
StringName to = E->get().input_node;
int to_idx = E->get().input_index;
@@ -888,7 +857,6 @@ bool AnimationNodeBlendTreeEditor::can_edit(const Ref<AnimationNode> &p_node) {
}
void AnimationNodeBlendTreeEditor::edit(const Ref<AnimationNode> &p_node) {
-
if (blend_tree.is_valid()) {
blend_tree->disconnect("removed_from_graph", callable_mp(this, &AnimationNodeBlendTreeEditor::_removed_from_graph));
}
@@ -905,7 +873,6 @@ void AnimationNodeBlendTreeEditor::edit(const Ref<AnimationNode> &p_node) {
}
AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
-
singleton = this;
updating = false;
use_popup_menu_position = false;
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.h b/editor/plugins/animation_blend_tree_editor_plugin.h
index 4f5badea9f..6bdb7e7909 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.h
+++ b/editor/plugins/animation_blend_tree_editor_plugin.h
@@ -44,7 +44,6 @@
class ProgressBar;
class AnimationNodeBlendTreeEditor : public AnimationTreeNodeEditorPlugin {
-
GDCLASS(AnimationNodeBlendTreeEditor, AnimationTreeNodeEditorPlugin);
Ref<AnimationNodeBlendTree> blend_tree;
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index d96a3b0bab..1e0a9535e2 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -30,7 +30,7 @@
#include "animation_player_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/resource_loader.h"
#include "core/io/resource_saver.h"
#include "core/os/keyboard.h"
@@ -44,7 +44,6 @@
#include "servers/rendering_server.h"
void AnimationPlayerEditor::_node_removed(Node *p_node) {
-
if (player && player == p_node) {
player = nullptr;
@@ -58,24 +57,21 @@ void AnimationPlayerEditor::_node_removed(Node *p_node) {
}
void AnimationPlayerEditor::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_PROCESS: {
-
- if (!player)
+ if (!player) {
return;
+ }
updating = true;
if (player->is_playing()) {
-
{
String animname = player->get_assigned_animation();
if (player->has_animation(animname)) {
Ref<Animation> anim = player->get_animation(animname);
if (!anim.is_null()) {
-
frame->set_max(anim->get_length());
}
}
@@ -96,7 +92,6 @@ void AnimationPlayerEditor::_notification(int p_what) {
updating = false;
} break;
case NOTIFICATION_ENTER_TREE: {
-
tool_anim->get_popup()->connect("id_pressed", callable_mp(this, &AnimationPlayerEditor::_animation_tool_menu));
onion_skinning->get_popup()->connect("id_pressed", callable_mp(this, &AnimationPlayerEditor::_onion_skinning_menu));
@@ -108,11 +103,9 @@ void AnimationPlayerEditor::_notification(int p_what) {
add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox("panel", "Panel"));
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
-
add_theme_style_override("panel", editor->get_gui_base()->get_theme_stylebox("panel", "Panel"));
} break;
case NOTIFICATION_THEME_CHANGED: {
-
autoplay->set_icon(get_theme_icon("AutoPlay", "EditorIcons"));
play->set_icon(get_theme_icon("PlayStart", "EditorIcons"));
@@ -147,9 +140,9 @@ void AnimationPlayerEditor::_notification(int p_what) {
}
void AnimationPlayerEditor::_autoplay_pressed() {
-
- if (updating)
+ if (updating) {
return;
+ }
if (animation->get_item_count() == 0) {
return;
}
@@ -176,17 +169,15 @@ void AnimationPlayerEditor::_autoplay_pressed() {
}
void AnimationPlayerEditor::_play_pressed() {
-
String current;
if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) {
-
current = animation->get_item_text(animation->get_selected());
}
if (current != "") {
-
- if (current == player->get_assigned_animation())
+ if (current == player->get_assigned_animation()) {
player->stop(); //so it won't blend with itself
+ }
player->play(current);
}
@@ -195,19 +186,15 @@ void AnimationPlayerEditor::_play_pressed() {
}
void AnimationPlayerEditor::_play_from_pressed() {
-
String current;
if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) {
-
current = animation->get_item_text(animation->get_selected());
}
if (current != "") {
-
float time = player->get_current_animation_position();
if (current == player->get_assigned_animation() && player->is_playing()) {
-
player->stop(); //so it won't blend with itself
}
@@ -220,17 +207,15 @@ void AnimationPlayerEditor::_play_from_pressed() {
}
void AnimationPlayerEditor::_play_bw_pressed() {
-
String current;
if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) {
-
current = animation->get_item_text(animation->get_selected());
}
if (current != "") {
-
- if (current == player->get_assigned_animation())
+ if (current == player->get_assigned_animation()) {
player->stop(); //so it won't blend with itself
+ }
player->play(current, -1, -1, true);
}
@@ -239,18 +224,16 @@ void AnimationPlayerEditor::_play_bw_pressed() {
}
void AnimationPlayerEditor::_play_bw_from_pressed() {
-
String current;
if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) {
-
current = animation->get_item_text(animation->get_selected());
}
if (current != "") {
-
float time = player->get_current_animation_position();
- if (current == player->get_assigned_animation())
+ if (current == player->get_assigned_animation()) {
player->stop(); //so it won't blend with itself
+ }
player->play(current, -1, -1, true);
player->seek(time);
@@ -259,8 +242,8 @@ void AnimationPlayerEditor::_play_bw_from_pressed() {
//unstop
stop->set_pressed(false);
}
-void AnimationPlayerEditor::_stop_pressed() {
+void AnimationPlayerEditor::_stop_pressed() {
if (!player) {
return;
}
@@ -271,24 +254,21 @@ void AnimationPlayerEditor::_stop_pressed() {
}
void AnimationPlayerEditor::_animation_selected(int p_which) {
-
- if (updating)
+ if (updating) {
return;
+ }
// when selecting an animation, the idea is that the only interesting behavior
// ui-wise is that it should play/blend the next one if currently playing
String current;
if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) {
-
current = animation->get_item_text(animation->get_selected());
}
if (current != "") {
-
player->set_assigned_animation(current);
Ref<Animation> anim = player->get_animation(current);
{
-
track_editor->set_animation(anim);
Node *root = player->get_node(player->get_root());
if (root) {
@@ -310,7 +290,6 @@ void AnimationPlayerEditor::_animation_selected(int p_which) {
}
void AnimationPlayerEditor::_animation_new() {
-
renaming = false;
name_title->set_text(TTR("New Animation Name:"));
@@ -318,8 +297,9 @@ void AnimationPlayerEditor::_animation_new() {
String base = TTR("New Anim");
while (true) {
String attempt = base;
- if (count > 1)
+ if (count > 1) {
attempt += " (" + itos(count) + ")";
+ }
if (player->has_animation(attempt)) {
count++;
continue;
@@ -333,10 +313,11 @@ void AnimationPlayerEditor::_animation_new() {
name->select_all();
name->grab_focus();
}
-void AnimationPlayerEditor::_animation_rename() {
- if (animation->get_item_count() == 0)
+void AnimationPlayerEditor::_animation_rename() {
+ if (animation->get_item_count() == 0) {
return;
+ }
int selected = animation->get_selected();
String selected_name = animation->get_item_text(selected);
@@ -347,6 +328,7 @@ void AnimationPlayerEditor::_animation_rename() {
name->select_all();
name->grab_focus();
}
+
void AnimationPlayerEditor::_animation_load() {
ERR_FAIL_COND(!player);
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
@@ -355,7 +337,6 @@ void AnimationPlayerEditor::_animation_load() {
ResourceLoader::get_recognized_extensions_for_type("Animation", &extensions);
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
-
file->add_filter("*." + E->get() + " ; " + E->get().to_upper());
}
@@ -364,10 +345,10 @@ void AnimationPlayerEditor::_animation_load() {
}
void AnimationPlayerEditor::_animation_save_in_path(const Ref<Resource> &p_resource, const String &p_path) {
-
int flg = 0;
- if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources"))
+ if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) {
flg |= ResourceSaver::FLAG_COMPRESS;
+ }
String path = ProjectSettings::get_singleton()->localize_path(p_path);
Error err = ResourceSaver::save(path, p_resource, flg | ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS);
@@ -382,7 +363,6 @@ void AnimationPlayerEditor::_animation_save_in_path(const Ref<Resource> &p_resou
}
void AnimationPlayerEditor::_animation_save(const Ref<Resource> &p_resource) {
-
if (p_resource->get_path().is_resource_file()) {
_animation_save_in_path(p_resource, p_resource->get_path());
} else {
@@ -391,14 +371,12 @@ void AnimationPlayerEditor::_animation_save(const Ref<Resource> &p_resource) {
}
void AnimationPlayerEditor::_animation_save_as(const Ref<Resource> &p_resource) {
-
file->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
List<String> extensions;
ResourceSaver::get_recognized_extensions(p_resource, &extensions);
file->clear_filters();
for (int i = 0; i < extensions.size(); i++) {
-
file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
}
@@ -412,7 +390,6 @@ void AnimationPlayerEditor::_animation_save_as(const Ref<Resource> &p_resource)
}
}
} else {
-
String existing;
if (extensions.size()) {
if (p_resource->get_name() != "") {
@@ -429,16 +406,17 @@ void AnimationPlayerEditor::_animation_save_as(const Ref<Resource> &p_resource)
}
void AnimationPlayerEditor::_animation_remove() {
-
- if (animation->get_item_count() == 0)
+ if (animation->get_item_count() == 0) {
return;
+ }
- delete_dialog->set_text(TTR("Delete Animation?"));
+ String current = animation->get_item_text(animation->get_selected());
+
+ delete_dialog->set_text(TTR("Delete Animation '" + current + "'?"));
delete_dialog->popup_centered();
}
void AnimationPlayerEditor::_animation_remove_confirmed() {
-
String current = animation->get_item_text(animation->get_selected());
Ref<Animation> anim = player->get_animation(current);
@@ -461,12 +439,9 @@ void AnimationPlayerEditor::_animation_remove_confirmed() {
}
void AnimationPlayerEditor::_select_anim_by_name(const String &p_anim) {
-
int idx = -1;
for (int i = 0; i < animation->get_item_count(); i++) {
-
if (animation->get_item_text(i) == p_anim) {
-
idx = i;
break;
}
@@ -480,7 +455,6 @@ void AnimationPlayerEditor::_select_anim_by_name(const String &p_anim) {
}
double AnimationPlayerEditor::_get_editor_step() const {
-
// Returns the effective snapping value depending on snapping modifiers, or 0 if snapping is disabled.
if (track_editor->is_snap_enabled()) {
const String current = player->get_assigned_animation();
@@ -488,14 +462,13 @@ double AnimationPlayerEditor::_get_editor_step() const {
ERR_FAIL_COND_V(!anim.is_valid(), 0.0);
// Use more precise snapping when holding Shift
- return InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT) ? anim->get_step() * 0.25 : anim->get_step();
+ return Input::get_singleton()->is_key_pressed(KEY_SHIFT) ? anim->get_step() * 0.25 : anim->get_step();
}
return 0.0;
}
void AnimationPlayerEditor::_animation_name_edited() {
-
player->stop();
String new_name = name->get_text();
@@ -532,7 +505,6 @@ void AnimationPlayerEditor::_animation_name_edited() {
_select_anim_by_name(new_name);
} else {
-
Ref<Animation> new_anim = Ref<Animation>(memnew(Animation));
new_anim->set_name(new_name);
@@ -554,9 +526,9 @@ void AnimationPlayerEditor::_animation_name_edited() {
}
void AnimationPlayerEditor::_blend_editor_next_changed(const int p_idx) {
-
- if (animation->get_item_count() == 0)
+ if (animation->get_item_count() == 0) {
return;
+ }
String current = animation->get_item_text(animation->get_selected());
@@ -569,14 +541,15 @@ void AnimationPlayerEditor::_blend_editor_next_changed(const int p_idx) {
}
void AnimationPlayerEditor::_animation_blend() {
-
- if (updating_blends)
+ if (updating_blends) {
return;
+ }
blend_editor.tree->clear();
- if (animation->get_item_count() == 0)
+ if (animation->get_item_count() == 0) {
return;
+ }
String current = animation->get_item_text(animation->get_selected());
@@ -597,7 +570,6 @@ void AnimationPlayerEditor::_animation_blend() {
blend_editor.next->add_item("", i);
for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
-
String to = E->get();
TreeItem *blend = blend_editor.tree->create_item(root);
blend->set_editable(0, false);
@@ -625,18 +597,20 @@ void AnimationPlayerEditor::_animation_blend() {
}
void AnimationPlayerEditor::_blend_edited() {
-
- if (updating_blends)
+ if (updating_blends) {
return;
+ }
- if (animation->get_item_count() == 0)
+ if (animation->get_item_count() == 0) {
return;
+ }
String current = animation->get_item_text(animation->get_selected());
TreeItem *selected = blend_editor.tree->get_edited();
- if (!selected)
+ if (!selected) {
return;
+ }
updating_blends = true;
String to = selected->get_text(0);
@@ -653,15 +627,14 @@ void AnimationPlayerEditor::_blend_edited() {
}
void AnimationPlayerEditor::ensure_visibility() {
-
- if (player && pin->is_pressed())
+ if (player && pin->is_pressed()) {
return; // another player is pinned, don't reset
+ }
_animation_edit();
}
Dictionary AnimationPlayerEditor::get_state() const {
-
Dictionary d;
d["visible"] = is_visible_in_tree();
@@ -673,8 +646,8 @@ Dictionary AnimationPlayerEditor::get_state() const {
return d;
}
-void AnimationPlayerEditor::set_state(const Dictionary &p_state) {
+void AnimationPlayerEditor::set_state(const Dictionary &p_state) {
if (!p_state.has("visible") || !p_state["visible"]) {
return;
}
@@ -683,7 +656,6 @@ void AnimationPlayerEditor::set_state(const Dictionary &p_state) {
}
if (p_state.has("player")) {
-
Node *n = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["player"]);
if (Object::cast_to<AnimationPlayer>(n) && EditorNode::get_singleton()->get_editor_selection()->is_selected(n)) {
player = Object::cast_to<AnimationPlayer>(n);
@@ -708,7 +680,6 @@ void AnimationPlayerEditor::set_state(const Dictionary &p_state) {
}
void AnimationPlayerEditor::_animation_resource_edit() {
-
if (animation->get_item_count()) {
String current = animation->get_item_text(animation->get_selected());
Ref<Animation> anim = player->get_animation(current);
@@ -717,7 +688,6 @@ void AnimationPlayerEditor::_animation_resource_edit() {
}
void AnimationPlayerEditor::_animation_edit() {
-
if (animation->get_item_count()) {
String current = animation->get_item_text(animation->get_selected());
Ref<Animation> anim = player->get_animation(current);
@@ -734,7 +704,6 @@ void AnimationPlayerEditor::_animation_edit() {
}
void AnimationPlayerEditor::_dialog_action(String p_file) {
-
switch (current_option) {
case RESOURCE_LOAD: {
ERR_FAIL_COND(!player);
@@ -743,16 +712,15 @@ void AnimationPlayerEditor::_dialog_action(String p_file) {
ERR_FAIL_COND_MSG(res.is_null(), "Cannot load Animation from file '" + p_file + "'.");
ERR_FAIL_COND_MSG(!res->is_class("Animation"), "Loaded resource from file '" + p_file + "' is not Animation.");
if (p_file.find_last("/") != -1) {
-
p_file = p_file.substr(p_file.find_last("/") + 1, p_file.length());
}
if (p_file.find_last("\\") != -1) {
-
p_file = p_file.substr(p_file.find_last("\\") + 1, p_file.length());
}
- if (p_file.find(".") != -1)
+ if (p_file.find(".") != -1) {
p_file = p_file.substr(0, p_file.find("."));
+ }
undo_redo->create_action(TTR("Load Animation"));
undo_redo->add_do_method(player, "add_animation", p_file, res);
@@ -766,7 +734,6 @@ void AnimationPlayerEditor::_dialog_action(String p_file) {
break;
}
case RESOURCE_SAVE: {
-
String current = animation->get_item_text(animation->get_selected());
if (current != "") {
Ref<Animation> anim = player->get_animation(current);
@@ -782,24 +749,20 @@ void AnimationPlayerEditor::_dialog_action(String p_file) {
}
void AnimationPlayerEditor::_scale_changed(const String &p_scale) {
-
player->set_speed_scale(p_scale.to_double());
}
void AnimationPlayerEditor::_update_animation() {
-
// the purpose of _update_animation is to reflect the current state
// of the animation player in the current editor..
updating = true;
if (player->is_playing()) {
-
play->set_pressed(true);
stop->set_pressed(false);
} else {
-
play->set_pressed(false);
stop->set_pressed(true);
}
@@ -808,7 +771,6 @@ void AnimationPlayerEditor::_update_animation() {
String current = player->get_assigned_animation();
for (int i = 0; i < animation->get_item_count(); i++) {
-
if (animation->get_item_text(i) == current) {
animation->select(i);
break;
@@ -819,11 +781,11 @@ void AnimationPlayerEditor::_update_animation() {
}
void AnimationPlayerEditor::_update_player() {
-
updating = true;
List<StringName> animlist;
- if (player)
+ if (player) {
player->get_animation_list(&animlist);
+ }
animation->clear();
@@ -858,14 +820,15 @@ void AnimationPlayerEditor::_update_player() {
int active_idx = -1;
for (List<StringName>::Element *E = animlist.front(); E; E = E->next()) {
-
- if (player->get_autoplay() == E->get())
+ if (player->get_autoplay() == E->get()) {
animation->add_icon_item(autoplay_icon, E->get());
- else
+ } else {
animation->add_item(E->get());
+ }
- if (player->get_assigned_animation() == E->get())
+ if (player->get_assigned_animation() == E->get()) {
active_idx = animation->get_item_count() - 1;
+ }
}
updating = false;
@@ -875,7 +838,6 @@ void AnimationPlayerEditor::_update_player() {
_animation_selected(active_idx);
} else if (animation->get_item_count() > 0) {
-
animation->select(0);
autoplay->set_pressed(animation->get_item_text(0) == player->get_autoplay());
_animation_selected(0);
@@ -897,38 +859,41 @@ void AnimationPlayerEditor::_update_player() {
}
void AnimationPlayerEditor::edit(AnimationPlayer *p_player) {
-
- if (player && pin->is_pressed())
+ if (player && pin->is_pressed()) {
return; // Ignore, pinned.
+ }
player = p_player;
if (player) {
_update_player();
if (onion.enabled) {
- if (animation->get_item_count() > 0)
+ if (animation->get_item_count() > 0) {
_start_onion_skinning();
- else
+ } else {
_stop_onion_skinning();
+ }
}
track_editor->show_select_node_warning(false);
} else {
- if (onion.enabled)
+ if (onion.enabled) {
_stop_onion_skinning();
+ }
track_editor->show_select_node_warning(true);
}
}
void AnimationPlayerEditor::forward_canvas_force_draw_over_viewport(Control *p_overlay) {
-
- if (!onion.can_overlay)
+ if (!onion.can_overlay) {
return;
+ }
// Can happen on viewport resize, at least.
- if (!_are_onion_layers_valid())
+ if (!_are_onion_layers_valid()) {
return;
+ }
RID ci = p_overlay->get_canvas_item();
Rect2 src_rect = p_overlay->get_global_rect();
@@ -971,22 +936,21 @@ void AnimationPlayerEditor::forward_canvas_force_draw_over_viewport(Control *p_o
}
void AnimationPlayerEditor::_animation_duplicate() {
-
- if (!animation->get_item_count())
+ if (!animation->get_item_count()) {
return;
+ }
String current = animation->get_item_text(animation->get_selected());
Ref<Animation> anim = player->get_animation(current);
- if (!anim.is_valid())
+ if (!anim.is_valid()) {
return;
+ }
Ref<Animation> new_anim = memnew(Animation);
List<PropertyInfo> plist;
anim->get_property_list(&plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
if (E->get().usage & PROPERTY_USAGE_STORAGE) {
-
new_anim->set(E->get().name, anim->get(E->get().name));
}
}
@@ -1007,9 +971,7 @@ void AnimationPlayerEditor::_animation_duplicate() {
undo_redo->commit_action();
for (int i = 0; i < animation->get_item_count(); i++) {
-
if (animation->get_item_text(i) == new_name) {
-
animation->select(i);
_animation_selected(i);
return;
@@ -1018,7 +980,6 @@ void AnimationPlayerEditor::_animation_duplicate() {
}
void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) {
-
if (updating || !player || player->is_playing()) {
return;
};
@@ -1054,41 +1015,42 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set) {
};
void AnimationPlayerEditor::_animation_player_changed(Object *p_pl) {
-
if (player == p_pl && is_visible_in_tree()) {
-
_update_player();
- if (blend_editor.dialog->is_visible())
+ if (blend_editor.dialog->is_visible()) {
_animation_blend(); // Update.
+ }
}
}
void AnimationPlayerEditor::_list_changed() {
-
- if (is_visible_in_tree())
+ if (is_visible_in_tree()) {
_update_player();
+ }
}
void AnimationPlayerEditor::_animation_key_editor_anim_len_changed(float p_len) {
-
frame->set_max(p_len);
}
void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag) {
-
timeline_position = p_pos;
- if (!is_visible_in_tree())
+ if (!is_visible_in_tree()) {
return;
+ }
- if (!player)
+ if (!player) {
return;
+ }
- if (player->is_playing())
+ if (player->is_playing()) {
return;
+ }
- if (!player->has_animation(player->get_assigned_animation()))
+ if (!player->has_animation(player->get_assigned_animation())) {
return;
+ }
updating = true;
frame->set_value(Math::stepify(p_pos, _get_editor_step()));
@@ -1099,7 +1061,6 @@ void AnimationPlayerEditor::_animation_key_editor_seek(float p_pos, bool p_drag)
}
void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
-
String current;
if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count()) {
current = animation->get_item_text(animation->get_selected());
@@ -1111,45 +1072,37 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
}
switch (p_option) {
-
case TOOL_NEW_ANIM: {
-
_animation_new();
} break;
case TOOL_LOAD_ANIM: {
-
_animation_load();
} break;
case TOOL_SAVE_ANIM: {
-
if (anim.is_valid()) {
_animation_save(anim);
}
} break;
case TOOL_SAVE_AS_ANIM: {
-
if (anim.is_valid()) {
_animation_save_as(anim);
}
} break;
case TOOL_DUPLICATE_ANIM: {
-
_animation_duplicate();
- } break;
- case TOOL_RENAME_ANIM: {
+ [[fallthrough]]; // Allow immediate rename after animation is duplicated
+ }
+ case TOOL_RENAME_ANIM: {
_animation_rename();
} break;
case TOOL_EDIT_TRANSITIONS: {
-
_animation_blend();
} break;
case TOOL_REMOVE_ANIM: {
-
_animation_remove();
} break;
case TOOL_COPY_ANIM: {
-
if (!animation->get_item_count()) {
error_dialog->set_text(TTR("No animation to copy!"));
error_dialog->popup_centered();
@@ -1161,7 +1114,6 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
EditorSettings::get_singleton()->set_resource_clipboard(anim2);
} break;
case TOOL_PASTE_ANIM: {
-
Ref<Animation> anim2 = EditorSettings::get_singleton()->get_resource_clipboard();
if (!anim2.is_valid()) {
error_dialog->set_text(TTR("No animation resource on clipboard!"));
@@ -1177,7 +1129,6 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
int idx = 1;
String base = name;
while (player->has_animation(name)) {
-
idx++;
name = base + " " + itos(idx);
}
@@ -1192,7 +1143,6 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
_select_anim_by_name(name);
} break;
case TOOL_EDIT_RESOURCE: {
-
if (!animation->get_item_count()) {
error_dialog->set_text(TTR("No animation to edit!"));
error_dialog->popup_centered();
@@ -1207,30 +1157,26 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
}
void AnimationPlayerEditor::_onion_skinning_menu(int p_option) {
-
PopupMenu *menu = onion_skinning->get_popup();
int idx = menu->get_item_index(p_option);
switch (p_option) {
-
case ONION_SKINNING_ENABLE: {
-
onion.enabled = !onion.enabled;
- if (onion.enabled)
+ if (onion.enabled) {
_start_onion_skinning();
- else
+ } else {
_stop_onion_skinning();
+ }
} break;
case ONION_SKINNING_PAST: {
-
// Ensure at least one of past/future is checked.
onion.past = onion.future ? !onion.past : true;
menu->set_item_checked(idx, onion.past);
} break;
case ONION_SKINNING_FUTURE: {
-
// Ensure at least one of past/future is checked.
onion.future = onion.past ? !onion.future : true;
menu->set_item_checked(idx, onion.future);
@@ -1238,7 +1184,6 @@ void AnimationPlayerEditor::_onion_skinning_menu(int p_option) {
case ONION_SKINNING_1_STEP: // Fall-through.
case ONION_SKINNING_2_STEPS:
case ONION_SKINNING_3_STEPS: {
-
onion.steps = (p_option - ONION_SKINNING_1_STEP) + 1;
int one_frame_idx = menu->get_item_index(ONION_SKINNING_1_STEP);
for (int i = 0; i <= ONION_SKINNING_LAST_STEPS_OPTION - ONION_SKINNING_1_STEP; i++) {
@@ -1246,17 +1191,14 @@ void AnimationPlayerEditor::_onion_skinning_menu(int p_option) {
}
} break;
case ONION_SKINNING_DIFFERENCES_ONLY: {
-
onion.differences_only = !onion.differences_only;
menu->set_item_checked(idx, onion.differences_only);
} break;
case ONION_SKINNING_FORCE_WHITE_MODULATE: {
-
onion.force_white_modulate = !onion.force_white_modulate;
menu->set_item_checked(idx, onion.force_white_modulate);
} break;
case ONION_SKINNING_INCLUDE_GIZMOS: {
-
onion.include_gizmos = !onion.include_gizmos;
menu->set_item_checked(idx, onion.include_gizmos);
} break;
@@ -1264,40 +1206,37 @@ void AnimationPlayerEditor::_onion_skinning_menu(int p_option) {
}
void AnimationPlayerEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
-
Ref<InputEventKey> k = p_ev;
if (is_visible_in_tree() && k.is_valid() && k->is_pressed() && !k->is_echo() && !k->get_alt() && !k->get_control() && !k->get_metakey()) {
-
switch (k->get_keycode()) {
-
case KEY_A: {
- if (!k->get_shift())
+ if (!k->get_shift()) {
_play_bw_from_pressed();
- else
+ } else {
_play_bw_pressed();
+ }
} break;
case KEY_S: {
_stop_pressed();
} break;
case KEY_D: {
- if (!k->get_shift())
+ if (!k->get_shift()) {
_play_from_pressed();
- else
+ } else {
_play_pressed();
+ }
} break;
}
}
}
void AnimationPlayerEditor::_editor_visibility_changed() {
-
if (is_visible() && animation->get_item_count() > 0) {
_start_onion_skinning();
}
}
bool AnimationPlayerEditor::_are_onion_layers_valid() {
-
ERR_FAIL_COND_V(!onion.past && !onion.future, false);
Point2 capture_size = get_tree()->get_root()->get_size();
@@ -1305,7 +1244,6 @@ bool AnimationPlayerEditor::_are_onion_layers_valid() {
}
void AnimationPlayerEditor::_allocate_onion_layers() {
-
_free_onion_layers();
int captures = onion.get_needed_capture_count();
@@ -1334,7 +1272,6 @@ void AnimationPlayerEditor::_allocate_onion_layers() {
}
void AnimationPlayerEditor::_free_onion_layers() {
-
for (int i = 0; i < onion.captures.size(); i++) {
if (onion.captures[i].is_valid()) {
RS::get_singleton()->free(onion.captures[i]);
@@ -1345,11 +1282,11 @@ void AnimationPlayerEditor::_free_onion_layers() {
}
void AnimationPlayerEditor::_prepare_onion_layers_1() {
-
// This would be called per viewport and we want to act once only.
int64_t frame = get_tree()->get_frame();
- if (frame == onion.last_frame)
+ if (frame == onion.last_frame) {
return;
+ }
if (!onion.enabled || !is_processing() || !is_visible() || !get_player()) {
_stop_onion_skinning();
@@ -1362,8 +1299,9 @@ void AnimationPlayerEditor::_prepare_onion_layers_1() {
onion.can_overlay = false;
plugin->update_overlays();
- if (player->is_playing())
+ if (player->is_playing()) {
return;
+ }
// And go to next step afterwards.
call_deferred("_prepare_onion_layers_2");
@@ -1374,13 +1312,14 @@ void AnimationPlayerEditor::_prepare_onion_layers_1_deferred() {
}
void AnimationPlayerEditor::_prepare_onion_layers_2() {
-
Ref<Animation> anim = player->get_animation(player->get_assigned_animation());
- if (!anim.is_valid())
+ if (!anim.is_valid()) {
return;
+ }
- if (!_are_onion_layers_valid())
+ if (!_are_onion_layers_valid()) {
_allocate_onion_layers();
+ }
// Hide superfluous elements that would make the overlay unnecessary cluttered.
Dictionary canvas_edit_state;
@@ -1451,11 +1390,11 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
int cidx = 0;
onion.capture.material->set_shader_param("dir_color", onion.force_white_modulate ? Color(1, 1, 1) : Color(EDITOR_GET("editors/animation/onion_layers_past_color")));
for (int step_off = step_off_a; step_off <= step_off_b; step_off++) {
-
if (step_off == 0) {
// Skip present step and switch to the color of future.
- if (!onion.force_white_modulate)
+ if (!onion.force_white_modulate) {
onion.capture.material->set_shader_param("dir_color", EDITOR_GET("editors/animation/onion_layers_future_color"));
+ }
continue;
}
@@ -1503,7 +1442,6 @@ void AnimationPlayerEditor::_prepare_onion_layers_2() {
}
void AnimationPlayerEditor::_start_onion_skinning() {
-
// FIXME: Using "idle_frame" makes onion layers update one frame behind the current.
if (!get_tree()->is_connected("idle_frame", callable_mp(this, &AnimationPlayerEditor::_prepare_onion_layers_1_deferred))) {
get_tree()->connect("idle_frame", callable_mp(this, &AnimationPlayerEditor::_prepare_onion_layers_1_deferred));
@@ -1511,9 +1449,7 @@ void AnimationPlayerEditor::_start_onion_skinning() {
}
void AnimationPlayerEditor::_stop_onion_skinning() {
-
if (get_tree()->is_connected("idle_frame", callable_mp(this, &AnimationPlayerEditor::_prepare_onion_layers_1_deferred))) {
-
get_tree()->disconnect("idle_frame", callable_mp(this, &AnimationPlayerEditor::_prepare_onion_layers_1_deferred));
_free_onion_layers();
@@ -1525,12 +1461,10 @@ void AnimationPlayerEditor::_stop_onion_skinning() {
}
void AnimationPlayerEditor::_pin_pressed() {
-
EditorNode::get_singleton()->get_scene_tree_dock()->get_tree_editor()->update_tree();
}
void AnimationPlayerEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_animation_new"), &AnimationPlayerEditor::_animation_new);
ClassDB::bind_method(D_METHOD("_animation_rename"), &AnimationPlayerEditor::_animation_rename);
ClassDB::bind_method(D_METHOD("_animation_load"), &AnimationPlayerEditor::_animation_load);
@@ -1552,7 +1486,6 @@ void AnimationPlayerEditor::_bind_methods() {
AnimationPlayerEditor *AnimationPlayerEditor::singleton = nullptr;
AnimationPlayer *AnimationPlayerEditor::get_player() const {
-
return player;
}
@@ -1796,39 +1729,33 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
}
AnimationPlayerEditor::~AnimationPlayerEditor() {
-
_free_onion_layers();
RS::get_singleton()->free(onion.capture.canvas);
RS::get_singleton()->free(onion.capture.canvas_item);
}
void AnimationPlayerEditorPlugin::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
-
set_force_draw_over_forwarding_enabled();
} break;
}
}
void AnimationPlayerEditorPlugin::edit(Object *p_object) {
-
anim_editor->set_undo_redo(&get_undo_redo());
- if (!p_object)
+ if (!p_object) {
return;
+ }
anim_editor->edit(Object::cast_to<AnimationPlayer>(p_object));
}
bool AnimationPlayerEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("AnimationPlayer");
}
void AnimationPlayerEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
-
editor->make_bottom_panel_item_visible(anim_editor);
anim_editor->set_process(true);
anim_editor->ensure_visibility();
@@ -1836,7 +1763,6 @@ void AnimationPlayerEditorPlugin::make_visible(bool p_visible) {
}
AnimationPlayerEditorPlugin::AnimationPlayerEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
anim_editor = memnew(AnimationPlayerEditor(editor, this));
anim_editor->set_undo_redo(EditorNode::get_undo_redo());
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 1abefad635..18f2d3b25e 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -43,7 +43,6 @@ class AnimationTrackEditor;
class AnimationPlayerEditorPlugin;
class AnimationPlayerEditor : public VBoxContainer {
-
GDCLASS(AnimationPlayerEditor, VBoxContainer);
EditorNode *editor;
@@ -114,7 +113,6 @@ class AnimationPlayerEditor : public VBoxContainer {
int current_option;
struct BlendEditor {
-
AcceptDialog *dialog;
Tree *tree;
OptionButton *next;
@@ -244,7 +242,6 @@ public:
};
class AnimationPlayerEditorPlugin : public EditorPlugin {
-
GDCLASS(AnimationPlayerEditorPlugin, EditorPlugin);
AnimationPlayerEditor *anim_editor;
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index c06f62a8c1..652754a146 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -30,9 +30,9 @@
#include "animation_state_machine_editor.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/resource_loader.h"
-#include "core/math/delaunay.h"
+#include "core/math/delaunay_2d.h"
#include "core/os/keyboard.h"
#include "core/project_settings.h"
#include "editor/editor_scale.h"
@@ -43,17 +43,14 @@
#include "scene/main/window.h"
bool AnimationNodeStateMachineEditor::can_edit(const Ref<AnimationNode> &p_node) {
-
Ref<AnimationNodeStateMachine> ansm = p_node;
return ansm.is_valid();
}
void AnimationNodeStateMachineEditor::edit(const Ref<AnimationNode> &p_node) {
-
state_machine = p_node;
if (state_machine.is_valid()) {
-
selected_transition_from = StringName();
selected_transition_to = StringName();
selected_node = StringName();
@@ -63,10 +60,10 @@ void AnimationNodeStateMachineEditor::edit(const Ref<AnimationNode> &p_node) {
}
void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
- if (playback.is_null())
+ if (playback.is_null()) {
return;
+ }
Ref<InputEventKey> k = p_event;
if (tool_select->is_pressed() && k.is_valid() && k->is_pressed() && k->get_keycode() == KEY_DELETE && !k->is_echo()) {
@@ -104,10 +101,10 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
}
for (List<StringName>::Element *E = classes.front(); E; E = E->next()) {
-
String name = String(E->get()).replace_first("AnimationNode", "");
- if (name == "Animation")
+ if (name == "Animation") {
continue; // nope
+ }
int idx = menu->get_item_count();
menu->add_item(vformat("Add %s", name), idx);
menu->set_item_metadata(idx, E->get());
@@ -128,7 +125,6 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
// select node or push a field inside
if (mb.is_valid() && !mb->get_shift() && mb->is_pressed() && tool_select->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
selected_transition_from = StringName();
selected_transition_to = StringName();
selected_node = StringName();
@@ -191,7 +187,6 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
int closest = -1;
float closest_d = 1e20;
for (int i = 0; i < transition_lines.size(); i++) {
-
Vector2 s[2] = {
transition_lines[i].from,
transition_lines[i].to
@@ -222,9 +217,7 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
//end moving node
if (mb.is_valid() && dragging_selected_attempt && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) {
-
if (dragging_selected) {
-
Ref<AnimationNode> an = state_machine->get_node(selected_node);
updating = true;
undo_redo->create_action(TTR("Move Node"));
@@ -245,7 +238,6 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
//connect nodes
if (mb.is_valid() && ((tool_select->is_pressed() && mb->get_shift()) || tool_connect->is_pressed()) && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
-
for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order
if (node_rects[i].node.has_point(mb->get_position())) { //select node since nothing else was selected
connecting = true;
@@ -259,14 +251,11 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
//end connecting nodes
if (mb.is_valid() && connecting && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) {
-
if (connecting_to_node != StringName()) {
-
if (state_machine->has_transition(connecting_from, connecting_to_node)) {
EditorNode::get_singleton()->show_warning(TTR("Transition exists!"));
} else {
-
Ref<AnimationNodeStateMachineTransition> tr;
tr.instance();
tr->set_switch_mode(AnimationNodeStateMachineTransition::SwitchMode(transition_mode->get_selected()));
@@ -296,14 +285,12 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
//pan window
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_MIDDLE) {
-
h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x);
v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y);
}
//move mouse while connecting
if (mm.is_valid() && connecting) {
-
connecting_to = mm->get_position();
connecting_to_node = StringName();
state_machine_draw->update();
@@ -318,7 +305,6 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
//move mouse while moving a node
if (mm.is_valid() && dragging_selected_attempt) {
-
dragging_selected = true;
drag_ofs = mm->get_position() - drag_from;
snap_x = StringName();
@@ -333,8 +319,9 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
float best_d_y = 1e20;
for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) {
- if (E->get() == selected_node)
+ if (E->get() == selected_node) {
continue;
+ }
Vector2 npos = state_machine->get_node_position(E->get());
float d_x = ABS(npos.x - cpos.x);
@@ -358,14 +345,12 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
//put ibeam (text cursor) over names to make it clearer that they are editable
if (mm.is_valid()) {
-
state_machine_draw->grab_focus();
bool over_text_now = false;
String new_over_node = StringName();
int new_over_node_what = -1;
if (tool_select->is_pressed()) {
-
for (int i = node_rects.size() - 1; i >= 0; i--) { //inverse to draw order
if (node_rects[i].name.has_point(mm->get_position())) {
@@ -392,7 +377,6 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
}
if (over_text != over_text_now) {
-
if (over_text_now) {
state_machine_draw->set_default_cursor_shape(CURSOR_IBEAM);
} else {
@@ -405,7 +389,6 @@ void AnimationNodeStateMachineEditor::_state_machine_gui_input(const Ref<InputEv
}
void AnimationNodeStateMachineEditor::_file_opened(const String &p_file) {
-
file_loaded = ResourceLoader::load(p_file);
if (file_loaded.is_valid()) {
_add_menu_type(MENU_LOAD_FILE_CONFIRM);
@@ -413,12 +396,10 @@ void AnimationNodeStateMachineEditor::_file_opened(const String &p_file) {
}
void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) {
-
String base_name;
Ref<AnimationRootNode> node;
if (p_index == MENU_LOAD_FILE) {
-
open_file->clear_filters();
List<String> filters;
ResourceLoader::get_recognized_extensions_for_type("AnimationRootNode", &filters);
@@ -431,7 +412,6 @@ void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) {
node = file_loaded;
file_loaded.unref();
} else if (p_index == MENU_PASTE) {
-
node = EditorSettings::get_singleton()->get_resource_clipboard();
} else {
@@ -452,7 +432,6 @@ void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) {
}
if (base_name == String()) {
-
base_name = node->get_class().replace_first("AnimationNode", "");
}
@@ -476,7 +455,6 @@ void AnimationNodeStateMachineEditor::_add_menu_type(int p_index) {
}
void AnimationNodeStateMachineEditor::_add_animation_type(int p_index) {
-
Ref<AnimationNodeAnimation> anim;
anim.instance();
@@ -503,7 +481,6 @@ void AnimationNodeStateMachineEditor::_add_animation_type(int p_index) {
}
void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, const Vector2 &p_to, AnimationNodeStateMachineTransition::SwitchMode p_mode, bool p_enabled, bool p_selected, bool p_travel, bool p_auto_advance) {
-
Color linecolor = get_theme_color("font_color", "Label");
Color icon_color(1, 1, 1);
Color accent = get_theme_color("accent_color", "Editor");
@@ -546,9 +523,9 @@ void AnimationNodeStateMachineEditor::_connection_draw(const Vector2 &p_from, co
}
void AnimationNodeStateMachineEditor::_clip_src_line_to_rect(Vector2 &r_from, Vector2 &r_to, const Rect2 &p_rect) {
-
- if (r_to == r_from)
+ if (r_to == r_from) {
return;
+ }
//this could be optimized...
Vector2 n = (r_to - r_from).normalized();
@@ -558,9 +535,9 @@ void AnimationNodeStateMachineEditor::_clip_src_line_to_rect(Vector2 &r_from, Ve
}
void AnimationNodeStateMachineEditor::_clip_dst_line_to_rect(Vector2 &r_from, Vector2 &r_to, const Rect2 &p_rect) {
-
- if (r_to == r_from)
+ if (r_to == r_from) {
return;
+ }
//this could be optimized...
Vector2 n = (r_to - r_from).normalized();
@@ -570,7 +547,6 @@ void AnimationNodeStateMachineEditor::_clip_dst_line_to_rect(Vector2 &r_from, Ve
}
void AnimationNodeStateMachineEditor::_state_machine_draw() {
-
Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
Ref<StyleBox> style = get_theme_stylebox("state_machine_frame", "GraphNode");
@@ -611,7 +587,6 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
//snap lines
if (dragging_selected) {
-
Vector2 from = (state_machine->get_node_position(selected_node) * EDSCALE) + drag_ofs - state_machine->get_graph_offset() * EDSCALE;
if (snap_x != StringName()) {
Vector2 to = (state_machine->get_node_position(snap_x) * EDSCALE) - state_machine->get_graph_offset() * EDSCALE;
@@ -625,7 +600,6 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
//pre pass nodes so we know the rectangles
for (List<StringName>::Element *E = nodes.front(); E; E = E->next()) {
-
Ref<AnimationNode> anode = state_machine->get_node(E->get());
String name = E->get();
bool needs_editor = EditorNode::get_singleton()->item_has_editor(anode.ptr());
@@ -691,7 +665,6 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
//draw transition lines
for (int i = 0; i < state_machine->get_transition_count(); i++) {
-
TransitionLine tl;
tl.from_node = state_machine->get_transition_from(i);
Vector2 ofs_from = (dragging_selected && tl.from_node == selected_node) ? drag_ofs : Vector2();
@@ -733,7 +706,6 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
}
if (travel_path.size()) {
-
if (current == tl.from_node && travel_path[0] == tl.to_node) {
travel = true;
} else {
@@ -759,7 +731,6 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
//draw actual nodes
for (int i = 0; i < node_rects.size(); i++) {
-
String name = node_rects[i].node_name;
Ref<AnimationNode> anode = state_machine->get_node(name);
bool needs_editor = AnimationTreeEditor::get_singleton()->can_edit(anode);
@@ -786,7 +757,6 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
}
if (state_machine->get_end_node() == name) {
-
int endofs = nr.node.size.x - font->get_string_size(TTR("End")).x;
state_machine_draw->draw_string(font, offset + Vector2(endofs, -font->get_height() - 3 * EDSCALE + font->get_ascent()), TTR("End"), font_color);
}
@@ -844,11 +814,11 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
}
void AnimationNodeStateMachineEditor::_state_machine_pos_draw() {
-
Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
- if (!playback.is_valid() || !playback->is_playing())
+ if (!playback.is_valid() || !playback->is_playing()) {
return;
+ }
int idx = -1;
for (int i = 0; i < node_rects.size(); i++) {
@@ -858,8 +828,9 @@ void AnimationNodeStateMachineEditor::_state_machine_pos_draw() {
}
}
- if (idx == -1)
+ if (idx == -1) {
return;
+ }
const NodeRect &nr = node_rects[idx];
@@ -885,15 +856,15 @@ void AnimationNodeStateMachineEditor::_state_machine_pos_draw() {
state_machine_play_pos->draw_line(from, to, bg, 2);
- to = from.linear_interpolate(to, c);
+ to = from.lerp(to, c);
state_machine_play_pos->draw_line(from, to, fg, 2);
}
void AnimationNodeStateMachineEditor::_update_graph() {
-
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
@@ -903,7 +874,6 @@ void AnimationNodeStateMachineEditor::_update_graph() {
}
void AnimationNodeStateMachineEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
error_panel->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree"));
error_label->add_theme_color_override("font_color", get_theme_color("error_color", "Editor"));
@@ -928,7 +898,6 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) {
}
if (p_what == NOTIFICATION_PROCESS) {
-
String error;
Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
@@ -1017,7 +986,6 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) {
}
{
-
if (last_travel_path.size() != tp.size()) {
same_travel_path = false;
} else {
@@ -1032,7 +1000,6 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) {
//update if travel state changed
if (!same_travel_path || last_active != is_playing || last_current_node != current_node || last_blend_from_node != blend_from_node) {
-
state_machine_draw->update();
last_travel_path = tp;
last_current_node = current_node;
@@ -1043,7 +1010,6 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) {
{
if (current_node != StringName() && state_machine->has_node(current_node)) {
-
String next = current_node;
Ref<AnimationNodeStateMachine> anodesm = state_machine->get_node(next);
Ref<AnimationNodeStateMachinePlayback> current_node_playback;
@@ -1063,7 +1029,6 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) {
}
if (last_play_pos != play_pos) {
-
last_play_pos = play_pos;
state_machine_play_pos->update();
}
@@ -1076,17 +1041,14 @@ void AnimationNodeStateMachineEditor::_notification(int p_what) {
}
void AnimationNodeStateMachineEditor::_open_editor(const String &p_name) {
-
AnimationTreeEditor::get_singleton()->enter_editor(p_name);
}
void AnimationNodeStateMachineEditor::_removed_from_graph() {
-
EditorNode::get_singleton()->edit_item(nullptr);
}
void AnimationNodeStateMachineEditor::_name_edited(const String &p_text) {
-
const String &new_name = p_text;
ERR_FAIL_COND(new_name == "" || new_name.find(".") != -1 || new_name.find("/") != -1);
@@ -1117,24 +1079,23 @@ void AnimationNodeStateMachineEditor::_name_edited(const String &p_text) {
}
void AnimationNodeStateMachineEditor::_name_edited_focus_out() {
-
- if (updating)
+ if (updating) {
return;
+ }
_name_edited(name_edit->get_text());
}
void AnimationNodeStateMachineEditor::_scroll_changed(double) {
-
- if (updating)
+ if (updating) {
return;
+ }
state_machine->set_graph_offset(Vector2(h_scroll->get_value(), v_scroll->get_value()));
state_machine_draw->update();
}
void AnimationNodeStateMachineEditor::_erase_selected() {
-
if (selected_node != StringName() && state_machine->has_node(selected_node)) {
updating = true;
undo_redo->create_action(TTR("Node Removed"));
@@ -1158,7 +1119,6 @@ void AnimationNodeStateMachineEditor::_erase_selected() {
}
if (selected_transition_to != StringName() && selected_transition_from != StringName() && state_machine->has_transition(selected_transition_from, selected_transition_to)) {
-
Ref<AnimationNodeStateMachineTransition> tr = state_machine->get_transition(state_machine->find_transition(selected_transition_from, selected_transition_to));
updating = true;
undo_redo->create_action(TTR("Transition Removed"));
@@ -1176,9 +1136,7 @@ void AnimationNodeStateMachineEditor::_erase_selected() {
}
void AnimationNodeStateMachineEditor::_autoplay_selected() {
-
if (selected_node != StringName() && state_machine->has_node(selected_node)) {
-
StringName new_start_node;
if (state_machine->get_start_node() == selected_node) { //toggle it
new_start_node = StringName();
@@ -1199,9 +1157,7 @@ void AnimationNodeStateMachineEditor::_autoplay_selected() {
}
void AnimationNodeStateMachineEditor::_end_selected() {
-
if (selected_node != StringName() && state_machine->has_node(selected_node)) {
-
StringName new_end_node;
if (state_machine->get_end_node() == selected_node) { //toggle it
new_end_node = StringName();
@@ -1220,8 +1176,8 @@ void AnimationNodeStateMachineEditor::_end_selected() {
state_machine_draw->update();
}
}
-void AnimationNodeStateMachineEditor::_update_mode() {
+void AnimationNodeStateMachineEditor::_update_mode() {
if (tool_select->is_pressed()) {
tool_erase_hb->show();
tool_erase->set_disabled(selected_node == StringName() && selected_transition_from == StringName() && selected_transition_to == StringName());
@@ -1233,7 +1189,6 @@ void AnimationNodeStateMachineEditor::_update_mode() {
}
void AnimationNodeStateMachineEditor::_bind_methods() {
-
ClassDB::bind_method("_update_graph", &AnimationNodeStateMachineEditor::_update_graph);
ClassDB::bind_method("_removed_from_graph", &AnimationNodeStateMachineEditor::_removed_from_graph);
@@ -1244,7 +1199,6 @@ void AnimationNodeStateMachineEditor::_bind_methods() {
AnimationNodeStateMachineEditor *AnimationNodeStateMachineEditor::singleton = nullptr;
AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
-
singleton = this;
updating = false;
diff --git a/editor/plugins/animation_state_machine_editor.h b/editor/plugins/animation_state_machine_editor.h
index 5c4fc87df5..022c32ef48 100644
--- a/editor/plugins/animation_state_machine_editor.h
+++ b/editor/plugins/animation_state_machine_editor.h
@@ -42,7 +42,6 @@
#include "scene/gui/tree.h"
class AnimationNodeStateMachineEditor : public AnimationTreeNodeEditorPlugin {
-
GDCLASS(AnimationNodeStateMachineEditor, AnimationTreeNodeEditorPlugin);
Ref<AnimationNodeStateMachine> state_machine;
diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp
index e771c5610f..ec3e25f999 100644
--- a/editor/plugins/animation_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_tree_editor_plugin.cpp
@@ -34,9 +34,9 @@
#include "animation_blend_space_2d_editor.h"
#include "animation_blend_tree_editor_plugin.h"
#include "animation_state_machine_editor.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/resource_loader.h"
-#include "core/math/delaunay.h"
+#include "core/math/delaunay_2d.h"
#include "core/os/keyboard.h"
#include "core/project_settings.h"
#include "editor/editor_scale.h"
@@ -48,9 +48,9 @@
#include "scene/scene_string_names.h"
void AnimationTreeEditor::edit(AnimationTree *p_tree) {
-
- if (tree == p_tree)
+ if (tree == p_tree) {
return;
+ }
tree = p_tree;
@@ -64,7 +64,6 @@ void AnimationTreeEditor::edit(AnimationTree *p_tree) {
}
void AnimationTreeEditor::_path_button_pressed(int p_path) {
-
edited_path.clear();
for (int i = 0; i <= p_path; i++) {
edited_path.push_back(button_path[i]);
@@ -100,7 +99,6 @@ void AnimationTreeEditor::_update_path() {
}
void AnimationTreeEditor::edit_path(const Vector<String> &p_path) {
-
button_path.clear();
Ref<AnimationNode> node = tree->get_tree_root();
@@ -109,7 +107,6 @@ void AnimationTreeEditor::edit_path(const Vector<String> &p_path) {
current_root = node->get_instance_id();
for (int i = 0; i < p_path.size(); i++) {
-
Ref<AnimationNode> child = node->get_child_by_name(p_path[i]);
ERR_BREAK(child.is_null());
node = child;
@@ -140,7 +137,6 @@ Vector<String> AnimationTreeEditor::get_edited_path() const {
}
void AnimationTreeEditor::enter_editor(const String &p_path) {
-
Vector<String> path = edited_path;
path.push_back(p_path);
edit_path(path);
@@ -204,19 +200,20 @@ bool AnimationTreeEditor::can_edit(const Ref<AnimationNode> &p_node) const {
}
Vector<String> AnimationTreeEditor::get_animation_list() {
-
if (!singleton->is_visible()) {
return Vector<String>();
}
AnimationTree *tree = singleton->tree;
- if (!tree || !tree->has_node(tree->get_animation_player()))
+ if (!tree || !tree->has_node(tree->get_animation_player())) {
return Vector<String>();
+ }
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(tree->get_node(tree->get_animation_player()));
- if (!ap)
+ if (!ap) {
return Vector<String>();
+ }
List<StringName> anims;
ap->get_animation_list(&anims);
@@ -229,7 +226,6 @@ Vector<String> AnimationTreeEditor::get_animation_list() {
}
AnimationTreeEditor::AnimationTreeEditor() {
-
AnimationNodeAnimation::get_editable_animation_list = get_animation_list;
path_edit = memnew(ScrollContainer);
add_child(path_edit);
@@ -253,17 +249,14 @@ AnimationTreeEditor::AnimationTreeEditor() {
}
void AnimationTreeEditorPlugin::edit(Object *p_object) {
-
anim_tree_editor->edit(Object::cast_to<AnimationTree>(p_object));
}
bool AnimationTreeEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("AnimationTree");
}
void AnimationTreeEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
//editor->hide_animation_player_editors();
//editor->animation_panel_make_visible(true);
@@ -271,16 +264,15 @@ void AnimationTreeEditorPlugin::make_visible(bool p_visible) {
editor->make_bottom_panel_item_visible(anim_tree_editor);
anim_tree_editor->set_process(true);
} else {
-
- if (anim_tree_editor->is_visible_in_tree())
+ if (anim_tree_editor->is_visible_in_tree()) {
editor->hide_bottom_panel();
+ }
button->hide();
anim_tree_editor->set_process(false);
}
}
AnimationTreeEditorPlugin::AnimationTreeEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
anim_tree_editor = memnew(AnimationTreeEditor);
anim_tree_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
diff --git a/editor/plugins/animation_tree_editor_plugin.h b/editor/plugins/animation_tree_editor_plugin.h
index 0b93b0fd8e..25af81ea9b 100644
--- a/editor/plugins/animation_tree_editor_plugin.h
+++ b/editor/plugins/animation_tree_editor_plugin.h
@@ -49,7 +49,6 @@ public:
};
class AnimationTreeEditor : public VBoxContainer {
-
GDCLASS(AnimationTreeEditor, VBoxContainer);
ScrollContainer *path_edit;
@@ -95,7 +94,6 @@ public:
};
class AnimationTreeEditorPlugin : public EditorPlugin {
-
GDCLASS(AnimationTreeEditorPlugin, EditorPlugin);
AnimationTreeEditor *anim_tree_editor;
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 14c44b7973..da170cd498 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -30,7 +30,7 @@
#include "asset_library_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/json.h"
#include "core/os/keyboard.h"
#include "core/version.h"
@@ -40,7 +40,6 @@
#include "editor/project_settings_editor.h"
void EditorAssetLibraryItem::configure(const String &p_title, int p_asset_id, const String &p_category, int p_category_id, const String &p_author, int p_author_id, const String &p_cost) {
-
title->set_text(p_title);
asset_id = p_asset_id;
category->set_text(p_category);
@@ -51,7 +50,6 @@ void EditorAssetLibraryItem::configure(const String &p_title, int p_asset_id, co
}
void EditorAssetLibraryItem::set_image(int p_type, int p_index, const Ref<Texture2D> &p_image) {
-
ERR_FAIL_COND(p_type != EditorAssetLibrary::IMAGE_QUEUE_ICON);
ERR_FAIL_COND(p_index != 0);
@@ -59,9 +57,7 @@ void EditorAssetLibraryItem::set_image(int p_type, int p_index, const Ref<Textur
}
void EditorAssetLibraryItem::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
icon->set_normal_texture(get_theme_icon("ProjectIconLoading", "EditorIcons"));
category->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
author->add_theme_color_override("font_color", Color(0.5, 0.5, 0.5));
@@ -70,21 +66,18 @@ void EditorAssetLibraryItem::_notification(int p_what) {
}
void EditorAssetLibraryItem::_asset_clicked() {
-
emit_signal("asset_selected", asset_id);
}
void EditorAssetLibraryItem::_category_clicked() {
-
emit_signal("category_selected", category_id);
}
-void EditorAssetLibraryItem::_author_clicked() {
+void EditorAssetLibraryItem::_author_clicked() {
emit_signal("author_selected", author_id);
}
void EditorAssetLibraryItem::_bind_methods() {
-
ClassDB::bind_method("set_image", &EditorAssetLibraryItem::set_image);
ADD_SIGNAL(MethodInfo("asset_selected"));
ADD_SIGNAL(MethodInfo("category_selected"));
@@ -92,7 +85,6 @@ void EditorAssetLibraryItem::_bind_methods() {
}
EditorAssetLibraryItem::EditorAssetLibraryItem() {
-
Ref<StyleBoxEmpty> border;
border.instance();
border->set_default_margin(MARGIN_LEFT, 5 * EDSCALE);
@@ -143,16 +135,12 @@ EditorAssetLibraryItem::EditorAssetLibraryItem() {
//////////////////////////////////////////////////////////////////////////////
void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const Ref<Texture2D> &p_image) {
-
switch (p_type) {
-
case EditorAssetLibrary::IMAGE_QUEUE_ICON: {
-
item->call("set_image", p_type, p_index, p_image);
icon = p_image;
} break;
case EditorAssetLibrary::IMAGE_QUEUE_THUMBNAIL: {
-
for (int i = 0; i < preview_images.size(); i++) {
if (preview_images[i].id == p_index) {
if (preview_images[i].is_video) {
@@ -181,7 +169,6 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const
}
} break;
case EditorAssetLibrary::IMAGE_QUEUE_SCREENSHOT: {
-
for (int i = 0; i < preview_images.size(); i++) {
if (preview_images[i].id == p_index) {
preview_images.write[i].image = p_image;
@@ -231,7 +218,6 @@ void EditorAssetLibraryItemDescription::_preview_click(int p_id) {
}
void EditorAssetLibraryItemDescription::configure(const String &p_title, int p_asset_id, const String &p_category, int p_category_id, const String &p_author, int p_author_id, const String &p_cost, int p_version, const String &p_version_string, const String &p_description, const String &p_download_url, const String &p_browse_url, const String &p_sha256_hash) {
-
asset_id = p_asset_id;
title = p_title;
download_url = p_download_url;
@@ -249,7 +235,6 @@ void EditorAssetLibraryItemDescription::configure(const String &p_title, int p_a
}
void EditorAssetLibraryItemDescription::add_preview(int p_id, bool p_video, const String &p_url) {
-
Preview preview;
preview.id = p_id;
preview.video_link = p_url;
@@ -270,7 +255,6 @@ void EditorAssetLibraryItemDescription::add_preview(int p_id, bool p_video, cons
}
EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() {
-
HBoxContainer *hbox = memnew(HBoxContainer);
add_child(hbox);
VBoxContainer *desc_vbox = memnew(VBoxContainer);
@@ -314,14 +298,13 @@ EditorAssetLibraryItemDescription::EditorAssetLibraryItemDescription() {
get_ok()->set_text(TTR("Download"));
get_cancel()->set_text(TTR("Close"));
}
+
///////////////////////////////////////////////////////////////////////////////////
void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) {
-
String error_text;
switch (p_status) {
-
case HTTPRequest::RESULT_CHUNKED_BODY_SIZE_MISMATCH:
case HTTPRequest::RESULT_CONNECTION_ERROR:
case HTTPRequest::RESULT_BODY_SIZE_LIMIT_EXCEEDED: {
@@ -388,29 +371,25 @@ void EditorAssetLibraryItemDownload::_http_download_completed(int p_status, int
}
void EditorAssetLibraryItemDownload::configure(const String &p_title, int p_asset_id, const Ref<Texture2D> &p_preview, const String &p_download_url, const String &p_sha256_hash) {
-
title->set_text(p_title);
icon->set_texture(p_preview);
asset_id = p_asset_id;
- if (!p_preview.is_valid())
+ if (!p_preview.is_valid()) {
icon->set_texture(get_theme_icon("FileBrokenBigThumb", "EditorIcons"));
+ }
host = p_download_url;
sha256 = p_sha256_hash;
_make_request();
}
void EditorAssetLibraryItemDownload::_notification(int p_what) {
-
switch (p_what) {
-
// FIXME: The editor crashes if 'NOTICATION_THEME_CHANGED' is used.
case NOTIFICATION_ENTER_TREE: {
-
add_theme_style_override("panel", get_theme_stylebox("panel", "TabContainer"));
dismiss->set_normal_texture(get_theme_icon("Close", "EditorIcons"));
} break;
case NOTIFICATION_PROCESS: {
-
// Make the progress bar visible again when retrying the download.
progress->set_modulate(Color(1, 1, 1, 1));
@@ -438,7 +417,6 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) {
if (cstatus != prev_status) {
switch (cstatus) {
-
case HTTPClient::STATUS_RESOLVING: {
status->set_text(TTR("Resolving..."));
progress->set_max(1);
@@ -462,15 +440,14 @@ void EditorAssetLibraryItemDownload::_notification(int p_what) {
} break;
}
}
-void EditorAssetLibraryItemDownload::_close() {
+void EditorAssetLibraryItemDownload::_close() {
// Clean up downloaded file.
DirAccess::remove_file_or_error(download->get_download_file());
queue_delete();
}
void EditorAssetLibraryItemDownload::_install() {
-
String file = download->get_download_file();
if (external_install) {
@@ -494,12 +471,10 @@ void EditorAssetLibraryItemDownload::_make_request() {
}
void EditorAssetLibraryItemDownload::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("install_asset", PropertyInfo(Variant::STRING, "zip_path"), PropertyInfo(Variant::STRING, "name")));
}
EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
-
HBoxContainer *hb = memnew(HBoxContainer);
add_child(hb);
icon = memnew(TextureRect);
@@ -566,11 +541,8 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() {
////////////////////////////////////////////////////////////////////////////////
void EditorAssetLibrary::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_READY: {
-
error_tr->set_texture(get_theme_icon("Error", "EditorIcons"));
filter->set_right_icon(get_theme_icon("Search", "EditorIcons"));
filter->set_clear_button_enabled(true);
@@ -578,13 +550,11 @@ void EditorAssetLibrary::_notification(int p_what) {
error_label->raise();
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
if (is_visible() && initial_loading) {
_repository_changed(0); // Update when shown for the first time.
}
} break;
case NOTIFICATION_PROCESS: {
-
HTTPClient::Status s = request->get_http_client_status();
const bool loading = s != HTTPClient::STATUS_DISCONNECTED;
@@ -601,7 +571,6 @@ void EditorAssetLibrary::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
-
library_scroll_bg->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree"));
downloads_scroll->add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
error_tr->set_texture(get_theme_icon("Error", "EditorIcons"));
@@ -612,13 +581,10 @@ void EditorAssetLibrary::_notification(int p_what) {
}
void EditorAssetLibrary::_unhandled_input(const Ref<InputEvent> &p_event) {
-
const Ref<InputEventKey> key = p_event;
if (key.is_valid() && key->is_pressed()) {
-
if (key->get_keycode_with_modifiers() == (KEY_MASK_CMD | KEY_F) && is_visible_in_tree()) {
-
filter->grab_focus();
filter->select_all();
accept_event();
@@ -627,16 +593,14 @@ void EditorAssetLibrary::_unhandled_input(const Ref<InputEvent> &p_event) {
}
void EditorAssetLibrary::_install_asset() {
-
ERR_FAIL_COND(!description);
for (int i = 0; i < downloads_hb->get_child_count(); i++) {
-
EditorAssetLibraryItemDownload *d = Object::cast_to<EditorAssetLibraryItemDownload>(downloads_hb->get_child(i));
if (d && d->get_asset_id() == description->get_asset_id()) {
-
- if (EditorNode::get_singleton() != nullptr)
+ if (EditorNode::get_singleton() != nullptr) {
EditorNode::get_singleton()->show_warning(TTR("Download for this asset is already in progress!"));
+ }
return;
}
}
@@ -676,16 +640,14 @@ const char *EditorAssetLibrary::support_key[SUPPORT_MAX] = {
};
void EditorAssetLibrary::_select_author(int p_id) {
-
// Open author window.
}
void EditorAssetLibrary::_select_category(int p_id) {
-
for (int i = 0; i < categories->get_item_count(); i++) {
-
- if (i == 0)
+ if (i == 0) {
continue;
+ }
int id = categories->get_item_metadata(i);
if (id == p_id) {
categories->select(i);
@@ -694,8 +656,8 @@ void EditorAssetLibrary::_select_category(int p_id) {
}
}
}
-void EditorAssetLibrary::_select_asset(int p_id) {
+void EditorAssetLibrary::_select_asset(int p_id) {
_api_request("asset/" + itos(p_id), REQUESTING_ASSET);
}
@@ -780,11 +742,9 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PackedB
}
void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data, int p_queue_id) {
-
ERR_FAIL_COND(!image_queue.has(p_queue_id));
if (p_status == HTTPRequest::RESULT_SUCCESS && p_code < HTTPClient::RESPONSE_BAD_REQUEST) {
-
if (p_code != HTTPClient::RESPONSE_NOT_MODIFIED) {
for (int i = 0; i < headers.size(); i++) {
if (headers[i].findn("ETag:") == 0) { // Save etag
@@ -830,14 +790,12 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons
}
void EditorAssetLibrary::_update_image_queue() {
-
const int max_images = 6;
int current_images = 0;
List<int> to_delete;
for (Map<int, ImageQueue>::Element *E = image_queue.front(); E; E = E->next()) {
if (!E->get().active && current_images < max_images) {
-
String cache_filename_base = EditorSettings::get_singleton()->get_cache_dir().plus_file("assetimage_" + E->get().image_url.md5_text());
Vector<String> headers;
@@ -870,7 +828,6 @@ void EditorAssetLibrary::_update_image_queue() {
}
void EditorAssetLibrary::_request_image(ObjectID p_for, String p_image_url, ImageType p_type, int p_image_index) {
-
ImageQueue iq;
iq.image_url = p_image_url;
iq.image_index = p_image_index;
@@ -911,7 +868,6 @@ void EditorAssetLibrary::_rerun_search(int p_ignore) {
}
void EditorAssetLibrary::_search(int p_page) {
-
String args;
if (templates_only) {
@@ -935,7 +891,6 @@ void EditorAssetLibrary::_search(int p_page) {
}
if (categories->get_selected() > 0) {
-
args += "&category=" + itos(categories->get_item_metadata(categories->get_selected()));
}
@@ -956,24 +911,25 @@ void EditorAssetLibrary::_search(int p_page) {
}
void EditorAssetLibrary::_search_text_entered(const String &p_text) {
-
_search();
}
HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int p_page_len, int p_total_items, int p_current_items) {
-
HBoxContainer *hbc = memnew(HBoxContainer);
- if (p_page_count < 2)
+ if (p_page_count < 2) {
return hbc;
+ }
//do the mario
int from = p_page - 5;
- if (from < 0)
+ if (from < 0) {
from = 0;
+ }
int to = from + 10;
- if (to > p_page_count)
+ if (to > p_page_count) {
to = p_page_count;
+ }
hbc->add_spacer();
hbc->add_theme_constant_override("separation", 5 * EDSCALE);
@@ -1000,9 +956,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
hbc->add_child(memnew(VSeparator));
for (int i = from; i < to; i++) {
-
if (i == p_page) {
-
Button *current = memnew(Button);
current->set_text(itos(i + 1));
current->set_disabled(true);
@@ -1010,7 +964,6 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
hbc->add_child(current);
} else {
-
Button *current = memnew(Button);
current->set_text(itos(i + 1));
current->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), varray(i));
@@ -1046,7 +999,6 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
}
void EditorAssetLibrary::_api_request(const String &p_request, RequestType p_request_type, const String &p_arguments) {
-
if (requesting != REQUESTING_NONE) {
request->cancel_request();
}
@@ -1058,7 +1010,6 @@ void EditorAssetLibrary::_api_request(const String &p_request, RequestType p_req
}
void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) {
-
String str;
{
@@ -1070,7 +1021,6 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
bool error_abort = true;
switch (p_status) {
-
case HTTPRequest::RESULT_CANT_RESOLVE: {
error_label->set_text(TTR("Can't resolve hostname:") + " " + host);
} break;
@@ -1097,7 +1047,6 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
if (p_code != 200) {
error_label->set_text(TTR("Request failed, return code:") + " " + itos(p_code));
} else {
-
error_abort = false;
}
} break;
@@ -1122,7 +1071,6 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
switch (requested) {
case REQUESTING_CONFIG: {
-
categories->clear();
categories->add_item(TTR("All"));
categories->set_item_metadata(0, 0);
@@ -1130,8 +1078,9 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
Array clist = d["categories"];
for (int i = 0; i < clist.size(); i++) {
Dictionary cat = clist[i];
- if (!cat.has("name") || !cat.has("id"))
+ if (!cat.has("name") || !cat.has("id")) {
continue;
+ }
String name = cat["name"];
int id = cat["id"];
categories->add_item(name);
@@ -1143,7 +1092,6 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
_search();
} break;
case REQUESTING_SEARCH: {
-
initial_loading = false;
// The loading text only needs to be displayed before the first page is loaded.
@@ -1214,7 +1162,6 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
}
for (int i = 0; i < result.size(); i++) {
-
Dictionary r = result[i];
ERR_CONTINUE(!r.has("title"));
@@ -1273,7 +1220,6 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
Array previews = d["previews"];
for (int i = 0; i < previews.size(); i++) {
-
Dictionary p = previews[i];
ERR_CONTINUE(!p.has("type"));
@@ -1297,12 +1243,12 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
}
}
} break;
- default: break;
+ default:
+ break;
}
}
void EditorAssetLibrary::_asset_file_selected(const String &p_file) {
-
if (asset_installer) {
memdelete(asset_installer);
asset_installer = nullptr;
@@ -1314,18 +1260,15 @@ void EditorAssetLibrary::_asset_file_selected(const String &p_file) {
}
void EditorAssetLibrary::_asset_open() {
-
asset_open->popup_centered_ratio();
}
void EditorAssetLibrary::_manage_plugins() {
-
ProjectSettingsEditor::get_singleton()->popup_project_settings();
ProjectSettingsEditor::get_singleton()->set_plugins_page();
}
void EditorAssetLibrary::_install_external_asset(String p_zip_path, String p_title) {
-
emit_signal("install_asset", p_zip_path, p_title);
}
@@ -1334,14 +1277,12 @@ void EditorAssetLibrary::disable_community_support() {
}
void EditorAssetLibrary::_bind_methods() {
-
ClassDB::bind_method("_unhandled_input", &EditorAssetLibrary::_unhandled_input);
ADD_SIGNAL(MethodInfo("install_asset", PropertyInfo(Variant::STRING, "zip_path"), PropertyInfo(Variant::STRING, "name")));
}
EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
-
requesting = REQUESTING_NONE;
templates_only = p_templates_only;
initial_loading = true;
@@ -1363,8 +1304,9 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
search->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search), make_binds(0));
search_hb->add_child(search);
- if (!p_templates_only)
+ if (!p_templates_only) {
search_hb->add_child(memnew(VSeparator));
+ }
Button *open_asset = memnew(Button);
open_asset->set_text(TTR("Import..."));
@@ -1526,18 +1468,14 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
///////
void AssetLibraryEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
-
addon_library->show();
} else {
-
addon_library->hide();
}
}
AssetLibraryEditorPlugin::AssetLibraryEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
addon_library = memnew(EditorAssetLibrary);
addon_library->set_v_size_flags(Control::SIZE_EXPAND_FILL);
diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h
index 536a855d03..d5d381dee3 100644
--- a/editor/plugins/asset_library_editor_plugin.h
+++ b/editor/plugins/asset_library_editor_plugin.h
@@ -50,7 +50,6 @@
#include "scene/main/http_request.h"
class EditorAssetLibraryItem : public PanelContainer {
-
GDCLASS(EditorAssetLibraryItem, PanelContainer);
TextureButton *icon;
@@ -81,7 +80,6 @@ public:
};
class EditorAssetLibraryItemDescription : public ConfirmationDialog {
-
GDCLASS(EditorAssetLibraryItemDescription, ConfirmationDialog);
EditorAssetLibraryItem *item;
@@ -129,7 +127,6 @@ public:
};
class EditorAssetLibraryItemDownload : public PanelContainer {
-
GDCLASS(EditorAssetLibraryItemDownload, PanelContainer);
TextureRect *icon;
@@ -237,7 +234,6 @@ class EditorAssetLibrary : public PanelContainer {
};
struct ImageQueue {
-
bool active;
int queue_id;
ImageType image_type;
@@ -309,7 +305,6 @@ public:
};
class AssetLibraryEditorPlugin : public EditorPlugin {
-
GDCLASS(AssetLibraryEditorPlugin, EditorPlugin);
EditorAssetLibrary *addon_library;
diff --git a/editor/plugins/audio_stream_editor_plugin.cpp b/editor/plugins/audio_stream_editor_plugin.cpp
index 0459ac7618..3b7a9320f0 100644
--- a/editor/plugins/audio_stream_editor_plugin.cpp
+++ b/editor/plugins/audio_stream_editor_plugin.cpp
@@ -37,7 +37,6 @@
#include "editor/editor_settings.h"
void AudioStreamEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_READY) {
AudioStreamPreviewGenerator::get_singleton()->connect("preview_updated", callable_mp(this, &AudioStreamEditor::_preview_changed));
}
@@ -75,7 +74,6 @@ void AudioStreamEditor::_draw_preview() {
lines.resize(size.width * 2);
for (int i = 0; i < size.width; i++) {
-
float ofs = i * preview_len / size.width;
float ofs_n = (i + 1) * preview_len / size.width;
float max = preview->get_max(ofs, ofs_n) * 0.5 + 0.5;
@@ -93,21 +91,19 @@ void AudioStreamEditor::_draw_preview() {
}
void AudioStreamEditor::_preview_changed(ObjectID p_which) {
-
if (stream.is_valid() && stream->get_instance_id() == p_which) {
_preview->update();
}
}
void AudioStreamEditor::_changed_callback(Object *p_changed, const char *p_prop) {
-
- if (!is_visible())
+ if (!is_visible()) {
return;
+ }
update();
}
void AudioStreamEditor::_play() {
-
if (_player->is_playing()) {
_player->stop();
_play_button->set_icon(get_theme_icon("MainPlay", "EditorIcons"));
@@ -120,7 +116,6 @@ void AudioStreamEditor::_play() {
}
void AudioStreamEditor::_stop() {
-
_player->stop();
_play_button->set_icon(get_theme_icon("MainPlay", "EditorIcons"));
_current = 0;
@@ -129,7 +124,6 @@ void AudioStreamEditor::_stop() {
}
void AudioStreamEditor::_on_finished() {
-
_play_button->set_icon(get_theme_icon("MainPlay", "EditorIcons"));
if (_current == _player->get_stream()->get_length()) {
_current = 0;
@@ -138,7 +132,6 @@ void AudioStreamEditor::_on_finished() {
}
void AudioStreamEditor::_draw_indicator() {
-
if (!stream.is_valid()) {
return;
}
@@ -178,9 +171,9 @@ void AudioStreamEditor::_seek_to(real_t p_x) {
}
void AudioStreamEditor::edit(Ref<AudioStream> p_stream) {
-
- if (!stream.is_null())
+ if (!stream.is_null()) {
stream->remove_change_receptor(this);
+ }
stream = p_stream;
_player->set_stream(stream);
@@ -200,7 +193,6 @@ void AudioStreamEditor::_bind_methods() {
}
AudioStreamEditor::AudioStreamEditor() {
-
set_custom_minimum_size(Size2(1, 100) * EDSCALE);
_current = 0;
_dragging = false;
@@ -251,26 +243,23 @@ AudioStreamEditor::AudioStreamEditor() {
}
void AudioStreamEditorPlugin::edit(Object *p_object) {
-
AudioStream *s = Object::cast_to<AudioStream>(p_object);
- if (!s)
+ if (!s) {
return;
+ }
audio_editor->edit(Ref<AudioStream>(s));
}
bool AudioStreamEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("AudioStream");
}
void AudioStreamEditorPlugin::make_visible(bool p_visible) {
-
audio_editor->set_visible(p_visible);
}
AudioStreamEditorPlugin::AudioStreamEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
audio_editor = memnew(AudioStreamEditor);
add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM, audio_editor);
diff --git a/editor/plugins/audio_stream_editor_plugin.h b/editor/plugins/audio_stream_editor_plugin.h
index 2191b541f6..dd7caaa15e 100644
--- a/editor/plugins/audio_stream_editor_plugin.h
+++ b/editor/plugins/audio_stream_editor_plugin.h
@@ -38,7 +38,6 @@
#include "scene/resources/texture.h"
class AudioStreamEditor : public ColorRect {
-
GDCLASS(AudioStreamEditor, ColorRect);
Ref<AudioStream> stream;
@@ -73,7 +72,6 @@ public:
};
class AudioStreamEditorPlugin : public EditorPlugin {
-
GDCLASS(AudioStreamEditorPlugin, EditorPlugin);
AudioStreamEditor *audio_editor;
diff --git a/editor/plugins/baked_lightmap_editor_plugin.cpp b/editor/plugins/baked_lightmap_editor_plugin.cpp
index ba161244d6..8fbe1646f7 100644
--- a/editor/plugins/baked_lightmap_editor_plugin.cpp
+++ b/editor/plugins/baked_lightmap_editor_plugin.cpp
@@ -28,23 +28,35 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if 0
#include "baked_lightmap_editor_plugin.h"
-void BakedLightmapEditorPlugin::_bake() {
-
+void BakedLightmapEditorPlugin::_bake_select_file(const String &p_file) {
if (lightmap) {
BakedLightmap::BakeError err;
if (get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root() == lightmap) {
- err = lightmap->bake(lightmap);
+ err = lightmap->bake(lightmap, p_file, bake_func_step);
} else {
- err = lightmap->bake(lightmap->get_parent());
+ err = lightmap->bake(lightmap->get_parent(), p_file, bake_func_step);
}
+ bake_func_end();
+
switch (err) {
- case BakedLightmap::BAKE_ERROR_NO_SAVE_PATH:
- EditorNode::get_singleton()->show_warning(TTR("Can't determine a save path for lightmap images.\nSave your scene (for images to be saved in the same dir), or pick a save path from the BakedLightmap properties."));
- break;
+ case BakedLightmap::BAKE_ERROR_NO_SAVE_PATH: {
+ String scene_path = lightmap->get_filename();
+ if (scene_path == String()) {
+ scene_path = lightmap->get_owner()->get_filename();
+ }
+ if (scene_path == String()) {
+ EditorNode::get_singleton()->show_warning(TTR("Can't determine a save path for lightmap images.\nSave your scene and try again."));
+ break;
+ }
+ scene_path = scene_path.get_basename() + ".lmbake";
+
+ file_dialog->set_current_path(scene_path);
+ file_dialog->popup_centered_ratio();
+
+ } break;
case BakedLightmap::BAKE_ERROR_NO_MESHES:
EditorNode::get_singleton()->show_warning(TTR("No meshes to bake. Make sure they contain an UV2 channel and that the 'Bake Light' flag is on."));
break;
@@ -57,72 +69,69 @@ void BakedLightmapEditorPlugin::_bake() {
}
}
-void BakedLightmapEditorPlugin::edit(Object *p_object) {
+void BakedLightmapEditorPlugin::_bake() {
+ _bake_select_file("");
+}
+void BakedLightmapEditorPlugin::edit(Object *p_object) {
BakedLightmap *s = Object::cast_to<BakedLightmap>(p_object);
- if (!s)
+ if (!s) {
return;
+ }
lightmap = s;
}
bool BakedLightmapEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("BakedLightmap");
}
void BakedLightmapEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
bake->show();
} else {
-
bake->hide();
}
}
EditorProgress *BakedLightmapEditorPlugin::tmp_progress = nullptr;
-void BakedLightmapEditorPlugin::bake_func_begin(int p_steps) {
-
- ERR_FAIL_COND(tmp_progress != nullptr);
-
- tmp_progress = memnew(EditorProgress("bake_lightmaps", TTR("Bake Lightmaps"), p_steps, true));
-}
-
-bool BakedLightmapEditorPlugin::bake_func_step(int p_step, const String &p_description) {
-
- ERR_FAIL_COND_V(tmp_progress == nullptr, false);
- return tmp_progress->step(p_description, p_step, false);
+bool BakedLightmapEditorPlugin::bake_func_step(float p_progress, const String &p_description, void *, bool p_refresh) {
+ if (!tmp_progress) {
+ tmp_progress = memnew(EditorProgress("bake_lightmaps", TTR("Bake Lightmaps"), 1000, false));
+ ERR_FAIL_COND_V(tmp_progress == nullptr, false);
+ }
+ return tmp_progress->step(p_description, p_progress * 1000, p_refresh);
}
void BakedLightmapEditorPlugin::bake_func_end() {
- ERR_FAIL_COND(tmp_progress == nullptr);
- memdelete(tmp_progress);
- tmp_progress = nullptr;
+ if (tmp_progress != nullptr) {
+ memdelete(tmp_progress);
+ tmp_progress = nullptr;
+ }
}
void BakedLightmapEditorPlugin::_bind_methods() {
-
ClassDB::bind_method("_bake", &BakedLightmapEditorPlugin::_bake);
}
BakedLightmapEditorPlugin::BakedLightmapEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
bake = memnew(ToolButton);
- bake->set_icon(editor->get_gui_base()->get_icon("Bake", "EditorIcons"));
+ bake->set_icon(editor->get_gui_base()->get_theme_icon("Bake", "EditorIcons"));
bake->set_text(TTR("Bake Lightmaps"));
bake->hide();
- bake->connect("pressed", this, "_bake");
+ bake->connect("pressed", Callable(this, "_bake"));
add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake);
lightmap = nullptr;
- BakedLightmap::bake_begin_function = bake_func_begin;
- BakedLightmap::bake_step_function = bake_func_step;
- BakedLightmap::bake_end_function = bake_func_end;
+ file_dialog = memnew(EditorFileDialog);
+ file_dialog->set_file_mode(EditorFileDialog::FILE_MODE_SAVE_FILE);
+ file_dialog->add_filter("*.lmbake ; LightMap Bake");
+ file_dialog->set_title(TTR("Select lightmap bake file:"));
+ file_dialog->connect("file_selected", callable_mp(this, &BakedLightmapEditorPlugin::_bake_select_file));
+ bake->add_child(file_dialog);
}
BakedLightmapEditorPlugin::~BakedLightmapEditorPlugin() {
}
-#endif
diff --git a/editor/plugins/baked_lightmap_editor_plugin.h b/editor/plugins/baked_lightmap_editor_plugin.h
index 818cdfe8fa..67fb368a86 100644
--- a/editor/plugins/baked_lightmap_editor_plugin.h
+++ b/editor/plugins/baked_lightmap_editor_plugin.h
@@ -28,7 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if 0
#ifndef BAKED_LIGHTMAP_EDITOR_PLUGIN_H
#define BAKED_LIGHTMAP_EDITOR_PLUGIN_H
@@ -38,7 +37,6 @@
#include "scene/resources/material.h"
class BakedLightmapEditorPlugin : public EditorPlugin {
-
GDCLASS(BakedLightmapEditorPlugin, EditorPlugin);
BakedLightmap *lightmap;
@@ -46,11 +44,12 @@ class BakedLightmapEditorPlugin : public EditorPlugin {
ToolButton *bake;
EditorNode *editor;
+ EditorFileDialog *file_dialog;
static EditorProgress *tmp_progress;
- static void bake_func_begin(int p_steps);
- static bool bake_func_step(int p_step, const String &p_description);
+ static bool bake_func_step(float p_progress, const String &p_description, void *, bool p_refresh);
static void bake_func_end();
+ void _bake_select_file(const String &p_file);
void _bake();
protected:
@@ -67,5 +66,4 @@ public:
~BakedLightmapEditorPlugin();
};
-#endif // BAKED_LIGHTMAP_EDITOR_PLUGIN_H
#endif
diff --git a/editor/plugins/camera_3d_editor_plugin.cpp b/editor/plugins/camera_3d_editor_plugin.cpp
index 8bc1374269..48f9f208a5 100644
--- a/editor/plugins/camera_3d_editor_plugin.cpp
+++ b/editor/plugins/camera_3d_editor_plugin.cpp
@@ -33,7 +33,6 @@
#include "node_3d_editor_plugin.h"
void Camera3DEditor::_node_removed(Node *p_node) {
-
if (p_node == node) {
node = nullptr;
Node3DEditor::get_singleton()->set_custom_camera(nullptr);
@@ -42,7 +41,6 @@ void Camera3DEditor::_node_removed(Node *p_node) {
}
void Camera3DEditor::_pressed() {
-
Node *sn = (node && preview->is_pressed()) ? node : nullptr;
Node3DEditor::get_singleton()->set_custom_camera(sn);
}
@@ -51,23 +49,21 @@ void Camera3DEditor::_bind_methods() {
}
void Camera3DEditor::edit(Node *p_camera) {
-
node = p_camera;
if (!node) {
preview->set_pressed(false);
Node3DEditor::get_singleton()->set_custom_camera(nullptr);
} else {
-
- if (preview->is_pressed())
+ if (preview->is_pressed()) {
Node3DEditor::get_singleton()->set_custom_camera(p_camera);
- else
+ } else {
Node3DEditor::get_singleton()->set_custom_camera(nullptr);
+ }
}
}
Camera3DEditor::Camera3DEditor() {
-
preview = memnew(Button);
add_child(preview);
@@ -83,18 +79,15 @@ Camera3DEditor::Camera3DEditor() {
}
void Camera3DEditorPlugin::edit(Object *p_object) {
-
Node3DEditor::get_singleton()->set_can_preview(Object::cast_to<Camera3D>(p_object));
//camera_editor->edit(Object::cast_to<Node>(p_object));
}
bool Camera3DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("Camera3D");
}
void Camera3DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
//Node3DEditor::get_singleton()->set_can_preview(Object::cast_to<Camera3D>(p_object));
} else {
@@ -103,7 +96,6 @@ void Camera3DEditorPlugin::make_visible(bool p_visible) {
}
Camera3DEditorPlugin::Camera3DEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
/* camera_editor = memnew( CameraEditor );
editor->get_viewport()->add_child(camera_editor);
diff --git a/editor/plugins/camera_3d_editor_plugin.h b/editor/plugins/camera_3d_editor_plugin.h
index 1e57ac7cd2..2603229a46 100644
--- a/editor/plugins/camera_3d_editor_plugin.h
+++ b/editor/plugins/camera_3d_editor_plugin.h
@@ -36,7 +36,6 @@
#include "scene/3d/camera_3d.h"
class Camera3DEditor : public Control {
-
GDCLASS(Camera3DEditor, Control);
Panel *panel;
@@ -55,7 +54,6 @@ public:
};
class Camera3DEditorPlugin : public EditorPlugin {
-
GDCLASS(Camera3DEditorPlugin, EditorPlugin);
//CameraEditor *camera_editor;
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index cd3df08276..8f88612ffa 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -30,7 +30,7 @@
#include "canvas_item_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/keyboard.h"
#include "core/print_string.h"
#include "core/project_settings.h"
@@ -61,7 +61,6 @@
#define MOVE_HANDLE_DISTANCE 25
class SnapDialog : public ConfirmationDialog {
-
GDCLASS(SnapDialog, ConfirmationDialog);
friend class CanvasItemEditor;
@@ -252,7 +251,6 @@ void CanvasItemEditor::_snap_if_closer_float(
float &r_current_snap, SnapTarget &r_current_snap_target,
float p_target_value, SnapTarget p_snap_target,
float p_radius) {
-
float radius = p_radius / zoom;
float dist = Math::abs(p_value - p_target_value);
if ((p_radius < 0 || dist < radius) && (r_current_snap_target == SNAP_TARGET_NONE || dist < Math::abs(r_current_snap - p_value))) {
@@ -267,7 +265,6 @@ void CanvasItemEditor::_snap_if_closer_point(
Point2 p_target_value, SnapTarget p_snap_target,
real_t rotation,
float p_radius) {
-
Transform2D rot_trans = Transform2D(rotation, Point2());
p_value = rot_trans.inverse().xform(p_value);
p_target_value = rot_trans.inverse().xform(p_target_value);
@@ -330,11 +327,10 @@ void CanvasItemEditor::_snap_other_nodes(
}
Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsigned int p_forced_modes, const CanvasItem *p_self_canvas_item, List<CanvasItem *> p_other_nodes_exceptions) {
-
snap_target[0] = SNAP_TARGET_NONE;
snap_target[1] = SNAP_TARGET_NONE;
- bool is_snap_active = smart_snap_active ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool is_snap_active = smart_snap_active ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL);
// Smart snap using the canvas position
Vector2 output = p_target;
@@ -462,7 +458,7 @@ Point2 CanvasItemEditor::snap_point(Point2 p_target, unsigned int p_modes, unsig
}
float CanvasItemEditor::snap_angle(float p_target, float p_start) const {
- if (((smart_snap_active || snap_rotation) ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) {
+ if (((smart_snap_active || snap_rotation) ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) && snap_rotation_step != 0) {
if (snap_relative) {
return Math::stepify(p_target - snap_rotation_offset, snap_rotation_step) + snap_rotation_offset + (p_start - (int)(p_start / snap_rotation_step) * snap_rotation_step);
} else {
@@ -474,11 +470,11 @@ float CanvasItemEditor::snap_angle(float p_target, float p_start) const {
}
void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
-
Ref<InputEventKey> k = p_ev;
- if (!is_visible_in_tree())
+ if (!is_visible_in_tree()) {
return;
+ }
if (k->get_keycode() == KEY_CONTROL || k->get_keycode() == KEY_ALT || k->get_keycode() == KEY_SHIFT) {
viewport->update();
@@ -492,28 +488,29 @@ void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
} else if ((grid_snap_active || show_grid) && divide_grid_step_shortcut.is_valid() && divide_grid_step_shortcut->is_shortcut(p_ev)) {
// Divide the grid size
Point2 new_grid_step = grid_step * Math::pow(2.0, grid_step_multiplier - 1);
- if (new_grid_step.x >= 1.0 && new_grid_step.y >= 1.0)
+ if (new_grid_step.x >= 1.0 && new_grid_step.y >= 1.0) {
grid_step_multiplier--;
+ }
viewport->update();
}
}
}
Object *CanvasItemEditor::_get_editor_data(Object *p_what) {
-
CanvasItem *ci = Object::cast_to<CanvasItem>(p_what);
- if (!ci)
+ if (!ci) {
return nullptr;
+ }
return memnew(CanvasItemEditorSelectedItem);
}
void CanvasItemEditor::_keying_changed() {
-
- if (AnimationPlayerEditor::singleton->get_track_editor()->is_visible_in_tree())
+ if (AnimationPlayerEditor::singleton->get_track_editor()->is_visible_in_tree()) {
animation_hb->show();
- else
+ } else {
animation_hb->hide();
+ }
}
Rect2 CanvasItemEditor::_get_encompassing_rect_from_list(List<CanvasItem *> p_list) {
@@ -539,10 +536,12 @@ Rect2 CanvasItemEditor::_get_encompassing_rect_from_list(List<CanvasItem *> p_li
}
void CanvasItemEditor::_expand_encompassing_rect_using_children(Rect2 &r_rect, const Node *p_node, bool &r_first, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform, bool include_locked_nodes) {
- if (!p_node)
+ if (!p_node) {
return;
- if (Object::cast_to<Viewport>(p_node))
+ }
+ if (Object::cast_to<Viewport>(p_node)) {
return;
+ }
const CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
@@ -578,10 +577,12 @@ Rect2 CanvasItemEditor::_get_encompassing_rect(const Node *p_node) {
}
void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_node, Vector<_SelectResult> &r_items, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
- if (!p_node)
+ if (!p_node) {
return;
- if (Object::cast_to<Viewport>(p_node))
+ }
+ if (Object::cast_to<Viewport>(p_node)) {
return;
+ }
const real_t grab_distance = EDITOR_GET("editors/poly_editor/point_grab_radius");
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
@@ -615,7 +616,6 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no
}
void CanvasItemEditor::_get_canvas_items_at_pos(const Point2 &p_pos, Vector<_SelectResult> &r_items, bool p_allow_locked) {
-
Node *scene = editor->get_edited_scene();
_find_canvas_items_at_pos(p_pos, scene, r_items);
@@ -667,8 +667,9 @@ void CanvasItemEditor::_get_bones_at_pos(const Point2 &p_pos, Vector<_SelectResu
Node2D *from_node = Object::cast_to<Node2D>(ObjectDB::get_instance(E->key().from));
Vector<Vector2> bone_shape;
- if (!_get_bone_shape(&bone_shape, nullptr, E))
+ if (!_get_bone_shape(&bone_shape, nullptr, E)) {
continue;
+ }
// Check if the point is inside the Polygon2D
if (Geometry::is_point_in_polygon(screen_pos, bone_shape)) {
@@ -680,8 +681,9 @@ void CanvasItemEditor::_get_bones_at_pos(const Point2 &p_pos, Vector<_SelectResu
break;
}
}
- if (duplicate)
+ if (duplicate) {
continue;
+ }
// Else, add it
_SelectResult res;
@@ -700,21 +702,25 @@ bool CanvasItemEditor::_get_bone_shape(Vector<Vector2> *shape, Vector<Vector2> *
Node2D *from_node = Object::cast_to<Node2D>(ObjectDB::get_instance(bone->key().from));
Node2D *to_node = Object::cast_to<Node2D>(ObjectDB::get_instance(bone->key().to));
- if (!from_node)
+ if (!from_node) {
return false;
- if (!from_node->is_inside_tree())
+ }
+ if (!from_node->is_inside_tree()) {
return false; //may have been removed
+ }
- if (!to_node && bone->get().length == 0)
+ if (!to_node && bone->get().length == 0) {
return false;
+ }
Vector2 from = transform.xform(from_node->get_global_position());
Vector2 to;
- if (to_node)
+ if (to_node) {
to = transform.xform(to_node->get_global_position());
- else
+ } else {
to = transform.xform(from_node->get_global_transform().xform(Vector2(bone->get().length, 0)));
+ }
Vector2 rel = to - from;
Vector2 relt = rel.tangent().normalized() * bone_width;
@@ -742,10 +748,12 @@ bool CanvasItemEditor::_get_bone_shape(Vector<Vector2> *shape, Vector<Vector2> *
}
void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_node, List<CanvasItem *> *r_items, const Transform2D &p_parent_xform, const Transform2D &p_canvas_xform) {
- if (!p_node)
+ if (!p_node) {
return;
- if (Object::cast_to<Viewport>(p_node))
+ }
+ if (Object::cast_to<Viewport>(p_node)) {
return;
+ }
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
Node *scene = editor->get_edited_scene();
@@ -778,7 +786,6 @@ void CanvasItemEditor::_find_canvas_items_in_rect(const Rect2 &p_rect, Node *p_n
p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, 0))) &&
p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, rect.size.y))) &&
p_rect.has_point(xform.xform(rect.position + Vector2(0, rect.size.y)))) {
-
r_items->push_back(canvas_item);
}
} else {
@@ -861,10 +868,12 @@ Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2
}
void CanvasItemEditor::_save_canvas_item_ik_chain(const CanvasItem *p_canvas_item, List<float> *p_bones_length, List<Dictionary> *p_bones_state) {
- if (p_bones_length)
+ if (p_bones_length) {
*p_bones_length = List<float>();
- if (p_bones_state)
+ }
+ if (p_bones_state) {
*p_bones_state = List<Dictionary>();
+ }
const Node2D *bone = Object::cast_to<Node2D>(p_canvas_item);
if (bone && bone->has_meta("_edit_bone_")) {
@@ -890,10 +899,12 @@ void CanvasItemEditor::_save_canvas_item_ik_chain(const CanvasItem *p_canvas_ite
for (List<const Node2D *>::Element *bone_E = bone_ik_list.front(); bone_E; bone_E = bone_E->next()) {
bone_xform = bone_xform * bone->get_transform().affine_inverse();
const Node2D *parent_bone = bone_E->get();
- if (p_bones_length)
+ if (p_bones_length) {
p_bones_length->push_back(parent_bone->get_global_transform().get_origin().distance_to(bone->get_global_position()));
- if (p_bones_state)
+ }
+ if (p_bones_state) {
p_bones_state->push_back(parent_bone->_edit_get_state());
+ }
bone = parent_bone;
}
}
@@ -965,18 +976,18 @@ void CanvasItemEditor::_snap_changed() {
}
void CanvasItemEditor::_selection_result_pressed(int p_result) {
-
- if (selection_results.size() <= p_result)
+ if (selection_results.size() <= p_result) {
return;
+ }
CanvasItem *item = selection_results[p_result].item;
- if (item)
+ if (item) {
_select_click_on_item(item, Point2(), selection_menu_additive_selection);
+ }
}
void CanvasItemEditor::_selection_menu_hide() {
-
selection_results.clear();
selection_menu->clear();
selection_menu->set_size(Vector2(0, 0));
@@ -1027,7 +1038,6 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve
// Start dragging a guide
if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed()) {
-
// Press button
if (b->get_position().x < RULER_WIDTH && b->get_position().y < RULER_WIDTH) {
// Drag a new double guide
@@ -1274,8 +1284,9 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo
}
}
- if (is_pan_key)
+ if (is_pan_key) {
pan_pressed = k->is_pressed();
+ }
}
Ref<InputEventMouseMotion> m = p_event;
@@ -1284,7 +1295,7 @@ bool CanvasItemEditor::_gui_input_zoom_or_pan(const Ref<InputEvent> &p_event, bo
// Pan the viewport
Point2i relative;
if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) {
- relative = InputFilter::get_singleton()->warp_mouse_motion(m, viewport->get_global_rect());
+ relative = Input::get_singleton()->warp_mouse_motion(m, viewport->get_global_rect());
} else {
relative = m->get_relative();
}
@@ -1362,10 +1373,11 @@ bool CanvasItemEditor::_gui_input_pivot(const Ref<InputEvent> &p_event) {
drag_to = transform.affine_inverse().xform(m->get_position());
_restore_canvas_item_state(drag_selection);
Vector2 new_pos;
- if (drag_selection.size() == 1)
+ if (drag_selection.size() == 1) {
new_pos = snap_point(drag_to, SNAP_NODE_SIDES | SNAP_NODE_CENTER | SNAP_NODE_ANCHORS | SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL, 0, drag_selection[0]);
- else
+ } else {
new_pos = snap_point(drag_to, SNAP_OTHER_NODES | SNAP_GRID | SNAP_PIXEL);
+ }
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
canvas_item->_edit_set_pivot(canvas_item->get_global_transform_with_canvas().affine_inverse().xform(new_pos));
@@ -1397,7 +1409,6 @@ void CanvasItemEditor::_solve_IK(Node2D *leaf_node, Point2 target_position) {
if (se) {
int nb_bones = se->pre_drag_bones_undo_state.size();
if (nb_bones > 0) {
-
// Build the node list
Point2 leaf_pos = target_position;
@@ -1437,13 +1448,13 @@ void CanvasItemEditor::_solve_IK(Node2D *leaf_node, Point2 target_position) {
Vector2 direction = (joints_pos[node_id + 1] - joints_pos[node_id]).normalized();
int len = E->get();
if (E == se->pre_drag_bones_length.front()) {
- joints_pos[1] = joints_pos[1].linear_interpolate(joints_pos[0] + len * direction, solver_k);
+ joints_pos[1] = joints_pos[1].lerp(joints_pos[0] + len * direction, solver_k);
} else if (E == se->pre_drag_bones_length.back()) {
- joints_pos[node_id] = joints_pos[node_id].linear_interpolate(joints_pos[node_id + 1] - len * direction, solver_k);
+ joints_pos[node_id] = joints_pos[node_id].lerp(joints_pos[node_id + 1] - len * direction, solver_k);
} else {
Vector2 center = (joints_pos[node_id + 1] + joints_pos[node_id]) / 2.0;
- joints_pos[node_id] = joints_pos[node_id].linear_interpolate(center - (direction * len) / 2.0, solver_k);
- joints_pos[node_id + 1] = joints_pos[node_id + 1].linear_interpolate(center + (direction * len) / 2.0, solver_k);
+ joints_pos[node_id] = joints_pos[node_id].lerp(center - (direction * len) / 2.0, solver_k);
+ joints_pos[node_id + 1] = joints_pos[node_id + 1].lerp(center + (direction * len) / 2.0, solver_k);
}
node_id++;
}
@@ -1475,8 +1486,9 @@ bool CanvasItemEditor::_gui_input_rotate(const Ref<InputEvent> &p_event) {
// Remove not movable nodes
for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) {
- if (!_is_node_movable(E->get(), true))
+ if (!_is_node_movable(E->get(), true)) {
selection.erase(E);
+ }
}
drag_selection = selection;
@@ -1624,20 +1636,36 @@ bool CanvasItemEditor::_gui_input_anchors(const Ref<InputEvent> &p_event) {
switch (drag_type) {
case DRAG_ANCHOR_TOP_LEFT:
- if (!use_single_axis || !use_y) control->set_anchor(MARGIN_LEFT, new_anchor.x, false, false);
- if (!use_single_axis || use_y) control->set_anchor(MARGIN_TOP, new_anchor.y, false, false);
+ if (!use_single_axis || !use_y) {
+ control->set_anchor(MARGIN_LEFT, new_anchor.x, false, false);
+ }
+ if (!use_single_axis || use_y) {
+ control->set_anchor(MARGIN_TOP, new_anchor.y, false, false);
+ }
break;
case DRAG_ANCHOR_TOP_RIGHT:
- if (!use_single_axis || !use_y) control->set_anchor(MARGIN_RIGHT, new_anchor.x, false, false);
- if (!use_single_axis || use_y) control->set_anchor(MARGIN_TOP, new_anchor.y, false, false);
+ if (!use_single_axis || !use_y) {
+ control->set_anchor(MARGIN_RIGHT, new_anchor.x, false, false);
+ }
+ if (!use_single_axis || use_y) {
+ control->set_anchor(MARGIN_TOP, new_anchor.y, false, false);
+ }
break;
case DRAG_ANCHOR_BOTTOM_RIGHT:
- if (!use_single_axis || !use_y) control->set_anchor(MARGIN_RIGHT, new_anchor.x, false, false);
- if (!use_single_axis || use_y) control->set_anchor(MARGIN_BOTTOM, new_anchor.y, false, false);
+ if (!use_single_axis || !use_y) {
+ control->set_anchor(MARGIN_RIGHT, new_anchor.x, false, false);
+ }
+ if (!use_single_axis || use_y) {
+ control->set_anchor(MARGIN_BOTTOM, new_anchor.y, false, false);
+ }
break;
case DRAG_ANCHOR_BOTTOM_LEFT:
- if (!use_single_axis || !use_y) control->set_anchor(MARGIN_LEFT, new_anchor.x, false, false);
- if (!use_single_axis || use_y) control->set_anchor(MARGIN_BOTTOM, new_anchor.y, false, false);
+ if (!use_single_axis || !use_y) {
+ control->set_anchor(MARGIN_LEFT, new_anchor.x, false, false);
+ }
+ if (!use_single_axis || use_y) {
+ control->set_anchor(MARGIN_BOTTOM, new_anchor.y, false, false);
+ }
break;
case DRAG_ANCHOR_ALL:
if (!use_single_axis || !use_y) {
@@ -1715,13 +1743,15 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) {
Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized();
ofs *= (select_handle->get_size().width / 2);
ofs += endpoints[i];
- if (ofs.distance_to(b->get_position()) < radius)
+ if (ofs.distance_to(b->get_position()) < radius) {
resize_drag = dragger[i * 2];
+ }
ofs = (endpoints[i] + endpoints[next]) / 2;
ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2);
- if (ofs.distance_to(b->get_position()) < radius)
+ if (ofs.distance_to(b->get_position()) < radius) {
resize_drag = dragger[i * 2 + 1];
+ }
}
if (resize_drag != DRAG_NONE) {
@@ -1858,7 +1888,6 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) {
}
bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> b = p_event;
Ref<InputEventMouseMotion> m = p_event;
@@ -1870,7 +1899,6 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
CanvasItem *canvas_item = selection[0];
if (_is_node_movable(canvas_item)) {
-
Transform2D xform = transform * canvas_item->get_global_transform_with_canvas();
Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized();
Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
@@ -1912,7 +1940,7 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) {
Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform;
bool uniform = m->get_shift();
- bool is_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
Point2 drag_from_local = simple_xform.xform(drag_from);
Point2 drag_to_local = simple_xform.xform(drag_to);
@@ -2033,7 +2061,6 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
if (drag_type == DRAG_MOVE || drag_type == DRAG_MOVE_X || drag_type == DRAG_MOVE_Y) {
// Move the nodes
if (m.is_valid()) {
-
// Save the ik chain for reapplying before IK solve
Vector<List<Dictionary>> all_bones_ik_states;
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
@@ -2135,7 +2162,6 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
}
if (drag_selection.size() > 0) {
-
// Save the ik chain for reapplying before IK solve
Vector<List<Dictionary>> all_bones_ik_states;
for (List<CanvasItem *>::Element *E = drag_selection.front(); E; E = E->next()) {
@@ -2150,20 +2176,23 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
bool move_local_base_rotated = k->get_control() || k->get_metakey();
Vector2 dir;
- if (k->get_keycode() == KEY_UP)
+ if (k->get_keycode() == KEY_UP) {
dir += Vector2(0, -1);
- else if (k->get_keycode() == KEY_DOWN)
+ } else if (k->get_keycode() == KEY_DOWN) {
dir += Vector2(0, 1);
- else if (k->get_keycode() == KEY_LEFT)
+ } else if (k->get_keycode() == KEY_LEFT) {
dir += Vector2(-1, 0);
- else if (k->get_keycode() == KEY_RIGHT)
+ } else if (k->get_keycode() == KEY_RIGHT) {
dir += Vector2(1, 0);
- if (k->get_shift())
+ }
+ if (k->get_shift()) {
dir *= grid_step * Math::pow(2.0, grid_step_multiplier);
+ }
drag_to += dir;
- if (k->get_shift())
+ if (k->get_shift()) {
drag_to = drag_to.snapped(grid_step * Math::pow(2.0, grid_step_multiplier));
+ }
Point2 previous_pos;
if (drag_selection.size() == 1) {
@@ -2211,13 +2240,13 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) {
return true;
}
- if (k.is_valid() && !k->is_pressed() && drag_type == DRAG_KEY_MOVE && tool == TOOL_SELECT &&
+ if (k.is_valid() && !k->is_pressed() && drag_type == DRAG_KEY_MOVE && (tool == TOOL_SELECT || tool == TOOL_MOVE) &&
(k->get_keycode() == KEY_UP || k->get_keycode() == KEY_DOWN || k->get_keycode() == KEY_LEFT || k->get_keycode() == KEY_RIGHT)) {
// Confirm canvas items move by arrow keys
- if ((!InputFilter::get_singleton()->is_key_pressed(KEY_UP)) &&
- (!InputFilter::get_singleton()->is_key_pressed(KEY_DOWN)) &&
- (!InputFilter::get_singleton()->is_key_pressed(KEY_LEFT)) &&
- (!InputFilter::get_singleton()->is_key_pressed(KEY_RIGHT))) {
+ if ((!Input::get_singleton()->is_key_pressed(KEY_UP)) &&
+ (!Input::get_singleton()->is_key_pressed(KEY_DOWN)) &&
+ (!Input::get_singleton()->is_key_pressed(KEY_LEFT)) &&
+ (!Input::get_singleton()->is_key_pressed(KEY_RIGHT))) {
_commit_canvas_item_state(drag_selection, TTR("Move CanvasItem"), true);
drag_type = DRAG_NONE;
}
@@ -2302,8 +2331,9 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
Point2 click = transform.affine_inverse().xform(b->get_position());
Node *scene = editor->get_edited_scene();
- if (!scene)
+ if (!scene) {
return true;
+ }
// Find the item to select
CanvasItem *canvas_item = nullptr;
@@ -2371,10 +2401,12 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
Point2 bsfrom = drag_from;
Point2 bsto = box_selecting_to;
- if (bsfrom.x > bsto.x)
+ if (bsfrom.x > bsto.x) {
SWAP(bsfrom.x, bsto.x);
- if (bsfrom.y > bsto.y)
+ }
+ if (bsfrom.y > bsto.y) {
SWAP(bsfrom.y, bsto.y);
+ }
_find_canvas_items_in_rect(Rect2(bsfrom, bsto - bsfrom), scene, &selitems);
for (List<CanvasItem *>::Element *E = selitems.front(); E; E = E->next()) {
@@ -2411,16 +2443,17 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
}
bool CanvasItemEditor::_gui_input_ruler_tool(const Ref<InputEvent> &p_event) {
-
- if (tool != TOOL_RULER)
+ if (tool != TOOL_RULER) {
return false;
+ }
Ref<InputEventMouseButton> b = p_event;
Ref<InputEventMouseMotion> m = p_event;
Point2 previous_origin = ruler_tool_origin;
- if (!ruler_tool_active)
+ if (!ruler_tool_active) {
ruler_tool_origin = snap_point(viewport->get_local_mouse_position() / zoom + view_offset);
+ }
if (b.is_valid() && b->get_button_index() == BUTTON_LEFT) {
if (b->is_pressed()) {
@@ -2434,7 +2467,6 @@ bool CanvasItemEditor::_gui_input_ruler_tool(const Ref<InputEvent> &p_event) {
}
if (m.is_valid() && (ruler_tool_active || (grid_snap_active && previous_origin != ruler_tool_origin))) {
-
viewport->update();
return true;
}
@@ -2443,7 +2475,6 @@ bool CanvasItemEditor::_gui_input_ruler_tool(const Ref<InputEvent> &p_event) {
}
bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseMotion> m = p_event;
if (m.is_valid()) {
Point2 click = transform.affine_inverse().xform(m->get_position());
@@ -2458,8 +2489,9 @@ bool CanvasItemEditor::_gui_input_hover(const Ref<InputEvent> &p_event) {
for (int i = 0; i < hovering_results_items.size(); i++) {
CanvasItem *canvas_item = hovering_results_items[i].item;
- if (canvas_item->_edit_use_rect())
+ if (canvas_item->_edit_use_rect()) {
continue;
+ }
_HoverResult hover_result;
hover_result.position = canvas_item->get_global_transform_with_canvas().get_origin();
@@ -2528,8 +2560,9 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
accepted = (_gui_input_zoom_or_pan(p_event, accepted) || accepted);
- if (accepted)
+ if (accepted) {
accept_event();
+ }
// Handles the mouse hovering
_gui_input_hover(p_event);
@@ -2581,10 +2614,11 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
break;
}
- if (is_hovering_h_guide)
+ if (is_hovering_h_guide) {
c = CURSOR_VSIZE;
- else if (is_hovering_v_guide)
+ } else if (is_hovering_v_guide) {
c = CURSOR_HSIZE;
+ }
viewport->set_default_cursor_shape(c);
@@ -2638,7 +2672,6 @@ void CanvasItemEditor::_draw_focus() {
}
void CanvasItemEditor::_draw_guides() {
-
Color guide_color = EditorSettings::get_singleton()->get("editors/2d/guides_color");
Transform2D xform = viewport_scrollable->get_transform() * transform;
@@ -2646,8 +2679,9 @@ void CanvasItemEditor::_draw_guides() {
if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) {
Array vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_");
for (int i = 0; i < vguides.size(); i++) {
- if (drag_type == DRAG_V_GUIDE && i == dragged_guide_index)
+ if (drag_type == DRAG_V_GUIDE && i == dragged_guide_index) {
continue;
+ }
float x = xform.xform(Point2(vguides[i], 0)).x;
viewport->draw_line(Point2(x, 0), Point2(x, viewport->get_size().y), guide_color, Math::round(EDSCALE));
}
@@ -2656,8 +2690,9 @@ void CanvasItemEditor::_draw_guides() {
if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) {
Array hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_");
for (int i = 0; i < hguides.size(); i++) {
- if (drag_type == DRAG_H_GUIDE && i == dragged_guide_index)
+ if (drag_type == DRAG_H_GUIDE && i == dragged_guide_index) {
continue;
+ }
float y = xform.xform(Point2(0, hguides[i])).y;
viewport->draw_line(Point2(0, y), Point2(viewport->get_size().x, y), guide_color, Math::round(EDSCALE));
}
@@ -2698,7 +2733,7 @@ void CanvasItemEditor::_draw_smart_snapping() {
void CanvasItemEditor::_draw_rulers() {
Color bg_color = get_theme_color("dark_color_2", "Editor");
- Color graduation_color = get_theme_color("font_color", "Editor").linear_interpolate(bg_color, 0.5);
+ Color graduation_color = get_theme_color("font_color", "Editor").lerp(bg_color, 0.5);
Color font_color = get_theme_color("font_color", "Editor");
font_color.a = 0.8;
Ref<Font> font = get_theme_font("rulers", "EditorFonts");
@@ -2785,7 +2820,6 @@ void CanvasItemEditor::_draw_rulers() {
}
void CanvasItemEditor::_draw_grid() {
-
if (show_grid || grid_snap_active) {
// Draw the grid
Vector2 real_grid_offset;
@@ -2858,9 +2892,9 @@ void CanvasItemEditor::_draw_grid() {
}
void CanvasItemEditor::_draw_ruler_tool() {
-
- if (tool != TOOL_RULER)
+ if (tool != TOOL_RULER) {
return;
+ }
if (ruler_tool_active) {
Color ruler_primary_color = get_theme_color("accent_color", "Editor");
@@ -2959,7 +2993,6 @@ void CanvasItemEditor::_draw_ruler_tool() {
}
if (grid_snap_active) {
-
text_pos = (begin + end) / 2 + Vector2(-text_width / 2, text_height / 2);
text_pos.x = CLAMP(text_pos.x, text_width / 2, viewport->get_rect().size.x - text_width * 1.5);
text_pos.y = CLAMP(text_pos.y, text_height * 2.5, viewport->get_rect().size.y - text_height / 2);
@@ -2979,7 +3012,6 @@ void CanvasItemEditor::_draw_ruler_tool() {
}
}
} else {
-
if (grid_snap_active) {
Ref<Texture2D> position_icon = get_theme_icon("EditorPosition", "EditorIcons");
viewport->draw_texture(get_theme_icon("EditorPosition", "EditorIcons"), (ruler_tool_origin - view_offset) * zoom - position_icon->get_size() / 2);
@@ -2991,7 +3023,6 @@ void CanvasItemEditor::_draw_control_anchors(Control *control) {
Transform2D xform = transform * control->get_global_transform_with_canvas();
RID ci = viewport->get_canvas_item();
if (tool == TOOL_SELECT && !Object::cast_to<Container>(control->get_parent())) {
-
// Compute the anchors
float anchors_values[4];
anchors_values[0] = control->get_anchor(MARGIN_LEFT);
@@ -3072,8 +3103,8 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) {
Vector2 line_ends[4];
for (int i = 0; i < 4; i++) {
float anchor_val = (i >= 2) ? ANCHOR_END - anchors_values[i] : anchors_values[i];
- line_starts[i] = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val);
- line_ends[i] = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val);
+ line_starts[i] = corners_pos[i].lerp(corners_pos[(i + 1) % 4], anchor_val);
+ line_ends[i] = corners_pos[(i + 3) % 4].lerp(corners_pos[(i + 2) % 4], anchor_val);
anchor_snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0;
viewport->draw_line(line_starts[i], line_ends[i], anchor_snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1);
}
@@ -3256,7 +3287,6 @@ void CanvasItemEditor::_draw_selection() {
viewport->draw_line(endpoints[i], endpoints[(i + 1) % 4], c, Math::round(2 * EDSCALE));
}
} else {
-
Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized();
Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
viewport->draw_set_transform_matrix(simple_xform);
@@ -3267,7 +3297,6 @@ void CanvasItemEditor::_draw_selection() {
if (single && !item_locked && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks
// Draw the pivot
if (canvas_item->_edit_use_pivot()) {
-
// Draw the node's pivot
Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized();
Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
@@ -3310,8 +3339,8 @@ void CanvasItemEditor::_draw_selection() {
}
// Draw the move handles
- bool is_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
- bool is_alt = InputFilter::get_singleton()->is_key_pressed(KEY_ALT);
+ bool is_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT);
if (tool == TOOL_MOVE && show_transformation_gizmos) {
if (_is_node_movable(canvas_item)) {
Transform2D unscaled_transform = (xform * canvas_item->get_transform().affine_inverse() * canvas_item->_edit_get_transform()).orthonormalized();
@@ -3347,7 +3376,7 @@ void CanvasItemEditor::_draw_selection() {
Transform2D simple_xform = viewport->get_transform() * unscaled_transform;
Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE);
- bool uniform = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
+ bool uniform = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
Point2 offset = (simple_xform.affine_inverse().xform(drag_to) - simple_xform.affine_inverse().xform(drag_from)) * zoom;
if (drag_type == DRAG_SCALE_X) {
@@ -3445,15 +3474,12 @@ void CanvasItemEditor::_draw_straight_line(Point2 p_from, Point2 p_to, Color p_c
}
void CanvasItemEditor::_draw_axis() {
-
if (show_origin) {
-
_draw_straight_line(Point2(), Point2(1, 0), get_theme_color("axis_x_color", "Editor") * Color(1, 1, 1, 0.75));
_draw_straight_line(Point2(), Point2(0, 1), get_theme_color("axis_y_color", "Editor") * Color(1, 1, 1, 0.75));
}
if (show_viewport) {
-
RID ci = viewport->get_canvas_item();
Color area_axis_color = EditorSettings::get_singleton()->get("editors/2d/viewport_border_color");
@@ -3484,15 +3510,16 @@ void CanvasItemEditor::_draw_bones() {
Color bone_selected_color = EditorSettings::get_singleton()->get("editors/2d/bone_selected_color");
for (Map<BoneKey, BoneList>::Element *E = bone_list.front(); E; E = E->next()) {
-
Vector<Vector2> bone_shape;
Vector<Vector2> bone_shape_outline;
- if (!_get_bone_shape(&bone_shape, &bone_shape_outline, E))
+ if (!_get_bone_shape(&bone_shape, &bone_shape_outline, E)) {
continue;
+ }
Node2D *from_node = Object::cast_to<Node2D>(ObjectDB::get_instance(E->key().from));
- if (!from_node->is_visible_in_tree())
+ if (!from_node->is_visible_in_tree()) {
continue;
+ }
Vector<Color> colors;
if (from_node->has_meta("_edit_ik_")) {
@@ -3535,11 +3562,13 @@ void CanvasItemEditor::_draw_invisible_nodes_positions(Node *p_node, const Trans
ERR_FAIL_COND(!p_node);
Node *scene = editor->get_edited_scene();
- if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner()))
+ if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner())) {
return;
+ }
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
- if (canvas_item && !canvas_item->is_visible())
+ if (canvas_item && !canvas_item->is_visible()) {
return;
+ }
Transform2D parent_xform = p_parent_xform;
Transform2D canvas_xform = p_canvas_xform;
@@ -3573,7 +3602,6 @@ void CanvasItemEditor::_draw_hover() {
List<Rect2> previous_rects;
for (int i = 0; i < hovering_results.size(); i++) {
-
Ref<Texture2D> node_icon = hovering_results[i].icon;
String node_name = hovering_results[i].name;
@@ -3603,11 +3631,13 @@ void CanvasItemEditor::_draw_locks_and_groups(Node *p_node, const Transform2D &p
ERR_FAIL_COND(!p_node);
Node *scene = editor->get_edited_scene();
- if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner()))
+ if (p_node != scene && p_node->get_owner() != scene && !scene->is_editable_instance(p_node->get_owner())) {
return;
+ }
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
- if (canvas_item && !canvas_item->is_visible())
+ if (canvas_item && !canvas_item->is_visible()) {
return;
+ }
Transform2D parent_xform = p_parent_xform;
Transform2D canvas_xform = p_canvas_xform;
@@ -3709,7 +3739,6 @@ bool CanvasItemEditor::_build_bones_list(Node *p_node) {
}
void CanvasItemEditor::_draw_viewport() {
-
// Update the transform
transform = Transform2D();
transform.scale_basis(Size2(zoom, zoom));
@@ -3769,10 +3798,12 @@ void CanvasItemEditor::_draw_viewport() {
}
_draw_bones();
- if (show_rulers)
+ if (show_rulers) {
_draw_rulers();
- if (show_guides)
+ }
+ if (show_guides) {
_draw_guides();
+ }
_draw_smart_snapping();
_draw_focus();
_draw_hover();
@@ -3788,7 +3819,6 @@ void CanvasItemEditor::set_current_tool(Tool p_tool) {
}
void CanvasItemEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_PHYSICS_PROCESS) {
EditorNode::get_singleton()->get_scene_root()->set_snap_controls_to_pixels(GLOBAL_GET("gui/common/snap_controls_to_pixels"));
@@ -3874,10 +3904,8 @@ void CanvasItemEditor::_notification(int p_what) {
// Update the viewport if bones changes
for (Map<BoneKey, BoneList>::Element *E = bone_list.front(); E; E = E->next()) {
-
Object *b = ObjectDB::get_instance(E->key().from);
if (!b) {
-
viewport->update();
break;
}
@@ -3890,14 +3918,12 @@ void CanvasItemEditor::_notification(int p_what) {
Transform2D global_xform = b2->get_global_transform();
if (global_xform != E->get().xform) {
-
E->get().xform = global_xform;
viewport->update();
}
Bone2D *bone = Object::cast_to<Bone2D>(b);
if (bone && bone->get_default_length() != E->get().length) {
-
E->get().length = bone->get_default_length();
viewport->update();
}
@@ -3905,7 +3931,6 @@ void CanvasItemEditor::_notification(int p_what) {
}
if (p_what == NOTIFICATION_ENTER_TREE) {
-
select_sb->set_texture(get_theme_icon("EditorRect2D", "EditorIcons"));
for (int i = 0; i < 4; i++) {
select_sb->set_margin_size(Margin(i), 4);
@@ -3918,7 +3943,6 @@ void CanvasItemEditor::_notification(int p_what) {
get_tree()->connect("node_removed", callable_mp(this, &CanvasItemEditor::_tree_changed), varray());
} else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
-
select_sb->set_texture(get_theme_icon("EditorRect2D", "EditorIcons"));
}
@@ -4026,10 +4050,12 @@ void CanvasItemEditor::_selection_changed() {
List<Node *> selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
Control *control = Object::cast_to<Control>(E->get());
- if (!control)
+ if (!control) {
continue;
- if (Object::cast_to<Container>(control->get_parent()))
+ }
+ if (Object::cast_to<Container>(control->get_parent())) {
continue;
+ }
nbValidControls++;
if (control->has_meta("_edit_use_anchors_") && control->get_meta("_edit_use_anchors_")) {
@@ -4046,7 +4072,6 @@ void CanvasItemEditor::_selection_changed() {
}
void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
-
Array selection = editor_selection->get_selected_nodes();
if (selection.size() != 1 || (Node *)selection[0] != p_canvas_item) {
drag_type = DRAG_NONE;
@@ -4058,16 +4083,15 @@ void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
}
void CanvasItemEditor::_queue_update_bone_list() {
-
- if (bone_list_dirty)
+ if (bone_list_dirty) {
return;
+ }
call_deferred("_update_bone_list");
bone_list_dirty = true;
}
void CanvasItemEditor::_update_bone_list() {
-
bone_last_frame++;
if (editor->get_edited_scene()) {
@@ -4099,7 +4123,6 @@ void CanvasItemEditor::_tree_changed(Node *) {
}
void CanvasItemEditor::_update_scrollbars() {
-
updating_scroll = true;
// Move the zoom buttons.
@@ -4217,9 +4240,9 @@ void CanvasItemEditor::_popup_warning_temporarily(Control *p_control, const floa
}
void CanvasItemEditor::_update_scroll(float) {
-
- if (updating_scroll)
+ if (updating_scroll) {
return;
+ }
view_offset.x = h_scroll->get_value();
view_offset.y = v_scroll->get_value();
@@ -4232,7 +4255,6 @@ void CanvasItemEditor::_set_anchors_and_margins_preset(Control::LayoutPreset p_p
undo_redo->create_action(TTR("Change Anchors and Margins"));
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Control *control = Object::cast_to<Control>(E->get());
if (control) {
undo_redo->add_do_method(control, "set_anchors_preset", p_preset);
@@ -4274,7 +4296,6 @@ void CanvasItemEditor::_set_anchors_and_margins_to_keep_ratio() {
undo_redo->create_action(TTR("Change Anchors and Margins"));
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Control *control = Object::cast_to<Control>(E->get());
if (control) {
Point2 top_left_anchor = _position_to_anchor(control, Point2());
@@ -4302,7 +4323,6 @@ void CanvasItemEditor::_set_anchors_preset(Control::LayoutPreset p_preset) {
undo_redo->create_action(TTR("Change Anchors"));
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Control *control = Object::cast_to<Control>(E->get());
if (control) {
undo_redo->add_do_method(control, "set_anchors_preset", p_preset);
@@ -4314,8 +4334,9 @@ void CanvasItemEditor::_set_anchors_preset(Control::LayoutPreset p_preset) {
}
void CanvasItemEditor::_zoom_on_position(float p_zoom, Point2 p_position) {
- if (p_zoom < MIN_ZOOM || p_zoom > MAX_ZOOM)
+ if (p_zoom < MIN_ZOOM || p_zoom > MAX_ZOOM) {
return;
+ }
float prev_zoom = zoom;
zoom = p_zoom;
@@ -4375,6 +4396,7 @@ void CanvasItemEditor::_button_toggle_grid_snap(bool p_status) {
grid_snap_active = p_status;
viewport->update();
}
+
void CanvasItemEditor::_button_override_camera(bool p_pressed) {
EditorDebuggerNode *debugger = EditorDebuggerNode::get_singleton();
@@ -4386,7 +4408,6 @@ void CanvasItemEditor::_button_override_camera(bool p_pressed) {
}
void CanvasItemEditor::_button_tool_select(int p_index) {
-
ToolButton *tb[TOOL_MAX] = { select_button, list_select_button, move_button, scale_button, rotate_button, pivot_button, pan_button, ruler_button };
for (int i = 0; i < TOOL_MAX; i++) {
tb[i]->set_pressed(i == p_index);
@@ -4397,27 +4418,30 @@ void CanvasItemEditor::_button_tool_select(int p_index) {
}
void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation, bool p_scale, bool p_on_existing) {
-
Map<Node *, Object *> &selection = editor_selection->get_selection();
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
-
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
- if (!canvas_item || !canvas_item->is_visible_in_tree())
+ if (!canvas_item || !canvas_item->is_visible_in_tree()) {
continue;
+ }
- if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
+ }
if (Object::cast_to<Node2D>(canvas_item)) {
Node2D *n2d = Object::cast_to<Node2D>(canvas_item);
- if (key_pos && p_location)
+ if (key_pos && p_location) {
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(n2d, "position", n2d->get_position(), p_on_existing);
- if (key_rot && p_rotation)
+ }
+ if (key_rot && p_rotation) {
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(n2d, "rotation_degrees", Math::rad2deg(n2d->get_rotation()), p_on_existing);
- if (key_scale && p_scale)
+ }
+ if (key_scale && p_scale) {
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(n2d, "scale", n2d->get_scale(), p_on_existing);
+ }
if (n2d->has_meta("_edit_bone_") && n2d->get_parent_item()) {
//look for an IK chain
@@ -4427,42 +4451,45 @@ void CanvasItemEditor::_insert_animation_keys(bool p_location, bool p_rotation,
bool has_chain = false;
while (n) {
-
ik_chain.push_back(n);
if (n->has_meta("_edit_ik_")) {
has_chain = true;
break;
}
- if (!n->get_parent_item())
+ if (!n->get_parent_item()) {
break;
+ }
n = Object::cast_to<Node2D>(n->get_parent_item());
}
if (has_chain && ik_chain.size()) {
-
for (List<Node2D *>::Element *F = ik_chain.front(); F; F = F->next()) {
-
- if (key_pos)
+ if (key_pos) {
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F->get(), "position", F->get()->get_position(), p_on_existing);
- if (key_rot)
+ }
+ if (key_rot) {
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F->get(), "rotation_degrees", Math::rad2deg(F->get()->get_rotation()), p_on_existing);
- if (key_scale)
+ }
+ if (key_scale) {
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(F->get(), "scale", F->get()->get_scale(), p_on_existing);
+ }
}
}
}
} else if (Object::cast_to<Control>(canvas_item)) {
-
Control *ctrl = Object::cast_to<Control>(canvas_item);
- if (key_pos)
+ if (key_pos) {
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(ctrl, "rect_position", ctrl->get_position(), p_on_existing);
- if (key_rot)
+ }
+ if (key_rot) {
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(ctrl, "rect_rotation", ctrl->get_rotation_degrees(), p_on_existing);
- if (key_scale)
+ }
+ if (key_scale) {
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(ctrl, "rect_size", ctrl->get_size(), p_on_existing);
+ }
}
}
}
@@ -4471,8 +4498,9 @@ void CanvasItemEditor::_button_toggle_anchor_mode(bool p_status) {
List<CanvasItem *> selection = _get_edited_canvas_items(false, false);
for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) {
Control *control = Object::cast_to<Control>(E->get());
- if (!control || Object::cast_to<Container>(control->get_parent()))
+ if (!control || Object::cast_to<Container>(control->get_parent())) {
continue;
+ }
control->set_meta("_edit_use_anchors_", p_status);
}
@@ -4611,10 +4639,12 @@ void CanvasItemEditor::_popup_callback(int p_op) {
List<Node *> selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
- if (!canvas_item || !canvas_item->is_inside_tree())
+ if (!canvas_item || !canvas_item->is_inside_tree()) {
continue;
- if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ }
+ if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
+ }
undo_redo->add_do_method(canvas_item, "set_meta", "_edit_lock_", true);
undo_redo->add_undo_method(canvas_item, "remove_meta", "_edit_lock_");
@@ -4631,10 +4661,12 @@ void CanvasItemEditor::_popup_callback(int p_op) {
List<Node *> selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
- if (!canvas_item || !canvas_item->is_inside_tree())
+ if (!canvas_item || !canvas_item->is_inside_tree()) {
continue;
- if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ }
+ if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
+ }
undo_redo->add_do_method(canvas_item, "remove_meta", "_edit_lock_");
undo_redo->add_undo_method(canvas_item, "set_meta", "_edit_lock_", true);
@@ -4651,10 +4683,12 @@ void CanvasItemEditor::_popup_callback(int p_op) {
List<Node *> selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
- if (!canvas_item || !canvas_item->is_inside_tree())
+ if (!canvas_item || !canvas_item->is_inside_tree()) {
continue;
- if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ }
+ if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
+ }
undo_redo->add_do_method(canvas_item, "set_meta", "_edit_group_", true);
undo_redo->add_undo_method(canvas_item, "remove_meta", "_edit_group_");
@@ -4671,10 +4705,12 @@ void CanvasItemEditor::_popup_callback(int p_op) {
List<Node *> selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
- if (!canvas_item || !canvas_item->is_inside_tree())
+ if (!canvas_item || !canvas_item->is_inside_tree()) {
continue;
- if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ }
+ if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
+ }
undo_redo->add_do_method(canvas_item, "remove_meta", "_edit_group_");
undo_redo->add_undo_method(canvas_item, "set_meta", "_edit_group_", true);
@@ -4788,41 +4824,36 @@ void CanvasItemEditor::_popup_callback(int p_op) {
case ANIM_INSERT_KEY:
case ANIM_INSERT_KEY_EXISTING: {
-
bool existing = p_op == ANIM_INSERT_KEY_EXISTING;
_insert_animation_keys(true, true, true, existing);
} break;
case ANIM_INSERT_POS: {
-
key_pos = key_loc_button->is_pressed();
} break;
case ANIM_INSERT_ROT: {
-
key_rot = key_rot_button->is_pressed();
} break;
case ANIM_INSERT_SCALE: {
-
key_scale = key_scale_button->is_pressed();
} break;
case ANIM_COPY_POSE: {
-
pose_clipboard.clear();
Map<Node *, Object *> &selection = editor_selection->get_selection();
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
-
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
- if (!canvas_item || !canvas_item->is_visible_in_tree())
+ if (!canvas_item || !canvas_item->is_visible_in_tree()) {
continue;
+ }
- if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
+ }
if (Object::cast_to<Node2D>(canvas_item)) {
-
Node2D *n2d = Object::cast_to<Node2D>(canvas_item);
PoseClipboard pc;
pc.pos = n2d->get_position();
@@ -4835,16 +4866,16 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case ANIM_PASTE_POSE: {
-
- if (!pose_clipboard.size())
+ if (!pose_clipboard.size()) {
break;
+ }
undo_redo->create_action(TTR("Paste Pose"));
for (List<PoseClipboard>::Element *E = pose_clipboard.front(); E; E = E->next()) {
-
Node2D *n2d = Object::cast_to<Node2D>(ObjectDB::get_instance(E->get().id));
- if (!n2d)
+ if (!n2d) {
continue;
+ }
undo_redo->add_do_method(n2d, "set_position", E->get().pos);
undo_redo->add_do_method(n2d, "set_rotation", E->get().rot);
undo_redo->add_do_method(n2d, "set_scale", E->get().scale);
@@ -4856,33 +4887,36 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case ANIM_CLEAR_POSE: {
-
Map<Node *, Object *> &selection = editor_selection->get_selection();
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
-
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
- if (!canvas_item || !canvas_item->is_visible_in_tree())
+ if (!canvas_item || !canvas_item->is_visible_in_tree()) {
continue;
+ }
- if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
+ }
if (Object::cast_to<Node2D>(canvas_item)) {
Node2D *n2d = Object::cast_to<Node2D>(canvas_item);
- if (key_pos)
+ if (key_pos) {
n2d->set_position(Vector2());
- if (key_rot)
+ }
+ if (key_rot) {
n2d->set_rotation(0);
- if (key_scale)
+ }
+ if (key_scale) {
n2d->set_scale(Vector2(1, 1));
+ }
} else if (Object::cast_to<Control>(canvas_item)) {
-
Control *ctrl = Object::cast_to<Control>(canvas_item);
- if (key_pos)
+ if (key_pos) {
ctrl->set_position(Point2());
+ }
/*
if (key_scale)
AnimationPlayerEditor::singleton->get_track_editor()->insert_node_value_key(ctrl,"rect/size",ctrl->get_size());
@@ -4892,7 +4926,6 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case CLEAR_GUIDES: {
-
Node *const root = EditorNode::get_singleton()->get_edited_scene();
if (root && (root->has_meta("_edit_horizontal_guides_") || root->has_meta("_edit_vertical_guides_"))) {
@@ -4916,12 +4949,10 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case VIEW_CENTER_TO_SELECTION:
case VIEW_FRAME_TO_SELECTION: {
-
_focus_selection(p_op);
} break;
case PREVIEW_CANVAS_SCALE: {
-
bool preview = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(PREVIEW_CANVAS_SCALE));
preview = !preview;
RS::get_singleton()->canvas_set_disable_scale(!preview);
@@ -4929,21 +4960,23 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case SKELETON_MAKE_BONES: {
-
Map<Node *, Object *> &selection = editor_selection->get_selection();
undo_redo->create_action(TTR("Create Custom Bone(s) from Node(s)"));
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
-
Node2D *n2d = Object::cast_to<Node2D>(E->key());
- if (!n2d)
+ if (!n2d) {
continue;
- if (!n2d->is_visible_in_tree())
+ }
+ if (!n2d->is_visible_in_tree()) {
continue;
- if (!n2d->get_parent_item())
+ }
+ if (!n2d->get_parent_item()) {
continue;
- if (n2d->has_meta("_edit_bone_") && n2d->get_meta("_edit_bone_"))
+ }
+ if (n2d->has_meta("_edit_bone_") && n2d->get_meta("_edit_bone_")) {
continue;
+ }
undo_redo->add_do_method(n2d, "set_meta", "_edit_bone_", true);
undo_redo->add_undo_method(n2d, "remove_meta", "_edit_bone_");
@@ -4956,19 +4989,20 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case SKELETON_CLEAR_BONES: {
-
Map<Node *, Object *> &selection = editor_selection->get_selection();
undo_redo->create_action(TTR("Clear Bones"));
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
-
Node2D *n2d = Object::cast_to<Node2D>(E->key());
- if (!n2d)
+ if (!n2d) {
continue;
- if (!n2d->is_visible_in_tree())
+ }
+ if (!n2d->is_visible_in_tree()) {
continue;
- if (!n2d->has_meta("_edit_bone_"))
+ }
+ if (!n2d->has_meta("_edit_bone_")) {
continue;
+ }
undo_redo->add_do_method(n2d, "remove_meta", "_edit_bone_");
undo_redo->add_undo_method(n2d, "set_meta", "_edit_bone_", n2d->get_meta("_edit_bone_"));
@@ -4981,19 +5015,20 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case SKELETON_SET_IK_CHAIN: {
-
List<Node *> selection = editor_selection->get_selected_node_list();
undo_redo->create_action(TTR("Make IK Chain"));
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->get());
- if (!canvas_item || !canvas_item->is_visible_in_tree())
+ if (!canvas_item || !canvas_item->is_visible_in_tree()) {
continue;
- if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ }
+ if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
- if (canvas_item->has_meta("_edit_ik_") && canvas_item->get_meta("_edit_ik_"))
+ }
+ if (canvas_item->has_meta("_edit_ik_") && canvas_item->get_meta("_edit_ik_")) {
continue;
+ }
undo_redo->add_do_method(canvas_item, "set_meta", "_edit_ik_", true);
undo_redo->add_undo_method(canvas_item, "remove_meta", "_edit_ik_");
@@ -5004,19 +5039,20 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
case SKELETON_CLEAR_IK_CHAIN: {
-
Map<Node *, Object *> &selection = editor_selection->get_selection();
undo_redo->create_action(TTR("Clear IK Chain"));
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
-
CanvasItem *n2d = Object::cast_to<CanvasItem>(E->key());
- if (!n2d)
+ if (!n2d) {
continue;
- if (!n2d->is_visible_in_tree())
+ }
+ if (!n2d->is_visible_in_tree()) {
continue;
- if (!n2d->has_meta("_edit_ik_"))
+ }
+ if (!n2d->has_meta("_edit_ik_")) {
continue;
+ }
undo_redo->add_do_method(n2d, "remove_meta", "_edit_ik_");
undo_redo->add_undo_method(n2d, "set_meta", "_edit_ik_", n2d->get_meta("_edit_ik_"));
@@ -5037,9 +5073,12 @@ void CanvasItemEditor::_focus_selection(int p_op) {
Map<Node *, Object *> &selection = editor_selection->get_selection();
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(E->key());
- if (!canvas_item) continue;
- if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ if (!canvas_item) {
continue;
+ }
+ if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
+ continue;
+ }
// counting invisible items, for now
//if (!canvas_item->is_visible_in_tree()) continue;
@@ -5065,10 +5104,11 @@ void CanvasItemEditor::_focus_selection(int p_op) {
rect = rect.merge(canvas_item_rect);
}
};
- if (count == 0) return;
+ if (count == 0) {
+ return;
+ }
if (p_op == VIEW_CENTER_TO_SELECTION) {
-
center = rect.position + rect.size / 2;
Vector2 offset = viewport->get_size() / 2 - editor->get_scene_root()->get_global_canvas_transform().xform(center);
view_offset.x -= Math::round(offset.x / zoom);
@@ -5090,7 +5130,6 @@ void CanvasItemEditor::_focus_selection(int p_op) {
}
void CanvasItemEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_update_override_camera_button", "game_running"), &CanvasItemEditor::_update_override_camera_button);
ClassDB::bind_method("_get_editor_data", &CanvasItemEditor::_get_editor_data);
ClassDB::bind_method("_unhandled_key_input", &CanvasItemEditor::_unhandled_key_input);
@@ -5104,7 +5143,6 @@ void CanvasItemEditor::_bind_methods() {
}
Dictionary CanvasItemEditor::get_state() const {
-
Dictionary state;
// Take the editor scale into account.
state["zoom"] = zoom / MAX(1, EDSCALE);
@@ -5141,7 +5179,6 @@ Dictionary CanvasItemEditor::get_state() const {
}
void CanvasItemEditor::set_state(const Dictionary &p_state) {
-
bool update_scrollbars = false;
Dictionary state = p_state;
if (state.has("zoom")) {
@@ -5326,7 +5363,6 @@ void CanvasItemEditor::add_control_to_info_overlay(Control *p_control) {
}
void CanvasItemEditor::remove_control_from_info_overlay(Control *p_control) {
-
info_overlay->remove_child(p_control);
info_overlay->set_margin(MARGIN_LEFT, (show_rulers ? RULER_WIDTH : 0) + 10);
}
@@ -5338,17 +5374,14 @@ void CanvasItemEditor::add_control_to_menu_panel(Control *p_control) {
}
void CanvasItemEditor::remove_control_from_menu_panel(Control *p_control) {
-
hb->remove_child(p_control);
}
HSplitContainer *CanvasItemEditor::get_palette_split() {
-
return palette_split;
}
VSplitContainer *CanvasItemEditor::get_bottom_split() {
-
return bottom_split;
}
@@ -5357,7 +5390,6 @@ void CanvasItemEditor::focus_selection() {
}
CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
-
key_pos = true;
key_rot = true;
key_scale = false;
@@ -5816,25 +5848,21 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
CanvasItemEditor *CanvasItemEditor::singleton = nullptr;
void CanvasItemEditorPlugin::edit(Object *p_object) {
-
canvas_item_editor->set_undo_redo(&get_undo_redo());
canvas_item_editor->edit(Object::cast_to<CanvasItem>(p_object));
}
bool CanvasItemEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("CanvasItem");
}
void CanvasItemEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
canvas_item_editor->show();
canvas_item_editor->set_physics_process(true);
RenderingServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport_rid(), false);
} else {
-
canvas_item_editor->hide();
canvas_item_editor->set_physics_process(false);
RenderingServer::get_singleton()->viewport_set_hide_canvas(editor->get_scene_root()->get_viewport_rid(), true);
@@ -5842,16 +5870,14 @@ void CanvasItemEditorPlugin::make_visible(bool p_visible) {
}
Dictionary CanvasItemEditorPlugin::get_state() const {
-
return canvas_item_editor->get_state();
}
-void CanvasItemEditorPlugin::set_state(const Dictionary &p_state) {
+void CanvasItemEditorPlugin::set_state(const Dictionary &p_state) {
canvas_item_editor->set_state(p_state);
}
CanvasItemEditorPlugin::CanvasItemEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
canvas_item_editor = memnew(CanvasItemEditor(editor));
canvas_item_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -5877,8 +5903,9 @@ void CanvasItemEditorViewport::_on_select_type(Object *selected) {
}
void CanvasItemEditorViewport::_on_change_type_confirmed() {
- if (!button_group->get_pressed_button())
+ if (!button_group->get_pressed_button()) {
return;
+ }
CheckBox *check = Object::cast_to<CheckBox>(button_group->get_pressed_button());
default_type = check->get_text();
@@ -5887,7 +5914,6 @@ void CanvasItemEditorViewport::_on_change_type_confirmed() {
}
void CanvasItemEditorViewport::_on_change_type_closed() {
-
_remove_preview();
}
@@ -5919,8 +5945,9 @@ void CanvasItemEditorViewport::_create_preview(const Vector<String> &files) cons
}
}
- if (add_preview)
+ if (add_preview) {
editor->get_scene_root()->add_child(preview_node);
+ }
}
void CanvasItemEditorViewport::_remove_preview() {
@@ -6094,20 +6121,21 @@ void CanvasItemEditorViewport::_perform_drop_data() {
Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(*res));
if (texture != nullptr && texture.is_valid()) {
Node *child;
- if (default_type == "Light2D")
+ if (default_type == "Light2D") {
child = memnew(Light2D);
- else if (default_type == "GPUParticles2D")
+ } else if (default_type == "GPUParticles2D") {
child = memnew(GPUParticles2D);
- else if (default_type == "Polygon2D")
+ } else if (default_type == "Polygon2D") {
child = memnew(Polygon2D);
- else if (default_type == "TouchScreenButton")
+ } else if (default_type == "TouchScreenButton") {
child = memnew(TouchScreenButton);
- else if (default_type == "TextureRect")
+ } else if (default_type == "TextureRect") {
child = memnew(TextureRect);
- else if (default_type == "NinePatchRect")
+ } else if (default_type == "NinePatchRect") {
child = memnew(NinePatchRect);
- else
+ } else {
child = memnew(Sprite2D); // default
+ }
_create_nodes(target_node, child, path, drop_pos);
}
@@ -6151,7 +6179,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2 &p_point, const Varian
type == "ViewportTexture" ||
type == "CurveTexture" ||
type == "GradientTexture" ||
- type == "StreamTexture" ||
+ type == "StreamTexture2D" ||
type == "AtlasTexture" ||
type == "LargeTexture") {
Ref<Texture2D> texture = Ref<Texture2D>(Object::cast_to<Texture2D>(*res));
@@ -6193,7 +6221,6 @@ void CanvasItemEditorViewport::_show_resource_type_selector() {
}
bool CanvasItemEditorViewport::_only_packed_scenes_selected() const {
-
for (int i = 0; i < selected_files.size(); ++i) {
if (ResourceLoader::load(selected_files[i])->get_class() != "PackedScene") {
return false;
@@ -6204,16 +6231,17 @@ bool CanvasItemEditorViewport::_only_packed_scenes_selected() const {
}
void CanvasItemEditorViewport::drop_data(const Point2 &p_point, const Variant &p_data) {
- bool is_shift = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
- bool is_alt = InputFilter::get_singleton()->is_key_pressed(KEY_ALT);
+ bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
+ bool is_alt = Input::get_singleton()->is_key_pressed(KEY_ALT);
selected_files.clear();
Dictionary d = p_data;
if (d.has("type") && String(d["type"]) == "files") {
selected_files = d["files"];
}
- if (selected_files.size() == 0)
+ if (selected_files.size() == 0) {
return;
+ }
List<Node *> list = editor->get_editor_selection()->get_selected_node_list();
if (list.size() == 0) {
@@ -6252,7 +6280,8 @@ void CanvasItemEditorViewport::_notification(int p_what) {
disconnect("mouse_exited", callable_mp(this, &CanvasItemEditorViewport::_on_mouse_exit));
} break;
- default: break;
+ default:
+ break;
}
}
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 9f1a92f563..a686c98f65 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -43,15 +43,14 @@
class CanvasItemEditorViewport;
class CanvasItemEditorSelectedItem : public Object {
-
GDCLASS(CanvasItemEditorSelectedItem, Object);
public:
Transform2D prev_xform;
- float prev_rot;
+ float prev_rot = 0;
Rect2 prev_rect;
Vector2 prev_pivot;
- float prev_anchors[4];
+ float prev_anchors[4] = { 0.0f };
Transform2D pre_drag_xform;
Rect2 pre_drag_rect;
@@ -61,14 +60,10 @@ public:
Dictionary undo_state;
- CanvasItemEditorSelectedItem() :
- prev_anchors() {
- prev_rot = 0;
- }
+ CanvasItemEditorSelectedItem() {}
};
class CanvasItemEditor : public VBoxContainer {
-
GDCLASS(CanvasItemEditor, VBoxContainer);
public:
@@ -293,7 +288,6 @@ private:
MenuOption last_option;
struct _SelectResult {
-
CanvasItem *item;
float z_index;
bool has_z;
@@ -304,7 +298,6 @@ private:
Vector<_SelectResult> selection_results;
struct _HoverResult {
-
Point2 position;
Ref<Texture2D> icon;
String name;
@@ -312,14 +305,11 @@ private:
Vector<_HoverResult> hovering_results;
struct BoneList {
-
Transform2D xform;
- float length;
- uint64_t last_pass;
+ float length = 0.f;
+ uint64_t last_pass = 0;
- BoneList() :
- length(0.f),
- last_pass(0) {}
+ BoneList() {}
};
uint64_t bone_last_frame;
@@ -328,10 +318,11 @@ private:
ObjectID from;
ObjectID to;
_FORCE_INLINE_ bool operator<(const BoneKey &p_key) const {
- if (from == p_key.from)
+ if (from == p_key.from) {
return to < p_key.to;
- else
+ } else {
return from < p_key.from;
+ }
}
};
@@ -651,7 +642,6 @@ public:
};
class CanvasItemEditorPlugin : public EditorPlugin {
-
GDCLASS(CanvasItemEditorPlugin, EditorPlugin);
CanvasItemEditor *canvas_item_editor;
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
index 87e9987aa1..08d6fc966d 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
@@ -31,12 +31,10 @@
#include "collision_polygon_2d_editor_plugin.h"
Node2D *CollisionPolygon2DEditor::_get_node() const {
-
return node;
}
void CollisionPolygon2DEditor::_set_node(Node *p_polygon) {
-
node = Object::cast_to<CollisionPolygon2D>(p_polygon);
}
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h
index a4fa7c7b3b..b0be92db44 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.h
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.h
@@ -35,7 +35,6 @@
#include "scene/2d/collision_polygon_2d.h"
class CollisionPolygon2DEditor : public AbstractPolygon2DEditor {
-
GDCLASS(CollisionPolygon2DEditor, AbstractPolygon2DEditor);
CollisionPolygon2D *node;
@@ -49,7 +48,6 @@ public:
};
class CollisionPolygon2DEditorPlugin : public AbstractPolygon2DEditorPlugin {
-
GDCLASS(CollisionPolygon2DEditorPlugin, AbstractPolygon2DEditorPlugin);
public:
diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/collision_polygon_3d_editor_plugin.cpp
index 26adc5156b..c61d410d38 100644
--- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_3d_editor_plugin.cpp
@@ -31,7 +31,7 @@
#include "collision_polygon_3d_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/file_access.h"
#include "core/os/keyboard.h"
#include "editor/editor_settings.h"
@@ -39,11 +39,8 @@
#include "scene/3d/camera_3d.h"
void CollisionPolygon3DEditor::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_READY: {
-
button_create->set_icon(get_theme_icon("Edit", "EditorIcons"));
button_edit->set_icon(get_theme_icon("MovePoint", "EditorIcons"));
button_edit->set_pressed(true);
@@ -63,29 +60,26 @@ void CollisionPolygon3DEditor::_notification(int p_what) {
} break;
}
}
-void CollisionPolygon3DEditor::_node_removed(Node *p_node) {
+void CollisionPolygon3DEditor::_node_removed(Node *p_node) {
if (p_node == node) {
node = nullptr;
- if (imgeom->get_parent() == p_node)
+ if (imgeom->get_parent() == p_node) {
p_node->remove_child(imgeom);
+ }
hide();
set_process(false);
}
}
void CollisionPolygon3DEditor::_menu_option(int p_option) {
-
switch (p_option) {
-
case MODE_CREATE: {
-
mode = MODE_CREATE;
button_create->set_pressed(true);
button_edit->set_pressed(false);
} break;
case MODE_EDIT: {
-
mode = MODE_EDIT;
button_create->set_pressed(false);
button_edit->set_pressed(true);
@@ -94,7 +88,6 @@ void CollisionPolygon3DEditor::_menu_option(int p_option) {
}
void CollisionPolygon3DEditor::_wip_close() {
-
undo_redo->create_action(TTR("Create Polygon3D"));
undo_redo->add_undo_method(node, "set_polygon", node->call("get_polygon"));
undo_redo->add_do_method(node, "set_polygon", wip);
@@ -110,9 +103,9 @@ void CollisionPolygon3DEditor::_wip_close() {
}
bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
-
- if (!node)
+ if (!node) {
return false;
+ }
Transform gt = node->get_global_transform();
Transform gi = gt.affine_inverse();
@@ -123,15 +116,15 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
-
Vector2 gpoint = mb->get_position();
Vector3 ray_from = p_camera->project_ray_origin(gpoint);
Vector3 ray_dir = p_camera->project_ray_normal(gpoint);
Vector3 spoint;
- if (!p.intersects_ray(ray_from, ray_dir, &spoint))
+ if (!p.intersects_ray(ray_from, ray_dir, &spoint)) {
return false;
+ }
spoint = gi.xform(spoint);
@@ -147,13 +140,9 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
switch (mode) {
-
case MODE_CREATE: {
-
if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
-
if (!wip_active) {
-
wip.clear();
wip.push_back(cpoint);
wip_active = true;
@@ -163,14 +152,12 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
edited_point = 1;
return true;
} else {
-
if (wip.size() > 1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x, wip[0].y, depth))).distance_to(gpoint) < grab_threshold) {
//wip closed
_wip_close();
return true;
} else {
-
wip.push_back(cpoint);
edited_point = wip.size();
snap_ignore = false;
@@ -185,14 +172,10 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
} break;
case MODE_EDIT: {
-
if (mb->get_button_index() == BUTTON_LEFT) {
if (mb->is_pressed()) {
-
if (mb->get_control()) {
-
if (poly.size() < 3) {
-
undo_redo->create_action(TTR("Edit Poly"));
undo_redo->add_undo_method(node, "set_polygon", poly);
poly.push_back(cpoint);
@@ -208,15 +191,15 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
Vector2 closest_pos;
real_t closest_dist = 1e10;
for (int i = 0; i < poly.size(); i++) {
-
Vector2 points[2] = {
p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth))),
p_camera->unproject_position(gt.xform(Vector3(poly[(i + 1) % poly.size()].x, poly[(i + 1) % poly.size()].y, depth)))
};
Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points);
- if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2)
+ if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2) {
continue; //not valid to reuse point
+ }
real_t d = cp.distance_to(gpoint);
if (d < closest_dist && d < grab_threshold) {
@@ -227,7 +210,6 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
}
if (closest_idx >= 0) {
-
pre_move_edit = poly;
poly.insert(closest_idx + 1, cpoint);
edited_point = closest_idx + 1;
@@ -239,14 +221,12 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
return true;
}
} else {
-
//look for points to move
int closest_idx = -1;
Vector2 closest_pos;
real_t closest_dist = 1e10;
for (int i = 0; i < poly.size(); i++) {
-
Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth)));
real_t d = cp.distance_to(gpoint);
@@ -258,7 +238,6 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
}
if (closest_idx >= 0) {
-
pre_move_edit = poly;
edited_point = closest_idx;
edited_point_pos = poly[closest_idx];
@@ -268,11 +247,9 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
}
}
} else {
-
snap_ignore = false;
if (edited_point != -1) {
-
//apply
ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
@@ -290,12 +267,10 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
}
}
if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && edited_point == -1) {
-
int closest_idx = -1;
Vector2 closest_pos;
real_t closest_dist = 1e10;
for (int i = 0; i < poly.size(); i++) {
-
Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth)));
real_t d = cp.distance_to(gpoint);
@@ -307,7 +282,6 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
}
if (closest_idx >= 0) {
-
undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
undo_redo->add_undo_method(node, "set_polygon", poly);
poly.remove(closest_idx);
@@ -327,7 +301,6 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
if (mm.is_valid()) {
if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) {
-
Vector2 gpoint = mm->get_position();
Vector3 ray_from = p_camera->project_ray_origin(gpoint);
@@ -335,14 +308,15 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
Vector3 spoint;
- if (!p.intersects_ray(ray_from, ray_dir, &spoint))
+ if (!p.intersects_ray(ray_from, ray_dir, &spoint)) {
return false;
+ }
spoint = gi.xform(spoint);
Vector2 cpoint(spoint.x, spoint.y);
- if (snap_ignore && !InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+ if (snap_ignore && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
snap_ignore = false;
}
@@ -361,24 +335,25 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
}
float CollisionPolygon3DEditor::_get_depth() {
-
- if (bool(node->call("_has_editable_3d_polygon_no_depth")))
+ if (bool(node->call("_has_editable_3d_polygon_no_depth"))) {
return 0;
+ }
return float(node->call("get_depth"));
}
void CollisionPolygon3DEditor::_polygon_draw() {
-
- if (!node)
+ if (!node) {
return;
+ }
Vector<Vector2> poly;
- if (wip_active)
+ if (wip_active) {
poly = wip;
- else
+ } else {
poly = node->call("get_polygon");
+ }
float depth = _get_depth() * 0.5;
@@ -389,18 +364,19 @@ void CollisionPolygon3DEditor::_polygon_draw() {
Rect2 rect;
for (int i = 0; i < poly.size(); i++) {
-
Vector2 p, p2;
p = i == edited_point ? edited_point_pos : poly[i];
- if ((wip_active && i == poly.size() - 1) || (((i + 1) % poly.size()) == edited_point))
+ if ((wip_active && i == poly.size() - 1) || (((i + 1) % poly.size()) == edited_point)) {
p2 = edited_point_pos;
- else
+ } else {
p2 = poly[(i + 1) % poly.size()];
+ }
- if (i == 0)
+ if (i == 0) {
rect.position = p;
- else
+ } else {
rect.expand_to(p);
+ }
Vector3 point = Vector3(p.x, p.y, depth);
Vector3 next_point = Vector3(p2.x, p2.y, depth);
@@ -465,18 +441,17 @@ void CollisionPolygon3DEditor::_polygon_draw() {
m->clear_surfaces();
- if (poly.size() == 0)
+ if (poly.size() == 0) {
return;
+ }
Array a;
a.resize(Mesh::ARRAY_MAX);
Vector<Vector3> va;
{
-
va.resize(poly.size());
Vector3 *w = va.ptrw();
for (int i = 0; i < poly.size(); i++) {
-
Vector2 p, p2;
p = i == edited_point ? edited_point_pos : poly[i];
@@ -490,9 +465,7 @@ void CollisionPolygon3DEditor::_polygon_draw() {
}
void CollisionPolygon3DEditor::edit(Node *p_collision_polygon) {
-
if (p_collision_polygon) {
-
node = Object::cast_to<Node3D>(p_collision_polygon);
//Enable the pencil tool if the polygon is empty
if (Vector<Vector2>(node->call("get_polygon")).size() == 0) {
@@ -509,20 +482,19 @@ void CollisionPolygon3DEditor::edit(Node *p_collision_polygon) {
} else {
node = nullptr;
- if (imgeom->get_parent())
+ if (imgeom->get_parent()) {
imgeom->get_parent()->remove_child(imgeom);
+ }
set_process(false);
}
}
void CollisionPolygon3DEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_polygon_draw"), &CollisionPolygon3DEditor::_polygon_draw);
}
CollisionPolygon3DEditor::CollisionPolygon3DEditor(EditorNode *p_editor) {
-
node = nullptr;
editor = p_editor;
undo_redo = EditorNode::get_undo_redo();
@@ -570,33 +542,27 @@ CollisionPolygon3DEditor::CollisionPolygon3DEditor(EditorNode *p_editor) {
}
CollisionPolygon3DEditor::~CollisionPolygon3DEditor() {
-
memdelete(imgeom);
}
void Polygon3DEditorPlugin::edit(Object *p_object) {
-
collision_polygon_editor->edit(Object::cast_to<Node>(p_object));
}
bool Polygon3DEditorPlugin::handles(Object *p_object) const {
-
return Object::cast_to<Node3D>(p_object) && bool(p_object->call("_is_editable_3d_polygon"));
}
void Polygon3DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
collision_polygon_editor->show();
} else {
-
collision_polygon_editor->hide();
collision_polygon_editor->edit(nullptr);
}
}
Polygon3DEditorPlugin::Polygon3DEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
collision_polygon_editor = memnew(CollisionPolygon3DEditor(p_node));
Node3DEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor);
diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.h b/editor/plugins/collision_polygon_3d_editor_plugin.h
index 9751b1f79e..5215cbb678 100644
--- a/editor/plugins/collision_polygon_3d_editor_plugin.h
+++ b/editor/plugins/collision_polygon_3d_editor_plugin.h
@@ -41,7 +41,6 @@
class CanvasItemEditor;
class CollisionPolygon3DEditor : public HBoxContainer {
-
GDCLASS(CollisionPolygon3DEditor, HBoxContainer);
UndoRedo *undo_redo;
@@ -97,7 +96,6 @@ public:
};
class Polygon3DEditorPlugin : public EditorPlugin {
-
GDCLASS(Polygon3DEditorPlugin, EditorPlugin);
CollisionPolygon3DEditor *collision_polygon_editor;
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index 594dd0d0cb..0f381c06b4 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -40,14 +40,12 @@
#include "scene/resources/segment_shape_2d.h"
void CollisionShape2DEditor::_node_removed(Node *p_node) {
-
if (p_node == node) {
node = nullptr;
}
}
Variant CollisionShape2DEditor::get_handle_value(int idx) const {
-
switch (shape_type) {
case CAPSULE_SHAPE: {
Ref<CapsuleShape2D> capsule = node->get_shape();
@@ -70,18 +68,16 @@ Variant CollisionShape2DEditor::get_handle_value(int idx) const {
} break;
case CONCAVE_POLYGON_SHAPE: {
-
} break;
case CONVEX_POLYGON_SHAPE: {
-
} break;
case LINE_SHAPE: {
Ref<LineShape2D> line = node->get_shape();
if (idx == 0) {
- return line->get_d();
+ return line->get_distance();
} else {
return line->get_normal();
}
@@ -122,7 +118,6 @@ Variant CollisionShape2DEditor::get_handle_value(int idx) const {
}
void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
-
switch (shape_type) {
case CAPSULE_SHAPE: {
if (idx < 2) {
@@ -150,11 +145,9 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
} break;
case CONCAVE_POLYGON_SHAPE: {
-
} break;
case CONVEX_POLYGON_SHAPE: {
-
} break;
case LINE_SHAPE: {
@@ -162,7 +155,7 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
Ref<LineShape2D> line = node->get_shape();
if (idx == 0) {
- line->set_d(p_point.length());
+ line->set_distance(p_point.length());
} else {
line->set_normal(p_point.normalized());
}
@@ -217,7 +210,6 @@ void CollisionShape2DEditor::set_handle(int idx, Point2 &p_point) {
}
void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
-
undo_redo->create_action(TTR("Set Handle"));
switch (shape_type) {
@@ -249,20 +241,18 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
} break;
case CONCAVE_POLYGON_SHAPE: {
-
} break;
case CONVEX_POLYGON_SHAPE: {
-
} break;
case LINE_SHAPE: {
Ref<LineShape2D> line = node->get_shape();
if (idx == 0) {
- undo_redo->add_do_method(line.ptr(), "set_d", line->get_d());
+ undo_redo->add_do_method(line.ptr(), "set_distance", line->get_distance());
undo_redo->add_do_method(canvas_item_editor, "update_viewport");
- undo_redo->add_undo_method(line.ptr(), "set_d", p_org);
+ undo_redo->add_undo_method(line.ptr(), "set_distance", p_org);
undo_redo->add_undo_method(canvas_item_editor, "update_viewport");
} else {
undo_redo->add_do_method(line.ptr(), "set_normal", line->get_normal());
@@ -314,7 +304,6 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
}
bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
-
if (!node) {
return false;
}
@@ -331,7 +320,6 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
if (mb.is_valid()) {
-
Vector2 gpoint = mb->get_position();
if (mb->get_button_index() == BUTTON_LEFT) {
@@ -373,7 +361,6 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
if (edit_handle == -1 || !pressed) {
return false;
}
@@ -390,7 +377,6 @@ bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_e
}
void CollisionShape2DEditor::_get_current_shape_type() {
-
if (!node) {
return;
}
@@ -425,7 +411,6 @@ void CollisionShape2DEditor::_get_current_shape_type() {
}
void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
-
if (!node) {
return;
}
@@ -474,19 +459,17 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla
} break;
case CONCAVE_POLYGON_SHAPE: {
-
} break;
case CONVEX_POLYGON_SHAPE: {
-
} break;
case LINE_SHAPE: {
Ref<LineShape2D> shape = node->get_shape();
handles.resize(2);
- handles.write[0] = shape->get_normal() * shape->get_d();
- handles.write[1] = shape->get_normal() * (shape->get_d() + 30.0);
+ handles.write[0] = shape->get_normal() * shape->get_distance();
+ handles.write[1] = shape->get_normal() * (shape->get_distance() + 30.0);
p_overlay->draw_texture(h, gt.xform(handles[0]) - size);
p_overlay->draw_texture(h, gt.xform(handles[1]) - size);
@@ -533,9 +516,7 @@ void CollisionShape2DEditor::forward_canvas_draw_over_viewport(Control *p_overla
}
void CollisionShape2DEditor::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
get_tree()->connect("node_removed", callable_mp(this, &CollisionShape2DEditor::_node_removed));
} break;
@@ -547,7 +528,6 @@ void CollisionShape2DEditor::_notification(int p_what) {
}
void CollisionShape2DEditor::edit(Node *p_node) {
-
if (!canvas_item_editor) {
canvas_item_editor = CanvasItemEditor::get_singleton();
}
@@ -568,12 +548,10 @@ void CollisionShape2DEditor::edit(Node *p_node) {
}
void CollisionShape2DEditor::_bind_methods() {
-
ClassDB::bind_method("_get_current_shape_type", &CollisionShape2DEditor::_get_current_shape_type);
}
CollisionShape2DEditor::CollisionShape2DEditor(EditorNode *p_editor) {
-
node = nullptr;
canvas_item_editor = nullptr;
editor = p_editor;
@@ -585,24 +563,20 @@ CollisionShape2DEditor::CollisionShape2DEditor(EditorNode *p_editor) {
}
void CollisionShape2DEditorPlugin::edit(Object *p_obj) {
-
collision_shape_2d_editor->edit(Object::cast_to<Node>(p_obj));
}
bool CollisionShape2DEditorPlugin::handles(Object *p_obj) const {
-
return p_obj->is_class("CollisionShape2D");
}
void CollisionShape2DEditorPlugin::make_visible(bool visible) {
-
if (!visible) {
edit(nullptr);
}
}
CollisionShape2DEditorPlugin::CollisionShape2DEditorPlugin(EditorNode *p_editor) {
-
editor = p_editor;
collision_shape_2d_editor = memnew(CollisionShape2DEditor(p_editor));
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.cpp b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
index ef4d7d7646..008de7cfb4 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.cpp
@@ -37,53 +37,42 @@
#include "scene/resources/particles_material.h"
void CPUParticles2DEditorPlugin::edit(Object *p_object) {
-
particles = Object::cast_to<CPUParticles2D>(p_object);
}
bool CPUParticles2DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("CPUParticles2D");
}
void CPUParticles2DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
-
toolbar->show();
} else {
-
toolbar->hide();
}
}
void CPUParticles2DEditorPlugin::_file_selected(const String &p_file) {
-
source_emission_file = p_file;
emission_mask->popup_centered();
}
void CPUParticles2DEditorPlugin::_menu_callback(int p_idx) {
-
switch (p_idx) {
case MENU_LOAD_EMISSION_MASK: {
-
file->popup_centered_ratio();
} break;
case MENU_CLEAR_EMISSION_MASK: {
-
emission_mask->popup_centered();
} break;
case MENU_RESTART: {
-
particles->restart();
}
}
}
void CPUParticles2DEditorPlugin::_generate_emission_mask() {
-
Ref<Image> img;
img.instance();
Error err = ImageLoader::load_image(source_emission_file, img);
@@ -123,13 +112,10 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() {
for (int i = 0; i < s.width; i++) {
for (int j = 0; j < s.height; j++) {
-
uint8_t a = r[(j * s.width + i) * 4 + 3];
if (a > 128) {
-
if (emode == EMISSION_MODE_SOLID) {
-
if (capture_colors) {
valid_colors.write[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
valid_colors.write[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
@@ -139,19 +125,18 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() {
valid_positions.write[vpc++] = Point2(i, j);
} else {
-
bool on_border = false;
for (int x = i - 1; x <= i + 1; x++) {
for (int y = j - 1; y <= j + 1; y++) {
-
if (x < 0 || y < 0 || x >= s.width || y >= s.height || r[(y * s.width + x) * 4 + 3] <= 128) {
on_border = true;
break;
}
}
- if (on_border)
+ if (on_border) {
break;
+ }
}
if (on_border) {
@@ -161,9 +146,9 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() {
Vector2 normal;
for (int x = i - 2; x <= i + 2; x++) {
for (int y = j - 2; y <= j + 2; y++) {
-
- if (x == i && y == j)
+ if (x == i && y == j) {
continue;
+ }
if (x < 0 || y < 0 || x >= s.width || y >= s.height || r[(y * s.width + x) * 4 + 3] <= 128) {
normal += Vector2(x - i, y - j).normalized();
@@ -237,9 +222,7 @@ void CPUParticles2DEditorPlugin::_generate_emission_mask() {
}
void CPUParticles2DEditorPlugin::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
menu->get_popup()->connect("id_pressed", callable_mp(this, &CPUParticles2DEditorPlugin::_menu_callback));
menu->set_icon(epoints->get_theme_icon("CPUParticles2D", "EditorIcons"));
file->connect("file_selected", callable_mp(this, &CPUParticles2DEditorPlugin::_file_selected));
@@ -250,7 +233,6 @@ void CPUParticles2DEditorPlugin::_bind_methods() {
}
CPUParticles2DEditorPlugin::CPUParticles2DEditorPlugin(EditorNode *p_node) {
-
particles = nullptr;
editor = p_node;
undo_redo = editor->get_undo_redo();
diff --git a/editor/plugins/cpu_particles_2d_editor_plugin.h b/editor/plugins/cpu_particles_2d_editor_plugin.h
index 21b06b6489..fecbb8b1cd 100644
--- a/editor/plugins/cpu_particles_2d_editor_plugin.h
+++ b/editor/plugins/cpu_particles_2d_editor_plugin.h
@@ -39,7 +39,6 @@
#include "scene/gui/file_dialog.h"
class CPUParticles2DEditorPlugin : public EditorPlugin {
-
GDCLASS(CPUParticles2DEditorPlugin, EditorPlugin);
enum {
diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.cpp b/editor/plugins/cpu_particles_3d_editor_plugin.cpp
index 59a353a581..ef26ecd767 100644
--- a/editor/plugins/cpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/cpu_particles_3d_editor_plugin.cpp
@@ -33,7 +33,6 @@
#include "editor/plugins/node_3d_editor_plugin.h"
void CPUParticles3DEditor::_node_removed(Node *p_node) {
-
if (p_node == node) {
node = nullptr;
hide();
@@ -41,24 +40,19 @@ void CPUParticles3DEditor::_node_removed(Node *p_node) {
}
void CPUParticles3DEditor::_notification(int p_notification) {
-
if (p_notification == NOTIFICATION_ENTER_TREE) {
options->set_icon(get_theme_icon("CPUParticles3D", "EditorIcons"));
}
}
void CPUParticles3DEditor::_menu_option(int p_option) {
-
switch (p_option) {
-
case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: {
-
emission_tree_dialog->popup_centered_ratio();
} break;
case MENU_OPTION_RESTART: {
-
node->restart();
} break;
@@ -66,13 +60,11 @@ void CPUParticles3DEditor::_menu_option(int p_option) {
}
void CPUParticles3DEditor::edit(CPUParticles3D *p_particles) {
-
base_node = p_particles;
node = p_particles;
}
void CPUParticles3DEditor::_generate_emission_points() {
-
/// hacer codigo aca
Vector<Vector3> points;
Vector<Vector3> normals;
@@ -95,7 +87,6 @@ void CPUParticles3DEditor::_bind_methods() {
}
CPUParticles3DEditor::CPUParticles3DEditor() {
-
particles_editor_hb = memnew(HBoxContainer);
Node3DEditor::get_singleton()->add_control_to_menu_panel(particles_editor_hb);
options = memnew(MenuButton);
@@ -110,17 +101,14 @@ CPUParticles3DEditor::CPUParticles3DEditor() {
}
void CPUParticles3DEditorPlugin::edit(Object *p_object) {
-
particles_editor->edit(Object::cast_to<CPUParticles3D>(p_object));
}
bool CPUParticles3DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("CPUParticles3D");
}
void CPUParticles3DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
particles_editor->show();
particles_editor->particles_editor_hb->show();
@@ -132,7 +120,6 @@ void CPUParticles3DEditorPlugin::make_visible(bool p_visible) {
}
CPUParticles3DEditorPlugin::CPUParticles3DEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
particles_editor = memnew(CPUParticles3DEditor);
editor->get_viewport()->add_child(particles_editor);
diff --git a/editor/plugins/cpu_particles_3d_editor_plugin.h b/editor/plugins/cpu_particles_3d_editor_plugin.h
index 796c842e07..d9680496ba 100644
--- a/editor/plugins/cpu_particles_3d_editor_plugin.h
+++ b/editor/plugins/cpu_particles_3d_editor_plugin.h
@@ -35,7 +35,6 @@
#include "scene/3d/cpu_particles_3d.h"
class CPUParticles3DEditor : public GPUParticles3DEditorBase {
-
GDCLASS(CPUParticles3DEditor, GPUParticles3DEditorBase);
enum Menu {
@@ -65,7 +64,6 @@ public:
};
class CPUParticles3DEditorPlugin : public EditorPlugin {
-
GDCLASS(CPUParticles3DEditorPlugin, EditorPlugin);
CPUParticles3DEditor *particles_editor;
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index 71c5a78e0b..539ab03f5b 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -32,7 +32,7 @@
#include "canvas_item_editor_plugin.h"
#include "core/core_string_names.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/keyboard.h"
#include "editor/editor_scale.h"
@@ -65,9 +65,9 @@ CurveEditor::CurveEditor() {
}
void CurveEditor::set_curve(Ref<Curve> curve) {
-
- if (curve == _curve_ref)
+ if (curve == _curve_ref) {
return;
+ }
if (_curve_ref.is_valid()) {
_curve_ref->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CurveEditor::_curve_changed));
@@ -96,24 +96,23 @@ Size2 CurveEditor::get_minimum_size() const {
}
void CurveEditor::_notification(int p_what) {
- if (p_what == NOTIFICATION_DRAW)
+ if (p_what == NOTIFICATION_DRAW) {
_draw();
+ }
}
void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> mb_ref = p_event;
if (mb_ref.is_valid()) {
-
const InputEventMouseButton &mb = **mb_ref;
if (mb.is_pressed() && !_dragging) {
-
Vector2 mpos = mb.get_position();
_selected_tangent = get_tangent_at(mpos);
- if (_selected_tangent == TANGENT_NONE)
+ if (_selected_tangent == TANGENT_NONE) {
set_selected_point(get_point_at(mpos));
+ }
switch (mb.get_button_index()) {
case BUTTON_RIGHT:
@@ -134,7 +133,6 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
if (!mb.is_pressed() && _dragging && mb.get_button_index() == BUTTON_LEFT) {
_dragging = false;
if (_has_undo_data) {
-
UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo();
ur.create_action(_selected_tangent == TANGENT_NONE ? TTR("Modify Curve Point") : TTR("Modify Curve Tangent"));
@@ -151,13 +149,11 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm_ref = p_event;
if (mm_ref.is_valid()) {
-
const InputEventMouseMotion &mm = **mm_ref;
Vector2 mpos = mm.get_position();
if (_dragging && _curve_ref.is_valid()) {
-
if (_selected_point != -1) {
Curve &curve = **_curve_ref;
@@ -189,10 +185,11 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
set_selected_point(i);
// This is to prevent the user from losing a point out of view.
- if (point_pos.y < curve.get_min_value())
+ if (point_pos.y < curve.get_min_value()) {
point_pos.y = curve.get_min_value();
- else if (point_pos.y > curve.get_max_value())
+ } else if (point_pos.y > curve.get_max_value()) {
point_pos.y = curve.get_max_value();
+ }
curve.set_point_value(_selected_point, point_pos.y);
@@ -205,25 +202,28 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
Vector2 dir = (control_pos - point_pos).normalized();
real_t tangent;
- if (!Math::is_zero_approx(dir.x))
+ if (!Math::is_zero_approx(dir.x)) {
tangent = dir.y / dir.x;
- else
+ } else {
tangent = 9999 * (dir.y >= 0 ? 1 : -1);
+ }
- bool link = !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
+ bool link = !Input::get_singleton()->is_key_pressed(KEY_SHIFT);
if (_selected_tangent == TANGENT_LEFT) {
curve.set_point_left_tangent(_selected_point, tangent);
// Note: if a tangent is set to linear, it shouldn't be linked to the other
- if (link && _selected_point != (curve.get_point_count() - 1) && curve.get_point_right_mode(_selected_point) != Curve::TANGENT_LINEAR)
+ if (link && _selected_point != (curve.get_point_count() - 1) && curve.get_point_right_mode(_selected_point) != Curve::TANGENT_LINEAR) {
curve.set_point_right_tangent(_selected_point, tangent);
+ }
} else {
curve.set_point_right_tangent(_selected_point, tangent);
- if (link && _selected_point != 0 && curve.get_point_left_mode(_selected_point) != Curve::TANGENT_LINEAR)
+ if (link && _selected_point != 0 && curve.get_point_left_mode(_selected_point) != Curve::TANGENT_LINEAR) {
curve.set_point_left_tangent(_selected_point, tangent);
+ }
}
}
}
@@ -238,8 +238,9 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
const InputEventKey &key = **key_ref;
if (key.is_pressed() && _selected_point != -1) {
- if (key.get_keycode() == KEY_DELETE)
+ if (key.get_keycode() == KEY_DELETE) {
remove_point(_selected_point);
+ }
}
}
}
@@ -358,8 +359,9 @@ void CurveEditor::open_context_menu(Vector2 pos) {
_context_menu->set_item_checked(_context_menu->get_item_index(CONTEXT_LINEAR), is_linear);
} else {
- if (_selected_point > 0 || _selected_point + 1 < _curve_ref->get_point_count())
+ if (_selected_point > 0 || _selected_point + 1 < _curve_ref->get_point_count()) {
_context_menu->add_separator();
+ }
if (_selected_point > 0) {
_context_menu->add_check_item(TTR("Left Linear"), CONTEXT_LEFT_LINEAR);
@@ -384,8 +386,9 @@ void CurveEditor::open_context_menu(Vector2 pos) {
}
int CurveEditor::get_point_at(Vector2 pos) const {
- if (_curve_ref.is_null())
+ if (_curve_ref.is_null()) {
return -1;
+ }
const Curve &curve = **_curve_ref;
const float r = _hover_radius * _hover_radius;
@@ -401,8 +404,9 @@ int CurveEditor::get_point_at(Vector2 pos) const {
}
CurveEditor::TangentIndex CurveEditor::get_tangent_at(Vector2 pos) const {
- if (_curve_ref.is_null() || _selected_point < 0)
+ if (_curve_ref.is_null() || _selected_point < 0) {
return TANGENT_NONE;
+ }
if (_selected_point != 0) {
Vector2 control_pos = get_tangent_view_pos(_selected_point, TANGENT_LEFT);
@@ -428,10 +432,11 @@ void CurveEditor::add_point(Vector2 pos) {
ur.create_action(TTR("Remove Curve Point"));
Vector2 point_pos = get_world_pos(pos);
- if (point_pos.y < 0.0)
+ if (point_pos.y < 0.0) {
point_pos.y = 0.0;
- else if (point_pos.y > 1.0)
+ } else if (point_pos.y > 1.0) {
point_pos.y = 1.0;
+ }
// Small trick to get the point index to feed the undo method
int i = _curve_ref->add_point(point_pos);
@@ -454,11 +459,13 @@ void CurveEditor::remove_point(int index) {
ur.add_do_method(*_curve_ref, "remove_point", index);
ur.add_undo_method(*_curve_ref, "add_point", p.pos, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode);
- if (index == _selected_point)
+ if (index == _selected_point) {
set_selected_point(-1);
+ }
- if (index == _hover_point)
+ if (index == _hover_point) {
set_hover_point_index(-1);
+ }
ur.commit_action();
}
@@ -469,11 +476,11 @@ void CurveEditor::toggle_linear(TangentIndex tangent) {
UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo();
ur.create_action(TTR("Toggle Curve Linear Tangent"));
- if (tangent == TANGENT_NONE)
+ if (tangent == TANGENT_NONE) {
tangent = _selected_tangent;
+ }
if (tangent == TANGENT_LEFT) {
-
bool is_linear = _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR;
Curve::TangentMode prev_mode = _curve_ref->get_point_left_mode(_selected_point);
@@ -483,7 +490,6 @@ void CurveEditor::toggle_linear(TangentIndex tangent) {
ur.add_undo_method(*_curve_ref, "set_point_left_mode", _selected_point, prev_mode);
} else {
-
bool is_linear = _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR;
Curve::TangentMode prev_mode = _curve_ref->get_point_right_mode(_selected_point);
@@ -538,12 +544,12 @@ void CurveEditor::update_view_transform() {
}
Vector2 CurveEditor::get_tangent_view_pos(int i, TangentIndex tangent) const {
-
Vector2 dir;
- if (tangent == TANGENT_LEFT)
+ if (tangent == TANGENT_LEFT) {
dir = -Vector2(1, _curve_ref->get_point_left_tangent(i));
- else
+ } else {
dir = Vector2(1, _curve_ref->get_point_right_tangent(i));
+ }
Vector2 point_pos = get_view_pos(_curve_ref->get_point_position(i));
Vector2 control_pos = get_view_pos(_curve_ref->get_point_position(i) + dir);
@@ -562,7 +568,6 @@ Vector2 CurveEditor::get_world_pos(Vector2 view_pos) const {
// Uses non-baked points, but takes advantage of ordered iteration to be faster
template <typename T>
static void plot_curve_accurate(const Curve &curve, float step, T plot_func) {
-
if (curve.get_point_count() <= 1) {
// Not enough points to make a curve, so it's just a straight line
float y = curve.interpolate(0);
@@ -600,7 +605,6 @@ static void plot_curve_accurate(const Curve &curve, float step, T plot_func) {
}
struct CanvasItemPlotCurve {
-
CanvasItem &ci;
Color color1;
Color color2;
@@ -617,8 +621,9 @@ struct CanvasItemPlotCurve {
};
void CurveEditor::_draw() {
- if (_curve_ref.is_null())
+ if (_curve_ref.is_null()) {
return;
+ }
Curve &curve = **_curve_ref;
update_view_transform();
@@ -685,7 +690,6 @@ void CurveEditor::_draw() {
// Draw tangents for current point
if (_selected_point >= 0) {
-
const Color tangent_color = get_theme_color("accent_color", "Editor");
int i = _selected_point;
@@ -754,12 +758,10 @@ void CurveEditor::_bind_methods() {
//---------------
bool EditorInspectorPluginCurve::can_handle(Object *p_object) {
-
return Object::cast_to<Curve>(p_object) != nullptr;
}
void EditorInspectorPluginCurve::parse_begin(Object *p_object) {
-
Curve *curve = Object::cast_to<Curve>(p_object);
ERR_FAIL_COND(!curve);
Ref<Curve> c(curve);
@@ -785,7 +787,6 @@ bool CurvePreviewGenerator::handles(const String &p_type) const {
}
Ref<Texture2D> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, const Size2 &p_size) const {
-
Ref<Curve> curve_ref = p_from;
ERR_FAIL_COND_V_MSG(curve_ref.is_null(), Ref<Texture2D>(), "It's not a reference to a valid Resource object.");
Curve &curve = **curve_ref;
@@ -797,7 +798,7 @@ Ref<Texture2D> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, cons
img_ref.instance();
Image &im = **img_ref;
- im.create(thumbnail_size, thumbnail_size / 2, 0, Image::FORMAT_RGBA8);
+ im.create(thumbnail_size, thumbnail_size / 2, false, Image::FORMAT_RGBA8);
Color bg_color(0.1, 0.1, 0.1, 1.0);
for (int i = 0; i < thumbnail_size; i++) {
@@ -811,7 +812,6 @@ Ref<Texture2D> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, cons
int prev_y = 0;
for (int x = 0; x < im.get_width(); ++x) {
-
float t = static_cast<float>(x) / im.get_width();
float v = (curve.interpolate_baked(t) - curve.get_min_value()) / range_y;
int y = CLAMP(im.get_height() - v * im.get_height(), 0, im.get_height());
diff --git a/editor/plugins/debugger_editor_plugin.cpp b/editor/plugins/debugger_editor_plugin.cpp
index 566ff378c3..0ca479555d 100644
--- a/editor/plugins/debugger_editor_plugin.cpp
+++ b/editor/plugins/debugger_editor_plugin.cpp
@@ -32,11 +32,14 @@
#include "core/os/keyboard.h"
#include "editor/debugger/editor_debugger_node.h"
+#include "editor/debugger/editor_debugger_server.h"
#include "editor/editor_node.h"
#include "editor/fileserver/editor_file_server.h"
#include "scene/gui/menu_button.h"
DebuggerEditorPlugin::DebuggerEditorPlugin(EditorNode *p_editor, MenuButton *p_debug_menu) {
+ EditorDebuggerServer::initialize();
+
ED_SHORTCUT("debugger/step_into", TTR("Step Into"), KEY_F11);
ED_SHORTCUT("debugger/step_over", TTR("Step Over"), KEY_F10);
ED_SHORTCUT("debugger/break", TTR("Break"));
@@ -96,6 +99,7 @@ DebuggerEditorPlugin::DebuggerEditorPlugin(EditorNode *p_editor, MenuButton *p_d
}
DebuggerEditorPlugin::~DebuggerEditorPlugin() {
+ EditorDebuggerServer::deinitialize();
memdelete(file_server);
}
@@ -110,7 +114,6 @@ void DebuggerEditorPlugin::_select_run_count(int p_index) {
void DebuggerEditorPlugin::_menu_option(int p_option) {
switch (p_option) {
case RUN_FILE_SERVER: {
-
bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_FILE_SERVER));
if (ischecked) {
@@ -124,7 +127,6 @@ void DebuggerEditorPlugin::_menu_option(int p_option) {
} break;
case RUN_LIVE_DEBUG: {
-
bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_LIVE_DEBUG));
debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_LIVE_DEBUG), !ischecked);
@@ -133,28 +135,24 @@ void DebuggerEditorPlugin::_menu_option(int p_option) {
} break;
case RUN_DEPLOY_REMOTE_DEBUG: {
-
bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG));
debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG), !ischecked);
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_deploy_remote_debug", !ischecked);
} break;
case RUN_DEBUG_COLLISONS: {
-
bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_COLLISONS));
debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_COLLISONS), !ischecked);
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_collisons", !ischecked);
} break;
case RUN_DEBUG_NAVIGATION: {
-
bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION));
debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION), !ischecked);
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_navigation", !ischecked);
} break;
case RUN_RELOAD_SCRIPTS: {
-
bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_RELOAD_SCRIPTS));
debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_RELOAD_SCRIPTS), !ischecked);
@@ -166,8 +164,9 @@ void DebuggerEditorPlugin::_menu_option(int p_option) {
}
void DebuggerEditorPlugin::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY)
+ if (p_what == NOTIFICATION_READY) {
_update_debug_options();
+ }
}
void DebuggerEditorPlugin::_update_debug_options() {
@@ -179,12 +178,24 @@ void DebuggerEditorPlugin::_update_debug_options() {
bool check_reload_scripts = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_reload_scripts", false);
int instances = EditorSettings::get_singleton()->get_project_metadata("debug_options", "run_debug_instances", 1);
- if (check_deploy_remote) _menu_option(RUN_DEPLOY_REMOTE_DEBUG);
- if (check_file_server) _menu_option(RUN_FILE_SERVER);
- if (check_debug_collisions) _menu_option(RUN_DEBUG_COLLISONS);
- if (check_debug_navigation) _menu_option(RUN_DEBUG_NAVIGATION);
- if (check_live_debug) _menu_option(RUN_LIVE_DEBUG);
- if (check_reload_scripts) _menu_option(RUN_RELOAD_SCRIPTS);
+ if (check_deploy_remote) {
+ _menu_option(RUN_DEPLOY_REMOTE_DEBUG);
+ }
+ if (check_file_server) {
+ _menu_option(RUN_FILE_SERVER);
+ }
+ if (check_debug_collisions) {
+ _menu_option(RUN_DEBUG_COLLISONS);
+ }
+ if (check_debug_navigation) {
+ _menu_option(RUN_DEBUG_NAVIGATION);
+ }
+ if (check_live_debug) {
+ _menu_option(RUN_LIVE_DEBUG);
+ }
+ if (check_reload_scripts) {
+ _menu_option(RUN_RELOAD_SCRIPTS);
+ }
int len = instances_menu->get_item_count();
for (int idx = 0; idx < len; idx++) {
diff --git a/editor/plugins/debugger_editor_plugin.h b/editor/plugins/debugger_editor_plugin.h
index 5ec6399921..465041b5a7 100644
--- a/editor/plugins/debugger_editor_plugin.h
+++ b/editor/plugins/debugger_editor_plugin.h
@@ -39,7 +39,6 @@ class MenuButton;
class PopupMenu;
class DebuggerEditorPlugin : public EditorPlugin {
-
GDCLASS(DebuggerEditorPlugin, EditorPlugin);
private:
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index a8c4bddccf..9cb167b41c 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -43,9 +43,9 @@
#include "servers/audio/audio_stream.h"
void post_process_preview(Ref<Image> p_image) {
-
- if (p_image->get_format() != Image::FORMAT_RGBA8)
+ if (p_image->get_format() != Image::FORMAT_RGBA8) {
p_image->convert(Image::FORMAT_RGBA8);
+ }
const int w = p_image->get_width();
const int h = p_image->get_height();
@@ -71,7 +71,6 @@ void post_process_preview(Ref<Image> p_image) {
}
bool EditorTexturePreviewPlugin::handles(const String &p_type) const {
-
return ClassDB::is_parent_class(p_type, "Texture2D");
}
@@ -80,7 +79,6 @@ bool EditorTexturePreviewPlugin::generate_small_preview_automatically() const {
}
Ref<Texture2D> EditorTexturePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const {
-
Ref<Image> img;
Ref<AtlasTexture> atex = p_from;
Ref<LargeTexture> ltex = p_from;
@@ -108,14 +106,16 @@ Ref<Texture2D> EditorTexturePreviewPlugin::generate(const RES &p_from, const Siz
}
}
- if (img.is_null() || img->empty())
+ if (img.is_null() || img->empty()) {
return Ref<Texture2D>();
+ }
img->clear_mipmaps();
if (img->is_compressed()) {
- if (img->decompress() != OK)
+ if (img->decompress() != OK) {
return Ref<Texture2D>();
+ }
} else if (img->get_format() != Image::FORMAT_RGB8 && img->get_format() != Image::FORMAT_RGBA8) {
img->convert(Image::FORMAT_RGBA8);
}
@@ -143,23 +143,23 @@ EditorTexturePreviewPlugin::EditorTexturePreviewPlugin() {
////////////////////////////////////////////////////////////////////////////
bool EditorImagePreviewPlugin::handles(const String &p_type) const {
-
return p_type == "Image";
}
Ref<Texture2D> EditorImagePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const {
-
Ref<Image> img = p_from;
- if (img.is_null() || img->empty())
+ if (img.is_null() || img->empty()) {
return Ref<Image>();
+ }
img = img->duplicate();
img->clear_mipmaps();
if (img->is_compressed()) {
- if (img->decompress() != OK)
+ if (img->decompress() != OK) {
return Ref<Image>();
+ }
} else if (img->get_format() != Image::FORMAT_RGB8 && img->get_format() != Image::FORMAT_RGBA8) {
img->convert(Image::FORMAT_RGBA8);
}
@@ -188,15 +188,14 @@ EditorImagePreviewPlugin::EditorImagePreviewPlugin() {
bool EditorImagePreviewPlugin::generate_small_preview_automatically() const {
return true;
}
+
////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////
bool EditorBitmapPreviewPlugin::handles(const String &p_type) const {
-
return ClassDB::is_parent_class(p_type, "BitMap");
}
Ref<Texture2D> EditorBitmapPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const {
-
Ref<BitMap> bm = p_from;
if (bm->get_size() == Size2()) {
@@ -223,11 +222,12 @@ Ref<Texture2D> EditorBitmapPreviewPlugin::generate(const RES &p_from, const Size
Ref<Image> img;
img.instance();
- img->create(bm->get_size().width, bm->get_size().height, 0, Image::FORMAT_L8, data);
+ img->create(bm->get_size().width, bm->get_size().height, false, Image::FORMAT_L8, data);
if (img->is_compressed()) {
- if (img->decompress() != OK)
+ if (img->decompress() != OK) {
return Ref<Texture2D>();
+ }
} else if (img->get_format() != Image::FORMAT_RGB8 && img->get_format() != Image::FORMAT_RGBA8) {
img->convert(Image::FORMAT_RGBA8);
}
@@ -259,17 +259,14 @@ EditorBitmapPreviewPlugin::EditorBitmapPreviewPlugin() {
///////////////////////////////////////////////////////////////////////////
bool EditorPackedScenePreviewPlugin::handles(const String &p_type) const {
-
return ClassDB::is_parent_class(p_type, "PackedScene");
}
Ref<Texture2D> EditorPackedScenePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const {
-
return generate_from_path(p_from->get_path(), p_size);
}
Ref<Texture2D> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const {
-
String temp_path = EditorSettings::get_singleton()->get_cache_dir();
String cache_base = ProjectSettings::get_singleton()->globalize_path(p_path).md5_text();
cache_base = temp_path.plus_file("resthumb-" + cache_base);
@@ -278,14 +275,14 @@ Ref<Texture2D> EditorPackedScenePreviewPlugin::generate_from_path(const String &
String path = cache_base + ".png";
- if (!FileAccess::exists(path))
+ if (!FileAccess::exists(path)) {
return Ref<Texture2D>();
+ }
Ref<Image> img;
img.instance();
Error err = img->load(path);
if (err == OK) {
-
Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
post_process_preview(img);
@@ -303,17 +300,14 @@ EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() {
//////////////////////////////////////////////////////////////////
void EditorMaterialPreviewPlugin::_preview_done(const Variant &p_udata) {
-
preview_done = true;
}
void EditorMaterialPreviewPlugin::_bind_methods() {
-
ClassDB::bind_method("_preview_done", &EditorMaterialPreviewPlugin::_preview_done);
}
bool EditorMaterialPreviewPlugin::handles(const String &p_type) const {
-
return ClassDB::is_parent_class(p_type, "Material"); //any material
}
@@ -322,12 +316,10 @@ bool EditorMaterialPreviewPlugin::generate_small_preview_automatically() const {
}
Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const {
-
Ref<Material> material = p_from;
ERR_FAIL_COND_V(material.is_null(), Ref<Texture2D>());
if (material->get_shader_mode() == Shader::MODE_SPATIAL) {
-
RS::get_singleton()->mesh_surface_set_material(sphere, 0, material->get_rid());
RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_ONCE); //once used for capture
@@ -357,7 +349,6 @@ Ref<Texture2D> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Si
}
EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
-
scenario = RS::get_singleton()->scenario_create();
viewport = RS::get_singleton()->viewport_create();
@@ -408,7 +399,6 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
double zr1 = Math::cos(lat1);
for (int j = lons; j >= 1; j--) {
-
double lng0 = 2 * Math_PI * (double)(j - 1) / lons;
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
@@ -462,7 +452,6 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
}
EditorMaterialPreviewPlugin::~EditorMaterialPreviewPlugin() {
-
RS::get_singleton()->free(sphere);
RS::get_singleton()->free(sphere_instance);
RS::get_singleton()->free(viewport);
@@ -477,24 +466,23 @@ EditorMaterialPreviewPlugin::~EditorMaterialPreviewPlugin() {
///////////////////////////////////////////////////////////////////////////
static bool _is_text_char(CharType c) {
-
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
bool EditorScriptPreviewPlugin::handles(const String &p_type) const {
-
return ClassDB::is_parent_class(p_type, "Script");
}
Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const {
-
Ref<Script> scr = p_from;
- if (scr.is_null())
+ if (scr.is_null()) {
return Ref<Texture2D>();
+ }
String code = scr->get_source_code().strip_edges();
- if (code == "")
+ if (code == "") {
return Ref<Texture2D>();
+ }
List<String> kwors;
scr->get_language()->get_reserved_words(&kwors);
@@ -502,7 +490,6 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size
Set<String> keywords;
for (List<String>::Element *E = kwors.front(); E; E = E->next()) {
-
keywords.insert(E->get());
}
@@ -511,15 +498,16 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size
Ref<Image> img;
img.instance();
int thumbnail_size = MAX(p_size.x, p_size.y);
- img->create(thumbnail_size, thumbnail_size, 0, Image::FORMAT_RGBA8);
+ img->create(thumbnail_size, thumbnail_size, false, Image::FORMAT_RGBA8);
Color bg_color = EditorSettings::get_singleton()->get("text_editor/highlighting/background_color");
Color keyword_color = EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color");
Color text_color = EditorSettings::get_singleton()->get("text_editor/highlighting/text_color");
Color symbol_color = EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color");
- if (bg_color.a == 0)
+ if (bg_color.a == 0) {
bg_color = Color(0, 0, 0, 0);
+ }
bg_color.a = MAX(bg_color.a, 0.2); // some background
for (int i = 0; i < thumbnail_size; i++) {
@@ -536,7 +524,6 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size
bool prev_is_text = false;
bool in_keyword = false;
for (int i = 0; i < code.length(); i++) {
-
CharType c = code[i];
if (c > 32) {
if (col < thumbnail_size) {
@@ -553,15 +540,17 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size
pos++;
}
String word = code.substr(i, pos - i);
- if (keywords.has(word))
+ if (keywords.has(word)) {
in_keyword = true;
+ }
} else if (!_is_text_char(c)) {
in_keyword = false;
}
- if (in_keyword)
+ if (in_keyword) {
color = keyword_color;
+ }
Color ul = color;
ul.a *= 0.5;
@@ -571,15 +560,15 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size
prev_is_text = _is_text_char(c);
}
} else {
-
prev_is_text = false;
in_keyword = false;
if (c == '\n') {
col = x0;
line++;
- if (line >= available_height / 2)
+ if (line >= available_height / 2) {
break;
+ }
} else if (c == '\t') {
col += 3;
}
@@ -597,15 +586,14 @@ Ref<Texture2D> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size
EditorScriptPreviewPlugin::EditorScriptPreviewPlugin() {
}
+
///////////////////////////////////////////////////////////////////
bool EditorAudioStreamPreviewPlugin::handles(const String &p_type) const {
-
return ClassDB::is_parent_class(p_type, "AudioStream");
}
Ref<Texture2D> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const {
-
Ref<AudioStream> stream = p_from;
ERR_FAIL_COND_V(stream.is_null(), Ref<Texture2D>());
@@ -635,7 +623,6 @@ Ref<Texture2D> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const
playback->stop();
for (int i = 0; i < w; i++) {
-
float max = -1000;
float min = 1000;
int from = uint64_t(i) * frame_length / w;
@@ -647,7 +634,6 @@ Ref<Texture2D> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const
}
for (int j = from; j < to; j++) {
-
max = MAX(max, frames[j].l);
max = MAX(max, frames[j].r);
@@ -688,21 +674,18 @@ EditorAudioStreamPreviewPlugin::EditorAudioStreamPreviewPlugin() {
///////////////////////////////////////////////////////////////////////////
void EditorMeshPreviewPlugin::_preview_done(const Variant &p_udata) {
-
preview_done = true;
}
void EditorMeshPreviewPlugin::_bind_methods() {
-
ClassDB::bind_method("_preview_done", &EditorMeshPreviewPlugin::_preview_done);
}
-bool EditorMeshPreviewPlugin::handles(const String &p_type) const {
+bool EditorMeshPreviewPlugin::handles(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Mesh"); //any Mesh
}
Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const {
-
Ref<Mesh> mesh = p_from;
ERR_FAIL_COND_V(mesh.is_null(), Ref<Texture2D>());
@@ -716,8 +699,9 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2
xform.basis = Basis().rotated(Vector3(1, 0, 0), Math_PI * 0.125) * xform.basis;
AABB rot_aabb = xform.xform(aabb);
float m = MAX(rot_aabb.size.x, rot_aabb.size.y) * 0.5;
- if (m == 0)
+ if (m == 0) {
return Ref<Texture2D>();
+ }
m = 1.0 / m;
m *= 0.5;
xform.basis.scale(Vector3(m, m, m));
@@ -758,7 +742,6 @@ Ref<Texture2D> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2
}
EditorMeshPreviewPlugin::EditorMeshPreviewPlugin() {
-
scenario = RS::get_singleton()->scenario_create();
viewport = RS::get_singleton()->viewport_create();
@@ -792,7 +775,6 @@ EditorMeshPreviewPlugin::EditorMeshPreviewPlugin() {
}
EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() {
-
//RS::get_singleton()->free(sphere);
RS::get_singleton()->free(mesh_instance);
RS::get_singleton()->free(viewport);
@@ -807,22 +789,18 @@ EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() {
///////////////////////////////////////////////////////////////////////////
void EditorFontPreviewPlugin::_preview_done(const Variant &p_udata) {
-
preview_done = true;
}
void EditorFontPreviewPlugin::_bind_methods() {
-
ClassDB::bind_method("_preview_done", &EditorFontPreviewPlugin::_preview_done);
}
bool EditorFontPreviewPlugin::handles(const String &p_type) const {
-
return ClassDB::is_parent_class(p_type, "DynamicFontData") || ClassDB::is_parent_class(p_type, "DynamicFont");
}
Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const {
-
RES res = ResourceLoader::load(p_path);
Ref<DynamicFont> sampled_font;
if (res->is_class("DynamicFont")) {
@@ -881,7 +859,6 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate_from_path(const String &p_path,
}
Ref<Texture2D> EditorFontPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const {
-
String path = p_from->get_path();
if (!FileAccess::exists(path)) {
return Ref<Texture2D>();
@@ -890,7 +867,6 @@ Ref<Texture2D> EditorFontPreviewPlugin::generate(const RES &p_from, const Size2
}
EditorFontPreviewPlugin::EditorFontPreviewPlugin() {
-
viewport = RS::get_singleton()->viewport_create();
RS::get_singleton()->viewport_set_update_mode(viewport, RS::VIEWPORT_UPDATE_DISABLED);
RS::get_singleton()->viewport_set_size(viewport, 128, 128);
@@ -905,7 +881,6 @@ EditorFontPreviewPlugin::EditorFontPreviewPlugin() {
}
EditorFontPreviewPlugin::~EditorFontPreviewPlugin() {
-
RS::get_singleton()->free(canvas_item);
RS::get_singleton()->free(canvas);
RS::get_singleton()->free(viewport);
diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h
index 840fa2410a..8a9d6a93fb 100644
--- a/editor/plugins/editor_preview_plugins.h
+++ b/editor/plugins/editor_preview_plugins.h
@@ -69,7 +69,6 @@ public:
};
class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator {
-
public:
virtual bool handles(const String &p_type) const;
virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const;
@@ -79,7 +78,6 @@ public:
};
class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator {
-
GDCLASS(EditorMaterialPreviewPlugin, EditorResourcePreviewGenerator);
RID scenario;
@@ -125,7 +123,6 @@ public:
};
class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator {
-
GDCLASS(EditorMeshPreviewPlugin, EditorResourcePreviewGenerator);
RID scenario;
@@ -153,7 +150,6 @@ public:
};
class EditorFontPreviewPlugin : public EditorResourcePreviewGenerator {
-
GDCLASS(EditorFontPreviewPlugin, EditorResourcePreviewGenerator);
RID viewport;
diff --git a/editor/plugins/gi_probe_editor_plugin.cpp b/editor/plugins/gi_probe_editor_plugin.cpp
index 6a171c4703..94f771e643 100644
--- a/editor/plugins/gi_probe_editor_plugin.cpp
+++ b/editor/plugins/gi_probe_editor_plugin.cpp
@@ -31,7 +31,6 @@
#include "gi_probe_editor_plugin.h"
void GIProbeEditorPlugin::_bake() {
-
if (gi_probe) {
if (gi_probe->get_probe_data().is_null()) {
String path = get_tree()->get_edited_scene_root()->get_filename();
@@ -50,21 +49,19 @@ void GIProbeEditorPlugin::_bake() {
}
void GIProbeEditorPlugin::edit(Object *p_object) {
-
GIProbe *s = Object::cast_to<GIProbe>(p_object);
- if (!s)
+ if (!s) {
return;
+ }
gi_probe = s;
}
bool GIProbeEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("GIProbe");
}
void GIProbeEditorPlugin::_notification(int p_what) {
-
if (p_what == NOTIFICATION_PROCESS) {
if (!gi_probe) {
return;
@@ -102,12 +99,10 @@ void GIProbeEditorPlugin::_notification(int p_what) {
}
void GIProbeEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
bake_hb->show();
set_process(true);
} else {
-
bake_hb->hide();
set_process(false);
}
@@ -116,14 +111,12 @@ void GIProbeEditorPlugin::make_visible(bool p_visible) {
EditorProgress *GIProbeEditorPlugin::tmp_progress = nullptr;
void GIProbeEditorPlugin::bake_func_begin(int p_steps) {
-
ERR_FAIL_COND(tmp_progress != nullptr);
tmp_progress = memnew(EditorProgress("bake_gi", TTR("Bake GI Probe"), p_steps));
}
void GIProbeEditorPlugin::bake_func_step(int p_step, const String &p_description) {
-
ERR_FAIL_COND(tmp_progress == nullptr);
tmp_progress->step(p_description, p_step, false);
}
@@ -147,7 +140,6 @@ void GIProbeEditorPlugin::_bind_methods() {
}
GIProbeEditorPlugin::GIProbeEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
bake_hb = memnew(HBoxContainer);
bake_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
diff --git a/editor/plugins/gi_probe_editor_plugin.h b/editor/plugins/gi_probe_editor_plugin.h
index 2068ebaaa8..508c3d825b 100644
--- a/editor/plugins/gi_probe_editor_plugin.h
+++ b/editor/plugins/gi_probe_editor_plugin.h
@@ -37,7 +37,6 @@
#include "scene/resources/material.h"
class GIProbeEditorPlugin : public EditorPlugin {
-
GDCLASS(GIProbeEditorPlugin, EditorPlugin);
GIProbe *gi_probe;
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.cpp b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
index 5c35285c22..01420dac3e 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.cpp
@@ -37,54 +37,45 @@
#include "scene/resources/particles_material.h"
void GPUParticles2DEditorPlugin::edit(Object *p_object) {
-
particles = Object::cast_to<GPUParticles2D>(p_object);
}
bool GPUParticles2DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("GPUParticles2D");
}
void GPUParticles2DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
-
toolbar->show();
} else {
-
toolbar->hide();
}
}
void GPUParticles2DEditorPlugin::_file_selected(const String &p_file) {
-
source_emission_file = p_file;
emission_mask->popup_centered();
}
void GPUParticles2DEditorPlugin::_menu_callback(int p_idx) {
-
switch (p_idx) {
case MENU_GENERATE_VISIBILITY_RECT: {
float gen_time = particles->get_lifetime();
- if (gen_time < 1.0)
+ if (gen_time < 1.0) {
generate_seconds->set_value(1.0);
- else
+ } else {
generate_seconds->set_value(trunc(gen_time) + 1.0);
+ }
generate_visibility_rect->popup_centered();
} break;
case MENU_LOAD_EMISSION_MASK: {
-
file->popup_centered_ratio();
} break;
case MENU_CLEAR_EMISSION_MASK: {
-
emission_mask->popup_centered();
} break;
case MENU_OPTION_CONVERT_TO_CPU_PARTICLES: {
-
CPUParticles2D *cpu_particles = memnew(CPUParticles2D);
cpu_particles->convert_from_particles(particles);
cpu_particles->set_name(particles->get_name());
@@ -103,14 +94,12 @@ void GPUParticles2DEditorPlugin::_menu_callback(int p_idx) {
} break;
case MENU_RESTART: {
-
particles->restart();
}
}
}
void GPUParticles2DEditorPlugin::_generate_visibility_rect() {
-
float time = generate_seconds->get_value();
float running = 0.0;
@@ -125,16 +114,16 @@ void GPUParticles2DEditorPlugin::_generate_visibility_rect() {
Rect2 rect;
while (running < time) {
-
uint64_t ticks = OS::get_singleton()->get_ticks_usec();
ep.step("Generating...", int(running), true);
OS::get_singleton()->delay_usec(1000);
Rect2 capture = particles->capture_rect();
- if (rect == Rect2())
+ if (rect == Rect2()) {
rect = capture;
- else
+ } else {
rect = rect.merge(capture);
+ }
running += (OS::get_singleton()->get_ticks_usec() - ticks) / 1000000.0;
}
@@ -150,7 +139,6 @@ void GPUParticles2DEditorPlugin::_generate_visibility_rect() {
}
void GPUParticles2DEditorPlugin::_generate_emission_mask() {
-
Ref<ParticlesMaterial> pm = particles->get_process_material();
if (!pm.is_valid()) {
EditorNode::get_singleton()->show_warning(TTR("Can only set point into a ParticlesMaterial process material"));
@@ -196,13 +184,10 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() {
for (int i = 0; i < s.width; i++) {
for (int j = 0; j < s.height; j++) {
-
uint8_t a = r[(j * s.width + i) * 4 + 3];
if (a > 128) {
-
if (emode == EMISSION_MODE_SOLID) {
-
if (capture_colors) {
valid_colors.write[vpc * 4 + 0] = r[(j * s.width + i) * 4 + 0];
valid_colors.write[vpc * 4 + 1] = r[(j * s.width + i) * 4 + 1];
@@ -212,19 +197,18 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() {
valid_positions.write[vpc++] = Point2(i, j);
} else {
-
bool on_border = false;
for (int x = i - 1; x <= i + 1; x++) {
for (int y = j - 1; y <= j + 1; y++) {
-
if (x < 0 || y < 0 || x >= s.width || y >= s.height || r[(y * s.width + x) * 4 + 3] <= 128) {
on_border = true;
break;
}
}
- if (on_border)
+ if (on_border) {
break;
+ }
}
if (on_border) {
@@ -234,9 +218,9 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() {
Vector2 normal;
for (int x = i - 2; x <= i + 2; x++) {
for (int y = j - 2; y <= j + 2; y++) {
-
- if (x == i && y == j)
+ if (x == i && y == j) {
continue;
+ }
if (x < 0 || y < 0 || x >= s.width || y >= s.height || r[(y * s.width + x) * 4 + 3] <= 128) {
normal += Vector2(x - i, y - j).normalized();
@@ -281,7 +265,6 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() {
uint8_t *tw = texdata.ptrw();
float *twf = (float *)tw;
for (int i = 0; i < vpc; i++) {
-
twf[i * 2 + 0] = valid_positions[i].x;
twf[i * 2 + 1] = valid_positions[i].y;
}
@@ -298,14 +281,12 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() {
pm->set_emission_point_count(vpc);
if (capture_colors) {
-
Vector<uint8_t> colordata;
colordata.resize(w * h * 4); //use RG texture
{
uint8_t *tw = colordata.ptrw();
for (int i = 0; i < vpc * 4; i++) {
-
tw[i] = valid_colors[i];
}
}
@@ -346,9 +327,7 @@ void GPUParticles2DEditorPlugin::_generate_emission_mask() {
}
void GPUParticles2DEditorPlugin::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
menu->get_popup()->connect("id_pressed", callable_mp(this, &GPUParticles2DEditorPlugin::_menu_callback));
menu->set_icon(menu->get_theme_icon("GPUParticles2D", "EditorIcons"));
file->connect("file_selected", callable_mp(this, &GPUParticles2DEditorPlugin::_file_selected));
@@ -359,7 +338,6 @@ void GPUParticles2DEditorPlugin::_bind_methods() {
}
GPUParticles2DEditorPlugin::GPUParticles2DEditorPlugin(EditorNode *p_node) {
-
particles = nullptr;
editor = p_node;
undo_redo = editor->get_undo_redo();
diff --git a/editor/plugins/gpu_particles_2d_editor_plugin.h b/editor/plugins/gpu_particles_2d_editor_plugin.h
index 008d04a211..c76cecb3a2 100644
--- a/editor/plugins/gpu_particles_2d_editor_plugin.h
+++ b/editor/plugins/gpu_particles_2d_editor_plugin.h
@@ -39,7 +39,6 @@
#include "scene/gui/file_dialog.h"
class GPUParticles2DEditorPlugin : public EditorPlugin {
-
GDCLASS(GPUParticles2DEditorPlugin, EditorPlugin);
enum {
diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.cpp b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
index 7f80acc176..fa507dd3d7 100644
--- a/editor/plugins/gpu_particles_3d_editor_plugin.cpp
+++ b/editor/plugins/gpu_particles_3d_editor_plugin.cpp
@@ -36,25 +36,22 @@
#include "scene/resources/particles_material.h"
bool GPUParticles3DEditorBase::_generate(Vector<Vector3> &points, Vector<Vector3> &normals) {
-
bool use_normals = emission_fill->get_selected() == 1;
if (emission_fill->get_selected() < 2) {
-
float area_accum = 0;
Map<float, int> triangle_area_map;
for (int i = 0; i < geometry.size(); i++) {
-
float area = geometry[i].get_area();
- if (area < CMP_EPSILON)
+ if (area < CMP_EPSILON) {
continue;
+ }
triangle_area_map[area_accum] = i;
area_accum += area;
}
if (!triangle_area_map.size() || area_accum == 0) {
-
EditorNode::get_singleton()->show_warning(TTR("The geometry's faces don't contain any area."));
return false;
}
@@ -62,7 +59,6 @@ bool GPUParticles3DEditorBase::_generate(Vector<Vector3> &points, Vector<Vector3
int emissor_count = emission_amount->get_value();
for (int i = 0; i < emissor_count; i++) {
-
float areapos = Math::random(0.0f, area_accum);
Map<float, int>::Element *E = triangle_area_map.find_closest(areapos);
@@ -84,11 +80,9 @@ bool GPUParticles3DEditorBase::_generate(Vector<Vector3> &points, Vector<Vector3
}
}
} else {
-
int gcount = geometry.size();
if (gcount == 0) {
-
EditorNode::get_singleton()->show_warning(TTR("The geometry doesn't contain any faces."));
return false;
}
@@ -98,24 +92,21 @@ bool GPUParticles3DEditorBase::_generate(Vector<Vector3> &points, Vector<Vector3
AABB aabb;
for (int i = 0; i < gcount; i++) {
-
for (int j = 0; j < 3; j++) {
-
- if (i == 0 && j == 0)
+ if (i == 0 && j == 0) {
aabb.position = r[i].vertex[j];
- else
+ } else {
aabb.expand_to(r[i].vertex[j]);
+ }
}
}
int emissor_count = emission_amount->get_value();
for (int i = 0; i < emissor_count; i++) {
-
int attempts = 5;
for (int j = 0; j < attempts; j++) {
-
Vector3 dir;
dir[Math::rand() % 3] = 1.0;
Vector3 ofs = (Vector3(1, 1, 1) - dir) * Vector3(Math::randf(), Math::randf(), Math::randf()) * aabb.size + aabb.position;
@@ -129,24 +120,25 @@ bool GPUParticles3DEditorBase::_generate(Vector<Vector3> &points, Vector<Vector3
float max = -1e7, min = 1e7;
for (int k = 0; k < gcount; k++) {
-
const Face3 &f3 = r[k];
Vector3 res;
if (f3.intersects_segment(ofs, ofsv, &res)) {
-
res -= ofs;
float d = dir.dot(res);
- if (d < min)
+ if (d < min) {
min = d;
- if (d > max)
+ }
+ if (d > max) {
max = d;
+ }
}
}
- if (max < min)
+ if (max < min) {
continue; //lost attempt
+ }
float val = min + (max - min) * Math::randf();
@@ -162,20 +154,18 @@ bool GPUParticles3DEditorBase::_generate(Vector<Vector3> &points, Vector<Vector3
}
void GPUParticles3DEditorBase::_node_selected(const NodePath &p_path) {
-
Node *sel = get_node(p_path);
- if (!sel)
+ if (!sel) {
return;
+ }
if (!sel->is_class("Node3D")) {
-
EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't inherit from Node3D."), sel->get_name()));
return;
}
VisualInstance3D *vi = Object::cast_to<VisualInstance3D>(sel);
if (!vi) {
-
EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't contain geometry."), sel->get_name()));
return;
}
@@ -183,7 +173,6 @@ void GPUParticles3DEditorBase::_node_selected(const NodePath &p_path) {
geometry = vi->get_faces(VisualInstance3D::FACES_SOLID);
if (geometry.size() == 0) {
-
EditorNode::get_singleton()->show_warning(vformat(TTR("\"%s\" doesn't contain face geometry."), sel->get_name()));
return;
}
@@ -206,7 +195,6 @@ void GPUParticles3DEditorBase::_bind_methods() {
}
GPUParticles3DEditorBase::GPUParticles3DEditorBase() {
-
emission_dialog = memnew(ConfirmationDialog);
emission_dialog->set_title(TTR("Create Emitter"));
add_child(emission_dialog);
@@ -234,7 +222,6 @@ GPUParticles3DEditorBase::GPUParticles3DEditorBase() {
}
void GPUParticles3DEditor::_node_removed(Node *p_node) {
-
if (p_node == node) {
node = nullptr;
hide();
@@ -242,7 +229,6 @@ void GPUParticles3DEditor::_node_removed(Node *p_node) {
}
void GPUParticles3DEditor::_notification(int p_notification) {
-
if (p_notification == NOTIFICATION_ENTER_TREE) {
options->set_icon(options->get_popup()->get_theme_icon("GPUParticles3D", "EditorIcons"));
get_tree()->connect("node_removed", callable_mp(this, &GPUParticles3DEditor::_node_removed));
@@ -250,16 +236,15 @@ void GPUParticles3DEditor::_notification(int p_notification) {
}
void GPUParticles3DEditor::_menu_option(int p_option) {
-
switch (p_option) {
-
case MENU_OPTION_GENERATE_AABB: {
float gen_time = node->get_lifetime();
- if (gen_time < 1.0)
+ if (gen_time < 1.0) {
generate_seconds->set_value(1.0);
- else
+ } else {
generate_seconds->set_value(trunc(gen_time) + 1.0);
+ }
generate_aabb->popup_centered();
} break;
case MENU_OPTION_CREATE_EMISSION_VOLUME_FROM_NODE: {
@@ -273,7 +258,6 @@ void GPUParticles3DEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CONVERT_TO_CPU_PARTICLES: {
-
CPUParticles3D *cpu_particles = memnew(CPUParticles3D);
cpu_particles->convert_from_particles(node);
cpu_particles->set_name(node->get_name());
@@ -291,7 +275,6 @@ void GPUParticles3DEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_RESTART: {
-
node->restart();
} break;
@@ -299,7 +282,6 @@ void GPUParticles3DEditor::_menu_option(int p_option) {
}
void GPUParticles3DEditor::_generate_aabb() {
-
float time = generate_seconds->get_value();
float running = 0.0;
@@ -315,16 +297,16 @@ void GPUParticles3DEditor::_generate_aabb() {
AABB rect;
while (running < time) {
-
uint64_t ticks = OS::get_singleton()->get_ticks_usec();
ep.step("Generating...", int(running), true);
OS::get_singleton()->delay_usec(1000);
AABB capture = node->capture_aabb();
- if (rect == AABB())
+ if (rect == AABB()) {
rect = capture;
- else
+ } else {
rect.merge_with(capture);
+ }
running += (OS::get_singleton()->get_ticks_usec() - ticks) / 1000000.0;
}
@@ -341,13 +323,11 @@ void GPUParticles3DEditor::_generate_aabb() {
}
void GPUParticles3DEditor::edit(GPUParticles3D *p_particles) {
-
base_node = p_particles;
node = p_particles;
}
void GPUParticles3DEditor::_generate_emission_points() {
-
/// hacer codigo aca
Vector<Vector3> points;
Vector<Vector3> normals;
@@ -385,7 +365,6 @@ void GPUParticles3DEditor::_generate_emission_points() {
ERR_FAIL_COND(material.is_null());
if (normals.size() > 0) {
-
material->set_emission_shape(ParticlesMaterial::EMISSION_SHAPE_DIRECTED_POINTS);
material->set_emission_point_count(point_count);
material->set_emission_point_texture(tex);
@@ -412,7 +391,6 @@ void GPUParticles3DEditor::_generate_emission_points() {
material->set_emission_normal_texture(tex2);
} else {
-
material->set_emission_shape(ParticlesMaterial::EMISSION_SHAPE_POINTS);
material->set_emission_point_count(point_count);
material->set_emission_point_texture(tex);
@@ -423,7 +401,6 @@ void GPUParticles3DEditor::_bind_methods() {
}
GPUParticles3DEditor::GPUParticles3DEditor() {
-
node = nullptr;
particles_editor_hb = memnew(HBoxContainer);
Node3DEditor::get_singleton()->add_control_to_menu_panel(particles_editor_hb);
@@ -456,17 +433,14 @@ GPUParticles3DEditor::GPUParticles3DEditor() {
}
void GPUParticles3DEditorPlugin::edit(Object *p_object) {
-
particles_editor->edit(Object::cast_to<GPUParticles3D>(p_object));
}
bool GPUParticles3DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("GPUParticles3D");
}
void GPUParticles3DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
particles_editor->show();
particles_editor->particles_editor_hb->show();
@@ -478,7 +452,6 @@ void GPUParticles3DEditorPlugin::make_visible(bool p_visible) {
}
GPUParticles3DEditorPlugin::GPUParticles3DEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
particles_editor = memnew(GPUParticles3DEditor);
editor->get_viewport()->add_child(particles_editor);
diff --git a/editor/plugins/gpu_particles_3d_editor_plugin.h b/editor/plugins/gpu_particles_3d_editor_plugin.h
index cf1cff32c0..7838a63436 100644
--- a/editor/plugins/gpu_particles_3d_editor_plugin.h
+++ b/editor/plugins/gpu_particles_3d_editor_plugin.h
@@ -37,7 +37,6 @@
#include "scene/gui/spin_box.h"
class GPUParticles3DEditorBase : public Control {
-
GDCLASS(GPUParticles3DEditorBase, Control);
protected:
@@ -65,7 +64,6 @@ public:
};
class GPUParticles3DEditor : public GPUParticles3DEditorBase {
-
GDCLASS(GPUParticles3DEditor, GPUParticles3DEditorBase);
ConfirmationDialog *generate_aabb;
@@ -101,7 +99,6 @@ public:
};
class GPUParticles3DEditorPlugin : public EditorPlugin {
-
GDCLASS(GPUParticles3DEditorPlugin, EditorPlugin);
GPUParticles3DEditor *particles_editor;
diff --git a/editor/plugins/gradient_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp
index 67de610ae7..13b5c8cef5 100644
--- a/editor/plugins/gradient_editor_plugin.cpp
+++ b/editor/plugins/gradient_editor_plugin.cpp
@@ -37,10 +37,11 @@
Size2 GradientEditor::get_minimum_size() const {
return Size2(0, 60) * EDSCALE;
}
-void GradientEditor::_gradient_changed() {
- if (editing)
+void GradientEditor::_gradient_changed() {
+ if (editing) {
return;
+ }
editing = true;
Vector<Gradient::Point> points = gradient->get_points();
@@ -49,7 +50,6 @@ void GradientEditor::_gradient_changed() {
}
void GradientEditor::_ramp_changed() {
-
editing = true;
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(TTR("Gradient Edited"));
@@ -78,12 +78,10 @@ GradientEditor::GradientEditor() {
///////////////////////
bool EditorInspectorPluginGradient::can_handle(Object *p_object) {
-
return Object::cast_to<Gradient>(p_object) != nullptr;
}
void EditorInspectorPluginGradient::parse_begin(Object *p_object) {
-
Gradient *gradient = Object::cast_to<Gradient>(p_object);
Ref<Gradient> g(gradient);
@@ -93,7 +91,6 @@ void EditorInspectorPluginGradient::parse_begin(Object *p_object) {
}
GradientEditorPlugin::GradientEditorPlugin(EditorNode *p_node) {
-
Ref<EditorInspectorPluginGradient> plugin;
plugin.instance();
add_inspector_plugin(plugin);
diff --git a/editor/plugins/gradient_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h
index 9ebd9610e5..0641d54d5c 100644
--- a/editor/plugins/gradient_editor_plugin.h
+++ b/editor/plugins/gradient_editor_plugin.h
@@ -62,7 +62,6 @@ public:
};
class GradientEditorPlugin : public EditorPlugin {
-
GDCLASS(GradientEditorPlugin, EditorPlugin);
public:
diff --git a/editor/plugins/item_list_editor_plugin.cpp b/editor/plugins/item_list_editor_plugin.cpp
index 1dbc78804b..7402baad57 100644
--- a/editor/plugins/item_list_editor_plugin.cpp
+++ b/editor/plugins/item_list_editor_plugin.cpp
@@ -34,16 +34,15 @@
#include "editor/editor_scale.h"
bool ItemListPlugin::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
int idx = name.get_slice("/", 0).to_int();
String what = name.get_slice("/", 1);
- if (what == "text")
+ if (what == "text") {
set_item_text(idx, p_value);
- else if (what == "icon")
+ } else if (what == "icon") {
set_item_icon(idx, p_value);
- else if (what == "checkable") {
+ } else if (what == "checkable") {
// This keeps compatibility to/from versions where this property was a boolean, before radio buttons
switch ((int)p_value) {
case 0:
@@ -54,54 +53,54 @@ bool ItemListPlugin::_set(const StringName &p_name, const Variant &p_value) {
set_item_radio_checkable(idx, true);
break;
}
- } else if (what == "checked")
+ } else if (what == "checked") {
set_item_checked(idx, p_value);
- else if (what == "id")
+ } else if (what == "id") {
set_item_id(idx, p_value);
- else if (what == "enabled")
+ } else if (what == "enabled") {
set_item_enabled(idx, p_value);
- else if (what == "separator")
+ } else if (what == "separator") {
set_item_separator(idx, p_value);
- else
+ } else {
return false;
+ }
return true;
}
bool ItemListPlugin::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
int idx = name.get_slice("/", 0).to_int();
String what = name.get_slice("/", 1);
- if (what == "text")
+ if (what == "text") {
r_ret = get_item_text(idx);
- else if (what == "icon")
+ } else if (what == "icon") {
r_ret = get_item_icon(idx);
- else if (what == "checkable") {
+ } else if (what == "checkable") {
// This keeps compatibility to/from versions where this property was a boolean, before radio buttons
if (!is_item_checkable(idx)) {
r_ret = 0;
} else {
r_ret = is_item_radio_checkable(idx) ? 2 : 1;
}
- } else if (what == "checked")
+ } else if (what == "checked") {
r_ret = is_item_checked(idx);
- else if (what == "id")
+ } else if (what == "id") {
r_ret = get_item_id(idx);
- else if (what == "enabled")
+ } else if (what == "enabled") {
r_ret = is_item_enabled(idx);
- else if (what == "separator")
+ } else if (what == "separator") {
r_ret = is_item_separator(idx);
- else
+ } else {
return false;
+ }
return true;
}
-void ItemListPlugin::_get_property_list(List<PropertyInfo> *p_list) const {
+void ItemListPlugin::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < get_item_count(); i++) {
-
String base = itos(i) + "/";
p_list->push_back(PropertyInfo(Variant::STRING, base + "text"));
@@ -114,14 +113,17 @@ void ItemListPlugin::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::BOOL, base + "checked"));
}
- if (flags & FLAG_ID)
+ if (flags & FLAG_ID) {
p_list->push_back(PropertyInfo(Variant::INT, base + "id", PROPERTY_HINT_RANGE, "-1,4096"));
+ }
- if (flags & FLAG_ENABLE)
+ if (flags & FLAG_ENABLE) {
p_list->push_back(PropertyInfo(Variant::BOOL, base + "enabled"));
+ }
- if (flags & FLAG_SEPARATOR)
+ if (flags & FLAG_SEPARATOR) {
p_list->push_back(PropertyInfo(Variant::BOOL, base + "separator"));
+ }
}
}
@@ -130,120 +132,100 @@ void ItemListPlugin::_get_property_list(List<PropertyInfo> *p_list) const {
///////////////////////////////////////////////////////////////
void ItemListOptionButtonPlugin::set_object(Object *p_object) {
-
ob = Object::cast_to<OptionButton>(p_object);
}
bool ItemListOptionButtonPlugin::handles(Object *p_object) const {
-
return p_object->is_class("OptionButton");
}
int ItemListOptionButtonPlugin::get_flags() const {
-
return FLAG_ICON | FLAG_ID | FLAG_ENABLE;
}
void ItemListOptionButtonPlugin::add_item() {
-
ob->add_item(vformat(TTR("Item %d"), ob->get_item_count()));
_change_notify();
}
int ItemListOptionButtonPlugin::get_item_count() const {
-
return ob->get_item_count();
}
void ItemListOptionButtonPlugin::erase(int p_idx) {
-
ob->remove_item(p_idx);
_change_notify();
}
ItemListOptionButtonPlugin::ItemListOptionButtonPlugin() {
-
ob = nullptr;
}
///////////////////////////////////////////////////////////////
void ItemListPopupMenuPlugin::set_object(Object *p_object) {
-
- if (p_object->is_class("MenuButton"))
+ if (p_object->is_class("MenuButton")) {
pp = Object::cast_to<MenuButton>(p_object)->get_popup();
- else
+ } else {
pp = Object::cast_to<PopupMenu>(p_object);
+ }
}
bool ItemListPopupMenuPlugin::handles(Object *p_object) const {
-
return p_object->is_class("PopupMenu") || p_object->is_class("MenuButton");
}
int ItemListPopupMenuPlugin::get_flags() const {
-
return FLAG_ICON | FLAG_CHECKABLE | FLAG_ID | FLAG_ENABLE | FLAG_SEPARATOR;
}
void ItemListPopupMenuPlugin::add_item() {
-
pp->add_item(vformat(TTR("Item %d"), pp->get_item_count()));
_change_notify();
}
int ItemListPopupMenuPlugin::get_item_count() const {
-
return pp->get_item_count();
}
void ItemListPopupMenuPlugin::erase(int p_idx) {
-
pp->remove_item(p_idx);
_change_notify();
}
ItemListPopupMenuPlugin::ItemListPopupMenuPlugin() {
-
pp = nullptr;
}
///////////////////////////////////////////////////////////////
void ItemListItemListPlugin::set_object(Object *p_object) {
-
pp = Object::cast_to<ItemList>(p_object);
}
bool ItemListItemListPlugin::handles(Object *p_object) const {
-
return p_object->is_class("ItemList");
}
int ItemListItemListPlugin::get_flags() const {
-
return FLAG_ICON | FLAG_ENABLE;
}
void ItemListItemListPlugin::add_item() {
-
pp->add_item(vformat(TTR("Item %d"), pp->get_item_count()));
_change_notify();
}
int ItemListItemListPlugin::get_item_count() const {
-
return pp->get_item_count();
}
void ItemListItemListPlugin::erase(int p_idx) {
-
pp->remove_item(p_idx);
_change_notify();
}
ItemListItemListPlugin::ItemListItemListPlugin() {
-
pp = nullptr;
}
@@ -252,7 +234,6 @@ ItemListItemListPlugin::ItemListItemListPlugin() {
///////////////////////////////////////////////////////////////
void ItemListEditor::_node_removed(Node *p_node) {
-
if (p_node == item_list) {
item_list = nullptr;
hide();
@@ -261,34 +242,32 @@ void ItemListEditor::_node_removed(Node *p_node) {
}
void ItemListEditor::_notification(int p_notification) {
-
if (p_notification == NOTIFICATION_ENTER_TREE || p_notification == NOTIFICATION_THEME_CHANGED) {
-
add_button->set_icon(get_theme_icon("Add", "EditorIcons"));
del_button->set_icon(get_theme_icon("Remove", "EditorIcons"));
} else if (p_notification == NOTIFICATION_READY) {
-
get_tree()->connect("node_removed", callable_mp(this, &ItemListEditor::_node_removed));
}
}
void ItemListEditor::_add_pressed() {
-
- if (selected_idx == -1)
+ if (selected_idx == -1) {
return;
+ }
item_plugins[selected_idx]->add_item();
}
void ItemListEditor::_delete_pressed() {
-
- if (selected_idx == -1)
+ if (selected_idx == -1) {
return;
+ }
String current_selected = (String)property_editor->get_selected_path();
- if (current_selected == "")
+ if (current_selected == "") {
return;
+ }
// FIXME: Currently relying on selecting a *property* to derive what item to delete
// e.g. you select "1/enabled" to delete item 1.
@@ -301,12 +280,10 @@ void ItemListEditor::_delete_pressed() {
}
void ItemListEditor::_edit_items() {
-
dialog->popup_centered_clamped(Vector2(425, 1200) * EDSCALE, 0.8);
}
void ItemListEditor::edit(Node *p_item_list) {
-
item_list = p_item_list;
if (!item_list) {
@@ -317,7 +294,6 @@ void ItemListEditor::edit(Node *p_item_list) {
for (int i = 0; i < item_plugins.size(); i++) {
if (item_plugins[i]->handles(p_item_list)) {
-
item_plugins[i]->set_object(p_item_list);
property_editor->edit(item_plugins[i]);
@@ -333,7 +309,6 @@ void ItemListEditor::edit(Node *p_item_list) {
}
bool ItemListEditor::handles(Object *p_object) const {
-
for (int i = 0; i < item_plugins.size(); i++) {
if (item_plugins[i]->handles(p_object)) {
return true;
@@ -347,7 +322,6 @@ void ItemListEditor::_bind_methods() {
}
ItemListEditor::ItemListEditor() {
-
selected_idx = -1;
item_list = nullptr;
@@ -386,34 +360,29 @@ ItemListEditor::ItemListEditor() {
}
ItemListEditor::~ItemListEditor() {
-
- for (int i = 0; i < item_plugins.size(); i++)
+ for (int i = 0; i < item_plugins.size(); i++) {
memdelete(item_plugins[i]);
+ }
}
void ItemListEditorPlugin::edit(Object *p_object) {
-
item_list_editor->edit(Object::cast_to<Node>(p_object));
}
bool ItemListEditorPlugin::handles(Object *p_object) const {
-
return item_list_editor->handles(p_object);
}
void ItemListEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
item_list_editor->show();
} else {
-
item_list_editor->hide();
item_list_editor->edit(nullptr);
}
}
ItemListEditorPlugin::ItemListEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
item_list_editor = memnew(ItemListEditor);
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(item_list_editor);
diff --git a/editor/plugins/item_list_editor_plugin.h b/editor/plugins/item_list_editor_plugin.h
index 8dcf938139..61dd617e3b 100644
--- a/editor/plugins/item_list_editor_plugin.h
+++ b/editor/plugins/item_list_editor_plugin.h
@@ -40,7 +40,6 @@
#include "scene/gui/popup_menu.h"
class ItemListPlugin : public Object {
-
GDCLASS(ItemListPlugin, Object);
protected:
@@ -96,7 +95,6 @@ public:
///////////////////////////////////////////////////////////////
class ItemListOptionButtonPlugin : public ItemListPlugin {
-
GDCLASS(ItemListOptionButtonPlugin, ItemListPlugin);
OptionButton *ob;
@@ -126,7 +124,6 @@ public:
};
class ItemListPopupMenuPlugin : public ItemListPlugin {
-
GDCLASS(ItemListPopupMenuPlugin, ItemListPlugin);
PopupMenu *pp;
@@ -169,7 +166,6 @@ public:
///////////////////////////////////////////////////////////////
class ItemListItemListPlugin : public ItemListPlugin {
-
GDCLASS(ItemListItemListPlugin, ItemListPlugin);
ItemList *pp;
@@ -198,7 +194,6 @@ public:
///////////////////////////////////////////////////////////////
class ItemListEditor : public HBoxContainer {
-
GDCLASS(ItemListEditor, HBoxContainer);
Node *item_list;
@@ -235,7 +230,6 @@ public:
};
class ItemListEditorPlugin : public EditorPlugin {
-
GDCLASS(ItemListEditorPlugin, EditorPlugin);
ItemListEditor *item_list_editor;
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp
index f8550a884b..e422140efa 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.cpp
+++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp
@@ -31,10 +31,8 @@
#include "light_occluder_2d_editor_plugin.h"
Ref<OccluderPolygon2D> LightOccluder2DEditor::_ensure_occluder() const {
-
Ref<OccluderPolygon2D> occluder = node->get_occluder_polygon();
if (!occluder.is_valid()) {
-
occluder = Ref<OccluderPolygon2D>(memnew(OccluderPolygon2D));
node->set_occluder_polygon(occluder);
}
@@ -42,64 +40,59 @@ Ref<OccluderPolygon2D> LightOccluder2DEditor::_ensure_occluder() const {
}
Node2D *LightOccluder2DEditor::_get_node() const {
-
return node;
}
void LightOccluder2DEditor::_set_node(Node *p_polygon) {
-
node = Object::cast_to<LightOccluder2D>(p_polygon);
}
bool LightOccluder2DEditor::_is_line() const {
-
Ref<OccluderPolygon2D> occluder = node->get_occluder_polygon();
- if (occluder.is_valid())
+ if (occluder.is_valid()) {
return !occluder->is_closed();
- else
+ } else {
return false;
+ }
}
int LightOccluder2DEditor::_get_polygon_count() const {
-
Ref<OccluderPolygon2D> occluder = node->get_occluder_polygon();
- if (occluder.is_valid())
+ if (occluder.is_valid()) {
return occluder->get_polygon().size();
- else
+ } else {
return 0;
+ }
}
Variant LightOccluder2DEditor::_get_polygon(int p_idx) const {
-
Ref<OccluderPolygon2D> occluder = node->get_occluder_polygon();
- if (occluder.is_valid())
+ if (occluder.is_valid()) {
return occluder->get_polygon();
- else
+ } else {
return Variant(Vector<Vector2>());
+ }
}
void LightOccluder2DEditor::_set_polygon(int p_idx, const Variant &p_polygon) const {
-
Ref<OccluderPolygon2D> occluder = _ensure_occluder();
occluder->set_polygon(p_polygon);
}
void LightOccluder2DEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) {
-
Ref<OccluderPolygon2D> occluder = _ensure_occluder();
undo_redo->add_do_method(occluder.ptr(), "set_polygon", p_polygon);
undo_redo->add_undo_method(occluder.ptr(), "set_polygon", p_previous);
}
bool LightOccluder2DEditor::_has_resource() const {
-
return node && node->get_occluder_polygon().is_valid();
}
void LightOccluder2DEditor::_create_resource() {
-
- if (!node)
+ if (!node) {
return;
+ }
undo_redo->create_action(TTR("Create Occluder Polygon"));
undo_redo->add_do_method(node, "set_occluder_polygon", Ref<OccluderPolygon2D>(memnew(OccluderPolygon2D)));
@@ -111,7 +104,6 @@ void LightOccluder2DEditor::_create_resource() {
LightOccluder2DEditor::LightOccluder2DEditor(EditorNode *p_editor) :
AbstractPolygon2DEditor(p_editor) {
-
node = nullptr;
}
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h
index 74ae9e0889..11c9f2b2a4 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.h
+++ b/editor/plugins/light_occluder_2d_editor_plugin.h
@@ -35,7 +35,6 @@
#include "scene/2d/light_occluder_2d.h"
class LightOccluder2DEditor : public AbstractPolygon2DEditor {
-
GDCLASS(LightOccluder2DEditor, AbstractPolygon2DEditor);
LightOccluder2D *node;
@@ -61,7 +60,6 @@ public:
};
class LightOccluder2DEditorPlugin : public AbstractPolygon2DEditorPlugin {
-
GDCLASS(LightOccluder2DEditorPlugin, AbstractPolygon2DEditorPlugin);
public:
diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp
index 5b887390a6..77eeb19d26 100644
--- a/editor/plugins/line_2d_editor_plugin.cpp
+++ b/editor/plugins/line_2d_editor_plugin.cpp
@@ -31,32 +31,26 @@
#include "line_2d_editor_plugin.h"
Node2D *Line2DEditor::_get_node() const {
-
return node;
}
void Line2DEditor::_set_node(Node *p_line) {
-
node = Object::cast_to<Line2D>(p_line);
}
bool Line2DEditor::_is_line() const {
-
return true;
}
Variant Line2DEditor::_get_polygon(int p_idx) const {
-
return _get_node()->get("points");
}
void Line2DEditor::_set_polygon(int p_idx, const Variant &p_polygon) const {
-
_get_node()->set("points", p_polygon);
}
void Line2DEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) {
-
Node2D *node = _get_node();
undo_redo->add_do_method(node, "set_points", p_polygon);
undo_redo->add_undo_method(node, "set_points", p_previous);
diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h
index ef54dbc3f7..bf411a070a 100644
--- a/editor/plugins/line_2d_editor_plugin.h
+++ b/editor/plugins/line_2d_editor_plugin.h
@@ -35,7 +35,6 @@
#include "scene/2d/line_2d.h"
class Line2DEditor : public AbstractPolygon2DEditor {
-
GDCLASS(Line2DEditor, AbstractPolygon2DEditor);
Line2D *node;
@@ -54,7 +53,6 @@ public:
};
class Line2DEditorPlugin : public AbstractPolygon2DEditorPlugin {
-
GDCLASS(Line2DEditorPlugin, AbstractPolygon2DEditorPlugin);
public:
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index eb14495b9c..e49cfd51f7 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -36,9 +36,7 @@
#include "scene/resources/sky_material.h"
void MaterialEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_READY) {
-
//get_scene()->connect("node_removed",this,"_node_removed");
if (first_enter) {
@@ -59,7 +57,6 @@ void MaterialEditor::_notification(int p_what) {
}
if (p_what == NOTIFICATION_DRAW) {
-
Ref<Texture2D> checkerboard = get_theme_icon("Checkerboard", "EditorIcons");
Size2 size = get_size();
@@ -68,20 +65,17 @@ void MaterialEditor::_notification(int p_what) {
}
void MaterialEditor::edit(Ref<Material> p_material, const Ref<Environment> &p_env) {
-
material = p_material;
camera->set_environment(p_env);
if (!material.is_null()) {
sphere_instance->set_material_override(material);
box_instance->set_material_override(material);
} else {
-
hide();
}
}
void MaterialEditor::_button_pressed(Node *p_button) {
-
if (p_button == light_1_switch) {
light1->set_visible(!light_1_switch->is_pressed());
}
@@ -111,15 +105,14 @@ void MaterialEditor::_bind_methods() {
}
MaterialEditor::MaterialEditor() {
-
vc = memnew(SubViewportContainer);
vc->set_stretch(true);
add_child(vc);
vc->set_anchors_and_margins_preset(PRESET_WIDE);
viewport = memnew(SubViewport);
- Ref<World3D> world;
- world.instance();
- viewport->set_world(world); //use own world
+ Ref<World3D> world_3d;
+ world_3d.instance();
+ viewport->set_world_3d(world_3d); //use own world
vc->add_child(viewport);
viewport->set_disable_input(true);
viewport->set_transparent_background(true);
@@ -209,16 +202,15 @@ MaterialEditor::MaterialEditor() {
///////////////////////
bool EditorInspectorPluginMaterial::can_handle(Object *p_object) {
-
Material *material = Object::cast_to<Material>(p_object);
- if (!material)
+ if (!material) {
return false;
+ }
return material->get_shader_mode() == Shader::MODE_SPATIAL;
}
void EditorInspectorPluginMaterial::parse_begin(Object *p_object) {
-
Material *material = Object::cast_to<Material>(p_object);
if (!material) {
return;
@@ -240,23 +232,21 @@ EditorInspectorPluginMaterial::EditorInspectorPluginMaterial() {
}
MaterialEditorPlugin::MaterialEditorPlugin(EditorNode *p_node) {
-
Ref<EditorInspectorPluginMaterial> plugin;
plugin.instance();
add_inspector_plugin(plugin);
}
String StandardMaterial3DConversionPlugin::converts_to() const {
-
return "ShaderMaterial";
}
-bool StandardMaterial3DConversionPlugin::handles(const Ref<Resource> &p_resource) const {
+bool StandardMaterial3DConversionPlugin::handles(const Ref<Resource> &p_resource) const {
Ref<StandardMaterial3D> mat = p_resource;
return mat.is_valid();
}
-Ref<Resource> StandardMaterial3DConversionPlugin::convert(const Ref<Resource> &p_resource) const {
+Ref<Resource> StandardMaterial3DConversionPlugin::convert(const Ref<Resource> &p_resource) const {
Ref<StandardMaterial3D> mat = p_resource;
ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
@@ -276,7 +266,6 @@ Ref<Resource> StandardMaterial3DConversionPlugin::convert(const Ref<Resource> &p
RS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), &params);
for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) {
-
// Texture parameter has to be treated specially since StandardMaterial3D saved it
// as RID but ShaderMaterial needs Texture itself
Ref<Texture2D> texture = mat->get_texture_by_name(E->get().name);
@@ -293,16 +282,15 @@ Ref<Resource> StandardMaterial3DConversionPlugin::convert(const Ref<Resource> &p
}
String ParticlesMaterialConversionPlugin::converts_to() const {
-
return "ShaderMaterial";
}
-bool ParticlesMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
+bool ParticlesMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
Ref<ParticlesMaterial> mat = p_resource;
return mat.is_valid();
}
-Ref<Resource> ParticlesMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
+Ref<Resource> ParticlesMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
Ref<ParticlesMaterial> mat = p_resource;
ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
@@ -331,16 +319,15 @@ Ref<Resource> ParticlesMaterialConversionPlugin::convert(const Ref<Resource> &p_
}
String CanvasItemMaterialConversionPlugin::converts_to() const {
-
return "ShaderMaterial";
}
-bool CanvasItemMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
+bool CanvasItemMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
Ref<CanvasItemMaterial> mat = p_resource;
return mat.is_valid();
}
-Ref<Resource> CanvasItemMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
+Ref<Resource> CanvasItemMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
Ref<CanvasItemMaterial> mat = p_resource;
ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
@@ -369,16 +356,15 @@ Ref<Resource> CanvasItemMaterialConversionPlugin::convert(const Ref<Resource> &p
}
String ProceduralSkyMaterialConversionPlugin::converts_to() const {
-
return "ShaderMaterial";
}
-bool ProceduralSkyMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
+bool ProceduralSkyMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
Ref<ProceduralSkyMaterial> mat = p_resource;
return mat.is_valid();
}
-Ref<Resource> ProceduralSkyMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
+Ref<Resource> ProceduralSkyMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
Ref<ProceduralSkyMaterial> mat = p_resource;
ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
@@ -407,16 +393,15 @@ Ref<Resource> ProceduralSkyMaterialConversionPlugin::convert(const Ref<Resource>
}
String PanoramaSkyMaterialConversionPlugin::converts_to() const {
-
return "ShaderMaterial";
}
-bool PanoramaSkyMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
+bool PanoramaSkyMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
Ref<PanoramaSkyMaterial> mat = p_resource;
return mat.is_valid();
}
-Ref<Resource> PanoramaSkyMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
+Ref<Resource> PanoramaSkyMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
Ref<PanoramaSkyMaterial> mat = p_resource;
ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
@@ -445,16 +430,15 @@ Ref<Resource> PanoramaSkyMaterialConversionPlugin::convert(const Ref<Resource> &
}
String PhysicalSkyMaterialConversionPlugin::converts_to() const {
-
return "ShaderMaterial";
}
-bool PhysicalSkyMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
+bool PhysicalSkyMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
Ref<PhysicalSkyMaterial> mat = p_resource;
return mat.is_valid();
}
-Ref<Resource> PhysicalSkyMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
+Ref<Resource> PhysicalSkyMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) const {
Ref<PhysicalSkyMaterial> mat = p_resource;
ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h
index 50036e4f72..e03cb1b3ab 100644
--- a/editor/plugins/material_editor_plugin.h
+++ b/editor/plugins/material_editor_plugin.h
@@ -44,7 +44,6 @@
class SubViewportContainer;
class MaterialEditor : public Control {
-
GDCLASS(MaterialEditor, Control);
SubViewportContainer *vc;
@@ -91,7 +90,6 @@ public:
};
class MaterialEditorPlugin : public EditorPlugin {
-
GDCLASS(MaterialEditorPlugin, EditorPlugin);
public:
diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp
index 5e657c3b71..9d396467c3 100644
--- a/editor/plugins/mesh_editor_plugin.cpp
+++ b/editor/plugins/mesh_editor_plugin.cpp
@@ -33,15 +33,13 @@
#include "editor/editor_scale.h"
void MeshEditor::_gui_input(Ref<InputEvent> p_event) {
-
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
-
rot_x -= mm->get_relative().y * 0.01;
rot_y -= mm->get_relative().x * 0.01;
- if (rot_x < -Math_PI / 2)
+ if (rot_x < -Math_PI / 2) {
rot_x = -Math_PI / 2;
- else if (rot_x > Math_PI / 2) {
+ } else if (rot_x > Math_PI / 2) {
rot_x = Math_PI / 2;
}
_update_rotation();
@@ -49,9 +47,7 @@ void MeshEditor::_gui_input(Ref<InputEvent> p_event) {
}
void MeshEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_READY) {
-
//get_scene()->connect("node_removed",this,"_node_removed");
if (first_enter) {
@@ -67,7 +63,6 @@ void MeshEditor::_notification(int p_what) {
}
void MeshEditor::_update_rotation() {
-
Transform t;
t.basis.rotate(Vector3(0, 1, 0), -rot_y);
t.basis.rotate(Vector3(1, 0, 0), -rot_x);
@@ -75,7 +70,6 @@ void MeshEditor::_update_rotation() {
}
void MeshEditor::edit(Ref<Mesh> p_mesh) {
-
mesh = p_mesh;
mesh_instance->set_mesh(mesh);
@@ -98,7 +92,6 @@ void MeshEditor::edit(Ref<Mesh> p_mesh) {
}
void MeshEditor::_button_pressed(Node *p_button) {
-
if (p_button == light_1_switch) {
light1->set_visible(!light_1_switch->is_pressed());
}
@@ -109,16 +102,14 @@ void MeshEditor::_button_pressed(Node *p_button) {
}
void MeshEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &MeshEditor::_gui_input);
}
MeshEditor::MeshEditor() {
-
viewport = memnew(SubViewport);
- Ref<World3D> world;
- world.instance();
- viewport->set_world(world); //use own world
+ Ref<World3D> world_3d;
+ world_3d.instance();
+ viewport->set_world_3d(world_3d); //use own world
add_child(viewport);
viewport->set_disable_input(true);
viewport->set_msaa(Viewport::MSAA_2X);
@@ -172,12 +163,10 @@ MeshEditor::MeshEditor() {
///////////////////////
bool EditorInspectorPluginMesh::can_handle(Object *p_object) {
-
return Object::cast_to<Mesh>(p_object) != nullptr;
}
void EditorInspectorPluginMesh::parse_begin(Object *p_object) {
-
Mesh *mesh = Object::cast_to<Mesh>(p_object);
if (!mesh) {
return;
@@ -190,7 +179,6 @@ void EditorInspectorPluginMesh::parse_begin(Object *p_object) {
}
MeshEditorPlugin::MeshEditorPlugin(EditorNode *p_node) {
-
Ref<EditorInspectorPluginMesh> plugin;
plugin.instance();
add_inspector_plugin(plugin);
diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h
index 072e21f260..6f171a0eab 100644
--- a/editor/plugins/mesh_editor_plugin.h
+++ b/editor/plugins/mesh_editor_plugin.h
@@ -40,7 +40,6 @@
#include "scene/resources/material.h"
class MeshEditor : public SubViewportContainer {
-
GDCLASS(MeshEditor, SubViewportContainer);
float rot_x;
@@ -82,7 +81,6 @@ public:
};
class MeshEditorPlugin : public EditorPlugin {
-
GDCLASS(MeshEditorPlugin, EditorPlugin);
public:
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
index 7819f62bc7..1b65987af0 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp
@@ -38,7 +38,6 @@
#include "scene/gui/box_container.h"
void MeshInstance3DEditor::_node_removed(Node *p_node) {
-
if (p_node == node) {
node = nullptr;
options->hide();
@@ -46,12 +45,10 @@ void MeshInstance3DEditor::_node_removed(Node *p_node) {
}
void MeshInstance3DEditor::edit(MeshInstance3D *p_mesh) {
-
node = p_mesh;
}
void MeshInstance3DEditor::_menu_option(int p_option) {
-
Ref<Mesh> mesh = node->get_mesh();
if (mesh.is_null()) {
err_dialog->set_text(TTR("Mesh is empty!"));
@@ -61,7 +58,6 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
switch (p_option) {
case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY: {
-
EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
@@ -95,18 +91,20 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
ur->create_action(TTR("Create Static Trimesh Body"));
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
MeshInstance3D *instance = Object::cast_to<MeshInstance3D>(E->get());
- if (!instance)
+ if (!instance) {
continue;
+ }
Ref<Mesh> m = instance->get_mesh();
- if (m.is_null())
+ if (m.is_null()) {
continue;
+ }
Ref<Shape3D> shape = m->create_trimesh_shape();
- if (shape.is_null())
+ if (shape.is_null()) {
continue;
+ }
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(shape);
@@ -127,7 +125,6 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE: {
-
if (node == get_tree()->get_edited_scene_root()) {
err_dialog->set_text(TTR("This doesn't work on scene root!"));
err_dialog->popup_centered();
@@ -135,8 +132,9 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
}
Ref<Shape3D> shape = mesh->create_trimesh_shape();
- if (shape.is_null())
+ if (shape.is_null()) {
return;
+ }
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(shape);
@@ -155,7 +153,6 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
ur->commit_action();
} break;
case MENU_OPTION_CREATE_SINGLE_CONVEX_COLLISION_SHAPE: {
-
if (node == get_tree()->get_edited_scene_root()) {
err_dialog->set_text(TTR("Can't create a single convex collision shape for the scene root."));
err_dialog->popup_centered();
@@ -189,7 +186,6 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CREATE_MULTIPLE_CONVEX_COLLISION_SHAPES: {
-
if (node == get_tree()->get_edited_scene_root()) {
err_dialog->set_text(TTR("Can't create multiple convex collision shapes for the scene root."));
err_dialog->popup_centered();
@@ -208,7 +204,6 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
ur->create_action(TTR("Create Multiple Convex Shapes"));
for (int i = 0; i < shapes.size(); i++) {
-
CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(shapes[i]);
cshape->set_transform(node->get_transform());
@@ -226,11 +221,11 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CREATE_NAVMESH: {
-
Ref<NavigationMesh> nmesh = memnew(NavigationMesh);
- if (nmesh.is_null())
+ if (nmesh.is_null()) {
return;
+ }
nmesh->create_from_mesh(mesh);
NavigationRegion3D *nmi = memnew(NavigationRegion3D);
@@ -250,11 +245,9 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CREATE_OUTLINE_MESH: {
-
outline_dialog->popup_centered(Vector2(200, 90));
} break;
case MENU_OPTION_CREATE_UV2: {
-
Ref<ArrayMesh> mesh2 = node->get_mesh();
if (!mesh2.is_valid()) {
err_dialog->set_text(TTR("Contained Mesh is not of type ArrayMesh."));
@@ -292,15 +285,15 @@ void MeshInstance3DEditor::_menu_option(int p_option) {
}
struct MeshInstance3DEditorEdgeSort {
-
Vector2 a;
Vector2 b;
bool operator<(const MeshInstance3DEditorEdgeSort &p_b) const {
- if (a == p_b.a)
+ if (a == p_b.a) {
return b < p_b.b;
- else
+ } else {
return a < p_b.a;
+ }
}
MeshInstance3DEditorEdgeSort() {}
@@ -316,15 +309,15 @@ struct MeshInstance3DEditorEdgeSort {
};
void MeshInstance3DEditor::_create_uv_lines(int p_layer) {
-
Ref<Mesh> mesh = node->get_mesh();
ERR_FAIL_COND(!mesh.is_valid());
Set<MeshInstance3DEditorEdgeSort> edges;
uv_lines.clear();
for (int i = 0; i < mesh->get_surface_count(); i++) {
- if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
+ if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
continue;
+ }
Array a = mesh->surface_get_arrays(i);
Vector<Vector2> uv = a[p_layer == 0 ? Mesh::ARRAY_TEX_UV : Mesh::ARRAY_TEX_UV2];
@@ -349,9 +342,7 @@ void MeshInstance3DEditor::_create_uv_lines(int p_layer) {
}
for (int j = 0; j < ic; j += 3) {
-
for (int k = 0; k < 3; k++) {
-
MeshInstance3DEditorEdgeSort edge;
if (ri) {
edge.a = r[ri[j + k]];
@@ -361,8 +352,9 @@ void MeshInstance3DEditor::_create_uv_lines(int p_layer) {
edge.b = r[j + ((k + 1) % 3)];
}
- if (edges.has(edge))
+ if (edges.has(edge)) {
continue;
+ }
uv_lines.push_back(edge.a);
uv_lines.push_back(edge.b);
@@ -375,9 +367,9 @@ void MeshInstance3DEditor::_create_uv_lines(int p_layer) {
}
void MeshInstance3DEditor::_debug_uv_draw() {
-
- if (uv_lines.size() == 0)
+ if (uv_lines.size() == 0) {
return;
+ }
debug_uv->set_clip_contents(true);
debug_uv->draw_rect(Rect2(Vector2(), debug_uv->get_size()), Color(0.2, 0.2, 0.0));
@@ -386,7 +378,6 @@ void MeshInstance3DEditor::_debug_uv_draw() {
}
void MeshInstance3DEditor::_create_outline_mesh() {
-
Ref<Mesh> mesh = node->get_mesh();
if (mesh.is_null()) {
err_dialog->set_text(TTR("MeshInstance3D lacks a Mesh."));
@@ -435,7 +426,6 @@ void MeshInstance3DEditor::_bind_methods() {
}
MeshInstance3DEditor::MeshInstance3DEditor() {
-
options = memnew(MenuButton);
options->set_switch_on_hover(true);
Node3DEditor::get_singleton()->add_control_to_menu_panel(options);
@@ -495,28 +485,23 @@ MeshInstance3DEditor::MeshInstance3DEditor() {
}
void MeshInstance3DEditorPlugin::edit(Object *p_object) {
-
mesh_editor->edit(Object::cast_to<MeshInstance3D>(p_object));
}
bool MeshInstance3DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("MeshInstance3D");
}
void MeshInstance3DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
mesh_editor->options->show();
} else {
-
mesh_editor->options->hide();
mesh_editor->edit(nullptr);
}
}
MeshInstance3DEditorPlugin::MeshInstance3DEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
mesh_editor = memnew(MeshInstance3DEditor);
editor->get_viewport()->add_child(mesh_editor);
diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.h b/editor/plugins/mesh_instance_3d_editor_plugin.h
index a5d90c42d5..3350a792bc 100644
--- a/editor/plugins/mesh_instance_3d_editor_plugin.h
+++ b/editor/plugins/mesh_instance_3d_editor_plugin.h
@@ -37,7 +37,6 @@
#include "scene/gui/spin_box.h"
class MeshInstance3DEditor : public Control {
-
GDCLASS(MeshInstance3DEditor, Control);
enum Menu {
@@ -84,7 +83,6 @@ public:
};
class MeshInstance3DEditorPlugin : public EditorPlugin {
-
GDCLASS(MeshInstance3DEditorPlugin, EditorPlugin);
MeshInstance3DEditor *mesh_editor;
diff --git a/editor/plugins/mesh_library_editor_plugin.cpp b/editor/plugins/mesh_library_editor_plugin.cpp
index a3e3d88ae2..7690beeee8 100644
--- a/editor/plugins/mesh_library_editor_plugin.cpp
+++ b/editor/plugins/mesh_library_editor_plugin.cpp
@@ -41,18 +41,15 @@
#include "scene/resources/packed_scene.h"
void MeshLibraryEditor::edit(const Ref<MeshLibrary> &p_mesh_library) {
-
mesh_library = p_mesh_library;
- if (mesh_library.is_valid())
+ if (mesh_library.is_valid()) {
menu->get_popup()->set_item_disabled(menu->get_popup()->get_item_index(MENU_OPTION_UPDATE_FROM_SCENE), !mesh_library->has_meta("_editor_source_scene"));
+ }
}
void MeshLibraryEditor::_menu_confirm() {
-
switch (option) {
-
case MENU_OPTION_REMOVE_ITEM: {
-
mesh_library->remove_item(to_erase);
} break;
case MENU_OPTION_UPDATE_FROM_SCENE: {
@@ -67,14 +64,13 @@ void MeshLibraryEditor::_menu_confirm() {
}
void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library, bool p_merge) {
-
- if (!p_merge)
+ if (!p_merge) {
p_library->clear();
+ }
Map<int, MeshInstance3D *> mesh_instances;
for (int i = 0; i < p_scene->get_child_count(); i++) {
-
Node *child = p_scene->get_child(i);
if (!Object::cast_to<MeshInstance3D>(child)) {
@@ -84,14 +80,16 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
continue;
}
- } else
+ } else {
continue;
+ }
}
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(child);
Ref<Mesh> mesh = mi->get_mesh();
- if (mesh.is_null())
+ if (mesh.is_null()) {
continue;
+ }
mesh = mesh->duplicate();
for (int j = 0; j < mesh->get_surface_count(); ++j) {
@@ -104,7 +102,6 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
int id = p_library->find_item_by_name(mi->get_name());
if (id < 0) {
-
id = p_library->get_last_unused_item_id();
p_library->create_item(id);
p_library->set_item_name(id, mi->get_name());
@@ -116,28 +113,29 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
Vector<MeshLibrary::ShapeData> collisions;
for (int j = 0; j < mi->get_child_count(); j++) {
-
Node *child2 = mi->get_child(j);
- if (!Object::cast_to<StaticBody3D>(child2))
+ if (!Object::cast_to<StaticBody3D>(child2)) {
continue;
+ }
StaticBody3D *sb = Object::cast_to<StaticBody3D>(child2);
List<uint32_t> shapes;
sb->get_shape_owners(&shapes);
for (List<uint32_t>::Element *E = shapes.front(); E; E = E->next()) {
- if (sb->is_shape_owner_disabled(E->get()))
+ if (sb->is_shape_owner_disabled(E->get())) {
continue;
+ }
//Transform shape_transform = sb->shape_owner_get_transform(E->get());
//shape_transform.set_origin(shape_transform.get_origin() - phys_offset);
for (int k = 0; k < sb->shape_owner_get_shape_count(E->get()); k++) {
-
Ref<Shape3D> collision = sb->shape_owner_get_shape(E->get(), k);
- if (!collision.is_valid())
+ if (!collision.is_valid()) {
continue;
+ }
MeshLibrary::ShapeData shape_data;
shape_data.shape = collision;
shape_data.local_transform = sb->get_transform() * sb->shape_owner_get_transform(E->get());
@@ -152,13 +150,15 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
Transform navmesh_transform;
for (int j = 0; j < mi->get_child_count(); j++) {
Node *child2 = mi->get_child(j);
- if (!Object::cast_to<NavigationRegion3D>(child2))
+ if (!Object::cast_to<NavigationRegion3D>(child2)) {
continue;
+ }
NavigationRegion3D *sb = Object::cast_to<NavigationRegion3D>(child2);
navmesh = sb->get_navigation_mesh();
navmesh_transform = sb->get_transform();
- if (!navmesh.is_null())
+ if (!navmesh.is_null()) {
break;
+ }
}
if (!navmesh.is_null()) {
p_library->set_item_navmesh(id, navmesh);
@@ -168,15 +168,12 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
//generate previews!
- if (1) {
-
+ if (true) {
Vector<Ref<Mesh>> meshes;
Vector<Transform> transforms;
Vector<int> ids = p_library->get_item_list();
for (int i = 0; i < ids.size(); i++) {
-
if (mesh_instances.find(ids[i])) {
-
meshes.push_back(p_library->get_item_mesh(ids[i]));
transforms.push_back(mesh_instances[ids[i]]->get_transform());
}
@@ -185,9 +182,7 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
Vector<Ref<Texture2D>> textures = EditorInterface::get_singleton()->make_mesh_previews(meshes, &transforms, EditorSettings::get_singleton()->get("editors/grid_map/preview_size"));
int j = 0;
for (int i = 0; i < ids.size(); i++) {
-
if (mesh_instances.find(ids[i])) {
-
p_library->set_item_preview(ids[i], textures[j]);
j++;
}
@@ -196,7 +191,6 @@ void MeshLibraryEditor::_import_scene(Node *p_scene, Ref<MeshLibrary> p_library,
}
void MeshLibraryEditor::_import_scene_cbk(const String &p_str) {
-
Ref<PackedScene> ps = ResourceLoader::load(p_str, "PackedScene");
ERR_FAIL_COND(ps.is_null());
Node *scene = ps->instance();
@@ -211,36 +205,28 @@ void MeshLibraryEditor::_import_scene_cbk(const String &p_str) {
}
Error MeshLibraryEditor::update_library_file(Node *p_base_scene, Ref<MeshLibrary> ml, bool p_merge) {
-
_import_scene(p_base_scene, ml, p_merge);
return OK;
}
void MeshLibraryEditor::_menu_cbk(int p_option) {
-
option = p_option;
switch (p_option) {
-
case MENU_OPTION_ADD_ITEM: {
-
mesh_library->create_item(mesh_library->get_last_unused_item_id());
} break;
case MENU_OPTION_REMOVE_ITEM: {
-
String p = editor->get_inspector()->get_selected_path();
if (p.begins_with("/MeshLibrary/item") && p.get_slice_count("/") >= 3) {
-
to_erase = p.get_slice("/", 3).to_int();
cd->set_text(vformat(TTR("Remove item %d?"), to_erase));
cd->popup_centered(Size2(300, 60));
}
} break;
case MENU_OPTION_IMPORT_FROM_SCENE: {
-
file->popup_centered_ratio();
} break;
case MENU_OPTION_UPDATE_FROM_SCENE: {
-
cd->set_text(vformat(TTR("Update from existing scene?:\n%s"), String(mesh_library->get_meta("_editor_source_scene"))));
cd->popup_centered(Size2(500, 60));
} break;
@@ -251,7 +237,6 @@ void MeshLibraryEditor::_bind_methods() {
}
MeshLibraryEditor::MeshLibraryEditor(EditorNode *p_editor) {
-
file = memnew(EditorFileDialog);
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
//not for now?
@@ -260,7 +245,6 @@ MeshLibraryEditor::MeshLibraryEditor(EditorNode *p_editor) {
file->clear_filters();
file->set_title(TTR("Import Scene"));
for (int i = 0; i < extensions.size(); i++) {
-
file->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper());
}
add_child(file);
@@ -287,21 +271,19 @@ MeshLibraryEditor::MeshLibraryEditor(EditorNode *p_editor) {
}
void MeshLibraryEditorPlugin::edit(Object *p_node) {
-
if (Object::cast_to<MeshLibrary>(p_node)) {
mesh_library_editor->edit(Object::cast_to<MeshLibrary>(p_node));
mesh_library_editor->show();
- } else
+ } else {
mesh_library_editor->hide();
+ }
}
bool MeshLibraryEditorPlugin::handles(Object *p_node) const {
-
return p_node->is_class("MeshLibrary");
}
void MeshLibraryEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
mesh_library_editor->show();
mesh_library_editor->get_menu_button()->show();
@@ -312,7 +294,6 @@ void MeshLibraryEditorPlugin::make_visible(bool p_visible) {
}
MeshLibraryEditorPlugin::MeshLibraryEditorPlugin(EditorNode *p_node) {
-
EDITOR_DEF("editors/grid_map/preview_size", 64);
mesh_library_editor = memnew(MeshLibraryEditor(p_node));
diff --git a/editor/plugins/mesh_library_editor_plugin.h b/editor/plugins/mesh_library_editor_plugin.h
index 74b0a280e3..61ce5692bc 100644
--- a/editor/plugins/mesh_library_editor_plugin.h
+++ b/editor/plugins/mesh_library_editor_plugin.h
@@ -35,7 +35,6 @@
#include "scene/resources/mesh_library.h"
class MeshLibraryEditor : public Control {
-
GDCLASS(MeshLibraryEditor, Control);
Ref<MeshLibrary> mesh_library;
@@ -74,7 +73,6 @@ public:
};
class MeshLibraryEditorPlugin : public EditorPlugin {
-
GDCLASS(MeshLibraryEditorPlugin, EditorPlugin);
MeshLibraryEditor *mesh_library_editor;
diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp
index 4f482c2b43..3904389e09 100644
--- a/editor/plugins/multimesh_editor_plugin.cpp
+++ b/editor/plugins/multimesh_editor_plugin.cpp
@@ -35,7 +35,6 @@
#include "scene/gui/box_container.h"
void MultiMeshEditor::_node_removed(Node *p_node) {
-
if (p_node == node) {
node = nullptr;
hide();
@@ -43,24 +42,21 @@ void MultiMeshEditor::_node_removed(Node *p_node) {
}
void MultiMeshEditor::_populate() {
-
- if (!node)
+ if (!node) {
return;
+ }
Ref<Mesh> mesh;
if (mesh_source->get_text() == "") {
-
Ref<MultiMesh> multimesh;
multimesh = node->get_multimesh();
if (multimesh.is_null()) {
-
err_dialog->set_text(TTR("No mesh source specified (and no MultiMesh set in node)."));
err_dialog->popup_centered();
return;
}
if (multimesh->get_mesh().is_null()) {
-
err_dialog->set_text(TTR("No mesh source specified (and MultiMesh contains no Mesh)."));
err_dialog->popup_centered();
return;
@@ -68,11 +64,9 @@ void MultiMeshEditor::_populate() {
mesh = multimesh->get_mesh();
} else {
-
Node *ms_node = node->get_node(mesh_source->get_text());
if (!ms_node) {
-
err_dialog->set_text(TTR("Mesh source is invalid (invalid path)."));
err_dialog->popup_centered();
return;
@@ -81,7 +75,6 @@ void MultiMeshEditor::_populate() {
MeshInstance3D *ms_instance = Object::cast_to<MeshInstance3D>(ms_node);
if (!ms_instance) {
-
err_dialog->set_text(TTR("Mesh source is invalid (not a MeshInstance3D)."));
err_dialog->popup_centered();
return;
@@ -90,7 +83,6 @@ void MultiMeshEditor::_populate() {
mesh = ms_instance->get_mesh();
if (mesh.is_null()) {
-
err_dialog->set_text(TTR("Mesh source is invalid (contains no Mesh resource)."));
err_dialog->popup_centered();
return;
@@ -98,7 +90,6 @@ void MultiMeshEditor::_populate() {
}
if (surface_source->get_text() == "") {
-
err_dialog->set_text(TTR("No surface source specified."));
err_dialog->popup_centered();
return;
@@ -107,7 +98,6 @@ void MultiMeshEditor::_populate() {
Node *ss_node = node->get_node(surface_source->get_text());
if (!ss_node) {
-
err_dialog->set_text(TTR("Surface source is invalid (invalid path)."));
err_dialog->popup_centered();
return;
@@ -116,7 +106,6 @@ void MultiMeshEditor::_populate() {
GeometryInstance3D *ss_instance = Object::cast_to<MeshInstance3D>(ss_node);
if (!ss_instance) {
-
err_dialog->set_text(TTR("Surface source is invalid (no geometry)."));
err_dialog->popup_centered();
return;
@@ -127,7 +116,6 @@ void MultiMeshEditor::_populate() {
Vector<Face3> geometry = ss_instance->get_faces(VisualInstance3D::FACES_SOLID);
if (geometry.size() == 0) {
-
err_dialog->set_text(TTR("Surface source is invalid (no faces)."));
err_dialog->popup_centered();
return;
@@ -153,10 +141,10 @@ void MultiMeshEditor::_populate() {
float area_accum = 0;
Map<float, int> triangle_area_map;
for (int i = 0; i < facecount; i++) {
-
float area = r[i].get_area();
- if (area < CMP_EPSILON)
+ if (area < CMP_EPSILON) {
continue;
+ }
triangle_area_map[area_accum] = i;
area_accum += area;
}
@@ -188,7 +176,6 @@ void MultiMeshEditor::_populate() {
}
for (int i = 0; i < instance_count; i++) {
-
float areapos = Math::random(0.0f, area_accum);
Map<float, int>::Element *E = triangle_area_map.find_closest(areapos);
@@ -227,23 +214,19 @@ void MultiMeshEditor::_populate() {
}
void MultiMeshEditor::_browsed(const NodePath &p_path) {
-
NodePath path = node->get_path_to(get_node(p_path));
- if (browsing_source)
+ if (browsing_source) {
mesh_source->set_text(path);
- else
+ } else {
surface_source->set_text(path);
+ }
}
void MultiMeshEditor::_menu_option(int p_option) {
-
switch (p_option) {
-
case MENU_OPTION_POPULATE: {
-
if (_last_pp_node != node) {
-
surface_source->set_text("..");
mesh_source->set_text("..");
populate_axis->select(1);
@@ -262,26 +245,24 @@ void MultiMeshEditor::_menu_option(int p_option) {
}
void MultiMeshEditor::edit(MultiMeshInstance3D *p_multimesh) {
-
node = p_multimesh;
}
void MultiMeshEditor::_browse(bool p_source) {
-
browsing_source = p_source;
std->get_scene_tree()->set_marked(node, false);
std->popup_centered_ratio();
- if (p_source)
+ if (p_source) {
std->set_title(TTR("Select a Source Mesh:"));
- else
+ } else {
std->set_title(TTR("Select a Target Surface:"));
+ }
}
void MultiMeshEditor::_bind_methods() {
}
MultiMeshEditor::MultiMeshEditor() {
-
options = memnew(MenuButton);
options->set_switch_on_hover(true);
Node3DEditor::get_singleton()->add_control_to_menu_panel(options);
@@ -378,28 +359,23 @@ MultiMeshEditor::MultiMeshEditor() {
}
void MultiMeshEditorPlugin::edit(Object *p_object) {
-
multimesh_editor->edit(Object::cast_to<MultiMeshInstance3D>(p_object));
}
bool MultiMeshEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("MultiMeshInstance3D");
}
void MultiMeshEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
multimesh_editor->options->show();
} else {
-
multimesh_editor->options->hide();
multimesh_editor->edit(nullptr);
}
}
MultiMeshEditorPlugin::MultiMeshEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
multimesh_editor = memnew(MultiMeshEditor);
editor->get_viewport()->add_child(multimesh_editor);
diff --git a/editor/plugins/multimesh_editor_plugin.h b/editor/plugins/multimesh_editor_plugin.h
index 15c9b91fee..2b0a0c137f 100644
--- a/editor/plugins/multimesh_editor_plugin.h
+++ b/editor/plugins/multimesh_editor_plugin.h
@@ -37,7 +37,6 @@
#include "scene/gui/spin_box.h"
class MultiMeshEditor : public Control {
-
GDCLASS(MultiMeshEditor, Control);
friend class MultiMeshEditorPlugin;
@@ -83,7 +82,6 @@ public:
};
class MultiMeshEditorPlugin : public EditorPlugin {
-
GDCLASS(MultiMeshEditorPlugin, EditorPlugin);
MultiMeshEditor *multimesh_editor;
diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp
index e41b32ac86..8cf9f01fa0 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.cpp
+++ b/editor/plugins/navigation_polygon_editor_plugin.cpp
@@ -31,10 +31,8 @@
#include "navigation_polygon_editor_plugin.h"
Ref<NavigationPolygon> NavigationPolygonEditor::_ensure_navpoly() const {
-
Ref<NavigationPolygon> navpoly = node->get_navigation_polygon();
if (!navpoly.is_valid()) {
-
navpoly = Ref<NavigationPolygon>(memnew(NavigationPolygon));
node->set_navigation_polygon(navpoly);
}
@@ -42,42 +40,38 @@ Ref<NavigationPolygon> NavigationPolygonEditor::_ensure_navpoly() const {
}
Node2D *NavigationPolygonEditor::_get_node() const {
-
return node;
}
void NavigationPolygonEditor::_set_node(Node *p_polygon) {
-
node = Object::cast_to<NavigationRegion2D>(p_polygon);
}
int NavigationPolygonEditor::_get_polygon_count() const {
-
Ref<NavigationPolygon> navpoly = node->get_navigation_polygon();
- if (navpoly.is_valid())
+ if (navpoly.is_valid()) {
return navpoly->get_outline_count();
- else
+ } else {
return 0;
+ }
}
Variant NavigationPolygonEditor::_get_polygon(int p_idx) const {
-
Ref<NavigationPolygon> navpoly = node->get_navigation_polygon();
- if (navpoly.is_valid())
+ if (navpoly.is_valid()) {
return navpoly->get_outline(p_idx);
- else
+ } else {
return Variant(Vector<Vector2>());
+ }
}
void NavigationPolygonEditor::_set_polygon(int p_idx, const Variant &p_polygon) const {
-
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
navpoly->set_outline(p_idx, p_polygon);
navpoly->make_polygons_from_outlines();
}
void NavigationPolygonEditor::_action_add_polygon(const Variant &p_polygon) {
-
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
undo_redo->add_do_method(navpoly.ptr(), "add_outline", p_polygon);
undo_redo->add_undo_method(navpoly.ptr(), "remove_outline", navpoly->get_outline_count());
@@ -86,7 +80,6 @@ void NavigationPolygonEditor::_action_add_polygon(const Variant &p_polygon) {
}
void NavigationPolygonEditor::_action_remove_polygon(int p_idx) {
-
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
undo_redo->add_do_method(navpoly.ptr(), "remove_outline", p_idx);
undo_redo->add_undo_method(navpoly.ptr(), "add_outline_at_index", navpoly->get_outline(p_idx), p_idx);
@@ -95,7 +88,6 @@ void NavigationPolygonEditor::_action_remove_polygon(int p_idx) {
}
void NavigationPolygonEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) {
-
Ref<NavigationPolygon> navpoly = _ensure_navpoly();
undo_redo->add_do_method(navpoly.ptr(), "set_outline", p_idx, p_polygon);
undo_redo->add_undo_method(navpoly.ptr(), "set_outline", p_idx, p_previous);
@@ -104,14 +96,13 @@ void NavigationPolygonEditor::_action_set_polygon(int p_idx, const Variant &p_pr
}
bool NavigationPolygonEditor::_has_resource() const {
-
return node && node->get_navigation_polygon().is_valid();
}
void NavigationPolygonEditor::_create_resource() {
-
- if (!node)
+ if (!node) {
return;
+ }
undo_redo->create_action(TTR("Create Navigation Polygon"));
undo_redo->add_do_method(node, "set_navigation_polygon", Ref<NavigationPolygon>(memnew(NavigationPolygon)));
diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h
index 0bc35e2498..0767322c17 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.h
+++ b/editor/plugins/navigation_polygon_editor_plugin.h
@@ -35,7 +35,6 @@
#include "scene/2d/navigation_region_2d.h"
class NavigationPolygonEditor : public AbstractPolygon2DEditor {
-
GDCLASS(NavigationPolygonEditor, AbstractPolygon2DEditor);
NavigationRegion2D *node;
@@ -62,7 +61,6 @@ public:
};
class NavigationPolygonEditorPlugin : public AbstractPolygon2DEditorPlugin {
-
GDCLASS(NavigationPolygonEditorPlugin, AbstractPolygon2DEditorPlugin);
public:
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 354c951a7c..3c12022854 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -30,7 +30,7 @@
#include "node_3d_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/math/camera_matrix.h"
#include "core/os/keyboard.h"
#include "core/print_string.h"
@@ -51,7 +51,6 @@
#include "scene/gui/subviewport_container.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/surface_tool.h"
-#include "servers/display_server.h"
#define DISTANCE_DEFAULT 4
@@ -78,7 +77,6 @@
#define MAX_FOV 179
void ViewportRotationControl::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
axis_menu_options.clear();
axis_menu_options.push_back(Node3DEditorViewport::VIEW_RIGHT);
@@ -196,12 +194,20 @@ void ViewportRotationControl::_gui_input(Ref<InputEvent> p_event) {
_update_focus();
}
orbiting = false;
+ if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_CAPTURED) {
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ Input::get_singleton()->warp_mouse_position(orbiting_mouse_start);
+ }
}
}
const Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
if (orbiting) {
+ if (Input::get_singleton()->get_mouse_mode() == Input::MOUSE_MODE_VISIBLE) {
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
+ orbiting_mouse_start = mm->get_global_position();
+ }
viewport->_nav_orbit(mm, viewport->_get_warped_mouse_motion(mm));
focused_axis = -1;
} else {
@@ -248,19 +254,16 @@ void ViewportRotationControl::_bind_methods() {
}
void Node3DEditorViewport::_update_camera(float p_interp_delta) {
-
bool is_orthogonal = camera->get_projection() == Camera3D::PROJECTION_ORTHOGONAL;
Cursor old_camera_cursor = camera_cursor;
camera_cursor = cursor;
if (p_interp_delta > 0) {
-
//-------
// Perform smoothing
if (is_freelook_active()) {
-
// Higher inertia should increase "lag" (lerp with factor between 0 and 1)
// Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1.
real_t inertia = EDITOR_GET("editors/3d/freelook/freelook_inertia");
@@ -268,7 +271,7 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) {
real_t factor = (1.0 / inertia) * p_interp_delta;
// We interpolate a different point here, because in freelook mode the focus point (cursor.pos) orbits around eye_pos
- camera_cursor.eye_pos = old_camera_cursor.eye_pos.linear_interpolate(cursor.eye_pos, CLAMP(factor, 0, 1));
+ camera_cursor.eye_pos = old_camera_cursor.eye_pos.lerp(cursor.eye_pos, CLAMP(factor, 0, 1));
float orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
orbit_inertia = MAX(0.0001, orbit_inertia);
@@ -287,7 +290,6 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) {
camera_cursor.pos = camera_cursor.eye_pos + forward * camera_cursor.distance;
} else {
-
//when not being manipulated, move softly
float free_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
float free_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/translation_inertia");
@@ -298,10 +300,10 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) {
float zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia");
//determine if being manipulated
- bool manipulated = InputFilter::get_singleton()->get_mouse_button_mask() & (2 | 4);
- manipulated |= InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
- manipulated |= InputFilter::get_singleton()->is_key_pressed(KEY_ALT);
- manipulated |= InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool manipulated = Input::get_singleton()->get_mouse_button_mask() & (2 | 4);
+ manipulated |= Input::get_singleton()->is_key_pressed(KEY_SHIFT);
+ manipulated |= Input::get_singleton()->is_key_pressed(KEY_ALT);
+ manipulated |= Input::get_singleton()->is_key_pressed(KEY_CONTROL);
float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia);
float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia);
@@ -318,7 +320,7 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) {
camera_cursor.y_rot = cursor.y_rot;
}
- camera_cursor.pos = old_camera_cursor.pos.linear_interpolate(cursor.pos, MIN(1.f, p_interp_delta * (1 / translation_inertia)));
+ camera_cursor.pos = old_camera_cursor.pos.lerp(cursor.pos, MIN(1.f, p_interp_delta * (1 / translation_inertia)));
camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN(1.f, p_interp_delta * (1 / zoom_inertia)));
}
}
@@ -341,7 +343,6 @@ void Node3DEditorViewport::_update_camera(float p_interp_delta) {
}
if (!equal || p_interp_delta == 0 || is_freelook_active() || is_orthogonal != orthogonal) {
-
camera->set_global_transform(to_camera_transform(camera_cursor));
if (orthogonal) {
@@ -363,29 +364,30 @@ Transform Node3DEditorViewport::to_camera_transform(const Cursor &p_cursor) cons
camera_transform.basis.rotate(Vector3(1, 0, 0), -p_cursor.x_rot);
camera_transform.basis.rotate(Vector3(0, 1, 0), -p_cursor.y_rot);
- if (orthogonal)
+ if (orthogonal) {
camera_transform.translate(0, 0, (get_zfar() - get_znear()) / 2.0);
- else
+ } else {
camera_transform.translate(0, 0, p_cursor.distance);
+ }
return camera_transform;
}
int Node3DEditorViewport::get_selected_count() const {
-
Map<Node *, Object *> &selection = editor_selection->get_selection();
int count = 0;
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->key());
- if (!sp)
+ if (!sp) {
continue;
+ }
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
count++;
}
@@ -394,62 +396,55 @@ int Node3DEditorViewport::get_selected_count() const {
}
float Node3DEditorViewport::get_znear() const {
-
return CLAMP(spatial_editor->get_znear(), MIN_Z, MAX_Z);
}
-float Node3DEditorViewport::get_zfar() const {
+float Node3DEditorViewport::get_zfar() const {
return CLAMP(spatial_editor->get_zfar(), MIN_Z, MAX_Z);
}
-float Node3DEditorViewport::get_fov() const {
+float Node3DEditorViewport::get_fov() const {
return CLAMP(spatial_editor->get_fov(), MIN_FOV, MAX_FOV);
}
Transform Node3DEditorViewport::_get_camera_transform() const {
-
return camera->get_global_transform();
}
Vector3 Node3DEditorViewport::_get_camera_position() const {
-
return _get_camera_transform().origin;
}
Point2 Node3DEditorViewport::_point_to_screen(const Vector3 &p_point) {
-
return camera->unproject_position(p_point) * subviewport_container->get_stretch_shrink();
}
Vector3 Node3DEditorViewport::_get_ray_pos(const Vector2 &p_pos) const {
-
return camera->project_ray_origin(p_pos / subviewport_container->get_stretch_shrink());
}
Vector3 Node3DEditorViewport::_get_camera_normal() const {
-
return -_get_camera_transform().basis.get_axis(2);
}
Vector3 Node3DEditorViewport::_get_ray(const Vector2 &p_pos) const {
-
return camera->project_ray_normal(p_pos / subviewport_container->get_stretch_shrink());
}
void Node3DEditorViewport::_clear_selected() {
-
editor_selection->clear();
}
void Node3DEditorViewport::_select_clicked(bool p_append, bool p_single, bool p_allow_locked) {
-
- if (clicked.is_null())
+ if (clicked.is_null()) {
return;
+ }
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(clicked));
Node3D *selected = Object::cast_to<Node3D>(node);
- if (!selected)
+ if (!selected) {
return;
+ }
if (!p_allow_locked) {
// Replace the node by the group if grouped
@@ -468,7 +463,6 @@ void Node3DEditorViewport::_select_clicked(bool p_append, bool p_single, bool p_
}
void Node3DEditorViewport::_select(Node *p_node, bool p_append, bool p_single) {
-
if (!p_append) {
editor_selection->clear();
}
@@ -477,26 +471,26 @@ void Node3DEditorViewport::_select(Node *p_node, bool p_append, bool p_single) {
//erase
editor_selection->remove_node(p_node);
} else {
-
editor_selection->add_node(p_node);
}
if (p_single) {
- if (Engine::get_singleton()->is_editor_hint())
+ if (Engine::get_singleton()->is_editor_hint()) {
editor->call("edit_node", p_node);
+ }
}
}
ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, bool &r_includes_current, int *r_gizmo_handle, bool p_alt_select) {
-
- if (r_gizmo_handle)
+ if (r_gizmo_handle) {
*r_gizmo_handle = -1;
+ }
Vector3 ray = _get_ray(p_pos);
Vector3 pos = _get_ray_pos(p_pos);
Vector2 shrinked_pos = p_pos / subviewport_container->get_stretch_shrink();
- Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world()->get_scenario());
+ Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world_3d()->get_scenario());
Set<Ref<EditorNode3DGizmo>> found_gizmos;
Node *edited_scene = get_tree()->get_edited_scene_root();
@@ -506,11 +500,11 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, b
int selected_handle = -1;
for (int i = 0; i < instances.size(); i++) {
-
Node3D *spat = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i]));
- if (!spat)
+ if (!spat) {
continue;
+ }
Ref<EditorNode3DGizmo> seg = spat->get_gizmo();
@@ -525,16 +519,17 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, b
int handle = -1;
bool inters = seg->intersect_ray(camera, shrinked_pos, point, normal, &handle, p_alt_select);
- if (!inters)
+ if (!inters) {
continue;
+ }
float dist = pos.distance_to(point);
- if (dist < 0)
+ if (dist < 0) {
continue;
+ }
if (dist < closest_dist) {
-
item = Object::cast_to<Node>(spat);
while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) {
item = item->get_owner();
@@ -546,42 +541,44 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos, bool p_append, b
}
}
- if (!item)
+ if (!item) {
return ObjectID();
+ }
if (!editor_selection->is_selected(item) || (r_gizmo_handle && selected_handle >= 0)) {
-
- if (r_gizmo_handle)
+ if (r_gizmo_handle) {
*r_gizmo_handle = selected_handle;
+ }
}
return closest;
}
void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_includes_current, Vector<_RayResult> &results, bool p_alt_select) {
-
Vector3 ray = _get_ray(p_pos);
Vector3 pos = _get_ray_pos(p_pos);
- Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world()->get_scenario());
+ Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, ray, get_tree()->get_root()->get_world_3d()->get_scenario());
Set<Ref<EditorNode3DGizmo>> found_gizmos;
r_includes_current = false;
for (int i = 0; i < instances.size(); i++) {
-
Node3D *spat = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i]));
- if (!spat)
+ if (!spat) {
continue;
+ }
Ref<EditorNode3DGizmo> seg = spat->get_gizmo();
- if (!seg.is_valid())
+ if (!seg.is_valid()) {
continue;
+ }
- if (found_gizmos.has(seg))
+ if (found_gizmos.has(seg)) {
continue;
+ }
found_gizmos.insert(seg);
Vector3 point;
@@ -590,16 +587,19 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_inclu
int handle = -1;
bool inters = seg->intersect_ray(camera, p_pos, point, normal, nullptr, p_alt_select);
- if (!inters)
+ if (!inters) {
continue;
+ }
float dist = pos.distance_to(point);
- if (dist < 0)
+ if (dist < 0) {
continue;
+ }
- if (editor_selection->is_selected(spat))
+ if (editor_selection->is_selected(spat)) {
r_includes_current = true;
+ }
_RayResult res;
res.item = spat;
@@ -608,14 +608,14 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, bool &r_inclu
results.push_back(res);
}
- if (results.empty())
+ if (results.empty()) {
return;
+ }
results.sort();
}
Vector3 Node3DEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) {
-
CameraMatrix cm;
if (orthogonal) {
cm.set_orthogonal(camera->get_size(), get_size().aspect(), get_znear() + p_vector3.z, get_zfar());
@@ -634,9 +634,9 @@ Vector3 Node3DEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) {
}
void Node3DEditorViewport::_select_region() {
-
- if (cursor.region_begin == cursor.region_end)
+ if (cursor.region_begin == cursor.region_end) {
return; //nothing really
+ }
float z_offset = MAX(0.0, 5.0 - get_znear());
@@ -664,7 +664,6 @@ void Node3DEditorViewport::_select_region() {
Vector3 cam_pos = _get_camera_position();
for (int i = 0; i < 4; i++) {
-
Vector3 a = _get_screen_to_space(box[i]);
Vector3 b = _get_screen_to_space(box[(i + 1) % 4]);
if (orthogonal) {
@@ -674,28 +673,24 @@ void Node3DEditorViewport::_select_region() {
}
}
- if (!orthogonal) {
- Plane near(cam_pos, -_get_camera_normal());
- near.d -= get_znear();
+ Plane near(cam_pos, -_get_camera_normal());
+ near.d -= get_znear();
+ frustum.push_back(near);
- frustum.push_back(near);
+ Plane far = -near;
+ far.d += get_zfar();
+ frustum.push_back(far);
- Plane far = -near;
- far.d += get_zfar();
-
- frustum.push_back(far);
- }
-
- Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world()->get_scenario());
+ Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_convex(frustum, get_tree()->get_root()->get_world_3d()->get_scenario());
Vector<Node *> selected;
Node *edited_scene = get_tree()->get_edited_scene_root();
for (int i = 0; i < instances.size(); i++) {
-
Node3D *sp = Object::cast_to<Node3D>(ObjectDB::get_instance(instances[i]));
- if (!sp || _is_node_locked(sp))
+ if (!sp || _is_node_locked(sp)) {
continue;
+ }
Node *item = Object::cast_to<Node>(sp);
while (item->get_owner() && item->get_owner() != edited_scene && !edited_scene->is_editable_instance(item->get_owner())) {
@@ -715,14 +710,19 @@ void Node3DEditorViewport::_select_region() {
item = sel;
}
- if (selected.find(item) != -1) continue;
+ if (selected.find(item) != -1) {
+ continue;
+ }
- if (_is_node_locked(item)) continue;
+ if (_is_node_locked(item)) {
+ continue;
+ }
Ref<EditorNode3DGizmo> seg = sp->get_gizmo();
- if (!seg.is_valid())
+ if (!seg.is_valid()) {
continue;
+ }
if (seg->intersect_frustum(camera, frustum)) {
selected.push_back(item);
@@ -736,23 +736,22 @@ void Node3DEditorViewport::_select_region() {
}
void Node3DEditorViewport::_update_name() {
-
String view_mode = orthogonal ? TTR("Orthogonal") : TTR("Perspective");
if (auto_orthogonal) {
view_mode += " [auto]";
}
- if (name != "")
+ if (name != "") {
view_menu->set_text(name + " " + view_mode);
- else
+ } else {
view_menu->set_text(view_mode);
+ }
view_menu->set_size(Vector2(0, 0)); // resets the button size
}
void Node3DEditorViewport::_compute_edit(const Point2 &p_point) {
-
_edit.click_ray = _get_ray(Vector2(p_point.x, p_point.y));
_edit.click_ray_pos = _get_ray_pos(Vector2(p_point.x, p_point.y));
_edit.plane = TRANSFORM_VIEW;
@@ -762,14 +761,15 @@ void Node3DEditorViewport::_compute_edit(const Point2 &p_point) {
List<Node *> &selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
- if (!sp)
+ if (!sp) {
continue;
+ }
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
se->original = se->sp->get_global_gizmo_transform();
se->original_local = se->sp->get_local_gizmo_transform();
@@ -777,37 +777,45 @@ void Node3DEditorViewport::_compute_edit(const Point2 &p_point) {
}
static int _get_key_modifier_setting(const String &p_property) {
-
switch (EditorSettings::get_singleton()->get(p_property).operator int()) {
-
- case 0: return 0;
- case 1: return KEY_SHIFT;
- case 2: return KEY_ALT;
- case 3: return KEY_META;
- case 4: return KEY_CONTROL;
+ case 0:
+ return 0;
+ case 1:
+ return KEY_SHIFT;
+ case 2:
+ return KEY_ALT;
+ case 3:
+ return KEY_META;
+ case 4:
+ return KEY_CONTROL;
}
return 0;
}
static int _get_key_modifier(Ref<InputEventWithModifiers> e) {
- if (e->get_shift())
+ if (e->get_shift()) {
return KEY_SHIFT;
- if (e->get_alt())
+ }
+ if (e->get_alt()) {
return KEY_ALT;
- if (e->get_control())
+ }
+ if (e->get_control()) {
return KEY_CONTROL;
- if (e->get_metakey())
+ }
+ if (e->get_metakey()) {
return KEY_META;
+ }
return 0;
}
bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only) {
-
- if (!spatial_editor->is_gizmo_visible())
+ if (!spatial_editor->is_gizmo_visible()) {
return false;
+ }
if (get_selected_count() == 0) {
- if (p_highlight_only)
+ if (p_highlight_only) {
spatial_editor->select_gizmo_highlight_axis(-1);
+ }
return false;
}
@@ -818,12 +826,10 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
float gs = gizmo_scale;
if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE) {
-
int col_axis = -1;
float col_d = 1e20;
for (int i = 0; i < 3; i++) {
-
Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i) * gs * (GIZMO_ARROW_OFFSET + (GIZMO_ARROW_SIZE * 0.5));
float grabber_radius = gs * GIZMO_ARROW_SIZE;
@@ -844,7 +850,6 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
col_d = 1e20;
for (int i = 0; i < 3; i++) {
-
Vector3 ivec2 = gt.basis.get_axis((i + 1) % 3).normalized();
Vector3 ivec3 = gt.basis.get_axis((i + 2) % 3).normalized();
@@ -854,10 +859,8 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
Plane plane(gt.origin, gt.basis.get_axis(i).normalized());
if (plane.intersects_ray(ray_pos, ray, &r)) {
-
float dist = r.distance_to(grabber_pos);
if (dist < (gs * GIZMO_PLANE_SIZE)) {
-
float d = ray_pos.distance_to(r);
if (d < col_d) {
col_d = d;
@@ -871,9 +874,7 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
}
if (col_axis != -1) {
-
if (p_highlight_only) {
-
spatial_editor->select_gizmo_highlight_axis(col_axis + (is_plane_translate ? 6 : 0));
} else {
@@ -887,21 +888,19 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
}
if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
-
int col_axis = -1;
float col_d = 1e20;
for (int i = 0; i < 3; i++) {
-
Plane plane(gt.origin, gt.basis.get_axis(i).normalized());
Vector3 r;
- if (!plane.intersects_ray(ray_pos, ray, &r))
+ if (!plane.intersects_ray(ray_pos, ray, &r)) {
continue;
+ }
float dist = r.distance_to(gt.origin);
if (dist > gs * (GIZMO_CIRCLE_SIZE - GIZMO_RING_HALF_WIDTH) && dist < gs * (GIZMO_CIRCLE_SIZE + GIZMO_RING_HALF_WIDTH)) {
-
float d = ray_pos.distance_to(r);
if (d < col_d) {
col_d = d;
@@ -911,9 +910,7 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
}
if (col_axis != -1) {
-
if (p_highlight_only) {
-
spatial_editor->select_gizmo_highlight_axis(col_axis + 3);
} else {
//handle rotate
@@ -926,12 +923,10 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
}
if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE) {
-
int col_axis = -1;
float col_d = 1e20;
for (int i = 0; i < 3; i++) {
-
Vector3 grabber_pos = gt.origin + gt.basis.get_axis(i) * gs * GIZMO_SCALE_OFFSET;
float grabber_radius = gs * GIZMO_ARROW_SIZE;
@@ -952,7 +947,6 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
col_d = 1e20;
for (int i = 0; i < 3; i++) {
-
Vector3 ivec2 = gt.basis.get_axis((i + 1) % 3).normalized();
Vector3 ivec3 = gt.basis.get_axis((i + 2) % 3).normalized();
@@ -962,10 +956,8 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
Plane plane(gt.origin, gt.basis.get_axis(i).normalized());
if (plane.intersects_ray(ray_pos, ray, &r)) {
-
float dist = r.distance_to(grabber_pos);
if (dist < (gs * GIZMO_PLANE_SIZE)) {
-
float d = ray_pos.distance_to(r);
if (d < col_d) {
col_d = d;
@@ -979,9 +971,7 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
}
if (col_axis != -1) {
-
if (p_highlight_only) {
-
spatial_editor->select_gizmo_highlight_axis(col_axis + (is_plane_scale ? 12 : 9));
} else {
@@ -994,37 +984,36 @@ bool Node3DEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_high
}
}
- if (p_highlight_only)
+ if (p_highlight_only) {
spatial_editor->select_gizmo_highlight_axis(-1);
+ }
return false;
}
void Node3DEditorViewport::_surface_mouse_enter() {
-
- if (!surface->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
+ if (!surface->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field())) {
surface->grab_focus();
+ }
}
void Node3DEditorViewport::_surface_mouse_exit() {
-
_remove_preview();
}
void Node3DEditorViewport::_surface_focus_enter() {
-
view_menu->set_disable_shortcuts(false);
}
void Node3DEditorViewport::_surface_focus_exit() {
-
view_menu->set_disable_shortcuts(true);
}
+
bool Node3DEditorViewport ::_is_node_locked(const Node *p_node) {
return p_node->has_meta("_edit_lock_") && p_node->get_meta("_edit_lock_");
}
-void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
+void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
_find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->get_shift());
Node *scene = editor->get_edited_scene();
@@ -1041,7 +1030,6 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
clicked_wants_append = b->get_shift();
if (selection_results.size() == 1) {
-
clicked = selection_results[0].item->get_instance_id();
selection_results.clear();
@@ -1051,12 +1039,10 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
}
} else if (!selection_results.empty()) {
-
NodePath root_path = get_tree()->get_edited_scene_root()->get_path();
StringName root_name = root_path.get_name(root_path.get_name_count() - 1);
for (int i = 0; i < selection_results.size(); i++) {
-
Node3D *spat = selection_results[i].item;
Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(spat, "Node");
@@ -1097,17 +1083,18 @@ void Node3DEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
}
void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
-
- if (previewing)
+ if (previewing) {
return; //do NONE
+ }
{
EditorNode *en = editor;
EditorPluginList *force_input_forwarding_list = en->get_editor_plugins_force_input_forwarding();
if (!force_input_forwarding_list->empty()) {
bool discard = force_input_forwarding_list->forward_spatial_gui_input(camera, p_event, true);
- if (discard)
+ if (discard) {
return;
+ }
}
}
{
@@ -1115,8 +1102,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
EditorPluginList *over_plugin_list = en->get_editor_plugins_over();
if (!over_plugin_list->empty()) {
bool discard = over_plugin_list->forward_spatial_gui_input(camera, p_event, false);
- if (discard)
+ if (discard) {
return;
+ }
}
}
@@ -1127,23 +1115,23 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
float zoom_factor = 1 + (ZOOM_MULTIPLIER - 1) * b->get_factor();
switch (b->get_button_index()) {
-
case BUTTON_WHEEL_UP: {
- if (is_freelook_active())
+ if (is_freelook_active()) {
scale_freelook_speed(zoom_factor);
- else
+ } else {
scale_cursor_distance(1.0 / zoom_factor);
+ }
} break;
case BUTTON_WHEEL_DOWN: {
- if (is_freelook_active())
+ if (is_freelook_active()) {
scale_freelook_speed(1.0 / zoom_factor);
- else
+ } else {
scale_cursor_distance(zoom_factor);
+ }
} break;
case BUTTON_RIGHT: {
-
NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
if (b->is_pressed() && _edit.gizmo.is_valid()) {
@@ -1153,11 +1141,10 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (_edit.mode == TRANSFORM_NONE && b->is_pressed()) {
-
if (b->get_alt()) {
-
- if (nav_scheme == NAVIGATION_MAYA)
+ if (nav_scheme == NAVIGATION_MAYA) {
break;
+ }
_list_select(b);
return;
@@ -1171,14 +1158,15 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
List<Node *> &selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
- if (!sp)
+ if (!sp) {
continue;
+ }
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
sp->set_global_transform(se->original);
}
@@ -1205,32 +1193,25 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
} break;
case BUTTON_MIDDLE: {
-
if (b->is_pressed() && _edit.mode != TRANSFORM_NONE) {
-
switch (_edit.plane) {
-
case TRANSFORM_VIEW: {
-
_edit.plane = TRANSFORM_X_AXIS;
set_message(TTR("X-Axis Transform."), 2);
name = "";
_update_name();
} break;
case TRANSFORM_X_AXIS: {
-
_edit.plane = TRANSFORM_Y_AXIS;
set_message(TTR("Y-Axis Transform."), 2);
} break;
case TRANSFORM_Y_AXIS: {
-
_edit.plane = TRANSFORM_Z_AXIS;
set_message(TTR("Z-Axis Transform."), 2);
} break;
case TRANSFORM_Z_AXIS: {
-
_edit.plane = TRANSFORM_VIEW;
set_message(TTR("View Plane Transform."), 2);
@@ -1243,9 +1224,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
} break;
case BUTTON_LEFT: {
-
if (b->is_pressed()) {
-
NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b->get_alt()) {
break;
@@ -1270,7 +1249,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (can_select_gizmos && spatial_editor->get_selected()) {
-
Ref<EditorNode3DGizmo> seg = spatial_editor->get_selected()->get_gizmo();
if (seg.is_valid()) {
int handle = -1;
@@ -1278,7 +1256,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Vector3 normal;
bool inters = seg->intersect_ray(camera, _edit.mouse_pos, point, normal, &handle, b->get_shift());
if (inters && handle != -1) {
-
_edit.gizmo = seg;
_edit.gizmo_handle = handle;
_edit.gizmo_initial_value = seg->get_handle_value(handle);
@@ -1287,17 +1264,18 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
}
- if (_gizmo_select(_edit.mouse_pos))
+ if (_gizmo_select(_edit.mouse_pos)) {
break;
+ }
clicked = ObjectID();
clicked_includes_current = false;
if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->get_control()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
-
/* HANDLE ROTATION */
- if (get_selected_count() == 0)
+ if (get_selected_count() == 0) {
break; //bye
+ }
//handle rotate
_edit.mode = TRANSFORM_ROTATE;
_compute_edit(b->get_position());
@@ -1305,9 +1283,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE) {
-
- if (get_selected_count() == 0)
+ if (get_selected_count() == 0) {
break; //bye
+ }
//handle translate
_edit.mode = TRANSFORM_TRANSLATE;
_compute_edit(b->get_position());
@@ -1315,9 +1293,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE) {
-
- if (get_selected_count() == 0)
+ if (get_selected_count() == 0) {
break; //bye
+ }
//handle scale
_edit.mode = TRANSFORM_SCALE;
_compute_edit(b->get_position());
@@ -1335,9 +1313,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
clicked_wants_append = b->get_shift();
if (clicked.is_null()) {
-
- if (!clicked_wants_append)
+ if (!clicked_wants_append) {
_clear_selected();
+ }
//default to regionselect
cursor.region_select = true;
@@ -1346,13 +1324,10 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (clicked.is_valid() && gizmo_handle >= 0) {
-
Node3D *spa = Object::cast_to<Node3D>(ObjectDB::get_instance(clicked));
if (spa) {
-
Ref<EditorNode3DGizmo> seg = spa->get_gizmo();
if (seg.is_valid()) {
-
_edit.gizmo = seg;
_edit.gizmo_handle = gizmo_handle;
_edit.gizmo_initial_value = seg->get_handle_value(gizmo_handle);
@@ -1363,9 +1338,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
surface->update();
} else {
-
if (_edit.gizmo.is_valid()) {
-
_edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, false);
_edit.gizmo = Ref<EditorNode3DGizmo>();
break;
@@ -1377,8 +1350,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (cursor.region_select) {
-
- if (!clicked_wants_append) _clear_selected();
+ if (!clicked_wants_append) {
+ _clear_selected();
+ }
_select_region();
cursor.region_select = false;
@@ -1386,21 +1360,21 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (_edit.mode != TRANSFORM_NONE) {
-
static const char *_transform_name[4] = { "None", "Rotate", "Translate", "Scale" };
undo_redo->create_action(_transform_name[_edit.mode]);
List<Node *> &selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
- if (!sp)
+ if (!sp) {
continue;
+ }
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_gizmo_transform());
undo_redo->add_undo_method(sp, "set_global_transform", se->original);
@@ -1420,14 +1394,11 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> m = p_event;
if (m.is_valid()) {
-
_edit.mouse_pos = m->get_position();
if (spatial_editor->get_selected()) {
-
Ref<EditorNode3DGizmo> seg = spatial_editor->get_selected()->get_gizmo();
if (seg.is_valid()) {
-
int selected_handle = -1;
int handle = -1;
@@ -1435,21 +1406,20 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Vector3 normal;
bool inters = seg->intersect_ray(camera, _edit.mouse_pos, point, normal, &handle, false);
if (inters && handle != -1) {
-
selected_handle = handle;
}
if (selected_handle != spatial_editor->get_over_gizmo_handle()) {
spatial_editor->set_over_gizmo_handle(selected_handle);
spatial_editor->get_selected()->update_gizmo();
- if (selected_handle != -1)
+ if (selected_handle != -1) {
spatial_editor->select_gizmo_highlight_axis(-1);
+ }
}
}
}
if (spatial_editor->get_over_gizmo_handle() == -1 && !(m->get_button_mask() & 1) && !_edit.gizmo.is_valid()) {
-
_gizmo_select(_edit.mouse_pos, true);
}
@@ -1457,14 +1427,12 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
NavigationMode nav_mode = NAVIGATION_NONE;
if (_edit.gizmo.is_valid()) {
-
_edit.gizmo->set_handle(_edit.gizmo_handle, camera, m->get_position());
Variant v = _edit.gizmo->get_handle_value(_edit.gizmo_handle);
String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle);
set_message(n + ": " + String(v));
} else if (m->get_button_mask() & BUTTON_MASK_LEFT) {
-
if (nav_scheme == NAVIGATION_MAYA && m->get_alt()) {
nav_mode = NAVIGATION_ORBIT;
} else if (nav_scheme == NAVIGATION_MODO && m->get_alt() && m->get_shift()) {
@@ -1475,9 +1443,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
nav_mode = NAVIGATION_ORBIT;
} else {
if (clicked.is_valid()) {
-
if (!clicked_includes_current) {
-
_select_clicked(clicked_wants_append, true);
// Processing was deferred.
}
@@ -1494,8 +1460,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
return;
}
- if (_edit.mode == TRANSFORM_NONE)
+ if (_edit.mode == TRANSFORM_NONE) {
return;
+ }
Vector3 ray_pos = _get_ray_pos(m->get_position());
Vector3 ray = _get_ray(m->get_position());
@@ -1503,9 +1470,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
int snap_step_decimals = Math::range_step_decimals(snap);
switch (_edit.mode) {
-
case TRANSFORM_SCALE: {
-
Vector3 motion_mask;
Plane plane;
bool plane_mv = false;
@@ -1545,22 +1510,21 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
Vector3 intersection;
- if (!plane.intersects_ray(ray_pos, ray, &intersection))
+ if (!plane.intersects_ray(ray_pos, ray, &intersection)) {
break;
+ }
Vector3 click;
- if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click))
+ if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) {
break;
+ }
Vector3 motion = intersection - click;
if (_edit.plane != TRANSFORM_VIEW) {
-
if (!plane_mv) {
-
motion = motion_mask.dot(motion) * motion_mask;
} else {
-
// Alternative planar scaling mode
if (_get_key_modifier(m) != KEY_SHIFT) {
motion = motion_mask.dot(motion) * motion_mask;
@@ -1570,8 +1534,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
} else {
float center_click_dist = click.distance_to(_edit.center);
float center_inters_dist = intersection.distance_to(_edit.center);
- if (center_click_dist == 0)
+ if (center_click_dist == 0) {
break;
+ }
float scale = center_inters_dist - center_click_dist;
motion = Vector3(scale, scale, scale);
@@ -1592,7 +1557,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
if (!sp) {
continue;
@@ -1614,7 +1578,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Vector3 local_scale;
if (local_coords) {
-
Basis g = original.basis.orthonormalized();
Vector3 local_motion = g.inverse().xform(motion);
@@ -1628,13 +1591,11 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Basis check = original_local.basis;
check.scale(local_scale);
if (check.determinant() != 0) {
-
// Apply scale
sp->set_scale(local_scale);
}
} else {
-
if (_edit.snap || spatial_editor->is_snap_enabled()) {
motion.snap(Vector3(snap, snap, snap));
}
@@ -1653,7 +1614,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
} break;
case TRANSFORM_TRANSLATE: {
-
Vector3 motion_mask;
Plane plane;
bool plane_mv = false;
@@ -1689,12 +1649,14 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
Vector3 intersection;
- if (!plane.intersects_ray(ray_pos, ray, &intersection))
+ if (!plane.intersects_ray(ray_pos, ray, &intersection)) {
break;
+ }
Vector3 click;
- if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click))
+ if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) {
break;
+ }
Vector3 motion = intersection - click;
if (_edit.plane != TRANSFORM_VIEW) {
@@ -1717,7 +1679,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
String::num(motion_snapped.y, snap_step_decimals) + ", " + String::num(motion_snapped.z, snap_step_decimals) + ")");
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
if (!sp) {
continue;
@@ -1736,7 +1697,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Transform t;
if (local_coords) {
-
if (_edit.snap || spatial_editor->is_snap_enabled()) {
Basis g = original.basis.orthonormalized();
Vector3 local_motion = g.inverse().xform(motion);
@@ -1746,7 +1706,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
} else {
-
if (_edit.snap || spatial_editor->is_snap_enabled()) {
motion.snap(Vector3(snap, snap, snap));
}
@@ -1763,7 +1722,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
} break;
case TRANSFORM_ROTATE: {
-
Plane plane;
Vector3 axis;
@@ -1790,12 +1748,14 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
Vector3 intersection;
- if (!plane.intersects_ray(ray_pos, ray, &intersection))
+ if (!plane.intersects_ray(ray_pos, ray, &intersection)) {
break;
+ }
Vector3 click;
- if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click))
+ if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click)) {
break;
+ }
Vector3 y_axis = (click - _edit.center).normalized();
Vector3 x_axis = plane.normal.cross(y_axis).normalized();
@@ -1815,14 +1775,15 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
bool local_coords = (spatial_editor->are_local_coords_enabled() && _edit.plane != TRANSFORM_VIEW); // Disable local transformation for TRANSFORM_VIEW
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
- if (!sp)
+ if (!sp) {
continue;
+ }
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
if (sp->has_meta("_edit_lock_")) {
continue;
@@ -1831,7 +1792,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Transform t;
if (local_coords) {
-
Transform original_local = se->original_local;
Basis rot = Basis(axis, angle);
@@ -1843,7 +1803,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
sp->set_scale(original_local.basis.get_scale()); // re-apply original scale
} else {
-
Transform original = se->original;
Transform r;
Transform base = Transform(Basis(), _edit.center);
@@ -1865,7 +1824,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
} else if ((m->get_button_mask() & BUTTON_MASK_RIGHT) || freelook_active) {
-
if (nav_scheme == NAVIGATION_MAYA && m->get_alt()) {
nav_mode = NAVIGATION_ZOOM;
} else if (freelook_active) {
@@ -1875,9 +1833,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
} else if (m->get_button_mask() & BUTTON_MASK_MIDDLE) {
-
if (nav_scheme == NAVIGATION_GODOT) {
-
const int mod = _get_key_modifier(m);
if (mod == _get_key_modifier_setting("editors/3d/navigation/pan_modifier")) {
@@ -1890,8 +1846,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
} else if (nav_scheme == NAVIGATION_MAYA) {
- if (m->get_alt())
+ if (m->get_alt()) {
nav_mode = NAVIGATION_PAN;
+ }
}
} else if (EditorSettings::get_singleton()->get("editors/3d/navigation/emulate_3_button_mouse")) {
@@ -1938,21 +1895,19 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Ref<InputEventMagnifyGesture> magnify_gesture = p_event;
if (magnify_gesture.is_valid()) {
-
- if (is_freelook_active())
+ if (is_freelook_active()) {
scale_freelook_speed(magnify_gesture->get_factor());
- else
+ } else {
scale_cursor_distance(1.0 / magnify_gesture->get_factor());
+ }
}
Ref<InputEventPanGesture> pan_gesture = p_event;
if (pan_gesture.is_valid()) {
-
NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
NavigationMode nav_mode = NAVIGATION_NONE;
if (nav_scheme == NAVIGATION_GODOT) {
-
const int mod = _get_key_modifier(pan_gesture);
if (mod == _get_key_modifier_setting("editors/3d/navigation/pan_modifier")) {
@@ -1965,8 +1920,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
} else if (nav_scheme == NAVIGATION_MAYA) {
- if (pan_gesture->get_alt())
+ if (pan_gesture->get_alt()) {
nav_mode = NAVIGATION_PAN;
+ }
}
switch (nav_mode) {
@@ -1998,8 +1954,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
- if (!k->is_pressed())
+ if (!k->is_pressed()) {
return;
+ }
if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) {
if (_edit.mode != TRANSFORM_NONE) {
@@ -2042,8 +1999,9 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
_menu_option(VIEW_ALIGN_ROTATION_WITH_VIEW);
}
if (ED_IS_SHORTCUT("spatial_editor/insert_anim_key", p_event)) {
- if (!get_selected_count() || _edit.mode != TRANSFORM_NONE)
+ if (!get_selected_count() || _edit.mode != TRANSFORM_NONE) {
return;
+ }
if (!AnimationPlayerEditor::singleton->get_track_editor()->has_keying()) {
set_message(TTR("Keying is disabled (no key inserted)."));
@@ -2053,10 +2011,10 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
List<Node *> &selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
- if (!sp)
+ if (!sp) {
continue;
+ }
spatial_editor->emit_signal("transform_key_request", sp, "", sp->get_transform());
}
@@ -2073,24 +2031,27 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
if (k->get_keycode() == KEY_SPACE) {
- if (!k->is_pressed()) emit_signal("toggle_maximize_view", this);
+ if (!k->is_pressed()) {
+ emit_signal("toggle_maximize_view", this);
+ }
}
}
// freelook uses most of the useful shortcuts, like save, so its ok
// to consider freelook active as end of the line for future events.
- if (freelook_active)
+ if (freelook_active) {
accept_event();
+ }
}
void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) {
-
const NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
real_t pan_speed = 1 / 150.0;
int pan_speed_modifier = 10;
- if (nav_scheme == NAVIGATION_MAYA && p_event->get_shift())
+ if (nav_scheme == NAVIGATION_MAYA && p_event->get_shift()) {
pan_speed *= pan_speed_modifier;
+ }
Transform camera_transform;
@@ -2104,30 +2065,31 @@ void Node3DEditorViewport::_nav_pan(Ref<InputEventWithModifiers> p_event, const
}
void Node3DEditorViewport::_nav_zoom(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) {
-
const NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation/navigation_scheme").operator int();
real_t zoom_speed = 1 / 80.0;
int zoom_speed_modifier = 10;
- if (nav_scheme == NAVIGATION_MAYA && p_event->get_shift())
+ if (nav_scheme == NAVIGATION_MAYA && p_event->get_shift()) {
zoom_speed *= zoom_speed_modifier;
+ }
NavigationZoomStyle zoom_style = (NavigationZoomStyle)EditorSettings::get_singleton()->get("editors/3d/navigation/zoom_style").operator int();
if (zoom_style == NAVIGATION_ZOOM_HORIZONTAL) {
- if (p_relative.x > 0)
+ if (p_relative.x > 0) {
scale_cursor_distance(1 - p_relative.x * zoom_speed);
- else if (p_relative.x < 0)
+ } else if (p_relative.x < 0) {
scale_cursor_distance(1.0 / (1 + p_relative.x * zoom_speed));
+ }
} else {
- if (p_relative.y > 0)
+ if (p_relative.y > 0) {
scale_cursor_distance(1 + p_relative.y * zoom_speed);
- else if (p_relative.y < 0)
+ } else if (p_relative.y < 0) {
scale_cursor_distance(1.0 / (1 - p_relative.y * zoom_speed));
+ }
}
}
void Node3DEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) {
-
if (lock_rotation) {
_nav_pan(p_event, p_relative);
return;
@@ -2147,16 +2109,17 @@ void Node3DEditorViewport::_nav_orbit(Ref<InputEventWithModifiers> p_event, cons
cursor.x_rot += p_relative.y * radians_per_pixel;
}
cursor.y_rot += p_relative.x * radians_per_pixel;
- if (cursor.x_rot > Math_PI / 2.0)
+ if (cursor.x_rot > Math_PI / 2.0) {
cursor.x_rot = Math_PI / 2.0;
- if (cursor.x_rot < -Math_PI / 2.0)
+ }
+ if (cursor.x_rot < -Math_PI / 2.0) {
cursor.x_rot = -Math_PI / 2.0;
+ }
name = "";
_update_name();
}
void Node3DEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const Vector2 &p_relative) {
-
if (orthogonal) {
_nav_pan(p_event, p_relative);
return;
@@ -2166,7 +2129,7 @@ void Node3DEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const
_menu_option(VIEW_PERSPECTIVE);
}
- real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
+ real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_sensitivity");
real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
bool invert_y_axis = EditorSettings::get_singleton()->get("editors/3d/navigation/invert_y_axis");
@@ -2179,10 +2142,12 @@ void Node3DEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const
cursor.x_rot += p_relative.y * radians_per_pixel;
}
cursor.y_rot += p_relative.x * radians_per_pixel;
- if (cursor.x_rot > Math_PI / 2.0)
+ if (cursor.x_rot > Math_PI / 2.0) {
cursor.x_rot = Math_PI / 2.0;
- if (cursor.x_rot < -Math_PI / 2.0)
+ }
+ if (cursor.x_rot < -Math_PI / 2.0) {
cursor.x_rot = -Math_PI / 2.0;
+ }
// Look is like the opposite of Orbit: the focus point rotates around the camera
Transform camera_transform = to_camera_transform(cursor);
@@ -2196,7 +2161,6 @@ void Node3DEditorViewport::_nav_look(Ref<InputEventWithModifiers> p_event, const
}
void Node3DEditorViewport::set_freelook_active(bool active_now) {
-
if (!freelook_active && active_now) {
// Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential
cursor = camera_cursor;
@@ -2214,44 +2178,46 @@ void Node3DEditorViewport::set_freelook_active(bool active_now) {
}
// Hide mouse like in an FPS (warping doesn't work)
- DisplayServer::get_singleton()->mouse_set_mode(DisplayServer::MOUSE_MODE_CAPTURED);
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
} else if (freelook_active && !active_now) {
// Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential
cursor = camera_cursor;
// Restore mouse
- DisplayServer::get_singleton()->mouse_set_mode(DisplayServer::MOUSE_MODE_VISIBLE);
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
}
freelook_active = active_now;
}
void Node3DEditorViewport::scale_cursor_distance(real_t scale) {
-
// Prevents zero distance which would short-circuit any scaling
- if (cursor.distance < ZOOM_MIN_DISTANCE)
+ if (cursor.distance < ZOOM_MIN_DISTANCE) {
cursor.distance = ZOOM_MIN_DISTANCE;
+ }
cursor.distance *= scale;
- if (cursor.distance < ZOOM_MIN_DISTANCE)
+ if (cursor.distance < ZOOM_MIN_DISTANCE) {
cursor.distance = ZOOM_MIN_DISTANCE;
+ }
zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S;
surface->update();
}
void Node3DEditorViewport::scale_freelook_speed(real_t scale) {
-
// Prevents zero distance which would short-circuit any scaling
- if (freelook_speed < FREELOOK_MIN_SPEED)
+ if (freelook_speed < FREELOOK_MIN_SPEED) {
freelook_speed = FREELOOK_MIN_SPEED;
+ }
freelook_speed *= scale;
- if (freelook_speed < FREELOOK_MIN_SPEED)
+ if (freelook_speed < FREELOOK_MIN_SPEED) {
freelook_speed = FREELOOK_MIN_SPEED;
+ }
zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S;
surface->update();
@@ -2260,7 +2226,7 @@ void Node3DEditorViewport::scale_freelook_speed(real_t scale) {
Point2i Node3DEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const {
Point2i relative;
if (bool(EDITOR_DEF("editors/3d/navigation/warped_mouse_panning", false))) {
- relative = InputFilter::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect());
+ relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect());
} else {
relative = p_ev_mouse_motion->get_relative();
}
@@ -2276,20 +2242,37 @@ static bool is_shortcut_pressed(const String &p_path) {
if (k == nullptr) {
return false;
}
- const InputFilter &input = *InputFilter::get_singleton();
+ const Input &input = *Input::get_singleton();
int keycode = k->get_keycode();
return input.is_key_pressed(keycode);
}
void Node3DEditorViewport::_update_freelook(real_t delta) {
-
if (!is_freelook_active()) {
return;
}
- const Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1));
+ const FreelookNavigationScheme navigation_scheme = (FreelookNavigationScheme)EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_navigation_scheme").operator int();
+
+ Vector3 forward;
+ if (navigation_scheme == FREELOOK_FULLY_AXIS_LOCKED) {
+ // Forward/backward keys will always go straight forward/backward, never moving on the Y axis.
+ forward = Vector3(0, 0, -1).rotated(Vector3(0, 1, 0), camera->get_rotation().y);
+ } else {
+ // Forward/backward keys will be relative to the camera pitch.
+ forward = camera->get_transform().basis.xform(Vector3(0, 0, -1));
+ }
+
const Vector3 right = camera->get_transform().basis.xform(Vector3(1, 0, 0));
- const Vector3 up = camera->get_transform().basis.xform(Vector3(0, 1, 0));
+
+ Vector3 up;
+ if (navigation_scheme == FREELOOK_PARTIALLY_AXIS_LOCKED || navigation_scheme == FREELOOK_FULLY_AXIS_LOCKED) {
+ // Up/down keys will always go up/down regardless of camera pitch.
+ up = Vector3(0, 1, 0);
+ } else {
+ // Up/down keys will be relative to the camera pitch.
+ up = camera->get_transform().basis.xform(Vector3(0, 1, 0));
+ }
Vector3 direction;
@@ -2327,7 +2310,6 @@ void Node3DEditorViewport::_update_freelook(real_t delta) {
}
void Node3DEditorViewport::set_message(String p_message, float p_time) {
-
message = p_message;
message_time = p_time;
}
@@ -2342,9 +2324,7 @@ void Node3DEditorPlugin::edited_scene_changed() {
}
void Node3DEditorViewport::_notification(int p_what) {
-
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
bool visible = is_visible_in_tree();
set_process(visible);
@@ -2361,7 +2341,6 @@ void Node3DEditorViewport::_notification(int p_what) {
}
if (p_what == NOTIFICATION_RESIZED) {
-
call_deferred("update_transform_gizmo_view");
}
@@ -2373,7 +2352,6 @@ void Node3DEditorViewport::_notification(int p_what) {
}
if (p_what == NOTIFICATION_PROCESS) {
-
real_t delta = get_process_delta_time();
if (zoom_indicator_delay > 0) {
@@ -2408,20 +2386,22 @@ void Node3DEditorViewport::_notification(int p_what) {
bool exist = false;
for (Map<Node *, Object *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->key());
- if (!sp)
+ if (!sp) {
continue;
+ }
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
Transform t = sp->get_global_gizmo_transform();
exist = true;
- if (se->last_xform == t && !se->last_xform_dirty)
+ if (se->last_xform == t && !se->last_xform_dirty) {
continue;
+ }
changed = true;
se->last_xform_dirty = false;
se->last_xform = t;
@@ -2445,15 +2425,15 @@ void Node3DEditorViewport::_notification(int p_what) {
}
if (message_time > 0) {
-
if (message != last_message) {
surface->update();
last_message = message;
}
message_time -= get_physics_process_delta_time();
- if (message_time < 0)
+ if (message_time < 0) {
surface->update();
+ }
}
//update shadow atlas if changed
@@ -2531,7 +2511,6 @@ void Node3DEditorViewport::_notification(int p_what) {
cpu_time_history_index = 0;
}
if (show_fps) {
-
cpu_time_history[cpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_cpu(viewport->get_viewport_rid());
cpu_time_history_index = (cpu_time_history_index + 1) % FRAME_TIME_HISTORY;
float cpu_time = 0.0;
@@ -2570,7 +2549,6 @@ void Node3DEditorViewport::_notification(int p_what) {
}
if (p_what == NOTIFICATION_ENTER_TREE) {
-
surface->connect("draw", callable_mp(this, &Node3DEditorViewport::_draw));
surface->connect("gui_input", callable_mp(this, &Node3DEditorViewport::_sinput));
surface->connect("mouse_entered", callable_mp(this, &Node3DEditorViewport::_surface_mouse_enter));
@@ -2582,12 +2560,10 @@ void Node3DEditorViewport::_notification(int p_what) {
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
_finish_gizmo_instances();
}
if (p_what == NOTIFICATION_THEME_CHANGED) {
-
view_menu->set_icon(get_theme_icon("GuiTabMenu", "EditorIcons"));
preview_camera->set_icon(get_theme_icon("Camera3D", "EditorIcons"));
@@ -2611,7 +2587,6 @@ void Node3DEditorViewport::_notification(int p_what) {
}
static void draw_indicator_bar(Control &surface, real_t fill, Ref<Texture2D> icon) {
-
// Adjust bar size from control height
Vector2 surface_size = surface.get_size();
real_t h = surface_size.y / 2.0;
@@ -2632,7 +2607,6 @@ static void draw_indicator_bar(Control &surface, real_t fill, Ref<Texture2D> ico
}
void Node3DEditorViewport::_draw() {
-
EditorPluginList *over_plugin_list = EditorNode::get_singleton()->get_editor_plugins_over();
if (!over_plugin_list->empty()) {
over_plugin_list->forward_spatial_draw_over_viewport(surface);
@@ -2674,7 +2648,6 @@ void Node3DEditorViewport::_draw() {
}
if (_edit.mode == TRANSFORM_ROTATE) {
-
Point2 center = _point_to_screen(_edit.center);
RenderingServer::get_singleton()->canvas_item_add_line(
ci,
@@ -2684,7 +2657,6 @@ void Node3DEditorViewport::_draw() {
Math::round(2 * EDSCALE));
}
if (previewing) {
-
Size2 ss = Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"));
float aspect = ss.aspect();
Size2 s = get_size();
@@ -2693,14 +2665,12 @@ void Node3DEditorViewport::_draw() {
switch (previewing->get_keep_aspect_mode()) {
case Camera3D::KEEP_WIDTH: {
-
draw_rect.size = Size2(s.width, s.width / aspect);
draw_rect.position.x = 0;
draw_rect.position.y = (s.height - draw_rect.size.y) * 0.5;
} break;
case Camera3D::KEEP_HEIGHT: {
-
draw_rect.size = Size2(s.height * aspect, s.height);
draw_rect.position.y = 0;
draw_rect.position.x = (s.width - draw_rect.size.x) * 0.5;
@@ -2713,9 +2683,7 @@ void Node3DEditorViewport::_draw() {
surface->draw_rect(draw_rect, Color(0.6, 0.6, 0.1, 0.5), false, Math::round(2 * EDSCALE));
} else {
-
if (zoom_indicator_delay > 0.0) {
-
if (is_freelook_active()) {
// Show speed
@@ -2728,8 +2696,9 @@ void Node3DEditorViewport::_draw() {
// There is no real maximum speed so that factor can become negative,
// Let's make it look asymptotic instead (will decrease slower and slower).
- if (logscale_t < 0.25)
+ if (logscale_t < 0.25) {
logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0);
+ }
draw_indicator_bar(*surface, 1.0 - logscale_t, get_theme_icon("ViewportSpeed", "EditorIcons"));
}
@@ -2746,8 +2715,9 @@ void Node3DEditorViewport::_draw() {
// There is no real maximum distance so that factor can become negative,
// Let's make it look asymptotic instead (will decrease slower and slower).
- if (logscale_t < 0.25)
+ if (logscale_t < 0.25) {
logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0);
+ }
draw_indicator_bar(*surface, logscale_t, get_theme_icon("ViewportZoom", "EditorIcons"));
}
@@ -2757,11 +2727,8 @@ void Node3DEditorViewport::_draw() {
}
void Node3DEditorViewport::_menu_option(int p_option) {
-
switch (p_option) {
-
case VIEW_TOP: {
-
cursor.y_rot = 0;
cursor.x_rot = Math_PI / 2.0;
set_message(TTR("Top View."), 2);
@@ -2771,7 +2738,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_BOTTOM: {
-
cursor.y_rot = 0;
cursor.x_rot = -Math_PI / 2.0;
set_message(TTR("Bottom View."), 2);
@@ -2781,7 +2747,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_LEFT: {
-
cursor.x_rot = 0;
cursor.y_rot = Math_PI / 2.0;
set_message(TTR("Left View."), 2);
@@ -2791,7 +2756,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_RIGHT: {
-
cursor.x_rot = 0;
cursor.y_rot = -Math_PI / 2.0;
set_message(TTR("Right View."), 2);
@@ -2801,7 +2765,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_FRONT: {
-
cursor.x_rot = 0;
cursor.y_rot = 0;
set_message(TTR("Front View."), 2);
@@ -2811,7 +2774,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_REAR: {
-
cursor.x_rot = 0;
cursor.y_rot = Math_PI;
set_message(TTR("Rear View."), 2);
@@ -2821,19 +2783,17 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_CENTER_TO_ORIGIN: {
-
cursor.pos = Vector3(0, 0, 0);
} break;
case VIEW_CENTER_TO_SELECTION: {
-
focus_selection();
} break;
case VIEW_ALIGN_TRANSFORM_WITH_VIEW: {
-
- if (!get_selected_count())
+ if (!get_selected_count()) {
break;
+ }
Transform camera_transform = camera->get_global_transform();
@@ -2842,14 +2802,15 @@ void Node3DEditorViewport::_menu_option(int p_option) {
undo_redo->create_action(TTR("Align Transform with View"));
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
- if (!sp)
+ if (!sp) {
continue;
+ }
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
Transform xform;
if (orthogonal) {
@@ -2864,13 +2825,12 @@ void Node3DEditorViewport::_menu_option(int p_option) {
undo_redo->add_undo_method(sp, "set_global_transform", sp->get_global_gizmo_transform());
}
undo_redo->commit_action();
- focus_selection();
} break;
case VIEW_ALIGN_ROTATION_WITH_VIEW: {
-
- if (!get_selected_count())
+ if (!get_selected_count()) {
break;
+ }
Transform camera_transform = camera->get_global_transform();
@@ -2878,14 +2838,15 @@ void Node3DEditorViewport::_menu_option(int p_option) {
undo_redo->create_action(TTR("Align Rotation with View"));
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
- if (!sp)
+ if (!sp) {
continue;
+ }
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
undo_redo->add_do_method(sp, "set_rotation", camera_transform.basis.get_rotation());
undo_redo->add_undo_method(sp, "set_rotation", sp->get_rotation());
@@ -2894,15 +2855,12 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_ENVIRONMENT: {
-
int idx = view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT);
bool current = view_menu->get_popup()->is_item_checked(idx);
current = !current;
if (current) {
-
camera->set_environment(RES());
} else {
-
camera->set_environment(Node3DEditor::get_singleton()->get_viewport_environment());
}
@@ -2910,7 +2868,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_PERSPECTIVE: {
-
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), true);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL), false);
orthogonal = false;
@@ -2920,7 +2877,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_ORTHOGONAL: {
-
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), false);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL), true);
orthogonal = true;
@@ -2930,7 +2886,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_AUTO_ORTHOGONAL: {
-
int idx = view_menu->get_popup()->get_item_index(VIEW_AUTO_ORTHOGONAL);
bool current = view_menu->get_popup()->is_item_checked(idx);
current = !current;
@@ -2941,7 +2896,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
}
} break;
case VIEW_LOCK_ROTATION: {
-
int idx = view_menu->get_popup()->get_item_index(VIEW_LOCK_ROTATION);
bool current = view_menu->get_popup()->is_item_checked(idx);
lock_rotation = !current;
@@ -2954,7 +2908,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_AUDIO_LISTENER: {
-
int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER);
bool current = view_menu->get_popup()->is_item_checked(idx);
current = !current;
@@ -2963,7 +2916,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_AUDIO_DOPPLER: {
-
int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_DOPPLER);
bool current = view_menu->get_popup()->is_item_checked(idx);
current = !current;
@@ -2972,7 +2924,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
} break;
case VIEW_CINEMATIC_PREVIEW: {
-
int idx = view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW);
bool current = view_menu->get_popup()->is_item_checked(idx);
current = !current;
@@ -2983,38 +2934,36 @@ void Node3DEditorViewport::_menu_option(int p_option) {
if (current) {
preview_camera->hide();
} else {
- if (previewing != nullptr)
+ if (previewing != nullptr) {
preview_camera->show();
+ }
}
} break;
case VIEW_GIZMOS: {
-
int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS);
bool current = view_menu->get_popup()->is_item_checked(idx);
current = !current;
- if (current)
+ if (current) {
camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + index)) | (1 << GIZMO_EDIT_LAYER) | (1 << GIZMO_GRID_LAYER));
- else
+ } else {
camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + index)) | (1 << GIZMO_GRID_LAYER));
+ }
view_menu->get_popup()->set_item_checked(idx, current);
} break;
case VIEW_HALF_RESOLUTION: {
-
int idx = view_menu->get_popup()->get_item_index(VIEW_HALF_RESOLUTION);
bool current = view_menu->get_popup()->is_item_checked(idx);
current = !current;
view_menu->get_popup()->set_item_checked(idx, current);
} break;
case VIEW_INFORMATION: {
-
int idx = view_menu->get_popup()->get_item_index(VIEW_INFORMATION);
bool current = view_menu->get_popup()->is_item_checked(idx);
view_menu->get_popup()->set_item_checked(idx, !current);
} break;
case VIEW_FRAME_TIME: {
-
int idx = view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME);
bool current = view_menu->get_popup()->is_item_checked(idx);
view_menu->get_popup()->set_item_checked(idx, !current);
@@ -3036,7 +2985,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
case VIEW_DISPLAY_DEBUG_PSSM_SPLITS:
case VIEW_DISPLAY_DEBUG_DECAL_ATLAS:
case VIEW_DISPLAY_DEBUG_ROUGHNESS_LIMITER: {
-
static const int display_options[] = {
VIEW_DISPLAY_NORMAL,
VIEW_DISPLAY_WIREFRAME,
@@ -3080,7 +3028,6 @@ void Node3DEditorViewport::_menu_option(int p_option) {
int idx = 0;
while (display_options[idx] != VIEW_MAX) {
-
int id = display_options[idx];
int item_idx = view_menu->get_popup()->get_item_index(id);
if (item_idx != -1) {
@@ -3108,7 +3055,6 @@ void Node3DEditorViewport::_set_auto_orthogonal() {
}
void Node3DEditorViewport::_preview_exited_scene() {
-
preview_camera->disconnect("toggled", callable_mp(this, &Node3DEditorViewport::_toggle_camera_preview));
preview_camera->set_pressed(false);
_toggle_camera_preview(false);
@@ -3117,41 +3063,40 @@ void Node3DEditorViewport::_preview_exited_scene() {
}
void Node3DEditorViewport::_init_gizmo_instance(int p_idx) {
-
uint32_t layer = 1 << (GIZMO_BASE_LAYER + p_idx);
for (int i = 0; i < 3; i++) {
move_gizmo_instance[i] = RS::get_singleton()->instance_create();
RS::get_singleton()->instance_set_base(move_gizmo_instance[i], spatial_editor->get_move_gizmo(i)->get_rid());
- RS::get_singleton()->instance_set_scenario(move_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
+ RS::get_singleton()->instance_set_scenario(move_gizmo_instance[i], get_tree()->get_root()->get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_visible(move_gizmo_instance[i], false);
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(move_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(move_gizmo_instance[i], layer);
move_plane_gizmo_instance[i] = RS::get_singleton()->instance_create();
RS::get_singleton()->instance_set_base(move_plane_gizmo_instance[i], spatial_editor->get_move_plane_gizmo(i)->get_rid());
- RS::get_singleton()->instance_set_scenario(move_plane_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
+ RS::get_singleton()->instance_set_scenario(move_plane_gizmo_instance[i], get_tree()->get_root()->get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_visible(move_plane_gizmo_instance[i], false);
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(move_plane_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(move_plane_gizmo_instance[i], layer);
rotate_gizmo_instance[i] = RS::get_singleton()->instance_create();
RS::get_singleton()->instance_set_base(rotate_gizmo_instance[i], spatial_editor->get_rotate_gizmo(i)->get_rid());
- RS::get_singleton()->instance_set_scenario(rotate_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
+ RS::get_singleton()->instance_set_scenario(rotate_gizmo_instance[i], get_tree()->get_root()->get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_visible(rotate_gizmo_instance[i], false);
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(rotate_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(rotate_gizmo_instance[i], layer);
scale_gizmo_instance[i] = RS::get_singleton()->instance_create();
RS::get_singleton()->instance_set_base(scale_gizmo_instance[i], spatial_editor->get_scale_gizmo(i)->get_rid());
- RS::get_singleton()->instance_set_scenario(scale_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
+ RS::get_singleton()->instance_set_scenario(scale_gizmo_instance[i], get_tree()->get_root()->get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_visible(scale_gizmo_instance[i], false);
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(scale_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(scale_gizmo_instance[i], layer);
scale_plane_gizmo_instance[i] = RS::get_singleton()->instance_create();
RS::get_singleton()->instance_set_base(scale_plane_gizmo_instance[i], spatial_editor->get_scale_plane_gizmo(i)->get_rid());
- RS::get_singleton()->instance_set_scenario(scale_plane_gizmo_instance[i], get_tree()->get_root()->get_world()->get_scenario());
+ RS::get_singleton()->instance_set_scenario(scale_plane_gizmo_instance[i], get_tree()->get_root()->get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_visible(scale_plane_gizmo_instance[i], false);
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(scale_plane_gizmo_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
RS::get_singleton()->instance_set_layer_mask(scale_plane_gizmo_instance[i], layer);
@@ -3159,7 +3104,6 @@ void Node3DEditorViewport::_init_gizmo_instance(int p_idx) {
}
void Node3DEditorViewport::_finish_gizmo_instances() {
-
for (int i = 0; i < 3; i++) {
RS::get_singleton()->free(move_gizmo_instance[i]);
RS::get_singleton()->free(move_plane_gizmo_instance[i]);
@@ -3168,23 +3112,24 @@ void Node3DEditorViewport::_finish_gizmo_instances() {
RS::get_singleton()->free(scale_plane_gizmo_instance[i]);
}
}
-void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) {
+void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) {
ERR_FAIL_COND(p_activate && !preview);
ERR_FAIL_COND(!p_activate && !previewing);
- if (!p_activate) {
+ rotation_control->set_visible(!p_activate);
+ if (!p_activate) {
previewing->disconnect("tree_exiting", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
previewing = nullptr;
RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), camera->get_camera()); //restore
- if (!preview)
+ if (!preview) {
preview_camera->hide();
+ }
view_menu->set_disabled(false);
surface->update();
} else {
-
previewing = preview;
previewing->connect("tree_exiting", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), preview->get_camera()); //replace
@@ -3196,8 +3141,9 @@ void Node3DEditorViewport::_toggle_camera_preview(bool p_activate) {
void Node3DEditorViewport::_toggle_cinema_preview(bool p_activate) {
previewing_cinema = p_activate;
if (!previewing_cinema) {
- if (previewing != nullptr)
+ if (previewing != nullptr) {
previewing->disconnect("tree_exited", callable_mp(this, &Node3DEditorViewport::_preview_exited_scene));
+ }
previewing = nullptr;
RS::get_singleton()->viewport_attach_camera(viewport->get_viewport_rid(), camera->get_camera()); //restore
@@ -3213,9 +3159,9 @@ void Node3DEditorViewport::_toggle_cinema_preview(bool p_activate) {
}
void Node3DEditorViewport::_selection_result_pressed(int p_result) {
-
- if (selection_results.size() <= p_result)
+ if (selection_results.size() <= p_result) {
return;
+ }
clicked = selection_results[p_result].item->get_instance_id();
@@ -3226,24 +3172,23 @@ void Node3DEditorViewport::_selection_result_pressed(int p_result) {
}
void Node3DEditorViewport::_selection_menu_hide() {
-
selection_results.clear();
selection_menu->clear();
selection_menu->set_size(Vector2(0, 0));
}
void Node3DEditorViewport::set_can_preview(Camera3D *p_preview) {
-
preview = p_preview;
- if (!preview_camera->is_pressed() && !previewing_cinema)
+ if (!preview_camera->is_pressed() && !previewing_cinema) {
preview_camera->set_visible(p_preview);
+ }
}
void Node3DEditorViewport::update_transform_gizmo_view() {
-
- if (!is_visible_in_tree())
+ if (!is_visible_in_tree()) {
return;
+ }
Transform xform = spatial_editor->get_gizmo_transform();
@@ -3267,8 +3212,9 @@ void Node3DEditorViewport::update_transform_gizmo_view() {
float d0 = camera->unproject_position(camera_xform.origin + camz * gizmo_d).y;
float d1 = camera->unproject_position(camera_xform.origin + camz * gizmo_d + camy).y;
float dd = Math::abs(d0 - d1);
- if (dd == 0)
+ if (dd == 0) {
dd = 0.0001;
+ }
float gizmo_size = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size");
// At low viewport heights, multiply the gizmo scale based on the viewport height.
@@ -3297,23 +3243,27 @@ void Node3DEditorViewport::update_transform_gizmo_view() {
}
void Node3DEditorViewport::set_state(const Dictionary &p_state) {
-
- if (p_state.has("position"))
+ if (p_state.has("position")) {
cursor.pos = p_state["position"];
- if (p_state.has("x_rotation"))
+ }
+ if (p_state.has("x_rotation")) {
cursor.x_rot = p_state["x_rotation"];
- if (p_state.has("y_rotation"))
+ }
+ if (p_state.has("y_rotation")) {
cursor.y_rot = p_state["y_rotation"];
- if (p_state.has("distance"))
+ }
+ if (p_state.has("distance")) {
cursor.distance = p_state["distance"];
+ }
if (p_state.has("use_orthogonal")) {
bool orth = p_state["use_orthogonal"];
- if (orth)
+ if (orth) {
_menu_option(VIEW_ORTHOGONAL);
- else
+ } else {
_menu_option(VIEW_PERSPECTIVE);
+ }
}
if (p_state.has("view_name")) {
name = p_state["view_name"];
@@ -3331,8 +3281,9 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) {
int display = p_state["display_mode"];
int idx = view_menu->get_popup()->get_item_index(display);
- if (!view_menu->get_popup()->is_item_checked(idx))
+ if (!view_menu->get_popup()->is_item_checked(idx)) {
_menu_option(display);
+ }
}
if (p_state.has("lock_rotation")) {
lock_rotation = p_state["lock_rotation"];
@@ -3343,8 +3294,9 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) {
if (p_state.has("use_environment")) {
bool env = p_state["use_environment"];
- if (env != camera->get_environment().is_valid())
+ if (env != camera->get_environment().is_valid()) {
_menu_option(VIEW_ENVIRONMENT);
+ }
}
if (p_state.has("listener")) {
bool listener = p_state["listener"];
@@ -3364,22 +3316,25 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) {
bool gizmos = p_state["gizmos"];
int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS);
- if (view_menu->get_popup()->is_item_checked(idx) != gizmos)
+ if (view_menu->get_popup()->is_item_checked(idx) != gizmos) {
_menu_option(VIEW_GIZMOS);
+ }
}
if (p_state.has("information")) {
bool information = p_state["information"];
int idx = view_menu->get_popup()->get_item_index(VIEW_INFORMATION);
- if (view_menu->get_popup()->is_item_checked(idx) != information)
+ if (view_menu->get_popup()->is_item_checked(idx) != information) {
_menu_option(VIEW_INFORMATION);
+ }
}
if (p_state.has("frame_time")) {
bool fps = p_state["frame_time"];
int idx = view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME);
- if (view_menu->get_popup()->is_item_checked(idx) != fps)
+ if (view_menu->get_popup()->is_item_checked(idx) != fps) {
_menu_option(VIEW_FRAME_TIME);
+ }
}
if (p_state.has("half_res")) {
bool half_res = p_state["half_res"];
@@ -3413,7 +3368,6 @@ void Node3DEditorViewport::set_state(const Dictionary &p_state) {
}
Dictionary Node3DEditorViewport::get_state() const {
-
Dictionary d;
d["position"] = cursor.pos;
d["x_rotation"] = cursor.x_rot;
@@ -3424,14 +3378,15 @@ Dictionary Node3DEditorViewport::get_state() const {
d["view_name"] = name;
d["auto_orthogonal"] = auto_orthogonal;
d["auto_orthogonal_enabled"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUTO_ORTHOGONAL));
- if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL)))
+ if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL))) {
d["display_mode"] = VIEW_DISPLAY_NORMAL;
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME))) {
d["display_mode"] = VIEW_DISPLAY_WIREFRAME;
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW))) {
d["display_mode"] = VIEW_DISPLAY_OVERDRAW;
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS))) {
d["display_mode"] = VIEW_DISPLAY_SHADELESS;
+ }
d["listener"] = viewport->is_audio_listener();
d["doppler"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_DOPPLER));
d["gizmos"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS));
@@ -3439,16 +3394,17 @@ Dictionary Node3DEditorViewport::get_state() const {
d["frame_time"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_FRAME_TIME));
d["half_res"] = subviewport_container->get_stretch_shrink() > 1;
d["cinematic_preview"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_CINEMATIC_PREVIEW));
- if (previewing)
+ if (previewing) {
d["previewing"] = EditorNode::get_singleton()->get_edited_scene()->get_path_to(previewing);
- if (lock_rotation)
+ }
+ if (lock_rotation) {
d["lock_rotation"] = lock_rotation;
+ }
return d;
}
void Node3DEditorViewport::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("update_transform_gizmo_view"), &Node3DEditorViewport::update_transform_gizmo_view); // Used by call_deferred.
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &Node3DEditorViewport::can_drop_data_fw);
ClassDB::bind_method(D_METHOD("drop_data_fw"), &Node3DEditorViewport::drop_data_fw);
@@ -3458,7 +3414,6 @@ void Node3DEditorViewport::_bind_methods() {
}
void Node3DEditorViewport::reset() {
-
orthogonal = false;
auto_orthogonal = false;
lock_rotation = false;
@@ -3476,8 +3431,9 @@ void Node3DEditorViewport::reset() {
}
void Node3DEditorViewport::focus_selection() {
- if (!get_selected_count())
+ if (!get_selected_count()) {
return;
+ }
Vector3 center;
int count = 0;
@@ -3485,14 +3441,15 @@ void Node3DEditorViewport::focus_selection() {
List<Node *> &selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
- if (!sp)
+ if (!sp) {
continue;
+ }
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
center += sp->get_global_gizmo_transform().origin;
count++;
@@ -3517,7 +3474,7 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
Vector3 world_ray = _get_ray(p_pos);
Vector3 world_pos = _get_ray_pos(p_pos);
- Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(world_pos, world_ray, get_tree()->get_root()->get_world()->get_scenario());
+ Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(world_pos, world_ray, get_tree()->get_root()->get_world_3d()->get_scenario());
Set<Ref<EditorNode3DGizmo>> found_gizmos;
float closest_dist = MAX_DISTANCE;
@@ -3526,11 +3483,11 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
Vector3 normal = Vector3(0.0, 0.0, 0.0);
for (int i = 0; i < instances.size(); i++) {
-
MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(ObjectDB::get_instance(instances[i]));
- if (!mesh_instance)
+ if (!mesh_instance) {
continue;
+ }
Ref<EditorNode3DGizmo> seg = mesh_instance->get_gizmo();
@@ -3544,13 +3501,15 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
Vector3 hit_normal;
bool inters = seg->intersect_ray(camera, p_pos, hit_point, hit_normal, nullptr, false);
- if (!inters)
+ if (!inters) {
continue;
+ }
float dist = world_pos.distance_to(hit_point);
- if (dist < 0)
+ if (dist < 0) {
continue;
+ }
if (dist < closest_dist) {
closest_dist = dist;
@@ -3560,10 +3519,11 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
}
Vector3 offset = Vector3();
for (int i = 0; i < 3; i++) {
- if (normal[i] > 0.0)
+ if (normal[i] > 0.0) {
offset[i] = (preview_bounds->get_size()[i] - (preview_bounds->get_size()[i] + preview_bounds->get_position()[i]));
- else if (normal[i] < 0.0)
+ } else if (normal[i] < 0.0) {
offset[i] = -(preview_bounds->get_size()[i] + preview_bounds->get_position()[i]);
+ }
}
return point + offset;
}
@@ -3703,8 +3663,9 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po
Transform global_transform;
Node3D *parent_spatial = Object::cast_to<Node3D>(parent);
- if (parent_spatial)
+ if (parent_spatial) {
global_transform = parent_spatial->get_global_gizmo_transform();
+ }
global_transform.origin = spatial_editor->snap_point(_get_instance_position(p_point));
@@ -3750,7 +3711,6 @@ void Node3DEditorViewport::_perform_drop_data() {
}
bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
bool can_instance = false;
if (!preview_node->is_inside_tree()) {
@@ -3807,10 +3767,11 @@ bool Node3DEditorViewport::can_drop_data_fw(const Point2 &p_point, const Variant
}
void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
- if (!can_drop_data_fw(p_point, p_data, p_from))
+ if (!can_drop_data_fw(p_point, p_data, p_from)) {
return;
+ }
- bool is_shift = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
+ bool is_shift = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
selected_files.clear();
Dictionary d = p_data;
@@ -3847,14 +3808,13 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_
}
Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, EditorNode *p_editor, int p_index) {
-
cpu_time_history_index = 0;
gpu_time_history_index = 0;
_edit.mode = TRANSFORM_NONE;
_edit.plane = TRANSFORM_VIEW;
_edit.edited_gizmo = 0;
- _edit.snap = 1;
+ _edit.snap = true;
_edit.gizmo_handle = 0;
index = p_index;
@@ -4101,11 +4061,9 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
//////////////////////////////////////////////////////////////
void Node3DEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) {
-
if (mb->is_pressed()) {
Vector2 size = get_size();
@@ -4124,25 +4082,21 @@ void Node3DEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event) {
switch (view) {
case VIEW_USE_1_VIEWPORT: {
-
dragging_h = false;
dragging_v = false;
} break;
case VIEW_USE_2_VIEWPORTS: {
-
dragging_h = false;
} break;
case VIEW_USE_2_VIEWPORTS_ALT: {
-
dragging_v = false;
} break;
case VIEW_USE_3_VIEWPORTS:
case VIEW_USE_3_VIEWPORTS_ALT:
case VIEW_USE_4_VIEWPORTS: {
-
// Do nothing.
} break;
@@ -4156,7 +4110,6 @@ void Node3DEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
if (view == VIEW_USE_3_VIEWPORTS || view == VIEW_USE_3_VIEWPORTS_ALT || view == VIEW_USE_4_VIEWPORTS) {
Vector2 size = get_size();
@@ -4194,15 +4147,12 @@ void Node3DEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event) {
}
void Node3DEditorViewportContainer::_notification(int p_what) {
-
if (p_what == NOTIFICATION_MOUSE_ENTER || p_what == NOTIFICATION_MOUSE_EXIT) {
-
mouseover = (p_what == NOTIFICATION_MOUSE_ENTER);
update();
}
if (p_what == NOTIFICATION_DRAW && mouseover) {
-
Ref<Texture2D> h_grabber = get_theme_icon("grabber", "HSplitContainer");
Ref<Texture2D> v_grabber = get_theme_icon("grabber", "VSplitContainer");
@@ -4223,26 +4173,21 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
int size_bottom = size.height - mid_h - v_sep / 2;
switch (view) {
-
case VIEW_USE_1_VIEWPORT: {
-
// Nothing to show.
} break;
case VIEW_USE_2_VIEWPORTS: {
-
draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
set_default_cursor_shape(CURSOR_VSPLIT);
} break;
case VIEW_USE_2_VIEWPORTS_ALT: {
-
draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
set_default_cursor_shape(CURSOR_HSPLIT);
} break;
case VIEW_USE_3_VIEWPORTS: {
-
if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
draw_texture(hdiag_grabber, Vector2(mid_w - hdiag_grabber->get_width() / 2, mid_h - v_grabber->get_height() / 4));
set_default_cursor_shape(CURSOR_DRAG);
@@ -4256,7 +4201,6 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
} break;
case VIEW_USE_3_VIEWPORTS_ALT: {
-
if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
draw_texture(vdiag_grabber, Vector2(mid_w - vdiag_grabber->get_width() + v_grabber->get_height() / 4, mid_h - vdiag_grabber->get_height() / 2));
set_default_cursor_shape(CURSOR_DRAG);
@@ -4270,7 +4214,6 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
} break;
case VIEW_USE_4_VIEWPORTS: {
-
Vector2 half(mid_w, mid_h);
if ((hovering_v && hovering_h && !dragging_v && !dragging_h) || (dragging_v && dragging_h)) {
draw_texture(vh_grabber, half - vh_grabber->get_size() / 2.0);
@@ -4288,7 +4231,6 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
}
if (p_what == NOTIFICATION_SORT_CHILDREN) {
-
Node3DEditorViewport *viewports[4];
int vc = 0;
for (int i = 0; i < get_child_count(); i++) {
@@ -4322,12 +4264,9 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
int size_bottom = size.height - mid_h - v_sep / 2;
switch (view) {
-
case VIEW_USE_1_VIEWPORT: {
-
viewports[0]->show();
for (int i = 1; i < 4; i++) {
-
viewports[i]->hide();
}
@@ -4335,13 +4274,12 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
} break;
case VIEW_USE_2_VIEWPORTS: {
-
for (int i = 0; i < 4; i++) {
-
- if (i == 1 || i == 3)
+ if (i == 1 || i == 3) {
viewports[i]->hide();
- else
+ } else {
viewports[i]->show();
+ }
}
fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
@@ -4349,26 +4287,24 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
} break;
case VIEW_USE_2_VIEWPORTS_ALT: {
-
for (int i = 0; i < 4; i++) {
-
- if (i == 1 || i == 3)
+ if (i == 1 || i == 3) {
viewports[i]->hide();
- else
+ } else {
viewports[i]->show();
+ }
}
fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size.height)));
fit_child_in_rect(viewports[2], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size.height)));
} break;
case VIEW_USE_3_VIEWPORTS: {
-
for (int i = 0; i < 4; i++) {
-
- if (i == 1)
+ if (i == 1) {
viewports[i]->hide();
- else
+ } else {
viewports[i]->show();
+ }
}
fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
@@ -4377,13 +4313,12 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
} break;
case VIEW_USE_3_VIEWPORTS_ALT: {
-
for (int i = 0; i < 4; i++) {
-
- if (i == 1)
+ if (i == 1) {
viewports[i]->hide();
- else
+ } else {
viewports[i]->show();
+ }
}
fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size_top)));
@@ -4392,9 +4327,7 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
} break;
case VIEW_USE_4_VIEWPORTS: {
-
for (int i = 0; i < 4; i++) {
-
viewports[i]->show();
}
@@ -4409,23 +4342,19 @@ void Node3DEditorViewportContainer::_notification(int p_what) {
}
void Node3DEditorViewportContainer::set_view(View p_view) {
-
view = p_view;
queue_sort();
}
Node3DEditorViewportContainer::View Node3DEditorViewportContainer::get_view() {
-
return view;
}
void Node3DEditorViewportContainer::_bind_methods() {
-
ClassDB::bind_method("_gui_input", &Node3DEditorViewportContainer::_gui_input);
}
Node3DEditorViewportContainer::Node3DEditorViewportContainer() {
-
set_clip_contents(true);
view = VIEW_USE_1_VIEWPORT;
mouseover = false;
@@ -4442,15 +4371,13 @@ Node3DEditorViewportContainer::Node3DEditorViewportContainer() {
Node3DEditor *Node3DEditor::singleton = nullptr;
Node3DEditorSelectedItem::~Node3DEditorSelectedItem() {
-
- if (sbox_instance.is_valid())
+ if (sbox_instance.is_valid()) {
RenderingServer::get_singleton()->free(sbox_instance);
+ }
}
void Node3DEditor::select_gizmo_highlight_axis(int p_axis) {
-
for (int i = 0; i < 3; i++) {
-
move_gizmo[i]->surface_set_material(0, i == p_axis ? gizmo_color_hl[i] : gizmo_color[i]);
move_plane_gizmo[i]->surface_set_material(0, (i + 6) == p_axis ? plane_gizmo_color_hl[i] : plane_gizmo_color[i]);
rotate_gizmo[i]->surface_set_material(0, (i + 3) == p_axis ? gizmo_color_hl[i] : gizmo_color[i]);
@@ -4460,7 +4387,6 @@ void Node3DEditor::select_gizmo_highlight_axis(int p_axis) {
}
void Node3DEditor::update_transform_gizmo() {
-
List<Node *> &selection = editor_selection->get_selected_node_list();
AABB center;
bool first = true;
@@ -4469,14 +4395,15 @@ void Node3DEditor::update_transform_gizmo() {
bool local_gizmo_coords = are_local_coords_enabled();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
- if (!sp)
+ if (!sp) {
continue;
+ }
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
Transform xf = se->sp->get_global_gizmo_transform();
@@ -4522,22 +4449,21 @@ void Node3DEditor::update_all_gizmos(Node *p_node) {
}
Object *Node3DEditor::_get_editor_data(Object *p_what) {
-
Node3D *sp = Object::cast_to<Node3D>(p_what);
- if (!sp)
+ if (!sp) {
return nullptr;
+ }
Node3DEditorSelectedItem *si = memnew(Node3DEditorSelectedItem);
si->sp = sp;
- si->sbox_instance = RenderingServer::get_singleton()->instance_create2(selection_box->get_rid(), sp->get_world()->get_scenario());
+ si->sbox_instance = RenderingServer::get_singleton()->instance_create2(selection_box->get_rid(), sp->get_world_3d()->get_scenario());
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(si->sbox_instance, RS::SHADOW_CASTING_SETTING_OFF);
return si;
}
void Node3DEditor::_generate_selection_box() {
-
AABB aabb(Vector3(), Vector3(1, 1, 1));
aabb.grow_by(aabb.get_longest_axis_size() / 20.0);
@@ -4545,17 +4471,16 @@ void Node3DEditor::_generate_selection_box() {
st->begin(Mesh::PRIMITIVE_LINES);
for (int i = 0; i < 12; i++) {
-
Vector3 a, b;
aabb.get_edge(i, a, b);
st->add_color(Color(1.0, 1.0, 0.8, 0.8));
st->add_vertex(a);
st->add_color(Color(1.0, 1.0, 0.8, 0.4));
- st->add_vertex(a.linear_interpolate(b, 0.2));
+ st->add_vertex(a.lerp(b, 0.2));
st->add_color(Color(1.0, 1.0, 0.8, 0.4));
- st->add_vertex(a.linear_interpolate(b, 0.8));
+ st->add_vertex(a.lerp(b, 0.8));
st->add_color(Color(1.0, 1.0, 0.8, 0.8));
st->add_vertex(b);
}
@@ -4571,7 +4496,6 @@ void Node3DEditor::_generate_selection_box() {
}
Dictionary Node3DEditor::get_state() const {
-
Dictionary d;
d["snap_enabled"] = snap_enabled;
@@ -4582,18 +4506,19 @@ Dictionary Node3DEditor::get_state() const {
d["local_coords"] = tool_option_button[TOOL_OPT_LOCAL_COORDS]->is_pressed();
int vc = 0;
- if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT)))
+ if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT))) {
vc = 1;
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS))) {
vc = 2;
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS))) {
vc = 3;
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS))) {
vc = 4;
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT))) {
vc = 5;
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT))) {
vc = 6;
+ }
d["viewport_mode"] = vc;
Array vpdata;
@@ -4611,7 +4536,9 @@ Dictionary Node3DEditor::get_state() const {
Dictionary gizmos_status;
for (int i = 0; i < gizmo_plugins_by_name.size(); i++) {
- if (!gizmo_plugins_by_name[i]->can_be_hidden()) continue;
+ if (!gizmo_plugins_by_name[i]->can_be_hidden()) {
+ continue;
+ }
int state = gizmos_menu->get_item_state(gizmos_menu->get_item_index(i));
String name = gizmo_plugins_by_name[i]->get_name();
gizmos_status[name] = state;
@@ -4621,8 +4548,8 @@ Dictionary Node3DEditor::get_state() const {
return d;
}
-void Node3DEditor::set_state(const Dictionary &p_state) {
+void Node3DEditor::set_state(const Dictionary &p_state) {
Dictionary d = p_state;
if (d.has("snap_enabled")) {
@@ -4630,14 +4557,17 @@ void Node3DEditor::set_state(const Dictionary &p_state) {
tool_option_button[TOOL_OPT_USE_SNAP]->set_pressed(d["snap_enabled"]);
}
- if (d.has("translate_snap"))
+ if (d.has("translate_snap")) {
snap_translate_value = d["translate_snap"];
+ }
- if (d.has("rotate_snap"))
+ if (d.has("rotate_snap")) {
snap_rotate_value = d["rotate_snap"];
+ }
- if (d.has("scale_snap"))
+ if (d.has("scale_snap")) {
snap_scale_value = d["scale_snap"];
+ }
_snap_update();
@@ -4649,18 +4579,19 @@ void Node3DEditor::set_state(const Dictionary &p_state) {
if (d.has("viewport_mode")) {
int vc = d["viewport_mode"];
- if (vc == 1)
+ if (vc == 1) {
_menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT);
- else if (vc == 2)
+ } else if (vc == 2) {
_menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS);
- else if (vc == 3)
+ } else if (vc == 3) {
_menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS);
- else if (vc == 4)
+ } else if (vc == 4) {
_menu_item_pressed(MENU_VIEW_USE_4_VIEWPORTS);
- else if (vc == 5)
+ } else if (vc == 5) {
_menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS_ALT);
- else if (vc == 6)
+ } else if (vc == 6) {
_menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS_ALT);
+ }
}
if (d.has("viewports")) {
@@ -4676,12 +4607,15 @@ void Node3DEditor::set_state(const Dictionary &p_state) {
}
}
- if (d.has("zfar"))
+ if (d.has("zfar")) {
settings_zfar->set_value(float(d["zfar"]));
- if (d.has("znear"))
+ }
+ if (d.has("znear")) {
settings_znear->set_value(float(d["znear"]));
- if (d.has("fov"))
+ }
+ if (d.has("fov")) {
settings_fov->set_value(float(d["fov"]));
+ }
if (d.has("show_grid")) {
bool use = d["show_grid"];
@@ -4705,7 +4639,9 @@ void Node3DEditor::set_state(const Dictionary &p_state) {
gizmos_status.get_key_list(&keys);
for (int j = 0; j < gizmo_plugins_by_name.size(); ++j) {
- if (!gizmo_plugins_by_name[j]->can_be_hidden()) continue;
+ if (!gizmo_plugins_by_name[j]->can_be_hidden()) {
+ continue;
+ }
int state = EditorNode3DGizmoPlugin::VISIBLE;
for (int i = 0; i < keys.size(); i++) {
if (gizmo_plugins_by_name.write[j]->get_name() == keys[i]) {
@@ -4721,10 +4657,8 @@ void Node3DEditor::set_state(const Dictionary &p_state) {
}
void Node3DEditor::edit(Node3D *p_spatial) {
-
if (p_spatial != selected) {
if (selected) {
-
Ref<EditorNode3DGizmo> seg = selected->get_gizmo();
if (seg.is_valid()) {
seg->set_selected(false);
@@ -4736,7 +4670,6 @@ void Node3DEditor::edit(Node3D *p_spatial) {
over_gizmo_handle = -1;
if (selected) {
-
Ref<EditorNode3DGizmo> seg = selected->get_gizmo();
if (seg.is_valid()) {
seg->set_selected(true);
@@ -4747,21 +4680,18 @@ void Node3DEditor::edit(Node3D *p_spatial) {
}
void Node3DEditor::_snap_changed() {
-
snap_translate_value = snap_translate->get_text().to_double();
snap_rotate_value = snap_rotate->get_text().to_double();
snap_scale_value = snap_scale->get_text().to_double();
}
void Node3DEditor::_snap_update() {
-
snap_translate->set_text(String::num(snap_translate_value));
snap_rotate->set_text(String::num(snap_rotate_value));
snap_scale->set_text(String::num(snap_scale_value));
}
void Node3DEditor::_xform_dialog_action() {
-
Transform t;
//translation
Vector3 scale;
@@ -4783,22 +4713,22 @@ void Node3DEditor::_xform_dialog_action() {
List<Node *> &selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *sp = Object::cast_to<Node3D>(E->get());
- if (!sp)
+ if (!sp) {
continue;
+ }
Node3DEditorSelectedItem *se = editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(sp);
- if (!se)
+ if (!se) {
continue;
+ }
bool post = xform_type->get_selected() > 0;
Transform tr = sp->get_global_gizmo_transform();
- if (post)
+ if (post) {
tr = tr * t;
- else {
-
+ } else {
tr.basis = t.basis * tr.basis;
tr.origin += t.origin;
}
@@ -4810,10 +4740,8 @@ void Node3DEditor::_xform_dialog_action() {
}
void Node3DEditor::_menu_item_toggled(bool pressed, int p_option) {
-
switch (p_option) {
case MENU_TOOL_LOCAL_COORDS: {
-
tool_option_button[TOOL_OPT_LOCAL_COORDS]->set_pressed(pressed);
update_transform_gizmo();
} break;
@@ -4828,7 +4756,6 @@ void Node3DEditor::_menu_item_toggled(bool pressed, int p_option) {
using Override = EditorDebuggerNode::CameraOverride;
if (pressed) {
-
debugger->set_camera_override((Override)(Override::OVERRIDE_3D_1 + camera_override_viewport_id));
} else {
debugger->set_camera_override(Override::OVERRIDE_NONE);
@@ -4839,7 +4766,6 @@ void Node3DEditor::_menu_item_toggled(bool pressed, int p_option) {
}
void Node3DEditor::_menu_gizmo_toggled(int p_option) {
-
const int idx = gizmos_menu->get_item_index(p_option);
gizmos_menu->toggle_item_multistate(idx);
@@ -4878,8 +4804,9 @@ void Node3DEditor::_update_camera_override_button(bool p_game_running) {
void Node3DEditor::_update_camera_override_viewport(Object *p_viewport) {
Node3DEditorViewport *current_viewport = Object::cast_to<Node3DEditorViewport>(p_viewport);
- if (!current_viewport)
+ if (!current_viewport) {
return;
+ }
EditorDebuggerNode *const debugger = EditorDebuggerNode::get_singleton();
@@ -4892,29 +4819,24 @@ void Node3DEditor::_update_camera_override_viewport(Object *p_viewport) {
}
void Node3DEditor::_menu_item_pressed(int p_option) {
-
switch (p_option) {
-
case MENU_TOOL_SELECT:
case MENU_TOOL_MOVE:
case MENU_TOOL_ROTATE:
case MENU_TOOL_SCALE:
case MENU_TOOL_LIST_SELECT: {
-
- for (int i = 0; i < TOOL_MAX; i++)
+ for (int i = 0; i < TOOL_MAX; i++) {
tool_button[i]->set_pressed(i == p_option);
+ }
tool_mode = (ToolMode)p_option;
update_transform_gizmo();
} break;
case MENU_TRANSFORM_CONFIGURE_SNAP: {
-
snap_dialog->popup_centered(Size2(200, 180));
} break;
case MENU_TRANSFORM_DIALOG: {
-
for (int i = 0; i < 3; i++) {
-
xform_translate[i]->set_text("0");
xform_rotate[i]->set_text("0");
xform_scale[i]->set_text("1");
@@ -4924,7 +4846,6 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_1_VIEWPORT: {
-
viewport_base->set_view(Node3DEditorViewportContainer::VIEW_USE_1_VIEWPORT);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), true);
@@ -4936,7 +4857,6 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_2_VIEWPORTS: {
-
viewport_base->set_view(Node3DEditorViewportContainer::VIEW_USE_2_VIEWPORTS);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false);
@@ -4948,7 +4868,6 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_2_VIEWPORTS_ALT: {
-
viewport_base->set_view(Node3DEditorViewportContainer::VIEW_USE_2_VIEWPORTS_ALT);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false);
@@ -4960,7 +4879,6 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_3_VIEWPORTS: {
-
viewport_base->set_view(Node3DEditorViewportContainer::VIEW_USE_3_VIEWPORTS);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false);
@@ -4972,7 +4890,6 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_3_VIEWPORTS_ALT: {
-
viewport_base->set_view(Node3DEditorViewportContainer::VIEW_USE_3_VIEWPORTS_ALT);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false);
@@ -4984,7 +4901,6 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_4_VIEWPORTS: {
-
viewport_base->set_view(Node3DEditorViewportContainer::VIEW_USE_4_VIEWPORTS);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false);
@@ -4996,7 +4912,6 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_ORIGIN: {
-
bool is_checked = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(p_option));
origin_enabled = !is_checked;
@@ -5008,7 +4923,6 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(p_option), origin_enabled);
} break;
case MENU_VIEW_GRID: {
-
bool is_checked = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(p_option));
grid_enabled = !is_checked;
@@ -5024,7 +4938,6 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_CAMERA_SETTINGS: {
-
settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50));
} break;
case MENU_SNAP_TO_FLOOR: {
@@ -5036,13 +4949,14 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
List<Node *> &selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *spatial = Object::cast_to<Node3D>(E->get());
- if (!spatial || !spatial->is_visible_in_tree())
+ if (!spatial || !spatial->is_visible_in_tree()) {
continue;
+ }
- if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
+ }
undo_redo->add_do_method(spatial, "set_meta", "_edit_lock_", true);
undo_redo->add_undo_method(spatial, "remove_meta", "_edit_lock_");
@@ -5060,13 +4974,14 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
List<Node *> &selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *spatial = Object::cast_to<Node3D>(E->get());
- if (!spatial || !spatial->is_visible_in_tree())
+ if (!spatial || !spatial->is_visible_in_tree()) {
continue;
+ }
- if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
+ }
undo_redo->add_do_method(spatial, "remove_meta", "_edit_lock_");
undo_redo->add_undo_method(spatial, "set_meta", "_edit_lock_", true);
@@ -5084,13 +4999,14 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
List<Node *> &selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *spatial = Object::cast_to<Node3D>(E->get());
- if (!spatial || !spatial->is_visible_in_tree())
+ if (!spatial || !spatial->is_visible_in_tree()) {
continue;
+ }
- if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
+ }
undo_redo->add_do_method(spatial, "set_meta", "_edit_group_", true);
undo_redo->add_undo_method(spatial, "remove_meta", "_edit_group_");
@@ -5107,13 +5023,14 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
List<Node *> &selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
Node3D *spatial = Object::cast_to<Node3D>(E->get());
- if (!spatial || !spatial->is_visible_in_tree())
+ if (!spatial || !spatial->is_visible_in_tree()) {
continue;
+ }
- if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root())
+ if (spatial->get_viewport() != EditorNode::get_singleton()->get_scene_root()) {
continue;
+ }
undo_redo->add_do_method(spatial, "remove_meta", "_edit_group_");
undo_redo->add_undo_method(spatial, "set_meta", "_edit_group_", true);
@@ -5129,7 +5046,6 @@ void Node3DEditor::_menu_item_pressed(int p_option) {
}
void Node3DEditor::_init_indicators() {
-
{
origin_enabled = true;
grid_enabled = true;
@@ -5184,18 +5100,16 @@ void Node3DEditor::_init_indicators() {
RenderingServer::get_singleton()->mesh_add_surface_from_arrays(origin, RenderingServer::PRIMITIVE_LINES, d);
RenderingServer::get_singleton()->mesh_surface_set_material(origin, 0, indicator_mat->get_rid());
- origin_instance = RenderingServer::get_singleton()->instance_create2(origin, get_tree()->get_root()->get_world()->get_scenario());
+ origin_instance = RenderingServer::get_singleton()->instance_create2(origin, get_tree()->get_root()->get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_layer_mask(origin_instance, 1 << Node3DEditorViewport::GIZMO_GRID_LAYER);
RenderingServer::get_singleton()->instance_geometry_set_cast_shadows_setting(origin_instance, RS::SHADOW_CASTING_SETTING_OFF);
}
{
-
//move gizmo
for (int i = 0; i < 3; i++) {
-
Color col;
switch (i) {
case 0:
@@ -5243,7 +5157,6 @@ void Node3DEditor::_init_indicators() {
//translate
{
-
Ref<SurfaceTool> surftool = memnew(SurfaceTool);
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
@@ -5260,12 +5173,10 @@ void Node3DEditor::_init_indicators() {
int arrow_sides = 16;
for (int k = 0; k < arrow_sides; k++) {
-
Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides);
Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides);
for (int j = 0; j < arrow_points - 1; j++) {
-
Vector3 points[4] = {
ma.xform(arrow[j]),
mb.xform(arrow[j]),
@@ -5332,7 +5243,6 @@ void Node3DEditor::_init_indicators() {
// Rotate
{
-
Ref<SurfaceTool> surftool = memnew(SurfaceTool);
surftool->begin(Mesh::PRIMITIVE_TRIANGLES);
@@ -5345,12 +5255,10 @@ void Node3DEditor::_init_indicators() {
};
for (int k = 0; k < 64; k++) {
-
Basis ma(ivec, Math_PI * 2 * float(k) / 64);
Basis mb(ivec, Math_PI * 2 * float(k + 1) / 64);
for (int j = 0; j < 4; j++) {
-
Vector3 points[4] = {
ma.xform(circle[j]),
mb.xform(circle[j]),
@@ -5390,12 +5298,10 @@ void Node3DEditor::_init_indicators() {
int arrow_sides = 4;
for (int k = 0; k < 4; k++) {
-
Basis ma(ivec, Math_PI * 2 * float(k) / arrow_sides);
Basis mb(ivec, Math_PI * 2 * float(k + 1) / arrow_sides);
for (int j = 0; j < arrow_points - 1; j++) {
-
Vector3 points[4] = {
ma.xform(arrow[j]),
mb.xform(arrow[j]),
@@ -5466,11 +5372,12 @@ void Node3DEditor::_init_indicators() {
}
void Node3DEditor::_update_gizmos_menu() {
-
gizmos_menu->clear();
for (int i = 0; i < gizmo_plugins_by_name.size(); ++i) {
- if (!gizmo_plugins_by_name[i]->can_be_hidden()) continue;
+ if (!gizmo_plugins_by_name[i]->can_be_hidden()) {
+ continue;
+ }
String plugin_name = gizmo_plugins_by_name[i]->get_name();
const int plugin_state = gizmo_plugins_by_name[i]->get_state();
gizmos_menu->add_multistate_item(TTR(plugin_name), 3, plugin_state, i);
@@ -5491,7 +5398,9 @@ void Node3DEditor::_update_gizmos_menu() {
void Node3DEditor::_update_gizmos_menu_theme() {
for (int i = 0; i < gizmo_plugins_by_name.size(); ++i) {
- if (!gizmo_plugins_by_name[i]->can_be_hidden()) continue;
+ if (!gizmo_plugins_by_name[i]->can_be_hidden()) {
+ continue;
+ }
const int plugin_state = gizmo_plugins_by_name[i]->get_state();
const int idx = gizmos_menu->get_item_index(i);
switch (plugin_state) {
@@ -5509,7 +5418,6 @@ void Node3DEditor::_update_gizmos_menu_theme() {
}
void Node3DEditor::_init_grid() {
-
Vector<Color> grid_colors[3];
Vector<Vector3> grid_points[3];
@@ -5559,7 +5467,7 @@ void Node3DEditor::_init_grid() {
d[RenderingServer::ARRAY_COLOR] = grid_colors[i];
RenderingServer::get_singleton()->mesh_add_surface_from_arrays(grid[i], RenderingServer::PRIMITIVE_LINES, d);
RenderingServer::get_singleton()->mesh_surface_set_material(grid[i], 0, indicator_mat->get_rid());
- grid_instance[i] = RenderingServer::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world()->get_scenario());
+ grid_instance[i] = RenderingServer::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world_3d()->get_scenario());
RenderingServer::get_singleton()->instance_set_visible(grid_instance[i], grid_visible[i]);
RenderingServer::get_singleton()->instance_geometry_set_cast_shadows_setting(grid_instance[i], RS::SHADOW_CASTING_SETTING_OFF);
@@ -5568,7 +5476,6 @@ void Node3DEditor::_init_grid() {
}
void Node3DEditor::_finish_indicators() {
-
RenderingServer::get_singleton()->free(origin_instance);
RenderingServer::get_singleton()->free(origin);
@@ -5584,14 +5491,14 @@ void Node3DEditor::_finish_grid() {
bool Node3DEditor::is_any_freelook_active() const {
for (unsigned int i = 0; i < VIEWPORTS_COUNT; ++i) {
- if (viewports[i]->is_freelook_active())
+ if (viewports[i]->is_freelook_active()) {
return true;
+ }
}
return false;
}
void Node3DEditor::_refresh_menu_icons() {
-
bool all_locked = true;
bool all_grouped = true;
@@ -5704,7 +5611,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
}
}
- PhysicsDirectSpaceState3D *ss = get_tree()->get_root()->get_world()->get_direct_space_state();
+ PhysicsDirectSpaceState3D *ss = get_tree()->get_root()->get_world_3d()->get_direct_space_state();
PhysicsDirectSpaceState3D::RayResult result;
Array keys = snap_data.keys();
@@ -5763,16 +5670,15 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
}
void Node3DEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
-
- if (!is_visible_in_tree())
+ if (!is_visible_in_tree()) {
return;
+ }
- snap_key_enabled = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
+ snap_key_enabled = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
}
-void Node3DEditor::_notification(int p_what) {
+void Node3DEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
-
tool_button[Node3DEditor::TOOL_MODE_SELECT]->set_icon(get_theme_icon("ToolSelect", "EditorIcons"));
tool_button[Node3DEditor::TOOL_MODE_MOVE]->set_icon(get_theme_icon("ToolMove", "EditorIcons"));
tool_button[Node3DEditor::TOOL_MODE_ROTATE]->set_icon(get_theme_icon("ToolRotate", "EditorIcons"));
@@ -5805,14 +5711,12 @@ void Node3DEditor::_notification(int p_what) {
editor->connect("stop_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(false));
editor->connect("play_pressed", callable_mp(this, &Node3DEditor::_update_camera_override_button), make_binds(true));
} else if (p_what == NOTIFICATION_ENTER_TREE) {
-
_register_all_gizmos();
_update_gizmos_menu();
_init_indicators();
} else if (p_what == NOTIFICATION_THEME_CHANGED) {
_update_gizmos_menu_theme();
} else if (p_what == NOTIFICATION_EXIT_TREE) {
-
_finish_indicators();
} else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
tool_button[Node3DEditor::TOOL_MODE_SELECT]->set_icon(get_theme_icon("ToolSelect", "EditorIcons"));
@@ -5849,39 +5753,33 @@ void Node3DEditor::_notification(int p_what) {
}
void Node3DEditor::add_control_to_menu_panel(Control *p_control) {
-
hbc_menu->add_child(p_control);
}
void Node3DEditor::remove_control_from_menu_panel(Control *p_control) {
-
hbc_menu->remove_child(p_control);
}
void Node3DEditor::set_can_preview(Camera3D *p_preview) {
-
for (int i = 0; i < 4; i++) {
viewports[i]->set_can_preview(p_preview);
}
}
VSplitContainer *Node3DEditor::get_shader_split() {
-
return shader_split;
}
HSplitContainer *Node3DEditor::get_palette_split() {
-
return palette_split;
}
void Node3DEditor::_request_gizmo(Object *p_obj) {
-
Node3D *sp = Object::cast_to<Node3D>(p_obj);
- if (!sp)
+ if (!sp) {
return;
+ }
if (editor->get_edited_scene() && (sp == editor->get_edited_scene() || (sp->get_owner() && editor->get_edited_scene()->is_a_parent_of(sp)))) {
-
Ref<EditorNode3DGizmo> seg;
for (int i = 0; i < gizmo_plugins_by_priority.size(); ++i) {
@@ -5902,54 +5800,62 @@ void Node3DEditor::_request_gizmo(Object *p_obj) {
}
void Node3DEditor::_toggle_maximize_view(Object *p_viewport) {
- if (!p_viewport) return;
+ if (!p_viewport) {
+ return;
+ }
Node3DEditorViewport *current_viewport = Object::cast_to<Node3DEditorViewport>(p_viewport);
- if (!current_viewport) return;
+ if (!current_viewport) {
+ return;
+ }
int index = -1;
bool maximized = false;
for (int i = 0; i < 4; i++) {
if (viewports[i] == current_viewport) {
index = i;
- if (current_viewport->get_global_rect() == viewport_base->get_global_rect())
+ if (current_viewport->get_global_rect() == viewport_base->get_global_rect()) {
maximized = true;
+ }
break;
}
}
- if (index == -1) return;
+ if (index == -1) {
+ return;
+ }
if (!maximized) {
-
for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
- if (i == (uint32_t)index)
+ if (i == (uint32_t)index) {
viewports[i]->set_anchors_and_margins_preset(Control::PRESET_WIDE);
- else
+ } else {
viewports[i]->hide();
+ }
}
} else {
-
- for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++)
+ for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->show();
+ }
- if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT)))
+ if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT))) {
_menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT);
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS))) {
_menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS);
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS_ALT))) {
_menu_item_pressed(MENU_VIEW_USE_2_VIEWPORTS_ALT);
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS))) {
_menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS);
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT))) {
_menu_item_pressed(MENU_VIEW_USE_3_VIEWPORTS_ALT);
- else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS)))
+ } else if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_4_VIEWPORTS))) {
_menu_item_pressed(MENU_VIEW_USE_4_VIEWPORTS);
+ }
}
}
void Node3DEditor::_node_removed(Node *p_node) {
-
- if (p_node == selected)
+ if (p_node == selected) {
selected = nullptr;
+ }
}
void Node3DEditor::_register_all_gizmos() {
@@ -5970,7 +5876,8 @@ void Node3DEditor::_register_all_gizmos() {
add_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin)));
add_gizmo_plugin(Ref<DecalGizmoPlugin>(memnew(DecalGizmoPlugin)));
add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin)));
- // add_gizmo_plugin(Ref<BakedIndirectLightGizmoPlugin>(memnew(BakedIndirectLightGizmoPlugin)));
+ add_gizmo_plugin(Ref<BakedLightmapGizmoPlugin>(memnew(BakedLightmapGizmoPlugin)));
+ add_gizmo_plugin(Ref<LightmapProbeGizmoPlugin>(memnew(LightmapProbeGizmoPlugin)));
add_gizmo_plugin(Ref<CollisionShape3DGizmoPlugin>(memnew(CollisionShape3DGizmoPlugin)));
add_gizmo_plugin(Ref<CollisionPolygon3DGizmoPlugin>(memnew(CollisionPolygon3DGizmoPlugin)));
add_gizmo_plugin(Ref<NavigationRegion3DGizmoPlugin>(memnew(NavigationRegion3DGizmoPlugin)));
@@ -5979,7 +5886,6 @@ void Node3DEditor::_register_all_gizmos() {
}
void Node3DEditor::_bind_methods() {
-
ClassDB::bind_method("_unhandled_key_input", &Node3DEditor::_unhandled_key_input);
ClassDB::bind_method("_get_editor_data", &Node3DEditor::_get_editor_data);
ClassDB::bind_method("_request_gizmo", &Node3DEditor::_request_gizmo);
@@ -5990,7 +5896,6 @@ void Node3DEditor::_bind_methods() {
}
void Node3DEditor::clear() {
-
settings_fov->set_value(EDITOR_DEF("editors/3d/default_fov", 70.0));
settings_znear->set_value(EDITOR_DEF("editors/3d/default_z_near", 0.05));
settings_zfar->set_value(EDITOR_DEF("editors/3d/default_z_far", 1500.0));
@@ -6009,7 +5914,6 @@ void Node3DEditor::clear() {
}
for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
-
viewports[i]->view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(Node3DEditorViewport::VIEW_AUDIO_LISTENER), i == 0);
viewports[i]->viewport->set_as_audio_listener(i == 0);
}
@@ -6018,7 +5922,6 @@ void Node3DEditor::clear() {
}
Node3DEditor::Node3DEditor(EditorNode *p_editor) {
-
gizmo.visible = true;
gizmo.scale = 1.0;
@@ -6231,7 +6134,6 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
shader_split->add_child(viewport_base);
viewport_base->set_v_size_flags(SIZE_EXPAND_FILL);
for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) {
-
viewports[i] = memnew(Node3DEditorViewport(this, editor, i));
viewports[i]->connect("toggle_maximize_view", callable_mp(this, &Node3DEditor::_toggle_maximize_view));
viewports[i]->connect("clicked", callable_mp(this, &Node3DEditor::_update_camera_override_viewport));
@@ -6316,7 +6218,6 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
xform_vbc->add_child(xform_hbc);
for (int i = 0; i < 3; i++) {
-
xform_translate[i] = memnew(LineEdit);
xform_translate[i]->set_h_size_flags(SIZE_EXPAND_FILL);
xform_hbc->add_child(xform_translate[i]);
@@ -6381,25 +6282,21 @@ Node3DEditor::~Node3DEditor() {
}
void Node3DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
-
spatial_editor->show();
spatial_editor->set_process(true);
} else {
-
spatial_editor->hide();
spatial_editor->set_process(false);
}
}
-void Node3DEditorPlugin::edit(Object *p_object) {
+void Node3DEditorPlugin::edit(Object *p_object) {
spatial_editor->edit(Object::cast_to<Node3D>(p_object));
}
bool Node3DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("Node3D");
}
@@ -6408,12 +6305,10 @@ Dictionary Node3DEditorPlugin::get_state() const {
}
void Node3DEditorPlugin::set_state(const Dictionary &p_state) {
-
spatial_editor->set_state(p_state);
}
void Node3DEditor::snap_cursor_to_plane(const Plane &p_plane) {
-
//cursor.pos=p_plane.project(cursor.pos);
}
@@ -6428,7 +6323,7 @@ Vector3 Node3DEditor::snap_point(Vector3 p_target, Vector3 p_start) const {
float Node3DEditor::get_translate_snap() const {
float snap_value;
- if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
snap_value = snap_translate->get_text().to_double() / 10.0;
} else {
snap_value = snap_translate->get_text().to_double();
@@ -6439,7 +6334,7 @@ float Node3DEditor::get_translate_snap() const {
float Node3DEditor::get_rotate_snap() const {
float snap_value;
- if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
snap_value = snap_rotate->get_text().to_double() / 3.0;
} else {
snap_value = snap_rotate->get_text().to_double();
@@ -6450,7 +6345,7 @@ float Node3DEditor::get_rotate_snap() const {
float Node3DEditor::get_scale_snap() const {
float snap_value;
- if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
snap_value = snap_scale->get_text().to_double() / 2.0;
} else {
snap_value = snap_scale->get_text().to_double();
@@ -6460,17 +6355,14 @@ float Node3DEditor::get_scale_snap() const {
}
void Node3DEditorPlugin::_bind_methods() {
-
ClassDB::bind_method("snap_cursor_to_plane", &Node3DEditorPlugin::snap_cursor_to_plane);
}
void Node3DEditorPlugin::snap_cursor_to_plane(const Plane &p_plane) {
-
spatial_editor->snap_cursor_to_plane(p_plane);
}
struct _GizmoPluginPriorityComparator {
-
bool operator()(const Ref<EditorNode3DGizmoPlugin> &p_a, const Ref<EditorNode3DGizmoPlugin> &p_b) const {
if (p_a->get_priority() == p_b->get_priority()) {
return p_a->get_name() < p_b->get_name();
@@ -6480,7 +6372,6 @@ struct _GizmoPluginPriorityComparator {
};
struct _GizmoPluginNameComparator {
-
bool operator()(const Ref<EditorNode3DGizmoPlugin> &p_a, const Ref<EditorNode3DGizmoPlugin> &p_b) const {
return p_a->get_name() < p_b->get_name();
}
@@ -6506,7 +6397,6 @@ void Node3DEditor::remove_gizmo_plugin(Ref<EditorNode3DGizmoPlugin> p_plugin) {
}
Node3DEditorPlugin::Node3DEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
spatial_editor = memnew(Node3DEditor(p_node));
spatial_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@@ -6520,7 +6410,6 @@ Node3DEditorPlugin::~Node3DEditorPlugin() {
}
void EditorNode3DGizmoPlugin::create_material(const String &p_name, const Color &p_color, bool p_billboard, bool p_on_top, bool p_use_vertex_color) {
-
Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.6));
Vector<Ref<StandardMaterial3D>> mats;
@@ -6562,7 +6451,6 @@ void EditorNode3DGizmoPlugin::create_material(const String &p_name, const Color
}
void EditorNode3DGizmoPlugin::create_icon_material(const String &p_name, const Ref<Texture2D> &p_texture, bool p_on_top, const Color &p_albedo) {
-
Color instanced_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/instanced", Color(0.7, 0.7, 0.7, 0.6));
Vector<Ref<StandardMaterial3D>> icons;
@@ -6633,7 +6521,9 @@ Ref<StandardMaterial3D> EditorNode3DGizmoPlugin::get_material(const String &p_na
ERR_FAIL_COND_V(!materials.has(p_name), Ref<StandardMaterial3D>());
ERR_FAIL_COND_V(materials[p_name].size() == 0, Ref<StandardMaterial3D>());
- if (p_gizmo.is_null() || materials[p_name].size() == 1) return materials[p_name][0];
+ if (p_gizmo.is_null() || materials[p_name].size() == 1) {
+ return materials[p_name][0];
+ }
int index = (p_gizmo->is_selected() ? 1 : 0) + (p_gizmo->is_editable() ? 2 : 0);
@@ -6663,14 +6553,15 @@ int EditorNode3DGizmoPlugin::get_priority() const {
}
Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::get_gizmo(Node3D *p_spatial) {
-
if (get_script_instance() && get_script_instance()->has_method("get_gizmo")) {
return get_script_instance()->call("get_gizmo", p_spatial);
}
Ref<EditorNode3DGizmo> ref = create_gizmo(p_spatial);
- if (ref.is_null()) return ref;
+ if (ref.is_null()) {
+ return ref;
+ }
ref->set_plugin(this);
ref->set_spatial_node(p_spatial);
@@ -6723,13 +6614,14 @@ bool EditorNode3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
}
Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::create_gizmo(Node3D *p_spatial) {
-
if (get_script_instance() && get_script_instance()->has_method("create_gizmo")) {
return get_script_instance()->call("create_gizmo", p_spatial);
}
Ref<EditorNode3DGizmo> ref;
- if (has_gizmo(p_spatial)) ref.instance();
+ if (has_gizmo(p_spatial)) {
+ ref.instance();
+ }
return ref;
}
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 2c3b15cfc8..3d92e7e7e1 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -46,7 +46,6 @@ class Node3DEditorViewport;
class SubViewportContainer;
class EditorNode3DGizmo : public Node3DGizmo {
-
GDCLASS(EditorNode3DGizmo, Node3DGizmo);
bool selected;
@@ -57,7 +56,6 @@ public:
bool is_selected() const { return selected; }
struct Instance {
-
RID instance;
Ref<ArrayMesh> mesh;
Ref<Material> material;
@@ -68,7 +66,6 @@ public:
bool can_intersect;
bool extra_margin;
Instance() {
-
billboard = false;
unscaled = false;
can_intersect = false;
@@ -158,6 +155,7 @@ class ViewportRotationControl : public Control {
Node3DEditorViewport *viewport = nullptr;
Vector<Color> axis_colors;
Vector<int> axis_menu_options;
+ Vector2i orbiting_mouse_start;
bool orbiting = false;
int focused_axis = -2;
@@ -178,7 +176,6 @@ public:
};
class Node3DEditorViewport : public Control {
-
GDCLASS(Node3DEditorViewport, Control);
friend class Node3DEditor;
friend class ViewportRotationControl;
@@ -241,6 +238,12 @@ public:
NAVIGATION_MODO,
};
+ enum FreelookNavigationScheme {
+ FREELOOK_DEFAULT,
+ FREELOOK_PARTIALLY_AXIS_LOCKED,
+ FREELOOK_FULLY_AXIS_LOCKED,
+ };
+
private:
float cpu_time_history[FRAME_TIME_HISTORY];
int cpu_time_history_index;
@@ -292,7 +295,6 @@ private:
Label *fps_label;
struct _RayResult {
-
Node3D *item;
float depth;
int handle;
@@ -382,7 +384,6 @@ private:
} _edit;
struct Cursor {
-
Vector3 pos;
float x_rot, y_rot, distance;
Vector3 eye_pos; // Used in freelook mode
@@ -483,7 +484,6 @@ public:
};
class Node3DEditorSelectedItem : public Object {
-
GDCLASS(Node3DEditorSelectedItem, Object);
public:
@@ -503,7 +503,6 @@ public:
};
class Node3DEditorViewportContainer : public Container {
-
GDCLASS(Node3DEditorViewportContainer, Container);
public:
@@ -544,7 +543,6 @@ public:
};
class Node3DEditor : public VBoxContainer {
-
GDCLASS(Node3DEditor, VBoxContainer);
public:
@@ -622,7 +620,6 @@ private:
AABB preview_bounds;
struct Gizmo {
-
bool visible;
float scale;
Transform transform;
@@ -812,7 +809,6 @@ public:
};
class Node3DEditorPlugin : public EditorPlugin {
-
GDCLASS(Node3DEditorPlugin, EditorPlugin);
Node3DEditor *spatial_editor;
@@ -842,7 +838,6 @@ public:
};
class EditorNode3DGizmoPlugin : public Resource {
-
GDCLASS(EditorNode3DGizmoPlugin, Resource);
public:
@@ -850,12 +845,11 @@ public:
static const int HIDDEN = 1;
static const int ON_TOP = 2;
-private:
+protected:
int current_state;
List<EditorNode3DGizmo *> current_gizmos;
HashMap<String, Vector<Ref<StandardMaterial3D>>> materials;
-protected:
static void _bind_methods();
virtual bool has_gizmo(Node3D *p_spatial);
virtual Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial);
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index 4516b7035b..a3dab665b8 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -37,11 +37,8 @@
#include "editor/editor_settings.h"
void Path2DEditor::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_READY: {
-
//button_create->set_icon( get_icon("Edit","EditorIcons"));
//button_edit->set_icon( get_icon("MovePoint","EditorIcons"));
//set_pressed_button(button_edit);
@@ -49,12 +46,11 @@ void Path2DEditor::_notification(int p_what) {
} break;
case NOTIFICATION_PHYSICS_PROCESS: {
-
} break;
}
}
-void Path2DEditor::_node_removed(Node *p_node) {
+void Path2DEditor::_node_removed(Node *p_node) {
if (p_node == node) {
node = nullptr;
hide();
@@ -62,31 +58,31 @@ void Path2DEditor::_node_removed(Node *p_node) {
}
bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
- if (!node)
+ if (!node) {
return false;
+ }
- if (!node->is_visible_in_tree())
+ if (!node->is_visible_in_tree()) {
return false;
+ }
- if (!node->get_curve().is_valid())
+ if (!node->get_curve().is_valid()) {
return false;
+ }
real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
-
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
Vector2 gpoint = mb->get_position();
Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position())));
if (mb->is_pressed() && action == ACTION_NONE) {
-
Ref<Curve2D> curve = node->get_curve();
for (int i = 0; i < curve->get_point_count(); i++) {
-
real_t dist_to_p = gpoint.distance_to(xform.xform(curve->get_point_position(i)));
real_t dist_to_p_out = gpoint.distance_to(xform.xform(curve->get_point_position(i) + curve->get_point_out(i)));
real_t dist_to_p_in = gpoint.distance_to(xform.xform(curve->get_point_position(i) + curve->get_point_in(i)));
@@ -104,7 +100,6 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} else if (mode == MODE_EDIT || mode == MODE_EDIT_CURVE) {
// In/out controls can be moved in multiple modes.
if (dist_to_p_out < grab_threshold && i < (curve->get_point_count() - 1)) {
-
action = ACTION_MOVING_OUT;
action_point = i;
moving_from = curve->get_point_out(i);
@@ -112,7 +107,6 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
orig_in_length = curve->get_point_in(action_point).length();
return true;
} else if (dist_to_p_in < grab_threshold && i > 0) {
-
action = ACTION_MOVING_IN;
action_point = i;
moving_from = curve->get_point_in(i);
@@ -126,7 +120,6 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
// Check for point deletion.
if ((mb->get_button_index() == BUTTON_RIGHT && mode == MODE_EDIT) || (mb->get_button_index() == BUTTON_LEFT && mode == MODE_DELETE)) {
if (dist_to_p < grab_threshold) {
-
undo_redo->create_action(TTR("Remove Point from Curve"));
undo_redo->add_do_method(curve.ptr(), "remove_point", i);
undo_redo->add_undo_method(curve.ptr(), "add_point", curve->get_point_position(i), curve->get_point_in(i), curve->get_point_out(i), i);
@@ -135,7 +128,6 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->commit_action();
return true;
} else if (dist_to_p_out < grab_threshold) {
-
undo_redo->create_action(TTR("Remove Out-Control from Curve"));
undo_redo->add_do_method(curve.ptr(), "set_point_out", i, Vector2());
undo_redo->add_undo_method(curve.ptr(), "set_point_out", i, curve->get_point_out(i));
@@ -144,7 +136,6 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->commit_action();
return true;
} else if (dist_to_p_in < grab_threshold) {
-
undo_redo->create_action(TTR("Remove In-Control from Curve"));
undo_redo->add_do_method(curve.ptr(), "set_point_in", i, Vector2());
undo_redo->add_undo_method(curve.ptr(), "set_point_in", i, curve->get_point_in(i));
@@ -159,7 +150,6 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
// Check for point creation.
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && ((mb->get_command() && mode == MODE_EDIT) || mode == MODE_CREATE)) {
-
Ref<Curve2D> curve = node->get_curve();
undo_redo->create_action(TTR("Add Point to Curve"));
@@ -189,11 +179,13 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
int len = curve->get_point_count();
for (int i = 0; i < len - 1; i++) {
float compareLength = curve->get_closest_offset(curve->get_point_position(i + 1));
- if (mbLength >= curve->get_closest_offset(curve->get_point_position(i)) && mbLength <= compareLength)
+ if (mbLength >= curve->get_closest_offset(curve->get_point_position(i)) && mbLength <= compareLength) {
insertion_point = i;
+ }
}
- if (insertion_point == -1)
+ if (insertion_point == -1) {
insertion_point = curve->get_point_count() - 2;
+ }
undo_redo->create_action(TTR("Split Curve"));
undo_redo->add_do_method(curve.ptr(), "add_point", xform.affine_inverse().xform(gpoint2), Vector2(0, 0), Vector2(0, 0), insertion_point + 1);
@@ -216,18 +208,15 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
// Check for point movement completion.
if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && action != ACTION_NONE) {
-
Ref<Curve2D> curve = node->get_curve();
Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from);
switch (action) {
-
case ACTION_NONE:
// N/A, handled in above condition.
break;
case ACTION_MOVING_POINT: {
-
undo_redo->create_action(TTR("Move Point in Curve"));
undo_redo->add_do_method(curve.ptr(), "set_point_position", action_point, cpoint);
undo_redo->add_undo_method(curve.ptr(), "set_point_position", action_point, moving_from);
@@ -238,7 +227,6 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} break;
case ACTION_MOVING_IN: {
-
undo_redo->create_action(TTR("Move In-Control in Curve"));
undo_redo->add_do_method(curve.ptr(), "set_point_in", action_point, new_pos);
undo_redo->add_undo_method(curve.ptr(), "set_point_in", action_point, moving_from);
@@ -254,7 +242,6 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} break;
case ACTION_MOVING_OUT: {
-
undo_redo->create_action(TTR("Move Out-Control in Curve"));
undo_redo->add_do_method(curve.ptr(), "set_point_out", action_point, new_pos);
undo_redo->add_undo_method(curve.ptr(), "set_point_out", action_point, moving_from);
@@ -279,7 +266,6 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
if (action == ACTION_NONE && mode == MODE_EDIT) {
// Handle Edge Follow
bool old_edge = on_edge;
@@ -288,8 +274,12 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Vector2 gpoint = mm->get_position();
Ref<Curve2D> curve = node->get_curve();
- if (curve == nullptr) return true;
- if (curve->get_point_count() < 2) return true;
+ if (curve == nullptr) {
+ return true;
+ }
+ if (curve->get_point_count() < 2) {
+ return true;
+ }
// Find edge
edge_point = xform.xform(curve->get_closest_point(xform.affine_inverse().xform(mm->get_position())));
@@ -334,7 +324,6 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from);
switch (action) {
-
case ACTION_NONE:
// N/A, handled in above condition.
break;
@@ -346,15 +335,17 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
case ACTION_MOVING_IN: {
curve->set_point_in(action_point, new_pos);
- if (mirror_handle_angle)
+ if (mirror_handle_angle) {
curve->set_point_out(action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_out_length));
+ }
} break;
case ACTION_MOVING_OUT: {
curve->set_point_out(action_point, new_pos);
- if (mirror_handle_angle)
+ if (mirror_handle_angle) {
curve->set_point_in(action_point, mirror_handle_length ? -new_pos : (-new_pos.normalized() * orig_in_length));
+ }
} break;
}
@@ -367,9 +358,9 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
-
- if (!node || !node->is_visible_in_tree() || !node->get_curve().is_valid())
+ if (!node || !node->is_visible_in_tree() || !node->get_curve().is_valid()) {
return;
+ }
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
@@ -426,77 +417,73 @@ void Path2DEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
}
void Path2DEditor::_node_visibility_changed() {
- if (!node)
+ if (!node) {
return;
+ }
canvas_item_editor->update_viewport();
}
void Path2DEditor::edit(Node *p_path2d) {
-
if (!canvas_item_editor) {
canvas_item_editor = CanvasItemEditor::get_singleton();
}
if (p_path2d) {
-
node = Object::cast_to<Path2D>(p_path2d);
- if (!node->is_connected("visibility_changed", callable_mp(this, &Path2DEditor::_node_visibility_changed)))
+ if (!node->is_connected("visibility_changed", callable_mp(this, &Path2DEditor::_node_visibility_changed))) {
node->connect("visibility_changed", callable_mp(this, &Path2DEditor::_node_visibility_changed));
+ }
} else {
-
// node may have been deleted at this point
- if (node && node->is_connected("visibility_changed", callable_mp(this, &Path2DEditor::_node_visibility_changed)))
+ if (node && node->is_connected("visibility_changed", callable_mp(this, &Path2DEditor::_node_visibility_changed))) {
node->disconnect("visibility_changed", callable_mp(this, &Path2DEditor::_node_visibility_changed));
+ }
node = nullptr;
}
}
void Path2DEditor::_bind_methods() {
-
//ClassDB::bind_method(D_METHOD("_menu_option"),&Path2DEditor::_menu_option);
}
void Path2DEditor::_mode_selected(int p_mode) {
-
if (p_mode == MODE_CREATE) {
-
curve_create->set_pressed(true);
curve_edit->set_pressed(false);
curve_edit_curve->set_pressed(false);
curve_del->set_pressed(false);
} else if (p_mode == MODE_EDIT) {
-
curve_create->set_pressed(false);
curve_edit->set_pressed(true);
curve_edit_curve->set_pressed(false);
curve_del->set_pressed(false);
} else if (p_mode == MODE_EDIT_CURVE) {
-
curve_create->set_pressed(false);
curve_edit->set_pressed(false);
curve_edit_curve->set_pressed(true);
curve_del->set_pressed(false);
} else if (p_mode == MODE_DELETE) {
-
curve_create->set_pressed(false);
curve_edit->set_pressed(false);
curve_edit_curve->set_pressed(false);
curve_del->set_pressed(true);
} else if (p_mode == ACTION_CLOSE) {
-
//?
- if (!node->get_curve().is_valid())
+ if (!node->get_curve().is_valid()) {
return;
- if (node->get_curve()->get_point_count() < 3)
+ }
+ if (node->get_curve()->get_point_count() < 3) {
return;
+ }
Vector2 begin = node->get_curve()->get_point_position(0);
Vector2 end = node->get_curve()->get_point_position(node->get_curve()->get_point_count() - 1);
- if (begin.distance_to(end) < CMP_EPSILON)
+ if (begin.distance_to(end) < CMP_EPSILON) {
return;
+ }
undo_redo->create_action(TTR("Remove Point from Curve"));
undo_redo->add_do_method(node->get_curve().ptr(), "add_point", begin);
@@ -511,7 +498,6 @@ void Path2DEditor::_mode_selected(int p_mode) {
}
void Path2DEditor::_handle_option_pressed(int p_option) {
-
PopupMenu *pm;
pm = handle_menu->get_popup();
@@ -531,7 +517,6 @@ void Path2DEditor::_handle_option_pressed(int p_option) {
}
Path2DEditor::Path2DEditor(EditorNode *p_editor) {
-
canvas_item_editor = nullptr;
editor = p_editor;
undo_redo = editor->get_undo_redo();
@@ -601,23 +586,19 @@ Path2DEditor::Path2DEditor(EditorNode *p_editor) {
}
void Path2DEditorPlugin::edit(Object *p_object) {
-
path2d_editor->edit(Object::cast_to<Node>(p_object));
}
bool Path2DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("Path2D");
}
void Path2DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
path2d_editor->show();
path2d_editor->base_hb->show();
} else {
-
path2d_editor->hide();
path2d_editor->base_hb->hide();
path2d_editor->edit(nullptr);
@@ -625,7 +606,6 @@ void Path2DEditorPlugin::make_visible(bool p_visible) {
}
Path2DEditorPlugin::Path2DEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
path2d_editor = memnew(Path2DEditor(p_node));
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(path2d_editor);
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index aae0e11c99..390dfdfdf7 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -39,7 +39,6 @@
class CanvasItemEditor;
class Path2DEditor : public HBoxContainer {
-
GDCLASS(Path2DEditor, HBoxContainer);
UndoRedo *undo_redo;
@@ -112,7 +111,6 @@ public:
};
class Path2DEditorPlugin : public EditorPlugin {
-
GDCLASS(Path2DEditorPlugin, EditorPlugin);
Path2DEditor *path2d_editor;
diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp
index d3ece9556d..a44fe69ff6 100644
--- a/editor/plugins/path_3d_editor_plugin.cpp
+++ b/editor/plugins/path_3d_editor_plugin.cpp
@@ -35,13 +35,12 @@
#include "scene/resources/curve.h"
String Path3DGizmo::get_handle_name(int p_idx) const {
-
Ref<Curve3D> c = path->get_curve();
- if (c.is_null())
+ if (c.is_null()) {
return "";
+ }
if (p_idx < c->get_point_count()) {
-
return TTR("Curve Point #") + itos(p_idx);
}
@@ -50,21 +49,22 @@ String Path3DGizmo::get_handle_name(int p_idx) const {
int idx = p_idx / 2;
int t = p_idx % 2;
String n = TTR("Curve Point #") + itos(idx);
- if (t == 0)
+ if (t == 0) {
n += " In";
- else
+ } else {
n += " Out";
+ }
return n;
}
-Variant Path3DGizmo::get_handle_value(int p_idx) {
+Variant Path3DGizmo::get_handle_value(int p_idx) {
Ref<Curve3D> c = path->get_curve();
- if (c.is_null())
+ if (c.is_null()) {
return Variant();
+ }
if (p_idx < c->get_point_count()) {
-
original = c->get_point_position(p_idx);
return original;
}
@@ -75,20 +75,22 @@ Variant Path3DGizmo::get_handle_value(int p_idx) {
int t = p_idx % 2;
Vector3 ofs;
- if (t == 0)
+ if (t == 0) {
ofs = c->get_point_in(idx);
- else
+ } else {
ofs = c->get_point_out(idx);
+ }
original = ofs + c->get_point_position(idx);
return ofs;
}
-void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_point) {
+void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_point) {
Ref<Curve3D> c = path->get_curve();
- if (c.is_null())
+ if (c.is_null()) {
return;
+ }
Transform gt = path->get_global_transform();
Transform gi = gt.affine_inverse();
@@ -97,13 +99,11 @@ void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_poin
// Setting curve point positions
if (p_idx < c->get_point_count()) {
-
Plane p(gt.xform(original), p_camera->get_transform().basis.get_axis(2));
Vector3 inters;
if (p.intersects_ray(ray_from, ray_dir, &inters)) {
-
if (Node3DEditor::get_singleton()->is_snap_enabled()) {
float snap = Node3DEditor::get_singleton()->get_translate_snap();
inters.snap(Vector3(snap, snap, snap));
@@ -129,7 +129,6 @@ void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_poin
// Setting curve in/out positions
if (p.intersects_ray(ray_from, ray_dir, &inters)) {
-
if (!Path3DEditorPlugin::singleton->is_handle_clicked()) {
orig_in_length = c->get_point_in(idx).length();
orig_out_length = c->get_point_out(idx).length();
@@ -144,28 +143,28 @@ void Path3DGizmo::set_handle(int p_idx, Camera3D *p_camera, const Point2 &p_poin
if (t == 0) {
c->set_point_in(idx, local);
- if (Path3DEditorPlugin::singleton->mirror_angle_enabled())
+ if (Path3DEditorPlugin::singleton->mirror_angle_enabled()) {
c->set_point_out(idx, Path3DEditorPlugin::singleton->mirror_length_enabled() ? -local : (-local.normalized() * orig_out_length));
+ }
} else {
c->set_point_out(idx, local);
- if (Path3DEditorPlugin::singleton->mirror_angle_enabled())
+ if (Path3DEditorPlugin::singleton->mirror_angle_enabled()) {
c->set_point_in(idx, Path3DEditorPlugin::singleton->mirror_length_enabled() ? -local : (-local.normalized() * orig_in_length));
+ }
}
}
}
void Path3DGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
-
Ref<Curve3D> c = path->get_curve();
- if (c.is_null())
+ if (c.is_null()) {
return;
+ }
UndoRedo *ur = Node3DEditor::get_singleton()->get_undo_redo();
if (p_idx < c->get_point_count()) {
-
if (p_cancel) {
-
c->set_point_position(p_idx, p_restore);
return;
}
@@ -218,7 +217,6 @@ void Path3DGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_canc
}
void Path3DGizmo::redraw() {
-
clear();
Ref<StandardMaterial3D> path_material = gizmo_plugin->get_material("path_material", this);
@@ -226,21 +224,22 @@ void Path3DGizmo::redraw() {
Ref<StandardMaterial3D> handles_material = gizmo_plugin->get_material("handles");
Ref<Curve3D> c = path->get_curve();
- if (c.is_null())
+ if (c.is_null()) {
return;
+ }
Vector<Vector3> v3a = c->tessellate();
//Vector<Vector3> v3a=c->get_baked_points();
int v3s = v3a.size();
- if (v3s == 0)
+ if (v3s == 0) {
return;
+ }
Vector<Vector3> v3p;
const Vector3 *r = v3a.ptr();
// BUG: the following won't work when v3s, avoid drawing as a temporary workaround.
for (int i = 0; i < v3s - 1; i++) {
-
v3p.push_back(r[i]);
v3p.push_back(r[i + 1]);
//v3p.push_back(r[i]);
@@ -258,7 +257,6 @@ void Path3DGizmo::redraw() {
Vector<Vector3> sec_handles;
for (int i = 0; i < c->get_point_count(); i++) {
-
Vector3 p = c->get_point_position(i);
handles.push_back(p);
if (i > 0) {
@@ -287,18 +285,18 @@ void Path3DGizmo::redraw() {
}
Path3DGizmo::Path3DGizmo(Path3D *p_path) {
-
path = p_path;
set_spatial_node(p_path);
}
bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
-
- if (!path)
+ if (!path) {
return false;
+ }
Ref<Curve3D> c = path->get_curve();
- if (c.is_null())
+ if (c.is_null()) {
return false;
+ }
Transform gt = path->get_global_transform();
Transform it = gt.affine_inverse();
@@ -307,11 +305,11 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
-
Point2 mbpos(mb->get_position().x, mb->get_position().y);
- if (!mb->is_pressed())
+ if (!mb->is_pressed()) {
set_handle_clicked(false);
+ }
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && (curve_create->is_pressed() || (curve_edit->is_pressed() && mb->get_control()))) {
//click into curve, break it down
@@ -325,17 +323,18 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
if (rc >= 2) {
const Vector3 *r = v3a.ptr();
- if (p_camera->unproject_position(gt.xform(c->get_point_position(0))).distance_to(mbpos) < click_dist)
+ if (p_camera->unproject_position(gt.xform(c->get_point_position(0))).distance_to(mbpos) < click_dist) {
return false; //nope, existing
+ }
for (int i = 0; i < c->get_point_count() - 1; i++) {
//find the offset and point index of the place to break up
int j = idx;
- if (p_camera->unproject_position(gt.xform(c->get_point_position(i + 1))).distance_to(mbpos) < click_dist)
+ if (p_camera->unproject_position(gt.xform(c->get_point_position(i + 1))).distance_to(mbpos) < click_dist) {
return false; //nope, existing
+ }
while (j < rc && c->get_point_position(i + 1) != r[j]) {
-
Vector3 from = r[j];
Vector3 to = r[j + 1];
real_t cdist = from.distance_to(to);
@@ -349,7 +348,6 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
float d = inters.distance_to(mbpos);
if (d < 10 && d < closest_d) {
-
closest_d = d;
closest_seg = i;
Vector3 ray_from = p_camera->project_ray_origin(mbpos);
@@ -363,13 +361,15 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
}
j++;
}
- if (idx == j)
+ if (idx == j) {
idx++; //force next
- else
+ } else {
idx = j; //swap
+ }
- if (j == rc)
+ if (j == rc) {
break;
+ }
}
}
@@ -384,19 +384,18 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
return true;
} else {
-
Vector3 org;
- if (c->get_point_count() == 0)
+ if (c->get_point_count() == 0) {
org = path->get_transform().get_origin();
- else
+ } else {
org = gt.xform(c->get_point_position(c->get_point_count() - 1));
+ }
Plane p(org, p_camera->get_transform().basis.get_axis(2));
Vector3 ray_from = p_camera->project_ray_origin(mbpos);
Vector3 ray_dir = p_camera->project_ray_normal(mbpos);
Vector3 inters;
if (p.intersects_ray(ray_from, ray_dir, &inters)) {
-
ur->create_action(TTR("Add Point to Curve"));
ur->add_do_method(c.ptr(), "add_point", it.xform(inters), Vector3(), Vector3(), -1);
ur->add_undo_method(c.ptr(), "remove_point", c->get_point_count());
@@ -408,7 +407,6 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
}
} else if (mb->is_pressed() && ((mb->get_button_index() == BUTTON_LEFT && curve_del->is_pressed()) || (mb->get_button_index() == BUTTON_RIGHT && curve_edit->is_pressed()))) {
-
for (int i = 0; i < c->get_point_count(); i++) {
real_t dist_to_p = p_camera->unproject_position(gt.xform(c->get_point_position(i))).distance_to(mbpos);
real_t dist_to_p_out = p_camera->unproject_position(gt.xform(c->get_point_position(i) + c->get_point_out(i))).distance_to(mbpos);
@@ -417,7 +415,6 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
// Find the offset and point index of the place to break up.
// Also check for the control points.
if (dist_to_p < click_dist) {
-
UndoRedo *ur = editor->get_undo_redo();
ur->create_action(TTR("Remove Path Point"));
ur->add_do_method(c.ptr(), "remove_point", i);
@@ -425,7 +422,6 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
ur->commit_action();
return true;
} else if (dist_to_p_out < click_dist) {
-
UndoRedo *ur = editor->get_undo_redo();
ur->create_action(TTR("Remove Out-Control Point"));
ur->add_do_method(c.ptr(), "set_point_out", i, Vector3());
@@ -433,7 +429,6 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
ur->commit_action();
return true;
} else if (dist_to_p_in < click_dist) {
-
UndoRedo *ur = editor->get_undo_redo();
ur->create_action(TTR("Remove In-Control Point"));
ur->add_do_method(c.ptr(), "set_point_in", i, Vector3());
@@ -449,11 +444,9 @@ bool Path3DEditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref
}
void Path3DEditorPlugin::edit(Object *p_object) {
-
if (p_object) {
path = Object::cast_to<Path3D>(p_object);
if (path) {
-
if (path->get_curve().is_valid()) {
path->get_curve()->emit_signal("changed");
}
@@ -469,14 +462,11 @@ void Path3DEditorPlugin::edit(Object *p_object) {
}
bool Path3DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("Path3D");
}
void Path3DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
-
curve_create->show();
curve_edit->show();
curve_del->show();
@@ -484,7 +474,6 @@ void Path3DEditorPlugin::make_visible(bool p_visible) {
handle_menu->show();
sep->show();
} else {
-
curve_create->hide();
curve_edit->hide();
curve_del->hide();
@@ -503,24 +492,23 @@ void Path3DEditorPlugin::make_visible(bool p_visible) {
}
void Path3DEditorPlugin::_mode_changed(int p_idx) {
-
curve_create->set_pressed(p_idx == 0);
curve_edit->set_pressed(p_idx == 1);
curve_del->set_pressed(p_idx == 2);
}
void Path3DEditorPlugin::_close_curve() {
-
Ref<Curve3D> c = path->get_curve();
- if (c.is_null())
+ if (c.is_null()) {
return;
- if (c->get_point_count() < 2)
+ }
+ if (c->get_point_count() < 2) {
return;
+ }
c->add_point(c->get_point_position(0), c->get_point_in(0), c->get_point_out(0));
}
void Path3DEditorPlugin::_handle_option_pressed(int p_option) {
-
PopupMenu *pm;
pm = handle_menu->get_popup();
@@ -540,9 +528,7 @@ void Path3DEditorPlugin::_handle_option_pressed(int p_option) {
}
void Path3DEditorPlugin::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
curve_create->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(0));
curve_edit->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(1));
curve_del->connect("pressed", callable_mp(this, &Path3DEditorPlugin::_mode_changed), make_binds(2));
@@ -556,7 +542,6 @@ void Path3DEditorPlugin::_bind_methods() {
Path3DEditorPlugin *Path3DEditorPlugin::singleton = nullptr;
Path3DEditorPlugin::Path3DEditorPlugin(EditorNode *p_node) {
-
path = nullptr;
editor = p_node;
singleton = this;
@@ -631,7 +616,9 @@ Ref<EditorNode3DGizmo> Path3DGizmoPlugin::create_gizmo(Node3D *p_spatial) {
Ref<Path3DGizmo> ref;
Path3D *path = Object::cast_to<Path3D>(p_spatial);
- if (path) ref = Ref<Path3DGizmo>(memnew(Path3DGizmo(path)));
+ if (path) {
+ ref = Ref<Path3DGizmo>(memnew(Path3DGizmo(path)));
+ }
return ref;
}
@@ -645,7 +632,6 @@ int Path3DGizmoPlugin::get_priority() const {
}
Path3DGizmoPlugin::Path3DGizmoPlugin() {
-
Color path_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/path", Color(0.5, 0.5, 1.0, 0.8));
create_material("path_material", path_color);
create_material("path_thin_material", Color(0.5, 0.5, 0.5));
diff --git a/editor/plugins/path_3d_editor_plugin.h b/editor/plugins/path_3d_editor_plugin.h
index 3f18cadacd..8bec5df797 100644
--- a/editor/plugins/path_3d_editor_plugin.h
+++ b/editor/plugins/path_3d_editor_plugin.h
@@ -35,7 +35,6 @@
#include "scene/3d/path_3d.h"
class Path3DGizmo : public EditorNode3DGizmo {
-
GDCLASS(Path3DGizmo, EditorNode3DGizmo);
Path3D *path;
@@ -54,7 +53,6 @@ public:
};
class Path3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(Path3DGizmoPlugin, EditorNode3DGizmoPlugin);
protected:
@@ -67,7 +65,6 @@ public:
};
class Path3DEditorPlugin : public EditorPlugin {
-
GDCLASS(Path3DEditorPlugin, EditorPlugin);
Separator *sep;
diff --git a/editor/plugins/physical_bone_3d_editor_plugin.cpp b/editor/plugins/physical_bone_3d_editor_plugin.cpp
index 6d38f7f318..bcbf88e7dc 100644
--- a/editor/plugins/physical_bone_3d_editor_plugin.cpp
+++ b/editor/plugins/physical_bone_3d_editor_plugin.cpp
@@ -37,7 +37,6 @@ void PhysicalBone3DEditor::_bind_methods() {
}
void PhysicalBone3DEditor::_on_toggle_button_transform_joint(bool p_is_pressed) {
-
_set_move_joint();
}
@@ -48,9 +47,7 @@ void PhysicalBone3DEditor::_set_move_joint() {
}
PhysicalBone3DEditor::PhysicalBone3DEditor(EditorNode *p_editor) :
- editor(p_editor),
- selected(nullptr) {
-
+ editor(p_editor) {
spatial_editor_hb = memnew(HBoxContainer);
spatial_editor_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
spatial_editor_hb->set_alignment(BoxContainer::ALIGN_BEGIN);
@@ -69,10 +66,7 @@ PhysicalBone3DEditor::PhysicalBone3DEditor(EditorNode *p_editor) :
hide();
}
-PhysicalBone3DEditor::~PhysicalBone3DEditor() {}
-
void PhysicalBone3DEditor::set_selected(PhysicalBone3D *p_pb) {
-
button_transform_joint->set_pressed(false);
_set_move_joint();
@@ -90,15 +84,12 @@ void PhysicalBone3DEditor::show() {
PhysicalBone3DEditorPlugin::PhysicalBone3DEditorPlugin(EditorNode *p_editor) :
editor(p_editor),
- selected(nullptr),
physical_bone_editor(editor) {}
void PhysicalBone3DEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
-
physical_bone_editor.show();
} else {
-
physical_bone_editor.hide();
physical_bone_editor.set_selected(nullptr);
selected = nullptr;
diff --git a/editor/plugins/physical_bone_3d_editor_plugin.h b/editor/plugins/physical_bone_3d_editor_plugin.h
index 74932710d6..79c7cc4bb1 100644
--- a/editor/plugins/physical_bone_3d_editor_plugin.h
+++ b/editor/plugins/physical_bone_3d_editor_plugin.h
@@ -40,7 +40,7 @@ class PhysicalBone3DEditor : public Object {
HBoxContainer *spatial_editor_hb;
ToolButton *button_transform_joint;
- PhysicalBone3D *selected;
+ PhysicalBone3D *selected = nullptr;
protected:
static void _bind_methods();
@@ -51,7 +51,7 @@ private:
public:
PhysicalBone3DEditor(EditorNode *p_editor);
- ~PhysicalBone3DEditor();
+ ~PhysicalBone3DEditor() {}
void set_selected(PhysicalBone3D *p_pb);
@@ -63,7 +63,7 @@ class PhysicalBone3DEditorPlugin : public EditorPlugin {
GDCLASS(PhysicalBone3DEditorPlugin, EditorPlugin);
EditorNode *editor;
- PhysicalBone3D *selected;
+ PhysicalBone3D *selected = nullptr;
PhysicalBone3DEditor physical_bone_editor;
public:
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 1f7a5b9968..7ee695b9fe 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -31,7 +31,7 @@
#include "polygon_2d_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/file_access.h"
#include "core/os/keyboard.h"
#include "editor/editor_scale.h"
@@ -39,23 +39,19 @@
#include "scene/2d/skeleton_2d.h"
Node2D *Polygon2DEditor::_get_node() const {
-
return node;
}
void Polygon2DEditor::_set_node(Node *p_polygon) {
-
node = Object::cast_to<Polygon2D>(p_polygon);
_update_polygon_editing_state();
}
Vector2 Polygon2DEditor::_get_offset(int p_idx) const {
-
return node->get_offset();
}
int Polygon2DEditor::_get_polygon_count() const {
-
if (node->get_internal_vertex_count() > 0) {
return 0; //do not edit if internal vertices exist
} else {
@@ -64,17 +60,13 @@ int Polygon2DEditor::_get_polygon_count() const {
}
void Polygon2DEditor::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
-
uv_edit_draw->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree"));
bone_scroll->add_theme_style_override("bg", get_theme_stylebox("bg", "Tree"));
} break;
case NOTIFICATION_READY: {
-
button_uv->set_icon(get_theme_icon("Uv", "EditorIcons"));
uv_button[UV_MODE_CREATE]->set_icon(get_theme_icon("Edit", "EditorIcons"));
@@ -97,7 +89,6 @@ void Polygon2DEditor::_notification(int p_what) {
uv_hscroll->set_anchors_and_margins_preset(PRESET_BOTTOM_WIDE);
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
if (!is_visible()) {
uv_edit->hide();
}
@@ -106,7 +97,6 @@ void Polygon2DEditor::_notification(int p_what) {
}
void Polygon2DEditor::_sync_bones() {
-
Skeleton2D *skeleton = nullptr;
if (!node->has_node(node->get_skeleton())) {
error->set_text(TTR("The skeleton property of the Polygon2D does not point to a Skeleton2D node"));
@@ -161,7 +151,6 @@ void Polygon2DEditor::_sync_bones() {
}
void Polygon2DEditor::_update_bone_list() {
-
NodePath selected;
while (bone_scroll_vb->get_child_count()) {
CheckBox *cb = Object::cast_to<CheckBox>(bone_scroll_vb->get_child(0));
@@ -189,8 +178,9 @@ void Polygon2DEditor::_update_bone_list() {
cb->set_focus_mode(FOCUS_NONE);
bone_scroll_vb->add_child(cb);
- if (np == selected || bone_scroll_vb->get_child_count() < 2)
+ if (np == selected || bone_scroll_vb->get_child_count() < 2) {
cb->set_pressed(true);
+ }
cb->connect("pressed", callable_mp(this, &Polygon2DEditor::_bone_paint_selected), varray(i));
}
@@ -203,7 +193,6 @@ void Polygon2DEditor::_bone_paint_selected(int p_index) {
}
void Polygon2DEditor::_uv_edit_mode_select(int p_mode) {
-
if (p_mode == 0) { //uv
uv_button[UV_MODE_CREATE]->hide();
@@ -274,20 +263,15 @@ void Polygon2DEditor::_uv_edit_mode_select(int p_mode) {
}
void Polygon2DEditor::_uv_edit_popup_hide() {
-
EditorSettings::get_singleton()->set("interface/dialogs/uv_editor_bounds", Rect2(uv_edit->get_position(), uv_edit->get_size()));
_cancel_editing();
}
void Polygon2DEditor::_menu_option(int p_option) {
-
switch (p_option) {
-
case MODE_EDIT_UV: {
-
if (node->get_texture().is_null()) {
-
error->set_text(TTR("No texture in this polygon.\nSet a texture to be able to edit UV."));
error->popup_centered();
return;
@@ -304,17 +288,18 @@ void Polygon2DEditor::_menu_option(int p_option) {
undo_redo->commit_action();
}
- if (EditorSettings::get_singleton()->has_setting("interface/dialogs/uv_editor_bounds"))
+ if (EditorSettings::get_singleton()->has_setting("interface/dialogs/uv_editor_bounds")) {
uv_edit->popup(EditorSettings::get_singleton()->get("interface/dialogs/uv_editor_bounds"));
- else
+ } else {
uv_edit->popup_centered_ratio(0.85);
+ }
_update_bone_list();
} break;
case UVEDIT_POLYGON_TO_UV: {
-
Vector<Vector2> points = node->get_polygon();
- if (points.size() == 0)
+ if (points.size() == 0) {
break;
+ }
Vector<Vector2> uvs = node->get_uv();
undo_redo->create_action(TTR("Create UV Map"));
undo_redo->add_do_method(node, "set_uv", points);
@@ -324,11 +309,11 @@ void Polygon2DEditor::_menu_option(int p_option) {
undo_redo->commit_action();
} break;
case UVEDIT_UV_TO_POLYGON: {
-
Vector<Vector2> points = node->get_polygon();
Vector<Vector2> uvs = node->get_uv();
- if (uvs.size() == 0)
+ if (uvs.size() == 0) {
break;
+ }
undo_redo->create_action(TTR("Create Polygon"));
undo_redo->add_do_method(node, "set_polygon", uvs);
@@ -338,10 +323,10 @@ void Polygon2DEditor::_menu_option(int p_option) {
undo_redo->commit_action();
} break;
case UVEDIT_UV_CLEAR: {
-
Vector<Vector2> uvs = node->get_uv();
- if (uvs.size() == 0)
+ if (uvs.size() == 0) {
break;
+ }
undo_redo->create_action(TTR("Create UV Map"));
undo_redo->add_do_method(node, "set_uv", Vector<Vector2>());
undo_redo->add_undo_method(node, "set_uv", uvs);
@@ -350,18 +335,15 @@ void Polygon2DEditor::_menu_option(int p_option) {
undo_redo->commit_action();
} break;
case UVEDIT_GRID_SETTINGS: {
-
grid_settings->popup_centered();
} break;
default: {
-
AbstractPolygon2DEditor::_menu_option(p_option);
} break;
}
}
void Polygon2DEditor::_cancel_editing() {
-
if (uv_create) {
uv_drag = false;
uv_create = false;
@@ -386,18 +368,18 @@ void Polygon2DEditor::_cancel_editing() {
}
void Polygon2DEditor::_update_polygon_editing_state() {
-
- if (!_get_node())
+ if (!_get_node()) {
return;
+ }
- if (node->get_internal_vertex_count() > 0)
+ if (node->get_internal_vertex_count() > 0) {
disable_polygon_editing(true, TTR("Polygon 2D has internal vertices, so it can no longer be edited in the viewport."));
- else
+ } else {
disable_polygon_editing(false, String());
+ }
}
void Polygon2DEditor::_commit_action() {
-
// Makes that undo/redoing actions made outside of the UV editor still affect its polygon.
undo_redo->add_do_method(uv_edit_draw, "update");
undo_redo->add_undo_method(uv_edit_draw, "update");
@@ -442,7 +424,6 @@ void Polygon2DEditor::_set_snap_step_y(float p_val) {
}
void Polygon2DEditor::_uv_mode(int p_mode) {
-
polygon_create.clear();
uv_drag = false;
uv_create = false;
@@ -454,9 +435,9 @@ void Polygon2DEditor::_uv_mode(int p_mode) {
}
void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
-
- if (!_get_node())
+ if (!_get_node()) {
return;
+ }
Transform2D mtx;
mtx.elements[2] = -uv_draw_ofs;
@@ -465,11 +446,8 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
Ref<InputEventMouseButton> mb = p_input;
if (mb.is_valid()) {
-
if (mb->get_button_index() == BUTTON_LEFT) {
-
if (mb->is_pressed()) {
-
uv_drag_from = snap_point(Vector2(mb->get_position().x, mb->get_position().y));
uv_drag = true;
points_prev = node->get_uv();
@@ -482,9 +460,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
uv_move_current = uv_mode;
if (uv_move_current == UV_MODE_CREATE) {
-
if (!uv_create) {
-
points_prev.resize(0);
Vector2 tuv = mtx.affine_inverse().xform(snap_point(Vector2(mb->get_position().x, mb->get_position().y)));
points_prev.push_back(tuv);
@@ -506,7 +482,6 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
uv_edit_draw->update();
} else {
-
Vector2 tuv = mtx.affine_inverse().xform(snap_point(Vector2(mb->get_position().x, mb->get_position().y)));
if (points_prev.size() > 2 && tuv.distance_to(points_prev[0]) < 8) {
@@ -544,7 +519,6 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
if (uv_move_current == UV_MODE_CREATE_INTERNAL) {
-
uv_create_uv_prev = node->get_uv();
uv_create_poly_prev = node->get_polygon();
uv_create_colors_prev = node->get_vertex_colors();
@@ -582,21 +556,20 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
if (uv_move_current == UV_MODE_REMOVE_INTERNAL) {
-
uv_create_uv_prev = node->get_uv();
uv_create_poly_prev = node->get_polygon();
uv_create_colors_prev = node->get_vertex_colors();
uv_create_bones_prev = node->call("_get_bones");
int internal_vertices = node->get_internal_vertex_count();
- if (internal_vertices <= 0)
+ if (internal_vertices <= 0) {
return;
+ }
int closest = -1;
float closest_dist = 1e20;
for (int i = points_prev.size() - internal_vertices; i < points_prev.size(); i++) {
-
Vector2 tuv = mtx.xform(uv_create_poly_prev[i]);
float dist = tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y));
if (dist < 8 && dist < closest_dist) {
@@ -605,8 +578,9 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
}
- if (closest == -1)
+ if (closest == -1) {
return;
+ }
uv_create_poly_prev.remove(closest);
uv_create_uv_prev.remove(closest);
@@ -637,20 +611,18 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
if (uv_move_current == UV_MODE_EDIT_POINT) {
-
- if (mb->get_shift() && mb->get_command())
+ if (mb->get_shift() && mb->get_command()) {
uv_move_current = UV_MODE_SCALE;
- else if (mb->get_shift())
+ } else if (mb->get_shift()) {
uv_move_current = UV_MODE_MOVE;
- else if (mb->get_command())
+ } else if (mb->get_command()) {
uv_move_current = UV_MODE_ROTATE;
+ }
}
if (uv_move_current == UV_MODE_EDIT_POINT) {
-
point_drag_index = -1;
for (int i = 0; i < points_prev.size(); i++) {
-
Vector2 tuv = mtx.xform(points_prev[i]);
if (tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y)) < 8) {
uv_drag_from = tuv;
@@ -664,12 +636,10 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
if (uv_move_current == UV_MODE_ADD_POLYGON) {
-
int closest = -1;
float closest_dist = 1e20;
for (int i = 0; i < points_prev.size(); i++) {
-
Vector2 tuv = mtx.xform(points_prev[i]);
float dist = tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y));
if (dist < 8 && dist < closest_dist) {
@@ -717,8 +687,9 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
polys.resize(points.size());
for (int j = 0; j < polys.size(); j++) {
int idx = points[j];
- if (idx < 0 || idx >= points_prev.size())
+ if (idx < 0 || idx >= points_prev.size()) {
continue;
+ }
polys.write[j] = mtx.xform(points_prev[idx]);
}
@@ -740,7 +711,6 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
if (uv_move_current == UV_MODE_PAINT_WEIGHT || uv_move_current == UV_MODE_CLEAR_WEIGHT) {
-
int bone_selected = -1;
for (int i = 0; i < bone_scroll_vb->get_child_count(); i++) {
CheckBox *c = Object::cast_to<CheckBox>(bone_scroll_vb->get_child(i));
@@ -751,7 +721,6 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
if (bone_selected != -1 && node->get_bone_weights(bone_selected).size() == points_prev.size()) {
-
prev_weights = node->get_bone_weights(bone_selected);
bone_painting = true;
bone_painting_bone = bone_selected;
@@ -759,7 +728,6 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
} else if (uv_drag && !uv_create) {
-
if (uv_edit_mode[0]->is_pressed()) { // Edit UV.
undo_redo->create_action(TTR("Transform UV Map"));
undo_redo->add_do_method(node, "set_uv", node->get_uv());
@@ -778,7 +746,6 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
uv_drag = false;
} else if (bone_painting) {
-
undo_redo->create_action(TTR("Paint Bone Weights"));
undo_redo->add_do_method(node, "set_bone_weights", bone_painting_bone, node->get_bone_weights(bone_painting_bone));
undo_redo->add_undo_method(node, "set_bone_weights", bone_painting_bone, prev_weights);
@@ -789,19 +756,17 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
} else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
-
_cancel_editing();
- if (bone_painting)
+ if (bone_painting) {
node->set_bone_weights(bone_painting_bone, prev_weights);
+ }
uv_edit_draw->update();
} else if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
-
uv_zoom->set_value(uv_zoom->get_value() / (1 - (0.1 * mb->get_factor())));
} else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) {
-
uv_zoom->set_value(uv_zoom->get_value() * (1 - (0.1 * mb->get_factor())));
}
}
@@ -809,29 +774,23 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
Ref<InputEventMouseMotion> mm = p_input;
if (mm.is_valid()) {
-
- if ((mm->get_button_mask() & BUTTON_MASK_MIDDLE) || InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)) {
-
+ if ((mm->get_button_mask() & BUTTON_MASK_MIDDLE) || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
Vector2 drag(mm->get_relative().x, mm->get_relative().y);
uv_hscroll->set_value(uv_hscroll->get_value() - drag.x);
uv_vscroll->set_value(uv_vscroll->get_value() - drag.y);
} else if (uv_drag) {
-
Vector2 uv_drag_to = mm->get_position();
uv_drag_to = snap_point(uv_drag_to); // FIXME: Only works correctly with 'UV_MODE_EDIT_POINT', it's imprecise with the rest.
Vector2 drag = mtx.affine_inverse().xform(uv_drag_to) - mtx.affine_inverse().xform(uv_drag_from);
switch (uv_move_current) {
-
case UV_MODE_CREATE: {
-
if (uv_create) {
uv_create_to = mtx.affine_inverse().xform(snap_point(Vector2(mm->get_position().x, mm->get_position().y)));
}
} break;
case UV_MODE_EDIT_POINT: {
-
Vector<Vector2> uv_new = points_prev;
uv_new.set(point_drag_index, uv_new[point_drag_index] + drag);
@@ -842,10 +801,10 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
} break;
case UV_MODE_MOVE: {
-
Vector<Vector2> uv_new = points_prev;
- for (int i = 0; i < uv_new.size(); i++)
+ for (int i = 0; i < uv_new.size(); i++) {
uv_new.set(i, uv_new[i] + drag);
+ }
if (uv_edit_mode[0]->is_pressed()) { //edit uv
node->set_uv(uv_new);
@@ -854,12 +813,12 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
} break;
case UV_MODE_ROTATE: {
-
Vector2 center;
Vector<Vector2> uv_new = points_prev;
- for (int i = 0; i < uv_new.size(); i++)
+ for (int i = 0; i < uv_new.size(); i++) {
center += points_prev[i];
+ }
center /= uv_new.size();
float angle = (uv_drag_from - mtx.xform(center)).normalized().angle_to((uv_drag_to - mtx.xform(center)).normalized());
@@ -877,18 +836,19 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
}
} break;
case UV_MODE_SCALE: {
-
Vector2 center;
Vector<Vector2> uv_new = points_prev;
- for (int i = 0; i < uv_new.size(); i++)
+ for (int i = 0; i < uv_new.size(); i++) {
center += points_prev[i];
+ }
center /= uv_new.size();
float from_dist = uv_drag_from.distance_to(mtx.xform(center));
float to_dist = uv_drag_to.distance_to(mtx.xform(center));
- if (from_dist < 2)
+ if (from_dist < 2) {
break;
+ }
float scale = to_dist / from_dist;
@@ -906,7 +866,6 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
} break;
case UV_MODE_PAINT_WEIGHT:
case UV_MODE_CLEAR_WEIGHT: {
-
bone_paint_pos = Vector2(mm->get_position().x, mm->get_position().y);
} break;
default: {
@@ -952,22 +911,20 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
Ref<InputEventMagnifyGesture> magnify_gesture = p_input;
if (magnify_gesture.is_valid()) {
-
uv_zoom->set_value(uv_zoom->get_value() * magnify_gesture->get_factor());
}
Ref<InputEventPanGesture> pan_gesture = p_input;
if (pan_gesture.is_valid()) {
-
uv_hscroll->set_value(uv_hscroll->get_value() + uv_hscroll->get_page() * pan_gesture->get_delta().x / 8);
uv_vscroll->set_value(uv_vscroll->get_value() + uv_vscroll->get_page() * pan_gesture->get_delta().y / 8);
}
}
void Polygon2DEditor::_uv_scroll_changed(float) {
-
- if (updating_uv_scroll)
+ if (updating_uv_scroll) {
return;
+ }
uv_draw_ofs.x = uv_hscroll->get_value();
uv_draw_ofs.y = uv_vscroll->get_value();
@@ -976,13 +933,14 @@ void Polygon2DEditor::_uv_scroll_changed(float) {
}
void Polygon2DEditor::_uv_draw() {
-
- if (!uv_edit->is_visible() || !_get_node())
+ if (!uv_edit->is_visible() || !_get_node()) {
return;
+ }
Ref<Texture2D> base_tex = node->get_texture();
- if (base_tex.is_null())
+ if (base_tex.is_null()) {
return;
+ }
String warning;
@@ -1002,10 +960,12 @@ void Polygon2DEditor::_uv_draw() {
if (snap_step.x != 0) {
for (int i = 0; i < s.width; i++) {
int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(i, 0)).x - snap_offset.x) / snap_step.x));
- if (i == 0)
+ if (i == 0) {
last_cell = cell;
- if (last_cell != cell)
+ }
+ if (last_cell != cell) {
uv_edit_draw->draw_line(Point2(i, 0), Point2(i, s.height), grid_color, Math::round(EDSCALE));
+ }
last_cell = cell;
}
}
@@ -1013,10 +973,12 @@ void Polygon2DEditor::_uv_draw() {
if (snap_step.y != 0) {
for (int i = 0; i < s.height; i++) {
int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(0, i)).y - snap_offset.y) / snap_step.y));
- if (i == 0)
+ if (i == 0) {
last_cell = cell;
- if (last_cell != cell)
+ }
+ if (last_cell != cell) {
uv_edit_draw->draw_line(Point2(0, i), Point2(s.width, i), grid_color, Math::round(EDSCALE));
+ }
last_cell = cell;
}
}
@@ -1073,7 +1035,6 @@ void Polygon2DEditor::_uv_draw() {
}
for (int i = 0; i < uvs.size(); i++) {
-
int next = uv_draw_max > 0 ? (i + 1) % uv_draw_max : 0;
if (i < uv_draw_max && uv_drag && uv_move_current == UV_MODE_EDIT_POINT && EDITOR_DEF("editors/poly_editor/show_previous_outline", true)) {
@@ -1092,7 +1053,6 @@ void Polygon2DEditor::_uv_draw() {
}
for (int i = 0; i < polygons.size(); i++) {
-
Vector<int> points = polygons[i];
Vector<Vector2> polypoints;
for (int j = 0; j < points.size(); j++) {
@@ -1100,12 +1060,14 @@ void Polygon2DEditor::_uv_draw() {
int idx = points[j];
int idx_next = points[next];
- if (idx < 0 || idx >= uvs.size())
+ if (idx < 0 || idx >= uvs.size()) {
continue;
+ }
polypoints.push_back(mtx.xform(uvs[idx]));
- if (idx_next < 0 || idx_next >= uvs.size())
+ if (idx_next < 0 || idx_next >= uvs.size()) {
continue;
+ }
uv_edit_draw->draw_line(mtx.xform(uvs[idx]), mtx.xform(uvs[idx_next]), polygon_line_color, Math::round(EDSCALE));
}
if (points.size() >= 3) {
@@ -1114,7 +1076,6 @@ void Polygon2DEditor::_uv_draw() {
}
for (int i = 0; i < uvs.size(); i++) {
-
if (weight_r) {
Vector2 draw_pos = mtx.xform(uvs[i]);
float weight = weight_r[i];
@@ -1138,7 +1099,6 @@ void Polygon2DEditor::_uv_draw() {
}
if (uv_mode == UV_MODE_PAINT_WEIGHT || uv_mode == UV_MODE_CLEAR_WEIGHT) {
-
NodePath bone_path;
for (int i = 0; i < bone_scroll_vb->get_child_count(); i++) {
CheckBox *c = Object::cast_to<CheckBox>(bone_scroll_vb->get_child(i));
@@ -1154,20 +1114,20 @@ void Polygon2DEditor::_uv_draw() {
Skeleton2D *skeleton = Object::cast_to<Skeleton2D>(node->get_node(skeleton_path));
if (skeleton) {
for (int i = 0; i < skeleton->get_bone_count(); i++) {
-
Bone2D *bone = skeleton->get_bone(i);
- if (bone->get_rest() == Transform2D(0, 0, 0, 0, 0, 0))
+ if (bone->get_rest() == Transform2D(0, 0, 0, 0, 0, 0)) {
continue; //not set
+ }
bool current = bone_path == skeleton->get_path_to(bone);
bool found_child = false;
for (int j = 0; j < bone->get_child_count(); j++) {
-
Bone2D *n = Object::cast_to<Bone2D>(bone->get_child(j));
- if (!n)
+ if (!n) {
continue;
+ }
found_child = true;
@@ -1232,7 +1192,6 @@ void Polygon2DEditor::_uv_draw() {
}
void Polygon2DEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_update_bone_list"), &Polygon2DEditor::_update_bone_list);
ClassDB::bind_method(D_METHOD("_update_polygon_editing_state"), &Polygon2DEditor::_update_polygon_editing_state);
}
@@ -1248,7 +1207,6 @@ Vector2 Polygon2DEditor::snap_point(Vector2 p_target) const {
Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) :
AbstractPolygon2DEditor(p_editor) {
-
node = nullptr;
snap_offset = EditorSettings::get_singleton()->get_project_metadata("polygon_2d_uv_editor", "snap_offset", Vector2());
snap_step = EditorSettings::get_singleton()->get_project_metadata("polygon_2d_uv_editor", "snap_step", Vector2(10, 10));
@@ -1305,7 +1263,6 @@ Polygon2DEditor::Polygon2DEditor(EditorNode *p_editor) :
uv_main_vb->add_child(uv_mode_hb);
for (int i = 0; i < UV_MODE_MAX; i++) {
-
uv_button[i] = memnew(ToolButton);
uv_button[i]->set_toggle_mode(true);
uv_mode_hb->add_child(uv_button[i]);
diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h
index 2b00b50e5c..b94ae53e2b 100644
--- a/editor/plugins/polygon_2d_editor_plugin.h
+++ b/editor/plugins/polygon_2d_editor_plugin.h
@@ -35,7 +35,6 @@
#include "scene/gui/scroll_container.h"
class Polygon2DEditor : public AbstractPolygon2DEditor {
-
GDCLASS(Polygon2DEditor, AbstractPolygon2DEditor);
enum Mode {
@@ -165,7 +164,6 @@ public:
};
class Polygon2DEditorPlugin : public AbstractPolygon2DEditorPlugin {
-
GDCLASS(Polygon2DEditorPlugin, AbstractPolygon2DEditorPlugin);
public:
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index 852feeb675..75cb93ee76 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -39,13 +39,11 @@ void ResourcePreloaderEditor::_gui_input(Ref<InputEvent> p_event) {
}
void ResourcePreloaderEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
load->set_icon(get_theme_icon("Folder", "EditorIcons"));
}
if (p_what == NOTIFICATION_READY) {
-
//NodePath("/root")->connect("node_removed", this,"_node_removed",Vector<Variant>(),true);
}
@@ -54,9 +52,7 @@ void ResourcePreloaderEditor::_notification(int p_what) {
}
void ResourcePreloaderEditor::_files_load_request(const Vector<String> &p_paths) {
-
for (int i = 0; i < p_paths.size(); i++) {
-
String path = p_paths[i];
RES resource;
@@ -89,14 +85,14 @@ void ResourcePreloaderEditor::_files_load_request(const Vector<String> &p_paths)
}
void ResourcePreloaderEditor::_load_pressed() {
-
loading_scene = false;
file->clear_filters();
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("", &extensions);
- for (int i = 0; i < extensions.size(); i++)
+ for (int i = 0; i < extensions.size(); i++) {
file->add_filter("*." + extensions[i]);
+ }
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES);
@@ -104,9 +100,9 @@ void ResourcePreloaderEditor::_load_pressed() {
}
void ResourcePreloaderEditor::_item_edited() {
-
- if (!tree->get_selected())
+ if (!tree->get_selected()) {
return;
+ }
TreeItem *s = tree->get_selected();
@@ -114,11 +110,11 @@ void ResourcePreloaderEditor::_item_edited() {
// renamed
String old_name = s->get_metadata(0);
String new_name = s->get_text(0);
- if (old_name == new_name)
+ if (old_name == new_name) {
return;
+ }
if (new_name == "" || new_name.find("\\") != -1 || new_name.find("/") != -1 || preloader->has_resource(new_name)) {
-
s->set_text(0, old_name);
return;
}
@@ -136,7 +132,6 @@ void ResourcePreloaderEditor::_item_edited() {
}
void ResourcePreloaderEditor::_remove_resource(const String &p_to_remove) {
-
undo_redo->create_action(TTR("Delete Resource"));
undo_redo->add_do_method(preloader, "remove_resource", p_to_remove);
undo_redo->add_undo_method(preloader, "add_resource", p_to_remove, preloader->get_resource(p_to_remove));
@@ -146,7 +141,6 @@ void ResourcePreloaderEditor::_remove_resource(const String &p_to_remove) {
}
void ResourcePreloaderEditor::_paste_pressed() {
-
RES r = EditorSettings::get_singleton()->get_resource_clipboard();
if (!r.is_valid()) {
dialog->set_text(TTR("Resource clipboard is empty!"));
@@ -157,10 +151,12 @@ void ResourcePreloaderEditor::_paste_pressed() {
}
String name = r->get_name();
- if (name == "")
+ if (name == "") {
name = r->get_path().get_file();
- if (name == "")
+ }
+ if (name == "") {
name = r->get_class();
+ }
String basename = name;
int counter = 1;
@@ -178,7 +174,6 @@ void ResourcePreloaderEditor::_paste_pressed() {
}
void ResourcePreloaderEditor::_update_library() {
-
tree->clear();
tree->set_hide_root(true);
TreeItem *root = tree->create_item(nullptr);
@@ -194,7 +189,6 @@ void ResourcePreloaderEditor::_update_library() {
names.sort();
for (List<String>::Element *E = names.front(); E; E = E->next()) {
-
TreeItem *ti = tree->create_item(root);
ti->set_cell_mode(0, TreeItem::CELL_MODE_STRING);
ti->set_editable(0, true);
@@ -226,7 +220,6 @@ void ResourcePreloaderEditor::_update_library() {
}
void ResourcePreloaderEditor::_cell_button_pressed(Object *p_item, int p_column, int p_id) {
-
TreeItem *item = Object::cast_to<TreeItem>(p_item);
ERR_FAIL_COND(!item);
@@ -244,42 +237,42 @@ void ResourcePreloaderEditor::_cell_button_pressed(Object *p_item, int p_column,
}
void ResourcePreloaderEditor::edit(ResourcePreloader *p_preloader) {
-
preloader = p_preloader;
if (p_preloader) {
_update_library();
} else {
-
hide();
set_physics_process(false);
}
}
Variant ResourcePreloaderEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
TreeItem *ti = tree->get_item_at_position(p_point);
- if (!ti)
+ if (!ti) {
return Variant();
+ }
String name = ti->get_metadata(0);
RES res = preloader->get_resource(name);
- if (!res.is_valid())
+ if (!res.is_valid()) {
return Variant();
+ }
return EditorNode::get_singleton()->drag_resource(res, p_from);
}
bool ResourcePreloaderEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return false;
+ }
- if (d.has("from") && (Object *)(d["from"]) == tree)
+ if (d.has("from") && (Object *)(d["from"]) == tree) {
return false;
+ }
if (String(d["type"]) == "resource" && d.has("resource")) {
RES r = d["resource"];
@@ -288,7 +281,6 @@ bool ResourcePreloaderEditor::can_drop_data_fw(const Point2 &p_point, const Vari
}
if (String(d["type"]) == "files") {
-
Vector<String> files = d["files"];
return files.size() != 0;
@@ -297,20 +289,20 @@ bool ResourcePreloaderEditor::can_drop_data_fw(const Point2 &p_point, const Vari
}
void ResourcePreloaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
-
- if (!can_drop_data_fw(p_point, p_data, p_from))
+ if (!can_drop_data_fw(p_point, p_data, p_from)) {
return;
+ }
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return;
+ }
if (String(d["type"]) == "resource" && d.has("resource")) {
RES r = d["resource"];
if (r.is_valid()) {
-
String basename;
if (r->get_name() != "") {
basename = r->get_name();
@@ -337,7 +329,6 @@ void ResourcePreloaderEditor::drop_data_fw(const Point2 &p_point, const Variant
}
if (String(d["type"]) == "files") {
-
Vector<String> files = d["files"];
_files_load_request(files);
@@ -345,7 +336,6 @@ void ResourcePreloaderEditor::drop_data_fw(const Point2 &p_point, const Variant
}
void ResourcePreloaderEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &ResourcePreloaderEditor::_gui_input);
ClassDB::bind_method(D_METHOD("_update_library"), &ResourcePreloaderEditor::_update_library);
ClassDB::bind_method(D_METHOD("_remove_resource", "to_remove"), &ResourcePreloaderEditor::_remove_resource);
@@ -356,7 +346,6 @@ void ResourcePreloaderEditor::_bind_methods() {
}
ResourcePreloaderEditor::ResourcePreloaderEditor() {
-
//add_style_override("panel", EditorNode::get_singleton()->get_gui_base()->get_stylebox("panel","Panel"));
VBoxContainer *vbc = memnew(VBoxContainer);
@@ -399,31 +388,29 @@ ResourcePreloaderEditor::ResourcePreloaderEditor() {
}
void ResourcePreloaderEditorPlugin::edit(Object *p_object) {
-
preloader_editor->set_undo_redo(&get_undo_redo());
ResourcePreloader *s = Object::cast_to<ResourcePreloader>(p_object);
- if (!s)
+ if (!s) {
return;
+ }
preloader_editor->edit(s);
}
bool ResourcePreloaderEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("ResourcePreloader");
}
void ResourcePreloaderEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
//preloader_editor->show();
button->show();
editor->make_bottom_panel_item_visible(preloader_editor);
//preloader_editor->set_process(true);
} else {
-
- if (preloader_editor->is_visible_in_tree())
+ if (preloader_editor->is_visible_in_tree()) {
editor->hide_bottom_panel();
+ }
button->hide();
//preloader_editor->hide();
//preloader_editor->set_process(false);
@@ -431,7 +418,6 @@ void ResourcePreloaderEditorPlugin::make_visible(bool p_visible) {
}
ResourcePreloaderEditorPlugin::ResourcePreloaderEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
preloader_editor = memnew(ResourcePreloaderEditor);
preloader_editor->set_custom_minimum_size(Size2(0, 250) * EDSCALE);
diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h
index 88e9cf4956..2d7a54eda5 100644
--- a/editor/plugins/resource_preloader_editor_plugin.h
+++ b/editor/plugins/resource_preloader_editor_plugin.h
@@ -39,7 +39,6 @@
#include "scene/main/resource_preloader.h"
class ResourcePreloaderEditor : public PanelContainer {
-
GDCLASS(ResourcePreloaderEditor, PanelContainer);
enum {
@@ -87,7 +86,6 @@ public:
};
class ResourcePreloaderEditorPlugin : public EditorPlugin {
-
GDCLASS(ResourcePreloaderEditorPlugin, EditorPlugin);
ResourcePreloaderEditor *preloader_editor;
diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp
index a7120c5d68..e107435373 100644
--- a/editor/plugins/root_motion_editor_plugin.cpp
+++ b/editor/plugins/root_motion_editor_plugin.cpp
@@ -33,10 +33,10 @@
#include "scene/main/window.h"
void EditorPropertyRootMotion::_confirmed() {
-
TreeItem *ti = filters->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
NodePath path = ti->get_metadata(0);
emit_changed(get_edited_property(), path);
@@ -45,7 +45,6 @@ void EditorPropertyRootMotion::_confirmed() {
}
void EditorPropertyRootMotion::_node_assign() {
-
NodePath current = get_edited_object()->get(get_edited_property());
AnimationTree *atree = Object::cast_to<AnimationTree>(get_edited_object());
@@ -72,7 +71,6 @@ void EditorPropertyRootMotion::_node_assign() {
player->get_animation_list(&animations);
for (List<StringName>::Element *E = animations.front(); E; E = E->next()) {
-
Ref<Animation> anim = player->get_animation(E->get());
for (int i = 0; i < anim->get_track_count(); i++) {
paths.insert(anim->track_get_path(i));
@@ -86,7 +84,6 @@ void EditorPropertyRootMotion::_node_assign() {
Map<String, TreeItem *> parenthood;
for (Set<String>::Element *E = paths.front(); E; E = E->next()) {
-
NodePath path = E->get();
TreeItem *ti = nullptr;
String accum;
@@ -121,11 +118,11 @@ void EditorPropertyRootMotion::_node_assign() {
if (base->has_node(accum)) {
node = base->get_node(accum);
}
- if (!node)
+ if (!node) {
continue; //no node, can't edit
+ }
if (path.get_subname_count()) {
-
String concat = path.get_concatenated_subnames();
Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node);
@@ -194,13 +191,11 @@ void EditorPropertyRootMotion::_node_assign() {
}
void EditorPropertyRootMotion::_node_clear() {
-
emit_changed(get_edited_property(), NodePath());
update_property();
}
void EditorPropertyRootMotion::update_property() {
-
NodePath p = get_edited_object()->get(get_edited_property());
assign->set_tooltip(p);
@@ -235,12 +230,10 @@ void EditorPropertyRootMotion::update_property() {
}
void EditorPropertyRootMotion::setup(const NodePath &p_base_hint) {
-
base_hint = p_base_hint;
}
void EditorPropertyRootMotion::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
Ref<Texture2D> t = get_theme_icon("Clear", "EditorIcons");
clear->set_icon(t);
@@ -251,7 +244,6 @@ void EditorPropertyRootMotion::_bind_methods() {
}
EditorPropertyRootMotion::EditorPropertyRootMotion() {
-
HBoxContainer *hbc = memnew(HBoxContainer);
add_child(hbc);
assign = memnew(Button);
@@ -278,6 +270,7 @@ EditorPropertyRootMotion::EditorPropertyRootMotion() {
filters->connect("item_activated", callable_mp(this, &EditorPropertyRootMotion::_confirmed));
//filters->connect("item_edited", this, "_filter_edited");
}
+
//////////////////////////
bool EditorInspectorRootMotionPlugin::can_handle(Object *p_object) {
@@ -289,7 +282,6 @@ void EditorInspectorRootMotionPlugin::parse_begin(Object *p_object) {
}
bool EditorInspectorRootMotionPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
-
if (p_path == "root_motion_track" && p_object->is_class("AnimationTree") && p_type == Variant::NODE_PATH) {
EditorPropertyRootMotion *editor = memnew(EditorPropertyRootMotion);
if (p_hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && p_hint_text != String()) {
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 2c831979de..8d6dac3907 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -30,7 +30,7 @@
#include "script_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/resource_loader.h"
#include "core/os/file_access.h"
#include "core/os/keyboard.h"
@@ -54,7 +54,6 @@
/*** SCRIPT EDITOR ****/
void ScriptEditorBase::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("name_changed"));
ADD_SIGNAL(MethodInfo("edited_script_changed"));
ADD_SIGNAL(MethodInfo("request_help", PropertyInfo(Variant::STRING, "topic")));
@@ -73,7 +72,6 @@ static bool _is_built_in_script(Script *p_script) {
}
class EditorScriptCodeCompletionCache : public ScriptCodeCompletionCache {
-
struct Cache {
uint64_t time_loaded;
RES cache;
@@ -86,7 +84,6 @@ public:
int max_cache_size;
void cleanup() {
-
List<Map<String, Cache>::Element *> to_clean;
Map<String, Cache>::Element *I = cached.front();
@@ -104,10 +101,8 @@ public:
}
virtual RES get_cached_resource(const String &p_path) {
-
Map<String, Cache>::Element *E = cached.find(p_path);
if (!E) {
-
Cache c;
c.cache = ResourceLoader::load(p_path);
E = cached.insert(p_path, c);
@@ -137,7 +132,6 @@ public:
}
EditorScriptCodeCompletionCache() {
-
max_cache_size = 128;
max_time_cache = 5 * 60 * 1000; //minutes, five
}
@@ -146,50 +140,45 @@ public:
};
void ScriptEditorQuickOpen::popup_dialog(const Vector<String> &p_functions, bool p_dontclear) {
-
popup_centered_ratio(0.6);
- if (p_dontclear)
+ if (p_dontclear) {
search_box->select_all();
- else
+ } else {
search_box->clear();
+ }
search_box->grab_focus();
functions = p_functions;
_update_search();
}
void ScriptEditorQuickOpen::_text_changed(const String &p_newtext) {
-
_update_search();
}
void ScriptEditorQuickOpen::_sbox_input(const Ref<InputEvent> &p_ie) {
-
Ref<InputEventKey> k = p_ie;
if (k.is_valid() && (k->get_keycode() == KEY_UP ||
k->get_keycode() == KEY_DOWN ||
k->get_keycode() == KEY_PAGEUP ||
k->get_keycode() == KEY_PAGEDOWN)) {
-
search_options->call("_gui_input", k);
search_box->accept_event();
}
}
void ScriptEditorQuickOpen::_update_search() {
-
search_options->clear();
TreeItem *root = search_options->create_item();
for (int i = 0; i < functions.size(); i++) {
-
String file = functions[i];
if ((search_box->get_text() == "" || file.findn(search_box->get_text()) != -1)) {
-
TreeItem *ti = search_options->create_item(root);
ti->set_text(0, file);
- if (root->get_children() == ti)
+ if (root->get_children() == ti) {
ti->select(0);
+ }
}
}
@@ -197,10 +186,10 @@ void ScriptEditorQuickOpen::_update_search() {
}
void ScriptEditorQuickOpen::_confirmed() {
-
TreeItem *ti = search_options->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
int line = ti->get_text(0).get_slice(":", 1).to_int();
emit_signal("goto_line", line - 1);
@@ -208,7 +197,6 @@ void ScriptEditorQuickOpen::_confirmed() {
}
void ScriptEditorQuickOpen::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
connect("confirmed", callable_mp(this, &ScriptEditorQuickOpen::_confirmed));
@@ -226,12 +214,10 @@ void ScriptEditorQuickOpen::_notification(int p_what) {
}
void ScriptEditorQuickOpen::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("goto_line", PropertyInfo(Variant::INT, "line")));
}
ScriptEditorQuickOpen::ScriptEditorQuickOpen() {
-
VBoxContainer *vbc = memnew(VBoxContainer);
add_child(vbc);
search_box = memnew(LineEdit);
@@ -257,24 +243,20 @@ ScriptEditor *ScriptEditor::script_editor = nullptr;
/*** SCRIPT EDITOR ******/
String ScriptEditor::_get_debug_tooltip(const String &p_text, Node *_se) {
-
String val = EditorDebuggerNode::get_singleton()->get_var_value(p_text);
if (val != String()) {
return p_text + ": " + val;
} else {
-
return String();
}
}
void ScriptEditor::_breaked(bool p_breaked, bool p_can_debug) {
-
if (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) {
return;
}
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (!se) {
continue;
@@ -289,14 +271,13 @@ void ScriptEditor::_script_created(Ref<Script> p_script) {
}
void ScriptEditor::_goto_script_line2(int p_line) {
-
ScriptEditorBase *current = _get_current_editor();
- if (current)
+ if (current) {
current->goto_line(p_line);
+ }
}
void ScriptEditor::_goto_script_line(REF p_script, int p_line) {
-
Ref<Script> script = Object::cast_to<Script>(*p_script);
if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) {
if (edit(p_script, p_line, 0)) {
@@ -316,10 +297,10 @@ void ScriptEditor::_set_execution(REF p_script, int p_line) {
Ref<Script> script = Object::cast_to<Script>(*p_script);
if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) {
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
- if (!se)
+ if (!se) {
continue;
+ }
if ((script != nullptr && se->get_edited_resource() == p_script) || se->get_edited_resource()->get_path() == script->get_path()) {
se->set_executing_line(p_line);
@@ -332,10 +313,10 @@ void ScriptEditor::_clear_execution(REF p_script) {
Ref<Script> script = Object::cast_to<Script>(*p_script);
if (script.is_valid() && (script->has_source_code() || script->get_path().is_resource_file())) {
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
- if (!se)
+ if (!se) {
continue;
+ }
if ((script != nullptr && se->get_edited_resource() == p_script) || se->get_edited_resource()->get_path() == script->get_path()) {
se->clear_executing_line();
@@ -345,32 +326,27 @@ void ScriptEditor::_clear_execution(REF p_script) {
}
ScriptEditorBase *ScriptEditor::_get_current_editor() const {
-
int selected = tab_container->get_current_tab();
- if (selected < 0 || selected >= tab_container->get_child_count())
+ if (selected < 0 || selected >= tab_container->get_child_count()) {
return nullptr;
+ }
return Object::cast_to<ScriptEditorBase>(tab_container->get_child(selected));
}
void ScriptEditor::_update_history_arrows() {
-
script_back->set_disabled(history_pos <= 0);
script_forward->set_disabled(history_pos >= history.size() - 1);
}
void ScriptEditor::_save_history() {
-
if (history_pos >= 0 && history_pos < history.size() && history[history_pos].control == tab_container->get_current_tab_control()) {
-
Node *n = tab_container->get_current_tab_control();
if (Object::cast_to<ScriptEditorBase>(n)) {
-
history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
}
if (Object::cast_to<EditorHelp>(n)) {
-
history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
}
}
@@ -387,29 +363,25 @@ void ScriptEditor::_save_history() {
}
void ScriptEditor::_go_to_tab(int p_idx) {
-
ScriptEditorBase *current = _get_current_editor();
if (current) {
if (current->is_unsaved()) {
-
current->apply_code();
}
}
Control *c = Object::cast_to<Control>(tab_container->get_child(p_idx));
- if (!c)
+ if (!c) {
return;
+ }
if (history_pos >= 0 && history_pos < history.size() && history[history_pos].control == tab_container->get_current_tab_control()) {
-
Node *n = tab_container->get_current_tab_control();
if (Object::cast_to<ScriptEditorBase>(n)) {
-
history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
}
if (Object::cast_to<EditorHelp>(n)) {
-
history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
}
}
@@ -427,11 +399,11 @@ void ScriptEditor::_go_to_tab(int p_idx) {
c = tab_container->get_current_tab_control();
if (Object::cast_to<ScriptEditorBase>(c)) {
-
script_name_label->set_text(Object::cast_to<ScriptEditorBase>(c)->get_name());
script_icon->set_texture(Object::cast_to<ScriptEditorBase>(c)->get_theme_icon());
- if (is_visible_in_tree())
+ if (is_visible_in_tree()) {
Object::cast_to<ScriptEditorBase>(c)->ensure_focus();
+ }
Ref<Script> script = Object::cast_to<ScriptEditorBase>(c)->get_edited_resource();
if (script != nullptr) {
@@ -441,11 +413,11 @@ void ScriptEditor::_go_to_tab(int p_idx) {
Object::cast_to<ScriptEditorBase>(c)->validate();
}
if (Object::cast_to<EditorHelp>(c)) {
-
script_name_label->set_text(Object::cast_to<EditorHelp>(c)->get_class());
script_icon->set_texture(get_theme_icon("Help", "EditorIcons"));
- if (is_visible_in_tree())
+ if (is_visible_in_tree()) {
Object::cast_to<EditorHelp>(c)->set_focused();
+ }
}
c->set_meta("__editor_pass", ++edit_pass);
@@ -459,7 +431,6 @@ void ScriptEditor::_go_to_tab(int p_idx) {
}
void ScriptEditor::_add_recent_script(String p_path) {
-
if (p_path.empty()) {
return;
}
@@ -478,13 +449,11 @@ void ScriptEditor::_add_recent_script(String p_path) {
}
void ScriptEditor::_update_recent_scripts() {
-
Array rc = EditorSettings::get_singleton()->get_project_metadata("recent_files", "scripts", Array());
recent_scripts->clear();
String path;
for (int i = 0; i < rc.size(); i++) {
-
path = rc[i];
recent_scripts->add_item(path.replace("res://", ""));
}
@@ -496,7 +465,6 @@ void ScriptEditor::_update_recent_scripts() {
}
void ScriptEditor::_open_recent_script(int p_idx) {
-
// clear button
if (p_idx == recent_scripts->get_item_count() - 1) {
EditorSettings::get_singleton()->set_project_metadata("recent_files", "scripts", Array());
@@ -555,16 +523,15 @@ void ScriptEditor::_open_recent_script(int p_idx) {
}
void ScriptEditor::_show_error_dialog(String p_path) {
-
error_dialog->set_text(vformat(TTR("Can't open '%s'. The file could have been moved or deleted."), p_path));
error_dialog->popup_centered();
}
void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
-
int selected = p_idx;
- if (selected < 0 || selected >= tab_container->get_child_count())
+ if (selected < 0 || selected >= tab_container->get_child_count()) {
return;
+ }
Node *tselected = tab_container->get_child(selected);
@@ -606,10 +573,10 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
current->clear_edit_menu();
}
memdelete(tselected);
- if (idx >= tab_container->get_child_count())
+ if (idx >= tab_container->get_child_count()) {
idx = tab_container->get_child_count() - 1;
+ }
if (idx >= 0) {
-
if (history_pos >= 0) {
idx = history[history_pos].control->get_index();
}
@@ -627,7 +594,6 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save, bool p_history_back) {
}
void ScriptEditor::_close_current_tab() {
-
_close_tab(tab_container->get_current_tab());
}
@@ -637,10 +603,8 @@ void ScriptEditor::_close_discard_current_tab(const String &p_str) {
}
void ScriptEditor::_close_docs_tab() {
-
int child_count = tab_container->get_child_count();
for (int i = child_count - 1; i >= 0; i--) {
-
EditorHelp *se = Object::cast_to<EditorHelp>(tab_container->get_child(i));
if (se) {
@@ -656,11 +620,9 @@ void ScriptEditor::_copy_script_path() {
}
void ScriptEditor::_close_other_tabs() {
-
int child_count = tab_container->get_child_count();
int current_idx = tab_container->get_current_tab();
for (int i = child_count - 1; i >= 0; i--) {
-
if (i == current_idx) {
continue;
}
@@ -669,7 +631,6 @@ void ScriptEditor::_close_other_tabs() {
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (se) {
-
// Maybe there are unsaved changes
if (se->is_unsaved()) {
_ask_close_current_unsaved_tab(se);
@@ -682,15 +643,12 @@ void ScriptEditor::_close_other_tabs() {
}
void ScriptEditor::_close_all_tabs() {
-
int child_count = tab_container->get_child_count();
for (int i = child_count - 1; i >= 0; i--) {
-
tab_container->set_current_tab(i);
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (se) {
-
// Maybe there are unsaved changes
if (se->is_unsaved()) {
_ask_close_current_unsaved_tab(se);
@@ -708,19 +666,19 @@ void ScriptEditor::_ask_close_current_unsaved_tab(ScriptEditorBase *current) {
}
void ScriptEditor::_resave_scripts(const String &p_str) {
-
apply_scripts();
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
- if (!se)
+ if (!se) {
continue;
+ }
RES script = se->get_edited_resource();
- if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1)
+ if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1) {
continue; //internal script, who cares
+ }
if (trim_trailing_whitespace_on_save) {
se->trim_trailing_whitespace();
@@ -751,19 +709,15 @@ void ScriptEditor::_resave_scripts(const String &p_str) {
}
void ScriptEditor::_reload_scripts() {
-
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (!se) {
-
continue;
}
RES edited_res = se->get_edited_resource();
if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1) {
-
continue; //internal script, who cares
}
@@ -799,12 +753,9 @@ void ScriptEditor::_reload_scripts() {
}
void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) {
-
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (!se) {
-
continue;
}
@@ -815,7 +766,6 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource> &p_res) {
}
if (script == p_res) {
-
se->tag_saved_version();
}
}
@@ -834,7 +784,6 @@ void ScriptEditor::_live_auto_reload_running_scripts() {
}
bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) {
-
disk_changed_list->clear();
TreeItem *r = disk_changed_list->create_item();
disk_changed_list->set_hide_root(true);
@@ -844,22 +793,21 @@ bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) {
bool use_autoreload = bool(EDITOR_DEF("text_editor/files/auto_reload_scripts_on_external_change", false));
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (se) {
-
RES edited_res = se->get_edited_resource();
- if (p_for_script.is_valid() && edited_res.is_valid() && p_for_script != edited_res)
+ if (p_for_script.is_valid() && edited_res.is_valid() && p_for_script != edited_res) {
continue;
+ }
- if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1)
+ if (edited_res->get_path() == "" || edited_res->get_path().find("local://") != -1 || edited_res->get_path().find("::") != -1) {
continue; //internal script, who cares
+ }
uint64_t last_date = edited_res->get_last_modified_time();
uint64_t date = FileAccess::get_modified_time(edited_res->get_path());
if (last_date != date) {
-
TreeItem *ti = disk_changed_list->create_item(r);
ti->set_text(0, edited_res->get_path().get_file());
@@ -884,7 +832,6 @@ bool ScriptEditor::_test_script_times_on_disk(RES p_for_script) {
}
void ScriptEditor::_file_dialog_action(String p_file) {
-
switch (file_dialog_option) {
case FILE_NEW_TEXTFILE: {
Error err;
@@ -899,7 +846,6 @@ void ScriptEditor::_file_dialog_action(String p_file) {
[[fallthrough]];
}
case FILE_OPEN: {
-
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
if (extensions.find(p_file.get_extension())) {
@@ -956,7 +902,6 @@ void ScriptEditor::_file_dialog_action(String p_file) {
}
Ref<Script> ScriptEditor::_get_current_script() {
-
ScriptEditorBase *current = _get_current_editor();
if (current) {
@@ -968,7 +913,6 @@ Ref<Script> ScriptEditor::_get_current_script() {
}
Array ScriptEditor::_get_open_scripts() const {
-
Array ret;
Vector<Ref<Script>> scripts = get_open_scripts();
int scrits_amount = scripts.size();
@@ -988,7 +932,6 @@ bool ScriptEditor::is_scripts_panel_toggled() {
}
void ScriptEditor::_menu_option(int p_option) {
-
ScriptEditorBase *current = _get_current_editor();
switch (p_option) {
case FILE_NEW: {
@@ -1021,9 +964,9 @@ void ScriptEditor::_menu_option(int p_option) {
return;
} break;
case FILE_REOPEN_CLOSED: {
-
- if (previous_scripts.empty())
+ if (previous_scripts.empty()) {
return;
+ }
String path = previous_scripts.back()->get();
previous_scripts.pop_back();
@@ -1060,8 +1003,9 @@ void ScriptEditor::_menu_option(int p_option) {
} else {
Error error;
Ref<TextFile> text_file = _load_text_file(path, &error);
- if (error != OK)
+ if (error != OK) {
editor->show_warning(TTR("Could not load file at:") + "\n\n" + path, TTR("Error!"));
+ }
if (text_file.is_valid()) {
edit(text_file);
@@ -1071,34 +1015,28 @@ void ScriptEditor::_menu_option(int p_option) {
}
} break;
case FILE_SAVE_ALL: {
-
- if (_test_script_times_on_disk())
+ if (_test_script_times_on_disk()) {
return;
+ }
save_all_scripts();
} break;
case SEARCH_IN_FILES: {
-
_on_find_in_files_requested("");
} break;
case REPLACE_IN_FILES: {
-
_on_replace_in_files_requested("");
} break;
case SEARCH_HELP: {
-
help_search_dialog->popup_dialog();
} break;
case SEARCH_WEBSITE: {
-
OS::get_singleton()->shell_open("https://docs.godotengine.org/");
} break;
case WINDOW_NEXT: {
-
_history_forward();
} break;
case WINDOW_PREV: {
-
_history_back();
} break;
case WINDOW_SORT: {
@@ -1119,15 +1057,15 @@ void ScriptEditor::_menu_option(int p_option) {
}
if (current) {
-
switch (p_option) {
case FILE_SAVE: {
-
- if (_test_script_times_on_disk())
+ if (_test_script_times_on_disk()) {
return;
+ }
- if (trim_trailing_whitespace_on_save)
+ if (trim_trailing_whitespace_on_save) {
current->trim_trailing_whitespace();
+ }
current->insert_final_newline();
@@ -1149,9 +1087,9 @@ void ScriptEditor::_menu_option(int p_option) {
} break;
case FILE_SAVE_AS: {
-
- if (trim_trailing_whitespace_on_save)
+ if (trim_trailing_whitespace_on_save) {
current->trim_trailing_whitespace();
+ }
current->insert_final_newline();
@@ -1186,12 +1124,10 @@ void ScriptEditor::_menu_option(int p_option) {
case FILE_TOOL_RELOAD:
case FILE_TOOL_RELOAD_SOFT: {
-
current->reload(p_option == FILE_TOOL_RELOAD_SOFT);
} break;
case FILE_RUN: {
-
Ref<Script> scr = current->get_edited_resource();
if (scr == nullptr || scr.is_null()) {
EditorNode::get_singleton()->show_warning(TTR("Can't obtain the script for running."));
@@ -1206,13 +1142,11 @@ void ScriptEditor::_menu_option(int p_option) {
return;
}
if (!scr->is_tool()) {
-
EditorNode::get_singleton()->show_warning(TTR("Script is not in tool mode, will not be able to run."));
return;
}
if (!ClassDB::is_parent_class(scr->get_instance_base_type(), "EditorScript")) {
-
EditorNode::get_singleton()->show_warning(TTR("To run this script, it must inherit EditorScript and be set to tool mode."));
return;
}
@@ -1256,7 +1190,6 @@ void ScriptEditor::_menu_option(int p_option) {
_close_all_tabs();
} break;
case WINDOW_MOVE_UP: {
-
if (tab_container->get_current_tab() > 0) {
tab_container->move_child(current, tab_container->get_current_tab() - 1);
tab_container->set_current_tab(tab_container->get_current_tab() - 1);
@@ -1264,7 +1197,6 @@ void ScriptEditor::_menu_option(int p_option) {
}
} break;
case WINDOW_MOVE_DOWN: {
-
if (tab_container->get_current_tab() < tab_container->get_child_count() - 1) {
tab_container->move_child(current, tab_container->get_current_tab() + 1);
tab_container->set_current_tab(tab_container->get_current_tab() + 1);
@@ -1272,19 +1204,15 @@ void ScriptEditor::_menu_option(int p_option) {
}
} break;
default: {
-
if (p_option >= WINDOW_SELECT_BASE) {
-
tab_container->set_current_tab(p_option - WINDOW_SELECT_BASE);
_update_script_names();
}
}
}
} else {
-
EditorHelp *help = Object::cast_to<EditorHelp>(tab_container->get_current_tab_control());
if (help) {
-
switch (p_option) {
case HELP_SEARCH_FIND: {
help->popup_search();
@@ -1308,7 +1236,6 @@ void ScriptEditor::_menu_option(int p_option) {
_close_all_tabs();
} break;
case WINDOW_MOVE_UP: {
-
if (tab_container->get_current_tab() > 0) {
tab_container->move_child(help, tab_container->get_current_tab() - 1);
tab_container->set_current_tab(tab_container->get_current_tab() - 1);
@@ -1316,7 +1243,6 @@ void ScriptEditor::_menu_option(int p_option) {
}
} break;
case WINDOW_MOVE_DOWN: {
-
if (tab_container->get_current_tab() < tab_container->get_child_count() - 1) {
tab_container->move_child(help, tab_container->get_current_tab() + 1);
tab_container->set_current_tab(tab_container->get_current_tab() + 1);
@@ -1367,16 +1293,12 @@ void ScriptEditor::_show_save_theme_as_dialog() {
}
void ScriptEditor::_tab_changed(int p_which) {
-
ensure_select_current();
}
void ScriptEditor::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
editor->connect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop));
editor->connect("script_add_function_request", callable_mp(this, &ScriptEditor::_add_callback));
editor->connect("resource_saved", callable_mp(this, &ScriptEditor::_res_saved_callback));
@@ -1390,7 +1312,6 @@ void ScriptEditor::_notification(int p_what) {
[[fallthrough]];
}
case NOTIFICATION_THEME_CHANGED: {
-
help_search->set_icon(get_theme_icon("HelpSearch", "EditorIcons"));
site_search->set_icon(get_theme_icon("Instance", "EditorIcons"));
@@ -1408,25 +1329,21 @@ void ScriptEditor::_notification(int p_what) {
} break;
case NOTIFICATION_READY: {
-
get_tree()->connect("tree_changed", callable_mp(this, &ScriptEditor::_tree_changed));
editor->get_inspector_dock()->connect("request_help", callable_mp(this, &ScriptEditor::_help_class_open));
editor->connect("request_help_search", callable_mp(this, &ScriptEditor::_help_search));
} break;
case NOTIFICATION_EXIT_TREE: {
-
editor->disconnect("stop_pressed", callable_mp(this, &ScriptEditor::_editor_stop));
} break;
case NOTIFICATION_WM_FOCUS_IN: {
-
_test_script_times_on_disk();
_update_modified_scripts_for_external_editor();
} break;
case CanvasItem::NOTIFICATION_VISIBILITY_CHANGED: {
-
if (is_visible()) {
find_in_files_button->show();
} else {
@@ -1444,25 +1361,23 @@ void ScriptEditor::_notification(int p_what) {
}
bool ScriptEditor::can_take_away_focus() const {
-
ScriptEditorBase *current = _get_current_editor();
- if (current)
+ if (current) {
return current->can_lose_focus_on_node_selection();
- else
+ } else {
return true;
+ }
}
void ScriptEditor::close_builtin_scripts_from_scene(const String &p_scene) {
-
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (se) {
-
Ref<Script> script = se->get_edited_resource();
- if (script == nullptr || !script.is_valid())
+ if (script == nullptr || !script.is_valid()) {
continue;
+ }
if (script->get_path().find("::") != -1 && script->get_path().begins_with(p_scene)) { //is an internal script and belongs to scene being closed
_close_tab(i);
@@ -1473,7 +1388,6 @@ void ScriptEditor::close_builtin_scripts_from_scene(const String &p_scene) {
}
void ScriptEditor::edited_scene_changed() {
-
_update_modified_scripts_for_external_editor();
}
@@ -1486,12 +1400,11 @@ void ScriptEditor::notify_script_changed(const Ref<Script> &p_script) {
}
void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
-
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
- if (!se)
+ if (!se) {
continue;
+ }
Ref<Script> script = se->get_edited_resource();
if (script == nullptr) {
@@ -1504,20 +1417,20 @@ void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
ERR_CONTINUE(base.begins_with("local://") || base == "");
for (List<int>::Element *E = bpoints.front(); E; E = E->next()) {
-
p_breakpoints->push_back(base + ":" + itos(E->get() + 1));
}
}
}
void ScriptEditor::ensure_focus_current() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
ScriptEditorBase *current = _get_current_editor();
- if (current)
+ if (current) {
current->ensure_focus();
+ }
}
void ScriptEditor::_members_overview_selected(int p_idx) {
@@ -1544,22 +1457,19 @@ void ScriptEditor::_help_overview_selected(int p_idx) {
}
void ScriptEditor::_script_selected(int p_idx) {
-
- grab_focus_block = !InputFilter::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing
+ grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing
_go_to_tab(script_list->get_item_metadata(p_idx));
grab_focus_block = false;
}
void ScriptEditor::ensure_select_current() {
-
if (tab_container->get_child_count() && tab_container->get_current_tab() >= 0) {
-
ScriptEditorBase *se = _get_current_editor();
if (se) {
-
- if (!grab_focus_block && is_visible_in_tree())
+ if (!grab_focus_block && is_visible_in_tree()) {
se->ensure_focus();
+ }
}
}
@@ -1567,13 +1477,15 @@ void ScriptEditor::ensure_select_current() {
}
void ScriptEditor::_find_scripts(Node *p_base, Node *p_current, Set<Ref<Script>> &used) {
- if (p_current != p_base && p_current->get_owner() != p_base)
+ if (p_current != p_base && p_current->get_owner() != p_base) {
return;
+ }
if (p_current->get_script_instance()) {
Ref<Script> scr = p_current->get_script();
- if (scr.is_valid())
+ if (scr.is_valid()) {
used.insert(scr);
+ }
}
for (int i = 0; i < p_current->get_child_count(); i++) {
@@ -1582,7 +1494,6 @@ void ScriptEditor::_find_scripts(Node *p_base, Node *p_current, Set<Ref<Script>>
}
struct _ScriptEditorItemData {
-
String name;
String sort_key;
Ref<Texture2D> icon;
@@ -1593,7 +1504,6 @@ struct _ScriptEditorItemData {
Node *ref;
bool operator<(const _ScriptEditorItemData &id) const {
-
if (category == id.category) {
if (sort_key == id.sort_key) {
return index < id.index;
@@ -1607,7 +1517,6 @@ struct _ScriptEditorItemData {
};
void ScriptEditor::_update_members_overview_visibility() {
-
ScriptEditorBase *se = _get_current_editor();
if (!se) {
members_overview_alphabeta_sort_button->set_visible(false);
@@ -1661,7 +1570,6 @@ void ScriptEditor::_update_members_overview() {
}
void ScriptEditor::_update_help_overview_visibility() {
-
int selected = tab_container->get_current_tab();
if (selected < 0 || selected >= tab_container->get_child_count()) {
help_overview->set_visible(false);
@@ -1690,8 +1598,9 @@ void ScriptEditor::_update_help_overview() {
help_overview->clear();
int selected = tab_container->get_current_tab();
- if (selected < 0 || selected >= tab_container->get_child_count())
+ if (selected < 0 || selected >= tab_container->get_child_count()) {
return;
+ }
Node *current = tab_container->get_child(tab_container->get_current_tab());
EditorHelp *se = Object::cast_to<EditorHelp>(current);
@@ -1707,7 +1616,6 @@ void ScriptEditor::_update_help_overview() {
}
void ScriptEditor::_update_script_colors() {
-
bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/script_list/script_temperature_enabled");
bool highlight_current = EditorSettings::get_singleton()->get("text_editor/script_list/highlight_current_script");
@@ -1716,11 +1624,11 @@ void ScriptEditor::_update_script_colors() {
Color cold_color = get_theme_color("font_color", "Editor");
for (int i = 0; i < script_list->get_item_count(); i++) {
-
int c = script_list->get_item_metadata(i);
Node *n = tab_container->get_child(c);
- if (!n)
+ if (!n) {
continue;
+ }
script_list->set_item_custom_bg_color(i, Color(0, 0, 0, 0));
@@ -1729,7 +1637,6 @@ void ScriptEditor::_update_script_colors() {
script_list->set_item_custom_bg_color(i, EditorSettings::get_singleton()->get("text_editor/script_list/current_script_background_color"));
} else if (script_temperature_enabled) {
-
if (!n->has_meta("__editor_pass")) {
continue;
}
@@ -1742,15 +1649,15 @@ void ScriptEditor::_update_script_colors() {
int non_zero_hist_size = (hist_size == 0) ? 1 : hist_size;
float v = Math::ease((edit_pass - pass) / float(non_zero_hist_size), 0.4);
- script_list->set_item_custom_fg_color(i, hot_color.linear_interpolate(cold_color, v));
+ script_list->set_item_custom_fg_color(i, hot_color.lerp(cold_color, v));
}
}
}
void ScriptEditor::_update_script_names() {
-
- if (restoring_layout)
+ if (restoring_layout) {
return;
+ }
Set<Ref<Script>> used;
Node *edited = EditorNode::get_singleton()->get_edited_scene();
@@ -1766,17 +1673,14 @@ void ScriptEditor::_update_script_names() {
Vector<_ScriptEditorItemData> sedata;
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (se) {
-
Ref<Texture2D> icon = se->get_theme_icon();
String path = se->get_edited_resource()->get_path();
bool built_in = !path.is_resource_file();
String name;
if (built_in) {
-
name = path.get_file();
const String &resource_name = se->get_edited_resource()->get_name();
if (resource_name != "") {
@@ -1785,7 +1689,6 @@ void ScriptEditor::_update_script_names() {
name = vformat("%s (%s)", resource_name, name.substr(0, name.find("::", 0)));
}
} else {
-
name = se->get_name();
}
@@ -1831,7 +1734,6 @@ void ScriptEditor::_update_script_names() {
EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(i));
if (eh) {
-
String name = eh->get_class();
Ref<Texture2D> icon = get_theme_icon("Help", "EditorIcons");
String tooltip = vformat(TTR("%s Class Reference"), name);
@@ -1866,6 +1768,10 @@ void ScriptEditor::_update_script_names() {
if (new_cur_tab == -1 && sedata[i].index == cur_tab) {
new_cur_tab = i;
}
+ // Update index of sd entries for sorted order
+ _ScriptEditorItemData sd = sedata[i];
+ sd.index = i;
+ sedata.set(i, sd);
}
tab_container->set_current_tab(new_prev_tab);
tab_container->set_current_tab(new_cur_tab);
@@ -1974,9 +1880,9 @@ Error ScriptEditor::_save_text_file(Ref<TextFile> p_text_file, const String &p_p
}
bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_grab_focus) {
-
- if (p_resource.is_null())
+ if (p_resource.is_null()) {
return false;
+ }
Ref<Script> script = p_resource;
@@ -1991,8 +1897,9 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
if (script != nullptr && script->get_language()->overrides_external_editor()) {
if (should_open) {
Error err = script->get_language()->open_in_external_editor(script, p_line >= 0 ? p_line : 0, p_col);
- if (err != OK)
+ if (err != OK) {
ERR_PRINT("Couldn't open script in the overridden external text editor");
+ }
}
return false;
}
@@ -2001,7 +1908,6 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
p_resource->get_path().is_resource_file() &&
p_resource->get_class_name() != StringName("VisualScript") &&
bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) {
-
String path = EditorSettings::get_singleton()->get("text_editor/external/exec_path");
String flags = EditorSettings::get_singleton()->get("text_editor/external/exec_flags");
@@ -2021,16 +1927,13 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
bool inside_quotes = false;
for (int i = 0; i < flags.size(); i++) {
-
if (flags[i] == '"' && (!i || flags[i - 1] != '\\')) {
-
if (!inside_quotes) {
from++;
}
inside_quotes = !inside_quotes;
} else if (flags[i] == '\0' || (!inside_quotes && flags[i] == ' ')) {
-
String arg = flags.substr(from, num_chars);
if (arg.find("{file}") != -1) {
has_file_flag = true;
@@ -2055,26 +1958,27 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
}
Error err = OS::get_singleton()->execute(path, args, false);
- if (err == OK)
+ if (err == OK) {
return false;
+ }
WARN_PRINT("Couldn't open external text editor, using internal");
}
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
- if (!se)
+ if (!se) {
continue;
+ }
if ((script != nullptr && se->get_edited_resource() == p_resource) || se->get_edited_resource()->get_path() == p_resource->get_path()) {
-
if (should_open) {
if (tab_container->get_current_tab() != i) {
_go_to_tab(i);
_update_script_names();
}
- if (is_visible_in_tree())
+ if (is_visible_in_tree()) {
se->ensure_focus();
+ }
if (p_line > 0) {
se->goto_line(p_line - 1);
@@ -2092,8 +1996,9 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
for (int i = script_editor_func_count - 1; i >= 0; i--) {
se = script_editor_funcs[i](p_resource);
- if (se)
+ if (se) {
break;
+ }
}
ERR_FAIL_COND_V(!se, false);
@@ -2153,12 +2058,11 @@ bool ScriptEditor::edit(const RES &p_resource, int p_line, int p_col, bool p_gra
}
void ScriptEditor::save_all_scripts() {
-
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
- if (!se)
+ if (!se) {
continue;
+ }
if (convert_indent_on_save) {
if (use_space_indentation) {
@@ -2174,8 +2078,9 @@ void ScriptEditor::save_all_scripts() {
se->insert_final_newline();
- if (!se->is_unsaved())
+ if (!se->is_unsaved()) {
continue;
+ }
RES edited_res = se->get_edited_resource();
if (edited_res.is_valid()) {
@@ -2197,12 +2102,11 @@ void ScriptEditor::save_all_scripts() {
}
void ScriptEditor::apply_scripts() const {
-
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
- if (!se)
+ if (!se) {
continue;
+ }
se->apply_code();
}
}
@@ -2214,10 +2118,8 @@ void ScriptEditor::open_script_create_dialog(const String &p_base_name, const St
void ScriptEditor::_editor_stop() {
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (!se) {
-
continue;
}
@@ -2226,7 +2128,6 @@ void ScriptEditor::_editor_stop() {
}
void ScriptEditor::_add_callback(Object *p_obj, const String &p_function, const PackedStringArray &p_args) {
-
ERR_FAIL_COND(!p_obj);
Ref<Script> script = p_obj->get_script();
ERR_FAIL_COND(!script.is_valid());
@@ -2234,12 +2135,13 @@ void ScriptEditor::_add_callback(Object *p_obj, const String &p_function, const
editor->push_item(script.ptr());
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
- if (!se)
+ if (!se) {
continue;
- if (se->get_edited_resource() != script)
+ }
+ if (se->get_edited_resource() != script) {
continue;
+ }
se->add_callback(p_function, p_args);
@@ -2252,7 +2154,6 @@ void ScriptEditor::_add_callback(Object *p_obj, const String &p_function, const
}
void ScriptEditor::_save_layout() {
-
if (restoring_layout) {
return;
}
@@ -2261,7 +2162,6 @@ void ScriptEditor::_save_layout() {
}
void ScriptEditor::_editor_settings_changed() {
-
trim_trailing_whitespace_on_save = EditorSettings::get_singleton()->get("text_editor/files/trim_trailing_whitespace_on_save");
convert_indent_on_save = EditorSettings::get_singleton()->get("text_editor/indent/convert_indent_on_save");
use_space_indentation = EditorSettings::get_singleton()->get("text_editor/indent/type");
@@ -2281,10 +2181,10 @@ void ScriptEditor::_editor_settings_changed() {
}
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
- if (!se)
+ if (!se) {
continue;
+ }
se->update_settings();
}
@@ -2295,12 +2195,10 @@ void ScriptEditor::_editor_settings_changed() {
}
void ScriptEditor::_autosave_scripts() {
-
save_all_scripts();
}
void ScriptEditor::_update_autosave_timer() {
-
if (!autosave_timer->is_inside_tree()) {
return;
}
@@ -2315,9 +2213,9 @@ void ScriptEditor::_update_autosave_timer() {
}
void ScriptEditor::_tree_changed() {
-
- if (waiting_update_names)
+ if (waiting_update_names) {
return;
+ }
waiting_update_names = true;
call_deferred("_update_script_names");
@@ -2325,14 +2223,13 @@ void ScriptEditor::_tree_changed() {
}
void ScriptEditor::_script_split_dragged(float) {
-
_save_layout();
}
Variant ScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
- if (tab_container->get_child_count() == 0)
+ if (tab_container->get_child_count() == 0) {
return Variant();
+ }
Node *cur_node = tab_container->get_child(tab_container->get_current_tab());
@@ -2368,13 +2265,12 @@ Variant ScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
}
bool ScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return false;
+ }
if (String(d["type"]) == "script_list_element") {
-
Node *node = d["script_list_element"];
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node);
@@ -2388,10 +2284,10 @@ bool ScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data
}
if (String(d["type"]) == "nodes") {
-
Array nodes = d["nodes"];
- if (nodes.size() == 0)
+ if (nodes.size() == 0) {
return false;
+ }
Node *node = get_node((nodes[0]));
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node);
@@ -2405,16 +2301,17 @@ bool ScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data
}
if (String(d["type"]) == "files") {
-
Vector<String> files = d["files"];
- if (files.size() == 0)
+ if (files.size() == 0) {
return false; //weird
+ }
for (int i = 0; i < files.size(); i++) {
String file = files[i];
- if (file == "" || !FileAccess::exists(file))
+ if (file == "" || !FileAccess::exists(file)) {
continue;
+ }
Ref<Script> scr = ResourceLoader::load(file);
if (scr.is_valid()) {
return true;
@@ -2427,16 +2324,16 @@ bool ScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data
}
void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
-
- if (!can_drop_data_fw(p_point, p_data, p_from))
+ if (!can_drop_data_fw(p_point, p_data, p_from)) {
return;
+ }
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return;
+ }
if (String(d["type"]) == "script_list_element") {
-
Node *node = d["script_list_element"];
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node);
@@ -2453,10 +2350,10 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
}
if (String(d["type"]) == "nodes") {
-
Array nodes = d["nodes"];
- if (nodes.size() == 0)
+ if (nodes.size() == 0) {
return;
+ }
Node *node = get_node(nodes[0]);
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(node);
@@ -2473,7 +2370,6 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
}
if (String(d["type"]) == "files") {
-
Vector<String> files = d["files"];
int new_index = 0;
@@ -2483,8 +2379,9 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
int num_tabs_before = tab_container->get_child_count();
for (int i = 0; i < files.size(); i++) {
String file = files[i];
- if (file == "" || !FileAccess::exists(file))
+ if (file == "" || !FileAccess::exists(file)) {
continue;
+ }
Ref<Script> scr = ResourceLoader::load(file);
if (scr.is_valid()) {
edit(scr);
@@ -2502,8 +2399,9 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
}
void ScriptEditor::_unhandled_input(const Ref<InputEvent> &p_event) {
- if (!is_visible_in_tree() || !p_event->is_pressed() || p_event->is_echo())
+ if (!is_visible_in_tree() || !p_event->is_pressed() || p_event->is_echo()) {
return;
+ }
if (ED_IS_SHORTCUT("script_editor/next_script", p_event)) {
if (script_list->get_item_count() > 1) {
int next_tab = script_list->get_current() + 1;
@@ -2529,11 +2427,9 @@ void ScriptEditor::_unhandled_input(const Ref<InputEvent> &p_event) {
}
void ScriptEditor::_script_list_gui_input(const Ref<InputEvent> &ev) {
-
Ref<InputEventMouseButton> mb = ev;
if (mb.is_valid() && mb->is_pressed()) {
switch (mb->get_button_index()) {
-
case BUTTON_MIDDLE: {
// Right-click selects automatically; middle-click does not.
int idx = script_list->get_item_at_position(mb->get_position(), true);
@@ -2552,12 +2448,12 @@ void ScriptEditor::_script_list_gui_input(const Ref<InputEvent> &ev) {
}
void ScriptEditor::_make_script_list_context_menu() {
-
context_menu->clear();
int selected = tab_container->get_current_tab();
- if (selected < 0 || selected >= tab_container->get_child_count())
+ if (selected < 0 || selected >= tab_container->get_child_count()) {
return;
+ }
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(selected));
if (se) {
@@ -2593,18 +2489,19 @@ void ScriptEditor::_make_script_list_context_menu() {
}
void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
-
if (!bool(EDITOR_DEF("text_editor/files/restore_scripts_on_load", true))) {
return;
}
- if (!p_layout->has_section_key("ScriptEditor", "open_scripts") && !p_layout->has_section_key("ScriptEditor", "open_help"))
+ if (!p_layout->has_section_key("ScriptEditor", "open_scripts") && !p_layout->has_section_key("ScriptEditor", "open_help")) {
return;
+ }
Array scripts = p_layout->get_value("ScriptEditor", "open_scripts");
Array helps;
- if (p_layout->has_section_key("ScriptEditor", "open_help"))
+ if (p_layout->has_section_key("ScriptEditor", "open_help")) {
helps = p_layout->get_value("ScriptEditor", "open_help");
+ }
restoring_layout = true;
@@ -2612,7 +2509,6 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
ResourceLoader::get_recognized_extensions_for_type("Script", &extensions);
for (int i = 0; i < scripts.size(); i++) {
-
String path = scripts[i];
Dictionary script_info = scripts[i];
@@ -2620,8 +2516,9 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
path = script_info["path"];
}
- if (!FileAccess::exists(path))
+ if (!FileAccess::exists(path)) {
continue;
+ }
if (extensions.find(path.get_extension())) {
Ref<Script> scr = ResourceLoader::load(path);
@@ -2651,7 +2548,6 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
}
for (int i = 0; i < helps.size(); i++) {
-
String path = helps[i];
if (path == "") { // invalid, skip
continue;
@@ -2673,18 +2569,16 @@ void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
}
void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) {
-
Array scripts;
Array helps;
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (se) {
-
String path = se->get_edited_resource()->get_path();
- if (!path.is_resource_file())
+ if (!path.is_resource_file()) {
continue;
+ }
Dictionary script_info;
script_info["path"] = path;
@@ -2696,7 +2590,6 @@ void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) {
EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(i));
if (eh) {
-
helps.push_back(eh->get_class());
}
}
@@ -2707,16 +2600,14 @@ void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) {
}
void ScriptEditor::_help_class_open(const String &p_class) {
-
- if (p_class == "")
+ if (p_class == "") {
return;
+ }
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(i));
if (eh && eh->get_class() == p_class) {
-
_go_to_tab(i);
_update_script_names();
return;
@@ -2737,15 +2628,12 @@ void ScriptEditor::_help_class_open(const String &p_class) {
}
void ScriptEditor::_help_class_goto(const String &p_desc) {
-
String cname = p_desc.get_slice(":", 1);
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_child(i));
if (eh && eh->get_class() == cname) {
-
_go_to_tab(i);
eh->go_to_help(p_desc);
_update_script_names();
@@ -2767,25 +2655,22 @@ void ScriptEditor::_help_class_goto(const String &p_desc) {
}
void ScriptEditor::_update_selected_editor_menu() {
-
for (int i = 0; i < tab_container->get_child_count(); i++) {
-
bool current = tab_container->get_current_tab() == i;
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
if (se && se->get_edit_menu()) {
-
- if (current)
+ if (current) {
se->get_edit_menu()->show();
- else
+ } else {
se->get_edit_menu()->hide();
+ }
}
}
EditorHelp *eh = Object::cast_to<EditorHelp>(tab_container->get_current_tab_control());
script_search_menu->get_popup()->clear();
if (eh) {
-
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find", TTR("Find..."), KEY_MASK_CMD | KEY_F), HELP_SEARCH_FIND);
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_next", TTR("Find Next"), KEY_F3), HELP_SEARCH_FIND_NEXT);
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_previous", TTR("Find Previous"), KEY_MASK_SHIFT | KEY_F3), HELP_SEARCH_FIND_PREVIOUS);
@@ -2793,7 +2678,6 @@ void ScriptEditor::_update_selected_editor_menu() {
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F), SEARCH_IN_FILES);
script_search_menu->show();
} else {
-
if (tab_container->get_child_count() == 0) {
script_search_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/find_in_files", TTR("Find in Files"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F), SEARCH_IN_FILES);
script_search_menu->show();
@@ -2804,15 +2688,12 @@ void ScriptEditor::_update_selected_editor_menu() {
}
void ScriptEditor::_update_history_pos(int p_new_pos) {
-
Node *n = tab_container->get_current_tab_control();
if (Object::cast_to<ScriptEditorBase>(n)) {
-
history.write[history_pos].state = Object::cast_to<ScriptEditorBase>(n)->get_edit_state();
}
if (Object::cast_to<EditorHelp>(n)) {
-
history.write[history_pos].state = Object::cast_to<EditorHelp>(n)->get_scroll();
}
@@ -2822,7 +2703,6 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
n = history[history_pos].control;
if (Object::cast_to<ScriptEditorBase>(n)) {
-
Object::cast_to<ScriptEditorBase>(n)->set_edit_state(history[history_pos].state);
Object::cast_to<ScriptEditorBase>(n)->ensure_focus();
@@ -2833,7 +2713,6 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
}
if (Object::cast_to<EditorHelp>(n)) {
-
Object::cast_to<EditorHelp>(n)->set_scroll(history[history_pos].state);
Object::cast_to<EditorHelp>(n)->set_focused();
}
@@ -2845,27 +2724,25 @@ void ScriptEditor::_update_history_pos(int p_new_pos) {
}
void ScriptEditor::_history_forward() {
-
if (history_pos < history.size() - 1) {
_update_history_pos(history_pos + 1);
}
}
void ScriptEditor::_history_back() {
-
if (history_pos > 0) {
_update_history_pos(history_pos - 1);
}
}
Vector<Ref<Script>> ScriptEditor::get_open_scripts() const {
-
Vector<Ref<Script>> out_scripts = Vector<Ref<Script>>();
for (int i = 0; i < tab_container->get_child_count(); i++) {
ScriptEditorBase *se = Object::cast_to<ScriptEditorBase>(tab_container->get_child(i));
- if (!se)
+ if (!se) {
continue;
+ }
Ref<Script> script = se->get_edited_resource();
if (script != nullptr) {
@@ -2877,11 +2754,11 @@ Vector<Ref<Script>> ScriptEditor::get_open_scripts() const {
}
void ScriptEditor::set_scene_root_script(Ref<Script> p_script) {
-
bool open_dominant = EditorSettings::get_singleton()->get("text_editor/files/open_dominant_script_on_scene_change");
- if (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")))
+ if (bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) {
return;
+ }
if (open_dominant && p_script.is_valid()) {
edit(p_script);
@@ -2889,17 +2766,16 @@ void ScriptEditor::set_scene_root_script(Ref<Script> p_script) {
}
bool ScriptEditor::script_goto_method(Ref<Script> p_script, const String &p_method) {
-
int line = p_script->get_member_line(p_method);
- if (line == -1)
+ if (line == -1) {
return false;
+ }
return edit(p_script, line, 0);
}
void ScriptEditor::set_live_auto_reload_running_scripts(bool p_enabled) {
-
auto_reload_running_scripts = p_enabled;
}
@@ -2908,7 +2784,6 @@ void ScriptEditor::_help_search(String p_text) {
}
void ScriptEditor::_open_script_request(const String &p_path) {
-
Ref<Script> script = ResourceLoader::load(p_path);
if (script.is_valid()) {
script_editor->edit(script, false);
@@ -2935,25 +2810,21 @@ int ScriptEditor::script_editor_func_count = 0;
CreateScriptEditorFunc ScriptEditor::script_editor_funcs[ScriptEditor::SCRIPT_EDITOR_FUNC_MAX];
void ScriptEditor::register_create_script_editor_function(CreateScriptEditorFunc p_func) {
-
ERR_FAIL_COND(script_editor_func_count == SCRIPT_EDITOR_FUNC_MAX);
script_editor_funcs[script_editor_func_count++] = p_func;
}
void ScriptEditor::_script_changed() {
-
NodeDock::singleton->update_lists();
}
void ScriptEditor::_on_find_in_files_requested(String text) {
-
find_in_files_dialog->set_find_in_files_mode(FindInFilesDialog::SEARCH_MODE);
find_in_files_dialog->set_search_text(text);
find_in_files_dialog->popup_centered();
}
void ScriptEditor::_on_replace_in_files_requested(String text) {
-
find_in_files_dialog->set_find_in_files_mode(FindInFilesDialog::REPLACE_MODE);
find_in_files_dialog->set_search_text(text);
find_in_files_dialog->set_replace_text("");
@@ -2961,7 +2832,6 @@ void ScriptEditor::_on_replace_in_files_requested(String text) {
}
void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_number, int begin, int end) {
-
if (ResourceLoader::exists(fpath)) {
RES res = ResourceLoader::load(fpath);
@@ -2999,7 +2869,6 @@ void ScriptEditor::_on_find_in_files_result_selected(String fpath, int line_numb
}
void ScriptEditor::_start_find_in_files(bool with_replace) {
-
FindInFiles *f = find_in_files->get_finder();
f->set_search_text(find_in_files_dialog->get_search_text());
@@ -3016,7 +2885,6 @@ void ScriptEditor::_start_find_in_files(bool with_replace) {
}
void ScriptEditor::_on_find_in_files_modified_files(PackedStringArray paths) {
-
_test_script_times_on_disk();
_update_modified_scripts_for_external_editor();
}
@@ -3030,7 +2898,6 @@ void ScriptEditor::_filter_methods_text_changed(const String &p_newtext) {
}
void ScriptEditor::_bind_methods() {
-
ClassDB::bind_method("_close_docs_tab", &ScriptEditor::_close_docs_tab);
ClassDB::bind_method("_close_all_tabs", &ScriptEditor::_close_all_tabs);
ClassDB::bind_method("_close_other_tabs", &ScriptEditor::_close_other_tabs);
@@ -3059,7 +2926,6 @@ void ScriptEditor::_bind_methods() {
}
ScriptEditor::ScriptEditor(EditorNode *p_editor) {
-
current_theme = "";
completion_cache = memnew(EditorScriptCodeCompletionCache);
@@ -3186,7 +3052,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_as", TTR("Save As...")), FILE_SAVE_AS);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/save_all", TTR("Save All"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_MASK_ALT | KEY_S), FILE_SAVE_ALL);
file_menu->get_popup()->add_separator();
- file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_script_soft", TTR("Soft Reload Script"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_R), FILE_TOOL_RELOAD_SOFT);
+ file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/reload_script_soft", TTR("Soft Reload Script"), KEY_MASK_CMD | KEY_MASK_ALT | KEY_R), FILE_TOOL_RELOAD_SOFT);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/copy_path", TTR("Copy Script Path")), FILE_COPY_PATH);
file_menu->get_popup()->add_shortcut(ED_SHORTCUT("script_editor/show_in_file_system", TTR("Show in FileSystem")), SHOW_IN_FILE_SYSTEM);
file_menu->get_popup()->add_separator();
@@ -3360,14 +3226,11 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
}
ScriptEditor::~ScriptEditor() {
-
memdelete(completion_cache);
}
void ScriptEditorPlugin::edit(Object *p_object) {
-
if (Object::cast_to<Script>(p_object)) {
-
Script *p_script = Object::cast_to<Script>(p_object);
String res_path = p_script->get_path().get_slice("::", 0);
@@ -3387,7 +3250,6 @@ void ScriptEditorPlugin::edit(Object *p_object) {
}
bool ScriptEditorPlugin::handles(Object *p_object) const {
-
if (Object::cast_to<TextFile>(p_object)) {
return true;
}
@@ -3400,30 +3262,25 @@ bool ScriptEditorPlugin::handles(Object *p_object) const {
}
void ScriptEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
script_editor->show();
script_editor->set_process(true);
script_editor->ensure_select_current();
} else {
-
script_editor->hide();
script_editor->set_process(false);
}
}
void ScriptEditorPlugin::selected_notify() {
-
script_editor->ensure_select_current();
}
void ScriptEditorPlugin::save_external_data() {
-
script_editor->save_all_scripts();
}
void ScriptEditorPlugin::apply_changes() {
-
script_editor->apply_scripts();
}
@@ -3434,27 +3291,22 @@ void ScriptEditorPlugin::save_global_state() {
}
void ScriptEditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) {
-
script_editor->set_window_layout(p_layout);
}
void ScriptEditorPlugin::get_window_layout(Ref<ConfigFile> p_layout) {
-
script_editor->get_window_layout(p_layout);
}
void ScriptEditorPlugin::get_breakpoints(List<String> *p_breakpoints) {
-
script_editor->get_breakpoints(p_breakpoints);
}
void ScriptEditorPlugin::edited_scene_changed() {
-
script_editor->edited_scene_changed();
}
ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
script_editor = memnew(ScriptEditor(p_node));
editor->get_viewport()->add_child(script_editor);
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index e895867268..f7352be7e8 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -49,7 +49,6 @@
#include "scene/resources/text_file.h"
class ScriptEditorQuickOpen : public ConfirmationDialog {
-
GDCLASS(ScriptEditorQuickOpen, ConfirmationDialog);
LineEdit *search_box;
@@ -76,7 +75,6 @@ public:
class EditorDebuggerNode;
class ScriptEditorBase : public VBoxContainer {
-
GDCLASS(ScriptEditorBase, VBoxContainer);
protected:
@@ -131,7 +129,6 @@ class FindInFilesDialog;
class FindInFilesPanel;
class ScriptEditor : public PanelContainer {
-
GDCLASS(ScriptEditor, PanelContainer);
EditorNode *editor;
@@ -250,7 +247,6 @@ class ScriptEditor : public PanelContainer {
static CreateSyntaxHighlighterFunc syntax_highlighters_funcs[SYNTAX_HIGHLIGHTER_FUNC_MAX];
struct ScriptHistory {
-
Control *control;
Variant state;
};
@@ -454,7 +450,6 @@ public:
};
class ScriptEditorPlugin : public EditorPlugin {
-
GDCLASS(ScriptEditorPlugin, EditorPlugin);
ScriptEditor *script_editor;
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 4b8383e1e5..e7f8a56e5e 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -109,7 +109,6 @@ ConnectionInfoDialog::ConnectionInfoDialog() {
////////////////////////////////////////////////////////////////////////////////
Vector<String> ScriptTextEditor::get_functions() {
-
String errortxt;
int line = -1, col;
TextEdit *te = code_editor->get_text_edit();
@@ -117,11 +116,9 @@ Vector<String> ScriptTextEditor::get_functions() {
List<String> fnc;
if (script->get_language()->validate(text, line, col, errortxt, script->get_path(), &fnc)) {
-
//if valid rewrite functions to latest
functions.clear();
for (List<String>::Element *E = fnc.front(); E; E = E->next()) {
-
functions.push_back(E->get());
}
}
@@ -130,9 +127,9 @@ Vector<String> ScriptTextEditor::get_functions() {
}
void ScriptTextEditor::apply_code() {
-
- if (script.is_null())
+ if (script.is_null()) {
return;
+ }
script->set_source_code(code_editor->get_text_edit()->get_text());
script->update_exports();
_update_member_keywords();
@@ -165,17 +162,20 @@ void ScriptTextEditor::_update_member_keywords() {
StringName instance_base = script->get_instance_base_type();
- if (instance_base == StringName())
+ if (instance_base == StringName()) {
return;
+ }
List<PropertyInfo> plist;
ClassDB::get_property_list(instance_base, &plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
String name = E->get().name;
- if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP)
+ if (E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_SUBGROUP) {
continue;
- if (name.find("/") != -1)
+ }
+ if (name.find("/") != -1) {
continue;
+ }
code_editor->get_text_edit()->add_member_keyword(name, member_variable_color);
}
@@ -184,13 +184,11 @@ void ScriptTextEditor::_update_member_keywords() {
ClassDB::get_integer_constant_list(instance_base, &clist);
for (List<String>::Element *E = clist.front(); E; E = E->next()) {
-
code_editor->get_text_edit()->add_member_keyword(E->get(), member_variable_color);
}
}
void ScriptTextEditor::_load_theme_settings() {
-
TextEdit *text_edit = code_editor->get_text_edit();
text_edit->clear_colors();
@@ -270,14 +268,15 @@ void ScriptTextEditor::_load_theme_settings() {
colors_cache.string_color = string_color;
theme_loaded = true;
- if (!script.is_null())
+ if (!script.is_null()) {
_set_theme_for_script();
+ }
}
void ScriptTextEditor::_set_theme_for_script() {
-
- if (!theme_loaded)
+ if (!theme_loaded) {
return;
+ }
TextEdit *text_edit = code_editor->get_text_edit();
@@ -285,7 +284,6 @@ void ScriptTextEditor::_set_theme_for_script() {
script->get_language()->get_reserved_words(&keywords);
for (List<String>::Element *E = keywords.front(); E; E = E->next()) {
-
text_edit->add_keyword_color(E->get(), colors_cache.keyword_color);
}
@@ -327,10 +325,10 @@ void ScriptTextEditor::_set_theme_for_script() {
ClassDB::get_class_list(&types);
for (List<StringName>::Element *E = types.front(); E; E = E->next()) {
-
String n = E->get();
- if (n.begins_with("_"))
+ if (n.begins_with("_")) {
n = n.substr(1, n.length());
+ }
text_edit->add_keyword_color(n, colors_cache.type_color);
}
@@ -341,7 +339,6 @@ void ScriptTextEditor::_set_theme_for_script() {
ScriptServer::get_global_class_list(&global_classes);
for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
-
text_edit->add_keyword_color(E->get(), colors_cache.usertype_color);
}
@@ -364,7 +361,6 @@ void ScriptTextEditor::_set_theme_for_script() {
script->get_language()->get_comment_delimiters(&comments);
for (List<String>::Element *E = comments.front(); E; E = E->next()) {
-
String comment = E->get();
String beg = comment.get_slice(" ", 0);
String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String();
@@ -376,7 +372,6 @@ void ScriptTextEditor::_set_theme_for_script() {
List<String> strings;
script->get_language()->get_string_delimiters(&strings);
for (List<String>::Element *E = strings.front(); E; E = E->next()) {
-
String string = E->get();
String beg = string.get_slice(" ", 0);
String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String();
@@ -403,7 +398,6 @@ void ScriptTextEditor::_warning_clicked(Variant p_line) {
}
void ScriptTextEditor::reload_text() {
-
ERR_FAIL_COND(script.is_null());
TextEdit *te = code_editor->get_text_edit();
@@ -424,7 +418,6 @@ void ScriptTextEditor::reload_text() {
}
void ScriptTextEditor::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_READY:
_load_theme_settings();
@@ -433,7 +426,6 @@ void ScriptTextEditor::_notification(int p_what) {
}
void ScriptTextEditor::add_callback(const String &p_function, PackedStringArray p_args) {
-
String code = code_editor->get_text_edit()->get_text();
int pos = script->get_language()->find_function(p_function, code);
if (pos == -1) {
@@ -455,22 +447,18 @@ bool ScriptTextEditor::show_members_overview() {
}
void ScriptTextEditor::update_settings() {
-
code_editor->update_editor_settings();
}
bool ScriptTextEditor::is_unsaved() {
-
return code_editor->get_text_edit()->get_version() != code_editor->get_text_edit()->get_saved_version();
}
Variant ScriptTextEditor::get_edit_state() {
-
return code_editor->get_edit_state();
}
void ScriptTextEditor::set_edit_state(const Variant &p_state) {
-
code_editor->set_edit_state(p_state);
Dictionary state = p_state;
@@ -483,47 +471,38 @@ void ScriptTextEditor::set_edit_state(const Variant &p_state) {
}
void ScriptTextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
-
code_editor->convert_case(p_case);
}
void ScriptTextEditor::trim_trailing_whitespace() {
-
code_editor->trim_trailing_whitespace();
}
void ScriptTextEditor::insert_final_newline() {
-
code_editor->insert_final_newline();
}
void ScriptTextEditor::convert_indent_to_spaces() {
-
code_editor->convert_indent_to_spaces();
}
void ScriptTextEditor::convert_indent_to_tabs() {
-
code_editor->convert_indent_to_tabs();
}
void ScriptTextEditor::tag_saved_version() {
-
code_editor->get_text_edit()->tag_saved_version();
}
void ScriptTextEditor::goto_line(int p_line, bool p_with_error) {
-
code_editor->goto_line(p_line);
}
void ScriptTextEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
-
code_editor->goto_line_selection(p_line, p_begin, p_end);
}
void ScriptTextEditor::goto_line_centered(int p_line) {
-
code_editor->goto_line_centered(p_line);
}
@@ -536,7 +515,6 @@ void ScriptTextEditor::clear_executing_line() {
}
void ScriptTextEditor::ensure_focus() {
-
code_editor->get_text_edit()->grab_focus();
}
@@ -548,16 +526,16 @@ String ScriptTextEditor::get_name() {
if (is_unsaved()) {
name += "(*)";
}
- } else if (script->get_name() != "")
+ } else if (script->get_name() != "") {
name = script->get_name();
- else
+ } else {
name = script->get_class() + "(" + itos(script->get_instance_id()) + ")";
+ }
return name;
}
Ref<Texture2D> ScriptTextEditor::get_theme_icon() {
-
if (get_parent_control() && get_parent_control()->has_theme_icon(script->get_class(), "EditorIcons")) {
return get_parent_control()->get_theme_icon(script->get_class(), "EditorIcons");
}
@@ -566,7 +544,6 @@ Ref<Texture2D> ScriptTextEditor::get_theme_icon() {
}
void ScriptTextEditor::_validate_script() {
-
String errortxt;
int line = -1, col;
TextEdit *te = code_editor->get_text_edit();
@@ -592,7 +569,6 @@ void ScriptTextEditor::_validate_script() {
functions.clear();
for (List<String>::Element *E = fnc.front(); E; E = E->next()) {
-
functions.push_back(E->get());
}
script_is_valid = true;
@@ -682,7 +658,6 @@ void ScriptTextEditor::_validate_script() {
}
void ScriptTextEditor::_update_bookmark_list() {
-
bookmarks_menu->clear();
bookmarks_menu->set_size(Size2(1, 1));
@@ -714,7 +689,6 @@ void ScriptTextEditor::_update_bookmark_list() {
}
void ScriptTextEditor::_bookmark_item_pressed(int p_idx) {
-
if (p_idx < 4) { // Any item before the separator.
_edit_option(bookmarks_menu->get_item_id(p_idx));
} else {
@@ -724,7 +698,6 @@ void ScriptTextEditor::_bookmark_item_pressed(int p_idx) {
}
static Vector<Node *> _find_all_node_for_script(Node *p_base, Node *p_current, const Ref<Script> &p_script) {
-
Vector<Node *> nodes;
if (p_current->get_owner() != p_base && p_base != p_current) {
@@ -745,29 +718,32 @@ static Vector<Node *> _find_all_node_for_script(Node *p_base, Node *p_current, c
}
static Node *_find_node_for_script(Node *p_base, Node *p_current, const Ref<Script> &p_script) {
-
- if (p_current->get_owner() != p_base && p_base != p_current)
+ if (p_current->get_owner() != p_base && p_base != p_current) {
return nullptr;
+ }
Ref<Script> c = p_current->get_script();
- if (c == p_script)
+ if (c == p_script) {
return p_current;
+ }
for (int i = 0; i < p_current->get_child_count(); i++) {
Node *found = _find_node_for_script(p_base, p_current->get_child(i), p_script);
- if (found)
+ if (found) {
return found;
+ }
}
return nullptr;
}
static void _find_changed_scripts_for_external_editor(Node *p_base, Node *p_current, Set<Ref<Script>> &r_scripts) {
-
- if (p_current->get_owner() != p_base && p_base != p_current)
+ if (p_current->get_owner() != p_base && p_base != p_current) {
return;
+ }
Ref<Script> c = p_current->get_script();
- if (c.is_valid())
+ if (c.is_valid()) {
r_scripts.insert(c);
+ }
for (int i = 0; i < p_current->get_child_count(); i++) {
_find_changed_scripts_for_external_editor(p_base, p_current->get_child(i), r_scripts);
@@ -775,9 +751,9 @@ static void _find_changed_scripts_for_external_editor(Node *p_base, Node *p_curr
}
void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_for_script) {
-
- if (!bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor")))
+ if (!bool(EditorSettings::get_singleton()->get("text_editor/external/use_external_editor"))) {
return;
+ }
ERR_FAIL_COND(!get_tree());
@@ -789,14 +765,13 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo
}
for (Set<Ref<Script>>::Element *E = scripts.front(); E; E = E->next()) {
-
Ref<Script> script = E->get();
- if (p_for_script.is_valid() && p_for_script != script)
+ if (p_for_script.is_valid() && p_for_script != script) {
continue;
+ }
if (script->get_path() == "" || script->get_path().find("local://") != -1 || script->get_path().find("::") != -1) {
-
continue; //internal script, who cares, though weird
}
@@ -804,7 +779,6 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo
uint64_t date = FileAccess::get_modified_time(script->get_path());
if (last_date != date) {
-
Ref<Script> rel_script = ResourceLoader::load(script->get_path(), script->get_class(), true);
ERR_CONTINUE(!rel_script.is_valid());
script->set_source_code(rel_script->get_source_code());
@@ -815,14 +789,14 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo
}
void ScriptTextEditor::_code_complete_scripts(void *p_ud, const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_force) {
-
ScriptTextEditor *ste = (ScriptTextEditor *)p_ud;
ste->_code_complete_script(p_code, r_options, r_force);
}
void ScriptTextEditor::_code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_force) {
-
- if (color_panel->is_visible()) return;
+ if (color_panel->is_visible()) {
+ return;
+ }
Node *base = get_tree()->get_edited_scene_root();
if (base) {
base = _find_node_for_script(base, base, script);
@@ -835,7 +809,6 @@ void ScriptTextEditor::_code_complete_script(const String &p_code, List<ScriptCo
}
void ScriptTextEditor::_update_breakpoint_list() {
-
breakpoints_menu->clear();
breakpoints_menu->set_size(Size2(1, 1));
@@ -867,7 +840,6 @@ void ScriptTextEditor::_update_breakpoint_list() {
}
void ScriptTextEditor::_breakpoint_item_pressed(int p_idx) {
-
if (p_idx < 4) { // Any item before the separator.
_edit_option(breakpoints_menu->get_item_id(p_idx));
} else {
@@ -877,12 +849,10 @@ void ScriptTextEditor::_breakpoint_item_pressed(int p_idx) {
}
void ScriptTextEditor::_breakpoint_toggled(int p_row) {
-
EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), p_row + 1, code_editor->get_text_edit()->is_line_set_as_breakpoint(p_row));
}
void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_column) {
-
Node *base = get_tree()->get_edited_scene_root();
if (base) {
base = _find_node_for_script(base, base, script);
@@ -902,14 +872,12 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
}
} else if (script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK) {
-
_goto_line(p_row);
result.class_name = result.class_name.trim_prefix("_");
switch (result.type) {
case ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION: {
-
if (result.script.is_valid()) {
emit_signal("request_open_script_at_line", result.script, result.location - 1);
} else {
@@ -921,7 +889,6 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
emit_signal("go_to_help", "class_name:" + result.class_name);
} break;
case ScriptLanguage::LookupResult::RESULT_CLASS_CONSTANT: {
-
StringName cname = result.class_name;
bool success;
while (true) {
@@ -942,7 +909,6 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
} break;
case ScriptLanguage::LookupResult::RESULT_CLASS_METHOD: {
-
StringName cname = result.class_name;
while (true) {
@@ -958,7 +924,6 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
} break;
case ScriptLanguage::LookupResult::RESULT_CLASS_ENUM: {
-
StringName cname = result.class_name;
StringName success;
while (true) {
@@ -978,11 +943,30 @@ void ScriptTextEditor::_lookup_symbol(const String &p_symbol, int p_row, int p_c
emit_signal("go_to_help", "class_global:" + result.class_name + ":" + result.class_member);
} break;
}
+ } else if (ProjectSettings::get_singleton()->has_setting("autoload/" + p_symbol)) {
+ //check for Autoload scenes
+ String path = ProjectSettings::get_singleton()->get("autoload/" + p_symbol);
+ if (path.begins_with("*")) {
+ path = path.substr(1, path.length());
+ EditorNode::get_singleton()->load_scene(path);
+ }
+ } else if (p_symbol.is_rel_path()) {
+ // Every symbol other than absolute path is relative path so keep this condition at last.
+ String path = _get_absolute_path(p_symbol);
+ if (FileAccess::exists(path)) {
+ List<String> scene_extensions;
+ ResourceLoader::get_recognized_extensions_for_type("PackedScene", &scene_extensions);
+
+ if (scene_extensions.find(path.get_extension())) {
+ EditorNode::get_singleton()->load_scene(path);
+ } else {
+ EditorNode::get_singleton()->load_resource(path);
+ }
+ }
}
}
void ScriptTextEditor::_validate_symbol(const String &p_symbol) {
-
TextEdit *text_edit = code_editor->get_text_edit();
Node *base = get_tree()->get_edited_scene_root();
@@ -991,13 +975,27 @@ void ScriptTextEditor::_validate_symbol(const String &p_symbol) {
}
ScriptLanguage::LookupResult result;
- if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK) {
+ if (ScriptServer::is_global_class(p_symbol) || p_symbol.is_resource_file() || script->get_language()->lookup_code(code_editor->get_text_edit()->get_text_for_lookup_completion(), p_symbol, script->get_path(), base, result) == OK || ProjectSettings::get_singleton()->has_setting("autoload/" + p_symbol)) {
text_edit->set_highlighted_word(p_symbol);
+ } else if (p_symbol.is_rel_path()) {
+ String path = _get_absolute_path(p_symbol);
+ if (FileAccess::exists(path)) {
+ text_edit->set_highlighted_word(p_symbol);
+ } else {
+ text_edit->set_highlighted_word(String());
+ }
+
} else {
text_edit->set_highlighted_word(String());
}
}
+String ScriptTextEditor::_get_absolute_path(const String &rel_path) {
+ String base_path = script->get_path().get_base_dir();
+ String path = base_path.plus_file(rel_path);
+ return path.replace("///", "//").simplify_path();
+}
+
void ScriptTextEditor::update_toggle_scripts_button() {
if (code_editor != nullptr) {
code_editor->update_toggle_scripts_button();
@@ -1088,101 +1086,85 @@ void ScriptTextEditor::_lookup_connections(int p_row, String p_method) {
}
void ScriptTextEditor::_edit_option(int p_op) {
-
TextEdit *tx = code_editor->get_text_edit();
switch (p_op) {
case EDIT_UNDO: {
-
tx->undo();
tx->call_deferred("grab_focus");
} break;
case EDIT_REDO: {
-
tx->redo();
tx->call_deferred("grab_focus");
} break;
case EDIT_CUT: {
-
tx->cut();
tx->call_deferred("grab_focus");
} break;
case EDIT_COPY: {
-
tx->copy();
tx->call_deferred("grab_focus");
} break;
case EDIT_PASTE: {
-
tx->paste();
tx->call_deferred("grab_focus");
} break;
case EDIT_SELECT_ALL: {
-
tx->select_all();
tx->call_deferred("grab_focus");
} break;
case EDIT_MOVE_LINE_UP: {
-
code_editor->move_lines_up();
} break;
case EDIT_MOVE_LINE_DOWN: {
-
code_editor->move_lines_down();
} break;
case EDIT_INDENT_LEFT: {
-
Ref<Script> scr = script;
- if (scr.is_null())
+ if (scr.is_null()) {
return;
+ }
tx->indent_left();
} break;
case EDIT_INDENT_RIGHT: {
-
Ref<Script> scr = script;
- if (scr.is_null())
+ if (scr.is_null()) {
return;
+ }
tx->indent_right();
} break;
case EDIT_DELETE_LINE: {
-
code_editor->delete_lines();
} break;
case EDIT_CLONE_DOWN: {
-
code_editor->clone_lines_down();
} break;
case EDIT_TOGGLE_FOLD_LINE: {
-
tx->toggle_fold_line(tx->cursor_get_line());
tx->update();
} break;
case EDIT_FOLD_ALL_LINES: {
-
tx->fold_all_lines();
tx->update();
} break;
case EDIT_UNFOLD_ALL_LINES: {
-
tx->unhide_all_lines();
tx->update();
} break;
case EDIT_TOGGLE_COMMENT: {
-
_edit_option_toggle_inline_comment();
} break;
case EDIT_COMPLETE: {
-
tx->query_code_comple();
} break;
case EDIT_AUTO_INDENT: {
-
String text = tx->get_text();
Ref<Script> scr = script;
- if (scr.is_null())
+ if (scr.is_null()) {
return;
+ }
tx->begin_complex_operation();
int begin, end;
@@ -1206,35 +1188,27 @@ void ScriptTextEditor::_edit_option(int p_op) {
tx->end_complex_operation();
} break;
case EDIT_TRIM_TRAILING_WHITESAPCE: {
-
trim_trailing_whitespace();
} break;
case EDIT_CONVERT_INDENT_TO_SPACES: {
-
convert_indent_to_spaces();
} break;
case EDIT_CONVERT_INDENT_TO_TABS: {
-
convert_indent_to_tabs();
} break;
case EDIT_PICK_COLOR: {
-
color_panel->popup();
} break;
case EDIT_TO_UPPERCASE: {
-
_convert_case(CodeTextEditor::UPPER);
} break;
case EDIT_TO_LOWERCASE: {
-
_convert_case(CodeTextEditor::LOWER);
} break;
case EDIT_CAPITALIZE: {
-
_convert_case(CodeTextEditor::CAPITALIZE);
} break;
case EDIT_EVALUATE: {
-
Expression expression;
Vector<String> lines = code_editor->get_text_edit()->get_selection_text().split("\n");
PackedStringArray results;
@@ -1260,23 +1234,18 @@ void ScriptTextEditor::_edit_option(int p_op) {
code_editor->get_text_edit()->end_complex_operation();
} break;
case SEARCH_FIND: {
-
code_editor->get_find_replace_bar()->popup_search();
} break;
case SEARCH_FIND_NEXT: {
-
code_editor->get_find_replace_bar()->search_next();
} break;
case SEARCH_FIND_PREV: {
-
code_editor->get_find_replace_bar()->search_prev();
} break;
case SEARCH_REPLACE: {
-
code_editor->get_find_replace_bar()->popup_replace();
} break;
case SEARCH_IN_FILES: {
-
String selected_text = code_editor->get_text_edit()->get_selection_text();
// Yep, because it doesn't make sense to instance this dialog for every single script open...
@@ -1284,45 +1253,36 @@ void ScriptTextEditor::_edit_option(int p_op) {
emit_signal("search_in_files_requested", selected_text);
} break;
case REPLACE_IN_FILES: {
-
String selected_text = code_editor->get_text_edit()->get_selection_text();
emit_signal("replace_in_files_requested", selected_text);
} break;
case SEARCH_LOCATE_FUNCTION: {
-
quick_open->popup_dialog(get_functions());
quick_open->set_title(TTR("Go to Function"));
} break;
case SEARCH_GOTO_LINE: {
-
goto_line_dialog->popup_find_line(tx);
} break;
case BOOKMARK_TOGGLE: {
-
code_editor->toggle_bookmark();
} break;
case BOOKMARK_GOTO_NEXT: {
-
code_editor->goto_next_bookmark();
} break;
case BOOKMARK_GOTO_PREV: {
-
code_editor->goto_prev_bookmark();
} break;
case BOOKMARK_REMOVE_ALL: {
-
code_editor->remove_all_bookmarks();
} break;
case DEBUG_TOGGLE_BREAKPOINT: {
-
int line = tx->cursor_get_line();
bool dobreak = !tx->is_line_set_as_breakpoint(line);
tx->set_line_as_breakpoint(line, dobreak);
EditorDebuggerNode::get_singleton()->set_breakpoint(script->get_path(), line + 1, dobreak);
} break;
case DEBUG_REMOVE_ALL_BREAKPOINTS: {
-
List<int> bpoints;
tx->get_breakpoints(&bpoints);
@@ -1334,7 +1294,6 @@ void ScriptTextEditor::_edit_option(int p_op) {
}
} break;
case DEBUG_GOTO_NEXT_BREAKPOINT: {
-
List<int> bpoints;
tx->get_breakpoints(&bpoints);
if (bpoints.size() <= 0) {
@@ -1362,7 +1321,6 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case DEBUG_GOTO_PREV_BREAKPOINT: {
-
List<int> bpoints;
tx->get_breakpoints(&bpoints);
if (bpoints.size() <= 0) {
@@ -1389,19 +1347,19 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break;
case HELP_CONTEXTUAL: {
-
String text = tx->get_selection_text();
- if (text == "")
+ if (text == "") {
text = tx->get_word_under_cursor();
+ }
if (text != "") {
emit_signal("request_help", text);
}
} break;
case LOOKUP_SYMBOL: {
-
String text = tx->get_word_under_cursor();
- if (text == "")
+ if (text == "") {
text = tx->get_selection_text();
+ }
if (text != "") {
_lookup_symbol(text, tx->cursor_get_line(), tx->cursor_get_column());
}
@@ -1410,8 +1368,9 @@ void ScriptTextEditor::_edit_option(int p_op) {
}
void ScriptTextEditor::_edit_option_toggle_inline_comment() {
- if (script.is_null())
+ if (script.is_null()) {
return;
+ }
String delimiter = "#";
List<String> comment_delimiters;
@@ -1436,10 +1395,11 @@ void ScriptTextEditor::add_syntax_highlighter(SyntaxHighlighter *p_highlighter)
void ScriptTextEditor::set_syntax_highlighter(SyntaxHighlighter *p_highlighter) {
TextEdit *te = code_editor->get_text_edit();
te->_set_syntax_highlighting(p_highlighter);
- if (p_highlighter != nullptr)
+ if (p_highlighter != nullptr) {
highlighter_menu->set_item_checked(highlighter_menu->get_item_idx_from_text(p_highlighter->get_name()), true);
- else
+ } else {
highlighter_menu->set_item_checked(highlighter_menu->get_item_idx_from_text(TTR("Standard")), true);
+ }
}
void ScriptTextEditor::_change_syntax_highlighter(int p_idx) {
@@ -1453,7 +1413,6 @@ void ScriptTextEditor::_change_syntax_highlighter(int p_idx) {
}
void ScriptTextEditor::_bind_methods() {
-
ClassDB::bind_method("_update_connected_methods", &ScriptTextEditor::_update_connected_methods);
ClassDB::bind_method("get_drag_data_fw", &ScriptTextEditor::get_drag_data_fw);
@@ -1462,7 +1421,6 @@ void ScriptTextEditor::_bind_methods() {
}
Control *ScriptTextEditor::get_edit_menu() {
-
return edit_hb;
}
@@ -1471,11 +1429,11 @@ void ScriptTextEditor::clear_edit_menu() {
}
void ScriptTextEditor::reload(bool p_soft) {
-
TextEdit *te = code_editor->get_text_edit();
Ref<Script> scr = script;
- if (scr.is_null())
+ if (scr.is_null()) {
return;
+ }
scr->set_source_code(te->get_text());
bool soft = p_soft || scr->get_instance_base_type() == "EditorPlugin"; //always soft-reload editor plugins
@@ -1483,12 +1441,10 @@ void ScriptTextEditor::reload(bool p_soft) {
}
void ScriptTextEditor::get_breakpoints(List<int> *p_breakpoints) {
-
code_editor->get_text_edit()->get_breakpoints(p_breakpoints);
}
void ScriptTextEditor::set_tooltip_request_func(String p_method, Object *p_obj) {
-
code_editor->get_text_edit()->set_tooltip_request_func(p_obj, p_method, this);
}
@@ -1496,18 +1452,15 @@ void ScriptTextEditor::set_debugger_active(bool p_active) {
}
Variant ScriptTextEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
return Variant();
}
bool ScriptTextEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
Dictionary d = p_data;
if (d.has("type") && (String(d["type"]) == "resource" ||
String(d["type"]) == "files" ||
String(d["type"]) == "nodes" ||
String(d["type"]) == "files_and_dirs")) {
-
return true;
}
@@ -1515,26 +1468,27 @@ bool ScriptTextEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_
}
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
-
- if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
+ if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) {
return nullptr;
+ }
Ref<Script> scr = p_current_node->get_script();
- if (scr.is_valid() && scr == script)
+ if (scr.is_valid() && scr == script) {
return p_current_node;
+ }
for (int i = 0; i < p_current_node->get_child_count(); i++) {
Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);
- if (n)
+ if (n) {
return n;
+ }
}
return nullptr;
}
void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
-
Dictionary d = p_data;
TextEdit *te = code_editor->get_text_edit();
@@ -1542,7 +1496,6 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
te->_get_mouse_pos(p_point, row, col);
if (d.has("type") && String(d["type"]) == "resource") {
-
Ref<Resource> res = d["resource"];
if (!res.is_valid()) {
return;
@@ -1559,14 +1512,13 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
}
if (d.has("type") && (String(d["type"]) == "files" || String(d["type"]) == "files_and_dirs")) {
-
Array files = d["files"];
String text_to_drop;
for (int i = 0; i < files.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
text_to_drop += ",";
+ }
text_to_drop += "\"" + String(files[i]).c_escape() + "\"";
}
@@ -1576,7 +1528,6 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
}
if (d.has("type") && String(d["type"]) == "nodes") {
-
Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script);
if (!sn) {
@@ -1587,9 +1538,9 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
Array nodes = d["nodes"];
String text_to_drop;
for (int i = 0; i < nodes.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
text_to_drop += ",";
+ }
NodePath np = nodes[i];
Node *node = get_node(np);
@@ -1608,7 +1559,6 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
}
void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
-
Ref<InputEventMouseButton> mb = ev;
Ref<InputEventKey> k = ev;
Point2 local_pos;
@@ -1647,10 +1597,12 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
}
String word_at_pos = tx->get_word_at_pos(local_pos);
- if (word_at_pos == "")
+ if (word_at_pos == "") {
word_at_pos = tx->get_word_under_cursor();
- if (word_at_pos == "")
+ }
+ if (word_at_pos == "") {
word_at_pos = tx->get_selection_text();
+ }
bool has_color = (word_at_pos == "Color");
bool foldable = tx->can_fold(row) || tx->is_folded(row);
@@ -1727,7 +1679,6 @@ void ScriptTextEditor::_color_changed(const Color &p_color) {
}
void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p_foldable, bool p_open_docs, bool p_goto_definition, Vector2 p_pos) {
-
context_menu->clear();
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/undo"), EDIT_UNDO);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/redo"), EDIT_REDO);
@@ -1752,15 +1703,18 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/evaluate_selection"), EDIT_EVALUATE);
}
- if (p_foldable)
+ if (p_foldable) {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
+ }
if (p_color || p_open_docs || p_goto_definition) {
context_menu->add_separator();
- if (p_open_docs)
+ if (p_open_docs) {
context_menu->add_item(TTR("Lookup Symbol"), LOOKUP_SYMBOL);
- if (p_color)
+ }
+ if (p_color) {
context_menu->add_item(TTR("Pick Color"), EDIT_PICK_COLOR);
+ }
}
context_menu->set_position(get_global_transform().xform(p_pos));
@@ -1769,7 +1723,6 @@ void ScriptTextEditor::_make_context_menu(bool p_selection, bool p_color, bool p
}
ScriptTextEditor::ScriptTextEditor() {
-
theme_loaded = false;
script_is_valid = false;
@@ -1828,10 +1781,11 @@ ScriptTextEditor::ScriptTextEditor() {
// get default color picker mode from editor settings
int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode");
- if (default_color_mode == 1)
+ if (default_color_mode == 1) {
color_picker->set_hsv_mode(true);
- else if (default_color_mode == 2)
+ } else if (default_color_mode == 2) {
color_picker->set_raw_mode(true);
+ }
edit_hb = memnew(HBoxContainer);
@@ -1952,7 +1906,6 @@ ScriptTextEditor::~ScriptTextEditor() {
}
static ScriptEditorBase *create_editor(const RES &p_resource) {
-
if (Object::cast_to<Script>(*p_resource)) {
return memnew(ScriptTextEditor);
}
@@ -1960,7 +1913,6 @@ static ScriptEditorBase *create_editor(const RES &p_resource) {
}
void ScriptTextEditor::register_editor() {
-
ED_SHORTCUT("script_text_editor/undo", TTR("Undo"), KEY_MASK_CMD | KEY_Z);
ED_SHORTCUT("script_text_editor/redo", TTR("Redo"), KEY_MASK_CMD | KEY_Y);
ED_SHORTCUT("script_text_editor/cut", TTR("Cut"), KEY_MASK_CMD | KEY_X);
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 51ce30c831..adcd0218bc 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -37,7 +37,6 @@
#include "script_editor_plugin.h"
class ConnectionInfoDialog : public AcceptDialog {
-
GDCLASS(ConnectionInfoDialog, AcceptDialog);
Label *method;
@@ -52,7 +51,6 @@ public:
};
class ScriptTextEditor : public ScriptEditorBase {
-
GDCLASS(ScriptTextEditor, ScriptEditorBase);
CodeTextEditor *code_editor;
@@ -188,6 +186,8 @@ protected:
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
+ String _get_absolute_path(const String &rel_path);
+
public:
void _update_connected_methods();
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 9ef8148241..0c3a44e4cd 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -44,11 +44,10 @@
/*** SHADER SCRIPT EDITOR ****/
Ref<Shader> ShaderTextEditor::get_edited_shader() const {
-
return shader;
}
-void ShaderTextEditor::set_edited_shader(const Ref<Shader> &p_shader) {
+void ShaderTextEditor::set_edited_shader(const Ref<Shader> &p_shader) {
if (shader == p_shader) {
return;
}
@@ -84,7 +83,6 @@ void ShaderTextEditor::reload_text() {
}
void ShaderTextEditor::_load_theme_settings() {
-
get_text_edit()->clear_colors();
Color background_color = EDITOR_GET("text_editor/highlighting/background_color");
@@ -149,22 +147,18 @@ void ShaderTextEditor::_load_theme_settings() {
ShaderLanguage::get_keyword_list(&keywords);
if (shader.is_valid()) {
-
for (const Map<StringName, ShaderLanguage::FunctionInfo>::Element *E = ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader->get_mode())).front(); E; E = E->next()) {
-
for (const Map<StringName, ShaderLanguage::BuiltInInfo>::Element *F = E->get().built_ins.front(); F; F = F->next()) {
keywords.push_back(F->key());
}
}
for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode())).size(); i++) {
-
keywords.push_back(ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader->get_mode()))[i]);
}
}
for (List<String>::Element *E = keywords.front(); E; E = E->next()) {
-
get_text_edit()->add_keyword_color(E->get(), keyword_color);
}
@@ -174,7 +168,6 @@ void ShaderTextEditor::_load_theme_settings() {
}
void ShaderTextEditor::_check_shader_mode() {
-
String type = ShaderLanguage::get_shader_type(get_text_edit()->get_text());
Shader::Mode mode;
@@ -194,13 +187,11 @@ void ShaderTextEditor::_check_shader_mode() {
}
static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) {
-
RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable);
return RS::global_variable_type_get_shader_datatype(gvt);
}
void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options) {
-
_check_shader_mode();
ShaderLanguage sl;
@@ -212,7 +203,6 @@ void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCo
}
void ShaderTextEditor::_validate_script() {
-
_check_shader_mode();
String code = get_text_edit()->get_text();
@@ -227,13 +217,15 @@ void ShaderTextEditor::_validate_script() {
String error_text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text();
set_error(error_text);
set_error_pos(sl.get_error_line() - 1, 0);
- for (int i = 0; i < get_text_edit()->get_line_count(); i++)
+ for (int i = 0; i < get_text_edit()->get_line_count(); i++) {
get_text_edit()->set_line_as_marked(i, false);
+ }
get_text_edit()->set_line_as_marked(sl.get_error_line() - 1, true);
} else {
- for (int i = 0; i < get_text_edit()->get_line_count(); i++)
+ for (int i = 0; i < get_text_edit()->get_line_count(); i++) {
get_text_edit()->set_line_as_marked(i, false);
+ }
set_error("");
}
@@ -249,7 +241,6 @@ ShaderTextEditor::ShaderTextEditor() {
/*** SCRIPT EDITOR ******/
void ShaderEditor::_menu_option(int p_option) {
-
switch (p_option) {
case EDIT_UNDO: {
shader_editor->get_text_edit()->undo();
@@ -276,18 +267,18 @@ void ShaderEditor::_menu_option(int p_option) {
shader_editor->move_lines_down();
} break;
case EDIT_INDENT_LEFT: {
-
- if (shader.is_null())
+ if (shader.is_null()) {
return;
+ }
TextEdit *tx = shader_editor->get_text_edit();
tx->indent_left();
} break;
case EDIT_INDENT_RIGHT: {
-
- if (shader.is_null())
+ if (shader.is_null()) {
return;
+ }
TextEdit *tx = shader_editor->get_text_edit();
tx->indent_right();
@@ -300,51 +291,41 @@ void ShaderEditor::_menu_option(int p_option) {
shader_editor->clone_lines_down();
} break;
case EDIT_TOGGLE_COMMENT: {
-
- if (shader.is_null())
+ if (shader.is_null()) {
return;
+ }
shader_editor->toggle_inline_comment("//");
} break;
case EDIT_COMPLETE: {
-
shader_editor->get_text_edit()->query_code_comple();
} break;
case SEARCH_FIND: {
-
shader_editor->get_find_replace_bar()->popup_search();
} break;
case SEARCH_FIND_NEXT: {
-
shader_editor->get_find_replace_bar()->search_next();
} break;
case SEARCH_FIND_PREV: {
-
shader_editor->get_find_replace_bar()->search_prev();
} break;
case SEARCH_REPLACE: {
-
shader_editor->get_find_replace_bar()->popup_replace();
} break;
case SEARCH_GOTO_LINE: {
-
goto_line_dialog->popup_find_line(shader_editor->get_text_edit());
} break;
case BOOKMARK_TOGGLE: {
-
shader_editor->toggle_bookmark();
} break;
case BOOKMARK_GOTO_NEXT: {
-
shader_editor->goto_next_bookmark();
} break;
case BOOKMARK_GOTO_PREV: {
-
shader_editor->goto_prev_bookmark();
} break;
case BOOKMARK_REMOVE_ALL: {
-
shader_editor->remove_all_bookmarks();
} break;
case HELP_DOCS: {
@@ -357,19 +338,16 @@ void ShaderEditor::_menu_option(int p_option) {
}
void ShaderEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_WM_FOCUS_IN) {
_check_for_external_edit();
}
}
void ShaderEditor::_params_changed() {
-
shader_editor->_validate_script();
}
void ShaderEditor::_editor_settings_changed() {
-
shader_editor->get_text_edit()->set_auto_brace_completion(EditorSettings::get_singleton()->get("text_editor/completion/auto_brace_complete"));
shader_editor->get_text_edit()->set_scroll_pass_end_of_file(EditorSettings::get_singleton()->get("text_editor/cursor/scroll_past_end_of_file"));
shader_editor->get_text_edit()->set_indent_size(EditorSettings::get_singleton()->get("text_editor/indent/size"));
@@ -396,12 +374,10 @@ void ShaderEditor::_editor_settings_changed() {
}
void ShaderEditor::_bind_methods() {
-
ClassDB::bind_method("_params_changed", &ShaderEditor::_params_changed);
}
void ShaderEditor::ensure_select_current() {
-
/*
if (tab_container->get_child_count() && tab_container->get_current_tab()>=0) {
@@ -414,12 +390,10 @@ void ShaderEditor::ensure_select_current() {
}
void ShaderEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
-
shader_editor->goto_line_selection(p_line, p_begin, p_end);
}
void ShaderEditor::_check_for_external_edit() {
-
if (shader.is_null() || !shader.is_valid()) {
return;
}
@@ -440,7 +414,6 @@ void ShaderEditor::_check_for_external_edit() {
}
void ShaderEditor::_reload_shader_from_disk() {
-
Ref<Shader> rel_shader = ResourceLoader::load(shader->get_path(), shader->get_class(), true);
ERR_FAIL_COND(!rel_shader.is_valid());
@@ -450,12 +423,13 @@ void ShaderEditor::_reload_shader_from_disk() {
}
void ShaderEditor::edit(const Ref<Shader> &p_shader) {
-
- if (p_shader.is_null() || !p_shader->is_text_shader())
+ if (p_shader.is_null() || !p_shader->is_text_shader()) {
return;
+ }
- if (shader == p_shader)
+ if (shader == p_shader) {
return;
+ }
shader = p_shader;
@@ -466,7 +440,6 @@ void ShaderEditor::edit(const Ref<Shader> &p_shader) {
}
void ShaderEditor::save_external_data(const String &p_str) {
-
if (shader.is_null()) {
disk_changed->hide();
return;
@@ -482,7 +455,6 @@ void ShaderEditor::save_external_data(const String &p_str) {
}
void ShaderEditor::apply_shaders() {
-
if (shader.is_valid()) {
String shader_code = shader->get_code();
String editor_code = shader_editor->get_text_edit()->get_text();
@@ -494,13 +466,10 @@ void ShaderEditor::apply_shaders() {
}
void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
-
Ref<InputEventMouseButton> mb = ev;
if (mb.is_valid()) {
-
if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
-
int col, row;
TextEdit *tx = shader_editor->get_text_edit();
tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
@@ -508,7 +477,6 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
if (tx->is_right_click_moving_caret()) {
if (tx->is_selection_active()) {
-
int from_line = tx->get_selection_from_line();
int to_line = tx->get_selection_to_line();
int from_column = tx->get_selection_from_column();
@@ -537,7 +505,6 @@ void ShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
}
void ShaderEditor::_update_bookmark_list() {
-
bookmarks_menu->clear();
bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
@@ -565,7 +532,6 @@ void ShaderEditor::_update_bookmark_list() {
}
void ShaderEditor::_bookmark_item_pressed(int p_idx) {
-
if (p_idx < 4) { // Any item before the separator.
_menu_option(bookmarks_menu->get_item_id(p_idx));
} else {
@@ -574,7 +540,6 @@ void ShaderEditor::_bookmark_item_pressed(int p_idx) {
}
void ShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) {
-
context_menu->clear();
if (p_selection) {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
@@ -599,7 +564,6 @@ void ShaderEditor::_make_context_menu(bool p_selection, Vector2 p_position) {
}
ShaderEditor::ShaderEditor(EditorNode *p_node) {
-
shader_editor = memnew(ShaderTextEditor);
shader_editor->set_v_size_flags(SIZE_EXPAND_FILL);
shader_editor->add_theme_constant_override("separation", 0);
@@ -714,49 +678,42 @@ ShaderEditor::ShaderEditor(EditorNode *p_node) {
}
void ShaderEditorPlugin::edit(Object *p_object) {
-
Shader *s = Object::cast_to<Shader>(p_object);
shader_editor->edit(s);
}
bool ShaderEditorPlugin::handles(Object *p_object) const {
-
Shader *shader = Object::cast_to<Shader>(p_object);
return shader != nullptr && shader->is_text_shader();
}
void ShaderEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
button->show();
editor->make_bottom_panel_item_visible(shader_editor);
} else {
-
button->hide();
- if (shader_editor->is_visible_in_tree())
+ if (shader_editor->is_visible_in_tree()) {
editor->hide_bottom_panel();
+ }
shader_editor->apply_shaders();
}
}
void ShaderEditorPlugin::selected_notify() {
-
shader_editor->ensure_select_current();
}
void ShaderEditorPlugin::save_external_data() {
-
shader_editor->save_external_data();
}
void ShaderEditorPlugin::apply_changes() {
-
shader_editor->apply_shaders();
}
ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
shader_editor = memnew(ShaderEditor(p_node));
diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h
index f02ed590fc..0208b43e13 100644
--- a/editor/plugins/shader_editor_plugin.h
+++ b/editor/plugins/shader_editor_plugin.h
@@ -42,7 +42,6 @@
#include "servers/rendering/shader_language.h"
class ShaderTextEditor : public CodeTextEditor {
-
GDCLASS(ShaderTextEditor, CodeTextEditor);
Ref<Shader> shader;
@@ -66,7 +65,6 @@ public:
};
class ShaderEditor : public PanelContainer {
-
GDCLASS(ShaderEditor, PanelContainer);
enum {
@@ -143,7 +141,6 @@ public:
};
class ShaderEditorPlugin : public EditorPlugin {
-
GDCLASS(ShaderEditorPlugin, EditorPlugin);
bool _2d;
diff --git a/editor/plugins/shader_file_editor_plugin.cpp b/editor/plugins/shader_file_editor_plugin.cpp
new file mode 100644
index 0000000000..0ac29f68f6
--- /dev/null
+++ b/editor/plugins/shader_file_editor_plugin.cpp
@@ -0,0 +1,324 @@
+/*************************************************************************/
+/* shader_file_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "shader_file_editor_plugin.h"
+
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/os/keyboard.h"
+#include "core/os/os.h"
+#include "editor/editor_node.h"
+#include "editor/editor_scale.h"
+#include "editor/editor_settings.h"
+#include "editor/property_editor.h"
+#include "servers/display_server.h"
+#include "servers/rendering/shader_types.h"
+
+/*** SHADER SCRIPT EDITOR ****/
+
+/*** SCRIPT EDITOR ******/
+
+void ShaderFileEditor::_update_version(const StringName &p_version_txt, const RD::ShaderStage p_stage) {
+}
+
+void ShaderFileEditor::_version_selected(int p_option) {
+ int c = versions->get_current();
+ StringName version_txt = versions->get_item_metadata(c);
+
+ RD::ShaderStage stage = RD::SHADER_STAGE_MAX;
+ int first_found = -1;
+
+ Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(version_txt);
+ ERR_FAIL_COND(bytecode.is_null());
+
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ if (bytecode->get_stage_bytecode(RD::ShaderStage(i)).empty() && bytecode->get_stage_compile_error(RD::ShaderStage(i)) == String()) {
+ stages[i]->set_icon(Ref<Texture2D>());
+ continue;
+ }
+
+ Ref<Texture2D> icon;
+ if (bytecode->get_stage_compile_error(RD::ShaderStage(i)) != String()) {
+ icon = get_theme_icon("ImportFail", "EditorIcons");
+ } else {
+ icon = get_theme_icon("ImportCheck", "EditorIcons");
+ }
+ stages[i]->set_icon(icon);
+
+ if (first_found == -1) {
+ first_found = i;
+ }
+
+ if (stages[i]->is_pressed()) {
+ stage = RD::ShaderStage(i);
+ break;
+ }
+ }
+
+ error_text->clear();
+
+ if (stage == RD::SHADER_STAGE_MAX) { //need to change stage, does not have it
+ if (first_found == -1) {
+ error_text->add_text(TTR("No valid shader stages found."));
+ return; //well you did not put any stage I guess?
+ }
+ stages[first_found]->set_pressed(true);
+ stage = RD::ShaderStage(first_found);
+ }
+
+ String error = bytecode->get_stage_compile_error(stage);
+
+ error_text->push_font(get_theme_font("source", "EditorFonts"));
+
+ if (error == String()) {
+ error_text->add_text(TTR("Shader stage compiled without errors."));
+ } else {
+ error_text->add_text(error);
+ }
+}
+
+void ShaderFileEditor::_update_options() {
+ ERR_FAIL_COND(shader_file.is_null());
+
+ if (shader_file->get_base_error() != String()) {
+ stage_hb->hide();
+ versions->hide();
+ error_text->clear();
+ error_text->push_font(get_theme_font("source", "EditorFonts"));
+ error_text->add_text(vformat(TTR("File structure for '%s' contains unrecoverable errors:\n\n"), shader_file->get_path().get_file()));
+ error_text->add_text(shader_file->get_base_error());
+ return;
+ }
+
+ stage_hb->show();
+ versions->show();
+
+ int c = versions->get_current();
+ //remember current
+ versions->clear();
+ Vector<StringName> version_list = shader_file->get_version_list();
+
+ if (c >= version_list.size()) {
+ c = version_list.size() - 1;
+ }
+ if (c < 0) {
+ c = 0;
+ }
+
+ StringName current_version;
+
+ for (int i = 0; i < version_list.size(); i++) {
+ String title = version_list[i];
+ if (title == "") {
+ title = "default";
+ }
+
+ Ref<Texture2D> icon;
+
+ Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(version_list[i]);
+ ERR_FAIL_COND(bytecode.is_null());
+
+ bool failed = false;
+ for (int j = 0; j < RD::SHADER_STAGE_MAX; j++) {
+ String error = bytecode->get_stage_compile_error(RD::ShaderStage(j));
+ if (error != String()) {
+ failed = true;
+ }
+ }
+
+ if (failed) {
+ icon = get_theme_icon("ImportFail", "EditorIcons");
+ } else {
+ icon = get_theme_icon("ImportCheck", "EditorIcons");
+ }
+
+ versions->add_item(title, icon);
+ versions->set_item_metadata(i, version_list[i]);
+
+ if (i == c) {
+ versions->select(i);
+ current_version = version_list[i];
+ }
+ }
+
+ if (version_list.size() == 0) {
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ stages[i]->set_disabled(true);
+ }
+ return;
+ }
+
+ Ref<RDShaderBytecode> bytecode = shader_file->get_bytecode(current_version);
+ ERR_FAIL_COND(bytecode.is_null());
+ int first_valid = -1;
+ int current = -1;
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ Vector<uint8_t> bc = bytecode->get_stage_bytecode(RD::ShaderStage(i));
+ String error = bytecode->get_stage_compile_error(RD::ShaderStage(i));
+ bool disable = error == String() && bc.empty();
+ stages[i]->set_disabled(disable);
+ if (!disable) {
+ if (stages[i]->is_pressed()) {
+ current = i;
+ }
+ first_valid = i;
+ }
+ }
+
+ if (current == -1 && first_valid != -1) {
+ stages[first_valid]->set_pressed(true);
+ }
+
+ _version_selected(0);
+}
+
+void ShaderFileEditor::_notification(int p_what) {
+ if (p_what == NOTIFICATION_WM_FOCUS_IN) {
+ if (is_visible_in_tree() && shader_file.is_valid()) {
+ _update_options();
+ }
+ }
+}
+
+void ShaderFileEditor::_editor_settings_changed() {
+ if (is_visible_in_tree() && shader_file.is_valid()) {
+ _update_options();
+ }
+}
+
+void ShaderFileEditor::_bind_methods() {
+}
+
+void ShaderFileEditor::edit(const Ref<RDShaderFile> &p_shader) {
+ if (p_shader.is_null()) {
+ if (shader_file.is_valid()) {
+ shader_file->disconnect("changed", callable_mp(this, &ShaderFileEditor::_shader_changed));
+ }
+ return;
+ }
+
+ if (shader_file == p_shader) {
+ return;
+ }
+
+ shader_file = p_shader;
+
+ if (shader_file.is_valid()) {
+ shader_file->connect("changed", callable_mp(this, &ShaderFileEditor::_shader_changed));
+ }
+
+ _update_options();
+}
+
+void ShaderFileEditor::_shader_changed() {
+ if (is_visible_in_tree()) {
+ _update_options();
+ }
+}
+
+ShaderFileEditor *ShaderFileEditor::singleton = nullptr;
+
+ShaderFileEditor::ShaderFileEditor(EditorNode *p_node) {
+ singleton = this;
+ HSplitContainer *main_hs = memnew(HSplitContainer);
+
+ add_child(main_hs);
+
+ versions = memnew(ItemList);
+ versions->connect("item_selected", callable_mp(this, &ShaderFileEditor::_version_selected));
+ versions->set_custom_minimum_size(Size2i(200 * EDSCALE, 0));
+ main_hs->add_child(versions);
+
+ VBoxContainer *main_vb = memnew(VBoxContainer);
+ main_vb->set_h_size_flags(SIZE_EXPAND_FILL);
+ main_hs->add_child(main_vb);
+
+ static const char *stage_str[RD::SHADER_STAGE_MAX] = {
+ "Vertex",
+ "Fragment",
+ "TessControl",
+ "TessEval",
+ "Compute"
+ };
+
+ stage_hb = memnew(HBoxContainer);
+ main_vb->add_child(stage_hb);
+
+ Ref<ButtonGroup> bg;
+ bg.instance();
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ Button *button = memnew(Button(stage_str[i]));
+ button->set_toggle_mode(true);
+ button->set_focus_mode(FOCUS_NONE);
+ stage_hb->add_child(button);
+ stages[i] = button;
+ button->set_button_group(bg);
+ button->connect("pressed", callable_mp(this, &ShaderFileEditor::_version_selected), varray(i));
+ }
+
+ error_text = memnew(RichTextLabel);
+ error_text->set_v_size_flags(SIZE_EXPAND_FILL);
+ main_vb->add_child(error_text);
+}
+
+void ShaderFileEditorPlugin::edit(Object *p_object) {
+ RDShaderFile *s = Object::cast_to<RDShaderFile>(p_object);
+ shader_editor->edit(s);
+}
+
+bool ShaderFileEditorPlugin::handles(Object *p_object) const {
+ RDShaderFile *shader = Object::cast_to<RDShaderFile>(p_object);
+ return shader != nullptr;
+}
+
+void ShaderFileEditorPlugin::make_visible(bool p_visible) {
+ if (p_visible) {
+ button->show();
+ editor->make_bottom_panel_item_visible(shader_editor);
+
+ } else {
+ button->hide();
+ if (shader_editor->is_visible_in_tree()) {
+ editor->hide_bottom_panel();
+ }
+ }
+}
+
+ShaderFileEditorPlugin::ShaderFileEditorPlugin(EditorNode *p_node) {
+ editor = p_node;
+ shader_editor = memnew(ShaderFileEditor(p_node));
+
+ shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
+ button = editor->add_bottom_panel_item(TTR("ShaderFile"), shader_editor);
+ button->hide();
+}
+
+ShaderFileEditorPlugin::~ShaderFileEditorPlugin() {
+}
diff --git a/editor/plugins/shader_file_editor_plugin.h b/editor/plugins/shader_file_editor_plugin.h
new file mode 100644
index 0000000000..19617366b2
--- /dev/null
+++ b/editor/plugins/shader_file_editor_plugin.h
@@ -0,0 +1,92 @@
+/*************************************************************************/
+/* shader_file_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef SHADER_FILE_EDITOR_PLUGIN_H
+#define SHADER_FILE_EDITOR_PLUGIN_H
+
+#include "editor/code_editor.h"
+#include "editor/editor_plugin.h"
+#include "scene/gui/menu_button.h"
+#include "scene/gui/panel_container.h"
+#include "scene/gui/rich_text_label.h"
+#include "scene/gui/tab_container.h"
+#include "scene/gui/text_edit.h"
+#include "scene/main/timer.h"
+#include "servers/rendering/rendering_device_binds.h"
+
+class ShaderFileEditor : public PanelContainer {
+ GDCLASS(ShaderFileEditor, PanelContainer);
+
+ Ref<RDShaderFile> shader_file;
+
+ HBoxContainer *stage_hb;
+ ItemList *versions;
+ Button *stages[RD::SHADER_STAGE_MAX];
+ RichTextLabel *error_text;
+
+ void _update_version(const StringName &p_version_txt, const RenderingDevice::ShaderStage p_stage);
+ void _version_selected(int p_stage);
+ void _editor_settings_changed();
+
+ void _update_options();
+ void _shader_changed();
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ static ShaderFileEditor *singleton;
+ void edit(const Ref<RDShaderFile> &p_shader);
+
+ ShaderFileEditor(EditorNode *p_node);
+};
+
+class ShaderFileEditorPlugin : public EditorPlugin {
+ GDCLASS(ShaderFileEditorPlugin, EditorPlugin);
+
+ ShaderFileEditor *shader_editor;
+ EditorNode *editor;
+ Button *button;
+
+public:
+ virtual String get_name() const { return "ShaderFile"; }
+ bool has_main_screen() const { return false; }
+ virtual void edit(Object *p_object);
+ virtual bool handles(Object *p_object) const;
+ virtual void make_visible(bool p_visible);
+
+ ShaderFileEditor *get_shader_editor() const { return shader_editor; }
+
+ ShaderFileEditorPlugin(EditorNode *p_node);
+ ~ShaderFileEditorPlugin();
+};
+
+#endif // SHADER_FILE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/skeleton_2d_editor_plugin.cpp b/editor/plugins/skeleton_2d_editor_plugin.cpp
index c81d3f787e..a198e4ff8f 100644
--- a/editor/plugins/skeleton_2d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_2d_editor_plugin.cpp
@@ -36,7 +36,6 @@
#include "thirdparty/misc/clipper.hpp"
void Skeleton2DEditor::_node_removed(Node *p_node) {
-
if (p_node == node) {
node = nullptr;
options->hide();
@@ -44,19 +43,16 @@ void Skeleton2DEditor::_node_removed(Node *p_node) {
}
void Skeleton2DEditor::edit(Skeleton2D *p_sprite) {
-
node = p_sprite;
}
void Skeleton2DEditor::_menu_option(int p_option) {
-
if (!node) {
return;
}
switch (p_option) {
case MENU_OPTION_MAKE_REST: {
-
if (node->get_bone_count() == 0) {
err_dialog->set_text(TTR("This skeleton has no bones, create some children Bone2D nodes."));
err_dialog->popup_centered();
@@ -95,7 +91,6 @@ void Skeleton2DEditor::_bind_methods() {
}
Skeleton2DEditor::Skeleton2DEditor() {
-
options = memnew(MenuButton);
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(options);
@@ -115,28 +110,23 @@ Skeleton2DEditor::Skeleton2DEditor() {
}
void Skeleton2DEditorPlugin::edit(Object *p_object) {
-
sprite_editor->edit(Object::cast_to<Skeleton2D>(p_object));
}
bool Skeleton2DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("Skeleton2D");
}
void Skeleton2DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
sprite_editor->options->show();
} else {
-
sprite_editor->options->hide();
sprite_editor->edit(nullptr);
}
}
Skeleton2DEditorPlugin::Skeleton2DEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
sprite_editor = memnew(Skeleton2DEditor);
editor->get_viewport()->add_child(sprite_editor);
diff --git a/editor/plugins/skeleton_2d_editor_plugin.h b/editor/plugins/skeleton_2d_editor_plugin.h
index ebc6746b81..f1ba1a3612 100644
--- a/editor/plugins/skeleton_2d_editor_plugin.h
+++ b/editor/plugins/skeleton_2d_editor_plugin.h
@@ -37,7 +37,6 @@
#include "scene/gui/spin_box.h"
class Skeleton2DEditor : public Control {
-
GDCLASS(Skeleton2DEditor, Control);
enum Menu {
@@ -65,7 +64,6 @@ public:
};
class Skeleton2DEditorPlugin : public EditorPlugin {
-
GDCLASS(Skeleton2DEditorPlugin, EditorPlugin);
Skeleton2DEditor *sprite_editor;
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index fac4cb19d8..c256acd17b 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -63,22 +63,18 @@ void Skeleton3DEditor::create_physical_skeleton() {
bones_infos.resize(bc);
for (int bone_id = 0; bc > bone_id; ++bone_id) {
-
const int parent = skeleton->get_bone_parent(bone_id);
if (parent < 0) {
-
bones_infos.write[bone_id].relative_rest = skeleton->get_bone_rest(bone_id);
} else {
-
const int parent_parent = skeleton->get_bone_parent(parent);
bones_infos.write[bone_id].relative_rest = bones_infos[parent].relative_rest * skeleton->get_bone_rest(bone_id);
/// create physical bone on parent
if (!bones_infos[parent].physical_bone) {
-
bones_infos.write[parent].physical_bone = create_physical_bone(parent, bone_id, bones_infos);
ur->create_action(TTR("Create physical bones"));
@@ -93,7 +89,6 @@ void Skeleton3DEditor::create_physical_skeleton() {
/// Create joint between parent of parent
if (-1 != parent_parent) {
-
bones_infos[parent].physical_bone->set_joint_type(PhysicalBone3D::JOINT_TYPE_PIN);
}
}
@@ -102,7 +97,6 @@ void Skeleton3DEditor::create_physical_skeleton() {
}
PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_child_id, const Vector<BoneInfo> &bones_infos) {
-
const Transform child_rest = skeleton->get_bone_rest(bone_child_id);
const real_t half_height(child_rest.origin.length() * 0.5);
@@ -131,7 +125,6 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi
}
void Skeleton3DEditor::edit(Skeleton3D *p_node) {
-
skeleton = p_node;
}
@@ -142,7 +135,6 @@ void Skeleton3DEditor::_notification(int p_what) {
}
void Skeleton3DEditor::_node_removed(Node *p_node) {
-
if (p_node == skeleton) {
skeleton = nullptr;
options->hide();
@@ -180,7 +172,6 @@ void Skeleton3DEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
skeleton_editor->options->show();
} else {
-
skeleton_editor->options->hide();
skeleton_editor->edit(nullptr);
}
diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h
index 2ba5a817bc..af9ebb6246 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.h
+++ b/editor/plugins/skeleton_3d_editor_plugin.h
@@ -46,10 +46,9 @@ class Skeleton3DEditor : public Node {
};
struct BoneInfo {
- PhysicalBone3D *physical_bone;
+ PhysicalBone3D *physical_bone = nullptr;
Transform relative_rest; // Relative to skeleton node
- BoneInfo() :
- physical_bone(nullptr) {}
+ BoneInfo() {}
};
Skeleton3D *skeleton;
@@ -76,7 +75,6 @@ public:
};
class Skeleton3DEditorPlugin : public EditorPlugin {
-
GDCLASS(Skeleton3DEditorPlugin, EditorPlugin);
EditorNode *editor;
diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
index a22534eac0..8fc789b94a 100644
--- a/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_ik_3d_editor_plugin.cpp
@@ -33,12 +33,13 @@
#include "scene/3d/skeleton_ik_3d.h"
void SkeletonIK3DEditorPlugin::_play() {
-
- if (!skeleton_ik)
+ if (!skeleton_ik) {
return;
+ }
- if (!skeleton_ik->get_parent_skeleton())
+ if (!skeleton_ik->get_parent_skeleton()) {
return;
+ }
if (play_btn->is_pressed()) {
skeleton_ik->start();
@@ -49,7 +50,6 @@ void SkeletonIK3DEditorPlugin::_play() {
}
void SkeletonIK3DEditorPlugin::edit(Object *p_object) {
-
if (p_object != skeleton_ik) {
if (skeleton_ik) {
play_btn->set_pressed(false);
@@ -58,30 +58,29 @@ void SkeletonIK3DEditorPlugin::edit(Object *p_object) {
}
SkeletonIK3D *s = Object::cast_to<SkeletonIK3D>(p_object);
- if (!s)
+ if (!s) {
return;
+ }
skeleton_ik = s;
}
bool SkeletonIK3DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("SkeletonIK3D");
}
void SkeletonIK3DEditorPlugin::make_visible(bool p_visible) {
-
- if (p_visible)
+ if (p_visible) {
play_btn->show();
- else
+ } else {
play_btn->hide();
+ }
}
void SkeletonIK3DEditorPlugin::_bind_methods() {
}
SkeletonIK3DEditorPlugin::SkeletonIK3DEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
play_btn = memnew(Button);
play_btn->set_icon(editor->get_gui_base()->get_theme_icon("Play", "EditorIcons"));
diff --git a/editor/plugins/skeleton_ik_3d_editor_plugin.h b/editor/plugins/skeleton_ik_3d_editor_plugin.h
index 88472a2963..bd4c5ba93e 100644
--- a/editor/plugins/skeleton_ik_3d_editor_plugin.h
+++ b/editor/plugins/skeleton_ik_3d_editor_plugin.h
@@ -37,7 +37,6 @@
class SkeletonIK3D;
class SkeletonIK3DEditorPlugin : public EditorPlugin {
-
GDCLASS(SkeletonIK3DEditorPlugin, EditorPlugin);
SkeletonIK3D *skeleton_ik;
diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp
index ab0f15d3d0..b21586a6b0 100644
--- a/editor/plugins/sprite_2d_editor_plugin.cpp
+++ b/editor/plugins/sprite_2d_editor_plugin.cpp
@@ -40,7 +40,6 @@
#include "thirdparty/misc/clipper.hpp"
void Sprite2DEditor::_node_removed(Node *p_node) {
-
if (p_node == node) {
node = nullptr;
options->hide();
@@ -48,7 +47,6 @@ void Sprite2DEditor::_node_removed(Node *p_node) {
}
void Sprite2DEditor::edit(Sprite2D *p_sprite) {
-
node = p_sprite;
}
@@ -63,7 +61,6 @@ Vector<Vector2> expand(const Vector<Vector2> &points, const Rect2i &rect, float
ClipperLib::PolyTree out;
for (int i = 0; i < points.size(); i++) {
-
subj << ClipperLib::IntPoint(points[i].x * PRECISION, points[i].y * PRECISION);
}
ClipperLib::ClipperOffset co;
@@ -104,7 +101,6 @@ Vector<Vector2> expand(const Vector<Vector2> &points, const Rect2i &rect, float
int lasti = p2->Contour.size() - 1;
Vector2 prev = Vector2(p2->Contour[lasti].X / PRECISION, p2->Contour[lasti].Y / PRECISION);
for (uint64_t i = 0; i < p2->Contour.size(); i++) {
-
Vector2 cur = Vector2(p2->Contour[i].X / PRECISION, p2->Contour[i].Y / PRECISION);
if (cur.distance_to(prev) > 0.5) {
outPoints.push_back(cur);
@@ -115,7 +111,6 @@ Vector<Vector2> expand(const Vector<Vector2> &points, const Rect2i &rect, float
}
void Sprite2DEditor::_menu_option(int p_option) {
-
if (!node) {
return;
}
@@ -124,7 +119,6 @@ void Sprite2DEditor::_menu_option(int p_option) {
switch (p_option) {
case MENU_OPTION_CONVERT_TO_MESH_2D: {
-
debug_uv_dialog->get_ok()->set_text(TTR("Create Mesh2D"));
debug_uv_dialog->set_title(TTR("Mesh2D Preview"));
@@ -134,7 +128,6 @@ void Sprite2DEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CONVERT_TO_POLYGON_2D: {
-
debug_uv_dialog->get_ok()->set_text(TTR("Create Polygon2D"));
debug_uv_dialog->set_title(TTR("Polygon2D Preview"));
@@ -143,7 +136,6 @@ void Sprite2DEditor::_menu_option(int p_option) {
debug_uv->update();
} break;
case MENU_OPTION_CREATE_COLLISION_POLY_2D: {
-
debug_uv_dialog->get_ok()->set_text(TTR("Create CollisionPolygon2D"));
debug_uv_dialog->set_title(TTR("CollisionPolygon2D Preview"));
@@ -153,7 +145,6 @@ void Sprite2DEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CREATE_LIGHT_OCCLUDER_2D: {
-
debug_uv_dialog->get_ok()->set_text(TTR("Create LightOccluder2D"));
debug_uv_dialog->set_title(TTR("LightOccluder2D Preview"));
@@ -166,7 +157,6 @@ void Sprite2DEditor::_menu_option(int p_option) {
}
void Sprite2DEditor::_update_mesh_data() {
-
Ref<Texture2D> texture = node->get_texture();
if (texture.is_null()) {
err_dialog->set_text(TTR("Sprite2D is empty!"));
@@ -183,10 +173,11 @@ void Sprite2DEditor::_update_mesh_data() {
Ref<Image> image = texture->get_data();
ERR_FAIL_COND(image.is_null());
Rect2 rect;
- if (node->is_region())
+ if (node->is_region()) {
rect = node->get_region_rect();
- else
+ } else {
rect.size = Size2(image->get_width(), image->get_height());
+ }
Ref<BitMap> bm;
bm.instance();
@@ -218,7 +209,6 @@ void Sprite2DEditor::_update_mesh_data() {
}
if (selected_menu_item == MENU_OPTION_CONVERT_TO_MESH_2D) {
-
for (int j = 0; j < lines.size(); j++) {
int index_ofs = computed_vertices.size();
@@ -229,13 +219,16 @@ void Sprite2DEditor::_update_mesh_data() {
vtx -= rect.position; //offset by rect position
//flip if flipped
- if (node->is_flipped_h())
+ if (node->is_flipped_h()) {
vtx.x = rect.size.x - vtx.x - 1.0;
- if (node->is_flipped_v())
+ }
+ if (node->is_flipped_v()) {
vtx.y = rect.size.y - vtx.y - 1.0;
+ }
- if (node->is_centered())
+ if (node->is_centered()) {
vtx -= rect.size / 2.0;
+ }
computed_vertices.push_back(vtx);
}
@@ -262,7 +255,6 @@ void Sprite2DEditor::_update_mesh_data() {
outline_lines.resize(lines.size());
computed_outline_lines.resize(lines.size());
for (int pi = 0; pi < lines.size(); pi++) {
-
Vector<Vector2> ol;
Vector<Vector2> col;
@@ -277,13 +269,16 @@ void Sprite2DEditor::_update_mesh_data() {
vtx -= rect.position; //offset by rect position
//flip if flipped
- if (node->is_flipped_h())
+ if (node->is_flipped_h()) {
vtx.x = rect.size.x - vtx.x - 1.0;
- if (node->is_flipped_v())
+ }
+ if (node->is_flipped_v()) {
vtx.y = rect.size.y - vtx.y - 1.0;
+ }
- if (node->is_centered())
+ if (node->is_centered()) {
vtx -= rect.size / 2.0;
+ }
col.write[i] = vtx;
}
@@ -314,7 +309,6 @@ void Sprite2DEditor::_create_node() {
}
void Sprite2DEditor::_convert_to_mesh_2d_node() {
-
if (computed_vertices.size() < 3) {
err_dialog->set_text(TTR("Invalid geometry, can't replace by mesh."));
err_dialog->popup_centered();
@@ -345,7 +339,6 @@ void Sprite2DEditor::_convert_to_mesh_2d_node() {
}
void Sprite2DEditor::_convert_to_polygon_2d_node() {
-
if (computed_outline_lines.empty()) {
err_dialog->set_text(TTR("Invalid geometry, can't create polygon."));
err_dialog->popup_centered();
@@ -355,8 +348,9 @@ void Sprite2DEditor::_convert_to_polygon_2d_node() {
Polygon2D *polygon_2d_instance = memnew(Polygon2D);
int total_point_count = 0;
- for (int i = 0; i < computed_outline_lines.size(); i++)
+ for (int i = 0; i < computed_outline_lines.size(); i++) {
total_point_count += computed_outline_lines[i].size();
+ }
PackedVector2Array polygon;
polygon.resize(total_point_count);
@@ -372,7 +366,6 @@ void Sprite2DEditor::_convert_to_polygon_2d_node() {
polys.resize(computed_outline_lines.size());
for (int i = 0; i < computed_outline_lines.size(); i++) {
-
Vector<Vector2> outline = computed_outline_lines[i];
Vector<Vector2> uv_outline = outline_lines[i];
@@ -404,7 +397,6 @@ void Sprite2DEditor::_convert_to_polygon_2d_node() {
}
void Sprite2DEditor::_create_collision_polygon_2d_node() {
-
if (computed_outline_lines.empty()) {
err_dialog->set_text(TTR("Invalid geometry, can't create collision polygon."));
err_dialog->popup_centered();
@@ -412,7 +404,6 @@ void Sprite2DEditor::_create_collision_polygon_2d_node() {
}
for (int i = 0; i < computed_outline_lines.size(); i++) {
-
Vector<Vector2> outline = computed_outline_lines[i];
CollisionPolygon2D *collision_polygon_2d_instance = memnew(CollisionPolygon2D);
@@ -428,7 +419,6 @@ void Sprite2DEditor::_create_collision_polygon_2d_node() {
}
void Sprite2DEditor::_create_light_occluder_2d_node() {
-
if (computed_outline_lines.empty()) {
err_dialog->set_text(TTR("Invalid geometry, can't create light occluder."));
err_dialog->popup_centered();
@@ -436,7 +426,6 @@ void Sprite2DEditor::_create_light_occluder_2d_node() {
}
for (int i = 0; i < computed_outline_lines.size(); i++) {
-
Vector<Vector2> outline = computed_outline_lines[i];
Ref<OccluderPolygon2D> polygon;
@@ -475,7 +464,6 @@ void Sprite2DEditor::_add_as_sibling_or_child(Node *p_own_node, Node *p_new_node
}
void Sprite2DEditor::_debug_uv_draw() {
-
Ref<Texture2D> tex = node->get_texture();
ERR_FAIL_COND(!tex.is_valid());
@@ -503,12 +491,10 @@ void Sprite2DEditor::_debug_uv_draw() {
}
void Sprite2DEditor::_bind_methods() {
-
ClassDB::bind_method("_add_as_sibling_or_child", &Sprite2DEditor::_add_as_sibling_or_child);
}
Sprite2DEditor::Sprite2DEditor() {
-
options = memnew(MenuButton);
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(options);
@@ -577,28 +563,23 @@ Sprite2DEditor::Sprite2DEditor() {
}
void Sprite2DEditorPlugin::edit(Object *p_object) {
-
sprite_editor->edit(Object::cast_to<Sprite2D>(p_object));
}
bool Sprite2DEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("Sprite2D");
}
void Sprite2DEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
sprite_editor->options->show();
} else {
-
sprite_editor->options->hide();
sprite_editor->edit(nullptr);
}
}
Sprite2DEditorPlugin::Sprite2DEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
sprite_editor = memnew(Sprite2DEditor);
editor->get_viewport()->add_child(sprite_editor);
diff --git a/editor/plugins/sprite_2d_editor_plugin.h b/editor/plugins/sprite_2d_editor_plugin.h
index 0add77843b..c2b942fd82 100644
--- a/editor/plugins/sprite_2d_editor_plugin.h
+++ b/editor/plugins/sprite_2d_editor_plugin.h
@@ -37,7 +37,6 @@
#include "scene/gui/spin_box.h"
class Sprite2DEditor : public Control {
-
GDCLASS(Sprite2DEditor, Control);
enum Menu {
@@ -97,7 +96,6 @@ public:
};
class Sprite2DEditorPlugin : public EditorPlugin {
-
GDCLASS(Sprite2DEditorPlugin, EditorPlugin);
Sprite2DEditor *sprite_editor;
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 76e60bb014..859fec1628 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -41,7 +41,6 @@ void SpriteFramesEditor::_gui_input(Ref<InputEvent> p_event) {
}
void SpriteFramesEditor::_open_sprite_sheet() {
-
file_split_sheet->clear_filters();
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("Texture2D", &extensions);
@@ -53,7 +52,6 @@ void SpriteFramesEditor::_open_sprite_sheet() {
}
void SpriteFramesEditor::_sheet_preview_draw() {
-
Size2i size = split_sheet_preview->get_size();
int h = split_sheet_h->get_value();
int v = split_sheet_v->get_value();
@@ -61,13 +59,11 @@ void SpriteFramesEditor::_sheet_preview_draw() {
int height = size.height / v;
const float a = 0.3;
for (int i = 1; i < h; i++) {
-
int x = i * width;
split_sheet_preview->draw_line(Point2(x, 0), Point2(x, size.height), Color(1, 1, 1, a));
split_sheet_preview->draw_line(Point2(x + 1, 0), Point2(x + 1, size.height), Color(0, 0, 0, a));
for (int j = 1; j < v; j++) {
-
int y = j * height;
split_sheet_preview->draw_line(Point2(0, y), Point2(size.width, y), Color(1, 1, 1, a));
@@ -102,8 +98,8 @@ void SpriteFramesEditor::_sheet_preview_draw() {
split_sheet_dialog->get_ok()->set_disabled(false);
split_sheet_dialog->get_ok()->set_text(vformat(TTR("Add %d Frame(s)"), frames_selected.size()));
}
-void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) {
+void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
@@ -145,7 +141,6 @@ void SpriteFramesEditor::_sheet_preview_input(const Ref<InputEvent> &p_event) {
}
void SpriteFramesEditor::_sheet_add_frames() {
-
Size2i size = split_sheet_preview->get_size();
int h = split_sheet_h->get_value();
int v = split_sheet_v->get_value();
@@ -154,14 +149,22 @@ void SpriteFramesEditor::_sheet_add_frames() {
int fc = frames->get_frame_count(edited_anim);
+ AtlasTexture *atlas_source = Object::cast_to<AtlasTexture>(*split_sheet_preview->get_texture());
+
+ Rect2 region_rect = Rect2();
+
+ if (atlas_source && atlas_source->get_atlas().is_valid()) {
+ region_rect = atlas_source->get_region();
+ }
+
for (Set<int>::Element *E = frames_selected.front(); E; E = E->next()) {
int idx = E->get();
int width = size.width / h;
int height = size.height / v;
int xp = idx % h;
int yp = (idx - xp) / h;
- int x = xp * width;
- int y = yp * height;
+ int x = (xp * width) + region_rect.position.x;
+ int y = (yp * height) + region_rect.position.y;
Ref<AtlasTexture> at;
at.instance();
@@ -178,7 +181,6 @@ void SpriteFramesEditor::_sheet_add_frames() {
}
void SpriteFramesEditor::_sheet_select_clear_all_frames() {
-
bool should_clear = true;
for (int i = 0; i < split_sheet_h->get_value() * split_sheet_v->get_value(); i++) {
if (!frames_selected.has(i)) {
@@ -194,14 +196,12 @@ void SpriteFramesEditor::_sheet_select_clear_all_frames() {
}
void SpriteFramesEditor::_sheet_spin_changed(double) {
-
frames_selected.clear();
last_frame_selected = -1;
split_sheet_preview->update();
}
void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
-
Ref<Resource> texture = ResourceLoader::load(p_file);
if (!texture.is_valid()) {
EditorNode::get_singleton()->show_warning(TTR("Unable to load images"));
@@ -220,7 +220,6 @@ void SpriteFramesEditor::_prepare_sprite_sheet(const String &p_file) {
}
void SpriteFramesEditor::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
load->set_icon(get_theme_icon("Load", "EditorIcons"));
@@ -246,13 +245,11 @@ void SpriteFramesEditor::_notification(int p_what) {
}
void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_at_pos) {
-
ERR_FAIL_COND(!frames->has_animation(edited_anim));
List<Ref<Texture2D>> resources;
for (int i = 0; i < p_path.size(); i++) {
-
Ref<Texture2D> resource;
resource = ResourceLoader::load(p_path[i]);
@@ -279,7 +276,6 @@ void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_
int count = 0;
for (List<Ref<Texture2D>>::Element *E = resources.front(); E; E = E->next()) {
-
undo_redo->add_do_method(frames, "add_frame", edited_anim, E->get(), p_at_pos == -1 ? -1 : p_at_pos + count);
undo_redo->add_undo_method(frames, "remove_frame", edited_anim, p_at_pos == -1 ? fc : p_at_pos);
count++;
@@ -291,15 +287,15 @@ void SpriteFramesEditor::_file_load_request(const Vector<String> &p_path, int p_
}
void SpriteFramesEditor::_load_pressed() {
-
ERR_FAIL_COND(!frames->has_animation(edited_anim));
loading_scene = false;
file->clear_filters();
List<String> extensions;
ResourceLoader::get_recognized_extensions_for_type("Texture2D", &extensions);
- for (int i = 0; i < extensions.size(); i++)
+ for (int i = 0; i < extensions.size(); i++) {
file->add_filter("*." + extensions[i]);
+ }
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES);
@@ -307,7 +303,6 @@ void SpriteFramesEditor::_load_pressed() {
}
void SpriteFramesEditor::_paste_pressed() {
-
ERR_FAIL_COND(!frames->has_animation(edited_anim));
Ref<Texture2D> r = EditorSettings::get_singleton()->get_resource_clipboard();
@@ -331,8 +326,9 @@ void SpriteFramesEditor::_paste_pressed() {
void SpriteFramesEditor::_copy_pressed() {
ERR_FAIL_COND(!frames->has_animation(edited_anim));
- if (tree->get_current() < 0)
+ if (tree->get_current() < 0) {
return;
+ }
Ref<Texture2D> r = frames->get_frame(edited_anim, tree->get_current());
if (!r.is_valid()) {
return;
@@ -342,13 +338,11 @@ void SpriteFramesEditor::_copy_pressed() {
}
void SpriteFramesEditor::_empty_pressed() {
-
ERR_FAIL_COND(!frames->has_animation(edited_anim));
int from = -1;
if (tree->get_current() >= 0) {
-
from = tree->get_current();
sel = from;
@@ -367,13 +361,11 @@ void SpriteFramesEditor::_empty_pressed() {
}
void SpriteFramesEditor::_empty2_pressed() {
-
ERR_FAIL_COND(!frames->has_animation(edited_anim));
int from = -1;
if (tree->get_current() >= 0) {
-
from = tree->get_current();
sel = from;
@@ -392,15 +384,16 @@ void SpriteFramesEditor::_empty2_pressed() {
}
void SpriteFramesEditor::_up_pressed() {
-
ERR_FAIL_COND(!frames->has_animation(edited_anim));
- if (tree->get_current() < 0)
+ if (tree->get_current() < 0) {
return;
+ }
int to_move = tree->get_current();
- if (to_move < 1)
+ if (to_move < 1) {
return;
+ }
sel = to_move;
sel -= 1;
@@ -416,15 +409,16 @@ void SpriteFramesEditor::_up_pressed() {
}
void SpriteFramesEditor::_down_pressed() {
-
ERR_FAIL_COND(!frames->has_animation(edited_anim));
- if (tree->get_current() < 0)
+ if (tree->get_current() < 0) {
return;
+ }
int to_move = tree->get_current();
- if (to_move < 0 || to_move >= frames->get_frame_count(edited_anim) - 1)
+ if (to_move < 0 || to_move >= frames->get_frame_count(edited_anim) - 1) {
return;
+ }
sel = to_move;
sel += 1;
@@ -440,11 +434,11 @@ void SpriteFramesEditor::_down_pressed() {
}
void SpriteFramesEditor::_delete_pressed() {
-
ERR_FAIL_COND(!frames->has_animation(edited_anim));
- if (tree->get_current() < 0)
+ if (tree->get_current() < 0) {
return;
+ }
int to_delete = tree->get_current();
if (to_delete < 0 || to_delete >= frames->get_frame_count(edited_anim)) {
@@ -460,14 +454,15 @@ void SpriteFramesEditor::_delete_pressed() {
}
void SpriteFramesEditor::_animation_select() {
-
- if (updating)
+ if (updating) {
return;
+ }
if (frames->has_animation(edited_anim)) {
double value = anim_speed->get_line_edit()->get_text().to_double();
- if (!Math::is_equal_approx(value, frames->get_animation_speed(edited_anim)))
+ if (!Math::is_equal_approx(value, frames->get_animation_speed(edited_anim))) {
_animation_fps_changed(value);
+ }
}
TreeItem *selected = animations->get_selected();
@@ -477,12 +472,13 @@ void SpriteFramesEditor::_animation_select() {
}
static void _find_anim_sprites(Node *p_node, List<Node *> *r_nodes, Ref<SpriteFrames> p_sfames) {
-
Node *edited = EditorNode::get_singleton()->get_edited_scene();
- if (!edited)
+ if (!edited) {
return;
- if (p_node != edited && p_node->get_owner() != edited)
+ }
+ if (p_node != edited && p_node->get_owner() != edited) {
return;
+ }
{
AnimatedSprite2D *as = Object::cast_to<AnimatedSprite2D>(p_node);
@@ -504,21 +500,24 @@ static void _find_anim_sprites(Node *p_node, List<Node *> *r_nodes, Ref<SpriteFr
}
void SpriteFramesEditor::_animation_name_edited() {
-
- if (updating)
+ if (updating) {
return;
+ }
- if (!frames->has_animation(edited_anim))
+ if (!frames->has_animation(edited_anim)) {
return;
+ }
TreeItem *edited = animations->get_edited();
- if (!edited)
+ if (!edited) {
return;
+ }
String new_name = edited->get_text(0);
- if (new_name == String(edited_anim))
+ if (new_name == String(edited_anim)) {
return;
+ }
new_name = new_name.replace("/", "_").replace(",", " ");
@@ -537,7 +536,6 @@ void SpriteFramesEditor::_animation_name_edited() {
undo_redo->add_undo_method(frames, "rename_animation", name, edited_anim);
for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) {
-
String current = E->get()->call("get_animation");
undo_redo->add_do_method(E->get(), "set_animation", name);
undo_redo->add_undo_method(E->get(), "set_animation", edited_anim);
@@ -552,7 +550,6 @@ void SpriteFramesEditor::_animation_name_edited() {
}
void SpriteFramesEditor::_animation_add() {
-
String name = "New Anim";
int counter = 0;
while (frames->has_animation(name)) {
@@ -570,7 +567,6 @@ void SpriteFramesEditor::_animation_add() {
undo_redo->add_undo_method(this, "_update_library");
for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) {
-
String current = E->get()->call("get_animation");
undo_redo->add_do_method(E->get(), "set_animation", name);
undo_redo->add_undo_method(E->get(), "set_animation", current);
@@ -583,19 +579,19 @@ void SpriteFramesEditor::_animation_add() {
}
void SpriteFramesEditor::_animation_remove() {
-
- if (updating)
+ if (updating) {
return;
+ }
- if (!frames->has_animation(edited_anim))
+ if (!frames->has_animation(edited_anim)) {
return;
+ }
delete_dialog->set_text(TTR("Delete Animation?"));
delete_dialog->popup_centered();
}
void SpriteFramesEditor::_animation_remove_confirmed() {
-
undo_redo->create_action(TTR("Remove Animation"));
undo_redo->add_do_method(frames, "remove_animation", edited_anim);
undo_redo->add_undo_method(frames, "add_animation", edited_anim);
@@ -615,9 +611,9 @@ void SpriteFramesEditor::_animation_remove_confirmed() {
}
void SpriteFramesEditor::_animation_loop_changed() {
-
- if (updating)
+ if (updating) {
return;
+ }
undo_redo->create_action(TTR("Change Animation Loop"));
undo_redo->add_do_method(frames, "set_animation_loop", edited_anim, anim_loop->is_pressed());
@@ -628,9 +624,9 @@ void SpriteFramesEditor::_animation_loop_changed() {
}
void SpriteFramesEditor::_animation_fps_changed(double p_value) {
-
- if (updating)
+ if (updating) {
return;
+ }
undo_redo->create_action(TTR("Change Animation FPS"), UndoRedo::MERGE_ENDS);
undo_redo->add_do_method(frames, "set_animation_speed", edited_anim, p_value);
@@ -642,7 +638,6 @@ void SpriteFramesEditor::_animation_fps_changed(double p_value) {
}
void SpriteFramesEditor::_update_library(bool p_skip_selector) {
-
updating = true;
if (!p_skip_selector) {
@@ -657,7 +652,6 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
anim_names.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *E = anim_names.front(); E; E = E->next()) {
-
String name = E->get();
TreeItem *it = animations->create_item(anim_root);
@@ -680,18 +674,17 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
return;
}
- if (sel >= frames->get_frame_count(edited_anim))
+ if (sel >= frames->get_frame_count(edited_anim)) {
sel = frames->get_frame_count(edited_anim) - 1;
- else if (sel < 0 && frames->get_frame_count(edited_anim))
+ } else if (sel < 0 && frames->get_frame_count(edited_anim)) {
sel = 0;
+ }
for (int i = 0; i < frames->get_frame_count(edited_anim); i++) {
-
String name;
Ref<Texture2D> icon;
if (frames->get_frame(edited_anim, i).is_null()) {
-
name = itos(i) + ": " + TTR("(empty)");
} else {
@@ -700,10 +693,12 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
}
tree->add_item(name, icon);
- if (frames->get_frame(edited_anim, i).is_valid())
+ if (frames->get_frame(edited_anim, i).is_valid()) {
tree->set_item_tooltip(tree->get_item_count() - 1, frames->get_frame(edited_anim, i)->get_path());
- if (sel == i)
+ }
+ if (sel == i) {
tree->select(tree->get_item_count() - 1);
+ }
}
anim_speed->set_value(frames->get_animation_speed(edited_anim));
@@ -714,16 +709,14 @@ void SpriteFramesEditor::_update_library(bool p_skip_selector) {
}
void SpriteFramesEditor::edit(SpriteFrames *p_frames) {
-
- if (frames == p_frames)
+ if (frames == p_frames) {
return;
+ }
frames = p_frames;
if (p_frames) {
-
if (!p_frames->has_animation(edited_anim)) {
-
List<StringName> anim_names;
frames->get_animation_list(&anim_names);
anim_names.sort_custom<StringName::AlphCompare>();
@@ -736,25 +729,26 @@ void SpriteFramesEditor::edit(SpriteFrames *p_frames) {
_update_library();
} else {
-
hide();
}
}
Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
- if (!frames->has_animation(edited_anim))
+ if (!frames->has_animation(edited_anim)) {
return false;
+ }
int idx = tree->get_item_at_position(p_point, true);
- if (idx < 0 || idx >= frames->get_frame_count(edited_anim))
+ if (idx < 0 || idx >= frames->get_frame_count(edited_anim)) {
return Variant();
+ }
RES frame = frames->get_frame(edited_anim, idx);
- if (frame.is_null())
+ if (frame.is_null()) {
return Variant();
+ }
Dictionary drag_data = EditorNode::get_singleton()->drag_resource(frame, p_from);
drag_data["frame"] = idx; // store the frame, in case we want to reorder frames inside 'drop_data_fw'
@@ -762,15 +756,16 @@ Variant SpriteFramesEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f
}
bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return false;
+ }
// reordering frames
- if (d.has("from") && (Object *)(d["from"]) == tree)
+ if (d.has("from") && (Object *)(d["from"]) == tree) {
return true;
+ }
if (String(d["type"]) == "resource" && d.has("resource")) {
RES r = d["resource"];
@@ -778,17 +773,16 @@ bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
Ref<Texture2D> texture = r;
if (texture.is_valid()) {
-
return true;
}
}
if (String(d["type"]) == "files") {
-
Vector<String> files = d["files"];
- if (files.size() == 0)
+ if (files.size() == 0) {
return false;
+ }
for (int i = 0; i < files.size(); i++) {
String file = files[i];
@@ -805,14 +799,15 @@ bool SpriteFramesEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
}
void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
-
- if (!can_drop_data_fw(p_point, p_data, p_from))
+ if (!can_drop_data_fw(p_point, p_data, p_from)) {
return;
+ }
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return;
+ }
int at_pos = tree->get_item_at_position(p_point, true);
@@ -823,13 +818,15 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
if (texture.is_valid()) {
bool reorder = false;
- if (d.has("from") && (Object *)(d["from"]) == tree)
+ if (d.has("from") && (Object *)(d["from"]) == tree) {
reorder = true;
+ }
if (reorder) { //drop is from reordering frames
int from_frame = -1;
- if (d.has("frame"))
+ if (d.has("frame")) {
from_frame = d["frame"];
+ }
undo_redo->create_action(TTR("Move Frame"));
undo_redo->add_do_method(frames, "remove_frame", edited_anim, from_frame == -1 ? frames->get_frame_count(edited_anim) : from_frame);
@@ -851,7 +848,6 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
if (String(d["type"]) == "files") {
-
Vector<String> files = d["files"];
_file_load_request(files, at_pos);
@@ -859,7 +855,6 @@ void SpriteFramesEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
void SpriteFramesEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_update_library", "skipsel"), &SpriteFramesEditor::_update_library, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_drag_data_fw"), &SpriteFramesEditor::get_drag_data_fw);
ClassDB::bind_method(D_METHOD("can_drop_data_fw"), &SpriteFramesEditor::can_drop_data_fw);
@@ -867,7 +862,6 @@ void SpriteFramesEditor::_bind_methods() {
}
SpriteFramesEditor::SpriteFramesEditor() {
-
VBoxContainer *vbc_animlist = memnew(VBoxContainer);
add_child(vbc_animlist);
vbc_animlist->set_custom_minimum_size(Size2(150, 0) * EDSCALE);
@@ -1064,7 +1058,6 @@ SpriteFramesEditor::SpriteFramesEditor() {
}
void SpriteFramesEditorPlugin::edit(Object *p_object) {
-
frames_editor->set_undo_redo(&get_undo_redo());
SpriteFrames *s;
@@ -1076,7 +1069,6 @@ void SpriteFramesEditorPlugin::edit(Object *p_object) {
if (animated_sprite_3d) {
s = *animated_sprite_3d->get_sprite_frames();
} else {
-
s = Object::cast_to<SpriteFrames>(p_object);
}
}
@@ -1085,7 +1077,6 @@ void SpriteFramesEditorPlugin::edit(Object *p_object) {
}
bool SpriteFramesEditorPlugin::handles(Object *p_object) const {
-
AnimatedSprite2D *animated_sprite = Object::cast_to<AnimatedSprite2D>(p_object);
AnimatedSprite3D *animated_sprite_3d = Object::cast_to<AnimatedSprite3D>(p_object);
if (animated_sprite && *animated_sprite->get_sprite_frames()) {
@@ -1098,20 +1089,18 @@ bool SpriteFramesEditorPlugin::handles(Object *p_object) const {
}
void SpriteFramesEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
button->show();
editor->make_bottom_panel_item_visible(frames_editor);
} else {
-
button->hide();
- if (frames_editor->is_visible_in_tree())
+ if (frames_editor->is_visible_in_tree()) {
editor->hide_bottom_panel();
+ }
}
}
SpriteFramesEditorPlugin::SpriteFramesEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
frames_editor = memnew(SpriteFramesEditor);
frames_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h
index 89d9bc6fd3..45646eb9e4 100644
--- a/editor/plugins/sprite_frames_editor_plugin.h
+++ b/editor/plugins/sprite_frames_editor_plugin.h
@@ -41,7 +41,6 @@
#include "scene/gui/tree.h"
class SpriteFramesEditor : public HSplitContainer {
-
GDCLASS(SpriteFramesEditor, HSplitContainer);
ToolButton *load;
@@ -134,7 +133,6 @@ public:
};
class SpriteFramesEditorPlugin : public EditorPlugin {
-
GDCLASS(SpriteFramesEditorPlugin, EditorPlugin);
SpriteFramesEditor *frames_editor;
diff --git a/editor/plugins/style_box_editor_plugin.cpp b/editor/plugins/style_box_editor_plugin.cpp
index eb6e261305..3641052a4e 100644
--- a/editor/plugins/style_box_editor_plugin.cpp
+++ b/editor/plugins/style_box_editor_plugin.cpp
@@ -33,28 +33,28 @@
#include "editor/editor_scale.h"
bool EditorInspectorPluginStyleBox::can_handle(Object *p_object) {
-
return Object::cast_to<StyleBox>(p_object) != nullptr;
}
void EditorInspectorPluginStyleBox::parse_begin(Object *p_object) {
-
Ref<StyleBox> sb = Ref<StyleBox>(Object::cast_to<StyleBox>(p_object));
StyleBoxPreview *preview = memnew(StyleBoxPreview);
preview->edit(sb);
add_custom_control(preview);
}
+
bool EditorInspectorPluginStyleBox::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
return false; //do not want
}
+
void EditorInspectorPluginStyleBox::parse_end() {
}
void StyleBoxPreview::edit(const Ref<StyleBox> &p_stylebox) {
-
- if (stylebox.is_valid())
+ if (stylebox.is_valid()) {
stylebox->disconnect("changed", callable_mp(this, &StyleBoxPreview::_sb_changed));
+ }
stylebox = p_stylebox;
if (p_stylebox.is_valid()) {
preview->add_theme_style_override("panel", stylebox);
@@ -64,7 +64,6 @@ void StyleBoxPreview::edit(const Ref<StyleBox> &p_stylebox) {
}
void StyleBoxPreview::_sb_changed() {
-
preview->update();
}
@@ -93,7 +92,6 @@ StyleBoxPreview::StyleBoxPreview() {
}
StyleBoxEditorPlugin::StyleBoxEditorPlugin(EditorNode *p_node) {
-
Ref<EditorInspectorPluginStyleBox> inspector_plugin;
inspector_plugin.instance();
add_inspector_plugin(inspector_plugin);
diff --git a/editor/plugins/style_box_editor_plugin.h b/editor/plugins/style_box_editor_plugin.h
index 1eea9260b2..d9958d42e6 100644
--- a/editor/plugins/style_box_editor_plugin.h
+++ b/editor/plugins/style_box_editor_plugin.h
@@ -38,7 +38,6 @@
#include "scene/resources/style_box.h"
class StyleBoxPreview : public VBoxContainer {
-
GDCLASS(StyleBoxPreview, VBoxContainer);
Control *preview;
@@ -67,7 +66,6 @@ public:
};
class StyleBoxEditorPlugin : public EditorPlugin {
-
GDCLASS(StyleBoxEditorPlugin, EditorPlugin);
public:
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index 2786a568ea..3ceb9bfd82 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -70,7 +70,6 @@ void TextEditor::_change_syntax_highlighter(int p_idx) {
}
void TextEditor::_load_theme_settings() {
-
TextEdit *text_edit = code_editor->get_text_edit();
text_edit->clear_colors();
@@ -164,7 +163,6 @@ String TextEditor::get_name() {
}
Ref<Texture2D> TextEditor::get_theme_icon() {
-
return EditorNode::get_singleton()->get_object_icon(text_file.operator->(), "");
}
@@ -195,7 +193,6 @@ void TextEditor::get_breakpoints(List<int> *p_breakpoints) {
}
void TextEditor::reload_text() {
-
ERR_FAIL_COND(text_file.is_null());
TextEdit *te = code_editor->get_text_edit();
@@ -221,7 +218,6 @@ void TextEditor::_validate_script() {
}
void TextEditor::_update_bookmark_list() {
-
bookmarks_menu->clear();
bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE);
@@ -249,7 +245,6 @@ void TextEditor::_update_bookmark_list() {
}
void TextEditor::_bookmark_item_pressed(int p_idx) {
-
if (p_idx < 4) { // Any item before the separator.
_edit_option(bookmarks_menu->get_item_id(p_idx));
} else {
@@ -262,17 +257,14 @@ void TextEditor::apply_code() {
}
bool TextEditor::is_unsaved() {
-
return code_editor->get_text_edit()->get_version() != code_editor->get_text_edit()->get_saved_version();
}
Variant TextEditor::get_edit_state() {
-
return code_editor->get_edit_state();
}
void TextEditor::set_edit_state(const Variant &p_state) {
-
code_editor->set_edit_state(p_state);
Dictionary state = p_state;
@@ -285,42 +277,34 @@ void TextEditor::set_edit_state(const Variant &p_state) {
}
void TextEditor::trim_trailing_whitespace() {
-
code_editor->trim_trailing_whitespace();
}
void TextEditor::insert_final_newline() {
-
code_editor->insert_final_newline();
}
void TextEditor::convert_indent_to_spaces() {
-
code_editor->convert_indent_to_spaces();
}
void TextEditor::convert_indent_to_tabs() {
-
code_editor->convert_indent_to_tabs();
}
void TextEditor::tag_saved_version() {
-
code_editor->get_text_edit()->tag_saved_version();
}
void TextEditor::goto_line(int p_line, bool p_with_error) {
-
code_editor->goto_line(p_line);
}
void TextEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
-
code_editor->goto_line_selection(p_line, p_begin, p_end);
}
void TextEditor::set_executing_line(int p_line) {
-
code_editor->set_executing_line(p_line);
}
@@ -329,12 +313,10 @@ void TextEditor::clear_executing_line() {
}
void TextEditor::ensure_focus() {
-
code_editor->get_text_edit()->grab_focus();
}
Vector<String> TextEditor::get_functions() {
-
return Vector<String>();
}
@@ -343,17 +325,14 @@ bool TextEditor::show_members_overview() {
}
void TextEditor::update_settings() {
-
code_editor->update_editor_settings();
}
void TextEditor::set_tooltip_request_func(String p_method, Object *p_obj) {
-
code_editor->get_text_edit()->set_tooltip_request_func(p_obj, p_method, this);
}
Control *TextEditor::get_edit_menu() {
-
return edit_hb;
}
@@ -362,7 +341,6 @@ void TextEditor::clear_edit_menu() {
}
void TextEditor::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_READY:
_load_theme_settings();
@@ -375,116 +353,90 @@ void TextEditor::_edit_option(int p_op) {
switch (p_op) {
case EDIT_UNDO: {
-
tx->undo();
tx->call_deferred("grab_focus");
} break;
case EDIT_REDO: {
-
tx->redo();
tx->call_deferred("grab_focus");
} break;
case EDIT_CUT: {
-
tx->cut();
tx->call_deferred("grab_focus");
} break;
case EDIT_COPY: {
-
tx->copy();
tx->call_deferred("grab_focus");
} break;
case EDIT_PASTE: {
-
tx->paste();
tx->call_deferred("grab_focus");
} break;
case EDIT_SELECT_ALL: {
-
tx->select_all();
tx->call_deferred("grab_focus");
} break;
case EDIT_MOVE_LINE_UP: {
-
code_editor->move_lines_up();
} break;
case EDIT_MOVE_LINE_DOWN: {
-
code_editor->move_lines_down();
} break;
case EDIT_INDENT_LEFT: {
-
tx->indent_left();
} break;
case EDIT_INDENT_RIGHT: {
-
tx->indent_right();
} break;
case EDIT_DELETE_LINE: {
-
code_editor->delete_lines();
} break;
case EDIT_CLONE_DOWN: {
-
code_editor->clone_lines_down();
} break;
case EDIT_TOGGLE_FOLD_LINE: {
-
tx->toggle_fold_line(tx->cursor_get_line());
tx->update();
} break;
case EDIT_FOLD_ALL_LINES: {
-
tx->fold_all_lines();
tx->update();
} break;
case EDIT_UNFOLD_ALL_LINES: {
-
tx->unhide_all_lines();
tx->update();
} break;
case EDIT_TRIM_TRAILING_WHITESAPCE: {
-
trim_trailing_whitespace();
} break;
case EDIT_CONVERT_INDENT_TO_SPACES: {
-
convert_indent_to_spaces();
} break;
case EDIT_CONVERT_INDENT_TO_TABS: {
-
convert_indent_to_tabs();
} break;
case EDIT_TO_UPPERCASE: {
-
_convert_case(CodeTextEditor::UPPER);
} break;
case EDIT_TO_LOWERCASE: {
-
_convert_case(CodeTextEditor::LOWER);
} break;
case EDIT_CAPITALIZE: {
-
_convert_case(CodeTextEditor::CAPITALIZE);
} break;
case SEARCH_FIND: {
-
code_editor->get_find_replace_bar()->popup_search();
} break;
case SEARCH_FIND_NEXT: {
-
code_editor->get_find_replace_bar()->search_next();
} break;
case SEARCH_FIND_PREV: {
-
code_editor->get_find_replace_bar()->search_prev();
} break;
case SEARCH_REPLACE: {
-
code_editor->get_find_replace_bar()->popup_replace();
} break;
case SEARCH_IN_FILES: {
-
String selected_text = code_editor->get_text_edit()->get_selection_text();
// Yep, because it doesn't make sense to instance this dialog for every single script open...
@@ -492,36 +444,29 @@ void TextEditor::_edit_option(int p_op) {
emit_signal("search_in_files_requested", selected_text);
} break;
case REPLACE_IN_FILES: {
-
String selected_text = code_editor->get_text_edit()->get_selection_text();
emit_signal("replace_in_files_requested", selected_text);
} break;
case SEARCH_GOTO_LINE: {
-
goto_line_dialog->popup_find_line(tx);
} break;
case BOOKMARK_TOGGLE: {
-
code_editor->toggle_bookmark();
} break;
case BOOKMARK_GOTO_NEXT: {
-
code_editor->goto_next_bookmark();
} break;
case BOOKMARK_GOTO_PREV: {
-
code_editor->goto_prev_bookmark();
} break;
case BOOKMARK_REMOVE_ALL: {
-
code_editor->remove_all_bookmarks();
} break;
}
}
void TextEditor::_convert_case(CodeTextEditor::CaseStyle p_case) {
-
code_editor->convert_case(p_case);
}
@@ -529,7 +474,6 @@ void TextEditor::_bind_methods() {
}
static ScriptEditorBase *create_editor(const RES &p_resource) {
-
if (Object::cast_to<TextFile>(*p_resource)) {
return memnew(TextEditor);
}
@@ -537,17 +481,14 @@ static ScriptEditorBase *create_editor(const RES &p_resource) {
}
void TextEditor::register_editor() {
-
ScriptEditor::register_create_script_editor_function(create_editor);
}
void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
-
Ref<InputEventMouseButton> mb = ev;
if (mb.is_valid()) {
if (mb->get_button_index() == BUTTON_RIGHT) {
-
int col, row;
TextEdit *tx = code_editor->get_text_edit();
tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
@@ -558,7 +499,6 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
if (tx->is_right_click_moving_caret()) {
if (tx->is_selection_active()) {
-
int from_line = tx->get_selection_from_line();
int to_line = tx->get_selection_to_line();
int from_column = tx->get_selection_from_column();
@@ -591,7 +531,6 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
}
void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is_folded, Vector2 p_position) {
-
context_menu->clear();
if (p_selection) {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/cut"), EDIT_CUT);
@@ -613,8 +552,9 @@ void TextEditor::_make_context_menu(bool p_selection, bool p_can_fold, bool p_is
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_uppercase"), EDIT_TO_UPPERCASE);
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/convert_to_lowercase"), EDIT_TO_LOWERCASE);
}
- if (p_can_fold || p_is_folded)
+ if (p_can_fold || p_is_folded) {
context_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_fold_line"), EDIT_TOGGLE_FOLD_LINE);
+ }
context_menu->set_position(get_global_transform().xform(p_position));
context_menu->set_size(Vector2(1, 1));
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index b41e11c3aa..9d9025a2c4 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -34,7 +34,6 @@
#include "script_editor_plugin.h"
class TextEditor : public ScriptEditorBase {
-
GDCLASS(TextEditor, ScriptEditorBase);
private:
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index c1184c1c89..b728a6700c 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -38,14 +38,11 @@ void TextureEditor::_gui_input(Ref<InputEvent> p_event) {
}
void TextureEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_READY) {
-
//get_scene()->connect("node_removed",this,"_node_removed");
}
if (p_what == NOTIFICATION_DRAW) {
-
Ref<Texture2D> checkerboard = get_theme_icon("Checkerboard", "EditorIcons");
Size2 size = get_size();
@@ -60,10 +57,12 @@ void TextureEditor::_notification(int p_what) {
}
// Prevent the texture from being unpreviewable after the rescale, so that we can still see something
- if (tex_height <= 0)
+ if (tex_height <= 0) {
tex_height = 1;
- if (tex_width <= 0)
+ }
+ if (tex_width <= 0) {
tex_width = 1;
+ }
int ofs_x = (size.width - tex_width) / 2;
int ofs_y = (size.height - tex_height) / 2;
@@ -84,8 +83,8 @@ void TextureEditor::_notification(int p_what) {
String format;
if (Object::cast_to<ImageTexture>(*texture)) {
format = Image::get_format_name(Object::cast_to<ImageTexture>(*texture)->get_format());
- } else if (Object::cast_to<StreamTexture>(*texture)) {
- format = Image::get_format_name(Object::cast_to<StreamTexture>(*texture)->get_format());
+ } else if (Object::cast_to<StreamTexture2D>(*texture)) {
+ format = Image::get_format_name(Object::cast_to<StreamTexture2D>(*texture)->get_format());
} else {
format = texture->get_class();
}
@@ -94,8 +93,9 @@ void TextureEditor::_notification(int p_what) {
Size2 rect = font->get_string_size(text);
Vector2 draw_from = size - rect + Size2(-2, font->get_ascent() - 2);
- if (draw_from.x < 0)
+ if (draw_from.x < 0) {
draw_from.x = 0;
+ }
draw_string(font, draw_from + Vector2(2, 2), text, Color(0, 0, 0, 0.5), size.width);
draw_string(font, draw_from - Vector2(2, 2), text, Color(0, 0, 0, 0.5), size.width);
@@ -104,16 +104,16 @@ void TextureEditor::_notification(int p_what) {
}
void TextureEditor::_changed_callback(Object *p_changed, const char *p_prop) {
-
- if (!is_visible())
+ if (!is_visible()) {
return;
+ }
update();
}
void TextureEditor::edit(Ref<Texture2D> p_texture) {
-
- if (!texture.is_null())
+ if (!texture.is_null()) {
texture->remove_change_receptor(this);
+ }
texture = p_texture;
@@ -126,12 +126,10 @@ void TextureEditor::edit(Ref<Texture2D> p_texture) {
}
void TextureEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &TextureEditor::_gui_input);
}
TextureEditor::TextureEditor() {
-
set_texture_repeat(TextureRepeat::TEXTURE_REPEAT_ENABLED);
set_custom_minimum_size(Size2(1, 150));
}
@@ -141,14 +139,13 @@ TextureEditor::~TextureEditor() {
texture->remove_change_receptor(this);
}
}
+
//
bool EditorInspectorPluginTexture::can_handle(Object *p_object) {
-
- return Object::cast_to<ImageTexture>(p_object) != nullptr || Object::cast_to<AtlasTexture>(p_object) != nullptr || Object::cast_to<StreamTexture>(p_object) != nullptr || Object::cast_to<LargeTexture>(p_object) != nullptr || Object::cast_to<AnimatedTexture>(p_object) != nullptr;
+ return Object::cast_to<ImageTexture>(p_object) != nullptr || Object::cast_to<AtlasTexture>(p_object) != nullptr || Object::cast_to<StreamTexture2D>(p_object) != nullptr || Object::cast_to<LargeTexture>(p_object) != nullptr || Object::cast_to<AnimatedTexture>(p_object) != nullptr;
}
void EditorInspectorPluginTexture::parse_begin(Object *p_object) {
-
Texture2D *texture = Object::cast_to<Texture2D>(p_object);
if (!texture) {
return;
@@ -161,7 +158,6 @@ void EditorInspectorPluginTexture::parse_begin(Object *p_object) {
}
TextureEditorPlugin::TextureEditorPlugin(EditorNode *p_node) {
-
Ref<EditorInspectorPluginTexture> plugin;
plugin.instance();
add_inspector_plugin(plugin);
diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h
index 29ad0183dc..63eea2b767 100644
--- a/editor/plugins/texture_editor_plugin.h
+++ b/editor/plugins/texture_editor_plugin.h
@@ -36,7 +36,6 @@
#include "scene/resources/texture.h"
class TextureEditor : public Control {
-
GDCLASS(TextureEditor, Control);
Ref<Texture2D> texture;
@@ -62,7 +61,6 @@ public:
};
class TextureEditorPlugin : public EditorPlugin {
-
GDCLASS(TextureEditorPlugin, EditorPlugin);
public:
diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp
new file mode 100644
index 0000000000..59e87fb273
--- /dev/null
+++ b/editor/plugins/texture_layered_editor_plugin.cpp
@@ -0,0 +1,278 @@
+/*************************************************************************/
+/* texture_layered_editor_plugin.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "texture_layered_editor_plugin.h"
+
+#include "core/io/resource_loader.h"
+#include "core/project_settings.h"
+#include "editor/editor_settings.h"
+
+void TextureLayeredEditor::_gui_input(Ref<InputEvent> p_event) {
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
+ y_rot += -mm->get_relative().x * 0.01;
+ x_rot += mm->get_relative().y * 0.01;
+ _update_material();
+ }
+}
+
+void TextureLayeredEditor::_texture_rect_draw() {
+ texture_rect->draw_rect(Rect2(Point2(), texture_rect->get_size()), Color(1, 1, 1, 1));
+}
+
+void TextureLayeredEditor::_notification(int p_what) {
+ if (p_what == NOTIFICATION_READY) {
+ //get_scene()->connect("node_removed",this,"_node_removed");
+ }
+ if (p_what == NOTIFICATION_RESIZED) {
+ _texture_rect_update_area();
+ }
+
+ if (p_what == NOTIFICATION_DRAW) {
+ Ref<Texture2D> checkerboard = get_theme_icon("Checkerboard", "EditorIcons");
+ Size2 size = get_size();
+
+ draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
+ }
+}
+
+void TextureLayeredEditor::_changed_callback(Object *p_changed, const char *p_prop) {
+ if (!is_visible()) {
+ return;
+ }
+ update();
+}
+
+void TextureLayeredEditor::_update_material() {
+ materials[0]->set_shader_param("layer", layer->get_value());
+ materials[2]->set_shader_param("layer", layer->get_value());
+ materials[texture->get_layered_type()]->set_shader_param("tex", texture->get_rid());
+
+ Vector3 v(1, 1, 1);
+ v.normalize();
+
+ Basis b;
+ b.rotate(Vector3(1, 0, 0), x_rot);
+ b.rotate(Vector3(0, 1, 0), y_rot);
+
+ materials[1]->set_shader_param("normal", v);
+ materials[1]->set_shader_param("rot", b);
+ materials[2]->set_shader_param("normal", v);
+ materials[2]->set_shader_param("rot", b);
+
+ String format = Image::get_format_name(texture->get_format());
+
+ String text;
+ if (texture->get_layered_type() == TextureLayered::LAYERED_TYPE_2D_ARRAY) {
+ text = itos(texture->get_width()) + "x" + itos(texture->get_height()) + " (x " + itos(texture->get_layers()) + ")" + format;
+ } else if (texture->get_layered_type() == TextureLayered::LAYERED_TYPE_CUBEMAP) {
+ text = itos(texture->get_width()) + "x" + itos(texture->get_height()) + " " + format;
+ } else if (texture->get_layered_type() == TextureLayered::LAYERED_TYPE_CUBEMAP_ARRAY) {
+ text = itos(texture->get_width()) + "x" + itos(texture->get_height()) + " (x " + itos(texture->get_layers() / 6) + ")" + format;
+ }
+
+ info->set_text(text);
+}
+
+void TextureLayeredEditor::_make_shaders() {
+ String shader_2d_array = ""
+ "shader_type canvas_item;\n"
+ "uniform sampler2DArray tex;\n"
+ "uniform float layer;\n"
+ "void fragment() {\n"
+ " COLOR = textureLod(tex,vec3(UV,layer),0.0);\n"
+ "}";
+
+ shaders[0].instance();
+ shaders[0]->set_code(shader_2d_array);
+
+ String shader_cube = ""
+ "shader_type canvas_item;\n"
+ "uniform samplerCube tex;\n"
+ "uniform vec3 normal;\n"
+ "uniform mat3 rot;\n"
+ "void fragment() {\n"
+ " vec3 n = rot * normalize(vec3(normal.xy*(UV * 2.0 - 1.0),normal.z));\n"
+ " COLOR = textureLod(tex,n,0.0);\n"
+ "}";
+
+ shaders[1].instance();
+ shaders[1]->set_code(shader_cube);
+
+ String shader_cube_array = ""
+ "shader_type canvas_item;\n"
+ "uniform samplerCubeArray tex;\n"
+ "uniform vec3 normal;\n"
+ "uniform mat3 rot;\n"
+ "uniform float layer;\n"
+ "void fragment() {\n"
+ " vec3 n = rot * normalize(vec3(normal.xy*(UV * 2.0 - 1.0),normal.z));\n"
+ " COLOR = textureLod(tex,vec4(n,layer),0.0);\n"
+ "}";
+
+ shaders[2].instance();
+ shaders[2]->set_code(shader_cube_array);
+
+ for (int i = 0; i < 3; i++) {
+ materials[i].instance();
+ materials[i]->set_shader(shaders[i]);
+ }
+}
+
+void TextureLayeredEditor::_texture_rect_update_area() {
+ Size2 size = get_size();
+ int tex_width = texture->get_width() * size.height / texture->get_height();
+ int tex_height = size.height;
+
+ if (tex_width > size.width) {
+ tex_width = size.width;
+ tex_height = texture->get_height() * tex_width / texture->get_width();
+ }
+
+ // Prevent the texture from being unpreviewable after the rescale, so that we can still see something
+ if (tex_height <= 0) {
+ tex_height = 1;
+ }
+ if (tex_width <= 0) {
+ tex_width = 1;
+ }
+
+ int ofs_x = (size.width - tex_width) / 2;
+ int ofs_y = (size.height - tex_height) / 2;
+
+ texture_rect->set_position(Vector2(ofs_x, ofs_y));
+ texture_rect->set_size(Vector2(tex_width, tex_height));
+}
+
+void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) {
+ if (!texture.is_null()) {
+ texture->remove_change_receptor(this);
+ }
+
+ texture = p_texture;
+
+ if (!texture.is_null()) {
+ if (shaders[0].is_null()) {
+ _make_shaders();
+ }
+
+ texture->add_change_receptor(this);
+ update();
+ texture_rect->set_material(materials[texture->get_layered_type()]);
+ setting = true;
+ if (texture->get_layered_type() == TextureLayered::LAYERED_TYPE_2D_ARRAY) {
+ layer->set_max(texture->get_layers() - 1);
+ layer->set_value(0);
+ layer->show();
+ } else if (texture->get_layered_type() == TextureLayered::LAYERED_TYPE_CUBEMAP_ARRAY) {
+ layer->set_max(texture->get_layers() / 6 - 1);
+ layer->set_value(0);
+ layer->show();
+ } else {
+ layer->hide();
+ }
+ x_rot = 0;
+ y_rot = 0;
+ _update_material();
+ setting = false;
+ _texture_rect_update_area();
+ } else {
+ hide();
+ }
+}
+
+void TextureLayeredEditor::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_gui_input"), &TextureLayeredEditor::_gui_input);
+ ClassDB::bind_method(D_METHOD("_layer_changed"), &TextureLayeredEditor::_layer_changed);
+}
+
+TextureLayeredEditor::TextureLayeredEditor() {
+ set_texture_repeat(TextureRepeat::TEXTURE_REPEAT_ENABLED);
+ set_custom_minimum_size(Size2(1, 150));
+ texture_rect = memnew(Control);
+ texture_rect->connect("draw", callable_mp(this, &TextureLayeredEditor::_texture_rect_draw));
+ texture_rect->set_mouse_filter(MOUSE_FILTER_IGNORE);
+ add_child(texture_rect);
+
+ layer = memnew(SpinBox);
+ layer->set_step(1);
+ layer->set_max(100);
+ add_child(layer);
+ layer->set_anchor(MARGIN_RIGHT, 1);
+ layer->set_anchor(MARGIN_LEFT, 1);
+ layer->set_h_grow_direction(GROW_DIRECTION_BEGIN);
+ layer->set_modulate(Color(1, 1, 1, 0.8));
+ info = memnew(Label);
+ add_child(info);
+ info->set_anchor(MARGIN_RIGHT, 1);
+ info->set_anchor(MARGIN_LEFT, 1);
+ info->set_anchor(MARGIN_BOTTOM, 1);
+ info->set_anchor(MARGIN_TOP, 1);
+ info->set_h_grow_direction(GROW_DIRECTION_BEGIN);
+ info->set_v_grow_direction(GROW_DIRECTION_BEGIN);
+ info->add_theme_color_override("font_color", Color(1, 1, 1, 1));
+ info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5));
+ info->add_theme_color_override("font_color_shadow", Color(0, 0, 0, 0.5));
+ info->add_theme_constant_override("shadow_as_outline", 1);
+ info->add_theme_constant_override("shadow_offset_x", 2);
+ info->add_theme_constant_override("shadow_offset_y", 2);
+
+ setting = false;
+ layer->connect("value_changed", Callable(this, "_layer_changed"));
+}
+
+TextureLayeredEditor::~TextureLayeredEditor() {
+ if (!texture.is_null()) {
+ texture->remove_change_receptor(this);
+ }
+}
+
+//
+bool EditorInspectorPluginLayeredTexture::can_handle(Object *p_object) {
+ return Object::cast_to<TextureLayered>(p_object) != nullptr;
+}
+
+void EditorInspectorPluginLayeredTexture::parse_begin(Object *p_object) {
+ TextureLayered *texture = Object::cast_to<TextureLayered>(p_object);
+ if (!texture) {
+ return;
+ }
+ Ref<TextureLayered> m(texture);
+
+ TextureLayeredEditor *editor = memnew(TextureLayeredEditor);
+ editor->edit(m);
+ add_custom_control(editor);
+}
+
+TextureLayeredEditorPlugin::TextureLayeredEditorPlugin(EditorNode *p_node) {
+ Ref<EditorInspectorPluginLayeredTexture> plugin;
+ plugin.instance();
+ add_inspector_plugin(plugin);
+}
diff --git a/editor/plugins/texture_layered_editor_plugin.h b/editor/plugins/texture_layered_editor_plugin.h
new file mode 100644
index 0000000000..4c5e06a5b8
--- /dev/null
+++ b/editor/plugins/texture_layered_editor_plugin.h
@@ -0,0 +1,95 @@
+/*************************************************************************/
+/* texture_layered_editor_plugin.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEXTURE_LAYERED_EDITOR_PLUGIN_H
+#define TEXTURE_LAYERED_EDITOR_PLUGIN_H
+
+#include "editor/editor_node.h"
+#include "editor/editor_plugin.h"
+#include "scene/resources/shader.h"
+#include "scene/resources/texture.h"
+
+class TextureLayeredEditor : public Control {
+ GDCLASS(TextureLayeredEditor, Control);
+
+ SpinBox *layer;
+ Label *info;
+ Ref<TextureLayered> texture;
+
+ Ref<Shader> shaders[3];
+ Ref<ShaderMaterial> materials[3];
+
+ float x_rot = 0;
+ float y_rot = 0;
+ Control *texture_rect;
+
+ void _make_shaders();
+
+ void _update_material();
+ bool setting;
+ void _layer_changed(double) {
+ if (!setting) {
+ _update_material();
+ }
+ }
+
+ void _texture_rect_update_area();
+ void _texture_rect_draw();
+
+protected:
+ void _notification(int p_what);
+ void _gui_input(Ref<InputEvent> p_event);
+ void _changed_callback(Object *p_changed, const char *p_prop);
+ static void _bind_methods();
+
+public:
+ void edit(Ref<TextureLayered> p_texture);
+ TextureLayeredEditor();
+ ~TextureLayeredEditor();
+};
+
+class EditorInspectorPluginLayeredTexture : public EditorInspectorPlugin {
+ GDCLASS(EditorInspectorPluginLayeredTexture, EditorInspectorPlugin);
+
+public:
+ virtual bool can_handle(Object *p_object);
+ virtual void parse_begin(Object *p_object);
+};
+
+class TextureLayeredEditorPlugin : public EditorPlugin {
+ GDCLASS(TextureLayeredEditorPlugin, EditorPlugin);
+
+public:
+ virtual String get_name() const { return "TextureLayered"; }
+
+ TextureLayeredEditorPlugin(EditorNode *p_node);
+};
+
+#endif // TEXTURE_EDITOR_PLUGIN_H
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 8892d13f51..9b8b111be5 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -31,7 +31,7 @@
#include "texture_region_editor_plugin.h"
#include "core/core_string_names.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/keyboard.h"
#include "editor/editor_scale.h"
#include "scene/gui/check_box.h"
@@ -50,19 +50,21 @@ void draw_margin_line(Control *edit_draw, Vector2 from, Vector2 to) {
void TextureRegionEditor::_region_draw() {
Ref<Texture2D> base_tex = nullptr;
- if (node_sprite)
+ if (node_sprite) {
base_tex = node_sprite->get_texture();
- else if (node_sprite_3d)
+ } else if (node_sprite_3d) {
base_tex = node_sprite_3d->get_texture();
- else if (node_ninepatch)
+ } else if (node_ninepatch) {
base_tex = node_ninepatch->get_texture();
- else if (obj_styleBox.is_valid())
+ } else if (obj_styleBox.is_valid()) {
base_tex = obj_styleBox->get_texture();
- else if (atlas_tex.is_valid())
+ } else if (atlas_tex.is_valid()) {
base_tex = atlas_tex->get_atlas();
+ }
- if (base_tex.is_null())
+ if (base_tex.is_null()) {
return;
+ }
Transform2D mtx;
mtx.elements[2] = -draw_ofs * draw_zoom;
@@ -78,45 +80,55 @@ void TextureRegionEditor::_region_draw() {
int last_cell = 0;
if (snap_step.x != 0) {
- if (snap_separation.x == 0)
+ if (snap_separation.x == 0) {
for (int i = 0; i < s.width; i++) {
int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(i, 0)).x - snap_offset.x) / snap_step.x));
- if (i == 0)
+ if (i == 0) {
last_cell = cell;
- if (last_cell != cell)
+ }
+ if (last_cell != cell) {
edit_draw->draw_line(Point2(i, 0), Point2(i, s.height), grid_color);
+ }
last_cell = cell;
}
- else
+ } else {
for (int i = 0; i < s.width; i++) {
int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(i, 0)).x - snap_offset.x) / (snap_step.x + snap_separation.x)));
- if (i == 0)
+ if (i == 0) {
last_cell = cell;
- if (last_cell != cell)
+ }
+ if (last_cell != cell) {
edit_draw->draw_rect(Rect2(i - snap_separation.x * draw_zoom, 0, snap_separation.x * draw_zoom, s.height), grid_color);
+ }
last_cell = cell;
}
+ }
}
if (snap_step.y != 0) {
- if (snap_separation.y == 0)
+ if (snap_separation.y == 0) {
for (int i = 0; i < s.height; i++) {
int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(0, i)).y - snap_offset.y) / snap_step.y));
- if (i == 0)
+ if (i == 0) {
last_cell = cell;
- if (last_cell != cell)
+ }
+ if (last_cell != cell) {
edit_draw->draw_line(Point2(0, i), Point2(s.width, i), grid_color);
+ }
last_cell = cell;
}
- else
+ } else {
for (int i = 0; i < s.height; i++) {
int cell = Math::fast_ftoi(Math::floor((mtx.affine_inverse().xform(Vector2(0, i)).y - snap_offset.y) / (snap_step.y + snap_separation.y)));
- if (i == 0)
+ if (i == 0) {
last_cell = cell;
- if (last_cell != cell)
+ }
+ if (last_cell != cell) {
edit_draw->draw_rect(Rect2(0, i - snap_separation.y * draw_zoom, s.width, snap_separation.y * draw_zoom), grid_color);
+ }
last_cell = cell;
}
+ }
}
} else if (snap_mode == SNAP_AUTOSLICE) {
for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) {
@@ -152,7 +164,6 @@ void TextureRegionEditor::_region_draw() {
};
Color color = get_theme_color("mono_color", "Editor");
for (int i = 0; i < 4; i++) {
-
int prev = (i + 3) % 4;
int next = (i + 1) % 4;
@@ -161,14 +172,16 @@ void TextureRegionEditor::_region_draw() {
edit_draw->draw_line(endpoints[i] - draw_ofs * draw_zoom, endpoints[next] - draw_ofs * draw_zoom, color, 2);
- if (snap_mode != SNAP_AUTOSLICE)
+ if (snap_mode != SNAP_AUTOSLICE) {
edit_draw->draw_texture(select_handle, (endpoints[i] + ofs - (select_handle->get_size() / 2)).floor() - draw_ofs * draw_zoom);
+ }
ofs = (endpoints[next] - endpoints[i]) / 2;
ofs += (endpoints[next] - endpoints[i]).tangent().normalized() * (select_handle->get_size().width / 2);
- if (snap_mode != SNAP_AUTOSLICE)
+ if (snap_mode != SNAP_AUTOSLICE) {
edit_draw->draw_texture(select_handle, (endpoints[i] + ofs - (select_handle->get_size() / 2)).floor() - draw_ofs * draw_zoom);
+ }
scroll_rect.expand_to(raw_endpoints[i]);
}
@@ -259,9 +272,7 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
Ref<InputEventMouseButton> mb = p_input;
if (mb.is_valid()) {
-
if (mb->get_button_index() == BUTTON_LEFT) {
-
if (mb->is_pressed()) {
if (node_ninepatch || obj_styleBox.is_valid()) {
edited_margin = -1;
@@ -307,18 +318,19 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) {
if (E->get().has_point(point)) {
rect = E->get();
- if (InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL) && !(InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT | KEY_ALT))) {
+ if (Input::get_singleton()->is_key_pressed(KEY_CONTROL) && !(Input::get_singleton()->is_key_pressed(KEY_SHIFT | KEY_ALT))) {
Rect2 r;
- if (node_sprite)
+ if (node_sprite) {
r = node_sprite->get_region_rect();
- else if (node_sprite_3d)
+ } else if (node_sprite_3d) {
r = node_sprite_3d->get_region_rect();
- else if (node_ninepatch)
+ } else if (node_ninepatch) {
r = node_ninepatch->get_region_rect();
- else if (obj_styleBox.is_valid())
+ } else if (obj_styleBox.is_valid()) {
r = obj_styleBox->get_region_rect();
- else if (atlas_tex.is_valid())
+ } else if (atlas_tex.is_valid()) {
r = atlas_tex->get_region();
+ }
rect.expand_to(r.position);
rect.expand_to(r.position + r.size);
}
@@ -349,21 +361,23 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
}
} else if (edited_margin < 0) {
drag_from = mtx.affine_inverse().xform(Vector2(mb->get_position().x, mb->get_position().y));
- if (snap_mode == SNAP_PIXEL)
+ if (snap_mode == SNAP_PIXEL) {
drag_from = drag_from.snapped(Vector2(1, 1));
- else if (snap_mode == SNAP_GRID)
+ } else if (snap_mode == SNAP_GRID) {
drag_from = snap_point(drag_from);
+ }
drag = true;
- if (node_sprite)
+ if (node_sprite) {
rect_prev = node_sprite->get_region_rect();
- else if (node_sprite_3d)
+ } else if (node_sprite_3d) {
rect_prev = node_sprite_3d->get_region_rect();
- else if (node_ninepatch)
+ } else if (node_ninepatch) {
rect_prev = node_ninepatch->get_region_rect();
- else if (obj_styleBox.is_valid())
+ } else if (obj_styleBox.is_valid()) {
rect_prev = obj_styleBox->get_region_rect();
- else if (atlas_tex.is_valid())
+ } else if (atlas_tex.is_valid()) {
rect_prev = atlas_tex->get_region();
+ }
for (int i = 0; i < 8; i++) {
Vector2 tuv = endpoints[i];
@@ -421,15 +435,16 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
}
} else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
-
if (drag) {
drag = false;
if (edited_margin >= 0) {
static Margin m[4] = { MARGIN_TOP, MARGIN_BOTTOM, MARGIN_LEFT, MARGIN_RIGHT };
- if (node_ninepatch)
+ if (node_ninepatch) {
node_ninepatch->set_patch_margin(m[edited_margin], prev_margin);
- if (obj_styleBox.is_valid())
+ }
+ if (obj_styleBox.is_valid()) {
obj_styleBox->set_margin_size(m[edited_margin], prev_margin);
+ }
edited_margin = -1;
} else {
apply_rect(rect_prev);
@@ -448,41 +463,43 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
Ref<InputEventMouseMotion> mm = p_input;
if (mm.is_valid()) {
-
- if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)) {
-
+ if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
Vector2 dragged(mm->get_relative().x / draw_zoom, mm->get_relative().y / draw_zoom);
hscroll->set_value(hscroll->get_value() - dragged.x);
vscroll->set_value(vscroll->get_value() - dragged.y);
} else if (drag) {
-
if (edited_margin >= 0) {
float new_margin = 0;
- if (edited_margin == 0)
+ if (edited_margin == 0) {
new_margin = prev_margin + (mm->get_position().y - drag_from.y) / draw_zoom;
- else if (edited_margin == 1)
+ } else if (edited_margin == 1) {
new_margin = prev_margin - (mm->get_position().y - drag_from.y) / draw_zoom;
- else if (edited_margin == 2)
+ } else if (edited_margin == 2) {
new_margin = prev_margin + (mm->get_position().x - drag_from.x) / draw_zoom;
- else if (edited_margin == 3)
+ } else if (edited_margin == 3) {
new_margin = prev_margin - (mm->get_position().x - drag_from.x) / draw_zoom;
- else
+ } else {
ERR_PRINT("Unexpected edited_margin");
+ }
- if (new_margin < 0)
+ if (new_margin < 0) {
new_margin = 0;
+ }
static Margin m[4] = { MARGIN_TOP, MARGIN_BOTTOM, MARGIN_LEFT, MARGIN_RIGHT };
- if (node_ninepatch)
+ if (node_ninepatch) {
node_ninepatch->set_patch_margin(m[edited_margin], new_margin);
- if (obj_styleBox.is_valid())
+ }
+ if (obj_styleBox.is_valid()) {
obj_styleBox->set_margin_size(m[edited_margin], new_margin);
+ }
} else {
Vector2 new_pos = mtx.affine_inverse().xform(mm->get_position());
- if (snap_mode == SNAP_PIXEL)
+ if (snap_mode == SNAP_PIXEL) {
new_pos = new_pos.snapped(Vector2(1, 1));
- else if (snap_mode == SNAP_GRID)
+ } else if (snap_mode == SNAP_GRID) {
new_pos = snap_point(new_pos);
+ }
if (creating) {
rect = Rect2(drag_from, Size2());
@@ -560,8 +577,9 @@ void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
}
void TextureRegionEditor::_scroll_changed(float) {
- if (updating_scroll)
+ if (updating_scroll) {
return;
+ }
draw_ofs.x = hscroll->get_value();
draw_ofs.y = vscroll->get_value();
@@ -571,10 +589,11 @@ void TextureRegionEditor::_scroll_changed(float) {
void TextureRegionEditor::_set_snap_mode(int p_mode) {
snap_mode = p_mode;
- if (snap_mode == SNAP_GRID)
+ if (snap_mode == SNAP_GRID) {
hb_grid->show();
- else
+ } else {
hb_grid->hide();
+ }
if (snap_mode == SNAP_AUTOSLICE && is_visible() && autoslice_is_dirty) {
_update_autoslice();
@@ -614,8 +633,9 @@ void TextureRegionEditor::_set_snap_sep_y(float p_val) {
}
void TextureRegionEditor::_zoom_on_position(float p_zoom, Point2 p_position) {
- if (p_zoom < 0.25 || p_zoom > 8)
+ if (p_zoom < 0.25 || p_zoom > 8) {
return;
+ }
float prev_zoom = draw_zoom;
draw_zoom = p_zoom;
@@ -640,32 +660,34 @@ void TextureRegionEditor::_zoom_out() {
}
void TextureRegionEditor::apply_rect(const Rect2 &p_rect) {
- if (node_sprite)
+ if (node_sprite) {
node_sprite->set_region_rect(p_rect);
- else if (node_sprite_3d)
+ } else if (node_sprite_3d) {
node_sprite_3d->set_region_rect(p_rect);
- else if (node_ninepatch)
+ } else if (node_ninepatch) {
node_ninepatch->set_region_rect(p_rect);
- else if (obj_styleBox.is_valid())
+ } else if (obj_styleBox.is_valid()) {
obj_styleBox->set_region_rect(p_rect);
- else if (atlas_tex.is_valid())
+ } else if (atlas_tex.is_valid()) {
atlas_tex->set_region(p_rect);
+ }
}
void TextureRegionEditor::_update_rect() {
- if (node_sprite)
+ if (node_sprite) {
rect = node_sprite->get_region_rect();
- else if (node_sprite_3d)
+ } else if (node_sprite_3d) {
rect = node_sprite_3d->get_region_rect();
- else if (node_ninepatch) {
+ } else if (node_ninepatch) {
rect = node_ninepatch->get_region_rect();
if (rect == Rect2()) {
rect = Rect2(Vector2(), node_ninepatch->get_texture()->get_size());
}
- } else if (obj_styleBox.is_valid())
+ } else if (obj_styleBox.is_valid()) {
rect = obj_styleBox->get_region_rect();
- else if (atlas_tex.is_valid())
+ } else if (atlas_tex.is_valid()) {
rect = atlas_tex->get_region();
+ }
}
void TextureRegionEditor::_update_autoslice() {
@@ -673,16 +695,17 @@ void TextureRegionEditor::_update_autoslice() {
autoslice_cache.clear();
Ref<Texture2D> texture = nullptr;
- if (node_sprite)
+ if (node_sprite) {
texture = node_sprite->get_texture();
- else if (node_sprite_3d)
+ } else if (node_sprite_3d) {
texture = node_sprite_3d->get_texture();
- else if (node_ninepatch)
+ } else if (node_ninepatch) {
texture = node_ninepatch->get_texture();
- else if (obj_styleBox.is_valid())
+ } else if (obj_styleBox.is_valid()) {
texture = obj_styleBox->get_texture();
- else if (atlas_tex.is_valid())
+ } else if (atlas_tex.is_valid()) {
texture = atlas_tex->get_atlas();
+ }
if (texture.is_null()) {
return;
@@ -707,8 +730,9 @@ void TextureRegionEditor::_update_autoslice() {
autoslice_cache.erase(F->prev());
queue_erase = false;
}
- if (F == E)
+ if (F == E) {
continue;
+ }
if (E->get().grow(1).intersects(F->get())) {
E->get().expand_to(F->get().position);
E->get().expand_to(F->get().position + F->get().size);
@@ -788,7 +812,6 @@ bool TextureRegionEditor::is_stylebox() {
}
bool TextureRegionEditor::is_atlas_texture() {
-
return atlas_tex.is_valid();
}
@@ -805,24 +828,31 @@ Sprite2D *TextureRegionEditor::get_sprite() {
}
void TextureRegionEditor::edit(Object *p_obj) {
- if (node_sprite)
+ if (node_sprite) {
node_sprite->remove_change_receptor(this);
- if (node_sprite_3d)
+ }
+ if (node_sprite_3d) {
node_sprite_3d->remove_change_receptor(this);
- if (node_ninepatch)
+ }
+ if (node_ninepatch) {
node_ninepatch->remove_change_receptor(this);
- if (obj_styleBox.is_valid())
+ }
+ if (obj_styleBox.is_valid()) {
obj_styleBox->remove_change_receptor(this);
- if (atlas_tex.is_valid())
+ }
+ if (atlas_tex.is_valid()) {
atlas_tex->remove_change_receptor(this);
+ }
if (p_obj) {
node_sprite = Object::cast_to<Sprite2D>(p_obj);
node_sprite_3d = Object::cast_to<Sprite3D>(p_obj);
node_ninepatch = Object::cast_to<NinePatchRect>(p_obj);
- if (Object::cast_to<StyleBoxTexture>(p_obj))
+ if (Object::cast_to<StyleBoxTexture>(p_obj)) {
obj_styleBox = Ref<StyleBoxTexture>(Object::cast_to<StyleBoxTexture>(p_obj));
- if (Object::cast_to<AtlasTexture>(p_obj))
+ }
+ if (Object::cast_to<AtlasTexture>(p_obj)) {
atlas_tex = Ref<AtlasTexture>(Object::cast_to<AtlasTexture>(p_obj));
+ }
p_obj->add_change_receptor(this);
_edit_region();
} else {
@@ -842,25 +872,27 @@ void TextureRegionEditor::edit(Object *p_obj) {
}
void TextureRegionEditor::_changed_callback(Object *p_changed, const char *p_prop) {
-
- if (!is_visible())
+ if (!is_visible()) {
return;
- if (p_prop == StringName("atlas") || p_prop == StringName("texture"))
+ }
+ if (p_prop == StringName("atlas") || p_prop == StringName("texture")) {
_edit_region();
+ }
}
void TextureRegionEditor::_edit_region() {
Ref<Texture2D> texture = nullptr;
- if (node_sprite)
+ if (node_sprite) {
texture = node_sprite->get_texture();
- else if (node_sprite_3d)
+ } else if (node_sprite_3d) {
texture = node_sprite_3d->get_texture();
- else if (node_ninepatch)
+ } else if (node_ninepatch) {
texture = node_ninepatch->get_texture();
- else if (obj_styleBox.is_valid())
+ } else if (obj_styleBox.is_valid()) {
texture = obj_styleBox->get_texture();
- else if (atlas_tex.is_valid())
+ } else if (atlas_tex.is_valid()) {
texture = atlas_tex->get_atlas();
+ }
if (texture.is_null()) {
_zoom_reset();
@@ -1063,7 +1095,6 @@ void TextureRegionEditorPlugin::make_visible(bool p_visible) {
}
Dictionary TextureRegionEditorPlugin::get_state() const {
-
Dictionary state;
state["snap_offset"] = region_editor->snap_offset;
state["snap_step"] = region_editor->snap_step;
@@ -1073,7 +1104,6 @@ Dictionary TextureRegionEditorPlugin::get_state() const {
}
void TextureRegionEditorPlugin::set_state(const Dictionary &p_state) {
-
Dictionary state = p_state;
if (state.has("snap_step")) {
Vector2 s = state["snap_step"];
diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h
index c6cd648842..93da23fd50 100644
--- a/editor/plugins/texture_region_editor_plugin.h
+++ b/editor/plugins/texture_region_editor_plugin.h
@@ -45,7 +45,6 @@
*/
class TextureRegionEditor : public VBoxContainer {
-
GDCLASS(TextureRegionEditor, VBoxContainer);
enum SnapMode {
diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp
index b246b611fd..eb028659fd 100644
--- a/editor/plugins/theme_editor_plugin.cpp
+++ b/editor/plugins/theme_editor_plugin.cpp
@@ -36,52 +36,55 @@
#include "scene/gui/progress_bar.h"
void ThemeEditor::edit(const Ref<Theme> &p_theme) {
-
theme = p_theme;
main_panel->set_theme(p_theme);
main_container->set_theme(p_theme);
}
void ThemeEditor::_propagate_redraw(Control *p_at) {
-
p_at->notification(NOTIFICATION_THEME_CHANGED);
p_at->minimum_size_changed();
p_at->update();
for (int i = 0; i < p_at->get_child_count(); i++) {
Control *a = Object::cast_to<Control>(p_at->get_child(i));
- if (a)
+ if (a) {
_propagate_redraw(a);
+ }
}
}
void ThemeEditor::_refresh_interval() {
-
_propagate_redraw(main_panel);
_propagate_redraw(main_container);
}
void ThemeEditor::_type_menu_cbk(int p_option) {
-
type_edit->set_text(type_menu->get_popup()->get_item_text(p_option));
}
void ThemeEditor::_name_menu_about_to_show() {
-
String fromtype = type_edit->get_text();
List<StringName> names;
if (popup_mode == POPUP_ADD) {
-
switch (type_select->get_selected()) {
-
- case 0: Theme::get_default()->get_icon_list(fromtype, &names); break;
- case 1: Theme::get_default()->get_stylebox_list(fromtype, &names); break;
- case 2: Theme::get_default()->get_font_list(fromtype, &names); break;
- case 3: Theme::get_default()->get_color_list(fromtype, &names); break;
- case 4: Theme::get_default()->get_constant_list(fromtype, &names); break;
+ case 0:
+ Theme::get_default()->get_icon_list(fromtype, &names);
+ break;
+ case 1:
+ Theme::get_default()->get_stylebox_list(fromtype, &names);
+ break;
+ case 2:
+ Theme::get_default()->get_font_list(fromtype, &names);
+ break;
+ case 3:
+ Theme::get_default()->get_color_list(fromtype, &names);
+ break;
+ case 4:
+ Theme::get_default()->get_constant_list(fromtype, &names);
+ break;
}
} else if (popup_mode == POPUP_REMOVE) {
-
theme->get_icon_list(fromtype, &names);
theme->get_stylebox_list(fromtype, &names);
theme->get_font_list(fromtype, &names);
@@ -92,21 +95,17 @@ void ThemeEditor::_name_menu_about_to_show() {
name_menu->get_popup()->clear();
name_menu->get_popup()->set_size(Size2());
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
-
name_menu->get_popup()->add_item(E->get());
}
}
void ThemeEditor::_name_menu_cbk(int p_option) {
-
name_edit->set_text(name_menu->get_popup()->get_item_text(p_option));
}
struct _TECategory {
-
template <class T>
struct RefItem {
-
Ref<T> item;
StringName name;
bool operator<(const RefItem<T> &p) const { return item->get_instance_id() < p.item->get_instance_id(); }
@@ -114,7 +113,6 @@ struct _TECategory {
template <class T>
struct Item {
-
T item;
String name;
bool operator<(const Item<T> &p) const { return name < p.name; }
@@ -129,7 +127,6 @@ struct _TECategory {
};
void ThemeEditor::_save_template_cbk(String fname) {
-
String filename = file_dialog->get_current_path();
Map<String, _TECategory> categories;
@@ -143,7 +140,6 @@ void ThemeEditor::_save_template_cbk(String fname) {
// Fill default theme.
for (Map<String, _TECategory>::Element *E = categories.front(); E; E = E->next()) {
-
_TECategory &tc = E->get();
List<StringName> stylebox_list;
@@ -260,55 +256,55 @@ void ThemeEditor::_save_template_cbk(String fname) {
// Write default theme.
for (Map<String, _TECategory>::Element *E = categories.front(); E; E = E->next()) {
-
_TECategory &tc = E->get();
String underline = "; ";
- for (int i = 0; i < E->key().length(); i++)
+ for (int i = 0; i < E->key().length(); i++) {
underline += "*";
+ }
file->store_line("");
file->store_line(underline);
file->store_line("; " + E->key());
file->store_line(underline);
- if (tc.stylebox_items.size())
+ if (tc.stylebox_items.size()) {
file->store_line("\n; StyleBox Items:\n");
+ }
for (Set<_TECategory::RefItem<StyleBox>>::Element *F = tc.stylebox_items.front(); F; F = F->next()) {
-
file->store_line(E->key() + "." + F->get().name + " = default");
}
- if (tc.font_items.size())
+ if (tc.font_items.size()) {
file->store_line("\n; Font Items:\n");
+ }
for (Set<_TECategory::RefItem<Font>>::Element *F = tc.font_items.front(); F; F = F->next()) {
-
file->store_line(E->key() + "." + F->get().name + " = default");
}
- if (tc.icon_items.size())
+ if (tc.icon_items.size()) {
file->store_line("\n; Icon Items:\n");
+ }
for (Set<_TECategory::RefItem<Texture2D>>::Element *F = tc.icon_items.front(); F; F = F->next()) {
-
file->store_line(E->key() + "." + F->get().name + " = default");
}
- if (tc.color_items.size())
+ if (tc.color_items.size()) {
file->store_line("\n; Color Items:\n");
+ }
for (Set<_TECategory::Item<Color>>::Element *F = tc.color_items.front(); F; F = F->next()) {
-
file->store_line(E->key() + "." + F->get().name + " = default");
}
- if (tc.constant_items.size())
+ if (tc.constant_items.size()) {
file->store_line("\n; Constant Items:\n");
+ }
for (Set<_TECategory::Item<int>>::Element *F = tc.constant_items.front(); F; F = F->next()) {
-
file->store_line(E->key() + "." + F->get().name + " = default");
}
}
@@ -318,22 +314,28 @@ void ThemeEditor::_save_template_cbk(String fname) {
}
void ThemeEditor::_dialog_cbk() {
-
switch (popup_mode) {
case POPUP_ADD: {
-
switch (type_select->get_selected()) {
-
- case 0: theme->set_icon(name_edit->get_text(), type_edit->get_text(), Ref<Texture2D>()); break;
- case 1: theme->set_stylebox(name_edit->get_text(), type_edit->get_text(), Ref<StyleBox>()); break;
- case 2: theme->set_font(name_edit->get_text(), type_edit->get_text(), Ref<Font>()); break;
- case 3: theme->set_color(name_edit->get_text(), type_edit->get_text(), Color()); break;
- case 4: theme->set_constant(name_edit->get_text(), type_edit->get_text(), 0); break;
+ case 0:
+ theme->set_icon(name_edit->get_text(), type_edit->get_text(), Ref<Texture2D>());
+ break;
+ case 1:
+ theme->set_stylebox(name_edit->get_text(), type_edit->get_text(), Ref<StyleBox>());
+ break;
+ case 2:
+ theme->set_font(name_edit->get_text(), type_edit->get_text(), Ref<Font>());
+ break;
+ case 3:
+ theme->set_color(name_edit->get_text(), type_edit->get_text(), Color());
+ break;
+ case 4:
+ theme->set_constant(name_edit->get_text(), type_edit->get_text(), 0);
+ break;
}
} break;
case POPUP_CLASS_ADD: {
-
StringName fromtype = type_edit->get_text();
List<StringName> names;
@@ -375,12 +377,21 @@ void ThemeEditor::_dialog_cbk() {
} break;
case POPUP_REMOVE: {
switch (type_select->get_selected()) {
-
- case 0: theme->clear_icon(name_edit->get_text(), type_edit->get_text()); break;
- case 1: theme->clear_stylebox(name_edit->get_text(), type_edit->get_text()); break;
- case 2: theme->clear_font(name_edit->get_text(), type_edit->get_text()); break;
- case 3: theme->clear_color(name_edit->get_text(), type_edit->get_text()); break;
- case 4: theme->clear_constant(name_edit->get_text(), type_edit->get_text()); break;
+ case 0:
+ theme->clear_icon(name_edit->get_text(), type_edit->get_text());
+ break;
+ case 1:
+ theme->clear_stylebox(name_edit->get_text(), type_edit->get_text());
+ break;
+ case 2:
+ theme->clear_font(name_edit->get_text(), type_edit->get_text());
+ break;
+ case 3:
+ theme->clear_color(name_edit->get_text(), type_edit->get_text());
+ break;
+ case 4:
+ theme->clear_constant(name_edit->get_text(), type_edit->get_text());
+ break;
}
} break;
@@ -429,9 +440,7 @@ void ThemeEditor::_dialog_cbk() {
}
void ThemeEditor::_theme_menu_cbk(int p_option) {
-
if (p_option == POPUP_CREATE_EMPTY || p_option == POPUP_CREATE_EDITOR_EMPTY || p_option == POPUP_IMPORT_EDITOR_THEME) {
-
bool import = (p_option == POPUP_IMPORT_EDITOR_THEME);
Ref<Theme> base_theme;
@@ -443,7 +452,6 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
}
{
-
List<StringName> types;
base_theme->get_type_list(&types);
@@ -525,7 +533,6 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
type_select->hide();
} else if (p_option == POPUP_REMOVE) {
-
add_del_dialog->set_title(TTR("Remove Item"));
add_del_dialog->get_ok()->set_text(TTR("Remove"));
add_del_dialog->popup_centered(Size2(490, 85) * EDSCALE);
@@ -533,7 +540,6 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
base_theme = theme;
} else if (p_option == POPUP_CLASS_REMOVE) {
-
add_del_dialog->set_title(TTR("Remove All Items"));
add_del_dialog->get_ok()->set_text(TTR("Remove All"));
add_del_dialog->popup_centered(Size2(240, 85) * EDSCALE);
@@ -559,30 +565,27 @@ void ThemeEditor::_theme_menu_cbk(int p_option) {
List<StringName> new_types;
theme->get_type_list(&new_types);
for (List<StringName>::Element *F = new_types.front(); F; F = F->next()) {
-
bool found = false;
for (List<StringName>::Element *E = types.front(); E; E = E->next()) {
-
if (E->get() == F->get()) {
found = true;
break;
}
}
- if (!found)
+ if (!found) {
types.push_back(F->get());
+ }
}
}
types.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *E = types.front(); E; E = E->next()) {
-
type_menu->get_popup()->add_item(E->get());
}
}
void ThemeEditor::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_PROCESS: {
time_left -= get_process_delta_time();
@@ -601,7 +604,6 @@ void ThemeEditor::_bind_methods() {
}
ThemeEditor::ThemeEditor() {
-
time_left = 0;
HBoxContainer *top_menu = memnew(HBoxContainer);
@@ -871,7 +873,6 @@ ThemeEditor::ThemeEditor() {
}
void ThemeEditorPlugin::edit(Object *p_node) {
-
if (Object::cast_to<Theme>(p_node)) {
theme_editor->edit(Object::cast_to<Theme>(p_node));
} else {
@@ -880,27 +881,25 @@ void ThemeEditorPlugin::edit(Object *p_node) {
}
bool ThemeEditorPlugin::handles(Object *p_node) const {
-
return p_node->is_class("Theme");
}
void ThemeEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
theme_editor->set_process(true);
button->show();
editor->make_bottom_panel_item_visible(theme_editor);
} else {
theme_editor->set_process(false);
- if (theme_editor->is_visible_in_tree())
+ if (theme_editor->is_visible_in_tree()) {
editor->hide_bottom_panel();
+ }
button->hide();
}
}
ThemeEditorPlugin::ThemeEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
theme_editor = memnew(ThemeEditor);
theme_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE);
diff --git a/editor/plugins/theme_editor_plugin.h b/editor/plugins/theme_editor_plugin.h
index c51583593d..983bfb6b50 100644
--- a/editor/plugins/theme_editor_plugin.h
+++ b/editor/plugins/theme_editor_plugin.h
@@ -42,7 +42,6 @@
#include "editor/editor_node.h"
class ThemeEditor : public VBoxContainer {
-
GDCLASS(ThemeEditor, VBoxContainer);
Panel *main_panel;
@@ -99,7 +98,6 @@ public:
};
class ThemeEditorPlugin : public EditorPlugin {
-
GDCLASS(ThemeEditorPlugin, EditorPlugin);
ThemeEditor *theme_editor;
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index ce421ac0a5..3010d72d81 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -31,7 +31,7 @@
#include "tile_map_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/math/math_funcs.h"
#include "core/os/keyboard.h"
#include "editor/editor_scale.h"
@@ -39,35 +39,30 @@
#include "scene/gui/split_container.h"
void TileMapEditor::_node_removed(Node *p_node) {
-
if (p_node == node) {
node = nullptr;
}
}
void TileMapEditor::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_PROCESS: {
-
if (bucket_queue.size()) {
CanvasItemEditor::get_singleton()->update_viewport();
}
} break;
- case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ case NOTIFICATION_ENTER_TREE: {
+ get_tree()->connect("node_removed", callable_mp(this, &TileMapEditor::_node_removed));
+ [[fallthrough]];
+ }
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
if (is_visible_in_tree()) {
_update_palette();
}
- [[fallthrough]];
- }
-
- case NOTIFICATION_ENTER_TREE: {
- get_tree()->connect("node_removed", callable_mp(this, &TileMapEditor::_node_removed));
paint_button->set_icon(get_theme_icon("Edit", "EditorIcons"));
bucket_fill_button->set_icon(get_theme_icon("Bucket", "EditorIcons"));
picker_button->set_icon(get_theme_icon("ColorPick", "EditorIcons"));
@@ -96,7 +91,6 @@ void TileMapEditor::_notification(int p_what) {
}
void TileMapEditor::_update_button_tool() {
-
ToolButton *tb[4] = { paint_button, bucket_fill_button, picker_button, select_button };
// Unpress all buttons
for (int i = 0; i < 4; i++) {
@@ -122,8 +116,9 @@ void TileMapEditor::_update_button_tool() {
break;
}
- if (tool != TOOL_PICKING)
+ if (tool != TOOL_PICKING) {
last_tool = tool;
+ }
}
void TileMapEditor::_button_tool_select(int p_tool) {
@@ -131,7 +126,6 @@ void TileMapEditor::_button_tool_select(int p_tool) {
_update_button_tool();
switch (tool) {
case TOOL_SELECTING: {
-
selection_active = false;
} break;
default:
@@ -141,10 +135,8 @@ void TileMapEditor::_button_tool_select(int p_tool) {
}
void TileMapEditor::_menu_option(int p_option) {
-
switch (p_option) {
case OPTION_COPY: {
-
_update_copydata();
if (selection_active) {
@@ -154,9 +146,9 @@ void TileMapEditor::_menu_option(int p_option) {
}
} break;
case OPTION_ERASE_SELECTION: {
-
- if (!selection_active)
+ if (!selection_active) {
return;
+ }
_start_undo(TTR("Erase Selection"));
_erase_selection();
@@ -168,7 +160,6 @@ void TileMapEditor::_menu_option(int p_option) {
CanvasItemEditor::get_singleton()->update_viewport();
} break;
case OPTION_FIX_INVALID: {
-
undo_redo->create_action(TTR("Fix Invalid Tiles"));
undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
node->fix_invalid_tiles();
@@ -177,7 +168,6 @@ void TileMapEditor::_menu_option(int p_option) {
} break;
case OPTION_CUT: {
-
if (selection_active) {
_update_copydata();
@@ -205,19 +195,16 @@ void TileMapEditor::_palette_multi_selected(int index, bool selected) {
}
void TileMapEditor::_canvas_mouse_enter() {
-
mouse_over = true;
CanvasItemEditor::get_singleton()->update_viewport();
}
void TileMapEditor::_canvas_mouse_exit() {
-
mouse_over = false;
CanvasItemEditor::get_singleton()->update_viewport();
}
Vector<int> TileMapEditor::get_selected_tiles() const {
-
Vector<int> items = palette->get_selected_items();
if (items.size() == 0) {
@@ -232,7 +219,6 @@ Vector<int> TileMapEditor::get_selected_tiles() const {
}
void TileMapEditor::set_selected_tiles(Vector<int> p_tiles) {
-
palette->unselect_all();
for (int i = p_tiles.size() - 1; i >= 0; i--) {
@@ -247,7 +233,6 @@ void TileMapEditor::set_selected_tiles(Vector<int> p_tiles) {
}
Dictionary TileMapEditor::_create_cell_dictionary(int tile, bool flip_x, bool flip_y, bool transpose, Vector2 autotile_coord) {
-
Dictionary cell;
cell["id"] = tile;
@@ -260,7 +245,6 @@ Dictionary TileMapEditor::_create_cell_dictionary(int tile, bool flip_x, bool fl
}
void TileMapEditor::_create_set_cell_undo_redo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new) {
-
Dictionary cell_old = _create_cell_dictionary(p_cell_old.idx, p_cell_old.xf, p_cell_old.yf, p_cell_old.tr, p_cell_old.ac);
Dictionary cell_new = _create_cell_dictionary(p_cell_new.idx, p_cell_new.xf, p_cell_new.yf, p_cell_new.tr, p_cell_new.ac);
@@ -269,13 +253,11 @@ void TileMapEditor::_create_set_cell_undo_redo(const Vector2 &p_vec, const CellO
}
void TileMapEditor::_start_undo(const String &p_action) {
-
undo_data.clear();
undo_redo->create_action(p_action);
}
void TileMapEditor::_finish_undo() {
-
if (undo_data.size()) {
for (Map<Point2i, CellOp>::Element *E = undo_data.front(); E; E = E->next()) {
_create_set_cell_undo_redo(E->key(), E->get(), _get_op_from_cell(E->key()));
@@ -288,11 +270,11 @@ void TileMapEditor::_finish_undo() {
}
void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i &p_autotile_coord) {
-
ERR_FAIL_COND(!node);
- if (p_values.size() == 0)
+ if (p_values.size() == 0) {
return;
+ }
int p_value = p_values[Math::rand() % p_values.size()];
int prev_val = node->get_cell(p_pos.x, p_pos.y);
@@ -318,8 +300,9 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p
position = prev_position;
}
- if (p_value == prev_val && p_flip_h == prev_flip_h && p_flip_v == prev_flip_v && p_transpose == prev_transpose && prev_position == position)
+ if (p_value == prev_val && p_flip_h == prev_flip_h && p_flip_v == prev_flip_v && p_transpose == prev_transpose && prev_position == position) {
return; // Check that it's actually different.
+ }
for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) {
for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) {
@@ -332,8 +315,9 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p
node->_set_celld(p_pos, _create_cell_dictionary(p_value, p_flip_h, p_flip_v, p_transpose, p_autotile_coord));
- if (tool == TOOL_PASTING)
+ if (tool == TOOL_PASTING) {
return;
+ }
if (manual_autotile || (p_value != -1 && node->get_tileset()->tile_get_tile_mode(p_value) == TileSet::ATLAS_TILE)) {
if (current != -1) {
@@ -359,7 +343,6 @@ void TileMapEditor::_priority_toggled(bool p_enabled) {
}
void TileMapEditor::_text_entered(const String &p_text) {
-
canvas_item_editor_viewport->grab_focus();
}
@@ -368,14 +351,12 @@ void TileMapEditor::_text_changed(const String &p_text) {
}
void TileMapEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
-
Ref<InputEventKey> k = p_ie;
if (k.is_valid() && (k->get_keycode() == KEY_UP ||
k->get_keycode() == KEY_DOWN ||
k->get_keycode() == KEY_PAGEUP ||
k->get_keycode() == KEY_PAGEDOWN)) {
-
palette->call("_gui_input", k);
search_box->accept_event();
}
@@ -395,9 +376,9 @@ struct _PaletteEntry {
} // namespace
void TileMapEditor::_update_palette() {
-
- if (!node)
+ if (!node) {
return;
+ }
// Update the clear button.
clear_transform_button->set_disabled(!flip_h && !flip_v && !transpose);
@@ -423,8 +404,9 @@ void TileMapEditor::_update_palette() {
List<int> tiles;
tileset->get_tile_list(&tiles);
- if (tiles.empty())
+ if (tiles.empty()) {
return;
+ }
float min_size = EDITOR_DEF("editors/tile_map/preview_size", 64);
min_size *= EDSCALE;
@@ -446,7 +428,6 @@ void TileMapEditor::_update_palette() {
Vector<_PaletteEntry> entries;
for (List<int>::Element *E = tiles.front(); E; E = E->next()) {
-
String name = tileset->tile_get_name(E->get());
if (name != "") {
@@ -461,8 +442,9 @@ void TileMapEditor::_update_palette() {
name = "#" + itos(E->get());
}
- if (filter != "" && !filter.is_subsequence_ofi(name))
+ if (filter != "" && !filter.is_subsequence_ofi(name)) {
continue;
+ }
const _PaletteEntry entry = { E->get(), name };
entries.push_back(entry);
@@ -473,7 +455,6 @@ void TileMapEditor::_update_palette() {
}
for (int i = 0; i < entries.size(); i++) {
-
if (show_tile_names) {
palette->add_item(entries[i].name);
} else {
@@ -501,8 +482,9 @@ void TileMapEditor::_update_palette() {
}
// Set region.
- if (region.size != Size2())
+ if (region.size != Size2()) {
palette->set_item_icon_region(palette->get_item_count() - 1, region);
+ }
// Set icon.
palette->set_item_icon(palette->get_item_count() - 1, tex);
@@ -525,7 +507,6 @@ void TileMapEditor::_update_palette() {
}
if (sel_tile != TileMap::INVALID_CELL && ((manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) || (!priority_atlastile && tileset->tile_get_tile_mode(sel_tile) == TileSet::ATLAS_TILE))) {
-
const Map<Vector2, uint32_t> &tiles2 = tileset->autotile_get_bitmask_map(sel_tile);
Vector<Vector2> entries2;
@@ -543,18 +524,17 @@ void TileMapEditor::_update_palette() {
Ref<Texture2D> tex = tileset->tile_get_texture(sel_tile);
for (int i = 0; i < entries2.size(); i++) {
-
manual_palette->add_item(String());
if (tex.is_valid()) {
-
Rect2 region = tileset->tile_get_region(sel_tile);
int spacing = tileset->autotile_get_spacing(sel_tile);
region.size = tileset->autotile_get_size(sel_tile); // !!
region.position += (region.size + Vector2(spacing, spacing)) * entries2[i];
- if (!region.has_no_area())
+ if (!region.has_no_area()) {
manual_palette->set_item_icon_region(manual_palette->get_item_count() - 1, region);
+ }
manual_palette->set_item_icon(manual_palette->get_item_count() - 1, tex);
}
@@ -565,10 +545,12 @@ void TileMapEditor::_update_palette() {
if (manual_palette->get_item_count() > 0) {
// Only show the manual palette if at least tile exists in it.
- if (selected_manual == -1 || selected_single != palette->get_current())
+ if (selected_manual == -1 || selected_single != palette->get_current()) {
selected_manual = 0;
- if (selected_manual < manual_palette->get_item_count())
+ }
+ if (selected_manual < manual_palette->get_item_count()) {
manual_palette->set_current(selected_manual);
+ }
manual_palette->show();
}
@@ -582,11 +564,11 @@ void TileMapEditor::_update_palette() {
}
void TileMapEditor::_pick_tile(const Point2 &p_pos) {
-
int id = node->get_cell(p_pos.x, p_pos.y);
- if (id == TileMap::INVALID_CELL)
+ if (id == TileMap::INVALID_CELL) {
return;
+ }
if (search_box->get_text() != "") {
search_box->set_text("");
@@ -611,15 +593,15 @@ void TileMapEditor::_pick_tile(const Point2 &p_pos) {
}
Vector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool erase, bool preview) {
-
int prev_id = node->get_cell(p_start.x, p_start.y);
Vector<int> ids;
ids.push_back(TileMap::INVALID_CELL);
if (!erase) {
ids = get_selected_tiles();
- if (ids.size() == 0 || ids[0] == TileMap::INVALID_CELL)
+ if (ids.size() == 0 || ids[0] == TileMap::INVALID_CELL) {
return Vector<Vector2>();
+ }
} else if (prev_id == TileMap::INVALID_CELL) {
return Vector<Vector2>();
}
@@ -636,8 +618,9 @@ Vector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool erase,
// Test if we can re-use the result from preview bucket fill
bool invalidate_cache = false;
// Area changed
- if (r != bucket_cache_rect)
+ if (r != bucket_cache_rect) {
_clear_bucket_cache();
+ }
// Cache grid is not initialized
if (bucket_cache_visited == nullptr) {
bucket_cache_visited = new bool[area];
@@ -650,8 +633,9 @@ Vector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool erase,
invalidate_cache = true;
}
if (invalidate_cache) {
- for (int i = 0; i < area; ++i)
+ for (int i = 0; i < area; ++i) {
bucket_cache_visited[i] = false;
+ }
bucket_cache = Vector<Vector2>();
bucket_cache_tile = prev_id;
bucket_cache_rect = r;
@@ -673,24 +657,25 @@ Vector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool erase,
bucket_queue.push_back(p_start);
while (bucket_queue.size()) {
-
Point2i n = bucket_queue.front()->get();
bucket_queue.pop_front();
- if (!r.has_point(n))
+ if (!r.has_point(n)) {
continue;
+ }
if (node->get_cell(n.x, n.y) == prev_id) {
-
if (preview) {
int loc = (n.x - r.position.x) + (n.y - r.position.y) * r.get_size().x;
- if (bucket_cache_visited[loc])
+ if (bucket_cache_visited[loc]) {
continue;
+ }
bucket_cache_visited[loc] = true;
bucket_cache.push_back(n);
} else {
- if (non_preview_cache.find(n) >= 0)
+ if (non_preview_cache.find(n) >= 0) {
continue;
+ }
points.push_back(n);
non_preview_cache.push_back(n);
}
@@ -711,7 +696,6 @@ Vector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool erase,
}
void TileMapEditor::_fill_points(const Vector<Vector2> &p_points, const Dictionary &p_op) {
-
int len = p_points.size();
const Vector2 *pr = p_points.ptr();
@@ -724,32 +708,28 @@ void TileMapEditor::_fill_points(const Vector<Vector2> &p_points, const Dictiona
_set_cell(pr[i], ids, xf, yf, tr);
node->make_bitmask_area_dirty(pr[i]);
}
- if (!manual_autotile)
+ if (!manual_autotile) {
node->update_dirty_bitmask();
+ }
}
void TileMapEditor::_erase_points(const Vector<Vector2> &p_points) {
-
int len = p_points.size();
const Vector2 *pr = p_points.ptr();
for (int i = 0; i < len; i++) {
-
_set_cell(pr[i], invalid_cell);
}
}
void TileMapEditor::_select(const Point2i &p_from, const Point2i &p_to) {
-
Point2i begin = p_from;
Point2i end = p_to;
if (begin.x > end.x) {
-
SWAP(begin.x, end.x);
}
if (begin.y > end.y) {
-
SWAP(begin.y, end.y);
}
@@ -760,23 +740,23 @@ void TileMapEditor::_select(const Point2i &p_from, const Point2i &p_to) {
}
void TileMapEditor::_erase_selection() {
- if (!selection_active)
+ if (!selection_active) {
return;
+ }
for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
-
_set_cell(Point2i(j, i), invalid_cell, false, false, false);
}
}
}
void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i &p_autotile_coord, const Transform2D &p_xform) {
-
Ref<Texture2D> t = node->get_tileset()->tile_get_texture(p_cell);
- if (t.is_null())
+ if (t.is_null()) {
return;
+ }
Vector2 tile_ofs = node->get_tileset()->tile_get_texture_offset(p_cell);
@@ -813,11 +793,13 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p
if (compatibility_mode_enabled && !centered_texture) {
if (rect.size.y > rect.size.x) {
- if ((p_flip_h && (p_flip_v || p_transpose)) || (p_flip_v && !p_transpose))
+ if ((p_flip_h && (p_flip_v || p_transpose)) || (p_flip_v && !p_transpose)) {
tile_ofs.y += rect.size.y - rect.size.x;
+ }
} else if (rect.size.y < rect.size.x) {
- if ((p_flip_v && (p_flip_h || p_transpose)) || (p_flip_h && !p_transpose))
+ if ((p_flip_v && (p_flip_h || p_transpose)) || (p_flip_h && !p_transpose)) {
tile_ofs.x += rect.size.x - rect.size.y;
+ }
}
}
@@ -843,37 +825,38 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p
if (compatibility_mode_enabled && !centered_texture) {
if (node->get_tile_origin() == TileMap::TILE_ORIGIN_TOP_LEFT) {
-
rect.position += tile_ofs;
} else if (node->get_tile_origin() == TileMap::TILE_ORIGIN_BOTTOM_LEFT) {
-
rect.position += tile_ofs;
if (p_transpose) {
- if (p_flip_h)
+ if (p_flip_h) {
rect.position.x -= cell_size.x;
- else
+ } else {
rect.position.x += cell_size.x;
+ }
} else {
- if (p_flip_v)
+ if (p_flip_v) {
rect.position.y -= cell_size.y;
- else
+ } else {
rect.position.y += cell_size.y;
+ }
}
} else if (node->get_tile_origin() == TileMap::TILE_ORIGIN_CENTER) {
-
rect.position += tile_ofs;
- if (p_flip_h)
+ if (p_flip_h) {
rect.position.x -= cell_size.x / 2;
- else
+ } else {
rect.position.x += cell_size.x / 2;
+ }
- if (p_flip_v)
+ if (p_flip_v) {
rect.position.y -= cell_size.y / 2;
- else
+ } else {
rect.position.y += cell_size.y / 2;
+ }
}
} else {
rect.position += tile_ofs;
@@ -893,7 +876,6 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p
}
void TileMapEditor::_draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i &p_autotile_coord, const Transform2D &p_xform) {
-
Vector<Vector2> points = _bucket_fill(p_point, false, true);
const Vector2 *pr = points.ptr();
int len = points.size();
@@ -911,16 +893,14 @@ void TileMapEditor::_clear_bucket_cache() {
}
void TileMapEditor::_update_copydata() {
-
copydata.clear();
- if (!selection_active)
+ if (!selection_active) {
return;
+ }
for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
-
for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
-
TileData tcd;
tcd.cell = node->get_cell(j, i);
@@ -938,7 +918,6 @@ void TileMapEditor::_update_copydata() {
}
static inline Vector<Point2i> line(int x0, int x1, int y0, int y1) {
-
Vector<Point2i> points;
float dx = ABS(x1 - x0);
@@ -982,9 +961,9 @@ static inline Vector<Point2i> line(int x0, int x1, int y0, int y1) {
}
bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
-
- if (!node || !node->get_tileset().is_valid() || !node->is_visible_in_tree() || CanvasItemEditor::get_singleton()->get_current_tool() != CanvasItemEditor::TOOL_SELECT)
+ if (!node || !node->get_tileset().is_valid() || !node->is_visible_in_tree() || CanvasItemEditor::get_singleton()->get_current_tool() != CanvasItemEditor::TOOL_SELECT) {
return false;
+ }
Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
Transform2D xform_inv = xform.affine_inverse();
@@ -993,20 +972,18 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid()) {
if (mb->get_button_index() == BUTTON_LEFT) {
-
if (mb->is_pressed()) {
-
- if (InputFilter::get_singleton()->is_key_pressed(KEY_SPACE))
+ if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
return false; // Drag.
+ }
if (tool == TOOL_NONE) {
-
if (mb->get_shift()) {
-
- if (mb->get_command())
+ if (mb->get_command()) {
tool = TOOL_RECTANGLE_PAINT;
- else
+ } else {
tool = TOOL_LINE_PAINT;
+ }
selection_active = false;
rectangle_begin = over_tile;
@@ -1028,20 +1005,16 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
if (tool == TOOL_PAINTING) {
-
Vector<int> ids = get_selected_tiles();
if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
-
tool = TOOL_PAINTING;
_start_undo(TTR("Paint TileMap"));
}
} else if (tool == TOOL_PICKING) {
-
_pick_tile(over_tile);
} else if (tool == TOOL_SELECTING) {
-
selection_active = true;
rectangle_begin = over_tile;
}
@@ -1052,27 +1025,21 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} else {
// Mousebutton was released.
if (tool != TOOL_NONE) {
-
if (tool == TOOL_PAINTING) {
-
Vector<int> ids = get_selected_tiles();
if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
-
_set_cell(over_tile, ids, flip_h, flip_v, transpose);
_finish_undo();
paint_undo.clear();
}
} else if (tool == TOOL_LINE_PAINT) {
-
Vector<int> ids = get_selected_tiles();
if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
-
_start_undo(TTR("Line Draw"));
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
-
_set_cell(E->key(), ids, flip_h, flip_v, transpose);
}
_finish_undo();
@@ -1082,15 +1049,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
CanvasItemEditor::get_singleton()->update_viewport();
}
} else if (tool == TOOL_RECTANGLE_PAINT) {
-
Vector<int> ids = get_selected_tiles();
if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
-
_start_undo(TTR("Rectangle Paint"));
for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
-
_set_cell(Point2i(j, i), ids, flip_h, flip_v, transpose);
}
}
@@ -1099,14 +1063,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
CanvasItemEditor::get_singleton()->update_viewport();
}
} else if (tool == TOOL_PASTING) {
-
Point2 ofs = over_tile - rectangle.position;
Vector<int> ids;
_start_undo(TTR("Paste"));
ids.push_back(0);
for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
-
ids.write[0] = E->get().cell;
_set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose, E->get().autotile_coord);
}
@@ -1116,15 +1078,14 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return true; // We want to keep the Pasting tool.
} else if (tool == TOOL_SELECTING) {
-
CanvasItemEditor::get_singleton()->update_viewport();
} else if (tool == TOOL_BUCKET) {
-
Vector<Vector2> points = _bucket_fill(over_tile);
- if (points.size() == 0)
+ if (points.size() == 0) {
return false;
+ }
_start_undo(TTR("Bucket Fill"));
@@ -1152,11 +1113,8 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
}
} else if (mb->get_button_index() == BUTTON_RIGHT) {
-
if (mb->is_pressed()) {
-
if (tool == TOOL_SELECTING || selection_active) {
-
tool = TOOL_NONE;
selection_active = false;
@@ -1167,7 +1125,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
if (tool == TOOL_PASTING) {
-
tool = TOOL_NONE;
copydata.clear();
@@ -1178,7 +1135,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
if (tool == TOOL_NONE) {
-
paint_undo.clear();
Point2 local = node->world_to_map(xform_inv.xform(mb->get_position()));
@@ -1186,15 +1142,15 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
_start_undo(TTR("Erase TileMap"));
if (mb->get_shift()) {
- if (mb->get_command())
+ if (mb->get_command()) {
tool = TOOL_RECTANGLE_ERASE;
- else
+ } else {
tool = TOOL_LINE_ERASE;
+ }
selection_active = false;
rectangle_begin = local;
} else {
-
tool = TOOL_ERASING;
_set_cell(local, invalid_cell);
@@ -1206,7 +1162,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} else {
if (tool == TOOL_ERASING || tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
-
_finish_undo();
if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
@@ -1219,7 +1174,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return true;
} else if (tool == TOOL_BUCKET) {
-
Vector<int> ids;
ids.push_back(node->get_cell(over_tile.x, over_tile.y));
Dictionary pop;
@@ -1230,8 +1184,9 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Vector<Vector2> points = _bucket_fill(over_tile, true);
- if (points.size() == 0)
+ if (points.size() == 0) {
return false;
+ }
undo_redo->create_action(TTR("Bucket Fill"));
@@ -1247,12 +1202,10 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
Point2i new_over_tile = node->world_to_map(xform_inv.xform(mm->get_position()));
Point2i old_over_tile = over_tile;
if (new_over_tile != over_tile) {
-
over_tile = new_over_tile;
CanvasItemEditor::get_singleton()->update_viewport();
}
@@ -1260,20 +1213,19 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
int tile_under = node->get_cell(over_tile.x, over_tile.y);
String tile_name = "none";
- if (node->get_tileset()->has_tile(tile_under))
+ if (node->get_tileset()->has_tile(tile_under)) {
tile_name = node->get_tileset()->tile_get_name(tile_under);
+ }
tile_info->show();
tile_info->set_text(String::num(over_tile.x) + ", " + String::num(over_tile.y) + " [" + tile_name + "]");
if (tool == TOOL_PAINTING) {
-
// Paint using bresenham line to prevent holes in painting if the user moves fast.
Vector<Point2i> points = line(old_over_tile.x, over_tile.x, old_over_tile.y, over_tile.y);
Vector<int> ids = get_selected_tiles();
for (int i = 0; i < points.size(); ++i) {
-
Point2i pos = points[i];
if (!paint_undo.has(pos)) {
@@ -1287,13 +1239,11 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
if (tool == TOOL_ERASING) {
-
// Erase using bresenham line to prevent holes in painting if the user moves fast.
Vector<Point2i> points = line(old_over_tile.x, over_tile.x, old_over_tile.y, over_tile.y);
for (int i = 0; i < points.size(); ++i) {
-
Point2i pos = points[i];
_set_cell(pos, invalid_cell);
@@ -1303,23 +1253,19 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
if (tool == TOOL_SELECTING) {
-
_select(rectangle_begin, over_tile);
return true;
}
if (tool == TOOL_LINE_PAINT || tool == TOOL_LINE_ERASE) {
-
Vector<int> ids = get_selected_tiles();
Vector<int> tmp_cell;
bool erasing = (tool == TOOL_LINE_ERASE);
tmp_cell.push_back(0);
if (erasing && paint_undo.size()) {
-
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
-
tmp_cell.write[0] = E->get().idx;
_set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
}
@@ -1328,15 +1274,14 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
paint_undo.clear();
if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
-
Vector<Point2i> points = line(rectangle_begin.x, over_tile.x, rectangle_begin.y, over_tile.y);
for (int i = 0; i < points.size(); i++) {
-
paint_undo[points[i]] = _get_op_from_cell(points[i]);
- if (erasing)
+ if (erasing) {
_set_cell(points[i], invalid_cell);
+ }
}
CanvasItemEditor::get_singleton()->update_viewport();
@@ -1345,18 +1290,14 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return true;
}
if (tool == TOOL_RECTANGLE_PAINT || tool == TOOL_RECTANGLE_ERASE) {
-
Vector<int> tmp_cell;
tmp_cell.push_back(0);
_select(rectangle_begin, over_tile);
if (tool == TOOL_RECTANGLE_ERASE) {
-
if (paint_undo.size()) {
-
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
-
tmp_cell.write[0] = E->get().idx;
_set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
}
@@ -1366,7 +1307,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
-
Point2i tile = Point2i(j, i);
paint_undo[tile] = _get_op_from_cell(tile);
@@ -1377,8 +1317,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return true;
}
- if (tool == TOOL_PICKING && InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
-
+ if (tool == TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
_pick_tile(over_tile);
return true;
@@ -1388,7 +1327,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed()) {
-
if (last_tool == TOOL_NONE && tool == TOOL_PICKING && k->get_keycode() == KEY_SHIFT && k->get_command()) {
// trying to draw a rectangle with the painting tool, so change to the correct tool
tool = last_tool;
@@ -1398,11 +1336,11 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
if (k->get_keycode() == KEY_ESCAPE) {
-
- if (tool == TOOL_PASTING)
+ if (tool == TOOL_PASTING) {
copydata.clear();
- else if (tool == TOOL_SELECTING || selection_active)
+ } else if (tool == TOOL_SELECTING || selection_active) {
selection_active = false;
+ }
tool = TOOL_NONE;
@@ -1517,14 +1455,11 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} else if (k.is_valid()) { // Release event.
if (tool == TOOL_NONE) {
-
if (k->get_keycode() == KEY_SHIFT && k->get_command()) {
-
tool = TOOL_PICKING;
_update_button_tool();
}
} else if (tool == TOOL_PICKING) {
-
#ifdef APPLE_STYLE_KEYS
if (k->get_keycode() == KEY_META) {
#else
@@ -1542,9 +1477,9 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
-
- if (!node || CanvasItemEditor::get_singleton()->get_current_tool() != CanvasItemEditor::TOOL_SELECT)
+ if (!node || CanvasItemEditor::get_singleton()->get_current_tool() != CanvasItemEditor::TOOL_SELECT) {
return;
+ }
Transform2D cell_xf = node->get_cell_transform();
Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
@@ -1560,27 +1495,23 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
Rect2i si = aabb.grow(1.0);
if (node->get_half_offset() != TileMap::HALF_OFFSET_X && node->get_half_offset() != TileMap::HALF_OFFSET_NEGATIVE_X) {
-
int max_lines = 2000; //avoid crash if size too small
for (int i = (si.position.x) - 1; i <= (si.position.x + si.size.x); i++) {
-
Vector2 from = xform.xform(node->map_to_world(Vector2(i, si.position.y)));
Vector2 to = xform.xform(node->map_to_world(Vector2(i, si.position.y + si.size.y + 1)));
Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2);
p_overlay->draw_line(from, to, col, 1);
- if (max_lines-- == 0)
+ if (max_lines-- == 0) {
break;
+ }
}
} else {
-
int max_lines = 10000; //avoid crash if size too small
for (int i = (si.position.x) - 1; i <= (si.position.x + si.size.x); i++) {
-
for (int j = (si.position.y) - 1; j <= (si.position.y + si.size.y); j++) {
-
Vector2 ofs;
if (ABS(j) & 1) {
ofs = cell_xf[0] * (node->get_half_offset() == TileMap::HALF_OFFSET_X ? 0.5 : -0.5);
@@ -1592,35 +1523,33 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2);
p_overlay->draw_line(from, to, col, 1);
- if (--max_lines == 0)
+ if (--max_lines == 0) {
break;
+ }
}
- if (max_lines == 0)
+ if (max_lines == 0) {
break;
+ }
}
}
int max_lines = 10000; //avoid crash if size too small
if (node->get_half_offset() != TileMap::HALF_OFFSET_Y && node->get_half_offset() != TileMap::HALF_OFFSET_NEGATIVE_Y) {
-
for (int i = (si.position.y) - 1; i <= (si.position.y + si.size.y); i++) {
-
Vector2 from = xform.xform(node->map_to_world(Vector2(si.position.x, i)));
Vector2 to = xform.xform(node->map_to_world(Vector2(si.position.x + si.size.x + 1, i)));
Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2);
p_overlay->draw_line(from, to, col, 1);
- if (max_lines-- == 0)
+ if (max_lines-- == 0) {
break;
+ }
}
} else {
-
for (int i = (si.position.y) - 1; i <= (si.position.y + si.size.y); i++) {
-
for (int j = (si.position.x) - 1; j <= (si.position.x + si.size.x); j++) {
-
Vector2 ofs;
if (ABS(j) & 1) {
ofs = cell_xf[1] * (node->get_half_offset() == TileMap::HALF_OFFSET_Y ? 0.5 : -0.5);
@@ -1632,17 +1561,18 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2);
p_overlay->draw_line(from, to, col, 1);
- if (--max_lines == 0)
+ if (--max_lines == 0) {
break;
+ }
}
- if (max_lines == 0)
+ if (max_lines == 0) {
break;
+ }
}
}
}
if (selection_active) {
-
Vector<Vector2> points;
points.push_back(xform.xform(node->map_to_world((rectangle.position))));
points.push_back(xform.xform(node->map_to_world((rectangle.position + Point2(rectangle.size.x + 1, 0)))));
@@ -1653,7 +1583,6 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
}
if (mouse_over && node->get_tileset().is_valid()) {
-
Vector2 endpoints[4] = {
node->map_to_world(over_tile, true),
node->map_to_world((over_tile + Point2(1, 0)), true),
@@ -1662,24 +1591,30 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
};
for (int i = 0; i < 4; i++) {
- if (node->get_half_offset() == TileMap::HALF_OFFSET_X && ABS(over_tile.y) & 1)
+ if (node->get_half_offset() == TileMap::HALF_OFFSET_X && ABS(over_tile.y) & 1) {
endpoints[i] += cell_xf[0] * 0.5;
- if (node->get_half_offset() == TileMap::HALF_OFFSET_NEGATIVE_X && ABS(over_tile.y) & 1)
+ }
+ if (node->get_half_offset() == TileMap::HALF_OFFSET_NEGATIVE_X && ABS(over_tile.y) & 1) {
endpoints[i] += cell_xf[0] * -0.5;
- if (node->get_half_offset() == TileMap::HALF_OFFSET_Y && ABS(over_tile.x) & 1)
+ }
+ if (node->get_half_offset() == TileMap::HALF_OFFSET_Y && ABS(over_tile.x) & 1) {
endpoints[i] += cell_xf[1] * 0.5;
- if (node->get_half_offset() == TileMap::HALF_OFFSET_NEGATIVE_Y && ABS(over_tile.x) & 1)
+ }
+ if (node->get_half_offset() == TileMap::HALF_OFFSET_NEGATIVE_Y && ABS(over_tile.x) & 1) {
endpoints[i] += cell_xf[1] * -0.5;
+ }
endpoints[i] = xform.xform(endpoints[i]);
}
Color col;
- if (node->get_cell(over_tile.x, over_tile.y) != TileMap::INVALID_CELL)
+ if (node->get_cell(over_tile.x, over_tile.y) != TileMap::INVALID_CELL) {
col = Color(0.2, 0.8, 1.0, 0.8);
- else
+ } else {
col = Color(1.0, 0.4, 0.2, 0.8);
+ }
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++) {
p_overlay->draw_line(endpoints[i], endpoints[(i + 1) % 4], col, 2);
+ }
bool bucket_preview = EditorSettings::get_singleton()->get("editors/tile_map/bucket_fill_preview");
if (tool == TOOL_SELECTING || tool == TOOL_PICKING || !bucket_preview) {
@@ -1687,49 +1622,49 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
}
if (tool == TOOL_LINE_PAINT) {
-
- if (paint_undo.empty())
+ if (paint_undo.empty()) {
return;
+ }
Vector<int> ids = get_selected_tiles();
- if (ids.size() == 1 && ids[0] == TileMap::INVALID_CELL)
+ if (ids.size() == 1 && ids[0] == TileMap::INVALID_CELL) {
return;
+ }
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
-
_draw_cell(p_overlay, ids[0], E->key(), flip_h, flip_v, transpose, autotile_coord, xform);
}
} else if (tool == TOOL_RECTANGLE_PAINT) {
-
Vector<int> ids = get_selected_tiles();
- if (ids.size() == 1 && ids[0] == TileMap::INVALID_CELL)
+ if (ids.size() == 1 && ids[0] == TileMap::INVALID_CELL) {
return;
+ }
for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
-
_draw_cell(p_overlay, ids[0], Point2i(j, i), flip_h, flip_v, transpose, autotile_coord, xform);
}
}
} else if (tool == TOOL_PASTING) {
-
- if (copydata.empty())
+ if (copydata.empty()) {
return;
+ }
Ref<TileSet> ts = node->get_tileset();
- if (ts.is_null())
+ if (ts.is_null()) {
return;
+ }
Point2 ofs = over_tile - rectangle.position;
for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
-
- if (!ts->has_tile(E->get().cell))
+ if (!ts->has_tile(E->get().cell)) {
continue;
+ }
TileData tcd = E->get();
@@ -1748,16 +1683,15 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
p_overlay->draw_colored_polygon(points, Color(0.2, 1.0, 0.8, 0.2));
} else if (tool == TOOL_BUCKET) {
-
Vector<int> tiles = get_selected_tiles();
_draw_fill_preview(p_overlay, tiles[0], over_tile, flip_h, flip_v, transpose, autotile_coord, xform);
} else {
-
Vector<int> st = get_selected_tiles();
- if (st.size() == 1 && st[0] == TileMap::INVALID_CELL)
+ if (st.size() == 1 && st[0] == TileMap::INVALID_CELL) {
return;
+ }
_draw_cell(p_overlay, st[0], over_tile, flip_h, flip_v, transpose, autotile_coord, xform);
}
@@ -1765,44 +1699,47 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
}
void TileMapEditor::edit(Node *p_tile_map) {
-
search_box->set_text("");
if (!canvas_item_editor_viewport) {
canvas_item_editor_viewport = CanvasItemEditor::get_singleton()->get_viewport_control();
}
- if (node)
+ if (node) {
node->disconnect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed));
+ }
if (p_tile_map) {
-
node = Object::cast_to<TileMap>(p_tile_map);
- if (!canvas_item_editor_viewport->is_connected("mouse_entered", callable_mp(this, &TileMapEditor::_canvas_mouse_enter)))
+ if (!canvas_item_editor_viewport->is_connected("mouse_entered", callable_mp(this, &TileMapEditor::_canvas_mouse_enter))) {
canvas_item_editor_viewport->connect("mouse_entered", callable_mp(this, &TileMapEditor::_canvas_mouse_enter));
- if (!canvas_item_editor_viewport->is_connected("mouse_exited", callable_mp(this, &TileMapEditor::_canvas_mouse_exit)))
+ }
+ if (!canvas_item_editor_viewport->is_connected("mouse_exited", callable_mp(this, &TileMapEditor::_canvas_mouse_exit))) {
canvas_item_editor_viewport->connect("mouse_exited", callable_mp(this, &TileMapEditor::_canvas_mouse_exit));
+ }
_update_palette();
} else {
node = nullptr;
- if (canvas_item_editor_viewport->is_connected("mouse_entered", callable_mp(this, &TileMapEditor::_canvas_mouse_enter)))
+ if (canvas_item_editor_viewport->is_connected("mouse_entered", callable_mp(this, &TileMapEditor::_canvas_mouse_enter))) {
canvas_item_editor_viewport->disconnect("mouse_entered", callable_mp(this, &TileMapEditor::_canvas_mouse_enter));
- if (canvas_item_editor_viewport->is_connected("mouse_exited", callable_mp(this, &TileMapEditor::_canvas_mouse_exit)))
+ }
+ if (canvas_item_editor_viewport->is_connected("mouse_exited", callable_mp(this, &TileMapEditor::_canvas_mouse_exit))) {
canvas_item_editor_viewport->disconnect("mouse_exited", callable_mp(this, &TileMapEditor::_canvas_mouse_exit));
+ }
_update_palette();
}
- if (node)
+ if (node) {
node->connect("settings_changed", callable_mp(this, &TileMapEditor::_tileset_settings_changed));
+ }
_clear_bucket_cache();
}
void TileMapEditor::_tileset_settings_changed() {
-
_update_palette();
CanvasItemEditor::get_singleton()->update_viewport();
}
@@ -1816,7 +1753,6 @@ void TileMapEditor::_icon_size_changed(float p_value) {
}
void TileMapEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_fill_points"), &TileMapEditor::_fill_points);
ClassDB::bind_method(D_METHOD("_erase_points"), &TileMapEditor::_erase_points);
}
@@ -1825,12 +1761,15 @@ TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i &p_pos) {
CellOp op;
op.idx = node->get_cell(p_pos.x, p_pos.y);
if (op.idx != TileMap::INVALID_CELL) {
- if (node->is_cell_x_flipped(p_pos.x, p_pos.y))
+ if (node->is_cell_x_flipped(p_pos.x, p_pos.y)) {
op.xf = true;
- if (node->is_cell_y_flipped(p_pos.x, p_pos.y))
+ }
+ if (node->is_cell_y_flipped(p_pos.x, p_pos.y)) {
op.yf = true;
- if (node->is_cell_transposed(p_pos.x, p_pos.y))
+ }
+ if (node->is_cell_transposed(p_pos.x, p_pos.y)) {
op.tr = true;
+ }
op.ac = node->get_cell_autotile_coord(p_pos.x, p_pos.y);
}
return op;
@@ -1900,7 +1839,6 @@ void TileMapEditor::_clear_transform() {
}
TileMapEditor::TileMapEditor(EditorNode *p_editor) {
-
node = nullptr;
manual_autotile = false;
priority_atlastile = false;
@@ -2111,9 +2049,7 @@ TileMapEditor::~TileMapEditor() {
///////////////////////////////////////////////////////////////
void TileMapEditorPlugin::_notification(int p_what) {
-
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
-
switch ((int)EditorSettings::get_singleton()->get("editors/tile_map/editor_side")) {
case 0: { // Left.
CanvasItemEditor::get_singleton()->get_palette_split()->move_child(tile_map_editor, 0);
@@ -2126,19 +2062,15 @@ void TileMapEditorPlugin::_notification(int p_what) {
}
void TileMapEditorPlugin::edit(Object *p_object) {
-
tile_map_editor->edit(Object::cast_to<Node>(p_object));
}
bool TileMapEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("TileMap");
}
void TileMapEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
-
tile_map_editor->show();
tile_map_editor->get_toolbar()->show();
tile_map_editor->get_toolbar_right()->show();
@@ -2149,7 +2081,6 @@ void TileMapEditorPlugin::make_visible(bool p_visible) {
// Change to TOOL_SELECT when TileMap node is selected, to prevent accidental movement.
CanvasItemEditor::get_singleton()->set_current_tool(CanvasItemEditor::TOOL_SELECT);
} else {
-
tile_map_editor->hide();
tile_map_editor->get_toolbar()->hide();
tile_map_editor->get_toolbar_right()->hide();
@@ -2159,7 +2090,6 @@ void TileMapEditorPlugin::make_visible(bool p_visible) {
}
TileMapEditorPlugin::TileMapEditorPlugin(EditorNode *p_node) {
-
EDITOR_DEF("editors/tile_map/preview_size", 64);
EDITOR_DEF("editors/tile_map/palette_item_hseparation", 8);
EDITOR_DEF("editors/tile_map/show_tile_names", true);
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index f43e5bb5cb..5f82d7bfb8 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -33,7 +33,6 @@
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
-
#include "scene/2d/tile_map.h"
#include "scene/gui/check_box.h"
#include "scene/gui/label.h"
@@ -42,7 +41,6 @@
#include "scene/gui/tool_button.h"
class TileMapEditor : public VBoxContainer {
-
GDCLASS(TileMapEditor, VBoxContainer);
enum Tool {
@@ -127,34 +125,26 @@ class TileMapEditor : public VBoxContainer {
List<Point2i> bucket_queue;
struct CellOp {
- int idx;
- bool xf;
- bool yf;
- bool tr;
+ int idx = TileMap::INVALID_CELL;
+ bool xf = false;
+ bool yf = false;
+ bool tr = false;
Vector2 ac;
- CellOp() :
- idx(TileMap::INVALID_CELL),
- xf(false),
- yf(false),
- tr(false) {}
+ CellOp() {}
};
Map<Point2i, CellOp> paint_undo;
struct TileData {
Point2i pos;
- int cell;
- bool flip_h;
- bool flip_v;
- bool transpose;
+ int cell = TileMap::INVALID_CELL;
+ bool flip_h = false;
+ bool flip_v = false;
+ bool transpose = false;
Point2i autotile_coord;
- TileData() :
- cell(TileMap::INVALID_CELL),
- flip_h(false),
- flip_v(false),
- transpose(false) {}
+ TileData() {}
};
List<TileData> copydata;
@@ -230,7 +220,6 @@ public:
};
class TileMapEditorPlugin : public EditorPlugin {
-
GDCLASS(TileMapEditorPlugin, EditorPlugin);
TileMapEditor *tile_map_editor;
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index d1dda68c1d..644facd5bd 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -30,7 +30,7 @@
#include "tile_set_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/keyboard.h"
#include "editor/editor_scale.h"
#include "editor/plugins/canvas_item_editor_plugin.h"
@@ -38,7 +38,6 @@
#include "scene/2d/sprite_2d.h"
void TileSetEditor::edit(const Ref<TileSet> &p_tileset) {
-
tileset = p_tileset;
tileset->add_change_receptor(this);
@@ -48,9 +47,7 @@ void TileSetEditor::edit(const Ref<TileSet> &p_tileset) {
}
void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) {
-
for (int i = 0; i < p_node->get_child_count(); i++) {
-
Node *child = p_node->get_child(i);
if (!Object::cast_to<Sprite2D>(child)) {
@@ -66,12 +63,12 @@ void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) {
Ref<Texture2D> normal_map = mi->get_normal_map();
Ref<ShaderMaterial> material = mi->get_material();
- if (texture.is_null())
+ if (texture.is_null()) {
continue;
+ }
int id = p_library->find_tile_by_name(mi->get_name());
if (id < 0) {
-
id = p_library->get_last_unused_tile_id();
p_library->create_tile(id);
p_library->tile_set_name(id, mi->get_name());
@@ -106,17 +103,19 @@ void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) {
bool found_collisions = false;
for (int j = 0; j < mi->get_child_count(); j++) {
-
Node *child2 = mi->get_child(j);
- if (Object::cast_to<NavigationRegion2D>(child2))
+ if (Object::cast_to<NavigationRegion2D>(child2)) {
nav_poly = Object::cast_to<NavigationRegion2D>(child2)->get_navigation_polygon();
+ }
- if (Object::cast_to<LightOccluder2D>(child2))
+ if (Object::cast_to<LightOccluder2D>(child2)) {
occluder = Object::cast_to<LightOccluder2D>(child2)->get_occluder_polygon();
+ }
- if (!Object::cast_to<StaticBody2D>(child2))
+ if (!Object::cast_to<StaticBody2D>(child2)) {
continue;
+ }
found_collisions = true;
@@ -126,7 +125,9 @@ void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) {
sb->get_shape_owners(&shapes);
for (List<uint32_t>::Element *E = shapes.front(); E; E = E->next()) {
- if (sb->is_shape_owner_disabled(E->get())) continue;
+ if (sb->is_shape_owner_disabled(E->get())) {
+ continue;
+ }
Transform2D shape_transform = sb->get_transform() * sb->shape_owner_get_transform(E->get());
bool one_way = sb->is_shape_owner_one_way_collision_enabled(E->get());
@@ -134,7 +135,6 @@ void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) {
shape_transform[2] -= phys_offset;
for (int k = 0; k < sb->shape_owner_get_shape_count(E->get()); k++) {
-
Ref<Shape2D> shape = sb->shape_owner_get_shape(E->get(), k);
TileSet::ShapeData shape_data;
shape_data.shape = shape;
@@ -159,38 +159,36 @@ void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) {
}
void TileSetEditor::_import_scene(Node *p_scene, Ref<TileSet> p_library, bool p_merge) {
-
- if (!p_merge)
+ if (!p_merge) {
p_library->clear();
+ }
_import_node(p_scene, p_library);
}
void TileSetEditor::_undo_redo_import_scene(Node *p_scene, bool p_merge) {
-
_import_scene(p_scene, tileset, p_merge);
}
Error TileSetEditor::update_library_file(Node *p_base_scene, Ref<TileSet> ml, bool p_merge) {
-
_import_scene(p_base_scene, ml, p_merge);
return OK;
}
Variant TileSetEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
return false;
}
bool TileSetEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return false;
+ }
- if (d.has("from") && (Object *)(d["from"]) == texture_list)
+ if (d.has("from") && (Object *)(d["from"]) == texture_list) {
return false;
+ }
if (String(d["type"]) == "resource" && d.has("resource")) {
RES r = d["resource"];
@@ -198,17 +196,16 @@ bool TileSetEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_dat
Ref<Texture2D> texture = r;
if (texture.is_valid()) {
-
return true;
}
}
if (String(d["type"]) == "files") {
-
Vector<String> files = d["files"];
- if (files.size() == 0)
+ if (files.size() == 0) {
return false;
+ }
for (int i = 0; i < files.size(); i++) {
String file = files[i];
@@ -225,22 +222,24 @@ bool TileSetEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_dat
}
void TileSetEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
-
- if (!can_drop_data_fw(p_point, p_data, p_from))
+ if (!can_drop_data_fw(p_point, p_data, p_from)) {
return;
+ }
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return;
+ }
if (String(d["type"]) == "resource" && d.has("resource")) {
RES r = d["resource"];
Ref<Texture2D> texture = r;
- if (texture.is_valid())
+ if (texture.is_valid()) {
add_texture(texture);
+ }
if (texture_list->get_item_count() > 0) {
update_texture_list_icon();
@@ -250,7 +249,6 @@ void TileSetEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, C
}
if (String(d["type"]) == "files") {
-
Vector<String> files = d["files"];
_on_textures_added(files);
@@ -258,7 +256,6 @@ void TileSetEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, C
}
void TileSetEditor::_bind_methods() {
-
ClassDB::bind_method("_undo_redo_import_scene", &TileSetEditor::_undo_redo_import_scene);
ClassDB::bind_method("_on_workspace_process", &TileSetEditor::_on_workspace_process); // Still used by some connect_compat.
ClassDB::bind_method("_set_snap_step", &TileSetEditor::_set_snap_step);
@@ -280,15 +277,12 @@ void TileSetEditor::_bind_methods() {
}
void TileSetEditor::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_READY: {
-
add_theme_constant_override("autohide", 1); // Fixes the dragger always showing up.
} break;
case NOTIFICATION_ENTER_TREE:
case NOTIFICATION_THEME_CHANGED: {
-
tileset_toolbar_buttons[TOOL_TILESET_ADD_TEXTURE]->set_icon(get_theme_icon("ToolAddNode", "EditorIcons"));
tileset_toolbar_buttons[TOOL_TILESET_REMOVE_TEXTURE]->set_icon(get_theme_icon("Remove", "EditorIcons"));
tileset_toolbar_tools->set_icon(get_theme_icon("Tools", "EditorIcons"));
@@ -330,7 +324,6 @@ void TileSetEditor::_notification(int p_what) {
}
TileSetEditor::TileSetEditor(EditorNode *p_editor) {
-
editor = p_editor;
undo_redo = EditorNode::get_undo_redo();
current_tile = -1;
@@ -625,7 +618,6 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
ResourceLoader::get_recognized_extensions_for_type("Texture2D", &extensions);
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
-
texture_dialog->add_filter("*." + E->get() + " ; " + E->get().to_upper());
}
add_child(texture_dialog);
@@ -642,8 +634,9 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
}
TileSetEditor::~TileSetEditor() {
- if (helper)
+ if (helper) {
memdelete(helper);
+ }
}
void TileSetEditor::_on_tileset_toolbar_button_pressed(int p_index) {
@@ -662,12 +655,10 @@ void TileSetEditor::_on_tileset_toolbar_button_pressed(int p_index) {
}
} break;
case TOOL_TILESET_CREATE_SCENE: {
-
cd->set_text(TTR("Create from scene? This will overwrite all current tiles."));
cd->popup_centered(Size2(300, 60));
} break;
case TOOL_TILESET_MERGE_SCENE: {
-
cd->set_text(TTR("Merge from scene?"));
cd->popup_centered(Size2(300, 60));
} break;
@@ -695,11 +686,11 @@ void TileSetEditor::_on_tileset_toolbar_confirm() {
} break;
case TOOL_TILESET_MERGE_SCENE:
case TOOL_TILESET_CREATE_SCENE: {
-
EditorNode *en = editor;
Node *scene = en->get_edited_scene();
- if (!scene)
+ if (!scene) {
break;
+ }
List<int> ids;
tileset->get_tile_list(&ids);
@@ -894,9 +885,9 @@ void TileSetEditor::_on_workspace_mode_changed(int p_workspace_mode) {
}
void TileSetEditor::_on_workspace_draw() {
-
- if (tileset.is_null() || !get_current_texture().is_valid())
+ if (tileset.is_null() || !get_current_texture().is_valid()) {
return;
+ }
const Color COLOR_AUTOTILE = Color(0.3, 0.6, 1);
const Color COLOR_SINGLE = Color(1, 1, 0.3);
@@ -1055,12 +1046,13 @@ void TileSetEditor::_on_workspace_draw() {
Rect2i region = tileset->tile_get_region(t_id);
region.position += WORKSPACE_MARGIN;
Color c;
- if (tileset->tile_get_tile_mode(t_id) == TileSet::SINGLE_TILE)
+ if (tileset->tile_get_tile_mode(t_id) == TileSet::SINGLE_TILE) {
c = COLOR_SINGLE;
- else if (tileset->tile_get_tile_mode(t_id) == TileSet::AUTO_TILE)
+ } else if (tileset->tile_get_tile_mode(t_id) == TileSet::AUTO_TILE) {
c = COLOR_AUTOTILE;
- else if (tileset->tile_get_tile_mode(t_id) == TileSet::ATLAS_TILE)
+ } else if (tileset->tile_get_tile_mode(t_id) == TileSet::ATLAS_TILE) {
c = COLOR_ATLAS;
+ }
draw_tile_subdivision(t_id, COLOR_SUBDIVISION);
workspace->draw_rect(region, c, false);
}
@@ -1071,39 +1063,43 @@ void TileSetEditor::_on_workspace_draw() {
if (workspace_mode != WORKSPACE_EDIT) {
Rect2i region = edited_region;
Color c;
- if (workspace_mode == WORKSPACE_CREATE_SINGLE)
+ if (workspace_mode == WORKSPACE_CREATE_SINGLE) {
c = COLOR_SINGLE;
- else if (workspace_mode == WORKSPACE_CREATE_AUTOTILE)
+ } else if (workspace_mode == WORKSPACE_CREATE_AUTOTILE) {
c = COLOR_AUTOTILE;
- else if (workspace_mode == WORKSPACE_CREATE_ATLAS)
+ } else if (workspace_mode == WORKSPACE_CREATE_ATLAS) {
c = COLOR_ATLAS;
+ }
workspace->draw_rect(region, c, false);
draw_edited_region_subdivision();
} else {
int t_id = get_current_tile();
- if (t_id < 0)
+ if (t_id < 0) {
return;
+ }
Rect2i region;
- if (draw_edited_region)
+ if (draw_edited_region) {
region = edited_region;
- else {
+ } else {
region = tileset->tile_get_region(t_id);
region.position += WORKSPACE_MARGIN;
}
- if (draw_edited_region)
+ if (draw_edited_region) {
draw_edited_region_subdivision();
- else
+ } else {
draw_tile_subdivision(t_id, COLOR_SUBDIVISION);
+ }
Color c;
- if (tileset->tile_get_tile_mode(t_id) == TileSet::SINGLE_TILE)
+ if (tileset->tile_get_tile_mode(t_id) == TileSet::SINGLE_TILE) {
c = COLOR_SINGLE;
- else if (tileset->tile_get_tile_mode(t_id) == TileSet::AUTO_TILE)
+ } else if (tileset->tile_get_tile_mode(t_id) == TileSet::AUTO_TILE) {
c = COLOR_AUTOTILE;
- else if (tileset->tile_get_tile_mode(t_id) == TileSet::ATLAS_TILE)
+ } else if (tileset->tile_get_tile_mode(t_id) == TileSet::ATLAS_TILE) {
c = COLOR_ATLAS;
+ }
workspace->draw_rect(region, c, false);
}
}
@@ -1112,8 +1108,7 @@ void TileSetEditor::_on_workspace_draw() {
}
void TileSetEditor::_on_workspace_process() {
-
- if (InputFilter::get_singleton()->is_key_pressed(KEY_ALT) || tools[VISIBLE_INFO]->is_pressed()) {
+ if (Input::get_singleton()->is_key_pressed(KEY_ALT) || tools[VISIBLE_INFO]->is_pressed()) {
if (!tile_names_visible) {
tile_names_visible = true;
workspace_overlay->update();
@@ -1125,9 +1120,9 @@ void TileSetEditor::_on_workspace_process() {
}
void TileSetEditor::_on_workspace_overlay_draw() {
-
- if (!tileset.is_valid() || !get_current_texture().is_valid())
+ if (!tileset.is_valid() || !get_current_texture().is_valid()) {
return;
+ }
const Color COLOR_AUTOTILE = Color(0.266373, 0.565288, 0.988281);
const Color COLOR_SINGLE = Color(0.988281, 0.909323, 0.266373);
@@ -1139,19 +1134,21 @@ void TileSetEditor::_on_workspace_overlay_draw() {
tileset->get_tile_list(tiles);
for (List<int>::Element *E = tiles->front(); E; E = E->next()) {
int t_id = E->get();
- if (tileset->tile_get_texture(t_id)->get_rid() != current_texture_rid)
+ if (tileset->tile_get_texture(t_id)->get_rid() != current_texture_rid) {
continue;
+ }
Rect2 region = tileset->tile_get_region(t_id);
region.position += WORKSPACE_MARGIN;
region.position *= workspace->get_scale().x;
Color c;
- if (tileset->tile_get_tile_mode(t_id) == TileSet::SINGLE_TILE)
+ if (tileset->tile_get_tile_mode(t_id) == TileSet::SINGLE_TILE) {
c = COLOR_SINGLE;
- else if (tileset->tile_get_tile_mode(t_id) == TileSet::AUTO_TILE)
+ } else if (tileset->tile_get_tile_mode(t_id) == TileSet::AUTO_TILE) {
c = COLOR_AUTOTILE;
- else if (tileset->tile_get_tile_mode(t_id) == TileSet::ATLAS_TILE)
+ } else if (tileset->tile_get_tile_mode(t_id) == TileSet::ATLAS_TILE) {
c = COLOR_ATLAS;
+ }
String tile_id_name = String::num(t_id, 0) + ": " + tileset->tile_get_name(t_id);
Ref<Font> font = get_theme_font("font", "Label");
region.set_size(font->get_string_size(tile_id_name));
@@ -1164,8 +1161,9 @@ void TileSetEditor::_on_workspace_overlay_draw() {
}
int t_id = get_current_tile();
- if (t_id < 0)
+ if (t_id < 0) {
return;
+ }
Ref<Texture2D> handle = get_theme_icon("EditorHandle", "EditorIcons");
if (draw_handles) {
@@ -1201,9 +1199,9 @@ bool TileSetEditor::is_within_grabbing_distance_of_first_point(const Vector2 &p_
}
void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
-
- if (tileset.is_null() || !get_current_texture().is_valid())
+ if (tileset.is_null() || !get_current_texture().is_valid()) {
return;
+ }
static bool dragging;
static bool erasing;
@@ -1395,7 +1393,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
if ((mb->get_button_index() == BUTTON_RIGHT || mb->get_button_index() == BUTTON_LEFT) && current_tile_region.has_point(mb->get_position())) {
dragging = true;
erasing = (mb->get_button_index() == BUTTON_RIGHT);
- alternative = InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT);
+ alternative = Input::get_singleton()->is_key_pressed(KEY_SHIFT);
Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
Vector2 pos(coord.x * (spacing + size.x), coord.y * (spacing + size.y));
pos = mb->get_position() - (pos + current_tile_region.position);
@@ -1657,7 +1655,6 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
pos = snap_point(pos);
if (creating_shape) {
if (current_shape.size() > 2) {
-
if (is_within_grabbing_distance_of_first_point(mb->get_position(), grab_threshold)) {
close_shape(shape_anchor);
workspace->update();
@@ -1707,7 +1704,6 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
} else if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
if (creating_shape) {
-
// if the first two corners are within grabbing distance of one another, expand the rect to fill the tile
if (is_within_grabbing_distance_of_first_point(current_shape[1], grab_threshold)) {
current_shape.set(0, snap_point(shape_anchor));
@@ -1908,8 +1904,9 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
}
void TileSetEditor::_on_priority_changed(float val) {
- if ((int)val == tileset->autotile_get_subtile_priority(get_current_tile(), edited_shape_coord))
+ if ((int)val == tileset->autotile_get_subtile_priority(get_current_tile(), edited_shape_coord)) {
return;
+ }
undo_redo->create_action(TTR("Edit Tile Priority"));
undo_redo->add_do_method(tileset.ptr(), "autotile_set_subtile_priority", get_current_tile(), edited_shape_coord, (int)val);
@@ -1920,8 +1917,9 @@ void TileSetEditor::_on_priority_changed(float val) {
}
void TileSetEditor::_on_z_index_changed(float val) {
- if ((int)val == tileset->autotile_get_z_index(get_current_tile(), edited_shape_coord))
+ if ((int)val == tileset->autotile_get_z_index(get_current_tile(), edited_shape_coord)) {
return;
+ }
undo_redo->create_action(TTR("Edit Tile Z Index"));
undo_redo->add_do_method(tileset.ptr(), "autotile_set_z_index", get_current_tile(), edited_shape_coord, (int)val);
@@ -1977,8 +1975,9 @@ void TileSetEditor::_set_edited_shape_points(const Vector<Vector2> &points) {
void TileSetEditor::_update_tile_data() {
current_tile_data.clear();
- if (get_current_tile() < 0)
+ if (get_current_tile() < 0) {
return;
+ }
Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(get_current_tile());
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
@@ -2322,8 +2321,9 @@ void TileSetEditor::_set_snap_sep(Vector2 p_val) {
}
void TileSetEditor::_validate_current_tile_id() {
- if (get_current_tile() >= 0 && !tileset->has_tile(get_current_tile()))
+ if (get_current_tile() >= 0 && !tileset->has_tile(get_current_tile())) {
set_current_tile(-1);
+ }
}
void TileSetEditor::_select_edited_shape_coord() {
@@ -2387,6 +2387,7 @@ void TileSetEditor::_zoom_in() {
workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
}
}
+
void TileSetEditor::_zoom_out() {
float scale = workspace->get_scale().x;
if (scale > min_scale) {
@@ -2396,6 +2397,7 @@ void TileSetEditor::_zoom_out() {
workspace_overlay->set_custom_minimum_size(workspace->get_rect().size * scale);
}
}
+
void TileSetEditor::_zoom_reset() {
workspace->set_scale(Vector2(1, 1));
workspace_container->set_custom_minimum_size(workspace->get_rect().size);
@@ -2403,7 +2405,6 @@ void TileSetEditor::_zoom_reset() {
}
void TileSetEditor::draw_highlight_current_tile() {
-
Color shadow_color = Color(0.3, 0.3, 0.3, 0.3);
if ((workspace_mode == WORKSPACE_EDIT && get_current_tile() >= 0) || !edited_region.has_no_area()) {
Rect2 region;
@@ -2414,21 +2415,24 @@ void TileSetEditor::draw_highlight_current_tile() {
region = edited_region;
}
- if (region.position.y >= 0)
+ if (region.position.y >= 0) {
workspace->draw_rect(Rect2(0, 0, workspace->get_rect().size.x, region.position.y), shadow_color);
- if (region.position.x >= 0)
+ }
+ if (region.position.x >= 0) {
workspace->draw_rect(Rect2(0, MAX(0, region.position.y), region.position.x, MIN(workspace->get_rect().size.y - region.position.y, MIN(region.size.y, region.position.y + region.size.y))), shadow_color);
- if (region.position.x + region.size.x <= workspace->get_rect().size.x)
+ }
+ if (region.position.x + region.size.x <= workspace->get_rect().size.x) {
workspace->draw_rect(Rect2(region.position.x + region.size.x, MAX(0, region.position.y), workspace->get_rect().size.x - region.position.x - region.size.x, MIN(workspace->get_rect().size.y - region.position.y, MIN(region.size.y, region.position.y + region.size.y))), shadow_color);
- if (region.position.y + region.size.y <= workspace->get_rect().size.y)
+ }
+ if (region.position.y + region.size.y <= workspace->get_rect().size.y) {
workspace->draw_rect(Rect2(0, region.position.y + region.size.y, workspace->get_rect().size.x, workspace->get_rect().size.y - region.size.y - region.position.y), shadow_color);
+ }
} else {
workspace->draw_rect(Rect2(Point2(0, 0), workspace->get_rect().size), shadow_color);
}
}
void TileSetEditor::draw_highlight_subtile(Vector2 coord, const Vector<Vector2> &other_highlighted) {
-
Color shadow_color = Color(0.3, 0.3, 0.3, 0.3);
Vector2 size = tileset->autotile_get_size(get_current_tile());
int spacing = tileset->autotile_get_spacing(get_current_tile());
@@ -2438,14 +2442,18 @@ void TileSetEditor::draw_highlight_subtile(Vector2 coord, const Vector<Vector2>
coord += region.position;
coord += WORKSPACE_MARGIN;
- if (coord.y >= 0)
+ if (coord.y >= 0) {
workspace->draw_rect(Rect2(0, 0, workspace->get_rect().size.x, coord.y), shadow_color);
- if (coord.x >= 0)
+ }
+ if (coord.x >= 0) {
workspace->draw_rect(Rect2(0, MAX(0, coord.y), coord.x, MIN(workspace->get_rect().size.y - coord.y, MIN(size.y, coord.y + size.y))), shadow_color);
- if (coord.x + size.x <= workspace->get_rect().size.x)
+ }
+ if (coord.x + size.x <= workspace->get_rect().size.x) {
workspace->draw_rect(Rect2(coord.x + size.x, MAX(0, coord.y), workspace->get_rect().size.x - coord.x - size.x, MIN(workspace->get_rect().size.y - coord.y, MIN(size.y, coord.y + size.y))), shadow_color);
- if (coord.y + size.y <= workspace->get_rect().size.y)
+ }
+ if (coord.y + size.y <= workspace->get_rect().size.y) {
workspace->draw_rect(Rect2(0, coord.y + size.y, workspace->get_rect().size.x, workspace->get_rect().size.y - size.y - coord.y), shadow_color);
+ }
coord += Vector2(1, 1) / workspace->get_scale().x;
workspace->draw_rect(Rect2(coord, size - Vector2(2, 2) / workspace->get_scale().x), Color(1, 0, 0), false);
@@ -2578,10 +2586,10 @@ void TileSetEditor::draw_grid_snap() {
}
void TileSetEditor::draw_polygon_shapes() {
-
int t_id = get_current_tile();
- if (t_id < 0)
+ if (t_id < 0) {
return;
+ }
switch (edit_mode) {
case EDITMODE_COLLISION: {
@@ -2637,8 +2645,9 @@ void TileSetEditor::draw_polygon_shapes() {
}
}
- if (polygon.size() < 3)
+ if (polygon.size() < 3) {
continue;
+ }
workspace->draw_polygon(polygon, colors);
@@ -2847,7 +2856,6 @@ void TileSetEditor::draw_polygon_shapes() {
}
void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
-
creating_shape = false;
if (edit_mode == EDITMODE_COLLISION) {
@@ -2860,14 +2868,16 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
for (int i = 0; i < current_shape.size(); i++) {
points.push_back(current_shape[i] - shape_anchor);
- if (i != current_shape.size() - 1)
+ if (i != current_shape.size() - 1) {
p_total += ((current_shape[i + 1].x - current_shape[i].x) * (-current_shape[i + 1].y + (-current_shape[i].y)));
- else
+ } else {
p_total += ((current_shape[0].x - current_shape[i].x) * (-current_shape[0].y + (-current_shape[i].y)));
+ }
}
- if (p_total < 0)
+ if (p_total < 0) {
points.invert();
+ }
shape->set_points(points);
@@ -2882,10 +2892,11 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
}
}
undo_redo->add_do_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd);
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE)
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
undo_redo->add_do_method(tileset.ptr(), "tile_add_shape", get_current_tile(), shape, Transform2D(), false, edited_shape_coord);
- else
+ } else {
undo_redo->add_do_method(tileset.ptr(), "tile_add_shape", get_current_tile(), shape, Transform2D());
+ }
tools[TOOL_SELECT]->set_pressed(true);
undo_redo->add_do_method(this, "_select_edited_shape_coord");
undo_redo->add_undo_method(this, "_select_edited_shape_coord");
@@ -2954,17 +2965,21 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
void TileSetEditor::select_coord(const Vector2 &coord) {
_update_tile_data();
current_shape = PackedVector2Array();
- if (get_current_tile() == -1)
+ if (get_current_tile() == -1) {
return;
+ }
Rect2 current_tile_region = tileset->tile_get_region(get_current_tile());
current_tile_region.position += WORKSPACE_MARGIN;
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
- if (edited_collision_shape != tileset->tile_get_shape(get_current_tile(), 0))
+ if (edited_collision_shape != tileset->tile_get_shape(get_current_tile(), 0)) {
_set_edited_collision_shape(tileset->tile_get_shape(get_current_tile(), 0));
- if (edited_occlusion_shape != tileset->tile_get_light_occluder(get_current_tile()))
+ }
+ if (edited_occlusion_shape != tileset->tile_get_light_occluder(get_current_tile())) {
edited_occlusion_shape = tileset->tile_get_light_occluder(get_current_tile());
- if (edited_navigation_shape != tileset->tile_get_navigation_polygon(get_current_tile()))
+ }
+ if (edited_navigation_shape != tileset->tile_get_navigation_polygon(get_current_tile())) {
edited_navigation_shape = tileset->tile_get_navigation_polygon(get_current_tile());
+ }
if (edit_mode == EDITMODE_COLLISION) {
current_shape.resize(0);
@@ -2996,18 +3011,22 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
bool found_collision_shape = false;
for (int i = 0; i < sd.size(); i++) {
if (sd[i].autotile_coord == coord) {
- if (edited_collision_shape != sd[i].shape)
+ if (edited_collision_shape != sd[i].shape) {
_set_edited_collision_shape(sd[i].shape);
+ }
found_collision_shape = true;
break;
}
}
- if (!found_collision_shape)
+ if (!found_collision_shape) {
_set_edited_collision_shape(Ref<ConvexPolygonShape2D>(nullptr));
- if (edited_occlusion_shape != tileset->autotile_get_light_occluder(get_current_tile(), coord))
+ }
+ if (edited_occlusion_shape != tileset->autotile_get_light_occluder(get_current_tile(), coord)) {
edited_occlusion_shape = tileset->autotile_get_light_occluder(get_current_tile(), coord);
- if (edited_navigation_shape != tileset->autotile_get_navigation_polygon(get_current_tile(), coord))
+ }
+ if (edited_navigation_shape != tileset->autotile_get_navigation_polygon(get_current_tile(), coord)) {
edited_navigation_shape = tileset->autotile_get_navigation_polygon(get_current_tile(), coord);
+ }
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->autotile_get_size(get_current_tile());
@@ -3067,14 +3086,18 @@ Vector2 TileSetEditor::snap_point(const Vector2 &point) {
p.y = Math::snap_scalar_separation(snap_offset.y, snap_step.y, p.y, snap_separation.y);
}
if (tools[SHAPE_KEEP_INSIDE_TILE]->is_pressed()) {
- if (p.x < region.position.x)
+ if (p.x < region.position.x) {
p.x = region.position.x;
- if (p.y < region.position.y)
+ }
+ if (p.y < region.position.y) {
p.y = region.position.y;
- if (p.x > region.position.x + region.size.x)
+ }
+ if (p.x > region.position.x + region.size.x) {
p.x = region.position.x + region.size.x;
- if (p.y > region.position.y + region.size.y)
+ }
+ if (p.y > region.position.y + region.size.y) {
p.y = region.position.y + region.size.y;
+ }
}
return p;
}
@@ -3122,8 +3145,9 @@ void TileSetEditor::update_texture_list() {
if (texture_list->get_item_count() > 0 && selected_texture.is_valid()) {
texture_list->select(texture_list->find_metadata(selected_texture->get_rid()));
- if (texture_list->get_selected_items().size() > 0)
+ if (texture_list->get_selected_items().size() > 0) {
_on_texture_list_selected(texture_list->get_selected_items()[0]);
+ }
} else if (get_current_texture().is_valid()) {
_on_texture_list_selected(texture_list->find_metadata(get_current_texture()->get_rid()));
} else {
@@ -3136,7 +3160,6 @@ void TileSetEditor::update_texture_list() {
}
void TileSetEditor::update_texture_list_icon() {
-
for (int current_idx = 0; current_idx < texture_list->get_item_count(); current_idx++) {
RID rid = texture_list->get_item_metadata(current_idx);
texture_list->set_item_icon(current_idx, texture_map[rid]);
@@ -3147,7 +3170,6 @@ void TileSetEditor::update_texture_list_icon() {
}
void TileSetEditor::update_workspace_tile_mode() {
-
if (!get_current_texture().is_valid()) {
tool_workspacemode[WORKSPACE_EDIT]->set_pressed(true);
workspace_mode = WORKSPACE_EDIT;
@@ -3223,19 +3245,21 @@ void TileSetEditor::update_workspace_tile_mode() {
tool_editmode[EDITMODE_PRIORITY]->hide();
tool_editmode[EDITMODE_Z_INDEX]->hide();
} else if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE) {
- if (edit_mode == EDITMODE_ICON)
+ if (edit_mode == EDITMODE_ICON) {
select_coord(tileset->autotile_get_icon_coordinate(get_current_tile()));
- else
+ } else {
_select_edited_shape_coord();
+ }
} else if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
if (tool_editmode[EDITMODE_PRIORITY]->is_pressed() || tool_editmode[EDITMODE_BITMASK]->is_pressed()) {
tool_editmode[EDITMODE_COLLISION]->set_pressed(true);
edit_mode = EDITMODE_COLLISION;
}
- if (edit_mode == EDITMODE_ICON)
+ if (edit_mode == EDITMODE_ICON) {
select_coord(tileset->autotile_get_icon_coordinate(get_current_tile()));
- else
+ } else {
_select_edited_shape_coord();
+ }
tool_editmode[EDITMODE_BITMASK]->hide();
}
@@ -3308,14 +3332,14 @@ void TileSetEditor::set_current_tile(int p_id) {
}
Ref<Texture2D> TileSetEditor::get_current_texture() {
- if (texture_list->get_selected_items().size() == 0)
+ if (texture_list->get_selected_items().size() == 0) {
return Ref<Texture2D>();
- else
+ } else {
return texture_map[texture_list->get_item_metadata(texture_list->get_selected_items()[0])];
+ }
}
void TilesetEditorContext::set_tileset(const Ref<TileSet> &p_tileset) {
-
tileset = p_tileset;
}
@@ -3325,7 +3349,6 @@ void TilesetEditorContext::set_snap_options_visible(bool p_visible) {
}
bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name.operator String();
if (name == "options_offset") {
@@ -3344,8 +3367,9 @@ bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value
String name2 = p_name.operator String().right(5);
bool v = false;
- if (tileset_editor->get_current_tile() < 0 || tileset.is_null())
+ if (tileset_editor->get_current_tile() < 0 || tileset.is_null()) {
return false;
+ }
if (name2 == "autotile_bitmask_mode") {
tileset->set(String::num(tileset_editor->get_current_tile(), 0) + "/autotile/bitmask_mode", p_value, &v);
@@ -3391,7 +3415,6 @@ bool TilesetEditorContext::_set(const StringName &p_name, const Variant &p_value
}
bool TilesetEditorContext::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name.operator String();
bool v = false;
@@ -3407,10 +3430,12 @@ bool TilesetEditorContext::_get(const StringName &p_name, Variant &r_ret) const
} else if (name.left(5) == "tile_") {
name = name.right(5);
- if (tileset_editor->get_current_tile() < 0 || tileset.is_null())
+ if (tileset_editor->get_current_tile() < 0 || tileset.is_null()) {
return false;
- if (!tileset->has_tile(tileset_editor->get_current_tile()))
+ }
+ if (!tileset->has_tile(tileset_editor->get_current_tile())) {
return false;
+ }
if (name == "autotile_bitmask_mode") {
r_ret = tileset->get(String::num(tileset_editor->get_current_tile(), 0) + "/autotile/bitmask_mode", &v);
@@ -3457,7 +3482,6 @@ bool TilesetEditorContext::_get(const StringName &p_name, Variant &r_ret) const
}
void TilesetEditorContext::_get_property_list(List<PropertyInfo> *p_list) const {
-
if (snap_options_visible) {
p_list->push_back(PropertyInfo(Variant::NIL, "Snap Options", PROPERTY_HINT_NONE, "options_", PROPERTY_USAGE_GROUP));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "options_offset"));
@@ -3506,25 +3530,21 @@ void TilesetEditorContext::_get_property_list(List<PropertyInfo> *p_list) const
}
void TilesetEditorContext::_bind_methods() {
-
ClassDB::bind_method("_hide_script_from_inspector", &TilesetEditorContext::_hide_script_from_inspector);
}
TilesetEditorContext::TilesetEditorContext(TileSetEditor *p_tileset_editor) {
-
tileset_editor = p_tileset_editor;
snap_options_visible = false;
}
void TileSetEditorPlugin::edit(Object *p_node) {
-
if (Object::cast_to<TileSet>(p_node)) {
tileset_editor->edit(Object::cast_to<TileSet>(p_node));
}
}
bool TileSetEditorPlugin::handles(Object *p_node) const {
-
return p_node->is_class("TileSet") || p_node->is_class("TilesetEditorContext");
}
@@ -3541,7 +3561,6 @@ void TileSetEditorPlugin::make_visible(bool p_visible) {
}
Dictionary TileSetEditorPlugin::get_state() const {
-
Dictionary state;
state["snap_offset"] = tileset_editor->snap_offset;
state["snap_step"] = tileset_editor->snap_step;
@@ -3553,7 +3572,6 @@ Dictionary TileSetEditorPlugin::get_state() const {
}
void TileSetEditorPlugin::set_state(const Dictionary &p_state) {
-
Dictionary state = p_state;
if (state.has("snap_step")) {
tileset_editor->_set_snap_step(state["snap_step"]);
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index 53f8e8c4d6..827325cfd7 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -41,7 +41,6 @@
class TilesetEditorContext;
class TileSetEditor : public HSplitContainer {
-
friend class TileSetEditorPlugin;
friend class TilesetEditorContext;
@@ -252,7 +251,6 @@ private:
};
class TilesetEditorContext : public Object {
-
friend class TileSetEditor;
GDCLASS(TilesetEditorContext, Object);
@@ -278,7 +276,6 @@ public:
};
class TileSetEditorPlugin : public EditorPlugin {
-
GDCLASS(TileSetEditorPlugin, EditorPlugin);
TileSetEditor *tileset_editor;
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index fe8392593b..a1436e123d 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -38,7 +38,6 @@
VersionControlEditorPlugin *VersionControlEditorPlugin::singleton = nullptr;
void VersionControlEditorPlugin::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("popup_vcs_set_up_dialog"), &VersionControlEditorPlugin::popup_vcs_set_up_dialog);
// Used to track the status of files in the staging area
@@ -50,20 +49,16 @@ void VersionControlEditorPlugin::_bind_methods() {
}
void VersionControlEditorPlugin::_selected_a_vcs(int p_id) {
-
List<StringName> available_addons = get_available_vcs_names();
const StringName selected_vcs = set_up_choice->get_item_text(p_id);
}
void VersionControlEditorPlugin::_populate_available_vcs_names() {
-
static bool called = false;
if (!called) {
-
List<StringName> available_addons = get_available_vcs_names();
for (int i = 0; i < available_addons.size(); i++) {
-
set_up_choice->add_item(available_addons[i]);
}
@@ -72,16 +67,13 @@ void VersionControlEditorPlugin::_populate_available_vcs_names() {
}
VersionControlEditorPlugin *VersionControlEditorPlugin::get_singleton() {
-
return singleton ? singleton : memnew(VersionControlEditorPlugin);
}
void VersionControlEditorPlugin::popup_vcs_set_up_dialog(const Control *p_gui_base) {
-
fetch_available_vcs_addon_names();
List<StringName> available_addons = get_available_vcs_names();
if (available_addons.size() >= 1) {
-
Size2 popup_size = Size2(400, 100);
Size2 window_size = p_gui_base->get_viewport_rect().size;
popup_size.x = MIN(window_size.x * 0.5, popup_size.x);
@@ -91,13 +83,11 @@ void VersionControlEditorPlugin::popup_vcs_set_up_dialog(const Control *p_gui_ba
set_up_dialog->popup_centered_clamped(popup_size * EDSCALE);
} else {
-
EditorNode::get_singleton()->show_warning(TTR("No VCS addons are available."), TTR("Error"));
}
}
void VersionControlEditorPlugin::_initialize_vcs() {
-
register_editor();
ERR_FAIL_COND_MSG(EditorVCSInterface::get_singleton(), EditorVCSInterface::get_singleton()->get_vcs_name() + " is already active");
@@ -129,18 +119,14 @@ void VersionControlEditorPlugin::_initialize_vcs() {
}
void VersionControlEditorPlugin::_send_commit_msg() {
-
String msg = commit_message->get_text();
if (msg == "") {
-
commit_status->set_text(TTR("No commit message was provided"));
return;
}
if (EditorVCSInterface::get_singleton()) {
-
if (staged_files_count == 0) {
-
commit_status->set_text(TTR("No files added to stage"));
return;
}
@@ -150,7 +136,6 @@ void VersionControlEditorPlugin::_send_commit_msg() {
commit_message->set_text("");
version_control_dock_button->set_pressed(false);
} else {
-
WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu");
}
@@ -160,20 +145,16 @@ void VersionControlEditorPlugin::_send_commit_msg() {
}
void VersionControlEditorPlugin::_refresh_stage_area() {
-
if (EditorVCSInterface::get_singleton()) {
-
staged_files_count = 0;
clear_stage_area();
Dictionary modified_file_paths = EditorVCSInterface::get_singleton()->get_modified_files_data();
String file_path;
for (int i = 0; i < modified_file_paths.size(); i++) {
-
file_path = modified_file_paths.get_key_at_index(i);
TreeItem *found = stage_files->search_item_text(file_path, nullptr, true);
if (!found) {
-
ChangeType change_index = (ChangeType)(int)modified_file_paths.get_value_at_index(i);
String change_text = file_path + " (" + change_type_to_strings[change_index] + ")";
Color &change_color = change_type_to_color[change_index];
@@ -185,24 +166,19 @@ void VersionControlEditorPlugin::_refresh_stage_area() {
new_item->set_checked(0, true);
new_item->set_editable(0, true);
} else {
-
if (found->get_metadata(0) == diff_file_name->get_text()) {
-
_refresh_file_diff();
}
}
commit_status->set_text("New changes detected");
}
} else {
-
WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu.");
}
}
void VersionControlEditorPlugin::_stage_selected() {
-
if (!EditorVCSInterface::get_singleton()) {
-
WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu");
return;
}
@@ -210,17 +186,13 @@ void VersionControlEditorPlugin::_stage_selected() {
staged_files_count = 0;
TreeItem *root = stage_files->get_root();
if (root) {
-
TreeItem *file_entry = root->get_children();
while (file_entry) {
-
if (file_entry->is_checked(0)) {
-
EditorVCSInterface::get_singleton()->stage_file(file_entry->get_metadata(0));
file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_theme_color("success_color", "Editor"));
staged_files_count++;
} else {
-
EditorVCSInterface::get_singleton()->unstage_file(file_entry->get_metadata(0));
file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_theme_color("error_color", "Editor"));
}
@@ -233,9 +205,7 @@ void VersionControlEditorPlugin::_stage_selected() {
}
void VersionControlEditorPlugin::_stage_all() {
-
if (!EditorVCSInterface::get_singleton()) {
-
WARN_PRINT("No VCS addon is initialized. Select a Version Control Addon from Project menu");
return;
}
@@ -243,10 +213,8 @@ void VersionControlEditorPlugin::_stage_all() {
staged_files_count = 0;
TreeItem *root = stage_files->get_root();
if (root) {
-
TreeItem *file_entry = root->get_children();
while (file_entry) {
-
EditorVCSInterface::get_singleton()->stage_file(file_entry->get_metadata(0));
file_entry->set_icon_modulate(0, EditorNode::get_singleton()->get_gui_base()->get_theme_color("success_color", "Editor"));
file_entry->set_checked(0, true);
@@ -260,7 +228,6 @@ void VersionControlEditorPlugin::_stage_all() {
}
void VersionControlEditorPlugin::_view_file_diff() {
-
version_control_dock_button->set_pressed(true);
String file_path = stage_files->get_selected()->get_metadata(0);
@@ -269,7 +236,6 @@ void VersionControlEditorPlugin::_view_file_diff() {
}
void VersionControlEditorPlugin::_display_file_diff(String p_file_path) {
-
Array diff_content = EditorVCSInterface::get_singleton()->get_file_diff(p_file_path);
diff_file_name->set_text(p_file_path);
@@ -277,17 +243,13 @@ void VersionControlEditorPlugin::_display_file_diff(String p_file_path) {
diff->clear();
diff->push_font(EditorNode::get_singleton()->get_gui_base()->get_theme_font("source", "EditorFonts"));
for (int i = 0; i < diff_content.size(); i++) {
-
Dictionary line_result = diff_content[i];
if (line_result["status"] == "+") {
-
diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color("success_color", "Editor"));
} else if (line_result["status"] == "-") {
-
diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color("error_color", "Editor"));
} else {
-
diff->push_color(EditorNode::get_singleton()->get_gui_base()->get_theme_color("font_color", "Label"));
}
@@ -299,42 +261,33 @@ void VersionControlEditorPlugin::_display_file_diff(String p_file_path) {
}
void VersionControlEditorPlugin::_refresh_file_diff() {
-
String open_file = diff_file_name->get_text();
if (open_file != "") {
-
_display_file_diff(diff_file_name->get_text());
}
}
void VersionControlEditorPlugin::_clear_file_diff() {
-
diff->clear();
diff_file_name->set_text("");
version_control_dock_button->set_pressed(false);
}
void VersionControlEditorPlugin::_update_stage_status() {
-
String status;
if (staged_files_count == 1) {
-
status = "Stage contains 1 file";
} else {
-
status = "Stage contains " + String::num_int64(staged_files_count) + " files";
}
commit_status->set_text(status);
}
void VersionControlEditorPlugin::_update_commit_status() {
-
String status;
if (staged_files_count == 1) {
-
status = "Committed 1 file";
} else {
-
status = "Committed " + String::num_int64(staged_files_count) + " files ";
}
commit_status->set_text(status);
@@ -342,9 +295,7 @@ void VersionControlEditorPlugin::_update_commit_status() {
}
void VersionControlEditorPlugin::register_editor() {
-
if (!EditorVCSInterface::get_singleton()) {
-
EditorNode::get_singleton()->add_control_to_dock(EditorNode::DOCK_SLOT_RIGHT_UL, version_commit_dock);
TabContainer *dock_vbc = (TabContainer *)version_commit_dock->get_parent_control();
dock_vbc->set_tab_title(version_commit_dock->get_index(), TTR("Commit"));
@@ -355,30 +306,25 @@ void VersionControlEditorPlugin::register_editor() {
}
void VersionControlEditorPlugin::fetch_available_vcs_addon_names() {
-
List<StringName> global_classes;
ScriptServer::get_global_class_list(&global_classes);
for (int i = 0; i != global_classes.size(); i++) {
-
String path = ScriptServer::get_global_class_path(global_classes[i]);
Ref<Script> script = ResourceLoader::load(path);
ERR_FAIL_COND(script.is_null());
if (script->get_instance_base_type() == "EditorVCSInterface") {
-
available_addons.push_back(global_classes[i]);
}
}
}
void VersionControlEditorPlugin::clear_stage_area() {
-
stage_files->get_root()->clear_children();
}
void VersionControlEditorPlugin::shut_down() {
-
if (EditorVCSInterface::get_singleton()) {
if (EditorFileSystem::get_singleton()->is_connected("filesystem_changed", callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area))) {
EditorFileSystem::get_singleton()->disconnect("filesystem_changed", callable_mp(this, &VersionControlEditorPlugin::_refresh_stage_area));
@@ -393,17 +339,14 @@ void VersionControlEditorPlugin::shut_down() {
}
bool VersionControlEditorPlugin::is_vcs_initialized() const {
-
return EditorVCSInterface::get_singleton() ? EditorVCSInterface::get_singleton()->is_vcs_initialized() : false;
}
const String VersionControlEditorPlugin::get_vcs_name() const {
-
return EditorVCSInterface::get_singleton() ? EditorVCSInterface::get_singleton()->get_vcs_name() : "";
}
VersionControlEditorPlugin::VersionControlEditorPlugin() {
-
singleton = this;
staged_files_count = 0;
@@ -570,7 +513,6 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
}
VersionControlEditorPlugin::~VersionControlEditorPlugin() {
-
shut_down();
memdelete(version_control_dock);
memdelete(version_commit_dock);
diff --git a/editor/plugins/version_control_editor_plugin.h b/editor/plugins/version_control_editor_plugin.h
index 4a98c8580e..664e38d65f 100644
--- a/editor/plugins/version_control_editor_plugin.h
+++ b/editor/plugins/version_control_editor_plugin.h
@@ -39,7 +39,6 @@
#include "scene/gui/tree.h"
class VersionControlEditorPlugin : public EditorPlugin {
-
GDCLASS(VersionControlEditorPlugin, EditorPlugin)
public:
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index d5128db0d5..92bdba93e7 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -30,7 +30,7 @@
#include "visual_shader_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/resource_loader.h"
#include "core/math/math_defs.h"
#include "core/os/keyboard.h"
@@ -48,7 +48,6 @@
#include "servers/rendering/shader_types.h"
Control *VisualShaderNodePlugin::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
-
if (get_script_instance()) {
return get_script_instance()->call("create_editor", p_parent_resource, p_node);
}
@@ -56,14 +55,12 @@ Control *VisualShaderNodePlugin::create_editor(const Ref<Resource> &p_parent_res
}
void VisualShaderNodePlugin::_bind_methods() {
-
BIND_VMETHOD(MethodInfo(Variant::OBJECT, "create_editor", PropertyInfo(Variant::OBJECT, "parent_resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::OBJECT, "for_node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode")));
}
///////////////////
void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
-
bool changed = false;
if (p_visual_shader) {
if (visual_shader.is_null()) {
@@ -106,8 +103,9 @@ void VisualShaderEditor::edit(VisualShader *p_visual_shader) {
}
void VisualShaderEditor::add_plugin(const Ref<VisualShaderNodePlugin> &p_plugin) {
- if (plugins.find(p_plugin) != -1)
+ if (plugins.find(p_plugin) != -1) {
return;
+ }
plugins.push_back(p_plugin);
}
@@ -125,14 +123,14 @@ void VisualShaderEditor::clear_custom_types() {
}
void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script> &p_script, const String &p_description, int p_return_icon_type, const String &p_category, bool p_highend) {
-
ERR_FAIL_COND(!p_name.is_valid_identifier());
ERR_FAIL_COND(!p_script.is_valid());
for (int i = 0; i < add_options.size(); i++) {
if (add_options[i].is_custom) {
- if (add_options[i].script == p_script)
+ if (add_options[i].script == p_script) {
return;
+ }
}
}
@@ -166,11 +164,9 @@ void VisualShaderEditor::add_custom_type(const String &p_name, const Ref<Script>
}
bool VisualShaderEditor::_is_available(int p_mode) {
-
int current_mode = edit_type->get_selected();
if (p_mode != -1) {
-
switch (current_mode) {
case VisualShader::TYPE_VERTEX:
current_mode = 1;
@@ -215,7 +211,6 @@ void VisualShaderEditor::update_custom_nodes() {
Dictionary added;
for (int i = 0; i < class_list.size(); i++) {
if (ScriptServer::get_global_class_native_base(class_list[i]) == "VisualShaderNodeCustom") {
-
String script_path = ScriptServer::get_global_class_path(class_list[i]);
Ref<Resource> res = ResourceLoader::load(script_path);
ERR_FAIL_COND(res.is_null());
@@ -285,7 +280,6 @@ void VisualShaderEditor::update_custom_nodes() {
keys.sort();
for (int i = 0; i < keys.size(); i++) {
-
const Variant &key = keys.get(i);
const Dictionary &value = (Dictionary)added[key];
@@ -301,7 +295,6 @@ String VisualShaderEditor::_get_description(int p_idx) {
}
void VisualShaderEditor::_update_options_menu() {
-
node_desc->set_text("");
members_dialog->get_ok()->set_disabled(true);
@@ -374,10 +367,11 @@ void VisualShaderEditor::_update_options_menu() {
}
TreeItem *item = members->create_item(category);
- if (options[i].highend && low_driver)
+ if (options[i].highend && low_driver) {
item->set_custom_color(0, unsupported_color);
- else if (options[i].highend)
+ } else if (options[i].highend) {
item->set_custom_color(0, supported_color);
+ }
item->set_text(0, options[i].name);
if (is_first_item && use_filter) {
item->select(0);
@@ -411,15 +405,14 @@ void VisualShaderEditor::_update_options_menu() {
}
Size2 VisualShaderEditor::get_minimum_size() const {
-
return Size2(10, 200);
}
void VisualShaderEditor::_draw_color_over_button(Object *obj, Color p_color) {
-
Button *button = Object::cast_to<Button>(obj);
- if (!button)
+ if (!button) {
return;
+ }
Ref<StyleBox> normal = get_theme_stylebox("normal", "Button");
button->draw_rect(Rect2(normal->get_offset(), button->get_size() - normal->get_minimum_size()), p_color);
@@ -435,7 +428,6 @@ static Ref<StyleBoxEmpty> make_empty_stylebox(float p_margin_left = -1, float p_
}
void VisualShaderEditor::_update_created_node(GraphNode *node) {
-
if (EditorSettings::get_singleton()->get("interface/theme/use_graph_node_headers")) {
Ref<StyleBoxFlat> sb = node->get_theme_stylebox("frame", "GraphNode");
Color c = sb->get_border_color();
@@ -459,12 +451,13 @@ void VisualShaderEditor::_update_created_node(GraphNode *node) {
}
void VisualShaderEditor::_update_graph() {
-
- if (updating)
+ if (updating) {
return;
+ }
- if (visual_shader.is_null())
+ if (visual_shader.is_null()) {
return;
+ }
graph->set_scroll_ofs(visual_shader->get_graph_offset() * EDSCALE);
@@ -472,7 +465,6 @@ void VisualShaderEditor::_update_graph() {
graph->clear_connections();
//erase all nodes
for (int i = 0; i < graph->get_child_count(); i++) {
-
if (Object::cast_to<GraphNode>(graph->get_child(i))) {
Node *node = graph->get_child(i);
graph->remove_child(node);
@@ -500,7 +492,6 @@ void VisualShaderEditor::_update_graph() {
Control *offset;
for (int n_i = 0; n_i < nodes.size(); n_i++) {
-
Vector2 position = visual_shader->get_node_position(type, nodes[n_i]);
Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, nodes[n_i]);
@@ -546,6 +537,10 @@ void VisualShaderEditor::_update_graph() {
Ref<VisualShaderNodeUniform> uniform = vsnode;
Ref<VisualShaderNodeFloatUniform> float_uniform = vsnode;
Ref<VisualShaderNodeIntUniform> int_uniform = vsnode;
+ Ref<VisualShaderNodeVec3Uniform> vec3_uniform = vsnode;
+ Ref<VisualShaderNodeColorUniform> color_uniform = vsnode;
+ Ref<VisualShaderNodeBooleanUniform> bool_uniform = vsnode;
+ Ref<VisualShaderNodeTransformUniform> transform_uniform = vsnode;
if (uniform.is_valid()) {
graph->add_child(node);
_update_created_node(node);
@@ -571,7 +566,7 @@ void VisualShaderEditor::_update_graph() {
//shortcut
VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0);
node->set_slot(0, false, VisualShaderNode::PORT_TYPE_SCALAR, Color(), true, port_right, type_color[port_right]);
- if (!float_uniform.is_valid() && !int_uniform.is_valid()) {
+ if (!float_uniform.is_valid() && !int_uniform.is_valid() && !vec3_uniform.is_valid() && !color_uniform.is_valid() && !bool_uniform.is_valid() && !transform_uniform.is_valid()) {
continue;
}
}
@@ -585,13 +580,15 @@ void VisualShaderEditor::_update_graph() {
}
}
- if (custom_editor && !float_uniform.is_valid() && !int_uniform.is_valid() && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) {
+ if (custom_editor && !float_uniform.is_valid() && !int_uniform.is_valid() && !vec3_uniform.is_valid() && !bool_uniform.is_valid() && !transform_uniform.is_valid() && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) {
//will be embedded in first port
} else if (custom_editor) {
-
port_offset++;
node->add_child(custom_editor);
- if (float_uniform.is_valid() || int_uniform.is_valid()) {
+ if (color_uniform.is_valid()) {
+ custom_editor->call_deferred("_show_prop_names", true);
+ }
+ if (float_uniform.is_valid() || int_uniform.is_valid() || vec3_uniform.is_valid() || bool_uniform.is_valid() || transform_uniform.is_valid()) {
custom_editor->call_deferred("_show_prop_names", true);
continue;
}
@@ -599,7 +596,6 @@ void VisualShaderEditor::_update_graph() {
}
if (is_group) {
-
offset = memnew(Control);
offset->set_custom_minimum_size(Size2(0, 6 * EDSCALE));
node->add_child(offset);
@@ -624,7 +620,6 @@ void VisualShaderEditor::_update_graph() {
}
for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) {
-
if (vsnode->is_port_separator(i)) {
node->add_child(memnew(HSeparator));
port_offset++;
@@ -667,7 +662,6 @@ void VisualShaderEditor::_update_graph() {
button->connect("pressed", callable_mp(this, &VisualShaderEditor::_edit_port_default_input), varray(button, nodes[n_i], i));
switch (default_value.get_type()) {
-
case Variant::COLOR: {
button->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
button->connect("draw", callable_mp(this, &VisualShaderEditor::_draw_color_over_button), varray(button, default_value));
@@ -692,9 +686,7 @@ void VisualShaderEditor::_update_graph() {
hb->add_child(custom_editor);
custom_editor->set_h_size_flags(SIZE_EXPAND_FILL);
} else {
-
if (valid_left) {
-
if (is_group) {
OptionButton *type_box = memnew(OptionButton);
hb->add_child(type_box);
@@ -722,14 +714,12 @@ void VisualShaderEditor::_update_graph() {
remove_btn->connect("pressed", callable_mp(this, &VisualShaderEditor::_remove_input_port), varray(nodes[n_i], i), CONNECT_DEFERRED);
hb->add_child(remove_btn);
} else {
-
Label *label = memnew(Label);
label->set_text(name_left);
label->add_theme_style_override("normal", label_style); //more compact
hb->add_child(label);
if (vsnode->get_input_port_default_hint(i) != "" && !port_left_used) {
-
Label *hint_label = memnew(Label);
hint_label->set_text("[" + vsnode->get_input_port_default_hint(i) + "]");
hint_label->add_theme_color_override("font_color", get_theme_color("font_color_readonly", "TextEdit"));
@@ -833,7 +823,6 @@ void VisualShaderEditor::_update_graph() {
}
if (is_expression) {
-
TextEdit *expression_box = memnew(TextEdit);
expression_node->set_control(expression_box, 0);
node->add_child(expression_box);
@@ -848,7 +837,6 @@ void VisualShaderEditor::_update_graph() {
expression_box->add_theme_color_override("background_color", background_color);
for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) {
-
expression_box->add_keyword_color(E->get(), keyword_color);
}
@@ -868,13 +856,13 @@ void VisualShaderEditor::_update_graph() {
if (!uniform.is_valid()) {
graph->add_child(node);
_update_created_node(node);
- if (is_group)
+ if (is_group) {
call_deferred("_set_node_size", (int)type, nodes[n_i], size);
+ }
}
}
for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) {
-
int from = E->get().from_node;
int from_idx = E->get().from_port;
int to = E->get().to_node;
@@ -885,7 +873,6 @@ void VisualShaderEditor::_update_graph() {
}
void VisualShaderEditor::_add_input_port(int p_node, int p_port, int p_port_type, const String &p_name) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNodeExpression> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
@@ -903,7 +890,6 @@ void VisualShaderEditor::_add_input_port(int p_node, int p_port, int p_port_type
}
void VisualShaderEditor::_add_output_port(int p_node, int p_port, int p_port_type, const String &p_name) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
@@ -921,7 +907,6 @@ void VisualShaderEditor::_add_output_port(int p_node, int p_port, int p_port_typ
}
void VisualShaderEditor::_change_input_port_type(int p_type, int p_node, int p_port) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
@@ -939,7 +924,6 @@ void VisualShaderEditor::_change_input_port_type(int p_type, int p_node, int p_p
}
void VisualShaderEditor::_change_output_port_type(int p_type, int p_node, int p_port) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
@@ -957,7 +941,6 @@ void VisualShaderEditor::_change_output_port_type(int p_type, int p_node, int p_
}
void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *line_edit, int p_node_id, int p_port_id) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id);
@@ -972,7 +955,6 @@ void VisualShaderEditor::_change_input_port_name(const String &p_text, Object *l
}
void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *line_edit, int p_node_id, int p_port_id) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id);
@@ -987,7 +969,6 @@ void VisualShaderEditor::_change_output_port_name(const String &p_text, Object *
}
void VisualShaderEditor::_remove_input_port(int p_node, int p_port) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
@@ -999,7 +980,6 @@ void VisualShaderEditor::_remove_input_port(int p_node, int p_port) {
List<VisualShader::Connection> conns;
visual_shader->get_node_connections(type, &conns);
for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
-
int from_node = E->get().from_node;
int from_port = E->get().from_port;
int to_node = E->get().to_node;
@@ -1032,7 +1012,6 @@ void VisualShaderEditor::_remove_input_port(int p_node, int p_port) {
}
void VisualShaderEditor::_remove_output_port(int p_node, int p_port) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
@@ -1044,7 +1023,6 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) {
List<VisualShader::Connection> conns;
visual_shader->get_node_connections(type, &conns);
for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
-
int from_node = E->get().from_node;
int from_port = E->get().from_port;
int to_node = E->get().to_node;
@@ -1077,7 +1055,6 @@ void VisualShaderEditor::_remove_output_port(int p_node, int p_port) {
}
void VisualShaderEditor::_expression_focus_out(Object *text_edit, int p_node) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNodeExpression> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
@@ -1086,8 +1063,9 @@ void VisualShaderEditor::_expression_focus_out(Object *text_edit, int p_node) {
TextEdit *expression_box = Object::cast_to<TextEdit>(text_edit);
- if (node->get_expression() == expression_box->get_text())
+ if (node->get_expression() == expression_box->get_text()) {
return;
+ }
undo_redo->create_action(TTR("Set expression"));
undo_redo->add_do_method(node.ptr(), "set_expression", expression_box->get_text());
@@ -1105,7 +1083,6 @@ void VisualShaderEditor::_rebuild() {
}
void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p_size) {
-
VisualShader::Type type = VisualShader::Type(p_type);
Ref<VisualShaderNode> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
@@ -1126,8 +1103,9 @@ void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p
if (edit_type->get_selected() == p_type) { // check - otherwise the error will be emitted
Node *node2 = graph->get_node(itos(p_node));
gn = Object::cast_to<GraphNode>(node2);
- if (!gn)
+ if (!gn) {
return;
+ }
gn->set_custom_minimum_size(size);
gn->set_size(Size2(1, 1));
@@ -1152,7 +1130,6 @@ void VisualShaderEditor::_set_node_size(int p_type, int p_node, const Vector2 &p
}
void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, int p_node) {
-
VisualShader::Type type = VisualShader::Type(p_type);
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
@@ -1166,7 +1143,6 @@ void VisualShaderEditor::_node_resized(const Vector2 &p_new_size, int p_type, in
}
void VisualShaderEditor::_preview_select_port(int p_node, int p_port) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNode> node = visual_shader->get_node(type, p_node);
if (node.is_null()) {
@@ -1185,7 +1161,6 @@ void VisualShaderEditor::_preview_select_port(int p_node, int p_port) {
}
void VisualShaderEditor::_line_edit_changed(const String &p_text, Object *line_edit, int p_node_id) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNodeUniform> node = visual_shader->get_node(type, p_node_id);
@@ -1206,13 +1181,11 @@ void VisualShaderEditor::_line_edit_changed(const String &p_text, Object *line_e
}
void VisualShaderEditor::_line_edit_focus_out(Object *line_edit, int p_node_id) {
-
String text = Object::cast_to<LineEdit>(line_edit)->get_text();
_line_edit_changed(text, line_edit, p_node_id);
}
void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id, int p_port_id, bool p_output) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNodeGroupBase> node = visual_shader->get_node(type, p_node_id);
@@ -1221,22 +1194,28 @@ void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id,
String text = Object::cast_to<LineEdit>(line_edit)->get_text();
if (!p_output) {
- if (node->get_input_port_name(p_port_id) == text)
+ if (node->get_input_port_name(p_port_id) == text) {
return;
+ }
} else {
- if (node->get_output_port_name(p_port_id) == text)
+ if (node->get_output_port_name(p_port_id) == text) {
return;
+ }
}
List<String> input_names;
List<String> output_names;
for (int i = 0; i < node->get_input_port_count(); i++) {
- if (!p_output && i == p_port_id) continue;
+ if (!p_output && i == p_port_id) {
+ continue;
+ }
input_names.push_back(node->get_input_port_name(i));
}
for (int i = 0; i < node->get_output_port_count(); i++) {
- if (p_output && i == p_port_id) continue;
+ if (p_output && i == p_port_id) {
+ continue;
+ }
output_names.push_back(node->get_output_port_name(i));
}
@@ -1258,7 +1237,6 @@ void VisualShaderEditor::_port_name_focus_out(Object *line_edit, int p_node_id,
}
void VisualShaderEditor::_port_edited() {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Variant value = property_editor->get_variant();
@@ -1276,7 +1254,6 @@ void VisualShaderEditor::_port_edited() {
}
void VisualShaderEditor::_edit_port_default_input(Object *p_button, int p_node, int p_port) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNode> vsn = visual_shader->get_node(type, p_node);
@@ -1292,7 +1269,6 @@ void VisualShaderEditor::_edit_port_default_input(Object *p_button, int p_node,
}
void VisualShaderEditor::_add_custom_node(const String &p_path) {
-
int idx = -1;
for (int i = custom_node_option_idx; i < add_options.size(); i++) {
@@ -1314,7 +1290,6 @@ void VisualShaderEditor::_add_texture_node(const String &p_path) {
}
VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
-
ERR_FAIL_INDEX_V(p_idx, add_options.size(), nullptr);
Ref<VisualShaderNode> vsnode;
@@ -1328,12 +1303,12 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
VisualShaderNodeFloatConstant *constant = Object::cast_to<VisualShaderNodeFloatConstant>(vsn);
if (constant) {
- if ((int)add_options[p_idx].value != -1)
+ if ((int)add_options[p_idx].value != -1) {
constant->set_constant(add_options[p_idx].value);
+ }
}
if (p_op_idx != -1) {
-
VisualShaderNodeInput *input = Object::cast_to<VisualShaderNodeInput>(vsn);
if (input) {
@@ -1454,7 +1429,6 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
if (to_node != -1 && to_slot != -1) {
if (vsnode->get_output_port_count() > 0) {
-
int _from_node = id_to_use;
int _from_slot = 0;
@@ -1465,7 +1439,6 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
}
} else if (from_node != -1 && from_slot != -1) {
if (vsnode->get_input_port_count() > 0) {
-
int _to_node = id_to_use;
int _to_slot = 0;
@@ -1483,7 +1456,6 @@ VisualShaderNode *VisualShaderEditor::_add_node(int p_idx, int p_op_idx) {
}
void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_to, int p_node) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
updating = true;
@@ -1497,7 +1469,6 @@ void VisualShaderEditor::_node_dragged(const Vector2 &p_from, const Vector2 &p_t
}
void VisualShaderEditor::_connection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
int from = p_from.to_int();
@@ -1527,7 +1498,6 @@ void VisualShaderEditor::_connection_request(const String &p_from, int p_from_in
}
void VisualShaderEditor::_disconnection_request(const String &p_from, int p_from_index, const String &p_to, int p_to_index) {
-
graph->disconnect_node(p_from, p_from_index, p_to, p_to_index);
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
@@ -1558,7 +1528,6 @@ void VisualShaderEditor::_connection_from_empty(const String &p_to, int p_to_slo
}
void VisualShaderEditor::_delete_request(int which) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
Ref<VisualShaderNode> node = Ref<VisualShaderNode>(visual_shader->get_node(type, which));
@@ -1598,7 +1567,6 @@ void VisualShaderEditor::_delete_request(int which) {
}
void VisualShaderEditor::_node_selected(Object *p_node) {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
GraphNode *gn = Object::cast_to<GraphNode>(p_node);
@@ -1614,7 +1582,6 @@ void VisualShaderEditor::_node_selected(Object *p_node) {
}
void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) {
@@ -1635,7 +1602,7 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
popup_menu->set_item_disabled(NodeMenuOptions::DELETE, to_change.empty());
popup_menu->set_item_disabled(NodeMenuOptions::DUPLICATE, to_change.empty());
menu_point = graph->get_local_mouse_position();
- Point2 gpos = InputFilter::get_singleton()->get_mouse_position();
+ Point2 gpos = Input::get_singleton()->get_mouse_position();
popup_menu->set_position(gpos);
popup_menu->popup();
}
@@ -1643,12 +1610,11 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
}
void VisualShaderEditor::_show_members_dialog(bool at_mouse_pos) {
-
if (at_mouse_pos) {
saved_node_pos_dirty = true;
saved_node_pos = graph->get_local_mouse_position();
- Point2 gpos = InputFilter::get_singleton()->get_mouse_position();
+ Point2 gpos = Input::get_singleton()->get_mouse_position();
members_dialog->popup();
members_dialog->set_position(gpos);
} else {
@@ -1679,7 +1645,6 @@ void VisualShaderEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
ie->get_keycode() == KEY_DOWN ||
ie->get_keycode() == KEY_ENTER ||
ie->get_keycode() == KEY_KP_ENTER)) {
-
members->call("_gui_input", ie);
node_filter->accept_event();
}
@@ -1687,7 +1652,6 @@ void VisualShaderEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
void VisualShaderEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
-
node_filter->set_clear_button_enabled(true);
// collapse tree by default
@@ -1714,7 +1678,6 @@ void VisualShaderEditor::_notification(int p_what) {
}
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
-
highend_label->set_modulate(get_theme_color("vulkan_color", "Editor"));
error_panel->add_theme_style_override("panel", get_theme_stylebox("bg", "Tree"));
@@ -1734,7 +1697,6 @@ void VisualShaderEditor::_notification(int p_what) {
preview_text->add_theme_color_override("background_color", background_color);
for (List<String>::Element *E = keyword_list.front(); E; E = E->next()) {
-
preview_text->add_keyword_color(E->get(), keyword_color);
}
@@ -1750,22 +1712,25 @@ void VisualShaderEditor::_notification(int p_what) {
tools->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Tools", "EditorIcons"));
- if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree())
+ if (p_what == NOTIFICATION_THEME_CHANGED && is_visible_in_tree()) {
_update_graph();
+ }
}
}
void VisualShaderEditor::_scroll_changed(const Vector2 &p_scroll) {
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
visual_shader->set_graph_offset(p_scroll / EDSCALE);
updating = false;
}
void VisualShaderEditor::_node_changed(int p_id) {
- if (updating)
+ if (updating) {
return;
+ }
if (is_visible_in_tree()) {
_update_graph();
@@ -1777,7 +1742,6 @@ void VisualShaderEditor::_dup_update_excluded(int p_type, Set<int> &r_excluded)
VisualShader::Type type = (VisualShader::Type)p_type;
for (int i = 0; i < graph->get_child_count(); i++) {
-
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
if (gn) {
int id = String(gn->get_name()).to_int();
@@ -1793,14 +1757,12 @@ void VisualShaderEditor::_dup_update_excluded(int p_type, Set<int> &r_excluded)
}
void VisualShaderEditor::_dup_copy_nodes(int p_type, List<int> &r_nodes, Set<int> &r_excluded) {
-
VisualShader::Type type = (VisualShader::Type)p_type;
selection_center.x = 0.0f;
selection_center.y = 0.0f;
for (int i = 0; i < graph->get_child_count(); i++) {
-
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
if (gn) {
int id = String(gn->get_name()).to_int();
@@ -1823,7 +1785,6 @@ void VisualShaderEditor::_dup_copy_nodes(int p_type, List<int> &r_nodes, Set<int
}
void VisualShaderEditor::_dup_paste_nodes(int p_type, int p_pasted_type, List<int> &r_nodes, Set<int> &r_excluded, const Vector2 &p_offset, bool p_select) {
-
VisualShader::Type type = (VisualShader::Type)p_type;
VisualShader::Type pasted_type = (VisualShader::Type)p_pasted_type;
@@ -1833,7 +1794,6 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, int p_pasted_type, List<in
Set<int> unsupported_set;
for (List<int>::Element *E = r_nodes.front(); E; E = E->next()) {
-
connection_remap[E->get()] = id_from;
Ref<VisualShaderNode> node = visual_shader->get_node(pasted_type, E->get());
@@ -1891,7 +1851,6 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, int p_pasted_type, List<in
if (p_select) {
// reselect duplicated nodes by excluding the other ones
for (int i = 0; i < graph->get_child_count(); i++) {
-
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
if (gn) {
int id = String(gn->get_name()).to_int();
@@ -1906,13 +1865,11 @@ void VisualShaderEditor::_dup_paste_nodes(int p_type, int p_pasted_type, List<in
}
void VisualShaderEditor::_clear_buffer() {
-
copy_nodes_buffer.clear();
copy_nodes_excluded_buffer.clear();
}
void VisualShaderEditor::_duplicate_nodes() {
-
int type = edit_type->get_selected();
List<int> nodes;
@@ -1920,8 +1877,9 @@ void VisualShaderEditor::_duplicate_nodes() {
_dup_copy_nodes(type, nodes, excluded);
- if (nodes.empty())
+ if (nodes.empty()) {
return;
+ }
undo_redo->create_action(TTR("Duplicate Nodes"));
@@ -1929,7 +1887,6 @@ void VisualShaderEditor::_duplicate_nodes() {
}
void VisualShaderEditor::_copy_nodes() {
-
copy_type = edit_type->get_selected();
_clear_buffer();
@@ -1938,9 +1895,9 @@ void VisualShaderEditor::_copy_nodes() {
}
void VisualShaderEditor::_paste_nodes(bool p_use_custom_position, const Vector2 &p_custom_position) {
-
- if (copy_nodes_buffer.empty())
+ if (copy_nodes_buffer.empty()) {
return;
+ }
int type = edit_type->get_selected();
@@ -1961,7 +1918,6 @@ void VisualShaderEditor::_paste_nodes(bool p_use_custom_position, const Vector2
}
void VisualShaderEditor::_delete_nodes() {
-
VisualShader::Type type = VisualShader::Type(edit_type->get_selected());
List<int> to_erase;
@@ -1974,13 +1930,13 @@ void VisualShaderEditor::_delete_nodes() {
}
}
- if (to_erase.empty())
+ if (to_erase.empty()) {
return;
+ }
undo_redo->create_action(TTR("Delete Nodes"));
for (List<int>::Element *F = to_erase.front(); F; F = F->next()) {
-
Ref<VisualShaderNode> node = visual_shader->get_node(type, F->get());
undo_redo->add_do_method(visual_shader.ptr(), "remove_node", type, F->get());
@@ -2011,7 +1967,6 @@ void VisualShaderEditor::_delete_nodes() {
for (List<int>::Element *F = to_erase.front(); F; F = F->next()) {
for (List<VisualShader::Connection>::Element *E = conns.front(); E; E = E->next()) {
if (E->get().from_node == F->get() || E->get().to_node == F->get()) {
-
bool cancel = false;
for (List<VisualShader::Connection>::Element *R = used_conns.front(); R; R = R->next()) {
if (R->get().from_node == E->get().from_node && R->get().from_port == E->get().from_port && R->get().to_node == E->get().to_node && R->get().to_port == E->get().to_port) {
@@ -2033,17 +1988,16 @@ void VisualShaderEditor::_delete_nodes() {
}
void VisualShaderEditor::_mode_selected(int p_id) {
-
_update_options_menu();
_update_graph();
}
void VisualShaderEditor::_input_select_item(Ref<VisualShaderNodeInput> input, String name) {
-
String prev_name = input->get_input_name();
- if (name == prev_name)
+ if (name == prev_name) {
return;
+ }
bool type_changed = input->get_input_type_by_name(name) != input->get_input_type_by_name(prev_name);
@@ -2110,7 +2064,6 @@ void VisualShaderEditor::_member_cancel() {
}
void VisualShaderEditor::_tools_menu_option(int p_idx) {
-
TreeItem *category = members->get_root()->get_children();
switch (p_idx) {
@@ -2167,13 +2120,14 @@ void VisualShaderEditor::_node_menu_id_pressed(int p_idx) {
}
Variant VisualShaderEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
if (p_from == members) {
TreeItem *it = members->get_item_at_position(p_point);
- if (!it)
+ if (!it) {
return Variant();
- if (!it->has_meta("id"))
+ }
+ if (!it->has_meta("id")) {
return Variant();
+ }
int id = it->get_meta("id");
AddOption op = add_options[id];
@@ -2195,9 +2149,7 @@ Variant VisualShaderEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f
}
bool VisualShaderEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
if (p_from == graph) {
-
Dictionary d = p_data;
if (d.has("id")) {
@@ -2212,9 +2164,7 @@ bool VisualShaderEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
}
void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
-
if (p_from == graph) {
-
Dictionary d = p_data;
if (d.has("id")) {
@@ -2224,11 +2174,9 @@ void VisualShaderEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
_add_node(idx, add_options[idx].sub_func);
} else if (d.has("files")) {
if (d["files"].get_type() == Variant::PACKED_STRING_ARRAY) {
-
int j = 0;
PackedStringArray arr = d["files"];
for (int i = 0; i < arr.size(); i++) {
-
String type = ResourceLoader::get_resource_type(arr[i]);
if (type == "GDScript") {
Ref<Script> script = ResourceLoader::load(arr[i]);
@@ -2262,13 +2210,11 @@ void VisualShaderEditor::_show_preview_text() {
}
static ShaderLanguage::DataType _get_global_variable_type(const StringName &p_variable) {
-
RS::GlobalVariableType gvt = RS::get_singleton()->global_variable_get_type(p_variable);
return RS::global_variable_type_get_shader_datatype(gvt);
}
void VisualShaderEditor::_update_preview() {
-
if (!preview_showed) {
pending_update_preview = true;
return;
@@ -2318,7 +2264,6 @@ void VisualShaderEditor::_bind_methods() {
VisualShaderEditor *VisualShaderEditor::singleton = nullptr;
VisualShaderEditor::VisualShaderEditor() {
-
singleton = this;
updating = false;
saved_node_pos_dirty = false;
@@ -2650,7 +2595,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Texture", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), "texture", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
- add_options.push_back(AddOption("LightAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_alpha"), "light_alpha", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("LightAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_alpha"), "light_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("LightHeight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_height"), "light_height", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("LightUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_uv"), "light_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
@@ -2658,7 +2603,9 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("PointCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ScreenUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ShadowAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_alpha"), "shadow_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("ShadowColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_color"), "shadow_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
+ add_options.push_back(AddOption("ShadowVec", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_vec"), "shadow_vec", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Texture", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "texture"), "texture", VisualShaderNode::PORT_TYPE_SAMPLER, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM));
add_options.push_back(AddOption("Extra", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "extra"), "extra", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM));
@@ -2934,17 +2881,14 @@ VisualShaderEditor::VisualShaderEditor() {
}
void VisualShaderEditorPlugin::edit(Object *p_object) {
-
visual_shader_editor->edit(Object::cast_to<VisualShader>(p_object));
}
bool VisualShaderEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("VisualShader");
}
void VisualShaderEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
//editor->hide_animation_player_editors();
//editor->animation_panel_make_visible(true);
@@ -2954,9 +2898,9 @@ void VisualShaderEditorPlugin::make_visible(bool p_visible) {
visual_shader_editor->set_process_input(true);
//visual_shader_editor->set_process(true);
} else {
-
- if (visual_shader_editor->is_visible_in_tree())
+ if (visual_shader_editor->is_visible_in_tree()) {
editor->hide_bottom_panel();
+ }
button->hide();
visual_shader_editor->set_process_input(false);
//visual_shader_editor->set_process(false);
@@ -2964,7 +2908,6 @@ void VisualShaderEditorPlugin::make_visible(bool p_visible) {
}
VisualShaderEditorPlugin::VisualShaderEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
visual_shader_editor = memnew(VisualShaderEditor);
visual_shader_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
@@ -3026,9 +2969,9 @@ class VisualShaderNodePluginDefaultEditor : public VBoxContainer {
public:
void _property_changed(const String &p_property, const Variant &p_value, const String &p_field = "", bool p_changing = false) {
-
- if (p_changing)
+ if (p_changing) {
return;
+ }
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
@@ -3038,7 +2981,6 @@ public:
undo_redo->add_undo_property(node.ptr(), p_property, node->get(p_property));
if (p_value.get_type() == Variant::OBJECT) {
-
RES prev_res = node->get(p_property);
RES curr_res = p_value;
@@ -3061,8 +3003,9 @@ public:
}
void _node_changed() {
- if (updating)
+ if (updating) {
return;
+ }
for (int i = 0; i < properties.size(); i++) {
properties[i]->update_property();
}
@@ -3098,7 +3041,6 @@ public:
properties = p_properties;
for (int i = 0; i < p_properties.size(); i++) {
-
HBoxContainer *hbox = memnew(HBoxContainer);
hbox->set_h_size_flags(SIZE_EXPAND_FILL);
add_child(hbox);
@@ -3136,7 +3078,6 @@ public:
};
Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
-
if (p_node->is_class("VisualShaderNodeInput")) {
//create input
VisualShaderNodePluginInputEditor *input_editor = memnew(VisualShaderNodePluginInputEditor);
@@ -3155,7 +3096,6 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par
Vector<PropertyInfo> pinfo;
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
for (int i = 0; i < properties.size(); i++) {
if (E->get().name == String(properties[i])) {
pinfo.push_back(E->get());
@@ -3163,8 +3103,9 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par
}
}
- if (pinfo.size() == 0)
+ if (pinfo.size() == 0) {
return nullptr;
+ }
properties.clear();
@@ -3172,10 +3113,10 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par
Vector<EditorProperty *> editors;
for (int i = 0; i < pinfo.size(); i++) {
-
EditorProperty *prop = EditorInspector::instantiate_property_editor(node.ptr(), pinfo[i].type, pinfo[i].name, pinfo[i].hint, pinfo[i].hint_string, pinfo[i].usage);
- if (!prop)
+ if (!prop) {
return nullptr;
+ }
if (Object::cast_to<EditorPropertyResource>(prop)) {
Object::cast_to<EditorPropertyResource>(prop)->set_use_sub_inspector(false);
@@ -3198,14 +3139,14 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par
}
void EditorPropertyShaderMode::_option_selected(int p_which) {
-
//will not use this, instead will do all the logic setting manually
//emit_signal("property_changed", get_edited_property(), p_which);
Ref<VisualShader> visual_shader(Object::cast_to<VisualShader>(get_edited_object()));
- if (visual_shader->get_mode() == p_which)
+ if (visual_shader->get_mode() == p_which) {
return;
+ }
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
undo_redo->create_action(TTR("Visual Shader Mode Changed"));
@@ -3216,7 +3157,6 @@ void EditorPropertyShaderMode::_option_selected(int p_which) {
//1. restore connections to output
for (int i = 0; i < VisualShader::TYPE_MAX; i++) {
-
VisualShader::Type type = VisualShader::Type(i);
List<VisualShader::Connection> conns;
visual_shader->get_node_connections(type, &conns);
@@ -3228,7 +3168,6 @@ void EditorPropertyShaderMode::_option_selected(int p_which) {
}
//2. restore input indices
for (int i = 0; i < VisualShader::TYPE_MAX; i++) {
-
VisualShader::Type type = VisualShader::Type(i);
Vector<int> nodes = visual_shader->get_node_list(type);
for (int j = 0; j < nodes.size(); j++) {
@@ -3246,7 +3185,6 @@ void EditorPropertyShaderMode::_option_selected(int p_which) {
visual_shader->get_property_list(&props);
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
if (E->get().name.begins_with("flags/") || E->get().name.begins_with("modes/")) {
undo_redo->add_undo_property(visual_shader.ptr(), E->get().name, visual_shader->get(E->get().name));
}
@@ -3263,7 +3201,6 @@ void EditorPropertyShaderMode::_option_selected(int p_which) {
}
void EditorPropertyShaderMode::update_property() {
-
int which = get_edited_object()->get(get_edited_property());
options->select(which);
}
@@ -3298,9 +3235,7 @@ void EditorInspectorShaderModePlugin::parse_begin(Object *p_object) {
}
bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
-
if (p_path == "mode" && p_object->is_class("VisualShader") && p_type == Variant::INT) {
-
EditorPropertyShaderMode *editor = memnew(EditorPropertyShaderMode);
Vector<String> options = p_hint_text.split(",");
editor->setup(options);
@@ -3315,6 +3250,7 @@ bool EditorInspectorShaderModePlugin::parse_property(Object *p_object, Variant::
void EditorInspectorShaderModePlugin::parse_end() {
//do none
}
+
//////////////////////////////////
void VisualShaderNodePortPreview::_shader_changed() {
@@ -3340,11 +3276,11 @@ void VisualShaderNodePortPreview::_shader_changed() {
for (int i = EditorNode::get_singleton()->get_editor_history()->get_path_size() - 1; i >= 0; i--) {
Object *object = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_history()->get_path_object(i));
- if (!object)
+ if (!object) {
continue;
+ }
ShaderMaterial *src_mat = Object::cast_to<ShaderMaterial>(object);
if (src_mat && src_mat->get_shader().is_valid()) {
-
List<PropertyInfo> params;
src_mat->get_shader()->get_param_list(&params);
for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) {
@@ -3357,7 +3293,6 @@ void VisualShaderNodePortPreview::_shader_changed() {
}
void VisualShaderNodePortPreview::setup(const Ref<VisualShader> &p_shader, VisualShader::Type p_type, int p_node, int p_port) {
-
shader = p_shader;
shader->connect("changed", callable_mp(this, &VisualShaderNodePortPreview::_shader_changed));
type = p_type;
@@ -3402,18 +3337,15 @@ VisualShaderNodePortPreview::VisualShaderNodePortPreview() {
//////////////////////////////////
String VisualShaderConversionPlugin::converts_to() const {
-
return "Shader";
}
bool VisualShaderConversionPlugin::handles(const Ref<Resource> &p_resource) const {
-
Ref<VisualShader> vshader = p_resource;
return vshader.is_valid();
}
Ref<Resource> VisualShaderConversionPlugin::convert(const Ref<Resource> &p_resource) const {
-
Ref<VisualShader> vshader = p_resource;
ERR_FAIL_COND_V(!vshader.is_valid(), Ref<Resource>());
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index a495b09b5c..d2f10d9407 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -41,7 +41,6 @@
#include "scene/resources/visual_shader.h"
class VisualShaderNodePlugin : public Reference {
-
GDCLASS(VisualShaderNodePlugin, Reference);
protected:
@@ -52,7 +51,6 @@ public:
};
class VisualShaderEditor : public VBoxContainer {
-
GDCLASS(VisualShaderEditor, VBoxContainer);
CustomPropertyEditor *property_editor;
@@ -157,7 +155,6 @@ class VisualShaderEditor : public VBoxContainer {
}
};
struct _OptionComparator {
-
_FORCE_INLINE_ bool operator()(const AddOption &a, const AddOption &b) const {
return a.category.count("/") > b.category.count("/") || (a.category + "/" + a.name).naturalnocasecmp_to(b.category + "/" + b.name) < 0;
}
@@ -290,7 +287,6 @@ public:
};
class VisualShaderEditorPlugin : public EditorPlugin {
-
GDCLASS(VisualShaderEditorPlugin, EditorPlugin);
VisualShaderEditor *visual_shader_editor;
@@ -309,7 +305,6 @@ public:
};
class VisualShaderNodePluginDefault : public VisualShaderNodePlugin {
-
GDCLASS(VisualShaderNodePluginDefault, VisualShaderNodePlugin);
public:
diff --git a/editor/progress_dialog.cpp b/editor/progress_dialog.cpp
index 86df069b8b..541cba836b 100644
--- a/editor/progress_dialog.cpp
+++ b/editor/progress_dialog.cpp
@@ -37,7 +37,6 @@
#include "servers/display_server.h"
void BackgroundProgress::_add_task(const String &p_task, const String &p_label, int p_steps) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_MSG(tasks.has(p_task), "Task '" + p_task + "' already exists.");
BackgroundProgress::Task t;
@@ -62,11 +61,9 @@ void BackgroundProgress::_add_task(const String &p_task, const String &p_label,
}
void BackgroundProgress::_update() {
-
_THREAD_SAFE_METHOD_
for (Map<String, int>::Element *E = updates.front(); E; E = E->next()) {
-
if (tasks.has(E->key())) {
_task_step(E->key(), E->get());
}
@@ -76,19 +73,19 @@ void BackgroundProgress::_update() {
}
void BackgroundProgress::_task_step(const String &p_task, int p_step) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!tasks.has(p_task));
Task &t = tasks[p_task];
- if (p_step < 0)
+ if (p_step < 0) {
t.progress->set_value(t.progress->get_value() + 1);
- else
+ } else {
t.progress->set_value(p_step);
+ }
}
-void BackgroundProgress::_end_task(const String &p_task) {
+void BackgroundProgress::_end_task(const String &p_task) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!tasks.has(p_task));
@@ -99,7 +96,6 @@ void BackgroundProgress::_end_task(const String &p_task) {
}
void BackgroundProgress::_bind_methods() {
-
ClassDB::bind_method("_add_task", &BackgroundProgress::_add_task);
ClassDB::bind_method("_task_step", &BackgroundProgress::_task_step);
ClassDB::bind_method("_end_task", &BackgroundProgress::_end_task);
@@ -107,11 +103,10 @@ void BackgroundProgress::_bind_methods() {
}
void BackgroundProgress::add_task(const String &p_task, const String &p_label, int p_steps) {
-
MessageQueue::get_singleton()->push_call(this, "_add_task", p_task, p_label, p_steps);
}
-void BackgroundProgress::task_step(const String &p_task, int p_step) {
+void BackgroundProgress::task_step(const String &p_task, int p_step) {
//this code is weird, but it prevents deadlock.
bool no_updates = true;
{
@@ -119,8 +114,9 @@ void BackgroundProgress::task_step(const String &p_task, int p_step) {
no_updates = updates.empty();
}
- if (no_updates)
+ if (no_updates) {
MessageQueue::get_singleton()->push_call(this, "_update");
+ }
{
_THREAD_SAFE_METHOD_
@@ -129,7 +125,6 @@ void BackgroundProgress::task_step(const String &p_task, int p_step) {
}
void BackgroundProgress::end_task(const String &p_task) {
-
MessageQueue::get_singleton()->push_call(this, "_end_task", p_task);
}
@@ -141,7 +136,6 @@ void ProgressDialog::_notification(int p_what) {
}
void ProgressDialog::_popup() {
-
Size2 ms = main->get_combined_minimum_size();
ms.width = MAX(500 * EDSCALE, ms.width);
@@ -157,7 +151,6 @@ void ProgressDialog::_popup() {
}
void ProgressDialog::add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel) {
-
if (MessageQueue::get_singleton()->is_flushing()) {
ERR_PRINT("Do not use progress dialog (task) while flushing the message queue or using call_deferred()!");
return;
@@ -192,20 +185,21 @@ void ProgressDialog::add_task(const String &p_task, const String &p_label, int p
}
bool ProgressDialog::task_step(const String &p_task, const String &p_state, int p_step, bool p_force_redraw) {
-
ERR_FAIL_COND_V(!tasks.has(p_task), cancelled);
if (!p_force_redraw) {
uint64_t tus = OS::get_singleton()->get_ticks_usec();
- if (tus - last_progress_tick < 200000) //200ms
+ if (tus - last_progress_tick < 200000) { //200ms
return cancelled;
+ }
}
Task &t = tasks[p_task];
- if (p_step < 0)
+ if (p_step < 0) {
t.progress->set_value(t.progress->get_value() + 1);
- else
+ } else {
t.progress->set_value(p_step);
+ }
t.state->set_text(p_state);
last_progress_tick = OS::get_singleton()->get_ticks_usec();
@@ -218,17 +212,17 @@ bool ProgressDialog::task_step(const String &p_task, const String &p_state, int
}
void ProgressDialog::end_task(const String &p_task) {
-
ERR_FAIL_COND(!tasks.has(p_task));
Task &t = tasks[p_task];
memdelete(t.vb);
tasks.erase(p_task);
- if (tasks.empty())
+ if (tasks.empty()) {
hide();
- else
+ } else {
_popup();
+ }
}
void ProgressDialog::_cancel_pressed() {
@@ -239,7 +233,6 @@ void ProgressDialog::_bind_methods() {
}
ProgressDialog::ProgressDialog() {
-
main = memnew(VBoxContainer);
add_child(main);
main->set_anchors_and_margins_preset(Control::PRESET_WIDE);
diff --git a/editor/progress_dialog.h b/editor/progress_dialog.h
index 82f479ae9d..753b6ac955 100644
--- a/editor/progress_dialog.h
+++ b/editor/progress_dialog.h
@@ -38,13 +38,11 @@
#include "scene/gui/progress_bar.h"
class BackgroundProgress : public HBoxContainer {
-
GDCLASS(BackgroundProgress, HBoxContainer);
_THREAD_SAFE_CLASS_
struct Task {
-
HBoxContainer *hb;
ProgressBar *progress;
};
@@ -69,10 +67,8 @@ public:
};
class ProgressDialog : public PopupPanel {
-
GDCLASS(ProgressDialog, PopupPanel);
struct Task {
-
String task;
VBoxContainer *vb;
ProgressBar *progress;
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 04ec5ae043..e5372a5d47 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -52,11 +52,12 @@ void ProjectExportDialog::_theme_changed() {
duplicate_preset->set_icon(presets->get_theme_icon("Duplicate", "EditorIcons"));
delete_preset->set_icon(presets->get_theme_icon("Remove", "EditorIcons"));
Control *panel = custom_feature_display->get_parent_control();
- if (panel)
+ if (panel) {
panel->add_theme_style_override("panel", patches->get_theme_stylebox("bg", "Tree"));
+ }
}
-void ProjectExportDialog::_notification(int p_what) {
+void ProjectExportDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (!is_visible()) {
@@ -73,10 +74,8 @@ void ProjectExportDialog::_notification(int p_what) {
}
void ProjectExportDialog::popup_export() {
-
add_preset->get_popup()->clear();
for (int i = 0; i < EditorExport::get_singleton()->get_export_platform_count(); i++) {
-
Ref<EditorExportPlatform> plat = EditorExport::get_singleton()->get_export_platform(i);
add_preset->get_popup()->add_icon_item(plat->get_logo(), plat->get_name());
@@ -97,7 +96,6 @@ void ProjectExportDialog::popup_export() {
}
void ProjectExportDialog::_add_preset(int p_platform) {
-
Ref<EditorExportPreset> preset = EditorExport::get_singleton()->get_export_platform(p_platform)->create_preset();
ERR_FAIL_COND(!preset.is_valid());
@@ -105,7 +103,6 @@ void ProjectExportDialog::_add_preset(int p_platform) {
bool make_runnable = true;
int attempt = 1;
while (true) {
-
bool valid = true;
for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
@@ -119,33 +116,40 @@ void ProjectExportDialog::_add_preset(int p_platform) {
}
}
- if (valid)
+ if (valid) {
break;
+ }
attempt++;
name = EditorExport::get_singleton()->get_export_platform(p_platform)->get_name() + " " + itos(attempt);
}
preset->set_name(name);
- if (make_runnable)
+ if (make_runnable) {
preset->set_runnable(make_runnable);
+ }
EditorExport::get_singleton()->add_export_preset(preset);
_update_presets();
_edit_preset(EditorExport::get_singleton()->get_export_preset_count() - 1);
}
-void ProjectExportDialog::_update_current_preset() {
+void ProjectExportDialog::_force_update_current_preset_parameters() {
+ // Force the parameters section to refresh its UI.
+ parameters->edit(nullptr);
+ _update_current_preset();
+}
+void ProjectExportDialog::_update_current_preset() {
_edit_preset(presets->get_current());
}
void ProjectExportDialog::_update_presets() {
-
updating = true;
Ref<EditorExportPreset> current;
- if (presets->get_current() >= 0 && presets->get_current() < presets->get_item_count())
+ if (presets->get_current() >= 0 && presets->get_current() < presets->get_item_count()) {
current = get_current_preset();
+ }
int current_idx = -1;
presets->clear();
@@ -156,8 +160,9 @@ void ProjectExportDialog::_update_presets() {
}
String name = preset->get_name();
- if (preset->is_runnable())
+ if (preset->is_runnable()) {
name += " (" + TTR("Runnable") + ")";
+ }
presets->add_item(name, preset->get_platform()->get_logo());
}
@@ -169,7 +174,6 @@ void ProjectExportDialog::_update_presets() {
}
void ProjectExportDialog::_update_export_all() {
-
bool can_export = EditorExport::get_singleton()->get_export_preset_count() > 0;
for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
@@ -190,7 +194,6 @@ void ProjectExportDialog::_update_export_all() {
}
void ProjectExportDialog::_edit_preset(int p_index) {
-
if (p_index < 0 || p_index >= presets->get_item_count()) {
name->set_text("");
name->set_editable(false);
@@ -246,8 +249,9 @@ void ProjectExportDialog::_edit_preset(int p_index) {
String file = patchlist[i].get_file();
patch->set_editable(0, true);
patch->set_text(0, file.get_file().replace("*", ""));
- if (file.ends_with("*"))
+ if (file.ends_with("*")) {
patch->set_checked(0, true);
+ }
patch->set_tooltip(0, patchlist[i]);
patch->set_metadata(0, i);
patch->add_button(0, presets->get_theme_icon("Remove", "EditorIcons"), 0);
@@ -256,10 +260,11 @@ void ProjectExportDialog::_edit_preset(int p_index) {
TreeItem *patch_add = patches->create_item(patch_root);
patch_add->set_metadata(0, patchlist.size());
- if (patchlist.size() == 0)
+ if (patchlist.size() == 0) {
patch_add->set_text(0, TTR("Add initial export..."));
- else
+ } else {
patch_add->set_text(0, TTR("Add previous patches..."));
+ }
patch_add->add_button(0, presets->get_theme_icon("folder", "FileDialog"), 1);
@@ -268,14 +273,13 @@ void ProjectExportDialog::_edit_preset(int p_index) {
bool needs_templates;
String error;
if (!current->get_platform()->can_export(current, error, needs_templates)) {
-
if (error != String()) {
-
Vector<String> items = error.split("\n", false);
error = "";
for (int i = 0; i < items.size(); i++) {
- if (i > 0)
+ if (i > 0) {
error += "\n";
+ }
error += " - " + items[i];
}
@@ -284,10 +288,11 @@ void ProjectExportDialog::_edit_preset(int p_index) {
} else {
export_error->hide();
}
- if (needs_templates)
+ if (needs_templates) {
export_templates_error->show();
- else
+ } else {
export_templates_error->hide();
+ }
export_button->set_disabled(true);
get_ok()->set_disabled(true);
@@ -329,7 +334,6 @@ void ProjectExportDialog::_edit_preset(int p_index) {
}
void ProjectExportDialog::_update_feature_list() {
-
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
@@ -363,9 +367,9 @@ void ProjectExportDialog::_update_feature_list() {
}
void ProjectExportDialog::_custom_features_changed(const String &p_text) {
-
- if (updating)
+ if (updating) {
return;
+ }
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
@@ -379,7 +383,6 @@ void ProjectExportDialog::_tab_changed(int) {
}
void ProjectExportDialog::_patch_button_pressed(Object *p_item, int p_column, int p_id) {
-
TreeItem *ti = (TreeItem *)p_item;
patch_index = ti->get_metadata(0);
@@ -398,10 +401,10 @@ void ProjectExportDialog::_patch_button_pressed(Object *p_item, int p_column, in
}
void ProjectExportDialog::_patch_edited() {
-
TreeItem *item = patches->get_edited();
- if (!item)
+ if (!item) {
return;
+ }
int index = item->get_metadata(0);
Ref<EditorExportPreset> current = get_current_preset();
@@ -421,14 +424,12 @@ void ProjectExportDialog::_patch_edited() {
}
void ProjectExportDialog::_patch_selected(const String &p_path) {
-
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
Vector<String> patches = current->get_patches();
if (patch_index >= patches.size()) {
-
current->add_patch(ProjectSettings::get_singleton()->get_resource_path().path_to(p_path) + "*");
} else {
String enabled = patches[patch_index].ends_with("*") ? String("*") : String();
@@ -439,33 +440,29 @@ void ProjectExportDialog::_patch_selected(const String &p_path) {
}
void ProjectExportDialog::_patch_deleted() {
-
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
Vector<String> patches = current->get_patches();
if (patch_index < patches.size()) {
-
current->remove_patch(patch_index);
_update_current_preset();
}
}
void ProjectExportDialog::_update_parameters(const String &p_edited_property) {
-
_update_current_preset();
}
void ProjectExportDialog::_runnable_pressed() {
-
- if (updating)
+ if (updating) {
return;
+ }
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
if (runnable->is_pressed()) {
-
for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
Ref<EditorExportPreset> p = EditorExport::get_singleton()->get_export_preset(i);
if (p->get_platform() == current->get_platform()) {
@@ -473,7 +470,6 @@ void ProjectExportDialog::_runnable_pressed() {
}
}
} else {
-
current->set_runnable(false);
}
@@ -481,9 +477,9 @@ void ProjectExportDialog::_runnable_pressed() {
}
void ProjectExportDialog::_name_changed(const String &p_string) {
-
- if (updating)
+ if (updating) {
return;
+ }
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
@@ -507,14 +503,13 @@ String ProjectExportDialog::get_export_path() {
}
Ref<EditorExportPreset> ProjectExportDialog::get_current_preset() const {
-
return EditorExport::get_singleton()->get_export_preset(presets->get_current());
}
void ProjectExportDialog::_export_path_changed(const StringName &p_property, const Variant &p_value, const String &p_field, bool p_changing) {
-
- if (updating)
+ if (updating) {
return;
+ }
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
@@ -524,9 +519,9 @@ void ProjectExportDialog::_export_path_changed(const StringName &p_property, con
}
void ProjectExportDialog::_script_export_mode_changed(int p_mode) {
-
- if (updating)
+ if (updating) {
return;
+ }
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
@@ -537,9 +532,9 @@ void ProjectExportDialog::_script_export_mode_changed(int p_mode) {
}
void ProjectExportDialog::_script_encryption_key_changed(const String &p_key) {
-
- if (updating)
+ if (updating) {
return;
+ }
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
@@ -552,7 +547,6 @@ void ProjectExportDialog::_script_encryption_key_changed(const String &p_key) {
}
bool ProjectExportDialog::_validate_script_encryption_key(const String &p_key) {
-
bool is_valid = false;
if (!p_key.empty() && p_key.is_valid_hex_number(false) && p_key.length() == 64) {
@@ -562,10 +556,10 @@ bool ProjectExportDialog::_validate_script_encryption_key(const String &p_key) {
}
void ProjectExportDialog::_duplicate_preset() {
-
Ref<EditorExportPreset> current = get_current_preset();
- if (current.is_null())
+ if (current.is_null()) {
return;
+ }
Ref<EditorExportPreset> preset = current->get_platform()->create_preset();
ERR_FAIL_COND(!preset.is_valid());
@@ -573,7 +567,6 @@ void ProjectExportDialog::_duplicate_preset() {
String name = current->get_name() + " (copy)";
bool make_runnable = true;
while (true) {
-
bool valid = true;
for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
@@ -587,15 +580,17 @@ void ProjectExportDialog::_duplicate_preset() {
}
}
- if (valid)
+ if (valid) {
break;
+ }
name += " (copy)";
}
preset->set_name(name);
- if (make_runnable)
+ if (make_runnable) {
preset->set_runnable(make_runnable);
+ }
preset->set_export_filter(current->get_export_filter());
preset->set_include_filter(current->get_include_filter());
preset->set_exclude_filter(current->get_exclude_filter());
@@ -615,17 +610,16 @@ void ProjectExportDialog::_duplicate_preset() {
}
void ProjectExportDialog::_delete_preset() {
-
Ref<EditorExportPreset> current = get_current_preset();
- if (current.is_null())
+ if (current.is_null()) {
return;
+ }
delete_confirm->set_text(vformat(TTR("Delete preset '%s'?"), current->get_name()));
delete_confirm->popup_centered();
}
void ProjectExportDialog::_delete_preset_confirm() {
-
int idx = presets->get_current();
_edit_preset(-1);
export_button->set_disabled(true);
@@ -635,7 +629,6 @@ void ProjectExportDialog::_delete_preset_confirm() {
}
Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
if (p_from == presets) {
int pos = presets->get_item_at_position(p_point, true);
@@ -657,11 +650,9 @@ Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_
return d;
}
} else if (p_from == patches) {
-
TreeItem *item = patches->get_item_at_position(p_point);
if (item && item->get_cell_mode(0) == TreeItem::CELL_MODE_CHECK) {
-
int metadata = item->get_metadata(0);
Dictionary d;
d["type"] = "export_patch";
@@ -679,26 +670,26 @@ Variant ProjectExportDialog::get_drag_data_fw(const Point2 &p_point, Control *p_
}
bool ProjectExportDialog::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
if (p_from == presets) {
Dictionary d = p_data;
- if (!d.has("type") || String(d["type"]) != "export_preset")
+ if (!d.has("type") || String(d["type"]) != "export_preset") {
return false;
+ }
- if (presets->get_item_at_position(p_point, true) < 0 && !presets->is_pos_at_end_of_items(p_point))
+ if (presets->get_item_at_position(p_point, true) < 0 && !presets->is_pos_at_end_of_items(p_point)) {
return false;
+ }
} else if (p_from == patches) {
-
Dictionary d = p_data;
- if (!d.has("type") || String(d["type"]) != "export_patch")
+ if (!d.has("type") || String(d["type"]) != "export_patch") {
return false;
+ }
patches->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM);
TreeItem *item = patches->get_item_at_position(p_point);
if (!item) {
-
return false;
}
}
@@ -707,7 +698,6 @@ bool ProjectExportDialog::can_drop_data_fw(const Point2 &p_point, const Variant
}
void ProjectExportDialog::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
-
if (p_from == presets) {
Dictionary d = p_data;
int from_pos = d["preset"];
@@ -718,12 +708,13 @@ void ProjectExportDialog::drop_data_fw(const Point2 &p_point, const Variant &p_d
to_pos = presets->get_item_at_position(p_point, true);
}
- if (to_pos == -1 && !presets->is_pos_at_end_of_items(p_point))
+ if (to_pos == -1 && !presets->is_pos_at_end_of_items(p_point)) {
return;
+ }
- if (to_pos == from_pos)
+ if (to_pos == from_pos) {
return;
- else if (to_pos > from_pos) {
+ } else if (to_pos > from_pos) {
to_pos--;
}
@@ -732,27 +723,29 @@ void ProjectExportDialog::drop_data_fw(const Point2 &p_point, const Variant &p_d
EditorExport::get_singleton()->add_export_preset(preset, to_pos);
_update_presets();
- if (to_pos >= 0)
+ if (to_pos >= 0) {
_edit_preset(to_pos);
- else
+ } else {
_edit_preset(presets->get_item_count() - 1);
+ }
} else if (p_from == patches) {
-
Dictionary d = p_data;
- if (!d.has("type") || String(d["type"]) != "export_patch")
+ if (!d.has("type") || String(d["type"]) != "export_patch") {
return;
+ }
int from_pos = d["patch"];
TreeItem *item = patches->get_item_at_position(p_point);
- if (!item)
+ if (!item) {
return;
+ }
int to_pos = item->get_cell_mode(0) == TreeItem::CELL_MODE_CHECK ? int(item->get_metadata(0)) : -1;
- if (to_pos == from_pos)
+ if (to_pos == from_pos) {
return;
- else if (to_pos > from_pos) {
+ } else if (to_pos > from_pos) {
to_pos--;
}
@@ -766,13 +759,14 @@ void ProjectExportDialog::drop_data_fw(const Point2 &p_point, const Variant &p_d
}
void ProjectExportDialog::_export_type_changed(int p_which) {
-
- if (updating)
+ if (updating) {
return;
+ }
Ref<EditorExportPreset> current = get_current_preset();
- if (current.is_null())
+ if (current.is_null()) {
return;
+ }
current->set_export_filter(EditorExportPreset::ExportFilter(p_which));
updating = true;
@@ -781,27 +775,28 @@ void ProjectExportDialog::_export_type_changed(int p_which) {
}
void ProjectExportDialog::_filter_changed(const String &p_filter) {
-
- if (updating)
+ if (updating) {
return;
+ }
Ref<EditorExportPreset> current = get_current_preset();
- if (current.is_null())
+ if (current.is_null()) {
return;
+ }
current->set_include_filter(include_filters->get_text());
current->set_exclude_filter(exclude_filters->get_text());
}
void ProjectExportDialog::_fill_resource_tree() {
-
include_files->clear();
include_label->hide();
include_margin->hide();
Ref<EditorExportPreset> current = get_current_preset();
- if (current.is_null())
+ if (current.is_null()) {
return;
+ }
EditorExportPreset::ExportFilter f = current->get_export_filter();
@@ -818,13 +813,11 @@ void ProjectExportDialog::_fill_resource_tree() {
}
bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem *p_item, Ref<EditorExportPreset> &current, bool p_only_scenes) {
-
p_item->set_icon(0, presets->get_theme_icon("folder", "FileDialog"));
p_item->set_text(0, p_dir->get_name() + "/");
bool used = false;
for (int i = 0; i < p_dir->get_subdir_count(); i++) {
-
TreeItem *subdir = include_files->create_item(p_item);
if (_fill_tree(p_dir->get_subdir(i), subdir, current, p_only_scenes)) {
used = true;
@@ -834,10 +827,10 @@ bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem
}
for (int i = 0; i < p_dir->get_file_count(); i++) {
-
String type = p_dir->get_file_type(i);
- if (p_only_scenes && type != "PackedScene")
+ if (p_only_scenes && type != "PackedScene") {
continue;
+ }
TreeItem *file = include_files->create_item(p_item);
file->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
@@ -857,17 +850,19 @@ bool ProjectExportDialog::_fill_tree(EditorFileSystemDirectory *p_dir, TreeItem
}
void ProjectExportDialog::_tree_changed() {
-
- if (updating)
+ if (updating) {
return;
+ }
Ref<EditorExportPreset> current = get_current_preset();
- if (current.is_null())
+ if (current.is_null()) {
return;
+ }
TreeItem *item = include_files->get_edited();
- if (!item)
+ if (!item) {
return;
+ }
String path = item->get_metadata(0);
bool added = item->is_checked(0);
@@ -880,12 +875,10 @@ void ProjectExportDialog::_tree_changed() {
}
void ProjectExportDialog::_export_pck_zip() {
-
export_pck_zip->popup_centered_ratio();
}
void ProjectExportDialog::_export_pck_zip_selected(const String &p_path) {
-
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
Ref<EditorExportPlatform> platform = current->get_platform();
@@ -899,7 +892,6 @@ void ProjectExportDialog::_export_pck_zip_selected(const String &p_path) {
}
void ProjectExportDialog::_open_export_template_manager() {
-
EditorNode::get_singleton()->open_export_template_manager();
hide();
}
@@ -909,10 +901,12 @@ void ProjectExportDialog::_validate_export_path(const String &p_path) {
bool invalid_path = (p_path.get_file().get_basename() == "");
// Check if state change before needlessly messing with signals
- if (invalid_path && export_project->get_ok()->is_disabled())
+ if (invalid_path && export_project->get_ok()->is_disabled()) {
return;
- if (!invalid_path && !export_project->get_ok()->is_disabled())
+ }
+ if (!invalid_path && !export_project->get_ok()->is_disabled()) {
return;
+ }
if (invalid_path) {
export_project->get_ok()->set_disabled(true);
@@ -924,7 +918,6 @@ void ProjectExportDialog::_validate_export_path(const String &p_path) {
}
void ProjectExportDialog::_export_project() {
-
Ref<EditorExportPreset> current = get_current_preset();
ERR_FAIL_COND(current.is_null());
Ref<EditorExportPlatform> platform = current->get_platform();
@@ -987,20 +980,17 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) {
}
void ProjectExportDialog::_export_all_dialog() {
-
export_all_dialog->show();
export_all_dialog->popup_centered(Size2(300, 80));
}
void ProjectExportDialog::_export_all_dialog_action(const String &p_str) {
-
export_all_dialog->hide();
_export_all(p_str != "release");
}
void ProjectExportDialog::_export_all(bool p_debug) {
-
String mode = p_debug ? TTR("Debug") : TTR("Release");
EditorProgress ep("exportall", TTR("Exporting All") + " " + mode, EditorExport::get_singleton()->get_export_preset_count(), true);
@@ -1027,7 +1017,6 @@ void ProjectExportDialog::_export_all(bool p_debug) {
}
void ProjectExportDialog::_bind_methods() {
-
ClassDB::bind_method("get_drag_data_fw", &ProjectExportDialog::get_drag_data_fw);
ClassDB::bind_method("can_drop_data_fw", &ProjectExportDialog::can_drop_data_fw);
ClassDB::bind_method("drop_data_fw", &ProjectExportDialog::drop_data_fw);
@@ -1040,7 +1029,6 @@ void ProjectExportDialog::_bind_methods() {
}
ProjectExportDialog::ProjectExportDialog() {
-
set_title(TTR("Export"));
VBoxContainer *main_vb = memnew(VBoxContainer);
@@ -1119,6 +1107,7 @@ ProjectExportDialog::ProjectExportDialog() {
parameters->set_name(TTR("Options"));
parameters->set_v_size_flags(Control::SIZE_EXPAND_FILL);
parameters->connect("property_edited", callable_mp(this, &ProjectExportDialog::_update_parameters));
+ EditorExport::get_singleton()->connect("export_presets_updated", callable_mp(this, &ProjectExportDialog::_force_update_current_preset_parameters));
// Resources export parameters.
diff --git a/editor/project_export.h b/editor/project_export.h
index 2e311eb3b3..cfa00773d8 100644
--- a/editor/project_export.h
+++ b/editor/project_export.h
@@ -123,6 +123,7 @@ private:
void _delete_preset_confirm();
void _update_export_all();
+ void _force_update_current_preset_parameters();
void _update_current_preset();
void _update_presets();
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 0ca540a33f..dc5ff6a5eb 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -59,7 +59,6 @@ static inline String get_project_key_from_path(const String &dir) {
}
class ProjectDialog : public ConfirmationDialog {
-
GDCLASS(ProjectDialog, ConfirmationDialog);
public:
@@ -107,30 +106,25 @@ private:
String created_folder_path;
void set_message(const String &p_msg, MessageType p_type = MESSAGE_SUCCESS, InputType input_type = PROJECT_PATH) {
-
msg->set_text(p_msg);
Ref<Texture2D> current_path_icon = status_rect->get_texture();
Ref<Texture2D> current_install_icon = install_status_rect->get_texture();
Ref<Texture2D> new_icon;
switch (p_type) {
-
case MESSAGE_ERROR: {
-
msg->add_theme_color_override("font_color", msg->get_theme_color("error_color", "Editor"));
msg->set_modulate(Color(1, 1, 1, 1));
new_icon = msg->get_theme_icon("StatusError", "EditorIcons");
} break;
case MESSAGE_WARNING: {
-
msg->add_theme_color_override("font_color", msg->get_theme_color("warning_color", "Editor"));
msg->set_modulate(Color(1, 1, 1, 1));
new_icon = msg->get_theme_icon("StatusWarning", "EditorIcons");
} break;
case MESSAGE_SUCCESS: {
-
msg->set_modulate(Color(1, 1, 1, 0));
new_icon = msg->get_theme_icon("StatusSuccess", "EditorIcons");
@@ -147,7 +141,6 @@ private:
}
String _test_path() {
-
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
String valid_path, valid_install_path;
if (d->change_dir(project_path->get_text()) == OK) {
@@ -187,16 +180,13 @@ private:
}
if (mode == MODE_IMPORT || mode == MODE_RENAME) {
-
if (valid_path != "" && !d->file_exists("project.godot")) {
-
if (valid_path.ends_with(".zip")) {
FileAccess *src_f = nullptr;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
unzFile pkg = unzOpen2(valid_path.utf8().get_data(), &io);
if (!pkg) {
-
set_message(TTR("Error opening package file (it's not in ZIP format)."), MESSAGE_ERROR);
memdelete(d);
get_ok()->set_disabled(true);
@@ -245,7 +235,6 @@ private:
d->list_dir_end();
if (!is_empty) {
-
set_message(TTR("Please choose an empty folder."), MESSAGE_WARNING, INSTALL_PATH);
memdelete(d);
get_ok()->set_disabled(true);
@@ -261,7 +250,6 @@ private:
}
} else if (valid_path.ends_with("zip")) {
-
set_message(TTR("This directory already contains a Godot project."), MESSAGE_ERROR, INSTALL_PATH);
memdelete(d);
get_ok()->set_disabled(true);
@@ -269,7 +257,6 @@ private:
}
} else {
-
// check if the specified folder is empty, even though this is not an error, it is good to check here
d->list_dir_begin();
bool is_empty = true;
@@ -288,7 +275,6 @@ private:
d->list_dir_end();
if (!is_empty) {
-
set_message(TTR("Please choose an empty folder."), MESSAGE_ERROR);
memdelete(d);
get_ok()->set_disabled(true);
@@ -304,10 +290,8 @@ private:
}
void _path_text_changed(const String &p_path) {
-
String sp = _test_path();
if (sp != "") {
-
// If the project name is empty or default, infer the project name from the selected folder name
if (project_name->get_text() == "" || project_name->get_text() == TTR("New Game Project")) {
sp = sp.replace("\\", "/");
@@ -316,8 +300,9 @@ private:
if (lidx != -1) {
sp = sp.substr(lidx + 1, sp.length()).capitalize();
}
- if (sp == "" && mode == MODE_IMPORT)
+ if (sp == "" && mode == MODE_IMPORT) {
sp = TTR("Imported Project");
+ }
project_name->set_text(sp);
_text_changed(sp);
@@ -330,7 +315,6 @@ private:
}
void _file_selected(const String &p_path) {
-
String p = p_path;
if (mode == MODE_IMPORT) {
if (p.ends_with("project.godot")) {
@@ -358,7 +342,6 @@ private:
}
void _path_selected(const String &p_path) {
-
String sp = p_path.simplify_path();
project_path->set_text(sp);
_path_text_changed(sp);
@@ -366,7 +349,6 @@ private:
}
void _install_path_selected(const String &p_path) {
-
String sp = p_path.simplify_path();
install_path->set_text(sp);
_path_text_changed(sp);
@@ -374,11 +356,9 @@ private:
}
void _browse_path() {
-
fdialog->set_current_dir(project_path->get_text());
if (mode == MODE_IMPORT) {
-
fdialog->set_file_mode(FileDialog::FILE_MODE_OPEN_FILE);
fdialog->clear_filters();
fdialog->add_filter(vformat("project.godot ; %s %s", VERSION_NAME, TTR("Project")));
@@ -396,7 +376,6 @@ private:
}
void _create_folder() {
-
if (project_name->get_text() == "" || created_folder_path != "" || project_name->get_text().ends_with(".") || project_name->get_text().ends_with(" ")) {
set_message(TTR("Invalid Project Name."), MESSAGE_WARNING);
return;
@@ -404,11 +383,8 @@ private:
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
if (d->change_dir(project_path->get_text()) == OK) {
-
if (!d->dir_exists(project_name->get_text())) {
-
if (d->make_dir(project_name->get_text()) == OK) {
-
d->change_dir(project_name->get_text());
String dir_str = d->get_current_dir();
project_path->set_text(dir_str);
@@ -416,12 +392,10 @@ private:
created_folder_path = d->get_current_dir();
create_dir->set_disabled(true);
} else {
-
dialog_error->set_text(TTR("Couldn't create folder."));
dialog_error->popup_centered();
}
} else {
-
dialog_error->set_text(TTR("There is already a folder in this path with the specified name."));
dialog_error->popup_centered();
}
@@ -431,22 +405,21 @@ private:
}
void _text_changed(const String &p_text) {
-
- if (mode != MODE_NEW)
+ if (mode != MODE_NEW) {
return;
+ }
_test_path();
- if (p_text == "")
+ if (p_text == "") {
set_message(TTR("It would be a good idea to name your project."), MESSAGE_WARNING);
+ }
}
void ok_pressed() {
-
String dir = project_path->get_text();
if (mode == MODE_RENAME) {
-
String dir2 = _test_path();
if (dir2 == "") {
set_message(TTR("Invalid project path (changed anything?)."), MESSAGE_ERROR);
@@ -471,11 +444,8 @@ private:
emit_signal("projects_updated");
} else {
-
if (mode == MODE_IMPORT) {
-
if (project_path->get_text().ends_with(".zip")) {
-
mode = MODE_INSTALL;
ok_pressed();
@@ -484,7 +454,6 @@ private:
} else {
if (mode == MODE_NEW) {
-
ProjectSettings::CustomMap initial_settings;
if (rasterizer_button_group->get_pressed_button()->get_meta("driver_name") == "Vulkan") {
initial_settings["rendering/quality/driver/driver_name"] = "Vulkan";
@@ -516,7 +485,6 @@ private:
}
} else if (mode == MODE_INSTALL) {
-
if (project_path->get_text().ends_with(".zip")) {
dir = install_path->get_text();
zip_path = project_path->get_text();
@@ -527,7 +495,6 @@ private:
unzFile pkg = unzOpen2(zip_path.utf8().get_data(), &io);
if (!pkg) {
-
dialog_error->set_text(TTR("Error opening package file, not in ZIP format."));
dialog_error->popup_centered();
return;
@@ -539,7 +506,6 @@ private:
int idx = 0;
while (ret == UNZ_OK) {
-
//get filename
unz_file_info info;
char fname[16384];
@@ -570,7 +536,6 @@ private:
memdelete(da);
} else {
-
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
@@ -598,7 +563,6 @@ private:
if (failed_files.size()) {
String msg = TTR("The following files failed extraction from package:") + "\n\n";
for (int i = 0; i < failed_files.size(); i++) {
-
if (i > 15) {
msg += "\nAnd " + itos(failed_files.size() - i) + " more files.";
break;
@@ -617,8 +581,9 @@ private:
}
dir = dir.replace("\\", "/");
- if (dir.ends_with("/"))
+ if (dir.ends_with("/")) {
dir = dir.substr(0, dir.length() - 1);
+ }
String proj = get_project_key_from_path(dir);
EditorSettings::get_singleton()->set("projects/" + proj, dir);
EditorSettings::get_singleton()->save();
@@ -629,7 +594,6 @@ private:
}
void _remove_created_folder() {
-
if (created_folder_path != "") {
DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
d->remove(created_folder_path);
@@ -641,7 +605,6 @@ private:
}
void cancel_pressed() {
-
_remove_created_folder();
project_path->clear();
@@ -649,22 +612,23 @@ private:
project_name->clear();
_text_changed("");
- if (status_rect->get_texture() == msg->get_theme_icon("StatusError", "EditorIcons"))
+ if (status_rect->get_texture() == msg->get_theme_icon("StatusError", "EditorIcons")) {
msg->show();
+ }
- if (install_status_rect->get_texture() == msg->get_theme_icon("StatusError", "EditorIcons"))
+ if (install_status_rect->get_texture() == msg->get_theme_icon("StatusError", "EditorIcons")) {
msg->show();
+ }
}
void _notification(int p_what) {
-
- if (p_what == NOTIFICATION_WM_CLOSE_REQUEST)
+ if (p_what == NOTIFICATION_WM_CLOSE_REQUEST) {
_remove_created_folder();
+ }
}
protected:
static void _bind_methods() {
-
ClassDB::bind_method("_browse_path", &ProjectDialog::_browse_path);
ClassDB::bind_method("_create_folder", &ProjectDialog::_create_folder);
ClassDB::bind_method("_text_changed", &ProjectDialog::_text_changed);
@@ -686,7 +650,6 @@ public:
}
void set_mode(Mode p_mode) {
-
mode = p_mode;
}
@@ -695,9 +658,7 @@ public:
}
void show_dialog() {
-
if (mode == MODE_RENAME) {
-
project_path->set_editable(false);
browse->hide();
install_browse->hide();
@@ -731,7 +692,6 @@ public:
create_dir->hide();
} else {
-
fav_dir = EditorSettings::get_singleton()->get("filesystem/directories/default_project_path");
if (fav_dir != "") {
project_path->set_text(fav_dir);
@@ -765,7 +725,6 @@ public:
project_path->grab_focus();
} else if (mode == MODE_NEW) {
-
set_title(TTR("Create New Project"));
get_ok()->set_text(TTR("Create & Edit"));
name_container->show();
@@ -775,7 +734,6 @@ public:
project_name->call_deferred("select_all");
} else if (mode == MODE_INSTALL) {
-
set_title(TTR("Install Project:") + " " + zip_title);
get_ok()->set_text(TTR("Install & Edit"));
project_name->set_text(zip_title);
@@ -792,7 +750,6 @@ public:
}
ProjectDialog() {
-
VBoxContainer *vb = memnew(VBoxContainer);
add_child(vb);
@@ -1024,7 +981,6 @@ public:
bool p_grayed,
bool p_missing,
int p_version) {
-
project_key = p_project;
project_name = p_name;
description = p_description;
@@ -1137,7 +1093,6 @@ void ProjectList::update_icons_async() {
void ProjectList::_notification(int p_what) {
if (p_what == NOTIFICATION_PROCESS) {
-
// Load icons as a coroutine to speed up launch when you have hundreds of projects
if (_icon_load_index < _projects.size()) {
Item &item = _projects.write[_icon_load_index];
@@ -1162,7 +1117,6 @@ void ProjectList::load_project_icon(int p_index) {
img.instance();
Error err = img->load(item.icon.replace_first("res://", item.path + "/"));
if (err == OK) {
-
img->resize(default_icon->get_width(), default_icon->get_height(), Image::INTERPOLATE_LANCZOS);
Ref<ImageTexture> it = memnew(ImageTexture);
it->create_from_image(img);
@@ -1178,7 +1132,6 @@ void ProjectList::load_project_icon(int p_index) {
}
void ProjectList::load_project_data(const String &p_property_key, Item &p_item, bool p_favorite) {
-
String path = EditorSettings::get_singleton()->get(p_property_key);
String conf = path.plus_file("project.godot");
bool grayed = false;
@@ -1191,8 +1144,9 @@ void ProjectList::load_project_data(const String &p_property_key, Item &p_item,
String project_name = TTR("Unnamed Project");
if (cf_err == OK) {
String cf_project_name = static_cast<String>(cf->get_value("application", "config/name", ""));
- if (cf_project_name != "")
+ if (cf_project_name != "") {
project_name = cf_project_name.xml_unescape();
+ }
config_version = (int)cf->get_value("", "config_version", 0);
}
@@ -1215,8 +1169,9 @@ void ProjectList::load_project_data(const String &p_property_key, Item &p_item,
String fscache = path.plus_file(".fscache");
if (FileAccess::exists(fscache)) {
uint64_t cache_modified = FileAccess::get_modified_time(fscache);
- if (cache_modified > last_edited)
+ if (cache_modified > last_edited) {
last_edited = cache_modified;
+ }
}
} else {
grayed = true;
@@ -1262,8 +1217,9 @@ void ProjectList::load_projects() {
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
// This is actually something like "projects/C:::Documents::Godot::Projects::MyGame"
String property_key = E->get().name;
- if (!property_key.begins_with("projects/"))
+ if (!property_key.begins_with("projects/")) {
continue;
+ }
String project_key = property_key.get_slice("/", 1);
bool favorite = favorites.has("favorite_projects/" + project_key);
@@ -1289,7 +1245,6 @@ void ProjectList::load_projects() {
}
void ProjectList::update_dock_menu() {
-
if (!DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_GLOBAL_MENU)) {
return;
}
@@ -1341,7 +1296,6 @@ void ProjectList::_global_menu_open_project(const Variant &p_tag) {
}
void ProjectList::create_project_item_control(int p_index) {
-
// Will be added last in the list, so make sure indexes match
ERR_FAIL_COND(p_index != _scroll_children->get_child_count());
@@ -1383,8 +1337,9 @@ void ProjectList::create_project_item_control(int p_index) {
hb->icon = tf;
VBoxContainer *vb = memnew(VBoxContainer);
- if (item.grayed)
+ if (item.grayed) {
vb->set_modulate(Color(1, 1, 1, 0.5));
+ }
vb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
hb->add_child(vb);
Control *ec = memnew(Control);
@@ -1442,7 +1397,6 @@ void ProjectList::set_order_option(ProjectListFilter::FilterOption p_option) {
}
void ProjectList::sort_projects() {
-
SortArray<Item, ProjectListComparator> sorter;
sorter.compare.order_option = _order_option;
sorter.sort(_projects.ptrw(), _projects.size());
@@ -1452,7 +1406,6 @@ void ProjectList::sort_projects() {
bool visible = true;
if (_search_term != "") {
-
String search_path;
if (_search_term.find("/") != -1) {
// Search path will match the whole path
@@ -1568,7 +1521,6 @@ bool ProjectList::is_any_project_missing() const {
}
void ProjectList::erase_missing_projects() {
-
if (_projects.empty()) {
return;
}
@@ -1669,7 +1621,6 @@ int ProjectList::get_project_count() const {
}
void ProjectList::select_project(int p_index) {
-
Vector<Item> previous_selected_items = get_selected_projects();
_selected_project_keys.clear();
@@ -1724,7 +1675,6 @@ void ProjectList::toggle_select(int p_index) {
}
void ProjectList::erase_selected_projects() {
-
if (_selected_project_keys.size() == 0) {
return;
}
@@ -1732,7 +1682,6 @@ void ProjectList::erase_selected_projects() {
for (int i = 0; i < _projects.size(); ++i) {
Item &item = _projects.write[i];
if (_selected_project_keys.has(item.project_key) && item.control->is_visible()) {
-
EditorSettings::get_singleton()->erase("projects/" + item.project_key);
EditorSettings::get_singleton()->erase("favorite_projects/" + item.project_key);
@@ -1765,15 +1714,12 @@ void ProjectList::_panel_draw(Node *p_hb) {
// Input for each item in the list
void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
-
Ref<InputEventMouseButton> mb = p_ev;
int clicked_index = p_hb->get_index();
const Item &clicked_project = _projects[clicked_index];
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
if (mb->get_shift() && _selected_project_keys.size() > 0 && _last_clicked != "" && clicked_project.project_key != _last_clicked) {
-
int anchor_index = -1;
for (int i = 0; i < _projects.size(); ++i) {
const Item &p = _projects[i];
@@ -1802,7 +1748,6 @@ void ProjectList::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
}
void ProjectList::_favorite_pressed(Node *p_hb) {
-
ProjectListItemControl *control = Object::cast_to<ProjectListItemControl>(p_hb);
int index = control->get_index();
@@ -1836,7 +1781,6 @@ void ProjectList::_favorite_pressed(Node *p_hb) {
}
void ProjectList::_show_project(const String &p_path) {
-
OS::get_singleton()->shell_open(String("file://") + p_path);
}
@@ -1844,28 +1788,24 @@ const char *ProjectList::SIGNAL_SELECTION_CHANGED = "selection_changed";
const char *ProjectList::SIGNAL_PROJECT_ASK_OPEN = "project_ask_open";
void ProjectList::_bind_methods() {
-
ADD_SIGNAL(MethodInfo(SIGNAL_SELECTION_CHANGED));
ADD_SIGNAL(MethodInfo(SIGNAL_PROJECT_ASK_OPEN));
}
void ProjectManager::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
-
Engine::get_singleton()->set_editor_hint(false);
} break;
case NOTIFICATION_RESIZED: {
-
if (open_templates->is_visible()) {
open_templates->popup_centered();
}
} break;
case NOTIFICATION_READY: {
-
- if (_project_list->get_project_count() == 0 && StreamPeerSSL::is_available())
+ if (_project_list->get_project_count() == 0 && StreamPeerSSL::is_available()) {
open_templates->popup_centered();
+ }
if (_project_list->get_project_count() >= 1) {
// Focus on the search box immediately to allow the user
@@ -1874,18 +1814,15 @@ void ProjectManager::_notification(int p_what) {
}
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
set_process_unhandled_input(is_visible_in_tree());
} break;
case NOTIFICATION_WM_CLOSE_REQUEST: {
-
_dim_window();
} break;
}
}
void ProjectManager::_dim_window() {
-
// This method must be called before calling `get_tree()->quit()`.
// Otherwise, its effect won't be visible
@@ -1897,7 +1834,6 @@ void ProjectManager::_dim_window() {
}
void ProjectManager::_update_project_buttons() {
-
Vector<ProjectList::Item> selected_projects = _project_list->get_selected_projects();
bool empty_selection = selected_projects.empty();
@@ -1918,11 +1854,9 @@ void ProjectManager::_update_project_buttons() {
}
void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
-
Ref<InputEventKey> k = p_ev;
if (k.is_valid()) {
-
if (!k->is_pressed()) {
return;
}
@@ -1937,23 +1871,20 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
}
#endif
- if (tabs->get_current_tab() != 0)
+ if (tabs->get_current_tab() != 0) {
return;
+ }
bool keycode_handled = true;
switch (k->get_keycode()) {
-
case KEY_ENTER: {
-
_open_selected_projects_ask();
} break;
case KEY_DELETE: {
-
_erase_project();
} break;
case KEY_HOME: {
-
if (_project_list->get_project_count() > 0) {
_project_list->select_project(0);
_update_project_buttons();
@@ -1961,7 +1892,6 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
} break;
case KEY_END: {
-
if (_project_list->get_project_count() > 0) {
_project_list->select_project(_project_list->get_project_count() - 1);
_update_project_buttons();
@@ -1969,9 +1899,9 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
} break;
case KEY_UP: {
-
- if (k->get_shift())
+ if (k->get_shift()) {
break;
+ }
int index = _project_list->get_single_selected_index();
if (index > 0) {
@@ -1983,9 +1913,9 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
break;
}
case KEY_DOWN: {
-
- if (k->get_shift())
+ if (k->get_shift()) {
break;
+ }
int index = _project_list->get_single_selected_index();
if (index + 1 < _project_list->get_project_count()) {
@@ -1996,10 +1926,11 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
} break;
case KEY_F: {
- if (k->get_command())
+ if (k->get_command()) {
this->project_filter->search_box->grab_focus();
- else
+ } else {
keycode_handled = false;
+ }
} break;
default: {
keycode_handled = false;
@@ -2013,7 +1944,6 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
}
void ProjectManager::_load_recent_projects() {
-
_project_list->set_order_option(project_order_filter->get_filter_option());
_project_list->set_search_term(project_filter->get_search_term());
_project_list->load_projects();
@@ -2051,7 +1981,6 @@ void ProjectManager::_confirm_update_settings() {
}
void ProjectManager::_open_selected_projects() {
-
const Set<String> &selected_list = _project_list->get_selected_project_keys();
for (const Set<String>::Element *E = selected_list.front(); E; E = E->next()) {
@@ -2090,7 +2019,6 @@ void ProjectManager::_open_selected_projects() {
}
void ProjectManager::_open_selected_projects_ask() {
-
const Set<String> &selected_list = _project_list->get_selected_project_keys();
if (selected_list.size() < 1) {
@@ -2136,11 +2064,9 @@ void ProjectManager::_open_selected_projects_ask() {
}
void ProjectManager::_run_project_confirm() {
-
Vector<ProjectList::Item> selected_list = _project_list->get_selected_projects();
for (int i = 0; i < selected_list.size(); ++i) {
-
const String &selected_main = selected_list[i].main_scene;
if (selected_main == "") {
run_error_diag->set_text(TTR("Can't run project: no main scene defined.\nPlease edit the project and set the main scene in the Project Settings under the \"Application\" category."));
@@ -2178,7 +2104,6 @@ void ProjectManager::_run_project_confirm() {
// When you press the "Run" button
void ProjectManager::_run_project() {
-
const Set<String> &selected_list = _project_list->get_selected_project_keys();
if (selected_list.size() < 1) {
@@ -2211,7 +2136,6 @@ void ProjectManager::_scan_dir(const String &path, List<String> *r_projects) {
}
void ProjectManager::_scan_begin(const String &p_base) {
-
print_line("Scanning projects at: " + p_base);
List<String> projects;
_scan_dir(p_base, &projects);
@@ -2226,24 +2150,20 @@ void ProjectManager::_scan_begin(const String &p_base) {
}
void ProjectManager::_scan_projects() {
-
scan_dir->popup_centered_ratio();
}
void ProjectManager::_new_project() {
-
npdialog->set_mode(ProjectDialog::MODE_NEW);
npdialog->show_dialog();
}
void ProjectManager::_import_project() {
-
npdialog->set_mode(ProjectDialog::MODE_IMPORT);
npdialog->show_dialog();
}
void ProjectManager::_rename_project() {
-
const Set<String> &selected_list = _project_list->get_selected_project_keys();
if (selected_list.size() == 0) {
@@ -2270,11 +2190,11 @@ void ProjectManager::_erase_missing_projects_confirm() {
}
void ProjectManager::_erase_project() {
-
const Set<String> &selected_list = _project_list->get_selected_project_keys();
- if (selected_list.size() == 0)
+ if (selected_list.size() == 0) {
return;
+ }
String confirm_message;
if (selected_list.size() >= 2) {
@@ -2288,13 +2208,11 @@ void ProjectManager::_erase_project() {
}
void ProjectManager::_erase_missing_projects() {
-
erase_missing_ask->set_text(TTR("Remove all missing projects from the list?\nThe project folders' contents won't be modified."));
erase_missing_ask->popup_centered();
}
void ProjectManager::_language_selected(int p_id) {
-
String lang = language_btn->get_item_metadata(p_id);
EditorSettings::get_singleton()->set("interface/editor/editor_language", lang);
language_btn->set_text(lang);
@@ -2305,7 +2223,6 @@ void ProjectManager::_language_selected(int p_id) {
}
void ProjectManager::_restart_confirm() {
-
List<String> args = OS::get_singleton()->get_cmdline_args();
String exec = OS::get_singleton()->get_executable_path();
OS::ProcessID pid = 0;
@@ -2317,13 +2234,11 @@ void ProjectManager::_restart_confirm() {
}
void ProjectManager::_exit_dialog() {
-
_dim_window();
get_tree()->quit();
}
void ProjectManager::_install_project(const String &p_zip_path, const String &p_title) {
-
npdialog->set_mode(ProjectDialog::MODE_INSTALL);
npdialog->set_zip_path(p_zip_path);
npdialog->set_zip_title(p_title);
@@ -2395,7 +2310,6 @@ void ProjectManager::_on_filter_option_changed() {
}
void ProjectManager::_bind_methods() {
-
ClassDB::bind_method("_exit_dialog", &ProjectManager::_exit_dialog);
ClassDB::bind_method("_unhandled_input", &ProjectManager::_unhandled_input);
ClassDB::bind_method("_update_project_buttons", &ProjectManager::_update_project_buttons);
@@ -2407,10 +2321,10 @@ void ProjectManager::_open_asset_library() {
}
ProjectManager::ProjectManager() {
-
// load settings
- if (!EditorSettings::get_singleton())
+ if (!EditorSettings::get_singleton()) {
EditorSettings::create();
+ }
EditorSettings::get_singleton()->set_optimize_save(false); //just write settings as they came
@@ -2429,12 +2343,24 @@ ProjectManager::ProjectManager() {
#endif
} break;
- case 1: editor_set_scale(0.75); break;
- case 2: editor_set_scale(1.0); break;
- case 3: editor_set_scale(1.25); break;
- case 4: editor_set_scale(1.5); break;
- case 5: editor_set_scale(1.75); break;
- case 6: editor_set_scale(2.0); break;
+ case 1:
+ editor_set_scale(0.75);
+ break;
+ case 2:
+ editor_set_scale(1.0);
+ break;
+ case 3:
+ editor_set_scale(1.25);
+ break;
+ case 4:
+ editor_set_scale(1.5);
+ break;
+ case 5:
+ editor_set_scale(1.75);
+ break;
+ case 6:
+ editor_set_scale(2.0);
+ break;
default: {
editor_set_scale(custom_display_scale);
@@ -2718,16 +2644,16 @@ ProjectManager::ProjectManager() {
}
ProjectManager::~ProjectManager() {
-
- if (EditorSettings::get_singleton())
+ if (EditorSettings::get_singleton()) {
EditorSettings::destroy();
+ }
}
void ProjectListFilter::_setup_filters(Vector<String> options) {
-
filter_option->clear();
- for (int i = 0; i < options.size(); i++)
+ for (int i = 0; i < options.size(); i++) {
filter_option->add_item(options[i]);
+ }
}
void ProjectListFilter::_search_text_changed(const String &p_newtext) {
@@ -2751,13 +2677,13 @@ void ProjectListFilter::_filter_option_selected(int p_idx) {
FilterOption selected = (FilterOption)(filter_option->get_selected());
if (_current_filter != selected) {
_current_filter = selected;
- if (is_inside_tree())
+ if (is_inside_tree()) {
emit_signal("filter_changed");
+ }
}
}
void ProjectListFilter::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE && has_search_box) {
search_box->set_right_icon(get_theme_icon("Search", "EditorIcons"));
search_box->set_clear_button_enabled(true);
@@ -2765,7 +2691,6 @@ void ProjectListFilter::_notification(int p_what) {
}
void ProjectListFilter::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("filter_changed"));
}
@@ -2779,6 +2704,8 @@ void ProjectListFilter::add_filter_option() {
void ProjectListFilter::add_search_box() {
search_box = memnew(LineEdit);
search_box->set_placeholder(TTR("Search"));
+ search_box->set_tooltip(
+ TTR("The search box filters projects by name and last path component.\nTo filter projects by name and full path, the query must contain at least one `/` character."));
search_box->connect("text_changed", callable_mp(this, &ProjectListFilter::_search_text_changed));
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
add_child(search_box);
@@ -2791,7 +2718,6 @@ void ProjectListFilter::set_filter_size(int h_size) {
}
ProjectListFilter::ProjectListFilter() {
-
_current_filter = FILTER_NAME;
has_search_box = false;
}
diff --git a/editor/project_manager.h b/editor/project_manager.h
index 6385000821..e5471bd392 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -43,7 +43,6 @@ class ProjectList;
class ProjectListFilter;
class ProjectManager : public Control {
-
GDCLASS(ProjectManager, Control);
Button *erase_btn;
@@ -126,7 +125,6 @@ public:
};
class ProjectListFilter : public HBoxContainer {
-
GDCLASS(ProjectListFilter, HBoxContainer);
public:
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 49c02dc895..a7c260c0f8 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -43,45 +43,51 @@
ProjectSettingsEditor *ProjectSettingsEditor::singleton = nullptr;
-static const char *_button_names[JOY_BUTTON_MAX] = {
- "DualShock Cross, Xbox A, Nintendo B",
- "DualShock Circle, Xbox B, Nintendo A",
- "DualShock Square, Xbox X, Nintendo Y",
- "DualShock Triangle, Xbox Y, Nintendo X",
- "L, L1",
- "R, R1",
- "L2",
- "R2",
- "L3",
- "R3",
- "Select, DualShock Share, Nintendo -",
- "Start, DualShock Options, Nintendo +",
+static const char *_button_descriptions[JOY_SDL_BUTTONS] = {
+ "Face Bottom, DualShock Cross, Xbox A, Nintendo B",
+ "Face Right, DualShock Circle, Xbox B, Nintendo A",
+ "Face Left, DualShock Square, Xbox X, Nintendo Y",
+ "Face Top, DualShock Triangle, Xbox Y, Nintendo X",
+ "DualShock Select, Xbox Back, Nintendo -",
+ "Home, DualShock PS, Guide",
+ "Start, Nintendo +",
+ "Left Stick, DualShock L3, Xbox L/LS",
+ "Right Stick, DualShock R3, Xbox R/RS",
+ "Left Shoulder, DualShock L1, Xbox LB",
+ "Right Shoulder, DualShock R1, Xbox RB",
"D-Pad Up",
"D-Pad Down",
"D-Pad Left",
"D-Pad Right"
};
-static const char *_axis_names[JOY_AXIS_MAX * 2] = {
- " (Left Stick Left)",
- " (Left Stick Right)",
- " (Left Stick Up)",
- " (Left Stick Down)",
- " (Right Stick Left)",
- " (Right Stick Right)",
- " (Right Stick Up)",
- " (Right Stick Down)",
- "", "", "", "",
- "", " (L2)",
- "", " (R2)"
+static const char *_axis_descriptions[JOY_AXIS_MAX * 2] = {
+ "Left Stick Left",
+ "Left Stick Right",
+ "Left Stick Up",
+ "Left Stick Down",
+ "Right Stick Left",
+ "Right Stick Right",
+ "Right Stick Up",
+ "Right Stick Down",
+ "Joystick 2 Left",
+ "Joystick 2 Right, Left Trigger, L2, LT",
+ "Joystick 2 Up",
+ "Joystick 2 Down, Right Trigger, R2, RT",
+ "Joystick 3 Left",
+ "Joystick 3 Right",
+ "Joystick 3 Up",
+ "Joystick 3 Down",
+ "Joystick 4 Left",
+ "Joystick 4 Right",
+ "Joystick 4 Up",
+ "Joystick 4 Down",
};
void ProjectSettingsEditor::_unhandled_input(const Ref<InputEvent> &p_event) {
-
const Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed()) {
-
if (k->get_keycode_with_modifiers() == (KEY_MASK_CMD | KEY_F)) {
if (search_button->is_pressed()) {
search_box->grab_focus();
@@ -97,7 +103,6 @@ void ProjectSettingsEditor::_unhandled_input(const Ref<InputEvent> &p_event) {
}
void ProjectSettingsEditor::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (!is_visible()) {
@@ -125,14 +130,12 @@ void ProjectSettingsEditor::_notification(int p_what) {
List<String> tfn;
ResourceLoader::get_recognized_extensions_for_type("Translation", &tfn);
for (List<String>::Element *E = tfn.front(); E; E = E->next()) {
-
translation_file_open->add_filter("*." + E->get());
}
List<String> rfn;
ResourceLoader::get_recognized_extensions_for_type("Resource", &rfn);
for (List<String>::Element *E = rfn.front(); E; E = E->next()) {
-
translation_res_file_open->add_filter("*." + E->get());
translation_res_option_file_open->add_filter("*." + E->get());
}
@@ -160,39 +163,40 @@ void ProjectSettingsEditor::_notification(int p_what) {
static bool _validate_action_name(const String &p_name) {
const CharType *cstr = p_name.c_str();
- for (int i = 0; cstr[i]; i++)
+ for (int i = 0; cstr[i]; i++) {
if (cstr[i] == '/' || cstr[i] == ':' || cstr[i] == '"' ||
- cstr[i] == '=' || cstr[i] == '\\' || cstr[i] < 32)
+ cstr[i] == '=' || cstr[i] == '\\' || cstr[i] < 32) {
return false;
+ }
+ }
return true;
}
void ProjectSettingsEditor::_action_selected() {
-
TreeItem *ti = input_editor->get_selected();
- if (!ti || !ti->is_editable(0))
+ if (!ti || !ti->is_editable(0)) {
return;
+ }
add_at = "input/" + ti->get_text(0);
edit_idx = -1;
}
void ProjectSettingsEditor::_action_edited() {
-
TreeItem *ti = input_editor->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
if (input_editor->get_selected_column() == 0) {
-
String new_name = ti->get_text(0);
String old_name = add_at.substr(add_at.find("/") + 1, add_at.length());
- if (new_name == old_name)
+ if (new_name == old_name) {
return;
+ }
if (new_name == "" || !_validate_action_name(new_name)) {
-
ti->set_text(0, old_name);
add_at = "input/" + old_name;
@@ -204,7 +208,6 @@ void ProjectSettingsEditor::_action_edited() {
String action_prop = "input/" + new_name;
if (ProjectSettings::get_singleton()->has_setting(action_prop)) {
-
ti->set_text(0, old_name);
add_at = "input/" + old_name;
@@ -233,7 +236,6 @@ void ProjectSettingsEditor::_action_edited() {
add_at = action_prop;
} else if (input_editor->get_selected_column() == 1) {
-
String name = "input/" + ti->get_text(0);
Dictionary old_action = ProjectSettings::get_singleton()->get(name);
Dictionary new_action = old_action.duplicate();
@@ -249,7 +251,6 @@ void ProjectSettingsEditor::_action_edited() {
}
void ProjectSettingsEditor::_device_input_add() {
-
Ref<InputEvent> ie;
String name = add_at;
int idx = edit_idx;
@@ -258,19 +259,17 @@ void ProjectSettingsEditor::_device_input_add() {
Array events = action["events"];
switch (add_type) {
-
case INPUT_MOUSE_BUTTON: {
-
Ref<InputEventMouseButton> mb;
mb.instance();
mb->set_button_index(device_index->get_selected() + 1);
mb->set_device(_get_current_device());
for (int i = 0; i < events.size(); i++) {
-
Ref<InputEventMouseButton> aie = events[i];
- if (aie.is_null())
+ if (aie.is_null()) {
continue;
+ }
if (aie->get_device() == mb->get_device() && aie->get_button_index() == mb->get_button_index()) {
return;
}
@@ -280,7 +279,6 @@ void ProjectSettingsEditor::_device_input_add() {
} break;
case INPUT_JOY_MOTION: {
-
Ref<InputEventJoypadMotion> jm;
jm.instance();
jm->set_axis(device_index->get_selected() >> 1);
@@ -288,10 +286,10 @@ void ProjectSettingsEditor::_device_input_add() {
jm->set_device(_get_current_device());
for (int i = 0; i < events.size(); i++) {
-
Ref<InputEventJoypadMotion> aie = events[i];
- if (aie.is_null())
+ if (aie.is_null()) {
continue;
+ }
if (aie->get_device() == jm->get_device() && aie->get_axis() == jm->get_axis() && aie->get_axis_value() == jm->get_axis_value()) {
return;
@@ -302,7 +300,6 @@ void ProjectSettingsEditor::_device_input_add() {
} break;
case INPUT_JOY_BUTTON: {
-
Ref<InputEventJoypadButton> jb;
jb.instance();
@@ -310,10 +307,10 @@ void ProjectSettingsEditor::_device_input_add() {
jb->set_device(_get_current_device());
for (int i = 0; i < events.size(); i++) {
-
Ref<InputEventJoypadButton> aie = events[i];
- if (aie.is_null())
+ if (aie.is_null()) {
continue;
+ }
if (aie->get_device() == jb->get_device() && aie->get_button_index() == jb->get_button_index()) {
return;
}
@@ -353,15 +350,16 @@ int ProjectSettingsEditor::_get_current_device() {
}
String ProjectSettingsEditor::_get_device_string(int i_device) {
- if (i_device == InputMap::ALL_DEVICES)
+ if (i_device == InputMap::ALL_DEVICES) {
return TTR("All Devices");
+ }
return TTR("Device") + " " + itos(i_device);
}
void ProjectSettingsEditor::_press_a_key_confirm() {
-
- if (last_wait_for_key.is_null())
+ if (last_wait_for_key.is_null()) {
return;
+ }
Ref<InputEventKey> ie;
ie.instance();
@@ -385,10 +383,10 @@ void ProjectSettingsEditor::_press_a_key_confirm() {
Array events = action["events"];
for (int i = 0; i < events.size(); i++) {
-
Ref<InputEventKey> aie = events[i];
- if (aie.is_null())
+ if (aie.is_null()) {
continue;
+ }
if (!press_a_key_physical) {
if (aie->get_keycode_with_modifiers() == ie->get_keycode_with_modifiers()) {
return;
@@ -424,11 +422,13 @@ void ProjectSettingsEditor::_show_last_added(const Ref<InputEvent> &p_event, con
String name = p_name;
name.erase(0, 6);
- if (!r)
+ if (!r) {
return;
+ }
r = r->get_children();
- if (!r)
+ if (!r) {
return;
+ }
bool found = false;
while (r) {
if (r->get_text(0) != name) {
@@ -446,19 +446,21 @@ void ProjectSettingsEditor::_show_last_added(const Ref<InputEvent> &p_event, con
}
child = child->get_next();
}
- if (found) break;
+ if (found) {
+ break;
+ }
r = r->get_next();
}
- if (found) input_editor->ensure_cursor_is_visible();
+ if (found) {
+ input_editor->ensure_cursor_is_visible();
+ }
}
void ProjectSettingsEditor::_wait_for_key(const Ref<InputEvent> &p_event) {
-
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed() && k->get_keycode() != 0) {
-
last_wait_for_key = p_event;
const String str = (press_a_key_physical) ? keycode_get_string(k->get_physical_keycode_with_modifiers()) + TTR(" (Physical)") : keycode_get_string(k->get_keycode_with_modifiers());
@@ -469,13 +471,10 @@ void ProjectSettingsEditor::_wait_for_key(const Ref<InputEvent> &p_event) {
}
void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_event) {
-
add_type = InputType(p_item);
switch (add_type) {
-
case INPUT_KEY: {
-
press_a_key_physical = false;
press_a_key_label->set_text(TTR("Press a Key..."));
press_a_key->get_ok()->set_disabled(true);
@@ -485,7 +484,6 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
} break;
case INPUT_KEY_PHYSICAL: {
-
press_a_key_physical = true;
press_a_key_label->set_text(TTR("Press a Key..."));
@@ -495,7 +493,6 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
} break;
case INPUT_MOUSE_BUTTON: {
-
device_index_label->set_text(TTR("Mouse Button Index:"));
device_index->clear();
device_index->add_item(TTR("Left Button"));
@@ -521,13 +518,12 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
} break;
case INPUT_JOY_MOTION: {
-
device_index_label->set_text(TTR("Joypad Axis Index:"));
device_index->clear();
for (int i = 0; i < JOY_AXIS_MAX * 2; i++) {
-
- String desc = _axis_names[i];
- device_index->add_item(TTR("Axis") + " " + itos(i / 2) + " " + ((i & 1) ? "+" : "-") + desc);
+ String desc = TTR("Axis") + " " + itos(i / 2) + " " + ((i & 1) ? "+" : "-") +
+ " (" + TTR(_axis_descriptions[i]) + ")";
+ device_index->add_item(desc);
}
device_input->popup_centered(Size2(350, 95) * EDSCALE);
@@ -543,13 +539,14 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
} break;
case INPUT_JOY_BUTTON: {
-
device_index_label->set_text(TTR("Joypad Button Index:"));
device_index->clear();
-
for (int i = 0; i < JOY_BUTTON_MAX; i++) {
-
- device_index->add_item(itos(i) + ": " + String(_button_names[i]));
+ String desc = TTR("Button") + " " + itos(i);
+ if (i < JOY_SDL_BUTTONS) {
+ desc += " (" + TTR(_button_descriptions[i]) + ")";
+ }
+ device_index->add_item(desc);
}
device_input->popup_centered(Size2(350, 95) * EDSCALE);
@@ -570,7 +567,6 @@ void ProjectSettingsEditor::_add_item(int p_item, Ref<InputEvent> p_exiting_even
}
void ProjectSettingsEditor::_edit_item(Ref<InputEvent> p_exiting_event) {
-
InputType ie_type;
if ((Ref<InputEventKey>(p_exiting_event)).is_valid()) {
@@ -595,12 +591,13 @@ void ProjectSettingsEditor::_edit_item(Ref<InputEvent> p_exiting_event) {
_add_item(ie_type, p_exiting_event);
}
-void ProjectSettingsEditor::_action_activated() {
+void ProjectSettingsEditor::_action_activated() {
TreeItem *ti = input_editor->get_selected();
- if (!ti || ti->get_parent() == input_editor->get_root())
+ if (!ti || ti->get_parent() == input_editor->get_root()) {
return;
+ }
String name = "input/" + ti->get_parent()->get_text(0);
int idx = ti->get_metadata(0);
@@ -609,8 +606,9 @@ void ProjectSettingsEditor::_action_activated() {
ERR_FAIL_INDEX(idx, events.size());
Ref<InputEvent> event = events[idx];
- if (event.is_null())
+ if (event.is_null()) {
return;
+ }
add_at = name;
edit_idx = idx;
@@ -618,7 +616,6 @@ void ProjectSettingsEditor::_action_activated() {
}
void ProjectSettingsEditor::_action_button_pressed(Object *p_obj, int p_column, int p_id) {
-
TreeItem *ti = Object::cast_to<TreeItem>(p_obj);
ERR_FAIL_COND(!ti);
@@ -694,8 +691,9 @@ void ProjectSettingsEditor::_action_button_pressed(Object *p_obj, int p_column,
Ref<InputEvent> event = events[idx];
- if (event.is_null())
+ if (event.is_null()) {
return;
+ }
ti->set_as_cursor(0);
add_at = name;
@@ -706,9 +704,9 @@ void ProjectSettingsEditor::_action_button_pressed(Object *p_obj, int p_column,
}
void ProjectSettingsEditor::_update_actions() {
-
- if (setting)
+ if (setting) {
return;
+ }
Map<String, bool> collapsed;
@@ -726,14 +724,15 @@ void ProjectSettingsEditor::_update_actions() {
ProjectSettings::get_singleton()->get_property_list(&props);
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
const PropertyInfo &pi = E->get();
- if (!pi.name.begins_with("input/"))
+ if (!pi.name.begins_with("input/")) {
continue;
+ }
String name = pi.name.get_slice("/", 1);
- if (name == "")
+ if (name == "") {
continue;
+ }
Dictionary action = ProjectSettings::get_singleton()->get(pi.name);
Array events = action["events"];
@@ -741,8 +740,9 @@ void ProjectSettingsEditor::_update_actions() {
TreeItem *item = input_editor->create_item(root);
item->set_text(0, name);
item->set_custom_bg_color(0, input_editor->get_theme_color("prop_subsection", "Editor"));
- if (collapsed.has(name))
+ if (collapsed.has(name)) {
item->set_collapsed(collapsed[name]);
+ }
item->set_editable(1, true);
item->set_cell_mode(1, TreeItem::CELL_MODE_RANGE);
@@ -766,16 +766,15 @@ void ProjectSettingsEditor::_update_actions() {
}
for (int i = 0; i < events.size(); i++) {
-
Ref<InputEvent> event = events[i];
- if (event.is_null())
+ if (event.is_null()) {
continue;
+ }
TreeItem *action2 = input_editor->create_item(item);
Ref<InputEventKey> k = event;
if (k.is_valid()) {
-
const String str = (k->get_keycode() == 0) ? keycode_get_string(k->get_physical_keycode_with_modifiers()) + TTR(" (Physical)") : keycode_get_string(k->get_keycode_with_modifiers());
action2->set_text(0, str);
@@ -789,10 +788,10 @@ void ProjectSettingsEditor::_update_actions() {
Ref<InputEventJoypadButton> jb = event;
if (jb.is_valid()) {
-
- String str = _get_device_string(jb->get_device()) + ", " + TTR("Button") + " " + itos(jb->get_button_index());
- if (jb->get_button_index() >= 0 && jb->get_button_index() < JOY_BUTTON_MAX) {
- str += String() + " (" + _button_names[jb->get_button_index()] + ")";
+ String str = _get_device_string(jb->get_device()) + ", " +
+ TTR("Button") + " " + itos(jb->get_button_index());
+ if (jb->get_button_index() >= 0 && jb->get_button_index() < JOY_SDL_BUTTONS) {
+ str += String() + " (" + TTR(_button_descriptions[jb->get_button_index()]) + ")";
}
action2->set_text(0, str);
@@ -804,12 +803,23 @@ void ProjectSettingsEditor::_update_actions() {
if (mb.is_valid()) {
String str = _get_device_string(mb->get_device()) + ", ";
switch (mb->get_button_index()) {
- case BUTTON_LEFT: str += TTR("Left Button"); break;
- case BUTTON_RIGHT: str += TTR("Right Button"); break;
- case BUTTON_MIDDLE: str += TTR("Middle Button"); break;
- case BUTTON_WHEEL_UP: str += TTR("Wheel Up"); break;
- case BUTTON_WHEEL_DOWN: str += TTR("Wheel Down"); break;
- default: str += vformat(TTR("%d Button"), mb->get_button_index());
+ case BUTTON_LEFT:
+ str += TTR("Left Button");
+ break;
+ case BUTTON_RIGHT:
+ str += TTR("Right Button");
+ break;
+ case BUTTON_MIDDLE:
+ str += TTR("Middle Button");
+ break;
+ case BUTTON_WHEEL_UP:
+ str += TTR("Wheel Up");
+ break;
+ case BUTTON_WHEEL_DOWN:
+ str += TTR("Wheel Down");
+ break;
+ default:
+ str += vformat(TTR("%d Button"), mb->get_button_index());
}
action2->set_text(0, str);
@@ -819,11 +829,11 @@ void ProjectSettingsEditor::_update_actions() {
Ref<InputEventJoypadMotion> jm = event;
if (jm.is_valid()) {
-
int ax = jm->get_axis();
int n = 2 * ax + (jm->get_axis_value() < 0 ? 0 : 1);
- String desc = _axis_names[n];
- String str = _get_device_string(jm->get_device()) + ", " + TTR("Axis") + " " + itos(ax) + " " + (jm->get_axis_value() < 0 ? "-" : "+") + desc;
+ String str = _get_device_string(jm->get_device()) + ", " +
+ TTR("Axis") + " " + itos(ax) + " " + (jm->get_axis_value() < 0 ? "-" : "+") +
+ " (" + _axis_descriptions[n] + ")";
action2->set_text(0, str);
action2->set_icon(0, input_editor->get_theme_icon("JoyAxis", "EditorIcons"));
}
@@ -843,7 +853,6 @@ void ProjectSettingsEditor::_update_actions() {
}
void ProjectSettingsEditor::popup_project_settings() {
-
// Restore valid window bounds or pop up at default size.
Rect2 saved_size = EditorSettings::get_singleton()->get_project_metadata("dialog_bounds", "project_settings", Rect2());
if (saved_size != Rect2()) {
@@ -864,22 +873,20 @@ void ProjectSettingsEditor::update_plugins() {
}
void ProjectSettingsEditor::_item_selected(const String &p_path) {
-
const String &selected_path = p_path;
- if (selected_path == String())
+ if (selected_path == String()) {
return;
+ }
category->set_text(globals_editor->get_current_section());
property->set_text(selected_path);
popup_copy_to_feature->set_disabled(false);
}
void ProjectSettingsEditor::_item_adds(String) {
-
_item_add();
}
void ProjectSettingsEditor::_item_add() {
-
// Initialize the property with the default value for the given type.
// The type list starts at 1 (as we exclude Nil), so add 1 to the selected value.
Callable::CallError ce;
@@ -922,7 +929,6 @@ void ProjectSettingsEditor::_item_add() {
}
void ProjectSettingsEditor::_item_del() {
-
String path = globals_editor->get_inspector()->get_selected_path();
if (path == String()) {
EditorNode::get_singleton()->show_warning(TTR("Select a setting item first!"));
@@ -960,21 +966,16 @@ void ProjectSettingsEditor::_item_del() {
}
void ProjectSettingsEditor::_action_check(String p_action) {
-
if (p_action == "") {
-
action_add->set_disabled(true);
} else {
-
if (!_validate_action_name(p_action)) {
-
action_add_error->set_text(TTR("Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or '\"'."));
action_add_error->show();
action_add->set_disabled(true);
return;
}
if (ProjectSettings::get_singleton()->has_setting("input/" + p_action)) {
-
action_add_error->set_text(vformat(TTR("An action with the name '%s' already exists."), p_action));
action_add_error->show();
action_add->set_disabled(true);
@@ -988,14 +989,12 @@ void ProjectSettingsEditor::_action_check(String p_action) {
}
void ProjectSettingsEditor::_action_adds(String) {
-
if (!action_add->is_disabled()) {
_action_add();
}
}
void ProjectSettingsEditor::_action_add() {
-
Dictionary action;
action["events"] = Array();
action["deadzone"] = 0.5f;
@@ -1011,13 +1010,16 @@ void ProjectSettingsEditor::_action_add() {
TreeItem *r = input_editor->get_root();
- if (!r)
+ if (!r) {
return;
+ }
r = r->get_children();
- if (!r)
+ if (!r) {
return;
- while (r->get_next())
+ }
+ while (r->get_next()) {
r = r->get_next();
+ }
r->select(0);
input_editor->ensure_cursor_is_visible();
@@ -1029,20 +1031,17 @@ void ProjectSettingsEditor::_item_checked(const String &p_item, bool p_check) {
}
void ProjectSettingsEditor::_save() {
-
Error err = ProjectSettings::get_singleton()->save();
message->set_text(err != OK ? TTR("Error saving settings.") : TTR("Settings saved OK."));
message->popup_centered(Size2(300, 100) * EDSCALE);
}
void ProjectSettingsEditor::_settings_prop_edited(const String &p_name) {
-
// Method needed to discard the mandatory argument of the property_edited signal
_settings_changed();
}
void ProjectSettingsEditor::_settings_changed() {
-
timer->start();
}
@@ -1051,7 +1050,6 @@ void ProjectSettingsEditor::queue_save() {
}
void ProjectSettingsEditor::_copy_to_platform_about_to_show() {
-
Set<String> presets;
presets.insert("bptc");
@@ -1077,7 +1075,6 @@ void ProjectSettingsEditor::_copy_to_platform_about_to_show() {
}
for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
-
List<String> p;
EditorExport::get_singleton()->get_export_preset(i)->get_platform()->get_preset_features(EditorExport::get_singleton()->get_export_preset(i), &p);
for (List<String>::Element *E = p.front(); E; E = E->next()) {
@@ -1102,10 +1099,10 @@ void ProjectSettingsEditor::_copy_to_platform_about_to_show() {
}
Variant ProjectSettingsEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
TreeItem *selected = input_editor->get_selected();
- if (!selected || selected->get_parent() != input_editor->get_root())
+ if (!selected || selected->get_parent() != input_editor->get_root()) {
return Variant();
+ }
String name = selected->get_text(0);
VBoxContainer *vb = memnew(VBoxContainer);
@@ -1125,28 +1122,30 @@ Variant ProjectSettingsEditor::get_drag_data_fw(const Point2 &p_point, Control *
}
bool ProjectSettingsEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
Dictionary d = p_data;
- if (!d.has("type") || d["type"] != "nodes")
+ if (!d.has("type") || d["type"] != "nodes") {
return false;
+ }
TreeItem *selected = input_editor->get_selected();
TreeItem *item = input_editor->get_item_at_position(p_point);
- if (!selected || !item || item == selected || item->get_parent() == selected)
+ if (!selected || !item || item == selected || item->get_parent() == selected) {
return false;
+ }
return true;
}
void ProjectSettingsEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
-
- if (!can_drop_data_fw(p_point, p_data, p_from))
+ if (!can_drop_data_fw(p_point, p_data, p_from)) {
return;
+ }
TreeItem *selected = input_editor->get_selected();
TreeItem *item = input_editor->get_item_at_position(p_point);
- if (!item)
+ if (!item) {
return;
+ }
TreeItem *target = item->get_parent() == input_editor->get_root() ? item : item->get_parent();
String selected_name = "input/" + selected->get_text(0);
@@ -1160,7 +1159,6 @@ void ProjectSettingsEditor::drop_data_fw(const Point2 &p_point, const Variant &p
undo_redo->create_action(TTR("Moved Input Action Event"));
while (iterator != target) {
-
String iterator_name = "input/" + iterator->get_text(0);
int iterator_order = ProjectSettings::get_singleton()->get_order(iterator_name);
undo_redo->add_do_method(ProjectSettings::get_singleton(), "set_order", iterator_name, order);
@@ -1182,7 +1180,6 @@ void ProjectSettingsEditor::drop_data_fw(const Point2 &p_point, const Variant &p
}
void ProjectSettingsEditor::_copy_to_platform(int p_which) {
-
String path = globals_editor->get_inspector()->get_selected_path();
if (path == String()) {
EditorNode::get_singleton()->show_warning(TTR("Select a setting item first!"));
@@ -1217,18 +1214,16 @@ void ProjectSettingsEditor::_copy_to_platform(int p_which) {
}
void ProjectSettingsEditor::add_translation(const String &p_translation) {
-
_translation_add(p_translation);
}
void ProjectSettingsEditor::_translation_add(const String &p_path) {
-
PackedStringArray translations = ProjectSettings::get_singleton()->get("locale/translations");
for (int i = 0; i < translations.size(); i++) {
-
- if (translations[i] == p_path)
+ if (translations[i] == p_path) {
return; //exists
+ }
}
translations.push_back(p_path);
@@ -1243,12 +1238,10 @@ void ProjectSettingsEditor::_translation_add(const String &p_path) {
}
void ProjectSettingsEditor::_translation_file_open() {
-
translation_file_open->popup_centered_ratio();
}
void ProjectSettingsEditor::_translation_delete(Object *p_item, int p_column, int p_button) {
-
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
ERR_FAIL_COND(!ti);
@@ -1271,12 +1264,10 @@ void ProjectSettingsEditor::_translation_delete(Object *p_item, int p_column, in
}
void ProjectSettingsEditor::_translation_res_file_open() {
-
translation_res_file_open->popup_centered_ratio();
}
void ProjectSettingsEditor::_translation_res_add(const String &p_path) {
-
Variant prev;
Dictionary remaps;
@@ -1285,8 +1276,9 @@ void ProjectSettingsEditor::_translation_res_add(const String &p_path) {
prev = remaps;
}
- if (remaps.has(p_path))
+ if (remaps.has(p_path)) {
return; //pointless already has it
+ }
remaps[p_path] = PackedStringArray();
@@ -1301,11 +1293,10 @@ void ProjectSettingsEditor::_translation_res_add(const String &p_path) {
}
void ProjectSettingsEditor::_translation_res_option_file_open() {
-
translation_res_option_file_open->popup_centered_ratio();
}
-void ProjectSettingsEditor::_translation_res_option_add(const String &p_path) {
+void ProjectSettingsEditor::_translation_res_option_add(const String &p_path) {
ERR_FAIL_COND(!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps"));
Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
@@ -1331,20 +1322,21 @@ void ProjectSettingsEditor::_translation_res_option_add(const String &p_path) {
}
void ProjectSettingsEditor::_translation_res_select() {
-
- if (updating_translations)
+ if (updating_translations) {
return;
+ }
call_deferred("_update_translations");
}
void ProjectSettingsEditor::_translation_res_option_changed() {
-
- if (updating_translations)
+ if (updating_translations) {
return;
+ }
- if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps"))
+ if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
return;
+ }
Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
@@ -1385,12 +1377,13 @@ void ProjectSettingsEditor::_translation_res_option_changed() {
}
void ProjectSettingsEditor::_translation_res_delete(Object *p_item, int p_column, int p_button) {
-
- if (updating_translations)
+ if (updating_translations) {
return;
+ }
- if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps"))
+ if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
return;
+ }
Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
@@ -1412,12 +1405,13 @@ void ProjectSettingsEditor::_translation_res_delete(Object *p_item, int p_column
}
void ProjectSettingsEditor::_translation_res_option_delete(Object *p_item, int p_column, int p_button) {
-
- if (updating_translations)
+ if (updating_translations) {
return;
+ }
- if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps"))
+ if (!ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
return;
+ }
Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
@@ -1446,7 +1440,6 @@ void ProjectSettingsEditor::_translation_res_option_delete(Object *p_item, int p
}
void ProjectSettingsEditor::_translation_filter_option_changed() {
-
int sel_id = translation_locale_filter_mode->get_selected_id();
TreeItem *t = translation_filter->get_edited();
String locale = t->get_tooltip(0);
@@ -1495,7 +1488,6 @@ void ProjectSettingsEditor::_translation_filter_option_changed() {
}
void ProjectSettingsEditor::_translation_filter_mode_changed(int p_mode) {
-
int sel_id = translation_locale_filter_mode->get_selected_id();
Variant prev;
@@ -1528,11 +1520,11 @@ void ProjectSettingsEditor::_translation_filter_mode_changed(int p_mode) {
}
void ProjectSettingsEditor::_update_translations() {
-
//update translations
- if (updating_translations)
+ if (updating_translations) {
return;
+ }
updating_translations = true;
@@ -1540,10 +1532,8 @@ void ProjectSettingsEditor::_update_translations() {
TreeItem *root = translation_list->create_item(nullptr);
translation_list->set_hide_root(true);
if (ProjectSettings::get_singleton()->has_setting("locale/translations")) {
-
PackedStringArray translations = ProjectSettings::get_singleton()->get("locale/translations");
for (int i = 0; i < translations.size(); i++) {
-
TreeItem *t = translation_list->create_item(root);
t->set_editable(0, false);
t->set_text(0, translations[i].replace_first("res://", ""));
@@ -1561,17 +1551,14 @@ void ProjectSettingsEditor::_update_translations() {
bool is_arr_empty = true;
if (ProjectSettings::get_singleton()->has_setting("locale/locale_filter")) {
-
l_filter_all = ProjectSettings::get_singleton()->get("locale/locale_filter");
if (l_filter_all.size() == 2) {
-
translation_locale_filter_mode->select(l_filter_all[0]);
is_arr_empty = false;
}
}
if (is_arr_empty) {
-
l_filter_all.append(0);
l_filter_all.append(Array());
translation_locale_filter_mode->select(0);
@@ -1586,7 +1573,6 @@ void ProjectSettingsEditor::_update_translations() {
bool should_recreate_locales_list = is_short_list_when_show_all_selected || is_full_list_when_show_only_selected;
if (!translation_locales_list_created || should_recreate_locales_list) {
-
translation_locales_list_created = true;
translation_filter->clear();
root = translation_filter->create_item(nullptr);
@@ -1596,7 +1582,9 @@ void ProjectSettingsEditor::_update_translations() {
String n = names[i];
String l = langs[i];
bool is_checked = l_filter.has(l);
- if (filter_mode == SHOW_ONLY_SELECTED_LOCALES && !is_checked) continue;
+ if (filter_mode == SHOW_ONLY_SELECTED_LOCALES && !is_checked) {
+ continue;
+ }
TreeItem *t = translation_filter->create_item(root);
t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
@@ -1635,27 +1623,26 @@ void ProjectSettingsEditor::_update_translations() {
String langnames = "";
int l_idx = 0;
for (int i = 0; i < names.size(); i++) {
-
if (filter_mode == SHOW_ONLY_SELECTED_LOCALES && fl_idx_count != 0) {
if (l_filter.size() > 0) {
-
if (l_filter.find(langs[i]) != -1) {
- if (langnames.length() > 0)
+ if (langnames.length() > 0) {
langnames += ",";
+ }
langnames += names[i];
translation_locales_idxs_remap.write[l_idx] = i;
l_idx++;
}
}
} else {
- if (i > 0)
+ if (i > 0) {
langnames += ",";
+ }
langnames += names[i];
}
}
if (ProjectSettings::get_singleton()->has_setting("locale/translation_remaps")) {
-
Dictionary remaps = ProjectSettings::get_singleton()->get("locale/translation_remaps");
List<Variant> rk;
remaps.get_key_list(&rk);
@@ -1666,7 +1653,6 @@ void ProjectSettingsEditor::_update_translations() {
keys.sort();
for (int i = 0; i < keys.size(); i++) {
-
TreeItem *t = translation_remap->create_item(root);
t->set_editable(0, false);
t->set_text(0, keys[i].replace_first("res://", ""));
@@ -1679,7 +1665,6 @@ void ProjectSettingsEditor::_update_translations() {
PackedStringArray selected = remaps[keys[i]];
for (int j = 0; j < selected.size(); j++) {
-
String s2 = selected[j];
int qp = s2.find_last(":");
String path = s2.substr(0, qp);
@@ -1696,15 +1681,14 @@ void ProjectSettingsEditor::_update_translations() {
t2->set_editable(1, true);
t2->set_metadata(1, path);
int idx = langs.find(locale);
- if (idx < 0)
+ if (idx < 0) {
idx = 0;
+ }
int f_idx = translation_locales_idxs_remap.find(idx);
if (f_idx != -1 && fl_idx_count > 0 && filter_mode == SHOW_ONLY_SELECTED_LOCALES) {
-
t2->set_range(1, f_idx);
} else {
-
t2->set_range(1, idx);
}
}
@@ -1716,17 +1700,14 @@ void ProjectSettingsEditor::_update_translations() {
}
void ProjectSettingsEditor::_toggle_search_bar(bool p_pressed) {
-
globals_editor->get_inspector()->set_use_filter(p_pressed);
if (p_pressed) {
-
search_bar->show();
add_prop_bar->hide();
search_box->grab_focus();
search_box->select_all();
} else {
-
search_box->clear();
search_bar->hide();
add_prop_bar->show();
@@ -1734,12 +1715,10 @@ void ProjectSettingsEditor::_toggle_search_bar(bool p_pressed) {
}
void ProjectSettingsEditor::set_plugins_page() {
-
tab_container->set_current_tab(plugin_settings->get_index());
}
TabContainer *ProjectSettingsEditor::get_tabs() {
-
return tab_container;
}
@@ -1757,7 +1736,6 @@ void ProjectSettingsEditor::_editor_restart_close() {
}
void ProjectSettingsEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_unhandled_input"), &ProjectSettingsEditor::_unhandled_input);
ClassDB::bind_method(D_METHOD("_item_checked"), &ProjectSettingsEditor::_item_checked);
ClassDB::bind_method(D_METHOD("_save"), &ProjectSettingsEditor::_save);
@@ -1773,7 +1751,6 @@ void ProjectSettingsEditor::_bind_methods() {
}
ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
-
singleton = this;
set_title(TTR("Project Settings (project.godot)"));
@@ -1996,8 +1973,9 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
vbc_left->add_child(l);
device_id = memnew(OptionButton);
- for (int i = -1; i < 8; i++)
+ for (int i = -1; i < 8; i++) {
device_id->add_item(_get_device_string(i));
+ }
_set_current_device(0);
vbc_left->add_child(device_id);
@@ -2027,7 +2005,6 @@ ProjectSettingsEditor::ProjectSettingsEditor(EditorData *p_data) {
translation_locales_list_created = false;
{
-
VBoxContainer *tvb = memnew(VBoxContainer);
translations->add_child(tvb);
tvb->set_name(TTR("Translations"));
diff --git a/editor/project_settings_editor.h b/editor/project_settings_editor.h
index 5475bb5508..445ef58351 100644
--- a/editor/project_settings_editor.h
+++ b/editor/project_settings_editor.h
@@ -41,7 +41,6 @@
#include "scene/gui/tab_container.h"
class ProjectSettingsEditor : public AcceptDialog {
-
GDCLASS(ProjectSettingsEditor, AcceptDialog);
enum InputType {
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 978c95b9c8..c6efcc944b 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -31,7 +31,7 @@
#include "property_editor.h"
#include "core/class_db.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/image_loader.h"
#include "core/io/marshalls.h"
#include "core/io/resource_loader.h"
@@ -59,7 +59,6 @@
#include "scene/scene_string_names.h"
void EditorResourceConversionPlugin::_bind_methods() {
-
MethodInfo mi;
mi.name = "_convert";
mi.return_val.type = Variant::OBJECT;
@@ -78,48 +77,42 @@ void EditorResourceConversionPlugin::_bind_methods() {
}
String EditorResourceConversionPlugin::converts_to() const {
-
- if (get_script_instance())
+ if (get_script_instance()) {
return get_script_instance()->call("_converts_to");
+ }
return "";
}
bool EditorResourceConversionPlugin::handles(const Ref<Resource> &p_resource) const {
-
- if (get_script_instance())
+ if (get_script_instance()) {
return get_script_instance()->call("_handles", p_resource);
+ }
return false;
}
Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) const {
-
- if (get_script_instance())
+ if (get_script_instance()) {
return get_script_instance()->call("_convert", p_resource);
+ }
return Ref<Resource>();
}
void CustomPropertyEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_WM_CLOSE_REQUEST) {
hide();
}
}
void CustomPropertyEditor::_menu_option(int p_which) {
-
switch (type) {
-
case Variant::INT: {
-
if (hint == PROPERTY_HINT_FLAGS) {
-
int val = v;
if (val & (1 << p_which)) {
-
val &= ~(1 << p_which);
} else {
val |= (1 << p_which);
@@ -128,30 +121,24 @@ void CustomPropertyEditor::_menu_option(int p_which) {
v = val;
emit_signal("variant_changed");
} else if (hint == PROPERTY_HINT_ENUM) {
-
v = menu->get_item_metadata(p_which);
emit_signal("variant_changed");
}
} break;
case Variant::STRING: {
-
if (hint == PROPERTY_HINT_ENUM) {
-
v = hint_text.get_slice(",", p_which);
emit_signal("variant_changed");
}
} break;
case Variant::OBJECT: {
-
switch (p_which) {
case OBJ_MENU_LOAD: {
-
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
String type = (hint == PROPERTY_HINT_RESOURCE_TYPE) ? hint_text : String();
List<String> extensions;
for (int i = 0; i < type.get_slice_count(","); i++) {
-
ResourceLoader::get_recognized_extensions_for_type(type.get_slice(",", i), &extensions);
}
@@ -162,7 +149,6 @@ void CustomPropertyEditor::_menu_option(int p_which) {
file->clear_filters();
for (Set<String>::Element *E = valid_extensions.front(); E; E = E->next()) {
-
file->add_filter("*." + E->get() + " ; " + E->get().to_upper());
}
@@ -170,38 +156,33 @@ void CustomPropertyEditor::_menu_option(int p_which) {
} break;
case OBJ_MENU_EDIT: {
-
REF r = v;
if (!r.is_null()) {
-
emit_signal("resource_edit_request");
hide();
}
} break;
case OBJ_MENU_CLEAR: {
-
v = Variant();
emit_signal("variant_changed");
hide();
} break;
case OBJ_MENU_MAKE_UNIQUE: {
-
Ref<Resource> res_orig = v;
- if (res_orig.is_null())
+ if (res_orig.is_null()) {
return;
+ }
List<PropertyInfo> property_list;
res_orig->get_property_list(&property_list);
List<Pair<String, Variant>> propvalues;
for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
-
Pair<String, Variant> p;
PropertyInfo &pi = E->get();
if (pi.usage & PROPERTY_USAGE_STORAGE) {
-
p.first = pi.name;
p.second = res_orig->get(pi.name);
}
@@ -218,7 +199,6 @@ void CustomPropertyEditor::_menu_option(int p_which) {
ERR_FAIL_COND(res.is_null());
for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) {
-
Pair<String, Variant> &p = E->get();
res->set(p.first, p.second);
}
@@ -229,26 +209,24 @@ void CustomPropertyEditor::_menu_option(int p_which) {
} break;
case OBJ_MENU_COPY: {
-
EditorSettings::get_singleton()->set_resource_clipboard(v);
} break;
case OBJ_MENU_PASTE: {
-
v = EditorSettings::get_singleton()->get_resource_clipboard();
emit_signal("variant_changed");
} break;
case OBJ_MENU_NEW_SCRIPT: {
-
- if (Object::cast_to<Node>(owner))
+ if (Object::cast_to<Node>(owner)) {
EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(owner), false);
+ }
} break;
case OBJ_MENU_EXTEND_SCRIPT: {
-
- if (Object::cast_to<Node>(owner))
+ if (Object::cast_to<Node>(owner)) {
EditorNode::get_singleton()->get_scene_tree_dock()->open_script_dialog(Object::cast_to<Node>(owner), true);
+ }
} break;
case OBJ_MENU_SHOW_IN_FILE_SYSTEM: {
@@ -260,9 +238,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
tab_container->set_current_tab(file_system_dock->get_index());
} break;
default: {
-
if (p_which >= CONVERT_BASE_ID) {
-
int to_type = p_which - CONVERT_BASE_ID;
Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(RES(v));
@@ -280,7 +256,6 @@ void CustomPropertyEditor::_menu_option(int p_which) {
String intype = inheritors_array[p_which - TYPE_BASE_ID];
if (intype == "ViewportTexture") {
-
scene_tree->set_title(TTR("Pick a Viewport"));
scene_tree->popup_centered_ratio();
picking_viewport = true;
@@ -322,17 +297,14 @@ void CustomPropertyEditor::hide_menu() {
}
Variant CustomPropertyEditor::get_variant() const {
-
return v;
}
String CustomPropertyEditor::get_name() const {
-
return name;
}
bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::Type p_type, const Variant &p_variant, int p_hint, String p_hint_text) {
-
owner = p_owner;
updating = true;
name = p_name;
@@ -341,8 +313,9 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
hint = p_hint;
hint_text = p_hint_text;
type_button->hide();
- if (color_picker)
+ if (color_picker) {
color_picker->hide();
+ }
texture_preview->hide();
inheritors_array.clear();
text_edit->hide();
@@ -353,28 +326,26 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
menu->set_size(Size2(1, 1) * EDSCALE);
for (int i = 0; i < MAX_VALUE_EDITORS; i++) {
-
value_editor[i]->hide();
value_label[i]->hide();
- if (i < 4)
+ if (i < 4) {
scroll[i]->hide();
+ }
}
for (int i = 0; i < MAX_ACTION_BUTTONS; i++) {
-
action_buttons[i]->hide();
}
checks20gc->hide();
- for (int i = 0; i < 20; i++)
+ for (int i = 0; i < 20; i++) {
checks20[i]->hide();
+ }
type = (p_variant.get_type() != Variant::NIL && p_variant.get_type() != Variant::_RID && p_type != Variant::OBJECT) ? p_variant.get_type() : p_type;
switch (type) {
-
case Variant::BOOL: {
-
checks20gc->show();
CheckBox *c = checks20[0];
@@ -389,26 +360,24 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} break;
case Variant::INT:
case Variant::FLOAT: {
-
if (hint == PROPERTY_HINT_RANGE) {
-
int c = hint_text.get_slice_count(",");
float min = 0, max = 100, step = type == Variant::FLOAT ? .01 : 1;
if (c >= 1) {
-
- if (!hint_text.get_slice(",", 0).empty())
+ if (!hint_text.get_slice(",", 0).empty()) {
min = hint_text.get_slice(",", 0).to_double();
+ }
}
if (c >= 2) {
-
- if (!hint_text.get_slice(",", 1).empty())
+ if (!hint_text.get_slice(",", 1).empty()) {
max = hint_text.get_slice(",", 1).to_double();
+ }
}
if (c >= 3) {
-
- if (!hint_text.get_slice(",", 2).empty())
+ if (!hint_text.get_slice(",", 2).empty()) {
step = hint_text.get_slice(",", 2).to_double();
+ }
}
if (c >= 4 && hint_text.get_slice(",", 3) == "slider") {
@@ -428,13 +397,13 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
}
} else if (hint == PROPERTY_HINT_ENUM) {
-
Vector<String> options = hint_text.split(",");
int current_val = 0;
for (int i = 0; i < options.size(); i++) {
Vector<String> text_split = options[i].split(":");
- if (text_split.size() != 1)
+ if (text_split.size() != 1) {
current_val = text_split[1].to_int();
+ }
menu->add_item(text_split[0]);
menu->set_item_metadata(i, current_val);
current_val += 1;
@@ -446,7 +415,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
return false;
} else if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || hint == PROPERTY_HINT_LAYERS_2D_RENDER || hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || hint == PROPERTY_HINT_LAYERS_3D_RENDER) {
-
String basename;
switch (hint) {
case PROPERTY_HINT_LAYERS_2D_RENDER:
@@ -466,11 +434,9 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
checks20gc->show();
uint32_t flgs = v;
for (int i = 0; i < 2; i++) {
-
Point2 ofs(4, 4);
ofs.y += 22 * i;
for (int j = 0; j < 10; j++) {
-
int idx = i * 10 + j;
CheckBox *c = checks20[idx];
c->set_text(ProjectSettings::get_singleton()->get(basename + "/layer_" + itos(idx + 1)));
@@ -487,7 +453,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
set_size(Vector2(4, 4) * EDSCALE + checks20gc->get_position() + checks20gc->get_size());
} else if (hint == PROPERTY_HINT_EXP_EASING) {
-
easing_draw->set_anchor_and_margin(MARGIN_LEFT, Control::ANCHOR_BEGIN, 5 * EDSCALE);
easing_draw->set_anchor_and_margin(MARGIN_RIGHT, Control::ANCHOR_END, -5 * EDSCALE);
easing_draw->set_anchor_and_margin(MARGIN_TOP, Control::ANCHOR_BEGIN, 5 * EDSCALE);
@@ -514,12 +479,14 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
Vector<String> flags = hint_text.split(",");
for (int i = 0; i < flags.size(); i++) {
String flag = flags[i];
- if (flag == "")
+ if (flag == "") {
continue;
+ }
menu->add_check_item(flag, i);
int f = v;
- if (f & (1 << i))
+ if (f & (1 << i)) {
menu->set_item_checked(menu->get_item_index(i), true);
+ }
}
menu->set_position(get_position());
menu->popup();
@@ -536,22 +503,18 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} break;
case Variant::STRING: {
-
if (hint == PROPERTY_HINT_FILE || hint == PROPERTY_HINT_GLOBAL_FILE) {
-
List<String> names;
names.push_back(TTR("File..."));
names.push_back(TTR("Clear"));
config_action_buttons(names);
} else if (hint == PROPERTY_HINT_DIR || hint == PROPERTY_HINT_GLOBAL_DIR) {
-
List<String> names;
names.push_back(TTR("Dir..."));
names.push_back(TTR("Clear"));
config_action_buttons(names);
} else if (hint == PROPERTY_HINT_ENUM) {
-
Vector<String> options = hint_text.split(",");
for (int i = 0; i < options.size(); i++) {
menu->add_item(options[i], i);
@@ -563,7 +526,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
return false;
} else if (hint == PROPERTY_HINT_MULTILINE_TEXT) {
-
text_edit->show();
text_edit->set_text(v);
text_edit->deselect();
@@ -581,7 +543,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
action_buttons[0]->show();
} else if (hint == PROPERTY_HINT_TYPE_STRING) {
-
if (!create_dialog) {
create_dialog = memnew(CreateDialog);
create_dialog->connect("create", callable_mp(this, &CustomPropertyEditor::_create_dialog_callback));
@@ -616,8 +577,9 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
type = Variant::Type(i);
}
}
- if (type != Variant::NIL)
+ if (type != Variant::NIL) {
property_select->select_method_from_basic_type(type, v);
+ }
updating = false;
return false;
@@ -630,12 +592,12 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
return false;
} else if (hint == PROPERTY_HINT_METHOD_OF_INSTANCE) {
-
MAKE_PROPSELECT
Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
- if (instance)
+ if (instance) {
property_select->select_method_from_instance(instance, v);
+ }
updating = false;
return false;
@@ -651,26 +613,26 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
return false;
} else if (hint == PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE) {
-
MAKE_PROPSELECT
Variant::Type type = Variant::NIL;
String tname = hint_text;
- if (tname.find(".") != -1)
+ if (tname.find(".") != -1) {
tname = tname.get_slice(".", 0);
+ }
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
if (tname == Variant::get_type_name(Variant::Type(i))) {
type = Variant::Type(Variant::Type(i));
}
}
- if (type != Variant::NIL)
+ if (type != Variant::NIL) {
property_select->select_property_from_basic_type(type, v);
+ }
updating = false;
return false;
} else if (hint == PROPERTY_HINT_PROPERTY_OF_BASE_TYPE) {
-
MAKE_PROPSELECT
property_select->select_property_from_base_type(hint_text, v);
@@ -679,12 +641,12 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
return false;
} else if (hint == PROPERTY_HINT_PROPERTY_OF_INSTANCE) {
-
MAKE_PROPSELECT
Object *instance = ObjectDB::get_instance(ObjectID(hint_text.to_int64()));
- if (instance)
+ if (instance) {
property_select->select_property_from_instance(instance, v);
+ }
updating = false;
return false;
@@ -709,7 +671,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} break;
case Variant::VECTOR2: {
-
field_names.push_back("x");
field_names.push_back("y");
config_value_editors(2, 2, 10, field_names);
@@ -718,7 +679,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
value_editor[1]->set_text(String::num(vec.y));
} break;
case Variant::RECT2: {
-
field_names.push_back("x");
field_names.push_back("y");
field_names.push_back("w");
@@ -731,7 +691,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
value_editor[3]->set_text(String::num(r.size.y));
} break;
case Variant::VECTOR3: {
-
field_names.push_back("x");
field_names.push_back("y");
field_names.push_back("z");
@@ -742,7 +701,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
value_editor[2]->set_text(String::num(vec.z));
} break;
case Variant::PLANE: {
-
field_names.push_back("x");
field_names.push_back("y");
field_names.push_back("z");
@@ -756,7 +714,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} break;
case Variant::QUAT: {
-
field_names.push_back("x");
field_names.push_back("y");
field_names.push_back("z");
@@ -770,7 +727,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} break;
case Variant::AABB: {
-
field_names.push_back("px");
field_names.push_back("py");
field_names.push_back("pz");
@@ -789,7 +745,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} break;
case Variant::TRANSFORM2D: {
-
field_names.push_back("xx");
field_names.push_back("xy");
field_names.push_back("yx");
@@ -800,13 +755,11 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
Transform2D basis = v;
for (int i = 0; i < 6; i++) {
-
value_editor[i]->set_text(String::num(basis.elements[i / 2][i % 2]));
}
} break;
case Variant::BASIS: {
-
field_names.push_back("xx");
field_names.push_back("xy");
field_names.push_back("xz");
@@ -820,13 +773,11 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
Basis basis = v;
for (int i = 0; i < 9; i++) {
-
value_editor[i]->set_text(String::num(basis.elements[i / 3][i % 3]));
}
} break;
case Variant::TRANSFORM: {
-
field_names.push_back("xx");
field_names.push_back("xy");
field_names.push_back("xz");
@@ -843,7 +794,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
Transform tr = v;
for (int i = 0; i < 9; i++) {
-
value_editor[(i / 3) * 4 + i % 3]->set_text(String::num(tr.basis.elements[i / 3][i % 3]));
}
@@ -853,7 +803,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} break;
case Variant::COLOR: {
-
if (!color_picker) {
//late init for performance
color_picker = memnew(ColorPicker);
@@ -864,10 +813,11 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
// get default color picker mode from editor settings
int default_color_mode = EDITOR_GET("interface/inspector/default_color_picker_mode");
- if (default_color_mode == 1)
+ if (default_color_mode == 1) {
color_picker->set_hsv_mode(true);
- else if (default_color_mode == 2)
+ } else if (default_color_mode == 2) {
color_picker->set_raw_mode(true);
+ }
}
color_picker->show();
@@ -878,21 +828,21 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} break;
case Variant::NODE_PATH: {
-
List<String> names;
names.push_back(TTR("Assign"));
names.push_back(TTR("Clear"));
- if (owner && owner->is_class("Node") && (v.get_type() == Variant::NODE_PATH) && Object::cast_to<Node>(owner)->has_node(v))
+ if (owner && owner->is_class("Node") && (v.get_type() == Variant::NODE_PATH) && Object::cast_to<Node>(owner)->has_node(v)) {
names.push_back(TTR("Select Node"));
+ }
config_action_buttons(names);
} break;
case Variant::OBJECT: {
-
- if (hint != PROPERTY_HINT_RESOURCE_TYPE)
+ if (hint != PROPERTY_HINT_RESOURCE_TYPE) {
break;
+ }
if (p_name == "script" && hint_text == "Script" && Object::cast_to<Node>(owner)) {
menu->add_item(TTR("New Script"), OBJ_MENU_NEW_SCRIPT);
@@ -907,7 +857,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
}
for (int i = 0; i < hint_text.get_slice_count(","); i++) {
-
String base = hint_text.get_slice(",", i);
Set<String> valid_inheritors;
@@ -934,15 +883,17 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
for (int k = 0; k < custom_resources.size(); k++) {
if (custom_resources[k].name == t) {
is_custom_resource = true;
- if (custom_resources[k].icon.is_valid())
+ if (custom_resources[k].icon.is_valid()) {
icon = custom_resources[k].icon;
+ }
break;
}
}
}
- if (!is_custom_resource && !ClassDB::can_instance(t))
+ if (!is_custom_resource && !ClassDB::can_instance(t)) {
continue;
+ }
inheritors_array.push_back(t);
@@ -954,14 +905,14 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
}
}
- if (menu->get_item_count())
+ if (menu->get_item_count()) {
menu->add_separator();
+ }
}
menu->add_item(TTR("Load"), OBJ_MENU_LOAD);
if (!RES(v).is_null()) {
-
menu->add_item(TTR("Edit"), OBJ_MENU_EDIT);
menu->add_item(TTR("Clear"), OBJ_MENU_CLEAR);
menu->add_item(TTR("Make Unique"), OBJ_MENU_MAKE_UNIQUE);
@@ -976,32 +927,31 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
RES cb = EditorSettings::get_singleton()->get_resource_clipboard();
bool paste_valid = false;
if (cb.is_valid()) {
- if (hint_text == "")
+ if (hint_text == "") {
paste_valid = true;
- else
- for (int i = 0; i < hint_text.get_slice_count(","); i++)
+ } else {
+ for (int i = 0; i < hint_text.get_slice_count(","); i++) {
if (ClassDB::is_parent_class(cb->get_class(), hint_text.get_slice(",", i))) {
paste_valid = true;
break;
}
+ }
+ }
}
if (!RES(v).is_null() || paste_valid) {
menu->add_separator();
if (!RES(v).is_null()) {
-
menu->add_item(TTR("Copy"), OBJ_MENU_COPY);
}
if (paste_valid) {
-
menu->add_item(TTR("Paste"), OBJ_MENU_PASTE);
}
}
if (!RES(v).is_null()) {
-
Vector<Ref<EditorResourceConversionPlugin>> conversions = EditorNode::get_singleton()->find_resource_conversion_plugin(RES(v));
if (conversions.size()) {
menu->add_separator();
@@ -1017,34 +967,24 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
hide();
updating = false;
return false;
-
} break;
case Variant::DICTIONARY: {
-
} break;
case Variant::PACKED_BYTE_ARRAY: {
-
} break;
case Variant::PACKED_INT32_ARRAY: {
-
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
-
} break;
case Variant::PACKED_INT64_ARRAY: {
-
} break;
case Variant::PACKED_FLOAT64_ARRAY: {
-
} break;
case Variant::PACKED_STRING_ARRAY: {
-
} break;
case Variant::PACKED_VECTOR3_ARRAY: {
-
} break;
case Variant::PACKED_COLOR_ARRAY: {
-
} break;
default: {
}
@@ -1055,20 +995,15 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
}
void CustomPropertyEditor::_file_selected(String p_file) {
-
switch (type) {
-
case Variant::STRING: {
-
if (hint == PROPERTY_HINT_FILE || hint == PROPERTY_HINT_DIR) {
-
v = ProjectSettings::get_singleton()->localize_path(p_file);
emit_signal("variant_changed");
hide();
}
if (hint == PROPERTY_HINT_GLOBAL_FILE || hint == PROPERTY_HINT_GLOBAL_DIR) {
-
v = p_file;
emit_signal("variant_changed");
hide();
@@ -1076,7 +1011,6 @@ void CustomPropertyEditor::_file_selected(String p_file) {
} break;
case Variant::OBJECT: {
-
String type = (hint == PROPERTY_HINT_RESOURCE_TYPE) ? hint_text : String();
RES res = ResourceLoader::load(p_file, type);
@@ -1095,29 +1029,22 @@ void CustomPropertyEditor::_file_selected(String p_file) {
}
void CustomPropertyEditor::_type_create_selected(int p_idx) {
-
if (type == Variant::INT || type == Variant::FLOAT) {
-
float newval = 0;
switch (p_idx) {
-
case EASING_LINEAR: {
-
newval = 1;
} break;
case EASING_EASE_IN: {
-
newval = 2.0;
} break;
case EASING_EASE_OUT: {
newval = 0.5;
} break;
case EASING_ZERO: {
-
newval = 0;
} break;
case EASING_IN_OUT: {
-
newval = -0.5;
} break;
case EASING_OUT_IN: {
@@ -1130,7 +1057,6 @@ void CustomPropertyEditor::_type_create_selected(int p_idx) {
easing_draw->update();
} else if (type == Variant::OBJECT) {
-
ERR_FAIL_INDEX(p_idx, inheritors_array.size());
String intype = inheritors_array[p_idx];
@@ -1157,15 +1083,12 @@ void CustomPropertyEditor::_type_create_selected(int p_idx) {
}
void CustomPropertyEditor::_color_changed(const Color &p_color) {
-
v = p_color;
emit_signal("variant_changed");
}
void CustomPropertyEditor::_node_path_selected(NodePath p_path) {
-
if (picking_viewport) {
-
Node *to_node = get_node(p_path);
if (!Object::cast_to<Viewport>(to_node)) {
EditorNode::get_singleton()->show_warning(TTR("Selected node is not a Viewport!"));
@@ -1182,10 +1105,8 @@ void CustomPropertyEditor::_node_path_selected(NodePath p_path) {
}
if (hint == PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && hint_text != String()) {
-
Node *node = get_node(hint_text);
if (node) {
-
Node *tonode = node->get_node(p_path);
if (tonode) {
p_path = node->get_path_to(tonode);
@@ -1193,15 +1114,15 @@ void CustomPropertyEditor::_node_path_selected(NodePath p_path) {
}
} else if (owner) {
-
Node *node = nullptr;
- if (owner->is_class("Node"))
+ if (owner->is_class("Node")) {
node = Object::cast_to<Node>(owner);
- else if (owner->is_class("ArrayPropertyEdit"))
+ } else if (owner->is_class("ArrayPropertyEdit")) {
node = Object::cast_to<ArrayPropertyEdit>(owner)->get_node();
- else if (owner->is_class("DictionaryPropertyEdit"))
+ } else if (owner->is_class("DictionaryPropertyEdit")) {
node = Object::cast_to<DictionaryPropertyEdit>(owner)->get_node();
+ }
if (!node) {
v = p_path;
emit_signal("variant_changed");
@@ -1221,9 +1142,9 @@ void CustomPropertyEditor::_node_path_selected(NodePath p_path) {
}
void CustomPropertyEditor::_action_pressed(int p_which) {
-
- if (updating)
+ if (updating) {
return;
+ }
switch (type) {
case Variant::BOOL: {
@@ -1231,14 +1152,13 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
emit_signal("variant_changed");
} break;
case Variant::INT: {
-
if (hint == PROPERTY_HINT_LAYERS_2D_PHYSICS || hint == PROPERTY_HINT_LAYERS_2D_RENDER || hint == PROPERTY_HINT_LAYERS_3D_PHYSICS || hint == PROPERTY_HINT_LAYERS_3D_RENDER) {
-
uint32_t f = v;
- if (checks20[p_which]->is_pressed())
+ if (checks20[p_which]->is_pressed()) {
f |= (1 << p_which);
- else
+ } else {
f &= ~(1 << p_which);
+ }
v = f;
emit_signal("variant_changed");
@@ -1246,18 +1166,16 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
} break;
case Variant::STRING: {
-
if (hint == PROPERTY_HINT_MULTILINE_TEXT) {
-
hide();
} else if (hint == PROPERTY_HINT_FILE || hint == PROPERTY_HINT_GLOBAL_FILE) {
if (p_which == 0) {
-
- if (hint == PROPERTY_HINT_FILE)
+ if (hint == PROPERTY_HINT_FILE) {
file->set_access(EditorFileDialog::ACCESS_RESOURCES);
- else
+ } else {
file->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+ }
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
file->clear_filters();
@@ -1267,37 +1185,34 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
if (hint_text != "") {
Vector<String> extensions = hint_text.split(",");
for (int i = 0; i < extensions.size(); i++) {
-
String filter = extensions[i];
- if (filter.begins_with("."))
+ if (filter.begins_with(".")) {
filter = "*" + extensions[i];
- else if (!filter.begins_with("*"))
+ } else if (!filter.begins_with("*")) {
filter = "*." + extensions[i];
+ }
file->add_filter(filter + " ; " + extensions[i].to_upper());
}
}
file->popup_centered_ratio();
} else {
-
v = "";
emit_signal("variant_changed");
hide();
}
} else if (hint == PROPERTY_HINT_DIR || hint == PROPERTY_HINT_GLOBAL_DIR) {
-
if (p_which == 0) {
-
- if (hint == PROPERTY_HINT_DIR)
+ if (hint == PROPERTY_HINT_DIR) {
file->set_access(EditorFileDialog::ACCESS_RESOURCES);
- else
+ } else {
file->set_access(EditorFileDialog::ACCESS_FILESYSTEM);
+ }
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_DIR);
file->clear_filters();
file->popup_centered_ratio();
} else {
-
v = "";
emit_signal("variant_changed");
hide();
@@ -1306,22 +1221,17 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
} break;
case Variant::NODE_PATH: {
-
if (p_which == 0) {
-
picking_viewport = false;
scene_tree->set_title(TTR("Pick a Node"));
scene_tree->popup_centered_ratio();
} else if (p_which == 1) {
-
v = NodePath();
emit_signal("variant_changed");
hide();
} else if (p_which == 2) {
-
if (owner->is_class("Node") && (v.get_type() == Variant::NODE_PATH) && Object::cast_to<Node>(owner)->has_node(v)) {
-
Node *target_node = Object::cast_to<Node>(owner)->get_node(v);
EditorNode::get_singleton()->get_editor_selection()->clear();
EditorNode::get_singleton()->get_scene_tree_dock()->set_selected(target_node);
@@ -1332,15 +1242,12 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
} break;
case Variant::OBJECT: {
-
if (p_which == 0) {
-
ERR_FAIL_COND(inheritors_array.empty());
String intype = inheritors_array[0];
if (hint == PROPERTY_HINT_RESOURCE_TYPE) {
-
Object *obj = ClassDB::instance(intype);
if (!obj) {
@@ -1360,7 +1267,6 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
hide();
}
} else if (p_which == 1) {
-
file->set_access(EditorFileDialog::ACCESS_RESOURCES);
file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
List<String> extensions;
@@ -1369,43 +1275,37 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
ResourceLoader::get_recognized_extensions_for_type(type, &extensions);
file->clear_filters();
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
-
file->add_filter("*." + E->get() + " ; " + E->get().to_upper());
}
file->popup_centered_ratio();
} else if (p_which == 2) {
-
RES r = v;
if (!r.is_null()) {
-
emit_signal("resource_edit_request");
hide();
}
} else if (p_which == 3) {
-
v = Variant();
emit_signal("variant_changed");
hide();
} else if (p_which == 4) {
-
Ref<Resource> res_orig = v;
- if (res_orig.is_null())
+ if (res_orig.is_null()) {
return;
+ }
List<PropertyInfo> property_list;
res_orig->get_property_list(&property_list);
List<Pair<String, Variant>> propvalues;
for (List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
-
Pair<String, Variant> p;
PropertyInfo &pi = E->get();
if (pi.usage & PROPERTY_USAGE_STORAGE) {
-
p.first = pi.name;
p.second = res_orig->get(pi.name);
}
@@ -1418,7 +1318,6 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
ERR_FAIL_COND(res.is_null());
for (List<Pair<String, Variant>>::Element *E = propvalues.front(); E; E = E->next()) {
-
Pair<String, Variant> &p = E->get();
res->set(p.first, p.second);
}
@@ -1436,23 +1335,24 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
}
void CustomPropertyEditor::_drag_easing(const Ref<InputEvent> &p_ev) {
-
Ref<InputEventMouseMotion> mm = p_ev;
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
-
float rel = mm->get_relative().x;
- if (rel == 0)
+ if (rel == 0) {
return;
+ }
bool flip = hint_text == "attenuation";
- if (flip)
+ if (flip) {
rel = -rel;
+ }
float val = v;
- if (val == 0)
+ if (val == 0) {
return;
+ }
bool sg = val < 0;
val = Math::absf(val);
@@ -1461,8 +1361,9 @@ void CustomPropertyEditor::_drag_easing(const Ref<InputEvent> &p_ev) {
val += rel * 0.05;
val = Math::pow(2.0f, val);
- if (sg)
+ if (sg) {
val = -val;
+ }
v = val;
easing_draw->update();
@@ -1471,7 +1372,6 @@ void CustomPropertyEditor::_drag_easing(const Ref<InputEvent> &p_ev) {
}
void CustomPropertyEditor::_draw_easing() {
-
RID ci = easing_draw->get_canvas_item();
Size2 s = easing_draw->get_size();
@@ -1489,7 +1389,6 @@ void CustomPropertyEditor::_draw_easing() {
Color color = easing_draw->get_theme_color("font_color", "Label");
for (int i = 1; i <= points; i++) {
-
float ifl = i / float(points);
float iflp = (i - 1) / float(points);
@@ -1508,27 +1407,24 @@ void CustomPropertyEditor::_draw_easing() {
}
void CustomPropertyEditor::_text_edit_changed() {
-
v = text_edit->get_text();
emit_signal("variant_changed");
}
void CustomPropertyEditor::_create_dialog_callback() {
-
v = create_dialog->get_selected_type();
emit_signal("variant_changed");
}
void CustomPropertyEditor::_create_selected_property(const String &p_prop) {
-
v = p_prop;
emit_signal("variant_changed");
}
void CustomPropertyEditor::_modified(String p_string) {
-
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
switch (type) {
@@ -1547,7 +1443,6 @@ void CustomPropertyEditor::_modified(String p_string) {
} break;
case Variant::FLOAT: {
-
if (hint != PROPERTY_HINT_EXP_EASING) {
String text = value_editor[0]->get_text();
v = _parse_real_expression(text);
@@ -1556,12 +1451,10 @@ void CustomPropertyEditor::_modified(String p_string) {
} break;
case Variant::STRING: {
-
v = value_editor[0]->get_text();
emit_signal("variant_changed");
} break;
case Variant::VECTOR2: {
-
Vector2 vec;
vec.x = _parse_real_expression(value_editor[0]->get_text());
vec.y = _parse_real_expression(value_editor[1]->get_text());
@@ -1570,7 +1463,6 @@ void CustomPropertyEditor::_modified(String p_string) {
} break;
case Variant::RECT2: {
-
Rect2 r2;
r2.position.x = _parse_real_expression(value_editor[0]->get_text());
@@ -1583,7 +1475,6 @@ void CustomPropertyEditor::_modified(String p_string) {
} break;
case Variant::VECTOR3: {
-
Vector3 vec;
vec.x = _parse_real_expression(value_editor[0]->get_text());
vec.y = _parse_real_expression(value_editor[1]->get_text());
@@ -1593,7 +1484,6 @@ void CustomPropertyEditor::_modified(String p_string) {
} break;
case Variant::PLANE: {
-
Plane pl;
pl.normal.x = _parse_real_expression(value_editor[0]->get_text());
pl.normal.y = _parse_real_expression(value_editor[1]->get_text());
@@ -1604,7 +1494,6 @@ void CustomPropertyEditor::_modified(String p_string) {
} break;
case Variant::QUAT: {
-
Quat q;
q.x = _parse_real_expression(value_editor[0]->get_text());
q.y = _parse_real_expression(value_editor[1]->get_text());
@@ -1615,7 +1504,6 @@ void CustomPropertyEditor::_modified(String p_string) {
} break;
case Variant::AABB: {
-
Vector3 pos;
Vector3 size;
@@ -1630,7 +1518,6 @@ void CustomPropertyEditor::_modified(String p_string) {
} break;
case Variant::TRANSFORM2D: {
-
Transform2D m;
for (int i = 0; i < 6; i++) {
m.elements[i / 2][i % 2] = _parse_real_expression(value_editor[i]->get_text());
@@ -1641,7 +1528,6 @@ void CustomPropertyEditor::_modified(String p_string) {
} break;
case Variant::BASIS: {
-
Basis m;
for (int i = 0; i < 9; i++) {
m.elements[i / 3][i % 3] = _parse_real_expression(value_editor[i]->get_text());
@@ -1652,7 +1538,6 @@ void CustomPropertyEditor::_modified(String p_string) {
} break;
case Variant::TRANSFORM: {
-
Basis basis;
for (int i = 0; i < 9; i++) {
basis.elements[i / 3][i % 3] = _parse_real_expression(value_editor[(i / 3) * 4 + i % 3]->get_text());
@@ -1669,34 +1554,25 @@ void CustomPropertyEditor::_modified(String p_string) {
} break;
case Variant::COLOR: {
-
} break;
case Variant::NODE_PATH: {
-
v = NodePath(value_editor[0]->get_text());
emit_signal("variant_changed");
} break;
case Variant::DICTIONARY: {
-
} break;
case Variant::PACKED_BYTE_ARRAY: {
-
} break;
case Variant::PACKED_INT32_ARRAY: {
-
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
-
} break;
case Variant::PACKED_STRING_ARRAY: {
-
} break;
case Variant::PACKED_VECTOR3_ARRAY: {
-
} break;
case Variant::PACKED_COLOR_ARRAY: {
-
} break;
default: {
}
@@ -1719,8 +1595,7 @@ real_t CustomPropertyEditor::_parse_real_expression(String text) {
}
void CustomPropertyEditor::_emit_changed_whole_or_field() {
-
- if (!InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (!Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
emit_signal("variant_changed");
} else {
emit_signal("variant_field_changed", field_names[focused_value_editor]);
@@ -1781,7 +1656,6 @@ void CustomPropertyEditor::_focus_exit() {
}
void CustomPropertyEditor::config_action_buttons(const List<String> &p_strings) {
-
Ref<StyleBox> sb = action_buttons[0]->get_theme_stylebox("panel");
int margin_top = sb->get_margin(MARGIN_TOP);
int margin_left = sb->get_margin(MARGIN_LEFT);
@@ -1792,15 +1666,14 @@ void CustomPropertyEditor::config_action_buttons(const List<String> &p_strings)
int height = 0;
for (int i = 0; i < MAX_ACTION_BUTTONS; i++) {
-
if (i < p_strings.size()) {
-
action_buttons[i]->show();
action_buttons[i]->set_text(p_strings[i]);
Size2 btn_m_size = action_buttons[i]->get_minimum_size();
- if (btn_m_size.width > max_width)
+ if (btn_m_size.width > max_width) {
max_width = btn_m_size.width;
+ }
} else {
action_buttons[i]->hide();
@@ -1808,7 +1681,6 @@ void CustomPropertyEditor::config_action_buttons(const List<String> &p_strings)
}
for (int i = 0; i < p_strings.size(); i++) {
-
Size2 btn_m_size = action_buttons[i]->get_size();
action_buttons[i]->set_position(Point2(0, height) + Point2(margin_left, margin_top));
action_buttons[i]->set_size(Size2(max_width, btn_m_size.height));
@@ -1819,7 +1691,6 @@ void CustomPropertyEditor::config_action_buttons(const List<String> &p_strings)
}
void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns, int p_label_w, const List<String> &p_strings) {
-
int cell_width = 95;
int cell_height = 25;
int cell_margin = 5;
@@ -1830,7 +1701,6 @@ void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns, int
set_size(Size2(cell_margin + p_label_w + (cell_width + cell_margin + p_label_w) * p_columns, cell_margin + (cell_height + cell_margin) * rows) * EDSCALE);
for (int i = 0; i < MAX_VALUE_EDITORS; i++) {
-
int c = i % p_columns;
int r = i / p_columns;
@@ -1850,19 +1720,16 @@ void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns, int
}
void CustomPropertyEditor::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("variant_changed"));
ADD_SIGNAL(MethodInfo("variant_field_changed", PropertyInfo(Variant::STRING, "field")));
ADD_SIGNAL(MethodInfo("resource_edit_request"));
}
CustomPropertyEditor::CustomPropertyEditor() {
-
read_only = false;
updating = false;
for (int i = 0; i < MAX_VALUE_EDITORS; i++) {
-
value_editor[i] = memnew(LineEdit);
add_child(value_editor[i]);
value_label[i] = memnew(Label);
@@ -1876,7 +1743,6 @@ CustomPropertyEditor::CustomPropertyEditor() {
focused_value_editor = -1;
for (int i = 0; i < 4; i++) {
-
scroll[i] = memnew(HScrollBar);
scroll[i]->hide();
scroll[i]->set_min(0);
@@ -1914,7 +1780,6 @@ CustomPropertyEditor::CustomPropertyEditor() {
text_edit->connect("text_changed", callable_mp(this, &CustomPropertyEditor::_text_edit_changed));
for (int i = 0; i < MAX_ACTION_BUTTONS; i++) {
-
action_buttons[i] = memnew(Button);
action_buttons[i]->hide();
add_child(action_buttons[i]);
diff --git a/editor/property_editor.h b/editor/property_editor.h
index 45466eaa42..5b7db3b83f 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -51,7 +51,6 @@ class CreateDialog;
class PropertySelector;
class EditorResourceConversionPlugin : public Reference {
-
GDCLASS(EditorResourceConversionPlugin, Reference);
protected:
@@ -64,7 +63,6 @@ public:
};
class CustomPropertyEditor : public PopupPanel {
-
GDCLASS(CustomPropertyEditor, PopupPanel);
enum {
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index 1960ecc604..6888ebdc71 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -35,28 +35,25 @@
#include "editor_scale.h"
void PropertySelector::_text_changed(const String &p_newtext) {
-
_update_search();
}
void PropertySelector::_sbox_input(const Ref<InputEvent> &p_ie) {
-
Ref<InputEventKey> k = p_ie;
if (k.is_valid()) {
-
switch (k->get_keycode()) {
case KEY_UP:
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
-
search_options->call("_gui_input", k);
search_box->accept_event();
TreeItem *root = search_options->get_root();
- if (!root->get_children())
+ if (!root->get_children()) {
break;
+ }
TreeItem *current = search_options->get_selected();
@@ -74,13 +71,13 @@ void PropertySelector::_sbox_input(const Ref<InputEvent> &p_ie) {
}
void PropertySelector::_update_search() {
-
- if (properties)
+ if (properties) {
set_title(TTR("Select Property"));
- else if (virtuals_only)
+ } else if (virtuals_only) {
set_title(TTR("Select Virtual Method"));
- else
+ } else {
set_title(TTR("Select Method"));
+ }
search_options->clear();
help_bit->set_text("");
@@ -88,7 +85,6 @@ void PropertySelector::_update_search() {
TreeItem *root = search_options->create_item();
if (properties) {
-
List<PropertyInfo> props;
if (instance) {
@@ -100,10 +96,8 @@ void PropertySelector::_update_search() {
v.get_property_list(&props);
} else {
-
Object *obj = ObjectDB::get_instance(script);
if (Object::cast_to<Script>(obj)) {
-
props.push_back(PropertyInfo(Variant::NIL, "Script Variables", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_CATEGORY));
Object::cast_to<Script>(obj)->get_script_property_list(&props);
}
@@ -169,14 +163,17 @@ void PropertySelector::_update_search() {
continue;
}
- if (!(E->get().usage & PROPERTY_USAGE_EDITOR) && !(E->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE))
+ if (!(E->get().usage & PROPERTY_USAGE_EDITOR) && !(E->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE)) {
continue;
+ }
- if (search_box->get_text() != String() && E->get().name.find(search_box->get_text()) == -1)
+ if (search_box->get_text() != String() && E->get().name.find(search_box->get_text()) == -1) {
continue;
+ }
- if (type_filter.size() && type_filter.find(E->get().type) == -1)
+ if (type_filter.size() && type_filter.find(E->get().type) == -1) {
continue;
+ }
TreeItem *item = search_options->create_item(category ? category : root);
item->set_text(0, E->get().name);
@@ -195,7 +192,6 @@ void PropertySelector::_update_search() {
memdelete(category); //old category was unused
}
} else {
-
List<MethodInfo> methods;
if (type != Variant::NIL) {
@@ -204,10 +200,8 @@ void PropertySelector::_update_search() {
v = Variant::construct(type, nullptr, 0, ce);
v.get_method_list(&methods);
} else {
-
Object *obj = ObjectDB::get_instance(script);
if (Object::cast_to<Script>(obj)) {
-
methods.push_back(MethodInfo("*Script Methods"));
Object::cast_to<Script>(obj)->get_script_method_list(&methods);
}
@@ -249,17 +243,21 @@ void PropertySelector::_update_search() {
}
String name = E->get().name.get_slice(":", 0);
- if (!script_methods && name.begins_with("_") && !(E->get().flags & METHOD_FLAG_VIRTUAL))
+ if (!script_methods && name.begins_with("_") && !(E->get().flags & METHOD_FLAG_VIRTUAL)) {
continue;
+ }
- if (virtuals_only && !(E->get().flags & METHOD_FLAG_VIRTUAL))
+ if (virtuals_only && !(E->get().flags & METHOD_FLAG_VIRTUAL)) {
continue;
+ }
- if (!virtuals_only && (E->get().flags & METHOD_FLAG_VIRTUAL))
+ if (!virtuals_only && (E->get().flags & METHOD_FLAG_VIRTUAL)) {
continue;
+ }
- if (search_box->get_text() != String() && name.find(search_box->get_text()) == -1)
+ if (search_box->get_text() != String() && name.find(search_box->get_text()) == -1) {
continue;
+ }
TreeItem *item = search_options->create_item(category ? category : root);
@@ -269,36 +267,40 @@ void PropertySelector::_update_search() {
if (mi.name.find(":") != -1) {
desc = mi.name.get_slice(":", 1) + " ";
mi.name = mi.name.get_slice(":", 0);
- } else if (mi.return_val.type != Variant::NIL)
+ } else if (mi.return_val.type != Variant::NIL) {
desc = Variant::get_type_name(mi.return_val.type);
- else
+ } else {
desc = "void ";
+ }
desc += " " + mi.name + " ( ";
for (int i = 0; i < mi.arguments.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
desc += ", ";
+ }
- if (mi.arguments[i].type == Variant::NIL)
+ if (mi.arguments[i].type == Variant::NIL) {
desc += "var ";
- else if (mi.arguments[i].name.find(":") != -1) {
+ } else if (mi.arguments[i].name.find(":") != -1) {
desc += mi.arguments[i].name.get_slice(":", 1) + " ";
mi.arguments[i].name = mi.arguments[i].name.get_slice(":", 0);
- } else
+ } else {
desc += Variant::get_type_name(mi.arguments[i].type) + " ";
+ }
desc += mi.arguments[i].name;
}
desc += " )";
- if (E->get().flags & METHOD_FLAG_CONST)
+ if (E->get().flags & METHOD_FLAG_CONST) {
desc += " const";
+ }
- if (E->get().flags & METHOD_FLAG_VIRTUAL)
+ if (E->get().flags & METHOD_FLAG_VIRTUAL) {
desc += " virtual";
+ }
item->set_text(0, desc);
item->set_metadata(0, name);
@@ -319,21 +321,21 @@ void PropertySelector::_update_search() {
}
void PropertySelector::_confirmed() {
-
TreeItem *ti = search_options->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
emit_signal("selected", ti->get_metadata(0));
hide();
}
void PropertySelector::_item_selected() {
-
help_bit->set_text("");
TreeItem *item = search_options->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
String name = item->get_metadata(0);
String class_type;
@@ -348,11 +350,9 @@ void PropertySelector::_item_selected() {
String text;
if (properties) {
-
String at_class = class_type;
while (at_class != String()) {
-
Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(at_class);
if (E) {
for (int i = 0; i < E->get().properties.size(); i++) {
@@ -365,11 +365,9 @@ void PropertySelector::_item_selected() {
at_class = ClassDB::get_parent_class(at_class);
}
} else {
-
String at_class = class_type;
while (at_class != String()) {
-
Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(at_class);
if (E) {
for (int i = 0; i < E->get().methods.size(); i++) {
@@ -383,8 +381,9 @@ void PropertySelector::_item_selected() {
}
}
- if (text == String())
+ if (text == String()) {
return;
+ }
help_bit->set_text(text);
}
@@ -394,9 +393,7 @@ void PropertySelector::_hide_requested() {
}
void PropertySelector::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
connect("confirmed", callable_mp(this, &PropertySelector::_confirmed));
} else if (p_what == NOTIFICATION_EXIT_TREE) {
disconnect("confirmed", callable_mp(this, &PropertySelector::_confirmed));
@@ -404,7 +401,6 @@ void PropertySelector::_notification(int p_what) {
}
void PropertySelector::select_method_from_base_type(const String &p_base, const String &p_current, bool p_virtuals_only) {
-
base_type = p_base;
selected = p_current;
type = Variant::NIL;
@@ -420,7 +416,6 @@ void PropertySelector::select_method_from_base_type(const String &p_base, const
}
void PropertySelector::select_method_from_script(const Ref<Script> &p_script, const String &p_current) {
-
ERR_FAIL_COND(p_script.is_null());
base_type = p_script->get_instance_base_type();
selected = p_current;
@@ -435,8 +430,8 @@ void PropertySelector::select_method_from_script(const Ref<Script> &p_script, co
search_box->grab_focus();
_update_search();
}
-void PropertySelector::select_method_from_basic_type(Variant::Type p_type, const String &p_current) {
+void PropertySelector::select_method_from_basic_type(Variant::Type p_type, const String &p_current) {
ERR_FAIL_COND(p_type == Variant::NIL);
base_type = "";
selected = p_current;
@@ -453,15 +448,15 @@ void PropertySelector::select_method_from_basic_type(Variant::Type p_type, const
}
void PropertySelector::select_method_from_instance(Object *p_instance, const String &p_current) {
-
base_type = p_instance->get_class();
selected = p_current;
type = Variant::NIL;
script = ObjectID();
{
Ref<Script> scr = p_instance->get_script();
- if (scr.is_valid())
+ if (scr.is_valid()) {
script = scr->get_instance_id();
+ }
}
properties = false;
instance = nullptr;
@@ -474,7 +469,6 @@ void PropertySelector::select_method_from_instance(Object *p_instance, const Str
}
void PropertySelector::select_property_from_base_type(const String &p_base, const String &p_current) {
-
base_type = p_base;
selected = p_current;
type = Variant::NIL;
@@ -490,7 +484,6 @@ void PropertySelector::select_property_from_base_type(const String &p_base, cons
}
void PropertySelector::select_property_from_script(const Ref<Script> &p_script, const String &p_current) {
-
ERR_FAIL_COND(p_script.is_null());
base_type = p_script->get_instance_base_type();
@@ -508,7 +501,6 @@ void PropertySelector::select_property_from_script(const Ref<Script> &p_script,
}
void PropertySelector::select_property_from_basic_type(Variant::Type p_type, const String &p_current) {
-
ERR_FAIL_COND(p_type == Variant::NIL);
base_type = "";
selected = p_current;
@@ -525,7 +517,6 @@ void PropertySelector::select_property_from_basic_type(Variant::Type p_type, con
}
void PropertySelector::select_property_from_instance(Object *p_instance, const String &p_current) {
-
base_type = "";
selected = p_current;
type = Variant::NIL;
@@ -545,12 +536,10 @@ void PropertySelector::set_type_filter(const Vector<Variant::Type> &p_type_filte
}
void PropertySelector::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "name")));
}
PropertySelector::PropertySelector() {
-
VBoxContainer *vbc = memnew(VBoxContainer);
add_child(vbc);
//set_child_rect(vbc);
diff --git a/editor/pvrtc_compress.cpp b/editor/pvrtc_compress.cpp
index 1363fe2942..23bcf9540e 100644
--- a/editor/pvrtc_compress.cpp
+++ b/editor/pvrtc_compress.cpp
@@ -42,21 +42,21 @@ static void (*_base_image_compress_pvrtc2_func)(Image *) = nullptr;
static void (*_base_image_compress_pvrtc4_func)(Image *) = nullptr;
static void _compress_image(Image::CompressMode p_mode, Image *p_image) {
-
String ttpath = EditorSettings::get_singleton()->get("filesystem/import/pvrtc_texture_tool");
if (ttpath.strip_edges() == "" || !FileAccess::exists(ttpath)) {
switch (p_mode) {
-
case Image::COMPRESS_PVRTC2:
- if (_base_image_compress_pvrtc2_func)
+ if (_base_image_compress_pvrtc2_func) {
_base_image_compress_pvrtc2_func(p_image);
- else if (_base_image_compress_pvrtc4_func)
+ } else if (_base_image_compress_pvrtc4_func) {
_base_image_compress_pvrtc4_func(p_image);
+ }
break;
case Image::COMPRESS_PVRTC4:
- if (_base_image_compress_pvrtc4_func)
+ if (_base_image_compress_pvrtc4_func) {
_base_image_compress_pvrtc4_func(p_image);
+ }
break;
default:
ERR_FAIL_MSG("Unsupported Image compress mode used in PVRTC module.");
@@ -125,17 +125,14 @@ static void _compress_image(Image::CompressMode p_mode, Image *p_image) {
}
static void _compress_pvrtc2(Image *p_image) {
-
_compress_image(Image::COMPRESS_PVRTC2, p_image);
}
static void _compress_pvrtc4(Image *p_image) {
-
_compress_image(Image::COMPRESS_PVRTC4, p_image);
}
void _pvrtc_register_compressors() {
-
_base_image_compress_pvrtc2_func = Image::_image_compress_pvrtc2_func;
_base_image_compress_pvrtc4_func = Image::_image_compress_pvrtc4_func;
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index 1b4439f0a8..bcef29dfa6 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -33,38 +33,37 @@
#include "core/os/keyboard.h"
void EditorQuickOpen::popup_dialog(const StringName &p_base, bool p_enable_multi, bool p_add_dirs, bool p_dontclear) {
-
add_directories = p_add_dirs;
popup_centered_ratio(0.6);
- if (p_dontclear)
+ if (p_dontclear) {
search_box->select_all();
- else
+ } else {
search_box->clear();
- if (p_enable_multi)
+ }
+ if (p_enable_multi) {
search_options->set_select_mode(Tree::SELECT_MULTI);
- else
+ } else {
search_options->set_select_mode(Tree::SELECT_SINGLE);
+ }
search_box->grab_focus();
base_type = p_base;
_update_search();
}
String EditorQuickOpen::get_selected() const {
-
TreeItem *ti = search_options->get_selected();
- if (!ti)
+ if (!ti) {
return String();
+ }
return "res://" + ti->get_text(0);
}
Vector<String> EditorQuickOpen::get_selected_files() const {
-
Vector<String> files;
TreeItem *item = search_options->get_next_selected(search_options->get_root());
while (item) {
-
files.push_back("res://" + item->get_text(0));
item = search_options->get_next_selected(item);
@@ -74,27 +73,24 @@ Vector<String> EditorQuickOpen::get_selected_files() const {
}
void EditorQuickOpen::_text_changed(const String &p_newtext) {
-
_update_search();
}
void EditorQuickOpen::_sbox_input(const Ref<InputEvent> &p_ie) {
-
Ref<InputEventKey> k = p_ie;
if (k.is_valid()) {
-
switch (k->get_keycode()) {
case KEY_UP:
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
-
search_options->call("_gui_input", k);
search_box->accept_event();
TreeItem *root = search_options->get_root();
- if (!root->get_children())
+ if (!root->get_children()) {
break;
+ }
TreeItem *current = search_options->get_selected();
@@ -112,21 +108,24 @@ void EditorQuickOpen::_sbox_input(const Ref<InputEvent> &p_ie) {
}
float EditorQuickOpen::_path_cmp(String search, String path) const {
-
+ // Exact match.
if (search == path) {
return 1.2f;
}
- if (path.findn(search) != -1) {
- return 1.1f;
+
+ // Substring match, with positive bias for matches close to the end of the path.
+ int pos = path.rfindn(search);
+ if (pos != -1) {
+ return 1.1f + 0.09 / (path.length() - pos + 1);
}
+
+ // Similarity.
return path.to_lower().similarity(search.to_lower());
}
void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<String, Ref<Texture2D>>> &list) {
-
if (!add_directories) {
for (int i = 0; i < efsd->get_subdir_count(); i++) {
-
_parse_fs(efsd->get_subdir(i), list);
}
}
@@ -135,8 +134,9 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str
if (add_directories) {
String path = efsd->get_path();
- if (!path.ends_with("/"))
+ if (!path.ends_with("/")) {
path += "/";
+ }
if (path != "res://") {
path = path.substr(6, path.length());
if (search_text.is_subsequence_ofi(path)) {
@@ -145,7 +145,6 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str
pair.second = search_options->get_theme_icon("folder", "FileDialog");
if (search_text != String() && list.size() > 0) {
-
float this_sim = _path_cmp(search_text, path);
float other_sim = _path_cmp(list[0].first, path);
int pos = 1;
@@ -164,7 +163,6 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str
}
}
for (int i = 0; i < efsd->get_file_count(); i++) {
-
String file = efsd->get_file_path(i);
file = file.substr(6, file.length());
@@ -178,27 +176,26 @@ void EditorQuickOpen::_parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<Str
if (add_directories) {
for (int i = 0; i < efsd->get_subdir_count(); i++) {
-
_parse_fs(efsd->get_subdir(i), list);
}
}
}
Vector<Pair<String, Ref<Texture2D>>> EditorQuickOpen::_sort_fs(Vector<Pair<String, Ref<Texture2D>>> &list) {
-
String search_text = search_box->get_text();
Vector<Pair<String, Ref<Texture2D>>> sorted_list;
- if (search_text == String() || list.size() == 0)
+ if (search_text == String() || list.size() == 0) {
return list;
+ }
Vector<float> scores;
scores.resize(list.size());
- for (int i = 0; i < list.size(); i++)
+ for (int i = 0; i < list.size(); i++) {
scores.write[i] = _path_cmp(search_text, list[i].first);
+ }
while (list.size() > 0) {
-
float best_score = 0.0f;
int best_idx = 0;
@@ -219,7 +216,6 @@ Vector<Pair<String, Ref<Texture2D>>> EditorQuickOpen::_sort_fs(Vector<Pair<Strin
}
void EditorQuickOpen::_update_search() {
-
search_options->clear();
TreeItem *root = search_options->create_item();
EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->get_filesystem();
@@ -245,21 +241,19 @@ void EditorQuickOpen::_update_search() {
}
void EditorQuickOpen::_confirmed() {
-
TreeItem *ti = search_options->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
emit_signal("quick_open");
hide();
}
void EditorQuickOpen::_theme_changed() {
-
search_box->set_right_icon(search_options->get_theme_icon("Search", "EditorIcons"));
}
void EditorQuickOpen::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
connect("confirmed", callable_mp(this, &EditorQuickOpen::_confirmed));
@@ -273,17 +267,14 @@ void EditorQuickOpen::_notification(int p_what) {
}
StringName EditorQuickOpen::get_base_type() const {
-
return base_type;
}
void EditorQuickOpen::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("quick_open"));
}
EditorQuickOpen::EditorQuickOpen() {
-
VBoxContainer *vbc = memnew(VBoxContainer);
vbc->connect("theme_changed", callable_mp(this, &EditorQuickOpen::_theme_changed));
diff --git a/editor/quick_open.h b/editor/quick_open.h
index c0e2cb85d8..e446ed6823 100644
--- a/editor/quick_open.h
+++ b/editor/quick_open.h
@@ -36,7 +36,6 @@
#include "scene/gui/dialogs.h"
#include "scene/gui/tree.h"
class EditorQuickOpen : public ConfirmationDialog {
-
GDCLASS(EditorQuickOpen, ConfirmationDialog);
LineEdit *search_box;
diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp
index 0266ef6a2b..6a54894f40 100644
--- a/editor/rename_dialog.cpp
+++ b/editor/rename_dialog.cpp
@@ -42,7 +42,6 @@
#include "scene/gui/tab_container.h"
RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_undo_redo) {
-
scene_tree_editor = p_scene_tree_editor;
undo_redo = p_undo_redo;
preview_node = nullptr;
@@ -341,12 +340,10 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und
}
void RenameDialog::_bind_methods() {
-
ClassDB::bind_method("rename", &RenameDialog::rename);
}
void RenameDialog::_update_substitute() {
-
LineEdit *focus_owner_line_edit = Object::cast_to<LineEdit>(scene_tree_editor->get_focus_owner());
bool is_main_field = _is_main_field(focus_owner_line_edit);
@@ -367,7 +364,6 @@ void RenameDialog::_update_substitute() {
}
void RenameDialog::_post_popup() {
-
EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection();
preview_node = nullptr;
@@ -385,9 +381,9 @@ void RenameDialog::_update_preview_int(int new_value) {
}
void RenameDialog::_update_preview(String new_text) {
-
- if (lock_preview_update || preview_node == nullptr)
+ if (lock_preview_update || preview_node == nullptr) {
return;
+ }
has_errors = false;
add_error_handler(&eh);
@@ -395,7 +391,6 @@ void RenameDialog::_update_preview(String new_text) {
String new_name = _apply_rename(preview_node, spn_count_start->get_value());
if (!has_errors) {
-
lbl_preview_title->set_text(TTR("Preview"));
lbl_preview->set_text(new_name);
@@ -403,7 +398,7 @@ void RenameDialog::_update_preview(String new_text) {
// New name is identical to the old one. Don't color it as much to avoid distracting the user.
const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color("accent_color", "Editor");
const Color text_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color("default_color", "RichTextLabel");
- lbl_preview->add_theme_color_override("font_color", accent_color.linear_interpolate(text_color, 0.5));
+ lbl_preview->add_theme_color_override("font_color", accent_color.lerp(text_color, 0.5));
} else {
lbl_preview->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color("success_color", "Editor"));
}
@@ -413,7 +408,6 @@ void RenameDialog::_update_preview(String new_text) {
}
String RenameDialog::_apply_rename(const Node *node, int count) {
-
String search = lne_search->get_text();
String replace = lne_replace->get_text();
String prefix = lne_prefix->get_text();
@@ -428,7 +422,6 @@ String RenameDialog::_apply_rename(const Node *node, int count) {
}
if (cbut_regex->is_pressed()) {
-
new_name = _regex(search, new_name, replace);
} else {
new_name = new_name.replace(search, replace);
@@ -444,7 +437,6 @@ String RenameDialog::_apply_rename(const Node *node, int count) {
}
String RenameDialog::_substitute(const String &subject, const Node *node, int count) {
-
String result = subject.replace("${COUNTER}", vformat("%0" + itos(spn_count_padding->get_value()) + "d", count));
if (node) {
@@ -474,13 +466,13 @@ String RenameDialog::_substitute(const String &subject, const Node *node, int co
}
void RenameDialog::_error_handler(void *p_self, const char *p_func, const char *p_file, int p_line, const char *p_error, const char *p_errorexp, ErrorHandlerType p_type) {
-
RenameDialog *self = (RenameDialog *)p_self;
String source_file(p_file);
// Only show first error that is related to "regex"
- if (self->has_errors || source_file.find("regex") < 0)
+ if (self->has_errors || source_file.find("regex") < 0) {
return;
+ }
String err_str;
if (p_errorexp && p_errorexp[0]) {
@@ -496,14 +488,12 @@ void RenameDialog::_error_handler(void *p_self, const char *p_func, const char *
}
String RenameDialog::_regex(const String &pattern, const String &subject, const String &replacement) {
-
RegEx regex(pattern);
return regex.sub(subject, replacement, true);
}
String RenameDialog::_postprocess(const String &subject) {
-
int style_id = opt_style->get_selected();
String result = subject;
@@ -550,12 +540,11 @@ String RenameDialog::_postprocess(const String &subject) {
}
void RenameDialog::_iterate_scene(const Node *node, const Array &selection, int *counter) {
-
- if (!node)
+ if (!node) {
return;
+ }
if (selection.has(node)) {
-
String new_name = _apply_rename(node, *counter);
if (node->get_name() != new_name) {
@@ -581,7 +570,6 @@ void RenameDialog::_iterate_scene(const Node *node, const Array &selection, int
}
void RenameDialog::rename() {
-
// Editor selection is not ordered via scene tree. Instead iterate
// over scene tree until all selected nodes are found in order.
@@ -596,12 +584,10 @@ void RenameDialog::rename() {
_iterate_scene(root_node, selected_node_list, &global_count);
if (undo_redo && !to_rename.empty()) {
-
undo_redo->create_action(TTR("Batch Rename"));
// Make sure to iterate reversed so that child nodes will find parents.
for (int i = to_rename.size() - 1; i >= 0; --i) {
-
Node *n = root_node->get_node(to_rename[i].first);
const String &new_name = to_rename[i].second;
@@ -620,7 +606,6 @@ void RenameDialog::rename() {
}
void RenameDialog::reset() {
-
lock_preview_update = true;
lne_prefix->clear();
@@ -651,7 +636,6 @@ bool RenameDialog::_is_main_field(LineEdit *line_edit) {
}
void RenameDialog::_insert_text(String text) {
-
LineEdit *focus_owner = Object::cast_to<LineEdit>(scene_tree_editor->get_focus_owner());
if (_is_main_field(focus_owner)) {
diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h
index 194dd57648..dfdb1bcd76 100644
--- a/editor/rename_dialog.h
+++ b/editor/rename_dialog.h
@@ -44,11 +44,10 @@
*/
class RenameDialog : public ConfirmationDialog {
-
GDCLASS(RenameDialog, ConfirmationDialog);
virtual void ok_pressed() { rename(); };
- void _cancel_pressed(){};
+ void _cancel_pressed() {}
void _features_toggled(bool pressed);
void _insert_text(String text);
void _update_substitute();
@@ -111,7 +110,7 @@ public:
void rename();
RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_undo_redo = nullptr);
- ~RenameDialog(){};
+ ~RenameDialog() {}
};
#endif
diff --git a/editor/reparent_dialog.cpp b/editor/reparent_dialog.cpp
index b71c2bd078..e5ae09f5ff 100644
--- a/editor/reparent_dialog.cpp
+++ b/editor/reparent_dialog.cpp
@@ -35,46 +35,38 @@
#include "scene/gui/label.h"
void ReparentDialog::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
connect("confirmed", callable_mp(this, &ReparentDialog::_reparent));
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
disconnect("confirmed", callable_mp(this, &ReparentDialog::_reparent));
}
}
void ReparentDialog::_cancel() {
-
hide();
}
-void ReparentDialog::_reparent() {
+void ReparentDialog::_reparent() {
if (tree->get_selected()) {
-
emit_signal("reparent", tree->get_selected()->get_path(), keep_transform->is_pressed());
hide();
}
}
void ReparentDialog::set_current(const Set<Node *> &p_selection) {
-
tree->set_marked(p_selection, false, false);
//tree->set_selected(p_node->get_parent());
}
void ReparentDialog::_bind_methods() {
-
ClassDB::bind_method("_cancel", &ReparentDialog::_cancel);
ADD_SIGNAL(MethodInfo("reparent", PropertyInfo(Variant::NODE_PATH, "path"), PropertyInfo(Variant::BOOL, "keep_global_xform")));
}
ReparentDialog::ReparentDialog() {
-
set_title(TTR("Reparent Node"));
VBoxContainer *vbc = memnew(VBoxContainer);
diff --git a/editor/reparent_dialog.h b/editor/reparent_dialog.h
index 29db70baa5..4566e3a02a 100644
--- a/editor/reparent_dialog.h
+++ b/editor/reparent_dialog.h
@@ -41,7 +41,6 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class ReparentDialog : public ConfirmationDialog {
-
GDCLASS(ReparentDialog, ConfirmationDialog);
SceneTreeEditor *tree;
diff --git a/editor/run_settings_dialog.cpp b/editor/run_settings_dialog.cpp
index a5ae1fd8a6..b6dda4c5bb 100644
--- a/editor/run_settings_dialog.cpp
+++ b/editor/run_settings_dialog.cpp
@@ -31,45 +31,39 @@
#include "run_settings_dialog.h"
void RunSettingsDialog::popup_run_settings() {
-
popup_centered(Size2(300, 150));
}
void RunSettingsDialog::set_custom_arguments(const String &p_arguments) {
-
arguments->set_text(p_arguments);
}
-String RunSettingsDialog::get_custom_arguments() const {
+String RunSettingsDialog::get_custom_arguments() const {
return arguments->get_text();
}
void RunSettingsDialog::_bind_methods() {
-
//ClassDB::bind_method("_browse_selected_file",&RunSettingsDialog::_browse_selected_file);
}
void RunSettingsDialog::_run_mode_changed(int idx) {
-
- if (idx == 0)
+ if (idx == 0) {
arguments->set_editable(false);
- else
+ } else {
arguments->set_editable(true);
+ }
}
int RunSettingsDialog::get_run_mode() const {
-
return run_mode->get_selected();
}
void RunSettingsDialog::set_run_mode(int p_run_mode) {
-
run_mode->select(p_run_mode);
arguments->set_editable(p_run_mode);
}
RunSettingsDialog::RunSettingsDialog() {
-
/* SNAP DIALOG */
VBoxContainer *vbc = memnew(VBoxContainer);
diff --git a/editor/run_settings_dialog.h b/editor/run_settings_dialog.h
index b812bbfa9e..4d6d842de0 100644
--- a/editor/run_settings_dialog.h
+++ b/editor/run_settings_dialog.h
@@ -37,7 +37,6 @@
#include "scene/gui/line_edit.h"
class RunSettingsDialog : public AcceptDialog {
-
GDCLASS(RunSettingsDialog, AcceptDialog);
public:
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index a729f62123..a81a2ff4e9 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -30,7 +30,7 @@
#include "scene_tree_dock.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/resource_saver.h"
#include "core/os/keyboard.h"
#include "core/project_settings.h"
@@ -50,7 +50,6 @@
#include "servers/rendering_server.h"
void SceneTreeDock::_nodes_drag_begin() {
-
if (restore_script_editor_on_drag) {
EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
restore_script_editor_on_drag = false;
@@ -65,7 +64,6 @@ void SceneTreeDock::_quick_open() {
}
void SceneTreeDock::_input(Ref<InputEvent> p_event) {
-
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
@@ -74,12 +72,13 @@ void SceneTreeDock::_input(Ref<InputEvent> p_event) {
}
void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
-
- if (get_focus_owner() && get_focus_owner()->is_text_field())
+ if (get_focus_owner() && get_focus_owner()->is_text_field()) {
return;
+ }
- if (!p_event->is_pressed() || p_event->is_echo())
+ if (!p_event->is_pressed() || p_event->is_echo()) {
return;
+ }
if (ED_IS_SHORTCUT("scene_tree/batch_rename", p_event)) {
_tool_selected(TOOL_BATCH_RENAME);
@@ -97,8 +96,8 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
_tool_selected(TOOL_DUPLICATE);
} else if (ED_IS_SHORTCUT("scene_tree/attach_script", p_event)) {
_tool_selected(TOOL_ATTACH_SCRIPT);
- } else if (ED_IS_SHORTCUT("scene_tree/clear_script", p_event)) {
- _tool_selected(TOOL_CLEAR_SCRIPT);
+ } else if (ED_IS_SHORTCUT("scene_tree/detach_script", p_event)) {
+ _tool_selected(TOOL_DETACH_SCRIPT);
} else if (ED_IS_SHORTCUT("scene_tree/move_up", p_event)) {
_tool_selected(TOOL_MOVE_UP);
} else if (ED_IS_SHORTCUT("scene_tree/move_down", p_event)) {
@@ -119,7 +118,6 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
}
void SceneTreeDock::instance(const String &p_file) {
-
Node *parent = scene_tree->get_selected();
if (!parent) {
@@ -127,7 +125,6 @@ void SceneTreeDock::instance(const String &p_file) {
};
if (!edited_scene) {
-
current_option = -1;
accept->set_text(TTR("No parent to instance a child at."));
accept->popup_centered();
@@ -142,7 +139,6 @@ void SceneTreeDock::instance(const String &p_file) {
}
void SceneTreeDock::instance_scenes(const Vector<String> &p_files, Node *p_parent) {
-
Node *parent = p_parent;
if (!parent) {
@@ -150,7 +146,6 @@ void SceneTreeDock::instance_scenes(const Vector<String> &p_files, Node *p_paren
}
if (!parent || !edited_scene) {
-
accept->set_text(TTR("No parent to instance the scenes at."));
accept->popup_centered();
return;
@@ -160,7 +155,6 @@ void SceneTreeDock::instance_scenes(const Vector<String> &p_files, Node *p_paren
}
void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node *parent, int p_pos) {
-
ERR_FAIL_COND(!parent);
Vector<Node *> instances;
@@ -168,7 +162,6 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
bool error = false;
for (int i = 0; i < p_files.size(); i++) {
-
Ref<PackedScene> sdata = ResourceLoader::load(p_files[i]);
if (!sdata.is_valid()) {
current_option = -1;
@@ -188,9 +181,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
}
if (edited_scene->get_filename() != "") {
-
if (_cyclical_dependency_exists(edited_scene->get_filename(), instanced_scene)) {
-
accept->set_text(vformat(TTR("Cannot instance the scene '%s' because the current scene exists within one of its nodes."), p_files[i]));
accept->popup_centered();
error = true;
@@ -213,7 +204,6 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String> &p_files, Node
editor_data->get_undo_redo().create_action(TTR("Instance Scene(s)"));
for (int i = 0; i < instances.size(); i++) {
-
Node *instanced_scene = instances[i];
editor_data->get_undo_redo().add_do_method(parent, "add_child", instanced_scene);
@@ -316,13 +306,16 @@ bool SceneTreeDock::_track_inherit(const String &p_target_scene_path, Node *p_de
Ref<PackedScene> data = ResourceLoader::load(path);
if (data.is_valid()) {
p = data->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
- if (!p)
+ if (!p) {
continue;
+ }
instances.push_back(p);
- } else
+ } else {
break;
- } else
+ }
+ } else {
break;
+ }
}
for (int i = 0; i < instances.size(); i++) {
memdelete(instances[i]);
@@ -331,11 +324,9 @@ bool SceneTreeDock::_track_inherit(const String &p_target_scene_path, Node *p_de
}
void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
-
current_option = p_tool;
switch (p_tool) {
-
case TOOL_BATCH_RENAME: {
if (!profile_allow_editing) {
break;
@@ -356,7 +347,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_NEW:
case TOOL_REPARENT_TO_NEW_NODE: {
-
if (!profile_allow_editing) {
break;
}
@@ -364,17 +354,16 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Node *current_edited_scene_root = EditorNode::get_singleton()->get_edited_scene();
if (current_edited_scene_root) {
-
- if (ClassDB::is_parent_class(current_edited_scene_root->get_class_name(), "Node2D"))
+ if (ClassDB::is_parent_class(current_edited_scene_root->get_class_name(), "Node2D")) {
preferred = "Node2D";
- else if (ClassDB::is_parent_class(current_edited_scene_root->get_class_name(), "Node3D"))
+ } else if (ClassDB::is_parent_class(current_edited_scene_root->get_class_name(), "Node3D")) {
preferred = "Node3D";
+ }
}
create_dialog->set_preferred_search_result_type(preferred);
create_dialog->popup_create(true);
} break;
case TOOL_INSTANCE: {
-
if (!profile_allow_editing) {
break;
}
@@ -390,15 +379,16 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_EXPAND_COLLAPSE: {
-
- if (!scene_tree->get_selected())
+ if (!scene_tree->get_selected()) {
break;
+ }
Tree *tree = scene_tree->get_scene_tree();
TreeItem *selected_item = tree->get_selected();
- if (!selected_item)
+ if (!selected_item) {
selected_item = tree->get_root();
+ }
bool collapsed = _is_collapsed_recursive(selected_item);
_set_collapsed_recursive(selected_item, !collapsed);
@@ -407,17 +397,18 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_REPLACE: {
-
if (!profile_allow_editing) {
break;
}
Node *selected = scene_tree->get_selected();
- if (!selected && !editor_selection->get_selected_node_list().empty())
+ if (!selected && !editor_selection->get_selected_node_list().empty()) {
selected = editor_selection->get_selected_node_list().front()->get();
+ }
- if (selected)
+ if (selected) {
create_dialog->popup_create(false, true, selected->get_class());
+ }
} break;
case TOOL_EXTEND_SCRIPT: {
@@ -426,22 +417,21 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
case TOOL_ATTACH_SCRIPT: {
attach_script_to_selected(false);
} break;
- case TOOL_CLEAR_SCRIPT: {
-
+ case TOOL_DETACH_SCRIPT: {
if (!profile_allow_script_editing) {
break;
}
Array selection = editor_selection->get_selected_nodes();
- if (selection.empty())
+ if (selection.empty()) {
return;
+ }
- editor_data->get_undo_redo().create_action(TTR("Clear Script"));
+ editor_data->get_undo_redo().create_action(TTR("Detach Script"));
editor_data->get_undo_redo().add_do_method(editor, "push_item", (Script *)nullptr);
for (int i = 0; i < selection.size(); i++) {
-
Node *n = Object::cast_to<Node>(selection[i]);
Ref<Script> existing = n->get_script();
Ref<Script> empty = EditorNode::get_singleton()->get_object_custom_type_base(n);
@@ -458,24 +448,24 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_MOVE_UP:
case TOOL_MOVE_DOWN: {
-
if (!profile_allow_editing) {
break;
}
- if (!scene_tree->get_selected())
+ if (!scene_tree->get_selected()) {
break;
+ }
if (scene_tree->get_selected() == edited_scene) {
-
current_option = -1;
accept->set_text(TTR("This operation can't be done on the tree root."));
accept->popup_centered();
break;
}
- if (!_validate_no_foreign())
+ if (!_validate_no_foreign()) {
break;
+ }
bool MOVING_DOWN = (p_tool == TOOL_MOVE_DOWN);
bool MOVING_UP = !MOVING_DOWN;
@@ -483,26 +473,37 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Node *common_parent = scene_tree->get_selected()->get_parent();
List<Node *> selection = editor_selection->get_selected_node_list();
selection.sort_custom<Node::Comparator>(); // sort by index
- if (MOVING_DOWN)
+ if (MOVING_DOWN) {
selection.invert();
+ }
int lowest_id = common_parent->get_child_count() - 1;
int highest_id = 0;
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
int index = E->get()->get_index();
- if (index > highest_id) highest_id = index;
- if (index < lowest_id) lowest_id = index;
+ if (index > highest_id) {
+ highest_id = index;
+ }
+ if (index < lowest_id) {
+ lowest_id = index;
+ }
- if (E->get()->get_parent() != common_parent)
+ if (E->get()->get_parent() != common_parent) {
common_parent = nullptr;
+ }
}
- if (!common_parent || (MOVING_DOWN && highest_id >= common_parent->get_child_count() - MOVING_DOWN) || (MOVING_UP && lowest_id == 0))
+ if (!common_parent || (MOVING_DOWN && highest_id >= common_parent->get_child_count() - MOVING_DOWN) || (MOVING_UP && lowest_id == 0)) {
break; // one or more nodes can not be moved
+ }
- if (selection.size() == 1) editor_data->get_undo_redo().create_action(TTR("Move Node In Parent"));
- if (selection.size() > 1) editor_data->get_undo_redo().create_action(TTR("Move Nodes In Parent"));
+ if (selection.size() == 1) {
+ editor_data->get_undo_redo().create_action(TTR("Move Node In Parent"));
+ }
+ if (selection.size() > 1) {
+ editor_data->get_undo_redo().create_action(TTR("Move Nodes In Parent"));
+ }
for (int i = 0; i < selection.size(); i++) {
Node *top_node = selection[i];
@@ -522,28 +523,29 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_DUPLICATE: {
-
if (!profile_allow_editing) {
break;
}
- if (!edited_scene)
+ if (!edited_scene) {
break;
+ }
if (editor_selection->is_selected(edited_scene)) {
-
current_option = -1;
accept->set_text(TTR("This operation can't be done on the tree root."));
accept->popup_centered();
break;
}
- if (!_validate_no_foreign())
+ if (!_validate_no_foreign()) {
break;
+ }
List<Node *> selection = editor_selection->get_selected_node_list();
- if (selection.size() == 0)
+ if (selection.size() == 0) {
break;
+ }
editor_data->get_undo_redo().create_action(TTR("Duplicate Node(s)"));
editor_data->get_undo_redo().add_do_method(editor_selection, "clear");
@@ -553,11 +555,11 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
selection.sort_custom<Node::Comparator>();
- for (List<Node *>::Element *E = selection.back(); E; E = E->prev()) {
+ Node *add_below_node = selection.back()->get();
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
Node *node = E->get();
Node *parent = node->get_parent();
- Node *selection_tail = _get_selection_group_tail(node, selection);
List<Node *> owned;
node->get_owned_by(node->get_owner(), &owned);
@@ -565,25 +567,26 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Map<const Node *, Node *> duplimap;
Node *dup = node->duplicate_from_editor(duplimap);
- if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node))
+ if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node)) {
editable_children.push_back(dup);
+ }
ERR_CONTINUE(!dup);
- if (selection.size() == 1)
+ if (selection.size() == 1) {
dupsingle = dup;
+ }
dup->set_name(parent->validate_child_name(dup));
- editor_data->get_undo_redo().add_do_method(parent, "add_child_below_node", selection_tail, dup);
- for (List<Node *>::Element *F = owned.front(); F; F = F->next()) {
+ editor_data->get_undo_redo().add_do_method(add_below_node, "add_sibling", dup);
+ for (List<Node *>::Element *F = owned.front(); F; F = F->next()) {
if (!duplimap.has(F->get())) {
-
continue;
}
Node *d = duplimap[F->get()];
- editor_data->get_undo_redo().add_do_method(d, "set_owner", selection_tail->get_owner());
+ editor_data->get_undo_redo().add_do_method(d, "set_owner", node->get_owner());
}
editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", dup);
editor_data->get_undo_redo().add_undo_method(parent, "remove_child", dup);
@@ -593,41 +596,44 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
editor_data->get_undo_redo().add_do_method(ed, "live_debug_duplicate_node", edited_scene->get_path_to(node), dup->get_name());
editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(parent)).plus_file(dup->get_name())));
+
+ add_below_node = dup;
}
editor_data->get_undo_redo().commit_action();
- if (dupsingle)
+ if (dupsingle) {
editor->push_item(dupsingle);
+ }
- for (List<Node *>::Element *E = editable_children.front(); E; E = E->next())
+ for (List<Node *>::Element *E = editable_children.back(); E; E = E->prev()) {
_toggle_editable_children(E->get());
+ }
} break;
case TOOL_REPARENT: {
-
if (!profile_allow_editing) {
break;
}
- if (!scene_tree->get_selected())
+ if (!scene_tree->get_selected()) {
break;
+ }
if (editor_selection->is_selected(edited_scene)) {
-
current_option = -1;
accept->set_text(TTR("This operation can't be done on the tree root."));
accept->popup_centered();
break;
}
- if (!_validate_no_foreign())
+ if (!_validate_no_foreign()) {
break;
+ }
List<Node *> nodes = editor_selection->get_selected_node_list();
Set<Node *> nodeset;
for (List<Node *>::Element *E = nodes.front(); E; E = E->next()) {
-
nodeset.insert(E->get());
}
reparent_dialog->popup_centered_ratio();
@@ -635,7 +641,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_MAKE_ROOT: {
-
if (!profile_allow_editing) {
break;
}
@@ -646,8 +651,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
Node *node = nodes.front()->get();
Node *root = get_tree()->get_edited_scene_root();
- if (node == root)
+ if (node == root) {
return;
+ }
//check that from node to root, all owners are right
@@ -694,14 +700,14 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
editor_data->get_undo_redo().commit_action();
} break;
case TOOL_MULTI_EDIT: {
-
if (!profile_allow_editing) {
break;
}
Node *root = EditorNode::get_singleton()->get_edited_scene();
- if (!root)
+ if (!root) {
break;
+ }
Ref<MultiNodeEdit> mne = memnew(MultiNodeEdit);
for (const Map<Node *, Object *>::Element *E = EditorNode::get_singleton()->get_editor_selection()->get_selection().front(); E; E = E->next()) {
mne->add_node(root->get_path_to(E->key()));
@@ -712,18 +718,19 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_ERASE: {
-
if (!profile_allow_editing) {
break;
}
List<Node *> remove_list = editor_selection->get_selected_node_list();
- if (remove_list.empty())
+ if (remove_list.empty()) {
return;
+ }
- if (!_validate_no_foreign())
+ if (!_validate_no_foreign()) {
break;
+ }
if (p_confirm_override) {
_delete_confirm();
@@ -749,7 +756,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
case TOOL_MERGE_FROM_SCENE: {
-
if (!profile_allow_editing) {
break;
}
@@ -757,7 +763,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
EditorNode::get_singleton()->merge_from_scene();
} break;
case TOOL_NEW_SCENE_FROM: {
-
if (!profile_allow_editing) {
break;
}
@@ -813,7 +818,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
new_scene_from_dialog->set_title(TTR("Save New Scene As..."));
} break;
case TOOL_COPY_NODE_PATH: {
-
List<Node *> selection = editor_selection->get_selected_node_list();
List<Node *>::Element *e = selection.front();
if (e) {
@@ -833,7 +837,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
} break;
case TOOL_SCENE_EDITABLE_CHILDREN: {
-
if (!profile_allow_editing) {
break;
}
@@ -855,7 +858,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
} break;
case TOOL_SCENE_USE_PLACEHOLDER: {
-
if (!profile_allow_editing) {
break;
}
@@ -877,8 +879,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
placeholder = !placeholder;
- if (placeholder)
+ if (placeholder) {
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node, false);
+ }
node->set_scene_instance_load_placeholder(placeholder);
scene_tree->update_tree();
@@ -886,7 +889,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
} break;
case TOOL_SCENE_MAKE_LOCAL: {
-
if (!profile_allow_editing) {
break;
}
@@ -898,8 +900,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (node) {
Node *root = EditorNode::get_singleton()->get_edited_scene();
UndoRedo *undo_redo = &editor_data->get_undo_redo();
- if (!root)
+ if (!root) {
break;
+ }
ERR_FAIL_COND(node->get_filename() == String());
undo_redo->create_action(TTR("Make Local"));
@@ -913,7 +916,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
} break;
case TOOL_SCENE_OPEN: {
-
List<Node *> selection = editor_selection->get_selected_node_list();
List<Node *>::Element *e = selection.front();
if (e) {
@@ -947,7 +949,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
} break;
case TOOL_SCENE_OPEN_INHERITED: {
-
List<Node *> selection = editor_selection->get_selected_node_list();
List<Node *>::Element *e = selection.front();
if (e) {
@@ -961,7 +962,6 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
case TOOL_CREATE_3D_SCENE:
case TOOL_CREATE_USER_INTERFACE:
case TOOL_CREATE_FAVORITE: {
-
Node *new_node = nullptr;
if (TOOL_CREATE_FAVORITE == p_tool) {
@@ -983,8 +983,12 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
} else {
switch (p_tool) {
- case TOOL_CREATE_2D_SCENE: new_node = memnew(Node2D); break;
- case TOOL_CREATE_3D_SCENE: new_node = memnew(Node3D); break;
+ case TOOL_CREATE_2D_SCENE:
+ new_node = memnew(Node2D);
+ break;
+ case TOOL_CREATE_3D_SCENE:
+ new_node = memnew(Node3D);
+ break;
case TOOL_CREATE_USER_INTERFACE: {
Control *node = memnew(Control);
node->set_anchors_and_margins_preset(PRESET_WIDE); //more useful for resizable UIs.
@@ -1008,9 +1012,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
} break;
default: {
-
if (p_tool >= EDIT_SUBRESOURCE_BASE) {
-
int idx = p_tool - EDIT_SUBRESOURCE_BASE;
ERR_FAIL_INDEX(idx, subresources.size());
@@ -1025,23 +1027,22 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
void SceneTreeDock::_node_collapsed(Object *p_obj) {
-
TreeItem *ti = Object::cast_to<TreeItem>(p_obj);
- if (!ti)
+ if (!ti) {
return;
+ }
- if (InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
_set_collapsed_recursive(ti, ti->is_collapsed());
}
}
void SceneTreeDock::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_READY: {
-
- if (!first_enter)
+ if (!first_enter) {
break;
+ }
first_enter = false;
EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &SceneTreeDock::_feature_profile_changed));
@@ -1060,7 +1061,7 @@ void SceneTreeDock::_notification(int p_what) {
button_add->set_icon(get_theme_icon("Add", "EditorIcons"));
button_instance->set_icon(get_theme_icon("Instance", "EditorIcons"));
button_create_script->set_icon(get_theme_icon("ScriptCreate", "EditorIcons"));
- button_clear_script->set_icon(get_theme_icon("ScriptRemove", "EditorIcons"));
+ button_detach_script->set_icon(get_theme_icon("ScriptRemove", "EditorIcons"));
filter->set_right_icon(get_theme_icon("Search", "EditorIcons"));
filter->set_clear_button_enabled(true);
@@ -1137,13 +1138,12 @@ void SceneTreeDock::_notification(int p_what) {
button_add->set_icon(get_theme_icon("Add", "EditorIcons"));
button_instance->set_icon(get_theme_icon("Instance", "EditorIcons"));
button_create_script->set_icon(get_theme_icon("ScriptCreate", "EditorIcons"));
- button_clear_script->set_icon(get_theme_icon("ScriptRemove", "EditorIcons"));
+ button_detach_script->set_icon(get_theme_icon("ScriptRemove", "EditorIcons"));
filter->set_right_icon(get_theme_icon("Search", "EditorIcons"));
filter->set_clear_button_enabled(true);
} break;
case NOTIFICATION_PROCESS: {
-
bool show_create_root = bool(EDITOR_GET("interface/editors/show_scene_tree_root_selection")) && get_tree()->get_edited_scene_root() == nullptr;
if (show_create_root != create_root_dialog->is_visible_in_tree() && !remote_tree->is_visible()) {
@@ -1161,7 +1161,6 @@ void SceneTreeDock::_notification(int p_what) {
}
void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root, ReplaceOwnerMode p_mode) {
-
if (p_node->get_owner() == p_base && p_node != p_root) {
UndoRedo *undo_redo = &editor_data->get_undo_redo();
switch (p_mode) {
@@ -1187,21 +1186,17 @@ void SceneTreeDock::_node_replace_owner(Node *p_base, Node *p_node, Node *p_root
}
void SceneTreeDock::_load_request(const String &p_path) {
-
editor->open_request(p_path);
}
void SceneTreeDock::_script_open_request(const Ref<Script> &p_script) {
-
editor->edit_resource(p_script);
}
void SceneTreeDock::_node_selected() {
-
Node *node = scene_tree->get_selected();
if (!node) {
-
editor->push_item(nullptr);
return;
}
@@ -1214,31 +1209,30 @@ void SceneTreeDock::_node_selected() {
}
void SceneTreeDock::_node_renamed() {
-
_node_selected();
}
void SceneTreeDock::_set_owners(Node *p_owner, const Array &p_nodes) {
-
for (int i = 0; i < p_nodes.size(); i++) {
-
Node *n = Object::cast_to<Node>(p_nodes[i]);
- if (!n)
+ if (!n) {
continue;
+ }
n->set_owner(p_owner);
}
}
void SceneTreeDock::_fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, List<Pair<NodePath, NodePath>> *p_renames) {
-
base_path.push_back(p_node->get_name());
- if (new_base_path.size())
+ if (new_base_path.size()) {
new_base_path.push_back(p_node->get_name());
+ }
NodePath from(base_path, true);
NodePath to;
- if (new_base_path.size())
+ if (new_base_path.size()) {
to = NodePath(new_base_path, true);
+ }
Pair<NodePath, NodePath> npp;
npp.first = from;
@@ -1247,15 +1241,14 @@ void SceneTreeDock::_fill_path_renames(Vector<StringName> base_path, Vector<Stri
p_renames->push_back(npp);
for (int i = 0; i < p_node->get_child_count(); i++) {
-
_fill_path_renames(base_path, new_base_path, p_node->get_child(i), p_renames);
}
}
void SceneTreeDock::fill_path_renames(Node *p_node, Node *p_new_parent, List<Pair<NodePath, NodePath>> *p_renames) {
-
- if (!bool(EDITOR_DEF("editors/animation/autorename_animation_tracks", true)))
+ if (!bool(EDITOR_DEF("editors/animation/autorename_animation_tracks", true))) {
return;
+ }
Vector<StringName> base_path;
Node *n = p_node->get_parent();
@@ -1280,39 +1273,34 @@ void SceneTreeDock::fill_path_renames(Node *p_node, Node *p_new_parent, List<Pai
}
void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodePath>> *p_renames, Map<Ref<Animation>, Set<int>> *r_rem_anims) {
-
Map<Ref<Animation>, Set<int>> rem_anims;
- if (!r_rem_anims)
+ if (!r_rem_anims) {
r_rem_anims = &rem_anims;
+ }
if (!p_base) {
-
p_base = edited_scene;
}
- if (!p_base)
+ if (!p_base) {
return;
+ }
// Renaming node paths used in script instances
if (p_base->get_script_instance()) {
-
ScriptInstance *si = p_base->get_script_instance();
if (si) {
-
List<PropertyInfo> properties;
si->get_property_list(&properties);
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
-
String propertyname = E->get().name;
Variant p = p_base->get(propertyname);
if (p.get_type() == Variant::NODE_PATH) {
-
// Goes through all paths to check if its matching
for (List<Pair<NodePath, NodePath>>::Element *F = p_renames->front(); F; F = F->next()) {
-
NodePath root_path = p_base->get_path();
NodePath rel_path_old = root_path.rel_path_to(F->get().first);
@@ -1326,7 +1314,6 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP
// if old path detected, then it needs to be replaced with the new one
if (p == rel_path_old) {
-
editor_data->get_undo_redo().add_do_property(p_base, propertyname, rel_path_new);
editor_data->get_undo_redo().add_undo_property(p_base, propertyname, rel_path_old);
@@ -1342,19 +1329,16 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP
bool autorename_animation_tracks = bool(EDITOR_DEF("editors/animation/autorename_animation_tracks", true));
if (autorename_animation_tracks && Object::cast_to<AnimationPlayer>(p_base)) {
-
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_base);
List<StringName> anims;
ap->get_animation_list(&anims);
Node *root = ap->get_node(ap->get_root());
if (root) {
-
NodePath root_path = root->get_path();
NodePath new_root_path = root_path;
for (List<Pair<NodePath, NodePath>>::Element *E = p_renames->front(); E; E = E->next()) {
-
if (E->get().first == root_path) {
new_root_path = E->get().second;
break;
@@ -1365,22 +1349,22 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP
//will not be erased
for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
-
Ref<Animation> anim = ap->get_animation(E->get());
if (!r_rem_anims->has(anim)) {
r_rem_anims->insert(anim, Set<int>());
Set<int> &ran = r_rem_anims->find(anim)->get();
- for (int i = 0; i < anim->get_track_count(); i++)
+ for (int i = 0; i < anim->get_track_count(); i++) {
ran.insert(i);
+ }
}
Set<int> &ran = r_rem_anims->find(anim)->get();
- if (anim.is_null())
+ if (anim.is_null()) {
continue;
+ }
for (int i = 0; i < anim->get_track_count(); i++) {
-
NodePath track_np = anim->track_get_path(i);
Node *n = root->get_node(track_np);
if (!n) {
@@ -1389,13 +1373,12 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP
NodePath old_np = n->get_path();
- if (!ran.has(i))
+ if (!ran.has(i)) {
continue; //channel was removed
+ }
for (List<Pair<NodePath, NodePath>>::Element *F = p_renames->front(); F; F = F->next()) {
-
if (F->get().first == old_np) {
-
if (F->get().second == NodePath()) {
//will be erased
@@ -1413,7 +1396,6 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP
editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_path", idx, track_np);
editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_interpolation_type", idx, anim->track_get_interpolation_type(i));
for (int j = 0; j < anim->track_get_key_count(i); j++) {
-
editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_insert_key", idx, anim->track_get_key_time(i, j), anim->track_get_key_value(i, j), anim->track_get_key_transition(i, j));
}
@@ -1424,8 +1406,9 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP
NodePath rel_path = new_root_path.rel_path_to(F->get().second);
NodePath new_path = NodePath(rel_path.get_names(), track_np.get_subnames(), false);
- if (new_path == track_np)
+ if (new_path == track_np) {
continue; //bleh
+ }
editor_data->get_undo_redo().add_do_method(anim.ptr(), "track_set_path", i, new_path);
editor_data->get_undo_redo().add_undo_method(anim.ptr(), "track_set_path", i, track_np);
}
@@ -1437,12 +1420,12 @@ void SceneTreeDock::perform_node_renames(Node *p_base, List<Pair<NodePath, NodeP
}
}
- for (int i = 0; i < p_base->get_child_count(); i++)
+ for (int i = 0; i < p_base->get_child_count(); i++) {
perform_node_renames(p_base->get_child(i), p_renames, r_rem_anims);
+ }
}
void SceneTreeDock::_node_prerenamed(Node *p_node, const String &p_new_name) {
-
List<Pair<NodePath, NodePath>> path_renames;
Vector<StringName> base_path;
@@ -1463,20 +1446,18 @@ void SceneTreeDock::_node_prerenamed(Node *p_node, const String &p_new_name) {
npp.second = NodePath(new_base_path, true);
path_renames.push_back(npp);
- for (int i = 0; i < p_node->get_child_count(); i++)
+ for (int i = 0; i < p_node->get_child_count(); i++) {
_fill_path_renames(base_path, new_base_path, p_node->get_child(i), &path_renames);
+ }
perform_node_renames(nullptr, &path_renames);
}
bool SceneTreeDock::_validate_no_foreign() {
-
List<Node *> selection = editor_selection->get_selected_node_list();
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
if (E->get() != edited_scene && E->get()->get_owner() != edited_scene) {
-
accept->set_text(TTR("Can't operate on nodes from a foreign scene!"));
accept->popup_centered();
return false;
@@ -1490,7 +1471,6 @@ bool SceneTreeDock::_validate_no_foreign() {
}
if (edited_scene->get_scene_inherited_state().is_valid() && edited_scene->get_scene_inherited_state()->find_node_by_path(edited_scene->get_path_to(E->get())) >= 0) {
-
accept->set_text(TTR("Can't operate on nodes the current scene inherits from!"));
accept->popup_centered();
return false;
@@ -1501,14 +1481,14 @@ bool SceneTreeDock::_validate_no_foreign() {
}
void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) {
-
Node *new_parent = scene_root->get_node(p_path);
ERR_FAIL_COND(!new_parent);
List<Node *> selection = editor_selection->get_selected_node_list();
- if (selection.empty())
+ if (selection.empty()) {
return; // Nothing to reparent.
+ }
Vector<Node *> nodes;
@@ -1520,31 +1500,32 @@ void SceneTreeDock::_node_reparent(NodePath p_path, bool p_keep_global_xform) {
}
void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, Vector<Node *> p_nodes, bool p_keep_global_xform) {
-
Node *new_parent = p_new_parent;
ERR_FAIL_COND(!new_parent);
- if (p_nodes.size() == 0)
+ if (p_nodes.size() == 0) {
return; // Nothing to reparent.
+ }
p_nodes.sort_custom<Node::Comparator>(); //Makes result reliable.
bool no_change = true;
for (int ni = 0; ni < p_nodes.size(); ni++) {
-
- if (p_nodes[ni] == p_new_parent)
+ if (p_nodes[ni] == p_new_parent) {
return; // Attempt to reparent to itself.
+ }
- if (p_nodes[ni]->get_parent() != p_new_parent || p_position_in_parent + ni != p_nodes[ni]->get_index())
+ if (p_nodes[ni]->get_parent() != p_new_parent || p_position_in_parent + ni != p_nodes[ni]->get_index()) {
no_change = false;
+ }
}
- if (no_change)
+ if (no_change) {
return; // Position and parent didn't change.
+ }
Node *validate = new_parent;
while (validate) {
-
ERR_FAIL_COND_MSG(p_nodes.find(validate) != -1, "Selection changed at some point. Can't reparent.");
validate = validate->get_parent();
}
@@ -1560,7 +1541,6 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
int inc = 0;
for (int ni = 0; ni < p_nodes.size(); ni++) {
-
// No undo implemented for this yet.
Node *node = p_nodes[ni];
@@ -1574,14 +1554,16 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
owners.push_back(E->get());
}
- if (new_parent == node->get_parent() && node->get_index() < p_position_in_parent + ni)
+ if (new_parent == node->get_parent() && node->get_index() < p_position_in_parent + ni) {
inc--; // If the child will generate a gap when moved, adjust.
+ }
editor_data->get_undo_redo().add_do_method(node->get_parent(), "remove_child", node);
editor_data->get_undo_redo().add_do_method(new_parent, "add_child", node);
- if (p_position_in_parent >= 0)
+ if (p_position_in_parent >= 0) {
editor_data->get_undo_redo().add_do_method(new_parent, "move_child", node, p_position_in_parent + inc);
+ }
EditorDebuggerNode *ed = EditorDebuggerNode::get_singleton();
String old_name = former_names[ni];
@@ -1589,7 +1571,6 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
// Name was modified, fix the path renames.
if (old_name.casecmp_to(new_name) != 0) {
-
// Fix the to name to have the new name.
NodePath old_new_name = path_renames[ni].second;
NodePath new_path;
@@ -1612,18 +1593,22 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
editor_data->get_undo_redo().add_undo_method(ed, "live_debug_reparent_node", NodePath(String(edited_scene->get_path_to(new_parent)).plus_file(new_name)), edited_scene->get_path_to(node->get_parent()), node->get_name(), node->get_index());
if (p_keep_global_xform) {
- if (Object::cast_to<Node2D>(node))
+ if (Object::cast_to<Node2D>(node)) {
editor_data->get_undo_redo().add_do_method(node, "set_global_transform", Object::cast_to<Node2D>(node)->get_global_transform());
- if (Object::cast_to<Node3D>(node))
+ }
+ if (Object::cast_to<Node3D>(node)) {
editor_data->get_undo_redo().add_do_method(node, "set_global_transform", Object::cast_to<Node3D>(node)->get_global_transform());
- if (Object::cast_to<Control>(node))
+ }
+ if (Object::cast_to<Control>(node)) {
editor_data->get_undo_redo().add_do_method(node, "set_global_position", Object::cast_to<Control>(node)->get_global_position());
+ }
}
editor_data->get_undo_redo().add_do_method(this, "_set_owners", edited_scene, owners);
- if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == node)
+ if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == node) {
editor_data->get_undo_redo().add_do_method(AnimationPlayerEditor::singleton->get_track_editor(), "set_root", node);
+ }
editor_data->get_undo_redo().add_undo_method(new_parent, "remove_child", node);
editor_data->get_undo_redo().add_undo_method(node, "set_name", former_names[ni]);
@@ -1633,14 +1618,12 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
// Add and move in a second step (so old order is preserved).
for (int ni = 0; ni < p_nodes.size(); ni++) {
-
Node *node = p_nodes[ni];
List<Node *> owned;
node->get_owned_by(node->get_owner(), &owned);
Array owners;
for (List<Node *>::Element *E = owned.front(); E; E = E->next()) {
-
owners.push_back(E->get());
}
@@ -1649,16 +1632,20 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
editor_data->get_undo_redo().add_undo_method(node->get_parent(), "add_child", node);
editor_data->get_undo_redo().add_undo_method(node->get_parent(), "move_child", node, child_pos);
editor_data->get_undo_redo().add_undo_method(this, "_set_owners", edited_scene, owners);
- if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == node)
+ if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == node) {
editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::singleton->get_track_editor(), "set_root", node);
+ }
if (p_keep_global_xform) {
- if (Object::cast_to<Node2D>(node))
+ if (Object::cast_to<Node2D>(node)) {
editor_data->get_undo_redo().add_undo_method(node, "set_transform", Object::cast_to<Node2D>(node)->get_transform());
- if (Object::cast_to<Node3D>(node))
+ }
+ if (Object::cast_to<Node3D>(node)) {
editor_data->get_undo_redo().add_undo_method(node, "set_transform", Object::cast_to<Node3D>(node)->get_transform());
- if (Object::cast_to<Control>(node))
+ }
+ if (Object::cast_to<Control>(node)) {
editor_data->get_undo_redo().add_undo_method(node, "set_position", Object::cast_to<Control>(node)->get_position());
+ }
}
}
@@ -1668,14 +1655,12 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V
}
bool SceneTreeDock::_is_collapsed_recursive(TreeItem *p_item) const {
-
bool is_branch_collapsed = false;
List<TreeItem *> needs_check;
needs_check.push_back(p_item);
while (!needs_check.empty()) {
-
TreeItem *item = needs_check.back()->get();
needs_check.pop_back();
@@ -1694,12 +1679,10 @@ bool SceneTreeDock::_is_collapsed_recursive(TreeItem *p_item) const {
}
void SceneTreeDock::_set_collapsed_recursive(TreeItem *p_item, bool p_collapsed) {
-
List<TreeItem *> to_collapse;
to_collapse.push_back(p_item);
while (!to_collapse.empty()) {
-
TreeItem *item = to_collapse.back()->get();
to_collapse.pop_back();
@@ -1714,15 +1697,14 @@ void SceneTreeDock::_set_collapsed_recursive(TreeItem *p_item, bool p_collapsed)
}
void SceneTreeDock::_script_created(Ref<Script> p_script) {
-
List<Node *> selected = editor_selection->get_selected_node_list();
- if (selected.empty())
+ if (selected.empty()) {
return;
+ }
editor_data->get_undo_redo().create_action(TTR("Attach Script"));
for (List<Node *>::Element *E = selected.front(); E; E = E->next()) {
-
Ref<Script> existing = E->get()->get_script();
editor_data->get_undo_redo().add_do_method(E->get(), "set_script", p_script);
editor_data->get_undo_redo().add_undo_method(E->get(), "set_script", existing);
@@ -1741,7 +1723,6 @@ void SceneTreeDock::_script_creation_closed() {
}
void SceneTreeDock::_toggle_editable_children_from_selection() {
-
List<Node *> selection = editor_selection->get_selected_node_list();
List<Node *>::Element *e = selection.front();
@@ -1751,7 +1732,6 @@ void SceneTreeDock::_toggle_editable_children_from_selection() {
}
void SceneTreeDock::_toggle_placeholder_from_selection() {
-
List<Node *> selection = editor_selection->get_selected_node_list();
List<Node *>::Element *e = selection.front();
@@ -1770,12 +1750,12 @@ void SceneTreeDock::_toggle_placeholder_from_selection() {
}
void SceneTreeDock::_toggle_editable_children(Node *p_node) {
-
if (p_node) {
bool editable = !EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node);
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(p_node, editable);
- if (editable)
+ if (editable) {
p_node->set_scene_instance_load_placeholder(false);
+ }
Node3DEditor::get_singleton()->update_all_gizmos(p_node);
@@ -1784,11 +1764,11 @@ void SceneTreeDock::_toggle_editable_children(Node *p_node) {
}
void SceneTreeDock::_delete_confirm() {
-
List<Node *> remove_list = editor_selection->get_selected_node_list();
- if (remove_list.empty())
+ if (remove_list.empty()) {
return;
+ }
editor->get_editor_plugins_over()->make_visible(false);
@@ -1797,14 +1777,12 @@ void SceneTreeDock::_delete_confirm() {
bool entire_scene = false;
for (List<Node *>::Element *E = remove_list.front(); E; E = E->next()) {
-
if (E->get() == edited_scene) {
entire_scene = true;
}
}
if (entire_scene) {
-
editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", (Object *)nullptr);
editor_data->get_undo_redo().add_undo_method(editor, "set_edited_scene", edited_scene);
editor_data->get_undo_redo().add_undo_method(edited_scene, "set_owner", edited_scene->get_owner());
@@ -1812,15 +1790,15 @@ void SceneTreeDock::_delete_confirm() {
editor_data->get_undo_redo().add_undo_reference(edited_scene);
} else {
-
remove_list.sort_custom<Node::Comparator>(); //sort nodes to keep positions
List<Pair<NodePath, NodePath>> path_renames;
//delete from animation
for (List<Node *>::Element *E = remove_list.front(); E; E = E->next()) {
Node *n = E->get();
- if (!n->is_inside_tree() || !n->get_parent())
+ if (!n->is_inside_tree() || !n->get_parent()) {
continue;
+ }
fill_path_renames(n, nullptr, &path_renames);
}
@@ -1829,22 +1807,23 @@ void SceneTreeDock::_delete_confirm() {
//delete for read
for (List<Node *>::Element *E = remove_list.front(); E; E = E->next()) {
Node *n = E->get();
- if (!n->is_inside_tree() || !n->get_parent())
+ if (!n->is_inside_tree() || !n->get_parent()) {
continue;
+ }
List<Node *> owned;
n->get_owned_by(n->get_owner(), &owned);
Array owners;
for (List<Node *>::Element *F = owned.front(); F; F = F->next()) {
-
owners.push_back(F->get());
}
editor_data->get_undo_redo().add_do_method(n->get_parent(), "remove_child", n);
editor_data->get_undo_redo().add_undo_method(n->get_parent(), "add_child", n);
editor_data->get_undo_redo().add_undo_method(n->get_parent(), "move_child", n, n->get_index());
- if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == n)
+ if (AnimationPlayerEditor::singleton->get_track_editor()->get_root() == n) {
editor_data->get_undo_redo().add_undo_method(AnimationPlayerEditor::singleton->get_track_editor(), "set_root", n);
+ }
editor_data->get_undo_redo().add_undo_method(this, "_set_owners", edited_scene, owners);
editor_data->get_undo_redo().add_undo_reference(n);
@@ -1856,8 +1835,9 @@ void SceneTreeDock::_delete_confirm() {
editor_data->get_undo_redo().commit_action();
// hack, force 2d editor viewport to refresh after deletion
- if (CanvasItemEditor *editor = CanvasItemEditor::get_singleton())
+ if (CanvasItemEditor *editor = CanvasItemEditor::get_singleton()) {
editor->get_viewport_control()->update();
+ }
editor->push_item(nullptr);
@@ -1868,22 +1848,20 @@ void SceneTreeDock::_delete_confirm() {
}
void SceneTreeDock::_update_script_button() {
-
if (!profile_allow_script_editing) {
-
button_create_script->hide();
- button_clear_script->hide();
+ button_detach_script->hide();
} else if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size() == 0) {
button_create_script->hide();
- button_clear_script->hide();
+ button_detach_script->hide();
} else if (EditorNode::get_singleton()->get_editor_selection()->get_selection().size() == 1) {
Node *n = EditorNode::get_singleton()->get_editor_selection()->get_selected_node_list()[0];
if (n->get_script().is_null()) {
button_create_script->show();
- button_clear_script->hide();
+ button_detach_script->hide();
} else {
button_create_script->hide();
- button_clear_script->show();
+ button_detach_script->show();
}
} else {
button_create_script->hide();
@@ -1891,16 +1869,15 @@ void SceneTreeDock::_update_script_button() {
for (int i = 0; i < selection.size(); i++) {
Node *n = Object::cast_to<Node>(selection[i]);
if (!n->get_script().is_null()) {
- button_clear_script->show();
+ button_detach_script->show();
return;
}
}
- button_clear_script->hide();
+ button_detach_script->hide();
}
}
void SceneTreeDock::_selection_changed() {
-
int selection_size = EditorNode::get_singleton()->get_editor_selection()->get_selection().size();
if (selection_size > 1) {
//automatically turn on multi-edit
@@ -1914,17 +1891,17 @@ void SceneTreeDock::_selection_changed() {
}
Node *SceneTreeDock::_get_selection_group_tail(Node *p_node, List<Node *> p_list) {
-
Node *tail = p_node;
Node *parent = tail->get_parent();
for (int i = p_node->get_index(); i < parent->get_child_count(); i++) {
Node *sibling = parent->get_child(i);
- if (p_list.find(sibling))
+ if (p_list.find(sibling)) {
tail = sibling;
- else
+ } else {
break;
+ }
}
return tail;
@@ -1940,7 +1917,6 @@ void SceneTreeDock::_do_create(Node *p_parent) {
editor_data->get_undo_redo().create_action(TTR("Create Node"));
if (edited_scene) {
-
editor_data->get_undo_redo().add_do_method(p_parent, "add_child", child);
editor_data->get_undo_redo().add_do_method(child, "set_owner", edited_scene);
editor_data->get_undo_redo().add_do_method(editor_selection, "clear");
@@ -1954,7 +1930,6 @@ void SceneTreeDock::_do_create(Node *p_parent) {
editor_data->get_undo_redo().add_undo_method(ed, "live_debug_remove_node", NodePath(String(edited_scene->get_path_to(p_parent)).plus_file(new_name)));
} else {
-
editor_data->get_undo_redo().add_do_method(editor, "set_edited_scene", child);
editor_data->get_undo_redo().add_do_method(scene_tree, "update_tree");
editor_data->get_undo_redo().add_do_reference(child);
@@ -1970,25 +1945,26 @@ void SceneTreeDock::_do_create(Node *p_parent) {
Control *ct = Object::cast_to<Control>(c);
Size2 ms = ct->get_minimum_size();
- if (ms.width < 4)
+ if (ms.width < 4) {
ms.width = 40;
- if (ms.height < 4)
+ }
+ if (ms.height < 4) {
ms.height = 40;
+ }
ct->set_size(ms);
}
}
void SceneTreeDock::_create() {
-
if (current_option == TOOL_NEW) {
-
Node *parent = nullptr;
if (edited_scene) {
// If root exists in edited scene
parent = scene_tree->get_selected();
- if (!parent)
+ if (!parent) {
parent = edited_scene;
+ }
} else {
// If no root exist in edited scene
@@ -2046,17 +2022,19 @@ void SceneTreeDock::_create() {
smaller_path_to_top = path_length;
only_one_top_node = true;
} else if (smaller_path_to_top == path_length) {
- if (only_one_top_node && top_node->get_parent() != n->get_parent())
+ if (only_one_top_node && top_node->get_parent() != n->get_parent()) {
only_one_top_node = false;
+ }
}
}
}
Node *parent = nullptr;
- if (only_one_top_node)
+ if (only_one_top_node) {
parent = top_node->get_parent();
- else
+ } else {
parent = top_node->get_parent()->get_parent();
+ }
_do_create(parent);
@@ -2074,7 +2052,6 @@ void SceneTreeDock::_create() {
}
void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_properties, bool p_remove_old) {
-
Node *n = p_node;
Node *newnode = p_by_node;
@@ -2084,10 +2061,24 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop
n->get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
- if (E->get().name == "__meta__")
+ }
+
+ if (E->get().name == "__meta__") {
+ if (Object::cast_to<CanvasItem>(newnode)) {
+ Dictionary metadata = n->get(E->get().name);
+ if (metadata.has("_edit_group_") && metadata["_edit_group_"]) {
+ newnode->set_meta("_edit_group_", true);
+ }
+ if (metadata.has("_edit_lock_") && metadata["_edit_lock_"]) {
+ newnode->set_meta("_edit_lock_", true);
+ }
+ }
+
continue;
+ }
+
if (default_oldnode->get(E->get().name) != n->get(E->get().name)) {
newnode->set(E->get().name, n->get(E->get().name));
}
@@ -2103,15 +2094,14 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop
n->get_signal_list(&sl);
for (List<MethodInfo>::Element *E = sl.front(); E; E = E->next()) {
-
List<Object::Connection> cl;
n->get_signal_connection_list(E->get().name, &cl);
for (List<Object::Connection>::Element *F = cl.front(); F; F = F->next()) {
-
Object::Connection &c = F->get();
- if (!(c.flags & Object::CONNECT_PERSIST))
+ if (!(c.flags & Object::CONNECT_PERSIST)) {
continue;
+ }
newnode->connect(c.signal.get_name(), c.callable, c.binds, Object::CONNECT_PERSIST);
}
}
@@ -2138,8 +2128,9 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop
c->call("set_transform", c->call("get_transform"));
}
//p_remove_old was added to support undo
- if (p_remove_old)
+ if (p_remove_old) {
editor_data->get_undo_redo().clear_history();
+ }
newnode->set_name(newname);
editor->push_item(newnode);
@@ -2155,22 +2146,18 @@ void SceneTreeDock::replace_node(Node *p_node, Node *p_by_node, bool p_keep_prop
}
void SceneTreeDock::set_edited_scene(Node *p_scene) {
-
edited_scene = p_scene;
}
void SceneTreeDock::set_selected(Node *p_node, bool p_emit_selected) {
-
scene_tree->set_selected(p_node, p_emit_selected);
}
void SceneTreeDock::import_subscene() {
-
import_subscene_dialog->popup_centered_clamped(Size2(500, 800) * EDSCALE, 0.8);
}
void SceneTreeDock::_import_subscene() {
-
Node *parent = scene_tree->get_selected();
if (!parent) {
parent = editor_data->get_edited_scene_root();
@@ -2182,7 +2169,6 @@ void SceneTreeDock::_import_subscene() {
}
void SceneTreeDock::_new_scene_from(String p_file) {
-
List<Node *> selection = editor_selection->get_selected_node_list();
if (selection.size() != 1) {
@@ -2203,7 +2189,6 @@ void SceneTreeDock::_new_scene_from(String p_file) {
reown[editor_data->get_edited_scene_root()] = base;
Node *copy = base->duplicate_and_reown(reown);
if (copy) {
-
Ref<PackedScene> sdata = memnew(PackedScene);
Error err = sdata->pack(copy);
memdelete(copy);
@@ -2215,8 +2200,9 @@ void SceneTreeDock::_new_scene_from(String p_file) {
}
int flg = 0;
- if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources"))
+ if (EditorSettings::get_singleton()->get("filesystem/on_save/compress_binary_resources")) {
flg |= ResourceSaver::FLAG_COMPRESS;
+ }
err = ResourceSaver::save(p_file, sdata, flg);
if (err != OK) {
@@ -2233,26 +2219,27 @@ void SceneTreeDock::_new_scene_from(String p_file) {
}
static bool _is_node_visible(Node *p_node) {
-
- if (!p_node->get_owner())
+ if (!p_node->get_owner()) {
return false;
- if (p_node->get_owner() != EditorNode::get_singleton()->get_edited_scene() && !EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node->get_owner()))
+ }
+ if (p_node->get_owner() != EditorNode::get_singleton()->get_edited_scene() && !EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(p_node->get_owner())) {
return false;
+ }
return true;
}
static bool _has_visible_children(Node *p_node) {
-
bool collapsed = p_node->is_displayed_folded();
- if (collapsed)
+ if (collapsed) {
return false;
+ }
for (int i = 0; i < p_node->get_child_count(); i++) {
-
Node *child = p_node->get_child(i);
- if (!_is_node_visible(child))
+ if (!_is_node_visible(child)) {
continue;
+ }
return true;
}
@@ -2261,7 +2248,6 @@ static bool _has_visible_children(Node *p_node) {
}
void SceneTreeDock::_normalize_drop(Node *&to_node, int &to_pos, int p_type) {
-
to_pos = -1;
if (p_type == -1) {
@@ -2304,7 +2290,6 @@ void SceneTreeDock::_normalize_drop(Node *&to_node, int &to_pos, int p_type) {
}
void SceneTreeDock::_files_dropped(Vector<String> p_files, NodePath p_to, int p_type) {
-
Node *node = get_node(p_to);
ERR_FAIL_COND(!node);
@@ -2328,15 +2313,16 @@ void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) {
}
void SceneTreeDock::_nodes_dragged(Array p_nodes, NodePath p_to, int p_type) {
-
List<Node *> selection = editor_selection->get_selected_node_list();
- if (selection.empty())
+ if (selection.empty()) {
return; //nothing to reparent
+ }
Node *to_node = get_node(p_to);
- if (!to_node)
+ if (!to_node) {
return;
+ }
Vector<Node *> nodes;
for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
@@ -2346,29 +2332,32 @@ void SceneTreeDock::_nodes_dragged(Array p_nodes, NodePath p_to, int p_type) {
int to_pos = -1;
_normalize_drop(to_node, to_pos, p_type);
- _do_reparent(to_node, to_pos, nodes, !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT));
+ _do_reparent(to_node, to_pos, nodes, !Input::get_singleton()->is_key_pressed(KEY_SHIFT));
}
void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) {
-
- if (p_depth > 8)
+ if (p_depth > 8) {
return;
+ }
List<PropertyInfo> pinfo;
p_obj->get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_EDITOR))
+ if (!(E->get().usage & PROPERTY_USAGE_EDITOR)) {
continue;
- if (E->get().hint != PROPERTY_HINT_RESOURCE_TYPE)
+ }
+ if (E->get().hint != PROPERTY_HINT_RESOURCE_TYPE) {
continue;
+ }
Variant value = p_obj->get(E->get().name);
- if (value.get_type() != Variant::OBJECT)
+ if (value.get_type() != Variant::OBJECT) {
continue;
+ }
Object *obj = value;
- if (!obj)
+ if (!obj) {
continue;
+ }
Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(obj);
@@ -2385,9 +2374,7 @@ void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) {
}
void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
-
if (!EditorNode::get_singleton()->get_edited_scene()) {
-
menu->clear();
if (profile_allow_editing) {
menu->add_icon_shortcut(get_theme_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
@@ -2403,15 +2390,15 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
List<Node *> selection = editor_selection->get_selected_node_list();
List<Node *> full_selection = editor_selection->get_full_selected_node_list(); // Above method only returns nodes with common parent.
- if (selection.size() == 0)
+ if (selection.size() == 0) {
return;
+ }
menu->clear();
Ref<Script> existing_script;
bool existing_script_removable = true;
if (selection.size() == 1) {
-
Node *selected = selection[0];
if (profile_allow_editing) {
@@ -2419,8 +2406,9 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu_subresources->clear();
menu_subresources->set_size(Size2(1, 1));
_add_children_to_popup(selection.front()->get(), 0);
- if (menu->get_item_count() > 0)
+ if (menu->get_item_count() > 0) {
menu->add_separator();
+ }
menu->add_icon_shortcut(get_theme_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
menu->add_icon_shortcut(get_theme_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE);
@@ -2447,7 +2435,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
}
if (existing_script.is_valid() && existing_script_removable) {
add_separator = true;
- menu->add_icon_shortcut(get_theme_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
+ menu->add_icon_shortcut(get_theme_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/detach_script"), TOOL_DETACH_SCRIPT);
} else if (full_selection.size() > 1) {
bool script_exists = false;
for (List<Node *>::Element *E = full_selection.front(); E; E = E->next()) {
@@ -2459,7 +2447,7 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (script_exists) {
add_separator = true;
- menu->add_icon_shortcut(get_theme_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/clear_script"), TOOL_CLEAR_SCRIPT);
+ menu->add_icon_shortcut(get_theme_icon("ScriptRemove", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/detach_script"), TOOL_DETACH_SCRIPT);
}
}
@@ -2487,7 +2475,6 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
}
}
if (selection.size() == 1) {
-
if (profile_allow_editing) {
menu->add_separator();
menu->add_icon_shortcut(get_theme_icon("Blend", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/merge_from_scene"), TOOL_MERGE_FROM_SCENE);
@@ -2544,23 +2531,19 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
}
void SceneTreeDock::_filter_changed(const String &p_filter) {
-
scene_tree->set_filter(p_filter);
}
String SceneTreeDock::get_filter() {
-
return filter->get_text();
}
void SceneTreeDock::set_filter(const String &p_filter) {
-
filter->set_text(p_filter);
scene_tree->set_filter(p_filter);
}
void SceneTreeDock::_focus_node() {
-
Node *node = scene_tree->get_selected();
ERR_FAIL_COND(!node);
@@ -2579,12 +2562,14 @@ void SceneTreeDock::attach_script_to_selected(bool p_extend) {
}
List<Node *> selection = editor_selection->get_selected_node_list();
- if (selection.empty())
+ if (selection.empty()) {
return;
+ }
Node *selected = scene_tree->get_selected();
- if (!selected)
+ if (!selected) {
selected = selection.front()->get();
+ }
Ref<Script> existing = selected->get_script();
@@ -2623,7 +2608,6 @@ void SceneTreeDock::attach_script_to_selected(bool p_extend) {
}
void SceneTreeDock::open_script_dialog(Node *p_for_node, bool p_extend) {
-
scene_tree->set_selected(p_for_node, false);
if (p_extend) {
@@ -2641,31 +2625,27 @@ void SceneTreeDock::add_remote_tree_editor(Control *p_remote) {
}
void SceneTreeDock::show_remote_tree() {
-
_remote_tree_selected();
}
void SceneTreeDock::hide_remote_tree() {
-
_local_tree_selected();
}
void SceneTreeDock::show_tab_buttons() {
-
button_hb->show();
}
void SceneTreeDock::hide_tab_buttons() {
-
button_hb->hide();
}
void SceneTreeDock::_remote_tree_selected() {
-
scene_tree->hide();
create_root_dialog->hide();
- if (remote_tree)
+ if (remote_tree) {
remote_tree->show();
+ }
edit_remote->set_pressed(true);
edit_local->set_pressed(false);
@@ -2673,32 +2653,32 @@ void SceneTreeDock::_remote_tree_selected() {
}
void SceneTreeDock::_local_tree_selected() {
-
scene_tree->show();
- if (remote_tree)
+ if (remote_tree) {
remote_tree->hide();
+ }
edit_remote->set_pressed(false);
edit_local->set_pressed(true);
}
void SceneTreeDock::_update_create_root_dialog() {
-
BaseButton *toggle = Object::cast_to<BaseButton>(create_root_dialog->get_node(String("NodeShortcutsTopRow/NodeShortcutsToggle")));
Node *node_shortcuts = create_root_dialog->get_node(String("NodeShortcuts"));
- if (!toggle || !node_shortcuts)
+ if (!toggle || !node_shortcuts) {
return;
+ }
Control *beginner_nodes = Object::cast_to<Control>(node_shortcuts->get_node(String("BeginnerNodeShortcuts")));
Control *favorite_nodes = Object::cast_to<Control>(node_shortcuts->get_node(String("FavoriteNodeShortcuts")));
- if (!beginner_nodes || !favorite_nodes)
+ if (!beginner_nodes || !favorite_nodes) {
return;
+ }
EditorSettings::get_singleton()->set_setting("_use_favorites_root_selection", toggle->is_pressed());
EditorSettings::get_singleton()->save();
if (toggle->is_pressed()) {
-
for (int i = 0; i < favorite_nodes->get_child_count(); i++) {
favorite_nodes->get_child(i)->queue_delete();
}
@@ -2706,7 +2686,6 @@ void SceneTreeDock::_update_create_root_dialog() {
FileAccess *f = FileAccess::open(EditorSettings::get_singleton()->get_project_settings_dir().plus_file("favorites.Node"), FileAccess::READ);
if (f) {
-
while (!f->eof_reached()) {
String l = f->get_line().strip_edges();
@@ -2715,8 +2694,9 @@ void SceneTreeDock::_update_create_root_dialog() {
favorite_nodes->add_child(button);
button->set_text(TTR(l));
String name = l.get_slicec(' ', 0);
- if (ScriptServer::is_global_class(name))
+ if (ScriptServer::is_global_class(name)) {
name = ScriptServer::get_global_class_native_base(name);
+ }
button->set_icon(EditorNode::get_singleton()->get_class_icon(name));
button->connect("pressed", callable_mp(this, &SceneTreeDock::_favorite_root_selected), make_binds(l));
}
@@ -2743,11 +2723,9 @@ void SceneTreeDock::_favorite_root_selected(const String &p_class) {
}
void SceneTreeDock::_feature_profile_changed() {
-
Ref<EditorFeatureProfile> profile = EditorFeatureProfileManager::get_singleton()->get_current_profile();
if (profile.is_valid()) {
-
profile_allow_editing = !profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCENE_TREE);
profile_allow_script_editing = !profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT);
bool profile_allow_3d = !profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D);
@@ -2770,7 +2748,6 @@ void SceneTreeDock::_feature_profile_changed() {
}
void SceneTreeDock::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_set_owners"), &SceneTreeDock::_set_owners);
ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &SceneTreeDock::_unhandled_key_input);
ClassDB::bind_method(D_METHOD("_input"), &SceneTreeDock::_input);
@@ -2784,7 +2761,6 @@ void SceneTreeDock::_bind_methods() {
}
SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSelection *p_editor_selection, EditorData &p_editor_data) {
-
set_name("Scene");
editor = p_editor;
edited_scene = nullptr;
@@ -2805,7 +2781,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type"));
ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script"));
ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script"));
- ED_SHORTCUT("scene_tree/clear_script", TTR("Clear Script"));
+ ED_SHORTCUT("scene_tree/detach_script", TTR("Detach Script"));
ED_SHORTCUT("scene_tree/move_up", TTR("Move Up"), KEY_MASK_CMD | KEY_UP);
ED_SHORTCUT("scene_tree/move_down", TTR("Move Down"), KEY_MASK_CMD | KEY_DOWN);
ED_SHORTCUT("scene_tree/duplicate", TTR("Duplicate"), KEY_MASK_CMD | KEY_D);
@@ -2840,17 +2816,17 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
button_create_script = memnew(ToolButton);
button_create_script->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_ATTACH_SCRIPT, false));
- button_create_script->set_tooltip(TTR("Attach a new or existing script for the selected node."));
+ button_create_script->set_tooltip(TTR("Attach a new or existing script to the selected node."));
button_create_script->set_shortcut(ED_GET_SHORTCUT("scene_tree/attach_script"));
filter_hbc->add_child(button_create_script);
button_create_script->hide();
- button_clear_script = memnew(ToolButton);
- button_clear_script->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_CLEAR_SCRIPT, false));
- button_clear_script->set_tooltip(TTR("Clear a script for the selected node."));
- button_clear_script->set_shortcut(ED_GET_SHORTCUT("scene_tree/clear_script"));
- filter_hbc->add_child(button_clear_script);
- button_clear_script->hide();
+ button_detach_script = memnew(ToolButton);
+ button_detach_script->connect("pressed", callable_mp(this, &SceneTreeDock::_tool_selected), make_binds(TOOL_DETACH_SCRIPT, false));
+ button_detach_script->set_tooltip(TTR("Detach the script from the selected node."));
+ button_detach_script->set_shortcut(ED_GET_SHORTCUT("scene_tree/detach_script"));
+ filter_hbc->add_child(button_detach_script);
+ button_detach_script->hide();
button_hb = memnew(HBoxContainer);
vbc->add_child(button_hb);
@@ -2867,6 +2843,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
edit_local->set_h_size_flags(SIZE_EXPAND_FILL);
edit_local->set_text(TTR("Local"));
edit_local->set_toggle_mode(true);
+ edit_local->set_pressed(true);
edit_local->connect("pressed", callable_mp(this, &SceneTreeDock::_local_tree_selected));
remote_tree = nullptr;
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index 31ef1ce7d0..72be3fb02f 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -53,7 +53,6 @@
class EditorNode;
class SceneTreeDock : public VBoxContainer {
-
GDCLASS(SceneTreeDock, VBoxContainer);
enum Tool {
@@ -66,7 +65,7 @@ class SceneTreeDock : public VBoxContainer {
TOOL_REPLACE,
TOOL_EXTEND_SCRIPT,
TOOL_ATTACH_SCRIPT,
- TOOL_CLEAR_SCRIPT,
+ TOOL_DETACH_SCRIPT,
TOOL_MOVE_UP,
TOOL_MOVE_DOWN,
TOOL_DUPLICATE,
@@ -110,7 +109,7 @@ class SceneTreeDock : public VBoxContainer {
ToolButton *button_add;
ToolButton *button_instance;
ToolButton *button_create_script;
- ToolButton *button_clear_script;
+ ToolButton *button_detach_script;
Button *button_3d;
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 251c911038..1b818036e1 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -41,14 +41,12 @@
#include "scene/resources/packed_scene.h"
Node *SceneTreeEditor::get_scene_node() {
-
ERR_FAIL_COND_V(!is_inside_tree(), nullptr);
return get_tree()->get_edited_scene_root();
}
void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_id) {
-
if (connect_to_script_mode) {
return; //don't do anything in this mode
}
@@ -71,8 +69,9 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
}
} else if (p_id == BUTTON_SCRIPT) {
Ref<Script> script_typed = n->get_script();
- if (!script_typed.is_null())
+ if (!script_typed.is_null()) {
emit_signal("open_script", script_typed);
+ }
} else if (p_id == BUTTON_VISIBILITY) {
undo_redo->create_action(TTR("Toggle Visible"));
@@ -93,7 +92,6 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
undo_redo->create_action(TTR("Unlock Node"));
if (n->is_class("CanvasItem") || n->is_class("Node3D")) {
-
undo_redo->add_do_method(n, "remove_meta", "_edit_lock_");
undo_redo->add_undo_method(n, "set_meta", "_edit_lock_", true);
undo_redo->add_do_method(this, "_update_tree", Variant());
@@ -103,7 +101,6 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
}
undo_redo->commit_action();
} else if (p_id == BUTTON_PIN) {
-
if (n->is_class("AnimationPlayer")) {
AnimationPlayerEditor::singleton->unpin();
_update_tree();
@@ -113,7 +110,6 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
undo_redo->create_action(TTR("Button Group"));
if (n->is_class("CanvasItem") || n->is_class("Node3D")) {
-
undo_redo->add_do_method(n, "remove_meta", "_edit_group_");
undo_redo->add_undo_method(n, "set_meta", "_edit_group_", true);
undo_redo->add_do_method(this, "_update_tree", Variant());
@@ -123,16 +119,15 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
}
undo_redo->commit_action();
} else if (p_id == BUTTON_WARNING) {
-
String config_err = n->get_configuration_warning();
- if (config_err == String())
+ if (config_err == String()) {
return;
+ }
config_err = config_err.word_wrap(80);
warning->set_text(config_err);
warning->popup_centered();
} else if (p_id == BUTTON_SIGNALS) {
-
editor_selection->clear();
editor_selection->add_node(n);
@@ -142,7 +137,6 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
NodeDock::singleton->show_connections();
} else if (p_id == BUTTON_GROUPS) {
-
editor_selection->clear();
editor_selection->add_node(n);
@@ -152,6 +146,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
NodeDock::singleton->show_groups();
}
}
+
void SceneTreeEditor::_toggle_visible(Node *p_node) {
if (p_node->has_method("is_visible") && p_node->has_method("set_visible")) {
bool v = bool(p_node->call("is_visible"));
@@ -161,9 +156,9 @@ void SceneTreeEditor::_toggle_visible(Node *p_node) {
}
bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
-
- if (!p_node)
+ if (!p_node) {
return false;
+ }
// only owned nodes are editable, since nodes can create their own (manually owned) child nodes,
// which the editor needs not to know about.
@@ -171,9 +166,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
bool part_of_subscene = false;
if (!display_foreign && p_node->get_owner() != get_scene_node() && p_node != get_scene_node()) {
-
if ((show_enabled_subscene || can_open_instance) && p_node->get_owner() && (get_scene_node()->is_editable_instance(p_node->get_owner()))) {
-
part_of_subscene = true;
//allow
} else {
@@ -186,14 +179,16 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
TreeItem *item = tree->create_item(p_parent);
item->set_text(0, p_node->get_name());
- if (can_rename && !part_of_subscene)
+ if (can_rename && !part_of_subscene) {
item->set_editable(0, true);
+ }
item->set_selectable(0, true);
if (can_rename) {
bool collapsed = p_node->is_displayed_folded();
- if (collapsed)
+ if (collapsed) {
item->set_collapsed(true);
+ }
}
Ref<Texture2D> icon = EditorNode::get_singleton()->get_object_icon(p_node, "Node");
@@ -229,12 +224,10 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
item->set_custom_color(0, accent);
}
} else if (part_of_subscene) {
-
if (valid_types.size() == 0) {
item->set_custom_color(0, get_theme_color("disabled_font_color", "Editor"));
}
} else if (marked.has(p_node)) {
-
String node_name = p_node->get_name();
if (connecting_signal) {
node_name += " " + TTR("(Connecting From)");
@@ -243,7 +236,6 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
item->set_selectable(0, marked_selectable);
item->set_custom_color(0, get_theme_color("accent_color", "Editor"));
} else if (!marked_selectable && !marked_children_selectable) {
-
Node *node = p_node;
while (node) {
if (marked.has(node)) {
@@ -323,8 +315,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
if (can_open_instance && undo_redo) { //Show buttons only when necessary(SceneTreeDock) to avoid crashes
- if (!p_node->is_connected("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed)))
+ if (!p_node->is_connected("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed))) {
p_node->connect("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed), varray(p_node));
+ }
Ref<Script> script = p_node->get_script();
if (!script.is_null()) {
@@ -335,47 +328,52 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
if (p_node->is_class("CanvasItem")) {
-
bool is_locked = p_node->has_meta("_edit_lock_"); //_edit_group_
- if (is_locked)
+ if (is_locked) {
item->add_button(0, get_theme_icon("Lock", "EditorIcons"), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock it."));
+ }
bool is_grouped = p_node->has_meta("_edit_group_");
- if (is_grouped)
+ if (is_grouped) {
item->add_button(0, get_theme_icon("Group", "EditorIcons"), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make selectable."));
+ }
bool v = p_node->call("is_visible");
- if (v)
+ if (v) {
item->add_button(0, get_theme_icon("GuiVisibilityVisible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
- else
+ } else {
item->add_button(0, get_theme_icon("GuiVisibilityHidden", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
+ }
- if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed)))
+ if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) {
p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed), varray(p_node));
+ }
_update_visibility_color(p_node, item);
} else if (p_node->is_class("Node3D")) {
-
bool is_locked = p_node->has_meta("_edit_lock_");
- if (is_locked)
+ if (is_locked) {
item->add_button(0, get_theme_icon("Lock", "EditorIcons"), BUTTON_LOCK, false, TTR("Node is locked.\nClick to unlock it."));
+ }
bool is_grouped = p_node->has_meta("_edit_group_");
- if (is_grouped)
+ if (is_grouped) {
item->add_button(0, get_theme_icon("Group", "EditorIcons"), BUTTON_GROUP, false, TTR("Children are not selectable.\nClick to make selectable."));
+ }
bool v = p_node->call("is_visible");
- if (v)
+ if (v) {
item->add_button(0, get_theme_icon("GuiVisibilityVisible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
- else
+ } else {
item->add_button(0, get_theme_icon("GuiVisibilityHidden", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
+ }
- if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed)))
+ if (!p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) {
p_node->connect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed), varray(p_node));
+ }
_update_visibility_color(p_node, item);
} else if (p_node->is_class("AnimationPlayer")) {
-
bool is_pinned = AnimationPlayerEditor::singleton->get_player() == p_node && AnimationPlayerEditor::singleton->is_pinned();
if (is_pinned) {
@@ -386,21 +384,20 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
if (editor_selection) {
if (editor_selection->is_selected(p_node)) {
-
item->select(0);
}
}
if (selected == p_node) {
- if (!editor_selection)
+ if (!editor_selection) {
item->select(0);
+ }
item->set_as_cursor(0);
}
bool keep = (filter.is_subsequence_ofi(String(p_node->get_name())));
for (int i = 0; i < p_node->get_child_count(); i++) {
-
bool child_keep = _add_nodes(p_node->get_child(i), item);
keep = keep || child_keep;
@@ -437,9 +434,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
void SceneTreeEditor::_node_visibility_changed(Node *p_node) {
-
if (!p_node || (p_node != get_scene_node() && !p_node->get_owner())) {
-
return;
}
@@ -461,10 +456,11 @@ void SceneTreeEditor::_node_visibility_changed(Node *p_node) {
visible = p_node->call("is_visible");
}
- if (visible)
+ if (visible) {
item->set_button(0, idx, get_theme_icon("GuiVisibilityVisible", "EditorIcons"));
- else
+ } else {
item->set_button(0, idx, get_theme_icon("GuiVisibilityHidden", "EditorIcons"));
+ }
_update_visibility_color(p_node, item);
}
@@ -482,25 +478,27 @@ void SceneTreeEditor::_update_visibility_color(Node *p_node, TreeItem *p_item) {
}
void SceneTreeEditor::_node_script_changed(Node *p_node) {
-
- if (tree_dirty)
+ if (tree_dirty) {
return;
+ }
MessageQueue::get_singleton()->push_call(this, "_update_tree");
tree_dirty = true;
}
void SceneTreeEditor::_node_removed(Node *p_node) {
-
- if (EditorNode::get_singleton()->is_exiting())
+ if (EditorNode::get_singleton()->is_exiting()) {
return; //speed up exit
+ }
- if (p_node->is_connected("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed)))
+ if (p_node->is_connected("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed))) {
p_node->disconnect("script_changed", callable_mp(this, &SceneTreeEditor::_node_script_changed));
+ }
if (p_node->is_class("Node3D") || p_node->is_class("CanvasItem")) {
- if (p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed)))
+ if (p_node->is_connected("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed))) {
p_node->disconnect("visibility_changed", callable_mp(this, &SceneTreeEditor::_node_visibility_changed));
+ }
}
if (p_node == selected) {
@@ -510,7 +508,6 @@ void SceneTreeEditor::_node_removed(Node *p_node) {
}
void SceneTreeEditor::_node_renamed(Node *p_node) {
-
emit_signal("node_renamed");
if (!tree_dirty) {
@@ -520,7 +517,6 @@ void SceneTreeEditor::_node_renamed(Node *p_node) {
}
void SceneTreeEditor::_update_tree() {
-
if (!is_inside_tree()) {
tree_dirty = false;
return;
@@ -539,61 +535,65 @@ void SceneTreeEditor::_update_tree() {
}
void SceneTreeEditor::_compute_hash(Node *p_node, uint64_t &hash) {
-
hash = hash_djb2_one_64(p_node->get_instance_id(), hash);
- if (p_node->get_parent())
+ if (p_node->get_parent()) {
hash = hash_djb2_one_64(p_node->get_parent()->get_instance_id(), hash); //so a reparent still produces a different hash
+ }
for (int i = 0; i < p_node->get_child_count(); i++) {
-
_compute_hash(p_node->get_child(i), hash);
}
}
void SceneTreeEditor::_test_update_tree() {
-
pending_test_update = false;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
- if (tree_dirty)
+ if (tree_dirty) {
return; // don't even bother
+ }
uint64_t hash = hash_djb2_one_64(0);
- if (get_scene_node())
+ if (get_scene_node()) {
_compute_hash(get_scene_node(), hash);
+ }
//test hash
- if (hash == last_hash)
+ if (hash == last_hash) {
return; // did not change
+ }
MessageQueue::get_singleton()->push_call(this, "_update_tree");
tree_dirty = true;
}
void SceneTreeEditor::_tree_changed() {
-
- if (EditorNode::get_singleton()->is_exiting())
+ if (EditorNode::get_singleton()->is_exiting()) {
return; //speed up exit
- if (pending_test_update)
+ }
+ if (pending_test_update) {
return;
- if (tree_dirty)
+ }
+ if (tree_dirty) {
return;
+ }
MessageQueue::get_singleton()->push_call(this, "_test_update_tree");
pending_test_update = true;
}
void SceneTreeEditor::_selected_changed() {
-
TreeItem *s = tree->get_selected();
ERR_FAIL_COND(!s);
NodePath np = s->get_metadata(0);
Node *n = get_node(np);
- if (n == selected)
+ if (n == selected) {
return;
+ }
selected = get_node(np);
@@ -603,7 +603,6 @@ void SceneTreeEditor::_selected_changed() {
}
void SceneTreeEditor::_deselect_items() {
-
// Clear currently elected items in scene tree dock.
if (editor_selection) {
editor_selection->clear();
@@ -612,7 +611,6 @@ void SceneTreeEditor::_deselect_items() {
}
void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_selected) {
-
TreeItem *item = Object::cast_to<TreeItem>(p_object);
ERR_FAIL_COND(!item);
@@ -620,11 +618,13 @@ void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_
Node *n = get_node(np);
- if (!n)
+ if (!n) {
return;
+ }
- if (!editor_selection)
+ if (!editor_selection) {
return;
+ }
if (p_selected) {
editor_selection->add_node(n);
@@ -636,10 +636,8 @@ void SceneTreeEditor::_cell_multi_selected(Object *p_object, int p_cell, bool p_
}
void SceneTreeEditor::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
-
get_tree()->connect("tree_changed", callable_mp(this, &SceneTreeEditor::_tree_changed));
get_tree()->connect("node_removed", callable_mp(this, &SceneTreeEditor::_node_removed));
get_tree()->connect("node_renamed", callable_mp(this, &SceneTreeEditor::_node_renamed));
@@ -650,7 +648,6 @@ void SceneTreeEditor::_notification(int p_what) {
_update_tree();
} break;
case NOTIFICATION_EXIT_TREE: {
-
get_tree()->disconnect("tree_changed", callable_mp(this, &SceneTreeEditor::_tree_changed));
get_tree()->disconnect("node_removed", callable_mp(this, &SceneTreeEditor::_node_removed));
get_tree()->disconnect("node_renamed", callable_mp(this, &SceneTreeEditor::_node_renamed));
@@ -658,27 +655,27 @@ void SceneTreeEditor::_notification(int p_what) {
get_tree()->disconnect("node_configuration_warning_changed", callable_mp(this, &SceneTreeEditor::_warning_changed));
} break;
case NOTIFICATION_THEME_CHANGED: {
-
_update_tree();
} break;
}
}
TreeItem *SceneTreeEditor::_find(TreeItem *p_node, const NodePath &p_path) {
-
- if (!p_node)
+ if (!p_node) {
return nullptr;
+ }
NodePath np = p_node->get_metadata(0);
- if (np == p_path)
+ if (np == p_path) {
return p_node;
+ }
TreeItem *children = p_node->get_children();
while (children) {
-
TreeItem *n = _find(children, p_path);
- if (n)
+ if (n) {
return n;
+ }
children = children->get_next();
}
@@ -686,16 +683,18 @@ TreeItem *SceneTreeEditor::_find(TreeItem *p_node, const NodePath &p_path) {
}
void SceneTreeEditor::set_selected(Node *p_node, bool p_emit_selected) {
-
ERR_FAIL_COND(blocked > 0);
- if (pending_test_update)
+ if (pending_test_update) {
_test_update_tree();
- if (tree_dirty)
+ }
+ if (tree_dirty) {
_update_tree();
+ }
- if (selected == p_node)
+ if (selected == p_node) {
return;
+ }
TreeItem *item = p_node ? _find(tree->get_root(), p_node->get_path()) : nullptr;
@@ -712,8 +711,9 @@ void SceneTreeEditor::set_selected(Node *p_node, bool p_emit_selected) {
tree->ensure_cursor_is_visible();
} else {
- if (!p_node)
+ if (!p_node) {
selected = nullptr;
+ }
_update_tree();
selected = p_node;
}
@@ -724,7 +724,6 @@ void SceneTreeEditor::set_selected(Node *p_node, bool p_emit_selected) {
}
void SceneTreeEditor::_rename_node(ObjectID p_node, const String &p_name) {
-
Object *o = ObjectDB::get_instance(p_node);
ERR_FAIL_COND(!o);
Node *n = Object::cast_to<Node>(o);
@@ -738,7 +737,6 @@ void SceneTreeEditor::_rename_node(ObjectID p_node, const String &p_name) {
}
void SceneTreeEditor::_renamed() {
-
TreeItem *which = tree->get_edited();
ERR_FAIL_COND(!which);
@@ -755,7 +753,6 @@ void SceneTreeEditor::_renamed() {
String new_name = which->get_text(0);
if (!Node::_validate_node_name(new_name)) {
-
error->set_text(TTR("Invalid node name, the following characters are not allowed:") + "\n" + Node::invalid_character);
error->popup_centered();
@@ -767,8 +764,9 @@ void SceneTreeEditor::_renamed() {
which->set_text(0, new_name);
}
- if (new_name == n->get_name())
+ if (new_name == n->get_name()) {
return;
+ }
if (!undo_redo) {
n->set_name(new_name);
@@ -784,14 +782,13 @@ void SceneTreeEditor::_renamed() {
}
Node *SceneTreeEditor::get_selected() {
-
return selected;
}
void SceneTreeEditor::set_marked(const Set<Node *> &p_marked, bool p_selectable, bool p_children_selectable) {
-
- if (tree_dirty)
+ if (tree_dirty) {
_update_tree();
+ }
marked = p_marked;
marked_selectable = p_selectable;
marked_children_selectable = p_children_selectable;
@@ -799,31 +796,28 @@ void SceneTreeEditor::set_marked(const Set<Node *> &p_marked, bool p_selectable,
}
void SceneTreeEditor::set_marked(Node *p_marked, bool p_selectable, bool p_children_selectable) {
-
Set<Node *> s;
- if (p_marked)
+ if (p_marked) {
s.insert(p_marked);
+ }
set_marked(s, p_selectable, p_children_selectable);
}
void SceneTreeEditor::set_filter(const String &p_filter) {
-
filter = p_filter;
_update_tree();
}
String SceneTreeEditor::get_filter() const {
-
return filter;
}
void SceneTreeEditor::set_display_foreign_nodes(bool p_display) {
-
display_foreign = p_display;
_update_tree();
}
-bool SceneTreeEditor::get_display_foreign_nodes() const {
+bool SceneTreeEditor::get_display_foreign_nodes() const {
return display_foreign;
}
@@ -832,7 +826,6 @@ void SceneTreeEditor::set_valid_types(const Vector<StringName> &p_valid) {
}
void SceneTreeEditor::set_editor_selection(EditorSelection *p_selection) {
-
editor_selection = p_selection;
tree->set_select_mode(Tree::SELECT_MULTI);
tree->set_cursor_can_exit_tree(false);
@@ -840,55 +833,59 @@ void SceneTreeEditor::set_editor_selection(EditorSelection *p_selection) {
}
void SceneTreeEditor::_update_selection(TreeItem *item) {
-
ERR_FAIL_COND(!item);
NodePath np = item->get_metadata(0);
- if (!has_node(np))
+ if (!has_node(np)) {
return;
+ }
Node *n = get_node(np);
- if (!n)
+ if (!n) {
return;
+ }
- if (editor_selection->is_selected(n))
+ if (editor_selection->is_selected(n)) {
item->select(0);
- else
+ } else {
item->deselect(0);
+ }
TreeItem *c = item->get_children();
while (c) {
-
_update_selection(c);
c = c->get_next();
}
}
void SceneTreeEditor::_selection_changed() {
-
- if (!editor_selection)
+ if (!editor_selection) {
return;
+ }
TreeItem *root = tree->get_root();
- if (!root)
+ if (!root) {
return;
+ }
_update_selection(root);
}
void SceneTreeEditor::_cell_collapsed(Object *p_obj) {
-
- if (updating_tree)
+ if (updating_tree) {
return;
- if (!can_rename)
+ }
+ if (!can_rename) {
return;
+ }
TreeItem *ti = Object::cast_to<TreeItem>(p_obj);
- if (!ti)
+ if (!ti) {
return;
+ }
bool collapsed = ti->is_collapsed();
@@ -901,14 +898,14 @@ void SceneTreeEditor::_cell_collapsed(Object *p_obj) {
}
Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
- if (!can_rename)
+ if (!can_rename) {
return Variant(); //not editable tree
+ }
Vector<Node *> selected;
Vector<Ref<Texture2D>> icons;
TreeItem *next = tree->get_next_selected(nullptr);
while (next) {
-
NodePath np = next->get_metadata(0);
Node *n = get_node(np);
@@ -922,8 +919,9 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from
next = tree->get_next_selected(next);
}
- if (selected.empty())
+ if (selected.empty()) {
return Variant();
+ }
VBoxContainer *vb = memnew(VBoxContainer);
Array objs;
@@ -931,7 +929,6 @@ Variant SceneTreeEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from
float opacity_step = 1.0f / list_max;
float opacity_item = 1.0f;
for (int i = 0; i < selected.size(); i++) {
-
if (i < list_max) {
HBoxContainer *hb = memnew(HBoxContainer);
TextureRect *tf = memnew(TextureRect);
@@ -964,30 +961,34 @@ bool SceneTreeEditor::_is_script_type(const StringName &p_type) const {
}
bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
- if (!can_rename)
+ if (!can_rename) {
return false; //not editable tree
- if (filter != String())
+ }
+ if (filter != String()) {
return false; //can't rearrange tree with filter turned on
+ }
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return false;
+ }
TreeItem *item = tree->get_item_at_position(p_point);
- if (!item)
+ if (!item) {
return false;
+ }
int section = tree->get_drop_section_at_position(p_point);
- if (section < -1 || (section == -1 && !item->get_parent()))
+ if (section < -1 || (section == -1 && !item->get_parent())) {
return false;
+ }
if (String(d["type"]) == "files") {
-
Vector<String> files = d["files"];
- if (files.size() == 0)
+ if (files.size() == 0) {
return false; //weird
+ }
if (_is_script_type(EditorFileSystem::get_singleton()->get_file_type(files[0]))) {
tree->set_drop_mode_flags(Tree::DROP_MODE_ON_ITEM);
@@ -997,8 +998,9 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_d
for (int i = 0; i < files.size(); i++) {
String file = files[i];
String ftype = EditorFileSystem::get_singleton()->get_file_type(file);
- if (ftype != "PackedScene")
+ if (ftype != "PackedScene") {
return false;
+ }
}
tree->set_drop_mode_flags(Tree::DROP_MODE_INBETWEEN | Tree::DROP_MODE_ON_ITEM); //so it works..
@@ -1019,22 +1021,26 @@ bool SceneTreeEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_d
return String(d["type"]) == "nodes";
}
-void SceneTreeEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
- if (!can_drop_data_fw(p_point, p_data, p_from))
+void SceneTreeEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
+ if (!can_drop_data_fw(p_point, p_data, p_from)) {
return;
+ }
TreeItem *item = tree->get_item_at_position(p_point);
- if (!item)
+ if (!item) {
return;
+ }
int section = tree->get_drop_section_at_position(p_point);
- if (section < -1)
+ if (section < -1) {
return;
+ }
NodePath np = item->get_metadata(0);
Node *n = get_node(np);
- if (!n)
+ if (!n) {
return;
+ }
Dictionary d = p_data;
@@ -1044,7 +1050,6 @@ void SceneTreeEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data,
}
if (String(d["type"]) == "files") {
-
Vector<String> files = d["files"];
String ftype = EditorFileSystem::get_singleton()->get_file_type(files[0]);
@@ -1067,12 +1072,10 @@ void SceneTreeEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data,
}
void SceneTreeEditor::_rmb_select(const Vector2 &p_pos) {
-
emit_signal("rmb_pressed", tree->get_global_transform().xform(p_pos));
}
void SceneTreeEditor::_warning_changed(Node *p_for_node) {
-
//should use a timer
update_timer->start();
}
@@ -1088,7 +1091,6 @@ void SceneTreeEditor::set_connecting_signal(bool p_enable) {
}
void SceneTreeEditor::_bind_methods() {
-
ClassDB::bind_method("_update_tree", &SceneTreeEditor::_update_tree); // Still used by some connect_compat.
ClassDB::bind_method("_rename_node", &SceneTreeEditor::_rename_node);
ClassDB::bind_method("_test_update_tree", &SceneTreeEditor::_test_update_tree);
@@ -1114,7 +1116,6 @@ void SceneTreeEditor::_bind_methods() {
}
SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_open_instance) {
-
connect_to_script_mode = false;
connecting_signal = false;
undo_redo = nullptr;
@@ -1184,19 +1185,17 @@ SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_ope
}
SceneTreeEditor::~SceneTreeEditor() {
-
memdelete(script_types);
}
/******** DIALOG *********/
void SceneTreeDialog::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
-
- if (is_visible())
+ if (is_visible()) {
tree->update_tree();
+ }
} break;
case NOTIFICATION_ENTER_TREE: {
connect("confirmed", callable_mp(this, &SceneTreeDialog::_select));
@@ -1210,11 +1209,10 @@ void SceneTreeDialog::_notification(int p_what) {
}
void SceneTreeDialog::_cancel() {
-
hide();
}
-void SceneTreeDialog::_select() {
+void SceneTreeDialog::_select() {
if (tree->get_selected()) {
emit_signal("selected", tree->get_selected()->get_path());
hide();
@@ -1222,19 +1220,16 @@ void SceneTreeDialog::_select() {
}
void SceneTreeDialog::_filter_changed(const String &p_filter) {
-
tree->set_filter(p_filter);
}
void SceneTreeDialog::_bind_methods() {
-
ClassDB::bind_method("_cancel", &SceneTreeDialog::_cancel);
ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::NODE_PATH, "path")));
}
SceneTreeDialog::SceneTreeDialog() {
-
set_title(TTR("Select a Node"));
VBoxContainer *vbc = memnew(VBoxContainer);
add_child(vbc);
diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h
index 17ee5ace66..106837f69a 100644
--- a/editor/scene_tree_editor.h
+++ b/editor/scene_tree_editor.h
@@ -39,7 +39,6 @@
#include "scene/gui/tree.h"
class SceneTreeEditor : public Control {
-
GDCLASS(SceneTreeEditor, Control);
EditorSelection *editor_selection;
@@ -163,7 +162,6 @@ public:
};
class SceneTreeDialog : public ConfirmationDialog {
-
GDCLASS(SceneTreeDialog, ConfirmationDialog);
SceneTreeEditor *tree;
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 12b21d871b..04fbfdff9d 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -67,8 +67,8 @@ void ScriptCreateDialog::_theme_changed() {
parent_search_button->set_icon(gc->get_theme_icon("ClassList", "EditorIcons"));
status_panel->add_theme_style_override("panel", gc->get_theme_stylebox("bg", "Tree"));
}
-void ScriptCreateDialog::_notification(int p_what) {
+void ScriptCreateDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
_theme_changed();
@@ -99,7 +99,6 @@ bool ScriptCreateDialog::_can_be_built_in() {
}
void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_path, bool p_built_in_enabled, bool p_load_enabled) {
-
class_name->set_text("");
class_name->deselect();
parent_name->set_text(p_base_name);
@@ -124,54 +123,60 @@ void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_
}
void ScriptCreateDialog::set_inheritance_base_type(const String &p_base) {
-
base_type = p_base;
}
bool ScriptCreateDialog::_validate_parent(const String &p_string) {
-
- if (p_string.length() == 0)
+ if (p_string.length() == 0) {
return false;
+ }
if (can_inherit_from_file && p_string.is_quoted()) {
String p = p_string.substr(1, p_string.length() - 2);
- if (_validate_path(p, true) == "")
+ if (_validate_path(p, true) == "") {
return true;
+ }
}
return ClassDB::class_exists(p_string) || ScriptServer::is_global_class(p_string);
}
bool ScriptCreateDialog::_validate_class(const String &p_string) {
-
- if (p_string.length() == 0)
+ if (p_string.length() == 0) {
return false;
+ }
for (int i = 0; i < p_string.length(); i++) {
-
if (i == 0) {
- if (p_string[0] >= '0' && p_string[0] <= '9')
+ if (p_string[0] >= '0' && p_string[0] <= '9') {
return false; // no start with number plz
+ }
}
bool valid_char = (p_string[i] >= '0' && p_string[i] <= '9') || (p_string[i] >= 'a' && p_string[i] <= 'z') || (p_string[i] >= 'A' && p_string[i] <= 'Z') || p_string[i] == '_' || p_string[i] == '.';
- if (!valid_char)
+ if (!valid_char) {
return false;
+ }
}
return true;
}
String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must_exist) {
-
String p = p_path.strip_edges();
- if (p == "") return TTR("Path is empty.");
- if (p.get_file().get_basename() == "") return TTR("Filename is empty.");
+ if (p == "") {
+ return TTR("Path is empty.");
+ }
+ if (p.get_file().get_basename() == "") {
+ return TTR("Filename is empty.");
+ }
p = ProjectSettings::get_singleton()->localize_path(p);
- if (!p.begins_with("res://")) return TTR("Path is not local.");
+ if (!p.begins_with("res://")) {
+ return TTR("Path is not local.");
+ }
DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
if (d->change_dir(p.get_base_dir()) != OK) {
@@ -216,19 +221,24 @@ String ScriptCreateDialog::_validate_path(const String &p_path, bool p_file_must
index++;
}
- if (!found) return TTR("Invalid extension.");
- if (!match) return TTR("Wrong extension chosen.");
+ if (!found) {
+ return TTR("Invalid extension.");
+ }
+ if (!match) {
+ return TTR("Wrong extension chosen.");
+ }
/* Let ScriptLanguage do custom validation */
String path_error = ScriptServer::get_language(language_menu->get_selected())->validate_path(p);
- if (path_error != "") return path_error;
+ if (path_error != "") {
+ return path_error;
+ }
/* All checks passed */
return "";
}
void ScriptCreateDialog::_class_name_changed(const String &p_name) {
-
if (_validate_class(class_name->get_text())) {
is_class_name_valid = true;
} else {
@@ -238,7 +248,6 @@ void ScriptCreateDialog::_class_name_changed(const String &p_name) {
}
void ScriptCreateDialog::_parent_name_changed(const String &p_parent) {
-
if (_validate_parent(parent_name->get_text())) {
is_parent_name_valid = true;
} else {
@@ -248,7 +257,6 @@ void ScriptCreateDialog::_parent_name_changed(const String &p_parent) {
}
void ScriptCreateDialog::_template_changed(int p_template) {
-
String selected_template = p_template == 0 ? "" : template_menu->get_item_text(p_template);
EditorSettings::get_singleton()->set_project_metadata("script_setup", "last_selected_template", selected_template);
if (p_template == 0) {
@@ -268,7 +276,6 @@ void ScriptCreateDialog::_template_changed(int p_template) {
}
void ScriptCreateDialog::ok_pressed() {
-
if (is_new_script_created) {
_create_new();
} else {
@@ -280,7 +287,6 @@ void ScriptCreateDialog::ok_pressed() {
}
void ScriptCreateDialog::_create_new() {
-
String cname_param;
if (has_named_classes) {
@@ -305,8 +311,9 @@ void ScriptCreateDialog::_create_new() {
if (has_named_classes) {
String cname = class_name->get_text();
- if (cname.length())
+ if (cname.length()) {
scr->set_name(cname);
+ }
}
if (!is_built_in) {
@@ -325,7 +332,6 @@ void ScriptCreateDialog::_create_new() {
}
void ScriptCreateDialog::_load_exist() {
-
String path = file_path->get_text();
RES p_script = ResourceLoader::load(path, "Script");
if (p_script.is_null()) {
@@ -339,14 +345,14 @@ void ScriptCreateDialog::_load_exist() {
}
void ScriptCreateDialog::_lang_changed(int l) {
-
ScriptLanguage *language = ScriptServer::get_language(l);
has_named_classes = language->has_named_classes();
can_inherit_from_file = language->can_inherit_from_file();
supports_built_in = language->supports_builtin_mode();
- if (!supports_built_in)
+ if (!supports_built_in) {
is_built_in = false;
+ }
String selected_ext = "." + language->get_extension();
String path = file_path->get_text();
@@ -403,7 +409,6 @@ void ScriptCreateDialog::_lang_changed(int l) {
// Populate script template items previously sorted and now grouped by origin
for (int i = 0; i < template_list.size(); i++) {
-
if (int(templates[i].origin) != cur_origin) {
template_menu->add_separator();
@@ -468,7 +473,6 @@ void ScriptCreateDialog::_lang_changed(int l) {
}
void ScriptCreateDialog::_update_script_templates(const String &p_extension) {
-
template_list.clear();
template_overrides.clear();
@@ -479,7 +483,6 @@ void ScriptCreateDialog::_update_script_templates(const String &p_extension) {
dirs.push_back(EditorSettings::get_singleton()->get_script_templates_dir());
for (int i = 0; i < dirs.size(); i++) {
-
Vector<String> list = EditorSettings::get_singleton()->get_script_templates(p_extension, dirs[i]);
for (int j = 0; j < list.size(); j++) {
@@ -503,7 +506,6 @@ void ScriptCreateDialog::_update_script_templates(const String &p_extension) {
}
void ScriptCreateDialog::_built_in_pressed() {
-
if (internal->is_pressed()) {
is_built_in = true;
is_new_script_created = true;
@@ -515,7 +517,6 @@ void ScriptCreateDialog::_built_in_pressed() {
}
void ScriptCreateDialog::_browse_path(bool browse_parent, bool p_save) {
-
is_browsing_parent = browse_parent;
if (p_save) {
@@ -543,7 +544,6 @@ void ScriptCreateDialog::_browse_path(bool browse_parent, bool p_save) {
}
void ScriptCreateDialog::_file_selected(const String &p_file) {
-
String p = ProjectSettings::get_singleton()->localize_path(p_file);
if (is_browsing_parent) {
parent_name->set_text("\"" + p + "\"");
@@ -561,19 +561,16 @@ void ScriptCreateDialog::_file_selected(const String &p_file) {
}
void ScriptCreateDialog::_create() {
-
parent_name->set_text(select_class->get_selected_type().split(" ")[0]);
_parent_name_changed(parent_name->get_text());
}
void ScriptCreateDialog::_browse_class_in_tree() {
-
select_class->set_base_type(base_type);
select_class->popup_create(true);
}
void ScriptCreateDialog::_path_changed(const String &p_path) {
-
if (is_built_in) {
return;
}
@@ -606,7 +603,6 @@ void ScriptCreateDialog::_path_entered(const String &p_path) {
}
void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) {
-
error_label->set_text("- " + TTR(p_msg));
if (valid) {
error_label->add_theme_color_override("font_color", gc->get_theme_color("success_color", "Editor"));
@@ -616,7 +612,6 @@ void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) {
}
void ScriptCreateDialog::_msg_path_valid(bool valid, const String &p_msg) {
-
path_error_label->set_text("- " + TTR(p_msg));
if (valid) {
path_error_label->add_theme_color_override("font_color", gc->get_theme_color("success_color", "Editor"));
@@ -626,7 +621,6 @@ void ScriptCreateDialog::_msg_path_valid(bool valid, const String &p_msg) {
}
void ScriptCreateDialog::_update_dialog() {
-
/* "Add Script Dialog" GUI logic and script checks. */
bool script_ok = true;
@@ -731,14 +725,12 @@ void ScriptCreateDialog::_update_dialog() {
}
void ScriptCreateDialog::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("config", "inherits", "path", "built_in_enabled", "load_enabled"), &ScriptCreateDialog::config, DEFVAL(true), DEFVAL(true));
ADD_SIGNAL(MethodInfo("script_created", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script")));
}
ScriptCreateDialog::ScriptCreateDialog() {
-
/* DIALOG */
/* Main Controls */
@@ -793,7 +785,6 @@ ScriptCreateDialog::ScriptCreateDialog() {
default_language = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
-
String lang = ScriptServer::get_language(i)->get_name();
language_menu->add_item(lang);
if (lang == "GDScript") {
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 8910e8ec3a..c461bf0410 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -41,21 +41,19 @@
#include "scene/gui/margin_container.h"
void EditorSettingsDialog::ok_pressed() {
-
- if (!EditorSettings::get_singleton())
+ if (!EditorSettings::get_singleton()) {
return;
+ }
_settings_save();
timer->stop();
}
void EditorSettingsDialog::_settings_changed() {
-
timer->start();
}
void EditorSettingsDialog::_settings_property_edited(const String &p_name) {
-
String full_name = inspector->get_full_item_path(p_name);
if (full_name == "interface/theme/accent_color" || full_name == "interface/theme/base_color" || full_name == "interface/theme/contrast") {
@@ -66,23 +64,22 @@ void EditorSettingsDialog::_settings_property_edited(const String &p_name) {
}
void EditorSettingsDialog::_settings_save() {
-
EditorSettings::get_singleton()->notify_changes();
EditorSettings::get_singleton()->save();
}
void EditorSettingsDialog::cancel_pressed() {
-
- if (!EditorSettings::get_singleton())
+ if (!EditorSettings::get_singleton()) {
return;
+ }
EditorSettings::get_singleton()->notify_changes();
}
void EditorSettingsDialog::popup_edit_settings() {
-
- if (!EditorSettings::get_singleton())
+ if (!EditorSettings::get_singleton()) {
return;
+ }
EditorSettings::get_singleton()->list_text_editor_themes(); // make sure we have an up to date list of themes
@@ -116,7 +113,6 @@ void EditorSettingsDialog::_undo_redo_callback(void *p_self, const String &p_nam
}
void EditorSettingsDialog::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (!is_visible()) {
@@ -142,17 +138,16 @@ void EditorSettingsDialog::_notification(int p_what) {
}
void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
-
const Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed()) {
-
bool handled = false;
if (ED_IS_SHORTCUT("editor/undo", p_event)) {
String action = undo_redo->get_current_action_name();
- if (action != "")
+ if (action != "") {
EditorNode::get_log()->add_message("Undo: " + action, EditorLog::MSG_TYPE_EDITOR);
+ }
undo_redo->undo();
handled = true;
}
@@ -160,8 +155,9 @@ void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
if (ED_IS_SHORTCUT("editor/redo", p_event)) {
undo_redo->redo();
String action = undo_redo->get_current_action_name();
- if (action != "")
+ if (action != "") {
EditorNode::get_log()->add_message("Redo: " + action, EditorLog::MSG_TYPE_EDITOR);
+ }
handled = true;
}
@@ -177,7 +173,6 @@ void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
}
void EditorSettingsDialog::_update_icons() {
-
search_box->set_right_icon(shortcuts->get_theme_icon("Search", "EditorIcons"));
search_box->set_clear_button_enabled(true);
shortcut_search_box->set_right_icon(shortcuts->get_theme_icon("Search", "EditorIcons"));
@@ -190,7 +185,6 @@ void EditorSettingsDialog::_update_icons() {
}
void EditorSettingsDialog::_update_shortcuts() {
-
Map<String, bool> collapsed;
if (shortcuts->get_root() && shortcuts->get_root()->get_children()) {
@@ -208,10 +202,10 @@ void EditorSettingsDialog::_update_shortcuts() {
Map<String, TreeItem *> sections;
for (List<String>::Element *E = slist.front(); E; E = E->next()) {
-
Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(E->get());
- if (!sc->has_meta("original"))
+ if (!sc->has_meta("original")) {
continue;
+ }
Ref<InputEvent> original = sc->get_meta("original");
@@ -270,7 +264,6 @@ void EditorSettingsDialog::_update_shortcuts() {
}
void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column, int p_idx) {
-
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
ERR_FAIL_COND(!ti);
@@ -287,8 +280,9 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
shortcut_configured = item;
} else if (p_idx == 1) { //erase
- if (!sc.is_valid())
+ if (!sc.is_valid()) {
return; //pointless, there is nothing
+ }
undo_redo->create_action(TTR("Erase Shortcut"));
undo_redo->add_do_method(sc.ptr(), "set_shortcut", Ref<InputEvent>());
@@ -299,8 +293,9 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
undo_redo->add_undo_method(this, "_settings_changed");
undo_redo->commit_action();
} else if (p_idx == 2) { //revert to original
- if (!sc.is_valid())
+ if (!sc.is_valid()) {
return; //pointless, there is nothing
+ }
Ref<InputEvent> original = sc->get_meta("original");
@@ -316,11 +311,9 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
}
void EditorSettingsDialog::_wait_for_key(const Ref<InputEvent> &p_event) {
-
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed() && k->get_keycode() != 0) {
-
last_wait_for_key = k;
const String str = keycode_get_string(k->get_keycode_with_modifiers());
@@ -330,9 +323,9 @@ void EditorSettingsDialog::_wait_for_key(const Ref<InputEvent> &p_event) {
}
void EditorSettingsDialog::_press_a_key_confirm() {
-
- if (last_wait_for_key.is_null())
+ if (last_wait_for_key.is_null()) {
return;
+ }
Ref<InputEventKey> ie;
ie.instance();
@@ -355,18 +348,17 @@ void EditorSettingsDialog::_press_a_key_confirm() {
}
void EditorSettingsDialog::_tabs_tab_changed(int p_tab) {
-
_focus_current_search_box();
}
void EditorSettingsDialog::_focus_current_search_box() {
-
Control *tab = tabs->get_current_tab_control();
LineEdit *current_search_box = nullptr;
- if (tab == tab_general)
+ if (tab == tab_general) {
current_search_box = search_box;
- else if (tab == tab_shortcuts)
+ } else if (tab == tab_shortcuts) {
current_search_box = shortcut_search_box;
+ }
if (current_search_box) {
current_search_box->grab_focus();
@@ -388,13 +380,11 @@ void EditorSettingsDialog::_editor_restart_close() {
}
void EditorSettingsDialog::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_unhandled_input"), &EditorSettingsDialog::_unhandled_input);
ClassDB::bind_method(D_METHOD("_update_shortcuts"), &EditorSettingsDialog::_update_shortcuts);
}
EditorSettingsDialog::EditorSettingsDialog() {
-
set_title(TTR("Editor Settings"));
undo_redo = memnew(UndoRedo);
diff --git a/editor/settings_config_dialog.h b/editor/settings_config_dialog.h
index 03dd18d23f..05566762fc 100644
--- a/editor/settings_config_dialog.h
+++ b/editor/settings_config_dialog.h
@@ -41,7 +41,6 @@
#include "scene/gui/tool_button.h"
class EditorSettingsDialog : public AcceptDialog {
-
GDCLASS(EditorSettingsDialog, AcceptDialog);
bool updating;
diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp
index 566ac54612..aa88b0ef39 100644
--- a/editor/shader_globals_editor.cpp
+++ b/editor/shader_globals_editor.cpp
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* shader_globals_editor.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#include "shader_globals_editor.h"
#include "editor_node.h"
@@ -195,7 +225,6 @@ protected:
pinfo.hint_string = "Cubemap";
} break;
default: {
-
} break;
}
@@ -337,7 +366,6 @@ static Variant create_var(RS::GlobalVariableType p_type) {
}
void ShaderGlobalsEditor::_variable_added() {
-
String var = variable_name->get_text().strip_edges();
if (var == "" || !var.is_valid_identifier()) {
EditorNode::get_singleton()->show_warning(TTR("Please specify a valid variable identifier name."));
@@ -376,7 +404,6 @@ void ShaderGlobalsEditor::_variable_added() {
}
void ShaderGlobalsEditor::_variable_deleted(const String &p_variable) {
-
print_line("deleted " + p_variable);
UndoRedo *undo_redo = EditorNode::get_singleton()->get_undo_redo();
@@ -413,7 +440,6 @@ void ShaderGlobalsEditor::_notification(int p_what) {
}
ShaderGlobalsEditor::ShaderGlobalsEditor() {
-
HBoxContainer *add_menu_hb = memnew(HBoxContainer);
add_child(add_menu_hb);
@@ -446,7 +472,8 @@ ShaderGlobalsEditor::ShaderGlobalsEditor() {
interface = memnew(ShaderGlobalsEditorInterface);
interface->connect("var_changed", Callable(this, "_changed"));
}
+
ShaderGlobalsEditor::~ShaderGlobalsEditor() {
- inspector->edit(NULL);
+ inspector->edit(nullptr);
memdelete(interface);
}
diff --git a/editor/shader_globals_editor.h b/editor/shader_globals_editor.h
index 59cdeddd8d..33f527f314 100644
--- a/editor/shader_globals_editor.h
+++ b/editor/shader_globals_editor.h
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* shader_globals_editor.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef SHADER_GLOBALS_EDITOR_H
#define SHADER_GLOBALS_EDITOR_H
@@ -12,7 +42,6 @@
class ShaderGlobalsEditorInterface;
class ShaderGlobalsEditor : public VBoxContainer {
-
GDCLASS(ShaderGlobalsEditor, VBoxContainer)
ShaderGlobalsEditorInterface *interface;
diff --git a/editor/translations/af.po b/editor/translations/af.po
index d9e1753c65..fb354fa199 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -9944,6 +9944,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -11063,6 +11070,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index 2ea1bd1dd5..22358973a0 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -7,7 +7,7 @@
# Basil Al-Khateeb <basil.y.alkhateeb@gmail.com>, 2017.
# Jamal Alyafei <jamal.qassim@gmail.com>, 2017.
# john lennon <khoanantonio@outlook.com>, 2017.
-# Mohammmad Khashashneh <mohammad.rasmi@gmail.com>, 2016.
+# Mohammmad Khashashneh <mohammad.rasmi@gmail.com>, 2016, 2020.
# Mr ChaosXD <mrchaosxd3@gmail.com>, 2018.
# Mrwan Ashraf <mrwan.ashraf94@gmail.com>, 2017.
# noureldin sharaf <sharaf.noureldin@yahoo.com>, 2017.
@@ -35,12 +35,14 @@
# hshw <shw@tutanota.com>, 2020.
# Youssef Harmal <the.coder.crab@gmail.com>, 2020.
# Nabeel20 <nabeelandnizam@gmail.com>, 2020.
+# merouche djallal <kbordora@gmail.com>, 2020.
+# Airbus5717 <Abdussamadf350@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-04-15 14:29+0000\n"
-"Last-Translator: Nabeel20 <nabeelandnizam@gmail.com>\n"
+"PO-Revision-Date: 2020-05-05 14:01+0000\n"
+"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/"
"godot/ar/>\n"
"Language: ar\n"
@@ -49,12 +51,12 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
"&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr "نوع معامل خاطئ للدالة convert()، إستخدم ثوابت TYPE_*."
+msgstr "معامل type خاطئ لدالة Convert, استخدم احدى الثوابت من مجموعة TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
@@ -344,7 +346,7 @@ msgstr "Ø§Ù„ØªÙØ§Ù الحلقة المثبتة"
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key"
-msgstr "أدخل Ù…ÙØªØ§Ø­"
+msgstr "أدخل Ø§Ù„Ù…ÙØªØ§Ø­"
#: editor/animation_track_editor.cpp
msgid "Duplicate Key(s)"
@@ -448,7 +450,7 @@ msgstr "لا يمكن Ø¥Ø¶Ø§ÙØ© مقطع جديد بدون جذر"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
-msgstr ""
+msgstr "مقطع غير متواÙÙ‚ مع منحنى بيزير Bezier (خصائص ÙØ±Ø¹ÙŠØ© غير متواÙقة)"
#: editor/animation_track_editor.cpp
msgid "Add Bezier Track"
@@ -594,11 +596,11 @@ msgstr "إحد٠المحدد (المجموعة المختارة)"
#: editor/animation_track_editor.cpp
msgid "Go to Next Step"
-msgstr "إذهب إلي الخطوة التالية"
+msgstr "إذهب إلى الخطوة التالية"
#: editor/animation_track_editor.cpp
msgid "Go to Previous Step"
-msgstr "إذهب إلي الخطوة السابقة"
+msgstr "إذهب إلى الخطوة السابقة"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
@@ -671,7 +673,7 @@ msgstr "إختر المقاطع المراد نسخها"
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
-msgstr "أنسخ"
+msgstr "نسخ"
#: editor/animation_track_editor.cpp
msgid "Select All/None"
@@ -710,9 +712,8 @@ msgid "Line Number:"
msgstr "رقم الخط:"
#: editor/code_editor.cpp
-#, fuzzy
msgid "%d replaced."
-msgstr "تم إستبدال %d"
+msgstr "تم إستبدال %d."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
@@ -755,13 +756,13 @@ msgstr "تحديد التبويب البرمجي"
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
msgid "Zoom In"
-msgstr "تقريب"
+msgstr "تكبير"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
msgid "Zoom Out"
-msgstr "إبعاد"
+msgstr "تصغير"
#: editor/code_editor.cpp
msgid "Reset Zoom"
@@ -829,9 +830,8 @@ msgid "Extra Call Arguments:"
msgstr "وسائط إستدعاء إضاÙية :"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Receiver Method:"
-msgstr "إختر طريقة"
+msgstr "الدالة Ø§Ù„Ù…ÙØªÙ„قنة:"
#: editor/connections_dialog.cpp
msgid "Advanced"
@@ -871,14 +871,13 @@ msgstr "إشارة غير قادر على الاتصال"
#: editor/run_settings_dialog.cpp editor/settings_config_dialog.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Close"
-msgstr "اغلاق"
+msgstr "إغلاق"
#: editor/connections_dialog.cpp
msgid "Connect"
msgstr "وصل"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Signal:"
msgstr "إشارة:"
@@ -1103,7 +1102,7 @@ msgstr "Ù…ØªØµÙØ­ الموارد Ø£ÙˆØ±ÙØ§Ù†"
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/project_export.cpp
#: editor/project_settings_editor.cpp editor/scene_tree_dock.cpp
msgid "Delete"
-msgstr "مسح"
+msgstr "حذÙ"
#: editor/dependency_editor.cpp
msgid "Owns"
@@ -1214,9 +1213,8 @@ msgid "Error opening package file, not in ZIP format."
msgstr "حدث خطأ Ø¹Ù†Ø¯ÙØªØ­ مل٠الحزمة بسبب أن المل٠ليس ÙÙŠ صيغة \"ZIP\"."
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "%s (Already Exists)"
-msgstr "التحميل التلقائي '%s' موجود اصلا!"
+msgstr "%s (موجود أصلاً!)"
#: editor/editor_asset_installer.cpp
msgid "Uncompressing Assets"
@@ -1228,7 +1226,7 @@ msgstr "ÙØ´Ù„ استخراج Ø§Ù„Ù…Ù„ÙØ§Øª التالية من الحزمة:"
#: editor/editor_asset_installer.cpp
msgid "And %s more files."
-msgstr "%s مزيد من Ø§Ù„Ù…Ù„ÙØ§Øª"
+msgstr "Ùˆ %s أيضاً من Ø§Ù„Ù…Ù„ÙØ§Øª."
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package installed successfully!"
@@ -1240,9 +1238,8 @@ msgid "Success!"
msgstr "تم بشكل ناجح!"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Package Contents:"
-msgstr "المحتويات:"
+msgstr "محتويات الرزمة:"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
msgid "Install"
@@ -1436,18 +1433,16 @@ msgid "Must not collide with an existing engine class name."
msgstr "إسم غير صالح، يجب أن لا يتصادم مع أسم ÙØ¦Ø© خاصة بالمحرك."
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing built-in type name."
-msgstr "إسم غير صالح، يجب أن لا يتصادم مع الأسماء المبنية تلقائياً الموجودة."
+msgstr "اسم غير صالح يجب ألا يتضارب مع اسم موجود ومبني ضمناً بالمحرك."
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing global constant name."
-msgstr "إسم غير صالح، ييجب ألاّ يتصادم مع إسم موجود لثابت عمومي."
+msgstr "اإسم غير صالح، ييجب ألاّ يتضارب مع اسم ثابت عام موجود Ø³Ù„ÙØ§Ù‹."
#: editor/editor_autoload_settings.cpp
msgid "Keyword cannot be used as an autoload name."
-msgstr ""
+msgstr "لا يمكن استخدام الكلمة Ø§Ù„Ù…ÙØªØ§Ø­ÙŠØ© كاسم التحميل التلقائي."
#: editor/editor_autoload_settings.cpp
msgid "Autoload '%s' already exists!"
@@ -1478,7 +1473,6 @@ msgid "Rearrange Autoloads"
msgstr "اعادة ترتيب التحميلات التلقائية"
#: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid path."
msgstr "مسار غير صالح."
@@ -1540,9 +1534,8 @@ msgid "[unsaved]"
msgstr "[غير محÙوظ]"
#: editor/editor_dir_dialog.cpp
-#, fuzzy
msgid "Please select a base directory first."
-msgstr "من ÙØ¶Ù„Ùƒ حدد الوجهة الأساسية أولاً"
+msgstr "من ÙØ¶Ù„Ùƒ حدد الوجهة الأساسية أولاً."
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
@@ -1605,6 +1598,10 @@ msgid ""
"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
+"تتطلب المنصة Ø§Ù„Ù…Ø³ØªÙ‡Ø¯ÙØ© ضغط الرسومات النقشية 'ETC' texture ليرجع المعرّ٠إلى "
+"GLES2.\n"
+"مكّن 'استيراد Etc' ÙÙŠ إعدادات المشروع، أو عطّل 'تمكين التواÙÙ‚ الرجعي Ù„Ù„ØªØ¹Ø±ÙŠÙØ§Øª "
+"Driver Fallback Enabled'."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
@@ -1624,20 +1621,19 @@ msgstr "مل٠النموذج غير موجود:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
-msgstr ""
+msgstr "لا يمكن Ù„Ù…ÙØµØ¯Ø±Ø§Øª 32-bit التي تتضمن PCK أن تكون أكبر من 4 GiB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
-msgstr "معدل تلاثي الأبعاد"
+msgstr "محرر تلاثي الأبعاد"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Script Editor"
-msgstr "ÙØªØ­ Ù…ÙØ¹Ø¯Ù„ الكود"
+msgstr "محرر النص البرمجي"
#: editor/editor_feature_profile.cpp
msgid "Asset Library"
-msgstr "مكتبة الأصول"
+msgstr "مكتبة المÙلحقات"
#: editor/editor_feature_profile.cpp
msgid "Scene Tree Editing"
@@ -1649,92 +1645,81 @@ msgstr "رصي٠الاستيراد"
#: editor/editor_feature_profile.cpp
msgid "Node Dock"
-msgstr "رصي٠العقد"
+msgstr "رصي٠العÙقد"
#: editor/editor_feature_profile.cpp
msgid "FileSystem and Import Docks"
msgstr "رصي٠نظام Ø§Ù„Ù…Ù„ÙØ§Øª Ùˆ الاستيراد"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Erase profile '%s'? (no undo)"
-msgstr "إستبدال الكل"
+msgstr "مسح المل٠الشخصي '%s'؟ (لا تراجع)"
#: editor/editor_feature_profile.cpp
msgid "Profile must be a valid filename and must not contain '.'"
-msgstr ""
+msgstr "ينبغي أن يكون المل٠الشخصي اسم مل٠صالح وألّا يحتوي '.'"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Profile with this name already exists."
-msgstr "مل٠أو مجلد مع هذا الأسم موجود Ø¨Ø§Ù„ÙØ¹Ù„."
+msgstr "ملÙÙŒ بهذا الاسم موجود Ø¨Ø§Ù„ÙØ¹Ù„."
#: editor/editor_feature_profile.cpp
msgid "(Editor Disabled, Properties Disabled)"
-msgstr ""
+msgstr "(المحرر Ù…ÙØ¹Ø·Ù‘Ù„ØŒ الخاصيات Ù…ÙØ¹Ø·Ù‘لة)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Properties Disabled)"
-msgstr "خصائص Ùقط"
+msgstr "(الخاصيات Ù…ÙØ¹Ø·Ù‘لة)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Editor Disabled)"
-msgstr "معطّل"
+msgstr "(Ø§Ù„Ù…ÙØ­Ø±Ø± Ù…ÙØ¹Ø·Ù‘Ù„)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Class Options:"
-msgstr "وص٠الصÙ:"
+msgstr "إعدادات الص٠Class:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enable Contextual Editor"
-msgstr "ÙØªØ­ ÙÙŠ Ø§Ù„Ù…ÙØ¹Ø¯Ù„ التالي"
+msgstr "مكّن المحرر السياقي Contextual"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Properties:"
-msgstr "خصائص:"
+msgstr "الخصائص المÙمكّنة:"
#: editor/editor_feature_profile.cpp
msgid "Enabled Features:"
-msgstr "الميزات Ø§Ù„Ù…ÙØ¹Ù„Ø©:"
+msgstr "الميزات المÙمكّنة:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Classes:"
-msgstr "إبحث ÙÙŠ الأصناÙ"
+msgstr "الصÙو٠المÙمكّنة:"
#: editor/editor_feature_profile.cpp
msgid "File '%s' format is invalid, import aborted."
-msgstr ""
+msgstr "لاحقة المل٠'%s' غير صالحة، أجهض الإستيراد."
#: editor/editor_feature_profile.cpp
msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
-msgstr ""
+msgstr "الملÙ'%s' موجود Ø³Ù„ÙØ§Ù‹ØŒ قم بإزالته بداية قبل الاستيراد، أجهض الإستيراد."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Error saving profile to path: '%s'."
-msgstr "خطأ ÙÙŠ Ø­ÙØ¸ مجموعة البلاط!"
+msgstr "خطأ ÙÙŠ Ø­ÙØ¸ المل٠إلى المسار: '%s'."
#: editor/editor_feature_profile.cpp
msgid "Unset"
-msgstr ""
+msgstr "غير Ù…ÙØ­Ø¯Ø¯"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "النسخة الحالية:"
+msgstr "المل٠(النسخة) الحالية:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Make Current"
-msgstr "الحالي:"
+msgstr "إجعل الحالي"
#: editor/editor_feature_profile.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
@@ -1752,44 +1737,36 @@ msgid "Export"
msgstr "تصدير"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "خصائص:"
+msgstr "Ø§Ù„Ù…Ù„ÙØ§Øª Ø§Ù„Ù…ØªÙˆØ§ÙØ±Ø©:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Class Options"
-msgstr "وص٠الصÙ"
+msgstr "إعدادات الص٠Class"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "New profile name:"
-msgstr "إسم جديد:"
+msgstr "اسم مَل٠profile جديد:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Erase Profile"
-msgstr "زر Ø§Ù„ÙØ£Ø±Ø© الأيمن: مسح النقطة."
+msgstr "مسح الملÙ"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Godot Feature Profile"
-msgstr "إدارة قوالب التصدير"
+msgstr "Ù…Ù„ÙØ§Øª غودوت Ø§Ù„Ù…ÙØ±Ø´Ù‘حة"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Import Profile(s)"
-msgstr "%d مزيد من Ø§Ù„Ù…Ù„ÙØ§Øª"
+msgstr "استيراد الملÙ(Ø§Ù„Ù…Ù„ÙØ§Øª)"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Export Profile"
-msgstr "تصدير المشروع"
+msgstr "تصدير الملÙ"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Manage Editor Feature Profiles"
-msgstr "إدارة قوالب التصدير"
+msgstr "تدبير محرر Ø§Ù„Ù…Ù„ÙØ§Øª Ø§Ù„Ù…ÙØ±Ø´Ø­Ø©"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
@@ -1800,7 +1777,6 @@ msgid "File Exists, Overwrite?"
msgstr "المل٠موجود، إستبدال؟"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Select This Folder"
msgstr "حدد هذا المجلد"
@@ -1809,13 +1785,11 @@ msgid "Copy Path"
msgstr "نسخ المسار"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "Open in File Manager"
-msgstr "أظهر ÙÙŠ مدير Ø§Ù„Ù…Ù„ÙØ§Øª"
+msgstr "Ø§ÙØªØ­ ÙÙŠ مدير Ø§Ù„Ù…Ù„ÙØ§Øª"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/filesystem_dock.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Show in File Manager"
msgstr "أظهر ÙÙŠ مدير Ø§Ù„Ù…Ù„ÙØ§Øª"
@@ -1865,15 +1839,15 @@ msgstr "Ø­ÙØ¸ ملÙ"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
-msgstr "إرجع للخلÙ"
+msgstr "الرجوع للخلÙ"
#: editor/editor_file_dialog.cpp
msgid "Go Forward"
-msgstr "إذهب للأمام"
+msgstr "الذهاب للأمام"
#: editor/editor_file_dialog.cpp
msgid "Go Up"
-msgstr "إذهب للأعلي"
+msgstr "إذهب للأعلى"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
@@ -1893,51 +1867,43 @@ msgstr "مسار التركيز"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
-msgstr "حرك المÙÙØ¶Ù„Ø© للأعلي"
+msgstr "حرك المÙÙØ¶Ù„Ø© للأعلى"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Down"
msgstr "حرك المÙÙØ¶Ù„Ø© للأسÙÙ„"
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to previous folder."
-msgstr "إذهب إلي المجلد السابق"
+msgstr "إرجع إلي المجلد السابق."
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to next folder."
-msgstr "إذهب إلي المجلد السابق"
+msgstr "إذهب إلي المجلد التالي."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Go to parent folder."
-msgstr "إذهب إلي المجلد السابق"
+msgstr "إذهب إلي مجلد الأصل."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Refresh files."
-msgstr "إبحث ÙÙŠ الأصناÙ"
+msgstr "Ø­ÙŽØ¯Ù‘ÙØ« Ø§Ù„Ù…Ù„ÙØ§Øª."
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "(Un)favorite current folder."
-msgstr "لا يمكن إنشاء المجلد."
+msgstr "Ø¥Ø¶Ø§ÙØ© المجلد إلى Ø§Ù„Ù…ÙØ¶Ù„Ø© / إخراجه من Ø§Ù„Ù…ÙØ¶Ù„Ø©."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Toggle the visibility of hidden files."
-msgstr "أظهر Ø§Ù„Ù…Ù„ÙØ§Øª المخÙية"
+msgstr "إظهار/Ø¥Ø®ÙØ§Ø¡ Ø§Ù„Ù…Ù„ÙØ§Øª المخÙية."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "View items as a grid of thumbnails."
-msgstr "أظهر العناصر كشبكة من الصور المصغرة"
+msgstr "أظهر العناصر كشبكة من الصور المصغرة."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "View items as a list."
-msgstr "أظهر العناصر كقائمة"
+msgstr "أظهر العناصر كقائمة."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Directories & Files:"
@@ -1965,7 +1931,7 @@ msgstr "ÙØ­Øµ المصادر"
msgid ""
"There are multiple importers for different types pointing to file %s, import "
"aborted"
-msgstr ""
+msgstr "هناك عدة مستوردات مخصوصة لعدة أنواع حددت المل٠%s، أجهض الإستيراد"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
@@ -1989,14 +1955,12 @@ msgid "Inherited by:"
msgstr "مورث بواسطة:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Description"
-msgstr "الوصÙ:"
+msgstr "الوصÙ"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Online Tutorials"
-msgstr "الدورس علي الإنترنت:"
+msgstr "التعليمات على الإنترنت"
#: editor/editor_help.cpp
msgid "Properties"
@@ -2004,12 +1968,11 @@ msgstr "خصائص"
#: editor/editor_help.cpp
msgid "override:"
-msgstr ""
+msgstr "يتجاوز:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "default:"
-msgstr "Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ"
+msgstr "Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ:"
#: editor/editor_help.cpp
msgid "Methods"
@@ -2028,14 +1991,12 @@ msgid "Constants"
msgstr "الثوابت"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Property Descriptions"
-msgstr "وص٠الملكية:"
+msgstr "أوصا٠المÙلكية"
#: editor/editor_help.cpp
-#, fuzzy
msgid "(value)"
-msgstr "القيمة:"
+msgstr "(القيمة)"
#: editor/editor_help.cpp
msgid ""
@@ -2046,9 +2007,8 @@ msgstr ""
"المساهمة واحد [color=$color][url=$url]!"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Method Descriptions"
-msgstr "وص٠الطريقة:"
+msgstr "أوصا٠الدوال Method"
#: editor/editor_help.cpp
msgid ""
@@ -2061,16 +2021,15 @@ msgstr ""
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr "إبحث ÙÙŠ المساعدة"
+msgstr "ابحث ÙÙŠ المساعدة"
#: editor/editor_help_search.cpp
msgid "Case Sensitive"
msgstr "حساسة لحالة الأحرÙ"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Show Hierarchy"
-msgstr "أظهر المساعدات"
+msgstr "اظهر التراتبية"
#: editor/editor_help_search.cpp
msgid "Display All"
@@ -2097,9 +2056,8 @@ msgid "Properties Only"
msgstr "خصائص Ùقط"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Theme Properties Only"
-msgstr "خصائص"
+msgstr "خصائص الموضوع Theme Ùقط"
#: editor/editor_help_search.cpp
msgid "Member Type"
@@ -2107,35 +2065,31 @@ msgstr "نوع العضو"
#: editor/editor_help_search.cpp
msgid "Class"
-msgstr "الصنÙ"
+msgstr "الصÙ"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Method"
-msgstr "قائمة الطرق"
+msgstr "دالة"
#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Signal"
-msgstr "إشارات"
+msgstr "الإشاراة"
#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Constant"
msgstr "ثابت"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Property"
-msgstr "خصيصة:"
+msgstr "خاصية"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Theme Property"
-msgstr "خصائص الثمة"
+msgstr "خاصية الموضوع Theme"
#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
msgid "Property:"
-msgstr "خصيصة:"
+msgstr "خاصية:"
#: editor/editor_inspector.cpp
msgid "Set"
@@ -2143,16 +2097,15 @@ msgstr "مجموعة"
#: editor/editor_inspector.cpp
msgid "Set Multiple:"
-msgstr ""
+msgstr "تحديد التكرار:"
#: editor/editor_log.cpp
msgid "Output:"
-msgstr "الخرج:"
+msgstr "Ø§Ù„Ù…ÙØ®Ø±Ø¬Ø§Øª:"
#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Copy Selection"
-msgstr "Ø­Ø°Ù Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
+msgstr "نسخ Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
#: editor/editor_log.cpp editor/editor_network_profiler.cpp
#: editor/editor_profiler.cpp editor/editor_properties.cpp
@@ -2162,11 +2115,11 @@ msgstr "Ø­Ø°Ù Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Clear"
-msgstr "خالي"
+msgstr "مسح"
#: editor/editor_log.cpp
msgid "Clear Output"
-msgstr "أخلاء الخرج"
+msgstr "مسح Ø§Ù„Ù…ÙØ®Ø±Ø¬Ø§Øª"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
#: editor/editor_profiler.cpp
@@ -2175,22 +2128,20 @@ msgstr "إيقاÙ"
#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
-#, fuzzy
msgid "Start"
-msgstr "بدء!"
+msgstr "بدء"
#: editor/editor_network_profiler.cpp
msgid "%s/s"
-msgstr ""
+msgstr "%s/s"
#: editor/editor_network_profiler.cpp
-#, fuzzy
msgid "Down"
-msgstr "تنزيل"
+msgstr "أسÙÙ„"
#: editor/editor_network_profiler.cpp
msgid "Up"
-msgstr "Ùوق"
+msgstr "أعلى"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
msgid "Node"
@@ -2198,19 +2149,19 @@ msgstr "عقدة"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
-msgstr ""
+msgstr "نداء إجراء بعيد وادر"
#: editor/editor_network_profiler.cpp
msgid "Incoming RSET"
-msgstr ""
+msgstr "RSET (ناقل الحالة التمثيلية) وارد"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RPC"
-msgstr ""
+msgstr "نداء الإجراء البعيد RPC صادر"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RSET"
-msgstr ""
+msgstr "ناقل الحالة التمثيلية RSET صادر"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "New Window"
@@ -2218,7 +2169,7 @@ msgstr "Ù†Ø§ÙØ°Ø© جديدة"
#: editor/editor_node.cpp
msgid "Imported resources can't be saved."
-msgstr ""
+msgstr "لا يمكن Ø­ÙØ¸ الموارد المستوردة."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
@@ -2234,6 +2185,8 @@ msgid ""
"This resource can't be saved because it does not belong to the edited scene. "
"Make it unique first."
msgstr ""
+"لا يمكن Ø­ÙØ¸ هذا المورد كونه لا ينتمي إلى المشهد الذي تم تحريره. اجعله مميزاً "
+"بداية."
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
@@ -2253,7 +2206,7 @@ msgstr "خطأ خلال Ø§Ù„Ø­ÙØ¸."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Can't open '%s'. The file could have been moved or deleted."
-msgstr ""
+msgstr "لا يمكن ÙØªØ­ '%s'. ربما تم حذ٠المل٠أو نقله."
#: editor/editor_node.cpp
msgid "Error while parsing '%s'."
@@ -2285,13 +2238,15 @@ msgstr "ينشئ الصورة المصغرة"
#: editor/editor_node.cpp
msgid "This operation can't be done without a tree root."
-msgstr "هذه العملية لا يمكنها الإكتمال من غير جزر الشجرة."
+msgstr "هذه العملية لا يمكنها الإكتمال من غير جذر شجرة ."
#: editor/editor_node.cpp
msgid ""
"This scene can't be saved because there is a cyclic instancing inclusion.\n"
"Please resolve it and then attempt to save again."
msgstr ""
+"لا يمكن Ø­ÙØ¸ هذا المشهد كونخ يتضمن نمذجة دورية cyclic instancing.\n"
+"من ÙØ¶Ù„Ùƒ قم بحل تلك المشكلة ومن ثمَّ حاول من جديد."
#: editor/editor_node.cpp
msgid ""
@@ -2301,7 +2256,7 @@ msgstr "لا يمكن Ø­ÙØ¸ المشهد. على الأرجح لا يمكن Ø¥Ø
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "Can't overwrite scene that is still open!"
-msgstr ""
+msgstr "لا يمكن الكتابة عنوة (استبدال overwrite ) المشهد كونه ما زال Ù…ÙØªÙˆØ­Ø§Ù‹!"
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
@@ -2346,7 +2301,6 @@ msgstr ""
"هذا النظام."
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"This resource belongs to a scene that was instanced or inherited.\n"
"Changes to it won't be kept when saving the current scene."
@@ -2363,7 +2317,6 @@ msgstr ""
"الإستيراد ومن ثم أعد إستيراده."
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"This scene was imported, so changes to it won't be kept.\n"
"Instancing it or inheriting will allow making changes to it.\n"
@@ -2376,13 +2329,12 @@ msgstr ""
"هذا النظام."
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"This is a remote object, so changes to it won't be kept.\n"
"Please read the documentation relevant to debugging to better understand "
"this workflow."
msgstr ""
-"هذا المصدر ينتمي إلي مشهد قد تم إستيراده، إذا لا يمكن تعديله.\n"
+"هذا المصدر ينتمي إلي مشهد قد تم إستيراده، التعديلات لن ØªØ­ÙØ¸.\n"
"من ÙØ¶Ù„Ùƒ إقرأ التوثيق المرتبط بإستيراد المشاهد لكي تÙهم بشكل Ø£ÙØ¶Ù„ كيÙية عمل "
"هذا النظام."
@@ -2407,9 +2359,8 @@ msgid "Open Base Scene"
msgstr "ÙØªØ­ مشهد أساسي"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Quick Open..."
-msgstr "ÙØªØ­ سريع للمشهد..."
+msgstr "ÙØªØ­ سريع ..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
@@ -2428,13 +2379,12 @@ msgid "Save changes to '%s' before closing?"
msgstr "هل تريد Ø­ÙØ¸ التغييرات إلي'%s' قبل الإغلاق؟"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Saved %s modified resource(s)."
-msgstr "ÙØ´Ù„ تحميل المورد."
+msgstr "Ø­ÙØ¸Øª %s الموارد المعدلة."
#: editor/editor_node.cpp
msgid "A root node is required to save the scene."
-msgstr ""
+msgstr "يتطلب Ø­ÙØ¸ المشهد ØªÙˆØ§ÙØ± عÙقدة رئيسة."
#: editor/editor_node.cpp
msgid "Save Scene As..."
@@ -2494,7 +2444,7 @@ msgstr "تشغيل مشهد بسرعة..."
#: editor/editor_node.cpp
msgid "Quit"
-msgstr "خروج"
+msgstr "إنهاء"
#: editor/editor_node.cpp
msgid "Exit the editor?"
@@ -2535,9 +2485,8 @@ msgid "Close Scene"
msgstr "اغلاق المشهد"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Reopen Closed Scene"
-msgstr "اغلاق المشهد"
+msgstr "إعادة ÙØªØ­ المشهد"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
@@ -2553,19 +2502,19 @@ msgid "Unable to load addon script from path: '%s'."
msgstr "غير قادر علي تحميل كود Ø§Ù„Ø¥Ø¶Ø§ÙØ© من المسار: '%s'."
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
msgstr ""
-"غير قادر علي تحميل كود Ø§Ù„Ø¥Ø¶Ø§ÙØ© من المسار: '%s' الكود ليس ÙÙŠ وضع الأداة."
+"غير قادر علي تحميل كود Ø§Ù„Ø¥Ø¶Ø§ÙØ© من المسار: '%s' يبدو أن الكود يوجد Ùيه "
+"أخطاء , الرجاء مراجعة الكود."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
msgstr ""
"غير قادر علي تحميل كود Ø§Ù„Ø¥Ø¶Ø§ÙØ© من المسار: '%s' النوع الأساسي ليس Ø¥Ø¶Ø§ÙØ© "
-"Ù„Ù„Ù…ÙØ¹Ø¯Ù„."
+"Ø§Ù„Ù…ÙØ¹Ø¯Ù„."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
@@ -2638,24 +2587,20 @@ msgstr "Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ"
#: editor/editor_node.cpp editor/editor_properties.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
-#, fuzzy
msgid "Show in FileSystem"
msgstr "أظهر ÙÙŠ مدير Ø§Ù„Ù…Ù„ÙØ§Øª"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Play This Scene"
msgstr "تشغيل المشهد"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close Tab"
-msgstr "اغلاق"
+msgstr "اغلاق التبويب"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Undo Close Tab"
-msgstr "اغلاق"
+msgstr "تراجع عن ‭‬إغلاق التبويب"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
@@ -2663,12 +2608,11 @@ msgstr "أغلق الألسنة الاخرى"
#: editor/editor_node.cpp
msgid "Close Tabs to the Right"
-msgstr ""
+msgstr "أغلق التبويبات على اليمين"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close All Tabs"
-msgstr "اغلاق"
+msgstr "اغلاق جميع Ù†ÙˆØ§ÙØ° التبويب"
#: editor/editor_node.cpp
msgid "Switch Scene Tab"
@@ -2711,9 +2655,8 @@ msgid "Go to previously opened scene."
msgstr "اذهب الي المشهد Ø§Ù„Ù…ÙØªÙˆØ­ مسبقا."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Copy Text"
-msgstr "نسخ المسار"
+msgstr "نسخ النص"
#: editor/editor_node.cpp
msgid "Next tab"
@@ -2752,7 +2695,6 @@ msgid "Save Scene"
msgstr "Ø­ÙØ¸ المشهد"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save All Scenes"
msgstr "Ø­ÙØ¸ جميع المشاهد"
@@ -2776,7 +2718,7 @@ msgstr "تراجع"
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Redo"
-msgstr "إعادة"
+msgstr "إعادة تراجع"
#: editor/editor_node.cpp
msgid "Revert Scene"
@@ -2792,49 +2734,44 @@ msgid "Project"
msgstr "مشروع"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Project Settings..."
-msgstr "إعدادات المشروع"
+msgstr "إعدادات المشروع..."
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Version Control"
-msgstr "النسخة:"
+msgstr "التحكم ÙÙŠ الإصدار"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
-msgstr ""
+msgstr "إعداد التحكم بالنسخة"
#: editor/editor_node.cpp
msgid "Shut Down Version Control"
-msgstr ""
+msgstr "Ø¥Ø·ÙØ§Ø¡ التحكم بالنسخة Version Control"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Export..."
-msgstr "تصدير"
+msgstr "تصدير..."
#: editor/editor_node.cpp
msgid "Install Android Build Template..."
-msgstr ""
+msgstr "تحميل قالب البناء للأندرويد..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Project Data Folder"
-msgstr "ÙØªØ­ مدير المشروع؟"
+msgstr "ÙØªØ­ مجلد بيانات المشروع"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
msgstr "ادوات"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Orphan Resource Explorer..."
-msgstr "Ù…ØªØµÙØ­ الموارد Ø£ÙˆØ±ÙØ§Ù†"
+msgstr "Ù…ØªØµÙØ­ الموارد Ø£ÙˆØ±ÙØ§Ù†..."
#: editor/editor_node.cpp
msgid "Quit to Project List"
-msgstr "غادر الي قائمه المشاريع"
+msgstr "غادر إلى قائمه المشاريع"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
@@ -2931,56 +2868,48 @@ msgid "Editor"
msgstr "Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Editor Settings..."
-msgstr "إعدادات Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
+msgstr "إعدادات المحرّر"
#: editor/editor_node.cpp
msgid "Editor Layout"
msgstr "نسق Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "Ø­ÙØ¸ المشهد"
+msgstr "أخذ صورة للشاشة"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Screenshots are stored in the Editor Data/Settings Folder."
-msgstr "إعدادات Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
+msgstr "لقطات الشاشة تكون محÙوظة ÙÙŠ مجلّد البيانات/الإعدادت داخل المحرّر"
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
msgstr "إلغاء/ØªÙØ¹ÙŠÙ„ وضع الشاشة الكاملة"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Toggle System Console"
-msgstr "أظهر المود"
+msgstr "إظهار/Ø¥Ø®ÙØ§Ø¡ وحدة التحكم بالنظام"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Data/Settings Folder"
-msgstr "إعدادات Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
+msgstr "ÙØªØ­ مجلّد البيانات/الإعدادت المحرّر"
#: editor/editor_node.cpp
msgid "Open Editor Data Folder"
-msgstr ""
+msgstr "Ø§ÙØªØ­ مل٠بيانات المحرر"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Settings Folder"
-msgstr "إعدادات Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
+msgstr "ÙØªØ­ مجلّد إعدادات المحرّر"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Editor Features..."
-msgstr "إدارة قوالب التصدير"
+msgstr "إدارة ميّزات المحرّر"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Export Templates..."
-msgstr "إدارة قوالب التصدير"
+msgstr "إدارة قوالب التصدير..."
#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
@@ -3005,13 +2934,12 @@ msgid "Q&A"
msgstr "الأسئلة و الأجوبة"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "إعادة إستيراد"
+msgstr "إرسال تقرير عن bug أو خلل ÙÙŠ شيء ما"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "إرسال مستندات التغذية الراجعة Feedback"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3031,7 +2959,7 @@ msgstr "تشغيل"
#: editor/editor_node.cpp
msgid "Pause the scene execution for debugging."
-msgstr ""
+msgstr "إيقا٠جلسة المشهد من أجل تنقيح الكبوات البرمجية debugging."
#: editor/editor_node.cpp
msgid "Pause Scene"
@@ -3059,28 +2987,24 @@ msgstr "تشغيل المشهد المخصص"
#: editor/editor_node.cpp
msgid "Changing the video driver requires restarting the editor."
-msgstr ""
+msgstr "تعديل معرّ٠الÙيديو video driver يتطلب إعادة تشغيل المحرر."
#: editor/editor_node.cpp editor/project_settings_editor.cpp
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Save & Restart"
-msgstr "Ø­ÙØ¸ Ùˆ خروج"
+msgstr "Ø­ÙØ¸ Ùˆ إعادة تشغيل"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Spins when the editor window redraws."
-msgstr "يدور حينما Ù†Ø§ÙØ°Ø© Ø§Ù„Ù…ÙØ¹Ø¯Ù„ يتم إعادة دهانة!"
+msgstr "يدور حينما يتم إعادة رسم Ù†Ø§ÙØ°Ø© المحرّر"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "متواصل"
+msgstr "تحديث متواصل"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update When Changed"
-msgstr "تحديث التغييرات"
+msgstr "تحديث عند التغيير"
#: editor/editor_node.cpp
#, fuzzy
@@ -3096,9 +3020,8 @@ msgid "Inspector"
msgstr "Ù…ÙØ±Ø§Ù‚ب"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Expand Bottom Panel"
-msgstr "توسيع الكل"
+msgstr "توسيع التبويب السÙلي"
#: editor/editor_node.cpp
msgid "Output"
@@ -3110,12 +3033,11 @@ msgstr "لا ØªØ­ÙØ¸"
#: editor/editor_node.cpp
msgid "Android build template is missing, please install relevant templates."
-msgstr ""
+msgstr "قالب البناء الخاص بالأندرويد Ù…Ùقود، من ÙØ¶Ù„Ùƒ نزل قوالب ذات صلة."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Templates"
-msgstr "إدارة قوالب التصدير"
+msgstr "إدارة القوالب"
#: editor/editor_node.cpp
msgid ""
@@ -3127,6 +3049,13 @@ msgid ""
"the \"Use Custom Build\" option should be enabled in the Android export "
"preset."
msgstr ""
+"بهذه الطريقة سيتم إعداد المشروع الخاص بك لأجل نسخ بناء أندريد مخصوصة عن طريق "
+"تنزيل قوالب المصدر البرمجي ÙÙŠ \"res://android/build\".\n"
+"يمكنك تطبيق تعديلات الخاصة على نسخة البناء للحصول على حزمة تطبيق أندرويد APK "
+"معدّلة عند التصدير (زيادة Ù…Ùلحقات، تعديل مل٠AndroidManifest.xml إلخ..).\n"
+"ضع ÙÙŠ بالك أنه من أجل إنشاء نسخ بناء مخصوصة بدلاً من الحزم APKs المبنية Ø³Ù„ÙØ§Ù‹ØŒ "
+"ينبغي أن يكون إعداد \"استخدام بناء مخصص\" ممكناً ÙÙŠ إعدادات تصدير الأندرويد "
+"Android export preset."
#: editor/editor_node.cpp
msgid ""
@@ -3135,15 +3064,17 @@ msgid ""
"Remove the \"res://android/build\" directory manually before attempting this "
"operation again."
msgstr ""
+"إن قالب البناء الخاص بالأندرويد تم تنزيله Ø³Ù„ÙØ§Ù‹ لأجل هذا المشروع ولا يمكنه "
+"الكتابة Ùوق البيانات السابقة.\n"
+"قم بإزالة \"res://android/build\" يدوياً قبل الشروع بهذه العملية مرة أخرى."
#: editor/editor_node.cpp
msgid "Import Templates From ZIP File"
msgstr "إستيراد القوالب من مل٠مضغوط بصيغة Zip"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Template Package"
-msgstr "‌تصدير مدير القوالب"
+msgstr "رزمة القوالب"
#: editor/editor_node.cpp
msgid "Export Library"
@@ -3194,12 +3125,10 @@ msgid "Open the previous Editor"
msgstr "Ø¥ÙØªØ­ Ø§Ù„Ù…ÙØ¹Ø¯Ù„ السابق"
#: editor/editor_node.h
-#, fuzzy
msgid "Warning!"
-msgstr "تحذيرات"
+msgstr "تحذيرات!"
#: editor/editor_path.cpp
-#, fuzzy
msgid "No sub-resources found."
msgstr "لا مصدر للسطح تم تحديده."
@@ -3212,14 +3141,12 @@ msgid "Thumbnail..."
msgstr "الصورة المصغرة..."
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Main Script:"
-msgstr "ÙØªØ­ الكود"
+msgstr "النص البرمجي الأصلي :"
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Edit Plugin"
-msgstr "تعديل البولي"
+msgstr "تعديل Ø§Ù„Ø¥Ø¶Ø§ÙØ©"
#: editor/editor_plugin_settings.cpp
msgid "Installed Plugins:"
@@ -3243,9 +3170,8 @@ msgid "Status:"
msgstr "الحالة:"
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Edit:"
-msgstr "Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
+msgstr "تحرير:"
#: editor/editor_profiler.cpp
msgid "Measure:"
@@ -3277,7 +3203,7 @@ msgstr "ذاتي"
#: editor/editor_profiler.cpp
msgid "Frame #:"
-msgstr "اطار #:"
+msgstr "إطار #:"
#: editor/editor_profiler.cpp
msgid "Time"
@@ -3285,32 +3211,31 @@ msgstr "الوقت"
#: editor/editor_profiler.cpp
msgid "Calls"
-msgstr "ندائات"
+msgstr "إستدعاءات"
#: editor/editor_properties.cpp
-#, fuzzy
msgid "Edit Text:"
-msgstr "الأعضاء"
+msgstr "تحرير النص:"
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
-msgstr ""
+msgstr "ÙØ¹Ù‘ال"
#: editor/editor_properties.cpp
msgid "Layer"
-msgstr ""
+msgstr "طبقة"
#: editor/editor_properties.cpp
msgid "Bit %d, value %d"
-msgstr ""
+msgstr "Bit %d، القيمة %d"
#: editor/editor_properties.cpp
msgid "[Empty]"
-msgstr ""
+msgstr "[ÙØ§Ø±Øº]"
#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
msgid "Assign..."
-msgstr ""
+msgstr "إلحاق..."
#: editor/editor_properties.cpp
#, fuzzy
@@ -3322,12 +3247,15 @@ msgid ""
"The selected resource (%s) does not match any type expected for this "
"property (%s)."
msgstr ""
+"يلا يتطابق نوع المورد المختار (%s) مع أي نوع متوقع لأجل هذه الخاصية (%s)."
#: editor/editor_properties.cpp
msgid ""
"Can't create a ViewportTexture on resources saved as a file.\n"
"Resource needs to belong to a scene."
msgstr ""
+"لا يمكن إنشاء نقشة إطار العرض ViewportTexture على مورد تم Ø­ÙØ¸Ù‡ كملÙ.\n"
+"ينبغي أن ينتمي المورد إلى مشهد ما."
#: editor/editor_properties.cpp
msgid ""
@@ -3336,14 +3264,18 @@ msgid ""
"Please switch on the 'local to scene' property on it (and all resources "
"containing it up to a node)."
msgstr ""
+"لا يمكن إنشاء نقشة إطار العرض ViewportTexture اعتماداً على هذا المصدر كونه "
+"ليس محلياً بالنسبة للمشهد.\n"
+"قم بتشغيل خاصية 'محلي بالنسبة للمشهد local to scene' لذلك المورد (ولكل "
+"الموارد التي تضمنتها وصولاً إلى العقدة)."
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Pick a Viewport"
-msgstr ""
+msgstr "اختر إطار عرض"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New Script"
-msgstr ""
+msgstr "نص برمجي جديد"
#: editor/editor_properties.cpp editor/scene_tree_dock.cpp
#, fuzzy
@@ -3352,7 +3284,7 @@ msgstr "ÙØªØ­ الكود"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New %s"
-msgstr ""
+msgstr "%s جديدة"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Make Unique"
@@ -3370,7 +3302,7 @@ msgstr "إجعلة مميزاً"
#: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Paste"
-msgstr ""
+msgstr "لصق"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Convert To %s"
@@ -3378,20 +3310,20 @@ msgstr "تحويل إلي %s"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Selected node is not a Viewport!"
-msgstr ""
+msgstr "العÙقدة المختارة ليست إطار عرض Viewport!"
#: editor/editor_properties_array_dict.cpp
msgid "Size: "
-msgstr ""
+msgstr "الحجم: "
#: editor/editor_properties_array_dict.cpp
msgid "Page: "
-msgstr ""
+msgstr "Ø§Ù„ØµÙØ­Ø©: "
#: editor/editor_properties_array_dict.cpp
#: editor/plugins/theme_editor_plugin.cpp
msgid "Remove Item"
-msgstr ""
+msgstr "إزالة عنصر"
#: editor/editor_properties_array_dict.cpp
#, fuzzy
@@ -3405,7 +3337,7 @@ msgstr "إسم جديد:"
#: editor/editor_properties_array_dict.cpp
msgid "Add Key/Value Pair"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© زوج Ù…ÙØªØ§Ø­/قيمة"
#: editor/editor_run_native.cpp
msgid ""
@@ -3445,7 +3377,7 @@ msgstr "إختيار عقدة(عقد) للإستيراد"
#: editor/editor_sub_scene.cpp editor/project_manager.cpp
msgid "Browse"
-msgstr ""
+msgstr "ØªØµÙØ­"
#: editor/editor_sub_scene.cpp
msgid "Scene Path:"
@@ -3475,7 +3407,7 @@ msgstr "تنزيل"
#: editor/export_template_manager.cpp
msgid "Official export templates aren't available for development builds."
-msgstr ""
+msgstr "قوالب التصدير الرسمية غير مدعومة لأجل البناء الخاص بالتطوير."
#: editor/export_template_manager.cpp
msgid "(Missing)"
@@ -3520,11 +3452,13 @@ msgstr "يستورد:"
#: editor/export_template_manager.cpp
msgid "Error getting the list of mirrors."
-msgstr ""
+msgstr "هناك خطأ ÙÙŠ جلب قائمة المرايا mirrors."
#: editor/export_template_manager.cpp
msgid "Error parsing JSON of mirror list. Please report this issue!"
msgstr ""
+"حدث خطأ ÙÙŠ ÙÙƒ (ØªÙØ³ÙŠØ± parsing) مل٠JSON الخاص بقائمة المرايا. من ÙØ¶Ù„Ùƒ بلّغ عن "
+"هذه المشكلة!"
#: editor/export_template_manager.cpp
msgid ""
@@ -3576,6 +3510,8 @@ msgid ""
"Templates installation failed.\n"
"The problematic templates archives can be found at '%s'."
msgstr ""
+"أخÙÙ‚ تنصيب القوالب.\n"
+"يمكن إيجاد أرشي٠القوالب المعطوبة ÙÙŠ '%s'."
#: editor/export_template_manager.cpp
#, fuzzy
@@ -3860,7 +3796,7 @@ msgstr "مل٠أو مجلد مع هذا الأسم موجود Ø¨Ø§Ù„ÙØ¹Ù„."
#: editor/filesystem_dock.cpp
msgid "Overwrite"
-msgstr ""
+msgstr "الكتابة Ø§Ù„Ù…ÙØªØ±Ø§ÙƒØ¨Ø© Overwrite"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3869,7 +3805,7 @@ msgstr "Ø­ÙØ¸ المشهد"
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "Create Script"
-msgstr ""
+msgstr "إنشاء نص برمجي"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -3896,15 +3832,17 @@ msgid ""
"Include the files with the following extensions. Add or remove them in "
"ProjectSettings."
msgstr ""
+"يتضمن Ø§Ù„Ù…Ù„ÙØ§Øª ذات Ø§Ù„Ø¥Ø¶Ø§ÙØ§Øª التالية. قم Ø¨Ø¥Ø¶Ø§ÙØªÙ‡Ù… أو إزالتهم ÙÙŠ إعدادات "
+"المشروع."
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find..."
-msgstr ""
+msgstr "ابحث..."
#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp
msgid "Replace..."
-msgstr ""
+msgstr "استبدال..."
#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp
msgid "Cancel"
@@ -3975,7 +3913,7 @@ msgstr "Ø¥Ø¶Ø§ÙØ© إلي مجموعة"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
#: editor/scene_tree_editor.cpp
msgid "Filter nodes"
-msgstr ""
+msgstr "العÙقد Ø§Ù„Ù…ÙØ±Ø´Ø­Ø© Filter nodes"
#: editor/groups_editor.cpp
#, fuzzy
@@ -3984,7 +3922,7 @@ msgstr "Ø¥Ø¶Ø§ÙØ© إلي مجموعة"
#: editor/groups_editor.cpp
msgid "Empty groups will be automatically removed."
-msgstr ""
+msgstr "ستزال المجموعات Ø§Ù„ÙØ§Ø±ØºØ© بصورة تلقائية."
#: editor/groups_editor.cpp
#, fuzzy
@@ -4074,9 +4012,8 @@ msgid "Saving..."
msgstr "جاري Ø§Ù„Ø­ÙØ¸..."
#: editor/import_dock.cpp
-#, fuzzy
msgid "%d Files"
-msgstr " Ù…Ù„ÙØ§Øª"
+msgstr "%d Ù…Ù„ÙØ§Øª"
#: editor/import_dock.cpp
msgid "Set as Default for '%s'"
@@ -4101,16 +4038,16 @@ msgstr "إعادة إستيراد"
#: editor/import_dock.cpp
msgid "Save Scenes, Re-Import, and Restart"
-msgstr ""
+msgstr "Ø§Ø­ÙØ¸ المشاهد، إعادة-الإستيراد، وإعادة التشغيل"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
-msgstr ""
+msgstr "يتطلب تعديل نوع Ø§Ù„Ù…Ù„ÙØ§Øª المستوردة إعادة تشغيل المحرر."
#: editor/import_dock.cpp
msgid ""
"WARNING: Assets exist that use this resource, they may stop loading properly."
-msgstr ""
+msgstr "تحذير: هناك Ù…Ùلحقات تستخدم هذا المورد، ربما سيتوق٠تحميلها بشكل صحيح."
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
@@ -4219,19 +4156,19 @@ msgstr "Ø¥Ø¶Ø§ÙØ§Øª"
#: editor/plugin_config_dialog.cpp
msgid "Subfolder:"
-msgstr ""
+msgstr "المجلد Ø§Ù„ÙØ±Ø¹ÙŠ:"
#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp
msgid "Language:"
-msgstr ""
+msgstr "اللغة:"
#: editor/plugin_config_dialog.cpp
msgid "Script Name:"
-msgstr ""
+msgstr "اسم النص البرمجي:"
#: editor/plugin_config_dialog.cpp
msgid "Activate now?"
-msgstr ""
+msgstr "Ø§Ù„ØªÙØ¹ÙŠÙ„ الآن؟"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/polygon_2d_editor_plugin.cpp
@@ -4320,6 +4257,7 @@ msgstr "تغيير وقت الدمج"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "This type of node can't be used. Only root nodes are allowed."
msgstr ""
+"لا يمكن استخدام هذا النوع من العÙقد. Ùقط العÙقد الرئيسة root nodes مسموحة."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4334,13 +4272,12 @@ msgid "Add Animation Point"
msgstr "أض٠حركة"
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace1D Point"
-msgstr "مسح البولي والنقطة"
+msgstr "إزالة نقطة BlendSpace1D"
#: editor/plugins/animation_blend_space_1d_editor.cpp
msgid "Move BlendSpace1D Node Point"
-msgstr ""
+msgstr "حرك نقطعة العÙقدة BlendSpace1D"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4350,95 +4287,92 @@ msgid ""
"AnimationTree is inactive.\n"
"Activate to enable playback, check node warnings if activation fails."
msgstr ""
+"شجرة الرسومات المتحركة غير ÙØ¹Ø§Ù„Ø©.\n"
+"ÙØ¹Ù„ها لتتمكن من التشغيل playbackØŒ تÙقد التنبيه الذي تصدره العÙقدة إن ÙØ´Ù„ "
+"Ø§Ù„ØªÙØ¹ÙŠÙ„."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Set the blending position within the space"
-msgstr ""
+msgstr "حدد مكان الخلط blending position ضمن Ø§Ù„ÙØ±Ø§Øº"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Select and move points, create points with RMB."
-msgstr ""
+msgstr "حدد وحرك النقاط، أنشئ النقاط باستخدام RMB."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
+#, fuzzy
msgid "Enable snap and show grid."
-msgstr ""
+msgstr "تمكين المحاذاة وإظهار الشبكة."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Point"
-msgstr ""
+msgstr "نقطة"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Open Editor"
-msgstr "ÙØªØ­ Ø§Ù„Ù…ÙØ¹Ø¯Ù„ 2D"
+msgstr "ÙØªØ­ Ø§Ù„Ù…ÙØ­Ø±Ø± ثنائي الأبعاد 2D"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Open Animation Node"
-msgstr "عقدة الحركة"
+msgstr "ÙØªØ­ عÙقدة الرسم المتحرك Animation"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Triangle already exists."
-msgstr "خطأ: إسم الحركة موجود Ø¨Ø§Ù„ÙØ¹Ù„!"
+msgstr "المثلثات موجودة Ø³Ù„ÙØ§Ù‹."
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Add Triangle"
-msgstr "Ø¥Ø¶Ø§ÙØ© مسار"
+msgstr "Ø¥Ø¶Ø§ÙØ© مثلث"
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace2D Limits"
-msgstr "تغيير وقت الدمج"
+msgstr "تغيير حدود(إمكانيات) BlendSpace2D \"الدمج_Ø§Ù„ÙØ¶Ø§Ø¦ÙŠ_ثنائي Ø§Ù„Ø¨ÙØ¹Ø¯\""
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Change BlendSpace2D Labels"
-msgstr "تغيير وقت الدمج"
+msgstr "تعديل لصاقات BlendSpace2D \"الدمج Ø§Ù„ÙØ¶Ø§Ø¦ÙŠ Ø«Ù†Ø§Ø¦ÙŠ Ø§Ù„Ø¨ÙØ¹Ø¯\""
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Remove BlendSpace2D Point"
-msgstr "مسح البولي والنقطة"
+msgstr "إزالة نقاط الدمج Ø§Ù„ÙØ¶Ø§Ø¦ÙŠ Ø«Ù†Ø§Ø¦ÙŠ Ø§Ù„Ø¨ÙØ¹Ø¯ BlendSpace2D"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Remove BlendSpace2D Triangle"
-msgstr ""
+msgstr "إزالة مثلث الدمج Ø§Ù„ÙØ¶Ø§Ø¦ÙŠ Ø«Ù†Ø§Ø¦ÙŠ Ø§Ù„Ø¨ÙØ¹Ø¯ BlendSpace2D"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "BlendSpace2D does not belong to an AnimationTree node."
msgstr ""
+"إن BlendSpace2D لا ينتمي إلى عÙقدة شجرة الرسومات المتحركة AnimationTree."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "No triangles exist, so no blending can take place."
-msgstr ""
+msgstr "لا وجود لأي من المثلثات، لذا لا يمكن أن يتم الخلط."
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Toggle Auto Triangles"
-msgstr "تبديل التحميل التلقائي العام"
+msgstr "ØªÙØ¹ÙŠÙ„ المثلثات التلقائية"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Create triangles by connecting points."
-msgstr ""
+msgstr "إنشاء المثلثات عن طريق وصل النقاط."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Erase points and triangles."
-msgstr ""
+msgstr "مسح النقط والمثلثات."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Generate blend triangles automatically (instead of manually)"
-msgstr ""
+msgstr "توليد مثلثات دمج بصورة تلقائية (بدلاً من اليدوية)"
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -4446,78 +4380,73 @@ msgid "Blend:"
msgstr "الدمج:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Parameter Changed"
-msgstr "تحديث التغييرات"
+msgstr "لقد تم تغيير المَعلم"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "Edit Filters"
-msgstr "تعديل المصاÙÙŠ"
+msgstr "تعديل Ø§Ù„Ù…ÙØ±Ø´Ø­Ø§Øª"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Output node can't be added to the blend tree."
-msgstr ""
+msgstr "لا يمكن Ø¥Ø¶Ø§ÙØ© عÙقدة المخرجات إلى شجرة الدمج."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Add Node to BlendTree"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© عÙقدة إلى شجرة الدمج BlendTree"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Node Moved"
-msgstr "وضع التحريك"
+msgstr "لقد تحركت العÙقدة"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Unable to connect, port may be in use or connection may be invalid."
msgstr ""
+"غير قادر على الاتصال، ربما البوابة قيد الاستخدام أو أن الإتصال غير صالح."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Nodes Connected"
-msgstr "متصل"
+msgstr "العÙقد متصلة"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Nodes Disconnected"
-msgstr "غير متصل"
+msgstr "العÙقد غير متصلة"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Set Animation"
-msgstr "صورة متحركة"
+msgstr "تحديد الرسومية المتحركة"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Delete Node"
-msgstr "إنشاء عقدة"
+msgstr "حذ٠العÙقدة"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/scene_tree_dock.cpp
msgid "Delete Node(s)"
-msgstr ""
+msgstr "حذ٠عÙقدة (عÙقد)"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Filter On/Off"
-msgstr "تمكين/إيقا٠هذا المسار."
+msgstr "تعديل Ø§Ù„Ù…ÙØ±Ø´Ø­Ø§Øª تشغيل/إيقاÙ"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Change Filter"
-msgstr "تغيير خط الحركة"
+msgstr "تغيير Ø§Ù„Ù…ÙØ±Ø´Ø­ Filter"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "No animation player set, so unable to retrieve track names."
msgstr ""
+"لم يتم تحديد أي من الرسومات المتحركة للاعب، لذا لا يمكن استرجاع أسماء "
+"المقاطع."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Player path set is invalid, so unable to retrieve track names."
-msgstr ""
+msgstr "المسار المحدد للاعب غير مناسب، لا يمكن استرجاع أسماء المقاطع."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
@@ -4525,43 +4454,39 @@ msgid ""
"Animation player has no valid root node path, so unable to retrieve track "
"names."
msgstr ""
+"الرسومات المتحركة الخاصة باللاعب لا تملك مسار عÙقدة صالح، غير قادر على "
+"استرجاع أسماء المقاطع."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Anim Clips"
-msgstr "مقاطع الرسوم المتحركة:"
+msgstr "مقاطع الرسوم المتحركة"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Audio Clips"
-msgstr "مقاطع صوتية:"
+msgstr "مقاطع صوتية"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Functions"
-msgstr "الإعدادات:"
+msgstr "الوظائ٠البرمجية"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Node Renamed"
-msgstr "إسم العقدة:"
+msgstr "العÙقدة معادة التسمية"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add Node..."
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© عÙقدة..."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
-#, fuzzy
msgid "Edit Filtered Tracks:"
-msgstr "تعديل المصاÙÙŠ"
+msgstr "تحرير المقاطع Ø§Ù„Ù…ÙØ±Ø´Ø­Ø© Filtered Tracks:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Enable Filtering"
-msgstr "تغيير خط الحركة"
+msgstr "تمكين الترشيح Filtering"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Toggle Autoplay"
@@ -4621,27 +4546,24 @@ msgid "Duplicate Animation"
msgstr "تكرير الحركة"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to copy!"
-msgstr "خطأ: لا حركة لنسخها!"
+msgstr "لا حركة رسومية لنسخها!"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation resource on clipboard!"
-msgstr "خطأ: لا مصدر حركة علي Ø§Ù„Ø­Ø§ÙØ¸Ø©!"
+msgstr "لا يوجد مورد لرسومية متحركة ÙÙŠ Ø§Ù„Ø­Ø§ÙØ¸Ø© clipboard!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Pasted Animation"
-msgstr "حركة Ù…Ùلصقة"
+msgstr "الحركة الرسومية المÙلصقة"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Paste Animation"
-msgstr "لصق الحركة"
+msgstr "لصق الرسوم المتحركة"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "No animation to edit!"
-msgstr "خطأ: لا حركة لتعديلها!"
+msgstr "لا رسومات متحركة لتحريرها!"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Play selected animation backwards from current pos. (A)"
@@ -4680,14 +4602,12 @@ msgid "Animation"
msgstr "صورة متحركة"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Edit Transitions..."
-msgstr "تحويلات"
+msgstr "تحرير الانتقالات..."
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Open in Inspector"
-msgstr "Ù…ÙØ±Ø§Ù‚ب"
+msgstr "Ø§ÙØªØ­ ÙÙŠ Ø§Ù„Ù…ÙØªØµÙØ­"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Display list of animations in player."
@@ -4702,9 +4622,8 @@ msgid "Enable Onion Skinning"
msgstr "ØªÙØ¹ÙŠÙ„ تقشير البصل"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Onion Skinning Options"
-msgstr "تقشير البصل"
+msgstr "إعدادت Ø´ÙØ§Ùية طبقات البصل"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Directions"
@@ -4724,7 +4643,7 @@ msgstr "العمق"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "1 step"
-msgstr "الخطوة 1"
+msgstr "خطوة واحدة"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "2 steps"
@@ -4747,9 +4666,8 @@ msgid "Include Gizmos (3D)"
msgstr "تضمين جيزموس (3D)"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Pin AnimationPlayer"
-msgstr "لصق الحركة"
+msgstr "تثبيت Ù…ÙØ´ØºÙ‘Ù„ الرسوميات المتحركة"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Create New Animation"
@@ -4779,48 +4697,45 @@ msgid "Cross-Animation Blend Times"
msgstr "وقت الدمج عبر الحركة"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Move Node"
-msgstr "وضع التحريك"
+msgstr "تحريك العÙقدة"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition exists!"
-msgstr "تحول"
+msgstr "الإنتقال موجود Ø³Ù„ÙØ§Ù‹!"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Add Transition"
-msgstr "تحول"
+msgstr "Ø¥Ø¶Ø§ÙØ© انتقال"
#: editor/plugins/animation_state_machine_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Node"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© عÙقدة"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "End"
-msgstr ""
+msgstr "النهاية"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Immediate"
-msgstr ""
+msgstr "Ùوري"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Sync"
-msgstr ""
+msgstr "مزامنة"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "At End"
-msgstr ""
+msgstr "ÙÙŠ النهاية"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Travel"
-msgstr ""
+msgstr "Ø§Ù„Ø³ÙØ±"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Start and end nodes are needed for a sub-transition."
-msgstr ""
+msgstr "عÙقد البداية والنهاية مطلوبة لأجل الانتقال الجزيئ sub-transition."
#: editor/plugins/animation_state_machine_editor.cpp
#, fuzzy
@@ -4839,7 +4754,7 @@ msgstr "عقدة التنقل"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set Start Node (Autoplay)"
-msgstr ""
+msgstr "تحديد عÙقدة البداية (التشغيل التلقائي)"
#: editor/plugins/animation_state_machine_editor.cpp
msgid ""
@@ -4847,6 +4762,9 @@ msgid ""
"RMB to add new nodes.\n"
"Shift+LMB to create connections."
msgstr ""
+"اختر وحرّك العÙقد.\n"
+"RMB (زر Ø§Ù„ÙØ£Ø±Ø© الأيمن) Ù„Ø¥Ø¶Ø§ÙØ© عÙقد جديدة.\n"
+"LMB + Shift (زر Ø§Ù„ÙØ£Ø±Ø© الأيسر) لإنشاء الوصلات."
#: editor/plugins/animation_state_machine_editor.cpp
#, fuzzy
@@ -4866,10 +4784,13 @@ msgstr "ازالة المسار المحدد."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Toggle autoplay this animation on start, restart or seek to zero."
msgstr ""
+"تبديل (نعم/لا) التشغيل التلقائي لهذا الرسم المتحرك ليشتغل، يعيد التشغيل، أو "
+"يسعى Ù„Ù„ØµÙØ±."
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set the end animation. This is useful for sub-transitions."
msgstr ""
+"تحديد الرسومية المتحركة الخاصة بالنهاية. سيكون ذلك Ù…Ùيداً للحركات Ø§Ù„ÙØ±Ø¹ÙŠØ©."
#: editor/plugins/animation_state_machine_editor.cpp
#, fuzzy
@@ -5062,7 +4983,7 @@ msgstr "لا يمكن المسح:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Write error."
-msgstr ""
+msgstr "كتابة خطأ."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Request failed, too many redirects"
@@ -5144,19 +5065,19 @@ msgstr "تحميل هذا الأصل قيد التنÙيذ أصلاً!"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Recently Updated"
-msgstr ""
+msgstr "Ø­ÙØ¯Ù‘Ø« منذ ÙØªØ±Ø© وجيزة"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Least Recently Updated"
-msgstr ""
+msgstr "آخر تحديث قريب الأمد"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (A-Z)"
-msgstr ""
+msgstr "الاسم (أل٠بائياً)"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (Z-A)"
-msgstr ""
+msgstr "الاسم (ترتيب أل٠بائي معكوس)"
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
@@ -5184,7 +5105,7 @@ msgstr "التالي"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Last"
-msgstr ""
+msgstr "الأخير"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "All"
@@ -5192,7 +5113,7 @@ msgstr "الكل"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "No results for \"%s\"."
-msgstr ""
+msgstr "لا نتائج من أجل \"%s\"."
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
@@ -5263,12 +5184,12 @@ msgstr "لا يمكن انشاء خرائط الضوء, تاكد من ان الÙ
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
-msgstr "اعداد خرائط الضوء"
+msgstr "إعداد خرائط الضوء"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Preview"
-msgstr "إستعراض"
+msgstr "استعراض"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Configure Snap"
@@ -5284,12 +5205,11 @@ msgstr "خطوة الشبكة:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Primary Line Every:"
-msgstr ""
+msgstr "الأخط الأولي ÙƒÙÙ„:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "steps"
-msgstr "خطوتان"
+msgstr "خطوات"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Offset:"
@@ -5300,42 +5220,34 @@ msgid "Rotation Step:"
msgstr "خطوة الدوران:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale Step:"
-msgstr "تكبير/تصغير:"
+msgstr "خطوة التحجيم:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move Vertical Guide"
msgstr "تحريك الموجه العمودي"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Vertical Guide"
msgstr "إنشاء موجه عمودي جديد"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Remove Vertical Guide"
msgstr "مسح الموجه العمودي"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move Horizontal Guide"
msgstr "تحريك الموجه الأÙقي"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Horizontal Guide"
msgstr "إنشاء موجه Ø£Ùقي جديد"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Remove Horizontal Guide"
msgstr "مسح الموجه الأÙقي"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Horizontal and Vertical Guides"
msgstr "إنشاء موجه عمودي وأÙقي جديد"
@@ -5378,85 +5290,76 @@ msgid ""
"When active, moving Control nodes changes their anchors instead of their "
"margins."
msgstr ""
+"عندما يكون ÙØ¹Ø§Ù„اً، إن تحريك عÙقد التحكم سيغير نقطة التثبيت anchors الخاص بها "
+"بدلاً من الهوامش."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Top Left"
-msgstr "وضع التدوير"
+msgstr "ÙÙŠ الأعلى يساراً"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Top Right"
-msgstr "وضع التدوير"
+msgstr "ÙÙŠ الأعلى يميناً"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Bottom Right"
-msgstr "وضع التدوير"
+msgstr "ÙÙŠ الأسÙÙ„ يميناً"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Bottom Left"
-msgstr "وضع التدوير"
+msgstr "ÙÙŠ الأسÙÙ„ يساراً"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Left"
-msgstr "Ù†ØµÙ Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
+msgstr "ÙÙŠ المنتص٠يساراً"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Top"
-msgstr "Ù†ØµÙ Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
+msgstr "ÙÙŠ أعلى المنتصÙ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Right"
-msgstr "وضع التدوير"
+msgstr "ÙÙŠ المنتص٠يميناً"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Center Bottom"
-msgstr "Ù†ØµÙ Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
+msgstr "ÙÙŠ أسÙÙ„ المنتصÙ"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center"
-msgstr ""
+msgstr "المنتصÙ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Left Wide"
-msgstr "الخط الشمالي"
+msgstr "بالعرض يساراً"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Top Wide"
-msgstr ""
+msgstr "بالعرض بالأعلى"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Right Wide"
-msgstr "الخط اليميني"
+msgstr "بالعرض يميناً"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Bottom Wide"
-msgstr ""
+msgstr "بالعرض بالأسÙÙ„"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "VCenter Wide"
-msgstr ""
+msgstr "بالعرض بالمنتص٠شاقولياً"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "HCenter Wide"
-msgstr ""
+msgstr "بالعرض بالمنتص٠أÙقياً"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Full Rect"
-msgstr ""
+msgstr "على كامل المستطيل"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Keep Ratio"
-msgstr "نسبة التكبير:"
+msgstr "نسبة التكبير"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
@@ -5476,6 +5379,8 @@ msgid ""
"Game Camera Override\n"
"Overrides game camera with editor viewport camera."
msgstr ""
+"تجاوز كاميرا اللعبة.\n"
+"تجاوز كاميرا اللعبة عن طريق كاميرا إطار العرض ÙÙŠ المحرر."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5483,48 +5388,44 @@ msgid ""
"Game Camera Override\n"
"No game instance running."
msgstr ""
+"تجاوز كاميرا اللعبة.\n"
+"ليس هناك لعبة منمذجة قيد التشغيل."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Lock Selected"
-msgstr "حدد"
+msgstr "Ø­ÙØ¯Ø¯ القÙÙ„"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Unlock Selected"
-msgstr ""
+msgstr "Ø­ÙØ¯Ø¯ إلغاء القÙÙ„"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Group Selected"
-msgstr "Ø­Ø°Ù Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
+msgstr "Ø­ÙØ¯Ø¯ التجميع"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Ungroup Selected"
-msgstr "Ø­Ø°Ù Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
+msgstr "Ø­ÙØ¯Ø¯ إلغاء التجميع"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Paste Pose"
msgstr "لصق الوضع"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Guides"
-msgstr "إخلاء الوضع"
+msgstr "مسح الموجهات"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Custom Bone(s) from Node(s)"
-msgstr "أنشئ نقاط إنبعاث من الشبكة"
+msgstr "إنشاء عظمة (عظام) مخصوصة من عÙقدة (عÙقد)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Bones"
-msgstr "إخلاء الوضع"
+msgstr "مسح العظام"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Make IK Chain"
@@ -5579,9 +5480,8 @@ msgstr "وضع التدوير"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Scale Mode"
-msgstr "تحديد الوضع"
+msgstr "وضع التحجيم"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5601,91 +5501,77 @@ msgid "Pan Mode"
msgstr "وضع السحب"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Ruler Mode"
-msgstr "تحديد الوضع"
+msgstr "وضع المسطرة"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Toggle smart snapping."
-msgstr "إلغاء/ØªÙØ¹ÙŠÙ„ الكبس"
+msgstr "إلغاء/ØªÙØ¹ÙŠÙ„ محاذاة الشبكة بذكاء."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Smart Snap"
-msgstr "إستخدم الكبس"
+msgstr "استخدام المحاذاة الذكية"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Toggle grid snapping."
-msgstr "إلغاء/ØªÙØ¹ÙŠÙ„ الكبس"
+msgstr "إلغاء/ØªÙØ¹ÙŠÙ„ المحاذاة للشبكة."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Grid Snap"
-msgstr "إستخدم الكبس"
+msgstr "استخادم المحاذاة للشبكة"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snapping Options"
-msgstr "إعدادات الكبس"
+msgstr "إعدادت المحاذاة"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Rotation Snap"
-msgstr "إستعمال كبس التدوير"
+msgstr "استعمال محاذاة التدوير"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Scale Snap"
-msgstr "إستخدم الكبس"
+msgstr "استخدام محاذاة التحجيم"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
-msgstr "نسبية الكبس"
+msgstr "نسبية المحاذاة"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Pixel Snap"
msgstr "إستخدام كبس البكسل"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Smart Snapping"
-msgstr "الكبس الذكي"
+msgstr "المحاذاة الذكية"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Configure Snap..."
-msgstr "تعديل الكبس..."
+msgstr "تعديل المحاذاة..."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Parent"
-msgstr "الكبس إلي الطÙÙ„"
+msgstr "المحاذاة بالنسبة للأصل Parent"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Anchor"
-msgstr "إكبس إلي مرتكز العقدة"
+msgstr "حاذي إلي مرتكز العقدة"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Sides"
-msgstr "إكبس إلي جوانب العقدة"
+msgstr "حاذي إلي جوانب العقدة"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Node Center"
-msgstr "إكبس إلي مرتكز العقدة"
+msgstr "حاذي إلي Ù…Ùنتص٠العقدة"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Other Nodes"
-msgstr "إكبس إلي العقد الأخري"
+msgstr "حاذي إلى العقد الأخرى"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Snap to Guides"
-msgstr "أكبس إلي الموجهات"
+msgstr "حاذي إلى الموجهات"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5708,9 +5594,8 @@ msgid "Restores the object's children's ability to be selected."
msgstr "إرجاع مقدرة تحديد الطÙÙ„ للعنصر."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton Options"
-msgstr "Ø§Ù„ÙØ±Ø¯ÙŠØ©"
+msgstr "إعدادات الهكيل العظمي"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Bones"
@@ -5718,12 +5603,11 @@ msgstr "إظهار العظام"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Make Custom Bone(s) from Node(s)"
-msgstr ""
+msgstr "إنشاء عظمة (عظام) مخصوصة من عÙقدة (عÙقد)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Custom Bones"
-msgstr "إخلاء العظام"
+msgstr "مسح العظام المخصوصة"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5731,9 +5615,8 @@ msgid "View"
msgstr "أظهر"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Always Show Grid"
-msgstr "إظهار الشبكة"
+msgstr "إظهار الشبكة دوماً"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Helpers"
@@ -5757,7 +5640,7 @@ msgstr "أظهر الشاشة"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Group And Lock Icons"
-msgstr ""
+msgstr "إظهار أيقونات المجوعة والقÙÙ„"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center Selection"
@@ -5765,23 +5648,23 @@ msgstr "Ù†ØµÙ Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Frame Selection"
-msgstr "إملئ الشاشة بالمحدد"
+msgstr "تحديد الإطار"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Preview Canvas Scale"
-msgstr ""
+msgstr "إظهار تحجيم اللوحة Canvas"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Translation mask for inserting keys."
-msgstr ""
+msgstr "قناع الترجمة لأجل إدخال Ø§Ù„Ù…ÙØ§ØªÙŠØ­."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation mask for inserting keys."
-msgstr ""
+msgstr "قناع التدوير لأجل إدخال Ø§Ù„Ù…ÙØ§ØªÙŠØ­."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Scale mask for inserting keys."
-msgstr ""
+msgstr "قناع التحجيم لأجل إدخال Ø§Ù„Ù…ÙØ§ØªÙŠØ­."
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5795,16 +5678,18 @@ msgid ""
"Keys are only added to existing tracks, no new tracks will be created.\n"
"Keys must be inserted manually for the first time."
msgstr ""
+"إدخال تلقائي Ù„Ù„Ù…ÙØ§ØªÙŠØ­ عندما تترجم، ØªÙØ¯Ø§Ø± أو تحجم الأشياء objects (بناء على "
+"القناع).\n"
+"ØªÙØ¶Ø§Ù Ø§Ù„Ù…ÙØ§ØªÙŠØ­ Ùقط للمقاطع الموجودة Ø³Ù„ÙØ§Ù‹ØŒ Ùلا يتم إنشاء مقاطع جديدة.\n"
+"يجب إدخال Ø§Ù„Ù…ÙØ§ØªÙŠØ­ يدوياً ÙÙŠ أول مرة."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Auto Insert Key"
-msgstr "Ø£Ø¶Ù Ù…ÙØªØ§Ø­ الحركة"
+msgstr "Ù…ÙØªØ§Ø­ Ù…ÙØ¯Ø®Ù„ بصورة تلقائية"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Animation Key and Pose Options"
-msgstr "مدة الحركة (seconds)"
+msgstr "إعدادت Ø§Ù„Ù…ÙØªØ§Ø­ والوضعية للرسومات المتحركة"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key (Existing Tracks)"
@@ -5867,17 +5752,16 @@ msgstr ""
"سحب و إسقاط + Alt : تغيير نوع العقدة"
#: editor/plugins/collision_polygon_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon3D"
-msgstr "إنشاء بولي"
+msgstr "إنشاء متعدد سطوح ثلاثي الأبعاد"
#: editor/plugins/collision_polygon_editor_plugin.cpp
msgid "Edit Poly"
-msgstr "تعديل البولي"
+msgstr "تعديل Ù…ÙØªØ¹Ø¯Ø¯ السطوح"
#: editor/plugins/collision_polygon_editor_plugin.cpp
msgid "Edit Poly (Remove Point)"
-msgstr "تعديل البولي (مسح النقطة)"
+msgstr "تعديل متعدد السطوح (مسح النقطة)"
#: editor/plugins/collision_shape_2d_editor_plugin.cpp
msgid "Set Handle"
@@ -5892,14 +5776,13 @@ msgstr "حمل قناع الانبعاث"
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Restart"
-msgstr "إعادة تشغيل (ثواني):"
+msgstr "إعادة التشغيل"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Clear Emission Mask"
-msgstr "إمسح قناع الانبعاث"
+msgstr "امسح قناع الانبعاث"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5920,18 +5803,17 @@ msgstr "قناع الانبعاث"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Solid Pixels"
-msgstr ""
+msgstr "البكسيلات الأساسية Solid Pixels"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Border Pixels"
-msgstr ""
+msgstr "البكسلات المحيطية (الحدودية)"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
-#, fuzzy
msgid "Directed Border Pixels"
-msgstr "الوجهات ÙˆØ§Ù„Ù…Ù„ÙØ§Øª:"
+msgstr "البكسلات المحيطية (الحدودية) الموجهة"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5959,22 +5841,20 @@ msgid "Create Emission Points From Node"
msgstr "أنشئ نقاط إنبعاث من العقدة"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Flat 0"
-msgstr "مسطح0"
+msgstr "السطح 0"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Flat 1"
-msgstr "مسطح1"
+msgstr "السطح 1"
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
msgid "Ease In"
-msgstr ""
+msgstr "دخول متسارع Ease In"
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
msgid "Ease Out"
-msgstr ""
+msgstr "تراجع Ù…ÙØªØ¨Ø§Ø·Ø¦ Ease Out"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Smoothstep"
@@ -5982,7 +5862,7 @@ msgstr "خطوة ناعمة"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Modify Curve Point"
-msgstr "نعديل نقطة الإنحناء"
+msgstr "تعديل نقطة الإنحناء"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Modify Curve Tangent"
@@ -5993,22 +5873,18 @@ msgid "Load Curve Preset"
msgstr "تحميل إعداد مسبق للإنحناء"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Add Point"
msgstr "Ø¥Ø¶Ø§ÙØ© نقطة"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Remove Point"
msgstr "مسح النقطة"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Left Linear"
-msgstr "الخط الشمالي"
+msgstr "الخط اليساري"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Right Linear"
msgstr "الخط اليميني"
@@ -6027,12 +5903,11 @@ msgstr "إلغاء/ØªÙØ¹ÙŠÙ„ مماس خط المنحني"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Hold Shift to edit tangents individually"
-msgstr "إبقي ضاغطاً علي Shift لتعديل المماس ÙØ±Ø¯ÙŠØ§Ù‹"
+msgstr "إبقى ضاغطاً على Shift لتعديل المماس ÙØ±Ø¯ÙŠØ§Ù‹"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Right click to add point"
-msgstr "إظغط: أض٠نقطة"
+msgstr "اضغط بالزر الأيمن Ù„Ø¥Ø¶Ø§ÙØ© نقطة"
#: editor/plugins/gi_probe_editor_plugin.cpp
msgid "Bake GI Probe"
@@ -6040,7 +5915,7 @@ msgstr "طبخ مجس GI"
#: editor/plugins/gradient_editor_plugin.cpp
msgid "Gradient Edited"
-msgstr ""
+msgstr "التدرج Ø§Ù„Ù…ÙØ­Ø±Ø±"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item %d"
@@ -6063,9 +5938,8 @@ msgid "Mesh is empty!"
msgstr "الميش ÙØ§Ø±Øº!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Couldn't create a Trimesh collision shape."
-msgstr "إنشاء متصادم تراميش قريب"
+msgstr "لا يمكن إنشاء شكل Trimesh تصادمي."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Static Trimesh Body"
@@ -6073,47 +5947,43 @@ msgstr "أنشئ جسم تراميش ثابت"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "This doesn't work on scene root!"
-msgstr "هذا لا يعمل علي جزر المشهد!"
+msgstr "لا يعمل هذا على المشهد الرئيس!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Trimesh Static Shape"
-msgstr "أنشئ شكل تراميش"
+msgstr "أنشئ شكل Trimesh ساكن"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Can't create a single convex collision shape for the scene root."
-msgstr ""
+msgstr "لا يمكن إنشاء شكل تصادمي Ù…ÙØ­Ø¯Ø¨ لأجل المشهد الرئيس."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Couldn't create a single convex collision shape."
-msgstr ""
+msgstr "لم يتم إنشاء شكل محدب تصادمي وحيد."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Shape"
-msgstr "أنشئ شكل محدب"
+msgstr "أنشئ شكل محدب وحيد"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Can't create multiple convex collision shapes for the scene root."
-msgstr ""
+msgstr "لا يمكن إنشاء أشكال تصادم محدبة عديدة لأجل المشهد الرئيس."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Couldn't create any collision shapes."
-msgstr "لا يمكن إنشاء المجلد."
+msgstr "لا يمكن إنشاء أي شكل تصادمي."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Multiple Convex Shapes"
-msgstr "أنشئ شكل محدب"
+msgstr "أنشئ أشكال محدبة متعددة"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Navigation Mesh"
-msgstr "أنشئ ميش التنقل"
+msgstr "أنشئ سطح Mesh التنقل"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Contained Mesh is not of type ArrayMesh."
-msgstr "الميش المتضمن ليس من النوع الميش المتعدد."
+msgstr "السطح المتضمن ليس نوعاً من مصÙÙˆÙØ© السطوح ArrayMesh."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "UV Unwrap failed, mesh may not be manifold?"
@@ -6161,6 +6031,8 @@ msgid ""
"automatically.\n"
"This is the most accurate (but slowest) option for collision detection."
msgstr ""
+"إنشاء جسم سكوني وقرنه مع جسم تصادمي شبيه Ø¨Ø§Ù„Ù…ÙØ¶Ù„ع تلقائياً.\n"
+"هذا الخيار هو Ø§Ù„Ø£ÙØ¶Ù„ والأكثر دقة (ولكنه الأبطئ) لأجل الكش٠عن وجود تصادمات."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Collision Sibling"
@@ -6171,6 +6043,8 @@ msgid ""
"Creates a polygon-based collision shape.\n"
"This is the most accurate (but slowest) option for collision detection."
msgstr ""
+"إنشاء شكل تصادمي Ù…ÙØ¶Ù„عي الشكل.\n"
+"هذا هو الخيار الأكثر دقة (لكنه الأبطئ) لأجل للكش٠عن وقوع التصادم."
#: editor/plugins/mesh_instance_editor_plugin.cpp
#, fuzzy
@@ -6182,6 +6056,8 @@ msgid ""
"Creates a single convex collision shape.\n"
"This is the fastest (but least accurate) option for collision detection."
msgstr ""
+"إنشاء شكل تصادمي ذو تحدب وحيد.\n"
+"هذا هو الخيار الأسرع (لكنه الأقل دقة) للكش٠عن وقوع التصادم."
#: editor/plugins/mesh_instance_editor_plugin.cpp
#, fuzzy
@@ -6193,6 +6069,8 @@ msgid ""
"Creates a polygon-based collision shape.\n"
"This is a performance middle-ground between the two above options."
msgstr ""
+"إنشاء شكل تصادمي Ù…ÙØ¶Ù„عي الهيئة.\n"
+"هذا الخيار \\Ù…ÙØªÙˆØ³Ø· الأداء بين الخيارين أعلاه."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Outline Mesh..."
@@ -6205,6 +6083,10 @@ msgid ""
"This can be used instead of the SpatialMaterial Grow property when using "
"that property isn't possible."
msgstr ""
+"ÙŠÙنشى سطحاً مخططاً outline mesh سكونياً. هذا السطح تكون قيمه الطبيعية مقلوبة "
+"بصورة تلقائية.\n"
+"يمكن أن يستخدم بدلاً من خاصية التمدد (Grow ) لمادة الحيز المكاني "
+"SpatialMaterial عندما يكون استخدام هذه الخاصية غير مقدور عليه."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "View UV1"
@@ -6228,7 +6110,7 @@ msgstr "حجم الخطوط:"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "UV Channel Debug"
-msgstr ""
+msgstr "منقح أخطاء قناة UV"
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Remove item %d?"
@@ -6386,7 +6268,7 @@ msgstr "وقت التوليد (تانية):"
#: editor/plugins/particles_editor_plugin.cpp
msgid "The geometry's faces don't contain any area."
-msgstr ""
+msgstr "الوجوه الهندسية لا تتضمن أي منطقة."
#: editor/plugins/particles_editor_plugin.cpp
#, fuzzy
@@ -6395,7 +6277,7 @@ msgstr "العقدة لا تحتوي على هندسة (الوجوه)."
#: editor/plugins/particles_editor_plugin.cpp
msgid "\"%s\" doesn't inherit from Spatial."
-msgstr ""
+msgstr "\"%s\" لا يرث Ø§Ù„ÙØ±Ø§ØºÙŠ Spatial."
#: editor/plugins/particles_editor_plugin.cpp
#, fuzzy
@@ -6421,7 +6303,7 @@ msgstr "نقاط المساحة"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Surface Points+Normal (Directed)"
-msgstr ""
+msgstr "نقاط السطح + طبيعي (Ù…Ùوجّه)"
#: editor/plugins/particles_editor_plugin.cpp
msgid "Volume"
@@ -6498,31 +6380,31 @@ msgstr "إظغط: أض٠نقطة"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Left Click: Split Segment (in curve)"
-msgstr ""
+msgstr "بالزر الأيسر: ÙØµÙ„ القطعة (من المنحنى)"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Right Click: Delete Point"
-msgstr ""
+msgstr "بالزر الأيمن: احذ٠النقطة"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Select Control Points (Shift+Drag)"
-msgstr ""
+msgstr "اختر العÙقد الآباء (بالسحب + Shift)"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Add Point (in empty space)"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© عÙقدة (ÙÙŠ ÙÙØ³Ø­Ø© ÙØ§Ø±ØºØ©)"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Delete Point"
-msgstr ""
+msgstr "احذ٠النقطة"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Close Curve"
-msgstr ""
+msgstr "إغلاق المنحنى"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp
@@ -6533,16 +6415,16 @@ msgstr "الإعدادات"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Mirror Handle Angles"
-msgstr ""
+msgstr "زوايا مقبض المرآة"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Mirror Handle Lengths"
-msgstr ""
+msgstr "أطول مقابض المرآة"
#: editor/plugins/path_editor_plugin.cpp
msgid "Curve Point #"
-msgstr ""
+msgstr "Ù†Ùقطة المنحنى #"
#: editor/plugins/path_editor_plugin.cpp
msgid "Set Curve Point Position"
@@ -6558,11 +6440,11 @@ msgstr "حدد موقع خروج الإنحناء"
#: editor/plugins/path_editor_plugin.cpp
msgid "Split Path"
-msgstr ""
+msgstr "ÙØµÙ„ المسار"
#: editor/plugins/path_editor_plugin.cpp
msgid "Remove Path Point"
-msgstr ""
+msgstr "إزالة Ù†Ùقطة المسار"
#: editor/plugins/path_editor_plugin.cpp
msgid "Remove Out-Control Point"
@@ -6570,367 +6452,346 @@ msgstr "مسح نقطة خروج التحكم"
#: editor/plugins/path_editor_plugin.cpp
msgid "Remove In-Control Point"
-msgstr ""
+msgstr "إزالة النÙقطة داخلية التحكم In-Control"
#: editor/plugins/path_editor_plugin.cpp
msgid "Split Segment (in curve)"
-msgstr ""
+msgstr "ÙØµÙ„ القطعة (من المÙنحنى)"
#: editor/plugins/physical_bone_plugin.cpp
-#, fuzzy
msgid "Move Joint"
-msgstr "مسح النقطة"
+msgstr "تحريك النÙقطة"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
"The skeleton property of the Polygon2D does not point to a Skeleton2D node"
msgstr ""
+"إن خاصية الهيكل الخاص بالمضلع ثنائي الأبعاد لا تشير إلى عÙقدة هيكلية ثنائية "
+"الأبعاد Skeleton2D"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Sync Bones"
-msgstr "إظهار العظام"
+msgstr "Ù…ÙØ²Ø§Ù…نة العظام"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
"No texture in this polygon.\n"
"Set a texture to be able to edit UV."
msgstr ""
+"لا نقوش ÙÙŠ هذا Ø§Ù„Ù…ÙØ¶Ù„ع.\n"
+"حدد نقشاً لتتمكن من تعديل UV."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Create UV Map"
-msgstr ""
+msgstr "إنشاء خريطة UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
"Polygon 2D has internal vertices, so it can no longer be edited in the "
"viewport."
msgstr ""
+"يمتلك Ø§Ù„Ù…ÙØ¶Ù„ع ثنائي الأبعاد رؤوساً داخلياً، لذا لا يمكن الاستمرار بتعديله ÙÙŠ "
+"إطار العرض."
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Create Polygon & UV"
-msgstr "إنشاء بولي"
+msgstr "إنشاء Ù…ÙØ¶Ù„ع ÙˆUV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Create Internal Vertex"
-msgstr "إنشاء موجه Ø£Ùقي جديد"
+msgstr "إنشاء رأس داخلي"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Remove Internal Vertex"
-msgstr "مسح الموجه العمودي"
+msgstr "إزالة الرأس الداخلي"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Invalid Polygon (need 3 different vertices)"
-msgstr ""
+msgstr "Ù…ÙØ¶Ù„ع غير صالح (يحتاج لثلاثة رؤوس Ù…Ø®ØªÙ„ÙØ©)"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Add Custom Polygon"
-msgstr "تعديل البولي"
+msgstr "Ø¥Ø¶Ø§ÙØ© Ù…ÙØ¶Ù„ع مخصوص"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Remove Custom Polygon"
-msgstr "مسح البولي والنقطة"
+msgstr "إزالة Ø§Ù„Ù…ÙØ¶Ù„ع المخصوص"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Transform UV Map"
-msgstr ""
+msgstr "إعادة تشكيل خريطة UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Transform Polygon"
-msgstr "إنشاء بولي"
+msgstr "إعادة تشكيل Ø§Ù„Ù…ÙØ¶Ù„ع"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Paint Bone Weights"
-msgstr ""
+msgstr "طلاء العظام وزنياً"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Open Polygon 2D UV editor."
-msgstr "ÙØªØ­ Ø§Ù„Ù…ÙØ¹Ø¯Ù„ 2D"
+msgstr "ÙØªØ­ Ù…ÙØ­Ø±Ø± UV الخاص Ø¨Ø§Ù„Ù…ÙØ¶Ù„عات ثنائية Ø§Ù„Ø¨ÙØ¹Ø¯."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Polygon 2D UV Editor"
-msgstr ""
+msgstr "Ù…ÙØ­Ø±Ø± UV الخاص Ø¨Ø§Ù„Ù…ÙØ¶Ù„عات ثنائية Ø§Ù„Ø¨ÙØ¹Ø¯"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "UV"
-msgstr ""
+msgstr "ال UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Points"
-msgstr "مسح النقطة"
+msgstr "النقاط"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Polygons"
-msgstr "تعديل البولي"
+msgstr "Ø§Ù„Ù…ÙØ¶Ù„عات"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Bones"
-msgstr "أنشئ عظام"
+msgstr "العظام"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Move Points"
-msgstr "مسح النقطة"
+msgstr "تحريك النقاط"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Ctrl: Rotate"
-msgstr ""
+msgstr "Ctrl: تدوير"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift: Move All"
-msgstr ""
+msgstr "Shift: تحريك الكÙÙ„"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift+Ctrl: Scale"
-msgstr ""
+msgstr "Shift+Ctrl: تحجيم"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Move Polygon"
-msgstr ""
+msgstr "تحريك Ø§Ù„Ù…ÙØ¶Ù„ع"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Rotate Polygon"
-msgstr ""
+msgstr "تدوير Ø§Ù„Ù…ÙØ¶Ù„ع"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Scale Polygon"
-msgstr ""
+msgstr "تحجيم Ø§Ù„Ù…ÙØ¶Ù„ع"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Create a custom polygon. Enables custom polygon rendering."
-msgstr ""
+msgstr "إنشاء Ù…ÙØ¶Ù„ع مخصوص. تمكين إخراج Ø§Ù„Ù…ÙØ¶Ù„ع المخصوص بصرياً."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
"Remove a custom polygon. If none remain, custom polygon rendering is "
"disabled."
msgstr ""
+"إزالة Ø§Ù„Ù…ÙØ¶Ù„ع المخصوص. إن لم يتبق شيء، سيتم تعطيل إخراج Ø§Ù„Ù…ÙØ¶Ù„ع المخصوص بصرياً."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Paint weights with specified intensity."
-msgstr ""
+msgstr "طلاء الأوزان بشدات محددة."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Unpaint weights with specified intensity."
-msgstr ""
+msgstr "إزالة طلاء الأوزان بشدات محددة."
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Radius:"
-msgstr ""
+msgstr "نص٠القطر:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Polygon->UV"
-msgstr ""
+msgstr "Ù…ÙØ¶Ù„ع > UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "UV->Polygon"
-msgstr ""
+msgstr "UV > Ù…ÙØ¶Ù„ع"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Clear UV"
-msgstr ""
+msgstr "إزالة UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Settings"
-msgstr "إعدادات Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
+msgstr "إعدادات الشبكة"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Snap"
-msgstr ""
+msgstr "محاذاة"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Enable Snap"
-msgstr ""
+msgstr "تمكين المحاذاة"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid"
-msgstr ""
+msgstr "الشبكة"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Show Grid"
msgstr "إظهار الشبكة"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Configure Grid:"
-msgstr "تعديل اللقطة"
+msgstr "تهيئة الشكبة:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Offset X:"
-msgstr "معادل الشبكة:"
+msgstr "معادل الشبكة على المحور الأÙقي X:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Offset Y:"
-msgstr "معادل الشبكة:"
+msgstr "معادل الشبكة على المحور Y:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Step X:"
-msgstr "خطوة الشبكة:"
+msgstr "خطوة الشبكة على المحور X:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Grid Step Y:"
-msgstr "خطوة الشبكة:"
+msgstr "خطوة الشبكة على المحور Y:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Sync Bones to Polygon"
-msgstr ""
+msgstr "مزامنة العظام مع Ø§Ù„Ù…ÙØ¶Ù„ع"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "ERROR: Couldn't load resource!"
-msgstr ""
+msgstr "خطأ: لا يمكن تحميل المورد!"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Add Resource"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© مورد"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Rename Resource"
-msgstr ""
+msgstr "إعادة تسمية المورد"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Resource"
-msgstr ""
+msgstr "حذ٠المورد"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Resource clipboard is empty!"
-msgstr ""
+msgstr "Ø­Ø§ÙØ¸Ø© الموارد ÙØ§Ø±ØºØ©!"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Paste Resource"
-msgstr "لصق الموارد"
+msgstr "لصق المورد"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/scene_tree_editor.cpp
msgid "Instance:"
-msgstr ""
+msgstr "نمذجة:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp
#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Type:"
-msgstr ""
+msgstr "نوع:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
msgid "Open in Editor"
-msgstr ""
+msgstr "Ø§ÙØªØ­ ÙÙŠ Ø§Ù„Ù…ÙØ­Ø±Ø±"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Load Resource"
-msgstr ""
+msgstr "تحميل المورد"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "ResourcePreloader"
-msgstr "محدث مسبق للموارد"
+msgstr "مورد محمل Ø³Ù„ÙØ§Ù‹"
#: editor/plugins/root_motion_editor_plugin.cpp
msgid "AnimationTree has no path set to an AnimationPlayer"
-msgstr ""
+msgstr "لا تملك شجرة الرسومات المتحركة مساراً لمشغل الرسومات المتحركة"
#: editor/plugins/root_motion_editor_plugin.cpp
-#, fuzzy
msgid "Path to AnimationPlayer is invalid"
-msgstr "شجرة الحركة خاطئة."
+msgstr "المسار لمشغل الرسومات المتحركة غير صالح"
#: editor/plugins/script_editor_plugin.cpp
msgid "Clear Recent Files"
-msgstr ""
+msgstr "إزالة Ø§Ù„Ù…Ù„ÙØ§Øª الحديثة"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close and save changes?"
-msgstr ""
+msgstr "الإغلاق مع Ø­ÙØ¸ التعديلات؟"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error writing TextFile:"
-msgstr "خطأ ÙÙŠ Ø­ÙØ¸ مجموعة البلاط!"
+msgstr "خطأ ÙÙŠ كتابة المل٠النصي TextFile:"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Could not load file at:"
-msgstr "لا يمكن إنشاء المجلد."
+msgstr "لا يمكن تحميل المجلد ÙÙŠ:"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error saving file!"
-msgstr "خطأ ÙÙŠ Ø­ÙØ¸ مجموعة البلاط!"
+msgstr "خطأ ÙÙŠ Ø­ÙØ¸ الملÙ!"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error while saving theme."
-msgstr "خطأ خلال Ø§Ù„Ø­ÙØ¸."
+msgstr "خطأ أثناء Ø­ÙØ¸ الموضوع (Theme)."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Saving"
-msgstr "خطأ ÙÙŠ تحريك:"
+msgstr "خطأ ÙÙŠ Ø§Ù„Ø­ÙØ¸"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error importing theme."
-msgstr "خطأ ÙÙŠ تحريك:"
+msgstr "خطأ ÙÙŠ استيراد الموضوع (Theme)."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Importing"
-msgstr "خطأ ÙÙŠ تحريك:"
+msgstr "خطأ ÙÙŠ الاستيراد"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "New Text File..."
-msgstr "مجلد جديد..."
+msgstr "مل٠نصي جديد..."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open File"
-msgstr "Ø¥ÙØªØ­ ملÙ"
+msgstr "Ø§ÙØªØ­ الملÙ"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Save File As..."
-msgstr "Ø­ÙØ¸ باسم..."
+msgstr "Ø­ÙØ¸ المل٠ك..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Can't obtain the script for running."
-msgstr ""
+msgstr "لا يمكن الحصول على النص البرمجي للتشغيل."
#: editor/plugins/script_editor_plugin.cpp
msgid "Script failed reloading, check console for errors."
-msgstr ""
+msgstr "أخÙÙ‚ تحميل النص البرمجي، تÙقد الأخطاء ÙÙŠ العارض console."
#: editor/plugins/script_editor_plugin.cpp
msgid "Script is not in tool mode, will not be able to run."
-msgstr ""
+msgstr "النص البرمجي ليس ÙÙŠ وضعية الأداة، لم ينجح التشغيل."
#: editor/plugins/script_editor_plugin.cpp
msgid ""
"To run this script, it must inherit EditorScript and be set to tool mode."
msgstr ""
+"ليتم تشغيل النص البرمجي، ينبغي أن يرث النص البرمجي للمحرر EditorScript وأن "
+"ÙŠÙØ¶Ø¹ ÙÙŠ وضعية الأداة."
#: editor/plugins/script_editor_plugin.cpp
msgid "Import Theme"
-msgstr ""
+msgstr "استيراد الموضوع Theme"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error while saving theme"
-msgstr ""
+msgstr "خطأ أثناء Ø­ÙØ¸ الموضوع Theme"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving"
@@ -6938,36 +6799,33 @@ msgstr "خطأ ÙÙŠ Ø§Ù„Ø­ÙØ¸"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme As..."
-msgstr ""
+msgstr "Ø­ÙØ¸ الموضوع Theme Ùƒ..."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "%s Class Reference"
-msgstr " مرجع الصنÙ"
+msgstr "%s مرجعية الص٠Class"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find Next"
-msgstr "بحث عن التالي"
+msgstr "إيجاد التالي"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find Previous"
-msgstr ""
+msgstr "إيجاد السابق"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter scripts"
-msgstr "خصائص العنصر."
+msgstr "تشريح النصوص البرمجية"
#: editor/plugins/script_editor_plugin.cpp
msgid "Toggle alphabetical sorting of the method list."
-msgstr ""
+msgstr "ØªÙØ¹ÙŠÙ„ الترتيب Ø§Ù„Ø£Ù„ÙØ¨Ø§Ø¦ÙŠ Ù„Ù‚Ø§Ø¦Ù…Ø© الدوال."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter methods"
-msgstr "وضع Ø§Ù„Ù…ÙØµÙÙŠ:"
+msgstr "ترشيح الدوال"
#: editor/plugins/script_editor_plugin.cpp
msgid "Sort"
@@ -6983,147 +6841,143 @@ msgstr "تحريك لأعلى"
#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Move Down"
-msgstr "تحرك لأسÙÙ„"
+msgstr "تحريك لأسÙÙ„"
#: editor/plugins/script_editor_plugin.cpp
msgid "Next script"
-msgstr ""
+msgstr "النص البرمجي التالي"
#: editor/plugins/script_editor_plugin.cpp
msgid "Previous script"
-msgstr ""
+msgstr "النص البرمجي السابق"
#: editor/plugins/script_editor_plugin.cpp
msgid "File"
msgstr "ملÙ"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open..."
-msgstr "Ø¥ÙØªØ­"
+msgstr "Ø§ÙØªØ­..."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Reopen Closed Script"
-msgstr "ÙØªØ­ الكود"
+msgstr "إعادة ÙØªØ­ النص البرمجي Ø§Ù„Ù…ÙØºÙ„Ù‚"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
-msgstr "Ø§Ø­ÙØ¸ الكل"
+msgstr "Ø¥Ø­ÙØ¸ الكل"
#: editor/plugins/script_editor_plugin.cpp
msgid "Soft Reload Script"
-msgstr ""
+msgstr "إعادة تحميل النص البرمجي بلطÙ"
#: editor/plugins/script_editor_plugin.cpp
msgid "Copy Script Path"
-msgstr "نسخ مسار الكود"
+msgstr "نسخ مسار النص البرمجي"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "History Previous"
-msgstr "التبويب السابق"
+msgstr "التاريخ السابق"
#: editor/plugins/script_editor_plugin.cpp
msgid "History Next"
-msgstr ""
+msgstr "التاريخ التالي"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme"
-msgstr ""
+msgstr "الموضوع"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Import Theme..."
-msgstr "حاري إستيراد المشهد..."
+msgstr "استيراد الموضوع…"
#: editor/plugins/script_editor_plugin.cpp
msgid "Reload Theme"
-msgstr ""
+msgstr "إعادة تحميل الموضوع"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme"
-msgstr ""
+msgstr "Ø§Ø­ÙØ¸ الموضوع"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
-msgstr ""
+msgstr "إغلاق الكل"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close Docs"
-msgstr ""
+msgstr "إغلاق المستندات"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
msgid "Run"
-msgstr ""
+msgstr "تشغيل"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
-msgstr ""
+msgstr "اخط خطوة ضمن"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Over"
-msgstr ""
+msgstr "اخط خطوة متجاوزة"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Break"
-msgstr ""
+msgstr "توقÙ"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
#: editor/script_editor_debugger.cpp
msgid "Continue"
-msgstr ""
+msgstr "استمرار"
#: editor/plugins/script_editor_plugin.cpp
msgid "Keep Debugger Open"
-msgstr ""
+msgstr "إبقاء منÙقتح الأخطاء البرمجية Ù…ÙØªÙˆØ­Ø§Ù‹"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Debug with External Editor"
-msgstr "ÙØªØ­ ÙÙŠ Ø§Ù„Ù…ÙØ¹Ø¯Ù„ التالي"
+msgstr "تنقيح الأخطاء ÙÙŠ محرر خارجي"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open Godot online documentation."
-msgstr "ÙÙØªØ­ مؤخراً"
+msgstr "Ø§ÙØªØ­ مستندات غودوت على الشبكة."
#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
-msgstr ""
+msgstr "ابحث ÙÙŠ الوثائق المرجعية."
#: editor/plugins/script_editor_plugin.cpp
msgid "Go to previous edited document."
-msgstr ""
+msgstr "التوجه إلى المستند Ø§Ù„Ù…ÙØ­Ø±Ø± السابق."
#: editor/plugins/script_editor_plugin.cpp
msgid "Go to next edited document."
-msgstr ""
+msgstr "التوجه إلى المستند Ø§Ù„Ù…ÙØ­Ø±Ø± التالي."
#: editor/plugins/script_editor_plugin.cpp
msgid "Discard"
-msgstr ""
+msgstr "تجاهل"
#: editor/plugins/script_editor_plugin.cpp
msgid ""
"The following files are newer on disk.\n"
"What action should be taken?:"
msgstr ""
+"Ø§Ù„Ù…Ù„ÙØ§Øª التالية أحدث على القرص.\n"
+"ما الإجراء الذي ينبغي اتخاذه؟:"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Reload"
-msgstr ""
+msgstr "إعادة تحميل"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Resave"
-msgstr ""
+msgstr "إعادة Ø­ÙØ¸"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Debugger"
-msgstr ""
+msgstr "Ù…Ùنقح الأخطاء"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -7147,7 +7001,7 @@ msgstr "مورد"
#: editor/plugins/script_text_editor.cpp
msgid "Target"
-msgstr ""
+msgstr "الهدÙ"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7162,7 +7016,7 @@ msgstr "الخط:"
#: editor/plugins/script_text_editor.cpp
msgid "(ignore)"
-msgstr ""
+msgstr "(تجاهل)"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7171,50 +7025,50 @@ msgstr "مسح المهمة"
#: editor/plugins/script_text_editor.cpp
msgid "Only resources from filesystem can be dropped."
-msgstr ""
+msgstr "يمكن إسقاط موارد Ù…Ù„ÙØ§Øª النظام filesystem Ùقط."
#: editor/plugins/script_text_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't drop nodes because script '%s' is not used in this scene."
-msgstr ""
+msgstr "لا يمكن إسقاط العÙقد لأن النص البرمجي '%s' غير Ù…ÙØ³ØªØ®Ø¯Ù… ÙÙŠ هذا المشهد."
#: editor/plugins/script_text_editor.cpp
msgid "Lookup Symbol"
-msgstr ""
+msgstr "رمز البحث"
#: editor/plugins/script_text_editor.cpp
msgid "Pick Color"
-msgstr ""
+msgstr "اختر لوناً"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Convert Case"
-msgstr ""
+msgstr "حالة التحويل"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Uppercase"
-msgstr ""
+msgstr "الأحر٠الكبيرة (Uppercase)"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Lowercase"
-msgstr ""
+msgstr "الأحر٠الصغيرة (Lowercase)"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Capitalize"
-msgstr ""
+msgstr "تكبير الحرو٠Capitalize"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Syntax Highlighter"
-msgstr ""
+msgstr "Ù…ÙØ¹Ù„ّم التركيب Syntax"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "التوجه إلى"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Bookmarks"
-msgstr ""
+msgstr "المحÙوظات"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7224,7 +7078,7 @@ msgstr "مسح النقاط"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Cut"
-msgstr ""
+msgstr "قص"
#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
@@ -7233,19 +7087,19 @@ msgstr "تحديد الكل"
#: editor/plugins/script_text_editor.cpp
msgid "Delete Line"
-msgstr ""
+msgstr "حذ٠الخط"
#: editor/plugins/script_text_editor.cpp
msgid "Indent Left"
-msgstr ""
+msgstr "Ø§Ù„Ù…Ø³Ø§ÙØ© البادئة يساراً"
#: editor/plugins/script_text_editor.cpp
msgid "Indent Right"
-msgstr ""
+msgstr "Ø§Ù„Ù…Ø³Ø§ÙØ© البادئة يميناً"
#: editor/plugins/script_text_editor.cpp
msgid "Toggle Comment"
-msgstr ""
+msgstr "ØªÙØ¹ÙŠÙ„ Toggle التعليقات"
#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
@@ -7253,19 +7107,19 @@ msgstr "إلغاء/ØªÙØ¹ÙŠÙ„ طي الخط"
#: editor/plugins/script_text_editor.cpp
msgid "Fold All Lines"
-msgstr ""
+msgstr "طي جميع الخطوط"
#: editor/plugins/script_text_editor.cpp
msgid "Unfold All Lines"
-msgstr ""
+msgstr "كش٠جميع الخطوط"
#: editor/plugins/script_text_editor.cpp
msgid "Clone Down"
-msgstr ""
+msgstr "استنساخ أدناه"
#: editor/plugins/script_text_editor.cpp
msgid "Complete Symbol"
-msgstr ""
+msgstr "رمز التمام"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7274,7 +7128,7 @@ msgstr "تكبير المحدد"
#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
-msgstr ""
+msgstr "تشذيب Ø§Ù„ÙØ±Ø§ØºØ§Øª البيضاء الزائدة"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7288,7 +7142,7 @@ msgstr "تحويل إلي %s"
#: editor/plugins/script_text_editor.cpp
msgid "Auto Indent"
-msgstr ""
+msgstr "Ù…Ø³Ø§ÙØ© بادئة تلقائية"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7297,7 +7151,7 @@ msgstr "Ùلتر Ø§Ù„Ù…Ù„ÙØ§Øª..."
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
-msgstr ""
+msgstr "مساعدة سياقية"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7332,11 +7186,11 @@ msgstr "إذهب إلي الخط"
#: editor/plugins/script_text_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Toggle Breakpoint"
-msgstr ""
+msgstr "ØªÙØ¹ÙŠÙ„/إلغاء ØªÙØ¹ÙŠÙ„ نقطة التكسّر"
#: editor/plugins/script_text_editor.cpp
msgid "Remove All Breakpoints"
-msgstr ""
+msgstr "إزالة جميع نقاط التكسّر"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7353,14 +7207,16 @@ msgid ""
"This shader has been modified on on disk.\n"
"What action should be taken?"
msgstr ""
+"لقد تم تعديل هذا Ø§Ù„Ù…ÙØ¸Ù„Ù„ على القرص.\n"
+"ما الإجراء الذي ينبغي اتخاذه؟"
#: editor/plugins/shader_editor_plugin.cpp
msgid "Shader"
-msgstr ""
+msgstr "Ù…ÙØ¸Ù„Ù„"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "This skeleton has no bones, create some children Bone2D nodes."
-msgstr ""
+msgstr "لا يملك هذا الهكيل أيّة عظام، أنشئ بعض عÙقد العظام ثنائية Ø§Ù„Ø¨ÙØ¹Ø¯ كأبناء."
#: editor/plugins/skeleton_2d_editor_plugin.cpp
#, fuzzy
@@ -7369,20 +7225,19 @@ msgstr "أنشئ نقاط إنبعاث من الشبكة"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Set Rest Pose to Bones"
-msgstr ""
+msgstr "تحديد وضعية الراحة على العظام"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton2D"
-msgstr "Ø§Ù„ÙØ±Ø¯ÙŠØ©"
+msgstr "هيكل ثنائي Ø§Ù„Ø¨ÙØ¹Ø¯"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Make Rest Pose (From Bones)"
-msgstr ""
+msgstr "إنشاء وضعية الراحة (من العظام)"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Set Bones to Rest Pose"
-msgstr ""
+msgstr "تحديد العظام لتكون ÙÙŠ وضعية الراحة"
#: editor/plugins/skeleton_editor_plugin.cpp
#, fuzzy
@@ -7405,35 +7260,35 @@ msgstr "تشغيل"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Orthogonal"
-msgstr ""
+msgstr "متعامد"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective"
-msgstr ""
+msgstr "منظوري"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Aborted."
-msgstr ""
+msgstr "أجهض التحول."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "X-Axis Transform."
-msgstr ""
+msgstr "التحوّل المحوري X."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Y-Axis Transform."
-msgstr ""
+msgstr "التحوّل المحوري Y."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Z-Axis Transform."
-msgstr ""
+msgstr "التحوّل المحوري Z."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Plane Transform."
-msgstr ""
+msgstr "إظهار تحولات المستوى."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scaling: "
-msgstr ""
+msgstr "ÙŠÙØ­Ø¬Ù…: "
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Translating: "
@@ -7441,103 +7296,103 @@ msgstr "يترجم: "
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotating %s degrees."
-msgstr ""
+msgstr "ÙŠÙØ¯ÙŠØ± %s من الدرجات."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Keying is disabled (no key inserted)."
-msgstr ""
+msgstr "تم تعطيل تعيين Ø§Ù„Ù…ÙØ§ØªÙŠØ­ (لم يتم إدخال أيّة Ù…ÙØ§ØªÙŠØ­)."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Animation Key Inserted."
-msgstr ""
+msgstr "Ø£ÙØ¯Ø®Ù„ Ù…ÙØªØ§Ø­ الرسوم المتحركة."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Pitch"
-msgstr ""
+msgstr "حدّة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Yaw"
-msgstr ""
+msgstr "الإنحرا٠Yaw"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
-msgstr ""
+msgstr "كائنات مرسومة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Material Changes"
-msgstr ""
+msgstr "ØªÙØºÙŠØ±Ø§Øª المادة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Shader Changes"
-msgstr ""
+msgstr "تغيرات Ø§Ù„Ù…ÙØ¸Ù„Ù„"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Surface Changes"
-msgstr ""
+msgstr "تغيرات السطح"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Draw Calls"
-msgstr ""
+msgstr "رسم الاستدعاءات"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Vertices"
-msgstr ""
+msgstr "القمم"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View."
-msgstr ""
+msgstr "الواجهة العلوية."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View."
-msgstr ""
+msgstr "الواجهة السÙلية."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom"
-msgstr ""
+msgstr "الأسÙÙ„"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Left View."
-msgstr ""
+msgstr "الواجهة Ø§Ù„ÙŠÙØ³Ø±Ù‰."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Left"
-msgstr ""
+msgstr "اليسار"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Right View."
-msgstr ""
+msgstr "الواجهة اليÙمنى."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Right"
-msgstr ""
+msgstr "اليمين"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Front View."
-msgstr ""
+msgstr "الواجهة الأمامية."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Front"
-msgstr ""
+msgstr "الأمام"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rear View."
-msgstr ""
+msgstr "الواجهة الخلÙية."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rear"
-msgstr ""
+msgstr "الخلÙ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Align Transform with View"
-msgstr ""
+msgstr "محاذاة التحوّل مع الواجهة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Align Rotation with View"
-msgstr ""
+msgstr "محاذاة التدوير مع الواجهة"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
-msgstr "لا أب للصق الطÙÙ„ عليه."
+msgstr "لا أب لنمذجة ابن له."
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "This operation requires a single selected node."
@@ -7545,51 +7400,51 @@ msgstr "هذه العملية تتطلب عقدة واحدة محددة."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Auto Orthogonal Enabled"
-msgstr ""
+msgstr "الإسقاط العمودي Ù…Ùمكن تلقائياً"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
-msgstr ""
+msgstr "Ù‚ÙÙ„ تدوير الواجهة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Normal"
-msgstr ""
+msgstr "عرض الطبيعي"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Wireframe"
-msgstr ""
+msgstr "عرض Ø§Ù„Ù…ÙØ®Ø·Ø· Wireframe"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Overdraw"
-msgstr ""
+msgstr "عرض تراكبات الرسم Overdraw"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Unshaded"
-msgstr ""
+msgstr "عرض من غير ظلال"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Environment"
-msgstr ""
+msgstr "عرض البيئة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Gizmos"
-msgstr ""
+msgstr "إظهار الأدوات Gizmos"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Information"
-msgstr ""
+msgstr "إظهار المعلومات"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View FPS"
-msgstr "إظهار Ø§Ù„ÙØ±ÙŠÙ…/ثانية"
+msgstr "إظهار عدد الإطارات بالثانية"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Half Resolution"
-msgstr "نص٠حجم الشاشة"
+msgstr "نص٠دقة الشاشة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Audio Listener"
-msgstr ""
+msgstr "المستمع الصوتي"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7603,62 +7458,63 @@ msgstr "ÙŠÙنشئ مستعرضات الميش"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Not available when using the GLES2 renderer."
-msgstr ""
+msgstr "غير Ù…ØªÙˆØ§ÙØ± عند استخدام الخرج البصري GLES2 ."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Left"
-msgstr ""
+msgstr "الرؤية Ø§Ù„Ø­ÙØ±Ø© Freelook يساراً"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Right"
-msgstr ""
+msgstr "الرؤية الحرة Freelook يميناً"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Forward"
-msgstr ""
+msgstr "الرؤية الحرة Freelook Ù‚ÙØ¯Ù…اً"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Backwards"
-msgstr ""
+msgstr "الرؤية Ø§Ù„Ø­ÙØ±Ø© Freelook تراجعياً"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Up"
-msgstr ""
+msgstr "الرؤية Ø§Ù„Ø­ÙØ±Ø© Freelook للأعلى"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Down"
-msgstr ""
+msgstr "الرؤية Ø§Ù„Ø­ÙØ±Ø© للأسÙÙ„"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Speed Modifier"
-msgstr ""
+msgstr "Ù…ÙØ¹Ø¯Ù‘Ù„ سرعة الرؤية Ø§Ù„Ø­ÙØ±Ø©"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Slow Modifier"
-msgstr ""
+msgstr "Ù…ÙØ¹Ø¯Ù‘Ù„ تباطؤ الرؤية Ø§Ù„Ø­ÙØ±Ø©"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Rotation Locked"
-msgstr ""
+msgstr "تدوير الرؤية مقÙول"
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
+"ملاحظة: إن قيمة عدد الإطارات بالثانية الظاهر هو Ù…ÙØ¹Ø¯Ù„ خاص بالمحرر.\n"
+"لا يمكن الاعتماد على تلك القيمة كمؤشر لأداء اللعبة."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
-msgstr ""
+msgstr "Ù†Ø§ÙØ°Ø© XForm"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Snap Nodes To Floor"
-msgstr "الكبس إلي الشبكة"
+msgstr "محاذاة العÙقد إلى الأرضية"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Couldn't find a solid floor to snap the selection to."
-msgstr ""
+msgstr "لم يتم إيجاد أرضية صÙلبة لمحاذاة ما تم اختياره إليها."
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7666,63 +7522,66 @@ msgid ""
"Alt+Drag: Move\n"
"Alt+RMB: Depth list selection"
msgstr ""
+"السحب: تدوير.\n"
+"Alt+السحب: تحريك.\n"
+"Alt+ كبسة الزر الأيمن Ù„Ù„ÙØ£Ø±Ø©RMB : اختيار قائمة العÙمق"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Local Space"
-msgstr ""
+msgstr "استخدام الحيّز المحلي"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
-msgstr "إستخدم الكبس"
+msgstr "استخدام المحاذاة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
-msgstr ""
+msgstr "الواجهة View السÙلية"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View"
-msgstr ""
+msgstr "الواجهة View العلوية"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rear View"
-msgstr ""
+msgstr "الواجهة View الخلÙية"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Front View"
-msgstr ""
+msgstr "الواجهة View الأمامية"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Left View"
-msgstr ""
+msgstr "الواجهة View Ø§Ù„ÙŠÙØ³Ø±Ù‰"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Right View"
-msgstr ""
+msgstr "الواجهة View اليÙمنى"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Switch Perspective/Orthogonal View"
-msgstr ""
+msgstr "التبديل بين الرؤية المنظورية / الإسقاطية Orthogonal"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Insert Animation Key"
-msgstr ""
+msgstr "إدخال Ù…ÙØªØ§Ø­ للرسوميات المتحركة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Origin"
-msgstr ""
+msgstr "مصدر التركيز"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Selection"
-msgstr ""
+msgstr "اختيار التركيز"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
-msgstr "إلغاء/ØªÙØ¹ÙŠÙ„ وضع النظرة الحرة"
+msgstr "إلغاء/ØªÙØ¹ÙŠÙ„ وضع الرؤية Ø§Ù„Ø­ÙØ±Ø©"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Transform"
-msgstr ""
+msgstr "التحوّل"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7731,43 +7590,43 @@ msgstr "الكبس إلي الشبكة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Dialog..."
-msgstr ""
+msgstr "Ù†Ø§ÙØ°Ø© التحويلات ..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "1 Viewport"
-msgstr ""
+msgstr "ساحة رؤية واحدة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "2 Viewports"
-msgstr ""
+msgstr "ساحتان للرؤية"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "2 Viewports (Alt)"
-msgstr ""
+msgstr "ساحتان للرؤية (Alt)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports"
-msgstr ""
+msgstr "3 ساحات للرؤية"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports (Alt)"
-msgstr ""
+msgstr "3 ساحات للرؤية (Alt)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "4 Viewports"
-msgstr ""
+msgstr "4 ساحات للرؤية"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Gizmos"
-msgstr ""
+msgstr "الأدوات Gizmos"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Origin"
-msgstr ""
+msgstr "إظهار الأصل (المصدر)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Grid"
-msgstr ""
+msgstr "إظهار الشبكة"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
@@ -7777,67 +7636,68 @@ msgstr "جاري الإعداد..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
-msgstr ""
+msgstr "إعدادات المحاذاة"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Translate Snap:"
-msgstr ""
+msgstr "ترجمة المحاذاة:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Snap (deg.):"
-msgstr ""
+msgstr "تدوير المحاذاة (بالدرجات):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Snap (%):"
-msgstr ""
+msgstr "تحجيم المحاذاة (%):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Viewport Settings"
-msgstr ""
+msgstr "إعدادات إطار العرض"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective FOV (deg.):"
-msgstr ""
+msgstr "مجال الرؤية FOV المنظورية (بالدرجات):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Z-Near:"
-msgstr ""
+msgstr "إظهار Z-Near:"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid "View Z-Far:"
-msgstr ""
+msgstr "إظهار Z-Far:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Change"
-msgstr ""
+msgstr "تعديل التحولات"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Translate:"
-msgstr ""
+msgstr "الترجمة:"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate (deg.):"
-msgstr ""
+msgstr "التدوير (بالدرجات):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale (ratio):"
-msgstr ""
+msgstr "التحجيم (نسبةً):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Type"
-msgstr ""
+msgstr "نوع التحوّل"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Pre"
-msgstr ""
+msgstr "سابق"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Post"
-msgstr ""
+msgstr "لاحق"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Nameless gizmo"
-msgstr ""
+msgstr "أداة (gizmo) غير مسماة"
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7856,7 +7716,7 @@ msgstr "إنشاء بولي"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Polygon2D Preview"
-msgstr ""
+msgstr "Ù…ÙØ¹Ø§ÙŠÙ†Ø© Ø§Ù„Ù…ÙØ¶Ù„ع ثنائي الأبعاد"
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7886,10 +7746,12 @@ msgstr "الميش ÙØ§Ø±Øº!"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Can't convert a sprite using animation frames to mesh."
msgstr ""
+"لا يمكن تحويل الرسومية (sprite) إلى سطح (mesh) باستخدام إطارات الرسوم "
+"المتحركة."
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't replace by mesh."
-msgstr ""
+msgstr "هندسياً غير صالح، لا يمكن استبداله بسطح (mesh)."
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7898,7 +7760,7 @@ msgstr "تحويل إلي %s"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create polygon."
-msgstr ""
+msgstr "هندسياصً غير صالح، لا يمكن إنشاء Ù…ÙØ¶Ù„ّع."
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7907,7 +7769,7 @@ msgstr "تحويل إلي %s"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create collision polygon."
-msgstr ""
+msgstr "هندسياً غير صالح، لا يمكن إنشاء Ù…ÙØ¶Ù„ع تصادم."
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7916,7 +7778,7 @@ msgstr "إنشاء Ù…ÙØ¶Ù„ع التنقل"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create light occluder."
-msgstr ""
+msgstr "هندسياً غير صالح، لا يمكن إنشاء Ø­ÙØ¸Ø§Ø± (occluder) الضوء."
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7925,19 +7787,19 @@ msgstr "أنشئ شكل Ù…ÙØ·Ø¨Ù‚"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Sprite"
-msgstr ""
+msgstr "رسومية"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Simplification: "
-msgstr ""
+msgstr "التبسيط: "
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Shrink (Pixels): "
-msgstr ""
+msgstr "التقلص (Pixels): "
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Grow (Pixels): "
-msgstr ""
+msgstr "التكبير (Pixels): "
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7945,79 +7807,72 @@ msgid "Update Preview"
msgstr "إستعراض"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Settings:"
-msgstr "إعدادات Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
+msgstr "الإعدادات:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "No Frames Selected"
-msgstr "إملئ الشاشة بالمحدد"
+msgstr "لا إطارات Ù…ÙØ­Ø¯Ø¯Ø©"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add %d Frame(s)"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© %d إطار(ات)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frame"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© إطار"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Unable to load images"
-msgstr "ÙØ´Ù„ تحميل المورد."
+msgstr "غير قادر على تحميل الصور"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "ERROR: Couldn't load frame resource!"
-msgstr ""
+msgstr "خطأ: لم يتم تحميل مورد الإطار!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Resource clipboard is empty or not a texture!"
-msgstr ""
+msgstr "إما أن تكون Ø­Ø§ÙØ¸Ø© الموارد ÙØ§Ø±ØºØ© أو ليست نقشاً!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Paste Frame"
-msgstr ""
+msgstr "الصق إطاراً"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Empty"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØªÙ‡ ÙØ§Ø±ØºØ§Ù‹"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation FPS"
-msgstr ""
+msgstr "تغيير Ù…ÙØ¹Ø¯Ù„ الإطارات ÙÙŠ الثانية FPS للرسوم المتحركة"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "(empty)"
-msgstr ""
+msgstr "(ÙØ§Ø±Øº)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Move Frame"
-msgstr "وضع التحريك"
+msgstr "تحريك الإطار"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Animations:"
-msgstr "صورة متحركة"
+msgstr "الرسومات المتحركة:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "New Animation"
-msgstr "صورة متحركة"
+msgstr "رسومية متحركة جديدة"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Speed (FPS):"
-msgstr ""
+msgstr "السرعة (إطار Ù. Ø«. FPS):"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Loop"
-msgstr ""
+msgstr "حلقة Loop"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Animation Frames:"
-msgstr "إسم الحركة:"
+msgstr "إطارات الرسومات المتحركة:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -8026,15 +7881,15 @@ msgstr "التقط من البيكسل"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frames from a Sprite Sheet"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© الإطارات من ورقة الرسوميات Sprite Sheet"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (Before)"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØªÙ‡ ÙØ§Ø±ØºØ§Ù‹ (قبل)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (After)"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØªÙ‡ ÙØ§Ø±ØºØ§Ù‹ (بَعد)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Move (Before)"
@@ -8051,61 +7906,60 @@ msgstr "تحديد الوضع"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Horizontal:"
-msgstr ""
+msgstr "عَرضياً:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Vertical:"
-msgstr ""
+msgstr "شاقولياً:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Select/Clear All Frames"
-msgstr ""
+msgstr "اختيار / مسح جميع الإطارات"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Create Frames from Sprite Sheet"
-msgstr ""
+msgstr "إنشاء الإطارات من ورقة الرسومية Sprite Sheet"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "SpriteFrames"
-msgstr ""
+msgstr "إطارات الرسوميات SpriteFrames"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Set Region Rect"
-msgstr ""
+msgstr "تحديد مستطيل المنطقة"
#: editor/plugins/texture_region_editor_plugin.cpp
-#, fuzzy
msgid "Set Margin"
-msgstr "حدد المعامل"
+msgstr "تحديد الهامش"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Snap Mode:"
-msgstr ""
+msgstr "وضع المحاذاة:"
#: editor/plugins/texture_region_editor_plugin.cpp
#: scene/resources/visual_shader.cpp
msgid "None"
-msgstr ""
+msgstr "لا شيء"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Pixel Snap"
-msgstr ""
+msgstr "محاذاة البكسل"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Grid Snap"
-msgstr ""
+msgstr "شبكة المحاذاة"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Auto Slice"
-msgstr ""
+msgstr "الاقتطاع التلقائي"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Offset:"
-msgstr ""
+msgstr "Ø§Ù„Ù…ÙØ¹Ø§Ø¯Ù„:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Step:"
-msgstr ""
+msgstr "الخطوة:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Sep.:"
@@ -8113,32 +7967,31 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "TextureRegion"
-msgstr ""
+msgstr "منطقة النقش TextureRegion"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© جميع العناصر"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© الجميع"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Remove All Items"
-msgstr ""
+msgstr "إزالة جميع العناصر"
#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
msgid "Remove All"
msgstr "مسح الكل"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Edit Theme"
-msgstr "الأعضاء"
+msgstr "تحرير الموضوع"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme editing menu."
-msgstr ""
+msgstr "قائمة تحرير الموضوع."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add Class Items"
@@ -8150,15 +8003,15 @@ msgstr "حذ٠بنود من الصنÙ"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Create Empty Template"
-msgstr ""
+msgstr "إنشاء قالب ÙØ§Ø±Øº"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Create Empty Editor Template"
-msgstr ""
+msgstr "إنشاء قالب Ù…ÙØ­Ø±Ø± ÙØ§Ø±Øº"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Create From Current Editor Theme"
-msgstr ""
+msgstr "إنشاء مستمد من موضوع Theme المحرر الحالي"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
@@ -8201,7 +8054,7 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Submenu"
-msgstr ""
+msgstr "القائمة Ø§Ù„ÙØ±Ø¹ÙŠØ©"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
@@ -8215,11 +8068,11 @@ msgstr "عنصر"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has"
-msgstr ""
+msgstr "يملك"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Many"
-msgstr ""
+msgstr "العديد"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
@@ -8245,7 +8098,7 @@ msgstr "عنصر انتقاء"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subtree"
-msgstr ""
+msgstr "الشجرة Ø§Ù„ÙØ±Ø¹ÙŠØ©"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
@@ -8254,24 +8107,24 @@ msgstr "بكثير، خيارات عديدة،!"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Data Type:"
-msgstr ""
+msgstr "نوع البيانات:"
#: editor/plugins/theme_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Icon"
-msgstr ""
+msgstr "الأيقونة"
#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Style"
-msgstr ""
+msgstr "الأسلوب"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Font"
-msgstr ""
+msgstr "الخط"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Color"
-msgstr ""
+msgstr "اللون"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
@@ -8280,7 +8133,7 @@ msgstr "Ø¥ÙØªØ­ ملÙ"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase Selection"
-msgstr ""
+msgstr "إزالة عملية الاختيار"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -8295,23 +8148,23 @@ msgstr "Ù†ØµÙ Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint TileMap"
-msgstr ""
+msgstr "طلاء خريطة البلاط TileMap"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Line Draw"
-msgstr ""
+msgstr "رسم الخط"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rectangle Paint"
-msgstr ""
+msgstr "مستطيل الطلاء"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Bucket Fill"
-msgstr ""
+msgstr "وعاء التعبئة"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase TileMap"
-msgstr ""
+msgstr "مسح خريطة البلاط TileMap"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -8320,11 +8173,11 @@ msgstr "جد"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Transpose"
-msgstr ""
+msgstr "المصÙÙˆÙØ© المنقولة Transpose"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
-msgstr ""
+msgstr "تعطيل البلاط التلقائي Autotile"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -8339,20 +8192,23 @@ msgstr "Ùلتر Ø§Ù„Ù…Ù„ÙØ§Øª..."
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Give a TileSet resource to this TileMap to use its tiles."
msgstr ""
+"منح مورد Ù…ÙØ­Ø¯Ø¯ البلاطات TileSet لخريطة البلاط TileMap هذه كي تستخدم بلاطاتها."
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint Tile"
-msgstr ""
+msgstr "طلاء البلاط"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
"Shift+LMB: Line Draw\n"
"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
+"Shift+ الزر الأيسر Ù„Ù„ÙØ£Ø±Ø©: الرسم خطياً\n"
+"Shift+Ctrl+الزر الأيسر Ù„Ù„ÙØ£Ø±Ø©: طلاء المستطيلات"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Pick Tile"
-msgstr ""
+msgstr "اختيار البلاط"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -8366,11 +8222,11 @@ msgstr "وضع التدوير"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Horizontally"
-msgstr ""
+msgstr "القلب Ø£Ùقياً"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Vertically"
-msgstr ""
+msgstr "القلب عموديًا"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -8379,7 +8235,7 @@ msgstr "تحويل تغيير التحريك"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Add Texture(s) to TileSet."
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© نقش(نقوش) إلى Ù…ÙØ­Ø¯Ø¯ البلاط TileSet."
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8388,15 +8244,15 @@ msgstr "مسح المدخلة الحالية"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from Scene"
-msgstr ""
+msgstr "إنشاء من المشهد"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Merge from Scene"
-msgstr ""
+msgstr "دمج من المشهد"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "New Single Tile"
-msgstr ""
+msgstr "بلاطة Ù…ÙÙØ±Ø¯Ø© جديدة"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8405,15 +8261,15 @@ msgstr "إظهار Ø§Ù„Ù…Ù„ÙØ§Øª"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "New Atlas"
-msgstr ""
+msgstr "أطلس جديد"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Next Coordinate"
-msgstr ""
+msgstr "الإحداثيات التالية"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Select the next shape, subtile, or Tile."
-msgstr ""
+msgstr "اختر الشكل أو البلاط Ø§Ù„ÙØ±Ø¹ÙŠ Ø£Ùˆ البلاط التالي."
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8422,86 +8278,71 @@ msgstr "التبويب السابق"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Select the previous shape, subtile, or Tile."
-msgstr ""
+msgstr "اختر الشكل أو البلاط Ø§Ù„ÙØ±Ø¹ÙŠ Ø£Ùˆ البلاط، السابق."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Region"
-msgstr "وضع التدوير"
+msgstr "الإقليم"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Collision"
-msgstr "وضعية Ø§Ù„Ø£Ø³ØªÙŠÙØ§Ø¡"
+msgstr "التصادم"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Occlusion"
-msgstr "تعديل البولي"
+msgstr "الإطباق Occlusion"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Navigation"
-msgstr "أنشئ ميش التنقل"
+msgstr "Ø§Ù„ØªØµÙØ­"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Bitmask"
-msgstr "وضع التدوير"
+msgstr "قناع Ø§Ù„Ø¨ÙØª Bitmask"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Priority"
-msgstr "تصدير المشروع"
+msgstr "Ø§Ù„ØªÙØ§Ø¶Ù„ Priority"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Z Index"
-msgstr "وضع السحب"
+msgstr "تراتبية المحور Z"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Region Mode"
-msgstr "وضع التدوير"
+msgstr "وضع الأقليم Region"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Collision Mode"
-msgstr "وضعية Ø§Ù„Ø£Ø³ØªÙŠÙØ§Ø¡"
+msgstr "وضع التصادم"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Occlusion Mode"
-msgstr "تعديل البولي"
+msgstr "وضع الإطباق Occlusion"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Navigation Mode"
-msgstr "أنشئ ميش التنقل"
+msgstr "وضع Ø§Ù„ØªØµÙØ­"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Bitmask Mode"
-msgstr "وضع التدوير"
+msgstr "وضع Bitmask"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Priority Mode"
-msgstr "تصدير المشروع"
+msgstr "وضع Ø§Ù„ØªÙØ§Ø¶Ù„ Priority"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Icon Mode"
-msgstr "وضع السحب"
+msgstr "وضع الأيقونة"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Z Index Mode"
-msgstr "وضع السحب"
+msgstr "وضع Z Index"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Copy bitmask."
-msgstr ""
+msgstr "نسخ bitmask."
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8519,84 +8360,86 @@ msgid "Create a new rectangle."
msgstr "إنشاء %s جديد"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create a new polygon."
-msgstr "أنشئ شكل جديد من لا شئ."
+msgstr "إنشاء Ù…ÙØ¶Ù„ع جديد."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Keep polygon inside region Rect."
-msgstr ""
+msgstr "إبقاء Ø§Ù„Ù…ÙØ¶Ù„ع داخل مستطيل المنطقة."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Enable snap and show grid (configurable via the Inspector)."
-msgstr ""
+msgstr "تمكين المحاذاة وإظهار الشبكة (التهيئة عبر Ø§Ù„Ù…ÙØªÙحص)."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Display Tile Names (Hold Alt Key)"
-msgstr ""
+msgstr "تعطيل أسماء البلاطات (اضغط على زر Alt)"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
"Add or select a texture on the left panel to edit the tiles bound to it."
-msgstr ""
+msgstr "أض٠أو اختر نقشاً من اللوحة على اليسار لتحرير البلاطات المقترنة بها."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove selected texture? This will remove all tiles which use it."
-msgstr "مسح المدخلة الحالية"
+msgstr "مسح النقش Ø§Ù„Ù…ÙØ®ØªØ§Ø±ØŸ هذا سيزيل جميع البلاطات التي تستخدمه."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "You haven't selected a texture to remove."
-msgstr ""
+msgstr "لم تختر نقشاً لإزالته."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from scene? This will overwrite all current tiles."
msgstr ""
+"إنشاء اعتماداً على مشهد؟ هذا سيكتب متجاوزاً overwrite جميع البلاطات الحالية."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Merge from scene?"
-msgstr ""
+msgstr "دمج من مشهد؟"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Texture"
-msgstr "مسح القالب"
+msgstr "إزالة النقش"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "%s file(s) were not added because was already on the list."
-msgstr ""
+msgstr "%s الملÙ(ات) لم تض٠بسبب كونها موجودة Ø³Ù„ÙØ§Ù‹ بالقائمة."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
"Drag handles to edit Rect.\n"
"Click on another Tile to edit it."
msgstr ""
+"اسحب المقابض لتحرير المستطيل.\n"
+"اضغط على بلاطة أخرى لتحريرها."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete selected Rect."
-msgstr "إمسح Ø§Ù„Ù…Ù„ÙØ§Øª المحددة؟"
+msgstr "مسح المستطيلات المحددة."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"Select current edited sub-tile.\n"
"Click on another Tile to edit it."
-msgstr "Ø­ÙØ¸ العنوان Ø§Ù„ÙØ±Ø¹ÙŠ Ø§Ù„Ø°ÙŠ يتم تعديله حاليا."
+msgstr ""
+"اختر البلاطات Ø§Ù„ÙØ±Ø¹ÙŠØ© Ø§Ù„Ù…ÙØ­Ø¯Ø¯Ø© حديثاً.\n"
+"اضغط على بلاطة أخرى لتحريرها."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete polygon."
-msgstr "مسح النقاط"
+msgstr "مسح Ø§Ù„Ù…ÙØ¶Ù„ع."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"LMB: Set bit on.\n"
"RMB: Set bit off.\n"
"Shift+LMB: Set wildcard bit.\n"
"Click on another Tile to edit it."
-msgstr "Ø­ÙØ¸ العنوان Ø§Ù„ÙØ±Ø¹ÙŠ Ø§Ù„Ø°ÙŠ يتم تعديله حاليا."
+msgstr ""
+"الزر الأيسر Ù„Ù„ÙØ£Ø±Ø©: تشغيل bit.\n"
+"الزر الأيمن Ù„Ù„ÙØ£Ø±Ø©: Ø¥Ø·ÙØ§Ø¡ bit.\n"
+"Shift+الزر الأيسر Ù„Ù„ÙØ£Ø±Ø©: تحديد wildcard bit.\n"
+"اضغط على بلاطة أخرى لتحريرها."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8604,210 +8447,189 @@ msgid ""
"bindings.\n"
"Click on another Tile to edit it."
msgstr ""
+"اختر بلاطة ÙØ±Ø¹ÙŠØ© لاستخدامها كأيقونة، حيث سيتم استخدامها ÙÙŠ قرن البلاط "
+"التلقائي غير الصالح.\n"
+"اضغط على بلاطة أخرى لتحريرها."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
"Select sub-tile to change its priority.\n"
"Click on another Tile to edit it."
msgstr ""
+"اختر بلاطة ÙØ±Ø¹ÙŠØ© لتغير Ø§Ù„ØªÙØ§Ø¶Ù„ الخاص بها.\n"
+"اختر بلاطة أخرى لتحريرها."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"Select sub-tile to change its z index.\n"
"Click on another Tile to edit it."
-msgstr "Ø­ÙØ¸ العنوان Ø§Ù„ÙØ±Ø¹ÙŠ Ø§Ù„Ø°ÙŠ يتم تعديله حاليا."
+msgstr ""
+"اختر بلاطة ÙØ±Ø¹ÙŠØ© لتغير ترتيبها على المحور Z.\n"
+"اضغط على بلاطة أخرى لتحريرها."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Set Tile Region"
-msgstr ""
+msgstr "تحديد منطقة البلاط"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create Tile"
-msgstr "أنشئ مجلد"
+msgstr "إنشاء بلاط"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Set Tile Icon"
-msgstr ""
+msgstr "تحديد أيقونة البلاط"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Tile Bitmask"
-msgstr "تعديل المصاÙÙŠ"
+msgstr "تحرير قناع Ø§Ù„Ø¨ÙØª Bitmask البلاط"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Collision Polygon"
-msgstr "تعديل الشكل الموجود Ø¨Ø§Ù„ÙØ¹Ù„:"
+msgstr "تعديل Ù…ÙØ¶Ù„ع التصادم"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Occlusion Polygon"
-msgstr "تعديل البولي"
+msgstr "تحرير Ù…ÙØ¶Ù„ع الإطباق"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Navigation Polygon"
-msgstr "إنشاء Ù…ÙØ¶Ù„ع التنقل"
+msgstr "تحرير Ù…ÙØ¶Ù„ع Ø§Ù„ØªØµÙØ­"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Paste Tile Bitmask"
-msgstr "لصق الحركة"
+msgstr "لصق قناع Ø¨ÙØª Bitmask البلاط"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Clear Tile Bitmask"
-msgstr ""
+msgstr "مسح قناع Ø¨ÙØª Bitmask البلاط"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Make Polygon Concave"
-msgstr ""
+msgstr "جعل Ø§Ù„Ù…ÙØ¶Ù„ع Ù…Ùقعراً"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Make Polygon Convex"
-msgstr "إنشاء بولي"
+msgstr "جعل Ø§Ù„Ù…ÙØ¶Ù„ع Ù…ÙØ­Ø¯Ù‘باً"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Tile"
-msgstr "مسح القالب"
+msgstr "إزالة البلاط"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Collision Polygon"
-msgstr "مسح البولي والنقطة"
+msgstr "إزالة Ù…ÙØ¶Ù„ع التصادم"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Occlusion Polygon"
-msgstr "أنشئ شكل Ù…ÙØ·Ø¨Ù‚"
+msgstr "إزالة Ù…ÙØ¶Ù„ع الإطباق"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove Navigation Polygon"
-msgstr "إنشاء Ù…ÙØ¶Ù„ع التنقل"
+msgstr "إزالة Ù…ÙØ¶Ù„ع التنقل"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Edit Tile Priority"
-msgstr "تعديل المصاÙÙŠ"
+msgstr "تعديل ØªÙØ§Ø¶Ù„ البلاط"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Edit Tile Z Index"
-msgstr ""
+msgstr "تعديل تراتبية البلاط على المحور Z"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Make Convex"
-msgstr "إنشاء بولي"
+msgstr "جعله Ù…ÙØ­Ø¯Ø¨Ø§Ù‹"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Make Concave"
-msgstr "أنشئ عظام"
+msgstr "جعله Ù…Ùقعراً"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create Collision Polygon"
-msgstr "إنشاء Ù…ÙØ¶Ù„ع التنقل"
+msgstr "إنشاء Ù…ÙØ¶Ù„ع التصادم"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create Occlusion Polygon"
-msgstr "أنشئ شكل Ù…ÙØ·Ø¨Ù‚"
+msgstr "إنشاء Ù…ÙØ¶Ù„ع الإطباق Occlusion"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "This property can't be changed."
-msgstr "هذه العملية لا يمكن الإكتمال من غير مشهد."
+msgstr "لا يمكن تعديل هذه الخاصية."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "TileSet"
-msgstr "مجموعة البلاط"
+msgstr "Ù…ÙØ­Ø¯Ø¯ البلاط"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "No VCS addons are available."
-msgstr ""
+msgstr "لا يوجد Ø¥Ø¶Ø§ÙØ§Øª VCS Ù…ØªÙˆØ§ÙØ±Ø©."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Error"
-msgstr ""
+msgstr "خطأ"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "No commit message was provided"
-msgstr "لا أسم Ù…Ùقدم"
+msgstr "لم يتم تقديم رسالة ارتكاب commit"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
-msgstr ""
+msgstr "لم يتم Ø¥Ø¶Ø§ÙØ© Ù…Ù„ÙØ§Øª إلى المرحلة"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Commit"
-msgstr "المجتمع"
+msgstr "ارتكاب"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "VCS Addon is not initialized"
-msgstr ""
+msgstr "لم يتم تهيئة Ø¥Ø¶Ø§ÙØ§Øª VCS"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
-msgstr ""
+msgstr "نظام التحكم بالإصدار VCS"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Initialize"
-msgstr ""
+msgstr "الشروع"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Staging area"
-msgstr ""
+msgstr "حيز التدريج"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Detect new changes"
-msgstr "إنشاء %s جديد"
+msgstr "الكش٠عن التغيرات الجديدة"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Changes"
-msgstr "تغير"
+msgstr "التغيرات"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
-msgstr ""
+msgstr "Ù…ÙØ¹Ø¯Ù‘Ù„"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Renamed"
-msgstr "إعادة التسمية"
+msgstr "Ù…ÙØ¹Ø§Ø¯ تسميته"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Deleted"
-msgstr "مسح"
+msgstr "Ù…ÙØ²Ø§Ù„"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Typechange"
-msgstr "تغير"
+msgstr "تعديل النوع"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Stage Selected"
-msgstr "تكبير المحدد"
+msgstr "Ø­ÙØ¯Ø¯Øª المرحلة"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Stage All"
-msgstr "Ø§Ø­ÙØ¸ الكل"
+msgstr "Ù…ÙØ¬Ù…Ù„ المراحل"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Add a commit message"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© رسالة إجراء"
#: editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
@@ -8817,343 +8639,328 @@ msgstr "مزامنة تغييرات الكود"
#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
-msgstr ""
+msgstr "الحالة"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "View file diffs before committing them to the latest version"
-msgstr ""
+msgstr "إظهار آخر تعديلات المل٠قبل قبولهم ÙÙŠ آخر نسخة."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "No file diff is active"
-msgstr ""
+msgstr "لا Ù…Ù„Ù ÙØ±ÙˆÙ‚ نشط"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Detect changes in file diff"
-msgstr ""
+msgstr "الكش٠عن التغييرات ÙÙŠ Ù…Ù„Ù Ø§Ù„ÙØ±ÙˆÙ‚"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
-msgstr ""
+msgstr "(GLES3 Ùقط)"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add Output"
-msgstr "أض٠مدخله"
+msgstr "Ø¥Ø¶Ø§ÙØ© Ù…ÙØ®Ø±Ø¬"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar"
-msgstr "تكبير/تصغير:"
+msgstr "كمية قياسية Scalar"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector"
-msgstr "متجه"
+msgstr "Ù…ÙØªØ¬Ù‡"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean"
-msgstr ""
+msgstr "منطق Boolean"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Sampler"
msgstr "عينات (صوتية)"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add input port"
-msgstr "أض٠مدخله"
+msgstr "أض٠بوابة Ø§Ù„Ù…ÙØ¯Ø®Ù„ات"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add output port"
-msgstr ""
+msgstr "Ø£Ø¶Ù Ù…Ù†ÙØ° Ø§Ù„Ù…ÙØ®Ø±Ø¬Ø§Øª"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port type"
-msgstr "غير النوع Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ"
+msgstr "غيّر نوع Ù…Ù†ÙØ° Ø§Ù„Ù…ÙØ¯Ø®Ù„ات"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change output port type"
-msgstr "غير النوع Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ"
+msgstr "غيّر نوع Ù…Ù†ÙØ° Ø§Ù„Ù…ÙØ®Ø±Ø¬Ø§Øª"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port name"
-msgstr "تغيير إسم الحركة:"
+msgstr "غيّر اسم Ù…Ù†ÙØ° Ø§Ù„Ù…ÙØ¯Ø®Ù„ات"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Change output port name"
-msgstr ""
+msgstr "غيّر اسم Ù…Ù†ÙØ° Ø§Ù„Ù…ÙØ®Ø±Ø¬Ø§Øª"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Remove input port"
-msgstr "مسح النقطة"
+msgstr "إزالة Ù…Ù†ÙØ° Ø§Ù„Ù…ÙØ¯Ø®Ù„ات"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Remove output port"
-msgstr "مسح النقطة"
+msgstr "إزالة Ù…Ù†ÙØ° Ø§Ù„Ù…ÙØ®Ø±Ø¬Ø§Øª"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Set expression"
-msgstr "النسخة الحالية:"
+msgstr "تحديد التعبير"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Resize VisualShader node"
-msgstr ""
+msgstr "تغيير حجم عÙقدة VisualShader (التظليل البصري)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Set Uniform Name"
-msgstr ""
+msgstr "تحديد اسم موحد"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Set Input Default Port"
-msgstr "حدد ÙƒØ¥ÙØªØ±Ø§Ø¶ÙŠ Ù…Ù† أجل '%s'"
+msgstr "تحديد Ù…Ù†ÙØ° المدخلات Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add Node to Visual Shader"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© عÙقدة للتظليل البصري Visual Shader"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Duplicate Nodes"
-msgstr "Ù…ÙØ§ØªÙŠØ­ نسخ التحريك"
+msgstr "Ù…Ø¶Ø§Ø¹ÙØ© العÙقد"
#: editor/plugins/visual_shader_editor_plugin.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Paste Nodes"
-msgstr ""
+msgstr "لصق العÙقد"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Delete Nodes"
-msgstr "إنشاء عقدة"
+msgstr "حذ٠العÙقد"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Visual Shader Input Type Changed"
-msgstr ""
+msgstr "تعدل نوع Ù…ÙØ¯Ø®Ù„ات التظليل البصري Visual Shader"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vertex"
-msgstr ""
+msgstr "رأس"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Fragment"
-msgstr "البراهين:"
+msgstr "شظايا"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Light"
-msgstr ""
+msgstr "ضوء"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Show resulted shader code."
-msgstr "إنشاء عقدة"
+msgstr "إظهار نص التظليل البرمجي الناتج."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Create Shader Node"
-msgstr "إنشاء عقدة"
+msgstr "إنشاء عÙقدة تظليل"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color function."
-msgstr "مسح المهمة"
+msgstr "Ø§Ù„ÙˆØ¸ÙŠÙØ© البرمجية للون."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Color operator."
-msgstr ""
+msgstr "Ù…ÙØ´ØºÙ‘Ù„ اللون."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Grayscale function."
-msgstr "إصنع دالة"
+msgstr "ÙˆØ¸ÙŠÙØ© التدرج الرمادي."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts HSV vector to RGB equivalent."
-msgstr ""
+msgstr "تحويل Ù…ÙØªØ¬Ù‡ HSV إلى معادله من RGB."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts RGB vector to HSV equivalent."
-msgstr ""
+msgstr "تحويل Ù…ÙØªØ¬Ù‡ RGB إلى معادله من HSV."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Sepia function."
-msgstr "إصنع دالة"
+msgstr "ÙˆØ¸ÙŠÙØ© البÙني الداكن."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Burn operator."
-msgstr ""
+msgstr "Ù…ÙØ´ØºÙ„ الحرق."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Darken operator."
-msgstr ""
+msgstr "Ù…ÙØ´ØºÙ„ التعتيم."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Difference operator."
-msgstr "Ø§Ù„Ø¥Ø®ØªÙ„Ø§ÙØ§Øª Ùقط"
+msgstr "Ù…ÙØ´ØºÙ„ Ø§Ù„ÙØ§Ø±Ù‚."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Dodge operator."
-msgstr ""
+msgstr "Ù…ÙØ´ØºÙ„ التملص Dodge."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "HardLight operator."
-msgstr ""
+msgstr "Ù…ÙØ´ØºÙ„ الضوء الساطع."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Lighten operator."
-msgstr ""
+msgstr "Ù…ÙØ´ØºÙ„ Ø§Ù„ØªÙØªÙŠØ­."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Overlay operator."
-msgstr ""
+msgstr "Ù…ÙØ´ØºÙ„ التراكم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Screen operator."
-msgstr ""
+msgstr "Ù…ÙØ´ØºÙ„ الشاشة."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "SoftLight operator."
-msgstr ""
+msgstr "Ù…ÙØ´ØºÙ„ الضوء Ø§Ù„Ø®Ø§ÙØª."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color constant."
-msgstr "ثابت"
+msgstr "ثابت اللون."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color uniform."
-msgstr "تحويل تغيير التحريك"
+msgstr "اللون المÙوحد."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the boolean result of the %s comparison between two parameters."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ المنطق الناتج عن مقارنة %s بين اثنين من Ø§Ù„Ù…ÙØ¹Ø§Ù…لات."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Equal (==)"
-msgstr ""
+msgstr "ÙŠÙØ¹Ø§Ø¯Ù„ (==)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Greater Than (>)"
-msgstr ""
+msgstr "أكبر من (>)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Greater Than or Equal (>=)"
-msgstr ""
+msgstr "أكبر أو يساوي (>=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided scalars are equal, greater or "
"less."
msgstr ""
+"ÙŠÙØ±Ø¬Ø¹ Ø§Ù„Ù…ÙØªØ¬Ù‡ المقرون إذا كانت القيمة القياسية المÙقدمة مساوية، أكبر أو أصغر."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the boolean result of the comparison between INF and a scalar "
"parameter."
msgstr ""
+"ÙŠÙØ±Ø¬Ø¹ قيمة المنطق (صح/خطأ) من المقارنة بين INF ومَعلم الكمية القياسية scalar "
+"parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the boolean result of the comparison between NaN and a scalar "
"parameter."
msgstr ""
+"ÙŠÙØ±Ø¬Ø¹ منطق المقارنة (صحيح/خاطئ) بين NaN (ليس عدداً) Ùˆ مَعلم الكمية القياسية "
+"scalar parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Less Than (<)"
-msgstr ""
+msgstr "أصغر من (<)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Less Than or Equal (<=)"
-msgstr ""
+msgstr "أصغر أو يساوي (<=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Not Equal (!=)"
-msgstr ""
+msgstr "لا ÙŠÙØ¹Ø§Ø¯Ù„ (!=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated vector if the provided boolean value is true or false."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ المٌتجه المقرون إن كانت قيمة المنطق المزود صحيحة أو خاطئة."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns an associated scalar if the provided boolean value is true or false."
msgstr ""
+"ÙŠÙØ±Ø¬Ø¹ قيمة الكمية القياسية scalar المقرونة إن كانت قيمة المنطق المزود صحيحة "
+"أو خاطئة."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the boolean result of the comparison between two parameters."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ نتيجة المنطق (صحيح/خاطئ) بعد المقارنة بين اثنين من المعالم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the boolean result of the comparison between INF (or NaN) and a "
"scalar parameter."
msgstr ""
+"ÙŠÙØ±Ø¬Ø¹ نتيجة المنطق (صحيح/خاطئ) الناتج عن المقارنة ما بين INF (أو NaN \"ليس "
+"عدداً\") و مَعلم كمية قياسية scalar parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
-msgstr ""
+msgstr "ثابت المنطق (صحيح/خاطئ)."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean uniform."
-msgstr ""
+msgstr "المنطق (صحيح/خاطئ) المÙوحد."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for all shader modes."
-msgstr ""
+msgstr "'%s' مَعلم Ø§Ù„Ù…ÙØ¯Ø®Ù„ لأجل جميع أساليب التظليل shader modes."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Input parameter."
-msgstr "الكبس إلي الطÙÙ„"
+msgstr "مَعلم Ø§Ù„Ù…ÙØ¯Ø®Ù„."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader modes."
-msgstr ""
+msgstr "'%s' مَعلم Ø§Ù„Ù…ÙØ¯Ø®Ù„ لأجل أساليب تظليل الرأس والقطع."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment and light shader modes."
-msgstr ""
+msgstr "'%s' مَعلم Ø§Ù„Ù…ÙØ¯Ø®Ù„ لأجل أساليب تظليل القطع والإضاءة."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for fragment shader mode."
-msgstr ""
+msgstr "'%s' مَعلم Ø§Ù„Ù…ÙØ¯Ø®Ù„ لأجل أساليب تظليل القطع."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for light shader mode."
-msgstr ""
+msgstr "'%s' مَعلم Ø§Ù„Ù…ÙØ¯Ø®Ù„ لأسلوب تظليل الإضاءة."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex shader mode."
-msgstr ""
+msgstr "'%s' مَعلم Ø§Ù„Ù…ÙØ¯Ø®Ù„ لأجل تظليل الرأس vertex."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader mode."
-msgstr ""
+msgstr "'%s' مَعلم Ø§Ù„Ù…ÙØ¯Ø®Ù„ لأجل أساليب تظليل الرأس ÙˆØ§Ù„Ù‚ÙØ·Ø¹."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar function."
-msgstr "تكبير المحدد"
+msgstr "ÙˆØ¸ÙŠÙØ© الكمية القياسية Scalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Scalar operator."
-msgstr ""
+msgstr "Ù…ÙØ´ØºÙ„ الكمية القياسية Scalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "E constant (2.718282). Represents the base of the natural logarithm."
msgstr ""
-"ثابت E ويعادل القيمة (2.718282)ØŒ وهو يمثل الأساس ÙÙŠ اللوغاريتم الطبيعي."
+"الثابت E وتعادل قيمته (2.718282)ØŒ وهو يمثل الأساس ÙÙŠ اللوغاريتم الطبيعي."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Epsilon constant (0.00001). Smallest possible scalar number."
@@ -9189,141 +8996,142 @@ msgstr "يحسب القيمة المطلقة لقيمة المَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-cosine of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة جيب التمام \"arc-cosine\" للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse hyperbolic cosine of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة جيب تمام القطع الزائد العكسي للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة الجيب العكسية للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse hyperbolic sine of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة جيب القطع الزائد العكسي للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة ظل الزاوية العكسية \"arc-tangent\" للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameters."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة ظل الزاوية العكسي \"arc-tangent\" للمعالم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse hyperbolic tangent of the parameter."
msgstr ""
+"ÙŠÙØ±Ø¬Ø¹ قيمة ظل الزاوية العكسي (قطع زائد) \"inverse hyperbolic tangent\" للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Finds the nearest integer that is greater than or equal to the parameter."
-msgstr ""
+msgstr "يجد أقرب رقم أكبر أو يساوي المَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Constrains a value to lie between two further values."
-msgstr ""
+msgstr "ÙŠÙØ¬Ø¨Ø± قيمة على التوضع بين قيميتن إضاÙيتين."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the cosine of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ جيب التمام \"cosine \" لقيمة المَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic cosine of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة جيب التمام الزائدي \"hyperbolic cosine\" لقيمة المَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
-msgstr ""
+msgstr "يحوّل قيمة (كمية) من الراديان إلى الدرجات."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-e Exponential."
-msgstr ""
+msgstr "الدالة Base-e."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 Exponential."
-msgstr ""
+msgstr "الدالة Base-2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer less than or equal to the parameter."
-msgstr ""
+msgstr "يجد أقرب رقم أصغر أو يساوي المَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Computes the fractional part of the argument."
-msgstr ""
+msgstr "يحسب الجزء الكسري من المعامل."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse of the square root of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ عكس قيمة الجذر التربيعي للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Natural logarithm."
-msgstr ""
+msgstr "اللوغاريتم الطبيعي."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 logarithm."
-msgstr ""
+msgstr "اللوغاريتم Base-2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the greater of two values."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ القيمة Ø§Ù„ÙƒÙØ¨Ø±Ù‰ بين القيمتين."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the lesser of two values."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ القيمة الأصغر بين القيمتين."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two scalars."
-msgstr ""
+msgstr "Ø§Ø³ØªÙŠÙØ§Ø¡ (استقراء داخلي interpolation ) خطي بين كميتين قياسيتين scalar."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the opposite value of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ القيمة المعاكسة للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 - scalar"
-msgstr ""
+msgstr "1.0 - الكمية القياسية"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the value of the first parameter raised to the power of the second."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة المَعلم الأول مرÙوعاً إلى قوّة الثاني."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in degrees to radians."
-msgstr ""
+msgstr "يحول الكمية المقاسة بالدرجات إلى الراديان."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 / scalar"
-msgstr ""
+msgstr "1.0 \\ الكمية القياسية"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer to the parameter."
-msgstr ""
+msgstr "يوجد الرقم الأقرب للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest even integer to the parameter."
-msgstr ""
+msgstr "يجد العدد الزوجي الأقرب لقيمة المَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
-msgstr ""
+msgstr "ÙŠÙمخلب (يحصر) القيمة بين 0.0 Ùˆ 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Extracts the sign of the parameter."
-msgstr ""
+msgstr "يستخرج إشارة المَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the sine of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ جيب sine المَعلم parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic sine of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة الجيب العكس hyperbolic sine للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة الجذر التربيعي للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9333,6 +9141,12 @@ msgid ""
"'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 "
"using Hermite polynomials."
msgstr ""
+"Ø§Ù„ÙˆØ¸ÙŠÙØ© البرمجية \"الخطوة الناعمة\" SmoothStep وهي function( scalar(edge0), "
+"scalar(edge1), scalar(x) ).\n"
+"\n"
+"ØªÙØ±Ø¬Ø¹ 0.0 إذا كان 'x' أصغر من 'edge0' Ùˆ 1.0 إذا كان x أكبر من 'edge1'. عدا "
+"ذلك سيتم Ø§Ø³ØªÙŠÙØ§Ø¡ (استقراء داخلي interpolated) للقيمة ما بين 0.0 Ùˆ 1.0 "
+"باستخدام متعددات الحدود لهيرمت Hermite polynomials."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9340,42 +9154,45 @@ msgid ""
"\n"
"Returns 0.0 if 'x' is smaller than 'edge' and otherwise 1.0."
msgstr ""
+"Ø§Ù„ÙˆØ¸ÙŠÙØ© البرمجية \"الخطوة\" function( scalar(edge), scalar(x) ).\n"
+"\n"
+"ØªÙØ±Ø¬Ø¹ 0.0 إذا كان 'x' أصغر من 'edge' وعدا ذلك 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the tangent of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة ظل الزاوية tangent للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic tangent of the parameter."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ قيمة ظل الزاوية العكسي hyperbolic tangent للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the truncated value of the parameter."
-msgstr ""
+msgstr "يجد قيمة الاقتطاع truncated للمَعلم."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© كمية قياسية إلى كمية قياسية."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides scalar by scalar."
-msgstr ""
+msgstr "تقسيم كمية قياسية على كمية قياسية."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies scalar by scalar."
-msgstr ""
+msgstr "الضرب الرياضي لكمية قياسية بكمية قياسية."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two scalars."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ باقي الكميتين القياسيتين."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts scalar from scalar."
-msgstr ""
+msgstr "طرح كمية قياسية من كمية قياسية."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Scalar constant."
-msgstr ""
+msgstr "ثابت الكمية القياسية Scalar constant."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9384,28 +9201,28 @@ msgstr "تحويل تغيير التحريك"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the cubic texture lookup."
-msgstr ""
+msgstr "إجراء البحث عن النقش المكعبي."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the texture lookup."
-msgstr ""
+msgstr "إجراء البحث عن النقش."
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Cubic texture uniform lookup."
-msgstr ""
+msgstr "البحث عن النقش المكعبي الموحد."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "2D texture uniform lookup."
-msgstr ""
+msgstr "البحث عن النقش الموحد ثنائي Ø§Ù„Ø¨ÙØ¹Ø¯."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform function."
-msgstr "إنشاء بولي"
+msgstr "ÙˆØ¸ÙŠÙØ© التحويل."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9420,70 +9237,67 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes transform from four vectors."
-msgstr ""
+msgstr "تألي٠التحوّل من أربع Ù…ÙØªØ¬Ù‡Ø§Øª vectors."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes transform to four vectors."
-msgstr ""
+msgstr "Ùكّ التحوّل إلى أربع Ù…ÙØªØ¬Ù‡Ø§Øª vectors."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the determinant of a transform."
-msgstr ""
+msgstr "حساب Ù…ÙØ­Ø¯Ø¯ determinant التحوّل."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the inverse of a transform."
-msgstr ""
+msgstr "حساب عكس التحوّل."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the transpose of a transform."
-msgstr ""
+msgstr "حساب تبدل موضع التحوّل."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies transform by transform."
-msgstr ""
+msgstr "Ù…Ø¶Ø§Ø¹ÙØ© التحوّلات بالتحوّل."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by transform."
-msgstr ""
+msgstr "Ù…ÙØ¶Ø§Ø¹ÙØ© Ø§Ù„Ù…ÙØªØ¬Ù‡Ø§Øª بالتحوّل."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform constant."
-msgstr "إنشاء بولي"
+msgstr "ثابت التحوّل."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform uniform."
-msgstr "إنشاء بولي"
+msgstr "Ù…Ùوحد التحوّل Transform uniform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector function."
-msgstr "التعيين لتعمل."
+msgstr "ÙˆØ¸ÙŠÙØ© Ø§Ù„Ù…ÙØªØ¬Ù‡ Vector ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector operator."
-msgstr ""
+msgstr "Ù…ÙØ´ØºÙ‘Ù„ Ø§Ù„Ù…ÙØªØ¬Ù‡."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Composes vector from three scalars."
-msgstr ""
+msgstr "ØªØ£Ù„ÙŠÙ Ø§Ù„Ù…ÙØªØ¬Ù‡ من ثلاث كميات قياسية."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Decomposes vector to three scalars."
-msgstr ""
+msgstr "Ùكّ تركيب Ø§Ù„Ù…ÙØªØ¬Ù‡ إلى ثلاث كميات قياسية."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the cross product of two vectors."
-msgstr ""
+msgstr "حساب المنتوج الوسيط Ù„Ù„Ù…ÙØªØ¬Ù‡ÙŠÙ†."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the distance between two points."
-msgstr ""
+msgstr "ÙŠÙØ±Ø¬Ø¹ Ø§Ù„Ù…Ø³Ø§ÙØ© ما بين نقطتين."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the dot product of two vectors."
-msgstr ""
+msgstr "حساب الجداء السلمي dot product Ù„Ù„Ù…ÙØªØ¬Ù‡ÙŠÙ† (الشعاعين)."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9495,15 +9309,17 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the length of a vector."
-msgstr ""
+msgstr "حساب طول Ø§Ù„Ù…ÙØªØ¬Ù‡ (الشعاع)."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two vectors."
-msgstr ""
+msgstr "Ø§Ù„Ø§Ø³ØªÙŠÙØ§Ø¡ (الاستقراء الداخلي interpolation ) بين Ù…ÙØªØ¬Ù‡ÙŠÙ†."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two vectors using scalar."
msgstr ""
+"Ø§Ù„Ø§Ø³ØªÙŠÙØ§Ø¡ (الاستقراء الداخلي interpolation) بين Ù…ÙØªØ¬Ù‡ÙŠÙ† باستخدام الكمية "
+"القياسية."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Calculates the normalize product of vector."
@@ -9565,7 +9381,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides vector by vector."
-msgstr ""
+msgstr "ÙŠÙقسّم Ø§Ù„Ù…ÙØªØ¬Ù‡ (الشعاع) على Ø§Ù„Ù…ÙØªØ¬Ù‡."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies vector by vector."
@@ -9655,43 +9471,43 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "VisualShader"
-msgstr ""
+msgstr "Ø§Ù„Ù…ÙØ¸Ù„Ù„ البصري"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Edit Visual Property"
-msgstr "تعديل المصاÙÙŠ"
+msgstr "تحرير الخاصية البصرية"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Visual Shader Mode Changed"
-msgstr ""
+msgstr "تغيير وضع Ø§Ù„Ù…ÙØ¸Ù„Ù„ البصري"
#: editor/project_export.cpp
msgid "Runnable"
-msgstr ""
+msgstr "قابل للتشغيل"
#: editor/project_export.cpp
-#, fuzzy
msgid "Add initial export..."
-msgstr "أض٠مدخله"
+msgstr "Ø¥Ø¶Ø§ÙØ© تصدير مبدئي..."
#: editor/project_export.cpp
msgid "Add previous patches..."
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© الرÙقع السابقة..."
#: editor/project_export.cpp
msgid "Delete patch '%s' from list?"
-msgstr ""
+msgstr "حذ٠رÙقعة '%s' من القائمة؟"
#: editor/project_export.cpp
msgid "Delete preset '%s'?"
-msgstr ""
+msgstr "Ø­Ø°Ù Ø§Ù„Ù…ÙØ¹Ø¯ Ù…ÙØ³Ø¨Ù‚اً '%s'ØŸ"
#: editor/project_export.cpp
msgid ""
"Failed to export the project for platform '%s'.\n"
"Export templates seem to be missing or invalid."
msgstr ""
+"أخÙÙ‚ تصدير المشروع لمنصة '%s'.\n"
+"على ما يبدو قوالب التصدير Ù…Ùقودة أو غير صالحة."
#: editor/project_export.cpp
msgid ""
@@ -9699,165 +9515,165 @@ msgid ""
"This might be due to a configuration issue in the export preset or your "
"export settings."
msgstr ""
+"أخÙÙ‚ تصدير المشروع لمنصة '%s'.\n"
+"قد يعود ذلك إلى خلل تهيئة ÙÙŠ الإعدادات Ø§Ù„Ù…ÙØ¹Ø¯Ù‘Ø© Ø³Ù„ÙØ§Ù‹ أو إعدادات التصدير الخاصة "
+"بك."
#: editor/project_export.cpp
msgid "Release"
-msgstr ""
+msgstr "الإصدار"
#: editor/project_export.cpp
-#, fuzzy
msgid "Exporting All"
-msgstr "التصدير كـ %s"
+msgstr "تصدير الكÙÙ„"
#: editor/project_export.cpp
-#, fuzzy
msgid "The given export path doesn't exist:"
-msgstr "هذا المسار غير موجود."
+msgstr "مسار التصدير Ø§Ù„Ù…ÙØ²ÙˆØ¯ غير موجود:"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing/corrupted:"
-msgstr ""
+msgstr "قوالب تصدير هذه المنصة Ù…Ùقودة / ØªØ§Ù„ÙØ©:"
#: editor/project_export.cpp
msgid "Presets"
-msgstr ""
+msgstr "Ù…ÙØ¹Ø¯ Ø³Ù„ÙØ§Ù‹"
#: editor/project_export.cpp editor/project_settings_editor.cpp
msgid "Add..."
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ©..."
#: editor/project_export.cpp
msgid ""
"If checked, the preset will be available for use in one-click deploy.\n"
"Only one preset per platform may be marked as runnable."
msgstr ""
+"إن تم تحدديها، ستتم إتاحة Ø§Ù„Ù…ÙØ¹Ø¯Ù‘Ø© Ø³Ù„ÙØ§Ù‹ لتكون جاهزة للنشر deploy بضغط واحدة.\n"
+"Ùقط واحدة من Ø§Ù„Ù…ÙØ¹Ø¯Ù‘Ø© Ø³Ù„ÙØ§Ù‹ preset لكل منصة ستوسم على أنها قابلة للتشغيل."
#: editor/project_export.cpp
-#, fuzzy
msgid "Export Path"
-msgstr "تصدير المشروع"
+msgstr "مسار التصدير"
#: editor/project_export.cpp
msgid "Resources"
-msgstr ""
+msgstr "الموراد"
#: editor/project_export.cpp
msgid "Export all resources in the project"
-msgstr ""
+msgstr "تصدير جميع الموارد ÙÙŠ المشروع"
#: editor/project_export.cpp
msgid "Export selected scenes (and dependencies)"
-msgstr ""
+msgstr "تصدير المشاهد Ø§Ù„Ù…ÙØ®ØªØ§Ø±Ø© (وتبعاتها)"
#: editor/project_export.cpp
msgid "Export selected resources (and dependencies)"
-msgstr ""
+msgstr "تصدير الموارد Ø§Ù„Ù…ÙØ®ØªØ§Ø±Ø© (وتبعياتها)"
#: editor/project_export.cpp
msgid "Export Mode:"
-msgstr ""
+msgstr "وضع التصدير:"
#: editor/project_export.cpp
msgid "Resources to export:"
-msgstr ""
+msgstr "الموارد Ø§Ù„Ù…ÙØ¹Ø¯Ù‘Ø© للتصدير:"
#: editor/project_export.cpp
msgid ""
"Filters to export non-resource files/folders\n"
"(comma-separated, e.g: *.json, *.txt, docs/*)"
msgstr ""
+"Ù…ÙØ±Ø´Ø­Ø§Øª Filters تصدير Ø§Ù„Ù…Ù„ÙØ§Øª / المجلدات من غير الموارد\n"
+"(تلك Ø§Ù„Ù…ÙØµÙˆÙ„Ø© Ø¨Ø§Ù„ÙØ§ØµÙ„ة، على سبيل المثال: *.json, *.txt, docs/*)"
#: editor/project_export.cpp
msgid ""
"Filters to exclude files/folders from project\n"
"(comma-separated, e.g: *.json, *.txt, docs/*)"
msgstr ""
+"Ù…ÙØ±Ø´Ø­Ø§Øª Filters تصدير Ø§Ù„Ù…Ù„ÙØ§Øª/Ø§Ù„Ù…ÙØ¬Ù„دات من المشروع\n"
+"(Ø§Ù„Ù…ÙØµÙˆÙ„Ø© Ø¨ÙØ§ØµÙ„ة، مثلاً: *.json, *.txt, docs/*)"
#: editor/project_export.cpp
msgid "Patches"
-msgstr ""
+msgstr "الرÙقع Patches"
#: editor/project_export.cpp
msgid "Make Patch"
-msgstr ""
+msgstr "إنشاء رÙقعة Patch"
#: editor/project_export.cpp
-#, fuzzy
msgid "Pack File"
-msgstr " Ù…Ù„ÙØ§Øª"
+msgstr "Ù…Ù„Ù Ø§Ù„Ø­ÙØ²Ù…Ø©"
#: editor/project_export.cpp
msgid "Features"
-msgstr ""
+msgstr "المزايا"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
-msgstr ""
+msgstr "Ù…ÙØ®ØµØµ (Ù…ÙØµÙˆÙ„ Ø¨ÙØ§ØµÙ„Ø©):"
#: editor/project_export.cpp
msgid "Feature List:"
-msgstr ""
+msgstr "قائمة المزايا:"
#: editor/project_export.cpp
-#, fuzzy
msgid "Script"
-msgstr "تشغيل الكود"
+msgstr "النص البرمجي"
#: editor/project_export.cpp
-#, fuzzy
msgid "Script Export Mode:"
-msgstr "تصدير المشروع"
+msgstr "وضع تصدير النص البرمجي:"
#: editor/project_export.cpp
msgid "Text"
-msgstr ""
+msgstr "نص"
#: editor/project_export.cpp
msgid "Compiled"
-msgstr ""
+msgstr "Ù…ÙØ­ÙˆÙ„Ø© برمجياً"
#: editor/project_export.cpp
msgid "Encrypted (Provide Key Below)"
-msgstr ""
+msgstr "مشÙّرة (قدّم Ø§Ù„Ù…ÙØªØ§Ø­ أدناه)"
#: editor/project_export.cpp
msgid "Invalid Encryption Key (must be 64 characters long)"
-msgstr ""
+msgstr "Ù…ÙØªØ§Ø­ تشÙير غير صالح (ينبغي أن يكون طوله 46 حرÙ)"
#: editor/project_export.cpp
msgid "Script Encryption Key (256-bits as hex):"
-msgstr ""
+msgstr "Ù…ÙØªØ§Ø­ تشÙير النص البرمجي (256-bits Ùƒ hex ):"
#: editor/project_export.cpp
msgid "Export PCK/Zip"
-msgstr ""
+msgstr "تصدير PCK/ مل٠مضغوط Zip"
#: editor/project_export.cpp
msgid "Export Project"
msgstr "تصدير المشروع"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export mode?"
-msgstr "تصدير المشروع"
+msgstr "وضع التصدير؟"
#: editor/project_export.cpp
-#, fuzzy
msgid "Export All"
-msgstr "تصدير"
+msgstr "تصدير الكÙÙ„"
#: editor/project_export.cpp editor/project_manager.cpp
-#, fuzzy
msgid "ZIP File"
-msgstr " Ù…Ù„ÙØ§Øª"
+msgstr "المل٠المضغوط ZIP File"
#: editor/project_export.cpp
msgid "Godot Game Pack"
-msgstr ""
+msgstr "Ø±ÙØ²Ù…Ø© لعبة غودوت"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing:"
-msgstr ""
+msgstr "قوالب التصدير لهذه المنصة Ù…Ùقودة:"
#: editor/project_export.cpp
msgid "Manage Export Templates"
@@ -9865,47 +9681,44 @@ msgstr "إدارة قوالب التصدير"
#: editor/project_export.cpp
msgid "Export With Debug"
-msgstr ""
+msgstr "التصدير مع Ù…Ùنقح الأخطاء"
#: editor/project_manager.cpp
-#, fuzzy
msgid "The path specified doesn't exist."
-msgstr "هذا المسار غير موجود."
+msgstr "المسار Ø§Ù„Ù…ÙØ­Ø¯Ø¯ غير موجود."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Error opening package file (it's not in ZIP format)."
msgstr "حدث خطأ Ø¹Ù†Ø¯ÙØªØ­ مل٠الحزمة بسبب أن المل٠ليس ÙÙŠ صيغة \"ZIP\"."
#: editor/project_manager.cpp
msgid ""
"Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file."
-msgstr ""
+msgstr "مل٠المشروع \".zip\" غير صالح؛ لا يحوي مل٠\"project.godot\"."
#: editor/project_manager.cpp
msgid "Please choose an empty folder."
-msgstr ""
+msgstr "من ÙØ¶Ù„Ùƒ اختر Ù…ÙØ¬Ù„داً ÙØ§Ø±ØºØ§Ù‹."
#: editor/project_manager.cpp
msgid "Please choose a \"project.godot\" or \".zip\" file."
-msgstr ""
+msgstr "من ÙØ¶Ù„Ùƒ اختر مل٠\"project.godot\" أو \".zip\"."
#: editor/project_manager.cpp
msgid "This directory already contains a Godot project."
-msgstr ""
+msgstr "الدليل Ø§Ù„Ù…ÙØ®ØªØ§Ø± يتضمن Ø¨Ø§Ù„ÙØ¹Ù„ مشروعاً لغودوت."
#: editor/project_manager.cpp
msgid "New Game Project"
-msgstr ""
+msgstr "مشروع لعبة جديد"
#: editor/project_manager.cpp
msgid "Imported Project"
-msgstr ""
+msgstr "المشاريع المستوردة"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Invalid Project Name."
-msgstr "اسم غير صالح."
+msgstr "اسم مشروع غير صالح."
#: editor/project_manager.cpp
msgid "Couldn't create folder."
@@ -9913,37 +9726,38 @@ msgstr "لا يمكن إنشاء المجلد."
#: editor/project_manager.cpp
msgid "There is already a folder in this path with the specified name."
-msgstr ""
+msgstr "يوجد Ù…Ù„Ù Ø¨Ø§Ù„ÙØ¹Ù„ بالمسار Ø§Ù„Ù…ÙØ®ØªØ§Ø± بذات الاسم Ø§Ù„Ù…ÙØ®ØªØ§Ø±."
#: editor/project_manager.cpp
msgid "It would be a good idea to name your project."
-msgstr ""
+msgstr "إنها Ù„Ùكرة جيدة أن تقوم بتسمية مشروعك."
#: editor/project_manager.cpp
msgid "Invalid project path (changed anything?)."
-msgstr ""
+msgstr "مسار مشروع غير صالح (أعدلت شيء؟)."
#: editor/project_manager.cpp
msgid ""
"Couldn't load project.godot in project path (error %d). It may be missing or "
"corrupted."
msgstr ""
+"لم يتم تحميل project.godot من مسار المشروع (خطأ %d). قد يكون Ù…Ùقوداً أو ØªØ§Ù„ÙØ§Ù‹."
#: editor/project_manager.cpp
msgid "Couldn't edit project.godot in project path."
-msgstr ""
+msgstr "لا قدرة على تحرير project.godot ÙÙŠ مسار المشروع."
#: editor/project_manager.cpp
msgid "Couldn't create project.godot in project path."
-msgstr ""
+msgstr "لا قدرة على إنشاء project.godot ÙÙŠ مسار المشروع."
#: editor/project_manager.cpp
msgid "Rename Project"
-msgstr ""
+msgstr "إعادة تسمية المشروع"
#: editor/project_manager.cpp
msgid "Import Existing Project"
-msgstr ""
+msgstr "استيراد مشروع موجود"
#: editor/project_manager.cpp
msgid "Import & Edit"
@@ -9951,7 +9765,7 @@ msgstr "إستيراد و تعديل"
#: editor/project_manager.cpp
msgid "Create New Project"
-msgstr ""
+msgstr "إنشاء مشروع جديد"
#: editor/project_manager.cpp
msgid "Create & Edit"
@@ -9959,7 +9773,7 @@ msgstr "إنشاء و تعديل"
#: editor/project_manager.cpp
msgid "Install Project:"
-msgstr ""
+msgstr "تنصيب المشروع:"
#: editor/project_manager.cpp
msgid "Install & Edit"
@@ -9967,23 +9781,23 @@ msgstr "تثبيت و تعديل"
#: editor/project_manager.cpp
msgid "Project Name:"
-msgstr ""
+msgstr "اسم المشروع:"
#: editor/project_manager.cpp
msgid "Project Path:"
-msgstr ""
+msgstr "مسار المشروع:"
#: editor/project_manager.cpp
msgid "Project Installation Path:"
-msgstr ""
+msgstr "مسار تنصيب المشروع:"
#: editor/project_manager.cpp
msgid "Renderer:"
-msgstr ""
+msgstr "Ù…ÙØ­Ø±Ùƒ الإخراج البصري:"
#: editor/project_manager.cpp
msgid "OpenGL ES 3.0"
-msgstr ""
+msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid ""
@@ -9992,10 +9806,14 @@ msgid ""
"Incompatible with older hardware\n"
"Not recommended for web games"
msgstr ""
+"جودة بصرية أعلى\n"
+"جميع الميزات المتاحة\n"
+"غير متواÙÙ‚ مع الأجهزة القديمة\n"
+"لا ينصح به لألعاب الويب"
#: editor/project_manager.cpp
msgid "OpenGL ES 2.0"
-msgstr ""
+msgstr "OpenGL ES 2.0"
#: editor/project_manager.cpp
msgid ""
@@ -10004,32 +9822,34 @@ msgid ""
"Works on most hardware\n"
"Recommended for web games"
msgstr ""
+"جودة بصرية أقل\n"
+"بعض الميزات غير Ù…ØªÙˆÙØ±Ø© \n"
+"يعمل على معظم الأجهزة\n"
+"يوصى به لألعاب الويب"
#: editor/project_manager.cpp
msgid "Renderer can be changed later, but scenes may need to be adjusted."
-msgstr ""
+msgstr "يمكن تعديل جهاز العرض لاحقاً، ولكن قد تحتاج المشاهد إلى تعديل."
#: editor/project_manager.cpp
msgid "Unnamed Project"
-msgstr ""
+msgstr "مشروع غير مسمى"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Missing Project"
-msgstr "بناء المشروع"
+msgstr "مشروع Ù…Ùقود"
#: editor/project_manager.cpp
msgid "Error: Project is missing on the filesystem."
-msgstr ""
+msgstr "خطأ: المشروع Ù…Ùقود ÙÙŠ نظام Ø§Ù„Ù…Ù„ÙØ§Øª."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Can't open project at '%s'."
-msgstr "لا يمكن ÙØªØ­ المشروع"
+msgstr "لا يمكن ÙØªØ­ المشروع ÙÙŠ '%s'."
#: editor/project_manager.cpp
msgid "Are you sure to open more than one project?"
-msgstr ""
+msgstr "هل أنت واثق من ÙØªØ­ أكثر من مشروع؟"
#: editor/project_manager.cpp
msgid ""
@@ -10061,188 +9881,208 @@ msgid ""
"The project settings were created by a newer engine version, whose settings "
"are not compatible with this version."
msgstr ""
+"لقد تم إنشاء إعدادات المشروع هذا بإصدار أحدث من Ø§Ù„Ù…ÙØ­Ø±ÙƒØŒ تلك الإعدادات غير "
+"متواÙقة مع هذا الإصدار."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Can't run project: no main scene defined.\n"
"Please edit the project and set the main scene in the Project Settings under "
"the \"Application\" category."
msgstr ""
-"لا مشهد أساسي تم تحديده، حدد واحد؟\n"
-"يمكنك تغييره لاحقاً ÙÙŠ \"إعدادات المشروع\" تحت قسم 'التطبيق'."
+"لا يمكن تشغيل المشروع: لم يتم تحديد مشهد رئيس.\n"
+"من ÙØ¶Ù„Ùƒ حرر المشروع وحدد مشهداً رئيساً ÙÙŠ إعدادات المشروع تحت خيار \"التطبيق\"."
#: editor/project_manager.cpp
msgid ""
"Can't run project: Assets need to be imported.\n"
"Please edit the project to trigger the initial import."
msgstr ""
+"لا يمكن تشغيل المشروع: يجب استيراد المÙلحقات.\n"
+"من ÙØ¶Ù„Ùƒ حرر المشروع لتحريض الشروع بالاستيراد."
#: editor/project_manager.cpp
msgid "Are you sure to run %d projects at once?"
-msgstr ""
+msgstr "هل أنت متأكد من ÙØªØ­ %d مشاريع مرّة واحدة؟"
#: editor/project_manager.cpp
msgid ""
"Remove %d projects from the list?\n"
"The project folders' contents won't be modified."
msgstr ""
+"إزالة %d مشاريع من القائمة؟\n"
+"لن يتم تعديل محتويات Ù…ÙØ¬Ù„دات المشاريع."
#: editor/project_manager.cpp
msgid ""
"Remove this project from the list?\n"
"The project folder's contents won't be modified."
msgstr ""
+"إزالة هذا المشروع من القائمة؟\n"
+"لن يتم تعديل محتوى Ù…ÙØ¬Ù„د المشروع."
#: editor/project_manager.cpp
msgid ""
"Remove all missing projects from the list?\n"
"The project folders' contents won't be modified."
msgstr ""
+"إزالة جميع المشاريع المÙقودة من القائمة؟\n"
+"لن يتم تعديل محتوى Ù…ÙØ¬Ù„دات المشاريع."
#: editor/project_manager.cpp
msgid ""
"Language changed.\n"
"The interface will update after restarting the editor or project manager."
msgstr ""
+"تم تغيير Ø§Ù„Ù„ÙØºØ©.\n"
+"ستتحدث الواجهة بعد إعادة تشغيل Ø§Ù„Ù…ÙØ­Ø±Ø± أو Ù…ÙØ¯ÙŠØ± المشاريع."
#: editor/project_manager.cpp
msgid ""
"Are you sure to scan %s folders for existing Godot projects?\n"
"This could take a while."
msgstr ""
+"هل أنت متأكد من ÙØ­Øµ %s من المجلدات بحثاً عن مشاريع غودوت Ù…ØªÙˆØ§ÙØ±Ø©ØŸ\n"
+"قد يستغرق وقتاً."
#: editor/project_manager.cpp
msgid "Project Manager"
msgstr "مدير المشروع"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Projects"
-msgstr "مشروع"
+msgstr "المشاريع"
#: editor/project_manager.cpp
msgid "Last Modified"
-msgstr ""
+msgstr "آخر ما تم تعديله"
#: editor/project_manager.cpp
msgid "Scan"
-msgstr ""
+msgstr "ÙØ­Øµ"
#: editor/project_manager.cpp
msgid "Select a Folder to Scan"
-msgstr ""
+msgstr "اختر Ù…ÙØ¬Ù„داً Ù„ÙØ­ØµÙ‡"
#: editor/project_manager.cpp
msgid "New Project"
-msgstr ""
+msgstr "مشروع جديد"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Remove Missing"
-msgstr "مسح النقطة"
+msgstr "إزالة المÙقود"
#: editor/project_manager.cpp
msgid "Templates"
-msgstr ""
+msgstr "القوالب"
#: editor/project_manager.cpp
msgid "Restart Now"
-msgstr ""
+msgstr "إعادة التشغيل الآن"
#: editor/project_manager.cpp
msgid "Can't run project"
-msgstr ""
+msgstr "غير قادر على تشغيل المشروع"
#: editor/project_manager.cpp
msgid ""
"You currently don't have any projects.\n"
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+"لا تملك حالياً أية مشاريع.\n"
+"هل ترغب ÙÙŠ استكشا٠مشاريع الأمثلة الرسمية ÙÙŠ مكتبة المÙلحقات؟"
+
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
#: editor/project_settings_editor.cpp
msgid "Key "
-msgstr ""
+msgstr "زر "
#: editor/project_settings_editor.cpp
msgid "Joy Button"
-msgstr ""
+msgstr "زر Joy"
#: editor/project_settings_editor.cpp
msgid "Joy Axis"
-msgstr ""
+msgstr "محور Joy"
#: editor/project_settings_editor.cpp
msgid "Mouse Button"
-msgstr ""
+msgstr "زر Ø§Ù„ÙØ£Ø±Ø©"
#: editor/project_settings_editor.cpp
msgid ""
"Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'"
msgstr ""
+"اسم ÙØ¹Ø§Ù„ية غير صحيح. لا يمكن أن يكون ÙØ§Ø±ØºØ§Ù‹ أو أو يتضمن '/'ØŒ ':'ØŒ '='ØŒ '\\' "
+"أو '\"'"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "An action with the name '%s' already exists."
-msgstr "خطأ: إسم الحركة موجود Ø¨Ø§Ù„ÙØ¹Ù„!"
+msgstr "ÙØ¹Ø§Ù„ية action بهذا الاسم '%s' موجودة Ø³Ù„ÙØ§Ù‹."
#: editor/project_settings_editor.cpp
msgid "Rename Input Action Event"
-msgstr ""
+msgstr "إعادة تسمية حدث ÙØ¹Ø§Ù„ية الإدخال"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Change Action deadzone"
-msgstr "تغيير إسم الحركة:"
+msgstr "تغيير المنطقة الميتة Ù„Ù„ÙØ¹Ø§Ù„ية Action deadzone"
#: editor/project_settings_editor.cpp
msgid "Add Input Action Event"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© حدث ÙØ¹Ø§Ù„ية الإدخال"
#: editor/project_settings_editor.cpp
msgid "All Devices"
-msgstr ""
+msgstr "جميع الأجهزة"
#: editor/project_settings_editor.cpp
msgid "Device"
-msgstr ""
+msgstr "الجهاز"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Press a Key..."
-msgstr ""
+msgstr "اضغط زراً..."
#: editor/project_settings_editor.cpp
msgid "Mouse Button Index:"
-msgstr ""
+msgstr "مؤشر Index زر Ø§Ù„ÙØ£Ø±Ø©:"
#: editor/project_settings_editor.cpp
msgid "Left Button"
-msgstr ""
+msgstr "الزر الأيسر"
#: editor/project_settings_editor.cpp
msgid "Right Button"
-msgstr ""
+msgstr "الزر الأيمن"
#: editor/project_settings_editor.cpp
msgid "Middle Button"
-msgstr ""
+msgstr "الزر الأوسط"
#: editor/project_settings_editor.cpp
msgid "Wheel Up Button"
-msgstr ""
+msgstr "زر العجلة للأعلى"
#: editor/project_settings_editor.cpp
msgid "Wheel Down Button"
-msgstr ""
+msgstr "زر العجلة للأسÙÙ„"
#: editor/project_settings_editor.cpp
msgid "Wheel Left Button"
-msgstr ""
+msgstr "زر العجلة يساراً"
#: editor/project_settings_editor.cpp
msgid "Wheel Right Button"
-msgstr ""
+msgstr "زر العجلة يميناً"
#: editor/project_settings_editor.cpp
msgid "X Button 1"
@@ -10270,73 +10110,75 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Erase Input Action Event"
-msgstr ""
+msgstr "مسح حدث إجراء Ø§Ù„Ø¥Ø¶Ø§ÙØ©"
#: editor/project_settings_editor.cpp
msgid "Add Event"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© حَدث"
#: editor/project_settings_editor.cpp
msgid "Button"
-msgstr ""
+msgstr "زر"
#: editor/project_settings_editor.cpp
msgid "Left Button."
-msgstr ""
+msgstr "الزر الأيسر."
#: editor/project_settings_editor.cpp
msgid "Right Button."
-msgstr ""
+msgstr "الزر الأيمن."
#: editor/project_settings_editor.cpp
msgid "Middle Button."
-msgstr ""
+msgstr "الزر الأوسط."
#: editor/project_settings_editor.cpp
msgid "Wheel Up."
-msgstr ""
+msgstr "العجلة نحو الأقصى."
#: editor/project_settings_editor.cpp
msgid "Wheel Down."
-msgstr ""
+msgstr "العجلة نحو الأدنى."
#: editor/project_settings_editor.cpp
msgid "Add Global Property"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© خاصية شمولية"
#: editor/project_settings_editor.cpp
msgid "Select a setting item first!"
-msgstr ""
+msgstr "اختر عنصر إعدادات بدايةً!"
#: editor/project_settings_editor.cpp
msgid "No property '%s' exists."
-msgstr ""
+msgstr "لا خاصية '%s' موجودة."
#: editor/project_settings_editor.cpp
msgid "Setting '%s' is internal, and it can't be deleted."
-msgstr ""
+msgstr "الإعداد '%s' ضمني، ولا يمكن حذÙÙ‡."
#: editor/project_settings_editor.cpp
msgid "Delete Item"
-msgstr ""
+msgstr "حذ٠العÙنصر"
#: editor/project_settings_editor.cpp
msgid ""
"Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or "
"'\"'."
msgstr ""
+"اسم إجراء غير صالح. لا يجوز أن يكون الاسم ÙØ§Ø±ØºØ§Ù‹ أو متضمناً '/'ØŒ ':'ØŒ'='ØŒ '\\' "
+"أو'\"'."
#: editor/project_settings_editor.cpp
msgid "Add Input Action"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© إجراء إدخال"
#: editor/project_settings_editor.cpp
msgid "Error saving settings."
-msgstr ""
+msgstr "خطأ ÙÙŠ Ø­ÙØ¸ الإعدادات."
#: editor/project_settings_editor.cpp
msgid "Settings saved OK."
-msgstr ""
+msgstr "تيسّر Ø­ÙØ¸ الإعدادات."
#: editor/project_settings_editor.cpp
#, fuzzy
@@ -10345,19 +10187,19 @@ msgstr "حرك النقطة داخل المنحنى"
#: editor/project_settings_editor.cpp
msgid "Override for Feature"
-msgstr ""
+msgstr "التجاوز للميزة"
#: editor/project_settings_editor.cpp
msgid "Add Translation"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© ترجمة"
#: editor/project_settings_editor.cpp
msgid "Remove Translation"
-msgstr ""
+msgstr "إزالة الترجمة"
#: editor/project_settings_editor.cpp
msgid "Add Remapped Path"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© مسار Ù…ÙØ¹Ø§Ø¯ تعيينه Remapped"
#: editor/project_settings_editor.cpp
msgid "Resource Remap Add Remap"
@@ -10377,7 +10219,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Changed Locale Filter"
-msgstr ""
+msgstr "Ù…ÙØ±Ø´Ø­ محلي Ù…ÙØ¹Ø¯Ù‘Ù„"
#: editor/project_settings_editor.cpp
msgid "Changed Locale Filter Mode"
@@ -10385,7 +10227,7 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Project Settings (project.godot)"
-msgstr ""
+msgstr "إعدادات المشروع (project.godot)"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "General"
@@ -10393,47 +10235,47 @@ msgstr "بشكل عام"
#: editor/project_settings_editor.cpp
msgid "Override For..."
-msgstr ""
+msgstr "تجاوز لأجل..."
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "The editor must be restarted for changes to take effect."
-msgstr ""
+msgstr "لكي يظهر تأثير التغييرات ينبغي إعادة تشغيل Ø§Ù„Ù…ÙØ­Ø±Ø±."
#: editor/project_settings_editor.cpp
msgid "Input Map"
-msgstr ""
+msgstr "خريطة الإدخال"
#: editor/project_settings_editor.cpp
msgid "Action:"
-msgstr ""
+msgstr "إجراء:"
#: editor/project_settings_editor.cpp
msgid "Action"
-msgstr "Ø§Ù„ÙØ¹Ù„"
+msgstr "إجراء"
#: editor/project_settings_editor.cpp
msgid "Deadzone"
-msgstr ""
+msgstr "الحيز الميّت"
#: editor/project_settings_editor.cpp
msgid "Device:"
-msgstr ""
+msgstr "الجهاز:"
#: editor/project_settings_editor.cpp
msgid "Index:"
-msgstr ""
+msgstr "الÙهرس:"
#: editor/project_settings_editor.cpp
msgid "Localization"
-msgstr ""
+msgstr "توطين"
#: editor/project_settings_editor.cpp
msgid "Translations"
-msgstr ""
+msgstr "الترجمات"
#: editor/project_settings_editor.cpp
msgid "Translations:"
-msgstr ""
+msgstr "الترجمات:"
#: editor/project_settings_editor.cpp
msgid "Remaps"
@@ -10441,41 +10283,39 @@ msgstr ""
#: editor/project_settings_editor.cpp
msgid "Resources:"
-msgstr ""
+msgstr "الموارد:"
#: editor/project_settings_editor.cpp
msgid "Remaps by Locale:"
-msgstr ""
+msgstr "إعادة تعيين الخرائط محلياً:"
#: editor/project_settings_editor.cpp
msgid "Locale"
-msgstr ""
+msgstr "محلي"
#: editor/project_settings_editor.cpp
msgid "Locales Filter"
-msgstr ""
+msgstr "Ù…ÙØ±Ø´Ø­ المحليّات Locales"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show All Locales"
-msgstr "إظهار العظام"
+msgstr "إظهار جميع المَحليّات Locales"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Show Selected Locales Only"
-msgstr "المحدد Ùقط"
+msgstr "إظهار المَحليّات Ø§Ù„Ù…ÙØ®ØªØ§Ø±Ø© ÙØ­Ø³Ø¨"
#: editor/project_settings_editor.cpp
msgid "Filter mode:"
-msgstr "وضع Ø§Ù„Ù…ÙØµÙÙŠ:"
+msgstr "وضع Ø§Ù„Ù…ÙØ±Ø´Ø­:"
#: editor/project_settings_editor.cpp
msgid "Locales:"
-msgstr ""
+msgstr "مَحليّات:"
#: editor/project_settings_editor.cpp
msgid "AutoLoad"
-msgstr ""
+msgstr "تحميل تلقائي"
#: editor/project_settings_editor.cpp
msgid "Plugins"
@@ -10487,19 +10327,19 @@ msgstr "إعداد Ù…ÙØ³Ø¨Ù‚..."
#: editor/property_editor.cpp
msgid "Zero"
-msgstr ""
+msgstr "ØµÙØ±"
#: editor/property_editor.cpp
msgid "Easing In-Out"
-msgstr ""
+msgstr "تسارع بعد بداية بطيئة"
#: editor/property_editor.cpp
msgid "Easing Out-In"
-msgstr ""
+msgstr "تباطؤ بعد بداية سريعة"
#: editor/property_editor.cpp
msgid "File..."
-msgstr ""
+msgstr "ملÙ..."
#: editor/property_editor.cpp
msgid "Dir..."
@@ -10507,31 +10347,31 @@ msgstr ""
#: editor/property_editor.cpp
msgid "Assign"
-msgstr ""
+msgstr "ألحق"
#: editor/property_editor.cpp
msgid "Select Node"
-msgstr ""
+msgstr "اختر عÙقدة"
#: editor/property_editor.cpp
msgid "Error loading file: Not a resource!"
-msgstr ""
+msgstr "خطأ ÙÙŠ تحميل الملÙ: ليس مورداً!"
#: editor/property_editor.cpp
msgid "Pick a Node"
-msgstr ""
+msgstr "اختر عÙقدة"
#: editor/property_editor.cpp
msgid "Bit %d, val %d."
-msgstr ""
+msgstr "Bit %d، قيمة%d."
#: editor/property_selector.cpp
msgid "Select Property"
-msgstr ""
+msgstr "انتقاء الخاصية"
#: editor/property_selector.cpp
msgid "Select Virtual Method"
-msgstr "إختر طريقة Ø¥ÙØªØ±Ø§Ø¶ÙŠØ©"
+msgstr "اختر الطريقة Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠØ©"
#: editor/property_selector.cpp
msgid "Select Method"
@@ -10544,25 +10384,23 @@ msgstr "إعادة التسمية"
#: editor/rename_dialog.cpp
msgid "Prefix"
-msgstr ""
+msgstr "بادئة"
#: editor/rename_dialog.cpp
msgid "Suffix"
-msgstr ""
+msgstr "لاحقة"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Use Regular Expressions"
-msgstr "النسخة الحالية:"
+msgstr "استخدام التعبيرات الاعتيادية Regular Expressions"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Advanced Options"
-msgstr "إعدادات الكبس"
+msgstr "إعدادات Ù…ÙØªÙ‚دمة"
#: editor/rename_dialog.cpp
msgid "Substitute"
-msgstr ""
+msgstr "استبدال"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10571,40 +10409,39 @@ msgstr "إسم العقدة:"
#: editor/rename_dialog.cpp
msgid "Node's parent name, if available"
-msgstr ""
+msgstr "اسم العÙقدة الأب، إن ØªÙˆØ§ÙØ±"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Node type"
-msgstr "إسم العقدة:"
+msgstr "نوع العÙقدة"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Current scene name"
-msgstr "لم يتم Ø­ÙØ¸ المشهد الحالي. Ø¥ÙØªØ­Ù‡ علي أية حال؟"
+msgstr "اسم المشهد الحالي"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Root node name"
-msgstr "إعادة التسمية"
+msgstr "اسم العÙقدة الرئيسة (الجذر)"
#: editor/rename_dialog.cpp
msgid ""
"Sequential integer counter.\n"
"Compare counter options."
msgstr ""
+"عداد الأعداد الصحيحة التسلسلية.\n"
+"يقارن إعدادات العداد."
#: editor/rename_dialog.cpp
msgid "Per-level Counter"
-msgstr ""
+msgstr "العداد ÙˆÙÙ‚-المستوى"
#: editor/rename_dialog.cpp
msgid "If set the counter restarts for each group of child nodes"
-msgstr ""
+msgstr "إذا تم تحديده ÙØ¥Ù† العداد سيعيد البدء لكل مجموعة من العÙقد الأبناء"
#: editor/rename_dialog.cpp
msgid "Initial value for the counter"
-msgstr ""
+msgstr "القيمة المبدئية للعداد"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10613,7 +10450,7 @@ msgstr "خطوة (ثانية):"
#: editor/rename_dialog.cpp
msgid "Amount by which counter is incremented for each node"
-msgstr ""
+msgstr "مقدار الزيادة للعداد لكل عÙقدة"
#: editor/rename_dialog.cpp
msgid "Padding"
@@ -10627,31 +10464,31 @@ msgstr ""
#: editor/rename_dialog.cpp
msgid "Post-Process"
-msgstr ""
+msgstr "المعالجة-اللاحقة Post-Process"
#: editor/rename_dialog.cpp
msgid "Keep"
-msgstr ""
+msgstr "Ø§Ø­ØªÙØ¸"
#: editor/rename_dialog.cpp
msgid "PascalCase to snake_case"
-msgstr ""
+msgstr "حالة أحر٠PascalCase إلى snake_case"
#: editor/rename_dialog.cpp
msgid "snake_case to PascalCase"
-msgstr ""
+msgstr "حالة أحر٠snake_case إلى PascalCase"
#: editor/rename_dialog.cpp
msgid "Case"
-msgstr ""
+msgstr "حالة"
#: editor/rename_dialog.cpp
msgid "To Lowercase"
-msgstr ""
+msgstr "لأحر٠صغيرة Lowercase"
#: editor/rename_dialog.cpp
msgid "To Uppercase"
-msgstr ""
+msgstr "لأحر٠كبيرة Uppercase"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10660,74 +10497,73 @@ msgstr "إرجاع التكبير"
#: editor/rename_dialog.cpp
msgid "Regular Expression Error"
-msgstr ""
+msgstr "خطأ ذو علاقة بالتعبير الاعتيادي Regular Expression"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "At character %s"
-msgstr "الأحر٠الصالحة:"
+msgstr "عند الحر٠%s"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent Node"
-msgstr ""
+msgstr "إعادة اختيار أبوة العÙقدة"
#: editor/reparent_dialog.cpp
msgid "Reparent Location (Select new Parent):"
-msgstr ""
+msgstr "إعادة اختيار أبوة المكان (اختر أب جديد):"
#: editor/reparent_dialog.cpp
msgid "Keep Global Transform"
-msgstr ""
+msgstr "Ø§Ù„Ø§Ø­ØªÙØ§Ø¸ بالتحوّل الشمولي Global"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent"
-msgstr ""
+msgstr "إعادة اختيار الأبوة"
#: editor/run_settings_dialog.cpp
msgid "Run Mode:"
-msgstr ""
+msgstr "وضع التشغيل:"
#: editor/run_settings_dialog.cpp
msgid "Current Scene"
-msgstr ""
+msgstr "المشهد الحالي"
#: editor/run_settings_dialog.cpp
msgid "Main Scene"
-msgstr ""
+msgstr "المشهد الرئيس"
#: editor/run_settings_dialog.cpp
msgid "Main Scene Arguments:"
-msgstr ""
+msgstr "معاملات المشهد الرئيس:"
#: editor/run_settings_dialog.cpp
msgid "Scene Run Settings"
-msgstr ""
+msgstr "إعدادت تشغيل المشهد"
#: editor/scene_tree_dock.cpp
msgid "No parent to instance the scenes at."
-msgstr ""
+msgstr "لا أب لنمذجة المشاهد عنده."
#: editor/scene_tree_dock.cpp
msgid "Error loading scene from %s"
-msgstr ""
+msgstr "خطأ ÙÙŠ تحميل المشهد من %s"
#: editor/scene_tree_dock.cpp
msgid ""
"Cannot instance the scene '%s' because the current scene exists within one "
"of its nodes."
-msgstr ""
+msgstr "لا يمكن نمذجة المشهد '%s' لأن المشهد الحالي Ù…ÙØªØ¶ÙŽÙ…Ù† ÙÙŠ واحد من عÙقده."
#: editor/scene_tree_dock.cpp
msgid "Instance Scene(s)"
-msgstr ""
+msgstr "نمذجة المشهد(المشاهد)"
#: editor/scene_tree_dock.cpp
msgid "Replace with Branch Scene"
-msgstr ""
+msgstr "استبدال بمشهد ÙØ±Ø¹ÙŠ"
#: editor/scene_tree_dock.cpp
msgid "Instance Child Scene"
-msgstr ""
+msgstr "نمذجة المشهد الابن"
#: editor/scene_tree_dock.cpp
msgid "Clear Script"
@@ -10735,31 +10571,33 @@ msgstr "إخلاء الكود"
#: editor/scene_tree_dock.cpp
msgid "This operation can't be done on the tree root."
-msgstr ""
+msgstr "لا يمكن إجراء هذه العملية على جذر الشجرة."
#: editor/scene_tree_dock.cpp
msgid "Move Node In Parent"
-msgstr ""
+msgstr "نقل العÙقدة عند الأب"
#: editor/scene_tree_dock.cpp
msgid "Move Nodes In Parent"
-msgstr ""
+msgstr "تحريك العÙقد عند الأب"
#: editor/scene_tree_dock.cpp
msgid "Duplicate Node(s)"
-msgstr ""
+msgstr "Ù…Ø¶Ø§Ø¹ÙØ© العÙقدة(العÙقد)"
#: editor/scene_tree_dock.cpp
msgid "Can't reparent nodes in inherited scenes, order of nodes can't change."
msgstr ""
+"لا يمكن إعادة اختيار أبوة العÙقدة ÙÙŠ المشاهد الموروثة، لا يمكن تغيير ترتيب "
+"العÙقد."
#: editor/scene_tree_dock.cpp
msgid "Node must belong to the edited scene to become root."
-msgstr ""
+msgstr "لكي تصبح هذه العÙقدة رئيسة (جذر) عليها أن تنتمي إلى المشهد Ø§Ù„Ù…ÙØ­Ø±Ø±."
#: editor/scene_tree_dock.cpp
msgid "Instantiated scenes can't become root"
-msgstr ""
+msgstr "لا يمكن أن تصبح المشاهد المنمذجة مشاهد رئيسة (جذر)"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -10773,11 +10611,11 @@ msgstr "إنشاء عقدة"
#: editor/scene_tree_dock.cpp
msgid "Delete the root node \"%s\"?"
-msgstr ""
+msgstr "حذ٠العÙقدة الرئيسة (الجذر) \"%s\"ØŸ"
#: editor/scene_tree_dock.cpp
msgid "Delete node \"%s\" and its children?"
-msgstr ""
+msgstr "حذ٠العÙقدة \"%s\" مع جميع أبنائها؟"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -10786,56 +10624,56 @@ msgstr "إنشاء عقدة"
#: editor/scene_tree_dock.cpp
msgid "Can not perform with the root node."
-msgstr ""
+msgstr "لا يمكن التنÙيذ مع العÙقدة الرئيسة (الجذر)."
#: editor/scene_tree_dock.cpp
msgid "This operation can't be done on instanced scenes."
-msgstr ""
+msgstr "لا يمكن تنÙيذ هذا الإجراء على المشاهد المÙنمذجة."
#: editor/scene_tree_dock.cpp
msgid "Save New Scene As..."
-msgstr ""
+msgstr "Ø§Ø­ÙØ¸ المشهد الجديد كـ..."
#: editor/scene_tree_dock.cpp
msgid ""
"Disabling \"editable_instance\" will cause all properties of the node to be "
"reverted to their default."
msgstr ""
+"سيسبب تعطيل خاصية \"النمذجة_Ø§Ù„Ù…ÙØ­Ø±Ø±Ø©\" \"editable_instance\" عودة قيم العÙقد "
+"إلى القيم Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ© لها."
#: editor/scene_tree_dock.cpp
msgid ""
"Enabling \"Load As Placeholder\" will disable \"Editable Children\" and "
"cause all properties of the node to be reverted to their default."
msgstr ""
+"سيسبب تمكين \"التحميل كعنصر نائب\" \"Load As Placeholder\" تعطيل \"ابن قابل "
+"للتحرير\" \"Editable Children\" والذي ينجم عنه عودة قيم جميع العÙقد إلى قيمها "
+"Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ©."
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Make Local"
-msgstr "أنشئ عظام"
+msgstr "اجعله محلياً"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "New Scene Root"
-msgstr "Ø­ÙØ¸ المشهد"
+msgstr "مشهد رئيس (جذر) جديد"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Create Root Node:"
-msgstr "إنشاء عقدة"
+msgstr "إنشاء العÙقدة الرئيسة (الجذر):"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "2D Scene"
-msgstr "مشهد"
+msgstr "مشهد ثنائي Ø§Ù„Ø¨ÙØ¹Ø¯"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "3D Scene"
-msgstr "مشهد"
+msgstr "مشهد ثلاثي الأبعاد"
#: editor/scene_tree_dock.cpp
msgid "User Interface"
-msgstr ""
+msgstr "واجهة المستخدم"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -10844,37 +10682,37 @@ msgstr "إنشاء عقدة"
#: editor/scene_tree_dock.cpp
msgid "Can't operate on nodes from a foreign scene!"
-msgstr ""
+msgstr "لا يمكن تنÙيذ الإجراء على عÙقدة من مشهد أجنبي!"
#: editor/scene_tree_dock.cpp
msgid "Can't operate on nodes the current scene inherits from!"
-msgstr ""
+msgstr "لا يمكن تنÙيذ الإجراء على عÙقد يرثها المشهد الحالي!"
#: editor/scene_tree_dock.cpp
msgid "Attach Script"
-msgstr ""
+msgstr "إلحاق نص برمجي"
#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
-msgstr ""
+msgstr "إزالة عÙقدة (عÙقد)"
#: editor/scene_tree_dock.cpp
msgid "Change type of node(s)"
-msgstr ""
+msgstr "تغيير نوع العÙقدة(العÙقد)"
#: editor/scene_tree_dock.cpp
msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
-msgstr ""
+msgstr "لم ينجح Ø­ÙØ¸ المشهد الجديد. غالباً لا يمكن إشباع التبعات (النماذج)."
#: editor/scene_tree_dock.cpp
msgid "Error saving scene."
-msgstr ""
+msgstr "خطأ ÙÙŠ Ø­ÙØ¸ المشهد."
#: editor/scene_tree_dock.cpp
msgid "Error duplicating scene to save it."
-msgstr ""
+msgstr "خطأ ÙÙŠ Ù…Ø¶Ø§Ø¹ÙØ© المشهد Ù„Ø­ÙØ¸Ù‡."
#: editor/scene_tree_dock.cpp
msgid "Sub-Resources"
@@ -10882,15 +10720,15 @@ msgstr "مورد ÙØ±Ø¹ÙŠ"
#: editor/scene_tree_dock.cpp
msgid "Clear Inheritance"
-msgstr ""
+msgstr "مسح الميراث"
#: editor/scene_tree_dock.cpp
msgid "Editable Children"
-msgstr ""
+msgstr "أبناء قابلين للتعديل"
#: editor/scene_tree_dock.cpp
msgid "Load As Placeholder"
-msgstr ""
+msgstr "تحميله كعنصر نائب"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -10899,7 +10737,7 @@ msgstr "ÙÙØªØ­ مؤخراً"
#: editor/scene_tree_dock.cpp
msgid "Add Child Node"
-msgstr ""
+msgstr "Ø¥Ø¶Ø§ÙØ© عÙقدة ابن"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -10908,7 +10746,7 @@ msgstr "طوي الكل"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
-msgstr ""
+msgstr "تغيير النوع"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -10922,19 +10760,19 @@ msgstr "Ø­ÙØ¸ المشهد"
#: editor/scene_tree_dock.cpp
msgid "Merge From Scene"
-msgstr ""
+msgstr "دمج من المشهد"
#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
msgid "Save Branch as Scene"
-msgstr ""
+msgstr "Ø­ÙØ¸ Ø§Ù„ÙØ±Ø¹ كمشهد"
#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
msgid "Copy Node Path"
-msgstr ""
+msgstr "نسخ مسار العÙقدة"
#: editor/scene_tree_dock.cpp
msgid "Delete (No Confirm)"
-msgstr ""
+msgstr "حذ٠(دون تأكيد)"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -10946,14 +10784,16 @@ msgid ""
"Instance a scene file as a Node. Creates an inherited scene if no root node "
"exists."
msgstr ""
+"نمذجة مل٠المشهد كعÙقدة. إن لم يكن هناك عÙقدة رئيسة (جذر) سيتم إنشاء مشهد "
+"موروث."
#: editor/scene_tree_dock.cpp
msgid "Attach a new or existing script for the selected node."
-msgstr ""
+msgstr "إلحاق نص برمجي موجود أو جديد للعÙقدة المختارة."
#: editor/scene_tree_dock.cpp
msgid "Clear a script for the selected node."
-msgstr ""
+msgstr "مسح النص البرمجي للعÙقدة المختارة."
#: editor/scene_tree_dock.cpp
msgid "Remote"
@@ -10961,11 +10801,11 @@ msgstr "عن بعد"
#: editor/scene_tree_dock.cpp
msgid "Local"
-msgstr ""
+msgstr "محلي"
#: editor/scene_tree_dock.cpp
msgid "Clear Inheritance? (No Undo!)"
-msgstr ""
+msgstr "مسح الموروث؟ (لا تراجع!)"
#: editor/scene_tree_editor.cpp
#, fuzzy
@@ -11273,9 +11113,8 @@ msgid "Profiler"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Network Profiler"
-msgstr "تصدير المشروع"
+msgstr "مل٠تعري٠الشبكة Network Profiler"
#: editor/script_editor_debugger.cpp
msgid "Monitor"
@@ -11302,6 +11141,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "تصدير الملÙ"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
@@ -11335,11 +11179,11 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Set From Tree"
-msgstr ""
+msgstr "التحديد من الشجرة"
#: editor/script_editor_debugger.cpp
msgid "Export measures as CSV"
-msgstr ""
+msgstr "تصدير القياسات ك CSV"
#: editor/settings_config_dialog.cpp
#, fuzzy
@@ -11348,7 +11192,7 @@ msgstr "تخÙي٠للخارج"
#: editor/settings_config_dialog.cpp
msgid "Restore Shortcut"
-msgstr ""
+msgstr "إعادة تعيين الاختصارات"
#: editor/settings_config_dialog.cpp
#, fuzzy
@@ -11361,15 +11205,15 @@ msgstr "إعدادات Ø§Ù„Ù…ÙØ¹Ø¯Ù„"
#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
-msgstr ""
+msgstr "الاختصارات"
#: editor/settings_config_dialog.cpp
msgid "Binding"
-msgstr ""
+msgstr "الربط"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Light Radius"
-msgstr ""
+msgstr "تغيير نص٠قطر الإنارة"
#: editor/spatial_editor_gizmos.cpp
msgid "Change AudioStreamPlayer3D Emission Angle"
@@ -11381,7 +11225,7 @@ msgstr ""
#: editor/spatial_editor_gizmos.cpp
msgid "Change Camera Size"
-msgstr ""
+msgstr "غيّر حجم الكاميرا"
#: editor/spatial_editor_gizmos.cpp
msgid "Change Notifier AABB"
@@ -11655,9 +11499,8 @@ msgid "Clear Selection"
msgstr "إخلاء المحدد"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Fill Selection"
-msgstr "ÙƒÙÙ„ Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
+msgstr "تعبئة Ø§Ù„Ù…ÙØ­Ø¯Ø¯"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "GridMap Settings"
@@ -12159,80 +12002,88 @@ msgstr "إخلاء الكود"
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Get %s"
-msgstr ""
+msgstr "جلب %s"
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
-msgstr ""
+msgstr "تحديد %s"
#: platform/android/export/export.cpp
msgid "Package name is missing."
-msgstr ""
+msgstr "اسم Ø§Ù„Ø±ÙØ²Ù…Ø© Ù…Ùقود."
#: platform/android/export/export.cpp
msgid "Package segments must be of non-zero length."
-msgstr ""
+msgstr "أقسام Ø§Ù„Ø±ÙØ²Ù…Ø© ينبغي أن تكون ذات Ù…Ø³Ø§ÙØ§Øª غير-ØµÙØ±ÙŠØ© non-zero length."
#: platform/android/export/export.cpp
msgid "The character '%s' is not allowed in Android application package names."
-msgstr ""
+msgstr "إن الحر٠'%s' غير مسموح ÙÙŠ أسماء Ø­ÙØ²Ù… تطبيقات الأندرويد."
#: platform/android/export/export.cpp
msgid "A digit cannot be the first character in a package segment."
-msgstr ""
+msgstr "لا يمكن أن يكون الرقم هو أول حر٠ÙÙŠ مقطع Ø§Ù„Ø±ÙØ²Ù…Ø©."
#: platform/android/export/export.cpp
msgid "The character '%s' cannot be the first character in a package segment."
-msgstr ""
+msgstr "الحر٠'%s' لا يمكن أن يكون الحر٠الأول من مقطع Ø§Ù„Ø±ÙØ²Ù…Ø©."
#: platform/android/export/export.cpp
msgid "The package must have at least one '.' separator."
-msgstr ""
+msgstr "يجب أن تتضمن الرزمة على الأقل واحد من الÙواصل '.' ."
#: platform/android/export/export.cpp
msgid "Select device from the list"
-msgstr "اختار جهاز من القائمة"
+msgstr "اختر جهازاً من القائمة"
#: platform/android/export/export.cpp
msgid "ADB executable not configured in the Editor Settings."
-msgstr ""
+msgstr "لم يتم تهيئة Ù…ÙÙ†Ùّذ ADB ÙÙŠ إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
#: platform/android/export/export.cpp
msgid "OpenJDK jarsigner not configured in the Editor Settings."
msgstr ""
+"‌مÙوقّع Ù…Ù„ÙØ§Øª الجار jarsigner Ø§Ù„Ù…ÙØªÙˆØ­ الخاص بحزمة التطوير OpenJDK غير Ù…Ùهيّئ ÙÙŠ "
+"إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
#: platform/android/export/export.cpp
msgid "Debug keystore not configured in the Editor Settings nor in the preset."
msgstr ""
+"Ù…Ùنقح أخطاء Ù…ÙØªØ§Ø­ المتجر keystore غير Ù…Ùهيئ ÙÙŠ إعدادت Ø§Ù„Ù…ÙØ­Ø±Ø± أو ÙÙŠ الإعدادات "
+"الموضوعة Ø³Ù„ÙØ§Ù‹."
#: platform/android/export/export.cpp
msgid "Custom build requires a valid Android SDK path in Editor Settings."
msgstr ""
+"البÙنى المخصوصة تتطلب مساراً لحزمة تطوير Android SDK صالحة ÙÙŠ إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
#: platform/android/export/export.cpp
msgid "Invalid Android SDK path for custom build in Editor Settings."
msgstr ""
+"مسار حزمة تطوير Android SDK للبÙنى المخصوصة، غير صالح ÙÙŠ إعدادات Ø§Ù„Ù…ÙØ­Ø±Ø±."
#: platform/android/export/export.cpp
msgid ""
"Android build template not installed in the project. Install it from the "
"Project menu."
msgstr ""
+"لم يتم تنزيل قالب بناء Android لهذا المشروع. نزّل واحداً من قائمة المشروع."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
-msgstr ""
+msgstr "Ù…ÙØªØ§Ø­ عام غير صالح لأجل تصدير حزمة تطبيق أندرويد APK."
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Invalid package name:"
-msgstr "إسم صن٠غير صالح"
+msgstr "اسم Ø±ÙØ²Ù…Ø© غير صالح:"
#: platform/android/export/export.cpp
msgid ""
"Trying to build from a custom built template, but no version info for it "
"exists. Please reinstall from the 'Project' menu."
msgstr ""
+"تتم محاولة البناء من قالب بناء Ù…ÙØ®ØµØµØŒ ولكن لا تتواجد معلومات النسخة. من ÙØ¶Ù„Ùƒ "
+"أعد التحميل من قائمة \"المشروع\"."
#: platform/android/export/export.cpp
msgid ""
@@ -12241,45 +12092,52 @@ msgid ""
" Godot Version: %s\n"
"Please reinstall Android build template from 'Project' menu."
msgstr ""
+"نسخ بناء Android غير متواÙقة:\n"
+"\tقوالب Ù…Ùنصبة: %s\n"
+"\tإصدار غودوت: %s\n"
+"من ÙØ¶Ù„Ùƒ أعد تنصيب قالب بناء الأندرويد Android من قائمة \"المشروع\"."
#: platform/android/export/export.cpp
msgid "Building Android Project (gradle)"
-msgstr ""
+msgstr "بناء مشروع الأندرويد (gradle)"
#: platform/android/export/export.cpp
msgid ""
"Building of Android project failed, check output for the error.\n"
"Alternatively visit docs.godotengine.org for Android build documentation."
msgstr ""
+"أخÙÙ‚ بناء مشروع الأندرويد، تÙقد Ø§Ù„Ù…ÙØ®Ø±Ø¬Ø§Øª للإطلاع على الخطأ.\n"
+"بصورة بديلة يمكنك زيارة docs.godotengine.org لأجل مستندات البناء للأندرويد."
#: platform/android/export/export.cpp
msgid "No build apk generated at: "
-msgstr ""
+msgstr "لم يتم توليد حزمة أندرويد apk ÙÙŠ: "
#: platform/iphone/export/export.cpp
msgid "Identifier is missing."
-msgstr ""
+msgstr "Ø§Ù„Ù…ÙØ­Ø¯Ø¯ Ù…Ùقود."
#: platform/iphone/export/export.cpp
msgid "The character '%s' is not allowed in Identifier."
-msgstr ""
+msgstr "إن الحر٠'%s' غير مسموح ÙÙŠ Ø§Ù„Ù…ÙØ­Ø¯Ø¯ Identifier."
#: platform/iphone/export/export.cpp
msgid "App Store Team ID not specified - cannot configure the project."
msgstr ""
+"لم يتم تحديد ID الÙÙØ±Ù‚ الخاص بمتجر التطبيقات - لا يمكن تهيئة configure "
+"المشروع."
#: platform/iphone/export/export.cpp
-#, fuzzy
msgid "Invalid Identifier:"
-msgstr "حجم الخط غير صالح"
+msgstr "Ù…ÙØ­Ø¯Ø¯ غير صالح:"
#: platform/iphone/export/export.cpp
msgid "Required icon is not specified in the preset."
-msgstr ""
+msgstr "الأيقونة المطلوبة لم ØªÙØ­Ø¯Ø¯ ÙÙŠ الإعدادات Ø§Ù„Ù…ÙØ³Ø¨Ù‚Ø©."
#: platform/javascript/export/export.cpp
msgid "Stop HTTP Server"
-msgstr ""
+msgstr "Ø¥ÙŠÙ‚Ø§Ù Ù…ÙØ®Ø¯Ù… HTTP"
#: platform/javascript/export/export.cpp
msgid "Run in Browser"
@@ -12311,65 +12169,59 @@ msgstr "لا يمكن قراءة مل٠الإقلاع الصوري:"
#: platform/javascript/export/export.cpp
msgid "Using default boot splash image."
-msgstr ""
+msgstr "استخدام الصورة Ø§Ù„Ø§ÙØªØ±Ø§Ø¶ÙŠØ© للشروع بالتشغيل."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid package short name."
-msgstr "إسم صن٠غير صالح"
+msgstr "اسم Ø§Ù„Ø±ÙØ²Ù…Ø© القصير غير صالح."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid package unique name."
-msgstr "اسم غير صالح."
+msgstr "الاسم المميز Ù„Ù„Ø±ÙØ²Ù…Ø© غير صالح."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid package publisher display name."
-msgstr "اسم غير صالح."
+msgstr "اسم الناشر المعروض Ù„Ù„Ø±ÙØ²Ù…Ø© غير صالح."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid product GUID."
-msgstr "اسم غير صالح."
+msgstr "Ù…ÙØ¹Ø±Ù GUID (Ø§Ù„Ù…ÙØ¹Ø±Ù‘Ù Ø§Ù„ÙØ±ÙŠØ¯ العالمي) للمنتج غير صالح."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid publisher GUID."
-msgstr "مسار غير صالح."
+msgstr "Ø§Ù„Ù…ÙØ¹Ø±Ù Ø§Ù„ÙØ±ÙŠØ¯ العالمي للناشر GUID غير صالح."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid background color."
-msgstr "اسم غير صالح."
+msgstr "لون خلÙية غير صالح."
#: platform/uwp/export/export.cpp
msgid "Invalid Store Logo image dimensions (should be 50x50)."
-msgstr ""
+msgstr "أبعاد صورة الشعار الخاص بالمتجر غير صالحة (ينبغي أن تكون50 × 50)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
-msgstr ""
+msgstr "أبعاد صورة الشعار المربع 44×44 غير صالحة (ينبغي أن تكون 44×44)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 71x71 logo image dimensions (should be 71x71)."
-msgstr ""
+msgstr "أبعاد صورة شعار 71×71 غير صالحة (ينبغي أن تكون 71×71)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 150x150 logo image dimensions (should be 150x150)."
-msgstr ""
+msgstr "أبعاد صورة الشعار Ø§Ù„Ù…ÙØ±Ø¨Ø¹ 150×150 غير صالحة (ينبغي أن تكون 150×150)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 310x310 logo image dimensions (should be 310x310)."
-msgstr ""
+msgstr "أبعاد صورة الشعار Ø§Ù„Ù…ÙØ±Ø¨Ø¹ 310×310 غير صالحة (ينبغي أن تكون 310×310)."
#: platform/uwp/export/export.cpp
msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)."
-msgstr ""
+msgstr "أبعاد صورة الشعار المربع 310x150 غير صالحة (ينبغي أن تكون 310x150)."
#: platform/uwp/export/export.cpp
msgid "Invalid splash screen image dimensions (should be 620x300)."
-msgstr ""
+msgstr "أبعاد شاشة البداية غير صالحة (ينبغي أن تكون 620×300)."
#: scene/2d/animated_sprite.cpp
#, fuzzy
@@ -12402,7 +12254,7 @@ msgstr ""
#: scene/2d/collision_polygon_2d.cpp
msgid "An empty CollisionPolygon2D has no effect on collision."
-msgstr ""
+msgstr "Ù…ÙØ¶Ù„ع تصادم ثنائي الأبعاد ÙØ§Ø±Øº ليس له أي تأثير على التصادم."
#: scene/2d/collision_shape_2d.cpp
msgid ""
@@ -12494,6 +12346,8 @@ msgstr ""
#: scene/2d/skeleton_2d.cpp
msgid "This Bone2D chain should end at a Skeleton2D node."
msgstr ""
+"سلسلة العظم ثنائي Ø§Ù„Ø¨ÙØ¹Ø¯ Bone2D هذه، ينبغي أن تنتهي ÙÙŠ عÙقدة هيكل ثنائي Ø§Ù„Ø¨ÙØ¹Ø¯ "
+"Skeleton2D."
#: scene/2d/skeleton_2d.cpp
msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
@@ -12547,11 +12401,11 @@ msgstr ""
#: scene/3d/baked_lightmap.cpp
msgid "%d%%"
-msgstr ""
+msgstr "%d%%"
#: scene/3d/baked_lightmap.cpp
msgid "(Time Left: %d:%02d s)"
-msgstr ""
+msgstr "(الوقت المتبقي: %d:%02d ثانية)"
#: scene/3d/baked_lightmap.cpp
msgid "Plotting Meshes: "
@@ -12636,7 +12490,7 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
-msgstr ""
+msgstr "بقعة الضوء بزاوية أكبر من 90 درجة لا يمكنها إلقاء الظلال."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -12668,7 +12522,7 @@ msgstr ""
#: scene/3d/path.cpp
msgid "PathFollow only works when set as a child of a Path node."
-msgstr ""
+msgstr "يعمل تتبع المسار PathFollow Ùقط عندما يكون ابناً لعÙقدة مسار Path."
#: scene/3d/path.cpp
msgid ""
@@ -12691,7 +12545,7 @@ msgstr ""
#: scene/3d/soft_body.cpp
msgid "This body will be ignored until you set a mesh."
-msgstr ""
+msgstr "سيتم تجاهل هذا الجسم حتى تضع تحدد سطحاً mesh."
#: scene/3d/soft_body.cpp
msgid ""
@@ -12737,45 +12591,43 @@ msgid "On BlendTree node '%s', animation not found: '%s'"
msgstr ""
#: scene/animation/animation_blend_tree.cpp
-#, fuzzy
msgid "Animation not found: '%s'"
-msgstr "أدوات الحركة"
+msgstr "لم يتم إيجاد الرسم المتحرك: '%s'"
#: scene/animation/animation_tree.cpp
msgid "In node '%s', invalid animation: '%s'."
-msgstr ""
+msgstr "ÙÙŠ العÙقدة '%s'ØŒ رسومية متحركة غير صالحة: '%s'."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Invalid animation: '%s'."
-msgstr "خطأ: إسم حركة خاطئ!"
+msgstr "رسومية متحركة غير صالحة: '%s'."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Nothing connected to input '%s' of node '%s'."
-msgstr "قطع إتصال'%s' من '%s'"
+msgstr "ليس هناك وصل بين أي من Ù…ÙØ¯Ø®Ù„ات '%s' للعÙقدة '%s'."
#: scene/animation/animation_tree.cpp
msgid "No root AnimationNode for the graph is set."
-msgstr ""
+msgstr "لم يتم تحديد عÙقدة رئيسة لعÙقدة الرسومات المتحركة لأجل الرسم graph."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Path to an AnimationPlayer node containing animations is not set."
-msgstr "حدد مشغل حركة من شجرة المشهد لكي تعدل الحركة."
+msgstr "لم يتم تحديد مسار يحتوي ارسومات المتحركة لعÙقدة Ù…ÙØ´ØºÙ„ الرسومات المتحركة."
#: scene/animation/animation_tree.cpp
msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node."
msgstr ""
+"المسار Ø§Ù„Ù…ÙØ­Ø¯Ø¯ Ù„Ù…ÙØ´ØºÙ„ الرسومات المتحركة لا يقود إلى عÙقدة Ù…ÙØ´ØºÙ„ رسومات Ù…ÙØªØ­Ø±ÙƒØ©."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "The AnimationPlayer root node is not a valid node."
-msgstr "شجرة الحركة خاطئة."
+msgstr "العÙقدة الرئيسة Ù„Ù…ÙØ´ØºÙ„ الرسومات المتحركة ليست عÙقدة صالحة."
#: scene/animation/animation_tree_player.cpp
msgid "This node has been deprecated. Use AnimationTree instead."
msgstr ""
+"لقد تم إهمال هذه العÙقدةز استخدم شجرة الرسومات المتحركة AnimationTree بدلاً عن "
+"ذلك."
#: scene/gui/color_picker.cpp
msgid ""
@@ -12783,27 +12635,29 @@ msgid ""
"LMB: Set color\n"
"RMB: Remove preset"
msgstr ""
+"اللون: #%s\n"
+"الزر الأيسر Ù„Ù„ÙØ£Ø±Ø©: تحديد اللون\n"
+"الزر الأيمن Ù„Ù„ÙØ£Ø±Ø©: إزالة اللون الحالي"
#: scene/gui/color_picker.cpp
msgid "Pick a color from the editor window."
-msgstr ""
+msgstr "اختر لوناً من Ù†Ø§ÙØ°Ø© Ø§Ù„Ù…ÙØ­Ø±Ø±."
#: scene/gui/color_picker.cpp
msgid "HSV"
-msgstr ""
+msgstr "HSV"
#: scene/gui/color_picker.cpp
msgid "Raw"
-msgstr ""
+msgstr "خام"
#: scene/gui/color_picker.cpp
msgid "Switch between hexadecimal and code values."
-msgstr ""
+msgstr "بدّل بين القيم البرمجية والسداسية العشرية."
#: scene/gui/color_picker.cpp
-#, fuzzy
msgid "Add current color as a preset."
-msgstr "أض٠اللون الحالي كإعداد مسبق"
+msgstr "أض٠اللون الحالي كإعداد مسبق."
#: scene/gui/container.cpp
msgid ""
@@ -12824,7 +12678,7 @@ msgstr "تنبيه!"
#: scene/gui/dialogs.cpp
msgid "Please Confirm..."
-msgstr "يرجى التاكيد..."
+msgstr "ÙŠÙØ±Ø¬Ù‰ التأكيد..."
#: scene/gui/popup.cpp
msgid ""
@@ -12846,7 +12700,7 @@ msgstr ""
#: scene/gui/tree.cpp
msgid "(Other)"
-msgstr ""
+msgstr "(أخرى)"
#: scene/main/scene_tree.cpp
msgid ""
@@ -12864,7 +12718,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
-msgstr ""
+msgstr "ينبغي أن يكون حجم إطار العرض أكبر من 0 ليتم الإخراج البصري لأي شيء."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
@@ -12876,11 +12730,11 @@ msgstr "مصدر غير صالح لتظليل."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid comparison function for that type."
-msgstr "comparison function غير صالحة لهذا النوع."
+msgstr "ÙˆØ¸ÙŠÙØ© برمجية Ù…ÙقارÙنة غير صالحة لأجل ذلك النوع."
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
-msgstr "التعيين لتعمل."
+msgstr "تكليÙها Ù„ÙˆØ¸ÙŠÙØ© برمجية."
#: servers/visual/shader_language.cpp
msgid "Assignment to uniform."
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index 1dcaf7fa32..c9be0c2c3f 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -8,7 +8,6 @@
# MaresPW <marespw206@gmail.com>, 2018.
# PakoSt <kokotekilata@gmail.com>, 2018, 2020.
# Damyan Dichev <mwshock2@gmail.com>, 2019.
-# anonymous <noreply@weblate.org>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
@@ -9684,6 +9683,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10796,6 +10802,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "ИзнаÑÑне на профила"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index b37267652e..aaa46da54d 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -7,12 +7,13 @@
# Tahmid Karim <tahmidk15@gmail.com>, 2016.
# Tawhid H. <Tawhidk757@yahoo.com>, 2019.
# Hasibul Hasan <hasibeng78@gmail.com>, 2019.
+# Oymate <dhruboadittya96@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-12-13 09:38+0000\n"
-"Last-Translator: Hasibul Hasan <hasibeng78@gmail.com>\n"
+"PO-Revision-Date: 2020-05-04 15:11+0000\n"
+"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Bengali <https://hosted.weblate.org/projects/godot-engine/"
"godot/bn/>\n"
"Language: bn\n"
@@ -20,7 +21,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Weblate 3.10-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -29,7 +30,7 @@ msgstr "অবৈধ পà§à¦°à¦•ার রূপানà§à¦¤à¦° করার à¦
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr ""
+msgstr "à§§ (à¦à¦•টি অকà§à¦·à¦°) দৈরà§à¦˜à§à¦¯ à¦à¦° সà§à¦Ÿà§à¦°à¦¿à¦‚ পà§à¦°à¦¤à§à¦¯à¦¾à¦¶à¦¿à¦¤à¥¤"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -10559,6 +10560,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "কী/চাবি "
@@ -11764,6 +11772,11 @@ msgid "Total:"
msgstr "সরà§à¦¬à¦®à§‹à¦Ÿ:"
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "পà§à¦°à¦•লà§à¦ª à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "রিসোরà§à¦¸-à¦à¦° পথ"
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index 21886cea24..a1577b5a15 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -10189,6 +10189,13 @@ msgstr ""
"Actualment no teniu cap projecte.\n"
"Us agradaria explorar projectes d'exemple oficials a la biblioteca d'actius?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Tecla "
@@ -11351,6 +11358,11 @@ msgid "Total:"
msgstr "Total:"
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Exportar Perfil"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Camí de Recursos"
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index 887bbeb8f4..566ff0c1e2 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -9916,6 +9916,13 @@ msgstr ""
"V této chvíli nemáte žádný projekt.\n"
"Přejete si prozkoumat oficiální ukázkové projekty v knihovně assetů?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Klávesa "
@@ -11035,6 +11042,11 @@ msgid "Total:"
msgstr "Celkem:"
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Exportovat profil"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Cesta ke zdroji"
diff --git a/editor/translations/da.po b/editor/translations/da.po
index e582e4f3f9..5e88313d95 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -10149,6 +10149,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -11303,6 +11310,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Eksporter Projekt"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/de.po b/editor/translations/de.po
index dc12e814b0..c3b2d6ee58 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -53,8 +53,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-14 15:05+0000\n"
-"Last-Translator: So Wieso <sowieso@dukun.de>\n"
+"PO-Revision-Date: 2020-05-04 15:11+0000\n"
+"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/"
"godot/de/>\n"
"Language: de\n"
@@ -62,7 +62,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2992,17 +2992,16 @@ msgid "Q&A"
msgstr "Fragen & Antworten"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Neuimport"
+msgstr "Fehler berichten"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Dokumentationsvorschläge senden"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
-msgstr "Community"
+msgstr "Gemeinschaft"
#: editor/editor_node.cpp
msgid "About"
@@ -4056,7 +4055,6 @@ msgid "Reimport"
msgstr "Neuimport"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
msgstr "Szenen speichern, reimportieren und neu starten"
@@ -7365,9 +7363,8 @@ msgid "This operation requires a single selected node."
msgstr "Diese Aktion benötigt einen einzelnen ausgewählten Node."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Orthogonal"
+msgstr "Auto-Orthogonal aktiviert"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -9999,6 +9996,17 @@ msgstr ""
"Sollen offizielle Beispielprojekte aus der Nutzerinhaltesammlung angezeigt "
"werden?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"Die Suchmaske filtert Projekte nach ihrem Namen oder der letzten Komponente "
+"ihres Pfadnamens.\n"
+"Um den Filter auf den gesamten Pfadnamen anzuwenden muss mindestens ein ‚/‘-"
+"Zeichen in der Suchanfrage vorhanden sein."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Taste "
@@ -10751,7 +10759,7 @@ msgstr "Node unter neues Node hängen"
#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
-msgstr "Szenen-Wurzel erstellen"
+msgstr "Als Szenen-Wurzel festlegen"
#: editor/scene_tree_dock.cpp
msgid "Merge From Scene"
@@ -10995,6 +11003,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Hinweis: Eingebettete Skripte unterliegen gewissen Einschränkungen und "
+"können nicht mit einem externen Editor bearbeitet werden."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11117,6 +11127,10 @@ msgid "Total:"
msgstr "Insgesamt:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "Liste als CSV-Datei exportieren"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Ressourcenpfad"
@@ -12808,6 +12822,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
+"Die Größe des Viewports muss größer als 0 sein um etwas rendern zu können."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po
index e17231a0dd..c86daa54dc 100644
--- a/editor/translations/de_CH.po
+++ b/editor/translations/de_CH.po
@@ -4,7 +4,6 @@
# This file is distributed under the same license as the Godot source code.
# Christian Fisch <christian.fiesel@gmail.com>, 2016.
# Nils <nfa106008@iet-gibb.ch>, 2020.
-# anonymous <noreply@weblate.org>, 2020.
# PagDev <pag.develop@gmail.com>, 2020.
msgid ""
msgstr ""
@@ -9969,6 +9968,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Taste "
@@ -11099,6 +11105,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Projekt exportieren"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index 466aa8fa7f..1302e33e47 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -9501,6 +9501,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10582,6 +10589,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/el.po b/editor/translations/el.po
index 2c8335393b..b01976c477 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-23 03:47+0000\n"
+"PO-Revision-Date: 2020-04-20 05:51+0000\n"
"Last-Translator: George Tsiamasiotis <gtsiam@windowslive.com>\n"
"Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/"
"el/>\n"
@@ -20,7 +20,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2951,13 +2951,12 @@ msgid "Q&A"
msgstr "ΕÏωτήσεις & Απαντήσεις"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Επανεισαγωγή"
+msgstr "ΑναφοÏά Σφάλματος"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Αποστολή Σχολίων ΤεκμηÏίωσης"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4018,9 +4017,8 @@ msgid "Reimport"
msgstr "Επανεισαγωγή"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
-msgstr "Αποθήκευση σκηνών, επανεισαγωγή και επανεκκίνηση"
+msgstr "Αποθήκευση Σκηνών, Επανεισαγωγή και Επανεκκίνηση"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -7334,9 +7332,8 @@ msgid "This operation requires a single selected node."
msgstr "Αυτή η λειτουÏγία απαιτεί έναν μόνο επιλεγμένο κόμβο."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "ΑξονομετÏική"
+msgstr "Αυτόματη ΑξονομετÏική ΕνεÏγή"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -9958,6 +9955,13 @@ msgstr ""
"Δεν έχετε κανένα έÏγο.\n"
"Θέλετε να εξεÏευνήσετε μεÏικά επίσημα παÏαδείγματα στην βιβλιοθήκη πόÏων;"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Κλειδί "
@@ -10955,6 +10959,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Σημείωση: Οι ενσωματωμένες δέσμες ενεÏγειών έχουν πεÏιοÏισμοÏÏ‚ και δεν "
+"μποÏοÏν να ανοιχτοÏν σε εξωτεÏικό επεξεÏγαστή."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11079,6 +11085,11 @@ msgid "Total:"
msgstr "Συνολικά:"
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Εξαγωγή ΠÏοφίλ"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "ΔιαδÏομή πόÏου"
@@ -12762,6 +12773,8 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
+"Το μέγεθος της οπτικής γωνίας Ï€Ïέπει να είναι μεγαλÏτεÏο του 0 για να γίνει "
+"απόδοση."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/eo.po b/editor/translations/eo.po
index 7dc152659f..d75cb88920 100644
--- a/editor/translations/eo.po
+++ b/editor/translations/eo.po
@@ -7,18 +7,19 @@
# Teashrock <kajitsu22@gmail.com>, 2019.
# Brandon Dyer <brandondyer64@gmail.com>, 2019.
# Alejandro Sánchez Medina <alejandrosanchzmedina@gmail.com>, 2019.
+# Sr Half <flavio05@outlook.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2019-11-11 14:19+0000\n"
-"Last-Translator: Alejandro Sánchez Medina <alejandrosanchzmedina@gmail.com>\n"
+"PO-Revision-Date: 2020-05-01 11:43+0000\n"
+"Last-Translator: Sr Half <flavio05@outlook.com>\n"
"Language-Team: Esperanto <https://hosted.weblate.org/projects/godot-engine/"
"godot/eo/>\n"
"Language: eo\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.10-dev\n"
+"X-Generator: Weblate 4.0.2\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -27,7 +28,7 @@ msgstr "Nevalida tip-argumento por funkcio convert(). Uzu konstantojn TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr ""
+msgstr "Atendas ĉenon de longo 1 (unu karaktero)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -65,31 +66,31 @@ msgstr "En voko al '%s':"
#: core/ustring.cpp
msgid "B"
-msgstr ""
+msgstr "B"
#: core/ustring.cpp
msgid "KiB"
-msgstr ""
+msgstr "Kib"
#: core/ustring.cpp
msgid "MiB"
-msgstr ""
+msgstr "MiB"
#: core/ustring.cpp
msgid "GiB"
-msgstr ""
+msgstr "Gib"
#: core/ustring.cpp
msgid "TiB"
-msgstr ""
+msgstr "TiB"
#: core/ustring.cpp
msgid "PiB"
-msgstr ""
+msgstr "PiB"
#: core/ustring.cpp
msgid "EiB"
-msgstr ""
+msgstr "EiB"
#: editor/animation_bezier_editor.cpp
msgid "Free"
@@ -422,7 +423,7 @@ msgstr "Äœi ne estas ebla adici novan vojeton sen radiko"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
-msgstr ""
+msgstr "Nevalida trako por Bezier (neniu taŭga subproprietaĵoj)"
#: editor/animation_track_editor.cpp
msgid "Add Bezier Track"
@@ -9647,6 +9648,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10737,6 +10745,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
@@ -12274,7 +12286,7 @@ msgstr ""
#: servers/visual/shader_language.cpp
msgid "Constants cannot be modified."
-msgstr ""
+msgstr "Konstantoj ne povas esti modifitaj."
#, fuzzy
#~ msgid "Help improve the Godot documentation by giving feedback."
diff --git a/editor/translations/es.po b/editor/translations/es.po
index c9ca261498..8446ed2415 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -43,15 +43,15 @@
# Dario <darlex259@gmail.com>, 2019.
# Adolfo Jayme Barrientos <fitojb@ubuntu.com>, 2019.
# Julián Luini <jluini@gmail.com>, 2020.
-# anonymous <noreply@weblate.org>, 2020.
# Victor S. <victorstancioiu@gmail.com>, 2020.
# henry rujano herrera <rujhen@gmail.com>, 2020.
+# Megamega53 <Christopher.Morales21@myhunter.cuny.edu>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-04-16 11:03+0000\n"
-"Last-Translator: anonymous <noreply@weblate.org>\n"
+"PO-Revision-Date: 2020-05-04 15:11+0000\n"
+"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
"Language: es\n"
@@ -59,7 +59,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0.1-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -618,11 +618,11 @@ msgstr "Eliminar Selección"
#: editor/animation_track_editor.cpp
msgid "Go to Next Step"
-msgstr "Ir al Paso Siguiente"
+msgstr "Ir al Siguiente Paso"
#: editor/animation_track_editor.cpp
msgid "Go to Previous Step"
-msgstr "Ir al Paso Anterior"
+msgstr "Ir al Anterior Paso"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
@@ -642,7 +642,7 @@ msgstr "Usar Curvas Bezier"
#: editor/animation_track_editor.cpp
msgid "Anim. Optimizer"
-msgstr "Optimizador de Animación"
+msgstr "Optimizar Animación"
#: editor/animation_track_editor.cpp
msgid "Max. Linear Error:"
@@ -845,7 +845,7 @@ msgstr "Eliminar"
#: editor/connections_dialog.cpp
msgid "Add Extra Call Argument:"
-msgstr "Añadir un Argumento de Llamada Extra:"
+msgstr "Añadir Argumento de Llamada Extra:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
@@ -2044,7 +2044,7 @@ msgstr ""
#: editor/editor_help.cpp
msgid "Method Descriptions"
-msgstr "Descripción de Métodos"
+msgstr "Descripciones de Métodos"
#: editor/editor_help.cpp
msgid ""
@@ -2692,7 +2692,7 @@ msgstr "Posición del Dock"
#: editor/editor_node.cpp
msgid "Distraction Free Mode"
-msgstr "Modo sin distracciones"
+msgstr "Modo Sin Distracciones"
#: editor/editor_node.cpp
msgid "Toggle distraction-free mode."
@@ -2716,11 +2716,11 @@ msgstr "Copiar Texto"
#: editor/editor_node.cpp
msgid "Next tab"
-msgstr "Pestaña siguiente"
+msgstr "Siguiente pestaña"
#: editor/editor_node.cpp
msgid "Previous tab"
-msgstr "Pestaña anterior"
+msgstr "Anterior pestaña"
#: editor/editor_node.cpp
msgid "Filter Files..."
@@ -2994,13 +2994,12 @@ msgid "Q&A"
msgstr "Preguntas y respuestas"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Reimportar"
+msgstr "Reportar un Bug"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Enviar Feedback de la Documentación"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3012,7 +3011,7 @@ msgstr "Acerca de"
#: editor/editor_node.cpp
msgid "Play the project."
-msgstr "Ejecutar el proyecto."
+msgstr "Reproducir el proyecto."
#: editor/editor_node.cpp
msgid "Play"
@@ -4060,9 +4059,8 @@ msgid "Reimport"
msgstr "Reimportar"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
-msgstr "Guardar escenas, reimportar y reiniciar"
+msgstr "Guardar Escenas, Reimportar y Reiniciar"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -5274,8 +5272,8 @@ msgid ""
"When active, moving Control nodes changes their anchors instead of their "
"margins."
msgstr ""
-"Cuando esté activo, moviendo los nodos de Control cambiará sus anclas en "
-"lugar de sus márgenes."
+"Cuando está activo, el movimiento de los nodos de Control cambian sus "
+"anclajes en lugar de sus márgenes."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Top Left"
@@ -5431,7 +5429,7 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
msgid "Zoom Reset"
-msgstr "Resetear el Zoom"
+msgstr "Resetear Zoom"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5459,17 +5457,17 @@ msgstr "Alt + Clic Derecho: Selección en listado de solapamientos"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
-msgstr "Modo Movimiento"
+msgstr "Modo de Movimiento"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
-msgstr "Modo Rotación"
+msgstr "Modo de Rotación"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
-msgstr "Modo Escalado"
+msgstr "Modo de Escalado"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5491,7 +5489,7 @@ msgstr "Modo desplazamiento lateral"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Ruler Mode"
-msgstr "Modo Regla"
+msgstr "Modo de Regla"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Toggle smart snapping."
@@ -5682,7 +5680,7 @@ msgstr "Clave de animación y Opciones de Pose"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key (Existing Tracks)"
-msgstr "Insertar clave (pistas existentes)"
+msgstr "Insertar Clave (Pistas Existentes)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Copy Pose"
@@ -6038,7 +6036,7 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Single Convex Collision Sibling"
-msgstr "Crear Colisión Convexa Única Hermana"
+msgstr "Crear Collider Convexo Único Hermano"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -6050,7 +6048,7 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Multiple Convex Collision Siblings"
-msgstr "Crear Múltiples Colisiones Convexas Hermanas"
+msgstr "Crear Múltiples Collider Convexos Hermanos"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -6858,7 +6856,7 @@ msgstr "Guardar Todo"
#: editor/plugins/script_editor_plugin.cpp
msgid "Soft Reload Script"
-msgstr "Recargar parcialmente el script"
+msgstr "Recargar Parcialmente el Script"
#: editor/plugins/script_editor_plugin.cpp
msgid "Copy Script Path"
@@ -6866,7 +6864,7 @@ msgstr "Copiar Ruta del Script"
#: editor/plugins/script_editor_plugin.cpp
msgid "History Previous"
-msgstr "Previo en Historial"
+msgstr "Previo en el Historial"
#: editor/plugins/script_editor_plugin.cpp
msgid "History Next"
@@ -6903,11 +6901,11 @@ msgstr "Ejecutar"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
-msgstr "Step Into"
+msgstr "Entrar En"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Over"
-msgstr "Step Over"
+msgstr "Salir de Aquí"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Break"
@@ -7115,15 +7113,15 @@ msgstr "Eliminar Espacios Sobrantes al Final"
#: editor/plugins/script_text_editor.cpp
msgid "Convert Indent to Spaces"
-msgstr "Convertir Indentación en Espacios"
+msgstr "Convertir Sangría en Espacios"
#: editor/plugins/script_text_editor.cpp
msgid "Convert Indent to Tabs"
-msgstr "Convertir Indentación en Tabulaciones"
+msgstr "Convertir Sangría en Tabulaciones"
#: editor/plugins/script_text_editor.cpp
msgid "Auto Indent"
-msgstr "Autoindentar"
+msgstr "Auto Sangría"
#: editor/plugins/script_text_editor.cpp
msgid "Find in Files..."
@@ -7143,7 +7141,7 @@ msgstr "Ir al Siguiente Marcador"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Previous Bookmark"
-msgstr "Ir al Marcador Anterior"
+msgstr "Ir al Anterior Marcador"
#: editor/plugins/script_text_editor.cpp
msgid "Remove All Bookmarks"
@@ -7160,19 +7158,19 @@ msgstr "Ir a Línea..."
#: editor/plugins/script_text_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Toggle Breakpoint"
-msgstr "Act./Desact. Breakpoint"
+msgstr "Cambiar Punto de Ruptura"
#: editor/plugins/script_text_editor.cpp
msgid "Remove All Breakpoints"
-msgstr "Eliminar Todos los Breakpoints"
+msgstr "Eliminar Todos los Puntos de Ruptura"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Next Breakpoint"
-msgstr "Ir al Siguiente Breakpoint"
+msgstr "Ir al Siguiente Punto de Ruptura"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Previous Breakpoint"
-msgstr "Ir al Breakpoint Anterior"
+msgstr "Ir al Anterior Punto de Ruptura"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -7352,11 +7350,11 @@ msgstr "Detrás"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Align Transform with View"
-msgstr "Alinear Transform con Vista"
+msgstr "Alinear la Transformación con la Vista"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Align Rotation with View"
-msgstr "Alinear Rotación con Vista"
+msgstr "Alinear la Rotación con la Vista"
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
@@ -7367,9 +7365,8 @@ msgid "This operation requires a single selected node."
msgstr "Esta operación requiere un solo nodo seleccionado."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Ortogonal"
+msgstr "Auto Ortogonal Activado"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -7441,7 +7438,7 @@ msgstr "Vista Libre Frontal"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Backwards"
-msgstr "Vista Libre Posterior"
+msgstr "Vista Libre Trasera"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Up"
@@ -7511,7 +7508,7 @@ msgstr "Vista Superior"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rear View"
-msgstr "Vista Posterior"
+msgstr "Vista Trasera"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Front View"
@@ -8129,7 +8126,7 @@ msgstr "Asignar un recurso TileSet a este TileMap para usas sus tiles."
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint Tile"
-msgstr "Dibujar tile"
+msgstr "Dibujar Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
@@ -8237,35 +8234,35 @@ msgstr "Ãndice Z"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Region Mode"
-msgstr "Modo Región"
+msgstr "Modo de Región"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Collision Mode"
-msgstr "Modo Colisión"
+msgstr "Modo de Colisión"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Occlusion Mode"
-msgstr "Modo Oclusión"
+msgstr "Modo de Oclusión"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Navigation Mode"
-msgstr "Modo Navegación"
+msgstr "Modo de Navegación"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Bitmask Mode"
-msgstr "Modo Bitmask"
+msgstr "Modo de Bitmask"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Priority Mode"
-msgstr "Modo Prioridad"
+msgstr "Modo de Prioridad"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Icon Mode"
-msgstr "Modo Icono"
+msgstr "Modo de Icono"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Z Index Mode"
-msgstr "Modo Ãndice Z"
+msgstr "Modo de Ãndice Z"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Copy bitmask."
@@ -9995,6 +9992,17 @@ msgstr ""
"Actualmente no tienes ningún proyecto.\n"
"¿Quieres explorar proyectos de ejemplo oficiales en la Biblioteca de Assets?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"La casilla de búsqueda filtra los proyectos por nombre y el último "
+"componente de la ruta.\n"
+"Para filtrar los proyectos por nombre y ruta completa, la consulta debe "
+"contener al menos un carácter `/`."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Tecla "
@@ -10988,6 +10996,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Nota: Los scripts integrados tienen algunas limitaciones y no pueden ser "
+"editados usando un editor externo."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11110,6 +11120,10 @@ msgid "Total:"
msgstr "Total:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "Exportar lista a un archivo CSV"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Ruta de Recursos"
@@ -11443,7 +11457,7 @@ msgstr "Eliminar Rotación del Cursor"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Paste Selects"
-msgstr "Pegar Selecciona"
+msgstr "Pegar Seleccionados"
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Clear Selection"
@@ -11880,7 +11894,7 @@ msgstr "Crear Función"
#: modules/visual_script/visual_script_editor.cpp
msgid "Refresh Graph"
-msgstr "Actualizar Gráfico"
+msgstr "Refrescar Gráfico"
#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
@@ -12801,6 +12815,8 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
+"El tamaño del Viewport debe ser mayor que 0 para poder renderizar cualquier "
+"cosa."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 7e7ed33aca..9136ac11c3 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -18,8 +18,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-11 12:20+0000\n"
-"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
+"PO-Revision-Date: 2020-05-02 01:48+0000\n"
+"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/"
"godot-engine/godot/es_AR/>\n"
"Language: es_AR\n"
@@ -27,7 +27,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2954,13 +2954,12 @@ msgid "Q&A"
msgstr "Q&A"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Reimportar"
+msgstr "Reportar un Bug"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Enviar comentarios sobre la documentación"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4020,9 +4019,8 @@ msgid "Reimport"
msgstr "Reimportar"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
-msgstr "Guardar escenas, reimportar y reiniciar"
+msgstr "Guardar Escenas, Reimportar y Reiniciar"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -7323,9 +7321,8 @@ msgid "This operation requires a single selected node."
msgstr "Esta operación requiere un solo nodo seleccionado."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Ortogonal"
+msgstr "Auto Ortogonal Activado"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -8390,7 +8387,7 @@ msgstr "Crear Polígono Cóncavo"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Make Polygon Convex"
-msgstr "Crear Polígono Convexo"
+msgstr "Hacer el Polígono Convexo"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Remove Tile"
@@ -9950,6 +9947,17 @@ msgstr ""
"Actualmente no tenés ningún proyecto.\n"
"¿Te gustaría explorar los ejemplos oficiales en la Biblioteca de Assets?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"La casilla de búsqueda filtra los proyectos por nombre y el último "
+"componente de la ruta.\n"
+"Para filtrar los proyectos por nombre y ruta completa, la consulta debe "
+"contener al menos un carácter `/`."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Tecla "
@@ -10944,6 +10952,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Nota: Los scripts integrados tienen algunas limitaciones y no pueden ser "
+"editados con un editor externo."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11066,6 +11076,10 @@ msgid "Total:"
msgstr "Total:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "Exportar lista a un archivo CSV"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Ruta de Recursos"
@@ -12747,7 +12761,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
-msgstr ""
+msgstr "El tamaño del viewport debe ser mayor a 0 para poder renderizar."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/et.po b/editor/translations/et.po
index 6c052803e0..2ed8f83317 100644
--- a/editor/translations/et.po
+++ b/editor/translations/et.po
@@ -9524,6 +9524,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10608,6 +10615,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/eu.po b/editor/translations/eu.po
index 49fb37e599..f633f1c298 100644
--- a/editor/translations/eu.po
+++ b/editor/translations/eu.po
@@ -9506,6 +9506,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10587,6 +10594,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index f45393c505..2754720d3b 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -11,15 +11,14 @@
# Behrooz Kashani <bkashani@gmail.com>, 2018.
# Mahdi <sadisticwarlock@gmail.com>, 2018.
# hpn33 <hamed.hpn332@gmail.com>, 2019, 2020.
-# Focus <saeeddashticlash@gmail.com>, 2019.
-# anonymous <noreply@weblate.org>, 2020.
+# Focus <saeeddashticlash@gmail.com>, 2019, 2020.
# mohamad por <mohamad24xx@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-04-09 07:52+0000\n"
-"Last-Translator: hpn33 <hamed.hpn332@gmail.com>\n"
+"PO-Revision-Date: 2020-04-23 20:21+0000\n"
+"Last-Translator: Focus <saeeddashticlash@gmail.com>\n"
"Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/"
"godot/fa/>\n"
"Language: fa\n"
@@ -27,7 +26,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -1257,7 +1256,7 @@ msgstr ""
#: editor/editor_asset_installer.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Success!"
-msgstr ""
+msgstr "موÙقیت!"
#: editor/editor_asset_installer.cpp
#, fuzzy
@@ -1352,7 +1351,7 @@ msgstr "حذ٠اثر"
#: editor/editor_audio_buses.cpp
msgid "Audio"
-msgstr ""
+msgstr "صدا"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus"
@@ -2905,6 +2904,7 @@ msgid ""
msgstr ""
#: editor/editor_node.cpp editor/script_create_dialog.cpp
+#, fuzzy
msgid "Editor"
msgstr "ویرایشگر"
@@ -4641,7 +4641,7 @@ msgstr ""
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Animation"
-msgstr ""
+msgstr "انیمیشن"
#: editor/plugins/animation_player_editor_plugin.cpp
#, fuzzy
@@ -10102,6 +10102,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10428,7 +10435,7 @@ msgstr "بارگیری خودکار"
#: editor/project_settings_editor.cpp
msgid "Plugins"
-msgstr ""
+msgstr "پلاگین ها"
#: editor/property_editor.cpp
msgid "Preset..."
@@ -11260,6 +11267,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "صدور پروژه"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index 74bc461021..6695783866 100644
--- a/editor/translations/fi.po
+++ b/editor/translations/fi.po
@@ -10,11 +10,12 @@
# Sami Lehtilä <sami.lehtila@gmail.com>, 2018.
# Tapani Niemi <tapani.niemi@kapsi.fi>, 2018, 2019, 2020.
# Tuomas Lähteenmäki <lahtis@gmail.com>, 2019.
+# Matti Niskanen <matti.t.niskanen@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-14 15:05+0000\n"
+"PO-Revision-Date: 2020-05-01 11:42+0000\n"
"Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n"
"Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/"
"godot/fi/>\n"
@@ -23,7 +24,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.2\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2757,7 +2758,7 @@ msgstr "Irrallisten resurssien hallinta..."
#: editor/editor_node.cpp
msgid "Quit to Project List"
-msgstr "Lopeta ja palaa projektiluetteloon"
+msgstr "Poistu projektiluetteloon"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
@@ -2921,13 +2922,12 @@ msgid "Q&A"
msgstr "Kysymykset ja vastaukset"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Tuo uudelleen"
+msgstr "Raportoi bugi"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Lähetä palautetta ohjeesta"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3981,7 +3981,6 @@ msgid "Reimport"
msgstr "Tuo uudelleen"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
msgstr "Tallenna skenet, tuo uudelleen ja käynnistä uudelleen"
@@ -5355,7 +5354,7 @@ msgstr "Palauta oletuslähennystaso"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
-msgstr "Valitse tila"
+msgstr "Valintatila"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Drag: Rotate"
@@ -5383,7 +5382,7 @@ msgstr "Siirtotila"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
-msgstr "Kääntötila"
+msgstr "Kiertotila"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5543,7 +5542,7 @@ msgstr "Näytä origo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Viewport"
-msgstr "Näytä näyttöikkuna"
+msgstr "Näytä näyttöruutu"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Group And Lock Icons"
@@ -7277,9 +7276,8 @@ msgid "This operation requires a single selected node."
msgstr "Tämä toiminto vaatii yhden valitun solmun."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Ortogonaalinen"
+msgstr "Automaattinen ortogonaalinen päällä"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -9895,6 +9893,16 @@ msgstr ""
"Sinulla ei ole tällä hetkellä yhtään projekteja.\n"
"Haluaisitko selata virallisia esimerkkiprojekteja Asset-kirjastosta?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"Hakulaatikko suodattaa projektit nimen ja polun loppuosan mukaan.\n"
+"Suodattaaksesi projektit nimen ja koko polun mukaan, haussa tulee olla "
+"mukana vähintään yksi `/` merkki."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Näppäin "
@@ -10889,6 +10897,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Huom: sisäänrakennetuilla skripteillä on joitakin rajoituksia, eikä niitä "
+"voi muokata ulkoisella editorilla."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11011,6 +11021,10 @@ msgid "Total:"
msgstr "Yhteensä:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "Vie lista CSV tiedostoon"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Resurssipolku"
@@ -11779,7 +11793,7 @@ msgstr "Tee funktio"
#: modules/visual_script/visual_script_editor.cpp
msgid "Refresh Graph"
-msgstr "Päivitä graafi"
+msgstr "Päivitä kaaviokuva"
#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
@@ -12673,6 +12687,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
+"Näyttöruudun koko on oltava suurempi kuin 0, jotta mitään renderöidään."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/fil.po b/editor/translations/fil.po
index 5a1942fee5..32405930ea 100644
--- a/editor/translations/fil.po
+++ b/editor/translations/fil.po
@@ -9525,6 +9525,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10607,6 +10614,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index 0844df8dc7..bb371b7674 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -71,13 +71,13 @@
# Pierre Stempin <pierre.stempin@gmail.com>, 2019.
# Pierre Caye <pierrecaye@laposte.net>, 2020.
# Kevin Bouancheau <kevin.bouancheau@gmail.com>, 2020.
-# anonymous <noreply@weblate.org>, 2020.
+# LaurentOngaro <laurent@gameamea.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-04-03 09:09+0000\n"
-"Last-Translator: anonymous <noreply@weblate.org>\n"
+"PO-Revision-Date: 2020-05-05 14:01+0000\n"
+"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
"Language: fr\n"
@@ -85,7 +85,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -105,11 +105,11 @@ msgstr "Pas assez d'octets pour le décodage, ou format non valide."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr "Entrée non valide %i (pas passée) dans l’expression"
+msgstr "Entrée non valide %i (non transmise) dans l’expression"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr "self ne peut être utilisé car l'instance est null (pas passée)"
+msgstr "self ne peut être utilisé car l'instance est nulle (non passée)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -2230,7 +2230,7 @@ msgstr "Nouvelle Fenêtre"
#: editor/editor_node.cpp
msgid "Imported resources can't be saved."
-msgstr "Les ressources importés ne peuvent pas être sauvegarder."
+msgstr "Les ressources importées ne peuvent pas être sauvegardées."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
@@ -3024,13 +3024,12 @@ msgid "Q&A"
msgstr "Questions et réponses"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Réimporter"
+msgstr "Signaler un bug"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Envoyez vos retours sur la documentation"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4092,9 +4091,8 @@ msgid "Reimport"
msgstr "Réimporter"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
-msgstr "Sauvegarde des scènes, réimportation et redémarrage"
+msgstr "Sauvegarder les scènes, Réimporter, et Redémarrer"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -5469,12 +5467,12 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
msgid "Zoom Reset"
-msgstr "Réinitialiser le facteur d'agrandissement"
+msgstr "Réinitialiser le zoom"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Select Mode"
-msgstr "Sélectionner le mode"
+msgstr "Mode sélection"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Drag: Rotate"
@@ -5507,7 +5505,7 @@ msgstr "Mode rotation"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
-msgstr "Mode de mise à l'échelle"
+msgstr "Mode mise à l'échelle"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5544,7 +5542,7 @@ msgstr "Activer/Désactiver l'aimantation à la grille."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Grid Snap"
-msgstr "Aimanter à la grille"
+msgstr "Utiliser l'aimantation à la grille"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snapping Options"
@@ -5674,7 +5672,7 @@ msgstr "Centrer sur la sélection"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Frame Selection"
-msgstr "Cadrer la sélection"
+msgstr "Encadrer la sélection"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Preview Canvas Scale"
@@ -6857,7 +6855,7 @@ msgstr "Basculer le tri alphabétique de la liste de méthodes."
#: editor/plugins/script_editor_plugin.cpp
msgid "Filter methods"
-msgstr "Méthodes de filtrage"
+msgstr "Filtrer les méthodes"
#: editor/plugins/script_editor_plugin.cpp
msgid "Sort"
@@ -7396,7 +7394,7 @@ msgstr "Arrière"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Align Transform with View"
-msgstr "Aligner le Transform avec la vue"
+msgstr "Aligner Transform avec la vue"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Align Rotation with View"
@@ -7413,9 +7411,8 @@ msgstr ""
"sélectionné."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Orthogonale"
+msgstr "Auto Orthogonal Activé"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -7483,19 +7480,19 @@ msgstr "Vue libre droite"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Forward"
-msgstr "Vue libre de devant"
+msgstr "Vue libre avant"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Backwards"
-msgstr "Vue libre de derrière"
+msgstr "Vue libre arrière"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Up"
-msgstr "Vue libre de dessus"
+msgstr "Vue libre haut"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Down"
-msgstr "Vue libre de dessous"
+msgstr "Vue libre bas"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Speed Modifier"
@@ -7503,20 +7500,20 @@ msgstr "Modificateur de vitesse de la vue libre"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Slow Modifier"
-msgstr "Modificateur de vitesse de la vue libre"
+msgstr "Ralentissement de la vue libre"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Rotation Locked"
-msgstr "Verrouiller la rotation de la vue"
+msgstr "Rotation de la vue verrouillée"
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
-"Note : La valeur FPS affichée est la fréquence d'images de l'éditeur.\n"
-"Il ne doit pas être utilisé comme un indicateur fiable de la performance en "
-"jeu."
+"Note : Les FPS (images par secondes) affichées sont celles de éditeur.\n"
+"Elles ne doivent pas être utilisées comme un indicateur fiable de la "
+"performance en jeu."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
@@ -7524,11 +7521,11 @@ msgstr "Dialogue XForm"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Nodes To Floor"
-msgstr "Aligner les nœuds au sol"
+msgstr "Aligner les nœuds avec le sol"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Couldn't find a solid floor to snap the selection to."
-msgstr "N'a pas pu trouvé de sol solide pour y attacher la sélection."
+msgstr "Pas de sol solide trouvé pour y attacher la sélection."
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7542,11 +7539,11 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Local Space"
-msgstr "Utiliser l'espace local"
+msgstr "Utiliser les coordonées locales"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
-msgstr "Aligner sur la grille"
+msgstr "Aligner avec la grille"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
@@ -7558,11 +7555,11 @@ msgstr "Vue de dessus"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rear View"
-msgstr "Vue arrière"
+msgstr "Vue de derrière"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Front View"
-msgstr "Vue avant"
+msgstr "Vue de devant"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Left View"
@@ -7582,7 +7579,7 @@ msgstr "Insérer une clef d'animation"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Origin"
-msgstr "Focaliser l'origine"
+msgstr "Focaliser sur l'origine"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Selection"
@@ -8177,7 +8174,7 @@ msgstr "Donnez une ressource TileSet à cette TileMap pour utiliser ses tuiles."
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint Tile"
-msgstr "Peindre la case"
+msgstr "Peindre la tuile"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
@@ -8189,7 +8186,7 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Pick Tile"
-msgstr "Sélectionner une case"
+msgstr "Sélectionner une tuile"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rotate Left"
@@ -9699,7 +9696,7 @@ msgstr "Fichier ZIP"
#: editor/project_export.cpp
msgid "Godot Game Pack"
-msgstr "Données de jeu Godot"
+msgstr "Archive Godot"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing:"
@@ -10051,6 +10048,17 @@ msgstr ""
"Vous n'avez pour l'instant aucun projets.\n"
"Voulez-vous explorer des exemples de projets officiels dans l'Asset Library ?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"La barre de recherche filtre les projets par leur nom et la dernière partie "
+"de leur chemin d'accès.\n"
+"Pour filter les projects par leur nom et le chemin d'accès complet, la "
+"recherche doit inclure au moins un caractère `/`."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Touche "
@@ -10253,19 +10261,19 @@ msgstr "Ajouter un chemin remappé"
#: editor/project_settings_editor.cpp
msgid "Resource Remap Add Remap"
-msgstr "Réaffectation des ressources ; Ajouter une réaffectation"
+msgstr "Réaffectation (remap) des ressources ; Ajouter une réaffectation"
#: editor/project_settings_editor.cpp
msgid "Change Resource Remap Language"
-msgstr "Modifier le langage de réaffectation des ressources"
+msgstr "Modifier le langage de réaffectation (remap) des ressources"
#: editor/project_settings_editor.cpp
msgid "Remove Resource Remap"
-msgstr "Supprimer la réaffectation des ressources"
+msgstr "Supprimer la réaffectation (remap) des ressources"
#: editor/project_settings_editor.cpp
msgid "Remove Resource Remap Option"
-msgstr "Supprimer option de remap de ressource"
+msgstr "Supprimer l'option de réaffectation (remap) de ressource"
#: editor/project_settings_editor.cpp
msgid "Changed Locale Filter"
@@ -10273,7 +10281,7 @@ msgstr "Filtre de langue modifié"
#: editor/project_settings_editor.cpp
msgid "Changed Locale Filter Mode"
-msgstr "Changé le mode de filtrage des langues"
+msgstr "Mode de filtrage des langues modifié"
#: editor/project_settings_editor.cpp
msgid "Project Settings (project.godot)"
@@ -10285,7 +10293,7 @@ msgstr "Général"
#: editor/project_settings_editor.cpp
msgid "Override For..."
-msgstr "Écraser pour…"
+msgstr "Surcharge pour…"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "The editor must be restarted for changes to take effect."
@@ -10329,7 +10337,7 @@ msgstr "Traductions :"
#: editor/project_settings_editor.cpp
msgid "Remaps"
-msgstr "Remaps"
+msgstr "Réaffectation"
#: editor/project_settings_editor.cpp
msgid "Resources:"
@@ -10337,7 +10345,7 @@ msgstr "Ressources :"
#: editor/project_settings_editor.cpp
msgid "Remaps by Locale:"
-msgstr "Remaps par langue :"
+msgstr "Réaffectations (remaps) par langue :"
#: editor/project_settings_editor.cpp
msgid "Locale"
@@ -11043,6 +11051,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Remarque : les scripts intégrés ont certaines limitations et ne peuvent pas "
+"être modifiés à l'aide d'un éditeur externe."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11166,6 +11176,10 @@ msgid "Total:"
msgstr "Total :"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "Exporter la liste en fichier CSV"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Chemin de la ressource"
@@ -12867,6 +12881,8 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
+"La taille de la fenêtre d'affichage doit être supérieure à 0 pour pouvoir "
+"afficher quoi que ce soit."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/ga.po b/editor/translations/ga.po
index d40b50cd90..7b271f6a77 100644
--- a/editor/translations/ga.po
+++ b/editor/translations/ga.po
@@ -9520,6 +9520,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10603,6 +10610,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/he.po b/editor/translations/he.po
index 1a82804b31..69d8bcc3b5 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -5,18 +5,19 @@
# Daniel <lorddaniel09@gmail.com>, 2018.
# Ben Golan <golanben4@gmail.com>, 2017.
# Luc Stepniewski <lior@gradstein.info>, 2017.
-# Yaron Shahrabani <sh.yaron@gmail.com>, 2018, 2019.
+# Yaron Shahrabani <sh.yaron@gmail.com>, 2018, 2019, 2020.
# RaikaRakka <shaiyatta@gmail.com>, 2018.
# Ido Dana <idodana01@gmail.com>, 2019.
# Daniel Dovgun <daniel.dovgun@gmail.com>, 2019.
# MordechaiHadad <Mordechai.hadad01@gmail.com>, 2019.
# Daniel <danielharush5252@gmail.com>, 2020.
+# test test <ugbdvwpeikvyzwaadt@awdrt.org>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-02-25 09:41+0000\n"
-"Last-Translator: Daniel <danielharush5252@gmail.com>\n"
+"PO-Revision-Date: 2020-05-05 14:01+0000\n"
+"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n"
"Language-Team: Hebrew <https://hosted.weblate.org/projects/godot-engine/"
"godot/he/>\n"
"Language: he\n"
@@ -25,7 +26,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && "
"n % 10 == 0) ? 2 : 3));\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -34,7 +35,7 @@ msgstr "משתנה סוג ×œ× ×—×•×§×™ לפונקציית convert()‎, יש ל
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr "צופה מחרוזת ב×ורך 1 (תו)"
+msgstr "צפויה מחרוזת ב×ורך 1 (תו)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -722,13 +723,12 @@ msgid "Line Number:"
msgstr "מספר השורה:"
#: editor/code_editor.cpp
-#, fuzzy
msgid "%d replaced."
-msgstr "החלפה…"
+msgstr "%d הוחלף."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
-msgstr ""
+msgstr "d% הת×מות."
#: editor/code_editor.cpp editor/editor_help.cpp
#, fuzzy
@@ -4044,9 +4044,8 @@ msgid "Saving..."
msgstr "שמירה…"
#: editor/import_dock.cpp
-#, fuzzy
msgid "%d Files"
-msgstr " קבצי×"
+msgstr "%d קבצי×"
#: editor/import_dock.cpp
msgid "Set as Default for '%s'"
@@ -6788,66 +6787,58 @@ msgid "Error writing TextFile:"
msgstr "שגי××” ×‘×™×™×‘×•× ×¢×¨×›×ª הנוש×"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Could not load file at:"
-msgstr "×œ× × ×™×ª×Ÿ ליצור תיקייה."
+msgstr "×œ× × ×™×ª×Ÿ לטעון קובץ מהמיקו×:"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error saving file!"
-msgstr "שגי××” בשמירה"
+msgstr "שגי××” בשמירת קובץ!"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error while saving theme."
-msgstr "שגי××” בשמירת ערכת העיצוב"
+msgstr "שגי××” בשמירת ערכת העיצוב."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Saving"
msgstr "שגי××” בשמירה"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error importing theme."
-msgstr "שגי××” ×‘×™×™×‘×•× ×¢×¨×›×ª הנוש×"
+msgstr "שגי××” ×‘×™×™×‘×•× ×¢×¨×›×ª העיצוב."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Importing"
msgstr "שגי××” בייבו×"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "New Text File..."
-msgstr "תיקייה חדשה…"
+msgstr "קובץ טקסט חדש…"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open File"
msgstr "פתיחת קובץ"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Save File As..."
-msgstr "שמירה בש×…"
+msgstr "שמירת קובץ בש×…"
#: editor/plugins/script_editor_plugin.cpp
msgid "Can't obtain the script for running."
-msgstr ""
+msgstr "×œ× × ×™×ª×Ÿ לקבל ×ת הסקריפט להרצה."
#: editor/plugins/script_editor_plugin.cpp
msgid "Script failed reloading, check console for errors."
-msgstr ""
+msgstr "רענון הסקריפט נכשל, × × ×œ×—×¤×© ×ת השגי×ות במסוף."
#: editor/plugins/script_editor_plugin.cpp
msgid "Script is not in tool mode, will not be able to run."
-msgstr ""
+msgstr "הסקריפט ×ינו במצב כלי×, ×œ× ×ª×”×™×” לו ×פשרות לרוץ."
#: editor/plugins/script_editor_plugin.cpp
msgid ""
"To run this script, it must inherit EditorScript and be set to tool mode."
msgstr ""
+"כדי להריץ ×ת הסקריפט ×”×–×”, עליו לרשת EditorScript ולהגדיר ×ותו למצב כלי×."
#: editor/plugins/script_editor_plugin.cpp
msgid "Import Theme"
@@ -6880,9 +6871,8 @@ msgid "Find Previous"
msgstr "×יתור הקוד×"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Filter scripts"
-msgstr "מ×פייני פריט."
+msgstr "סינון סקריפטי×"
#: editor/plugins/script_editor_plugin.cpp
msgid "Toggle alphabetical sorting of the method list."
@@ -10077,6 +10067,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "מקש "
@@ -11225,6 +11222,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "×™×™×¦×•× ×ž×™×–×"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index 75f29b8e0b..12cf8fd242 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -10,14 +10,13 @@
# Lakshmi-Jayakumar <lakshmi.jayakumar.tkm@gmail.com>, 2019.
# Devashishsingh98 <devashishsingh98@gmail.com>, 2019.
# Shirious <sad3119823@gmail.com>, 2020.
-# anonymous <noreply@weblate.org>, 2020.
# Abhay Patel <Traumaticbean@protonmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-04-03 09:50+0000\n"
-"Last-Translator: Suryansh5545 <suryanshpathak5545@gmail.com>\n"
+"PO-Revision-Date: 2020-04-24 06:48+0000\n"
+"Last-Translator: Shirious <sad3119823@gmail.com>\n"
"Language-Team: Hindi <https://hosted.weblate.org/projects/godot-engine/godot/"
"hi/>\n"
"Language: hi\n"
@@ -25,7 +24,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2332,9 +2331,8 @@ msgid "Open Base Scene"
msgstr "ओपन बेस सीन"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Quick Open..."
-msgstr "खोलो इसे"
+msgstr "तà¥à¤°à¤‚त खोलिये..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
@@ -2457,9 +2455,8 @@ msgid "Close Scene"
msgstr "कà¥à¤²à¥‹à¤œ सीन"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Reopen Closed Scene"
-msgstr "खोलो इसे"
+msgstr "बंद सीन फिर से खोलें"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
@@ -2564,14 +2561,12 @@ msgid "Play This Scene"
msgstr "इस दृशà¥à¤¯ को खेलो"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close Tab"
-msgstr "बंद करे"
+msgstr "टैब बंद करे"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Undo Close Tab"
-msgstr "बंद करे"
+msgstr "बंद टैब अनकिया करें"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
@@ -2582,9 +2577,8 @@ msgid "Close Tabs to the Right"
msgstr "टैब को दाईं ओर बंद करें"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close All Tabs"
-msgstr "बंद करे"
+msgstr "सभी टैब बंद करे"
#: editor/editor_node.cpp
msgid "Switch Scene Tab"
@@ -2627,9 +2621,8 @@ msgid "Go to previously opened scene."
msgstr "पहले खोले गठदृशà¥à¤¯ में जाà¤à¤‚।"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Copy Text"
-msgstr "सभी खंड"
+msgstr "टेकà¥à¤¸à¥à¤Ÿ कौपी कीजिये"
#: editor/editor_node.cpp
msgid "Next tab"
@@ -2731,18 +2724,16 @@ msgid "Install Android Build Template..."
msgstr "à¤à¤‚डà¥à¤°à¥‰à¤¯à¤¡ बिलà¥à¤¡ टेमà¥à¤ªà¤²à¥‡à¤Ÿ सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ करें..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Project Data Folder"
-msgstr "परियोजना के संसà¥à¤¥à¤¾à¤ªà¤•"
+msgstr "पà¥à¤°à¥‹à¤œà¥‡à¤•à¥à¤Ÿ डेटा फ़ोलà¥à¤¡à¤° खोलिये"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
msgstr "उपकरण"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Orphan Resource Explorer..."
-msgstr "Orphan Resource Explorer"
+msgstr "असहाय रेसोरà¥à¤¸ खोजकरà¥à¤¤à¤¾..."
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2842,9 +2833,8 @@ msgid "Editor"
msgstr "संपादक"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Editor Settings..."
-msgstr "अनà¥à¤µà¤¾à¤¦ में बदलाव करें:"
+msgstr "à¤à¤¡à¥€à¤Ÿà¤° सेटिनà¥à¤—स..."
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2910,11 +2900,11 @@ msgstr "Q&A"
#: editor/editor_node.cpp
msgid "Report a Bug"
-msgstr ""
+msgstr "पà¥à¤°à¥‹à¤—à¥à¤°à¤¾à¤® में तà¥à¤°à¥à¤Ÿà¤¿ की शिकायत करें"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Docs की पà¥à¤°à¤¤à¤¿à¤•à¥à¤°à¤¿à¤¯à¤¾ भेजें"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3103,9 +3093,8 @@ msgid "Warning!"
msgstr "चेतावनी!"
#: editor/editor_path.cpp
-#, fuzzy
msgid "No sub-resources found."
-msgstr "संसाधन"
+msgstr "सब-रिसोरà¥à¤¸ नहीं मिला."
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
@@ -3116,9 +3105,8 @@ msgid "Thumbnail..."
msgstr "थंबनेल..."
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Main Script:"
-msgstr "निरà¥à¤­à¤°à¤¤à¤¾ संपादक"
+msgstr "मेन सà¥à¤•à¥à¤°à¤¿à¤ªà¥à¤Ÿ:"
#: editor/editor_plugin_settings.cpp
msgid "Edit Plugin"
@@ -3190,9 +3178,8 @@ msgid "Calls"
msgstr "कॉल"
#: editor/editor_properties.cpp
-#, fuzzy
msgid "Edit Text:"
-msgstr "परिवरà¥à¤¤à¤¨ वकà¥à¤° चयन"
+msgstr "टेकà¥à¤¸à¥à¤Ÿ संपादित करें:"
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
@@ -3215,9 +3202,8 @@ msgid "Assign..."
msgstr "सौंपना..."
#: editor/editor_properties.cpp
-#, fuzzy
msgid "Invalid RID"
-msgstr "गलत फॉणà¥à¤Ÿ का आकार |"
+msgstr "अमानà¥à¤¯ RID"
#: editor/editor_properties.cpp
msgid ""
@@ -3469,9 +3455,8 @@ msgid "Download Complete."
msgstr "पूरा डाउनलोड करें।"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Cannot remove temporary file:"
-msgstr "निकाला नहीं जा सकता:"
+msgstr "अलà¥à¤ªà¤•ालिक फ़ाइल निकाली नहीं जा सकà¥à¤¤à¥€:"
#: editor/export_template_manager.cpp
msgid ""
@@ -3610,19 +3595,19 @@ msgstr "बशरà¥à¤¤à¥‡ नाम में अमानà¥à¤¯ पातà¥à¤
#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
-msgstr ""
+msgstr "इस नाम से फ़ाइल या फ़ोलà¥à¤¡à¤° पहले से मौजूद."
#: editor/filesystem_dock.cpp
msgid "Name contains invalid characters."
-msgstr ""
+msgstr "नाम मे अमानà¥à¤¯ अकà¥à¤·à¤° मौजूद."
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
-msgstr ""
+msgstr "फ़ाइल का नाम बदल रहे है:"
#: editor/filesystem_dock.cpp
msgid "Renaming folder:"
-msgstr ""
+msgstr "फ़ोलà¥à¤¡à¤° का नाम बदल रहे है:"
#: editor/filesystem_dock.cpp
msgid "Duplicating file:"
@@ -3634,11 +3619,11 @@ msgstr "डà¥à¤ªà¥à¤²à¤¿à¤•ेटिंग फ़ोलà¥à¤¡à¤°:"
#: editor/filesystem_dock.cpp
msgid "New Inherited Scene"
-msgstr ""
+msgstr "नई उतà¥à¤¤à¤°à¤¾à¤§à¤¿à¤•ार पà¥à¤°à¤¾à¤ªà¥à¤¤ सीन"
#: editor/filesystem_dock.cpp
msgid "Set As Main Scene"
-msgstr ""
+msgstr "मेन सीन सेट करे"
#: editor/filesystem_dock.cpp
msgid "Open Scenes"
@@ -3658,7 +3643,7 @@ msgstr "पसंदीदा से निकालें"
#: editor/filesystem_dock.cpp
msgid "Edit Dependencies..."
-msgstr ""
+msgstr "निरà¥à¤­à¤°à¤¿à¤¤ फ़ाइलें संपादित करें..."
#: editor/filesystem_dock.cpp
msgid "View Owners..."
@@ -9730,6 +9715,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10833,6 +10825,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "â€à¤à¤•à¥à¤¸à¤ªà¥‹à¤°à¥à¤Ÿ पà¥à¤°à¥‹à¤«à¤¼à¤¾à¤‡à¤²"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/hr.po b/editor/translations/hr.po
index 5087044b13..8627e7f239 100644
--- a/editor/translations/hr.po
+++ b/editor/translations/hr.po
@@ -9567,6 +9567,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10656,6 +10663,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index 54206db36f..620a2d4d5b 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -10,7 +10,6 @@
# Tusa Gamer <tusagamer@mailinator.com>, 2018.
# Máté Lugosi <mate.lugosi@gmail.com>, 2019.
# sztrovacsek <magadeve@gmail.com>, 2019.
-# Deleted User <noreply+18797@weblate.org>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
@@ -10265,6 +10264,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -11409,6 +11415,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Projekt Exportálása"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/id.po b/editor/translations/id.po
index 087a274249..54222d1aeb 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -9925,6 +9925,13 @@ msgstr ""
"Saat ini Anda tidak memiliki proyek.\n"
"Apakah Anda ingin menjelajahi contoh proyek resmi di Pustaka Aset?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Kunci "
@@ -11041,6 +11048,11 @@ msgid "Total:"
msgstr "Total:"
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Ekspor Profil"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Lokasi Resource"
diff --git a/editor/translations/is.po b/editor/translations/is.po
index bb865e255a..e2943eb9cf 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -9629,6 +9629,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10716,6 +10723,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/it.po b/editor/translations/it.po
index 4ce247c712..8e9432baac 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -45,12 +45,15 @@
# Fabio Iotti <fabiogiopla@gmail.com>, 2020.
# Douglas Fiedler <dognew@gmail.com>, 2020.
# E440QF <ettore.beltra@gmail.com>, 2020.
+# Giuseppe Lucido <giuseppe.lucido@gmail.com>, 2020.
+# Mirko Proto <mirko7@protonmail.com>, 2020.
+# J. Lavoie <j.lavoie@net-c.ca>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-04-08 16:36+0000\n"
-"Last-Translator: E440QF <ettore.beltra@gmail.com>\n"
+"PO-Revision-Date: 2020-05-04 15:12+0000\n"
+"Last-Translator: J. Lavoie <j.lavoie@net-c.ca>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/"
"godot/it/>\n"
"Language: it\n"
@@ -58,7 +61,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2984,13 +2987,12 @@ msgid "Q&A"
msgstr "Domande e risposte"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Reimporta"
+msgstr "Riporta un Bug"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Invia opinione sui documenti"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3026,7 +3028,7 @@ msgstr "Esegui la scena in modifica."
#: editor/editor_node.cpp
msgid "Play Scene"
-msgstr "Esegui scena"
+msgstr "Avvia Scena"
#: editor/editor_node.cpp
msgid "Play custom scene"
@@ -3034,7 +3036,7 @@ msgstr "Esegui scena personalizzata"
#: editor/editor_node.cpp
msgid "Play Custom Scene"
-msgstr "Esegui scena personalizzata"
+msgstr "Avvia Scena Personalizzata"
#: editor/editor_node.cpp
msgid "Changing the video driver requires restarting the editor."
@@ -3071,7 +3073,7 @@ msgstr "Ispettore"
#: editor/editor_node.cpp
msgid "Expand Bottom Panel"
-msgstr "Espandi pannello inferiore"
+msgstr "Espandi Pannello Inferiore"
#: editor/editor_node.cpp
msgid "Output"
@@ -4049,9 +4051,8 @@ msgid "Reimport"
msgstr "Reimporta"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
-msgstr "Salva scene, importa nuovamente e riavvia"
+msgstr "Salva scene, re-importa e riavvia"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -6030,7 +6031,6 @@ msgstr ""
"collisioni."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Collision Sibling"
msgstr "Crea Singolo Fratello di Collisione Convessa"
@@ -7360,9 +7360,8 @@ msgid "This operation requires a single selected node."
msgstr "Questa operazione richiede un solo nodo selezionato."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Ortogonale"
+msgstr "Ortogonale Automatico Abilitato"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -9991,6 +9990,13 @@ msgstr ""
"Al momento non hai nessun progetto.\n"
"Ti piacerebbe esplorare gli esempi ufficiali nella libreria degli Asset?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Tasto "
@@ -10983,6 +10989,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Note: Gli script pre-installati hanno alcune limitazioni e non possono "
+"essere modificati utilizzando un editor esterno."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11105,6 +11113,10 @@ msgid "Total:"
msgstr "Totale:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "Esporta l'elenco in un file CSV"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Percorso Risorsa"
@@ -12788,6 +12800,8 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
+"La dimensione del Viewport deve essere maggiore di 0 affinché qualcosa sia "
+"visibile."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index ab503d8294..8aef04db94 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -7,7 +7,7 @@
# Daisuke Saito <d.saito@coriginate.com>, 2017, 2018.
# h416 <shinichiro.hirama@gmail.com>, 2017.
# hopping tappy (ãŸã£ã´ã•ã‚“) <hopping.tappy@gmail.com>, 2016-2017, 2018.
-# Jun Shiozawa <haresecret@gmail.com>, 2017, 2018.
+# Jun Shiozawa <haresecret@gmail.com>, 2017, 2018, 2020.
# Lexi Grafen <shfeedly@gmail.com>, 2017.
# NoahDigital <taku_58@hotmail.com>, 2017.
# Shinsuke Masuda <shinsuke.masuda@gmail.com>, 2018.
@@ -35,7 +35,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-04-15 14:29+0000\n"
+"PO-Revision-Date: 2020-05-04 15:12+0000\n"
"Last-Translator: Wataru Onuki <bettawat@yahoo.co.jp>\n"
"Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/"
"godot/ja/>\n"
@@ -44,7 +44,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -297,7 +297,7 @@ msgstr "時間 (秒): "
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
-msgstr "トラックを有効ã«ã™ã‚‹"
+msgstr "トラックを有効 / 無効"
#: editor/animation_track_editor.cpp
msgid "Continuous"
@@ -592,7 +592,7 @@ msgstr "é¸æŠžç¯„å›²ã‚’è¤‡è£½"
#: editor/animation_track_editor.cpp
msgid "Duplicate Transposed"
-msgstr "複製を転置"
+msgstr "転置ã—ã¦è¤‡è£½"
#: editor/animation_track_editor.cpp
msgid "Delete Selection"
@@ -1210,7 +1210,7 @@ msgstr "コンãƒãƒ¼ãƒãƒ³ãƒˆ"
#: editor/editor_about.cpp
msgid "Licenses"
-msgstr "ライセンス"
+msgstr "ライセンス文書"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Error opening package file, not in ZIP format."
@@ -1251,7 +1251,7 @@ msgstr "インストール"
#: editor/editor_asset_installer.cpp
msgid "Package Installer"
-msgstr "パッケージインストーラー"
+msgstr "パッケージインストーラ"
#: editor/editor_audio_buses.cpp
msgid "Speakers"
@@ -1271,15 +1271,15 @@ msgstr "オーディオãƒã‚¹ã®ãƒœãƒªãƒ¥ãƒ¼ãƒ ã‚’変更"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Solo"
-msgstr "オーディオãƒã‚¹ã®ã‚½ãƒ­ã‚’切り替ãˆ"
+msgstr "オーディオãƒã‚¹ã®ã‚½ãƒ­ã‚’オン / オフ"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Mute"
-msgstr "オーディオãƒã‚¹ã®ãƒŸãƒ¥ãƒ¼ãƒˆã‚’切り替ãˆ"
+msgstr "オーディオãƒã‚¹ã®ãƒŸãƒ¥ãƒ¼ãƒˆã‚’オン / オフ"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Bypass Effects"
-msgstr "オーディオãƒã‚¹ã®ãƒã‚¤ãƒ‘スエフェクトを切り替ãˆ"
+msgstr "オーディオãƒã‚¹ã®ãƒã‚¤ãƒ‘スエフェクトをオン / オフ"
#: editor/editor_audio_buses.cpp
msgid "Select Audio Bus Send"
@@ -1287,7 +1287,7 @@ msgstr "オーディオãƒã‚¹ã®å‡ºåŠ›å…ˆã‚’é¸æŠž"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
-msgstr "オーディオãƒã‚¹ã‚¨ãƒ•ェクトを追加"
+msgstr "オーディオãƒã‚¹ エフェクトを追加"
#: editor/editor_audio_buses.cpp
msgid "Move Bus Effect"
@@ -1458,7 +1458,7 @@ msgstr "自動読込ã¿ã®åå‰å¤‰æ›´"
#: editor/editor_autoload_settings.cpp
msgid "Toggle AutoLoad Globals"
-msgstr "グローãƒãƒ«ã®è‡ªå‹•読込ã¿ã‚’切り替ãˆ"
+msgstr "グローãƒãƒ«ã®è‡ªå‹•読込ã¿ã‚’オン / オフ"
#: editor/editor_autoload_settings.cpp
msgid "Move Autoload"
@@ -1858,11 +1858,11 @@ msgstr "上ã¸"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
-msgstr "éš ã—ファイルã®åˆ‡ã‚Šæ›¿ãˆ"
+msgstr "éš ã—ファイルをオン / オフ"
#: editor/editor_file_dialog.cpp
msgid "Toggle Favorite"
-msgstr "ãŠæ°—ã«å…¥ã‚Šã®åˆ‡ã‚Šæ›¿ãˆ"
+msgstr "ãŠæ°—ã«å…¥ã‚Šã«ã™ã‚‹ / ã—ãªã„"
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
@@ -1870,7 +1870,7 @@ msgstr "モード切替ãˆ"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
-msgstr "フォーカスパス"
+msgstr "パスã«ãƒ•ォーカス"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
@@ -1898,11 +1898,11 @@ msgstr "ファイル更新。"
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
-msgstr "ç¾åœ¨ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’ãŠæ°—ã«å…¥ã‚Šã«ã™ã‚‹/ãŠæ°—ã«å…¥ã‚Šã‹ã‚‰å¤–ã™ã€‚"
+msgstr "ç¾åœ¨ã®ãƒ•ã‚©ãƒ«ãƒ€ã‚’ãŠæ°—ã«å…¥ã‚Šã«ã™ã‚‹ / ã—ãªã„。"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Toggle the visibility of hidden files."
-msgstr "éš ã—ファイルã®è¡¨ç¤º/éžè¡¨ç¤ºã‚’切り替ãˆã¾ã™ã€‚"
+msgstr "éš ã—ファイルã®è¡¨ç¤º / éžè¡¨ç¤ºã‚’切り替ãˆã¾ã™ã€‚"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
@@ -1989,7 +1989,7 @@ msgstr "メソッド"
#: editor/editor_help.cpp
msgid "Theme Properties"
-msgstr "テーマプロパティ"
+msgstr "テーマ プロパティ"
#: editor/editor_help.cpp
msgid "Enumerations"
@@ -2902,11 +2902,11 @@ msgstr "スクリーンショットã¯Editor Data / Settingsフォルダã«ä¿å­
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
-msgstr "フルスクリーン切り替ãˆ"
+msgstr "ãƒ•ãƒ«ã‚¹ã‚¯ãƒªãƒ¼ãƒ³ã®æœ‰åŠ¹åŒ– / 無効化"
#: editor/editor_node.cpp
msgid "Toggle System Console"
-msgstr "システムコンソールã®åˆ‡ã‚Šæ›¿ãˆ"
+msgstr "ã‚·ã‚¹ãƒ†ãƒ ã‚³ãƒ³ã‚½ãƒ¼ãƒ«ã®æœ‰åŠ¹åŒ– / 無効化"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
@@ -2951,13 +2951,12 @@ msgid "Q&A"
msgstr "Q&A"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
+msgstr "ãƒã‚°ã‚’報告"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "ドキュメントã®ãƒ•ィードãƒãƒƒã‚¯ã‚’é€ã‚‹"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4008,9 +4007,8 @@ msgid "Reimport"
msgstr "å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
-msgstr "シーンをä¿å­˜ã—ã¦ã€å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¦å†èµ·å‹•ã—ã¦ãã ã•ã„"
+msgstr "シーンをä¿å­˜ã—ã€å†ã‚¤ãƒ³ãƒãƒ¼ãƒˆã—ã¦ã‹ã‚‰ã€å†èµ·å‹•ã—ã¾ã™"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -4053,6 +4051,7 @@ msgid "Copy Resource"
msgstr "リソースをコピー"
#: editor/inspector_dock.cpp
+#, fuzzy
msgid "Make Built-In"
msgstr "ビルトインを作æˆ"
@@ -4309,7 +4308,7 @@ msgstr "三角形ãŒå­˜åœ¨ã—ãªã„ãŸã‚ã€ãƒ–レンドã§ãã¾ã›ã‚“。"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Toggle Auto Triangles"
-msgstr "三角形ã®è‡ªå‹•作æˆã«åˆ‡ã‚Šæ›¿ãˆ"
+msgstr "三角形ã®è‡ªå‹•作æˆã‚’オン / オフ"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Create triangles by connecting points."
@@ -4437,7 +4436,7 @@ msgstr "フィルタリングを有効化"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Toggle Autoplay"
-msgstr "自動å†ç”Ÿã®åˆ‡ã‚Šæ›¿ãˆ"
+msgstr "自動å†ç”Ÿã®æœ‰åŠ¹åŒ– / 無効化"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "New Animation Name:"
@@ -4723,8 +4722,8 @@ msgstr "é¸æŠžã—ãŸãƒŽãƒ¼ãƒ‰ã¾ãŸã¯ãƒˆãƒ©ãƒ³ã‚¸ã‚·ãƒ§ãƒ³ã‚’除去。"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Toggle autoplay this animation on start, restart or seek to zero."
msgstr ""
-"ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®è‡ªå‹•å†ç”Ÿã®é–‹å§‹ã€å†èµ·å‹•ã€ã¾ãŸã¯ã‚¼ãƒ­ã¸ã®ã‚·ãƒ¼ã‚¯ã‚’切り替ãˆã¾"
-"ã™ã€‚"
+"é–‹å§‹ã€å†ã‚¹ã‚¿ãƒ¼ãƒˆã€ã¾ãŸã¯ã‚¼ãƒ­ã¸ã®ã‚·ãƒ¼ã‚¯æ™‚ã«ãŠã‘ã‚‹ã€ã“ã®ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã®è‡ªå‹•å†"
+"生をオン / オフã«ã—ã¾ã™ã€‚"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Set the end animation. This is useful for sub-transitions."
@@ -5318,22 +5317,22 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock Selected"
-msgstr "é¸æŠžã‚’ãƒ­ãƒƒã‚¯"
+msgstr "é¸æŠžå¯¾è±¡ã‚’ãƒ­ãƒƒã‚¯"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Unlock Selected"
-msgstr "é¸æŠžã‚’è§£é™¤"
+msgstr "é¸æŠžå¯¾è±¡ã‚’ãƒ­ãƒƒã‚¯è§£é™¤"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Group Selected"
-msgstr "é¸æŠžã—ãŸã‚°ãƒ«ãƒ¼ãƒ—"
+msgstr "é¸æŠžå¯¾è±¡ã‚’ã‚°ãƒ«ãƒ¼ãƒ—åŒ–"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Ungroup Selected"
-msgstr "グループ解除"
+msgstr "é¸æŠžå¯¾è±¡ã‚’ã‚°ãƒ«ãƒ¼ãƒ—è§£é™¤"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Paste Pose"
@@ -5378,7 +5377,7 @@ msgstr "é¸æŠžãƒ¢ãƒ¼ãƒ‰"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Drag: Rotate"
-msgstr "ドラッグ:回転"
+msgstr "ドラッグ: 回転"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+Drag: Move"
@@ -5392,7 +5391,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+RMB: Depth list selection"
-msgstr "Alt+å³ã‚¯ãƒªãƒƒã‚¯: 奥行ã(被写界深度)リストã®é¸æŠž"
+msgstr "Alt+å³ã‚¯ãƒªãƒƒã‚¯: 奥行ãé¸æŠžãƒªã‚¹ãƒˆ"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5432,7 +5431,7 @@ msgstr "定è¦ãƒ¢ãƒ¼ãƒ‰"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Toggle smart snapping."
-msgstr "スマートスナッピングを切り替ãˆã‚‹ã€‚"
+msgstr "スマート スナッピングをオン / オフ。"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Smart Snap"
@@ -5440,7 +5439,7 @@ msgstr "スマートスナップを使ã†"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Toggle grid snapping."
-msgstr "グリッドスナッピングを切り替ãˆã‚‹ã€‚"
+msgstr "グリッド スナッピングをオン / オフ。"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Grid Snap"
@@ -5502,12 +5501,12 @@ msgstr "ガイドã«ã‚¹ãƒŠãƒƒãƒ—"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock the selected object in place (can't be moved)."
-msgstr "é¸æŠžã—ãŸã‚ªãƒ–ジェクトをãã®å ´ã§ãƒ­ãƒƒã‚¯ (移動ä¸å¯èƒ½ã«ã™ã‚‹)。"
+msgstr "é¸æŠžã—ãŸã‚ªãƒ–ジェクトをç¾åœ¨ä½ç½®ã§ãƒ­ãƒƒã‚¯ (移動ä¸å¯èƒ½ã«ã™ã‚‹)。"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Unlock the selected object (can be moved)."
-msgstr "é¸æŠžã—ãŸã‚ªãƒ–ジェクトをアンロック (移動å¯èƒ½ã«ã™ã‚‹)。"
+msgstr "é¸æŠžã—ãŸã‚ªãƒ–ジェクトをロック解除 (移動å¯èƒ½ã«ã™ã‚‹)。"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5570,11 +5569,11 @@ msgstr "グループアイコンã¨ãƒ­ãƒƒã‚¯ã‚¢ã‚¤ã‚³ãƒ³ã‚’表示"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center Selection"
-msgstr "ã‚»ãƒ³ã‚¿ãƒ¼é¸æŠž"
+msgstr "é¸æŠžå¯¾è±¡ã‚’ä¸­å¤®ã«"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Frame Selection"
-msgstr "ãƒ•ãƒ¬ãƒ¼ãƒ é¸æŠž"
+msgstr "é¸æŠžå¯¾è±¡ã‚’å…¨é¢ã«"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Preview Canvas Scale"
@@ -5693,7 +5692,7 @@ msgstr "ãƒãƒ³ãƒ‰ãƒ«ã‚’設定ã™ã‚‹"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Load Emission Mask"
-msgstr "発光(Emission)マスクを読ã¿è¾¼ã‚€"
+msgstr "放射マスクを読ã¿è¾¼ã‚€"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/cpu_particles_editor_plugin.cpp
@@ -6272,7 +6271,7 @@ msgstr "曲線を分割ã™ã‚‹"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Move Point in Curve"
-msgstr "曲線内ã®ãƒã‚¤ãƒ³ãƒˆã‚’移動"
+msgstr "曲線内ã®ç‚¹ã‚’移動"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Move In-Control in Curve"
@@ -6844,7 +6843,7 @@ msgstr "ブレーク"
#: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp
#: editor/script_editor_debugger.cpp
msgid "Continue"
-msgstr "実行を継続"
+msgstr "続行"
#: editor/plugins/script_editor_plugin.cpp
msgid "Keep Debugger Open"
@@ -7036,7 +7035,7 @@ msgstr "シンボルを補完"
#: editor/plugins/script_text_editor.cpp
msgid "Evaluate Selection"
-msgstr "é¸æŠžã—ãŸã‚‚ã®ã‚’評価ã™ã‚‹"
+msgstr "é¸æŠžç¯„å›²ã‚’è©•ä¾¡ã™ã‚‹"
#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
@@ -7060,11 +7059,11 @@ msgstr "複数ファイル内を検索..."
#: editor/plugins/script_text_editor.cpp
msgid "Contextual Help"
-msgstr "コンテキストヘルプ"
+msgstr "コンテキスト ヘルプ"
#: editor/plugins/script_text_editor.cpp
msgid "Toggle Bookmark"
-msgstr "ブックマークã®åˆ‡ã‚Šæ›¿ãˆ"
+msgstr "ブックマークをã¤ã‘ã‚‹ / 外ã™"
#: editor/plugins/script_text_editor.cpp
msgid "Go to Next Bookmark"
@@ -7089,7 +7088,7 @@ msgstr "行ã«ç§»å‹•..."
#: editor/plugins/script_text_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Toggle Breakpoint"
-msgstr "ブレークãƒã‚¤ãƒ³ãƒˆã‚’切り替ãˆ"
+msgstr "ブレークãƒã‚¤ãƒ³ãƒˆã‚’ã¤ã‘ã‚‹ / 外ã™"
#: editor/plugins/script_text_editor.cpp
msgid "Remove All Breakpoints"
@@ -7296,9 +7295,8 @@ msgid "This operation requires a single selected node."
msgstr "å˜ä¸€ã®é¸æŠžã•れãŸãƒŽãƒ¼ãƒ‰ãŒãªã„ã¨ã€ã“ã®æ“作ã¯è¡Œãˆã¾ã›ã‚“。"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "平行投影"
+msgstr "自動平行投影 有効"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -7366,11 +7364,11 @@ msgstr "フリールックå³"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Forward"
-msgstr "剿–¹ã‚’フリールックã§è¦‹ã‚‹"
+msgstr "フリールックå‰é€²"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Backwards"
-msgstr "フリールック後方"
+msgstr "フリールック後進"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Up"
@@ -7382,11 +7380,11 @@ msgstr "フリールック下"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Speed Modifier"
-msgstr "フリールックã®é€Ÿåº¦ã‚’調整"
+msgstr "フリールックã®é€Ÿåº¦èª¿æ•´"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Slow Modifier"
-msgstr "ãƒ•ãƒªãƒ¼ãƒ«ãƒƒã‚¯ã®æ¸›é€Ÿã‚’調整"
+msgstr "ãƒ•ãƒªãƒ¼ãƒ«ãƒƒã‚¯ã®æ¸›é€Ÿèª¿æ•´"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Rotation Locked"
@@ -7402,7 +7400,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
-msgstr "Xformダイアログ"
+msgstr "XFormダイアログ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Nodes To Floor"
@@ -7410,7 +7408,7 @@ msgstr "ノードをフロアã«ã‚¹ãƒŠãƒƒãƒ—"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Couldn't find a solid floor to snap the selection to."
-msgstr "é¸æŠžã‚’ã‚¹ãƒŠãƒƒãƒ—ã™ã‚‹å‰›ä½“ã®åºŠã‚’見ã¤ã‘れã¾ã›ã‚“。"
+msgstr "é¸æŠžå¯¾è±¡ã‚’ã‚¹ãƒŠãƒƒãƒ—ã•ã›ã‚‹å‰›ä½“ã®åºŠã‚’見ã¤ã‘られã¾ã›ã‚“ã§ã—ãŸã€‚"
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
@@ -7418,9 +7416,9 @@ msgid ""
"Alt+Drag: Move\n"
"Alt+RMB: Depth list selection"
msgstr ""
-"ドラッグ:回転\n"
-"Alt+ドラッグ:移動\n"
-"Alt+å³ã‚¯ãƒªãƒƒã‚¯: 奥行ãリストã®é¸æŠž"
+"ドラッグ: 回転\n"
+"Alt+ドラッグ: 移動\n"
+"Alt+å³ã‚¯ãƒªãƒƒã‚¯: 奥行ãé¸æŠžãƒªã‚¹ãƒˆ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Local Space"
@@ -7456,7 +7454,7 @@ msgstr "å³å´é¢å›³"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Switch Perspective/Orthogonal View"
-msgstr "é€è¦–図/正投影図ã®åˆ‡ã‚Šæ›¿ãˆ"
+msgstr "é€è¦–投影 / 平行投影ã®åˆ‡ã‚Šæ›¿ãˆ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Insert Animation Key"
@@ -7468,11 +7466,11 @@ msgstr "原点ã«ãƒ•ォーカス"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Selection"
-msgstr "é¸æŠžã«ãƒ•ォーカス"
+msgstr "é¸æŠžå¯¾è±¡ã«ãƒ•ォーカス"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Toggle Freelook"
-msgstr "フリールックã®åˆ‡ã‚Šæ›¿ãˆ"
+msgstr "フリールックã®ã‚ªãƒ³ / オフ"
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
@@ -7497,7 +7495,7 @@ msgstr "2 ビューãƒãƒ¼ãƒˆ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "2 Viewports (Alt)"
-msgstr "2 ビューãƒãƒ¼ãƒˆ(Alt)"
+msgstr "2 ビューãƒãƒ¼ãƒˆ (Alt)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports"
@@ -7505,7 +7503,7 @@ msgstr "3 ビューãƒãƒ¼ãƒˆ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports (Alt)"
-msgstr "3 ビューãƒãƒ¼ãƒˆ(Alt)"
+msgstr "3 ビューãƒãƒ¼ãƒˆ (Alt)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "4 Viewports"
@@ -7594,7 +7592,7 @@ msgstr "ç„¡åã®ã‚®ã‚ºãƒ¢"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create Mesh2D"
-msgstr "Mesh2Dを作æˆ"
+msgstr "Mesh2Dを生æˆ"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Mesh2D Preview"
@@ -7802,7 +7800,7 @@ msgstr "スプライトフレーム"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Set Region Rect"
-msgstr "矩形ã®é ˜åŸŸã‚’設定"
+msgstr "領域 Rect を設定"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Set Margin"
@@ -7891,7 +7889,7 @@ msgstr "ç¾åœ¨ã®ã‚¨ãƒ‡ã‚£ã‚¿ãƒ†ãƒ¼ãƒžã‹ã‚‰ä½œæˆ"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Toggle Button"
-msgstr "ボタンã®åˆ‡ã‚Šæ›¿ãˆ"
+msgstr "切り替ãˆãƒœã‚¿ãƒ³"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Disabled Button"
@@ -7971,7 +7969,7 @@ msgstr "サブツリー"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has,Many,Options"
-msgstr "ã‚りã¾ã™ã‚ˆ,ãŸãã•ã‚“,オプション"
+msgstr "Has,Many,Options"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Data Type:"
@@ -7992,7 +7990,7 @@ msgstr "フォント"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Color"
-msgstr "\\ Color"
+msgstr "Color"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme File"
@@ -8000,7 +7998,7 @@ msgstr "テーマ ファイル"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase Selection"
-msgstr "é¸æŠžå¯¾è±¡ã‚’æ¶ˆåŽ»"
+msgstr "é¸æŠžç¯„å›²ã‚’æ¶ˆåŽ»"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Fix Invalid Tiles"
@@ -8009,7 +8007,7 @@ msgstr "無効ãªã‚¿ã‚¤ãƒ«ã‚’修正"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Cut Selection"
-msgstr "é¸æŠžå¯¾è±¡ã‚’åˆ‡ã‚Šå–り"
+msgstr "é¸æŠžç¯„å›²ã‚’åˆ‡ã‚Šå–り"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint TileMap"
@@ -8021,7 +8019,7 @@ msgstr "ç›´ç·šã‚’æç”»"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rectangle Paint"
-msgstr "矩形ペイント"
+msgstr "長方形ペイント"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Bucket Fill"
@@ -8033,7 +8031,7 @@ msgstr "タイルマップを消去"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Find Tile"
-msgstr "タイルを検索ã™ã‚‹"
+msgstr "タイルを検索"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Transpose"
@@ -8059,19 +8057,19 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint Tile"
-msgstr "タイルを塗る"
+msgstr "タイルをペイント"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
"Shift+LMB: Line Draw\n"
"Shift+Ctrl+LMB: Rectangle Paint"
msgstr ""
-"Shift+左マウスボタン:ç·šã®æç”»\n"
-"Shift+Ctrl+左マウスボタン:矩形ペイント"
+"Shift+左マウスボタン: ç›´ç·šã«æã\n"
+"Shift+Ctrl+左マウスボタン: 長方形ペイント"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Pick Tile"
-msgstr "ã‚¿ã‚¤ãƒ«ã‚’é¸æŠž"
+msgstr "タイルをピック"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rotate Left"
@@ -8211,7 +8209,7 @@ msgstr "ビットマスクを消去。"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create a new rectangle."
-msgstr "æ–°è¦çŸ©å½¢ã‚’作æˆã€‚"
+msgstr "æ–°ã—ã長方形を作æˆã€‚"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create a new polygon."
@@ -8268,12 +8266,12 @@ msgid ""
"Drag handles to edit Rect.\n"
"Click on another Tile to edit it."
msgstr ""
-"ãƒãƒ³ãƒ‰ãƒ«ã‚’ドラッグã—ã¦çŸ©å½¢ã‚’編集ã—ã¾ã™ã€‚\n"
-"別ã®ã‚¿ã‚¤ãƒ«ã‚’クリックã—ã¦ãれを編集ã—ã¾ã™ã€‚"
+"ãƒãƒ³ãƒ‰ãƒ«ã‚’ドラッグã—ã¦é•·æ–¹å½¢ã‚’編集ã—ã¾ã™ã€‚\n"
+"別ã®ã‚¿ã‚¤ãƒ«ã‚’クリックã™ã‚‹ã¨ãれを編集ã—ã¾ã™ã€‚"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Delete selected Rect."
-msgstr "é¸æŠžã—ãŸçŸ©å½¢ã‚’削除ã™ã‚‹ã€‚"
+msgstr "é¸æŠžã—ãŸé•·æ–¹å½¢ã‚’削除ã™ã‚‹ã€‚"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8479,7 +8477,7 @@ msgstr "タイプã®å¤‰æ›´"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Stage Selected"
-msgstr "é¸æŠžç‰©ã‚’ã‚¹ãƒ†ãƒ¼ã‚¸ã™ã‚‹"
+msgstr "é¸æŠžå¯¾è±¡ã‚’ã‚¹ãƒ†ãƒ¼ã‚¸ã™ã‚‹"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Stage All"
@@ -9288,6 +9286,7 @@ msgstr ""
"ãŸã‚ã«ãれを使用ã—ãªã„ã§ãã ã•ã„。"
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid ""
"Returns falloff based on the dot product of surface normal and view "
"direction of camera (pass associated inputs to it)."
@@ -9631,7 +9630,7 @@ msgstr "プロジェクトã«åå‰ã‚’付ã‘ã¦ãã ã•ã„."
#: editor/project_manager.cpp
msgid "Invalid project path (changed anything?)."
-msgstr "プロジェクトパスãŒç„¡åйã§ã™(何ã‹ã‚’変更ã—ã¾ã—ãŸã‹?)。"
+msgstr "無効ãªãƒ—ロジェクトパスã§ã™ (ãªã«ã‹å¤‰æ›´ãŒã‚りã¾ã—ãŸã‹ï¼Ÿ)。"
#: editor/project_manager.cpp
msgid ""
@@ -9762,13 +9761,13 @@ msgid ""
"Warning: You won't be able to open the project with previous versions of the "
"engine anymore."
msgstr ""
-"次ã®ãƒ—ロジェクト設定ファイルã«ã¯ã€ä½œæˆã«ä½¿ç”¨ã—ãŸGodotã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¯æŒ‡å®šã•れã¦"
-"ã„ã¾ã›ã‚“。\n"
+"次ã®ãƒ—ロジェクト設定ファイルã«ã¯ã€ä½œæˆã«ä½¿ç”¨ã•れãŸGodotã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒæŒ‡å®šã•れ"
+"ã¦ã„ã¾ã›ã‚“。\n"
"\n"
"%s\n"
"\n"
"ファイルを開ãã¨ã€Godotã®ç¾åœ¨ã®è¨­å®šãƒ•ァイル形å¼ã«å¤‰æ›ã•れã¾ã™ã€‚\n"
-"警告:以å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚¨ãƒ³ã‚¸ãƒ³ã§ã¯ãƒ—ロジェクトを開ã‘ã¾ã›ã‚“。"
+"警告: 以å‰ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚¨ãƒ³ã‚¸ãƒ³ã§ã¯ãƒ—ロジェクトを開ã‘ãªããªã‚Šã¾ã™ã€‚"
#: editor/project_manager.cpp
msgid ""
@@ -9908,6 +9907,17 @@ msgstr ""
"プロジェクトãŒä½•も登録ã•れã¦ã„ã¾ã›ã‚“。\n"
"アセットライブラリã§å…¬å¼ã®ã‚µãƒ³ãƒ—ルプロジェクトをãƒã‚§ãƒƒã‚¯ã—ã¾ã™ã‹ï¼Ÿ"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"検索ボックスã§ã¯ã€ãƒ—ロジェクトã¯åå‰ãŠã‚ˆã³ãƒ‘ã‚¹ã®æœ€å¾Œã®éƒ¨åˆ†ã§ãƒ•ィルターã•れã¾"
+"ã™ã€‚\n"
+"プロジェクトåãŠã‚ˆã³å®Œå…¨ãƒ‘スã§ãƒ•ィルターã™ã‚‹ã«ã¯ã€ã‚¯ã‚¨ãƒªã«ã¯ `/` 文字ãŒå°‘ãªã"
+"ã¨ã‚‚1ã¤å¿…è¦ã§ã™ã€‚"
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "キー "
@@ -10018,7 +10028,7 @@ msgstr "入力アクションを消去"
#: editor/project_settings_editor.cpp
msgid "Erase Input Action Event"
-msgstr "入力アクションイベントを消去"
+msgstr "入力アクション イベントを消去"
#: editor/project_settings_editor.cpp
msgid "Add Event"
@@ -10026,7 +10036,7 @@ msgstr "イベントを追加"
#: editor/project_settings_editor.cpp
msgid "Button"
-msgstr "\\ Button"
+msgstr "Button"
#: editor/project_settings_editor.cpp
msgid "Left Button."
@@ -10266,7 +10276,7 @@ msgstr "ファイル読ã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼: リソースã§ã¯ã‚りã¾ã›ã‚“!"
#: editor/property_editor.cpp
msgid "Pick a Node"
-msgstr "ãƒŽãƒ¼ãƒ‰ã‚’é¸æŠžã™ã‚‹"
+msgstr "ノードをé¸ã¶"
#: editor/property_editor.cpp
msgid "Bit %d, val %d."
@@ -10606,8 +10616,8 @@ msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
msgstr ""
-"æ–°ã—ã„シーンをä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ ãŠãらãä¾å­˜é–¢ä¿‚(インスタンス)を満ãŸã™ã“"
-"ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+"æ–°ã—ã„シーンをä¿å­˜ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ ãŠãらãä¾å­˜é–¢ä¿‚(インスタンス)を満ãŸã›ã¦"
+"ã„ã¾ã›ã‚“。"
#: editor/scene_tree_dock.cpp
msgid "Error saving scene."
@@ -10707,11 +10717,11 @@ msgstr "継承をクリアã—ã¾ã™ã‹? (å…ƒã«æˆ»ã›ã¾ã›ã‚“!)"
#: editor/scene_tree_editor.cpp
msgid "Toggle Visible"
-msgstr "表示ã®åˆ‡ã‚Šæ›¿ãˆ"
+msgstr "表示 / éžè¡¨ç¤ºã®åˆ‡ã‚Šæ›¿ãˆ"
#: editor/scene_tree_editor.cpp
msgid "Unlock Node"
-msgstr "ノードã®ãƒ­ãƒƒã‚¯è§£é™¤"
+msgstr "ノードをロック解除"
#: editor/scene_tree_editor.cpp
msgid "Button Group"
@@ -10839,7 +10849,7 @@ msgstr "エラー - ファイルシステムã«ã‚¹ã‚¯ãƒªãƒ—トを作æˆã§ãã¾
#: editor/script_create_dialog.cpp
msgid "Error loading script from %s"
-msgstr "%s ã‹ã‚‰ã®ã‚¹ã‚¯ãƒªãƒ—トã®èª­ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸ"
+msgstr "%s ã‹ã‚‰ã®ã‚¹ã‚¯ãƒªãƒ—トを読ã¿è¾¼ã¿ä¸­ã«ã‚¨ãƒ©ãƒ¼"
#: editor/script_create_dialog.cpp
msgid "Overrides"
@@ -10851,7 +10861,7 @@ msgstr "N/A"
#: editor/script_create_dialog.cpp
msgid "Open Script / Choose Location"
-msgstr "スクリプトを開ã/å ´æ‰€ã‚’é¸æŠžã™ã‚‹"
+msgstr "スクリプトを開ã / å ´æ‰€ã‚’é¸æŠžã™ã‚‹"
#: editor/script_create_dialog.cpp
msgid "Open Script"
@@ -10867,7 +10877,7 @@ msgstr "無効ãªã‚¯ãƒ©ã‚¹å。"
#: editor/script_create_dialog.cpp
msgid "Invalid inherited parent name or path."
-msgstr "継承ã•れãŸè¦ªã®åå‰ã¾ãŸã¯ãƒ‘スãŒç„¡åйã§ã™ã€‚"
+msgstr "継承ã™ã‚‹è¦ªã®åå‰ã€ã¾ãŸã¯ãƒ‘スãŒç„¡åйã§ã™ã€‚"
#: editor/script_create_dialog.cpp
msgid "Script path/name is valid."
@@ -10898,6 +10908,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"注: 組ã¿è¾¼ã¿ã‚¹ã‚¯ãƒªãƒ—トã«ã¯ã„ãã¤ã‹åˆ¶ç´„ãŒã‚りã€ã¾ãŸå¤–部ã®ã‚¨ãƒ‡ã‚£ã‚¿ã§ã¯ç·¨é›†ã§ã"
+"ã¾ã›ã‚“。"
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11020,6 +11032,10 @@ msgid "Total:"
msgstr "åˆè¨ˆ:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "CSVファイルã«ãƒªã‚¹ãƒˆã‚’エクスãƒãƒ¼ãƒˆ"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "リソースã®ãƒ‘ス(ResourcePath)"
@@ -11061,11 +11077,11 @@ msgstr "数値データをCSVã¨ã—ã¦ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ"
#: editor/settings_config_dialog.cpp
msgid "Erase Shortcut"
-msgstr "ã‚·ãƒ§ãƒ¼ãƒˆã‚«ãƒƒãƒˆã®æ¶ˆåŽ»"
+msgstr "ショートカットを消去"
#: editor/settings_config_dialog.cpp
msgid "Restore Shortcut"
-msgstr "ショートカットã®å¾©å…ƒ"
+msgstr "ショートカットを復元"
#: editor/settings_config_dialog.cpp
msgid "Change Shortcut"
@@ -11768,7 +11784,7 @@ msgstr "グラフを編集ã™ã‚‹é–¢æ•°ã‚’é¸æŠžã¾ãŸã¯ä½œæˆã—ã¾ã™ã€‚"
#: modules/visual_script/visual_script_editor.cpp
msgid "Delete Selected"
-msgstr "é¸æŠžæ¸ˆã¿ã‚’削除"
+msgstr "é¸æŠžå¯¾è±¡ã‚’å‰Šé™¤"
#: modules/visual_script/visual_script_editor.cpp
msgid "Find Node Type"
@@ -11784,11 +11800,11 @@ msgstr "ノードを切りå–ã‚‹"
#: modules/visual_script/visual_script_editor.cpp
msgid "Make Function"
-msgstr "関数ã®ä½œæˆ"
+msgstr "関数を作æˆ"
#: modules/visual_script/visual_script_editor.cpp
msgid "Refresh Graph"
-msgstr "ã‚°ãƒ©ãƒ•ã®æ›´æ–°"
+msgstr "グラフを更新"
#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
@@ -12192,8 +12208,8 @@ msgid ""
"CPUParticles\" option for this purpose."
msgstr ""
"GPUベースã®ãƒ‘ーティクルã¯ã€GLES2ビデオドライãƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。\n"
-"代ã‚りã«CPUParticles2Dノードを使用ã—ã¦ãã ã•ã„。 ã“ã®ç›®çš„ã®ãŸã‚ã« \"Convert "
-"to CPUParticles\" オプションを使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+"代ã‚りã«CPUParticles2Dノードを使用ã—ã¦ãã ã•ã„。ã“ã®ç›®çš„ã®ãŸã‚ã« \"CPUパー"
+"ティクルã«å¤‰æ›\" オプションを使用ã§ãã¾ã™ã€‚"
#: scene/2d/particles_2d.cpp scene/3d/particles.cpp
msgid ""
@@ -12222,9 +12238,9 @@ msgid ""
"by the physics engine when running.\n"
"Change the size in children collision shapes instead."
msgstr ""
-"RigidBody2D(キャラクタモードã¾ãŸã¯ãƒªã‚¸ãƒƒãƒ‰ãƒ¢ãƒ¼ãƒ‰)ã«å¯¾ã™ã‚‹ã‚µã‚¤ã‚ºå¤‰æ›´ã¯ã€å®Ÿè¡Œæ™‚"
-"ã«ç‰©ç†ã‚¨ãƒ³ã‚¸ãƒ³ã«ã‚ˆã£ã¦ã‚ªãƒ¼ãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã•れã¾ã™ã€‚\n"
-"代ã‚りã«ã€å­ã®è¡çªã‚·ã‚§ã‚¤ãƒ—ã®ã‚µã‚¤ã‚ºã‚’変更ã—ã¦ãã ã•ã„。"
+"RigidBody2D (Characterモードã¾ãŸã¯Rigidモード) ã«å¯¾ã™ã‚‹ã‚µã‚¤ã‚ºå¤‰æ›´ã¯ã€å®Ÿè¡Œæ™‚ã«"
+"物ç†ã‚¨ãƒ³ã‚¸ãƒ³ã«ã‚ˆã£ã¦ä¸Šæ›¸ãã•れã¾ã™ã€‚\n"
+"代ã‚りã«ã€å­ã®ã‚³ãƒªã‚¸ãƒ§ãƒ³ シェイプã®ã‚µã‚¤ã‚ºã‚’変更ã—ã¦ãã ã•ã„。"
#: scene/2d/remote_transform_2d.cpp
msgid "Path property must point to a valid Node2D node to work."
@@ -12429,8 +12445,8 @@ msgid ""
"\" option for this purpose."
msgstr ""
"GPUベースã®ãƒ‘ーティクルã¯ã€GLES2ビデオドライãƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。\n"
-"代ã‚りã«CPUParticlesノードを使用ã—ã¦ãã ã•ã„。 ã“ã®ç›®çš„ã®ãŸã‚ã« \"Convert to "
-"CPUParticles\"オプションを使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚"
+"代ã‚りã«CPUParticlesノードを使用ã—ã¦ãã ã•ã„。ã“ã®ç›®çš„ã®ãŸã‚ã« \"CPUパーティ"
+"クルã«å¤‰æ›\" オプションを使用ã§ãã¾ã™ã€‚"
#: scene/3d/particles.cpp
msgid ""
@@ -12678,7 +12694,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
-msgstr ""
+msgstr "レンダーã™ã‚‹ã«ã¯ãƒ“ューãƒãƒ¼ãƒˆã®ã‚µã‚¤ã‚ºãŒ 0 より大ãã„å¿…è¦ãŒã‚りã¾ã™ã€‚"
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/ka.po b/editor/translations/ka.po
index ad4d5072f6..07eeeb5377 100644
--- a/editor/translations/ka.po
+++ b/editor/translations/ka.po
@@ -9824,6 +9824,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10933,6 +10940,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index dd2d617eb8..f25550709a 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -16,12 +16,13 @@
# Jiyoon Kim <kimjiy@dickinson.edu>, 2019.
# Ervin <zetsmart@gmail.com>, 2019.
# Tilto_ <tilto0822@develable.xyz>, 2020.
+# Myeongjin Lee <aranet100@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-27 07:42+0000\n"
-"Last-Translator: Tilto_ <tilto0822@develable.xyz>\n"
+"PO-Revision-Date: 2020-05-01 11:42+0000\n"
+"Last-Translator: Ch. <ccwpc@hanmail.net>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/"
"godot/ko/>\n"
"Language: ko\n"
@@ -29,7 +30,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.2\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2924,13 +2925,12 @@ msgid "Q&A"
msgstr "Q&A"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "다시 가져오기"
+msgstr "버그 보고"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "문서 피드백 보내기"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3976,7 +3976,6 @@ msgid "Reimport"
msgstr "다시 가져오기"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
msgstr "씬 저장, 다시 가져오기 ë° ë‹¤ì‹œ 시작"
@@ -5930,7 +5929,7 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Single Convex Collision Sibling"
-msgstr "개별 Convex ì¶©ëŒ í˜•ì œ 만들기"
+msgstr "ë‹¨ì¼ Convex ì¶©ëŒ í˜•ì œ 만들기"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -7250,9 +7249,8 @@ msgid "This operation requires a single selected node."
msgstr "ì´ ìž‘ì—…ì€ í•˜ë‚˜ì˜ ë…¸ë“œë¥¼ ì„ íƒí•´ì•¼ 합니다."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "ì§êµë³´ê¸°"
+msgstr "ìžë™ ì§êµ 활성화"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -9834,6 +9832,16 @@ msgstr ""
"현재 프로ì íŠ¸ê°€ í•˜ë‚˜ë„ ì—†ìŠµë‹ˆë‹¤.\n"
"ì• ì…‹ ë¼ì´ë¸ŒëŸ¬ë¦¬ì—서 ê³µì‹ ì˜ˆì œ 프로ì íŠ¸ë¥¼ 찾아볼까요?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"ì´ ê²€ìƒ‰ì°½ì€ í”„ë¡œì íŠ¸ë¥¼ ì´ë¦„ê³¼ ê²½ë¡œì˜ ë§ˆì§€ë§‰ 부분으로 거릅니다.\n"
+"프로ì íŠ¸ë¥¼ ì „ì²´ 경로를 기준으로 걸러내려면 ê²€ìƒ‰ì–´ì— `/` ê°€ 한 ê¸€ìž ì´ìƒ í¬í•¨"
+"시키세요."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "키 "
@@ -10820,6 +10828,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"참고: 내장 스í¬ë¦½íЏì—는 ì¼ë¶€ 제한 ì‚¬í•­ì´ ìžˆìœ¼ë©° 외부 편집기를 사용하여 편집"
+"할 수 없습니다."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -10942,6 +10952,10 @@ msgid "Total:"
msgstr "ì „ì²´:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "목ë¡ì„ CSV 파ì¼ë¡œ 내보내기"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "리소스 경로"
@@ -12572,7 +12586,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
-msgstr ""
+msgstr "무엇ì´ë“  ë Œë”ë§í•˜ë ¤ë©´ ë·°í¬íЏ í¬ê¸°ê°€ 0보다 커야 합니다."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index 25cec6842f..57c377b571 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -9811,6 +9811,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10917,6 +10924,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Importuoti iš Nodo:"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/lv.po b/editor/translations/lv.po
index 973e732e2d..642050468b 100644
--- a/editor/translations/lv.po
+++ b/editor/translations/lv.po
@@ -9778,6 +9778,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10884,6 +10891,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/mi.po b/editor/translations/mi.po
index f0b661e381..5c33f2e72e 100644
--- a/editor/translations/mi.po
+++ b/editor/translations/mi.po
@@ -9499,6 +9499,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10580,6 +10587,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/ml.po b/editor/translations/ml.po
index 92ffb6f097..e46fd5a10d 100644
--- a/editor/translations/ml.po
+++ b/editor/translations/ml.po
@@ -9515,6 +9515,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10596,6 +10603,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/mr.po b/editor/translations/mr.po
index f368062a85..902c243d16 100644
--- a/editor/translations/mr.po
+++ b/editor/translations/mr.po
@@ -3,41 +3,42 @@
# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
# Prachi Joshi <josprachi@yahoo.com>, 2019, 2020.
+# Shirious <sad3119823@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
-"PO-Revision-Date: 2020-01-30 03:56+0000\n"
-"Last-Translator: Prachi Joshi <josprachi@yahoo.com>\n"
+"PO-Revision-Date: 2020-05-05 14:01+0000\n"
+"Last-Translator: Shirious <sad3119823@gmail.com>\n"
"Language-Team: Marathi <https://hosted.weblate.org/projects/godot-engine/"
"godot/mr/>\n"
"Language: mr\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8-bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 3.11-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr ""
+msgstr "convert() साठी अवैध आरगà¥à¤¯à¥à¤®à¥‡à¤¨à¥à¤Ÿ, TYPE_* कोनà¥à¤¸à¤Ÿà¤¨à¥à¤Ÿ वापरा."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr ""
+msgstr "1 लांबीची सà¥à¤Ÿà¥à¤°à¤¿à¤‚ग अपेकà¥à¤·à¤¿à¤¤ (à¤à¤• कैरेकà¥à¤Ÿà¤°)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr ""
+msgstr "डिकोड करणà¥à¤¯à¤¾à¤¸à¤¾à¤ à¥€ पà¥à¤°à¤¸à¥‡ बाईटसॠनाहित, किंवा अवैध फ़ोरमैट."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr ""
+msgstr "à¤à¤•à¥à¤¸à¤ªà¥à¤°à¥‡à¤¶à¤¨ मधे अवैध इनपà¥à¤Ÿ %i (पास नाही à¤à¤¾à¤²à¥‡)"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr ""
+msgstr "self वापरले जाऊ शकत नाही कारण इनà¥à¤¸à¤Ÿà¤¨à¥à¤¸ null आहे (पास नाही à¤à¤¾à¤²à¥‡)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -1928,9 +1929,8 @@ msgid "Property Descriptions"
msgstr ""
#: editor/editor_help.cpp
-#, fuzzy
msgid "(value)"
-msgstr "मूलà¥à¤¯:"
+msgstr "(किंमत)"
#: editor/editor_help.cpp
msgid ""
@@ -9506,6 +9506,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10587,6 +10594,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index dc18540ce3..09e2bcc096 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -9572,6 +9572,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10657,6 +10664,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index 6ec911db7d..34d6e9dc76 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -10351,6 +10351,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -11509,6 +11516,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Eksporter Prosjekt"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index d270e51f6f..93219f8bfc 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -4,7 +4,7 @@
# This file is distributed under the same license as the Godot source code.
# aelspire <aelspire@gmail.com>, 2017.
# Aram Nap <xyphex.aram@gmail.com>, 2017.
-# Arjan219 <arjannugteren1@gmail.com>, 2017-2018.
+# Arjan219 <arjannugteren1@gmail.com>, 2017-2018, 2020.
# Christophe Swolfs <swolfschristophe@gmail.com>, 2017.
# Cornee Traas <corneetraas@hotmail.com>, 2017.
# Daeran Wereld <daeran@gmail.com>, 2017.
@@ -40,12 +40,11 @@
# Tirrin <lensenjoe@gmail.com>, 2019.
# Filip Van Raemdonck <arrawn@gmail.com>, 2019.
# Julian <jdhoogvorst@gmail.com>, 2019, 2020.
-# anonymous <noreply@weblate.org>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-04-15 14:29+0000\n"
+"PO-Revision-Date: 2020-05-04 15:12+0000\n"
"Last-Translator: Stijn Hinlopen <f.a.hinlopen@gmail.com>\n"
"Language-Team: Dutch <https://hosted.weblate.org/projects/godot-engine/godot/"
"nl/>\n"
@@ -54,7 +53,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -69,7 +68,7 @@ msgstr "Tekenreeks met lengte 1 verwacht (één karakter)."
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr "Niet genoeg bytes om bytes te decoderen, of ongeldig formaat."
+msgstr "Niet genoeg bytes om te decoderen, of ongeldig formaat."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
@@ -662,7 +661,7 @@ msgstr "Alle animaties opruimen"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation(s) (NO UNDO!)"
-msgstr "Animatie(s) Opruimen (KAN NIET ONGEDAAN WORDEN!)"
+msgstr "Animatie(s) opruimen (ONOMKEERBAAR!)"
#: editor/animation_track_editor.cpp
msgid "Clean-Up"
@@ -695,11 +694,11 @@ msgstr "Voeg audiospoor clip toe"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
-msgstr "Wijzig start afwijking van audiospoorclip"
+msgstr "Wijzig startverschuiving van audiospoorclip"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip End Offset"
-msgstr "Wijzig eind afwijking van audiospoorclip"
+msgstr "Wijzig eindverschuiving van audiospoorclip"
#: editor/array_property_edit.cpp
msgid "Resize Array"
@@ -723,7 +722,7 @@ msgstr "Regelnummer:"
#: editor/code_editor.cpp
msgid "%d replaced."
-msgstr "%d vervangen."
+msgstr "%d vervangingen."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
@@ -747,7 +746,7 @@ msgstr "Vervangen"
#: editor/code_editor.cpp
msgid "Replace All"
-msgstr "Alle Vervangen"
+msgstr "Alles vervangen"
#: editor/code_editor.cpp
msgid "Selection Only"
@@ -1071,7 +1070,7 @@ msgid ""
msgstr ""
"De bestanden die verwijderd worden zijn nodig om andere bronnen te laten "
"werken.\n"
-"Toch verwijderen? (Kan niet ongedaan worden)"
+"Toch verwijderen? (Onomkeerbaar)"
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1103,7 +1102,7 @@ msgstr "Fouten bij het laden!"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
-msgstr "%d bestand(en) voorgoed verwijderen? (Kan niet ongedaan worden!)"
+msgstr "%d bestand(en) voorgoed verwijderen? (Onomkeerbaar!)"
#: editor/dependency_editor.cpp
msgid "Show Dependencies"
@@ -1606,7 +1605,7 @@ msgid ""
"'Import Etc 2' in Project Settings."
msgstr ""
"Doelplatform vereist 'ETC2' textuurcompressie voor GLES3. Schakel 'Import "
-"Etc 2' in bij de Projectinstellingen."
+"Etc 2' in de Projectinstellingen in."
#: editor/editor_export.cpp
msgid ""
@@ -1670,7 +1669,7 @@ msgstr "Bestandssysteem- en Importtablad"
#: editor/editor_feature_profile.cpp
msgid "Erase profile '%s'? (no undo)"
-msgstr "Profiel '%s' verwijderen? (kan niet ongedaan gemaakt worden)"
+msgstr "Profiel '%s' verwijderen? (Onomkeerbaar)"
#: editor/editor_feature_profile.cpp
msgid "Profile must be a valid filename and must not contain '.'"
@@ -2024,8 +2023,8 @@ msgid ""
"There is currently no description for this property. Please help us by "
"[color=$color][url=$url]contributing one[/url][/color]!"
msgstr ""
-"Er is momenteel geen beschrijving voor deze eigenschap. Help ons alsjeblieft "
-"door [color=$color][url=$url]een toe te voegen[/url][/color]!"
+"Er is momenteel geen beschrijving voor deze eigenschap. Help ons alstublieft "
+"door [color=$color][url=$url]een bijdrage te leveren[/url][/color]!"
#: editor/editor_help.cpp
msgid "Method Descriptions"
@@ -2036,8 +2035,8 @@ msgid ""
"There is currently no description for this method. Please help us by [color="
"$color][url=$url]contributing one[/url][/color]!"
msgstr ""
-"Er is momenteel geen beschrijving voor deze methode. Help ons alsjeblieft "
-"door [color=$color][url=$url]een toe te voegen[/url][/color]!"
+"Er is momenteel geen beschrijving voor deze methode. Help ons alstublieft "
+"door [color=$color][url=$url]een bijdrage te leveren[/url][/color]!"
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -2387,7 +2386,7 @@ msgstr "Basisscène openen"
#: editor/editor_node.cpp
msgid "Quick Open..."
-msgstr "Snel Openen..."
+msgstr "Snel openen..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
@@ -2395,7 +2394,7 @@ msgstr "Scène snel openen..."
#: editor/editor_node.cpp
msgid "Quick Open Script..."
-msgstr "Open Script Snel..."
+msgstr "Script snel openen..."
#: editor/editor_node.cpp
msgid "Save & Close"
@@ -2464,7 +2463,8 @@ msgstr "Herstellen"
#: editor/editor_node.cpp
msgid "This action cannot be undone. Revert anyway?"
-msgstr "Deze actie kan niet ongedaan gemaakt worden. Toch herstellen?"
+msgstr ""
+"Deze actie kan niet ongedaan gemaakt worden. WIlt u desondanks terugzetten?"
#: editor/editor_node.cpp
msgid "Quick Run Scene..."
@@ -2500,8 +2500,8 @@ msgid ""
"This option is deprecated. Situations where refresh must be forced are now "
"considered a bug. Please report."
msgstr ""
-"Deze optie is verouderd. Situaties waar een hernieuwing geforceerd moet "
-"worden zijn softwarefouten. Rapporteer dit alsjeblieft."
+"Deze optie is verouderd. Situaties waarbij gedwongen herladen moet worden, "
+"worden gezien als softwarefouten. Rapporteer dit alstublieft."
#: editor/editor_node.cpp
msgid "Pick a Main Scene"
@@ -2730,7 +2730,7 @@ msgstr "Alle scènes opslaan"
#: editor/editor_node.cpp
msgid "Convert To..."
-msgstr "Converteer Naar..."
+msgstr "Omzetten naar..."
#: editor/editor_node.cpp
msgid "MeshLibrary..."
@@ -2743,7 +2743,7 @@ msgstr "TileSet..."
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Undo"
-msgstr "Ongedaan Maken"
+msgstr "Ongedaan maken"
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
@@ -2797,7 +2797,7 @@ msgstr "Hulpmiddelen"
#: editor/editor_node.cpp
msgid "Orphan Resource Explorer..."
-msgstr "Verweesde hulpbronnen verkenner..."
+msgstr "Beheer ongebruikte bronnen..."
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2918,7 +2918,7 @@ msgstr "Schermafbeeldingen worden bewaard in de map \"Editor Data/Settings\"."
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
-msgstr "Schakel Volledig Scherm"
+msgstr "Volledig scherm"
#: editor/editor_node.cpp
msgid "Toggle System Console"
@@ -2967,13 +2967,12 @@ msgid "Q&A"
msgstr "Vragen en antwoorden"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Opnieuw importeren"
+msgstr "Meld een probleem"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Suggesties voor documentatie verzenden"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3683,7 +3682,7 @@ msgstr "Naam bevat ongeldige tekens."
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
-msgstr "Bestandsnaam wijzigen:"
+msgstr "Bestand hernoemen:"
#: editor/filesystem_dock.cpp
msgid "Renaming folder:"
@@ -3865,7 +3864,7 @@ msgstr "Vervangen: "
#: editor/find_in_files.cpp
msgid "Replace all (no undo)"
-msgstr "Alle vervangen (geen ongedaan maken)"
+msgstr "Alles vervangen (onomkeerbaar)"
#: editor/find_in_files.cpp
msgid "Searching..."
@@ -4030,9 +4029,8 @@ msgid "Reimport"
msgstr "Opnieuw importeren"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
-msgstr "Opnieuw importeren en herstarten (alle scènes worden opgeslagen)"
+msgstr "Sla scènes op, importeer opnieuw en start dan opnieuw op"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -4082,7 +4080,7 @@ msgstr "Integreer"
#: editor/inspector_dock.cpp
msgid "Make Sub-Resources Unique"
-msgstr "Maak Onderliggende Bronnen Uniek"
+msgstr "Onderliggende bronnen zelfstandig maken"
#: editor/inspector_dock.cpp
msgid "Open in Help"
@@ -5892,7 +5890,7 @@ msgstr "Mesh is leeg!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Couldn't create a Trimesh collision shape."
-msgstr "Kon geen Trimesh-botsingsvorm maken."
+msgstr "Kan geen Trimesh-botsingsvorm maken."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Static Trimesh Body"
@@ -5900,7 +5898,7 @@ msgstr "Creëer een statisch tri-mesh lichaam"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "This doesn't work on scene root!"
-msgstr "Dit werkt niet op scènewortel!"
+msgstr "Dit werkt niet op de scènewortel!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Shape"
@@ -6988,7 +6986,7 @@ msgstr "Kies Kleur"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Convert Case"
-msgstr "Converteer Hoofdlettergebruik"
+msgstr "Letters omzetten"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Uppercase"
@@ -7000,7 +6998,7 @@ msgstr "Kleine letters"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Capitalize"
-msgstr "Maak Hoofdletters"
+msgstr "Elk Woord Met Hoofdletter"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Syntax Highlighter"
@@ -7076,15 +7074,15 @@ msgstr "Trim Navolgende Spaties"
#: editor/plugins/script_text_editor.cpp
msgid "Convert Indent to Spaces"
-msgstr "Converteer Indentatie Naar Spaties"
+msgstr "Insprong in spaties omzetten"
#: editor/plugins/script_text_editor.cpp
msgid "Convert Indent to Tabs"
-msgstr "Converteer Indentatie Naar Tabs"
+msgstr "Insprong in Tabs omzetten"
#: editor/plugins/script_text_editor.cpp
msgid "Auto Indent"
-msgstr "Auto Indentatie"
+msgstr "Automatisch inspringen"
#: editor/plugins/script_text_editor.cpp
msgid "Find in Files..."
@@ -7328,9 +7326,8 @@ msgid "This operation requires a single selected node."
msgstr "Deze bewerking vereist één geselecteerde knoop."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Orthogonaal"
+msgstr "Auto-orthogonaal ingeschakeld"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -7583,7 +7580,7 @@ msgstr "Beeldvensterinstellingen"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective FOV (deg.):"
-msgstr "Perspectief FOV (grad.):"
+msgstr "Gezichtsveld (graden):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Z-Near:"
@@ -7681,7 +7678,7 @@ msgstr "Ongeldige geometrie, kan geen polygon creëren."
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Convert to Polygon2D"
-msgstr "Converteer naar Polygon2D"
+msgstr "Naar Polygon2D omzetten"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create collision polygon."
@@ -7874,7 +7871,7 @@ msgstr "Stap:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Sep.:"
-msgstr "Separatie:"
+msgstr "Scheiding:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "TextureRegion"
@@ -9819,8 +9816,8 @@ msgstr ""
"\n"
"%s\n"
"\n"
-"Als je doorgaat met het openen van dit bestand, zal het worden geconverteerd "
-"naar Godot's huidige format voor project-configuratiebestanden.\n"
+"Als je doorgaat met het openen van dit bestand, zal het worden omgezet naar "
+"Godot's huidige formaat voor project-configuratiebestanden.\n"
"Waarschuwing: Hierna kan het project niet meer worden geopend door oudere "
"versies van Godot Engine."
@@ -9963,6 +9960,17 @@ msgstr ""
"U heeft momenteel geen projecten.\n"
"Wilt u de officiële voorbeeldprojecten verkennen in de Asset Library?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"De zoekbalk filtert projecten op naam en naam van de map waarin het project "
+"staat.\n"
+"Om ook op het volledige pad te filteren, moet de zoekopdracht tenminste één "
+"`/` karakter bevatten."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Toets "
@@ -10702,7 +10710,7 @@ msgstr "Knoop hieronder toevoegen"
#: editor/scene_tree_dock.cpp
msgid "Expand/Collapse All"
-msgstr "Alles uit-/inklappen"
+msgstr "Alles in-/uitklappen"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
@@ -10714,7 +10722,7 @@ msgstr "Onder nieuwe knoop hangen"
#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
-msgstr "Scènewortel instellen"
+msgstr "Als scènewortel instellen"
#: editor/scene_tree_dock.cpp
msgid "Merge From Scene"
@@ -10957,6 +10965,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Merk op: Ingebouwde scripten zijn onderhevig aan bepaalde beperkingen en "
+"kunnen niet in een externe editor bewerkt worden."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11079,6 +11089,10 @@ msgid "Total:"
msgstr "Totaal:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "Exporteer lijst naar een csv-bestand"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Bronpad"
@@ -12197,9 +12211,7 @@ msgstr ""
msgid ""
"A shape must be provided for CollisionShape2D to function. Please create a "
"shape resource for it!"
-msgstr ""
-"Een vorm moet voorzien worden om CollisionShape2D te laten functioneren. "
-"Creëer hiervoor alsjeblieft een vorm resource!"
+msgstr "Een CollisionShape2D heeft een vorm nodig in de Shape-eigenschap!"
#: scene/2d/cpu_particles_2d.cpp
msgid ""
@@ -12227,7 +12239,7 @@ msgstr ""
#: scene/2d/light_occluder_2d.cpp
msgid "The occluder polygon for this occluder is empty. Please draw a polygon."
msgstr ""
-"De occluder polygoon van deze occluder is leeg. Teken alsjeblieft een "
+"De occluder-polygoon van deze occluder is leeg. Teken alstublieft een "
"polygoon."
#: scene/2d/navigation_polygon.cpp
@@ -12692,7 +12704,7 @@ msgstr "Alarm!"
#: scene/gui/dialogs.cpp
msgid "Please Confirm..."
-msgstr "Bevestig alsjeblieft..."
+msgstr "Bevestig alstublieft..."
#: scene/gui/popup.cpp
msgid ""
@@ -12745,6 +12757,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
+"De grootte van een Viewport moet groter zijn dan 0 om iets weer te geven."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/or.po b/editor/translations/or.po
index 1858bad087..2ce05efe5d 100644
--- a/editor/translations/or.po
+++ b/editor/translations/or.po
@@ -9505,6 +9505,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10586,6 +10593,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index eb40e7ecaa..a7b57f31ba 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -42,7 +42,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-26 05:19+0000\n"
+"PO-Revision-Date: 2020-05-01 11:42+0000\n"
"Last-Translator: Tomek <kobewi4e@gmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/"
"godot/pl/>\n"
@@ -52,7 +52,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.2\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2952,13 +2952,12 @@ msgid "Q&A"
msgstr "Pytania i odpowiedzi"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Importuj ponownie"
+msgstr "Zgłoś błąd"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Wyślij opinię o dokumentacji"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4013,9 +4012,8 @@ msgid "Reimport"
msgstr "Importuj ponownie"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
-msgstr "Zapisz sceny, re-importuj i zrestartuj"
+msgstr "Zapisz sceny, reimportuj i uruchom ponownie"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -5401,7 +5399,7 @@ msgstr "Alt+Przeciągnij: Przesuń"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)."
msgstr ""
-"Wciśnij \"v\" by zmienić punkt zaczepienia (pivot), \"Shift+v\" by przesunąć "
+"Wciśnij \"V\" by zmienić punkt zaczepienia (pivot), \"Shift+V\" by przesunąć "
"punkt zaczepienia (podczas poruszania)."
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -7309,9 +7307,8 @@ msgid "This operation requires a single selected node."
msgstr "Ta operacja wymaga pojedynczego wybranego węzła."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Ortogonalna"
+msgstr "Automatyczna ortogonalizacja włączona"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -9930,6 +9927,17 @@ msgstr ""
"Nie posiadasz obecnie żadnych projektów.\n"
"Czy chcesz zobaczyć oficjalne przykładowe projekty w Bibliotece Zasobów?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"Pasek wyszukiwania filtruje projekty po nazwie i ostatnim komponencie "
+"ścieżki.\n"
+"By filtrować po nazwie i pełnej ścieżce, zapytanie musi zawierać "
+"przynajmniej jeden znak \"/\"."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Klawisz "
@@ -10921,6 +10929,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Uwaga: wbudowane skrypty posiadają pewne ograniczenia i nie mogą być "
+"edytowane przy użyciu zewnętrznego edytora."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11043,6 +11053,10 @@ msgid "Total:"
msgstr "Całkowity:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "Eksportuj listÄ™ do pliku CSV"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Ścieżka zasobu"
@@ -12708,7 +12722,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
-msgstr ""
+msgstr "Rozmiar węzła Viewport musi być większy niż 0, by coś wyrenderować."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index 70a061783c..646d14c2cf 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -9829,6 +9829,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10948,6 +10955,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index 82bd304311..d38c4186c7 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -12,7 +12,7 @@
# Guilherme Felipe C G Silva <guilhermefelipecgs@gmail.com>, 2017, 2018, 2019.
# João Victor Lima <victordevtb@outlook.com>, 2018.
# João Vitor de Oliveira Carlos <lopogax@gmail.com>, 2018.
-# Joaquim Ferreira <joaquimferreira1996@bol.com.br>, 2016, 2019.
+# Joaquim Ferreira <joaquimferreira1996@bol.com.br>, 2016, 2019, 2020.
# jonathan railarem <railarem@gmail.com>, 2017.
# Lucas Silva <lucasb.hpp@gmail.com>, 2018.
# Luiz G. Correia <luizgabriell2.0@gmail.com>, 2017.
@@ -28,7 +28,7 @@
# Michel G. Souza <Michelgomesdes@hotmail.com>, 2018.
# Caio Northfleet <caio.northfleet@gmail.com>, 2018.
# Henrique Combochi <henrique.combochi@gmail.com>, 2018, 2019.
-# Gabriel Carvalho <billlmaster@gmail.com>, 2018, 2019.
+# Gabriel Carvalho <billlmaster@gmail.com>, 2018, 2019, 2020.
# miketangogamer <miketangogamer@gmail.com>, 2018.
# Eduardo Abreu <eduo.abreu@gmail.com>, 2018, 2019.
# Bruno Miranda Da Silva <brunofreezee@gmail.com>, 2018.
@@ -74,7 +74,7 @@
# Rafael Silveira <res883@gmail.com>, 2019.
# Luigi <luigimendeszanchett@gmail.com>, 2019.
# Nicolas Abril <nicolas.abril@protonmail.ch>, 2019.
-# johnnybigoode <jamarson@gmail.com>, 2019.
+# johnnybigoode <jamarson@gmail.com>, 2019, 2020.
# Zeero <igcdzeero@gmail.com>, 2019.
# Gian Penna <gianfrancopen@gmail.com>, 2020.
# sribgui <sribgui@gmail.com>, 2020.
@@ -82,15 +82,18 @@
# Michael Leocádio <aeronmike@gmail.com>, 2020.
# Z <rainromes@gmail.com>, 2020.
# Leonardo Dimano <leodimano@live.com>, 2020.
-# anonymous <noreply@weblate.org>, 2020.
# Guilherme Souza Reis de Melo Lopes <gsrmlopes@gmail.com>, 2020.
# Richard Urban <redasuio1@gmail.com>, 2020.
+# Wellyngton R Weller <well.weller@hotmail.com>, 2020.
+# Lucas Araujo <lucassants2808@gmail.com>, 2020.
+# Sr Half <flavio05@outlook.com>, 2020.
+# Matheus Pesegoginski <pese.ek.tk@outlook.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2020-04-16 11:03+0000\n"
-"Last-Translator: Richard Urban <redasuio1@gmail.com>\n"
+"PO-Revision-Date: 2020-05-04 15:12+0000\n"
+"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_BR/>\n"
"Language: pt_BR\n"
@@ -98,16 +101,16 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.0.1-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr "Argumento de tipo inválido para converter(), use TYPE_* constantes."
+msgstr "Tipo de argumento inválido para converter(), use TYPE_* constantes."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr "Esperado uma string de comprimento 1 (um caractere)."
+msgstr "Esperado uma corda de comprimento 1 (um caractere)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -735,11 +738,11 @@ msgstr "Selecionar Todos/Nenhum"
#: editor/animation_track_editor_plugins.cpp
msgid "Add Audio Track Clip"
-msgstr "Adicionar Amostra de uma Trilha de Ãudio"
+msgstr "Adicionar Clipe de Trilha de Ãudio"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
-msgstr "Mudar Deslocamento de Início da Amostra da Trilha de Ãudio"
+msgstr "Mudar Deslocamento do Início do Clip de Trilha de Audio"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip End Offset"
@@ -3006,13 +3009,12 @@ msgid "Q&A"
msgstr "Perguntas & Respostas"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Reimportar"
+msgstr "Reportar bug"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Enviar Feedback de Docs"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3123,14 +3125,13 @@ msgid ""
"the \"Use Custom Build\" option should be enabled in the Android export "
"preset."
msgstr ""
-"Isso irá configurar seu projeto para compilações customizadas do Android "
-"instalando o template raíz em \"res://android/build\".\n"
-"Em seguida, você pode aplicar modificações e compilar seu próprio APK "
-"customizado na exportação (adicionando módulos, alterando o AndroidManifest."
-"xml, etc.).\n"
-"Note que para fazer uma compilação customizada em vez de usar APKs pre-"
-"compilados, a opção \"Usar compilação customizada\" deve estar ativa nas "
-"predefinições de exportação do Android."
+"Isso vai configurar seu projeto para construções customizadas do Android, "
+"instalando o modelo de fonte para \"res://android/build\".\n"
+"Você pode então aplicar modificações e construir seu próprio APK na guia "
+"Exportação (Adicionando módulos, trocando o AndroidManifest.xml, etc.).\n"
+"Note que para fazer uma construção customizada, em vez de usar APKs pre-"
+"construídos, a opção \"Usar Construção Customizada\" deve estar ativa nas "
+"predefinições de exportação Android."
#: editor/editor_node.cpp
msgid ""
@@ -3662,7 +3663,7 @@ msgstr "Selecionar o Arquivo de Modelo"
#: editor/export_template_manager.cpp
msgid "Godot Export Templates"
-msgstr "Modelos de Exportação do Godot"
+msgstr "Modelos de Exportação"
#: editor/export_template_manager.cpp
msgid "Export Template Manager"
@@ -4071,7 +4072,6 @@ msgid "Reimport"
msgstr "Reimportar"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
msgstr "Salvar cenas, reimportar e reiniciar"
@@ -4338,7 +4338,7 @@ msgstr "Abrir Editor"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Open Animation Node"
-msgstr "Abrir Nó de Animação"
+msgstr "Abrir Animação de Nós"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Triangle already exists."
@@ -5065,7 +5065,7 @@ msgstr "Download deste asset já está em progresso!"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Recently Updated"
-msgstr "Atualizado recentemente"
+msgstr "Atualizado Recentemente"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Least Recently Updated"
@@ -5274,7 +5274,7 @@ msgid ""
"Children of containers have their anchors and margins values overridden by "
"their parent."
msgstr ""
-"Filhos de contêineres tem suas posições e margens sobrescritos pelos seus "
+"Filhos de contêineres tem suas posições e tamanhos sobrescritos pelos seus "
"pais."
#: editor/plugins/canvas_item_editor_plugin.cpp
@@ -5328,27 +5328,27 @@ msgstr "Centro"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Left Wide"
-msgstr "Esquerda Largo"
+msgstr "Largura Esquerda"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Top Wide"
-msgstr "Superior Largo"
+msgstr "Largura Superior"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Right Wide"
-msgstr "Direita Largo"
+msgstr "Largura Direita"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Bottom Wide"
-msgstr "Inferior Largo"
+msgstr "Largura inferior"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "VCenter Wide"
-msgstr "Centro Vertical Largo"
+msgstr "Largura Centro Vertical"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "HCenter Wide"
-msgstr "Centro Horizontal Largo"
+msgstr "Largura Centro Horizontal"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Full Rect"
@@ -5376,8 +5376,8 @@ msgid ""
"Game Camera Override\n"
"Overrides game camera with editor viewport camera."
msgstr ""
-"Substituir Câmera do Jogo\n"
-"Substitui a câmera do jogo com a câmera de visualização do editor."
+"Sobrepor câmera de Jogo\n"
+"Sobrepõe a câmera de jogo com a janela de exibição da câmera."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5385,8 +5385,8 @@ msgid ""
"Game Camera Override\n"
"No game instance running."
msgstr ""
-"Substituir Câmera do Jogo\n"
-"Nenhuma instância de jogo em execução."
+"Sobrepor câmera de Jogo\n"
+"Sem instancia de jogo rodando."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5657,11 +5657,11 @@ msgstr "Visualizar Canvas Scale"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Translation mask for inserting keys."
-msgstr "Máscara de Translação para inserir chaves."
+msgstr "Máscara de tradução para inserção de chaves"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation mask for inserting keys."
-msgstr "Máscara de Rotação para inserir chaves."
+msgstr "Mascara de rotação para inserção de chaves."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Scale mask for inserting keys."
@@ -6046,7 +6046,7 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Single Convex Collision Sibling"
-msgstr "Criar Simples Colisão Convexa Irmã(s)"
+msgstr "Criar um irmão de Colisão Convexa"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -7370,9 +7370,8 @@ msgid "This operation requires a single selected node."
msgstr "Essa operação requer um único nó selecionado."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Ortogonal"
+msgstr "Auto-Ortogonal Habilitado"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -7692,7 +7691,7 @@ msgstr "Visualizar Polígono De Colisão 2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create LightOccluder2D"
-msgstr "Criar LightOccluder2D"
+msgstr "Criar Polígono de Oclusão (LightOccluder2D)"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "LightOccluder2D Preview"
@@ -7733,7 +7732,7 @@ msgstr "Criar PolígonoDeColisão2D Irmão"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create light occluder."
-msgstr "Geometria inválida, não é possível criar oclusor de luz."
+msgstr "Geometria inválida, não é possível criar o oclusor de luz."
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Create LightOccluder2D Sibling"
@@ -8148,11 +8147,11 @@ msgstr "Pegar Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rotate Left"
-msgstr "Girar à esquerda"
+msgstr "Girar à Esquerda"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rotate Right"
-msgstr "Girar à direita"
+msgstr "Girar à Direita"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Horizontally"
@@ -9988,6 +9987,17 @@ msgstr ""
"Você não tem nenhum projeto no momento.\n"
"Gostaria de explorar projetos de exemplo oficiais na Asset Library?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"A caixa de busca filtra projetos por nome e pelo último componente do "
+"caminho.\n"
+"Para filtrar projetos por nome e pelo caminho completo, a consulta deve "
+"conter pelo menos um caractere `/`."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Chave "
@@ -10979,6 +10989,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Nota: Os scripts internos têm algumas limitações e não podem ser editados "
+"usando um editor externo."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11101,6 +11113,10 @@ msgid "Total:"
msgstr "Total:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "Exportar lista para arquivo CSV"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Caminho do Recurso"
@@ -12765,6 +12781,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
+"O tamanho da viewport deve ser maior do que 0 para renderizar qualquer coisa."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po
index f3b1014123..6314d31908 100644
--- a/editor/translations/pt_PT.po
+++ b/editor/translations/pt_PT.po
@@ -20,8 +20,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-04-07 13:38+0000\n"
-"Last-Translator: Manuela Silva <mmsrs@sky.com>\n"
+"PO-Revision-Date: 2020-05-01 11:42+0000\n"
+"Last-Translator: João Lopes <linux-man@hotmail.com>\n"
"Language-Team: Portuguese (Portugal) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_PT/>\n"
"Language: pt_PT\n"
@@ -29,7 +29,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.2\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -1473,7 +1473,7 @@ msgstr "O Ficheiro não existe."
#: editor/editor_autoload_settings.cpp
msgid "Not in resource path."
-msgstr "Não está no Caminho do recurso."
+msgstr "Não está no caminho do recurso."
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
@@ -2474,7 +2474,7 @@ msgid ""
"considered a bug. Please report."
msgstr ""
"Esta opção foi descontinuada. Situações onde a atualização tem que ser "
-"forçada, são agora consideras um defeito. Por favor, reporte."
+"forçada, são agora consideras um defeito. Por favor, denuncie."
#: editor/editor_node.cpp
msgid "Pick a Main Scene"
@@ -2498,27 +2498,27 @@ msgstr "Incapaz de localizar campo Script para plugin em: 'res://addons/%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
-msgstr "Incapaz de carregar Script addon do Caminho: '%s'."
+msgstr "Incapaz de carregar script addon do caminho: '%s'."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
msgstr ""
-"Incapaz de carregar Script addon do caminho: '%s' Parece haver um erro no "
+"Incapaz de carregar script addon do caminho: '%s' Parece haver um erro no "
"código, reveja a sintaxe."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
msgstr ""
-"Incapaz de carregar Script addon do Caminho: '%s' Tipo base não é "
+"Incapaz de carregar script addon do Caminho: '%s' Tipo base não é "
"EditorPlugin."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
msgstr ""
-"Incapaz de carregar Script addon do Caminho: '%s' Script não está no modo "
+"Incapaz de carregar script addon do Caminho: '%s' Script não está no modo "
"ferramenta."
#: editor/editor_node.cpp
@@ -2940,13 +2940,12 @@ msgid "Q&A"
msgstr "Perguntas & Respostas"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Reimportar"
+msgstr "Denunciar um Bug"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Enviar Sugestão dos Docs"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3278,7 +3277,7 @@ msgstr ""
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Pick a Viewport"
-msgstr "Escolha uma Vista"
+msgstr "Escolha um Viewport"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New Script"
@@ -3316,7 +3315,7 @@ msgstr "Converter em %s"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Selected node is not a Viewport!"
-msgstr "Nó selecionado não é uma Vista!"
+msgstr "Nó selecionado não é um Viewport!"
#: editor/editor_properties_array_dict.cpp
msgid "Size: "
@@ -3444,7 +3443,7 @@ msgstr "Não foi encontrado version.txt dentro dos Modelos."
#: editor/export_template_manager.cpp
msgid "Error creating path for templates:"
-msgstr "Erro ao criar o Caminho para os Modelos:"
+msgstr "Erro ao criar o caminho para os modelos:"
#: editor/export_template_manager.cpp
msgid "Extracting Export Templates"
@@ -3461,7 +3460,7 @@ msgstr "Erro na receção da lista de mirrors."
#: editor/export_template_manager.cpp
msgid "Error parsing JSON of mirror list. Please report this issue!"
msgstr ""
-"Erro ao analisar a lista de mirrors JSON. Por favor comunique o problema!"
+"Erro ao analisar a lista de mirrors JSON. Por favor denuncie o problema!"
#: editor/export_template_manager.cpp
msgid ""
@@ -4000,9 +3999,8 @@ msgid "Reimport"
msgstr "Reimportar"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
-msgstr "Guardar cenas, reimportar e reiniciar"
+msgstr "Guardar Cenas, Reimportar e Reiniciar"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -4046,7 +4044,7 @@ msgstr "Copiar Recurso"
#: editor/inspector_dock.cpp
msgid "Make Built-In"
-msgstr "Tornar incorporado"
+msgstr "Tornar Incorporado"
#: editor/inspector_dock.cpp
msgid "Make Sub-Resources Unique"
@@ -5297,7 +5295,7 @@ msgid ""
"Overrides game camera with editor viewport camera."
msgstr ""
"Sobreposição de Câmara de Jogo\n"
-"Sobrepõe câmara de jogo com câmara do editor."
+"Sobrepõe câmara de jogo com câmara viewport do editor."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5556,7 +5554,7 @@ msgstr "Mostrar Origem"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Viewport"
-msgstr "Mostrar Vista"
+msgstr "Mostrar Viewport"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Group And Lock Icons"
@@ -6071,7 +6069,7 @@ msgstr "Fonte da Malha não especificada (e MultiMesh não contêm Malha)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (invalid path)."
-msgstr "A fonte da Malha é inválida (Caminho inválido)."
+msgstr "A fonte da malha é inválida (caminho inválido)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (not a MeshInstance)."
@@ -6087,7 +6085,7 @@ msgstr "Fonte de superfície não especificada."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Surface source is invalid (invalid path)."
-msgstr "A fonte de superfície é inválida (Caminho inválido)."
+msgstr "A fonte de superfície é inválida (caminho inválido)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Surface source is invalid (no geometry)."
@@ -7284,9 +7282,8 @@ msgid "This operation requires a single selected node."
msgstr "Esta operação requer um único nó selecionado."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Ortogonal"
+msgstr "Ortogonal Automático Ativado"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -7477,27 +7474,27 @@ msgstr "Diálogo de transformação..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "1 Viewport"
-msgstr "1 Vista"
+msgstr "1 Viewport"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "2 Viewports"
-msgstr "2 vistas"
+msgstr "2 Viewports"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "2 Viewports (Alt)"
-msgstr "2 vistas (Alt)"
+msgstr "2 Viewports (Alt)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports"
-msgstr "3 vistas"
+msgstr "3 Viewports"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports (Alt)"
-msgstr "3 vistas (Alt)"
+msgstr "3 Viewports (Alt)"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "4 Viewports"
-msgstr "4 vistas"
+msgstr "4 Viewports"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Gizmos"
@@ -7534,7 +7531,7 @@ msgstr "Ajuste de Escala (%):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Viewport Settings"
-msgstr "Configuração de Vista"
+msgstr "Configuração do Viewport"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective FOV (deg.):"
@@ -9618,7 +9615,7 @@ msgstr "Seria uma boa ideia dar um nome ao Projeto."
#: editor/project_manager.cpp
msgid "Invalid project path (changed anything?)."
-msgstr "Caminho de Projeto inválido (alguma alteração?)."
+msgstr "Caminho de projeto inválido (alguma alteração?)."
#: editor/project_manager.cpp
msgid ""
@@ -9899,6 +9896,17 @@ msgstr ""
"Atualmente não tem quaisquer projetos.\n"
"Gostaria de explorar os projetos de exemplo oficiais na Biblioteca de Ativos?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"A caixa de pesquisa filtra projetos por nome e último componente do "
+"caminho.\n"
+"Para filtrar projetos por nome e caminho completo, a pesquisa tem de conter "
+"pelo menos um caráter `/`."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Tecla "
@@ -10097,7 +10105,7 @@ msgstr "Remover tradução"
#: editor/project_settings_editor.cpp
msgid "Add Remapped Path"
-msgstr "Adicionar correção remapeada"
+msgstr "Adicionar Caminho Remapeado"
#: editor/project_settings_editor.cpp
msgid "Resource Remap Add Remap"
@@ -10858,11 +10866,11 @@ msgstr "Nome de classe inválido."
#: editor/script_create_dialog.cpp
msgid "Invalid inherited parent name or path."
-msgstr "Nome ou Caminho de parente herdado inválido."
+msgstr "Nome ou caminho de parente herdado inválido."
#: editor/script_create_dialog.cpp
msgid "Script path/name is valid."
-msgstr "Caminho/nome de Script é válido."
+msgstr "Caminho/nome de script é válido."
#: editor/script_create_dialog.cpp
msgid "Allowed: a-z, A-Z, 0-9, _ and ."
@@ -10889,6 +10897,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Nota: Scripts incorporados têm algumas limitações e não podem ser editados "
+"com um editor externo."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11011,8 +11021,12 @@ msgid "Total:"
msgstr "Total:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "Exportar lista para ficheiro CSV"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
-msgstr "Caminho do recurso"
+msgstr "Caminho do Recurso"
#: editor/script_editor_debugger.cpp
msgid "Type"
@@ -11230,7 +11244,7 @@ msgstr ""
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary format (invalid script at @path)"
-msgstr "Formato de dicionário de instância inválido (Script inválido em @path)"
+msgstr "Formato de dicionário de instância inválido (script inválido em @path)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary (invalid subclasses)"
@@ -11466,7 +11480,8 @@ msgstr "O nó retornou uma sequência de saída (output) incorreta: "
#: modules/visual_script/visual_script.cpp
msgid "Found sequence bit but not the node in the stack, report bug!"
-msgstr "Foi encontrada o bit da sequência mas não o nó na pilha, relate o bug!"
+msgstr ""
+"Foi encontrada o bit da sequência mas não o nó na pilha, denuncie o bug!"
#: modules/visual_script/visual_script.cpp
msgid "Stack overflow with stack depth: "
@@ -12228,7 +12243,7 @@ msgstr ""
#: scene/2d/remote_transform_2d.cpp
msgid "Path property must point to a valid Node2D node to work."
msgstr ""
-"Para funcionar, a Propriedade Caminho tem de apontar para um nó Node2D "
+"Para funcionar, a propriedade caminho tem de apontar para um nó Node2D "
"válido."
#: scene/2d/skeleton_2d.cpp
@@ -12664,14 +12679,14 @@ msgid ""
"obtain a size. Otherwise, make it a RenderTarget and assign its internal "
"texture to some node for display."
msgstr ""
-"Esta vista não está definida como alvo de Renderização. Se pretende "
+"Este viewport não está definida como alvo de Renderização. Se pretende "
"apresentar o seu conteúdo diretamente no ecrã, torne-a um filho de um "
"Control de modo a que obtenha um tamanho. Caso contrário, torne-a um "
"RenderTarget e atribua a sua textura interna a outro nó para visualizar."
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
-msgstr ""
+msgstr "O tamanho do viewport tem de ser maior do que 0 para renderizar."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index 28d33d4609..624ae005f2 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -10105,6 +10105,13 @@ msgstr ""
"Dorești să explorezi exemplele de proiecte oficiale din Librăria de Asset-"
"uri?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -11245,6 +11252,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Exportă Profil"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index a0e80d0ce8..d8c55d825e 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -65,17 +65,18 @@
# Ðндрей БелÑков <andbelandantrus@gmail.com>, 2020.
# Artur Tretiak <stikyt@protonmail.com>, 2020.
# Smadjavul <o1985af@gmail.com>, 2020.
-# anonymous <noreply@weblate.org>, 2020.
# Vinsent Insaider_red <vinsent.in7aider@gmail.com>, 2020.
# TMF <themysticalfox@mail.ru>, 2020.
# Ivan Kuzmenko <kuzmenko.ivan2002@yandex.com>, 2020.
# Super Pracion <superpracion2@gmail.com>, 2020.
+# PizzArt <7o7goo7o7@gmail.com>, 2020.
+# TheGracekale <mrsmailbot.lg@gmail.com>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-04-10 09:09+0000\n"
-"Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n"
+"PO-Revision-Date: 2020-05-05 14:01+0000\n"
+"Last-Translator: Super Pracion <superpracion2@gmail.com>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
"Language: ru\n"
@@ -84,7 +85,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.1-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2990,13 +2991,12 @@ msgid "Q&A"
msgstr "ВопроÑÑ‹ и ответы"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Переимпортировать"
+msgstr "Сообщить об ошибке"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Отправить отзыв о документации"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4050,7 +4050,6 @@ msgid "Reimport"
msgstr "Переимпортировать"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
msgstr "Сохранить Ñцены, переимпортировать и перезапуÑтить"
@@ -5249,7 +5248,6 @@ msgid ""
msgstr "Ð¯ÐºÐ¾Ñ€Ñ Ð¸ отÑтупы дочерних контейнеров переопределÑÑŽÑ‚ÑÑ Ð¸Ñ… родителÑми."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Presets for the anchors and margins values of a Control node."
msgstr "ПреÑеты значений Ð´Ð»Ñ Ñкорей и отÑтупов узла Control."
@@ -5660,9 +5658,8 @@ msgid "Auto Insert Key"
msgstr "ÐвтовÑтавка ключа"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Animation Key and Pose Options"
-msgstr "Опции анимационных Ключей и Позы"
+msgstr "ÐаÑтройки ключевых кадров и поз"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key (Existing Tracks)"
@@ -9108,12 +9105,10 @@ msgid "Perform the texture lookup."
msgstr "ВыполнÑет поиÑк текÑтуры."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Cubic texture uniform lookup."
-msgstr "Изменить текÑтурную единицу"
+msgstr "ПоиÑк кубичеÑкой текÑтуры."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "2D texture uniform lookup."
msgstr "Равномерный поиÑк 2D-текÑтур."
@@ -9966,6 +9961,16 @@ msgstr ""
"Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ñƒ Ð²Ð°Ñ Ð½ÐµÑ‚ никаких проектов.\n"
"Хотите изучить официальные примеры в Библиотеке реÑурÑов?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"Поле поиÑка фильтрует проекты по имени и поÑледнему компоненту пути\n"
+"Чтобы отфильтровать проекты по имени и полному пути, Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ Ñодержать "
+"Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один Ñимвол `/`."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Клавиша "
@@ -10149,7 +10154,7 @@ msgstr "ÐаÑтройки Ñохранены нормально."
#: editor/project_settings_editor.cpp
#, fuzzy
msgid "Moved Input Action Event"
-msgstr "Добавить дейÑтвие"
+msgstr "Событие ввода дейÑÑ‚Ð²Ð¸Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑ‰ÐµÐ½Ð¾"
#: editor/project_settings_editor.cpp
msgid "Override for Feature"
@@ -10396,9 +10401,8 @@ msgstr ""
"Сравните параметры Ñчетчика."
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Per-level Counter"
-msgstr "Счетчик уровнÑ"
+msgstr "Счетчик Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ уровнÑ"
#: editor/rename_dialog.cpp
msgid "If set the counter restarts for each group of child nodes"
@@ -10935,9 +10939,8 @@ msgid "Invalid inherited parent name or path."
msgstr "Ðеверное Ð¸Ð¼Ñ Ð¸Ð»Ð¸ путь наÑледуемого предка."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script path/name is valid."
-msgstr "Путь/Ð¸Ð¼Ñ Ñкрипта дейÑтвителен."
+msgstr "Путь/Ð¸Ð¼Ñ Ñкрипта допуÑтимы."
#: editor/script_create_dialog.cpp
msgid "Allowed: a-z, A-Z, 0-9, _ and ."
@@ -10964,6 +10967,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Примечание: вÑтроенные Ñкрипты имеют неÑколько ограничений и не могут быть "
+"редактированы через внешний редактор."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11034,9 +11039,8 @@ msgid "Copy Error"
msgstr "Копировать ошибку"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Video RAM"
-msgstr "Видео памÑть"
+msgstr "ВидеопамÑть"
#: editor/script_editor_debugger.cpp
msgid "Skip Breakpoints"
@@ -11088,6 +11092,10 @@ msgid "Total:"
msgstr "Ð’Ñего:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "ЭкÑпортировать профиль в CSV файл"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Путь к реÑурÑу"
@@ -11349,7 +11357,6 @@ msgid "GridMap Fill Selection"
msgstr "Залить выделенную GridMap"
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "GridMap Paste Selection"
msgstr "Ð’Ñтавить выделенную Ñетку"
@@ -12519,7 +12526,6 @@ msgid "PathFollow only works when set as a child of a Path node."
msgstr "PathFollow работает только при еÑли она дочь узла Path."
#: scene/3d/path.cpp
-#, fuzzy
msgid ""
"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its "
"parent Path's Curve resource."
@@ -12750,7 +12756,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
-msgstr ""
+msgstr "Размер окна проÑмотра должен быть больше 0 Ð´Ð»Ñ Ñ€ÐµÐ½Ð´ÐµÑ€Ð¸Ð½Ð³Ð°."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/si.po b/editor/translations/si.po
index f46a3ca292..2eb9cad3f8 100644
--- a/editor/translations/si.po
+++ b/editor/translations/si.po
@@ -9581,6 +9581,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10666,6 +10673,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index d0fe10184e..295b7ac429 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -9,12 +9,11 @@
# Michal <alladinsiffon@gmail.com>, 2019.
# Richard <rgarlik@gmail.com>, 2019.
# Richard Urban <redasuio1@gmail.com>, 2020.
-# anonymous <noreply@weblate.org>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-04-16 11:03+0000\n"
+"PO-Revision-Date: 2020-05-01 11:42+0000\n"
"Last-Translator: Richard Urban <redasuio1@gmail.com>\n"
"Language-Team: Slovak <https://hosted.weblate.org/projects/godot-engine/"
"godot/sk/>\n"
@@ -23,7 +22,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"X-Generator: Weblate 4.0.1-dev\n"
+"X-Generator: Weblate 4.0.2\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -1679,112 +1678,105 @@ msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
msgstr ""
+"Profil '%s' už existuje. Najprv ho Vymažte ako zaÄnete ImportovaÅ¥, import je "
+"prerušený."
#: editor/editor_feature_profile.cpp
msgid "Error saving profile to path: '%s'."
-msgstr ""
+msgstr "Error pri ukladaní profilu do cesty: '%s'."
#: editor/editor_feature_profile.cpp
msgid "Unset"
-msgstr ""
+msgstr "Unset"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "Vytvoriť adresár"
+msgstr "Aktuálny Profil:"
#: editor/editor_feature_profile.cpp
msgid "Make Current"
-msgstr ""
+msgstr "Spraviť Aktuálny"
#: editor/editor_feature_profile.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
#: editor/plugins/version_control_editor_plugin.cpp
msgid "New"
-msgstr ""
+msgstr "Nový"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
#: editor/project_manager.cpp
msgid "Import"
-msgstr ""
+msgstr "Import"
#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
-msgstr ""
+msgstr "Export"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "Filter:"
+msgstr "Profily k dispozícii:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Class Options"
-msgstr "Popis:"
+msgstr "Možnosti pre Class"
#: editor/editor_feature_profile.cpp
msgid "New profile name:"
-msgstr ""
+msgstr "Nové profilové meno:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Erase Profile"
-msgstr "Všetky vybrané"
+msgstr "Vymazať Profil"
#: editor/editor_feature_profile.cpp
msgid "Godot Feature Profile"
-msgstr ""
+msgstr "Godot Feature Profil"
#: editor/editor_feature_profile.cpp
msgid "Import Profile(s)"
-msgstr ""
+msgstr "Importovať Profil(y)"
#: editor/editor_feature_profile.cpp
msgid "Export Profile"
-msgstr ""
+msgstr "Exportovať Profil"
#: editor/editor_feature_profile.cpp
msgid "Manage Editor Feature Profiles"
-msgstr ""
+msgstr "Spravovať Feature Profily Editora"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Select Current Folder"
-msgstr "Vytvoriť adresár"
+msgstr "VybraÅ¥ Aktuálny PrieÄinok"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "File Exists, Overwrite?"
-msgstr ""
+msgstr "Súbor Existuje, Predpísať?"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Select This Folder"
-msgstr "Vytvoriť adresár"
+msgstr "VybraÅ¥ Tento PrieÄinok"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
-msgstr ""
+msgstr "Skopírovať Cestu"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "Open in File Manager"
-msgstr "Otvoriť súbor"
+msgstr "Otvoriť v File Manažérovy"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/filesystem_dock.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Show in File Manager"
-msgstr "Otvoriť súbor"
+msgstr "Ukázať v File Manažérovy"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Folder..."
-msgstr "Vytvoriť adresár"
+msgstr "Nový PrieÄinok..."
#: editor/editor_file_dialog.cpp editor/find_in_files.cpp
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Refresh"
-msgstr ""
+msgstr "Obnoviť"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Recognized"
@@ -1792,7 +1784,7 @@ msgstr "Všetko rozpoznané"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Files (*)"
-msgstr ""
+msgstr "Všetky Súbory (*)"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a File"
@@ -1823,74 +1815,71 @@ msgstr "Uložiť súbor"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
-msgstr ""
+msgstr "ÃsÅ¥ Naspäť"
#: editor/editor_file_dialog.cpp
msgid "Go Forward"
-msgstr ""
+msgstr "ÃsÅ¥ Dopredu"
#: editor/editor_file_dialog.cpp
msgid "Go Up"
-msgstr ""
+msgstr "ÃsÅ¥ Hore"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
-msgstr ""
+msgstr "Prepnúť Skryté Súbory"
#: editor/editor_file_dialog.cpp
msgid "Toggle Favorite"
-msgstr ""
+msgstr "Prepnúť Obľúbené"
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
-msgstr ""
+msgstr "Prepnúť Mode"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
-msgstr ""
+msgstr "Zamerať Cestu"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
-msgstr ""
+msgstr "Posunúť obľúbené Vyššie"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Down"
-msgstr ""
+msgstr "Posunúť Obľúbené Nižšie"
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to previous folder."
-msgstr "Vytvoriť adresár"
+msgstr "ÃsÅ¥ do predchádzajúceho prieÄinka."
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to next folder."
-msgstr "Vytvoriť adresár"
+msgstr "ÃsÅ¥ do ÄalÅ¡ieho prieÄinka."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Go to parent folder."
-msgstr "Vytvoriť adresár"
+msgstr "ÃsÅ¥ do parent folder."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Refresh files."
-msgstr ""
+msgstr "Obnoviť súbory."
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
-msgstr ""
+msgstr "(Od)obľúbiÅ¥ aktuálny prieÄinok."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Toggle the visibility of hidden files."
-msgstr ""
+msgstr "Prepnúť viditeľnosť skrytých súborov."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
-msgstr ""
+msgstr "Zobraziť veci ako mriežku náhľadov."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a list."
-msgstr ""
+msgstr "Zobraziť veci ako list."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Directories & Files:"
@@ -1900,7 +1889,7 @@ msgstr "PrieÄinky a Súbory:"
#: editor/plugins/style_box_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
msgid "Preview:"
-msgstr ""
+msgstr "Ako to bude vyzerať:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "File:"
@@ -1908,25 +1897,27 @@ msgstr "Súbor:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Must use a valid extension."
-msgstr ""
+msgstr "Musíte použiť platné rozšírenie."
#: editor/editor_file_system.cpp
msgid "ScanSources"
-msgstr ""
+msgstr "SkenZdrojov"
#: editor/editor_file_system.cpp
msgid ""
"There are multiple importers for different types pointing to file %s, import "
"aborted"
msgstr ""
+"Sú tu viacero importérov pre rozliÄné typy ukazujúce do súboru, import "
+"prerušený"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
-msgstr ""
+msgstr "(Re)Importovanie Asset-ov"
#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Top"
-msgstr ""
+msgstr "Top"
#: editor/editor_help.cpp
msgid "Class:"
@@ -1935,175 +1926,164 @@ msgstr "Trieda:"
#: editor/editor_help.cpp editor/scene_tree_editor.cpp
#: editor/script_create_dialog.cpp
msgid "Inherits:"
-msgstr ""
+msgstr "Inherit-y:"
#: editor/editor_help.cpp
msgid "Inherited by:"
-msgstr ""
+msgstr "Zdedené používateľom:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Description"
-msgstr "Popis:"
+msgstr "Popisok"
#: editor/editor_help.cpp
msgid "Online Tutorials"
-msgstr ""
+msgstr "Online Tutoriáli"
#: editor/editor_help.cpp
msgid "Properties"
-msgstr ""
+msgstr "Vlastnosti"
#: editor/editor_help.cpp
msgid "override:"
-msgstr ""
+msgstr "Predpísať:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "default:"
-msgstr "NaÄítaÅ¥ predvolené"
+msgstr "Å tandard:"
#: editor/editor_help.cpp
msgid "Methods"
-msgstr ""
+msgstr "Metódy"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Theme Properties"
-msgstr "Filter:"
+msgstr "Vlastnosti Témy"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Enumerations"
-msgstr "Popis:"
+msgstr "VýpoÄty"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Constants"
-msgstr "Konštanty:"
+msgstr "Konštanty"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Property Descriptions"
-msgstr "Popis:"
+msgstr "Popisok Vlastnosti"
#: editor/editor_help.cpp
-#, fuzzy
msgid "(value)"
-msgstr "Hodnota:"
+msgstr "(hodnota)"
#: editor/editor_help.cpp
msgid ""
"There is currently no description for this property. Please help us by "
"[color=$color][url=$url]contributing one[/url][/color]!"
msgstr ""
+"Zatiaľ tu není žiadny popisok pre túto vlastnosť. Prosím pomôžte nám pomocou "
+"[color=$color][url=$url]prispetím jedného[/url][/color]!"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Method Descriptions"
-msgstr "Popis:"
+msgstr "Popisky Metód"
#: editor/editor_help.cpp
msgid ""
"There is currently no description for this method. Please help us by [color="
"$color][url=$url]contributing one[/url][/color]!"
msgstr ""
+"Zatiaľ tu není žiadny popisok pre túto metódu. Prosím pomôžte nám pomocou "
+"[color=$color][url=$url]prispetím jedného[/url][/color]!"
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr ""
+msgstr "Vyhľadať Pomoc"
#: editor/editor_help_search.cpp
msgid "Case Sensitive"
-msgstr ""
+msgstr "Rozlišuje malé a veľké písmená"
#: editor/editor_help_search.cpp
msgid "Show Hierarchy"
-msgstr ""
+msgstr "Ukázať Hierarchiu"
#: editor/editor_help_search.cpp
msgid "Display All"
-msgstr ""
+msgstr "Zobraziť Všetko"
#: editor/editor_help_search.cpp
msgid "Classes Only"
-msgstr ""
+msgstr "Iba Class-y"
#: editor/editor_help_search.cpp
msgid "Methods Only"
-msgstr ""
+msgstr "Iba Metódy"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Signals Only"
-msgstr "Signály:"
+msgstr "Iba Signály"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Constants Only"
-msgstr "Konštanty:"
+msgstr "Iba Konštanty"
#: editor/editor_help_search.cpp
msgid "Properties Only"
-msgstr ""
+msgstr "Iba Vlastnosti"
#: editor/editor_help_search.cpp
msgid "Theme Properties Only"
-msgstr ""
+msgstr "Iba Vlastnosti Témy"
#: editor/editor_help_search.cpp
msgid "Member Type"
-msgstr ""
+msgstr "Typ ÄŒlena"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Class"
-msgstr "Trieda:"
+msgstr "Class"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Method"
-msgstr "Prejdite na Metódu"
+msgstr "Metóda"
#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Signal"
-msgstr "Signály"
+msgstr "Signál"
#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Constant"
-msgstr ""
+msgstr "Konštant"
#: editor/editor_help_search.cpp
msgid "Property"
-msgstr ""
+msgstr "Vlastnosť"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Theme Property"
-msgstr "Filter:"
+msgstr "Vlastnosť Témy"
#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
msgid "Property:"
-msgstr ""
+msgstr "Vlastnosť:"
#: editor/editor_inspector.cpp
msgid "Set"
-msgstr ""
+msgstr "Nastaviť"
#: editor/editor_inspector.cpp
msgid "Set Multiple:"
-msgstr ""
+msgstr "Nastaviť Viac:"
#: editor/editor_log.cpp
msgid "Output:"
-msgstr ""
+msgstr "Output:"
#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Copy Selection"
-msgstr "Odstrániť výber"
+msgstr "Skopírovať Výber"
#: editor/editor_log.cpp editor/editor_network_profiler.cpp
#: editor/editor_profiler.cpp editor/editor_properties.cpp
@@ -2113,177 +2093,182 @@ msgstr "Odstrániť výber"
#: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp
#: scene/gui/text_edit.cpp
msgid "Clear"
-msgstr ""
+msgstr "VyÄistiÅ¥"
#: editor/editor_log.cpp
-#, fuzzy
msgid "Clear Output"
-msgstr "Popis:"
+msgstr "VyÄistiÅ¥ Output"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
#: editor/editor_profiler.cpp
msgid "Stop"
-msgstr ""
+msgstr "Stop"
#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
msgid "Start"
-msgstr ""
+msgstr "Å tart"
#: editor/editor_network_profiler.cpp
msgid "%s/s"
-msgstr ""
+msgstr "%s/s"
#: editor/editor_network_profiler.cpp
msgid "Down"
-msgstr ""
+msgstr "Dole"
#: editor/editor_network_profiler.cpp
msgid "Up"
-msgstr ""
+msgstr "Hore"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
msgid "Node"
-msgstr ""
+msgstr "Node"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
-msgstr ""
+msgstr "Prichádzajúce RPC"
#: editor/editor_network_profiler.cpp
msgid "Incoming RSET"
-msgstr ""
+msgstr "Prichádzajúci RSET"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RPC"
-msgstr ""
+msgstr "Vychádzajúce RPC"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RSET"
-msgstr ""
+msgstr "Vychádzajúci RSET"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "New Window"
-msgstr ""
+msgstr "Nové Okno"
#: editor/editor_node.cpp
msgid "Imported resources can't be saved."
-msgstr ""
+msgstr "Importované zdroje nemôžu byť uložené."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
msgid "OK"
-msgstr ""
+msgstr "OK"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
-msgstr ""
+msgstr "Error pri ukladaní prostriedku!"
#: editor/editor_node.cpp
msgid ""
"This resource can't be saved because it does not belong to the edited scene. "
"Make it unique first."
msgstr ""
+"Tento prostriedok nemôže byť uložený lebo nepatrí editovanej scéne. Najprv "
+"ho spravte jedineÄným."
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
-msgstr ""
+msgstr "Uložiť Prostriedok Ako..."
#: editor/editor_node.cpp
msgid "Can't open file for writing:"
-msgstr ""
+msgstr "Nie je možné otvoriť súbor pre písanie:"
#: editor/editor_node.cpp
msgid "Requested file format unknown:"
-msgstr ""
+msgstr "Požadovaný formát súboru je neznámy:"
#: editor/editor_node.cpp
msgid "Error while saving."
-msgstr ""
+msgstr "Error pri ukladaní."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Can't open '%s'. The file could have been moved or deleted."
-msgstr ""
+msgstr "Nedá sa otvoriť '%s'. Súbor mohol byť presunutý alebo vymazaný."
#: editor/editor_node.cpp
msgid "Error while parsing '%s'."
-msgstr ""
+msgstr "Error pri analýze '%s'."
#: editor/editor_node.cpp
msgid "Unexpected end of file '%s'."
-msgstr ""
+msgstr "NeoÄakávaný koniec súboru '%s'."
#: editor/editor_node.cpp
msgid "Missing '%s' or its dependencies."
-msgstr ""
+msgstr "Chýba '%s' alebo jeho závislosti."
#: editor/editor_node.cpp
msgid "Error while loading '%s'."
-msgstr ""
+msgstr "Error pri naÄítavaní '%s'."
#: editor/editor_node.cpp
msgid "Saving Scene"
-msgstr ""
+msgstr "Ukladanie Scény"
#: editor/editor_node.cpp
msgid "Analyzing"
-msgstr ""
+msgstr "Analyzovanie"
#: editor/editor_node.cpp
msgid "Creating Thumbnail"
-msgstr ""
+msgstr "Vytváranie Náhľadu"
#: editor/editor_node.cpp
msgid "This operation can't be done without a tree root."
-msgstr ""
+msgstr "Tátu operáciu nie je možné vykonať bez tree root-u."
#: editor/editor_node.cpp
msgid ""
"This scene can't be saved because there is a cyclic instancing inclusion.\n"
"Please resolve it and then attempt to save again."
msgstr ""
+"Táto scéna nemôže byť uložená lebo je tu cyklické instancovanie inklúzie.\n"
+"Prosím vyriešte to a skúste to znova."
#: editor/editor_node.cpp
msgid ""
"Couldn't save scene. Likely dependencies (instances or inheritance) couldn't "
"be satisfied."
msgstr ""
+"Nedá sa uložiÅ¥ scéna. Pravdepodobne (inÅ¡tancie alebo dediÄstvo) nemôžu byÅ¥ "
+"spokojné."
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "Can't overwrite scene that is still open!"
-msgstr ""
+msgstr "Scéna sa nedá predpísaÅ¥ keÄ je stále otvorená!"
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
-msgstr ""
+msgstr "Nedá sa naÄítaÅ¥ MeshLibrary lebo sa spája!"
#: editor/editor_node.cpp
msgid "Error saving MeshLibrary!"
-msgstr ""
+msgstr "Error pri ukladaní MeshLibrary!"
#: editor/editor_node.cpp
msgid "Can't load TileSet for merging!"
-msgstr ""
+msgstr "Nedá sa naÄítaÅ¥ TileSet lebo sa spája!"
#: editor/editor_node.cpp
msgid "Error saving TileSet!"
-msgstr ""
+msgstr "Error pri ukladaní TileSet-u!"
#: editor/editor_node.cpp
msgid "Error trying to save layout!"
-msgstr ""
+msgstr "Error pri ukladaní layout-i!"
#: editor/editor_node.cpp
msgid "Default editor layout overridden."
-msgstr ""
+msgstr "Predvolený editor layout je prepísaný."
#: editor/editor_node.cpp
msgid "Layout name not found!"
-msgstr ""
+msgstr "Meno Layout-u sa nenašlo!"
#: editor/editor_node.cpp
msgid "Restored default layout to base settings."
-msgstr ""
+msgstr "Obnovené predvolené rozloženie na základné nastavenia."
#: editor/editor_node.cpp
msgid ""
@@ -2291,18 +2276,26 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
+"Tento prostriedok patrí scéne ktorá bola importovaná, takže není "
+"editovateľný.\n"
+"Prosím preÄítajte si dokumentáciu na importovanie scén aby ste tomu viac "
+"pochopili."
#: editor/editor_node.cpp
msgid ""
"This resource belongs to a scene that was instanced or inherited.\n"
"Changes to it won't be kept when saving the current scene."
msgstr ""
+"Tento prostriedok patrí scéne ktorá bola inštancovaná alebo zdedená.\n"
+"Zmeny sa nezanechajú po uložení aktuálnej scény."
#: editor/editor_node.cpp
msgid ""
"This resource was imported, so it's not editable. Change its settings in the "
"import panel and then re-import."
msgstr ""
+"Tento prostriedok bol importovaný, takže není editovateľný. Zmeňte jeho "
+"nastavenia v import panely a potom stlaÄÅ¥e re-import."
#: editor/editor_node.cpp
msgid ""
@@ -2311,6 +2304,11 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
+"Táto scéna bola importovaná, takže sa zmeny neuložia.\n"
+"Jej inštancovaním alebo zdedením povolíte to že môžete robiť zmeny v tejto "
+"scéne.\n"
+"Prosím preÄítajte si dokumentáciu na importovanie scén aby ste tomu viac "
+"pochopili."
#: editor/editor_node.cpp
msgid ""
@@ -2318,203 +2316,215 @@ msgid ""
"Please read the documentation relevant to debugging to better understand "
"this workflow."
msgstr ""
+"Toto je remote objekt, takže sa zmeny neuložia.\n"
+"Prosím preÄítajte si dokumentáciu o debbugging aby ste tomu viac pochopili."
#: editor/editor_node.cpp
msgid "There is no defined scene to run."
-msgstr ""
+msgstr "Nieje definovaná žiadna scéna na spustenie."
#: editor/editor_node.cpp
msgid "Current scene was never saved, please save it prior to running."
-msgstr ""
+msgstr "Aktuálna scéna sa nikdy neuložila, prosím uložte ju pred spustením."
#: editor/editor_node.cpp
msgid "Could not start subprocess!"
-msgstr ""
+msgstr "Subprocess sa nedá spustiť!"
#: editor/editor_node.cpp editor/filesystem_dock.cpp
msgid "Open Scene"
-msgstr ""
+msgstr "Otvoriť Scénu"
#: editor/editor_node.cpp
msgid "Open Base Scene"
-msgstr ""
+msgstr "Otvoriť Base Scene"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Quick Open..."
-msgstr "Otvoriť"
+msgstr "Rýchle Otvorenie..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
-msgstr ""
+msgstr "Rýchle Otvorenie Scény..."
#: editor/editor_node.cpp
msgid "Quick Open Script..."
-msgstr ""
+msgstr "Rýchle Otvorenie Scriptu..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save & Close"
-msgstr "Uložiť súbor"
+msgstr "Uložiť & Zatvoriť"
#: editor/editor_node.cpp
msgid "Save changes to '%s' before closing?"
-msgstr ""
+msgstr "Chcete uložiť zmeny do '%s' pred zatvorením?"
#: editor/editor_node.cpp
msgid "Saved %s modified resource(s)."
-msgstr ""
+msgstr "Uložené %s upravené zdroje."
#: editor/editor_node.cpp
msgid "A root node is required to save the scene."
-msgstr ""
+msgstr "Na uloženie scény je potrebný root node."
#: editor/editor_node.cpp
msgid "Save Scene As..."
-msgstr ""
+msgstr "Uložiť Scénu Ako..."
#: editor/editor_node.cpp
msgid "No"
-msgstr ""
+msgstr "Nie"
#: editor/editor_node.cpp
msgid "Yes"
-msgstr ""
+msgstr "ÃNO"
#: editor/editor_node.cpp
msgid "This scene has never been saved. Save before running?"
msgstr ""
+"Táto scéna ešte nikdy nebola uložená. Chcete ju uložiť predtým ako ju "
+"zapnete?"
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
-msgstr ""
+msgstr "Táto operácia nemôže byÅ¥ dokonÄená bez scény."
#: editor/editor_node.cpp
msgid "Export Mesh Library"
-msgstr ""
+msgstr "Exportovať Mesh Library"
#: editor/editor_node.cpp
msgid "This operation can't be done without a root node."
-msgstr ""
+msgstr "Táto operácia nemôže byÅ¥ dokonÄená bez root node-u."
#: editor/editor_node.cpp
msgid "Export Tile Set"
-msgstr ""
+msgstr "Exportovať Tile Set"
#: editor/editor_node.cpp
msgid "This operation can't be done without a selected node."
-msgstr ""
+msgstr "Táto operácia nemôže byÅ¥ dokonÄená bez vybraného node-u."
#: editor/editor_node.cpp
msgid "Current scene not saved. Open anyway?"
-msgstr ""
+msgstr "Aktuálna scéna sa neuložila. Chcete ju aj tak otvoriť?"
#: editor/editor_node.cpp
msgid "Can't reload a scene that was never saved."
-msgstr ""
+msgstr "Nemožno naÄítaÅ¥ scénu, ktorá nikdy nebola uložená."
#: editor/editor_node.cpp
msgid "Revert"
-msgstr ""
+msgstr "Revert"
#: editor/editor_node.cpp
msgid "This action cannot be undone. Revert anyway?"
-msgstr ""
+msgstr "Túto akciu nie je možné vrátiť späť. Chcete Revertovatť aj tak?"
#: editor/editor_node.cpp
msgid "Quick Run Scene..."
-msgstr ""
+msgstr "Rýchle Spustenie Scény..."
#: editor/editor_node.cpp
msgid "Quit"
-msgstr ""
+msgstr "Odísť"
#: editor/editor_node.cpp
msgid "Exit the editor?"
-msgstr ""
+msgstr "Odísť z editora?"
#: editor/editor_node.cpp
msgid "Open Project Manager?"
-msgstr ""
+msgstr "Otvoriť Manažéra Projektov?"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save & Quit"
-msgstr "Uložiť súbor"
+msgstr "UložiÅ¥ & UkonÄiÅ¥"
#: editor/editor_node.cpp
msgid "Save changes to the following scene(s) before quitting?"
-msgstr ""
+msgstr "UložiÅ¥ zmeny do nasledujúcich scén pred ukonÄením?"
#: editor/editor_node.cpp
msgid "Save changes the following scene(s) before opening Project Manager?"
-msgstr ""
+msgstr "Uložiť zmeny nasledujúcich scén pred otvorením Manažéra Projektov?"
#: editor/editor_node.cpp
msgid ""
"This option is deprecated. Situations where refresh must be forced are now "
"considered a bug. Please report."
msgstr ""
+"Táto možnosť je zastaraná. Situácie, v ktorých je potrebné obnovenie, sa "
+"teraz považujú za chybu. Prosím, nahláste."
#: editor/editor_node.cpp
msgid "Pick a Main Scene"
-msgstr ""
+msgstr "Vyberte hlavnú scénu"
#: editor/editor_node.cpp
msgid "Close Scene"
-msgstr ""
+msgstr "Zavrieť Scénu"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Reopen Closed Scene"
-msgstr "Otvoriť súbor(y)"
+msgstr "Preotvoriť Zatvorenú Scénu"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr ""
+"Addon plugin nie je možné povoliť pri: '% s' analýze konfigurácie zlyhalo."
#: editor/editor_node.cpp
msgid "Unable to find script field for addon plugin at: 'res://addons/%s'."
msgstr ""
+"Nepodarilo sa nájsť script field pre addon plugin v: 'res://addons/%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
-msgstr ""
+msgstr "Nepodarilo sa naÄítaÅ¥ addon script z cesty: '%s'."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
msgstr ""
+"Nepodarilo sa nájsť addon script z cesty: '%s' Vyzerá to tak že by mohol byť "
+"problém v kóde, prosím skontrolujte syntax."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
msgstr ""
+"Nepodarilo sa naÄítaÅ¥ addon script z cesty: '%s' Base type není EditorPlugin."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
msgstr ""
+"Nepodarilo sa naÄítaÅ¥ addon script z cesty: '%s' Script není v tool móde."
#: editor/editor_node.cpp
msgid ""
"Scene '%s' was automatically imported, so it can't be modified.\n"
"To make changes to it, a new inherited scene can be created."
msgstr ""
+"Scéna '%s' bola automaticky importovaná, takže nemôže byť modifikovaná.\n"
+"Aby ste v nej mohli spraviť úpravy, môžete vytvoriť novú zdedenú scénu."
#: editor/editor_node.cpp
msgid ""
"Error loading scene, it must be inside the project path. Use 'Import' to "
"open the scene, then save it inside the project path."
msgstr ""
+"Error pri naÄítavaní, musí byÅ¥ vo vnútri projektovej cesty. Použite 'Import' "
+"aby ste otvorili scénu, a potom ju uložte do projektovej cesty."
#: editor/editor_node.cpp
msgid "Scene '%s' has broken dependencies:"
-msgstr ""
+msgstr "Scéna '%s' má zniÄené závislosti:"
#: editor/editor_node.cpp
msgid "Clear Recent Scenes"
-msgstr ""
+msgstr "VyÄistiÅ¥ Posledné Scény"
#: editor/editor_node.cpp
msgid ""
@@ -2522,6 +2532,9 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"Ešte ste nedefinovali hlavnú scénu, chcete nejakú vybrať?\n"
+"Neskôr ju môžete zmeniť v \"Nastaveniach Projektu\" pod kategóriou "
+"'application'."
#: editor/editor_node.cpp
msgid ""
@@ -2529,6 +2542,9 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"Vybraná scéna '%s' neexistuje, vybrať platnú?\n"
+"Neskôr ju môžete zmeniť v \"Nastaveniach Projekta\" pod kategóriou "
+"'application'."
#: editor/editor_node.cpp
msgid ""
@@ -2536,147 +2552,147 @@ msgid ""
"You can change it later in \"Project Settings\" under the 'application' "
"category."
msgstr ""
+"Vybraná scéna '%s' není scene file, vybrať platnú scénu?\n"
+"Neskôr ju môžete zmeniť v \"Nastaveniach Projekta\" pod kategóriou "
+"'application'."
#: editor/editor_node.cpp
msgid "Save Layout"
-msgstr ""
+msgstr "Uložiť Layout"
#: editor/editor_node.cpp
msgid "Delete Layout"
-msgstr ""
+msgstr "Odstrániť Layout"
#: editor/editor_node.cpp editor/import_dock.cpp
#: editor/script_create_dialog.cpp
msgid "Default"
-msgstr ""
+msgstr "Predvolené"
#: editor/editor_node.cpp editor/editor_properties.cpp
#: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp
msgid "Show in FileSystem"
-msgstr ""
+msgstr "Ukázať v FileSystéme"
#: editor/editor_node.cpp
msgid "Play This Scene"
-msgstr ""
+msgstr "Spustiť Túto Scénu"
#: editor/editor_node.cpp
msgid "Close Tab"
-msgstr ""
+msgstr "Zavrieť Kartu"
#: editor/editor_node.cpp
msgid "Undo Close Tab"
-msgstr ""
+msgstr "Naspäť Otvoriť Kartu"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Close Other Tabs"
-msgstr ""
+msgstr "Zavrieť Ostatné Karty"
#: editor/editor_node.cpp
msgid "Close Tabs to the Right"
-msgstr ""
+msgstr "Zavrieť Karty na Pravo"
#: editor/editor_node.cpp
msgid "Close All Tabs"
-msgstr ""
+msgstr "Zatvoriť všetky Karty"
#: editor/editor_node.cpp
msgid "Switch Scene Tab"
-msgstr ""
+msgstr "Prepnúť Kartu Scény"
#: editor/editor_node.cpp
msgid "%d more files or folders"
-msgstr ""
+msgstr "%d viac súborov alebo prieÄinkov"
#: editor/editor_node.cpp
-#, fuzzy
msgid "%d more folders"
-msgstr "Vytvoriť adresár"
+msgstr "%d viac prieÄinkov"
#: editor/editor_node.cpp
msgid "%d more files"
-msgstr ""
+msgstr "%d viac súborov"
#: editor/editor_node.cpp
msgid "Dock Position"
-msgstr ""
+msgstr "Pozícia Dock-u"
#: editor/editor_node.cpp
msgid "Distraction Free Mode"
-msgstr ""
+msgstr "Režim bez rozptyľovania"
#: editor/editor_node.cpp
msgid "Toggle distraction-free mode."
-msgstr ""
+msgstr "Prepnúť režim bez rozptyľovania."
#: editor/editor_node.cpp
msgid "Add a new scene."
-msgstr ""
+msgstr "Pridať novú scénu."
#: editor/editor_node.cpp
msgid "Scene"
-msgstr ""
+msgstr "Scéna"
#: editor/editor_node.cpp
msgid "Go to previously opened scene."
-msgstr ""
+msgstr "ÃsÅ¥ do naposledy otvorenej scény."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Copy Text"
-msgstr "Kopírovať"
+msgstr "Kopírovať Text"
#: editor/editor_node.cpp
msgid "Next tab"
-msgstr ""
+msgstr "Ďalšia karta"
#: editor/editor_node.cpp
msgid "Previous tab"
-msgstr ""
+msgstr "Minulá karta"
#: editor/editor_node.cpp
msgid "Filter Files..."
-msgstr ""
+msgstr "Filtrovať Súbory..."
#: editor/editor_node.cpp
msgid "Operations with scene files."
-msgstr ""
+msgstr "Operácie zo súbormi scén."
#: editor/editor_node.cpp
msgid "New Scene"
-msgstr ""
+msgstr "Nová Scéna"
#: editor/editor_node.cpp
msgid "New Inherited Scene..."
-msgstr ""
+msgstr "Nové Zdedené Scény..."
#: editor/editor_node.cpp
msgid "Open Scene..."
-msgstr ""
+msgstr "Otvoriť Scénu..."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Open Recent"
-msgstr ""
+msgstr "Otvoriť Posledné"
#: editor/editor_node.cpp
msgid "Save Scene"
-msgstr ""
+msgstr "Uložiť Scénu"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save All Scenes"
-msgstr "Uložiť súbor"
+msgstr "Uložiť Všetky Scény"
#: editor/editor_node.cpp
msgid "Convert To..."
-msgstr ""
+msgstr "Konvertovať Do..."
#: editor/editor_node.cpp
msgid "MeshLibrary..."
-msgstr ""
+msgstr "MeshLibrary..."
#: editor/editor_node.cpp
msgid "TileSet..."
-msgstr ""
+msgstr "TileSet..."
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
@@ -2686,80 +2702,81 @@ msgstr "Späť"
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Redo"
-msgstr ""
+msgstr "Prerobiť"
#: editor/editor_node.cpp
msgid "Revert Scene"
-msgstr ""
+msgstr "Vrátiť Scénu"
#: editor/editor_node.cpp
msgid "Miscellaneous project or scene-wide tools."
-msgstr ""
+msgstr "Zmiešanosti projektových alebo scénových wide tool-ov."
#: editor/editor_node.cpp editor/project_manager.cpp
#: editor/script_create_dialog.cpp
msgid "Project"
-msgstr ""
+msgstr "Projekt"
#: editor/editor_node.cpp
msgid "Project Settings..."
-msgstr ""
+msgstr "Nastavenia Projektu..."
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control"
-msgstr ""
+msgstr "Kontrola Verzie"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
-msgstr ""
+msgstr "Nastaviť Kontrolu Verizie"
#: editor/editor_node.cpp
msgid "Shut Down Version Control"
-msgstr ""
+msgstr "Vypnúť Kontrolu Verzie"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Export..."
-msgstr "Upraviť..."
+msgstr "Export..."
#: editor/editor_node.cpp
msgid "Install Android Build Template..."
-msgstr ""
+msgstr "Inštalovať Android Build Template..."
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
-msgstr ""
+msgstr "Otvoriť Project Data Folder"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
-msgstr ""
+msgstr "Nástroje"
#: editor/editor_node.cpp
msgid "Orphan Resource Explorer..."
-msgstr ""
+msgstr "Orphan Resource Explorer..."
#: editor/editor_node.cpp
msgid "Quit to Project List"
-msgstr ""
+msgstr "Odísť do Listu Projektov"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
msgid "Debug"
-msgstr ""
+msgstr "Debug"
#: editor/editor_node.cpp
msgid "Deploy with Remote Debug"
-msgstr ""
+msgstr "Deploy-ovanie z Remote Debug-om"
#: editor/editor_node.cpp
msgid ""
"When exporting or deploying, the resulting executable will attempt to "
"connect to the IP of this computer in order to be debugged."
msgstr ""
+"Pri exportovaní alebo deploy-ovaní, súbor resulting executable sa pokúsi o "
+"pripojenie do IP vášho poÄítaÄa aby mohol byÅ¥ debugg-ovaný."
#: editor/editor_node.cpp
msgid "Small Deploy with Network FS"
-msgstr ""
+msgstr "Malý Deploy z Network FS"
#: editor/editor_node.cpp
msgid ""
@@ -2770,30 +2787,39 @@ msgid ""
"On Android, deploy will use the USB cable for faster performance. This "
"option speeds up testing for games with a large footprint."
msgstr ""
+"KeÄ bude povolená táto možnosÅ¥, export alebo deploy vyprodukujú menej \n"
+"súboru executable.\n"
+"Filesystém bude z projektu poskytovaný editorom v sieti. Na Androide, pre "
+"deploy budete potrebovať USB kábel \n"
+"rýchlejší výkon. Táto možnosť zrýchľuje proces testovania."
#: editor/editor_node.cpp
msgid "Visible Collision Shapes"
-msgstr ""
+msgstr "Viditeľné Tvary Kolízie"
#: editor/editor_node.cpp
msgid ""
"Collision shapes and raycast nodes (for 2D and 3D) will be visible on the "
"running game if this option is turned on."
msgstr ""
+"Tvary Kolízie a raycast node-y (pre 2D a 3D) budú viditeľné po spustení hry "
+"ak budete mať zapnutú túto možnosť."
#: editor/editor_node.cpp
msgid "Visible Navigation"
-msgstr ""
+msgstr "Viditeľná Navigácia"
#: editor/editor_node.cpp
msgid ""
"Navigation meshes and polygons will be visible on the running game if this "
"option is turned on."
msgstr ""
+"NavigaÄné mesh-e a polygony budú viditeľné po spustení hry ak budete maÅ¥ "
+"zapnutú túto možnosť."
#: editor/editor_node.cpp
msgid "Sync Scene Changes"
-msgstr ""
+msgstr "Zmeny Synchronizácie Scény"
#: editor/editor_node.cpp
msgid ""
@@ -2802,10 +2828,14 @@ msgid ""
"When used remotely on a device, this is more efficient with network "
"filesystem."
msgstr ""
+"KeÄ zapnete túto možnosÅ¥, akékoľvek zmeny v scéne v editore budú náhradné so "
+"spustenou hrou.\n"
+"KeÄ je použitá na diaľku v zariadení, je to viac efektívne z network "
+"filesystémom."
#: editor/editor_node.cpp
msgid "Sync Script Changes"
-msgstr ""
+msgstr "Zmeny Synchronizácie Scriptu"
#: editor/editor_node.cpp
msgid ""
@@ -2814,60 +2844,62 @@ msgid ""
"When used remotely on a device, this is more efficient with network "
"filesystem."
msgstr ""
+"KeÄ je zapnutá táto MožnosÅ¥, akýkoľvek uložený script bude znovu naÄítaný v "
+"spustenej hre.\n"
+"KeÄ je použitá na diaľku zo zariadenia, toto je viac efektívnejÅ¡ie z network "
+"filesystémom."
#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
msgstr "Editor"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Editor Settings..."
-msgstr "Prechody"
+msgstr "Nastavenia Editora..."
#: editor/editor_node.cpp
msgid "Editor Layout"
-msgstr ""
+msgstr "Layout Editora"
#: editor/editor_node.cpp
msgid "Take Screenshot"
-msgstr ""
+msgstr "Spraviť Snímku Obrazovky"
#: editor/editor_node.cpp
msgid "Screenshots are stored in the Editor Data/Settings Folder."
-msgstr ""
+msgstr "Snímky obrázky sú uložené v Editor Data/Settings Folder."
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
-msgstr ""
+msgstr "Prepnúť na Celú Obrazovku"
#: editor/editor_node.cpp
msgid "Toggle System Console"
-msgstr ""
+msgstr "Prepnúť Systémovú Konzolu"
#: editor/editor_node.cpp
msgid "Open Editor Data/Settings Folder"
-msgstr ""
+msgstr "Otvoriť Editor Data/Settings Folder"
#: editor/editor_node.cpp
msgid "Open Editor Data Folder"
-msgstr ""
+msgstr "OtvoriÅ¥ prieÄinok Editor Data"
#: editor/editor_node.cpp
msgid "Open Editor Settings Folder"
-msgstr ""
+msgstr "OtvoriÅ¥ PrieÄinok Editor Settings"
#: editor/editor_node.cpp
msgid "Manage Editor Features..."
-msgstr ""
+msgstr "Spravovať Funkcie Editora..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Export Templates..."
-msgstr "Všetky vybrané"
+msgstr "Spravovať Export Templates..."
#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
-msgstr ""
+msgstr "Pomoc"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
#: editor/plugins/script_editor_plugin.cpp
@@ -2876,24 +2908,24 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp
#: editor/project_settings_editor.cpp editor/rename_dialog.cpp
msgid "Search"
-msgstr ""
+msgstr "Vyhľadať"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
msgid "Online Docs"
-msgstr ""
+msgstr "Online Dokumentácie"
#: editor/editor_node.cpp
msgid "Q&A"
-msgstr ""
+msgstr "Q&A"
#: editor/editor_node.cpp
msgid "Report a Bug"
-msgstr ""
+msgstr "Nahlásiť Bugy"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Poslať spätnú väzbu Dokumentácie"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -2905,95 +2937,92 @@ msgstr "O nás"
#: editor/editor_node.cpp
msgid "Play the project."
-msgstr ""
+msgstr "Spustiť projekt."
#: editor/editor_node.cpp
msgid "Play"
-msgstr ""
+msgstr "Spustiť"
#: editor/editor_node.cpp
msgid "Pause the scene execution for debugging."
-msgstr ""
+msgstr "Pozastavenie vykonávania scény kvôli debugg-ovaniu."
#: editor/editor_node.cpp
msgid "Pause Scene"
-msgstr ""
+msgstr "Pozastaviť Scénu"
#: editor/editor_node.cpp
msgid "Stop the scene."
-msgstr ""
+msgstr "Zastaviť scénu."
#: editor/editor_node.cpp
msgid "Play the edited scene."
-msgstr ""
+msgstr "Spustiť editovanú scénu."
#: editor/editor_node.cpp
msgid "Play Scene"
-msgstr ""
+msgstr "Spustiť Scénu"
#: editor/editor_node.cpp
msgid "Play custom scene"
-msgstr ""
+msgstr "Spustiť vlastnú scénu"
#: editor/editor_node.cpp
msgid "Play Custom Scene"
-msgstr ""
+msgstr "Spustiť Vlastnú Scénu"
#: editor/editor_node.cpp
msgid "Changing the video driver requires restarting the editor."
-msgstr ""
+msgstr "Zmena video driver-u vyžaduje reštart editora."
#: editor/editor_node.cpp editor/project_settings_editor.cpp
#: editor/settings_config_dialog.cpp
-#, fuzzy
msgid "Save & Restart"
-msgstr "Uložiť súbor"
+msgstr "Uložiť & Reštartovať"
#: editor/editor_node.cpp
msgid "Spins when the editor window redraws."
-msgstr ""
+msgstr "OtáÄa sa, keÄ sa okno editora redistribuuje."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Update Continuously"
-msgstr "Priebežný"
+msgstr "Aktualizovať priebežne"
#: editor/editor_node.cpp
msgid "Update When Changed"
-msgstr ""
+msgstr "Aktualizovať po Zmene"
#: editor/editor_node.cpp
msgid "Hide Update Spinner"
-msgstr ""
+msgstr "Skryť aktualizáciu Spinner"
#: editor/editor_node.cpp
msgid "FileSystem"
-msgstr ""
+msgstr "FileSystém"
#: editor/editor_node.cpp
msgid "Inspector"
-msgstr ""
+msgstr "Inšpektor"
#: editor/editor_node.cpp
msgid "Expand Bottom Panel"
-msgstr ""
+msgstr "Expandovať Spodný Panel"
#: editor/editor_node.cpp
msgid "Output"
-msgstr ""
+msgstr "Výstup"
#: editor/editor_node.cpp
msgid "Don't Save"
-msgstr ""
+msgstr "Neukladať"
#: editor/editor_node.cpp
msgid "Android build template is missing, please install relevant templates."
-msgstr ""
+msgstr "Android build template chýba, prosím nainštalujte príslušné šablóny."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Templates"
-msgstr "Všetky vybrané"
+msgstr "Spravovať Šablóny"
#: editor/editor_node.cpp
msgid ""
@@ -3005,6 +3034,13 @@ msgid ""
"the \"Use Custom Build\" option should be enabled in the Android export "
"preset."
msgstr ""
+"Toto pripraví vás projekt pre vlastný Android builds keÄ inÅ¡talujete source "
+"template do \"res://android/build\".\n"
+"Teraz môžete pridať modifikácie a tak vytvoriť vlastné APK na export "
+"(pridávanie modulov, zmeniÅ¥ AndroidManifest.xml, atÄ.).\n"
+"Poznámka že v záujme vytvorenia vlastných zostavení namiesto použitia vopred "
+"vytvorených súborov APK by mala byť v predvoľbe exportu systému Android "
+"povolená možnosť \"Use Costom Build\"."
#: editor/editor_node.cpp
msgid ""
@@ -3013,27 +3049,30 @@ msgid ""
"Remove the \"res://android/build\" directory manually before attempting this "
"operation again."
msgstr ""
+"V tomto projekte už je nainštalovaný Android build template a nemôže byť "
+"prepísaný.\n"
+"Manuálne odstránte \"res://android/build\" predtým ako sa znova pokúsite o "
+"túto operáciu."
#: editor/editor_node.cpp
msgid "Import Templates From ZIP File"
-msgstr ""
+msgstr "Importovať Šablóny Zo ZIP File-u"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Template Package"
-msgstr "Všetky vybrané"
+msgstr "BalíÄek Å ablón"
#: editor/editor_node.cpp
msgid "Export Library"
-msgstr ""
+msgstr "Exportovať Library"
#: editor/editor_node.cpp
msgid "Merge With Existing"
-msgstr ""
+msgstr "Spojiť Z Existujúcim"
#: editor/editor_node.cpp
msgid "Open & Run a Script"
-msgstr ""
+msgstr "Otvoriť & Spustiť Script"
#: editor/editor_node.cpp
#, fuzzy
@@ -9853,6 +9892,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10973,6 +11019,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Exportovať Profil"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index 8145e5e5d9..a4a668f76b 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -10214,6 +10214,13 @@ msgstr ""
"Trenutno nimate projektov.\n"
"Želite raziskovati uradne primere projektov v Asset Library?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -11354,6 +11361,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Izvozi Projekt"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/sq.po b/editor/translations/sq.po
index 19b13a126b..f24645059a 100644
--- a/editor/translations/sq.po
+++ b/editor/translations/sq.po
@@ -9860,6 +9860,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10974,6 +10981,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Eksporto Projektin"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index f83bc8bcd1..52639bbeeb 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -10335,6 +10335,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -11490,6 +11497,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Извези пројекат"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index 80ff3bc4fa..a2ae9fccea 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -9657,6 +9657,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10749,6 +10756,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index cb1d4c22d6..a03a37b533 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -10154,6 +10154,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Nyckel "
@@ -11305,6 +11312,11 @@ msgid "Total:"
msgstr "Totalt:"
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Exportera Projekt"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/ta.po b/editor/translations/ta.po
index b93e16a597..7dd9f5f38c 100644
--- a/editor/translations/ta.po
+++ b/editor/translations/ta.po
@@ -9576,6 +9576,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10663,6 +10670,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/te.po b/editor/translations/te.po
index 38d8b80709..a6c727fe89 100644
--- a/editor/translations/te.po
+++ b/editor/translations/te.po
@@ -9508,6 +9508,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10589,6 +10596,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/th.po b/editor/translations/th.po
index 3ad01b7d05..e908dde33c 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -5,7 +5,6 @@
# Kaveeta Vivatchai <goodytong@gmail.com>, 2017.
# Poommetee Ketson (Noshyaar) <poommetee@protonmail.com>, 2017-2018.
# Thanachart Monpassorn <nunf_2539@hotmail.com>, 2020.
-# anonymous <noreply@weblate.org>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
@@ -9889,6 +9888,13 @@ msgstr ""
"คุณยังไม่มีโปรเจà¸à¸•์ใด ๆ\n"
"ต้องà¸à¸²à¸£à¸ªà¸³à¸£à¸§à¸ˆà¹‚ปรเจà¸à¸•์ตัวอย่างในà¹à¸«à¸¥à¹ˆà¸‡à¸£à¸§à¸¡à¸—รัพยาà¸à¸£à¸«à¸£à¸·à¸­à¹„ม่?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "ปุ่ม "
@@ -11012,6 +11018,11 @@ msgid "Total:"
msgstr "ทั้งหมด:"
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "ส่งออà¸à¹‚ปรไฟล์"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸£à¸µà¸‹à¸­à¸£à¹Œà¸ª"
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index e5e8f0ba97..fdb8f76605 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -43,12 +43,13 @@
# HALİL ATAŞ <halillatass@gmail.com>, 2019.
# Zsosu Ktosu <zktosu@gmail.com>, 2020.
# Mesut Aslan <kontinyu@gmail.com>, 2020.
+# Kaan Genç <kaan@kaangenc.me>, 2020.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-11 12:20+0000\n"
-"Last-Translator: Mesut Aslan <kontinyu@gmail.com>\n"
+"PO-Revision-Date: 2020-04-23 20:21+0000\n"
+"Last-Translator: Anonymous <noreply@weblate.org>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot/tr/>\n"
"Language: tr\n"
@@ -56,7 +57,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2961,13 +2962,12 @@ msgid "Q&A"
msgstr "S&C"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Yeniden İçe Aktar"
+msgstr "Hata Bildir"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Belgelendirme Hatası Bildir"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4018,7 +4018,6 @@ msgid "Reimport"
msgstr "Yeniden İçe Aktar"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
msgstr "Sahneleri kaydet, tekrar içe aktar ve baştan başlat"
@@ -5904,16 +5903,15 @@ msgstr "Tekil Dışbükey Şekil Oluştur"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Can't create multiple convex collision shapes for the scene root."
-msgstr ""
+msgstr "Sahne kökü için birden fazla dışbükey çarpışma şekli oluşturulamaz."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Couldn't create any collision shapes."
msgstr "Herhangi bir çarpışma şekli oluşturulamadı."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Multiple Convex Shapes"
-msgstr "Dışbükey Şekil[ler] Oluştur"
+msgstr "Dışbükey Şekilleri Oluştur"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Navigation Mesh"
@@ -5969,6 +5967,9 @@ msgid ""
"automatically.\n"
"This is the most accurate (but slowest) option for collision detection."
msgstr ""
+"Bir StaticBody oluşturur ve otomatik olarak çokgen tabanlı bir çarpışma "
+"ÅŸekli atar.\n"
+"Bu, çarpışma tespiti için en doğru (ancak en yavaş) seçenektir."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Collision Sibling"
@@ -5983,7 +5984,6 @@ msgstr ""
"Bu en hassas (fakat en yavaş) çarpışma algılama seçeneğidir."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Collision Sibling"
msgstr "Dışbükey Çarpışma Komşusu Oluştur"
@@ -5992,17 +5992,20 @@ msgid ""
"Creates a single convex collision shape.\n"
"This is the fastest (but least accurate) option for collision detection."
msgstr ""
+"Tek bir dışbükey çarpışma şekli oluşturur.\n"
+"Bu, çarpışma tespiti için en hızlı (ancak en az doğru) seçenektir."
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Multiple Convex Collision Siblings"
-msgstr "Dışbükey Çarpışma Komşusu Oluştur"
+msgstr "Dışbükey Çarpışma Komşuları Oluştur"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
"Creates a polygon-based collision shape.\n"
"This is a performance middle-ground between the two above options."
msgstr ""
+"Poligon bazlı bir çarpışma şekli oluştur.\n"
+"Bu performans açısından üstteki iki seçeneğin arasındadır."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Outline Mesh..."
@@ -6015,6 +6018,10 @@ msgid ""
"This can be used instead of the SpatialMaterial Grow property when using "
"that property isn't possible."
msgstr ""
+"Durgun bir anahat kafesi oluÅŸturur. Anahat kafesi normalleri otomatik olarak "
+"döndürülecekdir.\n"
+"Bu SpatialMaterial Grow özelliği kullanılamadığı zaman onun yerine "
+"kullanılabilir."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "View UV1"
@@ -7298,9 +7305,8 @@ msgid "This operation requires a single selected node."
msgstr "Bu işlem, seçilmiş tek bir düğüm gerektirir."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Dikey"
+msgstr "Otomatik Dikey EtkinleÅŸtirildi"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -9585,32 +9591,27 @@ msgid "Export With Debug"
msgstr "Hata Ayıklama İle Dışa Aktar"
#: editor/project_manager.cpp
-#, fuzzy
msgid "The path specified doesn't exist."
-msgstr "Yol mevcut deÄŸil."
+msgstr "Belirtilen yol mevcut deÄŸil."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Error opening package file (it's not in ZIP format)."
-msgstr "Paket dosyası açılırken hata oluştu, zip formatında değil."
+msgstr "Paket dosyası açılırken hata (ZIP formatında değil)."
#: editor/project_manager.cpp
-#, fuzzy
msgid ""
"Invalid \".zip\" project file; it doesn't contain a \"project.godot\" file."
-msgstr "Geçersiz '.zip' proje dosyası, 'project.godot' dosyası içermiyor."
+msgstr "Geçersiz \".zip\" proje dosyası; \"project.godot\" dosyası içermiyor."
#: editor/project_manager.cpp
msgid "Please choose an empty folder."
msgstr "Lütfen boş bir klasör seçin."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Please choose a \"project.godot\" or \".zip\" file."
-msgstr "Lütfen bir 'project.godot' veya '.zip' dosyası seçin."
+msgstr "Lütfen bir \"project.godot\" veya \".zip\" dosyası seçin."
#: editor/project_manager.cpp
-#, fuzzy
msgid "This directory already contains a Godot project."
msgstr "Bu dizinde zaten bir Godot projesi var."
@@ -9920,6 +9921,13 @@ msgstr ""
"Herhangi bir projen yok.\n"
"Varlık Kütüphanesi'ndeki resmî örnek projeleri incelemek ister misin?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Anahtar "
@@ -10309,9 +10317,8 @@ msgid "Suffix"
msgstr "Son Ek"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Use Regular Expressions"
-msgstr "Düzenli İfadeler"
+msgstr "Düzenli İfadeler Kullan"
#: editor/rename_dialog.cpp
msgid "Advanced Options"
@@ -10350,9 +10357,8 @@ msgstr ""
"Sayaç seçeneklerini karşılaştırın."
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Per-level Counter"
-msgstr "Seviye Başına sayaç"
+msgstr "Seviye Başına Sayaç"
#: editor/rename_dialog.cpp
msgid "If set the counter restarts for each group of child nodes"
@@ -10391,12 +10397,10 @@ msgid "Keep"
msgstr "Tut"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "PascalCase to snake_case"
msgstr "DeveŞekilli'den alt_tireli'ye dönüştür"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "snake_case to PascalCase"
msgstr "alt_tireli'den DeveŞekilli'ye dönüştür"
@@ -10417,9 +10421,8 @@ msgid "Reset"
msgstr "Sıfırla"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Regular Expression Error"
-msgstr "Düzenli İfadeler"
+msgstr "Düzenli İfade Hatası"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10889,9 +10892,8 @@ msgid "Invalid inherited parent name or path."
msgstr "Geçersiz devralınan üst ad veya yol."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script path/name is valid."
-msgstr "Betik geçerli."
+msgstr "Betik yolu/adı geçerli."
#: editor/script_create_dialog.cpp
msgid "Allowed: a-z, A-Z, 0-9, _ and ."
@@ -10918,6 +10920,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Not: Gömülü betikler bazı sınırlandırmalara mahsustur ve dış bir düzenleyici "
+"ile düzenlenemezler."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -10988,7 +10992,6 @@ msgid "Copy Error"
msgstr "Hatayı Kopyala"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Video RAM"
msgstr "Görüntü Belleği"
@@ -11041,6 +11044,11 @@ msgid "Total:"
msgstr "Toplam:"
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Profil Dışa Aktar"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "Kaynak Yolu"
@@ -12392,6 +12400,7 @@ msgstr ""
msgid ""
"ConcavePolygonShape doesn't support RigidBody in another mode than static."
msgstr ""
+"ConcavePolygonShape static dışında bir modda RigidBody'i desteklemiyor."
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
@@ -12694,6 +12703,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
+"Herhangi bir şeyi işlemek için görüntükapısı boyutu 0'dan büyük olmalıdır."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index 60e61d3bf7..e713e79a4c 100644
--- a/editor/translations/uk.po
+++ b/editor/translations/uk.po
@@ -17,7 +17,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Ukrainian (Godot Engine)\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-03-18 00:10+0000\n"
+"PO-Revision-Date: 2020-05-01 11:43+0000\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/"
"godot/uk/>\n"
@@ -27,7 +27,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.2\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2945,13 +2945,12 @@ msgid "Q&A"
msgstr "Ð—Ð°Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ‚Ð° відповіді"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "Переімпортувати"
+msgstr "Повідомити про ваду"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "ÐадіÑлати відгук щодо документації"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -4006,7 +4005,6 @@ msgid "Reimport"
msgstr "Переімпортувати"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
msgstr "Зберегти Ñцени, повторно імпортувати Ñ– перезапуÑтити"
@@ -7307,9 +7305,8 @@ msgid "This operation requires a single selected node."
msgstr "Ð¦Ñ Ð¾Ð¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð²Ð¸Ð¼Ð°Ð³Ð°Ñ” одного обраного вузла."
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "Ортогонально"
+msgstr "Увімкнено автоматичну ортогоналізацію"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -9934,6 +9931,16 @@ msgstr ""
"Зараз проєктів немає.\n"
"Хочете вивчити проєкти офіційних прикладів з бібліотеки даних?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"Поле пошуку фільтрує проєкти за назвою Ñ– оÑтаннім компонентом шлÑху.\n"
+"Щоб виконати Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñ–Ð² за назвою Ñ– повним шлÑхом, у запиті має "
+"бути принаймні один Ñимвол `/`."
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "Клавіша "
@@ -10927,6 +10934,8 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"ЗауваженнÑ: Ð´Ð»Ñ Ð²Ð±ÑƒÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ… Ñкриптів передбачено певні Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ â€” Ñ—Ñ… не "
+"можна редагувати у зовнішньому редакторі."
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -11049,6 +11058,10 @@ msgid "Total:"
msgstr "Загалом:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "ЕкÑпортувати ÑпиÑок до файла CSV"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "ШлÑÑ… до реÑурÑу"
@@ -12728,6 +12741,8 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
msgstr ""
+"Щоб програма могла хоч щоÑÑŒ показати, розмір Ð¿Ð¾Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду має бути більшим "
+"за 0."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index 1e2f87b352..432a8d1137 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -9746,6 +9746,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10851,6 +10858,10 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr ""
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index 88ca61847e..a52a3dedf3 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -9866,6 +9866,13 @@ msgstr ""
"Hiện giỠbạn không có project nào.\n"
"Bạn có muốn xem các project official ví dụ trên Asset Library không?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10997,6 +11004,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "Xuất hồ sơ"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index df8b8e1725..538e017a5d 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -64,7 +64,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Chinese (Simplified) (Godot Engine)\n"
"POT-Creation-Date: 2018-01-20 12:15+0200\n"
-"PO-Revision-Date: 2020-04-05 12:05+0000\n"
+"PO-Revision-Date: 2020-05-01 11:42+0000\n"
"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hans/>\n"
@@ -73,7 +73,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.0-dev\n"
+"X-Generator: Weblate 4.0.2\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2919,13 +2919,12 @@ msgid "Q&A"
msgstr "问答"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Report a Bug"
-msgstr "釿–°å¯¼å…¥"
+msgstr "报告问题"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "å‘逿–‡æ¡£å馈"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3962,9 +3961,8 @@ msgid "Reimport"
msgstr "釿–°å¯¼å…¥"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Save Scenes, Re-Import, and Restart"
-msgstr "ä¿å­˜åœºæ™¯ï¼Œé‡æ–°å¯¼å…¥ï¼Œä»Žå¤´å¼€å§‹"
+msgstr "ä¿å­˜åœºæ™¯ã€é‡æ–°å¯¼å…¥ï¼Œç„¶åŽé‡å¯"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
@@ -5681,7 +5679,7 @@ msgstr "从åƒç´ æ•获"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Emission Colors"
-msgstr "Emission Colors(å‘射颜色)"
+msgstr "Emission Colors(自å‘光颜色)"
#: editor/plugins/cpu_particles_editor_plugin.cpp
msgid "CPUParticles"
@@ -5903,7 +5901,6 @@ msgstr ""
"这是最准确(但是最慢)的碰撞检测手段。"
#: editor/plugins/mesh_instance_editor_plugin.cpp
-#, fuzzy
msgid "Create Single Convex Collision Sibling"
msgstr "创建å•一凸碰撞åŒçº§"
@@ -7213,9 +7210,8 @@ msgid "This operation requires a single selected node."
msgstr "æ­¤æ“作åªèƒ½åº”用于å•个选中节点。"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Auto Orthogonal Enabled"
-msgstr "正交"
+msgstr "å¯ç”¨è‡ªåŠ¨æ­£äº¤"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
@@ -9770,6 +9766,15 @@ msgstr ""
"ä½ ç›®å‰æ²¡æœ‰ä»»ä½•项目。 \n"
"æ˜¯å¦æŸ¥çœ‹ç´ æåº“中的官方示例项目?"
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+"æœç´¢æ¡†æ ¹æ®å称和路径的末尾部分æ¥è¿‡æ»¤é¡¹ç›®ã€‚\n"
+"å¦‚æžœè¦æ ¹æ®å称和完整路径过滤,æœç´¢å†…容应至少包å«ä¸€ä¸ªâ€œ/â€å­—符。"
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr "é”® "
@@ -10746,7 +10751,7 @@ msgstr "脚本文件已存在。"
msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
-msgstr ""
+msgstr "注æ„ï¼šå†…ç½®è„šæœ¬æœ‰å…¶å±€é™æ€§ï¼Œå¹¶ä¸”ä¸èƒ½ä½¿ç”¨å¤–部编辑器编辑。"
#: editor/script_create_dialog.cpp
msgid "Class Name:"
@@ -10869,6 +10874,10 @@ msgid "Total:"
msgstr "åˆè®¡:"
#: editor/script_editor_debugger.cpp
+msgid "Export list to a CSV file"
+msgstr "将列表导出为CSV文件"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "资æºè·¯å¾„"
@@ -12161,7 +12170,7 @@ msgstr "å¹³é¢å½¢çŠ¶æ— æ³•æ­£å¸¸å·¥ä½œï¼Œæœªæ¥ç‰ˆæœ¬å°†è¢«åˆ é™¤ã€‚请勿使用
#: scene/3d/collision_shape.cpp
msgid ""
"ConcavePolygonShape doesn't support RigidBody in another mode than static."
-msgstr ""
+msgstr "ConcavePolygonShape仅支æŒé™æ€RigidBody。"
#: scene/3d/cpu_particles.cpp
msgid "Nothing is visible because no mesh has been assigned."
@@ -12439,7 +12448,7 @@ msgstr ""
#: scene/main/viewport.cpp
msgid "Viewport size must be greater than 0 to render anything."
-msgstr ""
+msgstr "Viewport大å°å¤§äºŽ0æ—¶æ‰èƒ½è¿›è¡Œæ¸²æŸ“。"
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index 31306885ae..770b4d38f2 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -2,27 +2,28 @@
# Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.
# Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).
# This file is distributed under the same license as the Godot source code.
-# Wesley (zx-wt) <ZX_WT@ymail.com>, 2016-2017.
+# Wesley (zx-wt) <ZX_WT@ymail.com>, 2016-2017, 2020.
# cnieFIT <dtotncq@gmail.com>, 2019.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2019-04-10 00:46+0000\n"
-"Last-Translator: cnieFIT <dtotncq@gmail.com>\n"
-"Language-Team: Chinese (Hong Kong) <https://hosted.weblate.org/projects/"
-"godot-engine/godot/zh_Hant_HK/>\n"
+"PO-Revision-Date: 2020-05-01 11:43+0000\n"
+"Last-Translator: zx-wt <ZX_WT@ymail.com>\n"
+"Language-Team: Chinese (Traditional, Hong Kong) <https://hosted.weblate.org/"
+"projects/godot-engine/godot/zh_Hant_HK/>\n"
"Language: zh_HK\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 3.6-dev\n"
+"X-Generator: Weblate 4.0.2\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
+#, fuzzy
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr ""
+msgstr "convert()çš„é¡žåž‹åƒæ•¸ç„¡æ•ˆ, 請使用 TYPE_* 常數。"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
@@ -68,19 +69,19 @@ msgstr ""
#: core/ustring.cpp
msgid "KiB"
-msgstr ""
+msgstr "KiB"
#: core/ustring.cpp
msgid "MiB"
-msgstr ""
+msgstr "MiB"
#: core/ustring.cpp
msgid "GiB"
-msgstr ""
+msgstr "GiB"
#: core/ustring.cpp
msgid "TiB"
-msgstr ""
+msgstr "TiB"
#: core/ustring.cpp
msgid "PiB"
@@ -88,20 +89,19 @@ msgstr ""
#: core/ustring.cpp
msgid "EiB"
-msgstr ""
+msgstr "PiB"
#: editor/animation_bezier_editor.cpp
msgid "Free"
-msgstr ""
+msgstr "自由"
#: editor/animation_bezier_editor.cpp
msgid "Balanced"
-msgstr ""
+msgstr "å¹³å‡"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Mirror"
-msgstr "錯誤!"
+msgstr "å°ç¨±"
#: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp
msgid "Time:"
@@ -112,9 +112,8 @@ msgid "Value:"
msgstr ""
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Insert Key Here"
-msgstr "å‹•æ™æ’入關éµå¹€ï¼Ÿ"
+msgstr "在這æ’入關éµå¹€"
#: editor/animation_bezier_editor.cpp
#, fuzzy
@@ -127,14 +126,12 @@ msgid "Delete Selected Key(s)"
msgstr "刪除é¸ä¸­æª”案"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Add Bezier Point"
-msgstr "新增訊號"
+msgstr "新增Bezier節點"
#: editor/animation_bezier_editor.cpp
-#, fuzzy
msgid "Move Bezier Points"
-msgstr "下移"
+msgstr "Bezier節點下移"
#: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp
msgid "Anim Duplicate Keys"
@@ -158,9 +155,8 @@ msgid "Anim Change Transform"
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Change Keyframe Value"
-msgstr "動畫變化數值"
+msgstr "動畫變化關éµå¹€æ•¸å€¼"
#: editor/animation_track_editor.cpp
msgid "Anim Change Call"
@@ -199,7 +195,7 @@ msgstr "更改動畫å稱:"
#: editor/animation_track_editor.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation Loop"
-msgstr ""
+msgstr "變更動畫循環"
#: editor/animation_track_editor.cpp
msgid "Property Track"
@@ -241,23 +237,21 @@ msgid "Add Track"
msgstr "新增動畫軌跡"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation Looping"
-msgstr "動畫縮放。"
+msgstr "動畫循環"
#: editor/animation_track_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Functions:"
-msgstr "行為"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Audio Clips:"
-msgstr ""
+msgstr "è²éŸ³ç‰‡æ®µï¼š"
#: editor/animation_track_editor.cpp
msgid "Anim Clips:"
-msgstr ""
+msgstr "動畫片段:"
#: editor/animation_track_editor.cpp
msgid "Change Track Path"
@@ -272,9 +266,8 @@ msgid "Update Mode (How this property is set)"
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Interpolation Mode"
-msgstr "無干擾模å¼"
+msgstr "模å¼"
#: editor/animation_track_editor.cpp
msgid "Loop Wrap Mode (Interpolate end with beginning on loop)"
@@ -311,11 +304,11 @@ msgstr "發動"
#: editor/animation_track_editor.cpp
msgid "Capture"
-msgstr ""
+msgstr "æ•æ‰"
#: editor/animation_track_editor.cpp
msgid "Nearest"
-msgstr ""
+msgstr "最近"
#: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp
#: editor/property_editor.cpp
@@ -337,7 +330,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Insert Key"
-msgstr ""
+msgstr "æ’入動畫幀"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -447,16 +440,15 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
-msgstr ""
+msgstr "沒有ROOT以新增新動畫軌跡"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Add Bezier Track"
-msgstr "新增動畫軌跡"
+msgstr "新增Bezier軌跡"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
@@ -571,14 +563,12 @@ msgid "Edit"
msgstr "編輯"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation properties."
-msgstr "新增動畫"
+msgstr "動畫內容。"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Copy Tracks"
-msgstr "è¤‡è£½åƒæ•¸"
+msgstr "複製"
#: editor/animation_track_editor.cpp
msgid "Scale Selection"
@@ -701,9 +691,8 @@ msgid "Select All/None"
msgstr "ä¸é¸"
#: editor/animation_track_editor_plugins.cpp
-#, fuzzy
msgid "Add Audio Track Clip"
-msgstr "新增動畫軌跡"
+msgstr "新增è²éŸ³è»Œè·¡ç‰‡æ®µ"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
@@ -734,18 +723,16 @@ msgid "Line Number:"
msgstr "行數:"
#: editor/code_editor.cpp
-#, fuzzy
msgid "%d replaced."
-msgstr "å–代"
+msgstr "å·²å–代 %d。"
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
msgstr ""
#: editor/code_editor.cpp editor/editor_help.cpp
-#, fuzzy
msgid "%d matches."
-msgstr "沒有相åŒ"
+msgstr "%d 相åŒã€‚"
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -795,7 +782,7 @@ msgstr "é‡è¨­ç¸®æ”¾æ¯”例"
#: editor/code_editor.cpp
msgid "Warnings"
-msgstr ""
+msgstr "警告"
#: editor/code_editor.cpp
msgid "Line and column numbers."
@@ -817,18 +804,16 @@ msgid "Connect to Node:"
msgstr "連到:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Connect to Script:"
-msgstr "ä¸èƒ½é€£åˆ°ä¸»æ©Ÿï¼š"
+msgstr "連到腳本:"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "From Signal:"
-msgstr "訊號:"
+msgstr "來自訊號:"
#: editor/connections_dialog.cpp
msgid "Scene does not contain any script."
-msgstr ""
+msgstr "å ´æ™¯æ²’æœ‰å«æœ‰ä»»ä½•腳本。"
#: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp
#: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp
@@ -856,17 +841,16 @@ msgid "Extra Call Arguments:"
msgstr ""
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Receiver Method:"
-msgstr "鏿“‡æ¨¡å¼"
+msgstr "接收模å¼ï¼š"
#: editor/connections_dialog.cpp
msgid "Advanced"
-msgstr ""
+msgstr "進階"
#: editor/connections_dialog.cpp
msgid "Deferred"
-msgstr ""
+msgstr "å»¶é²"
#: editor/connections_dialog.cpp
msgid ""
@@ -875,16 +859,15 @@ msgstr ""
#: editor/connections_dialog.cpp
msgid "Oneshot"
-msgstr ""
+msgstr "åªé™ä¸€æ¬¡"
#: editor/connections_dialog.cpp
msgid "Disconnects the signal after its first emission."
msgstr ""
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Cannot connect signal"
-msgstr "連接訊號:"
+msgstr "無法連接訊號"
#: editor/connections_dialog.cpp editor/dependency_editor.cpp
#: editor/export_template_manager.cpp editor/groups_editor.cpp
@@ -956,9 +939,8 @@ msgid "Are you sure you want to remove all connections from this signal?"
msgstr ""
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Disconnect All"
-msgstr "中斷"
+msgstr "中斷全部"
#: editor/connections_dialog.cpp
#, fuzzy
@@ -1142,7 +1124,7 @@ msgstr "刪除"
#: editor/dependency_editor.cpp
msgid "Owns"
-msgstr ""
+msgstr "æ“æœ‰"
#: editor/dependency_editor.cpp
msgid "Resources Without Explicit Ownership:"
@@ -1166,19 +1148,16 @@ msgid "Godot Engine contributors"
msgstr "Godot Engine è²¢ç»è€…"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Project Founders"
-msgstr "專案設定"
+msgstr "專案開è’人"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Lead Developer"
-msgstr "開發者"
+msgstr "主è¦é–‹ç™¼è€…"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Project Manager "
-msgstr "開啟 Project Manager?"
+msgstr "開啟 Project Manager "
#: editor/editor_about.cpp
msgid "Developers"
@@ -1210,7 +1189,7 @@ msgstr "ç™½éŠ€ç´šææ¬¾äºº"
#: editor/editor_about.cpp
msgid "Bronze Donors"
-msgstr "é’éŠ…ææ¬¾äºº"
+msgstr "é’éŠ…ç´šææ¬¾äºº"
#: editor/editor_about.cpp
msgid "Donors"
@@ -1304,14 +1283,12 @@ msgid "Add Effect"
msgstr "新增效果"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Rename Audio Bus"
-msgstr "釿–°å‘½åAutoload"
+msgstr "釿–°å‘½åAudio Bus"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Change Audio Bus Volume"
-msgstr "動畫變化數值"
+msgstr "變更Audio Busè²é‡"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Solo"
@@ -1338,9 +1315,8 @@ msgid "Move Bus Effect"
msgstr ""
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Delete Bus Effect"
-msgstr "刪除é¸ä¸­æª”案"
+msgstr "刪除Bus Effect"
#: editor/editor_audio_buses.cpp
msgid "Drag & drop to rearrange."
@@ -1348,7 +1324,7 @@ msgstr ""
#: editor/editor_audio_buses.cpp
msgid "Solo"
-msgstr ""
+msgstr "Solo"
#: editor/editor_audio_buses.cpp
msgid "Mute"
@@ -1367,7 +1343,7 @@ msgstr "é¸é …"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Duplicate"
-msgstr "複製"
+msgstr "å†è£½"
#: editor/editor_audio_buses.cpp
#, fuzzy
@@ -1397,9 +1373,8 @@ msgid "Delete Audio Bus"
msgstr "刪除佈局"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Duplicate Audio Bus"
-msgstr "複製"
+msgstr "å†è£½ Audio Bus"
#: editor/editor_audio_buses.cpp
#, fuzzy
@@ -1407,9 +1382,8 @@ msgid "Reset Bus Volume"
msgstr "é‡è¨­ç¸®æ”¾æ¯”例"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Move Audio Bus"
-msgstr "移動"
+msgstr "移動 Audio Bus"
#: editor/editor_audio_buses.cpp
msgid "Save Audio Bus Layout As..."
@@ -1428,9 +1402,8 @@ msgid "There is no '%s' file."
msgstr ""
#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Layout"
-msgstr "儲存佈局"
+msgstr "佈局"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
@@ -1483,7 +1456,7 @@ msgstr ""
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
-msgstr "無效å稱"
+msgstr "無效å稱。"
#: editor/editor_autoload_settings.cpp
#, fuzzy
@@ -1491,19 +1464,16 @@ msgid "Valid characters:"
msgstr "有效字符:"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing engine class name."
-msgstr "有效å稱。"
+msgstr ""
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing built-in type name."
-msgstr "有效å稱。"
+msgstr ""
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing global constant name."
-msgstr "有效å稱。"
+msgstr ""
#: editor/editor_autoload_settings.cpp
msgid "Keyword cannot be used as an autoload name."
@@ -1571,7 +1541,7 @@ msgstr "路徑:"
#: editor/editor_autoload_settings.cpp
msgid "Node Name:"
-msgstr ""
+msgstr "Nodeå稱"
#: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp
#: editor/editor_profiler.cpp editor/project_manager.cpp
@@ -1602,16 +1572,15 @@ msgstr "正在更新場景..."
#: editor/editor_data.cpp editor/editor_properties.cpp
msgid "[empty]"
-msgstr ""
+msgstr "[空]"
#: editor/editor_data.cpp
msgid "[unsaved]"
-msgstr ""
+msgstr "[未儲存]"
#: editor/editor_dir_dialog.cpp
-#, fuzzy
msgid "Please select a base directory first."
-msgstr "請先儲存場景"
+msgstr "è«‹å…ˆé¸æ“‡ä¸»è¦è³‡æ–™å¤¾ã€‚"
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
@@ -1674,9 +1643,8 @@ msgstr ""
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
-#, fuzzy
msgid "Custom debug template not found."
-msgstr "未找到佈局å稱ï¼"
+msgstr ""
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
@@ -1685,23 +1653,20 @@ msgid "Custom release template not found."
msgstr ""
#: editor/editor_export.cpp platform/javascript/export/export.cpp
-#, fuzzy
msgid "Template file not found:"
-msgstr "未找到佈局å稱ï¼"
+msgstr ""
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
msgstr ""
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "3D Editor"
-msgstr "編輯器"
+msgstr "3D編輯器"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Script Editor"
-msgstr "開啟資料夾"
+msgstr ""
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1747,9 +1712,8 @@ msgid "(Editor Disabled, Properties Disabled)"
msgstr ""
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "(Properties Disabled)"
-msgstr "鏿“‡æ¨¡å¼"
+msgstr ""
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1799,9 +1763,8 @@ msgid "Unset"
msgstr ""
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "新增資料夾"
+msgstr ""
#: editor/editor_feature_profile.cpp
msgid "Make Current"
@@ -1881,15 +1844,13 @@ msgid "Copy Path"
msgstr "複製路徑"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "Open in File Manager"
-msgstr "開啟 Project Manager?"
+msgstr "在Project Manager開啟"
#: editor/editor_file_dialog.cpp editor/editor_node.cpp
#: editor/filesystem_dock.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Show in File Manager"
-msgstr "開啟 Project Manager?"
+msgstr "在Project Manager顯示"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
#, fuzzy
@@ -1903,7 +1864,7 @@ msgstr "釿–°æ•´ç†"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Recognized"
-msgstr "所有類型"
+msgstr "所有已知類型"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Files (*)"
@@ -1915,7 +1876,7 @@ msgstr "開啟檔案"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open File(s)"
-msgstr "開啟檔案"
+msgstr "開啟(多個)檔案"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Open a Directory"
@@ -1937,16 +1898,18 @@ msgid "Save a File"
msgstr "儲存檔案"
#: editor/editor_file_dialog.cpp
+#, fuzzy
msgid "Go Back"
-msgstr ""
+msgstr "å‘後"
#: editor/editor_file_dialog.cpp
+#, fuzzy
msgid "Go Forward"
-msgstr ""
+msgstr "å‘å‰"
#: editor/editor_file_dialog.cpp
msgid "Go Up"
-msgstr ""
+msgstr "å‘上"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
@@ -1975,14 +1938,12 @@ msgid "Move Favorite Down"
msgstr "下移最愛"
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to previous folder."
-msgstr "無法新增資料夾"
+msgstr "回到上一個資料夾。"
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to next folder."
-msgstr "無法新增資料夾"
+msgstr "下一個資料夾"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
#, fuzzy
@@ -2028,7 +1989,7 @@ msgstr "檔案:"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Must use a valid extension."
-msgstr "請用有效的副檔å"
+msgstr "請用有效的副檔å。"
#: editor/editor_file_system.cpp
msgid "ScanSources"
@@ -2069,13 +2030,12 @@ msgid "Description"
msgstr "æè¿°ï¼š"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Online Tutorials"
-msgstr "關閉場景"
+msgstr "Online教學"
#: editor/editor_help.cpp
msgid "Properties"
-msgstr ""
+msgstr "內客"
#: editor/editor_help.cpp
msgid "override:"
@@ -2158,29 +2118,24 @@ msgid "Classes Only"
msgstr ""
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Methods Only"
-msgstr "鏿“‡æ¨¡å¼"
+msgstr ""
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Signals Only"
-msgstr "訊號"
+msgstr "åªé™è¨Šè™Ÿ"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Constants Only"
-msgstr "常數"
+msgstr "åªé™å¸¸æ•¸"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Properties Only"
-msgstr "鏿“‡æ¨¡å¼"
+msgstr "åªé™å…§å®¹"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Theme Properties Only"
-msgstr "鏿“‡æ¨¡å¼"
+msgstr ""
#: editor/editor_help_search.cpp
msgid "Member Type"
@@ -2191,9 +2146,8 @@ msgid "Class"
msgstr ""
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Method"
-msgstr "鏿“‡æ¨¡å¼"
+msgstr ""
#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -2205,14 +2159,12 @@ msgid "Constant"
msgstr "常數"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Property"
-msgstr "鏿“‡æ¨¡å¼"
+msgstr "內容"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Theme Property"
-msgstr "篩é¸:"
+msgstr ""
#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
msgid "Property:"
@@ -2231,9 +2183,8 @@ msgid "Output:"
msgstr ""
#: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Copy Selection"
-msgstr "移除é¸é …"
+msgstr "複製é¸é …"
#: editor/editor_log.cpp editor/editor_network_profiler.cpp
#: editor/editor_profiler.cpp editor/editor_properties.cpp
@@ -2265,9 +2216,8 @@ msgid "%s/s"
msgstr ""
#: editor/editor_network_profiler.cpp
-#, fuzzy
msgid "Down"
-msgstr "下載"
+msgstr ""
#: editor/editor_network_profiler.cpp
msgid "Up"
@@ -2322,14 +2272,12 @@ msgid "Save Resource As..."
msgstr "把資æºå¦å­˜ç‚º..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Can't open file for writing:"
-msgstr "ä¸èƒ½å¯«å…¥ï¼Œä¸èƒ½é–‹å•Ÿæª”案:"
+msgstr "ä¸èƒ½é–‹å•Ÿæª”案以供寫入:"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Requested file format unknown:"
-msgstr "è¦æ±‚çš„æª”æ¡ˆæ ¼å¼æœªçŸ¥ï¼š"
+msgstr "è¦æ±‚的檔案格å¼ä¸æ˜Žï¼š"
#: editor/editor_node.cpp
msgid "Error while saving."
@@ -3501,15 +3449,16 @@ msgstr "你是å¦å¿˜äº†é—œéµè©ž 'tool' ?"
#: editor/editor_run_script.cpp
msgid "Couldn't run script:"
-msgstr ""
+msgstr "ä¸èƒ½åŸ·è¡Œè…³æœ¬ï¼š"
#: editor/editor_run_script.cpp
msgid "Did you forget the '_run' method?"
msgstr ""
#: editor/editor_sub_scene.cpp
+#, fuzzy
msgid "Select Node(s) to Import"
-msgstr ""
+msgstr "鏿“‡è¦å°Žå…¥çš„Node(s)"
#: editor/editor_sub_scene.cpp editor/project_manager.cpp
msgid "Browse"
@@ -3521,7 +3470,7 @@ msgstr "場景路徑:"
#: editor/editor_sub_scene.cpp
msgid "Import From Node:"
-msgstr ""
+msgstr "從Node導入:"
#: editor/export_template_manager.cpp
#, fuzzy
@@ -3542,59 +3491,66 @@ msgid "Download"
msgstr "下載"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Official export templates aren't available for development builds."
-msgstr ""
+msgstr "Development builds未能æä¾›å®˜æ–¹export templates。"
#: editor/export_template_manager.cpp
msgid "(Missing)"
-msgstr ""
+msgstr "(欠缺)"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "(Current)"
-msgstr ""
+msgstr "(Current)"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Retrieving mirrors, please wait..."
-msgstr ""
+msgstr "接收 mirrors中, è«‹ç¨ä¾¯..."
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Remove template version '%s'?"
-msgstr ""
+msgstr "移除版本 '%s' 的範本?"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Can't open export templates zip."
-msgstr ""
+msgstr "ä¸èƒ½é–‹å•Ÿexport templatesçš„zip壓縮檔。"
#: editor/export_template_manager.cpp
#, fuzzy
msgid "Invalid version.txt format inside templates: %s."
-msgstr "無效的 version.txt æ ¼å¼ inside templates."
+msgstr "範本文件: %s 中的 version.txt æ ¼å¼ç„¡æ•ˆã€‚"
#: editor/export_template_manager.cpp
#, fuzzy
msgid "No version.txt found inside templates."
-msgstr "找ä¸åˆ°version.txt inside templates."
+msgstr "範本中找ä¸åˆ°version.txt。"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Error creating path for templates:"
-msgstr "載入字形出ç¾éŒ¯èª¤"
+msgstr "範本創造路徑時出ç¾éŒ¯èª¤ï¼š"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Extracting Export Templates"
-msgstr ""
+msgstr "正在解壓Export Templates"
#: editor/export_template_manager.cpp
msgid "Importing:"
-msgstr "導入中:"
+msgstr "導入中:"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Error getting the list of mirrors."
-msgstr ""
+msgstr "å–å¾—mirrors列表時出錯。"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Error parsing JSON of mirror list. Please report this issue!"
-msgstr ""
+msgstr "parsing mirror列表的JSON出錯。 請回報此å•題ï¼"
#: editor/export_template_manager.cpp
#, fuzzy
@@ -3605,8 +3561,9 @@ msgstr "找ä¸åˆ°é€™å€‹ç‰ˆæœ¬çš„下載連çµã€‚直接下載åªé©ç”¨æ–¼official
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
+#, fuzzy
msgid "Can't resolve."
-msgstr ""
+msgstr "無法解決。"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -3624,8 +3581,9 @@ msgid "Request Failed."
msgstr "請求失敗。"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Redirect Loop."
-msgstr ""
+msgstr "釿–°å®šå‘循環。"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -3633,49 +3591,49 @@ msgid "Failed:"
msgstr "失敗:"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Download Complete."
-msgstr "下載出ç¾éŒ¯èª¤"
+msgstr "下載完æˆã€‚"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Cannot remove temporary file:"
-msgstr "無法移除:\n"
+msgstr "無法移除暫存檔:"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid ""
"Templates installation failed.\n"
"The problematic templates archives can be found at '%s'."
msgstr ""
+"Templates安è£å¤±æ•—。\n"
+"出ç¾å•題的templates 存檔å¯ä»¥åœ¨ \"%s\" 中找到。"
#: editor/export_template_manager.cpp
#, fuzzy
msgid "Error requesting URL:"
-msgstr "請求時出ç¾éŒ¯èª¤"
+msgstr "請求URL時出ç¾éŒ¯èª¤ï¼š"
#: editor/export_template_manager.cpp
#, fuzzy
msgid "Connecting to Mirror..."
-msgstr "連到..."
+msgstr "正在連到Mirror..."
#: editor/export_template_manager.cpp
#, fuzzy
msgid "Disconnected"
-msgstr "中斷"
+msgstr "æ–·ç·š"
#: editor/export_template_manager.cpp
msgid "Resolving"
-msgstr ""
+msgstr "解決中"
#: editor/export_template_manager.cpp
msgid "Can't Resolve"
-msgstr ""
+msgstr "ä¸èƒ½è§£æ±º"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Connecting..."
-msgstr "連到..."
+msgstr "連接中..."
#: editor/export_template_manager.cpp
#, fuzzy
@@ -3685,7 +3643,7 @@ msgstr "ä¸èƒ½é€£æŽ¥ã€‚"
#: editor/export_template_manager.cpp
#, fuzzy
msgid "Connected"
-msgstr "連到"
+msgstr "已連線"
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -3695,63 +3653,61 @@ msgstr "請求中..."
#: editor/export_template_manager.cpp
#, fuzzy
msgid "Downloading"
-msgstr "下載出ç¾éŒ¯èª¤"
+msgstr "下載中"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Connection Error"
-msgstr "連到..."
+msgstr "連接出錯"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "SSL Handshake Error"
-msgstr ""
+msgstr "SSL Handshake出錯"
#: editor/export_template_manager.cpp
#, fuzzy
msgid "Uncompressing Android Build Sources"
-msgstr "導入中:"
+msgstr "正在解壓Android Build Sources"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Current Version:"
-msgstr ""
+msgstr "ç•¶å‰ç‰ˆæœ¬ï¼š"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Installed Versions:"
-msgstr "無效副檔å"
+msgstr "已安è£çš„版本:"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Install From File"
-msgstr "從檔案下載"
+msgstr "從檔案安è£"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Remove Template"
-msgstr "移除é¸é …"
+msgstr "移除Template"
#: editor/export_template_manager.cpp
#, fuzzy
msgid "Select Template File"
-msgstr "è¦åˆªé™¤é¸ä¸­æª”案?"
+msgstr "é¸å–Template檔案"
#: editor/export_template_manager.cpp
#, fuzzy
msgid "Godot Export Templates"
-msgstr "管ç†è¼¸å‡ºç¯„本"
+msgstr "Godot輸出範本"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Export Template Manager"
-msgstr ""
+msgstr "Export Template管ç†å™¨"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Download Templates"
-msgstr "移除é¸é …"
+msgstr "下載Templates"
#: editor/export_template_manager.cpp
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
-msgstr ""
+msgstr "å¾žæ¸…å–®ä¸­é¸æ“‡é¡åƒ: (Shift + 單擊: 在ç€è¦½å™¨ä¸­æ‰“é–‹)"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3759,77 +3715,73 @@ msgid "Favorites"
msgstr "最愛:"
#: editor/filesystem_dock.cpp
+#, fuzzy
msgid "Status: Import of file failed. Please fix file and reimport manually."
-msgstr ""
+msgstr "ç‹€æ…‹ï¼šå°Žå…¥æª”æ¡ˆå¤±æ•—ã€‚è«‹ä¿®æ­£æª”æ¡ˆä¸¦å†æ‰‹å‹•導入。"
#: editor/filesystem_dock.cpp
+#, fuzzy
msgid "Cannot move/rename resources root."
-msgstr ""
+msgstr "ä¸èƒ½ç§»å‹•ï¼é‡æ–°å‘½å resources root."
#: editor/filesystem_dock.cpp
msgid "Cannot move a folder into itself."
-msgstr ""
+msgstr "ä¸èƒ½ç§»å‹•資料夾到資料夾自身。"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Error moving:"
-msgstr "載入錯誤:"
+msgstr "移動錯誤:"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Error duplicating:"
-msgstr "載入錯誤:"
+msgstr "å†è£½æ™‚出錯:"
#: editor/filesystem_dock.cpp
+#, fuzzy
msgid "Unable to update dependencies:"
-msgstr ""
+msgstr "未能更新dependencies:"
#: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp
msgid "No name provided."
-msgstr ""
+msgstr "沒有æä¾›å字。"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Provided name contains invalid characters."
-msgstr "有效字符:"
+msgstr "æä¾›çš„å字嫿œ‰ç„¡æ•ˆå­—符。"
#: editor/filesystem_dock.cpp
msgid "A file or folder with this name already exists."
-msgstr ""
+msgstr "具有此å稱的檔或資料夾已存在。"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Name contains invalid characters."
-msgstr "有效字符:"
+msgstr "å字嫿œ‰ç„¡æ•ˆå­—符。"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Renaming file:"
-msgstr "儲存TileSet時出ç¾éŒ¯èª¤ï¼"
+msgstr "釿–°å‘½å檔案:"
#: editor/filesystem_dock.cpp
msgid "Renaming folder:"
-msgstr ""
+msgstr "釿–°å‘½å資料夾:"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Duplicating file:"
-msgstr "複製"
+msgstr "å†è£½æª”案:"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Duplicating folder:"
-msgstr "複製"
+msgstr "å†è£½è³‡æ–™å¤¾ï¼š"
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "New Inherited Scene"
-msgstr "下一個腳本"
+msgstr "新增 Inherited Scene"
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Set As Main Scene"
-msgstr "鏿“‡ä¸»å ´æ™¯"
+msgstr "設家æˆä¸»å ´æ™¯"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3837,22 +3789,22 @@ msgid "Open Scenes"
msgstr "開啓場景"
#: editor/filesystem_dock.cpp
+#, fuzzy
msgid "Instance"
-msgstr ""
+msgstr "Instance"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Add to Favorites"
-msgstr "最愛:"
+msgstr "加到最愛"
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Remove from Favorites"
-msgstr "åªé™é¸ä¸­"
+msgstr "從最愛中移除"
#: editor/filesystem_dock.cpp
msgid "Edit Dependencies..."
-msgstr ""
+msgstr "編輯Dependencies..."
#: editor/filesystem_dock.cpp
msgid "View Owners..."
@@ -3864,9 +3816,8 @@ msgid "Rename..."
msgstr "釿–°å‘½å..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Duplicate..."
-msgstr "複製"
+msgstr "å†è£½..."
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3874,37 +3825,33 @@ msgid "Move To..."
msgstr "æ¬åˆ°..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Scene..."
-msgstr "新增場景"
+msgstr "新增場景..."
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "New Script..."
-msgstr "下一個腳本"
+msgstr "新增腳本..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Resource..."
-msgstr "把資æºå¦å­˜ç‚º..."
+msgstr "新增資æº..."
#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
msgid "Expand All"
-msgstr ""
+msgstr "全部展開"
#: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Collapse All"
-msgstr "關閉"
+msgstr "全部折疊"
#: editor/filesystem_dock.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
#: editor/project_manager.cpp editor/rename_dialog.cpp
#: editor/scene_tree_dock.cpp
msgid "Rename"
-msgstr "釿–°å‘½å..."
+msgstr "釿–°å‘½å"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3912,18 +3859,18 @@ msgid "Previous Folder/File"
msgstr "上一個tab"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Next Folder/File"
-msgstr "新增資料夾"
+msgstr "ä¸‹ä¸€å€‹è³‡æ–™å¤¾ï¼æª”案"
#: editor/filesystem_dock.cpp
+#, fuzzy
msgid "Re-Scan Filesystem"
-msgstr ""
+msgstr "釿–°æŽƒææª”案系統"
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Toggle Split Mode"
-msgstr "(ä¸ï¼‰é¡¯ç¤ºéš±è—的文件"
+msgstr "切æ›Split 模å¼"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3931,10 +3878,11 @@ msgid "Search files"
msgstr "在幫助檔æœå°‹"
#: editor/filesystem_dock.cpp
+#, fuzzy
msgid ""
"Scanning Files,\n"
"Please Wait..."
-msgstr ""
+msgstr "æ­£åœ¨æŽƒææª”案, è«‹ç¨å€™..."
#: editor/filesystem_dock.cpp
msgid "Move"
@@ -3942,35 +3890,35 @@ msgstr "移動"
#: editor/filesystem_dock.cpp
msgid "There is already file or folder with the same name in this location."
-msgstr ""
+msgstr "æ­¤ä½ç½®å·²å­˜åœ¨åŒå的檔案或資料夾。"
#: editor/filesystem_dock.cpp
+#, fuzzy
msgid "Overwrite"
-msgstr ""
+msgstr "覆蓋"
#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Create Scene"
-msgstr "儲存場景"
+msgstr "新增場景"
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
+#, fuzzy
msgid "Create Script"
-msgstr ""
+msgstr "新增腳本"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
#, fuzzy
msgid "Find in Files"
-msgstr "多 %d 檔案"
+msgstr "在檔案中本尋找"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Find:"
-msgstr "尋找"
+msgstr "尋找:"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Folder:"
-msgstr "新增資料夾"
+msgstr "資料夾:"
#: editor/find_in_files.cpp
#, fuzzy
@@ -3978,169 +3926,166 @@ msgid "Filters:"
msgstr "篩é¸:"
#: editor/find_in_files.cpp
+#, fuzzy
msgid ""
"Include the files with the following extensions. Add or remove them in "
"ProjectSettings."
-msgstr ""
+msgstr "包å«ä¸‹åˆ—副檔å的文件。在ProjectSettings增加或移除。"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find..."
-msgstr ""
+msgstr "尋找..."
#: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp
+#, fuzzy
msgid "Replace..."
-msgstr ""
+msgstr "替æ›â€¦"
#: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp
msgid "Cancel"
msgstr "å–æ¶ˆ"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Find: "
-msgstr "尋找"
+msgstr "尋找: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace: "
-msgstr "å–代"
+msgstr "å–代: "
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Replace all (no undo)"
-msgstr "全部å–代"
+msgstr "全部å–代(ä¸å¯é‚„原)"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Searching..."
-msgstr "儲存中..."
+msgstr "æœå°‹ä¸­..."
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Search complete"
-msgstr "在幫助檔æœå°‹"
+msgstr "æœå°‹å®Œæˆ"
#: editor/groups_editor.cpp
+#, fuzzy
msgid "Add to Group"
-msgstr ""
+msgstr "加到Group"
#: editor/groups_editor.cpp
msgid "Remove from Group"
-msgstr ""
+msgstr "從Group中移除"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Group name already exists."
-msgstr "錯誤:動畫å稱已存在ï¼"
+msgstr "錯誤:groupå稱已存在。"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Invalid group name."
-msgstr "無效å稱"
+msgstr "無效groupå稱。"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Rename Group"
-msgstr "專案"
+msgstr "釿–°å‘½åGroup"
#: editor/groups_editor.cpp
#, fuzzy
msgid "Delete Group"
-msgstr "刪除佈局"
+msgstr "刪除Group"
#: editor/groups_editor.cpp editor/node_dock.cpp
+#, fuzzy
msgid "Groups"
-msgstr ""
+msgstr "Groups"
#: editor/groups_editor.cpp
msgid "Nodes Not in Group"
-msgstr ""
+msgstr "ä¸åœ¨Groupå…§çš„Nodes"
#: editor/groups_editor.cpp editor/scene_tree_dock.cpp
#: editor/scene_tree_editor.cpp
#, fuzzy
msgid "Filter nodes"
-msgstr "篩é¸:"
+msgstr "篩é¸nodes:"
#: editor/groups_editor.cpp
msgid "Nodes in Group"
-msgstr ""
+msgstr "Group中的Nodes"
#: editor/groups_editor.cpp
msgid "Empty groups will be automatically removed."
-msgstr ""
+msgstr "空groups會被移除。"
#: editor/groups_editor.cpp
-#, fuzzy
msgid "Group Editor"
-msgstr "開啟資料夾"
+msgstr "Group編輯器"
#: editor/groups_editor.cpp
msgid "Manage Groups"
-msgstr ""
+msgstr "管ç†groups"
#: editor/import/resource_importer_scene.cpp
#, fuzzy
msgid "Import as Single Scene"
-msgstr "更新場景"
+msgstr "導入為單一場景"
#: editor/import/resource_importer_scene.cpp
+#, fuzzy
msgid "Import with Separate Animations"
-msgstr ""
+msgstr "以分開的動畫導入"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Materials"
-msgstr ""
+msgstr "以分開的Materials導入"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Objects"
-msgstr ""
+msgstr "以分開的物件導入"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Objects+Materials"
-msgstr ""
+msgstr "以分開的物件+Materials導入"
#: editor/import/resource_importer_scene.cpp
+#, fuzzy
msgid "Import with Separate Objects+Animations"
-msgstr ""
+msgstr "以分開的物件+動畫導入"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Materials+Animations"
-msgstr ""
+msgstr "以分開的Materials+動畫導入"
#: editor/import/resource_importer_scene.cpp
msgid "Import with Separate Objects+Materials+Animations"
-msgstr ""
+msgstr "以分開的物件+Materials+動畫導入"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Multiple Scenes"
-msgstr ""
+msgstr "導入為多個場景"
#: editor/import/resource_importer_scene.cpp
msgid "Import as Multiple Scenes+Materials"
-msgstr ""
+msgstr "導入為多個場景+Materials"
#: editor/import/resource_importer_scene.cpp
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Import Scene"
-msgstr ""
+msgstr "導入場景"
#: editor/import/resource_importer_scene.cpp
msgid "Importing Scene..."
-msgstr ""
+msgstr "導入場景中..."
#: editor/import/resource_importer_scene.cpp
msgid "Generating Lightmaps"
-msgstr ""
+msgstr "光照圖生æˆä¸­"
#: editor/import/resource_importer_scene.cpp
msgid "Generating for Mesh: "
-msgstr ""
+msgstr "為Mesh生æˆä¸­ï¼š "
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
-msgstr ""
+msgstr "正在é‹è¡Œè‡ªå®šç¾©è…³æœ¬..."
#: editor/import/resource_importer_scene.cpp
msgid "Couldn't load post-import script:"
@@ -9101,15 +9046,15 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Equal (==)"
-msgstr ""
+msgstr "等於 (==)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Greater Than (>)"
-msgstr ""
+msgstr "大於(>)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Greater Than or Equal (>=)"
-msgstr ""
+msgstr "大於或等於(>=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9131,15 +9076,15 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Less Than (<)"
-msgstr ""
+msgstr "å°æ–¼ (<)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Less Than or Equal (<=)"
-msgstr ""
+msgstr "å°æ–¼æˆ–等於 (<=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Not Equal (!=)"
-msgstr ""
+msgstr "ä¸ç­‰æ–¼ (!=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -10230,6 +10175,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -10826,23 +10778,24 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Move Nodes In Parent"
-msgstr ""
+msgstr "在Parent內移動Nodes"
#: editor/scene_tree_dock.cpp
msgid "Duplicate Node(s)"
-msgstr ""
+msgstr "å†è£½Node"
#: editor/scene_tree_dock.cpp
msgid "Can't reparent nodes in inherited scenes, order of nodes can't change."
-msgstr ""
+msgstr "ä¸èƒ½åœ¨inherited sceneså…§reparent nodes,nodesé †åºä¸èƒ½æ”¹è®Šã€‚"
#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Node must belong to the edited scene to become root."
-msgstr ""
+msgstr "Node必須屬於已編輯的場景以æˆç‚ºroot."
#: editor/scene_tree_dock.cpp
msgid "Instantiated scenes can't become root"
-msgstr ""
+msgstr "Instantiated scenesä¸èƒ½æˆç‚ºroot"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -10855,12 +10808,14 @@ msgid "Delete %d nodes?"
msgstr "ä¸é¸"
#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Delete the root node \"%s\"?"
-msgstr ""
+msgstr "删除root node \"%s\"?"
#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Delete node \"%s\" and its children?"
-msgstr ""
+msgstr "删除root node \"%s\"?"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -11390,6 +11345,11 @@ msgid "Total:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "匯出"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr ""
@@ -12926,7 +12886,7 @@ msgstr ""
#: scene/gui/range.cpp
msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."
-msgstr ""
+msgstr "當\"Exp Edit\" 啟用時,\"Min Value\" 必須大於0。"
#: scene/gui/scroll_container.cpp
msgid ""
@@ -12937,7 +12897,7 @@ msgstr ""
#: scene/gui/tree.cpp
msgid "(Other)"
-msgstr ""
+msgstr "(å…¶ä»–)"
#: scene/main/scene_tree.cpp
msgid ""
@@ -12954,23 +12914,22 @@ msgid ""
msgstr ""
#: scene/main/viewport.cpp
+#, fuzzy
msgid "Viewport size must be greater than 0 to render anything."
-msgstr ""
+msgstr "viewport大å°å¿…須大於ï¼ä»¥æ¸²æŸ“任何æ±è¥¿ã€‚"
#: scene/resources/visual_shader_nodes.cpp
#, fuzzy
msgid "Invalid source for preview."
-msgstr "無效字型"
+msgstr "é è¦½ä¾†è‡ªç„¡æ•ˆä¾†æºã€‚"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for shader."
-msgstr "無效字型"
+msgstr "無效的SHADER來æºã€‚"
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid comparison function for that type."
-msgstr "無效字型"
+msgstr "無效的函å¼é¡žåž‹å°æ¯”。"
#: servers/visual/shader_language.cpp
msgid "Assignment to function."
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index 235ce0d023..6b3651b5f6 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -10218,6 +10218,13 @@ msgid ""
"Would you like to explore official example projects in the Asset Library?"
msgstr ""
+#: editor/project_manager.cpp
+msgid ""
+"The search box filters projects by name and last path component.\n"
+"To filter projects by name and full path, the query must contain at least "
+"one `/` character."
+msgstr ""
+
#: editor/project_settings_editor.cpp
msgid "Key "
msgstr ""
@@ -11375,6 +11382,11 @@ msgid "Total:"
msgstr "總計:"
#: editor/script_editor_debugger.cpp
+#, fuzzy
+msgid "Export list to a CSV file"
+msgstr "輸出專案"
+
+#: editor/script_editor_debugger.cpp
msgid "Resource Path"
msgstr "資æºè·¯å¾‘"
diff --git a/gles_builders.py b/gles_builders.py
index 6ff2f4248b..85d0112c9a 100644
--- a/gles_builders.py
+++ b/gles_builders.py
@@ -36,14 +36,14 @@ def include_file_in_legacygl_header(filename, header_data, depth):
while line:
- if line.find("[vertex]") != -1:
+ if line.find("#[vertex]") != -1:
header_data.reading = "vertex"
line = fs.readline()
header_data.line_offset += 1
header_data.vertex_offset = header_data.line_offset
continue
- if line.find("[fragment]") != -1:
+ if line.find("#[fragment]") != -1:
header_data.reading = "fragment"
line = fs.readline()
header_data.line_offset += 1
@@ -612,21 +612,21 @@ def include_file_in_rd_header(filename, header_data, depth):
while line:
- if line.find("[vertex]") != -1:
+ if line.find("#[vertex]") != -1:
header_data.reading = "vertex"
line = fs.readline()
header_data.line_offset += 1
header_data.vertex_offset = header_data.line_offset
continue
- if line.find("[fragment]") != -1:
+ if line.find("#[fragment]") != -1:
header_data.reading = "fragment"
line = fs.readline()
header_data.line_offset += 1
header_data.fragment_offset = header_data.line_offset
continue
- if line.find("[compute]") != -1:
+ if line.find("#[compute]") != -1:
header_data.reading = "compute"
line = fs.readline()
header_data.line_offset += 1
@@ -740,5 +740,69 @@ def build_rd_headers(target, source, env):
build_rd_header(str(x))
+class RAWHeaderStruct:
+ def __init__(self):
+ self.code = ""
+
+
+def include_file_in_raw_header(filename, header_data, depth):
+ fs = open(filename, "r")
+ line = fs.readline()
+ text = ""
+
+ while line:
+
+ while line.find("#include ") != -1:
+ includeline = line.replace("#include ", "").strip()[1:-1]
+
+ import os.path
+
+ included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
+ include_file_in_raw_header(included_file, header_data, depth + 1)
+
+ line = fs.readline()
+
+ header_data.code += line
+ line = fs.readline()
+
+ fs.close()
+
+
+def build_raw_header(filename):
+ header_data = RAWHeaderStruct()
+ include_file_in_raw_header(filename, header_data, 0)
+
+ out_file = filename + ".gen.h"
+ fd = open(out_file, "w")
+
+ enum_constants = []
+
+ fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
+
+ out_file_base = out_file.replace(".glsl.gen.h", "_shader_glsl")
+ out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
+ out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
+ out_file_ifdef = out_file_base.replace(".", "_").upper()
+ fd.write("#ifndef " + out_file_ifdef + "_RAW_H\n")
+ fd.write("#define " + out_file_ifdef + "_RAW_H\n")
+ fd.write("\n")
+ fd.write("static const char " + out_file_base + "[] = {\n")
+ for c in header_data.code:
+ fd.write(str(ord(c)) + ",")
+ fd.write("\t\t0};\n\n")
+ fd.write("#endif\n")
+ fd.close()
+
+
+def build_rd_headers(target, source, env):
+ for x in source:
+ build_rd_header(str(x))
+
+
+def build_raw_headers(target, source, env):
+ for x in source:
+ build_raw_header(str(x))
+
+
if __name__ == "__main__":
subprocess_main(globals())
diff --git a/main/main.cpp b/main/main.cpp
index c625a9cb36..f05032e68c 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -32,7 +32,7 @@
#include "core/crypto/crypto.h"
#include "core/debugger/engine_debugger.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/input/input_map.h"
#include "core/io/file_access_network.h"
#include "core/io/file_access_pack.h"
@@ -55,6 +55,7 @@
#include "main/splash.gen.h"
#include "main/splash_editor.gen.h"
#include "main/tests/test_main.h"
+#include "modules/modules_enabled.gen.h"
#include "modules/register_module_types.h"
#include "platform/register_platform_apis.h"
#include "scene/main/scene_tree.h"
@@ -89,7 +90,7 @@
// Initialized in setup()
static Engine *engine = nullptr;
static ProjectSettings *globals = nullptr;
-static InputFilter *input = nullptr;
+static Input *input = nullptr;
static InputMap *input_map = nullptr;
static TranslationServer *translation_server = nullptr;
static Performance *performance = nullptr;
@@ -175,8 +176,9 @@ static String unescape_cmdline(const String &p_str) {
static String get_full_version_string() {
String hash = String(VERSION_HASH);
- if (hash.length() != 0)
+ if (hash.length() != 0) {
hash = "." + hash.left(9);
+ }
return String(VERSION_FULL_BUILD) + hash;
}
@@ -203,7 +205,6 @@ void initialize_physics() {
}
void finalize_physics() {
-
physics_server->finish();
memdelete(physics_server);
@@ -212,7 +213,6 @@ void finalize_physics() {
}
void finalize_display() {
-
rendering_server->finish();
memdelete(rendering_server);
@@ -242,7 +242,6 @@ void finalize_navigation_server() {
#endif
void Main::print_help(const char *p_binary) {
-
print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE));
OS::get_singleton()->print("Free and open source software under the terms of the MIT license.\n");
OS::get_singleton()->print("(c) 2007-2020 Juan Linietsky, Ariel Manzur.\n");
@@ -313,6 +312,13 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" --enable-vsync-via-compositor When vsync is enabled, vsync via the OS' window compositor (Windows only).\n");
OS::get_singleton()->print(" --disable-vsync-via-compositor Disable vsync via the OS' window compositor (Windows only).\n");
OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n");
+ OS::get_singleton()->print(" --tablet-driver Tablet input driver (");
+ for (int i = 0; i < OS::get_singleton()->get_tablet_driver_count(); i++) {
+ if (i != 0)
+ OS::get_singleton()->print(", ");
+ OS::get_singleton()->print("'%s'", OS::get_singleton()->get_tablet_driver_name(i).utf8().get_data());
+ }
+ OS::get_singleton()->print(") (Windows only).\n");
OS::get_singleton()->print("\n");
#endif
@@ -321,7 +327,7 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n");
OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n");
OS::get_singleton()->print(" --gpu-abort Abort on GPU errors (usually validation layer errors), may help see the problem if your system freezes.\n");
- OS::get_singleton()->print(" --remote-debug <address> Remote debug (<host/IP>:<port> address).\n");
+ OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n");
#if defined(DEBUG_ENABLED) && !defined(SERVER_ENABLED)
OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n");
OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n");
@@ -387,7 +393,6 @@ void Main::print_help(const char *p_binary) {
*/
Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_phase) {
-
OS::get_singleton()->initialize();
engine = memnew(Engine);
@@ -422,7 +427,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
List<String> main_args;
for (int i = 0; i < argc; i++) {
-
args.push_back(String::utf8(argv[i]));
}
@@ -431,7 +435,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
I = args.front();
while (I) {
-
I->get() = unescape_cmdline(I->get().strip_edges());
I = I->next();
}
@@ -440,6 +443,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
String display_driver = "";
String audio_driver = "";
+ String tablet_driver = "";
String project_path = ".";
bool upwards = false;
String debug_uri = "";
@@ -461,8 +465,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
bool use_vsync = false;
packed_data = PackedData::get_singleton();
- if (!packed_data)
+ if (!packed_data) {
packed_data = memnew(PackedData);
+ }
#ifdef MINIZIP_ENABLED
@@ -495,7 +500,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
goto error;
} else if (I->get() == "--version") {
-
print_line(get_full_version_string());
goto error;
@@ -509,7 +513,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--audio-driver") { // audio driver
if (I->next()) {
-
audio_driver = I->next()->get();
bool found = false;
@@ -546,7 +549,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--display-driver") { // force video driver
if (I->next()) {
-
display_driver = I->next()->get();
bool found = false;
@@ -594,6 +596,26 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--gpu-abort") { // force windowed window
Engine::singleton->abort_on_gpu_errors = true;
+ } else if (I->get() == "--tablet-driver") {
+ if (I->next()) {
+ tablet_driver = I->next()->get();
+ bool found = false;
+ for (int i = 0; i < OS::get_singleton()->get_tablet_driver_count(); i++) {
+ if (tablet_driver == OS::get_singleton()->get_tablet_driver_name(i)) {
+ found = true;
+ }
+ }
+
+ if (!found) {
+ OS::get_singleton()->print("Unknown tablet driver '%s', aborting.\n", tablet_driver.utf8().get_data());
+ goto error;
+ }
+
+ N = I->next()->next();
+ } else {
+ OS::get_singleton()->print("Missing tablet driver argument, aborting.\n");
+ goto error;
+ }
} else if (I->get() == "--single-window") { // force single window
single_window = true;
@@ -603,7 +625,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--resolution") { // force resolution
if (I->next()) {
-
String vm = I->next()->get();
if (vm.find("x") == -1) { // invalid parameter format
@@ -616,7 +637,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
int h = vm.get_slice("x", 1).to_int();
if (w <= 0 || h <= 0) {
-
OS::get_singleton()->print("Invalid resolution '%s', width and height must be above 0.\n", vm.utf8().get_data());
goto error;
}
@@ -634,7 +654,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--position") { // set window position
if (I->next()) {
-
String vm = I->next()->get();
if (vm.find(",") == -1) { // invalid parameter format
@@ -662,11 +681,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->set_no_window_mode(true);
} else if (I->get() == "--enable-vsync-via-compositor") {
-
window_vsync_via_compositor = true;
saw_vsync_via_compositor_override = true;
} else if (I->get() == "--disable-vsync-via-compositor") {
-
window_vsync_via_compositor = false;
saw_vsync_via_compositor_override = true;
#endif
@@ -677,7 +694,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "-l" || I->get() == "--language") { // language
if (I->next()) {
-
locale = I->next()->get();
N = I->next()->next();
} else {
@@ -688,7 +704,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--remote-fs") { // remote filesystem
if (I->next()) {
-
remotefs = I->next()->get();
N = I->next()->next();
} else {
@@ -698,7 +713,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--remote-fs-password") { // remote filesystem password
if (I->next()) {
-
remotefs_pass = I->next()->get();
N = I->next()->next();
} else {
@@ -708,13 +722,13 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--render-thread") { // render thread mode
if (I->next()) {
-
- if (I->next()->get() == "safe")
+ if (I->next()->get() == "safe") {
rtm = OS::RENDER_THREAD_SAFE;
- else if (I->next()->get() == "unsafe")
+ } else if (I->next()->get() == "unsafe") {
rtm = OS::RENDER_THREAD_UNSAFE;
- else if (I->next()->get() == "separate")
+ } else if (I->next()->get() == "separate") {
rtm = OS::RENDER_SEPARATE_THREAD;
+ }
N = I->next()->next();
} else {
@@ -748,7 +762,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--path") { // set path of project to start or edit
if (I->next()) {
-
String p = I->next()->get();
if (OS::get_singleton()->set_cwd(p) == OK) {
//nothing
@@ -768,9 +781,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
String path;
String file = I->get();
int sep = MAX(file.find_last("/"), file.find_last("\\"));
- if (sep == -1)
+ if (sep == -1) {
path = ".";
- else {
+ } else {
path = file.substr(0, sep);
}
if (OS::get_singleton()->set_cwd(path) == OK) {
@@ -784,7 +797,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "-b" || I->get() == "--breakpoints") { // add breakpoints
if (I->next()) {
-
String bplist = I->next()->get();
breakpoints = bplist.split(",");
N = I->next()->next();
@@ -796,7 +808,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--frame-delay") { // force frame delay
if (I->next()) {
-
frame_delay = I->next()->get().to_int();
N = I->next()->next();
} else {
@@ -807,7 +818,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
} else if (I->get() == "--time-scale") { // force time scale
if (I->next()) {
-
Engine::get_singleton()->set_time_scale(I->next()->get().to_double());
N = I->next()->next();
} else {
@@ -816,9 +826,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
} else if (I->get() == "--main-pack") {
-
if (I->next()) {
-
main_pack = I->next()->get();
N = I->next()->next();
} else {
@@ -836,13 +844,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#endif
} else if (I->get() == "--remote-debug") {
if (I->next()) {
-
debug_uri = I->next()->get();
- if (debug_uri.find(":") == -1) { // wrong address
- OS::get_singleton()->print("Invalid debug host address, it should be of the form <host/IP>:<port>.\n");
+ if (debug_uri.find("://") == -1) { // wrong address
+ OS::get_singleton()->print("Invalid debug host address, it should be of the form <protocol>://<host/IP>:<port>.\n");
goto error;
}
- debug_uri = "tcp://" + debug_uri; // will support multiple protocols eventually.
N = I->next()->next();
} else {
OS::get_singleton()->print("Missing remote debug host address, aborting.\n");
@@ -850,7 +856,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
} else if (I->get() == "--allow_focus_steal_pid") { // not exposed to user
if (I->next()) {
-
allow_focus_steal_pid = I->next()->get().to_int64();
N = I->next()->next();
} else {
@@ -891,7 +896,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
// 'project.godot' file which will only be available through the network if this is enabled
FileAccessNetwork::configure();
if (remotefs != "") {
-
file_access_network_client = memnew(FileAccessNetworkClient);
int port;
if (remotefs.find(":") != -1) {
@@ -915,7 +919,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
found_project = true;
#endif
} else {
-
#ifdef TOOLS_ENABLED
editor = false;
#else
@@ -1000,8 +1003,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
_print_error_enabled = false;
};
- if (quiet_stdout)
+ if (quiet_stdout) {
_print_line_enabled = false;
+ }
OS::get_singleton()->set_cmdline(execpath, main_args);
@@ -1028,13 +1032,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
ProjectSettings::get_singleton()->set_custom_property_info("display/window/size/test_height", PropertyInfo(Variant::INT, "display/window/size/test_height", PROPERTY_HINT_RANGE, "0,4320,or_greater")); // 8K resolution
if (use_custom_res) {
-
if (!force_res) {
window_size.width = GLOBAL_GET("display/window/size/width");
window_size.height = GLOBAL_GET("display/window/size/height");
if (globals->has_setting("display/window/size/test_width") && globals->has_setting("display/window/size/test_height")) {
-
int tw = globals->get("display/window/size/test_width");
if (tw > 0) {
window_size.width = tw;
@@ -1078,6 +1080,21 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->_vsync_via_compositor = window_vsync_via_compositor;
+ if (tablet_driver == "") { // specified in project.godot
+ tablet_driver = GLOBAL_DEF_RST("display/window/tablet_driver", OS::get_singleton()->get_tablet_driver_name(0));
+ }
+
+ for (int i = 0; i < OS::get_singleton()->get_tablet_driver_count(); i++) {
+ if (tablet_driver == OS::get_singleton()->get_tablet_driver_name(i)) {
+ OS::get_singleton()->set_current_tablet_driver(OS::get_singleton()->get_tablet_driver_name(i));
+ break;
+ }
+ }
+
+ if (tablet_driver == "") {
+ OS::get_singleton()->set_current_tablet_driver(OS::get_singleton()->get_tablet_driver_name(0));
+ }
+
/* todo restore
OS::get_singleton()->_allow_layered = GLOBAL_DEF("display/window/per_pixel_transparency/allowed", false);
video_mode.layered = GLOBAL_DEF("display/window/per_pixel_transparency/enabled", false);
@@ -1107,9 +1124,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
/* Determine audio and video drivers */
for (int i = 0; i < DisplayServer::get_create_function_count(); i++) {
-
if (display_driver == DisplayServer::get_create_function_name(i)) {
-
display_driver_idx = i;
break;
}
@@ -1124,9 +1139,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
-
if (audio_driver == AudioDriverManager::get_driver(i)->get_name()) {
-
audio_driver_idx = i;
break;
}
@@ -1139,20 +1152,21 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
{
String orientation = GLOBAL_DEF("display/window/handheld/orientation", "landscape");
- if (orientation == "portrait")
+ if (orientation == "portrait") {
window_orientation = DisplayServer::SCREEN_PORTRAIT;
- else if (orientation == "reverse_landscape")
+ } else if (orientation == "reverse_landscape") {
window_orientation = DisplayServer::SCREEN_REVERSE_LANDSCAPE;
- else if (orientation == "reverse_portrait")
+ } else if (orientation == "reverse_portrait") {
window_orientation = DisplayServer::SCREEN_REVERSE_PORTRAIT;
- else if (orientation == "sensor_landscape")
+ } else if (orientation == "sensor_landscape") {
window_orientation = DisplayServer::SCREEN_SENSOR_LANDSCAPE;
- else if (orientation == "sensor_portrait")
+ } else if (orientation == "sensor_portrait") {
window_orientation = DisplayServer::SCREEN_SENSOR_PORTRAIT;
- else if (orientation == "sensor")
+ } else if (orientation == "sensor") {
window_orientation = DisplayServer::SCREEN_SENSOR;
- else
+ } else {
window_orientation = DisplayServer::SCREEN_LANDSCAPE;
+ }
}
Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF("physics/common/physics_fps", 60));
@@ -1162,9 +1176,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
ProjectSettings::get_singleton()->set_custom_property_info("debug/settings/fps/force_fps", PropertyInfo(Variant::INT, "debug/settings/fps/force_fps", PROPERTY_HINT_RANGE, "0,120,1,or_greater"));
GLOBAL_DEF("debug/settings/stdout/print_fps", false);
+ GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false);
- if (!OS::get_singleton()->_verbose_stdout) //overridden
- OS::get_singleton()->_verbose_stdout = GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false);
+ if (!OS::get_singleton()->_verbose_stdout) { // Not manually overridden.
+ OS::get_singleton()->_verbose_stdout = GLOBAL_GET("debug/settings/stdout/verbose_stdout");
+ }
if (frame_delay == 0) {
frame_delay = GLOBAL_DEF("application/run/frame_delay_msec", 0);
@@ -1181,8 +1197,9 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
message_queue = memnew(MessageQueue);
- if (p_second_phase)
+ if (p_second_phase) {
return setup2();
+ }
return OK;
@@ -1190,38 +1207,48 @@ error:
display_driver = "";
audio_driver = "";
+ tablet_driver = "";
project_path = "";
args.clear();
main_args.clear();
- if (show_help)
+ if (show_help) {
print_help(execpath);
+ }
EngineDebugger::deinitialize();
- if (performance)
+ if (performance) {
memdelete(performance);
- if (input_map)
+ }
+ if (input_map) {
memdelete(input_map);
- if (translation_server)
+ }
+ if (translation_server) {
memdelete(translation_server);
- if (globals)
+ }
+ if (globals) {
memdelete(globals);
- if (engine)
+ }
+ if (engine) {
memdelete(engine);
- if (packed_data)
+ }
+ if (packed_data) {
memdelete(packed_data);
- if (file_access_network_client)
+ }
+ if (file_access_network_client) {
memdelete(file_access_network_client);
+ }
unregister_core_driver_types();
unregister_core_types();
OS::get_singleton()->_cmdline.clear();
- if (message_queue)
+ if (message_queue) {
memdelete(message_queue);
+ }
OS::get_singleton()->finalize_core();
locale = String();
@@ -1229,7 +1256,6 @@ error:
}
Error Main::setup2(Thread::ID p_main_tid_override) {
-
preregister_module_types();
preregister_server_types();
@@ -1246,12 +1272,11 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
/* Initialize Input */
- input = memnew(InputFilter);
+ input = memnew(Input);
/* Iniitalize Display Server */
{
-
String rendering_driver; // temp broken
Error err;
@@ -1356,8 +1381,9 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
if (boot_logo_path != String()) {
boot_logo.instance();
Error load_err = ImageLoader::load_image(boot_logo_path, boot_logo);
- if (load_err)
+ if (load_err) {
ERR_PRINT("Non-existing or invalid boot splash at '" + boot_logo_path + "'. Loading default splash.");
+ }
}
Color boot_bg_color = GLOBAL_DEF("application/boot_splash/bg_color", boot_splash_bg_color);
@@ -1400,10 +1426,9 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
GLOBAL_DEF("application/config/windows_native_icon", String());
ProjectSettings::get_singleton()->set_custom_property_info("application/config/windows_native_icon", PropertyInfo(Variant::STRING, "application/config/windows_native_icon", PROPERTY_HINT_FILE, "*.ico"));
- InputFilter *id = InputFilter::get_singleton();
+ Input *id = Input::get_singleton();
if (id) {
if (bool(GLOBAL_DEF("input_devices/pointing/emulate_touch_from_mouse", false)) && !(editor || project_manager)) {
-
bool found_touchscreen = false;
for (int i = 0; i < DisplayServer::get_singleton()->get_screen_count(); i++) {
if (DisplayServer::get_singleton()->screen_is_touchscreen(i)) {
@@ -1431,11 +1456,10 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
ProjectSettings::get_singleton()->set_custom_property_info("display/mouse_cursor/custom_image", PropertyInfo(Variant::STRING, "display/mouse_cursor/custom_image", PROPERTY_HINT_FILE, "*.png,*.webp"));
if (String(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image")) != String()) {
-
Ref<Texture2D> cursor = ResourceLoader::load(ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image"));
if (cursor.is_valid()) {
Vector2 hotspot = ProjectSettings::get_singleton()->get("display/mouse_cursor/custom_image_hotspot");
- InputFilter::get_singleton()->set_custom_mouse_cursor(cursor, InputFilter::CURSOR_ARROW, hotspot);
+ Input::get_singleton()->set_custom_mouse_cursor(cursor, Input::CURSOR_ARROW, hotspot);
}
}
#ifdef TOOLS_ENABLED
@@ -1466,7 +1490,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
translation_server->setup(); //register translations, load them, etc.
if (locale != "") {
-
translation_server->set_locale(locale);
}
translation_server->load_translations();
@@ -1506,7 +1529,6 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
static MainTimerSync main_timer_sync;
bool Main::start() {
-
ERR_FAIL_COND_V(!_start_success, false);
bool hasicon = false;
@@ -1543,7 +1565,11 @@ bool Main::start() {
} else if (args[i].length() && args[i][0] != '-' && positional_arg == "") {
positional_arg = args[i];
- if (args[i].ends_with(".scn") || args[i].ends_with(".tscn") || args[i].ends_with(".escn")) {
+ if (args[i].ends_with(".scn") ||
+ args[i].ends_with(".tscn") ||
+ args[i].ends_with(".escn") ||
+ args[i].ends_with(".res") ||
+ args[i].ends_with(".tres")) {
// Only consider the positional argument to be a scene path if it ends with
// a file extension associated with Godot scenes. This makes it possible
// for projects to parse command-line arguments for custom CLI arguments
@@ -1563,8 +1589,9 @@ bool Main::start() {
#ifdef TOOLS_ENABLED
} else if (args[i] == "--doctool") {
doc_tool = args[i + 1];
- for (int j = i + 2; j < args.size(); j++)
+ for (int j = i + 2; j < args.size(); j++) {
removal_docs.push_back(args[j]);
+ }
} else if (args[i] == "--export") {
editor = true; //needs editor
_export_preset = args[i + 1];
@@ -1590,13 +1617,25 @@ bool Main::start() {
String main_loop_type;
#ifdef TOOLS_ENABLED
if (doc_tool != "") {
-
Engine::get_singleton()->set_editor_hint(true); // Needed to instance editor-only classes for their default values
{
DirAccessRef da = DirAccess::open(doc_tool);
ERR_FAIL_COND_V_MSG(!da, false, "Argument supplied to --doctool must be a base Godot build directory.");
}
+
+#ifndef MODULE_MONO_ENABLED
+ // Hack to define Mono-specific project settings even on non-Mono builds,
+ // so that we don't lose their descriptions and default values in DocData.
+ // Default values should be synced with mono_gd/gd_mono.cpp.
+ GLOBAL_DEF("mono/debugger_agent/port", 23685);
+ GLOBAL_DEF("mono/debugger_agent/wait_for_debugger", false);
+ GLOBAL_DEF("mono/debugger_agent/wait_timeout", 3000);
+ GLOBAL_DEF("mono/profiler/args", "log:calls,alloc,sample,output=output.mlpd");
+ GLOBAL_DEF("mono/profiler/enabled", false);
+ GLOBAL_DEF("mono/unhandled_exception_policy", 0);
+#endif
+
DocData doc;
doc.generate(doc_base);
@@ -1668,12 +1707,12 @@ bool Main::start() {
#ifdef TOOLS_ENABLED
main_loop = test_main(test, args);
- if (!main_loop)
+ if (!main_loop) {
return false;
+ }
#endif
} else if (script != "") {
-
Ref<Script> script_res = ResourceLoader::load(script);
ERR_FAIL_COND_V_MSG(script_res.is_null(), false, "Can't load script: " + script);
@@ -1685,20 +1724,19 @@ bool Main::start() {
}
if (script_res->can_instance()) {
-
StringName instance_type = script_res->get_instance_base_type();
Object *obj = ClassDB::instance(instance_type);
MainLoop *script_loop = Object::cast_to<MainLoop>(obj);
if (!script_loop) {
- if (obj)
+ if (obj) {
memdelete(obj);
+ }
ERR_FAIL_V_MSG(false, vformat("Can't load the script \"%s\" as it doesn't inherit from SceneTree or MainLoop.", script));
}
script_loop->set_init_script(script_res);
main_loop = script_loop;
} else {
-
return false;
}
@@ -1706,21 +1744,20 @@ bool Main::start() {
main_loop_type = GLOBAL_DEF("application/run/main_loop_type", "");
}
- if (!main_loop && main_loop_type == "")
+ if (!main_loop && main_loop_type == "") {
main_loop_type = "SceneTree";
+ }
if (!main_loop) {
if (!ClassDB::class_exists(main_loop_type)) {
DisplayServer::get_singleton()->alert("Error: MainLoop type doesn't exist: " + main_loop_type);
return false;
} else {
-
Object *ml = ClassDB::instance(main_loop_type);
ERR_FAIL_COND_V_MSG(!ml, false, "Can't instance MainLoop type.");
main_loop = Object::cast_to<MainLoop>(ml);
if (!main_loop) {
-
memdelete(ml);
ERR_FAIL_V_MSG(false, "Invalid MainLoop type.");
}
@@ -1728,7 +1765,6 @@ bool Main::start() {
}
if (main_loop->is_class("SceneTree")) {
-
SceneTree *sml = Object::cast_to<SceneTree>(main_loop);
#ifdef DEBUG_ENABLED
@@ -1756,10 +1792,10 @@ bool Main::start() {
//first pass, add the constants so they exist before any script is loaded
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
String s = E->get().name;
- if (!s.begins_with("autoload/"))
+ if (!s.begins_with("autoload/")) {
continue;
+ }
String name = s.get_slicec('/', 1);
String path = ProjectSettings::get_singleton()->get(s);
bool global_var = false;
@@ -1777,10 +1813,10 @@ bool Main::start() {
//second pass, load into global constants
List<Node *> to_add;
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
String s = E->get().name;
- if (!s.begins_with("autoload/"))
+ if (!s.begins_with("autoload/")) {
continue;
+ }
String name = s.get_slicec('/', 1);
String path = ProjectSettings::get_singleton()->get(s);
bool global_var = false;
@@ -1823,7 +1859,6 @@ bool Main::start() {
}
for (List<Node *>::Element *E = to_add.front(); E; E = E->next()) {
-
sml->get_root()->add_child(E->get());
}
}
@@ -1843,7 +1878,6 @@ bool Main::start() {
#endif
{
-
int directional_atlas_size = GLOBAL_GET("rendering/quality/directional_shadow/size");
RenderingServer::get_singleton()->directional_shadow_atlas_set_size(directional_atlas_size);
}
@@ -1856,20 +1890,22 @@ bool Main::start() {
Size2i stretch_size = Size2(GLOBAL_DEF("display/window/size/width", 0), GLOBAL_DEF("display/window/size/height", 0));
Window::ContentScaleMode cs_sm = Window::CONTENT_SCALE_MODE_DISABLED;
- if (stretch_mode == "objects")
+ if (stretch_mode == "objects") {
cs_sm = Window::CONTENT_SCALE_MODE_OBJECTS;
- else if (stretch_mode == "pixels")
+ } else if (stretch_mode == "pixels") {
cs_sm = Window::CONTENT_SCALE_MODE_PIXELS;
+ }
Window::ContentScaleAspect cs_aspect = Window::CONTENT_SCALE_ASPECT_IGNORE;
- if (stretch_aspect == "keep")
+ if (stretch_aspect == "keep") {
cs_aspect = Window::CONTENT_SCALE_ASPECT_KEEP;
- else if (stretch_aspect == "keep_width")
+ } else if (stretch_aspect == "keep_width") {
cs_aspect = Window::CONTENT_SCALE_ASPECT_KEEP_WIDTH;
- else if (stretch_aspect == "keep_height")
+ } else if (stretch_aspect == "keep_height") {
cs_aspect = Window::CONTENT_SCALE_ASPECT_KEEP_HEIGHT;
- else if (stretch_aspect == "expand")
+ } else if (stretch_aspect == "expand") {
cs_aspect = Window::CONTENT_SCALE_ASPECT_EXPAND;
+ }
sml->get_root()->set_content_scale_mode(cs_sm);
sml->get_root()->set_content_scale_aspect(cs_aspect);
@@ -1905,7 +1941,6 @@ bool Main::start() {
sml->get_root()->set_default_canvas_item_texture_repeat(Viewport::DefaultCanvasItemTextureRepeat(texture_repeat));
} else {
-
GLOBAL_DEF("display/window/stretch/mode", "disabled");
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport"));
GLOBAL_DEF("display/window/stretch/aspect", "ignore");
@@ -1923,18 +1958,25 @@ bool Main::start() {
ProjectSettings::get_singleton()->set_custom_property_info("rendering/canvas_textures/default_texture_repeat", PropertyInfo(Variant::INT, "rendering/canvas_textures/default_texture_repeat", PROPERTY_HINT_ENUM, "Disable,Enable,Mirror"));
}
+#ifdef TOOLS_ENABLED
+ if (editor) {
+ bool editor_embed_subwindows = EditorSettings::get_singleton()->get_setting("interface/editor/single_window_mode");
+
+ if (editor_embed_subwindows) {
+ sml->get_root()->set_embed_subwindows_hint(true);
+ }
+ }
+#endif
+
String local_game_path;
if (game_path != "" && !project_manager) {
-
local_game_path = game_path.replace("\\", "/");
if (!local_game_path.begins_with("res://")) {
bool absolute = (local_game_path.size() > 1) && (local_game_path[0] == '/' || local_game_path[1] == ':');
if (!absolute) {
-
if (ProjectSettings::get_singleton()->is_using_datapack()) {
-
local_game_path = "res://" + local_game_path;
} else {
@@ -1945,7 +1987,6 @@ bool Main::start() {
local_game_path = da->get_current_dir().plus_file(local_game_path);
memdelete(da);
} else {
-
DirAccess *da = DirAccess::open(local_game_path.substr(0, sep));
if (da) {
local_game_path = da->get_current_dir().plus_file(local_game_path.substr(sep + 1, local_game_path.length()));
@@ -1960,17 +2001,11 @@ bool Main::start() {
#ifdef TOOLS_ENABLED
if (editor) {
-
- bool editor_embed_subwindows = EditorSettings::get_singleton()->get_setting("interface/editor/single_window_mode");
-
- if (editor_embed_subwindows) {
- sml->get_root()->set_embed_subwindows_hint(true);
- }
-
if (game_path != GLOBAL_GET("application/run/main_scene") || !editor_node->has_scenes_in_session()) {
Error serr = editor_node->load_scene(local_game_path);
- if (serr != OK)
+ if (serr != OK) {
ERR_PRINT("Failed to load scene");
+ }
}
DisplayServer::get_singleton()->set_context(DisplayServer::CONTEXT_EDITOR);
}
@@ -1983,13 +2018,14 @@ bool Main::start() {
if (!project_manager && !editor) { // game
// Load SSL Certificates from Project Settings (or builtin).
- Crypto::load_default_certificates(GLOBAL_DEF("network/ssl/certificates", ""));
+ Crypto::load_default_certificates(GLOBAL_DEF("network/ssl/certificate_bundle_override", ""));
if (game_path != "") {
Node *scene = nullptr;
Ref<PackedScene> scenedata = ResourceLoader::load(local_game_path);
- if (scenedata.is_valid())
+ if (scenedata.is_valid()) {
scene = scenedata->instance();
+ }
ERR_FAIL_COND_V_MSG(!scene, false, "Failed loading scene: " + local_game_path);
sml->add_current_scene(scene);
@@ -2024,7 +2060,6 @@ bool Main::start() {
#ifdef TOOLS_ENABLED
if (project_manager || (script == "" && test == "" && game_path == "" && !editor)) {
-
Engine::get_singleton()->set_editor_hint(true);
ProjectManager *pmanager = memnew(ProjectManager);
ProgressDialog *progress_dialog = memnew(ProgressDialog);
@@ -2035,9 +2070,11 @@ bool Main::start() {
}
if (project_manager || editor) {
- // Hide console window if requested (Windows-only).
- bool hide_console = EditorSettings::get_singleton()->get_setting("interface/editor/hide_console_window");
- DisplayServer::get_singleton()->console_set_visible(!hide_console);
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CONSOLE_WINDOW)) {
+ // Hide console window if requested (Windows-only).
+ bool hide_console = EditorSettings::get_singleton()->get_setting("interface/editor/hide_console_window");
+ DisplayServer::get_singleton()->console_set_visible(!hide_console);
+ }
// Load SSL Certificates from Editor Settings (or builtin)
Crypto::load_default_certificates(EditorSettings::get_singleton()->get_setting("network/ssl/editor_ssl_certificates").operator String());
@@ -2080,7 +2117,6 @@ static uint64_t physics_process_max = 0;
static uint64_t idle_process_max = 0;
bool Main::iteration() {
-
//for now do not error on this
//ERR_FAIL_COND_V(iterating, false);
@@ -2123,7 +2159,6 @@ bool Main::iteration() {
Engine::get_singleton()->_in_physics = true;
for (int iters = 0; iters < advance.physics_steps; ++iters) {
-
uint64_t physics_begin = OS::get_singleton()->get_ticks_usec();
PhysicsServer3D::get_singleton()->sync();
@@ -2165,7 +2200,6 @@ bool Main::iteration() {
RenderingServer::get_singleton()->sync(); //sync if still drawing from previous frames.
if (DisplayServer::get_singleton()->can_any_window_draw() && !disable_render_loop) {
-
if ((!force_redraw_requested) && OS::get_singleton()->is_in_low_processor_usage_mode()) {
if (RenderingServer::get_singleton()->has_changed()) {
RenderingServer::get_singleton()->draw(true, scaled_step); // flush visual commands
@@ -2188,14 +2222,14 @@ bool Main::iteration() {
AudioServer::get_singleton()->update();
- if (EngineDebugger::is_active())
+ if (EngineDebugger::is_active()) {
EngineDebugger::get_singleton()->iteration(frame_time, idle_process_ticks, physics_process_ticks, frame_slice);
+ }
frames++;
Engine::get_singleton()->_idle_frames++;
if (frame > 1000000) {
-
if (editor || project_manager) {
if (print_fps) {
print_line("Editor FPS: " + itos(frames));
@@ -2216,15 +2250,17 @@ bool Main::iteration() {
iterating--;
- if (fixed_fps != -1)
+ if (fixed_fps != -1) {
return exit;
+ }
- if (OS::get_singleton()->is_in_low_processor_usage_mode() || !DisplayServer::get_singleton()->can_any_window_draw())
+ if (OS::get_singleton()->is_in_low_processor_usage_mode() || !DisplayServer::get_singleton()->can_any_window_draw()) {
OS::get_singleton()->delay_usec(OS::get_singleton()->get_low_processor_usage_mode_sleep_usec()); //apply some delay to force idle time
- else {
+ } else {
uint32_t frame_delay = Engine::get_singleton()->get_frame_delay();
- if (frame_delay)
+ if (frame_delay) {
OS::get_singleton()->delay_usec(Engine::get_singleton()->get_frame_delay() * 1000);
+ }
}
int target_fps = Engine::get_singleton()->get_target_fps();
@@ -2232,7 +2268,9 @@ bool Main::iteration() {
uint64_t time_step = 1000000L / target_fps;
target_ticks += time_step;
uint64_t current_ticks = OS::get_singleton()->get_ticks_usec();
- if (current_ticks < target_ticks) OS::get_singleton()->delay_usec(target_ticks - current_ticks);
+ if (current_ticks < target_ticks) {
+ OS::get_singleton()->delay_usec(target_ticks - current_ticks);
+ }
current_ticks = OS::get_singleton()->get_ticks_usec();
target_ticks = MIN(MAX(target_ticks, current_ticks - time_step), current_ticks + time_step);
}
@@ -2264,7 +2302,6 @@ void Main::force_redraw() {
* The order matters as some of those steps are linked with each other.
*/
void Main::cleanup() {
-
ERR_FAIL_COND(!_start_success);
EngineDebugger::deinitialize();
@@ -2328,20 +2365,27 @@ void Main::cleanup() {
memdelete(input);
}
- if (packed_data)
+ if (packed_data) {
memdelete(packed_data);
- if (file_access_network_client)
+ }
+ if (file_access_network_client) {
memdelete(file_access_network_client);
- if (performance)
+ }
+ if (performance) {
memdelete(performance);
- if (input_map)
+ }
+ if (input_map) {
memdelete(input_map);
- if (translation_server)
+ }
+ if (translation_server) {
memdelete(translation_server);
- if (globals)
+ }
+ if (globals) {
memdelete(globals);
- if (engine)
+ }
+ if (engine) {
memdelete(engine);
+ }
if (OS::get_singleton()->is_restart_on_exit_set()) {
//attempt to restart with arguments
diff --git a/main/main.h b/main/main.h
index e8f8357518..ab6917a65c 100644
--- a/main/main.h
+++ b/main/main.h
@@ -36,7 +36,6 @@
#include "core/typedefs.h"
class Main {
-
static void print_help(const char *p_binary);
static uint64_t last_ticks;
static uint64_t target_ticks;
diff --git a/main/main_timer_sync.cpp b/main/main_timer_sync.cpp
index 9e23a1f5cb..5252ea005b 100644
--- a/main/main_timer_sync.cpp
+++ b/main/main_timer_sync.cpp
@@ -56,15 +56,17 @@ int MainTimerSync::get_average_physics_steps(float &p_min, float &p_max) {
for (int i = 1; i < CONTROL_STEPS; ++i) {
const float typical_lower = typical_physics_steps[i];
const float current_min = typical_lower / (i + 1);
- if (current_min > p_max)
+ if (current_min > p_max) {
return i; // bail out of further restrictions would void the interval
- else if (current_min > p_min)
+ } else if (current_min > p_min) {
p_min = current_min;
+ }
const float current_max = (typical_lower + 1) / (i + 1);
- if (current_max < p_min)
+ if (current_max < p_min) {
return i;
- else if (current_max < p_max)
+ } else if (current_max < p_max) {
p_max = current_max;
+ }
}
return CONTROL_STEPS;
@@ -95,10 +97,12 @@ MainFrameTime MainTimerSync::advance_core(float p_frame_slice, int p_iterations_
break;
}
- if (steps_left_to_match_typical > min_typical_steps)
+ if (steps_left_to_match_typical > min_typical_steps) {
min_typical_steps = steps_left_to_match_typical;
- if (steps_left_to_match_typical + 1 < max_typical_steps)
+ }
+ if (steps_left_to_match_typical + 1 < max_typical_steps) {
max_typical_steps = steps_left_to_match_typical + 1;
+ }
}
// try to keep it consistent with previous iterations
@@ -143,8 +147,9 @@ MainFrameTime MainTimerSync::advance_core(float p_frame_slice, int p_iterations_
// calls advance_core, keeps track of deficit it adds to animaption_step, make sure the deficit sum stays close to zero
MainFrameTime MainTimerSync::advance_checked(float p_frame_slice, int p_iterations_per_second, float p_idle_step) {
- if (fixed_fps != -1)
+ if (fixed_fps != -1) {
p_idle_step = 1.0 / fixed_fps;
+ }
// compensate for last deficit
p_idle_step += time_deficit;
@@ -193,12 +198,7 @@ float MainTimerSync::get_cpu_idle_step() {
return cpu_ticks_elapsed / 1000000.0;
}
-MainTimerSync::MainTimerSync() :
- last_cpu_ticks_usec(0),
- current_cpu_ticks_usec(0),
- time_accum(0),
- time_deficit(0),
- fixed_fps(0) {
+MainTimerSync::MainTimerSync() {
for (int i = CONTROL_STEPS - 1; i >= 0; --i) {
typical_physics_steps[i] = i;
accumulated_physics_steps[i] = i;
diff --git a/main/main_timer_sync.h b/main/main_timer_sync.h
index 620d1c747d..2126381c7c 100644
--- a/main/main_timer_sync.h
+++ b/main/main_timer_sync.h
@@ -43,14 +43,14 @@ struct MainFrameTime {
class MainTimerSync {
// wall clock time measured on the main thread
- uint64_t last_cpu_ticks_usec;
- uint64_t current_cpu_ticks_usec;
+ uint64_t last_cpu_ticks_usec = 0;
+ uint64_t current_cpu_ticks_usec = 0;
// logical game time since last physics timestep
- float time_accum;
+ float time_accum = 0;
// current difference between wall clock time and reported sum of idle_steps
- float time_deficit;
+ float time_deficit = 0;
// number of frames back for keeping accumulated physics steps roughly constant.
// value of 12 chosen because that is what is required to make 144 Hz monitors
@@ -64,7 +64,7 @@ class MainTimerSync {
// typical value for accumulated_physics_steps[i] is either this or this plus one
int typical_physics_steps[CONTROL_STEPS];
- int fixed_fps;
+ int fixed_fps = 0;
protected:
// returns the fraction of p_frame_slice required for the timer to overshoot
diff --git a/main/performance.cpp b/main/performance.cpp
index 3ca7d7bed8..7e6b9fca64 100644
--- a/main/performance.cpp
+++ b/main/performance.cpp
@@ -42,7 +42,6 @@
Performance *Performance::singleton = nullptr;
void Performance::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_monitor", "monitor"), &Performance::get_monitor);
BIND_ENUM_CONSTANT(TIME_FPS);
@@ -79,13 +78,13 @@ void Performance::_bind_methods() {
float Performance::_get_node_count() const {
MainLoop *ml = OS::get_singleton()->get_main_loop();
SceneTree *sml = Object::cast_to<SceneTree>(ml);
- if (!sml)
+ if (!sml) {
return 0;
+ }
return sml->get_node_count();
}
String Performance::get_monitor_name(Monitor p_monitor) const {
-
ERR_FAIL_INDEX_V(p_monitor, MONITOR_MAX, String());
static const char *names[MONITOR_MAX] = {
@@ -123,35 +122,61 @@ String Performance::get_monitor_name(Monitor p_monitor) const {
}
float Performance::get_monitor(Monitor p_monitor) const {
-
switch (p_monitor) {
- case TIME_FPS: return Engine::get_singleton()->get_frames_per_second();
- case TIME_PROCESS: return _process_time;
- case TIME_PHYSICS_PROCESS: return _physics_process_time;
- case MEMORY_STATIC: return Memory::get_mem_usage();
- case MEMORY_STATIC_MAX: return Memory::get_mem_max_usage();
- case MEMORY_MESSAGE_BUFFER_MAX: return MessageQueue::get_singleton()->get_max_buffer_usage();
- case OBJECT_COUNT: return ObjectDB::get_object_count();
- case OBJECT_RESOURCE_COUNT: return ResourceCache::get_cached_resource_count();
- case OBJECT_NODE_COUNT: return _get_node_count();
- case OBJECT_ORPHAN_NODE_COUNT: return Node::orphan_node_count;
- case RENDER_OBJECTS_IN_FRAME: return RS::get_singleton()->get_render_info(RS::INFO_OBJECTS_IN_FRAME);
- case RENDER_VERTICES_IN_FRAME: return RS::get_singleton()->get_render_info(RS::INFO_VERTICES_IN_FRAME);
- case RENDER_MATERIAL_CHANGES_IN_FRAME: return RS::get_singleton()->get_render_info(RS::INFO_MATERIAL_CHANGES_IN_FRAME);
- case RENDER_SHADER_CHANGES_IN_FRAME: return RS::get_singleton()->get_render_info(RS::INFO_SHADER_CHANGES_IN_FRAME);
- case RENDER_SURFACE_CHANGES_IN_FRAME: return RS::get_singleton()->get_render_info(RS::INFO_SURFACE_CHANGES_IN_FRAME);
- case RENDER_DRAW_CALLS_IN_FRAME: return RS::get_singleton()->get_render_info(RS::INFO_DRAW_CALLS_IN_FRAME);
- case RENDER_VIDEO_MEM_USED: return RS::get_singleton()->get_render_info(RS::INFO_VIDEO_MEM_USED);
- case RENDER_TEXTURE_MEM_USED: return RS::get_singleton()->get_render_info(RS::INFO_TEXTURE_MEM_USED);
- case RENDER_VERTEX_MEM_USED: return RS::get_singleton()->get_render_info(RS::INFO_VERTEX_MEM_USED);
- case RENDER_USAGE_VIDEO_MEM_TOTAL: return RS::get_singleton()->get_render_info(RS::INFO_USAGE_VIDEO_MEM_TOTAL);
- case PHYSICS_2D_ACTIVE_OBJECTS: return PhysicsServer2D::get_singleton()->get_process_info(PhysicsServer2D::INFO_ACTIVE_OBJECTS);
- case PHYSICS_2D_COLLISION_PAIRS: return PhysicsServer2D::get_singleton()->get_process_info(PhysicsServer2D::INFO_COLLISION_PAIRS);
- case PHYSICS_2D_ISLAND_COUNT: return PhysicsServer2D::get_singleton()->get_process_info(PhysicsServer2D::INFO_ISLAND_COUNT);
- case PHYSICS_3D_ACTIVE_OBJECTS: return PhysicsServer3D::get_singleton()->get_process_info(PhysicsServer3D::INFO_ACTIVE_OBJECTS);
- case PHYSICS_3D_COLLISION_PAIRS: return PhysicsServer3D::get_singleton()->get_process_info(PhysicsServer3D::INFO_COLLISION_PAIRS);
- case PHYSICS_3D_ISLAND_COUNT: return PhysicsServer3D::get_singleton()->get_process_info(PhysicsServer3D::INFO_ISLAND_COUNT);
- case AUDIO_OUTPUT_LATENCY: return AudioServer::get_singleton()->get_output_latency();
+ case TIME_FPS:
+ return Engine::get_singleton()->get_frames_per_second();
+ case TIME_PROCESS:
+ return _process_time;
+ case TIME_PHYSICS_PROCESS:
+ return _physics_process_time;
+ case MEMORY_STATIC:
+ return Memory::get_mem_usage();
+ case MEMORY_STATIC_MAX:
+ return Memory::get_mem_max_usage();
+ case MEMORY_MESSAGE_BUFFER_MAX:
+ return MessageQueue::get_singleton()->get_max_buffer_usage();
+ case OBJECT_COUNT:
+ return ObjectDB::get_object_count();
+ case OBJECT_RESOURCE_COUNT:
+ return ResourceCache::get_cached_resource_count();
+ case OBJECT_NODE_COUNT:
+ return _get_node_count();
+ case OBJECT_ORPHAN_NODE_COUNT:
+ return Node::orphan_node_count;
+ case RENDER_OBJECTS_IN_FRAME:
+ return RS::get_singleton()->get_render_info(RS::INFO_OBJECTS_IN_FRAME);
+ case RENDER_VERTICES_IN_FRAME:
+ return RS::get_singleton()->get_render_info(RS::INFO_VERTICES_IN_FRAME);
+ case RENDER_MATERIAL_CHANGES_IN_FRAME:
+ return RS::get_singleton()->get_render_info(RS::INFO_MATERIAL_CHANGES_IN_FRAME);
+ case RENDER_SHADER_CHANGES_IN_FRAME:
+ return RS::get_singleton()->get_render_info(RS::INFO_SHADER_CHANGES_IN_FRAME);
+ case RENDER_SURFACE_CHANGES_IN_FRAME:
+ return RS::get_singleton()->get_render_info(RS::INFO_SURFACE_CHANGES_IN_FRAME);
+ case RENDER_DRAW_CALLS_IN_FRAME:
+ return RS::get_singleton()->get_render_info(RS::INFO_DRAW_CALLS_IN_FRAME);
+ case RENDER_VIDEO_MEM_USED:
+ return RS::get_singleton()->get_render_info(RS::INFO_VIDEO_MEM_USED);
+ case RENDER_TEXTURE_MEM_USED:
+ return RS::get_singleton()->get_render_info(RS::INFO_TEXTURE_MEM_USED);
+ case RENDER_VERTEX_MEM_USED:
+ return RS::get_singleton()->get_render_info(RS::INFO_VERTEX_MEM_USED);
+ case RENDER_USAGE_VIDEO_MEM_TOTAL:
+ return RS::get_singleton()->get_render_info(RS::INFO_USAGE_VIDEO_MEM_TOTAL);
+ case PHYSICS_2D_ACTIVE_OBJECTS:
+ return PhysicsServer2D::get_singleton()->get_process_info(PhysicsServer2D::INFO_ACTIVE_OBJECTS);
+ case PHYSICS_2D_COLLISION_PAIRS:
+ return PhysicsServer2D::get_singleton()->get_process_info(PhysicsServer2D::INFO_COLLISION_PAIRS);
+ case PHYSICS_2D_ISLAND_COUNT:
+ return PhysicsServer2D::get_singleton()->get_process_info(PhysicsServer2D::INFO_ISLAND_COUNT);
+ case PHYSICS_3D_ACTIVE_OBJECTS:
+ return PhysicsServer3D::get_singleton()->get_process_info(PhysicsServer3D::INFO_ACTIVE_OBJECTS);
+ case PHYSICS_3D_COLLISION_PAIRS:
+ return PhysicsServer3D::get_singleton()->get_process_info(PhysicsServer3D::INFO_COLLISION_PAIRS);
+ case PHYSICS_3D_ISLAND_COUNT:
+ return PhysicsServer3D::get_singleton()->get_process_info(PhysicsServer3D::INFO_ISLAND_COUNT);
+ case AUDIO_OUTPUT_LATENCY:
+ return AudioServer::get_singleton()->get_output_latency();
default: {
}
@@ -199,17 +224,14 @@ Performance::MonitorType Performance::get_monitor_type(Monitor p_monitor) const
}
void Performance::set_process_time(float p_pt) {
-
_process_time = p_pt;
}
void Performance::set_physics_process_time(float p_pt) {
-
_physics_process_time = p_pt;
}
Performance::Performance() {
-
_process_time = 0;
_physics_process_time = 0;
singleton = this;
diff --git a/main/performance.h b/main/performance.h
index c0f6044ea0..ddbe45fa00 100644
--- a/main/performance.h
+++ b/main/performance.h
@@ -37,7 +37,6 @@
#define PERF_WARN_PROCESS_SYNC
class Performance : public Object {
-
GDCLASS(Performance, Object);
static Performance *singleton;
diff --git a/main/tests/test_astar.cpp b/main/tests/test_astar.cpp
index e0b4a7f2c8..fe335589b0 100644
--- a/main/tests/test_astar.cpp
+++ b/main/tests/test_astar.cpp
@@ -173,7 +173,9 @@ bool test_add_remove() {
for (int i = 0; i < 20000; i++) {
int u = Math::rand() % 5;
int v = Math::rand() % 4;
- if (u == v) v = 4;
+ if (u == v) {
+ v = 4;
+ }
if (Math::rand() % 2 == 1) {
// Add a (possibly existing) directed edge and confirm connectivity
a.connect_points(u, v, false);
@@ -188,18 +190,22 @@ bool test_add_remove() {
// Random tests for point removal
for (int i = 0; i < 20000; i++) {
a.clear();
- for (int j = 0; j < 5; j++)
+ for (int j = 0; j < 5; j++) {
a.add_point(j, Vector3(0, 0, 0));
+ }
// Add or remove random edges
for (int j = 0; j < 10; j++) {
int u = Math::rand() % 5;
int v = Math::rand() % 4;
- if (u == v) v = 4;
- if (Math::rand() % 2 == 1)
+ if (u == v) {
+ v = 4;
+ }
+ if (Math::rand() % 2 == 1) {
a.connect_points(u, v, false);
- else
+ } else {
a.disconnect_points(u, v, false);
+ }
}
// Remove point 0
@@ -239,7 +245,9 @@ bool test_solutions() {
int u, v;
u = Math::rand() % N;
v = Math::rand() % (N - 1);
- if (u == v) v = N - 1;
+ if (u == v) {
+ v = N - 1;
+ }
// Pick a random operation
int op = Math::rand();
@@ -253,14 +261,18 @@ bool test_solutions() {
// Add edge (u, v); possibly bidirectional
a.connect_points(u, v, op % 2);
adj[u][v] = true;
- if (op % 2) adj[v][u] = true;
+ if (op % 2) {
+ adj[v][u] = true;
+ }
break;
case 6:
case 7:
// Remove edge (u, v); possibly bidirectional
a.disconnect_points(u, v, op % 2);
adj[u][v] = false;
- if (op % 2) adj[v][u] = false;
+ if (op % 2) {
+ adj[v][u] = false;
+ }
break;
case 8:
// Remove point u and add it back; clears adjacent edges and changes coordinates
@@ -269,40 +281,55 @@ bool test_solutions() {
p[u].y = Math::rand() % 100;
p[u].z = Math::rand() % 100;
a.add_point(u, p[u]);
- for (v = 0; v < N; v++)
+ for (v = 0; v < N; v++) {
adj[u][v] = adj[v][u] = false;
+ }
break;
}
}
// Floyd-Warshall
float d[N][N];
- for (int u = 0; u < N; u++)
- for (int v = 0; v < N; v++)
+ for (int u = 0; u < N; u++) {
+ for (int v = 0; v < N; v++) {
d[u][v] = (u == v || adj[u][v]) ? p[u].distance_to(p[v]) : INFINITY;
+ }
+ }
- for (int w = 0; w < N; w++)
- for (int u = 0; u < N; u++)
- for (int v = 0; v < N; v++)
- if (d[u][v] > d[u][w] + d[w][v])
+ for (int w = 0; w < N; w++) {
+ for (int u = 0; u < N; u++) {
+ for (int v = 0; v < N; v++) {
+ if (d[u][v] > d[u][w] + d[w][v]) {
d[u][v] = d[u][w] + d[w][v];
+ }
+ }
+ }
+ }
// Display statistics
int count = 0;
- for (int u = 0; u < N; u++)
- for (int v = 0; v < N; v++)
- if (adj[u][v]) count++;
+ for (int u = 0; u < N; u++) {
+ for (int v = 0; v < N; v++) {
+ if (adj[u][v]) {
+ count++;
+ }
+ }
+ }
printf("Test #%4d: %3d edges, ", test + 1, count);
count = 0;
- for (int u = 0; u < N; u++)
- for (int v = 0; v < N; v++)
- if (!Math::is_inf(d[u][v])) count++;
+ for (int u = 0; u < N; u++) {
+ for (int v = 0; v < N; v++) {
+ if (!Math::is_inf(d[u][v])) {
+ count++;
+ }
+ }
+ }
printf("%3d/%d pairs of reachable points\n", count - N, N * (N - 1));
// Check A*'s output
bool match = true;
- for (int u = 0; u < N; u++)
- for (int v = 0; v < N; v++)
+ for (int u = 0; u < N; u++) {
+ for (int v = 0; v < N; v++) {
if (u != v) {
Vector<int> route = a.get_id_path(u, v);
if (!Math::is_inf(d[u][v])) {
@@ -337,14 +364,18 @@ bool test_solutions() {
}
}
}
+ }
+ }
exit:
- if (!match) return false;
+ if (!match) {
+ return false;
+ }
}
return true;
}
-typedef bool (*TestFunc)(void);
+typedef bool (*TestFunc)();
TestFunc test_funcs[] = {
test_abc,
@@ -359,11 +390,13 @@ MainLoop *test() {
int passed = 0;
while (true) {
- if (!test_funcs[count])
+ if (!test_funcs[count]) {
break;
+ }
bool pass = test_funcs[count]();
- if (pass)
+ if (pass) {
passed++;
+ }
OS::get_singleton()->print("\t%s\n", pass ? "PASS" : "FAILED");
count++;
diff --git a/main/tests/test_class_db.cpp b/main/tests/test_class_db.cpp
new file mode 100644
index 0000000000..3171091402
--- /dev/null
+++ b/main/tests/test_class_db.cpp
@@ -0,0 +1,882 @@
+/*************************************************************************/
+/* test_class_db.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "test_class_db.h"
+
+#include "core/global_constants.h"
+#include "core/ordered_hash_map.h"
+#include "core/os/os.h"
+#include "core/string_name.h"
+#include "core/ustring.h"
+#include "core/variant.h"
+
+namespace TestClassDB {
+
+enum class [[nodiscard]] TestResult{
+ FAILED,
+ PASS
+};
+
+#define TEST_FAIL_COND(m_cond, m_msg) \
+ if (unlikely(m_cond)) { \
+ ERR_PRINT(m_msg); \
+ return TestResult::FAILED; \
+ } else \
+ ((void)0)
+
+#define TEST_COND(m_cond, m_msg) \
+ if (unlikely(m_cond)) { \
+ ERR_PRINT(m_msg); \
+ __test_result__ = TestResult::FAILED; \
+ } else \
+ ((void)0)
+
+#define TEST_FAIL_CHECK(m_test_expr) \
+ if (unlikely((m_test_expr) == TestResult::FAILED)) { \
+ return TestResult::FAILED; \
+ } else \
+ ((void)0)
+
+#define TEST_CHECK(m_test_expr) \
+ if (unlikely((m_test_expr) == TestResult::FAILED)) { \
+ __test_result__ = TestResult::FAILED; \
+ } else \
+ ((void)0)
+
+#define TEST_START() \
+ TestResult __test_result__ = TestResult::PASS; \
+ ((void)0)
+
+#define TEST_END() return __test_result__;
+
+struct TypeReference {
+ StringName name;
+ bool is_enum = false;
+};
+
+struct ConstantData {
+ String name;
+ int value = 0;
+};
+
+struct EnumData {
+ StringName name;
+ List<ConstantData> constants;
+
+ _FORCE_INLINE_ bool operator==(const EnumData &p_enum) const {
+ return p_enum.name == name;
+ }
+};
+
+struct PropertyData {
+ StringName name;
+ int index = 0;
+
+ StringName getter;
+ StringName setter;
+};
+
+struct ArgumentData {
+ TypeReference type;
+ String name;
+ bool has_defval = false;
+ Variant defval;
+};
+
+struct MethodData {
+ StringName name;
+ TypeReference return_type;
+ List<ArgumentData> arguments;
+ bool is_virtual = false;
+ bool is_vararg = false;
+};
+
+struct SignalData {
+ StringName name;
+ List<ArgumentData> arguments;
+};
+
+struct ExposedClass {
+ StringName name;
+ StringName base;
+
+ bool is_singleton = false;
+ bool is_instantiable = false;
+ bool is_reference = false;
+
+ ClassDB::APIType api_type;
+
+ List<ConstantData> constants;
+ List<EnumData> enums;
+ List<PropertyData> properties;
+ List<MethodData> methods;
+ List<SignalData> signals_;
+
+ const PropertyData *find_property_by_name(const StringName &p_name) const {
+ for (const List<PropertyData>::Element *E = properties.front(); E; E = E->next()) {
+ if (E->get().name == p_name) {
+ return &E->get();
+ }
+ }
+
+ return nullptr;
+ }
+
+ const MethodData *find_method_by_name(const StringName &p_name) const {
+ for (const List<MethodData>::Element *E = methods.front(); E; E = E->next()) {
+ if (E->get().name == p_name) {
+ return &E->get();
+ }
+ }
+
+ return nullptr;
+ }
+};
+
+struct NamesCache {
+ StringName variant_type = StaticCString::create("Variant");
+ StringName object_class = StaticCString::create("Object");
+ StringName reference_class = StaticCString::create("Reference");
+ StringName string_type = StaticCString::create("String");
+ StringName string_name_type = StaticCString::create("StringName");
+ StringName node_path_type = StaticCString::create("NodePath");
+ StringName bool_type = StaticCString::create("bool");
+ StringName int_type = StaticCString::create("int");
+ StringName float_type = StaticCString::create("float");
+ StringName void_type = StaticCString::create("void");
+ StringName vararg_stub_type = StaticCString::create("@VarArg@");
+ StringName vector2_type = StaticCString::create("Vector2");
+ StringName rect2_type = StaticCString::create("Rect2");
+ StringName vector3_type = StaticCString::create("Vector3");
+
+ // Object not included as it must be checked for all derived classes
+ static constexpr int nullable_types_count = 17;
+ StringName nullable_types[nullable_types_count] = {
+ string_type,
+ string_name_type,
+ node_path_type,
+
+ StaticCString::create(_STR(Array)),
+ StaticCString::create(_STR(Dictionary)),
+ StaticCString::create(_STR(Callable)),
+ StaticCString::create(_STR(Signal)),
+
+ StaticCString::create(_STR(PackedByteArray)),
+ StaticCString::create(_STR(PackedInt32Array)),
+ StaticCString::create(_STR(PackedInt64rray)),
+ StaticCString::create(_STR(PackedFloat32Array)),
+ StaticCString::create(_STR(PackedFloat64Array)),
+ StaticCString::create(_STR(PackedStringArray)),
+ StaticCString::create(_STR(PackedVector2Array)),
+ StaticCString::create(_STR(PackedVector3Array)),
+ StaticCString::create(_STR(PackedColorArray)),
+ };
+
+ bool is_nullable_type(const StringName &p_type) const {
+ for (int i = 0; i < nullable_types_count; i++) {
+ if (p_type == nullable_types[i]) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+};
+
+typedef OrderedHashMap<StringName, ExposedClass> ExposedClasses;
+
+struct Context {
+ Vector<StringName> enum_types;
+ Vector<StringName> builtin_types;
+ ExposedClasses exposed_classes;
+ List<EnumData> global_enums;
+ NamesCache names_cache;
+
+ const ExposedClass *find_exposed_class(const StringName &p_name) const {
+ ExposedClasses::ConstElement elem = exposed_classes.find(p_name);
+ return elem ? &elem.value() : nullptr;
+ }
+
+ const ExposedClass *find_exposed_class(const TypeReference &p_type_ref) const {
+ ExposedClasses::ConstElement elem = exposed_classes.find(p_type_ref.name);
+ return elem ? &elem.value() : nullptr;
+ }
+
+ bool has_type(const TypeReference &p_type_ref) const {
+ if (builtin_types.find(p_type_ref.name) >= 0) {
+ return true;
+ }
+
+ if (p_type_ref.is_enum) {
+ if (enum_types.find(p_type_ref.name) >= 0) {
+ return true;
+ }
+
+ // Enum not found. Most likely because none of its constants were bound, so it's empty. That's fine. Use int instead.
+ return builtin_types.find(names_cache.int_type);
+ }
+
+ return false;
+ }
+};
+
+bool arg_default_value_is_assignable_to_type(const Context &p_context, const Variant &p_val, const TypeReference &p_arg_type) {
+ if (p_arg_type.name == p_context.names_cache.variant_type) {
+ // Variant can take anything
+ return true;
+ }
+
+ switch (p_val.get_type()) {
+ case Variant::NIL:
+ return p_context.find_exposed_class(p_arg_type) ||
+ p_context.names_cache.is_nullable_type(p_arg_type.name);
+ case Variant::BOOL:
+ return p_arg_type.name == p_context.names_cache.bool_type;
+ case Variant::INT:
+ return p_arg_type.name == p_context.names_cache.int_type ||
+ p_arg_type.name == p_context.names_cache.float_type ||
+ p_arg_type.is_enum;
+ case Variant::FLOAT:
+ return p_arg_type.name == p_context.names_cache.float_type;
+ case Variant::STRING:
+ case Variant::STRING_NAME:
+ return p_arg_type.name == p_context.names_cache.string_type ||
+ p_arg_type.name == p_context.names_cache.string_name_type ||
+ p_arg_type.name == p_context.names_cache.node_path_type;
+ case Variant::NODE_PATH:
+ return p_arg_type.name == p_context.names_cache.node_path_type;
+ case Variant::TRANSFORM:
+ case Variant::TRANSFORM2D:
+ case Variant::BASIS:
+ case Variant::QUAT:
+ case Variant::PLANE:
+ case Variant::AABB:
+ case Variant::COLOR:
+ case Variant::VECTOR2:
+ case Variant::RECT2:
+ case Variant::VECTOR3:
+ case Variant::_RID:
+ case Variant::ARRAY:
+ case Variant::DICTIONARY:
+ case Variant::PACKED_BYTE_ARRAY:
+ case Variant::PACKED_INT32_ARRAY:
+ case Variant::PACKED_INT64_ARRAY:
+ case Variant::PACKED_FLOAT32_ARRAY:
+ case Variant::PACKED_FLOAT64_ARRAY:
+ case Variant::PACKED_STRING_ARRAY:
+ case Variant::PACKED_VECTOR2_ARRAY:
+ case Variant::PACKED_VECTOR3_ARRAY:
+ case Variant::PACKED_COLOR_ARRAY:
+ case Variant::CALLABLE:
+ case Variant::SIGNAL:
+ return p_arg_type.name == Variant::get_type_name(p_val.get_type());
+ case Variant::OBJECT:
+ return p_context.find_exposed_class(p_arg_type);
+ case Variant::VECTOR2I:
+ return p_arg_type.name == p_context.names_cache.vector2_type ||
+ p_arg_type.name == Variant::get_type_name(p_val.get_type());
+ case Variant::RECT2I:
+ return p_arg_type.name == p_context.names_cache.rect2_type ||
+ p_arg_type.name == Variant::get_type_name(p_val.get_type());
+ case Variant::VECTOR3I:
+ return p_arg_type.name == p_context.names_cache.vector3_type ||
+ p_arg_type.name == Variant::get_type_name(p_val.get_type());
+ default:
+ ERR_PRINT("Unexpected Variant type: " + itos(p_val.get_type()));
+ break;
+ }
+
+ return false;
+}
+
+TestResult validate_property(const Context &p_context, const ExposedClass &p_class, const PropertyData &p_prop) {
+ TEST_START();
+
+ const MethodData *setter = p_class.find_method_by_name(p_prop.setter);
+
+ // Search it in base classes too
+ const ExposedClass *top = &p_class;
+ while (!setter && top->base != StringName()) {
+ top = p_context.find_exposed_class(top->base);
+ TEST_FAIL_COND(!top, "Class not found '" + top->base + "'. Inherited by '" + top->name + "'.");
+ setter = top->find_method_by_name(p_prop.setter);
+ }
+
+ const MethodData *getter = p_class.find_method_by_name(p_prop.getter);
+
+ // Search it in base classes too
+ top = &p_class;
+ while (!getter && top->base != StringName()) {
+ top = p_context.find_exposed_class(top->base);
+ TEST_FAIL_COND(!top, "Class not found '" + top->base + "'. Inherited by '" + top->name + "'.");
+ getter = top->find_method_by_name(p_prop.getter);
+ }
+
+ TEST_FAIL_COND(!setter && !getter,
+ "Couldn't find neither the setter nor the getter for property: '" + p_class.name + "." + String(p_prop.name) + "'.");
+
+ if (setter) {
+ int setter_argc = p_prop.index != -1 ? 2 : 1;
+ TEST_FAIL_COND(setter->arguments.size() != setter_argc,
+ "Invalid property setter argument count: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ }
+
+ if (getter) {
+ int getter_argc = p_prop.index != -1 ? 1 : 0;
+ TEST_FAIL_COND(getter->arguments.size() != getter_argc,
+ "Invalid property setter argument count: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ }
+
+ if (getter && setter) {
+ const ArgumentData &setter_first_arg = setter->arguments.back()->get();
+ if (getter->return_type.name != setter_first_arg.type.name) {
+ // Special case for Node::set_name
+ bool whitelisted = getter->return_type.name == p_context.names_cache.string_name_type &&
+ setter_first_arg.type.name == p_context.names_cache.string_type;
+
+ TEST_FAIL_COND(!whitelisted,
+ "Return type from getter doesn't match first argument of setter, for property: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ }
+ }
+
+ const TypeReference &prop_type_ref = getter ? getter->return_type : setter->arguments.back()->get().type;
+
+ const ExposedClass *prop_class = p_context.find_exposed_class(prop_type_ref);
+ if (prop_class) {
+ TEST_COND(prop_class->is_singleton,
+ "Property type is a singleton: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ } else {
+ TEST_FAIL_COND(!p_context.has_type(prop_type_ref),
+ "Property type '" + prop_type_ref.name + "' not found: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ }
+
+ if (getter) {
+ if (p_prop.index != -1) {
+ const ArgumentData &idx_arg = getter->arguments.front()->get();
+ if (idx_arg.type.name != p_context.names_cache.int_type) {
+ // If not an int, it can be an enum
+ TEST_COND(p_context.enum_types.find(idx_arg.type.name) < 0,
+ "Invalid type '" + idx_arg.type.name + "' for index argument of property getter: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ }
+ }
+ }
+
+ if (setter) {
+ if (p_prop.index != -1) {
+ const ArgumentData &idx_arg = setter->arguments.front()->get();
+ if (idx_arg.type.name != p_context.names_cache.int_type) {
+ // Assume the index parameter is an enum
+ // If not an int, it can be an enum
+ TEST_COND(p_context.enum_types.find(idx_arg.type.name) < 0,
+ "Invalid type '" + idx_arg.type.name + "' for index argument of property setter: '" + p_class.name + "." + String(p_prop.name) + "'.");
+ }
+ }
+ }
+
+ TEST_END();
+}
+
+TestResult validate_method(const Context &p_context, const ExposedClass &p_class, const MethodData &p_method) {
+ TEST_START();
+
+ const ExposedClass *return_class = p_context.find_exposed_class(p_method.return_type);
+ if (return_class) {
+ TEST_COND(return_class->is_singleton,
+ "Method return type is a singleton: '" + p_class.name + "." + p_method.name + "'.");
+ }
+
+ for (const List<ArgumentData>::Element *F = p_method.arguments.front(); F; F = F->next()) {
+ const ArgumentData &arg = F->get();
+
+ const ExposedClass *arg_class = p_context.find_exposed_class(arg.type);
+ if (arg_class) {
+ TEST_COND(arg_class->is_singleton,
+ "Argument type is a singleton: '" + arg.name + "' of method '" + p_class.name + "." + p_method.name + "'.");
+ } else {
+ TEST_FAIL_COND(!p_context.has_type(arg.type),
+ "Argument type '" + arg.type.name + "' not found: '" + arg.name + "' of method" + p_class.name + "." + p_method.name + "'.");
+ }
+
+ if (arg.has_defval) {
+ TEST_COND(!arg_default_value_is_assignable_to_type(p_context, arg.defval, arg.type),
+ "Invalid default value for parameter '" + arg.name + "' of method '" + p_class.name + "." + p_method.name + "'.");
+ }
+ }
+
+ TEST_END();
+}
+
+TestResult validate_signal(const Context &p_context, const ExposedClass &p_class, const SignalData &p_signal) {
+ TEST_START();
+
+ for (const List<ArgumentData>::Element *F = p_signal.arguments.front(); F; F = F->next()) {
+ const ArgumentData &arg = F->get();
+
+ const ExposedClass *arg_class = p_context.find_exposed_class(arg.type);
+ if (arg_class) {
+ TEST_COND(arg_class->is_singleton,
+ "Argument class is a singleton: '" + arg.name + "' of signal" + p_class.name + "." + p_signal.name + "'.");
+ } else {
+ TEST_FAIL_COND(!p_context.has_type(arg.type),
+ "Argument type '" + arg.type.name + "' not found: '" + arg.name + "' of signal" + p_class.name + "." + p_signal.name + "'.");
+ }
+ }
+
+ TEST_END();
+}
+
+TestResult validate_class(const Context &p_context, const ExposedClass &p_exposed_class) {
+ TEST_START();
+
+ bool is_derived_type = p_exposed_class.base != StringName();
+
+ if (!is_derived_type) {
+ // Asserts about the base Object class
+ TEST_FAIL_COND(p_exposed_class.name != p_context.names_cache.object_class,
+ "Class '" + p_exposed_class.name + "' has no base class.");
+ TEST_FAIL_COND(!p_exposed_class.is_instantiable,
+ "Object class is not instantiable.");
+ TEST_FAIL_COND(p_exposed_class.api_type != ClassDB::API_CORE,
+ "Object class is API is not API_CORE.");
+ TEST_FAIL_COND(p_exposed_class.is_singleton,
+ "Object class is registered as a singleton.");
+ }
+
+ TEST_FAIL_COND(p_exposed_class.is_singleton && p_exposed_class.base != p_context.names_cache.object_class,
+ "Singleton base class '" + String(p_exposed_class.base) + "' is not Object, for class '" + p_exposed_class.name + "'.");
+
+ TEST_FAIL_COND(is_derived_type && !p_context.exposed_classes.has(p_exposed_class.base),
+ "Base type '" + p_exposed_class.base.operator String() + "' does not exist, for class '" + p_exposed_class.name + "'.");
+
+ for (const List<PropertyData>::Element *F = p_exposed_class.properties.front(); F; F = F->next()) {
+ TEST_CHECK(validate_property(p_context, p_exposed_class, F->get()));
+ }
+
+ for (const List<MethodData>::Element *F = p_exposed_class.methods.front(); F; F = F->next()) {
+ TEST_CHECK(validate_method(p_context, p_exposed_class, F->get()));
+ }
+
+ for (const List<SignalData>::Element *F = p_exposed_class.signals_.front(); F; F = F->next()) {
+ TEST_CHECK(validate_signal(p_context, p_exposed_class, F->get()));
+ }
+
+ TEST_END();
+}
+
+TestResult add_exposed_classes(Context &r_context) {
+ TEST_START();
+
+ List<StringName> class_list;
+ ClassDB::get_class_list(&class_list);
+ class_list.sort_custom<StringName::AlphCompare>();
+
+ while (class_list.size()) {
+ StringName class_name = class_list.front()->get();
+
+ ClassDB::APIType api_type = ClassDB::get_api_type(class_name);
+
+ if (api_type == ClassDB::API_NONE) {
+ class_list.pop_front();
+ continue;
+ }
+
+ if (!ClassDB::is_class_exposed(class_name)) {
+ OS::get_singleton()->print("Ignoring class '%s' because it's not exposed\n", String(class_name).utf8().get_data());
+ class_list.pop_front();
+ continue;
+ }
+
+ if (!ClassDB::is_class_enabled(class_name)) {
+ OS::get_singleton()->print("Ignoring class '%s' because it's not enabled\n", String(class_name).utf8().get_data());
+ class_list.pop_front();
+ continue;
+ }
+
+ ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(class_name);
+
+ ExposedClass exposed_class;
+ exposed_class.name = class_name;
+ exposed_class.api_type = api_type;
+ exposed_class.is_singleton = Engine::get_singleton()->has_singleton(class_name);
+ exposed_class.is_instantiable = class_info->creation_func && !exposed_class.is_singleton;
+ exposed_class.is_reference = ClassDB::is_parent_class(class_name, "Reference");
+ exposed_class.base = ClassDB::get_parent_class(class_name);
+
+ // Add properties
+
+ List<PropertyInfo> property_list;
+ ClassDB::get_property_list(class_name, &property_list, true);
+
+ Map<StringName, StringName> accessor_methods;
+
+ for (const List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
+ const PropertyInfo &property = E->get();
+
+ if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_SUBGROUP || property.usage & PROPERTY_USAGE_CATEGORY) {
+ continue;
+ }
+
+ PropertyData prop;
+ prop.name = property.name;
+ prop.setter = ClassDB::get_property_setter(class_name, prop.name);
+ prop.getter = ClassDB::get_property_getter(class_name, prop.name);
+
+ if (prop.setter != StringName()) {
+ accessor_methods[prop.setter] = prop.name;
+ }
+ if (prop.getter != StringName()) {
+ accessor_methods[prop.getter] = prop.name;
+ }
+
+ bool valid = false;
+ prop.index = ClassDB::get_property_index(class_name, prop.name, &valid);
+ TEST_FAIL_COND(!valid, "Invalid property: '" + exposed_class.name + "." + String(prop.name) + "'.");
+
+ exposed_class.properties.push_back(prop);
+ }
+
+ // Add methods
+
+ List<MethodInfo> virtual_method_list;
+ ClassDB::get_virtual_methods(class_name, &virtual_method_list, true);
+
+ List<MethodInfo> method_list;
+ ClassDB::get_method_list(class_name, &method_list, true);
+ method_list.sort();
+
+ for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) {
+ const MethodInfo &method_info = E->get();
+
+ int argc = method_info.arguments.size();
+
+ if (method_info.name.empty()) {
+ continue;
+ }
+
+ MethodData method;
+ method.name = method_info.name;
+
+ if (method_info.flags & METHOD_FLAG_VIRTUAL) {
+ method.is_virtual = true;
+ }
+
+ PropertyInfo return_info = method_info.return_val;
+
+ MethodBind *m = method.is_virtual ? nullptr : ClassDB::get_method(class_name, method_info.name);
+
+ method.is_vararg = m && m->is_vararg();
+
+ if (!m && !method.is_virtual) {
+ TEST_FAIL_COND(!virtual_method_list.find(method_info),
+ "Missing MethodBind for non-virtual method: '" + exposed_class.name + "." + method.name + "'.");
+
+ // A virtual method without the virtual flag. This is a special case.
+
+ // The method Object.free is registered as a virtual method, but without the virtual flag.
+ // This is because this method is not supposed to be overridden, but called.
+ // We assume the return type is void.
+ method.return_type.name = r_context.names_cache.void_type;
+
+ // Actually, more methods like this may be added in the future, which could return
+ // something different. Let's put this check to notify us if that ever happens.
+ if (exposed_class.name != r_context.names_cache.object_class || String(method.name) != "free") {
+ WARN_PRINT("Notification: New unexpected virtual non-overridable method found."
+ " We only expected Object.free, but found '" +
+ exposed_class.name + "." + method.name + "'.");
+ }
+ } else if (return_info.type == Variant::INT && return_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ method.return_type.name = return_info.class_name;
+ method.return_type.is_enum = true;
+ } else if (return_info.class_name != StringName()) {
+ method.return_type.name = return_info.class_name;
+
+ bool bad_reference_hint = !method.is_virtual && return_info.hint != PROPERTY_HINT_RESOURCE_TYPE &&
+ ClassDB::is_parent_class(return_info.class_name, r_context.names_cache.reference_class);
+ TEST_COND(bad_reference_hint, String() + "Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'." +
+ " Are you returning a reference type by pointer? Method: '" +
+ exposed_class.name + "." + method.name + "'.");
+ } else if (return_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ method.return_type.name = return_info.hint_string;
+ } else if (return_info.type == Variant::NIL && return_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
+ method.return_type.name = r_context.names_cache.variant_type;
+ } else if (return_info.type == Variant::NIL) {
+ method.return_type.name = r_context.names_cache.void_type;
+ } else {
+ // NOTE: We don't care about the size and sign of int and float in these tests
+ method.return_type.name = Variant::get_type_name(return_info.type);
+ }
+
+ for (int i = 0; i < argc; i++) {
+ PropertyInfo arg_info = method_info.arguments[i];
+
+ String orig_arg_name = arg_info.name;
+
+ ArgumentData arg;
+ arg.name = orig_arg_name;
+
+ if (arg_info.type == Variant::INT && arg_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ arg.type.name = arg_info.class_name;
+ arg.type.is_enum = true;
+ } else if (arg_info.class_name != StringName()) {
+ arg.type.name = arg_info.class_name;
+ } else if (arg_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ arg.type.name = arg_info.hint_string;
+ } else if (arg_info.type == Variant::NIL) {
+ arg.type.name = r_context.names_cache.variant_type;
+ } else {
+ // NOTE: We don't care about the size and sign of int and float in these tests
+ arg.type.name = Variant::get_type_name(arg_info.type);
+ }
+
+ if (m && m->has_default_argument(i)) {
+ arg.has_defval = true;
+ arg.defval = m->get_default_argument(i);
+ }
+
+ method.arguments.push_back(arg);
+ }
+
+ if (method.is_vararg) {
+ ArgumentData vararg;
+ vararg.type.name = r_context.names_cache.vararg_stub_type;
+ vararg.name = "@varargs@";
+ method.arguments.push_back(vararg);
+ }
+
+ TEST_COND(exposed_class.find_property_by_name(method.name),
+ "Method name conflicts with property: '" + String(class_name) + "." + String(method.name) + "'.");
+
+ // Classes starting with an underscore are ignored unless they're used as a property setter or getter
+ if (!method.is_virtual && String(method.name)[0] == '_') {
+ for (const List<PropertyData>::Element *F = exposed_class.properties.front(); F; F = F->next()) {
+ const PropertyData &prop = F->get();
+
+ if (prop.setter == method.name || prop.getter == method.name) {
+ exposed_class.methods.push_back(method);
+ break;
+ }
+ }
+ } else {
+ exposed_class.methods.push_back(method);
+ }
+ }
+
+ // Add signals
+
+ const HashMap<StringName, MethodInfo> &signal_map = class_info->signal_map;
+ const StringName *k = nullptr;
+
+ while ((k = signal_map.next(k))) {
+ SignalData signal;
+
+ const MethodInfo &method_info = signal_map.get(*k);
+
+ signal.name = method_info.name;
+
+ int argc = method_info.arguments.size();
+
+ for (int i = 0; i < argc; i++) {
+ PropertyInfo arg_info = method_info.arguments[i];
+
+ String orig_arg_name = arg_info.name;
+
+ ArgumentData arg;
+ arg.name = orig_arg_name;
+
+ if (arg_info.type == Variant::INT && arg_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ arg.type.name = arg_info.class_name;
+ arg.type.is_enum = true;
+ } else if (arg_info.class_name != StringName()) {
+ arg.type.name = arg_info.class_name;
+ } else if (arg_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
+ arg.type.name = arg_info.hint_string;
+ } else if (arg_info.type == Variant::NIL) {
+ arg.type.name = r_context.names_cache.variant_type;
+ } else {
+ // NOTE: We don't care about the size and sign of int and float in these tests
+ arg.type.name = Variant::get_type_name(arg_info.type);
+ }
+
+ signal.arguments.push_back(arg);
+ }
+
+ bool method_conflict = exposed_class.find_property_by_name(signal.name);
+
+ if (method_conflict || exposed_class.find_method_by_name(signal.name)) {
+ // TODO:
+ // ClassDB allows signal names that conflict with method or property names.
+ // However registering a signal with a conflicting name is still considered wrong.
+ // Unfortunately there are some existing cases that are yet to be fixed.
+ // Until those are fixed we will print a warning instead of failing the test.
+ WARN_PRINT("Signal name conflicts with " + String(method_conflict ? "method" : "property") +
+ ": '" + String(class_name) + "." + String(signal.name) + "'.");
+ }
+
+ exposed_class.signals_.push_back(signal);
+ }
+
+ // Add enums and constants
+
+ List<String> constants;
+ ClassDB::get_integer_constant_list(class_name, &constants, true);
+
+ const HashMap<StringName, List<StringName>> &enum_map = class_info->enum_map;
+ k = nullptr;
+
+ while ((k = enum_map.next(k))) {
+ EnumData enum_;
+ enum_.name = *k;
+
+ const List<StringName> &enum_constants = enum_map.get(*k);
+ for (const List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) {
+ const StringName &constant_name = E->get();
+ int *value = class_info->constant_map.getptr(constant_name);
+ TEST_FAIL_COND(!value, "Missing enum constant value: '" +
+ String(class_name) + "." + String(enum_.name) + "." + String(constant_name) + "'.");
+ constants.erase(constant_name);
+
+ ConstantData constant;
+ constant.name = constant_name;
+ constant.value = *value;
+
+ enum_.constants.push_back(constant);
+ }
+
+ exposed_class.enums.push_back(enum_);
+
+ r_context.enum_types.push_back(String(class_name) + "." + String(*k));
+ }
+
+ for (const List<String>::Element *E = constants.front(); E; E = E->next()) {
+ const String &constant_name = E->get();
+ int *value = class_info->constant_map.getptr(StringName(E->get()));
+ TEST_FAIL_COND(!value, "Missing enum constant value: '" + String(class_name) + "." + String(constant_name) + "'.");
+
+ ConstantData constant;
+ constant.name = constant_name;
+ constant.value = *value;
+
+ exposed_class.constants.push_back(constant);
+ }
+
+ r_context.exposed_classes.insert(class_name, exposed_class);
+ class_list.pop_front();
+ }
+
+ TEST_END();
+}
+
+void add_builtin_types(Context &r_context) {
+ // NOTE: We don't care about the size and sign of int and float in these tests
+ for (int i = 0; i < Variant::VARIANT_MAX; i++) {
+ r_context.builtin_types.push_back(Variant::get_type_name(Variant::Type(i)));
+ }
+
+ r_context.builtin_types.push_back(_STR(Variant));
+ r_context.builtin_types.push_back(r_context.names_cache.vararg_stub_type);
+ r_context.builtin_types.push_back("void");
+}
+
+void add_global_enums(Context &r_context) {
+ int global_constants_count = GlobalConstants::get_global_constant_count();
+
+ if (global_constants_count > 0) {
+ for (int i = 0; i < global_constants_count; i++) {
+ StringName enum_name = GlobalConstants::get_global_constant_enum(i);
+
+ if (enum_name != StringName()) {
+ ConstantData constant;
+ constant.name = GlobalConstants::get_global_constant_name(i);
+ constant.value = GlobalConstants::get_global_constant_value(i);
+
+ EnumData enum_;
+ enum_.name = enum_name;
+ List<EnumData>::Element *enum_match = r_context.global_enums.find(enum_);
+ if (enum_match) {
+ enum_match->get().constants.push_back(constant);
+ } else {
+ enum_.constants.push_back(constant);
+ r_context.global_enums.push_back(enum_);
+ }
+ }
+ }
+
+ for (List<EnumData>::Element *E = r_context.global_enums.front(); E; E = E->next()) {
+ r_context.enum_types.push_back(E->get().name);
+ }
+ }
+
+ // HARDCODED
+ List<StringName> hardcoded_enums;
+ hardcoded_enums.push_back("Vector2.Axis");
+ hardcoded_enums.push_back("Vector2i.Axis");
+ hardcoded_enums.push_back("Vector3.Axis");
+ hardcoded_enums.push_back("Vector3i.Axis");
+ for (List<StringName>::Element *E = hardcoded_enums.front(); E; E = E->next()) {
+ // These enums are not generated and must be written manually (e.g.: Vector3.Axis)
+ // Here, we assume core types do not begin with underscore
+ r_context.enum_types.push_back(E->get());
+ }
+}
+
+TestResult run_class_db_tests() {
+ TEST_START();
+
+ Context context;
+
+ TEST_FAIL_CHECK(add_exposed_classes(context));
+ add_builtin_types(context);
+ add_global_enums(context);
+
+ const ExposedClass *object_class = context.find_exposed_class(context.names_cache.object_class);
+ TEST_FAIL_COND(!object_class, "Object class not found.");
+ TEST_FAIL_COND(object_class->base != StringName(),
+ "Object class derives from another class: '" + object_class->base + "'.");
+
+ for (ExposedClasses::Element E = context.exposed_classes.front(); E; E = E.next()) {
+ TEST_CHECK(validate_class(context, E.value()));
+ }
+
+ TEST_END();
+}
+
+MainLoop *test() {
+ TestResult pass = run_class_db_tests();
+
+ OS::get_singleton()->print("ClassDB tests: %s\n", pass == TestResult::PASS ? "PASS" : "FAILED");
+
+ if (pass == TestResult::FAILED) {
+ OS::get_singleton()->set_exit_code(pass == TestResult::PASS ? 0 : 1);
+ }
+
+ return nullptr;
+}
+
+} // namespace TestClassDB
diff --git a/core/path_remap.h b/main/tests/test_class_db.h
index 1580e88625..1a31cfb01b 100644
--- a/core/path_remap.h
+++ b/main/tests/test_class_db.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* path_remap.h */
+/* test_class_db.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef PATH_REMAP_H
-#define PATH_REMAP_H
+#ifndef GODOT_TEST_CLASS_DB_H
+#define GODOT_TEST_CLASS_DB_H
-#endif // PATH_REMAP_H
+#include "core/os/main_loop.h"
+
+namespace TestClassDB {
+
+MainLoop *test();
+
+}
+
+#endif //GODOT_TEST_CLASS_DB_H
diff --git a/main/tests/test_gdscript.cpp b/main/tests/test_gdscript.cpp
index 971460c655..10586c6495 100644
--- a/main/tests/test_gdscript.cpp
+++ b/main/tests/test_gdscript.cpp
@@ -45,7 +45,6 @@
namespace TestGDScript {
static void _print_indent(int p_ident, const String &p_text) {
-
String txt;
for (int i = 0; i < p_ident; i++) {
txt += '\t';
@@ -55,18 +54,18 @@ static void _print_indent(int p_ident, const String &p_text) {
}
static String _parser_extends(const GDScriptParser::ClassNode *p_class) {
-
String txt = "extends ";
if (String(p_class->extends_file) != "") {
txt += "\"" + p_class->extends_file + "\"";
- if (p_class->extends_class.size())
+ if (p_class->extends_class.size()) {
txt += ".";
+ }
}
for (int i = 0; i < p_class->extends_class.size(); i++) {
-
- if (i != 0)
+ if (i != 0) {
txt += ".";
+ }
txt += p_class->extends_class[i];
}
@@ -75,21 +74,19 @@ static String _parser_extends(const GDScriptParser::ClassNode *p_class) {
}
static String _parser_expr(const GDScriptParser::Node *p_expr) {
-
String txt;
switch (p_expr->type) {
-
case GDScriptParser::Node::TYPE_IDENTIFIER: {
-
const GDScriptParser::IdentifierNode *id_node = static_cast<const GDScriptParser::IdentifierNode *>(p_expr);
txt = id_node->name;
} break;
case GDScriptParser::Node::TYPE_CONSTANT: {
const GDScriptParser::ConstantNode *c_node = static_cast<const GDScriptParser::ConstantNode *>(p_expr);
- if (c_node->value.get_type() == Variant::STRING)
+ if (c_node->value.get_type() == Variant::STRING) {
txt = "\"" + String(c_node->value) + "\"";
- else
+ } else {
txt = c_node->value;
+ }
} break;
case GDScriptParser::Node::TYPE_SELF: {
@@ -99,9 +96,9 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
const GDScriptParser::ArrayNode *arr_node = static_cast<const GDScriptParser::ArrayNode *>(p_expr);
txt += "[";
for (int i = 0; i < arr_node->elements.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
txt += ", ";
+ }
txt += _parser_expr(arr_node->elements[i]);
}
txt += "]";
@@ -110,9 +107,9 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
const GDScriptParser::DictionaryNode *dict_node = static_cast<const GDScriptParser::DictionaryNode *>(p_expr);
txt += "{";
for (int i = 0; i < dict_node->elements.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
txt += ", ";
+ }
const GDScriptParser::DictionaryNode::Pair &p = dict_node->elements[i];
txt += _parser_expr(p.key);
@@ -122,37 +119,32 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
txt += "}";
} break;
case GDScriptParser::Node::TYPE_OPERATOR: {
-
const GDScriptParser::OperatorNode *c_node = static_cast<const GDScriptParser::OperatorNode *>(p_expr);
switch (c_node->op) {
-
case GDScriptParser::OperatorNode::OP_PARENT_CALL:
txt += ".";
[[fallthrough]];
case GDScriptParser::OperatorNode::OP_CALL: {
-
ERR_FAIL_COND_V(c_node->arguments.size() < 1, "");
String func_name;
const GDScriptParser::Node *nfunc = c_node->arguments[0];
int arg_ofs = 0;
if (nfunc->type == GDScriptParser::Node::TYPE_BUILT_IN_FUNCTION) {
-
const GDScriptParser::BuiltInFunctionNode *bif_node = static_cast<const GDScriptParser::BuiltInFunctionNode *>(nfunc);
func_name = GDScriptFunctions::get_func_name(bif_node->function);
arg_ofs = 1;
} else if (nfunc->type == GDScriptParser::Node::TYPE_TYPE) {
-
const GDScriptParser::TypeNode *t_node = static_cast<const GDScriptParser::TypeNode *>(nfunc);
func_name = Variant::get_type_name(t_node->vtype);
arg_ofs = 1;
} else {
-
ERR_FAIL_COND_V(c_node->arguments.size() < 2, "");
nfunc = c_node->arguments[1];
ERR_FAIL_COND_V(nfunc->type != GDScriptParser::Node::TYPE_IDENTIFIER, "");
- if (c_node->arguments[0]->type != GDScriptParser::Node::TYPE_SELF)
+ if (c_node->arguments[0]->type != GDScriptParser::Node::TYPE_SELF) {
func_name = _parser_expr(c_node->arguments[0]) + ".";
+ }
func_name += _parser_expr(nfunc);
arg_ofs = 2;
@@ -161,10 +153,10 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
txt += func_name + "(";
for (int i = arg_ofs; i < c_node->arguments.size(); i++) {
-
const GDScriptParser::Node *arg = c_node->arguments[i];
- if (i > arg_ofs)
+ if (i > arg_ofs) {
txt += ", ";
+ }
txt += _parser_expr(arg);
}
@@ -172,7 +164,6 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
} break;
case GDScriptParser::OperatorNode::OP_INDEX: {
-
ERR_FAIL_COND_V(c_node->arguments.size() != 2, "");
//index with []
@@ -180,7 +171,6 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
} break;
case GDScriptParser::OperatorNode::OP_INDEX_NAMED: {
-
ERR_FAIL_COND_V(c_node->arguments.size() != 2, "");
txt = _parser_expr(c_node->arguments[0]) + "." + _parser_expr(c_node->arguments[1]);
@@ -296,11 +286,9 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
} break;
case GDScriptParser::Node::TYPE_NEWLINE: {
-
//skippie
} break;
default: {
-
ERR_FAIL_V_MSG("", "Parser bug at " + itos(p_expr->line) + ", invalid expression type: " + itos(p_expr->type));
}
}
@@ -309,20 +297,14 @@ static String _parser_expr(const GDScriptParser::Node *p_expr) {
}
static void _parser_show_block(const GDScriptParser::BlockNode *p_block, int p_indent) {
-
for (int i = 0; i < p_block->statements.size(); i++) {
-
const GDScriptParser::Node *statement = p_block->statements[i];
switch (statement->type) {
-
case GDScriptParser::Node::TYPE_CONTROL_FLOW: {
-
const GDScriptParser::ControlFlowNode *cf_node = static_cast<const GDScriptParser::ControlFlowNode *>(statement);
switch (cf_node->cf_type) {
-
case GDScriptParser::ControlFlowNode::CF_IF: {
-
ERR_FAIL_COND(cf_node->arguments.size() != 1);
String txt;
txt += "if ";
@@ -351,7 +333,6 @@ static void _parser_show_block(const GDScriptParser::BlockNode *p_block, int p_i
} break;
case GDScriptParser::ControlFlowNode::CF_WHILE: {
-
ERR_FAIL_COND(cf_node->arguments.size() != 1);
String txt;
txt += "while ";
@@ -366,25 +347,22 @@ static void _parser_show_block(const GDScriptParser::BlockNode *p_block, int p_i
// FIXME: Implement
} break;
case GDScriptParser::ControlFlowNode::CF_CONTINUE: {
-
_print_indent(p_indent, "continue");
} break;
case GDScriptParser::ControlFlowNode::CF_BREAK: {
-
_print_indent(p_indent, "break");
} break;
case GDScriptParser::ControlFlowNode::CF_RETURN: {
-
- if (cf_node->arguments.size())
+ if (cf_node->arguments.size()) {
_print_indent(p_indent, "return " + _parser_expr(cf_node->arguments[0]));
- else
+ } else {
_print_indent(p_indent, "return ");
+ }
} break;
}
} break;
case GDScriptParser::Node::TYPE_LOCAL_VAR: {
-
const GDScriptParser::LocalVarNode *lv_node = static_cast<const GDScriptParser::LocalVarNode *>(statement);
_print_indent(p_indent, "var " + String(lv_node->name));
} break;
@@ -397,21 +375,22 @@ static void _parser_show_block(const GDScriptParser::BlockNode *p_block, int p_i
}
static void _parser_show_function(const GDScriptParser::FunctionNode *p_func, int p_indent, GDScriptParser::BlockNode *p_initializer = nullptr) {
-
String txt;
- if (p_func->_static)
+ if (p_func->_static) {
txt = "static ";
+ }
txt += "func ";
- if (p_func->name == "") // initializer
+ if (p_func->name == "") { // initializer
txt += "[built-in-initializer]";
- else
+ } else {
txt += String(p_func->name);
+ }
txt += "(";
for (int i = 0; i < p_func->arguments.size(); i++) {
-
- if (i != 0)
+ if (i != 0) {
txt += ", ";
+ }
txt += "var " + String(p_func->arguments[i]);
if (i >= (p_func->arguments.size() - p_func->default_values.size())) {
int defarg = i - (p_func->arguments.size() - p_func->default_values.size());
@@ -427,25 +406,24 @@ static void _parser_show_function(const GDScriptParser::FunctionNode *p_func, in
txt += ":";
_print_indent(p_indent, txt);
- if (p_initializer)
+ if (p_initializer) {
_parser_show_block(p_initializer, p_indent + 1);
+ }
_parser_show_block(p_func->body, p_indent + 1);
}
static void _parser_show_class(const GDScriptParser::ClassNode *p_class, int p_indent, const Vector<String> &p_code) {
-
if (p_indent == 0 && (String(p_class->extends_file) != "" || p_class->extends_class.size())) {
-
_print_indent(p_indent, _parser_extends(p_class));
print_line("\n");
}
for (int i = 0; i < p_class->subclasses.size(); i++) {
-
const GDScriptParser::ClassNode *subclass = p_class->subclasses[i];
String line = "class " + subclass->name;
- if (String(subclass->extends_file) != "" || subclass->extends_class.size())
+ if (String(subclass->extends_file) != "" || subclass->extends_class.size()) {
line += " " + _parser_extends(subclass);
+ }
line += ":";
_print_indent(p_indent, line);
_parser_show_class(subclass, p_indent + 1, p_code);
@@ -458,7 +436,6 @@ static void _parser_show_class(const GDScriptParser::ClassNode *p_class, int p_i
}
for (int i = 0; i < p_class->variables.size(); i++) {
-
const GDScriptParser::ClassNode::Member &m = p_class->variables[i];
_print_indent(p_indent, "var " + String(m.identifier));
@@ -467,17 +444,16 @@ static void _parser_show_class(const GDScriptParser::ClassNode *p_class, int p_i
print_line("\n");
for (int i = 0; i < p_class->static_functions.size(); i++) {
-
_parser_show_function(p_class->static_functions[i], p_indent);
print_line("\n");
}
for (int i = 0; i < p_class->functions.size(); i++) {
-
if (String(p_class->functions[i]->name) == "_init") {
_parser_show_function(p_class->functions[i], p_indent, p_class->initializer);
- } else
+ } else {
_parser_show_function(p_class->functions[i], p_indent);
+ }
print_line("\n");
}
//_parser_show_function(p_class->initializer,p_indent);
@@ -485,11 +461,9 @@ static void _parser_show_class(const GDScriptParser::ClassNode *p_class, int p_i
}
static String _disassemble_addr(const Ref<GDScript> &p_script, const GDScriptFunction &func, int p_addr) {
-
int addr = p_addr & GDScriptFunction::ADDR_MASK;
switch (p_addr >> GDScriptFunction::ADDR_BITS) {
-
case GDScriptFunction::ADDR_TYPE_SELF: {
return "self";
} break;
@@ -497,33 +471,28 @@ static String _disassemble_addr(const Ref<GDScript> &p_script, const GDScriptFun
return "class";
} break;
case GDScriptFunction::ADDR_TYPE_MEMBER: {
-
return "member(" + p_script->debug_get_member_by_index(addr) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT: {
-
return "class_const(" + func.get_global_name(addr) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT: {
-
Variant v = func.get_constant(addr);
String txt;
- if (v.get_type() == Variant::STRING || v.get_type() == Variant::NODE_PATH)
+ if (v.get_type() == Variant::STRING || v.get_type() == Variant::NODE_PATH) {
txt = "\"" + String(v) + "\"";
- else
+ } else {
txt = v;
+ }
return "const(" + txt + ")";
} break;
case GDScriptFunction::ADDR_TYPE_STACK: {
-
return "stack(" + itos(addr) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_STACK_VARIABLE: {
-
return "var_stack(" + itos(addr) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_GLOBAL: {
-
return "global(" + func.get_global_name(addr) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_NIL: {
@@ -535,11 +504,9 @@ static String _disassemble_addr(const Ref<GDScript> &p_script, const GDScriptFun
}
static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String> &p_code) {
-
const Map<StringName, GDScriptFunction *> &mf = p_class->debug_get_member_functions();
for (const Map<StringName, GDScriptFunction *>::Element *E = mf.front(); E; E = E->next()) {
-
const GDScriptFunction &func = *E->get();
const int *code = func.get_code();
int codelen = func.get_code_size();
@@ -547,9 +514,9 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
if (func.get_default_argument_count()) {
defargs = "defarg at: ";
for (int i = 0; i < func.get_default_argument_count(); i++) {
-
- if (i > 0)
+ if (i > 0) {
defargs += ",";
+ }
defargs += itos(func.get_default_argument_addr(i));
}
defargs += " ";
@@ -559,14 +526,11 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
#define DADDR(m_ip) (_disassemble_addr(p_class, func, code[ip + m_ip]))
for (int ip = 0; ip < codelen;) {
-
int incr = 0;
String txt = itos(ip) + " ";
switch (code[ip]) {
-
case GDScriptFunction::OPCODE_OPERATOR: {
-
int op = code[ip + 1];
txt += " op ";
@@ -581,7 +545,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_SET: {
-
txt += "set ";
txt += DADDR(1);
txt += "[";
@@ -592,7 +555,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_GET: {
-
txt += " get ";
txt += DADDR(3);
txt += "=";
@@ -604,7 +566,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_SET_NAMED: {
-
txt += " set_named ";
txt += DADDR(1);
txt += "[\"";
@@ -615,7 +576,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_GET_NAMED: {
-
txt += " get_named ";
txt += DADDR(3);
txt += "=";
@@ -627,7 +587,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_SET_MEMBER: {
-
txt += " set_member ";
txt += "[\"";
txt += func.get_global_name(code[ip + 1]);
@@ -637,7 +596,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_GET_MEMBER: {
-
txt += " get_member ";
txt += DADDR(2);
txt += "=";
@@ -648,7 +606,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_ASSIGN: {
-
txt += " assign ";
txt += DADDR(1);
txt += "=";
@@ -657,7 +614,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_ASSIGN_TRUE: {
-
txt += " assign ";
txt += DADDR(1);
txt += "= true";
@@ -665,7 +621,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_ASSIGN_FALSE: {
-
txt += " assign ";
txt += DADDR(1);
txt += "= false";
@@ -673,7 +628,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN: {
-
txt += " assign typed builtin (";
txt += Variant::get_type_name((Variant::Type)code[ip + 1]);
txt += ") ";
@@ -697,7 +651,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_CAST_TO_SCRIPT: {
-
txt += " cast ";
txt += DADDR(3);
txt += "=";
@@ -708,7 +661,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_CONSTRUCT: {
-
Variant::Type t = Variant::Type(code[ip + 1]);
int argc = code[ip + 2];
@@ -718,9 +670,9 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
txt += Variant::get_type_name(t) + "(";
for (int i = 0; i < argc; i++) {
-
- if (i > 0)
+ if (i > 0) {
txt += ", ";
+ }
txt += DADDR(i + 3);
}
txt += ")";
@@ -729,15 +681,15 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_CONSTRUCT_ARRAY: {
-
int argc = code[ip + 1];
txt += " make_array ";
txt += DADDR(2 + argc);
txt += " = [ ";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
txt += ", ";
+ }
txt += DADDR(2 + i);
}
@@ -747,15 +699,15 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_CONSTRUCT_DICTIONARY: {
-
int argc = code[ip + 1];
txt += " make_dict ";
txt += DADDR(2 + argc * 2);
txt += " = { ";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
txt += ", ";
+ }
txt += DADDR(2 + i * 2 + 0);
txt += ":";
txt += DADDR(2 + i * 2 + 1);
@@ -769,13 +721,13 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
case GDScriptFunction::OPCODE_CALL:
case GDScriptFunction::OPCODE_CALL_RETURN: {
-
bool ret = code[ip] == GDScriptFunction::OPCODE_CALL_RETURN;
- if (ret)
+ if (ret) {
txt += " call-ret ";
- else
+ } else {
txt += " call ";
+ }
int argc = code[ip + 1];
if (ret) {
@@ -787,8 +739,9 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
txt += "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
txt += ", ";
+ }
txt += DADDR(4 + i);
}
txt += ")";
@@ -797,7 +750,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_CALL_BUILT_IN: {
-
txt += " call-built-in ";
int argc = code[ip + 2];
@@ -807,8 +759,9 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
txt += "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
txt += ", ";
+ }
txt += DADDR(3 + i);
}
txt += ")";
@@ -817,7 +770,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_CALL_SELF_BASE: {
-
txt += " call-self-base ";
int argc = code[ip + 2];
@@ -827,8 +779,9 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
txt += "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
txt += ", ";
+ }
txt += DADDR(3 + i);
}
txt += ")";
@@ -837,13 +790,11 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_YIELD: {
-
txt += " yield ";
incr = 1;
} break;
case GDScriptFunction::OPCODE_YIELD_SIGNAL: {
-
txt += " yield_signal ";
txt += DADDR(1);
txt += ",";
@@ -851,13 +802,11 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
incr = 3;
} break;
case GDScriptFunction::OPCODE_YIELD_RESUME: {
-
txt += " yield resume: ";
txt += DADDR(1);
incr = 2;
} break;
case GDScriptFunction::OPCODE_JUMP: {
-
txt += " jump ";
txt += itos(code[ip + 1]);
@@ -865,7 +814,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_JUMP_IF: {
-
txt += " jump-if ";
txt += DADDR(1);
txt += " to ";
@@ -874,7 +822,6 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
incr = 3;
} break;
case GDScriptFunction::OPCODE_JUMP_IF_NOT: {
-
txt += " jump-if-not ";
txt += DADDR(1);
txt += " to ";
@@ -883,12 +830,10 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
incr = 3;
} break;
case GDScriptFunction::OPCODE_JUMP_TO_DEF_ARGUMENT: {
-
txt += " jump-to-default-argument ";
incr = 1;
} break;
case GDScriptFunction::OPCODE_RETURN: {
-
txt += " return ";
txt += DADDR(1);
@@ -896,33 +841,29 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
} break;
case GDScriptFunction::OPCODE_ITERATE_BEGIN: {
-
txt += " for-init " + DADDR(4) + " in " + DADDR(2) + " counter " + DADDR(1) + " end " + itos(code[ip + 3]);
incr += 5;
} break;
case GDScriptFunction::OPCODE_ITERATE: {
-
txt += " for-loop " + DADDR(4) + " in " + DADDR(2) + " counter " + DADDR(1) + " end " + itos(code[ip + 3]);
incr += 5;
} break;
case GDScriptFunction::OPCODE_LINE: {
-
int line = code[ip + 1] - 1;
- if (line >= 0 && line < p_code.size())
+ if (line >= 0 && line < p_code.size()) {
txt = "\n" + itos(line + 1) + ": " + p_code[line] + "\n";
- else
+ } else {
txt = "";
+ }
incr += 2;
} break;
case GDScriptFunction::OPCODE_END: {
-
txt += " end";
incr += 1;
} break;
case GDScriptFunction::OPCODE_ASSERT: {
-
txt += " assert ";
txt += DADDR(1);
incr += 2;
@@ -931,19 +872,18 @@ static void _disassemble_class(const Ref<GDScript> &p_class, const Vector<String
}
if (incr == 0) {
-
ERR_BREAK_MSG(true, "Unhandled opcode: " + itos(code[ip]));
}
ip += incr;
- if (txt != "")
+ if (txt != "") {
print_line(txt);
+ }
}
}
}
MainLoop *test(TestType p_type) {
-
List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
if (cmdlargs.empty()) {
@@ -972,40 +912,38 @@ MainLoop *test(TestType p_type) {
int last = 0;
for (int i = 0; i <= code.length(); i++) {
-
if (code[i] == '\n' || code[i] == 0) {
-
lines.push_back(code.substr(last, i - last));
last = i + 1;
}
}
if (p_type == TEST_TOKENIZER) {
-
GDScriptTokenizerText tk;
tk.set_code(code);
int line = -1;
while (tk.get_token() != GDScriptTokenizer::TK_EOF) {
-
String text;
- if (tk.get_token() == GDScriptTokenizer::TK_IDENTIFIER)
+ if (tk.get_token() == GDScriptTokenizer::TK_IDENTIFIER) {
text = "'" + tk.get_token_identifier() + "' (identifier)";
- else if (tk.get_token() == GDScriptTokenizer::TK_CONSTANT) {
+ } else if (tk.get_token() == GDScriptTokenizer::TK_CONSTANT) {
const Variant &c = tk.get_token_constant();
- if (c.get_type() == Variant::STRING)
+ if (c.get_type() == Variant::STRING) {
text = "\"" + String(c) + "\"";
- else
+ } else {
text = c;
+ }
text = text + " (" + Variant::get_type_name(c.get_type()) + " constant)";
- } else if (tk.get_token() == GDScriptTokenizer::TK_ERROR)
+ } else if (tk.get_token() == GDScriptTokenizer::TK_ERROR) {
text = "ERROR: " + tk.get_token_error();
- else if (tk.get_token() == GDScriptTokenizer::TK_NEWLINE)
+ } else if (tk.get_token() == GDScriptTokenizer::TK_NEWLINE) {
text = "newline (" + itos(tk.get_token_line()) + ") + indent: " + itos(tk.get_token_line_indent());
- else if (tk.get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC)
+ } else if (tk.get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC) {
text = "'" + String(GDScriptFunctions::get_func_name(tk.get_token_built_in_func())) + "' (built-in function)";
- else
+ } else {
text = tk.get_token_name(tk.get_token());
+ }
if (tk.get_token_line() != line) {
int from = line + 1;
@@ -1024,7 +962,6 @@ MainLoop *test(TestType p_type) {
}
if (p_type == TEST_PARSER) {
-
GDScriptParser parser;
Error err = parser.parse(code);
if (err) {
@@ -1041,7 +978,6 @@ MainLoop *test(TestType p_type) {
}
if (p_type == TEST_COMPILER) {
-
GDScriptParser parser;
Error err = parser.parse(code);
@@ -1057,7 +993,6 @@ MainLoop *test(TestType p_type) {
GDScriptCompiler gdc;
err = gdc.compile(&parser, gds.ptr());
if (err) {
-
print_line("Compile Error:\n" + itos(gdc.get_error_line()) + ":" + itos(gdc.get_error_column()) + ":" + gdc.get_error());
return nullptr;
}
@@ -1065,7 +1000,6 @@ MainLoop *test(TestType p_type) {
Ref<GDScript> current = gds;
while (current.is_valid()) {
-
print_line("** CLASS **");
_disassemble_class(current, lines);
@@ -1073,7 +1007,6 @@ MainLoop *test(TestType p_type) {
}
} else if (p_type == TEST_BYTECODE) {
-
Vector<uint8_t> buf2 = GDScriptTokenizerBuffer::parse_code_string(code);
String dst = test.get_basename() + ".gdc";
FileAccess *fw = FileAccess::open(dst, FileAccess::WRITE);
@@ -1085,6 +1018,7 @@ MainLoop *test(TestType p_type) {
return nullptr;
}
+
} // namespace TestGDScript
#else
@@ -1095,6 +1029,7 @@ MainLoop *test(TestType p_type) {
ERR_PRINT("The GDScript module is disabled, therefore GDScript tests cannot be used.");
return nullptr;
}
+
} // namespace TestGDScript
#endif
diff --git a/main/tests/test_gui.cpp b/main/tests/test_gui.cpp
index c5c8917a51..d46a13d2c0 100644
--- a/main/tests/test_gui.cpp
+++ b/main/tests/test_gui.cpp
@@ -59,14 +59,11 @@
namespace TestGUI {
class TestMainLoop : public SceneTree {
-
public:
virtual void request_quit() {
-
quit();
}
virtual void init() {
-
SceneTree::init();
Panel *frame = memnew(Panel);
@@ -266,9 +263,9 @@ public:
};
MainLoop *test() {
-
return memnew(TestMainLoop);
}
+
} // namespace TestGUI
#endif
diff --git a/main/tests/test_main.cpp b/main/tests/test_main.cpp
index 922a55b88e..0bb8367240 100644
--- a/main/tests/test_main.cpp
+++ b/main/tests/test_main.cpp
@@ -35,6 +35,7 @@
#ifdef DEBUG_ENABLED
#include "test_astar.h"
+#include "test_class_db.h"
#include "test_gdscript.h"
#include "test_gui.h"
#include "test_math.h"
@@ -47,7 +48,6 @@
#include "test_string.h"
const char **tests_get_names() {
-
static const char *test_names[] = {
"string",
"math",
@@ -55,6 +55,7 @@ const char **tests_get_names() {
"physics_3d",
"render",
"oa_hash_map",
+ "class_db",
"gui",
"shaderlang",
"gd_tokenizer",
@@ -70,76 +71,65 @@ const char **tests_get_names() {
}
MainLoop *test_main(String p_test, const List<String> &p_args) {
-
if (p_test == "string") {
-
return TestString::test();
}
if (p_test == "math") {
-
return TestMath::test();
}
if (p_test == "physics_2d") {
-
return TestPhysics2D::test();
}
if (p_test == "physics_3d") {
-
return TestPhysics3D::test();
}
if (p_test == "render") {
-
return TestRender::test();
}
if (p_test == "oa_hash_map") {
-
return TestOAHashMap::test();
}
+ if (p_test == "class_db") {
+ return TestClassDB::test();
+ }
+
#ifndef _3D_DISABLED
if (p_test == "gui") {
-
return TestGUI::test();
}
#endif
if (p_test == "shaderlang") {
-
return TestShaderLang::test();
}
if (p_test == "gd_tokenizer") {
-
return TestGDScript::test(TestGDScript::TEST_TOKENIZER);
}
if (p_test == "gd_parser") {
-
return TestGDScript::test(TestGDScript::TEST_PARSER);
}
if (p_test == "gd_compiler") {
-
return TestGDScript::test(TestGDScript::TEST_COMPILER);
}
if (p_test == "gd_bytecode") {
-
return TestGDScript::test(TestGDScript::TEST_BYTECODE);
}
if (p_test == "ordered_hash_map") {
-
return TestOrderedHashMap::test();
}
if (p_test == "astar") {
-
return TestAStar::test();
}
@@ -150,7 +140,6 @@ MainLoop *test_main(String p_test, const List<String> &p_args) {
#else
const char **tests_get_names() {
-
static const char *test_names[] = {
nullptr
};
@@ -159,7 +148,6 @@ const char **tests_get_names() {
}
MainLoop *test_main(String p_test, const List<String> &p_args) {
-
return nullptr;
}
diff --git a/main/tests/test_math.cpp b/main/tests/test_math.cpp
index 38f7371802..11aa164709 100644
--- a/main/tests/test_math.cpp
+++ b/main/tests/test_math.cpp
@@ -32,8 +32,10 @@
#include "core/math/basis.h"
#include "core/math/camera_matrix.h"
+#include "core/math/delaunay_3d.h"
#include "core/math/math_funcs.h"
#include "core/math/transform.h"
+#include "core/method_ptrcall.h"
#include "core/os/file_access.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
@@ -45,12 +47,9 @@
#include "scene/resources/texture.h"
#include "servers/rendering/shader_language.h"
-#include "core/method_ptrcall.h"
-
namespace TestMath {
class GetClassAndNamespace {
-
String code;
int idx;
int line;
@@ -77,12 +76,9 @@ class GetClassAndNamespace {
};
Token get_token() {
-
while (true) {
switch (code[idx]) {
-
case '\n': {
-
line++;
idx++;
break;
@@ -92,37 +88,30 @@ class GetClassAndNamespace {
} break;
case '{': {
-
idx++;
return TK_CURLY_BRACKET_OPEN;
};
case '}': {
-
idx++;
return TK_CURLY_BRACKET_CLOSE;
};
case '[': {
-
idx++;
return TK_BRACKET_OPEN;
};
case ']': {
-
idx++;
return TK_BRACKET_CLOSE;
};
case ':': {
-
idx++;
return TK_COLON;
};
case ',': {
-
idx++;
return TK_COMMA;
};
case '.': {
-
idx++;
return TK_PERIOD;
};
@@ -134,7 +123,6 @@ class GetClassAndNamespace {
continue;
} break;
case '/': {
-
switch (code[idx + 1]) {
case '*': { // block comment
@@ -145,7 +133,6 @@ class GetClassAndNamespace {
error = true;
return TK_ERROR;
} else if (code[idx] == '*' && code[idx + 1] == '/') {
-
idx += 2;
break;
} else if (code[idx] == '\n') {
@@ -174,7 +161,6 @@ class GetClassAndNamespace {
} break;
case '\'':
case '"': {
-
CharType begin_str = code[idx];
idx++;
String tk_string = String();
@@ -198,15 +184,24 @@ class GetClassAndNamespace {
CharType res = 0;
switch (next) {
-
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'f': res = 12; break;
+ case 'b':
+ res = 8;
+ break;
+ case 't':
+ res = 9;
+ break;
+ case 'n':
+ res = 10;
+ break;
+ case 'f':
+ res = 12;
+ break;
case 'r':
res = 13;
break;
- case '\"': res = '\"'; break;
+ case '\"':
+ res = '\"';
+ break;
case '\\':
res = '\\';
break;
@@ -218,8 +213,9 @@ class GetClassAndNamespace {
tk_string += res;
} else {
- if (code[idx] == '\n')
+ if (code[idx] == '\n') {
line++;
+ }
tk_string += code[idx];
}
idx++;
@@ -231,7 +227,6 @@ class GetClassAndNamespace {
} break;
default: {
-
if (code[idx] <= 32) {
idx++;
break;
@@ -252,11 +247,9 @@ class GetClassAndNamespace {
return TK_NUMBER;
} else if ((code[idx] >= 'A' && code[idx] <= 'Z') || (code[idx] >= 'a' && code[idx] <= 'z') || code[idx] > 127) {
-
String id;
while ((code[idx] >= 'A' && code[idx] <= 'Z') || (code[idx] >= 'a' && code[idx] <= 'z') || code[idx] > 127) {
-
id += code[idx];
idx++;
}
@@ -275,7 +268,6 @@ class GetClassAndNamespace {
public:
Error parse(const String &p_code, const String &p_known_class_name = String()) {
-
code = p_code;
idx = 0;
line = 0;
@@ -291,7 +283,6 @@ public:
int curly_stack = 0;
while (!error || tk != TK_EOF) {
-
if (tk == TK_BRACKET_OPEN) {
tk = get_token();
if (tk == TK_IDENTIFIER && String(value) == "ScriptClass") {
@@ -348,8 +339,9 @@ public:
tk = get_token();
}
- if (error)
+ if (error) {
return ERR_PARSE_ERROR;
+ }
return OK;
}
@@ -364,7 +356,6 @@ public:
};
void test_vec(Plane p_vec) {
-
CameraMatrix cm;
cm.set_perspective(45, 1, 0, 100);
Plane v0 = cm.xform4(p_vec);
@@ -403,6 +394,54 @@ uint32_t ihash3(uint32_t a) {
}
MainLoop *test() {
+ {
+ Vector<Vector3> points;
+ points.push_back(Vector3(0, 0, 0));
+ points.push_back(Vector3(0, 0, 1));
+ points.push_back(Vector3(0, 1, 0));
+ points.push_back(Vector3(0, 1, 1));
+ points.push_back(Vector3(1, 1, 0));
+ points.push_back(Vector3(1, 0, 0));
+ points.push_back(Vector3(1, 0, 1));
+ points.push_back(Vector3(1, 1, 1));
+
+ for (int i = 0; i < 800; i++) {
+ points.push_back(Vector3(Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0) * Vector3(25, 30, 33));
+ }
+
+ Vector<Delaunay3D::OutputSimplex> os = Delaunay3D::tetrahedralize(points);
+ print_line("simplices in the end: " + itos(os.size()));
+ for (int i = 0; i < os.size(); i++) {
+ print_line("Simplex " + itos(i) + ": ");
+ print_line(points[os[i].points[0]]);
+ print_line(points[os[i].points[1]]);
+ print_line(points[os[i].points[2]]);
+ print_line(points[os[i].points[3]]);
+ }
+
+ {
+ FileAccessRef f = FileAccess::open("res://bsp.obj", FileAccess::WRITE);
+ for (int i = 0; i < os.size(); i++) {
+ f->store_line("o Simplex" + itos(i));
+ for (int j = 0; j < 4; j++) {
+ f->store_line(vformat("v %f %f %f", points[os[i].points[j]].x, points[os[i].points[j]].y, points[os[i].points[j]].z));
+ }
+ static const int face_order[4][3] = {
+ { 1, 2, 3 },
+ { 1, 3, 4 },
+ { 1, 2, 4 },
+ { 2, 3, 4 }
+ };
+
+ for (int j = 0; j < 4; j++) {
+ f->store_line(vformat("f %d %d %d", 4 * i + face_order[j][0], 4 * i + face_order[j][1], 4 * i + face_order[j][2]));
+ }
+ }
+ f->close();
+ }
+
+ return nullptr;
+ }
{
float r = 1;
@@ -505,26 +544,22 @@ MainLoop *test() {
}
{
-
Vector<int> hashes;
List<StringName> tl;
ClassDB::get_class_list(&tl);
for (List<StringName>::Element *E = tl.front(); E; E = E->next()) {
-
Vector<uint8_t> m5b = E->get().operator String().md5_buffer();
hashes.push_back(hashes.size());
}
for (int i = nearest_shift(hashes.size()); i < 20; i++) {
-
bool success = true;
for (int s = 0; s < 10000; s++) {
Set<uint32_t> existing;
success = true;
for (int j = 0; j < hashes.size(); j++) {
-
uint32_t eh = ihash2(ihash3(hashes[j] + ihash(s) + s)) & ((1 << i) - 1);
if (existing.has(eh)) {
success = false;
@@ -538,8 +573,9 @@ MainLoop *test() {
break;
}
}
- if (success)
+ if (success) {
break;
+ }
}
print_line("DONE");
@@ -662,4 +698,5 @@ MainLoop *test() {
return nullptr;
}
+
} // namespace TestMath
diff --git a/main/tests/test_oa_hash_map.cpp b/main/tests/test_oa_hash_map.cpp
index cffec7fa77..719817baf4 100644
--- a/main/tests/test_oa_hash_map.cpp
+++ b/main/tests/test_oa_hash_map.cpp
@@ -35,8 +35,38 @@
namespace TestOAHashMap {
-MainLoop *test() {
+struct CountedItem {
+ static int count;
+
+ int id = -1;
+ bool destroyed = false;
+
+ CountedItem() {
+ count++;
+ }
+ CountedItem(int p_id) :
+ id(p_id) {
+ count++;
+ }
+
+ CountedItem(const CountedItem &p_other) :
+ id(p_other.id) {
+ count++;
+ }
+
+ CountedItem &operator=(const CountedItem &p_other) = default;
+
+ ~CountedItem() {
+ CRASH_COND(destroyed);
+ count--;
+ destroyed = true;
+ }
+};
+
+int CountedItem::count;
+
+MainLoop *test() {
OS::get_singleton()->print("\n\n\nHello from test\n");
// test element tracking.
@@ -71,8 +101,9 @@ MainLoop *test() {
uint32_t num_elems = 0;
for (int i = 0; i < 500; i++) {
int tmp;
- if (map.lookup(i, tmp) && tmp == i * 2)
+ if (map.lookup(i, tmp) && tmp == i * 2) {
num_elems++;
+ }
}
OS::get_singleton()->print("elements %d == %d.\n", map.get_num_elements(), num_elems);
@@ -105,8 +136,9 @@ MainLoop *test() {
keys[i] = Math::rand();
map.set(keys[i], dummy);
- if (!map.lookup(keys[i], dummy))
+ if (!map.lookup(keys[i], dummy)) {
OS::get_singleton()->print("could not find 0x%X despite it was just inserted!\n", unsigned(keys[i]));
+ }
}
// check whether the keys are still present
@@ -122,7 +154,6 @@ MainLoop *test() {
// regression test / test for issue related to #31402
{
-
OS::get_singleton()->print("test for issue #31402 started...\n");
const int num_test_values = 12;
@@ -152,6 +183,34 @@ MainLoop *test() {
map.set(5, 1);
}
+ // test memory management of items, should not crash or leak items
+ {
+ // Exercise different patterns of removal
+ for (int i = 0; i < 4; ++i) {
+ {
+ OAHashMap<String, CountedItem> map;
+ int id = 0;
+ for (int j = 0; j < 100; ++j) {
+ map.insert(itos(j), CountedItem(id));
+ }
+ if (i <= 1) {
+ for (int j = 0; j < 100; ++j) {
+ map.remove(itos(j));
+ }
+ }
+ if (i % 2 == 0) {
+ map.clear();
+ }
+ }
+
+ if (CountedItem::count != 0) {
+ OS::get_singleton()->print("%d != 0 (not performing the other test sub-cases, breaking...)\n", CountedItem::count);
+ break;
+ }
+ }
+ }
+
return nullptr;
}
+
} // namespace TestOAHashMap
diff --git a/main/tests/test_ordered_hash_map.cpp b/main/tests/test_ordered_hash_map.cpp
index 0720eebaf9..d18a3784be 100644
--- a/main/tests/test_ordered_hash_map.cpp
+++ b/main/tests/test_ordered_hash_map.cpp
@@ -130,7 +130,7 @@ bool test_const_iteration() {
return test_const_iteration(map);
}
-typedef bool (*TestFunc)(void);
+typedef bool (*TestFunc)();
TestFunc test_funcs[] = {
@@ -146,16 +146,17 @@ TestFunc test_funcs[] = {
};
MainLoop *test() {
-
int count = 0;
int passed = 0;
while (true) {
- if (!test_funcs[count])
+ if (!test_funcs[count]) {
break;
+ }
bool pass = test_funcs[count]();
- if (pass)
+ if (pass) {
passed++;
+ }
OS::get_singleton()->print("\t%s\n", pass ? "PASS" : "FAILED");
count++;
@@ -170,4 +171,5 @@ MainLoop *test() {
return nullptr;
}
+
} // namespace TestOrderedHashMap
diff --git a/main/tests/test_physics_2d.cpp b/main/tests/test_physics_2d.cpp
index 6feff3b0a9..6cb9bf7b60 100644
--- a/main/tests/test_physics_2d.cpp
+++ b/main/tests/test_physics_2d.cpp
@@ -44,7 +44,6 @@ static const unsigned char convex_png[] = {
};
class TestPhysics2DMainLoop : public MainLoop {
-
GDCLASS(TestPhysics2DMainLoop, MainLoop);
RID circle_img;
@@ -58,7 +57,6 @@ class TestPhysics2DMainLoop : public MainLoop {
Vector2 ray_from, ray_to;
struct BodyShapeData {
-
RID image;
RID shape;
};
@@ -72,13 +70,10 @@ class TestPhysics2DMainLoop : public MainLoop {
// SEGMENT
{
-
Vector<uint8_t> pixels;
pixels.resize(32 * 2 * 2);
for (int i = 0; i < 2; i++) {
-
for (int j = 0; j < 32; j++) {
-
pixels.set(i * 32 * 2 + j * 2 + 0, (j == 0) ? 255 : 0);
pixels.set(i * 32 * 2 + j * 2 + 1, 255);
}
@@ -97,13 +92,10 @@ class TestPhysics2DMainLoop : public MainLoop {
// CIRCLE
{
-
Vector<uint8_t> pixels;
pixels.resize(32 * 32 * 2);
for (int i = 0; i < 32; i++) {
-
for (int j = 0; j < 32; j++) {
-
bool black = Vector2(i - 16, j - 16).length_squared() < 16 * 16;
pixels.set(i * 32 * 2 + j * 2 + 0, (i == 16 || j == 16) ? 255 : 0);
@@ -124,13 +116,10 @@ class TestPhysics2DMainLoop : public MainLoop {
// BOX
{
-
Vector<uint8_t> pixels;
pixels.resize(32 * 32 * 2);
for (int i = 0; i < 32; i++) {
-
for (int j = 0; j < 32; j++) {
-
bool black = i > 0 && i < 31 && j > 0 && j < 31;
pixels.set(i * 32 * 2 + j * 2 + 0, black ? 0 : 255);
@@ -151,13 +140,10 @@ class TestPhysics2DMainLoop : public MainLoop {
// CAPSULE
{
-
Vector<uint8_t> pixels;
pixels.resize(32 * 64 * 2);
for (int i = 0; i < 64; i++) {
-
for (int j = 0; j < 32; j++) {
-
int si = i > 48 ? i - 32 : (i < 16 ? i : 16);
bool black = Vector2(si - 16, j - 16).length_squared() < 16 * 16;
@@ -179,7 +165,6 @@ class TestPhysics2DMainLoop : public MainLoop {
// CONVEX
{
-
Ref<Image> image = memnew(Image(convex_png));
body_shape_data[PhysicsServer2D::SHAPE_CONVEX_POLYGON].image = vs->texture_2d_create(image);
@@ -202,7 +187,6 @@ class TestPhysics2DMainLoop : public MainLoop {
}
void _do_ray_query() {
-
/*
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
ps->query_intersection_segment(ray_query,ray_from,ray_to);
@@ -211,13 +195,10 @@ class TestPhysics2DMainLoop : public MainLoop {
protected:
void input_event(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
-
if (mb->is_pressed()) {
-
Point2 p(mb->get_position().x, mb->get_position().y);
if (mb->get_button_index() == 1) {
@@ -233,7 +214,6 @@ protected:
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
Point2 p = mm->get_position();
if (mm->get_button_mask() & BUTTON_MASK_LEFT) {
@@ -247,7 +227,6 @@ protected:
}
RID _add_body(PhysicsServer2D::ShapeType p_shape, const Transform2D &p_xform) {
-
RenderingServer *vs = RenderingServer::get_singleton();
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
@@ -272,7 +251,6 @@ protected:
}
void _add_plane(const Vector2 &p_normal, real_t p_d) {
-
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
Array arr;
@@ -289,7 +267,6 @@ protected:
}
void _add_concave(const Vector<Vector2> &p_points, const Transform2D &p_xform = Transform2D()) {
-
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
RenderingServer *vs = RenderingServer::get_singleton();
@@ -315,7 +292,6 @@ protected:
}
void _ray_query_callback(const RID &p_rid, ObjectID p_id, int p_shape, const Vector2 &p_point, const Vector2 &p_normal) {
-
Vector2 ray_end;
if (p_rid.is_valid()) {
@@ -328,19 +304,18 @@ protected:
vs->canvas_item_clear(ray);
vs->canvas_item_add_line(ray, ray_from, ray_end, p_rid.is_valid() ? Color(0, 1, 0.4) : Color(1, 0.4, 0), 2);
- if (p_rid.is_valid())
+ if (p_rid.is_valid()) {
vs->canvas_item_add_line(ray, ray_end, ray_end + p_normal * 20, p_rid.is_valid() ? Color(0, 1, 0.4) : Color(1, 0.4, 0), 2);
+ }
}
static void _bind_methods() {
-
ClassDB::bind_method(D_METHOD("_body_moved"), &TestPhysics2DMainLoop::_body_moved);
ClassDB::bind_method(D_METHOD("_ray_query_callback"), &TestPhysics2DMainLoop::_ray_query_callback);
}
public:
virtual void init() {
-
RenderingServer *vs = RenderingServer::get_singleton();
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
@@ -351,7 +326,6 @@ public:
ps->area_set_param(space, PhysicsServer2D::AREA_PARAM_GRAVITY, 98);
{
-
RID vp = vs->viewport_create();
canvas = vs->canvas_create();
@@ -377,7 +351,6 @@ public:
_create_body_shape_data();
for (int i = 0; i < 32; i++) {
-
PhysicsServer2D::ShapeType types[4] = {
PhysicsServer2D::SHAPE_CIRCLE,
PhysicsServer2D::SHAPE_CAPSULE,
@@ -402,7 +375,6 @@ public:
Vector<Point2> parr;
for (int i = 0; i < 30; i++) {
-
Point2 p(i * 60, Math::randf() * 70 + 340);
if (i > 0) {
parr.push_back(prev);
@@ -418,7 +390,6 @@ public:
}
virtual bool idle(float p_time) {
-
return false;
}
virtual void finish() {
@@ -430,7 +401,7 @@ public:
namespace TestPhysics2D {
MainLoop *test() {
-
return memnew(TestPhysics2DMainLoop);
}
+
} // namespace TestPhysics2D
diff --git a/main/tests/test_physics_3d.cpp b/main/tests/test_physics_3d.cpp
index 2d208ee317..fe54ece98e 100644
--- a/main/tests/test_physics_3d.cpp
+++ b/main/tests/test_physics_3d.cpp
@@ -41,7 +41,6 @@
#include "servers/rendering_server.h"
class TestPhysics3DMainLoop : public MainLoop {
-
GDCLASS(TestPhysics3DMainLoop, MainLoop);
enum {
@@ -69,7 +68,6 @@ class TestPhysics3DMainLoop : public MainLoop {
Map<PhysicsServer3D::ShapeType, RID> type_mesh_map;
void body_changed_transform(Object *p_state, RID p_visual_instance) {
-
PhysicsDirectBodyState3D *state = (PhysicsDirectBodyState3D *)p_state;
RenderingServer *vs = RenderingServer::get_singleton();
Transform t = state->get_transform();
@@ -80,12 +78,10 @@ class TestPhysics3DMainLoop : public MainLoop {
protected:
static void _bind_methods() {
-
ClassDB::bind_method("body_changed_transform", &TestPhysics3DMainLoop::body_changed_transform);
}
RID create_body(PhysicsServer3D::ShapeType p_shape, PhysicsServer3D::BodyMode p_body, const Transform p_location, bool p_active_default = true, const Transform &p_shape_xform = Transform()) {
-
RenderingServer *vs = RenderingServer::get_singleton();
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
@@ -101,14 +97,12 @@ protected:
bodies.push_back(body);
if (p_body == PhysicsServer3D::BODY_MODE_STATIC) {
-
vs->instance_set_transform(mesh_instance, p_location);
}
return body;
}
RID create_static_plane(const Plane &p_plane) {
-
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
RID world_margin_shape = ps->shape_create(PhysicsServer3D::SHAPE_PLANE);
@@ -122,7 +116,6 @@ protected:
}
void configure_body(RID p_body, float p_mass, float p_friction, float p_bounce) {
-
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
ps->body_set_param(p_body, PhysicsServer3D::BODY_PARAM_MASS, p_mass);
ps->body_set_param(p_body, PhysicsServer3D::BODY_PARAM_FRICTION, p_friction);
@@ -130,7 +123,6 @@ protected:
}
void init_shapes() {
-
RenderingServer *vs = RenderingServer::get_singleton();
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
@@ -188,7 +180,6 @@ protected:
}
void make_trimesh(Vector<Vector3> p_faces, const Transform &p_xform = Transform()) {
-
RenderingServer *vs = RenderingServer::get_singleton();
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
RID trimesh_shape = ps->shape_create(PhysicsServer3D::SHAPE_CONCAVE_POLYGON);
@@ -196,7 +187,6 @@ protected:
p_faces = ps->shape_get_data(trimesh_shape); // optimized one
Vector<Vector3> normals; // for drawing
for (int i = 0; i < p_faces.size() / 3; i++) {
-
Plane p(p_faces[i * 3 + 0], p_faces[i * 3 + 1], p_faces[i * 3 + 2]);
normals.push_back(p.normal);
normals.push_back(p.normal);
@@ -222,17 +212,14 @@ protected:
}
void make_grid(int p_width, int p_height, float p_cellsize, float p_cellheight, const Transform &p_xform = Transform()) {
-
Vector<Vector<float>> grid;
grid.resize(p_width);
for (int i = 0; i < p_width; i++) {
-
grid.write[i].resize(p_height);
for (int j = 0; j < p_height; j++) {
-
grid.write[i].write[j] = 1.0 + Math::random(-p_cellheight, p_cellheight);
}
}
@@ -240,9 +227,7 @@ protected:
Vector<Vector3> faces;
for (int i = 1; i < p_width; i++) {
-
for (int j = 1; j < p_height; j++) {
-
#define MAKE_VERTEX(m_x, m_z) \
faces.push_back(Vector3((m_x - p_width / 2) * p_cellsize, grid[m_x][m_z], (m_z - p_height / 2) * p_cellsize))
@@ -261,21 +246,17 @@ protected:
public:
virtual void input_event(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && mm->get_button_mask() & 4) {
-
ofs_y -= mm->get_relative().y / 200.0;
ofs_x += mm->get_relative().x / 200.0;
}
if (mm.is_valid() && mm->get_button_mask() & 1) {
-
float y = -mm->get_relative().y / 20.0;
float x = mm->get_relative().x / 20.0;
if (mover.is_valid()) {
-
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
Transform t = ps->body_get_state(mover, PhysicsServer3D::BODY_STATE_TRANSFORM);
t.origin += Vector3(x, y, 0);
@@ -286,11 +267,9 @@ public:
}
virtual void request_quit() {
-
quit = true;
}
virtual void init() {
-
ofs_x = ofs_y = 0;
init_shapes();
@@ -332,7 +311,6 @@ public:
quit = false;
}
virtual bool iteration(float p_time) {
-
if (mover.is_valid()) {
static float joy_speed = 10;
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
@@ -360,7 +338,6 @@ public:
}
void test_character() {
-
RenderingServer *vs = RenderingServer::get_singleton();
PhysicsServer3D *ps = PhysicsServer3D::get_singleton();
@@ -393,9 +370,7 @@ public:
}
void test_fall() {
-
for (int i = 0; i < 35; i++) {
-
static const PhysicsServer3D::ShapeType shape_idx[] = {
PhysicsServer3D::SHAPE_CAPSULE,
PhysicsServer3D::SHAPE_BOX,
@@ -417,7 +392,6 @@ public:
}
void test_activate() {
-
create_body(PhysicsServer3D::SHAPE_BOX, PhysicsServer3D::BODY_MODE_RIGID, Transform(Basis(), Vector3(0, 2, 0)), true);
create_static_plane(Plane(Vector3(0, 1, 0), -1));
}
@@ -433,7 +407,7 @@ public:
namespace TestPhysics3D {
MainLoop *test() {
-
return memnew(TestPhysics3DMainLoop);
}
+
} // namespace TestPhysics3D
diff --git a/main/tests/test_render.cpp b/main/tests/test_render.cpp
index bcfcf61e25..afc09374b9 100644
--- a/main/tests/test_render.cpp
+++ b/main/tests/test_render.cpp
@@ -44,7 +44,6 @@
namespace TestRender {
class TestMainLoop : public MainLoop {
-
RID test_cube;
RID instance;
RID camera;
@@ -53,7 +52,6 @@ class TestMainLoop : public MainLoop {
RID scenario;
struct InstanceInfo {
-
RID instance;
Transform base;
Vector3 rot_axis;
@@ -67,13 +65,12 @@ class TestMainLoop : public MainLoop {
protected:
public:
virtual void input_event(const Ref<InputEvent> &p_event) {
-
- if (p_event->is_pressed())
+ if (p_event->is_pressed()) {
quit = true;
+ }
}
virtual void init() {
-
print_line("INITIALIZING TEST RENDER");
RenderingServer *vs = RenderingServer::get_singleton();
test_cube = vs->get_test_cube();
@@ -144,7 +141,6 @@ public:
};
for (int i = 0; i < object_count; i++) {
-
InstanceInfo ii;
ii.instance = vs->instance_create2(test_cube, scenario);
@@ -205,7 +201,6 @@ public:
quit = false;
}
virtual bool iteration(float p_time) {
-
RenderingServer *vs = RenderingServer::get_singleton();
//Transform t;
//t.rotate(Vector3(0, 1, 0), ofs);
@@ -217,7 +212,6 @@ public:
//return quit;
for (List<InstanceInfo>::Element *E = instances.front(); E; E = E->next()) {
-
Transform pre(Basis(E->get().rot_axis, ofs), Vector3());
vs->instance_set_transform(E->get().instance, pre * E->get().base);
/*
@@ -240,7 +234,7 @@ public:
};
MainLoop *test() {
-
return memnew(TestMainLoop);
}
+
} // namespace TestRender
diff --git a/main/tests/test_shader_lang.cpp b/main/tests/test_shader_lang.cpp
index dbe2da86cf..34ee3e3210 100644
--- a/main/tests/test_shader_lang.cpp
+++ b/main/tests/test_shader_lang.cpp
@@ -44,7 +44,6 @@ typedef ShaderLanguage SL;
namespace TestShaderLang {
static String _mktab(int p_level) {
-
String tb;
for (int i = 0; i < p_level; i++) {
tb += "\t";
@@ -54,61 +53,74 @@ static String _mktab(int p_level) {
}
static String _typestr(SL::DataType p_type) {
-
return ShaderLanguage::get_datatype_name(p_type);
}
static String _prestr(SL::DataPrecision p_pres) {
-
switch (p_pres) {
- case SL::PRECISION_LOWP: return "lowp ";
- case SL::PRECISION_MEDIUMP: return "mediump ";
- case SL::PRECISION_HIGHP: return "highp ";
- case SL::PRECISION_DEFAULT: return "";
+ case SL::PRECISION_LOWP:
+ return "lowp ";
+ case SL::PRECISION_MEDIUMP:
+ return "mediump ";
+ case SL::PRECISION_HIGHP:
+ return "highp ";
+ case SL::PRECISION_DEFAULT:
+ return "";
}
return "";
}
static String _opstr(SL::Operator p_op) {
-
return ShaderLanguage::get_operator_text(p_op);
}
static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value> &p_values) {
-
switch (p_type) {
- case SL::TYPE_BOOL: return p_values[0].boolean ? "true" : "false";
- case SL::TYPE_BVEC2: return String() + "bvec2(" + (p_values[0].boolean ? "true" : "false") + (p_values[1].boolean ? "true" : "false") + ")";
- case SL::TYPE_BVEC3: return String() + "bvec3(" + (p_values[0].boolean ? "true" : "false") + "," + (p_values[1].boolean ? "true" : "false") + "," + (p_values[2].boolean ? "true" : "false") + ")";
- case SL::TYPE_BVEC4: return String() + "bvec4(" + (p_values[0].boolean ? "true" : "false") + "," + (p_values[1].boolean ? "true" : "false") + "," + (p_values[2].boolean ? "true" : "false") + "," + (p_values[3].boolean ? "true" : "false") + ")";
- case SL::TYPE_INT: return rtos(p_values[0].sint);
- case SL::TYPE_IVEC2: return String() + "ivec2(" + rtos(p_values[0].sint) + "," + rtos(p_values[1].sint) + ")";
- case SL::TYPE_IVEC3: return String() + "ivec3(" + rtos(p_values[0].sint) + "," + rtos(p_values[1].sint) + "," + rtos(p_values[2].sint) + ")";
- case SL::TYPE_IVEC4: return String() + "ivec4(" + rtos(p_values[0].sint) + "," + rtos(p_values[1].sint) + "," + rtos(p_values[2].sint) + "," + rtos(p_values[3].sint) + ")";
- case SL::TYPE_UINT: return rtos(p_values[0].real);
- case SL::TYPE_UVEC2: return String() + "uvec2(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + ")";
- case SL::TYPE_UVEC3: return String() + "uvec3(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + "," + rtos(p_values[2].real) + ")";
- case SL::TYPE_UVEC4: return String() + "uvec4(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + "," + rtos(p_values[2].real) + "," + rtos(p_values[3].real) + ")";
- case SL::TYPE_FLOAT: return rtos(p_values[0].real);
- case SL::TYPE_VEC2: return String() + "vec2(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + ")";
- case SL::TYPE_VEC3: return String() + "vec3(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + "," + rtos(p_values[2].real) + ")";
- case SL::TYPE_VEC4: return String() + "vec4(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + "," + rtos(p_values[2].real) + "," + rtos(p_values[3].real) + ")";
- default: ERR_FAIL_V(String());
+ case SL::TYPE_BOOL:
+ return p_values[0].boolean ? "true" : "false";
+ case SL::TYPE_BVEC2:
+ return String() + "bvec2(" + (p_values[0].boolean ? "true" : "false") + (p_values[1].boolean ? "true" : "false") + ")";
+ case SL::TYPE_BVEC3:
+ return String() + "bvec3(" + (p_values[0].boolean ? "true" : "false") + "," + (p_values[1].boolean ? "true" : "false") + "," + (p_values[2].boolean ? "true" : "false") + ")";
+ case SL::TYPE_BVEC4:
+ return String() + "bvec4(" + (p_values[0].boolean ? "true" : "false") + "," + (p_values[1].boolean ? "true" : "false") + "," + (p_values[2].boolean ? "true" : "false") + "," + (p_values[3].boolean ? "true" : "false") + ")";
+ case SL::TYPE_INT:
+ return rtos(p_values[0].sint);
+ case SL::TYPE_IVEC2:
+ return String() + "ivec2(" + rtos(p_values[0].sint) + "," + rtos(p_values[1].sint) + ")";
+ case SL::TYPE_IVEC3:
+ return String() + "ivec3(" + rtos(p_values[0].sint) + "," + rtos(p_values[1].sint) + "," + rtos(p_values[2].sint) + ")";
+ case SL::TYPE_IVEC4:
+ return String() + "ivec4(" + rtos(p_values[0].sint) + "," + rtos(p_values[1].sint) + "," + rtos(p_values[2].sint) + "," + rtos(p_values[3].sint) + ")";
+ case SL::TYPE_UINT:
+ return rtos(p_values[0].real);
+ case SL::TYPE_UVEC2:
+ return String() + "uvec2(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + ")";
+ case SL::TYPE_UVEC3:
+ return String() + "uvec3(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + "," + rtos(p_values[2].real) + ")";
+ case SL::TYPE_UVEC4:
+ return String() + "uvec4(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + "," + rtos(p_values[2].real) + "," + rtos(p_values[3].real) + ")";
+ case SL::TYPE_FLOAT:
+ return rtos(p_values[0].real);
+ case SL::TYPE_VEC2:
+ return String() + "vec2(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + ")";
+ case SL::TYPE_VEC3:
+ return String() + "vec3(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + "," + rtos(p_values[2].real) + ")";
+ case SL::TYPE_VEC4:
+ return String() + "vec4(" + rtos(p_values[0].real) + "," + rtos(p_values[1].real) + "," + rtos(p_values[2].real) + "," + rtos(p_values[3].real) + ")";
+ default:
+ ERR_FAIL_V(String());
}
}
static String dump_node_code(SL::Node *p_node, int p_level) {
-
String code;
switch (p_node->type) {
-
case SL::Node::TYPE_SHADER: {
-
SL::ShaderNode *pnode = (SL::ShaderNode *)p_node;
for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) {
-
String ucode = "uniform ";
ucode += _prestr(E->get().precision);
ucode += _typestr(E->get().type);
@@ -128,14 +140,14 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
"white"
};
- if (E->get().hint)
+ if (E->get().hint) {
ucode += " : " + String(hint_name[E->get().hint]);
+ }
code += ucode + "\n";
}
for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) {
-
String vcode = "varying ";
vcode += _prestr(E->get().precision);
vcode += _typestr(E->get().type);
@@ -144,15 +156,14 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
code += vcode + "\n";
}
for (int i = 0; i < pnode->functions.size(); i++) {
-
SL::FunctionNode *fnode = pnode->functions[i].function;
String header;
header = _typestr(fnode->return_type) + " " + fnode->name + "(";
for (int j = 0; j < fnode->arguments.size(); j++) {
-
- if (j > 0)
+ if (j > 0) {
header += ", ";
+ }
header += _prestr(fnode->arguments[j].precision) + _typestr(fnode->arguments[j].type) + " " + fnode->arguments[j].name;
}
@@ -164,10 +175,8 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
//code+=dump_node_code(pnode->body,p_level);
} break;
case SL::Node::TYPE_STRUCT: {
-
} break;
case SL::Node::TYPE_FUNCTION: {
-
} break;
case SL::Node::TYPE_BLOCK: {
SL::BlockNode *bnode = (SL::BlockNode *)p_node;
@@ -175,12 +184,10 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
//variables
code += _mktab(p_level - 1) + "{\n";
for (Map<StringName, SL::BlockNode::Variable>::Element *E = bnode->variables.front(); E; E = E->next()) {
-
code += _mktab(p_level) + _prestr(E->get().precision) + _typestr(E->get().type) + " " + E->key() + ";\n";
}
for (int i = 0; i < bnode->statements.size(); i++) {
-
String scode = dump_node_code(bnode->statements[i], p_level);
if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW) {
@@ -219,7 +226,6 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
SL::OperatorNode *onode = (SL::OperatorNode *)p_node;
switch (onode->op) {
-
case SL::OP_ASSIGN:
case SL::OP_ASSIGN_ADD:
case SL::OP_ASSIGN_SUB:
@@ -248,14 +254,14 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
case SL::OP_CONSTRUCT:
code = dump_node_code(onode->arguments[0], p_level) + "(";
for (int i = 1; i < onode->arguments.size(); i++) {
- if (i > 1)
+ if (i > 1) {
code += ", ";
+ }
code += dump_node_code(onode->arguments[i], p_level);
}
code += ")";
break;
default: {
-
code = "(" + dump_node_code(onode->arguments[0], p_level) + _opstr(onode->op) + dump_node_code(onode->arguments[1], p_level) + ")";
break;
}
@@ -265,17 +271,14 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
case SL::Node::TYPE_CONTROL_FLOW: {
SL::ControlFlowNode *cfnode = (SL::ControlFlowNode *)p_node;
if (cfnode->flow_op == SL::FLOW_OP_IF) {
-
code += _mktab(p_level) + "if (" + dump_node_code(cfnode->expressions[0], p_level) + ")\n";
code += dump_node_code(cfnode->blocks[0], p_level + 1);
if (cfnode->blocks.size() == 2) {
-
code += _mktab(p_level) + "else\n";
code += dump_node_code(cfnode->blocks[1], p_level + 1);
}
} else if (cfnode->flow_op == SL::FLOW_OP_RETURN) {
-
if (cfnode->blocks.size()) {
code = "return " + dump_node_code(cfnode->blocks[0], p_level);
} else {
@@ -295,7 +298,6 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
}
static Error recreate_code(void *p_str, SL::ShaderNode *p_program) {
-
String *str = (String *)p_str;
*str = dump_node_code(p_program, 0);
@@ -304,7 +306,6 @@ static Error recreate_code(void *p_str, SL::ShaderNode *p_program) {
}
MainLoop *test() {
-
List<String> cmdlargs = OS::get_singleton()->get_cmdline_args();
if (cmdlargs.empty()) {
@@ -325,8 +326,9 @@ MainLoop *test() {
while (true) {
CharType c = fa->get_8();
- if (fa->eof_reached())
+ if (fa->eof_reached()) {
break;
+ }
code += c;
}
@@ -342,10 +344,9 @@ MainLoop *test() {
Set<String> types;
types.insert("spatial");
- Error err = sl.compile(code, dt, rm, types, NULL);
+ Error err = sl.compile(code, dt, rm, types, nullptr);
if (err) {
-
print_line("Error at line: " + rtos(sl.get_error_line()) + ": " + sl.get_error_text());
return nullptr;
} else {
@@ -356,4 +357,5 @@ MainLoop *test() {
return nullptr;
}
+
} // namespace TestShaderLang
diff --git a/main/tests/test_string.cpp b/main/tests/test_string.cpp
index 7438e2bae9..775c039282 100644
--- a/main/tests/test_string.cpp
+++ b/main/tests/test_string.cpp
@@ -45,7 +45,6 @@
namespace TestString {
bool test_1() {
-
OS::get_singleton()->print("\n\nTest 1: Assign from cstr\n");
String s = "Hello";
@@ -57,7 +56,6 @@ bool test_1() {
}
bool test_2() {
-
OS::get_singleton()->print("\n\nTest 2: Assign from string (operator=)\n");
String s = "Dolly";
@@ -70,7 +68,6 @@ bool test_2() {
}
bool test_3() {
-
OS::get_singleton()->print("\n\nTest 3: Assign from c-string (copycon)\n");
String s("Sheep");
@@ -83,7 +80,6 @@ bool test_3() {
}
bool test_4() {
-
OS::get_singleton()->print("\n\nTest 4: Assign from c-widechar (operator=)\n");
String s(L"Give me");
@@ -95,7 +91,6 @@ bool test_4() {
}
bool test_5() {
-
OS::get_singleton()->print("\n\nTest 5: Assign from c-widechar (copycon)\n");
String s(L"Wool");
@@ -107,67 +102,72 @@ bool test_5() {
}
bool test_6() {
-
OS::get_singleton()->print("\n\nTest 6: comparisons (equal)\n");
String s = "Test Compare";
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
- if (!(s == "Test Compare"))
+ if (!(s == "Test Compare")) {
return false;
+ }
- if (!(s == L"Test Compare"))
+ if (!(s == L"Test Compare")) {
return false;
+ }
- if (!(s == String("Test Compare")))
+ if (!(s == String("Test Compare"))) {
return false;
+ }
return true;
}
bool test_7() {
-
OS::get_singleton()->print("\n\nTest 7: comparisons (unequal)\n");
String s = "Test Compare";
OS::get_singleton()->print("\tComparing to \"Test Compare\"\n");
- if (!(s != "Peanut"))
+ if (!(s != "Peanut")) {
return false;
+ }
- if (!(s != L"Coconut"))
+ if (!(s != L"Coconut")) {
return false;
+ }
- if (!(s != String("Butter")))
+ if (!(s != String("Butter"))) {
return false;
+ }
return true;
}
bool test_8() {
-
OS::get_singleton()->print("\n\nTest 8: comparisons (operator<)\n");
String s = "Bees";
OS::get_singleton()->print("\tComparing to \"Bees\"\n");
- if (!(s < "Elephant"))
+ if (!(s < "Elephant")) {
return false;
+ }
- if (s < L"Amber")
+ if (s < L"Amber") {
return false;
+ }
- if (s < String("Beatrix"))
+ if (s < String("Beatrix")) {
return false;
+ }
return true;
}
bool test_9() {
-
OS::get_singleton()->print("\n\nTest 9: Concatenation\n");
String s;
@@ -186,23 +186,24 @@ bool test_9() {
}
bool test_10() {
-
OS::get_singleton()->print("\n\nTest 10: Misc funcs (size/length/empty/etc)\n");
- if (!String("").empty())
+ if (!String("").empty()) {
return false;
+ }
- if (String("Mellon").size() != 7)
+ if (String("Mellon").size() != 7) {
return false;
+ }
- if (String("Oranges").length() != 7)
+ if (String("Oranges").length() != 7) {
return false;
+ }
return true;
}
bool test_11() {
-
OS::get_singleton()->print("\n\nTest 11: Operator[]\n");
String a = "Kugar Sane";
@@ -210,32 +211,34 @@ bool test_11() {
a[0] = 'S';
a[6] = 'C';
- if (a != "Sugar Cane")
+ if (a != "Sugar Cane") {
return false;
+ }
- if (a[1] != 'u')
+ if (a[1] != 'u') {
return false;
+ }
return true;
}
bool test_12() {
-
OS::get_singleton()->print("\n\nTest 12: case functions\n");
String a = "MoMoNgA";
- if (a.to_upper() != "MOMONGA")
+ if (a.to_upper() != "MOMONGA") {
return false;
+ }
- if (a.nocasecmp_to("momonga") != 0)
+ if (a.nocasecmp_to("momonga") != 0) {
return false;
+ }
return true;
}
bool test_13() {
-
OS::get_singleton()->print("\n\nTest 13: UTF8\n");
/* how can i embed UTF in here? */
@@ -252,7 +255,6 @@ bool test_13() {
}
bool test_14() {
-
OS::get_singleton()->print("\n\nTest 14: ASCII\n");
String s = L"Primero Leche";
@@ -263,7 +265,6 @@ bool test_14() {
}
bool test_15() {
-
OS::get_singleton()->print("\n\nTest 15: substr\n");
String s = "Killer Baby";
@@ -273,7 +274,6 @@ bool test_15() {
}
bool test_16() {
-
OS::get_singleton()->print("\n\nTest 16: find\n");
String s = "Pretty Woman";
@@ -281,17 +281,18 @@ bool test_16() {
OS::get_singleton()->print("\t\"tty\" is at %i pos.\n", s.find("tty"));
OS::get_singleton()->print("\t\"Revenge of the Monster Truck\" is at %i pos.\n", s.find("Revenge of the Monster Truck"));
- if (s.find("tty") != 3)
+ if (s.find("tty") != 3) {
return false;
+ }
- if (s.find("Revenge of the Monster Truck") != -1)
+ if (s.find("Revenge of the Monster Truck") != -1) {
return false;
+ }
return true;
}
bool test_17() {
-
OS::get_singleton()->print("\n\nTest 17: find no case\n");
String s = "Pretty Whale";
@@ -299,17 +300,18 @@ bool test_17() {
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n", s.findn("WHA"));
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n", s.findn("Revenge of the Monster Truck"));
- if (s.findn("WHA") != 7)
+ if (s.findn("WHA") != 7) {
return false;
+ }
- if (s.findn("Revenge of the Monster SawFish") != -1)
+ if (s.findn("Revenge of the Monster SawFish") != -1) {
return false;
+ }
return true;
}
bool test_18() {
-
OS::get_singleton()->print("\n\nTest 18: find no case\n");
String s = "Pretty Whale";
@@ -317,17 +319,18 @@ bool test_18() {
OS::get_singleton()->print("\t\"WHA\" is at %i pos.\n", s.findn("WHA"));
OS::get_singleton()->print("\t\"Revenge of the Monster SawFish\" is at %i pos.\n", s.findn("Revenge of the Monster Truck"));
- if (s.findn("WHA") != 7)
+ if (s.findn("WHA") != 7) {
return false;
+ }
- if (s.findn("Revenge of the Monster SawFish") != -1)
+ if (s.findn("Revenge of the Monster SawFish") != -1) {
return false;
+ }
return true;
}
bool test_19() {
-
OS::get_singleton()->print("\n\nTest 19: Search & replace\n");
String s = "Happy Birthday, Anna!";
@@ -340,7 +343,6 @@ bool test_19() {
}
bool test_20() {
-
OS::get_singleton()->print("\n\nTest 20: Insertion\n");
String s = "Who is Frederic?";
@@ -353,7 +355,6 @@ bool test_20() {
}
bool test_21() {
-
OS::get_singleton()->print("\n\nTest 21: Number -> String\n");
OS::get_singleton()->print("\tPi is %f\n", 33.141593);
@@ -363,7 +364,6 @@ bool test_21() {
}
bool test_22() {
-
OS::get_singleton()->print("\n\nTest 22: String -> Int\n");
static const char *nums[4] = { "1237461283", "- 22", "0", " - 1123412" };
@@ -372,15 +372,15 @@ bool test_22() {
for (int i = 0; i < 4; i++) {
OS::get_singleton()->print("\tString: \"%s\" as Int is %i\n", nums[i], String(nums[i]).to_int());
- if (String(nums[i]).to_int() != num[i])
+ if (String(nums[i]).to_int() != num[i]) {
return false;
+ }
}
return true;
}
bool test_23() {
-
OS::get_singleton()->print("\n\nTest 23: String -> Float\n");
static const char *nums[4] = { "-12348298412.2", "0.05", "2.0002", " -0.0001" };
@@ -389,15 +389,15 @@ bool test_23() {
for (int i = 0; i < 4; i++) {
OS::get_singleton()->print("\tString: \"%s\" as Float is %f\n", nums[i], String(nums[i]).to_double());
- if (ABS(String(nums[i]).to_double() - num[i]) > 0.00001)
+ if (ABS(String(nums[i]).to_double() - num[i]) > 0.00001) {
return false;
+ }
}
return true;
}
bool test_24() {
-
OS::get_singleton()->print("\n\nTest 24: Slicing\n");
String s = "Mars,Jupiter,Saturn,Uranus";
@@ -407,18 +407,17 @@ bool test_24() {
OS::get_singleton()->print("\tSlicing \"%ls\" by \"%s\"..\n", s.c_str(), ",");
for (int i = 0; i < s.get_slice_count(","); i++) {
-
OS::get_singleton()->print("\t\t%i- %ls\n", i + 1, s.get_slice(",", i).c_str());
- if (s.get_slice(",", i) != slices[i])
+ if (s.get_slice(",", i) != slices[i]) {
return false;
+ }
}
return true;
}
bool test_25() {
-
OS::get_singleton()->print("\n\nTest 25: Erasing\n");
String s = "Josephine is such a cute girl!";
@@ -433,7 +432,6 @@ bool test_25() {
}
bool test_26() {
-
OS::get_singleton()->print("\n\nTest 26: RegEx substitution\n");
#ifndef MODULE_REGEX_ENABLED
@@ -461,7 +459,6 @@ struct test_27_data {
};
bool test_27() {
-
OS::get_singleton()->print("\n\nTest 27: begins_with\n");
test_27_data tc[] = {
{ "res://foobar", "res://", true },
@@ -486,7 +483,6 @@ bool test_27() {
};
bool test_28() {
-
OS::get_singleton()->print("\n\nTest 28: sprintf\n");
bool success, state = true;
@@ -822,7 +818,6 @@ bool test_28() {
}
bool test_29() {
-
bool state = true;
IP_Address ip0("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
@@ -972,28 +967,35 @@ bool test_31() {
String a = "";
success = a[0] == 0;
OS::get_singleton()->print("Is 0 String[0]:, %s\n", success ? "OK" : "FAIL");
- if (!success) state = false;
+ if (!success) {
+ state = false;
+ }
String b = "Godot";
success = b[b.size()] == 0;
OS::get_singleton()->print("Is 0 String[size()]:, %s\n", success ? "OK" : "FAIL");
- if (!success) state = false;
+ if (!success) {
+ state = false;
+ }
const String c = "";
success = c[0] == 0;
OS::get_singleton()->print("Is 0 const String[0]:, %s\n", success ? "OK" : "FAIL");
- if (!success) state = false;
+ if (!success) {
+ state = false;
+ }
const String d = "Godot";
success = d[d.size()] == 0;
OS::get_singleton()->print("Is 0 const String[size()]:, %s\n", success ? "OK" : "FAIL");
- if (!success) state = false;
+ if (!success) {
+ state = false;
+ }
return state;
};
bool test_32() {
-
#define STRIP_TEST(x) \
{ \
bool success = x; \
@@ -1125,7 +1127,7 @@ bool test_35() {
return state;
}
-typedef bool (*TestFunc)(void);
+typedef bool (*TestFunc)();
TestFunc test_funcs[] = {
@@ -1169,7 +1171,6 @@ TestFunc test_funcs[] = {
};
MainLoop *test() {
-
/** A character length != wchar_t may be forced, so the tests won't work */
static_assert(sizeof(CharType) == sizeof(wchar_t));
@@ -1178,11 +1179,13 @@ MainLoop *test() {
int passed = 0;
while (true) {
- if (!test_funcs[count])
+ if (!test_funcs[count]) {
break;
+ }
bool pass = test_funcs[count]();
- if (pass)
+ if (pass) {
passed++;
+ }
OS::get_singleton()->print("\t%s\n", pass ? "PASS" : "FAILED");
count++;
@@ -1197,4 +1200,5 @@ MainLoop *test() {
return nullptr;
}
+
} // namespace TestString
diff --git a/misc/dist/html/fixed-size.html b/misc/dist/html/fixed-size.html
index 6c6a3a5d2d..a5633115d5 100644
--- a/misc/dist/html/fixed-size.html
+++ b/misc/dist/html/fixed-size.html
@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<link id='-gd-engine-icon' rel='icon' type='image/png' href='favicon.png' />
- <title></title>
+ <title>$GODOT_PROJECT_NAME</title>
<style type="text/css">
body {
@@ -232,6 +232,7 @@ $GODOT_HEAD_INCLUDE
const EXECUTABLE_NAME = '$GODOT_BASENAME';
const MAIN_PACK = '$GODOT_BASENAME.pck';
+ const EXTRA_ARGS = JSON.parse('$GODOT_ARGS');
const DEBUG_ENABLED = $GODOT_DEBUG_ENABLED;
const INDETERMINATE_STATUS_STEP_MS = 100;
@@ -382,7 +383,7 @@ $GODOT_HEAD_INCLUDE
} else {
setStatusMode('indeterminate');
engine.setCanvas(canvas);
- engine.startGame(EXECUTABLE_NAME, MAIN_PACK).then(() => {
+ engine.startGame(EXECUTABLE_NAME, MAIN_PACK, EXTRA_ARGS).then(() => {
setStatusMode('hidden');
initializing = false;
}, displayFailureNotice);
diff --git a/misc/dist/html/full-size.html b/misc/dist/html/full-size.html
index 92b65257d4..435013cb5e 100644
--- a/misc/dist/html/full-size.html
+++ b/misc/dist/html/full-size.html
@@ -4,7 +4,7 @@
<meta charset='utf-8' />
<meta name='viewport' content='width=device-width, user-scalable=no' />
<link id='-gd-engine-icon' rel='icon' type='image/png' href='favicon.png' />
- <title></title>
+ <title>$GODOT_PROJECT_NAME</title>
<style type='text/css'>
body {
@@ -145,6 +145,7 @@ $GODOT_HEAD_INCLUDE
const EXECUTABLE_NAME = '$GODOT_BASENAME';
const MAIN_PACK = '$GODOT_BASENAME.pck';
+ const EXTRA_ARGS = JSON.parse('$GODOT_ARGS');
const INDETERMINATE_STATUS_STEP_MS = 100;
var canvas = document.getElementById('canvas');
@@ -169,8 +170,6 @@ $GODOT_HEAD_INCLUDE
var height = window.innerHeight;
canvas.width = width * scale;
canvas.height = height * scale;
- canvas.style.width = width + "px";
- canvas.style.height = height + "px";
}
animationCallbacks.push(adjustCanvasDimensions);
adjustCanvasDimensions();
@@ -256,7 +255,7 @@ $GODOT_HEAD_INCLUDE
} else {
setStatusMode('indeterminate');
engine.setCanvas(canvas);
- engine.startGame(EXECUTABLE_NAME, MAIN_PACK).then(() => {
+ engine.startGame(EXECUTABLE_NAME, MAIN_PACK, EXTRA_ARGS).then(() => {
setStatusMode('hidden');
initializing = false;
}, displayFailureNotice);
diff --git a/misc/dist/linux/org.godotengine.Godot.desktop b/misc/dist/linux/org.godotengine.Godot.desktop
index c8b99207f8..8b74234174 100644
--- a/misc/dist/linux/org.godotengine.Godot.desktop
+++ b/misc/dist/linux/org.godotengine.Godot.desktop
@@ -5,6 +5,7 @@ Comment=Multi-platform 2D and 3D game engine with a feature-rich editor
Exec=godot %f
Icon=godot
Terminal=false
+PrefersNonDefaultGPU=true
Type=Application
MimeType=application/x-godot-project;
Categories=Development;IDE;
diff --git a/misc/hooks/pre-commit-black b/misc/hooks/pre-commit-black
index 2dcc2e8cf1..76d97294da 100755
--- a/misc/hooks/pre-commit-black
+++ b/misc/hooks/pre-commit-black
@@ -6,7 +6,7 @@
##################################################################
# SETTINGS
# Set path to black binary.
-BLACK=`which black`
+BLACK=`which black 2>/dev/null`
BLACK_OPTIONS="-l 120"
# Remove any older patches from previous commits. Set to true or false.
@@ -18,13 +18,22 @@ FILE_EXTS="py"
# Use pygmentize instead of cat to parse diff with highlighting.
# Install it with `pip install pygments` (Linux) or `easy_install Pygments` (Mac)
-PYGMENTIZE=`which pygmentize`
+PYGMENTIZE=`which pygmentize 2>/dev/null`
if [ ! -z "$PYGMENTIZE" ]; then
READER="pygmentize -l diff"
else
READER=cat
fi
+# Path to zenity
+ZENITY=`which zenity 2>/dev/null`
+
+# Path to xmessage
+XMSG=`which xmessage 2>/dev/null`
+
+# Path to powershell (Windows only)
+PWSH=`which powershell 2>/dev/null`
+
##################################################################
# There should be no need to change anything below this line.
@@ -53,6 +62,19 @@ else
fi
if [ ! -x "$BLACK" ] ; then
+ if [ ! -t 1 ] ; then
+ if [ -x "$ZENITY" ] ; then
+ $ZENITY --error --title="Error" --text="Error: black executable not found."
+ exit 1
+ elif [ -x "$XMSG" ] ; then
+ $XMSG -center -title "Error" "Error: black executable not found."
+ exit 1
+ elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then
+ winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")"
+ $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -center -title "Error" --text "Error: black executable not found."
+ exit 1
+ fi
+ fi
printf "Error: black executable not found.\n"
printf "Set the correct path in $(canonicalize_filename "$0").\n"
exit 1
@@ -99,14 +121,62 @@ fi
# a patch has been created, notify the user and exit
printf "\nThe following differences were found between the code to commit "
printf "and the black formatter rules:\n\n"
-$READER "$patch"
-printf "\n"
-# Allows us to read user input below, assigns stdin to keyboard
-exec < /dev/tty
+if [ -t 1 ] ; then
+ $READER "$patch"
+ printf "\n"
+ # Allows us to read user input below, assigns stdin to keyboard
+ exec < /dev/tty
+ terminal="1"
+else
+ cat "$patch"
+ printf "\n"
+ # Allows non zero zenity/powershell output
+ set +e
+ terminal="0"
+fi
while true; do
- read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn
+ if [ $terminal = "0" ] ; then
+ if [ -x "$ZENITY" ] ; then
+ ans=$($ZENITY --text-info --filename="$patch" --width=800 --height=600 --title="Do you want to apply that patch?" --ok-label="Apply" --cancel-label="Do not apply" --extra-button="Apply and stage")
+ if [ "$?" = "0" ] ; then
+ yn="Y"
+ else
+ if [ "$ans" = "Apply and stage" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ fi
+ elif [ -x "$XMSG" ] ; then
+ $XMSG -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?"
+ ans=$?
+ if [ "$ans" = "100" ] ; then
+ yn="Y"
+ elif [ "$ans" = "200" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then
+ winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")"
+ $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?"
+ ans=$?
+ if [ "$ans" = "100" ] ; then
+ yn="Y"
+ elif [ "$ans" = "200" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ else
+ printf "Error: zenity, xmessage, or powershell executable not found.\n"
+ exit 1
+ fi
+ else
+ read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn
+ fi
case $yn in
[Yy] ) git apply $patch;
printf "The patch was applied. You can now stage the changes and commit again.\n\n";
diff --git a/misc/hooks/pre-commit-clang-format b/misc/hooks/pre-commit-clang-format
index c5cf4ecbb1..4e1fbdeb20 100755
--- a/misc/hooks/pre-commit-clang-format
+++ b/misc/hooks/pre-commit-clang-format
@@ -16,7 +16,7 @@
##################################################################
# SETTINGS
# Set path to clang-format binary.
-CLANG_FORMAT=`which clang-format`
+CLANG_FORMAT=`which clang-format 2>/dev/null`
# Remove any older patches from previous commits. Set to true or false.
DELETE_OLD_PATCHES=false
@@ -31,13 +31,22 @@ FILE_EXTS=".c .h .cpp .hpp .cc .hh .cxx .m .mm .inc .java .glsl"
# Use pygmentize instead of cat to parse diff with highlighting.
# Install it with `pip install pygments` (Linux) or `easy_install Pygments` (Mac)
-PYGMENTIZE=`which pygmentize`
+PYGMENTIZE=`which pygmentize 2>/dev/null`
if [ ! -z "$PYGMENTIZE" ]; then
READER="pygmentize -l diff"
else
READER=cat
fi
+# Path to zenity
+ZENITY=`which zenity 2>/dev/null`
+
+# Path to xmessage
+XMSG=`which xmessage 2>/dev/null`
+
+# Path to powershell (Windows only)
+PWSH=`which powershell 2>/dev/null`
+
##################################################################
# There should be no need to change anything below this line.
@@ -66,6 +75,19 @@ else
fi
if [ ! -x "$CLANG_FORMAT" ] ; then
+ if [ ! -t 1 ] ; then
+ if [ -x "$ZENITY" ] ; then
+ $ZENITY --error --title="Error" --text="Error: clang-format executable not found."
+ exit 1
+ elif [ -x "$XMSG" ] ; then
+ $XMSG -center -title "Error" "Error: clang-format executable not found."
+ exit 1
+ elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then
+ winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")"
+ $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -center -title "Error" --text "Error: clang-format executable not found."
+ exit 1
+ fi
+ fi
printf "Error: clang-format executable not found.\n"
printf "Set the correct path in $(canonicalize_filename "$0").\n"
exit 1
@@ -117,14 +139,62 @@ fi
# a patch has been created, notify the user and exit
printf "\nThe following differences were found between the code to commit "
printf "and the clang-format rules:\n\n"
-$READER "$patch"
-printf "\n"
-# Allows us to read user input below, assigns stdin to keyboard
-exec < /dev/tty
+if [ -t 1 ] ; then
+ $READER "$patch"
+ printf "\n"
+ # Allows us to read user input below, assigns stdin to keyboard
+ exec < /dev/tty
+ terminal="1"
+else
+ cat "$patch"
+ printf "\n"
+ # Allows non zero zenity/powershell output
+ set +e
+ terminal="0"
+fi
while true; do
- read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn
+ if [ $terminal = "0" ] ; then
+ if [ -x "$ZENITY" ] ; then
+ ans=$($ZENITY --text-info --filename="$patch" --width=800 --height=600 --title="Do you want to apply that patch?" --ok-label="Apply" --cancel-label="Do not apply" --extra-button="Apply and stage")
+ if [ "$?" = "0" ] ; then
+ yn="Y"
+ else
+ if [ "$ans" = "Apply and stage" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ fi
+ elif [ -x "$XMSG" ] ; then
+ $XMSG -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?"
+ ans=$?
+ if [ "$ans" = "100" ] ; then
+ yn="Y"
+ elif [ "$ans" = "200" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ elif [ \( \( "$OSTYPE" = "msys" \) -o \( "$OSTYPE" = "win32" \) \) -a \( -x "$PWSH" \) ]; then
+ winmessage="$(canonicalize_filename "./.git/hooks/winmessage.ps1")"
+ $PWSH -noprofile -executionpolicy bypass -file "$winmessage" -file "$patch" -buttons "Apply":100,"Apply and stage":200,"Do not apply":0 -center -default "Do not apply" -geometry 800x600 -title "Do you want to apply that patch?"
+ ans=$?
+ if [ "$ans" = "100" ] ; then
+ yn="Y"
+ elif [ "$ans" = "200" ] ; then
+ yn="S"
+ else
+ yn="N"
+ fi
+ else
+ printf "Error: zenity, xmessage, or powershell executable not found.\n"
+ exit 1
+ fi
+ else
+ read -p "Do you want to apply that patch (Y - Apply, N - Do not apply, S - Apply and stage files)? [Y/N/S] " yn
+ fi
case $yn in
[Yy] ) git apply $patch;
printf "The patch was applied. You can now stage the changes and commit again.\n\n";
diff --git a/misc/hooks/winmessage.ps1 b/misc/hooks/winmessage.ps1
new file mode 100755
index 0000000000..3672579544
--- /dev/null
+++ b/misc/hooks/winmessage.ps1
@@ -0,0 +1,103 @@
+Param (
+ [string]$file = "",
+ [string]$text = "",
+ [string]$buttons = "OK:0",
+ [string]$default = "",
+ [switch]$nearmouse = $false,
+ [switch]$center = $false,
+ [string]$geometry = "",
+ [int32]$timeout = 0,
+ [string]$title = "Message"
+)
+Add-Type -assembly System.Windows.Forms
+
+$global:Result = 0
+
+$main_form = New-Object System.Windows.Forms.Form
+$main_form.Text = $title
+
+$geometry_data = $geometry.Split("+")
+if ($geometry_data.Length -ge 1) {
+ $size_data = $geometry_data[0].Split("x")
+ if ($size_data.Length -eq 2) {
+ $main_form.Width = $size_data[0]
+ $main_form.Height = $size_data[1]
+ }
+}
+if ($geometry_data.Length -eq 3) {
+ $main_form.StartPosition = [System.Windows.Forms.FormStartPosition]::Manual
+ $main_form.Location = New-Object System.Drawing.Point($geometry_data[1], $geometry_data[2])
+}
+if ($nearmouse) {
+ $main_form.StartPosition = [System.Windows.Forms.FormStartPosition]::Manual
+ $main_form.Location = System.Windows.Forms.Cursor.Position
+}
+if ($center) {
+ $main_form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
+}
+
+$main_form.SuspendLayout()
+
+$button_panel = New-Object System.Windows.Forms.FlowLayoutPanel
+$button_panel.SuspendLayout()
+$button_panel.FlowDirection = [System.Windows.Forms.FlowDirection]::RightToLeft
+$button_panel.Dock = [System.Windows.Forms.DockStyle]::Bottom
+$button_panel.Autosize = $true
+
+if ($file -ne "") {
+ $text = [IO.File]::ReadAllText($file).replace("`n", "`r`n")
+}
+
+if ($text -ne "") {
+ $text_box = New-Object System.Windows.Forms.TextBox
+ $text_box.Multiline = $true
+ $text_box.ReadOnly = $true
+ $text_box.Autosize = $true
+ $text_box.Text = $text
+ $text_box.Select(0,0)
+ $text_box.Dock = [System.Windows.Forms.DockStyle]::Fill
+ $main_form.Controls.Add($text_box)
+}
+
+$buttons_array = $buttons.Split(",")
+foreach ($button in $buttons_array) {
+ $button_data = $button.Split(":")
+ $button_ctl = New-Object System.Windows.Forms.Button
+ if ($button_data.Length -eq 2) {
+ $button_ctl.Tag = $button_data[1]
+ } else {
+ $button_ctl.Tag = 100 + $buttons_array.IndexOf($button)
+ }
+ if ($default -eq $button_data[0]) {
+ $main_form.AcceptButton = $button_ctl
+ }
+ $button_ctl.Autosize = $true
+ $button_ctl.Text = $button_data[0]
+ $button_ctl.Add_Click(
+ {
+ Param($sender)
+ $global:Result = $sender.Tag
+ $main_form.Close()
+ }
+ )
+ $button_panel.Controls.Add($button_ctl)
+}
+$main_form.Controls.Add($button_panel)
+
+$button_panel.ResumeLayout($false)
+$main_form.ResumeLayout($false)
+
+if ($timeout -gt 0) {
+ $timer = New-Object System.Windows.Forms.Timer
+ $timer.Add_Tick(
+ {
+ $global:Result = 0
+ $main_form.Close()
+ }
+ )
+ $timer.Interval = $timeout
+ $timer.Start()
+}
+$dlg_res = $main_form.ShowDialog()
+
+[Environment]::Exit($global:Result)
diff --git a/misc/scons/compilation_db.py b/misc/scons/compilation_db.py
new file mode 100644
index 0000000000..87db32adc9
--- /dev/null
+++ b/misc/scons/compilation_db.py
@@ -0,0 +1,177 @@
+# Copyright 2015 MongoDB Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import SCons
+import itertools
+
+# Implements the ability for SCons to emit a compilation database for the MongoDB project. See
+# http://clang.llvm.org/docs/JSONCompilationDatabase.html for details on what a compilation
+# database is, and why you might want one. The only user visible entry point here is
+# 'env.CompilationDatabase'. This method takes an optional 'target' to name the file that
+# should hold the compilation database, otherwise, the file defaults to compile_commands.json,
+# which is the name that most clang tools search for by default.
+
+# TODO: Is there a better way to do this than this global? Right now this exists so that the
+# emitter we add can record all of the things it emits, so that the scanner for the top level
+# compilation database can access the complete list, and also so that the writer has easy
+# access to write all of the files. But it seems clunky. How can the emitter and the scanner
+# communicate more gracefully?
+__COMPILATION_DB_ENTRIES = []
+
+# We make no effort to avoid rebuilding the entries. Someday, perhaps we could and even
+# integrate with the cache, but there doesn't seem to be much call for it.
+class __CompilationDbNode(SCons.Node.Python.Value):
+ def __init__(self, value):
+ SCons.Node.Python.Value.__init__(self, value)
+ self.Decider(changed_since_last_build_node)
+
+
+def changed_since_last_build_node(child, target, prev_ni, node):
+ """ Dummy decider to force always building"""
+ return True
+
+
+def makeEmitCompilationDbEntry(comstr):
+ """
+ Effectively this creates a lambda function to capture:
+ * command line
+ * source
+ * target
+ :param comstr: unevaluated command line
+ :return: an emitter which has captured the above
+ """
+ user_action = SCons.Action.Action(comstr)
+
+ def EmitCompilationDbEntry(target, source, env):
+ """
+ This emitter will be added to each c/c++ object build to capture the info needed
+ for clang tools
+ :param target: target node(s)
+ :param source: source node(s)
+ :param env: Environment for use building this node
+ :return: target(s), source(s)
+ """
+
+ dbtarget = __CompilationDbNode(source)
+
+ entry = env.__COMPILATIONDB_Entry(
+ target=dbtarget,
+ source=[],
+ __COMPILATIONDB_UTARGET=target,
+ __COMPILATIONDB_USOURCE=source,
+ __COMPILATIONDB_UACTION=user_action,
+ __COMPILATIONDB_ENV=env,
+ )
+
+ # TODO: Technically, these next two lines should not be required: it should be fine to
+ # cache the entries. However, they don't seem to update properly. Since they are quick
+ # to re-generate disable caching and sidestep this problem.
+ env.AlwaysBuild(entry)
+ env.NoCache(entry)
+
+ __COMPILATION_DB_ENTRIES.append(dbtarget)
+
+ return target, source
+
+ return EmitCompilationDbEntry
+
+
+def CompilationDbEntryAction(target, source, env, **kw):
+ """
+ Create a dictionary with evaluated command line, target, source
+ and store that info as an attribute on the target
+ (Which has been stored in __COMPILATION_DB_ENTRIES array
+ :param target: target node(s)
+ :param source: source node(s)
+ :param env: Environment for use building this node
+ :param kw:
+ :return: None
+ """
+
+ command = env["__COMPILATIONDB_UACTION"].strfunction(
+ target=env["__COMPILATIONDB_UTARGET"], source=env["__COMPILATIONDB_USOURCE"], env=env["__COMPILATIONDB_ENV"],
+ )
+
+ entry = {
+ "directory": env.Dir("#").abspath,
+ "command": command,
+ "file": str(env["__COMPILATIONDB_USOURCE"][0]),
+ }
+
+ target[0].write(entry)
+
+
+def WriteCompilationDb(target, source, env):
+ entries = []
+
+ for s in __COMPILATION_DB_ENTRIES:
+ entries.append(s.read())
+
+ with open(str(target[0]), "w") as target_file:
+ json.dump(entries, target_file, sort_keys=True, indent=4, separators=(",", ": "))
+
+
+def ScanCompilationDb(node, env, path):
+ return __COMPILATION_DB_ENTRIES
+
+
+def generate(env, **kwargs):
+
+ static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
+
+ env["COMPILATIONDB_COMSTR"] = kwargs.get("COMPILATIONDB_COMSTR", "Building compilation database $TARGET")
+
+ components_by_suffix = itertools.chain(
+ itertools.product(
+ env["CPPSUFFIXES"],
+ [
+ (static_obj, SCons.Defaults.StaticObjectEmitter, "$CXXCOM"),
+ (shared_obj, SCons.Defaults.SharedObjectEmitter, "$SHCXXCOM"),
+ ],
+ ),
+ )
+
+ for entry in components_by_suffix:
+ suffix = entry[0]
+ builder, base_emitter, command = entry[1]
+
+ # Ensure we have a valid entry
+ # used to auto ignore header files
+ if suffix in builder.emitter:
+ emitter = builder.emitter[suffix]
+ builder.emitter[suffix] = SCons.Builder.ListEmitter([emitter, makeEmitCompilationDbEntry(command),])
+
+ env["BUILDERS"]["__COMPILATIONDB_Entry"] = SCons.Builder.Builder(
+ action=SCons.Action.Action(CompilationDbEntryAction, None),
+ )
+
+ env["BUILDERS"]["__COMPILATIONDB_Database"] = SCons.Builder.Builder(
+ action=SCons.Action.Action(WriteCompilationDb, "$COMPILATIONDB_COMSTR"),
+ target_scanner=SCons.Scanner.Scanner(function=ScanCompilationDb, node_class=None),
+ )
+
+ def CompilationDatabase(env, target):
+ result = env.__COMPILATIONDB_Database(target=target, source=[])
+
+ env.AlwaysBuild(result)
+ env.NoCache(result)
+
+ return result
+
+ env.AddMethod(CompilationDatabase, "CompilationDatabase")
+
+
+def exists(env):
+ return True
diff --git a/modules/arkit/arkit_interface.mm b/modules/arkit/arkit_interface.mm
index 79f09e2a7e..7de824815a 100644
--- a/modules/arkit/arkit_interface.mm
+++ b/modules/arkit/arkit_interface.mm
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/os.h"
#include "scene/resources/surface_tool.h"
#include "servers/rendering/rendering_server_globals.h"
diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp
index cc74674eff..9c90faf66b 100644
--- a/modules/assimp/editor_scene_importer_assimp.cpp
+++ b/modules/assimp/editor_scene_importer_assimp.cpp
@@ -53,7 +53,6 @@ aiBone *get_bone_by_name(const aiScene *scene, aiString bone_name) {
// iterate over all the bones on the mesh for this node only!
for (unsigned int boneIndex = 0; boneIndex < mesh->mNumBones; boneIndex++) {
-
aiBone *bone = mesh->mBones[boneIndex];
if (bone->mName == bone_name) {
printf("matched bone by name: %s\n", bone->mName.C_Str());
@@ -66,7 +65,6 @@ aiBone *get_bone_by_name(const aiScene *scene, aiString bone_name) {
}
void EditorSceneImporterAssimp::get_extensions(List<String> *r_extensions) const {
-
const String import_setting_string = "filesystem/import/open_asset_import/";
Map<String, ImportFormat> import_format;
@@ -156,14 +154,11 @@ Node *EditorSceneImporterAssimp::import_scene(const String &p_path, uint32_t p_f
template <class T>
struct EditorSceneImporterAssetImportInterpolate {
-
T lerp(const T &a, const T &b, float c) const {
-
return a + (b - a) * c;
}
T catmull_rom(const T &p0, const T &p1, const T &p2, const T &p3, float t) {
-
float t2 = t * t;
float t3 = t2 * t;
@@ -185,7 +180,6 @@ struct EditorSceneImporterAssetImportInterpolate {
//thank you for existing, partial specialization
template <>
struct EditorSceneImporterAssetImportInterpolate<Quat> {
-
Quat lerp(const Quat &a, const Quat &b, float c) const {
ERR_FAIL_COND_V_MSG(!a.is_normalized(), Quat(), "The quaternion \"a\" must be normalized.");
ERR_FAIL_COND_V_MSG(!b.is_normalized(), Quat(), "The quaternion \"b\" must be normalized.");
@@ -214,8 +208,9 @@ T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, co
//could use binary search, worth it?
int idx = -1;
for (int i = 0; i < p_times.size(); i++) {
- if (p_times[i] > p_time)
+ if (p_times[i] > p_time) {
break;
+ }
idx++;
}
@@ -223,7 +218,6 @@ T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, co
switch (p_interp) {
case AssetImportAnimation::INTERP_LINEAR: {
-
if (idx == -1) {
return p_values[0];
} else if (idx >= p_times.size() - 1) {
@@ -236,7 +230,6 @@ T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, co
} break;
case AssetImportAnimation::INTERP_STEP: {
-
if (idx == -1) {
return p_values[0];
} else if (idx >= p_times.size() - 1) {
@@ -247,7 +240,6 @@ T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, co
} break;
case AssetImportAnimation::INTERP_CATMULLROMSPLINE: {
-
if (idx == -1) {
return p_values[1];
} else if (idx >= p_times.size() - 1) {
@@ -260,7 +252,6 @@ T EditorSceneImporterAssimp::_interpolate_track(const Vector<float> &p_times, co
} break;
case AssetImportAnimation::INTERP_CUBIC_SPLINE: {
-
if (idx == -1) {
return p_values[1];
} else if (idx >= p_times.size() - 1) {
@@ -310,7 +301,6 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
// populate light map
for (unsigned int l = 0; l < scene->mNumLights; l++) {
-
aiLight *ai_light = scene->mLights[l];
ERR_CONTINUE(ai_light == nullptr);
state.light_cache[AssimpUtils::get_assimp_string(ai_light->mName)] = l;
@@ -490,7 +480,6 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
if (assimp_node->mNumMeshes > 0) {
MeshInstance3D *mesh = create_mesh(state, assimp_node, node_name, parent_node, node_transform);
if (mesh) {
-
parent_node->remove_child(mesh_template);
// re-parent children
@@ -530,7 +519,6 @@ EditorSceneImporterAssimp::_generate_scene(const String &p_path, aiScene *scene,
}
if (p_flags & IMPORT_ANIMATION && scene->mNumAnimations) {
-
state.animation_player = memnew(AnimationPlayer);
state.root->add_child(state.animation_player);
state.animation_player->set_owner(state.root);
@@ -621,7 +609,6 @@ void EditorSceneImporterAssimp::_insert_animation_track(ImportState &scene, cons
int skeleton_bone = skeleton->find_bone(node_name);
if (skeleton_bone >= 0 && track_bone) {
-
Transform xform;
xform.basis.set_quat_scale(rot, scale);
xform.origin = pos;
@@ -666,7 +653,6 @@ Node *EditorSceneImporterAssimp::get_node_by_name(ImportState &state, String nam
/* Bone stack is a fifo handler for multiple armatures since armatures aren't a thing in assimp (yet) */
void EditorSceneImporterAssimp::RegenerateBoneStack(ImportState &state) {
-
state.bone_stack.clear();
// build bone stack list
for (unsigned int mesh_id = 0; mesh_id < state.assimp_scene->mNumMeshes; ++mesh_id) {
@@ -700,7 +686,6 @@ void EditorSceneImporterAssimp::RegenerateBoneStack(ImportState &state, aiMesh *
// animation tracks are per bone
void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_animation_index, int p_bake_fps) {
-
ERR_FAIL_INDEX(p_animation_index, (int)state.assimp_scene->mNumAnimations);
const aiAnimation *anim = state.assimp_scene->mAnimations[p_animation_index];
@@ -795,7 +780,6 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
//blend shape tracks
for (size_t i = 0; i < anim->mNumMorphMeshChannels; i++) {
-
const aiMeshMorphAnim *anim_mesh = anim->mMorphMeshChannels[i];
const String prop_name = AssimpUtils::get_assimp_string(anim_mesh->mName);
@@ -816,14 +800,12 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
//add the tracks for this mesh
int base_track = animation->get_track_count();
for (int j = 0; j < mesh->get_blend_shape_count(); j++) {
-
animation->add_track(Animation::TYPE_VALUE);
animation->track_set_path(base_track + j, base_path + ":blend_shapes/" + mesh->get_blend_shape_name(j));
}
for (size_t k = 0; k < anim_mesh->mNumKeys; k++) {
for (size_t j = 0; j < anim_mesh->mKeys[k].mNumValuesAndWeights; j++) {
-
float t = anim_mesh->mKeys[k].mTime / ticks_per_second;
float w = anim_mesh->mKeys[k].mWeights[j];
@@ -836,6 +818,7 @@ void EditorSceneImporterAssimp::_import_animation(ImportState &state, int p_anim
state.animation_player->add_animation(name, animation);
}
}
+
//
// Mesh Generation from indices ? why do we need so much mesh code
// [debt needs looked into]
@@ -843,7 +826,6 @@ Ref<Mesh>
EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices,
const aiNode *assimp_node, Ref<Skin> &skin,
Skeleton3D *&skeleton_assigned) {
-
Ref<ArrayMesh> mesh;
mesh.instance();
bool has_uvs = false;
@@ -894,7 +876,6 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
int bone_index = skeleton_assigned->find_bone(bone_name);
ERR_CONTINUE(bone_index == -1);
for (size_t w = 0; w < bone->mNumWeights; w++) {
-
aiVertexWeight ai_weights = bone->mWeights[w];
BoneInfo bi;
@@ -920,7 +901,6 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
st->begin(Mesh::PRIMITIVE_TRIANGLES);
for (size_t j = 0; j < ai_mesh->mNumVertices; j++) {
-
// Get the texture coordinates if they exist
if (ai_mesh->HasTextureCoords(0)) {
has_uvs = true;
@@ -956,7 +936,6 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
// We have vertex weights right?
if (vertex_weights.has(j)) {
-
Vector<BoneInfo> bone_info = vertex_weights[j];
Vector<int> bones;
bones.resize(bone_info.size());
@@ -1200,7 +1179,6 @@ EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(ImportState &stat
Mesh::PrimitiveType primitive = Mesh::PRIMITIVE_TRIANGLES;
for (size_t j = 0; j < ai_mesh->mNumAnimMeshes; j++) {
-
String ai_anim_mesh_name = AssimpUtils::get_assimp_string(ai_mesh->mAnimMeshes[j]->mName);
if (ai_anim_mesh_name.empty()) {
@@ -1482,7 +1460,6 @@ Node3D *EditorSceneImporterAssimp::create_camera(
void EditorSceneImporterAssimp::_generate_node(
ImportState &state,
const aiNode *assimp_node) {
-
ERR_FAIL_COND(assimp_node == nullptr);
state.nodes.push_back(assimp_node);
String parent_name = AssimpUtils::get_assimp_string(assimp_node->mParent->mName);
diff --git a/modules/assimp/import_state.h b/modules/assimp/import_state.h
index cda1a854f0..4a3bd17acb 100644
--- a/modules/assimp/import_state.h
+++ b/modules/assimp/import_state.h
@@ -55,7 +55,6 @@ namespace AssimpImporter {
* This makes the code simpler and contains useful lookups.
*/
struct ImportState {
-
String path;
Node3D *root;
const aiScene *assimp_scene;
diff --git a/modules/assimp/import_utils.h b/modules/assimp/import_utils.h
index f78931add3..dc85d06fed 100644
--- a/modules/assimp/import_utils.h
+++ b/modules/assimp/import_utils.h
@@ -162,7 +162,6 @@ public:
}
static String get_anim_string_from_assimp(const aiString &p_string) {
-
String name;
name.parse_utf8(p_string.C_Str() /*,p_string.length*/);
if (name.find(":") != -1) {
@@ -202,20 +201,34 @@ public:
*/
static float get_fbx_fps(int32_t time_mode, const aiScene *p_scene) {
switch (time_mode) {
- case AssetImportFbx::TIME_MODE_DEFAULT: return 24; //hack
- case AssetImportFbx::TIME_MODE_120: return 120;
- case AssetImportFbx::TIME_MODE_100: return 100;
- case AssetImportFbx::TIME_MODE_60: return 60;
- case AssetImportFbx::TIME_MODE_50: return 50;
- case AssetImportFbx::TIME_MODE_48: return 48;
- case AssetImportFbx::TIME_MODE_30: return 30;
- case AssetImportFbx::TIME_MODE_30_DROP: return 30;
- case AssetImportFbx::TIME_MODE_NTSC_DROP_FRAME: return 29.9700262f;
- case AssetImportFbx::TIME_MODE_NTSC_FULL_FRAME: return 29.9700262f;
- case AssetImportFbx::TIME_MODE_PAL: return 25;
- case AssetImportFbx::TIME_MODE_CINEMA: return 24;
- case AssetImportFbx::TIME_MODE_1000: return 1000;
- case AssetImportFbx::TIME_MODE_CINEMA_ND: return 23.976f;
+ case AssetImportFbx::TIME_MODE_DEFAULT:
+ return 24; //hack
+ case AssetImportFbx::TIME_MODE_120:
+ return 120;
+ case AssetImportFbx::TIME_MODE_100:
+ return 100;
+ case AssetImportFbx::TIME_MODE_60:
+ return 60;
+ case AssetImportFbx::TIME_MODE_50:
+ return 50;
+ case AssetImportFbx::TIME_MODE_48:
+ return 48;
+ case AssetImportFbx::TIME_MODE_30:
+ return 30;
+ case AssetImportFbx::TIME_MODE_30_DROP:
+ return 30;
+ case AssetImportFbx::TIME_MODE_NTSC_DROP_FRAME:
+ return 29.9700262f;
+ case AssetImportFbx::TIME_MODE_NTSC_FULL_FRAME:
+ return 29.9700262f;
+ case AssetImportFbx::TIME_MODE_PAL:
+ return 25;
+ case AssetImportFbx::TIME_MODE_CINEMA:
+ return 24;
+ case AssetImportFbx::TIME_MODE_1000:
+ return 1000;
+ case AssetImportFbx::TIME_MODE_CINEMA_ND:
+ return 23.976f;
case AssetImportFbx::TIME_MODE_CUSTOM:
int32_t frame_rate = -1;
p_scene->mMetaData->Get("FrameRate", frame_rate);
@@ -340,7 +353,6 @@ public:
* Load or load from cache image :)
*/
static Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path) {
-
Map<String, Ref<Image>>::Element *match = state.path_to_image_cache.find(p_path);
// if our cache contains this image then don't bother
diff --git a/modules/assimp/register_types.cpp b/modules/assimp/register_types.cpp
index 3af8827bf9..6cb0fc982f 100644
--- a/modules/assimp/register_types.cpp
+++ b/modules/assimp/register_types.cpp
@@ -42,7 +42,6 @@ static void _editor_init() {
#endif
void register_assimp_types() {
-
#ifdef TOOLS_ENABLED
ClassDB::APIType prev_api = ClassDB::get_current_api();
ClassDB::set_current_api(ClassDB::API_EDITOR);
diff --git a/modules/basis_universal/register_types.cpp b/modules/basis_universal/register_types.cpp
index f31c889a6d..27b299a65d 100644
--- a/modules/basis_universal/register_types.cpp
+++ b/modules/basis_universal/register_types.cpp
@@ -54,7 +54,6 @@ basist::etc1_global_selector_codebook *sel_codebook = nullptr;
#ifdef TOOLS_ENABLED
static Vector<uint8_t> basis_universal_packer(const Ref<Image> &p_image, Image::UsedChannels p_channels) {
-
Vector<uint8_t> budata;
{
@@ -163,7 +162,6 @@ static Ref<Image> basis_universal_unpacker(const Vector<uint8_t> &p_buffer) {
switch (*(uint32_t *)(ptr)) {
case BASIS_DECOMPRESS_RG: {
-
if (RS::get_singleton()->has_os_feature("rgtc")) {
format = basist::transcoder_texture_format::cTFBC5; // get this from renderer
imgfmt = Image::FORMAT_RGTC_RG;
@@ -186,7 +184,6 @@ static Ref<Image> basis_universal_unpacker(const Vector<uint8_t> &p_buffer) {
format = basist::transcoder_texture_format::cTFBC1; // get this from renderer
imgfmt = Image::FORMAT_DXT1;
} else if (RS::get_singleton()->has_os_feature("etc")) {
-
format = basist::transcoder_texture_format::cTFETC1; // get this from renderer
imgfmt = Image::FORMAT_ETC;
} else {
@@ -243,13 +240,13 @@ static Ref<Image> basis_universal_unpacker(const Vector<uint8_t> &p_buffer) {
{
uint8_t *w = gpudata.ptrw();
uint8_t *dst = w;
- for (int i = 0; i < gpudata.size(); i++)
+ for (int i = 0; i < gpudata.size(); i++) {
dst[i] = 0x00;
+ }
int ofs = 0;
tr.start_transcoding(ptr, size);
for (uint32_t i = 0; i < info.m_total_levels; i++) {
-
basist::basisu_image_level_info level;
tr.get_image_level_info(ptr, size, level, 0, i);
@@ -279,7 +276,6 @@ void register_basis_universal_types() {
}
void unregister_basis_universal_types() {
-
#ifdef TOOLS_ENABLED
delete sel_codebook;
Image::basis_universal_packer = nullptr;
diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp
index ea2b2b548f..ac4e534983 100644
--- a/modules/bmp/image_loader_bmp.cpp
+++ b/modules/bmp/image_loader_bmp.cpp
@@ -35,11 +35,11 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
const uint8_t *p_color_buffer,
const uint32_t color_table_size,
const bmp_header_s &p_header) {
-
Error err = OK;
- if (p_buffer == nullptr)
+ if (p_buffer == nullptr) {
err = FAILED;
+ }
if (err == OK) {
size_t index = 0;
@@ -60,7 +60,6 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
ERR_FAIL_COND_V(height % 2 != 0, ERR_UNAVAILABLE);
} else if (bits_per_pixel == 16) {
-
ERR_FAIL_V(ERR_UNAVAILABLE);
}
@@ -153,7 +152,7 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
if (p_color_buffer == nullptr || color_table_size == 0) { // regular pixels
- p_image->create(width, height, 0, Image::FORMAT_RGBA8, data);
+ p_image->create(width, height, false, Image::FORMAT_RGBA8, data);
} else { // data is in indexed format, extend it
@@ -193,7 +192,7 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
dest += 4;
}
- p_image->create(width, height, 0, Image::FORMAT_RGBA8, extended_data);
+ p_image->create(width, height, false, Image::FORMAT_RGBA8, extended_data);
}
}
return err;
@@ -201,7 +200,6 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image,
Error ImageLoaderBMP::load_image(Ref<Image> p_image, FileAccess *f,
bool p_force_linear, float p_scale) {
-
bmp_header_s bmp_header;
Error err = ERR_INVALID_DATA;
@@ -290,7 +288,6 @@ Error ImageLoaderBMP::load_image(Ref<Image> p_image, FileAccess *f,
void ImageLoaderBMP::get_recognized_extensions(
List<String> *p_extensions) const {
-
p_extensions->push_back("bmp");
}
diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub
index 692c749886..b853ebfc63 100644
--- a/modules/bullet/SCsub
+++ b/modules/bullet/SCsub
@@ -175,6 +175,7 @@ if env["builtin_bullet"]:
"BulletSoftBody/btDeformableContactProjection.cpp",
"BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp",
"BulletSoftBody/btDeformableContactConstraint.cpp",
+ "BulletSoftBody/poly34.cpp",
# clew
"clew/clew.c",
# LinearMath
@@ -203,6 +204,8 @@ if env["builtin_bullet"]:
# if env['target'] == "debug" or env['target'] == "release_debug":
# env_bullet.Append(CPPDEFINES=['BT_DEBUG'])
+ env_bullet.Append(CPPDEFINES=["BT_USE_OLD_DAMPING_METHOD"])
+
env_thirdparty = env_bullet.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
diff --git a/modules/bullet/area_bullet.cpp b/modules/bullet/area_bullet.cpp
index 4d727529ef..79d8e252f0 100644
--- a/modules/bullet/area_bullet.cpp
+++ b/modules/bullet/area_bullet.cpp
@@ -44,19 +44,7 @@
*/
AreaBullet::AreaBullet() :
- RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_AREA),
- monitorable(true),
- spOv_mode(PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED),
- spOv_gravityPoint(false),
- spOv_gravityPointDistanceScale(0),
- spOv_gravityPointAttenuation(1),
- spOv_gravityVec(0, -1, 0),
- spOv_gravityMag(10),
- spOv_linearDump(0.1),
- spOv_angularDump(1),
- spOv_priority(0),
- isScratched(false) {
-
+ RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_AREA) {
btGhost = bulletnew(btGhostObject);
reload_shapes();
setupBulletCollisionObject(btGhost);
@@ -64,19 +52,22 @@ AreaBullet::AreaBullet() :
/// In order to use collision objects as trigger, you have to disable the collision response.
set_collision_enabled(false);
- for (int i = 0; i < 5; ++i)
+ for (int i = 0; i < 5; ++i) {
call_event_res_ptr[i] = &call_event_res[i];
+ }
}
AreaBullet::~AreaBullet() {
// signal are handled by godot, so just clear without notify
- for (int i = overlappingObjects.size() - 1; 0 <= i; --i)
+ for (int i = overlappingObjects.size() - 1; 0 <= i; --i) {
overlappingObjects[i].object->on_exit_area(this);
+ }
}
void AreaBullet::dispatch_callbacks() {
- if (!isScratched)
+ if (!isScratched) {
return;
+ }
isScratched = false;
// Reverse order because I've to remove EXIT objects
@@ -102,7 +93,6 @@ void AreaBullet::dispatch_callbacks() {
}
void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3D::AreaBodyStatus p_status) {
-
InOutEventCallback &event = eventsCallbacks[static_cast<int>(p_otherObject->getType())];
Object *areaGodoObject = ObjectDB::get_instance(event.event_callback_id);
@@ -122,15 +112,17 @@ void AreaBullet::call_event(CollisionObjectBullet *p_otherObject, PhysicsServer3
}
void AreaBullet::scratch() {
- if (isScratched)
+ if (isScratched) {
return;
+ }
isScratched = true;
}
void AreaBullet::clear_overlaps(bool p_notify) {
for (int i = overlappingObjects.size() - 1; 0 <= i; --i) {
- if (p_notify)
+ if (p_notify) {
call_event(overlappingObjects[i].object, PhysicsServer3D::AREA_BODY_REMOVED);
+ }
overlappingObjects[i].object->on_exit_area(this);
}
overlappingObjects.clear();
@@ -139,8 +131,9 @@ void AreaBullet::clear_overlaps(bool p_notify) {
void AreaBullet::remove_overlap(CollisionObjectBullet *p_object, bool p_notify) {
for (int i = overlappingObjects.size() - 1; 0 <= i; --i) {
if (overlappingObjects[i].object == p_object) {
- if (p_notify)
+ if (p_notify) {
call_event(overlappingObjects[i].object, PhysicsServer3D::AREA_BODY_REMOVED);
+ }
overlappingObjects[i].object->on_exit_area(this);
overlappingObjects.remove(i);
break;
diff --git a/modules/bullet/area_bullet.h b/modules/bullet/area_bullet.h
index 0272350510..cde889c1ba 100644
--- a/modules/bullet/area_bullet.h
+++ b/modules/bullet/area_bullet.h
@@ -61,12 +61,10 @@ public:
};
struct OverlappingObjectData {
- CollisionObjectBullet *object;
- OverlapState state;
+ CollisionObjectBullet *object = nullptr;
+ OverlapState state = OVERLAP_STATE_ENTER;
- OverlappingObjectData() :
- object(nullptr),
- state(OVERLAP_STATE_ENTER) {}
+ OverlappingObjectData() {}
OverlappingObjectData(CollisionObjectBullet *p_object, OverlapState p_state) :
object(p_object),
state(p_state) {}
@@ -86,19 +84,19 @@ private:
btGhostObject *btGhost;
Vector<OverlappingObjectData> overlappingObjects;
- bool monitorable;
-
- PhysicsServer3D::AreaSpaceOverrideMode spOv_mode;
- bool spOv_gravityPoint;
- real_t spOv_gravityPointDistanceScale;
- real_t spOv_gravityPointAttenuation;
- Vector3 spOv_gravityVec;
- real_t spOv_gravityMag;
- real_t spOv_linearDump;
- real_t spOv_angularDump;
- int spOv_priority;
-
- bool isScratched;
+ bool monitorable = true;
+
+ PhysicsServer3D::AreaSpaceOverrideMode spOv_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED;
+ bool spOv_gravityPoint = false;
+ real_t spOv_gravityPointDistanceScale = 0;
+ real_t spOv_gravityPointAttenuation = 1;
+ Vector3 spOv_gravityVec = Vector3(0, -1, 0);
+ real_t spOv_gravityMag = 10;
+ real_t spOv_linearDump = 0.1;
+ real_t spOv_angularDump = 1;
+ int spOv_priority = 0;
+
+ bool isScratched = false;
InOutEventCallback eventsCallbacks[2];
diff --git a/modules/bullet/btRayShape.cpp b/modules/bullet/btRayShape.cpp
index 0f54f848dc..a754ca6a89 100644
--- a/modules/bullet/btRayShape.cpp
+++ b/modules/bullet/btRayShape.cpp
@@ -50,7 +50,6 @@ btRayShape::~btRayShape() {
}
void btRayShape::setLength(btScalar p_length) {
-
m_length = p_length;
reload_cache();
}
@@ -61,7 +60,6 @@ void btRayShape::setMargin(btScalar margin) {
}
void btRayShape::setSlipsOnSlope(bool p_slipsOnSlope) {
-
slipsOnSlope = p_slipsOnSlope;
}
@@ -70,10 +68,11 @@ btVector3 btRayShape::localGetSupportingVertex(const btVector3 &vec) const {
}
btVector3 btRayShape::localGetSupportingVertexWithoutMargin(const btVector3 &vec) const {
- if (vec.z() > 0)
+ if (vec.z() > 0) {
return m_shapeAxis * m_cacheScaledLength;
- else
+ } else {
return btVector3(0, 0, 0);
+ }
}
void btRayShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3 *vectors, btVector3 *supportVerticesOut, int numVectors) const {
@@ -101,7 +100,6 @@ void btRayShape::getPreferredPenetrationDirection(int index, btVector3 &penetrat
}
void btRayShape::reload_cache() {
-
m_cacheScaledLength = m_length * m_localScaling[2];
m_cacheSupportPoint.setIdentity();
diff --git a/modules/bullet/btRayShape.h b/modules/bullet/btRayShape.h
index df6dd93d57..d9ecde81e6 100644
--- a/modules/bullet/btRayShape.h
+++ b/modules/bullet/btRayShape.h
@@ -42,7 +42,6 @@
/// Ray shape around z axis
ATTRIBUTE_ALIGNED16(class)
btRayShape : public btConvexInternalShape {
-
btScalar m_length;
bool slipsOnSlope;
/// The default axis is the z
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index 2705c749a2..55686543f3 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -79,9 +79,7 @@ void BulletPhysicsServer3D::_bind_methods() {
}
BulletPhysicsServer3D::BulletPhysicsServer3D() :
- PhysicsServer3D(),
- active(true),
- active_spaces_count(0) {}
+ PhysicsServer3D() {}
BulletPhysicsServer3D::~BulletPhysicsServer3D() {}
@@ -90,35 +88,27 @@ RID BulletPhysicsServer3D::shape_create(ShapeType p_shape) {
switch (p_shape) {
case SHAPE_PLANE: {
-
shape = bulletnew(PlaneShapeBullet);
} break;
case SHAPE_SPHERE: {
-
shape = bulletnew(SphereShapeBullet);
} break;
case SHAPE_BOX: {
-
shape = bulletnew(BoxShapeBullet);
} break;
case SHAPE_CAPSULE: {
-
shape = bulletnew(CapsuleShapeBullet);
} break;
case SHAPE_CYLINDER: {
-
shape = bulletnew(CylinderShapeBullet);
} break;
case SHAPE_CONVEX_POLYGON: {
-
shape = bulletnew(ConvexPolygonShapeBullet);
} break;
case SHAPE_CONCAVE_POLYGON: {
-
shape = bulletnew(ConcavePolygonShapeBullet);
} break;
case SHAPE_HEIGHTMAP: {
-
shape = bulletnew(HeightMapShapeBullet);
} break;
case SHAPE_RAY: {
@@ -178,7 +168,6 @@ RID BulletPhysicsServer3D::space_create() {
}
void BulletPhysicsServer3D::space_set_active(RID p_space, bool p_active) {
-
SpaceBullet *space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
@@ -337,8 +326,9 @@ void BulletPhysicsServer3D::area_clear_shapes(RID p_area) {
AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- for (int i = area->get_shape_count(); 0 < i; --i)
+ for (int i = area->get_shape_count(); 0 < i; --i) {
area->remove_shape_full(0);
+ }
}
void BulletPhysicsServer3D::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) {
@@ -373,7 +363,6 @@ void BulletPhysicsServer3D::area_set_param(RID p_area, AreaParameter p_param, co
space->set_param(p_param, p_value);
}
} else {
-
AreaBullet *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -455,8 +444,9 @@ RID BulletPhysicsServer3D::body_create(BodyMode p_mode, bool p_init_sleeping) {
body->set_mode(p_mode);
body->set_collision_layer(1);
body->set_collision_mask(1);
- if (p_init_sleeping)
+ if (p_init_sleeping) {
body->set_state(BODY_STATE_SLEEPING, p_init_sleeping);
+ }
CreateThenReturnRID(rigid_body_owner, body);
}
@@ -470,8 +460,9 @@ void BulletPhysicsServer3D::body_set_space(RID p_body, RID p_space) {
ERR_FAIL_COND(!space);
}
- if (body->get_space() == space)
+ if (body->get_space() == space) {
return; //pointles
+ }
body->set_space(space);
}
@@ -481,8 +472,9 @@ RID BulletPhysicsServer3D::body_get_space(RID p_body) const {
ERR_FAIL_COND_V(!body, RID());
SpaceBullet *space = body->get_space();
- if (!space)
+ if (!space) {
return RID();
+ }
return space->get_self();
}
@@ -499,7 +491,6 @@ PhysicsServer3D::BodyMode BulletPhysicsServer3D::body_get_mode(RID p_body) const
}
void BulletPhysicsServer3D::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform, bool p_disabled) {
-
RigidBodyBullet *body = rigid_body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -653,7 +644,6 @@ void BulletPhysicsServer3D::body_set_kinematic_safe_margin(RID p_body, real_t p_
ERR_FAIL_COND(!body);
if (body->get_kinematic_utilities()) {
-
body->get_kinematic_utilities()->setSafeMargin(p_margin);
}
}
@@ -663,7 +653,6 @@ real_t BulletPhysicsServer3D::body_get_kinematic_safe_margin(RID p_body) const {
ERR_FAIL_COND_V(!body, 0);
if (body->get_kinematic_utilities()) {
-
return body->get_kinematic_utilities()->safe_margin;
}
@@ -885,8 +874,9 @@ RID BulletPhysicsServer3D::soft_body_create(bool p_init_sleeping) {
SoftBodyBullet *body = bulletnew(SoftBodyBullet);
body->set_collision_layer(1);
body->set_collision_mask(1);
- if (p_init_sleeping)
+ if (p_init_sleeping) {
body->set_activation_state(false);
+ }
CreateThenReturnRID(soft_body_owner, body);
}
@@ -907,8 +897,9 @@ void BulletPhysicsServer3D::soft_body_set_space(RID p_body, RID p_space) {
ERR_FAIL_COND(!space);
}
- if (body->get_space() == space)
+ if (body->get_space() == space) {
return; //pointles
+ }
body->set_space(space);
}
@@ -918,8 +909,9 @@ RID BulletPhysicsServer3D::soft_body_get_space(RID p_body) const {
ERR_FAIL_COND_V(!body, RID());
SpaceBullet *space = body->get_space();
- if (!space)
+ if (!space) {
return RID();
+ }
return space->get_self();
}
@@ -1489,7 +1481,6 @@ int BulletPhysicsServer3D::generic_6dof_joint_get_precision(RID p_joint) {
void BulletPhysicsServer3D::free(RID p_rid) {
if (shape_owner.owns(p_rid)) {
-
ShapeBullet *shape = shape_owner.getornull(p_rid);
// Notify the shape is configured
@@ -1500,7 +1491,6 @@ void BulletPhysicsServer3D::free(RID p_rid) {
shape_owner.free(p_rid);
bulletdelete(shape);
} else if (rigid_body_owner.owns(p_rid)) {
-
RigidBodyBullet *body = rigid_body_owner.getornull(p_rid);
body->set_space(nullptr);
@@ -1511,7 +1501,6 @@ void BulletPhysicsServer3D::free(RID p_rid) {
bulletdelete(body);
} else if (soft_body_owner.owns(p_rid)) {
-
SoftBodyBullet *body = soft_body_owner.getornull(p_rid);
body->set_space(nullptr);
@@ -1520,7 +1509,6 @@ void BulletPhysicsServer3D::free(RID p_rid) {
bulletdelete(body);
} else if (area_owner.owns(p_rid)) {
-
AreaBullet *area = area_owner.getornull(p_rid);
area->set_space(nullptr);
@@ -1531,14 +1519,12 @@ void BulletPhysicsServer3D::free(RID p_rid) {
bulletdelete(area);
} else if (joint_owner.owns(p_rid)) {
-
JointBullet *joint = joint_owner.getornull(p_rid);
joint->destroy_internal_constraint();
joint_owner.free(p_rid);
bulletdelete(joint);
} else if (space_owner.owns(p_rid)) {
-
SpaceBullet *space = space_owner.getornull(p_rid);
space->remove_all_collision_objects();
@@ -1547,7 +1533,6 @@ void BulletPhysicsServer3D::free(RID p_rid) {
space_owner.free(p_rid);
bulletdelete(space);
} else {
-
ERR_FAIL_MSG("Invalid ID.");
}
}
@@ -1557,13 +1542,13 @@ void BulletPhysicsServer3D::init() {
}
void BulletPhysicsServer3D::step(float p_deltaTime) {
- if (!active)
+ if (!active) {
return;
+ }
BulletPhysicsDirectBodyState3D::singleton_setDeltaTime(p_deltaTime);
for (int i = 0; i < active_spaces_count; ++i) {
-
active_spaces[i]->step(p_deltaTime);
}
}
diff --git a/modules/bullet/bullet_physics_server.h b/modules/bullet/bullet_physics_server.h
index ea9c5e589e..558d1ce5f7 100644
--- a/modules/bullet/bullet_physics_server.h
+++ b/modules/bullet/bullet_physics_server.h
@@ -40,6 +40,7 @@
#include "shape_bullet.h"
#include "soft_body_bullet.h"
#include "space_bullet.h"
+
/**
@author AndreaCatania
*/
@@ -49,8 +50,8 @@ class BulletPhysicsServer3D : public PhysicsServer3D {
friend class BulletPhysicsDirectSpaceState;
- bool active;
- char active_spaces_count;
+ bool active = true;
+ char active_spaces_count = 0;
Vector<SpaceBullet *> active_spaces;
mutable RID_PtrOwner<SpaceBullet> space_owner;
diff --git a/modules/bullet/collision_object_bullet.cpp b/modules/bullet/collision_object_bullet.cpp
index 1b72c2f577..a3158a15e5 100644
--- a/modules/bullet/collision_object_bullet.cpp
+++ b/modules/bullet/collision_object_bullet.cpp
@@ -80,27 +80,17 @@ btTransform CollisionObjectBullet::ShapeWrapper::get_adjusted_transform() const
void CollisionObjectBullet::ShapeWrapper::claim_bt_shape(const btVector3 &body_scale) {
if (!bt_shape) {
- if (active)
+ if (active) {
bt_shape = shape->create_bt_shape(scale * body_scale);
- else
+ } else {
bt_shape = ShapeBullet::create_shape_empty();
+ }
}
}
CollisionObjectBullet::CollisionObjectBullet(Type p_type) :
RIDBullet(),
- type(p_type),
- instance_id(ObjectID()),
- collisionLayer(0),
- collisionMask(0),
- collisionsEnabled(true),
- m_isStatic(false),
- ray_pickable(false),
- bt_collision_object(nullptr),
- body_scale(1., 1., 1.),
- force_shape_reset(false),
- space(nullptr),
- isTransformChanged(false) {}
+ type(p_type) {}
CollisionObjectBullet::~CollisionObjectBullet() {
// Remove all overlapping, notify is not required since godot take care of it
@@ -147,18 +137,21 @@ void CollisionObjectBullet::setupBulletCollisionObject(btCollisionObject *p_coll
void CollisionObjectBullet::add_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject) {
exceptions.insert(p_ignoreCollisionObject->get_self());
- if (!bt_collision_object)
+ if (!bt_collision_object) {
return;
+ }
bt_collision_object->setIgnoreCollisionCheck(p_ignoreCollisionObject->bt_collision_object, true);
- if (space)
+ if (space) {
space->get_broadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bt_collision_object->getBroadphaseHandle(), space->get_dispatcher());
+ }
}
void CollisionObjectBullet::remove_collision_exception(const CollisionObjectBullet *p_ignoreCollisionObject) {
exceptions.erase(p_ignoreCollisionObject->get_self());
bt_collision_object->setIgnoreCollisionCheck(p_ignoreCollisionObject->bt_collision_object, false);
- if (space)
+ if (space) {
space->get_broadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bt_collision_object->getBroadphaseHandle(), space->get_dispatcher());
+ }
}
bool CollisionObjectBullet::has_collision_exception(const CollisionObjectBullet *p_otherCollisionObject) const {
@@ -195,7 +188,6 @@ int CollisionObjectBullet::get_godot_object_flags() const {
}
void CollisionObjectBullet::set_transform(const Transform &p_global_transform) {
-
set_body_scale(p_global_transform.basis.get_scale_abs());
btTransform bt_transform;
@@ -225,11 +217,6 @@ void CollisionObjectBullet::notify_transform_changed() {
isTransformChanged = true;
}
-RigidCollisionObjectBullet::RigidCollisionObjectBullet(Type p_type) :
- CollisionObjectBullet(p_type),
- mainShape(nullptr) {
-}
-
RigidCollisionObjectBullet::~RigidCollisionObjectBullet() {
remove_all_shapes(true, true);
if (mainShape && mainShape->isCompound()) {
@@ -266,8 +253,9 @@ btCollisionShape *RigidCollisionObjectBullet::get_bt_shape(int p_index) const {
int RigidCollisionObjectBullet::find_shape(ShapeBullet *p_shape) const {
const int size = shapes.size();
for (int i = 0; i < size; ++i) {
- if (shapes[i].shape == p_shape)
+ if (shapes[i].shape == p_shape) {
return i;
+ }
}
return -1;
}
@@ -297,8 +285,9 @@ void RigidCollisionObjectBullet::remove_all_shapes(bool p_permanentlyFromThisBod
internal_shape_destroy(i, p_permanentlyFromThisBody);
}
shapes.clear();
- if (!p_force_not_reload)
+ if (!p_force_not_reload) {
reload_shapes();
+ }
}
void RigidCollisionObjectBullet::set_shape_transform(int p_index, const Transform &p_transform) {
@@ -319,8 +308,9 @@ Transform RigidCollisionObjectBullet::get_shape_transform(int p_index) const {
}
void RigidCollisionObjectBullet::set_shape_disabled(int p_index, bool p_disabled) {
- if (shapes[p_index].active != p_disabled)
+ if (shapes[p_index].active != p_disabled) {
return;
+ }
shapes.write[p_index].active = !p_disabled;
shape_changed(p_index);
}
@@ -339,7 +329,6 @@ void RigidCollisionObjectBullet::shape_changed(int p_shape_index) {
}
void RigidCollisionObjectBullet::reload_shapes() {
-
if (mainShape && mainShape->isCompound()) {
// Destroy compound
bulletdelete(mainShape);
diff --git a/modules/bullet/collision_object_bullet.h b/modules/bullet/collision_object_bullet.h
index 25176458a7..f1423a69e4 100644
--- a/modules/bullet/collision_object_bullet.h
+++ b/modules/bullet/collision_object_bullet.h
@@ -69,27 +69,22 @@ public:
};
struct ShapeWrapper {
- ShapeBullet *shape;
- btCollisionShape *bt_shape;
+ ShapeBullet *shape = nullptr;
+ btCollisionShape *bt_shape = nullptr;
btTransform transform;
btVector3 scale;
- bool active;
+ bool active = true;
- ShapeWrapper() :
- shape(nullptr),
- bt_shape(nullptr),
- active(true) {}
+ ShapeWrapper() {}
ShapeWrapper(ShapeBullet *p_shape, const btTransform &p_transform, bool p_active) :
shape(p_shape),
- bt_shape(nullptr),
active(p_active) {
set_transform(p_transform);
}
ShapeWrapper(ShapeBullet *p_shape, const Transform &p_transform, bool p_active) :
shape(p_shape),
- bt_shape(nullptr),
active(p_active) {
set_transform(p_transform);
}
@@ -117,15 +112,15 @@ public:
protected:
Type type;
ObjectID instance_id;
- uint32_t collisionLayer;
- uint32_t collisionMask;
- bool collisionsEnabled;
- bool m_isStatic;
- bool ray_pickable;
- btCollisionObject *bt_collision_object;
- Vector3 body_scale;
- bool force_shape_reset;
- SpaceBullet *space;
+ uint32_t collisionLayer = 0;
+ uint32_t collisionMask = 0;
+ bool collisionsEnabled = true;
+ bool m_isStatic = false;
+ bool ray_pickable = false;
+ btCollisionObject *bt_collision_object = nullptr;
+ Vector3 body_scale = Vector3(1, 1, 1);
+ bool force_shape_reset = false;
+ SpaceBullet *space = nullptr;
VSet<RID> exceptions;
@@ -133,7 +128,7 @@ protected:
/// New area is added when overlap with new area (AreaBullet::addOverlap), then is removed when it exit (CollisionObjectBullet::onExitArea)
/// This array is used mainly to know which area hold the pointer of this object
Vector<AreaBullet *> areasOverlapped;
- bool isTransformChanged;
+ bool isTransformChanged = false;
public:
CollisionObjectBullet(Type p_type);
@@ -218,11 +213,12 @@ public:
class RigidCollisionObjectBullet : public CollisionObjectBullet, public ShapeOwnerBullet {
protected:
- btCollisionShape *mainShape;
+ btCollisionShape *mainShape = nullptr;
Vector<ShapeWrapper> shapes;
public:
- RigidCollisionObjectBullet(Type p_type);
+ RigidCollisionObjectBullet(Type p_type) :
+ CollisionObjectBullet(p_type) {}
~RigidCollisionObjectBullet();
_FORCE_INLINE_ const Vector<ShapeWrapper> &get_shapes_wrappers() const { return shapes; }
diff --git a/modules/bullet/cone_twist_joint_bullet.cpp b/modules/bullet/cone_twist_joint_bullet.cpp
index aac51034b8..b4735fa9e9 100644
--- a/modules/bullet/cone_twist_joint_bullet.cpp
+++ b/modules/bullet/cone_twist_joint_bullet.cpp
@@ -42,7 +42,6 @@
ConeTwistJointBullet::ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &rbAFrame, const Transform &rbBFrame) :
JointBullet() {
-
Transform scaled_AFrame(rbAFrame.scaled(rbA->get_body_scale()));
scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis);
@@ -50,7 +49,6 @@ ConeTwistJointBullet::ConeTwistJointBullet(RigidBodyBullet *rbA, RigidBodyBullet
G_TO_B(scaled_AFrame, btFrameA);
if (rbB) {
-
Transform scaled_BFrame(rbBFrame.scaled(rbB->get_body_scale()));
scaled_BFrame.basis.rotref_posscale_decomposition(scaled_BFrame.basis);
diff --git a/modules/bullet/config.py b/modules/bullet/config.py
index e8ca273f61..d22f9454ed 100644
--- a/modules/bullet/config.py
+++ b/modules/bullet/config.py
@@ -4,14 +4,3 @@ def can_build(env, platform):
def configure(env):
pass
-
-
-def get_doc_classes():
- return [
- "BulletPhysicsDirectBodyState3D",
- "BulletPhysicsServer3D",
- ]
-
-
-def get_doc_path():
- return "doc_classes"
diff --git a/modules/bullet/constraint_bullet.cpp b/modules/bullet/constraint_bullet.cpp
index 469b58521e..c47a23e75f 100644
--- a/modules/bullet/constraint_bullet.cpp
+++ b/modules/bullet/constraint_bullet.cpp
@@ -37,10 +37,7 @@
@author AndreaCatania
*/
-ConstraintBullet::ConstraintBullet() :
- space(nullptr),
- constraint(nullptr),
- disabled_collisions_between_bodies(true) {}
+ConstraintBullet::ConstraintBullet() {}
void ConstraintBullet::setup(btTypedConstraint *p_constraint) {
constraint = p_constraint;
diff --git a/modules/bullet/constraint_bullet.h b/modules/bullet/constraint_bullet.h
index 1946807bad..538808be51 100644
--- a/modules/bullet/constraint_bullet.h
+++ b/modules/bullet/constraint_bullet.h
@@ -45,11 +45,10 @@ class SpaceBullet;
class btTypedConstraint;
class ConstraintBullet : public RIDBullet {
-
protected:
- SpaceBullet *space;
- btTypedConstraint *constraint;
- bool disabled_collisions_between_bodies;
+ SpaceBullet *space = nullptr;
+ btTypedConstraint *constraint = nullptr;
+ bool disabled_collisions_between_bodies = true;
public:
ConstraintBullet();
diff --git a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml b/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml
deleted file mode 100644
index 1c0181bd9c..0000000000
--- a/modules/bullet/doc_classes/BulletPhysicsDirectBodyState3D.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="BulletPhysicsDirectBodyState3D" inherits="PhysicsDirectBodyState3D" version="4.0">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <tutorials>
- </tutorials>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/modules/bullet/generic_6dof_joint_bullet.cpp b/modules/bullet/generic_6dof_joint_bullet.cpp
index 638944df76..56a66dba45 100644
--- a/modules/bullet/generic_6dof_joint_bullet.cpp
+++ b/modules/bullet/generic_6dof_joint_bullet.cpp
@@ -42,7 +42,6 @@
Generic6DOFJointBullet::Generic6DOFJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB) :
JointBullet() {
-
for (int i = 0; i < 3; i++) {
for (int j = 0; j < PhysicsServer3D::G6DOF_JOINT_FLAG_MAX; j++) {
flags[i][j] = false;
diff --git a/modules/bullet/godot_collision_configuration.cpp b/modules/bullet/godot_collision_configuration.cpp
index 8e29845a36..ec7a1dbd9a 100644
--- a/modules/bullet/godot_collision_configuration.cpp
+++ b/modules/bullet/godot_collision_configuration.cpp
@@ -41,7 +41,6 @@
GodotCollisionConfiguration::GodotCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo) :
btDefaultCollisionConfiguration(constructionInfo) {
-
void *mem = nullptr;
mem = btAlignedAlloc(sizeof(GodotRayWorldAlgorithm::CreateFunc), 16);
@@ -60,44 +59,33 @@ GodotCollisionConfiguration::~GodotCollisionConfiguration() {
}
btCollisionAlgorithmCreateFunc *GodotCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1) {
-
if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
-
// This collision is not supported
return m_emptyCreateFunc;
} else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) {
-
return m_rayWorldCF;
} else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
-
return m_swappedRayWorldCF;
} else {
-
return btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0, proxyType1);
}
}
btCollisionAlgorithmCreateFunc *GodotCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1) {
-
if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
-
// This collision is not supported
return m_emptyCreateFunc;
} else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) {
-
return m_rayWorldCF;
} else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
-
return m_swappedRayWorldCF;
} else {
-
return btDefaultCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(proxyType0, proxyType1);
}
}
GodotSoftCollisionConfiguration::GodotSoftCollisionConfiguration(const btDiscreteDynamicsWorld *world, const btDefaultCollisionConstructionInfo &constructionInfo) :
btSoftBodyRigidBodyCollisionConfiguration(constructionInfo) {
-
void *mem = nullptr;
mem = btAlignedAlloc(sizeof(GodotRayWorldAlgorithm::CreateFunc), 16);
@@ -116,37 +104,27 @@ GodotSoftCollisionConfiguration::~GodotSoftCollisionConfiguration() {
}
btCollisionAlgorithmCreateFunc *GodotSoftCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1) {
-
if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
-
// This collision is not supported
return m_emptyCreateFunc;
} else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) {
-
return m_rayWorldCF;
} else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
-
return m_swappedRayWorldCF;
} else {
-
return btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0, proxyType1);
}
}
btCollisionAlgorithmCreateFunc *GodotSoftCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1) {
-
if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0 && CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
-
// This collision is not supported
return m_emptyCreateFunc;
} else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType0) {
-
return m_rayWorldCF;
} else if (CUSTOM_CONVEX_SHAPE_TYPE == proxyType1) {
-
return m_swappedRayWorldCF;
} else {
-
return btSoftBodyRigidBodyCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(proxyType0, proxyType1);
}
}
diff --git a/modules/bullet/godot_motion_state.h b/modules/bullet/godot_motion_state.h
index e2c1b10e94..90d1614a77 100644
--- a/modules/bullet/godot_motion_state.h
+++ b/modules/bullet/godot_motion_state.h
@@ -46,7 +46,6 @@ class RigidBodyBullet;
/// DOC:
/// http://www.bulletphysics.org/mediawiki-1.5.8/index.php/MotionStates#What.27s_a_MotionState.3F
class GodotMotionState : public btMotionState {
-
/// This data is used to store the new world position for kinematic body
btTransform bodyKinematicWorldTransf;
/// This data is used to store last world position
diff --git a/modules/bullet/godot_ray_world_algorithm.cpp b/modules/bullet/godot_ray_world_algorithm.cpp
index 2ef277cf5b..a84f3511ba 100644
--- a/modules/bullet/godot_ray_world_algorithm.cpp
+++ b/modules/bullet/godot_ray_world_algorithm.cpp
@@ -52,7 +52,6 @@ GodotRayWorldAlgorithm::GodotRayWorldAlgorithm(const btDiscreteDynamicsWorld *wo
btActivatingCollisionAlgorithm(ci, body0Wrap, body1Wrap),
m_world(world),
m_manifoldPtr(mf),
- m_ownManifold(false),
m_isSwapped(isSwapped) {}
GodotRayWorldAlgorithm::~GodotRayWorldAlgorithm() {
@@ -62,7 +61,6 @@ GodotRayWorldAlgorithm::~GodotRayWorldAlgorithm() {
}
void GodotRayWorldAlgorithm::processCollision(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap, const btDispatcherInfo &dispatchInfo, btManifoldResult *resultOut) {
-
if (!m_manifoldPtr) {
if (m_isSwapped) {
m_manifoldPtr = m_dispatcher->getNewManifold(body1Wrap->getCollisionObject(), body0Wrap->getCollisionObject());
@@ -80,13 +78,11 @@ void GodotRayWorldAlgorithm::processCollision(const btCollisionObjectWrapper *bo
const btCollisionObjectWrapper *other_co_wrapper;
if (m_isSwapped) {
-
ray_shape = static_cast<const btRayShape *>(body1Wrap->getCollisionShape());
ray_transform = body1Wrap->getWorldTransform();
other_co_wrapper = body0Wrap;
} else {
-
ray_shape = static_cast<const btRayShape *>(body0Wrap->getCollisionShape());
ray_transform = body0Wrap->getWorldTransform();
@@ -100,15 +96,15 @@ void GodotRayWorldAlgorithm::processCollision(const btCollisionObjectWrapper *bo
m_world->rayTestSingleInternal(ray_transform, to, other_co_wrapper, btResult);
if (btResult.hasHit()) {
-
btScalar depth(ray_shape->getScaledLength() * (btResult.m_closestHitFraction - 1));
- if (depth > -RAY_PENETRATION_DEPTH_EPSILON)
+ if (depth > -RAY_PENETRATION_DEPTH_EPSILON) {
depth = 0.0;
+ }
- if (ray_shape->getSlipsOnSlope())
+ if (ray_shape->getSlipsOnSlope()) {
resultOut->addContactPoint(btResult.m_hitNormalWorld, btResult.m_hitPointWorld, depth);
- else {
+ } else {
resultOut->addContactPoint((ray_transform.getOrigin() - to.getOrigin()).normalize(), btResult.m_hitPointWorld, depth);
}
}
diff --git a/modules/bullet/godot_ray_world_algorithm.h b/modules/bullet/godot_ray_world_algorithm.h
index 2cdea6c133..9786732d40 100644
--- a/modules/bullet/godot_ray_world_algorithm.h
+++ b/modules/bullet/godot_ray_world_algorithm.h
@@ -42,10 +42,9 @@
class btDiscreteDynamicsWorld;
class GodotRayWorldAlgorithm : public btActivatingCollisionAlgorithm {
-
const btDiscreteDynamicsWorld *m_world;
btPersistentManifold *m_manifoldPtr;
- bool m_ownManifold;
+ bool m_ownManifold = false;
bool m_isSwapped;
public:
@@ -57,11 +56,11 @@ public:
virtual void getAllContactManifolds(btManifoldArray &manifoldArray) {
///should we use m_ownManifold to avoid adding duplicates?
- if (m_manifoldPtr && m_ownManifold)
+ if (m_manifoldPtr && m_ownManifold) {
manifoldArray.push_back(m_manifoldPtr);
+ }
}
struct CreateFunc : public btCollisionAlgorithmCreateFunc {
-
const btDiscreteDynamicsWorld *m_world;
CreateFunc(const btDiscreteDynamicsWorld *world);
@@ -72,7 +71,6 @@ public:
};
struct SwappedCreateFunc : public btCollisionAlgorithmCreateFunc {
-
const btDiscreteDynamicsWorld *m_world;
SwappedCreateFunc(const btDiscreteDynamicsWorld *world);
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index ad20a7e451..f82648d6ff 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -62,11 +62,13 @@ bool GodotClosestRayResultCallback::needsCollision(btBroadphaseProxy *proxy0) co
CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) {
- if (!collide_with_areas)
+ if (!collide_with_areas) {
return false;
+ }
} else {
- if (!collide_with_bodies)
+ if (!collide_with_bodies) {
return false;
+ }
}
if (m_pickRay && !gObj->is_ray_pickable()) {
@@ -84,8 +86,9 @@ bool GodotClosestRayResultCallback::needsCollision(btBroadphaseProxy *proxy0) co
}
bool GodotAllConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
- if (count >= m_resultMax)
+ if (count >= m_resultMax) {
return false;
+ }
const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
if (needs) {
@@ -102,8 +105,9 @@ bool GodotAllConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0) con
}
btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) {
- if (count >= m_resultMax)
+ if (count >= m_resultMax) {
return 1; // not used by bullet
+ }
CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(convexResult.m_hitCollisionObject->getUserPointer());
@@ -126,16 +130,18 @@ bool GodotKinClosestConvexResultCallback::needsCollision(btBroadphaseProxy *prox
if (gObj == m_self_object) {
return false;
} else {
-
// A kinematic body can't be stopped by a rigid body since the mass of kinematic body is infinite
- if (m_infinite_inertia && !btObj->isStaticOrKinematicObject())
+ if (m_infinite_inertia && !btObj->isStaticOrKinematicObject()) {
return false;
+ }
- if (gObj->getType() == CollisionObjectBullet::TYPE_AREA)
+ if (gObj->getType() == CollisionObjectBullet::TYPE_AREA) {
return false;
+ }
- if (m_self_object->has_collision_exception(gObj) || gObj->has_collision_exception(m_self_object))
+ if (m_self_object->has_collision_exception(gObj) || gObj->has_collision_exception(m_self_object)) {
return false;
+ }
}
return true;
} else {
@@ -150,11 +156,13 @@ bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0)
CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) {
- if (!collide_with_areas)
+ if (!collide_with_areas) {
return false;
+ }
} else {
- if (!collide_with_bodies)
+ if (!collide_with_bodies) {
return false;
+ }
}
if (m_exclude->has(gObj->get_self())) {
@@ -167,16 +175,18 @@ bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0)
}
btScalar GodotClosestConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) {
- if (convexResult.m_localShapeInfo)
+ if (convexResult.m_localShapeInfo) {
m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
- else
+ } else {
m_shapeId = 0;
+ }
return btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
}
bool GodotAllContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
- if (m_count >= m_resultMax)
+ if (m_count >= m_resultMax) {
return false;
+ }
const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
if (needs) {
@@ -184,11 +194,13 @@ bool GodotAllContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) co
CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) {
- if (!collide_with_areas)
+ if (!collide_with_areas) {
return false;
+ }
} else {
- if (!collide_with_bodies)
+ if (!collide_with_bodies) {
return false;
+ }
}
if (m_exclude->has(gObj->get_self())) {
@@ -201,12 +213,11 @@ bool GodotAllContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) co
}
btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {
-
- if (m_count >= m_resultMax)
+ if (m_count >= m_resultMax) {
return cp.getDistance();
+ }
if (cp.getDistance() <= 0) {
-
PhysicsDirectSpaceState3D::ShapeResult &result = m_results[m_count];
// Penetrated
@@ -229,8 +240,9 @@ btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, con
}
bool GodotContactPairContactResultCallback::needsCollision(btBroadphaseProxy *proxy0) const {
- if (m_count >= m_resultMax)
+ if (m_count >= m_resultMax) {
return false;
+ }
const bool needs = GodotFilterCallback::test_collision_filters(m_collisionFilterGroup, m_collisionFilterMask, proxy0->m_collisionFilterGroup, proxy0->m_collisionFilterMask);
if (needs) {
@@ -238,11 +250,13 @@ bool GodotContactPairContactResultCallback::needsCollision(btBroadphaseProxy *pr
CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) {
- if (!collide_with_areas)
+ if (!collide_with_areas) {
return false;
+ }
} else {
- if (!collide_with_bodies)
+ if (!collide_with_bodies) {
return false;
+ }
}
if (m_exclude->has(gObj->get_self())) {
@@ -255,8 +269,9 @@ bool GodotContactPairContactResultCallback::needsCollision(btBroadphaseProxy *pr
}
btScalar GodotContactPairContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {
- if (m_count >= m_resultMax)
+ if (m_count >= m_resultMax) {
return 1; // not used by bullet
+ }
if (m_self_object == colObj0Wrap->getCollisionObject()) {
B_TO_G(cp.m_localPointA, m_results[m_count * 2 + 0]); // Local contact
@@ -278,11 +293,13 @@ bool GodotRestInfoContactResultCallback::needsCollision(btBroadphaseProxy *proxy
CollisionObjectBullet *gObj = static_cast<CollisionObjectBullet *>(btObj->getUserPointer());
if (CollisionObjectBullet::TYPE_AREA == gObj->getType()) {
- if (!collide_with_areas)
+ if (!collide_with_areas) {
return false;
+ }
} else {
- if (!collide_with_bodies)
+ if (!collide_with_bodies) {
return false;
+ }
}
if (m_exclude->has(gObj->get_self())) {
@@ -295,7 +312,6 @@ bool GodotRestInfoContactResultCallback::needsCollision(btBroadphaseProxy *proxy
}
btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp, const btCollisionObjectWrapper *colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper *colObj1Wrap, int partId1, int index1) {
-
if (cp.getDistance() <= m_min_distance) {
m_min_distance = cp.getDistance();
@@ -325,7 +341,6 @@ btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp
}
void GodotDeepPenetrationContactResultCallback::addContactPoint(const btVector3 &normalOnBInWorld, const btVector3 &pointInWorldOnB, btScalar depth) {
-
if (m_penetration_distance > depth) { // Has penetration?
const bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h
index 7e74a2b22e..1325542973 100644
--- a/modules/bullet/godot_result_callbacks.h
+++ b/modules/bullet/godot_result_callbacks.h
@@ -56,8 +56,8 @@ struct GodotFilterCallback : public btOverlapFilterCallback {
/// It performs an additional check allow exclusions.
struct GodotClosestRayResultCallback : public btCollisionWorld::ClosestRayResultCallback {
const Set<RID> *m_exclude;
- bool m_pickRay;
- int m_shapeId;
+ bool m_pickRay = false;
+ int m_shapeId = 0;
bool collide_with_bodies;
bool collide_with_areas;
@@ -66,18 +66,17 @@ public:
GodotClosestRayResultCallback(const btVector3 &rayFromWorld, const btVector3 &rayToWorld, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) :
btCollisionWorld::ClosestRayResultCallback(rayFromWorld, rayToWorld),
m_exclude(p_exclude),
- m_pickRay(false),
- m_shapeId(0),
collide_with_bodies(p_collide_with_bodies),
collide_with_areas(p_collide_with_areas) {}
virtual bool needsCollision(btBroadphaseProxy *proxy0) const;
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace) {
- if (rayResult.m_localShapeInfo)
+ if (rayResult.m_localShapeInfo) {
m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
- else
+ } else {
m_shapeId = 0;
+ }
return btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
}
};
@@ -88,13 +87,12 @@ public:
PhysicsDirectSpaceState3D::ShapeResult *m_results;
int m_resultMax;
const Set<RID> *m_exclude;
- int count;
+ int count = 0;
GodotAllConvexResultCallback(PhysicsDirectSpaceState3D::ShapeResult *p_results, int p_resultMax, const Set<RID> *p_exclude) :
m_results(p_results),
m_resultMax(p_resultMax),
- m_exclude(p_exclude),
- count(0) {}
+ m_exclude(p_exclude) {}
virtual bool needsCollision(btBroadphaseProxy *proxy0) const;
@@ -117,7 +115,7 @@ public:
struct GodotClosestConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback {
public:
const Set<RID> *m_exclude;
- int m_shapeId;
+ int m_shapeId = 0;
bool collide_with_bodies;
bool collide_with_areas;
@@ -125,7 +123,6 @@ public:
GodotClosestConvexResultCallback(const btVector3 &convexFromWorld, const btVector3 &convexToWorld, const Set<RID> *p_exclude, bool p_collide_with_bodies, bool p_collide_with_areas) :
btCollisionWorld::ClosestConvexResultCallback(convexFromWorld, convexToWorld),
m_exclude(p_exclude),
- m_shapeId(0),
collide_with_bodies(p_collide_with_bodies),
collide_with_areas(p_collide_with_areas) {}
@@ -140,7 +137,7 @@ public:
PhysicsDirectSpaceState3D::ShapeResult *m_results;
int m_resultMax;
const Set<RID> *m_exclude;
- int m_count;
+ int m_count = 0;
bool collide_with_bodies;
bool collide_with_areas;
@@ -150,7 +147,6 @@ public:
m_results(p_results),
m_resultMax(p_resultMax),
m_exclude(p_exclude),
- m_count(0),
collide_with_bodies(p_collide_with_bodies),
collide_with_areas(p_collide_with_areas) {}
@@ -166,7 +162,7 @@ public:
Vector3 *m_results;
int m_resultMax;
const Set<RID> *m_exclude;
- int m_count;
+ int m_count = 0;
bool collide_with_bodies;
bool collide_with_areas;
@@ -176,7 +172,6 @@ public:
m_results(p_results),
m_resultMax(p_resultMax),
m_exclude(p_exclude),
- m_count(0),
collide_with_bodies(p_collide_with_bodies),
collide_with_areas(p_collide_with_areas) {}
@@ -190,8 +185,8 @@ public:
const btCollisionObject *m_self_object;
PhysicsDirectSpaceState3D::ShapeRestInfo *m_result;
const Set<RID> *m_exclude;
- bool m_collided;
- real_t m_min_distance;
+ bool m_collided = false;
+ real_t m_min_distance = 0;
const btCollisionObject *m_rest_info_collision_object;
btVector3 m_rest_info_bt_point;
bool collide_with_bodies;
@@ -201,8 +196,6 @@ public:
m_self_object(p_self_object),
m_result(p_result),
m_exclude(p_exclude),
- m_collided(false),
- m_min_distance(0),
collide_with_bodies(p_collide_with_bodies),
collide_with_areas(p_collide_with_areas) {}
@@ -214,13 +207,11 @@ public:
struct GodotDeepPenetrationContactResultCallback : public btManifoldResult {
btVector3 m_pointNormalWorld;
btVector3 m_pointWorld;
- btScalar m_penetration_distance;
- int m_other_compound_shape_index;
+ btScalar m_penetration_distance = 0;
+ int m_other_compound_shape_index = 0;
GodotDeepPenetrationContactResultCallback(const btCollisionObjectWrapper *body0Wrap, const btCollisionObjectWrapper *body1Wrap) :
- btManifoldResult(body0Wrap, body1Wrap),
- m_penetration_distance(0),
- m_other_compound_shape_index(0) {}
+ btManifoldResult(body0Wrap, body1Wrap) {}
void reset() {
m_penetration_distance = 0;
diff --git a/modules/bullet/hinge_joint_bullet.cpp b/modules/bullet/hinge_joint_bullet.cpp
index 4bea9f87c0..2338277565 100644
--- a/modules/bullet/hinge_joint_bullet.cpp
+++ b/modules/bullet/hinge_joint_bullet.cpp
@@ -42,7 +42,6 @@
HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameA, const Transform &frameB) :
JointBullet() {
-
Transform scaled_AFrame(frameA.scaled(rbA->get_body_scale()));
scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis);
@@ -50,7 +49,6 @@ HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, c
G_TO_B(scaled_AFrame, btFrameA);
if (rbB) {
-
Transform scaled_BFrame(frameB.scaled(rbB->get_body_scale()));
scaled_BFrame.basis.rotref_posscale_decomposition(scaled_BFrame.basis);
@@ -59,7 +57,6 @@ HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, c
hingeConstraint = bulletnew(btHingeConstraint(*rbA->get_bt_rigid_body(), *rbB->get_bt_rigid_body(), btFrameA, btFrameB));
} else {
-
hingeConstraint = bulletnew(btHingeConstraint(*rbA->get_bt_rigid_body(), btFrameA));
}
@@ -68,7 +65,6 @@ HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, c
HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB, const Vector3 &axisInA, const Vector3 &axisInB) :
JointBullet() {
-
btVector3 btPivotA;
btVector3 btAxisA;
G_TO_B(pivotInA * rbA->get_body_scale(), btPivotA);
@@ -82,7 +78,6 @@ HingeJointBullet::HingeJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, c
hingeConstraint = bulletnew(btHingeConstraint(*rbA->get_bt_rigid_body(), *rbB->get_bt_rigid_body(), btPivotA, btPivotB, btAxisA, btAxisB));
} else {
-
hingeConstraint = bulletnew(btHingeConstraint(*rbA->get_bt_rigid_body(), btPivotA, btAxisA));
}
@@ -162,7 +157,8 @@ void HingeJointBullet::set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_v
case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR:
hingeConstraint->enableMotor(p_value);
break;
- case PhysicsServer3D::HINGE_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::HINGE_JOINT_FLAG_MAX:
+ break; // Can't happen, but silences warning
}
}
diff --git a/modules/bullet/joint_bullet.h b/modules/bullet/joint_bullet.h
index 9cb8aab276..c70cea817e 100644
--- a/modules/bullet/joint_bullet.h
+++ b/modules/bullet/joint_bullet.h
@@ -42,7 +42,6 @@ class RigidBodyBullet;
class btTypedConstraint;
class JointBullet : public ConstraintBullet {
-
public:
JointBullet();
virtual ~JointBullet();
diff --git a/modules/bullet/pin_joint_bullet.cpp b/modules/bullet/pin_joint_bullet.cpp
index 68b40d7405..1cfbc65c78 100644
--- a/modules/bullet/pin_joint_bullet.cpp
+++ b/modules/bullet/pin_joint_bullet.cpp
@@ -42,7 +42,6 @@
PinJointBullet::PinJointBullet(RigidBodyBullet *p_body_a, const Vector3 &p_pos_a, RigidBodyBullet *p_body_b, const Vector3 &p_pos_b) :
JointBullet() {
if (p_body_b) {
-
btVector3 btPivotA;
btVector3 btPivotB;
G_TO_B(p_pos_a * p_body_a->get_body_scale(), btPivotA);
diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp
index a4f9affa95..9aac7ba9e4 100644
--- a/modules/bullet/rigid_body_bullet.cpp
+++ b/modules/bullet/rigid_body_bullet.cpp
@@ -256,26 +256,7 @@ void RigidBodyBullet::KinematicUtilities::just_delete_shapes(int new_size) {
}
RigidBodyBullet::RigidBodyBullet() :
- RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY),
- kinematic_utilities(nullptr),
- locked_axis(0),
- mass(1),
- gravity_scale(1),
- linearDamp(0),
- angularDamp(0),
- can_sleep(true),
- omit_forces_integration(false),
- can_integrate_forces(false),
- maxCollisionsDetection(0),
- collisionsCount(0),
- prev_collision_count(0),
- maxAreasWhereIam(10),
- areaWhereIamCount(0),
- countGravityPointSpaces(0),
- isScratchedSpaceOverrideModificator(false),
- previousActiveState(true),
- force_integration_callback(nullptr) {
-
+ RigidCollisionObjectBullet(CollisionObjectBullet::TYPE_RIGID_BODY) {
godotMotionState = bulletnew(GodotMotionState(this));
// Initial properties
@@ -302,8 +283,9 @@ RigidBodyBullet::RigidBodyBullet() :
RigidBodyBullet::~RigidBodyBullet() {
bulletdelete(godotMotionState);
- if (force_integration_callback)
+ if (force_integration_callback) {
memdelete(force_integration_callback);
+ }
destroy_kinematic_utilities();
}
@@ -328,8 +310,9 @@ void RigidBodyBullet::main_shape_changed() {
void RigidBodyBullet::reload_body() {
if (space) {
space->remove_rigid_body(this);
- if (get_main_shape())
+ if (get_main_shape()) {
space->add_rigid_body(this);
+ }
}
}
@@ -355,9 +338,9 @@ void RigidBodyBullet::set_space(SpaceBullet *p_space) {
void RigidBodyBullet::dispatch_callbacks() {
/// The check isFirstTransformChanged is necessary in order to call integrated forces only when the first transform is sent
if ((btBody->isKinematicObject() || btBody->isActive() || previousActiveState != btBody->isActive()) && force_integration_callback && can_integrate_forces) {
-
- if (omit_forces_integration)
+ if (omit_forces_integration) {
btBody->clearForces();
+ }
BulletPhysicsDirectBodyState3D *bodyDirect = BulletPhysicsDirectBodyState3D::get_singleton(this);
@@ -389,7 +372,6 @@ void RigidBodyBullet::dispatch_callbacks() {
}
void RigidBodyBullet::set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata) {
-
if (force_integration_callback) {
memdelete(force_integration_callback);
force_integration_callback = nullptr;
@@ -416,7 +398,6 @@ void RigidBodyBullet::on_collision_filters_change() {
}
void RigidBodyBullet::on_collision_checker_start() {
-
prev_collision_count = collisionsCount;
collisionsCount = 0;
@@ -432,7 +413,6 @@ void RigidBodyBullet::on_collision_checker_end() {
}
bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const Vector3 &p_hitWorldLocation, const Vector3 &p_hitLocalLocation, const Vector3 &p_hitNormal, const float &p_appliedImpulse, int p_other_shape_index, int p_local_shape_index) {
-
if (collisionsCount >= maxCollisionsDetection) {
return false;
}
@@ -454,8 +434,9 @@ bool RigidBodyBullet::add_collision_object(RigidBodyBullet *p_otherObject, const
bool RigidBodyBullet::was_colliding(RigidBodyBullet *p_other_object) {
for (int i = prev_collision_count - 1; 0 <= i; --i) {
- if ((*prev_collision_traces)[i] == p_other_object)
+ if ((*prev_collision_traces)[i] == p_other_object) {
return true;
+ }
}
return false;
}
@@ -464,11 +445,6 @@ void RigidBodyBullet::assert_no_constraints() {
if (btBody->getNumConstraintRefs()) {
WARN_PRINT("A body with a joints is destroyed. Please check the implementation in order to destroy the joint before the body.");
}
- /*for(int i = btBody->getNumConstraintRefs()-1; 0<=i; --i){
- btTypedConstraint* btConst = btBody->getConstraintRef(i);
- JointBullet* joint = static_cast<JointBullet*>( btConst->getUserConstraintPtr() );
- space->removeConstraint(joint);
- }*/
}
void RigidBodyBullet::set_activation_state(bool p_active) {
@@ -503,15 +479,18 @@ void RigidBodyBullet::set_param(PhysicsServer3D::BodyParameter p_param, real_t p
}
case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP:
linearDamp = p_value;
- btBody->setDamping(linearDamp, angularDamp);
+ // Mark for updating total linear damping.
+ scratch_space_override_modificator();
break;
case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP:
angularDamp = p_value;
- btBody->setDamping(linearDamp, angularDamp);
+ // Mark for updating total angular damping.
+ scratch_space_override_modificator();
break;
case PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE:
gravity_scale = p_value;
- /// The Bullet gravity will be is set by reload_space_override_modificator
+ // The Bullet gravity will be is set by reload_space_override_modificator.
+ // Mark for updating total gravity scale.
scratch_space_override_modificator();
break;
default:
@@ -575,12 +554,12 @@ void RigidBodyBullet::set_mode(PhysicsServer3D::BodyMode p_mode) {
btBody->setAngularVelocity(btVector3(0, 0, 0));
btBody->setLinearVelocity(btVector3(0, 0, 0));
}
+
PhysicsServer3D::BodyMode RigidBodyBullet::get_mode() const {
return mode;
}
void RigidBodyBullet::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) {
-
switch (p_state) {
case PhysicsServer3D::BODY_STATE_TRANSFORM:
set_transform(p_variant);
@@ -627,8 +606,9 @@ Variant RigidBodyBullet::get_state(PhysicsServer3D::BodyState p_state) const {
void RigidBodyBullet::apply_central_impulse(const Vector3 &p_impulse) {
btVector3 btImpu;
G_TO_B(p_impulse, btImpu);
- if (Vector3() != p_impulse)
+ if (Vector3() != p_impulse) {
btBody->activate();
+ }
btBody->applyCentralImpulse(btImpu);
}
@@ -637,16 +617,18 @@ void RigidBodyBullet::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impul
btVector3 btPos;
G_TO_B(p_impulse, btImpu);
G_TO_B(p_pos, btPos);
- if (Vector3() != p_impulse)
+ if (Vector3() != p_impulse) {
btBody->activate();
+ }
btBody->applyImpulse(btImpu, btPos);
}
void RigidBodyBullet::apply_torque_impulse(const Vector3 &p_impulse) {
btVector3 btImp;
G_TO_B(p_impulse, btImp);
- if (Vector3() != p_impulse)
+ if (Vector3() != p_impulse) {
btBody->activate();
+ }
btBody->applyTorqueImpulse(btImp);
}
@@ -655,32 +637,36 @@ void RigidBodyBullet::apply_force(const Vector3 &p_force, const Vector3 &p_pos)
btVector3 btPos;
G_TO_B(p_force, btForce);
G_TO_B(p_pos, btPos);
- if (Vector3() != p_force)
+ if (Vector3() != p_force) {
btBody->activate();
+ }
btBody->applyForce(btForce, btPos);
}
void RigidBodyBullet::apply_central_force(const Vector3 &p_force) {
btVector3 btForce;
G_TO_B(p_force, btForce);
- if (Vector3() != p_force)
+ if (Vector3() != p_force) {
btBody->activate();
+ }
btBody->applyCentralForce(btForce);
}
void RigidBodyBullet::apply_torque(const Vector3 &p_torque) {
btVector3 btTorq;
G_TO_B(p_torque, btTorq);
- if (Vector3() != p_torque)
+ if (Vector3() != p_torque) {
btBody->activate();
+ }
btBody->applyTorque(btTorq);
}
void RigidBodyBullet::set_applied_force(const Vector3 &p_force) {
btVector3 btVec = btBody->getTotalTorque();
- if (Vector3() != p_force)
+ if (Vector3() != p_force) {
btBody->activate();
+ }
btBody->clearForces();
btBody->applyTorque(btVec);
@@ -698,8 +684,9 @@ Vector3 RigidBodyBullet::get_applied_force() const {
void RigidBodyBullet::set_applied_torque(const Vector3 &p_torque) {
btVector3 btVec = btBody->getTotalForce();
- if (Vector3() != p_torque)
+ if (Vector3() != p_torque) {
btBody->activate();
+ }
btBody->clearForces();
btBody->applyCentralForce(btVec);
@@ -729,7 +716,6 @@ bool RigidBodyBullet::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const {
}
void RigidBodyBullet::reload_axis_lock() {
-
btBody->setLinearFactor(btVector3(float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_X)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Y)), float(!is_axis_locked(PhysicsServer3D::BODY_AXIS_LINEAR_Z))));
if (PhysicsServer3D::BODY_MODE_CHARACTER == mode) {
/// When character angular is always locked
@@ -768,8 +754,9 @@ bool RigidBodyBullet::is_continuous_collision_detection_enabled() const {
void RigidBodyBullet::set_linear_velocity(const Vector3 &p_velocity) {
btVector3 btVec;
G_TO_B(p_velocity, btVec);
- if (Vector3() != p_velocity)
+ if (Vector3() != p_velocity) {
btBody->activate();
+ }
btBody->setLinearVelocity(btVec);
}
@@ -782,8 +769,9 @@ Vector3 RigidBodyBullet::get_linear_velocity() const {
void RigidBodyBullet::set_angular_velocity(const Vector3 &p_velocity) {
btVector3 btVec;
G_TO_B(p_velocity, btVec);
- if (Vector3() != p_velocity)
+ if (Vector3() != p_velocity) {
btBody->activate();
+ }
btBody->setAngularVelocity(btVec);
}
@@ -795,8 +783,9 @@ Vector3 RigidBodyBullet::get_angular_velocity() const {
void RigidBodyBullet::set_transform__bullet(const btTransform &p_global_transform) {
if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) {
- if (space && space->get_delta_time() != 0)
+ if (space && space->get_delta_time() != 0) {
btBody->setLinearVelocity((p_global_transform.getOrigin() - btBody->getWorldTransform().getOrigin()) / space->get_delta_time());
+ }
// The kinematic use MotionState class
godotMotionState->moveBody(p_global_transform);
} else {
@@ -808,10 +797,8 @@ void RigidBodyBullet::set_transform__bullet(const btTransform &p_global_transfor
const btTransform &RigidBodyBullet::get_transform__bullet() const {
if (is_static()) {
-
return RigidCollisionObjectBullet::get_transform__bullet();
} else {
-
return godotMotionState->getCurrentWorldTransform();
}
}
@@ -827,8 +814,9 @@ void RigidBodyBullet::reload_shapes() {
// shapes incorrectly do not set the vector in calculateLocalIntertia.
// Arbitrary zero is preferable to undefined behaviour.
btVector3 inertia(0, 0, 0);
- if (EMPTY_SHAPE_PROXYTYPE != mainShape->getShapeType()) // Necessary to avoid assertion of the empty shape
+ if (EMPTY_SHAPE_PROXYTYPE != mainShape->getShapeType()) { // Necessary to avoid assertion of the empty shape
mainShape->calculateLocalInertia(mass, inertia);
+ }
btBody->setMassProps(mass, inertia);
}
btBody->updateInertiaTensor();
@@ -846,7 +834,6 @@ void RigidBodyBullet::on_enter_area(AreaBullet *p_area) {
return;
}
for (int i = 0; i < areaWhereIamCount; ++i) {
-
if (nullptr == areasWhereIam[i]) {
// This area has the highest priority
areasWhereIam.write[i] = p_area;
@@ -902,22 +889,21 @@ void RigidBodyBullet::on_exit_area(AreaBullet *p_area) {
}
void RigidBodyBullet::reload_space_override_modificator() {
-
// Make sure that kinematic bodies have their total gravity calculated
- if (!is_active() && PhysicsServer3D::BODY_MODE_KINEMATIC != mode)
+ if (!is_active() && PhysicsServer3D::BODY_MODE_KINEMATIC != mode) {
return;
+ }
- Vector3 newGravity(space->get_gravity_direction() * space->get_gravity_magnitude());
- real_t newLinearDamp(linearDamp);
- real_t newAngularDamp(angularDamp);
+ Vector3 newGravity(0.0, 0.0, 0.0);
+ real_t newLinearDamp = MAX(0.0, linearDamp);
+ real_t newAngularDamp = MAX(0.0, angularDamp);
AreaBullet *currentArea;
// Variable used to calculate new gravity for gravity point areas, it is pointed by currentGravity pointer
Vector3 support_gravity(0, 0, 0);
- int countCombined(0);
- for (int i = areaWhereIamCount - 1; 0 <= i; --i) {
-
+ bool stopped = false;
+ for (int i = areaWhereIamCount - 1; (0 <= i) && !stopped; --i) {
currentArea = areasWhereIam[i];
if (!currentArea || PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED == currentArea->get_spOv_mode()) {
@@ -926,7 +912,6 @@ void RigidBodyBullet::reload_space_override_modificator() {
/// Here is calculated the gravity
if (currentArea->is_spOv_gravityPoint()) {
-
/// It calculates the direction of new gravity
support_gravity = currentArea->get_transform().xform(currentArea->get_spOv_gravityVec()) - get_transform().get_origin();
real_t distanceMag = support_gravity.length();
@@ -965,7 +950,6 @@ void RigidBodyBullet::reload_space_override_modificator() {
newGravity += support_gravity;
newLinearDamp += currentArea->get_spOv_linearDamp();
newAngularDamp += currentArea->get_spOv_angularDamp();
- ++countCombined;
break;
case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE:
/// This area adds its gravity/damp values to whatever has been calculated
@@ -974,32 +958,31 @@ void RigidBodyBullet::reload_space_override_modificator() {
newGravity += support_gravity;
newLinearDamp += currentArea->get_spOv_linearDamp();
newAngularDamp += currentArea->get_spOv_angularDamp();
- ++countCombined;
- goto endAreasCycle;
+ stopped = true;
+ break;
case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE:
/// This area replaces any gravity/damp, even the default one, and
/// stops taking into account the rest of the areas.
newGravity = support_gravity;
newLinearDamp = currentArea->get_spOv_linearDamp();
newAngularDamp = currentArea->get_spOv_angularDamp();
- countCombined = 1;
- goto endAreasCycle;
+ stopped = true;
+ break;
case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE:
/// This area replaces any gravity/damp calculated so far, but keeps
/// calculating the rest of the areas, down to the default one.
newGravity = support_gravity;
newLinearDamp = currentArea->get_spOv_linearDamp();
newAngularDamp = currentArea->get_spOv_angularDamp();
- countCombined = 1;
break;
}
}
-endAreasCycle:
- if (1 < countCombined) {
- newGravity /= countCombined;
- newLinearDamp /= countCombined;
- newAngularDamp /= countCombined;
+ // Add default gravity and damping from space.
+ if (!stopped) {
+ newGravity += space->get_gravity_direction() * space->get_gravity_magnitude();
+ newLinearDamp += space->get_linear_damp();
+ newAngularDamp += space->get_angular_damp();
}
btVector3 newBtGravity;
@@ -1022,7 +1005,6 @@ void RigidBodyBullet::notify_transform_changed() {
}
void RigidBodyBullet::_internal_set_mass(real_t p_mass) {
-
btVector3 localInertia(0, 0, 0);
int clearedCurrentFlags = btBody->getCollisionFlags();
@@ -1031,19 +1013,18 @@ void RigidBodyBullet::_internal_set_mass(real_t p_mass) {
// Rigidbody is dynamic if and only if mass is non Zero, otherwise static
const bool isDynamic = p_mass != 0.f;
if (isDynamic) {
-
- if (PhysicsServer3D::BODY_MODE_RIGID != mode && PhysicsServer3D::BODY_MODE_CHARACTER != mode)
+ if (PhysicsServer3D::BODY_MODE_RIGID != mode && PhysicsServer3D::BODY_MODE_CHARACTER != mode) {
return;
+ }
m_isStatic = false;
- if (mainShape)
+ if (mainShape) {
mainShape->calculateLocalInertia(p_mass, localInertia);
+ }
if (PhysicsServer3D::BODY_MODE_RIGID == mode) {
-
btBody->setCollisionFlags(clearedCurrentFlags); // Just set the flags without Kin and Static
} else {
-
btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_CHARACTER_OBJECT);
}
@@ -1053,16 +1034,14 @@ void RigidBodyBullet::_internal_set_mass(real_t p_mass) {
btBody->forceActivationState(DISABLE_DEACTIVATION); // DISABLE_DEACTIVATION 4
}
} else {
-
- if (PhysicsServer3D::BODY_MODE_STATIC != mode && PhysicsServer3D::BODY_MODE_KINEMATIC != mode)
+ if (PhysicsServer3D::BODY_MODE_STATIC != mode && PhysicsServer3D::BODY_MODE_KINEMATIC != mode) {
return;
+ }
m_isStatic = true;
if (PhysicsServer3D::BODY_MODE_STATIC == mode) {
-
btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_STATIC_OBJECT);
} else {
-
btBody->setCollisionFlags(clearedCurrentFlags | btCollisionObject::CF_KINEMATIC_OBJECT);
set_transform__bullet(btBody->getWorldTransform()); // Set current Transform using kinematic method
}
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index 420b5cc443..6d159504b8 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -142,7 +142,6 @@ public:
};
class RigidBodyBullet : public RigidCollisionObjectBullet {
-
public:
struct CollisionData {
RigidBodyBullet *otherObject;
@@ -162,11 +161,10 @@ public:
/// Used to hold shapes
struct KinematicShape {
- class btConvexShape *shape;
+ class btConvexShape *shape = nullptr;
btTransform transform;
- KinematicShape() :
- shape(nullptr) {}
+ KinematicShape() {}
bool is_active() const { return shape; }
};
@@ -190,19 +188,19 @@ private:
friend class BulletPhysicsDirectBodyState3D;
// This is required only for Kinematic movement
- KinematicUtilities *kinematic_utilities;
+ KinematicUtilities *kinematic_utilities = nullptr;
PhysicsServer3D::BodyMode mode;
GodotMotionState *godotMotionState;
btRigidBody *btBody;
- uint16_t locked_axis;
- real_t mass;
- real_t gravity_scale;
- real_t linearDamp;
- real_t angularDamp;
- bool can_sleep;
- bool omit_forces_integration;
- bool can_integrate_forces;
+ uint16_t locked_axis = 0;
+ real_t mass = 1;
+ real_t gravity_scale = 1;
+ real_t linearDamp = 0;
+ real_t angularDamp = 0;
+ bool can_sleep = true;
+ bool omit_forces_integration = false;
+ bool can_integrate_forces = false;
Vector<CollisionData> collisions;
Vector<RigidBodyBullet *> collision_traces_1;
@@ -211,21 +209,21 @@ private:
Vector<RigidBodyBullet *> *curr_collision_traces;
// these parameters are used to avoid vector resize
- int maxCollisionsDetection;
- int collisionsCount;
- int prev_collision_count;
+ int maxCollisionsDetection = 0;
+ int collisionsCount = 0;
+ int prev_collision_count = 0;
Vector<AreaBullet *> areasWhereIam;
// these parameters are used to avoid vector resize
- int maxAreasWhereIam;
- int areaWhereIamCount;
+ int maxAreasWhereIam = 10;
+ int areaWhereIamCount = 0;
// Used to know if the area is used as gravity point
- int countGravityPointSpaces;
- bool isScratchedSpaceOverrideModificator;
+ int countGravityPointSpaces = 0;
+ bool isScratchedSpaceOverrideModificator = false;
- bool previousActiveState; // Last check state
+ bool previousActiveState = true; // Last check state
- ForceIntegrationCallback *force_integration_callback;
+ ForceIntegrationCallback *force_integration_callback = nullptr;
public:
RigidBodyBullet();
@@ -250,7 +248,6 @@ public:
virtual void on_collision_checker_end();
void set_max_collisions_detection(int p_maxCollisionsDetection) {
-
ERR_FAIL_COND(0 > p_maxCollisionsDetection);
maxCollisionsDetection = p_maxCollisionsDetection;
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index 8ac26a0fdb..d53f1e7d17 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -46,8 +46,7 @@
@author AndreaCatania
*/
-ShapeBullet::ShapeBullet() :
- margin(0.04) {}
+ShapeBullet::ShapeBullet() {}
ShapeBullet::~ShapeBullet() {}
@@ -81,7 +80,9 @@ void ShapeBullet::add_owner(ShapeOwnerBullet *p_owner) {
void ShapeBullet::remove_owner(ShapeOwnerBullet *p_owner, bool p_permanentlyFromThisBody) {
Map<ShapeOwnerBullet *, int>::Element *E = owners.find(p_owner);
- if (!E) return;
+ if (!E) {
+ return;
+ }
E->get()--;
if (p_permanentlyFromThisBody || 0 >= E->get()) {
owners.erase(E);
@@ -89,7 +90,6 @@ void ShapeBullet::remove_owner(ShapeOwnerBullet *p_owner, bool p_permanentlyFrom
}
bool ShapeBullet::is_owner(ShapeOwnerBullet *p_owner) const {
-
return owners.has(p_owner);
}
@@ -151,8 +151,9 @@ btHeightfieldTerrainShape *ShapeBullet::create_shape_height_field(Vector<real_t>
btHeightfieldTerrainShape *heightfield = bulletnew(btHeightfieldTerrainShape(p_width, p_depth, heightsPtr, ignoredHeightScale, p_min_height, p_max_height, YAxis, PHY_FLOAT, flipQuadEdges));
// The shape can be created without params when you do PhysicsServer3D.shape_create(PhysicsServer3D.SHAPE_HEIGHTMAP)
- if (heightsPtr)
+ if (heightsPtr) {
heightfield->buildAccelerator(16);
+ }
return heightfield;
}
@@ -349,9 +350,10 @@ void ConvexPolygonShapeBullet::setup(const Vector<Vector3> &p_vertices) {
}
btCollisionShape *ConvexPolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) {
- if (!vertices.size())
+ if (!vertices.size()) {
// This is necessary since 0 vertices
return prepare(ShapeBullet::create_shape_empty());
+ }
btCollisionShape *cs(ShapeBullet::create_shape_convex(vertices));
cs->setLocalScaling(p_implicit_scale);
prepare(cs);
@@ -361,8 +363,7 @@ btCollisionShape *ConvexPolygonShapeBullet::create_bt_shape(const btVector3 &p_i
/* Concave polygon */
ConcavePolygonShapeBullet::ConcavePolygonShapeBullet() :
- ShapeBullet(),
- meshShape(nullptr) {}
+ ShapeBullet() {}
ConcavePolygonShapeBullet::~ConcavePolygonShapeBullet() {
if (meshShape) {
@@ -395,7 +396,6 @@ void ConcavePolygonShapeBullet::setup(Vector<Vector3> p_faces) {
}
int src_face_count = faces.size();
if (0 < src_face_count) {
-
// It counts the faces and assert the array contains the correct number of vertices.
ERR_FAIL_COND(src_face_count % 3);
@@ -433,9 +433,10 @@ void ConcavePolygonShapeBullet::setup(Vector<Vector3> p_faces) {
btCollisionShape *ConcavePolygonShapeBullet::create_bt_shape(const btVector3 &p_implicit_scale, real_t p_extra_edge) {
btCollisionShape *cs = ShapeBullet::create_shape_concave(meshShape);
- if (!cs)
+ if (!cs) {
// This is necessary since if 0 faces the creation of concave return null
cs = ShapeBullet::create_shape_empty();
+ }
cs->setLocalScaling(p_implicit_scale);
prepare(cs);
cs->setMargin(0);
@@ -458,10 +459,12 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
real_t l_max_height = 0.0;
// If specified, min and max height will be used as precomputed values
- if (d.has("min_height"))
+ if (d.has("min_height")) {
l_min_height = d["min_height"];
- if (d.has("max_height"))
+ }
+ if (d.has("max_height")) {
l_max_height = d["max_height"];
+ }
ERR_FAIL_COND(l_min_height > l_max_height);
@@ -514,7 +517,6 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
// Compute min and max heights if not specified.
if (!d.has("min_height") && !d.has("max_height")) {
-
const real_t *r = l_heights.ptr();
int heights_size = l_heights.size();
@@ -562,18 +564,14 @@ btCollisionShape *HeightMapShapeBullet::create_bt_shape(const btVector3 &p_impli
/* Ray shape */
RayShapeBullet::RayShapeBullet() :
- ShapeBullet(),
- length(1),
- slips_on_slope(false) {}
+ ShapeBullet() {}
void RayShapeBullet::set_data(const Variant &p_data) {
-
Dictionary d = p_data;
setup(d["length"], d["slips_on_slope"]);
}
Variant RayShapeBullet::get_data() const {
-
Dictionary d;
d["length"] = length;
d["slips_on_slope"] = slips_on_slope;
diff --git a/modules/bullet/shape_bullet.h b/modules/bullet/shape_bullet.h
index 0dbc616fe5..b24ded574f 100644
--- a/modules/bullet/shape_bullet.h
+++ b/modules/bullet/shape_bullet.h
@@ -50,9 +50,8 @@ class ShapeOwnerBullet;
class btBvhTriangleMeshShape;
class ShapeBullet : public RIDBullet {
-
Map<ShapeOwnerBullet *, int> owners;
- real_t margin;
+ real_t margin = 0.04;
protected:
/// return self
@@ -95,7 +94,6 @@ public:
};
class PlaneShapeBullet : public ShapeBullet {
-
Plane plane;
public:
@@ -111,7 +109,6 @@ private:
};
class SphereShapeBullet : public ShapeBullet {
-
real_t radius;
public:
@@ -128,7 +125,6 @@ private:
};
class BoxShapeBullet : public ShapeBullet {
-
btVector3 half_extents;
public:
@@ -145,7 +141,6 @@ private:
};
class CapsuleShapeBullet : public ShapeBullet {
-
real_t height;
real_t radius;
@@ -164,7 +159,6 @@ private:
};
class CylinderShapeBullet : public ShapeBullet {
-
real_t height;
real_t radius;
@@ -183,7 +177,6 @@ private:
};
class ConvexPolygonShapeBullet : public ShapeBullet {
-
public:
btAlignedObjectArray<btVector3> vertices;
@@ -200,7 +193,7 @@ private:
};
class ConcavePolygonShapeBullet : public ShapeBullet {
- class btBvhTriangleMeshShape *meshShape;
+ class btBvhTriangleMeshShape *meshShape = nullptr;
public:
Vector<Vector3> faces;
@@ -218,7 +211,6 @@ private:
};
class HeightMapShapeBullet : public ShapeBullet {
-
public:
Vector<real_t> heights;
int width;
@@ -238,10 +230,9 @@ private:
};
class RayShapeBullet : public ShapeBullet {
-
public:
- real_t length;
- bool slips_on_slope;
+ real_t length = 1;
+ bool slips_on_slope = false;
RayShapeBullet();
diff --git a/modules/bullet/slider_joint_bullet.cpp b/modules/bullet/slider_joint_bullet.cpp
index f193daef39..6d5d95d07a 100644
--- a/modules/bullet/slider_joint_bullet.cpp
+++ b/modules/bullet/slider_joint_bullet.cpp
@@ -42,7 +42,6 @@
SliderJointBullet::SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB, const Transform &frameInA, const Transform &frameInB) :
JointBullet() {
-
Transform scaled_AFrame(frameInA.scaled(rbA->get_body_scale()));
scaled_AFrame.basis.rotref_posscale_decomposition(scaled_AFrame.basis);
@@ -50,7 +49,6 @@ SliderJointBullet::SliderJointBullet(RigidBodyBullet *rbA, RigidBodyBullet *rbB,
G_TO_B(scaled_AFrame, btFrameA);
if (rbB) {
-
Transform scaled_BFrame(frameInB.scaled(rbB->get_body_scale()));
scaled_BFrame.basis.rotref_posscale_decomposition(scaled_BFrame.basis);
@@ -121,6 +119,7 @@ real_t SliderJointBullet::getLowerLinLimit() const {
void SliderJointBullet::setLowerLinLimit(real_t lowerLimit) {
sliderConstraint->setLowerLinLimit(lowerLimit);
}
+
real_t SliderJointBullet::getUpperLinLimit() const {
return sliderConstraint->getUpperLinLimit();
}
@@ -344,56 +343,123 @@ real_t SliderJointBullet::getLinearPos() {
void SliderJointBullet::set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value) {
switch (p_param) {
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: setUpperLinLimit(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: setLowerLinLimit(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: setSoftnessLimLin(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: setRestitutionLimLin(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: setDampingLimLin(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: setSoftnessDirLin(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: setRestitutionDirLin(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: setDampingDirLin(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: setSoftnessOrthoLin(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: setRestitutionOrthoLin(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: setDampingOrthoLin(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: setUpperAngLimit(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: setLowerAngLimit(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: setSoftnessLimAng(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: setRestitutionLimAng(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: setDampingLimAng(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: setSoftnessDirAng(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: setRestitutionDirAng(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: setDampingDirAng(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: setSoftnessOrthoAng(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: setRestitutionOrthoAng(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: setDampingOrthoAng(p_value); break;
- case PhysicsServer3D::SLIDER_JOINT_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER:
+ setUpperLinLimit(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER:
+ setLowerLinLimit(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS:
+ setSoftnessLimLin(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION:
+ setRestitutionLimLin(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING:
+ setDampingLimLin(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS:
+ setSoftnessDirLin(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION:
+ setRestitutionDirLin(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING:
+ setDampingDirLin(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS:
+ setSoftnessOrthoLin(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION:
+ setRestitutionOrthoLin(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING:
+ setDampingOrthoLin(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER:
+ setUpperAngLimit(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER:
+ setLowerAngLimit(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS:
+ setSoftnessLimAng(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION:
+ setRestitutionLimAng(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING:
+ setDampingLimAng(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS:
+ setSoftnessDirAng(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION:
+ setRestitutionDirAng(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING:
+ setDampingDirAng(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS:
+ setSoftnessOrthoAng(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION:
+ setRestitutionOrthoAng(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING:
+ setDampingOrthoAng(p_value);
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_MAX:
+ break; // Can't happen, but silences warning
}
}
real_t SliderJointBullet::get_param(PhysicsServer3D::SliderJointParam p_param) const {
switch (p_param) {
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: return getUpperLinLimit();
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: return getLowerLinLimit();
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: return getSoftnessLimLin();
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: return getRestitutionLimLin();
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: return getDampingLimLin();
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: return getSoftnessDirLin();
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: return getRestitutionDirLin();
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: return getDampingDirLin();
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: return getSoftnessOrthoLin();
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: return getRestitutionOrthoLin();
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: return getDampingOrthoLin();
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: return getUpperAngLimit();
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: return getLowerAngLimit();
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: return getSoftnessLimAng();
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: return getRestitutionLimAng();
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: return getDampingLimAng();
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: return getSoftnessDirAng();
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: return getRestitutionDirAng();
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: return getDampingDirAng();
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: return getSoftnessOrthoAng();
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: return getRestitutionOrthoAng();
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: return getDampingOrthoAng();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER:
+ return getUpperLinLimit();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER:
+ return getLowerLinLimit();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS:
+ return getSoftnessLimLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION:
+ return getRestitutionLimLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING:
+ return getDampingLimLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS:
+ return getSoftnessDirLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION:
+ return getRestitutionDirLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING:
+ return getDampingDirLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS:
+ return getSoftnessOrthoLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION:
+ return getRestitutionOrthoLin();
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING:
+ return getDampingOrthoLin();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER:
+ return getUpperAngLimit();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER:
+ return getLowerAngLimit();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS:
+ return getSoftnessLimAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION:
+ return getRestitutionLimAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING:
+ return getDampingLimAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS:
+ return getSoftnessDirAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION:
+ return getRestitutionDirAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING:
+ return getDampingDirAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS:
+ return getSoftnessOrthoAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION:
+ return getRestitutionOrthoAng();
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING:
+ return getDampingOrthoAng();
default:
return 0;
}
diff --git a/modules/bullet/soft_body_bullet.cpp b/modules/bullet/soft_body_bullet.cpp
index 236bdc7c8a..6794d6c313 100644
--- a/modules/bullet/soft_body_bullet.cpp
+++ b/modules/bullet/soft_body_bullet.cpp
@@ -36,18 +36,7 @@
#include "space_bullet.h"
SoftBodyBullet::SoftBodyBullet() :
- CollisionObjectBullet(CollisionObjectBullet::TYPE_SOFT_BODY),
- bt_soft_body(nullptr),
- isScratched(false),
- simulation_precision(5),
- total_mass(1.),
- linear_stiffness(0.5),
- areaAngular_stiffness(0.5),
- volume_stiffness(0.5),
- pressure_coefficient(0.),
- pose_matching_coefficient(0.),
- damping_coefficient(0.01),
- drag_coefficient(0.) {}
+ CollisionObjectBullet(CollisionObjectBullet::TYPE_SOFT_BODY) {}
SoftBodyBullet::~SoftBodyBullet() {
}
@@ -77,8 +66,9 @@ void SoftBodyBullet::on_enter_area(AreaBullet *p_area) {}
void SoftBodyBullet::on_exit_area(AreaBullet *p_area) {}
void SoftBodyBullet::update_rendering_server(SoftBodyRenderingServerHandler *p_rendering_server_handler) {
- if (!bt_soft_body)
+ if (!bt_soft_body) {
return;
+ }
/// Update visual server vertices
const btSoftBody::tNodeArray &nodes(bt_soft_body->m_nodes);
@@ -116,14 +106,13 @@ void SoftBodyBullet::update_rendering_server(SoftBodyRenderingServerHandler *p_r
}
void SoftBodyBullet::set_soft_mesh(const Ref<Mesh> &p_mesh) {
-
- if (p_mesh.is_null())
+ if (p_mesh.is_null()) {
soft_mesh.unref();
- else
+ } else {
soft_mesh = p_mesh;
+ }
if (soft_mesh.is_null()) {
-
destroy_soft_body();
return;
}
@@ -134,9 +123,9 @@ void SoftBodyBullet::set_soft_mesh(const Ref<Mesh> &p_mesh) {
}
void SoftBodyBullet::destroy_soft_body() {
-
- if (!bt_soft_body)
+ if (!bt_soft_body) {
return;
+ }
if (space) {
/// Remove from world before deletion
@@ -153,8 +142,9 @@ void SoftBodyBullet::set_soft_transform(const Transform &p_transform) {
}
void SoftBodyBullet::move_all_nodes(const Transform &p_transform) {
- if (!bt_soft_body)
+ if (!bt_soft_body) {
return;
+ }
btTransform bt_transf;
G_TO_B(p_transform, bt_transf);
bt_soft_body->transform(bt_transf);
@@ -180,8 +170,9 @@ void SoftBodyBullet::get_node_position(int p_node_index, Vector3 &r_position) co
}
void SoftBodyBullet::get_node_offset(int p_node_index, Vector3 &r_offset) const {
- if (soft_mesh.is_null())
+ if (soft_mesh.is_null()) {
return;
+ }
Array arrays = soft_mesh->surface_get_arrays(0);
Vector<Vector3> vertices(arrays[RS::ARRAY_VERTEX]);
@@ -226,15 +217,15 @@ void SoftBodyBullet::reset_all_node_mass() {
}
void SoftBodyBullet::reset_all_node_positions() {
- if (soft_mesh.is_null())
+ if (soft_mesh.is_null()) {
return;
+ }
Array arrays = soft_mesh->surface_get_arrays(0);
Vector<Vector3> vs_vertices(arrays[RS::ARRAY_VERTEX]);
const Vector3 *vs_vertices_read = vs_vertices.ptr();
for (int vertex_index = bt_soft_body->m_nodes.size() - 1; 0 <= vertex_index; --vertex_index) {
-
G_TO_B(vs_vertices_read[indices_table[vertex_index][0]], bt_soft_body->m_nodes[vertex_index].m_x);
bt_soft_body->m_nodes[vertex_index].m_q = bt_soft_body->m_nodes[vertex_index].m_x;
@@ -342,7 +333,6 @@ void SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector
const Vector3 *p_vertices_read = p_vertices.ptr();
for (int vs_vertex_index = 0; vs_vertex_index < vs_vertices_size; ++vs_vertex_index) {
-
Map<Vector3, int>::Element *e = unique_vertices.find(p_vertices_read[vs_vertex_index]);
int vertex_id;
if (e) {
@@ -398,9 +388,9 @@ void SoftBodyBullet::set_trimesh_body_shape(Vector<int> p_indices, Vector<Vector
}
void SoftBodyBullet::setup_soft_body() {
-
- if (!bt_soft_body)
+ if (!bt_soft_body) {
return;
+ }
// Soft body setup
setupBulletCollisionObject(bt_soft_body);
diff --git a/modules/bullet/soft_body_bullet.h b/modules/bullet/soft_body_bullet.h
index 3c6871e0d6..da8a2412ed 100644
--- a/modules/bullet/soft_body_bullet.h
+++ b/modules/bullet/soft_body_bullet.h
@@ -56,24 +56,23 @@
*/
class SoftBodyBullet : public CollisionObjectBullet {
-
private:
- btSoftBody *bt_soft_body;
+ btSoftBody *bt_soft_body = nullptr;
Vector<Vector<int>> indices_table;
btSoftBody::Material *mat0; // This is just a copy of pointer managed by btSoftBody
- bool isScratched;
+ bool isScratched = false;
Ref<Mesh> soft_mesh;
- int simulation_precision;
- real_t total_mass;
- real_t linear_stiffness; // [0,1]
- real_t areaAngular_stiffness; // [0,1]
- real_t volume_stiffness; // [0,1]
- real_t pressure_coefficient; // [-inf,+inf]
- real_t pose_matching_coefficient; // [0,1]
- real_t damping_coefficient; // [0,1]
- real_t drag_coefficient; // [0,1]
+ int simulation_precision = 5;
+ real_t total_mass = 1.;
+ real_t linear_stiffness = 0.5; // [0,1]
+ real_t areaAngular_stiffness = 0.5; // [0,1]
+ real_t volume_stiffness = 0.5; // [0,1]
+ real_t pressure_coefficient = 0.; // [-inf,+inf]
+ real_t pose_matching_coefficient = 0.; // [0,1]
+ real_t damping_coefficient = 0.01; // [0,1]
+ real_t drag_coefficient = 0.; // [0,1]
Vector<int> pinned_nodes;
// Other property to add
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index 1659664ff9..99f58e7059 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -63,9 +63,9 @@ BulletPhysicsDirectSpaceState::BulletPhysicsDirectSpaceState(SpaceBullet *p_spac
space(p_space) {}
int BulletPhysicsDirectSpaceState::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
- if (p_result_max <= 0)
+ if (p_result_max <= 0) {
return 0;
+ }
btVector3 bt_point;
G_TO_B(p_point, bt_point);
@@ -86,7 +86,6 @@ int BulletPhysicsDirectSpaceState::intersect_point(const Vector3 &p_point, Shape
}
bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_ray) {
-
btVector3 btVec_from;
btVector3 btVec_to;
@@ -119,8 +118,9 @@ bool BulletPhysicsDirectSpaceState::intersect_ray(const Vector3 &p_from, const V
}
int BulletPhysicsDirectSpaceState::intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
- if (p_result_max <= 0)
+ if (p_result_max <= 0) {
return 0;
+ }
ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape);
@@ -204,8 +204,9 @@ bool BulletPhysicsDirectSpaceState::cast_motion(const RID &p_shape, const Transf
/// Returns the list of contacts pairs in this order: Local contact, other body contact
bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
- if (p_result_max <= 0)
- return 0;
+ if (p_result_max <= 0) {
+ return false;
+ }
ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape);
@@ -213,7 +214,7 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &
if (!btShape->isConvex()) {
bulletdelete(btShape);
ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type()));
- return 0;
+ return false;
}
btConvexShape *btConvex = static_cast<btConvexShape *>(btShape);
@@ -238,14 +239,13 @@ bool BulletPhysicsDirectSpaceState::collide_shape(RID p_shape, const Transform &
}
bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
ShapeBullet *shape = space->get_physics_server()->get_shape_owner()->getornull(p_shape);
btCollisionShape *btShape = shape->create_bt_shape(p_shape_xform.basis.get_scale_abs(), p_margin);
if (!btShape->isConvex()) {
bulletdelete(btShape);
ERR_PRINT("The shape is not a convex shape, then is not supported: shape type: " + itos(shape->get_type()));
- return 0;
+ return false;
}
btConvexShape *btConvex = static_cast<btConvexShape *>(btShape);
@@ -276,7 +276,6 @@ bool BulletPhysicsDirectSpaceState::rest_info(RID p_shape, const Transform &p_sh
}
Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const {
-
RigidCollisionObjectBullet *rigid_object = space->get_physics_server()->get_rigid_collisin_object(p_object);
ERR_FAIL_COND_V(!rigid_object, Vector3());
@@ -320,31 +319,16 @@ Vector3 BulletPhysicsDirectSpaceState::get_closest_point_to_object_volume(RID p_
}
if (shapes_found) {
-
Vector3 out;
B_TO_G(out_closest_point, out);
return out;
} else {
-
// no shapes found, use distance to origin.
return rigid_object->get_transform().get_origin();
}
}
-SpaceBullet::SpaceBullet() :
- broadphase(nullptr),
- collisionConfiguration(nullptr),
- dispatcher(nullptr),
- solver(nullptr),
- dynamicsWorld(nullptr),
- soft_body_world_info(nullptr),
- ghostPairCallback(nullptr),
- godotFilterCallback(nullptr),
- gravityDirection(0, -1, 0),
- gravityMagnitude(10),
- contactDebugCount(0),
- delta_time(0.) {
-
+SpaceBullet::SpaceBullet() {
create_empty_world(GLOBAL_DEF("physics/3d/active_soft_world", true));
direct_access = memnew(BulletPhysicsDirectSpaceState(this));
}
@@ -379,8 +363,11 @@ void SpaceBullet::set_param(PhysicsServer3D::AreaParameter p_param, const Varian
update_gravity();
break;
case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP:
+ linear_damp = p_value;
+ break;
case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP:
- break; // No damp
+ angular_damp = p_value;
+ break;
case PhysicsServer3D::AREA_PARAM_PRIORITY:
// Priority is always 0, the lower
break;
@@ -401,8 +388,9 @@ Variant SpaceBullet::get_param(PhysicsServer3D::AreaParameter p_param) {
case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR:
return gravityDirection;
case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP:
+ return linear_damp;
case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP:
- return 0; // No damp
+ return angular_damp;
case PhysicsServer3D::AREA_PARAM_PRIORITY:
return 0; // Priority is always 0, the lower
case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT:
@@ -548,7 +536,6 @@ void onBulletPreTickCallback(btDynamicsWorld *p_dynamicsWorld, btScalar timeStep
}
void onBulletTickCallback(btDynamicsWorld *p_dynamicsWorld, btScalar timeStep) {
-
const btCollisionObjectArray &colObjArray = p_dynamicsWorld->getCollisionObjectArray();
// Notify all Collision objects the collision checker is started
@@ -570,17 +557,14 @@ BulletPhysicsDirectSpaceState *SpaceBullet::get_direct_state() {
}
btScalar calculateGodotCombinedRestitution(const btCollisionObject *body0, const btCollisionObject *body1) {
-
return CLAMP(body0->getRestitution() + body1->getRestitution(), 0, 1);
}
btScalar calculateGodotCombinedFriction(const btCollisionObject *body0, const btCollisionObject *body1) {
-
return ABS(MIN(body0->getFriction(), body1->getFriction()));
}
void SpaceBullet::create_empty_world(bool p_create_soft_world) {
-
gjk_epa_pen_solver = bulletnew(btGjkEpaPenetrationDepthSolver);
gjk_simplex_solver = bulletnew(btVoronoiSimplexSolver);
@@ -633,7 +617,6 @@ void SpaceBullet::create_empty_world(bool p_create_soft_world) {
}
void SpaceBullet::destroy_world() {
-
/// The world elements (like: Collision Objects, Constraints, Shapes) are managed by godot
dynamicsWorld->getBroadphase()->getOverlappingPairCache()->setInternalGhostPairCallback(nullptr);
@@ -657,7 +640,6 @@ void SpaceBullet::destroy_world() {
}
void SpaceBullet::check_ghost_overlaps() {
-
/// Algorithm support variables
btCollisionShape *other_body_shape;
btConvexShape *area_shape;
@@ -671,8 +653,9 @@ void SpaceBullet::check_ghost_overlaps() {
btVector3 area_scale(area->get_bt_body_scale());
- if (!area->is_monitoring())
+ if (!area->is_monitoring()) {
continue;
+ }
/// 1. Reset all states
for (i = area->overlappingObjects.size() - 1; 0 <= i; --i) {
@@ -690,7 +673,6 @@ void SpaceBullet::check_ghost_overlaps() {
// For each overlapping
for (i = ghostOverlaps.size() - 1; 0 <= i; --i) {
-
bool hasOverlap = false;
btCollisionObject *overlapped_bt_co = ghostOverlaps[i];
RigidCollisionObjectBullet *otherObject = static_cast<RigidCollisionObjectBullet *>(overlapped_bt_co->getUserPointer());
@@ -702,15 +684,18 @@ void SpaceBullet::check_ghost_overlaps() {
}
if (overlapped_bt_co->getUserIndex() == CollisionObjectBullet::TYPE_AREA) {
- if (!static_cast<AreaBullet *>(overlapped_bt_co->getUserPointer())->is_monitorable())
+ if (!static_cast<AreaBullet *>(overlapped_bt_co->getUserPointer())->is_monitorable()) {
continue;
- } else if (overlapped_bt_co->getUserIndex() != CollisionObjectBullet::TYPE_RIGID_BODY)
+ }
+ } else if (overlapped_bt_co->getUserIndex() != CollisionObjectBullet::TYPE_RIGID_BODY) {
continue;
+ }
// For each area shape
for (y = area->get_shape_count() - 1; 0 <= y; --y) {
- if (!area->get_bt_shape(y)->isConvex())
+ if (!area->get_bt_shape(y)->isConvex()) {
continue;
+ }
btTransform area_shape_treansform(area->get_bt_shape_transform(y));
area_shape_treansform.getOrigin() *= area_scale;
@@ -723,7 +708,6 @@ void SpaceBullet::check_ghost_overlaps() {
// For each other object shape
for (z = otherObject->get_shape_count() - 1; 0 <= z; --z) {
-
other_body_shape = static_cast<btCollisionShape *>(otherObject->get_bt_shape(z));
btTransform other_shape_transform(otherObject->get_bt_shape_transform(z));
@@ -734,7 +718,6 @@ void SpaceBullet::check_ghost_overlaps() {
other_shape_transform;
if (other_body_shape->isConvex()) {
-
btPointCollector result;
btGjkPairDetector gjk_pair_detector(
area_shape,
@@ -749,14 +732,14 @@ void SpaceBullet::check_ghost_overlaps() {
}
} else {
-
btCollisionObjectWrapper obA(nullptr, area_shape, area->get_bt_ghost(), gjk_input.m_transformA, -1, y);
btCollisionObjectWrapper obB(nullptr, other_body_shape, otherObject->get_bt_collision_object(), gjk_input.m_transformB, -1, z);
btCollisionAlgorithm *algorithm = dispatcher->findAlgorithm(&obA, &obB, nullptr, BT_CONTACT_POINT_ALGORITHMS);
- if (!algorithm)
+ if (!algorithm) {
continue;
+ }
GodotDeepPenetrationContactResultCallback contactPointResult(&obA, &obB);
algorithm->processCollision(&obA, &obB, dynamicsWorld->getDispatchInfo(), &contactPointResult);
@@ -774,8 +757,9 @@ void SpaceBullet::check_ghost_overlaps() {
} // ~For each area shape
collision_found:
- if (!hasOverlap)
+ if (!hasOverlap) {
continue;
+ }
indexOverlap = area->find_overlapping_object(otherObject);
if (-1 == indexOverlap) {
@@ -832,7 +816,6 @@ void SpaceBullet::check_body_collision() {
pt.getDistance() <= 0.0 ||
bodyA->was_colliding(bodyB) ||
bodyB->was_colliding(bodyA)) {
-
Vector3 collisionWorldPosition;
Vector3 collisionLocalPosition;
Vector3 normalOnB;
@@ -892,7 +875,6 @@ static Ref<StandardMaterial3D> blue_mat;
#endif
bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes) {
-
#if debug_test_motion
/// Yes I know this is not good, but I've used it as fast debugging hack.
/// I'm leaving it here just for speedup the other eventual debugs
@@ -1009,7 +991,6 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
B_TO_G(motion + initial_recover_motion + __rec, r_result->motion);
if (has_penetration) {
-
const btRigidBody *btRigid = static_cast<const btRigidBody *>(r_recover_result.other_collision_object);
CollisionObjectBullet *collisionObject = static_cast<CollisionObjectBullet *>(btRigid->getUserPointer());
@@ -1043,7 +1024,6 @@ bool SpaceBullet::test_body_motion(RigidBodyBullet *p_body, const Transform &p_f
}
int SpaceBullet::test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, float p_margin) {
-
btTransform body_transform;
G_TO_B(p_transform, body_transform);
UNSCALE_BT_BASIS(body_transform);
@@ -1108,14 +1088,12 @@ public:
self_collision_object(p_self_collision_object),
collision_layer(p_collision_layer),
collision_mask(p_collision_mask) {
-
bounds = btDbvtVolume::FromMM(p_aabb_min, p_aabb_max);
}
virtual ~RecoverPenetrationBroadPhaseCallback() {}
virtual bool process(const btBroadphaseProxy *proxy) {
-
btCollisionObject *co = static_cast<btCollisionObject *>(proxy->m_clientObject);
if (co->getInternalType() <= btCollisionObject::CO_RIGID_BODY) {
if (self_collision_object != proxy->m_clientObject && GodotFilterCallback::test_collision_filters(collision_layer, collision_mask, proxy->m_collisionFilterGroup, proxy->m_collisionFilterMask)) {
@@ -1159,13 +1137,11 @@ public:
};
bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) {
-
// Calculate the cumulative AABB of all shapes of the kinematic body
btVector3 aabb_min, aabb_max;
bool shapes_found = false;
for (int kinIndex = p_body->get_kinematic_utilities()->shapes.size() - 1; 0 <= kinIndex; --kinIndex) {
-
const RigidBodyBullet::KinematicShape &kin_shape(p_body->get_kinematic_utilities()->shapes[kinIndex]);
if (!kin_shape.is_active()) {
continue;
@@ -1210,7 +1186,6 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran
// Perform narrowphase per shape
for (int kinIndex = p_body->get_kinematic_utilities()->shapes.size() - 1; 0 <= kinIndex; --kinIndex) {
-
const RigidBodyBullet::KinematicShape &kin_shape(p_body->get_kinematic_utilities()->shapes[kinIndex]);
if (!kin_shape.is_active()) {
continue;
@@ -1229,8 +1204,9 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran
if (p_infinite_inertia && !otherObject->isStaticOrKinematicObject()) {
otherObject->activate(); // Force activation of hitten rigid, soft body
continue;
- } else if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object()))
+ } else if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object())) {
continue;
+ }
if (otherObject->getCollisionShape()->isCompound()) {
const btCompoundShape *cs = static_cast<const btCompoundShape *>(otherObject->getCollisionShape());
@@ -1239,23 +1215,19 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran
if (cs->getChildShape(shape_idx)->isConvex()) {
if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(cs->getChildShape(shape_idx)), otherObject, kinIndex, shape_idx, shape_transform, otherObject->getWorldTransform() * cs->getChildTransform(shape_idx), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) {
-
penetration = true;
}
} else {
if (RFP_convex_world_test(kin_shape.shape, cs->getChildShape(shape_idx), p_body->get_bt_collision_object(), otherObject, kinIndex, shape_idx, shape_transform, otherObject->getWorldTransform() * cs->getChildTransform(shape_idx), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) {
-
penetration = true;
}
}
} else if (otherObject->getCollisionShape()->isConvex()) { /// Execute GJK test against object shape
if (RFP_convex_convex_test(kin_shape.shape, static_cast<const btConvexShape *>(otherObject->getCollisionShape()), otherObject, kinIndex, 0, shape_transform, otherObject->getWorldTransform(), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) {
-
penetration = true;
}
} else {
if (RFP_convex_world_test(kin_shape.shape, otherObject->getCollisionShape(), p_body->get_bt_collision_object(), otherObject, kinIndex, 0, shape_transform, otherObject->getWorldTransform(), p_recover_movement_scale, r_delta_recover_movement, r_recover_result)) {
-
penetration = true;
}
}
@@ -1266,7 +1238,6 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran
}
bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const btConvexShape *p_shapeB, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) {
-
// Initialize GJK input
btGjkPairDetector::ClosestPointInput gjk_input;
gjk_input.m_transformA = p_transformA;
@@ -1297,7 +1268,6 @@ bool SpaceBullet::RFP_convex_convex_test(const btConvexShape *p_shapeA, const bt
}
bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btCollisionShape *p_shapeB, btCollisionObject *p_objectA, btCollisionObject *p_objectB, int p_shapeId_A, int p_shapeId_B, const btTransform &p_transformA, const btTransform &p_transformB, btScalar p_recover_movement_scale, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result) {
-
/// Contact test
btTransform tA(p_transformA);
@@ -1334,7 +1304,6 @@ bool SpaceBullet::RFP_convex_world_test(const btConvexShape *p_shapeA, const btC
}
int SpaceBullet::add_separation_result(PhysicsServer3D::SeparationResult *r_result, const SpaceBullet::RecoverResult &p_recover_result, int p_shape_id, const btCollisionObject *p_other_object) const {
-
// optimize results (ignore non-colliding)
if (p_recover_result.penetration_distance < 0.0) {
const btRigidBody *btRigid = static_cast<const btRigidBody *>(p_other_object);
@@ -1356,13 +1325,11 @@ int SpaceBullet::add_separation_result(PhysicsServer3D::SeparationResult *r_resu
}
int SpaceBullet::recover_from_penetration_ray(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, int p_result_max, btVector3 &r_delta_recover_movement, PhysicsServer3D::SeparationResult *r_results) {
-
// Calculate the cumulative AABB of all shapes of the kinematic body
btVector3 aabb_min, aabb_max;
bool shapes_found = false;
for (int kinIndex = p_body->get_kinematic_utilities()->shapes.size() - 1; 0 <= kinIndex; --kinIndex) {
-
const RigidBodyBullet::KinematicShape &kin_shape(p_body->get_kinematic_utilities()->shapes[kinIndex]);
if (!kin_shape.is_active()) {
continue;
@@ -1406,7 +1373,6 @@ int SpaceBullet::recover_from_penetration_ray(RigidBodyBullet *p_body, const btT
// Perform narrowphase per shape
for (int kinIndex = p_body->get_kinematic_utilities()->shapes.size() - 1; 0 <= kinIndex; --kinIndex) {
-
if (ray_count >= p_result_max) {
break;
}
@@ -1428,8 +1394,9 @@ int SpaceBullet::recover_from_penetration_ray(RigidBodyBullet *p_body, const btT
if (p_infinite_inertia && !otherObject->isStaticOrKinematicObject()) {
otherObject->activate(); // Force activation of hitten rigid, soft body
continue;
- } else if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object()))
+ } else if (!p_body->get_bt_collision_object()->checkCollideWith(otherObject) || !otherObject->checkCollideWith(p_body->get_bt_collision_object())) {
continue;
+ }
if (otherObject->getCollisionShape()->isCompound()) {
const btCompoundShape *cs = static_cast<const btCompoundShape *>(otherObject->getCollisionShape());
@@ -1438,14 +1405,11 @@ int SpaceBullet::recover_from_penetration_ray(RigidBodyBullet *p_body, const btT
RecoverResult recover_result;
if (RFP_convex_world_test(kin_shape.shape, cs->getChildShape(shape_idx), p_body->get_bt_collision_object(), otherObject, kinIndex, shape_idx, shape_transform, otherObject->getWorldTransform() * cs->getChildTransform(shape_idx), p_recover_movement_scale, r_delta_recover_movement, &recover_result)) {
-
ray_count = add_separation_result(&r_results[ray_count], recover_result, kinIndex, otherObject);
}
} else {
-
RecoverResult recover_result;
if (RFP_convex_world_test(kin_shape.shape, otherObject->getCollisionShape(), p_body->get_bt_collision_object(), otherObject, kinIndex, 0, shape_transform, otherObject->getWorldTransform(), p_recover_movement_scale, r_delta_recover_movement, &recover_result)) {
-
ray_count = add_separation_result(&r_results[ray_count], recover_result, kinIndex, otherObject);
}
}
diff --git a/modules/bullet/space_bullet.h b/modules/bullet/space_bullet.h
index f9a8c063fd..5ff421ef52 100644
--- a/modules/bullet/space_bullet.h
+++ b/modules/bullet/space_bullet.h
@@ -87,32 +87,34 @@ public:
};
class SpaceBullet : public RIDBullet {
-
friend class AreaBullet;
friend void onBulletTickCallback(btDynamicsWorld *world, btScalar timeStep);
friend class BulletPhysicsDirectSpaceState;
- btBroadphaseInterface *broadphase;
- btDefaultCollisionConfiguration *collisionConfiguration;
- btCollisionDispatcher *dispatcher;
- btConstraintSolver *solver;
- btDiscreteDynamicsWorld *dynamicsWorld;
- btSoftBodyWorldInfo *soft_body_world_info;
- btGhostPairCallback *ghostPairCallback;
- GodotFilterCallback *godotFilterCallback;
+ btBroadphaseInterface *broadphase = nullptr;
+ btDefaultCollisionConfiguration *collisionConfiguration = nullptr;
+ btCollisionDispatcher *dispatcher = nullptr;
+ btConstraintSolver *solver = nullptr;
+ btDiscreteDynamicsWorld *dynamicsWorld = nullptr;
+ btSoftBodyWorldInfo *soft_body_world_info = nullptr;
+ btGhostPairCallback *ghostPairCallback = nullptr;
+ GodotFilterCallback *godotFilterCallback = nullptr;
btGjkEpaPenetrationDepthSolver *gjk_epa_pen_solver;
btVoronoiSimplexSolver *gjk_simplex_solver;
BulletPhysicsDirectSpaceState *direct_access;
- Vector3 gravityDirection;
- real_t gravityMagnitude;
+ Vector3 gravityDirection = Vector3(0, -1, 0);
+ real_t gravityMagnitude = 10;
+
+ real_t linear_damp = 0.0;
+ real_t angular_damp = 0.0;
Vector<AreaBullet *> areas;
Vector<Vector3> contactDebug;
- int contactDebugCount;
- real_t delta_time;
+ int contactDebugCount = 0;
+ real_t delta_time = 0.;
public:
SpaceBullet();
@@ -167,7 +169,9 @@ public:
contactDebugCount = 0;
}
_FORCE_INLINE_ void add_debug_contact(const Vector3 &p_contact) {
- if (contactDebugCount < contactDebug.size()) contactDebug.write[contactDebugCount++] = p_contact;
+ if (contactDebugCount < contactDebug.size()) {
+ contactDebug.write[contactDebugCount++] = p_contact;
+ }
}
_FORCE_INLINE_ Vector<Vector3> get_debug_contacts() { return contactDebug; }
_FORCE_INLINE_ int get_debug_contact_count() { return contactDebugCount; }
@@ -177,6 +181,9 @@ public:
void update_gravity();
+ real_t get_linear_damp() const { return linear_damp; }
+ real_t get_angular_damp() const { return angular_damp; }
+
bool test_body_motion(RigidBodyBullet *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes);
int test_ray_separation(RigidBodyBullet *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, float p_margin);
@@ -187,22 +194,15 @@ private:
void check_body_collision();
struct RecoverResult {
- bool hasPenetration;
- btVector3 normal;
- btVector3 pointWorld;
- btScalar penetration_distance; // Negative mean penetration
- int other_compound_shape_index;
- const btCollisionObject *other_collision_object;
- int local_shape_most_recovered;
-
- RecoverResult() :
- hasPenetration(false),
- normal(0, 0, 0),
- pointWorld(0, 0, 0),
- penetration_distance(1e20),
- other_compound_shape_index(0),
- other_collision_object(nullptr),
- local_shape_most_recovered(0) {}
+ bool hasPenetration = false;
+ btVector3 normal = btVector3(0, 0, 0);
+ btVector3 pointWorld = btVector3(0, 0, 0);
+ btScalar penetration_distance = 1e20; // Negative mean penetration
+ int other_compound_shape_index = 0;
+ const btCollisionObject *other_collision_object = nullptr;
+ int local_shape_most_recovered = 0;
+
+ RecoverResult() {}
};
bool recover_from_penetration(RigidBodyBullet *p_body, const btTransform &p_body_position, btScalar p_recover_movement_scale, bool p_infinite_inertia, btVector3 &r_delta_recover_movement, RecoverResult *r_recover_result = nullptr);
diff --git a/modules/camera/camera_win.cpp b/modules/camera/camera_win.cpp
index 875f0b26bc..1646644be3 100644
--- a/modules/camera/camera_win.cpp
+++ b/modules/camera/camera_win.cpp
@@ -53,9 +53,9 @@ public:
void deactivate_feed();
};
-CameraFeedWindows::CameraFeedWindows(){
+CameraFeedWindows::CameraFeedWindows() {
///@TODO implement this, should store information about our available camera
-};
+}
CameraFeedWindows::~CameraFeedWindows() {
// make sure we stop recording if we are!
@@ -75,16 +75,16 @@ bool CameraFeedWindows::activate_feed() {
///@TODO we should probably have a callback method here that is being called by the
// camera API which provides frames and call back into the CameraServer to update our texture
-void CameraFeedWindows::deactivate_feed(){
+void CameraFeedWindows::deactivate_feed() {
///@TODO this should deactivate our camera and stop the process of capturing frames
-};
+}
//////////////////////////////////////////////////////////////////////////
// CameraWindows - Subclass for our camera server on windows
-void CameraWindows::add_active_cameras(){
+void CameraWindows::add_active_cameras() {
///@TODO scan through any active cameras and create CameraFeedWindows objects for them
-};
+}
CameraWindows::CameraWindows() {
// Find cameras active right now
@@ -92,7 +92,3 @@ CameraWindows::CameraWindows() {
// need to add something that will react to devices being connected/removed...
};
-
-CameraWindows::~CameraWindows(){
-
-};
diff --git a/modules/camera/camera_win.h b/modules/camera/camera_win.h
index 39a1b0b86f..bbc8880c12 100644
--- a/modules/camera/camera_win.h
+++ b/modules/camera/camera_win.h
@@ -40,7 +40,7 @@ private:
public:
CameraWindows();
- ~CameraWindows();
+ ~CameraWindows() {}
};
#endif /* CAMERAWIN_H */
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index 3f61e2852f..df798623f9 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -37,30 +37,31 @@
// Static helper functions.
inline static bool is_snapable(const Vector3 &p_point1, const Vector3 &p_point2, real_t p_distance) {
-
return (p_point1 - p_point2).length_squared() < p_distance * p_distance;
}
inline static Vector2 interpolate_segment_uv(const Vector2 p_segement_points[2], const Vector2 p_uvs[2], const Vector2 &p_interpolation_point) {
-
float segment_length = (p_segement_points[1] - p_segement_points[0]).length();
- if (segment_length < CMP_EPSILON)
+ if (segment_length < CMP_EPSILON) {
return p_uvs[0];
+ }
float distance = (p_interpolation_point - p_segement_points[0]).length();
float fraction = distance / segment_length;
- return p_uvs[0].linear_interpolate(p_uvs[1], fraction);
+ return p_uvs[0].lerp(p_uvs[1], fraction);
}
inline static Vector2 interpolate_triangle_uv(const Vector2 p_vertices[3], const Vector2 p_uvs[3], const Vector2 &p_interpolation_point) {
-
- if (p_interpolation_point.distance_squared_to(p_vertices[0]) < CMP_EPSILON2)
+ if (p_interpolation_point.distance_squared_to(p_vertices[0]) < CMP_EPSILON2) {
return p_uvs[0];
- if (p_interpolation_point.distance_squared_to(p_vertices[1]) < CMP_EPSILON2)
+ }
+ if (p_interpolation_point.distance_squared_to(p_vertices[1]) < CMP_EPSILON2) {
return p_uvs[1];
- if (p_interpolation_point.distance_squared_to(p_vertices[2]) < CMP_EPSILON2)
+ }
+ if (p_interpolation_point.distance_squared_to(p_vertices[2]) < CMP_EPSILON2) {
return p_uvs[2];
+ }
Vector2 edge1 = p_vertices[1] - p_vertices[0];
Vector2 edge2 = p_vertices[2] - p_vertices[0];
@@ -72,8 +73,9 @@ inline static Vector2 interpolate_triangle_uv(const Vector2 p_vertices[3], const
float inter_on_edge1 = interpolation.dot(edge1);
float inter_on_edge2 = interpolation.dot(edge2);
float scale = (edge1_on_edge1 * edge2_on_edge2 - edge1_on_edge2 * edge1_on_edge2);
- if (scale == 0)
+ if (scale == 0) {
return p_uvs[0];
+ }
float v = (edge2_on_edge2 * inter_on_edge1 - edge1_on_edge2 * inter_on_edge2) / scale;
float w = (edge1_on_edge1 * inter_on_edge2 - edge1_on_edge2 * inter_on_edge1) / scale;
@@ -83,25 +85,27 @@ inline static Vector2 interpolate_triangle_uv(const Vector2 p_vertices[3], const
}
static inline bool ray_intersects_triangle(const Vector3 &p_from, const Vector3 &p_dir, const Vector3 p_vertices[3], float p_tolerance, Vector3 &r_intersection_point) {
-
Vector3 edge1 = p_vertices[1] - p_vertices[0];
Vector3 edge2 = p_vertices[2] - p_vertices[0];
Vector3 h = p_dir.cross(edge2);
real_t a = edge1.dot(h);
// Check if ray is parallel to triangle.
- if (Math::is_zero_approx(a))
+ if (Math::is_zero_approx(a)) {
return false;
+ }
real_t f = 1.0 / a;
Vector3 s = p_from - p_vertices[0];
real_t u = f * s.dot(h);
- if (u < 0.0 - p_tolerance || u > 1.0 + p_tolerance)
+ if (u < 0.0 - p_tolerance || u > 1.0 + p_tolerance) {
return false;
+ }
Vector3 q = s.cross(edge1);
real_t v = f * p_dir.dot(q);
- if (v < 0.0 - p_tolerance || u + v > 1.0 + p_tolerance)
+ if (v < 0.0 - p_tolerance || u + v > 1.0 + p_tolerance) {
return false;
+ }
// Ray intersects triangle.
// Calculate distance.
@@ -110,12 +114,12 @@ static inline bool ray_intersects_triangle(const Vector3 &p_from, const Vector3
if (t >= p_tolerance) {
r_intersection_point = p_from + p_dir * t;
return true;
- } else
+ } else {
return false;
+ }
}
inline bool is_point_in_triangle(const Vector3 &p_point, const Vector3 p_vertices[3], int p_shifted = 0) {
-
real_t det = p_vertices[0].dot(p_vertices[1].cross(p_vertices[2]));
// If determinant is, zero try shift the triangle and the point.
@@ -138,24 +142,28 @@ inline bool is_point_in_triangle(const Vector3 &p_point, const Vector3 p_vertice
lambda[2] = p_vertices[0].cross(p_vertices[1]).dot(p_point) / det;
// Point is in the plane if all lambdas sum to 1.
- if (!Math::is_equal_approx(lambda[0] + lambda[1] + lambda[2], 1)) return false;
+ if (!Math::is_equal_approx(lambda[0] + lambda[1] + lambda[2], 1)) {
+ return false;
+ }
// Point is inside the triangle if all lambdas are positive.
- if (lambda[0] < 0 || lambda[1] < 0 || lambda[2] < 0) return false;
+ if (lambda[0] < 0 || lambda[1] < 0 || lambda[2] < 0) {
+ return false;
+ }
return true;
}
inline static bool are_segements_parallel(const Vector2 p_segment1_points[2], const Vector2 p_segment2_points[2], float p_vertex_snap2) {
-
Vector2 segment1 = p_segment1_points[1] - p_segment1_points[0];
Vector2 segment2 = p_segment2_points[1] - p_segment2_points[0];
real_t segment1_length2 = segment1.dot(segment1);
real_t segment2_length2 = segment2.dot(segment2);
real_t segment_onto_segment = segment2.dot(segment1);
- if (segment1_length2 < p_vertex_snap2 || segment2_length2 < p_vertex_snap2)
+ if (segment1_length2 < p_vertex_snap2 || segment2_length2 < p_vertex_snap2) {
return true;
+ }
real_t max_separation2;
if (segment1_length2 > segment2_length2) {
@@ -170,7 +178,6 @@ inline static bool are_segements_parallel(const Vector2 p_segment1_points[2], co
// CSGBrush
void CSGBrush::_regen_face_aabbs() {
-
for (int i = 0; i < faces.size(); i++) {
faces.write[i].aabb = AABB();
faces.write[i].aabb.position = faces[i].vertices[0];
@@ -180,7 +187,6 @@ void CSGBrush::_regen_face_aabbs() {
}
void CSGBrush::build_from_faces(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials, const Vector<bool> &p_invert_faces) {
-
faces.clear();
int vc = p_vertices.size();
@@ -202,7 +208,6 @@ void CSGBrush::build_from_faces(const Vector<Vector3> &p_vertices, const Vector<
faces.resize(p_vertices.size() / 3);
for (int i = 0; i < faces.size(); i++) {
-
Face &f = faces.write[i];
f.vertices[0] = rv[i * 3 + 0];
f.vertices[1] = rv[i * 3 + 1];
@@ -214,21 +219,21 @@ void CSGBrush::build_from_faces(const Vector<Vector3> &p_vertices, const Vector<
f.uvs[2] = ruv[i * 3 + 2];
}
- if (sc == vc / 3)
+ if (sc == vc / 3) {
f.smooth = rs[i];
- else
+ } else {
f.smooth = false;
+ }
- if (ic == vc / 3)
+ if (ic == vc / 3) {
f.invert = ri[i];
- else
+ } else {
f.invert = false;
+ }
if (mc == vc / 3) {
-
Ref<Material> mat = rm[i];
if (mat.is_valid()) {
-
const Map<Ref<Material>, int>::Element *E = material_map.find(mat);
if (E) {
@@ -253,7 +258,6 @@ void CSGBrush::build_from_faces(const Vector<Vector3> &p_vertices, const Vector<
}
void CSGBrush::copy_from(const CSGBrush &p_brush, const Transform &p_xform) {
-
faces = p_brush.faces;
materials = p_brush.materials;
@@ -269,7 +273,6 @@ void CSGBrush::copy_from(const CSGBrush &p_brush, const Transform &p_xform) {
// CSGBrushOperation
void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_brush_a, const CSGBrush &p_brush_b, CSGBrush &r_merged_brush, float p_vertex_snap) {
-
// Check for face collisions and add necessary faces.
Build2DFaceCollection build2DFaceCollection;
for (int i = 0; i < p_brush_a.faces.size(); i++) {
@@ -285,7 +288,6 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b
mesh_merge.vertex_snap = p_vertex_snap;
for (int i = 0; i < p_brush_a.faces.size(); i++) {
-
Ref<Material> material;
if (p_brush_a.faces[i].material != -1) {
material = p_brush_a.materials[p_brush_a.faces[i].material];
@@ -305,7 +307,6 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b
}
for (int i = 0; i < p_brush_b.faces.size(); i++) {
-
Ref<Material> material;
if (p_brush_b.faces[i].material != -1) {
material = p_brush_b.materials[p_brush_b.faces[i].material];
@@ -331,14 +332,13 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b
r_merged_brush.faces.clear();
switch (p_operation) {
-
case OPERATION_UNION: {
-
int outside_count = 0;
for (int i = 0; i < mesh_merge.faces.size(); i++) {
- if (mesh_merge.faces[i].inside)
+ if (mesh_merge.faces[i].inside) {
continue;
+ }
outside_count++;
}
@@ -347,9 +347,9 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b
outside_count = 0;
for (int i = 0; i < mesh_merge.faces.size(); i++) {
-
- if (mesh_merge.faces[i].inside)
+ if (mesh_merge.faces[i].inside) {
continue;
+ }
for (int j = 0; j < 3; j++) {
r_merged_brush.faces.write[outside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
@@ -367,12 +367,12 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b
} break;
case OPERATION_INTERSECTION: {
-
int inside_count = 0;
for (int i = 0; i < mesh_merge.faces.size(); i++) {
- if (!mesh_merge.faces[i].inside)
+ if (!mesh_merge.faces[i].inside) {
continue;
+ }
inside_count++;
}
@@ -381,9 +381,9 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b
inside_count = 0;
for (int i = 0; i < mesh_merge.faces.size(); i++) {
-
- if (!mesh_merge.faces[i].inside)
+ if (!mesh_merge.faces[i].inside) {
continue;
+ }
for (int j = 0; j < 3; j++) {
r_merged_brush.faces.write[inside_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
@@ -401,14 +401,15 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b
} break;
case OPERATION_SUBSTRACTION: {
-
int face_count = 0;
for (int i = 0; i < mesh_merge.faces.size(); i++) {
- if (mesh_merge.faces[i].from_b && !mesh_merge.faces[i].inside)
+ if (mesh_merge.faces[i].from_b && !mesh_merge.faces[i].inside) {
continue;
- if (!mesh_merge.faces[i].from_b && mesh_merge.faces[i].inside)
+ }
+ if (!mesh_merge.faces[i].from_b && mesh_merge.faces[i].inside) {
continue;
+ }
face_count++;
}
@@ -417,11 +418,12 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b
face_count = 0;
for (int i = 0; i < mesh_merge.faces.size(); i++) {
-
- if (mesh_merge.faces[i].from_b && !mesh_merge.faces[i].inside)
+ if (mesh_merge.faces[i].from_b && !mesh_merge.faces[i].inside) {
continue;
- if (!mesh_merge.faces[i].from_b && mesh_merge.faces[i].inside)
+ }
+ if (!mesh_merge.faces[i].from_b && mesh_merge.faces[i].inside) {
continue;
+ }
for (int j = 0; j < 3; j++) {
r_merged_brush.faces.write[face_count].vertices[j] = mesh_merge.points[mesh_merge.faces[i].points[j]];
@@ -458,7 +460,6 @@ void CSGBrushOperation::merge_brushes(Operation p_operation, const CSGBrush &p_b
#define BVH_LIMIT 8
int CSGBrushOperation::MeshMerge::_create_bvh(FaceBVH *facebvhptr, FaceBVH **facebvhptrptr, int p_from, int p_size, int p_depth, int &r_max_depth, int &r_max_alloc) {
-
if (p_depth > r_max_depth) {
r_max_depth = p_depth;
}
@@ -483,7 +484,6 @@ int CSGBrushOperation::MeshMerge::_create_bvh(FaceBVH *facebvhptr, FaceBVH **fac
int li = aabb.get_longest_axis_index();
switch (li) {
-
case Vector3::AXIS_X: {
SortArray<FaceBVH *, FaceBVHCmpX> sort_x;
sort_x.nth_element(0, p_size, p_size / 2, &facebvhptrptr[p_from]);
@@ -519,18 +519,19 @@ int CSGBrushOperation::MeshMerge::_create_bvh(FaceBVH *facebvhptr, FaceBVH **fac
}
void CSGBrushOperation::MeshMerge::_add_distance(List<real_t> &r_intersectionsA, List<real_t> &r_intersectionsB, bool p_from_B, real_t p_distance) const {
-
List<real_t> &intersections = p_from_B ? r_intersectionsB : r_intersectionsA;
// Check if distance exists.
- for (const List<real_t>::Element *E = intersections.front(); E; E = E->next())
- if (Math::abs(**E - p_distance) < vertex_snap) return;
+ for (const List<real_t>::Element *E = intersections.front(); E; E = E->next()) {
+ if (Math::abs(**E - p_distance) < vertex_snap) {
+ return;
+ }
+ }
intersections.push_back(p_distance);
}
bool CSGBrushOperation::MeshMerge::_bvh_inside(FaceBVH *facebvhptr, int p_max_depth, int p_bvh_first, int p_face_idx) const {
-
Face face = faces[p_face_idx];
Vector3 face_points[3] = {
points[face.points[0]],
@@ -560,22 +561,16 @@ bool CSGBrushOperation::MeshMerge::_bvh_inside(FaceBVH *facebvhptr, int p_max_de
stack[0] = pos;
while (true) {
-
uint32_t node = stack[level] & NODE_IDX_MASK;
const FaceBVH *current_facebvhptr = &(facebvhptr[node]);
bool done = false;
switch (stack[level] >> VISITED_BIT_SHIFT) {
-
case TEST_AABB_BIT: {
-
if (current_facebvhptr->face >= 0) {
-
while (current_facebvhptr) {
-
if (p_face_idx != current_facebvhptr->face &&
current_facebvhptr->aabb.intersects_ray(face_center, face_normal)) {
-
const Face &current_face = faces[current_facebvhptr->face];
Vector3 current_points[3] = {
points[current_face.points[0]],
@@ -589,8 +584,9 @@ bool CSGBrushOperation::MeshMerge::_bvh_inside(FaceBVH *facebvhptr, int p_max_de
if ((current_normal - face_normal).length_squared() < CMP_EPSILON2 &&
is_point_in_triangle(face_center, current_points)) {
// Only add an intersection if checking a B face.
- if (face.from_b)
+ if (face.from_b) {
_add_distance(intersectionsA, intersectionsB, current_face.from_b, 0);
+ }
} else if (ray_intersects_triangle(face_center, face_normal, current_points, CMP_EPSILON, intersection_point)) {
real_t distance = (intersection_point - face_center).length();
_add_distance(intersectionsA, intersectionsB, current_face.from_b, distance);
@@ -607,7 +603,6 @@ bool CSGBrushOperation::MeshMerge::_bvh_inside(FaceBVH *facebvhptr, int p_max_de
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
bool valid = current_facebvhptr->aabb.intersects_ray(face_center, face_normal);
if (!valid) {
@@ -620,7 +615,6 @@ bool CSGBrushOperation::MeshMerge::_bvh_inside(FaceBVH *facebvhptr, int p_max_de
}
case VISIT_LEFT_BIT: {
-
stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = current_facebvhptr->left | TEST_AABB_BIT;
level++;
@@ -628,7 +622,6 @@ bool CSGBrushOperation::MeshMerge::_bvh_inside(FaceBVH *facebvhptr, int p_max_de
}
case VISIT_RIGHT_BIT: {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = current_facebvhptr->right | TEST_AABB_BIT;
level++;
@@ -636,18 +629,19 @@ bool CSGBrushOperation::MeshMerge::_bvh_inside(FaceBVH *facebvhptr, int p_max_de
}
case VISIT_DONE_BIT: {
-
if (level == 0) {
done = true;
break;
- } else
+ } else {
level--;
+ }
continue;
}
}
- if (done)
+ if (done) {
break;
+ }
}
// Inside if face normal intersects other faces an odd number of times.
@@ -655,7 +649,6 @@ bool CSGBrushOperation::MeshMerge::_bvh_inside(FaceBVH *facebvhptr, int p_max_de
}
void CSGBrushOperation::MeshMerge::mark_inside_faces() {
-
// Mark faces that are inside. This helps later do the boolean ops when merging.
// This approach is very brute force with a bunch of optimizations,
// such as BVH and pre AABB intersection test.
@@ -701,8 +694,9 @@ void CSGBrushOperation::MeshMerge::mark_inside_faces() {
AABB intersection_aabb = aabb_a.intersection(aabb_b);
// Check if shape AABBs intersect.
- if (intersection_aabb.size == Vector3())
+ if (intersection_aabb.size == Vector3()) {
return;
+ }
Vector<FaceBVH *> bvhtrvec;
bvhtrvec.resize(faces.size());
@@ -716,21 +710,20 @@ void CSGBrushOperation::MeshMerge::mark_inside_faces() {
_create_bvh(facebvh, bvhptr, 0, faces.size(), 1, max_depth, max_alloc);
for (int i = 0; i < faces.size(); i++) {
-
// Check if face AABB intersects the intersection AABB.
- if (!intersection_aabb.intersects_inclusive(facebvh[i].aabb))
+ if (!intersection_aabb.intersects_inclusive(facebvh[i].aabb)) {
continue;
+ }
- if (_bvh_inside(facebvh, max_depth, max_alloc - 1, i))
+ if (_bvh_inside(facebvh, max_depth, max_alloc - 1, i)) {
faces.write[i].inside = true;
+ }
}
}
void CSGBrushOperation::MeshMerge::add_face(const Vector3 p_points[], const Vector2 p_uvs[], bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b) {
-
int indices[3];
for (int i = 0; i < 3; i++) {
-
VertexKey vk;
vk.x = int((double(p_points[i].x) + double(vertex_snap) * 0.31234) / double(vertex_snap));
vk.y = int((double(p_points[i].y) + double(vertex_snap) * 0.31234) / double(vertex_snap));
@@ -747,8 +740,9 @@ void CSGBrushOperation::MeshMerge::add_face(const Vector3 p_points[], const Vect
}
// Don't add degenerate faces.
- if (indices[0] == indices[2] || indices[0] == indices[1] || indices[1] == indices[2])
+ if (indices[0] == indices[2] || indices[0] == indices[1] || indices[1] == indices[2]) {
return;
+ }
MeshMerge::Face face;
face.from_b = p_from_b;
@@ -778,26 +772,26 @@ void CSGBrushOperation::MeshMerge::add_face(const Vector3 p_points[], const Vect
// CSGBrushOperation::Build2DFaces
int CSGBrushOperation::Build2DFaces::_get_point_idx(const Vector2 &p_point) {
-
for (int vertex_idx = 0; vertex_idx < vertices.size(); ++vertex_idx) {
- if ((p_point - vertices[vertex_idx].point).length_squared() < vertex_snap2)
+ if ((p_point - vertices[vertex_idx].point).length_squared() < vertex_snap2) {
return vertex_idx;
+ }
}
return -1;
}
int CSGBrushOperation::Build2DFaces::_add_vertex(const Vertex2D &p_vertex) {
-
// Check if vertex exists.
int vertex_id = _get_point_idx(p_vertex.point);
- if (vertex_id != -1) return vertex_id;
+ if (vertex_id != -1) {
+ return vertex_id;
+ }
vertices.push_back(p_vertex);
return vertices.size() - 1;
}
void CSGBrushOperation::Build2DFaces::_add_vertex_idx_sorted(Vector<int> &r_vertex_indices, int p_new_vertex_index) {
-
if (p_new_vertex_index >= 0 && r_vertex_indices.find(p_new_vertex_index) == -1) {
ERR_FAIL_COND_MSG(p_new_vertex_index >= vertices.size(), "Invalid vertex index.");
@@ -810,19 +804,21 @@ void CSGBrushOperation::Build2DFaces::_add_vertex_idx_sorted(Vector<int> &r_vert
// The second vertex.
if (r_vertex_indices.size() == 1) {
-
Vector2 first_point = vertices[r_vertex_indices[0]].point;
Vector2 new_point = vertices[p_new_vertex_index].point;
// Sort along the axis with the greatest difference.
int axis = 0;
- if (Math::abs(new_point.x - first_point.x) < Math::abs(new_point.y - first_point.y)) axis = 1;
+ if (Math::abs(new_point.x - first_point.x) < Math::abs(new_point.y - first_point.y)) {
+ axis = 1;
+ }
// Add it to the beginning or the end appropriately.
- if (new_point[axis] < first_point[axis])
+ if (new_point[axis] < first_point[axis]) {
r_vertex_indices.insert(0, p_new_vertex_index);
- else
+ } else {
r_vertex_indices.push_back(p_new_vertex_index);
+ }
return;
}
@@ -834,7 +830,9 @@ void CSGBrushOperation::Build2DFaces::_add_vertex_idx_sorted(Vector<int> &r_vert
// Determine axis being sorted against i.e. the axis with the greatest difference.
int axis = 0;
- if (Math::abs(last_point.x - first_point.x) < Math::abs(last_point.y - first_point.y)) axis = 1;
+ if (Math::abs(last_point.x - first_point.x) < Math::abs(last_point.y - first_point.y)) {
+ axis = 1;
+ }
// Insert the point at the appropriate index.
for (int insert_idx = 0; insert_idx < r_vertex_indices.size(); ++insert_idx) {
@@ -851,13 +849,13 @@ void CSGBrushOperation::Build2DFaces::_add_vertex_idx_sorted(Vector<int> &r_vert
}
void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_indices) {
-
int segments = p_segment_indices.size() - 1;
- if (segments < 2) return;
+ if (segments < 2) {
+ return;
+ }
// Faces around an inner vertex are merged by moving the inner vertex to the first vertex.
for (int sorted_idx = 1; sorted_idx < segments; ++sorted_idx) {
-
int closest_idx = 0;
int inner_idx = p_segment_indices[sorted_idx];
@@ -886,14 +884,15 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_
// Create the new faces.
for (int merge_idx = 0; merge_idx < merge_faces.size(); ++merge_idx) {
-
int outer_edge_idx[2];
outer_edge_idx[0] = merge_faces[merge_idx].vertex_idx[(merge_faces_inner_vertex_idx[merge_idx] + 1) % 3];
outer_edge_idx[1] = merge_faces[merge_idx].vertex_idx[(merge_faces_inner_vertex_idx[merge_idx] + 2) % 3];
// Skip flattened faces.
if (outer_edge_idx[0] == p_segment_indices[closest_idx] ||
- outer_edge_idx[1] == p_segment_indices[closest_idx]) continue;
+ outer_edge_idx[1] == p_segment_indices[closest_idx]) {
+ continue;
+ }
//Don't create degenerate triangles.
Vector2 edge1[2] = {
@@ -921,14 +920,16 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_
// Delete the old faces in reverse index order.
merge_faces_idx.sort();
merge_faces_idx.invert();
- for (int i = 0; i < merge_faces_idx.size(); ++i)
+ for (int i = 0; i < merge_faces_idx.size(); ++i) {
faces.remove(merge_faces_idx[i]);
+ }
- if (degenerate_points.size() == 0) continue;
+ if (degenerate_points.size() == 0) {
+ continue;
+ }
// Split faces using degenerate points.
for (int face_idx = 0; face_idx < faces.size(); ++face_idx) {
-
Face2D face = faces[face_idx];
Vertex2D face_vertices[3] = {
vertices[face.vertex_idx[0]],
@@ -942,7 +943,6 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_
};
for (int point_idx = 0; point_idx < degenerate_points.size(); ++point_idx) {
-
int degenerate_idx = degenerate_points[point_idx];
Vector2 point_2D = vertices[degenerate_idx].point;
@@ -954,11 +954,12 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_
break;
}
}
- if (existing) continue;
+ if (existing) {
+ continue;
+ }
// Check if point is on an each edge.
for (int face_edge_idx = 0; face_edge_idx < 3; ++face_edge_idx) {
-
Vector2 edge_points[2] = {
face_points[face_edge_idx],
face_points[(face_edge_idx + 1) % 3]
@@ -966,7 +967,6 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_
Vector2 closest_point = Geometry::get_closest_point_to_segment_2d(point_2D, edge_points);
if ((closest_point - point_2D).length_squared() < vertex_snap2) {
-
int opposite_vertex_idx = face.vertex_idx[(face_edge_idx + 2) % 3];
// If new vertex snaps to degenerate vertex, just delete this face.
@@ -1004,10 +1004,8 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_
}
void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_segment_points[2], Vector<int> &r_segment_indices) {
-
// For each face.
for (int face_idx = 0; face_idx < faces.size(); ++face_idx) {
-
Face2D face = faces[face_idx];
Vertex2D face_vertices[3] = {
vertices[face.vertex_idx[0]],
@@ -1017,7 +1015,6 @@ void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_s
// Check each edge.
for (int face_edge_idx = 0; face_edge_idx < 3; ++face_edge_idx) {
-
Vector2 edge_points[2] = {
face_vertices[face_edge_idx].point,
face_vertices[(face_edge_idx + 1) % 3].point
@@ -1040,13 +1037,16 @@ void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_s
// Else check if the segment intersects the edge.
if (on_edge || Geometry::segment_intersects_segment_2d(p_segment_points[0], p_segment_points[1], edge_points[0], edge_points[1], &intersection_point)) {
-
// Check if intersection point is an edge point.
if ((intersection_point - edge_points[0]).length_squared() < vertex_snap2 ||
- (intersection_point - edge_points[1]).length_squared() < vertex_snap2) continue;
+ (intersection_point - edge_points[1]).length_squared() < vertex_snap2) {
+ continue;
+ }
// Check if edge exists, by checking if the intersecting segment is parallel to the edge.
- if (are_segements_parallel(p_segment_points, edge_points, vertex_snap2)) continue;
+ if (are_segements_parallel(p_segment_points, edge_points, vertex_snap2)) {
+ continue;
+ }
// Add the intersection point as a new vertex.
Vertex2D new_vertex;
@@ -1075,8 +1075,9 @@ void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_s
// If opposite point is on the segemnt, add its index to segment indices too.
Vector2 closest_point = Geometry::get_closest_point_to_segment_2d(vertices[opposite_vertex_idx].point, p_segment_points);
- if ((closest_point - vertices[opposite_vertex_idx].point).length_squared() < vertex_snap2)
+ if ((closest_point - vertices[opposite_vertex_idx].point).length_squared() < vertex_snap2) {
_add_vertex_idx_sorted(r_segment_indices, opposite_vertex_idx);
+ }
// Create two new faces around the new edge and remove this face.
// The new edge is the last edge.
@@ -1101,11 +1102,9 @@ void CSGBrushOperation::Build2DFaces::_find_edge_intersections(const Vector2 p_s
}
int CSGBrushOperation::Build2DFaces::_insert_point(const Vector2 &p_point) {
-
int new_vertex_idx = -1;
for (int face_idx = 0; face_idx < faces.size(); ++face_idx) {
-
Face2D face = faces[face_idx];
Vertex2D face_vertices[3] = {
vertices[face.vertex_idx[0]],
@@ -1125,14 +1124,14 @@ int CSGBrushOperation::Build2DFaces::_insert_point(const Vector2 &p_point) {
// Check if point is existing face vertex.
for (int i = 0; i < 3; ++i) {
- if ((p_point - face_vertices[i].point).length_squared() < vertex_snap2)
+ if ((p_point - face_vertices[i].point).length_squared() < vertex_snap2) {
return face.vertex_idx[i];
+ }
}
// Check if point is on an each edge.
bool on_edge = false;
for (int face_edge_idx = 0; face_edge_idx < 3; ++face_edge_idx) {
-
Vector2 edge_points[2] = {
points[face_edge_idx],
points[(face_edge_idx + 1) % 3]
@@ -1194,7 +1193,6 @@ int CSGBrushOperation::Build2DFaces::_insert_point(const Vector2 &p_point) {
// If not on an edge, check if the point is inside the face.
if (!on_edge && Geometry::is_point_in_triangle(p_point, face_vertices[0].point, face_vertices[1].point, face_vertices[2].point)) {
-
// Add the point as a new vertex.
Vertex2D new_vertex;
new_vertex.point = p_point;
@@ -1204,7 +1202,6 @@ int CSGBrushOperation::Build2DFaces::_insert_point(const Vector2 &p_point) {
// Create three new faces around this point and remove this face.
// The new vertex is the last vertex.
for (int i = 0; i < 3; ++i) {
-
// Don't create degenerate triangles.
Vector2 edge[2] = { points[i], points[(i + 1) % 3] };
Vector2 new_edge1[2] = { vertices[new_vertex_idx].point, points[i] };
@@ -1231,7 +1228,6 @@ int CSGBrushOperation::Build2DFaces::_insert_point(const Vector2 &p_point) {
}
void CSGBrushOperation::Build2DFaces::insert(const CSGBrush &p_brush, int p_face_idx) {
-
// Find edge points that cross the plane and face points that are in the plane.
// Map those points to 2D.
// Create new faces from those points.
@@ -1240,7 +1236,6 @@ void CSGBrushOperation::Build2DFaces::insert(const CSGBrush &p_brush, int p_face
int points_count = 0;
for (int i = 0; i < 3; i++) {
-
Vector3 point_3D = p_brush.faces[p_face_idx].vertices[i];
if (plane.has_point(point_3D)) {
@@ -1250,13 +1245,14 @@ void CSGBrushOperation::Build2DFaces::insert(const CSGBrush &p_brush, int p_face
points_2D[points_count++] = Vector2(point_2D.x, point_2D.y);
} else {
-
Vector3 next_point_3D = p_brush.faces[p_face_idx].vertices[(i + 1) % 3];
- if (plane.has_point(next_point_3D))
+ if (plane.has_point(next_point_3D)) {
continue; // Next point is in plane, it will be added separately.
- if (plane.is_point_over(point_3D) == plane.is_point_over(next_point_3D))
+ }
+ if (plane.is_point_over(point_3D) == plane.is_point_over(next_point_3D)) {
continue; // Both points on the same side of the plane, ignore.
+ }
// Edge crosses the plane, find and add the intersection point.
Vector3 point_2D;
@@ -1303,7 +1299,6 @@ void CSGBrushOperation::Build2DFaces::insert(const CSGBrush &p_brush, int p_face
}
void CSGBrushOperation::Build2DFaces::addFacesToMesh(MeshMerge &r_mesh_merge, bool p_smooth, bool p_invert, const Ref<Material> &p_material, bool p_from_b) {
-
for (int face_idx = 0; face_idx < faces.size(); ++face_idx) {
Face2D face = faces[face_idx];
Vertex2D fv[3] = {
@@ -1327,7 +1322,6 @@ void CSGBrushOperation::Build2DFaces::addFacesToMesh(MeshMerge &r_mesh_merge, bo
CSGBrushOperation::Build2DFaces::Build2DFaces(const CSGBrush &p_brush, int p_face_idx, float p_vertex_snap2) :
vertex_snap2(p_vertex_snap2 * p_vertex_snap2) {
-
// Convert 3D vertex points to 2D.
Vector3 points_3D[3] = {
p_brush.faces[p_face_idx].vertices[0],
@@ -1356,7 +1350,6 @@ CSGBrushOperation::Build2DFaces::Build2DFaces(const CSGBrush &p_brush, int p_fac
}
void CSGBrushOperation::update_faces(const CSGBrush &p_brush_a, const int p_face_idx_a, const CSGBrush &p_brush_b, const int p_face_idx_b, Build2DFaceCollection &p_collection, float p_vertex_snap) {
-
Vector3 vertices_a[3] = {
p_brush_a.faces[p_face_idx_a].vertices[0],
p_brush_a.faces[p_face_idx_a].vertices[1],
@@ -1384,7 +1377,9 @@ void CSGBrushOperation::update_faces(const CSGBrush &p_brush_a, const int p_face
p_collection.build2DFacesB[p_face_idx_b] = Build2DFaces();
has_degenerate = true;
}
- if (has_degenerate) return;
+ if (has_degenerate) {
+ return;
+ }
// Ensure B has points either side of or in the plane of A.
int in_plane_count = 0, over_count = 0, under_count = 0;
@@ -1392,15 +1387,18 @@ void CSGBrushOperation::update_faces(const CSGBrush &p_brush_a, const int p_face
ERR_FAIL_COND_MSG(plane_a.normal == Vector3(), "Couldn't form plane from Brush A face.");
for (int i = 0; i < 3; i++) {
- if (plane_a.has_point(vertices_b[i]))
+ if (plane_a.has_point(vertices_b[i])) {
in_plane_count++;
- else if (plane_a.is_point_over(vertices_b[i]))
+ } else if (plane_a.is_point_over(vertices_b[i])) {
over_count++;
- else
+ } else {
under_count++;
+ }
}
// If all points under or over the plane, there is no intesection.
- if (over_count == 3 || under_count == 3) return;
+ if (over_count == 3 || under_count == 3) {
+ return;
+ }
// Ensure A has points either side of or in the plane of B.
in_plane_count = 0;
@@ -1410,31 +1408,32 @@ void CSGBrushOperation::update_faces(const CSGBrush &p_brush_a, const int p_face
ERR_FAIL_COND_MSG(plane_b.normal == Vector3(), "Couldn't form plane from Brush B face.");
for (int i = 0; i < 3; i++) {
- if (plane_b.has_point(vertices_a[i]))
+ if (plane_b.has_point(vertices_a[i])) {
in_plane_count++;
- else if (plane_b.is_point_over(vertices_a[i]))
+ } else if (plane_b.is_point_over(vertices_a[i])) {
over_count++;
- else
+ } else {
under_count++;
+ }
}
// If all points under or over the plane, there is no intesection.
- if (over_count == 3 || under_count == 3) return;
+ if (over_count == 3 || under_count == 3) {
+ return;
+ }
// Check for intersection using the SAT theorem.
{
-
// Edge pair cross product combinations.
for (int i = 0; i < 3; i++) {
-
Vector3 axis_a = (vertices_a[i] - vertices_a[(i + 1) % 3]).normalized();
for (int j = 0; j < 3; j++) {
-
Vector3 axis_b = (vertices_b[j] - vertices_b[(j + 1) % 3]).normalized();
Vector3 sep_axis = axis_a.cross(axis_b);
- if (sep_axis == Vector3())
+ if (sep_axis == Vector3()) {
continue; //colineal
+ }
sep_axis.normalize();
real_t min_a = 1e20, max_a = -1e20;
diff --git a/modules/csg/csg.h b/modules/csg/csg.h
index d389cbc283..34ee239c17 100644
--- a/modules/csg/csg.h
+++ b/modules/csg/csg.h
@@ -44,7 +44,6 @@
#include "scene/resources/material.h"
struct CSGBrush {
-
struct Face {
Vector3 vertices[3];
Vector2 uvs[3];
@@ -65,7 +64,6 @@ struct CSGBrush {
};
struct CSGBrushOperation {
-
enum Operation {
OPERATION_UNION,
OPERATION_INTERSECTION,
@@ -75,7 +73,6 @@ struct CSGBrushOperation {
void merge_brushes(Operation p_operation, const CSGBrush &p_brush_a, const CSGBrush &p_brush_b, CSGBrush &r_merged_brush, float p_vertex_snap);
struct MeshMerge {
-
struct Face {
bool from_b;
bool inside;
@@ -156,7 +153,6 @@ struct CSGBrushOperation {
};
struct Build2DFaces {
-
struct Vertex2D {
Vector2 point;
Vector2 uv;
diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp
index fa176cb94e..9fa7dc1340 100644
--- a/modules/csg/csg_gizmos.cpp
+++ b/modules/csg/csg_gizmos.cpp
@@ -33,7 +33,6 @@
///////////
CSGShape3DGizmoPlugin::CSGShape3DGizmoPlugin() {
-
Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/csg", Color(0.0, 0.4, 1, 0.15));
create_material("shape_union_material", gizmo_color);
create_material("shape_union_solid_material", gizmo_color);
@@ -50,68 +49,62 @@ CSGShape3DGizmoPlugin::CSGShape3DGizmoPlugin() {
}
String CSGShape3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_idx) const {
-
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
if (Object::cast_to<CSGSphere3D>(cs)) {
-
return "Radius";
}
if (Object::cast_to<CSGBox3D>(cs)) {
-
static const char *hname[3] = { "Width", "Height", "Depth" };
return hname[p_idx];
}
if (Object::cast_to<CSGCylinder3D>(cs)) {
-
return p_idx == 0 ? "Radius" : "Height";
}
if (Object::cast_to<CSGTorus3D>(cs)) {
-
return p_idx == 0 ? "InnerRadius" : "OuterRadius";
}
return "";
}
-Variant CSGShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
+Variant CSGShape3DGizmoPlugin::get_handle_value(EditorNode3DGizmo *p_gizmo, int p_idx) const {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
if (Object::cast_to<CSGSphere3D>(cs)) {
-
CSGSphere3D *s = Object::cast_to<CSGSphere3D>(cs);
return s->get_radius();
}
if (Object::cast_to<CSGBox3D>(cs)) {
-
CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
switch (p_idx) {
- case 0: return s->get_width();
- case 1: return s->get_height();
- case 2: return s->get_depth();
+ case 0:
+ return s->get_width();
+ case 1:
+ return s->get_height();
+ case 2:
+ return s->get_depth();
}
}
if (Object::cast_to<CSGCylinder3D>(cs)) {
-
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
return p_idx == 0 ? s->get_radius() : s->get_height();
}
if (Object::cast_to<CSGTorus3D>(cs)) {
-
CSGTorus3D *s = Object::cast_to<CSGTorus3D>(cs);
return p_idx == 0 ? s->get_inner_radius() : s->get_outer_radius();
}
return Variant();
}
-void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
+void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Camera3D *p_camera, const Point2 &p_point) {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
Transform gt = cs->get_global_transform();
@@ -124,7 +117,6 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 16384) };
if (Object::cast_to<CSGSphere3D>(cs)) {
-
CSGSphere3D *s = Object::cast_to<CSGSphere3D>(cs);
Vector3 ra, rb;
@@ -134,14 +126,14 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
s->set_radius(d);
}
if (Object::cast_to<CSGBox3D>(cs)) {
-
CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
Vector3 axis;
@@ -153,18 +145,24 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
switch (p_idx) {
- case 0: s->set_width(d * 2); break;
- case 1: s->set_height(d * 2); break;
- case 2: s->set_depth(d * 2); break;
+ case 0:
+ s->set_width(d * 2);
+ break;
+ case 1:
+ s->set_height(d * 2);
+ break;
+ case 2:
+ s->set_depth(d * 2);
+ break;
}
}
if (Object::cast_to<CSGCylinder3D>(cs)) {
-
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
Vector3 axis;
@@ -176,17 +174,18 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
- if (p_idx == 0)
+ if (p_idx == 0) {
s->set_radius(d);
- else if (p_idx == 1)
+ } else if (p_idx == 1) {
s->set_height(d * 2.0);
+ }
}
if (Object::cast_to<CSGTorus3D>(cs)) {
-
CSGTorus3D *s = Object::cast_to<CSGTorus3D>(cs);
Vector3 axis;
@@ -198,17 +197,19 @@ void CSGShape3DGizmoPlugin::set_handle(EditorNode3DGizmo *p_gizmo, int p_idx, Ca
d = Math::stepify(d, Node3DEditor::get_singleton()->get_translate_snap());
}
- if (d < 0.001)
+ if (d < 0.001) {
d = 0.001;
+ }
- if (p_idx == 0)
+ if (p_idx == 0) {
s->set_inner_radius(d);
- else if (p_idx == 1)
+ } else if (p_idx == 1) {
s->set_outer_radius(d);
+ }
}
}
-void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
if (Object::cast_to<CSGSphere3D>(cs)) {
@@ -229,9 +230,15 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx,
CSGBox3D *s = Object::cast_to<CSGBox3D>(cs);
if (p_cancel) {
switch (p_idx) {
- case 0: s->set_width(p_restore); break;
- case 1: s->set_height(p_restore); break;
- case 2: s->set_depth(p_restore); break;
+ case 0:
+ s->set_width(p_restore);
+ break;
+ case 1:
+ s->set_height(p_restore);
+ break;
+ case 2:
+ s->set_depth(p_restore);
+ break;
}
return;
}
@@ -241,9 +248,15 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx,
static const char *method[3] = { "set_width", "set_height", "set_depth" };
float current = 0;
switch (p_idx) {
- case 0: current = s->get_width(); break;
- case 1: current = s->get_height(); break;
- case 2: current = s->get_depth(); break;
+ case 0:
+ current = s->get_width();
+ break;
+ case 1:
+ current = s->get_height();
+ break;
+ case 2:
+ current = s->get_depth();
+ break;
}
ur->add_do_method(s, method[p_idx], current);
@@ -254,10 +267,11 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx,
if (Object::cast_to<CSGCylinder3D>(cs)) {
CSGCylinder3D *s = Object::cast_to<CSGCylinder3D>(cs);
if (p_cancel) {
- if (p_idx == 0)
+ if (p_idx == 0) {
s->set_radius(p_restore);
- else
+ } else {
s->set_height(p_restore);
+ }
return;
}
@@ -278,10 +292,11 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx,
if (Object::cast_to<CSGTorus3D>(cs)) {
CSGTorus3D *s = Object::cast_to<CSGTorus3D>(cs);
if (p_cancel) {
- if (p_idx == 0)
+ if (p_idx == 0) {
s->set_inner_radius(p_restore);
- else
+ } else {
s->set_outer_radius(p_restore);
+ }
return;
}
@@ -299,6 +314,7 @@ void CSGShape3DGizmoPlugin::commit_handle(EditorNode3DGizmo *p_gizmo, int p_idx,
ur->commit_action();
}
}
+
bool CSGShape3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
return Object::cast_to<CSGSphere3D>(p_spatial) || Object::cast_to<CSGBox3D>(p_spatial) || Object::cast_to<CSGCylinder3D>(p_spatial) || Object::cast_to<CSGTorus3D>(p_spatial) || Object::cast_to<CSGMesh3D>(p_spatial) || Object::cast_to<CSGPolygon3D>(p_spatial);
}
@@ -316,7 +332,6 @@ bool CSGShape3DGizmoPlugin::is_selectable_when_hidden() const {
}
void CSGShape3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
-
CSGShape3D *cs = Object::cast_to<CSGShape3D>(p_gizmo->get_spatial_node());
p_gizmo->clear();
diff --git a/modules/csg/csg_gizmos.h b/modules/csg/csg_gizmos.h
index 7763989b2a..48a414d9c7 100644
--- a/modules/csg/csg_gizmos.h
+++ b/modules/csg/csg_gizmos.h
@@ -36,7 +36,6 @@
#include "editor/node_3d_editor_gizmos.h"
class CSGShape3DGizmoPlugin : public EditorNode3DGizmoPlugin {
-
GDCLASS(CSGShape3DGizmoPlugin, EditorNode3DGizmoPlugin);
public:
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index 5557da3014..7df65b04c4 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -32,21 +32,22 @@
#include "scene/3d/path_3d.h"
void CSGShape3D::set_use_collision(bool p_enable) {
-
- if (use_collision == p_enable)
+ if (use_collision == p_enable) {
return;
+ }
use_collision = p_enable;
- if (!is_inside_tree() || !is_root_shape())
+ if (!is_inside_tree() || !is_root_shape()) {
return;
+ }
if (use_collision) {
root_collision_shape.instance();
root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC);
PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
- PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world()->get_space());
+ PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space());
PhysicsServer3D::get_singleton()->body_attach_object_instance_id(root_collision_instance, get_instance_id());
set_collision_layer(collision_layer);
set_collision_mask(collision_mask);
@@ -71,12 +72,10 @@ void CSGShape3D::set_collision_layer(uint32_t p_layer) {
}
uint32_t CSGShape3D::get_collision_layer() const {
-
return collision_layer;
}
void CSGShape3D::set_collision_mask(uint32_t p_mask) {
-
collision_mask = p_mask;
if (root_collision_instance.is_valid()) {
PhysicsServer3D::get_singleton()->body_set_collision_mask(root_collision_instance, p_mask);
@@ -84,42 +83,38 @@ void CSGShape3D::set_collision_mask(uint32_t p_mask) {
}
uint32_t CSGShape3D::get_collision_mask() const {
-
return collision_mask;
}
void CSGShape3D::set_collision_mask_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
bool CSGShape3D::get_collision_mask_bit(int p_bit) const {
-
return get_collision_mask() & (1 << p_bit);
}
void CSGShape3D::set_collision_layer_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_layer();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_layer(mask);
}
bool CSGShape3D::get_collision_layer_bit(int p_bit) const {
-
return get_collision_layer() & (1 << p_bit);
}
bool CSGShape3D::is_root_shape() const {
-
return !parent;
}
@@ -132,9 +127,9 @@ float CSGShape3D::get_snap() const {
}
void CSGShape3D::_make_dirty() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
if (dirty) {
return;
@@ -151,7 +146,6 @@ void CSGShape3D::_make_dirty() {
}
CSGBrush *CSGShape3D::_get_brush() {
-
if (dirty) {
if (brush) {
memdelete(brush);
@@ -161,23 +155,24 @@ CSGBrush *CSGShape3D::_get_brush() {
CSGBrush *n = _build_brush();
for (int i = 0; i < get_child_count(); i++) {
-
CSGShape3D *child = Object::cast_to<CSGShape3D>(get_child(i));
- if (!child)
+ if (!child) {
continue;
- if (!child->is_visible_in_tree())
+ }
+ if (!child->is_visible_in_tree()) {
continue;
+ }
CSGBrush *n2 = child->_get_brush();
- if (!n2)
+ if (!n2) {
continue;
+ }
if (!n) {
n = memnew(CSGBrush);
n->copy_from(*n2, child->get_transform());
} else {
-
CSGBrush *nn = memnew(CSGBrush);
CSGBrush *nn2 = memnew(CSGBrush);
nn2->copy_from(*n2, child->get_transform());
@@ -185,9 +180,15 @@ CSGBrush *CSGShape3D::_get_brush() {
CSGBrushOperation bop;
switch (child->get_operation()) {
- case CSGShape3D::OPERATION_UNION: bop.merge_brushes(CSGBrushOperation::OPERATION_UNION, *n, *nn2, *nn, snap); break;
- case CSGShape3D::OPERATION_INTERSECTION: bop.merge_brushes(CSGBrushOperation::OPERATION_INTERSECTION, *n, *nn2, *nn, snap); break;
- case CSGShape3D::OPERATION_SUBTRACTION: bop.merge_brushes(CSGBrushOperation::OPERATION_SUBSTRACTION, *n, *nn2, *nn, snap); break;
+ case CSGShape3D::OPERATION_UNION:
+ bop.merge_brushes(CSGBrushOperation::OPERATION_UNION, *n, *nn2, *nn, snap);
+ break;
+ case CSGShape3D::OPERATION_INTERSECTION:
+ bop.merge_brushes(CSGBrushOperation::OPERATION_INTERSECTION, *n, *nn2, *nn, snap);
+ break;
+ case CSGShape3D::OPERATION_SUBTRACTION:
+ bop.merge_brushes(CSGBrushOperation::OPERATION_SUBSTRACTION, *n, *nn2, *nn, snap);
+ break;
}
memdelete(n);
memdelete(nn2);
@@ -199,10 +200,11 @@ CSGBrush *CSGShape3D::_get_brush() {
AABB aabb;
for (int i = 0; i < n->faces.size(); i++) {
for (int j = 0; j < 3; j++) {
- if (i == 0 && j == 0)
+ if (i == 0 && j == 0) {
aabb.position = n->faces[i].vertices[j];
- else
+ } else {
aabb.expand_to(n->faces[i].vertices[j]);
+ }
}
}
node_aabb = aabb;
@@ -257,7 +259,6 @@ void CSGShape3D::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTe
void CSGShape3D::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
const tbool bIsOrientationPreserving, const int iFace, const int iVert) {
-
ShapeUpdateSurface &surface = *((ShapeUpdateSurface *)pContext->m_pUserData);
int i = iFace * 3 + iVert;
@@ -274,9 +275,9 @@ void CSGShape3D::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const
}
void CSGShape3D::_update_shape() {
-
- if (parent)
+ if (parent) {
return;
+ }
set_base(RID());
root_mesh.unref(); //byebye root mesh
@@ -296,20 +297,18 @@ void CSGShape3D::_update_shape() {
int mat = n->faces[i].material;
ERR_CONTINUE(mat < -1 || mat >= face_count.size());
int idx = mat == -1 ? face_count.size() - 1 : mat;
- if (n->faces[i].smooth) {
- Plane p(n->faces[i].vertices[0], n->faces[i].vertices[1], n->faces[i].vertices[2]);
+ Plane p(n->faces[i].vertices[0], n->faces[i].vertices[1], n->faces[i].vertices[2]);
- for (int j = 0; j < 3; j++) {
- Vector3 v = n->faces[i].vertices[j];
- Vector3 add;
- if (vec_map.lookup(v, add)) {
- add += p.normal;
- } else {
- add = p.normal;
- }
- vec_map.set(v, add);
+ for (int j = 0; j < 3; j++) {
+ Vector3 v = n->faces[i].vertices[j];
+ Vector3 add;
+ if (vec_map.lookup(v, add)) {
+ add += p.normal;
+ } else {
+ add = p.normal;
}
+ vec_map.set(v, add);
}
face_count.write[idx]++;
@@ -321,7 +320,6 @@ void CSGShape3D::_update_shape() {
//create arrays
for (int i = 0; i < surfaces.size(); i++) {
-
surfaces.write[i].vertices.resize(face_count[i] * 3);
surfaces.write[i].normals.resize(face_count[i] * 3);
surfaces.write[i].uvs.resize(face_count[i] * 3);
@@ -342,35 +340,36 @@ void CSGShape3D::_update_shape() {
}
}
- //fill arrays
- Vector<Vector3> physics_faces;
- bool fill_physics_faces = false;
+ // Update collision faces.
if (root_collision_shape.is_valid()) {
+ Vector<Vector3> physics_faces;
physics_faces.resize(n->faces.size() * 3);
- fill_physics_faces = true;
- }
+ Vector3 *physicsw = physics_faces.ptrw();
- {
- Vector3 *physicsw;
+ for (int i = 0; i < n->faces.size(); i++) {
+ int order[3] = { 0, 1, 2 };
+
+ if (n->faces[i].invert) {
+ SWAP(order[1], order[2]);
+ }
- if (fill_physics_faces) {
- physicsw = physics_faces.ptrw();
+ physicsw[i * 3 + 0] = n->faces[i].vertices[order[0]];
+ physicsw[i * 3 + 1] = n->faces[i].vertices[order[1]];
+ physicsw[i * 3 + 2] = n->faces[i].vertices[order[2]];
}
- for (int i = 0; i < n->faces.size(); i++) {
+ root_collision_shape->set_faces(physics_faces);
+ }
+ //fill arrays
+ {
+ for (int i = 0; i < n->faces.size(); i++) {
int order[3] = { 0, 1, 2 };
if (n->faces[i].invert) {
SWAP(order[1], order[2]);
}
- if (fill_physics_faces) {
- physicsw[i * 3 + 0] = n->faces[i].vertices[order[0]];
- physicsw[i * 3 + 1] = n->faces[i].vertices[order[1]];
- physicsw[i * 3 + 2] = n->faces[i].vertices[order[2]];
- }
-
int mat = n->faces[i].material;
ERR_CONTINUE(mat < -1 || mat >= face_count.size());
int idx = mat == -1 ? face_count.size() - 1 : mat;
@@ -380,7 +379,6 @@ void CSGShape3D::_update_shape() {
Plane p(n->faces[i].vertices[0], n->faces[i].vertices[1], n->faces[i].vertices[2]);
for (int j = 0; j < 3; j++) {
-
Vector3 v = n->faces[i].vertices[j];
Vector3 normal = p.normal;
@@ -390,7 +388,6 @@ void CSGShape3D::_update_shape() {
}
if (n->faces[i].invert) {
-
normal = -normal;
}
@@ -435,8 +432,9 @@ void CSGShape3D::_update_shape() {
have_tangents = genTangSpaceDefault(&msc);
}
- if (surfaces[i].last_added == 0)
+ if (surfaces[i].last_added == 0) {
continue;
+ }
// and convert to surface array
Array array;
@@ -454,12 +452,9 @@ void CSGShape3D::_update_shape() {
root_mesh->surface_set_material(idx, surfaces[i].material);
}
- if (root_collision_shape.is_valid()) {
- root_collision_shape->set_faces(physics_faces);
- }
-
set_base(root_mesh->get_rid());
}
+
AABB CSGShape3D::get_aabb() const {
return node_aabb;
}
@@ -487,14 +482,11 @@ Vector<Vector3> CSGShape3D::get_brush_faces() {
}
Vector<Face3> CSGShape3D::get_faces(uint32_t p_usage_flags) const {
-
return Vector<Face3>();
}
void CSGShape3D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
Node *parentn = get_parent();
if (parentn) {
parent = Object::cast_to<CSGShape3D>(parentn);
@@ -509,7 +501,7 @@ void CSGShape3D::_notification(int p_what) {
root_collision_instance = PhysicsServer3D::get_singleton()->body_create(PhysicsServer3D::BODY_MODE_STATIC);
PhysicsServer3D::get_singleton()->body_set_state(root_collision_instance, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
PhysicsServer3D::get_singleton()->body_add_shape(root_collision_instance, root_collision_shape->get_rid());
- PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world()->get_space());
+ PhysicsServer3D::get_singleton()->body_set_space(root_collision_instance, get_world_3d()->get_space());
PhysicsServer3D::get_singleton()->body_attach_object_instance_id(root_collision_instance, get_instance_id());
set_collision_layer(collision_layer);
set_collision_mask(collision_mask);
@@ -519,23 +511,21 @@ void CSGShape3D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
-
if (parent) {
parent->_make_dirty();
}
}
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
if (parent) {
parent->_make_dirty();
}
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
- if (parent)
+ if (parent) {
parent->_make_dirty();
+ }
parent = nullptr;
if (use_collision && is_root_shape() && root_collision_instance.is_valid()) {
@@ -548,7 +538,6 @@ void CSGShape3D::_notification(int p_what) {
}
void CSGShape3D::set_operation(Operation p_operation) {
-
operation = p_operation;
_make_dirty();
update_gizmo();
@@ -578,7 +567,6 @@ void CSGShape3D::_validate_property(PropertyInfo &property) const {
}
Array CSGShape3D::get_meshes() const {
-
if (root_mesh.is_valid()) {
Array arr;
arr.resize(2);
@@ -589,8 +577,8 @@ Array CSGShape3D::get_meshes() const {
return Array();
}
-void CSGShape3D::_bind_methods() {
+void CSGShape3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_shape"), &CSGShape3D::_update_shape);
ClassDB::bind_method(D_METHOD("is_root_shape"), &CSGShape3D::is_root_shape);
@@ -653,10 +641,10 @@ CSGShape3D::~CSGShape3D() {
brush = nullptr;
}
}
+
//////////////////////////////////
CSGBrush *CSGCombiner3D::_build_brush() {
-
return nullptr; //does not build anything
}
@@ -666,7 +654,6 @@ CSGCombiner3D::CSGCombiner3D() {
/////////////////////
CSGBrush *CSGPrimitive3D::_create_brush_from_arrays(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uv, const Vector<bool> &p_smooth, const Vector<Ref<Material>> &p_materials) {
-
CSGBrush *brush = memnew(CSGBrush);
Vector<bool> invert;
@@ -684,7 +671,6 @@ CSGBrush *CSGPrimitive3D::_create_brush_from_arrays(const Vector<Vector3> &p_ver
}
void CSGPrimitive3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_invert_faces", "invert_faces"), &CSGPrimitive3D::set_invert_faces);
ClassDB::bind_method(D_METHOD("is_inverting_faces"), &CSGPrimitive3D::is_inverting_faces);
@@ -692,8 +678,9 @@ void CSGPrimitive3D::_bind_methods() {
}
void CSGPrimitive3D::set_invert_faces(bool p_invert) {
- if (invert_faces == p_invert)
+ if (invert_faces == p_invert) {
return;
+ }
invert_faces = p_invert;
@@ -711,9 +698,9 @@ CSGPrimitive3D::CSGPrimitive3D() {
/////////////////////
CSGBrush *CSGMesh3D::_build_brush() {
-
- if (!mesh.is_valid())
+ if (!mesh.is_valid()) {
return nullptr;
+ }
Vector<Vector3> vertices;
Vector<bool> smooth;
@@ -722,7 +709,6 @@ CSGBrush *CSGMesh3D::_build_brush() {
Ref<Material> material = get_material();
for (int i = 0; i < mesh->get_surface_count(); i++) {
-
if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
continue;
}
@@ -735,8 +721,9 @@ CSGBrush *CSGMesh3D::_build_brush() {
}
Vector<Vector3> avertices = arrays[Mesh::ARRAY_VERTEX];
- if (avertices.size() == 0)
+ if (avertices.size() == 0) {
continue;
+ }
const Vector3 *vr = avertices.ptr();
@@ -777,7 +764,6 @@ CSGBrush *CSGMesh3D::_build_brush() {
const int *ir = aindices.ptr();
for (int j = 0; j < is; j += 3) {
-
Vector3 vertex[3];
Vector3 normal[3];
Vector2 uv[3];
@@ -821,7 +807,6 @@ CSGBrush *CSGMesh3D::_build_brush() {
Ref<Material> *mw = materials.ptrw();
for (int j = 0; j < is; j += 3) {
-
Vector3 vertex[3];
Vector3 normal[3];
Vector2 uv[3];
@@ -852,8 +837,9 @@ CSGBrush *CSGMesh3D::_build_brush() {
}
}
- if (vertices.size() == 0)
+ if (vertices.size() == 0) {
return nullptr;
+ }
return _create_brush_from_arrays(vertices, uvs, smooth, materials);
}
@@ -864,19 +850,18 @@ void CSGMesh3D::_mesh_changed() {
}
void CSGMesh3D::set_material(const Ref<Material> &p_material) {
- if (material == p_material)
+ if (material == p_material) {
return;
+ }
material = p_material;
_make_dirty();
}
Ref<Material> CSGMesh3D::get_material() const {
-
return material;
}
void CSGMesh3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &CSGMesh3D::set_mesh);
ClassDB::bind_method(D_METHOD("get_mesh"), &CSGMesh3D::get_mesh);
@@ -888,9 +873,9 @@ void CSGMesh3D::_bind_methods() {
}
void CSGMesh3D::set_mesh(const Ref<Mesh> &p_mesh) {
-
- if (mesh == p_mesh)
+ if (mesh == p_mesh) {
return;
+ }
if (mesh.is_valid()) {
mesh->disconnect("changed", callable_mp(this, &CSGMesh3D::_mesh_changed));
}
@@ -910,7 +895,6 @@ Ref<Mesh> CSGMesh3D::get_mesh() {
////////////////////////////////
CSGBrush *CSGSphere3D::_build_brush() {
-
// set our bounding box
CSGBrush *brush = memnew(CSGBrush);
@@ -934,7 +918,6 @@ CSGBrush *CSGSphere3D::_build_brush() {
invert.resize(face_count);
{
-
Vector3 *facesw = faces.ptrw();
Vector2 *uvsw = uvs.ptrw();
bool *smoothw = smooth.ptrw();
@@ -955,7 +938,6 @@ CSGBrush *CSGSphere3D::_build_brush() {
double u1 = double(i) / rings;
for (int j = radial_segments; j >= 1; j--) {
-
double lng0 = 2 * Math_PI * (double)(j - 1) / radial_segments;
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
@@ -982,7 +964,6 @@ CSGBrush *CSGSphere3D::_build_brush() {
};
if (i < rings) {
-
//face 1
facesw[face * 3 + 0] = v[0];
facesw[face * 3 + 1] = v[1];
@@ -1092,13 +1073,11 @@ bool CSGSphere3D::get_smooth_faces() const {
}
void CSGSphere3D::set_material(const Ref<Material> &p_material) {
-
material = p_material;
_make_dirty();
}
Ref<Material> CSGSphere3D::get_material() const {
-
return material;
}
@@ -1113,7 +1092,6 @@ CSGSphere3D::CSGSphere3D() {
///////////////
CSGBrush *CSGBox3D::_build_brush() {
-
// set our bounding box
CSGBrush *brush = memnew(CSGBrush);
@@ -1137,7 +1115,6 @@ CSGBrush *CSGBox3D::_build_brush() {
invert.resize(face_count);
{
-
Vector3 *facesw = faces.ptrw();
Vector2 *uvsw = uvs.ptrw();
bool *smoothw = smooth.ptrw();
@@ -1149,25 +1126,22 @@ CSGBrush *CSGBox3D::_build_brush() {
Vector3 vertex_mul(width * 0.5, height * 0.5, depth * 0.5);
{
-
for (int i = 0; i < 6; i++) {
-
Vector3 face_points[4];
float uv_points[8] = { 0, 0, 0, 1, 1, 1, 1, 0 };
for (int j = 0; j < 4; j++) {
-
float v[3];
v[0] = 1.0;
v[1] = 1 - 2 * ((j >> 1) & 1);
v[2] = v[1] * (1 - 2 * (j & 1));
for (int k = 0; k < 3; k++) {
-
- if (i < 3)
+ if (i < 3) {
face_points[j][(i + k) % 3] = v[k];
- else
+ } else {
face_points[3 - j][(i + k) % 3] = -v[k];
+ }
}
}
@@ -1270,14 +1244,12 @@ float CSGBox3D::get_depth() const {
}
void CSGBox3D::set_material(const Ref<Material> &p_material) {
-
material = p_material;
_make_dirty();
update_gizmo();
}
Ref<Material> CSGBox3D::get_material() const {
-
return material;
}
@@ -1291,7 +1263,6 @@ CSGBox3D::CSGBox3D() {
///////////////
CSGBrush *CSGCylinder3D::_build_brush() {
-
// set our bounding box
CSGBrush *brush = memnew(CSGBrush);
@@ -1315,7 +1286,6 @@ CSGBrush *CSGCylinder3D::_build_brush() {
invert.resize(face_count);
{
-
Vector3 *facesw = faces.ptrw();
Vector2 *uvsw = uvs.ptrw();
bool *smoothw = smooth.ptrw();
@@ -1327,9 +1297,7 @@ CSGBrush *CSGCylinder3D::_build_brush() {
Vector3 vertex_mul(radius, height * 0.5, radius);
{
-
for (int i = 0; i < sides; i++) {
-
float inc = float(i) / sides;
float inc_n = float((i + 1)) / sides;
@@ -1506,13 +1474,11 @@ bool CSGCylinder3D::get_smooth_faces() const {
}
void CSGCylinder3D::set_material(const Ref<Material> &p_material) {
-
material = p_material;
_make_dirty();
}
Ref<Material> CSGCylinder3D::get_material() const {
-
return material;
}
@@ -1528,14 +1494,14 @@ CSGCylinder3D::CSGCylinder3D() {
///////////////
CSGBrush *CSGTorus3D::_build_brush() {
-
// set our bounding box
float min_radius = inner_radius;
float max_radius = outer_radius;
- if (min_radius == max_radius)
+ if (min_radius == max_radius) {
return nullptr; //sorry, can't
+ }
if (min_radius > max_radius) {
SWAP(min_radius, max_radius);
@@ -1564,7 +1530,6 @@ CSGBrush *CSGTorus3D::_build_brush() {
invert.resize(face_count);
{
-
Vector3 *facesw = faces.ptrw();
Vector2 *uvsw = uvs.ptrw();
bool *smoothw = smooth.ptrw();
@@ -1574,9 +1539,7 @@ CSGBrush *CSGTorus3D::_build_brush() {
int face = 0;
{
-
for (int i = 0; i < sides; i++) {
-
float inci = float(i) / sides;
float inci_n = float((i + 1)) / sides;
@@ -1587,7 +1550,6 @@ CSGBrush *CSGTorus3D::_build_brush() {
Vector3 normali_n = Vector3(Math::cos(angi_n), 0, Math::sin(angi_n));
for (int j = 0; j < ring_sides; j++) {
-
float incj = float(j) / ring_sides;
float incj_n = float((j + 1)) / ring_sides;
@@ -1734,13 +1696,11 @@ bool CSGTorus3D::get_smooth_faces() const {
}
void CSGTorus3D::set_material(const Ref<Material> &p_material) {
-
material = p_material;
_make_dirty();
}
Ref<Material> CSGTorus3D::get_material() const {
-
return material;
}
@@ -1756,11 +1716,11 @@ CSGTorus3D::CSGTorus3D() {
///////////////
CSGBrush *CSGPolygon3D::_build_brush() {
-
// set our bounding box
- if (polygon.size() < 3)
+ if (polygon.size() < 3) {
return nullptr;
+ }
Vector<Point2> final_polygon = polygon;
@@ -1770,8 +1730,9 @@ CSGBrush *CSGPolygon3D::_build_brush() {
Vector<int> triangles = Geometry::triangulate_polygon(final_polygon);
- if (triangles.size() < 3)
+ if (triangles.size() < 3) {
return nullptr;
+ }
Path3D *path = nullptr;
Ref<Curve3D> curve;
@@ -1785,24 +1746,35 @@ CSGBrush *CSGPolygon3D::_build_brush() {
final_polygon_min = p;
final_polygon_max = final_polygon_min;
} else {
- if (p.x < final_polygon_min.x) final_polygon_min.x = p.x;
- if (p.y < final_polygon_min.y) final_polygon_min.y = p.y;
+ if (p.x < final_polygon_min.x) {
+ final_polygon_min.x = p.x;
+ }
+ if (p.y < final_polygon_min.y) {
+ final_polygon_min.y = p.y;
+ }
- if (p.x > final_polygon_max.x) final_polygon_max.x = p.x;
- if (p.y > final_polygon_max.y) final_polygon_max.y = p.y;
+ if (p.x > final_polygon_max.x) {
+ final_polygon_max.x = p.x;
+ }
+ if (p.y > final_polygon_max.y) {
+ final_polygon_max.y = p.y;
+ }
}
}
Vector2 final_polygon_size = final_polygon_max - final_polygon_min;
if (mode == MODE_PATH) {
- if (!has_node(path_node))
+ if (!has_node(path_node)) {
return nullptr;
+ }
Node *n = get_node(path_node);
- if (!n)
+ if (!n) {
return nullptr;
+ }
path = Object::cast_to<Path3D>(n);
- if (!path)
+ if (!path) {
return nullptr;
+ }
if (path != path_cache) {
if (path_cache) {
@@ -1818,18 +1790,24 @@ CSGBrush *CSGPolygon3D::_build_brush() {
path_cache = nullptr;
}
curve = path->get_curve();
- if (curve.is_null())
+ if (curve.is_null()) {
return nullptr;
- if (curve->get_baked_length() <= 0)
+ }
+ if (curve->get_baked_length() <= 0) {
return nullptr;
+ }
}
CSGBrush *brush = memnew(CSGBrush);
int face_count = 0;
switch (mode) {
- case MODE_DEPTH: face_count = triangles.size() * 2 / 3 + (final_polygon.size()) * 2; break;
- case MODE_SPIN: face_count = (spin_degrees < 360 ? triangles.size() * 2 / 3 : 0) + (final_polygon.size()) * 2 * spin_sides; break;
+ case MODE_DEPTH:
+ face_count = triangles.size() * 2 / 3 + (final_polygon.size()) * 2;
+ break;
+ case MODE_SPIN:
+ face_count = (spin_degrees < 360 ? triangles.size() * 2 / 3 : 0) + (final_polygon.size()) * 2 * spin_sides;
+ break;
case MODE_PATH: {
float bl = curve->get_baked_length();
int splits = MAX(2, Math::ceil(bl / path_interval));
@@ -1859,7 +1837,6 @@ CSGBrush *CSGPolygon3D::_build_brush() {
AABB aabb; //must be computed
{
-
Vector3 *facesw = faces.ptrw();
Vector2 *uvsw = uvs.ptrw();
bool *smoothw = smooth.ptrw();
@@ -1870,10 +1847,8 @@ CSGBrush *CSGPolygon3D::_build_brush() {
switch (mode) {
case MODE_DEPTH: {
-
//add triangles, front and back
for (int i = 0; i < 2; i++) {
-
for (int j = 0; j < triangles.size(); j += 3) {
for (int k = 0; k < 3; k++) {
int src[3] = { 0, i == 0 ? 1 : 2, i == 0 ? 2 : 1 };
@@ -1898,7 +1873,6 @@ CSGBrush *CSGPolygon3D::_build_brush() {
//add triangles for depth
for (int i = 0; i < final_polygon.size(); i++) {
-
int i_n = (i + 1) % final_polygon.size();
Vector3 v[4] = {
@@ -1948,9 +1922,7 @@ CSGBrush *CSGPolygon3D::_build_brush() {
} break;
case MODE_SPIN: {
-
for (int i = 0; i < spin_sides; i++) {
-
float inci = float(i) / spin_sides;
float inci_n = float((i + 1)) / spin_sides;
@@ -1962,7 +1934,6 @@ CSGBrush *CSGPolygon3D::_build_brush() {
//add triangles for depth
for (int j = 0; j < final_polygon.size(); j++) {
-
int j_n = (j + 1) % final_polygon.size();
Vector3 v[4] = {
@@ -2011,7 +1982,6 @@ CSGBrush *CSGPolygon3D::_build_brush() {
}
if (i == 0 && spin_degrees < 360) {
-
for (int j = 0; j < triangles.size(); j += 3) {
for (int k = 0; k < 3; k++) {
int src[3] = { 0, 2, 1 };
@@ -2029,7 +1999,6 @@ CSGBrush *CSGPolygon3D::_build_brush() {
}
if (i == spin_sides - 1 && spin_degrees < 360) {
-
for (int j = 0; j < triangles.size(); j += 3) {
for (int k = 0; k < 3; k++) {
int src[3] = { 0, 1, 2 };
@@ -2049,7 +2018,6 @@ CSGBrush *CSGPolygon3D::_build_brush() {
}
} break;
case MODE_PATH: {
-
float bl = curve->get_baked_length();
int splits = MAX(2, Math::ceil(bl / path_interval));
float u1 = 0.0;
@@ -2075,7 +2043,6 @@ CSGBrush *CSGPolygon3D::_build_brush() {
}
for (int i = 0; i <= splits; i++) {
-
float ofs = i * path_interval;
if (ofs > bl) {
ofs = bl;
@@ -2115,7 +2082,6 @@ CSGBrush *CSGPolygon3D::_build_brush() {
//put triangles where they belong
//add triangles for depth
for (int j = 0; j < final_polygon.size(); j++) {
-
int j_n = (j + 1) % final_polygon.size();
Vector3 v[4] = {
@@ -2165,7 +2131,6 @@ CSGBrush *CSGPolygon3D::_build_brush() {
}
if (i == 0 && !path_joined) {
-
for (int j = 0; j < triangles.size(); j += 3) {
for (int k = 0; k < 3; k++) {
int src[3] = { 0, 1, 2 };
@@ -2183,7 +2148,6 @@ CSGBrush *CSGPolygon3D::_build_brush() {
}
if (i == splits && !path_joined) {
-
for (int j = 0; j < triangles.size(); j += 3) {
for (int k = 0; k < 3; k++) {
int src[3] = { 0, 2, 1 };
@@ -2405,6 +2369,7 @@ void CSGPolygon3D::set_path_interval(float p_interval) {
_make_dirty();
update_gizmo();
}
+
float CSGPolygon3D::get_path_interval() const {
return path_interval;
}
@@ -2449,13 +2414,11 @@ bool CSGPolygon3D::get_smooth_faces() const {
}
void CSGPolygon3D::set_material(const Ref<Material> &p_material) {
-
material = p_material;
_make_dirty();
}
Ref<Material> CSGPolygon3D::get_material() const {
-
return material;
}
diff --git a/modules/csg/csg_shape.h b/modules/csg/csg_shape.h
index abab1ded20..7e95d685c5 100644
--- a/modules/csg/csg_shape.h
+++ b/modules/csg/csg_shape.h
@@ -204,7 +204,6 @@ public:
};
class CSGSphere3D : public CSGPrimitive3D {
-
GDCLASS(CSGSphere3D, CSGPrimitive3D);
virtual CSGBrush *_build_brush();
@@ -237,7 +236,6 @@ public:
};
class CSGBox3D : public CSGPrimitive3D {
-
GDCLASS(CSGBox3D, CSGPrimitive3D);
virtual CSGBrush *_build_brush();
@@ -266,7 +264,6 @@ public:
};
class CSGCylinder3D : public CSGPrimitive3D {
-
GDCLASS(CSGCylinder3D, CSGPrimitive3D);
virtual CSGBrush *_build_brush();
@@ -303,7 +300,6 @@ public:
};
class CSGTorus3D : public CSGPrimitive3D {
-
GDCLASS(CSGTorus3D, CSGPrimitive3D);
virtual CSGBrush *_build_brush();
@@ -340,7 +336,6 @@ public:
};
class CSGPolygon3D : public CSGPrimitive3D {
-
GDCLASS(CSGPolygon3D, CSGPrimitive3D);
public:
diff --git a/modules/csg/register_types.cpp b/modules/csg/register_types.cpp
index 40eef84b1b..a8bcc2fed1 100644
--- a/modules/csg/register_types.cpp
+++ b/modules/csg/register_types.cpp
@@ -34,7 +34,6 @@
#include "csg_shape.h"
void register_csg_types() {
-
#ifndef _3D_DISABLED
ClassDB::register_virtual_class<CSGShape3D>();
diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp
index 9dbaa88202..2a4f836478 100644
--- a/modules/cvtt/image_compress_cvtt.cpp
+++ b/modules/cvtt/image_compress_cvtt.cpp
@@ -137,9 +137,9 @@ static void _digest_job_queue(void *p_job_queue) {
}
void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels) {
-
- if (p_image->get_format() >= Image::FORMAT_BPTC_RGBA)
+ if (p_image->get_format() >= Image::FORMAT_BPTC_RGBA) {
return; //do not compress, already compressed
+ }
int w = p_image->get_width();
int h = p_image->get_height();
@@ -154,16 +154,17 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChann
cvtt::Options options;
uint32_t flags = cvtt::Flags::Fastest;
- if (p_lossy_quality > 0.85)
+ if (p_lossy_quality > 0.85) {
flags = cvtt::Flags::Ultra;
- else if (p_lossy_quality > 0.75)
+ } else if (p_lossy_quality > 0.75) {
flags = cvtt::Flags::Better;
- else if (p_lossy_quality > 0.55)
+ } else if (p_lossy_quality > 0.55) {
flags = cvtt::Flags::Default;
- else if (p_lossy_quality > 0.35)
+ } else if (p_lossy_quality > 0.35) {
flags = cvtt::Flags::Fast;
- else if (p_lossy_quality > 0.15)
+ } else if (p_lossy_quality > 0.15) {
flags = cvtt::Flags::Faster;
+ }
flags |= cvtt::Flags::BC7_RespectPunchThrough;
@@ -222,7 +223,6 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChann
Vector<CVTTCompressionRowTask> tasks;
for (int i = 0; i <= mm_count; i++) {
-
int bw = w % 4 != 0 ? w + (4 - w % 4) : w;
int bh = h % 4 != 0 ? h + (4 - h % 4) : h;
@@ -280,7 +280,6 @@ void image_compress_cvtt(Image *p_image, float p_lossy_quality, Image::UsedChann
}
void image_decompress_cvtt(Image *p_image) {
-
Image::Format target_format;
bool is_signed = false;
bool is_hdr = false;
@@ -318,7 +317,6 @@ void image_decompress_cvtt(Image *p_image) {
int dst_ofs = 0;
for (int i = 0; i <= mm_count; i++) {
-
int src_ofs = p_image->get_mipmap_offset(i);
const uint8_t *in_bytes = &rb[src_ofs];
diff --git a/modules/cvtt/register_types.cpp b/modules/cvtt/register_types.cpp
index 38542a33b9..e4a01cc787 100644
--- a/modules/cvtt/register_types.cpp
+++ b/modules/cvtt/register_types.cpp
@@ -35,7 +35,6 @@
#include "image_compress_cvtt.h"
void register_cvtt_types() {
-
Image::set_compress_bptc_func(image_compress_cvtt);
Image::_image_decompress_bptc = image_decompress_cvtt;
}
diff --git a/modules/dds/register_types.cpp b/modules/dds/register_types.cpp
index c6281ff01b..3991964a28 100644
--- a/modules/dds/register_types.cpp
+++ b/modules/dds/register_types.cpp
@@ -35,13 +35,11 @@
static Ref<ResourceFormatDDS> resource_loader_dds;
void register_dds_types() {
-
resource_loader_dds.instance();
ResourceLoader::add_resource_format_loader(resource_loader_dds);
}
void unregister_dds_types() {
-
ResourceLoader::remove_resource_format_loader(resource_loader_dds);
resource_loader_dds.unref();
}
diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp
index ae21156b8b..ba425371a8 100644
--- a/modules/dds/texture_loader_dds.cpp
+++ b/modules/dds/texture_loader_dds.cpp
@@ -94,19 +94,21 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = {
{ "GRAYSCALE_ALPHA", false, false, 1, 2, Image::FORMAT_LA8 }
};
-RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
- if (r_error)
+RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_CANT_OPEN;
+ }
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
- if (!f)
+ if (!f) {
return RES();
+ }
FileAccessRef fref(f);
- if (r_error)
+ if (r_error) {
*r_error = ERR_FILE_CORRUPT;
+ }
ERR_FAIL_COND_V_MSG(err != OK, RES(), "Unable to open DDS texture file '" + p_path + "'.");
@@ -120,13 +122,13 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
uint32_t mipmaps = f->get_32();
//skip 11
- for (int i = 0; i < 11; i++)
+ for (int i = 0; i < 11; i++) {
f->get_32();
+ }
//validate
if (magic != DDS_MAGIC || hsize != 124 || !(flags & DDSD_PIXELFORMAT) || !(flags & DDSD_CAPS)) {
-
ERR_FAIL_V_MSG(RES(), "Invalid or unsupported DDS texture file '" + p_path + "'.");
}
@@ -157,70 +159,55 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
*/
//must avoid this later
- while (f->get_position() < 128)
+ while (f->get_position() < 128) {
f->get_8();
+ }
DDSFormat dds_format;
if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("DXT1")) {
-
dds_format = DDS_DXT1;
} else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("DXT3")) {
-
dds_format = DDS_DXT3;
} else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("DXT5")) {
-
dds_format = DDS_DXT5;
} else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("ATI1")) {
-
dds_format = DDS_ATI1;
} else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("ATI2")) {
-
dds_format = DDS_ATI2;
} else if (format_flags & DDPF_FOURCC && format_fourcc == PF_FOURCC("A2XY")) {
-
dds_format = DDS_A2XY;
} else if (format_flags & DDPF_RGB && format_flags & DDPF_ALPHAPIXELS && format_rgb_bits == 32 && format_red_mask == 0xff0000 && format_green_mask == 0xff00 && format_blue_mask == 0xff && format_alpha_mask == 0xff000000) {
-
dds_format = DDS_BGRA8;
} else if (format_flags & DDPF_RGB && !(format_flags & DDPF_ALPHAPIXELS) && format_rgb_bits == 24 && format_red_mask == 0xff0000 && format_green_mask == 0xff00 && format_blue_mask == 0xff) {
-
dds_format = DDS_BGR8;
} else if (format_flags & DDPF_RGB && format_flags & DDPF_ALPHAPIXELS && format_rgb_bits == 32 && format_red_mask == 0xff && format_green_mask == 0xff00 && format_blue_mask == 0xff0000 && format_alpha_mask == 0xff000000) {
-
dds_format = DDS_RGBA8;
} else if (format_flags & DDPF_RGB && !(format_flags & DDPF_ALPHAPIXELS) && format_rgb_bits == 24 && format_red_mask == 0xff && format_green_mask == 0xff00 && format_blue_mask == 0xff0000) {
-
dds_format = DDS_RGB8;
} else if (format_flags & DDPF_RGB && format_flags & DDPF_ALPHAPIXELS && format_rgb_bits == 16 && format_red_mask == 0x00007c00 && format_green_mask == 0x000003e0 && format_blue_mask == 0x0000001f && format_alpha_mask == 0x00008000) {
-
dds_format = DDS_BGR5A1;
} else if (format_flags & DDPF_RGB && format_flags & DDPF_ALPHAPIXELS && format_rgb_bits == 32 && format_red_mask == 0x3ff00000 && format_green_mask == 0xffc00 && format_blue_mask == 0x3ff && format_alpha_mask == 0xc0000000) {
-
dds_format = DDS_BGR10A2;
} else if (format_flags & DDPF_RGB && !(format_flags & DDPF_ALPHAPIXELS) && format_rgb_bits == 16 && format_red_mask == 0x0000f800 && format_green_mask == 0x000007e0 && format_blue_mask == 0x0000001f) {
-
dds_format = DDS_BGR565;
} else if (!(format_flags & DDPF_ALPHAPIXELS) && format_rgb_bits == 8 && format_red_mask == 0xff && format_green_mask == 0xff && format_blue_mask == 0xff) {
-
dds_format = DDS_LUMINANCE;
} else if ((format_flags & DDPF_ALPHAPIXELS) && format_rgb_bits == 16 && format_red_mask == 0xff && format_green_mask == 0xff && format_blue_mask == 0xff && format_alpha_mask == 0xff00) {
-
dds_format = DDS_LUMINANCE_ALPHA;
} else if (format_flags & DDPF_INDEXED && format_rgb_bits == 8) {
-
dds_format = DDS_BGR565;
} else {
-
printf("unrecognized fourcc %x format_flags: %x - rgbbits %i - red_mask %x green mask %x blue mask %x alpha mask %x\n", format_fourcc, format_flags, format_rgb_bits, format_red_mask, format_green_mask, format_blue_mask, format_alpha_mask);
ERR_FAIL_V_MSG(RES(), "Unrecognized or unsupported color layout in DDS '" + p_path + "'.");
}
- if (!(flags & DDSD_MIPMAPCOUNT))
+ if (!(flags & DDSD_MIPMAPCOUNT)) {
mipmaps = 1;
+ }
Vector<uint8_t> src_data;
@@ -236,7 +223,6 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
ERR_FAIL_COND_V(!(flags & DDSD_LINEARSIZE), RES());
for (uint32_t i = 1; i < mipmaps; i++) {
-
w = MAX(1, w >> 1);
h = MAX(1, h >> 1);
uint32_t bsize = MAX(info.divisor, w) / info.divisor * MAX(info.divisor, h) / info.divisor * info.block_size;
@@ -249,7 +235,6 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
f->get_buffer(wb, size);
} else if (info.palette) {
-
//indexed
ERR_FAIL_COND_V(!(flags & DDSD_PITCH), RES());
ERR_FAIL_COND_V(format_rgb_bits != 8, RES());
@@ -262,16 +247,15 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
int colsize = 3;
for (int i = 0; i < 256; i++) {
-
- if (palette[i * 4 + 3] < 255)
+ if (palette[i * 4 + 3] < 255) {
colsize = 4;
+ }
}
int w2 = width;
int h2 = height;
for (uint32_t i = 1; i < mipmaps; i++) {
-
w2 = (w2 + 1) >> 1;
h2 = (h2 + 1) >> 1;
size += w2 * h2 * info.block_size;
@@ -282,14 +266,14 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
f->get_buffer(wb, size);
for (int i = 0; i < 256; i++) {
-
int dst_ofs = size + i * colsize;
int src_ofs = i * 4;
wb[dst_ofs + 0] = palette[src_ofs + 2];
wb[dst_ofs + 1] = palette[src_ofs + 1];
wb[dst_ofs + 2] = palette[src_ofs + 0];
- if (colsize == 4)
+ if (colsize == 4) {
wb[dst_ofs + 3] = palette[src_ofs + 3];
+ }
}
} else {
//uncompressed generic...
@@ -297,30 +281,27 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
uint32_t size = width * height * info.block_size;
for (uint32_t i = 1; i < mipmaps; i++) {
-
w = (w + 1) >> 1;
h = (h + 1) >> 1;
size += w * h * info.block_size;
}
- if (dds_format == DDS_BGR565)
+ if (dds_format == DDS_BGR565) {
size = size * 3 / 2;
- else if (dds_format == DDS_BGR5A1)
+ } else if (dds_format == DDS_BGR5A1) {
size = size * 2;
+ }
src_data.resize(size);
uint8_t *wb = src_data.ptrw();
f->get_buffer(wb, size);
switch (dds_format) {
-
case DDS_BGR5A1: {
-
// TO RGBA
int colcount = size / 4;
for (int i = colcount - 1; i >= 0; i--) {
-
int src_ofs = i * 2;
int dst_ofs = i * 4;
@@ -335,11 +316,9 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
}
} break;
case DDS_BGR565: {
-
int colcount = size / 3;
for (int i = colcount - 1; i >= 0; i--) {
-
int src_ofs = i * 2;
int dst_ofs = i * 3;
@@ -353,12 +332,10 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
} break;
case DDS_BGR10A2: {
-
// TO RGBA
int colcount = size / 4;
for (int i = colcount - 1; i >= 0; i--) {
-
int ofs = i * 4;
uint32_t w32 = uint32_t(wb[ofs + 0]) | (uint32_t(wb[ofs + 1]) << 8) | (uint32_t(wb[ofs + 2]) << 16) | (uint32_t(wb[ofs + 3]) << 24);
@@ -375,26 +352,21 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
}
} break;
case DDS_BGRA8: {
-
int colcount = size / 4;
for (int i = 0; i < colcount; i++) {
-
SWAP(wb[i * 4 + 0], wb[i * 4 + 2]);
}
} break;
case DDS_BGR8: {
-
int colcount = size / 3;
for (int i = 0; i < colcount; i++) {
-
SWAP(wb[i * 3 + 0], wb[i * 3 + 2]);
}
} break;
case DDS_RGBA8: {
-
/* do nothing either
int colcount = size/4;
@@ -413,7 +385,6 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
*/
} break;
case DDS_RGB8: {
-
// do nothing
/*
int colcount = size/3;
@@ -424,12 +395,10 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
}*/
} break;
case DDS_LUMINANCE: {
-
// do nothing i guess?
} break;
case DDS_LUMINANCE_ALPHA: {
-
// do nothing i guess?
} break;
@@ -444,25 +413,24 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
Ref<ImageTexture> texture = memnew(ImageTexture);
texture->create_from_image(img);
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return texture;
}
void ResourceFormatDDS::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("dds");
}
bool ResourceFormatDDS::handles_type(const String &p_type) const {
-
return ClassDB::is_parent_class(p_type, "Texture2D");
}
String ResourceFormatDDS::get_resource_type(const String &p_path) const {
-
- if (p_path.get_extension().to_lower() == "dds")
+ if (p_path.get_extension().to_lower() == "dds") {
return "ImageTexture";
+ }
return "";
}
diff --git a/modules/dds/texture_loader_dds.h b/modules/dds/texture_loader_dds.h
index 5b89f16277..ef08967df7 100644
--- a/modules/dds/texture_loader_dds.h
+++ b/modules/dds/texture_loader_dds.h
@@ -36,7 +36,7 @@
class ResourceFormatDDS : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/denoise/SCsub b/modules/denoise/SCsub
new file mode 100644
index 0000000000..0fa65c6296
--- /dev/null
+++ b/modules/denoise/SCsub
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+
+import resource_to_cpp
+from platform_methods import run_in_subprocess
+
+Import("env")
+Import("env_modules")
+
+env_oidn = env_modules.Clone()
+
+# Thirdparty source files
+thirdparty_dir = "#thirdparty/oidn/"
+thirdparty_sources = [
+ "core/api.cpp",
+ "core/device.cpp",
+ "core/filter.cpp",
+ "core/network.cpp",
+ "core/autoencoder.cpp",
+ "core/transfer_function.cpp",
+ "weights/rtlightmap_hdr.gen.cpp",
+ "mkl-dnn/src/common/batch_normalization.cpp",
+ "mkl-dnn/src/common/concat.cpp",
+ "mkl-dnn/src/common/convolution.cpp",
+ "mkl-dnn/src/common/convolution_pd.cpp",
+ "mkl-dnn/src/common/deconvolution.cpp",
+ "mkl-dnn/src/common/eltwise.cpp",
+ "mkl-dnn/src/common/engine.cpp",
+ "mkl-dnn/src/common/inner_product.cpp",
+ "mkl-dnn/src/common/inner_product_pd.cpp",
+ "mkl-dnn/src/common/lrn.cpp",
+ "mkl-dnn/src/common/memory.cpp",
+ "mkl-dnn/src/common/memory_desc_wrapper.cpp",
+ "mkl-dnn/src/common/mkldnn_debug.cpp",
+ "mkl-dnn/src/common/mkldnn_debug_autogenerated.cpp",
+ "mkl-dnn/src/common/pooling.cpp",
+ "mkl-dnn/src/common/primitive.cpp",
+ "mkl-dnn/src/common/primitive_attr.cpp",
+ "mkl-dnn/src/common/primitive_desc.cpp",
+ "mkl-dnn/src/common/primitive_exec_types.cpp",
+ "mkl-dnn/src/common/primitive_iterator.cpp",
+ "mkl-dnn/src/common/query.cpp",
+ "mkl-dnn/src/common/reorder.cpp",
+ "mkl-dnn/src/common/rnn.cpp",
+ "mkl-dnn/src/common/scratchpad.cpp",
+ "mkl-dnn/src/common/shuffle.cpp",
+ "mkl-dnn/src/common/softmax.cpp",
+ "mkl-dnn/src/common/stream.cpp",
+ "mkl-dnn/src/common/sum.cpp",
+ "mkl-dnn/src/common/utils.cpp",
+ "mkl-dnn/src/common/verbose.cpp",
+ "mkl-dnn/src/cpu/cpu_barrier.cpp",
+ "mkl-dnn/src/cpu/cpu_concat.cpp",
+ "mkl-dnn/src/cpu/cpu_engine.cpp",
+ "mkl-dnn/src/cpu/cpu_memory.cpp",
+ "mkl-dnn/src/cpu/cpu_reducer.cpp",
+ "mkl-dnn/src/cpu/cpu_reorder.cpp",
+ "mkl-dnn/src/cpu/cpu_sum.cpp",
+ "mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.cpp",
+ "mkl-dnn/src/cpu/jit_avx2_convolution.cpp",
+ "mkl-dnn/src/cpu/jit_avx512_common_conv_kernel.cpp",
+ "mkl-dnn/src/cpu/jit_avx512_common_conv_winograd_kernel_f32.cpp",
+ "mkl-dnn/src/cpu/jit_avx512_common_convolution.cpp",
+ "mkl-dnn/src/cpu/jit_avx512_common_convolution_winograd.cpp",
+ "mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_2x3.cpp",
+ "mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3.cpp",
+ "mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3_kernel.cpp",
+ "mkl-dnn/src/cpu/jit_sse42_conv_kernel_f32.cpp",
+ "mkl-dnn/src/cpu/jit_sse42_convolution.cpp",
+ "mkl-dnn/src/cpu/jit_transpose_src_utils.cpp",
+ "mkl-dnn/src/cpu/jit_uni_eltwise.cpp",
+ "mkl-dnn/src/cpu/jit_uni_pool_kernel_f32.cpp",
+ "mkl-dnn/src/cpu/jit_uni_pooling.cpp",
+ "mkl-dnn/src/cpu/jit_uni_reorder.cpp",
+ "mkl-dnn/src/cpu/jit_uni_reorder_utils.cpp",
+ "mkl-dnn/src/cpu/jit_utils/jit_utils.cpp",
+ "mkl-dnn/src/cpu/jit_utils/jitprofiling/jitprofiling.c",
+ "common/platform.cpp",
+ "common/thread.cpp",
+ "common/tensor.cpp",
+]
+thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
+
+thirdparty_include_dirs = [
+ "",
+ "include",
+ "mkl-dnn/include",
+ "mkl-dnn/src",
+ "mkl-dnn/src/common",
+ "mkl-dnn/src/cpu/xbyak",
+ "mkl-dnn/src/cpu",
+]
+thirdparty_include_dirs = [thirdparty_dir + file for file in thirdparty_include_dirs]
+
+
+env_oidn.Prepend(CPPPATH=thirdparty_include_dirs)
+env_oidn.Append(
+ CPPDEFINES=[
+ "MKLDNN_THR=MKLDNN_THR_SEQ",
+ "OIDN_STATIC_LIB",
+ "__STDC_CONSTANT_MACROS",
+ "__STDC_LIMIT_MACROS",
+ "DISABLE_VERBOSE",
+ "MKLDNN_ENABLE_CONCURRENT_EXEC",
+ "NDEBUG",
+ ]
+)
+
+env_thirdparty = env_oidn.Clone()
+env_thirdparty.disable_warnings()
+env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
+
+weights_in_path = thirdparty_dir + "weights/rtlightmap_hdr.tza"
+weights_out_path = thirdparty_dir + "weights/rtlightmap_hdr.gen.cpp"
+
+env_thirdparty.Depends(weights_out_path, weights_in_path)
+env_thirdparty.CommandNoCache(weights_out_path, weights_in_path, resource_to_cpp.tza_to_cpp)
+
+env_oidn.add_source_files(env.modules_sources, "denoise_wrapper.cpp")
+env_modules.add_source_files(env.modules_sources, ["register_types.cpp", "lightmap_denoiser.cpp"])
diff --git a/modules/denoise/config.py b/modules/denoise/config.py
new file mode 100644
index 0000000000..53b8f2f2e3
--- /dev/null
+++ b/modules/denoise/config.py
@@ -0,0 +1,6 @@
+def can_build(env, platform):
+ return env["tools"]
+
+
+def configure(env):
+ pass
diff --git a/modules/denoise/denoise_wrapper.cpp b/modules/denoise/denoise_wrapper.cpp
new file mode 100644
index 0000000000..c12c6d9c31
--- /dev/null
+++ b/modules/denoise/denoise_wrapper.cpp
@@ -0,0 +1,64 @@
+/*************************************************************************/
+/* denoise_wrapper.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "denoise_wrapper.h"
+#include "thirdparty/oidn/include/OpenImageDenoise/oidn.h"
+#include <stdio.h>
+
+void *oidn_denoiser_init() {
+ OIDNDeviceImpl *device = oidnNewDevice(OIDN_DEVICE_TYPE_CPU);
+ oidnCommitDevice(device);
+ return device;
+}
+
+bool oidn_denoise(void *deviceptr, float *p_floats, int p_width, int p_height) {
+ OIDNDeviceImpl *device = (OIDNDeviceImpl *)deviceptr;
+ OIDNFilter filter = oidnNewFilter(device, "RTLightmap");
+ oidnSetSharedFilterImage(filter, "color", (void *)p_floats, OIDN_FORMAT_FLOAT3, p_width, p_height, 0, 0, 0);
+ oidnSetSharedFilterImage(filter, "output", (void *)p_floats, OIDN_FORMAT_FLOAT3, p_width, p_height, 0, 0, 0);
+ oidnSetFilter1b(filter, "hdr", true);
+ //oidnSetFilter1f(filter, "hdrScale", 1.0f);
+ oidnCommitFilter(filter);
+ oidnExecuteFilter(filter);
+
+ const char *msg;
+ bool success = true;
+ if (oidnGetDeviceError(device, &msg) != OIDN_ERROR_NONE) {
+ printf("LightmapDenoiser: %s\n", msg);
+ success = false;
+ }
+
+ oidnReleaseFilter(filter);
+ return success;
+}
+
+void oidn_denoiser_finish(void *device) {
+ oidnReleaseDevice((OIDNDeviceImpl *)device);
+}
diff --git a/modules/denoise/denoise_wrapper.h b/modules/denoise/denoise_wrapper.h
new file mode 100644
index 0000000000..2107df09c1
--- /dev/null
+++ b/modules/denoise/denoise_wrapper.h
@@ -0,0 +1,38 @@
+/*************************************************************************/
+/* denoise_wrapper.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef DENOISE_WRAPPER_H
+#define DENOISE_WRAPPER_H
+
+void *oidn_denoiser_init();
+bool oidn_denoise(void *device, float *p_floats, int p_width, int p_height);
+void oidn_denoiser_finish(void *device);
+
+#endif // DENOISE_WRAPPER_H
diff --git a/modules/denoise/lightmap_denoiser.cpp b/modules/denoise/lightmap_denoiser.cpp
new file mode 100644
index 0000000000..29d02e8ee2
--- /dev/null
+++ b/modules/denoise/lightmap_denoiser.cpp
@@ -0,0 +1,62 @@
+/*************************************************************************/
+/* lightmap_denoiser.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "lightmap_denoiser.h"
+#include "denoise_wrapper.h"
+
+LightmapDenoiser *LightmapDenoiserOIDN::create_oidn_denoiser() {
+ return memnew(LightmapDenoiserOIDN);
+}
+
+void LightmapDenoiserOIDN::make_default_denoiser() {
+ create_function = create_oidn_denoiser;
+}
+
+Ref<Image> LightmapDenoiserOIDN::denoise_image(const Ref<Image> &p_image) {
+ Ref<Image> img = p_image->duplicate();
+
+ img->convert(Image::FORMAT_RGBF);
+
+ Vector<uint8_t> data = img->get_data();
+ if (!oidn_denoise(device, (float *)data.ptrw(), img->get_width(), img->get_height())) {
+ return p_image;
+ }
+
+ img->create(img->get_width(), img->get_height(), false, img->get_format(), data);
+ return img;
+}
+
+LightmapDenoiserOIDN::LightmapDenoiserOIDN() {
+ device = oidn_denoiser_init();
+}
+
+LightmapDenoiserOIDN::~LightmapDenoiserOIDN() {
+ oidn_denoiser_finish(device);
+}
diff --git a/modules/denoise/lightmap_denoiser.h b/modules/denoise/lightmap_denoiser.h
new file mode 100644
index 0000000000..5b6e257df8
--- /dev/null
+++ b/modules/denoise/lightmap_denoiser.h
@@ -0,0 +1,56 @@
+/*************************************************************************/
+/* lightmap_denoiser.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef LIGHTMAP_DENOISER_H
+#define LIGHTMAP_DENOISER_H
+
+#include "core/object.h"
+#include "scene/3d/lightmapper.h"
+
+struct OIDNDeviceImpl;
+
+class LightmapDenoiserOIDN : public LightmapDenoiser {
+ GDCLASS(LightmapDenoiserOIDN, LightmapDenoiser);
+
+protected:
+ void *device = nullptr;
+
+public:
+ static LightmapDenoiser *create_oidn_denoiser();
+
+ Ref<Image> denoise_image(const Ref<Image> &p_image);
+
+ static void make_default_denoiser();
+
+ LightmapDenoiserOIDN();
+ ~LightmapDenoiserOIDN();
+};
+
+#endif // LIGHTMAP_DENOISER_H
diff --git a/core/path_remap.cpp b/modules/denoise/register_types.cpp
index e1708e0350..b78734a531 100644
--- a/core/path_remap.cpp
+++ b/modules/denoise/register_types.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* path_remap.cpp */
+/* register_types.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,4 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "path_remap.h"
+#include "register_types.h"
+#include "core/engine.h"
+#include "lightmap_denoiser.h"
+
+void register_denoise_types() {
+ LightmapDenoiserOIDN::make_default_denoiser();
+}
+
+void unregister_denoise_types() {
+}
diff --git a/core/math/audio_frame.cpp b/modules/denoise/register_types.h
index c565ea9b13..2ffc36ee2c 100644
--- a/core/math/audio_frame.cpp
+++ b/modules/denoise/register_types.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* audio_frame.cpp */
+/* register_types.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,4 +28,5 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "audio_frame.h"
+void register_denoise_types();
+void unregister_denoise_types();
diff --git a/modules/denoise/resource_to_cpp.py b/modules/denoise/resource_to_cpp.py
new file mode 100644
index 0000000000..4c0b67f701
--- /dev/null
+++ b/modules/denoise/resource_to_cpp.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+## ======================================================================== ##
+## Copyright 2009-2019 Intel Corporation ##
+## ##
+## Licensed under the Apache License, Version 2.0 (the "License"); ##
+## you may not use this file except in compliance with the License. ##
+## You may obtain a copy of the License at ##
+## ##
+## http://www.apache.org/licenses/LICENSE-2.0 ##
+## ##
+## Unless required by applicable law or agreed to in writing, software ##
+## distributed under the License is distributed on an "AS IS" BASIS, ##
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ##
+## See the License for the specific language governing permissions and ##
+## limitations under the License. ##
+## ======================================================================== ##
+
+import os
+import sys
+import argparse
+from array import array
+
+# Generates a C++ file from the specified binary resource file
+def generate(in_path, out_path):
+
+ namespace = "oidn::weights"
+ scopes = namespace.split("::")
+
+ file_name = os.path.basename(in_path)
+ var_name = os.path.splitext(file_name)[0]
+
+ with open(in_path, "rb") as in_file, open(out_path, "w") as out_file:
+ # Header
+ out_file.write("// Generated from: %s\n" % file_name)
+ out_file.write("#include <cstddef>\n\n")
+
+ # Open the namespaces
+ for s in scopes:
+ out_file.write("namespace %s {\n" % s)
+ if scopes:
+ out_file.write("\n")
+
+ # Read the file
+ in_data = array("B", in_file.read())
+
+ # Write the size
+ out_file.write("//const size_t %s_size = %d;\n\n" % (var_name, len(in_data)))
+
+ # Write the data
+ out_file.write("unsigned char %s[] = {" % var_name)
+ for i in range(len(in_data)):
+ c = in_data[i]
+ if i > 0:
+ out_file.write(",")
+ if (i + 1) % 20 == 1:
+ out_file.write("\n")
+ out_file.write("%d" % c)
+ out_file.write("\n};\n")
+
+ # Close the namespaces
+ if scopes:
+ out_file.write("\n")
+ for scope in reversed(scopes):
+ out_file.write("} // namespace %s\n" % scope)
+
+
+def tza_to_cpp(target, source, env):
+ for x in zip(source, target):
+ generate(str(x[0]), str(x[1]))
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp
index 444ffae713..4e7698b67c 100644
--- a/modules/enet/networked_multiplayer_enet.cpp
+++ b/modules/enet/networked_multiplayer_enet.cpp
@@ -34,21 +34,18 @@
#include "core/os/os.h"
void NetworkedMultiplayerENet::set_transfer_mode(TransferMode p_mode) {
-
transfer_mode = p_mode;
}
-NetworkedMultiplayerPeer::TransferMode NetworkedMultiplayerENet::get_transfer_mode() const {
+NetworkedMultiplayerPeer::TransferMode NetworkedMultiplayerENet::get_transfer_mode() const {
return transfer_mode;
}
void NetworkedMultiplayerENet::set_target_peer(int p_peer) {
-
target_peer = p_peer;
}
int NetworkedMultiplayerENet::get_packet_peer() const {
-
ERR_FAIL_COND_V_MSG(!active, 1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(incoming_packets.size() == 0, 1);
@@ -56,7 +53,6 @@ int NetworkedMultiplayerENet::get_packet_peer() const {
}
int NetworkedMultiplayerENet::get_packet_channel() const {
-
ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(incoming_packets.size() == 0, -1);
@@ -64,7 +60,6 @@ int NetworkedMultiplayerENet::get_packet_channel() const {
}
int NetworkedMultiplayerENet::get_last_packet_channel() const {
-
ERR_FAIL_COND_V_MSG(!active, -1, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V(!current_packet.packet, -1);
@@ -72,7 +67,6 @@ int NetworkedMultiplayerENet::get_last_packet_channel() const {
}
Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int p_in_bandwidth, int p_out_bandwidth) {
-
ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The port number must be set between 0 and 65535 (inclusive).");
ERR_FAIL_COND_V_MSG(p_max_clients < 1 || p_max_clients > 4095, ERR_INVALID_PARAMETER, "The number of clients must be set between 1 and 4095 (inclusive).");
@@ -120,8 +114,8 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
connection_status = CONNECTION_CONNECTED;
return OK;
}
-Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_port, int p_in_bandwidth, int p_out_bandwidth, int p_client_port) {
+Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_port, int p_in_bandwidth, int p_out_bandwidth, int p_client_port) {
ERR_FAIL_COND_V_MSG(active, ERR_ALREADY_IN_USE, "The multiplayer instance is already active.");
ERR_FAIL_COND_V_MSG(p_port < 0 || p_port > 65535, ERR_INVALID_PARAMETER, "The server port number must be set between 0 and 65535 (inclusive).");
ERR_FAIL_COND_V_MSG(p_client_port < 0 || p_client_port > 65535, ERR_INVALID_PARAMETER, "The client port number must be set between 0 and 65535 (inclusive).");
@@ -213,7 +207,6 @@ Error NetworkedMultiplayerENet::create_client(const String &p_address, int p_por
}
void NetworkedMultiplayerENet::poll() {
-
ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
_pop_current_packet();
@@ -221,9 +214,9 @@ void NetworkedMultiplayerENet::poll() {
ENetEvent event;
/* Keep servicing until there are no available events left in queue. */
while (true) {
-
- if (!host || !active) // Might have been disconnected while emitting a notification
+ if (!host || !active) { // Might have been disconnected while emitting a notification
return;
+ }
int ret = enet_host_service(host, &event, 0);
@@ -267,14 +260,15 @@ void NetworkedMultiplayerENet::poll() {
if (server) {
// Do not notify other peers when server_relay is disabled.
- if (!server_relay)
+ if (!server_relay) {
break;
+ }
// Someone connected, notify all the peers available
for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
-
- if (E->key() == *new_id)
+ if (E->key() == *new_id) {
continue;
+ }
// Send existing peers to new peer
ENetPacket *packet = enet_packet_create(nullptr, 8, ENET_PACKET_FLAG_RELIABLE);
encode_uint32(SYSMSG_ADD_PEER, &packet->data[0]);
@@ -287,13 +281,11 @@ void NetworkedMultiplayerENet::poll() {
enet_peer_send(E->get(), SYSCH_CONFIG, packet);
}
} else {
-
emit_signal("connection_succeeded");
}
} break;
case ENET_EVENT_TYPE_DISCONNECT: {
-
// Reset the peer's client information.
int *id = (int *)event.peer->data;
@@ -307,18 +299,16 @@ void NetworkedMultiplayerENet::poll() {
}
if (!server) {
-
// Client just disconnected from server.
emit_signal("server_disconnected");
close_connection();
return;
} else if (server_relay) {
-
// Server just received a client disconnect and is in relay mode, notify everyone else.
for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
-
- if (E->key() == *id)
+ if (E->key() == *id) {
continue;
+ }
ENetPacket *packet = enet_packet_create(nullptr, 8, ENET_PACKET_FLAG_RELIABLE);
encode_uint32(SYSMSG_REMOVE_PEER, &packet->data[0]);
@@ -332,7 +322,6 @@ void NetworkedMultiplayerENet::poll() {
memdelete(id);
} break;
case ENET_EVENT_TYPE_RECEIVE: {
-
if (event.channelID == SYSCH_CONFIG) {
// Some config message
ERR_CONTINUE(event.packet->dataLength < 8);
@@ -345,13 +334,11 @@ void NetworkedMultiplayerENet::poll() {
switch (msg) {
case SYSMSG_ADD_PEER: {
-
peer_map[id] = nullptr;
emit_signal("peer_connected", id);
} break;
case SYSMSG_REMOVE_PEER: {
-
peer_map.erase(id);
emit_signal("peer_disconnected", id);
} break;
@@ -359,7 +346,6 @@ void NetworkedMultiplayerENet::poll() {
enet_packet_destroy(event.packet);
} else if (event.channelID < channel_count) {
-
Packet packet;
packet.packet = event.packet;
@@ -391,9 +377,9 @@ void NetworkedMultiplayerENet::poll() {
incoming_packets.push_back(packet);
// And make copies for sending
for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
-
- if (uint32_t(E->key()) == source) // Do not resend to self
+ if (uint32_t(E->key()) == source) { // Do not resend to self
continue;
+ }
ENetPacket *packet2 = enet_packet_create(packet.packet->data, packet.packet->dataLength, packet.packet->flags);
@@ -405,9 +391,9 @@ void NetworkedMultiplayerENet::poll() {
// And make copies for sending
for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
-
- if (uint32_t(E->key()) == source || E->key() == -target) // Do not resend to self, also do not send to excluded
+ if (uint32_t(E->key()) == source || E->key() == -target) { // Do not resend to self, also do not send to excluded
continue;
+ }
ENetPacket *packet2 = enet_packet_create(packet.packet->data, packet.packet->dataLength, packet.packet->flags);
@@ -428,7 +414,6 @@ void NetworkedMultiplayerENet::poll() {
enet_peer_send(peer_map[target], event.channelID, packet.packet);
}
} else {
-
incoming_packets.push_back(packet);
}
@@ -452,7 +437,6 @@ bool NetworkedMultiplayerENet::is_server() const {
}
void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
-
ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
_pop_current_packet();
@@ -484,7 +468,6 @@ void NetworkedMultiplayerENet::close_connection(uint32_t wait_usec) {
}
void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
-
ERR_FAIL_COND_MSG(!active, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_MSG(!is_server(), "Can't disconnect a peer when not acting as a server.");
ERR_FAIL_COND_MSG(!peer_map.has(p_peer), vformat("Peer ID %d not found in the list of peers.", p_peer));
@@ -497,7 +480,6 @@ void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
// notify everyone else, send disconnect signal & remove from peer_map like in poll()
if (server_relay) {
for (Map<int, ENetPeer *>::Element *E = peer_map.front(); E; E = E->next()) {
-
if (E->key() == p_peer) {
continue;
}
@@ -509,8 +491,9 @@ void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
}
}
- if (id)
+ if (id) {
memdelete(id);
+ }
emit_signal("peer_disconnected", p_peer);
peer_map.erase(p_peer);
@@ -520,12 +503,10 @@ void NetworkedMultiplayerENet::disconnect_peer(int p_peer, bool now) {
}
int NetworkedMultiplayerENet::get_available_packet_count() const {
-
return incoming_packets.size();
}
Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
-
ERR_FAIL_COND_V_MSG(incoming_packets.size() == 0, ERR_UNAVAILABLE, "No incoming packets available.");
_pop_current_packet();
@@ -540,7 +521,6 @@ Error NetworkedMultiplayerENet::get_packet(const uint8_t **r_buffer, int &r_buff
}
Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
-
ERR_FAIL_COND_V_MSG(!active, ERR_UNCONFIGURED, "The multiplayer instance isn't currently active.");
ERR_FAIL_COND_V_MSG(connection_status != CONNECTION_CONNECTED, ERR_UNCONFIGURED, "The multiplayer instance isn't currently connected to any server or client.");
@@ -549,10 +529,11 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
switch (transfer_mode) {
case TRANSFER_MODE_UNRELIABLE: {
- if (always_ordered)
+ if (always_ordered) {
packet_flags = 0;
- else
+ } else {
packet_flags = ENET_PACKET_FLAG_UNSEQUENCED;
+ }
channel = SYSCH_UNRELIABLE;
} break;
case TRANSFER_MODE_UNRELIABLE_ORDERED: {
@@ -565,13 +546,13 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
} break;
}
- if (transfer_channel > SYSCH_CONFIG)
+ if (transfer_channel > SYSCH_CONFIG) {
channel = transfer_channel;
+ }
Map<int, ENetPeer *>::Element *E = nullptr;
if (target_peer != 0) {
-
E = peer_map.find(ABS(target_peer));
ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, vformat("Invalid target peer: %d", target_peer));
}
@@ -582,7 +563,6 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
copymem(&packet->data[8], p_buffer, p_buffer_size);
if (server) {
-
if (target_peer == 0) {
enet_host_broadcast(host, channel, packet);
} else if (target_peer < 0) {
@@ -592,9 +572,9 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
int exclude = -target_peer;
for (Map<int, ENetPeer *>::Element *F = peer_map.front(); F; F = F->next()) {
-
- if (F->key() == exclude) // Exclude packet
+ if (F->key() == exclude) { // Exclude packet
continue;
+ }
ENetPacket *packet2 = enet_packet_create(packet->data, packet->dataLength, packet_flags);
@@ -606,7 +586,6 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
enet_peer_send(E->get(), channel, packet);
}
} else {
-
ERR_FAIL_COND_V(!peer_map.has(1), ERR_BUG);
enet_peer_send(peer_map[1], channel, packet); // Send to server for broadcast
}
@@ -617,12 +596,10 @@ Error NetworkedMultiplayerENet::put_packet(const uint8_t *p_buffer, int p_buffer
}
int NetworkedMultiplayerENet::get_max_packet_size() const {
-
return 1 << 24; // Anything is good
}
void NetworkedMultiplayerENet::_pop_current_packet() {
-
if (current_packet.packet) {
enet_packet_destroy(current_packet.packet);
current_packet.packet = nullptr;
@@ -632,16 +609,13 @@ void NetworkedMultiplayerENet::_pop_current_packet() {
}
NetworkedMultiplayerPeer::ConnectionStatus NetworkedMultiplayerENet::get_connection_status() const {
-
return connection_status;
}
uint32_t NetworkedMultiplayerENet::_gen_unique_id() const {
-
uint32_t hash = 0;
while (hash == 0 || hash == 1) {
-
hash = hash_djb2_one_32(
(uint32_t)OS::get_singleton()->get_ticks_usec());
hash = hash_djb2_one_32(
@@ -660,33 +634,27 @@ uint32_t NetworkedMultiplayerENet::_gen_unique_id() const {
}
int NetworkedMultiplayerENet::get_unique_id() const {
-
ERR_FAIL_COND_V_MSG(!active, 0, "The multiplayer instance isn't currently active.");
return unique_id;
}
void NetworkedMultiplayerENet::set_refuse_new_connections(bool p_enable) {
-
refuse_connections = p_enable;
}
bool NetworkedMultiplayerENet::is_refusing_new_connections() const {
-
return refuse_connections;
}
void NetworkedMultiplayerENet::set_compression_mode(CompressionMode p_mode) {
-
compression_mode = p_mode;
}
NetworkedMultiplayerENet::CompressionMode NetworkedMultiplayerENet::get_compression_mode() const {
-
return compression_mode;
}
size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer *inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 *outData, size_t outLimit) {
-
NetworkedMultiplayerENet *enet = (NetworkedMultiplayerENet *)(context);
if (size_t(enet->src_compressor_mem.size()) < inLimit) {
@@ -727,11 +695,13 @@ size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer *
}
int ret = Compression::compress(enet->dst_compressor_mem.ptrw(), enet->src_compressor_mem.ptr(), ofs, mode);
- if (ret < 0)
+ if (ret < 0) {
return 0;
+ }
- if (ret > int(outLimit))
+ if (ret > int(outLimit)) {
return 0; // Do not bother
+ }
copymem(outData, enet->dst_compressor_mem.ptr(), ret);
@@ -739,20 +709,16 @@ size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer *
}
size_t NetworkedMultiplayerENet::enet_decompress(void *context, const enet_uint8 *inData, size_t inLimit, enet_uint8 *outData, size_t outLimit) {
-
NetworkedMultiplayerENet *enet = (NetworkedMultiplayerENet *)(context);
int ret = -1;
switch (enet->compression_mode) {
case COMPRESS_FASTLZ: {
-
ret = Compression::decompress(outData, outLimit, inData, inLimit, Compression::MODE_FASTLZ);
} break;
case COMPRESS_ZLIB: {
-
ret = Compression::decompress(outData, outLimit, inData, inLimit, Compression::MODE_DEFLATE);
} break;
case COMPRESS_ZSTD: {
-
ret = Compression::decompress(outData, outLimit, inData, inLimit, Compression::MODE_ZSTD);
} break;
default: {
@@ -766,11 +732,8 @@ size_t NetworkedMultiplayerENet::enet_decompress(void *context, const enet_uint8
}
void NetworkedMultiplayerENet::_setup_compressor() {
-
switch (compression_mode) {
-
case COMPRESS_NONE: {
-
enet_host_compress(host, nullptr);
} break;
case COMPRESS_RANGE_CODER: {
@@ -779,19 +742,16 @@ void NetworkedMultiplayerENet::_setup_compressor() {
case COMPRESS_FASTLZ:
case COMPRESS_ZLIB:
case COMPRESS_ZSTD: {
-
enet_host_compress(host, &enet_compressor);
} break;
}
}
void NetworkedMultiplayerENet::enet_compressor_destroy(void *context) {
-
// Nothing to do
}
IP_Address NetworkedMultiplayerENet::get_peer_address(int p_peer_id) const {
-
ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), IP_Address(), vformat("Peer ID %d not found in the list of peers.", p_peer_id));
ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, IP_Address(), "Can't get the address of peers other than the server (ID -1) when acting as a client.");
ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == nullptr, IP_Address(), vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
@@ -807,7 +767,6 @@ IP_Address NetworkedMultiplayerENet::get_peer_address(int p_peer_id) const {
}
int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
-
ERR_FAIL_COND_V_MSG(!peer_map.has(p_peer_id), 0, vformat("Peer ID %d not found in the list of peers.", p_peer_id));
ERR_FAIL_COND_V_MSG(!is_server() && p_peer_id != 1, 0, "Can't get the address of peers other than the server (ID -1) when acting as a client.");
ERR_FAIL_COND_V_MSG(peer_map[p_peer_id] == nullptr, 0, vformat("Peer ID %d found in the list of peers, but is null.", p_peer_id));
@@ -819,7 +778,6 @@ int NetworkedMultiplayerENet::get_peer_port(int p_peer_id) const {
}
void NetworkedMultiplayerENet::set_transfer_channel(int p_channel) {
-
ERR_FAIL_COND_MSG(p_channel < -1 || p_channel >= channel_count, vformat("The transfer channel must be set between 0 and %d, inclusive (got %d).", channel_count - 1, p_channel));
ERR_FAIL_COND_MSG(p_channel == SYSCH_CONFIG, vformat("The channel %d is reserved.", SYSCH_CONFIG));
transfer_channel = p_channel;
@@ -830,7 +788,6 @@ int NetworkedMultiplayerENet::get_transfer_channel() const {
}
void NetworkedMultiplayerENet::set_channel_count(int p_channel) {
-
ERR_FAIL_COND_MSG(active, "The channel count can't be set while the multiplayer instance is active.");
ERR_FAIL_COND_MSG(p_channel < SYSCH_MAX, vformat("The channel count must be greater than or equal to %d to account for reserved channels (got %d).", SYSCH_MAX, p_channel));
channel_count = p_channel;
@@ -859,7 +816,6 @@ bool NetworkedMultiplayerENet::is_server_relay_enabled() const {
}
void NetworkedMultiplayerENet::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("create_server", "port", "max_clients", "in_bandwidth", "out_bandwidth"), &NetworkedMultiplayerENet::create_server, DEFVAL(32), DEFVAL(0), DEFVAL(0));
ClassDB::bind_method(D_METHOD("create_client", "address", "port", "in_bandwidth", "out_bandwidth", "client_port"), &NetworkedMultiplayerENet::create_client, DEFVAL(0), DEFVAL(0), DEFVAL(0));
ClassDB::bind_method(D_METHOD("close_connection", "wait_usec"), &NetworkedMultiplayerENet::close_connection, DEFVAL(100));
@@ -903,7 +859,6 @@ void NetworkedMultiplayerENet::_bind_methods() {
}
NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
-
active = false;
server = false;
refuse_connections = false;
@@ -929,7 +884,6 @@ NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
}
NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
-
if (active) {
close_connection();
}
diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h
index ff436ce2c0..b2ed951327 100644
--- a/modules/enet/networked_multiplayer_enet.h
+++ b/modules/enet/networked_multiplayer_enet.h
@@ -38,7 +38,6 @@
#include <enet/enet.h>
class NetworkedMultiplayerENet : public NetworkedMultiplayerPeer {
-
GDCLASS(NetworkedMultiplayerENet, NetworkedMultiplayerPeer);
public:
@@ -86,7 +85,6 @@ private:
Map<int, ENetPeer *> peer_map;
struct Packet {
-
ENetPacket *packet;
int from;
int channel;
diff --git a/modules/enet/register_types.cpp b/modules/enet/register_types.cpp
index 27f27196d6..18051f756a 100644
--- a/modules/enet/register_types.cpp
+++ b/modules/enet/register_types.cpp
@@ -35,7 +35,6 @@
static bool enet_ok = false;
void register_enet_types() {
-
if (enet_initialize() != 0) {
ERR_PRINT("ENet initialization failure");
} else {
@@ -46,7 +45,7 @@ void register_enet_types() {
}
void unregister_enet_types() {
-
- if (enet_ok)
+ if (enet_ok) {
enet_deinitialize();
+ }
}
diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp
index 223830f445..9b6d8a2d35 100644
--- a/modules/etc/image_etc.cpp
+++ b/modules/etc/image_etc.cpp
@@ -127,8 +127,9 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f
Ref<Image> img = p_img->duplicate();
- if (img->get_format() != Image::FORMAT_RGBA8)
+ if (img->get_format() != Image::FORMAT_RGBA8) {
img->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert
+ }
if (img->has_mipmaps()) {
if (next_power_of_2(imgw) != imgw || next_power_of_2(imgh) != imgh) {
@@ -165,12 +166,13 @@ static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_f
int encoding_time = 0;
float effort = 0.0; //default, reasonable time
- if (p_lossy_quality > 0.75)
+ if (p_lossy_quality > 0.75) {
effort = 0.4;
- else if (p_lossy_quality > 0.85)
+ } else if (p_lossy_quality > 0.85) {
effort = 0.6;
- else if (p_lossy_quality > 0.95)
+ } else if (p_lossy_quality > 0.95) {
effort = 0.8;
+ }
Etc::ErrorMetric error_metric = Etc::ErrorMetric::RGBX; // NOTE: we can experiment with other error metrics
Etc::Image::Format etc2comp_etc_format = _image_format_to_etc2comp_format(etc_format);
@@ -219,7 +221,6 @@ static void _compress_etc2(Image *p_img, float p_lossy_quality, Image::UsedChann
}
void _register_etc_compress_func() {
-
Image::_image_compress_etc1_func = _compress_etc1;
Image::_image_compress_etc2_func = _compress_etc2;
}
diff --git a/modules/etc/register_types.cpp b/modules/etc/register_types.cpp
index 26809e0de9..0972857808 100644
--- a/modules/etc/register_types.cpp
+++ b/modules/etc/register_types.cpp
@@ -36,7 +36,6 @@
static Ref<ResourceFormatPKM> resource_loader_pkm;
void register_etc_types() {
-
resource_loader_pkm.instance();
ResourceLoader::add_resource_format_loader(resource_loader_pkm);
@@ -44,7 +43,6 @@ void register_etc_types() {
}
void unregister_etc_types() {
-
ResourceLoader::remove_resource_format_loader(resource_loader_pkm);
resource_loader_pkm.unref();
}
diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp
index ad0cc91c96..c40e9612a8 100644
--- a/modules/etc/texture_loader_pkm.cpp
+++ b/modules/etc/texture_loader_pkm.cpp
@@ -42,19 +42,21 @@ struct ETC1Header {
uint16_t origHeight;
};
-RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
- if (r_error)
+RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_CANT_OPEN;
+ }
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
- if (!f)
+ if (!f) {
return RES();
+ }
FileAccessRef fref(f);
- if (r_error)
+ if (r_error) {
*r_error = ERR_FILE_CORRUPT;
+ }
ERR_FAIL_COND_V_MSG(err != OK, RES(), "Unable to open PKM texture file '" + p_path + "'.");
@@ -87,8 +89,9 @@ RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path,
Ref<ImageTexture> texture = memnew(ImageTexture);
texture->create_from_image(img);
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
f->close();
memdelete(f);
@@ -96,18 +99,16 @@ RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path,
}
void ResourceFormatPKM::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("pkm");
}
bool ResourceFormatPKM::handles_type(const String &p_type) const {
-
return ClassDB::is_parent_class(p_type, "Texture2D");
}
String ResourceFormatPKM::get_resource_type(const String &p_path) const {
-
- if (p_path.get_extension().to_lower() == "pkm")
+ if (p_path.get_extension().to_lower() == "pkm") {
return "ImageTexture";
+ }
return "";
}
diff --git a/modules/etc/texture_loader_pkm.h b/modules/etc/texture_loader_pkm.h
index 989e203994..6507e0bdec 100644
--- a/modules/etc/texture_loader_pkm.h
+++ b/modules/etc/texture_loader_pkm.h
@@ -36,7 +36,7 @@
class ResourceFormatPKM : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index d3426044ec..3d747ba41e 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -63,7 +63,6 @@ GDNativeLibrary::~GDNativeLibrary() {
}
bool GDNativeLibrary::_set(const StringName &p_name, const Variant &p_property) {
-
String name = p_name;
if (name.begins_with("entry/")) {
@@ -115,8 +114,9 @@ void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
// set entries
List<String> entry_key_list;
- if (config_file->has_section("entry"))
+ if (config_file->has_section("entry")) {
config_file->get_section_keys("entry", &entry_key_list);
+ }
for (List<String>::Element *E = entry_key_list.front(); E; E = E->next()) {
String key = E->get();
@@ -132,8 +132,9 @@ void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
// set dependencies
List<String> dependency_key_list;
- if (config_file->has_section("dependencies"))
+ if (config_file->has_section("dependencies")) {
config_file->get_section_keys("dependencies", &dependency_key_list);
+ }
for (List<String>::Element *E = dependency_key_list.front(); E; E = E->next()) {
String key = E->get();
@@ -148,7 +149,6 @@ void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
}
void GDNativeLibrary::set_config_file(Ref<ConfigFile> p_config_file) {
-
set_singleton(p_config_file->get_value("general", "singleton", default_singleton));
set_load_once(p_config_file->get_value("general", "load_once", default_load_once));
set_symbol_prefix(p_config_file->get_value("general", "symbol_prefix", default_symbol_prefix));
@@ -156,11 +156,11 @@ void GDNativeLibrary::set_config_file(Ref<ConfigFile> p_config_file) {
String entry_lib_path;
{
-
List<String> entry_keys;
- if (p_config_file->has_section("entry"))
+ if (p_config_file->has_section("entry")) {
p_config_file->get_section_keys("entry", &entry_keys);
+ }
for (List<String>::Element *E = entry_keys.front(); E; E = E->next()) {
String key = E->get();
@@ -188,11 +188,11 @@ void GDNativeLibrary::set_config_file(Ref<ConfigFile> p_config_file) {
Vector<String> dependency_paths;
{
-
List<String> dependency_keys;
- if (p_config_file->has_section("dependencies"))
+ if (p_config_file->has_section("dependencies")) {
p_config_file->get_section_keys("dependencies", &dependency_keys);
+ }
for (List<String>::Element *E = dependency_keys.front(); E; E = E->next()) {
String key = E->get();
@@ -383,7 +383,6 @@ bool GDNative::initialize() {
}
bool GDNative::terminate() {
-
if (!initialized) {
ERR_PRINT("No valid library handle, can't terminate GDNative object");
return false;
@@ -452,7 +451,6 @@ Vector<StringName> GDNativeCallRegistry::get_native_call_types() {
}
Variant GDNative::call_native(StringName p_native_call_type, StringName p_procedure_name, Array p_arguments) {
-
Map<StringName, native_call_cb>::Element *E = GDNativeCallRegistry::singleton->native_calls.find(p_native_call_type);
if (!E) {
ERR_PRINT((String("No handler for native call type \"" + p_native_call_type) + "\" found").utf8().get_data());
@@ -478,7 +476,6 @@ Variant GDNative::call_native(StringName p_native_call_type, StringName p_proced
}
Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_optional) const {
-
if (!initialized) {
ERR_PRINT("No valid library handle, can't get symbol from GDNative object");
return ERR_CANT_OPEN;
@@ -493,7 +490,7 @@ Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle, bool p_
return result;
}
-RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES GDNativeLibraryResourceLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
Ref<GDNativeLibrary> lib;
lib.instance();
@@ -520,13 +517,13 @@ bool GDNativeLibraryResourceLoader::handles_type(const String &p_type) const {
String GDNativeLibraryResourceLoader::get_resource_type(const String &p_path) const {
String el = p_path.get_extension().to_lower();
- if (el == "gdnlib")
+ if (el == "gdnlib") {
return "GDNativeLibrary";
+ }
return "";
}
Error GDNativeLibraryResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
Ref<GDNativeLibrary> lib = p_resource;
if (lib.is_null()) {
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index 9ef9c706d1..6d26c2141d 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -166,7 +166,7 @@ public:
class GDNativeLibraryResourceLoader : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/gdnative/aabb.cpp b/modules/gdnative/gdnative/aabb.cpp
index 246e5d4e8d..7f22c7dfe3 100644
--- a/modules/gdnative/gdnative/aabb.cpp
+++ b/modules/gdnative/gdnative/aabb.cpp
@@ -37,6 +37,8 @@
extern "C" {
#endif
+static_assert(sizeof(godot_aabb) == sizeof(AABB), "AABB size mismatch");
+
void GDAPI godot_aabb_new(godot_aabb *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size) {
const Vector3 *pos = (const Vector3 *)p_pos;
const Vector3 *size = (const Vector3 *)p_size;
diff --git a/modules/gdnative/gdnative/array.cpp b/modules/gdnative/gdnative/array.cpp
index 0c764ab8fd..59953f5182 100644
--- a/modules/gdnative/gdnative/array.cpp
+++ b/modules/gdnative/gdnative/array.cpp
@@ -41,6 +41,8 @@
extern "C" {
#endif
+static_assert(sizeof(godot_array) == sizeof(Array), "Array size mismatch");
+
void GDAPI godot_array_new(godot_array *r_dest) {
Array *dest = (Array *)r_dest;
memnew_placement(dest, Array);
@@ -100,9 +102,33 @@ void GDAPI godot_array_new_packed_string_array(godot_array *r_dest, const godot_
}
}
-void GDAPI godot_array_new_packed_real_array(godot_array *r_dest, const godot_packed_real_array *p_pra) {
+void GDAPI godot_array_new_packed_float32_array(godot_array *r_dest, const godot_packed_float32_array *p_pra) {
+ Array *dest = (Array *)r_dest;
+ Vector<float> *pca = (Vector<float> *)p_pra;
+ memnew_placement(dest, Array);
+ dest->resize(pca->size());
+
+ for (int i = 0; i < dest->size(); i++) {
+ Variant v = pca->operator[](i);
+ dest->operator[](i) = v;
+ }
+}
+
+void GDAPI godot_array_new_packed_float64_array(godot_array *r_dest, const godot_packed_float64_array *p_pra) {
+ Array *dest = (Array *)r_dest;
+ Vector<double> *pca = (Vector<double> *)p_pra;
+ memnew_placement(dest, Array);
+ dest->resize(pca->size());
+
+ for (int i = 0; i < dest->size(); i++) {
+ Variant v = pca->operator[](i);
+ dest->operator[](i) = v;
+ }
+}
+
+void GDAPI godot_array_new_packed_int32_array(godot_array *r_dest, const godot_packed_int32_array *p_pia) {
Array *dest = (Array *)r_dest;
- Vector<godot_real> *pca = (Vector<godot_real> *)p_pra;
+ Vector<int32_t> *pca = (Vector<int32_t> *)p_pia;
memnew_placement(dest, Array);
dest->resize(pca->size());
@@ -112,9 +138,9 @@ void GDAPI godot_array_new_packed_real_array(godot_array *r_dest, const godot_pa
}
}
-void GDAPI godot_array_new_packed_int_array(godot_array *r_dest, const godot_packed_int_array *p_pia) {
+void GDAPI godot_array_new_packed_int64_array(godot_array *r_dest, const godot_packed_int64_array *p_pia) {
Array *dest = (Array *)r_dest;
- Vector<godot_int> *pca = (Vector<godot_int> *)p_pia;
+ Vector<int64_t> *pca = (Vector<int64_t> *)p_pia;
memnew_placement(dest, Array);
dest->resize(pca->size());
diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp
index 4f489287b9..990fd3795d 100644
--- a/modules/gdnative/gdnative/basis.cpp
+++ b/modules/gdnative/gdnative/basis.cpp
@@ -37,6 +37,8 @@
extern "C" {
#endif
+static_assert(sizeof(godot_basis) == sizeof(Basis), "Basis size mismatch");
+
void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis) {
const Vector3 *x_axis = (const Vector3 *)p_x_axis;
const Vector3 *y_axis = (const Vector3 *)p_y_axis;
diff --git a/modules/gdnative/gdnative/callable.cpp b/modules/gdnative/gdnative/callable.cpp
new file mode 100644
index 0000000000..868b324227
--- /dev/null
+++ b/modules/gdnative/gdnative/callable.cpp
@@ -0,0 +1,252 @@
+/*************************************************************************/
+/* callable.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "gdnative/callable.h"
+
+#include "core/callable.h"
+#include "core/resource.h"
+#include "core/variant.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static_assert(sizeof(godot_callable) == sizeof(Callable), "Callable size mismatch");
+static_assert(sizeof(godot_signal) == sizeof(Signal), "Signal size mismatch");
+
+// Callable
+
+void GDAPI godot_callable_new_with_object(godot_callable *r_dest, const godot_object *p_object, const godot_string_name *p_method) {
+ Callable *dest = (Callable *)r_dest;
+ const Object *object = (const Object *)p_object;
+ const StringName *method = (const StringName *)p_method;
+ memnew_placement(dest, Callable(object, *method));
+}
+
+void GDAPI godot_callable_new_with_object_id(godot_callable *r_dest, uint64_t p_objectid, const godot_string_name *p_method) {
+ Callable *dest = (Callable *)r_dest;
+ const StringName *method = (const StringName *)p_method;
+ memnew_placement(dest, Callable(ObjectID(p_objectid), *method));
+}
+
+void GDAPI godot_callable_new_copy(godot_callable *r_dest, const godot_callable *p_src) {
+ Callable *dest = (Callable *)r_dest;
+ const Callable *src = (const Callable *)p_src;
+ memnew_placement(dest, Callable(*src));
+}
+
+void GDAPI godot_callable_destroy(godot_callable *p_self) {
+ Callable *self = (Callable *)p_self;
+ self->~Callable();
+}
+
+godot_int GDAPI godot_callable_call(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount, godot_variant *r_return_value) {
+ const Callable *self = (const Callable *)p_self;
+ const Variant **arguments = (const Variant **)p_arguments;
+ Variant *return_value = (Variant *)r_return_value;
+ Variant ret;
+ Callable::CallError err;
+ self->call(arguments, p_argcount, ret, err);
+ if (return_value)
+ (*return_value) = ret;
+ return (godot_int)err.error;
+}
+
+void GDAPI godot_callable_call_deferred(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount) {
+ const Callable *self = (const Callable *)p_self;
+ const Variant **arguments = (const Variant **)p_arguments;
+ self->call_deferred(arguments, p_argcount);
+}
+
+godot_bool GDAPI godot_callable_is_null(const godot_callable *p_self) {
+ const Callable *self = (const Callable *)p_self;
+ return self->is_null();
+}
+
+godot_bool GDAPI godot_callable_is_custom(const godot_callable *p_self) {
+ const Callable *self = (const Callable *)p_self;
+ return self->is_custom();
+}
+
+godot_bool GDAPI godot_callable_is_standard(const godot_callable *p_self) {
+ const Callable *self = (const Callable *)p_self;
+ return self->is_standard();
+}
+
+godot_object GDAPI *godot_callable_get_object(const godot_callable *p_self) {
+ const Callable *self = (const Callable *)p_self;
+ return (godot_object *)self->get_object();
+}
+
+uint64_t GDAPI godot_callable_get_object_id(const godot_callable *p_self) {
+ const Callable *self = (const Callable *)p_self;
+ return (uint64_t)self->get_object_id();
+}
+
+godot_string_name GDAPI godot_callable_get_method(const godot_callable *p_self) {
+ godot_string_name raw_dest;
+ const Callable *self = (const Callable *)p_self;
+ StringName *dest = (StringName *)&raw_dest;
+ memnew_placement(dest, StringName(self->get_method()));
+ return raw_dest;
+}
+
+uint32_t GDAPI godot_callable_hash(const godot_callable *p_self) {
+ const Callable *self = (const Callable *)p_self;
+ return self->hash();
+}
+
+godot_string GDAPI godot_callable_as_string(const godot_callable *p_self) {
+ godot_string ret;
+ const Callable *self = (const Callable *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
+}
+
+godot_bool GDAPI godot_callable_operator_equal(const godot_callable *p_self, const godot_callable *p_other) {
+ const Callable *self = (const Callable *)p_self;
+ const Callable *other = (const Callable *)p_other;
+ return *self == *other;
+}
+
+godot_bool GDAPI godot_callable_operator_less(const godot_callable *p_self, const godot_callable *p_other) {
+ const Callable *self = (const Callable *)p_self;
+ const Callable *other = (const Callable *)p_other;
+ return *self < *other;
+}
+
+// Signal
+
+void GDAPI godot_signal_new_with_object(godot_signal *r_dest, const godot_object *p_object, const godot_string_name *p_name) {
+ Signal *dest = (Signal *)r_dest;
+ const Object *object = (const Object *)p_object;
+ const StringName *name = (const StringName *)p_name;
+ memnew_placement(dest, Signal(object, *name));
+}
+
+void GDAPI godot_signal_new_with_object_id(godot_signal *r_dest, uint64_t p_objectid, const godot_string_name *p_name) {
+ Signal *dest = (Signal *)r_dest;
+ const StringName *name = (const StringName *)p_name;
+ memnew_placement(dest, Signal(ObjectID(p_objectid), *name));
+}
+
+void GDAPI godot_signal_new_copy(godot_signal *r_dest, const godot_signal *p_src) {
+ Signal *dest = (Signal *)r_dest;
+ const Signal *src = (const Signal *)p_src;
+ memnew_placement(dest, Signal(*src));
+}
+
+void GDAPI godot_signal_destroy(godot_signal *p_self) {
+ Signal *self = (Signal *)p_self;
+ self->~Signal();
+}
+
+godot_int GDAPI godot_signal_emit(const godot_signal *p_self, const godot_variant **p_arguments, godot_int p_argcount) {
+ const Signal *self = (const Signal *)p_self;
+ const Variant **arguments = (const Variant **)p_arguments;
+ return (godot_int)self->emit(arguments, p_argcount);
+}
+
+godot_int GDAPI godot_signal_connect(godot_signal *p_self, const godot_callable *p_callable, const godot_array *p_binds, uint32_t p_flags) {
+ Signal *self = (Signal *)p_self;
+ const Callable *callable = (const Callable *)p_callable;
+ const Array *binds_ar = (const Array *)p_binds;
+ Vector<Variant> binds;
+ for (int i = 0; i < binds_ar->size(); i++) {
+ binds.push_back(binds_ar->get(i));
+ }
+ return (godot_int)self->connect(*callable, binds, p_flags);
+}
+
+void GDAPI godot_signal_disconnect(godot_signal *p_self, const godot_callable *p_callable) {
+ Signal *self = (Signal *)p_self;
+ const Callable *callable = (const Callable *)p_callable;
+ self->disconnect(*callable);
+}
+
+godot_bool GDAPI godot_signal_is_null(const godot_signal *p_self) {
+ const Signal *self = (const Signal *)p_self;
+ return self->is_null();
+}
+
+godot_bool GDAPI godot_signal_is_connected(const godot_signal *p_self, const godot_callable *p_callable) {
+ const Signal *self = (const Signal *)p_self;
+ const Callable *callable = (const Callable *)p_callable;
+ return self->is_connected(*callable);
+}
+
+godot_array GDAPI godot_signal_get_connections(const godot_signal *p_self) {
+ godot_array raw_dest;
+ const Signal *self = (const Signal *)p_self;
+ Array *dest = (Array *)&raw_dest;
+ memnew_placement(dest, Array(self->get_connections()));
+ return raw_dest;
+}
+
+godot_object GDAPI *godot_signal_get_object(const godot_signal *p_self) {
+ const Signal *self = (const Signal *)p_self;
+ return (godot_object *)self->get_object();
+}
+
+uint64_t GDAPI godot_signal_get_object_id(const godot_signal *p_self) {
+ const Signal *self = (const Signal *)p_self;
+ return (uint64_t)self->get_object_id();
+}
+
+godot_string_name GDAPI godot_signal_get_name(const godot_signal *p_self) {
+ godot_string_name raw_dest;
+ const Signal *self = (const Signal *)p_self;
+ StringName *dest = (StringName *)&raw_dest;
+ memnew_placement(dest, StringName(self->get_name()));
+ return raw_dest;
+}
+
+godot_string GDAPI godot_signal_as_string(const godot_signal *p_self) {
+ godot_string ret;
+ const Signal *self = (const Signal *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
+}
+
+godot_bool GDAPI godot_signal_operator_equal(const godot_signal *p_self, const godot_signal *p_other) {
+ const Signal *self = (const Signal *)p_self;
+ const Signal *other = (const Signal *)p_other;
+ return *self == *other;
+}
+
+godot_bool GDAPI godot_signal_operator_less(const godot_signal *p_self, const godot_signal *p_other) {
+ const Signal *self = (const Signal *)p_self;
+ const Signal *other = (const Signal *)p_other;
+ return *self < *other;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/modules/gdnative/gdnative/color.cpp b/modules/gdnative/gdnative/color.cpp
index 914d5b03f4..c75e74daba 100644
--- a/modules/gdnative/gdnative/color.cpp
+++ b/modules/gdnative/gdnative/color.cpp
@@ -37,14 +37,14 @@
extern "C" {
#endif
-void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a) {
+static_assert(sizeof(godot_color) == sizeof(Color), "Color size mismatch");
+void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a) {
Color *dest = (Color *)r_dest;
*dest = Color(p_r, p_g, p_b, p_a);
}
void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b) {
-
Color *dest = (Color *)r_dest;
*dest = Color(p_r, p_g, p_b);
}
@@ -155,11 +155,11 @@ godot_color GDAPI godot_color_contrasted(const godot_color *p_self) {
return dest;
}
-godot_color GDAPI godot_color_linear_interpolate(const godot_color *p_self, const godot_color *p_b, const godot_real p_t) {
+godot_color GDAPI godot_color_lerp(const godot_color *p_self, const godot_color *p_b, const godot_real p_t) {
godot_color dest;
const Color *self = (const Color *)p_self;
const Color *b = (const Color *)p_b;
- *((Color *)&dest) = self->linear_interpolate(*b, p_t);
+ *((Color *)&dest) = self->lerp(*b, p_t);
return dest;
}
diff --git a/modules/gdnative/gdnative/dictionary.cpp b/modules/gdnative/gdnative/dictionary.cpp
index b145b88934..a126974815 100644
--- a/modules/gdnative/gdnative/dictionary.cpp
+++ b/modules/gdnative/gdnative/dictionary.cpp
@@ -39,6 +39,8 @@
extern "C" {
#endif
+static_assert(sizeof(godot_dictionary) == sizeof(Dictionary), "Dictionary size mismatch");
+
void GDAPI godot_dictionary_new(godot_dictionary *r_dest) {
Dictionary *dest = (Dictionary *)r_dest;
memnew_placement(dest, Dictionary);
diff --git a/modules/gdnative/gdnative/gdnative.cpp b/modules/gdnative/gdnative/gdnative.cpp
index 3175340448..e94190b07b 100644
--- a/modules/gdnative/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative/gdnative.cpp
@@ -56,14 +56,12 @@ godot_object GDAPI *godot_global_get_singleton(char *p_name) {
// MethodBind API
godot_method_bind GDAPI *godot_method_bind_get_method(const char *p_classname, const char *p_methodname) {
-
MethodBind *mb = ClassDB::get_method(StringName(p_classname), StringName(p_methodname));
// MethodBind *mb = ClassDB::get_method("Node", "get_name");
return (godot_method_bind *)mb;
}
void GDAPI godot_method_bind_ptrcall(godot_method_bind *p_method_bind, godot_object *p_instance, const void **p_args, void *p_ret) {
-
MethodBind *mb = (MethodBind *)p_method_bind;
Object *o = (Object *)p_instance;
mb->ptrcall(o, p_args, p_ret);
@@ -93,8 +91,9 @@ godot_variant GDAPI godot_method_bind_call(godot_method_bind *p_method_bind, god
godot_class_constructor GDAPI godot_get_class_constructor(const char *p_classname) {
ClassDB::ClassInfo *class_info = ClassDB::classes.getptr(StringName(p_classname));
- if (class_info)
+ if (class_info) {
return (godot_class_constructor)class_info->creation_func;
+ }
return nullptr;
}
@@ -166,7 +165,7 @@ void _gdnative_report_loading_error(const godot_object *p_library, const char *p
_err_print_error("gdnative_init", library->get_current_library_path().utf8().ptr(), 0, message.utf8().ptr());
}
-godot_object GDAPI *godot_instance_from_id(godot_int p_instance_id) {
+godot_object GDAPI *godot_instance_from_id(uint64_t p_instance_id) {
return (godot_object *)ObjectDB::get_instance(ObjectID(p_instance_id));
}
@@ -177,12 +176,19 @@ void *godot_get_class_tag(const godot_string_name *p_class) {
}
godot_object *godot_object_cast_to(const godot_object *p_object, void *p_class_tag) {
- if (!p_object) return nullptr;
+ if (!p_object) {
+ return nullptr;
+ }
Object *o = (Object *)p_object;
return o->is_class_ptr(p_class_tag) ? (godot_object *)o : nullptr;
}
+uint64_t GDAPI godot_object_get_instance_id(const godot_object *p_object) {
+ const Object *o = (const Object *)p_object;
+ return (uint64_t)o->get_instance_id();
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/node_path.cpp b/modules/gdnative/gdnative/node_path.cpp
index 93f43835c8..88ed650ebe 100644
--- a/modules/gdnative/gdnative/node_path.cpp
+++ b/modules/gdnative/gdnative/node_path.cpp
@@ -37,6 +37,8 @@
extern "C" {
#endif
+static_assert(sizeof(godot_node_path) == sizeof(NodePath), "NodePath size mismatch");
+
void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from) {
NodePath *dest = (NodePath *)r_dest;
const String *from = (const String *)p_from;
diff --git a/modules/gdnative/gdnative/pool_arrays.cpp b/modules/gdnative/gdnative/packed_arrays.cpp
index 589b4d4dfe..675d66056a 100644
--- a/modules/gdnative/gdnative/pool_arrays.cpp
+++ b/modules/gdnative/gdnative/packed_arrays.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* pool_arrays.cpp */
+/* packed_arrays.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "gdnative/pool_arrays.h"
+#include "gdnative/packed_arrays.h"
#include "core/array.h"
@@ -42,6 +42,16 @@
extern "C" {
#endif
+static_assert(sizeof(godot_packed_byte_array) == sizeof(Vector<uint8_t>), "Vector<uint8_t> size mismatch");
+static_assert(sizeof(godot_packed_int32_array) == sizeof(Vector<int32_t>), "Vector<int32_t> size mismatch");
+static_assert(sizeof(godot_packed_int64_array) == sizeof(Vector<int64_t>), "Vector<int64_t> size mismatch");
+static_assert(sizeof(godot_packed_float32_array) == sizeof(Vector<float>), "Vector<float> size mismatch");
+static_assert(sizeof(godot_packed_float64_array) == sizeof(Vector<double>), "Vector<double> size mismatch");
+static_assert(sizeof(godot_packed_string_array) == sizeof(Vector<String>), "Vector<String> size mismatch");
+static_assert(sizeof(godot_packed_vector2_array) == sizeof(Vector<Vector2>), "Vector<Vector2> size mismatch");
+static_assert(sizeof(godot_packed_vector3_array) == sizeof(Vector<Vector3>), "Vector<Vector3> size mismatch");
+static_assert(sizeof(godot_packed_color_array) == sizeof(Vector<Color>), "Vector<Color> size mismatch");
+
#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
// byte
@@ -128,23 +138,191 @@ void GDAPI godot_packed_byte_array_destroy(godot_packed_byte_array *p_self) {
((Vector<uint8_t> *)p_self)->~Vector();
}
-// int
+// int32
+
+void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *r_dest) {
+ Vector<int32_t> *dest = (Vector<int32_t> *)r_dest;
+ memnew_placement(dest, Vector<int32_t>);
+}
+
+void GDAPI godot_packed_int32_array_new_copy(godot_packed_int32_array *r_dest, const godot_packed_int32_array *p_src) {
+ Vector<int32_t> *dest = (Vector<int32_t> *)r_dest;
+ const Vector<int32_t> *src = (const Vector<int32_t> *)p_src;
+ memnew_placement(dest, Vector<int32_t>(*src));
+}
+
+void GDAPI godot_packed_int32_array_new_with_array(godot_packed_int32_array *r_dest, const godot_array *p_a) {
+ Vector<int32_t> *dest = (Vector<int32_t> *)r_dest;
+ Array *a = (Array *)p_a;
+ memnew_placement(dest, Vector<int32_t>);
+
+ dest->resize(a->size());
+ for (int i = 0; i < a->size(); i++) {
+ dest->set(i, (*a)[i]);
+ }
+}
+
+void GDAPI godot_packed_int32_array_append(godot_packed_int32_array *p_self, const int32_t p_data) {
+ Vector<int32_t> *self = (Vector<int32_t> *)p_self;
+ self->push_back(p_data);
+}
+
+void GDAPI godot_packed_int32_array_append_array(godot_packed_int32_array *p_self, const godot_packed_int32_array *p_array) {
+ Vector<int32_t> *self = (Vector<int32_t> *)p_self;
+ Vector<int32_t> *array = (Vector<int32_t> *)p_array;
+ self->append_array(*array);
+}
+
+godot_error GDAPI godot_packed_int32_array_insert(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data) {
+ Vector<int32_t> *self = (Vector<int32_t> *)p_self;
+ return (godot_error)self->insert(p_idx, p_data);
+}
+
+void GDAPI godot_packed_int32_array_invert(godot_packed_int32_array *p_self) {
+ Vector<int32_t> *self = (Vector<int32_t> *)p_self;
+ self->invert();
+}
+
+void GDAPI godot_packed_int32_array_push_back(godot_packed_int32_array *p_self, const int32_t p_data) {
+ Vector<int32_t> *self = (Vector<int32_t> *)p_self;
+ self->push_back(p_data);
+}
+
+void GDAPI godot_packed_int32_array_remove(godot_packed_int32_array *p_self, const godot_int p_idx) {
+ Vector<int32_t> *self = (Vector<int32_t> *)p_self;
+ self->remove(p_idx);
+}
+
+void GDAPI godot_packed_int32_array_resize(godot_packed_int32_array *p_self, const godot_int p_size) {
+ Vector<int32_t> *self = (Vector<int32_t> *)p_self;
+ self->resize(p_size);
+}
+
+void GDAPI godot_packed_int32_array_set(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data) {
+ Vector<int32_t> *self = (Vector<int32_t> *)p_self;
+ self->set(p_idx, p_data);
+}
+
+int32_t GDAPI godot_packed_int32_array_get(const godot_packed_int32_array *p_self, const godot_int p_idx) {
+ const Vector<int32_t> *self = (const Vector<int32_t> *)p_self;
+ return self->get(p_idx);
+}
+
+godot_int GDAPI godot_packed_int32_array_size(const godot_packed_int32_array *p_self) {
+ const Vector<int32_t> *self = (const Vector<int32_t> *)p_self;
+ return self->size();
+}
+
+godot_bool GDAPI godot_packed_int32_array_empty(const godot_packed_int32_array *p_self) {
+ const Vector<int32_t> *self = (const Vector<int32_t> *)p_self;
+ return self->empty();
+}
+
+void GDAPI godot_packed_int32_array_destroy(godot_packed_int32_array *p_self) {
+ ((Vector<int32_t> *)p_self)->~Vector();
+}
+
+// int64
+
+void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *r_dest) {
+ Vector<int64_t> *dest = (Vector<int64_t> *)r_dest;
+ memnew_placement(dest, Vector<int64_t>);
+}
+
+void GDAPI godot_packed_int64_array_new_copy(godot_packed_int64_array *r_dest, const godot_packed_int64_array *p_src) {
+ Vector<int64_t> *dest = (Vector<int64_t> *)r_dest;
+ const Vector<int64_t> *src = (const Vector<int64_t> *)p_src;
+ memnew_placement(dest, Vector<int64_t>(*src));
+}
+
+void GDAPI godot_packed_int64_array_new_with_array(godot_packed_int64_array *r_dest, const godot_array *p_a) {
+ Vector<int64_t> *dest = (Vector<int64_t> *)r_dest;
+ Array *a = (Array *)p_a;
+ memnew_placement(dest, Vector<int64_t>);
+
+ dest->resize(a->size());
+ for (int i = 0; i < a->size(); i++) {
+ dest->set(i, (*a)[i]);
+ }
+}
+
+void GDAPI godot_packed_int64_array_append(godot_packed_int64_array *p_self, const int64_t p_data) {
+ Vector<int64_t> *self = (Vector<int64_t> *)p_self;
+ self->push_back(p_data);
+}
+
+void GDAPI godot_packed_int64_array_append_array(godot_packed_int64_array *p_self, const godot_packed_int64_array *p_array) {
+ Vector<int64_t> *self = (Vector<int64_t> *)p_self;
+ Vector<int64_t> *array = (Vector<int64_t> *)p_array;
+ self->append_array(*array);
+}
+
+godot_error GDAPI godot_packed_int64_array_insert(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data) {
+ Vector<int64_t> *self = (Vector<int64_t> *)p_self;
+ return (godot_error)self->insert(p_idx, p_data);
+}
+
+void GDAPI godot_packed_int64_array_invert(godot_packed_int64_array *p_self) {
+ Vector<int64_t> *self = (Vector<int64_t> *)p_self;
+ self->invert();
+}
+
+void GDAPI godot_packed_int64_array_push_back(godot_packed_int64_array *p_self, const int64_t p_data) {
+ Vector<int64_t> *self = (Vector<int64_t> *)p_self;
+ self->push_back(p_data);
+}
+
+void GDAPI godot_packed_int64_array_remove(godot_packed_int64_array *p_self, const godot_int p_idx) {
+ Vector<int64_t> *self = (Vector<int64_t> *)p_self;
+ self->remove(p_idx);
+}
+
+void GDAPI godot_packed_int64_array_resize(godot_packed_int64_array *p_self, const godot_int p_size) {
+ Vector<int64_t> *self = (Vector<int64_t> *)p_self;
+ self->resize(p_size);
+}
+
+void GDAPI godot_packed_int64_array_set(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data) {
+ Vector<int64_t> *self = (Vector<int64_t> *)p_self;
+ self->set(p_idx, p_data);
+}
+
+int64_t GDAPI godot_packed_int64_array_get(const godot_packed_int64_array *p_self, const godot_int p_idx) {
+ const Vector<int64_t> *self = (const Vector<int64_t> *)p_self;
+ return self->get(p_idx);
+}
+
+godot_int GDAPI godot_packed_int64_array_size(const godot_packed_int64_array *p_self) {
+ const Vector<int64_t> *self = (const Vector<int64_t> *)p_self;
+ return self->size();
+}
+
+godot_bool GDAPI godot_packed_int64_array_empty(const godot_packed_int64_array *p_self) {
+ const Vector<int64_t> *self = (const Vector<int64_t> *)p_self;
+ return self->empty();
+}
+
+void GDAPI godot_packed_int64_array_destroy(godot_packed_int64_array *p_self) {
+ ((Vector<int64_t> *)p_self)->~Vector();
+}
+
+// float32
-void GDAPI godot_packed_int_array_new(godot_packed_int_array *r_dest) {
- Vector<godot_int> *dest = (Vector<godot_int> *)r_dest;
- memnew_placement(dest, Vector<godot_int>);
+void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *r_dest) {
+ Vector<float> *dest = (Vector<float> *)r_dest;
+ memnew_placement(dest, Vector<float>);
}
-void GDAPI godot_packed_int_array_new_copy(godot_packed_int_array *r_dest, const godot_packed_int_array *p_src) {
- Vector<godot_int> *dest = (Vector<godot_int> *)r_dest;
- const Vector<godot_int> *src = (const Vector<godot_int> *)p_src;
- memnew_placement(dest, Vector<godot_int>(*src));
+void GDAPI godot_packed_float32_array_new_copy(godot_packed_float32_array *r_dest, const godot_packed_float32_array *p_src) {
+ Vector<float> *dest = (Vector<float> *)r_dest;
+ const Vector<float> *src = (const Vector<float> *)p_src;
+ memnew_placement(dest, Vector<float>(*src));
}
-void GDAPI godot_packed_int_array_new_with_array(godot_packed_int_array *r_dest, const godot_array *p_a) {
- Vector<godot_int> *dest = (Vector<godot_int> *)r_dest;
+void GDAPI godot_packed_float32_array_new_with_array(godot_packed_float32_array *r_dest, const godot_array *p_a) {
+ Vector<float> *dest = (Vector<float> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<godot_int>);
+ memnew_placement(dest, Vector<float>);
dest->resize(a->size());
for (int i = 0; i < a->size(); i++) {
@@ -152,83 +330,83 @@ void GDAPI godot_packed_int_array_new_with_array(godot_packed_int_array *r_dest,
}
}
-void GDAPI godot_packed_int_array_append(godot_packed_int_array *p_self, const godot_int p_data) {
- Vector<godot_int> *self = (Vector<godot_int> *)p_self;
+void GDAPI godot_packed_float32_array_append(godot_packed_float32_array *p_self, const float p_data) {
+ Vector<float> *self = (Vector<float> *)p_self;
self->push_back(p_data);
}
-void GDAPI godot_packed_int_array_append_array(godot_packed_int_array *p_self, const godot_packed_int_array *p_array) {
- Vector<godot_int> *self = (Vector<godot_int> *)p_self;
- Vector<godot_int> *array = (Vector<godot_int> *)p_array;
+void GDAPI godot_packed_float32_array_append_array(godot_packed_float32_array *p_self, const godot_packed_float32_array *p_array) {
+ Vector<float> *self = (Vector<float> *)p_self;
+ Vector<float> *array = (Vector<float> *)p_array;
self->append_array(*array);
}
-godot_error GDAPI godot_packed_int_array_insert(godot_packed_int_array *p_self, const godot_int p_idx, const godot_int p_data) {
- Vector<godot_int> *self = (Vector<godot_int> *)p_self;
+godot_error GDAPI godot_packed_float32_array_insert(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data) {
+ Vector<float> *self = (Vector<float> *)p_self;
return (godot_error)self->insert(p_idx, p_data);
}
-void GDAPI godot_packed_int_array_invert(godot_packed_int_array *p_self) {
- Vector<godot_int> *self = (Vector<godot_int> *)p_self;
+void GDAPI godot_packed_float32_array_invert(godot_packed_float32_array *p_self) {
+ Vector<float> *self = (Vector<float> *)p_self;
self->invert();
}
-void GDAPI godot_packed_int_array_push_back(godot_packed_int_array *p_self, const godot_int p_data) {
- Vector<godot_int> *self = (Vector<godot_int> *)p_self;
+void GDAPI godot_packed_float32_array_push_back(godot_packed_float32_array *p_self, const float p_data) {
+ Vector<float> *self = (Vector<float> *)p_self;
self->push_back(p_data);
}
-void GDAPI godot_packed_int_array_remove(godot_packed_int_array *p_self, const godot_int p_idx) {
- Vector<godot_int> *self = (Vector<godot_int> *)p_self;
+void GDAPI godot_packed_float32_array_remove(godot_packed_float32_array *p_self, const godot_int p_idx) {
+ Vector<float> *self = (Vector<float> *)p_self;
self->remove(p_idx);
}
-void GDAPI godot_packed_int_array_resize(godot_packed_int_array *p_self, const godot_int p_size) {
- Vector<godot_int> *self = (Vector<godot_int> *)p_self;
+void GDAPI godot_packed_float32_array_resize(godot_packed_float32_array *p_self, const godot_int p_size) {
+ Vector<float> *self = (Vector<float> *)p_self;
self->resize(p_size);
}
-void GDAPI godot_packed_int_array_set(godot_packed_int_array *p_self, const godot_int p_idx, const godot_int p_data) {
- Vector<godot_int> *self = (Vector<godot_int> *)p_self;
+void GDAPI godot_packed_float32_array_set(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data) {
+ Vector<float> *self = (Vector<float> *)p_self;
self->set(p_idx, p_data);
}
-godot_int GDAPI godot_packed_int_array_get(const godot_packed_int_array *p_self, const godot_int p_idx) {
- const Vector<godot_int> *self = (const Vector<godot_int> *)p_self;
+float GDAPI godot_packed_float32_array_get(const godot_packed_float32_array *p_self, const godot_int p_idx) {
+ const Vector<float> *self = (const Vector<float> *)p_self;
return self->get(p_idx);
}
-godot_int GDAPI godot_packed_int_array_size(const godot_packed_int_array *p_self) {
- const Vector<godot_int> *self = (const Vector<godot_int> *)p_self;
+godot_int GDAPI godot_packed_float32_array_size(const godot_packed_float32_array *p_self) {
+ const Vector<float> *self = (const Vector<float> *)p_self;
return self->size();
}
-godot_bool GDAPI godot_packed_int_array_empty(const godot_packed_int_array *p_self) {
- const Vector<godot_int> *self = (const Vector<godot_int> *)p_self;
+godot_bool GDAPI godot_packed_float32_array_empty(const godot_packed_float32_array *p_self) {
+ const Vector<float> *self = (const Vector<float> *)p_self;
return self->empty();
}
-void GDAPI godot_packed_int_array_destroy(godot_packed_int_array *p_self) {
- ((Vector<godot_int> *)p_self)->~Vector();
+void GDAPI godot_packed_float32_array_destroy(godot_packed_float32_array *p_self) {
+ ((Vector<float> *)p_self)->~Vector();
}
-// real
+// float64
-void GDAPI godot_packed_real_array_new(godot_packed_real_array *r_dest) {
- Vector<godot_real> *dest = (Vector<godot_real> *)r_dest;
- memnew_placement(dest, Vector<godot_real>);
+void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *r_dest) {
+ Vector<double> *dest = (Vector<double> *)r_dest;
+ memnew_placement(dest, Vector<double>);
}
-void GDAPI godot_packed_real_array_new_copy(godot_packed_real_array *r_dest, const godot_packed_real_array *p_src) {
- Vector<godot_real> *dest = (Vector<godot_real> *)r_dest;
- const Vector<godot_real> *src = (const Vector<godot_real> *)p_src;
- memnew_placement(dest, Vector<godot_real>(*src));
+void GDAPI godot_packed_float64_array_new_copy(godot_packed_float64_array *r_dest, const godot_packed_float64_array *p_src) {
+ Vector<double> *dest = (Vector<double> *)r_dest;
+ const Vector<double> *src = (const Vector<double> *)p_src;
+ memnew_placement(dest, Vector<double>(*src));
}
-void GDAPI godot_packed_real_array_new_with_array(godot_packed_real_array *r_dest, const godot_array *p_a) {
- Vector<godot_real> *dest = (Vector<godot_real> *)r_dest;
+void GDAPI godot_packed_float64_array_new_with_array(godot_packed_float64_array *r_dest, const godot_array *p_a) {
+ Vector<double> *dest = (Vector<double> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(dest, Vector<godot_real>);
+ memnew_placement(dest, Vector<double>);
dest->resize(a->size());
for (int i = 0; i < a->size(); i++) {
@@ -236,64 +414,64 @@ void GDAPI godot_packed_real_array_new_with_array(godot_packed_real_array *r_des
}
}
-void GDAPI godot_packed_real_array_append(godot_packed_real_array *p_self, const godot_real p_data) {
- Vector<godot_real> *self = (Vector<godot_real> *)p_self;
+void GDAPI godot_packed_float64_array_append(godot_packed_float64_array *p_self, const double p_data) {
+ Vector<double> *self = (Vector<double> *)p_self;
self->push_back(p_data);
}
-void GDAPI godot_packed_real_array_append_array(godot_packed_real_array *p_self, const godot_packed_real_array *p_array) {
- Vector<godot_real> *self = (Vector<godot_real> *)p_self;
- Vector<godot_real> *array = (Vector<godot_real> *)p_array;
+void GDAPI godot_packed_float64_array_append_array(godot_packed_float64_array *p_self, const godot_packed_float64_array *p_array) {
+ Vector<double> *self = (Vector<double> *)p_self;
+ Vector<double> *array = (Vector<double> *)p_array;
self->append_array(*array);
}
-godot_error GDAPI godot_packed_real_array_insert(godot_packed_real_array *p_self, const godot_int p_idx, const godot_real p_data) {
- Vector<godot_real> *self = (Vector<godot_real> *)p_self;
+godot_error GDAPI godot_packed_float64_array_insert(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data) {
+ Vector<double> *self = (Vector<double> *)p_self;
return (godot_error)self->insert(p_idx, p_data);
}
-void GDAPI godot_packed_real_array_invert(godot_packed_real_array *p_self) {
- Vector<godot_real> *self = (Vector<godot_real> *)p_self;
+void GDAPI godot_packed_float64_array_invert(godot_packed_float64_array *p_self) {
+ Vector<double> *self = (Vector<double> *)p_self;
self->invert();
}
-void GDAPI godot_packed_real_array_push_back(godot_packed_real_array *p_self, const godot_real p_data) {
- Vector<godot_real> *self = (Vector<godot_real> *)p_self;
+void GDAPI godot_packed_float64_array_push_back(godot_packed_float64_array *p_self, const double p_data) {
+ Vector<double> *self = (Vector<double> *)p_self;
self->push_back(p_data);
}
-void GDAPI godot_packed_real_array_remove(godot_packed_real_array *p_self, const godot_int p_idx) {
- Vector<godot_real> *self = (Vector<godot_real> *)p_self;
+void GDAPI godot_packed_float64_array_remove(godot_packed_float64_array *p_self, const godot_int p_idx) {
+ Vector<double> *self = (Vector<double> *)p_self;
self->remove(p_idx);
}
-void GDAPI godot_packed_real_array_resize(godot_packed_real_array *p_self, const godot_int p_size) {
- Vector<godot_real> *self = (Vector<godot_real> *)p_self;
+void GDAPI godot_packed_float64_array_resize(godot_packed_float64_array *p_self, const godot_int p_size) {
+ Vector<double> *self = (Vector<double> *)p_self;
self->resize(p_size);
}
-void GDAPI godot_packed_real_array_set(godot_packed_real_array *p_self, const godot_int p_idx, const godot_real p_data) {
- Vector<godot_real> *self = (Vector<godot_real> *)p_self;
+void GDAPI godot_packed_float64_array_set(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data) {
+ Vector<double> *self = (Vector<double> *)p_self;
self->set(p_idx, p_data);
}
-godot_real GDAPI godot_packed_real_array_get(const godot_packed_real_array *p_self, const godot_int p_idx) {
- const Vector<godot_real> *self = (const Vector<godot_real> *)p_self;
+double GDAPI godot_packed_float64_array_get(const godot_packed_float64_array *p_self, const godot_int p_idx) {
+ const Vector<double> *self = (const Vector<double> *)p_self;
return self->get(p_idx);
}
-godot_int GDAPI godot_packed_real_array_size(const godot_packed_real_array *p_self) {
- const Vector<godot_real> *self = (const Vector<godot_real> *)p_self;
+godot_int GDAPI godot_packed_float64_array_size(const godot_packed_float64_array *p_self) {
+ const Vector<double> *self = (const Vector<double> *)p_self;
return self->size();
}
-godot_bool GDAPI godot_packed_real_array_empty(const godot_packed_real_array *p_self) {
- const Vector<godot_real> *self = (const Vector<godot_real> *)p_self;
+godot_bool GDAPI godot_packed_float64_array_empty(const godot_packed_float64_array *p_self) {
+ const Vector<double> *self = (const Vector<double> *)p_self;
return self->empty();
}
-void GDAPI godot_packed_real_array_destroy(godot_packed_real_array *p_self) {
- ((Vector<godot_real> *)p_self)->~Vector();
+void GDAPI godot_packed_float64_array_destroy(godot_packed_float64_array *p_self) {
+ ((Vector<double> *)p_self)->~Vector();
}
// string
diff --git a/modules/gdnative/gdnative/plane.cpp b/modules/gdnative/gdnative/plane.cpp
index 17221fe081..663937f906 100644
--- a/modules/gdnative/gdnative/plane.cpp
+++ b/modules/gdnative/gdnative/plane.cpp
@@ -37,8 +37,9 @@
extern "C" {
#endif
-void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d) {
+static_assert(sizeof(godot_plane) == sizeof(Plane), "Plane size mismatch");
+void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d) {
Plane *dest = (Plane *)r_dest;
*dest = Plane(p_a, p_b, p_c, p_d);
}
diff --git a/modules/gdnative/gdnative/quat.cpp b/modules/gdnative/gdnative/quat.cpp
index be30b89e5f..de6308ad2a 100644
--- a/modules/gdnative/gdnative/quat.cpp
+++ b/modules/gdnative/gdnative/quat.cpp
@@ -37,8 +37,9 @@
extern "C" {
#endif
-void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w) {
+static_assert(sizeof(godot_quat) == sizeof(Quat), "Quat size mismatch");
+void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w) {
Quat *dest = (Quat *)r_dest;
*dest = Quat(p_x, p_y, p_z, p_w);
}
diff --git a/modules/gdnative/gdnative/rect2.cpp b/modules/gdnative/gdnative/rect2.cpp
index 906b4f0932..516f4d75ce 100644
--- a/modules/gdnative/gdnative/rect2.cpp
+++ b/modules/gdnative/gdnative/rect2.cpp
@@ -37,6 +37,11 @@
extern "C" {
#endif
+static_assert(sizeof(godot_rect2) == sizeof(Rect2), "Rect2 size mismatch");
+static_assert(sizeof(godot_rect2i) == sizeof(Rect2i), "Rect2i size mismatch");
+
+// Rect2
+
void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size) {
const Vector2 *position = (const Vector2 *)p_pos;
const Vector2 *size = (const Vector2 *)p_size;
@@ -45,7 +50,6 @@ void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const god
}
void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height) {
-
Rect2 *dest = (Rect2 *)r_dest;
*dest = Rect2(p_x, p_y, p_width, p_height);
}
@@ -57,6 +61,13 @@ godot_string GDAPI godot_rect2_as_string(const godot_rect2 *p_self) {
return ret;
}
+godot_rect2i GDAPI godot_rect2_as_rect2i(const godot_rect2 *p_self) {
+ godot_rect2i dest;
+ const Rect2 *self = (const Rect2 *)p_self;
+ *((Rect2i *)&dest) = Rect2i(*self);
+ return dest;
+}
+
godot_real GDAPI godot_rect2_get_area(const godot_rect2 *p_self) {
const Rect2 *self = (const Rect2 *)p_self;
return self->get_area();
@@ -172,6 +183,149 @@ void GDAPI godot_rect2_set_size(godot_rect2 *p_self, const godot_vector2 *p_size
self->set_size(*size);
}
+// Rect2i
+
+void GDAPI godot_rect2i_new_with_position_and_size(godot_rect2i *r_dest, const godot_vector2i *p_pos, const godot_vector2i *p_size) {
+ const Vector2i *position = (const Vector2i *)p_pos;
+ const Vector2i *size = (const Vector2i *)p_size;
+ Rect2i *dest = (Rect2i *)r_dest;
+ *dest = Rect2i(*position, *size);
+}
+
+void GDAPI godot_rect2i_new(godot_rect2i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_width, const godot_int p_height) {
+ Rect2i *dest = (Rect2i *)r_dest;
+ *dest = Rect2i(p_x, p_y, p_width, p_height);
+}
+
+godot_string GDAPI godot_rect2i_as_string(const godot_rect2i *p_self) {
+ godot_string ret;
+ const Rect2i *self = (const Rect2i *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
+}
+
+godot_rect2 GDAPI godot_rect2i_as_rect2(const godot_rect2i *p_self) {
+ godot_rect2 dest;
+ const Rect2i *self = (const Rect2i *)p_self;
+ *((Rect2 *)&dest) = Rect2(*self);
+ return dest;
+}
+
+godot_int GDAPI godot_rect2i_get_area(const godot_rect2i *p_self) {
+ const Rect2i *self = (const Rect2i *)p_self;
+ return self->get_area();
+}
+
+godot_bool GDAPI godot_rect2i_intersects(const godot_rect2i *p_self, const godot_rect2i *p_b) {
+ const Rect2i *self = (const Rect2i *)p_self;
+ const Rect2i *b = (const Rect2i *)p_b;
+ return self->intersects(*b);
+}
+
+godot_bool GDAPI godot_rect2i_encloses(const godot_rect2i *p_self, const godot_rect2i *p_b) {
+ const Rect2i *self = (const Rect2i *)p_self;
+ const Rect2i *b = (const Rect2i *)p_b;
+ return self->encloses(*b);
+}
+
+godot_bool GDAPI godot_rect2i_has_no_area(const godot_rect2i *p_self) {
+ const Rect2i *self = (const Rect2i *)p_self;
+ return self->has_no_area();
+}
+
+godot_rect2i GDAPI godot_rect2i_clip(const godot_rect2i *p_self, const godot_rect2i *p_b) {
+ godot_rect2i dest;
+ const Rect2i *self = (const Rect2i *)p_self;
+ const Rect2i *b = (const Rect2i *)p_b;
+ *((Rect2i *)&dest) = self->clip(*b);
+ return dest;
+}
+
+godot_rect2i GDAPI godot_rect2i_merge(const godot_rect2i *p_self, const godot_rect2i *p_b) {
+ godot_rect2i dest;
+ const Rect2i *self = (const Rect2i *)p_self;
+ const Rect2i *b = (const Rect2i *)p_b;
+ *((Rect2i *)&dest) = self->merge(*b);
+ return dest;
+}
+
+godot_bool GDAPI godot_rect2i_has_point(const godot_rect2i *p_self, const godot_vector2i *p_point) {
+ const Rect2i *self = (const Rect2i *)p_self;
+ const Vector2i *point = (const Vector2i *)p_point;
+ return self->has_point(*point);
+}
+
+godot_rect2i GDAPI godot_rect2i_grow(const godot_rect2i *p_self, const godot_int p_by) {
+ godot_rect2i dest;
+ const Rect2i *self = (const Rect2i *)p_self;
+
+ *((Rect2i *)&dest) = self->grow(p_by);
+ return dest;
+}
+
+godot_rect2i GDAPI godot_rect2i_grow_individual(const godot_rect2i *p_self, const godot_int p_left, const godot_int p_top, const godot_int p_right, const godot_int p_bottom) {
+ godot_rect2i dest;
+ const Rect2i *self = (const Rect2i *)p_self;
+ *((Rect2i *)&dest) = self->grow_individual(p_left, p_top, p_right, p_bottom);
+ return dest;
+}
+
+godot_rect2i GDAPI godot_rect2i_grow_margin(const godot_rect2i *p_self, const godot_int p_margin, const godot_int p_by) {
+ godot_rect2i dest;
+ const Rect2i *self = (const Rect2i *)p_self;
+ *((Rect2i *)&dest) = self->grow_margin((Margin)p_margin, p_by);
+ return dest;
+}
+
+godot_rect2i GDAPI godot_rect2i_abs(const godot_rect2i *p_self) {
+ godot_rect2i dest;
+ const Rect2i *self = (const Rect2i *)p_self;
+ *((Rect2i *)&dest) = self->abs();
+ return dest;
+}
+
+godot_rect2i GDAPI godot_rect2i_expand(const godot_rect2i *p_self, const godot_vector2i *p_to) {
+ godot_rect2i dest;
+ const Rect2i *self = (const Rect2i *)p_self;
+ const Vector2i *to = (const Vector2i *)p_to;
+ *((Rect2i *)&dest) = self->expand(*to);
+ return dest;
+}
+
+godot_bool GDAPI godot_rect2i_operator_equal(const godot_rect2i *p_self, const godot_rect2i *p_b) {
+ const Rect2i *self = (const Rect2i *)p_self;
+ const Rect2i *b = (const Rect2i *)p_b;
+ return *self == *b;
+}
+
+godot_vector2i GDAPI godot_rect2i_get_position(const godot_rect2i *p_self) {
+ godot_vector2i dest;
+ Vector2i *d = (Vector2i *)&dest;
+ const Rect2i *self = (const Rect2i *)p_self;
+ *d = self->get_position();
+ return dest;
+}
+
+godot_vector2i GDAPI godot_rect2i_get_size(const godot_rect2i *p_self) {
+ godot_vector2i dest;
+ Vector2i *d = (Vector2i *)&dest;
+ const Rect2i *self = (const Rect2i *)p_self;
+ *d = self->get_size();
+ return dest;
+}
+
+void GDAPI godot_rect2i_set_position(godot_rect2i *p_self, const godot_vector2i *p_pos) {
+ Rect2i *self = (Rect2i *)p_self;
+ const Vector2i *position = (const Vector2i *)p_pos;
+ self->set_position(*position);
+}
+
+void GDAPI godot_rect2i_set_size(godot_rect2i *p_self, const godot_vector2i *p_size) {
+ Rect2i *self = (Rect2i *)p_self;
+ const Vector2i *size = (const Vector2i *)p_size;
+ self->set_size(*size);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/rid.cpp b/modules/gdnative/gdnative/rid.cpp
index 7ea80123a3..d7a63f33a7 100644
--- a/modules/gdnative/gdnative/rid.cpp
+++ b/modules/gdnative/gdnative/rid.cpp
@@ -38,6 +38,8 @@
extern "C" {
#endif
+static_assert(sizeof(godot_rid) == sizeof(RID), "RID size mismatch");
+
void GDAPI godot_rid_new(godot_rid *r_dest) {
RID *dest = (RID *)r_dest;
memnew_placement(dest, RID);
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 4cb55900b0..724a4b56cb 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -40,6 +40,10 @@
extern "C" {
#endif
+static_assert(sizeof(godot_char_string) == sizeof(CharString), "CharString size mismatch");
+static_assert(sizeof(godot_string) == sizeof(String), "String size mismatch");
+static_assert(sizeof(godot_char_type) == sizeof(CharType), "CharType size mismatch");
+
godot_int GDAPI godot_char_string_length(const godot_char_string *p_cs) {
const CharString *cs = (const CharString *)p_cs;
@@ -137,6 +141,7 @@ signed char GDAPI godot_string_nocasecmp_to(const godot_string *p_self, const go
return self->nocasecmp_to(*str);
}
+
signed char GDAPI godot_string_naturalnocasecmp_to(const godot_string *p_self, const godot_string *p_str) {
const String *self = (const String *)p_self;
const String *str = (const String *)p_str;
diff --git a/modules/gdnative/gdnative/string_name.cpp b/modules/gdnative/gdnative/string_name.cpp
index 1abb4486b1..7bbaaeeaa0 100644
--- a/modules/gdnative/gdnative/string_name.cpp
+++ b/modules/gdnative/gdnative/string_name.cpp
@@ -39,6 +39,8 @@
extern "C" {
#endif
+static_assert(sizeof(godot_string_name) == sizeof(StringName), "StringName size mismatch");
+
void GDAPI godot_string_name_new(godot_string_name *r_dest, const godot_string *p_name) {
StringName *dest = (StringName *)r_dest;
const String *name = (const String *)p_name;
diff --git a/modules/gdnative/gdnative/transform.cpp b/modules/gdnative/gdnative/transform.cpp
index c9b3e37fb2..d19de93e9b 100644
--- a/modules/gdnative/gdnative/transform.cpp
+++ b/modules/gdnative/gdnative/transform.cpp
@@ -37,6 +37,8 @@
extern "C" {
#endif
+static_assert(sizeof(godot_transform) == sizeof(Transform), "Transform size mismatch");
+
void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin) {
const Vector3 *x_axis = (const Vector3 *)p_x_axis;
const Vector3 *y_axis = (const Vector3 *)p_y_axis;
diff --git a/modules/gdnative/gdnative/transform2d.cpp b/modules/gdnative/gdnative/transform2d.cpp
index 26a71333b1..c0f7878eb0 100644
--- a/modules/gdnative/gdnative/transform2d.cpp
+++ b/modules/gdnative/gdnative/transform2d.cpp
@@ -37,6 +37,8 @@
extern "C" {
#endif
+static_assert(sizeof(godot_transform2d) == sizeof(Transform2D), "Transform2D size mismatch");
+
void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos) {
const Vector2 *pos = (const Vector2 *)p_pos;
Transform2D *dest = (Transform2D *)r_dest;
diff --git a/modules/gdnative/gdnative/variant.cpp b/modules/gdnative/gdnative/variant.cpp
index f0fc44ae8a..dac4feb0e5 100644
--- a/modules/gdnative/gdnative/variant.cpp
+++ b/modules/gdnative/gdnative/variant.cpp
@@ -37,6 +37,8 @@
extern "C" {
#endif
+static_assert(sizeof(godot_variant) == sizeof(Variant), "Variant size mismatch");
+
// Workaround GCC ICE on armv7hl which was affected GCC 6.0 up to 8.0 (GH-16100).
// It was fixed upstream in 8.1, and a fix was backported to 7.4.
// This can be removed once no supported distro ships with versions older than 7.4.
@@ -97,24 +99,48 @@ void GDAPI godot_variant_new_string(godot_variant *r_dest, const godot_string *p
memnew_placement_custom(dest, Variant, Variant(*s));
}
+void GDAPI godot_variant_new_string_name(godot_variant *r_dest, const godot_string_name *p_s) {
+ Variant *dest = (Variant *)r_dest;
+ StringName *s = (StringName *)p_s;
+ memnew_placement_custom(dest, Variant, Variant(*s));
+}
+
void GDAPI godot_variant_new_vector2(godot_variant *r_dest, const godot_vector2 *p_v2) {
Variant *dest = (Variant *)r_dest;
Vector2 *v2 = (Vector2 *)p_v2;
memnew_placement_custom(dest, Variant, Variant(*v2));
}
+void GDAPI godot_variant_new_vector2i(godot_variant *r_dest, const godot_vector2i *p_v2) {
+ Variant *dest = (Variant *)r_dest;
+ Vector2i *v2 = (Vector2i *)p_v2;
+ memnew_placement_custom(dest, Variant, Variant(*v2));
+}
+
void GDAPI godot_variant_new_rect2(godot_variant *r_dest, const godot_rect2 *p_rect2) {
Variant *dest = (Variant *)r_dest;
Rect2 *rect2 = (Rect2 *)p_rect2;
memnew_placement_custom(dest, Variant, Variant(*rect2));
}
+void GDAPI godot_variant_new_rect2i(godot_variant *r_dest, const godot_rect2i *p_rect2) {
+ Variant *dest = (Variant *)r_dest;
+ Rect2i *rect2 = (Rect2i *)p_rect2;
+ memnew_placement_custom(dest, Variant, Variant(*rect2));
+}
+
void GDAPI godot_variant_new_vector3(godot_variant *r_dest, const godot_vector3 *p_v3) {
Variant *dest = (Variant *)r_dest;
Vector3 *v3 = (Vector3 *)p_v3;
memnew_placement_custom(dest, Variant, Variant(*v3));
}
+void GDAPI godot_variant_new_vector3i(godot_variant *r_dest, const godot_vector3i *p_v3) {
+ Variant *dest = (Variant *)r_dest;
+ Vector3i *v3 = (Vector3i *)p_v3;
+ memnew_placement_custom(dest, Variant, Variant(*v3));
+}
+
void GDAPI godot_variant_new_transform2d(godot_variant *r_dest, const godot_transform2d *p_t2d) {
Variant *dest = (Variant *)r_dest;
Transform2D *t2d = (Transform2D *)p_t2d;
@@ -169,6 +195,18 @@ void GDAPI godot_variant_new_rid(godot_variant *r_dest, const godot_rid *p_rid)
memnew_placement_custom(dest, Variant, Variant(*rid));
}
+void GDAPI godot_variant_new_callable(godot_variant *r_dest, const godot_callable *p_cb) {
+ Variant *dest = (Variant *)r_dest;
+ Callable *cb = (Callable *)p_cb;
+ memnew_placement_custom(dest, Variant, Variant(*cb));
+}
+
+void GDAPI godot_variant_new_signal(godot_variant *r_dest, const godot_signal *p_signal) {
+ Variant *dest = (Variant *)r_dest;
+ Signal *signal = (Signal *)p_signal;
+ memnew_placement_custom(dest, Variant, Variant(*signal));
+}
+
void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj) {
Variant *dest = (Variant *)r_dest;
Object *obj = (Object *)p_obj;
@@ -207,18 +245,30 @@ void GDAPI godot_variant_new_packed_byte_array(godot_variant *r_dest, const godo
memnew_placement_custom(dest, Variant, Variant(*pba));
}
-void GDAPI godot_variant_new_packed_int_array(godot_variant *r_dest, const godot_packed_int_array *p_pia) {
+void GDAPI godot_variant_new_packed_int32_array(godot_variant *r_dest, const godot_packed_int32_array *p_pia) {
Variant *dest = (Variant *)r_dest;
PackedInt32Array *pia = (PackedInt32Array *)p_pia;
memnew_placement_custom(dest, Variant, Variant(*pia));
}
-void GDAPI godot_variant_new_packed_real_array(godot_variant *r_dest, const godot_packed_real_array *p_pra) {
+void GDAPI godot_variant_new_packed_int64_array(godot_variant *r_dest, const godot_packed_int64_array *p_pia) {
+ Variant *dest = (Variant *)r_dest;
+ PackedInt64Array *pia = (PackedInt64Array *)p_pia;
+ memnew_placement_custom(dest, Variant, Variant(*pia));
+}
+
+void GDAPI godot_variant_new_packed_float32_array(godot_variant *r_dest, const godot_packed_float32_array *p_pra) {
Variant *dest = (Variant *)r_dest;
PackedFloat32Array *pra = (PackedFloat32Array *)p_pra;
memnew_placement_custom(dest, Variant, Variant(*pra));
}
+void GDAPI godot_variant_new_packed_float64_array(godot_variant *r_dest, const godot_packed_float64_array *p_pra) {
+ Variant *dest = (Variant *)r_dest;
+ PackedFloat64Array *pra = (PackedFloat64Array *)p_pra;
+ memnew_placement_custom(dest, Variant, Variant(*pra));
+}
+
void GDAPI godot_variant_new_packed_string_array(godot_variant *r_dest, const godot_packed_string_array *p_psa) {
Variant *dest = (Variant *)r_dest;
PackedStringArray *psa = (PackedStringArray *)p_psa;
@@ -271,6 +321,14 @@ godot_string GDAPI godot_variant_as_string(const godot_variant *p_self) {
return raw_dest;
}
+godot_string_name GDAPI godot_variant_as_string_name(const godot_variant *p_self) {
+ godot_string_name raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ StringName *dest = (StringName *)&raw_dest;
+ memnew_placement(dest, StringName(self->operator StringName())); // operator = is overloaded by StringName
+ return raw_dest;
+}
+
godot_vector2 GDAPI godot_variant_as_vector2(const godot_variant *p_self) {
godot_vector2 raw_dest;
const Variant *self = (const Variant *)p_self;
@@ -279,6 +337,14 @@ godot_vector2 GDAPI godot_variant_as_vector2(const godot_variant *p_self) {
return raw_dest;
}
+godot_vector2i GDAPI godot_variant_as_vector2i(const godot_variant *p_self) {
+ godot_vector2i raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Vector2i *dest = (Vector2i *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
+}
+
godot_rect2 GDAPI godot_variant_as_rect2(const godot_variant *p_self) {
godot_rect2 raw_dest;
const Variant *self = (const Variant *)p_self;
@@ -287,6 +353,14 @@ godot_rect2 GDAPI godot_variant_as_rect2(const godot_variant *p_self) {
return raw_dest;
}
+godot_rect2i GDAPI godot_variant_as_rect2i(const godot_variant *p_self) {
+ godot_rect2i raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Rect2i *dest = (Rect2i *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
+}
+
godot_vector3 GDAPI godot_variant_as_vector3(const godot_variant *p_self) {
godot_vector3 raw_dest;
const Variant *self = (const Variant *)p_self;
@@ -295,6 +369,14 @@ godot_vector3 GDAPI godot_variant_as_vector3(const godot_variant *p_self) {
return raw_dest;
}
+godot_vector3i GDAPI godot_variant_as_vector3i(const godot_variant *p_self) {
+ godot_vector3i raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Vector3i *dest = (Vector3i *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
+}
+
godot_transform2d GDAPI godot_variant_as_transform2d(const godot_variant *p_self) {
godot_transform2d raw_dest;
const Variant *self = (const Variant *)p_self;
@@ -367,6 +449,22 @@ godot_rid GDAPI godot_variant_as_rid(const godot_variant *p_self) {
return raw_dest;
}
+godot_callable GDAPI godot_variant_as_callable(const godot_variant *p_self) {
+ godot_callable raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Callable *dest = (Callable *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
+}
+
+godot_signal GDAPI godot_variant_as_signal(const godot_variant *p_self) {
+ godot_signal raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Signal *dest = (Signal *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
+}
+
godot_object GDAPI *godot_variant_as_object(const godot_variant *p_self) {
const Variant *self = (const Variant *)p_self;
Object *dest;
@@ -399,8 +497,8 @@ godot_packed_byte_array GDAPI godot_variant_as_packed_byte_array(const godot_var
return raw_dest;
}
-godot_packed_int_array GDAPI godot_variant_as_packed_int_array(const godot_variant *p_self) {
- godot_packed_int_array raw_dest;
+godot_packed_int32_array GDAPI godot_variant_as_packed_int32_array(const godot_variant *p_self) {
+ godot_packed_int32_array raw_dest;
const Variant *self = (const Variant *)p_self;
PackedInt32Array *dest = (PackedInt32Array *)&raw_dest;
memnew_placement(dest, PackedInt32Array(self->operator PackedInt32Array())); // operator = is overloaded by PackedInt32Array
@@ -408,8 +506,17 @@ godot_packed_int_array GDAPI godot_variant_as_packed_int_array(const godot_varia
return raw_dest;
}
-godot_packed_real_array GDAPI godot_variant_as_packed_real_array(const godot_variant *p_self) {
- godot_packed_real_array raw_dest;
+godot_packed_int64_array GDAPI godot_variant_as_packed_int64_array(const godot_variant *p_self) {
+ godot_packed_int64_array raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ PackedInt64Array *dest = (PackedInt64Array *)&raw_dest;
+ memnew_placement(dest, PackedInt64Array(self->operator PackedInt64Array())); // operator = is overloaded by PackedInt64Array
+ *dest = *self;
+ return raw_dest;
+}
+
+godot_packed_float32_array GDAPI godot_variant_as_packed_float32_array(const godot_variant *p_self) {
+ godot_packed_float32_array raw_dest;
const Variant *self = (const Variant *)p_self;
PackedFloat32Array *dest = (PackedFloat32Array *)&raw_dest;
memnew_placement(dest, PackedFloat32Array(self->operator PackedFloat32Array())); // operator = is overloaded by PackedFloat32Array
@@ -417,6 +524,15 @@ godot_packed_real_array GDAPI godot_variant_as_packed_real_array(const godot_var
return raw_dest;
}
+godot_packed_float64_array GDAPI godot_variant_as_packed_float64_array(const godot_variant *p_self) {
+ godot_packed_float64_array raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ PackedFloat64Array *dest = (PackedFloat64Array *)&raw_dest;
+ memnew_placement(dest, PackedFloat64Array(self->operator PackedFloat64Array())); // operator = is overloaded by PackedFloat64Array
+ *dest = *self;
+ return raw_dest;
+}
+
godot_packed_string_array GDAPI godot_variant_as_packed_string_array(const godot_variant *p_self) {
godot_packed_string_array raw_dest;
const Variant *self = (const Variant *)p_self;
@@ -487,6 +603,11 @@ godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_self, const
return self->operator<(*other);
}
+uint32_t GDAPI godot_variant_hash(const godot_variant *p_self) {
+ const Variant *self = (const Variant *)p_self;
+ return self->hash();
+}
+
godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const godot_variant *p_other) {
const Variant *self = (const Variant *)p_self;
const Variant *other = (const Variant *)p_other;
diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp
index e9e2a8edf8..1ee716df86 100644
--- a/modules/gdnative/gdnative/vector2.cpp
+++ b/modules/gdnative/gdnative/vector2.cpp
@@ -37,8 +37,12 @@
extern "C" {
#endif
-void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y) {
+static_assert(sizeof(godot_vector2) == sizeof(Vector2), "Vector2 size mismatch");
+static_assert(sizeof(godot_vector2i) == sizeof(Vector2i), "Vector2i size mismatch");
+
+// Vector2
+void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y) {
Vector2 *dest = (Vector2 *)r_dest;
*dest = Vector2(p_x, p_y);
}
@@ -50,6 +54,13 @@ godot_string GDAPI godot_vector2_as_string(const godot_vector2 *p_self) {
return ret;
}
+godot_vector2i GDAPI godot_vector2_as_vector2i(const godot_vector2 *p_self) {
+ godot_vector2i dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ *((Vector2i *)&dest) = Vector2i(*self);
+ return dest;
+}
+
godot_vector2 GDAPI godot_vector2_normalized(const godot_vector2 *p_self) {
godot_vector2 dest;
const Vector2 *self = (const Vector2 *)p_self;
@@ -109,11 +120,11 @@ godot_real GDAPI godot_vector2_angle_to_point(const godot_vector2 *p_self, const
return self->angle_to_point(*to);
}
-godot_vector2 GDAPI godot_vector2_linear_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_real p_t) {
+godot_vector2 GDAPI godot_vector2_lerp(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_real p_t) {
godot_vector2 dest;
const Vector2 *self = (const Vector2 *)p_self;
const Vector2 *b = (const Vector2 *)p_b;
- *((Vector2 *)&dest) = self->linear_interpolate(*b, p_t);
+ *((Vector2 *)&dest) = self->lerp(*b, p_t);
return dest;
}
@@ -157,6 +168,13 @@ godot_vector2 GDAPI godot_vector2_floor(const godot_vector2 *p_self) {
return dest;
}
+godot_vector2 GDAPI godot_vector2_sign(const godot_vector2 *p_self) {
+ godot_vector2 dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ *((Vector2 *)&dest) = self->sign();
+ return dest;
+}
+
godot_vector2 GDAPI godot_vector2_snapped(const godot_vector2 *p_self, const godot_vector2 *p_by) {
godot_vector2 dest;
const Vector2 *self = (const Vector2 *)p_self;
@@ -307,6 +325,138 @@ godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_self) {
return self->y;
}
+// Vector2i
+
+void GDAPI godot_vector2i_new(godot_vector2i *r_dest, const godot_int p_x, const godot_int p_y) {
+ Vector2i *dest = (Vector2i *)r_dest;
+ *dest = Vector2i(p_x, p_y);
+}
+
+godot_string GDAPI godot_vector2i_as_string(const godot_vector2i *p_self) {
+ godot_string ret;
+ const Vector2i *self = (const Vector2i *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
+}
+
+godot_vector2 GDAPI godot_vector2i_as_vector2(const godot_vector2i *p_self) {
+ godot_vector2 dest;
+ const Vector2i *self = (const Vector2i *)p_self;
+ *((Vector2 *)&dest) = Vector2(*self);
+ return dest;
+}
+
+godot_real GDAPI godot_vector2i_aspect(const godot_vector2i *p_self) {
+ const Vector2i *self = (const Vector2i *)p_self;
+ return self->aspect();
+}
+
+godot_vector2i GDAPI godot_vector2i_abs(const godot_vector2i *p_self) {
+ godot_vector2i dest;
+ const Vector2i *self = (const Vector2i *)p_self;
+ *((Vector2i *)&dest) = self->abs();
+ return dest;
+}
+
+godot_vector2i GDAPI godot_vector2i_sign(const godot_vector2i *p_self) {
+ godot_vector2i dest;
+ const Vector2i *self = (const Vector2i *)p_self;
+ *((Vector2i *)&dest) = self->sign();
+ return dest;
+}
+
+godot_vector2i GDAPI godot_vector2i_operator_add(const godot_vector2i *p_self, const godot_vector2i *p_b) {
+ godot_vector2i raw_dest;
+ Vector2i *dest = (Vector2i *)&raw_dest;
+ const Vector2i *self = (const Vector2i *)p_self;
+ const Vector2i *b = (const Vector2i *)p_b;
+ *dest = *self + *b;
+ return raw_dest;
+}
+
+godot_vector2i GDAPI godot_vector2i_operator_subtract(const godot_vector2i *p_self, const godot_vector2i *p_b) {
+ godot_vector2i raw_dest;
+ Vector2i *dest = (Vector2i *)&raw_dest;
+ const Vector2i *self = (const Vector2i *)p_self;
+ const Vector2i *b = (const Vector2i *)p_b;
+ *dest = *self - *b;
+ return raw_dest;
+}
+
+godot_vector2i GDAPI godot_vector2i_operator_multiply_vector(const godot_vector2i *p_self, const godot_vector2i *p_b) {
+ godot_vector2i raw_dest;
+ Vector2i *dest = (Vector2i *)&raw_dest;
+ const Vector2i *self = (const Vector2i *)p_self;
+ const Vector2i *b = (const Vector2i *)p_b;
+ *dest = *self * *b;
+ return raw_dest;
+}
+
+godot_vector2i GDAPI godot_vector2i_operator_multiply_scalar(const godot_vector2i *p_self, const godot_int p_b) {
+ godot_vector2i raw_dest;
+ Vector2i *dest = (Vector2i *)&raw_dest;
+ const Vector2i *self = (const Vector2i *)p_self;
+ *dest = *self * p_b;
+ return raw_dest;
+}
+
+godot_vector2i GDAPI godot_vector2i_operator_divide_vector(const godot_vector2i *p_self, const godot_vector2i *p_b) {
+ godot_vector2i raw_dest;
+ Vector2i *dest = (Vector2i *)&raw_dest;
+ const Vector2i *self = (const Vector2i *)p_self;
+ const Vector2i *b = (const Vector2i *)p_b;
+ *dest = *self / *b;
+ return raw_dest;
+}
+
+godot_vector2i GDAPI godot_vector2i_operator_divide_scalar(const godot_vector2i *p_self, const godot_int p_b) {
+ godot_vector2i raw_dest;
+ Vector2i *dest = (Vector2i *)&raw_dest;
+ const Vector2i *self = (const Vector2i *)p_self;
+ *dest = *self / p_b;
+ return raw_dest;
+}
+
+godot_bool GDAPI godot_vector2i_operator_equal(const godot_vector2i *p_self, const godot_vector2i *p_b) {
+ const Vector2i *self = (const Vector2i *)p_self;
+ const Vector2i *b = (const Vector2i *)p_b;
+ return *self == *b;
+}
+
+godot_bool GDAPI godot_vector2i_operator_less(const godot_vector2i *p_self, const godot_vector2i *p_b) {
+ const Vector2i *self = (const Vector2i *)p_self;
+ const Vector2i *b = (const Vector2i *)p_b;
+ return *self < *b;
+}
+
+godot_vector2i GDAPI godot_vector2i_operator_neg(const godot_vector2i *p_self) {
+ godot_vector2i raw_dest;
+ Vector2i *dest = (Vector2i *)&raw_dest;
+ const Vector2i *self = (const Vector2i *)p_self;
+ *dest = -(*self);
+ return raw_dest;
+}
+
+void GDAPI godot_vector2i_set_x(godot_vector2i *p_self, const godot_int p_x) {
+ Vector2i *self = (Vector2i *)p_self;
+ self->x = p_x;
+}
+
+void GDAPI godot_vector2i_set_y(godot_vector2i *p_self, const godot_int p_y) {
+ Vector2i *self = (Vector2i *)p_self;
+ self->y = p_y;
+}
+
+godot_int GDAPI godot_vector2i_get_x(const godot_vector2i *p_self) {
+ const Vector2i *self = (const Vector2i *)p_self;
+ return self->x;
+}
+
+godot_int GDAPI godot_vector2i_get_y(const godot_vector2i *p_self) {
+ const Vector2i *self = (const Vector2i *)p_self;
+ return self->y;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp
index e34a9370a5..32cad30c17 100644
--- a/modules/gdnative/gdnative/vector3.cpp
+++ b/modules/gdnative/gdnative/vector3.cpp
@@ -37,8 +37,12 @@
extern "C" {
#endif
-void GDAPI godot_vector3_new(godot_vector3 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z) {
+static_assert(sizeof(godot_vector3) == sizeof(Vector3), "Vector3 size mismatch");
+static_assert(sizeof(godot_vector3i) == sizeof(Vector3i), "Vector3i size mismatch");
+
+// Vector3
+void GDAPI godot_vector3_new(godot_vector3 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z) {
Vector3 *dest = (Vector3 *)r_dest;
*dest = Vector3(p_x, p_y, p_z);
}
@@ -50,6 +54,13 @@ godot_string GDAPI godot_vector3_as_string(const godot_vector3 *p_self) {
return ret;
}
+godot_vector3i GDAPI godot_vector3_as_vector3i(const godot_vector3 *p_self) {
+ godot_vector3i dest;
+ const Vector3 *self = (const Vector3 *)p_self;
+ *((Vector3i *)&dest) = Vector3i(*self);
+ return dest;
+}
+
godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_self) {
const Vector3 *self = (const Vector3 *)p_self;
return self->min_axis();
@@ -106,11 +117,11 @@ godot_vector3 GDAPI godot_vector3_rotated(const godot_vector3 *p_self, const god
return dest;
}
-godot_vector3 GDAPI godot_vector3_linear_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_real p_t) {
+godot_vector3 GDAPI godot_vector3_lerp(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_real p_t) {
godot_vector3 dest;
const Vector3 *self = (const Vector3 *)p_self;
const Vector3 *b = (const Vector3 *)p_b;
- *((Vector3 *)&dest) = self->linear_interpolate(*b, p_t);
+ *((Vector3 *)&dest) = self->lerp(*b, p_t);
return dest;
}
@@ -168,6 +179,13 @@ godot_vector3 GDAPI godot_vector3_abs(const godot_vector3 *p_self) {
return dest;
}
+godot_vector3 GDAPI godot_vector3_sign(const godot_vector3 *p_self) {
+ godot_vector3 dest;
+ const Vector3 *self = (const Vector3 *)p_self;
+ *((Vector3 *)&dest) = self->sign();
+ return dest;
+}
+
godot_vector3 GDAPI godot_vector3_floor(const godot_vector3 *p_self) {
godot_vector3 dest;
const Vector3 *self = (const Vector3 *)p_self;
@@ -314,6 +332,133 @@ godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_self, const godot
return self->get_axis(p_axis);
}
+// Vector3i
+
+void GDAPI godot_vector3i_new(godot_vector3i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_z) {
+ Vector3i *dest = (Vector3i *)r_dest;
+ *dest = Vector3i(p_x, p_y, p_z);
+}
+
+godot_string GDAPI godot_vector3i_as_string(const godot_vector3i *p_self) {
+ godot_string ret;
+ const Vector3i *self = (const Vector3i *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
+}
+
+godot_vector3 GDAPI godot_vector3i_as_vector3(const godot_vector3i *p_self) {
+ godot_vector3 dest;
+ const Vector3i *self = (const Vector3i *)p_self;
+ *((Vector3 *)&dest) = Vector3(*self);
+ return dest;
+}
+
+godot_int GDAPI godot_vector3i_min_axis(const godot_vector3i *p_self) {
+ const Vector3i *self = (const Vector3i *)p_self;
+ return self->min_axis();
+}
+
+godot_int GDAPI godot_vector3i_max_axis(const godot_vector3i *p_self) {
+ const Vector3i *self = (const Vector3i *)p_self;
+ return self->max_axis();
+}
+
+godot_vector3i GDAPI godot_vector3i_abs(const godot_vector3i *p_self) {
+ godot_vector3i dest;
+ const Vector3i *self = (const Vector3i *)p_self;
+ *((Vector3i *)&dest) = self->abs();
+ return dest;
+}
+
+godot_vector3i GDAPI godot_vector3i_sign(const godot_vector3i *p_self) {
+ godot_vector3i dest;
+ const Vector3i *self = (const Vector3i *)p_self;
+ *((Vector3i *)&dest) = self->sign();
+ return dest;
+}
+
+godot_vector3i GDAPI godot_vector3i_operator_add(const godot_vector3i *p_self, const godot_vector3i *p_b) {
+ godot_vector3i raw_dest;
+ Vector3i *dest = (Vector3i *)&raw_dest;
+ Vector3i *self = (Vector3i *)p_self;
+ const Vector3i *b = (const Vector3i *)p_b;
+ *dest = *self + *b;
+ return raw_dest;
+}
+
+godot_vector3i GDAPI godot_vector3i_operator_subtract(const godot_vector3i *p_self, const godot_vector3i *p_b) {
+ godot_vector3i raw_dest;
+ Vector3i *dest = (Vector3i *)&raw_dest;
+ Vector3i *self = (Vector3i *)p_self;
+ const Vector3i *b = (const Vector3i *)p_b;
+ *dest = *self - *b;
+ return raw_dest;
+}
+
+godot_vector3i GDAPI godot_vector3i_operator_multiply_vector(const godot_vector3i *p_self, const godot_vector3i *p_b) {
+ godot_vector3i raw_dest;
+ Vector3i *dest = (Vector3i *)&raw_dest;
+ Vector3i *self = (Vector3i *)p_self;
+ const Vector3i *b = (const Vector3i *)p_b;
+ *dest = *self * *b;
+ return raw_dest;
+}
+
+godot_vector3i GDAPI godot_vector3i_operator_multiply_scalar(const godot_vector3i *p_self, const godot_int p_b) {
+ godot_vector3i raw_dest;
+ Vector3i *dest = (Vector3i *)&raw_dest;
+ Vector3i *self = (Vector3i *)p_self;
+ *dest = *self * p_b;
+ return raw_dest;
+}
+
+godot_vector3i GDAPI godot_vector3i_operator_divide_vector(const godot_vector3i *p_self, const godot_vector3i *p_b) {
+ godot_vector3i raw_dest;
+ Vector3i *dest = (Vector3i *)&raw_dest;
+ Vector3i *self = (Vector3i *)p_self;
+ const Vector3i *b = (const Vector3i *)p_b;
+ *dest = *self / *b;
+ return raw_dest;
+}
+
+godot_vector3i GDAPI godot_vector3i_operator_divide_scalar(const godot_vector3i *p_self, const godot_int p_b) {
+ godot_vector3i raw_dest;
+ Vector3i *dest = (Vector3i *)&raw_dest;
+ Vector3i *self = (Vector3i *)p_self;
+ *dest = *self / p_b;
+ return raw_dest;
+}
+
+godot_bool GDAPI godot_vector3i_operator_equal(const godot_vector3i *p_self, const godot_vector3i *p_b) {
+ Vector3i *self = (Vector3i *)p_self;
+ const Vector3i *b = (const Vector3i *)p_b;
+ return *self == *b;
+}
+
+godot_bool GDAPI godot_vector3i_operator_less(const godot_vector3i *p_self, const godot_vector3i *p_b) {
+ Vector3i *self = (Vector3i *)p_self;
+ const Vector3i *b = (const Vector3i *)p_b;
+ return *self < *b;
+}
+
+godot_vector3i GDAPI godot_vector3i_operator_neg(const godot_vector3i *p_self) {
+ godot_vector3i raw_dest;
+ Vector3i *dest = (Vector3i *)&raw_dest;
+ const Vector3i *self = (const Vector3i *)p_self;
+ *dest = -(*self);
+ return raw_dest;
+}
+
+void GDAPI godot_vector3i_set_axis(godot_vector3i *p_self, const godot_vector3_axis p_axis, const godot_int p_val) {
+ Vector3i *self = (Vector3i *)p_self;
+ self->set_axis(p_axis, p_val);
+}
+
+godot_int GDAPI godot_vector3i_get_axis(const godot_vector3i *p_self, const godot_vector3_axis p_axis) {
+ const Vector3i *self = (const Vector3i *)p_self;
+ return self->get_axis(p_axis);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 9473a3d419..9c38c8b58d 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -17,7 +17,1125 @@
"major": 1,
"minor": 2
},
- "next": null,
+ "next": {
+ "type": "CORE",
+ "version": {
+ "major": 1,
+ "minor": 3
+ },
+ "next": null,
+ "api": [
+ {
+ "name": "godot_object_get_instance_id",
+ "return_type": "uint64_t",
+ "arguments": [
+ ["const godot_object *", "p_object"]
+ ]
+ },
+ {
+ "name": "godot_array_new_packed_float64_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "r_dest"],
+ ["const godot_packed_float64_array *", "p_pra"]
+ ]
+ },
+ {
+ "name": "godot_array_new_packed_int64_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_array *", "r_dest"],
+ ["const godot_packed_int64_array *", "p_pia"]
+ ]
+ },
+ {
+ "name": "godot_callable_new_with_object",
+ "return_type": "void",
+ "arguments": [
+ ["godot_callable *", "r_dest"],
+ ["const godot_object *", "p_object"],
+ ["const godot_string_name *", "p_method"]
+ ]
+ },
+ {
+ "name": "godot_callable_new_with_object_id",
+ "return_type": "void",
+ "arguments": [
+ ["godot_callable *", "r_dest"],
+ ["uint64_t", "p_objectid"],
+ ["const godot_string_name *", "p_method"]
+ ]
+ },
+ {
+ "name": "godot_callable_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_callable *", "r_dest"],
+ ["const godot_callable *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_callable_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_callable *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_callable_call",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_callable *", "p_self"],
+ ["const godot_variant **", "p_arguments"],
+ ["godot_int", "p_argcount"],
+ ["godot_variant *", "r_return_value"]
+ ]
+ },
+ {
+ "name": "godot_callable_call_deferred",
+ "return_type": "void",
+ "arguments": [
+ ["const godot_callable *", "p_self"],
+ ["const godot_variant **", "p_arguments"],
+ ["godot_int", "p_argcount"]
+ ]
+ },
+ {
+ "name": "godot_callable_is_null",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_callable *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_callable_is_custom",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_callable *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_callable_is_standard",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_callable *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_callable_get_object",
+ "return_type": "godot_object *",
+ "arguments": [
+ ["const godot_callable *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_callable_get_object_id",
+ "return_type": "uint64_t",
+ "arguments": [
+ ["const godot_callable *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_callable_get_method",
+ "return_type": "godot_string_name",
+ "arguments": [
+ ["const godot_callable *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_callable_hash",
+ "return_type": "uint32_t",
+ "arguments": [
+ ["const godot_callable *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_callable_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_callable *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_callable_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_callable *", "p_self"],
+ ["const godot_callable *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_callable_operator_less",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_callable *", "p_self"],
+ ["const godot_callable *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_signal_new_with_object",
+ "return_type": "void",
+ "arguments": [
+ ["godot_signal *", "r_dest"],
+ ["const godot_object *", "p_object"],
+ ["const godot_string_name *", "p_method"]
+ ]
+ },
+ {
+ "name": "godot_signal_new_with_object_id",
+ "return_type": "void",
+ "arguments": [
+ ["godot_signal *", "r_dest"],
+ ["uint64_t", "p_objectid"],
+ ["const godot_string_name *", "p_method"]
+ ]
+ },
+ {
+ "name": "godot_signal_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_signal *", "r_dest"],
+ ["const godot_signal *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_signal_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_signal *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_signal_emit",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_signal *", "p_self"],
+ ["const godot_variant **", "p_arguments"],
+ ["godot_int", "p_argcount"]
+ ]
+ },
+ {
+ "name": "godot_signal_connect",
+ "return_type": "godot_int",
+ "arguments": [
+ ["godot_signal *", "p_self"],
+ ["const godot_callable *", "p_callable"],
+ ["const godot_array *", "p_binds"],
+ ["uint32_t", "p_flags"]
+ ]
+ },
+ {
+ "name": "godot_signal_disconnect",
+ "return_type": "void",
+ "arguments": [
+ ["godot_signal *", "p_self"],
+ ["const godot_callable *", "p_callable"]
+ ]
+ },
+ {
+ "name": "godot_signal_is_null",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_signal *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_signal_is_connected",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_signal *", "p_self"],
+ ["const godot_callable *", "p_callable"]
+ ]
+ },
+ {
+ "name": "godot_signal_get_connections",
+ "return_type": "godot_array",
+ "arguments": [
+ ["const godot_signal *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_signal_get_object",
+ "return_type": "godot_object *",
+ "arguments": [
+ ["const godot_signal *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_signal_get_object_id",
+ "return_type": "uint64_t",
+ "arguments": [
+ ["const godot_signal *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_signal_get_name",
+ "return_type": "godot_string_name",
+ "arguments": [
+ ["const godot_signal *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_signal_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_signal *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_signal_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_signal *", "p_self"],
+ ["const godot_signal *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_signal_operator_less",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_signal *", "p_self"],
+ ["const godot_signal *", "p_other"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_int64_array *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_int64_array *", "r_dest"],
+ ["const godot_packed_int64_array *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_new_with_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_int64_array *", "r_dest"],
+ ["const godot_array *", "p_a"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_append",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_int64_array *", "p_self"],
+ ["const int64_t", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_append_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_int64_array *", "p_self"],
+ ["const godot_packed_int64_array *", "p_array"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_insert",
+ "return_type": "godot_error",
+ "arguments": [
+ ["godot_packed_int64_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const int64_t", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_invert",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_int64_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_push_back",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_int64_array *", "p_self"],
+ ["const int64_t", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_remove",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_int64_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_resize",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_int64_array *", "p_self"],
+ ["const godot_int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_set",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_int64_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const int64_t", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_get",
+ "return_type": "int64_t",
+ "arguments": [
+ ["const godot_packed_int64_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_size",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_packed_int64_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_packed_int64_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_int64_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_float64_array *", "r_dest"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_new_copy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_float64_array *", "r_dest"],
+ ["const godot_packed_float64_array *", "p_src"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_new_with_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_float64_array *", "r_dest"],
+ ["const godot_array *", "p_a"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_append",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_float64_array *", "p_self"],
+ ["const double", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_append_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_float64_array *", "p_self"],
+ ["const godot_packed_float64_array *", "p_array"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_insert",
+ "return_type": "godot_error",
+ "arguments": [
+ ["godot_packed_float64_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const double", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_invert",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_float64_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_push_back",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_float64_array *", "p_self"],
+ ["const double", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_remove",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_float64_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_resize",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_float64_array *", "p_self"],
+ ["const godot_int", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_set",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_float64_array *", "p_self"],
+ ["const godot_int", "p_idx"],
+ ["const double", "p_data"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_get",
+ "return_type": "double",
+ "arguments": [
+ ["const godot_packed_float64_array *", "p_self"],
+ ["const godot_int", "p_idx"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_size",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_packed_float64_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_packed_float64_array_destroy",
+ "return_type": "void",
+ "arguments": [
+ ["godot_packed_float64_array *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2_as_rect2i",
+ "return_type": "godot_rect2i",
+ "arguments": [
+ ["const godot_rect2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_new_with_position_and_size",
+ "return_type": "void",
+ "arguments": [
+ ["godot_rect2i *", "r_dest"],
+ ["const godot_vector2i *", "p_pos"],
+ ["const godot_vector2i *", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_rect2i *", "r_dest"],
+ ["const godot_int", "p_x"],
+ ["const godot_int", "p_y"],
+ ["const godot_int", "p_width"],
+ ["const godot_int", "p_height"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_as_rect2",
+ "return_type": "godot_rect2",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_get_area",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_intersects",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"],
+ ["const godot_rect2i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_encloses",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"],
+ ["const godot_rect2i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_has_no_area",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_clip",
+ "return_type": "godot_rect2i",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"],
+ ["const godot_rect2i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_merge",
+ "return_type": "godot_rect2i",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"],
+ ["const godot_rect2i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_has_point",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"],
+ ["const godot_vector2i *", "p_point"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_grow",
+ "return_type": "godot_rect2i",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"],
+ ["const godot_int", "p_by"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_grow_individual",
+ "return_type": "godot_rect2i",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"],
+ ["const godot_int", "p_left"],
+ ["const godot_int", "p_top"],
+ ["const godot_int", "p_right"],
+ ["const godot_int", "p_bottom"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_grow_margin",
+ "return_type": "godot_rect2i",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"],
+ ["const godot_int", "p_margin"],
+ ["const godot_int", "p_by"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_abs",
+ "return_type": "godot_rect2i",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_expand",
+ "return_type": "godot_rect2i",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"],
+ ["const godot_vector2i *", "p_to"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"],
+ ["const godot_rect2i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_get_position",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_get_size",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_rect2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_set_position",
+ "return_type": "void",
+ "arguments": [
+ ["godot_rect2i *", "p_self"],
+ ["const godot_vector2i *", "p_pos"]
+ ]
+ },
+ {
+ "name": "godot_rect2i_set_size",
+ "return_type": "void",
+ "arguments": [
+ ["godot_rect2i *", "p_self"],
+ ["const godot_vector2i *", "p_size"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_string_name",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_string_name *", "p_s"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_vector2i",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_vector2i *", "p_v2"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_rect2i",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_rect2i *", "p_rect2"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_vector3i",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_vector3i *", "p_v3"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_callable",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_callable *", "p_cb"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_signal",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_signal *", "p_signal"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_packed_int64_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_packed_int64_array *", "p_pia"]
+ ]
+ },
+ {
+ "name": "godot_variant_new_packed_float64_array",
+ "return_type": "void",
+ "arguments": [
+ ["godot_variant *", "r_dest"],
+ ["const godot_packed_float64_array *", "p_pra"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_string_name",
+ "return_type": "godot_string_name",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_vector2i",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_rect2i",
+ "return_type": "godot_rect2i",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_vector3i",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_callable",
+ "return_type": "godot_callable",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_signal",
+ "return_type": "godot_signal",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_packed_int64_array",
+ "return_type": "godot_packed_int64_array",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_as_packed_float64_array",
+ "return_type": "godot_packed_float64_array",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_variant_hash",
+ "return_type": "uint32_t",
+ "arguments": [
+ ["const godot_variant *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_as_vector2i",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2_sign",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_vector2i *", "r_dest"],
+ ["const godot_int", "p_x"],
+ ["const godot_int", "p_y"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_as_vector2",
+ "return_type": "godot_vector2",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_aspect",
+ "return_type": "godot_real",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_abs",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_sign",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_operator_add",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"],
+ ["const godot_vector2i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_operator_subtract",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"],
+ ["const godot_vector2i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_operator_multiply_vector",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"],
+ ["const godot_vector2i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_operator_multiply_scalar",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"],
+ ["const godot_int", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_operator_divide_vector",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"],
+ ["const godot_vector2i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_operator_divide_scalar",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"],
+ ["const godot_int", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"],
+ ["const godot_vector2i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_operator_less",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"],
+ ["const godot_vector2i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_operator_neg",
+ "return_type": "godot_vector2i",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_set_x",
+ "return_type": "void",
+ "arguments": [
+ ["godot_vector2i *", "p_self"],
+ ["const godot_int", "p_x"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_set_y",
+ "return_type": "void",
+ "arguments": [
+ ["godot_vector2i *", "p_self"],
+ ["const godot_int", "p_y"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_get_x",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector2i_get_y",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_vector2i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_as_vector3i",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3_sign",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3 *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_new",
+ "return_type": "void",
+ "arguments": [
+ ["godot_vector3i *", "r_dest"],
+ ["const godot_int", "p_x"],
+ ["const godot_int", "p_y"],
+ ["const godot_int", "p_z"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_as_string",
+ "return_type": "godot_string",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_as_vector3",
+ "return_type": "godot_vector3",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_min_axis",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_max_axis",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_abs",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_sign",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_operator_add",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"],
+ ["const godot_vector3i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_operator_subtract",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"],
+ ["const godot_vector3i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_operator_multiply_vector",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"],
+ ["const godot_vector3i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_operator_multiply_scalar",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"],
+ ["const godot_int", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_operator_divide_vector",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"],
+ ["const godot_vector3i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_operator_divide_scalar",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"],
+ ["const godot_int", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_operator_equal",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"],
+ ["const godot_vector3i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_operator_less",
+ "return_type": "godot_bool",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"],
+ ["const godot_vector3i *", "p_b"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_operator_neg",
+ "return_type": "godot_vector3i",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_set_axis",
+ "return_type": "void",
+ "arguments": [
+ ["godot_vector3i *", "p_self"],
+ ["const godot_vector3_axis", "p_axis"],
+ ["const godot_int", "p_val"]
+ ]
+ },
+ {
+ "name": "godot_vector3i_get_axis",
+ "return_type": "godot_int",
+ "arguments": [
+ ["const godot_vector3i *", "p_self"],
+ ["const godot_vector3_axis", "p_axis"]
+ ]
+ }
+ ]
+ },
"api": [
{
"name": "godot_dictionary_duplicate",
@@ -100,17 +1218,17 @@
]
},
{
- "name": "godot_packed_int_array_empty",
+ "name": "godot_packed_int32_array_empty",
"return_type": "godot_bool",
"arguments": [
- ["const godot_packed_int_array *", "p_self"]
+ ["const godot_packed_int32_array *", "p_self"]
]
},
{
- "name": "godot_packed_real_array_empty",
+ "name": "godot_packed_float32_array_empty",
"return_type": "godot_bool",
"arguments": [
- ["const godot_packed_real_array *", "p_self"]
+ ["const godot_packed_float32_array *", "p_self"]
]
},
{
@@ -160,7 +1278,7 @@
"name": "godot_instance_from_id",
"return_type": "godot_object *",
"arguments": [
- ["godot_int", "p_instance_id"]
+ ["uint64_t", "p_instance_id"]
]
}
]
@@ -586,7 +1704,7 @@
]
},
{
- "name": "godot_color_linear_interpolate",
+ "name": "godot_color_lerp",
"return_type": "godot_color",
"arguments": [
["const godot_color *", "p_self"],
@@ -710,7 +1828,7 @@
]
},
{
- "name": "godot_vector2_linear_interpolate",
+ "name": "godot_vector2_lerp",
"return_type": "godot_vector2",
"arguments": [
["const godot_vector2 *", "p_self"],
@@ -1449,7 +2567,7 @@
]
},
{
- "name": "godot_vector3_linear_interpolate",
+ "name": "godot_vector3_lerp",
"return_type": "godot_vector3",
"arguments": [
["const godot_vector3 *", "p_self"],
@@ -1767,223 +2885,223 @@
]
},
{
- "name": "godot_packed_int_array_new",
+ "name": "godot_packed_int32_array_new",
"return_type": "void",
"arguments": [
- ["godot_packed_int_array *", "r_dest"]
+ ["godot_packed_int32_array *", "r_dest"]
]
},
{
- "name": "godot_packed_int_array_new_copy",
+ "name": "godot_packed_int32_array_new_copy",
"return_type": "void",
"arguments": [
- ["godot_packed_int_array *", "r_dest"],
- ["const godot_packed_int_array *", "p_src"]
+ ["godot_packed_int32_array *", "r_dest"],
+ ["const godot_packed_int32_array *", "p_src"]
]
},
{
- "name": "godot_packed_int_array_new_with_array",
+ "name": "godot_packed_int32_array_new_with_array",
"return_type": "void",
"arguments": [
- ["godot_packed_int_array *", "r_dest"],
+ ["godot_packed_int32_array *", "r_dest"],
["const godot_array *", "p_a"]
]
},
{
- "name": "godot_packed_int_array_append",
+ "name": "godot_packed_int32_array_append",
"return_type": "void",
"arguments": [
- ["godot_packed_int_array *", "p_self"],
- ["const godot_int", "p_data"]
+ ["godot_packed_int32_array *", "p_self"],
+ ["const int32_t", "p_data"]
]
},
{
- "name": "godot_packed_int_array_append_array",
+ "name": "godot_packed_int32_array_append_array",
"return_type": "void",
"arguments": [
- ["godot_packed_int_array *", "p_self"],
- ["const godot_packed_int_array *", "p_array"]
+ ["godot_packed_int32_array *", "p_self"],
+ ["const godot_packed_int32_array *", "p_array"]
]
},
{
- "name": "godot_packed_int_array_insert",
+ "name": "godot_packed_int32_array_insert",
"return_type": "godot_error",
"arguments": [
- ["godot_packed_int_array *", "p_self"],
+ ["godot_packed_int32_array *", "p_self"],
["const godot_int", "p_idx"],
- ["const godot_int", "p_data"]
+ ["const int32_t", "p_data"]
]
},
{
- "name": "godot_packed_int_array_invert",
+ "name": "godot_packed_int32_array_invert",
"return_type": "void",
"arguments": [
- ["godot_packed_int_array *", "p_self"]
+ ["godot_packed_int32_array *", "p_self"]
]
},
{
- "name": "godot_packed_int_array_push_back",
+ "name": "godot_packed_int32_array_push_back",
"return_type": "void",
"arguments": [
- ["godot_packed_int_array *", "p_self"],
- ["const godot_int", "p_data"]
+ ["godot_packed_int32_array *", "p_self"],
+ ["const int32_t", "p_data"]
]
},
{
- "name": "godot_packed_int_array_remove",
+ "name": "godot_packed_int32_array_remove",
"return_type": "void",
"arguments": [
- ["godot_packed_int_array *", "p_self"],
+ ["godot_packed_int32_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_packed_int_array_resize",
+ "name": "godot_packed_int32_array_resize",
"return_type": "void",
"arguments": [
- ["godot_packed_int_array *", "p_self"],
+ ["godot_packed_int32_array *", "p_self"],
["const godot_int", "p_size"]
]
},
{
- "name": "godot_packed_int_array_set",
+ "name": "godot_packed_int32_array_set",
"return_type": "void",
"arguments": [
- ["godot_packed_int_array *", "p_self"],
+ ["godot_packed_int32_array *", "p_self"],
["const godot_int", "p_idx"],
- ["const godot_int", "p_data"]
+ ["const int32_t", "p_data"]
]
},
{
- "name": "godot_packed_int_array_get",
- "return_type": "godot_int",
+ "name": "godot_packed_int32_array_get",
+ "return_type": "int32_t",
"arguments": [
- ["const godot_packed_int_array *", "p_self"],
+ ["const godot_packed_int32_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_packed_int_array_size",
+ "name": "godot_packed_int32_array_size",
"return_type": "godot_int",
"arguments": [
- ["const godot_packed_int_array *", "p_self"]
+ ["const godot_packed_int32_array *", "p_self"]
]
},
{
- "name": "godot_packed_int_array_destroy",
+ "name": "godot_packed_int32_array_destroy",
"return_type": "void",
"arguments": [
- ["godot_packed_int_array *", "p_self"]
+ ["godot_packed_int32_array *", "p_self"]
]
},
{
- "name": "godot_packed_real_array_new",
+ "name": "godot_packed_float32_array_new",
"return_type": "void",
"arguments": [
- ["godot_packed_real_array *", "r_dest"]
+ ["godot_packed_float32_array *", "r_dest"]
]
},
{
- "name": "godot_packed_real_array_new_copy",
+ "name": "godot_packed_float32_array_new_copy",
"return_type": "void",
"arguments": [
- ["godot_packed_real_array *", "r_dest"],
- ["const godot_packed_real_array *", "p_src"]
+ ["godot_packed_float32_array *", "r_dest"],
+ ["const godot_packed_float32_array *", "p_src"]
]
},
{
- "name": "godot_packed_real_array_new_with_array",
+ "name": "godot_packed_float32_array_new_with_array",
"return_type": "void",
"arguments": [
- ["godot_packed_real_array *", "r_dest"],
+ ["godot_packed_float32_array *", "r_dest"],
["const godot_array *", "p_a"]
]
},
{
- "name": "godot_packed_real_array_append",
+ "name": "godot_packed_float32_array_append",
"return_type": "void",
"arguments": [
- ["godot_packed_real_array *", "p_self"],
- ["const godot_real", "p_data"]
+ ["godot_packed_float32_array *", "p_self"],
+ ["const float", "p_data"]
]
},
{
- "name": "godot_packed_real_array_append_array",
+ "name": "godot_packed_float32_array_append_array",
"return_type": "void",
"arguments": [
- ["godot_packed_real_array *", "p_self"],
- ["const godot_packed_real_array *", "p_array"]
+ ["godot_packed_float32_array *", "p_self"],
+ ["const godot_packed_float32_array *", "p_array"]
]
},
{
- "name": "godot_packed_real_array_insert",
+ "name": "godot_packed_float32_array_insert",
"return_type": "godot_error",
"arguments": [
- ["godot_packed_real_array *", "p_self"],
+ ["godot_packed_float32_array *", "p_self"],
["const godot_int", "p_idx"],
- ["const godot_real", "p_data"]
+ ["const float", "p_data"]
]
},
{
- "name": "godot_packed_real_array_invert",
+ "name": "godot_packed_float32_array_invert",
"return_type": "void",
"arguments": [
- ["godot_packed_real_array *", "p_self"]
+ ["godot_packed_float32_array *", "p_self"]
]
},
{
- "name": "godot_packed_real_array_push_back",
+ "name": "godot_packed_float32_array_push_back",
"return_type": "void",
"arguments": [
- ["godot_packed_real_array *", "p_self"],
- ["const godot_real", "p_data"]
+ ["godot_packed_float32_array *", "p_self"],
+ ["const float", "p_data"]
]
},
{
- "name": "godot_packed_real_array_remove",
+ "name": "godot_packed_float32_array_remove",
"return_type": "void",
"arguments": [
- ["godot_packed_real_array *", "p_self"],
+ ["godot_packed_float32_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_packed_real_array_resize",
+ "name": "godot_packed_float32_array_resize",
"return_type": "void",
"arguments": [
- ["godot_packed_real_array *", "p_self"],
+ ["godot_packed_float32_array *", "p_self"],
["const godot_int", "p_size"]
]
},
{
- "name": "godot_packed_real_array_set",
+ "name": "godot_packed_float32_array_set",
"return_type": "void",
"arguments": [
- ["godot_packed_real_array *", "p_self"],
+ ["godot_packed_float32_array *", "p_self"],
["const godot_int", "p_idx"],
- ["const godot_real", "p_data"]
+ ["const float", "p_data"]
]
},
{
- "name": "godot_packed_real_array_get",
- "return_type": "godot_real",
+ "name": "godot_packed_float32_array_get",
+ "return_type": "float",
"arguments": [
- ["const godot_packed_real_array *", "p_self"],
+ ["const godot_packed_float32_array *", "p_self"],
["const godot_int", "p_idx"]
]
},
{
- "name": "godot_packed_real_array_size",
+ "name": "godot_packed_float32_array_size",
"return_type": "godot_int",
"arguments": [
- ["const godot_packed_real_array *", "p_self"]
+ ["const godot_packed_float32_array *", "p_self"]
]
},
{
- "name": "godot_packed_real_array_destroy",
+ "name": "godot_packed_float32_array_destroy",
"return_type": "void",
"arguments": [
- ["godot_packed_real_array *", "p_self"]
+ ["godot_packed_float32_array *", "p_self"]
]
},
{
@@ -2474,19 +3592,19 @@
]
},
{
- "name": "godot_array_new_packed_real_array",
+ "name": "godot_array_new_packed_float32_array",
"return_type": "void",
"arguments": [
["godot_array *", "r_dest"],
- ["const godot_packed_real_array *", "p_pra"]
+ ["const godot_packed_float32_array *", "p_pra"]
]
},
{
- "name": "godot_array_new_packed_int_array",
+ "name": "godot_array_new_packed_int32_array",
"return_type": "void",
"arguments": [
["godot_array *", "r_dest"],
- ["const godot_packed_int_array *", "p_pia"]
+ ["const godot_packed_int32_array *", "p_pia"]
]
},
{
@@ -4059,19 +5177,19 @@
]
},
{
- "name": "godot_variant_new_packed_int_array",
+ "name": "godot_variant_new_packed_int32_array",
"return_type": "void",
"arguments": [
["godot_variant *", "r_dest"],
- ["const godot_packed_int_array *", "p_pia"]
+ ["const godot_packed_int32_array *", "p_pia"]
]
},
{
- "name": "godot_variant_new_packed_real_array",
+ "name": "godot_variant_new_packed_float32_array",
"return_type": "void",
"arguments": [
["godot_variant *", "r_dest"],
- ["const godot_packed_real_array *", "p_pra"]
+ ["const godot_packed_float32_array *", "p_pra"]
]
},
{
@@ -4254,15 +5372,15 @@
]
},
{
- "name": "godot_variant_as_packed_int_array",
- "return_type": "godot_packed_int_array",
+ "name": "godot_variant_as_packed_int32_array",
+ "return_type": "godot_packed_int32_array",
"arguments": [
["const godot_variant *", "p_self"]
]
},
{
- "name": "godot_variant_as_packed_real_array",
- "return_type": "godot_packed_real_array",
+ "name": "godot_variant_as_packed_float32_array",
+ "return_type": "godot_packed_float32_array",
"arguments": [
["const godot_variant *", "p_self"]
]
@@ -5869,7 +6987,7 @@
"arguments": [
["void *", "p_gdnative_handle"],
["const char *", "p_name"],
- ["const godot_signal *", "p_signal"]
+ ["const godot_nativescript_signal *", "p_signal"]
]
},
{
diff --git a/modules/gdnative/gdnative_library_editor_plugin.cpp b/modules/gdnative/gdnative_library_editor_plugin.cpp
index 10ddd79d3a..2a9836329e 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.cpp
+++ b/modules/gdnative/gdnative_library_editor_plugin.cpp
@@ -40,7 +40,6 @@ void GDNativeLibraryEditor::edit(Ref<GDNativeLibrary> p_library) {
for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) {
for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) {
-
String target = E->key() + "." + it->get();
TargetConfig ecfg;
ecfg.library = config->get_value("entry", target, "");
@@ -56,14 +55,12 @@ void GDNativeLibraryEditor::_bind_methods() {
}
void GDNativeLibraryEditor::_update_tree() {
-
tree->clear();
TreeItem *root = tree->create_item();
PopupMenu *filter_list = filter->get_popup();
String text = "";
for (int i = 0; i < filter_list->get_item_count(); i++) {
-
if (!filter_list->is_item_checked(i)) {
continue;
}
@@ -84,7 +81,6 @@ void GDNativeLibraryEditor::_update_tree() {
platform->set_expand_right(0, true);
for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) {
-
String target = E->key() + "." + it->get();
TreeItem *bit = tree->create_item(platform);
@@ -125,17 +121,16 @@ void GDNativeLibraryEditor::_update_tree() {
}
void GDNativeLibraryEditor::_on_item_button(Object *item, int column, int id) {
-
String target = Object::cast_to<TreeItem>(item)->get_metadata(0);
String platform = target.substr(0, target.find("."));
String entry = target.substr(platform.length() + 1, target.length());
String section = (id == BUTTON_SELECT_DEPENDENCES || id == BUTTON_CLEAR_DEPENDENCES) ? "dependencies" : "entry";
if (id == BUTTON_SELECT_LIBRARY || id == BUTTON_SELECT_DEPENDENCES) {
-
EditorFileDialog::FileMode mode = EditorFileDialog::FILE_MODE_OPEN_FILE;
- if (id == BUTTON_SELECT_DEPENDENCES)
+ if (id == BUTTON_SELECT_DEPENDENCES) {
mode = EditorFileDialog::FILE_MODE_OPEN_FILES;
+ }
file_dialog->set_meta("target", target);
file_dialog->set_meta("section", section);
@@ -156,24 +151,20 @@ void GDNativeLibraryEditor::_on_item_button(Object *item, int column, int id) {
}
void GDNativeLibraryEditor::_on_library_selected(const String &file) {
-
_set_target_value(file_dialog->get_meta("section"), file_dialog->get_meta("target"), file);
}
void GDNativeLibraryEditor::_on_dependencies_selected(const PackedStringArray &files) {
-
_set_target_value(file_dialog->get_meta("section"), file_dialog->get_meta("target"), files);
}
void GDNativeLibraryEditor::_on_filter_selected(int index) {
-
PopupMenu *filter_list = filter->get_popup();
filter_list->set_item_checked(index, !filter_list->is_item_checked(index));
_update_tree();
}
void GDNativeLibraryEditor::_on_item_collapsed(Object *p_item) {
-
TreeItem *item = Object::cast_to<TreeItem>(p_item);
String name = item->get_text(0);
@@ -185,7 +176,6 @@ void GDNativeLibraryEditor::_on_item_collapsed(Object *p_item) {
}
void GDNativeLibraryEditor::_on_item_activated() {
-
TreeItem *item = tree->get_selected();
if (item && tree->get_selected_column() == 0 && item->get_metadata(0).get_type() == Variant::NIL) {
new_architecture_dialog->set_meta("platform", item->get_metadata(1));
@@ -194,7 +184,6 @@ void GDNativeLibraryEditor::_on_item_activated() {
}
void GDNativeLibraryEditor::_on_create_new_entry() {
-
String platform = new_architecture_dialog->get_meta("platform");
String entry = new_architecture_input->get_text().strip_edges();
if (!entry.empty()) {
@@ -204,19 +193,18 @@ void GDNativeLibraryEditor::_on_create_new_entry() {
}
void GDNativeLibraryEditor::_set_target_value(const String &section, const String &target, Variant file) {
- if (section == "entry")
+ if (section == "entry") {
entry_configs[target].library = file;
- else if (section == "dependencies")
+ } else if (section == "dependencies") {
entry_configs[target].dependencies = file;
+ }
_translate_to_config_file();
_update_tree();
}
void GDNativeLibraryEditor::_erase_entry(const String &platform, const String &entry) {
-
if (platforms.has(platform)) {
if (List<String>::Element *E = platforms[platform].entries.find(entry)) {
-
String target = platform + "." + entry;
platforms[platform].entries.erase(E);
@@ -243,19 +231,17 @@ void GDNativeLibraryEditor::_move_entry(const String &platform, const String &en
}
void GDNativeLibraryEditor::_translate_to_config_file() {
-
if (!library.is_null()) {
-
Ref<ConfigFile> config = library->get_config_file();
config->erase_section("entry");
config->erase_section("dependencies");
for (Map<String, NativePlatformConfig>::Element *E = platforms.front(); E; E = E->next()) {
for (List<String>::Element *it = E->value().entries.front(); it; it = it->next()) {
-
String target = E->key() + "." + it->get();
- if (entry_configs[target].library.empty() && entry_configs[target].dependencies.empty())
+ if (entry_configs[target].library.empty() && entry_configs[target].dependencies.empty()) {
continue;
+ }
config->set_value("entry", target, entry_configs[target].library);
config->set_value("dependencies", target, entry_configs[target].dependencies);
@@ -267,7 +253,6 @@ void GDNativeLibraryEditor::_translate_to_config_file() {
}
GDNativeLibraryEditor::GDNativeLibraryEditor() {
-
{ // Define platforms
NativePlatformConfig platform_windows;
platform_windows.name = "Windows";
@@ -388,32 +373,30 @@ GDNativeLibraryEditor::GDNativeLibraryEditor() {
}
void GDNativeLibraryEditorPlugin::edit(Object *p_node) {
-
Ref<GDNativeLibrary> new_library = Object::cast_to<GDNativeLibrary>(p_node);
- if (new_library.is_valid())
+ if (new_library.is_valid()) {
library_editor->edit(new_library);
+ }
}
bool GDNativeLibraryEditorPlugin::handles(Object *p_node) const {
-
return p_node->is_class("GDNativeLibrary");
}
void GDNativeLibraryEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
button->show();
EditorNode::get_singleton()->make_bottom_panel_item_visible(library_editor);
} else {
- if (library_editor->is_visible_in_tree())
+ if (library_editor->is_visible_in_tree()) {
EditorNode::get_singleton()->hide_bottom_panel();
+ }
button->hide();
}
}
GDNativeLibraryEditorPlugin::GDNativeLibraryEditorPlugin(EditorNode *p_node) {
-
library_editor = memnew(GDNativeLibraryEditor);
library_editor->set_custom_minimum_size(Size2(0, 250 * EDSCALE));
button = p_node->add_bottom_panel_item(TTR("GDNativeLibrary"), library_editor);
diff --git a/modules/gdnative/gdnative_library_editor_plugin.h b/modules/gdnative/gdnative_library_editor_plugin.h
index b1274d08b3..5fdb860ca3 100644
--- a/modules/gdnative/gdnative_library_editor_plugin.h
+++ b/modules/gdnative/gdnative_library_editor_plugin.h
@@ -36,7 +36,6 @@
#include "gdnative.h"
class GDNativeLibraryEditor : public Control {
-
GDCLASS(GDNativeLibraryEditor, Control);
struct NativePlatformConfig {
@@ -94,7 +93,6 @@ public:
};
class GDNativeLibraryEditorPlugin : public EditorPlugin {
-
GDCLASS(GDNativeLibraryEditorPlugin, EditorPlugin);
GDNativeLibraryEditor *library_editor;
diff --git a/modules/gdnative/gdnative_library_singleton_editor.cpp b/modules/gdnative/gdnative_library_singleton_editor.cpp
index 378339ecea..409b6cbffe 100644
--- a/modules/gdnative/gdnative_library_singleton_editor.cpp
+++ b/modules/gdnative/gdnative_library_singleton_editor.cpp
@@ -35,7 +35,6 @@
#include "editor/editor_node.h"
Set<String> GDNativeLibrarySingletonEditor::_find_singletons_recursive(EditorFileSystemDirectory *p_dir) {
-
Set<String> file_paths;
// check children
@@ -67,7 +66,6 @@ Set<String> GDNativeLibrarySingletonEditor::_find_singletons_recursive(EditorFil
}
void GDNativeLibrarySingletonEditor::_discover_singletons() {
-
EditorFileSystemDirectory *dir = EditorFileSystem::get_singleton()->get_filesystem();
Set<String> file_paths = _find_singletons_recursive(dir);
@@ -97,7 +95,6 @@ void GDNativeLibrarySingletonEditor::_discover_singletons() {
}
if (changed) {
-
ProjectSettings::get_singleton()->set("gdnative/singletons", files);
_update_libraries(); // So singleton options (i.e. disabled) updates too
ProjectSettings::get_singleton()->save();
@@ -105,7 +102,6 @@ void GDNativeLibrarySingletonEditor::_discover_singletons() {
}
void GDNativeLibrarySingletonEditor::_update_libraries() {
-
updating = true;
libraries->clear();
libraries->create_item(); // root item
@@ -139,19 +135,22 @@ void GDNativeLibrarySingletonEditor::_update_libraries() {
}
// The singletons list changed, we must update the settings
- if (updated_disabled.size() != singletons_disabled.size())
+ if (updated_disabled.size() != singletons_disabled.size()) {
ProjectSettings::get_singleton()->set("gdnative/singletons_disabled", updated_disabled);
+ }
updating = false;
}
void GDNativeLibrarySingletonEditor::_item_edited() {
- if (updating)
+ if (updating) {
return;
+ }
TreeItem *item = libraries->get_edited();
- if (!item)
+ if (!item) {
return;
+ }
bool enabled = item->get_range(1);
String path = item->get_metadata(0);
@@ -169,8 +168,9 @@ void GDNativeLibrarySingletonEditor::_item_edited() {
if (enabled) {
disabled_paths.erase(path);
} else {
- if (disabled_paths.find(path) == -1)
+ if (disabled_paths.find(path) == -1) {
disabled_paths.push_back(path);
+ }
}
undo_redo->create_action(enabled ? TTR("Enabled GDNative Singleton") : TTR("Disabled GDNative Singleton"));
@@ -182,7 +182,6 @@ void GDNativeLibrarySingletonEditor::_item_edited() {
}
void GDNativeLibrarySingletonEditor::_notification(int p_what) {
-
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
if (is_visible_in_tree()) {
_update_libraries();
@@ -191,7 +190,6 @@ void GDNativeLibrarySingletonEditor::_notification(int p_what) {
}
void GDNativeLibrarySingletonEditor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_update_libraries"), &GDNativeLibrarySingletonEditor::_update_libraries);
}
diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h
index e3114e9348..4db685873f 100644
--- a/modules/gdnative/include/gdnative/array.h
+++ b/modules/gdnative/include/gdnative/array.h
@@ -51,7 +51,7 @@ typedef struct {
}
#endif
-#include <gdnative/pool_arrays.h>
+#include <gdnative/packed_arrays.h>
#include <gdnative/variant.h>
#include <gdnative/gdnative.h>
@@ -66,8 +66,10 @@ void GDAPI godot_array_new_packed_color_array(godot_array *r_dest, const godot_p
void GDAPI godot_array_new_packed_vector3_array(godot_array *r_dest, const godot_packed_vector3_array *p_pv3a);
void GDAPI godot_array_new_packed_vector2_array(godot_array *r_dest, const godot_packed_vector2_array *p_pv2a);
void GDAPI godot_array_new_packed_string_array(godot_array *r_dest, const godot_packed_string_array *p_psa);
-void GDAPI godot_array_new_packed_real_array(godot_array *r_dest, const godot_packed_real_array *p_pra);
-void GDAPI godot_array_new_packed_int_array(godot_array *r_dest, const godot_packed_int_array *p_pia);
+void GDAPI godot_array_new_packed_float32_array(godot_array *r_dest, const godot_packed_float32_array *p_pra);
+void GDAPI godot_array_new_packed_float64_array(godot_array *r_dest, const godot_packed_float64_array *p_pra);
+void GDAPI godot_array_new_packed_int32_array(godot_array *r_dest, const godot_packed_int32_array *p_pia);
+void GDAPI godot_array_new_packed_int64_array(godot_array *r_dest, const godot_packed_int64_array *p_pia);
void GDAPI godot_array_new_packed_byte_array(godot_array *r_dest, const godot_packed_byte_array *p_pba);
void GDAPI godot_array_set(godot_array *p_self, const godot_int p_idx, const godot_variant *p_value);
diff --git a/modules/gdnative/include/gdnative/callable.h b/modules/gdnative/include/gdnative/callable.h
new file mode 100644
index 0000000000..dbb5d02590
--- /dev/null
+++ b/modules/gdnative/include/gdnative/callable.h
@@ -0,0 +1,126 @@
+/*************************************************************************/
+/* callable.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef GODOT_CALLABLE_H
+#define GODOT_CALLABLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#define GODOT_CALLABLE_SIZE (16)
+
+#ifndef GODOT_CORE_API_GODOT_CALLABLE_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_CALLABLE_TYPE_DEFINED
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_CALLABLE_SIZE];
+} godot_callable;
+#endif
+
+#define GODOT_SIGNAL_SIZE (16)
+
+#ifndef GODOT_CORE_API_GODOT_SIGNAL_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_SIGNAL_TYPE_DEFINED
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_SIGNAL_SIZE];
+} godot_signal;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <gdnative/gdnative.h>
+#include <gdnative/string_name.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Callable
+
+void GDAPI godot_callable_new_with_object(godot_callable *r_dest, const godot_object *p_object, const godot_string_name *p_method);
+void GDAPI godot_callable_new_with_object_id(godot_callable *r_dest, uint64_t p_objectid, const godot_string_name *p_method);
+void GDAPI godot_callable_new_copy(godot_callable *r_dest, const godot_callable *p_src);
+
+void GDAPI godot_callable_destroy(godot_callable *p_self);
+
+godot_int GDAPI godot_callable_call(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount, godot_variant *r_return_value);
+void GDAPI godot_callable_call_deferred(const godot_callable *p_self, const godot_variant **p_arguments, godot_int p_argcount);
+
+godot_bool GDAPI godot_callable_is_null(const godot_callable *p_self);
+godot_bool GDAPI godot_callable_is_custom(const godot_callable *p_self);
+godot_bool GDAPI godot_callable_is_standard(const godot_callable *p_self);
+
+godot_object GDAPI *godot_callable_get_object(const godot_callable *p_self);
+uint64_t GDAPI godot_callable_get_object_id(const godot_callable *p_self);
+godot_string_name GDAPI godot_callable_get_method(const godot_callable *p_self);
+
+uint32_t GDAPI godot_callable_hash(const godot_callable *p_self);
+
+godot_string GDAPI godot_callable_as_string(const godot_callable *p_self);
+
+godot_bool GDAPI godot_callable_operator_equal(const godot_callable *p_self, const godot_callable *p_other);
+godot_bool GDAPI godot_callable_operator_less(const godot_callable *p_self, const godot_callable *p_other);
+
+// Signal
+
+void GDAPI godot_signal_new_with_object(godot_signal *r_dest, const godot_object *p_object, const godot_string_name *p_name);
+void GDAPI godot_signal_new_with_object_id(godot_signal *r_dest, uint64_t p_objectid, const godot_string_name *p_name);
+void GDAPI godot_signal_new_copy(godot_signal *r_dest, const godot_signal *p_src);
+
+void GDAPI godot_signal_destroy(godot_signal *p_self);
+
+godot_int GDAPI godot_signal_emit(const godot_signal *p_self, const godot_variant **p_arguments, godot_int p_argcount);
+
+godot_int GDAPI godot_signal_connect(godot_signal *p_self, const godot_callable *p_callable, const godot_array *p_binds, uint32_t p_flags);
+void GDAPI godot_signal_disconnect(godot_signal *p_self, const godot_callable *p_callable);
+
+godot_bool GDAPI godot_signal_is_null(const godot_signal *p_self);
+godot_bool GDAPI godot_signal_is_connected(const godot_signal *p_self, const godot_callable *p_callable);
+
+godot_array GDAPI godot_signal_get_connections(const godot_signal *p_self);
+
+godot_object GDAPI *godot_signal_get_object(const godot_signal *p_self);
+uint64_t GDAPI godot_signal_get_object_id(const godot_signal *p_self);
+godot_string_name GDAPI godot_signal_get_name(const godot_signal *p_self);
+
+godot_string GDAPI godot_signal_as_string(const godot_signal *p_self);
+
+godot_bool GDAPI godot_signal_operator_equal(const godot_signal *p_self, const godot_signal *p_other);
+godot_bool GDAPI godot_signal_operator_less(const godot_signal *p_self, const godot_signal *p_other);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/modules/gdnative/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h
index 47c01dbb20..e7737bf8e1 100644
--- a/modules/gdnative/include/gdnative/color.h
+++ b/modules/gdnative/include/gdnative/color.h
@@ -95,7 +95,7 @@ godot_color GDAPI godot_color_inverted(const godot_color *p_self);
godot_color GDAPI godot_color_contrasted(const godot_color *p_self);
-godot_color GDAPI godot_color_linear_interpolate(const godot_color *p_self, const godot_color *p_b, const godot_real p_t);
+godot_color GDAPI godot_color_lerp(const godot_color *p_self, const godot_color *p_b, const godot_real p_t);
godot_color GDAPI godot_color_blend(const godot_color *p_self, const godot_color *p_over);
diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index 6fdca30122..6a0a375da8 100644
--- a/modules/gdnative/include/gdnative/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -144,15 +144,15 @@ typedef void godot_object;
#include <gdnative/string_name.h>
-////// Vector2
+////// Vector2 & Vector2i
#include <gdnative/vector2.h>
-////// Rect2
+////// Rect2 & Rect2i
#include <gdnative/rect2.h>
-////// Vector3
+////// Vector3 & Vector3i
#include <gdnative/vector3.h>
@@ -192,6 +192,10 @@ typedef void godot_object;
#include <gdnative/rid.h>
+/////// Callable & Signal
+
+#include <gdnative/callable.h>
+
/////// Dictionary
#include <gdnative/dictionary.h>
@@ -200,8 +204,8 @@ typedef void godot_object;
#include <gdnative/array.h>
-// single API file for Pool*Array
-#include <gdnative/pool_arrays.h>
+// single API file for Packed*Array
+#include <gdnative/packed_arrays.h>
void GDAPI godot_object_destroy(godot_object *p_o);
@@ -289,7 +293,9 @@ void GDAPI *godot_get_class_tag(const godot_string_name *p_class);
godot_object GDAPI *godot_object_cast_to(const godot_object *p_object, void *p_class_tag);
// equivalent of GDScript's instance_from_id
-godot_object GDAPI *godot_instance_from_id(godot_int p_instance_id);
+godot_object GDAPI *godot_instance_from_id(uint64_t p_instance_id);
+
+uint64_t GDAPI godot_object_get_instance_id(const godot_object *p_object);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/include/gdnative/pool_arrays.h b/modules/gdnative/include/gdnative/packed_arrays.h
index c610377f54..d5bad70bdc 100644
--- a/modules/gdnative/include/gdnative/pool_arrays.h
+++ b/modules/gdnative/include/gdnative/packed_arrays.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* pool_arrays.h */
+/* packed_arrays.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,8 +28,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GODOT_POOL_ARRAYS_H
-#define GODOT_POOL_ARRAYS_H
+#ifndef GODOT_PACKED_ARRAYS_H
+#define GODOT_PACKED_ARRAYS_H
#ifdef __cplusplus
extern "C" {
@@ -39,7 +39,7 @@ extern "C" {
/////// PackedByteArray
-#define GODOT_PACKED_BYTE_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_BYTE_ARRAY_SIZE (2 * sizeof(void *))
#ifndef GODOT_CORE_API_GODOT_PACKED_BYTE_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_PACKED_BYTE_ARRAY_TYPE_DEFINED
@@ -50,29 +50,51 @@ typedef struct {
/////// PackedInt32Array
-#define GODOT_PACKED_INT_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_INT32_ARRAY_SIZE (2 * sizeof(void *))
-#ifndef GODOT_CORE_API_GODOT_PACKED_INT_ARRAY_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_PACKED_INT_ARRAY_TYPE_DEFINED
+#ifndef GODOT_CORE_API_GODOT_PACKED_INT32_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_INT32_ARRAY_TYPE_DEFINED
typedef struct {
- uint8_t _dont_touch_that[GODOT_PACKED_INT_ARRAY_SIZE];
-} godot_packed_int_array;
+ uint8_t _dont_touch_that[GODOT_PACKED_INT32_ARRAY_SIZE];
+} godot_packed_int32_array;
+#endif
+
+/////// PackedInt64Array
+
+#define GODOT_PACKED_INT64_ARRAY_SIZE (2 * sizeof(void *))
+
+#ifndef GODOT_CORE_API_GODOT_PACKED_INT64_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_INT64_ARRAY_TYPE_DEFINED
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_PACKED_INT64_ARRAY_SIZE];
+} godot_packed_int64_array;
#endif
/////// PackedFloat32Array
-#define GODOT_PACKED_REAL_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_FLOAT32_ARRAY_SIZE (2 * sizeof(void *))
+
+#ifndef GODOT_CORE_API_GODOT_PACKED_FLOAT32_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_FLOAT32_ARRAY_TYPE_DEFINED
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_PACKED_FLOAT32_ARRAY_SIZE];
+} godot_packed_float32_array;
+#endif
+
+/////// PackedFloat64Array
-#ifndef GODOT_CORE_API_GODOT_PACKED_REAL_ARRAY_TYPE_DEFINED
-#define GODOT_CORE_API_GODOT_PACKED_REAL_ARRAY_TYPE_DEFINED
+#define GODOT_PACKED_FLOAT64_ARRAY_SIZE (2 * sizeof(void *))
+
+#ifndef GODOT_CORE_API_GODOT_PACKED_FLOAT64_ARRAY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PACKED_FLOAT64_ARRAY_TYPE_DEFINED
typedef struct {
- uint8_t _dont_touch_that[GODOT_PACKED_REAL_ARRAY_SIZE];
-} godot_packed_real_array;
+ uint8_t _dont_touch_that[GODOT_PACKED_FLOAT64_ARRAY_SIZE];
+} godot_packed_float64_array;
#endif
/////// PackedStringArray
-#define GODOT_PACKED_STRING_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_STRING_ARRAY_SIZE (2 * sizeof(void *))
#ifndef GODOT_CORE_API_GODOT_PACKED_STRING_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_PACKED_STRING_ARRAY_TYPE_DEFINED
@@ -83,7 +105,7 @@ typedef struct {
/////// PackedVector2Array
-#define GODOT_PACKED_VECTOR2_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_VECTOR2_ARRAY_SIZE (2 * sizeof(void *))
#ifndef GODOT_CORE_API_GODOT_PACKED_VECTOR2_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_PACKED_VECTOR2_ARRAY_TYPE_DEFINED
@@ -94,7 +116,7 @@ typedef struct {
/////// PackedVector3Array
-#define GODOT_PACKED_VECTOR3_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_VECTOR3_ARRAY_SIZE (2 * sizeof(void *))
#ifndef GODOT_CORE_API_GODOT_PACKED_VECTOR3_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_PACKED_VECTOR3_ARRAY_TYPE_DEFINED
@@ -105,7 +127,7 @@ typedef struct {
/////// PackedColorArray
-#define GODOT_PACKED_COLOR_ARRAY_SIZE sizeof(void *)
+#define GODOT_PACKED_COLOR_ARRAY_SIZE (2 * sizeof(void *))
#ifndef GODOT_CORE_API_GODOT_PACKED_COLOR_ARRAY_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_PACKED_COLOR_ARRAY_TYPE_DEFINED
@@ -159,63 +181,121 @@ godot_bool GDAPI godot_packed_byte_array_empty(const godot_packed_byte_array *p_
void GDAPI godot_packed_byte_array_destroy(godot_packed_byte_array *p_self);
-// int
+// int32
+
+void GDAPI godot_packed_int32_array_new(godot_packed_int32_array *r_dest);
+void GDAPI godot_packed_int32_array_new_copy(godot_packed_int32_array *r_dest, const godot_packed_int32_array *p_src);
+void GDAPI godot_packed_int32_array_new_with_array(godot_packed_int32_array *r_dest, const godot_array *p_a);
+
+void GDAPI godot_packed_int32_array_append(godot_packed_int32_array *p_self, const int32_t p_data);
+
+void GDAPI godot_packed_int32_array_append_array(godot_packed_int32_array *p_self, const godot_packed_int32_array *p_array);
+
+godot_error GDAPI godot_packed_int32_array_insert(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data);
+
+void GDAPI godot_packed_int32_array_invert(godot_packed_int32_array *p_self);
+
+void GDAPI godot_packed_int32_array_push_back(godot_packed_int32_array *p_self, const int32_t p_data);
+
+void GDAPI godot_packed_int32_array_remove(godot_packed_int32_array *p_self, const godot_int p_idx);
+
+void GDAPI godot_packed_int32_array_resize(godot_packed_int32_array *p_self, const godot_int p_size);
+
+void GDAPI godot_packed_int32_array_set(godot_packed_int32_array *p_self, const godot_int p_idx, const int32_t p_data);
+int32_t GDAPI godot_packed_int32_array_get(const godot_packed_int32_array *p_self, const godot_int p_idx);
+
+godot_int GDAPI godot_packed_int32_array_size(const godot_packed_int32_array *p_self);
+
+godot_bool GDAPI godot_packed_int32_array_empty(const godot_packed_int32_array *p_self);
+
+void GDAPI godot_packed_int32_array_destroy(godot_packed_int32_array *p_self);
+
+// int64
+
+void GDAPI godot_packed_int64_array_new(godot_packed_int64_array *r_dest);
+void GDAPI godot_packed_int64_array_new_copy(godot_packed_int64_array *r_dest, const godot_packed_int64_array *p_src);
+void GDAPI godot_packed_int64_array_new_with_array(godot_packed_int64_array *r_dest, const godot_array *p_a);
+
+void GDAPI godot_packed_int64_array_append(godot_packed_int64_array *p_self, const int64_t p_data);
+
+void GDAPI godot_packed_int64_array_append_array(godot_packed_int64_array *p_self, const godot_packed_int64_array *p_array);
+
+godot_error GDAPI godot_packed_int64_array_insert(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data);
+
+void GDAPI godot_packed_int64_array_invert(godot_packed_int64_array *p_self);
+
+void GDAPI godot_packed_int64_array_push_back(godot_packed_int64_array *p_self, const int64_t p_data);
+
+void GDAPI godot_packed_int64_array_remove(godot_packed_int64_array *p_self, const godot_int p_idx);
+
+void GDAPI godot_packed_int64_array_resize(godot_packed_int64_array *p_self, const godot_int p_size);
+
+void GDAPI godot_packed_int64_array_set(godot_packed_int64_array *p_self, const godot_int p_idx, const int64_t p_data);
+int64_t GDAPI godot_packed_int64_array_get(const godot_packed_int64_array *p_self, const godot_int p_idx);
+
+godot_int GDAPI godot_packed_int64_array_size(const godot_packed_int64_array *p_self);
+
+godot_bool GDAPI godot_packed_int64_array_empty(const godot_packed_int64_array *p_self);
+
+void GDAPI godot_packed_int64_array_destroy(godot_packed_int64_array *p_self);
+
+// float32
-void GDAPI godot_packed_int_array_new(godot_packed_int_array *r_dest);
-void GDAPI godot_packed_int_array_new_copy(godot_packed_int_array *r_dest, const godot_packed_int_array *p_src);
-void GDAPI godot_packed_int_array_new_with_array(godot_packed_int_array *r_dest, const godot_array *p_a);
+void GDAPI godot_packed_float32_array_new(godot_packed_float32_array *r_dest);
+void GDAPI godot_packed_float32_array_new_copy(godot_packed_float32_array *r_dest, const godot_packed_float32_array *p_src);
+void GDAPI godot_packed_float32_array_new_with_array(godot_packed_float32_array *r_dest, const godot_array *p_a);
-void GDAPI godot_packed_int_array_append(godot_packed_int_array *p_self, const godot_int p_data);
+void GDAPI godot_packed_float32_array_append(godot_packed_float32_array *p_self, const float p_data);
-void GDAPI godot_packed_int_array_append_array(godot_packed_int_array *p_self, const godot_packed_int_array *p_array);
+void GDAPI godot_packed_float32_array_append_array(godot_packed_float32_array *p_self, const godot_packed_float32_array *p_array);
-godot_error GDAPI godot_packed_int_array_insert(godot_packed_int_array *p_self, const godot_int p_idx, const godot_int p_data);
+godot_error GDAPI godot_packed_float32_array_insert(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data);
-void GDAPI godot_packed_int_array_invert(godot_packed_int_array *p_self);
+void GDAPI godot_packed_float32_array_invert(godot_packed_float32_array *p_self);
-void GDAPI godot_packed_int_array_push_back(godot_packed_int_array *p_self, const godot_int p_data);
+void GDAPI godot_packed_float32_array_push_back(godot_packed_float32_array *p_self, const float p_data);
-void GDAPI godot_packed_int_array_remove(godot_packed_int_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_float32_array_remove(godot_packed_float32_array *p_self, const godot_int p_idx);
-void GDAPI godot_packed_int_array_resize(godot_packed_int_array *p_self, const godot_int p_size);
+void GDAPI godot_packed_float32_array_resize(godot_packed_float32_array *p_self, const godot_int p_size);
-void GDAPI godot_packed_int_array_set(godot_packed_int_array *p_self, const godot_int p_idx, const godot_int p_data);
-godot_int GDAPI godot_packed_int_array_get(const godot_packed_int_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_float32_array_set(godot_packed_float32_array *p_self, const godot_int p_idx, const float p_data);
+float GDAPI godot_packed_float32_array_get(const godot_packed_float32_array *p_self, const godot_int p_idx);
-godot_int GDAPI godot_packed_int_array_size(const godot_packed_int_array *p_self);
+godot_int GDAPI godot_packed_float32_array_size(const godot_packed_float32_array *p_self);
-godot_bool GDAPI godot_packed_int_array_empty(const godot_packed_int_array *p_self);
+godot_bool GDAPI godot_packed_float32_array_empty(const godot_packed_float32_array *p_self);
-void GDAPI godot_packed_int_array_destroy(godot_packed_int_array *p_self);
+void GDAPI godot_packed_float32_array_destroy(godot_packed_float32_array *p_self);
-// real
+// float64
-void GDAPI godot_packed_real_array_new(godot_packed_real_array *r_dest);
-void GDAPI godot_packed_real_array_new_copy(godot_packed_real_array *r_dest, const godot_packed_real_array *p_src);
-void GDAPI godot_packed_real_array_new_with_array(godot_packed_real_array *r_dest, const godot_array *p_a);
+void GDAPI godot_packed_float64_array_new(godot_packed_float64_array *r_dest);
+void GDAPI godot_packed_float64_array_new_copy(godot_packed_float64_array *r_dest, const godot_packed_float64_array *p_src);
+void GDAPI godot_packed_float64_array_new_with_array(godot_packed_float64_array *r_dest, const godot_array *p_a);
-void GDAPI godot_packed_real_array_append(godot_packed_real_array *p_self, const godot_real p_data);
+void GDAPI godot_packed_float64_array_append(godot_packed_float64_array *p_self, const double p_data);
-void GDAPI godot_packed_real_array_append_array(godot_packed_real_array *p_self, const godot_packed_real_array *p_array);
+void GDAPI godot_packed_float64_array_append_array(godot_packed_float64_array *p_self, const godot_packed_float64_array *p_array);
-godot_error GDAPI godot_packed_real_array_insert(godot_packed_real_array *p_self, const godot_int p_idx, const godot_real p_data);
+godot_error GDAPI godot_packed_float64_array_insert(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data);
-void GDAPI godot_packed_real_array_invert(godot_packed_real_array *p_self);
+void GDAPI godot_packed_float64_array_invert(godot_packed_float64_array *p_self);
-void GDAPI godot_packed_real_array_push_back(godot_packed_real_array *p_self, const godot_real p_data);
+void GDAPI godot_packed_float64_array_push_back(godot_packed_float64_array *p_self, const double p_data);
-void GDAPI godot_packed_real_array_remove(godot_packed_real_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_float64_array_remove(godot_packed_float64_array *p_self, const godot_int p_idx);
-void GDAPI godot_packed_real_array_resize(godot_packed_real_array *p_self, const godot_int p_size);
+void GDAPI godot_packed_float64_array_resize(godot_packed_float64_array *p_self, const godot_int p_size);
-void GDAPI godot_packed_real_array_set(godot_packed_real_array *p_self, const godot_int p_idx, const godot_real p_data);
-godot_real GDAPI godot_packed_real_array_get(const godot_packed_real_array *p_self, const godot_int p_idx);
+void GDAPI godot_packed_float64_array_set(godot_packed_float64_array *p_self, const godot_int p_idx, const double p_data);
+double GDAPI godot_packed_float64_array_get(const godot_packed_float64_array *p_self, const godot_int p_idx);
-godot_int GDAPI godot_packed_real_array_size(const godot_packed_real_array *p_self);
+godot_int GDAPI godot_packed_float64_array_size(const godot_packed_float64_array *p_self);
-godot_bool GDAPI godot_packed_real_array_empty(const godot_packed_real_array *p_self);
+godot_bool GDAPI godot_packed_float64_array_empty(const godot_packed_float64_array *p_self);
-void GDAPI godot_packed_real_array_destroy(godot_packed_real_array *p_self);
+void GDAPI godot_packed_float64_array_destroy(godot_packed_float64_array *p_self);
// string
diff --git a/modules/gdnative/include/gdnative/rect2.h b/modules/gdnative/include/gdnative/rect2.h
index 0ecf072471..f317afc9da 100644
--- a/modules/gdnative/include/gdnative/rect2.h
+++ b/modules/gdnative/include/gdnative/rect2.h
@@ -44,6 +44,13 @@ typedef struct godot_rect2 {
} godot_rect2;
#endif
+#ifndef GODOT_CORE_API_GODOT_RECT2I_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_RECT2I_TYPE_DEFINED
+typedef struct godot_rect2i {
+ uint8_t _dont_touch_that[16];
+} godot_rect2i;
+#endif
+
// reduce extern "C" nesting for VS2013
#ifdef __cplusplus
}
@@ -56,11 +63,15 @@ typedef struct godot_rect2 {
extern "C" {
#endif
+// Rect2
+
void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size);
void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height);
godot_string GDAPI godot_rect2_as_string(const godot_rect2 *p_self);
+godot_rect2i GDAPI godot_rect2_as_rect2i(const godot_rect2 *p_self);
+
godot_real GDAPI godot_rect2_get_area(const godot_rect2 *p_self);
godot_bool GDAPI godot_rect2_intersects(const godot_rect2 *p_self, const godot_rect2 *p_b);
@@ -95,6 +106,49 @@ void GDAPI godot_rect2_set_position(godot_rect2 *p_self, const godot_vector2 *p_
void GDAPI godot_rect2_set_size(godot_rect2 *p_self, const godot_vector2 *p_size);
+// Rect2I
+
+void GDAPI godot_rect2i_new_with_position_and_size(godot_rect2i *r_dest, const godot_vector2i *p_pos, const godot_vector2i *p_size);
+void GDAPI godot_rect2i_new(godot_rect2i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_width, const godot_int p_height);
+
+godot_string GDAPI godot_rect2i_as_string(const godot_rect2i *p_self);
+
+godot_rect2 GDAPI godot_rect2i_as_rect2(const godot_rect2i *p_self);
+
+godot_int GDAPI godot_rect2i_get_area(const godot_rect2i *p_self);
+
+godot_bool GDAPI godot_rect2i_intersects(const godot_rect2i *p_self, const godot_rect2i *p_b);
+
+godot_bool GDAPI godot_rect2i_encloses(const godot_rect2i *p_self, const godot_rect2i *p_b);
+
+godot_bool GDAPI godot_rect2i_has_no_area(const godot_rect2i *p_self);
+
+godot_rect2i GDAPI godot_rect2i_clip(const godot_rect2i *p_self, const godot_rect2i *p_b);
+
+godot_rect2i GDAPI godot_rect2i_merge(const godot_rect2i *p_self, const godot_rect2i *p_b);
+
+godot_bool GDAPI godot_rect2i_has_point(const godot_rect2i *p_self, const godot_vector2i *p_point);
+
+godot_rect2i GDAPI godot_rect2i_grow(const godot_rect2i *p_self, const godot_int p_by);
+
+godot_rect2i GDAPI godot_rect2i_grow_individual(const godot_rect2i *p_self, const godot_int p_left, const godot_int p_top, const godot_int p_right, const godot_int p_bottom);
+
+godot_rect2i GDAPI godot_rect2i_grow_margin(const godot_rect2i *p_self, const godot_int p_margin, const godot_int p_by);
+
+godot_rect2i GDAPI godot_rect2i_abs(const godot_rect2i *p_self);
+
+godot_rect2i GDAPI godot_rect2i_expand(const godot_rect2i *p_self, const godot_vector2i *p_to);
+
+godot_bool GDAPI godot_rect2i_operator_equal(const godot_rect2i *p_self, const godot_rect2i *p_b);
+
+godot_vector2i GDAPI godot_rect2i_get_position(const godot_rect2i *p_self);
+
+godot_vector2i GDAPI godot_rect2i_get_size(const godot_rect2i *p_self);
+
+void GDAPI godot_rect2i_set_position(godot_rect2i *p_self, const godot_vector2i *p_pos);
+
+void GDAPI godot_rect2i_set_size(godot_rect2i *p_self, const godot_vector2i *p_size);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/rid.h b/modules/gdnative/include/gdnative/rid.h
index 04661cedc8..73b601dc04 100644
--- a/modules/gdnative/include/gdnative/rid.h
+++ b/modules/gdnative/include/gdnative/rid.h
@@ -37,7 +37,7 @@ extern "C" {
#include <stdint.h>
-#define GODOT_RID_SIZE sizeof(void *)
+#define GODOT_RID_SIZE sizeof(uint64_t)
#ifndef GODOT_CORE_API_GODOT_RID_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_RID_TYPE_DEFINED
diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h
index 934e856fbf..0a611b76e9 100644
--- a/modules/gdnative/include/gdnative/variant.h
+++ b/modules/gdnative/include/gdnative/variant.h
@@ -37,7 +37,7 @@ extern "C" {
#include <stdint.h>
-#define GODOT_VARIANT_SIZE (16 + sizeof(void *))
+#define GODOT_VARIANT_SIZE (16 + sizeof(int64_t))
#ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED
#define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED
@@ -71,16 +71,21 @@ typedef enum godot_variant_type {
// misc types
GODOT_VARIANT_TYPE_COLOR,
+ GODOT_VARIANT_TYPE_STRING_NAME,
GODOT_VARIANT_TYPE_NODE_PATH,
GODOT_VARIANT_TYPE_RID,
GODOT_VARIANT_TYPE_OBJECT,
+ GODOT_VARIANT_TYPE_CALLABLE,
+ GODOT_VARIANT_TYPE_SIGNAL,
GODOT_VARIANT_TYPE_DICTIONARY,
GODOT_VARIANT_TYPE_ARRAY,
// arrays
GODOT_VARIANT_TYPE_PACKED_BYTE_ARRAY,
- GODOT_VARIANT_TYPE_PACKED_INT_ARRAY,
- GODOT_VARIANT_TYPE_PACKED_REAL_ARRAY,
+ GODOT_VARIANT_TYPE_PACKED_INT32_ARRAY,
+ GODOT_VARIANT_TYPE_PACKED_INT64_ARRAY,
+ GODOT_VARIANT_TYPE_PACKED_FLOAT32_ARRAY,
+ GODOT_VARIANT_TYPE_PACKED_FLOAT64_ARRAY,
GODOT_VARIANT_TYPE_PACKED_STRING_ARRAY,
GODOT_VARIANT_TYPE_PACKED_VECTOR2_ARRAY,
GODOT_VARIANT_TYPE_PACKED_VECTOR3_ARRAY,
@@ -149,15 +154,17 @@ typedef enum godot_variant_operator {
#include <gdnative/aabb.h>
#include <gdnative/array.h>
#include <gdnative/basis.h>
+#include <gdnative/callable.h>
#include <gdnative/color.h>
#include <gdnative/dictionary.h>
#include <gdnative/node_path.h>
+#include <gdnative/packed_arrays.h>
#include <gdnative/plane.h>
-#include <gdnative/pool_arrays.h>
#include <gdnative/quat.h>
#include <gdnative/rect2.h>
#include <gdnative/rid.h>
#include <gdnative/string.h>
+#include <gdnative/string_name.h>
#include <gdnative/transform.h>
#include <gdnative/transform2d.h>
#include <gdnative/variant.h>
@@ -181,9 +188,13 @@ void GDAPI godot_variant_new_uint(godot_variant *r_dest, const uint64_t p_i);
void GDAPI godot_variant_new_int(godot_variant *r_dest, const int64_t p_i);
void GDAPI godot_variant_new_real(godot_variant *r_dest, const double p_r);
void GDAPI godot_variant_new_string(godot_variant *r_dest, const godot_string *p_s);
+void GDAPI godot_variant_new_string_name(godot_variant *r_dest, const godot_string_name *p_s);
void GDAPI godot_variant_new_vector2(godot_variant *r_dest, const godot_vector2 *p_v2);
+void GDAPI godot_variant_new_vector2i(godot_variant *r_dest, const godot_vector2i *p_v2);
void GDAPI godot_variant_new_rect2(godot_variant *r_dest, const godot_rect2 *p_rect2);
+void GDAPI godot_variant_new_rect2i(godot_variant *r_dest, const godot_rect2i *p_rect2);
void GDAPI godot_variant_new_vector3(godot_variant *r_dest, const godot_vector3 *p_v3);
+void GDAPI godot_variant_new_vector3i(godot_variant *r_dest, const godot_vector3i *p_v3);
void GDAPI godot_variant_new_transform2d(godot_variant *r_dest, const godot_transform2d *p_t2d);
void GDAPI godot_variant_new_plane(godot_variant *r_dest, const godot_plane *p_plane);
void GDAPI godot_variant_new_quat(godot_variant *r_dest, const godot_quat *p_quat);
@@ -193,12 +204,16 @@ void GDAPI godot_variant_new_transform(godot_variant *r_dest, const godot_transf
void GDAPI godot_variant_new_color(godot_variant *r_dest, const godot_color *p_color);
void GDAPI godot_variant_new_node_path(godot_variant *r_dest, const godot_node_path *p_np);
void GDAPI godot_variant_new_rid(godot_variant *r_dest, const godot_rid *p_rid);
+void GDAPI godot_variant_new_callable(godot_variant *r_dest, const godot_callable *p_callable);
+void GDAPI godot_variant_new_signal(godot_variant *r_dest, const godot_signal *p_signal);
void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj);
void GDAPI godot_variant_new_dictionary(godot_variant *r_dest, const godot_dictionary *p_dict);
void GDAPI godot_variant_new_array(godot_variant *r_dest, const godot_array *p_arr);
void GDAPI godot_variant_new_packed_byte_array(godot_variant *r_dest, const godot_packed_byte_array *p_pba);
-void GDAPI godot_variant_new_packed_int_array(godot_variant *r_dest, const godot_packed_int_array *p_pia);
-void GDAPI godot_variant_new_packed_real_array(godot_variant *r_dest, const godot_packed_real_array *p_pra);
+void GDAPI godot_variant_new_packed_int32_array(godot_variant *r_dest, const godot_packed_int32_array *p_pia);
+void GDAPI godot_variant_new_packed_int64_array(godot_variant *r_dest, const godot_packed_int64_array *p_pia);
+void GDAPI godot_variant_new_packed_float32_array(godot_variant *r_dest, const godot_packed_float32_array *p_pra);
+void GDAPI godot_variant_new_packed_float64_array(godot_variant *r_dest, const godot_packed_float64_array *p_pra);
void GDAPI godot_variant_new_packed_string_array(godot_variant *r_dest, const godot_packed_string_array *p_psa);
void GDAPI godot_variant_new_packed_vector2_array(godot_variant *r_dest, const godot_packed_vector2_array *p_pv2a);
void GDAPI godot_variant_new_packed_vector3_array(godot_variant *r_dest, const godot_packed_vector3_array *p_pv3a);
@@ -209,9 +224,13 @@ uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_self);
int64_t GDAPI godot_variant_as_int(const godot_variant *p_self);
double GDAPI godot_variant_as_real(const godot_variant *p_self);
godot_string GDAPI godot_variant_as_string(const godot_variant *p_self);
+godot_string_name GDAPI godot_variant_as_string_name(const godot_variant *p_self);
godot_vector2 GDAPI godot_variant_as_vector2(const godot_variant *p_self);
+godot_vector2i GDAPI godot_variant_as_vector2i(const godot_variant *p_self);
godot_rect2 GDAPI godot_variant_as_rect2(const godot_variant *p_self);
+godot_rect2i GDAPI godot_variant_as_rect2i(const godot_variant *p_self);
godot_vector3 GDAPI godot_variant_as_vector3(const godot_variant *p_self);
+godot_vector3i GDAPI godot_variant_as_vector3i(const godot_variant *p_self);
godot_transform2d GDAPI godot_variant_as_transform2d(const godot_variant *p_self);
godot_plane GDAPI godot_variant_as_plane(const godot_variant *p_self);
godot_quat GDAPI godot_variant_as_quat(const godot_variant *p_self);
@@ -221,12 +240,16 @@ godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_self);
godot_color GDAPI godot_variant_as_color(const godot_variant *p_self);
godot_node_path GDAPI godot_variant_as_node_path(const godot_variant *p_self);
godot_rid GDAPI godot_variant_as_rid(const godot_variant *p_self);
+godot_callable GDAPI godot_variant_as_callable(const godot_variant *p_self);
+godot_signal GDAPI godot_variant_as_signal(const godot_variant *p_self);
godot_object GDAPI *godot_variant_as_object(const godot_variant *p_self);
godot_dictionary GDAPI godot_variant_as_dictionary(const godot_variant *p_self);
godot_array GDAPI godot_variant_as_array(const godot_variant *p_self);
godot_packed_byte_array GDAPI godot_variant_as_packed_byte_array(const godot_variant *p_self);
-godot_packed_int_array GDAPI godot_variant_as_packed_int_array(const godot_variant *p_self);
-godot_packed_real_array GDAPI godot_variant_as_packed_real_array(const godot_variant *p_self);
+godot_packed_int32_array GDAPI godot_variant_as_packed_int32_array(const godot_variant *p_self);
+godot_packed_int64_array GDAPI godot_variant_as_packed_int64_array(const godot_variant *p_self);
+godot_packed_float32_array GDAPI godot_variant_as_packed_float32_array(const godot_variant *p_self);
+godot_packed_float64_array GDAPI godot_variant_as_packed_float64_array(const godot_variant *p_self);
godot_packed_string_array GDAPI godot_variant_as_packed_string_array(const godot_variant *p_self);
godot_packed_vector2_array GDAPI godot_variant_as_packed_vector2_array(const godot_variant *p_self);
godot_packed_vector3_array GDAPI godot_variant_as_packed_vector3_array(const godot_variant *p_self);
@@ -239,6 +262,7 @@ godot_bool GDAPI godot_variant_has_method(const godot_variant *p_self, const god
godot_bool GDAPI godot_variant_operator_equal(const godot_variant *p_self, const godot_variant *p_other);
godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_self, const godot_variant *p_other);
+uint32_t GDAPI godot_variant_hash(const godot_variant *p_self);
godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const godot_variant *p_other);
godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_self);
diff --git a/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h
index 15a1a6063b..35b02c5a75 100644
--- a/modules/gdnative/include/gdnative/vector2.h
+++ b/modules/gdnative/include/gdnative/vector2.h
@@ -46,6 +46,15 @@ typedef struct {
} godot_vector2;
#endif
+#define GODOT_VECTOR2I_SIZE 8
+
+#ifndef GODOT_CORE_API_GODOT_VECTOR2I_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_VECTOR2I_TYPE_DEFINED
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_VECTOR2I_SIZE];
+} godot_vector2i;
+#endif
+
// reduce extern "C" nesting for VS2013
#ifdef __cplusplus
}
@@ -57,10 +66,14 @@ typedef struct {
extern "C" {
#endif
+// Vector2
+
void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y);
godot_string GDAPI godot_vector2_as_string(const godot_vector2 *p_self);
+godot_vector2i GDAPI godot_vector2_as_vector2i(const godot_vector2 *p_self);
+
godot_vector2 GDAPI godot_vector2_normalized(const godot_vector2 *p_self);
godot_real GDAPI godot_vector2_length(const godot_vector2 *p_self);
@@ -81,7 +94,7 @@ godot_real GDAPI godot_vector2_angle_to(const godot_vector2 *p_self, const godot
godot_real GDAPI godot_vector2_angle_to_point(const godot_vector2 *p_self, const godot_vector2 *p_to);
-godot_vector2 GDAPI godot_vector2_linear_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_real p_t);
+godot_vector2 GDAPI godot_vector2_lerp(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_real p_t);
godot_vector2 GDAPI godot_vector2_cubic_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_vector2 *p_pre_a, const godot_vector2 *p_post_b, const godot_real p_t);
@@ -93,6 +106,8 @@ godot_vector2 GDAPI godot_vector2_tangent(const godot_vector2 *p_self);
godot_vector2 GDAPI godot_vector2_floor(const godot_vector2 *p_self);
+godot_vector2 GDAPI godot_vector2_sign(const godot_vector2 *p_self);
+
godot_vector2 GDAPI godot_vector2_snapped(const godot_vector2 *p_self, const godot_vector2 *p_by);
godot_real GDAPI godot_vector2_aspect(const godot_vector2 *p_self);
@@ -135,6 +150,46 @@ godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_self);
godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_self);
+// Vector2i
+
+void GDAPI godot_vector2i_new(godot_vector2i *r_dest, const godot_int p_x, const godot_int p_y);
+
+godot_string GDAPI godot_vector2i_as_string(const godot_vector2i *p_self);
+
+godot_vector2 GDAPI godot_vector2i_as_vector2(const godot_vector2i *p_self);
+
+godot_real GDAPI godot_vector2i_aspect(const godot_vector2i *p_self);
+
+godot_vector2i GDAPI godot_vector2i_abs(const godot_vector2i *p_self);
+
+godot_vector2i GDAPI godot_vector2i_sign(const godot_vector2i *p_self);
+
+godot_vector2i GDAPI godot_vector2i_operator_add(const godot_vector2i *p_self, const godot_vector2i *p_b);
+
+godot_vector2i GDAPI godot_vector2i_operator_subtract(const godot_vector2i *p_self, const godot_vector2i *p_b);
+
+godot_vector2i GDAPI godot_vector2i_operator_multiply_vector(const godot_vector2i *p_self, const godot_vector2i *p_b);
+
+godot_vector2i GDAPI godot_vector2i_operator_multiply_scalar(const godot_vector2i *p_self, const godot_int p_b);
+
+godot_vector2i GDAPI godot_vector2i_operator_divide_vector(const godot_vector2i *p_self, const godot_vector2i *p_b);
+
+godot_vector2i GDAPI godot_vector2i_operator_divide_scalar(const godot_vector2i *p_self, const godot_int p_b);
+
+godot_bool GDAPI godot_vector2i_operator_equal(const godot_vector2i *p_self, const godot_vector2i *p_b);
+
+godot_bool GDAPI godot_vector2i_operator_less(const godot_vector2i *p_self, const godot_vector2i *p_b);
+
+godot_vector2i GDAPI godot_vector2i_operator_neg(const godot_vector2i *p_self);
+
+void GDAPI godot_vector2i_set_x(godot_vector2i *p_self, const godot_int p_x);
+
+void GDAPI godot_vector2i_set_y(godot_vector2i *p_self, const godot_int p_y);
+
+godot_int GDAPI godot_vector2i_get_x(const godot_vector2i *p_self);
+
+godot_int GDAPI godot_vector2i_get_y(const godot_vector2i *p_self);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h
index 1b344590ea..5127b8789b 100644
--- a/modules/gdnative/include/gdnative/vector3.h
+++ b/modules/gdnative/include/gdnative/vector3.h
@@ -46,6 +46,15 @@ typedef struct {
} godot_vector3;
#endif
+#define GODOT_VECTOR3I_SIZE 12
+
+#ifndef GODOT_CORE_API_GODOT_VECTOR3I_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_VECTOR3I_TYPE_DEFINED
+typedef struct {
+ uint8_t _dont_touch_that[GODOT_VECTOR3I_SIZE];
+} godot_vector3i;
+#endif
+
// reduce extern "C" nesting for VS2013
#ifdef __cplusplus
}
@@ -64,10 +73,14 @@ typedef enum {
GODOT_VECTOR3_AXIS_Z,
} godot_vector3_axis;
+// Vector3
+
void GDAPI godot_vector3_new(godot_vector3 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z);
godot_string GDAPI godot_vector3_as_string(const godot_vector3 *p_self);
+godot_vector3i GDAPI godot_vector3_as_vector3i(const godot_vector3 *p_self);
+
godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_self);
godot_int GDAPI godot_vector3_max_axis(const godot_vector3 *p_self);
@@ -86,7 +99,7 @@ godot_vector3 GDAPI godot_vector3_snapped(const godot_vector3 *p_self, const god
godot_vector3 GDAPI godot_vector3_rotated(const godot_vector3 *p_self, const godot_vector3 *p_axis, const godot_real p_phi);
-godot_vector3 GDAPI godot_vector3_linear_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_real p_t);
+godot_vector3 GDAPI godot_vector3_lerp(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_real p_t);
godot_vector3 GDAPI godot_vector3_cubic_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_vector3 *p_pre_a, const godot_vector3 *p_post_b, const godot_real p_t);
@@ -102,6 +115,8 @@ godot_basis GDAPI godot_vector3_to_diagonal_matrix(const godot_vector3 *p_self);
godot_vector3 GDAPI godot_vector3_abs(const godot_vector3 *p_self);
+godot_vector3 GDAPI godot_vector3_sign(const godot_vector3 *p_self);
+
godot_vector3 GDAPI godot_vector3_floor(const godot_vector3 *p_self);
godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_self);
@@ -142,6 +157,44 @@ void GDAPI godot_vector3_set_axis(godot_vector3 *p_self, const godot_vector3_axi
godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_self, const godot_vector3_axis p_axis);
+// Vector3i
+
+void GDAPI godot_vector3i_new(godot_vector3i *r_dest, const godot_int p_x, const godot_int p_y, const godot_int p_z);
+
+godot_string GDAPI godot_vector3i_as_string(const godot_vector3i *p_self);
+
+godot_vector3 GDAPI godot_vector3i_as_vector3(const godot_vector3i *p_self);
+
+godot_int GDAPI godot_vector3i_min_axis(const godot_vector3i *p_self);
+
+godot_int GDAPI godot_vector3i_max_axis(const godot_vector3i *p_self);
+
+godot_vector3i GDAPI godot_vector3i_abs(const godot_vector3i *p_self);
+
+godot_vector3i GDAPI godot_vector3i_sign(const godot_vector3i *p_self);
+
+godot_vector3i GDAPI godot_vector3i_operator_add(const godot_vector3i *p_self, const godot_vector3i *p_b);
+
+godot_vector3i GDAPI godot_vector3i_operator_subtract(const godot_vector3i *p_self, const godot_vector3i *p_b);
+
+godot_vector3i GDAPI godot_vector3i_operator_multiply_vector(const godot_vector3i *p_self, const godot_vector3i *p_b);
+
+godot_vector3i GDAPI godot_vector3i_operator_multiply_scalar(const godot_vector3i *p_self, const godot_int p_b);
+
+godot_vector3i GDAPI godot_vector3i_operator_divide_vector(const godot_vector3i *p_self, const godot_vector3i *p_b);
+
+godot_vector3i GDAPI godot_vector3i_operator_divide_scalar(const godot_vector3i *p_self, const godot_int p_b);
+
+godot_bool GDAPI godot_vector3i_operator_equal(const godot_vector3i *p_self, const godot_vector3i *p_b);
+
+godot_bool GDAPI godot_vector3i_operator_less(const godot_vector3i *p_self, const godot_vector3i *p_b);
+
+godot_vector3i GDAPI godot_vector3i_operator_neg(const godot_vector3i *p_self);
+
+void GDAPI godot_vector3i_set_axis(godot_vector3i *p_self, const godot_vector3_axis p_axis, const godot_int p_val);
+
+godot_int GDAPI godot_vector3i_get_axis(const godot_vector3i *p_self, const godot_vector3_axis p_axis);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/include/nativescript/godot_nativescript.h b/modules/gdnative/include/nativescript/godot_nativescript.h
index dcf2ddb9ca..d65b3f91f4 100644
--- a/modules/gdnative/include/nativescript/godot_nativescript.h
+++ b/modules/gdnative/include/nativescript/godot_nativescript.h
@@ -95,6 +95,7 @@ typedef enum {
GODOT_PROPERTY_USAGE_INTERNATIONALIZED = 64, //hint for internationalized strings
GODOT_PROPERTY_USAGE_GROUP = 128, //used for grouping props in the editor
GODOT_PROPERTY_USAGE_CATEGORY = 256,
+ GODOT_PROPERTY_USAGE_SUBGROUP = 512,
GODOT_PROPERTY_USAGE_NO_INSTANCE_STATE = 2048,
GODOT_PROPERTY_USAGE_RESTART_IF_CHANGED = 4096,
GODOT_PROPERTY_USAGE_SCRIPT_VARIABLE = 8192,
@@ -171,17 +172,17 @@ typedef struct {
godot_string hint_string;
godot_property_usage_flags usage;
godot_variant default_value;
-} godot_signal_argument;
+} godot_nativescript_signal_argument;
typedef struct {
godot_string name;
int num_args;
- godot_signal_argument *args;
+ godot_nativescript_signal_argument *args;
int num_default_args;
godot_variant *default_args;
-} godot_signal;
+} godot_nativescript_signal;
-void GDAPI godot_nativescript_register_signal(void *p_gdnative_handle, const char *p_name, const godot_signal *p_signal);
+void GDAPI godot_nativescript_register_signal(void *p_gdnative_handle, const char *p_name, const godot_nativescript_signal *p_signal);
void GDAPI *godot_nativescript_get_userdata(godot_object *p_instance);
diff --git a/modules/gdnative/include/net/godot_net.h b/modules/gdnative/include/net/godot_net.h
index d245f3b965..42804112f2 100644
--- a/modules/gdnative/include/net/godot_net.h
+++ b/modules/gdnative/include/net/godot_net.h
@@ -45,7 +45,6 @@ extern "C" {
#define GODOT_NET_API_MINOR 1
typedef struct {
-
godot_gdnative_api_version version; /* version of our API */
godot_object *data; /* User reference */
diff --git a/modules/gdnative/include/videodecoder/godot_videodecoder.h b/modules/gdnative/include/videodecoder/godot_videodecoder.h
index 3e91a2e9ac..16c92abd22 100644
--- a/modules/gdnative/include/videodecoder/godot_videodecoder.h
+++ b/modules/gdnative/include/videodecoder/godot_videodecoder.h
@@ -46,7 +46,7 @@ typedef struct
void *next;
void *(*constructor)(godot_object *);
void (*destructor)(void *);
- const char *(*get_plugin_name)(void);
+ const char *(*get_plugin_name)();
const char **(*get_supported_extensions)(int *count);
godot_bool (*open_file)(void *, void *); // data struct, and a FileAccess pointer
godot_real (*get_length)(const void *);
diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp
index 3c0cfd0484..62f2ec5024 100644
--- a/modules/gdnative/nativescript/api_generator.cpp
+++ b/modules/gdnative/nativescript/api_generator.cpp
@@ -41,7 +41,6 @@
// helper stuff
static Error save_file(const String &p_path, const List<String> &p_content) {
-
FileAccessRef file = FileAccess::open(p_path, FileAccess::WRITE);
ERR_FAIL_COND_V(!file, ERR_FILE_CANT_WRITE);
@@ -146,7 +145,6 @@ static String get_type_name(const PropertyInfo &info) {
struct MethodInfoComparator {
StringName::AlphCompare compare;
bool operator()(const MethodInfo &p_a, const MethodInfo &p_b) const {
-
return compare(p_a.name, p_b.name);
}
};
@@ -154,7 +152,6 @@ struct MethodInfoComparator {
struct PropertyInfoComparator {
StringName::AlphCompare compare;
bool operator()(const PropertyInfo &p_a, const PropertyInfo &p_b) const {
-
return compare(p_a.name, p_b.name);
}
};
@@ -162,7 +159,6 @@ struct PropertyInfoComparator {
struct ConstantAPIComparator {
NoCaseComparator compare;
bool operator()(const ConstantAPI &p_a, const ConstantAPI &p_b) const {
-
return compare(p_a.constant_name, p_b.constant_name);
}
};
@@ -171,7 +167,6 @@ struct ConstantAPIComparator {
* Reads the entire Godot API to a list
*/
List<ClassAPI> generate_c_api_classes() {
-
List<ClassAPI> api;
List<StringName> classes;
@@ -410,7 +405,6 @@ List<ClassAPI> generate_c_api_classes() {
* Generates the JSON source from the API in p_api
*/
static List<String> generate_c_api_json(const List<ClassAPI> &p_api) {
-
// I'm sorry for the \t mess
List<String> source;
@@ -520,7 +514,6 @@ static List<String> generate_c_api_json(const List<ClassAPI> &p_api) {
* p_path
*/
Error generate_c_api(const String &p_path) {
-
#ifndef TOOLS_ENABLED
return ERR_BUG;
#else
diff --git a/modules/gdnative/nativescript/godot_nativescript.cpp b/modules/gdnative/nativescript/godot_nativescript.cpp
index 0502458b4f..1aea8ad160 100644
--- a/modules/gdnative/nativescript/godot_nativescript.cpp
+++ b/modules/gdnative/nativescript/godot_nativescript.cpp
@@ -52,7 +52,6 @@ extern "C" void _native_script_hook() {
// Script API
void GDAPI godot_nativescript_register_class(void *p_gdnative_handle, const char *p_name, const char *p_base, godot_instance_create_func p_create_func, godot_instance_destroy_func p_destroy_func) {
-
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc> *classes = &NSL->library_classes[*s];
@@ -85,7 +84,6 @@ void GDAPI godot_nativescript_register_class(void *p_gdnative_handle, const char
}
void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const char *p_name, const char *p_base, godot_instance_create_func p_create_func, godot_instance_destroy_func p_destroy_func) {
-
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc> *classes = &NSL->library_classes[*s];
@@ -119,7 +117,6 @@ void GDAPI godot_nativescript_register_tool_class(void *p_gdnative_handle, const
}
void GDAPI godot_nativescript_register_method(void *p_gdnative_handle, const char *p_name, const char *p_function_name, godot_method_attributes p_attr, godot_instance_method p_method) {
-
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
@@ -139,7 +136,6 @@ void GDAPI godot_nativescript_register_method(void *p_gdnative_handle, const cha
}
void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const char *p_name, const char *p_path, godot_property_attributes *p_attr, godot_property_set_func p_set_func, godot_property_get_func p_get_func) {
-
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
@@ -163,8 +159,7 @@ void GDAPI godot_nativescript_register_property(void *p_gdnative_handle, const c
E->get().properties.insert(p_path, property);
}
-void GDAPI godot_nativescript_register_signal(void *p_gdnative_handle, const char *p_name, const godot_signal *p_signal) {
-
+void GDAPI godot_nativescript_register_signal(void *p_gdnative_handle, const char *p_name, const godot_nativescript_signal *p_signal) {
String *s = (String *)p_gdnative_handle;
Map<StringName, NativeScriptDesc>::Element *E = NSL->library_classes[*s].find(p_name);
@@ -176,7 +171,7 @@ void GDAPI godot_nativescript_register_signal(void *p_gdnative_handle, const cha
for (int i = 0; i < p_signal->num_args; i++) {
PropertyInfo info;
- godot_signal_argument arg = p_signal->args[i];
+ godot_nativescript_signal_argument arg = p_signal->args[i];
info.hint = (PropertyHint)arg.hint;
info.hint_string = *(String *)&arg.hint_string;
@@ -189,7 +184,7 @@ void GDAPI godot_nativescript_register_signal(void *p_gdnative_handle, const cha
for (int i = 0; i < p_signal->num_default_args; i++) {
Variant *v;
- godot_signal_argument attrib = p_signal->args[i];
+ godot_nativescript_signal_argument attrib = p_signal->args[i];
v = (Variant *)&attrib.default_value;
@@ -209,8 +204,9 @@ void GDAPI godot_nativescript_register_signal(void *p_gdnative_handle, const cha
void GDAPI *godot_nativescript_get_userdata(godot_object *p_instance) {
Object *instance = (Object *)p_instance;
- if (!instance)
+ if (!instance) {
return nullptr;
+ }
if (instance->get_script_instance() && instance->get_script_instance()->get_language() == NativeScriptLanguage::get_singleton()) {
return ((NativeScriptInstance *)instance->get_script_instance())->userdata;
}
@@ -315,7 +311,6 @@ void GDAPI godot_nativescript_set_type_tag(void *p_gdnative_handle, const char *
}
const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object) {
-
const Object *o = (Object *)p_object;
if (!o->get_script_instance()) {
@@ -326,8 +321,9 @@ const void GDAPI *godot_nativescript_get_type_tag(const godot_object *p_object)
return nullptr;
}
- if (script->get_script_desc())
+ if (script->get_script_desc()) {
return script->get_script_desc()->type_tag;
+ }
}
return nullptr;
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index bf458c15ee..f3dfd0b68e 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -111,6 +111,13 @@ void NativeScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder)
#endif
+bool NativeScript::inherits_script(const Ref<Script> &p_script) const {
+#ifndef _MSC_VER
+#warning inheritance needs to be implemented in NativeScript
+#endif
+ return false;
+}
+
void NativeScript::set_class_name(String p_class_name) {
class_name = p_class_name;
}
@@ -162,7 +169,6 @@ String NativeScript::get_script_class_icon_path() const {
}
bool NativeScript::can_instance() const {
-
NativeScriptDesc *script_data = get_script_desc();
#ifdef TOOLS_ENABLED
@@ -178,8 +184,9 @@ bool NativeScript::can_instance() const {
Ref<Script> NativeScript::get_base_script() const {
NativeScriptDesc *script_data = get_script_desc();
- if (!script_data)
+ if (!script_data) {
return Ref<Script>();
+ }
NativeScript *script = (NativeScript *)NSL->create_script();
Ref<NativeScript> ns = Ref<NativeScript>(script);
@@ -193,14 +200,14 @@ Ref<Script> NativeScript::get_base_script() const {
StringName NativeScript::get_instance_base_type() const {
NativeScriptDesc *script_data = get_script_desc();
- if (!script_data)
+ if (!script_data) {
return "";
+ }
return script_data->base_native_type;
}
ScriptInstance *NativeScript::instance_create(Object *p_this) {
-
NativeScriptDesc *script_data = get_script_desc();
if (!script_data) {
@@ -267,8 +274,9 @@ bool NativeScript::has_method(const StringName &p_method) const {
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
- if (script_data->methods.has(p_method))
+ if (script_data->methods.has(p_method)) {
return true;
+ }
script_data = script_data->base_data;
}
@@ -278,14 +286,16 @@ bool NativeScript::has_method(const StringName &p_method) const {
MethodInfo NativeScript::get_method_info(const StringName &p_method) const {
NativeScriptDesc *script_data = get_script_desc();
- if (!script_data)
+ if (!script_data) {
return MethodInfo();
+ }
while (script_data) {
Map<StringName, NativeScriptDesc::Method>::Element *M = script_data->methods.find(p_method);
- if (M)
+ if (M) {
return M->get().info;
+ }
script_data = script_data->base_data;
}
@@ -299,8 +309,9 @@ bool NativeScript::is_valid() const {
bool NativeScript::is_tool() const {
NativeScriptDesc *script_data = get_script_desc();
- if (script_data)
+ if (script_data) {
return script_data->is_tool;
+ }
return false;
}
@@ -313,8 +324,9 @@ bool NativeScript::has_script_signal(const StringName &p_signal) const {
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
- if (script_data->signals_.has(p_signal))
+ if (script_data->signals_.has(p_signal)) {
return true;
+ }
script_data = script_data->base_data;
}
return false;
@@ -323,13 +335,13 @@ bool NativeScript::has_script_signal(const StringName &p_signal) const {
void NativeScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
NativeScriptDesc *script_data = get_script_desc();
- if (!script_data)
+ if (!script_data) {
return;
+ }
Set<MethodInfo> signals_;
while (script_data) {
-
for (Map<StringName, NativeScriptDesc::Signal>::Element *S = script_data->signals_.front(); S; S = S->next()) {
signals_.insert(S->get().signal);
}
@@ -350,8 +362,9 @@ bool NativeScript::get_property_default_value(const StringName &p_property, Vari
P = script_data->properties.find(p_property);
script_data = script_data->base_data;
}
- if (!P)
+ if (!P) {
return false;
+ }
r_value = P.get().default_value;
return true;
@@ -363,13 +376,13 @@ void NativeScript::update_exports() {
void NativeScript::get_script_method_list(List<MethodInfo> *p_list) const {
NativeScriptDesc *script_data = get_script_desc();
- if (!script_data)
+ if (!script_data) {
return;
+ }
Set<MethodInfo> methods;
while (script_data) {
-
for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
methods.insert(E->get().info);
}
@@ -401,13 +414,11 @@ void NativeScript::get_script_property_list(List<PropertyInfo> *p_list) const {
}
Vector<ScriptNetData> NativeScript::get_rpc_methods() const {
-
Vector<ScriptNetData> v;
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
-
for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
if (E->get().rpc_mode != GODOT_METHOD_RPC_MODE_DISABLED) {
ScriptNetData nd;
@@ -427,7 +438,6 @@ uint16_t NativeScript::get_rpc_method_id(const StringName &p_method) const {
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
-
Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method);
if (E) {
return E->get().rpc_method_id;
@@ -445,7 +455,6 @@ StringName NativeScript::get_rpc_method(uint16_t p_id) const {
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
-
for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
if (E->get().rpc_method_id == p_id) {
return E->key();
@@ -459,13 +468,11 @@ StringName NativeScript::get_rpc_method(uint16_t p_id) const {
}
MultiplayerAPI::RPCMode NativeScript::get_rpc_mode_by_id(uint16_t p_id) const {
-
ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED);
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
-
for (Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.front(); E; E = E->next()) {
if (E->get().rpc_method_id == p_id) {
switch (E->get().rpc_mode) {
@@ -496,11 +503,9 @@ MultiplayerAPI::RPCMode NativeScript::get_rpc_mode_by_id(uint16_t p_id) const {
}
MultiplayerAPI::RPCMode NativeScript::get_rpc_mode(const StringName &p_method) const {
-
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
-
Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find(p_method);
if (E) {
switch (E->get().rpc_mode) {
@@ -535,7 +540,6 @@ Vector<ScriptNetData> NativeScript::get_rset_properties() const {
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
-
for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
if (E.get().rset_mode != GODOT_METHOD_RPC_MODE_DISABLED) {
ScriptNetData nd;
@@ -554,7 +558,6 @@ uint16_t NativeScript::get_rset_property_id(const StringName &p_variable) const
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
-
OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable);
if (E) {
return E.get().rset_property_id;
@@ -572,7 +575,6 @@ StringName NativeScript::get_rset_property(uint16_t p_id) const {
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
-
for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
if (E.get().rset_property_id == p_id) {
return E.key();
@@ -586,13 +588,11 @@ StringName NativeScript::get_rset_property(uint16_t p_id) const {
}
MultiplayerAPI::RPCMode NativeScript::get_rset_mode_by_id(uint16_t p_id) const {
-
ERR_FAIL_COND_V(p_id == UINT16_MAX, MultiplayerAPI::RPC_MODE_DISABLED);
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
-
for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.front(); E; E = E.next()) {
if (E.get().rset_property_id == p_id) {
switch (E.get().rset_mode) {
@@ -623,11 +623,9 @@ MultiplayerAPI::RPCMode NativeScript::get_rset_mode_by_id(uint16_t p_id) const {
}
MultiplayerAPI::RPCMode NativeScript::get_rset_mode(const StringName &p_variable) const {
-
NativeScriptDesc *script_data = get_script_desc();
while (script_data) {
-
OrderedHashMap<StringName, NativeScriptDesc::Property>::Element E = script_data->properties.find(p_variable);
if (E) {
switch (E.get().rset_mode) {
@@ -670,7 +668,6 @@ String NativeScript::get_method_documentation(const StringName &p_method) const
ERR_FAIL_COND_V_MSG(!script_data, "", "Attempt to get method documentation on invalid NativeScript.");
while (script_data) {
-
Map<StringName, NativeScriptDesc::Method>::Element *method = script_data->methods.find(p_method);
if (method) {
@@ -689,7 +686,6 @@ String NativeScript::get_signal_documentation(const StringName &p_signal_name) c
ERR_FAIL_COND_V_MSG(!script_data, "", "Attempt to get signal documentation on invalid NativeScript.");
while (script_data) {
-
Map<StringName, NativeScriptDesc::Signal>::Element *signal = script_data->signals_.find(p_signal_name);
if (signal) {
@@ -708,7 +704,6 @@ String NativeScript::get_property_documentation(const StringName &p_path) const
ERR_FAIL_COND_V_MSG(!script_data, "", "Attempt to get property documentation on invalid NativeScript.");
while (script_data) {
-
OrderedHashMap<StringName, NativeScriptDesc::Property>::Element property = script_data->properties.find(p_path);
if (property) {
@@ -722,7 +717,6 @@ String NativeScript::get_property_documentation(const StringName &p_path) const
}
Variant NativeScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (lib_path.empty() || class_name.empty() || library.is_null()) {
r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
return Variant();
@@ -833,6 +827,7 @@ bool NativeScriptInstance::set(const StringName &p_name, const Variant &p_value)
}
return false;
}
+
bool NativeScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
NativeScriptDesc *script_data = GET_SCRIPT_DESC();
@@ -877,10 +872,8 @@ void NativeScriptInstance::get_property_list(List<PropertyInfo> *p_properties) c
NativeScriptDesc *script_data = GET_SCRIPT_DESC();
while (script_data) {
-
Map<StringName, NativeScriptDesc::Method>::Element *E = script_data->methods.find("_get_property_list");
if (E) {
-
godot_variant result;
result = E->get().method.method((godot_object *)owner,
E->get().method.method_data,
@@ -929,11 +922,9 @@ void NativeScriptInstance::get_property_list(List<PropertyInfo> *p_properties) c
}
Variant::Type NativeScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
-
NativeScriptDesc *script_data = GET_SCRIPT_DESC();
while (script_data) {
-
OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P = script_data->properties.find(p_name);
if (P) {
*r_is_valid = true;
@@ -954,7 +945,6 @@ bool NativeScriptInstance::has_method(const StringName &p_method) const {
}
Variant NativeScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
NativeScriptDesc *script_data = GET_SCRIPT_DESC();
while (script_data) {
@@ -1010,17 +1000,20 @@ String NativeScriptInstance::to_string(bool *r_valid) {
Variant ret = call(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce);
if (ce.error == Callable::CallError::CALL_OK) {
if (ret.get_type() != Variant::STRING) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
}
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return ret.operator String();
}
}
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return String();
}
@@ -1120,11 +1113,11 @@ void NativeScriptInstance::call_multilevel_reversed(const StringName &p_method,
}
NativeScriptInstance::~NativeScriptInstance() {
-
NativeScriptDesc *script_data = GET_SCRIPT_DESC();
- if (!script_data)
+ if (!script_data) {
return;
+ }
script_data->destroy_func.destroy_func((godot_object *)owner, script_data->destroy_func.method_data, userdata);
@@ -1138,16 +1131,13 @@ NativeScriptInstance::~NativeScriptInstance() {
NativeScriptLanguage *NativeScriptLanguage::singleton;
void NativeScriptLanguage::_unload_stuff(bool p_reload) {
-
Map<String, Ref<GDNative>> erase_and_unload;
for (Map<String, Map<StringName, NativeScriptDesc>>::Element *L = library_classes.front(); L; L = L->next()) {
-
String lib_path = L->key();
Map<StringName, NativeScriptDesc> classes = L->get();
if (p_reload) {
-
Map<String, Ref<GDNative>>::Element *E = library_gdnatives.find(lib_path);
Ref<GDNative> gdn;
@@ -1177,28 +1167,32 @@ void NativeScriptLanguage::_unload_stuff(bool p_reload) {
}
for (Map<StringName, NativeScriptDesc>::Element *C = classes.front(); C; C = C->next()) {
-
// free property stuff first
for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P = C->get().properties.front(); P; P = P.next()) {
- if (P.get().getter.free_func)
+ if (P.get().getter.free_func) {
P.get().getter.free_func(P.get().getter.method_data);
+ }
- if (P.get().setter.free_func)
+ if (P.get().setter.free_func) {
P.get().setter.free_func(P.get().setter.method_data);
+ }
}
// free method stuff
for (Map<StringName, NativeScriptDesc::Method>::Element *M = C->get().methods.front(); M; M = M->next()) {
- if (M->get().method.free_func)
+ if (M->get().method.free_func) {
M->get().method.free_func(M->get().method.method_data);
+ }
}
// free constructor/destructor
- if (C->get().create_func.free_func)
+ if (C->get().create_func.free_func) {
C->get().create_func.free_func(C->get().create_func.method_data);
+ }
- if (C->get().destroy_func.free_func)
+ if (C->get().destroy_func.free_func) {
C->get().destroy_func.free_func(C->get().destroy_func.method_data);
+ }
}
erase_and_unload.insert(lib_path, gdn);
@@ -1246,13 +1240,10 @@ NativeScriptLanguage::NativeScriptLanguage() {
}
NativeScriptLanguage::~NativeScriptLanguage() {
-
for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
-
Ref<GDNative> lib = L->get();
// only shut down valid libs, duh!
if (lib.is_valid()) {
-
// If it's a singleton-library then the gdnative module
// manages the destruction at engine shutdown, not NativeScript.
if (!lib->get_library()->is_singleton()) {
@@ -1278,7 +1269,6 @@ void _add_reload_node() {
}
void NativeScriptLanguage::init() {
-
#if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED)
List<String> args = OS::get_singleton()->get_cmdline_args();
@@ -1297,22 +1287,29 @@ void NativeScriptLanguage::init() {
EditorNode::add_init_callback(&_add_reload_node);
#endif
}
+
String NativeScriptLanguage::get_type() const {
return "NativeScript";
}
+
String NativeScriptLanguage::get_extension() const {
return "gdns";
}
+
Error NativeScriptLanguage::execute_file(const String &p_path) {
return OK; // Qué?
}
+
void NativeScriptLanguage::finish() {
_unload_stuff();
}
+
void NativeScriptLanguage::get_reserved_words(List<String> *p_words) const {
}
+
void NativeScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
}
+
void NativeScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const {
}
@@ -1321,6 +1318,7 @@ Ref<Script> NativeScriptLanguage::get_template(const String &p_class_name, const
s->set_class_name(p_class_name);
return Ref<NativeScript>(s);
}
+
bool NativeScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
return true;
}
@@ -1329,20 +1327,26 @@ Script *NativeScriptLanguage::create_script() const {
NativeScript *script = memnew(NativeScript);
return script;
}
+
bool NativeScriptLanguage::has_named_classes() const {
return true;
}
+
bool NativeScriptLanguage::supports_builtin_mode() const {
return true;
}
+
int NativeScriptLanguage::find_function(const String &p_function, const String &p_code) const {
return -1;
}
+
String NativeScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const {
return "";
}
+
void NativeScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {
}
+
void NativeScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) {
}
@@ -1350,27 +1354,36 @@ void NativeScriptLanguage::add_global_constant(const StringName &p_variable, con
String NativeScriptLanguage::debug_get_error() const {
return "";
}
+
int NativeScriptLanguage::debug_get_stack_level_count() const {
return -1;
}
+
int NativeScriptLanguage::debug_get_stack_level_line(int p_level) const {
return -1;
}
+
String NativeScriptLanguage::debug_get_stack_level_function(int p_level) const {
return "";
}
+
String NativeScriptLanguage::debug_get_stack_level_source(int p_level) const {
return "";
}
+
void NativeScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
}
+
void NativeScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
}
+
void NativeScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
}
+
String NativeScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
return "";
}
+
// Debugging stuff end.
void NativeScriptLanguage::reload_all_scripts() {
@@ -1378,6 +1391,7 @@ void NativeScriptLanguage::reload_all_scripts() {
void NativeScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) {
}
+
void NativeScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("gdns");
}
@@ -1412,8 +1426,9 @@ int NativeScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_a
int current = 0;
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
- if (current >= p_info_max)
+ if (current >= p_info_max) {
break;
+ }
p_info_arr[current].call_count = d->get().call_count;
p_info_arr[current].self_time = d->get().self_time;
@@ -1435,8 +1450,9 @@ int NativeScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, in
int current = 0;
for (Map<StringName, ProfileData>::Element *d = profile_data.front(); d; d = d->next()) {
- if (current >= p_info_max)
+ if (current >= p_info_max) {
break;
+ }
if (d->get().last_frame_call_count) {
p_info_arr[current].call_count = d->get().last_frame_call_count;
@@ -1483,7 +1499,6 @@ void NativeScriptLanguage::profiling_add_data(StringName p_signature, uint64_t p
}
int NativeScriptLanguage::register_binding_functions(godot_instance_binding_functions p_binding_functions) {
-
// find index
int idx = -1;
@@ -1514,14 +1529,16 @@ void NativeScriptLanguage::unregister_binding_functions(int p_idx) {
for (Set<Vector<void *> *>::Element *E = binding_instances.front(); E; E = E->next()) {
Vector<void *> &binding_data = *E->get();
- if (p_idx < binding_data.size() && binding_data[p_idx] && binding_functions[p_idx].second.free_instance_binding_data)
+ if (p_idx < binding_data.size() && binding_data[p_idx] && binding_functions[p_idx].second.free_instance_binding_data) {
binding_functions[p_idx].second.free_instance_binding_data(binding_functions[p_idx].second.data, binding_data[p_idx]);
+ }
}
binding_functions.write[p_idx].first = false;
- if (binding_functions[p_idx].second.free_func)
+ if (binding_functions[p_idx].second.free_func) {
binding_functions[p_idx].second.free_func(binding_functions[p_idx].second.data);
+ }
}
void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_object) {
@@ -1531,8 +1548,9 @@ void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_objec
Vector<void *> *binding_data = (Vector<void *> *)p_object->get_script_instance_binding(lang_idx);
- if (!binding_data)
+ if (!binding_data) {
return nullptr; // should never happen.
+ }
if (binding_data->size() <= p_idx) {
// okay, add new elements here.
@@ -1546,7 +1564,6 @@ void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_objec
}
if (!(*binding_data)[p_idx]) {
-
const void *global_type_tag = get_global_type_tag(p_idx, p_object->get_class_name());
// no binding data yet, soooooo alloc new one \o/
@@ -1557,7 +1574,6 @@ void *NativeScriptLanguage::get_instance_binding_data(int p_idx, Object *p_objec
}
void *NativeScriptLanguage::alloc_instance_binding_data(Object *p_object) {
-
Vector<void *> *binding_data = new Vector<void *>;
binding_data->resize(binding_functions.size());
@@ -1572,15 +1588,16 @@ void *NativeScriptLanguage::alloc_instance_binding_data(Object *p_object) {
}
void NativeScriptLanguage::free_instance_binding_data(void *p_data) {
-
- if (!p_data)
+ if (!p_data) {
return;
+ }
Vector<void *> &binding_data = *(Vector<void *> *)p_data;
for (int i = 0; i < binding_data.size(); i++) {
- if (!binding_data[i])
+ if (!binding_data[i]) {
continue;
+ }
if (binding_functions[i].first && binding_functions[i].second.free_instance_binding_data) {
binding_functions[i].second.free_instance_binding_data(binding_functions[i].second.data, binding_data[i]);
@@ -1593,20 +1610,22 @@ void NativeScriptLanguage::free_instance_binding_data(void *p_data) {
}
void NativeScriptLanguage::refcount_incremented_instance_binding(Object *p_object) {
-
void *data = p_object->get_script_instance_binding(lang_idx);
- if (!data)
+ if (!data) {
return;
+ }
Vector<void *> &binding_data = *(Vector<void *> *)data;
for (int i = 0; i < binding_data.size(); i++) {
- if (!binding_data[i])
+ if (!binding_data[i]) {
continue;
+ }
- if (!binding_functions[i].first)
+ if (!binding_functions[i].first) {
continue;
+ }
if (binding_functions[i].second.refcount_incremented_instance_binding) {
binding_functions[i].second.refcount_incremented_instance_binding(binding_data[i], p_object);
@@ -1615,22 +1634,24 @@ void NativeScriptLanguage::refcount_incremented_instance_binding(Object *p_objec
}
bool NativeScriptLanguage::refcount_decremented_instance_binding(Object *p_object) {
-
void *data = p_object->get_script_instance_binding(lang_idx);
- if (!data)
+ if (!data) {
return true;
+ }
Vector<void *> &binding_data = *(Vector<void *> *)data;
bool can_die = true;
for (int i = 0; i < binding_data.size(); i++) {
- if (!binding_data[i])
+ if (!binding_data[i]) {
continue;
+ }
- if (!binding_functions[i].first)
+ if (!binding_functions[i].first) {
continue;
+ }
if (binding_functions[i].second.refcount_decremented_instance_binding) {
can_die = can_die && binding_functions[i].second.refcount_decremented_instance_binding(binding_data[i], p_object);
@@ -1651,13 +1672,15 @@ void NativeScriptLanguage::set_global_type_tag(int p_idx, StringName p_class_nam
}
const void *NativeScriptLanguage::get_global_type_tag(int p_idx, StringName p_class_name) const {
- if (!global_type_tags.has(p_idx))
+ if (!global_type_tags.has(p_idx)) {
return nullptr;
+ }
const HashMap<StringName, const void *> &tags = global_type_tags[p_idx];
- if (!tags.has(p_class_name))
+ if (!tags.has(p_class_name)) {
return nullptr;
+ }
const void *tag = tags.get(p_class_name);
@@ -1693,8 +1716,9 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
library_classes.insert(lib_path, Map<StringName, NativeScriptDesc>());
- if (!library_script_users.has(lib_path))
+ if (!library_script_users.has(lib_path)) {
library_script_users.insert(lib_path, Set<NativeScript *>());
+ }
void *proc_ptr;
@@ -1734,13 +1758,11 @@ void NativeScriptLanguage::unregister_script(NativeScript *script) {
void NativeScriptLanguage::call_libraries_cb(const StringName &name) {
// library_gdnatives is modified only from the main thread, so it's safe not to use mutex here
for (Map<String, Ref<GDNative>>::Element *L = library_gdnatives.front(); L; L = L->next()) {
-
if (L->get().is_null()) {
continue;
}
if (L->get()->is_initialized()) {
-
void *proc_ptr;
Error err = L->get()->get_symbol(L->get()->get_library()->get_symbol_prefix() + name, proc_ptr);
@@ -1805,16 +1827,20 @@ String NativeScriptLanguage::get_global_class_name(const String &p_path, String
if (!p_path.empty()) {
Ref<NativeScript> script = ResourceLoader::load(p_path, "NativeScript");
if (script.is_valid()) {
- if (r_base_type)
+ if (r_base_type) {
*r_base_type = script->get_instance_base_type();
- if (r_icon_path)
+ }
+ if (r_icon_path) {
*r_icon_path = script->get_script_class_icon_path();
+ }
return script->get_script_class_name();
}
- if (r_base_type)
+ if (r_base_type) {
*r_base_type = String();
- if (r_icon_path)
+ }
+ if (r_icon_path) {
*r_icon_path = String();
+ }
}
return String();
}
@@ -1828,14 +1854,13 @@ void NativeReloadNode::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_WM_FOCUS_OUT: {
-
- if (unloaded)
+ if (unloaded) {
break;
+ }
MutexLock lock(NSL->mutex);
NSL->_unload_stuff(true);
for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
-
Ref<GDNative> gdn = L->get();
if (gdn.is_null()) {
@@ -1863,14 +1888,13 @@ void NativeReloadNode::_notification(int p_what) {
} break;
case NOTIFICATION_WM_FOCUS_IN: {
-
- if (!unloaded)
+ if (!unloaded) {
break;
+ }
MutexLock lock(NSL->mutex);
Set<StringName> libs_to_remove;
for (Map<String, Ref<GDNative>>::Element *L = NSL->library_gdnatives.front(); L; L = L->next()) {
-
Ref<GDNative> gdn = L->get();
if (gdn.is_null()) {
@@ -1908,8 +1932,9 @@ void NativeReloadNode::_notification(int p_what) {
for (Set<NativeScript *>::Element *S = U->get().front(); S; S = S->next()) {
NativeScript *script = S->get();
- if (script->placeholders.size() == 0)
+ if (script->placeholders.size() == 0) {
continue;
+ }
for (Set<PlaceHolderScriptInstance *>::Element *P = script->placeholders.front(); P; P = P->next()) {
script->_update_placeholder(P->get());
@@ -1931,7 +1956,7 @@ void NativeReloadNode::_notification(int p_what) {
#endif
}
-RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderNativeScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
return ResourceFormatLoaderText::singleton->load(p_path, p_original_path, r_error);
}
@@ -1945,8 +1970,9 @@ bool ResourceFormatLoaderNativeScript::handles_type(const String &p_type) const
String ResourceFormatLoaderNativeScript::get_resource_type(const String &p_path) const {
String el = p_path.get_extension().to_lower();
- if (el == "gdns")
+ if (el == "gdns") {
return "NativeScript";
+ }
return "";
}
diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index 75bbb42664..1aca142889 100644
--- a/modules/gdnative/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -43,10 +43,10 @@
#include "scene/main/node.h"
#include "modules/gdnative/gdnative.h"
+
#include <nativescript/godot_nativescript.h>
struct NativeScriptDesc {
-
struct Method {
godot_instance_method method;
MethodInfo info;
@@ -54,6 +54,7 @@ struct NativeScriptDesc {
uint16_t rpc_method_id;
String documentation;
};
+
struct Property {
godot_property_set_func setter;
godot_property_get_func getter;
@@ -69,9 +70,9 @@ struct NativeScriptDesc {
String documentation;
};
- uint16_t rpc_count;
+ uint16_t rpc_count = 0;
Map<StringName, Method> methods;
- uint16_t rset_count;
+ uint16_t rset_count = 0;
OrderedHashMap<StringName, Property> properties;
Map<StringName, Signal> signals_; // QtCreator doesn't like the name signals
StringName base;
@@ -82,20 +83,11 @@ struct NativeScriptDesc {
String documentation;
- const void *type_tag;
+ const void *type_tag = nullptr;
bool is_tool;
- inline NativeScriptDesc() :
- rpc_count(0),
- methods(),
- rset_count(0),
- properties(),
- signals_(),
- base(),
- base_native_type(),
- documentation(),
- type_tag(nullptr) {
+ inline NativeScriptDesc() {
zeromem(&create_func, sizeof(godot_instance_create_func));
zeromem(&destroy_func, sizeof(godot_instance_destroy_func));
}
@@ -133,6 +125,8 @@ protected:
public:
inline NativeScriptDesc *get_script_desc() const;
+ bool inherits_script(const Ref<Script> &p_script) const;
+
void set_class_name(String p_class_name);
String get_class_name() const;
@@ -199,7 +193,6 @@ public:
};
class NativeScriptInstance : public ScriptInstance {
-
friend class NativeScript;
Object *owner;
@@ -250,7 +243,6 @@ public:
class NativeReloadNode;
class NativeScriptLanguage : public ScriptLanguage {
-
friend class NativeScript;
friend class NativeScriptInstance;
friend class NativeReloadNode;
@@ -394,19 +386,18 @@ inline NativeScriptDesc *NativeScript::get_script_desc() const {
class NativeReloadNode : public Node {
GDCLASS(NativeReloadNode, Node);
- bool unloaded;
+ bool unloaded = false;
public:
static void _bind_methods();
void _notification(int p_what);
- NativeReloadNode() :
- unloaded(false) {}
+ NativeReloadNode() {}
};
class ResourceFormatLoaderNativeScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/nativescript/register_types.cpp b/modules/gdnative/nativescript/register_types.cpp
index b5e8174e43..ac8c7ab2fd 100644
--- a/modules/gdnative/nativescript/register_types.cpp
+++ b/modules/gdnative/nativescript/register_types.cpp
@@ -58,7 +58,6 @@ void register_nativescript_types() {
}
void unregister_nativescript_types() {
-
ResourceLoader::remove_resource_format_loader(resource_loader_gdns);
resource_loader_gdns.unref();
diff --git a/modules/gdnative/net/multiplayer_peer_gdnative.cpp b/modules/gdnative/net/multiplayer_peer_gdnative.cpp
index a95697ea65..997eec6425 100644
--- a/modules/gdnative/net/multiplayer_peer_gdnative.cpp
+++ b/modules/gdnative/net/multiplayer_peer_gdnative.cpp
@@ -120,7 +120,6 @@ void MultiplayerPeerGDNative::_bind_methods() {
extern "C" {
void GDAPI godot_net_bind_multiplayer_peer(godot_object *p_obj, const godot_net_multiplayer_peer *p_impl) {
-
((MultiplayerPeerGDNative *)p_obj)->set_native_multiplayer_peer(p_impl);
}
}
diff --git a/modules/gdnative/net/packet_peer_gdnative.cpp b/modules/gdnative/net/packet_peer_gdnative.cpp
index 28135df3b6..6bb21cb48d 100644
--- a/modules/gdnative/net/packet_peer_gdnative.cpp
+++ b/modules/gdnative/net/packet_peer_gdnative.cpp
@@ -67,7 +67,6 @@ int PacketPeerGDNative::get_available_packet_count() const {
extern "C" {
void GDAPI godot_net_bind_packet_peer(godot_object *p_obj, const godot_net_packet_peer *p_impl) {
-
((PacketPeerGDNative *)p_obj)->set_native_packet_peer(p_impl);
}
}
diff --git a/modules/gdnative/net/stream_peer_gdnative.h b/modules/gdnative/net/stream_peer_gdnative.h
index f3711e0f0f..0b2f995aa7 100644
--- a/modules/gdnative/net/stream_peer_gdnative.h
+++ b/modules/gdnative/net/stream_peer_gdnative.h
@@ -36,7 +36,6 @@
#include "modules/gdnative/include/net/godot_net.h"
class StreamPeerGDNative : public StreamPeer {
-
GDCLASS(StreamPeerGDNative, StreamPeer);
protected:
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp
index 3fb22b3f8d..4feee4f4a5 100644
--- a/modules/gdnative/pluginscript/pluginscript_loader.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp
@@ -39,9 +39,10 @@ ResourceFormatLoaderPluginScript::ResourceFormatLoaderPluginScript(PluginScriptL
_language = language;
}
-RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
- if (r_error)
+RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
+ }
PluginScript *script = memnew(PluginScript);
script->init(_language);
@@ -55,8 +56,9 @@ RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p
script->reload();
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return scriptres;
}
@@ -71,8 +73,9 @@ bool ResourceFormatLoaderPluginScript::handles_type(const String &p_type) const
String ResourceFormatLoaderPluginScript::get_resource_type(const String &p_path) const {
String el = p_path.get_extension().to_lower();
- if (el == _language->get_extension())
+ if (el == _language->get_extension()) {
return _language->get_type();
+ }
return "";
}
@@ -101,13 +104,11 @@ Error ResourceFormatSaverPluginScript::save(const String &p_path, const RES &p_r
}
void ResourceFormatSaverPluginScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
-
if (Object::cast_to<PluginScript>(*p_resource)) {
p_extensions->push_back(_language->get_extension());
}
}
bool ResourceFormatSaverPluginScript::recognize(const RES &p_resource) const {
-
return Object::cast_to<PluginScript>(*p_resource) != nullptr;
}
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h
index c929be53bd..35fc79c2ca 100644
--- a/modules/gdnative/pluginscript/pluginscript_loader.h
+++ b/modules/gdnative/pluginscript/pluginscript_loader.h
@@ -39,19 +39,17 @@
class PluginScriptLanguage;
class ResourceFormatLoaderPluginScript : public ResourceFormatLoader {
-
PluginScriptLanguage *_language;
public:
ResourceFormatLoaderPluginScript(PluginScriptLanguage *language);
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
class ResourceFormatSaverPluginScript : public ResourceFormatSaver {
-
PluginScriptLanguage *_language;
public:
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp
index a4c84dc0ca..87c6288806 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_script.cpp
@@ -56,7 +56,6 @@ void PluginScript::_bind_methods() {
}
PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Callable::CallError &r_error) {
-
r_error.error = Callable::CallError::CALL_OK;
// Create instance
@@ -84,7 +83,6 @@ PluginScriptInstance *PluginScript::_create_instance(const Variant **p_args, int
}
Variant PluginScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
r_error.error = Callable::CallError::CALL_OK;
if (!_valid) {
@@ -140,6 +138,13 @@ bool PluginScript::can_instance() const {
return can;
}
+bool PluginScript::inherits_script(const Ref<Script> &p_script) const {
+#ifndef _MSC_VER
+#warning inheritance needs to be implemented in PluginScript
+#endif
+ return false;
+}
+
Ref<Script> PluginScript::get_base_script() const {
if (_ref_base_parent.is_valid()) {
return Ref<PluginScript>(_ref_base_parent);
@@ -149,10 +154,12 @@ Ref<Script> PluginScript::get_base_script() const {
}
StringName PluginScript::get_instance_base_type() const {
- if (_native_parent)
+ if (_native_parent) {
return _native_parent;
- if (_ref_base_parent.is_valid())
+ }
+ if (_ref_base_parent.is_valid()) {
return _ref_base_parent->get_instance_base_type();
+ }
return StringName();
}
@@ -160,7 +167,6 @@ void PluginScript::update_exports() {
#ifdef TOOLS_ENABLED
ASSERT_SCRIPT_VALID();
if (placeholders.size()) {
-
//update placeholders if any
Map<StringName, Variant> propdefvalues;
List<PropertyInfo> propinfos;
@@ -222,8 +228,9 @@ String PluginScript::get_source_code() const {
}
void PluginScript::set_source_code(const String &p_code) {
- if (_source == p_code)
+ if (_source == p_code) {
return;
+ }
_source = p_code;
}
@@ -237,11 +244,13 @@ Error PluginScript::reload(bool p_keep_state) {
_valid = false;
String basedir = _path;
- if (basedir == "")
+ if (basedir == "") {
basedir = get_path();
+ }
- if (basedir != "")
+ if (basedir != "") {
basedir = basedir.get_base_dir();
+ }
if (_data) {
_desc->finish(_data);
@@ -274,7 +283,6 @@ Error PluginScript::reload(bool p_keep_state) {
// ClassDB name (i.e. `Node2D`) or a resource path (i.e. `res://foo/bar.gd`)
StringName *base_name = (StringName *)&manifest.base;
if (*base_name) {
-
if (ClassDB::class_exists(*base_name)) {
_native_parent = *base_name;
} else {
@@ -427,7 +435,6 @@ ScriptLanguage *PluginScript::get_language() const {
}
Error PluginScript::load_source_code(const String &p_path) {
-
Vector<uint8_t> sourcef;
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
@@ -469,11 +476,11 @@ void PluginScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
int PluginScript::get_member_line(const StringName &p_member) const {
#ifdef TOOLS_ENABLED
- if (_member_lines.has(p_member))
+ if (_member_lines.has(p_member)) {
return _member_lines[p_member];
- else
+ }
#endif
- return -1;
+ return -1;
}
Vector<ScriptNetData> PluginScript::get_rpc_methods() const {
@@ -492,15 +499,17 @@ uint16_t PluginScript::get_rpc_method_id(const StringName &p_method) const {
StringName PluginScript::get_rpc_method(const uint16_t p_rpc_method_id) const {
ASSERT_SCRIPT_VALID_V(StringName());
- if (p_rpc_method_id >= _rpc_methods.size())
+ if (p_rpc_method_id >= _rpc_methods.size()) {
return StringName();
+ }
return _rpc_methods[p_rpc_method_id].name;
}
MultiplayerAPI::RPCMode PluginScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
- if (p_rpc_method_id >= _rpc_methods.size())
+ if (p_rpc_method_id >= _rpc_methods.size()) {
return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
return _rpc_methods[p_rpc_method_id].mode;
}
@@ -525,15 +534,17 @@ uint16_t PluginScript::get_rset_property_id(const StringName &p_property) const
StringName PluginScript::get_rset_property(const uint16_t p_rset_property_id) const {
ASSERT_SCRIPT_VALID_V(StringName());
- if (p_rset_property_id >= _rpc_variables.size())
+ if (p_rset_property_id >= _rpc_variables.size()) {
return StringName();
+ }
return _rpc_variables[p_rset_property_id].name;
}
MultiplayerAPI::RPCMode PluginScript::get_rset_mode_by_id(const uint16_t p_rset_property_id) const {
ASSERT_SCRIPT_VALID_V(MultiplayerAPI::RPC_MODE_DISABLED);
- if (p_rset_property_id >= _rpc_variables.size())
+ if (p_rset_property_id >= _rpc_variables.size()) {
return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
return _rpc_variables[p_rset_property_id].mode;
}
@@ -543,11 +554,6 @@ MultiplayerAPI::RPCMode PluginScript::get_rset_mode(const StringName &p_variable
}
PluginScript::PluginScript() :
- _data(nullptr),
- _desc(nullptr),
- _language(nullptr),
- _tool(false),
- _valid(false),
_script_list(this) {
}
diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h
index 5c93ae38f5..659289ef9b 100644
--- a/modules/gdnative/pluginscript/pluginscript_script.h
+++ b/modules/gdnative/pluginscript/pluginscript_script.h
@@ -38,18 +38,17 @@
#include <pluginscript/godot_pluginscript.h>
class PluginScript : public Script {
-
GDCLASS(PluginScript, Script);
friend class PluginScriptInstance;
friend class PluginScriptLanguage;
private:
- godot_pluginscript_script_data *_data;
- const godot_pluginscript_script_desc *_desc;
- PluginScriptLanguage *_language;
- bool _tool;
- bool _valid;
+ godot_pluginscript_script_data *_data = nullptr;
+ const godot_pluginscript_script_desc *_desc = nullptr;
+ PluginScriptLanguage *_language = nullptr;
+ bool _tool = false;
+ bool _valid = false;
Ref<Script> _ref_base_parent;
StringName _native_parent;
@@ -72,6 +71,8 @@ private:
protected:
static void _bind_methods();
+ bool inherits_script(const Ref<Script> &p_script) const;
+
PluginScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, Callable::CallError &r_error);
Variant _new(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index 67a286ee2e..136af5bd1e 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -53,7 +53,6 @@
#include "gdnative_library_singleton_editor.h"
class GDNativeExportPlugin : public EditorExportPlugin {
-
protected:
virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features);
};
@@ -77,7 +76,6 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty
Ref<ConfigFile> config = lib->get_config_file();
{
-
List<String> entry_keys;
config->get_section_keys("entry", &entry_keys);
@@ -189,7 +187,6 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty
}
static void editor_init_callback() {
-
GDNativeLibrarySingletonEditor *library_editor = memnew(GDNativeLibrarySingletonEditor);
library_editor->set_name(TTR("GDNative"));
ProjectSettingsEditor::get_singleton()->get_tabs()->add_child(library_editor);
@@ -205,7 +202,6 @@ static void editor_init_callback() {
#endif
static godot_variant cb_standard_varcall(void *p_procedure_handle, godot_array *p_args) {
-
godot_gdnative_procedure_fn proc;
proc = (godot_gdnative_procedure_fn)p_procedure_handle;
@@ -220,7 +216,6 @@ Ref<GDNativeLibraryResourceLoader> resource_loader_gdnlib;
Ref<GDNativeLibraryResourceSaver> resource_saver_gdnlib;
void register_gdnative_types() {
-
#ifdef TOOLS_ENABLED
EditorNode::add_init_callback(editor_init_callback);
@@ -259,8 +254,9 @@ void register_gdnative_types() {
for (int i = 0; i < singletons.size(); i++) {
String path = singletons[i];
- if (excluded.has(path))
+ if (excluded.has(path)) {
continue;
+ }
Ref<GDNativeLibrary> lib = ResourceLoader::load(path);
Ref<GDNative> singleton;
@@ -287,9 +283,7 @@ void register_gdnative_types() {
}
void unregister_gdnative_types() {
-
for (int i = 0; i < singleton_gdnatives.size(); i++) {
-
if (singleton_gdnatives[i].is_null()) {
continue;
}
diff --git a/modules/gdnative/videodecoder/register_types.cpp b/modules/gdnative/videodecoder/register_types.cpp
index c53e8f2c78..4181d8813f 100644
--- a/modules/gdnative/videodecoder/register_types.cpp
+++ b/modules/gdnative/videodecoder/register_types.cpp
@@ -36,7 +36,6 @@
static Ref<ResourceFormatLoaderVideoStreamGDNative> resource_loader_vsgdnative;
void register_videodecoder_types() {
-
resource_loader_vsgdnative.instance();
ResourceLoader::add_resource_format_loader(resource_loader_vsgdnative, true);
@@ -44,7 +43,6 @@ void register_videodecoder_types() {
}
void unregister_videodecoder_types() {
-
ResourceLoader::remove_resource_format_loader(resource_loader_vsgdnative);
resource_loader_vsgdnative.unref();
}
diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.cpp b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
index fa9f6be5c1..9d9c5b6473 100644
--- a/modules/gdnative/videodecoder/video_stream_gdnative.cpp
+++ b/modules/gdnative/videodecoder/video_stream_gdnative.cpp
@@ -105,7 +105,6 @@ int64_t GDAPI godot_videodecoder_file_seek(void *ptr, int64_t pos, int whence) {
}
void GDAPI godot_videodecoder_register_decoder(const godot_videodecoder_interface_gdnative *p_interface) {
-
decoder_server.register_decoder_interface(p_interface);
}
}
@@ -202,32 +201,19 @@ void VideoStreamPlaybackGDNative::update_texture() {
// ctor and dtor
VideoStreamPlaybackGDNative::VideoStreamPlaybackGDNative() :
- texture(Ref<ImageTexture>(memnew(ImageTexture))),
- playing(false),
- paused(false),
- mix_udata(nullptr),
- mix_callback(nullptr),
- num_channels(-1),
- time(0),
- seek_backward(false),
- mix_rate(0),
- delay_compensation(0),
- pcm(nullptr),
- pcm_write_idx(0),
- samples_decoded(0),
- file(nullptr),
- interface(nullptr),
- data_struct(nullptr) {}
+ texture(Ref<ImageTexture>(memnew(ImageTexture))) {}
VideoStreamPlaybackGDNative::~VideoStreamPlaybackGDNative() {
cleanup();
}
void VideoStreamPlaybackGDNative::cleanup() {
- if (data_struct)
+ if (data_struct) {
interface->destructor(data_struct);
- if (pcm)
+ }
+ if (pcm) {
memfree(pcm);
+ }
pcm = nullptr;
time = 0;
num_channels = -1;
@@ -255,7 +241,6 @@ bool VideoStreamPlaybackGDNative::is_paused() const {
}
void VideoStreamPlaybackGDNative::play() {
-
stop();
playing = true;
@@ -274,8 +259,9 @@ void VideoStreamPlaybackGDNative::stop() {
void VideoStreamPlaybackGDNative::seek(float p_time) {
ERR_FAIL_COND(interface == nullptr);
interface->seek(data_struct, p_time);
- if (p_time < time)
+ if (p_time < time) {
seek_backward = true;
+ }
time = p_time;
// reset audio buffers
memset(pcm, 0, num_channels * AUX_BUFFER_SIZE * sizeof(float));
@@ -297,7 +283,6 @@ float VideoStreamPlaybackGDNative::get_length() const {
}
float VideoStreamPlaybackGDNative::get_playback_position() const {
-
ERR_FAIL_COND_V(interface == nullptr, 0);
return interface->get_playback_position(data_struct);
}
@@ -317,7 +302,6 @@ void VideoStreamPlaybackGDNative::set_audio_track(int p_idx) {
}
void VideoStreamPlaybackGDNative::set_mix_callback(AudioMixCallback p_callback, void *p_userdata) {
-
mix_udata = p_userdata;
mix_callback = p_callback;
}
@@ -339,27 +323,26 @@ int VideoStreamPlaybackGDNative::get_mix_rate() const {
Ref<VideoStreamPlayback> VideoStreamGDNative::instance_playback() {
Ref<VideoStreamPlaybackGDNative> pb = memnew(VideoStreamPlaybackGDNative);
VideoDecoderGDNative *decoder = decoder_server.get_decoder(file.get_extension().to_lower());
- if (decoder == nullptr)
+ if (decoder == nullptr) {
return nullptr;
+ }
pb->set_interface(decoder->interface);
pb->set_audio_track(audio_track);
- if (pb->open_file(file))
+ if (pb->open_file(file)) {
return pb;
+ }
return nullptr;
}
void VideoStreamGDNative::set_file(const String &p_file) {
-
file = p_file;
}
String VideoStreamGDNative::get_file() {
-
return file;
}
void VideoStreamGDNative::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamGDNative::set_file);
ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamGDNative::get_file);
@@ -367,13 +350,12 @@ void VideoStreamGDNative::_bind_methods() {
}
void VideoStreamGDNative::set_audio_track(int p_track) {
-
audio_track = p_track;
}
/* --- NOTE ResourceFormatLoaderVideoStreamGDNative starts here. ----- */
-RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+RES ResourceFormatLoaderVideoStreamGDNative::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
if (r_error) {
@@ -405,7 +387,8 @@ bool ResourceFormatLoaderVideoStreamGDNative::handles_type(const String &p_type)
String ResourceFormatLoaderVideoStreamGDNative::get_resource_type(const String &p_path) const {
String el = p_path.get_extension().to_lower();
- if (VideoDecoderServer::get_instance()->get_extensions().has(el))
+ if (VideoDecoderServer::get_instance()->get_extensions().has(el)) {
return "VideoStreamGDNative";
+ }
return "";
}
diff --git a/modules/gdnative/videodecoder/video_stream_gdnative.h b/modules/gdnative/videodecoder/video_stream_gdnative.h
index fbc0d4016f..53017a6a97 100644
--- a/modules/gdnative/videodecoder/video_stream_gdnative.h
+++ b/modules/gdnative/videodecoder/video_stream_gdnative.h
@@ -37,13 +37,11 @@
#include "scene/resources/video_stream.h"
struct VideoDecoderGDNative {
- const godot_videodecoder_interface_gdnative *interface;
- String plugin_name;
+ const godot_videodecoder_interface_gdnative *interface = nullptr;
+ String plugin_name = "none";
Vector<String> supported_extensions;
- VideoDecoderGDNative() :
- interface(nullptr),
- plugin_name("none") {}
+ VideoDecoderGDNative() {}
VideoDecoderGDNative(const godot_videodecoder_interface_gdnative *p_interface) :
interface(p_interface),
@@ -88,8 +86,9 @@ public:
}
VideoDecoderGDNative *get_decoder(const String &extension) {
- if (extensions.size() == 0 || !extensions.has(extension))
+ if (extensions.size() == 0 || !extensions.has(extension)) {
return nullptr;
+ }
return decoders[extensions[extension]];
}
@@ -107,27 +106,26 @@ public:
};
class VideoStreamPlaybackGDNative : public VideoStreamPlayback {
-
GDCLASS(VideoStreamPlaybackGDNative, VideoStreamPlayback);
Ref<ImageTexture> texture;
- bool playing;
- bool paused;
+ bool playing = false;
+ bool paused = false;
Vector2 texture_size;
- void *mix_udata;
- AudioMixCallback mix_callback;
+ void *mix_udata = nullptr;
+ AudioMixCallback mix_callback = nullptr;
- int num_channels;
- float time;
- bool seek_backward;
- int mix_rate;
- double delay_compensation;
+ int num_channels = -1;
+ float time = 0;
+ bool seek_backward = false;
+ int mix_rate = 0;
+ double delay_compensation = 0;
- float *pcm;
- int pcm_write_idx;
- int samples_decoded;
+ float *pcm = nullptr;
+ int pcm_write_idx = 0;
+ int samples_decoded = 0;
void cleanup();
void update_texture();
@@ -135,10 +133,10 @@ class VideoStreamPlaybackGDNative : public VideoStreamPlayback {
protected:
String file_name;
- FileAccess *file;
+ FileAccess *file = nullptr;
- const godot_videodecoder_interface_gdnative *interface;
- void *data_struct;
+ const godot_videodecoder_interface_gdnative *interface = nullptr;
+ void *data_struct = nullptr;
public:
VideoStreamPlaybackGDNative();
@@ -177,11 +175,10 @@ public:
};
class VideoStreamGDNative : public VideoStream {
-
GDCLASS(VideoStreamGDNative, VideoStream);
String file;
- int audio_track;
+ int audio_track = 0;
protected:
static void
@@ -194,12 +191,12 @@ public:
virtual void set_audio_track(int p_track);
virtual Ref<VideoStreamPlayback> instance_playback();
- VideoStreamGDNative() { audio_track = 0; }
+ VideoStreamGDNative() {}
};
class ResourceFormatLoaderVideoStreamGDNative : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdnative/xr/xr_interface_gdnative.cpp b/modules/gdnative/xr/xr_interface_gdnative.cpp
index 0451945139..d03fc33935 100644
--- a/modules/gdnative/xr/xr_interface_gdnative.cpp
+++ b/modules/gdnative/xr/xr_interface_gdnative.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "xr_interface_gdnative.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "servers/rendering/rendering_server_globals.h"
#include "servers/xr/xr_positional_tracker.h"
@@ -80,7 +80,6 @@ void XRInterfaceGDNative::set_interface(const godot_xr_interface_gdnative *p_int
}
StringName XRInterfaceGDNative::get_name() const {
-
ERR_FAIL_COND_V(interface == nullptr, StringName());
godot_string result = interface->get_name(data);
@@ -103,21 +102,18 @@ int XRInterfaceGDNative::get_capabilities() const {
}
bool XRInterfaceGDNative::get_anchor_detection_is_enabled() const {
-
ERR_FAIL_COND_V(interface == nullptr, false);
return interface->get_anchor_detection_is_enabled(data);
}
void XRInterfaceGDNative::set_anchor_detection_is_enabled(bool p_enable) {
-
ERR_FAIL_COND(interface == nullptr);
interface->set_anchor_detection_is_enabled(data, p_enable);
}
int XRInterfaceGDNative::get_camera_feed_id() {
-
ERR_FAIL_COND_V(interface == nullptr, 0);
return (unsigned int)interface->get_camera_feed_id(data);
@@ -134,7 +130,6 @@ bool XRInterfaceGDNative::is_stereo() {
}
bool XRInterfaceGDNative::is_initialized() const {
-
ERR_FAIL_COND_V(interface == nullptr, false);
return interface->is_initialized(data);
@@ -170,7 +165,6 @@ void XRInterfaceGDNative::uninitialize() {
}
Size2 XRInterfaceGDNative::get_render_targetsize() {
-
ERR_FAIL_COND_V(interface == nullptr, Size2());
godot_vector2 result = interface->get_render_targetsize(data);
@@ -202,14 +196,12 @@ CameraMatrix XRInterfaceGDNative::get_projection_for_eye(XRInterface::Eyes p_eye
}
unsigned int XRInterfaceGDNative::get_external_texture_for_eye(XRInterface::Eyes p_eye) {
-
ERR_FAIL_COND_V(interface == nullptr, 0);
return (unsigned int)interface->get_external_texture_for_eye(data, (godot_int)p_eye);
}
void XRInterfaceGDNative::commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
-
ERR_FAIL_COND(interface == nullptr);
interface->commit_for_eye(data, (godot_int)p_eye, (godot_rid *)&p_render_target, (godot_rect2 *)&p_screen_rect);
@@ -306,7 +298,7 @@ godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, g
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, 0);
- InputFilter *input = InputFilter::get_singleton();
+ Input *input = Input::get_singleton();
ERR_FAIL_NULL_V(input, 0);
XRPositionalTracker *new_tracker = memnew(XRPositionalTracker);
@@ -345,7 +337,7 @@ void GDAPI godot_xr_remove_controller(godot_int p_controller_id) {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL(xr_server);
- InputFilter *input = InputFilter::get_singleton();
+ Input *input = Input::get_singleton();
ERR_FAIL_NULL(input);
XRPositionalTracker *remove_tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
@@ -383,7 +375,7 @@ void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL(xr_server);
- InputFilter *input = InputFilter::get_singleton();
+ Input *input = Input::get_singleton();
ERR_FAIL_NULL(input);
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
@@ -399,14 +391,14 @@ void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_a
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL(xr_server);
- InputFilter *input = InputFilter::get_singleton();
+ Input *input = Input::get_singleton();
ERR_FAIL_NULL(input);
XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
if (tracker != nullptr) {
int joyid = tracker->get_joy_id();
if (joyid != -1) {
- InputFilter::JoyAxis jx;
+ Input::JoyAxis jx;
jx.min = p_can_be_negative ? -1 : 0;
jx.value = p_value;
input->joy_axis(joyid, p_axis, jx);
diff --git a/modules/gdnavigation/gd_navigation_server.cpp b/modules/gdnavigation/gd_navigation_server.cpp
index 278c27ae22..c80cdcfeab 100644
--- a/modules/gdnavigation/gd_navigation_server.cpp
+++ b/modules/gdnavigation/gd_navigation_server.cpp
@@ -114,8 +114,7 @@
void GdNavigationServer::MERGE(_cmd_, F_NAME)(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3)
GdNavigationServer::GdNavigationServer() :
- NavigationServer3D(),
- active(true) {
+ NavigationServer3D() {
}
GdNavigationServer::~GdNavigationServer() {
@@ -250,9 +249,9 @@ COMMAND_2(region_set_map, RID, p_region, RID, p_map) {
ERR_FAIL_COND(region == nullptr);
if (region->get_map() != nullptr) {
-
- if (region->get_map()->get_self() == p_map)
+ if (region->get_map()->get_self() == p_map) {
return; // Pointless
+ }
region->get_map()->remove_region(region);
region->set_map(nullptr);
@@ -305,8 +304,9 @@ COMMAND_2(agent_set_map, RID, p_agent, RID, p_map) {
ERR_FAIL_COND(agent == nullptr);
if (agent->get_map()) {
- if (agent->get_map()->get_self() == p_map)
+ if (agent->get_map()->get_self() == p_map) {
return; // Pointless
+ }
agent->get_map()->remove_agent(agent);
}
diff --git a/modules/gdnavigation/gd_navigation_server.h b/modules/gdnavigation/gd_navigation_server.h
index 01d1a4fba9..e3e02f3d7c 100644
--- a/modules/gdnavigation/gd_navigation_server.h
+++ b/modules/gdnavigation/gd_navigation_server.h
@@ -78,7 +78,7 @@ class GdNavigationServer : public NavigationServer3D {
mutable RID_PtrOwner<NavRegion> region_owner;
mutable RID_PtrOwner<RvoAgent> agent_owner;
- bool active;
+ bool active = true;
Vector<NavMap *> active_maps;
public:
diff --git a/modules/gdnavigation/nav_map.cpp b/modules/gdnavigation/nav_map.cpp
index 7e6a3f7a26..4bea007104 100644
--- a/modules/gdnavigation/nav_map.cpp
+++ b/modules/gdnavigation/nav_map.cpp
@@ -33,6 +33,7 @@
#include "core/os/threaded_array_processor.h"
#include "nav_region.h"
#include "rvo_agent.h"
+
#include <algorithm>
/**
@@ -41,16 +42,6 @@
#define USE_ENTRY_POINT
-NavMap::NavMap() :
- up(0, 1, 0),
- cell_size(0.3),
- edge_connection_margin(5.0),
- regenerate_polygons(true),
- regenerate_links(true),
- agents_dirty(false),
- deltatime(0.0),
- map_update_id(0) {}
-
void NavMap::set_up(Vector3 p_up) {
up = p_up;
regenerate_polygons = true;
@@ -80,7 +71,6 @@ gd::PointKey NavMap::get_point_key(const Vector3 &p_pos) const {
}
Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p_optimize) const {
-
const gd::Polygon *begin_poly = nullptr;
const gd::Polygon *end_poly = nullptr;
Vector3 begin_point;
@@ -94,7 +84,6 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
// For each point cast a face and check the distance between the origin/destination
for (size_t point_id = 2; point_id < p.points.size(); point_id++) {
-
Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
Vector3 spoint = f.get_closest_point_to(p_origin);
float dpoint = spoint.distance_to(p_origin);
@@ -120,7 +109,6 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
}
if (begin_poly == end_poly) {
-
Vector<Vector3> path;
path.resize(2);
path.write[0] = begin_point;
@@ -151,15 +139,15 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
bool is_reachable = true;
while (found_route == false) {
-
{
// Takes the current least_cost_poly neighbors and compute the traveled_distance of each
for (size_t i = 0; i < navigation_polys[least_cost_id].poly->edges.size(); i++) {
gd::NavigationPoly *least_cost_poly = &navigation_polys[least_cost_id];
const gd::Edge &edge = least_cost_poly->poly->edges[i];
- if (!edge.other_polygon)
+ if (!edge.other_polygon) {
continue;
+ }
#ifdef USE_ENTRY_POINT
Vector3 edge_line[2] = {
@@ -181,7 +169,6 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
if (it != navigation_polys.end()) {
// Oh this was visited already, can we win the cost?
if (it->traveled_distance > new_distance) {
-
it->prev_navigation_poly_id = least_cost_id;
it->back_navigation_edge = edge.other_edge;
it->traveled_distance = new_distance;
@@ -283,10 +270,8 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
}
if (found_route) {
-
Vector<Vector3> path;
if (p_optimize) {
-
// String pulling
gd::NavigationPoly *apex_poly = &navigation_polys[least_cost_id];
@@ -300,7 +285,6 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
path.push_back(end_point);
while (p) {
-
Vector3 left;
Vector3 right;
@@ -315,7 +299,6 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
left = p->poly->points[prev].pos;
right = p->poly->points[prev_n].pos;
- //if (CLOCK_TANGENT(apex_point,left,(left+right)*0.5).dot(up) < 0){
if (p->poly->clockwise) {
SWAP(left, right);
}
@@ -329,7 +312,6 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
left_poly = p;
portal_left = left;
} else {
-
clip_path(navigation_polys, path, apex_poly, portal_right, right_poly);
apex_point = portal_right;
@@ -349,7 +331,6 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
right_poly = p;
portal_right = right;
} else {
-
clip_path(navigation_polys, path, apex_poly, portal_left, left_poly);
apex_point = portal_left;
@@ -362,15 +343,17 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
}
}
- if (p->prev_navigation_poly_id != -1)
+ if (p->prev_navigation_poly_id != -1) {
p = &navigation_polys[p->prev_navigation_poly_id];
- else
+ } else {
// The end
p = nullptr;
+ }
}
- if (path[path.size() - 1] != begin_point)
+ if (path[path.size() - 1] != begin_point) {
path.push_back(begin_point);
+ }
path.invert();
@@ -380,7 +363,6 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
// Add mid points
int np_id = least_cost_id;
while (np_id != -1) {
-
#ifdef USE_ENTRY_POINT
Vector3 point = navigation_polys[np_id].entry;
#else
@@ -402,7 +384,6 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
}
Vector3 NavMap::get_closest_point_to_segment(const Vector3 &p_from, const Vector3 &p_to, const bool p_use_collision) const {
-
bool use_collision = p_use_collision;
Vector3 closest_point;
real_t closest_point_d = 1e20;
@@ -413,7 +394,6 @@ Vector3 NavMap::get_closest_point_to_segment(const Vector3 &p_from, const Vector
// For each point cast a face and check the distance to the segment
for (size_t point_id = 2; point_id < p.points.size(); point_id += 1) {
-
const Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
Vector3 inters;
if (f.intersects_segment(p_from, p_to, &inters)) {
@@ -423,7 +403,6 @@ Vector3 NavMap::get_closest_point_to_segment(const Vector3 &p_from, const Vector
use_collision = true;
closest_point_d = d;
} else if (closest_point_d > d) {
-
closest_point = inters;
closest_point_d = d;
}
@@ -431,9 +410,7 @@ Vector3 NavMap::get_closest_point_to_segment(const Vector3 &p_from, const Vector
}
if (use_collision == false) {
-
for (size_t point_id = 0; point_id < p.points.size(); point_id += 1) {
-
Vector3 a, b;
Geometry::get_closest_points_between_segments(
@@ -446,7 +423,6 @@ Vector3 NavMap::get_closest_point_to_segment(const Vector3 &p_from, const Vector
const real_t d = a.distance_to(b);
if (d < closest_point_d) {
-
closest_point_d = d;
closest_point = b;
}
@@ -469,7 +445,6 @@ Vector3 NavMap::get_closest_point(const Vector3 &p_point) const {
// For each point cast a face and check the distance to the point
for (size_t point_id = 2; point_id < p.points.size(); point_id += 1) {
-
const Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
const Vector3 inters = f.get_closest_point_to(p_point);
const real_t d = inters.distance_to(p_point);
@@ -496,7 +471,6 @@ Vector3 NavMap::get_closest_point_normal(const Vector3 &p_point) const {
// For each point cast a face and check the distance to the point
for (size_t point_id = 2; point_id < p.points.size(); point_id += 1) {
-
const Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
const Vector3 inters = f.get_closest_point_to(p_point);
const real_t d = inters.distance_to(p_point);
@@ -524,7 +498,6 @@ RID NavMap::get_closest_point_owner(const Vector3 &p_point) const {
// For each point cast a face and check the distance to the point
for (size_t point_id = 2; point_id < p.points.size(); point_id += 1) {
-
const Face3 f(p.points[point_id - 2].pos, p.points[point_id - 1].pos, p.points[point_id].pos);
const Vector3 inters = f.get_closest_point_to(p_point);
const real_t d = inters.distance_to(p_point);
@@ -588,7 +561,6 @@ void NavMap::remove_agent_as_controlled(RvoAgent *agent) {
}
void NavMap::sync() {
-
if (regenerate_polygons) {
for (size_t r(0); r < regions.size(); r++) {
regions[r]->scratch_polygons();
@@ -741,8 +713,9 @@ void NavMap::sync() {
if (agents_dirty) {
std::vector<RVO::Agent *> raw_agents;
raw_agents.reserve(agents.size());
- for (size_t i(0); i < agents.size(); i++)
+ for (size_t i(0); i < agents.size(); i++) {
raw_agents.push_back(agents[i]->get_agent());
+ }
rvo.buildAgentTree(raw_agents);
}
@@ -776,17 +749,18 @@ void NavMap::dispatch_callbacks() {
void NavMap::clip_path(const std::vector<gd::NavigationPoly> &p_navigation_polys, Vector<Vector3> &path, const gd::NavigationPoly *from_poly, const Vector3 &p_to_point, const gd::NavigationPoly *p_to_poly) const {
Vector3 from = path[path.size() - 1];
- if (from.distance_to(p_to_point) < CMP_EPSILON)
+ if (from.distance_to(p_to_point) < CMP_EPSILON) {
return;
+ }
Plane cut_plane;
cut_plane.normal = (from - p_to_point).cross(up);
- if (cut_plane.normal == Vector3())
+ if (cut_plane.normal == Vector3()) {
return;
+ }
cut_plane.normal.normalize();
cut_plane.d = cut_plane.normal.dot(from);
while (from_poly != p_to_poly) {
-
int back_nav_edge = from_poly->back_navigation_edge;
Vector3 a = from_poly->poly->points[back_nav_edge].pos;
Vector3 b = from_poly->poly->points[(back_nav_edge + 1) % from_poly->poly->points.size()].pos;
@@ -795,7 +769,6 @@ void NavMap::clip_path(const std::vector<gd::NavigationPoly> &p_navigation_polys
from_poly = &p_navigation_polys[from_poly->prev_navigation_poly_id];
if (a.distance_to(b) > CMP_EPSILON) {
-
Vector3 inters;
if (cut_plane.intersects_segment(a, b, &inters)) {
if (inters.distance_to(p_to_point) > CMP_EPSILON && inters.distance_to(path[path.size() - 1]) > CMP_EPSILON) {
diff --git a/modules/gdnavigation/nav_map.h b/modules/gdnavigation/nav_map.h
index 4543f00926..892755f3f9 100644
--- a/modules/gdnavigation/nav_map.h
+++ b/modules/gdnavigation/nav_map.h
@@ -46,19 +46,18 @@ class RvoAgent;
class NavRegion;
class NavMap : public NavRid {
-
/// Map Up
- Vector3 up;
+ Vector3 up = Vector3(0, 1, 0);
/// To find the polygons edges the vertices are displaced in a grid where
/// each cell has the following cell_size.
- real_t cell_size;
+ real_t cell_size = 0.3;
/// This value is used to detect the near edges to connect.
- real_t edge_connection_margin;
+ real_t edge_connection_margin = 5.0;
- bool regenerate_polygons;
- bool regenerate_links;
+ bool regenerate_polygons = true;
+ bool regenerate_links = true;
std::vector<NavRegion *> regions;
@@ -69,7 +68,7 @@ class NavMap : public NavRid {
RVO::KdTree rvo;
/// Is agent array modified?
- bool agents_dirty;
+ bool agents_dirty = false;
/// All the Agents (even the controlled one)
std::vector<RvoAgent *> agents;
@@ -78,13 +77,13 @@ class NavMap : public NavRid {
std::vector<RvoAgent *> controlled_agents;
/// Physics delta time
- real_t deltatime;
+ real_t deltatime = 0.0;
/// Change the id each time the map is updated.
- uint32_t map_update_id;
+ uint32_t map_update_id = 0;
public:
- NavMap();
+ NavMap() {}
void set_up(Vector3 p_up);
Vector3 get_up() const {
diff --git a/modules/gdnavigation/nav_region.cpp b/modules/gdnavigation/nav_region.cpp
index b91376f761..51fba67cc3 100644
--- a/modules/gdnavigation/nav_region.cpp
+++ b/modules/gdnavigation/nav_region.cpp
@@ -36,11 +36,6 @@
@author AndreaCatania
*/
-NavRegion::NavRegion() :
- map(nullptr),
- polygons_dirty(true) {
-}
-
void NavRegion::set_map(NavMap *p_map) {
map = p_map;
polygons_dirty = true;
@@ -75,13 +70,15 @@ void NavRegion::update_polygons() {
return;
}
- if (mesh.is_null())
+ if (mesh.is_null()) {
return;
+ }
Vector<Vector3> vertices = mesh->get_vertices();
int len = vertices.size();
- if (len == 0)
+ if (len == 0) {
return;
+ }
const Vector3 *vertices_r = vertices.ptr();
@@ -89,7 +86,6 @@ void NavRegion::update_polygons() {
// Build
for (size_t i(0); i < polygons.size(); i++) {
-
gd::Polygon &p = polygons[i];
p.owner = this;
@@ -103,7 +99,6 @@ void NavRegion::update_polygons() {
float sum(0);
for (int j(0); j < mesh_poly.size(); j++) {
-
int idx = indices[j];
if (idx < 0 || idx >= len) {
valid = false;
diff --git a/modules/gdnavigation/nav_region.h b/modules/gdnavigation/nav_region.h
index f35ee4bea0..731855bfb5 100644
--- a/modules/gdnavigation/nav_region.h
+++ b/modules/gdnavigation/nav_region.h
@@ -45,17 +45,17 @@ class NavMap;
class NavRegion;
class NavRegion : public NavRid {
- NavMap *map;
+ NavMap *map = nullptr;
Transform transform;
Ref<NavigationMesh> mesh;
- bool polygons_dirty;
+ bool polygons_dirty = true;
/// Cache
std::vector<gd::Polygon> polygons;
public:
- NavRegion();
+ NavRegion() {}
void scratch_polygons() {
polygons_dirty = true;
diff --git a/modules/gdnavigation/nav_utils.h b/modules/gdnavigation/nav_utils.h
index 3401284c31..40e54df553 100644
--- a/modules/gdnavigation/nav_utils.h
+++ b/modules/gdnavigation/nav_utils.h
@@ -32,6 +32,7 @@
#define NAV_UTILS_H
#include "core/math/vector3.h"
+
#include <vector>
/**
@@ -44,7 +45,6 @@ namespace gd {
struct Polygon;
union PointKey {
-
struct {
int64_t x : 21;
int64_t y : 22;
@@ -56,7 +56,6 @@ union PointKey {
};
struct EdgeKey {
-
PointKey a;
PointKey b;
@@ -80,19 +79,15 @@ struct Point {
struct Edge {
/// This edge ID
- int this_edge;
+ int this_edge = -1;
/// Other Polygon
- Polygon *other_polygon;
+ Polygon *other_polygon = nullptr;
/// The other `Polygon` at this edge id has this `Polygon`.
- int other_edge;
+ int other_edge = -1;
- Edge() {
- this_edge = -1;
- other_polygon = nullptr;
- other_edge = -1;
- }
+ Edge() {}
};
struct Polygon {
@@ -112,40 +107,29 @@ struct Polygon {
};
struct Connection {
+ Polygon *A = nullptr;
+ int A_edge = -1;
+ Polygon *B = nullptr;
+ int B_edge = -1;
- Polygon *A;
- int A_edge;
- Polygon *B;
- int B_edge;
-
- Connection() {
- A = nullptr;
- B = nullptr;
- A_edge = -1;
- B_edge = -1;
- }
+ Connection() {}
};
struct NavigationPoly {
- uint32_t self_id;
+ uint32_t self_id = 0;
/// This poly.
const Polygon *poly;
/// The previous navigation poly (id in the `navigation_poly` array).
- int prev_navigation_poly_id;
+ int prev_navigation_poly_id = -1;
/// The edge id in this `Poly` to reach the `prev_navigation_poly_id`.
- uint32_t back_navigation_edge;
+ uint32_t back_navigation_edge = 0;
/// The entry location of this poly.
Vector3 entry;
/// The distance to the destination.
- float traveled_distance;
+ float traveled_distance = 0.0;
NavigationPoly(const Polygon *p_poly) :
- self_id(0),
- poly(p_poly),
- prev_navigation_poly_id(-1),
- back_navigation_edge(0),
- traveled_distance(0.0) {
- }
+ poly(p_poly) {}
bool operator==(const NavigationPoly &other) const {
return this->poly == other.poly;
diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
index abaf73ba6a..5fe1060aae 100644
--- a/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
+++ b/modules/gdnavigation/navigation_mesh_editor_plugin.cpp
@@ -38,7 +38,6 @@
#include "scene/gui/box_container.h"
void NavigationMeshEditor::_node_removed(Node *p_node) {
-
if (p_node == node) {
node = nullptr;
@@ -47,9 +46,7 @@ void NavigationMeshEditor::_node_removed(Node *p_node) {
}
void NavigationMeshEditor::_notification(int p_option) {
-
if (p_option == NOTIFICATION_ENTER_TREE) {
-
button_bake->set_icon(get_theme_icon("Bake", "EditorIcons"));
button_reset->set_icon(get_theme_icon("Reload", "EditorIcons"));
}
@@ -72,9 +69,9 @@ void NavigationMeshEditor::_bake_pressed() {
}
void NavigationMeshEditor::_clear_pressed() {
-
- if (node)
+ if (node) {
NavigationMeshGenerator::get_singleton()->clear(node->get_navigation_mesh());
+ }
button_bake->set_pressed(false);
bake_info->set_text("");
@@ -85,7 +82,6 @@ void NavigationMeshEditor::_clear_pressed() {
}
void NavigationMeshEditor::edit(NavigationRegion3D *p_nav_region) {
-
if (p_nav_region == nullptr || node == p_nav_region) {
return;
}
@@ -97,7 +93,6 @@ void NavigationMeshEditor::_bind_methods() {
}
NavigationMeshEditor::NavigationMeshEditor() {
-
bake_hbox = memnew(HBoxContainer);
button_bake = memnew(ToolButton);
@@ -124,22 +119,18 @@ NavigationMeshEditor::~NavigationMeshEditor() {
}
void NavigationMeshEditorPlugin::edit(Object *p_object) {
-
navigation_mesh_editor->edit(Object::cast_to<NavigationRegion3D>(p_object));
}
bool NavigationMeshEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("NavigationRegion3D");
}
void NavigationMeshEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
navigation_mesh_editor->show();
navigation_mesh_editor->bake_hbox->show();
} else {
-
navigation_mesh_editor->hide();
navigation_mesh_editor->bake_hbox->hide();
navigation_mesh_editor->edit(nullptr);
@@ -147,7 +138,6 @@ void NavigationMeshEditorPlugin::make_visible(bool p_visible) {
}
NavigationMeshEditorPlugin::NavigationMeshEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
navigation_mesh_editor = memnew(NavigationMeshEditor);
editor->get_viewport()->add_child(navigation_mesh_editor);
diff --git a/modules/gdnavigation/navigation_mesh_editor_plugin.h b/modules/gdnavigation/navigation_mesh_editor_plugin.h
index 434981c9e0..da3a981f8c 100644
--- a/modules/gdnavigation/navigation_mesh_editor_plugin.h
+++ b/modules/gdnavigation/navigation_mesh_editor_plugin.h
@@ -67,7 +67,6 @@ public:
};
class NavigationMeshEditorPlugin : public EditorPlugin {
-
GDCLASS(NavigationMeshEditorPlugin, EditorPlugin);
NavigationMeshEditor *navigation_mesh_editor;
diff --git a/modules/gdnavigation/navigation_mesh_generator.cpp b/modules/gdnavigation/navigation_mesh_generator.cpp
index acb4f0461f..7dc08fbf29 100644
--- a/modules/gdnavigation/navigation_mesh_generator.cpp
+++ b/modules/gdnavigation/navigation_mesh_generator.cpp
@@ -74,8 +74,9 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
current_vertex_count = p_verticies.size() / 3;
- if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
+ if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
continue;
+ }
int index_count = 0;
if (p_mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) {
@@ -94,7 +95,6 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
const Vector3 *vr = mesh_vertices.ptr();
if (p_mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_INDEX) {
-
Vector<int> mesh_indices = a[Mesh::ARRAY_INDEX];
const int *ir = mesh_indices.ptr();
@@ -139,9 +139,7 @@ void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, cons
}
void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, int p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
-
if (Object::cast_to<MeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
-
MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(p_node);
Ref<Mesh> mesh = mesh_instance->get_mesh();
if (mesh.is_valid()) {
@@ -151,7 +149,6 @@ void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform,
#ifdef MODULE_CSG_ENABLED
if (Object::cast_to<CSGShape3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
-
CSGShape3D *csg_shape = Object::cast_to<CSGShape3D>(p_node);
Array meshes = csg_shape->get_meshes();
if (!meshes.empty()) {
@@ -167,7 +164,6 @@ void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform,
StaticBody3D *static_body = Object::cast_to<StaticBody3D>(p_node);
if (static_body->get_collision_layer() & p_collision_mask) {
-
for (int i = 0; i < p_node->get_child_count(); ++i) {
Node *child = p_node->get_child(i);
if (Object::cast_to<CollisionShape3D>(child)) {
@@ -278,7 +274,6 @@ void NavigationMeshGenerator::_parse_geometry(Transform p_accumulated_transform,
}
void NavigationMeshGenerator::_convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh) {
-
Vector<Vector3> nav_vertices;
for (int i = 0; i < p_detail_mesh->nverts; i++) {
@@ -320,8 +315,9 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh(
rcContext ctx;
#ifdef TOOLS_ENABLED
- if (ep)
+ if (ep) {
ep->step(TTR("Setting up Configuration..."), 1);
+ }
#endif
const float *verts = vertices.ptr();
@@ -357,14 +353,16 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh(
cfg.bmax[2] = bmax[2];
#ifdef TOOLS_ENABLED
- if (ep)
+ if (ep) {
ep->step(TTR("Calculating grid size..."), 2);
+ }
#endif
rcCalcGridSize(cfg.bmin, cfg.bmax, cfg.cs, &cfg.width, &cfg.height);
#ifdef TOOLS_ENABLED
- if (ep)
+ if (ep) {
ep->step(TTR("Creating heightfield..."), 3);
+ }
#endif
hf = rcAllocHeightfield();
@@ -372,8 +370,9 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh(
ERR_FAIL_COND(!rcCreateHeightfield(&ctx, *hf, cfg.width, cfg.height, cfg.bmin, cfg.bmax, cfg.cs, cfg.ch));
#ifdef TOOLS_ENABLED
- if (ep)
+ if (ep) {
ep->step(TTR("Marking walkable triangles..."), 4);
+ }
#endif
{
Vector<unsigned char> tri_areas;
@@ -387,16 +386,20 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh(
ERR_FAIL_COND(!rcRasterizeTriangles(&ctx, verts, nverts, tris, tri_areas.ptr(), ntris, *hf, cfg.walkableClimb));
}
- if (p_nav_mesh->get_filter_low_hanging_obstacles())
+ if (p_nav_mesh->get_filter_low_hanging_obstacles()) {
rcFilterLowHangingWalkableObstacles(&ctx, cfg.walkableClimb, *hf);
- if (p_nav_mesh->get_filter_ledge_spans())
+ }
+ if (p_nav_mesh->get_filter_ledge_spans()) {
rcFilterLedgeSpans(&ctx, cfg.walkableHeight, cfg.walkableClimb, *hf);
- if (p_nav_mesh->get_filter_walkable_low_height_spans())
+ }
+ if (p_nav_mesh->get_filter_walkable_low_height_spans()) {
rcFilterWalkableLowHeightSpans(&ctx, cfg.walkableHeight, *hf);
+ }
#ifdef TOOLS_ENABLED
- if (ep)
+ if (ep) {
ep->step(TTR("Constructing compact heightfield..."), 5);
+ }
#endif
chf = rcAllocCompactHeightfield();
@@ -408,15 +411,17 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh(
hf = nullptr;
#ifdef TOOLS_ENABLED
- if (ep)
+ if (ep) {
ep->step(TTR("Eroding walkable area..."), 6);
+ }
#endif
ERR_FAIL_COND(!rcErodeWalkableArea(&ctx, cfg.walkableRadius, *chf));
#ifdef TOOLS_ENABLED
- if (ep)
+ if (ep) {
ep->step(TTR("Partitioning..."), 7);
+ }
#endif
if (p_nav_mesh->get_sample_partition_type() == NavigationMesh::SAMPLE_PARTITION_WATERSHED) {
@@ -429,8 +434,9 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh(
}
#ifdef TOOLS_ENABLED
- if (ep)
+ if (ep) {
ep->step(TTR("Creating contours..."), 8);
+ }
#endif
cset = rcAllocContourSet();
@@ -439,8 +445,9 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh(
ERR_FAIL_COND(!rcBuildContours(&ctx, *chf, cfg.maxSimplificationError, cfg.maxEdgeLen, *cset));
#ifdef TOOLS_ENABLED
- if (ep)
+ if (ep) {
ep->step(TTR("Creating polymesh..."), 9);
+ }
#endif
poly_mesh = rcAllocPolyMesh();
@@ -457,8 +464,9 @@ void NavigationMeshGenerator::_build_recast_navigation_mesh(
cset = nullptr;
#ifdef TOOLS_ENABLED
- if (ep)
+ if (ep) {
ep->step(TTR("Converting to native navigation mesh..."), 10);
+ }
#endif
_convert_detail_mesh_to_native_navigation_mesh(detail_mesh, p_nav_mesh);
@@ -481,7 +489,6 @@ NavigationMeshGenerator::~NavigationMeshGenerator() {
}
void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node) {
-
ERR_FAIL_COND(!p_nav_mesh.is_valid());
#ifdef TOOLS_ENABLED
@@ -490,8 +497,9 @@ void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node)
ep = memnew(EditorProgress("bake", TTR("Navigation Mesh Generator Setup:"), 11));
}
- if (ep)
+ if (ep) {
ep->step(TTR("Parsing Geometry..."), 0);
+ }
#endif
Vector<float> vertices;
@@ -514,7 +522,6 @@ void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node)
}
if (vertices.size() > 0 && indices.size() > 0) {
-
rcHeightfield *hf = nullptr;
rcCompactHeightfield *chf = nullptr;
rcContourSet *cset = nullptr;
@@ -551,11 +558,13 @@ void NavigationMeshGenerator::bake(Ref<NavigationMesh> p_nav_mesh, Node *p_node)
}
#ifdef TOOLS_ENABLED
- if (ep)
+ if (ep) {
ep->step(TTR("Done!"), 11);
+ }
- if (ep)
+ if (ep) {
memdelete(ep);
+ }
#endif
}
diff --git a/modules/gdnavigation/rvo_agent.cpp b/modules/gdnavigation/rvo_agent.cpp
index 3c39f02c26..1e1bdbd07d 100644
--- a/modules/gdnavigation/rvo_agent.cpp
+++ b/modules/gdnavigation/rvo_agent.cpp
@@ -36,8 +36,7 @@
@author AndreaCatania
*/
-RvoAgent::RvoAgent() :
- map(nullptr) {
+RvoAgent::RvoAgent() {
callback.id = ObjectID();
}
diff --git a/modules/gdnavigation/rvo_agent.h b/modules/gdnavigation/rvo_agent.h
index 914cbaa7d9..f5c579ba84 100644
--- a/modules/gdnavigation/rvo_agent.h
+++ b/modules/gdnavigation/rvo_agent.h
@@ -49,7 +49,7 @@ class RvoAgent : public NavRid {
Variant new_velocity;
};
- NavMap *map;
+ NavMap *map = nullptr;
RVO::Agent agent;
AvoidanceComputedCallback callback;
uint32_t map_update_id;
diff --git a/modules/gdscript/config.py b/modules/gdscript/config.py
index 185a10bcb2..6fc227e7f5 100644
--- a/modules/gdscript/config.py
+++ b/modules/gdscript/config.py
@@ -11,7 +11,6 @@ def get_doc_classes():
"@GDScript",
"GDScript",
"GDScriptFunctionState",
- "GDScriptNativeClass",
]
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 9324691df5..be159b6407 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -568,7 +568,7 @@
<description>
Linearly interpolates between two values by a normalized value. This is the opposite of [method inverse_lerp].
If the [code]from[/code] and [code]to[/code] arguments are of type [int] or [float], the return value is a [float].
- If both are of the same vector type ([Vector2], [Vector3] or [Color]), the return value will be of the same type ([code]lerp[/code] then calls the vector type's [code]linear_interpolate[/code] method).
+ If both are of the same vector type ([Vector2], [Vector3] or [Color]), the return value will be of the same type ([code]lerp[/code] then calls the vector type's [code]lerp[/code] method).
[codeblock]
lerp(0, 4, 0.75) # Returns 3.0
lerp(Vector2(1, 5), Vector2(3, 2), 0.5) # Returns Vector2(2, 3.5)
diff --git a/modules/gdscript/doc_classes/GDScriptNativeClass.xml b/modules/gdscript/doc_classes/GDScriptNativeClass.xml
deleted file mode 100644
index 0a8982de8e..0000000000
--- a/modules/gdscript/doc_classes/GDScriptNativeClass.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="GDScriptNativeClass" inherits="Reference" version="4.0">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <tutorials>
- </tutorials>
- <methods>
- <method name="new">
- <return type="Variant">
- </return>
- <description>
- </description>
- </method>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 0aca4dbc5e..d0f27b632b 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -34,17 +34,14 @@
#include "scene/gui/text_edit.h"
inline bool _is_symbol(CharType c) {
-
return is_symbol(c);
}
static bool _is_text_char(CharType c) {
-
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
static bool _is_char(CharType c) {
-
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
}
@@ -180,10 +177,10 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_
}
if (in_region == -1 && !in_keyword && is_char && !prev_is_char) {
-
int to = j;
- while (to < str.length() && _is_text_char(str[to]))
+ while (to < str.length() && _is_text_char(str[to])) {
to++;
+ }
String word = str.substr(j, to - j);
Color col = Color();
@@ -208,7 +205,6 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_
}
if (!in_function_name && in_word && !in_keyword) {
-
int k = j;
while (k < str.length() && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') {
k++;
@@ -238,7 +234,6 @@ Map<int, TextEdit::HighlighterInfo> GDScriptSyntaxHighlighter::_get_line_syntax_
}
if (is_symbol) {
-
if (in_function_name) {
in_function_args = true;
}
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index 9a4fa5cc86..632407c61f 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -44,12 +44,10 @@
///////////////////////////
GDScriptNativeClass::GDScriptNativeClass(const StringName &p_name) {
-
name = p_name;
}
bool GDScriptNativeClass::_get(const StringName &p_name, Variant &r_ret) const {
-
bool ok;
int v = ClassDB::get_integer_constant(name, p_name, &ok);
@@ -62,12 +60,10 @@ bool GDScriptNativeClass::_get(const StringName &p_name, Variant &r_ret) const {
}
void GDScriptNativeClass::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("new"), &GDScriptNativeClass::_new);
}
Variant GDScriptNativeClass::_new() {
-
Object *o = instance();
ERR_FAIL_COND_V_MSG(!o, Variant(), "Class type: '" + String(name) + "' is not instantiable.");
@@ -80,12 +76,10 @@ Variant GDScriptNativeClass::_new() {
}
Object *GDScriptNativeClass::instance() {
-
return ClassDB::instance(name);
}
GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) {
-
/* STEP 1, CREATE */
GDScriptInstance *instance = memnew(GDScriptInstance);
@@ -103,15 +97,14 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
instance->owner->set_script_instance(instance);
/* STEP 2, INITIALIZE AND CONSTRUCT */
-
{
MutexLock lock(GDScriptLanguage::singleton->lock);
-
instances.insert(instance->owner);
}
-
+ if (p_argcount < 0) {
+ return instance;
+ }
initializer->call(instance, p_args, p_argcount, r_error);
-
if (r_error.error != Callable::CallError::CALL_OK) {
instance->script = Ref<GDScript>();
instance->owner->set_script_instance(nullptr);
@@ -119,16 +112,13 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco
MutexLock lock(GDScriptLanguage::singleton->lock);
instances.erase(p_owner);
}
-
- ERR_FAIL_COND_V(r_error.error != Callable::CallError::CALL_OK, nullptr); //error constructing
+ ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance.");
}
-
//@TODO make thread safe
return instance;
}
Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
/* STEP 1, CREATE */
if (!valid) {
@@ -174,7 +164,6 @@ Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallErr
}
bool GDScript::can_instance() const {
-
#ifdef TOOLS_ENABLED
return valid && (tool || ScriptServer::is_scripting_enabled());
#else
@@ -183,7 +172,6 @@ bool GDScript::can_instance() const {
}
Ref<Script> GDScript::get_base_script() const {
-
if (_base) {
return Ref<GDScript>(_base);
} else {
@@ -192,16 +180,16 @@ Ref<Script> GDScript::get_base_script() const {
}
StringName GDScript::get_instance_base_type() const {
-
- if (native.is_valid())
+ if (native.is_valid()) {
return native->get_name();
- if (base.is_valid() && base->is_valid())
+ }
+ if (base.is_valid() && base->is_valid()) {
return base->get_instance_base_type();
+ }
return StringName();
}
struct _GDScriptMemberSort {
-
int index;
StringName name;
_FORCE_INLINE_ bool operator<(const _GDScriptMemberSort &p_member) const { return index < p_member.index; }
@@ -210,13 +198,11 @@ struct _GDScriptMemberSort {
#ifdef TOOLS_ENABLED
void GDScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {
-
placeholders.erase(p_placeholder);
}
#endif
void GDScript::get_script_method_list(List<MethodInfo> *p_list) const {
-
const GDScript *current = this;
while (current) {
for (const Map<StringName, GDScriptFunction *>::Element *E = current->member_functions.front(); E; E = E->next()) {
@@ -236,15 +222,12 @@ void GDScript::get_script_method_list(List<MethodInfo> *p_list) const {
}
void GDScript::get_script_property_list(List<PropertyInfo> *p_list) const {
-
const GDScript *sptr = this;
List<PropertyInfo> props;
while (sptr) {
-
Vector<_GDScriptMemberSort> msort;
for (Map<StringName, PropertyInfo>::Element *E = sptr->member_info.front(); E; E = E->next()) {
-
_GDScriptMemberSort ms;
ERR_CONTINUE(!sptr->member_indices.has(E->key()));
ms.index = sptr->member_indices[E->key()].index;
@@ -255,7 +238,6 @@ void GDScript::get_script_property_list(List<PropertyInfo> *p_list) const {
msort.sort();
msort.invert();
for (int i = 0; i < msort.size(); i++) {
-
props.push_front(sptr->member_info[msort[i].name]);
}
@@ -268,15 +250,14 @@ void GDScript::get_script_property_list(List<PropertyInfo> *p_list) const {
}
bool GDScript::has_method(const StringName &p_method) const {
-
return member_functions.has(p_method);
}
MethodInfo GDScript::get_method_info(const StringName &p_method) const {
-
const Map<StringName, GDScriptFunction *>::Element *E = member_functions.find(p_method);
- if (!E)
+ if (!E) {
return MethodInfo();
+ }
GDScriptFunction *func = E->get();
MethodInfo mi;
@@ -290,7 +271,6 @@ MethodInfo GDScript::get_method_info(const StringName &p_method) const {
}
bool GDScript::get_property_default_value(const StringName &p_property, Variant &r_value) const {
-
#ifdef TOOLS_ENABLED
const Map<StringName, Variant>::Element *E = member_default_values_cache.find(p_property);
@@ -307,14 +287,13 @@ bool GDScript::get_property_default_value(const StringName &p_property, Variant
}
ScriptInstance *GDScript::instance_create(Object *p_this) {
-
GDScript *top = this;
- while (top->_base)
+ while (top->_base) {
top = top->_base;
+ }
if (top->native.is_valid()) {
if (!ClassDB::is_parent_class(p_this->get_class_name(), top->native->get_name())) {
-
if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), 1, "Script inherits from native type '" + String(top->native->get_name()) + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'");
}
@@ -338,24 +317,23 @@ PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this)
}
bool GDScript::instance_has(const Object *p_this) const {
-
MutexLock lock(GDScriptLanguage::singleton->lock);
return instances.has((Object *)p_this);
}
bool GDScript::has_source_code() const {
-
return source != "";
}
-String GDScript::get_source_code() const {
+String GDScript::get_source_code() const {
return source;
}
-void GDScript::set_source_code(const String &p_code) {
- if (source == p_code)
+void GDScript::set_source_code(const String &p_code) {
+ if (source == p_code) {
return;
+ }
source = p_code;
#ifdef TOOLS_ENABLED
source_changed_cache = true;
@@ -364,7 +342,6 @@ void GDScript::set_source_code(const String &p_code) {
#ifdef TOOLS_ENABLED
void GDScript::_update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames) {
-
if (base_cache.is_valid()) {
base_cache->_update_exports_values(values, propnames);
}
@@ -379,10 +356,15 @@ void GDScript::_update_exports_values(Map<StringName, Variant> &values, List<Pro
}
#endif
-bool GDScript::_update_exports() {
-
+bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) {
#ifdef TOOLS_ENABLED
+ static Vector<GDScript *> base_caches;
+ if (!p_recursive_call) {
+ base_caches.clear();
+ }
+ base_caches.append(this);
+
bool changed = false;
if (source_changed_cache) {
@@ -391,17 +373,18 @@ bool GDScript::_update_exports() {
String basedir = path;
- if (basedir == "")
+ if (basedir == "") {
basedir = get_path();
+ }
- if (basedir != "")
+ if (basedir != "") {
basedir = basedir.get_base_dir();
+ }
GDScriptParser parser;
Error err = parser.parse(source, basedir, true, path);
if (err == OK) {
-
const GDScriptParser::Node *root = parser.get_parse_tree();
ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, false);
@@ -417,10 +400,8 @@ bool GDScript::_update_exports() {
if (String(c->extends_file) != "" && String(c->extends_file) != get_path()) {
path = c->extends_file;
if (path.is_rel_path()) {
-
String base = get_path();
if (base == "" || base.is_rel_path()) {
-
ERR_PRINT(("Could not resolve relative path for parent class: " + path).utf8().get_data());
} else {
path = base.get_base_dir().plus_file(path);
@@ -429,17 +410,16 @@ bool GDScript::_update_exports() {
} else if (c->extends_class.size() != 0) {
String base = c->extends_class[0];
- if (ScriptServer::is_global_class(base))
+ if (ScriptServer::is_global_class(base)) {
path = ScriptServer::get_global_class_path(base);
+ }
}
if (path != "") {
if (path != get_path()) {
-
Ref<GDScript> bf = ResourceLoader::load(path);
if (bf.is_valid()) {
-
base_cache = bf;
bf->inheriters_cache.insert(get_instance_id());
}
@@ -453,8 +433,9 @@ bool GDScript::_update_exports() {
member_default_values_cache.clear();
for (int i = 0; i < c->variables.size(); i++) {
- if (c->variables[i]._export.type == Variant::NIL)
+ if (c->variables[i]._export.type == Variant::NIL) {
continue;
+ }
members_cache.push_back(c->variables[i]._export);
member_default_values_cache[c->variables[i].identifier] = c->variables[i].default_value;
@@ -476,7 +457,24 @@ bool GDScript::_update_exports() {
placeholder_fallback_enabled = false;
if (base_cache.is_valid() && base_cache->is_valid()) {
- if (base_cache->_update_exports()) {
+ for (int i = 0; i < base_caches.size(); i++) {
+ if (base_caches[i] == base_cache.ptr()) {
+ if (r_err) {
+ *r_err = true;
+ }
+ valid = false; // to show error in the editor
+ base_cache->valid = false;
+ base_cache->inheriters_cache.clear(); // to prevent future stackoverflows
+ base_cache.unref();
+ base.unref();
+ _base = nullptr;
+ ERR_FAIL_V_MSG(false, "Cyclic inheritance in script class.");
+ }
+ }
+ if (base_cache->_update_exports(r_err, true)) {
+ if (r_err && *r_err) {
+ return false;
+ }
changed = true;
}
}
@@ -501,18 +499,22 @@ bool GDScript::_update_exports() {
}
void GDScript::update_exports() {
-
#ifdef TOOLS_ENABLED
- _update_exports();
+ bool cyclic_error = false;
+ _update_exports(&cyclic_error);
+ if (cyclic_error) {
+ return;
+ }
Set<ObjectID> copy = inheriters_cache; //might get modified
for (Set<ObjectID>::Element *E = copy.front(); E; E = E->next()) {
Object *id = ObjectDB::get_instance(E->get());
GDScript *s = Object::cast_to<GDScript>(id);
- if (!s)
+ if (!s) {
continue;
+ }
s->update_exports();
}
@@ -520,16 +522,13 @@ void GDScript::update_exports() {
}
void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) {
-
p_sc->path = p_path;
for (Map<StringName, Ref<GDScript>>::Element *E = p_sc->subclasses.front(); E; E = E->next()) {
-
_set_subclass_path(E->get(), p_path);
}
}
Error GDScript::reload(bool p_keep_state) {
-
bool has_instances;
{
MutexLock lock(GDScriptLanguage::singleton->lock);
@@ -541,11 +540,13 @@ Error GDScript::reload(bool p_keep_state) {
String basedir = path;
- if (basedir == "")
+ if (basedir == "") {
basedir = get_path();
+ }
- if (basedir != "")
+ if (basedir != "") {
basedir = basedir.get_base_dir();
+ }
if (source.find("%BASE%") != -1) {
//loading a template, don't parse
@@ -569,7 +570,6 @@ Error GDScript::reload(bool p_keep_state) {
err = compiler.compile(&parser, this, p_keep_state);
if (err) {
-
if (can_run) {
if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->debug_break_parse(get_path(), compiler.get_error_line(), "Parser Error: " + compiler.get_error());
@@ -593,7 +593,6 @@ Error GDScript::reload(bool p_keep_state) {
valid = true;
for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) {
-
_set_subclass_path(E->get(), path);
}
@@ -603,12 +602,10 @@ Error GDScript::reload(bool p_keep_state) {
}
ScriptLanguage *GDScript::get_language() const {
-
return GDScriptLanguage::get_singleton();
}
void GDScript::get_constants(Map<StringName, Variant> *p_constants) {
-
if (p_constants) {
for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) {
(*p_constants)[E->key()] = E->value();
@@ -638,12 +635,16 @@ uint16_t GDScript::get_rpc_method_id(const StringName &p_method) const {
}
StringName GDScript::get_rpc_method(const uint16_t p_rpc_method_id) const {
- ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), StringName());
+ if (p_rpc_method_id >= rpc_functions.size()) {
+ return StringName();
+ }
return rpc_functions[p_rpc_method_id].name;
}
MultiplayerAPI::RPCMode GDScript::get_rpc_mode_by_id(const uint16_t p_rpc_method_id) const {
- ERR_FAIL_COND_V(p_rpc_method_id >= rpc_functions.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ if (p_rpc_method_id >= rpc_functions.size()) {
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
return rpc_functions[p_rpc_method_id].mode;
}
@@ -665,12 +666,16 @@ uint16_t GDScript::get_rset_property_id(const StringName &p_variable) const {
}
StringName GDScript::get_rset_property(const uint16_t p_rset_member_id) const {
- ERR_FAIL_COND_V(p_rset_member_id >= rpc_variables.size(), StringName());
+ if (p_rset_member_id >= rpc_variables.size()) {
+ return StringName();
+ }
return rpc_variables[p_rset_member_id].name;
}
MultiplayerAPI::RPCMode GDScript::get_rset_mode_by_id(const uint16_t p_rset_member_id) const {
- ERR_FAIL_COND_V(p_rset_member_id >= rpc_variables.size(), MultiplayerAPI::RPC_MODE_DISABLED);
+ if (p_rset_member_id >= rpc_variables.size()) {
+ return MultiplayerAPI::RPC_MODE_DISABLED;
+ }
return rpc_variables[p_rset_member_id].mode;
}
@@ -679,13 +684,10 @@ MultiplayerAPI::RPCMode GDScript::get_rset_mode(const StringName &p_variable) co
}
Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
GDScript *top = this;
while (top) {
-
Map<StringName, GDScriptFunction *>::Element *E = top->member_functions.find(p_method);
if (E) {
-
ERR_FAIL_COND_V_MSG(!E->get()->is_static(), Variant(), "Can't call non-static function '" + String(p_method) + "' in script.");
return E->get()->call(nullptr, p_args, p_argcount, r_error);
@@ -699,16 +701,12 @@ Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p
}
bool GDScript::_get(const StringName &p_name, Variant &r_ret) const {
-
{
-
const GDScript *top = this;
while (top) {
-
{
const Map<StringName, Variant>::Element *E = top->constants.find(p_name);
if (E) {
-
r_ret = E->get();
return true;
}
@@ -717,7 +715,6 @@ bool GDScript::_get(const StringName &p_name, Variant &r_ret) const {
{
const Map<StringName, Ref<GDScript>>::Element *E = subclasses.find(p_name);
if (E) {
-
r_ret = E->get();
return true;
}
@@ -726,7 +723,6 @@ bool GDScript::_get(const StringName &p_name, Variant &r_ret) const {
}
if (p_name == GDScriptLanguage::get_singleton()->strings._script_source) {
-
r_ret = get_source_code();
return true;
}
@@ -734,42 +730,37 @@ bool GDScript::_get(const StringName &p_name, Variant &r_ret) const {
return false;
}
-bool GDScript::_set(const StringName &p_name, const Variant &p_value) {
+bool GDScript::_set(const StringName &p_name, const Variant &p_value) {
if (p_name == GDScriptLanguage::get_singleton()->strings._script_source) {
-
set_source_code(p_value);
reload();
- } else
+ } else {
return false;
+ }
return true;
}
void GDScript::_get_property_list(List<PropertyInfo> *p_properties) const {
-
p_properties->push_back(PropertyInfo(Variant::STRING, "script/source", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
void GDScript::_bind_methods() {
-
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &GDScript::_new, MethodInfo("new"));
ClassDB::bind_method(D_METHOD("get_as_byte_code"), &GDScript::get_as_byte_code);
}
Vector<uint8_t> GDScript::get_as_byte_code() const {
-
GDScriptTokenizerBuffer tokenizer;
return tokenizer.parse_code_string(source);
};
Error GDScript::load_byte_code(const String &p_path) {
-
Vector<uint8_t> bytecode;
if (p_path.ends_with("gde")) {
-
FileAccess *fa = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V(!fa, ERR_CANT_OPEN);
@@ -798,7 +789,6 @@ Error GDScript::load_byte_code(const String &p_path) {
memdelete(fae);
} else {
-
bytecode = FileAccess::get_file_as_array(p_path);
}
@@ -807,11 +797,13 @@ Error GDScript::load_byte_code(const String &p_path) {
String basedir = path;
- if (basedir == "")
+ if (basedir == "") {
basedir = get_path();
+ }
- if (basedir != "")
+ if (basedir != "") {
basedir = basedir.get_base_dir();
+ }
valid = false;
GDScriptParser parser;
@@ -832,7 +824,6 @@ Error GDScript::load_byte_code(const String &p_path) {
valid = true;
for (Map<StringName, Ref<GDScript>>::Element *E = subclasses.front(); E; E = E->next()) {
-
_set_subclass_path(E->get(), path);
}
@@ -842,12 +833,10 @@ Error GDScript::load_byte_code(const String &p_path) {
}
Error GDScript::load_source_code(const String &p_path) {
-
Vector<uint8_t> sourcef;
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
if (err) {
-
ERR_FAIL_COND_V(err, err);
}
@@ -862,7 +851,6 @@ Error GDScript::load_source_code(const String &p_path) {
String s;
if (s.parse_utf8((const char *)w)) {
-
ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode.");
}
@@ -875,29 +863,45 @@ Error GDScript::load_source_code(const String &p_path) {
}
const Map<StringName, GDScriptFunction *> &GDScript::debug_get_member_functions() const {
-
return member_functions;
}
StringName GDScript::debug_get_member_by_index(int p_idx) const {
-
for (const Map<StringName, MemberInfo>::Element *E = member_indices.front(); E; E = E->next()) {
-
- if (E->get().index == p_idx)
+ if (E->get().index == p_idx) {
return E->key();
+ }
}
return "<error>";
}
Ref<GDScript> GDScript::get_base() const {
-
return base;
}
+bool GDScript::inherits_script(const Ref<Script> &p_script) const {
+ Ref<GDScript> gd = p_script;
+ if (gd.is_null()) {
+ return false;
+ }
+
+ const GDScript *s = this;
+
+ while (s) {
+ if (s == p_script.ptr()) {
+ return true;
+ }
+ s = s->_base;
+ }
+
+ return false;
+}
+
bool GDScript::has_script_signal(const StringName &p_signal) const {
- if (_signals.has(p_signal))
+ if (_signals.has(p_signal)) {
return true;
+ }
if (base.is_valid()) {
return base->has_script_signal(p_signal);
}
@@ -908,10 +912,9 @@ bool GDScript::has_script_signal(const StringName &p_signal) const {
#endif
return false;
}
-void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
+void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
for (const Map<StringName, Vector<StringName>>::Element *E = _signals.front(); E; E = E->next()) {
-
MethodInfo mi;
mi.name = E->key();
for (int i = 0; i < E->get().size(); i++) {
@@ -935,7 +938,6 @@ void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
GDScript::GDScript() :
script_list(this) {
-
valid = false;
subclass_count = 0;
initializer = nullptr;
@@ -980,8 +982,9 @@ void GDScript::_save_orphaned_subclasses() {
for (int i = 0; i < weak_subclasses.size(); i++) {
ClassRefWithName subclass = weak_subclasses[i];
Object *obj = ObjectDB::get_instance(subclass.id);
- if (!obj)
+ if (!obj) {
continue;
+ }
// subclass is not released
GDScriptLanguage::get_singleton()->add_orphan_subclass(subclass.fully_qualified_name, subclass.id);
}
@@ -1022,13 +1025,15 @@ void GDScript::_init_rpc_methods_properties() {
}
}
- if (cscript != this)
+ if (cscript != this) {
sub_E = sub_E->next();
+ }
- if (sub_E)
+ if (sub_E) {
cscript = sub_E->get().ptr();
- else
+ } else {
cscript = nullptr;
+ }
}
// Sort so we are 100% that they are always the same.
@@ -1037,6 +1042,15 @@ void GDScript::_init_rpc_methods_properties() {
}
GDScript::~GDScript() {
+ {
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
+
+ while (SelfList<GDScriptFunctionState> *E = pending_func_states.first()) {
+ E->self()->_clear_stack();
+ pending_func_states.remove(E);
+ }
+ }
+
for (Map<StringName, GDScriptFunction *>::Element *E = member_functions.front(); E; E = E->next()) {
memdelete(E->get());
}
@@ -1057,7 +1071,6 @@ GDScript::~GDScript() {
//////////////////////////////
bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
-
//member
{
const Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name);
@@ -1092,17 +1105,16 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
GDScript *sptr = script.ptr();
while (sptr) {
-
Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._set);
if (E) {
-
Variant name = p_name;
const Variant *args[2] = { &name, &p_value };
Callable::CallError err;
Variant ret = E->get()->call(this, (const Variant **)args, 2, err);
- if (err.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool())
+ if (err.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool()) {
return true;
+ }
}
sptr = sptr->_base;
}
@@ -1111,10 +1123,8 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
}
bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
-
const GDScript *sptr = script.ptr();
while (sptr) {
-
{
const Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name);
if (E) {
@@ -1131,7 +1141,6 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
}
{
-
const GDScript *sl = sptr;
while (sl) {
const Map<StringName, Variant>::Element *E = sl->constants.find(p_name);
@@ -1146,7 +1155,6 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
{
const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get);
if (E) {
-
Variant name = p_name;
const Variant *args[1] = { &name };
@@ -1165,20 +1173,20 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
}
Variant::Type GDScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
-
const GDScript *sptr = script.ptr();
while (sptr) {
-
if (sptr->member_info.has(p_name)) {
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = true;
+ }
return sptr->member_info[p_name].type;
}
sptr = sptr->_base;
}
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = false;
+ }
return Variant::NIL;
}
@@ -1189,19 +1197,15 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
List<PropertyInfo> props;
while (sptr) {
-
const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get_property_list);
if (E) {
-
Callable::CallError err;
Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), nullptr, 0, err);
if (err.error == Callable::CallError::CALL_OK) {
-
ERR_FAIL_COND_MSG(ret.get_type() != Variant::ARRAY, "Wrong type for _get_property_list, must be an array of dictionaries.");
Array arr = ret;
for (int i = 0; i < arr.size(); i++) {
-
Dictionary d = arr[i];
ERR_CONTINUE(!d.has("name"));
ERR_CONTINUE(!d.has("type"));
@@ -1210,12 +1214,15 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
ERR_CONTINUE(pinfo.type < 0 || pinfo.type >= Variant::VARIANT_MAX);
pinfo.name = d["name"];
ERR_CONTINUE(pinfo.name == "");
- if (d.has("hint"))
+ if (d.has("hint")) {
pinfo.hint = PropertyHint(d["hint"].operator int());
- if (d.has("hint_string"))
+ }
+ if (d.has("hint_string")) {
pinfo.hint_string = d["hint_string"];
- if (d.has("usage"))
+ }
+ if (d.has("usage")) {
pinfo.usage = d["usage"];
+ }
props.push_back(pinfo);
}
@@ -1226,7 +1233,6 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
Vector<_GDScriptMemberSort> msort;
for (Map<StringName, PropertyInfo>::Element *F = sptr->member_info.front(); F; F = F->next()) {
-
_GDScriptMemberSort ms;
ERR_CONTINUE(!sptr->member_indices.has(F->key()));
ms.index = sptr->member_indices[F->key()].index;
@@ -1237,7 +1243,6 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
msort.sort();
msort.invert();
for (int i = 0; i < msort.size(); i++) {
-
props.push_front(sptr->member_info[msort[i].name]);
}
@@ -1245,23 +1250,20 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
}
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
p_properties->push_back(E->get());
}
}
void GDScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
-
const GDScript *sptr = script.ptr();
while (sptr) {
-
for (Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.front(); E; E = E->next()) {
-
MethodInfo mi;
mi.name = E->key();
mi.flags |= METHOD_FLAG_FROM_SCRIPT;
- for (int i = 0; i < E->get()->get_argument_count(); i++)
+ for (int i = 0; i < E->get()->get_argument_count(); i++) {
mi.arguments.push_back(PropertyInfo(Variant::NIL, "arg" + itos(i)));
+ }
p_list->push_back(mi);
}
sptr = sptr->_base;
@@ -1269,19 +1271,19 @@ void GDScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
}
bool GDScriptInstance::has_method(const StringName &p_method) const {
-
const GDScript *sptr = script.ptr();
while (sptr) {
const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method);
- if (E)
+ if (E) {
return true;
+ }
sptr = sptr->_base;
}
return false;
}
-Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
GDScript *sptr = script.ptr();
while (sptr) {
Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method);
@@ -1295,7 +1297,6 @@ Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_arg
}
void GDScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) {
-
GDScript *sptr = script.ptr();
Callable::CallError ce;
@@ -1309,9 +1310,9 @@ void GDScriptInstance::call_multilevel(const StringName &p_method, const Variant
}
void GDScriptInstance::_ml_call_reversed(GDScript *sptr, const StringName &p_method, const Variant **p_args, int p_argcount) {
-
- if (sptr->_base)
+ if (sptr->_base) {
_ml_call_reversed(sptr->_base, p_method, p_args, p_argcount);
+ }
Callable::CallError ce;
@@ -1322,14 +1323,12 @@ void GDScriptInstance::_ml_call_reversed(GDScript *sptr, const StringName &p_met
}
void GDScriptInstance::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) {
-
if (script.ptr()) {
_ml_call_reversed(script.ptr(), p_method, p_args, p_argcount);
}
}
void GDScriptInstance::notification(int p_notification) {
-
//notification is not virtual, it gets called at ALL levels just like in C.
Variant value = p_notification;
const Variant *args[1] = { &value };
@@ -1354,27 +1353,28 @@ String GDScriptInstance::to_string(bool *r_valid) {
Variant ret = call(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce);
if (ce.error == Callable::CallError::CALL_OK) {
if (ret.get_type() != Variant::STRING) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
}
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return ret.operator String();
}
}
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return String();
}
Ref<Script> GDScriptInstance::get_script() const {
-
return script;
}
ScriptLanguage *GDScriptInstance::get_language() {
-
return GDScriptLanguage::get_singleton();
}
@@ -1419,7 +1419,6 @@ MultiplayerAPI::RPCMode GDScriptInstance::get_rset_mode(const StringName &p_vari
}
void GDScriptInstance::reload_members() {
-
#ifdef DEBUG_ENABLED
members.resize(script->member_indices.size()); //resize
@@ -1429,7 +1428,6 @@ void GDScriptInstance::reload_members() {
//pass the values to the new indices
for (Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.front(); E; E = E->next()) {
-
if (member_indices_cache.has(E->key())) {
Variant value = members[member_indices_cache[E->key()]];
new_members.write[E->get().index] = value;
@@ -1442,7 +1440,6 @@ void GDScriptInstance::reload_members() {
//pass the values to the new indices
member_indices_cache.clear();
for (Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.front(); E; E = E->next()) {
-
member_indices_cache[E->key()] = E->get().index;
}
@@ -1455,9 +1452,14 @@ GDScriptInstance::GDScriptInstance() {
}
GDScriptInstance::~GDScriptInstance() {
- if (script.is_valid() && owner) {
- MutexLock lock(GDScriptLanguage::singleton->lock);
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
+
+ while (SelfList<GDScriptFunctionState> *E = pending_func_states.first()) {
+ E->self()->_clear_stack();
+ pending_func_states.remove(E);
+ }
+ if (script.is_valid() && owner) {
script->instances.erase(owner);
}
}
@@ -1467,14 +1469,12 @@ GDScriptInstance::~GDScriptInstance() {
GDScriptLanguage *GDScriptLanguage::singleton = nullptr;
String GDScriptLanguage::get_name() const {
-
return "GDScript";
}
/* LANGUAGE FUNCTIONS */
void GDScriptLanguage::_add_global(const StringName &p_name, const Variant &p_value) {
-
if (globals.has(p_name)) {
//overwrite existing
global_array.write[globals[p_name]] = p_value;
@@ -1486,7 +1486,6 @@ void GDScriptLanguage::_add_global(const StringName &p_name, const Variant &p_va
}
void GDScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) {
-
_add_global(p_variable, p_value);
}
@@ -1500,11 +1499,9 @@ void GDScriptLanguage::remove_named_global_constant(const StringName &p_name) {
}
void GDScriptLanguage::init() {
-
//populate global constants
int gcc = GlobalConstants::get_global_constant_count();
for (int i = 0; i < gcc; i++) {
-
_add_global(StaticCString::create(GlobalConstants::get_global_constant_name(i)), GlobalConstants::get_global_constant_value(i));
}
@@ -1518,14 +1515,15 @@ void GDScriptLanguage::init() {
List<StringName> class_list;
ClassDB::get_class_list(&class_list);
for (List<StringName>::Element *E = class_list.front(); E; E = E->next()) {
-
StringName n = E->get();
String s = String(n);
- if (s.begins_with("_"))
+ if (s.begins_with("_")) {
n = s.substr(1, s.length());
+ }
- if (globals.has(n))
+ if (globals.has(n)) {
continue;
+ }
Ref<GDScriptNativeClass> nc = memnew(GDScriptNativeClass(E->get()));
_add_global(n, nc);
}
@@ -1535,29 +1533,27 @@ void GDScriptLanguage::init() {
List<Engine::Singleton> singletons;
Engine::get_singleton()->get_singletons(&singletons);
for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
-
_add_global(E->get().name, E->get().ptr);
}
}
String GDScriptLanguage::get_type() const {
-
return "GDScript";
}
-String GDScriptLanguage::get_extension() const {
+String GDScriptLanguage::get_extension() const {
return "gd";
}
-Error GDScriptLanguage::execute_file(const String &p_path) {
+Error GDScriptLanguage::execute_file(const String &p_path) {
// ??
return OK;
}
+
void GDScriptLanguage::finish() {
}
void GDScriptLanguage::profiling_start() {
-
#ifdef DEBUG_ENABLED
MutexLock lock(this->lock);
@@ -1580,7 +1576,6 @@ void GDScriptLanguage::profiling_start() {
}
void GDScriptLanguage::profiling_stop() {
-
#ifdef DEBUG_ENABLED
MutexLock lock(this->lock);
@@ -1589,7 +1584,6 @@ void GDScriptLanguage::profiling_stop() {
}
int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
-
int current = 0;
#ifdef DEBUG_ENABLED
@@ -1597,8 +1591,9 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr,
SelfList<GDScriptFunction> *elem = function_list.first();
while (elem) {
- if (current >= p_info_max)
+ if (current >= p_info_max) {
break;
+ }
p_info_arr[current].call_count = elem->self()->profile.call_count;
p_info_arr[current].self_time = elem->self()->profile.self_time;
p_info_arr[current].total_time = elem->self()->profile.total_time;
@@ -1612,7 +1607,6 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr,
}
int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) {
-
int current = 0;
#ifdef DEBUG_ENABLED
@@ -1620,8 +1614,9 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_
SelfList<GDScriptFunction> *elem = function_list.first();
while (elem) {
- if (current >= p_info_max)
+ if (current >= p_info_max) {
break;
+ }
if (elem->self()->profile.last_frame_call_count > 0) {
p_info_arr[current].call_count = elem->self()->profile.last_frame_call_count;
p_info_arr[current].self_time = elem->self()->profile.last_frame_self_time;
@@ -1637,12 +1632,11 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_
}
struct GDScriptDepSort {
-
//must support sorting so inheritance works properly (parent must be reloaded first)
bool operator()(const Ref<GDScript> &A, const Ref<GDScript> &B) const {
-
- if (A == B)
+ if (A == B) {
return false; //shouldn't happen but..
+ }
const GDScript *I = B->get_base().ptr();
while (I) {
if (I == A.ptr()) {
@@ -1658,7 +1652,6 @@ struct GDScriptDepSort {
};
void GDScriptLanguage::reload_all_scripts() {
-
#ifdef DEBUG_ENABLED
print_verbose("GDScript: Reloading all scripts");
List<Ref<GDScript>> scripts;
@@ -1680,7 +1673,6 @@ void GDScriptLanguage::reload_all_scripts() {
scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order
for (List<Ref<GDScript>>::Element *E = scripts.front(); E; E = E->next()) {
-
print_verbose("GDScript: Reloading: " + E->get()->get_path());
E->get()->load_source_code(E->get()->get_path());
E->get()->reload(true);
@@ -1689,7 +1681,6 @@ void GDScriptLanguage::reload_all_scripts() {
}
void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) {
-
#ifdef DEBUG_ENABLED
List<Ref<GDScript>> scripts;
@@ -1699,7 +1690,6 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
SelfList<GDScript> *elem = script_list.first();
while (elem) {
if (elem->self()->get_path().is_resource_file()) {
-
scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident
}
elem = elem->next();
@@ -1715,16 +1705,15 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order
for (List<Ref<GDScript>>::Element *E = scripts.front(); E; E = E->next()) {
-
bool reload = E->get() == p_script || to_reload.has(E->get()->get_base());
- if (!reload)
+ if (!reload) {
continue;
+ }
to_reload.insert(E->get(), Map<ObjectID, List<Pair<StringName, Variant>>>());
if (!p_soft_reload) {
-
//save state and remove script from instances
Map<ObjectID, List<Pair<StringName, Variant>>> &map = to_reload[E->get()];
@@ -1733,7 +1722,6 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
//save instance info
List<Pair<StringName, Variant>> state;
if (obj->get_script_instance()) {
-
obj->get_script_instance()->get_property_state(state);
map[obj->get_instance_id()] = state;
obj->set_script(Variant());
@@ -1748,7 +1736,6 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
//save instance info
if (obj->get_script_instance()) {
-
map.insert(obj->get_instance_id(), List<Pair<StringName, Variant>>());
List<Pair<StringName, Variant>> &state = map[obj->get_instance_id()];
obj->get_script_instance()->get_property_state(state);
@@ -1768,18 +1755,17 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
}
for (Map<Ref<GDScript>, Map<ObjectID, List<Pair<StringName, Variant>>>>::Element *E = to_reload.front(); E; E = E->next()) {
-
Ref<GDScript> scr = E->key();
scr->reload(p_soft_reload);
//restore state if saved
for (Map<ObjectID, List<Pair<StringName, Variant>>>::Element *F = E->get().front(); F; F = F->next()) {
-
List<Pair<StringName, Variant>> &saved_state = F->get();
Object *obj = ObjectDB::get_instance(F->key());
- if (!obj)
+ if (!obj) {
continue;
+ }
if (!p_soft_reload) {
//clear it just in case (may be a pending reload state)
@@ -1818,7 +1804,6 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so
}
void GDScriptLanguage::frame() {
-
calls = 0;
#ifdef DEBUG_ENABLED
@@ -1842,7 +1827,6 @@ void GDScriptLanguage::frame() {
/* EDITOR FUNCTIONS */
void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
-
static const char *_reserved_words[] = {
// operators
"and",
@@ -1906,7 +1890,6 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
const char **w = _reserved_words;
while (*w) {
-
p_words->push_back(*w);
w++;
}
@@ -1917,12 +1900,10 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
}
bool GDScriptLanguage::handles_global_class_type(const String &p_type) const {
-
return p_type == "GDScript";
}
String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const {
-
Vector<uint8_t> sourcef;
Error err;
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err);
@@ -1936,16 +1917,15 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
parser.parse(source, p_path.get_base_dir(), true, p_path, false, nullptr, true);
if (parser.get_parse_tree() && parser.get_parse_tree()->type == GDScriptParser::Node::TYPE_CLASS) {
-
const GDScriptParser::ClassNode *c = static_cast<const GDScriptParser::ClassNode *>(parser.get_parse_tree());
if (r_icon_path) {
- if (c->icon_path.empty() || c->icon_path.is_abs_path())
+ if (c->icon_path.empty() || c->icon_path.is_abs_path()) {
*r_icon_path = c->icon_path;
- else if (c->icon_path.is_rel_path())
+ } else if (c->icon_path.is_rel_path()) {
*r_icon_path = p_path.get_base_dir().plus_file(c->icon_path).simplify_path();
+ }
}
if (r_base_type) {
-
const GDScriptParser::ClassNode *subclass = c;
String path = p_path;
GDScriptParser subparser;
@@ -2019,7 +1999,6 @@ String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_b
#ifdef DEBUG_ENABLED
String GDScriptWarning::get_message() const {
-
#define CHECK_SYMBOLS(m_amount) ERR_FAIL_COND_V(symbols.size() < m_amount, String());
switch (code) {
@@ -2126,7 +2105,8 @@ String GDScriptWarning::get_message() const {
case STANDALONE_TERNARY: {
return "Standalone ternary conditional operator: the return value is being discarded.";
}
- case WARNING_MAX: break; // Can't happen, but silences warning
+ case WARNING_MAX:
+ break; // Can't happen, but silences warning
}
ERR_FAIL_V_MSG(String(), "Invalid GDScript warning code: " + get_name_from_code(code) + ".");
@@ -2187,7 +2167,6 @@ GDScriptWarning::Code GDScriptWarning::get_code_from_name(const String &p_name)
#endif // DEBUG_ENABLED
GDScriptLanguage::GDScriptLanguage() {
-
calls = 0;
ERR_FAIL_COND(singleton);
singleton = this;
@@ -2232,7 +2211,6 @@ GDScriptLanguage::GDScriptLanguage() {
}
GDScriptLanguage::~GDScriptLanguage() {
-
if (_call_stack) {
memdelete_arr(_call_stack);
}
@@ -2245,29 +2223,30 @@ void GDScriptLanguage::add_orphan_subclass(const String &p_qualified_name, const
Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_name) {
Map<String, ObjectID>::Element *orphan_subclass_element = orphan_subclasses.find(p_qualified_name);
- if (!orphan_subclass_element)
+ if (!orphan_subclass_element) {
return Ref<GDScript>();
+ }
ObjectID orphan_subclass = orphan_subclass_element->get();
Object *obj = ObjectDB::get_instance(orphan_subclass);
orphan_subclasses.erase(orphan_subclass_element);
- if (!obj)
+ if (!obj) {
return Ref<GDScript>();
+ }
return Ref<GDScript>(Object::cast_to<GDScript>(obj));
}
/*************** RESOURCE ***************/
-RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
- if (r_error)
+RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
+ }
GDScript *script = memnew(GDScript);
Ref<GDScript> scriptres(script);
if (p_path.ends_with(".gde") || p_path.ends_with(".gdc")) {
-
script->set_script_path(p_original_path); // script needs this.
script->set_path(p_original_path);
Error err = script->load_byte_code(p_path);
@@ -2282,34 +2261,32 @@ RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_ori
script->reload();
}
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return scriptres;
}
void ResourceFormatLoaderGDScript::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("gd");
p_extensions->push_back("gdc");
p_extensions->push_back("gde");
}
bool ResourceFormatLoaderGDScript::handles_type(const String &p_type) const {
-
return (p_type == "Script" || p_type == "GDScript");
}
String ResourceFormatLoaderGDScript::get_resource_type(const String &p_path) const {
-
String el = p_path.get_extension().to_lower();
- if (el == "gd" || el == "gdc" || el == "gde")
+ if (el == "gd" || el == "gdc" || el == "gde") {
return "GDScript";
+ }
return "";
}
void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
-
FileAccessRef file = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_MSG(!file, "Cannot open file '" + p_path + "'.");
@@ -2329,7 +2306,6 @@ void ResourceFormatLoaderGDScript::get_dependencies(const String &p_path, List<S
}
Error ResourceFormatSaverGDScript::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
Ref<GDScript> sqscr = p_resource;
ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER);
@@ -2356,12 +2332,11 @@ Error ResourceFormatSaverGDScript::save(const String &p_path, const RES &p_resou
}
void ResourceFormatSaverGDScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
-
if (Object::cast_to<GDScript>(*p_resource)) {
p_extensions->push_back("gd");
}
}
-bool ResourceFormatSaverGDScript::recognize(const RES &p_resource) const {
+bool ResourceFormatSaverGDScript::recognize(const RES &p_resource) const {
return Object::cast_to<GDScript>(*p_resource) != nullptr;
}
diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h
index 2c5876372b..e770dc3abd 100644
--- a/modules/gdscript/gdscript.h
+++ b/modules/gdscript/gdscript.h
@@ -39,7 +39,6 @@
#include "gdscript_function.h"
class GDScriptNativeClass : public Reference {
-
GDCLASS(GDScriptNativeClass, Reference);
StringName name;
@@ -56,7 +55,6 @@ public:
};
class GDScript : public Script {
-
GDCLASS(GDScript, Script);
bool tool;
bool valid;
@@ -117,6 +115,8 @@ class GDScript : public Script {
String fully_qualified_name;
SelfList<GDScript> script_list;
+ SelfList<GDScriptFunctionState>::List pending_func_states;
+
GDScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error);
void _set_subclass_path(Ref<GDScript> &p_sc, const String &p_path);
@@ -133,7 +133,7 @@ class GDScript : public Script {
#endif
- bool _update_exports();
+ bool _update_exports(bool *r_err = nullptr, bool p_recursive_call = false);
void _save_orphaned_subclasses();
void _init_rpc_methods_properties();
@@ -151,6 +151,8 @@ protected:
public:
virtual bool is_valid() const { return valid; }
+ bool inherits_script(const Ref<Script> &p_script) const;
+
const Map<StringName, Ref<GDScript>> &get_subclasses() const { return subclasses; }
const Map<StringName, Variant> &get_constants() const { return constants; }
const Set<StringName> &get_members() const { return members; }
@@ -207,11 +209,11 @@ public:
virtual int get_member_line(const StringName &p_member) const {
#ifdef TOOLS_ENABLED
- if (member_lines.has(p_member))
+ if (member_lines.has(p_member)) {
return member_lines[p_member];
- else
+ }
#endif
- return -1;
+ return -1;
}
virtual void get_constants(Map<StringName, Variant> *p_constants);
@@ -252,6 +254,8 @@ class GDScriptInstance : public ScriptInstance {
Vector<Variant> members;
bool base_ref;
+ SelfList<GDScriptFunctionState>::List pending_func_states;
+
void _ml_call_reversed(GDScript *sptr, const StringName &p_method, const Variant **p_args, int p_argcount);
public:
@@ -328,22 +332,23 @@ struct GDScriptWarning {
DEPRECATED_KEYWORD, // The keyword is deprecated and should be replaced
STANDALONE_TERNARY, // Return value of ternary expression is discarded
WARNING_MAX,
- } code;
+ };
+
+ Code code = WARNING_MAX;
Vector<String> symbols;
- int line;
+ int line = -1;
String get_name() const;
String get_message() const;
static String get_name_from_code(Code p_code);
static Code get_code_from_name(const String &p_name);
- GDScriptWarning() :
- code(WARNING_MAX),
- line(-1) {}
+ GDScriptWarning() {}
};
#endif // DEBUG_ENABLED
class GDScriptLanguage : public ScriptLanguage {
+ friend class GDScriptFunctionState;
static GDScriptLanguage *singleton;
@@ -353,7 +358,6 @@ class GDScriptLanguage : public ScriptLanguage {
Map<StringName, Variant> named_globals;
struct CallLevel {
-
Variant *stack;
GDScriptFunction *function;
GDScriptInstance *instance;
@@ -392,12 +396,13 @@ public:
bool debug_break_parse(const String &p_file, int p_line, const String &p_error);
_FORCE_INLINE_ void enter_function(GDScriptInstance *p_instance, GDScriptFunction *p_function, Variant *p_stack, int *p_ip, int *p_line) {
-
- if (Thread::get_main_id() != Thread::get_caller_id())
+ if (Thread::get_main_id() != Thread::get_caller_id()) {
return; //no support for other threads than main for now
+ }
- if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0)
+ if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) {
EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() + 1);
+ }
if (_debug_call_stack_pos >= _debug_max_call_stack) {
//stack overflow
@@ -415,15 +420,15 @@ public:
}
_FORCE_INLINE_ void exit_function() {
-
- if (Thread::get_main_id() != Thread::get_caller_id())
+ if (Thread::get_main_id() != Thread::get_caller_id()) {
return; //no support for other threads than main for now
+ }
- if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0)
+ if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) {
EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() - 1);
+ }
if (_debug_call_stack_pos == 0) {
-
_debug_error = "Stack Underflow (Engine Bug)";
EngineDebugger::get_script_debugger()->debug(this);
return;
@@ -433,8 +438,9 @@ public:
}
virtual Vector<StackInfo> debug_get_current_stack_info() {
- if (Thread::get_main_id() != Thread::get_caller_id())
+ if (Thread::get_main_id() != Thread::get_caller_id()) {
return Vector<StackInfo>();
+ }
Vector<StackInfo> csi;
csi.resize(_debug_call_stack_pos);
@@ -449,7 +455,6 @@ public:
}
struct {
-
StringName _init;
StringName _notification;
StringName _set;
@@ -545,7 +550,7 @@ public:
class ResourceFormatLoaderGDScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 2bbec29043..bc095ae1f9 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -33,24 +33,24 @@
#include "gdscript.h"
bool GDScriptCompiler::_is_class_member_property(CodeGen &codegen, const StringName &p_name) {
-
- if (codegen.function_node && codegen.function_node->_static)
+ if (codegen.function_node && codegen.function_node->_static) {
return false;
+ }
- if (codegen.stack_identifiers.has(p_name))
+ if (codegen.stack_identifiers.has(p_name)) {
return false; //shadowed
+ }
return _is_class_member_property(codegen.script, p_name);
}
bool GDScriptCompiler::_is_class_member_property(GDScript *owner, const StringName &p_name) {
-
GDScript *scr = owner;
GDScriptNativeClass *nc = nullptr;
while (scr) {
-
- if (scr->native.is_valid())
+ if (scr->native.is_valid()) {
nc = scr->native.ptr();
+ }
scr = scr->_base;
}
@@ -60,9 +60,9 @@ bool GDScriptCompiler::_is_class_member_property(GDScript *owner, const StringNa
}
void GDScriptCompiler::_set_error(const String &p_error, const GDScriptParser::Node *p_node) {
-
- if (error != "")
+ if (error != "") {
return;
+ }
error = p_error;
if (p_node) {
@@ -75,12 +75,12 @@ void GDScriptCompiler::_set_error(const String &p_error, const GDScriptParser::N
}
bool GDScriptCompiler::_create_unary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level) {
-
ERR_FAIL_COND_V(on->arguments.size() != 1, false);
int src_address_a = _parse_expression(codegen, on->arguments[0], p_stack_level);
- if (src_address_a < 0)
+ if (src_address_a < 0) {
return false;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator
codegen.opcodes.push_back(op); //which operator
@@ -91,18 +91,20 @@ bool GDScriptCompiler::_create_unary_operator(CodeGen &codegen, const GDScriptPa
}
bool GDScriptCompiler::_create_binary_operator(CodeGen &codegen, const GDScriptParser::OperatorNode *on, Variant::Operator op, int p_stack_level, bool p_initializer, int p_index_addr) {
-
ERR_FAIL_COND_V(on->arguments.size() != 2, false);
int src_address_a = _parse_expression(codegen, on->arguments[0], p_stack_level, false, p_initializer, p_index_addr);
- if (src_address_a < 0)
+ if (src_address_a < 0) {
return false;
- if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)
+ }
+ if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
p_stack_level++; //uses stack for return, increase stack
+ }
int src_address_b = _parse_expression(codegen, on->arguments[1], p_stack_level, false, p_initializer);
- if (src_address_b < 0)
+ if (src_address_b < 0) {
return false;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_OPERATOR); // perform operator
codegen.opcodes.push_back(op); //which operator
@@ -172,28 +174,44 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
}
int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDScriptParser::OperatorNode *p_expression, int p_stack_level, int p_index_addr) {
-
Variant::Operator var_op = Variant::OP_MAX;
switch (p_expression->op) {
-
- case GDScriptParser::OperatorNode::OP_ASSIGN_ADD: var_op = Variant::OP_ADD; break;
- case GDScriptParser::OperatorNode::OP_ASSIGN_SUB: var_op = Variant::OP_SUBTRACT; break;
- case GDScriptParser::OperatorNode::OP_ASSIGN_MUL: var_op = Variant::OP_MULTIPLY; break;
- case GDScriptParser::OperatorNode::OP_ASSIGN_DIV: var_op = Variant::OP_DIVIDE; break;
- case GDScriptParser::OperatorNode::OP_ASSIGN_MOD: var_op = Variant::OP_MODULE; break;
- case GDScriptParser::OperatorNode::OP_ASSIGN_SHIFT_LEFT: var_op = Variant::OP_SHIFT_LEFT; break;
- case GDScriptParser::OperatorNode::OP_ASSIGN_SHIFT_RIGHT: var_op = Variant::OP_SHIFT_RIGHT; break;
- case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_AND: var_op = Variant::OP_BIT_AND; break;
- case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_OR: var_op = Variant::OP_BIT_OR; break;
- case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_XOR: var_op = Variant::OP_BIT_XOR; break;
+ case GDScriptParser::OperatorNode::OP_ASSIGN_ADD:
+ var_op = Variant::OP_ADD;
+ break;
+ case GDScriptParser::OperatorNode::OP_ASSIGN_SUB:
+ var_op = Variant::OP_SUBTRACT;
+ break;
+ case GDScriptParser::OperatorNode::OP_ASSIGN_MUL:
+ var_op = Variant::OP_MULTIPLY;
+ break;
+ case GDScriptParser::OperatorNode::OP_ASSIGN_DIV:
+ var_op = Variant::OP_DIVIDE;
+ break;
+ case GDScriptParser::OperatorNode::OP_ASSIGN_MOD:
+ var_op = Variant::OP_MODULE;
+ break;
+ case GDScriptParser::OperatorNode::OP_ASSIGN_SHIFT_LEFT:
+ var_op = Variant::OP_SHIFT_LEFT;
+ break;
+ case GDScriptParser::OperatorNode::OP_ASSIGN_SHIFT_RIGHT:
+ var_op = Variant::OP_SHIFT_RIGHT;
+ break;
+ case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_AND:
+ var_op = Variant::OP_BIT_AND;
+ break;
+ case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_OR:
+ var_op = Variant::OP_BIT_OR;
+ break;
+ case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_XOR:
+ var_op = Variant::OP_BIT_XOR;
+ break;
case GDScriptParser::OperatorNode::OP_INIT_ASSIGN:
case GDScriptParser::OperatorNode::OP_ASSIGN: {
-
//none
} break;
default: {
-
ERR_FAIL_V(-1);
}
}
@@ -201,12 +219,12 @@ int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDS
bool initializer = p_expression->op == GDScriptParser::OperatorNode::OP_INIT_ASSIGN;
if (var_op == Variant::OP_MAX) {
-
return _parse_expression(codegen, p_expression->arguments[1], p_stack_level, false, initializer);
}
- if (!_create_binary_operator(codegen, p_expression, var_op, p_stack_level, initializer, p_index_addr))
+ if (!_create_binary_operator(codegen, p_expression, var_op, p_stack_level, initializer, p_index_addr)) {
return -1;
+ }
int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
@@ -215,7 +233,6 @@ int GDScriptCompiler::_parse_assign_right_expression(CodeGen &codegen, const GDS
}
int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::Node *p_expression, int p_stack_level, bool p_root, bool p_initializer, int p_index_addr) {
-
switch (p_expression->type) {
//should parse variable declaration and adjust stack accordingly...
case GDScriptParser::Node::TYPE_IDENTIFIER: {
@@ -231,7 +248,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
// TRY STACK!
if (!p_initializer && codegen.stack_identifiers.has(identifier)) {
-
int pos = codegen.stack_identifiers[identifier];
return pos | (GDScriptFunction::ADDR_TYPE_STACK_VARIABLE << GDScriptFunction::ADDR_BITS);
}
@@ -249,11 +265,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
//TRY MEMBERS!
if (!codegen.function_node || !codegen.function_node->_static) {
-
// TRY MEMBER VARIABLES!
//static function
if (codegen.script->member_indices.has(identifier)) {
-
int idx = codegen.script->member_indices[identifier].index;
return idx | (GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS); //argument (stack root)
}
@@ -263,26 +277,23 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
GDScript *owner = codegen.script;
while (owner) {
-
GDScript *scr = owner;
GDScriptNativeClass *nc = nullptr;
while (scr) {
-
if (scr->constants.has(identifier)) {
-
//int idx=scr->constants[identifier];
int idx = codegen.get_name_map_pos(identifier);
return idx | (GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS); //argument (stack root)
}
- if (scr->native.is_valid())
+ if (scr->native.is_valid()) {
nc = scr->native.ptr();
+ }
scr = scr->_base;
}
// CLASS C++ Integer Constant
if (nc) {
-
bool success = false;
int constant = ClassDB::get_integer_constant(nc->get_name(), identifier, &success);
if (success) {
@@ -290,7 +301,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int idx;
if (!codegen.constant_map.has(key)) {
-
idx = codegen.constant_map.size();
codegen.constant_map[key] = idx;
@@ -306,7 +316,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
}
if (GDScriptLanguage::get_singleton()->get_global_map().has(identifier)) {
-
int idx = GDScriptLanguage::get_singleton()->get_global_map()[identifier];
return idx | (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
}
@@ -314,7 +323,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
/* TRY GLOBAL CLASSES */
if (ScriptServer::is_global_class(identifier)) {
-
const GDScriptParser::ClassNode *class_node = codegen.class_node;
while (class_node->owner) {
class_node = class_node->owner;
@@ -335,7 +343,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int idx;
if (!codegen.constant_map.has(key)) {
-
idx = codegen.constant_map.size();
codegen.constant_map[key] = idx;
@@ -348,7 +355,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
#ifdef TOOLS_ENABLED
if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(identifier)) {
-
int idx = codegen.named_globals.find(identifier);
if (idx == -1) {
idx = codegen.named_globals.size();
@@ -372,7 +378,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int idx;
if (!codegen.constant_map.has(cn->value)) {
-
idx = codegen.constant_map.size();
codegen.constant_map[cn->value] = idx;
@@ -392,17 +397,16 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
return (GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
} break;
case GDScriptParser::Node::TYPE_ARRAY: {
-
const GDScriptParser::ArrayNode *an = static_cast<const GDScriptParser::ArrayNode *>(p_expression);
Vector<int> values;
int slevel = p_stack_level;
for (int i = 0; i < an->elements.size(); i++) {
-
int ret = _parse_expression(codegen, an->elements[i], slevel);
- if (ret < 0)
+ if (ret < 0) {
return ret;
+ }
if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
@@ -413,8 +417,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT_ARRAY);
codegen.opcodes.push_back(values.size());
- for (int i = 0; i < values.size(); i++)
+ for (int i = 0; i < values.size(); i++) {
codegen.opcodes.push_back(values[i]);
+ }
int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
@@ -423,17 +428,16 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
} break;
case GDScriptParser::Node::TYPE_DICTIONARY: {
-
const GDScriptParser::DictionaryNode *dn = static_cast<const GDScriptParser::DictionaryNode *>(p_expression);
Vector<int> values;
int slevel = p_stack_level;
for (int i = 0; i < dn->elements.size(); i++) {
-
int ret = _parse_expression(codegen, dn->elements[i].key, slevel);
- if (ret < 0)
+ if (ret < 0) {
return ret;
+ }
if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
@@ -442,8 +446,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
values.push_back(ret);
ret = _parse_expression(codegen, dn->elements[i].value, slevel);
- if (ret < 0)
+ if (ret < 0) {
return ret;
+ }
if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
@@ -454,8 +459,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.opcodes.push_back(GDScriptFunction::OPCODE_CONSTRUCT_DICTIONARY);
codegen.opcodes.push_back(dn->elements.size());
- for (int i = 0; i < values.size(); i++)
+ for (int i = 0; i < values.size(); i++) {
codegen.opcodes.push_back(values[i]);
+ }
int dst_addr = (p_stack_level) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
codegen.opcodes.push_back(dst_addr); // append the stack level as destination address of the opcode
@@ -468,8 +474,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int slevel = p_stack_level;
int src_addr = _parse_expression(codegen, cn->source_node, slevel);
- if (src_addr < 0)
+ if (src_addr < 0) {
return src_addr;
+ }
if (src_addr & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
slevel++;
codegen.alloc_stack(slevel);
@@ -485,7 +492,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
case GDScriptDataType::NATIVE: {
int class_idx;
if (GDScriptLanguage::get_singleton()->get_global_map().has(cast_type.native_type)) {
-
class_idx = GDScriptLanguage::get_singleton()->get_global_map()[cast_type.native_type];
class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
} else {
@@ -497,7 +503,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
} break;
case GDScriptDataType::SCRIPT:
case GDScriptDataType::GDSCRIPT: {
-
Variant script = cast_type.script_type;
int idx = codegen.get_constant_pos(script);
idx |= GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS; //make it a local constant (faster access)
@@ -523,10 +528,8 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
const GDScriptParser::OperatorNode *on = static_cast<const GDScriptParser::OperatorNode *>(p_expression);
switch (on->op) {
-
//call/constructor operator
case GDScriptParser::OperatorNode::OP_PARENT_CALL: {
-
ERR_FAIL_COND_V(on->arguments.size() < 1, -1);
const GDScriptParser::IdentifierNode *in = (const GDScriptParser::IdentifierNode *)on->arguments[0];
@@ -534,10 +537,10 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
Vector<int> arguments;
int slevel = p_stack_level;
for (int i = 1; i < on->arguments.size(); i++) {
-
int ret = _parse_expression(codegen, on->arguments[i], slevel);
- if (ret < 0)
+ if (ret < 0) {
return ret;
+ }
if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
@@ -551,12 +554,12 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.opcodes.push_back(codegen.get_name_map_pos(in->name)); //instance
codegen.opcodes.push_back(arguments.size()); //argument count
codegen.alloc_call(arguments.size());
- for (int i = 0; i < arguments.size(); i++)
+ for (int i = 0; i < arguments.size(); i++) {
codegen.opcodes.push_back(arguments[i]); //arguments
+ }
} break;
case GDScriptParser::OperatorNode::OP_CALL: {
-
if (on->arguments[0]->type == GDScriptParser::Node::TYPE_TYPE) {
//construct a basic type
ERR_FAIL_COND_V(on->arguments.size() < 1, -1);
@@ -567,10 +570,10 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
Vector<int> arguments;
int slevel = p_stack_level;
for (int i = 1; i < on->arguments.size(); i++) {
-
int ret = _parse_expression(codegen, on->arguments[i], slevel);
- if (ret < 0)
+ if (ret < 0) {
return ret;
+ }
if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
@@ -583,8 +586,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.opcodes.push_back(vtype); //instance
codegen.opcodes.push_back(arguments.size()); //argument count
codegen.alloc_call(arguments.size());
- for (int i = 0; i < arguments.size(); i++)
+ for (int i = 0; i < arguments.size(); i++) {
codegen.opcodes.push_back(arguments[i]); //arguments
+ }
} else if (on->arguments[0]->type == GDScriptParser::Node::TYPE_BUILT_IN_FUNCTION) {
//built in function
@@ -594,10 +598,10 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
Vector<int> arguments;
int slevel = p_stack_level;
for (int i = 1; i < on->arguments.size(); i++) {
-
int ret = _parse_expression(codegen, on->arguments[i], slevel);
- if (ret < 0)
+ if (ret < 0) {
return ret;
+ }
if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
@@ -611,8 +615,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.opcodes.push_back(static_cast<const GDScriptParser::BuiltInFunctionNode *>(on->arguments[0])->function);
codegen.opcodes.push_back(on->arguments.size() - 1);
codegen.alloc_call(on->arguments.size() - 1);
- for (int i = 0; i < arguments.size(); i++)
+ for (int i = 0; i < arguments.size(); i++) {
codegen.opcodes.push_back(arguments[i]);
+ }
} else {
//regular function
@@ -628,14 +633,12 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int slevel = p_stack_level;
for (int i = 0; i < on->arguments.size(); i++) {
-
int ret;
if (i == 0 && on->arguments[i]->type == GDScriptParser::Node::TYPE_SELF && codegen.function_node && codegen.function_node->_static) {
//static call to self
ret = (GDScriptFunction::ADDR_TYPE_CLASS << GDScriptFunction::ADDR_BITS);
} else if (i == 1) {
-
if (on->arguments[i]->type != GDScriptParser::Node::TYPE_IDENTIFIER) {
_set_error("Attempt to call a non-identifier.", on);
return -1;
@@ -644,10 +647,10 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
ret = codegen.get_name_map_pos(id->name);
} else {
-
ret = _parse_expression(codegen, on->arguments[i], slevel);
- if (ret < 0)
+ if (ret < 0) {
return ret;
+ }
if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
@@ -659,21 +662,21 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.opcodes.push_back(p_root ? GDScriptFunction::OPCODE_CALL : GDScriptFunction::OPCODE_CALL_RETURN); // perform operator
codegen.opcodes.push_back(on->arguments.size() - 2);
codegen.alloc_call(on->arguments.size() - 2);
- for (int i = 0; i < arguments.size(); i++)
+ for (int i = 0; i < arguments.size(); i++) {
codegen.opcodes.push_back(arguments[i]);
+ }
}
} break;
case GDScriptParser::OperatorNode::OP_YIELD: {
-
ERR_FAIL_COND_V(on->arguments.size() && on->arguments.size() != 2, -1);
Vector<int> arguments;
int slevel = p_stack_level;
for (int i = 0; i < on->arguments.size(); i++) {
-
int ret = _parse_expression(codegen, on->arguments[i], slevel);
- if (ret < 0)
+ if (ret < 0) {
return ret;
+ }
if ((ret >> GDScriptFunction::ADDR_BITS & GDScriptFunction::ADDR_TYPE_STACK) == GDScriptFunction::ADDR_TYPE_STACK) {
slevel++;
codegen.alloc_stack(slevel);
@@ -683,8 +686,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
//push call bytecode
codegen.opcodes.push_back(arguments.size() == 0 ? GDScriptFunction::OPCODE_YIELD : GDScriptFunction::OPCODE_YIELD_SIGNAL); // basic type constructor
- for (int i = 0; i < arguments.size(); i++)
+ for (int i = 0; i < arguments.size(); i++) {
codegen.opcodes.push_back(arguments[i]); //arguments
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_YIELD_RESUME);
//next will be where to place the result :)
@@ -693,22 +697,21 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
//indexing operator
case GDScriptParser::OperatorNode::OP_INDEX:
case GDScriptParser::OperatorNode::OP_INDEX_NAMED: {
-
ERR_FAIL_COND_V(on->arguments.size() != 2, -1);
int slevel = p_stack_level;
bool named = (on->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED);
int from = _parse_expression(codegen, on->arguments[0], slevel);
- if (from < 0)
+ if (from < 0) {
return from;
+ }
int index;
if (p_index_addr != 0) {
index = p_index_addr;
} else if (named) {
if (on->arguments[0]->type == GDScriptParser::Node::TYPE_SELF && codegen.script && codegen.function_node && !codegen.function_node->_static) {
-
GDScriptParser::IdentifierNode *identifier = static_cast<GDScriptParser::IdentifierNode *>(on->arguments[1]);
const Map<StringName, GDScript::MemberInfo>::Element *MI = codegen.script->member_indices.find(identifier->name);
@@ -729,7 +732,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
index = codegen.get_name_map_pos(static_cast<GDScriptParser::IdentifierNode *>(on->arguments[1])->name);
} else {
-
if (on->arguments[1]->type == GDScriptParser::Node::TYPE_CONSTANT && static_cast<const GDScriptParser::ConstantNode *>(on->arguments[1])->value.get_type() == Variant::STRING) {
//also, somehow, named (speed up anyway)
StringName name = static_cast<const GDScriptParser::ConstantNode *>(on->arguments[1])->value;
@@ -744,8 +746,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
}
index = _parse_expression(codegen, on->arguments[1], slevel);
- if (index < 0)
+ if (index < 0) {
return index;
+ }
}
}
@@ -755,20 +758,21 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
} break;
case GDScriptParser::OperatorNode::OP_AND: {
-
// AND operator with early out on failure
int res = _parse_expression(codegen, on->arguments[0], p_stack_level);
- if (res < 0)
+ if (res < 0) {
return res;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
codegen.opcodes.push_back(res);
int jump_fail_pos = codegen.opcodes.size();
codegen.opcodes.push_back(0);
res = _parse_expression(codegen, on->arguments[1], p_stack_level);
- if (res < 0)
+ if (res < 0) {
return res;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
codegen.opcodes.push_back(res);
@@ -788,20 +792,21 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
} break;
case GDScriptParser::OperatorNode::OP_OR: {
-
// OR operator with early out on success
int res = _parse_expression(codegen, on->arguments[0], p_stack_level);
- if (res < 0)
+ if (res < 0) {
return res;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF);
codegen.opcodes.push_back(res);
int jump_success_pos = codegen.opcodes.size();
codegen.opcodes.push_back(0);
res = _parse_expression(codegen, on->arguments[1], p_stack_level);
- if (res < 0)
+ if (res < 0) {
return res;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF);
codegen.opcodes.push_back(res);
@@ -822,20 +827,21 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
} break;
// ternary operators
case GDScriptParser::OperatorNode::OP_TERNARY_IF: {
-
// x IF a ELSE y operator with early out on failure
int res = _parse_expression(codegen, on->arguments[0], p_stack_level);
- if (res < 0)
+ if (res < 0) {
return res;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
codegen.opcodes.push_back(res);
int jump_fail_pos = codegen.opcodes.size();
codegen.opcodes.push_back(0);
res = _parse_expression(codegen, on->arguments[1], p_stack_level);
- if (res < 0)
+ if (res < 0) {
return res;
+ }
codegen.alloc_stack(p_stack_level); //it will be used..
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
@@ -847,8 +853,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.opcodes.write[jump_fail_pos] = codegen.opcodes.size();
res = _parse_expression(codegen, on->arguments[2], p_stack_level);
- if (res < 0)
+ if (res < 0) {
return res;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
codegen.opcodes.push_back(p_stack_level | GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
@@ -861,71 +868,113 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
} break;
//unary operators
case GDScriptParser::OperatorNode::OP_NEG: {
- if (!_create_unary_operator(codegen, on, Variant::OP_NEGATE, p_stack_level)) return -1;
+ if (!_create_unary_operator(codegen, on, Variant::OP_NEGATE, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_POS: {
- if (!_create_unary_operator(codegen, on, Variant::OP_POSITIVE, p_stack_level)) return -1;
+ if (!_create_unary_operator(codegen, on, Variant::OP_POSITIVE, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_NOT: {
- if (!_create_unary_operator(codegen, on, Variant::OP_NOT, p_stack_level)) return -1;
+ if (!_create_unary_operator(codegen, on, Variant::OP_NOT, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_BIT_INVERT: {
- if (!_create_unary_operator(codegen, on, Variant::OP_BIT_NEGATE, p_stack_level)) return -1;
+ if (!_create_unary_operator(codegen, on, Variant::OP_BIT_NEGATE, p_stack_level)) {
+ return -1;
+ }
} break;
//binary operators (in precedence order)
case GDScriptParser::OperatorNode::OP_IN: {
- if (!_create_binary_operator(codegen, on, Variant::OP_IN, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_IN, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_EQUAL: {
- if (!_create_binary_operator(codegen, on, Variant::OP_EQUAL, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_EQUAL, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_NOT_EQUAL: {
- if (!_create_binary_operator(codegen, on, Variant::OP_NOT_EQUAL, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_NOT_EQUAL, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_LESS: {
- if (!_create_binary_operator(codegen, on, Variant::OP_LESS, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_LESS, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_LESS_EQUAL: {
- if (!_create_binary_operator(codegen, on, Variant::OP_LESS_EQUAL, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_LESS_EQUAL, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_GREATER: {
- if (!_create_binary_operator(codegen, on, Variant::OP_GREATER, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_GREATER, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_GREATER_EQUAL: {
- if (!_create_binary_operator(codegen, on, Variant::OP_GREATER_EQUAL, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_GREATER_EQUAL, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_ADD: {
- if (!_create_binary_operator(codegen, on, Variant::OP_ADD, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_ADD, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_SUB: {
- if (!_create_binary_operator(codegen, on, Variant::OP_SUBTRACT, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_SUBTRACT, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_MUL: {
- if (!_create_binary_operator(codegen, on, Variant::OP_MULTIPLY, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_MULTIPLY, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_DIV: {
- if (!_create_binary_operator(codegen, on, Variant::OP_DIVIDE, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_DIVIDE, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_MOD: {
- if (!_create_binary_operator(codegen, on, Variant::OP_MODULE, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_MODULE, p_stack_level)) {
+ return -1;
+ }
} break;
//case GDScriptParser::OperatorNode::OP_SHIFT_LEFT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_LEFT,p_stack_level)) return -1;} break;
//case GDScriptParser::OperatorNode::OP_SHIFT_RIGHT: { if (!_create_binary_operator(codegen,on,Variant::OP_SHIFT_RIGHT,p_stack_level)) return -1;} break;
case GDScriptParser::OperatorNode::OP_BIT_AND: {
- if (!_create_binary_operator(codegen, on, Variant::OP_BIT_AND, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_BIT_AND, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_BIT_OR: {
- if (!_create_binary_operator(codegen, on, Variant::OP_BIT_OR, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_BIT_OR, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_BIT_XOR: {
- if (!_create_binary_operator(codegen, on, Variant::OP_BIT_XOR, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_BIT_XOR, p_stack_level)) {
+ return -1;
+ }
} break;
//shift
case GDScriptParser::OperatorNode::OP_SHIFT_LEFT: {
- if (!_create_binary_operator(codegen, on, Variant::OP_SHIFT_LEFT, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_SHIFT_LEFT, p_stack_level)) {
+ return -1;
+ }
} break;
case GDScriptParser::OperatorNode::OP_SHIFT_RIGHT: {
- if (!_create_binary_operator(codegen, on, Variant::OP_SHIFT_RIGHT, p_stack_level)) return -1;
+ if (!_create_binary_operator(codegen, on, Variant::OP_SHIFT_RIGHT, p_stack_level)) {
+ return -1;
+ }
} break;
//assignment operators
case GDScriptParser::OperatorNode::OP_ASSIGN_ADD:
@@ -940,18 +989,15 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
case GDScriptParser::OperatorNode::OP_ASSIGN_BIT_XOR:
case GDScriptParser::OperatorNode::OP_INIT_ASSIGN:
case GDScriptParser::OperatorNode::OP_ASSIGN: {
-
ERR_FAIL_COND_V(on->arguments.size() != 2, -1);
if (on->arguments[0]->type == GDScriptParser::Node::TYPE_OPERATOR && (static_cast<GDScriptParser::OperatorNode *>(on->arguments[0])->op == GDScriptParser::OperatorNode::OP_INDEX || static_cast<GDScriptParser::OperatorNode *>(on->arguments[0])->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED)) {
-
// SET (chained) MODE!
#ifdef DEBUG_ENABLED
if (static_cast<GDScriptParser::OperatorNode *>(on->arguments[0])->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED) {
const GDScriptParser::OperatorNode *inon = static_cast<GDScriptParser::OperatorNode *>(on->arguments[0]);
if (inon->arguments[0]->type == GDScriptParser::Node::TYPE_SELF && codegen.script && codegen.function_node && !codegen.function_node->_static) {
-
const Map<StringName, GDScript::MemberInfo>::Element *MI = codegen.script->member_indices.find(static_cast<GDScriptParser::IdentifierNode *>(inon->arguments[1])->name);
if (MI && MI->get().setter == codegen.function_node->name) {
String n = static_cast<GDScriptParser::IdentifierNode *>(inon->arguments[1])->name;
@@ -976,13 +1022,10 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
//create get/set chain
GDScriptParser::OperatorNode *n = op;
while (true) {
-
chain.push_back(n);
if (n->arguments[0]->type != GDScriptParser::Node::TYPE_OPERATOR) {
-
//check for a built-in property
if (n->arguments[0]->type == GDScriptParser::Node::TYPE_IDENTIFIER) {
-
GDScriptParser::IdentifierNode *identifier = static_cast<GDScriptParser::IdentifierNode *>(n->arguments[0]);
if (_is_class_member_property(codegen, identifier->name)) {
assign_property = identifier->name;
@@ -991,8 +1034,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
break;
}
n = static_cast<GDScriptParser::OperatorNode *>(n->arguments[0]);
- if (n->op != GDScriptParser::OperatorNode::OP_INDEX && n->op != GDScriptParser::OperatorNode::OP_INDEX_NAMED)
+ if (n->op != GDScriptParser::OperatorNode::OP_INDEX && n->op != GDScriptParser::OperatorNode::OP_INDEX_NAMED) {
break;
+ }
}
}
@@ -1000,8 +1044,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
//get at (potential) root stack pos, so it can be returned
int prev_pos = _parse_expression(codegen, chain.back()->get()->arguments[0], slevel);
- if (prev_pos < 0)
+ if (prev_pos < 0) {
return prev_pos;
+ }
int retval = prev_pos;
if (retval & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
@@ -1012,7 +1057,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
Vector<int> setchain;
if (assign_property != StringName()) {
-
// recover and assign at the end, this allows stuff like
// position.x+=2.0
// in Node2D
@@ -1022,20 +1066,18 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
}
for (List<GDScriptParser::OperatorNode *>::Element *E = chain.back(); E; E = E->prev()) {
-
- if (E == chain.front()) //ignore first
+ if (E == chain.front()) { //ignore first
break;
+ }
bool named = E->get()->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED;
int key_idx;
if (named) {
-
key_idx = codegen.get_name_map_pos(static_cast<const GDScriptParser::IdentifierNode *>(E->get()->arguments[1])->name);
//printf("named key %x\n",key_idx);
} else {
-
if (prev_pos & (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)) {
slevel++;
codegen.alloc_stack(slevel);
@@ -1048,8 +1090,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
//stack was raised here if retval was stack but..
}
- if (key_idx < 0) //error
+ if (key_idx < 0) { //error
return key_idx;
+ }
codegen.opcodes.push_back(named ? GDScriptFunction::OPCODE_GET_NAMED : GDScriptFunction::OPCODE_GET);
codegen.opcodes.push_back(prev_pos);
@@ -1076,17 +1119,16 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
bool named = false;
if (op->op == GDScriptParser::OperatorNode::OP_INDEX_NAMED) {
-
set_index = codegen.get_name_map_pos(static_cast<const GDScriptParser::IdentifierNode *>(op->arguments[1])->name);
named = true;
} else {
-
set_index = _parse_expression(codegen, op->arguments[1], slevel + 1);
named = false;
}
- if (set_index < 0) //error
+ if (set_index < 0) { //error
return set_index;
+ }
if (set_index & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
slevel++;
@@ -1094,8 +1136,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
}
int set_value = _parse_assign_right_expression(codegen, on, slevel + 1, named ? 0 : set_index);
- if (set_value < 0) //error
+ if (set_value < 0) { //error
return set_value;
+ }
codegen.opcodes.push_back(named ? GDScriptFunction::OPCODE_SET_NAMED : GDScriptFunction::OPCODE_SET);
codegen.opcodes.push_back(prev_pos);
@@ -1103,7 +1146,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.opcodes.push_back(set_value);
for (int i = 0; i < setchain.size(); i++) {
-
codegen.opcodes.push_back(setchain[i]);
}
@@ -1115,8 +1157,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int slevel = p_stack_level;
int src_address = _parse_assign_right_expression(codegen, on, slevel);
- if (src_address < 0)
+ if (src_address < 0) {
return -1;
+ }
StringName name = static_cast<GDScriptParser::IdentifierNode *>(on->arguments[0])->name;
@@ -1126,14 +1169,14 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
return GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS;
} else {
-
//REGULAR ASSIGNMENT MODE!!
int slevel = p_stack_level;
int dst_address_a = _parse_expression(codegen, on->arguments[0], slevel, false, on->op == GDScriptParser::OperatorNode::OP_INIT_ASSIGN);
- if (dst_address_a < 0)
+ if (dst_address_a < 0) {
return -1;
+ }
if (dst_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
slevel++;
@@ -1141,8 +1184,9 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
}
int src_address_b = _parse_assign_right_expression(codegen, on, slevel);
- if (src_address_b < 0)
+ if (src_address_b < 0) {
return -1;
+ }
GDScriptDataType assign_type = _gdtype_from_datatype(on->arguments[0]->get_datatype());
@@ -1158,7 +1202,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
case GDScriptDataType::NATIVE: {
int class_idx;
if (GDScriptLanguage::get_singleton()->get_global_map().has(assign_type.native_type)) {
-
class_idx = GDScriptLanguage::get_singleton()->get_global_map()[assign_type.native_type];
class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS); //argument (stack root)
} else {
@@ -1172,7 +1215,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
} break;
case GDScriptDataType::SCRIPT:
case GDScriptDataType::GDSCRIPT: {
-
Variant script = assign_type.script_type;
int idx = codegen.get_constant_pos(script);
idx |= GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS; //make it a local constant (faster access)
@@ -1201,21 +1243,23 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
}
} break;
case GDScriptParser::OperatorNode::OP_IS: {
-
ERR_FAIL_COND_V(on->arguments.size() != 2, false);
int slevel = p_stack_level;
int src_address_a = _parse_expression(codegen, on->arguments[0], slevel);
- if (src_address_a < 0)
+ if (src_address_a < 0) {
return -1;
+ }
- if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)
+ if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
slevel++; //uses stack for return, increase stack
+ }
int src_address_b = _parse_expression(codegen, on->arguments[1], slevel);
- if (src_address_b < 0)
+ if (src_address_b < 0) {
return -1;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_EXTENDS_TEST); // perform operator
codegen.opcodes.push_back(src_address_a); // argument 1
@@ -1229,11 +1273,13 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
int slevel = p_stack_level;
int src_address_a = _parse_expression(codegen, on->arguments[0], slevel);
- if (src_address_a < 0)
+ if (src_address_a < 0) {
return -1;
+ }
- if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS)
+ if (src_address_a & GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) {
slevel++; //uses stack for return, increase stack
+ }
const GDScriptParser::TypeNode *tn = static_cast<const GDScriptParser::TypeNode *>(on->arguments[1]);
@@ -1242,7 +1288,6 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
codegen.opcodes.push_back((int)tn->vtype); // argument 2 (unary only takes one parameter)
} break;
default: {
-
ERR_FAIL_V_MSG(0, "Bug in bytecode compiler, unexpected operator #" + itos(on->op) + " in parse tree while parsing expression."); //unreachable code
} break;
@@ -1255,20 +1300,17 @@ int GDScriptCompiler::_parse_expression(CodeGen &codegen, const GDScriptParser::
} break;
//TYPE_TYPE,
default: {
-
ERR_FAIL_V_MSG(-1, "Bug in bytecode compiler, unexpected node in parse tree while parsing expression."); //unreachable code
} break;
}
}
Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::BlockNode *p_block, int p_stack_level, int p_break_addr, int p_continue_addr) {
-
codegen.push_stack_identifiers();
int new_identifiers = 0;
codegen.current_line = p_block->line;
for (int i = 0; i < p_block->statements.size(); i++) {
-
const GDScriptParser::Node *s = p_block->statements[i];
switch (s->type) {
@@ -1286,7 +1328,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
const GDScriptParser::ControlFlowNode *cf = static_cast<const GDScriptParser::ControlFlowNode *>(s);
switch (cf->cf_type) {
-
case GDScriptParser::ControlFlowNode::CF_MATCH: {
GDScriptParser::MatchNode *match = cf->match;
@@ -1360,10 +1401,10 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
} break;
case GDScriptParser::ControlFlowNode::CF_IF: {
-
int ret2 = _parse_expression(codegen, cf->arguments[0], p_stack_level, false);
- if (ret2 < 0)
+ if (ret2 < 0) {
return ERR_PARSE_ERROR;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
codegen.opcodes.push_back(ret2);
@@ -1371,19 +1412,20 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
codegen.opcodes.push_back(0); //temporary
Error err = _parse_block(codegen, cf->body, p_stack_level, p_break_addr, p_continue_addr);
- if (err)
+ if (err) {
return err;
+ }
if (cf->body_else) {
-
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
int end_addr = codegen.opcodes.size();
codegen.opcodes.push_back(0);
codegen.opcodes.write[else_addr] = codegen.opcodes.size();
Error err2 = _parse_block(codegen, cf->body_else, p_stack_level, p_break_addr, p_continue_addr);
- if (err2)
+ if (err2) {
return err2;
+ }
codegen.opcodes.write[end_addr] = codegen.opcodes.size();
} else {
@@ -1393,7 +1435,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
} break;
case GDScriptParser::ControlFlowNode::CF_FOR: {
-
int slevel = p_stack_level;
int iter_stack_pos = slevel;
int iterator_pos = (slevel++) | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
@@ -1405,8 +1446,9 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
codegen.add_stack_identifier(static_cast<const GDScriptParser::IdentifierNode *>(cf->arguments[0])->name, iter_stack_pos);
int ret2 = _parse_expression(codegen, cf->arguments[1], slevel, false);
- if (ret2 < 0)
+ if (ret2 < 0) {
return ERR_COMPILATION_FAILED;
+ }
//assign container
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSIGN);
@@ -1434,8 +1476,9 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
codegen.opcodes.push_back(iterator_pos);
Error err = _parse_block(codegen, cf->body, slevel, break_pos, continue_pos);
- if (err)
+ if (err) {
return err;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
codegen.opcodes.push_back(continue_pos);
@@ -1445,7 +1488,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
} break;
case GDScriptParser::ControlFlowNode::CF_WHILE: {
-
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
codegen.opcodes.push_back(codegen.opcodes.size() + 3);
int break_addr = codegen.opcodes.size();
@@ -1454,14 +1496,16 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
int continue_addr = codegen.opcodes.size();
int ret2 = _parse_expression(codegen, cf->arguments[0], p_stack_level, false);
- if (ret2 < 0)
+ if (ret2 < 0) {
return ERR_PARSE_ERROR;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_IF_NOT);
codegen.opcodes.push_back(ret2);
codegen.opcodes.push_back(break_addr);
Error err = _parse_block(codegen, cf->body, p_stack_level, break_addr, continue_addr);
- if (err)
+ if (err) {
return err;
+ }
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP);
codegen.opcodes.push_back(continue_addr);
@@ -1469,9 +1513,7 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
} break;
case GDScriptParser::ControlFlowNode::CF_BREAK: {
-
if (p_break_addr < 0) {
-
_set_error("'break'' not within loop", cf);
return ERR_COMPILATION_FAILED;
}
@@ -1480,9 +1522,7 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
} break;
case GDScriptParser::ControlFlowNode::CF_CONTINUE: {
-
if (p_continue_addr < 0) {
-
_set_error("'continue' not within loop", cf);
return ERR_COMPILATION_FAILED;
}
@@ -1492,17 +1532,15 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
} break;
case GDScriptParser::ControlFlowNode::CF_RETURN: {
-
int ret2;
if (cf->arguments.size()) {
-
ret2 = _parse_expression(codegen, cf->arguments[0], p_stack_level, false);
- if (ret2 < 0)
+ if (ret2 < 0) {
return ERR_PARSE_ERROR;
+ }
} else {
-
ret2 = GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS;
}
@@ -1519,14 +1557,16 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
const GDScriptParser::AssertNode *as = static_cast<const GDScriptParser::AssertNode *>(s);
int ret2 = _parse_expression(codegen, as->condition, p_stack_level, false);
- if (ret2 < 0)
+ if (ret2 < 0) {
return ERR_PARSE_ERROR;
+ }
int message_ret = 0;
if (as->message) {
message_ret = _parse_expression(codegen, as->message, p_stack_level + 1, false);
- if (message_ret < 0)
+ if (message_ret < 0) {
return ERR_PARSE_ERROR;
+ }
}
codegen.opcodes.push_back(GDScriptFunction::OPCODE_ASSERT);
@@ -1541,7 +1581,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
#endif
} break;
case GDScriptParser::Node::TYPE_LOCAL_VAR: {
-
const GDScriptParser::LocalVarNode *lv = static_cast<const GDScriptParser::LocalVarNode *>(s);
// since we are using properties now for most class access, allow shadowing of class members to make user's life easier.
@@ -1559,8 +1598,9 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
default: {
//expression
int ret2 = _parse_expression(codegen, s, p_stack_level, true);
- if (ret2 < 0)
+ if (ret2 < 0) {
return ERR_PARSE_ERROR;
+ }
} break;
}
}
@@ -1569,7 +1609,6 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Blo
}
Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser::ClassNode *p_class, const GDScriptParser::FunctionNode *p_func, bool p_for_ready) {
-
Vector<int> bytecode;
CodeGen codegen;
@@ -1610,7 +1649,6 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
if (is_initializer || (p_func && String(p_func->name) == "_init")) {
//parse initializer for class members
if (!p_func && p_class->extends_used && p_script->native.is_null()) {
-
//call implicit parent constructor
codegen.opcodes.push_back(GDScriptFunction::OPCODE_CALL_SELF_BASE);
codegen.opcodes.push_back(codegen.get_name_map_pos("_init"));
@@ -1618,8 +1656,9 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
codegen.opcodes.push_back((GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS) | 0);
}
Error err = _parse_block(codegen, p_class->initializer, stack_level);
- if (err)
+ if (err) {
return err;
+ }
is_initializer = true;
}
@@ -1627,8 +1666,9 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
//parse initializer for class members
if (p_class->ready->statements.size()) {
Error err = _parse_block(codegen, p_class->ready, stack_level);
- if (err)
+ if (err) {
return err;
+ }
}
}
@@ -1638,13 +1678,10 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
StringName func_name;
if (p_func) {
-
if (p_func->default_values.size()) {
-
codegen.opcodes.push_back(GDScriptFunction::OPCODE_JUMP_TO_DEF_ARGUMENT);
defarg_addr.push_back(codegen.opcodes.size());
for (int i = 0; i < p_func->default_values.size(); i++) {
-
_parse_expression(codegen, p_func->default_values[i], stack_level, true);
defarg_addr.push_back(codegen.opcodes.size());
}
@@ -1653,15 +1690,17 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
}
Error err = _parse_block(codegen, p_func->body, stack_level);
- if (err)
+ if (err) {
return err;
+ }
func_name = p_func->name;
} else {
- if (p_for_ready)
+ if (p_for_ready) {
func_name = "_ready";
- else
+ } else {
func_name = "_init";
+ }
}
codegen.opcodes.push_back(GDScriptFunction::OPCODE_END);
@@ -1706,17 +1745,14 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
gdfunc->constants.write[idx] = *K;
}
} else {
-
gdfunc->_constants_ptr = nullptr;
gdfunc->_constant_count = 0;
}
//global names
if (codegen.name_map.size()) {
-
gdfunc->global_names.resize(codegen.name_map.size());
gdfunc->_global_names_ptr = &gdfunc->global_names[0];
for (Map<StringName, int>::Element *E = codegen.name_map.front(); E; E = E->next()) {
-
gdfunc->global_names.write[E->get()] = E->key();
}
gdfunc->_global_names_count = gdfunc->global_names.size();
@@ -1739,19 +1775,16 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
#endif
if (codegen.opcodes.size()) {
-
gdfunc->code = codegen.opcodes;
gdfunc->_code_ptr = &gdfunc->code[0];
gdfunc->_code_size = codegen.opcodes.size();
} else {
-
gdfunc->_code_ptr = nullptr;
gdfunc->_code_size = 0;
}
if (defarg_addr.size()) {
-
gdfunc->default_arguments = defarg_addr;
gdfunc->_default_arg_count = defarg_addr.size() - 1;
gdfunc->_default_arg_ptr = &gdfunc->default_arguments[0];
@@ -1768,8 +1801,9 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
if (EngineDebugger::is_active()) {
String signature;
//path
- if (p_script->get_path() != String())
+ if (p_script->get_path() != String()) {
signature += p_script->get_path();
+ }
//loc
if (p_func) {
signature += "::" + itos(p_func->body->line);
@@ -1809,17 +1843,18 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
gdfunc->_initial_line = 0;
}
- if (codegen.debug_stack)
+ if (codegen.debug_stack) {
gdfunc->stack_debug = codegen.stack_debug;
+ }
- if (is_initializer)
+ if (is_initializer) {
p_script->initializer = gdfunc;
+ }
return OK;
}
Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
-
parsing_classes.insert(p_script);
if (p_class->owner && p_class->owner->owner) {
@@ -1890,7 +1925,6 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
}
for (int i = 0; i < p_class->variables.size(); i++) {
-
StringName name = p_class->variables[i].identifier;
GDScript::MemberInfo minfo;
@@ -1905,7 +1939,6 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
PropertyInfo export_info = p_class->variables[i]._export;
if (export_info.type != Variant::NIL) {
-
if (!minfo.data_type.has_type) {
prop_info.type = export_info.type;
prop_info.class_name = export_info.class_name;
@@ -1932,7 +1965,6 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
}
for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_class->constant_expressions.front(); E; E = E->next()) {
-
StringName name = E->key();
ERR_CONTINUE(E->get().expression->type != GDScriptParser::Node::TYPE_CONSTANT);
@@ -1947,13 +1979,11 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
}
for (int i = 0; i < p_class->_signals.size(); i++) {
-
StringName name = p_class->_signals[i].name;
GDScript *c = p_script;
while (c) {
-
if (c->_signals.has(name)) {
_set_error("Signal '" + name + "' redefined (in current or parent class)", p_class);
return ERR_ALREADY_EXISTS;
@@ -1989,8 +2019,9 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
// Subclass might still be parsing, just skip it
if (!parsed_classes.has(subclass_ptr) && !parsing_classes.has(subclass_ptr)) {
Error err = _parse_class_level(subclass_ptr, p_class->subclasses[i], p_keep_state);
- if (err)
+ if (err) {
return err;
+ }
}
#ifdef TOOLS_ENABLED
@@ -2011,37 +2042,41 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa
bool has_ready = false;
for (int i = 0; i < p_class->functions.size(); i++) {
-
- if (!has_initializer && p_class->functions[i]->name == "_init")
+ if (!has_initializer && p_class->functions[i]->name == "_init") {
has_initializer = true;
- if (!has_ready && p_class->functions[i]->name == "_ready")
+ }
+ if (!has_ready && p_class->functions[i]->name == "_ready") {
has_ready = true;
+ }
Error err = _parse_function(p_script, p_class, p_class->functions[i]);
- if (err)
+ if (err) {
return err;
+ }
}
//parse static methods
for (int i = 0; i < p_class->static_functions.size(); i++) {
-
Error err = _parse_function(p_script, p_class, p_class->static_functions[i]);
- if (err)
+ if (err) {
return err;
+ }
}
if (!has_initializer) {
//create a constructor
Error err = _parse_function(p_script, p_class, nullptr);
- if (err)
+ if (err) {
return err;
+ }
}
if (!has_ready && p_class->ready->statements.size()) {
//create a constructor
Error err = _parse_function(p_script, p_class, nullptr, true);
- if (err)
+ if (err) {
return err;
+ }
}
#ifdef DEBUG_ENABLED
@@ -2050,7 +2085,6 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa
if (p_keep_state) {
for (Set<Object *>::Element *E = p_script->instances.front(); E;) {
-
Set<Object *>::Element *N = E->next();
ScriptInstance *si = E->get()->get_script_instance();
@@ -2085,7 +2119,6 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa
}
#endif
} else {
-
GDScriptInstance *gi = static_cast<GDScriptInstance *>(si);
gi->reload_members();
}
@@ -2110,7 +2143,6 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa
}
void GDScriptCompiler::_make_scripts(GDScript *p_script, const GDScriptParser::ClassNode *p_class, bool p_keep_state) {
-
Map<StringName, Ref<GDScript>> old_subclasses;
if (p_keep_state) {
@@ -2145,7 +2177,6 @@ void GDScriptCompiler::_make_scripts(GDScript *p_script, const GDScriptParser::C
}
Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_script, bool p_keep_state) {
-
err_line = -1;
err_column = -1;
error = "";
@@ -2165,27 +2196,28 @@ Error GDScriptCompiler::compile(const GDScriptParser *p_parser, GDScript *p_scri
p_script->_owner = nullptr;
Error err = _parse_class_level(p_script, static_cast<const GDScriptParser::ClassNode *>(root), p_keep_state);
- if (err)
+ if (err) {
return err;
+ }
err = _parse_class_blocks(p_script, static_cast<const GDScriptParser::ClassNode *>(root), p_keep_state);
- if (err)
+ if (err) {
return err;
+ }
return OK;
}
String GDScriptCompiler::get_error() const {
-
return error;
}
-int GDScriptCompiler::get_error_line() const {
+int GDScriptCompiler::get_error_line() const {
return err_line;
}
-int GDScriptCompiler::get_error_column() const {
+int GDScriptCompiler::get_error_column() const {
return err_column;
}
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index 34b066b5c7..315d4f1842 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -36,13 +36,11 @@
#include "gdscript_parser.h"
class GDScriptCompiler {
-
const GDScriptParser *parser;
Set<GDScript *> parsed_classes;
Set<GDScript *> parsing_classes;
GDScript *main_script;
struct CodeGen {
-
GDScript *script;
const GDScriptParser::ClassNode *class_node;
const GDScriptParser::FunctionNode *function_node;
@@ -71,7 +69,6 @@ class GDScriptCompiler {
void push_stack_identifiers() {
stack_id_stack.push_back(stack_identifiers);
if (debug_stack) {
-
block_identifier_stack.push_back(block_identifiers);
block_identifiers.clear();
}
@@ -83,7 +80,6 @@ class GDScriptCompiler {
if (debug_stack) {
for (Map<StringName, int>::Element *E = block_identifiers.front(); E; E = E->next()) {
-
GDScriptFunction::StackDebug sd;
sd.added = false;
sd.identifier = E->key();
@@ -114,8 +110,9 @@ class GDScriptCompiler {
}
int get_constant_pos(const Variant &p_constant) {
- if (constant_map.has(p_constant))
+ if (constant_map.has(p_constant)) {
return constant_map[p_constant];
+ }
int pos = constant_map.size();
constant_map[p_constant] = pos;
return pos;
@@ -123,10 +120,14 @@ class GDScriptCompiler {
Vector<int> opcodes;
void alloc_stack(int p_level) {
- if (p_level >= stack_max) stack_max = p_level + 1;
+ if (p_level >= stack_max) {
+ stack_max = p_level + 1;
+ }
}
void alloc_call(int p_params) {
- if (p_params >= call_max) call_max = p_params;
+ if (p_params >= call_max) {
+ call_max = p_params;
+ }
}
int current_line;
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 2ec3352e70..7433c4a5bc 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -41,19 +41,16 @@
#endif
void GDScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
-
p_delimiters->push_back("#");
}
void GDScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const {
-
p_delimiters->push_back("\" \"");
p_delimiters->push_back("' '");
p_delimiters->push_back("\"\"\" \"\"\"");
}
String GDScriptLanguage::_get_processed_template(const String &p_template, const String &p_base_class_name) const {
-
String processed_template = p_template;
#ifdef TOOLS_ENABLED
@@ -109,18 +106,15 @@ Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const Str
}
bool GDScriptLanguage::is_using_templates() {
-
return true;
}
void GDScriptLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
-
String _template = _get_processed_template(p_script->get_source_code(), p_base_class_name);
p_script->set_source_code(_template);
}
bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
-
GDScriptParser parser;
Error err = parser.parse(p_script, p_path.get_base_dir(), true, p_path, false, r_safe_lines);
@@ -143,35 +137,29 @@ bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int &
r_test_error = parser.get_error();
return false;
} else {
-
const GDScriptParser::Node *root = parser.get_parse_tree();
ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, false);
const GDScriptParser::ClassNode *cl = static_cast<const GDScriptParser::ClassNode *>(root);
Map<int, String> funcs;
for (int i = 0; i < cl->functions.size(); i++) {
-
funcs[cl->functions[i]->line] = cl->functions[i]->name;
}
for (int i = 0; i < cl->static_functions.size(); i++) {
-
funcs[cl->static_functions[i]->line] = cl->static_functions[i]->name;
}
for (int i = 0; i < cl->subclasses.size(); i++) {
for (int j = 0; j < cl->subclasses[i]->functions.size(); j++) {
-
funcs[cl->subclasses[i]->functions[j]->line] = String(cl->subclasses[i]->name) + "." + cl->subclasses[i]->functions[j]->name;
}
for (int j = 0; j < cl->subclasses[i]->static_functions.size(); j++) {
-
funcs[cl->subclasses[i]->static_functions[j]->line] = String(cl->subclasses[i]->name) + "." + cl->subclasses[i]->static_functions[j]->name;
}
}
for (Map<int, String>::Element *E = funcs.front(); E; E = E->next()) {
-
r_functions->push_back(E->get() + ":" + itos(E->key()));
}
}
@@ -180,27 +168,22 @@ bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int &
}
bool GDScriptLanguage::has_named_classes() const {
-
return false;
}
bool GDScriptLanguage::supports_builtin_mode() const {
-
return true;
}
int GDScriptLanguage::find_function(const String &p_function, const String &p_code) const {
-
GDScriptTokenizerText tokenizer;
tokenizer.set_code(p_code);
int indent = 0;
while (tokenizer.get_token() != GDScriptTokenizer::TK_EOF && tokenizer.get_token() != GDScriptTokenizer::TK_ERROR) {
-
if (tokenizer.get_token() == GDScriptTokenizer::TK_NEWLINE) {
indent = tokenizer.get_token_line_indent();
}
if (indent == 0 && tokenizer.get_token() == GDScriptTokenizer::TK_PR_FUNCTION && tokenizer.get_token(1) == GDScriptTokenizer::TK_IDENTIFIER) {
-
String identifier = tokenizer.get_token_identifier(1);
if (identifier == p_function) {
return tokenizer.get_token_line();
@@ -212,7 +195,6 @@ int GDScriptLanguage::find_function(const String &p_function, const String &p_co
}
Script *GDScriptLanguage::create_script() const {
-
return memnew(GDScript);
}
@@ -222,7 +204,6 @@ bool GDScriptLanguage::debug_break_parse(const String &p_file, int p_line, const
//break because of parse error
if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
-
_debug_parse_err_line = p_line;
_debug_parse_err_file = p_file;
_debug_error = p_error;
@@ -234,9 +215,7 @@ bool GDScriptLanguage::debug_break_parse(const String &p_file, int p_line, const
}
bool GDScriptLanguage::debug_break(const String &p_error, bool p_allow_continue) {
-
if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
-
_debug_parse_err_line = -1;
_debug_parse_err_file = "";
_debug_error = p_error;
@@ -249,21 +228,21 @@ bool GDScriptLanguage::debug_break(const String &p_error, bool p_allow_continue)
}
String GDScriptLanguage::debug_get_error() const {
-
return _debug_error;
}
int GDScriptLanguage::debug_get_stack_level_count() const {
-
- if (_debug_parse_err_line >= 0)
+ if (_debug_parse_err_line >= 0) {
return 1;
+ }
return _debug_call_stack_pos;
}
-int GDScriptLanguage::debug_get_stack_level_line(int p_level) const {
- if (_debug_parse_err_line >= 0)
+int GDScriptLanguage::debug_get_stack_level_line(int p_level) const {
+ if (_debug_parse_err_line >= 0) {
return _debug_parse_err_line;
+ }
ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, -1);
@@ -271,28 +250,31 @@ int GDScriptLanguage::debug_get_stack_level_line(int p_level) const {
return *(_call_stack[l].line);
}
-String GDScriptLanguage::debug_get_stack_level_function(int p_level) const {
- if (_debug_parse_err_line >= 0)
+String GDScriptLanguage::debug_get_stack_level_function(int p_level) const {
+ if (_debug_parse_err_line >= 0) {
return "";
+ }
ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, "");
int l = _debug_call_stack_pos - p_level - 1;
return _call_stack[l].function->get_name();
}
-String GDScriptLanguage::debug_get_stack_level_source(int p_level) const {
- if (_debug_parse_err_line >= 0)
+String GDScriptLanguage::debug_get_stack_level_source(int p_level) const {
+ if (_debug_parse_err_line >= 0) {
return _debug_parse_err_file;
+ }
ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, "");
int l = _debug_call_stack_pos - p_level - 1;
return _call_stack[l].function->get_source();
}
-void GDScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
- if (_debug_parse_err_line >= 0)
+void GDScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
+ if (_debug_parse_err_line >= 0) {
return;
+ }
ERR_FAIL_INDEX(p_level, _debug_call_stack_pos);
int l = _debug_call_stack_pos - p_level - 1;
@@ -303,23 +285,24 @@ void GDScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p
f->debug_get_stack_member_state(*_call_stack[l].line, &locals);
for (List<Pair<StringName, int>>::Element *E = locals.front(); E; E = E->next()) {
-
p_locals->push_back(E->get().first);
p_values->push_back(_call_stack[l].stack[E->get().second]);
}
}
-void GDScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
- if (_debug_parse_err_line >= 0)
+void GDScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
+ if (_debug_parse_err_line >= 0) {
return;
+ }
ERR_FAIL_INDEX(p_level, _debug_call_stack_pos);
int l = _debug_call_stack_pos - p_level - 1;
GDScriptInstance *instance = _call_stack[l].instance;
- if (!instance)
+ if (!instance) {
return;
+ }
Ref<GDScript> script = instance->get_script();
ERR_FAIL_COND(script.is_null());
@@ -327,16 +310,15 @@ void GDScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *
const Map<StringName, GDScript::MemberInfo> &mi = script->debug_get_member_indices();
for (const Map<StringName, GDScript::MemberInfo>::Element *E = mi.front(); E; E = E->next()) {
-
p_members->push_back(E->key());
p_values->push_back(instance->debug_get_member_by_index(E->get().index));
}
}
ScriptInstance *GDScriptLanguage::debug_get_stack_level_instance(int p_level) {
-
- if (_debug_parse_err_line >= 0)
+ if (_debug_parse_err_line >= 0) {
return nullptr;
+ }
ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, nullptr);
@@ -347,7 +329,6 @@ ScriptInstance *GDScriptLanguage::debug_get_stack_level_instance(int p_level) {
}
void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
-
const Map<StringName, int> &name_idx = GDScriptLanguage::get_singleton()->get_global_map();
const Variant *globals = GDScriptLanguage::get_singleton()->get_global_array();
@@ -355,9 +336,9 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant>
get_public_constants(&cinfo);
for (const Map<StringName, int>::Element *E = name_idx.front(); E; E = E->next()) {
-
- if (ClassDB::class_exists(E->key()) || Engine::get_singleton()->has_singleton(E->key()))
+ if (ClassDB::class_exists(E->key()) || Engine::get_singleton()->has_singleton(E->key())) {
continue;
+ }
bool is_script_constant = false;
for (List<Pair<String, Variant>>::Element *CE = cinfo.front(); CE; CE = CE->next()) {
@@ -366,13 +347,15 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant>
break;
}
}
- if (is_script_constant)
+ if (is_script_constant) {
continue;
+ }
const Variant &var = globals[E->value()];
if (Object *obj = var) {
- if (Object::cast_to<GDScriptNativeClass>(obj))
+ if (Object::cast_to<GDScriptNativeClass>(obj)) {
continue;
+ }
}
bool skip = false;
@@ -382,8 +365,9 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant>
break;
}
}
- if (skip)
+ if (skip) {
continue;
+ }
p_globals->push_back(E->key());
p_values->push_back(var);
@@ -391,19 +375,15 @@ void GDScriptLanguage::debug_get_globals(List<String> *p_globals, List<Variant>
}
String GDScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
-
return "";
}
void GDScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("gd");
}
void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const {
-
for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) {
-
p_functions->push_back(GDScriptFunctions::get_info(GDScriptFunctions::Function(i)));
}
@@ -437,7 +417,6 @@ void GDScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const
}
void GDScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const {
-
Pair<String, Variant> pi;
pi.first = "PI";
pi.second = Math_PI;
@@ -460,7 +439,6 @@ void GDScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_const
}
String GDScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const {
-
#ifdef TOOLS_ENABLED
bool th = EditorSettings::get_singleton()->get_setting("text_editor/completion/add_type_hints");
#else
@@ -470,8 +448,9 @@ String GDScriptLanguage::make_function(const String &p_class, const String &p_na
String s = "func " + p_name + "(";
if (p_args.size()) {
for (int i = 0; i < p_args.size(); i++) {
- if (i > 0)
+ if (i > 0) {
s += ", ";
+ }
s += p_args[i].get_slice(":", 0);
if (th) {
String type = p_args[i].get_slice(":", 1);
@@ -491,36 +470,27 @@ String GDScriptLanguage::make_function(const String &p_class, const String &p_na
#if defined(DEBUG_METHODS_ENABLED) && defined(TOOLS_ENABLED)
struct GDScriptCompletionContext {
-
- const GDScriptParser::ClassNode *_class;
- const GDScriptParser::FunctionNode *function;
- const GDScriptParser::BlockNode *block;
- Object *base;
+ const GDScriptParser::ClassNode *_class = nullptr;
+ const GDScriptParser::FunctionNode *function = nullptr;
+ const GDScriptParser::BlockNode *block = nullptr;
+ Object *base = nullptr;
String base_path;
- int line;
- uint32_t depth;
-
- GDScriptCompletionContext() :
- _class(nullptr),
- function(nullptr),
- block(nullptr),
- base(nullptr),
- line(0),
- depth(0) {}
+ int line = 0;
+ uint32_t depth = 0;
+
+ GDScriptCompletionContext() {}
};
struct GDScriptCompletionIdentifier {
GDScriptParser::DataType type;
String enumeration;
Variant value;
- const GDScriptParser::Node *assigned_expression;
+ const GDScriptParser::Node *assigned_expression = nullptr;
- GDScriptCompletionIdentifier() :
- assigned_expression(nullptr) {}
+ GDScriptCompletionIdentifier() {}
};
static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String, ScriptCodeCompletionOption> &r_list) {
-
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
for (int i = 0; i < p_dir->get_file_count(); i++) {
@@ -535,7 +505,6 @@ static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String
}
static String _get_visual_datatype(const PropertyInfo &p_info, bool p_isarg = true) {
-
if (p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
String enum_name = p_info.class_name;
if (enum_name.find(".") == -1) {
@@ -835,7 +804,6 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G
Object *baseptr = base.value;
if (all_is_const && String(id) == "get_node" && ClassDB::is_parent_class(native_type.native_type, "Node") && args.size()) {
-
String arg1 = args[0];
if (arg1.begins_with("/root/")) {
String which = arg1.get_slice("/", 2);
@@ -849,7 +817,6 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G
ProjectSettings::get_singleton()->get_property_list(&props);
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
String s = E->get().name;
if (!s.begins_with("autoload/")) {
continue;
@@ -1082,16 +1049,36 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G
Variant::Operator vop = Variant::OP_MAX;
switch (op->op) {
- case GDScriptParser::OperatorNode::OP_ADD: vop = Variant::OP_ADD; break;
- case GDScriptParser::OperatorNode::OP_SUB: vop = Variant::OP_SUBTRACT; break;
- case GDScriptParser::OperatorNode::OP_MUL: vop = Variant::OP_MULTIPLY; break;
- case GDScriptParser::OperatorNode::OP_DIV: vop = Variant::OP_DIVIDE; break;
- case GDScriptParser::OperatorNode::OP_MOD: vop = Variant::OP_MODULE; break;
- case GDScriptParser::OperatorNode::OP_SHIFT_LEFT: vop = Variant::OP_SHIFT_LEFT; break;
- case GDScriptParser::OperatorNode::OP_SHIFT_RIGHT: vop = Variant::OP_SHIFT_RIGHT; break;
- case GDScriptParser::OperatorNode::OP_BIT_AND: vop = Variant::OP_BIT_AND; break;
- case GDScriptParser::OperatorNode::OP_BIT_OR: vop = Variant::OP_BIT_OR; break;
- case GDScriptParser::OperatorNode::OP_BIT_XOR: vop = Variant::OP_BIT_XOR; break;
+ case GDScriptParser::OperatorNode::OP_ADD:
+ vop = Variant::OP_ADD;
+ break;
+ case GDScriptParser::OperatorNode::OP_SUB:
+ vop = Variant::OP_SUBTRACT;
+ break;
+ case GDScriptParser::OperatorNode::OP_MUL:
+ vop = Variant::OP_MULTIPLY;
+ break;
+ case GDScriptParser::OperatorNode::OP_DIV:
+ vop = Variant::OP_DIVIDE;
+ break;
+ case GDScriptParser::OperatorNode::OP_MOD:
+ vop = Variant::OP_MODULE;
+ break;
+ case GDScriptParser::OperatorNode::OP_SHIFT_LEFT:
+ vop = Variant::OP_SHIFT_LEFT;
+ break;
+ case GDScriptParser::OperatorNode::OP_SHIFT_RIGHT:
+ vop = Variant::OP_SHIFT_RIGHT;
+ break;
+ case GDScriptParser::OperatorNode::OP_BIT_AND:
+ vop = Variant::OP_BIT_AND;
+ break;
+ case GDScriptParser::OperatorNode::OP_BIT_OR:
+ vop = Variant::OP_BIT_OR;
+ break;
+ case GDScriptParser::OperatorNode::OP_BIT_XOR:
+ vop = Variant::OP_BIT_XOR;
+ break;
default: {
}
}
@@ -1171,7 +1158,6 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G
}
static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
-
// Look in blocks first
const GDScriptParser::BlockNode *blk = p_context.block;
int last_assign_line = -1;
@@ -1427,6 +1413,7 @@ static bool _guess_identifier_type_from_base(GDScriptCompletionContext &p_contex
// Variable used in the same expression
return false;
}
+
if (_guess_expression_type(p_context, m.expression, r_type)) {
return true;
}
@@ -1732,7 +1719,6 @@ static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_con
}
static String _make_arguments_hint(const MethodInfo &p_info, int p_arg_idx) {
-
String arghint = _get_visual_datatype(p_info.return_val, false) + " " + p_info.name + "(";
int def_args = p_info.arguments.size() - p_info.default_arguments.size();
@@ -1777,7 +1763,6 @@ static String _make_arguments_hint(const MethodInfo &p_info, int p_arg_idx) {
}
static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_function, int p_arg_idx) {
-
String arghint = p_function->return_type.to_string() + " " + p_function->name.operator String() + "(";
int def_args = p_function->arguments.size() - p_function->default_values.size();
@@ -1819,7 +1804,6 @@ static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_functio
}
static void _find_enumeration_candidates(const String p_enum_hint, Map<String, ScriptCodeCompletionOption> &r_result) {
-
if (p_enum_hint.find(".") == -1) {
// Global constant
StringName current_enum = p_enum_hint;
@@ -2057,7 +2041,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
List<PropertyInfo> pinfo;
ClassDB::get_property_list(type, &pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
- if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)) {
+ if (E->get().usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_CATEGORY)) {
continue;
}
if (E->get().name.find("/") != -1) {
@@ -2098,7 +2082,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
if (!p_only_functions) {
List<PropertyInfo> members;
- p_base.value.get_property_list(&members);
+ tmp.get_property_list(&members);
for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) {
if (String(E->get().name).find("/") == -1) {
@@ -2130,11 +2114,9 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context
}
static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result) {
-
const GDScriptParser::BlockNode *block = p_context.block;
if (p_context.function) {
-
const GDScriptParser::FunctionNode *f = p_context.function;
for (int i = 0; i < f->arguments.size(); i++) {
@@ -2150,7 +2132,7 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p
}
const GDScriptParser::ClassNode *clss = p_context._class;
- bool _static = !p_context.function || p_context.function->_static;
+ bool _static = p_context.function && p_context.function->_static;
while (clss) {
GDScriptCompletionContext c = p_context;
@@ -2403,7 +2385,6 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
}
static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Map<String, ScriptCodeCompletionOption> &r_result, bool &r_forced, String &r_arghint) {
-
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
if (!p_node || p_node->type != GDScriptParser::Node::TYPE_OPERATOR) {
@@ -2459,7 +2440,6 @@ static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDS
}
return;
} else if (op->arguments[0]->type == GDScriptParser::Node::TYPE_SELF) {
-
if (op->arguments.size() < 2 || op->arguments[1]->type != GDScriptParser::Node::TYPE_IDENTIFIER) {
return;
}
@@ -2533,7 +2513,6 @@ static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDS
}
Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) {
-
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\"";
GDScriptParser parser;
@@ -2581,7 +2560,6 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
p_owner->get_argument_options("get_node", 0, &opts);
for (List<String>::Element *E = opts.front(); E; E = E->next()) {
-
String opt = E->get().strip_edges();
if (opt.is_quoted()) {
r_forced = true;
@@ -2689,7 +2667,6 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
List<MethodInfo> virtual_methods;
ClassDB::get_virtual_methods(class_name, &virtual_methods);
for (List<MethodInfo>::Element *E = virtual_methods.front(); E; E = E->next()) {
-
MethodInfo &mi = E->get();
String method_hint = mi.name;
if (method_hint.find(":") != -1) {
@@ -3013,19 +2990,16 @@ String GDScriptLanguage::_get_indentation() const {
}
void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {
-
String indent = _get_indentation();
Vector<String> lines = p_code.split("\n");
List<int> indent_stack;
for (int i = 0; i < lines.size(); i++) {
-
String l = lines[i];
int tc = 0;
for (int j = 0; j < l.length(); j++) {
if (l[j] == ' ' || l[j] == '\t') {
-
tc++;
} else {
break;
@@ -3033,8 +3007,9 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t
}
String st = l.substr(tc, l.length()).strip_edges();
- if (st == "" || st.begins_with("#"))
+ if (st == "" || st.begins_with("#")) {
continue; //ignore!
+ }
int ilevel = 0;
if (indent_stack.size()) {
@@ -3048,12 +3023,12 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t
indent_stack.pop_back();
}
- if (indent_stack.size() && indent_stack.back()->get() != tc)
+ if (indent_stack.size() && indent_stack.back()->get() != tc) {
indent_stack.push_back(tc); //this is not right but gets the job done
+ }
}
if (i >= p_from_line) {
-
l = "";
for (int j = 0; j < indent_stack.size(); j++) {
l += indent;
@@ -3069,8 +3044,9 @@ void GDScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_t
p_code = "";
for (int i = 0; i < lines.size(); i++) {
- if (i > 0)
+ if (i > 0) {
p_code += "\n";
+ }
p_code += lines[i];
}
}
@@ -3257,7 +3233,6 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
}
Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result) {
-
//before parsing, try the usual stuff
if (ClassDB::class_exists(p_symbol)) {
r_result.type = ScriptLanguage::LookupResult::RESULT_CLASS;
@@ -3338,7 +3313,6 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
[[fallthrough]];
}
case GDScriptParser::COMPLETION_IDENTIFIER: {
-
if (!is_function) {
is_function = parser.get_completion_identifier_is_function();
}
@@ -3390,13 +3364,12 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
ProjectSettings::get_singleton()->get_property_list(&props);
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
String s = E->get().name;
- if (!s.begins_with("autoload/"))
+ if (!s.begins_with("autoload/")) {
continue;
+ }
String name = s.get_slice("/", 1);
if (name == String(p_symbol)) {
-
String path = ProjectSettings::get_singleton()->get(s);
if (path.begins_with("*")) {
String script = path.substr(1, path.length());
@@ -3408,7 +3381,6 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
}
if (FileAccess::exists(script)) {
-
r_result.type = ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION;
r_result.location = 0;
r_result.script = ResourceLoader::load(script);
@@ -3490,6 +3462,16 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol
return OK;
}
} break;
+ case GDScriptParser::COMPLETION_TYPE_HINT: {
+ GDScriptParser::DataType base_type = context._class->base_type;
+ base_type.has_type = true;
+ base_type.kind = GDScriptParser::DataType::CLASS;
+ base_type.class_type = const_cast<GDScriptParser::ClassNode *>(context._class);
+
+ if (_lookup_symbol_from_base(base_type, p_symbol, false, r_result) == OK) {
+ return OK;
+ }
+ } break;
default: {
}
}
diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp
index ca4d6f6de9..fc0c4b3138 100644
--- a/modules/gdscript/gdscript_function.cpp
+++ b/modules/gdscript/gdscript_function.cpp
@@ -35,12 +35,10 @@
#include "gdscript_functions.h"
Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const {
-
int address = p_address & ADDR_MASK;
//sequential table (jump table generated by compiler)
switch ((p_address & ADDR_TYPE_MASK) >> ADDR_BITS) {
-
case ADDR_TYPE_SELF: {
#ifdef DEBUG_ENABLED
if (unlikely(!p_instance)) {
@@ -51,7 +49,6 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
return &self;
} break;
case ADDR_TYPE_CLASS: {
-
return &static_ref;
} break;
case ADDR_TYPE_MEMBER: {
@@ -65,7 +62,6 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
return &p_instance->members.write[address];
} break;
case ADDR_TYPE_CLASS_CONSTANT: {
-
//todo change to index!
GDScript *s = p_script;
#ifdef DEBUG_ENABLED
@@ -76,7 +72,6 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
while (s) {
GDScript *o = s;
while (o) {
-
Map<StringName, Variant>::Element *E = o->constants.find(*sn);
if (E) {
return &E->get();
@@ -133,7 +128,6 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
#ifdef DEBUG_ENABLED
static String _get_var_type(const Variant *p_var) {
-
String basestr;
if (p_var->get_type() == Variant::OBJECT) {
@@ -146,10 +140,11 @@ static String _get_var_type(const Variant *p_var) {
basestr = "previously freed";
}
} else {
- if (bobj->get_script_instance())
+ if (bobj->get_script_instance()) {
basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")";
- else
+ } else {
basestr = bobj->get_class();
+ }
}
} else {
@@ -161,7 +156,6 @@ static String _get_var_type(const Variant *p_var) {
#endif // DEBUG_ENABLED
String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const {
-
String err_text;
if (p_err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) {
@@ -259,11 +253,9 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const
#endif
Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Callable::CallError &r_err, CallState *p_state) {
-
OPCODES_TABLE;
if (!_code_ptr) {
-
return Variant();
}
@@ -294,29 +286,23 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
line = p_state->line;
ip = p_state->ip;
alloca_size = p_state->stack.size();
- script = p_state->script.ptr();
+ script = p_state->script;
p_instance = p_state->instance;
defarg = p_state->defarg;
self = p_state->self;
- //stack[p_state->result_pos]=p_state->result; //assign stack with result
} else {
-
if (p_argcount != _argument_count) {
-
if (p_argcount > _argument_count) {
-
r_err.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_err.argument = _argument_count;
return Variant();
} else if (p_argcount < _argument_count - _default_arg_count) {
-
r_err.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_err.argument = _argument_count - _default_arg_count;
return Variant();
} else {
-
defarg = _argument_count - p_argcount;
}
}
@@ -324,11 +310,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
alloca_size = sizeof(Variant *) * _call_size + sizeof(Variant) * _stack_size;
if (alloca_size) {
-
uint8_t *aptr = (uint8_t *)alloca(alloca_size);
if (_stack_size) {
-
stack = (Variant *)aptr;
for (int i = 0; i < p_argcount; i++) {
if (!argument_types[i].has_type) {
@@ -337,15 +321,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
if (!argument_types[i].is_type(*p_args[i], true)) {
- if (argument_types[i].is_type(Variant(), true)) {
- memnew_placement(&stack[i], Variant);
- continue;
- } else {
- r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_err.argument = i;
- r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
- return Variant();
- }
+ r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_err.argument = i;
+ r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
+ return Variant();
}
if (argument_types[i].kind == GDScriptDataType::BUILTIN) {
Variant arg = Variant::construct(argument_types[i].builtin_type, &p_args[i], 1, r_err);
@@ -362,10 +341,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
if (_call_size) {
-
call_args = (Variant **)&aptr[sizeof(Variant) * _stack_size];
} else {
-
call_args = nullptr;
}
@@ -376,7 +353,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
if (p_instance) {
if (p_instance->base_ref && static_cast<Reference *>(p_instance->owner)->is_referenced()) {
-
self = REF(static_cast<Reference *>(p_instance->owner));
} else {
self = p_instance->owner;
@@ -391,8 +367,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
- if (EngineDebugger::is_active())
+ if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->enter_function(p_instance, this, stack, &ip, &line);
+ }
#define GD_ERR_BREAK(m_cond) \
{ \
@@ -443,9 +420,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#endif
OPCODE_SWITCH(_code_ptr[ip]) {
-
OPCODE(OPCODE_OPERATOR) {
-
CHECK_SPACE(5);
bool valid;
@@ -465,7 +440,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#endif
#ifdef DEBUG_ENABLED
if (!valid) {
-
if (ret.get_type() == Variant::STRING) {
//return a string when invalid with the error
err_text = ret;
@@ -482,7 +456,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_EXTENDS_TEST) {
-
CHECK_SPACE(4);
GET_VARIANT_PTR(a, 1);
@@ -491,7 +464,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (b->get_type() != Variant::OBJECT || b->operator Object *() == nullptr) {
-
err_text = "Right operand of 'is' is not a class.";
OPCODE_BREAK;
}
@@ -499,7 +471,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
bool extends_ok = false;
if (a->get_type() == Variant::OBJECT && a->operator Object *() != nullptr) {
-
#ifdef DEBUG_ENABLED
bool was_freed;
Object *obj_A = a->get_validated_object_with_check(was_freed);
@@ -528,11 +499,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
//in other situation, this shoul return false.
if (obj_A->get_script_instance() && obj_A->get_script_instance()->get_language() == GDScriptLanguage::get_singleton()) {
-
GDScript *cmp = static_cast<GDScript *>(obj_A->get_script_instance()->get_script().ptr());
//bool found=false;
while (cmp) {
-
if (cmp == scr_B) {
//inherits from script, all ok
extends_ok = true;
@@ -544,12 +513,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
} else {
-
GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(obj_B);
#ifdef DEBUG_ENABLED
if (!nc) {
-
err_text = "Right operand of 'is' is not a class (type: '" + obj_B->get_class() + "').";
OPCODE_BREAK;
}
@@ -564,7 +531,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_IS_BUILTIN) {
-
CHECK_SPACE(4);
GET_VARIANT_PTR(value, 1);
@@ -579,7 +545,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_SET) {
-
CHECK_SPACE(3);
GET_VARIANT_PTR(dst, 1);
@@ -606,7 +571,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_GET) {
-
CHECK_SPACE(3);
GET_VARIANT_PTR(src, 1);
@@ -639,7 +603,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_SET_NAMED) {
-
CHECK_SPACE(3);
GET_VARIANT_PTR(dst, 1);
@@ -665,7 +628,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_GET_NAMED) {
-
CHECK_SPACE(4);
GET_VARIANT_PTR(src, 1);
@@ -700,7 +662,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_SET_MEMBER) {
-
CHECK_SPACE(3);
int indexname = _code_ptr[ip + 1];
GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count);
@@ -725,7 +686,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_GET_MEMBER) {
-
CHECK_SPACE(3);
int indexname = _code_ptr[ip + 1];
GD_ERR_BREAK(indexname < 0 || indexname >= _global_names_count);
@@ -746,7 +706,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_ASSIGN) {
-
CHECK_SPACE(3);
GET_VARIANT_PTR(dst, 1);
GET_VARIANT_PTR(src, 2);
@@ -758,7 +717,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_ASSIGN_TRUE) {
-
CHECK_SPACE(2);
GET_VARIANT_PTR(dst, 1);
@@ -769,7 +727,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_ASSIGN_FALSE) {
-
CHECK_SPACE(2);
GET_VARIANT_PTR(dst, 1);
@@ -780,7 +737,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_ASSIGN_TYPED_BUILTIN) {
-
CHECK_SPACE(4);
GET_VARIANT_PTR(dst, 2);
GET_VARIANT_PTR(src, 3);
@@ -810,7 +766,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_ASSIGN_TYPED_NATIVE) {
-
CHECK_SPACE(4);
GET_VARIANT_PTR(dst, 2);
GET_VARIANT_PTR(src, 3);
@@ -839,7 +794,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_ASSIGN_TYPED_SCRIPT) {
-
CHECK_SPACE(4);
GET_VARIANT_PTR(dst, 2);
GET_VARIANT_PTR(src, 3);
@@ -856,7 +810,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
if (src->get_type() != Variant::NIL && src->operator Object *() != nullptr) {
-
ScriptInstance *scr_inst = src->operator Object *()->get_script_instance();
if (!scr_inst) {
err_text = "Trying to assign value of type '" + src->operator Object *()->get_class_name() +
@@ -890,7 +843,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_CAST_TO_BUILTIN) {
-
CHECK_SPACE(4);
Variant::Type to_type = (Variant::Type)_code_ptr[ip + 1];
GET_VARIANT_PTR(src, 2);
@@ -913,7 +865,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_CAST_TO_NATIVE) {
-
CHECK_SPACE(4);
GET_VARIANT_PTR(to_type, 1);
GET_VARIANT_PTR(src, 2);
@@ -941,7 +892,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_CAST_TO_SCRIPT) {
-
CHECK_SPACE(4);
GET_VARIANT_PTR(to_type, 1);
GET_VARIANT_PTR(src, 2);
@@ -961,11 +911,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
bool valid = false;
if (src->get_type() != Variant::NIL && src->operator Object *() != nullptr) {
-
ScriptInstance *scr_inst = src->operator Object *()->get_script_instance();
if (scr_inst) {
-
Script *src_type = src->operator Object *()->get_script_instance()->get_script().ptr();
while (src_type) {
@@ -989,7 +937,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_CONSTRUCT) {
-
CHECK_SPACE(2);
Variant::Type t = Variant::Type(_code_ptr[ip + 1]);
int argc = _code_ptr[ip + 2];
@@ -1006,7 +953,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (err.error != Callable::CallError::CALL_OK) {
-
err_text = _get_call_error(err, "'" + Variant::get_type_name(t) + "' constructor", (const Variant **)argptrs);
OPCODE_BREAK;
}
@@ -1018,7 +964,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_CONSTRUCT_ARRAY) {
-
CHECK_SPACE(1);
int argc = _code_ptr[ip + 1];
Array array; //arrays are always shared
@@ -1039,7 +984,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_CONSTRUCT_DICTIONARY) {
-
CHECK_SPACE(1);
int argc = _code_ptr[ip + 1];
Dictionary dict; //arrays are always shared
@@ -1047,7 +991,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
CHECK_SPACE(argc * 2 + 2);
for (int i = 0; i < argc; i++) {
-
GET_VARIANT_PTR(k, 2 + i * 2 + 0);
GET_VARIANT_PTR(v, 2 + i * 2 + 1);
dict[*k] = *v;
@@ -1063,7 +1006,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE(OPCODE_CALL_RETURN)
OPCODE(OPCODE_CALL) {
-
CHECK_SPACE(4);
bool call_ret = _code_ptr[ip] == OPCODE_CALL_RETURN;
@@ -1094,11 +1036,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#endif
Callable::CallError err;
if (call_ret) {
-
GET_VARIANT_PTR(ret, argc);
base->call_ptr(*methodname, (const Variant **)argptrs, argc, ret, err);
} else {
-
base->call_ptr(*methodname, (const Variant **)argptrs, argc, nullptr, err);
}
#ifdef DEBUG_ENABLED
@@ -1107,7 +1047,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
if (err.error != Callable::CallError::CALL_OK) {
-
String methodstr = *methodname;
String basestr = _get_var_type(base);
@@ -1119,14 +1058,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
}
} else if (methodstr == "free") {
-
if (err.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) {
-
if (base->is_ref()) {
err_text = "Attempted to free a reference.";
OPCODE_BREAK;
} else if (base->get_type() == Variant::OBJECT) {
-
err_text = "Attempted to free a locked object (calling or emitting).";
OPCODE_BREAK;
}
@@ -1143,7 +1079,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_CALL_BUILT_IN) {
-
CHECK_SPACE(4);
GDScriptFunctions::Function func = GDScriptFunctions::Function(_code_ptr[ip + 1]);
@@ -1167,7 +1102,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
if (err.error != Callable::CallError::CALL_OK) {
-
String methodstr = GDScriptFunctions::get_func_name(func);
if (dst->get_type() == Variant::STRING) {
//call provided error string
@@ -1183,18 +1117,15 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_CALL_SELF) {
-
OPCODE_BREAK;
}
OPCODE(OPCODE_CALL_SELF_BASE) {
-
CHECK_SPACE(2);
int self_fun = _code_ptr[ip + 1];
#ifdef DEBUG_ENABLED
if (self_fun < 0 || self_fun >= _global_names_count) {
-
err_text = "compiler bug, function name not found";
OPCODE_BREAK;
}
@@ -1220,19 +1151,17 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
while (gds->base.ptr()) {
gds = gds->base.ptr();
E = gds->member_functions.find(*methodname);
- if (E)
+ if (E) {
break;
+ }
}
Callable::CallError err;
if (E) {
-
*dst = E->get()->call(p_instance, (const Variant **)argptrs, argc, err);
} else if (gds->native.ptr()) {
-
if (*methodname != GDScriptLanguage::get_singleton()->strings._init) {
-
MethodBind *mb = ClassDB::get_method(gds->native->get_name(), *methodname);
if (!mb) {
err.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -1243,7 +1172,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
err.error = Callable::CallError::CALL_OK;
}
} else {
-
if (*methodname != GDScriptLanguage::get_singleton()->strings._init) {
err.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
} else {
@@ -1252,7 +1180,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
if (err.error != Callable::CallError::CALL_OK) {
-
String methodstr = *methodname;
err_text = _get_call_error(err, "function '" + methodstr + "'", (const Variant **)argptrs);
@@ -1265,7 +1192,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE(OPCODE_YIELD)
OPCODE(OPCODE_YIELD_SIGNAL) {
-
int ipofs = 1;
if (_code_ptr[ip] == OPCODE_YIELD_SIGNAL) {
CHECK_SPACE(4);
@@ -1285,13 +1211,24 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
gdfs->state.stack_size = _stack_size;
gdfs->state.self = self;
gdfs->state.alloca_size = alloca_size;
- gdfs->state.script = Ref<GDScript>(_script);
gdfs->state.ip = ip + ipofs;
gdfs->state.line = line;
- gdfs->state.instance_id = (p_instance && p_instance->get_owner()) ? p_instance->get_owner()->get_instance_id() : ObjectID();
- //gdfs->state.result_pos=ip+ipofs-1;
+ gdfs->state.script = _script;
+ {
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
+ _script->pending_func_states.add(&gdfs->scripts_list);
+ if (p_instance) {
+ gdfs->state.instance = p_instance;
+ p_instance->pending_func_states.add(&gdfs->instances_list);
+ } else {
+ gdfs->state.instance = nullptr;
+ }
+ }
+#ifdef DEBUG_ENABLED
+ gdfs->state.function_name = name;
+ gdfs->state.script_path = _script->get_path();
+#endif
gdfs->state.defarg = defarg;
- gdfs->state.instance = p_instance;
gdfs->function = this;
retvalue = gdfs;
@@ -1327,7 +1264,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE_BREAK;
}
if (signal.length() == 0) {
-
err_text = "Second argument of yield() is an empty string (for signal name).";
OPCODE_BREAK;
}
@@ -1353,7 +1289,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
OPCODE(OPCODE_YIELD_RESUME) {
-
CHECK_SPACE(2);
#ifdef DEBUG_ENABLED
if (!p_state) {
@@ -1368,7 +1303,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_JUMP) {
-
CHECK_SPACE(2);
int to = _code_ptr[ip + 1];
@@ -1378,7 +1312,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_JUMP_IF) {
-
CHECK_SPACE(3);
GET_VARIANT_PTR(test, 1);
@@ -1396,7 +1329,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_JUMP_IF_NOT) {
-
CHECK_SPACE(3);
GET_VARIANT_PTR(test, 1);
@@ -1414,14 +1346,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_JUMP_TO_DEF_ARGUMENT) {
-
CHECK_SPACE(2);
ip = _default_arg_ptr[defarg];
}
DISPATCH_OPCODE;
OPCODE(OPCODE_RETURN) {
-
CHECK_SPACE(2);
GET_VARIANT_PTR(r, 1);
retvalue = *r;
@@ -1432,7 +1362,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
OPCODE(OPCODE_ITERATE_BEGIN) {
-
CHECK_SPACE(8); //space for this a regular iterate
GET_VARIANT_PTR(counter, 1);
@@ -1465,7 +1394,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
DISPATCH_OPCODE;
OPCODE(OPCODE_ITERATE) {
-
CHECK_SPACE(4);
GET_VARIANT_PTR(counter, 1);
@@ -1541,15 +1469,17 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
bool do_break = false;
if (EngineDebugger::get_script_debugger()->get_lines_left() > 0) {
-
- if (EngineDebugger::get_script_debugger()->get_depth() <= 0)
+ if (EngineDebugger::get_script_debugger()->get_depth() <= 0) {
EngineDebugger::get_script_debugger()->set_lines_left(EngineDebugger::get_script_debugger()->get_lines_left() - 1);
- if (EngineDebugger::get_script_debugger()->get_lines_left() <= 0)
+ }
+ if (EngineDebugger::get_script_debugger()->get_lines_left() <= 0) {
do_break = true;
+ }
}
- if (EngineDebugger::get_script_debugger()->is_breakpoint(line, source))
+ if (EngineDebugger::get_script_debugger()->is_breakpoint(line, source)) {
do_break = true;
+ }
if (do_break) {
GDScriptLanguage::get_singleton()->debug_break("Breakpoint", true);
@@ -1577,20 +1507,24 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODES_END
#ifdef DEBUG_ENABLED
- if (exit_ok)
+ if (exit_ok) {
OPCODE_OUT;
+ }
//error
// function, file, line, error, explanation
String err_file;
- if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->path != "")
+ if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->path != "") {
err_file = p_instance->script->path;
- else if (script)
+ } else if (script) {
err_file = script->path;
- if (err_file == "")
+ }
+ if (err_file == "") {
err_file = "<built-in>";
+ }
String err_func = name;
- if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->name != "")
+ if (p_instance && ObjectDB::get_instance(p_instance->owner_id) != nullptr && p_instance->script->is_valid() && p_instance->script->name != "") {
err_func = p_instance->script->name + "." + err_func;
+ }
int err_line = line;
if (err_text == "") {
err_text = "Internal Script Error! - opcode #" + itos(last_opcode) + " (report please).";
@@ -1622,14 +1556,16 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
// When it's the last resume it will postpone the exit from stack,
// so the debugger knows which function triggered the resume of the next function (if any)
if (!p_state || yielded) {
- if (EngineDebugger::is_active())
+ if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->exit_function();
+ }
#endif
if (_stack_size) {
//free stack
- for (int i = 0; i < _stack_size; i++)
+ for (int i = 0; i < _stack_size; i++) {
stack[i].~Variant();
+ }
}
#ifdef DEBUG_ENABLED
@@ -1640,32 +1576,28 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
const int *GDScriptFunction::get_code() const {
-
return _code_ptr;
}
-int GDScriptFunction::get_code_size() const {
+int GDScriptFunction::get_code_size() const {
return _code_size;
}
Variant GDScriptFunction::get_constant(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, constants.size(), "<errconst>");
return constants[p_idx];
}
StringName GDScriptFunction::get_global_name(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, global_names.size(), "<errgname>");
return global_names[p_idx];
}
int GDScriptFunction::get_default_argument_count() const {
-
return _default_arg_count;
}
-int GDScriptFunction::get_default_argument_addr(int p_idx) const {
+int GDScriptFunction::get_default_argument_addr(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, default_arguments.size(), -1);
return default_arguments[p_idx];
}
@@ -1680,45 +1612,38 @@ GDScriptDataType GDScriptFunction::get_argument_type(int p_idx) const {
}
StringName GDScriptFunction::get_name() const {
-
return name;
}
int GDScriptFunction::get_max_stack_size() const {
-
return _stack_size;
}
struct _GDFKC {
-
int order;
List<int> pos;
};
struct _GDFKCS {
-
int order;
StringName id;
int pos;
bool operator<(const _GDFKCS &p_r) const {
-
return order < p_r.order;
}
};
void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<StringName, int>> *r_stackvars) const {
-
int oc = 0;
Map<StringName, _GDFKC> sdmap;
for (const List<StackDebug>::Element *E = stack_debug.front(); E; E = E->next()) {
-
const StackDebug &sd = E->get();
- if (sd.line > p_line)
+ if (sd.line > p_line) {
break;
+ }
if (sd.added) {
-
if (!sdmap.has(sd.identifier)) {
_GDFKC d;
d.order = oc++;
@@ -1729,18 +1654,17 @@ void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<String
sdmap[sd.identifier].pos.push_back(sd.pos);
}
} else {
-
ERR_CONTINUE(!sdmap.has(sd.identifier));
sdmap[sd.identifier].pos.pop_back();
- if (sdmap[sd.identifier].pos.empty())
+ if (sdmap[sd.identifier].pos.empty()) {
sdmap.erase(sd.identifier);
+ }
}
}
List<_GDFKCS> stackpositions;
for (Map<StringName, _GDFKC>::Element *E = sdmap.front(); E; E = E->next()) {
-
_GDFKCS spp;
spp.id = E->key();
spp.order = E->get().order;
@@ -1751,7 +1675,6 @@ void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<String
stackpositions.sort();
for (List<_GDFKCS>::Element *E = stackpositions.front(); E; E = E->next()) {
-
Pair<StringName, int> p;
p.first = E->get().id;
p.second = E->get().pos;
@@ -1761,7 +1684,6 @@ void GDScriptFunction::debug_get_stack_member_state(int p_line, List<Pair<String
GDScriptFunction::GDScriptFunction() :
function_list(this) {
-
_stack_size = 0;
_call_size = 0;
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
@@ -1800,7 +1722,6 @@ GDScriptFunction::~GDScriptFunction() {
/////////////////////
Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
Variant arg;
r_error.error = Callable::CallError::CALL_OK;
@@ -1833,28 +1754,48 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar
}
bool GDScriptFunctionState::is_valid(bool p_extended_check) const {
-
- if (function == nullptr)
+ if (function == nullptr) {
return false;
+ }
if (p_extended_check) {
- //class instance gone?
- if (state.instance_id.is_valid() && !ObjectDB::get_instance(state.instance_id))
+ MutexLock lock(GDScriptLanguage::get_singleton()->lock);
+
+ // Script gone?
+ if (!scripts_list.in_list()) {
return false;
+ }
+ // Class instance gone? (if not static function)
+ if (state.instance && !instances_list.in_list()) {
+ return false;
+ }
}
return true;
}
Variant GDScriptFunctionState::resume(const Variant &p_arg) {
-
ERR_FAIL_COND_V(!function, Variant());
- if (state.instance_id.is_valid() && !ObjectDB::get_instance(state.instance_id)) {
+ {
+ MutexLock lock(GDScriptLanguage::singleton->lock);
+
+ if (!scripts_list.in_list()) {
#ifdef DEBUG_ENABLED
- ERR_FAIL_V_MSG(Variant(), "Resumed function '" + String(function->get_name()) + "()' after yield, but class instance is gone. At script: " + state.script->get_path() + ":" + itos(state.line));
+ ERR_FAIL_V_MSG(Variant(), "Resumed function '" + state.function_name + "()' after yield, but script is gone. At script: " + state.script_path + ":" + itos(state.line));
#else
- return Variant();
+ return Variant();
+#endif
+ }
+ if (state.instance && !instances_list.in_list()) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_V_MSG(Variant(), "Resumed function '" + state.function_name + "()' after yield, but class instance is gone. At script: " + state.script_path + ":" + itos(state.line));
+#else
+ return Variant();
#endif
+ }
+ // Do these now to avoid locking again after the call
+ scripts_list.remove_from_list();
+ instances_list.remove_from_list();
}
state.result = p_arg;
@@ -1884,13 +1825,8 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
}
#ifdef DEBUG_ENABLED
- if (EngineDebugger::is_active())
+ if (EngineDebugger::is_active()) {
GDScriptLanguage::get_singleton()->exit_function();
- if (state.stack_size) {
- //free stack
- Variant *stack = (Variant *)state.stack.ptr();
- for (int i = 0; i < state.stack_size; i++)
- stack[i].~Variant();
}
#endif
}
@@ -1898,8 +1834,17 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) {
return ret;
}
-void GDScriptFunctionState::_bind_methods() {
+void GDScriptFunctionState::_clear_stack() {
+ if (state.stack_size) {
+ Variant *stack = (Variant *)state.stack.ptr();
+ for (int i = 0; i < state.stack_size; i++) {
+ stack[i].~Variant();
+ }
+ state.stack_size = 0;
+ }
+}
+void GDScriptFunctionState::_bind_methods() {
ClassDB::bind_method(D_METHOD("resume", "arg"), &GDScriptFunctionState::resume, DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("is_valid", "extended_check"), &GDScriptFunctionState::is_valid, DEFVAL(false));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &GDScriptFunctionState::_signal_callback, MethodInfo("_signal_callback"));
@@ -1907,18 +1852,18 @@ void GDScriptFunctionState::_bind_methods() {
ADD_SIGNAL(MethodInfo("completed", PropertyInfo(Variant::NIL, "result", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
}
-GDScriptFunctionState::GDScriptFunctionState() {
-
+GDScriptFunctionState::GDScriptFunctionState() :
+ scripts_list(this),
+ instances_list(this) {
function = nullptr;
}
GDScriptFunctionState::~GDScriptFunctionState() {
+ _clear_stack();
- if (function != nullptr) {
- //never called, deinitialize stack
- for (int i = 0; i < state.stack_size; i++) {
- Variant *v = (Variant *)&state.stack[sizeof(Variant) * i];
- v->~Variant();
- }
+ {
+ MutexLock lock(GDScriptLanguage::singleton->lock);
+ scripts_list.remove_from_list();
+ instances_list.remove_from_list();
}
}
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index acfc0a95b4..583eab744a 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -43,20 +43,25 @@ class GDScriptInstance;
class GDScript;
struct GDScriptDataType {
- bool has_type;
- enum {
+ enum Kind {
UNINITIALIZED,
BUILTIN,
NATIVE,
SCRIPT,
GDSCRIPT,
- } kind;
- Variant::Type builtin_type;
+ };
+
+ Kind kind = UNINITIALIZED;
+
+ bool has_type = false;
+ Variant::Type builtin_type = Variant::NIL;
StringName native_type;
Ref<Script> script_type;
bool is_type(const Variant &p_variant, bool p_allow_implicit_conversion = false) const {
- if (!has_type) return true; // Can't type check
+ if (!has_type) {
+ return true; // Can't type check
+ }
switch (kind) {
case UNINITIALIZED:
@@ -146,10 +151,7 @@ struct GDScriptDataType {
return info;
}
- GDScriptDataType() :
- has_type(false),
- kind(UNINITIALIZED),
- builtin_type(Variant::NIL) {}
+ GDScriptDataType() {}
};
class GDScriptFunction {
@@ -214,7 +216,6 @@ public:
};
struct StackDebug {
-
int line;
int pos;
bool added;
@@ -292,14 +293,16 @@ private:
public:
struct CallState {
-
- ObjectID instance_id;
+ GDScript *script;
GDScriptInstance *instance;
+#ifdef DEBUG_ENABLED
+ StringName function_name;
+ String script_path;
+#endif
Vector<uint8_t> stack;
int stack_size;
Variant self;
uint32_t alloca_size;
- Ref<GDScript> script;
int ip;
int line;
int defarg;
@@ -347,7 +350,6 @@ public:
};
class GDScriptFunctionState : public Reference {
-
GDCLASS(GDScriptFunctionState, Reference);
friend class GDScriptFunction;
GDScriptFunction *function;
@@ -355,12 +357,18 @@ class GDScriptFunctionState : public Reference {
Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
Ref<GDScriptFunctionState> first_state;
+ SelfList<GDScriptFunctionState> scripts_list;
+ SelfList<GDScriptFunctionState> instances_list;
+
protected:
static void _bind_methods();
public:
bool is_valid(bool p_extended_check = false) const;
Variant resume(const Variant &p_arg = Variant());
+
+ void _clear_stack();
+
GDScriptFunctionState();
~GDScriptFunctionState();
};
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index 9154d6eb89..d4258c385e 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -41,7 +41,6 @@
#include "gdscript.h"
const char *GDScriptFunctions::get_func_name(Function p_func) {
-
ERR_FAIL_INDEX_V(p_func, FUNC_MAX, "");
static const char *_names[FUNC_MAX] = {
@@ -140,7 +139,6 @@ const char *GDScriptFunctions::get_func_name(Function p_func) {
}
void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Callable::CallError &r_error) {
-
r_error.error = Callable::CallError::CALL_OK;
#ifdef DEBUG_ENABLED
@@ -176,7 +174,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
//using a switch, so the compiler generates a jumptable
switch (p_func) {
-
case MATH_SIN: {
VALIDATE_ARG_COUNT(1);
VALIDATE_ARG_NUM(0);
@@ -269,15 +266,12 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case MATH_ABS: {
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() == Variant::INT) {
-
int64_t i = *p_args[0];
r_ret = ABS(i);
} else if (p_args[0]->get_type() == Variant::FLOAT) {
-
double r = *p_args[0];
r_ret = Math::abs(r);
} else {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::FLOAT;
@@ -287,15 +281,12 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case MATH_SIGN: {
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() == Variant::INT) {
-
int64_t i = *p_args[0];
r_ret = i < 0 ? -1 : (i > 0 ? +1 : 0);
} else if (p_args[0]->get_type() == Variant::FLOAT) {
-
real_t r = *p_args[0];
r_ret = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0);
} else {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::FLOAT;
@@ -362,13 +353,13 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
const double t = (double)*p_args[2];
switch (p_args[0]->get_type() == p_args[1]->get_type() ? p_args[0]->get_type() : Variant::FLOAT) {
case Variant::VECTOR2: {
- r_ret = ((Vector2)*p_args[0]).linear_interpolate((Vector2)*p_args[1], t);
+ r_ret = ((Vector2)*p_args[0]).lerp((Vector2)*p_args[1], t);
} break;
case Variant::VECTOR3: {
- r_ret = (p_args[0]->operator Vector3()).linear_interpolate(p_args[1]->operator Vector3(), t);
+ r_ret = (p_args[0]->operator Vector3()).lerp(p_args[1]->operator Vector3(), t);
} break;
case Variant::COLOR: {
- r_ret = ((Color)*p_args[0]).linear_interpolate((Color)*p_args[1], t);
+ r_ret = ((Color)*p_args[0]).lerp((Color)*p_args[1], t);
} break;
default: {
VALIDATE_ARG_NUM(0);
@@ -505,7 +496,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case LOGIC_MAX: {
VALIDATE_ARG_COUNT(2);
if (p_args[0]->get_type() == Variant::INT && p_args[1]->get_type() == Variant::INT) {
-
int64_t a = *p_args[0];
int64_t b = *p_args[1];
r_ret = MAX(a, b);
@@ -523,7 +513,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case LOGIC_MIN: {
VALIDATE_ARG_COUNT(2);
if (p_args[0]->get_type() == Variant::INT && p_args[1]->get_type() == Variant::INT) {
-
int64_t a = *p_args[0];
int64_t b = *p_args[1];
r_ret = MIN(a, b);
@@ -540,7 +529,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case LOGIC_CLAMP: {
VALIDATE_ARG_COUNT(3);
if (p_args[0]->get_type() == Variant::INT && p_args[1]->get_type() == Variant::INT && p_args[2]->get_type() == Variant::INT) {
-
int64_t a = *p_args[0];
int64_t b = *p_args[1];
int64_t c = *p_args[2];
@@ -595,7 +583,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case FUNC_FUNCREF: {
VALIDATE_ARG_COUNT(2);
if (p_args[0]->get_type() != Variant::OBJECT) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -603,7 +590,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
return;
}
if (p_args[1]->get_type() != Variant::STRING && p_args[1]->get_type() != Variant::NODE_PATH) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING;
@@ -624,7 +610,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
VALIDATE_ARG_NUM(1);
int type = *p_args[1];
if (type < 0 || type >= Variant::VARIANT_MAX) {
-
r_ret = RTR("Invalid type argument to convert(), use TYPE_* constants.");
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
@@ -632,18 +617,15 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
return;
} else {
-
r_ret = Variant::construct(Variant::Type(type), p_args, 1, r_error);
}
} break;
case TYPE_OF: {
-
VALIDATE_ARG_COUNT(1);
r_ret = p_args[0]->get_type();
} break;
case TYPE_EXISTS: {
-
VALIDATE_ARG_COUNT(1);
r_ret = ClassDB::class_exists(*p_args[0]);
@@ -655,11 +637,9 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
r_ret = String(result);
} break;
case TEXT_ORD: {
-
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::STRING) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -670,7 +650,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
String str = p_args[0]->operator String();
if (str.length() != 1) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::STRING;
@@ -691,23 +670,21 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
}
String str;
for (int i = 0; i < p_arg_count; i++) {
-
String os = p_args[i]->operator String();
- if (i == 0)
+ if (i == 0) {
str = os;
- else
+ } else {
str += os;
+ }
}
r_ret = str;
} break;
case TEXT_PRINT: {
-
String str;
for (int i = 0; i < p_arg_count; i++) {
-
str += p_args[i]->operator String();
}
@@ -716,12 +693,11 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case TEXT_PRINT_TABBED: {
-
String str;
for (int i = 0; i < p_arg_count; i++) {
-
- if (i)
+ if (i) {
str += "\t";
+ }
str += p_args[i]->operator String();
}
@@ -730,12 +706,11 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case TEXT_PRINT_SPACED: {
-
String str;
for (int i = 0; i < p_arg_count; i++) {
-
- if (i)
+ if (i) {
str += " ";
+ }
str += p_args[i]->operator String();
}
@@ -745,10 +720,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case TEXT_PRINTERR: {
-
String str;
for (int i = 0; i < p_arg_count; i++) {
-
str += p_args[i]->operator String();
}
@@ -759,7 +732,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case TEXT_PRINTRAW: {
String str;
for (int i = 0; i < p_arg_count; i++) {
-
str += p_args[i]->operator String();
}
@@ -770,7 +742,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
case TEXT_PRINT_DEBUG: {
String str;
for (int i = 0; i < p_arg_count; i++) {
-
str += p_args[i]->operator String();
}
@@ -922,18 +893,14 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case GEN_RANGE: {
-
switch (p_arg_count) {
-
case 0: {
-
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 1;
r_ret = Variant();
} break;
case 1: {
-
VALIDATE_ARG_NUM(0);
int count = *p_args[0];
Array arr;
@@ -955,7 +922,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
r_ret = arr;
} break;
case 2: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
@@ -973,12 +939,12 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
r_ret = Variant();
return;
}
- for (int i = from; i < to; i++)
+ for (int i = from; i < to; i++) {
arr[i - from] = i;
+ }
r_ret = arr;
} break;
case 3: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
@@ -987,7 +953,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
int to = *p_args[1];
int incr = *p_args[2];
if (incr == 0) {
-
r_ret = RTR("Step argument is zero!");
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return;
@@ -1006,10 +971,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
//calculate how many
int count = 0;
if (incr > 0) {
-
count = ((to - from - 1) / incr) + 1;
} else {
-
count = ((from - to - 1) / -incr) + 1;
}
@@ -1027,7 +990,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
arr[idx++] = i;
}
} else {
-
int idx = 0;
for (int i = from; i > to; i += incr) {
arr[idx++] = i;
@@ -1037,7 +999,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
r_ret = arr;
} break;
default: {
-
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument = 3;
r_ret = Variant();
@@ -1059,7 +1020,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case INST2DICT: {
-
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() == Variant::NIL) {
@@ -1069,24 +1029,20 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
r_error.argument = 0;
r_ret = Variant();
} else {
-
Object *obj = *p_args[0];
if (!obj) {
r_ret = Variant();
} else if (!obj->get_script_instance() || obj->get_script_instance()->get_language() != GDScriptLanguage::get_singleton()) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::DICTIONARY;
r_ret = RTR("Not a script with an instance");
return;
} else {
-
GDScriptInstance *ins = static_cast<GDScriptInstance *>(obj->get_script_instance());
Ref<GDScript> base = ins->get_script();
if (base.is_null()) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::DICTIONARY;
@@ -1098,7 +1054,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
Vector<StringName> sname;
while (p->_owner) {
-
sname.push_back(p->name);
p = p->_owner;
}
@@ -1132,11 +1087,9 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case DICT2INST: {
-
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::DICTIONARY) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::DICTIONARY;
@@ -1148,7 +1101,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
Dictionary d = *p_args[0];
if (!d.has("@path")) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -1159,7 +1111,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
Ref<Script> scr = ResourceLoader::load(d["@path"]);
if (!scr.is_valid()) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -1170,7 +1121,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
Ref<GDScript> gdscr = scr;
if (!gdscr.is_valid()) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -1185,10 +1135,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
}
for (int i = 0; i < sub.get_name_count(); i++) {
-
gdscr = gdscr->subclasses[sub.get_name(i)];
if (!gdscr.is_valid()) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -1197,8 +1145,12 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
return;
}
}
+ r_ret = gdscr->_new(nullptr, -1 /*skip initializer*/, r_error);
- r_ret = gdscr->_new(nullptr, 0, r_error);
+ if (r_error.error != Callable::CallError::CALL_OK) {
+ r_ret = Variant();
+ return;
+ }
GDScriptInstance *ins = static_cast<GDScriptInstance *>(static_cast<Object *>(r_ret)->get_script_instance());
Ref<GDScript> gd_ref = ins->get_script();
@@ -1211,7 +1163,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case VALIDATE_JSON: {
-
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::STRING) {
@@ -1235,7 +1186,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case PARSE_JSON: {
-
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::STRING) {
@@ -1263,13 +1213,11 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
r_ret = JSON::print(*p_args[0]);
} break;
case HASH: {
-
VALIDATE_ARG_COUNT(1);
r_ret = p_args[0]->hash();
} break;
case COLOR8: {
-
if (p_arg_count < 3) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 3;
@@ -1300,7 +1248,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case COLORN: {
-
if (p_arg_count < 1) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 1;
@@ -1335,7 +1282,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
ScriptLanguage *script = GDScriptLanguage::get_singleton();
for (int i = 0; i < script->debug_get_stack_level_count(); i++) {
-
print_line("Frame " + itos(i) + " - " + script->debug_get_stack_level_source(i) + ":" + itos(script->debug_get_stack_level_line(i)) + " in function '" + script->debug_get_stack_level_function(i) + "'");
};
} break;
@@ -1346,7 +1292,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
ScriptLanguage *script = GDScriptLanguage::get_singleton();
Array ret;
for (int i = 0; i < script->debug_get_stack_level_count(); i++) {
-
Dictionary frame;
frame["source"] = script->debug_get_stack_level_source(i);
frame["function"] = script->debug_get_stack_level_function(i);
@@ -1357,7 +1302,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case INSTANCE_FROM_ID: {
-
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::INT && p_args[0]->get_type() != Variant::FLOAT) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
@@ -1372,66 +1316,53 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case LEN: {
-
VALIDATE_ARG_COUNT(1);
switch (p_args[0]->get_type()) {
case Variant::STRING: {
-
String d = *p_args[0];
r_ret = d.length();
} break;
case Variant::DICTIONARY: {
-
Dictionary d = *p_args[0];
r_ret = d.size();
} break;
case Variant::ARRAY: {
-
Array d = *p_args[0];
r_ret = d.size();
} break;
case Variant::PACKED_BYTE_ARRAY: {
-
Vector<uint8_t> d = *p_args[0];
r_ret = d.size();
} break;
case Variant::PACKED_INT32_ARRAY: {
-
Vector<int32_t> d = *p_args[0];
r_ret = d.size();
} break;
case Variant::PACKED_INT64_ARRAY: {
-
Vector<int64_t> d = *p_args[0];
r_ret = d.size();
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
-
Vector<float> d = *p_args[0];
r_ret = d.size();
} break;
case Variant::PACKED_FLOAT64_ARRAY: {
-
Vector<double> d = *p_args[0];
r_ret = d.size();
} break;
case Variant::PACKED_STRING_ARRAY: {
-
Vector<String> d = *p_args[0];
r_ret = d.size();
} break;
case Variant::PACKED_VECTOR2_ARRAY: {
-
Vector<Vector2> d = *p_args[0];
r_ret = d.size();
} break;
case Variant::PACKED_VECTOR3_ARRAY: {
-
Vector<Vector3> d = *p_args[0];
r_ret = d.size();
} break;
case Variant::PACKED_COLOR_ARRAY: {
-
Vector<Color> d = *p_args[0];
r_ret = d.size();
} break;
@@ -1446,7 +1377,6 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case IS_INSTANCE_VALID: {
-
VALIDATE_ARG_COUNT(1);
if (p_args[0]->get_type() != Variant::OBJECT) {
r_ret = false;
@@ -1457,19 +1387,16 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
} break;
case FUNC_MAX: {
-
ERR_FAIL();
} break;
}
}
bool GDScriptFunctions::is_deterministic(Function p_func) {
-
//man i couldn't have chosen a worse function name,
//way too controversial..
switch (p_func) {
-
case MATH_SIN:
case MATH_COS:
case MATH_TAN:
@@ -1533,12 +1460,10 @@ bool GDScriptFunctions::is_deterministic(Function p_func) {
}
MethodInfo GDScriptFunctions::get_info(Function p_func) {
-
#ifdef DEBUG_ENABLED
//using a switch, so the compiler generates a jumptable
switch (p_func) {
-
case MATH_SIN: {
MethodInfo mi("sin", PropertyInfo(Variant::FLOAT, "s"));
mi.return_val.type = Variant::FLOAT;
@@ -1813,7 +1738,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
case OBJ_WEAKREF: {
-
MethodInfo mi("weakref", PropertyInfo(Variant::OBJECT, "obj"));
mi.return_val.type = Variant::OBJECT;
mi.return_val.class_name = "WeakRef";
@@ -1822,7 +1746,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case FUNC_FUNCREF: {
-
MethodInfo mi("funcref", PropertyInfo(Variant::OBJECT, "instance"), PropertyInfo(Variant::STRING, "funcname"));
mi.return_val.type = Variant::OBJECT;
mi.return_val.class_name = "FuncRef";
@@ -1830,42 +1753,36 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case TYPE_CONVERT: {
-
MethodInfo mi("convert", PropertyInfo(Variant::NIL, "what", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::INT, "type"));
mi.return_val.type = Variant::NIL;
mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
return mi;
} break;
case TYPE_OF: {
-
MethodInfo mi("typeof", PropertyInfo(Variant::NIL, "what", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
mi.return_val.type = Variant::INT;
return mi;
} break;
case TYPE_EXISTS: {
-
MethodInfo mi("type_exists", PropertyInfo(Variant::STRING, "type"));
mi.return_val.type = Variant::BOOL;
return mi;
} break;
case TEXT_CHAR: {
-
MethodInfo mi("char", PropertyInfo(Variant::INT, "code"));
mi.return_val.type = Variant::STRING;
return mi;
} break;
case TEXT_ORD: {
-
MethodInfo mi("ord", PropertyInfo(Variant::STRING, "char"));
mi.return_val.type = Variant::INT;
return mi;
} break;
case TEXT_STR: {
-
MethodInfo mi("str");
mi.return_val.type = Variant::STRING;
mi.flags |= METHOD_FLAG_VARARG;
@@ -1873,7 +1790,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case TEXT_PRINT: {
-
MethodInfo mi("print");
mi.return_val.type = Variant::NIL;
mi.flags |= METHOD_FLAG_VARARG;
@@ -1881,7 +1797,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case TEXT_PRINT_TABBED: {
-
MethodInfo mi("printt");
mi.return_val.type = Variant::NIL;
mi.flags |= METHOD_FLAG_VARARG;
@@ -1889,7 +1804,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case TEXT_PRINT_SPACED: {
-
MethodInfo mi("prints");
mi.return_val.type = Variant::NIL;
mi.flags |= METHOD_FLAG_VARARG;
@@ -1897,7 +1811,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case TEXT_PRINTERR: {
-
MethodInfo mi("printerr");
mi.return_val.type = Variant::NIL;
mi.flags |= METHOD_FLAG_VARARG;
@@ -1905,7 +1818,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case TEXT_PRINTRAW: {
-
MethodInfo mi("printraw");
mi.return_val.type = Variant::NIL;
mi.flags |= METHOD_FLAG_VARARG;
@@ -1913,7 +1825,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case TEXT_PRINT_DEBUG: {
-
MethodInfo mi("print_debug");
mi.return_val.type = Variant::NIL;
mi.flags |= METHOD_FLAG_VARARG;
@@ -1921,41 +1832,35 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
} break;
case PUSH_ERROR: {
-
MethodInfo mi(Variant::NIL, "push_error", PropertyInfo(Variant::STRING, "message"));
mi.return_val.type = Variant::NIL;
return mi;
} break;
case PUSH_WARNING: {
-
MethodInfo mi(Variant::NIL, "push_warning", PropertyInfo(Variant::STRING, "message"));
mi.return_val.type = Variant::NIL;
return mi;
} break;
case VAR_TO_STR: {
-
MethodInfo mi("var2str", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
mi.return_val.type = Variant::STRING;
return mi;
} break;
case STR_TO_VAR: {
-
MethodInfo mi(Variant::NIL, "str2var", PropertyInfo(Variant::STRING, "string"));
mi.return_val.type = Variant::NIL;
mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
return mi;
} break;
case VAR_TO_BYTES: {
-
MethodInfo mi("var2bytes", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::BOOL, "full_objects"));
mi.default_arguments.push_back(false);
mi.return_val.type = Variant::PACKED_BYTE_ARRAY;
return mi;
} break;
case BYTES_TO_VAR: {
-
MethodInfo mi(Variant::NIL, "bytes2var", PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytes"), PropertyInfo(Variant::BOOL, "allow_objects"));
mi.default_arguments.push_back(false);
mi.return_val.type = Variant::NIL;
@@ -1963,65 +1868,55 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
case GEN_RANGE: {
-
MethodInfo mi("range");
mi.return_val.type = Variant::ARRAY;
mi.flags |= METHOD_FLAG_VARARG;
return mi;
} break;
case RESOURCE_LOAD: {
-
MethodInfo mi("load", PropertyInfo(Variant::STRING, "path"));
mi.return_val.type = Variant::OBJECT;
mi.return_val.class_name = "Resource";
return mi;
} break;
case INST2DICT: {
-
MethodInfo mi("inst2dict", PropertyInfo(Variant::OBJECT, "inst"));
mi.return_val.type = Variant::DICTIONARY;
return mi;
} break;
case DICT2INST: {
-
MethodInfo mi("dict2inst", PropertyInfo(Variant::DICTIONARY, "dict"));
mi.return_val.type = Variant::OBJECT;
return mi;
} break;
case VALIDATE_JSON: {
-
MethodInfo mi("validate_json", PropertyInfo(Variant::STRING, "json"));
mi.return_val.type = Variant::STRING;
return mi;
} break;
case PARSE_JSON: {
-
MethodInfo mi(Variant::NIL, "parse_json", PropertyInfo(Variant::STRING, "json"));
mi.return_val.type = Variant::NIL;
mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
return mi;
} break;
case TO_JSON: {
-
MethodInfo mi("to_json", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
mi.return_val.type = Variant::STRING;
return mi;
} break;
case HASH: {
-
MethodInfo mi("hash", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT));
mi.return_val.type = Variant::INT;
return mi;
} break;
case COLOR8: {
-
MethodInfo mi("Color8", PropertyInfo(Variant::INT, "r8"), PropertyInfo(Variant::INT, "g8"), PropertyInfo(Variant::INT, "b8"), PropertyInfo(Variant::INT, "a8"));
mi.default_arguments.push_back(255);
mi.return_val.type = Variant::COLOR;
return mi;
} break;
case COLORN: {
-
MethodInfo mi("ColorN", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "alpha"));
mi.default_arguments.push_back(1.0f);
mi.return_val.type = Variant::COLOR;
@@ -2055,7 +1950,6 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
return mi;
} break;
default: {
-
ERR_FAIL_V(MethodInfo());
} break;
}
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 8d34ce5c70..0e498f6895 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -42,14 +42,14 @@
template <class T>
T *GDScriptParser::alloc_node() {
-
T *t = memnew(T);
t->next = list;
list = t;
- if (!head)
+ if (!head) {
head = t;
+ }
t->line = tokenizer->get_token_line();
t->column = tokenizer->get_token_column();
@@ -61,7 +61,6 @@ static String _find_function_name(const GDScriptParser::OperatorNode *p_call);
#endif // DEBUG_ENABLED
bool GDScriptParser::_end_statement() {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_SEMICOLON) {
tokenizer->advance();
return true; //handle next
@@ -72,8 +71,17 @@ bool GDScriptParser::_end_statement() {
return false;
}
-bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
+void GDScriptParser::_set_end_statement_error(String p_name) {
+ String error_msg;
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER) {
+ error_msg = vformat("Expected end of statement (\"%s\"), got %s (\"%s\") instead.", p_name, tokenizer->get_token_name(tokenizer->get_token()), tokenizer->get_token_identifier());
+ } else {
+ error_msg = vformat("Expected end of statement (\"%s\"), got %s instead.", p_name, tokenizer->get_token_name(tokenizer->get_token()));
+ }
+ _set_error(error_msg);
+}
+bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_COLON) {
// report location at the previous token (on the previous line)
int error_line = tokenizer->get_token_line(-1);
@@ -98,12 +106,10 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
while (true) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_NEWLINE) {
-
return false; //wtf
} else if (tokenizer->get_token(1) == GDScriptTokenizer::TK_EOF) {
return false;
} else if (tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE) {
-
int indent = tokenizer->get_token_line_indent();
int tabs = tokenizer->get_token_line_tab_indent();
IndentLevel current_level = indent_level.back()->get();
@@ -122,7 +128,6 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
return true;
} else if (p_block) {
-
NewLineNode *nl = alloc_node<NewLineNode>();
nl->line = tokenizer->get_token_line();
p_block->statements.push_back(nl);
@@ -133,16 +138,13 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) {
}
bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete, bool p_parsing_constant) {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
tokenizer->advance();
} else {
-
parenthesis++;
int argidx = 0;
while (true) {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
_make_completable_call(argidx);
completion_node = p_parent;
@@ -168,9 +170,7 @@ bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bo
break;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
-
if (tokenizer->get_token(1) == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
-
_set_error("Expression expected");
return false;
}
@@ -190,7 +190,6 @@ bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bo
}
void GDScriptParser::_make_completable_call(int p_arg) {
-
completion_cursor = StringName();
completion_type = COMPLETION_CALL_ARGUMENTS;
completion_class = current_class;
@@ -203,14 +202,12 @@ void GDScriptParser::_make_completable_call(int p_arg) {
}
bool GDScriptParser::_get_completable_identifier(CompletionType p_type, StringName &identifier) {
-
identifier = StringName();
if (tokenizer->is_token_literal()) {
identifier = tokenizer->get_token_literal();
tokenizer->advance();
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
-
completion_cursor = identifier;
completion_type = p_type;
completion_class = current_class;
@@ -236,7 +233,6 @@ bool GDScriptParser::_get_completable_identifier(CompletionType p_type, StringNa
}
GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign, bool p_parsing_constant) {
-
//Vector<Node*> expressions;
//Vector<OperatorNode::Operator> operators;
@@ -247,7 +243,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
int op_line = tokenizer->get_token_line(); // when operators are created at the bottom, the line might have been changed (\n found)
while (true) {
-
/*****************/
/* Parse Operand */
/*****************/
@@ -275,11 +270,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
parenthesis++;
Node *subexpr = _parse_expression(p_parent, p_static, p_allow_assign, p_parsing_constant);
parenthesis--;
- if (!subexpr)
+ if (!subexpr) {
return nullptr;
+ }
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
-
_set_error("Expected ')' in expression");
return nullptr;
}
@@ -296,7 +291,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
int line = tokenizer->get_token_line();
while (!done) {
-
switch (tokenizer->get_token()) {
case GDScriptTokenizer::TK_CURSOR: {
completion_type = COMPLETION_GET_NODE;
@@ -310,7 +304,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
} break;
case GDScriptTokenizer::TK_CONSTANT: {
-
if (!need_identifier) {
done = true;
break;
@@ -327,7 +320,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
} break;
case GDScriptTokenizer::TK_OP_DIV: {
-
if (need_identifier) {
done = true;
break;
@@ -382,7 +374,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
continue; //no point in cursor in the middle of expression
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT) {
-
//constant defined by tokenizer
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = tokenizer->get_token_constant();
@@ -390,7 +381,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
expr = constant;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_PI) {
-
//constant defined by tokenizer
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = Math_PI;
@@ -398,7 +388,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
expr = constant;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_TAU) {
-
//constant defined by tokenizer
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = Math_TAU;
@@ -406,7 +395,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
expr = constant;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_INF) {
-
//constant defined by tokenizer
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = Math_INF;
@@ -414,7 +402,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
expr = constant;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_CONST_NAN) {
-
//constant defined by tokenizer
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = Math_NAN;
@@ -422,7 +409,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
expr = constant;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_PRELOAD) {
-
//constant defined by tokenizer
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
@@ -479,11 +465,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
return nullptr;
}
- if (!path.is_abs_path() && base_path != "")
+ if (!path.is_abs_path() && base_path != "") {
path = base_path.plus_file(path);
+ }
path = path.replace("///", "//").simplify_path();
if (path == self_path) {
-
_set_error("Can't preload itself (use 'get_script()').");
return nullptr;
}
@@ -492,7 +478,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
dependencies.push_back(path);
if (!dependencies_only) {
if (!validating) {
-
//this can be too slow for just validating code
if (for_completion && ScriptCodeCompletionCache::get_singleton() && FileAccess::exists(path)) {
res = ScriptCodeCompletionCache::get_singleton()->get_cached_resource(path);
@@ -500,7 +485,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
res = ResourceLoader::load(path);
}
} else {
-
if (!FileAccess::exists(path)) {
_set_error("Can't preload resource at path: " + path);
return nullptr;
@@ -533,7 +517,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
expr = constant;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_YIELD) {
-
if (!current_function) {
_set_error("\"yield()\" can only be used inside function blocks.");
return nullptr;
@@ -560,12 +543,12 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
expr = yield;
tokenizer->advance();
} else {
-
parenthesis++;
Node *object = _parse_and_reduce_expression(p_parent, p_static);
- if (!object)
+ if (!object) {
return nullptr;
+ }
yield->arguments.push_back(object);
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
@@ -576,7 +559,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
-
completion_cursor = StringName();
completion_node = object;
completion_type = COMPLETION_YIELD;
@@ -590,8 +572,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
Node *signal = _parse_and_reduce_expression(p_parent, p_static);
- if (!signal)
+ if (!signal) {
return nullptr;
+ }
yield->arguments.push_back(signal);
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
@@ -607,7 +590,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_SELF) {
-
if (p_static) {
_set_error("\"self\" isn't allowed in a static function or constant expression.");
return nullptr;
@@ -617,28 +599,23 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
expr = self;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE && tokenizer->get_token(1) == GDScriptTokenizer::TK_PERIOD) {
-
Variant::Type bi_type = tokenizer->get_token_type();
tokenizer->advance(2);
StringName identifier;
if (_get_completable_identifier(COMPLETION_BUILT_IN_TYPE_CONSTANT, identifier)) {
-
completion_built_in_constant = bi_type;
}
if (identifier == StringName()) {
-
_set_error("Built-in type constant or static function expected after \".\".");
return nullptr;
}
if (!Variant::has_constant(bi_type, identifier)) {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN &&
Variant::is_method_const(bi_type, identifier) &&
Variant::get_method_return_type(bi_type, identifier) == bi_type) {
-
tokenizer->advance();
OperatorNode *construct = alloc_node<OperatorNode>();
@@ -656,8 +633,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
id->name = identifier;
op->arguments.push_back(id);
- if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant))
+ if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) {
return nullptr;
+ }
expr = op;
} else {
@@ -678,7 +656,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
}
} else {
-
ConstantNode *cn = alloc_node<ConstantNode>();
cn->value = Variant::get_constant_value(bi_type, identifier);
cn->datatype = _type_from_variant(cn->value);
@@ -723,13 +700,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance(2);
}
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC) {
-
BuiltInFunctionNode *bn = alloc_node<BuiltInFunctionNode>();
bn->function = tokenizer->get_token_built_in_func();
op->arguments.push_back(bn);
tokenizer->advance(2);
} else {
-
SelfNode *self = alloc_node<SelfNode>();
op->arguments.push_back(self);
@@ -746,10 +721,18 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (tokenizer->get_token() == GDScriptTokenizer::TK_CURSOR) {
_make_completable_call(0);
completion_node = op;
+
+ if (op->arguments[0]->type == GDScriptParser::Node::Type::TYPE_BUILT_IN_FUNCTION) {
+ BuiltInFunctionNode *bn = static_cast<BuiltInFunctionNode *>(op->arguments[0]);
+ if (bn->function == GDScriptFunctions::Function::RESOURCE_LOAD) {
+ completion_type = COMPLETION_RESOURCE_PATH;
+ }
+ }
}
if (!replaced) {
- if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant))
+ if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) {
return nullptr;
+ }
expr = op;
}
} else if (tokenizer->is_token_literal(0, true)) {
@@ -827,6 +810,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
//check from singletons
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = GDScriptLanguage::get_singleton()->get_named_globals_map()[identifier];
+ constant->datatype = _type_from_variant(constant->value);
expr = constant;
bfn = true;
}
@@ -837,6 +821,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (scr.is_valid() && scr->is_valid()) {
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = scr;
+ constant->datatype = _type_from_variant(constant->value);
expr = constant;
bfn = true;
}
@@ -852,6 +837,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
if (parent_constants.has(identifier)) {
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = parent_constants[identifier];
+ constant->datatype = _type_from_variant(constant->value);
expr = constant;
bfn = true;
}
@@ -893,17 +879,24 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ADD || tokenizer->get_token() == GDScriptTokenizer::TK_OP_SUB || tokenizer->get_token() == GDScriptTokenizer::TK_OP_NOT || tokenizer->get_token() == GDScriptTokenizer::TK_OP_BIT_INVERT) {
-
//single prefix operators like !expr +expr -expr ++expr --expr
alloc_node<OperatorNode>();
Expression e;
e.is_op = true;
switch (tokenizer->get_token()) {
- case GDScriptTokenizer::TK_OP_ADD: e.op = OperatorNode::OP_POS; break;
- case GDScriptTokenizer::TK_OP_SUB: e.op = OperatorNode::OP_NEG; break;
- case GDScriptTokenizer::TK_OP_NOT: e.op = OperatorNode::OP_NOT; break;
- case GDScriptTokenizer::TK_OP_BIT_INVERT: e.op = OperatorNode::OP_BIT_INVERT; break;
+ case GDScriptTokenizer::TK_OP_ADD:
+ e.op = OperatorNode::OP_POS;
+ break;
+ case GDScriptTokenizer::TK_OP_SUB:
+ e.op = OperatorNode::OP_NEG;
+ break;
+ case GDScriptTokenizer::TK_OP_NOT:
+ e.op = OperatorNode::OP_NOT;
+ break;
+ case GDScriptTokenizer::TK_OP_BIT_INVERT:
+ e.op = OperatorNode::OP_BIT_INVERT;
+ break;
default: {
}
}
@@ -951,9 +944,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
bool expecting_comma = false;
while (true) {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
-
_set_error("Unterminated array");
return nullptr;
@@ -961,7 +952,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
break;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
-
tokenizer->advance(); //ignore newline
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
if (!expecting_comma) {
@@ -978,8 +968,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
return nullptr;
}
Node *n = _parse_expression(arr, p_static, p_allow_assign, p_parsing_constant);
- if (!n)
+ if (!n) {
return nullptr;
+ }
arr->elements.push_back(n);
expecting_comma = true;
}
@@ -1007,14 +998,11 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
DictExpect expecting = DICT_EXPECT_KEY;
while (true) {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
-
_set_error("Unterminated dictionary");
return nullptr;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) {
-
if (expecting == DICT_EXPECT_COLON) {
_set_error("':' expected");
return nullptr;
@@ -1026,10 +1014,8 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance();
break;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
-
tokenizer->advance(); //ignore newline
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
-
if (expecting == DICT_EXPECT_KEY) {
_set_error("key or '}' expected");
return nullptr;
@@ -1047,7 +1033,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance(); //ignore newline
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON) {
-
if (expecting == DICT_EXPECT_KEY) {
_set_error("key or '}' expected");
return nullptr;
@@ -1064,7 +1049,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
expecting = DICT_EXPECT_VALUE;
tokenizer->advance(); //ignore newline
} else {
-
if (expecting == DICT_EXPECT_COMMA) {
_set_error("',' or '}' expected");
return nullptr;
@@ -1075,7 +1059,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
if (expecting == DICT_EXPECT_KEY) {
-
if (tokenizer->is_token_literal() && tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) {
// We check with is_token_literal, as this allows us to use match/sync/etc. as a name
//lua style identifier, easier to write
@@ -1088,16 +1071,18 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
} else {
//python/js style more flexible
key = _parse_expression(dict, p_static, p_allow_assign, p_parsing_constant);
- if (!key)
+ if (!key) {
return nullptr;
+ }
expecting = DICT_EXPECT_COLON;
}
}
if (expecting == DICT_EXPECT_VALUE) {
Node *value = _parse_expression(dict, p_static, p_allow_assign, p_parsing_constant);
- if (!value)
+ if (!value) {
return nullptr;
+ }
expecting = DICT_EXPECT_COMMA;
if (key->type == GDScriptParser::Node::TYPE_CONSTANT) {
@@ -1163,7 +1148,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
expr = tn;
tokenizer->advance();
} else {
-
//find list [ or find dictionary {
_set_error("Error parsing expression, misplaced: " + String(tokenizer->get_token_name(tokenizer->get_token())));
return nullptr; //nothing
@@ -1176,11 +1160,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
/******************/
while (true) {
-
//expressions can be indexed any number of times
if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD) {
-
//indexing using "."
if (tokenizer->get_token(1) != GDScriptTokenizer::TK_CURSOR && !tokenizer->is_token_literal(1)) {
@@ -1211,8 +1193,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
_make_completable_call(0);
completion_node = op;
}
- if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant))
+ if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) {
return nullptr;
+ }
expr = op;
} else {
@@ -1224,7 +1207,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
StringName identifier;
if (_get_completable_identifier(COMPLETION_INDEX, identifier)) {
-
if (identifier == StringName()) {
identifier = "@temp"; //so it parses alright
}
@@ -1264,8 +1246,9 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
tokenizer->advance(1);
expr = op;
- } else
+ } else {
break;
+ }
}
/*****************/
@@ -1319,25 +1302,55 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
switch (tokenizer->get_token()) { //see operator
- case GDScriptTokenizer::TK_OP_IN: op = OperatorNode::OP_IN; break;
- case GDScriptTokenizer::TK_OP_EQUAL: op = OperatorNode::OP_EQUAL; break;
- case GDScriptTokenizer::TK_OP_NOT_EQUAL: op = OperatorNode::OP_NOT_EQUAL; break;
- case GDScriptTokenizer::TK_OP_LESS: op = OperatorNode::OP_LESS; break;
- case GDScriptTokenizer::TK_OP_LESS_EQUAL: op = OperatorNode::OP_LESS_EQUAL; break;
- case GDScriptTokenizer::TK_OP_GREATER: op = OperatorNode::OP_GREATER; break;
- case GDScriptTokenizer::TK_OP_GREATER_EQUAL: op = OperatorNode::OP_GREATER_EQUAL; break;
- case GDScriptTokenizer::TK_OP_AND: op = OperatorNode::OP_AND; break;
- case GDScriptTokenizer::TK_OP_OR: op = OperatorNode::OP_OR; break;
- case GDScriptTokenizer::TK_OP_ADD: op = OperatorNode::OP_ADD; break;
- case GDScriptTokenizer::TK_OP_SUB: op = OperatorNode::OP_SUB; break;
- case GDScriptTokenizer::TK_OP_MUL: op = OperatorNode::OP_MUL; break;
- case GDScriptTokenizer::TK_OP_DIV: op = OperatorNode::OP_DIV; break;
+ case GDScriptTokenizer::TK_OP_IN:
+ op = OperatorNode::OP_IN;
+ break;
+ case GDScriptTokenizer::TK_OP_EQUAL:
+ op = OperatorNode::OP_EQUAL;
+ break;
+ case GDScriptTokenizer::TK_OP_NOT_EQUAL:
+ op = OperatorNode::OP_NOT_EQUAL;
+ break;
+ case GDScriptTokenizer::TK_OP_LESS:
+ op = OperatorNode::OP_LESS;
+ break;
+ case GDScriptTokenizer::TK_OP_LESS_EQUAL:
+ op = OperatorNode::OP_LESS_EQUAL;
+ break;
+ case GDScriptTokenizer::TK_OP_GREATER:
+ op = OperatorNode::OP_GREATER;
+ break;
+ case GDScriptTokenizer::TK_OP_GREATER_EQUAL:
+ op = OperatorNode::OP_GREATER_EQUAL;
+ break;
+ case GDScriptTokenizer::TK_OP_AND:
+ op = OperatorNode::OP_AND;
+ break;
+ case GDScriptTokenizer::TK_OP_OR:
+ op = OperatorNode::OP_OR;
+ break;
+ case GDScriptTokenizer::TK_OP_ADD:
+ op = OperatorNode::OP_ADD;
+ break;
+ case GDScriptTokenizer::TK_OP_SUB:
+ op = OperatorNode::OP_SUB;
+ break;
+ case GDScriptTokenizer::TK_OP_MUL:
+ op = OperatorNode::OP_MUL;
+ break;
+ case GDScriptTokenizer::TK_OP_DIV:
+ op = OperatorNode::OP_DIV;
+ break;
case GDScriptTokenizer::TK_OP_MOD:
op = OperatorNode::OP_MOD;
break;
//case GDScriptTokenizer::TK_OP_NEG: op=OperatorNode::OP_NEG ; break;
- case GDScriptTokenizer::TK_OP_SHIFT_LEFT: op = OperatorNode::OP_SHIFT_LEFT; break;
- case GDScriptTokenizer::TK_OP_SHIFT_RIGHT: op = OperatorNode::OP_SHIFT_RIGHT; break;
+ case GDScriptTokenizer::TK_OP_SHIFT_LEFT:
+ op = OperatorNode::OP_SHIFT_LEFT;
+ break;
+ case GDScriptTokenizer::TK_OP_SHIFT_RIGHT:
+ op = OperatorNode::OP_SHIFT_RIGHT;
+ break;
case GDScriptTokenizer::TK_OP_ASSIGN: {
_VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN;
@@ -1354,23 +1367,57 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
} break;
- case GDScriptTokenizer::TK_OP_ASSIGN_ADD: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_ADD; break;
- case GDScriptTokenizer::TK_OP_ASSIGN_SUB: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SUB; break;
- case GDScriptTokenizer::TK_OP_ASSIGN_MUL: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_MUL; break;
- case GDScriptTokenizer::TK_OP_ASSIGN_DIV: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_DIV; break;
- case GDScriptTokenizer::TK_OP_ASSIGN_MOD: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_MOD; break;
- case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_LEFT: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SHIFT_LEFT; break;
- case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_RIGHT: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SHIFT_RIGHT; break;
- case GDScriptTokenizer::TK_OP_ASSIGN_BIT_AND: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_AND; break;
- case GDScriptTokenizer::TK_OP_ASSIGN_BIT_OR: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_OR; break;
- case GDScriptTokenizer::TK_OP_ASSIGN_BIT_XOR: _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_XOR; break;
- case GDScriptTokenizer::TK_OP_BIT_AND: op = OperatorNode::OP_BIT_AND; break;
- case GDScriptTokenizer::TK_OP_BIT_OR: op = OperatorNode::OP_BIT_OR; break;
- case GDScriptTokenizer::TK_OP_BIT_XOR: op = OperatorNode::OP_BIT_XOR; break;
- case GDScriptTokenizer::TK_PR_IS: op = OperatorNode::OP_IS; break;
- case GDScriptTokenizer::TK_CF_IF: op = OperatorNode::OP_TERNARY_IF; break;
- case GDScriptTokenizer::TK_CF_ELSE: op = OperatorNode::OP_TERNARY_ELSE; break;
- default: valid = false; break;
+ case GDScriptTokenizer::TK_OP_ASSIGN_ADD:
+ _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_ADD;
+ break;
+ case GDScriptTokenizer::TK_OP_ASSIGN_SUB:
+ _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SUB;
+ break;
+ case GDScriptTokenizer::TK_OP_ASSIGN_MUL:
+ _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_MUL;
+ break;
+ case GDScriptTokenizer::TK_OP_ASSIGN_DIV:
+ _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_DIV;
+ break;
+ case GDScriptTokenizer::TK_OP_ASSIGN_MOD:
+ _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_MOD;
+ break;
+ case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_LEFT:
+ _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SHIFT_LEFT;
+ break;
+ case GDScriptTokenizer::TK_OP_ASSIGN_SHIFT_RIGHT:
+ _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_SHIFT_RIGHT;
+ break;
+ case GDScriptTokenizer::TK_OP_ASSIGN_BIT_AND:
+ _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_AND;
+ break;
+ case GDScriptTokenizer::TK_OP_ASSIGN_BIT_OR:
+ _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_OR;
+ break;
+ case GDScriptTokenizer::TK_OP_ASSIGN_BIT_XOR:
+ _VALIDATE_ASSIGN op = OperatorNode::OP_ASSIGN_BIT_XOR;
+ break;
+ case GDScriptTokenizer::TK_OP_BIT_AND:
+ op = OperatorNode::OP_BIT_AND;
+ break;
+ case GDScriptTokenizer::TK_OP_BIT_OR:
+ op = OperatorNode::OP_BIT_OR;
+ break;
+ case GDScriptTokenizer::TK_OP_BIT_XOR:
+ op = OperatorNode::OP_BIT_XOR;
+ break;
+ case GDScriptTokenizer::TK_PR_IS:
+ op = OperatorNode::OP_IS;
+ break;
+ case GDScriptTokenizer::TK_CF_IF:
+ op = OperatorNode::OP_TERNARY_IF;
+ break;
+ case GDScriptTokenizer::TK_CF_ELSE:
+ op = OperatorNode::OP_TERNARY_ELSE;
+ break;
+ default:
+ valid = false;
+ break;
}
if (valid) {
@@ -1386,16 +1433,13 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
/* Reduce the set set of expressions and place them in an operator tree, respecting precedence */
while (expression.size() > 1) {
-
int next_op = -1;
int min_priority = 0xFFFFF;
bool is_unary = false;
bool is_ternary = false;
for (int i = 0; i < expression.size(); i++) {
-
if (!expression[i].is_op) {
-
continue;
}
@@ -1407,7 +1451,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
bool right_to_left = false;
switch (expression[i].op) {
-
case OperatorNode::OP_IS:
case OperatorNode::OP_IS_BUILTIN:
priority = -1;
@@ -1423,36 +1466,74 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
unary = true;
break;
- case OperatorNode::OP_MUL: priority = 2; break;
- case OperatorNode::OP_DIV: priority = 2; break;
- case OperatorNode::OP_MOD: priority = 2; break;
+ case OperatorNode::OP_MUL:
+ priority = 2;
+ break;
+ case OperatorNode::OP_DIV:
+ priority = 2;
+ break;
+ case OperatorNode::OP_MOD:
+ priority = 2;
+ break;
- case OperatorNode::OP_ADD: priority = 3; break;
- case OperatorNode::OP_SUB: priority = 3; break;
+ case OperatorNode::OP_ADD:
+ priority = 3;
+ break;
+ case OperatorNode::OP_SUB:
+ priority = 3;
+ break;
- case OperatorNode::OP_SHIFT_LEFT: priority = 4; break;
- case OperatorNode::OP_SHIFT_RIGHT: priority = 4; break;
+ case OperatorNode::OP_SHIFT_LEFT:
+ priority = 4;
+ break;
+ case OperatorNode::OP_SHIFT_RIGHT:
+ priority = 4;
+ break;
- case OperatorNode::OP_BIT_AND: priority = 5; break;
- case OperatorNode::OP_BIT_XOR: priority = 6; break;
- case OperatorNode::OP_BIT_OR: priority = 7; break;
+ case OperatorNode::OP_BIT_AND:
+ priority = 5;
+ break;
+ case OperatorNode::OP_BIT_XOR:
+ priority = 6;
+ break;
+ case OperatorNode::OP_BIT_OR:
+ priority = 7;
+ break;
- case OperatorNode::OP_LESS: priority = 8; break;
- case OperatorNode::OP_LESS_EQUAL: priority = 8; break;
- case OperatorNode::OP_GREATER: priority = 8; break;
- case OperatorNode::OP_GREATER_EQUAL: priority = 8; break;
+ case OperatorNode::OP_LESS:
+ priority = 8;
+ break;
+ case OperatorNode::OP_LESS_EQUAL:
+ priority = 8;
+ break;
+ case OperatorNode::OP_GREATER:
+ priority = 8;
+ break;
+ case OperatorNode::OP_GREATER_EQUAL:
+ priority = 8;
+ break;
- case OperatorNode::OP_EQUAL: priority = 8; break;
- case OperatorNode::OP_NOT_EQUAL: priority = 8; break;
+ case OperatorNode::OP_EQUAL:
+ priority = 8;
+ break;
+ case OperatorNode::OP_NOT_EQUAL:
+ priority = 8;
+ break;
- case OperatorNode::OP_IN: priority = 10; break;
+ case OperatorNode::OP_IN:
+ priority = 10;
+ break;
case OperatorNode::OP_NOT:
priority = 11;
unary = true;
break;
- case OperatorNode::OP_AND: priority = 12; break;
- case OperatorNode::OP_OR: priority = 13; break;
+ case OperatorNode::OP_AND:
+ priority = 12;
+ break;
+ case OperatorNode::OP_OR:
+ priority = 13;
+ break;
case OperatorNode::OP_TERNARY_IF:
priority = 14;
@@ -1465,17 +1546,39 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
// Rigth-to-left should be false in this case, otherwise it would always error.
break;
- case OperatorNode::OP_ASSIGN: priority = 15; break;
- case OperatorNode::OP_ASSIGN_ADD: priority = 15; break;
- case OperatorNode::OP_ASSIGN_SUB: priority = 15; break;
- case OperatorNode::OP_ASSIGN_MUL: priority = 15; break;
- case OperatorNode::OP_ASSIGN_DIV: priority = 15; break;
- case OperatorNode::OP_ASSIGN_MOD: priority = 15; break;
- case OperatorNode::OP_ASSIGN_SHIFT_LEFT: priority = 15; break;
- case OperatorNode::OP_ASSIGN_SHIFT_RIGHT: priority = 15; break;
- case OperatorNode::OP_ASSIGN_BIT_AND: priority = 15; break;
- case OperatorNode::OP_ASSIGN_BIT_OR: priority = 15; break;
- case OperatorNode::OP_ASSIGN_BIT_XOR: priority = 15; break;
+ case OperatorNode::OP_ASSIGN:
+ priority = 15;
+ break;
+ case OperatorNode::OP_ASSIGN_ADD:
+ priority = 15;
+ break;
+ case OperatorNode::OP_ASSIGN_SUB:
+ priority = 15;
+ break;
+ case OperatorNode::OP_ASSIGN_MUL:
+ priority = 15;
+ break;
+ case OperatorNode::OP_ASSIGN_DIV:
+ priority = 15;
+ break;
+ case OperatorNode::OP_ASSIGN_MOD:
+ priority = 15;
+ break;
+ case OperatorNode::OP_ASSIGN_SHIFT_LEFT:
+ priority = 15;
+ break;
+ case OperatorNode::OP_ASSIGN_SHIFT_RIGHT:
+ priority = 15;
+ break;
+ case OperatorNode::OP_ASSIGN_BIT_AND:
+ priority = 15;
+ break;
+ case OperatorNode::OP_ASSIGN_BIT_OR:
+ priority = 15;
+ break;
+ case OperatorNode::OP_ASSIGN_BIT_XOR:
+ priority = 15;
+ break;
default: {
_set_error("GDScriptParser bug, invalid operator in expression: " + itos(expression[i].op));
@@ -1498,17 +1601,14 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
if (next_op == -1) {
-
_set_error("Yet another parser bug....");
ERR_FAIL_V(nullptr);
}
// OK! create operator..
if (is_unary) {
-
int expr_pos = next_op;
while (expression[expr_pos].is_op) {
-
expr_pos++;
if (expr_pos == expression.size()) {
//can happen..
@@ -1519,7 +1619,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
//consecutively do unary operators
for (int i = expr_pos - 1; i >= next_op; i--) {
-
OperatorNode *op = alloc_node<OperatorNode>();
op->op = expression[i].op;
op->arguments.push_back(expression[i + 1].node);
@@ -1549,7 +1648,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
op->line = op_line; //line might have been changed from a \n
if (expression[next_op - 1].is_op) {
-
_set_error("Parser bug...");
ERR_FAIL_V(nullptr);
}
@@ -1585,7 +1683,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
expression.remove(next_op);
expression.remove(next_op);
} else {
-
if (next_op < 1 || next_op >= (expression.size() - 1)) {
_set_error("Parser bug...");
ERR_FAIL_V(nullptr);
@@ -1596,7 +1693,6 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
op->line = op_line; //line might have been changed from a \n
if (expression[next_op - 1].is_op) {
-
_set_error("Parser bug...");
ERR_FAIL_V(nullptr);
}
@@ -1625,23 +1721,20 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s
}
GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to_const) {
-
switch (p_node->type) {
-
case Node::TYPE_BUILT_IN_FUNCTION: {
//many may probably be optimizable
return p_node;
} break;
case Node::TYPE_ARRAY: {
-
ArrayNode *an = static_cast<ArrayNode *>(p_node);
bool all_constants = true;
for (int i = 0; i < an->elements.size(); i++) {
-
an->elements.write[i] = _reduce_expression(an->elements[i], p_to_const);
- if (an->elements[i]->type != Node::TYPE_CONSTANT)
+ if (an->elements[i]->type != Node::TYPE_CONSTANT) {
all_constants = false;
+ }
}
if (all_constants && p_to_const) {
@@ -1663,18 +1756,18 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
} break;
case Node::TYPE_DICTIONARY: {
-
DictionaryNode *dn = static_cast<DictionaryNode *>(p_node);
bool all_constants = true;
for (int i = 0; i < dn->elements.size(); i++) {
-
dn->elements.write[i].key = _reduce_expression(dn->elements[i].key, p_to_const);
- if (dn->elements[i].key->type != Node::TYPE_CONSTANT)
+ if (dn->elements[i].key->type != Node::TYPE_CONSTANT) {
all_constants = false;
+ }
dn->elements.write[i].value = _reduce_expression(dn->elements[i].value, p_to_const);
- if (dn->elements[i].value->type != Node::TYPE_CONSTANT)
+ if (dn->elements[i].value->type != Node::TYPE_CONSTANT) {
all_constants = false;
+ }
}
if (all_constants && p_to_const) {
@@ -1697,14 +1790,12 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
} break;
case Node::TYPE_OPERATOR: {
-
OperatorNode *op = static_cast<OperatorNode *>(p_node);
bool all_constants = true;
int last_not_constant = -1;
for (int i = 0; i < op->arguments.size(); i++) {
-
op->arguments.write[i] = _reduce_expression(op->arguments[i], p_to_const);
if (op->arguments[i]->type != Node::TYPE_CONSTANT) {
all_constants = false;
@@ -1723,15 +1814,12 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
} else if (op->op == OperatorNode::OP_CALL) {
//can reduce base type constructors
if ((op->arguments[0]->type == Node::TYPE_TYPE || (op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && GDScriptFunctions::is_deterministic(static_cast<BuiltInFunctionNode *>(op->arguments[0])->function))) && last_not_constant == 0) {
-
//native type constructor or intrinsic function
const Variant **vptr = nullptr;
Vector<Variant *> ptrs;
if (op->arguments.size() > 1) {
-
ptrs.resize(op->arguments.size() - 1);
for (int i = 0; i < ptrs.size(); i++) {
-
ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i + 1]);
ptrs.write[i] = &cn->value;
}
@@ -1752,7 +1840,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
}
if (ce.error != Callable::CallError::CALL_OK) {
-
String errwhere;
if (op->arguments[0]->type == Node::TYPE_TYPE) {
TypeNode *tn = static_cast<TypeNode *>(op->arguments[0]);
@@ -1764,18 +1851,14 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
}
switch (ce.error) {
-
case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: {
-
_set_error("Invalid argument (#" + itos(ce.argument + 1) + ") for " + errwhere + ".");
} break;
case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: {
-
_set_error("Too many arguments for " + errwhere + ".");
} break;
case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: {
-
_set_error("Too few arguments for " + errwhere + ".");
} break;
default: {
@@ -1804,7 +1887,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
//can reduce indices into constant arrays or dictionaries
if (all_constants) {
-
ConstantNode *ca = static_cast<ConstantNode *>(op->arguments[0]);
ConstantNode *cb = static_cast<ConstantNode *>(op->arguments[1]);
@@ -1826,9 +1908,7 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
return op;
} else if (op->op == OperatorNode::OP_INDEX_NAMED) {
-
if (op->arguments[0]->type == Node::TYPE_CONSTANT && op->arguments[1]->type == Node::TYPE_IDENTIFIER) {
-
ConstantNode *ca = static_cast<ConstantNode *>(op->arguments[0]);
IdentifierNode *ib = static_cast<IdentifierNode *>(op->arguments[1]);
@@ -1851,7 +1931,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
//validate assignment (don't assign to constant expression
switch (op->op) {
-
case OperatorNode::OP_ASSIGN:
case OperatorNode::OP_ASSIGN_ADD:
case OperatorNode::OP_ASSIGN_SUB:
@@ -1863,7 +1942,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
case OperatorNode::OP_ASSIGN_BIT_AND:
case OperatorNode::OP_ASSIGN_BIT_OR:
case OperatorNode::OP_ASSIGN_BIT_XOR: {
-
if (op->arguments[0]->type == Node::TYPE_CONSTANT) {
_set_error("Can't assign to constant", tokenizer->get_token_line() - 1);
error_line = op->line;
@@ -1889,8 +1967,9 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
}
}
//now se if all are constants
- if (!all_constants)
+ if (!all_constants) {
return op; //nothing to reduce from here on
+ }
#define _REDUCE_UNARY(m_vop) \
bool valid = false; \
Variant res; \
@@ -1920,7 +1999,6 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
return cn;
switch (op->op) {
-
//unary operators
case OperatorNode::OP_NEG: {
_REDUCE_UNARY(Variant::OP_NEGATE);
@@ -2012,18 +2090,53 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to
}
GDScriptParser::Node *GDScriptParser::_parse_and_reduce_expression(Node *p_parent, bool p_static, bool p_reduce_const, bool p_allow_assign) {
-
Node *expr = _parse_expression(p_parent, p_static, p_allow_assign, p_reduce_const);
- if (!expr || error_set)
+ if (!expr || error_set) {
return nullptr;
+ }
expr = _reduce_expression(expr, p_reduce_const);
- if (!expr || error_set)
+ if (!expr || error_set) {
return nullptr;
+ }
return expr;
}
-bool GDScriptParser::_recover_from_completion() {
+bool GDScriptParser::_reduce_export_var_type(Variant &p_value, int p_line) {
+ if (p_value.get_type() == Variant::ARRAY) {
+ Array arr = p_value;
+ for (int i = 0; i < arr.size(); i++) {
+ if (!_reduce_export_var_type(arr[i], p_line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ if (p_value.get_type() == Variant::DICTIONARY) {
+ Dictionary dict = p_value;
+ for (int i = 0; i < dict.size(); i++) {
+ Variant value = dict.get_value_at_index(i);
+ if (!_reduce_export_var_type(value, p_line)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // validate type
+ DataType type = _type_from_variant(p_value);
+ if (type.kind == DataType::BUILTIN) {
+ return true;
+ } else if (type.kind == DataType::NATIVE) {
+ if (ClassDB::is_parent_class(type.native_type, "Resource")) {
+ return true;
+ }
+ }
+ _set_error("Invalid export type. Only built-in and native resource types can be exported.", p_line);
+ return false;
+}
+bool GDScriptParser::_recover_from_completion() {
if (!completion_found) {
return false; //can't recover if no completion
}
@@ -2041,12 +2154,12 @@ bool GDScriptParser::_recover_from_completion() {
}
GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
-
PatternNode *pattern = alloc_node<PatternNode>();
GDScriptTokenizer::Token token = tokenizer->get_token();
- if (error_set)
+ if (error_set) {
return nullptr;
+ }
if (token == GDScriptTokenizer::TK_EOF) {
return nullptr;
@@ -2058,7 +2171,6 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
tokenizer->advance();
pattern->pt_type = GDScriptParser::PatternNode::PT_ARRAY;
while (true) {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_BRACKET_CLOSE) {
tokenizer->advance();
break;
@@ -2130,7 +2242,6 @@ GDScriptParser::PatternNode *GDScriptParser::_parse_pattern(bool p_static) {
tokenizer->advance();
pattern->pt_type = GDScriptParser::PatternNode::PT_DICTIONARY;
while (true) {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) {
tokenizer->advance();
break;
@@ -2243,13 +2354,14 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran
bool catch_all_appeared = false;
while (true) {
-
- while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline())
+ while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline()) {
;
+ }
// GDScriptTokenizer::Token token = tokenizer->get_token();
- if (error_set)
+ if (error_set) {
return;
+ }
if (current_level.indent > indent_level.back()->get().indent) {
break; // go back a level
@@ -2321,12 +2433,10 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran
}
void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, Node *&p_resulting_node, Map<StringName, Node *> &p_bindings) {
-
const DataType &to_match_type = p_node_to_match->get_datatype();
switch (p_pattern->pt_type) {
case PatternNode::PT_CONSTANT: {
-
DataType pattern_type = _reduce_node_type(p_pattern->constant);
if (error_set) {
return;
@@ -2386,10 +2496,10 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// a bind always matches
ConstantNode *true_value = alloc_node<ConstantNode>();
true_value->value = Variant(true);
+ true_value->datatype = _type_from_variant(true_value->value);
p_resulting_node = true_value;
} break;
case PatternNode::PT_ARRAY: {
-
bool open_ended = false;
if (p_pattern->array.size() > 0) {
@@ -2432,6 +2542,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// size
ConstantNode *length = alloc_node<ConstantNode>();
length->value = Variant(open_ended ? p_pattern->array.size() - 1 : p_pattern->array.size());
+ length->datatype = _type_from_variant(length->value);
OperatorNode *call = alloc_node<OperatorNode>();
call->op = OperatorNode::OP_CALL;
@@ -2465,6 +2576,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
ConstantNode *index = alloc_node<ConstantNode>();
index->value = Variant(i);
+ index->datatype = _type_from_variant(index->value);
OperatorNode *indexed_value = alloc_node<OperatorNode>();
indexed_value->op = OperatorNode::OP_INDEX;
@@ -2484,7 +2596,6 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
} break;
case PatternNode::PT_DICTIONARY: {
-
bool open_ended = false;
if (p_pattern->array.size() > 0) {
@@ -2525,6 +2636,7 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// size
ConstantNode *length = alloc_node<ConstantNode>();
length->value = Variant(open_ended ? p_pattern->dictionary.size() - 1 : p_pattern->dictionary.size());
+ length->datatype = _type_from_variant(length->value);
OperatorNode *call = alloc_node<OperatorNode>();
call->op = OperatorNode::OP_CALL;
@@ -2552,7 +2664,6 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
}
for (Map<ConstantNode *, PatternNode *>::Element *e = p_pattern->dictionary.front(); e; e = e->next()) {
-
Node *condition = nullptr;
// check for has, then for pattern
@@ -2567,7 +2678,6 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
has_call->arguments.push_back(e->key());
if (e->value()) {
-
OperatorNode *indexed_value = alloc_node<OperatorNode>();
indexed_value->op = OperatorNode::OP_INDEX;
indexed_value->arguments.push_back(p_node_to_match);
@@ -2601,10 +2711,10 @@ void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_m
// simply generate a `true`
ConstantNode *true_value = alloc_node<ConstantNode>();
true_value->value = Variant(true);
+ true_value->datatype = _type_from_variant(true_value->value);
p_resulting_node = true_value;
} break;
default: {
-
} break;
}
}
@@ -2625,7 +2735,6 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) {
}
for (int i = 0; i < p_match_statement->branches.size(); i++) {
-
PatternBranchNode *branch = p_match_statement->branches[i];
MatchNode::CompiledPatternBranch compiled_branch;
@@ -2683,9 +2792,11 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) {
LocalVarNode *local_var = branch->body->variables[e->key()];
local_var->assign = e->value();
local_var->set_datatype(local_var->assign->get_datatype());
+ local_var->assignments++;
IdentifierNode *id2 = alloc_node<IdentifierNode>();
id2->name = local_var->name;
+ id2->datatype = local_var->datatype;
id2->declared_block = branch->body;
id2->set_datatype(local_var->assign->get_datatype());
@@ -2706,7 +2817,6 @@ void GDScriptParser::_transform_match_statment(MatchNode *p_match_statement) {
}
void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
-
IndentLevel current_level = indent_level.back()->get();
#ifdef DEBUG_ENABLED
@@ -2733,8 +2843,9 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
is_first_line = false;
GDScriptTokenizer::Token token = tokenizer->get_token();
- if (error_set)
+ if (error_set) {
return;
+ }
if (current_level.indent > indent_level.back()->get().indent) {
p_block->end_line = tokenizer->get_token_line();
@@ -2742,7 +2853,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
}
if (pending_newline != -1) {
-
NewLineNode *nl2 = alloc_node<NewLineNode>();
nl2->line = pending_newline;
p_block->statements.push_back(nl2);
@@ -2774,7 +2884,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
return;
} break;
case GDScriptTokenizer::TK_NEWLINE: {
-
int line = tokenizer->get_token_line();
if (!_parse_newline()) {
@@ -2785,6 +2894,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
return;
}
+ _mark_line_as_safe(line);
NewLineNode *nl2 = alloc_node<NewLineNode>();
nl2->line = line;
p_block->statements.push_back(nl2);
@@ -2792,7 +2902,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
} break;
case GDScriptTokenizer::TK_CF_PASS: {
if (tokenizer->get_token(1) != GDScriptTokenizer::TK_SEMICOLON && tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE && tokenizer->get_token(1) != GDScriptTokenizer::TK_EOF) {
-
_set_error("Expected \";\" or a line break.");
return;
}
@@ -2809,7 +2918,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
tokenizer->advance();
int var_line = tokenizer->get_token_line();
if (!tokenizer->is_token_literal(0, true)) {
-
_set_error("Expected an identifier for the local variable name.");
return;
}
@@ -2854,7 +2962,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
-
tokenizer->advance();
Node *subexpr = _parse_and_reduce_expression(p_block, p_static);
if (!subexpr) {
@@ -2867,7 +2974,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
lv->assignments++;
assigned = subexpr;
} else {
-
assigned = _get_default_value_for_type(lv->datatype, var_line);
}
//must be added later, to avoid self-referencing.
@@ -2888,13 +2994,12 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
lv->assign = assigned;
if (!_end_statement()) {
- _set_error("Expected end of statement (\"var\").");
+ _set_end_statement_error("var");
return;
}
} break;
case GDScriptTokenizer::TK_CF_IF: {
-
tokenizer->advance();
Node *condition = _parse_and_reduce_expression(p_block, p_static);
@@ -2926,17 +3031,18 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
_parse_block(cf_if->body, p_static);
current_block = p_block;
- if (error_set)
+ if (error_set) {
return;
+ }
p_block->statements.push_back(cf_if);
bool all_have_return = cf_if->body->has_return;
bool have_else = false;
while (true) {
-
- while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline())
+ while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline()) {
;
+ }
if (indent_level.back()->get().indent < current_level.indent) { //not at current indent level
p_block->end_line = tokenizer->get_token_line();
@@ -2944,9 +3050,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_CF_ELIF) {
-
if (indent_level.back()->get().indent > current_level.indent) {
-
_set_error("Invalid indentation.");
return;
}
@@ -2986,13 +3090,13 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
current_block = cf_else->body;
_parse_block(cf_else->body, p_static);
current_block = p_block;
- if (error_set)
+ if (error_set) {
return;
+ }
all_have_return = all_have_return && cf_else->body->has_return;
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_CF_ELSE) {
-
if (indent_level.back()->get().indent > current_level.indent) {
_set_error("Invalid indentation.");
return;
@@ -3011,16 +3115,18 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
current_block = cf_if->body_else;
_parse_block(cf_if->body_else, p_static);
current_block = p_block;
- if (error_set)
+ if (error_set) {
return;
+ }
all_have_return = all_have_return && cf_if->body_else->has_return;
have_else = true;
break; //after else, exit
- } else
+ } else {
break;
+ }
}
cf_if->body->has_return = all_have_return;
@@ -3029,7 +3135,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
} break;
case GDScriptTokenizer::TK_CF_WHILE: {
-
tokenizer->advance();
Node *condition2 = _parse_and_reduce_expression(p_block, p_static);
if (!condition2) {
@@ -3046,6 +3151,8 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
cf_while->body = alloc_node<BlockNode>();
cf_while->body->parent_block = p_block;
+ cf_while->body->can_break = true;
+ cf_while->body->can_continue = true;
p_block->sub_blocks.push_back(cf_while->body);
if (!_enter_indent_block(cf_while->body)) {
@@ -3057,17 +3164,15 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
current_block = cf_while->body;
_parse_block(cf_while->body, p_static);
current_block = p_block;
- if (error_set)
+ if (error_set) {
return;
- p_block->has_return = cf_while->body->has_return;
+ }
p_block->statements.push_back(cf_while);
} break;
case GDScriptTokenizer::TK_CF_FOR: {
-
tokenizer->advance();
if (!tokenizer->is_token_literal(0, true)) {
-
_set_error("Identifier expected after \"for\".");
}
@@ -3094,7 +3199,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
DataType iter_type;
if (container->type == Node::TYPE_OPERATOR) {
-
OperatorNode *op = static_cast<OperatorNode *>(container);
if (op->op == OperatorNode::OP_CALL && op->arguments[0]->type == Node::TYPE_BUILT_IN_FUNCTION && static_cast<BuiltInFunctionNode *>(op->arguments[0])->function == GDScriptFunctions::GEN_RANGE) {
//iterating a range, so see if range() can be optimized without allocating memory, by replacing it by vectors (which can work as iterable too!)
@@ -3110,6 +3214,8 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
ConstantNode *c = static_cast<ConstantNode *>(op->arguments[i]);
if (c->value.get_type() == Variant::FLOAT || c->value.get_type() == Variant::INT) {
constants.push_back(c->value);
+ } else {
+ constant = false;
}
} else {
constant = false;
@@ -3117,14 +3223,18 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
}
if (args.size() > 0 && args.size() < 4) {
-
if (constant) {
-
ConstantNode *cn = alloc_node<ConstantNode>();
switch (args.size()) {
- case 1: cn->value = (int)constants[0]; break;
- case 2: cn->value = Vector2(constants[0], constants[1]); break;
- case 3: cn->value = Vector3(constants[0], constants[1], constants[2]); break;
+ case 1:
+ cn->value = (int64_t)constants[0];
+ break;
+ case 2:
+ cn->value = Vector2i(constants[0], constants[1]);
+ break;
+ case 3:
+ cn->value = Vector3i(constants[0], constants[1], constants[2]);
+ break;
}
cn->datatype = _type_from_variant(cn->value);
container = cn;
@@ -3136,9 +3246,15 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
on->arguments.push_back(tn);
switch (args.size()) {
- case 1: tn->vtype = Variant::INT; break;
- case 2: tn->vtype = Variant::VECTOR2; break;
- case 3: tn->vtype = Variant::VECTOR3; break;
+ case 1:
+ tn->vtype = Variant::INT;
+ break;
+ case 2:
+ tn->vtype = Variant::VECTOR2I;
+ break;
+ case 3:
+ tn->vtype = Variant::VECTOR3I;
+ break;
}
for (int i = 0; i < args.size(); i++) {
@@ -3163,6 +3279,8 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
cf_for->body = alloc_node<BlockNode>();
cf_for->body->parent_block = p_block;
+ cf_for->body->can_break = true;
+ cf_for->body->can_continue = true;
p_block->sub_blocks.push_back(cf_for->body);
if (!_enter_indent_block(cf_for->body)) {
@@ -3186,12 +3304,26 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
_parse_block(cf_for->body, p_static);
current_block = p_block;
- if (error_set)
+ if (error_set) {
return;
- p_block->has_return = cf_for->body->has_return;
+ }
p_block->statements.push_back(cf_for);
} break;
case GDScriptTokenizer::TK_CF_CONTINUE: {
+ BlockNode *upper_block = p_block;
+ bool is_continue_valid = false;
+ while (upper_block) {
+ if (upper_block->can_continue) {
+ is_continue_valid = true;
+ break;
+ }
+ upper_block = upper_block->parent_block;
+ }
+
+ if (!is_continue_valid) {
+ _set_error("Unexpected keyword \"continue\" outside a loop.");
+ return;
+ }
_mark_line_as_safe(tokenizer->get_token_line());
tokenizer->advance();
@@ -3199,11 +3331,25 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
cf_continue->cf_type = ControlFlowNode::CF_CONTINUE;
p_block->statements.push_back(cf_continue);
if (!_end_statement()) {
- _set_error("Expected end of statement (\"continue\").");
+ _set_end_statement_error("continue");
return;
}
} break;
case GDScriptTokenizer::TK_CF_BREAK: {
+ BlockNode *upper_block = p_block;
+ bool is_break_valid = false;
+ while (upper_block) {
+ if (upper_block->can_break) {
+ is_break_valid = true;
+ break;
+ }
+ upper_block = upper_block->parent_block;
+ }
+
+ if (!is_break_valid) {
+ _set_error("Unexpected keyword \"break\" outside a loop.");
+ return;
+ }
_mark_line_as_safe(tokenizer->get_token_line());
tokenizer->advance();
@@ -3211,12 +3357,11 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
cf_break->cf_type = ControlFlowNode::CF_BREAK;
p_block->statements.push_back(cf_break);
if (!_end_statement()) {
- _set_error("Expected end of statement (\"break\").");
+ _set_end_statement_error("break");
return;
}
} break;
case GDScriptTokenizer::TK_CF_RETURN: {
-
tokenizer->advance();
ControlFlowNode *cf_return = alloc_node<ControlFlowNode>();
cf_return->cf_type = ControlFlowNode::CF_RETURN;
@@ -3240,7 +3385,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
cf_return->arguments.push_back(retexpr);
p_block->statements.push_back(cf_return);
if (!_end_statement()) {
- _set_error("Expected end of statement after return expression.");
+ _set_end_statement_error("return");
return;
}
}
@@ -3248,7 +3393,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
} break;
case GDScriptTokenizer::TK_CF_MATCH: {
-
tokenizer->advance();
MatchNode *match_node = alloc_node<MatchNode>();
@@ -3272,12 +3416,15 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
BlockNode *compiled_branches = alloc_node<BlockNode>();
compiled_branches->parent_block = p_block;
compiled_branches->parent_class = p_block->parent_class;
+ compiled_branches->can_continue = true;
p_block->sub_blocks.push_back(compiled_branches);
_parse_pattern_block(compiled_branches, match_node->branches, p_static);
- if (error_set) return;
+ if (error_set) {
+ return;
+ }
ControlFlowNode *match_cf_node = alloc_node<ControlFlowNode>();
match_cf_node->cf_type = ControlFlowNode::CF_MATCH;
@@ -3290,7 +3437,6 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
_end_statement();
} break;
case GDScriptTokenizer::TK_PR_ASSERT: {
-
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
@@ -3298,6 +3444,8 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
return;
}
+ int assert_line = tokenizer->get_token_line();
+
tokenizer->advance();
Vector<Node *> args;
@@ -3307,41 +3455,41 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
}
if (args.empty() || args.size() > 2) {
- _set_error("Wrong number of arguments, expected 1 or 2");
+ _set_error("Wrong number of arguments, expected 1 or 2", assert_line);
return;
}
AssertNode *an = alloc_node<AssertNode>();
an->condition = _reduce_expression(args[0], p_static);
+ an->line = assert_line;
if (args.size() == 2) {
an->message = _reduce_expression(args[1], p_static);
} else {
ConstantNode *message_node = alloc_node<ConstantNode>();
message_node->value = String();
+ message_node->datatype = _type_from_variant(message_node->value);
an->message = message_node;
}
p_block->statements.push_back(an);
if (!_end_statement()) {
- _set_error("Expected end of statement after \"assert\".");
+ _set_end_statement_error("assert");
return;
}
} break;
case GDScriptTokenizer::TK_PR_BREAKPOINT: {
-
tokenizer->advance();
BreakpointNode *bn = alloc_node<BreakpointNode>();
p_block->statements.push_back(bn);
if (!_end_statement()) {
- _set_error("Expected end of statement after \"breakpoint\".");
+ _set_end_statement_error("breakpoint");
return;
}
} break;
default: {
-
Node *expression = _parse_and_reduce_expression(p_block, p_static, false, true);
if (!expression) {
if (_recover_from_completion()) {
@@ -3355,7 +3503,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_COLON && tokenizer->get_token(1) == GDScriptTokenizer::TK_OP_ASSIGN) {
_set_error("Unexpected ':=', use '=' instead. Expected end of statement after expression.");
} else {
- _set_error(String() + "Expected end of statement after expression, got " + tokenizer->get_token_name(tokenizer->get_token()) + " instead");
+ _set_error(vformat("Expected end of statement after expression, got %s instead.", tokenizer->get_token_name(tokenizer->get_token())));
}
return;
}
@@ -3366,9 +3514,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) {
}
bool GDScriptParser::_parse_newline() {
-
if (tokenizer->get_token(1) != GDScriptTokenizer::TK_EOF && tokenizer->get_token(1) != GDScriptTokenizer::TK_NEWLINE) {
-
IndentLevel current_level = indent_level.back()->get();
int indent = tokenizer->get_token_line_indent();
int tabs = tokenizer->get_token_line_tab_indent();
@@ -3385,9 +3531,7 @@ bool GDScriptParser::_parse_newline() {
}
if (indent < current_level.indent) {
-
while (indent < current_level.indent) {
-
//exit block
if (indent_level.size() == 1) {
_set_error("Invalid indentation. Bug?");
@@ -3397,7 +3541,6 @@ bool GDScriptParser::_parse_newline() {
indent_level.pop_back();
if (indent_level.back()->get().indent < indent) {
-
_set_error("Unindent does not match any outer indentation level.");
return false;
}
@@ -3420,15 +3563,12 @@ bool GDScriptParser::_parse_newline() {
}
void GDScriptParser::_parse_extends(ClassNode *p_class) {
-
if (p_class->extends_used) {
-
_set_error("\"extends\" can only be present once per script.");
return;
}
if (!p_class->constant_expressions.empty() || !p_class->subclasses.empty() || !p_class->functions.empty() || !p_class->variables.empty()) {
-
_set_error("\"extends\" must be used before anything else.");
return;
}
@@ -3445,10 +3585,8 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) {
// see if inheritance happens from a file
if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT) {
-
Variant constant = tokenizer->get_token_constant();
if (constant.get_type() != Variant::STRING) {
-
_set_error("\"extends\" constant must be a string.");
return;
}
@@ -3465,16 +3603,14 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) {
if (tokenizer->get_token() != GDScriptTokenizer::TK_PERIOD) {
return;
- } else
+ } else {
tokenizer->advance();
+ }
}
while (true) {
-
switch (tokenizer->get_token()) {
-
case GDScriptTokenizer::TK_IDENTIFIER: {
-
StringName identifier = tokenizer->get_token_identifier();
p_class->extends_class.push_back(identifier);
} break;
@@ -3483,7 +3619,6 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) {
break;
default: {
-
_set_error("Invalid \"extends\" syntax, expected string constant (path) and/or identifier (parent class).");
return;
}
@@ -3492,7 +3627,6 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) {
tokenizer->advance(1);
switch (tokenizer->get_token()) {
-
case GDScriptTokenizer::TK_IDENTIFIER:
case GDScriptTokenizer::TK_PERIOD:
continue;
@@ -3504,14 +3638,13 @@ void GDScriptParser::_parse_extends(ClassNode *p_class) {
}
void GDScriptParser::_parse_class(ClassNode *p_class) {
-
IndentLevel current_level = indent_level.back()->get();
while (true) {
-
GDScriptTokenizer::Token token = tokenizer->get_token();
- if (error_set)
+ if (error_set) {
return;
+ }
if (current_level.indent > indent_level.back()->get().indent) {
p_class->end_line = tokenizer->get_token_line();
@@ -3519,7 +3652,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
switch (token) {
-
case GDScriptTokenizer::TK_CURSOR: {
tokenizer->advance();
} break;
@@ -3539,19 +3671,18 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
} break;
case GDScriptTokenizer::TK_PR_EXTENDS: {
-
_mark_line_as_safe(tokenizer->get_token_line());
_parse_extends(p_class);
- if (error_set)
+ if (error_set) {
return;
+ }
if (!_end_statement()) {
- _set_error("Expected end of statement after \"extends\".");
+ _set_end_statement_error("extends");
return;
}
} break;
case GDScriptTokenizer::TK_PR_CLASS_NAME: {
-
_mark_line_as_safe(tokenizer->get_token_line());
if (p_class->owner) {
_set_error("\"class_name\" is only valid for the main class namespace.");
@@ -3562,7 +3693,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
return;
}
if (tokenizer->get_token(1) != GDScriptTokenizer::TK_IDENTIFIER) {
-
_set_error("\"class_name\" syntax: \"class_name <UniqueName>\"");
return;
}
@@ -3628,9 +3758,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
} break;
case GDScriptTokenizer::TK_PR_TOOL: {
-
if (p_class->tool) {
-
_set_error("The \"tool\" keyword can only be present once per script.");
return;
}
@@ -3645,7 +3773,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
StringName name;
if (tokenizer->get_token(1) != GDScriptTokenizer::TK_IDENTIFIER) {
-
_set_error("\"class\" syntax: \"class <Name>:\" or \"class <Name> extends <BaseClass>:\"");
return;
}
@@ -3673,6 +3800,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_set_error("A constant named \"" + String(name) + "\" already exists in the outer class scope (at line" + itos(outer_class->constant_expressions[name].expression->line) + ").");
return;
}
+ for (int i = 0; i < outer_class->variables.size(); i++) {
+ if (outer_class->variables[i].identifier == name) {
+ _set_error("A variable named \"" + String(name) + "\" already exists in the outer class scope (at line " + itos(outer_class->variables[i].line) + ").");
+ return;
+ }
+ }
outer_class = outer_class->owner;
}
@@ -3688,14 +3821,13 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
p_class->subclasses.push_back(newclass);
if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_EXTENDS) {
-
_parse_extends(newclass);
- if (error_set)
+ if (error_set) {
return;
+ }
}
if (!_enter_indent_block()) {
-
_set_error("Indented block expected.");
return;
}
@@ -3713,7 +3845,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
case GDScriptTokenizer::TK_PR_STATIC: {
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
-
_set_error("Expected \"func\".");
return;
}
@@ -3721,12 +3852,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
[[fallthrough]];
}
case GDScriptTokenizer::TK_PR_FUNCTION: {
-
bool _static = false;
pending_newline = -1;
if (tokenizer->get_token(-1) == GDScriptTokenizer::TK_PR_STATIC) {
-
_static = true;
}
@@ -3737,7 +3866,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (name == StringName()) {
-
_set_error("Expected an identifier after \"func\" (syntax: \"func <identifier>([arguments]):\").");
return;
}
@@ -3770,7 +3898,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
#endif // DEBUG_ENABLED
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
-
_set_error("Expected \"(\" after the identifier (syntax: \"func <identifier>([arguments]):\" ).");
return;
}
@@ -3790,19 +3917,16 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
//has arguments
bool defaulting = false;
while (true) {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
tokenizer->advance();
continue;
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_VAR) {
-
tokenizer->advance(); //var before the identifier is allowed
}
if (!tokenizer->is_token_literal(0, true)) {
-
_set_error("Expected an identifier for an argument.");
return;
}
@@ -3834,7 +3958,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
argument_types.push_back(argtype);
if (defaulting && tokenizer->get_token() != GDScriptTokenizer::TK_OP_ASSIGN) {
-
_set_error("Default parameter expected.");
return;
}
@@ -3845,8 +3968,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
defaulting = true;
tokenizer->advance(1);
Node *defval = _parse_and_reduce_expression(p_class, _static);
- if (!defval || error_set)
+ if (!defval || error_set) {
return;
+ }
OperatorNode *on = alloc_node<OperatorNode>();
on->op = OperatorNode::OP_ASSIGN;
@@ -3875,7 +3999,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
continue;
} else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
-
_set_error("Expected \",\" or \")\".");
return;
}
@@ -3903,14 +4026,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
rpc_mode = MultiplayerAPI::RPC_MODE_DISABLED;
if (name == "_init") {
-
if (_static) {
_set_error("The constructor cannot be static.");
return;
}
if (p_class->extends_used) {
-
OperatorNode *cparent = alloc_node<OperatorNode>();
cparent->op = OperatorNode::OP_PARENT_CALL;
block->statements.push_back(cparent);
@@ -3931,7 +4052,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
//has arguments
parenthesis++;
while (true) {
-
current_function = function;
Node *arg = _parse_and_reduce_expression(p_class, _static);
current_function = nullptr;
@@ -3941,7 +4061,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
continue;
} else if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
-
_set_error("Expected \",\" or \")\".");
return;
}
@@ -3954,9 +4073,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
}
} else {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_PERIOD) {
-
_set_error("Parent constructor call found for a class without inheritance.");
return;
}
@@ -3965,7 +4082,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
DataType return_type;
if (tokenizer->get_token() == GDScriptTokenizer::TK_FORWARD_ARROW) {
-
if (!_parse_type(return_type, true)) {
_set_error("Expected a return type for the function.");
return;
@@ -3973,17 +4089,17 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (!_enter_indent_block(block)) {
-
- _set_error("Indented block expected.");
+ _set_error(vformat("Indented block expected after declaration of \"%s\" function.", function->name));
return;
}
function->return_type = return_type;
- if (_static)
+ if (_static) {
p_class->static_functions.push_back(function);
- else
+ } else {
p_class->functions.push_back(function);
+ }
current_function = function;
function->body = block;
@@ -4005,6 +4121,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
sig.name = tokenizer->get_token_identifier();
sig.emissions = 0;
sig.line = tokenizer->get_token_line();
+
+ for (int i = 0; i < current_class->_signals.size(); i++) {
+ if (current_class->_signals[i].name == sig.name) {
+ _set_error("The signal \"" + sig.name + "\" already exists in this class (at line: " + itos(current_class->_signals[i].line) + ").");
+ return;
+ }
+ }
+
tokenizer->advance();
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
@@ -4044,16 +4168,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
p_class->_signals.push_back(sig);
if (!_end_statement()) {
- _set_error("Expected end of statement (\"signal\").");
+ _set_end_statement_error("signal");
return;
}
} break;
case GDScriptTokenizer::TK_PR_EXPORT: {
-
tokenizer->advance();
if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_OPEN) {
-
#define _ADVANCE_AND_CONSUME_NEWLINES \
do { \
tokenizer->advance(); \
@@ -4078,7 +4200,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_TYPE) {
-
Variant::Type type = tokenizer->get_token_type();
if (type == Variant::NIL) {
_set_error("Can't export null type.");
@@ -4097,11 +4218,8 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_ADVANCE_AND_CONSUME_NEWLINES;
switch (type) {
-
case Variant::INT: {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FLAGS") {
-
_ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
@@ -4114,7 +4232,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
bool first = true;
while (true) {
-
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
current_export = PropertyInfo();
_set_error("Expected a string constant in the named bit flags hint.");
@@ -4122,16 +4239,18 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
String c = tokenizer->get_token_constant();
- if (!first)
+ if (!first) {
current_export.hint_string += ",";
- else
+ } else {
first = false;
+ }
current_export.hint_string += c.xml_escape();
_ADVANCE_AND_CONSUME_NEWLINES;
- if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
break;
+ }
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
current_export = PropertyInfo();
@@ -4145,7 +4264,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_RENDER") {
-
_ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" in the layers 2D render hint.");
@@ -4156,7 +4274,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_PHYSICS") {
-
_ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" in the layers 2D physics hint.");
@@ -4167,7 +4284,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_RENDER") {
-
_ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" in the layers 3D render hint.");
@@ -4178,7 +4294,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_PHYSICS") {
-
_ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
_set_error("Expected \")\" in the layers 3D physics hint.");
@@ -4193,25 +4308,25 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
current_export.hint = PROPERTY_HINT_ENUM;
bool first = true;
while (true) {
-
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
-
current_export = PropertyInfo();
_set_error("Expected a string constant in the enumeration hint.");
return;
}
String c = tokenizer->get_token_constant();
- if (!first)
+ if (!first) {
current_export.hint_string += ",";
- else
+ } else {
first = false;
+ }
current_export.hint_string += c.xml_escape();
_ADVANCE_AND_CONSUME_NEWLINES;
- if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
break;
+ }
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
current_export = PropertyInfo();
@@ -4228,7 +4343,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
[[fallthrough]];
}
case Variant::FLOAT: {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EASE") {
current_export.hint = PROPERTY_HINT_EXP_EASING;
_ADVANCE_AND_CONSUME_NEWLINES;
@@ -4241,19 +4355,19 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
// range
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EXP") {
-
current_export.hint = PROPERTY_HINT_EXP_RANGE;
_ADVANCE_AND_CONSUME_NEWLINES;
- if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
break;
- else if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
+ } else if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
_set_error("Expected \")\" or \",\" in the exponential range hint.");
return;
}
_ADVANCE_AND_CONSUME_NEWLINES;
- } else
+ } else {
current_export.hint = PROPERTY_HINT_RANGE;
+ }
float sign = 1.0;
@@ -4262,7 +4376,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
_ADVANCE_AND_CONSUME_NEWLINES;
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
-
current_export = PropertyInfo();
_set_error("Expected a range in the numeric hint.");
return;
@@ -4277,7 +4390,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
-
current_export = PropertyInfo();
_set_error("Expected \",\" or \")\" in the numeric range hint.");
return;
@@ -4292,7 +4404,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
-
current_export = PropertyInfo();
_set_error("Expected a number as upper bound in the numeric range hint.");
return;
@@ -4301,11 +4412,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
current_export.hint_string += "," + rtos(sign * double(tokenizer->get_token_constant()));
_ADVANCE_AND_CONSUME_NEWLINES;
- if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
break;
+ }
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
-
current_export = PropertyInfo();
_set_error("Expected \",\" or \")\" in the numeric range hint.");
return;
@@ -4319,7 +4430,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || !tokenizer->get_token_constant().is_num()) {
-
current_export = PropertyInfo();
_set_error("Expected a number as step in the numeric range hint.");
return;
@@ -4330,30 +4440,29 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
} break;
case Variant::STRING: {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING) {
//enumeration
current_export.hint = PROPERTY_HINT_ENUM;
bool first = true;
while (true) {
-
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
-
current_export = PropertyInfo();
_set_error("Expected a string constant in the enumeration hint.");
return;
}
String c = tokenizer->get_token_constant();
- if (!first)
+ if (!first) {
current_export.hint_string += ",";
- else
+ } else {
first = false;
+ }
current_export.hint_string += c.xml_escape();
_ADVANCE_AND_CONSUME_NEWLINES;
- if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
break;
+ }
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
current_export = PropertyInfo();
@@ -4367,13 +4476,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "DIR") {
-
_ADVANCE_AND_CONSUME_NEWLINES;
- if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
current_export.hint = PROPERTY_HINT_DIR;
- else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
-
+ } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
_ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER || !(tokenizer->get_token_identifier() == "GLOBAL")) {
@@ -4399,16 +4506,13 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "FILE") {
-
current_export.hint = PROPERTY_HINT_FILE;
_ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
-
_ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "GLOBAL") {
-
if (!p_class->tool) {
_set_error("Global filesystem hints may only be used in tool scripts.");
return;
@@ -4416,22 +4520,22 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
current_export.hint = PROPERTY_HINT_GLOBAL_FILE;
_ADVANCE_AND_CONSUME_NEWLINES;
- if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE)
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
break;
- else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA)
+ } else if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) {
_ADVANCE_AND_CONSUME_NEWLINES;
- else {
+ } else {
_set_error("Expected \")\" or \",\" in the hint.");
return;
}
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type() != Variant::STRING) {
-
- if (current_export.hint == PROPERTY_HINT_GLOBAL_FILE)
+ if (current_export.hint == PROPERTY_HINT_GLOBAL_FILE) {
_set_error("Expected string constant with filter.");
- else
+ } else {
_set_error("Expected \"GLOBAL\" or string constant with filter.");
+ }
return;
}
current_export.hint_string = tokenizer->get_token_constant();
@@ -4446,7 +4550,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "MULTILINE") {
-
current_export.hint = PROPERTY_HINT_MULTILINE_TEXT;
_ADVANCE_AND_CONSUME_NEWLINES;
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
@@ -4457,9 +4560,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
} break;
case Variant::COLOR: {
-
if (tokenizer->get_token() != GDScriptTokenizer::TK_IDENTIFIER) {
-
current_export = PropertyInfo();
_set_error("Color type hint expects RGB or RGBA as hints.");
return;
@@ -4479,7 +4580,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
} break;
default: {
-
current_export = PropertyInfo();
_set_error("Type \"" + Variant::get_type_name(type) + "\" can't take hints.");
return;
@@ -4488,7 +4588,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
} else {
-
parenthesis++;
Node *subexpr = _parse_and_reduce_expression(p_class, true, true);
if (!subexpr) {
@@ -4548,10 +4647,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
bool first = true;
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
if (enum_values[E->get()].get_type() == Variant::INT) {
- if (!first)
+ if (!first) {
current_export.hint_string += ",";
- else
+ } else {
first = false;
+ }
current_export.hint_string += E->get().operator String().camelcase_to_underscore(true).capitalize().xml_escape();
if (!is_flags) {
@@ -4568,7 +4668,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
-
current_export = PropertyInfo();
_set_error("Expected \")\" or \",\" after the export hint.");
return;
@@ -4590,7 +4689,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_ONREADY && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTE && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTER && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPET && tokenizer->get_token() != GDScriptTokenizer::TK_PR_REMOTESYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_MASTERSYNC && tokenizer->get_token() != GDScriptTokenizer::TK_PR_PUPPETSYNC) {
-
current_export = PropertyInfo();
_set_error("Expected \"var\", \"onready\", \"remote\", \"master\", \"puppet\", \"remotesync\", \"mastersync\", \"puppetsync\".");
return;
@@ -4599,7 +4697,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
continue;
} break;
case GDScriptTokenizer::TK_PR_ONREADY: {
-
//may be fallthrough from export, ignore if so
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR) {
@@ -4610,7 +4707,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
continue;
} break;
case GDScriptTokenizer::TK_PR_REMOTE: {
-
//may be fallthrough from export, ignore if so
tokenizer->advance();
if (current_export.type) {
@@ -4630,7 +4726,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
continue;
} break;
case GDScriptTokenizer::TK_PR_MASTER: {
-
//may be fallthrough from export, ignore if so
tokenizer->advance();
if (current_export.type) {
@@ -4650,7 +4745,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
continue;
} break;
case GDScriptTokenizer::TK_PR_PUPPET: {
-
//may be fallthrough from export, ignore if so
tokenizer->advance();
if (current_export.type) {
@@ -4670,14 +4764,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
continue;
} break;
case GDScriptTokenizer::TK_PR_REMOTESYNC: {
-
//may be fallthrough from export, ignore if so
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
- if (current_export.type)
+ if (current_export.type) {
_set_error("Expected \"var\".");
- else
+ } else {
_set_error("Expected \"var\" or \"func\".");
+ }
return;
}
@@ -4685,14 +4779,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
continue;
} break;
case GDScriptTokenizer::TK_PR_MASTERSYNC: {
-
//may be fallthrough from export, ignore if so
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
- if (current_export.type)
+ if (current_export.type) {
_set_error("Expected \"var\".");
- else
+ } else {
_set_error("Expected \"var\" or \"func\".");
+ }
return;
}
@@ -4700,14 +4794,14 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
continue;
} break;
case GDScriptTokenizer::TK_PR_PUPPETSYNC: {
-
//may be fallthrough from export, ignore if so
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_PR_VAR && tokenizer->get_token() != GDScriptTokenizer::TK_PR_FUNCTION) {
- if (current_export.type)
+ if (current_export.type) {
_set_error("Expected \"var\".");
- else
+ } else {
_set_error("Expected \"var\" or \"func\".");
+ }
return;
}
@@ -4729,7 +4823,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (!tokenizer->is_token_literal(0, true)) {
-
_set_error("Expected an identifier for the member variable name.");
return;
}
@@ -4819,7 +4912,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
#endif
if (tokenizer->get_token() == GDScriptTokenizer::TK_OP_ASSIGN) {
-
#ifdef DEBUG_ENABLED
int line = tokenizer->get_token_line();
#endif
@@ -4835,12 +4927,10 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
//discourage common error
if (!onready && subexpr->type == Node::TYPE_OPERATOR) {
-
OperatorNode *op = static_cast<OperatorNode *>(subexpr);
if (op->op == OperatorNode::OP_CALL && op->arguments[0]->type == Node::TYPE_SELF && op->arguments[1]->type == Node::TYPE_IDENTIFIER) {
IdentifierNode *id = static_cast<IdentifierNode *>(op->arguments[1]);
if (id->name == "get_node") {
-
_set_error("Use \"onready var " + String(member.identifier) + " = get_node(...)\" instead.");
return;
}
@@ -4850,19 +4940,21 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
member.expression = subexpr;
if (autoexport && !member.data_type.has_type) {
-
if (subexpr->type != Node::TYPE_CONSTANT) {
-
_set_error("Type-less export needs a constant expression assigned to infer type.");
return;
}
ConstantNode *cn = static_cast<ConstantNode *>(subexpr);
if (cn->value.get_type() == Variant::NIL) {
-
_set_error("Can't accept a null constant expression for inferring export type.");
return;
}
+
+ if (!_reduce_export_var_type(cn->value, member.line)) {
+ return;
+ }
+
member._export.type = cn->value.get_type();
member._export.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
if (cn->value.get_type() == Variant::OBJECT) {
@@ -4878,7 +4970,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
#ifdef TOOLS_ENABLED
if (subexpr->type == Node::TYPE_CONSTANT && (member._export.type != Variant::NIL || member.data_type.has_type)) {
-
ConstantNode *cn = static_cast<ConstantNode *>(subexpr);
if (cn->value.get_type() != Variant::NIL) {
if (member._export.type != Variant::NIL && cn->value.get_type() != member._export.type) {
@@ -4898,6 +4989,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
IdentifierNode *id = alloc_node<IdentifierNode>();
id->name = member.identifier;
+ id->datatype = member.data_type;
OperatorNode *op = alloc_node<OperatorNode>();
op->op = OperatorNode::OP_INIT_ASSIGN;
@@ -4907,20 +4999,21 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
#ifdef DEBUG_ENABLED
NewLineNode *nl2 = alloc_node<NewLineNode>();
nl2->line = line;
- if (onready)
+ if (onready) {
p_class->ready->statements.push_back(nl2);
- else
+ } else {
p_class->initializer->statements.push_back(nl2);
+ }
#endif
- if (onready)
+ if (onready) {
p_class->ready->statements.push_back(op);
- else
+ } else {
p_class->initializer->statements.push_back(op);
+ }
member.initial_assignment = op;
} else {
-
if (autoexport && !member.data_type.has_type) {
_set_error("Type-less export needs a constant expression assigned to infer type.");
return;
@@ -4940,6 +5033,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
IdentifierNode *id = alloc_node<IdentifierNode>();
id->name = member.identifier;
+ id->datatype = member.data_type;
OperatorNode *op = alloc_node<OperatorNode>();
op->op = OperatorNode::OP_INIT_ASSIGN;
@@ -4952,7 +5046,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (tokenizer->get_token() == GDScriptTokenizer::TK_PR_SETGET) {
-
tokenizer->advance();
if (tokenizer->get_token() != GDScriptTokenizer::TK_COMMA) {
@@ -4982,7 +5075,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
p_class->variables.push_back(member);
if (!_end_statement()) {
- _set_error("Expected end of statement (\"continue\").");
+ _set_end_statement_error("var");
return;
}
} break;
@@ -4993,7 +5086,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
tokenizer->advance();
if (!tokenizer->is_token_literal(0, true)) {
-
_set_error("Expected an identifier for the constant.");
return;
}
@@ -5062,7 +5154,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
p_class->constant_expressions.insert(const_id, constant);
if (!_end_statement()) {
- _set_error("Expected end of statement (constant).", line);
+ _set_end_statement_error("const");
return;
}
@@ -5109,14 +5201,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
while (true) {
if (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE) {
-
tokenizer->advance(); // Ignore newlines
} else if (tokenizer->get_token() == GDScriptTokenizer::TK_CURLY_BRACKET_CLOSE) {
-
tokenizer->advance();
break; // End of enum
} else if (!tokenizer->is_token_literal(0, true)) {
-
if (tokenizer->get_token() == GDScriptTokenizer::TK_EOF) {
_set_error("Unexpected end of file.");
} else {
@@ -5216,7 +5305,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
if (!_end_statement()) {
- _set_error("Expected end of statement (\"enum\").");
+ _set_end_statement_error("enum");
return;
}
@@ -5237,7 +5326,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
} break;
default: {
-
_set_error(String() + "Unexpected token: " + tokenizer->get_token_name(tokenizer->get_token()) + ":" + tokenizer->get_token_identifier());
return;
@@ -5247,7 +5335,6 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
}
void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive) {
-
if (p_class->base_type.has_type) {
// Already determined
} else if (p_class->extends_used) {
@@ -5262,7 +5349,6 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
//path (and optionally subclasses)
if (path.is_rel_path()) {
-
String base = base_path;
if (base == "" || base.is_rel_path()) {
@@ -5277,22 +5363,17 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
return;
}
if (!script->is_valid()) {
-
_set_error("Script isn't fully loaded (cyclic preload?): " + path, p_class->line);
return;
}
if (p_class->extends_class.size()) {
-
for (int i = 0; i < p_class->extends_class.size(); i++) {
-
String sub = p_class->extends_class[i];
if (script->get_subclasses().has(sub)) {
-
Ref<Script> subclass = script->get_subclasses()[sub]; //avoid reference from disappearing
script = subclass;
} else {
-
_set_error("Couldn't find the subclass: " + sub, p_class->line);
return;
}
@@ -5300,7 +5381,6 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
}
} else {
-
if (p_class->extends_class.size() == 0) {
_set_error("Parser bug: undecidable inheritance.", p_class->line);
ERR_FAIL();
@@ -5347,7 +5427,6 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
}
while (p) {
-
bool found = false;
for (int i = 0; i < p->subclasses.size(); i++) {
@@ -5376,8 +5455,12 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
}
}
- if (base_class) break;
- if (found) continue;
+ if (base_class) {
+ break;
+ }
+ if (found) {
+ continue;
+ }
if (p->constant_expressions.has(base)) {
if (p->constant_expressions[base].expression->type != Node::TYPE_CONSTANT) {
@@ -5397,21 +5480,17 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
}
if (base_script.is_valid()) {
-
String ident = base;
Ref<GDScript> find_subclass = base_script;
for (int i = extend_iter; i < p_class->extends_class.size(); i++) {
-
String subclass = p_class->extends_class[i];
ident += ("." + subclass);
if (find_subclass->get_subclasses().has(subclass)) {
-
find_subclass = find_subclass->get_subclasses()[subclass];
} else if (find_subclass->get_constants().has(subclass)) {
-
Ref<GDScript> new_base_class = find_subclass->get_constants()[subclass];
if (new_base_class.is_null()) {
_set_error("Constant isn't a class: " + ident, p_class->line);
@@ -5419,7 +5498,6 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
}
find_subclass = new_base_class;
} else {
-
_set_error("Couldn't find the subclass: " + ident, p_class->line);
return;
}
@@ -5428,15 +5506,12 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
script = find_subclass;
} else if (!base_class) {
-
if (p_class->extends_class.size() > 1) {
-
_set_error("Invalid inheritance (unknown class + subclasses).", p_class->line);
return;
}
//if not found, try engine classes
if (!GDScriptLanguage::get_singleton()->get_global_map().has(base)) {
-
_set_error("Unknown class: \"" + base + "\"", p_class->line);
return;
}
@@ -5479,10 +5554,14 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive
}
String GDScriptParser::DataType::to_string() const {
- if (!has_type) return "var";
+ if (!has_type) {
+ return "var";
+ }
switch (kind) {
case BUILTIN: {
- if (builtin_type == Variant::NIL) return "null";
+ if (builtin_type == Variant::NIL) {
+ return "null";
+ }
return Variant::get_type_name(builtin_type);
} break;
case NATIVE: {
@@ -5646,8 +5725,12 @@ bool GDScriptParser::_parse_type(DataType &r_type, bool p_can_be_void) {
}
GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source, int p_line) {
- if (!p_source.has_type) return p_source;
- if (p_source.kind != DataType::UNRESOLVED) return p_source;
+ if (!p_source.has_type) {
+ return p_source;
+ }
+ if (p_source.kind != DataType::UNRESOLVED) {
+ return p_source;
+ }
Vector<String> full_name = p_source.native_type.operator String().split(".", false);
int name_part = 0;
@@ -5656,7 +5739,6 @@ GDScriptParser::DataType GDScriptParser::_resolve_type(const DataType &p_source,
result.has_type = true;
while (name_part < full_name.size()) {
-
bool found = false;
StringName id = full_name[name_part];
DataType base_type = result;
@@ -6229,11 +6311,13 @@ GDScriptParser::Node *GDScriptParser::_get_default_value_for_type(const DataType
ConstantNode *c = alloc_node<ConstantNode>();
Callable::CallError err;
c->value = Variant::construct(p_type.builtin_type, nullptr, 0, err);
+ c->datatype = _type_from_variant(c->value);
result = c;
}
} else {
ConstantNode *c = alloc_node<ConstantNode>();
c->value = Variant();
+ c->datatype = _type_from_variant(c->value);
result = c;
}
@@ -6316,7 +6400,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
DataType source_type = _reduce_node_type(cn->source_node);
cn->cast_type = _resolve_type(cn->cast_type, cn->line);
if (source_type.has_type) {
-
bool valid = false;
if (check_types) {
if (cn->cast_type.kind == DataType::BUILTIN && source_type.kind == DataType::BUILTIN) {
@@ -6370,7 +6453,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
} break;
case OperatorNode::OP_IS:
case OperatorNode::OP_IS_BUILTIN: {
-
if (op->arguments.size() != 2) {
_set_error("Parser bug: binary operation without 2 arguments.", op->line);
ERR_FAIL_V(DataType());
@@ -6406,7 +6488,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
case OperatorNode::OP_POS:
case OperatorNode::OP_NOT:
case OperatorNode::OP_BIT_INVERT: {
-
DataType argument_type = _reduce_node_type(op->arguments[0]);
if (!argument_type.has_type) {
break;
@@ -6444,7 +6525,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
case OperatorNode::OP_BIT_AND:
case OperatorNode::OP_BIT_OR:
case OperatorNode::OP_BIT_XOR: {
-
if (op->arguments.size() != 2) {
_set_error("Parser bug: binary operation without 2 arguments.", op->line);
ERR_FAIL_V(DataType());
@@ -6512,7 +6592,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
case OperatorNode::OP_ASSIGN_BIT_OR:
case OperatorNode::OP_ASSIGN_BIT_XOR:
case OperatorNode::OP_INIT_ASSIGN: {
-
_set_error("Assignment inside an expression isn't allowed (parser bug?).", op->line);
return DataType();
@@ -6562,6 +6641,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
node_type = _reduce_identifier_type(&base_type, member_id->name, op->line, true);
#ifdef DEBUG_ENABLED
if (!node_type.has_type) {
+ _mark_line_as_unsafe(op->line);
_add_warning(GDScriptWarning::UNSAFE_PROPERTY_ACCESS, op->line, member_id->name.operator String(), base_type.to_string());
}
#endif // DEBUG_ENABLED
@@ -6574,7 +6654,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
}
} break;
case OperatorNode::OP_INDEX: {
-
if (op->arguments[1]->type == Node::TYPE_CONSTANT) {
ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[1]);
if (cn->value.get_type() == Variant::STRING) {
@@ -6582,6 +6661,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
IdentifierNode *id = alloc_node<IdentifierNode>();
id->name = cn->value.operator StringName();
+ id->datatype = cn->datatype;
op->op = OperatorNode::OP_INDEX_NAMED;
op->arguments.write[1] = id;
@@ -6772,7 +6852,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) {
}
bool GDScriptParser::_get_function_signature(DataType &p_base_type, const StringName &p_function, DataType &r_return_type, List<DataType> &r_arg_types, int &r_default_arg_count, bool &r_static, bool &r_vararg) const {
-
r_static = false;
r_default_arg_count = 0;
@@ -6883,7 +6962,9 @@ bool GDScriptParser::_get_function_signature(DataType &p_base_type, const String
native = "_" + native.operator String();
}
if (!ClassDB::class_exists(native)) {
- if (!check_types) return false;
+ if (!check_types) {
+ return false;
+ }
ERR_FAIL_V_MSG(false, "Parser bug: Class '" + String(native) + "' not found.");
}
@@ -6974,7 +7055,9 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
par_types.write[i - 1] = _reduce_node_type(p_call->arguments[i]);
}
- if (error_set) return DataType();
+ if (error_set) {
+ return DataType();
+ }
// Special case: check copy constructor. Those are defined implicitly in Variant.
if (par_types.size() == 1) {
@@ -7042,7 +7125,9 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
err += "' matches the signature '";
err += Variant::get_type_name(tn->vtype) + "(";
for (int i = 0; i < par_types.size(); i++) {
- if (i > 0) err += ", ";
+ if (i > 0) {
+ err += ", ";
+ }
err += par_types[i].to_string();
}
err += ")'.";
@@ -7271,7 +7356,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat
return return_type;
}
-bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringName &p_member, DataType &r_member_type) const {
+bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringName &p_member, DataType &r_member_type, bool *r_is_const) const {
DataType base_type = p_base_type;
// Check classes in current file
@@ -7282,6 +7367,9 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
while (base) {
if (base->constant_expressions.has(p_member)) {
+ if (r_is_const) {
+ *r_is_const = true;
+ }
r_member_type = base->constant_expressions[p_member].expression->get_datatype();
return true;
}
@@ -7364,7 +7452,7 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
}
}
-#define IS_USAGE_MEMBER(m_usage) (!(m_usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_CATEGORY)))
+#define IS_USAGE_MEMBER(m_usage) (!(m_usage & (PROPERTY_USAGE_GROUP | PROPERTY_USAGE_SUBGROUP | PROPERTY_USAGE_CATEGORY)))
// Check other script types
while (scr.is_valid()) {
@@ -7400,7 +7488,9 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
native = "_" + native.operator String();
}
if (!ClassDB::class_exists(native)) {
- if (!check_types) return false;
+ if (!check_types) {
+ return false;
+ }
ERR_FAIL_V_MSG(false, "Parser bug: Class \"" + String(native) + "\" not found.");
}
@@ -7488,7 +7578,6 @@ bool GDScriptParser::_get_member_type(const DataType &p_base_type, const StringN
}
GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType *p_base_type, const StringName &p_identifier, int p_line, bool p_is_indexing) {
-
if (p_base_type && !p_base_type->has_type) {
return DataType();
}
@@ -7505,7 +7594,12 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType
base_type = DataType(*p_base_type);
}
- if (_get_member_type(base_type, p_identifier, member_type)) {
+ bool is_const = false;
+ if (_get_member_type(base_type, p_identifier, member_type, &is_const)) {
+ if (!p_base_type && current_function && current_function->_static && !is_const) {
+ _set_error("Can't access member variable (\"" + p_identifier.operator String() + "\") from a static function.", p_line);
+ return DataType();
+ }
return member_type;
}
@@ -7657,7 +7751,6 @@ GDScriptParser::DataType GDScriptParser::_reduce_identifier_type(const DataType
}
void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
-
// Names of internal object properties that we check to avoid overriding them.
// "__meta__" could also be in here, but since it doesn't really affect object metadata,
// it is okay to override it on script.
@@ -7693,12 +7786,16 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
// Function declarations
for (int i = 0; i < p_class->static_functions.size(); i++) {
_check_function_types(p_class->static_functions[i]);
- if (error_set) return;
+ if (error_set) {
+ return;
+ }
}
for (int i = 0; i < p_class->functions.size(); i++) {
_check_function_types(p_class->functions[i]);
- if (error_set) return;
+ if (error_set) {
+ return;
+ }
}
// Class variables
@@ -7713,6 +7810,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
_mark_line_as_safe(v.line);
v.data_type = _resolve_type(v.data_type, v.line);
+ v.initial_assignment->arguments[0]->set_datatype(v.data_type);
if (v.expression) {
DataType expr_type = _reduce_node_type(v.expression);
@@ -7737,7 +7835,7 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
ConstantNode *tgt_type = alloc_node<ConstantNode>();
tgt_type->line = v.line;
- tgt_type->value = (int)v.data_type.builtin_type;
+ tgt_type->value = (int64_t)v.data_type.builtin_type;
OperatorNode *convert_call = alloc_node<OperatorNode>();
convert_call->line = v.line;
@@ -7756,6 +7854,10 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
_set_error("The assigned value doesn't have a set type; the variable type can't be inferred.", v.line);
return;
}
+ if (expr_type.kind == DataType::BUILTIN && expr_type.builtin_type == Variant::NIL) {
+ _set_error("The variable type cannot be inferred because its value is \"null\".", v.line);
+ return;
+ }
v.data_type = expr_type;
v.data_type.is_constant = false;
}
@@ -7773,7 +7875,9 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
}
// Setter and getter
- if (v.setter == StringName() && v.getter == StringName()) continue;
+ if (v.setter == StringName() && v.getter == StringName()) {
+ continue;
+ }
bool found_getter = false;
bool found_setter = false;
@@ -7816,10 +7920,14 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
return;
}
}
- if (found_getter && found_setter) break;
+ if (found_getter && found_setter) {
+ break;
+ }
}
- if ((found_getter || v.getter == StringName()) && (found_setter || v.setter == StringName())) continue;
+ if ((found_getter || v.getter == StringName()) && (found_setter || v.setter == StringName())) {
+ continue;
+ }
// Check for static functions
for (int j = 0; j < p_class->static_functions.size(); j++) {
@@ -7846,17 +7954,59 @@ void GDScriptParser::_check_class_level_types(ClassNode *p_class) {
}
}
+ // Signals
+ DataType base = p_class->base_type;
+
+ while (base.kind == DataType::CLASS) {
+ ClassNode *base_class = base.class_type;
+ for (int i = 0; i < p_class->_signals.size(); i++) {
+ for (int j = 0; j < base_class->_signals.size(); j++) {
+ if (p_class->_signals[i].name == base_class->_signals[j].name) {
+ _set_error("The signal \"" + p_class->_signals[i].name + "\" already exists in a parent class.", p_class->_signals[i].line);
+ return;
+ }
+ }
+ }
+ base = base_class->base_type;
+ }
+
+ StringName native;
+ if (base.kind == DataType::GDSCRIPT || base.kind == DataType::SCRIPT) {
+ Ref<Script> scr = base.script_type;
+ if (scr.is_valid() && scr->is_valid()) {
+ native = scr->get_instance_base_type();
+ for (int i = 0; i < p_class->_signals.size(); i++) {
+ if (scr->has_script_signal(p_class->_signals[i].name)) {
+ _set_error("The signal \"" + p_class->_signals[i].name + "\" already exists in a parent class.", p_class->_signals[i].line);
+ return;
+ }
+ }
+ }
+ } else if (base.kind == DataType::NATIVE) {
+ native = base.native_type;
+ }
+
+ if (native != StringName()) {
+ for (int i = 0; i < p_class->_signals.size(); i++) {
+ if (ClassDB::has_signal(native, p_class->_signals[i].name)) {
+ _set_error("The signal \"" + p_class->_signals[i].name + "\" already exists in a parent class.", p_class->_signals[i].line);
+ return;
+ }
+ }
+ }
+
// Inner classes
for (int i = 0; i < p_class->subclasses.size(); i++) {
current_class = p_class->subclasses[i];
_check_class_level_types(current_class);
- if (error_set) return;
+ if (error_set) {
+ return;
+ }
current_class = p_class;
}
}
void GDScriptParser::_check_function_types(FunctionNode *p_function) {
-
p_function->return_type = _resolve_type(p_function->return_type, p_function->line);
// Arguments
@@ -7975,21 +8125,9 @@ void GDScriptParser::_check_function_types(FunctionNode *p_function) {
p_function->return_type.has_type = false;
p_function->return_type.may_yield = true;
}
-
-#ifdef DEBUG_ENABLED
- for (Map<StringName, LocalVarNode *>::Element *E = p_function->body->variables.front(); E; E = E->next()) {
- LocalVarNode *lv = E->get();
- for (int i = 0; i < current_class->variables.size(); i++) {
- if (current_class->variables[i].identifier == lv->name) {
- _add_warning(GDScriptWarning::SHADOWED_VARIABLE, lv->line, lv->name, itos(current_class->variables[i].line));
- }
- }
- }
-#endif // DEBUG_ENABLED
}
void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) {
-
// Function blocks
for (int i = 0; i < p_class->static_functions.size(); i++) {
current_function = p_class->static_functions[i];
@@ -7998,7 +8136,9 @@ void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) {
_check_block_types(current_block);
current_block = nullptr;
current_function = nullptr;
- if (error_set) return;
+ if (error_set) {
+ return;
+ }
}
for (int i = 0; i < p_class->functions.size(); i++) {
@@ -8008,7 +8148,9 @@ void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) {
_check_block_types(current_block);
current_block = nullptr;
current_function = nullptr;
- if (error_set) return;
+ if (error_set) {
+ return;
+ }
}
#ifdef DEBUG_ENABLED
@@ -8029,7 +8171,9 @@ void GDScriptParser::_check_class_blocks_types(ClassNode *p_class) {
for (int i = 0; i < p_class->subclasses.size(); i++) {
current_class = p_class->subclasses[i];
_check_class_blocks_types(current_class);
- if (error_set) return;
+ if (error_set) {
+ return;
+ }
current_class = p_class;
}
}
@@ -8055,7 +8199,6 @@ static String _find_function_name(const GDScriptParser::OperatorNode *p_call) {
#endif // DEBUG_ENABLED
void GDScriptParser::_check_block_types(BlockNode *p_block) {
-
Node *last_var_assign = nullptr;
// Check each statement
@@ -8063,10 +8206,15 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
Node *statement = E->get();
switch (statement->type) {
case Node::TYPE_NEWLINE:
- case Node::TYPE_BREAKPOINT:
- case Node::TYPE_ASSERT: {
+ case Node::TYPE_BREAKPOINT: {
// Nothing to do
} break;
+ case Node::TYPE_ASSERT: {
+ AssertNode *an = static_cast<AssertNode *>(statement);
+ _mark_line_as_safe(an->line);
+ _reduce_node_type(an->condition);
+ _reduce_node_type(an->message);
+ } break;
case Node::TYPE_LOCAL_VAR: {
LocalVarNode *lv = static_cast<LocalVarNode *>(statement);
lv->datatype = _resolve_type(lv->datatype, lv->line);
@@ -8088,6 +8236,11 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
if (lv->datatype.has_type && assign_type.may_yield && lv->assign->type == Node::TYPE_OPERATOR) {
_add_warning(GDScriptWarning::FUNCTION_MAY_YIELD, lv->line, _find_function_name(static_cast<OperatorNode *>(lv->assign)));
}
+ for (int i = 0; i < current_class->variables.size(); i++) {
+ if (current_class->variables[i].identifier == lv->name) {
+ _add_warning(GDScriptWarning::SHADOWED_VARIABLE, lv->line, lv->name, itos(current_class->variables[i].line));
+ }
+ }
#endif // DEBUG_ENABLED
if (!_is_type_compatible(lv->datatype, assign_type)) {
@@ -8109,7 +8262,8 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
ConstantNode *tgt_type = alloc_node<ConstantNode>();
tgt_type->line = lv->line;
- tgt_type->value = (int)lv->datatype.builtin_type;
+ tgt_type->value = (int64_t)lv->datatype.builtin_type;
+ tgt_type->datatype = _type_from_variant(tgt_type->value);
OperatorNode *convert_call = alloc_node<OperatorNode>();
convert_call->line = lv->line;
@@ -8132,6 +8286,10 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
_set_error("The assigned value doesn't have a set type; the variable type can't be inferred.", lv->line);
return;
}
+ if (assign_type.kind == DataType::BUILTIN && assign_type.builtin_type == Variant::NIL) {
+ _set_error("The variable type cannot be inferred because its value is \"null\".", lv->line);
+ return;
+ }
lv->datatype = assign_type;
lv->datatype.is_constant = false;
}
@@ -8245,6 +8403,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
ConstantNode *tgt_type = alloc_node<ConstantNode>();
tgt_type->line = op->line;
tgt_type->value = (int)lh_type.builtin_type;
+ tgt_type->datatype = _type_from_variant(tgt_type->value);
OperatorNode *convert_call = alloc_node<OperatorNode>();
convert_call->line = op->line;
@@ -8285,7 +8444,9 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
_add_warning(GDScriptWarning::RETURN_VALUE_DISCARDED, op->line, func_name);
}
#endif // DEBUG_ENABLED
- if (error_set) return;
+ if (error_set) {
+ return;
+ }
} break;
case OperatorNode::OP_YIELD: {
_mark_line_as_safe(op->line);
@@ -8320,7 +8481,9 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
}
}
- if (!function_type.has_type) break;
+ if (!function_type.has_type) {
+ break;
+ }
if (function_type.kind == DataType::BUILTIN && function_type.builtin_type == Variant::NIL) {
// Return void, should not have arguments
@@ -8380,7 +8543,9 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
current_block = p_block->sub_blocks[i];
_check_block_types(current_block);
current_block = p_block;
- if (error_set) return;
+ if (error_set) {
+ return;
+ }
}
#ifdef DEBUG_ENABLED
@@ -8399,9 +8564,9 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) {
}
void GDScriptParser::_set_error(const String &p_error, int p_line, int p_column) {
-
- if (error_set)
+ if (error_set) {
return; //allow no further errors
+ }
error = p_error;
error_line = p_line < 0 ? tokenizer->get_token_line() : p_line;
@@ -8463,16 +8628,14 @@ void GDScriptParser::_add_warning(int p_code, int p_line, const Vector<String> &
#endif // DEBUG_ENABLED
String GDScriptParser::get_error() const {
-
return error;
}
int GDScriptParser::get_error_line() const {
-
return error_line;
}
-int GDScriptParser::get_error_column() const {
+int GDScriptParser::get_error_column() const {
return error_column;
}
@@ -8481,7 +8644,6 @@ bool GDScriptParser::has_error() const {
}
Error GDScriptParser::_parse(const String &p_base_path) {
-
base_path = p_base_path;
//assume class
@@ -8499,7 +8661,13 @@ Error GDScriptParser::_parse(const String &p_base_path) {
_set_error("Parse error: " + tokenizer->get_token_error());
}
- if (error_set && !for_completion) {
+ bool for_completion_error_set = false;
+ if (error_set && for_completion) {
+ for_completion_error_set = true;
+ error_set = false;
+ }
+
+ if (error_set) {
return ERR_PARSE_ERROR;
}
@@ -8517,7 +8685,9 @@ Error GDScriptParser::_parse(const String &p_base_path) {
current_function = nullptr;
current_block = nullptr;
- if (for_completion) check_types = false;
+ if (for_completion) {
+ check_types = false;
+ }
// Resolve all class-level stuff before getting into function blocks
_check_class_level_types(main_class);
@@ -8529,6 +8699,10 @@ Error GDScriptParser::_parse(const String &p_base_path) {
// Resolve the function blocks
_check_class_blocks_types(main_class);
+ if (for_completion_error_set) {
+ error_set = true;
+ }
+
if (error_set) {
return ERR_PARSE_ERROR;
}
@@ -8569,7 +8743,6 @@ Error GDScriptParser::_parse(const String &p_base_path) {
}
Error GDScriptParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const String &p_base_path, const String &p_self_path) {
-
clear();
self_path = p_self_path;
@@ -8583,7 +8756,6 @@ Error GDScriptParser::parse_bytecode(const Vector<uint8_t> &p_bytecode, const St
}
Error GDScriptParser::parse(const String &p_code, const String &p_base_path, bool p_just_validate, const String &p_self_path, bool p_for_completion, Set<int> *r_safe_lines, bool p_dependencies_only) {
-
clear();
self_path = p_self_path;
@@ -8604,19 +8776,15 @@ Error GDScriptParser::parse(const String &p_code, const String &p_base_path, boo
}
bool GDScriptParser::is_tool_script() const {
-
return (head && head->type == Node::TYPE_CLASS && static_cast<const ClassNode *>(head)->tool);
}
const GDScriptParser::Node *GDScriptParser::get_parse_tree() const {
-
return head;
}
void GDScriptParser::clear() {
-
while (list) {
-
Node *l = list;
list = list->next;
memdelete(l);
@@ -8658,57 +8826,46 @@ void GDScriptParser::clear() {
}
GDScriptParser::CompletionType GDScriptParser::get_completion_type() {
-
return completion_type;
}
StringName GDScriptParser::get_completion_cursor() {
-
return completion_cursor;
}
int GDScriptParser::get_completion_line() {
-
return completion_line;
}
Variant::Type GDScriptParser::get_completion_built_in_constant() {
-
return completion_built_in_constant;
}
GDScriptParser::Node *GDScriptParser::get_completion_node() {
-
return completion_node;
}
GDScriptParser::BlockNode *GDScriptParser::get_completion_block() {
-
return completion_block;
}
GDScriptParser::ClassNode *GDScriptParser::get_completion_class() {
-
return completion_class;
}
GDScriptParser::FunctionNode *GDScriptParser::get_completion_function() {
-
return completion_function;
}
int GDScriptParser::get_completion_argument_index() {
-
return completion_argument;
}
-int GDScriptParser::get_completion_identifier_is_function() {
-
+bool GDScriptParser::get_completion_identifier_is_function() {
return completion_ident_is_call;
}
GDScriptParser::GDScriptParser() {
-
head = nullptr;
list = nullptr;
tokenizer = nullptr;
@@ -8717,6 +8874,5 @@ GDScriptParser::GDScriptParser() {
}
GDScriptParser::~GDScriptParser() {
-
clear();
}
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index eca5f83f7a..7dedb6d6f9 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -45,25 +45,27 @@ public:
struct ClassNode;
struct DataType {
- enum {
+ enum Kind {
BUILTIN,
NATIVE,
SCRIPT,
GDSCRIPT,
CLASS,
UNRESOLVED
- } kind;
+ };
+
+ Kind kind = UNRESOLVED;
- bool has_type;
- bool is_constant;
- bool is_meta_type; // Whether the value can be used as a type
- bool infer_type;
- bool may_yield; // For function calls
+ bool has_type = false;
+ bool is_constant = false;
+ bool is_meta_type = false; // Whether the value can be used as a type
+ bool infer_type = false;
+ bool may_yield = false; // For function calls
- Variant::Type builtin_type;
+ Variant::Type builtin_type = Variant::NIL;
StringName native_type;
Ref<Script> script_type;
- ClassNode *class_type;
+ ClassNode *class_type = nullptr;
String to_string() const;
@@ -94,19 +96,10 @@ public:
return false;
}
- DataType() :
- kind(UNRESOLVED),
- has_type(false),
- is_constant(false),
- is_meta_type(false),
- infer_type(false),
- may_yield(false),
- builtin_type(Variant::NIL),
- class_type(nullptr) {}
+ DataType() {}
};
struct Node {
-
enum Type {
TYPE_CLASS,
TYPE_FUNCTION,
@@ -145,7 +138,6 @@ public:
struct OperatorNode;
struct ClassNode : public Node {
-
bool tool;
StringName name;
bool extends_used;
@@ -206,7 +198,6 @@ public:
};
struct FunctionNode : public Node {
-
bool _static;
MultiplayerAPI::RPCMode rpc_mode;
bool has_yield;
@@ -235,67 +226,65 @@ public:
};
struct BlockNode : public Node {
-
- ClassNode *parent_class;
- BlockNode *parent_block;
+ ClassNode *parent_class = nullptr;
+ BlockNode *parent_block = nullptr;
List<Node *> statements;
Map<StringName, LocalVarNode *> variables;
- bool has_return;
+ bool has_return = false;
+ bool can_break = false;
+ bool can_continue = false;
- Node *if_condition; //tiny hack to improve code completion on if () blocks
+ Node *if_condition = nullptr; //tiny hack to improve code completion on if () blocks
//the following is useful for code completion
List<BlockNode *> sub_blocks;
- int end_line;
+ int end_line = -1;
+
BlockNode() {
- if_condition = nullptr;
type = TYPE_BLOCK;
- end_line = -1;
- parent_block = nullptr;
- parent_class = nullptr;
- has_return = false;
}
};
struct TypeNode : public Node {
-
Variant::Type vtype;
- TypeNode() { type = TYPE_TYPE; }
+
+ TypeNode() {
+ type = TYPE_TYPE;
+ }
};
+
struct BuiltInFunctionNode : public Node {
GDScriptFunctions::Function function;
- BuiltInFunctionNode() { type = TYPE_BUILT_IN_FUNCTION; }
+
+ BuiltInFunctionNode() {
+ type = TYPE_BUILT_IN_FUNCTION;
+ }
};
struct IdentifierNode : public Node {
-
StringName name;
- BlockNode *declared_block; // Simplify lookup by checking if it is declared locally
+ BlockNode *declared_block = nullptr; // Simplify lookup by checking if it is declared locally
DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
+
IdentifierNode() {
type = TYPE_IDENTIFIER;
- declared_block = nullptr;
}
};
struct LocalVarNode : public Node {
-
StringName name;
- Node *assign;
- OperatorNode *assign_op;
- int assignments;
- int usages;
+ Node *assign = nullptr;
+ OperatorNode *assign_op = nullptr;
+ int assignments = 0;
+ int usages = 0;
DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
+
LocalVarNode() {
type = TYPE_LOCAL_VAR;
- assign = nullptr;
- assign_op = nullptr;
- assignments = 0;
- usages = 0;
}
};
@@ -304,15 +293,18 @@ public:
DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
- ConstantNode() { type = TYPE_CONSTANT; }
+
+ ConstantNode() {
+ type = TYPE_CONSTANT;
+ }
};
struct ArrayNode : public Node {
-
Vector<Node *> elements;
DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
+
ArrayNode() {
type = TYPE_ARRAY;
datatype.has_type = true;
@@ -322,9 +314,7 @@ public:
};
struct DictionaryNode : public Node {
-
struct Pair {
-
Node *key;
Node *value;
};
@@ -333,6 +323,7 @@ public:
DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
+
DictionaryNode() {
type = TYPE_DICTIONARY;
datatype.has_type = true;
@@ -342,7 +333,9 @@ public:
};
struct SelfNode : public Node {
- SelfNode() { type = TYPE_SELF; }
+ SelfNode() {
+ type = TYPE_SELF;
+ }
};
struct OperatorNode : public Node {
@@ -404,11 +397,12 @@ public:
DataType datatype;
virtual DataType get_datatype() const { return datatype; }
virtual void set_datatype(const DataType &p_datatype) { datatype = p_datatype; }
- OperatorNode() { type = TYPE_OPERATOR; }
+ OperatorNode() {
+ type = TYPE_OPERATOR;
+ }
};
struct PatternNode : public Node {
-
enum PatternType {
PT_CONSTANT,
PT_BIND,
@@ -454,19 +448,17 @@ public:
CF_MATCH
};
- CFType cf_type;
+ CFType cf_type = CF_IF;
Vector<Node *> arguments;
- BlockNode *body;
- BlockNode *body_else;
+ BlockNode *body = nullptr;
+ BlockNode *body_else = nullptr;
MatchNode *match;
ControlFlowNode *_else; //used for if
+
ControlFlowNode() {
type = TYPE_CONTROL_FLOW;
- cf_type = CF_IF;
- body = nullptr;
- body_else = nullptr;
}
};
@@ -476,29 +468,34 @@ public:
DataType return_type;
virtual DataType get_datatype() const { return return_type; }
virtual void set_datatype(const DataType &p_datatype) { return_type = p_datatype; }
- CastNode() { type = TYPE_CAST; }
+
+ CastNode() {
+ type = TYPE_CAST;
+ }
};
struct AssertNode : public Node {
- Node *condition;
- Node *message;
- AssertNode() :
- condition(0),
- message(0) {
+ Node *condition = nullptr;
+ Node *message = nullptr;
+
+ AssertNode() {
type = TYPE_ASSERT;
}
};
struct BreakpointNode : public Node {
- BreakpointNode() { type = TYPE_BREAKPOINT; }
+ BreakpointNode() {
+ type = TYPE_BREAKPOINT;
+ }
};
struct NewLineNode : public Node {
- NewLineNode() { type = TYPE_NEWLINE; }
+ NewLineNode() {
+ type = TYPE_NEWLINE;
+ }
};
struct Expression {
-
bool is_op;
union {
OperatorNode::Operator op;
@@ -553,8 +550,8 @@ private:
int pending_newline;
struct IndentLevel {
- int indent;
- int tabs;
+ int indent = 0;
+ int tabs = 0;
bool is_mixed(IndentLevel other) {
return (
@@ -563,9 +560,7 @@ private:
(indent < other.indent && tabs > other.tabs));
}
- IndentLevel() :
- indent(0),
- tabs(0) {}
+ IndentLevel() {}
IndentLevel(int p_indent, int p_tabs) :
indent(p_indent),
@@ -613,6 +608,7 @@ private:
Node *_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign = false, bool p_parsing_constant = false);
Node *_reduce_expression(Node *p_node, bool p_to_const = false);
Node *_parse_and_reduce_expression(Node *p_parent, bool p_static, bool p_reduce_const = false, bool p_allow_assign = false);
+ bool _reduce_export_var_type(Variant &p_value, int p_line = 0);
PatternNode *_parse_pattern(bool p_static);
void _parse_pattern_block(BlockNode *p_block, Vector<PatternBranchNode *> &p_branches, bool p_static);
@@ -623,6 +619,7 @@ private:
void _parse_extends(ClassNode *p_class);
void _parse_class(ClassNode *p_class);
bool _end_statement();
+ void _set_end_statement_error(String p_name);
void _determine_inheritance(ClassNode *p_class, bool p_recursive = true);
bool _parse_type(DataType &r_type, bool p_can_be_void = false);
@@ -633,7 +630,7 @@ private:
DataType _get_operation_type(const Variant::Operator p_op, const DataType &p_a, const DataType &p_b, bool &r_valid) const;
Variant::Operator _get_variant_operation(const OperatorNode::Operator &p_op) const;
bool _get_function_signature(DataType &p_base_type, const StringName &p_function, DataType &r_return_type, List<DataType> &r_arg_types, int &r_default_arg_count, bool &r_static, bool &r_vararg) const;
- bool _get_member_type(const DataType &p_base_type, const StringName &p_member, DataType &r_member_type) const;
+ bool _get_member_type(const DataType &p_base_type, const StringName &p_member, DataType &r_member_type, bool *r_is_const = nullptr) const;
bool _is_type_compatible(const DataType &p_container, const DataType &p_expression, bool p_allow_implicit_conversion = false) const;
Node *_get_default_value_for_type(const DataType &p_type, int p_line = -1);
@@ -646,12 +643,16 @@ private:
void _check_block_types(BlockNode *p_block);
_FORCE_INLINE_ void _mark_line_as_safe(int p_line) const {
#ifdef DEBUG_ENABLED
- if (safe_lines) safe_lines->insert(p_line);
+ if (safe_lines) {
+ safe_lines->insert(p_line);
+ }
#endif // DEBUG_ENABLED
}
_FORCE_INLINE_ void _mark_line_as_unsafe(int p_line) const {
#ifdef DEBUG_ENABLED
- if (safe_lines) safe_lines->erase(p_line);
+ if (safe_lines) {
+ safe_lines->erase(p_line);
+ }
#endif // DEBUG_ENABLED
}
@@ -682,7 +683,7 @@ public:
BlockNode *get_completion_block();
FunctionNode *get_completion_function();
int get_completion_argument_index();
- int get_completion_identifier_is_function();
+ bool get_completion_identifier_is_function();
const List<String> &get_dependencies() const { return dependencies; }
diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp
index d42ca52731..2db42601c6 100644
--- a/modules/gdscript/gdscript_tokenizer.cpp
+++ b/modules/gdscript/gdscript_tokenizer.cpp
@@ -240,7 +240,6 @@ static const _kws _keyword_list[] = {
};
const char *GDScriptTokenizer::get_token_name(Token p_token) {
-
ERR_FAIL_INDEX_V(p_token, TK_MAX, "<error>");
return token_names[p_token];
}
@@ -364,27 +363,22 @@ StringName GDScriptTokenizer::get_token_literal(int p_offset) const {
}
static bool _is_text_char(CharType c) {
-
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
static bool _is_number(CharType c) {
-
return (c >= '0' && c <= '9');
}
static bool _is_hex(CharType c) {
-
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
static bool _is_bin(CharType c) {
-
return (c == '0' || c == '1');
}
void GDScriptTokenizerText::_make_token(Token p_type) {
-
TokenData &tk = tk_rb[tk_rb_pos];
tk.type = p_type;
@@ -393,8 +387,8 @@ void GDScriptTokenizerText::_make_token(Token p_type) {
tk_rb_pos = (tk_rb_pos + 1) % TK_RB_SIZE;
}
-void GDScriptTokenizerText::_make_identifier(const StringName &p_identifier) {
+void GDScriptTokenizerText::_make_identifier(const StringName &p_identifier) {
TokenData &tk = tk_rb[tk_rb_pos];
tk.type = TK_IDENTIFIER;
@@ -406,7 +400,6 @@ void GDScriptTokenizerText::_make_identifier(const StringName &p_identifier) {
}
void GDScriptTokenizerText::_make_built_in_func(GDScriptFunctions::Function p_func) {
-
TokenData &tk = tk_rb[tk_rb_pos];
tk.type = TK_BUILT_IN_FUNC;
@@ -416,8 +409,8 @@ void GDScriptTokenizerText::_make_built_in_func(GDScriptFunctions::Function p_fu
tk_rb_pos = (tk_rb_pos + 1) % TK_RB_SIZE;
}
-void GDScriptTokenizerText::_make_constant(const Variant &p_constant) {
+void GDScriptTokenizerText::_make_constant(const Variant &p_constant) {
TokenData &tk = tk_rb[tk_rb_pos];
tk.type = TK_CONSTANT;
@@ -429,7 +422,6 @@ void GDScriptTokenizerText::_make_constant(const Variant &p_constant) {
}
void GDScriptTokenizerText::_make_type(const Variant::Type &p_type) {
-
TokenData &tk = tk_rb[tk_rb_pos];
tk.type = TK_BUILT_IN_TYPE;
@@ -441,7 +433,6 @@ void GDScriptTokenizerText::_make_type(const Variant::Type &p_type) {
}
void GDScriptTokenizerText::_make_error(const String &p_error) {
-
error_flag = true;
last_error = p_error;
@@ -454,7 +445,6 @@ void GDScriptTokenizerText::_make_error(const String &p_error) {
}
void GDScriptTokenizerText::_make_newline(int p_indentation, int p_tabs) {
-
TokenData &tk = tk_rb[tk_rb_pos];
tk.type = TK_NEWLINE;
tk.constant = Vector2(p_indentation, p_tabs);
@@ -464,7 +454,6 @@ void GDScriptTokenizerText::_make_newline(int p_indentation, int p_tabs) {
}
void GDScriptTokenizerText::_advance() {
-
if (error_flag) {
//parser broke
_make_error(last_error);
@@ -482,7 +471,6 @@ void GDScriptTokenizerText::_advance() {
column += m_amount; \
}
while (true) {
-
bool is_string_name = false;
StringMode string_mode = STRING_DOUBLE_QUOTE;
@@ -570,7 +558,6 @@ void GDScriptTokenizerText::_advance() {
return;
}
case '/': {
-
switch (GETCHAR(1)) {
case '=': { // diveq
@@ -587,13 +574,13 @@ void GDScriptTokenizerText::_advance() {
_make_token(TK_OP_EQUAL);
INCPOS(1);
- } else
+ } else {
_make_token(TK_OP_ASSIGN);
+ }
} break;
case '<': {
if (GETCHAR(1) == '=') {
-
_make_token(TK_OP_LESS_EQUAL);
INCPOS(1);
} else if (GETCHAR(1) == '<') {
@@ -604,8 +591,9 @@ void GDScriptTokenizerText::_advance() {
_make_token(TK_OP_SHIFT_LEFT);
}
INCPOS(1);
- } else
+ } else {
_make_token(TK_OP_LESS);
+ }
} break;
case '>': {
@@ -684,7 +672,6 @@ void GDScriptTokenizerText::_advance() {
break;
case '&': {
if (GETCHAR(1) == '&') {
-
_make_token(TK_OP_AND);
INCPOS(1);
} else if (GETCHAR(1) == '=') {
@@ -696,7 +683,6 @@ void GDScriptTokenizerText::_advance() {
} break;
case '|': {
if (GETCHAR(1) == '|') {
-
_make_token(TK_OP_OR);
INCPOS(1);
} else if (GETCHAR(1) == '=') {
@@ -707,7 +693,6 @@ void GDScriptTokenizerText::_advance() {
}
} break;
case '*': {
-
if (GETCHAR(1) == '=') {
_make_token(TK_OP_ASSIGN_MUL);
INCPOS(1);
@@ -716,7 +701,6 @@ void GDScriptTokenizerText::_advance() {
}
} break;
case '+': {
-
if (GETCHAR(1) == '=') {
_make_token(TK_OP_ASSIGN_ADD);
INCPOS(1);
@@ -731,7 +715,6 @@ void GDScriptTokenizerText::_advance() {
} break;
case '-': {
-
if (GETCHAR(1) == '=') {
_make_token(TK_OP_ASSIGN_SUB);
INCPOS(1);
@@ -743,7 +726,6 @@ void GDScriptTokenizerText::_advance() {
}
} break;
case '%': {
-
if (GETCHAR(1) == '=') {
_make_token(TK_OP_ASSIGN_MOD);
INCPOS(1);
@@ -761,9 +743,9 @@ void GDScriptTokenizerText::_advance() {
[[fallthrough]];
case '\'':
case '"': {
-
- if (GETCHAR(0) == '\'')
+ if (GETCHAR(0) == '\'') {
string_mode = STRING_SINGLE_QUOTE;
+ }
int i = 1;
if (string_mode == STRING_DOUBLE_QUOTE && GETCHAR(i) == '"' && GETCHAR(i + 1) == '"') {
@@ -774,7 +756,6 @@ void GDScriptTokenizerText::_advance() {
String str;
while (true) {
if (CharType(GETCHAR(i)) == 0) {
-
_make_error("Unterminated String");
return;
} else if (string_mode == STRING_DOUBLE_QUOTE && CharType(GETCHAR(i)) == '"') {
@@ -802,20 +783,36 @@ void GDScriptTokenizerText::_advance() {
CharType res = 0;
switch (next) {
-
- case 'a': res = 7; break;
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'v': res = 11; break;
- case 'f': res = 12; break;
- case 'r': res = 13; break;
- case '\'': res = '\''; break;
- case '\"': res = '\"'; break;
- case '\\': res = '\\'; break;
- case '/':
- res = '/';
- break; //wtf
+ case 'a':
+ res = '\a';
+ break;
+ case 'b':
+ res = '\b';
+ break;
+ case 't':
+ res = '\t';
+ break;
+ case 'n':
+ res = '\n';
+ break;
+ case 'v':
+ res = '\v';
+ break;
+ case 'f':
+ res = '\f';
+ break;
+ case 'r':
+ res = '\r';
+ break;
+ case '\'':
+ res = '\'';
+ break;
+ case '\"':
+ res = '\"';
+ break;
+ case '\\':
+ res = '\\';
+ break;
case 'u': {
// hex number
@@ -847,14 +844,19 @@ void GDScriptTokenizerText::_advance() {
i += 3;
} break;
+ case '\n': {
+ line++;
+ column = 1;
+ } break;
default: {
-
_make_error("Invalid escape sequence");
return;
} break;
}
- str += res;
+ if (next != '\n') {
+ str += res;
+ }
} else {
if (CharType(GETCHAR(i)) == '\n') {
@@ -879,7 +881,6 @@ void GDScriptTokenizerText::_advance() {
_make_token(TK_CURSOR);
} break;
default: {
-
if (_is_number(GETCHAR(0)) || (GETCHAR(0) == '.' && _is_number(GETCHAR(1)))) {
// parse number
bool period_found = false;
@@ -911,7 +912,6 @@ void GDScriptTokenizerText::_advance() {
}
hexa_found = true;
} else if (hexa_found && _is_hex(GETCHAR(i))) {
-
} else if (!hexa_found && GETCHAR(i) == 'b') {
if (bin_found || str.length() != 1 || !((i == 1 && str[0] == '0') || (i == 2 && str[1] == '0' && str[0] == '-'))) {
_make_error("Invalid numeric constant at 'b'");
@@ -928,7 +928,6 @@ void GDScriptTokenizerText::_advance() {
//all ok
} else if (bin_found && _is_bin(GETCHAR(i))) {
-
} else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) {
if (sign_found) {
_make_error("Invalid numeric constant at '-'");
@@ -938,8 +937,9 @@ void GDScriptTokenizerText::_advance() {
} else if (GETCHAR(i) == '_') {
i++;
continue; // Included for readability, shouldn't be a part of the string
- } else
+ } else {
break;
+ }
str += CharType(GETCHAR(i));
i++;
@@ -996,15 +996,12 @@ void GDScriptTokenizerText::_advance() {
} else if (str == "false") {
_make_constant(false);
} else {
-
bool found = false;
{
-
int idx = 0;
while (_type_list[idx].text) {
-
if (str == _type_list[idx].text) {
_make_type(_type_list[idx].type);
found = true;
@@ -1015,13 +1012,10 @@ void GDScriptTokenizerText::_advance() {
}
if (!found) {
-
//built in func?
for (int j = 0; j < GDScriptFunctions::FUNC_MAX; j++) {
-
if (str == GDScriptFunctions::get_func_name(GDScriptFunctions::Function(j))) {
-
_make_built_in_func(GDScriptFunctions::Function(j));
found = true;
break;
@@ -1036,7 +1030,6 @@ void GDScriptTokenizerText::_advance() {
found = false;
while (_keyword_list[idx].text) {
-
if (str == _keyword_list[idx].text) {
_make_token(_keyword_list[idx].token);
found = true;
@@ -1046,8 +1039,9 @@ void GDScriptTokenizerText::_advance() {
}
}
- if (!found)
+ if (!found) {
identifier = true;
+ }
}
if (identifier) {
@@ -1069,7 +1063,6 @@ void GDScriptTokenizerText::_advance() {
}
void GDScriptTokenizerText::set_code(const String &p_code) {
-
code = p_code;
len = p_code.length();
if (len) {
@@ -1086,8 +1079,9 @@ void GDScriptTokenizerText::set_code(const String &p_code) {
ignore_warnings = false;
#endif // DEBUG_ENABLED
last_error = "";
- for (int i = 0; i < MAX_LOOKAHEAD + 1; i++)
+ for (int i = 0; i < MAX_LOOKAHEAD + 1; i++) {
_advance();
+ }
}
GDScriptTokenizerText::Token GDScriptTokenizerText::get_token(int p_offset) const {
@@ -1124,7 +1118,6 @@ const Variant &GDScriptTokenizerText::get_token_constant(int p_offset) const {
}
StringName GDScriptTokenizerText::get_token_identifier(int p_offset) const {
-
ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, StringName());
ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, StringName());
@@ -1134,7 +1127,6 @@ StringName GDScriptTokenizerText::get_token_identifier(int p_offset) const {
}
GDScriptFunctions::Function GDScriptTokenizerText::get_token_built_in_func(int p_offset) const {
-
ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, GDScriptFunctions::FUNC_MAX);
ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, GDScriptFunctions::FUNC_MAX);
@@ -1144,7 +1136,6 @@ GDScriptFunctions::Function GDScriptTokenizerText::get_token_built_in_func(int p
}
Variant::Type GDScriptTokenizerText::get_token_type(int p_offset) const {
-
ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, Variant::NIL);
ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, Variant::NIL);
@@ -1154,7 +1145,6 @@ Variant::Type GDScriptTokenizerText::get_token_type(int p_offset) const {
}
int GDScriptTokenizerText::get_token_line_indent(int p_offset) const {
-
ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, 0);
ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, 0);
@@ -1164,7 +1154,6 @@ int GDScriptTokenizerText::get_token_line_indent(int p_offset) const {
}
int GDScriptTokenizerText::get_token_line_tab_indent(int p_offset) const {
-
ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, 0);
ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, 0);
@@ -1174,7 +1163,6 @@ int GDScriptTokenizerText::get_token_line_tab_indent(int p_offset) const {
}
String GDScriptTokenizerText::get_token_error(int p_offset) const {
-
ERR_FAIL_COND_V(p_offset <= -MAX_LOOKAHEAD, String());
ERR_FAIL_COND_V(p_offset >= MAX_LOOKAHEAD, String());
@@ -1184,10 +1172,10 @@ String GDScriptTokenizerText::get_token_error(int p_offset) const {
}
void GDScriptTokenizerText::advance(int p_amount) {
-
ERR_FAIL_COND(p_amount <= 0);
- for (int i = 0; i < p_amount; i++)
+ for (int i = 0; i < p_amount; i++) {
_advance();
+ }
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1195,7 +1183,6 @@ void GDScriptTokenizerText::advance(int p_amount) {
#define BYTECODE_VERSION 13
Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer) {
-
const uint8_t *buf = p_buffer.ptr();
int total_len = p_buffer.size();
ERR_FAIL_COND_V(p_buffer.size() < 24 || p_buffer[0] != 'G' || p_buffer[1] != 'D' || p_buffer[2] != 'S' || p_buffer[3] != 'C', ERR_INVALID_DATA);
@@ -1213,7 +1200,6 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer)
identifiers.resize(identifier_count);
for (int i = 0; i < identifier_count; i++) {
-
int len = decode_uint32(b);
ERR_FAIL_COND_V(len > total_len, ERR_INVALID_DATA);
b += 4;
@@ -1233,13 +1219,13 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer)
constants.resize(constant_count);
for (int i = 0; i < constant_count; i++) {
-
Variant v;
int len;
// An object cannot be constant, never decode objects
Error err = decode_variant(v, b, total_len, &len, false);
- if (err)
+ if (err) {
return err;
+ }
b += len;
total_len -= len;
constants.write[i] = v;
@@ -1248,7 +1234,6 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer)
ERR_FAIL_COND_V(line_count * 8 > total_len, ERR_INVALID_DATA);
for (int i = 0; i < line_count; i++) {
-
uint32_t token = decode_uint32(b);
b += 4;
uint32_t linecol = decode_uint32(b);
@@ -1261,7 +1246,6 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer)
tokens.resize(token_count);
for (int i = 0; i < token_count; i++) {
-
ERR_FAIL_COND_V(total_len < 1, ERR_INVALID_DATA);
if ((*b) & TOKEN_BYTE_MASK) { //little endian always
@@ -1282,7 +1266,6 @@ Error GDScriptTokenizerBuffer::set_code_buffer(const Vector<uint8_t> &p_buffer)
}
Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code) {
-
Vector<uint8_t> buf;
Map<StringName, int> identifier_map;
@@ -1295,16 +1278,13 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code)
int line = -1;
while (true) {
-
if (tt.get_token_line() != line) {
-
line = tt.get_token_line();
line_map[line] = token_array.size();
}
uint32_t token = tt.get_token();
switch (tt.get_token()) {
-
case TK_IDENTIFIER: {
StringName id = tt.get_token_identifier();
if (!identifier_map.has(id)) {
@@ -1314,7 +1294,6 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code)
token |= identifier_map[id] << TOKEN_BITS;
} break;
case TK_CONSTANT: {
-
const Variant &c = tt.get_token_constant();
if (!constant_map.has(c)) {
int idx = constant_map.size();
@@ -1323,20 +1302,16 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code)
token |= constant_map[c] << TOKEN_BITS;
} break;
case TK_BUILT_IN_TYPE: {
-
token |= tt.get_token_type() << TOKEN_BITS;
} break;
case TK_BUILT_IN_FUNC: {
-
token |= tt.get_token_built_in_func() << TOKEN_BITS;
} break;
case TK_NEWLINE: {
-
token |= tt.get_token_line_indent() << TOKEN_BITS;
} break;
case TK_ERROR: {
-
ERR_FAIL_V(Vector<uint8_t>());
} break;
default: {
@@ -1345,8 +1320,9 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code)
token_array.push_back(token);
- if (tt.get_token() == TK_EOF)
+ if (tt.get_token() == TK_EOF) {
break;
+ }
tt.advance();
}
@@ -1383,12 +1359,12 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code)
//save identifiers
for (Map<int, StringName>::Element *E = rev_identifier_map.front(); E; E = E->next()) {
-
CharString cs = String(E->get()).utf8();
int len = cs.length() + 1;
int extra = 4 - (len % 4);
- if (extra == 4)
+ if (extra == 4) {
extra = 0;
+ }
uint8_t ibuf[4];
encode_uint32(len + extra, ibuf);
@@ -1404,7 +1380,6 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code)
}
for (Map<int, Variant>::Element *E = rev_constant_map.front(); E; E = E->next()) {
-
int len;
// Objects cannot be constant, never encode objects
Error err = encode_variant(E->get(), nullptr, len, false);
@@ -1415,16 +1390,15 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code)
}
for (Map<int, uint32_t>::Element *E = rev_line_map.front(); E; E = E->next()) {
-
uint8_t ibuf[8];
encode_uint32(E->key(), &ibuf[0]);
encode_uint32(E->get(), &ibuf[4]);
- for (int i = 0; i < 8; i++)
+ for (int i = 0; i < 8; i++) {
buf.push_back(ibuf[i]);
+ }
}
for (int i = 0; i < token_array.size(); i++) {
-
uint32_t token = token_array[i];
if (token & ~TOKEN_MASK) {
@@ -1442,17 +1416,16 @@ Vector<uint8_t> GDScriptTokenizerBuffer::parse_code_string(const String &p_code)
}
GDScriptTokenizerBuffer::Token GDScriptTokenizerBuffer::get_token(int p_offset) const {
-
int offset = token + p_offset;
- if (offset < 0 || offset >= tokens.size())
+ if (offset < 0 || offset >= tokens.size()) {
return TK_EOF;
+ }
return GDScriptTokenizerBuffer::Token(tokens[offset] & TOKEN_MASK);
}
StringName GDScriptTokenizerBuffer::get_token_identifier(int p_offset) const {
-
int offset = token + p_offset;
ERR_FAIL_INDEX_V(offset, tokens.size(), StringName());
@@ -1463,14 +1436,12 @@ StringName GDScriptTokenizerBuffer::get_token_identifier(int p_offset) const {
}
GDScriptFunctions::Function GDScriptTokenizerBuffer::get_token_built_in_func(int p_offset) const {
-
int offset = token + p_offset;
ERR_FAIL_INDEX_V(offset, tokens.size(), GDScriptFunctions::FUNC_MAX);
return GDScriptFunctions::Function(tokens[offset] >> TOKEN_BITS);
}
Variant::Type GDScriptTokenizerBuffer::get_token_type(int p_offset) const {
-
int offset = token + p_offset;
ERR_FAIL_INDEX_V(offset, tokens.size(), Variant::NIL);
@@ -1478,55 +1449,57 @@ Variant::Type GDScriptTokenizerBuffer::get_token_type(int p_offset) const {
}
int GDScriptTokenizerBuffer::get_token_line(int p_offset) const {
-
int offset = token + p_offset;
int pos = lines.find_nearest(offset);
- if (pos < 0)
+ if (pos < 0) {
return -1;
- if (pos >= lines.size())
+ }
+ if (pos >= lines.size()) {
pos = lines.size() - 1;
+ }
uint32_t l = lines.getv(pos);
return l & TOKEN_LINE_MASK;
}
-int GDScriptTokenizerBuffer::get_token_column(int p_offset) const {
+int GDScriptTokenizerBuffer::get_token_column(int p_offset) const {
int offset = token + p_offset;
int pos = lines.find_nearest(offset);
- if (pos < 0)
+ if (pos < 0) {
return -1;
- if (pos >= lines.size())
+ }
+ if (pos >= lines.size()) {
pos = lines.size() - 1;
+ }
uint32_t l = lines.getv(pos);
return l >> TOKEN_LINE_BITS;
}
-int GDScriptTokenizerBuffer::get_token_line_indent(int p_offset) const {
+int GDScriptTokenizerBuffer::get_token_line_indent(int p_offset) const {
int offset = token + p_offset;
ERR_FAIL_INDEX_V(offset, tokens.size(), 0);
return tokens[offset] >> TOKEN_BITS;
}
-const Variant &GDScriptTokenizerBuffer::get_token_constant(int p_offset) const {
+const Variant &GDScriptTokenizerBuffer::get_token_constant(int p_offset) const {
int offset = token + p_offset;
ERR_FAIL_INDEX_V(offset, tokens.size(), nil);
uint32_t constant = tokens[offset] >> TOKEN_BITS;
ERR_FAIL_UNSIGNED_INDEX_V(constant, (uint32_t)constants.size(), nil);
return constants[constant];
}
-String GDScriptTokenizerBuffer::get_token_error(int p_offset) const {
+String GDScriptTokenizerBuffer::get_token_error(int p_offset) const {
ERR_FAIL_V(String());
}
void GDScriptTokenizerBuffer::advance(int p_amount) {
-
ERR_FAIL_INDEX(p_amount + token, tokens.size());
token += p_amount;
}
-GDScriptTokenizerBuffer::GDScriptTokenizerBuffer() {
+GDScriptTokenizerBuffer::GDScriptTokenizerBuffer() {
token = 0;
}
diff --git a/modules/gdscript/gdscript_tokenizer.h b/modules/gdscript/gdscript_tokenizer.h
index 180ec3c77e..32603c010f 100644
--- a/modules/gdscript/gdscript_tokenizer.h
+++ b/modules/gdscript/gdscript_tokenizer.h
@@ -176,11 +176,10 @@ public:
virtual bool is_ignoring_warnings() const = 0;
#endif // DEBUG_ENABLED
- virtual ~GDScriptTokenizer(){};
+ virtual ~GDScriptTokenizer() {}
};
class GDScriptTokenizerText : public GDScriptTokenizer {
-
enum {
MAX_LOOKAHEAD = 4,
TK_RB_SIZE = MAX_LOOKAHEAD * 2 + 1
@@ -252,7 +251,6 @@ public:
};
class GDScriptTokenizerBuffer : public GDScriptTokenizer {
-
enum {
TOKEN_BYTE_MASK = 0x80,
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.cpp b/modules/gdscript/language_server/gdscript_extend_parser.cpp
index b2c6b0e1ab..f87e8687e5 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.cpp
+++ b/modules/gdscript/language_server/gdscript_extend_parser.cpp
@@ -35,7 +35,6 @@
#include "gdscript_workspace.h"
void ExtendGDScriptParser::update_diagnostics() {
-
diagnostics.clear();
if (has_error()) {
@@ -80,12 +79,10 @@ void ExtendGDScriptParser::update_diagnostics() {
}
void ExtendGDScriptParser::update_symbols() {
-
members.clear();
const GDScriptParser::Node *head = get_parse_tree();
if (const GDScriptParser::ClassNode *gdclass = dynamic_cast<const GDScriptParser::ClassNode *>(head)) {
-
parse_class_symbol(gdclass, class_symbol);
for (int i = 0; i < class_symbol.children.size(); i++) {
@@ -141,15 +138,15 @@ void ExtendGDScriptParser::update_document_links(const String &p_code) {
}
void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p_class, lsp::DocumentSymbol &r_symbol) {
-
const String uri = get_uri();
r_symbol.uri = uri;
r_symbol.script_path = path;
r_symbol.children.clear();
r_symbol.name = p_class->name;
- if (r_symbol.name.empty())
+ if (r_symbol.name.empty()) {
r_symbol.name = path.get_file();
+ }
r_symbol.kind = lsp::SymbolKind::Class;
r_symbol.deprecated = false;
r_symbol.range.start.line = LINE_NUMBER_TO_INDEX(p_class->line);
@@ -161,7 +158,6 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
r_symbol.documentation = parse_documentation(is_root_class ? 0 : LINE_NUMBER_TO_INDEX(p_class->line), is_root_class);
for (int i = 0; i < p_class->variables.size(); ++i) {
-
const GDScriptParser::ClassNode::Member &m = p_class->variables[i];
lsp::DocumentSymbol symbol;
@@ -289,7 +285,6 @@ void ExtendGDScriptParser::parse_class_symbol(const GDScriptParser::ClassNode *p
}
void ExtendGDScriptParser::parse_function_symbol(const GDScriptParser::FunctionNode *p_func, lsp::DocumentSymbol &r_symbol) {
-
const String uri = get_uri();
r_symbol.name = p_func->name;
@@ -384,8 +379,9 @@ String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) {
int step = p_docs_down ? 1 : -1;
int start_line = p_docs_down ? p_line : p_line - 1;
for (int i = start_line; true; i += step) {
-
- if (i < 0 || i >= lines.size()) break;
+ if (i < 0 || i >= lines.size()) {
+ break;
+ }
String line_comment = lines[i].strip_edges(true, false);
if (line_comment.begins_with("#")) {
@@ -408,22 +404,20 @@ String ExtendGDScriptParser::parse_documentation(int p_line, bool p_docs_down) {
}
String ExtendGDScriptParser::get_text_for_completion(const lsp::Position &p_cursor) const {
-
String longthing;
int len = lines.size();
for (int i = 0; i < len; i++) {
-
if (i == p_cursor.line) {
longthing += lines[i].substr(0, p_cursor.character);
longthing += String::chr(0xFFFF); //not unicode, represents the cursor
longthing += lines[i].substr(p_cursor.character, lines[i].size());
} else {
-
longthing += lines[i];
}
- if (i != len - 1)
+ if (i != len - 1) {
longthing += "\n";
+ }
}
return longthing;
@@ -433,7 +427,6 @@ String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_c
String longthing;
int len = lines.size();
for (int i = 0; i < len; i++) {
-
if (i == p_cursor.line) {
String line = lines[i];
String first_part = line.substr(0, p_cursor.character);
@@ -457,19 +450,18 @@ String ExtendGDScriptParser::get_text_for_lookup_symbol(const lsp::Position &p_c
}
longthing += last_part;
} else {
-
longthing += lines[i];
}
- if (i != len - 1)
+ if (i != len - 1) {
longthing += "\n";
+ }
}
return longthing;
}
String ExtendGDScriptParser::get_identifier_under_position(const lsp::Position &p_position, Vector2i &p_offset) const {
-
ERR_FAIL_INDEX_V(p_position.line, lines.size(), "");
String line = lines[p_position.line];
ERR_FAIL_INDEX_V(p_position.character, line.size(), "");
@@ -524,7 +516,6 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::search_symbol_defined_at_line(i
}
Error ExtendGDScriptParser::get_left_function_call(const lsp::Position &p_position, lsp::Position &r_func_pos, int &r_arg_index) const {
-
ERR_FAIL_INDEX_V(p_position.line, lines.size(), ERR_INVALID_PARAMETER);
int bracket_stack = 0;
@@ -576,7 +567,6 @@ const lsp::DocumentSymbol *ExtendGDScriptParser::get_symbol_defined_at_line(int
}
const lsp::DocumentSymbol *ExtendGDScriptParser::get_member_symbol(const String &p_name, const String &p_subclass) const {
-
if (p_subclass.empty()) {
const lsp::DocumentSymbol *const *ptr = members.getptr(p_name);
if (ptr) {
@@ -599,12 +589,9 @@ const List<lsp::DocumentLink> &ExtendGDScriptParser::get_document_links() const
}
const Array &ExtendGDScriptParser::get_member_completions() {
-
if (member_completions.empty()) {
-
const String *name = members.next(nullptr);
while (name) {
-
const lsp::DocumentSymbol *symbol = members.get(*name);
lsp::CompletionItem item = symbol->make_completion_item();
item.data = JOIN_SYMBOLS(path, *name);
@@ -615,7 +602,6 @@ const Array &ExtendGDScriptParser::get_member_completions() {
const String *_class = inner_classes.next(nullptr);
while (_class) {
-
const ClassMembers *inner_class = inner_classes.getptr(*_class);
const String *member_name = inner_class->next(nullptr);
while (member_name) {
@@ -696,7 +682,6 @@ Dictionary ExtendGDScriptParser::dump_class_api(const GDScriptParser::ClassNode
Array constants;
for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_class->constant_expressions.front(); E; E = E->next()) {
-
const GDScriptParser::ClassNode::Constant &c = E->value();
const GDScriptParser::ConstantNode *node = dynamic_cast<const GDScriptParser::ConstantNode *>(c.expression);
ERR_FAIL_COND_V(!node, class_api);
@@ -765,7 +750,6 @@ Dictionary ExtendGDScriptParser::dump_class_api(const GDScriptParser::ClassNode
}
Dictionary ExtendGDScriptParser::generate_api() const {
-
Dictionary api;
const GDScriptParser::Node *head = get_parse_tree();
if (const GDScriptParser::ClassNode *gdclass = dynamic_cast<const GDScriptParser::ClassNode *>(head)) {
diff --git a/modules/gdscript/language_server/gdscript_extend_parser.h b/modules/gdscript/language_server/gdscript_extend_parser.h
index 43dfce994b..0c031d7883 100644
--- a/modules/gdscript/language_server/gdscript_extend_parser.h
+++ b/modules/gdscript/language_server/gdscript_extend_parser.h
@@ -50,7 +50,6 @@
typedef HashMap<String, const lsp::DocumentSymbol *> ClassMembers;
class ExtendGDScriptParser : public GDScriptParser {
-
String path;
Vector<String> lines;
diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp
index 69662e96f7..35bf4287b8 100644
--- a/modules/gdscript/language_server/gdscript_language_protocol.cpp
+++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp
@@ -47,10 +47,11 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() {
ERR_FAIL_COND_V_MSG(true, ERR_OUT_OF_MEMORY, "Response header too big");
}
Error err = connection->get_partial_data(&req_buf[req_pos], 1, read);
- if (err != OK)
+ if (err != OK) {
return FAILED;
- else if (read != 1) // Busy, wait until next poll
+ } else if (read != 1) { // Busy, wait until next poll
return ERR_BUSY;
+ }
char *r = (char *)req_buf;
int l = req_pos;
@@ -75,10 +76,11 @@ Error GDScriptLanguageProtocol::LSPeer::handle_data() {
ERR_FAIL_COND_V_MSG(req_pos >= LSP_MAX_BUFFER_SIZE, ERR_OUT_OF_MEMORY, "Response content too big");
}
Error err = connection->get_partial_data(&req_buf[req_pos], 1, read);
- if (err != OK)
+ if (err != OK) {
return FAILED;
- else if (read != 1)
+ } else if (read != 1) {
return ERR_BUSY;
+ }
req_pos++;
}
@@ -145,7 +147,6 @@ String GDScriptLanguageProtocol::process_message(const String &p_text) {
}
String GDScriptLanguageProtocol::format_output(const String &p_text) {
-
String header = "Content-Length: ";
CharString charstr = p_text.utf8();
size_t len = charstr.length();
@@ -168,7 +169,6 @@ void GDScriptLanguageProtocol::_bind_methods() {
}
Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
-
lsp::InitializeResult ret;
String root_uri = p_params["rootUri"];
@@ -183,7 +183,6 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
if (root_uri.length() && is_same_workspace) {
workspace->root_uri = root_uri;
} else {
-
workspace->root_uri = "file://" + workspace->root;
Dictionary params;
@@ -208,12 +207,10 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) {
}
void GDScriptLanguageProtocol::initialized(const Variant &p_params) {
-
lsp::GodotCapabilities capabilities;
DocData *doc = EditorHelp::get_doc_data();
for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) {
-
lsp::GodotNativeClassInfo gdclass;
gdclass.name = E->get().name;
gdclass.class_doc = &(E->get());
diff --git a/modules/gdscript/language_server/gdscript_language_server.cpp b/modules/gdscript/language_server/gdscript_language_server.cpp
index e1d86ecdd4..d53914814f 100644
--- a/modules/gdscript/language_server/gdscript_language_server.cpp
+++ b/modules/gdscript/language_server/gdscript_language_server.cpp
@@ -48,7 +48,6 @@ GDScriptLanguageServer::GDScriptLanguageServer() {
}
void GDScriptLanguageServer::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
start();
diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp
index f065b33570..778cb4d254 100644
--- a/modules/gdscript/language_server/gdscript_text_document.cpp
+++ b/modules/gdscript/language_server/gdscript_text_document.cpp
@@ -85,19 +85,15 @@ void GDScriptTextDocument::notify_client_show_symbol(const lsp::DocumentSymbol *
}
void GDScriptTextDocument::initialize() {
-
if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
-
const HashMap<StringName, ClassMembers> &native_members = GDScriptLanguageProtocol::get_singleton()->get_workspace()->native_members;
const StringName *class_ptr = native_members.next(nullptr);
while (class_ptr) {
-
const ClassMembers &members = native_members.get(*class_ptr);
const String *name = members.next(nullptr);
while (name) {
-
const lsp::DocumentSymbol *symbol = members.get(*name);
lsp::CompletionItem item = symbol->make_completion_item();
item.data = JOIN_SYMBOLS(String(*class_ptr), *name);
@@ -112,7 +108,6 @@ void GDScriptTextDocument::initialize() {
}
Variant GDScriptTextDocument::nativeSymbol(const Dictionary &p_params) {
-
Variant ret;
lsp::NativeSymbolInspectParams params;
@@ -142,7 +137,6 @@ Array GDScriptTextDocument::documentSymbol(const Dictionary &p_params) {
}
Array GDScriptTextDocument::completion(const Dictionary &p_params) {
-
Array arr;
lsp::CompletionParams params;
@@ -153,12 +147,10 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) {
GDScriptLanguageProtocol::get_singleton()->get_workspace()->completion(params, &options);
if (!options.empty()) {
-
int i = 0;
arr.resize(options.size());
for (const List<ScriptCodeCompletionOption>::Element *E = options.front(); E; E = E->next()) {
-
const ScriptCodeCompletionOption &option = E->get();
lsp::CompletionItem item;
item.label = option.display;
@@ -201,11 +193,9 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) {
i++;
}
} else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
-
arr = native_member_completions.duplicate();
for (Map<String, ExtendGDScriptParser *>::Element *E = GDScriptLanguageProtocol::get_singleton()->get_workspace()->scripts.front(); E; E = E->next()) {
-
ExtendGDScriptParser *script = E->get();
const Array &items = script->get_member_completions();
@@ -220,7 +210,6 @@ Array GDScriptTextDocument::completion(const Dictionary &p_params) {
}
Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) {
-
lsp::CompletionItem item;
item.load(p_params);
@@ -230,18 +219,15 @@ Dictionary GDScriptTextDocument::resolve(const Dictionary &p_params) {
const lsp::DocumentSymbol *symbol = nullptr;
if (data.get_type() == Variant::DICTIONARY) {
-
params.load(p_params["data"]);
symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_symbol(params, item.label, item.kind == lsp::CompletionItemKind::Method || item.kind == lsp::CompletionItemKind::Function);
} else if (data.get_type() == Variant::STRING) {
-
String query = data;
Vector<String> param_symbols = query.split(SYMBOL_SEPERATOR, false);
if (param_symbols.size() >= 2) {
-
String class_ = param_symbols[0];
StringName class_name = class_;
String member_name = param_symbols[param_symbols.size() - 1];
@@ -313,13 +299,11 @@ Array GDScriptTextDocument::colorPresentation(const Dictionary &p_params) {
}
Variant GDScriptTextDocument::hover(const Dictionary &p_params) {
-
lsp::TextDocumentPositionParams params;
params.load(p_params);
const lsp::DocumentSymbol *symbol = GDScriptLanguageProtocol::get_singleton()->get_workspace()->resolve_symbol(params);
if (symbol) {
-
lsp::Hover hover;
hover.contents = symbol->render();
hover.range.start = params.position;
@@ -327,7 +311,6 @@ Variant GDScriptTextDocument::hover(const Dictionary &p_params) {
return hover.to_json();
} else if (GDScriptLanguageProtocol::get_singleton()->is_smart_resolve_enabled()) {
-
Dictionary ret;
Array contents;
List<const lsp::DocumentSymbol *> list;
diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp
index 32fc8f36f0..9285d88157 100644
--- a/modules/gdscript/language_server/gdscript_workspace.cpp
+++ b/modules/gdscript/language_server/gdscript_workspace.cpp
@@ -71,7 +71,6 @@ void GDScriptWorkspace::remove_cache_parser(const String &p_path) {
}
const lsp::DocumentSymbol *GDScriptWorkspace::get_native_symbol(const String &p_class, const String &p_member) const {
-
StringName class_name = p_class;
StringName empty;
@@ -185,11 +184,12 @@ Array GDScriptWorkspace::symbol(const Dictionary &p_params) {
}
Error GDScriptWorkspace::initialize() {
- if (initialized) return OK;
+ if (initialized) {
+ return OK;
+ }
DocData *doc = EditorHelp::get_doc_data();
for (Map<String, DocData::ClassDoc>::Element *E = doc->class_list.front(); E; E = E->next()) {
-
const DocData::ClassDoc &class_data = E->value();
lsp::DocumentSymbol class_symbol;
String class_name = E->key();
@@ -314,14 +314,12 @@ Error GDScriptWorkspace::initialize() {
}
Error GDScriptWorkspace::parse_script(const String &p_path, const String &p_content) {
-
ExtendGDScriptParser *parser = memnew(ExtendGDScriptParser);
Error err = parser->parse(p_content, p_path);
Map<String, ExtendGDScriptParser *>::Element *last_parser = parse_results.find(p_path);
Map<String, ExtendGDScriptParser *>::Element *last_script = scripts.find(p_path);
if (err == OK) {
-
remove_cache_parser(p_path);
parse_results[p_path] = parser;
scripts[p_path] = parser;
@@ -377,15 +375,15 @@ void GDScriptWorkspace::publish_diagnostics(const String &p_path) {
}
void GDScriptWorkspace::_get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners) {
- if (!efsd)
+ if (!efsd) {
return;
+ }
for (int i = 0; i < efsd->get_subdir_count(); i++) {
_get_owners(efsd->get_subdir(i), p_path, owners);
}
for (int i = 0; i < efsd->get_file_count(); i++) {
-
Vector<String> deps = efsd->get_file_deps(i);
bool found = false;
for (int j = 0; j < deps.size(); j++) {
@@ -394,8 +392,9 @@ void GDScriptWorkspace::_get_owners(EditorFileSystemDirectory *efsd, String p_pa
break;
}
}
- if (!found)
+ if (!found) {
continue;
+ }
owners.push_back(efsd->get_file_path(i));
}
@@ -421,7 +420,6 @@ Node *GDScriptWorkspace::_get_owner_scene_node(String p_path) {
}
void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<ScriptCodeCompletionOption> *r_options) {
-
String path = get_file_path(p_params.textDocument.uri);
String call_hint;
bool forced = false;
@@ -437,12 +435,10 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S
}
const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocumentPositionParams &p_doc_pos, const String &p_symbol_name, bool p_func_requred) {
-
const lsp::DocumentSymbol *symbol = nullptr;
String path = get_file_path(p_doc_pos.textDocument.uri);
if (const ExtendGDScriptParser *parser = get_parse_result(path)) {
-
String symbol_identifier = p_symbol_name;
Vector<String> identifier_parts = symbol_identifier.split("(");
if (identifier_parts.size()) {
@@ -457,19 +453,14 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
}
if (!symbol_identifier.empty()) {
-
if (ScriptServer::is_global_class(symbol_identifier)) {
-
String class_path = ScriptServer::get_global_class_path(symbol_identifier);
symbol = get_script_symbol(class_path);
} else {
-
ScriptLanguage::LookupResult ret;
if (OK == GDScriptLanguage::get_singleton()->lookup_code(parser->get_text_for_lookup_symbol(pos, symbol_identifier, p_func_requred), symbol_identifier, path, nullptr, ret)) {
-
if (ret.type == ScriptLanguage::LookupResult::RESULT_SCRIPT_LOCATION) {
-
String target_script_path = path;
if (!ret.script.is_null()) {
target_script_path = ret.script->get_path();
@@ -480,7 +471,6 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
}
} else {
-
String member = ret.class_member;
if (member.empty() && symbol_identifier != ret.class_name) {
member = symbol_identifier;
@@ -498,10 +488,8 @@ const lsp::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const lsp::TextDocu
}
void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionParams &p_doc_pos, List<const lsp::DocumentSymbol *> &r_list) {
-
String path = get_file_path(p_doc_pos.textDocument.uri);
if (const ExtendGDScriptParser *parser = get_parse_result(path)) {
-
String symbol_identifier;
Vector2i offset;
symbol_identifier = parser->get_identifier_under_position(p_doc_pos.position, offset);
@@ -525,7 +513,6 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP
const HashMap<String, ClassMembers> &inner_classes = script->get_inner_classes();
const String *_class = inner_classes.next(nullptr);
while (_class) {
-
const ClassMembers *inner_class = inner_classes.getptr(*_class);
if (const lsp::DocumentSymbol *const *symbol = inner_class->getptr(symbol_identifier)) {
r_list.push_back(*symbol);
@@ -538,7 +525,6 @@ void GDScriptWorkspace::resolve_related_symbols(const lsp::TextDocumentPositionP
}
const lsp::DocumentSymbol *GDScriptWorkspace::resolve_native_symbol(const lsp::NativeSymbolInspectParams &p_params) {
-
if (Map<StringName, lsp::DocumentSymbol>::Element *E = native_symbols.find(p_params.native_class)) {
const lsp::DocumentSymbol &symbol = E->get();
if (p_params.symbol_name.empty() || p_params.symbol_name == symbol.name) {
@@ -574,12 +560,10 @@ Dictionary GDScriptWorkspace::generate_script_api(const String &p_path) {
Error GDScriptWorkspace::resolve_signature(const lsp::TextDocumentPositionParams &p_doc_pos, lsp::SignatureHelp &r_signature) {
if (const ExtendGDScriptParser *parser = get_parse_result(get_file_path(p_doc_pos.textDocument.uri))) {
-
lsp::TextDocumentPositionParams text_pos;
text_pos.textDocument = p_doc_pos.textDocument;
if (parser->get_left_function_call(p_doc_pos.position, text_pos.position, r_signature.activeParameter) == OK) {
-
List<const lsp::DocumentSymbol *> symbols;
if (const lsp::DocumentSymbol *symbol = resolve_symbol(text_pos)) {
@@ -591,7 +575,6 @@ Error GDScriptWorkspace::resolve_signature(const lsp::TextDocumentPositionParams
for (List<const lsp::DocumentSymbol *>::Element *E = symbols.front(); E; E = E->next()) {
const lsp::DocumentSymbol *symbol = E->get();
if (symbol->kind == lsp::SymbolKind::Method || symbol->kind == lsp::SymbolKind::Function) {
-
lsp::SignatureInformation signature_info;
signature_info.label = symbol->detail;
signature_info.documentation = symbol->render();
diff --git a/modules/gdscript/language_server/lsp.hpp b/modules/gdscript/language_server/lsp.hpp
index 124fcbfed8..cf27a1578c 100644
--- a/modules/gdscript/language_server/lsp.hpp
+++ b/modules/gdscript/language_server/lsp.hpp
@@ -149,7 +149,6 @@ struct Location {
* Represents a link between a source and a target location.
*/
struct LocationLink {
-
/**
* Span of the origin of this link.
*
@@ -220,7 +219,6 @@ struct DocumentLinkParams {
* text document or a web site.
*/
struct DocumentLink {
-
/**
* The range this link applies to.
*/
@@ -282,7 +280,9 @@ struct Command {
Dictionary dict;
dict["title"] = title;
dict["command"] = command;
- if (arguments.size()) dict["arguments"] = arguments;
+ if (arguments.size()) {
+ dict["arguments"] = arguments;
+ }
return dict;
}
};
@@ -486,7 +486,7 @@ struct TextDocumentSyncOptions {
* If present save notifications are sent to the server. If omitted the notification should not be
* sent.
*/
- SaveOptions save;
+ bool save = false;
Dictionary to_json() {
Dictionary dict;
@@ -494,7 +494,7 @@ struct TextDocumentSyncOptions {
dict["willSave"] = willSave;
dict["openClose"] = openClose;
dict["change"] = change;
- dict["save"] = save.to_json();
+ dict["save"] = save;
return dict;
}
};
@@ -946,16 +946,24 @@ struct CompletionItem {
dict["preselect"] = preselect;
dict["sortText"] = sortText;
dict["filterText"] = filterText;
- if (commitCharacters.size()) dict["commitCharacters"] = commitCharacters;
+ if (commitCharacters.size()) {
+ dict["commitCharacters"] = commitCharacters;
+ }
dict["command"] = command.to_json();
}
return dict;
}
void load(const Dictionary &p_dict) {
- if (p_dict.has("label")) label = p_dict["label"];
- if (p_dict.has("kind")) kind = p_dict["kind"];
- if (p_dict.has("detail")) detail = p_dict["detail"];
+ if (p_dict.has("label")) {
+ label = p_dict["label"];
+ }
+ if (p_dict.has("kind")) {
+ kind = p_dict["kind"];
+ }
+ if (p_dict.has("detail")) {
+ detail = p_dict["detail"];
+ }
if (p_dict.has("documentation")) {
Variant doc = p_dict["documentation"];
if (doc.get_type() == Variant::STRING) {
@@ -965,12 +973,24 @@ struct CompletionItem {
documentation.value = v["value"];
}
}
- if (p_dict.has("deprecated")) deprecated = p_dict["deprecated"];
- if (p_dict.has("preselect")) preselect = p_dict["preselect"];
- if (p_dict.has("sortText")) sortText = p_dict["sortText"];
- if (p_dict.has("filterText")) filterText = p_dict["filterText"];
- if (p_dict.has("insertText")) insertText = p_dict["insertText"];
- if (p_dict.has("data")) data = p_dict["data"];
+ if (p_dict.has("deprecated")) {
+ deprecated = p_dict["deprecated"];
+ }
+ if (p_dict.has("preselect")) {
+ preselect = p_dict["preselect"];
+ }
+ if (p_dict.has("sortText")) {
+ sortText = p_dict["sortText"];
+ }
+ if (p_dict.has("filterText")) {
+ filterText = p_dict["filterText"];
+ }
+ if (p_dict.has("insertText")) {
+ insertText = p_dict["insertText"];
+ }
+ if (p_dict.has("data")) {
+ data = p_dict["data"];
+ }
}
};
@@ -1096,7 +1116,6 @@ struct DocumentedSymbolInformation : public SymbolInformation {
* e.g. the range of an identifier.
*/
struct DocumentSymbol {
-
/**
* The name of this symbol. Will be displayed in the user interface and therefore must not be
* an empty string or a string only consisting of white spaces.
@@ -1205,7 +1224,6 @@ struct DocumentSymbol {
}
_FORCE_INLINE_ CompletionItem make_completion_item(bool resolved = false) const {
-
lsp::CompletionItem item;
item.label = name;
@@ -1249,7 +1267,6 @@ struct DocumentSymbol {
};
struct NativeSymbolInspectParams {
-
String native_class;
String symbol_name;
@@ -1281,7 +1298,6 @@ static const String Region = "region";
* Represents a folding range.
*/
struct FoldingRange {
-
/**
* The zero-based line number from where the folded range starts.
*/
@@ -1364,7 +1380,6 @@ struct CompletionContext {
};
struct CompletionParams : public TextDocumentPositionParams {
-
/**
* The completion context. This is only available if the client specifies
* to send this using `ClientCapabilities.textDocument.completion.contextSupport === true`
@@ -1405,7 +1420,6 @@ struct Hover {
* have a label and a doc-comment.
*/
struct ParameterInformation {
-
/**
* The label of this parameter information.
*
@@ -1642,7 +1656,7 @@ struct ServerCapabilities {
_FORCE_INLINE_ Dictionary to_json() {
Dictionary dict;
- dict["textDocumentSync"] = (int)textDocumentSync.change;
+ dict["textDocumentSync"] = textDocumentSync.to_json();
dict["completionProvider"] = completionProvider.to_json();
signatureHelpProvider.triggerCharacters.push_back(",");
signatureHelpProvider.triggerCharacters.push_back("(");
@@ -1684,7 +1698,6 @@ struct InitializeResult {
};
struct GodotNativeClassInfo {
-
String name;
const DocData::ClassDoc *class_doc = nullptr;
const ClassDB::ClassInfo *class_info = nullptr;
@@ -1699,7 +1712,6 @@ struct GodotNativeClassInfo {
/** Features not included in the standard lsp specifications */
struct GodotCapabilities {
-
/**
* Native class list
*/
@@ -1718,7 +1730,6 @@ struct GodotCapabilities {
/** Format BBCode documentation from DocData to markdown */
static String marked_documentation(const String &p_bbcode) {
-
String markdown = p_bbcode.strip_edges();
Vector<String> lines = markdown.split("\n");
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index 62b9d94d6c..0625123530 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -54,12 +54,10 @@ Ref<ResourceFormatSaverGDScript> resource_saver_gd;
#endif // !GDSCRIPT_NO_LSP
class EditorExportGDScript : public EditorExportPlugin {
-
GDCLASS(EditorExportGDScript, EditorExportPlugin);
public:
virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features) {
-
int script_mode = EditorExportPreset::MODE_SCRIPT_COMPILED;
String script_key;
@@ -70,21 +68,21 @@ public:
script_key = preset->get_script_encryption_key().to_lower();
}
- if (!p_path.ends_with(".gd") || script_mode == EditorExportPreset::MODE_SCRIPT_TEXT)
+ if (!p_path.ends_with(".gd") || script_mode == EditorExportPreset::MODE_SCRIPT_TEXT) {
return;
+ }
Vector<uint8_t> file = FileAccess::get_file_as_array(p_path);
- if (file.empty())
+ if (file.empty()) {
return;
+ }
String txt;
txt.parse_utf8((const char *)file.ptr(), file.size());
file = GDScriptTokenizerBuffer::parse_code_string(txt);
if (!file.empty()) {
-
if (script_mode == EditorExportPreset::MODE_SCRIPT_ENCRYPTED) {
-
String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("script.gde");
FileAccess *fa = FileAccess::open(tmp_path, FileAccess::WRITE);
@@ -94,19 +92,21 @@ public:
int v = 0;
if (i * 2 < script_key.length()) {
CharType ct = script_key[i * 2];
- if (ct >= '0' && ct <= '9')
+ if (ct >= '0' && ct <= '9') {
ct = ct - '0';
- else if (ct >= 'a' && ct <= 'f')
+ } else if (ct >= 'a' && ct <= 'f') {
ct = 10 + ct - 'a';
+ }
v |= ct << 4;
}
if (i * 2 + 1 < script_key.length()) {
CharType ct = script_key[i * 2 + 1];
- if (ct >= '0' && ct <= '9')
+ if (ct >= '0' && ct <= '9') {
ct = ct - '0';
- else if (ct >= 'a' && ct <= 'f')
+ } else if (ct >= 'a' && ct <= 'f') {
ct = 10 + ct - 'a';
+ }
v |= ct;
}
key.write[i] = v;
@@ -127,7 +127,6 @@ public:
DirAccess::remove_file_or_error(tmp_path);
} else {
-
add_file(p_path.get_basename() + ".gdc", file, true);
}
}
@@ -135,7 +134,6 @@ public:
};
static void _editor_init() {
-
Ref<EditorExportGDScript> gd_export;
gd_export.instance();
EditorExport::get_singleton()->add_export_plugin(gd_export);
@@ -151,7 +149,6 @@ static void _editor_init() {
#endif // TOOLS_ENABLED
void register_gdscript_types() {
-
ClassDB::register_class<GDScript>();
ClassDB::register_virtual_class<GDScriptFunctionState>();
@@ -171,11 +168,11 @@ void register_gdscript_types() {
}
void unregister_gdscript_types() {
-
ScriptServer::unregister_language(script_language_gd);
- if (script_language_gd)
+ if (script_language_gd) {
memdelete(script_language_gd);
+ }
ResourceLoader::remove_resource_format_loader(resource_loader_gd);
resource_loader_gd.unref();
diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp
index 2540ba476c..dd28c4ad4a 100644
--- a/modules/glslang/register_types.cpp
+++ b/modules/glslang/register_types.cpp
@@ -130,20 +130,19 @@ static const TBuiltInResource default_builtin_resource = {
/*maxTaskWorkGroupSizeZ_NV*/ 0,
/*maxMeshViewCountNV*/ 0,
/*limits*/ {
- /*nonInductiveForLoops*/ 1,
- /*whileLoops*/ 1,
- /*doWhileLoops*/ 1,
- /*generalUniformIndexing*/ 1,
- /*generalAttributeMatrixVectorIndexing*/ 1,
- /*generalVaryingIndexing*/ 1,
- /*generalSamplerIndexing*/ 1,
- /*generalVariableIndexing*/ 1,
- /*generalConstantMatrixVectorIndexing*/ 1,
+ /*nonInductiveForLoops*/ true,
+ /*whileLoops*/ true,
+ /*doWhileLoops*/ true,
+ /*generalUniformIndexing*/ true,
+ /*generalAttributeMatrixVectorIndexing*/ true,
+ /*generalVaryingIndexing*/ true,
+ /*generalSamplerIndexing*/ true,
+ /*generalVariableIndexing*/ true,
+ /*generalConstantMatrixVectorIndexing*/ true,
}
};
static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error) {
-
Vector<uint8_t> ret;
ERR_FAIL_COND_V(p_language == RenderingDevice::SHADER_LANGUAGE_HLSL, ret);
@@ -177,7 +176,6 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage
//preprocess
if (!shader.preprocess(&default_builtin_resource, DefaultVersion, ENoProfile, false, false, messages, &pre_processed_code, includer)) {
-
if (r_error) {
(*r_error) = "Failed pre-process:\n";
(*r_error) += shader.getInfoLog();
@@ -240,7 +238,7 @@ void preregister_glslang_types() {
void register_glslang_types() {
}
-void unregister_glslang_types() {
+void unregister_glslang_types() {
glslang::FinalizeProcess();
}
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index df7c2f397f..2975a97bfe 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -40,22 +40,18 @@
#include "servers/rendering_server.h"
bool GridMap::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name == "data") {
-
Dictionary d = p_value;
if (d.has("cells")) {
-
Vector<int> cells = d["cells"];
int amount = cells.size();
const int *r = cells.ptr();
ERR_FAIL_COND_V(amount % 3, false); // not even
cell_map.clear();
for (int i = 0; i < amount / 3; i++) {
-
IndexKey ik;
ik.key = decode_uint64((const uint8_t *)&r[i * 3]);
Cell cell;
@@ -67,7 +63,6 @@ bool GridMap::_set(const StringName &p_name, const Variant &p_value) {
_recreate_octant_data();
} else if (name == "baked_meshes") {
-
clear_baked_meshes();
Array meshes = p_value;
@@ -80,7 +75,7 @@ bool GridMap::_set(const StringName &p_name, const Variant &p_value) {
RS::get_singleton()->get_singleton()->instance_set_base(bm.instance, bm.mesh->get_rid());
RS::get_singleton()->instance_attach_object_instance_id(bm.instance, get_instance_id());
if (is_inside_tree()) {
- RS::get_singleton()->instance_set_scenario(bm.instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_scenario(bm.instance, get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_transform(bm.instance, get_global_transform());
}
baked_meshes.push_back(bm);
@@ -96,11 +91,9 @@ bool GridMap::_set(const StringName &p_name, const Variant &p_value) {
}
bool GridMap::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name == "data") {
-
Dictionary d;
Vector<int> cells;
@@ -109,7 +102,6 @@ bool GridMap::_get(const StringName &p_name, Variant &r_ret) const {
int *w = cells.ptrw();
int i = 0;
for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next(), i++) {
-
encode_uint64(E->key().key, (uint8_t *)&w[i * 3]);
encode_uint32(E->get().cell, (uint8_t *)&w[i * 3 + 2]);
}
@@ -119,7 +111,6 @@ bool GridMap::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = d;
} else if (name == "baked_meshes") {
-
Array ret;
ret.resize(baked_meshes.size());
for (int i = 0; i < baked_meshes.size(); i++) {
@@ -127,14 +118,14 @@ bool GridMap::_get(const StringName &p_name, Variant &r_ret) const {
}
r_ret = ret;
- } else
+ } else {
return false;
+ }
return true;
}
void GridMap::_get_property_list(List<PropertyInfo> *p_list) const {
-
if (baked_meshes.size()) {
p_list->push_back(PropertyInfo(Variant::ARRAY, "baked_meshes", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE));
}
@@ -143,71 +134,65 @@ void GridMap::_get_property_list(List<PropertyInfo> *p_list) const {
}
void GridMap::set_collision_layer(uint32_t p_layer) {
-
collision_layer = p_layer;
_reset_physic_bodies_collision_filters();
}
uint32_t GridMap::get_collision_layer() const {
-
return collision_layer;
}
void GridMap::set_collision_mask(uint32_t p_mask) {
-
collision_mask = p_mask;
_reset_physic_bodies_collision_filters();
}
uint32_t GridMap::get_collision_mask() const {
-
return collision_mask;
}
void GridMap::set_collision_mask_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
bool GridMap::get_collision_mask_bit(int p_bit) const {
-
return get_collision_mask() & (1 << p_bit);
}
void GridMap::set_collision_layer_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_layer();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_layer(mask);
}
bool GridMap::get_collision_layer_bit(int p_bit) const {
-
return get_collision_layer() & (1 << p_bit);
}
void GridMap::set_mesh_library(const Ref<MeshLibrary> &p_mesh_library) {
-
- if (!mesh_library.is_null())
+ if (!mesh_library.is_null()) {
mesh_library->unregister_owner(this);
+ }
mesh_library = p_mesh_library;
- if (!mesh_library.is_null())
+ if (!mesh_library.is_null()) {
mesh_library->register_owner(this);
+ }
_recreate_octant_data();
_change_notify("mesh_library");
}
Ref<MeshLibrary> GridMap::get_mesh_library() const {
-
return mesh_library;
}
@@ -217,24 +202,22 @@ void GridMap::set_cell_size(const Vector3 &p_size) {
_recreate_octant_data();
emit_signal("cell_size_changed", cell_size);
}
-Vector3 GridMap::get_cell_size() const {
+Vector3 GridMap::get_cell_size() const {
return cell_size;
}
void GridMap::set_octant_size(int p_size) {
-
ERR_FAIL_COND(p_size == 0);
octant_size = p_size;
_recreate_octant_data();
}
-int GridMap::get_octant_size() const {
+int GridMap::get_octant_size() const {
return octant_size;
}
void GridMap::set_center_x(bool p_enable) {
-
center_x = p_enable;
_recreate_octant_data();
}
@@ -244,7 +227,6 @@ bool GridMap::get_center_x() const {
}
void GridMap::set_center_y(bool p_enable) {
-
center_y = p_enable;
_recreate_octant_data();
}
@@ -254,7 +236,6 @@ bool GridMap::get_center_y() const {
}
void GridMap::set_center_z(bool p_enable) {
-
center_z = p_enable;
_recreate_octant_data();
}
@@ -264,7 +245,6 @@ bool GridMap::get_center_z() const {
}
void GridMap::set_cell_item(int p_x, int p_y, int p_z, int p_item, int p_rot) {
-
if (baked_meshes.size() && !recreating_octants) {
//if you set a cell item, baked meshes go good bye
clear_baked_meshes();
@@ -313,7 +293,6 @@ void GridMap::set_cell_item(int p_x, int p_y, int p_z, int p_item, int p_rot) {
SceneTree *st = SceneTree::get_singleton();
if (st && st->is_debugging_collisions_hint()) {
-
g->collision_debug = RenderingServer::get_singleton()->mesh_create();
g->collision_debug_instance = RenderingServer::get_singleton()->instance_create();
RenderingServer::get_singleton()->instance_set_base(g->collision_debug_instance, g->collision_debug);
@@ -340,7 +319,6 @@ void GridMap::set_cell_item(int p_x, int p_y, int p_z, int p_item, int p_rot) {
}
int GridMap::get_cell_item(int p_x, int p_y, int p_z) const {
-
ERR_FAIL_INDEX_V(ABS(p_x), 1 << 20, INVALID_CELL_ITEM);
ERR_FAIL_INDEX_V(ABS(p_y), 1 << 20, INVALID_CELL_ITEM);
ERR_FAIL_INDEX_V(ABS(p_z), 1 << 20, INVALID_CELL_ITEM);
@@ -350,13 +328,13 @@ int GridMap::get_cell_item(int p_x, int p_y, int p_z) const {
key.y = p_y;
key.z = p_z;
- if (!cell_map.has(key))
+ if (!cell_map.has(key)) {
return INVALID_CELL_ITEM;
+ }
return cell_map[key].item;
}
int GridMap::get_cell_item_orientation(int p_x, int p_y, int p_z) const {
-
ERR_FAIL_INDEX_V(ABS(p_x), 1 << 20, -1);
ERR_FAIL_INDEX_V(ABS(p_y), 1 << 20, -1);
ERR_FAIL_INDEX_V(ABS(p_z), 1 << 20, -1);
@@ -366,8 +344,9 @@ int GridMap::get_cell_item_orientation(int p_x, int p_y, int p_z) const {
key.y = p_y;
key.z = p_z;
- if (!cell_map.has(key))
+ if (!cell_map.has(key)) {
return -1;
+ }
return cell_map[key].rot;
}
@@ -389,7 +368,6 @@ Vector3 GridMap::map_to_world(int p_x, int p_y, int p_z) const {
}
void GridMap::_octant_transform(const OctantKey &p_key) {
-
ERR_FAIL_COND(!octant_map.has(p_key));
Octant &g = *octant_map[p_key];
PhysicsServer3D::get_singleton()->body_set_state(g.static_body, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
@@ -406,15 +384,15 @@ void GridMap::_octant_transform(const OctantKey &p_key) {
bool GridMap::_octant_update(const OctantKey &p_key) {
ERR_FAIL_COND_V(!octant_map.has(p_key), false);
Octant &g = *octant_map[p_key];
- if (!g.dirty)
+ if (!g.dirty) {
return false;
+ }
//erase body shapes
PhysicsServer3D::get_singleton()->body_clear_shapes(g.static_body);
//erase body shapes debug
if (g.collision_debug.is_valid()) {
-
RS::get_singleton()->mesh_clear(g.collision_debug);
}
@@ -427,7 +405,6 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
//erase multimeshes
for (int i = 0; i < g.multimesh_instances.size(); i++) {
-
RS::get_singleton()->free(g.multimesh_instances[i].instance);
RS::get_singleton()->free(g.multimesh_instances[i].multimesh);
}
@@ -450,12 +427,12 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
Map<int, List<Pair<Transform, IndexKey>>> multimesh_items;
for (Set<IndexKey>::Element *E = g.cells.front(); E; E = E->next()) {
-
ERR_CONTINUE(!cell_map.has(E->get()));
const Cell &c = cell_map[E->get()];
- if (!mesh_library.is_valid() || !mesh_library->has_item(c.item))
+ if (!mesh_library.is_valid() || !mesh_library->has_item(c.item)) {
continue;
+ }
Vector3 cellpos = Vector3(E->get().x, E->get().y, E->get().z);
Vector3 ofs = _get_offset();
@@ -482,8 +459,9 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
// add the item's shape at given xform to octant's static_body
for (int i = 0; i < shapes.size(); i++) {
// add the item's shape
- if (!shapes[i].shape.is_valid())
+ if (!shapes[i].shape.is_valid()) {
continue;
+ }
PhysicsServer3D::get_singleton()->body_add_shape(g.static_body, shapes[i].shape->get_rid(), xform * shapes[i].local_transform);
if (g.collision_debug.is_valid()) {
shapes.write[i].shape->add_vertices_to_array(col_debug, xform * shapes[i].local_transform);
@@ -509,7 +487,6 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
//update multimeshes, only if not baked
if (baked_meshes.size() == 0) {
-
for (Map<int, List<Pair<Transform, IndexKey>>>::Element *E = multimesh_items.front(); E; E = E->next()) {
Octant::MultimeshInstance mmi;
@@ -536,7 +513,7 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
RS::get_singleton()->instance_set_base(instance, mm);
if (is_inside_tree()) {
- RS::get_singleton()->instance_set_scenario(instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_scenario(instance, get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_transform(instance, get_global_transform());
}
@@ -548,7 +525,6 @@ bool GridMap::_octant_update(const OctantKey &p_key) {
}
if (col_debug.size()) {
-
Array arr;
arr.resize(RS::ARRAY_MAX);
arr[RS::ARRAY_VERTEX] = col_debug;
@@ -573,25 +549,23 @@ void GridMap::_reset_physic_bodies_collision_filters() {
}
void GridMap::_octant_enter_world(const OctantKey &p_key) {
-
ERR_FAIL_COND(!octant_map.has(p_key));
Octant &g = *octant_map[p_key];
PhysicsServer3D::get_singleton()->body_set_state(g.static_body, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
- PhysicsServer3D::get_singleton()->body_set_space(g.static_body, get_world()->get_space());
+ PhysicsServer3D::get_singleton()->body_set_space(g.static_body, get_world_3d()->get_space());
if (g.collision_debug_instance.is_valid()) {
- RS::get_singleton()->instance_set_scenario(g.collision_debug_instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_scenario(g.collision_debug_instance, get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_transform(g.collision_debug_instance, get_global_transform());
}
for (int i = 0; i < g.multimesh_instances.size(); i++) {
- RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_scenario(g.multimesh_instances[i].instance, get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_transform(g.multimesh_instances[i].instance, get_global_transform());
}
if (navigation && mesh_library.is_valid()) {
for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
-
if (cell_map.has(F->key()) && F->get().region.is_valid() == false) {
Ref<NavigationMesh> nm = mesh_library->get_item_navmesh(cell_map[F->key()].item);
if (nm.is_valid()) {
@@ -607,14 +581,12 @@ void GridMap::_octant_enter_world(const OctantKey &p_key) {
}
void GridMap::_octant_exit_world(const OctantKey &p_key) {
-
ERR_FAIL_COND(!octant_map.has(p_key));
Octant &g = *octant_map[p_key];
PhysicsServer3D::get_singleton()->body_set_state(g.static_body, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
PhysicsServer3D::get_singleton()->body_set_space(g.static_body, RID());
if (g.collision_debug_instance.is_valid()) {
-
RS::get_singleton()->instance_set_scenario(g.collision_debug_instance, RID());
}
@@ -624,7 +596,6 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) {
if (navigation) {
for (Map<IndexKey, Octant::NavMesh>::Element *F = g.navmesh_ids.front(); F; F = F->next()) {
-
if (F->get().region.is_valid()) {
NavigationServer3D::get_singleton()->free(F->get().region);
F->get().region = RID();
@@ -634,14 +605,15 @@ void GridMap::_octant_exit_world(const OctantKey &p_key) {
}
void GridMap::_octant_clean_up(const OctantKey &p_key) {
-
ERR_FAIL_COND(!octant_map.has(p_key));
Octant &g = *octant_map[p_key];
- if (g.collision_debug.is_valid())
+ if (g.collision_debug.is_valid()) {
RS::get_singleton()->free(g.collision_debug);
- if (g.collision_debug_instance.is_valid())
+ }
+ if (g.collision_debug_instance.is_valid()) {
RS::get_singleton()->free(g.collision_debug_instance);
+ }
PhysicsServer3D::get_singleton()->free(g.static_body);
@@ -654,7 +626,6 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) {
//erase multimeshes
for (int i = 0; i < g.multimesh_instances.size(); i++) {
-
RS::get_singleton()->free(g.multimesh_instances[i].instance);
RS::get_singleton()->free(g.multimesh_instances[i].multimesh);
}
@@ -662,11 +633,8 @@ void GridMap::_octant_clean_up(const OctantKey &p_key) {
}
void GridMap::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_WORLD: {
-
Node3D *c = this;
while (c) {
navigation = Object::cast_to<Navigation3D>(c);
@@ -684,16 +652,16 @@ void GridMap::_notification(int p_what) {
}
for (int i = 0; i < baked_meshes.size(); i++) {
- RS::get_singleton()->instance_set_scenario(baked_meshes[i].instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_scenario(baked_meshes[i].instance, get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_transform(baked_meshes[i].instance, get_global_transform());
}
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
Transform new_xform = get_global_transform();
- if (new_xform == last_transform)
+ if (new_xform == last_transform) {
break;
+ }
//update run
for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) {
_octant_transform(E->key());
@@ -707,7 +675,6 @@ void GridMap::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_WORLD: {
-
for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) {
_octant_exit_world(E->key());
}
@@ -729,8 +696,9 @@ void GridMap::_notification(int p_what) {
}
void GridMap::_update_visibility() {
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_change_notify("visible");
@@ -744,31 +712,29 @@ void GridMap::_update_visibility() {
}
void GridMap::_queue_octants_dirty() {
-
- if (awaiting_update)
+ if (awaiting_update) {
return;
+ }
MessageQueue::get_singleton()->push_call(this, "_update_octants_callback");
awaiting_update = true;
}
void GridMap::_recreate_octant_data() {
-
recreating_octants = true;
Map<IndexKey, Cell> cell_copy = cell_map;
_clear_internal();
for (Map<IndexKey, Cell>::Element *E = cell_copy.front(); E; E = E->next()) {
-
set_cell_item(E->key().x, E->key().y, E->key().z, E->get().item, E->get().rot);
}
recreating_octants = false;
}
void GridMap::_clear_internal() {
-
for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) {
- if (is_inside_world())
+ if (is_inside_world()) {
_octant_exit_world(E->key());
+ }
_octant_clean_up(E->key());
memdelete(E->get());
@@ -779,24 +745,21 @@ void GridMap::_clear_internal() {
}
void GridMap::clear() {
-
_clear_internal();
clear_baked_meshes();
}
void GridMap::resource_changed(const RES &p_res) {
-
_recreate_octant_data();
}
void GridMap::_update_octants_callback() {
-
- if (!awaiting_update)
+ if (!awaiting_update) {
return;
+ }
List<OctantKey> to_delete;
for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) {
-
if (_octant_update(E->key())) {
to_delete.push_back(E->key());
}
@@ -812,7 +775,6 @@ void GridMap::_update_octants_callback() {
}
void GridMap::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &GridMap::set_collision_layer);
ClassDB::bind_method(D_METHOD("get_collision_layer"), &GridMap::get_collision_layer);
@@ -885,11 +847,12 @@ void GridMap::_bind_methods() {
}
void GridMap::set_clip(bool p_enabled, bool p_clip_above, int p_floor, Vector3::Axis p_axis) {
-
- if (!p_enabled && !clip)
+ if (!p_enabled && !clip) {
return;
- if (clip && p_enabled && clip_floor == p_floor && p_clip_above == clip_above && p_axis == clip_axis)
+ }
+ if (clip && p_enabled && clip_floor == p_floor && p_clip_above == clip_above && p_axis == clip_axis) {
return;
+ }
clip = p_enabled;
clip_floor = p_floor;
@@ -898,7 +861,6 @@ void GridMap::set_clip(bool p_enabled, bool p_clip_above, int p_floor, Vector3::
//make it all update
for (Map<OctantKey, Octant *>::Element *E = octant_map.front(); E; E = E->next()) {
-
Octant *g = E->get();
g->dirty = true;
}
@@ -907,18 +869,15 @@ void GridMap::set_clip(bool p_enabled, bool p_clip_above, int p_floor, Vector3::
}
void GridMap::set_cell_scale(float p_scale) {
-
cell_scale = p_scale;
_recreate_octant_data();
}
float GridMap::get_cell_scale() const {
-
return cell_scale;
}
Array GridMap::get_used_cells() const {
-
Array a;
a.resize(cell_map.size());
int i = 0;
@@ -931,21 +890,22 @@ Array GridMap::get_used_cells() const {
}
Array GridMap::get_meshes() {
-
- if (mesh_library.is_null())
+ if (mesh_library.is_null()) {
return Array();
+ }
Vector3 ofs = _get_offset();
Array meshes;
for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next()) {
-
int id = E->get().item;
- if (!mesh_library->has_item(id))
+ if (!mesh_library->has_item(id)) {
continue;
+ }
Ref<Mesh> mesh = mesh_library->get_item_mesh(id);
- if (mesh.is_null())
+ if (mesh.is_null()) {
continue;
+ }
IndexKey ik = E->key();
@@ -973,7 +933,6 @@ Vector3 GridMap::_get_offset() const {
}
void GridMap::clear_baked_meshes() {
-
for (int i = 0; i < baked_meshes.size(); i++) {
RS::get_singleton()->free(baked_meshes[i].instance);
}
@@ -983,24 +942,25 @@ void GridMap::clear_baked_meshes() {
}
void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texel_size) {
-
- if (!mesh_library.is_valid())
+ if (!mesh_library.is_valid()) {
return;
+ }
//generate
Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>> surface_map;
for (Map<IndexKey, Cell>::Element *E = cell_map.front(); E; E = E->next()) {
-
IndexKey key = E->key();
int item = E->get().item;
- if (!mesh_library->has_item(item))
+ if (!mesh_library->has_item(item)) {
continue;
+ }
Ref<Mesh> mesh = mesh_library->get_item_mesh(item);
- if (!mesh.is_valid())
+ if (!mesh.is_valid()) {
continue;
+ }
Vector3 cellpos = Vector3(key.x, key.y, key.z);
Vector3 ofs = _get_offset();
@@ -1023,9 +983,9 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe
Map<Ref<Material>, Ref<SurfaceTool>> &mat_map = surface_map[ok];
for (int i = 0; i < mesh->get_surface_count(); i++) {
-
- if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
+ if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
continue;
+ }
Ref<Material> surf_mat = mesh->surface_get_material(i);
if (!mat_map.has(surf_mat)) {
@@ -1041,7 +1001,6 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe
}
for (Map<OctantKey, Map<Ref<Material>, Ref<SurfaceTool>>>::Element *E = surface_map.front(); E; E = E->next()) {
-
Ref<ArrayMesh> mesh;
mesh.instance();
for (Map<Ref<Material>, Ref<SurfaceTool>>::Element *F = E->get().front(); F; F = F->next()) {
@@ -1054,7 +1013,7 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe
RS::get_singleton()->get_singleton()->instance_set_base(bm.instance, bm.mesh->get_rid());
RS::get_singleton()->instance_attach_object_instance_id(bm.instance, get_instance_id());
if (is_inside_tree()) {
- RS::get_singleton()->instance_set_scenario(bm.instance, get_world()->get_scenario());
+ RS::get_singleton()->instance_set_scenario(bm.instance, get_world_3d()->get_scenario());
RS::get_singleton()->instance_set_transform(bm.instance, get_global_transform());
}
@@ -1068,7 +1027,6 @@ void GridMap::make_baked_meshes(bool p_gen_lightmap_uv, float p_lightmap_uv_texe
}
Array GridMap::get_bake_meshes() {
-
if (!baked_meshes.size()) {
make_baked_meshes(true);
}
@@ -1083,13 +1041,11 @@ Array GridMap::get_bake_meshes() {
}
RID GridMap::get_bake_mesh_instance(int p_idx) {
-
ERR_FAIL_INDEX_V(p_idx, baked_meshes.size(), RID());
return baked_meshes[p_idx].instance;
}
GridMap::GridMap() {
-
collision_layer = 1;
collision_mask = 1;
@@ -1113,9 +1069,9 @@ GridMap::GridMap() {
}
GridMap::~GridMap() {
-
- if (!mesh_library.is_null())
+ if (!mesh_library.is_null()) {
mesh_library->unregister_owner(this);
+ }
clear();
}
diff --git a/modules/gridmap/grid_map.h b/modules/gridmap/grid_map.h
index 3f3da09fe9..9eb9aee7d1 100644
--- a/modules/gridmap/grid_map.h
+++ b/modules/gridmap/grid_map.h
@@ -40,7 +40,6 @@
//should scale better with hardware that supports instancing
class GridMap : public Node3D {
-
GDCLASS(GridMap, Node3D);
enum {
@@ -49,7 +48,6 @@ class GridMap : public Node3D {
};
union IndexKey {
-
struct {
int16_t x;
int16_t y;
@@ -58,7 +56,6 @@ class GridMap : public Node3D {
uint64_t key;
_FORCE_INLINE_ bool operator<(const IndexKey &p_key) const {
-
return key < p_key.key;
}
@@ -69,7 +66,6 @@ class GridMap : public Node3D {
* @brief A Cell is a single cell in the cube map space; it is defined by its coordinates and the populating Item, identified by int id.
*/
union Cell {
-
struct {
unsigned int item : 16;
unsigned int rot : 5;
@@ -89,7 +85,6 @@ class GridMap : public Node3D {
* A GridMap can have multiple Octants.
*/
struct Octant {
-
struct NavMesh {
RID region;
Transform xform;
@@ -118,7 +113,6 @@ class GridMap : public Node3D {
};
union OctantKey {
-
struct {
int16_t x;
int16_t y;
@@ -129,7 +123,6 @@ class GridMap : public Node3D {
uint64_t key;
_FORCE_INLINE_ bool operator<(const OctantKey &p_key) const {
-
return key < p_key.key;
}
@@ -165,7 +158,6 @@ class GridMap : public Node3D {
void _recreate_octant_data();
struct BakeLight {
-
RS::LightType type;
Vector3 pos;
Vector3 dir;
@@ -173,7 +165,6 @@ class GridMap : public Node3D {
};
_FORCE_INLINE_ Vector3 _octant_get_offset(const OctantKey &p_key) const {
-
return Vector3(p_key.x, p_key.y, p_key.z) * cell_size * octant_size;
}
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index eb8feb5bc7..2bae43510a 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "grid_map_editor_plugin.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
#include "editor/plugins/node_3d_editor_plugin.h"
@@ -40,23 +40,21 @@
#include "scene/main/window.h"
void GridMapEditor::_node_removed(Node *p_node) {
-
- if (p_node == node)
+ if (p_node == node) {
node = nullptr;
+ }
}
void GridMapEditor::_configure() {
-
- if (!node)
+ if (!node) {
return;
+ }
update_grid();
}
void GridMapEditor::_menu_option(int p_option) {
-
switch (p_option) {
-
case MENU_OPTION_PREV_LEVEL: {
floor->set_value(floor->get_value() - 1);
} break;
@@ -66,7 +64,6 @@ void GridMapEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_LOCK_VIEW: {
-
int index = options->get_popup()->get_item_index(MENU_OPTION_LOCK_VIEW);
lock_view = !options->get_popup()->is_item_checked(index);
@@ -75,10 +72,8 @@ void GridMapEditor::_menu_option(int p_option) {
case MENU_OPTION_CLIP_DISABLED:
case MENU_OPTION_CLIP_ABOVE:
case MENU_OPTION_CLIP_BELOW: {
-
clip_mode = ClipMode(p_option - MENU_OPTION_CLIP_DISABLED);
for (int i = 0; i < 3; i++) {
-
int index = options->get_popup()->get_item_index(MENU_OPTION_CLIP_DISABLED + i);
options->get_popup()->set_item_checked(index, i == clip_mode);
}
@@ -88,7 +83,6 @@ void GridMapEditor::_menu_option(int p_option) {
case MENU_OPTION_X_AXIS:
case MENU_OPTION_Y_AXIS:
case MENU_OPTION_Z_AXIS: {
-
int new_axis = p_option - MENU_OPTION_X_AXIS;
for (int i = 0; i < 3; i++) {
int idx = options->get_popup()->get_item_index(MENU_OPTION_X_AXIS + i);
@@ -114,10 +108,8 @@ void GridMapEditor::_menu_option(int p_option) {
} break;
case MENU_OPTION_CURSOR_ROTATE_Y: {
-
Basis r;
if (input_action == INPUT_PASTE) {
-
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(0, 1, 0), -Math_PI / 2.0);
paste_indicator.orientation = r.get_orthogonal_index();
@@ -131,10 +123,8 @@ void GridMapEditor::_menu_option(int p_option) {
_update_cursor_transform();
} break;
case MENU_OPTION_CURSOR_ROTATE_X: {
-
Basis r;
if (input_action == INPUT_PASTE) {
-
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(1, 0, 0), -Math_PI / 2.0);
paste_indicator.orientation = r.get_orthogonal_index();
@@ -148,10 +138,8 @@ void GridMapEditor::_menu_option(int p_option) {
_update_cursor_transform();
} break;
case MENU_OPTION_CURSOR_ROTATE_Z: {
-
Basis r;
if (input_action == INPUT_PASTE) {
-
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(0, 0, 1), -Math_PI / 2.0);
paste_indicator.orientation = r.get_orthogonal_index();
@@ -165,10 +153,8 @@ void GridMapEditor::_menu_option(int p_option) {
_update_cursor_transform();
} break;
case MENU_OPTION_CURSOR_BACK_ROTATE_Y: {
-
Basis r;
if (input_action == INPUT_PASTE) {
-
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(0, 1, 0), Math_PI / 2.0);
paste_indicator.orientation = r.get_orthogonal_index();
@@ -182,10 +168,8 @@ void GridMapEditor::_menu_option(int p_option) {
_update_cursor_transform();
} break;
case MENU_OPTION_CURSOR_BACK_ROTATE_X: {
-
Basis r;
if (input_action == INPUT_PASTE) {
-
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(1, 0, 0), Math_PI / 2.0);
paste_indicator.orientation = r.get_orthogonal_index();
@@ -199,10 +183,8 @@ void GridMapEditor::_menu_option(int p_option) {
_update_cursor_transform();
} break;
case MENU_OPTION_CURSOR_BACK_ROTATE_Z: {
-
Basis r;
if (input_action == INPUT_PASTE) {
-
r.set_orthogonal_index(paste_indicator.orientation);
r.rotate(Vector3(0, 0, 1), Math_PI / 2.0);
paste_indicator.orientation = r.get_orthogonal_index();
@@ -216,9 +198,7 @@ void GridMapEditor::_menu_option(int p_option) {
_update_cursor_transform();
} break;
case MENU_OPTION_CURSOR_CLEAR_ROTATION: {
-
if (input_action == INPUT_PASTE) {
-
paste_indicator.orientation = 0;
_update_paste_indicator();
break;
@@ -235,8 +215,9 @@ void GridMapEditor::_menu_option(int p_option) {
case MENU_OPTION_SELECTION_DUPLICATE:
case MENU_OPTION_SELECTION_CUT: {
- if (!(selection.active && input_action == INPUT_NONE))
+ if (!(selection.active && input_action == INPUT_NONE)) {
break;
+ }
_set_clipboard_data();
@@ -253,15 +234,17 @@ void GridMapEditor::_menu_option(int p_option) {
_update_paste_indicator();
} break;
case MENU_OPTION_SELECTION_CLEAR: {
- if (!selection.active)
+ if (!selection.active) {
break;
+ }
_delete_selection();
} break;
case MENU_OPTION_SELECTION_FILL: {
- if (!selection.active)
+ if (!selection.active) {
return;
+ }
_fill_selection();
@@ -273,7 +256,6 @@ void GridMapEditor::_menu_option(int p_option) {
}
void GridMapEditor::_update_cursor_transform() {
-
cursor_transform = Transform();
cursor_transform.origin = cursor_origin;
cursor_transform.basis.set_orthogonal_index(cursor_rot);
@@ -291,7 +273,6 @@ void GridMapEditor::_update_selection_transform() {
xf_zero.basis.set_zero();
if (!selection.active) {
-
RenderingServer::get_singleton()->instance_set_transform(selection_instance, xf_zero);
for (int i = 0; i < 3; i++) {
RenderingServer::get_singleton()->instance_set_transform(selection_level_instance[i], xf_zero);
@@ -309,7 +290,6 @@ void GridMapEditor::_update_selection_transform() {
if (i != edit_axis || (edit_floor[edit_axis] < selection.begin[edit_axis]) || (edit_floor[edit_axis] > selection.end[edit_axis] + 1)) {
RenderingServer::get_singleton()->instance_set_transform(selection_level_instance[i], xf_zero);
} else {
-
Vector3 scale = (selection.end - selection.begin + Vector3(1, 1, 1));
scale[edit_axis] = 1.0;
Vector3 pos = selection.begin;
@@ -328,24 +308,26 @@ void GridMapEditor::_update_selection_transform() {
}
void GridMapEditor::_validate_selection() {
-
- if (!selection.active)
+ if (!selection.active) {
return;
+ }
selection.begin = selection.click;
selection.end = selection.current;
- if (selection.begin.x > selection.end.x)
+ if (selection.begin.x > selection.end.x) {
SWAP(selection.begin.x, selection.end.x);
- if (selection.begin.y > selection.end.y)
+ }
+ if (selection.begin.y > selection.end.y) {
SWAP(selection.begin.y, selection.end.y);
- if (selection.begin.z > selection.end.z)
+ }
+ if (selection.begin.z > selection.end.z) {
SWAP(selection.begin.z, selection.end.z);
+ }
_update_selection_transform();
}
void GridMapEditor::_set_selection(bool p_active, const Vector3 &p_begin, const Vector3 &p_end) {
-
selection.active = p_active;
selection.begin = p_begin;
selection.end = p_end;
@@ -363,17 +345,20 @@ void GridMapEditor::_set_selection(bool p_active, const Vector3 &p_begin, const
}
bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, bool p_click) {
-
- if (!spatial_editor)
+ if (!spatial_editor) {
return false;
+ }
- if (selected_palette < 0 && input_action != INPUT_PICK && input_action != INPUT_SELECT && input_action != INPUT_PASTE)
+ if (selected_palette < 0 && input_action != INPUT_PICK && input_action != INPUT_SELECT && input_action != INPUT_PASTE) {
return false;
+ }
Ref<MeshLibrary> mesh_library = node->get_mesh_library();
- if (mesh_library.is_null())
+ if (mesh_library.is_null()) {
return false;
- if (input_action != INPUT_PICK && input_action != INPUT_SELECT && input_action != INPUT_PASTE && !mesh_library->has_item(selected_palette))
+ }
+ if (input_action != INPUT_PICK && input_action != INPUT_SELECT && input_action != INPUT_PASTE && !mesh_library->has_item(selected_palette)) {
return false;
+ }
Camera3D *camera = p_camera;
Vector3 from = camera->project_ray_origin(p_point);
@@ -388,30 +373,30 @@ bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, b
p.d = edit_floor[edit_axis] * node->get_cell_size()[edit_axis];
Vector3 inters;
- if (!p.intersects_segment(from, from + normal * settings_pick_distance->get_value(), &inters))
+ if (!p.intersects_segment(from, from + normal * settings_pick_distance->get_value(), &inters)) {
return false;
+ }
// Make sure the intersection is inside the frustum planes, to avoid
// Painting on invisible regions.
for (int i = 0; i < planes.size(); i++) {
-
Plane fp = local_xform.xform(planes[i]);
- if (fp.is_point_over(inters))
+ if (fp.is_point_over(inters)) {
return false;
+ }
}
int cell[3];
float cell_size[3] = { node->get_cell_size().x, node->get_cell_size().y, node->get_cell_size().z };
for (int i = 0; i < 3; i++) {
-
- if (i == edit_axis)
+ if (i == edit_axis) {
cell[i] = edit_floor[i];
- else {
-
+ } else {
cell[i] = inters[i] / node->get_cell_size()[i];
- if (inters[i] < 0)
+ if (inters[i] < 0) {
cell[i] -= 1; // Compensate negative.
+ }
grid_ofs[i] = cell[i] * cell_size[i];
}
}
@@ -419,7 +404,6 @@ bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, b
RS::get_singleton()->instance_set_transform(grid_instance[edit_axis], node->get_global_transform() * edit_grid_xform);
if (cursor_instance.is_valid()) {
-
cursor_origin = (Vector3(cell[0], cell[1], cell[2]) + Vector3(0.5 * node->get_center_x(), 0.5 * node->get_center_y(), 0.5 * node->get_center_z())) * node->get_cell_size();
cursor_visible = true;
@@ -431,21 +415,19 @@ bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, b
}
if (input_action == INPUT_PASTE) {
-
paste_indicator.current = Vector3(cell[0], cell[1], cell[2]);
_update_paste_indicator();
} else if (input_action == INPUT_SELECT) {
-
selection.current = Vector3(cell[0], cell[1], cell[2]);
- if (p_click)
+ if (p_click) {
selection.click = selection.current;
+ }
selection.active = true;
_validate_selection();
return true;
} else if (input_action == INPUT_PICK) {
-
int item = node->get_cell_item(cell[0], cell[1], cell[2]);
if (item >= 0) {
selected_palette = item;
@@ -481,17 +463,14 @@ bool GridMapEditor::do_input_action(Camera3D *p_camera, const Point2 &p_point, b
}
void GridMapEditor::_delete_selection() {
-
- if (!selection.active)
+ if (!selection.active) {
return;
+ }
undo_redo->create_action(TTR("GridMap Delete Selection"));
for (int i = selection.begin.x; i <= selection.end.x; i++) {
-
for (int j = selection.begin.y; j <= selection.end.y; j++) {
-
for (int k = selection.begin.z; k <= selection.end.z; k++) {
-
undo_redo->add_do_method(node, "set_cell_item", i, j, k, GridMap::INVALID_CELL_ITEM);
undo_redo->add_undo_method(node, "set_cell_item", i, j, k, node->get_cell_item(i, j, k), node->get_cell_item_orientation(i, j, k));
}
@@ -503,17 +482,14 @@ void GridMapEditor::_delete_selection() {
}
void GridMapEditor::_fill_selection() {
-
- if (!selection.active)
+ if (!selection.active) {
return;
+ }
undo_redo->create_action(TTR("GridMap Fill Selection"));
for (int i = selection.begin.x; i <= selection.end.x; i++) {
-
for (int j = selection.begin.y; j <= selection.end.y; j++) {
-
for (int k = selection.begin.z; k <= selection.end.z; k++) {
-
undo_redo->add_do_method(node, "set_cell_item", i, j, k, selected_palette, cursor_rot);
undo_redo->add_undo_method(node, "set_cell_item", i, j, k, node->get_cell_item(i, j, k), node->get_cell_item_orientation(i, j, k));
}
@@ -525,9 +501,7 @@ void GridMapEditor::_fill_selection() {
}
void GridMapEditor::_clear_clipboard_data() {
-
for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) {
-
RenderingServer::get_singleton()->free(E->get().instance);
}
@@ -535,20 +509,17 @@ void GridMapEditor::_clear_clipboard_data() {
}
void GridMapEditor::_set_clipboard_data() {
-
_clear_clipboard_data();
Ref<MeshLibrary> meshLibrary = node->get_mesh_library();
for (int i = selection.begin.x; i <= selection.end.x; i++) {
-
for (int j = selection.begin.y; j <= selection.end.y; j++) {
-
for (int k = selection.begin.z; k <= selection.end.z; k++) {
-
int itm = node->get_cell_item(i, j, k);
- if (itm == GridMap::INVALID_CELL_ITEM)
+ if (itm == GridMap::INVALID_CELL_ITEM) {
continue;
+ }
Ref<Mesh> mesh = meshLibrary->get_item_mesh(itm);
@@ -556,7 +527,7 @@ void GridMapEditor::_set_clipboard_data() {
item.cell_item = itm;
item.grid_offset = Vector3(i, j, k) - selection.begin;
item.orientation = node->get_cell_item_orientation(i, j, k);
- item.instance = RenderingServer::get_singleton()->instance_create2(mesh->get_rid(), get_tree()->get_root()->get_world()->get_scenario());
+ item.instance = RenderingServer::get_singleton()->instance_create2(mesh->get_rid(), get_tree()->get_root()->get_world_3d()->get_scenario());
clipboard_items.push_back(item);
}
@@ -565,9 +536,7 @@ void GridMapEditor::_set_clipboard_data() {
}
void GridMapEditor::_update_paste_indicator() {
-
if (input_action != INPUT_PASTE) {
-
Transform xf;
xf.basis.set_zero();
RenderingServer::get_singleton()->instance_set_transform(paste_instance, xf);
@@ -587,7 +556,6 @@ void GridMapEditor::_update_paste_indicator() {
RenderingServer::get_singleton()->instance_set_transform(paste_instance, node->get_global_transform() * xf);
for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) {
-
ClipboardItem &item = E->get();
xf = Transform();
@@ -604,7 +572,6 @@ void GridMapEditor::_update_paste_indicator() {
}
void GridMapEditor::_do_paste() {
-
int idx = options->get_popup()->get_item_index(MENU_OPTION_PASTE_SELECTS);
bool reselect = options->get_popup()->is_item_checked(idx);
@@ -615,7 +582,6 @@ void GridMapEditor::_do_paste() {
undo_redo->create_action(TTR("GridMap Paste Selection"));
for (List<ClipboardItem>::Element *E = clipboard_items.front(); E; E = E->next()) {
-
ClipboardItem &item = E->get();
Vector3 pos = rot.xform(item.grid_offset) + paste_indicator.begin + ofs;
@@ -629,7 +595,6 @@ void GridMapEditor::_do_paste() {
}
if (reselect) {
-
undo_redo->add_do_method(this, "_set_selection", true, paste_indicator.begin + ofs, paste_indicator.end + ofs);
undo_redo->add_undo_method(this, "_set_selection", selection.active, selection.begin, selection.end);
}
@@ -647,15 +612,16 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
-
if (mb->get_button_index() == BUTTON_WHEEL_UP && (mb->get_command() || mb->get_shift())) {
- if (mb->is_pressed())
+ if (mb->is_pressed()) {
floor->set_value(floor->get_value() + mb->get_factor());
+ }
return true; // Eaten.
} else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && (mb->get_command() || mb->get_shift())) {
- if (mb->is_pressed())
+ if (mb->is_pressed()) {
floor->set_value(floor->get_value() - mb->get_factor());
+ }
return true;
}
@@ -664,7 +630,6 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
if ((nav_scheme == Node3DEditorViewport::NAVIGATION_MAYA || nav_scheme == Node3DEditorViewport::NAVIGATION_MODO) && mb->get_alt()) {
input_action = INPUT_NONE;
} else if (mb->get_button_index() == BUTTON_LEFT) {
-
bool can_edit = (node && node->get_mesh_library().is_valid());
if (input_action == INPUT_PASTE) {
_do_paste();
@@ -698,18 +663,14 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
return do_input_action(p_camera, Point2(mb->get_position().x, mb->get_position().y), true);
} else {
-
if ((mb->get_button_index() == BUTTON_RIGHT && input_action == INPUT_ERASE) || (mb->get_button_index() == BUTTON_LEFT && input_action == INPUT_PAINT)) {
-
if (set_items.size()) {
undo_redo->create_action(TTR("GridMap Paint"));
for (List<SetItem>::Element *E = set_items.front(); E; E = E->next()) {
-
const SetItem &si = E->get();
undo_redo->add_do_method(node, "set_cell_item", si.pos.x, si.pos.y, si.pos.z, si.new_value, si.new_orientation);
}
for (List<SetItem>::Element *E = set_items.back(); E; E = E->prev()) {
-
const SetItem &si = E->get();
undo_redo->add_undo_method(node, "set_cell_item", si.pos.x, si.pos.y, si.pos.z, si.old_value, si.old_orientation);
}
@@ -722,7 +683,6 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
}
if (mb->get_button_index() == BUTTON_LEFT && input_action == INPUT_SELECT) {
-
undo_redo->create_action("GridMap Selection");
undo_redo->add_do_method(this, "_set_selection", selection.active, selection.begin, selection.end);
undo_redo->add_undo_method(this, "_set_selection", last_selection.active, last_selection.begin, last_selection.end);
@@ -730,7 +690,6 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
}
if (mb->get_button_index() == BUTTON_LEFT && input_action != INPUT_NONE) {
-
set_items.clear();
input_action = INPUT_NONE;
return true;
@@ -745,7 +704,6 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
return do_input_action(p_camera, mm->get_position(), false);
}
@@ -754,7 +712,6 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
if (k.is_valid()) {
if (k->is_pressed()) {
if (k->get_keycode() == KEY_ESCAPE) {
-
if (input_action == INPUT_PASTE) {
_clear_clipboard_data();
input_action = INPUT_NONE;
@@ -773,7 +730,6 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
}
if (k->get_shift() && selection.active && input_action != INPUT_PASTE) {
-
if (k->get_keycode() == options->get_popup()->get_item_accelerator(options->get_popup()->get_item_index(MENU_OPTION_PREV_LEVEL))) {
selection.click[edit_axis]--;
_validate_selection();
@@ -790,7 +746,6 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
Ref<InputEventPanGesture> pan_gesture = p_event;
if (pan_gesture.is_valid()) {
-
if (pan_gesture->get_alt() && (pan_gesture->get_command() || pan_gesture->get_shift())) {
const real_t delta = pan_gesture->get_delta().y * 0.5;
accumulated_floor_delta += delta;
@@ -811,7 +766,6 @@ bool GridMapEditor::forward_spatial_input_event(Camera3D *p_camera, const Ref<In
}
struct _CGMEItemSort {
-
String name;
int id;
_FORCE_INLINE_ bool operator<(const _CGMEItemSort &r_it) const { return name < r_it.name; }
@@ -840,11 +794,9 @@ void GridMapEditor::_text_changed(const String &p_text) {
}
void GridMapEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
-
const Ref<InputEventKey> k = p_ie;
if (k.is_valid() && (k->get_keycode() == KEY_UP || k->get_keycode() == KEY_DOWN || k->get_keycode() == KEY_PAGEUP || k->get_keycode() == KEY_PAGEDOWN)) {
-
// Forward the key input to the ItemList so it can be scrolled
mesh_library_palette->call("_gui_input", k);
search_box->accept_event();
@@ -852,12 +804,10 @@ void GridMapEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
}
void GridMapEditor::_mesh_library_palette_input(const Ref<InputEvent> &p_ie) {
-
const Ref<InputEventMouseButton> mb = p_ie;
// Zoom in/out using Ctrl + mouse wheel
if (mb.is_valid() && mb->is_pressed() && mb->get_command()) {
-
if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) {
size_slider->set_value(size_slider->get_value() + 0.2);
}
@@ -911,7 +861,6 @@ void GridMapEditor::update_palette() {
List<_CGMEItemSort> il;
for (int i = 0; i < ids.size(); i++) {
-
_CGMEItemSort is;
is.id = ids[i];
is.name = mesh_library->get_item_name(ids[i]);
@@ -932,8 +881,9 @@ void GridMapEditor::update_palette() {
name = "#" + itos(id);
}
- if (filter != "" && !filter.is_subsequence_ofi(name))
+ if (filter != "" && !filter.is_subsequence_ofi(name)) {
continue;
+ }
mesh_library_palette->add_item("");
if (!preview.is_null()) {
@@ -954,8 +904,9 @@ void GridMapEditor::update_palette() {
}
void GridMapEditor::edit(GridMap *p_gridmap) {
- if (!p_gridmap && node)
+ if (!p_gridmap && node) {
node->disconnect("cell_size_changed", callable_mp(this, &GridMapEditor::_draw_grids));
+ }
node = p_gridmap;
@@ -993,16 +944,15 @@ void GridMapEditor::edit(GridMap *p_gridmap) {
}
void GridMapEditor::_update_clip() {
-
node->set_meta("_editor_clip_", clip_mode);
- if (clip_mode == CLIP_DISABLED)
+ if (clip_mode == CLIP_DISABLED) {
node->set_clip(false);
- else
+ } else {
node->set_clip(true, clip_mode == CLIP_ABOVE, edit_floor[edit_axis], edit_axis);
+ }
}
void GridMapEditor::update_grid() {
-
grid_xform.origin.x -= 1; // Force update in hackish way.
grid_ofs[edit_axis] = edit_floor[edit_axis] * node->get_cell_size()[edit_axis];
@@ -1031,7 +981,6 @@ void GridMapEditor::_draw_grids(const Vector3 &cell_size) {
Vector<Color> grid_colors[3];
for (int i = 0; i < 3; i++) {
-
Vector3 axis;
axis[i] = 1;
Vector3 axis_n1;
@@ -1040,9 +989,7 @@ void GridMapEditor::_draw_grids(const Vector3 &cell_size) {
axis_n2[(i + 2) % 3] = cell_size[(i + 2) % 3];
for (int j = -GRID_CURSOR_SIZE; j <= GRID_CURSOR_SIZE; j++) {
-
for (int k = -GRID_CURSOR_SIZE; k <= GRID_CURSOR_SIZE; k++) {
-
Vector3 p = axis_n1 * j + axis_n2 * k;
float trans = Math::pow(MAX(0, 1.0 - (Vector2(j, k).length() / GRID_CURSOR_SIZE)), 2);
@@ -1074,21 +1021,18 @@ void GridMapEditor::_draw_grids(const Vector3 &cell_size) {
}
void GridMapEditor::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
get_tree()->connect("node_removed", callable_mp(this, &GridMapEditor::_node_removed));
mesh_library_palette->connect("item_selected", callable_mp(this, &GridMapEditor::_item_selected_cbk));
for (int i = 0; i < 3; i++) {
-
grid[i] = RS::get_singleton()->mesh_create();
- grid_instance[i] = RS::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world()->get_scenario());
- selection_level_instance[i] = RenderingServer::get_singleton()->instance_create2(selection_level_mesh[i], get_tree()->get_root()->get_world()->get_scenario());
+ grid_instance[i] = RS::get_singleton()->instance_create2(grid[i], get_tree()->get_root()->get_world_3d()->get_scenario());
+ selection_level_instance[i] = RenderingServer::get_singleton()->instance_create2(selection_level_mesh[i], get_tree()->get_root()->get_world_3d()->get_scenario());
}
- selection_instance = RenderingServer::get_singleton()->instance_create2(selection_mesh, get_tree()->get_root()->get_world()->get_scenario());
- paste_instance = RenderingServer::get_singleton()->instance_create2(paste_mesh, get_tree()->get_root()->get_world()->get_scenario());
+ selection_instance = RenderingServer::get_singleton()->instance_create2(selection_mesh, get_tree()->get_root()->get_world_3d()->get_scenario());
+ paste_instance = RenderingServer::get_singleton()->instance_create2(paste_mesh, get_tree()->get_root()->get_world_3d()->get_scenario());
_update_selection_transform();
_update_paste_indicator();
@@ -1099,7 +1043,6 @@ void GridMapEditor::_notification(int p_what) {
_clear_clipboard_data();
for (int i = 0; i < 3; i++) {
-
RS::get_singleton()->free(grid_instance[i]);
RS::get_singleton()->free(grid[i]);
grid_instance[i] = RID();
@@ -1122,17 +1065,16 @@ void GridMapEditor::_notification(int p_what) {
if (xf != grid_xform) {
for (int i = 0; i < 3; i++) {
-
RS::get_singleton()->instance_set_transform(grid_instance[i], xf * edit_grid_xform);
}
grid_xform = xf;
}
Ref<MeshLibrary> cgmt = node->get_mesh_library();
- if (cgmt.operator->() != last_mesh_library)
+ if (cgmt.operator->() != last_mesh_library) {
update_palette();
+ }
if (lock_view) {
-
EditorNode *editor = Object::cast_to<EditorNode>(get_tree()->get_root()->get_child(0));
Plane p;
@@ -1141,8 +1083,9 @@ void GridMapEditor::_notification(int p_what) {
p = node->get_transform().xform(p); // plane to snap
Node3DEditorPlugin *sep = Object::cast_to<Node3DEditorPlugin>(editor->get_editor_plugin_screen());
- if (sep)
+ if (sep) {
sep->snap_cursor_to_plane(p);
+ }
}
} break;
@@ -1158,17 +1101,16 @@ void GridMapEditor::_update_cursor_instance() {
return;
}
- if (cursor_instance.is_valid())
+ if (cursor_instance.is_valid()) {
RenderingServer::get_singleton()->free(cursor_instance);
+ }
cursor_instance = RID();
if (selected_palette >= 0) {
-
if (node && !node->get_mesh_library().is_null()) {
Ref<Mesh> mesh = node->get_mesh_library()->get_item_mesh(selected_palette);
if (!mesh.is_null() && mesh->get_rid().is_valid()) {
-
- cursor_instance = RenderingServer::get_singleton()->instance_create2(mesh->get_rid(), get_tree()->get_root()->get_world()->get_scenario());
+ cursor_instance = RenderingServer::get_singleton()->instance_create2(mesh->get_rid(), get_tree()->get_root()->get_world_3d()->get_scenario());
RenderingServer::get_singleton()->instance_set_transform(cursor_instance, cursor_transform);
}
}
@@ -1182,9 +1124,9 @@ void GridMapEditor::_item_selected_cbk(int idx) {
}
void GridMapEditor::_floor_changed(float p_value) {
-
- if (updating)
+ if (updating) {
return;
+ }
edit_floor[edit_axis] = p_value;
node->set_meta("_editor_floor_", Vector3(edit_floor[0], edit_floor[1], edit_floor[2]));
@@ -1198,13 +1140,11 @@ void GridMapEditor::_floor_mouse_exited() {
}
void GridMapEditor::_bind_methods() {
-
ClassDB::bind_method("_configure", &GridMapEditor::_configure);
ClassDB::bind_method("_set_selection", &GridMapEditor::_set_selection);
}
GridMapEditor::GridMapEditor(EditorNode *p_editor) {
-
input_action = INPUT_NONE;
editor = p_editor;
undo_redo = p_editor->get_undo_redo();
@@ -1364,22 +1304,20 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
Vector<Vector3> square[3];
for (int i = 0; i < 6; i++) {
-
Vector3 face_points[4];
for (int j = 0; j < 4; j++) {
-
float v[3];
v[0] = 1.0;
v[1] = 1 - 2 * ((j >> 1) & 1);
v[2] = v[1] * (1 - 2 * (j & 1));
for (int k = 0; k < 3; k++) {
-
- if (i < 3)
+ if (i < 3) {
face_points[j][(i + k) % 3] = v[k];
- else
+ } else {
face_points[3 - j][(i + k) % 3] = -v[k];
+ }
}
}
@@ -1393,7 +1331,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
}
for (int i = 0; i < 12; i++) {
-
AABB base(Vector3(0, 0, 0), Vector3(1, 1, 1));
Vector3 a, b;
base.get_edge(i, a, b);
@@ -1404,9 +1341,8 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
for (int i = 0; i < 3; i++) {
Vector3 points[4];
for (int j = 0; j < 4; j++) {
-
- static const bool orderx[4] = { 0, 1, 1, 0 };
- static const bool ordery[4] = { 0, 0, 1, 1 };
+ static const bool orderx[4] = { false, true, true, false };
+ static const bool ordery[4] = { false, false, true, true };
Vector3 sp;
if (orderx[j]) {
@@ -1420,7 +1356,6 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
}
for (int j = 0; j < 4; j++) {
-
Vector3 ofs;
ofs[i] += 0.01;
square[i].push_back(points[j] - ofs);
@@ -1487,36 +1422,39 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
}
GridMapEditor::~GridMapEditor() {
-
_clear_clipboard_data();
for (int i = 0; i < 3; i++) {
-
- if (grid[i].is_valid())
+ if (grid[i].is_valid()) {
RenderingServer::get_singleton()->free(grid[i]);
- if (grid_instance[i].is_valid())
+ }
+ if (grid_instance[i].is_valid()) {
RenderingServer::get_singleton()->free(grid_instance[i]);
- if (cursor_instance.is_valid())
+ }
+ if (cursor_instance.is_valid()) {
RenderingServer::get_singleton()->free(cursor_instance);
- if (selection_level_instance[i].is_valid())
+ }
+ if (selection_level_instance[i].is_valid()) {
RenderingServer::get_singleton()->free(selection_level_instance[i]);
- if (selection_level_mesh[i].is_valid())
+ }
+ if (selection_level_mesh[i].is_valid()) {
RenderingServer::get_singleton()->free(selection_level_mesh[i]);
+ }
}
RenderingServer::get_singleton()->free(selection_mesh);
- if (selection_instance.is_valid())
+ if (selection_instance.is_valid()) {
RenderingServer::get_singleton()->free(selection_instance);
+ }
RenderingServer::get_singleton()->free(paste_mesh);
- if (paste_instance.is_valid())
+ if (paste_instance.is_valid()) {
RenderingServer::get_singleton()->free(paste_instance);
+ }
}
void GridMapEditorPlugin::_notification(int p_what) {
-
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
-
switch ((int)EditorSettings::get_singleton()->get("editors/grid_map/editor_side")) {
case 0: { // Left.
Node3DEditor::get_singleton()->get_palette_split()->move_child(grid_map_editor, 0);
@@ -1529,23 +1467,19 @@ void GridMapEditorPlugin::_notification(int p_what) {
}
void GridMapEditorPlugin::edit(Object *p_object) {
-
grid_map_editor->edit(Object::cast_to<GridMap>(p_object));
}
bool GridMapEditorPlugin::handles(Object *p_object) const {
-
return p_object->is_class("GridMap");
}
void GridMapEditorPlugin::make_visible(bool p_visible) {
-
if (p_visible) {
grid_map_editor->show();
grid_map_editor->spatial_editor_hb->show();
grid_map_editor->set_process(true);
} else {
-
grid_map_editor->spatial_editor_hb->hide();
grid_map_editor->hide();
grid_map_editor->edit(nullptr);
@@ -1554,7 +1488,6 @@ void GridMapEditorPlugin::make_visible(bool p_visible) {
}
GridMapEditorPlugin::GridMapEditorPlugin(EditorNode *p_node) {
-
editor = p_node;
EDITOR_DEF("editors/grid_map/editor_side", 1);
diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h
index fd880e8b7b..19eea18965 100644
--- a/modules/gridmap/grid_map_editor_plugin.h
+++ b/modules/gridmap/grid_map_editor_plugin.h
@@ -85,7 +85,6 @@ class GridMapEditor : public VBoxContainer {
Label *spin_box_label;
struct SetItem {
-
Vector3 pos;
int new_value;
int new_orientation;
@@ -133,7 +132,6 @@ class GridMapEditor : public VBoxContainer {
bool updating;
struct Selection {
-
Vector3 click;
Vector3 current;
Vector3 begin;
@@ -143,7 +141,6 @@ class GridMapEditor : public VBoxContainer {
Selection last_selection;
struct PasteIndicator {
-
Vector3 click;
Vector3 current;
Vector3 begin;
@@ -191,7 +188,6 @@ class GridMapEditor : public VBoxContainer {
Node3DEditorPlugin *spatial_editor;
struct AreaDisplay {
-
RID mesh;
RID instance;
};
@@ -251,7 +247,6 @@ public:
};
class GridMapEditorPlugin : public EditorPlugin {
-
GDCLASS(GridMapEditorPlugin, EditorPlugin);
GridMapEditor *grid_map_editor;
diff --git a/modules/gridmap/register_types.cpp b/modules/gridmap/register_types.cpp
index afd51945ab..906e506b62 100644
--- a/modules/gridmap/register_types.cpp
+++ b/modules/gridmap/register_types.cpp
@@ -36,7 +36,6 @@
#endif
void register_gridmap_types() {
-
#ifndef _3D_DISABLED
ClassDB::register_class<GridMap>();
#ifdef TOOLS_ENABLED
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
index c03ae4ab1f..333b1cf377 100644
--- a/modules/hdr/image_loader_hdr.cpp
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -34,7 +34,6 @@
#include "core/print_string.h"
Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
-
String header = f->get_token();
ERR_FAIL_COND_V_MSG(header != "#?RADIANCE" && header != "#?RGBE", ERR_FILE_UNRECOGNIZED, "Unsupported header information in HDR: " + header + ".");
@@ -42,8 +41,9 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
while (true) {
String line = f->get_line();
ERR_FAIL_COND_V(f->eof_reached(), ERR_FILE_UNRECOGNIZED);
- if (line == "") // empty line indicates end of header
+ if (line == "") { // empty line indicates end of header
break;
+ }
if (line.begins_with("FORMAT=")) { // leave option to implement other commands
ERR_FAIL_COND_V_MSG(line != "FORMAT=32-bit_rle_rgbe", ERR_FILE_UNRECOGNIZED, "Only 32-bit_rle_rgbe is supported for HDR files.");
} else if (!line.begins_with("#")) { // not comment
@@ -68,7 +68,6 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
imgdata.resize(height * width * sizeof(uint32_t));
{
-
uint8_t *w = imgdata.ptrw();
uint8_t *ptr = (uint8_t *)w;
@@ -109,12 +108,14 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
// Run
int value = f->get_8();
count -= 128;
- for (int z = 0; z < count; ++z)
+ for (int z = 0; z < count; ++z) {
ptr[(j * width + i++) * 4 + k] = uint8_t(value);
+ }
} else {
// Dump
- for (int z = 0; z < count; ++z)
+ for (int z = 0; z < count; ++z) {
ptr[(j * width + i++) * 4 + k] = f->get_8();
+ }
}
}
}
@@ -123,7 +124,6 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
//convert
for (int i = 0; i < width * height; i++) {
-
float exp = pow(2.0f, ptr[3] - 128.0f);
Color c(
@@ -146,7 +146,6 @@ Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
}
void ImageLoaderHDR::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("hdr");
}
diff --git a/modules/hdr/image_loader_hdr.h b/modules/hdr/image_loader_hdr.h
index a5f1f9c387..ef8e116616 100644
--- a/modules/hdr/image_loader_hdr.h
+++ b/modules/hdr/image_loader_hdr.h
@@ -34,7 +34,6 @@
#include "core/io/image_loader.h"
class ImageLoaderHDR : public ImageFormatLoader {
-
public:
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
diff --git a/modules/hdr/register_types.cpp b/modules/hdr/register_types.cpp
index 5f2d1578c5..e749928f60 100644
--- a/modules/hdr/register_types.cpp
+++ b/modules/hdr/register_types.cpp
@@ -35,12 +35,10 @@
static ImageLoaderHDR *image_loader_hdr = nullptr;
void register_hdr_types() {
-
image_loader_hdr = memnew(ImageLoaderHDR);
ImageLoader::add_image_format_loader(image_loader_hdr);
}
void unregister_hdr_types() {
-
memdelete(image_loader_hdr);
}
diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp
index 9e87d11ac1..9c7ace5cf2 100644
--- a/modules/jpg/image_loader_jpegd.cpp
+++ b/modules/jpg/image_loader_jpegd.cpp
@@ -37,7 +37,6 @@
#include <string.h>
Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p_buffer_len) {
-
jpgd::jpeg_decoder_mem_stream mem_stream(p_buffer, p_buffer_len);
jpgd::jpeg_decoder decoder(&mem_stream);
@@ -49,11 +48,13 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
const int image_width = decoder.get_width();
const int image_height = decoder.get_height();
const int comps = decoder.get_num_components();
- if (comps != 1 && comps != 3)
+ if (comps != 1 && comps != 3) {
return ERR_FILE_CORRUPT;
+ }
- if (decoder.begin_decoding() != jpgd::JPGD_SUCCESS)
+ if (decoder.begin_decoding() != jpgd::JPGD_SUCCESS) {
return ERR_FILE_CORRUPT;
+ }
const int dst_bpl = image_width * comps;
@@ -91,18 +92,18 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
//all good
Image::Format fmt;
- if (comps == 1)
+ if (comps == 1) {
fmt = Image::FORMAT_L8;
- else
+ } else {
fmt = Image::FORMAT_RGB8;
+ }
- p_image->create(image_width, image_height, 0, fmt, data);
+ p_image->create(image_width, image_height, false, fmt, data);
return OK;
}
Error ImageLoaderJPG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
-
Vector<uint8_t> src_image;
int src_image_len = f->get_len();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
@@ -120,13 +121,11 @@ Error ImageLoaderJPG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
}
void ImageLoaderJPG::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("jpg");
p_extensions->push_back("jpeg");
}
static Ref<Image> _jpegd_mem_loader_func(const uint8_t *p_png, int p_size) {
-
Ref<Image> img;
img.instance();
Error err = jpeg_load_image_from_buffer(img.ptr(), p_png, p_size);
@@ -135,6 +134,5 @@ static Ref<Image> _jpegd_mem_loader_func(const uint8_t *p_png, int p_size) {
}
ImageLoaderJPG::ImageLoaderJPG() {
-
Image::_jpg_mem_loader_func = _jpegd_mem_loader_func;
}
diff --git a/modules/jpg/image_loader_jpegd.h b/modules/jpg/image_loader_jpegd.h
index 9ef37ae303..9aebaad9e3 100644
--- a/modules/jpg/image_loader_jpegd.h
+++ b/modules/jpg/image_loader_jpegd.h
@@ -34,7 +34,6 @@
#include "core/io/image_loader.h"
class ImageLoaderJPG : public ImageFormatLoader {
-
public:
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
diff --git a/modules/jpg/register_types.cpp b/modules/jpg/register_types.cpp
index 61375fef10..b31746f769 100644
--- a/modules/jpg/register_types.cpp
+++ b/modules/jpg/register_types.cpp
@@ -35,12 +35,10 @@
static ImageLoaderJPG *image_loader_jpg = nullptr;
void register_jpg_types() {
-
image_loader_jpg = memnew(ImageLoaderJPG);
ImageLoader::add_image_format_loader(image_loader_jpg);
}
void unregister_jpg_types() {
-
memdelete(image_loader_jpg);
}
diff --git a/modules/jsonrpc/jsonrpc.cpp b/modules/jsonrpc/jsonrpc.cpp
index 393269d422..7bb70b098f 100644
--- a/modules/jsonrpc/jsonrpc.cpp
+++ b/modules/jsonrpc/jsonrpc.cpp
@@ -120,7 +120,7 @@ Variant JSONRPC::process_action(const Variant &p_action, bool p_process_arr_elem
}
if (object == nullptr || !object->has_method(method)) {
- ret = make_response_error(JSONRPC::METHOD_NOT_FOUND, "Method not found", id);
+ ret = make_response_error(JSONRPC::METHOD_NOT_FOUND, "Method not found: " + method, id);
} else {
Variant call_ret = object->callv(method, args);
if (id.get_type() != Variant::NIL) {
@@ -147,8 +147,9 @@ Variant JSONRPC::process_action(const Variant &p_action, bool p_process_arr_elem
}
String JSONRPC::process_string(const String &p_input) {
-
- if (p_input.empty()) return String();
+ if (p_input.empty()) {
+ return String();
+ }
Variant ret;
Variant input;
diff --git a/modules/lightmapper_rd/SCsub b/modules/lightmapper_rd/SCsub
new file mode 100644
index 0000000000..2f04f1833e
--- /dev/null
+++ b/modules/lightmapper_rd/SCsub
@@ -0,0 +1,12 @@
+#!/usr/bin/env python
+
+Import("env")
+Import("env_modules")
+
+env_lightmapper_rd = env_modules.Clone()
+env_lightmapper_rd.GLSL_HEADER("lm_raster.glsl")
+env_lightmapper_rd.GLSL_HEADER("lm_compute.glsl")
+env_lightmapper_rd.GLSL_HEADER("lm_blendseams.glsl")
+
+# Godot source files
+env_lightmapper_rd.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/lightmapper_rd/config.py b/modules/lightmapper_rd/config.py
new file mode 100644
index 0000000000..d22f9454ed
--- /dev/null
+++ b/modules/lightmapper_rd/config.py
@@ -0,0 +1,6 @@
+def can_build(env, platform):
+ return True
+
+
+def configure(env):
+ pass
diff --git a/modules/lightmapper_rd/lightmapper_rd.cpp b/modules/lightmapper_rd/lightmapper_rd.cpp
new file mode 100644
index 0000000000..b55c73e9bc
--- /dev/null
+++ b/modules/lightmapper_rd/lightmapper_rd.cpp
@@ -0,0 +1,1752 @@
+/*************************************************************************/
+/* lightmapper_rd.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "lightmapper_rd.h"
+#include "core/math/geometry.h"
+#include "core/project_settings.h"
+#include "lm_blendseams.glsl.gen.h"
+#include "lm_compute.glsl.gen.h"
+#include "lm_raster.glsl.gen.h"
+#include "servers/rendering/rendering_device_binds.h"
+
+//uncomment this if you want to see textures from all the process saved
+//#define DEBUG_TEXTURES
+
+void LightmapperRD::add_mesh(const MeshData &p_mesh) {
+ ERR_FAIL_COND(p_mesh.albedo_on_uv2.is_null() || p_mesh.albedo_on_uv2->empty());
+ ERR_FAIL_COND(p_mesh.emission_on_uv2.is_null() || p_mesh.emission_on_uv2->empty());
+ ERR_FAIL_COND(p_mesh.albedo_on_uv2->get_width() != p_mesh.emission_on_uv2->get_width());
+ ERR_FAIL_COND(p_mesh.albedo_on_uv2->get_height() != p_mesh.emission_on_uv2->get_height());
+ ERR_FAIL_COND(p_mesh.points.size() == 0);
+ MeshInstance mi;
+ mi.data = p_mesh;
+ mesh_instances.push_back(mi);
+}
+
+void LightmapperRD::add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance) {
+ Light l;
+ l.type = LIGHT_TYPE_DIRECTIONAL;
+ l.direction[0] = p_direction.x;
+ l.direction[1] = p_direction.y;
+ l.direction[2] = p_direction.z;
+ l.color[0] = p_color.r;
+ l.color[1] = p_color.g;
+ l.color[2] = p_color.b;
+ l.energy = p_energy;
+ l.static_bake = p_static;
+ l.size = p_angular_distance;
+ lights.push_back(l);
+}
+
+void LightmapperRD::add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size) {
+ Light l;
+ l.type = LIGHT_TYPE_OMNI;
+ l.position[0] = p_position.x;
+ l.position[1] = p_position.y;
+ l.position[2] = p_position.z;
+ l.range = p_range;
+ l.attenuation = p_attenuation;
+ l.color[0] = p_color.r;
+ l.color[1] = p_color.g;
+ l.color[2] = p_color.b;
+ l.energy = p_energy;
+ l.static_bake = p_static;
+ l.size = p_size;
+ lights.push_back(l);
+}
+
+void LightmapperRD::add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size) {
+ Light l;
+ l.type = LIGHT_TYPE_SPOT;
+ l.position[0] = p_position.x;
+ l.position[1] = p_position.y;
+ l.position[2] = p_position.z;
+ l.direction[0] = p_direction.x;
+ l.direction[1] = p_direction.y;
+ l.direction[2] = p_direction.z;
+ l.range = p_range;
+ l.attenuation = p_attenuation;
+ l.spot_angle = Math::deg2rad(p_spot_angle);
+ l.spot_attenuation = p_spot_attenuation;
+ l.color[0] = p_color.r;
+ l.color[1] = p_color.g;
+ l.color[2] = p_color.b;
+ l.energy = p_energy;
+ l.static_bake = p_static;
+ l.size = p_size;
+ lights.push_back(l);
+}
+
+void LightmapperRD::add_probe(const Vector3 &p_position) {
+ Probe probe;
+ probe.position[0] = p_position.x;
+ probe.position[1] = p_position.y;
+ probe.position[2] = p_position.z;
+ probe.position[3] = 0;
+ probe_positions.push_back(probe);
+}
+
+void LightmapperRD::_plot_triangle_into_triangle_index_list(int p_size, const Vector3i &p_ofs, const AABB &p_bounds, const Vector3 p_points[3], uint32_t p_triangle_index, LocalVector<TriangleSort> &triangles, uint32_t p_grid_size) {
+ int half_size = p_size / 2;
+
+ for (int i = 0; i < 8; i++) {
+ AABB aabb = p_bounds;
+ aabb.size *= 0.5;
+ Vector3i n = p_ofs;
+
+ if (i & 1) {
+ aabb.position.x += aabb.size.x;
+ n.x += half_size;
+ }
+ if (i & 2) {
+ aabb.position.y += aabb.size.y;
+ n.y += half_size;
+ }
+ if (i & 4) {
+ aabb.position.z += aabb.size.z;
+ n.z += half_size;
+ }
+
+ {
+ Vector3 qsize = aabb.size * 0.5; //quarter size, for fast aabb test
+
+ if (!Geometry::triangle_box_overlap(aabb.position + qsize, qsize, p_points)) {
+ //does not fit in child, go on
+ continue;
+ }
+ }
+
+ if (half_size == 1) {
+ //got to the end
+ TriangleSort ts;
+ ts.cell_index = n.x + (n.y * p_grid_size) + (n.z * p_grid_size * p_grid_size);
+ ts.triangle_index = p_triangle_index;
+ triangles.push_back(ts);
+ } else {
+ _plot_triangle_into_triangle_index_list(half_size, n, aabb, p_points, p_triangle_index, triangles, p_grid_size);
+ }
+ }
+}
+
+Lightmapper::BakeError LightmapperRD::_blit_meshes_into_atlas(int p_max_texture_size, Vector<Ref<Image>> &albedo_images, Vector<Ref<Image>> &emission_images, AABB &bounds, Size2i &atlas_size, int &atlas_slices, BakeStepFunc p_step_function, void *p_bake_userdata) {
+ Vector<Size2i> sizes;
+
+ for (int m_i = 0; m_i < mesh_instances.size(); m_i++) {
+ MeshInstance &mi = mesh_instances.write[m_i];
+ Size2i s = Size2i(mi.data.albedo_on_uv2->get_width(), mi.data.albedo_on_uv2->get_height());
+ sizes.push_back(s);
+ atlas_size.width = MAX(atlas_size.width, s.width);
+ atlas_size.height = MAX(atlas_size.height, s.height);
+ }
+
+ int max = nearest_power_of_2_templated(atlas_size.width);
+ max = MAX(max, nearest_power_of_2_templated(atlas_size.height));
+
+ if (max > p_max_texture_size) {
+ return BAKE_ERROR_LIGHTMAP_TOO_SMALL;
+ }
+
+ if (p_step_function) {
+ p_step_function(0.1, TTR("Determining optimal atlas size"), p_bake_userdata, true);
+ }
+
+ atlas_size = Size2i(max, max);
+
+ Size2i best_atlas_size;
+ int best_atlas_slices = 0;
+ int best_atlas_memory = 0x7FFFFFFF;
+ Vector<Vector3i> best_atlas_offsets;
+
+ //determine best texture array atlas size by bruteforce fitting
+ while (atlas_size.x <= p_max_texture_size && atlas_size.y <= p_max_texture_size) {
+ Vector<Vector2i> source_sizes = sizes;
+ Vector<int> source_indices;
+ source_indices.resize(source_sizes.size());
+ for (int i = 0; i < source_indices.size(); i++) {
+ source_indices.write[i] = i;
+ }
+ Vector<Vector3i> atlas_offsets;
+ atlas_offsets.resize(source_sizes.size());
+
+ int slices = 0;
+
+ while (source_sizes.size() > 0) {
+ Vector<Vector3i> offsets = Geometry::partial_pack_rects(source_sizes, atlas_size);
+ Vector<int> new_indices;
+ Vector<Vector2i> new_sources;
+ for (int i = 0; i < offsets.size(); i++) {
+ Vector3i ofs = offsets[i];
+ int sidx = source_indices[i];
+ if (ofs.z > 0) {
+ //valid
+ ofs.z = slices;
+ atlas_offsets.write[sidx] = ofs;
+ } else {
+ new_indices.push_back(sidx);
+ new_sources.push_back(source_sizes[i]);
+ }
+ }
+
+ source_sizes = new_sources;
+ source_indices = new_indices;
+ slices++;
+ }
+
+ int mem_used = atlas_size.x * atlas_size.y * slices;
+ if (mem_used < best_atlas_memory) {
+ best_atlas_size = atlas_size;
+ best_atlas_offsets = atlas_offsets;
+ best_atlas_slices = slices;
+ best_atlas_memory = mem_used;
+ }
+
+ if (atlas_size.width == atlas_size.height) {
+ atlas_size.width *= 2;
+ } else {
+ atlas_size.height *= 2;
+ }
+ }
+ atlas_size = best_atlas_size;
+ atlas_slices = best_atlas_slices;
+
+ // apply the offsets and slice to all images, and also blit albedo and emission
+ albedo_images.resize(atlas_slices);
+ emission_images.resize(atlas_slices);
+
+ if (p_step_function) {
+ p_step_function(0.2, TTR("Blitting albedo and emission"), p_bake_userdata, true);
+ }
+
+ for (int i = 0; i < atlas_slices; i++) {
+ Ref<Image> albedo;
+ albedo.instance();
+ albedo->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBA8);
+ albedo->set_as_black();
+ albedo_images.write[i] = albedo;
+
+ Ref<Image> emission;
+ emission.instance();
+ emission->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH);
+ emission->set_as_black();
+ emission_images.write[i] = emission;
+ }
+
+ //assign uv positions
+
+ for (int m_i = 0; m_i < mesh_instances.size(); m_i++) {
+ MeshInstance &mi = mesh_instances.write[m_i];
+ mi.offset.x = best_atlas_offsets[m_i].x;
+ mi.offset.y = best_atlas_offsets[m_i].y;
+ mi.slice = best_atlas_offsets[m_i].z;
+ albedo_images.write[mi.slice]->blit_rect(mi.data.albedo_on_uv2, Rect2(Vector2(), Size2i(mi.data.albedo_on_uv2->get_width(), mi.data.albedo_on_uv2->get_height())), mi.offset);
+ emission_images.write[mi.slice]->blit_rect(mi.data.emission_on_uv2, Rect2(Vector2(), Size2i(mi.data.emission_on_uv2->get_width(), mi.data.emission_on_uv2->get_height())), mi.offset);
+ }
+
+ return BAKE_OK;
+}
+
+void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, AABB &bounds, int grid_size, Vector<Probe> &probe_positions, GenerateProbes p_generate_probes, Vector<int> &slice_triangle_count, Vector<int> &slice_seam_count, RID &vertex_buffer, RID &triangle_buffer, RID &box_buffer, RID &lights_buffer, RID &triangle_cell_indices_buffer, RID &probe_positions_buffer, RID &grid_texture, RID &grid_texture_sdf, RID &seams_buffer, BakeStepFunc p_step_function, void *p_bake_userdata) {
+ HashMap<Vertex, uint32_t, VertexHash> vertex_map;
+
+ //fill triangles array and vertex array
+ LocalVector<Triangle> triangles;
+ LocalVector<Vertex> vertex_array;
+ LocalVector<Box> box_array;
+ LocalVector<Seam> seams;
+
+ slice_triangle_count.resize(atlas_slices);
+ slice_seam_count.resize(atlas_slices);
+
+ for (int i = 0; i < atlas_slices; i++) {
+ slice_triangle_count.write[i] = 0;
+ slice_seam_count.write[i] = 0;
+ }
+
+ bounds = AABB();
+
+ for (int m_i = 0; m_i < mesh_instances.size(); m_i++) {
+ if (p_step_function) {
+ float p = float(m_i + 1) / mesh_instances.size() * 0.1;
+ p_step_function(0.3 + p, vformat(TTR("Plotting mesh into acceleration structure %d/%d"), m_i + 1, mesh_instances.size()), p_bake_userdata, false);
+ }
+
+ HashMap<Edge, EdgeUV2, EdgeHash> edges;
+
+ MeshInstance &mi = mesh_instances.write[m_i];
+
+ Vector2 uv_scale = Vector2(mi.data.albedo_on_uv2->get_width(), mi.data.albedo_on_uv2->get_height()) / Vector2(atlas_size);
+ Vector2 uv_offset = Vector2(mi.offset) / Vector2(atlas_size);
+ if (m_i == 0) {
+ bounds.position = mi.data.points[0];
+ }
+
+ for (int i = 0; i < mi.data.points.size(); i += 3) {
+ Vector3 vtxs[3] = { mi.data.points[i + 0], mi.data.points[i + 1], mi.data.points[i + 2] };
+ Vector2 uvs[3] = { mi.data.uv2[i + 0] * uv_scale + uv_offset, mi.data.uv2[i + 1] * uv_scale + uv_offset, mi.data.uv2[i + 2] * uv_scale + uv_offset };
+ Vector3 normal[3] = { mi.data.normal[i + 0], mi.data.normal[i + 1], mi.data.normal[i + 2] };
+
+ AABB taabb;
+ Triangle t;
+ t.slice = mi.slice;
+ for (int k = 0; k < 3; k++) {
+ bounds.expand_to(vtxs[k]);
+
+ Vertex v;
+ v.position[0] = vtxs[k].x;
+ v.position[1] = vtxs[k].y;
+ v.position[2] = vtxs[k].z;
+ v.uv[0] = uvs[k].x;
+ v.uv[1] = uvs[k].y;
+ v.normal_xy[0] = normal[k].x;
+ v.normal_xy[1] = normal[k].y;
+ v.normal_z = normal[k].z;
+
+ uint32_t *indexptr = vertex_map.getptr(v);
+
+ if (indexptr) {
+ t.indices[k] = *indexptr;
+ } else {
+ uint32_t new_index = vertex_map.size();
+ t.indices[k] = new_index;
+ vertex_map[v] = new_index;
+ vertex_array.push_back(v);
+ }
+
+ if (k == 0) {
+ taabb.position = vtxs[k];
+ } else {
+ taabb.expand_to(vtxs[k]);
+ }
+ }
+
+ //compute seams that will need to be blended later
+ for (int k = 0; k < 3; k++) {
+ int n = (k + 1) % 3;
+
+ Edge edge(vtxs[k], vtxs[n], normal[k], normal[n]);
+ Vector2i edge_indices(t.indices[k], t.indices[n]);
+ EdgeUV2 uv2(uvs[k], uvs[n], edge_indices);
+
+ if (edge.b == edge.a) {
+ continue; //degenerate, somehow
+ }
+ if (edge.b < edge.a) {
+ SWAP(edge.a, edge.b);
+ SWAP(edge.na, edge.nb);
+ SWAP(uv2.a, uv2.b);
+ SWAP(edge_indices.x, edge_indices.y);
+ }
+
+ EdgeUV2 *euv2 = edges.getptr(edge);
+ if (!euv2) {
+ edges[edge] = uv2;
+ } else {
+ if (*euv2 == uv2) {
+ continue; // seam shared UV space, no need to blend
+ }
+ if (euv2->seam_found) {
+ continue; //bad geometry
+ }
+
+ Seam seam;
+ seam.a = edge_indices;
+ seam.b = euv2->indices;
+ seam.slice = mi.slice;
+ seams.push_back(seam);
+ slice_seam_count.write[mi.slice]++;
+ euv2->seam_found = true;
+ }
+ }
+
+ Box box;
+ box.min_bounds[0] = taabb.position.x;
+ box.min_bounds[1] = taabb.position.y;
+ box.min_bounds[2] = taabb.position.z;
+ box.max_bounds[0] = taabb.position.x + MAX(taabb.size.x, 0.0001);
+ box.max_bounds[1] = taabb.position.y + MAX(taabb.size.y, 0.0001);
+ box.max_bounds[2] = taabb.position.z + MAX(taabb.size.z, 0.0001);
+ box.pad0 = box.pad1 = 0; //make valgrind not complain
+ box_array.push_back(box);
+
+ triangles.push_back(t);
+ slice_triangle_count.write[t.slice]++;
+ }
+ }
+
+ //also consider probe positions for bounds
+ for (int i = 0; i < probe_positions.size(); i++) {
+ Vector3 pp(probe_positions[i].position[0], probe_positions[i].position[1], probe_positions[i].position[2]);
+ bounds.expand_to(pp);
+ }
+ bounds.grow_by(0.1); //grow a bit to avoid numerical error
+
+ triangles.sort(); //sort by slice
+ seams.sort();
+
+ if (p_step_function) {
+ p_step_function(0.4, TTR("Optimizing acceleration structure"), p_bake_userdata, true);
+ }
+
+ //fill list of triangles in grid
+ LocalVector<TriangleSort> triangle_sort;
+ for (uint32_t i = 0; i < triangles.size(); i++) {
+ const Triangle &t = triangles[i];
+ Vector3 face[3] = {
+ Vector3(vertex_array[t.indices[0]].position[0], vertex_array[t.indices[0]].position[1], vertex_array[t.indices[0]].position[2]),
+ Vector3(vertex_array[t.indices[1]].position[0], vertex_array[t.indices[1]].position[1], vertex_array[t.indices[1]].position[2]),
+ Vector3(vertex_array[t.indices[2]].position[0], vertex_array[t.indices[2]].position[1], vertex_array[t.indices[2]].position[2])
+ };
+ _plot_triangle_into_triangle_index_list(grid_size, Vector3i(), bounds, face, i, triangle_sort, grid_size);
+ }
+ //sort it
+ triangle_sort.sort();
+
+ Vector<uint32_t> triangle_indices;
+ triangle_indices.resize(triangle_sort.size());
+ Vector<uint32_t> grid_indices;
+ grid_indices.resize(grid_size * grid_size * grid_size * 2);
+ zeromem(grid_indices.ptrw(), grid_indices.size() * sizeof(uint32_t));
+ Vector<bool> solid;
+ solid.resize(grid_size * grid_size * grid_size);
+ zeromem(solid.ptrw(), solid.size() * sizeof(bool));
+
+ {
+ uint32_t *tiw = triangle_indices.ptrw();
+ uint32_t last_cell = 0xFFFFFFFF;
+ uint32_t *giw = grid_indices.ptrw();
+ bool *solidw = solid.ptrw();
+ for (uint32_t i = 0; i < triangle_sort.size(); i++) {
+ uint32_t cell = triangle_sort[i].cell_index;
+ if (cell != last_cell) {
+ //cell changed, update pointer to indices
+ giw[cell * 2 + 1] = i;
+ last_cell = cell;
+ solidw[cell] = true;
+ }
+ tiw[i] = triangle_sort[i].triangle_index;
+ giw[cell * 2]++; //update counter
+ last_cell = cell;
+ }
+ }
+#if 0
+ for (int i = 0; i < grid_size; i++) {
+ for (int j = 0; j < grid_size; j++) {
+ for (int k = 0; k < grid_size; k++) {
+ uint32_t index = i * (grid_size * grid_size) + j * grid_size + k;
+ grid_indices.write[index * 2] = float(i) / grid_size * 255;
+ grid_indices.write[index * 2 + 1] = float(j) / grid_size * 255;
+ }
+ }
+ }
+#endif
+
+#if 0
+ for (int i = 0; i < grid_size; i++) {
+ Vector<uint8_t> grid_usage;
+ grid_usage.resize(grid_size * grid_size);
+ for (int j = 0; j < grid_usage.size(); j++) {
+ uint32_t ofs = i * grid_size * grid_size + j;
+ uint32_t count = grid_indices[ofs * 2];
+ grid_usage.write[j] = count > 0 ? 255 : 0;
+ }
+
+ Ref<Image> img;
+ img.instance();
+ img->create(grid_size, grid_size, false, Image::FORMAT_L8, grid_usage);
+ img->save_png("res://grid_layer_" + itos(1000 + i).substr(1, 3) + ".png");
+ }
+#endif
+ if (p_step_function) {
+ p_step_function(0.45, TTR("Generating Signed Distance Field"), p_bake_userdata, true);
+ }
+
+ //generate SDF for raytracing
+ Vector<uint32_t> euclidean_pos = Geometry::generate_edf(solid, Vector3i(grid_size, grid_size, grid_size), false);
+ Vector<uint32_t> euclidean_neg = Geometry::generate_edf(solid, Vector3i(grid_size, grid_size, grid_size), true);
+ Vector<int8_t> sdf8 = Geometry::generate_sdf8(euclidean_pos, euclidean_neg);
+
+ /*****************************/
+ /*** CREATE GPU STRUCTURES ***/
+ /*****************************/
+
+ lights.sort();
+
+ Vector<Vector2i> seam_buffer_vec;
+ seam_buffer_vec.resize(seams.size() * 2);
+ for (uint32_t i = 0; i < seams.size(); i++) {
+ seam_buffer_vec.write[i * 2 + 0] = seams[i].a;
+ seam_buffer_vec.write[i * 2 + 1] = seams[i].b;
+ }
+
+ { //buffers
+ Vector<uint8_t> vb = vertex_array.to_byte_array();
+ vertex_buffer = rd->storage_buffer_create(vb.size(), vb);
+
+ Vector<uint8_t> tb = triangles.to_byte_array();
+ triangle_buffer = rd->storage_buffer_create(tb.size(), tb);
+
+ Vector<uint8_t> bb = box_array.to_byte_array();
+ box_buffer = rd->storage_buffer_create(bb.size(), bb);
+
+ Vector<uint8_t> tib = triangle_indices.to_byte_array();
+ triangle_cell_indices_buffer = rd->storage_buffer_create(tib.size(), tib);
+
+ Vector<uint8_t> lb = lights.to_byte_array();
+ if (lb.size() == 0) {
+ lb.resize(sizeof(Light)); //even if no lights, the buffer must exist
+ }
+ lights_buffer = rd->storage_buffer_create(lb.size(), lb);
+
+ Vector<uint8_t> sb = seam_buffer_vec.to_byte_array();
+ if (sb.size() == 0) {
+ sb.resize(sizeof(Vector2i) * 2); //even if no seams, the buffer must exist
+ }
+ seams_buffer = rd->storage_buffer_create(sb.size(), sb);
+
+ Vector<uint8_t> pb = probe_positions.to_byte_array();
+ if (pb.size() == 0) {
+ pb.resize(sizeof(Probe));
+ }
+ probe_positions_buffer = rd->storage_buffer_create(pb.size(), pb);
+ }
+
+ { //grid
+
+ RD::TextureFormat tf;
+ tf.width = grid_size;
+ tf.height = grid_size;
+ tf.depth = grid_size;
+ tf.type = RD::TEXTURE_TYPE_3D;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+
+ Vector<Vector<uint8_t>> texdata;
+ texdata.resize(1);
+ //grid and indices
+ tf.format = RD::DATA_FORMAT_R32G32_UINT;
+ texdata.write[0] = grid_indices.to_byte_array();
+ grid_texture = rd->texture_create(tf, RD::TextureView(), texdata);
+ //sdf
+ tf.format = RD::DATA_FORMAT_R8_SNORM;
+ texdata.write[0] = sdf8.to_byte_array();
+ grid_texture_sdf = rd->texture_create(tf, RD::TextureView(), texdata);
+ }
+}
+
+void LightmapperRD::_raster_geometry(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, int grid_size, AABB bounds, float p_bias, Vector<int> slice_triangle_count, RID position_tex, RID unocclude_tex, RID normal_tex, RID raster_depth_buffer, RID rasterize_shader, RID raster_base_uniform) {
+ Vector<RID> framebuffers;
+
+ for (int i = 0; i < atlas_slices; i++) {
+ RID slice_pos_tex = rd->texture_create_shared_from_slice(RD::TextureView(), position_tex, i, 0);
+ RID slice_unoc_tex = rd->texture_create_shared_from_slice(RD::TextureView(), unocclude_tex, i, 0);
+ RID slice_norm_tex = rd->texture_create_shared_from_slice(RD::TextureView(), normal_tex, i, 0);
+ Vector<RID> fb;
+ fb.push_back(slice_pos_tex);
+ fb.push_back(slice_norm_tex);
+ fb.push_back(slice_unoc_tex);
+ fb.push_back(raster_depth_buffer);
+ framebuffers.push_back(rd->framebuffer_create(fb));
+ }
+
+ RD::PipelineDepthStencilState ds;
+ ds.enable_depth_test = true;
+ ds.enable_depth_write = true;
+ ds.depth_compare_operator = RD::COMPARE_OP_LESS; //so it does render same pixel twice
+
+ RID raster_pipeline = rd->render_pipeline_create(rasterize_shader, rd->framebuffer_get_format(framebuffers[0]), RD::INVALID_FORMAT_ID, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(3), 0);
+ RID raster_pipeline_wire;
+ {
+ RD::PipelineRasterizationState rw;
+ rw.wireframe = true;
+ raster_pipeline_wire = rd->render_pipeline_create(rasterize_shader, rd->framebuffer_get_format(framebuffers[0]), RD::INVALID_FORMAT_ID, RD::RENDER_PRIMITIVE_TRIANGLES, rw, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(3), 0);
+ }
+
+ uint32_t triangle_offset = 0;
+ Vector<Color> clear_colors;
+ clear_colors.push_back(Color(0, 0, 0, 0));
+ clear_colors.push_back(Color(0, 0, 0, 0));
+ clear_colors.push_back(Color(0, 0, 0, 0));
+
+ for (int i = 0; i < atlas_slices; i++) {
+ RasterPushConstant raster_push_constant;
+ raster_push_constant.atlas_size[0] = atlas_size.x;
+ raster_push_constant.atlas_size[1] = atlas_size.y;
+ raster_push_constant.base_triangle = triangle_offset;
+ raster_push_constant.to_cell_offset[0] = bounds.position.x;
+ raster_push_constant.to_cell_offset[1] = bounds.position.y;
+ raster_push_constant.to_cell_offset[2] = bounds.position.z;
+ raster_push_constant.bias = p_bias;
+ raster_push_constant.to_cell_size[0] = (1.0 / bounds.size.x) * float(grid_size);
+ raster_push_constant.to_cell_size[1] = (1.0 / bounds.size.y) * float(grid_size);
+ raster_push_constant.to_cell_size[2] = (1.0 / bounds.size.z) * float(grid_size);
+ raster_push_constant.grid_size[0] = grid_size;
+ raster_push_constant.grid_size[1] = grid_size;
+ raster_push_constant.grid_size[2] = grid_size;
+ raster_push_constant.uv_offset[0] = 0;
+ raster_push_constant.uv_offset[1] = 0;
+
+ RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i], RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
+ //draw opaque
+ rd->draw_list_bind_render_pipeline(draw_list, raster_pipeline);
+ rd->draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0);
+ rd->draw_list_set_push_constant(draw_list, &raster_push_constant, sizeof(RasterPushConstant));
+ rd->draw_list_draw(draw_list, false, 1, slice_triangle_count[i] * 3);
+ //draw wire
+ rd->draw_list_bind_render_pipeline(draw_list, raster_pipeline_wire);
+ rd->draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0);
+ rd->draw_list_set_push_constant(draw_list, &raster_push_constant, sizeof(RasterPushConstant));
+ rd->draw_list_draw(draw_list, false, 1, slice_triangle_count[i] * 3);
+
+ rd->draw_list_end();
+
+ triangle_offset += slice_triangle_count[i];
+ }
+}
+
+LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function, void *p_bake_userdata) {
+ if (p_step_function) {
+ p_step_function(0.0, TTR("Begin Bake"), p_bake_userdata, true);
+ }
+ bake_textures.clear();
+ int grid_size = 128;
+
+ /* STEP 1: Fetch material textures and compute the bounds */
+
+ AABB bounds;
+ Size2i atlas_size;
+ int atlas_slices;
+ Vector<Ref<Image>> albedo_images;
+ Vector<Ref<Image>> emission_images;
+
+ BakeError bake_error = _blit_meshes_into_atlas(p_max_texture_size, albedo_images, emission_images, bounds, atlas_size, atlas_slices, p_step_function, p_bake_userdata);
+ if (bake_error != BAKE_OK) {
+ return bake_error;
+ }
+
+#ifdef DEBUG_TEXTURES
+ for (int i = 0; i < atlas_slices; i++) {
+ albedo_images[i]->save_png("res://0_albedo_" + itos(i) + ".png");
+ emission_images[i]->save_png("res://0_emission_" + itos(i) + ".png");
+ }
+#endif
+
+ RenderingDevice *rd = RenderingDevice::get_singleton()->create_local_device();
+
+ RID albedo_array_tex;
+ RID emission_array_tex;
+ RID normal_tex;
+ RID position_tex;
+ RID unocclude_tex;
+ RID light_source_tex;
+ RID light_dest_tex;
+ RID light_accum_tex;
+ RID light_accum_tex2;
+ RID light_primary_dynamic_tex;
+ RID light_environment_tex;
+
+#define FREE_TEXTURES \
+ rd->free(albedo_array_tex); \
+ rd->free(emission_array_tex); \
+ rd->free(normal_tex); \
+ rd->free(position_tex); \
+ rd->free(unocclude_tex); \
+ rd->free(light_source_tex); \
+ rd->free(light_accum_tex2); \
+ rd->free(light_accum_tex); \
+ rd->free(light_primary_dynamic_tex); \
+ rd->free(light_environment_tex);
+
+ { // create all textures
+
+ Vector<Vector<uint8_t>> albedo_data;
+ Vector<Vector<uint8_t>> emission_data;
+ for (int i = 0; i < atlas_slices; i++) {
+ albedo_data.push_back(albedo_images[i]->get_data());
+ emission_data.push_back(emission_images[i]->get_data());
+ }
+
+ RD::TextureFormat tf;
+ tf.width = atlas_size.width;
+ tf.height = atlas_size.height;
+ tf.array_layers = atlas_slices;
+ tf.type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+ tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+
+ albedo_array_tex = rd->texture_create(tf, RD::TextureView(), albedo_data);
+
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+
+ emission_array_tex = rd->texture_create(tf, RD::TextureView(), emission_data);
+
+ //this will be rastered to
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ normal_tex = rd->texture_create(tf, RD::TextureView());
+ tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
+ position_tex = rd->texture_create(tf, RD::TextureView());
+ unocclude_tex = rd->texture_create(tf, RD::TextureView());
+
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+
+ light_source_tex = rd->texture_create(tf, RD::TextureView());
+ rd->texture_clear(light_source_tex, Color(0, 0, 0, 0), 0, 1, 0, atlas_slices);
+ light_primary_dynamic_tex = rd->texture_create(tf, RD::TextureView());
+ rd->texture_clear(light_primary_dynamic_tex, Color(0, 0, 0, 0), 0, 1, 0, atlas_slices);
+
+ if (p_bake_sh) {
+ tf.array_layers *= 4;
+ }
+ light_accum_tex = rd->texture_create(tf, RD::TextureView());
+ rd->texture_clear(light_accum_tex, Color(0, 0, 0, 0), 0, 1, 0, tf.array_layers);
+ light_dest_tex = rd->texture_create(tf, RD::TextureView());
+ rd->texture_clear(light_dest_tex, Color(0, 0, 0, 0), 0, 1, 0, tf.array_layers);
+ light_accum_tex2 = light_dest_tex;
+
+ //env
+ {
+ Ref<Image> panorama_tex;
+ if (p_environment_panorama.is_valid()) {
+ panorama_tex = p_environment_panorama;
+ panorama_tex->convert(Image::FORMAT_RGBAF);
+ } else {
+ panorama_tex.instance();
+ panorama_tex->create(8, 8, false, Image::FORMAT_RGBAF);
+ for (int i = 0; i < 8; i++) {
+ for (int j = 0; j < 8; j++) {
+ panorama_tex->set_pixel(i, j, Color(0, 0, 0, 1));
+ }
+ }
+ }
+
+ RD::TextureFormat tfp;
+ tfp.width = panorama_tex->get_width();
+ tfp.height = panorama_tex->get_height();
+ tfp.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+ tfp.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
+
+ Vector<Vector<uint8_t>> tdata;
+ tdata.push_back(panorama_tex->get_data());
+ light_environment_tex = rd->texture_create(tfp, RD::TextureView(), tdata);
+
+#ifdef DEBUG_TEXTURES
+ panorama_tex->convert(Image::FORMAT_RGB8);
+ panorama_tex->save_png("res://0_panorama.png");
+#endif
+ }
+ }
+
+ /* STEP 2: create the acceleration structure for the GPU*/
+
+ Vector<int> slice_triangle_count;
+ RID vertex_buffer;
+ RID triangle_buffer;
+ RID box_buffer;
+ RID lights_buffer;
+ RID triangle_cell_indices_buffer;
+ RID grid_texture;
+ RID grid_texture_sdf;
+ RID seams_buffer;
+ RID probe_positions_buffer;
+
+ Vector<int> slice_seam_count;
+
+#define FREE_BUFFERS \
+ rd->free(vertex_buffer); \
+ rd->free(triangle_buffer); \
+ rd->free(box_buffer); \
+ rd->free(lights_buffer); \
+ rd->free(triangle_cell_indices_buffer); \
+ rd->free(grid_texture); \
+ rd->free(grid_texture_sdf); \
+ rd->free(seams_buffer); \
+ rd->free(probe_positions_buffer);
+
+ _create_acceleration_structures(rd, atlas_size, atlas_slices, bounds, grid_size, probe_positions, p_generate_probes, slice_triangle_count, slice_seam_count, vertex_buffer, triangle_buffer, box_buffer, lights_buffer, triangle_cell_indices_buffer, probe_positions_buffer, grid_texture, grid_texture_sdf, seams_buffer, p_step_function, p_bake_userdata);
+
+ if (p_step_function) {
+ p_step_function(0.47, TTR("Preparing shaders"), p_bake_userdata, true);
+ }
+
+ //shaders
+ Ref<RDShaderFile> raster_shader;
+ raster_shader.instance();
+ Error err = raster_shader->parse_versions_from_text(lm_raster_shader_glsl);
+ if (err != OK) {
+ raster_shader->print_errors("raster_shader");
+
+ FREE_TEXTURES
+ FREE_BUFFERS
+
+ memdelete(rd);
+ }
+ ERR_FAIL_COND_V(err != OK, BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES);
+
+ RID rasterize_shader = rd->shader_create_from_bytecode(raster_shader->get_bytecode());
+
+ ERR_FAIL_COND_V(rasterize_shader.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //this is a bug check, though, should not happen
+
+ RID sampler;
+ {
+ RD::SamplerState s;
+ s.mag_filter = RD::SAMPLER_FILTER_LINEAR;
+ s.min_filter = RD::SAMPLER_FILTER_LINEAR;
+ s.max_lod = 0;
+
+ sampler = rd->sampler_create(s);
+ }
+
+ Vector<RD::Uniform> base_uniforms;
+ {
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 1;
+ u.ids.push_back(vertex_buffer);
+ base_uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 2;
+ u.ids.push_back(triangle_buffer);
+ base_uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 3;
+ u.ids.push_back(box_buffer);
+ base_uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 4;
+ u.ids.push_back(triangle_cell_indices_buffer);
+ base_uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 5;
+ u.ids.push_back(lights_buffer);
+ base_uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 6;
+ u.ids.push_back(seams_buffer);
+ base_uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 7;
+ u.ids.push_back(probe_positions_buffer);
+ base_uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 8;
+ u.ids.push_back(grid_texture);
+ base_uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 9;
+ u.ids.push_back(grid_texture_sdf);
+ base_uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 10;
+ u.ids.push_back(albedo_array_tex);
+ base_uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 11;
+ u.ids.push_back(emission_array_tex);
+ base_uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 12;
+ u.ids.push_back(sampler);
+ base_uniforms.push_back(u);
+ }
+ }
+
+ RID raster_base_uniform = rd->uniform_set_create(base_uniforms, rasterize_shader, 0);
+ RID raster_depth_buffer;
+ {
+ RD::TextureFormat tf;
+ tf.width = atlas_size.width;
+ tf.height = atlas_size.height;
+ tf.depth = 1;
+ tf.type = RD::TEXTURE_TYPE_2D;
+ tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+ tf.format = RD::DATA_FORMAT_D32_SFLOAT;
+
+ raster_depth_buffer = rd->texture_create(tf, RD::TextureView());
+ }
+
+ rd->submit();
+ rd->sync();
+
+ /* STEP 3: Raster the geometry to UV2 coords in the atlas textures GPU*/
+
+ _raster_geometry(rd, atlas_size, atlas_slices, grid_size, bounds, p_bias, slice_triangle_count, position_tex, unocclude_tex, normal_tex, raster_depth_buffer, rasterize_shader, raster_base_uniform);
+
+#ifdef DEBUG_TEXTURES
+
+ for (int i = 0; i < atlas_slices; i++) {
+ Vector<uint8_t> s = rd->texture_get_data(position_tex, i);
+ Ref<Image> img;
+ img.instance();
+ img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAF, s);
+ img->convert(Image::FORMAT_RGBA8);
+ img->save_png("res://1_position_" + itos(i) + ".png");
+
+ s = rd->texture_get_data(normal_tex, i);
+ img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
+ img->convert(Image::FORMAT_RGBA8);
+ img->save_png("res://1_normal_" + itos(i) + ".png");
+ }
+#endif
+
+#define FREE_RASTER_RESOURCES \
+ rd->free(rasterize_shader); \
+ rd->free(sampler); \
+ rd->free(raster_depth_buffer);
+
+ /* Plot direct light */
+
+ Ref<RDShaderFile> compute_shader;
+ compute_shader.instance();
+ err = compute_shader->parse_versions_from_text(lm_compute_shader_glsl, p_bake_sh ? "\n#define USE_SH_LIGHTMAPS\n" : "");
+ if (err != OK) {
+ FREE_TEXTURES
+ FREE_BUFFERS
+ FREE_RASTER_RESOURCES
+ memdelete(rd);
+ compute_shader->print_errors("compute_shader");
+ }
+ ERR_FAIL_COND_V(err != OK, BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES);
+
+ //unoccluder
+ RID compute_shader_unocclude = rd->shader_create_from_bytecode(compute_shader->get_bytecode("unocclude"));
+ ERR_FAIL_COND_V(compute_shader_unocclude.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); // internal check, should not happen
+ RID compute_shader_unocclude_pipeline = rd->compute_pipeline_create(compute_shader_unocclude);
+
+ //direct light
+ RID compute_shader_primary = rd->shader_create_from_bytecode(compute_shader->get_bytecode("primary"));
+ ERR_FAIL_COND_V(compute_shader_primary.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); // internal check, should not happen
+ RID compute_shader_primary_pipeline = rd->compute_pipeline_create(compute_shader_primary);
+
+ //indirect light
+ RID compute_shader_secondary = rd->shader_create_from_bytecode(compute_shader->get_bytecode("secondary"));
+ ERR_FAIL_COND_V(compute_shader_secondary.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen
+ RID compute_shader_secondary_pipeline = rd->compute_pipeline_create(compute_shader_secondary);
+
+ //dilate
+ RID compute_shader_dilate = rd->shader_create_from_bytecode(compute_shader->get_bytecode("dilate"));
+ ERR_FAIL_COND_V(compute_shader_dilate.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen
+ RID compute_shader_dilate_pipeline = rd->compute_pipeline_create(compute_shader_dilate);
+
+ //dilate
+ RID compute_shader_light_probes = rd->shader_create_from_bytecode(compute_shader->get_bytecode("light_probes"));
+ ERR_FAIL_COND_V(compute_shader_light_probes.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES); //internal check, should not happen
+ RID compute_shader_light_probes_pipeline = rd->compute_pipeline_create(compute_shader_light_probes);
+
+ RID compute_base_uniform_set = rd->uniform_set_create(base_uniforms, compute_shader_primary, 0);
+
+#define FREE_COMPUTE_RESOURCES \
+ rd->free(compute_shader_unocclude); \
+ rd->free(compute_shader_primary); \
+ rd->free(compute_shader_secondary); \
+ rd->free(compute_shader_dilate); \
+ rd->free(compute_shader_light_probes);
+
+ PushConstant push_constant;
+ {
+ //set defaults
+ push_constant.atlas_size[0] = atlas_size.width;
+ push_constant.atlas_size[1] = atlas_size.height;
+ push_constant.world_size[0] = bounds.size.x;
+ push_constant.world_size[1] = bounds.size.y;
+ push_constant.world_size[2] = bounds.size.z;
+ push_constant.to_cell_offset[0] = bounds.position.x;
+ push_constant.to_cell_offset[1] = bounds.position.y;
+ push_constant.to_cell_offset[2] = bounds.position.z;
+ push_constant.bias = p_bias;
+ push_constant.to_cell_size[0] = (1.0 / bounds.size.x) * float(grid_size);
+ push_constant.to_cell_size[1] = (1.0 / bounds.size.y) * float(grid_size);
+ push_constant.to_cell_size[2] = (1.0 / bounds.size.z) * float(grid_size);
+ push_constant.light_count = lights.size();
+ push_constant.grid_size = grid_size;
+ push_constant.atlas_slice = 0;
+ push_constant.region_ofs[0] = 0;
+ push_constant.region_ofs[1] = 0;
+ push_constant.environment_xform[0] = p_environment_transform.elements[0][0];
+ push_constant.environment_xform[1] = p_environment_transform.elements[1][0];
+ push_constant.environment_xform[2] = p_environment_transform.elements[2][0];
+ push_constant.environment_xform[3] = 0;
+ push_constant.environment_xform[4] = p_environment_transform.elements[0][1];
+ push_constant.environment_xform[5] = p_environment_transform.elements[1][1];
+ push_constant.environment_xform[6] = p_environment_transform.elements[2][1];
+ push_constant.environment_xform[7] = 0;
+ push_constant.environment_xform[8] = p_environment_transform.elements[0][2];
+ push_constant.environment_xform[9] = p_environment_transform.elements[1][2];
+ push_constant.environment_xform[10] = p_environment_transform.elements[2][2];
+ push_constant.environment_xform[11] = 0;
+ }
+
+ Vector3i group_size((atlas_size.x - 1) / 8 + 1, (atlas_size.y - 1) / 8 + 1, 1);
+ rd->submit();
+ rd->sync();
+
+ if (p_step_function) {
+ p_step_function(0.49, TTR("Un-occluding geometry"), p_bake_userdata, true);
+ }
+
+ /* UNOCCLUDE */
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 0;
+ u.ids.push_back(position_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 1;
+ u.ids.push_back(unocclude_tex); //will be unused
+ uniforms.push_back(u);
+ }
+ }
+
+ RID unocclude_uniform_set = rd->uniform_set_create(uniforms, compute_shader_unocclude, 1);
+
+ RD::ComputeListID compute_list = rd->compute_list_begin();
+ rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_unocclude_pipeline);
+ rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0);
+ rd->compute_list_bind_uniform_set(compute_list, unocclude_uniform_set, 1);
+
+ for (int i = 0; i < atlas_slices; i++) {
+ push_constant.atlas_slice = i;
+ rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
+ rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z);
+ //no barrier, let them run all together
+ }
+ rd->compute_list_end(); //done
+ }
+
+ if (p_step_function) {
+ p_step_function(0.5, TTR("Plot direct lighting"), p_bake_userdata, true);
+ }
+
+ /* PRIMARY (direct) LIGHT PASS */
+ {
+ Vector<RD::Uniform> uniforms;
+ {
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 0;
+ u.ids.push_back(light_source_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1;
+ u.ids.push_back(light_dest_tex); //will be unused
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 2;
+ u.ids.push_back(position_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 3;
+ u.ids.push_back(normal_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 4;
+ u.ids.push_back(light_accum_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 5;
+ u.ids.push_back(light_primary_dynamic_tex);
+ uniforms.push_back(u);
+ }
+ }
+
+ RID light_uniform_set = rd->uniform_set_create(uniforms, compute_shader_primary, 1);
+
+ RD::ComputeListID compute_list = rd->compute_list_begin();
+ rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_primary_pipeline);
+ rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0);
+ rd->compute_list_bind_uniform_set(compute_list, light_uniform_set, 1);
+
+ for (int i = 0; i < atlas_slices; i++) {
+ push_constant.atlas_slice = i;
+ rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
+ rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z);
+ //no barrier, let them run all together
+ }
+ rd->compute_list_end(); //done
+ }
+
+#ifdef DEBUG_TEXTURES
+
+ for (int i = 0; i < atlas_slices; i++) {
+ Vector<uint8_t> s = rd->texture_get_data(light_source_tex, i);
+ Ref<Image> img;
+ img.instance();
+ img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
+ img->convert(Image::FORMAT_RGBA8);
+ img->save_png("res://2_light_primary_" + itos(i) + ".png");
+ }
+#endif
+
+ /* SECONDARY (indirect) LIGHT PASS(ES) */
+ if (p_step_function) {
+ p_step_function(0.6, TTR("Integrate indirect lighting"), p_bake_userdata, true);
+ }
+
+ if (p_bounces > 0) {
+ Vector<RD::Uniform> uniforms;
+ {
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 0;
+ u.ids.push_back(light_dest_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1;
+ u.ids.push_back(light_source_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 2;
+ u.ids.push_back(position_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 3;
+ u.ids.push_back(normal_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 4;
+ u.ids.push_back(light_accum_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 5;
+ u.ids.push_back(unocclude_tex); //reuse unocclude tex
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 6;
+ u.ids.push_back(light_environment_tex); //reuse unocclude tex
+ uniforms.push_back(u);
+ }
+ }
+
+ RID secondary_uniform_set[2];
+ secondary_uniform_set[0] = rd->uniform_set_create(uniforms, compute_shader_secondary, 1);
+ uniforms.write[0].ids.write[0] = light_source_tex;
+ uniforms.write[1].ids.write[0] = light_dest_tex;
+ secondary_uniform_set[1] = rd->uniform_set_create(uniforms, compute_shader_secondary, 1);
+
+ switch (p_quality) {
+ case BAKE_QUALITY_LOW: {
+ push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/low_quality_ray_count");
+ } break;
+ case BAKE_QUALITY_MEDIUM: {
+ push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/medium_quality_ray_count");
+ } break;
+ case BAKE_QUALITY_HIGH: {
+ push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/high_quality_ray_count");
+ } break;
+ case BAKE_QUALITY_ULTRA: {
+ push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/ultra_quality_ray_count");
+ } break;
+ }
+
+ push_constant.ray_count = CLAMP(push_constant.ray_count, 16, 8192);
+
+ int max_region_size = nearest_power_of_2_templated(int(GLOBAL_GET("rendering/gpu_lightmapper/performance/region_size")));
+ int max_rays = GLOBAL_GET("rendering/gpu_lightmapper/performance/max_rays_per_pass");
+
+ int x_regions = (atlas_size.width - 1) / max_region_size + 1;
+ int y_regions = (atlas_size.height - 1) / max_region_size + 1;
+ int ray_iterations = (push_constant.ray_count - 1) / max_rays + 1;
+
+ rd->submit();
+ rd->sync();
+
+ for (int b = 0; b < p_bounces; b++) {
+ int count = 0;
+ if (b > 0) {
+ SWAP(light_source_tex, light_dest_tex);
+ SWAP(secondary_uniform_set[0], secondary_uniform_set[1]);
+ }
+
+ for (int s = 0; s < atlas_slices; s++) {
+ push_constant.atlas_slice = s;
+
+ for (int i = 0; i < x_regions; i++) {
+ for (int j = 0; j < y_regions; j++) {
+ int x = i * max_region_size;
+ int y = j * max_region_size;
+ int w = MIN((i + 1) * max_region_size, atlas_size.width) - x;
+ int h = MIN((j + 1) * max_region_size, atlas_size.height) - y;
+
+ push_constant.region_ofs[0] = x;
+ push_constant.region_ofs[1] = y;
+
+ group_size = Vector3i((w - 1) / 8 + 1, (h - 1) / 8 + 1, 1);
+
+ for (int k = 0; k < ray_iterations; k++) {
+ RD::ComputeListID compute_list = rd->compute_list_begin();
+ rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_secondary_pipeline);
+ rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0);
+ rd->compute_list_bind_uniform_set(compute_list, secondary_uniform_set[0], 1);
+
+ push_constant.ray_from = k * max_rays;
+ push_constant.ray_to = MIN((k + 1) * max_rays, int32_t(push_constant.ray_count));
+ rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
+ rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z);
+
+ rd->compute_list_end(); //done
+ rd->submit();
+ rd->sync();
+
+ count++;
+ if (p_step_function) {
+ int total = (atlas_slices * x_regions * y_regions * ray_iterations);
+ int percent = count * 100 / total;
+ float p = float(count) / total * 0.1;
+ p_step_function(0.6 + p, vformat(TTR("Bounce %d/%d: Integrate indirect lighting %d%%"), b + 1, p_bounces, percent), p_bake_userdata, false);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* LIGHPROBES */
+
+ RID light_probe_buffer;
+
+ if (probe_positions.size()) {
+ light_probe_buffer = rd->storage_buffer_create(sizeof(float) * 4 * 9 * probe_positions.size());
+
+ if (p_step_function) {
+ p_step_function(0.7, TTR("Baking lightprobes"), p_bake_userdata, true);
+ }
+
+ Vector<RD::Uniform> uniforms;
+ {
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(light_probe_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1;
+ u.ids.push_back(light_dest_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 2;
+ u.ids.push_back(light_primary_dynamic_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 3;
+ u.ids.push_back(light_environment_tex);
+ uniforms.push_back(u);
+ }
+ }
+ RID light_probe_uniform_set = rd->uniform_set_create(uniforms, compute_shader_light_probes, 1);
+
+ switch (p_quality) {
+ case BAKE_QUALITY_LOW: {
+ push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/low_quality_probe_ray_count");
+ } break;
+ case BAKE_QUALITY_MEDIUM: {
+ push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/medium_quality_probe_ray_count");
+ } break;
+ case BAKE_QUALITY_HIGH: {
+ push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/high_quality_probe_ray_count");
+ } break;
+ case BAKE_QUALITY_ULTRA: {
+ push_constant.ray_count = GLOBAL_GET("rendering/gpu_lightmapper/quality/ultra_quality_probe_ray_count");
+ } break;
+ }
+
+ push_constant.atlas_size[0] = probe_positions.size();
+ push_constant.ray_count = CLAMP(push_constant.ray_count, 16, 8192);
+
+ int max_rays = GLOBAL_GET("rendering/gpu_lightmapper/performance/max_rays_per_probe_pass");
+ int ray_iterations = (push_constant.ray_count - 1) / max_rays + 1;
+
+ for (int i = 0; i < ray_iterations; i++) {
+ RD::ComputeListID compute_list = rd->compute_list_begin();
+ rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_light_probes_pipeline);
+ rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0);
+ rd->compute_list_bind_uniform_set(compute_list, light_probe_uniform_set, 1);
+
+ push_constant.ray_from = i * max_rays;
+ push_constant.ray_to = MIN((i + 1) * max_rays, int32_t(push_constant.ray_count));
+ rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
+ rd->compute_list_dispatch(compute_list, (probe_positions.size() - 1) / 64 + 1, 1, 1);
+
+ rd->compute_list_end(); //done
+ rd->submit();
+ rd->sync();
+
+ if (p_step_function) {
+ int percent = i * 100 / ray_iterations;
+ float p = float(i) / ray_iterations * 0.1;
+ p_step_function(0.7 + p, vformat(TTR("Integrating light probes %d%%"), percent), p_bake_userdata, false);
+ }
+ }
+
+ push_constant.atlas_size[0] = atlas_size.x; //restore
+ }
+
+#if 0
+ for (int i = 0; i < probe_positions.size(); i++) {
+ Ref<Image> img;
+ img.instance();
+ img->create(6, 4, false, Image::FORMAT_RGB8);
+ for (int j = 0; j < 6; j++) {
+ Vector<uint8_t> s = rd->texture_get_data(lightprobe_tex, i * 6 + j);
+ Ref<Image> img2;
+ img2.instance();
+ img2->create(2, 2, false, Image::FORMAT_RGBAF, s);
+ img2->convert(Image::FORMAT_RGB8);
+ img->blit_rect(img2, Rect2(0, 0, 2, 2), Point2((j % 3) * 2, (j / 3) * 2));
+ }
+ img->save_png("res://3_light_probe_" + itos(i) + ".png");
+ }
+#endif
+
+ /* DENOISE */
+
+ if (p_use_denoiser) {
+ if (p_step_function) {
+ p_step_function(0.8, TTR("Denoising"), p_bake_userdata, true);
+ }
+
+ Ref<LightmapDenoiser> denoiser = LightmapDenoiser::create();
+ if (denoiser.is_valid()) {
+ for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
+ Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i);
+ Ref<Image> img;
+ img.instance();
+ img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
+
+ Ref<Image> denoised = denoiser->denoise_image(img);
+ if (denoised != img) {
+ denoised->convert(Image::FORMAT_RGBAH);
+ Vector<uint8_t> ds = denoised->get_data();
+ denoised.unref(); //avoid copy on write
+ { //restore alpha
+ uint32_t count = s.size() / 2; //uint16s
+ const uint16_t *src = (const uint16_t *)s.ptr();
+ uint16_t *dst = (uint16_t *)ds.ptrw();
+ for (uint32_t j = 0; j < count; j += 4) {
+ dst[j + 3] = src[j + 3];
+ }
+ }
+ rd->texture_update(light_accum_tex, i, ds, true);
+ }
+ }
+ }
+ }
+
+#ifdef DEBUG_TEXTURES
+
+ for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
+ Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i);
+ Ref<Image> img;
+ img.instance();
+ img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
+ img->convert(Image::FORMAT_RGBA8);
+ img->save_png("res://4_light_secondary_" + itos(i) + ".png");
+ }
+#endif
+
+ /* DILATE LIGHTMAP */
+ {
+ SWAP(light_accum_tex, light_accum_tex2);
+
+ Vector<RD::Uniform> uniforms;
+ {
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 0;
+ u.ids.push_back(light_accum_tex);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1;
+ u.ids.push_back(light_accum_tex2);
+ uniforms.push_back(u);
+ }
+ }
+
+ RID dilate_uniform_set = rd->uniform_set_create(uniforms, compute_shader_dilate, 1);
+
+ RD::ComputeListID compute_list = rd->compute_list_begin();
+ rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_dilate_pipeline);
+ rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0);
+ rd->compute_list_bind_uniform_set(compute_list, dilate_uniform_set, 1);
+ push_constant.region_ofs[0] = 0;
+ push_constant.region_ofs[1] = 0;
+ group_size = Vector3i((atlas_size.x - 1) / 8 + 1, (atlas_size.y - 1) / 8 + 1, 1); //restore group size
+
+ for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
+ push_constant.atlas_slice = i;
+ rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
+ rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z);
+ //no barrier, let them run all together
+ }
+ rd->compute_list_end();
+ }
+
+#ifdef DEBUG_TEXTURES
+
+ for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
+ Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i);
+ Ref<Image> img;
+ img.instance();
+ img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
+ img->convert(Image::FORMAT_RGBA8);
+ img->save_png("res://5_dilated_" + itos(i) + ".png");
+ }
+#endif
+
+ /* BLEND SEAMS */
+ //shaders
+ Ref<RDShaderFile> blendseams_shader;
+ blendseams_shader.instance();
+ err = blendseams_shader->parse_versions_from_text(lm_blendseams_shader_glsl);
+ if (err != OK) {
+ FREE_TEXTURES
+ FREE_BUFFERS
+ FREE_RASTER_RESOURCES
+ FREE_COMPUTE_RESOURCES
+ memdelete(rd);
+ blendseams_shader->print_errors("blendseams_shader");
+ }
+ ERR_FAIL_COND_V(err != OK, BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES);
+
+ RID blendseams_line_raster_shader = rd->shader_create_from_bytecode(blendseams_shader->get_bytecode("lines"));
+
+ ERR_FAIL_COND_V(blendseams_line_raster_shader.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES);
+
+ RID blendseams_triangle_raster_shader = rd->shader_create_from_bytecode(blendseams_shader->get_bytecode("triangles"));
+
+ ERR_FAIL_COND_V(blendseams_triangle_raster_shader.is_null(), BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES);
+
+#define FREE_BLENDSEAMS_RESOURCES \
+ rd->free(blendseams_line_raster_shader); \
+ rd->free(blendseams_triangle_raster_shader);
+
+ {
+ //pre copy
+ for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
+ rd->texture_copy(light_accum_tex, light_accum_tex2, Vector3(), Vector3(), Vector3(atlas_size.width, atlas_size.height, 1), 0, 0, i, i, true);
+ }
+
+ Vector<RID> framebuffers;
+ for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
+ RID slice_tex = rd->texture_create_shared_from_slice(RD::TextureView(), light_accum_tex, i, 0);
+ Vector<RID> fb;
+ fb.push_back(slice_tex);
+ fb.push_back(raster_depth_buffer);
+ framebuffers.push_back(rd->framebuffer_create(fb));
+ }
+
+ Vector<RD::Uniform> uniforms;
+ {
+ {
+ RD::Uniform u;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 0;
+ u.ids.push_back(light_accum_tex2);
+ uniforms.push_back(u);
+ }
+ }
+
+ RID blendseams_raster_uniform = rd->uniform_set_create(uniforms, blendseams_line_raster_shader, 1);
+
+ bool debug = false;
+ RD::PipelineColorBlendState bs = RD::PipelineColorBlendState::create_blend(1);
+ bs.attachments.write[0].src_alpha_blend_factor = RD::BLEND_FACTOR_ZERO;
+ bs.attachments.write[0].dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
+
+ RD::PipelineDepthStencilState ds;
+ ds.enable_depth_test = true;
+ ds.enable_depth_write = true;
+ ds.depth_compare_operator = RD::COMPARE_OP_LESS; //so it does not render same pixel twice, this avoids wrong blending
+
+ RID blendseams_line_raster_pipeline = rd->render_pipeline_create(blendseams_line_raster_shader, rd->framebuffer_get_format(framebuffers[0]), RD::INVALID_FORMAT_ID, RD::RENDER_PRIMITIVE_LINES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), ds, bs, 0);
+ RID blendseams_triangle_raster_pipeline = rd->render_pipeline_create(blendseams_triangle_raster_shader, rd->framebuffer_get_format(framebuffers[0]), RD::INVALID_FORMAT_ID, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), ds, bs, 0);
+
+ uint32_t seam_offset = 0;
+ uint32_t triangle_offset = 0;
+
+ Vector<Color> clear_colors;
+ clear_colors.push_back(Color(0, 0, 0, 1));
+ for (int i = 0; i < atlas_slices; i++) {
+ int subslices = (p_bake_sh ? 4 : 1);
+ for (int k = 0; k < subslices; k++) {
+ RasterSeamsPushConstant seams_push_constant;
+ seams_push_constant.slice = uint32_t(i * subslices + k);
+ seams_push_constant.debug = debug;
+
+ RD::DrawListID draw_list = rd->draw_list_begin(framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
+
+ rd->draw_list_bind_uniform_set(draw_list, raster_base_uniform, 0);
+ rd->draw_list_bind_uniform_set(draw_list, blendseams_raster_uniform, 1);
+
+ const int uv_offset_count = 9;
+ static const Vector3 uv_offsets[uv_offset_count] = {
+ Vector3(0, 0, 0.5), //using zbuffer, so go inwards-outwards
+ Vector3(0, 1, 0.2),
+ Vector3(0, -1, 0.2),
+ Vector3(1, 0, 0.2),
+ Vector3(-1, 0, 0.2),
+ Vector3(-1, -1, 0.1),
+ Vector3(1, -1, 0.1),
+ Vector3(1, 1, 0.1),
+ Vector3(-1, 1, 0.1),
+ };
+
+ /* step 1 use lines to blend the edges */
+ {
+ seams_push_constant.base_index = seam_offset;
+ rd->draw_list_bind_render_pipeline(draw_list, blendseams_line_raster_pipeline);
+ seams_push_constant.uv_offset[0] = uv_offsets[0].x / float(atlas_size.width);
+ seams_push_constant.uv_offset[1] = uv_offsets[0].y / float(atlas_size.height);
+ seams_push_constant.blend = uv_offsets[0].z;
+
+ rd->draw_list_set_push_constant(draw_list, &seams_push_constant, sizeof(RasterSeamsPushConstant));
+ rd->draw_list_draw(draw_list, false, 1, slice_seam_count[i] * 4);
+ }
+
+ /* step 2 use triangles to mask the interior */
+
+ {
+ seams_push_constant.base_index = triangle_offset;
+ rd->draw_list_bind_render_pipeline(draw_list, blendseams_triangle_raster_pipeline);
+ seams_push_constant.blend = 0; //do not draw them, just fill the z-buffer so its used as a mask
+
+ rd->draw_list_set_push_constant(draw_list, &seams_push_constant, sizeof(RasterSeamsPushConstant));
+ rd->draw_list_draw(draw_list, false, 1, slice_triangle_count[i] * 3);
+ }
+ /* step 3 blend around the triangle */
+
+ rd->draw_list_bind_render_pipeline(draw_list, blendseams_line_raster_pipeline);
+
+ for (int j = 1; j < uv_offset_count; j++) {
+ seams_push_constant.base_index = seam_offset;
+ seams_push_constant.uv_offset[0] = uv_offsets[j].x / float(atlas_size.width);
+ seams_push_constant.uv_offset[1] = uv_offsets[j].y / float(atlas_size.height);
+ seams_push_constant.blend = uv_offsets[0].z;
+
+ rd->draw_list_set_push_constant(draw_list, &seams_push_constant, sizeof(RasterSeamsPushConstant));
+ rd->draw_list_draw(draw_list, false, 1, slice_seam_count[i] * 4);
+ }
+ rd->draw_list_end();
+ }
+ seam_offset += slice_seam_count[i];
+ triangle_offset += slice_triangle_count[i];
+ }
+ }
+
+#ifdef DEBUG_TEXTURES
+
+ for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
+ Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i);
+ Ref<Image> img;
+ img.instance();
+ img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
+ img->convert(Image::FORMAT_RGBA8);
+ img->save_png("res://5_blendseams" + itos(i) + ".png");
+ }
+#endif
+ if (p_step_function) {
+ p_step_function(0.9, TTR("Retrieving textures"), p_bake_userdata, true);
+ }
+
+ for (int i = 0; i < atlas_slices * (p_bake_sh ? 4 : 1); i++) {
+ Vector<uint8_t> s = rd->texture_get_data(light_accum_tex, i);
+ Ref<Image> img;
+ img.instance();
+ img->create(atlas_size.width, atlas_size.height, false, Image::FORMAT_RGBAH, s);
+ img->convert(Image::FORMAT_RGBH); //remove alpha
+ bake_textures.push_back(img);
+ }
+
+ if (probe_positions.size() > 0) {
+ probe_values.resize(probe_positions.size() * 9);
+ Vector<uint8_t> probe_data = rd->buffer_get_data(light_probe_buffer);
+ copymem(probe_values.ptrw(), probe_data.ptr(), probe_data.size());
+ rd->free(light_probe_buffer);
+
+#ifdef DEBUG_TEXTURES
+ {
+ Ref<Image> img2;
+ img2.instance();
+ img2->create(probe_values.size(), 1, false, Image::FORMAT_RGBAF, probe_data);
+ img2->save_png("res://6_lightprobes.png");
+ }
+#endif
+ }
+
+ FREE_TEXTURES
+ FREE_BUFFERS
+ FREE_RASTER_RESOURCES
+ FREE_COMPUTE_RESOURCES
+ FREE_BLENDSEAMS_RESOURCES
+
+ memdelete(rd);
+
+ return BAKE_OK;
+}
+
+int LightmapperRD::get_bake_texture_count() const {
+ return bake_textures.size();
+}
+
+Ref<Image> LightmapperRD::get_bake_texture(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, bake_textures.size(), Ref<Image>());
+ return bake_textures[p_index];
+}
+
+int LightmapperRD::get_bake_mesh_count() const {
+ return mesh_instances.size();
+}
+
+Variant LightmapperRD::get_bake_mesh_userdata(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, mesh_instances.size(), Variant());
+ return mesh_instances[p_index].data.userdata;
+}
+
+Rect2 LightmapperRD::get_bake_mesh_uv_scale(int p_index) const {
+ ERR_FAIL_COND_V(bake_textures.size() == 0, Rect2());
+ Rect2 uv_ofs;
+ Vector2 atlas_size = Vector2(bake_textures[0]->get_width(), bake_textures[0]->get_height());
+ uv_ofs.position = Vector2(mesh_instances[p_index].offset) / atlas_size;
+ uv_ofs.size = Vector2(mesh_instances[p_index].data.albedo_on_uv2->get_width(), mesh_instances[p_index].data.albedo_on_uv2->get_height()) / atlas_size;
+ return uv_ofs;
+}
+
+int LightmapperRD::get_bake_mesh_texture_slice(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, mesh_instances.size(), Variant());
+ return mesh_instances[p_index].slice;
+}
+
+int LightmapperRD::get_bake_probe_count() const {
+ return probe_positions.size();
+}
+
+Vector3 LightmapperRD::get_bake_probe_point(int p_probe) const {
+ ERR_FAIL_INDEX_V(p_probe, probe_positions.size(), Variant());
+ return Vector3(probe_positions[p_probe].position[0], probe_positions[p_probe].position[1], probe_positions[p_probe].position[2]);
+}
+
+Vector<Color> LightmapperRD::get_bake_probe_sh(int p_probe) const {
+ ERR_FAIL_INDEX_V(p_probe, probe_positions.size(), Vector<Color>());
+ Vector<Color> ret;
+ ret.resize(9);
+ copymem(ret.ptrw(), &probe_values[p_probe * 9], sizeof(Color) * 9);
+ return ret;
+}
+
+LightmapperRD::LightmapperRD() {
+}
diff --git a/modules/lightmapper_rd/lightmapper_rd.h b/modules/lightmapper_rd/lightmapper_rd.h
new file mode 100644
index 0000000000..6cb3ecbe9e
--- /dev/null
+++ b/modules/lightmapper_rd/lightmapper_rd.h
@@ -0,0 +1,258 @@
+/*************************************************************************/
+/* lightmapper_rd.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef LIGHTMAPPER_RD_H
+#define LIGHTMAPPER_RD_H
+
+#include "core/local_vector.h"
+#include "scene/3d/lightmapper.h"
+#include "scene/resources/mesh.h"
+#include "servers/rendering/rendering_device.h"
+
+class LightmapperRD : public Lightmapper {
+ GDCLASS(LightmapperRD, Lightmapper)
+
+ struct MeshInstance {
+ MeshData data;
+ int slice = 0;
+ Vector2i offset;
+ };
+
+ struct Light {
+ float position[3];
+ uint32_t type = LIGHT_TYPE_DIRECTIONAL;
+ float direction[3];
+ float energy;
+ float color[3];
+ float size;
+ float range;
+ float attenuation;
+ float spot_angle;
+ float spot_attenuation;
+ uint32_t static_bake;
+ uint32_t pad[3];
+
+ bool operator<(const Light &p_light) const {
+ return type < p_light.type;
+ }
+ };
+
+ struct Vertex {
+ float position[3];
+ float normal_z;
+ float uv[2];
+ float normal_xy[2];
+
+ bool operator==(const Vertex &p_vtx) const {
+ return (position[0] == p_vtx.position[0]) &&
+ (position[1] == p_vtx.position[1]) &&
+ (position[2] == p_vtx.position[2]) &&
+ (uv[0] == p_vtx.uv[0]) &&
+ (uv[1] == p_vtx.uv[1]) &&
+ (normal_xy[0] == p_vtx.normal_xy[0]) &&
+ (normal_xy[1] == p_vtx.normal_xy[1]) &&
+ (normal_z == p_vtx.normal_z);
+ }
+ };
+
+ struct Edge {
+ Vector3 a;
+ Vector3 b;
+ Vector3 na;
+ Vector3 nb;
+ bool operator==(const Edge &p_seam) const {
+ return a == p_seam.a && b == p_seam.b && na == p_seam.na && nb == p_seam.nb;
+ }
+ Edge() {
+ }
+
+ Edge(const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_na, const Vector3 &p_nb) {
+ a = p_a;
+ b = p_b;
+ na = p_na;
+ nb = p_nb;
+ }
+ };
+
+ struct Probe {
+ float position[4];
+ };
+
+ Vector<Probe> probe_positions;
+
+ struct EdgeHash {
+ _FORCE_INLINE_ static uint32_t hash(const Edge &p_edge) {
+ uint32_t h = hash_djb2_one_float(p_edge.a.x);
+ h = hash_djb2_one_float(p_edge.a.y, h);
+ h = hash_djb2_one_float(p_edge.a.z, h);
+ h = hash_djb2_one_float(p_edge.b.x, h);
+ h = hash_djb2_one_float(p_edge.b.y, h);
+ h = hash_djb2_one_float(p_edge.b.z, h);
+ return h;
+ }
+ };
+ struct EdgeUV2 {
+ Vector2 a;
+ Vector2 b;
+ Vector2i indices;
+ bool operator==(const EdgeUV2 &p_uv2) const {
+ return a == p_uv2.a && b == p_uv2.b;
+ }
+ bool seam_found = false;
+ EdgeUV2(Vector2 p_a, Vector2 p_b, Vector2i p_indices) {
+ a = p_a;
+ b = p_b;
+ indices = p_indices;
+ }
+ EdgeUV2() {}
+ };
+
+ struct Seam {
+ Vector2i a;
+ Vector2i b;
+ uint32_t slice;
+ bool operator<(const Seam &p_seam) const {
+ return slice < p_seam.slice;
+ }
+ };
+
+ struct VertexHash {
+ _FORCE_INLINE_ static uint32_t hash(const Vertex &p_vtx) {
+ uint32_t h = hash_djb2_one_float(p_vtx.position[0]);
+ h = hash_djb2_one_float(p_vtx.position[1], h);
+ h = hash_djb2_one_float(p_vtx.position[2], h);
+ h = hash_djb2_one_float(p_vtx.uv[0], h);
+ h = hash_djb2_one_float(p_vtx.uv[1], h);
+ h = hash_djb2_one_float(p_vtx.normal_xy[0], h);
+ h = hash_djb2_one_float(p_vtx.normal_xy[1], h);
+ h = hash_djb2_one_float(p_vtx.normal_z, h);
+ return h;
+ }
+ };
+
+ struct Box {
+ float min_bounds[3];
+ float pad0;
+ float max_bounds[3];
+ float pad1;
+ };
+
+ struct Triangle {
+ uint32_t indices[3];
+ uint32_t slice;
+ bool operator<(const Triangle &p_triangle) const {
+ return slice < p_triangle.slice;
+ }
+ };
+
+ Vector<MeshInstance> mesh_instances;
+
+ Vector<Light> lights;
+
+ struct TriangleSort {
+ uint32_t cell_index;
+ uint32_t triangle_index;
+ bool operator<(const TriangleSort &p_triangle_sort) const {
+ return cell_index < p_triangle_sort.cell_index; //sorting by triangle index in this case makes no sense
+ }
+ };
+
+ void _plot_triangle_into_triangle_index_list(int p_size, const Vector3i &p_ofs, const AABB &p_bounds, const Vector3 p_points[], uint32_t p_triangle_index, LocalVector<TriangleSort> &triangles, uint32_t p_grid_size);
+
+ struct RasterPushConstant {
+ float atlas_size[2];
+ float uv_offset[2];
+ float to_cell_size[3];
+ uint32_t base_triangle;
+ float to_cell_offset[3];
+ float bias;
+ int32_t grid_size[3];
+ uint32_t pad2;
+ };
+
+ struct RasterSeamsPushConstant {
+ uint32_t base_index;
+ uint32_t slice;
+ float uv_offset[2];
+ uint32_t debug;
+ float blend;
+ uint32_t pad[2];
+ };
+
+ struct PushConstant {
+ int32_t atlas_size[2];
+ uint32_t ray_count;
+ uint32_t ray_to;
+
+ float world_size[3];
+ float bias;
+
+ float to_cell_offset[3];
+ uint32_t ray_from;
+
+ float to_cell_size[3];
+ uint32_t light_count;
+
+ int32_t grid_size;
+ int32_t atlas_slice;
+ int32_t region_ofs[2];
+
+ float environment_xform[12];
+ };
+
+ Vector<Ref<Image>> bake_textures;
+ Vector<Color> probe_values;
+
+ BakeError _blit_meshes_into_atlas(int p_max_texture_size, Vector<Ref<Image>> &albedo_images, Vector<Ref<Image>> &emission_images, AABB &bounds, Size2i &atlas_size, int &atlas_slices, BakeStepFunc p_step_function, void *p_bake_userdata);
+ void _create_acceleration_structures(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, AABB &bounds, int grid_size, Vector<Probe> &probe_positions, GenerateProbes p_generate_probes, Vector<int> &slice_triangle_count, Vector<int> &slice_seam_count, RID &vertex_buffer, RID &triangle_buffer, RID &box_buffer, RID &lights_buffer, RID &triangle_cell_indices_buffer, RID &probe_positions_buffer, RID &grid_texture, RID &grid_texture_sdf, RID &seams_buffer, BakeStepFunc p_step_function, void *p_bake_userdata);
+ void _raster_geometry(RenderingDevice *rd, Size2i atlas_size, int atlas_slices, int grid_size, AABB bounds, float p_bias, Vector<int> slice_triangle_count, RID position_tex, RID unocclude_tex, RID normal_tex, RID raster_depth_buffer, RID rasterize_shader, RID raster_base_uniform);
+
+public:
+ virtual void add_mesh(const MeshData &p_mesh);
+ virtual void add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance);
+ virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size);
+ virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size);
+ virtual void add_probe(const Vector3 &p_position);
+ virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_bake_userdata = nullptr);
+
+ int get_bake_texture_count() const;
+ Ref<Image> get_bake_texture(int p_index) const;
+ int get_bake_mesh_count() const;
+ Variant get_bake_mesh_userdata(int p_index) const;
+ Rect2 get_bake_mesh_uv_scale(int p_index) const;
+ int get_bake_mesh_texture_slice(int p_index) const;
+ int get_bake_probe_count() const;
+ Vector3 get_bake_probe_point(int p_probe) const;
+ Vector<Color> get_bake_probe_sh(int p_probe) const;
+
+ LightmapperRD();
+};
+
+#endif // LIGHTMAPPER_H
diff --git a/modules/lightmapper_rd/lm_blendseams.glsl b/modules/lightmapper_rd/lm_blendseams.glsl
new file mode 100644
index 0000000000..e47e5fcc51
--- /dev/null
+++ b/modules/lightmapper_rd/lm_blendseams.glsl
@@ -0,0 +1,108 @@
+#[versions]
+
+lines = "#define MODE_LINES";
+triangles = "#define MODE_TRIANGLES";
+
+#[vertex]
+
+#version 450
+
+VERSION_DEFINES
+
+#include "lm_common_inc.glsl"
+
+layout(push_constant, binding = 0, std430) uniform Params {
+ uint base_index;
+ uint slice;
+ vec2 uv_offset;
+ bool debug;
+ float blend;
+ uint pad[2];
+}
+params;
+
+layout(location = 0) out vec3 uv_interp;
+
+void main() {
+#ifdef MODE_TRIANGLES
+ uint triangle_idx = params.base_index + gl_VertexIndex / 3;
+ uint triangle_subidx = gl_VertexIndex % 3;
+
+ vec2 uv;
+ if (triangle_subidx == 0) {
+ uv = vertices.data[triangles.data[triangle_idx].indices.x].uv;
+ } else if (triangle_subidx == 1) {
+ uv = vertices.data[triangles.data[triangle_idx].indices.y].uv;
+ } else {
+ uv = vertices.data[triangles.data[triangle_idx].indices.z].uv;
+ }
+
+ uv_interp = vec3(uv, float(params.slice));
+ gl_Position = vec4((uv + params.uv_offset) * 2.0 - 1.0, 0.0001, 1.0);
+#endif
+
+#ifdef MODE_LINES
+ uint seam_idx = params.base_index + gl_VertexIndex / 4;
+ uint seam_subidx = gl_VertexIndex % 4;
+
+ uint src_idx;
+ uint dst_idx;
+
+ if (seam_subidx == 0) {
+ src_idx = seams.data[seam_idx].b.x;
+ dst_idx = seams.data[seam_idx].a.x;
+ } else if (seam_subidx == 1) {
+ src_idx = seams.data[seam_idx].b.y;
+ dst_idx = seams.data[seam_idx].a.y;
+ } else if (seam_subidx == 2) {
+ src_idx = seams.data[seam_idx].a.x;
+ dst_idx = seams.data[seam_idx].b.x;
+ } else if (seam_subidx == 3) {
+ src_idx = seams.data[seam_idx].a.y;
+ dst_idx = seams.data[seam_idx].b.y;
+ }
+
+ vec2 src_uv = vertices.data[src_idx].uv;
+ vec2 dst_uv = vertices.data[dst_idx].uv + params.uv_offset;
+
+ uv_interp = vec3(src_uv, float(params.slice));
+ gl_Position = vec4(dst_uv * 2.0 - 1.0, 0.0001, 1.0);
+#endif
+}
+
+#[fragment]
+
+#version 450
+
+VERSION_DEFINES
+
+#include "lm_common_inc.glsl"
+
+layout(push_constant, binding = 0, std430) uniform Params {
+ uint base_index;
+ uint slice;
+ vec2 uv_offset;
+ bool debug;
+ float blend;
+ uint pad[2];
+}
+params;
+
+layout(location = 0) in vec3 uv_interp;
+
+layout(location = 0) out vec4 dst_color;
+
+layout(set = 1, binding = 0) uniform texture2DArray src_color_tex;
+
+void main() {
+ if (params.debug) {
+#ifdef MODE_TRIANGLES
+ dst_color = vec4(1, 0, 1, 1);
+#else
+ dst_color = vec4(1, 1, 0, 1);
+#endif
+ } else {
+ vec4 src_color = textureLod(sampler2DArray(src_color_tex, linear_sampler), uv_interp, 0.0);
+ dst_color = vec4(src_color.rgb, params.blend); //mix
+ }
+}
diff --git a/modules/lightmapper_rd/lm_common_inc.glsl b/modules/lightmapper_rd/lm_common_inc.glsl
new file mode 100644
index 0000000000..0ff455936e
--- /dev/null
+++ b/modules/lightmapper_rd/lm_common_inc.glsl
@@ -0,0 +1,92 @@
+
+/* SET 0, static data that does not change between any call */
+
+struct Vertex {
+ vec3 position;
+ float normal_z;
+ vec2 uv;
+ vec2 normal_xy;
+};
+
+layout(set = 0, binding = 1, std430) restrict readonly buffer Vertices {
+ Vertex data[];
+}
+vertices;
+
+struct Triangle {
+ uvec3 indices;
+ uint slice;
+};
+
+layout(set = 0, binding = 2, std430) restrict readonly buffer Triangles {
+ Triangle data[];
+}
+triangles;
+
+struct Box {
+ vec3 min_bounds;
+ uint pad0;
+ vec3 max_bounds;
+ uint pad1;
+};
+
+layout(set = 0, binding = 3, std430) restrict readonly buffer Boxes {
+ Box data[];
+}
+boxes;
+
+layout(set = 0, binding = 4, std430) restrict readonly buffer GridIndices {
+ uint data[];
+}
+grid_indices;
+
+#define LIGHT_TYPE_DIRECTIONAL 0
+#define LIGHT_TYPE_OMNI 1
+#define LIGHT_TYPE_SPOT 2
+
+struct Light {
+ vec3 position;
+ uint type;
+
+ vec3 direction;
+ float energy;
+
+ vec3 color;
+ float size;
+
+ float range;
+ float attenuation;
+ float spot_angle;
+ float spot_attenuation;
+
+ bool static_bake;
+ uint pad[3];
+};
+
+layout(set = 0, binding = 5, std430) restrict readonly buffer Lights {
+ Light data[];
+}
+lights;
+
+struct Seam {
+ uvec2 a;
+ uvec2 b;
+};
+
+layout(set = 0, binding = 6, std430) restrict readonly buffer Seams {
+ Seam data[];
+}
+seams;
+
+layout(set = 0, binding = 7, std430) restrict readonly buffer Probes {
+ vec4 data[];
+}
+probe_positions;
+
+layout(set = 0, binding = 8) uniform utexture3D grid;
+layout(set = 0, binding = 9) uniform texture3D grid_sdf;
+
+layout(set = 0, binding = 10) uniform texture2DArray albedo_tex;
+layout(set = 0, binding = 11) uniform texture2DArray emission_tex;
+
+layout(set = 0, binding = 12) uniform sampler linear_sampler;
diff --git a/modules/lightmapper_rd/lm_compute.glsl b/modules/lightmapper_rd/lm_compute.glsl
new file mode 100644
index 0000000000..56976bd623
--- /dev/null
+++ b/modules/lightmapper_rd/lm_compute.glsl
@@ -0,0 +1,644 @@
+#[versions]
+
+primary = "#define MODE_DIRECT_LIGHT";
+secondary = "#define MODE_BOUNCE_LIGHT";
+dilate = "#define MODE_DILATE";
+unocclude = "#define MODE_UNOCCLUDE";
+light_probes = "#define MODE_LIGHT_PROBES";
+
+#[compute]
+
+#version 450
+
+VERSION_DEFINES
+
+// One 2D local group focusing in one layer at a time, though all
+// in parallel (no barriers) makes more sense than a 3D local group
+// as this can take more advantage of the cache for each group.
+
+#ifdef MODE_LIGHT_PROBES
+
+layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
+
+#else
+
+layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
+
+#endif
+
+#include "lm_common_inc.glsl"
+
+#ifdef MODE_LIGHT_PROBES
+
+layout(set = 1, binding = 0, std430) restrict buffer LightProbeData {
+ vec4 data[];
+}
+light_probes;
+
+layout(set = 1, binding = 1) uniform texture2DArray source_light;
+layout(set = 1, binding = 2) uniform texture2DArray source_direct_light; //also need the direct light, which was omitted
+layout(set = 1, binding = 3) uniform texture2D environment;
+#endif
+
+#ifdef MODE_UNOCCLUDE
+
+layout(rgba32f, set = 1, binding = 0) uniform restrict image2DArray position;
+layout(rgba32f, set = 1, binding = 1) uniform restrict readonly image2DArray unocclude;
+
+#endif
+
+#if defined(MODE_DIRECT_LIGHT) || defined(MODE_BOUNCE_LIGHT)
+
+layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2DArray dest_light;
+layout(set = 1, binding = 1) uniform texture2DArray source_light;
+layout(set = 1, binding = 2) uniform texture2DArray source_position;
+layout(set = 1, binding = 3) uniform texture2DArray source_normal;
+layout(rgba16f, set = 1, binding = 4) uniform restrict image2DArray accum_light;
+
+#endif
+
+#ifdef MODE_BOUNCE_LIGHT
+layout(rgba32f, set = 1, binding = 5) uniform restrict image2DArray bounce_accum;
+layout(set = 1, binding = 6) uniform texture2D environment;
+#endif
+#ifdef MODE_DIRECT_LIGHT
+layout(rgba32f, set = 1, binding = 5) uniform restrict writeonly image2DArray primary_dynamic;
+#endif
+
+#ifdef MODE_DILATE
+layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2DArray dest_light;
+layout(set = 1, binding = 1) uniform texture2DArray source_light;
+#endif
+
+layout(push_constant, binding = 0, std430) uniform Params {
+ ivec2 atlas_size; // x used for light probe mode total probes
+ uint ray_count;
+ uint ray_to;
+
+ vec3 world_size;
+ float bias;
+
+ vec3 to_cell_offset;
+ uint ray_from;
+
+ vec3 to_cell_size;
+ uint light_count;
+
+ int grid_size;
+ int atlas_slice;
+ ivec2 region_ofs;
+
+ mat3x4 env_transform;
+}
+params;
+
+//check it, but also return distance and barycentric coords (for uv lookup)
+bool ray_hits_triangle(vec3 from, vec3 dir, float max_dist, vec3 p0, vec3 p1, vec3 p2, out float r_distance, out vec3 r_barycentric) {
+ const vec3 e0 = p1 - p0;
+ const vec3 e1 = p0 - p2;
+ vec3 triangleNormal = cross(e1, e0);
+
+ const vec3 e2 = (1.0 / dot(triangleNormal, dir)) * (p0 - from);
+ const vec3 i = cross(dir, e2);
+
+ r_barycentric.y = dot(i, e1);
+ r_barycentric.z = dot(i, e0);
+ r_barycentric.x = 1.0 - (r_barycentric.z + r_barycentric.y);
+ r_distance = dot(triangleNormal, e2);
+ return (r_distance > params.bias) && (r_distance < max_dist) && all(greaterThanEqual(r_barycentric, vec3(0.0)));
+}
+
+bool trace_ray(vec3 p_from, vec3 p_to
+#if defined(MODE_BOUNCE_LIGHT) || defined(MODE_LIGHT_PROBES)
+ ,
+ out uint r_triangle, out vec3 r_barycentric
+#endif
+#if defined(MODE_UNOCCLUDE)
+ ,
+ out float r_distance, out vec3 r_normal
+#endif
+) {
+ /* world coords */
+
+ vec3 rel = p_to - p_from;
+ float rel_len = length(rel);
+ vec3 dir = normalize(rel);
+ vec3 inv_dir = 1.0 / dir;
+
+ /* cell coords */
+
+ vec3 from_cell = (p_from - params.to_cell_offset) * params.to_cell_size;
+ vec3 to_cell = (p_to - params.to_cell_offset) * params.to_cell_size;
+
+ //prepare DDA
+ vec3 rel_cell = to_cell - from_cell;
+ ivec3 icell = ivec3(from_cell);
+ ivec3 iendcell = ivec3(to_cell);
+ vec3 dir_cell = normalize(rel_cell);
+ vec3 delta = abs(1.0 / dir_cell); //vec3(length(rel_cell)) / rel_cell);
+ ivec3 step = ivec3(sign(rel_cell));
+ vec3 side = (sign(rel_cell) * (vec3(icell) - from_cell) + (sign(rel_cell) * 0.5) + 0.5) * delta;
+
+ uint iters = 0;
+ while (all(greaterThanEqual(icell, ivec3(0))) && all(lessThan(icell, ivec3(params.grid_size))) && iters < 1000) {
+ uvec2 cell_data = texelFetch(usampler3D(grid, linear_sampler), icell, 0).xy;
+ if (cell_data.x > 0) { //triangles here
+ bool hit = false;
+#if defined(MODE_UNOCCLUDE)
+ bool hit_backface = false;
+#endif
+ float best_distance = 1e20;
+
+ for (uint i = 0; i < cell_data.x; i++) {
+ uint tidx = grid_indices.data[cell_data.y + i];
+
+ //Ray-Box test
+ vec3 t0 = (boxes.data[tidx].min_bounds - p_from) * inv_dir;
+ vec3 t1 = (boxes.data[tidx].max_bounds - p_from) * inv_dir;
+ vec3 tmin = min(t0, t1), tmax = max(t0, t1);
+
+ if (max(tmin.x, max(tmin.y, tmin.z)) <= min(tmax.x, min(tmax.y, tmax.z))) {
+ continue; //ray box failed
+ }
+
+ //prepare triangle vertices
+ vec3 vtx0 = vertices.data[triangles.data[tidx].indices.x].position;
+ vec3 vtx1 = vertices.data[triangles.data[tidx].indices.y].position;
+ vec3 vtx2 = vertices.data[triangles.data[tidx].indices.z].position;
+#if defined(MODE_UNOCCLUDE)
+ vec3 normal = -normalize(cross((vtx0 - vtx1), (vtx0 - vtx2)));
+
+ bool backface = dot(normal, dir) >= 0.0;
+#endif
+ float distance;
+ vec3 barycentric;
+
+ if (ray_hits_triangle(p_from, dir, rel_len, vtx0, vtx1, vtx2, distance, barycentric)) {
+#ifdef MODE_DIRECT_LIGHT
+ return true; //any hit good
+#endif
+
+#if defined(MODE_UNOCCLUDE)
+ if (!backface) {
+ // the case of meshes having both a front and back face in the same plane is more common than
+ // expected, so if this is a front-face, bias it closer to the ray origin, so it always wins over the back-face
+ distance = max(params.bias, distance - params.bias);
+ }
+
+ hit = true;
+
+ if (distance < best_distance) {
+ hit_backface = backface;
+ best_distance = distance;
+ r_distance = distance;
+ r_normal = normal;
+ }
+
+#endif
+
+#if defined(MODE_BOUNCE_LIGHT) || defined(MODE_LIGHT_PROBES)
+
+ hit = true;
+ if (distance < best_distance) {
+ best_distance = distance;
+ r_triangle = tidx;
+ r_barycentric = barycentric;
+ }
+#endif
+ }
+ }
+#if defined(MODE_UNOCCLUDE)
+
+ if (hit) {
+ return hit_backface;
+ }
+#endif
+#if defined(MODE_BOUNCE_LIGHT) || defined(MODE_LIGHT_PROBES)
+ if (hit) {
+ return true;
+ }
+#endif
+ }
+
+ if (icell == iendcell) {
+ break;
+ }
+
+ bvec3 mask = lessThanEqual(side.xyz, min(side.yzx, side.zxy));
+ side += vec3(mask) * delta;
+ icell += ivec3(vec3(mask)) * step;
+
+ iters++;
+ }
+
+ return false;
+}
+
+const float PI = 3.14159265f;
+const float GOLDEN_ANGLE = PI * (3.0 - sqrt(5.0));
+
+vec3 vogel_hemisphere(uint p_index, uint p_count, float p_offset) {
+ float r = sqrt(float(p_index) + 0.5f) / sqrt(float(p_count));
+ float theta = float(p_index) * GOLDEN_ANGLE + p_offset;
+ float y = cos(r * PI * 0.5);
+ float l = sin(r * PI * 0.5);
+ return vec3(l * cos(theta), l * sin(theta), y);
+}
+
+float quick_hash(vec2 pos) {
+ return fract(sin(dot(pos * 19.19, vec2(49.5791, 97.413))) * 49831.189237);
+}
+
+void main() {
+#ifdef MODE_LIGHT_PROBES
+ int probe_index = int(gl_GlobalInvocationID.x);
+ if (probe_index >= params.atlas_size.x) { //too large, do nothing
+ return;
+ }
+
+#else
+ ivec2 atlas_pos = ivec2(gl_GlobalInvocationID.xy) + params.region_ofs;
+ if (any(greaterThanEqual(atlas_pos, params.atlas_size))) { //too large, do nothing
+ return;
+ }
+#endif
+
+#ifdef MODE_DIRECT_LIGHT
+
+ vec3 normal = texelFetch(sampler2DArray(source_normal, linear_sampler), ivec3(atlas_pos, params.atlas_slice), 0).xyz;
+ if (length(normal) < 0.5) {
+ return; //empty texel, no process
+ }
+ vec3 position = texelFetch(sampler2DArray(source_position, linear_sampler), ivec3(atlas_pos, params.atlas_slice), 0).xyz;
+
+ //go through all lights
+ //start by own light (emissive)
+ vec3 static_light = vec3(0.0);
+ vec3 dynamic_light = vec3(0.0);
+
+#ifdef USE_SH_LIGHTMAPS
+ vec4 sh_accum[4] = vec4[](
+ vec4(0.0, 0.0, 0.0, 1.0),
+ vec4(0.0, 0.0, 0.0, 1.0),
+ vec4(0.0, 0.0, 0.0, 1.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+#endif
+
+ for (uint i = 0; i < params.light_count; i++) {
+ vec3 light_pos;
+ float attenuation;
+ if (lights.data[i].type == LIGHT_TYPE_DIRECTIONAL) {
+ vec3 light_vec = lights.data[i].direction;
+ light_pos = position - light_vec * length(params.world_size);
+ attenuation = 1.0;
+ } else {
+ light_pos = lights.data[i].position;
+ float d = distance(position, light_pos);
+ if (d > lights.data[i].range) {
+ continue;
+ }
+
+ d /= lights.data[i].range;
+
+ attenuation = pow(max(1.0 - d, 0.0), lights.data[i].attenuation);
+
+ if (lights.data[i].type == LIGHT_TYPE_SPOT) {
+ vec3 rel = normalize(position - light_pos);
+ float angle = acos(dot(rel, lights.data[i].direction));
+ if (angle > lights.data[i].spot_angle) {
+ continue; //invisible, dont try
+ }
+
+ float d = clamp(angle / lights.data[i].spot_angle, 0, 1);
+ attenuation *= pow(1.0 - d, lights.data[i].spot_attenuation);
+ }
+ }
+
+ vec3 light_dir = normalize(light_pos - position);
+ attenuation *= max(0.0, dot(normal, light_dir));
+
+ if (attenuation <= 0.0001) {
+ continue; //no need to do anything
+ }
+
+ if (!trace_ray(position + light_dir * params.bias, light_pos)) {
+ vec3 light = lights.data[i].color * lights.data[i].energy * attenuation;
+ if (lights.data[i].static_bake) {
+ static_light += light;
+#ifdef USE_SH_LIGHTMAPS
+
+ float c[4] = float[](
+ 0.282095, //l0
+ 0.488603 * light_dir.y, //l1n1
+ 0.488603 * light_dir.z, //l1n0
+ 0.488603 * light_dir.x //l1p1
+ );
+
+ for (uint j = 0; j < 4; j++) {
+ sh_accum[j].rgb += light * c[j] * (1.0 / 3.0);
+ }
+#endif
+
+ } else {
+ dynamic_light += light;
+ }
+ }
+ }
+
+ vec3 albedo = texelFetch(sampler2DArray(albedo_tex, linear_sampler), ivec3(atlas_pos, params.atlas_slice), 0).rgb;
+ vec3 emissive = texelFetch(sampler2DArray(emission_tex, linear_sampler), ivec3(atlas_pos, params.atlas_slice), 0).rgb;
+
+ dynamic_light *= albedo; //if it will bounce, must multiply by albedo
+ dynamic_light += emissive;
+
+ //keep for lightprobes
+ imageStore(primary_dynamic, ivec3(atlas_pos, params.atlas_slice), vec4(dynamic_light, 1.0));
+
+ dynamic_light += static_light * albedo; //send for bounces
+ imageStore(dest_light, ivec3(atlas_pos, params.atlas_slice), vec4(dynamic_light, 1.0));
+
+#ifdef USE_SH_LIGHTMAPS
+ //keep for adding at the end
+ imageStore(accum_light, ivec3(atlas_pos, params.atlas_slice * 4 + 0), sh_accum[0]);
+ imageStore(accum_light, ivec3(atlas_pos, params.atlas_slice * 4 + 1), sh_accum[1]);
+ imageStore(accum_light, ivec3(atlas_pos, params.atlas_slice * 4 + 2), sh_accum[2]);
+ imageStore(accum_light, ivec3(atlas_pos, params.atlas_slice * 4 + 3), sh_accum[3]);
+
+#else
+ imageStore(accum_light, ivec3(atlas_pos, params.atlas_slice), vec4(static_light, 1.0));
+#endif
+
+#endif
+
+#ifdef MODE_BOUNCE_LIGHT
+
+ vec3 normal = texelFetch(sampler2DArray(source_normal, linear_sampler), ivec3(atlas_pos, params.atlas_slice), 0).xyz;
+ if (length(normal) < 0.5) {
+ return; //empty texel, no process
+ }
+
+ vec3 position = texelFetch(sampler2DArray(source_position, linear_sampler), ivec3(atlas_pos, params.atlas_slice), 0).xyz;
+
+ vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
+ vec3 tangent = normalize(cross(v0, normal));
+ vec3 bitangent = normalize(cross(tangent, normal));
+ mat3 normal_mat = mat3(tangent, bitangent, normal);
+
+#ifdef USE_SH_LIGHTMAPS
+ vec4 sh_accum[4] = vec4[](
+ vec4(0.0, 0.0, 0.0, 1.0),
+ vec4(0.0, 0.0, 0.0, 1.0),
+ vec4(0.0, 0.0, 0.0, 1.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+#endif
+ vec3 light_average = vec3(0.0);
+ for (uint i = params.ray_from; i < params.ray_to; i++) {
+ vec3 ray_dir = normal_mat * vogel_hemisphere(i, params.ray_count, quick_hash(vec2(atlas_pos)));
+
+ uint tidx;
+ vec3 barycentric;
+
+ vec3 light;
+ if (trace_ray(position + ray_dir * params.bias, position + ray_dir * length(params.world_size), tidx, barycentric)) {
+ //hit a triangle
+ vec2 uv0 = vertices.data[triangles.data[tidx].indices.x].uv;
+ vec2 uv1 = vertices.data[triangles.data[tidx].indices.y].uv;
+ vec2 uv2 = vertices.data[triangles.data[tidx].indices.z].uv;
+ vec3 uvw = vec3(barycentric.x * uv0 + barycentric.y * uv1 + barycentric.z * uv2, float(triangles.data[tidx].slice));
+
+ light = textureLod(sampler2DArray(source_light, linear_sampler), uvw, 0.0).rgb;
+ } else {
+ //did not hit a triangle, reach out for the sky
+ vec3 sky_dir = normalize(mat3(params.env_transform) * ray_dir);
+
+ vec2 st = vec2(
+ atan(sky_dir.x, sky_dir.z),
+ acos(sky_dir.y));
+
+ if (st.x < 0.0)
+ st.x += PI * 2.0;
+
+ st /= vec2(PI * 2.0, PI);
+
+ light = textureLod(sampler2D(environment, linear_sampler), st, 0.0).rgb;
+ }
+
+ light_average += light;
+
+#ifdef USE_SH_LIGHTMAPS
+
+ float c[4] = float[](
+ 0.282095, //l0
+ 0.488603 * ray_dir.y, //l1n1
+ 0.488603 * ray_dir.z, //l1n0
+ 0.488603 * ray_dir.x //l1p1
+ );
+
+ for (uint j = 0; j < 4; j++) {
+ sh_accum[j].rgb += light * c[j] * (8.0 / float(params.ray_count));
+ }
+#endif
+ }
+
+ vec3 light_total;
+ if (params.ray_from == 0) {
+ light_total = vec3(0.0);
+ } else {
+ light_total = imageLoad(bounce_accum, ivec3(atlas_pos, params.atlas_slice)).rgb;
+ }
+
+ light_total += light_average;
+
+#ifdef USE_SH_LIGHTMAPS
+
+ for (int i = 0; i < 4; i++) {
+ vec4 accum = imageLoad(accum_light, ivec3(atlas_pos, params.atlas_slice * 4 + i));
+ accum.rgb += sh_accum[i].rgb;
+ imageStore(accum_light, ivec3(atlas_pos, params.atlas_slice * 4 + i), accum);
+ }
+
+#endif
+ if (params.ray_to == params.ray_count) {
+ light_total /= float(params.ray_count);
+ imageStore(dest_light, ivec3(atlas_pos, params.atlas_slice), vec4(light_total, 1.0));
+#ifndef USE_SH_LIGHTMAPS
+ vec4 accum = imageLoad(accum_light, ivec3(atlas_pos, params.atlas_slice));
+ accum.rgb += light_total;
+ imageStore(accum_light, ivec3(atlas_pos, params.atlas_slice), accum);
+#endif
+ } else {
+ imageStore(bounce_accum, ivec3(atlas_pos, params.atlas_slice), vec4(light_total, 1.0));
+ }
+
+#endif
+
+#ifdef MODE_UNOCCLUDE
+
+ //texel_size = 0.5;
+ //compute tangents
+
+ vec4 position_alpha = imageLoad(position, ivec3(atlas_pos, params.atlas_slice));
+ if (position_alpha.a < 0.5) {
+ return;
+ }
+
+ vec3 vertex_pos = position_alpha.xyz;
+ vec4 normal_tsize = imageLoad(unocclude, ivec3(atlas_pos, params.atlas_slice));
+
+ vec3 face_normal = normal_tsize.xyz;
+ float texel_size = normal_tsize.w;
+
+ vec3 v0 = abs(face_normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
+ vec3 tangent = normalize(cross(v0, face_normal));
+ vec3 bitangent = normalize(cross(tangent, face_normal));
+ vec3 base_pos = vertex_pos + face_normal * params.bias; //raise a bit
+
+ vec3 rays[4] = vec3[](tangent, bitangent, -tangent, -bitangent);
+ float min_d = 1e20;
+ for (int i = 0; i < 4; i++) {
+ vec3 ray_to = base_pos + rays[i] * texel_size;
+ float d;
+ vec3 norm;
+
+ if (trace_ray(base_pos, ray_to, d, norm)) {
+ if (d < min_d) {
+ vertex_pos = base_pos + rays[i] * d + norm * params.bias * 10.0; //this bias needs to be greater than the regular bias, because otherwise later, rays will go the other side when pointing back.
+ min_d = d;
+ }
+ }
+ }
+
+ position_alpha.xyz = vertex_pos;
+
+ imageStore(position, ivec3(atlas_pos, params.atlas_slice), position_alpha);
+
+#endif
+
+#ifdef MODE_LIGHT_PROBES
+
+ vec3 position = probe_positions.data[probe_index].xyz;
+
+ vec4 probe_sh_accum[9] = vec4[](
+ vec4(0.0),
+ vec4(0.0),
+ vec4(0.0),
+ vec4(0.0),
+ vec4(0.0),
+ vec4(0.0),
+ vec4(0.0),
+ vec4(0.0),
+ vec4(0.0));
+
+ for (uint i = params.ray_from; i < params.ray_to; i++) {
+ vec3 ray_dir = vogel_hemisphere(i, params.ray_count, quick_hash(vec2(float(probe_index), 0.0)));
+ if (bool(i & 1)) {
+ //throw to both sides, so alternate them
+ ray_dir.z *= -1.0;
+ }
+
+ uint tidx;
+ vec3 barycentric;
+ vec3 light;
+
+ if (trace_ray(position + ray_dir * params.bias, position + ray_dir * length(params.world_size), tidx, barycentric)) {
+ vec2 uv0 = vertices.data[triangles.data[tidx].indices.x].uv;
+ vec2 uv1 = vertices.data[triangles.data[tidx].indices.y].uv;
+ vec2 uv2 = vertices.data[triangles.data[tidx].indices.z].uv;
+ vec3 uvw = vec3(barycentric.x * uv0 + barycentric.y * uv1 + barycentric.z * uv2, float(triangles.data[tidx].slice));
+
+ light = textureLod(sampler2DArray(source_light, linear_sampler), uvw, 0.0).rgb;
+ light += textureLod(sampler2DArray(source_direct_light, linear_sampler), uvw, 0.0).rgb;
+ } else {
+ //did not hit a triangle, reach out for the sky
+ vec3 sky_dir = normalize(mat3(params.env_transform) * ray_dir);
+
+ vec2 st = vec2(
+ atan(sky_dir.x, sky_dir.z),
+ acos(sky_dir.y));
+
+ if (st.x < 0.0)
+ st.x += PI * 2.0;
+
+ st /= vec2(PI * 2.0, PI);
+
+ light = textureLod(sampler2D(environment, linear_sampler), st, 0.0).rgb;
+ }
+
+ {
+ float c[9] = float[](
+ 0.282095, //l0
+ 0.488603 * ray_dir.y, //l1n1
+ 0.488603 * ray_dir.z, //l1n0
+ 0.488603 * ray_dir.x, //l1p1
+ 1.092548 * ray_dir.x * ray_dir.y, //l2n2
+ 1.092548 * ray_dir.y * ray_dir.z, //l2n1
+ //0.315392 * (ray_dir.x * ray_dir.x + ray_dir.y * ray_dir.y + 2.0 * ray_dir.z * ray_dir.z), //l20
+ 0.315392 * (3.0 * ray_dir.z * ray_dir.z - 1.0), //l20
+ 1.092548 * ray_dir.x * ray_dir.z, //l2p1
+ 0.546274 * (ray_dir.x * ray_dir.x - ray_dir.y * ray_dir.y) //l2p2
+ );
+
+ for (uint j = 0; j < 9; j++) {
+ probe_sh_accum[j].rgb += light * c[j];
+ }
+ }
+ }
+
+ if (params.ray_from > 0) {
+ for (uint j = 0; j < 9; j++) { //accum from existing
+ probe_sh_accum[j] += light_probes.data[probe_index * 9 + j];
+ }
+ }
+
+ if (params.ray_to == params.ray_count) {
+ for (uint j = 0; j < 9; j++) { //accum from existing
+ probe_sh_accum[j] *= 4.0 / float(params.ray_count);
+ }
+ }
+
+ for (uint j = 0; j < 9; j++) { //accum from existing
+ light_probes.data[probe_index * 9 + j] = probe_sh_accum[j];
+ }
+
+#endif
+
+#ifdef MODE_DILATE
+
+ vec4 c = texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos, params.atlas_slice), 0);
+ //sides first, as they are closer
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-1, 0), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(0, 1), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(1, 0), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(0, -1), params.atlas_slice), 0);
+ //endpoints second
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-1, -1), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-1, 1), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(1, -1), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(1, 1), params.atlas_slice), 0);
+
+ //far sides third
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-2, 0), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(0, 2), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(2, 0), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(0, -2), params.atlas_slice), 0);
+
+ //far-mid endpoints
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-2, -1), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-2, 1), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(2, -1), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(2, 1), params.atlas_slice), 0);
+
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-1, -2), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-1, 2), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(1, -2), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(1, 2), params.atlas_slice), 0);
+ //far endpoints
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-2, -2), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(-2, 2), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(2, -2), params.atlas_slice), 0);
+ c = c.a > 0.5 ? c : texelFetch(sampler2DArray(source_light, linear_sampler), ivec3(atlas_pos + ivec2(2, 2), params.atlas_slice), 0);
+
+ imageStore(dest_light, ivec3(atlas_pos, params.atlas_slice), c);
+
+#endif
+}
diff --git a/modules/lightmapper_rd/lm_raster.glsl b/modules/lightmapper_rd/lm_raster.glsl
new file mode 100644
index 0000000000..6c2904192b
--- /dev/null
+++ b/modules/lightmapper_rd/lm_raster.glsl
@@ -0,0 +1,157 @@
+#[vertex]
+
+#version 450
+
+VERSION_DEFINES
+
+#include "lm_common_inc.glsl"
+
+layout(location = 0) out vec3 vertex_interp;
+layout(location = 1) out vec3 normal_interp;
+layout(location = 2) out vec2 uv_interp;
+layout(location = 3) out vec3 barycentric;
+layout(location = 4) flat out uvec3 vertex_indices;
+layout(location = 5) flat out vec3 face_normal;
+
+layout(push_constant, binding = 0, std430) uniform Params {
+ vec2 atlas_size;
+ vec2 uv_offset;
+ vec3 to_cell_size;
+ uint base_triangle;
+ vec3 to_cell_offset;
+ float bias;
+ ivec3 grid_size;
+ uint pad2;
+}
+params;
+
+void main() {
+ uint triangle_idx = params.base_triangle + gl_VertexIndex / 3;
+ uint triangle_subidx = gl_VertexIndex % 3;
+
+ vertex_indices = triangles.data[triangle_idx].indices;
+
+ uint vertex_idx;
+ if (triangle_subidx == 0) {
+ vertex_idx = vertex_indices.x;
+ barycentric = vec3(1, 0, 0);
+ } else if (triangle_subidx == 1) {
+ vertex_idx = vertex_indices.y;
+ barycentric = vec3(0, 1, 0);
+ } else {
+ vertex_idx = vertex_indices.z;
+ barycentric = vec3(0, 0, 1);
+ }
+
+ vertex_interp = vertices.data[vertex_idx].position;
+ uv_interp = vertices.data[vertex_idx].uv;
+ normal_interp = vec3(vertices.data[vertex_idx].normal_xy, vertices.data[vertex_idx].normal_z);
+
+ face_normal = -normalize(cross((vertices.data[vertex_indices.x].position - vertices.data[vertex_indices.y].position), (vertices.data[vertex_indices.x].position - vertices.data[vertex_indices.z].position)));
+
+ gl_Position = vec4((uv_interp + params.uv_offset) * 2.0 - 1.0, 0.0001, 1.0);
+}
+
+#[fragment]
+
+#version 450
+
+VERSION_DEFINES
+
+#include "lm_common_inc.glsl"
+
+layout(push_constant, binding = 0, std430) uniform Params {
+ vec2 atlas_size;
+ vec2 uv_offset;
+ vec3 to_cell_size;
+ uint base_triangle;
+ vec3 to_cell_offset;
+ float bias;
+ ivec3 grid_size;
+ uint pad2;
+}
+params;
+
+layout(location = 0) in vec3 vertex_interp;
+layout(location = 1) in vec3 normal_interp;
+layout(location = 2) in vec2 uv_interp;
+layout(location = 3) in vec3 barycentric;
+layout(location = 4) in flat uvec3 vertex_indices;
+layout(location = 5) in flat vec3 face_normal;
+
+layout(location = 0) out vec4 position;
+layout(location = 1) out vec4 normal;
+layout(location = 2) out vec4 unocclude;
+
+void main() {
+ vec3 vertex_pos = vertex_interp;
+
+ {
+ // smooth out vertex position by interpolating its projection in the 3 normal planes (normal plane is created by vertex pos and normal)
+ // because we don't want to interpolate inwards, normals found pointing inwards are pushed out.
+ vec3 pos_a = vertices.data[vertex_indices.x].position;
+ vec3 pos_b = vertices.data[vertex_indices.y].position;
+ vec3 pos_c = vertices.data[vertex_indices.z].position;
+ vec3 center = (pos_a + pos_b + pos_c) * 0.3333333;
+ vec3 norm_a = vec3(vertices.data[vertex_indices.x].normal_xy, vertices.data[vertex_indices.x].normal_z);
+ vec3 norm_b = vec3(vertices.data[vertex_indices.y].normal_xy, vertices.data[vertex_indices.y].normal_z);
+ vec3 norm_c = vec3(vertices.data[vertex_indices.z].normal_xy, vertices.data[vertex_indices.z].normal_z);
+
+ {
+ vec3 dir_a = normalize(pos_a - center);
+ float d_a = dot(dir_a, norm_a);
+ if (d_a < 0) {
+ //pointing inwards
+ norm_a = normalize(norm_a - dir_a * d_a);
+ }
+ }
+ {
+ vec3 dir_b = normalize(pos_b - center);
+ float d_b = dot(dir_b, norm_b);
+ if (d_b < 0) {
+ //pointing inwards
+ norm_b = normalize(norm_b - dir_b * d_b);
+ }
+ }
+ {
+ vec3 dir_c = normalize(pos_c - center);
+ float d_c = dot(dir_c, norm_c);
+ if (d_c < 0) {
+ //pointing inwards
+ norm_c = normalize(norm_c - dir_c * d_c);
+ }
+ }
+
+ float d_a = dot(norm_a, pos_a);
+ float d_b = dot(norm_b, pos_b);
+ float d_c = dot(norm_c, pos_c);
+
+ vec3 proj_a = vertex_pos - norm_a * (dot(norm_a, vertex_pos) - d_a);
+ vec3 proj_b = vertex_pos - norm_b * (dot(norm_b, vertex_pos) - d_b);
+ vec3 proj_c = vertex_pos - norm_c * (dot(norm_c, vertex_pos) - d_c);
+
+ vec3 smooth_position = proj_a * barycentric.x + proj_b * barycentric.y + proj_c * barycentric.z;
+
+ if (dot(face_normal, smooth_position) > dot(face_normal, vertex_pos)) { //only project outwards
+ vertex_pos = smooth_position;
+ }
+ }
+
+ {
+ // unocclusion technique based on:
+ // https://ndotl.wordpress.com/2018/08/29/baking-artifact-free-lightmaps/
+
+ /* compute texel size */
+ vec3 delta_uv = max(abs(dFdx(vertex_interp)), abs(dFdy(vertex_interp)));
+ float texel_size = max(delta_uv.x, max(delta_uv.y, delta_uv.z));
+ texel_size *= sqrt(2.0); //expand to unit box edge length (again, worst case)
+
+ unocclude.xyz = face_normal;
+ unocclude.w = texel_size;
+
+ //continued on lm_compute.glsl
+ }
+
+ position = vec4(vertex_pos, 1.0);
+ normal = vec4(normalize(normal_interp), 1.0);
+}
diff --git a/modules/lightmapper_rd/register_types.cpp b/modules/lightmapper_rd/register_types.cpp
new file mode 100644
index 0000000000..0e6d7590cc
--- /dev/null
+++ b/modules/lightmapper_rd/register_types.cpp
@@ -0,0 +1,63 @@
+/*************************************************************************/
+/* register_types.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "register_types.h"
+
+#include "core/project_settings.h"
+#include "lightmapper_rd.h"
+#include "scene/3d/lightmapper.h"
+
+#ifndef _3D_DISABLED
+static Lightmapper *create_lightmapper_rd() {
+ return memnew(LightmapperRD);
+}
+#endif
+
+void register_lightmapper_rd_types() {
+ GLOBAL_DEF("rendering/gpu_lightmapper/quality/low_quality_ray_count", 16);
+ GLOBAL_DEF("rendering/gpu_lightmapper/quality/medium_quality_ray_count", 64);
+ GLOBAL_DEF("rendering/gpu_lightmapper/quality/high_quality_ray_count", 256);
+ GLOBAL_DEF("rendering/gpu_lightmapper/quality/ultra_quality_ray_count", 1024);
+ GLOBAL_DEF("rendering/gpu_lightmapper/performance/max_rays_per_pass", 32);
+ GLOBAL_DEF("rendering/gpu_lightmapper/performance/region_size", 512);
+
+ GLOBAL_DEF("rendering/gpu_lightmapper/quality/low_quality_probe_ray_count", 64);
+ GLOBAL_DEF("rendering/gpu_lightmapper/quality/medium_quality_probe_ray_count", 256);
+ GLOBAL_DEF("rendering/gpu_lightmapper/quality/high_quality_probe_ray_count", 512);
+ GLOBAL_DEF("rendering/gpu_lightmapper/quality/ultra_quality_probe_ray_count", 2048);
+ GLOBAL_DEF("rendering/gpu_lightmapper/performance/max_rays_per_probe_pass", 64);
+#ifndef _3D_DISABLED
+ ClassDB::register_class<LightmapperRD>();
+ Lightmapper::create_gpu = create_lightmapper_rd;
+#endif
+}
+
+void unregister_lightmapper_rd_types() {
+}
diff --git a/core/os/semaphore.cpp b/modules/lightmapper_rd/register_types.h
index 93f1e2dff4..b0e15a927f 100644
--- a/core/os/semaphore.cpp
+++ b/modules/lightmapper_rd/register_types.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* semaphore.cpp */
+/* register_types.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,4 +28,10 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "semaphore.h"
+#ifndef LIGHTMAPPER_RD_REGISTER_TYPES_H
+#define LIGHTMAPPER_RD_REGISTER_TYPES_H
+
+void register_lightmapper_rd_types();
+void unregister_lightmapper_rd_types();
+
+#endif // XATLAS_UNWRAP_REGISTER_TYPES_H
diff --git a/modules/mbedtls/crypto_mbedtls.cpp b/modules/mbedtls/crypto_mbedtls.cpp
index a47a4503a5..1f9d8c2aa3 100644
--- a/modules/mbedtls/crypto_mbedtls.cpp
+++ b/modules/mbedtls/crypto_mbedtls.cpp
@@ -155,7 +155,6 @@ Crypto *CryptoMbedTLS::create() {
}
void CryptoMbedTLS::initialize_crypto() {
-
#ifdef DEBUG_ENABLED
mbedtls_debug_set_threshold(1);
#endif
diff --git a/modules/mbedtls/crypto_mbedtls.h b/modules/mbedtls/crypto_mbedtls.h
index db3d00a5e3..48855d082a 100644
--- a/modules/mbedtls/crypto_mbedtls.h
+++ b/modules/mbedtls/crypto_mbedtls.h
@@ -41,7 +41,6 @@
class CryptoMbedTLS;
class SSLContextMbedTLS;
class CryptoKeyMbedTLS : public CryptoKey {
-
private:
mbedtls_pk_context pkey;
int locks;
@@ -70,7 +69,6 @@ public:
};
class X509CertificateMbedTLS : public X509Certificate {
-
private:
mbedtls_x509_crt cert;
int locks;
@@ -100,7 +98,6 @@ public:
};
class CryptoMbedTLS : public Crypto {
-
private:
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
diff --git a/modules/mbedtls/dtls_server_mbedtls.cpp b/modules/mbedtls/dtls_server_mbedtls.cpp
index f31f067f4e..d9961b026f 100644
--- a/modules/mbedtls/dtls_server_mbedtls.cpp
+++ b/modules/mbedtls/dtls_server_mbedtls.cpp
@@ -54,12 +54,10 @@ Ref<PacketPeerDTLS> DTLSServerMbedTLS::take_connection(Ref<PacketPeerUDP> p_udp_
}
DTLSServer *DTLSServerMbedTLS::_create_func() {
-
return memnew(DTLSServerMbedTLS);
}
void DTLSServerMbedTLS::initialize() {
-
_create = _create_func;
available = true;
}
diff --git a/modules/mbedtls/dtls_server_mbedtls.h b/modules/mbedtls/dtls_server_mbedtls.h
index d61ab3179e..d93553bf7f 100644
--- a/modules/mbedtls/dtls_server_mbedtls.h
+++ b/modules/mbedtls/dtls_server_mbedtls.h
@@ -35,7 +35,6 @@
#include "ssl_context_mbedtls.h"
class DTLSServerMbedTLS : public DTLSServer {
-
private:
static DTLSServer *_create_func();
Ref<CryptoKey> _key;
diff --git a/modules/mbedtls/packet_peer_mbed_dtls.cpp b/modules/mbedtls/packet_peer_mbed_dtls.cpp
index b2aa5f5827..8206d739ae 100755..100644
--- a/modules/mbedtls/packet_peer_mbed_dtls.cpp
+++ b/modules/mbedtls/packet_peer_mbed_dtls.cpp
@@ -35,8 +35,9 @@
#include "core/os/file_access.h"
int PacketPeerMbedDTLS::bio_send(void *ctx, const unsigned char *buf, size_t len) {
-
- if (buf == nullptr || len <= 0) return 0;
+ if (buf == nullptr || len <= 0) {
+ return 0;
+ }
PacketPeerMbedDTLS *sp = (PacketPeerMbedDTLS *)ctx;
@@ -52,8 +53,9 @@ int PacketPeerMbedDTLS::bio_send(void *ctx, const unsigned char *buf, size_t len
}
int PacketPeerMbedDTLS::bio_recv(void *ctx, unsigned char *buf, size_t len) {
-
- if (buf == nullptr || len <= 0) return 0;
+ if (buf == nullptr || len <= 0) {
+ return 0;
+ }
PacketPeerMbedDTLS *sp = (PacketPeerMbedDTLS *)ctx;
@@ -77,7 +79,6 @@ int PacketPeerMbedDTLS::bio_recv(void *ctx, unsigned char *buf, size_t len) {
}
void PacketPeerMbedDTLS::_cleanup() {
-
ssl_ctx->clear();
base = Ref<PacketPeer>();
status = STATUS_DISCONNECTED;
@@ -114,7 +115,6 @@ Error PacketPeerMbedDTLS::_do_handshake() {
}
Error PacketPeerMbedDTLS::connect_to_peer(Ref<PacketPeerUDP> p_base, bool p_validate_certs, const String &p_for_hostname, Ref<X509Certificate> p_ca_certs) {
-
ERR_FAIL_COND_V(!p_base.is_valid() || !p_base->is_connected_to_host(), ERR_INVALID_PARAMETER);
base = p_base;
@@ -139,7 +139,6 @@ Error PacketPeerMbedDTLS::connect_to_peer(Ref<PacketPeerUDP> p_base, bool p_vali
}
Error PacketPeerMbedDTLS::accept_peer(Ref<PacketPeerUDP> p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain, Ref<CookieContextMbedTLS> p_cookies) {
-
Error err = ssl_ctx->init_server(MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_VERIFY_NONE, p_key, p_cert, p_cookies);
ERR_FAIL_COND_V(err != OK, err);
@@ -168,11 +167,11 @@ Error PacketPeerMbedDTLS::accept_peer(Ref<PacketPeerUDP> p_base, Ref<CryptoKey>
}
Error PacketPeerMbedDTLS::put_packet(const uint8_t *p_buffer, int p_bytes) {
-
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
- if (p_bytes == 0)
+ if (p_bytes == 0) {
return OK;
+ }
int ret = mbedtls_ssl_write(ssl_ctx->get_context(), p_buffer, p_bytes);
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
@@ -187,7 +186,6 @@ Error PacketPeerMbedDTLS::put_packet(const uint8_t *p_buffer, int p_bytes) {
}
Error PacketPeerMbedDTLS::get_packet(const uint8_t **r_buffer, int &r_bytes) {
-
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
r_bytes = 0;
@@ -213,7 +211,6 @@ Error PacketPeerMbedDTLS::get_packet(const uint8_t **r_buffer, int &r_bytes) {
}
void PacketPeerMbedDTLS::poll() {
-
if (status == STATUS_HANDSHAKING) {
_do_handshake();
return;
@@ -238,19 +235,16 @@ void PacketPeerMbedDTLS::poll() {
}
int PacketPeerMbedDTLS::get_available_packet_count() const {
-
ERR_FAIL_COND_V(status != STATUS_CONNECTED, 0);
return mbedtls_ssl_get_bytes_avail(&(ssl_ctx->ssl)) > 0 ? 1 : 0;
}
int PacketPeerMbedDTLS::get_max_packet_size() const {
-
return 488; // 512 (UDP in Godot) - 24 (DTLS header)
}
PacketPeerMbedDTLS::PacketPeerMbedDTLS() {
-
ssl_ctx.instance();
status = STATUS_DISCONNECTED;
}
@@ -260,33 +254,30 @@ PacketPeerMbedDTLS::~PacketPeerMbedDTLS() {
}
void PacketPeerMbedDTLS::disconnect_from_peer() {
-
- if (status != STATUS_CONNECTED && status != STATUS_HANDSHAKING)
+ if (status != STATUS_CONNECTED && status != STATUS_HANDSHAKING) {
return;
+ }
if (status == STATUS_CONNECTED) {
int ret = 0;
// Send SSL close notification, blocking, but ignore other errors.
- do
+ do {
ret = mbedtls_ssl_close_notify(ssl_ctx->get_context());
- while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
+ } while (ret == MBEDTLS_ERR_SSL_WANT_WRITE);
}
_cleanup();
}
PacketPeerMbedDTLS::Status PacketPeerMbedDTLS::get_status() const {
-
return status;
}
PacketPeerDTLS *PacketPeerMbedDTLS::_create_func() {
-
return memnew(PacketPeerMbedDTLS);
}
void PacketPeerMbedDTLS::initialize_dtls() {
-
_create = _create_func;
available = true;
}
diff --git a/modules/mbedtls/register_types.cpp b/modules/mbedtls/register_types.cpp
index d39af7fe87..84a27c29bd 100755..100644
--- a/modules/mbedtls/register_types.cpp
+++ b/modules/mbedtls/register_types.cpp
@@ -36,7 +36,6 @@
#include "stream_peer_mbedtls.h"
void register_mbedtls_types() {
-
CryptoMbedTLS::initialize_crypto();
StreamPeerMbedTLS::initialize_ssl();
PacketPeerMbedDTLS::initialize_dtls();
@@ -44,7 +43,6 @@ void register_mbedtls_types() {
}
void unregister_mbedtls_types() {
-
DTLSServerMbedTLS::finalize();
PacketPeerMbedDTLS::finalize_dtls();
StreamPeerMbedTLS::finalize_ssl();
diff --git a/modules/mbedtls/ssl_context_mbedtls.cpp b/modules/mbedtls/ssl_context_mbedtls.cpp
index 1ffb9bda05..a2200e0644 100644
--- a/modules/mbedtls/ssl_context_mbedtls.cpp
+++ b/modules/mbedtls/ssl_context_mbedtls.cpp
@@ -33,7 +33,6 @@
static void my_debug(void *ctx, int level,
const char *file, int line,
const char *str) {
-
printf("%s:%04d: %s", file, line, str);
fflush(stdout);
}
@@ -68,8 +67,9 @@ Error CookieContextMbedTLS::setup() {
}
void CookieContextMbedTLS::clear() {
- if (!inited)
+ if (!inited) {
return;
+ }
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
mbedtls_ssl_cookie_free(&cookie_ctx);
@@ -121,10 +121,12 @@ Error SSLContextMbedTLS::init_server(int p_transport, int p_authmode, Ref<Crypto
// Locking key and certificate(s)
pkey = p_pkey;
certs = p_cert;
- if (pkey.is_valid())
+ if (pkey.is_valid()) {
pkey->lock();
- if (certs.is_valid())
+ }
+ if (certs.is_valid()) {
certs->lock();
+ }
// Adding key and certificate
int ret = mbedtls_ssl_conf_own_cert(&conf, &(certs->cert), &(pkey->pkey));
@@ -176,19 +178,22 @@ Error SSLContextMbedTLS::init_client(int p_transport, int p_authmode, Ref<X509Ce
}
void SSLContextMbedTLS::clear() {
- if (!inited)
+ if (!inited) {
return;
+ }
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
mbedtls_ctr_drbg_free(&ctr_drbg);
mbedtls_entropy_free(&entropy);
// Unlock and key and certificates
- if (certs.is_valid())
+ if (certs.is_valid()) {
certs->unlock();
+ }
certs = Ref<X509Certificate>();
- if (pkey.is_valid())
+ if (pkey.is_valid()) {
pkey->unlock();
+ }
pkey = Ref<CryptoKeyMbedTLS>();
cookies = Ref<CookieContextMbedTLS>();
inited = false;
diff --git a/modules/mbedtls/ssl_context_mbedtls.h b/modules/mbedtls/ssl_context_mbedtls.h
index d3e1f87a8e..baaeb6eb85 100644
--- a/modules/mbedtls/ssl_context_mbedtls.h
+++ b/modules/mbedtls/ssl_context_mbedtls.h
@@ -47,7 +47,6 @@
class SSLContextMbedTLS;
class CookieContextMbedTLS : public Reference {
-
friend class SSLContextMbedTLS;
protected:
@@ -65,7 +64,6 @@ public:
};
class SSLContextMbedTLS : public Reference {
-
protected:
bool inited;
diff --git a/modules/mbedtls/stream_peer_mbedtls.cpp b/modules/mbedtls/stream_peer_mbedtls.cpp
index 983095c536..e9a610b7ee 100755..100644
--- a/modules/mbedtls/stream_peer_mbedtls.cpp
+++ b/modules/mbedtls/stream_peer_mbedtls.cpp
@@ -34,8 +34,9 @@
#include "core/os/file_access.h"
int StreamPeerMbedTLS::bio_send(void *ctx, const unsigned char *buf, size_t len) {
-
- if (buf == nullptr || len <= 0) return 0;
+ if (buf == nullptr || len <= 0) {
+ return 0;
+ }
StreamPeerMbedTLS *sp = (StreamPeerMbedTLS *)ctx;
@@ -53,8 +54,9 @@ int StreamPeerMbedTLS::bio_send(void *ctx, const unsigned char *buf, size_t len)
}
int StreamPeerMbedTLS::bio_recv(void *ctx, unsigned char *buf, size_t len) {
-
- if (buf == nullptr || len <= 0) return 0;
+ if (buf == nullptr || len <= 0) {
+ return 0;
+ }
StreamPeerMbedTLS *sp = (StreamPeerMbedTLS *)ctx;
@@ -72,7 +74,6 @@ int StreamPeerMbedTLS::bio_recv(void *ctx, unsigned char *buf, size_t len) {
}
void StreamPeerMbedTLS::_cleanup() {
-
ssl_ctx->clear();
base = Ref<StreamPeer>();
status = STATUS_DISCONNECTED;
@@ -102,7 +103,6 @@ Error StreamPeerMbedTLS::_do_handshake() {
}
Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs, const String &p_for_hostname, Ref<X509Certificate> p_ca_certs) {
-
ERR_FAIL_COND_V(p_base.is_null(), ERR_INVALID_PARAMETER);
base = p_base;
@@ -125,7 +125,6 @@ Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_valida
}
Error StreamPeerMbedTLS::accept_stream(Ref<StreamPeer> p_base, Ref<CryptoKey> p_key, Ref<X509Certificate> p_cert, Ref<X509Certificate> p_ca_chain) {
-
ERR_FAIL_COND_V(p_base.is_null(), ERR_INVALID_PARAMETER);
Error err = ssl_ctx->init_server(MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_VERIFY_NONE, p_key, p_cert);
@@ -144,8 +143,8 @@ Error StreamPeerMbedTLS::accept_stream(Ref<StreamPeer> p_base, Ref<CryptoKey> p_
status = STATUS_CONNECTED;
return OK;
}
-Error StreamPeerMbedTLS::put_data(const uint8_t *p_data, int p_bytes) {
+Error StreamPeerMbedTLS::put_data(const uint8_t *p_data, int p_bytes) {
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
Error err;
@@ -166,13 +165,13 @@ Error StreamPeerMbedTLS::put_data(const uint8_t *p_data, int p_bytes) {
}
Error StreamPeerMbedTLS::put_partial_data(const uint8_t *p_data, int p_bytes, int &r_sent) {
-
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
r_sent = 0;
- if (p_bytes == 0)
+ if (p_bytes == 0) {
return OK;
+ }
int ret = mbedtls_ssl_write(ssl_ctx->get_context(), p_data, p_bytes);
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
@@ -193,14 +192,12 @@ Error StreamPeerMbedTLS::put_partial_data(const uint8_t *p_data, int p_bytes, in
}
Error StreamPeerMbedTLS::get_data(uint8_t *p_buffer, int p_bytes) {
-
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
Error err;
int got = 0;
while (p_bytes > 0) {
-
err = get_partial_data(p_buffer, p_bytes, got);
if (err != OK) {
@@ -215,7 +212,6 @@ Error StreamPeerMbedTLS::get_data(uint8_t *p_buffer, int p_bytes) {
}
Error StreamPeerMbedTLS::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r_received) {
-
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_UNCONFIGURED);
r_received = 0;
@@ -238,7 +234,6 @@ Error StreamPeerMbedTLS::get_partial_data(uint8_t *p_buffer, int p_bytes, int &r
}
void StreamPeerMbedTLS::poll() {
-
ERR_FAIL_COND(status != STATUS_CONNECTED && status != STATUS_HANDSHAKING);
ERR_FAIL_COND(!base.is_valid());
@@ -272,13 +267,12 @@ void StreamPeerMbedTLS::poll() {
}
int StreamPeerMbedTLS::get_available_bytes() const {
-
ERR_FAIL_COND_V(status != STATUS_CONNECTED, 0);
return mbedtls_ssl_get_bytes_avail(&(ssl_ctx->ssl));
}
-StreamPeerMbedTLS::StreamPeerMbedTLS() {
+StreamPeerMbedTLS::StreamPeerMbedTLS() {
ssl_ctx.instance();
status = STATUS_DISCONNECTED;
}
@@ -288,9 +282,9 @@ StreamPeerMbedTLS::~StreamPeerMbedTLS() {
}
void StreamPeerMbedTLS::disconnect_from_stream() {
-
- if (status != STATUS_CONNECTED && status != STATUS_HANDSHAKING)
+ if (status != STATUS_CONNECTED && status != STATUS_HANDSHAKING) {
return;
+ }
Ref<StreamPeerTCP> tcp = base;
if (tcp.is_valid() && tcp->get_status() == StreamPeerTCP::STATUS_CONNECTED) {
@@ -302,23 +296,19 @@ void StreamPeerMbedTLS::disconnect_from_stream() {
}
StreamPeerMbedTLS::Status StreamPeerMbedTLS::get_status() const {
-
return status;
}
StreamPeerSSL *StreamPeerMbedTLS::_create_func() {
-
return memnew(StreamPeerMbedTLS);
}
void StreamPeerMbedTLS::initialize_ssl() {
-
_create = _create_func;
available = true;
}
void StreamPeerMbedTLS::finalize_ssl() {
-
available = false;
_create = nullptr;
}
diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp
index 2f0a15f20b..a2fb443ef0 100644
--- a/modules/mobile_vr/mobile_vr_interface.cpp
+++ b/modules/mobile_vr/mobile_vr_interface.cpp
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "mobile_vr_interface.h"
-#include "core/input/input_filter.h"
+
+#include "core/input/input.h"
#include "core/os/os.h"
#include "servers/display_server.h"
#include "servers/rendering/rendering_server_globals.h"
@@ -60,13 +61,25 @@ Vector3 MobileVRInterface::scale_magneto(const Vector3 &p_magnetometer) {
};
// adjust our min and max
- if (mag_raw.x > mag_next_max.x) mag_next_max.x = mag_raw.x;
- if (mag_raw.y > mag_next_max.y) mag_next_max.y = mag_raw.y;
- if (mag_raw.z > mag_next_max.z) mag_next_max.z = mag_raw.z;
+ if (mag_raw.x > mag_next_max.x) {
+ mag_next_max.x = mag_raw.x;
+ }
+ if (mag_raw.y > mag_next_max.y) {
+ mag_next_max.y = mag_raw.y;
+ }
+ if (mag_raw.z > mag_next_max.z) {
+ mag_next_max.z = mag_raw.z;
+ }
- if (mag_raw.x < mag_next_min.x) mag_next_min.x = mag_raw.x;
- if (mag_raw.y < mag_next_min.y) mag_next_min.y = mag_raw.y;
- if (mag_raw.z < mag_next_min.z) mag_next_min.z = mag_raw.z;
+ if (mag_raw.x < mag_next_min.x) {
+ mag_next_min.x = mag_raw.x;
+ }
+ if (mag_raw.y < mag_next_min.y) {
+ mag_next_min.y = mag_raw.y;
+ }
+ if (mag_raw.z < mag_next_min.z) {
+ mag_next_min.z = mag_raw.z;
+ }
// scale our x, y and z
if (!(mag_current_max.x - mag_current_min.x)) {
@@ -118,7 +131,7 @@ void MobileVRInterface::set_position_from_sensors() {
float delta_time = (double)ticks_elapsed / 1000000.0;
// few things we need
- InputFilter *input = InputFilter::get_singleton();
+ Input *input = Input::get_singleton();
Vector3 down(0.0, -1.0, 0.0); // Down is Y negative
Vector3 north(0.0, 0.0, 1.0); // North is Z positive
@@ -435,12 +448,6 @@ void MobileVRInterface::process() {
};
};
-void MobileVRInterface::notification(int p_what){
- _THREAD_SAFE_METHOD_
-
- // nothing to do here, I guess we could pauze our sensors...
-}
-
MobileVRInterface::MobileVRInterface() {
initialized = false;
diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h
index 3a9ed1314a..e986a4a3de 100644
--- a/modules/mobile_vr/mobile_vr_interface.h
+++ b/modules/mobile_vr/mobile_vr_interface.h
@@ -142,7 +142,7 @@ public:
virtual void commit_for_eye(XRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
virtual void process();
- virtual void notification(int p_what);
+ virtual void notification(int p_what) {}
MobileVRInterface();
~MobileVRInterface();
diff --git a/modules/mono/SCsub b/modules/mono/SCsub
index c723b210cb..e8f3174a0a 100644
--- a/modules/mono/SCsub
+++ b/modules/mono/SCsub
@@ -29,7 +29,7 @@ if env_mono["tools"] or env_mono["target"] != "release":
mono_configure.configure(env, env_mono)
-if env_mono["tools"] and env_mono["mono_glue"]:
+if env_mono["tools"] and env_mono["mono_glue"] and env_mono["build_cil"]:
# Build Godot API solution
import build_scripts.api_solution_build as api_solution_build
diff --git a/modules/mono/build_scripts/godot_tools_build.py b/modules/mono/build_scripts/godot_tools_build.py
index cffacf2577..7391e8790d 100644
--- a/modules/mono/build_scripts/godot_tools_build.py
+++ b/modules/mono/build_scripts/godot_tools_build.py
@@ -13,13 +13,9 @@ def build_godot_tools(source, target, env):
solution_path = os.path.join(module_dir, "editor/GodotTools/GodotTools.sln")
build_config = "Debug" if env["target"] == "debug" else "Release"
- # Custom build target to make sure output is always copied to the data dir.
- extra_build_args = ["/Target:Build;GodotTools:BuildAlwaysCopyToDataDir"]
+ from .solution_builder import build_solution
- from .solution_builder import build_solution, nuget_restore
-
- nuget_restore(env, solution_path)
- build_solution(env, solution_path, build_config, extra_build_args)
+ build_solution(env, solution_path, build_config)
# No need to copy targets. The GodotTools csproj takes care of copying them.
diff --git a/modules/mono/build_scripts/solution_builder.py b/modules/mono/build_scripts/solution_builder.py
index db6b4ff7aa..371819fd72 100644
--- a/modules/mono/build_scripts/solution_builder.py
+++ b/modules/mono/build_scripts/solution_builder.py
@@ -4,91 +4,41 @@ import os
verbose = False
-def find_nuget_unix():
- import os
-
- if "NUGET_PATH" in os.environ:
- hint_path = os.environ["NUGET_PATH"]
- if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
- return hint_path
- hint_path = os.path.join(hint_path, "nuget")
- if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
- return hint_path
-
+def find_dotnet_cli():
import os.path
- import sys
-
- hint_dirs = ["/opt/novell/mono/bin"]
- if sys.platform == "darwin":
- hint_dirs = [
- "/Library/Frameworks/Mono.framework/Versions/Current/bin",
- "/usr/local/var/homebrew/linked/mono/bin",
- ] + hint_dirs
-
- for hint_dir in hint_dirs:
- hint_path = os.path.join(hint_dir, "nuget")
- if os.path.isfile(hint_path):
- return hint_path
- elif os.path.isfile(hint_path + ".exe"):
- return hint_path + ".exe"
-
- for hint_dir in os.environ["PATH"].split(os.pathsep):
- hint_dir = hint_dir.strip('"')
- hint_path = os.path.join(hint_dir, "nuget")
- if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
- return hint_path
- if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK):
- return hint_path + ".exe"
-
- return None
-
-
-def find_nuget_windows(env):
- import os
-
- if "NUGET_PATH" in os.environ:
- hint_path = os.environ["NUGET_PATH"]
- if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
- return hint_path
- hint_path = os.path.join(hint_path, "nuget.exe")
- if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
- return hint_path
-
- from .mono_reg_utils import find_mono_root_dir
-
- mono_root = env["mono_prefix"] or find_mono_root_dir(env["bits"])
-
- if mono_root:
- mono_bin_dir = os.path.join(mono_root, "bin")
- nuget_mono = os.path.join(mono_bin_dir, "nuget.bat")
-
- if os.path.isfile(nuget_mono):
- return nuget_mono
-
- # Standalone NuGet
- for hint_dir in os.environ["PATH"].split(os.pathsep):
- hint_dir = hint_dir.strip('"')
- hint_path = os.path.join(hint_dir, "nuget.exe")
- if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
- return hint_path
-
- return None
+ if os.name == "nt":
+ windows_exts = os.environ["PATHEXT"]
+ windows_exts = windows_exts.split(os.pathsep) if windows_exts else []
+
+ for hint_dir in os.environ["PATH"].split(os.pathsep):
+ hint_dir = hint_dir.strip('"')
+ hint_path = os.path.join(hint_dir, "dotnet")
+ if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
+ return hint_path
+ if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK):
+ return hint_path + ".exe"
+ else:
+ for hint_dir in os.environ["PATH"].split(os.pathsep):
+ hint_dir = hint_dir.strip('"')
+ hint_path = os.path.join(hint_dir, "dotnet")
+ if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
+ return hint_path
-def find_msbuild_unix(filename):
+def find_msbuild_unix():
import os.path
import sys
- hint_dirs = ["/opt/novell/mono/bin"]
+ hint_dirs = []
if sys.platform == "darwin":
- hint_dirs = [
+ hint_dirs[:0] = [
"/Library/Frameworks/Mono.framework/Versions/Current/bin",
"/usr/local/var/homebrew/linked/mono/bin",
- ] + hint_dirs
+ ]
for hint_dir in hint_dirs:
- hint_path = os.path.join(hint_dir, filename)
+ hint_path = os.path.join(hint_dir, "msbuild")
if os.path.isfile(hint_path):
return hint_path
elif os.path.isfile(hint_path + ".exe"):
@@ -96,7 +46,7 @@ def find_msbuild_unix(filename):
for hint_dir in os.environ["PATH"].split(os.pathsep):
hint_dir = hint_dir.strip('"')
- hint_path = os.path.join(hint_dir, filename)
+ hint_path = os.path.join(hint_dir, "msbuild")
if os.path.isfile(hint_path) and os.access(hint_path, os.X_OK):
return hint_path
if os.path.isfile(hint_path + ".exe") and os.access(hint_path + ".exe", os.X_OK):
@@ -158,21 +108,6 @@ def run_command(command, args, env_override=None, name=None):
raise RuntimeError("'%s' exited with error code: %s" % (name, e.returncode))
-def nuget_restore(env, *args):
- global verbose
- verbose = env["verbose"]
-
- # Find NuGet
- nuget_path = find_nuget_windows(env) if os.name == "nt" else find_nuget_unix()
- if nuget_path is None:
- raise RuntimeError("Cannot find NuGet executable")
-
- print("NuGet path: " + nuget_path)
-
- # Do NuGet restore
- run_command(nuget_path, ["restore"] + list(args), name="nuget restore")
-
-
def build_solution(env, solution_path, build_config, extra_msbuild_args=[]):
global verbose
verbose = env["verbose"]
@@ -183,38 +118,33 @@ def build_solution(env, solution_path, build_config, extra_msbuild_args=[]):
if "PLATFORM" in msbuild_env:
del msbuild_env["PLATFORM"]
- # Find MSBuild
- if os.name == "nt":
- msbuild_info = find_msbuild_windows(env)
- if msbuild_info is None:
- raise RuntimeError("Cannot find MSBuild executable")
- msbuild_path = msbuild_info[0]
- msbuild_env.update(msbuild_info[1])
- else:
- msbuild_path = find_msbuild_unix("msbuild")
- if msbuild_path is None:
- xbuild_fallback = env["xbuild_fallback"]
-
- if xbuild_fallback and os.name == "nt":
- print("Option 'xbuild_fallback' not supported on Windows")
- xbuild_fallback = False
+ msbuild_args = []
- if xbuild_fallback:
- print("Cannot find MSBuild executable, trying with xbuild")
- print("Warning: xbuild is deprecated")
+ dotnet_cli = find_dotnet_cli()
- msbuild_path = find_msbuild_unix("xbuild")
-
- if msbuild_path is None:
- raise RuntimeError("Cannot find xbuild executable")
- else:
+ if dotnet_cli:
+ msbuild_path = dotnet_cli
+ msbuild_args += ["msbuild"] # `dotnet msbuild` command
+ else:
+ # Find MSBuild
+ if os.name == "nt":
+ msbuild_info = find_msbuild_windows(env)
+ if msbuild_info is None:
+ raise RuntimeError("Cannot find MSBuild executable")
+ msbuild_path = msbuild_info[0]
+ msbuild_env.update(msbuild_info[1])
+ else:
+ msbuild_path = find_msbuild_unix()
+ if msbuild_path is None:
raise RuntimeError("Cannot find MSBuild executable")
print("MSBuild path: " + msbuild_path)
# Build solution
- msbuild_args = [solution_path, "/p:Configuration=" + build_config]
+ targets = ["Restore", "Build"]
+
+ msbuild_args += [solution_path, "/t:%s" % ",".join(targets), "/p:Configuration=" + build_config]
msbuild_args += extra_msbuild_args
run_command(msbuild_path, msbuild_args, env_override=msbuild_env, name="msbuild")
diff --git a/modules/mono/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp
index 384685d04b..39e3a95afa 100644
--- a/modules/mono/class_db_api_json.cpp
+++ b/modules/mono/class_db_api_json.cpp
@@ -45,14 +45,12 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
const StringName *k = nullptr;
while ((k = ClassDB::classes.next(k))) {
-
names.push_back(*k);
}
//must be alphabetically sorted for hash to compute
names.sort_custom<StringName::AlphCompare>();
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
-
ClassDB::ClassInfo *t = ClassDB::classes.getptr(E->get());
ERR_FAIL_COND(!t);
if (t->api != p_api || !t->exposed)
@@ -70,7 +68,6 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
k = nullptr;
while ((k = t->method_map.next(k))) {
-
String name = k->operator String();
ERR_CONTINUE(name.empty());
@@ -135,7 +132,6 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
k = nullptr;
while ((k = t->constant_map.next(k))) {
-
snames.push_back(*k);
}
@@ -163,7 +159,6 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
k = nullptr;
while ((k = t->signal_map.next(k))) {
-
snames.push_back(*k);
}
@@ -199,7 +194,6 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
k = nullptr;
while ((k = t->property_setget.next(k))) {
-
snames.push_back(*k);
}
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 106ca6e028..7980a86cb3 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -30,12 +30,12 @@ def configure(env):
)
envvars.Add(BoolVariable("mono_static", "Statically link mono", default_mono_static))
envvars.Add(BoolVariable("mono_glue", "Build with the mono glue sources", True))
+ envvars.Add(BoolVariable("build_cil", "Build C# solutions", True))
envvars.Add(
BoolVariable(
"copy_mono_root", "Make a copy of the mono installation directory to bundle with the editor", False
)
)
- envvars.Add(BoolVariable("xbuild_fallback", "If MSBuild is not found, fallback to xbuild", False))
# TODO: It would be great if this could be detected automatically instead
envvars.Add(
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index 0b5d3c8dbc..958d72adb1 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -67,7 +67,6 @@
#ifdef TOOLS_ENABLED
static bool _create_project_solution_if_needed() {
-
String sln_path = GodotSharpDirs::get_project_sln_path();
String csproj_path = GodotSharpDirs::get_project_csproj_path();
@@ -85,28 +84,23 @@ static bool _create_project_solution_if_needed() {
CSharpLanguage *CSharpLanguage::singleton = nullptr;
String CSharpLanguage::get_name() const {
-
return "C#";
}
String CSharpLanguage::get_type() const {
-
return "CSharpScript";
}
String CSharpLanguage::get_extension() const {
-
return "cs";
}
Error CSharpLanguage::execute_file(const String &p_path) {
-
// ??
return OK;
}
void CSharpLanguage::init() {
-
#ifdef DEBUG_METHODS_ENABLED
if (OS::get_singleton()->get_cmdline_args().find("--class-db-json")) {
class_db_api_to_json("user://class_db_api.json", ClassDB::API_CORE);
@@ -140,7 +134,6 @@ void CSharpLanguage::init() {
}
void CSharpLanguage::finish() {
-
if (finalized)
return;
@@ -184,7 +177,6 @@ void CSharpLanguage::finish() {
}
void CSharpLanguage::get_reserved_words(List<String> *p_words) const {
-
static const char *_reserved_words[] = {
// Reserved keywords
"abstract",
@@ -295,7 +287,7 @@ void CSharpLanguage::get_reserved_words(List<String> *p_words) const {
"when",
"where",
"yield",
- 0
+ nullptr
};
const char **w = _reserved_words;
@@ -307,13 +299,11 @@ void CSharpLanguage::get_reserved_words(List<String> *p_words) const {
}
void CSharpLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
-
p_delimiters->push_back("//"); // single-line comment
p_delimiters->push_back("/* */"); // delimited comment
}
void CSharpLanguage::get_string_delimiters(List<String> *p_delimiters) const {
-
p_delimiters->push_back("' '"); // character literal
p_delimiters->push_back("\" \""); // regular string literal
// Verbatim string literals (`@" "`) don't render correctly, so don't highlight them.
@@ -321,7 +311,6 @@ void CSharpLanguage::get_string_delimiters(List<String> *p_delimiters) const {
}
static String get_base_class_name(const String &p_base_class_name, const String p_class_name) {
-
String base_class = p_base_class_name;
if (p_class_name == base_class) {
base_class = "Godot." + base_class;
@@ -330,7 +319,6 @@ static String get_base_class_name(const String &p_base_class_name, const String
}
Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
-
String script_template = "using " BINDINGS_NAMESPACE ";\n"
"using System;\n"
"\n"
@@ -366,12 +354,10 @@ Ref<Script> CSharpLanguage::get_template(const String &p_class_name, const Strin
}
bool CSharpLanguage::is_using_templates() {
-
return true;
}
void CSharpLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
-
String src = p_script->get_source_code();
String base_class_name = get_base_class_name(p_base_class_name, p_class_name);
src = src.replace("%BASE%", base_class_name)
@@ -381,7 +367,6 @@ void CSharpLanguage::make_template(const String &p_class_name, const String &p_b
}
String CSharpLanguage::validate_path(const String &p_path) const {
-
String class_name = p_path.get_file().get_basename();
List<String> keywords;
get_reserved_words(&keywords);
@@ -392,23 +377,19 @@ String CSharpLanguage::validate_path(const String &p_path) const {
}
Script *CSharpLanguage::create_script() const {
-
return memnew(CSharpScript);
}
bool CSharpLanguage::has_named_classes() const {
-
return false;
}
bool CSharpLanguage::supports_builtin_mode() const {
-
return false;
}
#ifdef TOOLS_ENABLED
static String variant_type_to_managed_name(const String &p_var_type_name) {
-
if (p_var_type_name.empty())
return "object";
@@ -531,12 +512,10 @@ String CSharpLanguage::_get_indentation() const {
}
String CSharpLanguage::debug_get_error() const {
-
return _debug_error;
}
int CSharpLanguage::debug_get_stack_level_count() const {
-
if (_debug_parse_err_line >= 0)
return 1;
@@ -545,7 +524,6 @@ int CSharpLanguage::debug_get_stack_level_count() const {
}
int CSharpLanguage::debug_get_stack_level_line(int p_level) const {
-
if (_debug_parse_err_line >= 0)
return _debug_parse_err_line;
@@ -554,7 +532,6 @@ int CSharpLanguage::debug_get_stack_level_line(int p_level) const {
}
String CSharpLanguage::debug_get_stack_level_function(int p_level) const {
-
if (_debug_parse_err_line >= 0)
return String();
@@ -563,7 +540,6 @@ String CSharpLanguage::debug_get_stack_level_function(int p_level) const {
}
String CSharpLanguage::debug_get_stack_level_source(int p_level) const {
-
if (_debug_parse_err_line >= 0)
return _debug_parse_err_file;
@@ -572,7 +548,6 @@ String CSharpLanguage::debug_get_stack_level_source(int p_level) const {
}
Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info() {
-
#ifdef DEBUG_ENABLED
// Printing an error here will result in endless recursion, so we must be careful
static thread_local bool _recursion_flag_ = false;
@@ -604,7 +579,6 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info()
#ifdef DEBUG_ENABLED
Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObject *p_stack_trace) {
-
// Printing an error here will result in endless recursion, so we must be careful
static thread_local bool _recursion_flag_ = false;
if (_recursion_flag_)
@@ -678,7 +652,6 @@ void CSharpLanguage::pre_unsafe_unreference(Object *p_obj) {
}
void CSharpLanguage::frame() {
-
if (gdmono && gdmono->is_runtime_initialized() && gdmono->get_core_api_assembly() != nullptr) {
const Ref<MonoGCHandleRef> &task_scheduler_handle = GDMonoCache::cached_data.task_scheduler_handle;
@@ -698,7 +671,6 @@ void CSharpLanguage::frame() {
}
struct CSharpScriptDepSort {
-
// must support sorting so inheritance works properly (parent must be reloaded first)
bool operator()(const Ref<CSharpScript> &A, const Ref<CSharpScript> &B) const {
if (A == B)
@@ -718,7 +690,6 @@ struct CSharpScriptDepSort {
};
void CSharpLanguage::reload_all_scripts() {
-
#ifdef GD_MONO_HOT_RELOAD
if (is_assembly_reloading_needed()) {
GD_MONO_SCOPE_THREAD_ATTACH;
@@ -728,7 +699,6 @@ void CSharpLanguage::reload_all_scripts() {
}
void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) {
-
(void)p_script; // UNUSED
CRASH_COND(!Engine::get_singleton()->is_editor_hint());
@@ -747,7 +717,6 @@ void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft
#ifdef GD_MONO_HOT_RELOAD
bool CSharpLanguage::is_assembly_reloading_needed() {
-
if (!gdmono->is_runtime_initialized())
return false;
@@ -782,7 +751,6 @@ bool CSharpLanguage::is_assembly_reloading_needed() {
}
void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
-
if (!gdmono->is_runtime_initialized())
return;
@@ -850,7 +818,7 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
to_reload.push_back(script);
if (script->get_path().empty()) {
- script->tied_class_name_for_reload = script->script_class->get_name();
+ script->tied_class_name_for_reload = script->script_class->get_name_for_lookup();
script->tied_class_namespace_for_reload = script->script_class->get_namespace();
}
@@ -1173,7 +1141,6 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) {
#endif
void CSharpLanguage::_load_scripts_metadata() {
-
scripts_metadata.clear();
String scripts_metadata_filename = "scripts_metadata.";
@@ -1218,24 +1185,20 @@ void CSharpLanguage::_load_scripts_metadata() {
}
void CSharpLanguage::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("cs");
}
#ifdef TOOLS_ENABLED
Error CSharpLanguage::open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) {
-
return (Error)(int)get_godotsharp_editor()->call("OpenInExternalEditor", p_script, p_line, p_col);
}
bool CSharpLanguage::overrides_external_editor() {
-
return get_godotsharp_editor()->call("OverridesExternalEditor");
}
#endif
void CSharpLanguage::thread_enter() {
-
#if 0
if (gdmono->is_runtime_initialized()) {
GDMonoUtils::attach_current_thread();
@@ -1244,7 +1207,6 @@ void CSharpLanguage::thread_enter() {
}
void CSharpLanguage::thread_exit() {
-
#if 0
if (gdmono->is_runtime_initialized()) {
GDMonoUtils::detach_current_thread();
@@ -1253,7 +1215,6 @@ void CSharpLanguage::thread_exit() {
}
bool CSharpLanguage::debug_break_parse(const String &p_file, int p_line, const String &p_error) {
-
// Not a parser error in our case, but it's still used for other type of errors
if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
_debug_parse_err_line = p_line;
@@ -1267,7 +1228,6 @@ bool CSharpLanguage::debug_break_parse(const String &p_file, int p_line, const S
}
bool CSharpLanguage::debug_break(const String &p_error, bool p_allow_continue) {
-
if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
_debug_parse_err_line = -1;
_debug_parse_err_file = "";
@@ -1301,7 +1261,6 @@ void CSharpLanguage::_on_scripts_domain_unloaded() {
#ifdef TOOLS_ENABLED
void CSharpLanguage::_editor_init_callback() {
-
register_editor_internal_calls();
// Initialize GodotSharpEditor
@@ -1328,13 +1287,11 @@ void CSharpLanguage::_editor_init_callback() {
#endif
void CSharpLanguage::set_language_index(int p_idx) {
-
ERR_FAIL_COND(lang_idx != -1);
lang_idx = p_idx;
}
void CSharpLanguage::release_script_gchandle(MonoGCHandleData &p_gchandle) {
-
if (!p_gchandle.is_released()) { // Do not lock unnecessarily
MutexLock lock(get_singleton()->script_gchandle_release_mutex);
p_gchandle.release();
@@ -1342,7 +1299,6 @@ void CSharpLanguage::release_script_gchandle(MonoGCHandleData &p_gchandle) {
}
void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, MonoGCHandleData &p_gchandle) {
-
uint32_t pinned_gchandle = GDMonoUtils::new_strong_gchandle_pinned(p_expected_obj); // We might lock after this, so pin it
if (!p_gchandle.is_released()) { // Do not lock unnecessarily
@@ -1363,19 +1319,16 @@ void CSharpLanguage::release_script_gchandle(MonoObject *p_expected_obj, MonoGCH
}
CSharpLanguage::CSharpLanguage() {
-
ERR_FAIL_COND_MSG(singleton, "C# singleton already exist.");
singleton = this;
}
CSharpLanguage::~CSharpLanguage() {
-
finish();
singleton = nullptr;
}
bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_binding, Object *p_object) {
-
#ifdef DEBUG_ENABLED
// I don't trust you
if (p_object->get_script_instance()) {
@@ -1424,7 +1377,6 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b
}
void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
-
MutexLock lock(language_bind_mutex);
Map<Object *, CSharpScriptBinding>::Element *match = script_bindings.find(p_object);
@@ -1440,12 +1392,10 @@ void *CSharpLanguage::alloc_instance_binding_data(Object *p_object) {
}
Map<Object *, CSharpScriptBinding>::Element *CSharpLanguage::insert_script_binding(Object *p_object, const CSharpScriptBinding &p_script_binding) {
-
return script_bindings.insert(p_object, p_script_binding);
}
void CSharpLanguage::free_instance_binding_data(void *p_data) {
-
if (GDMono::get_singleton() == nullptr) {
#ifdef DEBUG_ENABLED
CRASH_COND(!script_bindings.empty());
@@ -1481,7 +1431,6 @@ void CSharpLanguage::free_instance_binding_data(void *p_data) {
}
void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
-
Reference *ref_owner = Object::cast_to<Reference>(p_object);
#ifdef DEBUG_ENABLED
@@ -1517,7 +1466,6 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) {
}
bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
-
Reference *ref_owner = Object::cast_to<Reference>(p_object);
#ifdef DEBUG_ENABLED
@@ -1558,7 +1506,6 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) {
}
CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpScript *p_script, const MonoGCHandleData &p_gchandle) {
-
CSharpInstance *instance = memnew(CSharpInstance(Ref<CSharpScript>(p_script)));
Reference *ref = Object::cast_to<Reference>(p_owner);
@@ -1576,7 +1523,6 @@ CSharpInstance *CSharpInstance::create_for_managed_type(Object *p_owner, CSharpS
}
MonoObject *CSharpInstance::get_mono_object() const {
-
ERR_FAIL_COND_V(gchandle.is_released(), nullptr);
return gchandle.get_target();
}
@@ -1586,7 +1532,6 @@ Object *CSharpInstance::get_owner() {
}
bool CSharpInstance::set(const StringName &p_name, const Variant &p_value) {
-
ERR_FAIL_COND_V(!script.is_valid(), false);
GD_MONO_SCOPE_THREAD_ATTACH;
@@ -1640,7 +1585,6 @@ bool CSharpInstance::set(const StringName &p_name, const Variant &p_value) {
}
bool CSharpInstance::get(const StringName &p_name, Variant &r_ret) const {
-
ERR_FAIL_COND_V(!script.is_valid(), false);
GD_MONO_SCOPE_THREAD_ATTACH;
@@ -1704,7 +1648,6 @@ bool CSharpInstance::get(const StringName &p_name, Variant &r_ret) const {
}
void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Variant>> &r_state) {
-
List<PropertyInfo> pinfo;
get_property_list(&pinfo);
@@ -1729,7 +1672,6 @@ void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Va
}
void CSharpInstance::get_event_signals_state_for_reloading(List<Pair<StringName, Array>> &r_state) {
-
MonoObject *owner_managed = get_mono_object();
ERR_FAIL_NULL(owner_managed);
@@ -1760,7 +1702,6 @@ void CSharpInstance::get_event_signals_state_for_reloading(List<Pair<StringName,
}
void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
-
for (Map<StringName, PropertyInfo>::Element *E = script->member_info.front(); E; E = E->next()) {
p_properties->push_back(E->value());
}
@@ -1797,7 +1738,6 @@ void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const {
}
Variant::Type CSharpInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
-
if (script->member_info.has(p_name)) {
if (r_is_valid)
*r_is_valid = true;
@@ -1811,7 +1751,6 @@ Variant::Type CSharpInstance::get_property_type(const StringName &p_name, bool *
}
bool CSharpInstance::has_method(const StringName &p_method) const {
-
if (!script.is_valid())
return false;
@@ -1831,7 +1770,6 @@ bool CSharpInstance::has_method(const StringName &p_method) const {
}
Variant CSharpInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
ERR_FAIL_COND_V(!script.is_valid(), Variant());
GD_MONO_SCOPE_THREAD_ATTACH;
@@ -1869,7 +1807,6 @@ Variant CSharpInstance::call(const StringName &p_method, const Variant **p_args,
}
void CSharpInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) {
-
GD_MONO_SCOPE_THREAD_ATTACH;
if (script.is_valid()) {
@@ -1882,7 +1819,6 @@ void CSharpInstance::call_multilevel(const StringName &p_method, const Variant *
}
void CSharpInstance::_call_multilevel(MonoObject *p_mono_object, const StringName &p_method, const Variant **p_args, int p_argcount) {
-
GD_MONO_ASSERT_THREAD_ATTACHED;
GDMonoClass *top = script->script_class;
@@ -1900,14 +1836,12 @@ void CSharpInstance::_call_multilevel(MonoObject *p_mono_object, const StringNam
}
void CSharpInstance::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) {
-
// Sorry, the method is the one that controls the call order
call_multilevel(p_method, p_args, p_argcount);
}
bool CSharpInstance::_reference_owner_unsafe() {
-
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
CRASH_COND(owner == nullptr);
@@ -1929,7 +1863,6 @@ bool CSharpInstance::_reference_owner_unsafe() {
}
bool CSharpInstance::_unreference_owner_unsafe() {
-
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
CRASH_COND(owner == nullptr);
@@ -1991,7 +1924,6 @@ MonoObject *CSharpInstance::_internal_new_managed() {
}
void CSharpInstance::mono_object_disposed(MonoObject *p_obj) {
-
disconnect_event_signals();
#ifdef DEBUG_ENABLED
@@ -2002,7 +1934,6 @@ void CSharpInstance::mono_object_disposed(MonoObject *p_obj) {
}
void CSharpInstance::mono_object_disposed_baseref(MonoObject *p_obj, bool p_is_finalizer, bool &r_delete_owner, bool &r_remove_script_instance) {
-
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
CRASH_COND(gchandle.is_released());
@@ -2063,7 +1994,6 @@ void CSharpInstance::disconnect_event_signals() {
}
void CSharpInstance::refcount_incremented() {
-
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
CRASH_COND(owner == nullptr);
@@ -2086,7 +2016,6 @@ void CSharpInstance::refcount_incremented() {
}
bool CSharpInstance::refcount_decremented() {
-
#ifdef DEBUG_ENABLED
CRASH_COND(!base_ref);
CRASH_COND(owner == nullptr);
@@ -2156,7 +2085,6 @@ MultiplayerAPI::RPCMode CSharpInstance::get_rset_mode(const StringName &p_variab
}
void CSharpInstance::notification(int p_notification) {
-
GD_MONO_SCOPE_THREAD_ATTACH;
if (p_notification == Object::NOTIFICATION_PREDELETE) {
@@ -2195,7 +2123,6 @@ void CSharpInstance::notification(int p_notification) {
}
void CSharpInstance::_call_notification(int p_notification) {
-
GD_MONO_ASSERT_THREAD_ATTACHED;
MonoObject *mono_object = get_mono_object();
@@ -2252,12 +2179,10 @@ String CSharpInstance::to_string(bool *r_valid) {
}
Ref<Script> CSharpInstance::get_script() const {
-
return script;
}
ScriptLanguage *CSharpInstance::get_language() {
-
return CSharpLanguage::get_singleton();
}
@@ -2266,7 +2191,6 @@ CSharpInstance::CSharpInstance(const Ref<CSharpScript> &p_script) :
}
CSharpInstance::~CSharpInstance() {
-
GD_MONO_SCOPE_THREAD_ATTACH;
destructing_script_instance = true;
@@ -2348,14 +2272,12 @@ CSharpInstance::~CSharpInstance() {
#ifdef TOOLS_ENABLED
void CSharpScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {
-
placeholders.erase(p_placeholder);
}
#endif
#ifdef TOOLS_ENABLED
void CSharpScript::_update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames) {
-
if (base_cache.is_valid()) {
base_cache->_update_exports_values(values, propnames);
}
@@ -2370,7 +2292,6 @@ void CSharpScript::_update_exports_values(Map<StringName, Variant> &values, List
}
void CSharpScript::_update_member_info_no_exports() {
-
if (exports_invalidated) {
GD_MONO_ASSERT_THREAD_ATTACHED;
@@ -2419,60 +2340,69 @@ void CSharpScript::_update_member_info_no_exports() {
#endif
bool CSharpScript::_update_exports() {
-
#ifdef TOOLS_ENABLED
- if (!Engine::get_singleton()->is_editor_hint())
- return false;
-
- placeholder_fallback_enabled = true; // until proven otherwise
-
+ bool is_editor = Engine::get_singleton()->is_editor_hint();
+ if (is_editor)
+ placeholder_fallback_enabled = true; // until proven otherwise
+#endif
if (!valid)
return false;
bool changed = false;
- if (exports_invalidated) {
+#ifdef TOOLS_ENABLED
+ if (exports_invalidated)
+#endif
+ {
GD_MONO_SCOPE_THREAD_ATTACH;
- exports_invalidated = false;
-
changed = true;
member_info.clear();
- exported_members_cache.clear();
- exported_members_defval_cache.clear();
- // Here we create a temporary managed instance of the class to get the initial values
+#ifdef TOOLS_ENABLED
+ MonoObject *tmp_object = nullptr;
+ Object *tmp_native = nullptr;
+ uint32_t tmp_pinned_gchandle = 0;
- MonoObject *tmp_object = mono_object_new(mono_domain_get(), script_class->get_mono_ptr());
+ if (is_editor) {
+ exports_invalidated = false;
- if (!tmp_object) {
- ERR_PRINT("Failed to allocate temporary MonoObject.");
- return false;
- }
+ exported_members_cache.clear();
+ exported_members_defval_cache.clear();
- uint32_t tmp_pinned_gchandle = GDMonoUtils::new_strong_gchandle_pinned(tmp_object); // pin it (not sure if needed)
+ // Here we create a temporary managed instance of the class to get the initial values
+ tmp_object = mono_object_new(mono_domain_get(), script_class->get_mono_ptr());
- GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
+ if (!tmp_object) {
+ ERR_PRINT("Failed to allocate temporary MonoObject.");
+ return false;
+ }
- ERR_FAIL_NULL_V_MSG(ctor, false,
- "Cannot construct temporary MonoObject because the class does not define a parameterless constructor: '" + get_path() + "'.");
+ tmp_pinned_gchandle = GDMonoUtils::new_strong_gchandle_pinned(tmp_object); // pin it (not sure if needed)
- MonoException *ctor_exc = nullptr;
- ctor->invoke(tmp_object, nullptr, &ctor_exc);
+ GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), 0);
- Object *tmp_native = GDMonoMarshal::unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(tmp_object));
+ ERR_FAIL_NULL_V_MSG(ctor, false,
+ "Cannot construct temporary MonoObject because the class does not define a parameterless constructor: '" + get_path() + "'.");
- if (ctor_exc) {
- // TODO: Should we free 'tmp_native' if the exception was thrown after its creation?
+ MonoException *ctor_exc = nullptr;
+ ctor->invoke(tmp_object, nullptr, &ctor_exc);
- GDMonoUtils::free_gchandle(tmp_pinned_gchandle);
- tmp_object = nullptr;
+ tmp_native = GDMonoMarshal::unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(tmp_object));
- ERR_PRINT("Exception thrown from constructor of temporary MonoObject:");
- GDMonoUtils::debug_print_unhandled_exception(ctor_exc);
- return false;
+ if (ctor_exc) {
+ // TODO: Should we free 'tmp_native' if the exception was thrown after its creation?
+
+ GDMonoUtils::free_gchandle(tmp_pinned_gchandle);
+ tmp_object = nullptr;
+
+ ERR_PRINT("Exception thrown from constructor of temporary MonoObject:");
+ GDMonoUtils::debug_print_unhandled_exception(ctor_exc);
+ return false;
+ }
}
+#endif
GDMonoClass *top = script_class;
@@ -2488,15 +2418,22 @@ bool CSharpScript::_update_exports() {
if (_get_member_export(field, /* inspect export: */ true, prop_info, exported)) {
StringName member_name = field->get_name();
+ member_info[member_name] = prop_info;
+
if (exported) {
- member_info[member_name] = prop_info;
- exported_members_cache.push_front(prop_info);
+#ifdef TOOLS_ENABLED
+ if (is_editor) {
+ exported_members_cache.push_front(prop_info);
- if (tmp_object) {
- exported_members_defval_cache[member_name] = GDMonoMarshal::mono_object_to_variant(field->get_value(tmp_object));
+ if (tmp_object) {
+ exported_members_defval_cache[member_name] = GDMonoMarshal::mono_object_to_variant(field->get_value(tmp_object));
+ }
}
- } else {
- member_info[member_name] = prop_info;
+#endif
+
+#if defined(TOOLS_ENABLED) || defined(DEBUG_ENABLED)
+ exported_members_names.insert(member_name);
+#endif
}
}
}
@@ -2509,22 +2446,28 @@ bool CSharpScript::_update_exports() {
if (_get_member_export(property, /* inspect export: */ true, prop_info, exported)) {
StringName member_name = property->get_name();
+ member_info[member_name] = prop_info;
+
if (exported) {
- member_info[member_name] = prop_info;
- exported_members_cache.push_front(prop_info);
-
- if (tmp_object) {
- MonoException *exc = nullptr;
- MonoObject *ret = property->get_value(tmp_object, &exc);
- if (exc) {
- exported_members_defval_cache[member_name] = Variant();
- GDMonoUtils::debug_print_unhandled_exception(exc);
- } else {
- exported_members_defval_cache[member_name] = GDMonoMarshal::mono_object_to_variant(ret);
+#ifdef TOOLS_ENABLED
+ if (is_editor) {
+ exported_members_cache.push_front(prop_info);
+ if (tmp_object) {
+ MonoException *exc = nullptr;
+ MonoObject *ret = property->get_value(tmp_object, &exc);
+ if (exc) {
+ exported_members_defval_cache[member_name] = Variant();
+ GDMonoUtils::debug_print_unhandled_exception(exc);
+ } else {
+ exported_members_defval_cache[member_name] = GDMonoMarshal::mono_object_to_variant(ret);
+ }
}
}
- } else {
- member_info[member_name] = prop_info;
+#endif
+
+#if defined(TOOLS_ENABLED) || defined(DEBUG_ENABLED)
+ exported_members_names.insert(member_name);
+#endif
}
}
}
@@ -2532,52 +2475,57 @@ bool CSharpScript::_update_exports() {
top = top->get_parent_class();
}
- // Need to check this here, before disposal
- bool base_ref = Object::cast_to<Reference>(tmp_native) != nullptr;
+#ifdef TOOLS_ENABLED
+ if (is_editor) {
+ // Need to check this here, before disposal
+ bool base_ref = Object::cast_to<Reference>(tmp_native) != nullptr;
- // Dispose the temporary managed instance
+ // Dispose the temporary managed instance
- MonoException *exc = nullptr;
- GDMonoUtils::dispose(tmp_object, &exc);
+ MonoException *exc = nullptr;
+ GDMonoUtils::dispose(tmp_object, &exc);
- if (exc) {
- ERR_PRINT("Exception thrown from method Dispose() of temporary MonoObject:");
- GDMonoUtils::debug_print_unhandled_exception(exc);
- }
+ if (exc) {
+ ERR_PRINT("Exception thrown from method Dispose() of temporary MonoObject:");
+ GDMonoUtils::debug_print_unhandled_exception(exc);
+ }
- GDMonoUtils::free_gchandle(tmp_pinned_gchandle);
- tmp_object = nullptr;
+ GDMonoUtils::free_gchandle(tmp_pinned_gchandle);
+ tmp_object = nullptr;
- if (tmp_native && !base_ref) {
- Node *node = Object::cast_to<Node>(tmp_native);
- if (node && node->is_inside_tree()) {
- ERR_PRINT("Temporary instance was added to the scene tree.");
- } else {
- memdelete(tmp_native);
+ if (tmp_native && !base_ref) {
+ Node *node = Object::cast_to<Node>(tmp_native);
+ if (node && node->is_inside_tree()) {
+ ERR_PRINT("Temporary instance was added to the scene tree.");
+ } else {
+ memdelete(tmp_native);
+ }
}
}
+#endif
}
- placeholder_fallback_enabled = false;
+#ifdef TOOLS_ENABLED
+ if (is_editor) {
+ placeholder_fallback_enabled = false;
- if (placeholders.size()) {
- // Update placeholders if any
- Map<StringName, Variant> values;
- List<PropertyInfo> propnames;
- _update_exports_values(values, propnames);
+ if (placeholders.size()) {
+ // Update placeholders if any
+ Map<StringName, Variant> values;
+ List<PropertyInfo> propnames;
+ _update_exports_values(values, propnames);
- for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
- E->get()->update(propnames, values);
+ for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
+ E->get()->update(propnames, values);
+ }
}
}
+#endif
return changed;
-#endif
- return false;
}
void CSharpScript::load_script_signals(GDMonoClass *p_class, GDMonoClass *p_native_class) {
-
// no need to load the script's signals more than once
if (!signals_invalidated) {
return;
@@ -2679,13 +2627,11 @@ bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoMethod *p_delegate_in
return true;
}
-#ifdef TOOLS_ENABLED
/**
* Returns false if there was an error, otherwise true.
* If there was an error, r_prop_info and r_exported are not assigned any value.
*/
bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect_export, PropertyInfo &r_prop_info, bool &r_exported) {
-
GD_MONO_ASSERT_THREAD_ATTACHED;
// Goddammit, C++. All I wanted was some nested functions.
@@ -2693,8 +2639,10 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
(m_member->get_enclosing_class()->get_full_name() + "." + (String)m_member->get_name())
if (p_member->is_static()) {
+#ifdef TOOLS_ENABLED
if (p_member->has_attribute(CACHED_CLASS(ExportAttribute)))
ERR_PRINT("Cannot export member because it is static: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
+#endif
return false;
}
@@ -2716,13 +2664,17 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
if (p_member->get_member_type() == IMonoClassMember::MEMBER_TYPE_PROPERTY) {
GDMonoProperty *property = static_cast<GDMonoProperty *>(p_member);
if (!property->has_getter()) {
+#ifdef TOOLS_ENABLED
if (exported)
ERR_PRINT("Read-only property cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
+#endif
return false;
}
if (!property->has_setter()) {
+#ifdef TOOLS_ENABLED
if (exported)
ERR_PRINT("Write-only property (without getter) cannot be exported: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
+#endif
return false;
}
}
@@ -2742,10 +2694,13 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
String hint_string;
if (variant_type == Variant::NIL && !nil_is_variant) {
+#ifdef TOOLS_ENABLED
ERR_PRINT("Unknown exported member type: '" + MEMBER_FULL_QUALIFIED_NAME(p_member) + "'.");
+#endif
return false;
}
+#ifdef TOOLS_ENABLED
int hint_res = _try_get_member_export_hint(p_member, type, variant_type, /* allow_generics: */ true, hint, hint_string);
ERR_FAIL_COND_V_MSG(hint_res == -1, false,
@@ -2756,6 +2711,7 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
hint = PropertyHint(CACHED_FIELD(ExportAttribute, hint)->get_int_value(attr));
hint_string = CACHED_FIELD(ExportAttribute, hintString)->get_string_value(attr);
}
+#endif
uint32_t prop_usage = PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE;
@@ -2772,8 +2728,8 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect
#undef MEMBER_FULL_QUALIFIED_NAME
}
+#ifdef TOOLS_ENABLED
int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, ManagedType p_type, Variant::Type p_variant_type, bool p_allow_generics, PropertyHint &r_hint, String &r_hint_string) {
-
if (p_variant_type == Variant::NIL) {
// System.Object (Variant)
return 1;
@@ -2873,7 +2829,6 @@ int CSharpScript::_try_get_member_export_hint(IMonoClassMember *p_member, Manage
#endif
void CSharpScript::_clear() {
-
tool = false;
valid = false;
@@ -2883,7 +2838,6 @@ void CSharpScript::_clear() {
}
Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (unlikely(GDMono::get_singleton() == nullptr)) {
// Probably not the best error but eh.
r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
@@ -2915,7 +2869,6 @@ Variant CSharpScript::call(const StringName &p_method, const Variant **p_args, i
}
void CSharpScript::_resource_path_changed() {
-
String path = get_path();
if (!path.empty()) {
@@ -2924,9 +2877,7 @@ void CSharpScript::_resource_path_changed() {
}
bool CSharpScript::_get(const StringName &p_name, Variant &r_ret) const {
-
if (p_name == CSharpLanguage::singleton->string_names._script_source) {
-
r_ret = get_source_code();
return true;
}
@@ -2935,9 +2886,7 @@ bool CSharpScript::_get(const StringName &p_name, Variant &r_ret) const {
}
bool CSharpScript::_set(const StringName &p_name, const Variant &p_value) {
-
if (p_name == CSharpLanguage::singleton->string_names._script_source) {
-
set_source_code(p_value);
reload();
return true;
@@ -2947,17 +2896,14 @@ bool CSharpScript::_set(const StringName &p_name, const Variant &p_value) {
}
void CSharpScript::_get_property_list(List<PropertyInfo> *p_properties) const {
-
p_properties->push_back(PropertyInfo(Variant::STRING, CSharpLanguage::singleton->string_names._script_source, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
}
void CSharpScript::_bind_methods() {
-
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "new", &CSharpScript::_new, MethodInfo("new"));
}
Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native) {
-
// This method should not fail, only assertions allowed
CRASH_COND(p_class == nullptr);
@@ -2971,7 +2917,6 @@ Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GD
}
void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native) {
-
// This method should not fail, only assertions allowed
CRASH_COND(p_class == nullptr);
@@ -3035,7 +2980,6 @@ void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMon
}
bool CSharpScript::can_instance() const {
-
#ifdef TOOLS_ENABLED
bool extra_cond = tool || ScriptServer::is_scripting_enabled();
#else
@@ -3059,7 +3003,6 @@ bool CSharpScript::can_instance() const {
}
StringName CSharpScript::get_instance_base_type() const {
-
if (native)
return native->get_name();
else
@@ -3067,7 +3010,6 @@ StringName CSharpScript::get_instance_base_type() const {
}
CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) {
-
GD_MONO_ASSERT_THREAD_ATTACHED;
/* STEP 1, CREATE */
@@ -3157,7 +3099,6 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg
}
Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (!valid) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
return Variant();
@@ -3193,7 +3134,6 @@ Variant CSharpScript::_new(const Variant **p_args, int p_argcount, Callable::Cal
}
ScriptInstance *CSharpScript::instance_create(Object *p_this) {
-
#ifdef DEBUG_ENABLED
CRASH_COND(!valid);
#endif
@@ -3218,7 +3158,6 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) {
}
PlaceHolderScriptInstance *CSharpScript::placeholder_instance_create(Object *p_this) {
-
#ifdef TOOLS_ENABLED
PlaceHolderScriptInstance *si = memnew(PlaceHolderScriptInstance(CSharpLanguage::get_singleton(), Ref<Script>(this), p_this));
placeholders.insert(si);
@@ -3230,23 +3169,19 @@ PlaceHolderScriptInstance *CSharpScript::placeholder_instance_create(Object *p_t
}
bool CSharpScript::instance_has(const Object *p_this) const {
-
MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
return instances.has((Object *)p_this);
}
bool CSharpScript::has_source_code() const {
-
return !source.empty();
}
String CSharpScript::get_source_code() const {
-
return source;
}
void CSharpScript::set_source_code(const String &p_code) {
-
if (source == p_code)
return;
source = p_code;
@@ -3256,7 +3191,6 @@ void CSharpScript::set_source_code(const String &p_code) {
}
void CSharpScript::get_script_method_list(List<MethodInfo> *p_list) const {
-
if (!script_class)
return;
@@ -3270,7 +3204,6 @@ void CSharpScript::get_script_method_list(List<MethodInfo> *p_list) const {
}
bool CSharpScript::has_method(const StringName &p_method) const {
-
if (!script_class)
return false;
@@ -3280,7 +3213,6 @@ bool CSharpScript::has_method(const StringName &p_method) const {
}
MethodInfo CSharpScript::get_method_info(const StringName &p_method) const {
-
if (!script_class)
return MethodInfo();
@@ -3301,7 +3233,6 @@ MethodInfo CSharpScript::get_method_info(const StringName &p_method) const {
}
Error CSharpScript::reload(bool p_keep_state) {
-
bool has_instances;
{
MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
@@ -3323,9 +3254,7 @@ Error CSharpScript::reload(bool p_keep_state) {
ERR_FAIL_NULL_V(namespace_, ERR_BUG);
ERR_FAIL_NULL_V(class_name, ERR_BUG);
GDMonoClass *klass = project_assembly->get_class(namespace_->operator String(), class_name->operator String());
- if (klass) {
- bool obj_type = CACHED_CLASS(GodotObject)->is_assignable_from(klass);
- ERR_FAIL_COND_V(!obj_type, ERR_BUG);
+ if (klass && CACHED_CLASS(GodotObject)->is_assignable_from(klass)) {
script_class = klass;
}
} else {
@@ -3463,12 +3392,10 @@ Error CSharpScript::reload(bool p_keep_state) {
}
ScriptLanguage *CSharpScript::get_language() const {
-
return CSharpLanguage::get_singleton();
}
bool CSharpScript::get_property_default_value(const StringName &p_property, Variant &r_value) const {
-
#ifdef TOOLS_ENABLED
const Map<StringName, Variant>::Element *E = exported_members_defval_cache.find(p_property);
@@ -3486,7 +3413,6 @@ bool CSharpScript::get_property_default_value(const StringName &p_property, Vari
}
void CSharpScript::update_exports() {
-
#ifdef TOOLS_ENABLED
_update_exports();
#endif
@@ -3497,7 +3423,6 @@ bool CSharpScript::has_script_signal(const StringName &p_signal) const {
}
void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
-
for (const Map<StringName, Vector<SignalParameter>>::Element *E = _signals.front(); E; E = E->next()) {
MethodInfo mi;
mi.name = E->key();
@@ -3536,27 +3461,40 @@ void CSharpScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
}
}
-Ref<Script> CSharpScript::get_base_script() const {
+bool CSharpScript::inherits_script(const Ref<Script> &p_script) const {
+ Ref<CSharpScript> cs = p_script;
+ if (cs.is_null()) {
+ return false;
+ }
+
+ if (script_class == nullptr || cs->script_class == nullptr) {
+ return false;
+ }
+ if (script_class == cs->script_class) {
+ return true;
+ }
+
+ return cs->script_class->is_assignable_from(script_class);
+}
+
+Ref<Script> CSharpScript::get_base_script() const {
// TODO search in metadata file once we have it, not important any way?
return Ref<Script>();
}
void CSharpScript::get_script_property_list(List<PropertyInfo> *p_list) const {
-
for (Map<StringName, PropertyInfo>::Element *E = member_info.front(); E; E = E->next()) {
p_list->push_back(E->value());
}
}
int CSharpScript::get_member_line(const StringName &p_member) const {
-
// TODO omnisharp
return -1;
}
MultiplayerAPI::RPCMode CSharpScript::_member_get_rpc_mode(IMonoClassMember *p_member) const {
-
if (p_member->has_attribute(CACHED_CLASS(RemoteAttribute)))
return MultiplayerAPI::RPC_MODE_REMOTE;
if (p_member->has_attribute(CACHED_CLASS(MasterAttribute)))
@@ -3628,7 +3566,6 @@ MultiplayerAPI::RPCMode CSharpScript::get_rset_mode(const StringName &p_variable
}
Error CSharpScript::load_source_code(const String &p_path) {
-
Error ferr = read_all_file_utf8(p_path, source);
ERR_FAIL_COND_V_MSG(ferr != OK, ferr,
@@ -3645,12 +3582,10 @@ Error CSharpScript::load_source_code(const String &p_path) {
}
StringName CSharpScript::get_script_name() const {
-
return name;
}
CSharpScript::CSharpScript() {
-
_clear();
_resource_path_changed();
@@ -3664,17 +3599,25 @@ CSharpScript::CSharpScript() {
}
CSharpScript::~CSharpScript() {
-
#ifdef DEBUG_ENABLED
MutexLock lock(CSharpLanguage::get_singleton()->script_instances_mutex);
CSharpLanguage::get_singleton()->script_list.remove(&this->script_list);
#endif
}
-/*************** RESOURCE ***************/
+void CSharpScript::get_members(Set<StringName> *p_members) {
+#if defined(TOOLS_ENABLED) || defined(DEBUG_ENABLED)
+ if (p_members) {
+ for (Set<StringName>::Element *E = exported_members_names.front(); E; E = E->next()) {
+ p_members->insert(E->get());
+ }
+ }
+#endif
+}
-RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+/*************** RESOURCE ***************/
+RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
if (r_error)
*r_error = ERR_FILE_CANT_OPEN;
@@ -3700,22 +3643,18 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p
}
void ResourceFormatLoaderCSharpScript::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("cs");
}
bool ResourceFormatLoaderCSharpScript::handles_type(const String &p_type) const {
-
return p_type == "Script" || p_type == CSharpLanguage::get_singleton()->get_type();
}
String ResourceFormatLoaderCSharpScript::get_resource_type(const String &p_path) const {
-
return p_path.get_extension().to_lower() == "cs" ? CSharpLanguage::get_singleton()->get_type() : "";
}
Error ResourceFormatSaverCSharpScript::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
Ref<CSharpScript> sqscr = p_resource;
ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER);
@@ -3759,19 +3698,16 @@ Error ResourceFormatSaverCSharpScript::save(const String &p_path, const RES &p_r
}
void ResourceFormatSaverCSharpScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
-
if (Object::cast_to<CSharpScript>(p_resource.ptr())) {
p_extensions->push_back("cs");
}
}
bool ResourceFormatSaverCSharpScript::recognize(const RES &p_resource) const {
-
return Object::cast_to<CSharpScript>(p_resource.ptr()) != nullptr;
}
CSharpLanguage::StringNameCache::StringNameCache() {
-
_signal_callback = StaticCString::create("_signal_callback");
_set = StaticCString::create("_set");
_get = StaticCString::create("_get");
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 29c33b50bb..0bf08ceafd 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -66,7 +66,6 @@ TScriptInstance *cast_script_instance(ScriptInstance *p_inst) {
#define CAST_CSHARP_INSTANCE(m_inst) (cast_script_instance<CSharpInstance, CSharpLanguage>(m_inst))
class CSharpScript : public Script {
-
GDCLASS(CSharpScript, Script);
public:
@@ -139,6 +138,10 @@ private:
virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder);
#endif
+#if defined(TOOLS_ENABLED) || defined(DEBUG_ENABLED)
+ Set<StringName> exported_members_names;
+#endif
+
Map<StringName, PropertyInfo> member_info;
void _clear();
@@ -147,8 +150,9 @@ private:
bool _get_signal(GDMonoClass *p_class, GDMonoMethod *p_delegate_invoke, Vector<SignalParameter> &params);
bool _update_exports();
-#ifdef TOOLS_ENABLED
+
bool _get_member_export(IMonoClassMember *p_member, bool p_inspect_export, PropertyInfo &r_prop_info, bool &r_exported);
+#ifdef TOOLS_ENABLED
static int _try_get_member_export_hint(IMonoClassMember *p_member, ManagedType p_type, Variant::Type p_variant_type, bool p_allow_generics, PropertyHint &r_hint, String &r_hint_string);
#endif
@@ -191,9 +195,13 @@ public:
virtual void get_script_property_list(List<PropertyInfo> *p_list) const;
virtual void update_exports();
+ void get_members(Set<StringName> *p_members) override;
+
virtual bool is_tool() const { return tool; }
virtual bool is_valid() const { return valid; }
+ bool inherits_script(const Ref<Script> &p_script) const;
+
virtual Ref<Script> get_base_script() const;
virtual ScriptLanguage *get_language() const;
@@ -228,7 +236,6 @@ public:
};
class CSharpInstance : public ScriptInstance {
-
friend class CSharpScript;
friend class CSharpLanguage;
@@ -323,17 +330,13 @@ public:
};
struct CSharpScriptBinding {
- bool inited;
+ bool inited = false;
StringName type_name;
- GDMonoClass *wrapper_class;
+ GDMonoClass *wrapper_class = nullptr;
MonoGCHandleData gchandle;
- Object *owner;
+ Object *owner = nullptr;
- CSharpScriptBinding() :
- inited(false),
- wrapper_class(nullptr),
- owner(nullptr) {
- }
+ CSharpScriptBinding() {}
};
class ManagedCallableMiddleman : public Object {
@@ -341,7 +344,6 @@ class ManagedCallableMiddleman : public Object {
};
class CSharpLanguage : public ScriptLanguage {
-
friend class CSharpScript;
friend class CSharpInstance;
@@ -368,7 +370,6 @@ class CSharpLanguage : public ScriptLanguage {
ManagedCallableMiddleman *managed_callable_middleman = memnew(ManagedCallableMiddleman);
struct StringNameCache {
-
StringName _signal_callback;
StringName _set;
StringName _get;
@@ -530,7 +531,7 @@ public:
class ResourceFormatLoaderCSharpScript : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs
index 6015cb22b6..c2549b4ad5 100644
--- a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs
@@ -2,7 +2,6 @@ using System;
using System.IO;
using System.Security;
using Microsoft.Build.Framework;
-using GodotTools.Core;
namespace GodotTools.BuildLogger
{
@@ -183,4 +182,17 @@ namespace GodotTools.BuildLogger
private StreamWriter issuesStreamWriter;
private int indent;
}
+
+ internal static class StringExtensions
+ {
+ public static string CsvEscape(this string value, char delimiter = ',')
+ {
+ bool hasSpecialChar = value.IndexOfAny(new[] { '\"', '\n', '\r', delimiter }) != -1;
+
+ if (hasSpecialChar)
+ return "\"" + value.Replace("\"", "\"\"") + "\"";
+
+ return value;
+ }
+ }
}
diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj
index 8fdd485209..0afec970c6 100644
--- a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj
@@ -1,60 +1,10 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>GodotTools.BuildLogger</RootNamespace>
- <AssemblyName>GodotTools.BuildLogger</AssemblyName>
- <TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <LangVersion>7</LangVersion>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ <LangVersion>7.2</LangVersion>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugSymbols>true</DebugSymbols>
- <DebugType>portable</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugType>portable</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="Microsoft.Build.Framework" />
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="GodotBuildLogger.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
<ItemGroup>
- <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj">
- <Project>{639e48bd-44e5-4091-8edd-22d36dc0768d}</Project>
- <Name>GodotTools.Core</Name>
- </ProjectReference>
+ <PackageReference Include="Microsoft.Build.Framework" Version="16.5.0" />
</ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
</Project>
diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs
deleted file mode 100644
index 4374f21cfa..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("GodotTools.BuildLogger")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("Godot Engine contributors")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("6CE9A984-37B1-4F8A-8FE9-609F05F071B3")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs b/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs
new file mode 100644
index 0000000000..85760a3705
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/FileUtils.cs
@@ -0,0 +1,27 @@
+using System.IO;
+
+namespace GodotTools.Core
+{
+ public static class FileUtils
+ {
+ public static void SaveBackupCopy(string filePath)
+ {
+ string backupPathBase = filePath + ".old";
+ string backupPath = backupPathBase;
+
+ const int maxAttempts = 5;
+ int attempt = 1;
+
+ while (File.Exists(backupPath) && attempt <= maxAttempts)
+ {
+ backupPath = backupPathBase + "." + (attempt);
+ attempt++;
+ }
+
+ if (attempt > maxAttempts + 1)
+ return;
+
+ File.Copy(filePath, backupPath, overwrite: true);
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
index 2c35ef540a..d6d8962f90 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj
@@ -1,39 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{639E48BD-44E5-4091-8EDD-22D36DC0768D}</ProjectGuid>
- <OutputType>Library</OutputType>
- <RootNamespace>GodotTools.Core</RootNamespace>
- <AssemblyName>GodotTools.Core</AssemblyName>
- <TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
- <LangVersion>7</LangVersion>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ <LangVersion>7.2</LangVersion>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug</OutputPath>
- <DefineConstants>DEBUG;</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <Optimize>true</Optimize>
- <OutputPath>bin\Release</OutputPath>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="ProcessExtensions.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="StringExtensions.cs" />
- </ItemGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.Core/Properties/AssemblyInfo.cs
deleted file mode 100644
index 699ae6e741..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.Core/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle("GodotTools.Core")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("Godot Engine contributors")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
index 326c49f096..7ab5c5fc59 100644
--- a/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs
@@ -33,23 +33,13 @@ namespace GodotTools.Core
return rooted ? Path.DirectorySeparatorChar + path : path;
}
- private static readonly string driveRoot = Path.GetPathRoot(Environment.CurrentDirectory);
+ private static readonly string DriveRoot = Path.GetPathRoot(Environment.CurrentDirectory);
public static bool IsAbsolutePath(this string path)
{
return path.StartsWith("/", StringComparison.Ordinal) ||
path.StartsWith("\\", StringComparison.Ordinal) ||
- path.StartsWith(driveRoot, StringComparison.Ordinal);
- }
-
- public static string CsvEscape(this string value, char delimiter = ',')
- {
- bool hasSpecialChar = value.IndexOfAny(new char[] { '\"', '\n', '\r', delimiter }) != -1;
-
- if (hasSpecialChar)
- return "\"" + value.Replace("\"", "\"\"") + "\"";
-
- return value;
+ path.StartsWith(DriveRoot, StringComparison.Ordinal);
}
public static string ToSafeDirName(this string dirName, bool allowDirSeparator)
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs
deleted file mode 100644
index 7a2ff2ca56..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ConsoleLogger.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-using System;
-
-namespace GodotTools.IdeConnection
-{
- public class ConsoleLogger : ILogger
- {
- public void LogDebug(string message)
- {
- Console.WriteLine("DEBUG: " + message);
- }
-
- public void LogInfo(string message)
- {
- Console.WriteLine("INFO: " + message);
- }
-
- public void LogWarning(string message)
- {
- Console.WriteLine("WARN: " + message);
- }
-
- public void LogError(string message)
- {
- Console.WriteLine("ERROR: " + message);
- }
-
- public void LogError(string message, Exception e)
- {
- Console.WriteLine("EXCEPTION: " + message);
- Console.WriteLine(e);
- }
- }
-}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs
deleted file mode 100644
index be89638241..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeBase.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using System;
-using Path = System.IO.Path;
-
-namespace GodotTools.IdeConnection
-{
- public class GodotIdeBase : IDisposable
- {
- private ILogger logger;
-
- public ILogger Logger
- {
- get => logger ?? (logger = new ConsoleLogger());
- set => logger = value;
- }
-
- private readonly string projectMetadataDir;
-
- protected const string MetaFileName = "ide_server_meta.txt";
- protected string MetaFilePath => Path.Combine(projectMetadataDir, MetaFileName);
-
- private GodotIdeConnection connection;
- protected readonly object ConnectionLock = new object();
-
- public bool IsDisposed { get; private set; } = false;
-
- public bool IsConnected => connection != null && !connection.IsDisposed && connection.IsConnected;
-
- public event Action Connected
- {
- add
- {
- if (connection != null && !connection.IsDisposed)
- connection.Connected += value;
- }
- remove
- {
- if (connection != null && !connection.IsDisposed)
- connection.Connected -= value;
- }
- }
-
- protected GodotIdeConnection Connection
- {
- get => connection;
- set
- {
- connection?.Dispose();
- connection = value;
- }
- }
-
- protected GodotIdeBase(string projectMetadataDir)
- {
- this.projectMetadataDir = projectMetadataDir;
- }
-
- protected void DisposeConnection()
- {
- lock (ConnectionLock)
- {
- connection?.Dispose();
- }
- }
-
- ~GodotIdeBase()
- {
- Dispose(disposing: false);
- }
-
- public void Dispose()
- {
- if (IsDisposed)
- return;
-
- lock (ConnectionLock)
- {
- if (IsDisposed) // lock may not be fair
- return;
- IsDisposed = true;
- }
-
- Dispose(disposing: true);
- GC.SuppressFinalize(this);
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- connection?.Dispose();
- }
- }
- }
-}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs
deleted file mode 100644
index 2bf3b83c75..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeClient.cs
+++ /dev/null
@@ -1,219 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Threading;
-
-namespace GodotTools.IdeConnection
-{
- public abstract class GodotIdeClient : GodotIdeBase
- {
- protected GodotIdeMetadata GodotIdeMetadata;
-
- private readonly FileSystemWatcher fsWatcher;
-
- protected GodotIdeClient(string projectMetadataDir) : base(projectMetadataDir)
- {
- messageHandlers = InitializeMessageHandlers();
-
- // FileSystemWatcher requires an existing directory
- if (!File.Exists(projectMetadataDir))
- Directory.CreateDirectory(projectMetadataDir);
-
- fsWatcher = new FileSystemWatcher(projectMetadataDir, MetaFileName);
- }
-
- private void OnMetaFileChanged(object sender, FileSystemEventArgs e)
- {
- if (IsDisposed)
- return;
-
- lock (ConnectionLock)
- {
- if (IsDisposed)
- return;
-
- if (!File.Exists(MetaFilePath))
- return;
-
- var metadata = ReadMetadataFile();
-
- if (metadata != null && metadata != GodotIdeMetadata)
- {
- GodotIdeMetadata = metadata.Value;
- ConnectToServer();
- }
- }
- }
-
- private void OnMetaFileDeleted(object sender, FileSystemEventArgs e)
- {
- if (IsDisposed)
- return;
-
- if (IsConnected)
- DisposeConnection();
-
- // The file may have been re-created
-
- lock (ConnectionLock)
- {
- if (IsDisposed)
- return;
-
- if (IsConnected || !File.Exists(MetaFilePath))
- return;
-
- var metadata = ReadMetadataFile();
-
- if (metadata != null)
- {
- GodotIdeMetadata = metadata.Value;
- ConnectToServer();
- }
- }
- }
-
- private GodotIdeMetadata? ReadMetadataFile()
- {
- using (var reader = File.OpenText(MetaFilePath))
- {
- string portStr = reader.ReadLine();
-
- if (portStr == null)
- return null;
-
- string editorExecutablePath = reader.ReadLine();
-
- if (editorExecutablePath == null)
- return null;
-
- if (!int.TryParse(portStr, out int port))
- return null;
-
- return new GodotIdeMetadata(port, editorExecutablePath);
- }
- }
-
- private void ConnectToServer()
- {
- var tcpClient = new TcpClient();
-
- Connection = new GodotIdeConnectionClient(tcpClient, HandleMessage);
- Connection.Logger = Logger;
-
- try
- {
- Logger.LogInfo("Connecting to Godot Ide Server");
-
- tcpClient.Connect(IPAddress.Loopback, GodotIdeMetadata.Port);
-
- Logger.LogInfo("Connection open with Godot Ide Server");
-
- var clientThread = new Thread(Connection.Start)
- {
- IsBackground = true,
- Name = "Godot Ide Connection Client"
- };
- clientThread.Start();
- }
- catch (SocketException e)
- {
- if (e.SocketErrorCode == SocketError.ConnectionRefused)
- Logger.LogError("The connection to the Godot Ide Server was refused");
- else
- throw;
- }
- }
-
- public void Start()
- {
- Logger.LogInfo("Starting Godot Ide Client");
-
- fsWatcher.Changed += OnMetaFileChanged;
- fsWatcher.Deleted += OnMetaFileDeleted;
- fsWatcher.EnableRaisingEvents = true;
-
- lock (ConnectionLock)
- {
- if (IsDisposed)
- return;
-
- if (!File.Exists(MetaFilePath))
- {
- Logger.LogInfo("There is no Godot Ide Server running");
- return;
- }
-
- var metadata = ReadMetadataFile();
-
- if (metadata != null)
- {
- GodotIdeMetadata = metadata.Value;
- ConnectToServer();
- }
- else
- {
- Logger.LogError("Failed to read Godot Ide metadata file");
- }
- }
- }
-
- public bool WriteMessage(Message message)
- {
- return Connection.WriteMessage(message);
- }
-
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
-
- if (disposing)
- {
- fsWatcher?.Dispose();
- }
- }
-
- protected virtual bool HandleMessage(Message message)
- {
- if (messageHandlers.TryGetValue(message.Id, out var action))
- {
- action(message.Arguments);
- return true;
- }
-
- return false;
- }
-
- private readonly Dictionary<string, Action<string[]>> messageHandlers;
-
- private Dictionary<string, Action<string[]>> InitializeMessageHandlers()
- {
- return new Dictionary<string, Action<string[]>>
- {
- ["OpenFile"] = args =>
- {
- switch (args.Length)
- {
- case 1:
- OpenFile(file: args[0]);
- return;
- case 2:
- OpenFile(file: args[0], line: int.Parse(args[1]));
- return;
- case 3:
- OpenFile(file: args[0], line: int.Parse(args[1]), column: int.Parse(args[2]));
- return;
- default:
- throw new ArgumentException();
- }
- }
- };
- }
-
- protected abstract void OpenFile(string file);
- protected abstract void OpenFile(string file, int line);
- protected abstract void OpenFile(string file, int line, int column);
- }
-}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs
deleted file mode 100644
index 6441be8d6e..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnection.cs
+++ /dev/null
@@ -1,207 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Net.Sockets;
-using System.Text;
-
-namespace GodotTools.IdeConnection
-{
- public abstract class GodotIdeConnection : IDisposable
- {
- protected const string Version = "1.0";
-
- protected static readonly string ClientHandshake = $"Godot Ide Client Version {Version}";
- protected static readonly string ServerHandshake = $"Godot Ide Server Version {Version}";
-
- private const int ClientWriteTimeout = 8000;
- private readonly TcpClient tcpClient;
-
- private TextReader clientReader;
- private TextWriter clientWriter;
-
- private readonly object writeLock = new object();
-
- private readonly Func<Message, bool> messageHandler;
-
- public event Action Connected;
-
- private ILogger logger;
-
- public ILogger Logger
- {
- get => logger ?? (logger = new ConsoleLogger());
- set => logger = value;
- }
-
- public bool IsDisposed { get; private set; } = false;
-
- public bool IsConnected => tcpClient.Client != null && tcpClient.Client.Connected;
-
- protected GodotIdeConnection(TcpClient tcpClient, Func<Message, bool> messageHandler)
- {
- this.tcpClient = tcpClient;
- this.messageHandler = messageHandler;
- }
-
- public void Start()
- {
- try
- {
- if (!StartConnection())
- return;
-
- string messageLine;
- while ((messageLine = ReadLine()) != null)
- {
- if (!MessageParser.TryParse(messageLine, out Message msg))
- {
- Logger.LogError($"Received message with invalid format: {messageLine}");
- continue;
- }
-
- Logger.LogDebug($"Received message: {msg}");
-
- if (msg.Id == "close")
- {
- Logger.LogInfo("Closing connection");
- return;
- }
-
- try
- {
- try
- {
- Debug.Assert(messageHandler != null);
-
- if (!messageHandler(msg))
- Logger.LogError($"Received unknown message: {msg}");
- }
- catch (Exception e)
- {
- Logger.LogError($"Message handler for '{msg}' failed with exception", e);
- }
- }
- catch (Exception e)
- {
- Logger.LogError($"Exception thrown from message handler. Message: {msg}", e);
- }
- }
- }
- catch (Exception e)
- {
- Logger.LogError($"Unhandled exception in the Godot Ide Connection thread", e);
- }
- finally
- {
- Dispose();
- }
- }
-
- private bool StartConnection()
- {
- NetworkStream clientStream = tcpClient.GetStream();
-
- clientReader = new StreamReader(clientStream, Encoding.UTF8);
-
- lock (writeLock)
- clientWriter = new StreamWriter(clientStream, Encoding.UTF8);
-
- clientStream.WriteTimeout = ClientWriteTimeout;
-
- if (!WriteHandshake())
- {
- Logger.LogError("Could not write handshake");
- return false;
- }
-
- if (!IsValidResponseHandshake(ReadLine()))
- {
- Logger.LogError("Received invalid handshake");
- return false;
- }
-
- Connected?.Invoke();
-
- Logger.LogInfo("Godot Ide connection started");
-
- return true;
- }
-
- private string ReadLine()
- {
- try
- {
- return clientReader?.ReadLine();
- }
- catch (Exception e)
- {
- if (IsDisposed)
- {
- var se = e as SocketException ?? e.InnerException as SocketException;
- if (se != null && se.SocketErrorCode == SocketError.Interrupted)
- return null;
- }
-
- throw;
- }
- }
-
- public bool WriteMessage(Message message)
- {
- Logger.LogDebug($"Sending message {message}");
-
- var messageComposer = new MessageComposer();
-
- messageComposer.AddArgument(message.Id);
- foreach (string argument in message.Arguments)
- messageComposer.AddArgument(argument);
-
- return WriteLine(messageComposer.ToString());
- }
-
- protected bool WriteLine(string text)
- {
- if (clientWriter == null || IsDisposed || !IsConnected)
- return false;
-
- lock (writeLock)
- {
- try
- {
- clientWriter.WriteLine(text);
- clientWriter.Flush();
- }
- catch (Exception e)
- {
- if (!IsDisposed)
- {
- var se = e as SocketException ?? e.InnerException as SocketException;
- if (se != null && se.SocketErrorCode == SocketError.Shutdown)
- Logger.LogInfo("Client disconnected ungracefully");
- else
- Logger.LogError("Exception thrown when trying to write to client", e);
-
- Dispose();
- }
- }
- }
-
- return true;
- }
-
- protected abstract bool WriteHandshake();
- protected abstract bool IsValidResponseHandshake(string handshakeLine);
-
- public void Dispose()
- {
- if (IsDisposed)
- return;
-
- IsDisposed = true;
-
- clientReader?.Dispose();
- clientWriter?.Dispose();
- ((IDisposable)tcpClient)?.Dispose();
- }
- }
-}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs
deleted file mode 100644
index 1b11a14358..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionClient.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-
-namespace GodotTools.IdeConnection
-{
- public class GodotIdeConnectionClient : GodotIdeConnection
- {
- public GodotIdeConnectionClient(TcpClient tcpClient, Func<Message, bool> messageHandler)
- : base(tcpClient, messageHandler)
- {
- }
-
- protected override bool WriteHandshake()
- {
- return WriteLine(ClientHandshake);
- }
-
- protected override bool IsValidResponseHandshake(string handshakeLine)
- {
- return handshakeLine == ServerHandshake;
- }
- }
-}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs
deleted file mode 100644
index aa98dc7ca3..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeConnectionServer.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-using System.Net.Sockets;
-using System.Threading.Tasks;
-
-namespace GodotTools.IdeConnection
-{
- public class GodotIdeConnectionServer : GodotIdeConnection
- {
- public GodotIdeConnectionServer(TcpClient tcpClient, Func<Message, bool> messageHandler)
- : base(tcpClient, messageHandler)
- {
- }
-
- protected override bool WriteHandshake()
- {
- return WriteLine(ServerHandshake);
- }
-
- protected override bool IsValidResponseHandshake(string handshakeLine)
- {
- return handshakeLine == ClientHandshake;
- }
- }
-}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj
deleted file mode 100644
index 8454535fba..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotTools.IdeConnection.csproj
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{92600954-25F0-4291-8E11-1FEE9FC4BE20}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>GodotTools.IdeConnection</RootNamespace>
- <AssemblyName>GodotTools.IdeConnection</AssemblyName>
- <TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <LangVersion>7</LangVersion>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugSymbols>true</DebugSymbols>
- <DebugType>portable</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugType>portable</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="ConsoleLogger.cs" />
- <Compile Include="GodotIdeMetadata.cs" />
- <Compile Include="GodotIdeBase.cs" />
- <Compile Include="GodotIdeClient.cs" />
- <Compile Include="GodotIdeConnection.cs" />
- <Compile Include="GodotIdeConnectionClient.cs" />
- <Compile Include="GodotIdeConnectionServer.cs" />
- <Compile Include="ILogger.cs" />
- <Compile Include="Message.cs" />
- <Compile Include="MessageComposer.cs" />
- <Compile Include="MessageParser.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-</Project>
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs
deleted file mode 100644
index f24d324ae3..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Message.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Linq;
-
-namespace GodotTools.IdeConnection
-{
- public struct Message
- {
- public string Id { get; set; }
- public string[] Arguments { get; set; }
-
- public Message(string id, params string[] arguments)
- {
- Id = id;
- Arguments = arguments;
- }
-
- public override string ToString()
- {
- return $"(Id: '{Id}', Arguments: '{string.Join(",", Arguments)}')";
- }
- }
-}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs
deleted file mode 100644
index 30ffe7a06e..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageComposer.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System.Linq;
-using System.Text;
-
-namespace GodotTools.IdeConnection
-{
- public class MessageComposer
- {
- private readonly StringBuilder stringBuilder = new StringBuilder();
-
- private static readonly char[] CharsToEscape = { '\\', '"' };
-
- public void AddArgument(string argument)
- {
- AddArgument(argument, quoted: argument.Contains(","));
- }
-
- public void AddArgument(string argument, bool quoted)
- {
- if (stringBuilder.Length > 0)
- stringBuilder.Append(',');
-
- if (quoted)
- {
- stringBuilder.Append('"');
-
- foreach (char @char in argument)
- {
- if (CharsToEscape.Contains(@char))
- stringBuilder.Append('\\');
- stringBuilder.Append(@char);
- }
-
- stringBuilder.Append('"');
- }
- else
- {
- stringBuilder.Append(argument);
- }
- }
-
- public override string ToString()
- {
- return stringBuilder.ToString();
- }
- }
-}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs
deleted file mode 100644
index 4365d69989..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/MessageParser.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace GodotTools.IdeConnection
-{
- public static class MessageParser
- {
- public static bool TryParse(string messageLine, out Message message)
- {
- var arguments = new List<string>();
- var stringBuilder = new StringBuilder();
-
- bool expectingArgument = true;
-
- for (int i = 0; i < messageLine.Length; i++)
- {
- char @char = messageLine[i];
-
- if (@char == ',')
- {
- if (expectingArgument)
- arguments.Add(string.Empty);
-
- expectingArgument = true;
- continue;
- }
-
- bool quoted = false;
-
- if (messageLine[i] == '"')
- {
- quoted = true;
- i++;
- }
-
- while (i < messageLine.Length)
- {
- @char = messageLine[i];
-
- if (quoted && @char == '"')
- {
- i++;
- break;
- }
-
- if (@char == '\\')
- {
- i++;
- if (i < messageLine.Length)
- break;
-
- stringBuilder.Append(messageLine[i]);
- }
- else if (!quoted && @char == ',')
- {
- break; // We don't increment the counter to allow the colon to be parsed after this
- }
- else
- {
- stringBuilder.Append(@char);
- }
-
- i++;
- }
-
- arguments.Add(stringBuilder.ToString());
- stringBuilder.Clear();
-
- expectingArgument = false;
- }
-
- if (arguments.Count == 0)
- {
- message = new Message();
- return false;
- }
-
- message = new Message
- {
- Id = arguments[0],
- Arguments = arguments.Skip(1).ToArray()
- };
-
- return true;
- }
- }
-}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs
deleted file mode 100644
index 0806d02ca0..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("GodotTools.IdeConnection")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("Godot Engine contributors")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("92600954-25F0-4291-8E11-1FEE9FC4BE20")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/ForwarderMessageHandler.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/ForwarderMessageHandler.cs
new file mode 100644
index 0000000000..3cb6a6687e
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/ForwarderMessageHandler.cs
@@ -0,0 +1,57 @@
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using GodotTools.IdeMessaging.Utils;
+
+namespace GodotTools.IdeMessaging.CLI
+{
+ public class ForwarderMessageHandler : IMessageHandler
+ {
+ private readonly StreamWriter outputWriter;
+ private readonly SemaphoreSlim outputWriteSem = new SemaphoreSlim(1);
+
+ public ForwarderMessageHandler(StreamWriter outputWriter)
+ {
+ this.outputWriter = outputWriter;
+ }
+
+ public async Task<MessageContent> HandleRequest(Peer peer, string id, MessageContent content, ILogger logger)
+ {
+ await WriteRequestToOutput(id, content);
+ return new MessageContent(MessageStatus.RequestNotSupported, "null");
+ }
+
+ private async Task WriteRequestToOutput(string id, MessageContent content)
+ {
+ using (await outputWriteSem.UseAsync())
+ {
+ await outputWriter.WriteLineAsync("======= Request =======");
+ await outputWriter.WriteLineAsync(id);
+ await outputWriter.WriteLineAsync(content.Body.Count(c => c == '\n').ToString());
+ await outputWriter.WriteLineAsync(content.Body);
+ await outputWriter.WriteLineAsync("=======================");
+ await outputWriter.FlushAsync();
+ }
+ }
+
+ public async Task WriteResponseToOutput(string id, MessageContent content)
+ {
+ using (await outputWriteSem.UseAsync())
+ {
+ await outputWriter.WriteLineAsync("======= Response =======");
+ await outputWriter.WriteLineAsync(id);
+ await outputWriter.WriteLineAsync(content.Body.Count(c => c == '\n').ToString());
+ await outputWriter.WriteLineAsync(content.Body);
+ await outputWriter.WriteLineAsync("========================");
+ await outputWriter.FlushAsync();
+ }
+ }
+
+ public async Task WriteLineToOutput(string eventName)
+ {
+ using (await outputWriteSem.UseAsync())
+ await outputWriter.WriteLineAsync($"======= {eventName} =======");
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/GodotTools.IdeMessaging.CLI.csproj b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/GodotTools.IdeMessaging.CLI.csproj
new file mode 100644
index 0000000000..ae78da27bc
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/GodotTools.IdeMessaging.CLI.csproj
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <ProjectGuid>{B06C2951-C8E3-4F28-80B2-717CF327EB19}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net472</TargetFramework>
+ <LangVersion>7.2</LangVersion>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\GodotTools.IdeMessaging\GodotTools.IdeMessaging.csproj" />
+ </ItemGroup>
+ <ItemGroup>
+ <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
+ </ItemGroup>
+</Project>
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/Program.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/Program.cs
new file mode 100644
index 0000000000..99a55c471b
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging.CLI/Program.cs
@@ -0,0 +1,218 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using GodotTools.IdeMessaging.Requests;
+using Newtonsoft.Json;
+
+namespace GodotTools.IdeMessaging.CLI
+{
+ internal static class Program
+ {
+ private static readonly ILogger Logger = new CustomLogger();
+
+ public static int Main(string[] args)
+ {
+ try
+ {
+ var mainTask = StartAsync(args, Console.OpenStandardInput(), Console.OpenStandardOutput());
+ mainTask.Wait();
+ return mainTask.Result;
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError("Unhandled exception: ", ex);
+ return 1;
+ }
+ }
+
+ private static async Task<int> StartAsync(string[] args, Stream inputStream, Stream outputStream)
+ {
+ var inputReader = new StreamReader(inputStream, Encoding.UTF8);
+ var outputWriter = new StreamWriter(outputStream, Encoding.UTF8);
+
+ try
+ {
+ if (args.Length == 0)
+ {
+ Logger.LogError("Expected at least 1 argument");
+ return 1;
+ }
+
+ string godotProjectDir = args[0];
+
+ if (!Directory.Exists(godotProjectDir))
+ {
+ Logger.LogError($"The specified Godot project directory does not exist: {godotProjectDir}");
+ return 1;
+ }
+
+ var forwarder = new ForwarderMessageHandler(outputWriter);
+
+ using (var fwdClient = new Client("VisualStudioCode", godotProjectDir, forwarder, Logger))
+ {
+ fwdClient.Start();
+
+ // ReSharper disable AccessToDisposedClosure
+ fwdClient.Connected += async () => await forwarder.WriteLineToOutput("Event=Connected");
+ fwdClient.Disconnected += async () => await forwarder.WriteLineToOutput("Event=Disconnected");
+ // ReSharper restore AccessToDisposedClosure
+
+ // TODO: Await connected with timeout
+
+ while (!fwdClient.IsDisposed)
+ {
+ string firstLine = await inputReader.ReadLineAsync();
+
+ if (firstLine == null || firstLine == "QUIT")
+ goto ExitMainLoop;
+
+ string messageId = firstLine;
+
+ string messageArgcLine = await inputReader.ReadLineAsync();
+
+ if (messageArgcLine == null)
+ {
+ Logger.LogInfo("EOF when expecting argument count");
+ goto ExitMainLoop;
+ }
+
+ if (!int.TryParse(messageArgcLine, out int messageArgc))
+ {
+ Logger.LogError("Received invalid line for argument count: " + firstLine);
+ continue;
+ }
+
+ var body = new StringBuilder();
+
+ for (int i = 0; i < messageArgc; i++)
+ {
+ string bodyLine = await inputReader.ReadLineAsync();
+
+ if (bodyLine == null)
+ {
+ Logger.LogInfo($"EOF when expecting body line #{i + 1}");
+ goto ExitMainLoop;
+ }
+
+ body.AppendLine(bodyLine);
+ }
+
+ var response = await SendRequest(fwdClient, messageId, new MessageContent(MessageStatus.Ok, body.ToString()));
+
+ if (response == null)
+ {
+ Logger.LogError($"Failed to write message to the server: {messageId}");
+ }
+ else
+ {
+ var content = new MessageContent(response.Status, JsonConvert.SerializeObject(response));
+ await forwarder.WriteResponseToOutput(messageId, content);
+ }
+ }
+
+ ExitMainLoop:
+
+ await forwarder.WriteLineToOutput("Event=Quit");
+ }
+
+ return 0;
+ }
+ catch (Exception e)
+ {
+ Logger.LogError("Unhandled exception", e);
+ return 1;
+ }
+ }
+
+ private static async Task<Response> SendRequest(Client client, string id, MessageContent content)
+ {
+ var handlers = new Dictionary<string, Func<Task<Response>>>
+ {
+ [PlayRequest.Id] = async () =>
+ {
+ var request = JsonConvert.DeserializeObject<PlayRequest>(content.Body);
+ return await client.SendRequest<PlayResponse>(request);
+ },
+ [DebugPlayRequest.Id] = async () =>
+ {
+ var request = JsonConvert.DeserializeObject<DebugPlayRequest>(content.Body);
+ return await client.SendRequest<DebugPlayResponse>(request);
+ },
+ [ReloadScriptsRequest.Id] = async () =>
+ {
+ var request = JsonConvert.DeserializeObject<ReloadScriptsRequest>(content.Body);
+ return await client.SendRequest<ReloadScriptsResponse>(request);
+ },
+ [CodeCompletionRequest.Id] = async () =>
+ {
+ var request = JsonConvert.DeserializeObject<CodeCompletionRequest>(content.Body);
+ return await client.SendRequest<CodeCompletionResponse>(request);
+ }
+ };
+
+ if (handlers.TryGetValue(id, out var handler))
+ return await handler();
+
+ Console.WriteLine("INVALID REQUEST");
+ return null;
+ }
+
+ private class CustomLogger : ILogger
+ {
+ private static string ThisAppPath => Assembly.GetExecutingAssembly().Location;
+ private static string ThisAppPathWithoutExtension => Path.ChangeExtension(ThisAppPath, null);
+
+ private static readonly string LogPath = $"{ThisAppPathWithoutExtension}.log";
+
+ private static StreamWriter NewWriter() => new StreamWriter(LogPath, append: true, encoding: Encoding.UTF8);
+
+ private static void Log(StreamWriter writer, string message)
+ {
+ writer.WriteLine($"{DateTime.Now:HH:mm:ss.ffffff}: {message}");
+ }
+
+ public void LogDebug(string message)
+ {
+ using (var writer = NewWriter())
+ {
+ Log(writer, "DEBUG: " + message);
+ }
+ }
+
+ public void LogInfo(string message)
+ {
+ using (var writer = NewWriter())
+ {
+ Log(writer, "INFO: " + message);
+ }
+ }
+
+ public void LogWarning(string message)
+ {
+ using (var writer = NewWriter())
+ {
+ Log(writer, "WARN: " + message);
+ }
+ }
+
+ public void LogError(string message)
+ {
+ using (var writer = NewWriter())
+ {
+ Log(writer, "ERROR: " + message);
+ }
+ }
+
+ public void LogError(string message, Exception e)
+ {
+ using (var writer = NewWriter())
+ {
+ Log(writer, "EXCEPTION: " + message + '\n' + e);
+ }
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs
new file mode 100644
index 0000000000..d069651dd3
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Client.cs
@@ -0,0 +1,332 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using Newtonsoft.Json;
+using System.Threading;
+using System.Threading.Tasks;
+using GodotTools.IdeMessaging.Requests;
+using GodotTools.IdeMessaging.Utils;
+
+namespace GodotTools.IdeMessaging
+{
+ // ReSharper disable once UnusedType.Global
+ public sealed class Client : IDisposable
+ {
+ private readonly ILogger logger;
+
+ private readonly string identity;
+
+ private string MetaFilePath { get; }
+ private GodotIdeMetadata godotIdeMetadata;
+ private readonly FileSystemWatcher fsWatcher;
+
+ private readonly IMessageHandler messageHandler;
+
+ private Peer peer;
+ private readonly SemaphoreSlim connectionSem = new SemaphoreSlim(1);
+
+ private readonly Queue<NotifyAwaiter<bool>> clientConnectedAwaiters = new Queue<NotifyAwaiter<bool>>();
+ private readonly Queue<NotifyAwaiter<bool>> clientDisconnectedAwaiters = new Queue<NotifyAwaiter<bool>>();
+
+ // ReSharper disable once UnusedMember.Global
+ public async Task<bool> AwaitConnected()
+ {
+ var awaiter = new NotifyAwaiter<bool>();
+ clientConnectedAwaiters.Enqueue(awaiter);
+ return await awaiter;
+ }
+
+ // ReSharper disable once UnusedMember.Global
+ public async Task<bool> AwaitDisconnected()
+ {
+ var awaiter = new NotifyAwaiter<bool>();
+ clientDisconnectedAwaiters.Enqueue(awaiter);
+ return await awaiter;
+ }
+
+ // ReSharper disable once MemberCanBePrivate.Global
+ public bool IsDisposed { get; private set; }
+
+ // ReSharper disable once MemberCanBePrivate.Global
+ public bool IsConnected => peer != null && !peer.IsDisposed && peer.IsTcpClientConnected;
+
+ // ReSharper disable once EventNeverSubscribedTo.Global
+ public event Action Connected
+ {
+ add
+ {
+ if (peer != null && !peer.IsDisposed)
+ peer.Connected += value;
+ }
+ remove
+ {
+ if (peer != null && !peer.IsDisposed)
+ peer.Connected -= value;
+ }
+ }
+
+ // ReSharper disable once EventNeverSubscribedTo.Global
+ public event Action Disconnected
+ {
+ add
+ {
+ if (peer != null && !peer.IsDisposed)
+ peer.Disconnected += value;
+ }
+ remove
+ {
+ if (peer != null && !peer.IsDisposed)
+ peer.Disconnected -= value;
+ }
+ }
+
+ ~Client()
+ {
+ Dispose(disposing: false);
+ }
+
+ public async void Dispose()
+ {
+ if (IsDisposed)
+ return;
+
+ using (await connectionSem.UseAsync())
+ {
+ if (IsDisposed) // lock may not be fair
+ return;
+ IsDisposed = true;
+ }
+
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ peer?.Dispose();
+ fsWatcher?.Dispose();
+ }
+ }
+
+ public Client(string identity, string godotProjectDir, IMessageHandler messageHandler, ILogger logger)
+ {
+ this.identity = identity;
+ this.messageHandler = messageHandler;
+ this.logger = logger;
+
+ string projectMetadataDir = Path.Combine(godotProjectDir, ".mono", "metadata");
+
+ MetaFilePath = Path.Combine(projectMetadataDir, GodotIdeMetadata.DefaultFileName);
+
+ // FileSystemWatcher requires an existing directory
+ if (!File.Exists(projectMetadataDir))
+ Directory.CreateDirectory(projectMetadataDir);
+
+ fsWatcher = new FileSystemWatcher(projectMetadataDir, GodotIdeMetadata.DefaultFileName);
+ }
+
+ private async void OnMetaFileChanged(object sender, FileSystemEventArgs e)
+ {
+ if (IsDisposed)
+ return;
+
+ using (await connectionSem.UseAsync())
+ {
+ if (IsDisposed)
+ return;
+
+ if (!File.Exists(MetaFilePath))
+ return;
+
+ var metadata = ReadMetadataFile();
+
+ if (metadata != null && metadata != godotIdeMetadata)
+ {
+ godotIdeMetadata = metadata.Value;
+ _ = Task.Run(ConnectToServer);
+ }
+ }
+ }
+
+ private async void OnMetaFileDeleted(object sender, FileSystemEventArgs e)
+ {
+ if (IsDisposed)
+ return;
+
+ if (IsConnected)
+ {
+ using (await connectionSem.UseAsync())
+ peer?.Dispose();
+ }
+
+ // The file may have been re-created
+
+ using (await connectionSem.UseAsync())
+ {
+ if (IsDisposed)
+ return;
+
+ if (IsConnected || !File.Exists(MetaFilePath))
+ return;
+
+ var metadata = ReadMetadataFile();
+
+ if (metadata != null)
+ {
+ godotIdeMetadata = metadata.Value;
+ _ = Task.Run(ConnectToServer);
+ }
+ }
+ }
+
+ private GodotIdeMetadata? ReadMetadataFile()
+ {
+ using (var reader = File.OpenText(MetaFilePath))
+ {
+ string portStr = reader.ReadLine();
+
+ if (portStr == null)
+ return null;
+
+ string editorExecutablePath = reader.ReadLine();
+
+ if (editorExecutablePath == null)
+ return null;
+
+ if (!int.TryParse(portStr, out int port))
+ return null;
+
+ return new GodotIdeMetadata(port, editorExecutablePath);
+ }
+ }
+
+ private async Task AcceptClient(TcpClient tcpClient)
+ {
+ logger.LogDebug("Accept client...");
+
+ using (peer = new Peer(tcpClient, new ClientHandshake(), messageHandler, logger))
+ {
+ // ReSharper disable AccessToDisposedClosure
+ peer.Connected += () =>
+ {
+ logger.LogInfo("Connection open with Ide Client");
+
+ while (clientConnectedAwaiters.Count > 0)
+ clientConnectedAwaiters.Dequeue().SetResult(true);
+ };
+
+ peer.Disconnected += () =>
+ {
+ while (clientDisconnectedAwaiters.Count > 0)
+ clientDisconnectedAwaiters.Dequeue().SetResult(true);
+ };
+ // ReSharper restore AccessToDisposedClosure
+
+ try
+ {
+ if (!await peer.DoHandshake(identity))
+ {
+ logger.LogError("Handshake failed");
+ return;
+ }
+ }
+ catch (Exception e)
+ {
+ logger.LogError("Handshake failed with unhandled exception: ", e);
+ return;
+ }
+
+ await peer.Process();
+
+ logger.LogInfo("Connection closed with Ide Client");
+ }
+ }
+
+ private async Task ConnectToServer()
+ {
+ var tcpClient = new TcpClient();
+
+ try
+ {
+ logger.LogInfo("Connecting to Godot Ide Server");
+
+ await tcpClient.ConnectAsync(IPAddress.Loopback, godotIdeMetadata.Port);
+
+ logger.LogInfo("Connection open with Godot Ide Server");
+
+ await AcceptClient(tcpClient);
+ }
+ catch (SocketException e)
+ {
+ if (e.SocketErrorCode == SocketError.ConnectionRefused)
+ logger.LogError("The connection to the Godot Ide Server was refused");
+ else
+ throw;
+ }
+ }
+
+ // ReSharper disable once UnusedMember.Global
+ public async void Start()
+ {
+ fsWatcher.Changed += OnMetaFileChanged;
+ fsWatcher.Deleted += OnMetaFileDeleted;
+ fsWatcher.EnableRaisingEvents = true;
+
+ using (await connectionSem.UseAsync())
+ {
+ if (IsDisposed)
+ return;
+
+ if (IsConnected)
+ return;
+
+ if (!File.Exists(MetaFilePath))
+ {
+ logger.LogInfo("There is no Godot Ide Server running");
+ return;
+ }
+
+ var metadata = ReadMetadataFile();
+
+ if (metadata != null)
+ {
+ godotIdeMetadata = metadata.Value;
+ _ = Task.Run(ConnectToServer);
+ }
+ else
+ {
+ logger.LogError("Failed to read Godot Ide metadata file");
+ }
+ }
+ }
+
+ public async Task<TResponse> SendRequest<TResponse>(Request request)
+ where TResponse : Response, new()
+ {
+ if (!IsConnected)
+ {
+ logger.LogError("Cannot write request. Not connected to the Godot Ide Server.");
+ return null;
+ }
+
+ string body = JsonConvert.SerializeObject(request);
+ return await peer.SendRequest<TResponse>(request.Id, body);
+ }
+
+ public async Task<TResponse> SendRequest<TResponse>(string id, string body)
+ where TResponse : Response, new()
+ {
+ if (!IsConnected)
+ {
+ logger.LogError("Cannot write request. Not connected to the Godot Ide Server.");
+ return null;
+ }
+
+ return await peer.SendRequest<TResponse>(id, body);
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ClientHandshake.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ClientHandshake.cs
new file mode 100644
index 0000000000..43041be7be
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ClientHandshake.cs
@@ -0,0 +1,44 @@
+using System.Text.RegularExpressions;
+
+namespace GodotTools.IdeMessaging
+{
+ public class ClientHandshake : IHandshake
+ {
+ private static readonly string ClientHandshakeBase = $"{Peer.ClientHandshakeName},Version={Peer.ProtocolVersionMajor}.{Peer.ProtocolVersionMinor}.{Peer.ProtocolVersionRevision}";
+ private static readonly string ServerHandshakePattern = $@"{Regex.Escape(Peer.ServerHandshakeName)},Version=([0-9]+)\.([0-9]+)\.([0-9]+),([_a-zA-Z][_a-zA-Z0-9]{{0,63}})";
+
+ public string GetHandshakeLine(string identity) => $"{ClientHandshakeBase},{identity}";
+
+ public bool IsValidPeerHandshake(string handshake, out string identity, ILogger logger)
+ {
+ identity = null;
+
+ var match = Regex.Match(handshake, ServerHandshakePattern);
+
+ if (!match.Success)
+ return false;
+
+ if (!uint.TryParse(match.Groups[1].Value, out uint serverMajor) || Peer.ProtocolVersionMajor != serverMajor)
+ {
+ logger.LogDebug("Incompatible major version: " + match.Groups[1].Value);
+ return false;
+ }
+
+ if (!uint.TryParse(match.Groups[2].Value, out uint serverMinor) || Peer.ProtocolVersionMinor < serverMinor)
+ {
+ logger.LogDebug("Incompatible minor version: " + match.Groups[2].Value);
+ return false;
+ }
+
+ if (!uint.TryParse(match.Groups[3].Value, out uint _)) // Revision
+ {
+ logger.LogDebug("Incompatible revision build: " + match.Groups[3].Value);
+ return false;
+ }
+
+ identity = match.Groups[4].Value;
+
+ return true;
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ClientMessageHandler.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ClientMessageHandler.cs
new file mode 100644
index 0000000000..64bcfd824c
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ClientMessageHandler.cs
@@ -0,0 +1,52 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using GodotTools.IdeMessaging.Requests;
+using Newtonsoft.Json;
+
+namespace GodotTools.IdeMessaging
+{
+ // ReSharper disable once UnusedType.Global
+ public abstract class ClientMessageHandler : IMessageHandler
+ {
+ private readonly Dictionary<string, Peer.RequestHandler> requestHandlers;
+
+ protected ClientMessageHandler()
+ {
+ requestHandlers = InitializeRequestHandlers();
+ }
+
+ public async Task<MessageContent> HandleRequest(Peer peer, string id, MessageContent content, ILogger logger)
+ {
+ if (!requestHandlers.TryGetValue(id, out var handler))
+ {
+ logger.LogError($"Received unknown request: {id}");
+ return new MessageContent(MessageStatus.RequestNotSupported, "null");
+ }
+
+ try
+ {
+ var response = await handler(peer, content);
+ return new MessageContent(response.Status, JsonConvert.SerializeObject(response));
+ }
+ catch (JsonException)
+ {
+ logger.LogError($"Received request with invalid body: {id}");
+ return new MessageContent(MessageStatus.InvalidRequestBody, "null");
+ }
+ }
+
+ private Dictionary<string, Peer.RequestHandler> InitializeRequestHandlers()
+ {
+ return new Dictionary<string, Peer.RequestHandler>
+ {
+ [OpenFileRequest.Id] = async (peer, content) =>
+ {
+ var request = JsonConvert.DeserializeObject<OpenFileRequest>(content.Body);
+ return await HandleOpenFile(request);
+ }
+ };
+ }
+
+ protected abstract Task<Response> HandleOpenFile(OpenFileRequest request);
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeMetadata.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotIdeMetadata.cs
index d16daba0e2..686202e81e 100644
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/GodotIdeMetadata.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotIdeMetadata.cs
@@ -1,10 +1,12 @@
-namespace GodotTools.IdeConnection
+namespace GodotTools.IdeMessaging
{
- public struct GodotIdeMetadata
+ public readonly struct GodotIdeMetadata
{
public int Port { get; }
public string EditorExecutablePath { get; }
+ public const string DefaultFileName = "ide_messaging_meta.txt";
+
public GodotIdeMetadata(int port, string editorExecutablePath)
{
Port = port;
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotTools.IdeMessaging.csproj b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotTools.IdeMessaging.csproj
new file mode 100644
index 0000000000..67815959a6
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/GodotTools.IdeMessaging.csproj
@@ -0,0 +1,24 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <PropertyGroup>
+ <ProjectGuid>{92600954-25F0-4291-8E11-1FEE9FC4BE20}</ProjectGuid>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ <LangVersion>7.2</LangVersion>
+ <PackageId>GodotTools.IdeMessaging</PackageId>
+ <Version>1.1.0</Version>
+ <AssemblyVersion>$(Version)</AssemblyVersion>
+ <Authors>Godot Engine contributors</Authors>
+ <Company />
+ <PackageTags>godot</PackageTags>
+ <RepositoryUrl>https://github.com/godotengine/godot/tree/master/modules/mono/editor/GodotTools/GodotTools.IdeMessaging</RepositoryUrl>
+ <PackageLicenseExpression>MIT</PackageLicenseExpression>
+ <Description>
+This library enables communication with the Godot Engine editor (the version with .NET support).
+It's intended for use in IDEs/editors plugins for a better experience working with Godot C# projects.
+
+A client using this library is only compatible with servers of the same major version and of a lower or equal minor version.
+ </Description>
+ </PropertyGroup>
+ <ItemGroup>
+ <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
+ </ItemGroup>
+</Project>
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/IHandshake.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/IHandshake.cs
new file mode 100644
index 0000000000..6387145a28
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/IHandshake.cs
@@ -0,0 +1,8 @@
+namespace GodotTools.IdeMessaging
+{
+ public interface IHandshake
+ {
+ string GetHandshakeLine(string identity);
+ bool IsValidPeerHandshake(string handshake, out string identity, ILogger logger);
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ILogger.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ILogger.cs
index 614bb30271..d2855f93a1 100644
--- a/modules/mono/editor/GodotTools/GodotTools.IdeConnection/ILogger.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ILogger.cs
@@ -1,6 +1,6 @@
using System;
-namespace GodotTools.IdeConnection
+namespace GodotTools.IdeMessaging
{
public interface ILogger
{
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/IMessageHandler.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/IMessageHandler.cs
new file mode 100644
index 0000000000..9622fcc96d
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/IMessageHandler.cs
@@ -0,0 +1,9 @@
+using System.Threading.Tasks;
+
+namespace GodotTools.IdeMessaging
+{
+ public interface IMessageHandler
+ {
+ Task<MessageContent> HandleRequest(Peer peer, string id, MessageContent content, ILogger logger);
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Message.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Message.cs
new file mode 100644
index 0000000000..6903ec197b
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Message.cs
@@ -0,0 +1,52 @@
+namespace GodotTools.IdeMessaging
+{
+ public class Message
+ {
+ public MessageKind Kind { get; }
+ public string Id { get; }
+ public MessageContent Content { get; }
+
+ public Message(MessageKind kind, string id, MessageContent content)
+ {
+ Kind = kind;
+ Id = id;
+ Content = content;
+ }
+
+ public override string ToString()
+ {
+ return $"{Kind} | {Id}";
+ }
+ }
+
+ public enum MessageKind
+ {
+ Request,
+ Response
+ }
+
+ public enum MessageStatus
+ {
+ Ok,
+ RequestNotSupported,
+ InvalidRequestBody
+ }
+
+ public readonly struct MessageContent
+ {
+ public MessageStatus Status { get; }
+ public string Body { get; }
+
+ public MessageContent(string body)
+ {
+ Status = MessageStatus.Ok;
+ Body = body;
+ }
+
+ public MessageContent(MessageStatus status, string body)
+ {
+ Status = status;
+ Body = body;
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/MessageDecoder.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/MessageDecoder.cs
new file mode 100644
index 0000000000..a00575a2a1
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/MessageDecoder.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Text;
+
+namespace GodotTools.IdeMessaging
+{
+ public class MessageDecoder
+ {
+ private class DecodedMessage
+ {
+ public MessageKind? Kind;
+ public string Id;
+ public MessageStatus? Status;
+ public readonly StringBuilder Body = new StringBuilder();
+ public uint? PendingBodyLines;
+
+ public void Clear()
+ {
+ Kind = null;
+ Id = null;
+ Status = null;
+ Body.Clear();
+ PendingBodyLines = null;
+ }
+
+ public Message ToMessage()
+ {
+ if (!Kind.HasValue || Id == null || !Status.HasValue ||
+ !PendingBodyLines.HasValue || PendingBodyLines.Value > 0)
+ throw new InvalidOperationException();
+
+ return new Message(Kind.Value, Id, new MessageContent(Status.Value, Body.ToString()));
+ }
+ }
+
+ public enum State
+ {
+ Decoding,
+ Decoded,
+ Errored
+ }
+
+ private readonly DecodedMessage decodingMessage = new DecodedMessage();
+
+ public State Decode(string messageLine, out Message decodedMessage)
+ {
+ decodedMessage = null;
+
+ if (!decodingMessage.Kind.HasValue)
+ {
+ if (!Enum.TryParse(messageLine, ignoreCase: true, out MessageKind kind))
+ {
+ decodingMessage.Clear();
+ return State.Errored;
+ }
+
+ decodingMessage.Kind = kind;
+ }
+ else if (decodingMessage.Id == null)
+ {
+ decodingMessage.Id = messageLine;
+ }
+ else if (decodingMessage.Status == null)
+ {
+ if (!Enum.TryParse(messageLine, ignoreCase: true, out MessageStatus status))
+ {
+ decodingMessage.Clear();
+ return State.Errored;
+ }
+
+ decodingMessage.Status = status;
+ }
+ else if (decodingMessage.PendingBodyLines == null)
+ {
+ if (!uint.TryParse(messageLine, out uint pendingBodyLines))
+ {
+ decodingMessage.Clear();
+ return State.Errored;
+ }
+
+ decodingMessage.PendingBodyLines = pendingBodyLines;
+ }
+ else
+ {
+ if (decodingMessage.PendingBodyLines > 0)
+ {
+ decodingMessage.Body.AppendLine(messageLine);
+ decodingMessage.PendingBodyLines -= 1;
+ }
+ else
+ {
+ decodedMessage = decodingMessage.ToMessage();
+ decodingMessage.Clear();
+ return State.Decoded;
+ }
+ }
+
+ return State.Decoding;
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Peer.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Peer.cs
new file mode 100644
index 0000000000..a4e86d6177
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Peer.cs
@@ -0,0 +1,302 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Sockets;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using GodotTools.IdeMessaging.Requests;
+using GodotTools.IdeMessaging.Utils;
+
+namespace GodotTools.IdeMessaging
+{
+ public sealed class Peer : IDisposable
+ {
+ /// <summary>
+ /// Major version.
+ /// There is no forward nor backward compatibility between different major versions.
+ /// Connection is refused if client and server have different major versions.
+ /// </summary>
+ public static readonly int ProtocolVersionMajor = Assembly.GetAssembly(typeof(Peer)).GetName().Version.Major;
+
+ /// <summary>
+ /// Minor version, which clients must be backward compatible with.
+ /// Connection is refused if the client's minor version is lower than the server's.
+ /// </summary>
+ public static readonly int ProtocolVersionMinor = Assembly.GetAssembly(typeof(Peer)).GetName().Version.Minor;
+
+ /// <summary>
+ /// Revision, which doesn't affect compatibility.
+ /// </summary>
+ public static readonly int ProtocolVersionRevision = Assembly.GetAssembly(typeof(Peer)).GetName().Version.Revision;
+
+ public const string ClientHandshakeName = "GodotIdeClient";
+ public const string ServerHandshakeName = "GodotIdeServer";
+
+ private const int ClientWriteTimeout = 8000;
+
+ public delegate Task<Response> RequestHandler(Peer peer, MessageContent content);
+
+ private readonly TcpClient tcpClient;
+
+ private readonly TextReader clientReader;
+ private readonly TextWriter clientWriter;
+
+ private readonly SemaphoreSlim writeSem = new SemaphoreSlim(1);
+
+ private string remoteIdentity = string.Empty;
+ public string RemoteIdentity => remoteIdentity;
+
+ public event Action Connected;
+ public event Action Disconnected;
+
+ private ILogger Logger { get; }
+
+ public bool IsDisposed { get; private set; }
+
+ public bool IsTcpClientConnected => tcpClient.Client != null && tcpClient.Client.Connected;
+
+ private bool IsConnected { get; set; }
+
+ private readonly IHandshake handshake;
+ private readonly IMessageHandler messageHandler;
+
+ private readonly Dictionary<string, Queue<ResponseAwaiter>> requestAwaiterQueues = new Dictionary<string, Queue<ResponseAwaiter>>();
+ private readonly SemaphoreSlim requestsSem = new SemaphoreSlim(1);
+
+ public Peer(TcpClient tcpClient, IHandshake handshake, IMessageHandler messageHandler, ILogger logger)
+ {
+ this.tcpClient = tcpClient;
+ this.handshake = handshake;
+ this.messageHandler = messageHandler;
+
+ Logger = logger;
+
+ NetworkStream clientStream = tcpClient.GetStream();
+ clientStream.WriteTimeout = ClientWriteTimeout;
+
+ clientReader = new StreamReader(clientStream, Encoding.UTF8);
+ clientWriter = new StreamWriter(clientStream, Encoding.UTF8) {NewLine = "\n"};
+ }
+
+ public async Task Process()
+ {
+ try
+ {
+ var decoder = new MessageDecoder();
+
+ string messageLine;
+ while ((messageLine = await ReadLine()) != null)
+ {
+ var state = decoder.Decode(messageLine, out var msg);
+
+ if (state == MessageDecoder.State.Decoding)
+ continue; // Not finished decoding yet
+
+ if (state == MessageDecoder.State.Errored)
+ {
+ Logger.LogError($"Received message line with invalid format: {messageLine}");
+ continue;
+ }
+
+ Logger.LogDebug($"Received message: {msg}");
+
+ try
+ {
+ try
+ {
+ if (msg.Kind == MessageKind.Request)
+ {
+ var responseContent = await messageHandler.HandleRequest(this, msg.Id, msg.Content, Logger);
+ await WriteMessage(new Message(MessageKind.Response, msg.Id, responseContent));
+ }
+ else if (msg.Kind == MessageKind.Response)
+ {
+ ResponseAwaiter responseAwaiter;
+
+ using (await requestsSem.UseAsync())
+ {
+ if (!requestAwaiterQueues.TryGetValue(msg.Id, out var queue) || queue.Count <= 0)
+ {
+ Logger.LogError($"Received unexpected response: {msg.Id}");
+ return;
+ }
+
+ responseAwaiter = queue.Dequeue();
+ }
+
+ responseAwaiter.SetResult(msg.Content);
+ }
+ else
+ {
+ throw new IndexOutOfRangeException($"Invalid message kind {msg.Kind}");
+ }
+ }
+ catch (Exception e)
+ {
+ Logger.LogError($"Message handler for '{msg}' failed with exception", e);
+ }
+ }
+ catch (Exception e)
+ {
+ Logger.LogError($"Exception thrown from message handler. Message: {msg}", e);
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ Logger.LogError("Unhandled exception in the peer loop", e);
+ }
+ }
+
+ public async Task<bool> DoHandshake(string identity)
+ {
+ if (!await WriteLine(handshake.GetHandshakeLine(identity)))
+ {
+ Logger.LogError("Could not write handshake");
+ return false;
+ }
+
+ var readHandshakeTask = ReadLine();
+
+ if (await Task.WhenAny(readHandshakeTask, Task.Delay(8000)) != readHandshakeTask)
+ {
+ Logger.LogError("Timeout waiting for the client handshake");
+ return false;
+ }
+
+ string peerHandshake = await readHandshakeTask;
+
+ if (handshake == null || !handshake.IsValidPeerHandshake(peerHandshake, out remoteIdentity, Logger))
+ {
+ Logger.LogError("Received invalid handshake: " + peerHandshake);
+ return false;
+ }
+
+ IsConnected = true;
+ Connected?.Invoke();
+
+ Logger.LogInfo("Peer connection started");
+
+ return true;
+ }
+
+ private async Task<string> ReadLine()
+ {
+ try
+ {
+ return await clientReader.ReadLineAsync();
+ }
+ catch (Exception e)
+ {
+ if (IsDisposed)
+ {
+ var se = e as SocketException ?? e.InnerException as SocketException;
+ if (se != null && se.SocketErrorCode == SocketError.Interrupted)
+ return null;
+ }
+
+ throw;
+ }
+ }
+
+ private Task<bool> WriteMessage(Message message)
+ {
+ Logger.LogDebug($"Sending message: {message}");
+ int bodyLineCount = message.Content.Body.Count(c => c == '\n');
+
+ bodyLineCount += 1; // Extra line break at the end
+
+ var builder = new StringBuilder();
+
+ builder.AppendLine(message.Kind.ToString());
+ builder.AppendLine(message.Id);
+ builder.AppendLine(message.Content.Status.ToString());
+ builder.AppendLine(bodyLineCount.ToString());
+ builder.AppendLine(message.Content.Body);
+
+ return WriteLine(builder.ToString());
+ }
+
+ public async Task<TResponse> SendRequest<TResponse>(string id, string body)
+ where TResponse : Response, new()
+ {
+ ResponseAwaiter responseAwaiter;
+
+ using (await requestsSem.UseAsync())
+ {
+ bool written = await WriteMessage(new Message(MessageKind.Request, id, new MessageContent(body)));
+
+ if (!written)
+ return null;
+
+ if (!requestAwaiterQueues.TryGetValue(id, out var queue))
+ {
+ queue = new Queue<ResponseAwaiter>();
+ requestAwaiterQueues.Add(id, queue);
+ }
+
+ responseAwaiter = new ResponseAwaiter<TResponse>();
+ queue.Enqueue(responseAwaiter);
+ }
+
+ return (TResponse)await responseAwaiter;
+ }
+
+ private async Task<bool> WriteLine(string text)
+ {
+ if (clientWriter == null || IsDisposed || !IsTcpClientConnected)
+ return false;
+
+ using (await writeSem.UseAsync())
+ {
+ try
+ {
+ await clientWriter.WriteLineAsync(text);
+ await clientWriter.FlushAsync();
+ }
+ catch (Exception e)
+ {
+ if (!IsDisposed)
+ {
+ var se = e as SocketException ?? e.InnerException as SocketException;
+ if (se != null && se.SocketErrorCode == SocketError.Shutdown)
+ Logger.LogInfo("Client disconnected ungracefully");
+ else
+ Logger.LogError("Exception thrown when trying to write to client", e);
+
+ Dispose();
+ }
+ }
+ }
+
+ return true;
+ }
+
+ // ReSharper disable once UnusedMember.Global
+ public void ShutdownSocketSend()
+ {
+ tcpClient.Client.Shutdown(SocketShutdown.Send);
+ }
+
+ public void Dispose()
+ {
+ if (IsDisposed)
+ return;
+
+ IsDisposed = true;
+
+ if (IsTcpClientConnected)
+ {
+ if (IsConnected)
+ Disconnected?.Invoke();
+ }
+
+ clientReader?.Dispose();
+ clientWriter?.Dispose();
+ ((IDisposable)tcpClient)?.Dispose();
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Requests/Requests.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Requests/Requests.cs
new file mode 100644
index 0000000000..1dd4f852e5
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Requests/Requests.cs
@@ -0,0 +1,116 @@
+// ReSharper disable ClassNeverInstantiated.Global
+// ReSharper disable UnusedMember.Global
+// ReSharper disable UnusedAutoPropertyAccessor.Global
+
+using Newtonsoft.Json;
+
+namespace GodotTools.IdeMessaging.Requests
+{
+ public abstract class Request
+ {
+ [JsonIgnore] public string Id { get; }
+
+ protected Request(string id)
+ {
+ Id = id;
+ }
+ }
+
+ public abstract class Response
+ {
+ [JsonIgnore] public MessageStatus Status { get; set; } = MessageStatus.Ok;
+ }
+
+ public sealed class CodeCompletionRequest : Request
+ {
+ public enum CompletionKind
+ {
+ InputActions = 0,
+ NodePaths,
+ ResourcePaths,
+ ScenePaths,
+ ShaderParams,
+ Signals,
+ ThemeColors,
+ ThemeConstants,
+ ThemeFonts,
+ ThemeStyles
+ }
+
+ public CompletionKind Kind { get; set; }
+ public string ScriptFile { get; set; }
+
+ public new const string Id = "CodeCompletion";
+
+ public CodeCompletionRequest() : base(Id)
+ {
+ }
+ }
+
+ public sealed class CodeCompletionResponse : Response
+ {
+ public CodeCompletionRequest.CompletionKind Kind;
+ public string ScriptFile { get; set; }
+ public string[] Suggestions { get; set; }
+ }
+
+ public sealed class PlayRequest : Request
+ {
+ public new const string Id = "Play";
+
+ public PlayRequest() : base(Id)
+ {
+ }
+ }
+
+ public sealed class PlayResponse : Response
+ {
+ }
+
+ public sealed class DebugPlayRequest : Request
+ {
+ public string DebuggerHost { get; set; }
+ public int DebuggerPort { get; set; }
+ public bool? BuildBeforePlaying { get; set; }
+
+ public new const string Id = "DebugPlay";
+
+ public DebugPlayRequest() : base(Id)
+ {
+ }
+ }
+
+ public sealed class DebugPlayResponse : Response
+ {
+ }
+
+ public sealed class OpenFileRequest : Request
+ {
+ public string File { get; set; }
+ public int? Line { get; set; }
+ public int? Column { get; set; }
+
+ public new const string Id = "OpenFile";
+
+ public OpenFileRequest() : base(Id)
+ {
+ }
+ }
+
+ public sealed class OpenFileResponse : Response
+ {
+ }
+
+ public sealed class ReloadScriptsRequest : Request
+ {
+ public new const string Id = "ReloadScripts";
+
+ public ReloadScriptsRequest() : base(Id)
+ {
+ }
+ }
+
+ public sealed class ReloadScriptsResponse : Response
+ {
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ResponseAwaiter.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ResponseAwaiter.cs
new file mode 100644
index 0000000000..548e7f06ee
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/ResponseAwaiter.cs
@@ -0,0 +1,23 @@
+using GodotTools.IdeMessaging.Requests;
+using GodotTools.IdeMessaging.Utils;
+using Newtonsoft.Json;
+
+namespace GodotTools.IdeMessaging
+{
+ public abstract class ResponseAwaiter : NotifyAwaiter<Response>
+ {
+ public abstract void SetResult(MessageContent content);
+ }
+
+ public class ResponseAwaiter<T> : ResponseAwaiter
+ where T : Response, new()
+ {
+ public override void SetResult(MessageContent content)
+ {
+ if (content.Status == MessageStatus.Ok)
+ SetResult(JsonConvert.DeserializeObject<T>(content.Body));
+ else
+ SetResult(new T {Status = content.Status});
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/NotifyAwaiter.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/NotifyAwaiter.cs
index 700b786752..d84a63c83c 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/NotifyAwaiter.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/NotifyAwaiter.cs
@@ -1,9 +1,9 @@
using System;
using System.Runtime.CompilerServices;
-namespace GodotTools.Utils
+namespace GodotTools.IdeMessaging.Utils
{
- public sealed class NotifyAwaiter<T> : INotifyCompletion
+ public class NotifyAwaiter<T> : INotifyCompletion
{
private Action continuation;
private Exception exception;
diff --git a/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/SemaphoreExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/SemaphoreExtensions.cs
new file mode 100644
index 0000000000..9d593fbf8a
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.IdeMessaging/Utils/SemaphoreExtensions.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace GodotTools.IdeMessaging.Utils
+{
+ public static class SemaphoreExtensions
+ {
+ public static ConfiguredTaskAwaitable<IDisposable> UseAsync(this SemaphoreSlim semaphoreSlim, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ var wrapper = new SemaphoreSlimWaitReleaseWrapper(semaphoreSlim, out Task waitAsyncTask, cancellationToken);
+ return waitAsyncTask.ContinueWith<IDisposable>(t => wrapper, cancellationToken).ConfigureAwait(false);
+ }
+
+ private struct SemaphoreSlimWaitReleaseWrapper : IDisposable
+ {
+ private readonly SemaphoreSlim semaphoreSlim;
+
+ public SemaphoreSlimWaitReleaseWrapper(SemaphoreSlim semaphoreSlim, out Task waitAsyncTask, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ this.semaphoreSlim = semaphoreSlim;
+ waitAsyncTask = this.semaphoreSlim.WaitAsync(cancellationToken);
+ }
+
+ public void Dispose()
+ {
+ semaphoreSlim.Release();
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
index 9afd9adeb1..6f318aab4a 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs
@@ -153,7 +153,12 @@ EndProject";
var result = regex.Replace(input,m => dict[m.Value]);
if (result != input)
+ {
+ // Save a copy of the solution before replacing it
+ FileUtils.SaveBackupCopy(slnPath);
+
File.WriteAllText(slnPath, result);
+ }
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj
index b60e501beb..9cb50014b0 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj
@@ -1,57 +1,23 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}</ProjectGuid>
- <OutputType>Library</OutputType>
- <RootNamespace>GodotTools.ProjectEditor</RootNamespace>
- <AssemblyName>GodotTools.ProjectEditor</AssemblyName>
- <TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
- <BaseIntermediateOutputPath>obj</BaseIntermediateOutputPath>
- <LangVersion>7</LangVersion>
+ <TargetFramework>net472</TargetFramework>
+ <LangVersion>7.2</LangVersion>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>portable</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug</OutputPath>
- <DefineConstants>DEBUG;</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <Optimize>true</Optimize>
- <OutputPath>bin\Release</OutputPath>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="System" />
- <Reference Include="Microsoft.Build" />
- <Reference Include="DotNet.Glob, Version=2.1.1.0, Culture=neutral, PublicKeyToken=b68cc888b4f632d1, processorArchitecture=MSIL">
- <HintPath>$(SolutionDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath>
- </Reference>
- </ItemGroup>
<ItemGroup>
- <Compile Include="ApiAssembliesInfo.cs" />
- <Compile Include="DotNetSolution.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="IdentifierUtils.cs" />
- <Compile Include="ProjectExtensions.cs" />
- <Compile Include="ProjectGenerator.cs" />
- <Compile Include="ProjectUtils.cs" />
+ <PackageReference Include="Microsoft.Build" Version="16.5.0" />
+ <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
- <None Include="packages.config" />
+ <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj" />
</ItemGroup>
<ItemGroup>
- <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj">
- <Project>{639E48BD-44E5-4091-8EDD-22D36DC0768D}</Project>
- <Name>GodotTools.Core</Name>
- </ProjectReference>
+ <!--
+ The Microsoft.Build.Runtime package is too problematic so we create a MSBuild.exe stub. The workaround described
+ here doesn't work with Microsoft.NETFramework.ReferenceAssemblies: https://github.com/microsoft/msbuild/issues/3486
+ We need a MSBuild.exe file as there's an issue in Microsoft.Build where it executes platform dependent code when
+ searching for MSBuild.exe before the fallback to not using it. A stub is fine as it should never be executed.
+ -->
+ <None Include="MSBuild.exe" CopyToOutputDirectory="Always" />
</ItemGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/MSBuild.exe b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/MSBuild.exe
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/MSBuild.exe
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs
index f0e0d1b33d..704f2ec194 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs
@@ -2,8 +2,8 @@ using GodotTools.Core;
using System;
using System.Collections.Generic;
using System.IO;
-using DotNet.Globbing;
using Microsoft.Build.Construction;
+using Microsoft.Build.Globbing;
namespace GodotTools.ProjectEditor
{
@@ -11,8 +11,6 @@ namespace GodotTools.ProjectEditor
{
public static ProjectItemElement FindItemOrNull(this ProjectRootElement root, string itemType, string include, bool noCondition = false)
{
- GlobOptions globOptions = new GlobOptions {Evaluation = {CaseInsensitive = false}};
-
string normalizedInclude = include.NormalizePath();
foreach (var itemGroup in root.ItemGroups)
@@ -25,7 +23,8 @@ namespace GodotTools.ProjectEditor
if (item.ItemType != itemType)
continue;
- var glob = Glob.Parse(item.Include.NormalizePath(), globOptions);
+ //var glob = Glob.Parse(item.Include.NormalizePath(), globOptions);
+ var glob = MSBuildGlob.Parse(item.Include.NormalizePath());
if (glob.IsMatch(normalizedInclude))
return item;
@@ -36,8 +35,6 @@ namespace GodotTools.ProjectEditor
}
public static ProjectItemElement FindItemOrNullAbs(this ProjectRootElement root, string itemType, string include, bool noCondition = false)
{
- GlobOptions globOptions = new GlobOptions {Evaluation = {CaseInsensitive = false}};
-
string normalizedInclude = Path.GetFullPath(include).NormalizePath();
foreach (var itemGroup in root.ItemGroups)
@@ -50,7 +47,7 @@ namespace GodotTools.ProjectEditor
if (item.ItemType != itemType)
continue;
- var glob = Glob.Parse(Path.GetFullPath(item.Include).NormalizePath(), globOptions);
+ var glob = MSBuildGlob.Parse(Path.GetFullPath(item.Include).NormalizePath());
if (glob.IsMatch(normalizedInclude))
return item;
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
index cbe3afaedd..fb2beb6995 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs
@@ -125,6 +125,12 @@ namespace GodotTools.ProjectEditor
// References
var referenceGroup = root.AddItemGroup();
referenceGroup.AddItem("Reference", "System");
+ var frameworkRefAssembliesItem = referenceGroup.AddItem("PackageReference", "Microsoft.NETFramework.ReferenceAssemblies");
+
+ // Use metadata (child nodes) instead of attributes for the PackageReference.
+ // This is for compatibility with 3.2, where GodotTools uses an old Microsoft.Build.
+ frameworkRefAssembliesItem.AddMetadata("Version", "1.0.0");
+ frameworkRefAssembliesItem.AddMetadata("PrivateAssets", "All");
root.AddImport(Path.Combine("$(MSBuildBinPath)", "Microsoft.CSharp.targets").Replace("/", "\\"));
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
index 1776b46e6a..069a1edaa3 100644
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
+++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs
@@ -4,13 +4,33 @@ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
-using DotNet.Globbing;
using Microsoft.Build.Construction;
+using Microsoft.Build.Globbing;
namespace GodotTools.ProjectEditor
{
+ public sealed class MSBuildProject
+ {
+ public ProjectRootElement Root { get; }
+
+ public bool HasUnsavedChanges { get; set; }
+
+ public void Save() => Root.Save();
+
+ public MSBuildProject(ProjectRootElement root)
+ {
+ Root = root;
+ }
+ }
+
public static class ProjectUtils
{
+ public static MSBuildProject Open(string path)
+ {
+ var root = ProjectRootElement.Open(path);
+ return root != null ? new MSBuildProject(root) : null;
+ }
+
public static void AddItemToProjectChecked(string projectPath, string itemType, string include)
{
var dir = Directory.GetParent(projectPath).FullName;
@@ -43,7 +63,6 @@ namespace GodotTools.ProjectEditor
public static void RemoveItemFromProjectChecked(string projectPath, string itemType, string include)
{
- var dir = Directory.GetParent(projectPath).FullName;
var root = ProjectRootElement.Open(projectPath);
Debug.Assert(root != null);
@@ -114,9 +133,6 @@ namespace GodotTools.ProjectEditor
var result = new List<string>();
var existingFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs");
- var globOptions = new GlobOptions();
- globOptions.Evaluation.CaseInsensitive = false;
-
var root = ProjectRootElement.Open(projectPath);
Debug.Assert(root != null);
@@ -132,7 +148,7 @@ namespace GodotTools.ProjectEditor
string normalizedInclude = item.Include.NormalizePath();
- var glob = Glob.Parse(normalizedInclude, globOptions);
+ var glob = MSBuildGlob.Parse(normalizedInclude);
// TODO Check somehow if path has no blob to avoid the following loop...
@@ -150,17 +166,14 @@ namespace GodotTools.ProjectEditor
}
/// Simple function to make sure the Api assembly references are configured correctly
- public static void FixApiHintPath(string projectPath)
+ public static void FixApiHintPath(MSBuildProject project)
{
- var root = ProjectRootElement.Open(projectPath);
- Debug.Assert(root != null);
-
- bool dirty = false;
+ var root = project.Root;
void AddPropertyIfNotPresent(string name, string condition, string value)
{
if (root.PropertyGroups
- .Any(g => (g.Condition == string.Empty || g.Condition.Trim() == condition) &&
+ .Any(g => (string.IsNullOrEmpty(g.Condition) || g.Condition.Trim() == condition) &&
g.Properties
.Any(p => p.Name == name &&
p.Value == value &&
@@ -170,7 +183,7 @@ namespace GodotTools.ProjectEditor
}
root.AddProperty(name, value).Condition = " " + condition + " ";
- dirty = true;
+ project.HasUnsavedChanges = true;
}
AddPropertyIfNotPresent(name: "ApiConfiguration",
@@ -212,7 +225,7 @@ namespace GodotTools.ProjectEditor
}
referenceWithHintPath.AddMetadata("HintPath", hintPath);
- dirty = true;
+ project.HasUnsavedChanges = true;
return;
}
@@ -221,14 +234,14 @@ namespace GodotTools.ProjectEditor
{
// Found a Reference item without a HintPath
referenceWithoutHintPath.AddMetadata("HintPath", hintPath);
- dirty = true;
+ project.HasUnsavedChanges = true;
return;
}
}
// Found no Reference item at all. Add it.
root.AddItem("Reference", referenceName).Condition = " " + condition + " ";
- dirty = true;
+ project.HasUnsavedChanges = true;
}
const string coreProjectName = "GodotSharp";
@@ -242,22 +255,16 @@ namespace GodotTools.ProjectEditor
SetReferenceHintPath(coreProjectName, coreCondition, coreHintPath);
SetReferenceHintPath(editorProjectName, editorCondition, editorHintPath);
-
- if (dirty)
- root.Save();
}
- public static void MigrateFromOldConfigNames(string projectPath)
+ public static void MigrateFromOldConfigNames(MSBuildProject project)
{
- var root = ProjectRootElement.Open(projectPath);
- Debug.Assert(root != null);
-
- bool dirty = false;
+ var root = project.Root;
bool hasGodotProjectGeneratorVersion = false;
bool foundOldConfiguration = false;
- foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition == string.Empty))
+ foreach (var propertyGroup in root.PropertyGroups.Where(g => string.IsNullOrEmpty(g.Condition)))
{
if (!hasGodotProjectGeneratorVersion && propertyGroup.Properties.Any(p => p.Name == "GodotProjectGeneratorVersion"))
hasGodotProjectGeneratorVersion = true;
@@ -267,15 +274,15 @@ namespace GodotTools.ProjectEditor
{
configItem.Value = "Debug";
foundOldConfiguration = true;
- dirty = true;
+ project.HasUnsavedChanges = true;
}
}
if (!hasGodotProjectGeneratorVersion)
{
- root.PropertyGroups.First(g => g.Condition == string.Empty)?
+ root.PropertyGroups.First(g => string.IsNullOrEmpty(g.Condition))?
.AddProperty("GodotProjectGeneratorVersion", Assembly.GetExecutingAssembly().GetName().Version.ToString());
- dirty = true;
+ project.HasUnsavedChanges = true;
}
if (!foundOldConfiguration)
@@ -301,7 +308,7 @@ namespace GodotTools.ProjectEditor
foreach (var propertyGroup in root.PropertyGroups.Where(g => g.Condition.Trim() == oldCondition))
{
propertyGroup.Condition = " " + newCondition + " ";
- dirty = true;
+ project.HasUnsavedChanges = true;
}
foreach (var propertyGroup in root.PropertyGroups)
@@ -309,14 +316,14 @@ namespace GodotTools.ProjectEditor
foreach (var prop in propertyGroup.Properties.Where(p => p.Condition.Trim() == oldCondition))
{
prop.Condition = " " + newCondition + " ";
- dirty = true;
+ project.HasUnsavedChanges = true;
}
}
foreach (var itemGroup in root.ItemGroups.Where(g => g.Condition.Trim() == oldCondition))
{
itemGroup.Condition = " " + newCondition + " ";
- dirty = true;
+ project.HasUnsavedChanges = true;
}
foreach (var itemGroup in root.ItemGroups)
@@ -324,7 +331,7 @@ namespace GodotTools.ProjectEditor
foreach (var item in itemGroup.Items.Where(item => item.Condition.Trim() == oldCondition))
{
item.Condition = " " + newCondition + " ";
- dirty = true;
+ project.HasUnsavedChanges = true;
}
}
}
@@ -340,10 +347,26 @@ namespace GodotTools.ProjectEditor
MigrateConfigurationConditions("Release", "ExportRelease");
MigrateConfigurationConditions("Tools", "Debug"); // Must be last
}
+ }
+ public static void EnsureHasNugetNetFrameworkRefAssemblies(MSBuildProject project)
+ {
+ var root = project.Root;
- if (dirty)
- root.Save();
+ bool found = root.ItemGroups.Any(g => string.IsNullOrEmpty(g.Condition) && g.Items.Any(
+ item => item.ItemType == "PackageReference" && item.Include == "Microsoft.NETFramework.ReferenceAssemblies"));
+
+ if (found)
+ return;
+
+ var frameworkRefAssembliesItem = root.AddItem("PackageReference", "Microsoft.NETFramework.ReferenceAssemblies");
+
+ // Use metadata (child nodes) instead of attributes for the PackageReference.
+ // This is for compatibility with 3.2, where GodotTools uses an old Microsoft.Build.
+ frameworkRefAssembliesItem.AddMetadata("Version", "1.0.0");
+ frameworkRefAssembliesItem.AddMetadata("PrivateAssets", "All");
+
+ project.HasUnsavedChanges = true;
}
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/Properties/AssemblyInfo.cs
deleted file mode 100644
index 3a0464c9bc..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle("GodotTools.ProjectEditor")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("Godot Engine contributors")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
-
diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/packages.config b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/packages.config
deleted file mode 100644
index 2db030f9d8..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="DotNet.Glob" version="2.1.1" targetFramework="net45" />
-</packages>
diff --git a/modules/mono/editor/GodotTools/GodotTools.sln b/modules/mono/editor/GodotTools/GodotTools.sln
index a3438ea5f3..f6147eb5bb 100644
--- a/modules/mono/editor/GodotTools/GodotTools.sln
+++ b/modules/mono/editor/GodotTools/GodotTools.sln
@@ -9,7 +9,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.Core", "GodotToo
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.BuildLogger", "GodotTools.BuildLogger\GodotTools.BuildLogger.csproj", "{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.IdeConnection", "GodotTools.IdeConnection\GodotTools.IdeConnection.csproj", "{92600954-25F0-4291-8E11-1FEE9FC4BE20}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.IdeMessaging", "GodotTools.IdeMessaging\GodotTools.IdeMessaging.csproj", "{92600954-25F0-4291-8E11-1FEE9FC4BE20}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
index 43c96d2e30..e55558c100 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs
@@ -14,16 +14,6 @@ namespace GodotTools.Build
{
public static class BuildSystem
{
- private static string GetMsBuildPath()
- {
- string msbuildPath = MsBuildFinder.FindMsBuild();
-
- if (msbuildPath == null)
- throw new FileNotFoundException("Cannot find the MSBuild executable.");
-
- return msbuildPath;
- }
-
private static string MonoWindowsBinDir
{
get
@@ -46,8 +36,8 @@ namespace GodotTools.Build
{
if (OS.IsWindows)
{
- return (BuildManager.BuildTool)EditorSettings.GetSetting("mono/builds/build_tool")
- == BuildManager.BuildTool.MsBuildMono;
+ return (BuildTool)EditorSettings.GetSetting("mono/builds/build_tool")
+ == BuildTool.MsBuildMono;
}
return false;
@@ -57,16 +47,21 @@ namespace GodotTools.Build
private static bool PrintBuildOutput =>
(bool)EditorSettings.GetSetting("mono/builds/print_build_output");
- private static Process LaunchBuild(string solution, string config, string loggerOutputDir, IEnumerable<string> customProperties = null)
+ private static Process LaunchBuild(string solution, IEnumerable<string> targets, string config, string loggerOutputDir, IEnumerable<string> customProperties = null)
{
+ (string msbuildPath, BuildTool buildTool) = MsBuildFinder.FindMsBuild();
+
+ if (msbuildPath == null)
+ throw new FileNotFoundException("Cannot find the MSBuild executable.");
+
var customPropertiesList = new List<string>();
if (customProperties != null)
customPropertiesList.AddRange(customProperties);
- string compilerArgs = BuildArguments(solution, config, loggerOutputDir, customPropertiesList);
+ string compilerArgs = BuildArguments(buildTool, solution, targets, config, loggerOutputDir, customPropertiesList);
- var startInfo = new ProcessStartInfo(GetMsBuildPath(), compilerArgs);
+ var startInfo = new ProcessStartInfo(msbuildPath, compilerArgs);
bool redirectOutput = !IsDebugMsBuildRequested() && !PrintBuildOutput;
@@ -90,7 +85,7 @@ namespace GodotTools.Build
// Needed when running from Developer Command Prompt for VS
RemovePlatformVariable(startInfo.EnvironmentVariables);
- var process = new Process { StartInfo = startInfo };
+ var process = new Process {StartInfo = startInfo};
process.Start();
@@ -105,19 +100,19 @@ namespace GodotTools.Build
public static int Build(BuildInfo buildInfo)
{
- return Build(buildInfo.Solution, buildInfo.Configuration,
+ return Build(buildInfo.Solution, buildInfo.Targets, buildInfo.Configuration,
buildInfo.LogsDirPath, buildInfo.CustomProperties);
}
- public static async Task<int> BuildAsync(BuildInfo buildInfo)
+ public static Task<int> BuildAsync(BuildInfo buildInfo)
{
- return await BuildAsync(buildInfo.Solution, buildInfo.Configuration,
+ return BuildAsync(buildInfo.Solution, buildInfo.Targets, buildInfo.Configuration,
buildInfo.LogsDirPath, buildInfo.CustomProperties);
}
- public static int Build(string solution, string config, string loggerOutputDir, IEnumerable<string> customProperties = null)
+ public static int Build(string solution, string[] targets, string config, string loggerOutputDir, IEnumerable<string> customProperties = null)
{
- using (var process = LaunchBuild(solution, config, loggerOutputDir, customProperties))
+ using (var process = LaunchBuild(solution, targets, config, loggerOutputDir, customProperties))
{
process.WaitForExit();
@@ -125,9 +120,9 @@ namespace GodotTools.Build
}
}
- public static async Task<int> BuildAsync(string solution, string config, string loggerOutputDir, IEnumerable<string> customProperties = null)
+ public static async Task<int> BuildAsync(string solution, IEnumerable<string> targets, string config, string loggerOutputDir, IEnumerable<string> customProperties = null)
{
- using (var process = LaunchBuild(solution, config, loggerOutputDir, customProperties))
+ using (var process = LaunchBuild(solution, targets, config, loggerOutputDir, customProperties))
{
await process.WaitForExitAsync();
@@ -135,10 +130,15 @@ namespace GodotTools.Build
}
}
- private static string BuildArguments(string solution, string config, string loggerOutputDir, List<string> customProperties)
+ private static string BuildArguments(BuildTool buildTool, string solution, IEnumerable<string> targets, string config, string loggerOutputDir, IEnumerable<string> customProperties)
{
- string arguments = $@"""{solution}"" /v:normal /t:Build ""/p:{"Configuration=" + config}"" " +
- $@"""/l:{typeof(GodotBuildLogger).FullName},{GodotBuildLogger.AssemblyPath};{loggerOutputDir}""";
+ string arguments = string.Empty;
+
+ if (buildTool == BuildTool.DotnetCli)
+ arguments += "msbuild "; // `dotnet msbuild` command
+
+ arguments += $@"""{solution}"" /v:normal /t:{string.Join(",", targets)} ""/p:{"Configuration=" + config}"" " +
+ $@"""/l:{typeof(GodotBuildLogger).FullName},{GodotBuildLogger.AssemblyPath};{loggerOutputDir}""";
foreach (string customProperty in customProperties)
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildTool.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildTool.cs
new file mode 100644
index 0000000000..a1a69334e3
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildTool.cs
@@ -0,0 +1,10 @@
+namespace GodotTools.Build
+{
+ public enum BuildTool
+ {
+ MsBuildMono,
+ MsBuildVs,
+ JetBrainsMsBuild,
+ DotnetCli
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
index af8d070cbd..f36e581a5f 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs
@@ -17,75 +17,96 @@ namespace GodotTools.Build
private static string _msbuildToolsPath = string.Empty;
private static string _msbuildUnixPath = string.Empty;
- public static string FindMsBuild()
+ public static (string, BuildTool) FindMsBuild()
{
var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
- var buildTool = (BuildManager.BuildTool)editorSettings.GetSetting("mono/builds/build_tool");
+ var buildTool = (BuildTool)editorSettings.GetSetting("mono/builds/build_tool");
if (OS.IsWindows)
{
switch (buildTool)
{
- case BuildManager.BuildTool.MsBuildVs:
+ case BuildTool.DotnetCli:
{
- if (_msbuildToolsPath.Empty() || !File.Exists(_msbuildToolsPath))
+ string dotnetCliPath = OS.PathWhich("dotnet");
+ if (!string.IsNullOrEmpty(dotnetCliPath))
+ return (dotnetCliPath, BuildTool.DotnetCli);
+ GD.PushError("Cannot find dotnet CLI executable. Fallback to MSBuild from Visual Studio.");
+ goto case BuildTool.MsBuildVs;
+ }
+ case BuildTool.MsBuildVs:
+ {
+ if (string.IsNullOrEmpty(_msbuildToolsPath) || !File.Exists(_msbuildToolsPath))
{
// Try to search it again if it wasn't found last time or if it was removed from its location
_msbuildToolsPath = FindMsBuildToolsPathOnWindows();
- if (_msbuildToolsPath.Empty())
- {
- throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMsbuildVs}'.");
- }
+ if (string.IsNullOrEmpty(_msbuildToolsPath))
+ throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMSBuildVs}'.");
}
if (!_msbuildToolsPath.EndsWith("\\"))
_msbuildToolsPath += "\\";
- return Path.Combine(_msbuildToolsPath, "MSBuild.exe");
+ return (Path.Combine(_msbuildToolsPath, "MSBuild.exe"), BuildTool.MsBuildVs);
}
- case BuildManager.BuildTool.MsBuildMono:
+ case BuildTool.MsBuildMono:
{
string msbuildPath = Path.Combine(Internal.MonoWindowsInstallRoot, "bin", "msbuild.bat");
if (!File.Exists(msbuildPath))
- {
- throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMsbuildMono}'. Tried with path: {msbuildPath}");
- }
+ throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMSBuildMono}'. Tried with path: {msbuildPath}");
- return msbuildPath;
+ return (msbuildPath, BuildTool.MsBuildMono);
}
- case BuildManager.BuildTool.JetBrainsMsBuild:
+ case BuildTool.JetBrainsMsBuild:
+ {
var editorPath = (string)editorSettings.GetSetting(RiderPathManager.EditorPathSettingName);
+
if (!File.Exists(editorPath))
throw new FileNotFoundException($"Cannot find Rider executable. Tried with path: {editorPath}");
- var riderDir = new FileInfo(editorPath).Directory.Parent;
- return Path.Combine(riderDir.FullName, @"tools\MSBuild\Current\Bin\MSBuild.exe");
+
+ var riderDir = new FileInfo(editorPath).Directory?.Parent;
+
+ string msbuildPath = Path.Combine(riderDir.FullName, @"tools\MSBuild\Current\Bin\MSBuild.exe");
+
+ if (!File.Exists(msbuildPath))
+ throw new FileNotFoundException($"Cannot find executable for '{BuildManager.PropNameMSBuildJetBrains}'. Tried with path: {msbuildPath}");
+
+ return (msbuildPath, BuildTool.JetBrainsMsBuild);
+ }
default:
throw new IndexOutOfRangeException("Invalid build tool in editor settings");
}
}
- if (OS.IsUnixLike())
+ if (OS.IsUnixLike)
{
- if (buildTool == BuildManager.BuildTool.MsBuildMono)
+ switch (buildTool)
{
- if (_msbuildUnixPath.Empty() || !File.Exists(_msbuildUnixPath))
+ case BuildTool.DotnetCli:
{
- // Try to search it again if it wasn't found last time or if it was removed from its location
- _msbuildUnixPath = FindBuildEngineOnUnix("msbuild");
+ string dotnetCliPath = OS.PathWhich("dotnet");
+ if (!string.IsNullOrEmpty(dotnetCliPath))
+ return (dotnetCliPath, BuildTool.DotnetCli);
+ GD.PushError("Cannot find dotnet CLI executable. Fallback to MSBuild from Mono.");
+ goto case BuildTool.MsBuildMono;
}
-
- if (_msbuildUnixPath.Empty())
+ case BuildTool.MsBuildMono:
{
- throw new FileNotFoundException($"Cannot find binary for '{BuildManager.PropNameMsbuildMono}'");
- }
+ if (string.IsNullOrEmpty(_msbuildUnixPath) || !File.Exists(_msbuildUnixPath))
+ {
+ // Try to search it again if it wasn't found last time or if it was removed from its location
+ _msbuildUnixPath = FindBuildEngineOnUnix("msbuild");
+ }
- return _msbuildUnixPath;
- }
- else
- {
- throw new IndexOutOfRangeException("Invalid build tool in editor settings");
+ if (string.IsNullOrEmpty(_msbuildUnixPath))
+ throw new FileNotFoundException($"Cannot find binary for '{BuildManager.PropNameMSBuildMono}'");
+
+ return (_msbuildUnixPath, BuildTool.MsBuildMono);
+ }
+ default:
+ throw new IndexOutOfRangeException("Invalid build tool in editor settings");
}
}
@@ -114,12 +135,12 @@ namespace GodotTools.Build
{
string ret = OS.PathWhich(name);
- if (!ret.Empty())
+ if (!string.IsNullOrEmpty(ret))
return ret;
string retFallback = OS.PathWhich($"{name}.exe");
- if (!retFallback.Empty())
+ if (!string.IsNullOrEmpty(retFallback))
return retFallback;
foreach (string hintDir in MsBuildHintDirs)
@@ -143,7 +164,7 @@ namespace GodotTools.Build
string vsWherePath = Environment.GetEnvironmentVariable(Internal.GodotIs32Bits() ? "ProgramFiles" : "ProgramFiles(x86)");
vsWherePath += "\\Microsoft Visual Studio\\Installer\\vswhere.exe";
- var vsWhereArgs = new[] { "-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild" };
+ var vsWhereArgs = new[] {"-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"};
var outputArray = new Godot.Collections.Array<string>();
int exitCode = Godot.OS.Execute(vsWherePath, vsWhereArgs,
@@ -171,7 +192,7 @@ namespace GodotTools.Build
string value = line.Substring(sepIdx + 1).StripEdges();
- if (value.Empty())
+ if (string.IsNullOrEmpty(value))
throw new FormatException("installationPath value is empty");
if (!value.EndsWith("\\"))
diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildInfo.cs b/modules/mono/editor/GodotTools/GodotTools/BuildInfo.cs
index 70bd552f2f..cca0983c01 100644
--- a/modules/mono/editor/GodotTools/GodotTools/BuildInfo.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildInfo.cs
@@ -10,6 +10,7 @@ namespace GodotTools
public sealed class BuildInfo : Reference // TODO Remove Reference once we have proper serialization
{
public string Solution { get; }
+ public string[] Targets { get; }
public string Configuration { get; }
public Array<string> CustomProperties { get; } = new Array<string>(); // TODO Use List once we have proper serialization
@@ -38,9 +39,10 @@ namespace GodotTools
{
}
- public BuildInfo(string solution, string configuration)
+ public BuildInfo(string solution, string[] targets, string configuration)
{
Solution = solution;
+ Targets = targets;
Configuration = configuration;
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
index 520e665595..598787ba03 100644
--- a/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildManager.cs
@@ -15,20 +15,14 @@ namespace GodotTools
{
private static readonly List<BuildInfo> BuildsInProgress = new List<BuildInfo>();
- public const string PropNameMsbuildMono = "MSBuild (Mono)";
- public const string PropNameMsbuildVs = "MSBuild (VS Build Tools)";
- public const string PropNameMsbuildJetBrains = "MSBuild (JetBrains Rider)";
+ public const string PropNameMSBuildMono = "MSBuild (Mono)";
+ public const string PropNameMSBuildVs = "MSBuild (VS Build Tools)";
+ public const string PropNameMSBuildJetBrains = "MSBuild (JetBrains Rider)";
+ public const string PropNameDotnetCli = "dotnet CLI";
public const string MsBuildIssuesFileName = "msbuild_issues.csv";
public const string MsBuildLogFileName = "msbuild_log.txt";
- public enum BuildTool
- {
- MsBuildMono,
- MsBuildVs,
- JetBrainsMsBuild
- }
-
private static void RemoveOldIssuesFile(BuildInfo buildInfo)
{
var issuesFile = GetIssuesFilePath(buildInfo);
@@ -181,10 +175,12 @@ namespace GodotTools
{
pr.Step("Building project solution", 0);
- var buildInfo = new BuildInfo(GodotSharpDirs.ProjectSlnPath, config);
+ var buildInfo = new BuildInfo(GodotSharpDirs.ProjectSlnPath, targets: new[] {"Restore", "Build"}, config);
+
+ bool escapeNeedsDoubleBackslash = buildTool == BuildTool.MsBuildMono || buildTool == BuildTool.DotnetCli;
// Add Godot defines
- string constants = buildTool != BuildTool.MsBuildMono ? "GodotDefineConstants=\"" : "GodotDefineConstants=\\\"";
+ string constants = !escapeNeedsDoubleBackslash ? "GodotDefineConstants=\"" : "GodotDefineConstants=\\\"";
foreach (var godotDefine in godotDefines)
constants += $"GODOT_{godotDefine.ToUpper().Replace("-", "_").Replace(" ", "_").Replace(";", "_")};";
@@ -192,7 +188,7 @@ namespace GodotTools
if (Internal.GodotIsRealTDouble())
constants += "GODOT_REAL_T_IS_DOUBLE;";
- constants += buildTool != BuildTool.MsBuildMono ? "\"" : "\\\"";
+ constants += !escapeNeedsDoubleBackslash ? "\"" : "\\\"";
buildInfo.CustomProperties.Add(constants);
@@ -219,7 +215,7 @@ namespace GodotTools
if (File.Exists(editorScriptsMetadataPath))
File.Copy(editorScriptsMetadataPath, playerScriptsMetadataPath);
- var currentPlayRequest = GodotSharpEditor.Instance.GodotIdeManager.GodotIdeServer.CurrentPlayRequest;
+ var currentPlayRequest = GodotSharpEditor.Instance.CurrentPlaySettings;
if (currentPlayRequest != null)
{
@@ -233,7 +229,8 @@ namespace GodotTools
",server=n");
}
- return true; // Requested play from an external editor/IDE which already built the project
+ if (!currentPlayRequest.Value.BuildBeforePlaying)
+ return true; // Requested play from an external editor/IDE which already built the project
}
var godotDefines = new[]
@@ -249,22 +246,44 @@ namespace GodotTools
{
// Build tool settings
var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings();
- var msbuild = BuildTool.MsBuildMono;
+
+ BuildTool msbuildDefault;
+
if (OS.IsWindows)
- msbuild = RiderPathManager.IsExternalEditorSetToRider(editorSettings)
- ? BuildTool.JetBrainsMsBuild
- : BuildTool.MsBuildVs;
+ {
+ if (RiderPathManager.IsExternalEditorSetToRider(editorSettings))
+ msbuildDefault = BuildTool.JetBrainsMsBuild;
+ else
+ msbuildDefault = !string.IsNullOrEmpty(OS.PathWhich("dotnet")) ? BuildTool.DotnetCli : BuildTool.MsBuildVs;
+ }
+ else
+ {
+ msbuildDefault = !string.IsNullOrEmpty(OS.PathWhich("dotnet")) ? BuildTool.DotnetCli : BuildTool.MsBuildMono;
+ }
+
+ EditorDef("mono/builds/build_tool", msbuildDefault);
- EditorDef("mono/builds/build_tool", msbuild);
+ string hintString;
+
+ if (OS.IsWindows)
+ {
+ hintString = $"{PropNameMSBuildMono}:{(int)BuildTool.MsBuildMono}," +
+ $"{PropNameMSBuildVs}:{(int)BuildTool.MsBuildVs}," +
+ $"{PropNameMSBuildJetBrains}:{(int)BuildTool.JetBrainsMsBuild}," +
+ $"{PropNameDotnetCli}:{(int)BuildTool.DotnetCli}";
+ }
+ else
+ {
+ hintString = $"{PropNameMSBuildMono}:{(int)BuildTool.MsBuildMono}," +
+ $"{PropNameDotnetCli}:{(int)BuildTool.DotnetCli}";
+ }
editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary
{
["type"] = Godot.Variant.Type.Int,
["name"] = "mono/builds/build_tool",
["hint"] = Godot.PropertyHint.Enum,
- ["hint_string"] = OS.IsWindows ?
- $"{PropNameMsbuildMono},{PropNameMsbuildVs},{PropNameMsbuildJetBrains}" :
- $"{PropNameMsbuildMono}"
+ ["hint_string"] = hintString
});
EditorDef("mono/builds/print_build_output", false);
diff --git a/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
index 938c3d8be1..0106e1f1ac 100644
--- a/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/BuildTab.cs
@@ -72,7 +72,7 @@ namespace GodotTools
{
string[] csvColumns = file.GetCsvLine();
- if (csvColumns.Length == 1 && csvColumns[0].Empty())
+ if (csvColumns.Length == 1 && string.IsNullOrEmpty(csvColumns[0]))
return;
if (csvColumns.Length != 7)
@@ -115,12 +115,12 @@ namespace GodotTools
// Get correct issue idx from issue list
int issueIndex = (int)issuesList.GetItemMetadata(idx);
- if (idx < 0 || idx >= issues.Count)
+ if (issueIndex < 0 || issueIndex >= issues.Count)
throw new IndexOutOfRangeException("Issue index out of range");
BuildIssue issue = issues[issueIndex];
- if (issue.ProjectFile.Empty() && issue.File.Empty())
+ if (string.IsNullOrEmpty(issue.ProjectFile) && string.IsNullOrEmpty(issue.File))
return;
string projectDir = issue.ProjectFile.Length > 0 ? issue.ProjectFile.GetBaseDir() : BuildInfo.Solution.GetBaseDir();
@@ -158,14 +158,14 @@ namespace GodotTools
string tooltip = string.Empty;
tooltip += $"Message: {issue.Message}";
- if (!issue.Code.Empty())
+ if (!string.IsNullOrEmpty(issue.Code))
tooltip += $"\nCode: {issue.Code}";
tooltip += $"\nType: {(issue.Warning ? "warning" : "error")}";
string text = string.Empty;
- if (!issue.File.Empty())
+ if (!string.IsNullOrEmpty(issue.File))
{
text += $"{issue.File}({issue.Line},{issue.Column}): ";
@@ -174,7 +174,7 @@ namespace GodotTools
tooltip += $"\nColumn: {issue.Column}";
}
- if (!issue.ProjectFile.Empty())
+ if (!string.IsNullOrEmpty(issue.ProjectFile))
tooltip += $"\nProject: {issue.ProjectFile}";
text += issue.Message;
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index f1765f7e19..f60e469503 100755
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
@@ -587,7 +587,7 @@ MONO_AOT_MODE_LAST = 1000,
string arch = "x86_64";
return $"{platform}-{arch}";
}
- case OS.Platforms.X11:
+ case OS.Platforms.LinuxBSD:
case OS.Platforms.Server:
{
string arch = bits == "64" ? "x86_64" : "i686";
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index d782d4e61b..6bfbc62f3b 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -168,13 +168,13 @@ namespace GodotTools.Export
// Add dependency assemblies
- var dependencies = new Godot.Collections.Dictionary<string, string>();
+ var assemblies = new Godot.Collections.Dictionary<string, string>();
string projectDllName = GodotSharpEditor.ProjectAssemblyName;
string projectDllSrcDir = Path.Combine(GodotSharpDirs.ResTempAssembliesBaseDir, buildConfig);
string projectDllSrcPath = Path.Combine(projectDllSrcDir, $"{projectDllName}.dll");
- dependencies[projectDllName] = projectDllSrcPath;
+ assemblies[projectDllName] = projectDllSrcPath;
if (platform == OS.Platforms.Android)
{
@@ -184,15 +184,15 @@ namespace GodotTools.Export
if (!File.Exists(monoAndroidAssemblyPath))
throw new FileNotFoundException("Assembly not found: 'Mono.Android'", monoAndroidAssemblyPath);
- dependencies["Mono.Android"] = monoAndroidAssemblyPath;
+ assemblies["Mono.Android"] = monoAndroidAssemblyPath;
}
string bclDir = DeterminePlatformBclDir(platform);
- var initialDependencies = dependencies.Duplicate();
- internal_GetExportedAssemblyDependencies(initialDependencies, buildConfig, bclDir, dependencies);
+ var initialAssemblies = assemblies.Duplicate();
+ internal_GetExportedAssemblyDependencies(initialAssemblies, buildConfig, bclDir, assemblies);
- AddI18NAssemblies(dependencies, bclDir);
+ AddI18NAssemblies(assemblies, bclDir);
string outputDataDir = null;
@@ -211,20 +211,32 @@ namespace GodotTools.Export
Directory.CreateDirectory(outputDataGameAssembliesDir);
}
- foreach (var dependency in dependencies)
+ foreach (var assembly in assemblies)
{
- string dependSrcPath = dependency.Value;
-
- if (assembliesInsidePck)
- {
- string dependDstPath = Path.Combine(resAssembliesDir, dependSrcPath.GetFile());
- AddFile(dependSrcPath, dependDstPath);
- }
- else
+ void AddToAssembliesDir(string fileSrcPath)
{
- string dependDstPath = Path.Combine(outputDataDir, "Assemblies", dependSrcPath.GetFile());
- File.Copy(dependSrcPath, dependDstPath);
+ if (assembliesInsidePck)
+ {
+ string fileDstPath = Path.Combine(resAssembliesDir, fileSrcPath.GetFile());
+ AddFile(fileSrcPath, fileDstPath);
+ }
+ else
+ {
+ Debug.Assert(outputDataDir != null);
+ string fileDstPath = Path.Combine(outputDataDir, "Assemblies", fileSrcPath.GetFile());
+ File.Copy(fileSrcPath, fileDstPath);
+ }
}
+
+ string assemblySrcPath = assembly.Value;
+
+ string assemblyPathWithoutExtension = Path.ChangeExtension(assemblySrcPath, null);
+ string pdbSrcPath = assemblyPathWithoutExtension + ".pdb";
+
+ AddToAssembliesDir(assemblySrcPath);
+
+ if (File.Exists(pdbSrcPath))
+ AddToAssembliesDir(pdbSrcPath);
}
// AOT compilation
@@ -254,7 +266,7 @@ namespace GodotTools.Export
ToolchainPath = aotToolchainPath
};
- AotBuilder.CompileAssemblies(this, aotOpts, features, platform, isDebug, bclDir, outputDir, outputDataDir, dependencies);
+ AotBuilder.CompileAssemblies(this, aotOpts, features, platform, isDebug, bclDir, outputDir, outputDataDir, assemblies);
}
}
@@ -366,7 +378,7 @@ namespace GodotTools.Export
if (PlatformRequiresCustomBcl(platform))
throw new FileNotFoundException($"Missing BCL (Base Class Library) for platform: {platform}");
- platformBclDir = typeof(object).Assembly.Location; // Use the one we're running on
+ platformBclDir = typeof(object).Assembly.Location.GetBaseDir(); // Use the one we're running on
}
}
@@ -402,7 +414,7 @@ namespace GodotTools.Export
case OS.Platforms.UWP:
return "net_4_x_win";
case OS.Platforms.OSX:
- case OS.Platforms.X11:
+ case OS.Platforms.LinuxBSD:
case OS.Platforms.Server:
case OS.Platforms.Haiku:
return "net_4_x";
@@ -425,7 +437,7 @@ namespace GodotTools.Export
}
[MethodImpl(MethodImplOptions.InternalCall)]
- private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialDependencies,
- string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencies);
+ private static extern void internal_GetExportedAssemblyDependencies(Godot.Collections.Dictionary<string, string> initialAssemblies,
+ string buildConfig, string customBclDir, Godot.Collections.Dictionary<string, string> dependencyAssemblies);
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
index c9d7dd26f8..eb7696685f 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs
@@ -1,4 +1,5 @@
using Godot;
+using GodotTools.Core;
using GodotTools.Export;
using GodotTools.Utils;
using System;
@@ -36,6 +37,8 @@ namespace GodotTools
public BottomPanel BottomPanel { get; private set; }
+ public PlaySettings? CurrentPlaySettings { get; set; }
+
public static string ProjectAssemblyName
{
get
@@ -227,12 +230,12 @@ namespace GodotTools
[UsedImplicitly]
public Error OpenInExternalEditor(Script script, int line, int col)
{
- var editor = (ExternalEditorId)editorSettings.GetSetting("mono/editor/external_editor");
+ var editorId = (ExternalEditorId)editorSettings.GetSetting("mono/editor/external_editor");
- switch (editor)
+ switch (editorId)
{
case ExternalEditorId.None:
- // Tells the caller to fallback to the global external editor settings or the built-in editor
+ // Not an error. Tells the caller to fallback to the global external editor settings or the built-in editor.
return Error.Unavailable;
case ExternalEditorId.VisualStudio:
throw new NotSupportedException();
@@ -248,17 +251,20 @@ namespace GodotTools
{
string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath);
- if (line >= 0)
- GodotIdeManager.SendOpenFile(scriptPath, line + 1, col);
- else
- GodotIdeManager.SendOpenFile(scriptPath);
+ GodotIdeManager.LaunchIdeAsync().ContinueWith(launchTask =>
+ {
+ var editorPick = launchTask.Result;
+ if (line >= 0)
+ editorPick?.SendOpenFile(scriptPath, line + 1, col);
+ else
+ editorPick?.SendOpenFile(scriptPath);
+ });
break;
}
-
case ExternalEditorId.VsCode:
{
- if (_vsCodePath.Empty() || !File.Exists(_vsCodePath))
+ if (string.IsNullOrEmpty(_vsCodePath) || !File.Exists(_vsCodePath))
{
// Try to search it again if it wasn't found last time or if it was removed from its location
_vsCodePath = VsCodeNames.SelectFirstNotNull(OS.PathWhich, orElse: string.Empty);
@@ -299,7 +305,7 @@ namespace GodotTools
if (line >= 0)
{
args.Add("-g");
- args.Add($"{scriptPath}:{line + 1}:{col}");
+ args.Add($"{scriptPath}:{line}:{col}");
}
else
{
@@ -310,7 +316,7 @@ namespace GodotTools
if (OS.IsOSX)
{
- if (!osxAppBundleInstalled && _vsCodePath.Empty())
+ if (!osxAppBundleInstalled && string.IsNullOrEmpty(_vsCodePath))
{
GD.PushError("Cannot find code editor: VSCode");
return Error.FileNotFound;
@@ -320,7 +326,7 @@ namespace GodotTools
}
else
{
- if (_vsCodePath.Empty())
+ if (string.IsNullOrEmpty(_vsCodePath))
{
GD.PushError("Cannot find code editor: VSCode");
return Error.FileNotFound;
@@ -340,7 +346,6 @@ namespace GodotTools
break;
}
-
default:
throw new ArgumentOutOfRangeException();
}
@@ -442,13 +447,30 @@ namespace GodotTools
{
// Migrate solution from old configuration names to: Debug, ExportDebug and ExportRelease
DotNetSolution.MigrateFromOldConfigNames(GodotSharpDirs.ProjectSlnPath);
+
+ var msbuildProject = ProjectUtils.Open(GodotSharpDirs.ProjectCsProjPath)
+ ?? throw new Exception("Cannot open C# project");
+
+ // NOTE: The order in which changes are made to the project is important
+
// Migrate csproj from old configuration names to: Debug, ExportDebug and ExportRelease
- ProjectUtils.MigrateFromOldConfigNames(GodotSharpDirs.ProjectCsProjPath);
+ ProjectUtils.MigrateFromOldConfigNames(msbuildProject);
- // Apply the other fixes after configurations are migrated
+ // Apply the other fixes only after configurations have been migrated
// Make sure the existing project has Api assembly references configured correctly
- ProjectUtils.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath);
+ ProjectUtils.FixApiHintPath(msbuildProject);
+
+ // Make sure the existing project references the Microsoft.NETFramework.ReferenceAssemblies nuget package
+ ProjectUtils.EnsureHasNugetNetFrameworkRefAssemblies(msbuildProject);
+
+ if (msbuildProject.HasUnsavedChanges)
+ {
+ // Save a copy of the project before replacing it
+ FileUtils.SaveBackupCopy(GodotSharpDirs.ProjectCsProjPath);
+
+ msbuildProject.Save();
+ }
}
catch (Exception e)
{
@@ -490,7 +512,7 @@ namespace GodotTools
$",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +
$",JetBrains Rider:{(int)ExternalEditorId.Rider}";
}
- else if (OS.IsUnixLike())
+ else if (OS.IsUnixLike)
{
settingsHintStr += $",MonoDevelop:{(int)ExternalEditorId.MonoDevelop}" +
$",Visual Studio Code:{(int)ExternalEditorId.VsCode}" +
diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
index ac9379adf8..ba527ca3b5 100644
--- a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
+++ b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj
@@ -1,123 +1,37 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{27B00618-A6F2-4828-B922-05CAEB08C286}</ProjectGuid>
- <OutputType>Library</OutputType>
- <RootNamespace>GodotTools</RootNamespace>
- <AssemblyName>GodotTools</AssemblyName>
- <TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
+ <TargetFramework>net472</TargetFramework>
+ <LangVersion>7.2</LangVersion>
+ <GodotApiConfiguration>Debug</GodotApiConfiguration> <!-- The Godot editor uses the Debug Godot API assemblies -->
<GodotSourceRootPath>$(SolutionDir)/../../../../</GodotSourceRootPath>
- <DataDirToolsOutputPath>$(GodotSourceRootPath)/bin/GodotSharp/Tools</DataDirToolsOutputPath>
- <GodotApiConfiguration>Debug</GodotApiConfiguration>
- <LangVersion>7</LangVersion>
+ <GodotOutputDataDir>$(GodotSourceRootPath)/bin/GodotSharp</GodotOutputDataDir>
+ <GodotApiAssembliesDir>$(GodotOutputDataDir)/Api/$(GodotApiConfiguration)</GodotApiAssembliesDir>
</PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>portable</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug</OutputPath>
- <DefineConstants>DEBUG;</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <Optimize>true</Optimize>
- <OutputPath>bin\Release</OutputPath>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
+ <PropertyGroup Condition=" Exists('$(GodotApiAssembliesDir)/GodotSharp.dll') ">
+ <!-- The project is part of the Godot source tree -->
+ <!-- Use the Godot source tree output folder instead of '$(ProjectDir)/bin' -->
+ <OutputPath>$(GodotOutputDataDir)/Tools</OutputPath>
+ <!-- Must not append '$(TargetFramework)' to the output path in this case -->
+ <AppendTargetFrameworkToOutputPath>False</AppendTargetFrameworkToOutputPath>
</PropertyGroup>
<ItemGroup>
- <Reference Include="JetBrains.Annotations, Version=2019.1.3.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325">
- <HintPath>..\packages\JetBrains.Annotations.2019.1.3\lib\net20\JetBrains.Annotations.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed">
- <HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="System" />
+ <PackageReference Include="JetBrains.Annotations" Version="2019.1.3.0" ExcludeAssets="runtime" PrivateAssets="all" />
+ <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
+ <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<Reference Include="GodotSharp">
- <HintPath>$(GodotSourceRootPath)/bin/GodotSharp/Api/$(GodotApiConfiguration)/GodotSharp.dll</HintPath>
+ <HintPath>$(GodotApiAssembliesDir)/GodotSharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="GodotSharpEditor">
- <HintPath>$(GodotSourceRootPath)/bin/GodotSharp/Api/$(GodotApiConfiguration)/GodotSharpEditor.dll</HintPath>
+ <HintPath>$(GodotApiAssembliesDir)/GodotSharpEditor.dll</HintPath>
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
- <Compile Include="Build\MsBuildFinder.cs" />
- <Compile Include="Export\AotBuilder.cs" />
- <Compile Include="Export\ExportPlugin.cs" />
- <Compile Include="Export\XcodeHelper.cs" />
- <Compile Include="ExternalEditorId.cs" />
- <Compile Include="Ides\GodotIdeManager.cs" />
- <Compile Include="Ides\GodotIdeServer.cs" />
- <Compile Include="Ides\MonoDevelop\EditorId.cs" />
- <Compile Include="Ides\MonoDevelop\Instance.cs" />
- <Compile Include="Ides\Rider\RiderPathLocator.cs" />
- <Compile Include="Ides\Rider\RiderPathManager.cs" />
- <Compile Include="Internals\EditorProgress.cs" />
- <Compile Include="Internals\GodotSharpDirs.cs" />
- <Compile Include="Internals\Internal.cs" />
- <Compile Include="Internals\ScriptClassParser.cs" />
- <Compile Include="Internals\Globals.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Build\BuildSystem.cs" />
- <Compile Include="Utils\Directory.cs" />
- <Compile Include="Utils\File.cs" />
- <Compile Include="Utils\NotifyAwaiter.cs" />
- <Compile Include="Utils\OS.cs" />
- <Compile Include="GodotSharpEditor.cs" />
- <Compile Include="BuildManager.cs" />
- <Compile Include="HotReloadAssemblyWatcher.cs" />
- <Compile Include="BuildInfo.cs" />
- <Compile Include="BuildTab.cs" />
- <Compile Include="BottomPanel.cs" />
- <Compile Include="CsProjOperations.cs" />
- <Compile Include="Utils\CollectionExtensions.cs" />
- <Compile Include="Utils\User32Dll.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\GodotTools.BuildLogger\GodotTools.BuildLogger.csproj">
- <Project>{6ce9a984-37b1-4f8a-8fe9-609f05f071b3}</Project>
- <Name>GodotTools.BuildLogger</Name>
- </ProjectReference>
- <ProjectReference Include="..\GodotTools.IdeConnection\GodotTools.IdeConnection.csproj">
- <Project>{92600954-25f0-4291-8e11-1fee9fc4be20}</Project>
- <Name>GodotTools.IdeConnection</Name>
- </ProjectReference>
- <ProjectReference Include="..\GodotTools.ProjectEditor\GodotTools.ProjectEditor.csproj">
- <Project>{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}</Project>
- <Name>GodotTools.ProjectEditor</Name>
- </ProjectReference>
- <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj">
- <Project>{639E48BD-44E5-4091-8EDD-22D36DC0768D}</Project>
- <Name>GodotTools.Core</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <None Include="packages.config" />
+ <ProjectReference Include="..\GodotTools.BuildLogger\GodotTools.BuildLogger.csproj" />
+ <ProjectReference Include="..\GodotTools.IdeMessaging\GodotTools.IdeMessaging.csproj" />
+ <ProjectReference Include="..\GodotTools.ProjectEditor\GodotTools.ProjectEditor.csproj" />
+ <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj" />
</ItemGroup>
- <Target Name="CopyToDataDir" AfterTargets="Build">
- <ItemGroup>
- <GodotToolsCopy Include="$(OutputPath)\GodotTools*.dll" />
- <GodotToolsCopy Include="$(OutputPath)\Newtonsoft.Json.dll" />
- <GodotToolsCopy Include="$(OutputPath)\DotNet.Glob.dll" />
- </ItemGroup>
- <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
- <GodotToolsCopy Include="$(OutputPath)\GodotTools*.pdb" />
- </ItemGroup>
- <Copy SourceFiles="@(GodotToolsCopy)" DestinationFolder="$(DataDirToolsOutputPath)" ContinueOnError="false" />
- </Target>
- <Target Name="BuildAlwaysCopyToDataDir">
- <!-- Custom target run by SCons to make sure the CopyToDataDir target is always executed, without having to use DisableFastUpToDateCheck -->
- <CallTarget Targets="Build" />
- <CallTarget Targets="CopyToDataDir" />
- </Target>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
index 54f0ffab96..e4932ca217 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeManager.cs
@@ -1,73 +1,104 @@
using System;
using System.IO;
+using System.Threading.Tasks;
using Godot;
-using GodotTools.IdeConnection;
+using GodotTools.IdeMessaging;
+using GodotTools.IdeMessaging.Requests;
using GodotTools.Internals;
namespace GodotTools.Ides
{
- public class GodotIdeManager : Node, ISerializationListener
+ public sealed class GodotIdeManager : Node, ISerializationListener
{
- public GodotIdeServer GodotIdeServer { get; private set; }
+ private MessagingServer MessagingServer { get; set; }
private MonoDevelop.Instance monoDevelInstance;
private MonoDevelop.Instance vsForMacInstance;
- private GodotIdeServer GetRunningServer()
+ private MessagingServer GetRunningOrNewServer()
{
- if (GodotIdeServer != null && !GodotIdeServer.IsDisposed)
- return GodotIdeServer;
- StartServer();
- return GodotIdeServer;
+ if (MessagingServer != null && !MessagingServer.IsDisposed)
+ return MessagingServer;
+
+ MessagingServer?.Dispose();
+ MessagingServer = new MessagingServer(OS.GetExecutablePath(), ProjectSettings.GlobalizePath(GodotSharpDirs.ResMetadataDir), new GodotLogger());
+
+ _ = MessagingServer.Listen();
+
+ return MessagingServer;
}
public override void _Ready()
{
- StartServer();
+ _ = GetRunningOrNewServer();
}
public void OnBeforeSerialize()
{
- GodotIdeServer?.Dispose();
}
public void OnAfterDeserialize()
{
- StartServer();
+ _ = GetRunningOrNewServer();
}
- private ILogger logger;
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
- protected ILogger Logger
+ if (disposing)
+ {
+ MessagingServer?.Dispose();
+ }
+ }
+
+ private string GetExternalEditorIdentity(ExternalEditorId editorId)
{
- get => logger ?? (logger = new GodotLogger());
+ // Manually convert to string to avoid breaking compatibility in case we rename the enum fields.
+ switch (editorId)
+ {
+ case ExternalEditorId.None:
+ return null;
+ case ExternalEditorId.VisualStudio:
+ return "VisualStudio";
+ case ExternalEditorId.VsCode:
+ return "VisualStudioCode";
+ case ExternalEditorId.Rider:
+ return "Rider";
+ case ExternalEditorId.VisualStudioForMac:
+ return "VisualStudioForMac";
+ case ExternalEditorId.MonoDevelop:
+ return "MonoDevelop";
+ default:
+ throw new NotImplementedException();
+ }
}
- private void StartServer()
+ public async Task<EditorPick?> LaunchIdeAsync(int millisecondsTimeout = 10000)
{
- GodotIdeServer?.Dispose();
- GodotIdeServer = new GodotIdeServer(LaunchIde,
- OS.GetExecutablePath(),
- ProjectSettings.GlobalizePath(GodotSharpDirs.ResMetadataDir));
+ var editorId = (ExternalEditorId)GodotSharpEditor.Instance.GetEditorInterface()
+ .GetEditorSettings().GetSetting("mono/editor/external_editor");
+ string editorIdentity = GetExternalEditorIdentity(editorId);
- GodotIdeServer.Logger = Logger;
+ var runningServer = GetRunningOrNewServer();
- GodotIdeServer.StartServer();
- }
+ if (runningServer.IsAnyConnected(editorIdentity))
+ return new EditorPick(editorIdentity);
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
+ LaunchIde(editorId, editorIdentity);
+
+ var timeoutTask = Task.Delay(millisecondsTimeout);
+ var completedTask = await Task.WhenAny(timeoutTask, runningServer.AwaitClientConnected(editorIdentity));
+
+ if (completedTask != timeoutTask)
+ return new EditorPick(editorIdentity);
- GodotIdeServer?.Dispose();
+ return null;
}
- private void LaunchIde()
+ private void LaunchIde(ExternalEditorId editorId, string editorIdentity)
{
- var editor = (ExternalEditorId)GodotSharpEditor.Instance.GetEditorInterface()
- .GetEditorSettings().GetSetting("mono/editor/external_editor");
-
- switch (editor)
+ switch (editorId)
{
case ExternalEditorId.None:
case ExternalEditorId.VisualStudio:
@@ -80,14 +111,14 @@ namespace GodotTools.Ides
{
MonoDevelop.Instance GetMonoDevelopInstance(string solutionPath)
{
- if (Utils.OS.IsOSX && editor == ExternalEditorId.VisualStudioForMac)
+ if (Utils.OS.IsOSX && editorId == ExternalEditorId.VisualStudioForMac)
{
- vsForMacInstance = vsForMacInstance ??
+ vsForMacInstance = (vsForMacInstance?.IsDisposed ?? true ? null : vsForMacInstance) ??
new MonoDevelop.Instance(solutionPath, MonoDevelop.EditorId.VisualStudioForMac);
return vsForMacInstance;
}
- monoDevelInstance = monoDevelInstance ??
+ monoDevelInstance = (monoDevelInstance?.IsDisposed ?? true ? null : monoDevelInstance) ??
new MonoDevelop.Instance(solutionPath, MonoDevelop.EditorId.MonoDevelop);
return monoDevelInstance;
}
@@ -96,12 +127,25 @@ namespace GodotTools.Ides
{
var instance = GetMonoDevelopInstance(GodotSharpDirs.ProjectSlnPath);
- if (!instance.IsRunning)
+ if (instance.IsRunning && !GetRunningOrNewServer().IsAnyConnected(editorIdentity))
+ {
+ // After launch we wait up to 30 seconds for the IDE to connect to our messaging server.
+ var waitAfterLaunch = TimeSpan.FromSeconds(30);
+ var timeSinceLaunch = DateTime.Now - instance.LaunchTime;
+ if (timeSinceLaunch > waitAfterLaunch)
+ {
+ instance.Dispose();
+ instance.Execute();
+ }
+ }
+ else if (!instance.IsRunning)
+ {
instance.Execute();
+ }
}
catch (FileNotFoundException)
{
- string editorName = editor == ExternalEditorId.VisualStudioForMac ? "Visual Studio" : "MonoDevelop";
+ string editorName = editorId == ExternalEditorId.VisualStudioForMac ? "Visual Studio" : "MonoDevelop";
GD.PushError($"Cannot find code editor: {editorName}");
}
@@ -113,26 +157,45 @@ namespace GodotTools.Ides
}
}
- private void WriteMessage(string id, params string[] arguments)
+ public readonly struct EditorPick
{
- GetRunningServer().WriteMessage(new Message(id, arguments));
- }
+ private readonly string identity;
- public void SendOpenFile(string file)
- {
- WriteMessage("OpenFile", file);
- }
+ public EditorPick(string identity)
+ {
+ this.identity = identity;
+ }
- public void SendOpenFile(string file, int line)
- {
- WriteMessage("OpenFile", file, line.ToString());
- }
+ public bool IsAnyConnected() =>
+ GodotSharpEditor.Instance.GodotIdeManager.GetRunningOrNewServer().IsAnyConnected(identity);
- public void SendOpenFile(string file, int line, int column)
- {
- WriteMessage("OpenFile", file, line.ToString(), column.ToString());
+ private void SendRequest<TResponse>(Request request)
+ where TResponse : Response, new()
+ {
+ // Logs an error if no client is connected with the specified identity
+ GodotSharpEditor.Instance.GodotIdeManager
+ .GetRunningOrNewServer()
+ .BroadcastRequest<TResponse>(identity, request);
+ }
+
+ public void SendOpenFile(string file)
+ {
+ SendRequest<OpenFileResponse>(new OpenFileRequest {File = file});
+ }
+
+ public void SendOpenFile(string file, int line)
+ {
+ SendRequest<OpenFileResponse>(new OpenFileRequest {File = file, Line = line});
+ }
+
+ public void SendOpenFile(string file, int line, int column)
+ {
+ SendRequest<OpenFileResponse>(new OpenFileRequest {File = file, Line = line, Column = column});
+ }
}
+ public EditorPick PickEditor(ExternalEditorId editorId) => new EditorPick(GetExternalEditorIdentity(editorId));
+
private class GodotLogger : ILogger
{
public void LogDebug(string message)
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs
deleted file mode 100644
index 72676a8b24..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/GodotIdeServer.cs
+++ /dev/null
@@ -1,212 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using GodotTools.IdeConnection;
-using GodotTools.Internals;
-using GodotTools.Utils;
-using Directory = System.IO.Directory;
-using File = System.IO.File;
-using Thread = System.Threading.Thread;
-
-namespace GodotTools.Ides
-{
- public class GodotIdeServer : GodotIdeBase
- {
- private readonly TcpListener listener;
- private readonly FileStream metaFile;
- private readonly Action launchIdeAction;
- private readonly NotifyAwaiter<bool> clientConnectedAwaiter = new NotifyAwaiter<bool>();
-
- private async Task<bool> AwaitClientConnected()
- {
- return await clientConnectedAwaiter.Reset();
- }
-
- public GodotIdeServer(Action launchIdeAction, string editorExecutablePath, string projectMetadataDir)
- : base(projectMetadataDir)
- {
- messageHandlers = InitializeMessageHandlers();
-
- this.launchIdeAction = launchIdeAction;
-
- // Make sure the directory exists
- Directory.CreateDirectory(projectMetadataDir);
-
- // The Godot editor's file system thread can keep the file open for writing, so we are forced to allow write sharing...
- const FileShare metaFileShare = FileShare.ReadWrite;
-
- metaFile = File.Open(MetaFilePath, FileMode.Create, FileAccess.Write, metaFileShare);
-
- listener = new TcpListener(new IPEndPoint(IPAddress.Loopback, port: 0));
- listener.Start();
-
- int port = ((IPEndPoint)listener.Server.LocalEndPoint).Port;
- using (var metaFileWriter = new StreamWriter(metaFile, Encoding.UTF8))
- {
- metaFileWriter.WriteLine(port);
- metaFileWriter.WriteLine(editorExecutablePath);
- }
-
- StartServer();
- }
-
- public void StartServer()
- {
- var serverThread = new Thread(RunServerThread) { Name = "Godot Ide Connection Server" };
- serverThread.Start();
- }
-
- private void RunServerThread()
- {
- SynchronizationContext.SetSynchronizationContext(Godot.Dispatcher.SynchronizationContext);
-
- try
- {
- while (!IsDisposed)
- {
- TcpClient tcpClient = listener.AcceptTcpClient();
-
- Logger.LogInfo("Connection open with Ide Client");
-
- lock (ConnectionLock)
- {
- Connection = new GodotIdeConnectionServer(tcpClient, HandleMessage);
- Connection.Logger = Logger;
- }
-
- Connected += () => clientConnectedAwaiter.SetResult(true);
-
- Connection.Start();
- }
- }
- catch (Exception e)
- {
- if (!IsDisposed && !(e is SocketException se && se.SocketErrorCode == SocketError.Interrupted))
- throw;
- }
- }
-
- public async void WriteMessage(Message message)
- {
- async Task LaunchIde()
- {
- if (IsConnected)
- return;
-
- launchIdeAction();
- await Task.WhenAny(Task.Delay(10000), AwaitClientConnected());
- }
-
- await LaunchIde();
-
- if (!IsConnected)
- {
- Logger.LogError("Cannot write message: Godot Ide Server not connected");
- return;
- }
-
- Connection.WriteMessage(message);
- }
-
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
-
- if (disposing)
- {
- listener?.Stop();
-
- metaFile?.Dispose();
-
- File.Delete(MetaFilePath);
- }
- }
-
- protected virtual bool HandleMessage(Message message)
- {
- if (messageHandlers.TryGetValue(message.Id, out var action))
- {
- action(message.Arguments);
- return true;
- }
-
- return false;
- }
-
- private readonly Dictionary<string, Action<string[]>> messageHandlers;
-
- private Dictionary<string, Action<string[]>> InitializeMessageHandlers()
- {
- return new Dictionary<string, Action<string[]>>
- {
- ["Play"] = args =>
- {
- switch (args.Length)
- {
- case 0:
- Play();
- return;
- case 2:
- Play(debuggerHost: args[0], debuggerPort: int.Parse(args[1]));
- return;
- default:
- throw new ArgumentException();
- }
- },
- ["ReloadScripts"] = args => ReloadScripts()
- };
- }
-
- private void DispatchToMainThread(Action action)
- {
- var d = new SendOrPostCallback(state => action());
- Godot.Dispatcher.SynchronizationContext.Post(d, null);
- }
-
- private void Play()
- {
- DispatchToMainThread(() =>
- {
- CurrentPlayRequest = new PlayRequest();
- Internal.EditorRunPlay();
- CurrentPlayRequest = null;
- });
- }
-
- private void Play(string debuggerHost, int debuggerPort)
- {
- DispatchToMainThread(() =>
- {
- CurrentPlayRequest = new PlayRequest(debuggerHost, debuggerPort);
- Internal.EditorRunPlay();
- CurrentPlayRequest = null;
- });
- }
-
- private void ReloadScripts()
- {
- DispatchToMainThread(Internal.ScriptEditorDebugger_ReloadScripts);
- }
-
- public PlayRequest? CurrentPlayRequest { get; private set; }
-
- public struct PlayRequest
- {
- public bool HasDebugger { get; }
- public string DebuggerHost { get; }
- public int DebuggerPort { get; }
-
- public PlayRequest(string debuggerHost, int debuggerPort)
- {
- HasDebugger = true;
- DebuggerHost = debuggerHost;
- DebuggerPort = debuggerPort;
- }
- }
- }
-}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs
new file mode 100644
index 0000000000..32f264d100
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/MessagingServer.cs
@@ -0,0 +1,360 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using GodotTools.IdeMessaging;
+using GodotTools.IdeMessaging.Requests;
+using GodotTools.IdeMessaging.Utils;
+using GodotTools.Internals;
+using Newtonsoft.Json;
+using Directory = System.IO.Directory;
+using File = System.IO.File;
+
+namespace GodotTools.Ides
+{
+ public sealed class MessagingServer : IDisposable
+ {
+ private readonly ILogger logger;
+
+ private readonly FileStream metaFile;
+ private string MetaFilePath { get; }
+
+ private readonly SemaphoreSlim peersSem = new SemaphoreSlim(1);
+
+ private readonly TcpListener listener;
+
+ private readonly Dictionary<string, Queue<NotifyAwaiter<bool>>> clientConnectedAwaiters = new Dictionary<string, Queue<NotifyAwaiter<bool>>>();
+ private readonly Dictionary<string, Queue<NotifyAwaiter<bool>>> clientDisconnectedAwaiters = new Dictionary<string, Queue<NotifyAwaiter<bool>>>();
+
+ public async Task<bool> AwaitClientConnected(string identity)
+ {
+ if (!clientConnectedAwaiters.TryGetValue(identity, out var queue))
+ {
+ queue = new Queue<NotifyAwaiter<bool>>();
+ clientConnectedAwaiters.Add(identity, queue);
+ }
+
+ var awaiter = new NotifyAwaiter<bool>();
+ queue.Enqueue(awaiter);
+ return await awaiter;
+ }
+
+ public async Task<bool> AwaitClientDisconnected(string identity)
+ {
+ if (!clientDisconnectedAwaiters.TryGetValue(identity, out var queue))
+ {
+ queue = new Queue<NotifyAwaiter<bool>>();
+ clientDisconnectedAwaiters.Add(identity, queue);
+ }
+
+ var awaiter = new NotifyAwaiter<bool>();
+ queue.Enqueue(awaiter);
+ return await awaiter;
+ }
+
+ public bool IsDisposed { get; private set; }
+
+ public bool IsAnyConnected(string identity) => string.IsNullOrEmpty(identity) ?
+ Peers.Count > 0 :
+ Peers.Any(c => c.RemoteIdentity == identity);
+
+ private List<Peer> Peers { get; } = new List<Peer>();
+
+ ~MessagingServer()
+ {
+ Dispose(disposing: false);
+ }
+
+ public async void Dispose()
+ {
+ if (IsDisposed)
+ return;
+
+ using (await peersSem.UseAsync())
+ {
+ if (IsDisposed) // lock may not be fair
+ return;
+ IsDisposed = true;
+ }
+
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ foreach (var connection in Peers)
+ connection.Dispose();
+ Peers.Clear();
+ listener?.Stop();
+
+ metaFile?.Dispose();
+
+ File.Delete(MetaFilePath);
+ }
+ }
+
+ public MessagingServer(string editorExecutablePath, string projectMetadataDir, ILogger logger)
+ {
+ this.logger = logger;
+
+ MetaFilePath = Path.Combine(projectMetadataDir, GodotIdeMetadata.DefaultFileName);
+
+ // Make sure the directory exists
+ Directory.CreateDirectory(projectMetadataDir);
+
+ // The Godot editor's file system thread can keep the file open for writing, so we are forced to allow write sharing...
+ const FileShare metaFileShare = FileShare.ReadWrite;
+
+ metaFile = File.Open(MetaFilePath, FileMode.Create, FileAccess.Write, metaFileShare);
+
+ listener = new TcpListener(new IPEndPoint(IPAddress.Loopback, port: 0));
+ listener.Start();
+
+ int port = ((IPEndPoint)listener.Server.LocalEndPoint).Port;
+ using (var metaFileWriter = new StreamWriter(metaFile, Encoding.UTF8))
+ {
+ metaFileWriter.WriteLine(port);
+ metaFileWriter.WriteLine(editorExecutablePath);
+ }
+ }
+
+ private async Task AcceptClient(TcpClient tcpClient)
+ {
+ logger.LogDebug("Accept client...");
+
+ using (var peer = new Peer(tcpClient, new ServerHandshake(), new ServerMessageHandler(), logger))
+ {
+ // ReSharper disable AccessToDisposedClosure
+ peer.Connected += () =>
+ {
+ logger.LogInfo("Connection open with Ide Client");
+
+ if (clientConnectedAwaiters.TryGetValue(peer.RemoteIdentity, out var queue))
+ {
+ while (queue.Count > 0)
+ queue.Dequeue().SetResult(true);
+ clientConnectedAwaiters.Remove(peer.RemoteIdentity);
+ }
+ };
+
+ peer.Disconnected += () =>
+ {
+ if (clientDisconnectedAwaiters.TryGetValue(peer.RemoteIdentity, out var queue))
+ {
+ while (queue.Count > 0)
+ queue.Dequeue().SetResult(true);
+ clientDisconnectedAwaiters.Remove(peer.RemoteIdentity);
+ }
+ };
+ // ReSharper restore AccessToDisposedClosure
+
+ try
+ {
+ if (!await peer.DoHandshake("server"))
+ {
+ logger.LogError("Handshake failed");
+ return;
+ }
+ }
+ catch (Exception e)
+ {
+ logger.LogError("Handshake failed with unhandled exception: ", e);
+ return;
+ }
+
+ using (await peersSem.UseAsync())
+ Peers.Add(peer);
+
+ try
+ {
+ await peer.Process();
+ }
+ finally
+ {
+ using (await peersSem.UseAsync())
+ Peers.Remove(peer);
+ }
+ }
+ }
+
+ public async Task Listen()
+ {
+ try
+ {
+ while (!IsDisposed)
+ _ = AcceptClient(await listener.AcceptTcpClientAsync());
+ }
+ catch (Exception e)
+ {
+ if (!IsDisposed && !(e is SocketException se && se.SocketErrorCode == SocketError.Interrupted))
+ throw;
+ }
+ }
+
+ public async void BroadcastRequest<TResponse>(string identity, Request request)
+ where TResponse : Response, new()
+ {
+ using (await peersSem.UseAsync())
+ {
+ if (!IsAnyConnected(identity))
+ {
+ logger.LogError("Cannot write request. No client connected to the Godot Ide Server.");
+ return;
+ }
+
+ var selectedConnections = string.IsNullOrEmpty(identity) ?
+ Peers :
+ Peers.Where(c => c.RemoteIdentity == identity);
+
+ string body = JsonConvert.SerializeObject(request);
+
+ foreach (var connection in selectedConnections)
+ _ = connection.SendRequest<TResponse>(request.Id, body);
+ }
+ }
+
+ private class ServerHandshake : IHandshake
+ {
+ private static readonly string ServerHandshakeBase = $"{Peer.ServerHandshakeName},Version={Peer.ProtocolVersionMajor}.{Peer.ProtocolVersionMinor}.{Peer.ProtocolVersionRevision}";
+ private static readonly string ClientHandshakePattern = $@"{Regex.Escape(Peer.ClientHandshakeName)},Version=([0-9]+)\.([0-9]+)\.([0-9]+),([_a-zA-Z][_a-zA-Z0-9]{{0,63}})";
+
+ public string GetHandshakeLine(string identity) => $"{ServerHandshakeBase},{identity}";
+
+ public bool IsValidPeerHandshake(string handshake, out string identity, ILogger logger)
+ {
+ identity = null;
+
+ var match = Regex.Match(handshake, ClientHandshakePattern);
+
+ if (!match.Success)
+ return false;
+
+ if (!uint.TryParse(match.Groups[1].Value, out uint clientMajor) || Peer.ProtocolVersionMajor != clientMajor)
+ {
+ logger.LogDebug("Incompatible major version: " + match.Groups[1].Value);
+ return false;
+ }
+
+ // ReSharper disable once ConditionIsAlwaysTrueOrFalse
+ if (!uint.TryParse(match.Groups[2].Value, out uint clientMinor) || Peer.ProtocolVersionMinor > clientMinor)
+ {
+ logger.LogDebug("Incompatible minor version: " + match.Groups[2].Value);
+ return false;
+ }
+
+ if (!uint.TryParse(match.Groups[3].Value, out uint _)) // Revision
+ {
+ logger.LogDebug("Incompatible revision build: " + match.Groups[3].Value);
+ return false;
+ }
+
+ identity = match.Groups[4].Value;
+
+ return true;
+ }
+ }
+
+ private class ServerMessageHandler : IMessageHandler
+ {
+ private static void DispatchToMainThread(Action action)
+ {
+ var d = new SendOrPostCallback(state => action());
+ Godot.Dispatcher.SynchronizationContext.Post(d, null);
+ }
+
+ private readonly Dictionary<string, Peer.RequestHandler> requestHandlers = InitializeRequestHandlers();
+
+ public async Task<MessageContent> HandleRequest(Peer peer, string id, MessageContent content, ILogger logger)
+ {
+ if (!requestHandlers.TryGetValue(id, out var handler))
+ {
+ logger.LogError($"Received unknown request: {id}");
+ return new MessageContent(MessageStatus.RequestNotSupported, "null");
+ }
+
+ try
+ {
+ var response = await handler(peer, content);
+ return new MessageContent(response.Status, JsonConvert.SerializeObject(response));
+ }
+ catch (JsonException)
+ {
+ logger.LogError($"Received request with invalid body: {id}");
+ return new MessageContent(MessageStatus.InvalidRequestBody, "null");
+ }
+ }
+
+ private static Dictionary<string, Peer.RequestHandler> InitializeRequestHandlers()
+ {
+ return new Dictionary<string, Peer.RequestHandler>
+ {
+ [PlayRequest.Id] = async (peer, content) =>
+ {
+ _ = JsonConvert.DeserializeObject<PlayRequest>(content.Body);
+ return await HandlePlay();
+ },
+ [DebugPlayRequest.Id] = async (peer, content) =>
+ {
+ var request = JsonConvert.DeserializeObject<DebugPlayRequest>(content.Body);
+ return await HandleDebugPlay(request);
+ },
+ [ReloadScriptsRequest.Id] = async (peer, content) =>
+ {
+ _ = JsonConvert.DeserializeObject<ReloadScriptsRequest>(content.Body);
+ return await HandleReloadScripts();
+ },
+ [CodeCompletionRequest.Id] = async (peer, content) =>
+ {
+ var request = JsonConvert.DeserializeObject<CodeCompletionRequest>(content.Body);
+ return await HandleCodeCompletionRequest(request);
+ }
+ };
+ }
+
+ private static Task<Response> HandlePlay()
+ {
+ DispatchToMainThread(() =>
+ {
+ GodotSharpEditor.Instance.CurrentPlaySettings = new PlaySettings();
+ Internal.EditorRunPlay();
+ GodotSharpEditor.Instance.CurrentPlaySettings = null;
+ });
+ return Task.FromResult<Response>(new PlayResponse());
+ }
+
+ private static Task<Response> HandleDebugPlay(DebugPlayRequest request)
+ {
+ DispatchToMainThread(() =>
+ {
+ GodotSharpEditor.Instance.CurrentPlaySettings =
+ new PlaySettings(request.DebuggerHost, request.DebuggerPort, request.BuildBeforePlaying ?? true);
+ Internal.EditorRunPlay();
+ GodotSharpEditor.Instance.CurrentPlaySettings = null;
+ });
+ return Task.FromResult<Response>(new DebugPlayResponse());
+ }
+
+ private static Task<Response> HandleReloadScripts()
+ {
+ DispatchToMainThread(Internal.ScriptEditorDebugger_ReloadScripts);
+ return Task.FromResult<Response>(new ReloadScriptsResponse());
+ }
+
+ private static async Task<Response> HandleCodeCompletionRequest(CodeCompletionRequest request)
+ {
+ var response = new CodeCompletionResponse {Kind = request.Kind, ScriptFile = request.ScriptFile};
+ response.Suggestions = await Task.Run(() => Internal.CodeCompletionRequest(response.Kind, response.ScriptFile));
+ return response;
+ }
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
index 6026c109ad..d6fa2eeba7 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/MonoDevelop/Instance.cs
@@ -7,14 +7,16 @@ using GodotTools.Utils;
namespace GodotTools.Ides.MonoDevelop
{
- public class Instance
+ public class Instance : IDisposable
{
+ public DateTime LaunchTime { get; private set; }
private readonly string solutionFile;
private readonly EditorId editorId;
private Process process;
public bool IsRunning => process != null && !process.HasExited;
+ public bool IsDisposed { get; private set; }
public void Execute()
{
@@ -59,6 +61,8 @@ namespace GodotTools.Ides.MonoDevelop
if (command == null)
throw new FileNotFoundException();
+ LaunchTime = DateTime.Now;
+
if (newWindow)
{
process = Process.Start(new ProcessStartInfo
@@ -88,6 +92,12 @@ namespace GodotTools.Ides.MonoDevelop
this.editorId = editorId;
}
+ public void Dispose()
+ {
+ IsDisposed = true;
+ process?.Dispose();
+ }
+
private static readonly IReadOnlyDictionary<EditorId, string> ExecutableNames;
private static readonly IReadOnlyDictionary<EditorId, string> BundleIds;
@@ -118,7 +128,7 @@ namespace GodotTools.Ides.MonoDevelop
{EditorId.MonoDevelop, "MonoDevelop.exe"}
};
}
- else if (OS.IsUnixLike())
+ else if (OS.IsUnixLike)
{
ExecutableNames = new Dictionary<EditorId, string>
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
index e3a4fa7b45..e22e9af919 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Ides/Rider/RiderPathLocator.cs
@@ -36,7 +36,7 @@ namespace GodotTools.Ides.Rider
{
return CollectRiderInfosMac();
}
- if (OS.IsUnixLike())
+ if (OS.IsUnixLike)
{
return CollectAllRiderPathsLinux();
}
@@ -141,16 +141,16 @@ namespace GodotTools.Ides.Rider
if (OS.IsOSX)
{
var home = Environment.GetEnvironmentVariable("HOME");
- if (string.IsNullOrEmpty(home))
+ if (string.IsNullOrEmpty(home))
return string.Empty;
var localAppData = Path.Combine(home, @"Library/Application Support");
return GetToolboxRiderRootPath(localAppData);
}
- if (OS.IsUnixLike())
+ if (OS.IsUnixLike)
{
var home = Environment.GetEnvironmentVariable("HOME");
- if (string.IsNullOrEmpty(home))
+ if (string.IsNullOrEmpty(home))
return string.Empty;
var localAppData = Path.Combine(home, @".local/share");
return GetToolboxRiderRootPath(localAppData);
@@ -209,7 +209,7 @@ namespace GodotTools.Ides.Rider
private static string GetRelativePathToBuildTxt()
{
- if (OS.IsWindows || OS.IsUnixLike())
+ if (OS.IsWindows || OS.IsUnixLike)
return "../../build.txt";
if (OS.IsOSX)
return "Contents/Resources/build.txt";
@@ -322,7 +322,7 @@ namespace GodotTools.Ides.Rider
class SettingsJson
{
public string install_location;
-
+
[CanBeNull]
public static string GetInstallLocationFromJson(string json)
{
diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
index 026a7db89c..7e5049e4b7 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs
@@ -2,6 +2,7 @@ using System;
using System.Runtime.CompilerServices;
using Godot;
using Godot.Collections;
+using GodotTools.IdeMessaging.Requests;
namespace GodotTools.Internals
{
@@ -52,6 +53,9 @@ namespace GodotTools.Internals
public static void ScriptEditorDebugger_ReloadScripts() => internal_ScriptEditorDebugger_ReloadScripts();
+ public static string[] CodeCompletionRequest(CodeCompletionRequest.CompletionKind kind, string scriptFile) =>
+ internal_CodeCompletionRequest((int)kind, scriptFile);
+
#region Internal
[MethodImpl(MethodImplOptions.InternalCall)]
@@ -111,6 +115,9 @@ namespace GodotTools.Internals
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void internal_ScriptEditorDebugger_ReloadScripts();
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ private static extern string[] internal_CodeCompletionRequest(int kind, string scriptFile);
+
#endregion
}
}
diff --git a/modules/mono/editor/GodotTools/GodotTools/PlaySettings.cs b/modules/mono/editor/GodotTools/GodotTools/PlaySettings.cs
new file mode 100644
index 0000000000..820d0c0b83
--- /dev/null
+++ b/modules/mono/editor/GodotTools/GodotTools/PlaySettings.cs
@@ -0,0 +1,19 @@
+namespace GodotTools
+{
+ public struct PlaySettings
+ {
+ public bool HasDebugger { get; }
+ public string DebuggerHost { get; }
+ public int DebuggerPort { get; }
+
+ public bool BuildBeforePlaying { get; }
+
+ public PlaySettings(string debuggerHost, int debuggerPort, bool buildBeforePlaying)
+ {
+ HasDebugger = true;
+ DebuggerHost = debuggerHost;
+ DebuggerPort = debuggerPort;
+ BuildBeforePlaying = buildBeforePlaying;
+ }
+ }
+}
diff --git a/modules/mono/editor/GodotTools/GodotTools/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools/Properties/AssemblyInfo.cs
deleted file mode 100644
index f5fe85c722..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-// Information about this assembly is defined by the following attributes.
-// Change them to the values specific to your project.
-
-[assembly: AssemblyTitle("GodotTools")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("")]
-[assembly: AssemblyCopyright("Godot Engine contributors")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
-// The form "{Major}.{Minor}.*" will automatically update the build and revision,
-// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-
-[assembly: AssemblyVersion("1.0.*")]
-
-// The following attributes are used to specify the signing key for the assembly,
-// if desired. See the Mono documentation for more information about signing.
-
-//[assembly: AssemblyDelaySign(false)]
-//[assembly: AssemblyKeyFile("")]
diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
index b057ac12c6..6c05891f2c 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs
@@ -22,7 +22,10 @@ namespace GodotTools.Utils
{
public const string Windows = "Windows";
public const string OSX = "OSX";
- public const string X11 = "X11";
+ public const string Linux = "Linux";
+ public const string FreeBSD = "FreeBSD";
+ public const string NetBSD = "NetBSD";
+ public const string BSD = "BSD";
public const string Server = "Server";
public const string UWP = "UWP";
public const string Haiku = "Haiku";
@@ -35,7 +38,7 @@ namespace GodotTools.Utils
{
public const string Windows = "windows";
public const string OSX = "osx";
- public const string X11 = "linuxbsd";
+ public const string LinuxBSD = "linuxbsd";
public const string Server = "server";
public const string UWP = "uwp";
public const string Haiku = "haiku";
@@ -48,7 +51,10 @@ namespace GodotTools.Utils
{
[Names.Windows] = Platforms.Windows,
[Names.OSX] = Platforms.OSX,
- [Names.X11] = Platforms.X11,
+ [Names.Linux] = Platforms.LinuxBSD,
+ [Names.FreeBSD] = Platforms.LinuxBSD,
+ [Names.NetBSD] = Platforms.LinuxBSD,
+ [Names.BSD] = Platforms.LinuxBSD,
[Names.Server] = Platforms.Server,
[Names.UWP] = Platforms.UWP,
[Names.Haiku] = Platforms.Haiku,
@@ -62,38 +68,39 @@ namespace GodotTools.Utils
return name.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase);
}
+ private static bool IsAnyOS(IEnumerable<string> names)
+ {
+ return names.Any(p => p.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase));
+ }
+
+ private static readonly IEnumerable<string> LinuxBSDPlatforms =
+ new[] {Names.Linux, Names.FreeBSD, Names.NetBSD, Names.BSD};
+
+ private static readonly IEnumerable<string> UnixLikePlatforms =
+ new[] {Names.OSX, Names.Server, Names.Haiku, Names.Android, Names.iOS}
+ .Concat(LinuxBSDPlatforms).ToArray();
+
private static readonly Lazy<bool> _isWindows = new Lazy<bool>(() => IsOS(Names.Windows));
private static readonly Lazy<bool> _isOSX = new Lazy<bool>(() => IsOS(Names.OSX));
- private static readonly Lazy<bool> _isX11 = new Lazy<bool>(() => IsOS(Names.X11));
+ private static readonly Lazy<bool> _isLinuxBSD = new Lazy<bool>(() => IsAnyOS(LinuxBSDPlatforms));
private static readonly Lazy<bool> _isServer = new Lazy<bool>(() => IsOS(Names.Server));
private static readonly Lazy<bool> _isUWP = new Lazy<bool>(() => IsOS(Names.UWP));
private static readonly Lazy<bool> _isHaiku = new Lazy<bool>(() => IsOS(Names.Haiku));
private static readonly Lazy<bool> _isAndroid = new Lazy<bool>(() => IsOS(Names.Android));
private static readonly Lazy<bool> _isiOS = new Lazy<bool>(() => IsOS(Names.iOS));
private static readonly Lazy<bool> _isHTML5 = new Lazy<bool>(() => IsOS(Names.HTML5));
+ private static readonly Lazy<bool> _isUnixLike = new Lazy<bool>(() => IsAnyOS(UnixLikePlatforms));
public static bool IsWindows => _isWindows.Value || IsUWP;
public static bool IsOSX => _isOSX.Value;
- public static bool IsX11 => _isX11.Value;
+ public static bool IsLinuxBSD => _isLinuxBSD.Value;
public static bool IsServer => _isServer.Value;
public static bool IsUWP => _isUWP.Value;
public static bool IsHaiku => _isHaiku.Value;
public static bool IsAndroid => _isAndroid.Value;
public static bool IsiOS => _isiOS.Value;
public static bool IsHTML5 => _isHTML5.Value;
-
- private static bool? _isUnixCache;
- private static readonly string[] UnixLikePlatforms = { Names.OSX, Names.X11, Names.Server, Names.Haiku, Names.Android, Names.iOS };
-
- public static bool IsUnixLike()
- {
- if (_isUnixCache.HasValue)
- return _isUnixCache.Value;
-
- string osName = GetPlatformName();
- _isUnixCache = UnixLikePlatforms.Any(p => p.Equals(osName, StringComparison.OrdinalIgnoreCase));
- return _isUnixCache.Value;
- }
+ public static bool IsUnixLike => _isUnixLike.Value;
public static char PathSep => IsWindows ? ';' : ':';
@@ -121,10 +128,10 @@ namespace GodotTools.Utils
return searchDirs.Select(dir => Path.Combine(dir, name)).FirstOrDefault(File.Exists);
return (from dir in searchDirs
- select Path.Combine(dir, name)
+ select Path.Combine(dir, name)
into path
- from ext in windowsExts
- select path + ext).FirstOrDefault(File.Exists);
+ from ext in windowsExts
+ select path + ext).FirstOrDefault(File.Exists);
}
private static string PathWhichUnix([NotNull] string name)
@@ -189,7 +196,7 @@ namespace GodotTools.Utils
startInfo.UseShellExecute = false;
- using (var process = new Process { StartInfo = startInfo })
+ using (var process = new Process {StartInfo = startInfo})
{
process.Start();
process.WaitForExit();
diff --git a/modules/mono/editor/GodotTools/GodotTools/packages.config b/modules/mono/editor/GodotTools/GodotTools/packages.config
deleted file mode 100644
index dd3de2865a..0000000000
--- a/modules/mono/editor/GodotTools/GodotTools/packages.config
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="JetBrains.Annotations" version="2019.1.3" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="12.0.3" targetFramework="net45" />
-</packages>
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 71bb8ff851..730ffcb945 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -105,7 +105,6 @@
const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN("\t%0 %1_in = %1;\n");
static String fix_doc_description(const String &p_bbcode) {
-
// This seems to be the correct way to do this. It's the same EditorHelp does.
return p_bbcode.dedent()
@@ -115,7 +114,6 @@ static String fix_doc_description(const String &p_bbcode) {
}
static String snake_to_pascal_case(const String &p_identifier, bool p_input_is_upper = false) {
-
String ret;
Vector<String> parts = p_identifier.split("_", true);
@@ -125,8 +123,9 @@ static String snake_to_pascal_case(const String &p_identifier, bool p_input_is_u
if (part.length()) {
part[0] = _find_upper(part[0]);
if (p_input_is_upper) {
- for (int j = 1; j < part.length(); j++)
+ for (int j = 1; j < part.length(); j++) {
part[j] = _find_lower(part[j]);
+ }
}
ret += part;
} else {
@@ -148,7 +147,6 @@ static String snake_to_pascal_case(const String &p_identifier, bool p_input_is_u
}
static String snake_to_camel_case(const String &p_identifier, bool p_input_is_upper = false) {
-
String ret;
Vector<String> parts = p_identifier.split("_", true);
@@ -160,8 +158,9 @@ static String snake_to_camel_case(const String &p_identifier, bool p_input_is_up
part[0] = _find_upper(part[0]);
}
if (p_input_is_upper) {
- for (int j = i != 0 ? 1 : 0; j < part.length(); j++)
+ for (int j = i != 0 ? 1 : 0; j < part.length(); j++) {
part[j] = _find_lower(part[j]);
+ }
}
ret += part;
} else {
@@ -183,11 +182,11 @@ static String snake_to_camel_case(const String &p_identifier, bool p_input_is_up
}
String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterface *p_itype) {
-
// Based on the version in EditorHelp
- if (p_bbcode.empty())
+ if (p_bbcode.empty()) {
return String();
+ }
DocData *doc = EditorHelp::get_doc_data();
@@ -204,8 +203,9 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
while (pos < bbcode.length()) {
int brk_pos = bbcode.find("[", pos);
- if (brk_pos < 0)
+ if (brk_pos < 0) {
brk_pos = bbcode.length();
+ }
if (brk_pos > pos) {
String text = bbcode.substr(pos, brk_pos - pos);
@@ -214,19 +214,22 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
} else {
Vector<String> lines = text.split("\n");
for (int i = 0; i < lines.size(); i++) {
- if (i != 0)
+ if (i != 0) {
xml_output.append("<para>");
+ }
xml_output.append(lines[i].xml_escape());
- if (i != lines.size() - 1)
+ if (i != lines.size() - 1) {
xml_output.append("</para>\n");
+ }
}
}
}
- if (brk_pos == bbcode.length())
+ if (brk_pos == bbcode.length()) {
break; // nothing else to add
+ }
int brk_end = bbcode.find("]", brk_pos + 1);
@@ -237,13 +240,15 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
} else {
Vector<String> lines = text.split("\n");
for (int i = 0; i < lines.size(); i++) {
- if (i != 0)
+ if (i != 0) {
xml_output.append("<para>");
+ }
xml_output.append(lines[i].xml_escape());
- if (i != lines.size() - 1)
+ if (i != lines.size() - 1) {
xml_output.append("</para>\n");
+ }
}
}
@@ -416,8 +421,9 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
for (const List<EnumInterface>::Element *E = global_enums.front(); E; E = E->next()) {
target_ienum = &E->get();
target_iconst = find_constant_by_name(target_name, target_ienum->constants);
- if (target_iconst)
+ if (target_iconst) {
break;
+ }
}
if (target_iconst) {
@@ -454,8 +460,9 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
for (const List<EnumInterface>::Element *E = target_itype->enums.front(); E; E = E->next()) {
target_ienum = &E->get();
target_iconst = find_constant_by_name(target_name, target_ienum->constants);
- if (target_iconst)
+ if (target_iconst) {
break;
+ }
}
if (target_iconst) {
@@ -566,8 +573,12 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
code_tag = true;
pos = brk_end + 1;
tag_stack.push_front(tag);
+ } else if (tag == "kbd") {
+ // keyboard combinations are not supported in xml comments
+ pos = brk_end + 1;
+ tag_stack.push_front(tag);
} else if (tag == "center") {
- // center is alignment not supported in xml comments
+ // center alignment is not supported in xml comments
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "br") {
@@ -583,8 +594,9 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
tag_stack.push_front(tag);
} else if (tag == "url") {
int end = bbcode.find("[", brk_end);
- if (end == -1)
+ if (end == -1) {
end = bbcode.length();
+ }
String url = bbcode.substr(brk_end + 1, end - brk_end - 1);
xml_output.append("<a href=\"");
xml_output.append(url);
@@ -603,8 +615,9 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
tag_stack.push_front("url");
} else if (tag == "img") {
int end = bbcode.find("[", brk_end);
- if (end == -1)
+ if (end == -1) {
end = bbcode.length();
+ }
String image = bbcode.substr(brk_end + 1, end - brk_end - 1);
// Not supported. Just append the bbcode.
@@ -634,15 +647,15 @@ String BindingsGenerator::bbcode_to_xml(const String &p_bbcode, const TypeInterf
}
int BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) {
-
CRASH_COND(p_ienum.constants.empty());
const ConstantInterface &front_iconstant = p_ienum.constants.front()->get();
Vector<String> front_parts = front_iconstant.name.split("_", /* p_allow_empty: */ true);
int candidate_len = front_parts.size() - 1;
- if (candidate_len == 0)
+ if (candidate_len == 0) {
return 0;
+ }
for (const List<ConstantInterface>::Element *E = p_ienum.constants.front()->next(); E; E = E->next()) {
const ConstantInterface &iconstant = E->get();
@@ -654,21 +667,22 @@ int BindingsGenerator::_determine_enum_prefix(const EnumInterface &p_ienum) {
if (front_parts[i] != parts[i]) {
// HARDCODED: Some Flag enums have the prefix 'FLAG_' for everything except 'FLAGS_DEFAULT' (same for 'METHOD_FLAG_' and'METHOD_FLAGS_DEFAULT').
bool hardcoded_exc = (i == candidate_len - 1 && ((front_parts[i] == "FLAGS" && parts[i] == "FLAG") || (front_parts[i] == "FLAG" && parts[i] == "FLAGS")));
- if (!hardcoded_exc)
+ if (!hardcoded_exc) {
break;
+ }
}
}
candidate_len = i;
- if (candidate_len == 0)
+ if (candidate_len == 0) {
return 0;
+ }
}
return candidate_len;
}
void BindingsGenerator::_apply_prefix_to_enum_constants(BindingsGenerator::EnumInterface &p_ienum, int p_prefix_length) {
-
if (p_prefix_length > 0) {
for (List<ConstantInterface>::Element *E = p_ienum.constants.front(); E; E = E->next()) {
int curr_prefix_length = p_prefix_length;
@@ -679,22 +693,25 @@ void BindingsGenerator::_apply_prefix_to_enum_constants(BindingsGenerator::EnumI
Vector<String> parts = constant_name.split("_", /* p_allow_empty: */ true);
- if (parts.size() <= curr_prefix_length)
+ if (parts.size() <= curr_prefix_length) {
continue;
+ }
if (parts[curr_prefix_length][0] >= '0' && parts[curr_prefix_length][0] <= '9') {
// The name of enum constants may begin with a numeric digit when strip from the enum prefix,
// so we make the prefix for this constant one word shorter in those cases.
for (curr_prefix_length = curr_prefix_length - 1; curr_prefix_length > 0; curr_prefix_length--) {
- if (parts[curr_prefix_length][0] < '0' || parts[curr_prefix_length][0] > '9')
+ if (parts[curr_prefix_length][0] < '0' || parts[curr_prefix_length][0] > '9') {
break;
+ }
}
}
constant_name = "";
for (int i = curr_prefix_length; i < parts.size(); i++) {
- if (i > curr_prefix_length)
+ if (i > curr_prefix_length) {
constant_name += "_";
+ }
constant_name += parts[i];
}
@@ -704,12 +721,12 @@ void BindingsGenerator::_apply_prefix_to_enum_constants(BindingsGenerator::EnumI
}
void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
-
for (const List<MethodInterface>::Element *E = p_itype.methods.front(); E; E = E->next()) {
const MethodInterface &imethod = E->get();
- if (imethod.is_virtual)
+ if (imethod.is_virtual) {
continue;
+ }
const TypeInterface *return_type = _get_type_or_placeholder(imethod.return_type);
@@ -758,8 +775,9 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
List<InternalCall>::Element *match = method_icalls.find(im_icall);
if (match) {
- if (p_itype.api_type != ClassDB::API_EDITOR)
+ if (p_itype.api_type != ClassDB::API_EDITOR) {
match->get().editor_only = false;
+ }
method_icalls_map.insert(&E->get(), &match->get());
} else {
List<InternalCall>::Element *added = method_icalls.push_back(im_icall);
@@ -769,7 +787,6 @@ void BindingsGenerator::_generate_method_icalls(const TypeInterface &p_itype) {
}
void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
-
// Constants (in partial GD class)
p_output.append("\n#pragma warning disable CS1591 // Disable warning: "
@@ -805,8 +822,9 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
p_output.append(";");
}
- if (!global_constants.empty())
+ if (!global_constants.empty()) {
p_output.append("\n");
+ }
p_output.append(INDENT1 CLOSE_BLOCK); // end of GD class
@@ -868,8 +886,9 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
p_output.append(INDENT1 CLOSE_BLOCK);
- if (enum_in_static_class)
+ if (enum_in_static_class) {
p_output.append(INDENT1 CLOSE_BLOCK);
+ }
}
p_output.append(CLOSE_BLOCK); // end of namespace
@@ -878,7 +897,6 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) {
}
Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
-
ERR_FAIL_COND_V(!initialized, ERR_UNCONFIGURED);
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
@@ -904,8 +922,9 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
_generate_global_constants(constants_source);
String output_file = path::join(base_gen_dir, BINDINGS_GLOBAL_SCOPE_CLASS "_constants.cs");
Error save_err = _save_file(output_file, constants_source);
- if (save_err != OK)
+ if (save_err != OK) {
return save_err;
+ }
compile_items.push_back(output_file);
}
@@ -913,17 +932,20 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) {
const TypeInterface &itype = E.get();
- if (itype.api_type == ClassDB::API_EDITOR)
+ if (itype.api_type == ClassDB::API_EDITOR) {
continue;
+ }
String output_file = path::join(godot_objects_gen_dir, itype.proxy_name + ".cs");
Error err = _generate_cs_type(itype, output_file);
- if (err == ERR_SKIP)
+ if (err == ERR_SKIP) {
continue;
+ }
- if (err != OK)
+ if (err != OK) {
return err;
+ }
compile_items.push_back(output_file);
}
@@ -954,10 +976,12 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
cs_icalls_content.append(m_icall.im_sig + ");\n"); \
}
- for (const List<InternalCall>::Element *E = core_custom_icalls.front(); E; E = E->next())
+ for (const List<InternalCall>::Element *E = core_custom_icalls.front(); E; E = E->next()) {
ADD_INTERNAL_CALL(E->get());
- for (const List<InternalCall>::Element *E = method_icalls.front(); E; E = E->next())
+ }
+ for (const List<InternalCall>::Element *E = method_icalls.front(); E; E = E->next()) {
ADD_INTERNAL_CALL(E->get());
+ }
#undef ADD_INTERNAL_CALL
@@ -966,8 +990,9 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
String internal_methods_file = path::join(base_gen_dir, BINDINGS_CLASS_NATIVECALLS ".cs");
Error err = _save_file(internal_methods_file, cs_icalls_content);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
compile_items.push_back(internal_methods_file);
@@ -986,14 +1011,14 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
String includes_props_file = path::join(base_gen_dir, "GeneratedIncludes.props");
err = _save_file(includes_props_file, includes_props_content);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
return OK;
}
Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) {
-
ERR_FAIL_COND_V(!initialized, ERR_UNCONFIGURED);
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
@@ -1016,17 +1041,20 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) {
for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) {
const TypeInterface &itype = E.get();
- if (itype.api_type != ClassDB::API_EDITOR)
+ if (itype.api_type != ClassDB::API_EDITOR) {
continue;
+ }
String output_file = path::join(godot_objects_gen_dir, itype.proxy_name + ".cs");
Error err = _generate_cs_type(itype, output_file);
- if (err == ERR_SKIP)
+ if (err == ERR_SKIP) {
continue;
+ }
- if (err != OK)
+ if (err != OK) {
return err;
+ }
compile_items.push_back(output_file);
}
@@ -1056,10 +1084,12 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) {
cs_icalls_content.append(m_icall.im_sig + ");\n"); \
}
- for (const List<InternalCall>::Element *E = editor_custom_icalls.front(); E; E = E->next())
+ for (const List<InternalCall>::Element *E = editor_custom_icalls.front(); E; E = E->next()) {
ADD_INTERNAL_CALL(E->get());
- for (const List<InternalCall>::Element *E = method_icalls.front(); E; E = E->next())
+ }
+ for (const List<InternalCall>::Element *E = method_icalls.front(); E; E = E->next()) {
ADD_INTERNAL_CALL(E->get());
+ }
#undef ADD_INTERNAL_CALL
@@ -1068,8 +1098,9 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) {
String internal_methods_file = path::join(base_gen_dir, BINDINGS_CLASS_NATIVECALLS_EDITOR ".cs");
Error err = _save_file(internal_methods_file, cs_icalls_content);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
compile_items.push_back(internal_methods_file);
@@ -1088,14 +1119,14 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir) {
String includes_props_file = path::join(base_gen_dir, "GeneratedIncludes.props");
err = _save_file(includes_props_file, includes_props_content);
- if (err != OK)
+ if (err != OK) {
return err;
+ }
return OK;
}
Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
-
ERR_FAIL_COND_V(!initialized, ERR_UNCONFIGURED);
String output_dir = path::abspath(path::realpath(p_output_dir));
@@ -1143,7 +1174,6 @@ Error BindingsGenerator::generate_cs_api(const String &p_output_dir) {
// - Csc warning e.g.:
// ObjectType/LineEdit.cs(140,38): warning CS0108: 'LineEdit.FocusMode' hides inherited member 'Control.FocusMode'. Use the new keyword if hiding was intended.
Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const String &p_output_file) {
-
CRASH_COND(!itype.is_object_type);
bool is_derived_type = itype.base_name != StringName();
@@ -1218,93 +1248,89 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.append(INDENT1 "{");
- if (class_doc) {
+ // Add constants
- // Add constants
-
- for (const List<ConstantInterface>::Element *E = itype.constants.front(); E; E = E->next()) {
- const ConstantInterface &iconstant = E->get();
-
- if (iconstant.const_doc && iconstant.const_doc->description.size()) {
- String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), &itype);
- Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
+ for (const List<ConstantInterface>::Element *E = itype.constants.front(); E; E = E->next()) {
+ const ConstantInterface &iconstant = E->get();
- if (summary_lines.size()) {
- output.append(MEMBER_BEGIN "/// <summary>\n");
+ if (iconstant.const_doc && iconstant.const_doc->description.size()) {
+ String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), &itype);
+ Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
- for (int i = 0; i < summary_lines.size(); i++) {
- output.append(INDENT2 "/// ");
- output.append(summary_lines[i]);
- output.append("\n");
- }
+ if (summary_lines.size()) {
+ output.append(MEMBER_BEGIN "/// <summary>\n");
- output.append(INDENT2 "/// </summary>");
+ for (int i = 0; i < summary_lines.size(); i++) {
+ output.append(INDENT2 "/// ");
+ output.append(summary_lines[i]);
+ output.append("\n");
}
- }
- output.append(MEMBER_BEGIN "public const int ");
- output.append(iconstant.proxy_name);
- output.append(" = ");
- output.append(itos(iconstant.value));
- output.append(";");
+ output.append(INDENT2 "/// </summary>");
+ }
}
- if (itype.constants.size())
- output.append("\n");
+ output.append(MEMBER_BEGIN "public const int ");
+ output.append(iconstant.proxy_name);
+ output.append(" = ");
+ output.append(itos(iconstant.value));
+ output.append(";");
+ }
- // Add enums
+ if (itype.constants.size()) {
+ output.append("\n");
+ }
- for (const List<EnumInterface>::Element *E = itype.enums.front(); E; E = E->next()) {
- const EnumInterface &ienum = E->get();
+ // Add enums
- ERR_FAIL_COND_V(ienum.constants.empty(), ERR_BUG);
+ for (const List<EnumInterface>::Element *E = itype.enums.front(); E; E = E->next()) {
+ const EnumInterface &ienum = E->get();
- output.append(MEMBER_BEGIN "public enum ");
- output.append(ienum.cname.operator String());
- output.append(MEMBER_BEGIN OPEN_BLOCK);
+ ERR_FAIL_COND_V(ienum.constants.empty(), ERR_BUG);
- for (const List<ConstantInterface>::Element *F = ienum.constants.front(); F; F = F->next()) {
- const ConstantInterface &iconstant = F->get();
+ output.append(MEMBER_BEGIN "public enum ");
+ output.append(ienum.cname.operator String());
+ output.append(MEMBER_BEGIN OPEN_BLOCK);
- if (iconstant.const_doc && iconstant.const_doc->description.size()) {
- String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), &itype);
- Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
+ for (const List<ConstantInterface>::Element *F = ienum.constants.front(); F; F = F->next()) {
+ const ConstantInterface &iconstant = F->get();
- if (summary_lines.size()) {
- output.append(INDENT3 "/// <summary>\n");
+ if (iconstant.const_doc && iconstant.const_doc->description.size()) {
+ String xml_summary = bbcode_to_xml(fix_doc_description(iconstant.const_doc->description), &itype);
+ Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
- for (int i = 0; i < summary_lines.size(); i++) {
- output.append(INDENT3 "/// ");
- output.append(summary_lines[i]);
- output.append("\n");
- }
+ if (summary_lines.size()) {
+ output.append(INDENT3 "/// <summary>\n");
- output.append(INDENT3 "/// </summary>\n");
+ for (int i = 0; i < summary_lines.size(); i++) {
+ output.append(INDENT3 "/// ");
+ output.append(summary_lines[i]);
+ output.append("\n");
}
- }
- output.append(INDENT3);
- output.append(iconstant.proxy_name);
- output.append(" = ");
- output.append(itos(iconstant.value));
- output.append(F != ienum.constants.back() ? ",\n" : "\n");
+ output.append(INDENT3 "/// </summary>\n");
+ }
}
- output.append(INDENT2 CLOSE_BLOCK);
+ output.append(INDENT3);
+ output.append(iconstant.proxy_name);
+ output.append(" = ");
+ output.append(itos(iconstant.value));
+ output.append(F != ienum.constants.back() ? ",\n" : "\n");
}
- // Add properties
-
- for (const List<PropertyInterface>::Element *E = itype.properties.front(); E; E = E->next()) {
- const PropertyInterface &iprop = E->get();
- Error prop_err = _generate_cs_property(itype, iprop, output);
- ERR_FAIL_COND_V_MSG(prop_err != OK, prop_err,
- "Failed to generate property '" + iprop.cname.operator String() +
- "' for class '" + itype.name + "'.");
- }
+ output.append(INDENT2 CLOSE_BLOCK);
}
- // TODO: BINDINGS_NATIVE_NAME_FIELD should be StringName, once we support it in C#
+ // Add properties
+
+ for (const List<PropertyInterface>::Element *E = itype.properties.front(); E; E = E->next()) {
+ const PropertyInterface &iprop = E->get();
+ Error prop_err = _generate_cs_property(itype, iprop, output);
+ ERR_FAIL_COND_V_MSG(prop_err != OK, prop_err,
+ "Failed to generate property '" + iprop.cname.operator String() +
+ "' for class '" + itype.name + "'.");
+ }
if (itype.is_singleton) {
// Add the type name and the singleton pointer as static fields
@@ -1377,15 +1403,17 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
if (itype.is_singleton) {
InternalCall singleton_icall = InternalCall(itype.api_type, ICALL_PREFIX + itype.name + SINGLETON_ICALL_SUFFIX, "IntPtr");
- if (!find_icall_by_name(singleton_icall.name, custom_icalls))
+ if (!find_icall_by_name(singleton_icall.name, custom_icalls)) {
custom_icalls.push_back(singleton_icall);
+ }
}
if (is_derived_type && itype.is_instantiable) {
InternalCall ctor_icall = InternalCall(itype.api_type, ctor_method, "IntPtr", itype.proxy_name + " obj");
- if (!find_icall_by_name(ctor_icall.name, custom_icalls))
+ if (!find_icall_by_name(ctor_icall.name, custom_icalls)) {
custom_icalls.push_back(ctor_icall);
+ }
}
output.append(INDENT1 CLOSE_BLOCK /* class */
@@ -1399,7 +1427,6 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
}
Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInterface &p_itype, const PropertyInterface &p_iprop, StringBuilder &p_output) {
-
const MethodInterface *setter = p_itype.find_method_by_name(p_iprop.setter);
// Search it in base types too
@@ -1452,6 +1479,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
const TypeInterface *prop_itype = _get_type_or_null(proptype_name);
ERR_FAIL_NULL_V(prop_itype, ERR_BUG); // Property type not found
+ ERR_FAIL_COND_V_MSG(prop_itype->is_singleton, ERR_BUG,
+ "Property type is a singleton: '" + p_itype.name + "." + String(p_iprop.cname) + "'.");
+
if (p_iprop.prop_doc && p_iprop.prop_doc->description.size()) {
String xml_summary = bbcode_to_xml(fix_doc_description(p_iprop.prop_doc->description), &p_itype);
Vector<String> summary_lines = xml_summary.length() ? xml_summary.split("\n") : Vector<String>();
@@ -1471,8 +1501,9 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
p_output.append(MEMBER_BEGIN "public ");
- if (p_itype.is_singleton)
+ if (p_itype.is_singleton) {
p_output.append("static ");
+ }
p_output.append(prop_itype->cs_type);
p_output.append(" ");
@@ -1542,9 +1573,11 @@ Error BindingsGenerator::_generate_cs_property(const BindingsGenerator::TypeInte
}
Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::MethodInterface &p_imethod, int &p_method_bind_count, StringBuilder &p_output) {
-
const TypeInterface *return_type = _get_type_or_placeholder(p_imethod.return_type);
+ ERR_FAIL_COND_V_MSG(return_type->is_singleton, ERR_BUG,
+ "Method return type is a singleton: '" + p_itype.name + "." + p_imethod.name + "'.");
+
String method_bind_field = "__method_bind_" + itos(p_method_bind_count);
String arguments_sig;
@@ -1560,29 +1593,41 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
const ArgumentInterface &iarg = F->get();
const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type);
+ ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG,
+ "Argument type is a singleton: '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'.");
+
+ if (iarg.default_argument.size()) {
+ CRASH_COND_MSG(!_arg_default_value_is_assignable_to_type(iarg.def_param_value, *arg_type),
+ "Invalid default value for parameter '" + iarg.name + "' of method '" + p_itype.name + "." + p_imethod.name + "'.");
+ }
+
// Add the current arguments to the signature
// If the argument has a default value which is not a constant, we will make it Nullable
{
- if (F != p_imethod.arguments.front())
+ if (F != p_imethod.arguments.front()) {
arguments_sig += ", ";
+ }
- if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
+ if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL) {
arguments_sig += "Nullable<";
+ }
arguments_sig += arg_type->cs_type;
- if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
+ if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL) {
arguments_sig += "> ";
- else
+ } else {
arguments_sig += " ";
+ }
arguments_sig += iarg.name;
if (iarg.default_argument.size()) {
- if (iarg.def_param_mode != ArgumentInterface::CONSTANT)
+ if (iarg.def_param_mode != ArgumentInterface::CONSTANT) {
arguments_sig += " = null";
- else
+ } else {
arguments_sig += " = " + sformat(iarg.default_argument, arg_type->cs_type);
+ }
}
}
@@ -1600,17 +1645,19 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
cs_in_statements += " = ";
cs_in_statements += iarg.name;
- if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
+ if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL) {
cs_in_statements += ".HasValue ? ";
- else
+ } else {
cs_in_statements += " != null ? ";
+ }
cs_in_statements += iarg.name;
- if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL)
+ if (iarg.def_param_mode == ArgumentInterface::NULLABLE_VAL) {
cs_in_statements += ".Value : ";
- else
+ } else {
cs_in_statements += " : ";
+ }
String def_arg = sformat(iarg.default_argument, arg_type->cs_type);
@@ -1660,14 +1707,19 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
}
if (!p_imethod.is_internal) {
+ // TODO: This alone adds ~0.2 MB of bloat to the core API assembly. It would be
+ // better to generate a table in the C++ glue instead. That way the strings wouldn't
+ // add that much extra bloat as they're already used in engine code. Also, it would
+ // probably be much faster than looking up the attributes when fetching methods.
p_output.append(MEMBER_BEGIN "[GodotMethod(\"");
p_output.append(p_imethod.name);
p_output.append("\")]");
}
if (p_imethod.is_deprecated) {
- if (p_imethod.deprecation_message.empty())
+ if (p_imethod.deprecation_message.empty()) {
WARN_PRINT("An empty deprecation message is discouraged. Method: '" + p_imethod.proxy_name + "'.");
+ }
p_output.append(MEMBER_BEGIN "[Obsolete(\"");
p_output.append(p_imethod.deprecation_message);
@@ -1727,8 +1779,9 @@ Error BindingsGenerator::_generate_cs_method(const BindingsGenerator::TypeInterf
im_call += ".";
im_call += im_icall->name;
- if (p_imethod.arguments.size())
+ if (p_imethod.arguments.size()) {
p_output.append(cs_in_statements);
+ }
if (return_type->cname == name_cache.type_void) {
p_output.append(im_call + "(" + icall_params + ");\n");
@@ -1755,10 +1808,14 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
const ArgumentInterface &iarg = F->get();
const TypeInterface *arg_type = _get_type_or_placeholder(iarg.type);
+ ERR_FAIL_COND_V_MSG(arg_type->is_singleton, ERR_BUG,
+ "Argument type is a singleton: '" + iarg.name + "' of signal" + p_itype.name + "." + p_isignal.name + "'.");
+
// Add the current arguments to the signature
- if (F != p_isignal.arguments.front())
+ if (F != p_isignal.arguments.front()) {
arguments_sig += ", ";
+ }
arguments_sig += arg_type->cs_type;
arguments_sig += " ";
@@ -1785,8 +1842,9 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
}
if (p_isignal.is_deprecated) {
- if (p_isignal.deprecation_message.empty())
+ if (p_isignal.deprecation_message.empty()) {
WARN_PRINT("An empty deprecation message is discouraged. Signal: '" + p_isignal.proxy_name + "'.");
+ }
p_output.append(MEMBER_BEGIN "[Obsolete(\"");
p_output.append(p_isignal.deprecation_message);
@@ -1817,8 +1875,9 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
// Generate event
p_output.append(MEMBER_BEGIN "[Signal]" MEMBER_BEGIN "public ");
- if (p_itype.is_singleton)
+ if (p_itype.is_singleton) {
p_output.append("static ");
+ }
p_output.append("event ");
p_output.append(delegate_name);
@@ -1826,18 +1885,20 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
p_output.append(p_isignal.proxy_name);
p_output.append("\n" OPEN_BLOCK_L2);
- if (p_itype.is_singleton)
+ if (p_itype.is_singleton) {
p_output.append("add => Singleton.Connect(__signal_name_");
- else
+ } else {
p_output.append("add => Connect(__signal_name_");
+ }
p_output.append(p_isignal.name);
p_output.append(", new Callable(value));\n");
- if (p_itype.is_singleton)
+ if (p_itype.is_singleton) {
p_output.append(INDENT3 "remove => Singleton.Disconnect(__signal_name_");
- else
+ } else {
p_output.append(INDENT3 "remove => Disconnect(__signal_name_");
+ }
p_output.append(p_isignal.name);
p_output.append(", new Callable(value));\n");
@@ -1848,7 +1909,6 @@ Error BindingsGenerator::_generate_cs_signal(const BindingsGenerator::TypeInterf
}
Error BindingsGenerator::generate_glue(const String &p_output_dir) {
-
ERR_FAIL_COND_V(!initialized, ERR_UNCONFIGURED);
bool dir_exists = DirAccess::exists(p_output_dir);
@@ -1872,7 +1932,6 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
CRASH_COND(itype.cname != name_cache.type_Object);
CRASH_COND(!itype.is_instantiable);
CRASH_COND(itype.api_type != ClassDB::API_CORE);
- CRASH_COND(itype.is_reference);
CRASH_COND(itype.is_singleton);
}
@@ -1893,8 +1952,9 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
String singleton_icall_name = ICALL_PREFIX + itype.name + SINGLETON_ICALL_SUFFIX;
InternalCall singleton_icall = InternalCall(itype.api_type, singleton_icall_name, "IntPtr");
- if (!find_icall_by_name(singleton_icall.name, custom_icalls))
+ if (!find_icall_by_name(singleton_icall.name, custom_icalls)) {
custom_icalls.push_back(singleton_icall);
+ }
output.append("Object* ");
output.append(singleton_icall_name);
@@ -1906,8 +1966,9 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
if (is_derived_type && itype.is_instantiable) {
InternalCall ctor_icall = InternalCall(itype.api_type, ctor_method, "IntPtr", itype.proxy_name + " obj");
- if (!find_icall_by_name(ctor_icall.name, custom_icalls))
+ if (!find_icall_by_name(ctor_icall.name, custom_icalls)) {
custom_icalls.push_back(ctor_icall);
+ }
output.append("Object* ");
output.append(ctor_method);
@@ -1953,7 +2014,6 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
bool tools_sequence = false;
for (const List<InternalCall>::Element *E = core_custom_icalls.front(); E; E = E->next()) {
-
if (tools_sequence) {
if (!E->get().editor_only) {
tools_sequence = false;
@@ -2007,8 +2067,9 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
output.append("\n#endif // MONO_GLUE_ENABLED\n");
Error save_err = _save_file(path::join(p_output_dir, "mono_glue.gen.cpp"), output);
- if (save_err != OK)
+ if (save_err != OK) {
return save_err;
+ }
OS::get_singleton()->print("Mono glue generated successfully\n");
@@ -2020,7 +2081,6 @@ uint32_t BindingsGenerator::get_version() {
}
Error BindingsGenerator::_save_file(const String &p_path, const StringBuilder &p_content) {
-
FileAccessRef file = FileAccess::open(p_path, FileAccess::WRITE);
ERR_FAIL_COND_V_MSG(!file, ERR_FILE_CANT_WRITE, "Cannot open file: '" + p_path + "'.");
@@ -2032,9 +2092,9 @@ Error BindingsGenerator::_save_file(const String &p_path, const StringBuilder &p
}
Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInterface &p_itype, const BindingsGenerator::MethodInterface &p_imethod, StringBuilder &p_output) {
-
- if (p_imethod.is_virtual)
+ if (p_imethod.is_virtual) {
return OK; // Ignore
+ }
bool ret_void = p_imethod.return_type.cname == name_cache.type_void;
@@ -2062,10 +2122,12 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
c_in_statements += sformat(", &%s_in);\n", c_param_name);
}
} else {
- if (i > 0)
+ if (i > 0) {
c_args_var_content += ", ";
- if (arg_type->c_in.size())
+ }
+ if (arg_type->c_in.size()) {
c_in_statements += sformat(arg_type->c_in, arg_type->c_type, c_param_name);
+ }
c_args_var_content += sformat(arg_type->c_arg_in, c_param_name);
}
@@ -2095,8 +2157,9 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
if (!generated_icall_funcs.find(im_icall)) {
generated_icall_funcs.push_back(im_icall);
- if (im_icall->editor_only)
+ if (im_icall->editor_only) {
p_output.append("#ifdef TOOLS_ENABLED\n");
+ }
// Generate icall function
@@ -2135,7 +2198,7 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
if (return_type->ret_as_byref_arg) {
p_output.append("\tif (" CS_PARAM_INSTANCE " == nullptr) { *arg_ret = ");
p_output.append(fail_ret);
- p_output.append("; ERR_FAIL_MSG(\"Parameter ' arg_ret ' is null.\"); }\n");
+ p_output.append("; ERR_FAIL_MSG(\"Parameter ' " CS_PARAM_INSTANCE " ' is null.\"); }\n");
} else {
p_output.append("\tERR_FAIL_NULL_V(" CS_PARAM_INSTANCE ", ");
p_output.append(fail_ret);
@@ -2214,30 +2277,33 @@ Error BindingsGenerator::_generate_glue_method(const BindingsGenerator::TypeInte
p_output.append(CLOSE_BLOCK "\n");
- if (im_icall->editor_only)
+ if (im_icall->editor_only) {
p_output.append("#endif // TOOLS_ENABLED\n");
+ }
}
return OK;
}
const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_null(const TypeReference &p_typeref) {
-
const Map<StringName, TypeInterface>::Element *builtin_type_match = builtin_types.find(p_typeref.cname);
- if (builtin_type_match)
+ if (builtin_type_match) {
return &builtin_type_match->get();
+ }
const OrderedHashMap<StringName, TypeInterface>::Element obj_type_match = obj_types.find(p_typeref.cname);
- if (obj_type_match)
+ if (obj_type_match) {
return &obj_type_match.get();
+ }
if (p_typeref.is_enum) {
const Map<StringName, TypeInterface>::Element *enum_match = enum_types.find(p_typeref.cname);
- if (enum_match)
+ if (enum_match) {
return &enum_match->get();
+ }
// Enum not found. Most likely because none of its constants were bound, so it's empty. That's fine. Use int instead.
const Map<StringName, TypeInterface>::Element *int_match = builtin_types.find(name_cache.type_int);
@@ -2249,18 +2315,19 @@ const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_null(con
}
const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placeholder(const TypeReference &p_typeref) {
-
const TypeInterface *found = _get_type_or_null(p_typeref);
- if (found)
+ if (found) {
return found;
+ }
ERR_PRINT(String() + "Type not found. Creating placeholder: '" + p_typeref.cname.operator String() + "'.");
const Map<StringName, TypeInterface>::Element *match = placeholder_types.find(p_typeref.cname);
- if (match)
+ if (match) {
return &match->get();
+ }
TypeInterface placeholder;
TypeInterface::create_placeholder_type(placeholder, p_typeref.cname);
@@ -2269,7 +2336,6 @@ const BindingsGenerator::TypeInterface *BindingsGenerator::_get_type_or_placehol
}
StringName BindingsGenerator::_get_int_type_name_from_meta(GodotTypeInfo::Metadata p_meta) {
-
switch (p_meta) {
case GodotTypeInfo::METADATA_INT_IS_INT8:
return "sbyte";
@@ -2302,7 +2368,6 @@ StringName BindingsGenerator::_get_int_type_name_from_meta(GodotTypeInfo::Metada
}
StringName BindingsGenerator::_get_float_type_name_from_meta(GodotTypeInfo::Metadata p_meta) {
-
switch (p_meta) {
case GodotTypeInfo::METADATA_REAL_IS_FLOAT:
return "float";
@@ -2320,8 +2385,85 @@ StringName BindingsGenerator::_get_float_type_name_from_meta(GodotTypeInfo::Meta
}
}
-bool BindingsGenerator::_populate_object_type_interfaces() {
+bool BindingsGenerator::_arg_default_value_is_assignable_to_type(const Variant &p_val, const TypeInterface &p_arg_type) {
+ if (p_arg_type.name == name_cache.type_Variant) {
+ // Variant can take anything
+ return true;
+ }
+
+ switch (p_val.get_type()) {
+ case Variant::NIL:
+ return p_arg_type.is_object_type ||
+ name_cache.is_nullable_type(p_arg_type.name);
+ case Variant::BOOL:
+ return p_arg_type.name == name_cache.type_bool;
+ case Variant::INT:
+ return p_arg_type.name == name_cache.type_sbyte ||
+ p_arg_type.name == name_cache.type_short ||
+ p_arg_type.name == name_cache.type_int ||
+ p_arg_type.name == name_cache.type_byte ||
+ p_arg_type.name == name_cache.type_ushort ||
+ p_arg_type.name == name_cache.type_uint ||
+ p_arg_type.name == name_cache.type_long ||
+ p_arg_type.name == name_cache.type_ulong ||
+ p_arg_type.name == name_cache.type_float ||
+ p_arg_type.name == name_cache.type_double ||
+ p_arg_type.is_enum;
+ case Variant::FLOAT:
+ return p_arg_type.name == name_cache.type_float ||
+ p_arg_type.name == name_cache.type_double;
+ case Variant::STRING:
+ case Variant::STRING_NAME:
+ return p_arg_type.name == name_cache.type_String ||
+ p_arg_type.name == name_cache.type_StringName ||
+ p_arg_type.name == name_cache.type_NodePath;
+ case Variant::NODE_PATH:
+ return p_arg_type.name == name_cache.type_NodePath;
+ case Variant::TRANSFORM:
+ case Variant::TRANSFORM2D:
+ case Variant::BASIS:
+ case Variant::QUAT:
+ case Variant::PLANE:
+ case Variant::AABB:
+ case Variant::COLOR:
+ case Variant::VECTOR2:
+ case Variant::RECT2:
+ case Variant::VECTOR3:
+ case Variant::_RID:
+ case Variant::ARRAY:
+ case Variant::DICTIONARY:
+ case Variant::PACKED_BYTE_ARRAY:
+ case Variant::PACKED_INT32_ARRAY:
+ case Variant::PACKED_INT64_ARRAY:
+ case Variant::PACKED_FLOAT32_ARRAY:
+ case Variant::PACKED_FLOAT64_ARRAY:
+ case Variant::PACKED_STRING_ARRAY:
+ case Variant::PACKED_VECTOR2_ARRAY:
+ case Variant::PACKED_VECTOR3_ARRAY:
+ case Variant::PACKED_COLOR_ARRAY:
+ case Variant::CALLABLE:
+ case Variant::SIGNAL:
+ return p_arg_type.name == Variant::get_type_name(p_val.get_type());
+ case Variant::OBJECT:
+ return p_arg_type.is_object_type;
+ case Variant::VECTOR2I:
+ return p_arg_type.name == name_cache.type_Vector2 ||
+ p_arg_type.name == Variant::get_type_name(p_val.get_type());
+ case Variant::RECT2I:
+ return p_arg_type.name == name_cache.type_Rect2 ||
+ p_arg_type.name == Variant::get_type_name(p_val.get_type());
+ case Variant::VECTOR3I:
+ return p_arg_type.name == name_cache.type_Vector3 ||
+ p_arg_type.name == Variant::get_type_name(p_val.get_type());
+ default:
+ CRASH_NOW_MSG("Unexpected Variant type: " + itos(p_val.get_type()));
+ break;
+ }
+ return false;
+}
+
+bool BindingsGenerator::_populate_object_type_interfaces() {
obj_types.clear();
List<StringName> class_list;
@@ -2383,22 +2525,30 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
for (const List<PropertyInfo>::Element *E = property_list.front(); E; E = E->next()) {
const PropertyInfo &property = E->get();
- if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_CATEGORY)
+ if (property.usage & PROPERTY_USAGE_GROUP || property.usage & PROPERTY_USAGE_SUBGROUP || property.usage & PROPERTY_USAGE_CATEGORY) {
continue;
+ }
+
+ if (property.name.find("/") >= 0) {
+ // Ignore properties with '/' (slash) in the name. These are only meant for use in the inspector.
+ continue;
+ }
PropertyInterface iprop;
iprop.cname = property.name;
iprop.setter = ClassDB::get_property_setter(type_cname, iprop.cname);
iprop.getter = ClassDB::get_property_getter(type_cname, iprop.cname);
- if (iprop.setter != StringName())
+ if (iprop.setter != StringName()) {
accessor_methods[iprop.setter] = iprop.cname;
- if (iprop.getter != StringName())
+ }
+ if (iprop.getter != StringName()) {
accessor_methods[iprop.getter] = iprop.cname;
+ }
bool valid = false;
iprop.index = ClassDB::get_property_index(type_cname, iprop.cname, &valid);
- ERR_FAIL_COND_V(!valid, false);
+ ERR_FAIL_COND_V_MSG(!valid, false, "Invalid property: '" + itype.name + "." + String(iprop.cname) + "'.");
iprop.proxy_name = escape_csharp_keyword(snake_to_pascal_case(iprop.cname));
@@ -2410,8 +2560,6 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
iprop.proxy_name += "_";
}
- iprop.proxy_name = iprop.proxy_name.replace("/", "__"); // Some members have a slash...
-
iprop.prop_doc = nullptr;
for (int i = 0; i < itype.class_doc->properties.size(); i++) {
@@ -2440,20 +2588,23 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
int argc = method_info.arguments.size();
- if (method_info.name.empty())
+ if (method_info.name.empty()) {
continue;
+ }
String cname = method_info.name;
- if (blacklisted_methods.find(itype.cname) && blacklisted_methods[itype.cname].find(cname))
+ if (blacklisted_methods.find(itype.cname) && blacklisted_methods[itype.cname].find(cname)) {
continue;
+ }
MethodInterface imethod;
imethod.name = method_info.name;
imethod.cname = cname;
- if (method_info.flags & METHOD_FLAG_VIRTUAL)
+ if (method_info.flags & METHOD_FLAG_VIRTUAL) {
imethod.is_virtual = true;
+ }
PropertyInfo return_info = method_info.return_val;
@@ -2475,9 +2626,8 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
// We assume the return type is void.
imethod.return_type.cname = name_cache.type_void;
- // Actually, more methods like this may be added in the future,
- // which could actually will return something different.
- // Let's put this to notify us if that ever happens.
+ // Actually, more methods like this may be added in the future, which could return
+ // something different. Let's put this check to notify us if that ever happens.
if (itype.cname != name_cache.type_Object || imethod.name != "free") {
WARN_PRINT("Notification: New unexpected virtual non-overridable method found."
" We only expected Object.free, but found '" +
@@ -2488,13 +2638,12 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
imethod.return_type.is_enum = true;
} else if (return_info.class_name != StringName()) {
imethod.return_type.cname = return_info.class_name;
- if (!imethod.is_virtual && ClassDB::is_parent_class(return_info.class_name, name_cache.type_Reference) && return_info.hint != PROPERTY_HINT_RESOURCE_TYPE) {
- /* clang-format off */
- ERR_PRINT("Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'."
- " Are you returning a reference type by pointer? Method: '" + itype.name + "." + imethod.name + "'.");
- /* clang-format on */
- ERR_FAIL_V(false);
- }
+
+ bool bad_reference_hint = !imethod.is_virtual && return_info.hint != PROPERTY_HINT_RESOURCE_TYPE &&
+ ClassDB::is_parent_class(return_info.class_name, name_cache.type_Reference);
+ ERR_FAIL_COND_V_MSG(bad_reference_hint, false,
+ String() + "Return type is reference but hint is not '" _STR(PROPERTY_HINT_RESOURCE_TYPE) "'." +
+ " Are you returning a reference type by pointer? Method: '" + itype.name + "." + imethod.name + "'.");
} else if (return_info.hint == PROPERTY_HINT_RESOURCE_TYPE) {
imethod.return_type.cname = return_info.hint_string;
} else if (return_info.type == Variant::NIL && return_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT) {
@@ -2585,6 +2734,10 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
}
}
+ ERR_FAIL_COND_V_MSG(itype.find_property_by_name(imethod.cname), false,
+ "Method name conflicts with property: '" + itype.name + "." + imethod.name + "'.");
+
+ // Classes starting with an underscore are ignored unless they're used as a property setter or getter
if (!imethod.is_virtual && imethod.name[0] == '_') {
for (const List<PropertyInterface>::Element *F = itype.properties.front(); F; F = F->next()) {
const PropertyInterface &iprop = F->get();
@@ -2764,8 +2917,8 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
}
bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, ArgumentInterface &r_iarg) {
-
- r_iarg.default_argument = p_val;
+ r_iarg.def_param_value = p_val;
+ r_iarg.default_argument = p_val.operator String();
switch (p_val.get_type()) {
case Variant::NIL:
@@ -2798,8 +2951,9 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
}
break;
case Variant::TRANSFORM:
- if (p_val.operator Transform() == Transform())
+ if (p_val.operator Transform() == Transform()) {
r_iarg.default_argument.clear();
+ }
r_iarg.default_argument = "new %s(" + r_iarg.default_argument + ")";
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL;
break;
@@ -2865,14 +3019,14 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar
break;
}
- if (r_iarg.def_param_mode == ArgumentInterface::CONSTANT && r_iarg.type.cname == name_cache.type_Variant && r_iarg.default_argument != "null")
+ if (r_iarg.def_param_mode == ArgumentInterface::CONSTANT && r_iarg.type.cname == name_cache.type_Variant && r_iarg.default_argument != "null") {
r_iarg.def_param_mode = ArgumentInterface::NULLABLE_REF;
+ }
return true;
}
void BindingsGenerator::_populate_builtin_type_interfaces() {
-
builtin_types.clear();
TypeInterface itype;
@@ -3248,7 +3402,6 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
}
void BindingsGenerator::_populate_global_constants() {
-
int global_constants_count = GlobalConstants::get_global_constant_count();
if (global_constants_count > 0) {
@@ -3259,7 +3412,6 @@ void BindingsGenerator::_populate_global_constants() {
const DocData::ClassDoc &global_scope_doc = match->value();
for (int i = 0; i < global_constants_count; i++) {
-
String constant_name = GlobalConstants::get_global_constant_name(i);
const DocData::ConstantDoc *const_doc = nullptr;
@@ -3338,14 +3490,12 @@ void BindingsGenerator::_populate_global_constants() {
}
void BindingsGenerator::_initialize_blacklisted_methods() {
-
blacklisted_methods["Object"].push_back("to_string"); // there is already ToString
blacklisted_methods["Object"].push_back("_to_string"); // override ToString instead
blacklisted_methods["Object"].push_back("_init"); // never called in C# (TODO: implement it)
}
void BindingsGenerator::_log(const char *p_format, ...) {
-
if (log_print_enabled) {
va_list list;
@@ -3356,7 +3506,6 @@ void BindingsGenerator::_log(const char *p_format, ...) {
}
void BindingsGenerator::_initialize() {
-
initialized = false;
EditorHelp::generate_doc();
@@ -3377,14 +3526,14 @@ void BindingsGenerator::_initialize() {
core_custom_icalls.clear();
editor_custom_icalls.clear();
- for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next())
+ for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) {
_generate_method_icalls(E.get());
+ }
initialized = true;
}
void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) {
-
const int NUM_OPTIONS = 2;
String generate_all_glue_option = "--generate-mono-glue";
String generate_cs_glue_option = "--generate-mono-cs-glue";
@@ -3447,21 +3596,25 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args)
}
if (glue_dir_path.length()) {
- if (bindings_generator.generate_glue(glue_dir_path) != OK)
+ if (bindings_generator.generate_glue(glue_dir_path) != OK) {
ERR_PRINT(generate_all_glue_option + ": Failed to generate the C++ glue.");
+ }
- if (bindings_generator.generate_cs_api(glue_dir_path.plus_file(API_SOLUTION_NAME)) != OK)
+ if (bindings_generator.generate_cs_api(glue_dir_path.plus_file(API_SOLUTION_NAME)) != OK) {
ERR_PRINT(generate_all_glue_option + ": Failed to generate the C# API.");
+ }
}
if (cs_dir_path.length()) {
- if (bindings_generator.generate_cs_api(cs_dir_path) != OK)
+ if (bindings_generator.generate_cs_api(cs_dir_path) != OK) {
ERR_PRINT(generate_cs_glue_option + ": Failed to generate the C# API.");
+ }
}
if (cpp_dir_path.length()) {
- if (bindings_generator.generate_glue(cpp_dir_path) != OK)
+ if (bindings_generator.generate_glue(cpp_dir_path) != OK) {
ERR_PRINT(generate_cpp_glue_option + ": Failed to generate the C++ glue.");
+ }
}
// Exit once done
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index 7c87c688db..90c1c9f3ee 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -41,7 +41,6 @@
#include "core/ustring.h"
class BindingsGenerator {
-
struct ConstantInterface {
String name;
String proxy_name;
@@ -85,16 +84,12 @@ class BindingsGenerator {
struct TypeReference {
StringName cname;
- bool is_enum;
+ bool is_enum = false;
- TypeReference() :
- is_enum(false) {
- }
+ TypeReference() {}
TypeReference(const StringName &p_cname) :
- cname(p_cname),
- is_enum(false) {
- }
+ cname(p_cname) {}
};
struct ArgumentInterface {
@@ -107,7 +102,9 @@ class BindingsGenerator {
TypeReference type;
String name;
- DefaultParamMode def_param_mode;
+
+ Variant def_param_value;
+ DefaultParamMode def_param_mode = CONSTANT;
/**
* Determines the expression for the parameter default value.
@@ -116,9 +113,7 @@ class BindingsGenerator {
*/
String default_argument;
- ArgumentInterface() {
- def_param_mode = CONSTANT;
- }
+ ArgumentInterface() {}
};
struct MethodInterface {
@@ -138,19 +133,19 @@ class BindingsGenerator {
/**
* Determines if the method has a variable number of arguments (VarArg)
*/
- bool is_vararg;
+ bool is_vararg = false;
/**
* Virtual methods ("virtual" as defined by the Godot API) are methods that by default do nothing,
* but can be overridden by the user to add custom functionality.
* e.g.: _ready, _process, etc.
*/
- bool is_virtual;
+ bool is_virtual = false;
/**
* Determines if the call should fallback to Godot's object.Call(string, params) in C#.
*/
- bool requires_object_call;
+ bool requires_object_call = false;
/**
* Determines if the method visibility is 'internal' (visible only to files in the same assembly).
@@ -158,27 +153,20 @@ class BindingsGenerator {
* but are required by properties as getters or setters.
* Methods that are not meant to be exposed are those that begin with underscore and are not virtual.
*/
- bool is_internal;
+ bool is_internal = false;
List<ArgumentInterface> arguments;
- const DocData::MethodDoc *method_doc;
+ const DocData::MethodDoc *method_doc = nullptr;
- bool is_deprecated;
+ bool is_deprecated = false;
String deprecation_message;
void add_argument(const ArgumentInterface &argument) {
arguments.push_back(argument);
}
- MethodInterface() {
- is_vararg = false;
- is_virtual = false;
- requires_object_call = false;
- is_internal = false;
- method_doc = nullptr;
- is_deprecated = false;
- }
+ MethodInterface() {}
};
struct SignalInterface {
@@ -192,19 +180,16 @@ class BindingsGenerator {
List<ArgumentInterface> arguments;
- const DocData::MethodDoc *method_doc;
+ const DocData::MethodDoc *method_doc = nullptr;
- bool is_deprecated;
+ bool is_deprecated = false;
String deprecation_message;
void add_argument(const ArgumentInterface &argument) {
arguments.push_back(argument);
}
- SignalInterface() {
- method_doc = nullptr;
- is_deprecated = false;
- }
+ SignalInterface() {}
};
struct TypeInterface {
@@ -225,26 +210,26 @@ class BindingsGenerator {
*/
String proxy_name;
- ClassDB::APIType api_type;
+ ClassDB::APIType api_type = ClassDB::API_NONE;
- bool is_enum;
- bool is_object_type;
- bool is_singleton;
- bool is_reference;
+ bool is_enum = false;
+ bool is_object_type = false;
+ bool is_singleton = false;
+ bool is_reference = false;
/**
* Used only by Object-derived types.
* Determines if this type is not abstract (incomplete).
* e.g.: CanvasItem cannot be instantiated.
*/
- bool is_instantiable;
+ bool is_instantiable = false;
/**
* Used only by Object-derived types.
* Determines if the C# class owns the native handle and must free it somehow when disposed.
* e.g.: Reference types must notify when the C# instance is disposed, for proper refcounting.
*/
- bool memory_own;
+ bool memory_own = false;
/**
* This must be set to true for any struct bigger than 32-bits. Those cannot be passed/returned by value
@@ -252,7 +237,7 @@ class BindingsGenerator {
* In this case, [c_out] and [cs_out] must have a different format, explained below.
* The Mono IL interpreter icall trampolines don't support passing structs bigger than 32-bits by value (at least not on WASM).
*/
- bool ret_as_byref_arg;
+ bool ret_as_byref_arg = false;
// !! The comments of the following fields make reference to other fields via square brackets, e.g.: [field_name]
// !! When renaming those fields, make sure to rename their references in the comments
@@ -279,7 +264,7 @@ class BindingsGenerator {
* Formatting elements:
* %0 or %s: name of the parameter
*/
- String c_arg_in;
+ String c_arg_in = "%s";
/**
* One or more statements that determine how a variable of this type is returned from a function.
@@ -362,7 +347,7 @@ class BindingsGenerator {
*/
String im_type_out;
- const DocData::ClassDoc *class_doc;
+ const DocData::ClassDoc *class_doc = nullptr;
List<ConstantInterface> constants;
List<EnumInterface> enums;
@@ -372,8 +357,9 @@ class BindingsGenerator {
const MethodInterface *find_method_by_name(const StringName &p_cname) const {
for (const List<MethodInterface>::Element *E = methods.front(); E; E = E->next()) {
- if (E->get().cname == p_cname)
+ if (E->get().cname == p_cname) {
return &E->get();
+ }
}
return nullptr;
@@ -381,8 +367,9 @@ class BindingsGenerator {
const PropertyInterface *find_property_by_name(const StringName &p_cname) const {
for (const List<PropertyInterface>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().cname == p_cname)
+ if (E->get().cname == p_cname) {
return &E->get();
+ }
}
return nullptr;
@@ -390,8 +377,9 @@ class BindingsGenerator {
const PropertyInterface *find_property_by_proxy_name(const String &p_proxy_name) const {
for (const List<PropertyInterface>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().proxy_name == p_proxy_name)
+ if (E->get().proxy_name == p_proxy_name) {
return &E->get();
+ }
}
return nullptr;
@@ -399,8 +387,9 @@ class BindingsGenerator {
const MethodInterface *find_method_by_proxy_name(const String &p_proxy_name) const {
for (const List<MethodInterface>::Element *E = methods.front(); E; E = E->next()) {
- if (E->get().proxy_name == p_proxy_name)
+ if (E->get().proxy_name == p_proxy_name) {
return &E->get();
+ }
}
return nullptr;
@@ -482,24 +471,7 @@ class BindingsGenerator {
r_enum_itype.class_doc = &EditorHelp::get_doc_data()->class_list[r_enum_itype.proxy_name];
}
- TypeInterface() {
-
- api_type = ClassDB::API_NONE;
-
- is_enum = false;
- is_object_type = false;
- is_singleton = false;
- is_reference = false;
- is_instantiable = false;
-
- memory_own = false;
-
- ret_as_byref_arg = false;
-
- c_arg_in = "%s";
-
- class_doc = nullptr;
- }
+ TypeInterface() {}
};
struct InternalCall {
@@ -532,8 +504,8 @@ class BindingsGenerator {
}
};
- bool log_print_enabled;
- bool initialized;
+ bool log_print_enabled = true;
+ bool initialized = false;
OrderedHashMap<StringName, TypeInterface> obj_types;
@@ -557,58 +529,70 @@ class BindingsGenerator {
void _initialize_blacklisted_methods();
struct NameCache {
- StringName type_void;
- StringName type_Array;
- StringName type_Dictionary;
- StringName type_Variant;
- StringName type_VarArg;
- StringName type_Object;
- StringName type_Reference;
- StringName type_RID;
- StringName type_String;
- StringName type_StringName;
- StringName type_NodePath;
- StringName type_at_GlobalScope;
- StringName enum_Error;
-
- StringName type_sbyte;
- StringName type_short;
- StringName type_int;
- StringName type_long;
- StringName type_byte;
- StringName type_ushort;
- StringName type_uint;
- StringName type_ulong;
- StringName type_float;
- StringName type_double;
-
- NameCache() {
- type_void = StaticCString::create("void");
- type_Array = StaticCString::create("Array");
- type_Dictionary = StaticCString::create("Dictionary");
- type_Variant = StaticCString::create("Variant");
- type_VarArg = StaticCString::create("VarArg");
- type_Object = StaticCString::create("Object");
- type_Reference = StaticCString::create("Reference");
- type_RID = StaticCString::create("RID");
- type_String = StaticCString::create("String");
- type_StringName = StaticCString::create("StringName");
- type_NodePath = StaticCString::create("NodePath");
- type_at_GlobalScope = StaticCString::create("@GlobalScope");
- enum_Error = StaticCString::create("Error");
-
- type_sbyte = StaticCString::create("sbyte");
- type_short = StaticCString::create("short");
- type_int = StaticCString::create("int");
- type_long = StaticCString::create("long");
- type_byte = StaticCString::create("byte");
- type_ushort = StaticCString::create("ushort");
- type_uint = StaticCString::create("uint");
- type_ulong = StaticCString::create("ulong");
- type_float = StaticCString::create("float");
- type_double = StaticCString::create("double");
+ StringName type_void = StaticCString::create("void");
+ StringName type_Variant = StaticCString::create("Variant");
+ StringName type_VarArg = StaticCString::create("VarArg");
+ StringName type_Object = StaticCString::create("Object");
+ StringName type_Reference = StaticCString::create("Reference");
+ StringName type_RID = StaticCString::create("RID");
+ StringName type_String = StaticCString::create("String");
+ StringName type_StringName = StaticCString::create("StringName");
+ StringName type_NodePath = StaticCString::create("NodePath");
+ StringName type_at_GlobalScope = StaticCString::create("@GlobalScope");
+ StringName enum_Error = StaticCString::create("Error");
+
+ StringName type_sbyte = StaticCString::create("sbyte");
+ StringName type_short = StaticCString::create("short");
+ StringName type_int = StaticCString::create("int");
+ StringName type_byte = StaticCString::create("byte");
+ StringName type_ushort = StaticCString::create("ushort");
+ StringName type_uint = StaticCString::create("uint");
+ StringName type_long = StaticCString::create("long");
+ StringName type_ulong = StaticCString::create("ulong");
+
+ StringName type_bool = StaticCString::create("bool");
+ StringName type_float = StaticCString::create("float");
+ StringName type_double = StaticCString::create("double");
+
+ StringName type_Vector2 = StaticCString::create("Vector2");
+ StringName type_Rect2 = StaticCString::create("Rect2");
+ StringName type_Vector3 = StaticCString::create("Vector3");
+
+ // Object not included as it must be checked for all derived classes
+ static constexpr int nullable_types_count = 17;
+ StringName nullable_types[nullable_types_count] = {
+ type_String,
+ type_StringName,
+ type_NodePath,
+
+ StaticCString::create(_STR(Array)),
+ StaticCString::create(_STR(Dictionary)),
+ StaticCString::create(_STR(Callable)),
+ StaticCString::create(_STR(Signal)),
+
+ StaticCString::create(_STR(PackedByteArray)),
+ StaticCString::create(_STR(PackedInt32Array)),
+ StaticCString::create(_STR(PackedInt64rray)),
+ StaticCString::create(_STR(PackedFloat32Array)),
+ StaticCString::create(_STR(PackedFloat64Array)),
+ StaticCString::create(_STR(PackedStringArray)),
+ StaticCString::create(_STR(PackedVector2Array)),
+ StaticCString::create(_STR(PackedVector3Array)),
+ StaticCString::create(_STR(PackedColorArray)),
+ };
+
+ bool is_nullable_type(const StringName &p_type) const {
+ for (int i = 0; i < nullable_types_count; i++) {
+ if (p_type == nullable_types[i]) {
+ return true;
+ }
+ }
+
+ return false;
}
+ NameCache() {}
+
private:
NameCache(const NameCache &);
NameCache &operator=(const NameCache &);
@@ -619,7 +603,9 @@ class BindingsGenerator {
const List<InternalCall>::Element *find_icall_by_name(const String &p_name, const List<InternalCall> &p_list) {
const List<InternalCall>::Element *it = p_list.front();
while (it) {
- if (it->get().name == p_name) return it;
+ if (it->get().name == p_name) {
+ return it;
+ }
it = it->next();
}
return nullptr;
@@ -627,20 +613,22 @@ class BindingsGenerator {
const ConstantInterface *find_constant_by_name(const String &p_name, const List<ConstantInterface> &p_constants) const {
for (const List<ConstantInterface>::Element *E = p_constants.front(); E; E = E->next()) {
- if (E->get().name == p_name)
+ if (E->get().name == p_name) {
return &E->get();
+ }
}
return nullptr;
}
inline String get_unique_sig(const TypeInterface &p_type) {
- if (p_type.is_reference)
+ if (p_type.is_reference) {
return "Ref";
- else if (p_type.is_object_type)
+ } else if (p_type.is_object_type) {
return "Obj";
- else if (p_type.is_enum)
+ } else if (p_type.is_enum) {
return "int";
+ }
return p_type.name;
}
@@ -659,6 +647,7 @@ class BindingsGenerator {
StringName _get_float_type_name_from_meta(GodotTypeInfo::Metadata p_meta);
bool _arg_default_value_from_variant(const Variant &p_val, ArgumentInterface &r_iarg);
+ bool _arg_default_value_is_assignable_to_type(const Variant &p_val, const TypeInterface &p_arg_type);
bool _populate_object_type_interfaces();
void _populate_builtin_type_interfaces();
@@ -696,9 +685,7 @@ public:
static void handle_cmdline_args(const List<String> &p_cmdline_args);
- BindingsGenerator() :
- log_print_enabled(true),
- initialized(false) {
+ BindingsGenerator() {
_initialize();
}
};
diff --git a/modules/mono/editor/code_completion.cpp b/modules/mono/editor/code_completion.cpp
new file mode 100644
index 0000000000..7a5e465e7a
--- /dev/null
+++ b/modules/mono/editor/code_completion.cpp
@@ -0,0 +1,249 @@
+/*************************************************************************/
+/* code_completion.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "code_completion.h"
+
+#include "core/project_settings.h"
+#include "editor/editor_file_system.h"
+#include "editor/editor_settings.h"
+#include "scene/gui/control.h"
+#include "scene/main/node.h"
+
+namespace gdmono {
+
+// Almost everything here is taken from functions used by GDScript for code completion, adapted for C#.
+
+_FORCE_INLINE_ String quoted(const String &p_str) {
+ return "\"" + p_str + "\"";
+}
+
+void _add_nodes_suggestions(const Node *p_base, const Node *p_node, PackedStringArray &r_suggestions) {
+ if (p_node != p_base && !p_node->get_owner())
+ return;
+
+ String path_relative_to_orig = p_base->get_path_to(p_node);
+
+ r_suggestions.push_back(quoted(path_relative_to_orig));
+
+ for (int i = 0; i < p_node->get_child_count(); i++) {
+ _add_nodes_suggestions(p_base, p_node->get_child(i), r_suggestions);
+ }
+}
+
+Node *_find_node_for_script(Node *p_base, Node *p_current, const Ref<Script> &p_script) {
+ if (p_current->get_owner() != p_base && p_base != p_current)
+ return nullptr;
+
+ Ref<Script> c = p_current->get_script();
+
+ if (c == p_script)
+ return p_current;
+
+ for (int i = 0; i < p_current->get_child_count(); i++) {
+ Node *found = _find_node_for_script(p_base, p_current->get_child(i), p_script);
+ if (found)
+ return found;
+ }
+
+ return nullptr;
+}
+
+void _get_directory_contents(EditorFileSystemDirectory *p_dir, PackedStringArray &r_suggestions) {
+ for (int i = 0; i < p_dir->get_file_count(); i++) {
+ r_suggestions.push_back(quoted(p_dir->get_file_path(i)));
+ }
+
+ for (int i = 0; i < p_dir->get_subdir_count(); i++) {
+ _get_directory_contents(p_dir->get_subdir(i), r_suggestions);
+ }
+}
+
+Node *_try_find_owner_node_in_tree(const Ref<Script> p_script) {
+ SceneTree *tree = SceneTree::get_singleton();
+ if (!tree)
+ return nullptr;
+ Node *base = tree->get_edited_scene_root();
+ if (base) {
+ base = _find_node_for_script(base, base, p_script);
+ }
+ return base;
+}
+
+PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_script_file) {
+ PackedStringArray suggestions;
+
+ switch (p_kind) {
+ case CompletionKind::INPUT_ACTIONS: {
+ List<PropertyInfo> project_props;
+ ProjectSettings::get_singleton()->get_property_list(&project_props);
+
+ for (List<PropertyInfo>::Element *E = project_props.front(); E; E = E->next()) {
+ const PropertyInfo &prop = E->get();
+
+ if (!prop.name.begins_with("input/"))
+ continue;
+
+ String name = prop.name.substr(prop.name.find("/") + 1, prop.name.length());
+ suggestions.push_back(quoted(name));
+ }
+ } break;
+ case CompletionKind::NODE_PATHS: {
+ {
+ // AutoLoads
+ List<PropertyInfo> props;
+ ProjectSettings::get_singleton()->get_property_list(&props);
+
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+ String s = E->get().name;
+ if (!s.begins_with("autoload/")) {
+ continue;
+ }
+ String name = s.get_slice("/", 1);
+ suggestions.push_back(quoted("/root/" + name));
+ }
+ }
+
+ {
+ // Current edited scene tree
+ Ref<Script> script = ResourceLoader::load(p_script_file.simplify_path());
+ Node *base = _try_find_owner_node_in_tree(script);
+ if (base) {
+ _add_nodes_suggestions(base, base, suggestions);
+ }
+ }
+ } break;
+ case CompletionKind::RESOURCE_PATHS: {
+ if (bool(EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths"))) {
+ _get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), suggestions);
+ }
+ } break;
+ case CompletionKind::SCENE_PATHS: {
+ DirAccessRef dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ List<String> directories;
+ directories.push_back(dir_access->get_current_dir());
+
+ while (!directories.empty()) {
+ dir_access->change_dir(directories.back()->get());
+ directories.pop_back();
+
+ dir_access->list_dir_begin();
+ String filename = dir_access->get_next();
+
+ while (filename != "") {
+ if (filename == "." || filename == "..") {
+ filename = dir_access->get_next();
+ continue;
+ }
+
+ if (dir_access->dir_exists(filename)) {
+ directories.push_back(dir_access->get_current_dir().plus_file(filename));
+ } else if (filename.ends_with(".tscn") || filename.ends_with(".scn")) {
+ suggestions.push_back(quoted(dir_access->get_current_dir().plus_file(filename)));
+ }
+
+ filename = dir_access->get_next();
+ }
+ }
+ } break;
+ case CompletionKind::SHADER_PARAMS: {
+ print_verbose("Shared params completion for C# not implemented.");
+ } break;
+ case CompletionKind::SIGNALS: {
+ Ref<Script> script = ResourceLoader::load(p_script_file.simplify_path());
+
+ List<MethodInfo> signals;
+ script->get_script_signal_list(&signals);
+
+ StringName native = script->get_instance_base_type();
+ if (native != StringName()) {
+ ClassDB::get_signal_list(native, &signals, /* p_no_inheritance: */ false);
+ }
+
+ for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) {
+ const String &signal = E->get().name;
+ suggestions.push_back(quoted(signal));
+ }
+ } break;
+ case CompletionKind::THEME_COLORS: {
+ Ref<Script> script = ResourceLoader::load(p_script_file.simplify_path());
+ Node *base = _try_find_owner_node_in_tree(script);
+ if (base && Object::cast_to<Control>(base)) {
+ List<StringName> sn;
+ Theme::get_default()->get_color_list(base->get_class(), &sn);
+
+ for (List<StringName>::Element *E = sn.front(); E; E = E->next()) {
+ suggestions.push_back(quoted(E->get()));
+ }
+ }
+ } break;
+ case CompletionKind::THEME_CONSTANTS: {
+ Ref<Script> script = ResourceLoader::load(p_script_file.simplify_path());
+ Node *base = _try_find_owner_node_in_tree(script);
+ if (base && Object::cast_to<Control>(base)) {
+ List<StringName> sn;
+ Theme::get_default()->get_constant_list(base->get_class(), &sn);
+
+ for (List<StringName>::Element *E = sn.front(); E; E = E->next()) {
+ suggestions.push_back(quoted(E->get()));
+ }
+ }
+ } break;
+ case CompletionKind::THEME_FONTS: {
+ Ref<Script> script = ResourceLoader::load(p_script_file.simplify_path());
+ Node *base = _try_find_owner_node_in_tree(script);
+ if (base && Object::cast_to<Control>(base)) {
+ List<StringName> sn;
+ Theme::get_default()->get_font_list(base->get_class(), &sn);
+
+ for (List<StringName>::Element *E = sn.front(); E; E = E->next()) {
+ suggestions.push_back(quoted(E->get()));
+ }
+ }
+ } break;
+ case CompletionKind::THEME_STYLES: {
+ Ref<Script> script = ResourceLoader::load(p_script_file.simplify_path());
+ Node *base = _try_find_owner_node_in_tree(script);
+ if (base && Object::cast_to<Control>(base)) {
+ List<StringName> sn;
+ Theme::get_default()->get_stylebox_list(base->get_class(), &sn);
+
+ for (List<StringName>::Element *E = sn.front(); E; E = E->next()) {
+ suggestions.push_back(quoted(E->get()));
+ }
+ }
+ } break;
+ default:
+ ERR_FAIL_V_MSG(suggestions, "Invalid completion kind.");
+ }
+
+ return suggestions;
+}
+
+} // namespace gdmono
diff --git a/modules/mono/editor/code_completion.h b/modules/mono/editor/code_completion.h
new file mode 100644
index 0000000000..77673b766f
--- /dev/null
+++ b/modules/mono/editor/code_completion.h
@@ -0,0 +1,56 @@
+/*************************************************************************/
+/* code_completion.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef CODE_COMPLETION_H
+#define CODE_COMPLETION_H
+
+#include "core/ustring.h"
+#include "core/variant.h"
+
+namespace gdmono {
+
+enum class CompletionKind {
+ INPUT_ACTIONS = 0,
+ NODE_PATHS,
+ RESOURCE_PATHS,
+ SCENE_PATHS,
+ SHADER_PARAMS,
+ SIGNALS,
+ THEME_COLORS,
+ THEME_CONSTANTS,
+ THEME_FONTS,
+ THEME_STYLES
+};
+
+PackedStringArray get_code_completion(CompletionKind p_kind, const String &p_script_file);
+
+} // namespace gdmono
+
+#endif // CODE_COMPLETION_H
diff --git a/modules/mono/editor/csharp_project.cpp b/modules/mono/editor/csharp_project.cpp
index e5c2d023d3..3a30f3106c 100644
--- a/modules/mono/editor/csharp_project.cpp
+++ b/modules/mono/editor/csharp_project.cpp
@@ -45,7 +45,6 @@
namespace CSharpProject {
void add_item(const String &p_project_path, const String &p_item_type, const String &p_include) {
-
if (!GLOBAL_DEF("mono/project/auto_update_project", true))
return;
diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp
index 283d4beb8e..b183787618 100644
--- a/modules/mono/editor/editor_internal_calls.cpp
+++ b/modules/mono/editor/editor_internal_calls.cpp
@@ -48,6 +48,7 @@
#include "../mono_gd/gd_mono_marshal.h"
#include "../utils/osx_utils.h"
#include "bindings_generator.h"
+#include "code_completion.h"
#include "godotsharp_export.h"
#include "script_class_parser.h"
@@ -231,14 +232,14 @@ int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObje
return err;
}
-uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_dependencies,
- MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_dependencies) {
- Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_dependencies);
+uint32_t godot_icall_ExportPlugin_GetExportedAssemblyDependencies(MonoObject *p_initial_assemblies,
+ MonoString *p_build_config, MonoString *p_custom_bcl_dir, MonoObject *r_assembly_dependencies) {
+ Dictionary initial_dependencies = GDMonoMarshal::mono_object_to_variant(p_initial_assemblies);
String build_config = GDMonoMarshal::mono_string_to_godot(p_build_config);
String custom_bcl_dir = GDMonoMarshal::mono_string_to_godot(p_custom_bcl_dir);
- Dictionary dependencies = GDMonoMarshal::mono_object_to_variant(r_dependencies);
+ Dictionary assembly_dependencies = GDMonoMarshal::mono_object_to_variant(r_assembly_dependencies);
- return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, dependencies);
+ return GodotSharpExport::get_exported_assembly_dependencies(initial_dependencies, build_config, custom_bcl_dir, assembly_dependencies);
}
MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt(MonoString *p_config) {
@@ -354,6 +355,12 @@ void godot_icall_Internal_ScriptEditorDebugger_ReloadScripts() {
}
}
+MonoArray *godot_icall_Internal_CodeCompletionRequest(int32_t p_kind, MonoString *p_script_file) {
+ String script_file = GDMonoMarshal::mono_string_to_godot(p_script_file);
+ PackedStringArray suggestions = gdmono::get_code_completion((gdmono::CompletionKind)p_kind, script_file);
+ return GDMonoMarshal::PackedStringArray_to_mono_array(suggestions);
+}
+
float godot_icall_Globals_EditorScale() {
return EDSCALE;
}
@@ -392,7 +399,6 @@ MonoBoolean godot_icall_Utils_OS_UnixFileHasExecutableAccess(MonoString *p_file_
}
void register_editor_internal_calls() {
-
// GodotSharpDirs
mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResDataDir", (void *)godot_icall_GodotSharpDirs_ResDataDir);
mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResMetadataDir", (void *)godot_icall_GodotSharpDirs_ResMetadataDir);
@@ -454,6 +460,7 @@ void register_editor_internal_calls() {
mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunPlay", (void *)godot_icall_Internal_EditorRunPlay);
mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunStop", (void *)godot_icall_Internal_EditorRunStop);
mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorDebugger_ReloadScripts", (void *)godot_icall_Internal_ScriptEditorDebugger_ReloadScripts);
+ mono_add_internal_call("GodotTools.Internals.Internal::internal_CodeCompletionRequest", (void *)godot_icall_Internal_CodeCompletionRequest);
// Globals
mono_add_internal_call("GodotTools.Internals.Globals::internal_EditorScale", (void *)godot_icall_Globals_EditorScale);
diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp
index 324013e5e2..1cdb08d50e 100644
--- a/modules/mono/editor/godotsharp_export.cpp
+++ b/modules/mono/editor/godotsharp_export.cpp
@@ -32,78 +32,80 @@
#include <mono/metadata/image.h>
+#include "core/io/file_access_pack.h"
#include "core/os/os.h"
+#include "core/project_settings.h"
#include "../mono_gd/gd_mono.h"
#include "../mono_gd/gd_mono_assembly.h"
#include "../mono_gd/gd_mono_cache.h"
+#include "../utils/macros.h"
namespace GodotSharpExport {
-String get_assemblyref_name(MonoImage *p_image, int index) {
+struct AssemblyRefInfo {
+ String name;
+ uint16_t major;
+ uint16_t minor;
+ uint16_t build;
+ uint16_t revision;
+};
+
+AssemblyRefInfo get_assemblyref_name(MonoImage *p_image, int index) {
const MonoTableInfo *table_info = mono_image_get_table_info(p_image, MONO_TABLE_ASSEMBLYREF);
uint32_t cols[MONO_ASSEMBLYREF_SIZE];
mono_metadata_decode_row(table_info, index, cols, MONO_ASSEMBLYREF_SIZE);
- return String::utf8(mono_metadata_string_heap(p_image, cols[MONO_ASSEMBLYREF_NAME]));
+ return {
+ String::utf8(mono_metadata_string_heap(p_image, cols[MONO_ASSEMBLYREF_NAME])),
+ (uint16_t)cols[MONO_ASSEMBLYREF_MAJOR_VERSION],
+ (uint16_t)cols[MONO_ASSEMBLYREF_MINOR_VERSION],
+ (uint16_t)cols[MONO_ASSEMBLYREF_BUILD_NUMBER],
+ (uint16_t)cols[MONO_ASSEMBLYREF_REV_NUMBER]
+ };
}
-Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies) {
+Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_assembly_dependencies) {
MonoImage *image = p_assembly->get_image();
for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) {
- String ref_name = get_assemblyref_name(image, i);
+ AssemblyRefInfo ref_info = get_assemblyref_name(image, i);
+
+ const String &ref_name = ref_info.name;
- if (r_dependencies.has(ref_name))
+ if (r_assembly_dependencies.has(ref_name))
continue;
GDMonoAssembly *ref_assembly = nullptr;
- String path;
- bool has_extension = ref_name.ends_with(".dll") || ref_name.ends_with(".exe");
-
- for (int j = 0; j < p_search_dirs.size(); j++) {
- const String &search_dir = p_search_dirs[j];
-
- if (has_extension) {
- path = search_dir.plus_file(ref_name);
- if (FileAccess::exists(path)) {
- GDMono::get_singleton()->load_assembly_from(ref_name.get_basename(), path, &ref_assembly, true);
- if (ref_assembly != nullptr)
- break;
- }
- } else {
- path = search_dir.plus_file(ref_name + ".dll");
- if (FileAccess::exists(path)) {
- GDMono::get_singleton()->load_assembly_from(ref_name, path, &ref_assembly, true);
- if (ref_assembly != nullptr)
- break;
- }
-
- path = search_dir.plus_file(ref_name + ".exe");
- if (FileAccess::exists(path)) {
- GDMono::get_singleton()->load_assembly_from(ref_name, path, &ref_assembly, true);
- if (ref_assembly != nullptr)
- break;
- }
- }
- }
- ERR_FAIL_COND_V_MSG(!ref_assembly, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'.");
+ {
+ MonoAssemblyName *ref_aname = mono_assembly_name_new("A"); // We can't allocate an empty MonoAssemblyName, hence "A"
+ CRASH_COND(ref_aname == nullptr);
+ SCOPE_EXIT {
+ mono_assembly_name_free(ref_aname);
+ mono_free(ref_aname);
+ };
+
+ mono_assembly_get_assemblyref(image, i, ref_aname);
- // Use the path we got from the search. Don't try to get the path from the loaded assembly as we can't trust it will be from the selected BCL dir.
- r_dependencies[ref_name] = path;
+ if (!GDMono::get_singleton()->load_assembly(ref_name, ref_aname, &ref_assembly, /* refonly: */ true, p_search_dirs)) {
+ ERR_FAIL_V_MSG(ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + ref_name + "'.");
+ }
+
+ r_assembly_dependencies[ref_name] = ref_assembly->get_path();
+ }
- Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies);
+ Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_assembly_dependencies);
ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot load one of the dependencies for the assembly: '" + ref_name + "'.");
}
return OK;
}
-Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies,
- const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_dependencies) {
+Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
+ const String &p_build_config, const String &p_custom_bcl_dir, Dictionary &r_assembly_dependencies) {
MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.Domain.ProjectExport");
ERR_FAIL_NULL_V(export_domain, FAILED);
_GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain);
@@ -113,16 +115,21 @@ Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencie
Vector<String> search_dirs;
GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_bcl_dir);
- for (const Variant *key = p_initial_dependencies.next(); key; key = p_initial_dependencies.next(key)) {
+ if (p_custom_bcl_dir.length()) {
+ // Only one mscorlib can be loaded. We need this workaround to make sure we get it from the right BCL directory.
+ r_assembly_dependencies["mscorlib"] = p_custom_bcl_dir.plus_file("mscorlib.dll").simplify_path();
+ }
+
+ for (const Variant *key = p_initial_assemblies.next(); key; key = p_initial_assemblies.next(key)) {
String assembly_name = *key;
- String assembly_path = p_initial_dependencies[*key];
+ String assembly_path = p_initial_assemblies[*key];
GDMonoAssembly *assembly = nullptr;
bool load_success = GDMono::get_singleton()->load_assembly_from(assembly_name, assembly_path, &assembly, /* refonly: */ true);
ERR_FAIL_COND_V_MSG(!load_success, ERR_CANT_RESOLVE, "Cannot load assembly (refonly): '" + assembly_name + "'.");
- Error err = get_assembly_dependencies(assembly, search_dirs, r_dependencies);
+ Error err = get_assembly_dependencies(assembly, search_dirs, r_assembly_dependencies);
if (err != OK)
return err;
}
diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h
index 36138f81b7..9ab57755de 100644
--- a/modules/mono/editor/godotsharp_export.h
+++ b/modules/mono/editor/godotsharp_export.h
@@ -41,8 +41,8 @@ namespace GodotSharpExport {
Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies);
-Error get_exported_assembly_dependencies(const Dictionary &p_initial_dependencies,
- const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_dependencies);
+Error get_exported_assembly_dependencies(const Dictionary &p_initial_assemblies,
+ const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_assembly_dependencies);
} // namespace GodotSharpExport
diff --git a/modules/mono/editor/script_class_parser.cpp b/modules/mono/editor/script_class_parser.cpp
index bece23c9a6..7276612230 100644
--- a/modules/mono/editor/script_class_parser.cpp
+++ b/modules/mono/editor/script_class_parser.cpp
@@ -54,13 +54,11 @@ const char *ScriptClassParser::token_names[ScriptClassParser::TK_MAX] = {
};
String ScriptClassParser::get_token_name(ScriptClassParser::Token p_token) {
-
ERR_FAIL_INDEX_V(p_token, TK_MAX, "<error>");
return token_names[p_token];
}
ScriptClassParser::Token ScriptClassParser::get_token() {
-
while (true) {
switch (code[idx]) {
case '\n': {
@@ -181,14 +179,24 @@ ScriptClassParser::Token ScriptClassParser::get_token() {
CharType res = 0;
switch (next) {
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'f': res = 12; break;
+ case 'b':
+ res = 8;
+ break;
+ case 't':
+ res = 9;
+ break;
+ case 'n':
+ res = 10;
+ break;
+ case 'f':
+ res = 12;
+ break;
case 'r':
res = 13;
break;
- case '\"': res = '\"'; break;
+ case '\"':
+ res = '\"';
+ break;
case '\\':
res = '\\';
break;
@@ -258,7 +266,6 @@ ScriptClassParser::Token ScriptClassParser::get_token() {
}
Error ScriptClassParser::_skip_generic_type_params() {
-
Token tk;
while (true) {
@@ -327,7 +334,6 @@ Error ScriptClassParser::_skip_generic_type_params() {
}
Error ScriptClassParser::_parse_type_full_name(String &r_full_name) {
-
Token tk = get_token();
if (tk != TK_IDENTIFIER) {
@@ -360,7 +366,6 @@ Error ScriptClassParser::_parse_type_full_name(String &r_full_name) {
}
Error ScriptClassParser::_parse_class_base(Vector<String> &r_base) {
-
String name;
Error err = _parse_type_full_name(name);
@@ -460,7 +465,6 @@ Error ScriptClassParser::_parse_type_constraints() {
}
Error ScriptClassParser::_parse_namespace_name(String &r_name, int &r_curly_stack) {
-
Token tk = get_token();
if (tk == TK_IDENTIFIER) {
@@ -487,7 +491,6 @@ Error ScriptClassParser::_parse_namespace_name(String &r_name, int &r_curly_stac
}
Error ScriptClassParser::parse(const String &p_code) {
-
code = p_code;
idx = 0;
line = 0;
@@ -643,7 +646,6 @@ static String get_preprocessor_directive(const String &p_line, int p_from) {
}
static void run_dummy_preprocessor(String &r_source, const String &p_filepath) {
-
Vector<String> lines = r_source.split("\n", /* p_allow_empty: */ true);
bool *include_lines = memnew_arr(bool, lines.size());
@@ -710,7 +712,6 @@ static void run_dummy_preprocessor(String &r_source, const String &p_filepath) {
}
Error ScriptClassParser::parse_file(const String &p_filepath) {
-
String source;
Error ferr = read_all_file_utf8(p_filepath, source);
diff --git a/modules/mono/editor/script_class_parser.h b/modules/mono/editor/script_class_parser.h
index a76a3a50a9..c194ed1422 100644
--- a/modules/mono/editor/script_class_parser.h
+++ b/modules/mono/editor/script_class_parser.h
@@ -36,7 +36,6 @@
#include "core/vector.h"
class ScriptClassParser {
-
public:
struct NameDecl {
enum Type {
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
index aba1065498..a963810d63 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Array.cs
@@ -15,10 +15,7 @@ namespace Godot.Collections
public override bool IsInvalid
{
- get
- {
- return handle == IntPtr.Zero;
- }
+ get { return handle == IntPtr.Zero; }
}
protected override bool ReleaseHandle()
@@ -43,7 +40,8 @@ namespace Godot.Collections
if (collection == null)
throw new NullReferenceException($"Parameter '{nameof(collection)} cannot be null.'");
- MarshalUtils.EnumerableToArray(collection, GetPtr());
+ foreach (object element in collection)
+ Add(element);
}
internal Array(ArraySafeHandle handle)
@@ -272,14 +270,8 @@ namespace Godot.Collections
public T this[int index]
{
- get
- {
- return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass);
- }
- set
- {
- objectArray[index] = value;
- }
+ get { return (T)Array.godot_icall_Array_At_Generic(GetPtr(), index, elemTypeEncoding, elemTypeClass); }
+ set { objectArray[index] = value; }
}
public int IndexOf(T item)
@@ -301,18 +293,12 @@ namespace Godot.Collections
public int Count
{
- get
- {
- return objectArray.Count;
- }
+ get { return objectArray.Count; }
}
public bool IsReadOnly
{
- get
- {
- return objectArray.IsReadOnly;
- }
+ get { return objectArray.IsReadOnly; }
}
public void Add(T item)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
index 1d1a49945f..6030b72a44 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Color.cs
@@ -306,16 +306,26 @@ namespace Godot
return res;
}
- public Color LinearInterpolate(Color c, float t)
- {
- var res = this;
-
- res.r += t * (c.r - r);
- res.g += t * (c.g - g);
- res.b += t * (c.b - b);
- res.a += t * (c.a - a);
+ public Color Lerp(Color to, float weight)
+ {
+ return new Color
+ (
+ Mathf.Lerp(r, to.r, weight),
+ Mathf.Lerp(g, to.g, weight),
+ Mathf.Lerp(b, to.b, weight),
+ Mathf.Lerp(a, to.a, weight)
+ );
+ }
- return res;
+ public Color Lerp(Color to, Color weight)
+ {
+ return new Color
+ (
+ Mathf.Lerp(r, to.r, weight.r),
+ Mathf.Lerp(g, to.g, weight.g),
+ Mathf.Lerp(b, to.b, weight.b),
+ Mathf.Lerp(a, to.a, weight.a)
+ );
}
public uint ToAbgr32()
@@ -410,7 +420,7 @@ namespace Godot
return txt;
}
- // Constructors
+ // Constructors
public Color(float r, float g, float b, float a = 1.0f)
{
this.r = r;
@@ -419,6 +429,14 @@ namespace Godot
this.a = a;
}
+ public Color(Color c, float a = 1.0f)
+ {
+ r = c.r;
+ g = c.g;
+ b = c.b;
+ this.a = a;
+ }
+
public Color(uint rgba)
{
a = (rgba & 0xFF) / 255.0f;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
index d72109de92..213fc181c1 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Dictionary.cs
@@ -15,10 +15,7 @@ namespace Godot.Collections
public override bool IsInvalid
{
- get
- {
- return handle == IntPtr.Zero;
- }
+ get { return handle == IntPtr.Zero; }
}
protected override bool ReleaseHandle()
@@ -45,7 +42,8 @@ namespace Godot.Collections
if (dictionary == null)
throw new NullReferenceException($"Parameter '{nameof(dictionary)} cannot be null.'");
- MarshalUtils.IDictionaryToDictionary(dictionary, GetPtr());
+ foreach (DictionaryEntry entry in dictionary)
+ Add(entry.Key, entry.Value);
}
internal Dictionary(DictionarySafeHandle handle)
@@ -330,14 +328,8 @@ namespace Godot.Collections
public TValue this[TKey key]
{
- get
- {
- return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass);
- }
- set
- {
- objectDict[key] = value;
- }
+ get { return (TValue)Dictionary.godot_icall_Dictionary_GetValue_Generic(objectDict.GetPtr(), key, valTypeEncoding, valTypeClass); }
+ set { objectDict[key] = value; }
}
public ICollection<TKey> Keys
@@ -385,18 +377,12 @@ namespace Godot.Collections
public int Count
{
- get
- {
- return objectDict.Count;
- }
+ get { return objectDict.Count; }
}
public bool IsReadOnly
{
- get
- {
- return objectDict.IsReadOnly;
- }
+ get { return objectDict.IsReadOnly; }
}
public void Add(KeyValuePair<TKey, TValue> item)
@@ -440,7 +426,8 @@ namespace Godot.Collections
public bool Remove(KeyValuePair<TKey, TValue> item)
{
- return Dictionary.godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value); ;
+ return Dictionary.godot_icall_Dictionary_Remove(GetPtr(), item.Key, item.Value);
+ ;
}
// IEnumerable<KeyValuePair<TKey, TValue>>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
index a1d63a62ef..c59d083080 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/MarshalUtils.cs
@@ -16,10 +16,8 @@ namespace Godot
/// <exception cref="System.InvalidOperationException">
/// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false.
/// </exception>
- static bool TypeIsGenericArray(Type type)
- {
- return type.GetGenericTypeDefinition() == typeof(Godot.Collections.Array<>);
- }
+ static bool TypeIsGenericArray(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(Godot.Collections.Array<>);
/// <summary>
/// Returns <see langword="true"/> if the generic type definition of <paramref name="type"/>
@@ -28,10 +26,20 @@ namespace Godot
/// <exception cref="System.InvalidOperationException">
/// <paramref name="type"/> is not a generic type. That is, IsGenericType returns false.
/// </exception>
- static bool TypeIsGenericDictionary(Type type)
- {
- return type.GetGenericTypeDefinition() == typeof(Godot.Collections.Dictionary<,>);
- }
+ static bool TypeIsGenericDictionary(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(Godot.Collections.Dictionary<,>);
+
+ static bool TypeIsSystemGenericList(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.List<>);
+
+ static bool TypeIsSystemGenericDictionary(Type type) =>
+ type.GetGenericTypeDefinition() == typeof(System.Collections.Generic.Dictionary<,>);
+
+ static bool TypeIsGenericIEnumerable(Type type) => type.GetGenericTypeDefinition() == typeof(IEnumerable<>);
+
+ static bool TypeIsGenericICollection(Type type) => type.GetGenericTypeDefinition() == typeof(ICollection<>);
+
+ static bool TypeIsGenericIDictionary(Type type) => type.GetGenericTypeDefinition() == typeof(IDictionary<,>);
static void ArrayGetElementType(Type arrayType, out Type elementType)
{
@@ -45,105 +53,6 @@ namespace Godot
valueType = genericArgs[1];
}
- static bool GenericIEnumerableIsAssignableFromType(Type type)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- return true;
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- return true;
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- return false;
-
- return GenericIEnumerableIsAssignableFromType(baseType);
- }
-
- static bool GenericIDictionaryIsAssignableFromType(Type type)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- return true;
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- return true;
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- return false;
-
- return GenericIDictionaryIsAssignableFromType(baseType);
- }
-
- static bool GenericIEnumerableIsAssignableFromType(Type type, out Type elementType)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- {
- elementType = type.GetGenericArguments()[0];
- return true;
- }
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
- {
- elementType = interfaceType.GetGenericArguments()[0];
- return true;
- }
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- {
- elementType = null;
- return false;
- }
-
- return GenericIEnumerableIsAssignableFromType(baseType, out elementType);
- }
-
- static bool GenericIDictionaryIsAssignableFromType(Type type, out Type keyType, out Type valueType)
- {
- if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- {
- var genericArgs = type.GetGenericArguments();
- keyType = genericArgs[0];
- valueType = genericArgs[1];
- return true;
- }
-
- foreach (var interfaceType in type.GetInterfaces())
- {
- if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IDictionary<,>))
- {
- var genericArgs = interfaceType.GetGenericArguments();
- keyType = genericArgs[0];
- valueType = genericArgs[1];
- return true;
- }
- }
-
- Type baseType = type.BaseType;
-
- if (baseType == null)
- {
- keyType = null;
- valueType = null;
- return false;
- }
-
- return GenericIDictionaryIsAssignableFromType(baseType, out keyType, out valueType);
- }
-
static Type MakeGenericArrayType(Type elemType)
{
return typeof(Godot.Collections.Array<>).MakeGenericType(elemType);
@@ -153,60 +62,5 @@ namespace Godot
{
return typeof(Godot.Collections.Dictionary<,>).MakeGenericType(keyType, valueType);
}
-
- // TODO Add support for IEnumerable<T> and IDictionary<TKey, TValue>
- // TODO: EnumerableToArray and IDictionaryToDictionary can be optimized
-
- internal static void EnumerableToArray(IEnumerable enumerable, IntPtr godotArrayPtr)
- {
- if (enumerable is ICollection collection)
- {
- int count = collection.Count;
-
- object[] tempArray = new object[count];
- collection.CopyTo(tempArray, 0);
-
- for (int i = 0; i < count; i++)
- {
- Array.godot_icall_Array_Add(godotArrayPtr, tempArray[i]);
- }
- }
- else
- {
- foreach (object element in enumerable)
- {
- Array.godot_icall_Array_Add(godotArrayPtr, element);
- }
- }
- }
-
- internal static void IDictionaryToDictionary(IDictionary dictionary, IntPtr godotDictionaryPtr)
- {
- foreach (DictionaryEntry entry in dictionary)
- {
- Dictionary.godot_icall_Dictionary_Add(godotDictionaryPtr, entry.Key, entry.Value);
- }
- }
-
- internal static void GenericIDictionaryToDictionary(object dictionary, IntPtr godotDictionaryPtr)
- {
-#if DEBUG
- if (!GenericIDictionaryIsAssignableFromType(dictionary.GetType()))
- throw new InvalidOperationException("The type does not implement IDictionary<,>");
-#endif
-
- // TODO: Can we optimize this?
-
- var keys = ((IEnumerable)dictionary.GetType().GetProperty("Keys").GetValue(dictionary)).GetEnumerator();
- var values = ((IEnumerable)dictionary.GetType().GetProperty("Values").GetValue(dictionary)).GetEnumerator();
-
- while (keys.MoveNext() && values.MoveNext())
- {
- object key = keys.Current;
- object value = values.Current;
-
- Dictionary.godot_icall_Dictionary_Add(godotDictionaryPtr, key, value);
- }
- }
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
index 91e614dc7b..1098ffe4e5 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2.cs
@@ -127,7 +127,7 @@ namespace Godot
{
var g = this;
- g.GrowIndividual(Margin.Left == margin ? by : 0,
+ g = g.GrowIndividual(Margin.Left == margin ? by : 0,
Margin.Top == margin ? by : 0,
Margin.Right == margin ? by : 0,
Margin.Bottom == margin ? by : 0);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
index bc2cad8713..c0b236c524 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Rect2i.cs
@@ -122,7 +122,7 @@ namespace Godot
{
var g = this;
- g.GrowIndividual(Margin.Left == margin ? by : 0,
+ g = g.GrowIndividual(Margin.Left == margin ? by : 0,
Margin.Top == margin ? by : 0,
Margin.Right == margin ? by : 0,
Margin.Bottom == margin ? by : 0);
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index 099eacd7dd..41b4e9367f 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -12,7 +12,7 @@ namespace Godot
{
private static int GetSliceCount(this string instance, string splitter)
{
- if (instance.Empty() || splitter.Empty())
+ if (string.IsNullOrEmpty(instance) || string.IsNullOrEmpty(splitter))
return 0;
int pos = 0;
@@ -29,7 +29,7 @@ namespace Godot
private static string GetSliceCharacter(this string instance, char splitter, int slice)
{
- if (!instance.Empty() && slice >= 0)
+ if (!string.IsNullOrEmpty(instance) && slice >= 0)
{
int i = 0;
int prev = 0;
@@ -237,10 +237,10 @@ namespace Godot
// </summary>
public static int CompareTo(this string instance, string to, bool caseSensitive = true)
{
- if (instance.Empty())
- return to.Empty() ? 0 : -1;
+ if (string.IsNullOrEmpty(instance))
+ return string.IsNullOrEmpty(to) ? 0 : -1;
- if (to.Empty())
+ if (string.IsNullOrEmpty(to))
return 1;
int instanceIndex = 0;
@@ -287,14 +287,6 @@ namespace Godot
}
// <summary>
- // Return true if the string is empty.
- // </summary>
- public static bool Empty(this string instance)
- {
- return string.IsNullOrEmpty(instance);
- }
-
- // <summary>
// Return true if the strings ends with the given string.
// </summary>
public static bool EndsWith(this string instance, string text)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs
index aa8815d1aa..6a58b90561 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform.cs
@@ -104,8 +104,8 @@ namespace Godot
Vector3 destinationLocation = transform.origin;
var interpolated = new Transform();
- interpolated.basis.SetQuatScale(sourceRotation.Slerp(destinationRotation, c).Normalized(), sourceScale.LinearInterpolate(destinationScale, c));
- interpolated.origin = sourceLocation.LinearInterpolate(destinationLocation, c);
+ interpolated.basis.SetQuatScale(sourceRotation.Slerp(destinationRotation, c).Normalized(), sourceScale.Lerp(destinationScale, c));
+ interpolated.origin = sourceLocation.Lerp(destinationLocation, c);
return interpolated;
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
index e72a44809a..3ae96d4922 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Transform2D.cs
@@ -172,7 +172,7 @@ namespace Godot
if (dot > 0.9995f)
{
// Linearly interpolate to avoid numerical precision issues
- v = v1.LinearInterpolate(v2, c).Normalized();
+ v = v1.Lerp(v2, c).Normalized();
}
else
{
@@ -186,8 +186,8 @@ namespace Godot
Vector2 p2 = m.origin;
// Construct matrix
- var res = new Transform2D(Mathf.Atan2(v.y, v.x), p1.LinearInterpolate(p2, c));
- Vector2 scale = s1.LinearInterpolate(s2, c);
+ var res = new Transform2D(Mathf.Atan2(v.y, v.x), p1.Lerp(p2, c));
+ Vector2 scale = s1.Lerp(s2, c);
res.x *= scale;
res.y *= scale;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index f7b13198f8..7e4804f9fd 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -186,14 +186,22 @@ namespace Godot
return x * x + y * y;
}
- public Vector2 LinearInterpolate(Vector2 b, real_t t)
+ public Vector2 Lerp(Vector2 to, real_t weight)
{
- var res = this;
-
- res.x += t * (b.x - x);
- res.y += t * (b.y - y);
+ return new Vector2
+ (
+ Mathf.Lerp(x, to.x, weight),
+ Mathf.Lerp(y, to.y, weight)
+ );
+ }
- return res;
+ public Vector2 Lerp(Vector2 to, Vector2 weight)
+ {
+ return new Vector2
+ (
+ Mathf.Lerp(x, to.x, weight.x),
+ Mathf.Lerp(y, to.y, weight.y)
+ );
}
public Vector2 MoveToward(Vector2 to, real_t delta)
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index a43836e985..b26e17ecba 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -184,13 +184,23 @@ namespace Godot
return x2 + y2 + z2;
}
- public Vector3 LinearInterpolate(Vector3 b, real_t t)
+ public Vector3 Lerp(Vector3 to, real_t weight)
{
return new Vector3
(
- x + t * (b.x - x),
- y + t * (b.y - y),
- z + t * (b.z - z)
+ Mathf.Lerp(x, to.x, weight),
+ Mathf.Lerp(y, to.y, weight),
+ Mathf.Lerp(z, to.z, weight)
+ );
+ }
+
+ public Vector3 Lerp(Vector3 to, Vector3 weight)
+ {
+ return new Vector3
+ (
+ Mathf.Lerp(x, to.x, weight.x),
+ Mathf.Lerp(y, to.y, weight.y),
+ Mathf.Lerp(z, to.z, weight.z)
);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
index ba0bbd7630..b5ac124c9a 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
+++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj
@@ -30,6 +30,7 @@
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
+ <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
diff --git a/modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj b/modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj
index 22853797c1..8785931312 100644
--- a/modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj
+++ b/modules/mono/glue/GodotSharp/GodotSharpEditor/GodotSharpEditor.csproj
@@ -30,6 +30,7 @@
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
+ <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.0" PrivateAssets="All" />
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
diff --git a/modules/mono/glue/arguments_vector.h b/modules/mono/glue/arguments_vector.h
index aeb466ba72..4ee553fc11 100644
--- a/modules/mono/glue/arguments_vector.h
+++ b/modules/mono/glue/arguments_vector.h
@@ -35,7 +35,6 @@
template <typename T, int POOL_SIZE = 5>
struct ArgumentsVector {
-
private:
T pool[POOL_SIZE];
T *_ptr;
diff --git a/modules/mono/glue/gd_glue.cpp b/modules/mono/glue/gd_glue.cpp
index 2da39a916a..e43b06d18e 100644
--- a/modules/mono/glue/gd_glue.cpp
+++ b/modules/mono/glue/gd_glue.cpp
@@ -91,7 +91,6 @@ void godot_icall_GD_print(MonoArray *p_what) {
}
void godot_icall_GD_printerr(MonoArray *p_what) {
-
String str;
int length = mono_array_length(p_what);
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index d596163926..692da991c7 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -86,7 +86,6 @@ String _get_mono_user_dir() {
}
class _GodotSharpDirs {
-
public:
String res_data_dir;
String res_metadata_dir;
diff --git a/modules/mono/managed_callable.cpp b/modules/mono/managed_callable.cpp
index dfd78a8244..26347e9162 100644
--- a/modules/mono/managed_callable.cpp
+++ b/modules/mono/managed_callable.cpp
@@ -82,6 +82,7 @@ CallableCustom::CompareLessFunc ManagedCallable::get_compare_less_func() const {
}
ObjectID ManagedCallable::get_object() const {
+ // TODO: If the delegate target extends Godot.Object, use that instead!
return CSharpLanguage::get_singleton()->get_managed_callable_middleman()->get_instance_id();
}
diff --git a/modules/mono/mono_gc_handle.cpp b/modules/mono/mono_gc_handle.cpp
index e362d5affb..16a6875406 100644
--- a/modules/mono/mono_gc_handle.cpp
+++ b/modules/mono/mono_gc_handle.cpp
@@ -56,11 +56,9 @@ MonoGCHandleData MonoGCHandleData::new_weak_handle(MonoObject *p_object) {
}
Ref<MonoGCHandleRef> MonoGCHandleRef::create_strong(MonoObject *p_object) {
-
return memnew(MonoGCHandleRef(MonoGCHandleData::new_strong_handle(p_object)));
}
Ref<MonoGCHandleRef> MonoGCHandleRef::create_weak(MonoObject *p_object) {
-
return memnew(MonoGCHandleRef(MonoGCHandleData::new_weak_handle(p_object)));
}
diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h
index fbcb405b0d..13cfad4654 100644
--- a/modules/mono/mono_gc_handle.h
+++ b/modules/mono/mono_gc_handle.h
@@ -47,8 +47,8 @@ enum class GCHandleType : char {
// Manual release of the GC handle must be done when using this struct
struct MonoGCHandleData {
- uint32_t handle;
- gdmono::GCHandleType type;
+ uint32_t handle = 0;
+ gdmono::GCHandleType type = gdmono::GCHandleType::NIL;
_FORCE_INLINE_ bool is_released() const { return !handle; }
_FORCE_INLINE_ bool is_weak() const { return type == gdmono::GCHandleType::WEAK_HANDLE; }
@@ -68,10 +68,7 @@ struct MonoGCHandleData {
MonoGCHandleData(const MonoGCHandleData &) = default;
- MonoGCHandleData() :
- handle(0),
- type(gdmono::GCHandleType::NIL) {
- }
+ MonoGCHandleData() {}
MonoGCHandleData(uint32_t p_handle, gdmono::GCHandleType p_type) :
handle(p_handle),
@@ -84,7 +81,6 @@ struct MonoGCHandleData {
};
class MonoGCHandleRef : public Reference {
-
GDCLASS(MonoGCHandleRef, Reference);
MonoGCHandleData data;
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index 306a1997ab..5f518d0613 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -129,14 +129,13 @@ void gd_mono_profiler_init() {
}
}
-#if defined(DEBUG_ENABLED)
-
void gd_mono_debug_init() {
-
- mono_debug_init(MONO_DEBUG_FORMAT_MONO);
-
CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8();
+ if (da_args.length()) {
+ OS::get_singleton()->set_environment("GODOT_MONO_DEBUGGER_AGENT", String());
+ }
+
#ifdef TOOLS_ENABLED
int da_port = GLOBAL_DEF("mono/debugger_agent/port", 23685);
bool da_suspend = GLOBAL_DEF("mono/debugger_agent/wait_for_debugger", false);
@@ -159,6 +158,10 @@ void gd_mono_debug_init() {
return; // Exported games don't use the project settings to setup the debugger agent
#endif
+ // Debugging enabled
+
+ mono_debug_init(MONO_DEBUG_FORMAT_MONO);
+
// --debugger-agent=help
const char *options[] = {
"--soft-breakpoints",
@@ -167,7 +170,6 @@ void gd_mono_debug_init() {
mono_jit_parse_options(2, (char **)options);
}
-#endif // defined(DEBUG_ENABLED)
#endif // !defined(JAVASCRIPT_ENABLED)
#if defined(JAVASCRIPT_ENABLED)
@@ -175,6 +177,7 @@ MonoDomain *gd_initialize_mono_runtime() {
const char *vfs_prefix = "managed";
int enable_debugging = 0;
+ // TODO: Provide a way to enable debugging on WASM release builds.
#ifdef DEBUG_ENABLED
enable_debugging = 1;
#endif
@@ -185,9 +188,7 @@ MonoDomain *gd_initialize_mono_runtime() {
}
#else
MonoDomain *gd_initialize_mono_runtime() {
-#ifdef DEBUG_ENABLED
gd_mono_debug_init();
-#endif
#if defined(IPHONE_ENABLED) || defined(ANDROID_ENABLED)
// I don't know whether this actually matters or not
@@ -249,7 +250,6 @@ void GDMono::add_mono_shared_libs_dir_to_path() {
}
void GDMono::determine_mono_dirs(String &r_assembly_rootdir, String &r_config_dir) {
-
String bundled_assembly_rootdir = GodotSharpDirs::get_data_mono_lib_dir();
String bundled_config_dir = GodotSharpDirs::get_data_mono_etc_dir();
@@ -312,7 +312,6 @@ void GDMono::determine_mono_dirs(String &r_assembly_rootdir, String &r_config_di
}
void GDMono::initialize() {
-
ERR_FAIL_NULL(Engine::get_singleton());
print_verbose("Mono: Initializing module...");
@@ -411,7 +410,6 @@ void GDMono::initialize() {
}
void GDMono::initialize_load_assemblies() {
-
#ifndef MONO_GLUE_ENABLED
CRASH_NOW_MSG("Mono: This binary was built with 'mono_glue=no'; cannot load assemblies.");
#endif
@@ -426,6 +424,9 @@ void GDMono::initialize_load_assemblies() {
CRASH_COND_MSG(!tool_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies.");
#endif
+ if (Main::is_project_manager())
+ return;
+
// Load the project's main assembly. This doesn't necessarily need to succeed.
// The game may not be using .NET at all, or if the project does use .NET and
// we're running in the editor, it may just happen to be it wasn't built yet.
@@ -469,6 +470,7 @@ uint64_t get_editor_api_hash() {
uint32_t get_bindings_version() {
GD_UNREACHABLE();
}
+
uint32_t get_cs_glue_version() {
GD_UNREACHABLE();
}
@@ -511,14 +513,12 @@ void GDMono::_init_exception_policy() {
}
void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) {
-
assemblies[p_domain_id][p_assembly->get_name()] = p_assembly;
}
GDMonoAssembly *GDMono::get_loaded_assembly(const String &p_name) {
-
- if (p_name == "mscorlib")
- return get_corlib_assembly();
+ if (p_name == "mscorlib" && corlib_assembly)
+ return corlib_assembly;
MonoDomain *domain = mono_domain_get();
uint32_t domain_id = domain ? mono_domain_get_id(domain) : 0;
@@ -527,8 +527,9 @@ GDMonoAssembly *GDMono::get_loaded_assembly(const String &p_name) {
}
bool GDMono::load_assembly(const String &p_name, GDMonoAssembly **r_assembly, bool p_refonly) {
-
+#ifdef DEBUG_ENABLED
CRASH_COND(!r_assembly);
+#endif
MonoAssemblyName *aname = mono_assembly_name_new(p_name.utf8());
bool result = load_assembly(p_name, aname, r_assembly, p_refonly);
@@ -539,27 +540,26 @@ bool GDMono::load_assembly(const String &p_name, GDMonoAssembly **r_assembly, bo
}
bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly) {
+#ifdef DEBUG_ENABLED
+ CRASH_COND(!r_assembly);
+#endif
+
+ return load_assembly(p_name, p_aname, r_assembly, p_refonly, GDMonoAssembly::get_default_search_dirs());
+}
+bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly, const Vector<String> &p_search_dirs) {
+#ifdef DEBUG_ENABLED
CRASH_COND(!r_assembly);
+#endif
print_verbose("Mono: Loading assembly " + p_name + (p_refonly ? " (refonly)" : "") + "...");
- MonoImageOpenStatus status = MONO_IMAGE_OK;
- MonoAssembly *assembly = mono_assembly_load_full(p_aname, nullptr, &status, p_refonly);
+ GDMonoAssembly *assembly = GDMonoAssembly::load(p_name, p_aname, p_refonly, p_search_dirs);
if (!assembly)
return false;
- ERR_FAIL_COND_V(status != MONO_IMAGE_OK, false);
-
- uint32_t domain_id = mono_domain_get_id(mono_domain_get());
-
- GDMonoAssembly **stored_assembly = assemblies[domain_id].getptr(p_name);
-
- ERR_FAIL_COND_V(stored_assembly == nullptr, false);
- ERR_FAIL_COND_V((*stored_assembly)->get_assembly() != assembly, false);
-
- *r_assembly = *stored_assembly;
+ *r_assembly = assembly;
print_verbose("Mono: Assembly " + p_name + (p_refonly ? " (refonly)" : "") + " loaded from path: " + (*r_assembly)->get_path());
@@ -567,7 +567,6 @@ bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMo
}
bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMonoAssembly **r_assembly, bool p_refonly) {
-
CRASH_COND(!r_assembly);
print_verbose("Mono: Loading assembly " + p_name + (p_refonly ? " (refonly)" : "") + "...");
@@ -615,7 +614,6 @@ String ApiAssemblyInfo::to_string(ApiAssemblyInfo::Type p_type) {
}
bool GDMono::_load_corlib_assembly() {
-
if (corlib_assembly)
return true;
@@ -629,7 +627,6 @@ bool GDMono::_load_corlib_assembly() {
#ifdef TOOLS_ENABLED
bool GDMono::copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const String &p_config) {
-
String src_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config);
String dst_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config);
@@ -700,7 +697,6 @@ static bool try_get_cached_api_hash_for(const String &p_api_assemblies_dir, bool
}
static void create_cached_api_hash_for(const String &p_api_assemblies_dir) {
-
String core_api_assembly_path = p_api_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll");
String editor_api_assembly_path = p_api_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll");
String cached_api_hash_path = p_api_assemblies_dir.plus_file("api_hash_cache.cfg");
@@ -743,7 +739,6 @@ bool GDMono::_temp_domain_load_are_assemblies_out_of_sync(const String &p_config
}
String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const bool *p_core_api_out_of_sync, const bool *p_editor_api_out_of_sync) {
-
#define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \
( \
(m_out_of_sync ? \
@@ -800,7 +795,6 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const
#endif
bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) {
-
if (r_loaded_api_assembly.assembly)
return true;
@@ -834,7 +828,6 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c
#ifdef TOOLS_ENABLED
bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) {
-
if (r_loaded_api_assembly.assembly)
return true;
@@ -911,7 +904,6 @@ bool GDMono::_try_load_api_assemblies_preset() {
}
void GDMono::_load_api_assemblies() {
-
bool api_assemblies_loaded = _try_load_api_assemblies_preset();
#if defined(TOOLS_ENABLED) && !defined(GD_MONO_SINGLE_APPDOMAIN)
@@ -964,7 +956,6 @@ void GDMono::_load_api_assemblies() {
#ifdef TOOLS_ENABLED
bool GDMono::_load_tools_assemblies() {
-
if (tools_assembly && tools_project_editor_assembly)
return true;
@@ -976,7 +967,6 @@ bool GDMono::_load_tools_assemblies() {
#endif
bool GDMono::_load_project_assembly() {
-
if (project_assembly)
return true;
@@ -996,7 +986,6 @@ bool GDMono::_load_project_assembly() {
}
void GDMono::_install_trace_listener() {
-
#ifdef DEBUG_ENABLED
// Install the trace listener now before the project assembly is loaded
GDMonoClass *debug_utils = get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, "DebuggingUtils");
@@ -1013,7 +1002,6 @@ void GDMono::_install_trace_listener() {
#ifndef GD_MONO_SINGLE_APPDOMAIN
Error GDMono::_load_scripts_domain() {
-
ERR_FAIL_COND_V(scripts_domain != nullptr, ERR_BUG);
print_verbose("Mono: Loading scripts domain...");
@@ -1028,7 +1016,6 @@ Error GDMono::_load_scripts_domain() {
}
Error GDMono::_unload_scripts_domain() {
-
ERR_FAIL_NULL_V(scripts_domain, ERR_BUG);
print_verbose("Mono: Finalizing scripts domain...");
@@ -1081,7 +1068,6 @@ Error GDMono::_unload_scripts_domain() {
#ifdef GD_MONO_HOT_RELOAD
Error GDMono::reload_scripts_domain() {
-
ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG);
if (scripts_domain) {
@@ -1118,7 +1104,6 @@ Error GDMono::reload_scripts_domain() {
#ifndef GD_MONO_SINGLE_APPDOMAIN
Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
-
CRASH_COND(p_domain == nullptr);
CRASH_COND(p_domain == GDMono::get_singleton()->get_scripts_domain()); // Should use _unload_scripts_domain() instead
@@ -1151,7 +1136,6 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) {
#endif
GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
-
MonoImage *image = mono_class_get_image(p_raw_class);
if (image == corlib_assembly->get_image())
@@ -1175,7 +1159,6 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) {
}
GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &p_name) {
-
GDMonoClass *klass = corlib_assembly->get_class(p_namespace, p_name);
if (klass)
return klass;
@@ -1195,7 +1178,6 @@ GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &
}
void GDMono::_domain_assemblies_cleanup(uint32_t p_domain_id) {
-
HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[p_domain_id];
const String *k = nullptr;
@@ -1207,7 +1189,6 @@ void GDMono::_domain_assemblies_cleanup(uint32_t p_domain_id) {
}
void GDMono::unhandled_exception_hook(MonoObject *p_exc, void *) {
-
// This method will be called by the runtime when a thrown exception is not handled.
// It won't be called when we manually treat a thrown exception as unhandled.
// We assume the exception was already printed before calling this hook.
@@ -1224,7 +1205,6 @@ void GDMono::unhandled_exception_hook(MonoObject *p_exc, void *) {
}
GDMono::GDMono() {
-
singleton = this;
gdmono_log = memnew(GDMonoLog);
@@ -1251,7 +1231,6 @@ GDMono::GDMono() {
}
GDMono::~GDMono() {
-
if (is_runtime_initialized()) {
#ifndef GD_MONO_SINGLE_APPDOMAIN
if (scripts_domain) {
@@ -1325,51 +1304,42 @@ GDMono::~GDMono() {
_GodotSharp *_GodotSharp::singleton = nullptr;
void _GodotSharp::attach_thread() {
-
GDMonoUtils::attach_current_thread();
}
void _GodotSharp::detach_thread() {
-
GDMonoUtils::detach_current_thread();
}
int32_t _GodotSharp::get_domain_id() {
-
MonoDomain *domain = mono_domain_get();
CRASH_COND(!domain); // User must check if runtime is initialized before calling this method
return mono_domain_get_id(domain);
}
int32_t _GodotSharp::get_scripts_domain_id() {
-
MonoDomain *domain = GDMono::get_singleton()->get_scripts_domain();
CRASH_COND(!domain); // User must check if scripts domain is loaded before calling this method
return mono_domain_get_id(domain);
}
bool _GodotSharp::is_scripts_domain_loaded() {
-
return GDMono::get_singleton()->is_runtime_initialized() && GDMono::get_singleton()->get_scripts_domain() != nullptr;
}
bool _GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) {
-
return is_domain_finalizing_for_unload(p_domain_id);
}
bool _GodotSharp::is_domain_finalizing_for_unload() {
-
return is_domain_finalizing_for_unload(mono_domain_get());
}
bool _GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) {
-
return is_domain_finalizing_for_unload(mono_domain_get_by_id(p_domain_id));
}
bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) {
-
if (!p_domain)
return true;
if (p_domain == GDMono::get_singleton()->get_scripts_domain() && GDMono::get_singleton()->is_finalizing_scripts_domain())
@@ -1378,23 +1348,23 @@ bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) {
}
bool _GodotSharp::is_runtime_shutting_down() {
-
return mono_runtime_is_shutting_down();
}
bool _GodotSharp::is_runtime_initialized() {
-
return GDMono::get_singleton()->is_runtime_initialized();
}
void _GodotSharp::_reload_assemblies(bool p_soft_reload) {
#ifdef GD_MONO_HOT_RELOAD
- CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload);
+ // This method may be called more than once with `call_deferred`, so we need to check
+ // again if reloading is needed to avoid reloading multiple times unnecessarily.
+ if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed())
+ CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload);
#endif
}
void _GodotSharp::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("attach_thread"), &_GodotSharp::attach_thread);
ClassDB::bind_method(D_METHOD("detach_thread"), &_GodotSharp::detach_thread);
@@ -1409,11 +1379,9 @@ void _GodotSharp::_bind_methods() {
}
_GodotSharp::_GodotSharp() {
-
singleton = this;
}
_GodotSharp::~_GodotSharp() {
-
singleton = nullptr;
}
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index 4898833e8e..833855b371 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -48,9 +48,9 @@ enum Type {
};
struct Version {
- uint64_t godot_api_hash;
- uint32_t bindings_version;
- uint32_t cs_glue_version;
+ uint64_t godot_api_hash = 0;
+ uint32_t bindings_version = 0;
+ uint32_t cs_glue_version = 0;
bool operator==(const Version &p_other) const {
return godot_api_hash == p_other.godot_api_hash &&
@@ -58,11 +58,7 @@ struct Version {
cs_glue_version == p_other.cs_glue_version;
}
- Version() :
- godot_api_hash(0),
- bindings_version(0),
- cs_glue_version(0) {
- }
+ Version() {}
Version(uint64_t p_godot_api_hash,
uint32_t p_bindings_version,
@@ -79,7 +75,6 @@ String to_string(Type p_type);
} // namespace ApiAssemblyInfo
class GDMono {
-
public:
enum UnhandledExceptionPolicy {
POLICY_TERMINATE_APP,
@@ -87,13 +82,10 @@ public:
};
struct LoadedApiAssembly {
- GDMonoAssembly *assembly;
- bool out_of_sync;
+ GDMonoAssembly *assembly = nullptr;
+ bool out_of_sync = false;
- LoadedApiAssembly() :
- assembly(nullptr),
- out_of_sync(false) {
- }
+ LoadedApiAssembly() {}
};
private:
@@ -241,6 +233,7 @@ public:
bool load_assembly(const String &p_name, GDMonoAssembly **r_assembly, bool p_refonly = false);
bool load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly = false);
+ bool load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMonoAssembly **r_assembly, bool p_refonly, const Vector<String> &p_search_dirs);
bool load_assembly_from(const String &p_name, const String &p_path, GDMonoAssembly **r_assembly, bool p_refonly = false);
Error finalize_and_unload_domain(MonoDomain *p_domain);
@@ -255,7 +248,6 @@ public:
namespace gdmono {
class ScopeDomain {
-
MonoDomain *prev_domain;
public:
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index 8439769d84..073c9a5214 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -33,6 +33,7 @@
#include <mono/metadata/mono-debug.h>
#include <mono/metadata/tokentype.h>
+#include "core/io/file_access_pack.h"
#include "core/list.h"
#include "core/os/file_access.h"
#include "core/os/os.h"
@@ -45,7 +46,6 @@
Vector<String> GDMonoAssembly::search_dirs;
void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config, const String &p_custom_bcl_dir) {
-
String framework_dir;
if (!p_custom_bcl_dir.empty()) {
@@ -99,8 +99,7 @@ void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const Strin
// - The 'load' hook is called after the assembly has been loaded. Its job is to add the
// assembly to the list of loaded assemblies so that the 'search' hook can look it up.
-void GDMonoAssembly::assembly_load_hook(MonoAssembly *assembly, void *user_data) {
-
+void GDMonoAssembly::assembly_load_hook(MonoAssembly *assembly, [[maybe_unused]] void *user_data) {
String name = String::utf8(mono_assembly_name_get_name(mono_assembly_get_name(assembly)));
MonoImage *image = mono_assembly_get_image(assembly);
@@ -133,10 +132,7 @@ MonoAssembly *GDMonoAssembly::assembly_refonly_preload_hook(MonoAssemblyName *an
return GDMonoAssembly::_preload_hook(aname, assemblies_path, user_data, true);
}
-MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_data, bool refonly) {
-
- (void)user_data; // UNUSED
-
+MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, [[maybe_unused]] void *user_data, bool refonly) {
String name = String::utf8(mono_assembly_name_get_name(aname));
bool has_extension = name.ends_with(".dll") || name.ends_with(".exe");
@@ -147,16 +143,12 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, void *user_d
return nullptr;
}
-MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **, void *user_data, bool refonly) {
-
- (void)user_data; // UNUSED
-
+MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **, [[maybe_unused]] void *user_data, bool refonly) {
String name = String::utf8(mono_assembly_name_get_name(aname));
- return _load_assembly_search(name, search_dirs, refonly);
+ return _load_assembly_search(name, aname, refonly, search_dirs);
}
-MonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, const Vector<String> &p_search_dirs, bool p_refonly) {
-
+MonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs) {
MonoAssembly *res = nullptr;
String path;
@@ -168,21 +160,21 @@ MonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, const
if (has_extension) {
path = search_dir.plus_file(p_name);
if (FileAccess::exists(path)) {
- res = _real_load_assembly_from(path, p_refonly);
+ res = _real_load_assembly_from(path, p_refonly, p_aname);
if (res != nullptr)
return res;
}
} else {
path = search_dir.plus_file(p_name + ".dll");
if (FileAccess::exists(path)) {
- res = _real_load_assembly_from(path, p_refonly);
+ res = _real_load_assembly_from(path, p_refonly, p_aname);
if (res != nullptr)
return res;
}
path = search_dir.plus_file(p_name + ".exe");
if (FileAccess::exists(path)) {
- res = _real_load_assembly_from(path, p_refonly);
+ res = _real_load_assembly_from(path, p_refonly, p_aname);
if (res != nullptr)
return res;
}
@@ -193,7 +185,6 @@ MonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, const
}
String GDMonoAssembly::find_assembly(const String &p_name) {
-
String path;
bool has_extension = p_name.ends_with(".dll") || p_name.ends_with(".exe");
@@ -220,7 +211,6 @@ String GDMonoAssembly::find_assembly(const String &p_name) {
}
void GDMonoAssembly::initialize() {
-
fill_search_dirs(search_dirs);
mono_install_assembly_search_hook(&assembly_search_hook, nullptr);
@@ -230,8 +220,7 @@ void GDMonoAssembly::initialize() {
mono_install_assembly_load_hook(&assembly_load_hook, nullptr);
}
-MonoAssembly *GDMonoAssembly::_real_load_assembly_from(const String &p_path, bool p_refonly) {
-
+MonoAssembly *GDMonoAssembly::_real_load_assembly_from(const String &p_path, bool p_refonly, MonoAssemblyName *p_aname) {
Vector<uint8_t> data = FileAccess::get_file_as_array(p_path);
ERR_FAIL_COND_V_MSG(data.empty(), nullptr, "Could read the assembly in the specified location");
@@ -255,7 +244,33 @@ MonoAssembly *GDMonoAssembly::_real_load_assembly_from(const String &p_path, boo
true, &status, p_refonly,
image_filename.utf8());
- ERR_FAIL_COND_V_MSG(status != MONO_IMAGE_OK || !image, nullptr, "Failed to open assembly image from the loaded data");
+ ERR_FAIL_COND_V_MSG(status != MONO_IMAGE_OK || !image, nullptr, "Failed to open assembly image from memory: '" + p_path + "'.");
+
+ if (p_aname != nullptr) {
+ // Check assembly version
+ const MonoTableInfo *table = mono_image_get_table_info(image, MONO_TABLE_ASSEMBLY);
+
+ ERR_FAIL_NULL_V(table, nullptr);
+
+ if (mono_table_info_get_rows(table)) {
+ uint32_t cols[MONO_ASSEMBLY_SIZE];
+ mono_metadata_decode_row(table, 0, cols, MONO_ASSEMBLY_SIZE);
+
+ // Not sure about .NET's policy. We will only ensure major and minor are equal, and ignore build and revision.
+ uint16_t major = cols[MONO_ASSEMBLY_MAJOR_VERSION];
+ uint16_t minor = cols[MONO_ASSEMBLY_MINOR_VERSION];
+
+ uint16_t required_minor;
+ uint16_t required_major = mono_assembly_name_get_version(p_aname, &required_minor, nullptr, nullptr);
+
+ if (required_major != 0) {
+ if (major != required_major && minor != required_minor) {
+ mono_image_close(image);
+ return nullptr;
+ }
+ }
+ }
+ }
#ifdef DEBUG_ENABLED
Vector<uint8_t> pdb_data;
@@ -277,12 +292,25 @@ no_pdb:
#endif
+ bool need_manual_load_hook = mono_image_get_assembly(image) != nullptr; // Re-using an existing image with an assembly loaded
+
status = MONO_IMAGE_OK;
MonoAssembly *assembly = mono_assembly_load_from_full(image, image_filename.utf8().get_data(), &status, p_refonly);
ERR_FAIL_COND_V_MSG(status != MONO_IMAGE_OK || !assembly, nullptr, "Failed to load assembly for image");
+ if (need_manual_load_hook) {
+ // For some reason if an assembly survived domain reloading (maybe because it's referenced somewhere else),
+ // the mono internal search hook don't detect it, yet mono_image_open_from_data_with_name re-uses the image
+ // and assembly, and mono_assembly_load_from_full doesn't call the load hook. We need to call it manually.
+ String name = String::utf8(mono_assembly_name_get_name(mono_assembly_get_name(assembly)));
+ bool has_extension = name.ends_with(".dll") || name.ends_with(".exe");
+ GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name);
+ if (!loaded_asm)
+ assembly_load_hook(assembly, nullptr);
+ }
+
// Decrement refcount which was previously incremented by mono_image_open_from_data_with_name
mono_image_close(image);
@@ -290,7 +318,6 @@ no_pdb:
}
void GDMonoAssembly::unload() {
-
ERR_FAIL_NULL(image); // Should not be called if already unloaded
for (Map<MonoClass *, GDMonoClass *>::Element *E = cached_raw.front(); E; E = E->next()) {
@@ -309,7 +336,6 @@ String GDMonoAssembly::get_path() const {
}
GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const StringName &p_name) {
-
ERR_FAIL_NULL_V(image, nullptr);
ClassKey key(p_namespace, p_name);
@@ -333,7 +359,6 @@ GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const Stri
}
GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) {
-
ERR_FAIL_NULL_V(image, nullptr);
Map<MonoClass *, GDMonoClass *>::Element *match = cached_raw.find(p_mono_class);
@@ -353,7 +378,6 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) {
}
GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) {
-
GDMonoClass *match = nullptr;
if (gdobject_class_cache_updated) {
@@ -412,8 +436,26 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class)
return match;
}
-GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_path, bool p_refonly) {
+GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs) {
+ if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll"))
+ return GDMono::get_singleton()->get_corlib_assembly();
+
+ // We need to manually call the search hook in this case, as it won't be called in the next step
+ MonoAssembly *assembly = mono_assembly_invoke_search_hook(p_aname);
+
+ if (!assembly) {
+ assembly = _load_assembly_search(p_name, p_aname, p_refonly, p_search_dirs);
+ ERR_FAIL_NULL_V(assembly, nullptr);
+ }
+ GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(p_name);
+ ERR_FAIL_NULL_V_MSG(loaded_asm, nullptr, "Loaded assembly missing from table. Did we not receive the load hook?");
+ ERR_FAIL_COND_V(loaded_asm->get_assembly() != assembly, nullptr);
+
+ return loaded_asm;
+}
+
+GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_path, bool p_refonly) {
if (p_name == "mscorlib" || p_name == "mscorlib.dll")
return GDMono::get_singleton()->get_corlib_assembly();
@@ -434,18 +476,7 @@ GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_
return loaded_asm;
}
-GDMonoAssembly::GDMonoAssembly(const String &p_name, MonoImage *p_image, MonoAssembly *p_assembly) :
- name(p_name),
- image(p_image),
- assembly(p_assembly),
-#ifdef GD_MONO_HOT_RELOAD
- modified_time(0),
-#endif
- gdobject_class_cache_updated(false) {
-}
-
GDMonoAssembly::~GDMonoAssembly() {
-
if (image)
unload();
}
diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h
index 43c8225b74..63899dc9be 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.h
+++ b/modules/mono/mono_gd/gd_mono_assembly.h
@@ -40,7 +40,6 @@
#include "gd_mono_utils.h"
class GDMonoAssembly {
-
struct ClassKey {
struct Hasher {
static _FORCE_INLINE_ uint32_t hash(const ClassKey &p_key) {
@@ -73,10 +72,10 @@ class GDMonoAssembly {
MonoAssembly *assembly;
#ifdef GD_MONO_HOT_RELOAD
- uint64_t modified_time;
+ uint64_t modified_time = 0;
#endif
- bool gdobject_class_cache_updated;
+ bool gdobject_class_cache_updated = false;
Map<StringName, GDMonoClass *> gdobject_class_cache;
HashMap<ClassKey, GDMonoClass *, ClassKey::Hasher> cached_classes;
@@ -93,8 +92,8 @@ class GDMonoAssembly {
static MonoAssembly *_search_hook(MonoAssemblyName *aname, void *user_data, bool refonly);
static MonoAssembly *_preload_hook(MonoAssemblyName *aname, char **assemblies_path, void *user_data, bool refonly);
- static MonoAssembly *_real_load_assembly_from(const String &p_path, bool p_refonly);
- static MonoAssembly *_load_assembly_search(const String &p_name, const Vector<String> &p_search_dirs, bool p_refonly);
+ static MonoAssembly *_real_load_assembly_from(const String &p_path, bool p_refonly, MonoAssemblyName *p_aname = nullptr);
+ static MonoAssembly *_load_assembly_search(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs);
friend class GDMono;
static void initialize();
@@ -120,10 +119,16 @@ public:
static String find_assembly(const String &p_name);
static void fill_search_dirs(Vector<String> &r_search_dirs, const String &p_custom_config = String(), const String &p_custom_bcl_dir = String());
+ static const Vector<String> &get_default_search_dirs() { return search_dirs; }
+ static GDMonoAssembly *load(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs);
static GDMonoAssembly *load_from(const String &p_name, const String &p_path, bool p_refonly);
- GDMonoAssembly(const String &p_name, MonoImage *p_image, MonoAssembly *p_assembly);
+ GDMonoAssembly(const String &p_name, MonoImage *p_image, MonoAssembly *p_assembly) :
+ name(p_name),
+ image(p_image),
+ assembly(p_assembly) {
+ }
~GDMonoAssembly();
};
diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp
index facc0da780..c002ad2139 100644
--- a/modules/mono/mono_gd/gd_mono_cache.cpp
+++ b/modules/mono/mono_gd/gd_mono_cache.cpp
@@ -65,7 +65,6 @@ CachedData cached_data;
#define CACHE_METHOD_THUNK_AND_CHECK(m_class, m_method, m_val) CACHE_METHOD_THUNK_AND_CHECK_IMPL(cached_data.methodthunk_##m_class##_##m_method, m_val)
void CachedData::clear_corlib_cache() {
-
corlib_cache_updated = false;
class_MonoObject = nullptr;
@@ -84,6 +83,7 @@ void CachedData::clear_corlib_cache() {
class_IntPtr = nullptr;
class_System_Collections_IEnumerable = nullptr;
+ class_System_Collections_ICollection = nullptr;
class_System_Collections_IDictionary = nullptr;
#ifdef DEBUG_ENABLED
@@ -97,7 +97,6 @@ void CachedData::clear_corlib_cache() {
}
void CachedData::clear_godot_api_cache() {
-
godot_api_cache_updated = false;
rawclass_Dictionary = nullptr;
@@ -171,22 +170,18 @@ void CachedData::clear_godot_api_cache() {
methodthunk_MarshalUtils_TypeIsGenericArray.nullify();
methodthunk_MarshalUtils_TypeIsGenericDictionary.nullify();
+ methodthunk_MarshalUtils_TypeIsSystemGenericList.nullify();
+ methodthunk_MarshalUtils_TypeIsSystemGenericDictionary.nullify();
+ methodthunk_MarshalUtils_TypeIsGenericIEnumerable.nullify();
+ methodthunk_MarshalUtils_TypeIsGenericICollection.nullify();
+ methodthunk_MarshalUtils_TypeIsGenericIDictionary.nullify();
methodthunk_MarshalUtils_ArrayGetElementType.nullify();
methodthunk_MarshalUtils_DictionaryGetKeyValueTypes.nullify();
- methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType.nullify();
- methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType.nullify();
- methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info.nullify();
- methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info.nullify();
-
methodthunk_MarshalUtils_MakeGenericArrayType.nullify();
methodthunk_MarshalUtils_MakeGenericDictionaryType.nullify();
- methodthunk_MarshalUtils_EnumerableToArray.nullify();
- methodthunk_MarshalUtils_IDictionaryToDictionary.nullify();
- methodthunk_MarshalUtils_GenericIDictionaryToDictionary.nullify();
-
// End of MarshalUtils methods
task_scheduler_handle = Ref<MonoGCHandleRef>();
@@ -196,7 +191,6 @@ void CachedData::clear_godot_api_cache() {
#define GODOT_API_NS_CLASS(m_ns, m_class) (GDMono::get_singleton()->get_core_api_assembly()->get_class(m_ns, #m_class))
void update_corlib_cache() {
-
CACHE_CLASS_AND_CHECK(MonoObject, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_object_class()));
CACHE_CLASS_AND_CHECK(bool, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_boolean_class()));
CACHE_CLASS_AND_CHECK(int8_t, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_sbyte_class()));
@@ -213,6 +207,7 @@ void update_corlib_cache() {
CACHE_CLASS_AND_CHECK(IntPtr, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_intptr_class()));
CACHE_CLASS_AND_CHECK(System_Collections_IEnumerable, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "IEnumerable"));
+ CACHE_CLASS_AND_CHECK(System_Collections_ICollection, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "ICollection"));
CACHE_CLASS_AND_CHECK(System_Collections_IDictionary, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections", "IDictionary"));
#ifdef DEBUG_ENABLED
@@ -230,7 +225,6 @@ void update_corlib_cache() {
}
void update_godot_api_cache() {
-
CACHE_CLASS_AND_CHECK(Vector2, GODOT_API_CLASS(Vector2));
CACHE_CLASS_AND_CHECK(Vector2i, GODOT_API_CLASS(Vector2i));
CACHE_CLASS_AND_CHECK(Rect2, GODOT_API_CLASS(Rect2));
@@ -297,22 +291,18 @@ void update_godot_api_cache() {
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericArray, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericArray", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericDictionary", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsSystemGenericList, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsSystemGenericList", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsSystemGenericDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsSystemGenericDictionary", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIEnumerable, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIEnumerable", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericICollection, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericICollection", 1));
+ CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIDictionary", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, GODOT_API_CLASS(MarshalUtils)->get_method("ArrayGetElementType", 2));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, GODOT_API_CLASS(MarshalUtils)->get_method("DictionaryGetKeyValueTypes", 3));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIEnumerableIsAssignableFromType", 1));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryIsAssignableFromType", 1));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIEnumerableIsAssignableFromType", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryIsAssignableFromType", 3));
-
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericArrayType, GODOT_API_CLASS(MarshalUtils)->get_method("MakeGenericArrayType", 1));
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, MakeGenericDictionaryType, GODOT_API_CLASS(MarshalUtils)->get_method("MakeGenericDictionaryType", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, EnumerableToArray, GODOT_API_CLASS(MarshalUtils)->get_method("EnumerableToArray", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, IDictionaryToDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("IDictionaryToDictionary", 2));
- CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GenericIDictionaryToDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("GenericIDictionaryToDictionary", 2));
-
// End of MarshalUtils methods
#ifdef DEBUG_ENABLED
diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h
index 21c8ed4efe..a7bbc763a7 100644
--- a/modules/mono/mono_gd/gd_mono_cache.h
+++ b/modules/mono/mono_gd/gd_mono_cache.h
@@ -37,7 +37,6 @@
namespace GDMonoCache {
struct CachedData {
-
// -----------------------------------------------
// corlib classes
@@ -58,6 +57,7 @@ struct CachedData {
GDMonoClass *class_IntPtr; // System.IntPtr
GDMonoClass *class_System_Collections_IEnumerable;
+ GDMonoClass *class_System_Collections_ICollection;
GDMonoClass *class_System_Collections_IDictionary;
#ifdef DEBUG_ENABLED
@@ -141,22 +141,18 @@ struct CachedData {
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericArray;
GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericDictionary;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsSystemGenericList;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsSystemGenericDictionary;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIEnumerable;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericICollection;
+ GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIDictionary;
GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_ArrayGetElementType;
GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_DictionaryGetKeyValueTypes;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_GenericIEnumerableIsAssignableFromType_with_info;
- GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_GenericIDictionaryIsAssignableFromType_with_info;
-
GDMonoMethodThunkR<MonoReflectionType *, MonoReflectionType *> methodthunk_MarshalUtils_MakeGenericArrayType;
GDMonoMethodThunkR<MonoReflectionType *, MonoReflectionType *, MonoReflectionType *> methodthunk_MarshalUtils_MakeGenericDictionaryType;
- GDMonoMethodThunk<MonoObject *, Array *> methodthunk_MarshalUtils_EnumerableToArray;
- GDMonoMethodThunk<MonoObject *, Dictionary *> methodthunk_MarshalUtils_IDictionaryToDictionary;
- GDMonoMethodThunk<MonoObject *, Dictionary *> methodthunk_MarshalUtils_GenericIDictionaryToDictionary;
-
// End of MarshalUtils methods
Ref<MonoGCHandleRef> task_scheduler_handle;
@@ -186,14 +182,6 @@ inline void clear_godot_api_cache() {
cached_data.clear_godot_api_cache();
}
-_FORCE_INLINE_ bool tools_godot_api_check() {
-#ifdef TOOLS_ENABLED
- return cached_data.godot_api_cache_updated;
-#else
- return true; // Assume it's updated if this was called, otherwise it's a bug
-#endif
-}
-
} // namespace GDMonoCache
#define CACHED_CLASS(m_class) (GDMonoCache::cached_data.class_##m_class)
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index ede4203e35..691da55b10 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -31,6 +31,7 @@
#include "gd_mono_class.h"
#include <mono/metadata/attrdefs.h>
+#include <mono/metadata/debug-helpers.h>
#include "gd_mono_assembly.h"
#include "gd_mono_cache.h"
@@ -55,7 +56,11 @@ String GDMonoClass::get_full_name() const {
return get_full_name(mono_class);
}
-MonoType *GDMonoClass::get_mono_type() {
+String GDMonoClass::get_type_desc() const {
+ return GDMonoUtils::get_type_desc(get_mono_type());
+}
+
+MonoType *GDMonoClass::get_mono_type() const {
// Careful, you cannot compare two MonoType*.
// There is mono_metadata_type_equal, how is this different from comparing two MonoClass*?
return get_mono_type(mono_class);
@@ -74,19 +79,32 @@ bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const {
return mono_class_is_assignable_from(mono_class, p_from->mono_class);
}
-GDMonoClass *GDMonoClass::get_parent_class() {
+StringName GDMonoClass::get_namespace() const {
+ GDMonoClass *nesting_class = get_nesting_class();
+ if (!nesting_class)
+ return namespace_name;
+ return nesting_class->get_namespace();
+}
+
+String GDMonoClass::get_name_for_lookup() const {
+ GDMonoClass *nesting_class = get_nesting_class();
+ if (!nesting_class)
+ return class_name;
+ return nesting_class->get_name_for_lookup() + "/" + class_name;
+}
+
+GDMonoClass *GDMonoClass::get_parent_class() const {
MonoClass *parent_mono_class = mono_class_get_parent(mono_class);
return parent_mono_class ? GDMono::get_singleton()->get_class(parent_mono_class) : nullptr;
}
-GDMonoClass *GDMonoClass::get_nesting_class() {
+GDMonoClass *GDMonoClass::get_nesting_class() const {
MonoClass *nesting_type = mono_class_get_nesting_type(mono_class);
return nesting_type ? GDMono::get_singleton()->get_class(nesting_type) : nullptr;
}
#ifdef TOOLS_ENABLED
Vector<MonoClassField *> GDMonoClass::get_enum_fields() {
-
bool class_is_enum = mono_class_is_enum(mono_class);
ERR_FAIL_COND_V(!class_is_enum, Vector<MonoClassField *>());
@@ -109,7 +127,6 @@ Vector<MonoClassField *> GDMonoClass::get_enum_fields() {
#endif
bool GDMonoClass::has_attribute(GDMonoClass *p_attr_class) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_NULL_V(p_attr_class, false);
#endif
@@ -124,7 +141,6 @@ bool GDMonoClass::has_attribute(GDMonoClass *p_attr_class) {
}
MonoObject *GDMonoClass::get_attribute(GDMonoClass *p_attr_class) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_NULL_V(p_attr_class, nullptr);
#endif
@@ -139,7 +155,6 @@ MonoObject *GDMonoClass::get_attribute(GDMonoClass *p_attr_class) {
}
void GDMonoClass::fetch_attributes() {
-
ERR_FAIL_COND(attributes != nullptr);
attributes = mono_custom_attrs_from_class(get_mono_ptr());
@@ -147,7 +162,6 @@ void GDMonoClass::fetch_attributes() {
}
void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base) {
-
CRASH_COND(!CACHED_CLASS(GodotObject)->is_assignable_from(this));
if (methods_fetched)
@@ -163,7 +177,6 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
ERR_CONTINUE(!method);
if (method->get_name() != name) {
-
#ifdef DEBUG_ENABLED
String fullname = method->get_ret_type_full_name() + " " + name + "(" + method->get_signature_desc(true) + ")";
WARN_PRINT("Method '" + fullname + "' is hidden by Godot API method. Should be '" +
@@ -177,7 +190,6 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
// This allows us to warn the user here if he is using snake_case by mistake.
if (p_native_base != this) {
-
GDMonoClass *native_top = p_native_base;
while (native_top) {
GDMonoMethod *m = native_top->get_method(name, method->get_parameters_count());
@@ -241,7 +253,6 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
}
GDMonoMethod *GDMonoClass::get_fetched_method_unknown_params(const StringName &p_name) {
-
ERR_FAIL_COND_V(!methods_fetched, nullptr);
const MethodKey *k = nullptr;
@@ -255,17 +266,19 @@ GDMonoMethod *GDMonoClass::get_fetched_method_unknown_params(const StringName &p
}
bool GDMonoClass::has_fetched_method_unknown_params(const StringName &p_name) {
-
return get_fetched_method_unknown_params(p_name) != nullptr;
}
bool GDMonoClass::implements_interface(GDMonoClass *p_interface) {
-
return mono_class_implements_interface(mono_class, p_interface->get_mono_ptr());
}
-GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_count) {
+bool GDMonoClass::has_public_parameterless_ctor() {
+ GDMonoMethod *ctor = get_method(".ctor", 0);
+ return ctor && ctor->get_visibility() == IMonoClassMember::PUBLIC;
+}
+GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_count) {
MethodKey key = MethodKey(p_name, p_params_count);
GDMonoMethod **match = methods.getptr(key);
@@ -289,7 +302,6 @@ GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_cou
}
GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method) {
-
MonoMethodSignature *sig = mono_method_signature(p_raw_method);
int params_count = mono_signature_get_param_count(sig);
@@ -299,14 +311,12 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method) {
}
GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName &p_name) {
-
MonoMethodSignature *sig = mono_method_signature(p_raw_method);
int params_count = mono_signature_get_param_count(sig);
return get_method(p_raw_method, p_name, params_count);
}
GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName &p_name, int p_params_count) {
-
ERR_FAIL_NULL_V(p_raw_method, nullptr);
MethodKey key = MethodKey(p_name, p_params_count);
@@ -323,18 +333,19 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName
}
GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, bool p_include_namespace) {
-
MonoMethodDesc *desc = mono_method_desc_new(p_description.utf8().get_data(), p_include_namespace);
MonoMethod *method = mono_method_desc_search_in_class(desc, mono_class);
mono_method_desc_free(desc);
+ if (!method)
+ return nullptr;
+
ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, nullptr);
return get_method(method);
}
GDMonoField *GDMonoClass::get_field(const StringName &p_name) {
-
Map<StringName, GDMonoField *>::Element *result = fields.find(p_name);
if (result)
@@ -356,7 +367,6 @@ GDMonoField *GDMonoClass::get_field(const StringName &p_name) {
}
const Vector<GDMonoField *> &GDMonoClass::get_all_fields() {
-
if (fields_fetched)
return fields_list;
@@ -382,7 +392,6 @@ const Vector<GDMonoField *> &GDMonoClass::get_all_fields() {
}
GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) {
-
Map<StringName, GDMonoProperty *>::Element *result = properties.find(p_name);
if (result)
@@ -404,7 +413,6 @@ GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) {
}
const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() {
-
if (properties_fetched)
return properties_list;
@@ -457,7 +465,6 @@ const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() {
}
const Vector<GDMonoMethod *> &GDMonoClass::get_all_methods() {
-
if (!method_list_fetched) {
void *iter = nullptr;
MonoMethod *raw_method = nullptr;
@@ -472,7 +479,6 @@ const Vector<GDMonoMethod *> &GDMonoClass::get_all_methods() {
}
GDMonoClass::GDMonoClass(const StringName &p_namespace, const StringName &p_name, MonoClass *p_class, GDMonoAssembly *p_assembly) {
-
namespace_name = p_namespace;
class_name = p_name;
mono_class = p_class;
@@ -489,7 +495,6 @@ GDMonoClass::GDMonoClass(const StringName &p_namespace, const StringName &p_name
}
GDMonoClass::~GDMonoClass() {
-
if (attributes) {
mono_custom_attrs_free(attributes);
}
diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h
index 0c9a8cdafe..44b146b87c 100644
--- a/modules/mono/mono_gd/gd_mono_class.h
+++ b/modules/mono/mono_gd/gd_mono_class.h
@@ -31,8 +31,6 @@
#ifndef GD_MONO_CLASS_H
#define GD_MONO_CLASS_H
-#include <mono/metadata/debug-helpers.h>
-
#include "core/map.h"
#include "core/ustring.h"
@@ -107,21 +105,23 @@ public:
static MonoType *get_mono_type(MonoClass *p_mono_class);
String get_full_name() const;
- MonoType *get_mono_type();
+ String get_type_desc() const;
+ MonoType *get_mono_type() const;
uint32_t get_flags() const;
bool is_static() const;
bool is_assignable_from(GDMonoClass *p_from) const;
- _FORCE_INLINE_ StringName get_namespace() const { return namespace_name; }
+ StringName get_namespace() const;
_FORCE_INLINE_ StringName get_name() const { return class_name; }
+ String get_name_for_lookup() const;
_FORCE_INLINE_ MonoClass *get_mono_ptr() const { return mono_class; }
_FORCE_INLINE_ const GDMonoAssembly *get_assembly() const { return assembly; }
- GDMonoClass *get_parent_class();
- GDMonoClass *get_nesting_class();
+ GDMonoClass *get_parent_class() const;
+ GDMonoClass *get_nesting_class() const;
#ifdef TOOLS_ENABLED
Vector<MonoClassField *> get_enum_fields();
@@ -137,6 +137,7 @@ public:
void fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base);
bool implements_interface(GDMonoClass *p_interface);
+ bool has_public_parameterless_ctor();
GDMonoMethod *get_method(const StringName &p_name, int p_params_count = 0);
GDMonoMethod *get_method(MonoMethod *p_raw_method);
diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp
index 3f4e5fe5ac..948170f51c 100644
--- a/modules/mono/mono_gd/gd_mono_field.cpp
+++ b/modules/mono/mono_gd/gd_mono_field.cpp
@@ -322,6 +322,13 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) {
+ MonoArray *managed = GDMonoMarshal::Array_to_mono_array(p_value.operator ::Array(), array_type_class);
+ mono_field_set_value(p_object, mono_field, managed);
+ break;
+ }
+
ERR_FAIL_MSG("Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;
@@ -353,56 +360,22 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
break;
}
- if (CACHED_CLASS(Dictionary) == type_class) {
+ // Godot.Collections.Dictionary or IDictionary
+ if (CACHED_CLASS(Dictionary) == type_class || type_class == CACHED_CLASS(System_Collections_IDictionary)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
mono_field_set_value(p_object, mono_field, managed);
break;
}
- if (CACHED_CLASS(Array) == type_class) {
+ // Godot.Collections.Array or ICollection or IEnumerable
+ if (CACHED_CLASS(Array) == type_class ||
+ type_class == CACHED_CLASS(System_Collections_ICollection) ||
+ type_class == CACHED_CLASS(System_Collections_IEnumerable)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
mono_field_set_value(p_object, mono_field, managed);
break;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- } else {
- MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array());
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
- }
-
ERR_FAIL_MSG("Attempted to set the value of a field of unmarshallable type: '" + type_class->get_name() + "'.");
} break;
@@ -528,59 +501,70 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_
case Variant::PACKED_COLOR_ARRAY: {
SET_FROM_ARRAY(PackedColorArray);
} break;
- default: break;
+ default:
+ break;
}
} break;
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), type.type_class);
mono_field_set_value(p_object, mono_field, managed);
break;
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), type.type_class);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
+ MonoReflectionType *key_reftype = nullptr;
+ MonoReflectionType *value_reftype = nullptr;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ MonoObject *managed = GDMonoMarshal::Dictionary_to_system_generic_dict(p_value.operator Dictionary(),
+ type.type_class, key_reftype, value_reftype);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), CACHED_CLASS(Dictionary));
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
+ MonoReflectionType *elem_reftype = nullptr;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ MonoObject *managed = GDMonoMarshal::Array_to_system_generic_list(p_value.operator Array(),
+ type.type_class, elem_reftype);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
+ // IDictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
+ MonoReflectionType *key_reftype;
+ MonoReflectionType *value_reftype;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype);
+
+ MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), godot_dict_class);
mono_field_set_value(p_object, mono_field, managed);
break;
}
- if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array));
- mono_field_set_value(p_object, mono_field, managed);
- break;
- } else {
- MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array());
- mono_field_set_value(p_object, mono_field, managed);
- break;
- }
+ // ICollection<T> or IEnumerable<T>
+ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
+ MonoReflectionType *elem_reftype;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype);
+
+ MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), godot_array_class);
+ mono_field_set_value(p_object, mono_field, managed);
+ break;
}
} break;
diff --git a/modules/mono/mono_gd/gd_mono_field.h b/modules/mono/mono_gd/gd_mono_field.h
index 61f2c8f071..5b40b439f9 100644
--- a/modules/mono/mono_gd/gd_mono_field.h
+++ b/modules/mono/mono_gd/gd_mono_field.h
@@ -36,7 +36,6 @@
#include "i_mono_class_member.h"
class GDMonoField : public IMonoClassMember {
-
GDMonoClass *owner;
MonoClassField *mono_field;
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index 1898785699..27e402d777 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -45,7 +45,6 @@
namespace GDMonoInternals {
void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
-
// This method should not fail
CRASH_COND(!unmanaged);
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index ca16c2b76a..04728be725 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -51,7 +51,6 @@ GDMonoLog *GDMonoLog::singleton = nullptr;
#ifdef GD_MONO_LOG_ENABLED
static int get_log_level_id(const char *p_log_level) {
-
const char *valid_log_levels[] = { "error", "critical", "warning", "message", "info", "debug", nullptr };
int i = 0;
@@ -65,7 +64,6 @@ static int get_log_level_id(const char *p_log_level) {
}
void GDMonoLog::mono_log_callback(const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *) {
-
FileAccess *f = GDMonoLog::get_singleton()->log_file;
if (GDMonoLog::get_singleton()->log_level_id >= get_log_level_id(log_level)) {
@@ -94,7 +92,6 @@ void GDMonoLog::mono_log_callback(const char *log_domain, const char *log_level,
}
bool GDMonoLog::_try_create_logs_dir(const String &p_logs_dir) {
-
if (!DirAccess::exists(p_logs_dir)) {
DirAccessRef diraccess = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
ERR_FAIL_COND_V(!diraccess, false);
@@ -106,7 +103,6 @@ bool GDMonoLog::_try_create_logs_dir(const String &p_logs_dir) {
}
void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) {
-
static const uint64_t MAX_SECS = 5 * 86400; // 5 days
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
@@ -135,7 +131,6 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) {
}
void GDMonoLog::initialize() {
-
CharString log_level = OS::get_singleton()->get_environment("GODOT_MONO_LOG_LEVEL").utf8();
if (log_level.length() != 0 && get_log_level_id(log_level.get_data()) == -1) {
@@ -175,7 +170,7 @@ void GDMonoLog::initialize() {
log_level_id = get_log_level_id(log_level.get_data());
if (log_file) {
- OS::get_singleton()->print("Mono: Logfile is: %s\n", log_file_path.utf8().get_data());
+ OS::get_singleton()->print("Mono: Log file is: '%s'\n", log_file_path.utf8().get_data());
mono_trace_set_log_handler(mono_log_callback, this);
} else {
OS::get_singleton()->printerr("Mono: No log file, using default log handler\n");
@@ -183,14 +178,12 @@ void GDMonoLog::initialize() {
}
GDMonoLog::GDMonoLog() {
-
singleton = this;
log_level_id = -1;
}
GDMonoLog::~GDMonoLog() {
-
singleton = nullptr;
if (log_file) {
@@ -207,12 +200,10 @@ void GDMonoLog::initialize() {
}
GDMonoLog::GDMonoLog() {
-
singleton = this;
}
GDMonoLog::~GDMonoLog() {
-
singleton = nullptr;
}
diff --git a/modules/mono/mono_gd/gd_mono_log.h b/modules/mono/mono_gd/gd_mono_log.h
index 1fc21f7df5..3a52316060 100644
--- a/modules/mono/mono_gd/gd_mono_log.h
+++ b/modules/mono/mono_gd/gd_mono_log.h
@@ -45,7 +45,6 @@
#endif
class GDMonoLog {
-
#ifdef GD_MONO_LOG_ENABLED
int log_level_id;
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index 1878038f44..085062261d 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -154,6 +154,10 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
if (array_type->eklass == CACHED_CLASS_RAW(Color))
return Variant::PACKED_COLOR_ARRAY;
+
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ return Variant::ARRAY;
} break;
case MONO_TYPE_CLASS: {
@@ -184,23 +188,14 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
return Variant::ARRAY;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
- return Variant::DICTIONARY;
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
+ // IDictionary
+ if (p_type.type_class == CACHED_CLASS(System_Collections_IDictionary)) {
return Variant::DICTIONARY;
}
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
- return Variant::ARRAY;
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
+ // ICollection or IEnumerable
+ if (p_type.type_class == CACHED_CLASS(System_Collections_ICollection) ||
+ p_type.type_class == CACHED_CLASS(System_Collections_IEnumerable)) {
return Variant::ARRAY;
}
} break;
@@ -214,27 +209,33 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
return Variant::DICTIONARY;
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
return Variant::ARRAY;
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype))
- return Variant::DICTIONARY;
-
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
return Variant::DICTIONARY;
}
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype))
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
return Variant::ARRAY;
+ }
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
+ // IDictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
+ return Variant::DICTIONARY;
+ }
+
+ // ICollection<T> or IEnumerable<T>
+ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
return Variant::ARRAY;
}
} break;
@@ -252,10 +253,20 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_
bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type) {
switch (p_array_type.type_encoding) {
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_SZARRAY: {
+ MonoArrayType *array_type = mono_type_get_array_type(p_array_type.type_class->get_mono_type());
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ r_elem_type = ManagedType::from_class(array_type_class);
+ return true;
+ } break;
case MONO_TYPE_GENERICINST: {
MonoReflectionType *array_reftype = mono_type_get_object(mono_domain_get(), p_array_type.type_class->get_mono_type());
- if (GDMonoUtils::Marshal::type_is_generic_array(array_reftype)) {
+ if (GDMonoUtils::Marshal::type_is_generic_array(array_reftype) ||
+ GDMonoUtils::Marshal::type_is_system_generic_list(array_reftype) ||
+ GDMonoUtils::Marshal::type_is_generic_icollection(array_reftype) ||
+ GDMonoUtils::Marshal::type_is_generic_ienumerable(array_reftype)) {
MonoReflectionType *elem_reftype;
GDMonoUtils::Marshal::array_get_element_type(array_reftype, &elem_reftype);
@@ -263,12 +274,6 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_
r_elem_type = ManagedType::from_reftype(elem_reftype);
return true;
}
-
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(array_reftype, &elem_reftype)) {
- r_elem_type = ManagedType::from_reftype(elem_reftype);
- return true;
- }
} break;
default: {
} break;
@@ -282,7 +287,9 @@ bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, Ma
case MONO_TYPE_GENERICINST: {
MonoReflectionType *dict_reftype = mono_type_get_object(mono_domain_get(), p_dictionary_type.type_class->get_mono_type());
- if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype)) {
+ if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype) ||
+ GDMonoUtils::Marshal::type_is_system_generic_dictionary(dict_reftype) ||
+ GDMonoUtils::Marshal::type_is_generic_idictionary(dict_reftype)) {
MonoReflectionType *key_reftype;
MonoReflectionType *value_reftype;
@@ -292,13 +299,6 @@ bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, Ma
r_value_type = ManagedType::from_reftype(value_reftype);
return true;
}
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(dict_reftype, &key_reftype, &value_reftype)) {
- r_key_type = ManagedType::from_reftype(key_reftype);
- r_value_type = ManagedType::from_reftype(value_reftype);
- return true;
- }
} break;
default: {
} break;
@@ -577,6 +577,10 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
if (array_type->eklass == CACHED_CLASS_RAW(Color))
return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray());
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class);
+
ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type.");
} break;
@@ -600,41 +604,17 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
return GDMonoUtils::create_managed_from(p_var->operator RID());
}
- if (CACHED_CLASS(Dictionary) == type_class) {
+ // Godot.Collections.Dictionary or IDictionary
+ if (CACHED_CLASS(Dictionary) == type_class || CACHED_CLASS(System_Collections_IDictionary) == type_class) {
return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
}
- if (CACHED_CLASS(Array) == type_class) {
+ // Godot.Collections.Array or ICollection or IEnumerable
+ if (CACHED_CLASS(Array) == type_class ||
+ CACHED_CLASS(System_Collections_ICollection) == type_class ||
+ CACHED_CLASS(System_Collections_IEnumerable) == type_class) {
return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
}
-
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
- }
-
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
- } else {
- return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array());
- }
- }
} break;
case MONO_TYPE_OBJECT: {
// Variant
@@ -755,38 +735,48 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), p_type.type_class);
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
return GDMonoUtils::create_managed_from(p_var->operator Array(), p_type.type_class);
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *key_reftype, *value_reftype;
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(),
- GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype));
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
+ MonoReflectionType *key_reftype = nullptr;
+ MonoReflectionType *value_reftype = nullptr;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ return Dictionary_to_system_generic_dict(p_var->operator Dictionary(), p_type.type_class, key_reftype, value_reftype);
}
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), CACHED_CLASS(Dictionary));
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
+ MonoReflectionType *elem_reftype = nullptr;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ return Array_to_system_generic_list(p_var->operator Array(), p_type.type_class, elem_reftype);
}
- MonoReflectionType *elem_reftype;
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype, &elem_reftype)) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(),
- GDMonoUtils::Marshal::make_generic_array_type(elem_reftype));
+ // IDictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_generic_idictionary(reftype)) {
+ MonoReflectionType *key_reftype;
+ MonoReflectionType *value_reftype;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(key_reftype, value_reftype);
+
+ return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), godot_dict_class);
}
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- if (GDMonoCache::tools_godot_api_check()) {
- return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array));
- } else {
- return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array());
- }
+ // ICollection<T> or IEnumerable<T>
+ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) {
+ MonoReflectionType *elem_reftype;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(elem_reftype);
+
+ return GDMonoUtils::create_managed_from(p_var->operator Array(), godot_array_class);
}
} break;
} break;
@@ -797,7 +787,6 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
}
Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type, bool p_fail_with_err = true) {
-
ERR_FAIL_COND_V(!p_type.type_class, Variant());
switch (p_type.type_encoding) {
@@ -922,6 +911,10 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
if (array_type->eklass == CACHED_CLASS_RAW(Color))
return mono_array_to_PackedColorArray((MonoArray *)p_obj);
+ GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass);
+ if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class))
+ return mono_array_to_Array((MonoArray *)p_obj);
+
if (p_fail_with_err) {
ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant.");
} else {
@@ -957,44 +950,27 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return ptr ? Variant(*ptr) : Variant();
}
- if (CACHED_CLASS(Array) == type_class) {
+ // Godot.Collections.Dictionary
+ if (CACHED_CLASS(Dictionary) == type_class) {
MonoException *exc = nullptr;
- Array *ptr = CACHED_METHOD_THUNK(Array, GetPtr).invoke(p_obj, &exc);
+ Dictionary *ptr = CACHED_METHOD_THUNK(Dictionary, GetPtr).invoke(p_obj, &exc);
UNHANDLED_EXCEPTION(exc);
return ptr ? Variant(*ptr) : Variant();
}
- if (CACHED_CLASS(Dictionary) == type_class) {
+ // Godot.Collections.Array
+ if (CACHED_CLASS(Array) == type_class) {
MonoException *exc = nullptr;
- Dictionary *ptr = CACHED_METHOD_THUNK(Dictionary, GetPtr).invoke(p_obj, &exc);
+ Array *ptr = CACHED_METHOD_THUNK(Array, GetPtr).invoke(p_obj, &exc);
UNHANDLED_EXCEPTION(exc);
return ptr ? Variant(*ptr) : Variant();
}
-
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type());
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj);
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj);
- }
-
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
- }
-
- if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
- }
} break;
case MONO_TYPE_GENERICINST: {
MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type());
+ // Godot.Collections.Dictionary<TKey, TValue>
if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) {
MonoException *exc = nullptr;
MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc);
@@ -1002,6 +978,7 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return *unbox<Dictionary *>(ret);
}
+ // Godot.Collections.Array<T>
if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) {
MonoException *exc = nullptr;
MonoObject *ret = p_type.type_class->get_method("GetPtr")->invoke(p_obj, &exc);
@@ -1009,22 +986,19 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type
return *unbox<Array *>(ret);
}
- // The order in which we check the following interfaces is very important (dictionaries and generics first)
-
- if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj);
- }
-
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IDictionary))) {
- return GDMonoUtils::Marshal::idictionary_to_dictionary(p_obj);
- }
-
- if (GDMonoUtils::Marshal::generic_ienumerable_is_assignable_from(reftype)) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
+ // System.Collections.Generic.Dictionary<TKey, TValue>
+ if (GDMonoUtils::Marshal::type_is_system_generic_dictionary(reftype)) {
+ MonoReflectionType *key_reftype = nullptr;
+ MonoReflectionType *value_reftype = nullptr;
+ GDMonoUtils::Marshal::dictionary_get_key_value_types(reftype, &key_reftype, &value_reftype);
+ return system_generic_dict_to_Dictionary(p_obj, p_type.type_class, key_reftype, value_reftype);
}
- if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) {
- return GDMonoUtils::Marshal::enumerable_to_array(p_obj);
+ // System.Collections.Generic.List<T>
+ if (GDMonoUtils::Marshal::type_is_system_generic_list(reftype)) {
+ MonoReflectionType *elem_reftype = nullptr;
+ GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype);
+ return system_generic_list_to_Array(p_obj, p_type.type_class, elem_reftype);
}
} break;
}
@@ -1081,6 +1055,80 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) {
}
}
+MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) {
+ String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) +
+ ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)";
+ GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true);
+ CRASH_COND(ctor == nullptr);
+
+ MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr());
+ ERR_FAIL_NULL_V(mono_object, nullptr);
+
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype);
+ MonoObject *godot_dict = GDMonoUtils::create_managed_from(p_dict, godot_dict_class);
+
+ void *ctor_args[1] = { godot_dict };
+
+ MonoException *exc = nullptr;
+ ctor->invoke_raw(mono_object, ctor_args, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return mono_object;
+}
+
+Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, [[maybe_unused]] GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) {
+ GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype);
+ String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) +
+ ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)";
+ GDMonoMethod *godot_dict_ctor = godot_dict_class->get_method_with_desc(ctor_desc, true);
+ CRASH_COND(godot_dict_ctor == nullptr);
+
+ MonoObject *godot_dict = mono_object_new(mono_domain_get(), godot_dict_class->get_mono_ptr());
+ ERR_FAIL_NULL_V(godot_dict, Dictionary());
+
+ void *ctor_args[1] = { p_obj };
+
+ MonoException *exc = nullptr;
+ godot_dict_ctor->invoke_raw(godot_dict, ctor_args, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ exc = nullptr;
+ MonoObject *ret = godot_dict_class->get_method("GetPtr")->invoke(godot_dict, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return *unbox<Dictionary *>(ret);
+}
+
+MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype) {
+ GDMonoClass *elem_class = ManagedType::from_reftype(p_elem_reftype).type_class;
+
+ String ctor_desc = ":.ctor(System.Collections.Generic.IEnumerable`1<" + elem_class->get_type_desc() + ">)";
+ GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true);
+ CRASH_COND(ctor == nullptr);
+
+ MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr());
+ ERR_FAIL_NULL_V(mono_object, nullptr);
+
+ void *ctor_args[1] = { Array_to_mono_array(p_array, elem_class) };
+
+ MonoException *exc = nullptr;
+ ctor->invoke_raw(mono_object, ctor_args, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return mono_object;
+}
+
+Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, [[maybe_unused]] MonoReflectionType *p_elem_reftype) {
+ GDMonoMethod *to_array = p_class->get_method("ToArray", 0);
+ CRASH_COND(to_array == nullptr);
+
+ MonoException *exc = nullptr;
+ MonoArray *mono_array = (MonoArray *)to_array->invoke_raw(p_obj, nullptr, &exc);
+ UNHANDLED_EXCEPTION(exc);
+
+ return mono_array_to_Array(mono_array);
+}
+
MonoArray *Array_to_mono_array(const Array &p_array) {
int length = p_array.size();
MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), length);
@@ -1093,6 +1141,18 @@ MonoArray *Array_to_mono_array(const Array &p_array) {
return ret;
}
+MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class) {
+ int length = p_array.size();
+ MonoArray *ret = mono_array_new(mono_domain_get(), p_array_type_class->get_mono_ptr(), length);
+
+ for (int i = 0; i < length; i++) {
+ MonoObject *boxed = variant_to_mono_object(p_array[i]);
+ mono_array_setref(ret, i, boxed);
+ }
+
+ return ret;
+}
+
Array mono_array_to_Array(MonoArray *p_array) {
Array ret;
if (!p_array)
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index 8b405291a7..f2d887e6d6 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -123,9 +123,18 @@ Variant mono_object_to_variant_no_err(MonoObject *p_obj, const ManagedType &p_ty
/// If the MonoObject* cannot be converted to Variant, then 'ToString()' is called instead.
String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc);
+// System.Collections.Generic
+
+MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
+Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
+
+MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
+Array system_generic_list_to_Array(MonoObject *p_obj, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype);
+
// Array
MonoArray *Array_to_mono_array(const Array &p_array);
+MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_class);
Array mono_array_to_Array(MonoArray *p_array);
// PackedInt32Array
diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp
index c8cc5247c6..e601bb12ad 100644
--- a/modules/mono/mono_gd/gd_mono_method.cpp
+++ b/modules/mono/mono_gd/gd_mono_method.cpp
@@ -30,13 +30,14 @@
#include "gd_mono_method.h"
+#include <mono/metadata/attrdefs.h>
+#include <mono/metadata/debug-helpers.h>
+
#include "gd_mono_cache.h"
#include "gd_mono_class.h"
#include "gd_mono_marshal.h"
#include "gd_mono_utils.h"
-#include <mono/metadata/attrdefs.h>
-
void GDMonoMethod::_update_signature() {
// Apparently MonoMethodSignature needs not to be freed.
// mono_method_signature caches the result, we don't need to cache it ourselves.
@@ -244,7 +245,6 @@ void GDMonoMethod::get_parameter_types(Vector<ManagedType> &types) const {
}
const MethodInfo &GDMonoMethod::get_method_info() {
-
if (!method_info_fetched) {
method_info.name = name;
diff --git a/modules/mono/mono_gd/gd_mono_method.h b/modules/mono/mono_gd/gd_mono_method.h
index 54b2eba3e8..f78f57dca0 100644
--- a/modules/mono/mono_gd/gd_mono_method.h
+++ b/modules/mono/mono_gd/gd_mono_method.h
@@ -36,7 +36,6 @@
#include "i_mono_class_member.h"
class GDMonoMethod : public IMonoClassMember {
-
StringName name;
int params_count;
diff --git a/modules/mono/mono_gd/gd_mono_method_thunk.h b/modules/mono/mono_gd/gd_mono_method_thunk.h
index 0e05e974e9..01f3ae342a 100644
--- a/modules/mono/mono_gd/gd_mono_method_thunk.h
+++ b/modules/mono/mono_gd/gd_mono_method_thunk.h
@@ -47,10 +47,9 @@
template <class... ParamTypes>
struct GDMonoMethodThunk {
-
typedef void(GD_MONO_STDCALL *M)(ParamTypes... p_args, MonoException **);
- M mono_method_thunk;
+ M mono_method_thunk = nullptr;
public:
_FORCE_INLINE_ void invoke(ParamTypes... p_args, MonoException **r_exc) {
@@ -81,9 +80,7 @@ public:
mono_method_thunk = (M)mono_method_get_unmanaged_thunk(p_mono_method->get_mono_ptr());
}
- GDMonoMethodThunk() :
- mono_method_thunk(nullptr) {
- }
+ GDMonoMethodThunk() {}
explicit GDMonoMethodThunk(GDMonoMethod *p_mono_method) {
set_from_method(p_mono_method);
@@ -92,10 +89,9 @@ public:
template <class R, class... ParamTypes>
struct GDMonoMethodThunkR {
-
typedef R(GD_MONO_STDCALL *M)(ParamTypes... p_args, MonoException **);
- M mono_method_thunk;
+ M mono_method_thunk = nullptr;
public:
_FORCE_INLINE_ R invoke(ParamTypes... p_args, MonoException **r_exc) {
@@ -127,9 +123,7 @@ public:
mono_method_thunk = (M)mono_method_get_unmanaged_thunk(p_mono_method->get_mono_ptr());
}
- GDMonoMethodThunkR() :
- mono_method_thunk(nullptr) {
- }
+ GDMonoMethodThunkR() {}
explicit GDMonoMethodThunkR(GDMonoMethod *p_mono_method) {
#ifdef DEBUG_ENABLED
@@ -247,8 +241,7 @@ struct VariadicInvokeMonoMethodR<1, R, P1> {
template <class... ParamTypes>
struct GDMonoMethodThunk {
-
- GDMonoMethod *mono_method;
+ GDMonoMethod *mono_method = nullptr;
public:
_FORCE_INLINE_ void invoke(ParamTypes... p_args, MonoException **r_exc) {
@@ -277,9 +270,7 @@ public:
mono_method = p_mono_method;
}
- GDMonoMethodThunk() :
- mono_method(nullptr) {
- }
+ GDMonoMethodThunk() {}
explicit GDMonoMethodThunk(GDMonoMethod *p_mono_method) {
set_from_method(p_mono_method);
@@ -288,8 +279,7 @@ public:
template <class R, class... ParamTypes>
struct GDMonoMethodThunkR {
-
- GDMonoMethod *mono_method;
+ GDMonoMethod *mono_method = nullptr;
public:
_FORCE_INLINE_ R invoke(ParamTypes... p_args, MonoException **r_exc) {
@@ -318,9 +308,7 @@ public:
mono_method = p_mono_method;
}
- GDMonoMethodThunkR() :
- mono_method(nullptr) {
- }
+ GDMonoMethodThunkR() {}
explicit GDMonoMethodThunkR(GDMonoMethod *p_mono_method) {
set_from_method(p_mono_method);
diff --git a/modules/mono/mono_gd/gd_mono_property.h b/modules/mono/mono_gd/gd_mono_property.h
index 4653758a86..611ac293e4 100644
--- a/modules/mono/mono_gd/gd_mono_property.h
+++ b/modules/mono/mono_gd/gd_mono_property.h
@@ -36,7 +36,6 @@
#include "i_mono_class_member.h"
class GDMonoProperty : public IMonoClassMember {
-
GDMonoClass *owner;
MonoProperty *mono_property;
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 00119ced88..332744ae6e 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -30,6 +30,7 @@
#include "gd_mono_utils.h"
+#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/exception.h>
#include "core/debugger/engine_debugger.h"
@@ -55,7 +56,6 @@
namespace GDMonoUtils {
MonoObject *unmanaged_get_managed(Object *unmanaged) {
-
if (!unmanaged)
return nullptr;
@@ -358,6 +358,14 @@ MonoDomain *create_domain(const String &p_friendly_name) {
return domain;
}
+String get_type_desc(MonoType *p_type) {
+ return mono_type_full_name(p_type);
+}
+
+String get_type_desc(MonoReflectionType *p_reftype) {
+ return get_type_desc(mono_reflection_type_get_type(p_reftype));
+}
+
String get_exception_name_and_message(MonoException *p_exc) {
String res;
@@ -555,9 +563,10 @@ namespace Marshal {
#ifdef MONO_GLUE_ENABLED
#ifdef TOOLS_ENABLED
-#define NO_GLUE_RET(m_ret) \
- { \
- if (!GDMonoCache::cached_data.godot_api_cache_updated) return m_ret; \
+#define NO_GLUE_RET(m_ret) \
+ { \
+ if (!GDMonoCache::cached_data.godot_api_cache_updated) \
+ return m_ret; \
}
#else
#define NO_GLUE_RET(m_ret) \
@@ -584,75 +593,56 @@ bool type_is_generic_dictionary(MonoReflectionType *p_reftype) {
return (bool)res;
}
-void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) {
- MonoException *exc = nullptr;
- CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc);
- UNHANDLED_EXCEPTION(exc);
-}
-
-void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) {
- MonoException *exc = nullptr;
- CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes).invoke(p_dict_reftype, r_key_reftype, r_value_reftype, &exc);
- UNHANDLED_EXCEPTION(exc);
-}
-
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype) {
+bool type_is_system_generic_list(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
MonoException *exc = nullptr;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType).invoke(p_reftype, &exc);
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsSystemGenericList).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype) {
+bool type_is_system_generic_dictionary(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
MonoException *exc = nullptr;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType).invoke(p_reftype, &exc);
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsSystemGenericDictionary).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype) {
+bool type_is_generic_ienumerable(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
MonoException *exc = nullptr;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info).invoke(p_reftype, r_elem_reftype, &exc);
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericIEnumerable).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) {
+bool type_is_generic_icollection(MonoReflectionType *p_reftype) {
NO_GLUE_RET(false);
MonoException *exc = nullptr;
- MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info).invoke(p_reftype, r_key_reftype, r_value_reftype, &exc);
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericICollection).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
return (bool)res;
}
-Array enumerable_to_array(MonoObject *p_enumerable) {
- NO_GLUE_RET(Array());
- Array result;
+bool type_is_generic_idictionary(MonoReflectionType *p_reftype) {
+ NO_GLUE_RET(false);
MonoException *exc = nullptr;
- CACHED_METHOD_THUNK(MarshalUtils, EnumerableToArray).invoke(p_enumerable, &result, &exc);
+ MonoBoolean res = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericIDictionary).invoke(p_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
- return result;
+ return (bool)res;
}
-Dictionary idictionary_to_dictionary(MonoObject *p_idictionary) {
- NO_GLUE_RET(Dictionary());
- Dictionary result;
+void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) {
MonoException *exc = nullptr;
- CACHED_METHOD_THUNK(MarshalUtils, IDictionaryToDictionary).invoke(p_idictionary, &result, &exc);
+ CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
- return result;
}
-Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary) {
- NO_GLUE_RET(Dictionary());
- Dictionary result;
+void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) {
MonoException *exc = nullptr;
- CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryToDictionary).invoke(p_generic_idictionary, &result, &exc);
+ CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes).invoke(p_dict_reftype, r_key_reftype, r_value_reftype, &exc);
UNHANDLED_EXCEPTION(exc);
- return result;
}
GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype) {
@@ -673,8 +663,7 @@ GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, Mon
} // namespace Marshal
-ScopeThreadAttach::ScopeThreadAttach() :
- mono_thread(nullptr) {
+ScopeThreadAttach::ScopeThreadAttach() {
if (likely(GDMono::get_singleton()->is_runtime_initialized()) && unlikely(!mono_domain_get())) {
mono_thread = GDMonoUtils::attach_current_thread();
}
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index b850e1be9b..a7ca46f012 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -52,22 +52,18 @@ namespace Marshal {
bool type_is_generic_array(MonoReflectionType *p_reftype);
bool type_is_generic_dictionary(MonoReflectionType *p_reftype);
+bool type_is_system_generic_list(MonoReflectionType *p_reftype);
+bool type_is_system_generic_dictionary(MonoReflectionType *p_reftype);
+bool type_is_generic_ienumerable(MonoReflectionType *p_reftype);
+bool type_is_generic_icollection(MonoReflectionType *p_reftype);
+bool type_is_generic_idictionary(MonoReflectionType *p_reftype);
void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype);
void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype);
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype);
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype);
-bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype);
-bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype);
-
GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype);
GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype);
-Array enumerable_to_array(MonoObject *p_enumerable);
-Dictionary idictionary_to_dictionary(MonoObject *p_idictionary);
-Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary);
-
} // namespace Marshal
_FORCE_INLINE_ void hash_combine(uint32_t &p_hash, const uint32_t &p_with_hash) {
@@ -115,6 +111,9 @@ MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class);
MonoDomain *create_domain(const String &p_friendly_name);
+String get_type_desc(MonoType *p_type);
+String get_type_desc(MonoReflectionType *p_reftype);
+
String get_exception_name_and_message(MonoException *p_exc);
void set_exception_message(MonoException *p_exc, String message);
@@ -135,6 +134,7 @@ extern thread_local int current_invoke_count;
_FORCE_INLINE_ int get_runtime_invoke_count() {
return current_invoke_count;
}
+
_FORCE_INLINE_ int &get_runtime_invoke_count_ref() {
return current_invoke_count;
}
@@ -156,7 +156,7 @@ struct ScopeThreadAttach {
~ScopeThreadAttach();
private:
- MonoThread *mono_thread;
+ MonoThread *mono_thread = nullptr;
};
StringName get_native_godot_class_name(GDMonoClass *p_class);
diff --git a/modules/mono/mono_gd/managed_type.h b/modules/mono/mono_gd/managed_type.h
index 84d1837853..491a2f3d20 100644
--- a/modules/mono/mono_gd/managed_type.h
+++ b/modules/mono/mono_gd/managed_type.h
@@ -36,18 +36,15 @@
#include "gd_mono_header.h"
struct ManagedType {
- int type_encoding;
- GDMonoClass *type_class;
+ int type_encoding = 0;
+ GDMonoClass *type_class = nullptr;
static ManagedType from_class(GDMonoClass *p_class);
static ManagedType from_class(MonoClass *p_mono_class);
static ManagedType from_type(MonoType *p_mono_type);
static ManagedType from_reftype(MonoReflectionType *p_mono_reftype);
- ManagedType() :
- type_encoding(0),
- type_class(nullptr) {
- }
+ ManagedType() {}
ManagedType(int p_type_encoding, GDMonoClass *p_type_class) :
type_encoding(p_type_encoding),
diff --git a/modules/mono/mono_gd/support/android_support.cpp b/modules/mono/mono_gd/support/android_support.cpp
index 8bcdeec9dd..8bcdeec9dd 100755..100644
--- a/modules/mono/mono_gd/support/android_support.cpp
+++ b/modules/mono/mono_gd/support/android_support.cpp
diff --git a/modules/mono/mono_gd/support/ios_support.mm b/modules/mono/mono_gd/support/ios_support.mm
index e3d1a647fd..e3d1a647fd 100755..100644
--- a/modules/mono/mono_gd/support/ios_support.mm
+++ b/modules/mono/mono_gd/support/ios_support.mm
diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp
index e77a2e98f2..ed0dc5cc28 100644
--- a/modules/mono/signal_awaiter_utils.cpp
+++ b/modules/mono/signal_awaiter_utils.cpp
@@ -77,7 +77,6 @@ String SignalAwaiterCallable::get_as_text() const {
String class_name = base->get_class();
Ref<Script> script = base->get_script();
if (script.is_valid() && script->get_path().is_resource_file()) {
-
class_name += "(" + script->get_path().get_file() + ")";
}
return class_name + "::SignalAwaiterMiddleman::" + String(signal);
diff --git a/modules/mono/utils/macros.h b/modules/mono/utils/macros.h
index 8650d6cc09..dc542477f5 100644
--- a/modules/mono/utils/macros.h
+++ b/modules/mono/utils/macros.h
@@ -68,6 +68,6 @@ public:
} // namespace gdmono
#define SCOPE_EXIT \
- auto GD_UNIQUE_NAME(gd_scope_exit) = gdmono::ScopeExitAux() + [=]()
+ auto GD_UNIQUE_NAME(gd_scope_exit) = gdmono::ScopeExitAux() + [=]() -> void
#endif // UTIL_MACROS_H
diff --git a/modules/mono/utils/mono_reg_utils.cpp b/modules/mono/utils/mono_reg_utils.cpp
index 8f0ad8ba5e..1b4fe68582 100644
--- a/modules/mono/utils/mono_reg_utils.cpp
+++ b/modules/mono/utils/mono_reg_utils.cpp
@@ -58,7 +58,6 @@ REGSAM _get_bitness_sam() {
}
LONG _RegOpenKey(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult) {
-
LONG res = RegOpenKeyExW(hKey, lpSubKey, 0, KEY_READ, phkResult);
if (res != ERROR_SUCCESS)
@@ -68,7 +67,6 @@ LONG _RegOpenKey(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult) {
}
LONG _RegKeyQueryString(HKEY hKey, const String &p_value_name, String &r_value) {
-
Vector<WCHAR> buffer;
buffer.resize(512);
DWORD dwBufferSize = buffer.size();
@@ -92,7 +90,6 @@ LONG _RegKeyQueryString(HKEY hKey, const String &p_value_name, String &r_value)
}
LONG _find_mono_in_reg(const String &p_subkey, MonoRegInfo &r_info, bool p_old_reg = false) {
-
HKEY hKey;
LONG res = _RegOpenKey(HKEY_LOCAL_MACHINE, p_subkey.c_str(), &hKey);
@@ -128,7 +125,6 @@ cleanup:
}
LONG _find_mono_in_reg_old(const String &p_subkey, MonoRegInfo &r_info) {
-
String default_clr;
HKEY hKey;
@@ -150,7 +146,6 @@ cleanup:
}
MonoRegInfo find_mono() {
-
MonoRegInfo info;
if (_find_mono_in_reg("Software\\Mono", info) == ERROR_SUCCESS)
@@ -163,7 +158,6 @@ MonoRegInfo find_mono() {
}
String find_msbuild_tools_path() {
-
String msbuild_tools_path;
// Try to find 15.0 with vswhere
@@ -232,6 +226,7 @@ cleanup:
return msbuild_tools_path;
}
+
} // namespace MonoRegUtils
#endif // WINDOWS_ENABLED
diff --git a/modules/mono/utils/mono_reg_utils.h b/modules/mono/utils/mono_reg_utils.h
index f844a7233a..4ef876f2b6 100644
--- a/modules/mono/utils/mono_reg_utils.h
+++ b/modules/mono/utils/mono_reg_utils.h
@@ -36,7 +36,6 @@
#include "core/ustring.h"
struct MonoRegInfo {
-
String version;
String install_root_dir;
String assembly_dir;
diff --git a/modules/mono/utils/osx_utils.cpp b/modules/mono/utils/osx_utils.cpp
index 8fadf3c109..8e3e51e688 100644
--- a/modules/mono/utils/osx_utils.cpp
+++ b/modules/mono/utils/osx_utils.cpp
@@ -38,7 +38,6 @@
#include <CoreServices/CoreServices.h>
bool osx_is_app_bundle_installed(const String &p_bundle_id) {
-
CFURLRef app_url = nullptr;
CFStringRef bundle_id = CFStringCreateWithCString(nullptr, p_bundle_id.utf8(), kCFStringEncodingUTF8);
OSStatus result = LSFindApplicationForInfo(kLSUnknownCreator, bundle_id, nullptr, nullptr, &app_url);
diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp
index 907811355f..da1b719d99 100644
--- a/modules/mono/utils/string_utils.cpp
+++ b/modules/mono/utils/string_utils.cpp
@@ -81,6 +81,7 @@ int sfind(const String &p_text, int p_from) {
return -1;
}
+
} // namespace
String sformat(const String &p_text, const Variant &p1, const Variant &p2, const Variant &p3, const Variant &p4, const Variant &p5) {
@@ -132,7 +133,6 @@ String sformat(const String &p_text, const Variant &p1, const Variant &p2, const
#ifdef TOOLS_ENABLED
bool is_csharp_keyword(const String &p_name) {
-
// Reserved keywords
return p_name == "abstract" || p_name == "as" || p_name == "base" || p_name == "bool" ||
@@ -196,16 +196,6 @@ String str_format(const char *p_format, ...) {
return res;
}
-// va_copy was defined in the C99, but not in C++ standards before C++11.
-// When you compile C++ without --std=c++<XX> option, compilers still define
-// va_copy, otherwise you have to use the internal version (__va_copy).
-#if !defined(va_copy)
-#if defined(__GNUC__)
-#define va_copy(d, s) __va_copy((d), (s))
-#else
-#define va_copy(d, s) ((d) = (s))
-#endif
-#endif
#if defined(MINGW_ENABLED) || defined(_MSC_VER) && _MSC_VER < 1900
#define gd_vsnprintf(m_buffer, m_count, m_format, m_args_copy) vsnprintf_s(m_buffer, m_count, _TRUNCATE, m_format, m_args_copy)
diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp
index 2018f90e9f..1181e69cd3 100644
--- a/modules/opensimplex/noise_texture.cpp
+++ b/modules/opensimplex/noise_texture.cpp
@@ -59,7 +59,6 @@ NoiseTexture::~NoiseTexture() {
}
void NoiseTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_width", "width"), &NoiseTexture::set_width);
ClassDB::bind_method(D_METHOD("set_height", "height"), &NoiseTexture::set_height);
@@ -88,7 +87,6 @@ void NoiseTexture::_bind_methods() {
}
void NoiseTexture::_validate_property(PropertyInfo &property) const {
-
if (property.name == "bump_strength") {
if (!as_normalmap) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
@@ -110,7 +108,6 @@ void NoiseTexture::_set_texture_data(const Ref<Image> &p_image) {
}
void NoiseTexture::_thread_done(const Ref<Image> &p_image) {
-
_set_texture_data(p_image);
Thread::wait_to_finish(noise_thread);
memdelete(noise_thread);
@@ -127,16 +124,15 @@ void NoiseTexture::_thread_function(void *p_ud) {
}
void NoiseTexture::_queue_update() {
-
- if (update_queued)
+ if (update_queued) {
return;
+ }
update_queued = true;
call_deferred("_update_texture");
}
Ref<Image> NoiseTexture::_generate_texture() {
-
// Prevent memdelete due to unref() on other thread.
Ref<OpenSimplexNoise> ref_noise = noise;
@@ -169,7 +165,6 @@ void NoiseTexture::_update_texture() {
use_thread = false;
#endif
if (use_thread) {
-
if (!noise_thread) {
noise_thread = Thread::create(_thread_function, this);
regen_queued = false;
@@ -185,8 +180,9 @@ void NoiseTexture::_update_texture() {
}
void NoiseTexture::set_noise(Ref<OpenSimplexNoise> p_noise) {
- if (p_noise == noise)
+ if (p_noise == noise) {
return;
+ }
if (noise.is_valid()) {
noise->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &NoiseTexture::_queue_update));
}
@@ -202,19 +198,25 @@ Ref<OpenSimplexNoise> NoiseTexture::get_noise() {
}
void NoiseTexture::set_width(int p_width) {
- if (p_width == size.x) return;
+ if (p_width == size.x) {
+ return;
+ }
size.x = p_width;
_queue_update();
}
void NoiseTexture::set_height(int p_height) {
- if (p_height == size.y) return;
+ if (p_height == size.y) {
+ return;
+ }
size.y = p_height;
_queue_update();
}
void NoiseTexture::set_seamless(bool p_seamless) {
- if (p_seamless == seamless) return;
+ if (p_seamless == seamless) {
+ return;
+ }
seamless = p_seamless;
_queue_update();
}
@@ -224,7 +226,9 @@ bool NoiseTexture::get_seamless() {
}
void NoiseTexture::set_as_normalmap(bool p_as_normalmap) {
- if (p_as_normalmap == as_normalmap) return;
+ if (p_as_normalmap == as_normalmap) {
+ return;
+ }
as_normalmap = p_as_normalmap;
_queue_update();
_change_notify();
@@ -235,25 +239,24 @@ bool NoiseTexture::is_normalmap() {
}
void NoiseTexture::set_bump_strength(float p_bump_strength) {
-
- if (p_bump_strength == bump_strength) return;
+ if (p_bump_strength == bump_strength) {
+ return;
+ }
bump_strength = p_bump_strength;
- if (as_normalmap)
+ if (as_normalmap) {
_queue_update();
+ }
}
float NoiseTexture::get_bump_strength() {
-
return bump_strength;
}
int NoiseTexture::get_width() const {
-
return size.x;
}
int NoiseTexture::get_height() const {
-
return size.y;
}
@@ -266,6 +269,5 @@ RID NoiseTexture::get_rid() const {
}
Ref<Image> NoiseTexture::get_data() const {
-
return data;
}
diff --git a/modules/opensimplex/open_simplex_noise.cpp b/modules/opensimplex/open_simplex_noise.cpp
index 238faa4130..00b3d47db9 100644
--- a/modules/opensimplex/open_simplex_noise.cpp
+++ b/modules/opensimplex/open_simplex_noise.cpp
@@ -33,7 +33,6 @@
#include "core/core_string_names.h"
OpenSimplexNoise::OpenSimplexNoise() {
-
seed = 0;
persistence = 0.5;
octaves = 3;
@@ -53,9 +52,9 @@ void OpenSimplexNoise::_init_seeds() {
}
void OpenSimplexNoise::set_seed(int p_seed) {
-
- if (seed == p_seed)
+ if (seed == p_seed) {
return;
+ }
seed = p_seed;
@@ -65,12 +64,13 @@ void OpenSimplexNoise::set_seed(int p_seed) {
}
int OpenSimplexNoise::get_seed() {
-
return seed;
}
void OpenSimplexNoise::set_octaves(int p_octaves) {
- if (p_octaves == octaves) return;
+ if (p_octaves == octaves) {
+ return;
+ }
ERR_FAIL_COND_MSG(p_octaves > MAX_OCTAVES, vformat("The number of OpenSimplexNoise octaves is limited to %d; ignoring the new value.", MAX_OCTAVES));
@@ -79,25 +79,30 @@ void OpenSimplexNoise::set_octaves(int p_octaves) {
}
void OpenSimplexNoise::set_period(float p_period) {
- if (p_period == period) return;
+ if (p_period == period) {
+ return;
+ }
period = p_period;
emit_changed();
}
void OpenSimplexNoise::set_persistence(float p_persistence) {
- if (p_persistence == persistence) return;
+ if (p_persistence == persistence) {
+ return;
+ }
persistence = p_persistence;
emit_changed();
}
void OpenSimplexNoise::set_lacunarity(float p_lacunarity) {
- if (p_lacunarity == lacunarity) return;
+ if (p_lacunarity == lacunarity) {
+ return;
+ }
lacunarity = p_lacunarity;
emit_changed();
}
Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) {
-
Vector<uint8_t> data;
data.resize(p_width * p_height * 4);
@@ -120,7 +125,6 @@ Ref<Image> OpenSimplexNoise::get_image(int p_width, int p_height) {
}
Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) {
-
Vector<uint8_t> data;
data.resize(p_size * p_size * 4);
@@ -128,7 +132,6 @@ Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) {
for (int i = 0; i < p_size; i++) {
for (int j = 0; j < p_size; j++) {
-
float ii = (float)i / (float)p_size;
float jj = (float)j / (float)p_size;
@@ -157,7 +160,6 @@ Ref<Image> OpenSimplexNoise::get_seamless_image(int p_size) {
}
void OpenSimplexNoise::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_seed"), &OpenSimplexNoise::get_seed);
ClassDB::bind_method(D_METHOD("set_seed", "seed"), &OpenSimplexNoise::set_seed);
@@ -192,12 +194,10 @@ void OpenSimplexNoise::_bind_methods() {
}
float OpenSimplexNoise::get_noise_1d(float x) {
-
return get_noise_2d(x, 1.0);
}
float OpenSimplexNoise::get_noise_2d(float x, float y) {
-
x /= period;
y /= period;
@@ -218,7 +218,6 @@ float OpenSimplexNoise::get_noise_2d(float x, float y) {
}
float OpenSimplexNoise::get_noise_3d(float x, float y, float z) {
-
x /= period;
y /= period;
z /= period;
@@ -241,7 +240,6 @@ float OpenSimplexNoise::get_noise_3d(float x, float y, float z) {
}
float OpenSimplexNoise::get_noise_4d(float x, float y, float z, float w) {
-
x /= period;
y /= period;
z /= period;
diff --git a/modules/opensimplex/register_types.cpp b/modules/opensimplex/register_types.cpp
index 6fae1fe415..fef90cdce3 100644
--- a/modules/opensimplex/register_types.cpp
+++ b/modules/opensimplex/register_types.cpp
@@ -33,7 +33,6 @@
#include "open_simplex_noise.h"
void register_opensimplex_types() {
-
ClassDB::register_class<OpenSimplexNoise>();
ClassDB::register_class<NoiseTexture>();
}
diff --git a/modules/pvr/register_types.cpp b/modules/pvr/register_types.cpp
index 5f900a0256..1eb697bba3 100644
--- a/modules/pvr/register_types.cpp
+++ b/modules/pvr/register_types.cpp
@@ -35,13 +35,11 @@
static Ref<ResourceFormatPVR> resource_loader_pvr;
void register_pvr_types() {
-
resource_loader_pvr.instance();
ResourceLoader::add_resource_format_loader(resource_loader_pvr);
}
void unregister_pvr_types() {
-
ResourceLoader::remove_resource_format_loader(resource_loader_pvr);
resource_loader_pvr.unref();
}
diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp
index 10d4d71f5e..36c0913f62 100644
--- a/modules/pvr/texture_loader_pvr.cpp
+++ b/modules/pvr/texture_loader_pvr.cpp
@@ -51,22 +51,24 @@ enum PVRFLags {
};
-RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
- if (r_error)
+RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_CANT_OPEN;
+ }
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
- if (!f)
+ if (!f) {
return RES();
+ }
FileAccessRef faref(f);
ERR_FAIL_COND_V(err, RES());
- if (r_error)
+ if (r_error) {
*r_error = ERR_FILE_CORRUPT;
+ }
uint32_t hsize = f->get_32();
@@ -109,11 +111,14 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path,
Image::Format format = Image::FORMAT_MAX;
switch (flags & 0xFF) {
-
case 0x18:
- case 0xC: format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC2A : Image::FORMAT_PVRTC2; break;
+ case 0xC:
+ format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC2A : Image::FORMAT_PVRTC2;
+ break;
case 0x19:
- case 0xD: format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4; break;
+ case 0xD:
+ format = (flags & PVR_HAS_ALPHA) ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4;
+ break;
case 0x16:
format = Image::FORMAT_L8;
break;
@@ -158,29 +163,29 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path,
Ref<ImageTexture> texture = memnew(ImageTexture);
texture->create_from_image(image);
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return texture;
}
void ResourceFormatPVR::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("pvr");
}
-bool ResourceFormatPVR::handles_type(const String &p_type) const {
+bool ResourceFormatPVR::handles_type(const String &p_type) const {
return ClassDB::is_parent_class(p_type, "Texture2D");
}
-String ResourceFormatPVR::get_resource_type(const String &p_path) const {
- if (p_path.get_extension().to_lower() == "pvr")
+String ResourceFormatPVR::get_resource_type(const String &p_path) const {
+ if (p_path.get_extension().to_lower() == "pvr") {
return "Texture2D";
+ }
return "";
}
static void _compress_pvrtc4(Image *p_img) {
-
Ref<Image> img = p_img->duplicate();
bool make_mipmaps = false;
@@ -189,8 +194,9 @@ static void _compress_pvrtc4(Image *p_img) {
img->resize_to_po2(true);
}
img->convert(Image::FORMAT_RGBA8);
- if (!img->has_mipmaps() && make_mipmaps)
+ if (!img->has_mipmaps() && make_mipmaps) {
img->generate_mipmaps();
+ }
bool use_alpha = img->detect_alpha();
@@ -204,7 +210,6 @@ static void _compress_pvrtc4(Image *p_img) {
const uint8_t *r = img->get_data().ptr();
for (int i = 0; i <= new_img->get_mipmap_count(); i++) {
-
int ofs, size, w, h;
img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
Javelin::RgbaBitmap bm(w, h);
@@ -222,7 +227,6 @@ static void _compress_pvrtc4(Image *p_img) {
}
ResourceFormatPVR::ResourceFormatPVR() {
-
Image::_image_decompress_pvrtc = _pvrtc_decompress;
Image::_image_compress_pvrtc4_func = _compress_pvrtc4;
Image::_image_compress_pvrtc2_func = _compress_pvrtc4;
@@ -255,31 +259,28 @@ struct PVRTCBlock {
};
_FORCE_INLINE_ bool is_po2(uint32_t p_input) {
-
- if (p_input == 0)
- return 0;
+ if (p_input == 0) {
+ return false;
+ }
uint32_t minus1 = p_input - 1;
- return ((p_input | minus1) == (p_input ^ minus1)) ? 1 : 0;
+ return ((p_input | minus1) == (p_input ^ minus1)) ? true : false;
}
static void unpack_5554(const PVRTCBlock *p_block, int p_ab_colors[2][4]) {
-
uint32_t raw_bits[2];
raw_bits[0] = p_block->data[1] & (0xFFFE);
raw_bits[1] = p_block->data[1] >> 16;
for (int i = 0; i < 2; i++) {
-
if (raw_bits[i] & (1 << 15)) {
-
p_ab_colors[i][0] = (raw_bits[i] >> 10) & 0x1F;
p_ab_colors[i][1] = (raw_bits[i] >> 5) & 0x1F;
p_ab_colors[i][2] = raw_bits[i] & 0x1F;
- if (i == 0)
+ if (i == 0) {
p_ab_colors[0][2] |= p_ab_colors[0][2] >> 4;
+ }
p_ab_colors[i][3] = 0xF;
} else {
-
p_ab_colors[i][0] = (raw_bits[i] >> (8 - 1)) & 0x1E;
p_ab_colors[i][1] = (raw_bits[i] >> (4 - 1)) & 0x1E;
@@ -288,10 +289,11 @@ static void unpack_5554(const PVRTCBlock *p_block, int p_ab_colors[2][4]) {
p_ab_colors[i][2] = (raw_bits[i] & 0xF) << 1;
- if (i == 0)
+ if (i == 0) {
p_ab_colors[0][2] |= p_ab_colors[0][2] >> 3;
- else
+ } else {
p_ab_colors[0][2] |= p_ab_colors[0][2] >> 4;
+ }
p_ab_colors[i][3] = (raw_bits[i] >> 11) & 0xE;
}
@@ -299,15 +301,12 @@ static void unpack_5554(const PVRTCBlock *p_block, int p_ab_colors[2][4]) {
}
static void unpack_modulations(const PVRTCBlock *p_block, const int p_2bit, int p_modulation[8][16], int p_modulation_modes[8][16], int p_x, int p_y) {
-
int block_mod_mode = p_block->data[1] & 1;
uint32_t modulation_bits = p_block->data[0];
if (p_2bit && block_mod_mode) {
-
for (int y = 0; y < BLK_Y_SIZE; y++) {
for (int x = 0; x < BLK_X_2BPP; x++) {
-
p_modulation_modes[y + p_y][x + p_x] = block_mod_mode;
if (((x ^ y) & 1) == 0) {
@@ -318,15 +317,15 @@ static void unpack_modulations(const PVRTCBlock *p_block, const int p_2bit, int
}
} else if (p_2bit) {
-
for (int y = 0; y < BLK_Y_SIZE; y++) {
for (int x = 0; x < BLK_X_2BPP; x++) {
p_modulation_modes[y + p_y][x + p_x] = block_mod_mode;
- if (modulation_bits & 1)
+ if (modulation_bits & 1) {
p_modulation[y + p_y][x + p_x] = 0x3;
- else
+ } else {
p_modulation[y + p_y][x + p_x] = 0x0;
+ }
modulation_bits >>= 1;
}
@@ -361,10 +360,11 @@ static void interpolate_colors(const int p_colorp[4], const int p_colorq[4], con
v = (y & 0x3) | ((~y & 0x2) << 1);
- if (p_2bit)
+ if (p_2bit) {
u = (x & 0x7) | ((~x & 0x4) << 1);
- else
+ } else {
u = (x & 0x3) | ((~x & 0x2) << 1);
+ }
v = v - BLK_Y_SIZE / 2;
@@ -420,19 +420,20 @@ static void get_modulation_value(int x, int y, const int p_2bit, const int p_mod
y = (y & 0x3) | ((~y & 0x2) << 1);
- if (p_2bit)
+ if (p_2bit) {
x = (x & 0x7) | ((~x & 0x4) << 1);
- else
+ } else {
x = (x & 0x3) | ((~x & 0x2) << 1);
+ }
*p_dopt = 0;
if (p_modulation_modes[y][x] == 0) {
mod_val = rep_vals0[p_modulation[y][x]];
} else if (p_2bit) {
- if (((x ^ y) & 1) == 0)
+ if (((x ^ y) & 1) == 0) {
mod_val = rep_vals0[p_modulation[y][x]];
- else if (p_modulation_modes[y][x] == 1) {
+ } else if (p_modulation_modes[y][x] == 1) {
mod_val = (rep_vals0[p_modulation[y - 1][x]] +
rep_vals0[p_modulation[y + 1][x]] +
rep_vals0[p_modulation[y][x - 1]] +
@@ -459,7 +460,6 @@ static void get_modulation_value(int x, int y, const int p_2bit, const int p_mod
static int disable_twiddling = 0;
static uint32_t twiddle_uv(uint32_t p_height, uint32_t p_width, uint32_t p_y, uint32_t p_x) {
-
uint32_t twiddled;
uint32_t min_dimension;
@@ -484,8 +484,9 @@ static uint32_t twiddle_uv(uint32_t p_height, uint32_t p_width, uint32_t p_y, ui
max_value = p_y;
}
- if (disable_twiddling)
+ if (disable_twiddling) {
return (p_y * p_width + p_x);
+ }
scr_bit_pos = 1;
dst_bit_pos = 1;
@@ -545,17 +546,17 @@ static void decompress_pvrtc(PVRTCBlock *p_comp_img, const int p_2bit, const int
int r_result[4];
- if (p_2bit)
+ if (p_2bit) {
x_block_size = BLK_X_2BPP;
- else
+ } else {
x_block_size = BLK_X_4BPP;
+ }
block_width = MAX(2, p_width / x_block_size);
block_height = MAX(2, p_height / BLK_Y_SIZE);
for (y = 0; y < p_height; y++) {
for (x = 0; x < p_width; x++) {
-
block_x = (x - x_block_size / 2);
blk_y = (y - BLK_Y_SIZE / 2);
@@ -620,8 +621,9 @@ static void decompress_pvrtc(PVRTCBlock *p_comp_img, const int p_2bit, const int
r_result[i] >>= 3;
}
- if (DoPT)
+ if (DoPT) {
r_result[3] = 0;
+ }
u_pos = (x + y * p_width) << 2;
p_dst[u_pos + 0] = (uint8_t)r_result[0];
@@ -633,7 +635,6 @@ static void decompress_pvrtc(PVRTCBlock *p_comp_img, const int p_2bit, const int
}
static void _pvrtc_decompress(Image *p_img) {
-
ERR_FAIL_COND(p_img->get_format() != Image::FORMAT_PVRTC2 && p_img->get_format() != Image::FORMAT_PVRTC2A && p_img->get_format() != Image::FORMAT_PVRTC4 && p_img->get_format() != Image::FORMAT_PVRTC4A);
bool _2bit = (p_img->get_format() == Image::FORMAT_PVRTC2 || p_img->get_format() == Image::FORMAT_PVRTC2A);
@@ -649,6 +650,7 @@ static void _pvrtc_decompress(Image *p_img) {
bool make_mipmaps = p_img->has_mipmaps();
p_img->create(p_img->get_width(), p_img->get_height(), false, Image::FORMAT_RGBA8, newdata);
- if (make_mipmaps)
+ if (make_mipmaps) {
p_img->generate_mipmaps();
+ }
}
diff --git a/modules/pvr/texture_loader_pvr.h b/modules/pvr/texture_loader_pvr.h
index 642323db35..07ef129689 100644
--- a/modules/pvr/texture_loader_pvr.h
+++ b/modules/pvr/texture_loader_pvr.h
@@ -36,7 +36,7 @@
class ResourceFormatPVR : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path, Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/regex/regex.cpp b/modules/regex/regex.cpp
index 25cc580591..50ca01067b 100644
--- a/modules/regex/regex.cpp
+++ b/modules/regex/regex.cpp
@@ -36,48 +36,43 @@ extern "C" {
}
static void *_regex_malloc(PCRE2_SIZE size, void *user) {
-
return memalloc(size);
}
static void _regex_free(void *ptr, void *user) {
-
memfree(ptr);
}
int RegExMatch::_find(const Variant &p_name) const {
-
if (p_name.is_num()) {
-
int i = (int)p_name;
- if (i >= data.size())
+ if (i >= data.size()) {
return -1;
+ }
return i;
} else if (p_name.get_type() == Variant::STRING) {
-
const Map<String, int>::Element *found = names.find((String)p_name);
- if (found)
+ if (found) {
return found->value();
+ }
}
return -1;
}
String RegExMatch::get_subject() const {
-
return subject;
}
int RegExMatch::get_group_count() const {
-
- if (data.size() == 0)
+ if (data.size() == 0) {
return 0;
+ }
return data.size() - 1;
}
Dictionary RegExMatch::get_names() const {
-
Dictionary result;
for (const Map<String, int>::Element *i = names.front(); i != nullptr; i = i->next()) {
@@ -88,13 +83,11 @@ Dictionary RegExMatch::get_names() const {
}
Array RegExMatch::get_strings() const {
-
Array result;
int size = data.size();
for (int i = 0; i < size; i++) {
-
int start = data[i].start;
if (start == -1) {
@@ -111,16 +104,17 @@ Array RegExMatch::get_strings() const {
}
String RegExMatch::get_string(const Variant &p_name) const {
-
int id = _find(p_name);
- if (id < 0)
+ if (id < 0) {
return String();
+ }
int start = data[id].start;
- if (start == -1)
+ if (start == -1) {
return String();
+ }
int length = data[id].end - start;
@@ -128,27 +122,26 @@ String RegExMatch::get_string(const Variant &p_name) const {
}
int RegExMatch::get_start(const Variant &p_name) const {
-
int id = _find(p_name);
- if (id < 0)
+ if (id < 0) {
return -1;
+ }
return data[id].start;
}
int RegExMatch::get_end(const Variant &p_name) const {
-
int id = _find(p_name);
- if (id < 0)
+ if (id < 0) {
return -1;
+ }
return data[id].end;
}
void RegExMatch::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_subject"), &RegExMatch::get_subject);
ClassDB::bind_method(D_METHOD("get_group_count"), &RegExMatch::get_group_count);
ClassDB::bind_method(D_METHOD("get_names"), &RegExMatch::get_names);
@@ -163,28 +156,22 @@ void RegExMatch::_bind_methods() {
}
void RegEx::_pattern_info(uint32_t what, void *where) const {
-
if (sizeof(CharType) == 2) {
-
pcre2_pattern_info_16((pcre2_code_16 *)code, what, where);
} else {
-
pcre2_pattern_info_32((pcre2_code_32 *)code, what, where);
}
}
void RegEx::clear() {
-
if (sizeof(CharType) == 2) {
-
if (code) {
pcre2_code_free_16((pcre2_code_16 *)code);
code = nullptr;
}
} else {
-
if (code) {
pcre2_code_free_32((pcre2_code_32 *)code);
code = nullptr;
@@ -193,7 +180,6 @@ void RegEx::clear() {
}
Error RegEx::compile(const String &p_pattern) {
-
pattern = p_pattern;
clear();
@@ -202,7 +188,6 @@ Error RegEx::compile(const String &p_pattern) {
uint32_t flags = PCRE2_DUPNAMES;
if (sizeof(CharType) == 2) {
-
pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx;
pcre2_compile_context_16 *cctx = pcre2_compile_context_create_16(gctx);
PCRE2_SPTR16 p = (PCRE2_SPTR16)pattern.c_str();
@@ -220,7 +205,6 @@ Error RegEx::compile(const String &p_pattern) {
}
} else {
-
pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
pcre2_compile_context_32 *cctx = pcre2_compile_context_create_32(gctx);
PCRE2_SPTR32 p = (PCRE2_SPTR32)pattern.c_str();
@@ -241,17 +225,16 @@ Error RegEx::compile(const String &p_pattern) {
}
Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end) const {
-
ERR_FAIL_COND_V(!is_valid(), nullptr);
Ref<RegExMatch> result = memnew(RegExMatch);
int length = p_subject.length();
- if (p_end >= 0 && p_end < length)
+ if (p_end >= 0 && p_end < length) {
length = p_end;
+ }
if (sizeof(CharType) == 2) {
-
pcre2_code_16 *c = (pcre2_code_16 *)code;
pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx;
pcre2_match_context_16 *mctx = pcre2_match_context_create_16(gctx);
@@ -272,7 +255,6 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end)
result->data.resize(size);
for (uint32_t i = 0; i < size; i++) {
-
result->data.write[i].start = ovector[i * 2];
result->data.write[i].end = ovector[i * 2 + 1];
}
@@ -281,7 +263,6 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end)
pcre2_match_context_free_16(mctx);
} else {
-
pcre2_code_32 *c = (pcre2_code_32 *)code;
pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx);
@@ -304,7 +285,6 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end)
result->data.resize(size);
for (uint32_t i = 0; i < size; i++) {
-
result->data.write[i].start = ovector[i * 2];
result->data.write[i].end = ovector[i * 2 + 1];
}
@@ -324,13 +304,14 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end)
_pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &entry_size);
for (uint32_t i = 0; i < count; i++) {
-
CharType id = table[i * entry_size];
- if (result->data[id].start == -1)
+ if (result->data[id].start == -1) {
continue;
+ }
String name = &table[i * entry_size + 1];
- if (result->names.has(name))
+ if (result->names.has(name)) {
continue;
+ }
result->names.insert(name, id);
}
@@ -339,13 +320,13 @@ Ref<RegExMatch> RegEx::search(const String &p_subject, int p_offset, int p_end)
}
Array RegEx::search_all(const String &p_subject, int p_offset, int p_end) const {
-
int last_end = -1;
Array result;
Ref<RegExMatch> match = search(p_subject, p_offset, p_end);
while (match.is_valid()) {
- if (last_end == match->get_end(0))
+ if (last_end == match->get_end(0)) {
break;
+ }
result.push_back(match);
last_end = match->get_end(0);
match = search(p_subject, match->get_end(0), p_end);
@@ -354,7 +335,6 @@ Array RegEx::search_all(const String &p_subject, int p_offset, int p_end) const
}
String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_all, int p_offset, int p_end) const {
-
ERR_FAIL_COND_V(!is_valid(), String());
// safety_zone is the number of chars we allocate in addition to the number of chars expected in order to
@@ -368,15 +348,16 @@ String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_a
output.resize(olength + safety_zone);
uint32_t flags = PCRE2_SUBSTITUTE_OVERFLOW_LENGTH;
- if (p_all)
+ if (p_all) {
flags |= PCRE2_SUBSTITUTE_GLOBAL;
+ }
PCRE2_SIZE length = p_subject.length();
- if (p_end >= 0 && (uint32_t)p_end < length)
+ if (p_end >= 0 && (uint32_t)p_end < length) {
length = p_end;
+ }
if (sizeof(CharType) == 2) {
-
pcre2_code_16 *c = (pcre2_code_16 *)code;
pcre2_general_context_16 *gctx = (pcre2_general_context_16 *)general_ctx;
pcre2_match_context_16 *mctx = pcre2_match_context_create_16(gctx);
@@ -397,11 +378,11 @@ String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_a
pcre2_match_data_free_16(match);
pcre2_match_context_free_16(mctx);
- if (res < 0)
+ if (res < 0) {
return String();
+ }
} else {
-
pcre2_code_32 *c = (pcre2_code_32 *)code;
pcre2_general_context_32 *gctx = (pcre2_general_context_32 *)general_ctx;
pcre2_match_context_32 *mctx = pcre2_match_context_create_32(gctx);
@@ -422,25 +403,23 @@ String RegEx::sub(const String &p_subject, const String &p_replacement, bool p_a
pcre2_match_data_free_32(match);
pcre2_match_context_free_32(mctx);
- if (res < 0)
+ if (res < 0) {
return String();
+ }
}
return String(output.ptr(), olength);
}
bool RegEx::is_valid() const {
-
return (code != nullptr);
}
String RegEx::get_pattern() const {
-
return pattern;
}
int RegEx::get_group_count() const {
-
ERR_FAIL_COND_V(!is_valid(), 0);
uint32_t count;
@@ -451,7 +430,6 @@ int RegEx::get_group_count() const {
}
Array RegEx::get_names() const {
-
Array result;
ERR_FAIL_COND_V(!is_valid(), result);
@@ -465,7 +443,6 @@ Array RegEx::get_names() const {
_pattern_info(PCRE2_INFO_NAMEENTRYSIZE, &entry_size);
for (uint32_t i = 0; i < count; i++) {
-
String name = &table[i * entry_size + 1];
if (result.find(name) < 0) {
result.append(name);
@@ -476,26 +453,20 @@ Array RegEx::get_names() const {
}
RegEx::RegEx() {
-
if (sizeof(CharType) == 2) {
-
general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, nullptr);
} else {
-
general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr);
}
code = nullptr;
}
RegEx::RegEx(const String &p_pattern) {
-
if (sizeof(CharType) == 2) {
-
general_ctx = pcre2_general_context_create_16(&_regex_malloc, &_regex_free, nullptr);
} else {
-
general_ctx = pcre2_general_context_create_32(&_regex_malloc, &_regex_free, nullptr);
}
code = nullptr;
@@ -503,23 +474,21 @@ RegEx::RegEx(const String &p_pattern) {
}
RegEx::~RegEx() {
-
if (sizeof(CharType) == 2) {
-
- if (code)
+ if (code) {
pcre2_code_free_16((pcre2_code_16 *)code);
+ }
pcre2_general_context_free_16((pcre2_general_context_16 *)general_ctx);
} else {
-
- if (code)
+ if (code) {
pcre2_code_free_32((pcre2_code_32 *)code);
+ }
pcre2_general_context_free_32((pcre2_general_context_32 *)general_ctx);
}
}
void RegEx::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("clear"), &RegEx::clear);
ClassDB::bind_method(D_METHOD("compile", "pattern"), &RegEx::compile);
ClassDB::bind_method(D_METHOD("search", "subject", "offset", "end"), &RegEx::search, DEFVAL(0), DEFVAL(-1));
diff --git a/modules/regex/regex.h b/modules/regex/regex.h
index a342c17c78..52b49c783e 100644
--- a/modules/regex/regex.h
+++ b/modules/regex/regex.h
@@ -39,7 +39,6 @@
#include "core/vector.h"
class RegExMatch : public Reference {
-
GDCLASS(RegExMatch, Reference);
struct Range {
@@ -70,7 +69,6 @@ public:
};
class RegEx : public Reference {
-
GDCLASS(RegEx, Reference);
void *general_ctx;
diff --git a/modules/regex/register_types.cpp b/modules/regex/register_types.cpp
index 77b19fa8f0..5d4aeba2d7 100644
--- a/modules/regex/register_types.cpp
+++ b/modules/regex/register_types.cpp
@@ -33,7 +33,6 @@
#include "regex.h"
void register_regex_types() {
-
ClassDB::register_class<RegExMatch>();
ClassDB::register_class<RegEx>();
}
diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp
index bb77f68590..c510779317 100644
--- a/modules/squish/image_compress_squish.cpp
+++ b/modules/squish/image_compress_squish.cpp
@@ -78,21 +78,21 @@ void image_decompress_squish(Image *p_image) {
}
void image_compress_squish(Image *p_image, float p_lossy_quality, Image::UsedChannels p_channels) {
-
- if (p_image->get_format() >= Image::FORMAT_DXT1)
+ if (p_image->get_format() >= Image::FORMAT_DXT1) {
return; //do not compress, already compressed
+ }
int w = p_image->get_width();
int h = p_image->get_height();
if (p_image->get_format() <= Image::FORMAT_RGBA8) {
-
int squish_comp = squish::kColourRangeFit;
- if (p_lossy_quality > 0.85)
+ if (p_lossy_quality > 0.85) {
squish_comp = squish::kColourIterativeClusterFit;
- else if (p_lossy_quality > 0.75)
+ } else if (p_lossy_quality > 0.75) {
squish_comp = squish::kColourClusterFit;
+ }
Image::Format target_format = Image::FORMAT_RGBA8;
@@ -100,32 +100,26 @@ void image_compress_squish(Image *p_image, float p_lossy_quality, Image::UsedCha
switch (p_channels) {
case Image::USED_CHANNELS_L: {
-
target_format = Image::FORMAT_DXT1;
squish_comp |= squish::kDxt1;
} break;
case Image::USED_CHANNELS_LA: {
-
target_format = Image::FORMAT_DXT5;
squish_comp |= squish::kDxt5;
} break;
case Image::USED_CHANNELS_R: {
-
target_format = Image::FORMAT_RGTC_R;
squish_comp |= squish::kBc4;
} break;
case Image::USED_CHANNELS_RG: {
-
target_format = Image::FORMAT_RGTC_RG;
squish_comp |= squish::kBc5;
} break;
case Image::USED_CHANNELS_RGB: {
-
target_format = Image::FORMAT_DXT1;
squish_comp |= squish::kDxt1;
} break;
case Image::USED_CHANNELS_RGBA: {
-
//TODO, should convert both, then measure which one does a better job
target_format = Image::FORMAT_DXT5;
squish_comp |= squish::kDxt5;
@@ -149,7 +143,6 @@ void image_compress_squish(Image *p_image, float p_lossy_quality, Image::UsedCha
int dst_ofs = 0;
for (int i = 0; i <= mm_count; i++) {
-
int bw = w % 4 != 0 ? w + (4 - w % 4) : w;
int bh = h % 4 != 0 ? h + (4 - h % 4) : h;
diff --git a/modules/squish/register_types.cpp b/modules/squish/register_types.cpp
index 2a0cf82b56..ad28aff058 100644
--- a/modules/squish/register_types.cpp
+++ b/modules/squish/register_types.cpp
@@ -32,7 +32,6 @@
#include "image_compress_squish.h"
void register_squish_types() {
-
Image::set_compress_bc_func(image_compress_squish);
Image::_image_decompress_bc = image_decompress_squish;
}
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
index 9609c234ec..3aceaf11c5 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
@@ -33,7 +33,6 @@
#include "core/os/file_access.h"
void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_frames) {
-
ERR_FAIL_COND(!active);
int todo = p_frames;
@@ -76,12 +75,10 @@ void AudioStreamPlaybackOGGVorbis::_mix_internal(AudioFrame *p_buffer, int p_fra
}
float AudioStreamPlaybackOGGVorbis::get_stream_sampling_rate() {
-
return vorbis_stream->sample_rate;
}
void AudioStreamPlaybackOGGVorbis::start(float p_from_pos) {
-
active = true;
seek(p_from_pos);
loops = 0;
@@ -89,27 +86,25 @@ void AudioStreamPlaybackOGGVorbis::start(float p_from_pos) {
}
void AudioStreamPlaybackOGGVorbis::stop() {
-
active = false;
}
-bool AudioStreamPlaybackOGGVorbis::is_playing() const {
+bool AudioStreamPlaybackOGGVorbis::is_playing() const {
return active;
}
int AudioStreamPlaybackOGGVorbis::get_loop_count() const {
-
return loops;
}
float AudioStreamPlaybackOGGVorbis::get_playback_position() const {
-
return float(frames_mixed) / vorbis_stream->sample_rate;
}
-void AudioStreamPlaybackOGGVorbis::seek(float p_time) {
- if (!active)
+void AudioStreamPlaybackOGGVorbis::seek(float p_time) {
+ if (!active) {
return;
+ }
if (p_time >= vorbis_stream->get_length()) {
p_time = 0;
@@ -127,7 +122,6 @@ AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() {
}
Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instance_playback() {
-
Ref<AudioStreamPlaybackOGGVorbis> ovs;
ERR_FAIL_COND_V(data == nullptr, ovs);
@@ -142,7 +136,6 @@ Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instance_playback() {
int error;
ovs->ogg_stream = stb_vorbis_open_memory((const unsigned char *)data, data_len, &error, &ovs->ogg_alloc);
if (!ovs->ogg_stream) {
-
memfree(ovs->ogg_alloc.alloc_buffer);
ovs->ogg_alloc.alloc_buffer = nullptr;
ERR_FAIL_COND_V(!ovs->ogg_stream, Ref<AudioStreamPlaybackOGGVorbis>());
@@ -152,7 +145,6 @@ Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instance_playback() {
}
String AudioStreamOGGVorbis::get_stream_name() const {
-
return ""; //return stream_name;
}
@@ -165,7 +157,6 @@ void AudioStreamOGGVorbis::clear_data() {
}
void AudioStreamOGGVorbis::set_data(const Vector<uint8_t> &p_data) {
-
int src_data_len = p_data.size();
#define MAX_TEST_MEM (1 << 20)
@@ -176,7 +167,6 @@ void AudioStreamOGGVorbis::set_data(const Vector<uint8_t> &p_data) {
stb_vorbis_alloc ogg_alloc;
while (alloc_try < MAX_TEST_MEM) {
-
alloc_mem.resize(alloc_try);
w = alloc_mem.ptrw();
@@ -189,10 +179,8 @@ void AudioStreamOGGVorbis::set_data(const Vector<uint8_t> &p_data) {
ogg_stream = stb_vorbis_open_memory((const unsigned char *)src_datar, src_data_len, &error, &ogg_alloc);
if (!ogg_stream && error == VORBIS_outofmem) {
-
alloc_try *= 2;
} else {
-
ERR_FAIL_COND(alloc_try == MAX_TEST_MEM);
ERR_FAIL_COND(ogg_stream == nullptr);
@@ -220,7 +208,6 @@ void AudioStreamOGGVorbis::set_data(const Vector<uint8_t> &p_data) {
}
Vector<uint8_t> AudioStreamOGGVorbis::get_data() const {
-
Vector<uint8_t> vdata;
if (data_len && data) {
@@ -239,7 +226,6 @@ void AudioStreamOGGVorbis::set_loop(bool p_enable) {
}
bool AudioStreamOGGVorbis::has_loop() const {
-
return loop;
}
@@ -252,12 +238,10 @@ float AudioStreamOGGVorbis::get_loop_offset() const {
}
float AudioStreamOGGVorbis::get_length() const {
-
return length;
}
void AudioStreamOGGVorbis::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamOGGVorbis::set_data);
ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamOGGVorbis::get_data);
@@ -273,7 +257,6 @@ void AudioStreamOGGVorbis::_bind_methods() {
}
AudioStreamOGGVorbis::AudioStreamOGGVorbis() {
-
data = nullptr;
data_len = 0;
length = 0;
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.h b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
index f296e8c19f..3002134651 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.h
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
@@ -39,7 +39,6 @@
class AudioStreamOGGVorbis;
class AudioStreamPlaybackOGGVorbis : public AudioStreamPlaybackResampled {
-
GDCLASS(AudioStreamPlaybackOGGVorbis, AudioStreamPlaybackResampled);
stb_vorbis *ogg_stream;
@@ -71,7 +70,6 @@ public:
};
class AudioStreamOGGVorbis : public AudioStream {
-
GDCLASS(AudioStreamOGGVorbis, AudioStream);
OBJ_SAVE_TYPE(AudioStream); // Saves derived classes with common type so they can be interchanged.
RES_BASE_EXTENSION("oggstr");
diff --git a/modules/stb_vorbis/register_types.cpp b/modules/stb_vorbis/register_types.cpp
index ac2612bd6a..6669d30278 100644
--- a/modules/stb_vorbis/register_types.cpp
+++ b/modules/stb_vorbis/register_types.cpp
@@ -38,7 +38,6 @@
#endif
void register_stb_vorbis_types() {
-
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
Ref<ResourceImporterOGGVorbis> ogg_import;
diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
index 13d96541e3..d68d050d34 100644
--- a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
@@ -35,16 +35,14 @@
#include "scene/resources/texture.h"
String ResourceImporterOGGVorbis::get_importer_name() const {
-
return "ogg_vorbis";
}
String ResourceImporterOGGVorbis::get_visible_name() const {
-
return "OGGVorbis";
}
-void ResourceImporterOGGVorbis::get_recognized_extensions(List<String> *p_extensions) const {
+void ResourceImporterOGGVorbis::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("ogg");
}
@@ -53,31 +51,27 @@ String ResourceImporterOGGVorbis::get_save_extension() const {
}
String ResourceImporterOGGVorbis::get_resource_type() const {
-
return "AudioStreamOGGVorbis";
}
bool ResourceImporterOGGVorbis::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
-
return true;
}
int ResourceImporterOGGVorbis::get_preset_count() const {
return 0;
}
-String ResourceImporterOGGVorbis::get_preset_name(int p_idx) const {
+String ResourceImporterOGGVorbis::get_preset_name(int p_idx) const {
return String();
}
void ResourceImporterOGGVorbis::get_import_options(List<ImportOption> *r_options, int p_preset) const {
-
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "loop"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "loop_offset"), 0));
}
Error ResourceImporterOGGVorbis::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
-
bool loop = p_options["loop"];
float loop_offset = p_options["loop_offset"];
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index 3c2784f8de..8ca4452ac9 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -40,6 +40,7 @@ void SVGRasterizer::rasterize(NSVGimage *p_image, float p_tx, float p_ty, float
SVGRasterizer::SVGRasterizer() {
rasterizer = nsvgCreateRasterizer();
}
+
SVGRasterizer::~SVGRasterizer() {
nsvgDeleteRasterizer(rasterizer);
}
@@ -47,7 +48,6 @@ SVGRasterizer::~SVGRasterizer() {
SVGRasterizer ImageLoaderSVG::rasterizer;
inline void change_nsvg_paint_color(NSVGpaint *p_paint, const uint32_t p_old, const uint32_t p_new) {
-
if (p_paint->type == NSVG_PAINT_COLOR) {
if (p_paint->color << 8 == p_old << 8) {
p_paint->color = (p_paint->color & 0xFF000000) | (p_new & 0x00FFFFFF);
@@ -64,9 +64,7 @@ inline void change_nsvg_paint_color(NSVGpaint *p_paint, const uint32_t p_old, co
}
void ImageLoaderSVG::_convert_colors(NSVGimage *p_svg_image) {
-
for (NSVGshape *shape = p_svg_image->shapes; shape != nullptr; shape = shape->next) {
-
for (int i = 0; i < replace_colors.old_colors.size(); i++) {
change_nsvg_paint_color(&(shape->stroke), replace_colors.old_colors[i], replace_colors.new_colors[i]);
change_nsvg_paint_color(&(shape->fill), replace_colors.old_colors[i], replace_colors.new_colors[i]);
@@ -75,7 +73,6 @@ void ImageLoaderSVG::_convert_colors(NSVGimage *p_svg_image) {
}
void ImageLoaderSVG::set_convert_colors(Dictionary *p_replace_color) {
-
if (p_replace_color) {
Dictionary replace_color = *p_replace_color;
for (int i = 0; i < replace_color.keys().size(); i++) {
@@ -133,7 +130,6 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const Vector<uint8_t> *p
}
Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample, bool convert_colors) {
-
size_t str_len = strlen(p_svg_str);
Vector<uint8_t> src_data;
src_data.resize(str_len + 1);
@@ -144,7 +140,6 @@ Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *p
}
Error ImageLoaderSVG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
-
uint32_t size = f->get_len();
Vector<uint8_t> src_image;
src_image.resize(size + 1);
@@ -156,7 +151,6 @@ Error ImageLoaderSVG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
}
void ImageLoaderSVG::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("svg");
p_extensions->push_back("svgz");
}
diff --git a/modules/svg/image_loader_svg.h b/modules/svg/image_loader_svg.h
index 0fa4a0fdf4..ecaba5052b 100644
--- a/modules/svg/image_loader_svg.h
+++ b/modules/svg/image_loader_svg.h
@@ -43,7 +43,6 @@ struct NSVGrasterizer;
struct NSVGimage;
class SVGRasterizer {
-
NSVGrasterizer *rasterizer;
public:
diff --git a/modules/svg/register_types.cpp b/modules/svg/register_types.cpp
index 37875313aa..9fbefd2cfe 100644
--- a/modules/svg/register_types.cpp
+++ b/modules/svg/register_types.cpp
@@ -35,12 +35,10 @@
static ImageLoaderSVG *image_loader_svg = nullptr;
void register_svg_types() {
-
image_loader_svg = memnew(ImageLoaderSVG);
ImageLoader::add_image_format_loader(image_loader_svg);
}
void unregister_svg_types() {
-
memdelete(image_loader_svg);
}
diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp
index fc9d727bb0..ce889a4928 100644
--- a/modules/tga/image_loader_tga.cpp
+++ b/modules/tga/image_loader_tga.cpp
@@ -38,8 +38,9 @@ Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t
Vector<uint8_t> pixels;
error = pixels.resize(p_pixel_size);
- if (error != OK)
+ if (error != OK) {
return error;
+ }
uint8_t *pixels_w = pixels.ptrw();
@@ -77,7 +78,6 @@ Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t
}
Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome) {
-
#define TGA_PUT_PIXEL(r, g, b, a) \
int image_data_ofs = ((y * width) + x); \
image_data_w[image_data_ofs * 4 + 0] = r; \
@@ -199,13 +199,12 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff
}
}
- p_image->create(width, height, 0, Image::FORMAT_RGBA8, image_data);
+ p_image->create(width, height, false, Image::FORMAT_RGBA8, image_data);
return OK;
}
Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
-
Vector<uint8_t> src_image;
int src_image_len = f->get_len();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
@@ -234,8 +233,9 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
bool has_color_map = (tga_header.image_type == TGA_TYPE_RLE_INDEXED || tga_header.image_type == TGA_TYPE_INDEXED);
bool is_monochrome = (tga_header.image_type == TGA_TYPE_RLE_MONOCHROME || tga_header.image_type == TGA_TYPE_MONOCHROME);
- if (tga_header.image_type == TGA_TYPE_NO_DATA)
+ if (tga_header.image_type == TGA_TYPE_NO_DATA) {
err = FAILED;
+ }
if (has_color_map) {
if (tga_header.color_map_length > 256 || (tga_header.color_map_depth != 24) || tga_header.color_map_type != 1) {
@@ -247,8 +247,9 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
}
}
- if (tga_header.image_width <= 0 || tga_header.image_height <= 0)
+ if (tga_header.image_width <= 0 || tga_header.image_height <= 0) {
err = FAILED;
+ }
if (!(tga_header.pixel_depth == 8 || tga_header.pixel_depth == 24 || tga_header.pixel_depth == 32)) {
err = FAILED;
@@ -286,7 +287,6 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
const uint8_t *buffer = nullptr;
if (is_encoded) {
-
err = decode_tga_rle(src_image_r, pixel_size, uncompressed_buffer_w, buffer_size);
if (err == OK) {
@@ -308,7 +308,6 @@ Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force
}
void ImageLoaderTGA::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("tga");
}
diff --git a/modules/tga/register_types.cpp b/modules/tga/register_types.cpp
index 0d9268ebbf..320f748083 100644
--- a/modules/tga/register_types.cpp
+++ b/modules/tga/register_types.cpp
@@ -35,12 +35,10 @@
static ImageLoaderTGA *image_loader_tga = nullptr;
void register_tga_types() {
-
image_loader_tga = memnew(ImageLoaderTGA);
ImageLoader::add_image_format_loader(image_loader_tga);
}
void unregister_tga_types() {
-
memdelete(image_loader_tga);
}
diff --git a/modules/theora/register_types.cpp b/modules/theora/register_types.cpp
index f58e27c855..0676cab5c5 100644
--- a/modules/theora/register_types.cpp
+++ b/modules/theora/register_types.cpp
@@ -35,7 +35,6 @@
static Ref<ResourceFormatLoaderTheora> resource_loader_theora;
void register_theora_types() {
-
resource_loader_theora.instance();
ResourceLoader::add_resource_format_loader(resource_loader_theora, true);
@@ -43,7 +42,6 @@ void register_theora_types() {
}
void unregister_theora_types() {
-
ResourceLoader::remove_resource_format_loader(resource_loader_theora);
resource_loader_theora.unref();
}
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index e5fb6f996d..498391e44a 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -36,7 +36,6 @@
#include "thirdparty/misc/yuv2rgb.h"
int VideoStreamPlaybackTheora::buffer_data() {
-
char *buffer = ogg_sync_buffer(&oy, 4096);
#ifdef THEORA_USE_THREAD_STREAMING
@@ -69,18 +68,20 @@ int VideoStreamPlaybackTheora::buffer_data() {
int VideoStreamPlaybackTheora::queue_page(ogg_page *page) {
if (theora_p) {
ogg_stream_pagein(&to, page);
- if (to.e_o_s)
+ if (to.e_o_s) {
theora_eos = true;
+ }
}
if (vorbis_p) {
ogg_stream_pagein(&vo, page);
- if (vo.e_o_s)
+ if (vo.e_o_s) {
vorbis_eos = true;
+ }
}
return 0;
}
-void VideoStreamPlaybackTheora::video_write(void) {
+void VideoStreamPlaybackTheora::video_write() {
th_ycbcr_buffer yuv;
th_decode_ycbcr_out(td, yuv);
@@ -93,15 +94,12 @@ void VideoStreamPlaybackTheora::video_write(void) {
//uv_offset=(ti.pic_x/2)+(yuv[1].stride)*(ti.pic_y/2);
if (px_fmt == TH_PF_444) {
-
yuv444_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2);
} else if (px_fmt == TH_PF_422) {
-
yuv422_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2);
} else if (px_fmt == TH_PF_420) {
-
yuv420_2_rgb8888((uint8_t *)dst, (uint8_t *)yuv[0].data, (uint8_t *)yuv[1].data, (uint8_t *)yuv[2].data, size.x, size.y, yuv[0].stride, yuv[1].stride, size.x << 2);
};
@@ -116,9 +114,9 @@ void VideoStreamPlaybackTheora::video_write(void) {
}
void VideoStreamPlaybackTheora::clear() {
-
- if (!file)
+ if (!file) {
return;
+ }
if (vorbis_p) {
ogg_stream_clear(&vo);
@@ -164,7 +162,6 @@ void VideoStreamPlaybackTheora::clear() {
};
void VideoStreamPlaybackTheora::set_file(const String &p_file) {
-
ERR_FAIL_COND(playing);
ogg_packet op;
th_setup_info *ts = nullptr;
@@ -209,7 +206,9 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
while (!stateflag) {
int ret = buffer_data();
- if (ret == 0) break;
+ if (ret == 0) {
+ break;
+ }
while (ogg_sync_pageout(&oy, &og) > 0) {
ogg_stream_state test;
@@ -231,7 +230,6 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
copymem(&to, &test, sizeof(test));
theora_p = 1;
} else if (!vorbis_p && vorbis_synthesis_headerin(&vi, &vc, &op) >= 0) {
-
/* it is vorbis */
if (audio_track_skip) {
vorbis_info_clear(&vi);
@@ -286,7 +284,9 @@ void VideoStreamPlaybackTheora::set_file(const String &p_file) {
return;
}
vorbis_p++;
- if (vorbis_p == 3) break;
+ if (vorbis_p == 3) {
+ break;
+ }
}
/* The header pages/packets will arrive before anything else we
@@ -372,14 +372,13 @@ float VideoStreamPlaybackTheora::get_time() const {
};
Ref<Texture2D> VideoStreamPlaybackTheora::get_texture() const {
-
return texture;
}
void VideoStreamPlaybackTheora::update(float p_delta) {
-
- if (!file)
+ if (!file) {
return;
+ }
if (!playing || paused) {
//printf("not playing\n");
@@ -413,13 +412,11 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
/* if there's pending, decoded audio, grab it */
ret = vorbis_synthesis_pcmout(&vd, &pcm);
if (ret > 0) {
-
const int AUXBUF_LEN = 4096;
int to_read = ret;
float aux_buffer[AUXBUF_LEN];
while (to_read) {
-
int m = MIN(AUXBUF_LEN / vi.channels, to_read);
int count = 0;
@@ -447,7 +444,6 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
audio_frames_wrote += ret - to_read;
} else {
-
/* no pending audio; is there a pending packet to decode? */
if (ogg_stream_packetout(&vo, &op) > 0) {
if (vorbis_synthesis(&vb, &op) == 0) { /* test for success! */
@@ -460,14 +456,14 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
audio_done = videobuf_time < (audio_frames_wrote / float(vi.rate));
- if (buffer_full)
+ if (buffer_full) {
break;
+ }
}
while (theora_p && !frame_done) {
/* theora is one in, one out... */
if (ogg_stream_packetout(&to, &op) > 0) {
-
if (false && pp_inc) {
pp_level += pp_inc;
th_decode_ctl(td, TH_DECCTL_SET_PPLEVEL, &pp_level,
@@ -534,7 +530,6 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
/* are we at or past time for this video frame? */
if (videobuf_ready && videobuf_time <= get_time()) {
-
//video_write();
//videobuf_ready=0;
} else {
@@ -554,10 +549,9 @@ void VideoStreamPlaybackTheora::update(float p_delta) {
};
void VideoStreamPlaybackTheora::play() {
-
- if (!playing)
+ if (!playing) {
time = 0;
- else {
+ } else {
stop();
}
@@ -567,9 +561,7 @@ void VideoStreamPlaybackTheora::play() {
};
void VideoStreamPlaybackTheora::stop() {
-
if (playing) {
-
clear();
set_file(file_name); //reset
}
@@ -578,86 +570,68 @@ void VideoStreamPlaybackTheora::stop() {
};
bool VideoStreamPlaybackTheora::is_playing() const {
-
return playing;
};
void VideoStreamPlaybackTheora::set_paused(bool p_paused) {
-
paused = p_paused;
};
bool VideoStreamPlaybackTheora::is_paused() const {
-
return paused;
};
-void VideoStreamPlaybackTheora::set_loop(bool p_enable){
-
-};
+void VideoStreamPlaybackTheora::set_loop(bool p_enable) {
+}
bool VideoStreamPlaybackTheora::has_loop() const {
-
return false;
};
float VideoStreamPlaybackTheora::get_length() const {
-
return 0;
};
String VideoStreamPlaybackTheora::get_stream_name() const {
-
return "";
};
int VideoStreamPlaybackTheora::get_loop_count() const {
-
return 0;
};
float VideoStreamPlaybackTheora::get_playback_position() const {
-
return get_time();
};
-void VideoStreamPlaybackTheora::seek(float p_time){
-
- // no
-};
+void VideoStreamPlaybackTheora::seek(float p_time) {
+}
void VideoStreamPlaybackTheora::set_mix_callback(AudioMixCallback p_callback, void *p_userdata) {
-
mix_callback = p_callback;
mix_udata = p_userdata;
}
int VideoStreamPlaybackTheora::get_channels() const {
-
return vi.channels;
}
void VideoStreamPlaybackTheora::set_audio_track(int p_idx) {
-
audio_track = p_idx;
}
int VideoStreamPlaybackTheora::get_mix_rate() const {
-
return vi.rate;
}
#ifdef THEORA_USE_THREAD_STREAMING
void VideoStreamPlaybackTheora::_streaming_thread(void *ud) {
-
VideoStreamPlaybackTheora *vs = (VideoStreamPlaybackTheora *)ud;
while (!vs->thread_exit) {
-
//just fill back the buffer
if (!vs->thread_eof) {
-
int to_read = vs->ring_buffer.space_left();
if (to_read) {
int read = vs->file->get_buffer(vs->read_buffer.ptr(), to_read);
@@ -673,7 +647,6 @@ void VideoStreamPlaybackTheora::_streaming_thread(void *ud) {
#endif
VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
-
file = nullptr;
theora_p = 0;
vorbis_p = 0;
@@ -704,19 +677,18 @@ VideoStreamPlaybackTheora::VideoStreamPlaybackTheora() {
};
VideoStreamPlaybackTheora::~VideoStreamPlaybackTheora() {
-
#ifdef THEORA_USE_THREAD_STREAMING
memdelete(thread_sem);
#endif
clear();
- if (file)
+ if (file) {
memdelete(file);
+ }
};
void VideoStreamTheora::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamTheora::set_file);
ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamTheora::get_file);
@@ -725,8 +697,7 @@ void VideoStreamTheora::_bind_methods() {
////////////
-RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
+RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
if (r_error) {
@@ -750,19 +721,17 @@ RES ResourceFormatLoaderTheora::load(const String &p_path, const String &p_origi
}
void ResourceFormatLoaderTheora::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("ogv");
}
bool ResourceFormatLoaderTheora::handles_type(const String &p_type) const {
-
return ClassDB::is_parent_class(p_type, "VideoStream");
}
String ResourceFormatLoaderTheora::get_resource_type(const String &p_path) const {
-
String el = p_path.get_extension().to_lower();
- if (el == "ogv")
+ if (el == "ogv") {
return "VideoStreamTheora";
+ }
return "";
}
diff --git a/modules/theora/video_stream_theora.h b/modules/theora/video_stream_theora.h
index cd7bff7adb..f90c2465b4 100644
--- a/modules/theora/video_stream_theora.h
+++ b/modules/theora/video_stream_theora.h
@@ -45,7 +45,6 @@
//#define THEORA_USE_THREAD_STREAMING
class VideoStreamPlaybackTheora : public VideoStreamPlayback {
-
GDCLASS(VideoStreamPlaybackTheora, VideoStreamPlayback);
enum {
@@ -63,7 +62,7 @@ class VideoStreamPlaybackTheora : public VideoStreamPlayback {
int buffer_data();
int queue_page(ogg_page *page);
- void video_write(void);
+ void video_write();
float get_time() const;
bool theora_eos;
@@ -161,7 +160,6 @@ public:
};
class VideoStreamTheora : public VideoStream {
-
GDCLASS(VideoStreamTheora, VideoStream);
String file;
@@ -187,7 +185,7 @@ public:
class ResourceFormatLoaderTheora : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/tinyexr/SCsub b/modules/tinyexr/SCsub
index e7fd44fabd..84b3b4015b 100644
--- a/modules/tinyexr/SCsub
+++ b/modules/tinyexr/SCsub
@@ -15,6 +15,9 @@ thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
env_tinyexr.Prepend(CPPPATH=[thirdparty_dir])
+# Enable threaded loading with C++11.
+env_tinyexr.Append(CPPDEFINES=["TINYEXR_USE_THREAD"])
+
env_thirdparty = env_tinyexr.Clone()
env_thirdparty.disable_warnings()
env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources)
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 1c0f3cd03e..9e7266b95a 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -36,7 +36,6 @@
#include "thirdparty/tinyexr/tinyexr.h"
Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
-
Vector<uint8_t> src_image;
int src_image_len = f->get_len();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
@@ -62,7 +61,6 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
int ret = ParseEXRVersionFromMemory(&exr_version, w, src_image_len);
if (ret != TINYEXR_SUCCESS) {
-
return ERR_FILE_CORRUPT;
}
@@ -141,12 +139,10 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
int output_channels = 0;
if (idxA != -1) {
-
imgdata.resize(exr_image.width * exr_image.height * 8); //RGBA16
format = Image::FORMAT_RGBAH;
output_channels = 4;
} else {
-
imgdata.resize(exr_image.width * exr_image.height * 6); //RGB16
format = Image::FORMAT_RGBH;
output_channels = 3;
@@ -185,7 +181,6 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
// Assume `out_rgba` have enough memory allocated.
for (int tile_index = 0; tile_index < num_tiles; tile_index++) {
-
const EXRTile &tile = exr_tiles[tile_index];
int tw = tile.width;
@@ -215,11 +210,11 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
uint16_t *row_w = first_row_w + (y * exr_image.width * output_channels);
for (int x = 0; x < tw; x++) {
-
Color color(*r_channel++, *g_channel++, *b_channel++);
- if (p_force_linear)
+ if (p_force_linear) {
color = color.to_linear();
+ }
*row_w++ = Math::make_half_float(color.r);
*row_w++ = Math::make_half_float(color.g);
@@ -242,7 +237,6 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
}
void ImageLoaderTinyEXR::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("exr");
}
diff --git a/modules/tinyexr/image_loader_tinyexr.h b/modules/tinyexr/image_loader_tinyexr.h
index af95989254..ff040b0915 100644
--- a/modules/tinyexr/image_loader_tinyexr.h
+++ b/modules/tinyexr/image_loader_tinyexr.h
@@ -34,7 +34,6 @@
#include "core/io/image_loader.h"
class ImageLoaderTinyEXR : public ImageFormatLoader {
-
public:
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
diff --git a/modules/tinyexr/image_saver_tinyexr.cpp b/modules/tinyexr/image_saver_tinyexr.cpp
index 05080289bd..420619bd5f 100644
--- a/modules/tinyexr/image_saver_tinyexr.cpp
+++ b/modules/tinyexr/image_saver_tinyexr.cpp
@@ -140,7 +140,6 @@ static int get_channel_count(Image::Format p_format) {
}
Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale) {
-
Image::Format format = p_img->get_format();
if (!is_supported_format(format)) {
@@ -192,7 +191,6 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
const uint8_t *src_r = src_data.ptr();
for (int channel_index = 0; channel_index < channel_count; ++channel_index) {
-
// De-interleave channels
PackedByteArray &dst = channels[channel_index];
@@ -201,7 +199,6 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
uint8_t *dst_w = dst.ptrw();
if (src_pixel_type == SRC_FLOAT && target_pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
-
// Note: we don't save mipmaps
CRASH_COND(src_data.size() < pixel_count * channel_count * target_pixel_type_size);
@@ -213,7 +210,6 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
}
} else if (src_pixel_type == SRC_HALF && target_pixel_type == TINYEXR_PIXELTYPE_HALF) {
-
CRASH_COND(src_data.size() < pixel_count * channel_count * target_pixel_type_size);
const uint16_t *src_rp = (uint16_t *)src_r;
@@ -224,7 +220,6 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
}
} else if (src_pixel_type == SRC_BYTE && target_pixel_type == TINYEXR_PIXELTYPE_HALF) {
-
CRASH_COND(src_data.size() < pixel_count * channel_count);
const uint8_t *src_rp = (uint8_t *)src_r;
@@ -267,13 +262,21 @@ Error save_exr(const String &p_path, const Ref<Image> &p_img, bool p_grayscale)
header.channels = channel_infos;
header.pixel_types = pixel_types;
header.requested_pixel_types = requested_pixel_types;
+ header.compression_type = TINYEXR_COMPRESSIONTYPE_PIZ;
+
+ unsigned char *mem = nullptr;
+ const char *err = nullptr;
+
+ size_t bytes = SaveEXRImageToMemory(&image, &header, &mem, &err);
- CharString utf8_filename = p_path.utf8();
- const char *err;
- int ret = SaveEXRImageToFile(&image, &header, utf8_filename.ptr(), &err);
- if (ret != TINYEXR_SUCCESS) {
+ if (bytes == 0) {
print_error(String("Saving EXR failed. Error: {0}").format(varray(err)));
return ERR_FILE_CANT_WRITE;
+ } else {
+ FileAccessRef ref = FileAccess::open(p_path, FileAccess::WRITE);
+ ERR_FAIL_COND_V(!ref, ERR_FILE_CANT_WRITE);
+ ref->store_buffer(mem, bytes);
+ free(mem);
}
return OK;
diff --git a/modules/tinyexr/register_types.cpp b/modules/tinyexr/register_types.cpp
index af05a411e1..9d0fb8729e 100644
--- a/modules/tinyexr/register_types.cpp
+++ b/modules/tinyexr/register_types.cpp
@@ -36,7 +36,6 @@
static ImageLoaderTinyEXR *image_loader_tinyexr = nullptr;
void register_tinyexr_types() {
-
image_loader_tinyexr = memnew(ImageLoaderTinyEXR);
ImageLoader::add_image_format_loader(image_loader_tinyexr);
@@ -44,7 +43,6 @@ void register_tinyexr_types() {
}
void unregister_tinyexr_types() {
-
memdelete(image_loader_tinyexr);
Image::save_exr_func = nullptr;
diff --git a/modules/upnp/register_types.cpp b/modules/upnp/register_types.cpp
index 270aa2d7e8..34900206de 100644
--- a/modules/upnp/register_types.cpp
+++ b/modules/upnp/register_types.cpp
@@ -36,7 +36,6 @@
#include "upnp_device.h"
void register_upnp_types() {
-
ClassDB::register_class<UPNP>();
ClassDB::register_class<UPNPDevice>();
}
diff --git a/modules/upnp/upnp.h b/modules/upnp/upnp.h
index 46f44e04e5..1c4b5549f4 100644
--- a/modules/upnp/upnp.h
+++ b/modules/upnp/upnp.h
@@ -38,7 +38,6 @@
#include <miniupnpc/miniupnpc.h>
class UPNP : public Reference {
-
GDCLASS(UPNP, Reference);
private:
diff --git a/modules/upnp/upnp_device.h b/modules/upnp/upnp_device.h
index f25d3427fc..4b519fce32 100644
--- a/modules/upnp/upnp_device.h
+++ b/modules/upnp/upnp_device.h
@@ -34,7 +34,6 @@
#include "core/reference.h"
class UPNPDevice : public Reference {
-
GDCLASS(UPNPDevice, Reference);
public:
diff --git a/modules/vhacd/register_types.cpp b/modules/vhacd/register_types.cpp
index c006a9deec..40c5e47440 100644
--- a/modules/vhacd/register_types.cpp
+++ b/modules/vhacd/register_types.cpp
@@ -33,7 +33,6 @@
#include "thirdparty/vhacd/public/VHACD.h"
static Vector<Vector<Face3>> convex_decompose(const Vector<Face3> &p_faces) {
-
Vector<float> vertices;
vertices.resize(p_faces.size() * 9);
Vector<uint32_t> indices;
diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp
index 5ea84a32c4..8afed1229f 100644
--- a/modules/visual_script/register_types.cpp
+++ b/modules/visual_script/register_types.cpp
@@ -47,7 +47,6 @@ static _VisualScriptEditor *vs_editor_singleton = nullptr;
#endif
void register_visual_script_types() {
-
visual_script_language = memnew(VisualScriptLanguage);
//script_language_gd->init();
ScriptServer::register_language(visual_script_language);
@@ -125,7 +124,6 @@ void register_visual_script_types() {
}
void unregister_visual_script_types() {
-
unregister_visual_script_nodes();
ScriptServer::unregister_language(visual_script_language);
@@ -136,6 +134,7 @@ void unregister_visual_script_types() {
memdelete(vs_editor_singleton);
}
#endif
- if (visual_script_language)
+ if (visual_script_language) {
memdelete(visual_script_language);
+ }
}
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index 7cc52eef36..f387c0f288 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -44,7 +44,6 @@ void VisualScriptNode::set_breakpoint(bool p_breakpoint) {
}
bool VisualScriptNode::is_breakpoint() const {
-
return breakpoint;
}
@@ -53,7 +52,6 @@ void VisualScriptNode::ports_changed_notify() {
}
void VisualScriptNode::set_default_input_value(int p_port, const Variant &p_value) {
-
ERR_FAIL_INDEX(p_port, default_input_values.size());
default_input_values[p_port] = p_value;
@@ -66,13 +64,11 @@ void VisualScriptNode::set_default_input_value(int p_port, const Variant &p_valu
}
Variant VisualScriptNode::get_default_input_value(int p_port) const {
-
ERR_FAIL_INDEX_V(p_port, default_input_values.size(), Variant());
return default_input_values[p_port];
}
void VisualScriptNode::_set_default_input_values(Array p_values) {
-
default_input_values = p_values;
}
@@ -81,7 +77,6 @@ void VisualScriptNode::validate_input_default_values() {
//actually validate on save
for (int i = 0; i < get_input_value_port_count(); i++) {
-
Variant::Type expected = get_input_value_port_info(i).type;
if (expected == Variant::NIL || expected == default_input_values[i].get_type()) {
@@ -101,7 +96,6 @@ void VisualScriptNode::validate_input_default_values() {
}
Array VisualScriptNode::_get_default_input_values() const {
-
//validate on save, since on load there is little info about this
Array values = default_input_values;
values.resize(get_input_value_port_count());
@@ -114,7 +108,6 @@ String VisualScriptNode::get_text() const {
}
void VisualScriptNode::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_visual_script"), &VisualScriptNode::get_visual_script);
ClassDB::bind_method(D_METHOD("set_default_input_value", "port_idx", "value"), &VisualScriptNode::set_default_input_value);
ClassDB::bind_method(D_METHOD("get_default_input_value", "port_idx"), &VisualScriptNode::get_default_input_value);
@@ -127,7 +120,6 @@ void VisualScriptNode::_bind_methods() {
}
VisualScriptNode::TypeGuess VisualScriptNode::guess_output_type(TypeGuess *p_inputs, int p_output) const {
-
PropertyInfo pinfo = get_output_value_port_info(p_output);
TypeGuess tg;
@@ -141,9 +133,9 @@ VisualScriptNode::TypeGuess VisualScriptNode::guess_output_type(TypeGuess *p_inp
}
Ref<VisualScript> VisualScriptNode::get_visual_script() const {
-
- if (scripts_used.size())
+ if (scripts_used.size()) {
return Ref<VisualScript>(scripts_used.front()->get());
+ }
return Ref<VisualScript>();
}
@@ -157,13 +149,11 @@ VisualScriptNode::VisualScriptNode() {
/////////////////////
VisualScriptNodeInstance::VisualScriptNodeInstance() {
-
sequence_outputs = nullptr;
input_ports = nullptr;
}
VisualScriptNodeInstance::~VisualScriptNodeInstance() {
-
if (sequence_outputs) {
memdelete_arr(sequence_outputs);
}
@@ -178,7 +168,6 @@ VisualScriptNodeInstance::~VisualScriptNodeInstance() {
}
void VisualScript::add_function(const StringName &p_name) {
-
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!String(p_name).is_valid_identifier());
ERR_FAIL_COND(functions.has(p_name));
@@ -188,16 +177,14 @@ void VisualScript::add_function(const StringName &p_name) {
}
bool VisualScript::has_function(const StringName &p_name) const {
-
return functions.has(p_name);
}
-void VisualScript::remove_function(const StringName &p_name) {
+void VisualScript::remove_function(const StringName &p_name) {
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!functions.has(p_name));
for (Map<int, Function::NodeData>::Element *E = functions[p_name].nodes.front(); E; E = E->next()) {
-
E->get().node->disconnect("ports_changed", callable_mp(this, &VisualScript::_node_ports_changed));
E->get().node->scripts_used.erase(this);
}
@@ -206,11 +193,11 @@ void VisualScript::remove_function(const StringName &p_name) {
}
void VisualScript::rename_function(const StringName &p_name, const StringName &p_new_name) {
-
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!functions.has(p_name));
- if (p_new_name == p_name)
+ if (p_new_name == p_name) {
return;
+ }
ERR_FAIL_COND(!String(p_new_name).is_valid_identifier());
@@ -223,19 +210,16 @@ void VisualScript::rename_function(const StringName &p_name, const StringName &p
}
void VisualScript::set_function_scroll(const StringName &p_name, const Vector2 &p_scroll) {
-
ERR_FAIL_COND(!functions.has(p_name));
functions[p_name].scroll = p_scroll;
}
Vector2 VisualScript::get_function_scroll(const StringName &p_name) const {
-
ERR_FAIL_COND_V(!functions.has(p_name), Vector2());
return functions[p_name].scroll;
}
void VisualScript::get_function_list(List<StringName> *r_functions) const {
-
for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
r_functions->push_back(E->key());
}
@@ -244,18 +228,15 @@ void VisualScript::get_function_list(List<StringName> *r_functions) const {
}
int VisualScript::get_function_node_id(const StringName &p_name) const {
-
ERR_FAIL_COND_V(!functions.has(p_name), -1);
return functions[p_name].function_id;
}
void VisualScript::_node_ports_changed(int p_id) {
-
StringName function;
for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
-
if (E->get().nodes.has(p_id)) {
function = E->key();
break;
@@ -276,11 +257,9 @@ void VisualScript::_node_ports_changed(int p_id) {
for (Set<SequenceConnection>::Element *E = func.sequence_connections.front(); E; E = E->next()) {
if (E->get().from_node == p_id && E->get().from_output >= vsn->get_output_sequence_port_count()) {
-
to_remove.push_back(E->get());
}
if (E->get().to_node == p_id && !vsn->has_input_sequence_port()) {
-
to_remove.push_back(E->get());
}
}
@@ -292,7 +271,6 @@ void VisualScript::_node_ports_changed(int p_id) {
}
{
-
List<DataConnection> to_remove;
for (Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) {
@@ -317,12 +295,10 @@ void VisualScript::_node_ports_changed(int p_id) {
}
void VisualScript::add_node(const StringName &p_func, int p_id, const Ref<VisualScriptNode> &p_node, const Point2 &p_pos) {
-
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!functions.has(p_func));
for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
-
ERR_FAIL_COND(E->get().nodes.has(p_id)); //id can exist only one in script, even for different functions
}
@@ -348,7 +324,6 @@ void VisualScript::add_node(const StringName &p_func, int p_id, const Ref<Visual
}
void VisualScript::remove_node(const StringName &p_func, int p_id) {
-
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!functions.has(p_func));
Function &func = functions[p_func];
@@ -370,7 +345,6 @@ void VisualScript::remove_node(const StringName &p_func, int p_id) {
}
{
-
List<DataConnection> to_remove;
for (Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) {
@@ -396,7 +370,6 @@ void VisualScript::remove_node(const StringName &p_func, int p_id) {
}
bool VisualScript::has_node(const StringName &p_func, int p_id) const {
-
ERR_FAIL_COND_V(!functions.has(p_func), false);
const Function &func = functions[p_func];
@@ -404,7 +377,6 @@ bool VisualScript::has_node(const StringName &p_func, int p_id) const {
}
Ref<VisualScriptNode> VisualScript::get_node(const StringName &p_func, int p_id) const {
-
ERR_FAIL_COND_V(!functions.has(p_func), Ref<VisualScriptNode>());
const Function &func = functions[p_func];
@@ -414,7 +386,6 @@ Ref<VisualScriptNode> VisualScript::get_node(const StringName &p_func, int p_id)
}
void VisualScript::set_node_position(const StringName &p_func, int p_id, const Point2 &p_pos) {
-
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!functions.has(p_func));
Function &func = functions[p_func];
@@ -424,7 +395,6 @@ void VisualScript::set_node_position(const StringName &p_func, int p_id, const P
}
Point2 VisualScript::get_node_position(const StringName &p_func, int p_id) const {
-
ERR_FAIL_COND_V(!functions.has(p_func), Point2());
const Function &func = functions[p_func];
@@ -433,7 +403,6 @@ Point2 VisualScript::get_node_position(const StringName &p_func, int p_id) const
}
void VisualScript::get_node_list(const StringName &p_func, List<int> *r_nodes) const {
-
ERR_FAIL_COND(!functions.has(p_func));
const Function &func = functions[p_func];
@@ -443,7 +412,6 @@ void VisualScript::get_node_list(const StringName &p_func, List<int> *r_nodes) c
}
void VisualScript::sequence_connect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) {
-
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!functions.has(p_func));
Function &func = functions[p_func];
@@ -458,7 +426,6 @@ void VisualScript::sequence_connect(const StringName &p_func, int p_from_node, i
}
void VisualScript::sequence_disconnect(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) {
-
ERR_FAIL_COND(!functions.has(p_func));
Function &func = functions[p_func];
@@ -472,7 +439,6 @@ void VisualScript::sequence_disconnect(const StringName &p_func, int p_from_node
}
bool VisualScript::has_sequence_connection(const StringName &p_func, int p_from_node, int p_from_output, int p_to_node) const {
-
ERR_FAIL_COND_V(!functions.has(p_func), false);
const Function &func = functions[p_func];
@@ -485,7 +451,6 @@ bool VisualScript::has_sequence_connection(const StringName &p_func, int p_from_
}
void VisualScript::get_sequence_connection_list(const StringName &p_func, List<SequenceConnection> *r_connection) const {
-
ERR_FAIL_COND(!functions.has(p_func));
const Function &func = functions[p_func];
@@ -495,7 +460,6 @@ void VisualScript::get_sequence_connection_list(const StringName &p_func, List<S
}
void VisualScript::data_connect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
-
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!functions.has(p_func));
Function &func = functions[p_func];
@@ -512,7 +476,6 @@ void VisualScript::data_connect(const StringName &p_func, int p_from_node, int p
}
void VisualScript::data_disconnect(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) {
-
ERR_FAIL_COND(!functions.has(p_func));
Function &func = functions[p_func];
@@ -528,7 +491,6 @@ void VisualScript::data_disconnect(const StringName &p_func, int p_from_node, in
}
bool VisualScript::has_data_connection(const StringName &p_func, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
-
ERR_FAIL_COND_V(!functions.has(p_func), false);
const Function &func = functions[p_func];
@@ -542,20 +504,19 @@ bool VisualScript::has_data_connection(const StringName &p_func, int p_from_node
}
bool VisualScript::is_input_value_port_connected(const StringName &p_func, int p_node, int p_port) const {
-
ERR_FAIL_COND_V(!functions.has(p_func), false);
const Function &func = functions[p_func];
for (const Set<DataConnection>::Element *E = func.data_connections.front(); E; E = E->next()) {
- if (E->get().to_node == p_node && E->get().to_port == p_port)
+ if (E->get().to_node == p_node && E->get().to_port == p_port) {
return true;
+ }
}
return false;
}
bool VisualScript::get_input_value_port_connection_source(const StringName &p_func, int p_node, int p_port, int *r_node, int *r_port) const {
-
ERR_FAIL_COND_V(!functions.has(p_func), false);
const Function &func = functions[p_func];
@@ -571,7 +532,6 @@ bool VisualScript::get_input_value_port_connection_source(const StringName &p_fu
}
void VisualScript::get_data_connection_list(const StringName &p_func, List<DataConnection> *r_connection) const {
-
ERR_FAIL_COND(!functions.has(p_func));
const Function &func = functions[p_func];
@@ -585,7 +545,6 @@ void VisualScript::set_tool_enabled(bool p_enabled) {
}
void VisualScript::add_variable(const StringName &p_name, const Variant &p_default_value, bool p_export) {
-
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!String(p_name).is_valid_identifier());
ERR_FAIL_COND(variables.has(p_name));
@@ -605,12 +564,10 @@ void VisualScript::add_variable(const StringName &p_name, const Variant &p_defau
}
bool VisualScript::has_variable(const StringName &p_name) const {
-
return variables.has(p_name);
}
void VisualScript::remove_variable(const StringName &p_name) {
-
ERR_FAIL_COND(!variables.has(p_name));
variables.erase(p_name);
@@ -620,7 +577,6 @@ void VisualScript::remove_variable(const StringName &p_name) {
}
void VisualScript::set_variable_default_value(const StringName &p_name, const Variant &p_value) {
-
ERR_FAIL_COND(!variables.has(p_name));
variables[p_name].default_value = p_value;
@@ -629,13 +585,13 @@ void VisualScript::set_variable_default_value(const StringName &p_name, const Va
_update_placeholders();
#endif
}
-Variant VisualScript::get_variable_default_value(const StringName &p_name) const {
+Variant VisualScript::get_variable_default_value(const StringName &p_name) const {
ERR_FAIL_COND_V(!variables.has(p_name), Variant());
return variables[p_name].default_value;
}
-void VisualScript::set_variable_info(const StringName &p_name, const PropertyInfo &p_info) {
+void VisualScript::set_variable_info(const StringName &p_name, const PropertyInfo &p_info) {
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!variables.has(p_name));
variables[p_name].info = p_info;
@@ -645,14 +601,13 @@ void VisualScript::set_variable_info(const StringName &p_name, const PropertyInf
_update_placeholders();
#endif
}
-PropertyInfo VisualScript::get_variable_info(const StringName &p_name) const {
+PropertyInfo VisualScript::get_variable_info(const StringName &p_name) const {
ERR_FAIL_COND_V(!variables.has(p_name), PropertyInfo());
return variables[p_name].info;
}
void VisualScript::set_variable_export(const StringName &p_name, bool p_export) {
-
ERR_FAIL_COND(!variables.has(p_name));
variables[p_name]._export = p_export;
@@ -662,30 +617,32 @@ void VisualScript::set_variable_export(const StringName &p_name, bool p_export)
}
bool VisualScript::get_variable_export(const StringName &p_name) const {
-
ERR_FAIL_COND_V(!variables.has(p_name), false);
return variables[p_name]._export;
}
void VisualScript::_set_variable_info(const StringName &p_name, const Dictionary &p_info) {
-
PropertyInfo pinfo;
- if (p_info.has("type"))
+ if (p_info.has("type")) {
pinfo.type = Variant::Type(int(p_info["type"]));
- if (p_info.has("name"))
+ }
+ if (p_info.has("name")) {
pinfo.name = p_info["name"];
- if (p_info.has("hint"))
+ }
+ if (p_info.has("hint")) {
pinfo.hint = PropertyHint(int(p_info["hint"]));
- if (p_info.has("hint_string"))
+ }
+ if (p_info.has("hint_string")) {
pinfo.hint_string = p_info["hint_string"];
- if (p_info.has("usage"))
+ }
+ if (p_info.has("usage")) {
pinfo.usage = p_info["usage"];
+ }
set_variable_info(p_name, pinfo);
}
Dictionary VisualScript::_get_variable_info(const StringName &p_name) const {
-
PropertyInfo pinfo = get_variable_info(p_name);
Dictionary d;
d["type"] = pinfo.type;
@@ -698,7 +655,6 @@ Dictionary VisualScript::_get_variable_info(const StringName &p_name) const {
}
void VisualScript::get_variable_list(List<StringName> *r_variables) const {
-
for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) {
r_variables->push_back(E->key());
}
@@ -707,17 +663,16 @@ void VisualScript::get_variable_list(List<StringName> *r_variables) const {
}
void VisualScript::set_instance_base_type(const StringName &p_type) {
-
ERR_FAIL_COND(instances.size());
base_type = p_type;
}
void VisualScript::rename_variable(const StringName &p_name, const StringName &p_new_name) {
-
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!variables.has(p_name));
- if (p_new_name == p_name)
+ if (p_new_name == p_name) {
return;
+ }
ERR_FAIL_COND(!String(p_new_name).is_valid_identifier());
@@ -736,13 +691,15 @@ void VisualScript::rename_variable(const StringName &p_name, const StringName &p
for (List<int>::Element *E = ids.front(); E; E = E->next()) {
Ref<VisualScriptVariableGet> nodeget = get_node(F->get(), E->get());
if (nodeget.is_valid()) {
- if (nodeget->get_variable() == p_name)
+ if (nodeget->get_variable() == p_name) {
nodeget->set_variable(p_new_name);
+ }
} else {
Ref<VisualScriptVariableSet> nodeset = get_node(F->get(), E->get());
if (nodeset.is_valid()) {
- if (nodeset->get_variable() == p_name)
+ if (nodeset->get_variable() == p_name) {
nodeset->set_variable(p_new_name);
+ }
}
}
}
@@ -750,7 +707,6 @@ void VisualScript::rename_variable(const StringName &p_name, const StringName &p
}
void VisualScript::add_custom_signal(const StringName &p_name) {
-
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!String(p_name).is_valid_identifier());
ERR_FAIL_COND(custom_signals.has(p_name));
@@ -759,48 +715,49 @@ void VisualScript::add_custom_signal(const StringName &p_name) {
}
bool VisualScript::has_custom_signal(const StringName &p_name) const {
-
return custom_signals.has(p_name);
}
-void VisualScript::custom_signal_add_argument(const StringName &p_func, Variant::Type p_type, const String &p_name, int p_index) {
+void VisualScript::custom_signal_add_argument(const StringName &p_func, Variant::Type p_type, const String &p_name, int p_index) {
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!custom_signals.has(p_func));
Argument arg;
arg.type = p_type;
arg.name = p_name;
- if (p_index < 0)
+ if (p_index < 0) {
custom_signals[p_func].push_back(arg);
- else
+ } else {
custom_signals[p_func].insert(0, arg);
+ }
}
-void VisualScript::custom_signal_set_argument_type(const StringName &p_func, int p_argidx, Variant::Type p_type) {
+void VisualScript::custom_signal_set_argument_type(const StringName &p_func, int p_argidx, Variant::Type p_type) {
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!custom_signals.has(p_func));
ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size());
custom_signals[p_func].write[p_argidx].type = p_type;
}
-Variant::Type VisualScript::custom_signal_get_argument_type(const StringName &p_func, int p_argidx) const {
+Variant::Type VisualScript::custom_signal_get_argument_type(const StringName &p_func, int p_argidx) const {
ERR_FAIL_COND_V(!custom_signals.has(p_func), Variant::NIL);
ERR_FAIL_INDEX_V(p_argidx, custom_signals[p_func].size(), Variant::NIL);
return custom_signals[p_func][p_argidx].type;
}
+
void VisualScript::custom_signal_set_argument_name(const StringName &p_func, int p_argidx, const String &p_name) {
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!custom_signals.has(p_func));
ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size());
custom_signals[p_func].write[p_argidx].name = p_name;
}
-String VisualScript::custom_signal_get_argument_name(const StringName &p_func, int p_argidx) const {
+String VisualScript::custom_signal_get_argument_name(const StringName &p_func, int p_argidx) const {
ERR_FAIL_COND_V(!custom_signals.has(p_func), String());
ERR_FAIL_INDEX_V(p_argidx, custom_signals[p_func].size(), String());
return custom_signals[p_func][p_argidx].name;
}
-void VisualScript::custom_signal_remove_argument(const StringName &p_func, int p_argidx) {
+void VisualScript::custom_signal_remove_argument(const StringName &p_func, int p_argidx) {
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!custom_signals.has(p_func));
ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size());
@@ -808,12 +765,11 @@ void VisualScript::custom_signal_remove_argument(const StringName &p_func, int p
}
int VisualScript::custom_signal_get_argument_count(const StringName &p_func) const {
-
ERR_FAIL_COND_V(!custom_signals.has(p_func), 0);
return custom_signals[p_func].size();
}
-void VisualScript::custom_signal_swap_argument(const StringName &p_func, int p_argidx, int p_with_argidx) {
+void VisualScript::custom_signal_swap_argument(const StringName &p_func, int p_argidx, int p_with_argidx) {
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!custom_signals.has(p_func));
ERR_FAIL_INDEX(p_argidx, custom_signals[p_func].size());
@@ -821,19 +777,19 @@ void VisualScript::custom_signal_swap_argument(const StringName &p_func, int p_a
SWAP(custom_signals[p_func].write[p_argidx], custom_signals[p_func].write[p_with_argidx]);
}
-void VisualScript::remove_custom_signal(const StringName &p_name) {
+void VisualScript::remove_custom_signal(const StringName &p_name) {
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!custom_signals.has(p_name));
custom_signals.erase(p_name);
}
void VisualScript::rename_custom_signal(const StringName &p_name, const StringName &p_new_name) {
-
ERR_FAIL_COND(instances.size());
ERR_FAIL_COND(!custom_signals.has(p_name));
- if (p_new_name == p_name)
+ if (p_new_name == p_name) {
return;
+ }
ERR_FAIL_COND(!String(p_new_name).is_valid_identifier());
@@ -846,7 +802,6 @@ void VisualScript::rename_custom_signal(const StringName &p_name, const StringNa
}
void VisualScript::get_custom_signal_list(List<StringName> *r_custom_signals) const {
-
for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) {
r_custom_signals->push_back(E->key());
}
@@ -855,11 +810,11 @@ void VisualScript::get_custom_signal_list(List<StringName> *r_custom_signals) co
}
int VisualScript::get_available_id() const {
-
int max_id = 0;
for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
- if (E->get().nodes.empty())
+ if (E->get().nodes.empty()) {
continue;
+ }
int last_id = E->get().nodes.back()->key();
max_id = MAX(max_id, last_id + 1);
@@ -871,12 +826,10 @@ int VisualScript::get_available_id() const {
/////////////////////////////////
bool VisualScript::can_instance() const {
-
return true; //ScriptServer::is_scripting_enabled();
}
StringName VisualScript::get_instance_base_type() const {
-
return base_type;
}
@@ -886,21 +839,20 @@ Ref<Script> VisualScript::get_base_script() const {
#ifdef TOOLS_ENABLED
void VisualScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {
-
placeholders.erase(p_placeholder);
}
void VisualScript::_update_placeholders() {
-
- if (placeholders.size() == 0)
+ if (placeholders.size() == 0) {
return; //no bother if no placeholders
+ }
List<PropertyInfo> pinfo;
Map<StringName, Variant> values;
for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) {
-
- if (!E->get()._export)
+ if (!E->get()._export) {
continue;
+ }
PropertyInfo p = E->get().info;
p.name = String(E->key());
@@ -909,7 +861,6 @@ void VisualScript::_update_placeholders() {
}
for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
-
E->get()->update(pinfo, values);
}
}
@@ -917,11 +868,9 @@ void VisualScript::_update_placeholders() {
#endif
ScriptInstance *VisualScript::instance_create(Object *p_this) {
-
#ifdef TOOLS_ENABLED
if (!ScriptServer::is_scripting_enabled() && !is_tool_script) {
-
PlaceHolderScriptInstance *sins = memnew(PlaceHolderScriptInstance(VisualScriptLanguage::singleton, Ref<Script>((Script *)this), p_this));
placeholders.insert(sins);
@@ -929,9 +878,9 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) {
Map<StringName, Variant> values;
for (Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) {
-
- if (!E->get()._export)
+ if (!E->get()._export) {
continue;
+ }
PropertyInfo p = E->get().info;
p.name = String(E->key());
@@ -958,17 +907,14 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) {
}
bool VisualScript::instance_has(const Object *p_this) const {
-
return instances.has((Object *)p_this);
}
bool VisualScript::has_source_code() const {
-
return false;
}
String VisualScript::get_source_code() const {
-
return String();
}
@@ -976,12 +922,10 @@ void VisualScript::set_source_code(const String &p_code) {
}
Error VisualScript::reload(bool p_keep_state) {
-
return OK;
}
bool VisualScript::is_tool() const {
-
return is_tool_script;
}
@@ -990,19 +934,15 @@ bool VisualScript::is_valid() const {
}
ScriptLanguage *VisualScript::get_language() const {
-
return VisualScriptLanguage::singleton;
}
bool VisualScript::has_script_signal(const StringName &p_signal) const {
-
return custom_signals.has(p_signal);
}
void VisualScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
-
for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) {
-
MethodInfo mi;
mi.name = E->key();
for (int i = 0; i < E->get().size(); i++) {
@@ -1017,21 +957,19 @@ void VisualScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
}
bool VisualScript::get_property_default_value(const StringName &p_property, Variant &r_value) const {
-
- if (!variables.has(p_property))
+ if (!variables.has(p_property)) {
return false;
+ }
r_value = variables[p_property].default_value;
return true;
}
-void VisualScript::get_script_method_list(List<MethodInfo> *p_list) const {
+void VisualScript::get_script_method_list(List<MethodInfo> *p_list) const {
for (Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
-
MethodInfo mi;
mi.name = E->key();
if (E->get().function_id >= 0) {
-
Ref<VisualScriptFunction> func = E->get().nodes[E->get().function_id].node;
if (func.is_valid()) {
for (int i = 0; i < func->get_argument_count(); i++) {
@@ -1048,22 +986,20 @@ void VisualScript::get_script_method_list(List<MethodInfo> *p_list) const {
}
bool VisualScript::has_method(const StringName &p_method) const {
-
return functions.has(p_method);
}
-MethodInfo VisualScript::get_method_info(const StringName &p_method) const {
+MethodInfo VisualScript::get_method_info(const StringName &p_method) const {
const Map<StringName, Function>::Element *E = functions.find(p_method);
- if (!E)
+ if (!E) {
return MethodInfo();
+ }
MethodInfo mi;
mi.name = E->key();
if (E->get().function_id >= 0) {
-
Ref<VisualScriptFunction> func = E->get().nodes[E->get().function_id].node;
if (func.is_valid()) {
-
for (int i = 0; i < func->get_argument_count(); i++) {
PropertyInfo arg;
arg.name = func->get_argument_name(i);
@@ -1081,7 +1017,6 @@ MethodInfo VisualScript::get_method_info(const StringName &p_method) const {
}
void VisualScript::get_script_property_list(List<PropertyInfo> *p_list) const {
-
List<StringName> vars;
get_variable_list(&vars);
@@ -1098,8 +1033,9 @@ int VisualScript::get_member_line(const StringName &p_member) const {
#ifdef TOOLS_ENABLED
if (has_function(p_member)) {
for (Map<int, Function::NodeData>::Element *E = functions[p_member].nodes.front(); E; E = E->next()) {
- if (Object::cast_to<VisualScriptFunction>(E->get().node.ptr()))
+ if (Object::cast_to<VisualScriptFunction>(E->get().node.ptr())) {
return E->key();
+ }
}
}
#endif
@@ -1108,9 +1044,7 @@ int VisualScript::get_member_line(const StringName &p_member) const {
#ifdef TOOLS_ENABLED
bool VisualScript::are_subnodes_edited() const {
-
for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
-
for (const Map<int, Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) {
if (F->get().node->is_edited()) {
return true;
@@ -1177,15 +1111,14 @@ MultiplayerAPI::RPCMode VisualScript::get_rset_mode(const StringName &p_variable
}
void VisualScript::_set_data(const Dictionary &p_data) {
-
Dictionary d = p_data;
- if (d.has("base_type"))
+ if (d.has("base_type")) {
base_type = d["base_type"];
+ }
variables.clear();
Array vars = d["variables"];
for (int i = 0; i < vars.size(); i++) {
-
Dictionary v = vars[i];
StringName name = v["name"];
add_variable(name);
@@ -1197,7 +1130,6 @@ void VisualScript::_set_data(const Dictionary &p_data) {
custom_signals.clear();
Array sigs = d["signals"];
for (int i = 0; i < sigs.size(); i++) {
-
Dictionary cs = sigs[i];
add_custom_signal(cs["name"]);
@@ -1214,7 +1146,6 @@ void VisualScript::_set_data(const Dictionary &p_data) {
Vector2 last_size = Vector2(0.0, 0.0);
for (int i = 0; i < funcs.size(); i++) {
-
Dictionary func = funcs[i];
StringName name = func["name"];
@@ -1264,22 +1195,21 @@ void VisualScript::_set_data(const Dictionary &p_data) {
Array sequence_connections = func["sequence_connections"];
for (int j = 0; j < sequence_connections.size(); j += 3) {
-
sequence_connect(name, sequence_connections[j + 0], sequence_connections[j + 1], sequence_connections[j + 2]);
}
Array data_connections = func["data_connections"];
for (int j = 0; j < data_connections.size(); j += 4) {
-
data_connect(name, data_connections[j + 0], data_connections[j + 1], data_connections[j + 2], data_connections[j + 3]);
}
}
- if (d.has("is_tool_script"))
+ if (d.has("is_tool_script")) {
is_tool_script = d["is_tool_script"];
- else
+ } else {
is_tool_script = false;
+ }
// Takes all the rpc methods
rpc_functions.clear();
@@ -1307,12 +1237,10 @@ void VisualScript::_set_data(const Dictionary &p_data) {
}
Dictionary VisualScript::_get_data() const {
-
Dictionary d;
d["base_type"] = base_type;
Array vars;
for (const Map<StringName, Variable>::Element *E = variables.front(); E; E = E->next()) {
-
Dictionary var = _get_variable_info(E->key());
var["name"] = E->key(); //make sure it's the right one
var["default_value"] = E->get().default_value;
@@ -1323,7 +1251,6 @@ Dictionary VisualScript::_get_data() const {
Array sigs;
for (const Map<StringName, Vector<Argument>>::Element *E = custom_signals.front(); E; E = E->next()) {
-
Dictionary cs;
cs["name"] = E->key();
Array args;
@@ -1341,7 +1268,6 @@ Dictionary VisualScript::_get_data() const {
Array funcs;
for (const Map<StringName, Function>::Element *E = functions.front(); E; E = E->next()) {
-
Dictionary func;
func["name"] = E->key();
func["function_id"] = E->get().function_id;
@@ -1350,7 +1276,6 @@ Dictionary VisualScript::_get_data() const {
Array nodes;
for (const Map<int, Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) {
-
nodes.push_back(F->key());
nodes.push_back(F->get().pos);
nodes.push_back(F->get().node);
@@ -1361,7 +1286,6 @@ Dictionary VisualScript::_get_data() const {
Array sequence_connections;
for (const Set<SequenceConnection>::Element *F = E->get().sequence_connections.front(); F; F = F->next()) {
-
sequence_connections.push_back(F->get().from_node);
sequence_connections.push_back(F->get().from_output);
sequence_connections.push_back(F->get().to_node);
@@ -1372,7 +1296,6 @@ Dictionary VisualScript::_get_data() const {
Array data_connections;
for (const Set<DataConnection>::Element *F = E->get().data_connections.front(); F; F = F->next()) {
-
data_connections.push_back(F->get().from_node);
data_connections.push_back(F->get().from_port);
data_connections.push_back(F->get().to_node);
@@ -1392,7 +1315,6 @@ Dictionary VisualScript::_get_data() const {
}
void VisualScript::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_function", "name"), &VisualScript::add_function);
ClassDB::bind_method(D_METHOD("has_function", "name"), &VisualScript::has_function);
ClassDB::bind_method(D_METHOD("remove_function", "name"), &VisualScript::remove_function);
@@ -1455,11 +1377,14 @@ void VisualScript::_bind_methods() {
}
VisualScript::VisualScript() {
-
base_type = "Object";
is_tool_script = false;
}
+bool VisualScript::inherits_script(const Ref<Script> &p_script) const {
+ return this == p_script.ptr(); //there is no inheritance in visual scripts, so this is enough
+}
+
StringName VisualScript::get_default_func() const {
return StringName("f_312843592");
}
@@ -1478,7 +1403,6 @@ Set<int> VisualScript::get_output_sequence_ports_connected(const String &edited_
}
VisualScript::~VisualScript() {
-
while (!functions.empty()) {
remove_function(functions.front()->key());
}
@@ -1487,10 +1411,10 @@ VisualScript::~VisualScript() {
////////////////////////////////////////////
bool VisualScriptInstance::set(const StringName &p_name, const Variant &p_value) {
-
Map<StringName, Variant>::Element *E = variables.find(p_name);
- if (!E)
+ if (!E) {
return false;
+ }
E->get() = p_value;
@@ -1498,45 +1422,45 @@ bool VisualScriptInstance::set(const StringName &p_name, const Variant &p_value)
}
bool VisualScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
-
const Map<StringName, Variant>::Element *E = variables.find(p_name);
- if (!E)
+ if (!E) {
return false;
+ }
r_ret = E->get();
return true;
}
-void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const {
+void VisualScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const {
for (const Map<StringName, VisualScript::Variable>::Element *E = script->variables.front(); E; E = E->next()) {
-
- if (!E->get()._export)
+ if (!E->get()._export) {
continue;
+ }
PropertyInfo p = E->get().info;
p.name = String(E->key());
p.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
p_properties->push_back(p);
}
}
-Variant::Type VisualScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
+Variant::Type VisualScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
const Map<StringName, VisualScript::Variable>::Element *E = script->variables.find(p_name);
if (!E) {
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = false;
+ }
ERR_FAIL_V(Variant::NIL);
}
- if (r_is_valid)
+ if (r_is_valid) {
*r_is_valid = true;
+ }
return E->get().info.type;
}
void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
-
for (const Map<StringName, VisualScript::Function>::Element *E = script->functions.front(); E; E = E->next()) {
-
if (E->key() == script->get_default_func()) {
continue;
}
@@ -1544,10 +1468,8 @@ void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
MethodInfo mi;
mi.name = E->key();
if (E->get().function_id >= 0 && E->get().nodes.has(E->get().function_id)) {
-
Ref<VisualScriptFunction> vsf = E->get().nodes[E->get().function_id].node;
if (vsf.is_valid()) {
-
for (int i = 0; i < vsf->get_argument_count(); i++) {
PropertyInfo arg;
arg.name = vsf->get_argument_name(i);
@@ -1565,10 +1487,11 @@ void VisualScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
p_list->push_back(mi);
}
}
-bool VisualScriptInstance::has_method(const StringName &p_method) const {
- if (p_method == script->get_default_func())
+bool VisualScriptInstance::has_method(const StringName &p_method) const {
+ if (p_method == script->get_default_func()) {
return false;
+ }
return script->functions.has(p_method);
}
@@ -1577,29 +1500,27 @@ bool VisualScriptInstance::has_method(const StringName &p_method) const {
#define VSDEBUG(m_text)
void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int p_pass, int *pass_stack, const Variant **input_args, Variant **output_args, Variant *variant_stack, Callable::CallError &r_error, String &error_str, VisualScriptNodeInstance **r_error_node) {
-
ERR_FAIL_COND(node->pass_idx == -1);
- if (pass_stack[node->pass_idx] == p_pass)
+ if (pass_stack[node->pass_idx] == p_pass) {
return;
+ }
pass_stack[node->pass_idx] = p_pass;
if (!node->dependencies.empty()) {
-
int dc = node->dependencies.size();
VisualScriptNodeInstance **deps = node->dependencies.ptrw();
for (int i = 0; i < dc; i++) {
-
_dependency_step(deps[i], p_pass, pass_stack, input_args, output_args, variant_stack, r_error, error_str, r_error_node);
- if (r_error.error != Callable::CallError::CALL_OK)
+ if (r_error.error != Callable::CallError::CALL_OK) {
return;
+ }
}
}
for (int i = 0; i < node->input_port_count; i++) {
-
int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK;
if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
@@ -1624,7 +1545,6 @@ void VisualScriptInstance::_dependency_step(VisualScriptNodeInstance *node, int
}
Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p_stack, int p_stack_size, VisualScriptNodeInstance *p_node, int p_flow_stack_pos, int p_pass, bool p_resuming_yield, Callable::CallError &r_error) {
-
Map<StringName, Function>::Element *F = functions.find(p_method);
ERR_FAIL_COND_V(!F, Variant());
Function *f = &F->get();
@@ -1655,7 +1575,6 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
#endif
while (true) {
-
p_pass++; //increment pass
current_node_id = node->get_id();
@@ -1674,16 +1593,13 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
input_args[i] = &variant_stack[i];
}
} else {
-
//run dependencies first
if (!node->dependencies.empty()) {
-
int dc = node->dependencies.size();
VisualScriptNodeInstance **deps = node->dependencies.ptrw();
for (int i = 0; i < dc; i++) {
-
_dependency_step(deps[i], p_pass, pass_stack, input_args, output_args, variant_stack, r_error, error_str, &node);
if (r_error.error != Callable::CallError::CALL_OK) {
error = true;
@@ -1694,12 +1610,10 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
}
if (!error) {
-
//setup input pointers normally
VSDEBUG("INPUT PORTS: " + itos(node->input_port_count));
for (int i = 0; i < node->input_port_count; i++) {
-
int index = node->input_ports[i] & VisualScriptNodeInstance::INPUT_MASK;
if (node->input_ports[i] & VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT) {
@@ -1715,8 +1629,9 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
}
}
- if (error)
+ if (error) {
break;
+ }
//setup output pointers
@@ -1762,7 +1677,6 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
} else {
Ref<VisualScriptFunctionState> state = *working_mem;
if (!state.is_valid()) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
error_str = RTR("Node yielded, but did not return a function state in the first working memory.");
error = true;
@@ -1801,15 +1715,17 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
bool do_break = false;
if (EngineDebugger::get_script_debugger()->get_lines_left() > 0) {
-
- if (EngineDebugger::get_script_debugger()->get_depth() <= 0)
+ if (EngineDebugger::get_script_debugger()->get_depth() <= 0) {
EngineDebugger::get_script_debugger()->set_lines_left(EngineDebugger::get_script_debugger()->get_lines_left() - 1);
- if (EngineDebugger::get_script_debugger()->get_lines_left() <= 0)
+ }
+ if (EngineDebugger::get_script_debugger()->get_lines_left() <= 0) {
do_break = true;
+ }
}
- if (EngineDebugger::get_script_debugger()->is_breakpoint(current_node_id, source))
+ if (EngineDebugger::get_script_debugger()->is_breakpoint(current_node_id, source)) {
do_break = true;
+ }
if (do_break) {
VisualScriptLanguage::singleton->debug_break("Breakpoint", true);
@@ -1824,7 +1740,6 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
if (ret & VisualScriptNodeInstance::STEP_EXIT_FUNCTION_BIT) {
if (node->get_working_memory_size() == 0) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
error_str = RTR("Return value must be assigned to first element of node working memory! Fix your node please.");
error = true;
@@ -1857,13 +1772,11 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
}
if (flow_stack) {
-
//update flow stack pos (may have changed)
flow_stack[flow_stack_pos] = current_node_id;
//add stack push bit if requested
if (ret & VisualScriptNodeInstance::STEP_FLAG_PUSH_STACK_BIT) {
-
flow_stack[flow_stack_pos] |= VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT;
sequence_bits[node->sequence_index] = true; //remember sequence bit
VSDEBUG("NEXT SEQ - FLAG BIT");
@@ -1884,7 +1797,6 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
break; //simply exit without value or error
}
} else if (next) {
-
if (sequence_bits[next->sequence_index]) {
// what happened here is that we are entering a node that is in the middle of doing a sequence (pushed stack) from the front
// because each node has a working memory, we can't really do a sub-sequence
@@ -1894,7 +1806,6 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
bool found = false;
for (int i = flow_stack_pos; i >= 0; i--) {
-
if ((flow_stack[i] & VisualScriptNodeInstance::FLOW_STACK_MASK) == next->get_id()) {
flow_stack_pos = i; //roll back and remove bit
flow_stack[i] = next->get_id();
@@ -1936,10 +1847,8 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
bool found = false;
for (int i = flow_stack_pos; i >= 0; i--) {
-
VSDEBUG("FS " + itos(i) + " - " + itos(flow_stack[i]));
if (flow_stack[i] & VisualScriptNodeInstance::FLOW_STACK_PUSHED_BIT) {
-
node = instances[flow_stack[i] & VisualScriptNodeInstance::FLOW_STACK_MASK];
flow_stack_pos = i;
found = true;
@@ -1955,13 +1864,11 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
VSDEBUG("NO NEXT NODE, GO BACK TO: " + itos(flow_stack_pos));
}
} else {
-
node = next; //stackless mode, simply assign next node
}
}
if (error) {
-
//error
// function, file, line, error, explanation
String err_file = script->get_path();
@@ -1969,7 +1876,6 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
int err_line = current_node_id; //not a line but it works as one
if (node && (r_error.error != Callable::CallError::CALL_ERROR_INVALID_METHOD || error_str == String())) {
-
if (error_str != String()) {
error_str += " ";
}
@@ -1992,13 +1898,11 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
// debugger break did not happen
if (!VisualScriptLanguage::singleton->debug_break(error_str, false)) {
-
_err_print_error(err_func.utf8().get_data(), err_file.utf8().get_data(), err_line, error_str.utf8().get_data(), ERR_HANDLER_SCRIPT);
}
//}
} else {
-
//return_value=
}
@@ -2017,7 +1921,6 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p
}
Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
r_error.error = Callable::CallError::CALL_OK; //ok by default
Map<StringName, Function>::Element *F = functions.find(p_method);
@@ -2105,7 +2008,6 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p
}
void VisualScriptInstance::notification(int p_notification) {
-
//do nothing as this is called using virtual
Variant what = p_notification;
@@ -2120,22 +2022,24 @@ String VisualScriptInstance::to_string(bool *r_valid) {
Variant ret = call(CoreStringNames::get_singleton()->_to_string, nullptr, 0, ce);
if (ce.error == Callable::CallError::CALL_OK) {
if (ret.get_type() != Variant::STRING) {
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
ERR_FAIL_V_MSG(String(), "Wrong type for " + CoreStringNames::get_singleton()->_to_string + ", must be a String.");
}
- if (r_valid)
+ if (r_valid) {
*r_valid = true;
+ }
return ret.operator String();
}
}
- if (r_valid)
+ if (r_valid) {
*r_valid = false;
+ }
return String();
}
Ref<Script> VisualScriptInstance::get_script() const {
-
return script;
}
@@ -2180,7 +2084,6 @@ MultiplayerAPI::RPCMode VisualScriptInstance::get_rset_mode(const StringName &p_
}
void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_owner) {
-
script = p_script;
owner = p_owner;
source = p_script->get_path();
@@ -2191,16 +2094,21 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
if (Object::cast_to<Node>(p_owner)) {
//turn on these if they exist and base is a node
Node *node = Object::cast_to<Node>(p_owner);
- if (p_script->functions.has("_process"))
+ if (p_script->functions.has("_process")) {
node->set_process(true);
- if (p_script->functions.has("_physics_process"))
+ }
+ if (p_script->functions.has("_physics_process")) {
node->set_physics_process(true);
- if (p_script->functions.has("_input"))
+ }
+ if (p_script->functions.has("_input")) {
node->set_process_input(true);
- if (p_script->functions.has("_unhandled_input"))
+ }
+ if (p_script->functions.has("_unhandled_input")) {
node->set_process_unhandled_input(true);
- if (p_script->functions.has("_unhandled_key_input"))
+ }
+ if (p_script->functions.has("_unhandled_key_input")) {
node->set_process_unhandled_key_input(true);
+ }
}
for (const Map<StringName, VisualScript::Variable>::Element *E = script->variables.front(); E; E = E->next()) {
@@ -2208,7 +2116,6 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
}
for (const Map<StringName, VisualScript::Function>::Element *E = script->functions.front(); E; E = E->next()) {
-
if (E->key() == script->get_default_func()) {
continue;
}
@@ -2247,7 +2154,6 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
//first create the nodes
for (const Map<int, VisualScript::Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) {
-
Ref<VisualScriptNode> node = F->get().node;
VisualScriptNodeInstance *instance = node->instance(this); //create instance
@@ -2268,7 +2174,6 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
if (instance->input_port_count) {
instance->input_ports = memnew_arr(int, instance->input_port_count);
for (int i = 0; i < instance->input_port_count; i++) {
-
instance->input_ports[i] = -1; //if not assigned, will become default value
}
}
@@ -2293,10 +2198,11 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
StringName var_name;
- if (Object::cast_to<VisualScriptLocalVar>(*node))
+ if (Object::cast_to<VisualScriptLocalVar>(*node)) {
var_name = String(Object::cast_to<VisualScriptLocalVar>(*node)->get_var_name()).strip_edges();
- else
+ } else {
var_name = String(Object::cast_to<VisualScriptLocalVarSet>(*node)->get_var_name()).strip_edges();
+ }
if (!local_var_indices.has(var_name)) {
local_var_indices[var_name] = function.max_stack;
@@ -2323,7 +2229,6 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
//second pass, do data connections
for (const Set<VisualScript::DataConnection>::Element *F = E->get().data_connections.front(); F; F = F->next()) {
-
VisualScript::DataConnection dc = F->get();
ERR_CONTINUE(!instances.has(dc.from_node));
VisualScriptNodeInstance *from = instances[dc.from_node];
@@ -2333,7 +2238,6 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
ERR_CONTINUE(dc.to_port >= to->input_port_count);
if (from->output_ports[dc.from_port] == -1) {
-
int stack_pos = function.max_stack++;
from->output_ports[dc.from_port] = stack_pos;
}
@@ -2353,7 +2257,6 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
//third pass, do sequence connections
for (const Set<VisualScript::SequenceConnection>::Element *F = E->get().sequence_connections.front(); F; F = F->next()) {
-
VisualScript::SequenceConnection sc = F->get();
ERR_CONTINUE(!instances.has(sc.from_node));
VisualScriptNodeInstance *from = instances[sc.from_node];
@@ -2369,7 +2272,6 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
// 2) connect unassigned output ports to trash
for (const Map<int, VisualScript::Function::NodeData>::Element *F = E->get().nodes.front(); F; F = F->next()) {
-
ERR_CONTINUE(!instances.has(F->key()));
Ref<VisualScriptNode> node = F->get().node;
@@ -2378,7 +2280,6 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
// connect to default values
for (int i = 0; i < instance->input_port_count; i++) {
if (instance->input_ports[i] == -1) {
-
//unassigned, connect to default val
instance->input_ports[i] = default_values.size() | VisualScriptNodeInstance::INPUT_DEFAULT_VALUE_BIT;
default_values.push_back(node->get_default_input_value(i));
@@ -2398,7 +2299,6 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
}
ScriptLanguage *VisualScriptInstance::get_language() {
-
return VisualScriptLanguage::singleton;
}
@@ -2406,7 +2306,6 @@ VisualScriptInstance::VisualScriptInstance() {
}
VisualScriptInstance::~VisualScriptInstance() {
-
{
MutexLock lock(VisualScriptLanguage::singleton->lock);
@@ -2423,7 +2322,6 @@ VisualScriptInstance::~VisualScriptInstance() {
/////////////////////
Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
ERR_FAIL_COND_V(function == StringName(), Variant());
#ifdef DEBUG_ENABLED
@@ -2444,7 +2342,6 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int
} else if (p_argcount == 1) {
//noooneee, reserved for me, me and only me.
} else {
-
for (int i = 0; i < p_argcount - 1; i++) {
args.push_back(*p_args[i]);
}
@@ -2471,7 +2368,6 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int
}
void VisualScriptFunctionState::connect_to_signal(Object *p_obj, const String &p_signal, Array p_binds) {
-
Vector<Variant> binds;
for (int i = 0; i < p_binds.size(); i++) {
binds.push_back(p_binds[i]);
@@ -2481,12 +2377,10 @@ void VisualScriptFunctionState::connect_to_signal(Object *p_obj, const String &p
}
bool VisualScriptFunctionState::is_valid() const {
-
return function != StringName();
}
Variant VisualScriptFunctionState::resume(Array p_args) {
-
ERR_FAIL_COND_V(function == StringName(), Variant());
#ifdef DEBUG_ENABLED
@@ -2508,7 +2402,6 @@ Variant VisualScriptFunctionState::resume(Array p_args) {
}
void VisualScriptFunctionState::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("connect_to_signal", "obj", "signals", "args"), &VisualScriptFunctionState::connect_to_signal);
ClassDB::bind_method(D_METHOD("resume", "args"), &VisualScriptFunctionState::resume, DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("is_valid"), &VisualScriptFunctionState::is_valid);
@@ -2519,7 +2412,6 @@ VisualScriptFunctionState::VisualScriptFunctionState() {
}
VisualScriptFunctionState::~VisualScriptFunctionState() {
-
if (function != StringName()) {
Variant *s = ((Variant *)stack.ptr());
for (int i = 0; i < variant_stack_size; i++) {
@@ -2531,37 +2423,39 @@ VisualScriptFunctionState::~VisualScriptFunctionState() {
///////////////////////////////////////////////
String VisualScriptLanguage::get_name() const {
-
return "VisualScript";
}
/* LANGUAGE FUNCTIONS */
void VisualScriptLanguage::init() {
}
-String VisualScriptLanguage::get_type() const {
+String VisualScriptLanguage::get_type() const {
return "VisualScript";
}
-String VisualScriptLanguage::get_extension() const {
+String VisualScriptLanguage::get_extension() const {
return "vs";
}
-Error VisualScriptLanguage::execute_file(const String &p_path) {
+Error VisualScriptLanguage::execute_file(const String &p_path) {
return OK;
}
+
void VisualScriptLanguage::finish() {
}
/* EDITOR FUNCTIONS */
void VisualScriptLanguage::get_reserved_words(List<String> *p_words) const {
}
+
void VisualScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
}
+
void VisualScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const {
}
-Ref<Script> VisualScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
+Ref<Script> VisualScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
Ref<VisualScript> script;
script.instance();
script->set_instance_base_type(p_base_class_name);
@@ -2569,7 +2463,6 @@ Ref<Script> VisualScriptLanguage::get_template(const String &p_class_name, const
}
bool VisualScriptLanguage::is_using_templates() {
-
return true;
}
@@ -2579,32 +2472,32 @@ void VisualScriptLanguage::make_template(const String &p_class_name, const Strin
}
bool VisualScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions, List<ScriptLanguage::Warning> *r_warnings, Set<int> *r_safe_lines) const {
-
return false;
}
-Script *VisualScriptLanguage::create_script() const {
+Script *VisualScriptLanguage::create_script() const {
return memnew(VisualScript);
}
-bool VisualScriptLanguage::has_named_classes() const {
+bool VisualScriptLanguage::has_named_classes() const {
return false;
}
-bool VisualScriptLanguage::supports_builtin_mode() const {
+bool VisualScriptLanguage::supports_builtin_mode() const {
return true;
}
-int VisualScriptLanguage::find_function(const String &p_function, const String &p_code) const {
+int VisualScriptLanguage::find_function(const String &p_function, const String &p_code) const {
return -1;
}
-String VisualScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const {
+String VisualScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const {
return String();
}
void VisualScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {
}
+
void VisualScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) {
}
@@ -2614,7 +2507,6 @@ bool VisualScriptLanguage::debug_break_parse(const String &p_file, int p_node, c
//break because of parse error
if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
-
_debug_parse_err_node = p_node;
_debug_parse_err_file = p_file;
_debug_error = p_error;
@@ -2626,9 +2518,7 @@ bool VisualScriptLanguage::debug_break_parse(const String &p_file, int p_node, c
}
bool VisualScriptLanguage::debug_break(const String &p_error, bool p_allow_continue) {
-
if (EngineDebugger::is_active() && Thread::get_caller_id() == Thread::get_main_id()) {
-
_debug_parse_err_node = -1;
_debug_parse_err_file = "";
_debug_error = p_error;
@@ -2640,21 +2530,21 @@ bool VisualScriptLanguage::debug_break(const String &p_error, bool p_allow_conti
}
String VisualScriptLanguage::debug_get_error() const {
-
return _debug_error;
}
int VisualScriptLanguage::debug_get_stack_level_count() const {
-
- if (_debug_parse_err_node >= 0)
+ if (_debug_parse_err_node >= 0) {
return 1;
+ }
return _debug_call_stack_pos;
}
-int VisualScriptLanguage::debug_get_stack_level_line(int p_level) const {
- if (_debug_parse_err_node >= 0)
+int VisualScriptLanguage::debug_get_stack_level_line(int p_level) const {
+ if (_debug_parse_err_node >= 0) {
return _debug_parse_err_node;
+ }
ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, -1);
@@ -2662,28 +2552,31 @@ int VisualScriptLanguage::debug_get_stack_level_line(int p_level) const {
return *(_call_stack[l].current_id);
}
-String VisualScriptLanguage::debug_get_stack_level_function(int p_level) const {
- if (_debug_parse_err_node >= 0)
+String VisualScriptLanguage::debug_get_stack_level_function(int p_level) const {
+ if (_debug_parse_err_node >= 0) {
return "";
+ }
ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, "");
int l = _debug_call_stack_pos - p_level - 1;
return *_call_stack[l].function;
}
-String VisualScriptLanguage::debug_get_stack_level_source(int p_level) const {
- if (_debug_parse_err_node >= 0)
+String VisualScriptLanguage::debug_get_stack_level_source(int p_level) const {
+ if (_debug_parse_err_node >= 0) {
return _debug_parse_err_file;
+ }
ERR_FAIL_INDEX_V(p_level, _debug_call_stack_pos, "");
int l = _debug_call_stack_pos - p_level - 1;
return _call_stack[l].instance->get_script_ptr()->get_path();
}
-void VisualScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
- if (_debug_parse_err_node >= 0)
+void VisualScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
+ if (_debug_parse_err_node >= 0) {
return;
+ }
ERR_FAIL_INDEX(p_level, _debug_call_stack_pos);
@@ -2720,7 +2613,6 @@ void VisualScriptLanguage::debug_get_stack_level_locals(int p_level, List<String
}
for (int i = 0; i < node->output_port_count; i++) {
-
String name = node->get_base_node()->get_output_value_port_info(i).name;
if (name == String()) {
name = "out_" + itos(i);
@@ -2755,17 +2647,19 @@ void VisualScriptLanguage::debug_get_stack_level_locals(int p_level, List<String
}
*/
}
-void VisualScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
- if (_debug_parse_err_node >= 0)
+void VisualScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
+ if (_debug_parse_err_node >= 0) {
return;
+ }
ERR_FAIL_INDEX(p_level, _debug_call_stack_pos);
int l = _debug_call_stack_pos - p_level - 1;
Ref<VisualScript> vs = _call_stack[l].instance->get_script();
- if (vs.is_null())
+ if (vs.is_null()) {
return;
+ }
List<StringName> vars;
vs->get_variable_list(&vars);
@@ -2779,48 +2673,48 @@ void VisualScriptLanguage::debug_get_stack_level_members(int p_level, List<Strin
}
void VisualScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
-
//no globals are really reachable in gdscript
}
-String VisualScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
+String VisualScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
return "";
}
void VisualScriptLanguage::reload_all_scripts() {
}
+
void VisualScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) {
}
+
/* LOADER FUNCTIONS */
void VisualScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("vs");
}
+
void VisualScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const {
}
+
void VisualScriptLanguage::get_public_constants(List<Pair<String, Variant>> *p_constants) const {
}
void VisualScriptLanguage::profiling_start() {
}
+
void VisualScriptLanguage::profiling_stop() {
}
int VisualScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
-
return 0;
}
int VisualScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) {
-
return 0;
}
VisualScriptLanguage *VisualScriptLanguage::singleton = nullptr;
void VisualScriptLanguage::add_register_func(const String &p_name, VisualScriptNodeRegisterFunc p_func) {
-
ERR_FAIL_COND(register_funcs.has(p_name));
register_funcs[p_name] = p_func;
}
@@ -2831,21 +2725,18 @@ void VisualScriptLanguage::remove_register_func(const String &p_name) {
}
Ref<VisualScriptNode> VisualScriptLanguage::create_node_from_name(const String &p_name) {
-
ERR_FAIL_COND_V(!register_funcs.has(p_name), Ref<VisualScriptNode>());
return register_funcs[p_name](p_name);
}
void VisualScriptLanguage::get_registered_node_names(List<String> *r_names) {
-
for (Map<String, VisualScriptNodeRegisterFunc>::Element *E = register_funcs.front(); E; E = E->next()) {
r_names->push_back(E->key());
}
}
VisualScriptLanguage::VisualScriptLanguage() {
-
notification = "_notification";
_step = "_step";
_subcall = "_subcall";
@@ -2869,7 +2760,6 @@ VisualScriptLanguage::VisualScriptLanguage() {
}
VisualScriptLanguage::~VisualScriptLanguage() {
-
if (_call_stack) {
memdelete_arr(_call_stack);
}
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 29309aa156..d54b1faf42 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -89,7 +89,6 @@ public:
virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance) = 0;
struct TypeGuess {
-
Variant::Type type;
StringName gdclass;
Ref<Script> script;
@@ -166,16 +165,13 @@ public:
};
class VisualScript : public Script {
-
GDCLASS(VisualScript, Script);
RES_BASE_EXTENSION("vs");
public:
struct SequenceConnection {
-
union {
-
struct {
uint64_t from_node : 24;
uint64_t from_output : 16;
@@ -185,15 +181,12 @@ public:
};
bool operator<(const SequenceConnection &p_connection) const {
-
return id < p_connection.id;
}
};
struct DataConnection {
-
union {
-
struct {
uint64_t from_node : 24;
uint64_t from_port : 8;
@@ -204,7 +197,6 @@ public:
};
bool operator<(const DataConnection &p_connection) const {
-
return id < p_connection.id;
}
};
@@ -272,6 +264,8 @@ protected:
static void _bind_methods();
public:
+ bool inherits_script(const Ref<Script> &p_script) const;
+
// TODO: Remove it in future when breaking changes are acceptable
StringName get_default_func() const;
void add_function(const StringName &p_name);
@@ -429,20 +423,20 @@ public:
String to_string(bool *r_valid);
bool set_variable(const StringName &p_variable, const Variant &p_value) {
-
Map<StringName, Variant>::Element *E = variables.find(p_variable);
- if (!E)
+ if (!E) {
return false;
+ }
E->get() = p_value;
return true;
}
bool get_variable(const StringName &p_variable, Variant *r_variable) const {
-
const Map<StringName, Variant>::Element *E = variables.find(p_variable);
- if (!E)
+ if (!E) {
return false;
+ }
*r_variable = E->get();
return true;
@@ -474,7 +468,6 @@ public:
};
class VisualScriptFunctionState : public Reference {
-
GDCLASS(VisualScriptFunctionState, Reference);
friend class VisualScriptInstance;
@@ -505,11 +498,9 @@ public:
typedef Ref<VisualScriptNode> (*VisualScriptNodeRegisterFunc)(const String &p_type);
class VisualScriptLanguage : public ScriptLanguage {
-
Map<String, VisualScriptNodeRegisterFunc> register_funcs;
struct CallLevel {
-
Variant *stack;
Variant **work_mem;
const StringName *function;
@@ -538,12 +529,13 @@ public:
bool debug_break_parse(const String &p_file, int p_node, const String &p_error);
_FORCE_INLINE_ void enter_function(VisualScriptInstance *p_instance, const StringName *p_function, Variant *p_stack, Variant **p_work_mem, int *current_id) {
-
- if (Thread::get_main_id() != Thread::get_caller_id())
+ if (Thread::get_main_id() != Thread::get_caller_id()) {
return; //no support for other threads than main for now
+ }
- if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0)
+ if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) {
EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() + 1);
+ }
if (_debug_call_stack_pos >= _debug_max_call_stack) {
//stack overflow
@@ -561,15 +553,15 @@ public:
}
_FORCE_INLINE_ void exit_function() {
-
- if (Thread::get_main_id() != Thread::get_caller_id())
+ if (Thread::get_main_id() != Thread::get_caller_id()) {
return; //no support for other threads than main for now
+ }
- if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0)
+ if (EngineDebugger::get_script_debugger()->get_lines_left() > 0 && EngineDebugger::get_script_debugger()->get_depth() >= 0) {
EngineDebugger::get_script_debugger()->set_depth(EngineDebugger::get_script_debugger()->get_depth() - 1);
+ }
if (_debug_call_stack_pos == 0) {
-
_debug_error = "Stack Underflow (Engine Bug)";
EngineDebugger::get_script_debugger()->debug(this);
return;
@@ -643,7 +635,6 @@ public:
//aid for registering
template <class T>
static Ref<VisualScriptNode> create_node_generic(const String &p_name) {
-
Ref<T> node;
node.instance();
return node;
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index bb291b1cb6..a0dcd76d10 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -110,30 +110,26 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
};
VisualScriptBuiltinFunc::BuiltinFunc VisualScriptBuiltinFunc::find_function(const String &p_string) {
-
for (int i = 0; i < FUNC_MAX; i++) {
- if (p_string == func_name[i])
+ if (p_string == func_name[i]) {
return BuiltinFunc(i);
+ }
}
return FUNC_MAX;
}
String VisualScriptBuiltinFunc::get_func_name(BuiltinFunc p_func) {
-
ERR_FAIL_INDEX_V(p_func, FUNC_MAX, String());
return func_name[p_func];
}
int VisualScriptBuiltinFunc::get_output_sequence_port_count() const {
-
return has_input_sequence_port() ? 1 : 0;
}
bool VisualScriptBuiltinFunc::has_input_sequence_port() const {
-
switch (func) {
-
case MATH_RANDOMIZE:
case TEXT_PRINT:
case TEXT_PRINTERR:
@@ -145,9 +141,7 @@ bool VisualScriptBuiltinFunc::has_input_sequence_port() const {
}
int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
-
switch (p_func) {
-
case MATH_RANDOMIZE:
case MATH_RAND:
case MATH_RANDF:
@@ -228,11 +222,10 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
}
int VisualScriptBuiltinFunc::get_input_value_port_count() const {
-
return get_func_argument_count(func);
}
-int VisualScriptBuiltinFunc::get_output_value_port_count() const {
+int VisualScriptBuiltinFunc::get_output_value_port_count() const {
switch (func) {
case MATH_RANDOMIZE:
case TEXT_PRINT:
@@ -250,14 +243,11 @@ int VisualScriptBuiltinFunc::get_output_value_port_count() const {
}
String VisualScriptBuiltinFunc::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const {
-
switch (func) {
-
case MATH_SIN:
case MATH_COS:
case MATH_TAN:
@@ -280,96 +270,106 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
return PropertyInfo(Variant::FLOAT, "s");
} break;
case MATH_ATAN2: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "y");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "x");
+ }
} break;
case MATH_FMOD:
case MATH_FPOSMOD:
case LOGIC_MAX:
case LOGIC_MIN: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "a");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "b");
+ }
} break;
case MATH_POSMOD: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::INT, "a");
- else
+ } else {
return PropertyInfo(Variant::INT, "b");
+ }
} break;
case MATH_POW: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "base");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "exp");
+ }
} break;
case MATH_EASE: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "s");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "curve");
+ }
} break;
case MATH_STEP_DECIMALS: {
return PropertyInfo(Variant::FLOAT, "step");
} break;
case MATH_STEPIFY: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "s");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "steps");
+ }
} break;
case MATH_LERP:
case MATH_LERP_ANGLE:
case MATH_INVERSE_LERP:
case MATH_SMOOTHSTEP: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "from");
- else if (p_idx == 1)
+ } else if (p_idx == 1) {
return PropertyInfo(Variant::FLOAT, "to");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "weight");
+ }
} break;
case MATH_RANGE_LERP: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "value");
- else if (p_idx == 1)
+ } else if (p_idx == 1) {
return PropertyInfo(Variant::FLOAT, "istart");
- else if (p_idx == 2)
+ } else if (p_idx == 2) {
return PropertyInfo(Variant::FLOAT, "istop");
- else if (p_idx == 3)
+ } else if (p_idx == 3) {
return PropertyInfo(Variant::FLOAT, "ostart");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "ostop");
+ }
} break;
case MATH_MOVE_TOWARD: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "from");
- else if (p_idx == 1)
+ } else if (p_idx == 1) {
return PropertyInfo(Variant::FLOAT, "to");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "delta");
+ }
} break;
case MATH_DECTIME: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "value");
- else if (p_idx == 1)
+ } else if (p_idx == 1) {
return PropertyInfo(Variant::FLOAT, "amount");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "step");
+ }
} break;
case MATH_RANDOMIZE:
case MATH_RAND:
case MATH_RANDF: {
-
} break;
case MATH_RANDOM: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "from");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "to");
+ }
} break;
case MATH_SEED:
case MATH_RANDSEED: {
@@ -388,33 +388,37 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
return PropertyInfo(Variant::FLOAT, "db");
} break;
case MATH_POLAR2CARTESIAN: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "r");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "th");
+ }
} break;
case MATH_CARTESIAN2POLAR: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "x");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "y");
+ }
} break;
case MATH_WRAP: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::INT, "value");
- else if (p_idx == 1)
+ } else if (p_idx == 1) {
return PropertyInfo(Variant::INT, "min");
- else
+ } else {
return PropertyInfo(Variant::INT, "max");
+ }
} break;
case MATH_WRAPF:
case LOGIC_CLAMP: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::FLOAT, "value");
- else if (p_idx == 1)
+ } else if (p_idx == 1) {
return PropertyInfo(Variant::FLOAT, "min");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "max");
+ }
} break;
case LOGIC_NEAREST_PO2: {
return PropertyInfo(Variant::INT, "value");
@@ -423,16 +427,18 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
return PropertyInfo(Variant::OBJECT, "source");
} break;
case FUNC_FUNCREF: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::OBJECT, "instance");
- else
+ } else {
return PropertyInfo(Variant::STRING, "funcname");
+ }
} break;
case TYPE_CONVERT: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::NIL, "what");
- else
+ } else {
return PropertyInfo(Variant::STRING, "type");
+ }
} break;
case TYPE_OF: {
return PropertyInfo(Variant::NIL, "what");
@@ -453,29 +459,30 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
return PropertyInfo(Variant::NIL, "value");
} break;
case STR_TO_VAR: {
-
return PropertyInfo(Variant::STRING, "string");
} break;
case VAR_TO_STR:
case VAR_TO_BYTES: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::NIL, "var");
- else
+ } else {
return PropertyInfo(Variant::BOOL, "full_objects");
+ }
} break;
case BYTES_TO_VAR: {
-
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytes");
- else
+ } else {
return PropertyInfo(Variant::BOOL, "allow_objects");
+ }
} break;
case COLORN: {
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::STRING, "name");
- else
+ } else {
return PropertyInfo(Variant::FLOAT, "alpha");
+ }
} break;
case FUNC_MAX: {
}
@@ -485,10 +492,8 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
}
PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) const {
-
Variant::Type t = Variant::NIL;
switch (func) {
-
case MATH_SIN:
case MATH_COS:
case MATH_TAN:
@@ -545,10 +550,8 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
} break;
case MATH_RANDOMIZE: {
-
} break;
case MATH_RAND: {
-
t = Variant::INT;
} break;
case MATH_RANDF:
@@ -556,14 +559,13 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
t = Variant::FLOAT;
} break;
case MATH_SEED: {
-
} break;
case MATH_RANDSEED: {
-
- if (p_idx == 0)
+ if (p_idx == 0) {
return PropertyInfo(Variant::INT, "rnd");
- else
+ } else {
return PropertyInfo(Variant::INT, "seed");
+ }
} break;
case MATH_DEG2RAD:
case MATH_RAD2DEG:
@@ -582,24 +584,20 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
case LOGIC_MAX:
case LOGIC_MIN:
case LOGIC_CLAMP: {
-
} break;
case LOGIC_NEAREST_PO2: {
t = Variant::NIL;
} break;
case OBJ_WEAKREF: {
-
t = Variant::OBJECT;
} break;
case FUNC_FUNCREF: {
-
t = Variant::OBJECT;
} break;
case TYPE_CONVERT: {
-
} break;
case TEXT_ORD:
case TYPE_OF: {
@@ -607,41 +605,37 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
} break;
case TYPE_EXISTS: {
-
t = Variant::BOOL;
} break;
case TEXT_CHAR:
case TEXT_STR: {
-
t = Variant::STRING;
} break;
case TEXT_PRINT: {
-
} break;
case TEXT_PRINTERR: {
-
} break;
case TEXT_PRINTRAW: {
-
} break;
case VAR_TO_STR: {
t = Variant::STRING;
} break;
case STR_TO_VAR: {
-
} break;
case VAR_TO_BYTES: {
- if (p_idx == 0)
+ if (p_idx == 0) {
t = Variant::PACKED_BYTE_ARRAY;
- else
+ } else {
t = Variant::BOOL;
+ }
} break;
case BYTES_TO_VAR: {
- if (p_idx == 1)
+ if (p_idx == 1) {
t = Variant::BOOL;
+ }
} break;
case COLORN: {
t = Variant::COLOR;
@@ -658,15 +652,14 @@ String VisualScriptBuiltinFunc::get_caption() const {
return "BuiltinFunc";
}
+
*/
String VisualScriptBuiltinFunc::get_caption() const {
-
return func_name[func];
}
void VisualScriptBuiltinFunc::set_func(BuiltinFunc p_which) {
-
ERR_FAIL_INDEX(p_which, FUNC_MAX);
func = p_which;
_change_notify();
@@ -686,197 +679,159 @@ VisualScriptBuiltinFunc::BuiltinFunc VisualScriptBuiltinFunc::get_func() {
}
void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_inputs, Variant *r_return, Callable::CallError &r_error, String &r_error_str) {
-
switch (p_func) {
case VisualScriptBuiltinFunc::MATH_SIN: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::sin((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_COS: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::cos((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_TAN: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::tan((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_SINH: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::sinh((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_COSH: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::cosh((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_TANH: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::tanh((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_ASIN: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::asin((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_ACOS: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::acos((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_ATAN: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::atan((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_ATAN2: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::atan2((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case VisualScriptBuiltinFunc::MATH_SQRT: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::sqrt((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_FMOD: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::fmod((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case VisualScriptBuiltinFunc::MATH_FPOSMOD: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::fposmod((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case VisualScriptBuiltinFunc::MATH_POSMOD: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::posmod((int)*p_inputs[0], (int)*p_inputs[1]);
} break;
case VisualScriptBuiltinFunc::MATH_FLOOR: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::floor((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_CEIL: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::ceil((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_ROUND: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::round((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_ABS: {
-
if (p_inputs[0]->get_type() == Variant::INT) {
-
int64_t i = *p_inputs[0];
*r_return = ABS(i);
} else if (p_inputs[0]->get_type() == Variant::FLOAT) {
-
real_t r = *p_inputs[0];
*r_return = Math::abs(r);
} else {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::FLOAT;
}
} break;
case VisualScriptBuiltinFunc::MATH_SIGN: {
-
if (p_inputs[0]->get_type() == Variant::INT) {
-
int64_t i = *p_inputs[0];
*r_return = i < 0 ? -1 : (i > 0 ? +1 : 0);
} else if (p_inputs[0]->get_type() == Variant::FLOAT) {
-
real_t r = *p_inputs[0];
*r_return = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0);
} else {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::FLOAT;
}
} break;
case VisualScriptBuiltinFunc::MATH_POW: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::pow((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case VisualScriptBuiltinFunc::MATH_LOG: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::log((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_EXP: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::exp((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_ISNAN: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::is_nan((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_ISINF: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::is_inf((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_EASE: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::ease((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case VisualScriptBuiltinFunc::MATH_STEP_DECIMALS: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::step_decimals((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_STEPIFY: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::stepify((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case VisualScriptBuiltinFunc::MATH_LERP: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
*r_return = Math::lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case VisualScriptBuiltinFunc::MATH_LERP_ANGLE: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
*r_return = Math::lerp_angle((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case VisualScriptBuiltinFunc::MATH_INVERSE_LERP: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
*r_return = Math::inverse_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case VisualScriptBuiltinFunc::MATH_RANGE_LERP: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
@@ -891,14 +846,12 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
*r_return = Math::smoothstep((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case VisualScriptBuiltinFunc::MATH_MOVE_TOWARD: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
*r_return = Math::move_toward((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case VisualScriptBuiltinFunc::MATH_DECTIME: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
VALIDATE_ARG_NUM(2);
@@ -915,20 +868,17 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
*r_return = Math::randf();
} break;
case VisualScriptBuiltinFunc::MATH_RANDOM: {
-
VALIDATE_ARG_NUM(0);
VALIDATE_ARG_NUM(1);
*r_return = Math::random((double)*p_inputs[0], (double)*p_inputs[1]);
} break;
case VisualScriptBuiltinFunc::MATH_SEED: {
-
VALIDATE_ARG_NUM(0);
uint64_t seed = *p_inputs[0];
Math::seed(seed);
} break;
case VisualScriptBuiltinFunc::MATH_RANDSEED: {
-
VALIDATE_ARG_NUM(0);
uint64_t seed = *p_inputs[0];
int ret = Math::rand_from_seed(&seed);
@@ -939,22 +889,18 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
} break;
case VisualScriptBuiltinFunc::MATH_DEG2RAD: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::deg2rad((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_RAD2DEG: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::rad2deg((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_LINEAR2DB: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::linear2db((double)*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::MATH_DB2LINEAR: {
-
VALIDATE_ARG_NUM(0);
*r_return = Math::db2linear((double)*p_inputs[0]);
} break;
@@ -985,9 +931,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
*r_return = Math::wrapf((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
case VisualScriptBuiltinFunc::LOGIC_MAX: {
-
if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) {
-
int64_t a = *p_inputs[0];
int64_t b = *p_inputs[1];
*r_return = MAX(a, b);
@@ -1003,9 +947,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
} break;
case VisualScriptBuiltinFunc::LOGIC_MIN: {
-
if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT) {
-
int64_t a = *p_inputs[0];
int64_t b = *p_inputs[1];
*r_return = MIN(a, b);
@@ -1020,9 +962,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
}
} break;
case VisualScriptBuiltinFunc::LOGIC_CLAMP: {
-
if (p_inputs[0]->get_type() == Variant::INT && p_inputs[1]->get_type() == Variant::INT && p_inputs[2]->get_type() == Variant::INT) {
-
int64_t a = *p_inputs[0];
int64_t b = *p_inputs[1];
int64_t c = *p_inputs[2];
@@ -1040,15 +980,12 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
}
} break;
case VisualScriptBuiltinFunc::LOGIC_NEAREST_PO2: {
-
VALIDATE_ARG_NUM(0);
int64_t num = *p_inputs[0];
*r_return = next_power_of_2(num);
} break;
case VisualScriptBuiltinFunc::OBJ_WEAKREF: {
-
if (p_inputs[0]->get_type() != Variant::OBJECT) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -1057,10 +994,8 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
}
if (p_inputs[0]->is_ref()) {
-
REF r = *p_inputs[0];
if (!r.is_valid()) {
-
return;
}
@@ -1070,7 +1005,6 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
} else {
Object *obj = *p_inputs[0];
if (!obj) {
-
return;
}
Ref<WeakRef> wref = memnew(WeakRef);
@@ -1080,9 +1014,7 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
} break;
case VisualScriptBuiltinFunc::FUNC_FUNCREF: {
-
if (p_inputs[0]->get_type() != Variant::OBJECT) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
r_error.expected = Variant::OBJECT;
@@ -1090,7 +1022,6 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
return;
}
if (p_inputs[1]->get_type() != Variant::STRING && p_inputs[1]->get_type() != Variant::NODE_PATH) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
r_error.expected = Variant::STRING;
@@ -1107,11 +1038,9 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
} break;
case VisualScriptBuiltinFunc::TYPE_CONVERT: {
-
VALIDATE_ARG_NUM(1);
int type = *p_inputs[1];
if (type < 0 || type >= Variant::VARIANT_MAX) {
-
r_error_str = RTR("Invalid type argument to convert(), use TYPE_* constants.");
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
@@ -1119,29 +1048,24 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
return;
} else {
-
*r_return = Variant::construct(Variant::Type(type), p_inputs, 1, r_error);
}
} break;
case VisualScriptBuiltinFunc::TYPE_OF: {
-
*r_return = p_inputs[0]->get_type();
} break;
case VisualScriptBuiltinFunc::TYPE_EXISTS: {
-
*r_return = ClassDB::class_exists(*p_inputs[0]);
} break;
case VisualScriptBuiltinFunc::TEXT_CHAR: {
-
CharType result[2] = { *p_inputs[0], 0 };
*r_return = String(result);
} break;
case VisualScriptBuiltinFunc::TEXT_ORD: {
-
if (p_inputs[0]->get_type() != Variant::STRING) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
@@ -1165,39 +1089,33 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
} break;
case VisualScriptBuiltinFunc::TEXT_STR: {
-
String str = *p_inputs[0];
*r_return = str;
} break;
case VisualScriptBuiltinFunc::TEXT_PRINT: {
-
String str = *p_inputs[0];
print_line(str);
} break;
case VisualScriptBuiltinFunc::TEXT_PRINTERR: {
-
String str = *p_inputs[0];
print_error(str);
} break;
case VisualScriptBuiltinFunc::TEXT_PRINTRAW: {
-
String str = *p_inputs[0];
OS::get_singleton()->print("%s", str.utf8().get_data());
} break;
case VisualScriptBuiltinFunc::VAR_TO_STR: {
-
String vars;
VariantWriter::write_to_string(*p_inputs[0], vars);
*r_return = vars;
} break;
case VisualScriptBuiltinFunc::STR_TO_VAR: {
-
if (p_inputs[0]->get_type() != Variant::STRING) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
@@ -1223,7 +1141,6 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
} break;
case VisualScriptBuiltinFunc::VAR_TO_BYTES: {
-
if (p_inputs[1]->get_type() != Variant::BOOL) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 1;
@@ -1250,7 +1167,6 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
*r_return = barr;
} break;
case VisualScriptBuiltinFunc::BYTES_TO_VAR: {
-
if (p_inputs[0]->get_type() != Variant::PACKED_BYTE_ARRAY) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
r_error.argument = 0;
@@ -1283,7 +1199,6 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
} break;
case VisualScriptBuiltinFunc::COLORN: {
-
VALIDATE_ARG_NUM(1);
Color color = Color::named(*p_inputs[0]);
@@ -1309,14 +1224,12 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
VisualScriptBuiltinFunc::exec_func(func, p_inputs, p_outputs[0], r_error, r_error_str);
return 0;
}
};
VisualScriptNodeInstance *VisualScriptBuiltinFunc::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceBuiltinFunc *instance = memnew(VisualScriptNodeInstanceBuiltinFunc);
instance->node = this;
instance->instance = p_instance;
@@ -1325,16 +1238,15 @@ VisualScriptNodeInstance *VisualScriptBuiltinFunc::instance(VisualScriptInstance
}
void VisualScriptBuiltinFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_func", "which"), &VisualScriptBuiltinFunc::set_func);
ClassDB::bind_method(D_METHOD("get_func"), &VisualScriptBuiltinFunc::get_func);
String cc;
for (int i = 0; i < FUNC_MAX; i++) {
-
- if (i > 0)
+ if (i > 0) {
cc += ",";
+ }
cc += func_name[i];
}
ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, cc), "set_func", "get_func");
@@ -1411,24 +1323,20 @@ void VisualScriptBuiltinFunc::_bind_methods() {
}
VisualScriptBuiltinFunc::VisualScriptBuiltinFunc(VisualScriptBuiltinFunc::BuiltinFunc func) {
-
this->func = func;
}
VisualScriptBuiltinFunc::VisualScriptBuiltinFunc() {
-
func = MATH_SIN;
}
template <VisualScriptBuiltinFunc::BuiltinFunc func>
static Ref<VisualScriptNode> create_builtin_func_node(const String &p_name) {
-
Ref<VisualScriptBuiltinFunc> node = memnew(VisualScriptBuiltinFunc(func));
return node;
}
void register_visual_script_builtin_func_node() {
-
VisualScriptLanguage::singleton->add_register_func("functions/built_in/sin", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_SIN>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/cos", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_COS>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/tan", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_TAN>);
diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h
index d950f858d4..1b186353f1 100644
--- a/modules/visual_script/visual_script_builtin_funcs.h
+++ b/modules/visual_script/visual_script_builtin_funcs.h
@@ -34,7 +34,6 @@
#include "visual_script.h"
class VisualScriptBuiltinFunc : public VisualScriptNode {
-
GDCLASS(VisualScriptBuiltinFunc, VisualScriptNode);
public:
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 59b1bcdd96..fea7d151df 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -30,7 +30,7 @@
#include "visual_script_editor.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/object.h"
#include "core/os/keyboard.h"
#include "core/script_language.h"
@@ -46,7 +46,6 @@
#ifdef TOOLS_ENABLED
class VisualScriptEditorSignalEdit : public Object {
-
GDCLASS(VisualScriptEditorSignalEdit, Object);
StringName sig;
@@ -62,22 +61,21 @@ protected:
}
void _sig_changed() {
-
_change_notify();
emit_signal("changed");
}
bool _set(const StringName &p_name, const Variant &p_value) {
-
- if (sig == StringName())
+ if (sig == StringName()) {
return false;
+ }
if (p_name == "argument_count") {
-
int new_argc = p_value;
int argc = script->custom_signal_get_argument_count(sig);
- if (argc == new_argc)
+ if (argc == new_argc) {
return true;
+ }
undo_redo->create_action(TTR("Change Signal Arguments"));
@@ -87,9 +85,7 @@ protected:
undo_redo->add_undo_method(script.ptr(), "custom_signal_add_argument", sig, script->custom_signal_get_argument_name(sig, i), script->custom_signal_get_argument_type(sig, i), -1);
}
} else if (new_argc > argc) {
-
for (int i = argc; i < new_argc; i++) {
-
undo_redo->add_do_method(script.ptr(), "custom_signal_add_argument", sig, Variant::NIL, "arg" + itos(i + 1), -1);
undo_redo->add_undo_method(script.ptr(), "custom_signal_remove_argument", sig, argc);
}
@@ -107,7 +103,6 @@ protected:
ERR_FAIL_INDEX_V(idx, script->custom_signal_get_argument_count(sig), false);
String what = String(p_name).get_slice("/", 2);
if (what == "type") {
-
int old_type = script->custom_signal_get_argument_type(sig, idx);
int new_type = p_value;
undo_redo->create_action(TTR("Change Argument Type"));
@@ -119,7 +114,6 @@ protected:
}
if (what == "name") {
-
String old_name = script->custom_signal_get_argument_name(sig, idx);
String new_name = p_value;
undo_redo->create_action(TTR("Change Argument name"));
@@ -134,9 +128,9 @@ protected:
}
bool _get(const StringName &p_name, Variant &r_ret) const {
-
- if (sig == StringName())
+ if (sig == StringName()) {
return false;
+ }
if (p_name == "argument_count") {
r_ret = script->custom_signal_get_argument_count(sig);
@@ -159,9 +153,9 @@ protected:
return false;
}
void _get_property_list(List<PropertyInfo> *p_list) const {
-
- if (sig == StringName())
+ if (sig == StringName()) {
return;
+ }
p_list->push_back(PropertyInfo(Variant::INT, "argument_count", PROPERTY_HINT_RANGE, "0,256"));
String argt = "Variant";
@@ -177,7 +171,6 @@ protected:
public:
void edit(const StringName &p_sig) {
-
sig = p_sig;
_change_notify();
}
@@ -186,7 +179,6 @@ public:
};
class VisualScriptEditorVariableEdit : public Object {
-
GDCLASS(VisualScriptEditorVariableEdit, Object);
StringName var;
@@ -203,20 +195,18 @@ protected:
}
void _var_changed() {
-
_change_notify();
emit_signal("changed");
}
void _var_value_changed() {
-
_change_notify("value"); //so the whole tree is not redrawn, makes editing smoother in general
emit_signal("changed");
}
bool _set(const StringName &p_name, const Variant &p_value) {
-
- if (var == StringName())
+ if (var == StringName()) {
return false;
+ }
if (String(p_name) == "value") {
undo_redo->create_action(TTR("Set Variable Default Value"));
@@ -232,7 +222,6 @@ protected:
Dictionary d = script->call("get_variable_info", var);
if (String(p_name) == "type") {
-
Dictionary dc = d.duplicate();
dc["type"] = p_value;
undo_redo->create_action(TTR("Set Variable Type"));
@@ -245,7 +234,6 @@ protected:
}
if (String(p_name) == "hint") {
-
Dictionary dc = d.duplicate();
dc["hint"] = p_value;
undo_redo->create_action(TTR("Set Variable Type"));
@@ -258,7 +246,6 @@ protected:
}
if (String(p_name) == "hint_string") {
-
Dictionary dc = d.duplicate();
dc["hint_string"] = p_value;
undo_redo->create_action(TTR("Set Variable Type"));
@@ -280,9 +267,9 @@ protected:
}
bool _get(const StringName &p_name, Variant &r_ret) const {
-
- if (var == StringName())
+ if (var == StringName()) {
return false;
+ }
if (String(p_name) == "value") {
r_ret = script->get_variable_default_value(var);
@@ -312,9 +299,9 @@ protected:
return false;
}
void _get_property_list(List<PropertyInfo> *p_list) const {
-
- if (var == StringName())
+ if (var == StringName()) {
return;
+ }
String argt = "Variant";
for (int i = 1; i < Variant::VARIANT_MAX; i++) {
@@ -330,7 +317,6 @@ protected:
public:
void edit(const StringName &p_var) {
-
var = p_var;
_change_notify();
}
@@ -340,96 +326,224 @@ public:
static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) {
Color color;
- if (dark_theme)
+ if (dark_theme) {
switch (p_type) {
- case Variant::NIL: color = Color(0.41, 0.93, 0.74); break;
-
- case Variant::BOOL: color = Color(0.55, 0.65, 0.94); break;
- case Variant::INT: color = Color(0.49, 0.78, 0.94); break;
- case Variant::FLOAT: color = Color(0.38, 0.85, 0.96); break;
- case Variant::STRING: color = Color(0.42, 0.65, 0.93); break;
-
- case Variant::VECTOR2: color = Color(0.74, 0.57, 0.95); break;
- case Variant::VECTOR2I: color = Color(0.74, 0.57, 0.95); break;
- case Variant::RECT2: color = Color(0.95, 0.57, 0.65); break;
- case Variant::RECT2I: color = Color(0.95, 0.57, 0.65); break;
- case Variant::VECTOR3: color = Color(0.84, 0.49, 0.93); break;
- case Variant::VECTOR3I: color = Color(0.84, 0.49, 0.93); break;
- case Variant::TRANSFORM2D: color = Color(0.77, 0.93, 0.41); break;
- case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break;
- case Variant::QUAT: color = Color(0.93, 0.41, 0.64); break;
- case Variant::AABB: color = Color(0.93, 0.47, 0.57); break;
- case Variant::BASIS: color = Color(0.89, 0.93, 0.41); break;
- case Variant::TRANSFORM: color = Color(0.96, 0.66, 0.43); break;
-
- case Variant::COLOR: color = Color(0.62, 1.0, 0.44); break;
- case Variant::NODE_PATH: color = Color(0.41, 0.58, 0.93); break;
- case Variant::_RID: color = Color(0.41, 0.93, 0.6); break;
- case Variant::OBJECT: color = Color(0.47, 0.95, 0.91); break;
- case Variant::DICTIONARY: color = Color(0.47, 0.93, 0.69); break;
-
- case Variant::ARRAY: color = Color(0.88, 0.88, 0.88); break;
- case Variant::PACKED_BYTE_ARRAY: color = Color(0.67, 0.96, 0.78); break;
- case Variant::PACKED_INT32_ARRAY: color = Color(0.69, 0.86, 0.96); break;
- case Variant::PACKED_FLOAT32_ARRAY: color = Color(0.59, 0.91, 0.97); break;
- case Variant::PACKED_INT64_ARRAY: color = Color(0.69, 0.86, 0.96); break;
- case Variant::PACKED_FLOAT64_ARRAY: color = Color(0.59, 0.91, 0.97); break;
- case Variant::PACKED_STRING_ARRAY: color = Color(0.62, 0.77, 0.95); break;
- case Variant::PACKED_VECTOR2_ARRAY: color = Color(0.82, 0.7, 0.96); break;
- case Variant::PACKED_VECTOR3_ARRAY: color = Color(0.87, 0.61, 0.95); break;
- case Variant::PACKED_COLOR_ARRAY: color = Color(0.91, 1.0, 0.59); break;
+ case Variant::NIL:
+ color = Color(0.41, 0.93, 0.74);
+ break;
+
+ case Variant::BOOL:
+ color = Color(0.55, 0.65, 0.94);
+ break;
+ case Variant::INT:
+ color = Color(0.49, 0.78, 0.94);
+ break;
+ case Variant::FLOAT:
+ color = Color(0.38, 0.85, 0.96);
+ break;
+ case Variant::STRING:
+ color = Color(0.42, 0.65, 0.93);
+ break;
+
+ case Variant::VECTOR2:
+ color = Color(0.74, 0.57, 0.95);
+ break;
+ case Variant::VECTOR2I:
+ color = Color(0.74, 0.57, 0.95);
+ break;
+ case Variant::RECT2:
+ color = Color(0.95, 0.57, 0.65);
+ break;
+ case Variant::RECT2I:
+ color = Color(0.95, 0.57, 0.65);
+ break;
+ case Variant::VECTOR3:
+ color = Color(0.84, 0.49, 0.93);
+ break;
+ case Variant::VECTOR3I:
+ color = Color(0.84, 0.49, 0.93);
+ break;
+ case Variant::TRANSFORM2D:
+ color = Color(0.77, 0.93, 0.41);
+ break;
+ case Variant::PLANE:
+ color = Color(0.97, 0.44, 0.44);
+ break;
+ case Variant::QUAT:
+ color = Color(0.93, 0.41, 0.64);
+ break;
+ case Variant::AABB:
+ color = Color(0.93, 0.47, 0.57);
+ break;
+ case Variant::BASIS:
+ color = Color(0.89, 0.93, 0.41);
+ break;
+ case Variant::TRANSFORM:
+ color = Color(0.96, 0.66, 0.43);
+ break;
+
+ case Variant::COLOR:
+ color = Color(0.62, 1.0, 0.44);
+ break;
+ case Variant::NODE_PATH:
+ color = Color(0.41, 0.58, 0.93);
+ break;
+ case Variant::_RID:
+ color = Color(0.41, 0.93, 0.6);
+ break;
+ case Variant::OBJECT:
+ color = Color(0.47, 0.95, 0.91);
+ break;
+ case Variant::DICTIONARY:
+ color = Color(0.47, 0.93, 0.69);
+ break;
+
+ case Variant::ARRAY:
+ color = Color(0.88, 0.88, 0.88);
+ break;
+ case Variant::PACKED_BYTE_ARRAY:
+ color = Color(0.67, 0.96, 0.78);
+ break;
+ case Variant::PACKED_INT32_ARRAY:
+ color = Color(0.69, 0.86, 0.96);
+ break;
+ case Variant::PACKED_FLOAT32_ARRAY:
+ color = Color(0.59, 0.91, 0.97);
+ break;
+ case Variant::PACKED_INT64_ARRAY:
+ color = Color(0.69, 0.86, 0.96);
+ break;
+ case Variant::PACKED_FLOAT64_ARRAY:
+ color = Color(0.59, 0.91, 0.97);
+ break;
+ case Variant::PACKED_STRING_ARRAY:
+ color = Color(0.62, 0.77, 0.95);
+ break;
+ case Variant::PACKED_VECTOR2_ARRAY:
+ color = Color(0.82, 0.7, 0.96);
+ break;
+ case Variant::PACKED_VECTOR3_ARRAY:
+ color = Color(0.87, 0.61, 0.95);
+ break;
+ case Variant::PACKED_COLOR_ARRAY:
+ color = Color(0.91, 1.0, 0.59);
+ break;
default:
color.set_hsv(p_type / float(Variant::VARIANT_MAX), 0.7, 0.7);
}
- else
+ } else {
switch (p_type) {
- case Variant::NIL: color = Color(0.15, 0.89, 0.63); break;
-
- case Variant::BOOL: color = Color(0.43, 0.56, 0.92); break;
- case Variant::INT: color = Color(0.31, 0.7, 0.91); break;
- case Variant::FLOAT: color = Color(0.15, 0.8, 0.94); break;
- case Variant::STRING: color = Color(0.27, 0.56, 0.91); break;
-
- case Variant::VECTOR2: color = Color(0.68, 0.46, 0.93); break;
- case Variant::VECTOR2I: color = Color(0.68, 0.46, 0.93); break;
- case Variant::RECT2: color = Color(0.93, 0.46, 0.56); break;
- case Variant::RECT2I: color = Color(0.93, 0.46, 0.56); break;
- case Variant::VECTOR3: color = Color(0.86, 0.42, 0.93); break;
- case Variant::VECTOR3I: color = Color(0.86, 0.42, 0.93); break;
- case Variant::TRANSFORM2D: color = Color(0.59, 0.81, 0.1); break;
- case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break;
- case Variant::QUAT: color = Color(0.93, 0.41, 0.64); break;
- case Variant::AABB: color = Color(0.93, 0.47, 0.57); break;
- case Variant::BASIS: color = Color(0.7, 0.73, 0.1); break;
- case Variant::TRANSFORM: color = Color(0.96, 0.56, 0.28); break;
-
- case Variant::COLOR: color = Color(0.24, 0.75, 0.0); break;
- case Variant::NODE_PATH: color = Color(0.41, 0.58, 0.93); break;
- case Variant::_RID: color = Color(0.17, 0.9, 0.45); break;
- case Variant::OBJECT: color = Color(0.07, 0.84, 0.76); break;
- case Variant::DICTIONARY: color = Color(0.34, 0.91, 0.62); break;
-
- case Variant::ARRAY: color = Color(0.45, 0.45, 0.45); break;
- case Variant::PACKED_BYTE_ARRAY: color = Color(0.38, 0.92, 0.6); break;
- case Variant::PACKED_INT32_ARRAY: color = Color(0.38, 0.73, 0.92); break;
- case Variant::PACKED_FLOAT32_ARRAY: color = Color(0.25, 0.83, 0.95); break;
- case Variant::PACKED_INT64_ARRAY: color = Color(0.38, 0.73, 0.92); break;
- case Variant::PACKED_FLOAT64_ARRAY: color = Color(0.25, 0.83, 0.95); break;
- case Variant::PACKED_STRING_ARRAY: color = Color(0.38, 0.62, 0.92); break;
- case Variant::PACKED_VECTOR2_ARRAY: color = Color(0.62, 0.36, 0.92); break;
- case Variant::PACKED_VECTOR3_ARRAY: color = Color(0.79, 0.35, 0.92); break;
- case Variant::PACKED_COLOR_ARRAY: color = Color(0.57, 0.73, 0.0); break;
+ case Variant::NIL:
+ color = Color(0.15, 0.89, 0.63);
+ break;
+
+ case Variant::BOOL:
+ color = Color(0.43, 0.56, 0.92);
+ break;
+ case Variant::INT:
+ color = Color(0.31, 0.7, 0.91);
+ break;
+ case Variant::FLOAT:
+ color = Color(0.15, 0.8, 0.94);
+ break;
+ case Variant::STRING:
+ color = Color(0.27, 0.56, 0.91);
+ break;
+
+ case Variant::VECTOR2:
+ color = Color(0.68, 0.46, 0.93);
+ break;
+ case Variant::VECTOR2I:
+ color = Color(0.68, 0.46, 0.93);
+ break;
+ case Variant::RECT2:
+ color = Color(0.93, 0.46, 0.56);
+ break;
+ case Variant::RECT2I:
+ color = Color(0.93, 0.46, 0.56);
+ break;
+ case Variant::VECTOR3:
+ color = Color(0.86, 0.42, 0.93);
+ break;
+ case Variant::VECTOR3I:
+ color = Color(0.86, 0.42, 0.93);
+ break;
+ case Variant::TRANSFORM2D:
+ color = Color(0.59, 0.81, 0.1);
+ break;
+ case Variant::PLANE:
+ color = Color(0.97, 0.44, 0.44);
+ break;
+ case Variant::QUAT:
+ color = Color(0.93, 0.41, 0.64);
+ break;
+ case Variant::AABB:
+ color = Color(0.93, 0.47, 0.57);
+ break;
+ case Variant::BASIS:
+ color = Color(0.7, 0.73, 0.1);
+ break;
+ case Variant::TRANSFORM:
+ color = Color(0.96, 0.56, 0.28);
+ break;
+
+ case Variant::COLOR:
+ color = Color(0.24, 0.75, 0.0);
+ break;
+ case Variant::NODE_PATH:
+ color = Color(0.41, 0.58, 0.93);
+ break;
+ case Variant::_RID:
+ color = Color(0.17, 0.9, 0.45);
+ break;
+ case Variant::OBJECT:
+ color = Color(0.07, 0.84, 0.76);
+ break;
+ case Variant::DICTIONARY:
+ color = Color(0.34, 0.91, 0.62);
+ break;
+
+ case Variant::ARRAY:
+ color = Color(0.45, 0.45, 0.45);
+ break;
+ case Variant::PACKED_BYTE_ARRAY:
+ color = Color(0.38, 0.92, 0.6);
+ break;
+ case Variant::PACKED_INT32_ARRAY:
+ color = Color(0.38, 0.73, 0.92);
+ break;
+ case Variant::PACKED_FLOAT32_ARRAY:
+ color = Color(0.25, 0.83, 0.95);
+ break;
+ case Variant::PACKED_INT64_ARRAY:
+ color = Color(0.38, 0.73, 0.92);
+ break;
+ case Variant::PACKED_FLOAT64_ARRAY:
+ color = Color(0.25, 0.83, 0.95);
+ break;
+ case Variant::PACKED_STRING_ARRAY:
+ color = Color(0.38, 0.62, 0.92);
+ break;
+ case Variant::PACKED_VECTOR2_ARRAY:
+ color = Color(0.62, 0.36, 0.92);
+ break;
+ case Variant::PACKED_VECTOR3_ARRAY:
+ color = Color(0.79, 0.35, 0.92);
+ break;
+ case Variant::PACKED_COLOR_ARRAY:
+ color = Color(0.57, 0.73, 0.0);
+ break;
default:
color.set_hsv(p_type / float(Variant::VARIANT_MAX), 0.3, 0.3);
}
+ }
return color;
}
void VisualScriptEditor::_update_graph_connections() {
-
graph->clear_connections();
List<StringName> funcs;
@@ -441,12 +555,10 @@ void VisualScriptEditor::_update_graph_connections() {
}
for (List<StringName>::Element *F = funcs.front(); F; F = F->next()) {
-
List<VisualScript::SequenceConnection> sequence_conns;
script->get_sequence_connection_list(F->get(), &sequence_conns);
for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) {
-
graph->connect_node(itos(E->get().from_node), E->get().from_output, itos(E->get().to_node), 0);
}
@@ -454,7 +566,6 @@ void VisualScriptEditor::_update_graph_connections() {
script->get_data_connection_list(F->get(), &data_conns);
for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) {
-
VisualScript::DataConnection dc = E->get();
Ref<VisualScriptNode> from_node = script->get_node(F->get(), E->get().from_node);
@@ -472,9 +583,9 @@ void VisualScriptEditor::_update_graph_connections() {
}
void VisualScriptEditor::_update_graph(int p_only_id) {
-
- if (updating_graph)
+ if (updating_graph) {
return;
+ }
updating_graph = true;
@@ -482,13 +593,12 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
if (p_only_id >= 0) {
if (graph->has_node(itos(p_only_id))) {
Node *gid = graph->get_node(itos(p_only_id));
- if (gid)
+ if (gid) {
memdelete(gid);
+ }
}
} else {
-
for (int i = 0; i < graph->get_child_count(); i++) {
-
if (Object::cast_to<GraphNode>(graph->get_child(i))) {
memdelete(graph->get_child(i));
i--;
@@ -553,9 +663,9 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
StringName editor_icons = "EditorIcons";
for (List<int>::Element *E = ids.front(); E; E = E->next()) {
-
- if (p_only_id >= 0 && p_only_id != E->get())
+ if (p_only_id >= 0 && p_only_id != E->get()) {
continue;
+ }
Ref<VisualScriptNode> node = script->get_node(F->get(), E->get());
Vector2 pos = script->get_node_position(F->get(), E->get());
@@ -593,8 +703,9 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
btn->connect("pressed", callable_mp(this, &VisualScriptEditor::_add_input_port), varray(E->get()), CONNECT_DEFERRED);
}
if (nd_list->is_output_port_editable()) {
- if (nd_list->is_input_port_editable())
+ if (nd_list->is_input_port_editable()) {
hbnc->add_spacer();
+ }
has_gnode_text = true;
Button *btn = memnew(Button);
btn->set_text(TTR("Add Output Port"));
@@ -630,8 +741,9 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
if (node_styles.has(node->get_category())) {
Ref<StyleBoxFlat> sbf = node_styles[node->get_category()];
- if (gnode->is_comment())
+ if (gnode->is_comment()) {
sbf = EditorNode::get_singleton()->get_theme_base()->get_theme()->get_stylebox("comment", "GraphNode");
+ }
Color c = sbf->get_border_color();
Color ic = c;
@@ -679,12 +791,10 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
int mixed_seq_ports = 0;
if (!single_seq_output) {
-
if (node->has_mixed_input_and_sequence_ports()) {
mixed_seq_ports = node->get_output_sequence_port_count();
} else {
for (int i = 0; i < node->get_output_sequence_port_count(); i++) {
-
Label *text2 = memnew(Label);
text2->set_text(node->get_output_sequence_port_text(i));
text2->set_align(Label::ALIGN_RIGHT);
@@ -696,7 +806,6 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
}
for (int i = 0; i < MAX(node->get_output_value_port_count(), MAX(mixed_seq_ports, node->get_input_value_port_count())); i++) {
-
bool left_ok = false;
Variant::Type left_type = Variant::NIL;
String left_name;
@@ -724,7 +833,6 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
vbc->add_child(hbc);
vbc->add_child(hbc2);
if (left_ok) {
-
Ref<Texture2D> t;
if (left_type >= 0 && left_type < Variant::VARIANT_MAX) {
t = type_icons[left_type];
@@ -769,7 +877,6 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
}
if (left_type != Variant::NIL && !script->is_input_value_port_connected(F->get(), E->get(), i)) {
-
PropertyInfo pi = node->get_input_value_port_info(i);
Button *button = memnew(Button);
Variant value = node->get_default_input_value(i);
@@ -785,7 +892,6 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
button->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
button->connect("draw", callable_mp(this, &VisualScriptEditor::_draw_color_over_button), varray(button, value));
} else if (left_type == Variant::OBJECT && Ref<Resource>(value).is_valid()) {
-
Ref<Resource> res = value;
Array arr;
arr.push_back(button->get_instance_id());
@@ -793,10 +899,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
EditorResourcePreview::get_singleton()->queue_edited_resource_preview(res, this, "_button_resource_previewed", arr);
} else if (pi.type == Variant::INT && pi.hint == PROPERTY_HINT_ENUM) {
-
button->set_text(pi.hint_string.get_slice(",", value));
} else {
-
button->set_text(value);
}
button->connect("pressed", callable_mp(this, &VisualScriptEditor::_default_value_edited), varray(button, E->get(), i));
@@ -812,7 +916,6 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
hbc2->add_spacer();
if (i < mixed_seq_ports) {
-
Label *text2 = memnew(Label);
text2->set_text(node->get_output_sequence_port_text(i));
text2->set_align(Label::ALIGN_RIGHT);
@@ -820,7 +923,6 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
}
if (right_ok) {
-
if (is_vslist) {
Button *rmbtn = memnew(Button);
rmbtn->set_icon(EditorNode::get_singleton()->get_gui_base()->get_theme_icon("Remove", "EditorIcons"));
@@ -891,12 +993,12 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
}
void VisualScriptEditor::_change_port_type(int p_select, int p_id, int p_port, bool is_input) {
-
StringName func = _get_function_of_node(p_id);
Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
- if (!vsn.is_valid())
+ if (!vsn.is_valid()) {
return;
+ }
undo_redo->create_action("Change Port Type");
if (is_input) {
@@ -910,24 +1012,27 @@ void VisualScriptEditor::_change_port_type(int p_select, int p_id, int p_port, b
}
void VisualScriptEditor::_update_node_size(int p_id) {
-
Node *node = graph->get_node(itos(p_id));
- if (Object::cast_to<Control>(node))
+ if (Object::cast_to<Control>(node)) {
Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); //shrink if text is smaller
+ }
}
+
void VisualScriptEditor::_port_name_focus_out(const Node *p_name_box, int p_id, int p_port, bool is_input) {
StringName func = _get_function_of_node(p_id);
Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
- if (!vsn.is_valid())
+ if (!vsn.is_valid()) {
return;
+ }
String text;
- if (Object::cast_to<LineEdit>(p_name_box))
+ if (Object::cast_to<LineEdit>(p_name_box)) {
text = Object::cast_to<LineEdit>(p_name_box)->get_text();
- else
+ } else {
return;
+ }
undo_redo->create_action("Change Port Name");
if (is_input) {
@@ -958,7 +1063,6 @@ void VisualScriptEditor::_update_members() {
List<StringName> func_names;
script->get_function_list(&func_names);
for (List<StringName>::Element *E = func_names.front(); E; E = E->next()) {
-
if (E->get() == default_func) {
continue;
}
@@ -968,8 +1072,9 @@ void VisualScriptEditor::_update_members() {
ti->set_selectable(0, true);
ti->set_metadata(0, E->get());
ti->add_button(0, Control::get_theme_icon("Edit", "EditorIcons"), 0);
- if (selected == E->get())
+ if (selected == E->get()) {
ti->select(0);
+ }
}
TreeItem *variables = members->create_item(root);
@@ -1026,8 +1131,9 @@ void VisualScriptEditor::_update_members() {
ti->set_selectable(0, true);
ti->set_editable(0, true);
ti->set_metadata(0, E->get());
- if (selected == E->get())
+ if (selected == E->get()) {
ti->select(0);
+ }
}
TreeItem *_signals = members->create_item(root);
@@ -1044,8 +1150,9 @@ void VisualScriptEditor::_update_members() {
ti->set_selectable(0, true);
ti->set_editable(0, true);
ti->set_metadata(0, E->get());
- if (selected == E->get())
+ if (selected == E->get()) {
ti->select(0);
+ }
}
String base_type = script->get_instance_base_type();
@@ -1061,9 +1168,9 @@ void VisualScriptEditor::_update_members() {
}
void VisualScriptEditor::_member_selected() {
-
- if (updating_members)
+ if (updating_members) {
return;
+ }
TreeItem *ti = members->get_selected();
ERR_FAIL_COND(!ti);
@@ -1071,11 +1178,10 @@ void VisualScriptEditor::_member_selected() {
selected = ti->get_metadata(0);
if (ti->get_parent() == members->get_root()->get_children()) {
-
#ifdef OSX_ENABLED
- bool held_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_META);
+ bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_META);
#else
- bool held_ctrl = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool held_ctrl = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
#endif
if (held_ctrl) {
ERR_FAIL_COND(!script->has_function(selected));
@@ -1085,9 +1191,9 @@ void VisualScriptEditor::_member_selected() {
}
void VisualScriptEditor::_member_edited() {
-
- if (updating_members)
+ if (updating_members) {
return;
+ }
TreeItem *ti = members->get_edited();
ERR_FAIL_COND(!ti);
@@ -1095,11 +1201,11 @@ void VisualScriptEditor::_member_edited() {
String name = ti->get_metadata(0);
String new_name = ti->get_text(0);
- if (name == new_name)
+ if (name == new_name) {
return;
+ }
if (!new_name.is_valid_identifier()) {
-
EditorNode::get_singleton()->show_warning(TTR("Name is not a valid identifier:") + " " + new_name);
updating_members = true;
ti->set_text(0, name);
@@ -1108,7 +1214,6 @@ void VisualScriptEditor::_member_edited() {
}
if (script->has_function(new_name) || script->has_variable(new_name) || script->has_custom_signal(new_name)) {
-
EditorNode::get_singleton()->show_warning(TTR("Name already in use by another func/var/signal:") + " " + new_name);
updating_members = true;
ti->set_text(0, name);
@@ -1119,7 +1224,6 @@ void VisualScriptEditor::_member_edited() {
TreeItem *root = members->get_root();
if (ti->get_parent() == root->get_children()) {
-
selected = new_name;
int node_id = script->get_function_node_id(name);
@@ -1143,8 +1247,9 @@ void VisualScriptEditor::_member_edited() {
script->get_node_list(E->get(), &lst);
for (List<int>::Element *F = lst.front(); F; F = F->next()) {
Ref<VisualScriptFunctionCall> fncall = script->get_node(E->get(), F->get());
- if (!fncall.is_valid())
+ if (!fncall.is_valid()) {
continue;
+ }
if (fncall->get_function() == name) {
undo_redo->add_do_method(fncall.ptr(), "set_function", new_name);
undo_redo->add_undo_method(fncall.ptr(), "set_function", name);
@@ -1164,7 +1269,6 @@ void VisualScriptEditor::_member_edited() {
}
if (ti->get_parent() == root->get_children()->get_next()) {
-
selected = new_name;
undo_redo->create_action(TTR("Rename Variable"));
undo_redo->add_do_method(script.ptr(), "rename_variable", name, new_name);
@@ -1181,7 +1285,6 @@ void VisualScriptEditor::_member_edited() {
}
if (ti->get_parent() == root->get_children()->get_next()->get_next()) {
-
selected = new_name;
undo_redo->create_action(TTR("Rename Signal"));
undo_redo->add_do_method(script.ptr(), "rename_custom_signal", name, new_name);
@@ -1218,8 +1321,9 @@ void VisualScriptEditor::_create_function() {
for (int i = 0; i < func_input_vbox->get_child_count(); i++) {
OptionButton *opbtn = Object::cast_to<OptionButton>(func_input_vbox->get_child(i)->get_child(3));
LineEdit *lne = Object::cast_to<LineEdit>(func_input_vbox->get_child(i)->get_child(1));
- if (!opbtn || !lne)
+ if (!opbtn || !lne) {
continue;
+ }
Variant::Type arg_type = Variant::Type(opbtn->get_selected());
String arg_name = lne->get_text();
func_node->add_argument(arg_type, arg_name);
@@ -1264,8 +1368,9 @@ void VisualScriptEditor::_add_func_input() {
OptionButton *type_box = memnew(OptionButton);
type_box->set_custom_minimum_size(Size2(120 * EDSCALE, 0));
- for (int i = Variant::NIL; i < Variant::VARIANT_MAX; i++)
+ for (int i = Variant::NIL; i < Variant::VARIANT_MAX; i++) {
type_box->add_item(Variant::get_type_name(Variant::Type(i)));
+ }
type_box->select(1);
hbox->add_child(type_box);
@@ -1297,13 +1402,13 @@ void VisualScriptEditor::_deselect_input_names() {
int cn = func_input_vbox->get_child_count();
for (int i = 0; i < cn; i++) {
LineEdit *lne = Object::cast_to<LineEdit>(func_input_vbox->get_child(i)->get_child(1));
- if (lne)
+ if (lne) {
lne->deselect();
+ }
}
}
void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_button) {
-
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
TreeItem *root = members->get_root();
@@ -1318,7 +1423,6 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
return;
} else if (p_button == 0) {
-
String name = _validate_name("new_function");
selected = name;
Vector2 ofs = _get_available_pos();
@@ -1378,7 +1482,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
}
} else if (ti->get_parent() == root->get_children()) {
selected = ti->get_text(0);
- function_name_edit->set_position(InputFilter::get_singleton()->get_mouse_position() - Vector2(60, -10));
+ function_name_edit->set_position(Input::get_singleton()->get_mouse_position() - Vector2(60, -10));
function_name_edit->popup();
function_name_box->set_text(selected);
function_name_box->select_all();
@@ -1386,12 +1490,12 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
}
void VisualScriptEditor::_add_input_port(int p_id) {
-
StringName func = _get_function_of_node(p_id);
Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
- if (!vsn.is_valid())
+ if (!vsn.is_valid()) {
return;
+ }
updating_graph = true;
@@ -1408,12 +1512,12 @@ void VisualScriptEditor::_add_input_port(int p_id) {
}
void VisualScriptEditor::_add_output_port(int p_id) {
-
StringName func = _get_function_of_node(p_id);
Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
- if (!vsn.is_valid())
+ if (!vsn.is_valid()) {
return;
+ }
updating_graph = true;
@@ -1430,12 +1534,12 @@ void VisualScriptEditor::_add_output_port(int p_id) {
}
void VisualScriptEditor::_remove_input_port(int p_id, int p_port) {
-
StringName func = _get_function_of_node(p_id);
Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
- if (!vsn.is_valid())
+ if (!vsn.is_valid()) {
return;
+ }
updating_graph = true;
@@ -1444,14 +1548,16 @@ void VisualScriptEditor::_remove_input_port(int p_id, int p_port) {
int conn_from = -1, conn_port = -1;
script->get_input_value_port_connection_source(func, p_id, p_port, &conn_from, &conn_port);
- if (conn_from != -1)
+ if (conn_from != -1) {
undo_redo->add_do_method(script.ptr(), "data_disconnect", func, conn_from, conn_port, p_id, p_port);
+ }
undo_redo->add_do_method(vsn.ptr(), "remove_input_data_port", p_port);
undo_redo->add_do_method(this, "_update_graph", p_id);
- if (conn_from != -1)
+ if (conn_from != -1) {
undo_redo->add_undo_method(script.ptr(), "data_connect", func, conn_from, conn_port, p_id, p_port);
+ }
undo_redo->add_undo_method(vsn.ptr(), "add_input_data_port", vsn->get_input_value_port_info(p_port).type, vsn->get_input_value_port_info(p_port).name, p_port);
undo_redo->add_undo_method(this, "_update_graph", p_id);
@@ -1462,12 +1568,12 @@ void VisualScriptEditor::_remove_input_port(int p_id, int p_port) {
}
void VisualScriptEditor::_remove_output_port(int p_id, int p_port) {
-
StringName func = _get_function_of_node(p_id);
Ref<VisualScriptLists> vsn = script->get_node(func, p_id);
- if (!vsn.is_valid())
+ if (!vsn.is_valid()) {
return;
+ }
updating_graph = true;
@@ -1480,8 +1586,9 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) {
for (const List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
if (E->get().from_node == p_id && E->get().from_port == p_port) {
// push into the connections map
- if (!conn_map.has(E->get().to_node))
+ if (!conn_map.has(E->get().to_node)) {
conn_map.set(E->get().to_node, Set<int>());
+ }
conn_map[E->get().to_node].insert(E->get().to_port);
}
}
@@ -1506,12 +1613,12 @@ void VisualScriptEditor::_remove_output_port(int p_id, int p_port) {
}
void VisualScriptEditor::_expression_text_changed(const String &p_text, int p_id) {
-
StringName func = _get_function_of_node(p_id);
Ref<VisualScriptExpression> vse = script->get_node(func, p_id);
- if (!vse.is_valid())
+ if (!vse.is_valid()) {
return;
+ }
updating_graph = true;
@@ -1523,15 +1630,17 @@ void VisualScriptEditor::_expression_text_changed(const String &p_text, int p_id
undo_redo->commit_action();
Node *node = graph->get_node(itos(p_id));
- if (Object::cast_to<Control>(node))
+ if (Object::cast_to<Control>(node)) {
Object::cast_to<Control>(node)->set_size(Vector2(1, 1)); //shrink if text is smaller
+ }
updating_graph = false;
}
Vector2 VisualScriptEditor::_get_available_pos(bool centered, Vector2 ofs) const {
- if (centered)
+ if (centered) {
ofs = graph->get_scroll_ofs() + graph->get_size() * 0.5;
+ }
if (graph->is_using_snap()) {
int snap = graph->get_snap();
@@ -1557,8 +1666,9 @@ Vector2 VisualScriptEditor::_get_available_pos(bool centered, Vector2 ofs) const
}
}
}
- if (exists)
+ if (exists) {
continue;
+ }
break;
}
@@ -1566,12 +1676,10 @@ Vector2 VisualScriptEditor::_get_available_pos(bool centered, Vector2 ofs) const
}
String VisualScriptEditor::_validate_name(const String &p_name) const {
-
String valid = p_name;
int counter = 1;
while (true) {
-
bool exists = script->has_function(valid) || script->has_variable(valid) || script->has_custom_signal(valid);
if (exists) {
@@ -1587,7 +1695,6 @@ String VisualScriptEditor::_validate_name(const String &p_name) const {
}
void VisualScriptEditor::_on_nodes_delete() {
-
// delete all the selected nodes
List<int> to_erase;
@@ -1601,13 +1708,13 @@ void VisualScriptEditor::_on_nodes_delete() {
}
}
- if (to_erase.empty())
+ if (to_erase.empty()) {
return;
+ }
undo_redo->create_action(TTR("Remove VisualScript Nodes"));
for (List<int>::Element *F = to_erase.front(); F; F = F->next()) {
-
int cr_node = F->get();
StringName func = _get_function_of_node(cr_node);
@@ -1619,7 +1726,6 @@ void VisualScriptEditor::_on_nodes_delete() {
script->get_sequence_connection_list(func, &sequence_conns);
for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) {
-
if (E->get().from_node == cr_node || E->get().to_node == cr_node) {
undo_redo->add_undo_method(script.ptr(), "sequence_connect", func, E->get().from_node, E->get().from_output, E->get().to_node);
}
@@ -1629,7 +1735,6 @@ void VisualScriptEditor::_on_nodes_delete() {
script->get_data_connection_list(func, &data_conns);
for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) {
-
if (E->get().from_node == F->get() || E->get().to_node == F->get()) {
undo_redo->add_undo_method(script.ptr(), "data_connect", func, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
}
@@ -1642,7 +1747,6 @@ void VisualScriptEditor::_on_nodes_delete() {
}
void VisualScriptEditor::_on_nodes_duplicate() {
-
Set<int> to_duplicate;
List<StringName> funcs;
@@ -1657,8 +1761,9 @@ void VisualScriptEditor::_on_nodes_duplicate() {
}
}
- if (to_duplicate.empty())
+ if (to_duplicate.empty()) {
return;
+ }
undo_redo->create_action(TTR("Duplicate VisualScript Nodes"));
int idc = script->get_available_id() + 1;
@@ -1667,7 +1772,6 @@ void VisualScriptEditor::_on_nodes_duplicate() {
HashMap<int, int> remap;
for (Set<int>::Element *F = to_duplicate.front(); F; F = F->next()) {
-
// duplicate from the specific function but place it into the default func as it would lack the connections
StringName func = _get_function_of_node(F->get());
Ref<VisualScriptNode> node = script->get_node(func, F->get());
@@ -1719,10 +1823,11 @@ void VisualScriptEditor::_on_nodes_duplicate() {
}
void VisualScriptEditor::_generic_search(String p_base_type, Vector2 pos, bool node_centered) {
- if (node_centered)
+ if (node_centered) {
port_action_pos = graph->get_size() / 2.0f;
- else
+ } else {
port_action_pos = graph->get_viewport()->get_mouse_position() - graph->get_global_position();
+ }
new_connect_node_select->select_from_visual_script(p_base_type, false, false); // neither connecting nor reset text
@@ -1731,8 +1836,9 @@ void VisualScriptEditor::_generic_search(String p_base_type, Vector2 pos, bool n
pos.x = pos.x > bounds.x ? bounds.x : pos.x;
pos.y = pos.y > bounds.y ? bounds.y : pos.y;
- if (pos != Vector2())
+ if (pos != Vector2()) {
new_connect_node_select->set_position(pos);
+ }
}
void VisualScriptEditor::_input(const Ref<InputEvent> &p_event) {
@@ -1740,7 +1846,7 @@ void VisualScriptEditor::_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> key = p_event;
if (key.is_valid() && !key->is_pressed()) {
- mouse_up_position = InputFilter::get_singleton()->get_mouse_position();
+ mouse_up_position = Input::get_singleton()->get_mouse_position();
}
}
@@ -1750,13 +1856,12 @@ void VisualScriptEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
if (key.is_valid() && key->is_pressed() && key->get_button_mask() == BUTTON_RIGHT) {
saved_position = graph->get_local_mouse_position();
- Point2 gpos = InputFilter::get_singleton()->get_mouse_position();
+ Point2 gpos = Input::get_singleton()->get_mouse_position();
_generic_search(script->get_instance_base_type(), gpos);
}
}
void VisualScriptEditor::_members_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventKey> key = p_event;
if (key.is_valid() && key->is_pressed() && !key->is_echo()) {
if (members->has_focus()) {
@@ -1786,21 +1891,19 @@ void VisualScriptEditor::_members_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> btn = p_event;
if (btn.is_valid() && btn->is_doubleclick()) {
TreeItem *ti = members->get_selected();
- if (ti && ti->get_parent() == members->get_root()->get_children()) // to check if it's a function
+ if (ti && ti->get_parent() == members->get_root()->get_children()) { // to check if it's a function
_center_on_node(ti->get_metadata(0), script->get_function_node_id(ti->get_metadata(0)));
+ }
}
}
void VisualScriptEditor::_rename_function(const String &name, const String &new_name) {
-
if (!new_name.is_valid_identifier()) {
-
EditorNode::get_singleton()->show_warning(TTR("Name is not a valid identifier:") + " " + new_name);
return;
}
if (script->has_function(new_name) || script->has_variable(new_name) || script->has_custom_signal(new_name)) {
-
EditorNode::get_singleton()->show_warning(TTR("Name already in use by another func/var/signal:") + " " + new_name);
return;
}
@@ -1826,8 +1929,9 @@ void VisualScriptEditor::_rename_function(const String &name, const String &new_
script->get_node_list(E->get(), &lst);
for (List<int>::Element *F = lst.front(); F; F = F->next()) {
Ref<VisualScriptFunctionCall> fncall = script->get_node(E->get(), F->get());
- if (!fncall.is_valid())
+ if (!fncall.is_valid()) {
continue;
+ }
if (fncall->get_function() == name) {
undo_redo->add_do_method(fncall.ptr(), "set_function", new_name);
undo_redo->add_undo_method(fncall.ptr(), "set_function", name);
@@ -1845,9 +1949,9 @@ void VisualScriptEditor::_rename_function(const String &name, const String &new_
}
void VisualScriptEditor::_fn_name_box_input(const Ref<InputEvent> &p_event) {
-
- if (!function_name_edit->is_visible())
+ if (!function_name_edit->is_visible()) {
return;
+ }
Ref<InputEventKey> key = p_event;
if (key.is_valid() && key->is_pressed() && key->get_keycode() == KEY_ENTER) {
@@ -1858,31 +1962,28 @@ void VisualScriptEditor::_fn_name_box_input(const Ref<InputEvent> &p_event) {
}
Variant VisualScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
-
if (p_from == members) {
-
TreeItem *it = members->get_item_at_position(p_point);
- if (!it)
+ if (!it) {
return Variant();
+ }
String type = it->get_metadata(0);
- if (type == String())
+ if (type == String()) {
return Variant();
+ }
Dictionary dd;
TreeItem *root = members->get_root();
if (it->get_parent() == root->get_children()) {
-
dd["type"] = "visual_script_function_drag";
dd["function"] = type;
} else if (it->get_parent() == root->get_children()->get_next()) {
-
dd["type"] = "visual_script_variable_drag";
dd["variable"] = type;
} else if (it->get_parent() == root->get_children()->get_next()->get_next()) {
-
dd["type"] = "visual_script_signal_drag";
dd["signal"] = type;
@@ -1899,9 +2000,7 @@ Variant VisualScriptEditor::get_drag_data_fw(const Point2 &p_point, Control *p_f
}
bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
-
if (p_from == graph) {
-
Dictionary d = p_data;
if (d.has("type") &&
(String(d["type"]) == "visual_script_node_drag" ||
@@ -1912,9 +2011,7 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
String(d["type"]) == "resource" ||
String(d["type"]) == "files" ||
String(d["type"]) == "nodes")) {
-
if (String(d["type"]) == "obj_property") {
-
#ifdef OSX_ENABLED
const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Getter. Hold Shift to drop a generic signature."), find_keycode_name(KEY_META)));
#else
@@ -1923,7 +2020,6 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
}
if (String(d["type"]) == "nodes") {
-
#ifdef OSX_ENABLED
const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a simple reference to the node."), find_keycode_name(KEY_META)));
#else
@@ -1932,7 +2028,6 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
}
if (String(d["type"]) == "visual_script_variable_drag") {
-
#ifdef OSX_ENABLED
const_cast<VisualScriptEditor *>(this)->_show_hint(vformat(TTR("Hold %s to drop a Variable Setter."), find_keycode_name(KEY_META)));
#else
@@ -1948,26 +2043,27 @@ bool VisualScriptEditor::can_drop_data_fw(const Point2 &p_point, const Variant &
}
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
-
- if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
+ if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) {
return nullptr;
+ }
Ref<Script> scr = p_current_node->get_script();
- if (scr.is_valid() && scr == script)
+ if (scr.is_valid() && scr == script) {
return p_current_node;
+ }
for (int i = 0; i < p_current_node->get_child_count(); i++) {
Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);
- if (n)
+ if (n) {
return n;
+ }
}
return nullptr;
}
void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
-
if (p_from != graph) {
return;
}
@@ -2002,11 +2098,10 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
if (String(d["type"]) == "visual_script_variable_drag") {
-
#ifdef OSX_ENABLED
- bool use_set = InputFilter::get_singleton()->is_key_pressed(KEY_META);
+ bool use_set = Input::get_singleton()->is_key_pressed(KEY_META);
#else
- bool use_set = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool use_set = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
#endif
Vector2 ofs = graph->get_scroll_ofs() + p_point;
if (graph->is_using_snap()) {
@@ -2023,7 +2118,6 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
vnodes->set_variable(d["variable"]);
vnode = vnodes;
} else {
-
Ref<VisualScriptVariableGet> vnodeg;
vnodeg.instance();
vnodeg->set_variable(d["variable"]);
@@ -2047,7 +2141,6 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
if (String(d["type"]) == "visual_script_function_drag") {
-
Vector2 ofs = graph->get_scroll_ofs() + p_point;
if (graph->is_using_snap()) {
int snap = graph->get_snap();
@@ -2080,7 +2173,6 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
if (String(d["type"]) == "visual_script_signal_drag") {
-
Vector2 ofs = graph->get_scroll_ofs() + p_point;
if (graph->is_using_snap()) {
int snap = graph->get_snap();
@@ -2110,7 +2202,6 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
if (String(d["type"]) == "resource") {
-
Vector2 ofs = graph->get_scroll_ofs() + p_point;
if (graph->is_using_snap()) {
int snap = graph->get_snap();
@@ -2140,7 +2231,6 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
if (String(d["type"]) == "files") {
-
Vector2 ofs = graph->get_scroll_ofs() + p_point;
if (graph->is_using_snap()) {
int snap = graph->get_snap();
@@ -2158,10 +2248,10 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
undo_redo->create_action(TTR("Add Preload Node"));
for (int i = 0; i < files.size(); i++) {
-
Ref<Resource> res = ResourceLoader::load(files[i]);
- if (!res.is_valid())
+ if (!res.is_valid()) {
continue;
+ }
Ref<VisualScriptPreload> prnode;
prnode.instance();
@@ -2180,7 +2270,6 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
for (List<int>::Element *E = new_ids.front(); E; E = E->next()) {
-
Node *node = graph->get_node(itos(E->get()));
if (node) {
graph->set_selected(node);
@@ -2190,7 +2279,6 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
if (String(d["type"]) == "nodes") {
-
Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script);
if (!sn) {
@@ -2199,9 +2287,9 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
#ifdef OSX_ENABLED
- bool use_node = InputFilter::get_singleton()->is_key_pressed(KEY_META);
+ bool use_node = Input::get_singleton()->is_key_pressed(KEY_META);
#else
- bool use_node = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool use_node = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
#endif
Array nodes = d["nodes"];
@@ -2222,7 +2310,6 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
for (int i = 0; i < nodes.size(); i++) {
-
NodePath np = nodes[i];
Node *node = get_node(np);
if (!node) {
@@ -2260,18 +2347,18 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
if (String(d["type"]) == "obj_property") {
-
Node *sn = _find_script_node(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root(), script);
- if (!sn && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (!sn && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
EditorNode::get_singleton()->show_warning(vformat(TTR("Can't drop properties because script '%s' is not used in this scene.\nDrop holding 'Shift' to just copy the signature."), get_name()));
return;
}
Object *obj = d["object"];
- if (!obj)
+ if (!obj) {
return;
+ }
Node *node = Object::cast_to<Node>(obj);
Vector2 ofs = graph->get_scroll_ofs() + p_point;
@@ -2283,24 +2370,23 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
ofs /= EDSCALE;
#ifdef OSX_ENABLED
- bool use_get = InputFilter::get_singleton()->is_key_pressed(KEY_META);
+ bool use_get = Input::get_singleton()->is_key_pressed(KEY_META);
#else
- bool use_get = InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL);
+ bool use_get = Input::get_singleton()->is_key_pressed(KEY_CONTROL);
#endif
- if (!node || InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
-
- if (use_get)
+ if (!node || Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (use_get) {
undo_redo->create_action(TTR("Add Getter Property"));
- else
+ } else {
undo_redo->create_action(TTR("Add Setter Property"));
+ }
int base_id = script->get_available_id();
Ref<VisualScriptNode> vnode;
if (!use_get) {
-
Ref<VisualScriptPropertySet> pset;
pset.instance();
pset->set_call_mode(VisualScriptPropertySet::CALL_MODE_INSTANCE);
@@ -2311,7 +2397,6 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}*/
vnode = pset;
} else {
-
Ref<VisualScriptPropertyGet> pget;
pget.instance();
pget->set_call_mode(VisualScriptPropertyGet::CALL_MODE_INSTANCE);
@@ -2333,18 +2418,17 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
undo_redo->commit_action();
} else {
-
- if (use_get)
+ if (use_get) {
undo_redo->create_action(TTR("Add Getter Property"));
- else
+ } else {
undo_redo->create_action(TTR("Add Setter Property"));
+ }
int base_id = script->get_available_id();
Ref<VisualScriptNode> vnode;
if (!use_get) {
-
Ref<VisualScriptPropertySet> pset;
pset.instance();
if (sn == node) {
@@ -2356,7 +2440,6 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
vnode = pset;
} else {
-
Ref<VisualScriptPropertyGet> pget;
pget.instance();
if (sn == node) {
@@ -2382,33 +2465,33 @@ void VisualScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_da
}
void VisualScriptEditor::_selected_method(const String &p_method, const String &p_type, const bool p_connecting) {
-
Ref<VisualScriptFunctionCall> vsfc = script->get_node(default_func, selecting_method_id);
- if (!vsfc.is_valid())
+ if (!vsfc.is_valid()) {
return;
+ }
vsfc->set_function(p_method);
}
void VisualScriptEditor::_draw_color_over_button(Object *obj, Color p_color) {
-
Button *button = Object::cast_to<Button>(obj);
- if (!button)
+ if (!button) {
return;
+ }
Ref<StyleBox> normal = get_theme_stylebox("normal", "Button");
button->draw_rect(Rect2(normal->get_offset(), button->get_size() - normal->get_minimum_size()), p_color);
}
void VisualScriptEditor::_button_resource_previewed(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, Variant p_ud) {
-
Array ud = p_ud;
ERR_FAIL_COND(ud.size() != 2);
ObjectID id = ud[0];
Object *obj = ObjectDB::get_instance(id);
- if (!obj)
+ if (!obj) {
return;
+ }
Button *b = Object::cast_to<Button>(obj);
ERR_FAIL_COND(!b);
@@ -2416,7 +2499,6 @@ void VisualScriptEditor::_button_resource_previewed(const String &p_path, const
if (p_preview.is_null()) {
b->set_text(ud[1]);
} else {
-
b->set_icon(p_preview);
}
}
@@ -2431,7 +2513,6 @@ RES VisualScriptEditor::get_edited_resource() const {
}
void VisualScriptEditor::set_edited_resource(const RES &p_res) {
-
script = p_res;
signal_editor->script = script;
signal_editor->undo_redo = undo_redo;
@@ -2453,7 +2534,6 @@ void VisualScriptEditor::set_edited_resource(const RES &p_res) {
}
Vector<String> VisualScriptEditor::get_functions() {
-
return Vector<String>();
}
@@ -2461,7 +2541,6 @@ void VisualScriptEditor::reload_text() {
}
String VisualScriptEditor::get_name() {
-
String name;
if (script->get_path().find("local://") == -1 && script->get_path().find("::") == -1) {
@@ -2469,26 +2548,24 @@ String VisualScriptEditor::get_name() {
if (is_unsaved()) {
name += "(*)";
}
- } else if (script->get_name() != "")
+ } else if (script->get_name() != "") {
name = script->get_name();
- else
+ } else {
name = script->get_class() + "(" + itos(script->get_instance_id()) + ")";
+ }
return name;
}
Ref<Texture2D> VisualScriptEditor::get_theme_icon() {
-
return Control::get_theme_icon("VisualScript", "EditorIcons");
}
bool VisualScriptEditor::is_unsaved() {
-
return script->is_edited() || script->are_subnodes_edited();
}
Variant VisualScriptEditor::get_edit_state() {
-
Dictionary d;
d["function"] = default_func;
d["scroll"] = graph->get_scroll_ofs();
@@ -2499,7 +2576,6 @@ Variant VisualScriptEditor::get_edit_state() {
}
void VisualScriptEditor::set_edit_state(const Variant &p_state) {
-
Dictionary d = p_state;
if (d.has("function")) {
selected = default_func;
@@ -2523,15 +2599,15 @@ void VisualScriptEditor::set_edit_state(const Variant &p_state) {
}
void VisualScriptEditor::_center_on_node(const StringName &p_func, int p_id) {
-
Node *n = graph->get_node(itos(p_id));
GraphNode *gn = Object::cast_to<GraphNode>(n);
// clear selection
for (int i = 0; i < graph->get_child_count(); i++) {
GraphNode *gnd = Object::cast_to<GraphNode>(graph->get_child(i));
- if (gnd)
+ if (gnd) {
gnd->set_selected(false);
+ }
}
if (gn) {
@@ -2544,18 +2620,16 @@ void VisualScriptEditor::_center_on_node(const StringName &p_func, int p_id) {
}
void VisualScriptEditor::goto_line(int p_line, bool p_with_error) {
-
p_line += 1; //add one because script lines begin from 0.
- if (p_with_error)
+ if (p_with_error) {
error_line = p_line;
+ }
List<StringName> functions;
script->get_function_list(&functions);
for (List<StringName>::Element *E = functions.front(); E; E = E->next()) {
-
if (script->has_node(E->get(), p_line)) {
-
_update_graph();
_update_members();
@@ -2586,7 +2660,6 @@ void VisualScriptEditor::convert_indent_to_tabs() {
}
void VisualScriptEditor::ensure_focus() {
-
graph->grab_focus();
}
@@ -2598,15 +2671,12 @@ void VisualScriptEditor::reload(bool p_soft) {
}
void VisualScriptEditor::get_breakpoints(List<int> *p_breakpoints) {
-
List<StringName> functions;
script->get_function_list(&functions);
for (List<StringName>::Element *E = functions.front(); E; E = E->next()) {
-
List<int> nodes;
script->get_node_list(E->get(), &nodes);
for (List<int>::Element *F = nodes.front(); F; F = F->next()) {
-
Ref<VisualScriptNode> vsn = script->get_node(E->get(), F->get());
if (vsn->is_breakpoint()) {
p_breakpoints->push_back(F->get() - 1); //subtract 1 because breakpoints in text start from zero
@@ -2616,7 +2686,6 @@ void VisualScriptEditor::get_breakpoints(List<int> *p_breakpoints) {
}
void VisualScriptEditor::add_callback(const String &p_function, PackedStringArray p_args) {
-
if (script->has_function(p_function)) {
_update_members();
_update_graph();
@@ -2627,7 +2696,6 @@ void VisualScriptEditor::add_callback(const String &p_function, PackedStringArra
Ref<VisualScriptFunction> func;
func.instance();
for (int i = 0; i < p_args.size(); i++) {
-
String name = p_args[i];
Variant::Type type = Variant::NIL;
@@ -2635,7 +2703,6 @@ void VisualScriptEditor::add_callback(const String &p_function, PackedStringArra
String tt = name.get_slice(":", 1);
name = name.get_slice(":", 0);
for (int j = 0; j < Variant::VARIANT_MAX; j++) {
-
String tname = Variant::get_type_name(Variant::Type(j));
if (tname == tt) {
type = Variant::Type(j);
@@ -2662,7 +2729,6 @@ bool VisualScriptEditor::show_members_overview() {
}
void VisualScriptEditor::update_settings() {
-
_update_graph();
}
@@ -2677,12 +2743,10 @@ void VisualScriptEditor::set_tooltip_request_func(String p_method, Object *p_obj
}
Control *VisualScriptEditor::get_edit_menu() {
-
return edit_menu;
}
void VisualScriptEditor::_change_base_type() {
-
select_base_type->popup_create(true, true);
}
@@ -2696,7 +2760,6 @@ void VisualScriptEditor::clear_edit_menu() {
}
void VisualScriptEditor::_change_base_type_callback() {
-
String bt = select_base_type->get_selected_type();
ERR_FAIL_COND(bt == String());
@@ -2709,16 +2772,15 @@ void VisualScriptEditor::_change_base_type_callback() {
}
void VisualScriptEditor::_node_selected(Node *p_node) {
-
Ref<VisualScriptNode> vnode = p_node->get_meta("__vnode");
- if (vnode.is_null())
+ if (vnode.is_null()) {
return;
+ }
EditorNode::get_singleton()->push_item(vnode.ptr()); //edit node in inspector
}
static bool _get_out_slot(const Ref<VisualScriptNode> &p_node, int p_slot, int &r_real_slot, bool &r_sequence) {
-
if (p_slot < p_node->get_output_sequence_port_count()) {
r_sequence = true;
r_real_slot = p_slot;
@@ -2733,7 +2795,6 @@ static bool _get_out_slot(const Ref<VisualScriptNode> &p_node, int p_slot, int &
}
static bool _get_in_slot(const Ref<VisualScriptNode> &p_node, int p_slot, int &r_real_slot, bool &r_sequence) {
-
if (p_slot == 0 && p_node->has_input_sequence_port()) {
r_sequence = true;
r_real_slot = 0;
@@ -2747,30 +2808,28 @@ static bool _get_in_slot(const Ref<VisualScriptNode> &p_node, int p_slot, int &r
}
void VisualScriptEditor::_begin_node_move() {
-
undo_redo->create_action(TTR("Move Node(s)"));
}
void VisualScriptEditor::_end_node_move() {
-
undo_redo->commit_action();
}
void VisualScriptEditor::_move_node(const StringName &p_func, int p_id, const Vector2 &p_to) {
-
- if (!script->has_function(p_func))
+ if (!script->has_function(p_func)) {
return;
+ }
Node *node = graph->get_node(itos(p_id));
- if (Object::cast_to<GraphNode>(node))
+ if (Object::cast_to<GraphNode>(node)) {
Object::cast_to<GraphNode>(node)->set_offset(p_to);
+ }
script->set_node_position(p_func, p_id, p_to / EDSCALE);
}
StringName VisualScriptEditor::_get_function_of_node(int p_id) const {
-
List<StringName> funcs;
script->get_function_list(&funcs);
for (List<StringName>::Element *E = funcs.front(); E; E = E->next()) {
@@ -2783,7 +2842,6 @@ StringName VisualScriptEditor::_get_function_of_node(int p_id) const {
}
void VisualScriptEditor::_node_moved(Vector2 p_from, Vector2 p_to, int p_id) {
-
StringName func = _get_function_of_node(p_id);
undo_redo->add_do_method(this, "_move_node", func, p_id, p_to);
@@ -2791,7 +2849,6 @@ void VisualScriptEditor::_node_moved(Vector2 p_from, Vector2 p_to, int p_id) {
}
void VisualScriptEditor::_remove_node(int p_id) {
-
undo_redo->create_action(TTR("Remove VisualScript Node"));
StringName func = _get_function_of_node(p_id);
@@ -2803,7 +2860,6 @@ void VisualScriptEditor::_remove_node(int p_id) {
script->get_sequence_connection_list(func, &sequence_conns);
for (List<VisualScript::SequenceConnection>::Element *E = sequence_conns.front(); E; E = E->next()) {
-
if (E->get().from_node == p_id || E->get().to_node == p_id) {
undo_redo->add_undo_method(script.ptr(), "sequence_connect", func, E->get().from_node, E->get().from_output, E->get().to_node);
}
@@ -2813,7 +2869,6 @@ void VisualScriptEditor::_remove_node(int p_id) {
script->get_data_connection_list(func, &data_conns);
for (List<VisualScript::DataConnection>::Element *E = data_conns.front(); E; E = E->next()) {
-
if (E->get().from_node == p_id || E->get().to_node == p_id) {
undo_redo->add_undo_method(script.ptr(), "data_connect", func, E->get().from_node, E->get().from_port, E->get().to_node, E->get().to_port);
}
@@ -2826,7 +2881,6 @@ void VisualScriptEditor::_remove_node(int p_id) {
}
void VisualScriptEditor::_node_ports_changed(const String &p_func, int p_id) {
-
_update_graph(p_id);
}
@@ -2838,15 +2892,15 @@ bool VisualScriptEditor::node_has_sequence_connections(const StringName &p_func,
int from = E->get().from_node;
int to = E->get().to_node;
- if (to == p_id || from == p_id)
+ if (to == p_id || from == p_id) {
return true;
+ }
}
return false;
}
void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot) {
-
StringName from_func = _get_function_of_node(p_from.to_int());
Ref<VisualScriptNode> from_node = script->get_node(from_func, p_from.to_int());
@@ -2855,8 +2909,9 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot,
bool from_seq;
int from_port;
- if (!_get_out_slot(from_node, p_from_slot, from_port, from_seq))
+ if (!_get_out_slot(from_node, p_from_slot, from_port, from_seq)) {
return; //can't connect this, it's invalid
+ }
StringName to_func = _get_function_of_node(p_to.to_int());
@@ -2866,8 +2921,9 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot,
bool to_seq;
int to_port;
- if (!_get_in_slot(to_node, p_to_slot, to_port, to_seq))
+ if (!_get_in_slot(to_node, p_to_slot, to_port, to_seq)) {
return; //can't connect this, it's invalid
+ }
ERR_FAIL_COND(from_seq != to_seq);
@@ -2968,19 +3024,21 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot,
Vector2 constructor_pos;
if ((to_node_pos.x - from_node_pos.x) < 0) {
// to is behind from node
- if (to_node_pos.x > (from_node_pos.x - to_node_size.x - 240))
+ if (to_node_pos.x > (from_node_pos.x - to_node_size.x - 240)) {
new_to_node_pos.x = from_node_pos.x - to_node_size.x - 240; // approx size of constructor node + padding
- else
+ } else {
new_to_node_pos.x = to_node_pos.x;
+ }
new_to_node_pos.y = to_node_pos.y;
constructor_pos.x = from_node_pos.x - 210;
constructor_pos.y = to_node_pos.y;
} else {
// to is ahead of from node
- if (to_node_pos.x < (from_node_size.x + from_node_pos.x + 240))
+ if (to_node_pos.x < (from_node_size.x + from_node_pos.x + 240)) {
new_to_node_pos.x = from_node_size.x + from_node_pos.x + 240; // approx size of constructor node + padding
- else
+ } else {
new_to_node_pos.x = to_node_pos.x;
+ }
new_to_node_pos.y = to_node_pos.y;
constructor_pos.x = from_node_size.x + from_node_pos.x + 10;
constructor_pos.y = to_node_pos.y;
@@ -3044,7 +3102,6 @@ void VisualScriptEditor::_graph_connected(const String &p_from, int p_from_slot,
}
void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_slot, const String &p_to, int p_to_slot) {
-
StringName func = _get_function_of_node(p_from.to_int());
ERR_FAIL_COND(func != _get_function_of_node(p_to.to_int()));
@@ -3054,8 +3111,9 @@ void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_sl
bool from_seq;
int from_port;
- if (!_get_out_slot(from_node, p_from_slot, from_port, from_seq))
+ if (!_get_out_slot(from_node, p_from_slot, from_port, from_seq)) {
return; //can't connect this, it's invalid
+ }
Ref<VisualScriptNode> to_node = script->get_node(func, p_to.to_int());
ERR_FAIL_COND(!to_node.is_valid());
@@ -3063,8 +3121,9 @@ void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_sl
bool to_seq;
int to_port;
- if (!_get_in_slot(to_node, p_to_slot, to_port, to_seq))
+ if (!_get_in_slot(to_node, p_to_slot, to_port, to_seq)) {
return; //can't connect this, it's invalid
+ }
ERR_FAIL_COND(from_seq != to_seq);
@@ -3074,7 +3133,6 @@ void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_sl
undo_redo->add_do_method(script.ptr(), "sequence_disconnect", func, p_from.to_int(), from_port, p_to.to_int());
undo_redo->add_undo_method(script.ptr(), "sequence_connect", func, p_from.to_int(), from_port, p_to.to_int());
} else {
-
can_swap = true;
data_disconnect_node = p_to.to_int();
data_disconnect_port = to_port;
@@ -3094,7 +3152,6 @@ void VisualScriptEditor::_graph_disconnected(const String &p_from, int p_from_sl
}
void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from, const StringName &p_func_to, int p_id) {
-
Set<int> nodes_to_move;
HashMap<int, Map<int, int>> seqconns_to_move; // from => List(outp, to)
HashMap<int, Map<int, Pair<int, int>>> dataconns_to_move; // to => List(inp_p => from, outp)
@@ -3111,8 +3168,9 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from,
int from = E->get().from_node;
int to = E->get().to_node;
int out_p = E->get().from_output;
- if (!seqcons.has(from))
+ if (!seqcons.has(from)) {
seqcons.set(from, Map<int, int>());
+ }
seqcons[from].insert(out_p, to);
sequence_connections.insert(to);
sequence_connections.insert(from);
@@ -3135,12 +3193,14 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from,
}
continue;
}
- if (!seen.has(conn))
+ if (!seen.has(conn)) {
seen.set(conn, Set<int>());
+ }
seen[conn].insert(E->key());
stack.push_back(conn);
- if (!seqconns_to_move.has(conn))
+ if (!seqconns_to_move.has(conn)) {
seqconns_to_move.set(conn, Map<int, int>());
+ }
seqconns_to_move[conn].insert(E->key(), E->get());
conn = E->get();
nodes_to_move.insert(conn);
@@ -3165,8 +3225,9 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from,
int out_p = E->get().from_port;
int in_p = E->get().to_port;
- if (!connections.has(to))
+ if (!connections.has(to)) {
connections.set(to, Map<int, Pair<int, int>>());
+ }
connections[to].insert(in_p, Pair<int, int>(from, out_p));
}
@@ -3203,12 +3264,14 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from,
}
}
- if (!seen.has(id))
+ if (!seen.has(id)) {
seen.set(id, Set<int>());
+ }
seen[id].insert(E->key());
stack.push_back(id);
- if (!dataconns_to_move.has(id))
+ if (!dataconns_to_move.has(id)) {
dataconns_to_move.set(id, Map<int, Pair<int, int>>());
+ }
dataconns_to_move[id].insert(E->key(), Pair<int, int>(E->get().first, E->get().second));
id = E->get().first;
nodes_to_be_added.insert(id);
@@ -3304,22 +3367,22 @@ void VisualScriptEditor::_move_nodes_with_rescan(const StringName &p_func_from,
}
void VisualScriptEditor::_graph_connect_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_pos) {
-
Node *node = graph->get_node(p_from);
GraphNode *gn = Object::cast_to<GraphNode>(node);
- if (!gn)
+ if (!gn) {
return;
+ }
StringName func = _get_function_of_node(p_from.to_int());
Ref<VisualScriptNode> vsn = script->get_node(func, p_from.to_int());
- if (!vsn.is_valid())
+ if (!vsn.is_valid()) {
return;
+ }
port_action_pos = p_release_pos;
if (p_from_slot < vsn->get_output_sequence_port_count()) {
-
port_action_node = p_from.to_int();
port_action_output = p_from_slot;
_port_action_menu(CREATE_ACTION, func);
@@ -3331,12 +3394,12 @@ void VisualScriptEditor::_graph_connect_to_empty(const String &p_from, int p_fro
}
VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_action_node, int p_port_action_output, Set<int> &visited_nodes) {
-
VisualScriptNode::TypeGuess tg;
tg.type = Variant::NIL;
- if (visited_nodes.has(p_port_action_node))
+ if (visited_nodes.has(p_port_action_node)) {
return tg; //no loop
+ }
visited_nodes.insert(p_port_action_node);
@@ -3345,7 +3408,6 @@ VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_ac
Ref<VisualScriptNode> node = script->get_node(func, p_port_action_node);
if (!node.is_valid()) {
-
return tg;
}
@@ -3362,16 +3424,13 @@ VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_ac
int from_port;
if (script->get_input_value_port_connection_source(func, p_port_action_node, i, &from_node, &from_port)) {
-
g = _guess_output_type(from_node, from_port, visited_nodes);
} else {
Variant defval = node->get_default_input_value(i);
if (defval.get_type() == Variant::OBJECT) {
-
Object *obj = defval;
if (obj) {
-
g.type = Variant::OBJECT;
g.gdclass = obj->get_class();
g.script = obj->get_script();
@@ -3387,7 +3446,6 @@ VisualScriptNode::TypeGuess VisualScriptEditor::_guess_output_type(int p_port_ac
}
void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func) {
-
Vector2 ofs = graph->get_scroll_ofs() + port_action_pos;
if (graph->is_using_snap()) {
int snap = graph->get_snap();
@@ -3398,7 +3456,6 @@ void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func)
Set<int> vn;
switch (p_option) {
-
case CREATE_CALL_SET_GET: {
Ref<VisualScriptFunctionCall> n;
n.instance();
@@ -3462,7 +3519,6 @@ void VisualScriptEditor::_port_action_menu(int p_option, const StringName &func)
}
void VisualScriptEditor::connect_data(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode, int new_id) {
-
undo_redo->create_action(TTR("Connect Node Data"));
VisualScriptReturn *vnode_return = Object::cast_to<VisualScriptReturn>(vnode.ptr());
if (vnode_return != nullptr && vnode_old->get_output_value_port_count() > 0) {
@@ -3488,7 +3544,6 @@ void VisualScriptEditor::connect_data(Ref<VisualScriptNode> vnode_old, Ref<Visua
}
void VisualScriptEditor::_selected_connect_node(const String &p_text, const String &p_category, const bool p_connecting) {
-
Vector2 ofs = graph->get_scroll_ofs() + port_action_pos;
if (graph->is_using_snap()) {
int snap = graph->get_snap();
@@ -3510,8 +3565,9 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
if (p_category == "visualscript") {
Ref<VisualScriptNode> vnode_new = VisualScriptLanguage::singleton->create_node_from_name(p_text);
Ref<VisualScriptNode> vnode_old;
- if (port_node_exists)
+ if (port_node_exists) {
vnode_old = script->get_node(func, port_action_node);
+ }
int new_id = script->get_available_id();
if (Object::cast_to<VisualScriptOperator>(vnode_new.ptr()) && vnode_old.is_valid()) {
@@ -3550,18 +3606,15 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
Ref<VisualScriptPropertySet> script_prop_set;
if (p_category == String("method")) {
-
Ref<VisualScriptFunctionCall> n;
n.instance();
vnode = n;
} else if (p_category == String("set")) {
-
Ref<VisualScriptPropertySet> n;
n.instance();
vnode = n;
script_prop_set = n;
} else if (p_category == String("get")) {
-
Ref<VisualScriptPropertyGet> n;
n.instance();
n->set_property(p_text);
@@ -3570,33 +3623,27 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
if (p_category == String("action")) {
if (p_text == "VisualScriptCondition") {
-
Ref<VisualScriptCondition> n;
n.instance();
vnode = n;
}
if (p_text == "VisualScriptSwitch") {
-
Ref<VisualScriptSwitch> n;
n.instance();
vnode = n;
} else if (p_text == "VisualScriptSequence") {
-
Ref<VisualScriptSequence> n;
n.instance();
vnode = n;
} else if (p_text == "VisualScriptIterator") {
-
Ref<VisualScriptIterator> n;
n.instance();
vnode = n;
} else if (p_text == "VisualScriptWhile") {
-
Ref<VisualScriptWhile> n;
n.instance();
vnode = n;
} else if (p_text == "VisualScriptReturn") {
-
Ref<VisualScriptReturn> n;
n.instance();
vnode = n;
@@ -3611,15 +3658,15 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
undo_redo->add_undo_method(this, "_update_graph", new_id);
undo_redo->commit_action();
- if (script_prop_set.is_valid())
+ if (script_prop_set.is_valid()) {
script_prop_set->set_property(p_text);
+ }
port_action_new_node = new_id;
Ref<VisualScriptNode> vsn = script->get_node(func, port_action_new_node);
if (Object::cast_to<VisualScriptFunctionCall>(vsn.ptr())) {
-
Ref<VisualScriptFunctionCall> vsfc = vsn;
vsfc->set_function(p_text);
@@ -3724,12 +3771,12 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri
}
}
_update_graph(port_action_new_node);
- if (port_node_exists)
+ if (port_node_exists) {
_update_graph_connections();
+ }
}
void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<VisualScriptNode> vnode_new, int new_id) {
-
VisualScriptOperator *vnode_operator = Object::cast_to<VisualScriptOperator>(vnode_new.ptr());
if (vnode_operator != nullptr && !vnode_operator->has_input_sequence_port()) {
return;
@@ -3777,7 +3824,6 @@ void VisualScriptEditor::connect_seq(Ref<VisualScriptNode> vnode_old, Ref<Visual
}
void VisualScriptEditor::_selected_new_virtual_method(const String &p_text, const String &p_category, const bool p_connecting) {
-
String name = p_text;
if (script->has_function(name)) {
EditorNode::get_singleton()->show_warning(vformat(TTR("Script already has function '%s'"), name));
@@ -3840,10 +3886,10 @@ void VisualScriptEditor::_cancel_connect_node() {
}
int VisualScriptEditor::_create_new_node_from_name(const String &p_text, const Vector2 &p_point, const StringName &p_func) {
-
StringName func = default_func;
- if (p_func != StringName())
+ if (p_func != StringName()) {
func = p_func;
+ }
Ref<VisualScriptNode> vnode = VisualScriptLanguage::singleton->create_node_from_name(p_text);
int new_id = script->get_available_id();
@@ -3857,10 +3903,10 @@ int VisualScriptEditor::_create_new_node_from_name(const String &p_text, const V
}
void VisualScriptEditor::_default_value_changed() {
-
Ref<VisualScriptNode> vsn = script->get_node(_get_function_of_node(editing_id), editing_id);
- if (vsn.is_null())
+ if (vsn.is_null()) {
return;
+ }
undo_redo->create_action(TTR("Change Input Value"));
undo_redo->add_do_method(vsn.ptr(), "set_default_input_value", editing_input, default_value_edit->get_variant());
@@ -3872,15 +3918,14 @@ void VisualScriptEditor::_default_value_changed() {
}
void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_input_port) {
-
Ref<VisualScriptNode> vsn = script->get_node(_get_function_of_node(p_id), p_id);
- if (vsn.is_null())
+ if (vsn.is_null()) {
return;
+ }
PropertyInfo pinfo = vsn->get_input_value_port_info(p_input_port);
Variant existing = vsn->get_default_input_value(p_input_port);
if (pinfo.type != Variant::NIL && existing.get_type() != pinfo.type) {
-
Callable::CallError ce;
const Variant *existingp = &existing;
existing = Variant::construct(pinfo.type, &existingp, 1, ce, false);
@@ -3890,7 +3935,6 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i
default_value_edit->set_size(Size2(1, 1));
if (pinfo.type == Variant::NODE_PATH) {
-
Node *edited_scene = get_tree()->get_edited_scene_root();
if (edited_scene) { // Fixing an old crash bug ( Visual Script Crashes on editing NodePath with an empty scene open)
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
@@ -3908,10 +3952,11 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i
}
if (default_value_edit->edit(nullptr, pinfo.name, pinfo.type, existing, pinfo.hint, pinfo.hint_string)) {
- if (pinfo.hint == PROPERTY_HINT_MULTILINE_TEXT)
+ if (pinfo.hint == PROPERTY_HINT_MULTILINE_TEXT) {
default_value_edit->popup_centered_ratio();
- else
+ } else {
default_value_edit->popup();
+ }
}
editing_id = p_id;
@@ -3919,19 +3964,16 @@ void VisualScriptEditor::_default_value_edited(Node *p_button, int p_id, int p_i
}
void VisualScriptEditor::_show_hint(const String &p_hint) {
-
hint_text->set_text(p_hint);
hint_text->show();
hint_text_timer->start();
}
void VisualScriptEditor::_hide_timer() {
-
hint_text->hide();
}
void VisualScriptEditor::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_READY: {
variable_editor->connect("changed", callable_mp(this, &VisualScriptEditor::_update_members));
@@ -3994,9 +4036,9 @@ void VisualScriptEditor::_notification(int p_what) {
}
void VisualScriptEditor::_graph_ofs_changed(const Vector2 &p_ofs) {
-
- if (updating_graph || !script.is_valid())
+ if (updating_graph || !script.is_valid()) {
return;
+ }
updating_graph = true;
@@ -4009,20 +4051,22 @@ void VisualScriptEditor::_graph_ofs_changed(const Vector2 &p_ofs) {
}
void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_node) {
-
- if (updating_graph)
+ if (updating_graph) {
return;
+ }
StringName func = _get_function_of_node(p_node);
Ref<VisualScriptComment> vsc = script->get_node(func, p_node);
- if (vsc.is_null())
+ if (vsc.is_null()) {
return;
+ }
Node *node = graph->get_node(itos(p_node));
GraphNode *gn = Object::cast_to<GraphNode>(node);
- if (!gn)
+ if (!gn) {
return;
+ }
updating_graph = true;
@@ -4040,13 +4084,11 @@ void VisualScriptEditor::_comment_node_resized(const Vector2 &p_new_size, int p_
}
void VisualScriptEditor::_menu_option(int p_what) {
-
switch (p_what) {
case EDIT_DELETE_NODES: {
_on_nodes_delete();
} break;
case EDIT_TOGGLE_BREAKPOINT: {
-
List<String> reselect;
for (int i = 0; i < graph->get_child_count(); i++) {
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
@@ -4076,8 +4118,9 @@ void VisualScriptEditor::_menu_option(int p_what) {
} break;
case EDIT_COPY_NODES:
case EDIT_CUT_NODES: {
- if (!script->has_function(default_func))
+ if (!script->has_function(default_func)) {
break;
+ }
clipboard->nodes.clear();
clipboard->data_connections.clear();
@@ -4088,7 +4131,6 @@ void VisualScriptEditor::_menu_option(int p_what) {
GraphNode *gn = Object::cast_to<GraphNode>(graph->get_child(i));
if (gn) {
if (gn->is_selected()) {
-
int id = String(gn->get_name()).to_int();
StringName func = _get_function_of_node(id);
Ref<VisualScriptNode> node = script->get_node(func, id);
@@ -4105,8 +4147,9 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
}
- if (clipboard->nodes.empty())
+ if (clipboard->nodes.empty()) {
break;
+ }
for (Set<String>::Element *F = funcs.front(); F; F = F->next()) {
List<VisualScript::SequenceConnection> sequence_connections;
@@ -4114,9 +4157,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
script->get_sequence_connection_list(F->get(), &sequence_connections);
for (List<VisualScript::SequenceConnection>::Element *E = sequence_connections.front(); E; E = E->next()) {
-
if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) {
-
clipboard->sequence_connections.insert(E->get());
}
}
@@ -4126,9 +4167,7 @@ void VisualScriptEditor::_menu_option(int p_what) {
script->get_data_connection_list(F->get(), &data_connections);
for (List<VisualScript::DataConnection>::Element *E = data_connections.front(); E; E = E->next()) {
-
if (clipboard->nodes.has(E->get().from_node) && clipboard->nodes.has(E->get().to_node)) {
-
clipboard->data_connections.insert(E->get());
}
}
@@ -4139,8 +4178,9 @@ void VisualScriptEditor::_menu_option(int p_what) {
} break;
case EDIT_PASTE_NODES: {
- if (!script->has_function(default_func))
+ if (!script->has_function(default_func)) {
break;
+ }
if (clipboard->nodes.empty()) {
EditorNode::get_singleton()->show_warning(TTR("Clipboard is empty!"));
@@ -4170,7 +4210,6 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
for (Map<int, Ref<VisualScriptNode>>::Element *E = clipboard->nodes.front(); E; E = E->next()) {
-
Ref<VisualScriptNode> node = E->get()->duplicate();
int new_id = idc++;
@@ -4189,13 +4228,11 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
for (Set<VisualScript::SequenceConnection>::Element *E = clipboard->sequence_connections.front(); E; E = E->next()) {
-
undo_redo->add_do_method(script.ptr(), "sequence_connect", default_func, remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]);
undo_redo->add_undo_method(script.ptr(), "sequence_disconnect", default_func, remap[E->get().from_node], E->get().from_output, remap[E->get().to_node]);
}
for (Set<VisualScript::DataConnection>::Element *E = clipboard->data_connections.front(); E; E = E->next()) {
-
undo_redo->add_do_method(script.ptr(), "data_connect", default_func, remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port);
undo_redo->add_undo_method(script.ptr(), "data_disconnect", default_func, remap[E->get().from_node], E->get().from_port, remap[E->get().to_node], E->get().to_port);
}
@@ -4214,7 +4251,6 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
} break;
case EDIT_CREATE_FUNCTION: {
-
StringName function = "";
Map<int, Ref<VisualScriptNode>> nodes;
Set<int> selections;
@@ -4256,9 +4292,9 @@ void VisualScriptEditor::_menu_option(int p_what) {
Set<int> end_nodes;
if (nodes.size() == 1) {
Ref<VisualScriptNode> nd = script->get_node(function, nodes.front()->key());
- if (nd.is_valid() && nd->has_input_sequence_port())
+ if (nd.is_valid() && nd->has_input_sequence_port()) {
start_node = nodes.front()->key();
- else {
+ } else {
EditorNode::get_singleton()->show_warning(TTR("Select at least one node with sequence port."));
return;
}
@@ -4287,9 +4323,9 @@ void VisualScriptEditor::_menu_option(int p_what) {
}
}
Ref<VisualScriptNode> nd = script->get_node(function, top_nd);
- if (nd.is_valid() && nd->has_input_sequence_port())
+ if (nd.is_valid() && nd->has_input_sequence_port()) {
start_node = top_nd;
- else {
+ } else {
EditorNode::get_singleton()->show_warning(TTR("Select at least one node with sequence port."));
return;
}
@@ -4486,7 +4522,6 @@ void VisualScriptEditor::_get_ends(int p_node, const List<VisualScript::Sequence
}
void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) {
-
TreeItem *ti = members->get_selected();
ERR_FAIL_COND(!ti);
@@ -4504,7 +4539,6 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) {
Ref<Texture2D> edit_icon = Control::get_theme_icon("Edit", "EditorIcons");
if (ti->get_parent() == root->get_children()) {
-
member_type = MEMBER_FUNCTION;
member_name = ti->get_text(0);
member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT);
@@ -4515,7 +4549,6 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) {
}
if (ti->get_parent() == root->get_children()->get_next()) {
-
member_type = MEMBER_VARIABLE;
member_name = ti->get_text(0);
member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT);
@@ -4526,7 +4559,6 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) {
}
if (ti->get_parent() == root->get_children()->get_next()->get_next()) {
-
member_type = MEMBER_SIGNAL;
member_name = ti->get_text(0);
member_popup->add_icon_shortcut(edit_icon, ED_GET_SHORTCUT("visual_script_editor/edit_member"), MEMBER_EDIT);
@@ -4538,10 +4570,8 @@ void VisualScriptEditor::_member_rmb_selected(const Vector2 &p_pos) {
}
void VisualScriptEditor::_member_option(int p_option) {
-
switch (member_type) {
case MEMBER_FUNCTION: {
-
if (p_option == MEMBER_REMOVE) {
//delete the function
String name = member_name;
@@ -4584,7 +4614,6 @@ void VisualScriptEditor::_member_option(int p_option) {
}
} break;
case MEMBER_VARIABLE: {
-
String name = member_name;
if (p_option == MEMBER_REMOVE) {
@@ -4632,7 +4661,6 @@ void VisualScriptEditor::set_syntax_highlighter(SyntaxHighlighter *p_highlighter
}
void VisualScriptEditor::_bind_methods() {
-
ClassDB::bind_method("_move_node", &VisualScriptEditor::_move_node);
ClassDB::bind_method("_update_graph", &VisualScriptEditor::_update_graph, DEFVAL(-1));
@@ -4655,7 +4683,6 @@ void VisualScriptEditor::_bind_methods() {
}
VisualScriptEditor::VisualScriptEditor() {
-
if (!clipboard) {
clipboard = memnew(Clipboard);
}
@@ -4887,14 +4914,12 @@ VisualScriptEditor::VisualScriptEditor() {
}
VisualScriptEditor::~VisualScriptEditor() {
-
undo_redo->clear_history(); // Avoid crashes.
memdelete(signal_editor);
memdelete(variable_editor);
}
static ScriptEditorBase *create_editor(const RES &p_resource) {
-
if (Object::cast_to<VisualScript>(*p_resource)) {
return memnew(VisualScriptEditor);
}
@@ -4905,12 +4930,12 @@ static ScriptEditorBase *create_editor(const RES &p_resource) {
VisualScriptEditor::Clipboard *VisualScriptEditor::clipboard = nullptr;
void VisualScriptEditor::free_clipboard() {
- if (clipboard)
+ if (clipboard) {
memdelete(clipboard);
+ }
}
static void register_editor_callback() {
-
ScriptEditor::register_create_script_editor_function(create_editor);
ED_SHORTCUT("visual_script_editor/delete_selected", TTR("Delete Selected"), KEY_DELETE);
@@ -4925,13 +4950,11 @@ static void register_editor_callback() {
}
void VisualScriptEditor::register_editor() {
-
// Too early to register stuff here, request a callback.
EditorNode::add_plugin_init_callback(register_editor_callback);
}
Ref<VisualScriptNode> _VisualScriptEditor::create_node_custom(const String &p_name) {
-
Ref<VisualScriptCustomNode> node;
node.instance();
node->set_script(singleton->custom_nodes[p_name]);
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index d9494e4d04..37063b2da1 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -152,7 +152,6 @@ class VisualScriptEditor : public ScriptEditorBase {
String _validate_name(const String &p_name) const;
struct Clipboard {
-
Map<int, Ref<VisualScriptNode>> nodes;
Map<int, Vector2> nodes_positions;
diff --git a/modules/visual_script/visual_script_expression.cpp b/modules/visual_script/visual_script_expression.cpp
index 71ed483d65..bd41117497 100644
--- a/modules/visual_script/visual_script_expression.cpp
+++ b/modules/visual_script/visual_script_expression.cpp
@@ -31,7 +31,6 @@
#include "visual_script_expression.h"
bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_value) {
-
if (String(p_name) == "expression") {
expression = p_value;
expression_dirty = true;
@@ -52,7 +51,6 @@ bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_val
}
if (String(p_name) == "input_count") {
-
int from = inputs.size();
inputs.resize(int(p_value));
for (int i = from; i < inputs.size(); i++) {
@@ -70,17 +68,14 @@ bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_val
}
if (String(p_name).begins_with("input_")) {
-
int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int();
ERR_FAIL_INDEX_V(idx, inputs.size(), false);
String what = String(p_name).get_slice("/", 1);
if (what == "type") {
-
inputs.write[idx].type = Variant::Type(int(p_value));
} else if (what == "name") {
-
inputs.write[idx].name = p_value;
} else {
return false;
@@ -95,7 +90,6 @@ bool VisualScriptExpression::_set(const StringName &p_name, const Variant &p_val
}
bool VisualScriptExpression::_get(const StringName &p_name, Variant &r_ret) const {
-
if (String(p_name) == "expression") {
r_ret = expression;
return true;
@@ -117,17 +111,14 @@ bool VisualScriptExpression::_get(const StringName &p_name, Variant &r_ret) cons
}
if (String(p_name).begins_with("input_")) {
-
int idx = String(p_name).get_slicec('_', 1).get_slicec('/', 0).to_int();
ERR_FAIL_INDEX_V(idx, inputs.size(), false);
String what = String(p_name).get_slice("/", 1);
if (what == "type") {
-
r_ret = inputs[idx].type;
} else if (what == "name") {
-
r_ret = inputs[idx].name;
} else {
return false;
@@ -138,8 +129,8 @@ bool VisualScriptExpression::_get(const StringName &p_name, Variant &r_ret) cons
return false;
}
-void VisualScriptExpression::_get_property_list(List<PropertyInfo> *p_list) const {
+void VisualScriptExpression::_get_property_list(List<PropertyInfo> *p_list) const {
String argt = "Any";
for (int i = 1; i < Variant::VARIANT_MAX; i++) {
argt += "," + Variant::get_type_name(Variant::Type(i));
@@ -151,55 +142,48 @@ void VisualScriptExpression::_get_property_list(List<PropertyInfo> *p_list) cons
p_list->push_back(PropertyInfo(Variant::BOOL, "sequenced"));
for (int i = 0; i < inputs.size(); i++) {
-
p_list->push_back(PropertyInfo(Variant::INT, "input_" + itos(i) + "/type", PROPERTY_HINT_ENUM, argt));
p_list->push_back(PropertyInfo(Variant::STRING, "input_" + itos(i) + "/name"));
}
}
int VisualScriptExpression::get_output_sequence_port_count() const {
-
return sequenced ? 1 : 0;
}
-bool VisualScriptExpression::has_input_sequence_port() const {
+bool VisualScriptExpression::has_input_sequence_port() const {
return sequenced;
}
String VisualScriptExpression::get_output_sequence_port_text(int p_port) const {
-
return String();
}
int VisualScriptExpression::get_input_value_port_count() const {
-
return inputs.size();
}
-int VisualScriptExpression::get_output_value_port_count() const {
+int VisualScriptExpression::get_output_value_port_count() const {
return 1;
}
PropertyInfo VisualScriptExpression::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo(inputs[p_idx].type, inputs[p_idx].name);
}
-PropertyInfo VisualScriptExpression::get_output_value_port_info(int p_idx) const {
+PropertyInfo VisualScriptExpression::get_output_value_port_info(int p_idx) const {
return PropertyInfo(output_type, "result");
}
String VisualScriptExpression::get_caption() const {
-
return "Expression";
}
-String VisualScriptExpression::get_text() const {
+String VisualScriptExpression::get_text() const {
return expression;
}
Error VisualScriptExpression::_get_token(Token &r_token) {
-
while (true) {
#define GET_CHAR() (str_ofs >= expression.length() ? 0 : expression[str_ofs++])
@@ -210,58 +194,47 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
}
switch (cchar) {
-
case 0: {
r_token.type = TK_EOF;
return OK;
} break;
case '{': {
-
r_token.type = TK_CURLY_BRACKET_OPEN;
return OK;
};
case '}': {
-
r_token.type = TK_CURLY_BRACKET_CLOSE;
return OK;
};
case '[': {
-
r_token.type = TK_BRACKET_OPEN;
return OK;
};
case ']': {
-
r_token.type = TK_BRACKET_CLOSE;
return OK;
};
case '(': {
-
r_token.type = TK_PARENTHESIS_OPEN;
return OK;
};
case ')': {
-
r_token.type = TK_PARENTHESIS_CLOSE;
return OK;
};
case ',': {
-
r_token.type = TK_COMMA;
return OK;
};
case ':': {
-
r_token.type = TK_COLON;
return OK;
};
case '.': {
-
r_token.type = TK_PERIOD;
return OK;
};
case '=': {
-
cchar = GET_CHAR();
if (cchar == '=') {
r_token.type = TK_OP_EQUAL;
@@ -273,7 +246,6 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
return OK;
};
case '!': {
-
if (expression[str_ofs] == '=') {
r_token.type = TK_OP_NOT_EQUAL;
str_ofs++;
@@ -283,7 +255,6 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
return OK;
};
case '>': {
-
if (expression[str_ofs] == '=') {
r_token.type = TK_OP_GREATER_EQUAL;
str_ofs++;
@@ -296,7 +267,6 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
return OK;
};
case '<': {
-
if (expression[str_ofs] == '=') {
r_token.type = TK_OP_LESS_EQUAL;
str_ofs++;
@@ -329,7 +299,6 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
return OK;
};
case '&': {
-
if (expression[str_ofs] == '&') {
r_token.type = TK_OP_AND;
str_ofs++;
@@ -339,7 +308,6 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
return OK;
};
case '|': {
-
if (expression[str_ofs] == '|') {
r_token.type = TK_OP_OR;
str_ofs++;
@@ -349,22 +317,18 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
return OK;
};
case '^': {
-
r_token.type = TK_OP_BIT_XOR;
return OK;
};
case '~': {
-
r_token.type = TK_OP_BIT_INVERT;
return OK;
};
case '"': {
-
String str;
while (true) {
-
CharType ch = GET_CHAR();
if (ch == 0) {
@@ -385,12 +349,21 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
CharType res = 0;
switch (next) {
-
- case 'b': res = 8; break;
- case 't': res = 9; break;
- case 'n': res = 10; break;
- case 'f': res = 12; break;
- case 'r': res = 13; break;
+ case 'b':
+ res = 8;
+ break;
+ case 't':
+ res = 9;
+ break;
+ case 'n':
+ res = 10;
+ break;
+ case 'f':
+ res = 12;
+ break;
+ case 'r':
+ res = 13;
+ break;
case 'u': {
// hex number
for (int j = 0; j < 4; j++) {
@@ -402,7 +375,6 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
return ERR_PARSE_ERROR;
}
if (!((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))) {
-
_set_error("Malformed hex constant in string");
r_token.type = TK_ERROR;
return ERR_PARSE_ERROR;
@@ -444,7 +416,6 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
} break;
default: {
-
if (cchar <= 32) {
break;
}
@@ -466,10 +437,8 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
bool is_float = false;
while (true) {
-
switch (reading) {
case READING_INT: {
-
if (c >= '0' && c <= '9') {
//pass
} else if (c == '.') {
@@ -483,9 +452,7 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
} break;
case READING_DEC: {
-
if (c >= '0' && c <= '9') {
-
} else if (c == 'e') {
reading = READING_EXP;
@@ -495,13 +462,13 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
} break;
case READING_EXP: {
-
if (c >= '0' && c <= '9') {
exp_beg = true;
} else if ((c == '-' || c == '+') && !exp_sign && !exp_beg) {
- if (c == '-')
+ if (c == '-') {
is_float = true;
+ }
exp_sign = true;
} else {
@@ -510,8 +477,9 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
} break;
}
- if (reading == READING_DONE)
+ if (reading == READING_DONE) {
break;
+ }
num += String::chr(c);
c = GET_CHAR();
}
@@ -520,19 +488,18 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
r_token.type = TK_CONSTANT;
- if (is_float)
+ if (is_float) {
r_token.value = num.to_double();
- else
+ } else {
r_token.value = num.to_int();
+ }
return OK;
} else if ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_') {
-
String id;
bool first = true;
while ((cchar >= 'A' && cchar <= 'Z') || (cchar >= 'a' && cchar <= 'z') || cchar == '_' || (!first && cchar >= '0' && cchar <= '9')) {
-
id += String::chr(cchar);
cchar = GET_CHAR();
first = false;
@@ -572,7 +539,6 @@ Error VisualScriptExpression::_get_token(Token &r_token) {
} else if (id == "self") {
r_token.type = TK_SELF;
} else {
-
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
if (id == Variant::get_type_name(Variant::Type(i))) {
r_token.type = TK_BASIC_TYPE;
@@ -647,7 +613,6 @@ const char *VisualScriptExpression::token_name[TK_MAX] = {
};
VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
-
Vector<Expression> expression;
while (true) {
@@ -656,8 +621,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
Token tk;
_get_token(tk);
- if (error_set)
+ if (error_set) {
return nullptr;
+ }
switch (tk.type) {
case TK_CURLY_BRACKET_OPEN: {
@@ -665,7 +631,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
DictionaryNode *dn = alloc_node<DictionaryNode>();
while (true) {
-
int cofs = str_ofs;
_get_token(tk);
if (tk.type == TK_CURLY_BRACKET_CLOSE) {
@@ -674,8 +639,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
str_ofs = cofs; //revert
//parse an expression
ENode *expr2 = _parse_expression();
- if (!expr2)
+ if (!expr2) {
return nullptr;
+ }
dn->dict.push_back(expr2);
_get_token(tk);
@@ -685,8 +651,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
}
expr2 = _parse_expression();
- if (!expr2)
+ if (!expr2) {
return nullptr;
+ }
dn->dict.push_back(expr2);
@@ -709,7 +676,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
ArrayNode *an = alloc_node<ArrayNode>();
while (true) {
-
int cofs = str_ofs;
_get_token(tk);
if (tk.type == TK_BRACKET_CLOSE) {
@@ -718,8 +684,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
str_ofs = cofs; //revert
//parse an expression
ENode *expr2 = _parse_expression();
- if (!expr2)
+ if (!expr2) {
return nullptr;
+ }
an->array.push_back(expr2);
cofs = str_ofs;
@@ -738,8 +705,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
case TK_PARENTHESIS_OPEN: {
//a suexpression
ENode *e = _parse_expression();
- if (error_set)
+ if (error_set) {
return nullptr;
+ }
_get_token(tk);
if (tk.type != TK_PARENTHESIS_CLOSE) {
_set_error("Expected ')'");
@@ -750,7 +718,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
} break;
case TK_IDENTIFIER: {
-
String what = tk.value;
int index = -1;
for (int i = 0; i < inputs.size(); i++) {
@@ -770,7 +737,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
}
} break;
case TK_SELF: {
-
SelfNode *self = alloc_node<SelfNode>();
expr = self;
} break;
@@ -793,7 +759,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
constructor->data_type = bt;
while (true) {
-
int cofs = str_ofs;
_get_token(tk);
if (tk.type == TK_PARENTHESIS_CLOSE) {
@@ -802,8 +767,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
str_ofs = cofs; //revert
//parse an expression
ENode *expr2 = _parse_expression();
- if (!expr2)
+ if (!expr2) {
return nullptr;
+ }
constructor->arguments.push_back(expr2);
@@ -834,7 +800,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
bifunc->func = VisualScriptBuiltinFunc::BuiltinFunc(int(tk.value));
while (true) {
-
int cofs = str_ofs;
_get_token(tk);
if (tk.type == TK_PARENTHESIS_CLOSE) {
@@ -843,8 +808,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
str_ofs = cofs; //revert
//parse an expression
ENode *expr2 = _parse_expression();
- if (!expr2)
+ if (!expr2) {
return nullptr;
+ }
bifunc->arguments.push_back(expr2);
@@ -868,7 +834,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
} break;
case TK_OP_SUB: {
-
Expression e;
e.is_op = true;
e.op = Variant::OP_NEGATE;
@@ -876,7 +841,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
continue;
} break;
case TK_OP_NOT: {
-
Expression e;
e.is_op = true;
e.op = Variant::OP_NOT;
@@ -895,8 +859,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
while (true) {
int cofs2 = str_ofs;
_get_token(tk);
- if (error_set)
+ if (error_set) {
return nullptr;
+ }
bool done = false;
@@ -908,8 +873,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
index->base = expr;
ENode *what = _parse_expression();
- if (!what)
+ if (!what) {
return nullptr;
+ }
index->index = what;
@@ -940,7 +906,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
func_call->base = expr;
while (true) {
-
int cofs3 = str_ofs;
_get_token(tk);
if (tk.type == TK_PARENTHESIS_CLOSE) {
@@ -949,8 +914,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
str_ofs = cofs3; //revert
//parse an expression
ENode *expr2 = _parse_expression();
- if (!expr2)
+ if (!expr2) {
return nullptr;
+ }
func_call->arguments.push_back(expr2);
@@ -983,8 +949,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
} break;
}
- if (done)
+ if (done) {
break;
+ }
}
//push expression
@@ -999,33 +966,76 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
int cofs = str_ofs;
_get_token(tk);
- if (error_set)
+ if (error_set) {
return nullptr;
+ }
Variant::Operator op = Variant::OP_MAX;
switch (tk.type) {
- case TK_OP_IN: op = Variant::OP_IN; break;
- case TK_OP_EQUAL: op = Variant::OP_EQUAL; break;
- case TK_OP_NOT_EQUAL: op = Variant::OP_NOT_EQUAL; break;
- case TK_OP_LESS: op = Variant::OP_LESS; break;
- case TK_OP_LESS_EQUAL: op = Variant::OP_LESS_EQUAL; break;
- case TK_OP_GREATER: op = Variant::OP_GREATER; break;
- case TK_OP_GREATER_EQUAL: op = Variant::OP_GREATER_EQUAL; break;
- case TK_OP_AND: op = Variant::OP_AND; break;
- case TK_OP_OR: op = Variant::OP_OR; break;
- case TK_OP_NOT: op = Variant::OP_NOT; break;
- case TK_OP_ADD: op = Variant::OP_ADD; break;
- case TK_OP_SUB: op = Variant::OP_SUBTRACT; break;
- case TK_OP_MUL: op = Variant::OP_MULTIPLY; break;
- case TK_OP_DIV: op = Variant::OP_DIVIDE; break;
- case TK_OP_MOD: op = Variant::OP_MODULE; break;
- case TK_OP_SHIFT_LEFT: op = Variant::OP_SHIFT_LEFT; break;
- case TK_OP_SHIFT_RIGHT: op = Variant::OP_SHIFT_RIGHT; break;
- case TK_OP_BIT_AND: op = Variant::OP_BIT_AND; break;
- case TK_OP_BIT_OR: op = Variant::OP_BIT_OR; break;
- case TK_OP_BIT_XOR: op = Variant::OP_BIT_XOR; break;
- case TK_OP_BIT_INVERT: op = Variant::OP_BIT_NEGATE; break;
+ case TK_OP_IN:
+ op = Variant::OP_IN;
+ break;
+ case TK_OP_EQUAL:
+ op = Variant::OP_EQUAL;
+ break;
+ case TK_OP_NOT_EQUAL:
+ op = Variant::OP_NOT_EQUAL;
+ break;
+ case TK_OP_LESS:
+ op = Variant::OP_LESS;
+ break;
+ case TK_OP_LESS_EQUAL:
+ op = Variant::OP_LESS_EQUAL;
+ break;
+ case TK_OP_GREATER:
+ op = Variant::OP_GREATER;
+ break;
+ case TK_OP_GREATER_EQUAL:
+ op = Variant::OP_GREATER_EQUAL;
+ break;
+ case TK_OP_AND:
+ op = Variant::OP_AND;
+ break;
+ case TK_OP_OR:
+ op = Variant::OP_OR;
+ break;
+ case TK_OP_NOT:
+ op = Variant::OP_NOT;
+ break;
+ case TK_OP_ADD:
+ op = Variant::OP_ADD;
+ break;
+ case TK_OP_SUB:
+ op = Variant::OP_SUBTRACT;
+ break;
+ case TK_OP_MUL:
+ op = Variant::OP_MULTIPLY;
+ break;
+ case TK_OP_DIV:
+ op = Variant::OP_DIVIDE;
+ break;
+ case TK_OP_MOD:
+ op = Variant::OP_MODULE;
+ break;
+ case TK_OP_SHIFT_LEFT:
+ op = Variant::OP_SHIFT_LEFT;
+ break;
+ case TK_OP_SHIFT_RIGHT:
+ op = Variant::OP_SHIFT_RIGHT;
+ break;
+ case TK_OP_BIT_AND:
+ op = Variant::OP_BIT_AND;
+ break;
+ case TK_OP_BIT_OR:
+ op = Variant::OP_BIT_OR;
+ break;
+ case TK_OP_BIT_XOR:
+ op = Variant::OP_BIT_XOR;
+ break;
+ case TK_OP_BIT_INVERT:
+ op = Variant::OP_BIT_NEGATE;
+ break;
default: {
};
}
@@ -1047,15 +1057,12 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
/* Reduce the set set of expressions and place them in an operator tree, respecting precedence */
while (expression.size() > 1) {
-
int next_op = -1;
int min_priority = 0xFFFFF;
bool is_unary = false;
for (int i = 0; i < expression.size(); i++) {
-
if (!expression[i].is_op) {
-
continue;
}
@@ -1064,7 +1071,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
bool unary = false;
switch (expression[i].op) {
-
case Variant::OP_BIT_NEGATE:
priority = 0;
unary = true;
@@ -1074,36 +1080,74 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
unary = true;
break;
- case Variant::OP_MULTIPLY: priority = 2; break;
- case Variant::OP_DIVIDE: priority = 2; break;
- case Variant::OP_MODULE: priority = 2; break;
+ case Variant::OP_MULTIPLY:
+ priority = 2;
+ break;
+ case Variant::OP_DIVIDE:
+ priority = 2;
+ break;
+ case Variant::OP_MODULE:
+ priority = 2;
+ break;
- case Variant::OP_ADD: priority = 3; break;
- case Variant::OP_SUBTRACT: priority = 3; break;
+ case Variant::OP_ADD:
+ priority = 3;
+ break;
+ case Variant::OP_SUBTRACT:
+ priority = 3;
+ break;
- case Variant::OP_SHIFT_LEFT: priority = 4; break;
- case Variant::OP_SHIFT_RIGHT: priority = 4; break;
+ case Variant::OP_SHIFT_LEFT:
+ priority = 4;
+ break;
+ case Variant::OP_SHIFT_RIGHT:
+ priority = 4;
+ break;
- case Variant::OP_BIT_AND: priority = 5; break;
- case Variant::OP_BIT_XOR: priority = 6; break;
- case Variant::OP_BIT_OR: priority = 7; break;
+ case Variant::OP_BIT_AND:
+ priority = 5;
+ break;
+ case Variant::OP_BIT_XOR:
+ priority = 6;
+ break;
+ case Variant::OP_BIT_OR:
+ priority = 7;
+ break;
- case Variant::OP_LESS: priority = 8; break;
- case Variant::OP_LESS_EQUAL: priority = 8; break;
- case Variant::OP_GREATER: priority = 8; break;
- case Variant::OP_GREATER_EQUAL: priority = 8; break;
+ case Variant::OP_LESS:
+ priority = 8;
+ break;
+ case Variant::OP_LESS_EQUAL:
+ priority = 8;
+ break;
+ case Variant::OP_GREATER:
+ priority = 8;
+ break;
+ case Variant::OP_GREATER_EQUAL:
+ priority = 8;
+ break;
- case Variant::OP_EQUAL: priority = 8; break;
- case Variant::OP_NOT_EQUAL: priority = 8; break;
+ case Variant::OP_EQUAL:
+ priority = 8;
+ break;
+ case Variant::OP_NOT_EQUAL:
+ priority = 8;
+ break;
- case Variant::OP_IN: priority = 10; break;
+ case Variant::OP_IN:
+ priority = 10;
+ break;
case Variant::OP_NOT:
priority = 11;
unary = true;
break;
- case Variant::OP_AND: priority = 12; break;
- case Variant::OP_OR: priority = 13; break;
+ case Variant::OP_AND:
+ priority = 12;
+ break;
+ case Variant::OP_OR:
+ priority = 13;
+ break;
default: {
_set_error("Parser bug, invalid operator in expression: " + itos(expression[i].op));
@@ -1122,17 +1166,14 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
}
if (next_op == -1) {
-
_set_error("Yet another parser bug....");
ERR_FAIL_V(nullptr);
}
// OK! create operator..
if (is_unary) {
-
int expr_pos = next_op;
while (expression[expr_pos].is_op) {
-
expr_pos++;
if (expr_pos == expression.size()) {
//can happen..
@@ -1143,7 +1184,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
//consecutively do unary operators
for (int i = expr_pos - 1; i >= next_op; i--) {
-
OperatorNode *op = alloc_node<OperatorNode>();
op->op = expression[i].op;
op->nodes[0] = expression[i + 1].node;
@@ -1154,7 +1194,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
}
} else {
-
if (next_op < 1 || next_op >= (expression.size() - 1)) {
_set_error("Parser bug...");
ERR_FAIL_V(nullptr);
@@ -1164,7 +1203,6 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
op->op = expression[next_op].op;
if (expression[next_op - 1].is_op) {
-
_set_error("Parser bug...");
ERR_FAIL_V(nullptr);
}
@@ -1193,9 +1231,9 @@ VisualScriptExpression::ENode *VisualScriptExpression::_parse_expression() {
}
bool VisualScriptExpression::_compile_expression() {
-
- if (!expression_dirty)
+ if (!expression_dirty) {
return error_set;
+ }
if (nodes) {
memdelete(nodes);
@@ -1230,38 +1268,35 @@ public:
//virtual int get_working_memory_size() const { return 0; }
//execute by parsing the tree directly
virtual bool _execute(const Variant **p_inputs, VisualScriptExpression::ENode *p_node, Variant &r_ret, String &r_error_str, Callable::CallError &ce) {
-
switch (p_node->type) {
case VisualScriptExpression::ENode::TYPE_INPUT: {
-
const VisualScriptExpression::InputNode *in = static_cast<const VisualScriptExpression::InputNode *>(p_node);
r_ret = *p_inputs[in->index];
} break;
case VisualScriptExpression::ENode::TYPE_CONSTANT: {
-
const VisualScriptExpression::ConstantNode *c = static_cast<const VisualScriptExpression::ConstantNode *>(p_node);
r_ret = c->value;
} break;
case VisualScriptExpression::ENode::TYPE_SELF: {
-
r_ret = instance->get_owner_ptr();
} break;
case VisualScriptExpression::ENode::TYPE_OPERATOR: {
-
const VisualScriptExpression::OperatorNode *op = static_cast<const VisualScriptExpression::OperatorNode *>(p_node);
Variant a;
bool ret = _execute(p_inputs, op->nodes[0], a, r_error_str, ce);
- if (ret)
+ if (ret) {
return true;
+ }
Variant b;
if (op->nodes[1]) {
ret = _execute(p_inputs, op->nodes[1], b, r_error_str, ce);
- if (ret)
+ if (ret) {
return true;
+ }
}
bool valid = true;
@@ -1273,19 +1308,20 @@ public:
} break;
case VisualScriptExpression::ENode::TYPE_INDEX: {
-
const VisualScriptExpression::IndexNode *index = static_cast<const VisualScriptExpression::IndexNode *>(p_node);
Variant base;
bool ret = _execute(p_inputs, index->base, base, r_error_str, ce);
- if (ret)
+ if (ret) {
return true;
+ }
Variant idx;
ret = _execute(p_inputs, index->index, idx, r_error_str, ce);
- if (ret)
+ if (ret) {
return true;
+ }
bool valid;
r_ret = base.get(idx, &valid);
@@ -1296,13 +1332,13 @@ public:
} break;
case VisualScriptExpression::ENode::TYPE_NAMED_INDEX: {
-
const VisualScriptExpression::NamedIndexNode *index = static_cast<const VisualScriptExpression::NamedIndexNode *>(p_node);
Variant base;
bool ret = _execute(p_inputs, index->base, base, r_error_str, ce);
- if (ret)
+ if (ret) {
return true;
+ }
bool valid;
r_ret = base.get_named(index->name, &valid);
@@ -1318,11 +1354,11 @@ public:
Array arr;
arr.resize(array->array.size());
for (int i = 0; i < array->array.size(); i++) {
-
Variant value;
bool ret = _execute(p_inputs, array->array[i], value, r_error_str, ce);
- if (ret)
+ if (ret) {
return true;
+ }
arr[i] = value;
}
@@ -1334,16 +1370,17 @@ public:
Dictionary d;
for (int i = 0; i < dictionary->dict.size(); i += 2) {
-
Variant key;
bool ret = _execute(p_inputs, dictionary->dict[i + 0], key, r_error_str, ce);
- if (ret)
+ if (ret) {
return true;
+ }
Variant value;
ret = _execute(p_inputs, dictionary->dict[i + 1], value, r_error_str, ce);
- if (ret)
+ if (ret) {
return true;
+ }
d[key] = value;
}
@@ -1351,7 +1388,6 @@ public:
r_ret = d;
} break;
case VisualScriptExpression::ENode::TYPE_CONSTRUCTOR: {
-
const VisualScriptExpression::ConstructorNode *constructor = static_cast<const VisualScriptExpression::ConstructorNode *>(p_node);
Vector<Variant> arr;
@@ -1360,11 +1396,11 @@ public:
argp.resize(constructor->arguments.size());
for (int i = 0; i < constructor->arguments.size(); i++) {
-
Variant value;
bool ret = _execute(p_inputs, constructor->arguments[i], value, r_error_str, ce);
- if (ret)
+ if (ret) {
return true;
+ }
arr.write[i] = value;
argp.write[i] = &arr[i];
}
@@ -1378,7 +1414,6 @@ public:
} break;
case VisualScriptExpression::ENode::TYPE_BUILTIN_FUNC: {
-
const VisualScriptExpression::BuiltinFuncNode *bifunc = static_cast<const VisualScriptExpression::BuiltinFuncNode *>(p_node);
Vector<Variant> arr;
@@ -1387,11 +1422,11 @@ public:
argp.resize(bifunc->arguments.size());
for (int i = 0; i < bifunc->arguments.size(); i++) {
-
Variant value;
bool ret = _execute(p_inputs, bifunc->arguments[i], value, r_error_str, ce);
- if (ret)
+ if (ret) {
return true;
+ }
arr.write[i] = value;
argp.write[i] = &arr[i];
}
@@ -1405,13 +1440,13 @@ public:
} break;
case VisualScriptExpression::ENode::TYPE_CALL: {
-
const VisualScriptExpression::CallNode *call = static_cast<const VisualScriptExpression::CallNode *>(p_node);
Variant base;
bool ret = _execute(p_inputs, call->base, base, r_error_str, ce);
- if (ret)
+ if (ret) {
return true;
+ }
Vector<Variant> arr;
Vector<const Variant *> argp;
@@ -1419,11 +1454,11 @@ public:
argp.resize(call->arguments.size());
for (int i = 0; i < call->arguments.size(); i++) {
-
Variant value;
bool ret2 = _execute(p_inputs, call->arguments[i], value, r_error_str, ce);
- if (ret2)
+ if (ret2) {
return true;
+ }
arr.write[i] = value;
argp.write[i] = &arr[i];
}
@@ -1441,7 +1476,6 @@ public:
}
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (!expression->root || expression->error_set) {
r_error_str = expression->error_str;
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -1455,7 +1489,6 @@ public:
#ifdef DEBUG_ENABLED
if (!error && expression->output_type != Variant::NIL && !Variant::can_convert_strict(p_outputs[0]->get_type(), expression->output_type)) {
-
r_error_str += "Can't convert expression result from " + Variant::get_type_name(p_outputs[0]->get_type()) + " to " + Variant::get_type_name(expression->output_type) + ".";
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
}
@@ -1466,7 +1499,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptExpression::instance(VisualScriptInstance *p_instance) {
-
_compile_expression();
VisualScriptNodeInstanceExpression *instance = memnew(VisualScriptNodeInstanceExpression);
instance->instance = p_instance;
@@ -1484,13 +1516,11 @@ VisualScriptExpression::VisualScriptExpression() {
}
VisualScriptExpression::~VisualScriptExpression() {
-
if (nodes) {
memdelete(nodes);
}
}
void register_visual_script_expression_node() {
-
VisualScriptLanguage::singleton->add_register_func("operators/expression", create_node_generic<VisualScriptExpression>);
}
diff --git a/modules/visual_script/visual_script_expression.h b/modules/visual_script/visual_script_expression.h
index 61b50ff99d..dee0213d54 100644
--- a/modules/visual_script/visual_script_expression.h
+++ b/modules/visual_script/visual_script_expression.h
@@ -35,12 +35,10 @@
#include "visual_script_builtin_funcs.h"
class VisualScriptExpression : public VisualScriptNode {
-
GDCLASS(VisualScriptExpression, VisualScriptNode);
friend class VisualScriptNodeInstanceExpression;
struct Input {
-
Variant::Type type;
String name;
@@ -101,14 +99,14 @@ class VisualScriptExpression : public VisualScriptNode {
static const char *token_name[TK_MAX];
struct Token {
-
TokenType type;
Variant value;
};
void _set_error(const String &p_err) {
- if (error_set)
+ if (error_set) {
return;
+ }
error_str = p_err;
error_set = true;
}
@@ -119,7 +117,6 @@ class VisualScriptExpression : public VisualScriptNode {
bool error_set;
struct ENode {
-
enum Type {
TYPE_INPUT,
TYPE_CONSTANT,
@@ -147,7 +144,6 @@ class VisualScriptExpression : public VisualScriptNode {
};
struct Expression {
-
bool is_op;
union {
Variant::Operator op;
@@ -158,7 +154,6 @@ class VisualScriptExpression : public VisualScriptNode {
ENode *_parse_expression();
struct InputNode : public ENode {
-
int index;
InputNode() {
type = TYPE_INPUT;
@@ -166,7 +161,6 @@ class VisualScriptExpression : public VisualScriptNode {
};
struct ConstantNode : public ENode {
-
Variant value;
ConstantNode() {
type = TYPE_CONSTANT;
@@ -174,7 +168,6 @@ class VisualScriptExpression : public VisualScriptNode {
};
struct OperatorNode : public ENode {
-
Variant::Operator op;
ENode *nodes[2];
@@ -185,7 +178,6 @@ class VisualScriptExpression : public VisualScriptNode {
};
struct SelfNode : public ENode {
-
SelfNode() {
type = TYPE_SELF;
}
diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp
index 475893e86d..3ed20fab35 100644
--- a/modules/visual_script/visual_script_flow_control.cpp
+++ b/modules/visual_script/visual_script_flow_control.cpp
@@ -39,78 +39,70 @@
//////////////////////////////////////////
int VisualScriptReturn::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptReturn::has_input_sequence_port() const {
-
return true;
}
int VisualScriptReturn::get_input_value_port_count() const {
-
return with_value ? 1 : 0;
}
-int VisualScriptReturn::get_output_value_port_count() const {
+int VisualScriptReturn::get_output_value_port_count() const {
return 0;
}
String VisualScriptReturn::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptReturn::get_input_value_port_info(int p_idx) const {
-
PropertyInfo pinfo;
pinfo.name = "result";
pinfo.type = type;
return pinfo;
}
+
PropertyInfo VisualScriptReturn::get_output_value_port_info(int p_idx) const {
return PropertyInfo();
}
String VisualScriptReturn::get_caption() const {
-
return "Return";
}
String VisualScriptReturn::get_text() const {
-
return get_name();
}
void VisualScriptReturn::set_return_type(Variant::Type p_type) {
-
- if (type == p_type)
+ if (type == p_type) {
return;
+ }
type = p_type;
ports_changed_notify();
}
Variant::Type VisualScriptReturn::get_return_type() const {
-
return type;
}
void VisualScriptReturn::set_enable_return_value(bool p_enable) {
- if (with_value == p_enable)
+ if (with_value == p_enable) {
return;
+ }
with_value = p_enable;
ports_changed_notify();
}
bool VisualScriptReturn::is_return_value_enabled() const {
-
return with_value;
}
void VisualScriptReturn::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_return_type", "type"), &VisualScriptReturn::set_return_type);
ClassDB::bind_method(D_METHOD("get_return_type"), &VisualScriptReturn::get_return_type);
ClassDB::bind_method(D_METHOD("set_enable_return_value", "enable"), &VisualScriptReturn::set_enable_return_value);
@@ -136,7 +128,6 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (with_value) {
*p_working_mem = *p_inputs[0];
return STEP_EXIT_FUNCTION_BIT;
@@ -148,7 +139,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptReturn::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceReturn *instance = memnew(VisualScriptNodeInstanceReturn);
instance->node = this;
instance->instance = p_instance;
@@ -157,14 +147,12 @@ VisualScriptNodeInstance *VisualScriptReturn::instance(VisualScriptInstance *p_i
}
VisualScriptReturn::VisualScriptReturn() {
-
with_value = false;
type = Variant::NIL;
}
template <bool with_value>
static Ref<VisualScriptNode> create_return_node(const String &p_name) {
-
Ref<VisualScriptReturn> node;
node.instance();
node->set_enable_return_value(with_value);
@@ -176,52 +164,47 @@ static Ref<VisualScriptNode> create_return_node(const String &p_name) {
//////////////////////////////////////////
int VisualScriptCondition::get_output_sequence_port_count() const {
-
return 3;
}
bool VisualScriptCondition::has_input_sequence_port() const {
-
return true;
}
int VisualScriptCondition::get_input_value_port_count() const {
-
return 1;
}
-int VisualScriptCondition::get_output_value_port_count() const {
+int VisualScriptCondition::get_output_value_port_count() const {
return 0;
}
String VisualScriptCondition::get_output_sequence_port_text(int p_port) const {
-
- if (p_port == 0)
+ if (p_port == 0) {
return "true";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "false";
- else
+ } else {
return "done";
+ }
}
PropertyInfo VisualScriptCondition::get_input_value_port_info(int p_idx) const {
-
PropertyInfo pinfo;
pinfo.name = "cond";
pinfo.type = Variant::BOOL;
return pinfo;
}
+
PropertyInfo VisualScriptCondition::get_output_value_port_info(int p_idx) const {
return PropertyInfo();
}
String VisualScriptCondition::get_caption() const {
-
return "Condition";
}
String VisualScriptCondition::get_text() const {
-
return "if (cond) is: ";
}
@@ -238,18 +221,17 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
- if (p_start_mode == START_MODE_CONTINUE_SEQUENCE)
+ if (p_start_mode == START_MODE_CONTINUE_SEQUENCE) {
return 2;
- else if (p_inputs[0]->operator bool())
+ } else if (p_inputs[0]->operator bool()) {
return 0 | STEP_FLAG_PUSH_STACK_BIT;
- else
+ } else {
return 1 | STEP_FLAG_PUSH_STACK_BIT;
+ }
}
};
VisualScriptNodeInstance *VisualScriptCondition::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceCondition *instance = memnew(VisualScriptNodeInstanceCondition);
instance->node = this;
instance->instance = p_instance;
@@ -264,50 +246,45 @@ VisualScriptCondition::VisualScriptCondition() {
//////////////////////////////////////////
int VisualScriptWhile::get_output_sequence_port_count() const {
-
return 2;
}
bool VisualScriptWhile::has_input_sequence_port() const {
-
return true;
}
int VisualScriptWhile::get_input_value_port_count() const {
-
return 1;
}
-int VisualScriptWhile::get_output_value_port_count() const {
+int VisualScriptWhile::get_output_value_port_count() const {
return 0;
}
String VisualScriptWhile::get_output_sequence_port_text(int p_port) const {
-
- if (p_port == 0)
+ if (p_port == 0) {
return "repeat";
- else
+ } else {
return "exit";
+ }
}
PropertyInfo VisualScriptWhile::get_input_value_port_info(int p_idx) const {
-
PropertyInfo pinfo;
pinfo.name = "cond";
pinfo.type = Variant::BOOL;
return pinfo;
}
+
PropertyInfo VisualScriptWhile::get_output_value_port_info(int p_idx) const {
return PropertyInfo();
}
String VisualScriptWhile::get_caption() const {
-
return "While";
}
String VisualScriptWhile::get_text() const {
-
return "while (cond): ";
}
@@ -324,23 +301,23 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
bool keep_going = p_inputs[0]->operator bool();
- if (keep_going)
+ if (keep_going) {
return 0 | STEP_FLAG_PUSH_STACK_BIT;
- else
+ } else {
return 1;
+ }
}
};
VisualScriptNodeInstance *VisualScriptWhile::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceWhile *instance = memnew(VisualScriptNodeInstanceWhile);
instance->node = this;
instance->instance = p_instance;
return instance;
}
+
VisualScriptWhile::VisualScriptWhile() {
}
@@ -349,52 +326,48 @@ VisualScriptWhile::VisualScriptWhile() {
//////////////////////////////////////////
int VisualScriptIterator::get_output_sequence_port_count() const {
-
return 2;
}
bool VisualScriptIterator::has_input_sequence_port() const {
-
return true;
}
int VisualScriptIterator::get_input_value_port_count() const {
-
return 1;
}
-int VisualScriptIterator::get_output_value_port_count() const {
+int VisualScriptIterator::get_output_value_port_count() const {
return 1;
}
String VisualScriptIterator::get_output_sequence_port_text(int p_port) const {
-
- if (p_port == 0)
+ if (p_port == 0) {
return "each";
- else
+ } else {
return "exit";
+ }
}
PropertyInfo VisualScriptIterator::get_input_value_port_info(int p_idx) const {
-
PropertyInfo pinfo;
pinfo.name = "input";
pinfo.type = Variant::NIL;
return pinfo;
}
+
PropertyInfo VisualScriptIterator::get_output_value_port_info(int p_idx) const {
PropertyInfo pinfo;
pinfo.name = "elem";
pinfo.type = Variant::NIL;
return pinfo;
}
-String VisualScriptIterator::get_caption() const {
+String VisualScriptIterator::get_caption() const {
return "Iterator";
}
String VisualScriptIterator::get_text() const {
-
return "for (elem) in (input): ";
}
@@ -411,7 +384,6 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (p_start_mode == START_MODE_BEGIN_SEQUENCE) {
p_working_mem[0] = *p_inputs[0];
bool valid;
@@ -423,8 +395,9 @@ public:
return 0;
}
- if (!can_iter)
+ if (!can_iter) {
return 1; //nothing to iterate
+ }
*p_outputs[0] = p_working_mem[0].iter_get(p_working_mem[1], valid);
@@ -445,8 +418,9 @@ public:
return 0;
}
- if (!can_iter)
+ if (!can_iter) {
return 1; //nothing to iterate
+ }
*p_outputs[0] = p_working_mem[0].iter_get(p_working_mem[1], valid);
@@ -462,7 +436,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptIterator::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceIterator *instance = memnew(VisualScriptNodeInstanceIterator);
instance->node = this;
instance->instance = p_instance;
@@ -477,62 +450,56 @@ VisualScriptIterator::VisualScriptIterator() {
//////////////////////////////////////////
int VisualScriptSequence::get_output_sequence_port_count() const {
-
return steps;
}
bool VisualScriptSequence::has_input_sequence_port() const {
-
return true;
}
int VisualScriptSequence::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptSequence::get_output_value_port_count() const {
+int VisualScriptSequence::get_output_value_port_count() const {
return 1;
}
String VisualScriptSequence::get_output_sequence_port_text(int p_port) const {
-
return itos(p_port + 1);
}
PropertyInfo VisualScriptSequence::get_input_value_port_info(int p_idx) const {
return PropertyInfo();
}
+
PropertyInfo VisualScriptSequence::get_output_value_port_info(int p_idx) const {
return PropertyInfo(Variant::INT, "current");
}
-String VisualScriptSequence::get_caption() const {
+String VisualScriptSequence::get_caption() const {
return "Sequence";
}
String VisualScriptSequence::get_text() const {
-
return "in order: ";
}
void VisualScriptSequence::set_steps(int p_steps) {
-
ERR_FAIL_COND(p_steps < 1);
- if (steps == p_steps)
+ if (steps == p_steps) {
return;
+ }
steps = p_steps;
ports_changed_notify();
}
int VisualScriptSequence::get_steps() const {
-
return steps;
}
void VisualScriptSequence::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_steps", "steps"), &VisualScriptSequence::set_steps);
ClassDB::bind_method(D_METHOD("get_steps"), &VisualScriptSequence::get_steps);
@@ -550,9 +517,7 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (p_start_mode == START_MODE_BEGIN_SEQUENCE) {
-
p_working_mem[0] = 0;
}
@@ -560,9 +525,9 @@ public:
*p_outputs[0] = step;
- if (step + 1 == steps)
+ if (step + 1 == steps) {
return step;
- else {
+ } else {
p_working_mem[0] = step + 1;
return step | STEP_FLAG_PUSH_STACK_BIT;
}
@@ -570,15 +535,14 @@ public:
};
VisualScriptNodeInstance *VisualScriptSequence::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceSequence *instance = memnew(VisualScriptNodeInstanceSequence);
instance->node = this;
instance->instance = p_instance;
instance->steps = steps;
return instance;
}
-VisualScriptSequence::VisualScriptSequence() {
+VisualScriptSequence::VisualScriptSequence() {
steps = 1;
}
@@ -587,52 +551,46 @@ VisualScriptSequence::VisualScriptSequence() {
//////////////////////////////////////////
int VisualScriptSwitch::get_output_sequence_port_count() const {
-
return case_values.size() + 1;
}
bool VisualScriptSwitch::has_input_sequence_port() const {
-
return true;
}
int VisualScriptSwitch::get_input_value_port_count() const {
-
return case_values.size() + 1;
}
-int VisualScriptSwitch::get_output_value_port_count() const {
+int VisualScriptSwitch::get_output_value_port_count() const {
return 0;
}
String VisualScriptSwitch::get_output_sequence_port_text(int p_port) const {
-
- if (p_port == case_values.size())
+ if (p_port == case_values.size()) {
return "done";
+ }
return String();
}
PropertyInfo VisualScriptSwitch::get_input_value_port_info(int p_idx) const {
-
if (p_idx < case_values.size()) {
return PropertyInfo(case_values[p_idx].type, " =");
- } else
+ } else {
return PropertyInfo(Variant::NIL, "input");
+ }
}
PropertyInfo VisualScriptSwitch::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
String VisualScriptSwitch::get_caption() const {
-
return "Switch";
}
String VisualScriptSwitch::get_text() const {
-
return "'input' is:";
}
@@ -646,13 +604,11 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (p_start_mode == START_MODE_CONTINUE_SEQUENCE) {
return case_count; //exit
}
for (int i = 0; i < case_count; i++) {
-
if (*p_inputs[i] == *p_inputs[case_count]) {
return i | STEP_FLAG_PUSH_STACK_BIT;
}
@@ -663,7 +619,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptSwitch::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceSwitch *instance = memnew(VisualScriptNodeInstanceSwitch);
instance->instance = p_instance;
instance->case_count = case_values.size();
@@ -671,7 +626,6 @@ VisualScriptNodeInstance *VisualScriptSwitch::instance(VisualScriptInstance *p_i
}
bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value) {
-
if (String(p_name) == "case_count") {
case_values.resize(p_value);
_change_notify();
@@ -680,7 +634,6 @@ bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value)
}
if (String(p_name).begins_with("case/")) {
-
int idx = String(p_name).get_slice("/", 1).to_int();
ERR_FAIL_INDEX_V(idx, case_values.size(), false);
@@ -695,14 +648,12 @@ bool VisualScriptSwitch::_set(const StringName &p_name, const Variant &p_value)
}
bool VisualScriptSwitch::_get(const StringName &p_name, Variant &r_ret) const {
-
if (String(p_name) == "case_count") {
r_ret = case_values.size();
return true;
}
if (String(p_name).begins_with("case/")) {
-
int idx = String(p_name).get_slice("/", 1).to_int();
ERR_FAIL_INDEX_V(idx, case_values.size(), false);
@@ -712,8 +663,8 @@ bool VisualScriptSwitch::_get(const StringName &p_name, Variant &r_ret) const {
return false;
}
-void VisualScriptSwitch::_get_property_list(List<PropertyInfo> *p_list) const {
+void VisualScriptSwitch::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::INT, "case_count", PROPERTY_HINT_RANGE, "0,128"));
String argt = "Any";
@@ -737,56 +688,49 @@ VisualScriptSwitch::VisualScriptSwitch() {
//////////////////////////////////////////
int VisualScriptTypeCast::get_output_sequence_port_count() const {
-
return 2;
}
bool VisualScriptTypeCast::has_input_sequence_port() const {
-
return true;
}
int VisualScriptTypeCast::get_input_value_port_count() const {
-
return 1;
}
-int VisualScriptTypeCast::get_output_value_port_count() const {
+int VisualScriptTypeCast::get_output_value_port_count() const {
return 1;
}
String VisualScriptTypeCast::get_output_sequence_port_text(int p_port) const {
-
return p_port == 0 ? "yes" : "no";
}
PropertyInfo VisualScriptTypeCast::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo(Variant::OBJECT, "instance");
}
PropertyInfo VisualScriptTypeCast::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo(Variant::OBJECT, "", PROPERTY_HINT_TYPE_STRING, get_base_type());
}
String VisualScriptTypeCast::get_caption() const {
-
return "Type Cast";
}
String VisualScriptTypeCast::get_text() const {
-
- if (script != String())
+ if (script != String()) {
return "Is " + script.get_file() + "?";
- else
+ } else {
return "Is " + base_type + "?";
+ }
}
void VisualScriptTypeCast::set_base_type(const StringName &p_type) {
-
- if (base_type == p_type)
+ if (base_type == p_type) {
return;
+ }
base_type = p_type;
_change_notify();
@@ -794,26 +738,24 @@ void VisualScriptTypeCast::set_base_type(const StringName &p_type) {
}
StringName VisualScriptTypeCast::get_base_type() const {
-
return base_type;
}
void VisualScriptTypeCast::set_base_script(const String &p_path) {
-
- if (script == p_path)
+ if (script == p_path) {
return;
+ }
script = p_path;
_change_notify();
ports_changed_notify();
}
-String VisualScriptTypeCast::get_base_script() const {
+String VisualScriptTypeCast::get_base_script() const {
return script;
}
VisualScriptTypeCast::TypeGuess VisualScriptTypeCast::guess_output_type(TypeGuess *p_inputs, int p_output) const {
-
TypeGuess tg;
tg.type = Variant::OBJECT;
if (script != String()) {
@@ -837,7 +779,6 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
Object *obj = *p_inputs[0];
*p_outputs[0] = Variant();
@@ -849,7 +790,6 @@ public:
}
if (script != String()) {
-
Ref<Script> obj_script = obj->get_script();
if (!obj_script.is_valid()) {
return 1; //well, definitely not the script because object we got has no script.
@@ -867,7 +807,6 @@ public:
}
while (obj_script.is_valid()) {
-
if (cast_script == obj_script) {
*p_outputs[0] = *p_inputs[0]; //copy
return 0; // it is the script, yey
@@ -882,13 +821,13 @@ public:
if (ClassDB::is_parent_class(obj->get_class_name(), base_type)) {
*p_outputs[0] = *p_inputs[0]; //copy
return 0;
- } else
+ } else {
return 1;
+ }
}
};
VisualScriptNodeInstance *VisualScriptTypeCast::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceTypeCast *instance = memnew(VisualScriptNodeInstanceTypeCast);
instance->instance = p_instance;
instance->base_type = base_type;
@@ -897,7 +836,6 @@ VisualScriptNodeInstance *VisualScriptTypeCast::instance(VisualScriptInstance *p
}
void VisualScriptTypeCast::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_base_type", "type"), &VisualScriptTypeCast::set_base_type);
ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptTypeCast::get_base_type);
@@ -911,8 +849,9 @@ void VisualScriptTypeCast::_bind_methods() {
String script_ext_hint;
for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) {
- if (script_ext_hint != String())
+ if (script_ext_hint != String()) {
script_ext_hint += ",";
+ }
script_ext_hint += "*." + E->get();
}
@@ -921,12 +860,10 @@ void VisualScriptTypeCast::_bind_methods() {
}
VisualScriptTypeCast::VisualScriptTypeCast() {
-
base_type = "Object";
}
void register_visual_script_flow_control_nodes() {
-
VisualScriptLanguage::singleton->add_register_func("flow_control/return", create_return_node<false>);
VisualScriptLanguage::singleton->add_register_func("flow_control/return_with_value", create_return_node<true>);
VisualScriptLanguage::singleton->add_register_func("flow_control/condition", create_node_generic<VisualScriptCondition>);
@@ -934,6 +871,6 @@ void register_visual_script_flow_control_nodes() {
VisualScriptLanguage::singleton->add_register_func("flow_control/iterator", create_node_generic<VisualScriptIterator>);
VisualScriptLanguage::singleton->add_register_func("flow_control/sequence", create_node_generic<VisualScriptSequence>);
VisualScriptLanguage::singleton->add_register_func("flow_control/switch", create_node_generic<VisualScriptSwitch>);
- //VisualScriptLanguage::singleton->add_register_func("flow_control/input_filter", create_node_generic<VisualScriptInputFilter>);
+ //VisualScriptLanguage::singleton->add_register_func("flow_control/input", create_node_generic<VisualScriptInputFilter>);
VisualScriptLanguage::singleton->add_register_func("flow_control/type_cast", create_node_generic<VisualScriptTypeCast>);
}
diff --git a/modules/visual_script/visual_script_flow_control.h b/modules/visual_script/visual_script_flow_control.h
index 8597d051db..45b56b3073 100644
--- a/modules/visual_script/visual_script_flow_control.h
+++ b/modules/visual_script/visual_script_flow_control.h
@@ -34,7 +34,6 @@
#include "visual_script.h"
class VisualScriptReturn : public VisualScriptNode {
-
GDCLASS(VisualScriptReturn, VisualScriptNode);
Variant::Type type;
@@ -71,7 +70,6 @@ public:
};
class VisualScriptCondition : public VisualScriptNode {
-
GDCLASS(VisualScriptCondition, VisualScriptNode);
protected:
@@ -99,7 +97,6 @@ public:
};
class VisualScriptWhile : public VisualScriptNode {
-
GDCLASS(VisualScriptWhile, VisualScriptNode);
protected:
@@ -127,7 +124,6 @@ public:
};
class VisualScriptIterator : public VisualScriptNode {
-
GDCLASS(VisualScriptIterator, VisualScriptNode);
protected:
@@ -155,7 +151,6 @@ public:
};
class VisualScriptSequence : public VisualScriptNode {
-
GDCLASS(VisualScriptSequence, VisualScriptNode);
int steps;
@@ -188,7 +183,6 @@ public:
};
class VisualScriptSwitch : public VisualScriptNode {
-
GDCLASS(VisualScriptSwitch, VisualScriptNode);
struct Case {
@@ -230,7 +224,6 @@ public:
};
class VisualScriptTypeCast : public VisualScriptNode {
-
GDCLASS(VisualScriptTypeCast, VisualScriptNode);
StringName base_type;
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index 3b6ae369ae..f13377f3c8 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -42,33 +42,34 @@
//////////////////////////////////////////
int VisualScriptFunctionCall::get_output_sequence_port_count() const {
-
- if ((method_cache.flags & METHOD_FLAG_CONST && call_mode != CALL_MODE_INSTANCE) || (call_mode == CALL_MODE_BASIC_TYPE && Variant::is_method_const(basic_type, function)))
+ if ((method_cache.flags & METHOD_FLAG_CONST && call_mode != CALL_MODE_INSTANCE) || (call_mode == CALL_MODE_BASIC_TYPE && Variant::is_method_const(basic_type, function))) {
return 0;
- else
+ } else {
return 1;
+ }
}
bool VisualScriptFunctionCall::has_input_sequence_port() const {
-
return !((method_cache.flags & METHOD_FLAG_CONST && call_mode != CALL_MODE_INSTANCE) || (call_mode == CALL_MODE_BASIC_TYPE && Variant::is_method_const(basic_type, function)));
}
#ifdef TOOLS_ENABLED
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
-
- if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
+ if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) {
return nullptr;
+ }
Ref<Script> scr = p_current_node->get_script();
- if (scr.is_valid() && scr == script)
+ if (scr.is_valid() && scr == script) {
return p_current_node;
+ }
for (int i = 0; i < p_current_node->get_child_count(); i++) {
Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);
- if (n)
+ if (n) {
return n;
+ }
}
return nullptr;
@@ -76,30 +77,34 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const
#endif
Node *VisualScriptFunctionCall::_get_base_node() const {
-
#ifdef TOOLS_ENABLED
Ref<Script> script = get_visual_script();
- if (!script.is_valid())
+ if (!script.is_valid()) {
return nullptr;
+ }
MainLoop *main_loop = OS::get_singleton()->get_main_loop();
SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
- if (!scene_tree)
+ if (!scene_tree) {
return nullptr;
+ }
Node *edited_scene = scene_tree->get_edited_scene_root();
- if (!edited_scene)
+ if (!edited_scene) {
return nullptr;
+ }
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
- if (!script_node)
+ if (!script_node) {
return nullptr;
+ }
- if (!script_node->has_node(base_path))
+ if (!script_node->has_node(base_path)) {
return nullptr;
+ }
Node *path_to = script_node->get_node(base_path);
@@ -111,26 +116,24 @@ Node *VisualScriptFunctionCall::_get_base_node() const {
}
StringName VisualScriptFunctionCall::_get_base_type() const {
-
- if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid())
+ if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) {
return get_visual_script()->get_instance_base_type();
- else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
+ } else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
Node *path = _get_base_node();
- if (path)
+ if (path) {
return path->get_class();
+ }
}
return base_type;
}
int VisualScriptFunctionCall::get_input_value_port_count() const {
-
if (call_mode == CALL_MODE_BASIC_TYPE) {
Vector<Variant::Type> types = Variant::get_method_argument_types(basic_type, function);
return types.size() + (rpc_call_mode >= RPC_RELIABLE_TO_ID ? 1 : 0) + 1;
} else {
-
MethodBind *mb = ClassDB::get_method(_get_base_type(), function);
if (mb) {
int defaulted_args = mb->get_argument_count() < use_default_args ? mb->get_argument_count() : use_default_args;
@@ -141,10 +144,9 @@ int VisualScriptFunctionCall::get_input_value_port_count() const {
return method_cache.arguments.size() + (call_mode == CALL_MODE_INSTANCE ? 1 : 0) + (rpc_call_mode >= RPC_RELIABLE_TO_ID ? 1 : 0) - defaulted_args;
}
}
-int VisualScriptFunctionCall::get_output_value_port_count() const {
+int VisualScriptFunctionCall::get_output_value_port_count() const {
if (call_mode == CALL_MODE_BASIC_TYPE) {
-
bool returns = false;
Variant::get_method_return_type(basic_type, function, &returns);
return returns ? 1 : 0;
@@ -154,8 +156,9 @@ int VisualScriptFunctionCall::get_output_value_port_count() const {
MethodBind *mb = ClassDB::get_method(_get_base_type(), function);
if (mb) {
ret = mb->has_return() ? 1 : 0;
- } else
+ } else {
ret = 1; //it is assumed that script always returns something
+ }
if (call_mode == CALL_MODE_INSTANCE) {
ret++;
@@ -166,12 +169,10 @@ int VisualScriptFunctionCall::get_output_value_port_count() const {
}
String VisualScriptFunctionCall::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptFunctionCall::get_input_value_port_info(int p_idx) const {
-
if (call_mode == CALL_MODE_INSTANCE || call_mode == CALL_MODE_BASIC_TYPE) {
if (p_idx == 0) {
PropertyInfo pi;
@@ -184,7 +185,6 @@ PropertyInfo VisualScriptFunctionCall::get_input_value_port_info(int p_idx) cons
}
if (rpc_call_mode >= RPC_RELIABLE_TO_ID) {
-
if (p_idx == 0) {
return PropertyInfo(Variant::INT, "peer_id");
} else {
@@ -195,13 +195,11 @@ PropertyInfo VisualScriptFunctionCall::get_input_value_port_info(int p_idx) cons
#ifdef DEBUG_METHODS_ENABLED
if (call_mode == CALL_MODE_BASIC_TYPE) {
-
Vector<StringName> names = Variant::get_method_argument_names(basic_type, function);
Vector<Variant::Type> types = Variant::get_method_argument_types(basic_type, function);
return PropertyInfo(types[p_idx], names[p_idx]);
} else {
-
MethodBind *mb = ClassDB::get_method(_get_base_type(), function);
if (mb) {
return mb->get_argument_info(p_idx);
@@ -219,14 +217,11 @@ PropertyInfo VisualScriptFunctionCall::get_input_value_port_info(int p_idx) cons
}
PropertyInfo VisualScriptFunctionCall::get_output_value_port_info(int p_idx) const {
-
#ifdef DEBUG_METHODS_ENABLED
if (call_mode == CALL_MODE_BASIC_TYPE) {
-
return PropertyInfo(Variant::get_method_return_type(basic_type, function), "");
} else {
-
if (call_mode == CALL_MODE_INSTANCE) {
if (p_idx == 0) {
return PropertyInfo(Variant::OBJECT, "pass", PROPERTY_HINT_TYPE_STRING, get_base_type());
@@ -260,20 +255,21 @@ PropertyInfo VisualScriptFunctionCall::get_output_value_port_info(int p_idx) con
}
String VisualScriptFunctionCall::get_caption() const {
- if (call_mode == CALL_MODE_SELF)
+ if (call_mode == CALL_MODE_SELF) {
return " " + String(function) + "()";
- if (call_mode == CALL_MODE_SINGLETON)
+ }
+ if (call_mode == CALL_MODE_SINGLETON) {
return String(singleton) + ":" + String(function) + "()";
- else if (call_mode == CALL_MODE_BASIC_TYPE)
+ } else if (call_mode == CALL_MODE_BASIC_TYPE) {
return Variant::get_type_name(basic_type) + "." + String(function) + "()";
- else if (call_mode == CALL_MODE_NODE_PATH)
+ } else if (call_mode == CALL_MODE_NODE_PATH) {
return " [" + String(base_path.simplified()) + "]." + String(function) + "()";
- else
+ } else {
return " " + base_type + "." + String(function) + "()";
+ }
}
String VisualScriptFunctionCall::get_text() const {
-
if (rpc_call_mode) {
return "RPC";
}
@@ -281,9 +277,9 @@ String VisualScriptFunctionCall::get_text() const {
}
void VisualScriptFunctionCall::set_basic_type(Variant::Type p_type) {
-
- if (basic_type == p_type)
+ if (basic_type == p_type) {
return;
+ }
basic_type = p_type;
_change_notify();
@@ -291,14 +287,13 @@ void VisualScriptFunctionCall::set_basic_type(Variant::Type p_type) {
}
Variant::Type VisualScriptFunctionCall::get_basic_type() const {
-
return basic_type;
}
void VisualScriptFunctionCall::set_base_type(const StringName &p_type) {
-
- if (base_type == p_type)
+ if (base_type == p_type) {
return;
+ }
base_type = p_type;
_change_notify();
@@ -306,14 +301,13 @@ void VisualScriptFunctionCall::set_base_type(const StringName &p_type) {
}
StringName VisualScriptFunctionCall::get_base_type() const {
-
return base_type;
}
void VisualScriptFunctionCall::set_base_script(const String &p_path) {
-
- if (base_script == p_path)
+ if (base_script == p_path) {
return;
+ }
base_script = p_path;
_change_notify();
@@ -321,14 +315,13 @@ void VisualScriptFunctionCall::set_base_script(const String &p_path) {
}
String VisualScriptFunctionCall::get_base_script() const {
-
return base_script;
}
void VisualScriptFunctionCall::set_singleton(const StringName &p_type) {
-
- if (singleton == p_type)
+ if (singleton == p_type) {
return;
+ }
singleton = p_type;
Object *obj = Engine::get_singleton()->get_singleton_object(singleton);
@@ -341,7 +334,6 @@ void VisualScriptFunctionCall::set_singleton(const StringName &p_type) {
}
StringName VisualScriptFunctionCall::get_singleton() const {
-
return singleton;
}
@@ -350,7 +342,6 @@ void VisualScriptFunctionCall::_update_method_cache() {
Ref<Script> script;
if (call_mode == CALL_MODE_NODE_PATH) {
-
Node *node = _get_base_node();
if (node) {
type = node->get_class();
@@ -358,7 +349,6 @@ void VisualScriptFunctionCall::_update_method_cache() {
script = node->get_script();
}
} else if (call_mode == CALL_MODE_SELF) {
-
if (get_visual_script().is_valid()) {
type = get_visual_script()->get_instance_base_type();
base_type = type; //cache, too
@@ -366,7 +356,6 @@ void VisualScriptFunctionCall::_update_method_cache() {
}
} else if (call_mode == CALL_MODE_SINGLETON) {
-
Object *obj = Engine::get_singleton()->get_singleton_object(singleton);
if (obj) {
type = obj->get_class();
@@ -374,17 +363,13 @@ void VisualScriptFunctionCall::_update_method_cache() {
}
} else if (call_mode == CALL_MODE_INSTANCE) {
-
type = base_type;
if (base_script != String()) {
-
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
-
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
if (ResourceCache::has(base_script)) {
-
script = Ref<Resource>(ResourceCache::get(base_script));
} else {
return;
@@ -421,16 +406,15 @@ void VisualScriptFunctionCall::_update_method_cache() {
}
}
} else if (script.is_valid() && script->has_method(function)) {
-
method_cache = script->get_method_info(function);
use_default_args = method_cache.default_arguments.size();
}
}
void VisualScriptFunctionCall::set_function(const StringName &p_type) {
-
- if (function == p_type)
+ if (function == p_type) {
return;
+ }
function = p_type;
@@ -445,15 +429,15 @@ void VisualScriptFunctionCall::set_function(const StringName &p_type) {
_change_notify();
ports_changed_notify();
}
-StringName VisualScriptFunctionCall::get_function() const {
+StringName VisualScriptFunctionCall::get_function() const {
return function;
}
void VisualScriptFunctionCall::set_base_path(const NodePath &p_type) {
-
- if (base_path == p_type)
+ if (base_path == p_type) {
return;
+ }
base_path = p_type;
_change_notify();
@@ -461,59 +445,54 @@ void VisualScriptFunctionCall::set_base_path(const NodePath &p_type) {
}
NodePath VisualScriptFunctionCall::get_base_path() const {
-
return base_path;
}
void VisualScriptFunctionCall::set_call_mode(CallMode p_mode) {
-
- if (call_mode == p_mode)
+ if (call_mode == p_mode) {
return;
+ }
call_mode = p_mode;
_change_notify();
ports_changed_notify();
}
-VisualScriptFunctionCall::CallMode VisualScriptFunctionCall::get_call_mode() const {
+VisualScriptFunctionCall::CallMode VisualScriptFunctionCall::get_call_mode() const {
return call_mode;
}
void VisualScriptFunctionCall::set_use_default_args(int p_amount) {
-
- if (use_default_args == p_amount)
+ if (use_default_args == p_amount) {
return;
+ }
use_default_args = p_amount;
ports_changed_notify();
}
void VisualScriptFunctionCall::set_rpc_call_mode(VisualScriptFunctionCall::RPCCallMode p_mode) {
-
- if (rpc_call_mode == p_mode)
+ if (rpc_call_mode == p_mode) {
return;
+ }
rpc_call_mode = p_mode;
ports_changed_notify();
_change_notify();
}
VisualScriptFunctionCall::RPCCallMode VisualScriptFunctionCall::get_rpc_call_mode() const {
-
return rpc_call_mode;
}
int VisualScriptFunctionCall::get_use_default_args() const {
-
return use_default_args;
}
void VisualScriptFunctionCall::set_validate(bool p_amount) {
-
validate = p_amount;
}
bool VisualScriptFunctionCall::get_validate() const {
-
return validate;
}
@@ -523,12 +502,10 @@ void VisualScriptFunctionCall::_set_argument_cache(const Dictionary &p_cache) {
}
Dictionary VisualScriptFunctionCall::_get_argument_cache() const {
-
return method_cache;
}
void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const {
-
if (property.name == "base_type") {
if (call_mode != CALL_MODE_INSTANCE) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
@@ -556,8 +533,9 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
property.hint = PROPERTY_HINT_ENUM;
String sl;
for (List<Engine::Singleton>::Element *E = names.front(); E; E = E->next()) {
- if (sl != String())
+ if (sl != String()) {
sl += ",";
+ }
sl += E->get().name;
}
property.hint_string = sl;
@@ -568,7 +546,6 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
if (call_mode != CALL_MODE_NODE_PATH) {
property.usage = 0;
} else {
-
Node *bnode = _get_base_node();
if (bnode) {
property.hint_string = bnode->get_path(); //convert to loong string
@@ -577,9 +554,7 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
}
if (property.name == "function") {
-
if (call_mode == CALL_MODE_BASIC_TYPE) {
-
property.hint = PROPERTY_HINT_METHOD_OF_VARIANT_TYPE;
property.hint_string = Variant::get_type_name(basic_type);
@@ -587,13 +562,11 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
property.hint = PROPERTY_HINT_METHOD_OF_SCRIPT;
property.hint_string = itos(get_visual_script()->get_instance_id());
} else if (call_mode == CALL_MODE_SINGLETON) {
-
Object *obj = Engine::get_singleton()->get_singleton_object(singleton);
if (obj) {
property.hint = PROPERTY_HINT_METHOD_OF_INSTANCE;
property.hint_string = itos(obj->get_instance_id());
} else {
-
property.hint = PROPERTY_HINT_METHOD_OF_BASE_TYPE;
property.hint_string = base_type; //should be cached
}
@@ -603,15 +576,12 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
if (base_script != String()) {
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
-
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
if (ResourceCache::has(base_script)) {
-
Ref<Script> script = Ref<Resource>(ResourceCache::get(base_script));
if (script.is_valid()) {
-
property.hint = PROPERTY_HINT_METHOD_OF_SCRIPT;
property.hint_string = itos(script->get_instance_id());
}
@@ -631,18 +601,15 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
}
if (property.name == "use_default_args") {
-
property.hint = PROPERTY_HINT_RANGE;
int mc = 0;
if (call_mode == CALL_MODE_BASIC_TYPE) {
-
mc = Variant::get_method_default_arguments(basic_type, function).size();
} else {
MethodBind *mb = ClassDB::get_method(_get_base_type(), function);
if (mb) {
-
mc = mb->get_default_argument_count();
}
}
@@ -650,7 +617,6 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
if (mc == 0) {
property.usage = 0; //do not show
} else {
-
property.hint_string = "0," + itos(mc) + ",1";
}
}
@@ -663,7 +629,6 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const
}
void VisualScriptFunctionCall::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &VisualScriptFunctionCall::set_base_type);
ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptFunctionCall::get_base_type);
@@ -699,8 +664,9 @@ void VisualScriptFunctionCall::_bind_methods() {
String bt;
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
- if (i > 0)
+ if (i > 0) {
bt += ",";
+ }
bt += Variant::get_type_name(Variant::Type(i));
}
@@ -712,8 +678,9 @@ void VisualScriptFunctionCall::_bind_methods() {
String script_ext_hint;
for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) {
- if (script_ext_hint != String())
+ if (script_ext_hint != String()) {
script_ext_hint += ",";
+ }
script_ext_hint += "*." + E->get();
}
@@ -761,13 +728,14 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
_FORCE_INLINE_ bool call_rpc(Object *p_base, const Variant **p_args, int p_argcount) {
-
- if (!p_base)
+ if (!p_base) {
return false;
+ }
Node *node = Object::cast_to<Node>(p_base);
- if (!node)
+ if (!node) {
return false;
+ }
int to_id = 0;
bool reliable = true;
@@ -789,11 +757,8 @@ public:
}
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
switch (call_mode) {
-
case VisualScriptFunctionCall::CALL_MODE_SELF: {
-
Object *object = instance->get_owner_ptr();
if (rpc_mode) {
@@ -805,7 +770,6 @@ public:
}
} break;
case VisualScriptFunctionCall::CALL_MODE_NODE_PATH: {
-
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -831,7 +795,6 @@ public:
} break;
case VisualScriptFunctionCall::CALL_MODE_INSTANCE:
case VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE: {
-
Variant v = *p_inputs[0];
if (rpc_mode) {
@@ -863,7 +826,6 @@ public:
} break;
case VisualScriptFunctionCall::CALL_MODE_SINGLETON: {
-
Object *object = Engine::get_singleton()->get_singleton_object(singleton);
if (!object) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -882,7 +844,6 @@ public:
}
if (!validate) {
-
//ignore call errors if validation is disabled
r_error.error = Callable::CallError::CALL_OK;
r_error_str = String();
@@ -893,7 +854,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptFunctionCall::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceFunctionCall *instance = memnew(VisualScriptNodeInstanceFunctionCall);
instance->node = this;
instance->instance = p_instance;
@@ -909,7 +869,6 @@ VisualScriptNodeInstance *VisualScriptFunctionCall::instance(VisualScriptInstanc
}
VisualScriptFunctionCall::TypeGuess VisualScriptFunctionCall::guess_output_type(TypeGuess *p_inputs, int p_output) const {
-
if (p_output == 0 && call_mode == CALL_MODE_INSTANCE) {
return p_inputs[0];
}
@@ -918,7 +877,6 @@ VisualScriptFunctionCall::TypeGuess VisualScriptFunctionCall::guess_output_type(
}
VisualScriptFunctionCall::VisualScriptFunctionCall() {
-
validate = true;
call_mode = CALL_MODE_SELF;
basic_type = Variant::NIL;
@@ -929,7 +887,6 @@ VisualScriptFunctionCall::VisualScriptFunctionCall() {
template <VisualScriptFunctionCall::CallMode cmode>
static Ref<VisualScriptNode> create_function_call_node(const String &p_name) {
-
Ref<VisualScriptFunctionCall> node;
node.instance();
node->set_call_mode(cmode);
@@ -941,41 +898,43 @@ static Ref<VisualScriptNode> create_function_call_node(const String &p_name) {
//////////////////////////////////////////
int VisualScriptPropertySet::get_output_sequence_port_count() const {
-
return call_mode != CALL_MODE_BASIC_TYPE ? 1 : 0;
}
bool VisualScriptPropertySet::has_input_sequence_port() const {
-
return call_mode != CALL_MODE_BASIC_TYPE;
}
Node *VisualScriptPropertySet::_get_base_node() const {
-
#ifdef TOOLS_ENABLED
Ref<Script> script = get_visual_script();
- if (!script.is_valid())
+ if (!script.is_valid()) {
return nullptr;
+ }
MainLoop *main_loop = OS::get_singleton()->get_main_loop();
SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
- if (!scene_tree)
+ if (!scene_tree) {
return nullptr;
+ }
Node *edited_scene = scene_tree->get_edited_scene_root();
- if (!edited_scene)
+ if (!edited_scene) {
return nullptr;
+ }
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
- if (!script_node)
+ if (!script_node) {
return nullptr;
+ }
- if (!script_node->has_node(base_path))
+ if (!script_node->has_node(base_path)) {
return nullptr;
+ }
Node *path_to = script_node->get_node(base_path);
@@ -987,38 +946,34 @@ Node *VisualScriptPropertySet::_get_base_node() const {
}
StringName VisualScriptPropertySet::_get_base_type() const {
-
- if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid())
+ if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) {
return get_visual_script()->get_instance_base_type();
- else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
+ } else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
Node *path = _get_base_node();
- if (path)
+ if (path) {
return path->get_class();
+ }
}
return base_type;
}
int VisualScriptPropertySet::get_input_value_port_count() const {
-
int pc = (call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 2 : 1;
return pc;
}
-int VisualScriptPropertySet::get_output_value_port_count() const {
+int VisualScriptPropertySet::get_output_value_port_count() const {
return (call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 1 : 0;
}
String VisualScriptPropertySet::get_output_sequence_port_text(int p_port) const {
-
return String();
}
void VisualScriptPropertySet::_adjust_input_index(PropertyInfo &pinfo) const {
-
if (index != StringName()) {
-
Variant v;
Callable::CallError ce;
v = Variant::construct(pinfo.type, nullptr, 0, ce);
@@ -1065,7 +1020,6 @@ PropertyInfo VisualScriptPropertySet::get_output_value_port_info(int p_idx) cons
}
String VisualScriptPropertySet::get_caption() const {
-
static const char *opname[ASSIGN_OP_MAX] = {
"Set", "Add", "Subtract", "Multiply", "Divide", "Mod", "ShiftLeft", "ShiftRight", "BitAnd", "BitOr", "BitXor"
};
@@ -1079,7 +1033,6 @@ String VisualScriptPropertySet::get_caption() const {
}
String VisualScriptPropertySet::get_text() const {
-
if (call_mode == CALL_MODE_BASIC_TYPE) {
return String("On ") + Variant::get_type_name(basic_type);
}
@@ -1096,22 +1049,21 @@ String VisualScriptPropertySet::get_text() const {
void VisualScriptPropertySet::_update_base_type() {
//cache it because this information may not be available on load
if (call_mode == CALL_MODE_NODE_PATH) {
-
Node *node = _get_base_node();
if (node) {
base_type = node->get_class();
}
} else if (call_mode == CALL_MODE_SELF) {
-
if (get_visual_script().is_valid()) {
base_type = get_visual_script()->get_instance_base_type();
}
}
}
-void VisualScriptPropertySet::set_basic_type(Variant::Type p_type) {
- if (basic_type == p_type)
+void VisualScriptPropertySet::set_basic_type(Variant::Type p_type) {
+ if (basic_type == p_type) {
return;
+ }
basic_type = p_type;
_change_notify();
@@ -1120,14 +1072,13 @@ void VisualScriptPropertySet::set_basic_type(Variant::Type p_type) {
}
Variant::Type VisualScriptPropertySet::get_basic_type() const {
-
return basic_type;
}
void VisualScriptPropertySet::set_base_type(const StringName &p_type) {
-
- if (base_type == p_type)
+ if (base_type == p_type) {
return;
+ }
base_type = p_type;
_change_notify();
@@ -1135,14 +1086,13 @@ void VisualScriptPropertySet::set_base_type(const StringName &p_type) {
}
StringName VisualScriptPropertySet::get_base_type() const {
-
return base_type;
}
void VisualScriptPropertySet::set_base_script(const String &p_path) {
-
- if (base_script == p_path)
+ if (base_script == p_path) {
return;
+ }
base_script = p_path;
_change_notify();
@@ -1150,20 +1100,19 @@ void VisualScriptPropertySet::set_base_script(const String &p_path) {
}
String VisualScriptPropertySet::get_base_script() const {
-
return base_script;
}
void VisualScriptPropertySet::_update_cache() {
-
- if (!Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop()))
+ if (!Object::cast_to<SceneTree>(OS::get_singleton()->get_main_loop())) {
return;
+ }
- if (!Engine::get_singleton()->is_editor_hint()) //only update cache if editor exists, it's pointless otherwise
+ if (!Engine::get_singleton()->is_editor_hint()) { //only update cache if editor exists, it's pointless otherwise
return;
+ }
if (call_mode == CALL_MODE_BASIC_TYPE) {
-
//not super efficient..
Variant v;
@@ -1174,21 +1123,17 @@ void VisualScriptPropertySet::_update_cache() {
v.get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
if (E->get().name == property) {
-
type_cache = E->get();
}
}
} else {
-
StringName type;
Ref<Script> script;
Node *node = nullptr;
if (call_mode == CALL_MODE_NODE_PATH) {
-
node = _get_base_node();
if (node) {
type = node->get_class();
@@ -1196,24 +1141,19 @@ void VisualScriptPropertySet::_update_cache() {
script = node->get_script();
}
} else if (call_mode == CALL_MODE_SELF) {
-
if (get_visual_script().is_valid()) {
type = get_visual_script()->get_instance_base_type();
base_type = type; //cache, too
script = get_visual_script();
}
} else if (call_mode == CALL_MODE_INSTANCE) {
-
type = base_type;
if (base_script != String()) {
-
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
-
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
if (ResourceCache::has(base_script)) {
-
script = Ref<Resource>(ResourceCache::get(base_script));
} else {
return;
@@ -1224,19 +1164,16 @@ void VisualScriptPropertySet::_update_cache() {
List<PropertyInfo> pinfo;
if (node) {
-
node->get_property_list(&pinfo);
} else {
ClassDB::get_property_list(type, &pinfo);
}
if (script.is_valid()) {
-
script->get_script_property_list(&pinfo);
}
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
if (E->get().name == property) {
type_cache = E->get();
return;
@@ -1246,9 +1183,9 @@ void VisualScriptPropertySet::_update_cache() {
}
void VisualScriptPropertySet::set_property(const StringName &p_type) {
-
- if (property == p_type)
+ if (property == p_type) {
return;
+ }
property = p_type;
index = StringName();
@@ -1256,15 +1193,15 @@ void VisualScriptPropertySet::set_property(const StringName &p_type) {
_change_notify();
ports_changed_notify();
}
-StringName VisualScriptPropertySet::get_property() const {
+StringName VisualScriptPropertySet::get_property() const {
return property;
}
void VisualScriptPropertySet::set_base_path(const NodePath &p_type) {
-
- if (base_path == p_type)
+ if (base_path == p_type) {
return;
+ }
base_path = p_type;
_update_base_type();
@@ -1273,22 +1210,21 @@ void VisualScriptPropertySet::set_base_path(const NodePath &p_type) {
}
NodePath VisualScriptPropertySet::get_base_path() const {
-
return base_path;
}
void VisualScriptPropertySet::set_call_mode(CallMode p_mode) {
-
- if (call_mode == p_mode)
+ if (call_mode == p_mode) {
return;
+ }
call_mode = p_mode;
_update_base_type();
_change_notify();
ports_changed_notify();
}
-VisualScriptPropertySet::CallMode VisualScriptPropertySet::get_call_mode() const {
+VisualScriptPropertySet::CallMode VisualScriptPropertySet::get_call_mode() const {
return call_mode;
}
@@ -1297,14 +1233,13 @@ void VisualScriptPropertySet::_set_type_cache(const Dictionary &p_type) {
}
Dictionary VisualScriptPropertySet::_get_type_cache() const {
-
return type_cache;
}
void VisualScriptPropertySet::set_index(const StringName &p_type) {
-
- if (index == p_type)
+ if (index == p_type) {
return;
+ }
index = p_type;
_update_cache();
_change_notify();
@@ -1312,15 +1247,14 @@ void VisualScriptPropertySet::set_index(const StringName &p_type) {
}
StringName VisualScriptPropertySet::get_index() const {
-
return index;
}
void VisualScriptPropertySet::set_assign_op(AssignOp p_op) {
-
ERR_FAIL_INDEX(p_op, ASSIGN_OP_MAX);
- if (assign_op == p_op)
+ if (assign_op == p_op) {
return;
+ }
assign_op = p_op;
_update_cache();
@@ -1333,7 +1267,6 @@ VisualScriptPropertySet::AssignOp VisualScriptPropertySet::get_assign_op() const
}
void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
-
if (property.name == "base_type") {
if (call_mode != CALL_MODE_INSTANCE) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
@@ -1356,7 +1289,6 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
if (call_mode != CALL_MODE_NODE_PATH) {
property.usage = 0;
} else {
-
Node *bnode = _get_base_node();
if (bnode) {
property.hint_string = bnode->get_path(); //convert to loong string
@@ -1365,9 +1297,7 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
}
if (property.name == "property") {
-
if (call_mode == CALL_MODE_BASIC_TYPE) {
-
property.hint = PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE;
property.hint_string = Variant::get_type_name(basic_type);
@@ -1380,15 +1310,12 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
if (base_script != String()) {
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
-
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
if (ResourceCache::has(base_script)) {
-
Ref<Script> script = Ref<Resource>(ResourceCache::get(base_script));
if (script.is_valid()) {
-
property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT;
property.hint_string = itos(script->get_instance_id());
}
@@ -1408,7 +1335,6 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
}
if (property.name == "index") {
-
Callable::CallError ce;
Variant v = Variant::construct(type_cache.type, nullptr, 0, ce);
List<PropertyInfo> plist;
@@ -1421,13 +1347,13 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
property.hint = PROPERTY_HINT_ENUM;
property.hint_string = options;
property.type = Variant::STRING;
- if (options == "")
+ if (options == "") {
property.usage = 0; //hide if type has no usable index
+ }
}
}
void VisualScriptPropertySet::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &VisualScriptPropertySet::set_base_type);
ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptPropertySet::get_base_type);
@@ -1457,8 +1383,9 @@ void VisualScriptPropertySet::_bind_methods() {
String bt;
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
- if (i > 0)
+ if (i > 0) {
bt += ",";
+ }
bt += Variant::get_type_name(Variant::Type(i));
}
@@ -1470,8 +1397,9 @@ void VisualScriptPropertySet::_bind_methods() {
String script_ext_hint;
for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) {
- if (script_ext_hint != String())
+ if (script_ext_hint != String()) {
script_ext_hint += ",";
+ }
script_ext_hint += "*." + E->get();
}
@@ -1520,11 +1448,9 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
_FORCE_INLINE_ void _process_get(Variant &source, const Variant &p_argument, bool &valid) {
-
if (index != StringName() && assign_op == VisualScriptPropertySet::ASSIGN_OP_NONE) {
source.set_named(index, p_argument, &valid);
} else {
-
Variant value;
if (index != StringName()) {
value = source.get_named(index, &valid);
@@ -1579,11 +1505,8 @@ public:
}
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
switch (call_mode) {
-
case VisualScriptPropertySet::CALL_MODE_SELF: {
-
Object *object = instance->get_owner_ptr();
bool valid;
@@ -1602,7 +1525,6 @@ public:
}
} break;
case VisualScriptPropertySet::CALL_MODE_NODE_PATH: {
-
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -1620,7 +1542,6 @@ public:
bool valid;
if (needs_get) {
-
Variant value = another->get(property, &valid);
_process_get(value, *p_inputs[0], valid);
another->set(property, value, &valid);
@@ -1636,7 +1557,6 @@ public:
} break;
case VisualScriptPropertySet::CALL_MODE_INSTANCE:
case VisualScriptPropertySet::CALL_MODE_BASIC_TYPE: {
-
Variant v = *p_inputs[0];
bool valid;
@@ -1664,7 +1584,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptPropertySet::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstancePropertySet *instance = memnew(VisualScriptNodeInstancePropertySet);
instance->node = this;
instance->instance = p_instance;
@@ -1678,15 +1597,14 @@ VisualScriptNodeInstance *VisualScriptPropertySet::instance(VisualScriptInstance
}
VisualScriptPropertySet::TypeGuess VisualScriptPropertySet::guess_output_type(TypeGuess *p_inputs, int p_output) const {
-
if (p_output == 0 && call_mode == CALL_MODE_INSTANCE) {
return p_inputs[0];
}
return VisualScriptNode::guess_output_type(p_inputs, p_output);
}
-VisualScriptPropertySet::VisualScriptPropertySet() {
+VisualScriptPropertySet::VisualScriptPropertySet() {
assign_op = ASSIGN_OP_NONE;
call_mode = CALL_MODE_SELF;
base_type = "Object";
@@ -1695,7 +1613,6 @@ VisualScriptPropertySet::VisualScriptPropertySet() {
template <VisualScriptPropertySet::CallMode cmode>
static Ref<VisualScriptNode> create_property_set_node(const String &p_name) {
-
Ref<VisualScriptPropertySet> node;
node.instance();
node->set_call_mode(cmode);
@@ -1707,55 +1624,57 @@ static Ref<VisualScriptNode> create_property_set_node(const String &p_name) {
//////////////////////////////////////////
int VisualScriptPropertyGet::get_output_sequence_port_count() const {
-
return 0; // (call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?0:1;
}
bool VisualScriptPropertyGet::has_input_sequence_port() const {
-
return false; //(call_mode==CALL_MODE_SELF || call_mode==CALL_MODE_NODE_PATH)?false:true;
}
+
void VisualScriptPropertyGet::_update_base_type() {
//cache it because this information may not be available on load
if (call_mode == CALL_MODE_NODE_PATH) {
-
Node *node = _get_base_node();
if (node) {
base_type = node->get_class();
}
} else if (call_mode == CALL_MODE_SELF) {
-
if (get_visual_script().is_valid()) {
base_type = get_visual_script()->get_instance_base_type();
}
}
}
-Node *VisualScriptPropertyGet::_get_base_node() const {
+Node *VisualScriptPropertyGet::_get_base_node() const {
#ifdef TOOLS_ENABLED
Ref<Script> script = get_visual_script();
- if (!script.is_valid())
+ if (!script.is_valid()) {
return nullptr;
+ }
MainLoop *main_loop = OS::get_singleton()->get_main_loop();
SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
- if (!scene_tree)
+ if (!scene_tree) {
return nullptr;
+ }
Node *edited_scene = scene_tree->get_edited_scene_root();
- if (!edited_scene)
+ if (!edited_scene) {
return nullptr;
+ }
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
- if (!script_node)
+ if (!script_node) {
return nullptr;
+ }
- if (!script_node->has_node(base_path))
+ if (!script_node->has_node(base_path)) {
return nullptr;
+ }
Node *path_to = script_node->get_node(base_path);
@@ -1767,34 +1686,31 @@ Node *VisualScriptPropertyGet::_get_base_node() const {
}
StringName VisualScriptPropertyGet::_get_base_type() const {
-
- if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid())
+ if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) {
return get_visual_script()->get_instance_base_type();
- else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
+ } else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
Node *path = _get_base_node();
- if (path)
+ if (path) {
return path->get_class();
+ }
}
return base_type;
}
int VisualScriptPropertyGet::get_input_value_port_count() const {
-
return (call_mode == CALL_MODE_BASIC_TYPE || call_mode == CALL_MODE_INSTANCE) ? 1 : 0;
}
-int VisualScriptPropertyGet::get_output_value_port_count() const {
+int VisualScriptPropertyGet::get_output_value_port_count() const {
return 1;
}
String VisualScriptPropertyGet::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptPropertyGet::get_input_value_port_info(int p_idx) const {
-
if (call_mode == CALL_MODE_INSTANCE || call_mode == CALL_MODE_BASIC_TYPE) {
if (p_idx == 0) {
PropertyInfo pi;
@@ -1819,12 +1735,10 @@ PropertyInfo VisualScriptPropertyGet::get_output_value_port_info(int p_idx) cons
}
String VisualScriptPropertyGet::get_caption() const {
-
return String("Get ") + property;
}
String VisualScriptPropertyGet::get_text() const {
-
if (call_mode == CALL_MODE_BASIC_TYPE) {
return String("On ") + Variant::get_type_name(basic_type);
}
@@ -1839,9 +1753,9 @@ String VisualScriptPropertyGet::get_text() const {
}
void VisualScriptPropertyGet::set_base_type(const StringName &p_type) {
-
- if (base_type == p_type)
+ if (base_type == p_type) {
return;
+ }
base_type = p_type;
_change_notify();
@@ -1849,14 +1763,13 @@ void VisualScriptPropertyGet::set_base_type(const StringName &p_type) {
}
StringName VisualScriptPropertyGet::get_base_type() const {
-
return base_type;
}
void VisualScriptPropertyGet::set_base_script(const String &p_path) {
-
- if (base_script == p_path)
+ if (base_script == p_path) {
return;
+ }
base_script = p_path;
_change_notify();
@@ -1864,14 +1777,11 @@ void VisualScriptPropertyGet::set_base_script(const String &p_path) {
}
String VisualScriptPropertyGet::get_base_script() const {
-
return base_script;
}
void VisualScriptPropertyGet::_update_cache() {
-
if (call_mode == CALL_MODE_BASIC_TYPE) {
-
//not super efficient..
Variant v;
@@ -1882,22 +1792,18 @@ void VisualScriptPropertyGet::_update_cache() {
v.get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
if (E->get().name == property) {
-
type_cache = E->get().type;
return;
}
}
} else {
-
StringName type;
Ref<Script> script;
Node *node = nullptr;
if (call_mode == CALL_MODE_NODE_PATH) {
-
node = _get_base_node();
if (node) {
type = node->get_class();
@@ -1905,24 +1811,19 @@ void VisualScriptPropertyGet::_update_cache() {
script = node->get_script();
}
} else if (call_mode == CALL_MODE_SELF) {
-
if (get_visual_script().is_valid()) {
type = get_visual_script()->get_instance_base_type();
base_type = type; //cache, too
script = get_visual_script();
}
} else if (call_mode == CALL_MODE_INSTANCE) {
-
type = base_type;
if (base_script != String()) {
-
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
-
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
if (ResourceCache::has(base_script)) {
-
script = Ref<Resource>(ResourceCache::get(base_script));
} else {
return;
@@ -1942,7 +1843,6 @@ void VisualScriptPropertyGet::_update_cache() {
}
if (node) {
-
Variant prop = node->get(property, &valid);
if (valid) {
type_cache = prop.get_type();
@@ -1951,7 +1851,6 @@ void VisualScriptPropertyGet::_update_cache() {
}
if (script.is_valid()) {
-
type_ret = script->get_static_property_type(property, &valid);
if (valid) {
@@ -1963,9 +1862,9 @@ void VisualScriptPropertyGet::_update_cache() {
}
void VisualScriptPropertyGet::set_property(const StringName &p_type) {
-
- if (property == p_type)
+ if (property == p_type) {
return;
+ }
property = p_type;
@@ -1973,15 +1872,15 @@ void VisualScriptPropertyGet::set_property(const StringName &p_type) {
_change_notify();
ports_changed_notify();
}
-StringName VisualScriptPropertyGet::get_property() const {
+StringName VisualScriptPropertyGet::get_property() const {
return property;
}
void VisualScriptPropertyGet::set_base_path(const NodePath &p_type) {
-
- if (base_path == p_type)
+ if (base_path == p_type) {
return;
+ }
base_path = p_type;
_change_notify();
@@ -1990,29 +1889,28 @@ void VisualScriptPropertyGet::set_base_path(const NodePath &p_type) {
}
NodePath VisualScriptPropertyGet::get_base_path() const {
-
return base_path;
}
void VisualScriptPropertyGet::set_call_mode(CallMode p_mode) {
-
- if (call_mode == p_mode)
+ if (call_mode == p_mode) {
return;
+ }
call_mode = p_mode;
_change_notify();
_update_base_type();
ports_changed_notify();
}
-VisualScriptPropertyGet::CallMode VisualScriptPropertyGet::get_call_mode() const {
+VisualScriptPropertyGet::CallMode VisualScriptPropertyGet::get_call_mode() const {
return call_mode;
}
void VisualScriptPropertyGet::set_basic_type(Variant::Type p_type) {
-
- if (basic_type == p_type)
+ if (basic_type == p_type) {
return;
+ }
basic_type = p_type;
_change_notify();
@@ -2020,7 +1918,6 @@ void VisualScriptPropertyGet::set_basic_type(Variant::Type p_type) {
}
Variant::Type VisualScriptPropertyGet::get_basic_type() const {
-
return basic_type;
}
@@ -2029,14 +1926,13 @@ void VisualScriptPropertyGet::_set_type_cache(Variant::Type p_type) {
}
Variant::Type VisualScriptPropertyGet::_get_type_cache() const {
-
return type_cache;
}
void VisualScriptPropertyGet::set_index(const StringName &p_type) {
-
- if (index == p_type)
+ if (index == p_type) {
return;
+ }
index = p_type;
_update_cache();
_change_notify();
@@ -2044,12 +1940,10 @@ void VisualScriptPropertyGet::set_index(const StringName &p_type) {
}
StringName VisualScriptPropertyGet::get_index() const {
-
return index;
}
void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
-
if (property.name == "base_type") {
if (call_mode != CALL_MODE_INSTANCE) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
@@ -2072,7 +1966,6 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
if (call_mode != CALL_MODE_NODE_PATH) {
property.usage = 0;
} else {
-
Node *bnode = _get_base_node();
if (bnode) {
property.hint_string = bnode->get_path(); //convert to loong string
@@ -2081,9 +1974,7 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
}
if (property.name == "property") {
-
if (call_mode == CALL_MODE_BASIC_TYPE) {
-
property.hint = PROPERTY_HINT_PROPERTY_OF_VARIANT_TYPE;
property.hint_string = Variant::get_type_name(basic_type);
@@ -2096,15 +1987,12 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
if (base_script != String()) {
if (!ResourceCache::has(base_script) && ScriptServer::edit_request_func) {
-
ScriptServer::edit_request_func(base_script); //make sure it's loaded
}
if (ResourceCache::has(base_script)) {
-
Ref<Script> script = Ref<Resource>(ResourceCache::get(base_script));
if (script.is_valid()) {
-
property.hint = PROPERTY_HINT_PROPERTY_OF_SCRIPT;
property.hint_string = itos(script->get_instance_id());
}
@@ -2123,7 +2011,6 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
}
if (property.name == "index") {
-
Callable::CallError ce;
Variant v = Variant::construct(type_cache, nullptr, 0, ce);
List<PropertyInfo> plist;
@@ -2136,13 +2023,13 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
property.hint = PROPERTY_HINT_ENUM;
property.hint_string = options;
property.type = Variant::STRING;
- if (options == "")
+ if (options == "") {
property.usage = 0; //hide if type has no usable index
+ }
}
}
void VisualScriptPropertyGet::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &VisualScriptPropertyGet::set_base_type);
ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptPropertyGet::get_base_type);
@@ -2169,8 +2056,9 @@ void VisualScriptPropertyGet::_bind_methods() {
String bt;
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
- if (i > 0)
+ if (i > 0) {
bt += ",";
+ }
bt += Variant::get_type_name(Variant::Type(i));
}
@@ -2182,8 +2070,9 @@ void VisualScriptPropertyGet::_bind_methods() {
String script_ext_hint;
for (List<String>::Element *E = script_extensions.front(); E; E = E->next()) {
- if (script_ext_hint != String())
+ if (script_ext_hint != String()) {
script_ext_hint += ",";
+ }
script_ext_hint += "." + E->get();
}
@@ -2212,11 +2101,8 @@ public:
VisualScriptInstance *instance;
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
switch (call_mode) {
-
case VisualScriptPropertyGet::CALL_MODE_SELF: {
-
Object *object = instance->get_owner_ptr();
bool valid;
@@ -2234,7 +2120,6 @@ public:
}
} break;
case VisualScriptPropertyGet::CALL_MODE_NODE_PATH: {
-
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -2265,7 +2150,6 @@ public:
} break;
default: {
-
bool valid;
Variant v = *p_inputs[0];
@@ -2286,7 +2170,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptPropertyGet::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstancePropertyGet *instance = memnew(VisualScriptNodeInstancePropertyGet);
instance->node = this;
instance->instance = p_instance;
@@ -2299,7 +2182,6 @@ VisualScriptNodeInstance *VisualScriptPropertyGet::instance(VisualScriptInstance
}
VisualScriptPropertyGet::VisualScriptPropertyGet() {
-
call_mode = CALL_MODE_SELF;
base_type = "Object";
basic_type = Variant::NIL;
@@ -2308,7 +2190,6 @@ VisualScriptPropertyGet::VisualScriptPropertyGet() {
template <VisualScriptPropertyGet::CallMode cmode>
static Ref<VisualScriptNode> create_property_get_node(const String &p_name) {
-
Ref<VisualScriptPropertyGet> node;
node.instance();
node->set_call_mode(cmode);
@@ -2320,44 +2201,40 @@ static Ref<VisualScriptNode> create_property_get_node(const String &p_name) {
//////////////////////////////////////////
int VisualScriptEmitSignal::get_output_sequence_port_count() const {
-
return 1;
}
bool VisualScriptEmitSignal::has_input_sequence_port() const {
-
return true;
}
int VisualScriptEmitSignal::get_input_value_port_count() const {
-
Ref<VisualScript> vs = get_visual_script();
if (vs.is_valid()) {
-
- if (!vs->has_custom_signal(name))
+ if (!vs->has_custom_signal(name)) {
return 0;
+ }
return vs->custom_signal_get_argument_count(name);
}
return 0;
}
+
int VisualScriptEmitSignal::get_output_value_port_count() const {
return 0;
}
String VisualScriptEmitSignal::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptEmitSignal::get_input_value_port_info(int p_idx) const {
-
Ref<VisualScript> vs = get_visual_script();
if (vs.is_valid()) {
-
- if (!vs->has_custom_signal(name))
+ if (!vs->has_custom_signal(name)) {
return PropertyInfo();
+ }
return PropertyInfo(vs->custom_signal_get_argument_type(name, p_idx), vs->custom_signal_get_argument_name(name, p_idx));
}
@@ -2366,32 +2243,29 @@ PropertyInfo VisualScriptEmitSignal::get_input_value_port_info(int p_idx) const
}
PropertyInfo VisualScriptEmitSignal::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
String VisualScriptEmitSignal::get_caption() const {
-
return "Emit " + String(name);
}
void VisualScriptEmitSignal::set_signal(const StringName &p_type) {
-
- if (name == p_type)
+ if (name == p_type) {
return;
+ }
name = p_type;
_change_notify();
ports_changed_notify();
}
-StringName VisualScriptEmitSignal::get_signal() const {
+StringName VisualScriptEmitSignal::get_signal() const {
return name;
}
void VisualScriptEmitSignal::_validate_property(PropertyInfo &property) const {
-
if (property.name == "signal") {
property.hint = PROPERTY_HINT_ENUM;
@@ -2399,15 +2273,14 @@ void VisualScriptEmitSignal::_validate_property(PropertyInfo &property) const {
Ref<VisualScript> vs = get_visual_script();
if (vs.is_valid()) {
-
vs->get_custom_signal_list(&sigs);
}
String ml;
for (List<StringName>::Element *E = sigs.front(); E; E = E->next()) {
-
- if (ml != String())
+ if (ml != String()) {
ml += ",";
+ }
ml += E->get();
}
@@ -2416,7 +2289,6 @@ void VisualScriptEmitSignal::_validate_property(PropertyInfo &property) const {
}
void VisualScriptEmitSignal::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_signal", "name"), &VisualScriptEmitSignal::set_signal);
ClassDB::bind_method(D_METHOD("get_signal"), &VisualScriptEmitSignal::get_signal);
@@ -2435,7 +2307,6 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
Object *obj = instance->get_owner_ptr();
obj->emit_signal(name, p_inputs, argcount);
@@ -2445,7 +2316,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptEmitSignal::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceEmitSignal *instance = memnew(VisualScriptNodeInstanceEmitSignal);
instance->node = this;
instance->instance = p_instance;
@@ -2458,7 +2328,6 @@ VisualScriptEmitSignal::VisualScriptEmitSignal() {
}
static Ref<VisualScriptNode> create_basic_type_call_node(const String &p_name) {
-
Vector<String> path = p_name.split("/");
ERR_FAIL_COND_V(path.size() < 4, Ref<VisualScriptNode>());
String base_type = path[2];
@@ -2470,7 +2339,6 @@ static Ref<VisualScriptNode> create_basic_type_call_node(const String &p_name) {
Variant::Type type = Variant::VARIANT_MAX;
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
-
if (Variant::get_type_name(Variant::Type(i)) == base_type) {
type = Variant::Type(i);
break;
@@ -2487,7 +2355,6 @@ static Ref<VisualScriptNode> create_basic_type_call_node(const String &p_name) {
}
void register_visual_script_func_nodes() {
-
VisualScriptLanguage::singleton->add_register_func("functions/call", create_node_generic<VisualScriptFunctionCall>);
VisualScriptLanguage::singleton->add_register_func("functions/set", create_node_generic<VisualScriptPropertySet>);
VisualScriptLanguage::singleton->add_register_func("functions/get", create_node_generic<VisualScriptPropertyGet>);
@@ -2497,7 +2364,6 @@ void register_visual_script_func_nodes() {
VisualScriptLanguage::singleton->add_register_func("functions/emit_signal", create_node_generic<VisualScriptEmitSignal>);
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
-
Variant::Type t = Variant::Type(i);
String type_name = Variant::get_type_name(t);
Callable::CallError ce;
diff --git a/modules/visual_script/visual_script_func_nodes.h b/modules/visual_script/visual_script_func_nodes.h
index 2dba0ae3c1..6921f0e820 100644
--- a/modules/visual_script/visual_script_func_nodes.h
+++ b/modules/visual_script/visual_script_func_nodes.h
@@ -34,7 +34,6 @@
#include "visual_script.h"
class VisualScriptFunctionCall : public VisualScriptNode {
-
GDCLASS(VisualScriptFunctionCall, VisualScriptNode);
public:
@@ -137,7 +136,6 @@ VARIANT_ENUM_CAST(VisualScriptFunctionCall::CallMode);
VARIANT_ENUM_CAST(VisualScriptFunctionCall::RPCCallMode);
class VisualScriptPropertySet : public VisualScriptNode {
-
GDCLASS(VisualScriptPropertySet, VisualScriptNode);
public:
@@ -243,7 +241,6 @@ VARIANT_ENUM_CAST(VisualScriptPropertySet::CallMode);
VARIANT_ENUM_CAST(VisualScriptPropertySet::AssignOp);
class VisualScriptPropertyGet : public VisualScriptNode {
-
GDCLASS(VisualScriptPropertyGet, VisualScriptNode);
public:
@@ -325,7 +322,6 @@ public:
VARIANT_ENUM_CAST(VisualScriptPropertyGet::CallMode);
class VisualScriptEmitSignal : public VisualScriptNode {
-
GDCLASS(VisualScriptEmitSignal, VisualScriptNode);
private:
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index c860e08943..87aa64211e 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -32,7 +32,7 @@
#include "core/engine.h"
#include "core/global_constants.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "scene/main/node.h"
@@ -43,13 +43,12 @@
//////////////////////////////////////////
bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value) {
-
if (p_name == "argument_count") {
-
int new_argc = p_value;
int argc = arguments.size();
- if (argc == new_argc)
+ if (argc == new_argc) {
return true;
+ }
arguments.resize(new_argc);
@@ -66,7 +65,6 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value
ERR_FAIL_INDEX_V(idx, arguments.size(), false);
String what = String(p_name).get_slice("/", 1);
if (what == "type") {
-
Variant::Type new_type = Variant::Type(int(p_value));
arguments.write[idx].type = new_type;
ports_changed_notify();
@@ -75,7 +73,6 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value
}
if (what == "name") {
-
arguments.write[idx].name = p_value;
ports_changed_notify();
return true;
@@ -107,7 +104,6 @@ bool VisualScriptFunction::_set(const StringName &p_name, const Variant &p_value
}
bool VisualScriptFunction::_get(const StringName &p_name, Variant &r_ret) const {
-
if (p_name == "argument_count") {
r_ret = arguments.size();
return true;
@@ -148,8 +144,8 @@ bool VisualScriptFunction::_get(const StringName &p_name, Variant &r_ret) const
return false;
}
-void VisualScriptFunction::_get_property_list(List<PropertyInfo> *p_list) const {
+void VisualScriptFunction::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::INT, "argument_count", PROPERTY_HINT_RANGE, "0,256"));
String argt = "Any";
for (int i = 1; i < Variant::VARIANT_MAX; i++) {
@@ -171,35 +167,30 @@ void VisualScriptFunction::_get_property_list(List<PropertyInfo> *p_list) const
}
int VisualScriptFunction::get_output_sequence_port_count() const {
-
return 1;
}
bool VisualScriptFunction::has_input_sequence_port() const {
-
return false;
}
int VisualScriptFunction::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptFunction::get_output_value_port_count() const {
+int VisualScriptFunction::get_output_value_port_count() const {
return arguments.size();
}
String VisualScriptFunction::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptFunction::get_input_value_port_info(int p_idx) const {
-
ERR_FAIL_V(PropertyInfo());
}
-PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const {
+PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, arguments.size(), PropertyInfo());
PropertyInfo out;
out.type = arguments[p_idx].type;
@@ -210,55 +201,53 @@ PropertyInfo VisualScriptFunction::get_output_value_port_info(int p_idx) const {
}
String VisualScriptFunction::get_caption() const {
-
return "Function";
}
String VisualScriptFunction::get_text() const {
-
return get_name(); //use name as function name I guess
}
void VisualScriptFunction::add_argument(Variant::Type p_type, const String &p_name, int p_index, const PropertyHint p_hint, const String &p_hint_string) {
-
Argument arg;
arg.name = p_name;
arg.type = p_type;
arg.hint = p_hint;
arg.hint_string = p_hint_string;
- if (p_index >= 0)
+ if (p_index >= 0) {
arguments.insert(p_index, arg);
- else
+ } else {
arguments.push_back(arg);
+ }
ports_changed_notify();
}
-void VisualScriptFunction::set_argument_type(int p_argidx, Variant::Type p_type) {
+void VisualScriptFunction::set_argument_type(int p_argidx, Variant::Type p_type) {
ERR_FAIL_INDEX(p_argidx, arguments.size());
arguments.write[p_argidx].type = p_type;
ports_changed_notify();
}
-Variant::Type VisualScriptFunction::get_argument_type(int p_argidx) const {
+Variant::Type VisualScriptFunction::get_argument_type(int p_argidx) const {
ERR_FAIL_INDEX_V(p_argidx, arguments.size(), Variant::NIL);
return arguments[p_argidx].type;
}
-void VisualScriptFunction::set_argument_name(int p_argidx, const String &p_name) {
+void VisualScriptFunction::set_argument_name(int p_argidx, const String &p_name) {
ERR_FAIL_INDEX(p_argidx, arguments.size());
arguments.write[p_argidx].name = p_name;
ports_changed_notify();
}
-String VisualScriptFunction::get_argument_name(int p_argidx) const {
+String VisualScriptFunction::get_argument_name(int p_argidx) const {
ERR_FAIL_INDEX_V(p_argidx, arguments.size(), String());
return arguments[p_argidx].name;
}
-void VisualScriptFunction::remove_argument(int p_argidx) {
+void VisualScriptFunction::remove_argument(int p_argidx) {
ERR_FAIL_INDEX(p_argidx, arguments.size());
arguments.remove(p_argidx);
@@ -266,7 +255,6 @@ void VisualScriptFunction::remove_argument(int p_argidx) {
}
int VisualScriptFunction::get_argument_count() const {
-
return arguments.size();
}
@@ -286,7 +274,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
int ac = node->get_argument_count();
for (int i = 0; i < ac; i++) {
@@ -310,7 +297,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptFunction::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceFunction *instance = memnew(VisualScriptNodeInstanceFunction);
instance->node = this;
instance->instance = p_instance;
@@ -318,7 +304,6 @@ VisualScriptNodeInstance *VisualScriptFunction::instance(VisualScriptInstance *p
}
VisualScriptFunction::VisualScriptFunction() {
-
stack_size = 256;
stack_less = false;
sequenced = true;
@@ -335,23 +320,19 @@ bool VisualScriptFunction::is_stack_less() const {
}
void VisualScriptFunction::set_sequenced(bool p_enable) {
-
sequenced = p_enable;
}
bool VisualScriptFunction::is_sequenced() const {
-
return sequenced;
}
void VisualScriptFunction::set_stack_size(int p_size) {
-
ERR_FAIL_COND(p_size < 1 || p_size > 100000);
stack_size = p_size;
}
int VisualScriptFunction::get_stack_size() const {
-
return stack_size;
}
@@ -360,10 +341,12 @@ int VisualScriptFunction::get_stack_size() const {
//////////////////////////////////////////
int VisualScriptLists::get_output_sequence_port_count() const {
- if (sequenced)
+ if (sequenced) {
return 1;
+ }
return 0;
}
+
bool VisualScriptLists::has_input_sequence_port() const {
return sequenced;
}
@@ -375,6 +358,7 @@ String VisualScriptLists::get_output_sequence_port_text(int p_port) const {
int VisualScriptLists::get_input_value_port_count() const {
return inputports.size();
}
+
int VisualScriptLists::get_output_value_port_count() const {
return outputports.size();
}
@@ -387,6 +371,7 @@ PropertyInfo VisualScriptLists::get_input_value_port_info(int p_idx) const {
pi.type = inputports[p_idx].type;
return pi;
}
+
PropertyInfo VisualScriptLists::get_output_value_port_info(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, outputports.size(), PropertyInfo());
@@ -399,9 +384,11 @@ PropertyInfo VisualScriptLists::get_output_value_port_info(int p_idx) const {
bool VisualScriptLists::is_input_port_editable() const {
return ((flags & INPUT_EDITABLE) == INPUT_EDITABLE);
}
+
bool VisualScriptLists::is_input_port_name_editable() const {
return ((flags & INPUT_NAME_EDITABLE) == INPUT_NAME_EDITABLE);
}
+
bool VisualScriptLists::is_input_port_type_editable() const {
return ((flags & INPUT_TYPE_EDITABLE) == INPUT_TYPE_EDITABLE);
}
@@ -409,22 +396,23 @@ bool VisualScriptLists::is_input_port_type_editable() const {
bool VisualScriptLists::is_output_port_editable() const {
return ((flags & OUTPUT_EDITABLE) == OUTPUT_EDITABLE);
}
+
bool VisualScriptLists::is_output_port_name_editable() const {
return ((flags & INPUT_NAME_EDITABLE) == INPUT_NAME_EDITABLE);
}
+
bool VisualScriptLists::is_output_port_type_editable() const {
return ((flags & INPUT_TYPE_EDITABLE) == INPUT_TYPE_EDITABLE);
}
// for the inspector
bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {
-
if (p_name == "input_count" && is_input_port_editable()) {
-
int new_argc = p_value;
int argc = inputports.size();
- if (argc == new_argc)
+ if (argc == new_argc) {
return true;
+ }
inputports.resize(new_argc);
@@ -441,7 +429,6 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_INDEX_V(idx, inputports.size(), false);
String what = String(p_name).get_slice("/", 1);
if (what == "type") {
-
Variant::Type new_type = Variant::Type(int(p_value));
inputports.write[idx].type = new_type;
ports_changed_notify();
@@ -450,7 +437,6 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {
}
if (what == "name") {
-
inputports.write[idx].name = p_value;
ports_changed_notify();
return true;
@@ -458,11 +444,11 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {
}
if (p_name == "output_count" && is_output_port_editable()) {
-
int new_argc = p_value;
int argc = outputports.size();
- if (argc == new_argc)
+ if (argc == new_argc) {
return true;
+ }
outputports.resize(new_argc);
@@ -479,7 +465,6 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_INDEX_V(idx, outputports.size(), false);
String what = String(p_name).get_slice("/", 1);
if (what == "type") {
-
Variant::Type new_type = Variant::Type(int(p_value));
outputports.write[idx].type = new_type;
ports_changed_notify();
@@ -488,7 +473,6 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {
}
if (what == "name") {
-
outputports.write[idx].name = p_value;
ports_changed_notify();
return true;
@@ -503,8 +487,8 @@ bool VisualScriptLists::_set(const StringName &p_name, const Variant &p_value) {
return false;
}
-bool VisualScriptLists::_get(const StringName &p_name, Variant &r_ret) const {
+bool VisualScriptLists::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name == "input_count" && is_input_port_editable()) {
r_ret = inputports.size();
return true;
@@ -548,8 +532,8 @@ bool VisualScriptLists::_get(const StringName &p_name, Variant &r_ret) const {
return false;
}
-void VisualScriptLists::_get_property_list(List<PropertyInfo> *p_list) const {
+void VisualScriptLists::_get_property_list(List<PropertyInfo> *p_list) const {
if (is_input_port_editable()) {
p_list->push_back(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_RANGE, "0,256"));
String argt = "Any";
@@ -580,25 +564,27 @@ void VisualScriptLists::_get_property_list(List<PropertyInfo> *p_list) const {
// input data port interaction
void VisualScriptLists::add_input_data_port(Variant::Type p_type, const String &p_name, int p_index) {
-
- if (!is_input_port_editable())
+ if (!is_input_port_editable()) {
return;
+ }
Port inp;
inp.name = p_name;
inp.type = p_type;
- if (p_index >= 0)
+ if (p_index >= 0) {
inputports.insert(p_index, inp);
- else
+ } else {
inputports.push_back(inp);
+ }
ports_changed_notify();
_change_notify();
}
-void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type) {
- if (!is_input_port_type_editable())
+void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type) {
+ if (!is_input_port_type_editable()) {
return;
+ }
ERR_FAIL_INDEX(p_idx, inputports.size());
@@ -606,10 +592,11 @@ void VisualScriptLists::set_input_data_port_type(int p_idx, Variant::Type p_type
ports_changed_notify();
_change_notify();
}
-void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name) {
- if (!is_input_port_name_editable())
+void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name) {
+ if (!is_input_port_name_editable()) {
return;
+ }
ERR_FAIL_INDEX(p_idx, inputports.size());
@@ -617,10 +604,11 @@ void VisualScriptLists::set_input_data_port_name(int p_idx, const String &p_name
ports_changed_notify();
_change_notify();
}
-void VisualScriptLists::remove_input_data_port(int p_argidx) {
- if (!is_input_port_editable())
+void VisualScriptLists::remove_input_data_port(int p_argidx) {
+ if (!is_input_port_editable()) {
return;
+ }
ERR_FAIL_INDEX(p_argidx, inputports.size());
@@ -632,25 +620,27 @@ void VisualScriptLists::remove_input_data_port(int p_argidx) {
// output data port interaction
void VisualScriptLists::add_output_data_port(Variant::Type p_type, const String &p_name, int p_index) {
-
- if (!is_output_port_editable())
+ if (!is_output_port_editable()) {
return;
+ }
Port out;
out.name = p_name;
out.type = p_type;
- if (p_index >= 0)
+ if (p_index >= 0) {
outputports.insert(p_index, out);
- else
+ } else {
outputports.push_back(out);
+ }
ports_changed_notify();
_change_notify();
}
-void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_type) {
- if (!is_output_port_type_editable())
+void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_type) {
+ if (!is_output_port_type_editable()) {
return;
+ }
ERR_FAIL_INDEX(p_idx, outputports.size());
@@ -658,10 +648,11 @@ void VisualScriptLists::set_output_data_port_type(int p_idx, Variant::Type p_typ
ports_changed_notify();
_change_notify();
}
-void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_name) {
- if (!is_output_port_name_editable())
+void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_name) {
+ if (!is_output_port_name_editable()) {
return;
+ }
ERR_FAIL_INDEX(p_idx, outputports.size());
@@ -669,10 +660,11 @@ void VisualScriptLists::set_output_data_port_name(int p_idx, const String &p_nam
ports_changed_notify();
_change_notify();
}
-void VisualScriptLists::remove_output_data_port(int p_argidx) {
- if (!is_output_port_editable())
+void VisualScriptLists::remove_output_data_port(int p_argidx) {
+ if (!is_output_port_editable()) {
return;
+ }
ERR_FAIL_INDEX(p_argidx, outputports.size());
@@ -684,11 +676,13 @@ void VisualScriptLists::remove_output_data_port(int p_argidx) {
// sequences
void VisualScriptLists::set_sequenced(bool p_enable) {
- if (sequenced == p_enable)
+ if (sequenced == p_enable) {
return;
+ }
sequenced = p_enable;
ports_changed_notify();
}
+
bool VisualScriptLists::is_sequenced() const {
return sequenced;
}
@@ -716,10 +710,12 @@ void VisualScriptLists::_bind_methods() {
//////////////////////////////////////////
int VisualScriptComposeArray::get_output_sequence_port_count() const {
- if (sequenced)
+ if (sequenced) {
return 1;
+ }
return 0;
}
+
bool VisualScriptComposeArray::has_input_sequence_port() const {
return sequenced;
}
@@ -731,6 +727,7 @@ String VisualScriptComposeArray::get_output_sequence_port_text(int p_port) const
int VisualScriptComposeArray::get_input_value_port_count() const {
return inputports.size();
}
+
int VisualScriptComposeArray::get_output_value_port_count() const {
return 1;
}
@@ -743,6 +740,7 @@ PropertyInfo VisualScriptComposeArray::get_input_value_port_info(int p_idx) cons
pi.type = inputports[p_idx].type;
return pi;
}
+
PropertyInfo VisualScriptComposeArray::get_output_value_port_info(int p_idx) const {
PropertyInfo pi;
pi.name = "out";
@@ -753,6 +751,7 @@ PropertyInfo VisualScriptComposeArray::get_output_value_port_info(int p_idx) con
String VisualScriptComposeArray::get_caption() const {
return "Compose Array";
}
+
String VisualScriptComposeArray::get_text() const {
return "";
}
@@ -763,11 +762,11 @@ public:
virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (input_count > 0) {
Array arr;
- for (int i = 0; i < input_count; i++)
+ for (int i = 0; i < input_count; i++) {
arr.push_back((*p_inputs[i]));
+ }
Variant va = Variant(arr);
*p_outputs[0] = va;
@@ -778,7 +777,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptComposeArray::instance(VisualScriptInstance *p_instance) {
-
VisualScriptComposeArrayNode *instance = memnew(VisualScriptComposeArrayNode);
instance->input_count = inputports.size();
return instance;
@@ -795,31 +793,26 @@ VisualScriptComposeArray::VisualScriptComposeArray() {
//////////////////////////////////////////
int VisualScriptOperator::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptOperator::has_input_sequence_port() const {
-
return false;
}
int VisualScriptOperator::get_input_value_port_count() const {
-
return (op == Variant::OP_BIT_NEGATE || op == Variant::OP_NOT || op == Variant::OP_NEGATE || op == Variant::OP_POSITIVE) ? 1 : 2;
}
-int VisualScriptOperator::get_output_value_port_count() const {
+int VisualScriptOperator::get_output_value_port_count() const {
return 1;
}
String VisualScriptOperator::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptOperator::get_input_value_port_info(int p_idx) const {
-
static const Variant::Type port_types[Variant::OP_MAX][2] = {
{ Variant::NIL, Variant::NIL }, //OP_EQUAL,
{ Variant::NIL, Variant::NIL }, //OP_NOT_EQUAL,
@@ -857,10 +850,12 @@ PropertyInfo VisualScriptOperator::get_input_value_port_info(int p_idx) const {
PropertyInfo pinfo;
pinfo.name = p_idx == 0 ? "A" : "B";
pinfo.type = port_types[op][p_idx];
- if (pinfo.type == Variant::NIL)
+ if (pinfo.type == Variant::NIL) {
pinfo.type = typed;
+ }
return pinfo;
}
+
PropertyInfo VisualScriptOperator::get_output_value_port_info(int p_idx) const {
static const Variant::Type port_types[Variant::OP_MAX] = {
//comparison
@@ -898,8 +893,9 @@ PropertyInfo VisualScriptOperator::get_output_value_port_info(int p_idx) const {
PropertyInfo pinfo;
pinfo.name = "";
pinfo.type = port_types[op];
- if (pinfo.type == Variant::NIL)
+ if (pinfo.type == Variant::NIL) {
pinfo.type = typed;
+ }
return pinfo;
}
@@ -937,7 +933,6 @@ static const char *op_names[] = {
};
String VisualScriptOperator::get_caption() const {
-
static const wchar_t *op_names[] = {
//comparison
L"A = B", //OP_EQUAL,
@@ -974,34 +969,31 @@ String VisualScriptOperator::get_caption() const {
}
void VisualScriptOperator::set_operator(Variant::Operator p_op) {
-
- if (op == p_op)
+ if (op == p_op) {
return;
+ }
op = p_op;
ports_changed_notify();
}
Variant::Operator VisualScriptOperator::get_operator() const {
-
return op;
}
void VisualScriptOperator::set_typed(Variant::Type p_op) {
-
- if (typed == p_op)
+ if (typed == p_op) {
return;
+ }
typed = p_op;
ports_changed_notify();
}
Variant::Type VisualScriptOperator::get_typed() const {
-
return typed;
}
void VisualScriptOperator::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualScriptOperator::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualScriptOperator::get_operator);
@@ -1010,8 +1002,9 @@ void VisualScriptOperator::_bind_methods() {
String types;
for (int i = 0; i < Variant::OP_MAX; i++) {
- if (i > 0)
+ if (i > 0) {
types += ",";
+ }
types += op_names[i];
}
@@ -1032,25 +1025,23 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
bool valid;
if (unary) {
-
Variant::evaluate(op, *p_inputs[0], Variant(), *p_outputs[0], valid);
} else {
Variant::evaluate(op, *p_inputs[0], *p_inputs[1], *p_outputs[0], valid);
}
if (!valid) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
if (p_outputs[0]->get_type() == Variant::STRING) {
r_error_str = *p_outputs[0];
} else {
- if (unary)
+ if (unary) {
r_error_str = String(op_names[op]) + RTR(": Invalid argument of type: ") + Variant::get_type_name(p_inputs[0]->get_type());
- else
+ } else {
r_error_str = String(op_names[op]) + RTR(": Invalid arguments: ") + "A: " + Variant::get_type_name(p_inputs[0]->get_type()) + " B: " + Variant::get_type_name(p_inputs[1]->get_type());
+ }
}
}
@@ -1059,7 +1050,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptOperator::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceOperator *instance = memnew(VisualScriptNodeInstanceOperator);
instance->unary = get_input_value_port_count() == 1;
instance->op = op;
@@ -1067,14 +1057,12 @@ VisualScriptNodeInstance *VisualScriptOperator::instance(VisualScriptInstance *p
}
VisualScriptOperator::VisualScriptOperator() {
-
op = Variant::OP_ADD;
typed = Variant::NIL;
}
template <Variant::Operator OP>
static Ref<VisualScriptNode> create_op_node(const String &p_name) {
-
Ref<VisualScriptOperator> node;
node.instance();
node->set_operator(OP);
@@ -1086,31 +1074,26 @@ static Ref<VisualScriptNode> create_op_node(const String &p_name) {
//////////////////////////////////////////
int VisualScriptSelect::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptSelect::has_input_sequence_port() const {
-
return false;
}
int VisualScriptSelect::get_input_value_port_count() const {
-
return 3;
}
-int VisualScriptSelect::get_output_value_port_count() const {
+int VisualScriptSelect::get_output_value_port_count() const {
return 1;
}
String VisualScriptSelect::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptSelect::get_input_value_port_info(int p_idx) const {
-
if (p_idx == 0) {
return PropertyInfo(Variant::BOOL, "cond");
} else if (p_idx == 1) {
@@ -1119,37 +1102,33 @@ PropertyInfo VisualScriptSelect::get_input_value_port_info(int p_idx) const {
return PropertyInfo(typed, "b");
}
}
-PropertyInfo VisualScriptSelect::get_output_value_port_info(int p_idx) const {
+PropertyInfo VisualScriptSelect::get_output_value_port_info(int p_idx) const {
return PropertyInfo(typed, "out");
}
String VisualScriptSelect::get_caption() const {
-
return "Select";
}
String VisualScriptSelect::get_text() const {
-
return "a if cond, else b";
}
void VisualScriptSelect::set_typed(Variant::Type p_op) {
-
- if (typed == p_op)
+ if (typed == p_op) {
return;
+ }
typed = p_op;
ports_changed_notify();
}
Variant::Type VisualScriptSelect::get_typed() const {
-
return typed;
}
void VisualScriptSelect::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_typed", "type"), &VisualScriptSelect::set_typed);
ClassDB::bind_method(D_METHOD("get_typed"), &VisualScriptSelect::get_typed);
@@ -1166,25 +1145,23 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
bool cond = *p_inputs[0];
- if (cond)
+ if (cond) {
*p_outputs[0] = *p_inputs[1];
- else
+ } else {
*p_outputs[0] = *p_inputs[2];
+ }
return 0;
}
};
VisualScriptNodeInstance *VisualScriptSelect::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceSelect *instance = memnew(VisualScriptNodeInstanceSelect);
return instance;
}
VisualScriptSelect::VisualScriptSelect() {
-
typed = Variant::NIL;
}
@@ -1193,36 +1170,30 @@ VisualScriptSelect::VisualScriptSelect() {
//////////////////////////////////////////
int VisualScriptVariableGet::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptVariableGet::has_input_sequence_port() const {
-
return false;
}
int VisualScriptVariableGet::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptVariableGet::get_output_value_port_count() const {
+int VisualScriptVariableGet::get_output_value_port_count() const {
return 1;
}
String VisualScriptVariableGet::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptVariableGet::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptVariableGet::get_output_value_port_info(int p_idx) const {
-
PropertyInfo pinfo;
pinfo.name = "value";
if (get_visual_script().is_valid() && get_visual_script()->has_variable(variable)) {
@@ -1235,24 +1206,22 @@ PropertyInfo VisualScriptVariableGet::get_output_value_port_info(int p_idx) cons
}
String VisualScriptVariableGet::get_caption() const {
-
return "Get " + variable;
}
-void VisualScriptVariableGet::set_variable(StringName p_variable) {
- if (variable == p_variable)
+void VisualScriptVariableGet::set_variable(StringName p_variable) {
+ if (variable == p_variable) {
return;
+ }
variable = p_variable;
ports_changed_notify();
}
StringName VisualScriptVariableGet::get_variable() const {
-
return variable;
}
void VisualScriptVariableGet::_validate_property(PropertyInfo &property) const {
-
if (property.name == "var_name" && get_visual_script().is_valid()) {
Ref<VisualScript> vs = get_visual_script();
List<StringName> vars;
@@ -1260,8 +1229,9 @@ void VisualScriptVariableGet::_validate_property(PropertyInfo &property) const {
String vhint;
for (List<StringName>::Element *E = vars.front(); E; E = E->next()) {
- if (vhint != String())
+ if (vhint != String()) {
vhint += ",";
+ }
vhint += E->get().operator String();
}
@@ -1272,7 +1242,6 @@ void VisualScriptVariableGet::_validate_property(PropertyInfo &property) const {
}
void VisualScriptVariableGet::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_variable", "name"), &VisualScriptVariableGet::set_variable);
ClassDB::bind_method(D_METHOD("get_variable"), &VisualScriptVariableGet::get_variable);
@@ -1286,7 +1255,6 @@ public:
StringName variable;
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (!instance->get_variable(variable, p_outputs[0])) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("VariableGet not found in script: ") + "'" + String(variable) + "'";
@@ -1297,13 +1265,13 @@ public:
};
VisualScriptNodeInstance *VisualScriptVariableGet::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceVariableGet *instance = memnew(VisualScriptNodeInstanceVariableGet);
instance->node = this;
instance->instance = p_instance;
instance->variable = variable;
return instance;
}
+
VisualScriptVariableGet::VisualScriptVariableGet() {
}
@@ -1312,31 +1280,26 @@ VisualScriptVariableGet::VisualScriptVariableGet() {
//////////////////////////////////////////
int VisualScriptVariableSet::get_output_sequence_port_count() const {
-
return 1;
}
bool VisualScriptVariableSet::has_input_sequence_port() const {
-
return true;
}
int VisualScriptVariableSet::get_input_value_port_count() const {
-
return 1;
}
-int VisualScriptVariableSet::get_output_value_port_count() const {
+int VisualScriptVariableSet::get_output_value_port_count() const {
return 0;
}
String VisualScriptVariableSet::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptVariableSet::get_input_value_port_info(int p_idx) const {
-
PropertyInfo pinfo;
pinfo.name = "set";
if (get_visual_script().is_valid() && get_visual_script()->has_variable(variable)) {
@@ -1349,30 +1312,26 @@ PropertyInfo VisualScriptVariableSet::get_input_value_port_info(int p_idx) const
}
PropertyInfo VisualScriptVariableSet::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
String VisualScriptVariableSet::get_caption() const {
-
return "Set " + variable;
}
void VisualScriptVariableSet::set_variable(StringName p_variable) {
-
- if (variable == p_variable)
+ if (variable == p_variable) {
return;
+ }
variable = p_variable;
ports_changed_notify();
}
StringName VisualScriptVariableSet::get_variable() const {
-
return variable;
}
void VisualScriptVariableSet::_validate_property(PropertyInfo &property) const {
-
if (property.name == "var_name" && get_visual_script().is_valid()) {
Ref<VisualScript> vs = get_visual_script();
List<StringName> vars;
@@ -1380,8 +1339,9 @@ void VisualScriptVariableSet::_validate_property(PropertyInfo &property) const {
String vhint;
for (List<StringName>::Element *E = vars.front(); E; E = E->next()) {
- if (vhint != String())
+ if (vhint != String()) {
vhint += ",";
+ }
vhint += E->get().operator String();
}
@@ -1392,7 +1352,6 @@ void VisualScriptVariableSet::_validate_property(PropertyInfo &property) const {
}
void VisualScriptVariableSet::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_variable", "name"), &VisualScriptVariableSet::set_variable);
ClassDB::bind_method(D_METHOD("get_variable"), &VisualScriptVariableSet::get_variable);
@@ -1408,9 +1367,7 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (!instance->set_variable(variable, *p_inputs[0])) {
-
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
r_error_str = RTR("VariableSet not found in script: ") + "'" + String(variable) + "'";
}
@@ -1420,13 +1377,13 @@ public:
};
VisualScriptNodeInstance *VisualScriptVariableSet::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceVariableSet *instance = memnew(VisualScriptNodeInstanceVariableSet);
instance->node = this;
instance->instance = p_instance;
instance->variable = variable;
return instance;
}
+
VisualScriptVariableSet::VisualScriptVariableSet() {
}
@@ -1435,36 +1392,30 @@ VisualScriptVariableSet::VisualScriptVariableSet() {
//////////////////////////////////////////
int VisualScriptConstant::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptConstant::has_input_sequence_port() const {
-
return false;
}
int VisualScriptConstant::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptConstant::get_output_value_port_count() const {
+int VisualScriptConstant::get_output_value_port_count() const {
return 1;
}
String VisualScriptConstant::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptConstant::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptConstant::get_output_value_port_info(int p_idx) const {
-
PropertyInfo pinfo;
pinfo.name = String(value);
pinfo.type = type;
@@ -1472,14 +1423,13 @@ PropertyInfo VisualScriptConstant::get_output_value_port_info(int p_idx) const {
}
String VisualScriptConstant::get_caption() const {
-
return "Constant";
}
void VisualScriptConstant::set_constant_type(Variant::Type p_type) {
-
- if (type == p_type)
+ if (type == p_type) {
return;
+ }
type = p_type;
Callable::CallError ce;
@@ -1489,34 +1439,32 @@ void VisualScriptConstant::set_constant_type(Variant::Type p_type) {
}
Variant::Type VisualScriptConstant::get_constant_type() const {
-
return type;
}
void VisualScriptConstant::set_constant_value(Variant p_value) {
-
- if (value == p_value)
+ if (value == p_value) {
return;
+ }
value = p_value;
ports_changed_notify();
}
-Variant VisualScriptConstant::get_constant_value() const {
+Variant VisualScriptConstant::get_constant_value() const {
return value;
}
void VisualScriptConstant::_validate_property(PropertyInfo &property) const {
-
if (property.name == "value") {
property.type = type;
- if (type == Variant::NIL)
+ if (type == Variant::NIL) {
property.usage = 0; //do not save if nil
+ }
}
}
void VisualScriptConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant_type", "type"), &VisualScriptConstant::set_constant_type);
ClassDB::bind_method(D_METHOD("get_constant_type"), &VisualScriptConstant::get_constant_type);
@@ -1538,21 +1486,18 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
*p_outputs[0] = constant;
return 0;
}
};
VisualScriptNodeInstance *VisualScriptConstant::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceConstant *instance = memnew(VisualScriptNodeInstanceConstant);
instance->constant = value;
return instance;
}
VisualScriptConstant::VisualScriptConstant() {
-
type = Variant::NIL;
}
@@ -1561,36 +1506,30 @@ VisualScriptConstant::VisualScriptConstant() {
//////////////////////////////////////////
int VisualScriptPreload::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptPreload::has_input_sequence_port() const {
-
return false;
}
int VisualScriptPreload::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptPreload::get_output_value_port_count() const {
+int VisualScriptPreload::get_output_value_port_count() const {
return 1;
}
String VisualScriptPreload::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptPreload::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptPreload::get_output_value_port_info(int p_idx) const {
-
PropertyInfo pinfo;
pinfo.type = Variant::OBJECT;
if (preload.is_valid()) {
@@ -1611,26 +1550,23 @@ PropertyInfo VisualScriptPreload::get_output_value_port_info(int p_idx) const {
}
String VisualScriptPreload::get_caption() const {
-
return "Preload";
}
void VisualScriptPreload::set_preload(const Ref<Resource> &p_preload) {
-
- if (preload == p_preload)
+ if (preload == p_preload) {
return;
+ }
preload = p_preload;
ports_changed_notify();
}
Ref<Resource> VisualScriptPreload::get_preload() const {
-
return preload;
}
void VisualScriptPreload::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_preload", "resource"), &VisualScriptPreload::set_preload);
ClassDB::bind_method(D_METHOD("get_preload"), &VisualScriptPreload::get_preload);
@@ -1643,14 +1579,12 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
*p_outputs[0] = preload;
return 0;
}
};
VisualScriptNodeInstance *VisualScriptPreload::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstancePreload *instance = memnew(VisualScriptNodeInstancePreload);
instance->preload = preload;
return instance;
@@ -1664,31 +1598,26 @@ VisualScriptPreload::VisualScriptPreload() {
//////////////////////////////////////////
int VisualScriptIndexGet::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptIndexGet::has_input_sequence_port() const {
-
return false;
}
int VisualScriptIndexGet::get_input_value_port_count() const {
-
return 2;
}
-int VisualScriptIndexGet::get_output_value_port_count() const {
+int VisualScriptIndexGet::get_output_value_port_count() const {
return 1;
}
String VisualScriptIndexGet::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptIndexGet::get_input_value_port_info(int p_idx) const {
-
if (p_idx == 0) {
return PropertyInfo(Variant::NIL, "base");
} else {
@@ -1697,12 +1626,10 @@ PropertyInfo VisualScriptIndexGet::get_input_value_port_info(int p_idx) const {
}
PropertyInfo VisualScriptIndexGet::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
String VisualScriptIndexGet::get_caption() const {
-
return "Get Index";
}
@@ -1711,7 +1638,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
bool valid;
*p_outputs[0] = p_inputs[0]->get(*p_inputs[1], &valid);
@@ -1724,10 +1650,10 @@ public:
};
VisualScriptNodeInstance *VisualScriptIndexGet::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceIndexGet *instance = memnew(VisualScriptNodeInstanceIndexGet);
return instance;
}
+
VisualScriptIndexGet::VisualScriptIndexGet() {
}
@@ -1736,31 +1662,26 @@ VisualScriptIndexGet::VisualScriptIndexGet() {
//////////////////////////////////////////
int VisualScriptIndexSet::get_output_sequence_port_count() const {
-
return 1;
}
bool VisualScriptIndexSet::has_input_sequence_port() const {
-
return true;
}
int VisualScriptIndexSet::get_input_value_port_count() const {
-
return 3;
}
-int VisualScriptIndexSet::get_output_value_port_count() const {
+int VisualScriptIndexSet::get_output_value_port_count() const {
return 0;
}
String VisualScriptIndexSet::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptIndexSet::get_input_value_port_info(int p_idx) const {
-
if (p_idx == 0) {
return PropertyInfo(Variant::NIL, "base");
} else if (p_idx == 1) {
@@ -1772,12 +1693,10 @@ PropertyInfo VisualScriptIndexSet::get_input_value_port_info(int p_idx) const {
}
PropertyInfo VisualScriptIndexSet::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
String VisualScriptIndexSet::get_caption() const {
-
return "Set Index";
}
@@ -1786,7 +1705,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
bool valid;
*p_outputs[0] = *p_inputs[0];
p_outputs[0]->set(*p_inputs[1], *p_inputs[2], &valid);
@@ -1800,10 +1718,10 @@ public:
};
VisualScriptNodeInstance *VisualScriptIndexSet::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceIndexSet *instance = memnew(VisualScriptNodeInstanceIndexSet);
return instance;
}
+
VisualScriptIndexSet::VisualScriptIndexSet() {
}
@@ -1812,31 +1730,26 @@ VisualScriptIndexSet::VisualScriptIndexSet() {
//////////////////////////////////////////
int VisualScriptGlobalConstant::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptGlobalConstant::has_input_sequence_port() const {
-
return false;
}
int VisualScriptGlobalConstant::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptGlobalConstant::get_output_value_port_count() const {
+int VisualScriptGlobalConstant::get_output_value_port_count() const {
return 1;
}
String VisualScriptGlobalConstant::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptGlobalConstant::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
@@ -1846,12 +1759,10 @@ PropertyInfo VisualScriptGlobalConstant::get_output_value_port_info(int p_idx) c
}
String VisualScriptGlobalConstant::get_caption() const {
-
return "Global Constant";
}
void VisualScriptGlobalConstant::set_global_constant(int p_which) {
-
index = p_which;
_change_notify();
ports_changed_notify();
@@ -1867,37 +1778,33 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
*p_outputs[0] = GlobalConstants::get_global_constant_value(index);
return 0;
}
};
VisualScriptNodeInstance *VisualScriptGlobalConstant::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceGlobalConstant *instance = memnew(VisualScriptNodeInstanceGlobalConstant);
instance->index = index;
return instance;
}
void VisualScriptGlobalConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_global_constant", "index"), &VisualScriptGlobalConstant::set_global_constant);
ClassDB::bind_method(D_METHOD("get_global_constant"), &VisualScriptGlobalConstant::get_global_constant);
String cc;
for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) {
-
- if (i > 0)
+ if (i > 0) {
cc += ",";
+ }
cc += GlobalConstants::get_global_constant_name(i);
}
ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_global_constant", "get_global_constant");
}
VisualScriptGlobalConstant::VisualScriptGlobalConstant() {
-
index = 0;
}
@@ -1906,31 +1813,26 @@ VisualScriptGlobalConstant::VisualScriptGlobalConstant() {
//////////////////////////////////////////
int VisualScriptClassConstant::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptClassConstant::has_input_sequence_port() const {
-
return false;
}
int VisualScriptClassConstant::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptClassConstant::get_output_value_port_count() const {
+int VisualScriptClassConstant::get_output_value_port_count() const {
return 1;
}
String VisualScriptClassConstant::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptClassConstant::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
@@ -1943,12 +1845,10 @@ PropertyInfo VisualScriptClassConstant::get_output_value_port_info(int p_idx) co
}
String VisualScriptClassConstant::get_caption() const {
-
return "Class Constant";
}
void VisualScriptClassConstant::set_class_constant(const StringName &p_which) {
-
name = p_which;
_change_notify();
ports_changed_notify();
@@ -1959,7 +1859,6 @@ StringName VisualScriptClassConstant::get_class_constant() {
}
void VisualScriptClassConstant::set_base_type(const StringName &p_which) {
-
base_type = p_which;
List<String> constants;
ClassDB::get_integer_constant_list(base_type, &constants, true);
@@ -1992,7 +1891,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (!valid) {
r_error_str = "Invalid constant name, pick a valid class constant.";
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -2004,16 +1902,13 @@ public:
};
VisualScriptNodeInstance *VisualScriptClassConstant::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceClassConstant *instance = memnew(VisualScriptNodeInstanceClassConstant);
instance->value = ClassDB::get_integer_constant(base_type, name, &instance->valid);
return instance;
}
void VisualScriptClassConstant::_validate_property(PropertyInfo &property) const {
-
if (property.name == "constant") {
-
List<String> constants;
ClassDB::get_integer_constant_list(base_type, &constants, true);
@@ -2028,7 +1923,6 @@ void VisualScriptClassConstant::_validate_property(PropertyInfo &property) const
}
void VisualScriptClassConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_class_constant", "name"), &VisualScriptClassConstant::set_class_constant);
ClassDB::bind_method(D_METHOD("get_class_constant"), &VisualScriptClassConstant::get_class_constant);
@@ -2040,7 +1934,6 @@ void VisualScriptClassConstant::_bind_methods() {
}
VisualScriptClassConstant::VisualScriptClassConstant() {
-
base_type = "Object";
}
@@ -2049,41 +1942,34 @@ VisualScriptClassConstant::VisualScriptClassConstant() {
//////////////////////////////////////////
int VisualScriptBasicTypeConstant::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptBasicTypeConstant::has_input_sequence_port() const {
-
return false;
}
int VisualScriptBasicTypeConstant::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptBasicTypeConstant::get_output_value_port_count() const {
+int VisualScriptBasicTypeConstant::get_output_value_port_count() const {
return 1;
}
String VisualScriptBasicTypeConstant::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptBasicTypeConstant::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptBasicTypeConstant::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo(type, "value");
}
String VisualScriptBasicTypeConstant::get_caption() const {
-
return "Basic Constant";
}
@@ -2096,7 +1982,6 @@ String VisualScriptBasicTypeConstant::get_text() const {
}
void VisualScriptBasicTypeConstant::set_basic_type_constant(const StringName &p_which) {
-
name = p_which;
_change_notify();
ports_changed_notify();
@@ -2107,7 +1992,6 @@ StringName VisualScriptBasicTypeConstant::get_basic_type_constant() const {
}
void VisualScriptBasicTypeConstant::set_basic_type(Variant::Type p_which) {
-
type = p_which;
List<StringName> constants;
@@ -2141,7 +2025,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (!valid) {
r_error_str = "Invalid constant name, pick a valid basic type constant.";
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -2153,16 +2036,13 @@ public:
};
VisualScriptNodeInstance *VisualScriptBasicTypeConstant::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceBasicTypeConstant *instance = memnew(VisualScriptNodeInstanceBasicTypeConstant);
instance->value = Variant::get_constant_value(type, name, &instance->valid);
return instance;
}
void VisualScriptBasicTypeConstant::_validate_property(PropertyInfo &property) const {
-
if (property.name == "constant") {
-
List<StringName> constants;
Variant::get_constants_for_type(type, &constants);
@@ -2181,7 +2061,6 @@ void VisualScriptBasicTypeConstant::_validate_property(PropertyInfo &property) c
}
void VisualScriptBasicTypeConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_basic_type", "name"), &VisualScriptBasicTypeConstant::set_basic_type);
ClassDB::bind_method(D_METHOD("get_basic_type"), &VisualScriptBasicTypeConstant::get_basic_type);
@@ -2198,7 +2077,6 @@ void VisualScriptBasicTypeConstant::_bind_methods() {
}
VisualScriptBasicTypeConstant::VisualScriptBasicTypeConstant() {
-
type = Variant::NIL;
}
@@ -2229,46 +2107,38 @@ double VisualScriptMathConstant::const_value[MATH_CONSTANT_MAX] = {
};
int VisualScriptMathConstant::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptMathConstant::has_input_sequence_port() const {
-
return false;
}
int VisualScriptMathConstant::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptMathConstant::get_output_value_port_count() const {
+int VisualScriptMathConstant::get_output_value_port_count() const {
return 1;
}
String VisualScriptMathConstant::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptMathConstant::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptMathConstant::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo(Variant::FLOAT, const_name[constant]);
}
String VisualScriptMathConstant::get_caption() const {
-
return "Math Constant";
}
void VisualScriptMathConstant::set_math_constant(MathConstant p_which) {
-
constant = p_which;
_change_notify();
ports_changed_notify();
@@ -2284,30 +2154,27 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
*p_outputs[0] = value;
return 0;
}
};
VisualScriptNodeInstance *VisualScriptMathConstant::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceMathConstant *instance = memnew(VisualScriptNodeInstanceMathConstant);
instance->value = const_value[constant];
return instance;
}
void VisualScriptMathConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_math_constant", "which"), &VisualScriptMathConstant::set_math_constant);
ClassDB::bind_method(D_METHOD("get_math_constant"), &VisualScriptMathConstant::get_math_constant);
String cc;
for (int i = 0; i < MATH_CONSTANT_MAX; i++) {
-
- if (i > 0)
+ if (i > 0) {
cc += ",";
+ }
cc += const_name[i];
}
ADD_PROPERTY(PropertyInfo(Variant::INT, "constant", PROPERTY_HINT_ENUM, cc), "set_math_constant", "get_math_constant");
@@ -2324,7 +2191,6 @@ void VisualScriptMathConstant::_bind_methods() {
}
VisualScriptMathConstant::VisualScriptMathConstant() {
-
constant = MATH_CONSTANT_ONE;
}
@@ -2333,46 +2199,38 @@ VisualScriptMathConstant::VisualScriptMathConstant() {
//////////////////////////////////////////
int VisualScriptEngineSingleton::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptEngineSingleton::has_input_sequence_port() const {
-
return false;
}
int VisualScriptEngineSingleton::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptEngineSingleton::get_output_value_port_count() const {
+int VisualScriptEngineSingleton::get_output_value_port_count() const {
return 1;
}
String VisualScriptEngineSingleton::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptEngineSingleton::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptEngineSingleton::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo(Variant::OBJECT, singleton);
}
String VisualScriptEngineSingleton::get_caption() const {
-
return "Get Engine Singleton";
}
void VisualScriptEngineSingleton::set_singleton(const String &p_string) {
-
singleton = p_string;
_change_notify();
@@ -2390,21 +2248,18 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
*p_outputs[0] = singleton;
return 0;
}
};
VisualScriptNodeInstance *VisualScriptEngineSingleton::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceEngineSingleton *instance = memnew(VisualScriptNodeInstanceEngineSingleton);
instance->singleton = Engine::get_singleton()->get_singleton_object(singleton);
return instance;
}
VisualScriptEngineSingleton::TypeGuess VisualScriptEngineSingleton::guess_output_type(TypeGuess *p_inputs, int p_output) const {
-
Object *obj = Engine::get_singleton()->get_singleton_object(singleton);
TypeGuess tg;
tg.type = Variant::OBJECT;
@@ -2417,7 +2272,6 @@ VisualScriptEngineSingleton::TypeGuess VisualScriptEngineSingleton::guess_output
}
void VisualScriptEngineSingleton::_validate_property(PropertyInfo &property) const {
-
String cc;
List<Engine::Singleton> singletons;
@@ -2425,11 +2279,13 @@ void VisualScriptEngineSingleton::_validate_property(PropertyInfo &property) con
Engine::get_singleton()->get_singletons(&singletons);
for (List<Engine::Singleton>::Element *E = singletons.front(); E; E = E->next()) {
- if (E->get().name == "VS" || E->get().name == "PS" || E->get().name == "PS2D" || E->get().name == "AS" || E->get().name == "TS" || E->get().name == "SS" || E->get().name == "SS2D")
+ if (E->get().name == "VS" || E->get().name == "PS" || E->get().name == "PS2D" || E->get().name == "AS" || E->get().name == "TS" || E->get().name == "SS" || E->get().name == "SS2D") {
continue; //skip these, too simple named
+ }
- if (cc != String())
+ if (cc != String()) {
cc += ",";
+ }
cc += E->get().name;
}
@@ -2438,7 +2294,6 @@ void VisualScriptEngineSingleton::_validate_property(PropertyInfo &property) con
}
void VisualScriptEngineSingleton::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_singleton", "name"), &VisualScriptEngineSingleton::set_singleton);
ClassDB::bind_method(D_METHOD("get_singleton"), &VisualScriptEngineSingleton::get_singleton);
@@ -2446,7 +2301,6 @@ void VisualScriptEngineSingleton::_bind_methods() {
}
VisualScriptEngineSingleton::VisualScriptEngineSingleton() {
-
singleton = String();
}
@@ -2455,46 +2309,38 @@ VisualScriptEngineSingleton::VisualScriptEngineSingleton() {
//////////////////////////////////////////
int VisualScriptSceneNode::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptSceneNode::has_input_sequence_port() const {
-
return false;
}
int VisualScriptSceneNode::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptSceneNode::get_output_value_port_count() const {
+int VisualScriptSceneNode::get_output_value_port_count() const {
return 1;
}
String VisualScriptSceneNode::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptSceneNode::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptSceneNode::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo(Variant::OBJECT, path.simplified());
}
String VisualScriptSceneNode::get_caption() const {
-
return "Get Scene Node";
}
void VisualScriptSceneNode::set_node_path(const NodePath &p_path) {
-
path = p_path;
_change_notify();
ports_changed_notify();
@@ -2513,7 +2359,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -2535,7 +2380,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptSceneNode::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceSceneNode *instance = memnew(VisualScriptNodeInstanceSceneNode);
instance->node = this;
instance->instance = p_instance;
@@ -2546,19 +2390,21 @@ VisualScriptNodeInstance *VisualScriptSceneNode::instance(VisualScriptInstance *
#ifdef TOOLS_ENABLED
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
-
- if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
+ if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) {
return nullptr;
+ }
Ref<Script> scr = p_current_node->get_script();
- if (scr.is_valid() && scr == script)
+ if (scr.is_valid() && scr == script) {
return p_current_node;
+ }
for (int i = 0; i < p_current_node->get_child_count(); i++) {
Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);
- if (n)
+ if (n) {
return n;
+ }
}
return nullptr;
@@ -2567,31 +2413,34 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const
#endif
VisualScriptSceneNode::TypeGuess VisualScriptSceneNode::guess_output_type(TypeGuess *p_inputs, int p_output) const {
-
VisualScriptSceneNode::TypeGuess tg;
tg.type = Variant::OBJECT;
tg.gdclass = "Node";
#ifdef TOOLS_ENABLED
Ref<Script> script = get_visual_script();
- if (!script.is_valid())
+ if (!script.is_valid()) {
return tg;
+ }
MainLoop *main_loop = OS::get_singleton()->get_main_loop();
SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
- if (!scene_tree)
+ if (!scene_tree) {
return tg;
+ }
Node *edited_scene = scene_tree->get_edited_scene_root();
- if (!edited_scene)
+ if (!edited_scene) {
return tg;
+ }
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
- if (!script_node)
+ if (!script_node) {
return tg;
+ }
Node *another = script_node->get_node(path);
@@ -2604,29 +2453,31 @@ VisualScriptSceneNode::TypeGuess VisualScriptSceneNode::guess_output_type(TypeGu
}
void VisualScriptSceneNode::_validate_property(PropertyInfo &property) const {
-
#ifdef TOOLS_ENABLED
if (property.name == "node_path") {
-
Ref<Script> script = get_visual_script();
- if (!script.is_valid())
+ if (!script.is_valid()) {
return;
+ }
MainLoop *main_loop = OS::get_singleton()->get_main_loop();
SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
- if (!scene_tree)
+ if (!scene_tree) {
return;
+ }
Node *edited_scene = scene_tree->get_edited_scene_root();
- if (!edited_scene)
+ if (!edited_scene) {
return;
+ }
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
- if (!script_node)
+ if (!script_node) {
return;
+ }
property.hint_string = script_node->get_path();
}
@@ -2634,7 +2485,6 @@ void VisualScriptSceneNode::_validate_property(PropertyInfo &property) const {
}
void VisualScriptSceneNode::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_node_path", "path"), &VisualScriptSceneNode::set_node_path);
ClassDB::bind_method(D_METHOD("get_node_path"), &VisualScriptSceneNode::get_node_path);
@@ -2642,7 +2492,6 @@ void VisualScriptSceneNode::_bind_methods() {
}
VisualScriptSceneNode::VisualScriptSceneNode() {
-
path = String(".");
}
@@ -2651,41 +2500,34 @@ VisualScriptSceneNode::VisualScriptSceneNode() {
//////////////////////////////////////////
int VisualScriptSceneTree::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptSceneTree::has_input_sequence_port() const {
-
return false;
}
int VisualScriptSceneTree::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptSceneTree::get_output_value_port_count() const {
+int VisualScriptSceneTree::get_output_value_port_count() const {
return 1;
}
String VisualScriptSceneTree::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptSceneTree::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptSceneTree::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo(Variant::OBJECT, "Scene Tree", PROPERTY_HINT_TYPE_STRING, "SceneTree");
}
String VisualScriptSceneTree::get_caption() const {
-
return "Get Scene Tree";
}
@@ -2697,7 +2539,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -2719,7 +2560,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptSceneTree::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceSceneTree *instance = memnew(VisualScriptNodeInstanceSceneTree);
instance->node = this;
instance->instance = p_instance;
@@ -2727,7 +2567,6 @@ VisualScriptNodeInstance *VisualScriptSceneTree::instance(VisualScriptInstance *
}
VisualScriptSceneTree::TypeGuess VisualScriptSceneTree::guess_output_type(TypeGuess *p_inputs, int p_output) const {
-
TypeGuess tg;
tg.type = Variant::OBJECT;
tg.gdclass = "SceneTree";
@@ -2748,46 +2587,38 @@ VisualScriptSceneTree::VisualScriptSceneTree() {
//////////////////////////////////////////
int VisualScriptResourcePath::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptResourcePath::has_input_sequence_port() const {
-
return false;
}
int VisualScriptResourcePath::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptResourcePath::get_output_value_port_count() const {
+int VisualScriptResourcePath::get_output_value_port_count() const {
return 1;
}
String VisualScriptResourcePath::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptResourcePath::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptResourcePath::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo(Variant::STRING, path);
}
String VisualScriptResourcePath::get_caption() const {
-
return "Resource Path";
}
void VisualScriptResourcePath::set_resource_path(const String &p_path) {
-
path = p_path;
_change_notify();
ports_changed_notify();
@@ -2804,21 +2635,18 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
*p_outputs[0] = path;
return 0;
}
};
VisualScriptNodeInstance *VisualScriptResourcePath::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceResourcePath *instance = memnew(VisualScriptNodeInstanceResourcePath);
instance->path = path;
return instance;
}
void VisualScriptResourcePath::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_resource_path", "path"), &VisualScriptResourcePath::set_resource_path);
ClassDB::bind_method(D_METHOD("get_resource_path"), &VisualScriptResourcePath::get_resource_path);
@@ -2826,7 +2654,6 @@ void VisualScriptResourcePath::_bind_methods() {
}
VisualScriptResourcePath::VisualScriptResourcePath() {
-
path = "";
}
@@ -2835,47 +2662,41 @@ VisualScriptResourcePath::VisualScriptResourcePath() {
//////////////////////////////////////////
int VisualScriptSelf::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptSelf::has_input_sequence_port() const {
-
return false;
}
int VisualScriptSelf::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptSelf::get_output_value_port_count() const {
+int VisualScriptSelf::get_output_value_port_count() const {
return 1;
}
String VisualScriptSelf::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptSelf::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptSelf::get_output_value_port_info(int p_idx) const {
-
String type_name;
- if (get_visual_script().is_valid())
+ if (get_visual_script().is_valid()) {
type_name = get_visual_script()->get_instance_base_type();
- else
+ } else {
type_name = "instance";
+ }
return PropertyInfo(Variant::OBJECT, type_name);
}
String VisualScriptSelf::get_caption() const {
-
return "Get Self";
}
@@ -2886,28 +2707,26 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
*p_outputs[0] = instance->get_owner_ptr();
return 0;
}
};
VisualScriptNodeInstance *VisualScriptSelf::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceSelf *instance = memnew(VisualScriptNodeInstanceSelf);
instance->instance = p_instance;
return instance;
}
VisualScriptSelf::TypeGuess VisualScriptSelf::guess_output_type(TypeGuess *p_inputs, int p_output) const {
-
VisualScriptSceneNode::TypeGuess tg;
tg.type = Variant::OBJECT;
tg.gdclass = "Object";
Ref<Script> script = get_visual_script();
- if (!script.is_valid())
+ if (!script.is_valid()) {
return tg;
+ }
tg.gdclass = script->get_instance_base_type();
tg.script = script;
@@ -2926,7 +2745,6 @@ VisualScriptSelf::VisualScriptSelf() {
//////////////////////////////////////////
int VisualScriptCustomNode::get_output_sequence_port_count() const {
-
if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_count")) {
return get_script_instance()->call("_get_output_sequence_port_count");
}
@@ -2934,7 +2752,6 @@ int VisualScriptCustomNode::get_output_sequence_port_count() const {
}
bool VisualScriptCustomNode::has_input_sequence_port() const {
-
if (get_script_instance() && get_script_instance()->has_method("_has_input_sequence_port")) {
return get_script_instance()->call("_has_input_sequence_port");
}
@@ -2942,14 +2759,13 @@ bool VisualScriptCustomNode::has_input_sequence_port() const {
}
int VisualScriptCustomNode::get_input_value_port_count() const {
-
if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_count")) {
return get_script_instance()->call("_get_input_value_port_count");
}
return 0;
}
-int VisualScriptCustomNode::get_output_value_port_count() const {
+int VisualScriptCustomNode::get_output_value_port_count() const {
if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_count")) {
return get_script_instance()->call("_get_output_value_port_count");
}
@@ -2957,7 +2773,6 @@ int VisualScriptCustomNode::get_output_value_port_count() const {
}
String VisualScriptCustomNode::get_output_sequence_port_text(int p_port) const {
-
if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_text")) {
return get_script_instance()->call("_get_output_sequence_port_text", p_port);
}
@@ -2966,7 +2781,6 @@ String VisualScriptCustomNode::get_output_sequence_port_text(int p_port) const {
}
PropertyInfo VisualScriptCustomNode::get_input_value_port_info(int p_idx) const {
-
PropertyInfo info;
if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_type")) {
info.type = Variant::Type(int(get_script_instance()->call("_get_input_value_port_type", p_idx)));
@@ -2978,7 +2792,6 @@ PropertyInfo VisualScriptCustomNode::get_input_value_port_info(int p_idx) const
}
PropertyInfo VisualScriptCustomNode::get_output_value_port_info(int p_idx) const {
-
PropertyInfo info;
if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_type")) {
info.type = Variant::Type(int(get_script_instance()->call("_get_output_value_port_type", p_idx)));
@@ -2990,7 +2803,6 @@ PropertyInfo VisualScriptCustomNode::get_output_value_port_info(int p_idx) const
}
String VisualScriptCustomNode::get_caption() const {
-
if (get_script_instance() && get_script_instance()->has_method("_get_caption")) {
return get_script_instance()->call("_get_caption");
}
@@ -2998,7 +2810,6 @@ String VisualScriptCustomNode::get_caption() const {
}
String VisualScriptCustomNode::get_text() const {
-
if (get_script_instance() && get_script_instance()->has_method("_get_text")) {
return get_script_instance()->call("_get_text");
}
@@ -3006,7 +2817,6 @@ String VisualScriptCustomNode::get_text() const {
}
String VisualScriptCustomNode::get_category() const {
-
if (get_script_instance() && get_script_instance()->has_method("_get_category")) {
return get_script_instance()->call("_get_category");
}
@@ -3023,7 +2833,6 @@ public:
virtual int get_working_memory_size() const { return work_mem_size; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (node->get_script_instance()) {
#ifdef DEBUG_ENABLED
if (!node->get_script_instance()->has_method(VisualScriptLanguage::singleton->_step)) {
@@ -3085,7 +2894,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptCustomNode::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceCustomNode *instance = memnew(VisualScriptNodeInstanceCustomNode);
instance->instance = p_instance;
instance->node = this;
@@ -3106,7 +2914,6 @@ void VisualScriptCustomNode::_script_changed() {
}
void VisualScriptCustomNode::_bind_methods() {
-
BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_sequence_port_count"));
BIND_VMETHOD(MethodInfo(Variant::BOOL, "_has_input_sequence_port"));
@@ -3150,42 +2957,35 @@ VisualScriptCustomNode::VisualScriptCustomNode() {
//////////////////////////////////////////
int VisualScriptSubCall::get_output_sequence_port_count() const {
-
return 1;
}
bool VisualScriptSubCall::has_input_sequence_port() const {
-
return true;
}
int VisualScriptSubCall::get_input_value_port_count() const {
-
Ref<Script> script = get_script();
if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) {
-
MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall);
return mi.arguments.size();
}
return 0;
}
-int VisualScriptSubCall::get_output_value_port_count() const {
+int VisualScriptSubCall::get_output_value_port_count() const {
return 1;
}
String VisualScriptSubCall::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptSubCall::get_input_value_port_info(int p_idx) const {
-
Ref<Script> script = get_script();
if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) {
-
MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall);
return mi.arguments[p_idx];
}
@@ -3194,7 +2994,6 @@ PropertyInfo VisualScriptSubCall::get_input_value_port_info(int p_idx) const {
}
PropertyInfo VisualScriptSubCall::get_output_value_port_info(int p_idx) const {
-
Ref<Script> script = get_script();
if (script.is_valid() && script->has_method(VisualScriptLanguage::singleton->_subcall)) {
MethodInfo mi = script->get_method_info(VisualScriptLanguage::singleton->_subcall);
@@ -3204,25 +3003,24 @@ PropertyInfo VisualScriptSubCall::get_output_value_port_info(int p_idx) const {
}
String VisualScriptSubCall::get_caption() const {
-
return "SubCall";
}
String VisualScriptSubCall::get_text() const {
-
Ref<Script> script = get_script();
if (script.is_valid()) {
- if (script->get_name() != String())
+ if (script->get_name() != String()) {
return script->get_name();
- if (script->get_path().is_resource_file())
+ }
+ if (script->get_path().is_resource_file()) {
return script->get_path().get_file();
+ }
return script->get_class();
}
return "";
}
String VisualScriptSubCall::get_category() const {
-
return "custom";
}
@@ -3236,7 +3034,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (!valid) {
r_error_str = "Node requires a script with a _subcall(<args>) method to work.";
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -3248,7 +3045,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptSubCall::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceSubCall *instance = memnew(VisualScriptNodeInstanceSubCall);
instance->instance = p_instance;
Ref<Script> script = get_script();
@@ -3262,7 +3058,6 @@ VisualScriptNodeInstance *VisualScriptSubCall::instance(VisualScriptInstance *p_
}
void VisualScriptSubCall::_bind_methods() {
-
MethodInfo scmi(Variant::NIL, "_subcall", PropertyInfo(Variant::NIL, "arguments"));
scmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
BIND_VMETHOD(scmi);
@@ -3276,87 +3071,78 @@ VisualScriptSubCall::VisualScriptSubCall() {
//////////////////////////////////////////
int VisualScriptComment::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptComment::has_input_sequence_port() const {
-
return false;
}
int VisualScriptComment::get_input_value_port_count() const {
return 0;
}
-int VisualScriptComment::get_output_value_port_count() const {
+int VisualScriptComment::get_output_value_port_count() const {
return 0;
}
String VisualScriptComment::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptComment::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptComment::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
String VisualScriptComment::get_caption() const {
-
return title;
}
String VisualScriptComment::get_text() const {
-
return description;
}
void VisualScriptComment::set_title(const String &p_title) {
-
- if (title == p_title)
+ if (title == p_title) {
return;
+ }
title = p_title;
ports_changed_notify();
}
String VisualScriptComment::get_title() const {
-
return title;
}
void VisualScriptComment::set_description(const String &p_description) {
-
- if (description == p_description)
+ if (description == p_description) {
return;
+ }
description = p_description;
ports_changed_notify();
}
-String VisualScriptComment::get_description() const {
+String VisualScriptComment::get_description() const {
return description;
}
void VisualScriptComment::set_size(const Size2 &p_size) {
-
- if (size == p_size)
+ if (size == p_size) {
return;
+ }
size = p_size;
ports_changed_notify();
}
-Size2 VisualScriptComment::get_size() const {
+Size2 VisualScriptComment::get_size() const {
return size;
}
String VisualScriptComment::get_category() const {
-
return "data";
}
@@ -3367,20 +3153,17 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
return 0;
}
};
VisualScriptNodeInstance *VisualScriptComment::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceComment *instance = memnew(VisualScriptNodeInstanceComment);
instance->instance = p_instance;
return instance;
}
void VisualScriptComment::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_title", "title"), &VisualScriptComment::set_title);
ClassDB::bind_method(D_METHOD("get_title"), &VisualScriptComment::get_title);
@@ -3396,7 +3179,6 @@ void VisualScriptComment::_bind_methods() {
}
VisualScriptComment::VisualScriptComment() {
-
title = "Comment";
size = Size2(150, 150);
}
@@ -3406,70 +3188,60 @@ VisualScriptComment::VisualScriptComment() {
//////////////////////////////////////////
int VisualScriptConstructor::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptConstructor::has_input_sequence_port() const {
-
return false;
}
int VisualScriptConstructor::get_input_value_port_count() const {
return constructor.arguments.size();
}
-int VisualScriptConstructor::get_output_value_port_count() const {
+int VisualScriptConstructor::get_output_value_port_count() const {
return 1;
}
String VisualScriptConstructor::get_output_sequence_port_text(int p_port) const {
-
return "";
}
PropertyInfo VisualScriptConstructor::get_input_value_port_info(int p_idx) const {
-
return constructor.arguments[p_idx];
}
PropertyInfo VisualScriptConstructor::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo(type, "value");
}
String VisualScriptConstructor::get_caption() const {
-
return "Construct " + Variant::get_type_name(type);
}
String VisualScriptConstructor::get_category() const {
-
return "functions";
}
void VisualScriptConstructor::set_constructor_type(Variant::Type p_type) {
-
- if (type == p_type)
+ if (type == p_type) {
return;
+ }
type = p_type;
ports_changed_notify();
}
Variant::Type VisualScriptConstructor::get_constructor_type() const {
-
return type;
}
void VisualScriptConstructor::set_constructor(const Dictionary &p_info) {
-
constructor = MethodInfo::from_dict(p_info);
ports_changed_notify();
}
Dictionary VisualScriptConstructor::get_constructor() const {
-
return constructor;
}
@@ -3482,7 +3254,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
Callable::CallError ce;
*p_outputs[0] = Variant::construct(type, p_inputs, argcount, ce);
if (ce.error != Callable::CallError::CALL_OK) {
@@ -3494,7 +3265,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptConstructor::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceConstructor *instance = memnew(VisualScriptNodeInstanceConstructor);
instance->instance = p_instance;
instance->type = type;
@@ -3503,7 +3273,6 @@ VisualScriptNodeInstance *VisualScriptConstructor::instance(VisualScriptInstance
}
void VisualScriptConstructor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constructor_type", "type"), &VisualScriptConstructor::set_constructor_type);
ClassDB::bind_method(D_METHOD("get_constructor_type"), &VisualScriptConstructor::get_constructor_type);
@@ -3515,14 +3284,12 @@ void VisualScriptConstructor::_bind_methods() {
}
VisualScriptConstructor::VisualScriptConstructor() {
-
type = Variant::NIL;
}
static Map<String, Pair<Variant::Type, MethodInfo>> constructor_map;
static Ref<VisualScriptNode> create_constructor_node(const String &p_name) {
-
ERR_FAIL_COND_V(!constructor_map.has(p_name), Ref<VisualScriptNode>());
Ref<VisualScriptConstructor> vsc;
@@ -3538,69 +3305,60 @@ static Ref<VisualScriptNode> create_constructor_node(const String &p_name) {
//////////////////////////////////////////
int VisualScriptLocalVar::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptLocalVar::has_input_sequence_port() const {
-
return false;
}
int VisualScriptLocalVar::get_input_value_port_count() const {
return 0;
}
-int VisualScriptLocalVar::get_output_value_port_count() const {
+int VisualScriptLocalVar::get_output_value_port_count() const {
return 1;
}
String VisualScriptLocalVar::get_output_sequence_port_text(int p_port) const {
-
return "";
}
PropertyInfo VisualScriptLocalVar::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
-PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const {
+PropertyInfo VisualScriptLocalVar::get_output_value_port_info(int p_idx) const {
return PropertyInfo(type, name);
}
String VisualScriptLocalVar::get_caption() const {
-
return "Get Local Var";
}
String VisualScriptLocalVar::get_category() const {
-
return "data";
}
void VisualScriptLocalVar::set_var_name(const StringName &p_name) {
-
- if (name == p_name)
+ if (name == p_name) {
return;
+ }
name = p_name;
ports_changed_notify();
}
StringName VisualScriptLocalVar::get_var_name() const {
-
return name;
}
void VisualScriptLocalVar::set_var_type(Variant::Type p_type) {
-
type = p_type;
ports_changed_notify();
}
Variant::Type VisualScriptLocalVar::get_var_type() const {
-
return type;
}
@@ -3611,14 +3369,12 @@ public:
virtual int get_working_memory_size() const { return 1; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
*p_outputs[0] = *p_working_mem;
return 0;
}
};
VisualScriptNodeInstance *VisualScriptLocalVar::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceLocalVar *instance = memnew(VisualScriptNodeInstanceLocalVar);
instance->instance = p_instance;
instance->name = name;
@@ -3627,7 +3383,6 @@ VisualScriptNodeInstance *VisualScriptLocalVar::instance(VisualScriptInstance *p
}
void VisualScriptLocalVar::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_var_name", "name"), &VisualScriptLocalVar::set_var_name);
ClassDB::bind_method(D_METHOD("get_var_name"), &VisualScriptLocalVar::get_var_name);
@@ -3644,7 +3399,6 @@ void VisualScriptLocalVar::_bind_methods() {
}
VisualScriptLocalVar::VisualScriptLocalVar() {
-
name = "new_local";
type = Variant::NIL;
}
@@ -3654,74 +3408,64 @@ VisualScriptLocalVar::VisualScriptLocalVar() {
//////////////////////////////////////////
int VisualScriptLocalVarSet::get_output_sequence_port_count() const {
-
return 1;
}
bool VisualScriptLocalVarSet::has_input_sequence_port() const {
-
return true;
}
int VisualScriptLocalVarSet::get_input_value_port_count() const {
return 1;
}
-int VisualScriptLocalVarSet::get_output_value_port_count() const {
+int VisualScriptLocalVarSet::get_output_value_port_count() const {
return 1;
}
String VisualScriptLocalVarSet::get_output_sequence_port_text(int p_port) const {
-
return "";
}
PropertyInfo VisualScriptLocalVarSet::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo(type, "set");
}
-PropertyInfo VisualScriptLocalVarSet::get_output_value_port_info(int p_idx) const {
+PropertyInfo VisualScriptLocalVarSet::get_output_value_port_info(int p_idx) const {
return PropertyInfo(type, "get");
}
String VisualScriptLocalVarSet::get_caption() const {
-
return "Set Local Var";
}
String VisualScriptLocalVarSet::get_text() const {
-
return name;
}
String VisualScriptLocalVarSet::get_category() const {
-
return "data";
}
void VisualScriptLocalVarSet::set_var_name(const StringName &p_name) {
-
- if (name == p_name)
+ if (name == p_name) {
return;
+ }
name = p_name;
ports_changed_notify();
}
StringName VisualScriptLocalVarSet::get_var_name() const {
-
return name;
}
void VisualScriptLocalVarSet::set_var_type(Variant::Type p_type) {
-
type = p_type;
ports_changed_notify();
}
Variant::Type VisualScriptLocalVarSet::get_var_type() const {
-
return type;
}
@@ -3732,7 +3476,6 @@ public:
virtual int get_working_memory_size() const { return 1; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
*p_working_mem = *p_inputs[0];
*p_outputs[0] = *p_working_mem;
return 0;
@@ -3740,7 +3483,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptLocalVarSet::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceLocalVarSet *instance = memnew(VisualScriptNodeInstanceLocalVarSet);
instance->instance = p_instance;
instance->name = name;
@@ -3749,7 +3491,6 @@ VisualScriptNodeInstance *VisualScriptLocalVarSet::instance(VisualScriptInstance
}
void VisualScriptLocalVarSet::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_var_name", "name"), &VisualScriptLocalVarSet::set_var_name);
ClassDB::bind_method(D_METHOD("get_var_name"), &VisualScriptLocalVarSet::get_var_name);
@@ -3766,7 +3507,6 @@ void VisualScriptLocalVarSet::_bind_methods() {
}
VisualScriptLocalVarSet::VisualScriptLocalVarSet() {
-
name = "new_local";
type = Variant::NIL;
}
@@ -3776,34 +3516,30 @@ VisualScriptLocalVarSet::VisualScriptLocalVarSet() {
//////////////////////////////////////////
int VisualScriptInputAction::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptInputAction::has_input_sequence_port() const {
-
return false;
}
int VisualScriptInputAction::get_input_value_port_count() const {
return 0;
}
-int VisualScriptInputAction::get_output_value_port_count() const {
+int VisualScriptInputAction::get_output_value_port_count() const {
return 1;
}
String VisualScriptInputAction::get_output_sequence_port_text(int p_port) const {
-
return "";
}
PropertyInfo VisualScriptInputAction::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
-PropertyInfo VisualScriptInputAction::get_output_value_port_info(int p_idx) const {
+PropertyInfo VisualScriptInputAction::get_output_value_port_info(int p_idx) const {
String mstr;
switch (mode) {
case MODE_PRESSED: {
@@ -3824,39 +3560,36 @@ PropertyInfo VisualScriptInputAction::get_output_value_port_info(int p_idx) cons
}
String VisualScriptInputAction::get_caption() const {
-
return "Action " + name;
}
String VisualScriptInputAction::get_category() const {
-
return "data";
}
void VisualScriptInputAction::set_action_name(const StringName &p_name) {
-
- if (name == p_name)
+ if (name == p_name) {
return;
+ }
name = p_name;
ports_changed_notify();
}
StringName VisualScriptInputAction::get_action_name() const {
-
return name;
}
void VisualScriptInputAction::set_action_mode(Mode p_mode) {
-
- if (mode == p_mode)
+ if (mode == p_mode) {
return;
+ }
mode = p_mode;
ports_changed_notify();
}
-VisualScriptInputAction::Mode VisualScriptInputAction::get_action_mode() const {
+VisualScriptInputAction::Mode VisualScriptInputAction::get_action_mode() const {
return mode;
}
@@ -3867,19 +3600,18 @@ public:
VisualScriptInputAction::Mode mode;
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
switch (mode) {
case VisualScriptInputAction::MODE_PRESSED: {
- *p_outputs[0] = InputFilter::get_singleton()->is_action_pressed(action);
+ *p_outputs[0] = Input::get_singleton()->is_action_pressed(action);
} break;
case VisualScriptInputAction::MODE_RELEASED: {
- *p_outputs[0] = !InputFilter::get_singleton()->is_action_pressed(action);
+ *p_outputs[0] = !Input::get_singleton()->is_action_pressed(action);
} break;
case VisualScriptInputAction::MODE_JUST_PRESSED: {
- *p_outputs[0] = InputFilter::get_singleton()->is_action_just_pressed(action);
+ *p_outputs[0] = Input::get_singleton()->is_action_just_pressed(action);
} break;
case VisualScriptInputAction::MODE_JUST_RELEASED: {
- *p_outputs[0] = InputFilter::get_singleton()->is_action_just_released(action);
+ *p_outputs[0] = Input::get_singleton()->is_action_just_released(action);
} break;
}
@@ -3888,7 +3620,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptInputAction::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceInputAction *instance = memnew(VisualScriptNodeInstanceInputAction);
instance->instance = p_instance;
instance->action = name;
@@ -3898,9 +3629,7 @@ VisualScriptNodeInstance *VisualScriptInputAction::instance(VisualScriptInstance
}
void VisualScriptInputAction::_validate_property(PropertyInfo &property) const {
-
if (property.name == "action") {
-
property.hint = PROPERTY_HINT_ENUM;
String actions;
@@ -3911,8 +3640,9 @@ void VisualScriptInputAction::_validate_property(PropertyInfo &property) const {
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
const PropertyInfo &pi = E->get();
- if (!pi.name.begins_with("input/"))
+ if (!pi.name.begins_with("input/")) {
continue;
+ }
String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
@@ -3922,8 +3652,9 @@ void VisualScriptInputAction::_validate_property(PropertyInfo &property) const {
al.sort();
for (int i = 0; i < al.size(); i++) {
- if (actions != String())
+ if (actions != String()) {
actions += ",";
+ }
actions += al[i];
}
@@ -3932,7 +3663,6 @@ void VisualScriptInputAction::_validate_property(PropertyInfo &property) const {
}
void VisualScriptInputAction::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_action_name", "name"), &VisualScriptInputAction::set_action_name);
ClassDB::bind_method(D_METHOD("get_action_name"), &VisualScriptInputAction::get_action_name);
@@ -3949,7 +3679,6 @@ void VisualScriptInputAction::_bind_methods() {
}
VisualScriptInputAction::VisualScriptInputAction() {
-
name = "";
mode = MODE_PRESSED;
}
@@ -3959,50 +3688,42 @@ VisualScriptInputAction::VisualScriptInputAction() {
//////////////////////////////////////////
int VisualScriptDeconstruct::get_output_sequence_port_count() const {
-
return 0;
}
bool VisualScriptDeconstruct::has_input_sequence_port() const {
-
return false;
}
int VisualScriptDeconstruct::get_input_value_port_count() const {
return 1;
}
-int VisualScriptDeconstruct::get_output_value_port_count() const {
+int VisualScriptDeconstruct::get_output_value_port_count() const {
return elements.size();
}
String VisualScriptDeconstruct::get_output_sequence_port_text(int p_port) const {
-
return "";
}
PropertyInfo VisualScriptDeconstruct::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo(type, "value");
}
PropertyInfo VisualScriptDeconstruct::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo(elements[p_idx].type, elements[p_idx].name);
}
String VisualScriptDeconstruct::get_caption() const {
-
return "Deconstruct " + Variant::get_type_name(type);
}
String VisualScriptDeconstruct::get_category() const {
-
return "functions";
}
void VisualScriptDeconstruct::_update_elements() {
-
elements.clear();
Variant v;
Callable::CallError ce;
@@ -4012,7 +3733,6 @@ void VisualScriptDeconstruct::_update_elements() {
v.get_property_list(&pinfo);
for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
-
Element e;
e.name = E->get().name;
e.type = E->get().type;
@@ -4021,9 +3741,9 @@ void VisualScriptDeconstruct::_update_elements() {
}
void VisualScriptDeconstruct::set_deconstruct_type(Variant::Type p_type) {
-
- if (type == p_type)
+ if (type == p_type) {
return;
+ }
type = p_type;
_update_elements();
@@ -4032,12 +3752,10 @@ void VisualScriptDeconstruct::set_deconstruct_type(Variant::Type p_type) {
}
Variant::Type VisualScriptDeconstruct::get_deconstruct_type() const {
-
return type;
}
void VisualScriptDeconstruct::_set_elem_cache(const Array &p_elements) {
-
ERR_FAIL_COND(p_elements.size() % 2 == 1);
elements.resize(p_elements.size() / 2);
for (int i = 0; i < elements.size(); i++) {
@@ -4047,7 +3765,6 @@ void VisualScriptDeconstruct::_set_elem_cache(const Array &p_elements) {
}
Array VisualScriptDeconstruct::_get_elem_cache() const {
-
Array ret;
for (int i = 0; i < elements.size(); i++) {
ret.push_back(elements[i].name);
@@ -4064,7 +3781,6 @@ public:
//virtual int get_working_memory_size() const { return 0; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
Variant in = *p_inputs[0];
for (int i = 0; i < outputs.size(); i++) {
@@ -4082,7 +3798,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptDeconstruct::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceDeconstruct *instance = memnew(VisualScriptNodeInstanceDeconstruct);
instance->instance = p_instance;
instance->outputs.resize(elements.size());
@@ -4097,7 +3812,6 @@ void VisualScriptDeconstruct::_validate_property(PropertyInfo &property) const {
}
void VisualScriptDeconstruct::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_deconstruct_type", "type"), &VisualScriptDeconstruct::set_deconstruct_type);
ClassDB::bind_method(D_METHOD("get_deconstruct_type"), &VisualScriptDeconstruct::get_deconstruct_type);
@@ -4114,7 +3828,6 @@ void VisualScriptDeconstruct::_bind_methods() {
}
VisualScriptDeconstruct::VisualScriptDeconstruct() {
-
type = Variant::NIL;
}
@@ -4127,7 +3840,6 @@ static Ref<VisualScriptNode> create_node_deconst_typed(const String &p_name) {
}
void register_visual_script_nodes() {
-
VisualScriptLanguage::singleton->add_register_func("data/set_variable", create_node_generic<VisualScriptVariableSet>);
VisualScriptLanguage::singleton->add_register_func("data/get_variable", create_node_generic<VisualScriptVariableGet>);
VisualScriptLanguage::singleton->add_register_func("data/engine_singleton", create_node_generic<VisualScriptEngineSingleton>);
@@ -4199,12 +3911,10 @@ void register_visual_script_nodes() {
VisualScriptLanguage::singleton->add_register_func("functions/compose_array", create_node_generic<VisualScriptComposeArray>);
for (int i = 1; i < Variant::VARIANT_MAX; i++) {
-
List<MethodInfo> constructors;
Variant::get_constructor_list(Variant::Type(i), &constructors);
for (List<MethodInfo>::Element *E = constructors.front(); E; E = E->next()) {
-
if (E->get().arguments.size() > 0) {
String name = "functions/constructors/" + Variant::get_type_name(Variant::Type(i)) + "(";
for (int j = 0; j < E->get().arguments.size(); j++) {
@@ -4229,6 +3939,5 @@ void register_visual_script_nodes() {
}
void unregister_visual_script_nodes() {
-
constructor_map.clear();
}
diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h
index 0df5071491..fa284b216c 100644
--- a/modules/visual_script/visual_script_nodes.h
+++ b/modules/visual_script/visual_script_nodes.h
@@ -34,7 +34,6 @@
#include "visual_script.h"
class VisualScriptFunction : public VisualScriptNode {
-
GDCLASS(VisualScriptFunction, VisualScriptNode);
struct Argument {
@@ -104,7 +103,6 @@ public:
};
class VisualScriptLists : public VisualScriptNode {
-
GDCLASS(VisualScriptLists, VisualScriptNode)
struct Port {
@@ -176,7 +174,6 @@ public:
};
class VisualScriptComposeArray : public VisualScriptLists {
-
GDCLASS(VisualScriptComposeArray, VisualScriptLists)
public:
@@ -201,7 +198,6 @@ public:
};
class VisualScriptOperator : public VisualScriptNode {
-
GDCLASS(VisualScriptOperator, VisualScriptNode);
Variant::Type typed;
@@ -237,7 +233,6 @@ public:
};
class VisualScriptSelect : public VisualScriptNode {
-
GDCLASS(VisualScriptSelect, VisualScriptNode);
Variant::Type typed;
@@ -270,7 +265,6 @@ public:
};
class VisualScriptVariableGet : public VisualScriptNode {
-
GDCLASS(VisualScriptVariableGet, VisualScriptNode);
StringName variable;
@@ -303,7 +297,6 @@ public:
};
class VisualScriptVariableSet : public VisualScriptNode {
-
GDCLASS(VisualScriptVariableSet, VisualScriptNode);
StringName variable;
@@ -336,7 +329,6 @@ public:
};
class VisualScriptConstant : public VisualScriptNode {
-
GDCLASS(VisualScriptConstant, VisualScriptNode);
Variant::Type type;
@@ -373,7 +365,6 @@ public:
};
class VisualScriptPreload : public VisualScriptNode {
-
GDCLASS(VisualScriptPreload, VisualScriptNode);
Ref<Resource> preload;
@@ -405,7 +396,6 @@ public:
};
class VisualScriptIndexGet : public VisualScriptNode {
-
GDCLASS(VisualScriptIndexGet, VisualScriptNode);
public:
@@ -429,7 +419,6 @@ public:
};
class VisualScriptIndexSet : public VisualScriptNode {
-
GDCLASS(VisualScriptIndexSet, VisualScriptNode);
public:
@@ -453,7 +442,6 @@ public:
};
class VisualScriptGlobalConstant : public VisualScriptNode {
-
GDCLASS(VisualScriptGlobalConstant, VisualScriptNode);
int index;
@@ -484,7 +472,6 @@ public:
};
class VisualScriptClassConstant : public VisualScriptNode {
-
GDCLASS(VisualScriptClassConstant, VisualScriptNode);
StringName base_type;
@@ -521,7 +508,6 @@ public:
};
class VisualScriptBasicTypeConstant : public VisualScriptNode {
-
GDCLASS(VisualScriptBasicTypeConstant, VisualScriptNode);
Variant::Type type;
@@ -559,7 +545,6 @@ public:
};
class VisualScriptMathConstant : public VisualScriptNode {
-
GDCLASS(VisualScriptMathConstant, VisualScriptNode);
public:
@@ -609,7 +594,6 @@ public:
VARIANT_ENUM_CAST(VisualScriptMathConstant::MathConstant)
class VisualScriptEngineSingleton : public VisualScriptNode {
-
GDCLASS(VisualScriptEngineSingleton, VisualScriptNode);
String singleton;
@@ -645,7 +629,6 @@ public:
};
class VisualScriptSceneNode : public VisualScriptNode {
-
GDCLASS(VisualScriptSceneNode, VisualScriptNode);
NodePath path;
@@ -680,7 +663,6 @@ public:
};
class VisualScriptSceneTree : public VisualScriptNode {
-
GDCLASS(VisualScriptSceneTree, VisualScriptNode);
protected:
@@ -710,7 +692,6 @@ public:
};
class VisualScriptResourcePath : public VisualScriptNode {
-
GDCLASS(VisualScriptResourcePath, VisualScriptNode);
String path;
@@ -742,7 +723,6 @@ public:
};
class VisualScriptSelf : public VisualScriptNode {
-
GDCLASS(VisualScriptSelf, VisualScriptNode);
protected:
@@ -771,7 +751,6 @@ public:
};
class VisualScriptCustomNode : public VisualScriptNode {
-
GDCLASS(VisualScriptCustomNode, VisualScriptNode);
protected:
@@ -819,7 +798,6 @@ public:
VARIANT_ENUM_CAST(VisualScriptCustomNode::StartMode);
class VisualScriptSubCall : public VisualScriptNode {
-
GDCLASS(VisualScriptSubCall, VisualScriptNode);
protected:
@@ -847,7 +825,6 @@ public:
};
class VisualScriptComment : public VisualScriptNode {
-
GDCLASS(VisualScriptComment, VisualScriptNode);
String title;
@@ -888,7 +865,6 @@ public:
};
class VisualScriptConstructor : public VisualScriptNode {
-
GDCLASS(VisualScriptConstructor, VisualScriptNode);
Variant::Type type;
@@ -924,7 +900,6 @@ public:
};
class VisualScriptLocalVar : public VisualScriptNode {
-
GDCLASS(VisualScriptLocalVar, VisualScriptNode);
StringName name;
@@ -960,7 +935,6 @@ public:
};
class VisualScriptLocalVarSet : public VisualScriptNode {
-
GDCLASS(VisualScriptLocalVarSet, VisualScriptNode);
StringName name;
@@ -997,7 +971,6 @@ public:
};
class VisualScriptInputAction : public VisualScriptNode {
-
GDCLASS(VisualScriptInputAction, VisualScriptNode);
public:
@@ -1045,7 +1018,6 @@ public:
VARIANT_ENUM_CAST(VisualScriptInputAction::Mode)
class VisualScriptDeconstruct : public VisualScriptNode {
-
GDCLASS(VisualScriptDeconstruct, VisualScriptNode);
struct Element {
diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp
index f57853078d..f14c9ce49d 100644
--- a/modules/visual_script/visual_script_property_selector.cpp
+++ b/modules/visual_script/visual_script_property_selector.cpp
@@ -46,23 +46,21 @@ void VisualScriptPropertySelector::_text_changed(const String &p_newtext) {
}
void VisualScriptPropertySelector::_sbox_input(const Ref<InputEvent> &p_ie) {
-
Ref<InputEventKey> k = p_ie;
if (k.is_valid()) {
-
switch (k->get_keycode()) {
case KEY_UP:
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
-
search_options->call("_gui_input", k);
search_box->accept_event();
TreeItem *root = search_options->get_root();
- if (!root->get_children())
+ if (!root->get_children()) {
break;
+ }
TreeItem *current = search_options->get_selected();
@@ -153,11 +151,13 @@ void VisualScriptPropertySelector::_update_search() {
}
}
for (List<PropertyInfo>::Element *F = props.front(); F; F = F->next()) {
- if (!(F->get().usage & PROPERTY_USAGE_EDITOR) && !(F->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE))
+ if (!(F->get().usage & PROPERTY_USAGE_EDITOR) && !(F->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE)) {
continue;
+ }
- if (type_filter.size() && type_filter.find(F->get().type) == -1)
+ if (type_filter.size() && type_filter.find(F->get().type) == -1) {
continue;
+ }
// capitalize() also converts underscore to space, we'll match again both possible styles
String get_text_raw = String(vformat(TTR("Get %s"), F->get().name));
@@ -172,7 +172,7 @@ void VisualScriptPropertySelector::_update_search() {
item->set_metadata(0, F->get().name);
item->set_icon(0, type_icons[F->get().type]);
item->set_metadata(1, "get");
- item->set_collapsed(1);
+ item->set_collapsed(true);
item->set_selectable(0, true);
item->set_selectable(1, false);
item->set_selectable(2, false);
@@ -199,7 +199,6 @@ void VisualScriptPropertySelector::_update_search() {
v = Variant::construct(type, nullptr, 0, ce);
v.get_method_list(&methods);
} else {
-
Object *obj = ObjectDB::get_instance(script);
if (Object::cast_to<Script>(obj)) {
Object::cast_to<Script>(obj)->get_script_method_list(&methods);
@@ -209,23 +208,24 @@ void VisualScriptPropertySelector::_update_search() {
}
}
for (List<MethodInfo>::Element *M = methods.front(); M; M = M->next()) {
-
String name = M->get().name.get_slice(":", 0);
- if (name.begins_with("_") && !(M->get().flags & METHOD_FLAG_VIRTUAL))
+ if (name.begins_with("_") && !(M->get().flags & METHOD_FLAG_VIRTUAL)) {
continue;
+ }
- if (virtuals_only && !(M->get().flags & METHOD_FLAG_VIRTUAL))
+ if (virtuals_only && !(M->get().flags & METHOD_FLAG_VIRTUAL)) {
continue;
+ }
- if (!virtuals_only && (M->get().flags & METHOD_FLAG_VIRTUAL))
+ if (!virtuals_only && (M->get().flags & METHOD_FLAG_VIRTUAL)) {
continue;
+ }
MethodInfo mi = M->get();
String desc_arguments;
if (mi.arguments.size() > 0) {
desc_arguments = "(";
for (int i = 0; i < mi.arguments.size(); i++) {
-
if (i > 0) {
desc_arguments += ", ";
}
@@ -257,7 +257,7 @@ void VisualScriptPropertySelector::_update_search() {
item->set_selectable(0, true);
item->set_metadata(1, "method");
- item->set_collapsed(1);
+ item->set_collapsed(true);
item->set_selectable(1, false);
item->set_selectable(2, false);
@@ -320,7 +320,7 @@ void VisualScriptPropertySelector::create_visualscript_item(const String &name,
item->set_metadata(0, name);
item->set_metadata(1, "action");
item->set_selectable(0, true);
- item->set_collapsed(1);
+ item->set_collapsed(true);
item->set_selectable(1, false);
item->set_selectable(2, false);
item->set_metadata(2, connecting);
@@ -359,8 +359,9 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt
bool in_modifier = p_modifiers.empty();
for (Set<String>::Element *F = p_modifiers.front(); F && in_modifier; F = F->next()) {
- if (E->get().findn(F->get()) != -1)
+ if (E->get().findn(F->get()) != -1) {
in_modifier = true;
+ }
}
if (!in_modifier) {
continue;
@@ -411,21 +412,21 @@ void VisualScriptPropertySelector::get_visual_node_names(const String &root_filt
}
void VisualScriptPropertySelector::_confirmed() {
-
TreeItem *ti = search_options->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
emit_signal("selected", ti->get_metadata(0), ti->get_metadata(1), ti->get_metadata(2));
set_visible(false);
}
void VisualScriptPropertySelector::_item_selected() {
-
help_bit->set_text("");
TreeItem *item = search_options->get_selected();
- if (!item)
+ if (!item) {
return;
+ }
String name = item->get_metadata(0);
String class_type;
@@ -442,7 +443,6 @@ void VisualScriptPropertySelector::_item_selected() {
String at_class = class_type;
while (at_class != String()) {
-
Map<String, DocData::ClassDoc>::Element *E = dd->class_list.find(at_class);
if (E) {
for (int i = 0; i < E->get().properties.size(); i++) {
@@ -457,7 +457,6 @@ void VisualScriptPropertySelector::_item_selected() {
at_class = class_type;
while (at_class != String()) {
-
Map<String, DocData::ClassDoc>::Element *C = dd->class_list.find(at_class);
if (C) {
for (int i = 0; i < C->get().methods.size(); i++) {
@@ -512,8 +511,9 @@ void VisualScriptPropertySelector::_item_selected() {
memdelete(names);
- if (text == String())
+ if (text == String()) {
return;
+ }
help_bit->set_text(text);
}
@@ -523,15 +523,12 @@ void VisualScriptPropertySelector::_hide_requested() {
}
void VisualScriptPropertySelector::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
connect("confirmed", callable_mp(this, &VisualScriptPropertySelector::_confirmed));
}
}
void VisualScriptPropertySelector::select_method_from_base_type(const String &p_base, const String &p_current, const bool p_virtuals_only, const bool p_connecting, bool clear_text) {
-
base_type = p_base;
selected = p_current;
type = Variant::NIL;
@@ -540,10 +537,11 @@ void VisualScriptPropertySelector::select_method_from_base_type(const String &p_
virtuals_only = p_virtuals_only;
show_window(.5f);
- if (clear_text)
+ if (clear_text) {
search_box->set_text("");
- else
+ } else {
search_box->select_all();
+ }
search_box->grab_focus();
connecting = p_connecting;
@@ -555,7 +553,6 @@ void VisualScriptPropertySelector::set_type_filter(const Vector<Variant::Type> &
}
void VisualScriptPropertySelector::select_from_base_type(const String &p_base, const String &p_current, bool p_virtuals_only, bool p_seq_connect, const bool p_connecting, bool clear_text) {
-
base_type = p_base;
selected = p_current;
type = Variant::NIL;
@@ -565,10 +562,11 @@ void VisualScriptPropertySelector::select_from_base_type(const String &p_base, c
virtuals_only = p_virtuals_only;
show_window(.5f);
- if (clear_text)
+ if (clear_text) {
search_box->set_text("");
- else
+ } else {
search_box->select_all();
+ }
search_box->grab_focus();
seq_connect = p_seq_connect;
connecting = p_connecting;
@@ -589,10 +587,11 @@ void VisualScriptPropertySelector::select_from_script(const Ref<Script> &p_scrip
virtuals_only = false;
show_window(.5f);
- if (clear_text)
+ if (clear_text) {
search_box->set_text("");
- else
+ } else {
search_box->select_all();
+ }
search_box->grab_focus();
seq_connect = false;
connecting = p_connecting;
@@ -611,10 +610,11 @@ void VisualScriptPropertySelector::select_from_basic_type(Variant::Type p_type,
virtuals_only = false;
show_window(.5f);
- if (clear_text)
+ if (clear_text) {
search_box->set_text("");
- else
+ } else {
search_box->select_all();
+ }
search_box->grab_focus();
seq_connect = false;
connecting = p_connecting;
@@ -632,10 +632,11 @@ void VisualScriptPropertySelector::select_from_action(const String &p_type, cons
virtuals_only = false;
show_window(.5f);
- if (clear_text)
+ if (clear_text) {
search_box->set_text("");
- else
+ } else {
search_box->select_all();
+ }
search_box->grab_focus();
seq_connect = true;
connecting = p_connecting;
@@ -653,10 +654,11 @@ void VisualScriptPropertySelector::select_from_instance(Object *p_instance, cons
virtuals_only = false;
show_window(.5f);
- if (clear_text)
+ if (clear_text) {
search_box->set_text("");
- else
+ } else {
search_box->select_all();
+ }
search_box->grab_focus();
seq_connect = false;
connecting = p_connecting;
@@ -673,10 +675,11 @@ void VisualScriptPropertySelector::select_from_visual_script(const String &p_bas
instance = nullptr;
virtuals_only = false;
show_window(.5f);
- if (clear_text)
+ if (clear_text) {
search_box->set_text("");
- else
+ } else {
search_box->select_all();
+ }
search_box->grab_focus();
connecting = p_connecting;
@@ -684,17 +687,14 @@ void VisualScriptPropertySelector::select_from_visual_script(const String &p_bas
}
void VisualScriptPropertySelector::show_window(float p_screen_ratio) {
-
popup_centered_ratio(p_screen_ratio);
}
void VisualScriptPropertySelector::_bind_methods() {
-
ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::STRING, "category"), PropertyInfo(Variant::BOOL, "connecting")));
}
VisualScriptPropertySelector::VisualScriptPropertySelector() {
-
vbc = memnew(VBoxContainer);
add_child(vbc);
//set_child_rect(vbc);
diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp
index b300aec385..dd07cc45a7 100644
--- a/modules/visual_script/visual_script_yield_nodes.cpp
+++ b/modules/visual_script/visual_script_yield_nodes.cpp
@@ -40,51 +40,51 @@
//////////////////////////////////////////
int VisualScriptYield::get_output_sequence_port_count() const {
-
return 1;
}
bool VisualScriptYield::has_input_sequence_port() const {
-
return true;
}
int VisualScriptYield::get_input_value_port_count() const {
-
return 0;
}
-int VisualScriptYield::get_output_value_port_count() const {
+int VisualScriptYield::get_output_value_port_count() const {
return 0;
}
String VisualScriptYield::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptYield::get_input_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
PropertyInfo VisualScriptYield::get_output_value_port_info(int p_idx) const {
-
return PropertyInfo();
}
String VisualScriptYield::get_caption() const {
-
return yield_mode == YIELD_RETURN ? "Yield" : "Wait";
}
String VisualScriptYield::get_text() const {
-
switch (yield_mode) {
- case YIELD_RETURN: return ""; break;
- case YIELD_FRAME: return "Next Frame"; break;
- case YIELD_PHYSICS_FRAME: return "Next Physics Frame"; break;
- case YIELD_WAIT: return rtos(wait_time) + " sec(s)"; break;
+ case YIELD_RETURN:
+ return "";
+ break;
+ case YIELD_FRAME:
+ return "Next Frame";
+ break;
+ case YIELD_PHYSICS_FRAME:
+ return "Next Physics Frame";
+ break;
+ case YIELD_WAIT:
+ return rtos(wait_time) + " sec(s)";
+ break;
}
return String();
@@ -100,7 +100,6 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return false; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (p_start_mode == START_MODE_RESUME_YIELD) {
return 0; //resuming yield
} else {
@@ -118,13 +117,18 @@ public:
int ret = STEP_YIELD_BIT;
switch (mode) {
-
case VisualScriptYield::YIELD_RETURN:
ret = STEP_EXIT_FUNCTION_BIT;
break; //return the yield
- case VisualScriptYield::YIELD_FRAME: state->connect_to_signal(tree, "idle_frame", Array()); break;
- case VisualScriptYield::YIELD_PHYSICS_FRAME: state->connect_to_signal(tree, "physics_frame", Array()); break;
- case VisualScriptYield::YIELD_WAIT: state->connect_to_signal(tree->create_timer(wait_time).ptr(), "timeout", Array()); break;
+ case VisualScriptYield::YIELD_FRAME:
+ state->connect_to_signal(tree, "idle_frame", Array());
+ break;
+ case VisualScriptYield::YIELD_PHYSICS_FRAME:
+ state->connect_to_signal(tree, "physics_frame", Array());
+ break;
+ case VisualScriptYield::YIELD_WAIT:
+ state->connect_to_signal(tree->create_timer(wait_time).ptr(), "timeout", Array());
+ break;
}
*p_working_mem = state;
@@ -135,7 +139,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptYield::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceYield *instance = memnew(VisualScriptNodeInstanceYield);
//instance->instance=p_instance;
instance->mode = yield_mode;
@@ -144,34 +147,31 @@ VisualScriptNodeInstance *VisualScriptYield::instance(VisualScriptInstance *p_in
}
void VisualScriptYield::set_yield_mode(YieldMode p_mode) {
-
- if (yield_mode == p_mode)
+ if (yield_mode == p_mode) {
return;
+ }
yield_mode = p_mode;
ports_changed_notify();
_change_notify();
}
VisualScriptYield::YieldMode VisualScriptYield::get_yield_mode() {
-
return yield_mode;
}
void VisualScriptYield::set_wait_time(float p_time) {
-
- if (wait_time == p_time)
+ if (wait_time == p_time) {
return;
+ }
wait_time = p_time;
ports_changed_notify();
}
float VisualScriptYield::get_wait_time() {
-
return wait_time;
}
void VisualScriptYield::_validate_property(PropertyInfo &property) const {
-
if (property.name == "wait_time") {
if (yield_mode != YIELD_WAIT) {
property.usage = 0;
@@ -180,7 +180,6 @@ void VisualScriptYield::_validate_property(PropertyInfo &property) const {
}
void VisualScriptYield::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_yield_mode", "mode"), &VisualScriptYield::set_yield_mode);
ClassDB::bind_method(D_METHOD("get_yield_mode"), &VisualScriptYield::get_yield_mode);
@@ -196,14 +195,12 @@ void VisualScriptYield::_bind_methods() {
}
VisualScriptYield::VisualScriptYield() {
-
yield_mode = YIELD_FRAME;
wait_time = 1;
}
template <VisualScriptYield::YieldMode MODE>
static Ref<VisualScriptNode> create_yield_node(const String &p_name) {
-
Ref<VisualScriptYield> node;
node.instance();
node->set_yield_mode(MODE);
@@ -215,30 +212,30 @@ static Ref<VisualScriptNode> create_yield_node(const String &p_name) {
//////////////////////////////////////////////////
int VisualScriptYieldSignal::get_output_sequence_port_count() const {
-
return 1;
}
bool VisualScriptYieldSignal::has_input_sequence_port() const {
-
return true;
}
#ifdef TOOLS_ENABLED
static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const Ref<Script> &script) {
-
- if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene)
+ if (p_edited_scene != p_current_node && p_current_node->get_owner() != p_edited_scene) {
return nullptr;
+ }
Ref<Script> scr = p_current_node->get_script();
- if (scr.is_valid() && scr == script)
+ if (scr.is_valid() && scr == script) {
return p_current_node;
+ }
for (int i = 0; i < p_current_node->get_child_count(); i++) {
Node *n = _find_script_node(p_edited_scene, p_current_node->get_child(i), script);
- if (n)
+ if (n) {
return n;
+ }
}
return nullptr;
@@ -246,30 +243,34 @@ static Node *_find_script_node(Node *p_edited_scene, Node *p_current_node, const
#endif
Node *VisualScriptYieldSignal::_get_base_node() const {
-
#ifdef TOOLS_ENABLED
Ref<Script> script = get_visual_script();
- if (!script.is_valid())
+ if (!script.is_valid()) {
return nullptr;
+ }
MainLoop *main_loop = OS::get_singleton()->get_main_loop();
SceneTree *scene_tree = Object::cast_to<SceneTree>(main_loop);
- if (!scene_tree)
+ if (!scene_tree) {
return nullptr;
+ }
Node *edited_scene = scene_tree->get_edited_scene_root();
- if (!edited_scene)
+ if (!edited_scene) {
return nullptr;
+ }
Node *script_node = _find_script_node(edited_scene, edited_scene, script);
- if (!script_node)
+ if (!script_node) {
return nullptr;
+ }
- if (!script_node->has_node(base_path))
+ if (!script_node->has_node(base_path)) {
return nullptr;
+ }
Node *path_to = script_node->get_node(base_path);
@@ -281,60 +282,59 @@ Node *VisualScriptYieldSignal::_get_base_node() const {
}
StringName VisualScriptYieldSignal::_get_base_type() const {
-
- if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid())
+ if (call_mode == CALL_MODE_SELF && get_visual_script().is_valid()) {
return get_visual_script()->get_instance_base_type();
- else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
+ } else if (call_mode == CALL_MODE_NODE_PATH && get_visual_script().is_valid()) {
Node *path = _get_base_node();
- if (path)
+ if (path) {
return path->get_class();
+ }
}
return base_type;
}
int VisualScriptYieldSignal::get_input_value_port_count() const {
-
- if (call_mode == CALL_MODE_INSTANCE)
+ if (call_mode == CALL_MODE_INSTANCE) {
return 1;
- else
+ } else {
return 0;
+ }
}
-int VisualScriptYieldSignal::get_output_value_port_count() const {
+int VisualScriptYieldSignal::get_output_value_port_count() const {
MethodInfo sr;
- if (!ClassDB::get_signal(_get_base_type(), signal, &sr))
+ if (!ClassDB::get_signal(_get_base_type(), signal, &sr)) {
return 0;
+ }
return sr.arguments.size();
}
String VisualScriptYieldSignal::get_output_sequence_port_text(int p_port) const {
-
return String();
}
PropertyInfo VisualScriptYieldSignal::get_input_value_port_info(int p_idx) const {
-
- if (call_mode == CALL_MODE_INSTANCE)
+ if (call_mode == CALL_MODE_INSTANCE) {
return PropertyInfo(Variant::OBJECT, "instance");
- else
+ } else {
return PropertyInfo();
+ }
}
PropertyInfo VisualScriptYieldSignal::get_output_value_port_info(int p_idx) const {
-
MethodInfo sr;
- if (!ClassDB::get_signal(_get_base_type(), signal, &sr))
+ if (!ClassDB::get_signal(_get_base_type(), signal, &sr)) {
return PropertyInfo(); //no signal
+ }
ERR_FAIL_INDEX_V(p_idx, sr.arguments.size(), PropertyInfo());
return sr.arguments[p_idx];
}
String VisualScriptYieldSignal::get_caption() const {
-
static const char *cname[3] = {
"WaitSignal",
"WaitNodeSignal",
@@ -345,17 +345,17 @@ String VisualScriptYieldSignal::get_caption() const {
}
String VisualScriptYieldSignal::get_text() const {
-
- if (call_mode == CALL_MODE_SELF)
+ if (call_mode == CALL_MODE_SELF) {
return " " + String(signal) + "()";
- else
+ } else {
return " " + _get_base_type() + "." + String(signal) + "()";
+ }
}
void VisualScriptYieldSignal::set_base_type(const StringName &p_type) {
-
- if (base_type == p_type)
+ if (base_type == p_type) {
return;
+ }
base_type = p_type;
@@ -364,29 +364,28 @@ void VisualScriptYieldSignal::set_base_type(const StringName &p_type) {
}
StringName VisualScriptYieldSignal::get_base_type() const {
-
return base_type;
}
void VisualScriptYieldSignal::set_signal(const StringName &p_type) {
-
- if (signal == p_type)
+ if (signal == p_type) {
return;
+ }
signal = p_type;
_change_notify();
ports_changed_notify();
}
-StringName VisualScriptYieldSignal::get_signal() const {
+StringName VisualScriptYieldSignal::get_signal() const {
return signal;
}
void VisualScriptYieldSignal::set_base_path(const NodePath &p_type) {
-
- if (base_path == p_type)
+ if (base_path == p_type) {
return;
+ }
base_path = p_type;
@@ -395,14 +394,13 @@ void VisualScriptYieldSignal::set_base_path(const NodePath &p_type) {
}
NodePath VisualScriptYieldSignal::get_base_path() const {
-
return base_path;
}
void VisualScriptYieldSignal::set_call_mode(CallMode p_mode) {
-
- if (call_mode == p_mode)
+ if (call_mode == p_mode) {
return;
+ }
call_mode = p_mode;
@@ -411,12 +409,10 @@ void VisualScriptYieldSignal::set_call_mode(CallMode p_mode) {
}
VisualScriptYieldSignal::CallMode VisualScriptYieldSignal::get_call_mode() const {
-
return call_mode;
}
void VisualScriptYieldSignal::_validate_property(PropertyInfo &property) const {
-
if (property.name == "base_type") {
if (call_mode != CALL_MODE_INSTANCE) {
property.usage = PROPERTY_USAGE_NOEDITOR;
@@ -427,7 +423,6 @@ void VisualScriptYieldSignal::_validate_property(PropertyInfo &property) const {
if (call_mode != CALL_MODE_NODE_PATH) {
property.usage = 0;
} else {
-
Node *bnode = _get_base_node();
if (bnode) {
property.hint_string = bnode->get_path(); //convert to loong string
@@ -444,8 +439,9 @@ void VisualScriptYieldSignal::_validate_property(PropertyInfo &property) const {
List<String> mstring;
for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) {
- if (E->get().name.begins_with("_"))
+ if (E->get().name.begins_with("_")) {
continue;
+ }
mstring.push_back(E->get().name.get_slice(":", 0));
}
@@ -453,9 +449,9 @@ void VisualScriptYieldSignal::_validate_property(PropertyInfo &property) const {
String ml;
for (List<String>::Element *E = mstring.front(); E; E = E->next()) {
-
- if (ml != String())
+ if (ml != String()) {
ml += ",";
+ }
ml += E->get();
}
@@ -464,7 +460,6 @@ void VisualScriptYieldSignal::_validate_property(PropertyInfo &property) const {
}
void VisualScriptYieldSignal::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_base_type", "base_type"), &VisualScriptYieldSignal::set_base_type);
ClassDB::bind_method(D_METHOD("get_base_type"), &VisualScriptYieldSignal::get_base_type);
@@ -479,8 +474,9 @@ void VisualScriptYieldSignal::_bind_methods() {
String bt;
for (int i = 0; i < Variant::VARIANT_MAX; i++) {
- if (i > 0)
+ if (i > 0) {
bt += ",";
+ }
bt += Variant::get_type_name(Variant::Type(i));
}
@@ -510,7 +506,6 @@ public:
//virtual bool get_output_port_unsequenced(int p_idx,Variant* r_value,Variant* p_working_mem,String &r_error) const { return true; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
-
if (p_start_mode == START_MODE_RESUME_YIELD) {
return 0; //resuming yield
} else {
@@ -519,14 +514,11 @@ public:
Object *object = nullptr;
switch (call_mode) {
-
case VisualScriptYieldSignal::CALL_MODE_SELF: {
-
object = instance->get_owner_ptr();
} break;
case VisualScriptYieldSignal::CALL_MODE_NODE_PATH: {
-
Node *node = Object::cast_to<Node>(instance->get_owner_ptr());
if (!node) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -545,7 +537,6 @@ public:
} break;
case VisualScriptYieldSignal::CALL_MODE_INSTANCE: {
-
object = *p_inputs[0];
if (!object) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -569,7 +560,6 @@ public:
};
VisualScriptNodeInstance *VisualScriptYieldSignal::instance(VisualScriptInstance *p_instance) {
-
VisualScriptNodeInstanceYieldSignal *instance = memnew(VisualScriptNodeInstanceYieldSignal);
instance->node = this;
instance->instance = p_instance;
@@ -579,15 +569,14 @@ VisualScriptNodeInstance *VisualScriptYieldSignal::instance(VisualScriptInstance
instance->output_args = get_output_value_port_count();
return instance;
}
-VisualScriptYieldSignal::VisualScriptYieldSignal() {
+VisualScriptYieldSignal::VisualScriptYieldSignal() {
call_mode = CALL_MODE_SELF;
base_type = "Object";
}
template <VisualScriptYieldSignal::CallMode cmode>
static Ref<VisualScriptNode> create_yield_signal_node(const String &p_name) {
-
Ref<VisualScriptYieldSignal> node;
node.instance();
node->set_call_mode(cmode);
@@ -595,7 +584,6 @@ static Ref<VisualScriptNode> create_yield_signal_node(const String &p_name) {
}
void register_visual_script_yield_nodes() {
-
VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_frame", create_yield_node<VisualScriptYield::YIELD_FRAME>);
VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_physics_frame", create_yield_node<VisualScriptYield::YIELD_PHYSICS_FRAME>);
VisualScriptLanguage::singleton->add_register_func("functions/wait/wait_time", create_yield_node<VisualScriptYield::YIELD_WAIT>);
diff --git a/modules/visual_script/visual_script_yield_nodes.h b/modules/visual_script/visual_script_yield_nodes.h
index 4b976bd6c6..4877e8b7e6 100644
--- a/modules/visual_script/visual_script_yield_nodes.h
+++ b/modules/visual_script/visual_script_yield_nodes.h
@@ -34,7 +34,6 @@
#include "visual_script.h"
class VisualScriptYield : public VisualScriptNode {
-
GDCLASS(VisualScriptYield, VisualScriptNode);
public:
@@ -84,7 +83,6 @@ public:
VARIANT_ENUM_CAST(VisualScriptYield::YieldMode)
class VisualScriptYieldSignal : public VisualScriptNode {
-
GDCLASS(VisualScriptYieldSignal, VisualScriptNode);
public:
diff --git a/modules/webm/register_types.cpp b/modules/webm/register_types.cpp
index 5449dd458c..6248787879 100644
--- a/modules/webm/register_types.cpp
+++ b/modules/webm/register_types.cpp
@@ -35,7 +35,6 @@
static Ref<ResourceFormatLoaderWebm> resource_loader_webm;
void register_webm_types() {
-
resource_loader_webm.instance();
ResourceLoader::add_resource_format_loader(resource_loader_webm, true);
@@ -43,7 +42,6 @@ void register_webm_types() {
}
void unregister_webm_types() {
-
ResourceLoader::remove_resource_format_loader(resource_loader_webm);
resource_loader_webm.unref();
}
diff --git a/modules/webm/video_stream_webm.cpp b/modules/webm/video_stream_webm.cpp
index ca78d664f7..832e14d91a 100644
--- a/modules/webm/video_stream_webm.cpp
+++ b/modules/webm/video_stream_webm.cpp
@@ -48,41 +48,39 @@
#include <mkvparser/mkvparser.h>
class MkvReader : public mkvparser::IMkvReader {
-
public:
MkvReader(const String &p_file) {
-
file = FileAccess::open(p_file, FileAccess::READ);
ERR_FAIL_COND_MSG(!file, "Failed loading resource: '" + p_file + "'.");
}
~MkvReader() {
-
- if (file)
+ if (file) {
memdelete(file);
+ }
}
virtual int Read(long long pos, long len, unsigned char *buf) {
-
if (file) {
-
- if (file->get_position() != (size_t)pos)
+ if (file->get_position() != (size_t)pos) {
file->seek(pos);
- if (file->get_buffer(buf, len) == len)
+ }
+ if (file->get_buffer(buf, len) == len) {
return 0;
+ }
}
return -1;
}
virtual int Length(long long *total, long long *available) {
-
if (file) {
-
const size_t len = file->get_len();
- if (total)
+ if (total) {
*total = len;
- if (available)
+ }
+ if (available) {
*available = len;
+ }
return 0;
}
return -1;
@@ -95,47 +93,23 @@ private:
/**/
VideoStreamPlaybackWebm::VideoStreamPlaybackWebm() :
- audio_track(0),
- webm(nullptr),
- video(nullptr),
- audio(nullptr),
- video_frames(nullptr),
- audio_frame(nullptr),
- video_frames_pos(0),
- video_frames_capacity(0),
- num_decoded_samples(0),
- samples_offset(-1),
- mix_callback(nullptr),
- mix_udata(nullptr),
- playing(false),
- paused(false),
- delay_compensation(0.0),
- time(0.0),
- video_frame_delay(0.0),
- video_pos(0.0),
- texture(memnew(ImageTexture)),
- pcm(nullptr) {}
-VideoStreamPlaybackWebm::~VideoStreamPlaybackWebm() {
+ texture(memnew(ImageTexture)) {}
+VideoStreamPlaybackWebm::~VideoStreamPlaybackWebm() {
delete_pointers();
}
bool VideoStreamPlaybackWebm::open_file(const String &p_file) {
-
file_name = p_file;
webm = memnew(WebMDemuxer(new MkvReader(file_name), 0, audio_track));
if (webm->isOpen()) {
-
video = memnew(VPXDecoder(*webm, OS::get_singleton()->get_processor_count()));
if (video->isOpen()) {
-
audio = memnew(OpusVorbisDecoder(*webm));
if (audio->isOpen()) {
-
audio_frame = memnew(WebMFrame);
pcm = (float *)memalloc(sizeof(float) * audio->getBufferSamples() * webm->getChannels());
} else {
-
memdelete(audio);
audio = nullptr;
}
@@ -157,9 +131,7 @@ bool VideoStreamPlaybackWebm::open_file(const String &p_file) {
}
void VideoStreamPlaybackWebm::stop() {
-
if (playing) {
-
delete_pointers();
pcm = nullptr;
@@ -180,8 +152,8 @@ void VideoStreamPlaybackWebm::stop() {
time = 0.0;
playing = false;
}
-void VideoStreamPlaybackWebm::play() {
+void VideoStreamPlaybackWebm::play() {
stop();
delay_compensation = ProjectSettings::get_singleton()->get("audio/video_delay_compensation_ms");
@@ -191,58 +163,52 @@ void VideoStreamPlaybackWebm::play() {
}
bool VideoStreamPlaybackWebm::is_playing() const {
-
return playing;
}
void VideoStreamPlaybackWebm::set_paused(bool p_paused) {
-
paused = p_paused;
}
-bool VideoStreamPlaybackWebm::is_paused() const {
+bool VideoStreamPlaybackWebm::is_paused() const {
return paused;
}
void VideoStreamPlaybackWebm::set_loop(bool p_enable) {
-
//Empty
}
-bool VideoStreamPlaybackWebm::has_loop() const {
+bool VideoStreamPlaybackWebm::has_loop() const {
return false;
}
float VideoStreamPlaybackWebm::get_length() const {
-
- if (webm)
+ if (webm) {
return webm->getLength();
+ }
return 0.0f;
}
float VideoStreamPlaybackWebm::get_playback_position() const {
-
return video_pos;
}
-void VideoStreamPlaybackWebm::seek(float p_time) {
+void VideoStreamPlaybackWebm::seek(float p_time) {
//Not implemented
}
void VideoStreamPlaybackWebm::set_audio_track(int p_idx) {
-
audio_track = p_idx;
}
Ref<Texture2D> VideoStreamPlaybackWebm::get_texture() const {
-
return texture;
}
void VideoStreamPlaybackWebm::update(float p_delta) {
-
- if ((!playing || paused) || !video)
+ if ((!playing || paused) || !video) {
return;
+ }
time += p_delta;
@@ -253,16 +219,13 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
bool audio_buffer_full = false;
if (samples_offset > -1) {
-
//Mix remaining samples
const int to_read = num_decoded_samples - samples_offset;
const int mixed = mix_callback(mix_udata, pcm + samples_offset * webm->getChannels(), to_read);
if (mixed != to_read) {
-
samples_offset += mixed;
audio_buffer_full = true;
} else {
-
samples_offset = -1;
}
}
@@ -270,10 +233,8 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
const bool hasAudio = (audio && mix_callback);
while ((hasAudio && !audio_buffer_full && !has_enough_video_frames()) ||
(!hasAudio && video_frames_pos == 0)) {
-
if (hasAudio && !audio_buffer_full && audio_frame->isValid() &&
audio->getPCMF(*audio_frame, pcm, num_decoded_samples) && num_decoded_samples > 0) {
-
const int mixed = mix_callback(mix_udata, pcm, num_decoded_samples);
if (mixed != num_decoded_samples) {
@@ -284,42 +245,37 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
WebMFrame *video_frame;
if (video_frames_pos >= video_frames_capacity) {
-
WebMFrame **video_frames_new = (WebMFrame **)memrealloc(video_frames, ++video_frames_capacity * sizeof(void *));
ERR_FAIL_COND(!video_frames_new); //Out of memory
(video_frames = video_frames_new)[video_frames_capacity - 1] = memnew(WebMFrame);
}
video_frame = video_frames[video_frames_pos];
- if (!webm->readFrame(video_frame, audio_frame)) //This will invalidate frames
+ if (!webm->readFrame(video_frame, audio_frame)) { //This will invalidate frames
break; //Can't demux, EOS?
+ }
- if (video_frame->isValid())
+ if (video_frame->isValid()) {
++video_frames_pos;
+ }
};
bool video_frame_done = false;
while (video_frames_pos > 0 && !video_frame_done) {
-
WebMFrame *video_frame = video_frames[0];
// It seems VPXDecoder::decode has to be executed even though we might skip this frame
if (video->decode(*video_frame)) {
-
VPXDecoder::IMAGE_ERROR err;
VPXDecoder::Image image;
if (should_process(*video_frame)) {
-
if ((err = video->getImage(image)) != VPXDecoder::NO_FRAME) {
-
if (err == VPXDecoder::NO_ERROR && image.w == webm->getWidth() && image.h == webm->getHeight()) {
-
uint8_t *w = frame_data.ptrw();
bool converted = false;
if (image.chromaShiftW == 0 && image.chromaShiftH == 0 && image.cs == VPX_CS_SRGB) {
-
uint8_t *wp = w;
unsigned char *rRow = image.planes[2];
unsigned char *gRow = image.planes[0];
@@ -337,22 +293,18 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
}
converted = true;
} else if (image.chromaShiftW == 1 && image.chromaShiftH == 1) {
-
yuv420_2_rgb8888(w, image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
//libyuv::I420ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
converted = true;
} else if (image.chromaShiftW == 1 && image.chromaShiftH == 0) {
-
yuv422_2_rgb8888(w, image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
//libyuv::I422ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
converted = true;
} else if (image.chromaShiftW == 0 && image.chromaShiftH == 0) {
-
yuv444_2_rgb8888(w, image.planes[0], image.planes[1], image.planes[2], image.w, image.h, image.linesize[0], image.linesize[1], image.w << 2);
//libyuv::I444ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2], image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
converted = true;
} else if (image.chromaShiftW == 2 && image.chromaShiftH == 0) {
-
//libyuv::I411ToARGB(image.planes[0], image.linesize[0], image.planes[2], image.linesize[2] image.planes[1], image.linesize[1], w.ptr(), image.w << 2, image.w, image.h);
//converted = true;
}
@@ -372,25 +324,27 @@ void VideoStreamPlaybackWebm::update(float p_delta) {
video_frames[video_frames_pos] = video_frame;
}
- if (video_frames_pos == 0 && webm->isEOS())
+ if (video_frames_pos == 0 && webm->isEOS()) {
stop();
+ }
}
void VideoStreamPlaybackWebm::set_mix_callback(VideoStreamPlayback::AudioMixCallback p_callback, void *p_userdata) {
-
mix_callback = p_callback;
mix_udata = p_userdata;
}
-int VideoStreamPlaybackWebm::get_channels() const {
- if (audio)
+int VideoStreamPlaybackWebm::get_channels() const {
+ if (audio) {
return webm->getChannels();
+ }
return 0;
}
-int VideoStreamPlaybackWebm::get_mix_rate() const {
- if (audio)
+int VideoStreamPlaybackWebm::get_mix_rate() const {
+ if (audio) {
return webm->getSampleRate();
+ }
return 0;
}
@@ -415,52 +369,54 @@ bool VideoStreamPlaybackWebm::should_process(WebMFrame &video_frame) {
}
void VideoStreamPlaybackWebm::delete_pointers() {
-
- if (pcm)
+ if (pcm) {
memfree(pcm);
+ }
- if (audio_frame)
+ if (audio_frame) {
memdelete(audio_frame);
+ }
if (video_frames) {
- for (int i = 0; i < video_frames_capacity; ++i)
+ for (int i = 0; i < video_frames_capacity; ++i) {
memdelete(video_frames[i]);
+ }
memfree(video_frames);
}
- if (video)
+ if (video) {
memdelete(video);
- if (audio)
+ }
+ if (audio) {
memdelete(audio);
+ }
- if (webm)
+ if (webm) {
memdelete(webm);
+ }
}
/**/
-VideoStreamWebm::VideoStreamWebm() :
- audio_track(0) {}
+VideoStreamWebm::VideoStreamWebm() {}
Ref<VideoStreamPlayback> VideoStreamWebm::instance_playback() {
-
Ref<VideoStreamPlaybackWebm> pb = memnew(VideoStreamPlaybackWebm);
pb->set_audio_track(audio_track);
- if (pb->open_file(file))
+ if (pb->open_file(file)) {
return pb;
+ }
return nullptr;
}
void VideoStreamWebm::set_file(const String &p_file) {
-
file = p_file;
}
-String VideoStreamWebm::get_file() {
+String VideoStreamWebm::get_file() {
return file;
}
void VideoStreamWebm::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_file", "file"), &VideoStreamWebm::set_file);
ClassDB::bind_method(D_METHOD("get_file"), &VideoStreamWebm::get_file);
@@ -468,14 +424,12 @@ void VideoStreamWebm::_bind_methods() {
}
void VideoStreamWebm::set_audio_track(int p_track) {
-
audio_track = p_track;
}
////////////
-RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
+RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
if (r_error) {
@@ -499,19 +453,17 @@ RES ResourceFormatLoaderWebm::load(const String &p_path, const String &p_origina
}
void ResourceFormatLoaderWebm::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("webm");
}
bool ResourceFormatLoaderWebm::handles_type(const String &p_type) const {
-
return ClassDB::is_parent_class(p_type, "VideoStream");
}
String ResourceFormatLoaderWebm::get_resource_type(const String &p_path) const {
-
String el = p_path.get_extension().to_lower();
- if (el == "webm")
+ if (el == "webm") {
return "VideoStreamWebm";
+ }
return "";
}
diff --git a/modules/webm/video_stream_webm.h b/modules/webm/video_stream_webm.h
index bc209e0057..f6c148b29b 100644
--- a/modules/webm/video_stream_webm.h
+++ b/modules/webm/video_stream_webm.h
@@ -40,31 +40,30 @@ class VPXDecoder;
class OpusVorbisDecoder;
class VideoStreamPlaybackWebm : public VideoStreamPlayback {
-
GDCLASS(VideoStreamPlaybackWebm, VideoStreamPlayback);
String file_name;
- int audio_track;
+ int audio_track = 0;
- WebMDemuxer *webm;
- VPXDecoder *video;
- OpusVorbisDecoder *audio;
+ WebMDemuxer *webm = nullptr;
+ VPXDecoder *video = nullptr;
+ OpusVorbisDecoder *audio = nullptr;
- WebMFrame **video_frames, *audio_frame;
- int video_frames_pos, video_frames_capacity;
+ WebMFrame **video_frames = nullptr, *audio_frame = nullptr;
+ int video_frames_pos = 0, video_frames_capacity = 0;
- int num_decoded_samples, samples_offset;
- AudioMixCallback mix_callback;
- void *mix_udata;
+ int num_decoded_samples = 0, samples_offset = -1;
+ AudioMixCallback mix_callback = nullptr;
+ void *mix_udata = nullptr;
- bool playing, paused;
- double delay_compensation;
- double time, video_frame_delay, video_pos;
+ bool playing = false, paused = false;
+ double delay_compensation = 0.0;
+ double time = 0.0, video_frame_delay = 0.0, video_pos = 0.0;
Vector<uint8_t> frame_data;
Ref<ImageTexture> texture;
- float *pcm;
+ float *pcm = nullptr;
public:
VideoStreamPlaybackWebm();
@@ -107,11 +106,10 @@ private:
/**/
class VideoStreamWebm : public VideoStream {
-
GDCLASS(VideoStreamWebm, VideoStream);
String file;
- int audio_track;
+ int audio_track = 0;
protected:
static void _bind_methods();
@@ -128,7 +126,7 @@ public:
class ResourceFormatLoaderWebm : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp
index 0998977bb4..d5c80e7909 100644
--- a/modules/webp/image_loader_webp.cpp
+++ b/modules/webp/image_loader_webp.cpp
@@ -39,14 +39,14 @@
#include <webp/encode.h>
static Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) {
-
ERR_FAIL_COND_V(p_image.is_null() || p_image->empty(), Vector<uint8_t>());
Ref<Image> img = p_image->duplicate();
- if (img->detect_alpha())
+ if (img->detect_alpha()) {
img->convert(Image::FORMAT_RGBA8);
- else
+ } else {
img->convert(Image::FORMAT_RGB8);
+ }
Size2 s(img->get_width(), img->get_height());
Vector<uint8_t> data = img->get_data();
@@ -55,7 +55,6 @@ static Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quali
uint8_t *dst_buff = nullptr;
size_t dst_size = 0;
if (img->get_format() == Image::FORMAT_RGB8) {
-
dst_size = WebPEncodeRGB(r, s.width, s.height, 3 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff);
} else {
dst_size = WebPEncodeRGBA(r, s.width, s.height, 4 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff);
@@ -76,7 +75,6 @@ static Vector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quali
}
static Ref<Image> _webp_lossy_unpack(const Vector<uint8_t> &p_buffer) {
-
int size = p_buffer.size() - 4;
ERR_FAIL_COND_V(size <= 0, Ref<Image>());
const uint8_t *r = p_buffer.ptr();
@@ -113,7 +111,6 @@ static Ref<Image> _webp_lossy_unpack(const Vector<uint8_t> &p_buffer) {
}
Error webp_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p_buffer_len) {
-
ERR_FAIL_NULL_V(p_image, ERR_INVALID_PARAMETER);
WebPBitstreamFeatures features;
@@ -135,13 +132,12 @@ Error webp_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
ERR_FAIL_COND_V_MSG(errdec, ERR_FILE_CORRUPT, "Failed decoding WebP image.");
- p_image->create(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image);
+ p_image->create(features.width, features.height, false, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image);
return OK;
}
static Ref<Image> _webp_mem_loader_func(const uint8_t *p_png, int p_size) {
-
Ref<Image> img;
img.instance();
Error err = webp_load_image_from_buffer(img.ptr(), p_png, p_size);
@@ -150,7 +146,6 @@ static Ref<Image> _webp_mem_loader_func(const uint8_t *p_png, int p_size) {
}
Error ImageLoaderWEBP::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
-
Vector<uint8_t> src_image;
int src_image_len = f->get_len();
ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
@@ -168,7 +163,6 @@ Error ImageLoaderWEBP::load_image(Ref<Image> p_image, FileAccess *f, bool p_forc
}
void ImageLoaderWEBP::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("webp");
}
diff --git a/modules/webp/image_loader_webp.h b/modules/webp/image_loader_webp.h
index 9206ca2525..49a7407600 100644
--- a/modules/webp/image_loader_webp.h
+++ b/modules/webp/image_loader_webp.h
@@ -34,7 +34,6 @@
#include "core/io/image_loader.h"
class ImageLoaderWEBP : public ImageFormatLoader {
-
public:
virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
diff --git a/modules/webp/register_types.cpp b/modules/webp/register_types.cpp
index fe945b01d4..0788b06309 100644
--- a/modules/webp/register_types.cpp
+++ b/modules/webp/register_types.cpp
@@ -35,12 +35,10 @@
static ImageLoaderWEBP *image_loader_webp = nullptr;
void register_webp_types() {
-
image_loader_webp = memnew(ImageLoaderWEBP);
ImageLoader::add_image_format_loader(image_loader_webp);
}
void unregister_webp_types() {
-
memdelete(image_loader_webp);
}
diff --git a/modules/webrtc/webrtc_data_channel_js.cpp b/modules/webrtc/webrtc_data_channel_js.cpp
index 1b360720a2..2c648ba9f9 100644
--- a/modules/webrtc/webrtc_data_channel_js.cpp
+++ b/modules/webrtc/webrtc_data_channel_js.cpp
@@ -68,7 +68,6 @@ void WebRTCDataChannelJS::_on_error() {
}
void WebRTCDataChannelJS::_on_message(uint8_t *p_data, uint32_t p_size, bool p_is_string) {
-
ERR_FAIL_COND_MSG(in_buffer.space_left() < (int)(p_size + 5), "Buffer full! Dropping data.");
uint8_t is_string = p_is_string ? 1 : 0;
@@ -312,14 +311,14 @@ WebRTCDataChannelJS::WebRTCDataChannelJS(int js_id) {
return;
}
var len = buffer.length*buffer.BYTES_PER_ELEMENT;
- var out = Module._malloc(len);
- Module.HEAPU8.set(buffer, out);
+ var out = _malloc(len);
+ HEAPU8.set(buffer, out);
ccall("_emrtc_on_ch_message",
"void",
["number", "number", "number", "number"],
[c_ptr, out, len, is_string]
);
- Module._free(out);
+ _free(out);
}
}, this, js_id);
diff --git a/modules/webrtc/webrtc_multiplayer.cpp b/modules/webrtc/webrtc_multiplayer.cpp
index 78a4d1e61a..e0c0cad68c 100644
--- a/modules/webrtc/webrtc_multiplayer.cpp
+++ b/modules/webrtc/webrtc_multiplayer.cpp
@@ -65,8 +65,9 @@ bool WebRTCMultiplayer::is_server() const {
}
void WebRTCMultiplayer::poll() {
- if (peer_map.size() == 0)
+ if (peer_map.size() == 0) {
return;
+ }
List<int> remove;
List<int> add;
@@ -113,15 +114,17 @@ void WebRTCMultiplayer::poll() {
// Remove disconnected peers
for (List<int>::Element *E = remove.front(); E; E = E->next()) {
remove_peer(E->get());
- if (next_packet_peer == E->get())
+ if (next_packet_peer == E->get()) {
next_packet_peer = 0;
+ }
}
// Signal newly connected peers
for (List<int>::Element *E = add.front(); E; E = E->next()) {
// Already connected to server: simply notify new peer.
// NOTE: Mesh is always connected.
- if (connection_status == CONNECTION_CONNECTED)
+ if (connection_status == CONNECTION_CONNECTED) {
emit_signal("peer_connected", E->get());
+ }
// Server emulation mode suppresses peer_conencted until server connects.
if (server_compat && E->get() == TARGET_PEER_SERVER) {
@@ -131,20 +134,24 @@ void WebRTCMultiplayer::poll() {
emit_signal("connection_succeeded");
// Notify of all previously connected peers
for (Map<int, Ref<ConnectedPeer>>::Element *F = peer_map.front(); F; F = F->next()) {
- if (F->key() != 1 && F->get()->connected)
+ if (F->key() != 1 && F->get()->connected) {
emit_signal("peer_connected", F->key());
+ }
}
break; // Because we already notified of all newly added peers.
}
}
// Fetch next packet
- if (next_packet_peer == 0)
+ if (next_packet_peer == 0) {
_find_next_peer();
+ }
}
void WebRTCMultiplayer::_find_next_peer() {
Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.find(next_packet_peer);
- if (E) E = E->next();
+ if (E) {
+ E = E->next();
+ }
// After last.
while (E) {
for (List<Ref<WebRTCDataChannel>>::Element *F = E->get()->channels.front(); F; F = F->next()) {
@@ -164,8 +171,9 @@ void WebRTCMultiplayer::_find_next_peer() {
return;
}
}
- if (E->key() == (int)next_packet_peer)
+ if (E->key() == (int)next_packet_peer) {
break;
+ }
E = E->next();
}
// No packet found
@@ -190,10 +198,11 @@ Error WebRTCMultiplayer::initialize(int p_self_id, bool p_server_compat) {
server_compat = p_server_compat;
// Mesh and server are always connected
- if (!server_compat || p_self_id == 1)
+ if (!server_compat || p_self_id == 1) {
connection_status = CONNECTION_CONNECTED;
- else
+ } else {
connection_status = CONNECTION_CONNECTING;
+ }
return OK;
}
@@ -319,7 +328,6 @@ Error WebRTCMultiplayer::put_packet(const uint8_t *p_buffer, int p_buffer_size)
Map<int, Ref<ConnectedPeer>>::Element *E = nullptr;
if (target_peer > 0) {
-
E = peer_map.find(target_peer);
ERR_FAIL_COND_V_MSG(!E, ERR_INVALID_PARAMETER, "Invalid target peer: " + itos(target_peer) + ".");
@@ -331,10 +339,10 @@ Error WebRTCMultiplayer::put_packet(const uint8_t *p_buffer, int p_buffer_size)
int exclude = -target_peer;
for (Map<int, Ref<ConnectedPeer>>::Element *F = peer_map.front(); F; F = F->next()) {
-
// Exclude packet. If target_peer == 0 then don't exclude any packets
- if (target_peer != 0 && F->key() == exclude)
+ if (target_peer != 0 && F->key() == exclude) {
continue;
+ }
ERR_CONTINUE(F->value()->channels.size() <= ch || !F->value()->channels[ch].is_valid());
F->value()->channels[ch]->put_packet(p_buffer, p_buffer_size);
@@ -344,8 +352,9 @@ Error WebRTCMultiplayer::put_packet(const uint8_t *p_buffer, int p_buffer_size)
}
int WebRTCMultiplayer::get_available_packet_count() const {
- if (next_packet_peer == 0)
+ if (next_packet_peer == 0) {
return 0; // To be sure next call to get_packet works if size > 0 .
+ }
int size = 0;
for (Map<int, Ref<ConnectedPeer>>::Element *E = peer_map.front(); E; E = E->next()) {
for (List<Ref<WebRTCDataChannel>>::Element *F = E->get()->channels.front(); F; F = F->next()) {
diff --git a/modules/webrtc/webrtc_multiplayer.h b/modules/webrtc/webrtc_multiplayer.h
index 0e1335b8a8..906b90a1b6 100644
--- a/modules/webrtc/webrtc_multiplayer.h
+++ b/modules/webrtc/webrtc_multiplayer.h
@@ -35,7 +35,6 @@
#include "webrtc_peer_connection.h"
class WebRTCMultiplayer : public NetworkedMultiplayerPeer {
-
GDCLASS(WebRTCMultiplayer, NetworkedMultiplayerPeer);
protected:
@@ -50,7 +49,6 @@ private:
};
class ConnectedPeer : public Reference {
-
public:
Ref<WebRTCPeerConnection> connection;
List<Ref<WebRTCDataChannel>> channels;
@@ -58,8 +56,9 @@ private:
ConnectedPeer() {
connected = false;
- for (int i = 0; i < CH_RESERVED_MAX; i++)
+ for (int i = 0; i < CH_RESERVED_MAX; i++) {
channels.push_front(Ref<WebRTCDataChannel>());
+ }
}
};
diff --git a/modules/webrtc/webrtc_peer_connection.cpp b/modules/webrtc/webrtc_peer_connection.cpp
index 399e4f09ff..670924bca2 100644
--- a/modules/webrtc/webrtc_peer_connection.cpp
+++ b/modules/webrtc/webrtc_peer_connection.cpp
@@ -33,14 +33,13 @@
WebRTCPeerConnection *(*WebRTCPeerConnection::_create)() = nullptr;
Ref<WebRTCPeerConnection> WebRTCPeerConnection::create_ref() {
-
return create();
}
WebRTCPeerConnection *WebRTCPeerConnection::create() {
-
- if (!_create)
+ if (!_create) {
return nullptr;
+ }
return _create();
}
diff --git a/modules/webrtc/webrtc_peer_connection_gdnative.cpp b/modules/webrtc/webrtc_peer_connection_gdnative.cpp
index f082646629..aaa45d3a54 100644
--- a/modules/webrtc/webrtc_peer_connection_gdnative.cpp
+++ b/modules/webrtc/webrtc_peer_connection_gdnative.cpp
@@ -49,7 +49,6 @@ Error WebRTCPeerConnectionGDNative::set_default_library(const godot_net_webrtc_l
}
WebRTCPeerConnection *WebRTCPeerConnectionGDNative::_create() {
-
WebRTCPeerConnectionGDNative *obj = memnew(WebRTCPeerConnectionGDNative);
ERR_FAIL_COND_V_MSG(!default_library, obj, "Default GDNative WebRTC implementation not defined.");
diff --git a/modules/webrtc/webrtc_peer_connection_js.h b/modules/webrtc/webrtc_peer_connection_js.h
index 6540077e84..cdaf3068e3 100644
--- a/modules/webrtc/webrtc_peer_connection_js.h
+++ b/modules/webrtc/webrtc_peer_connection_js.h
@@ -36,7 +36,6 @@
#include "webrtc_peer_connection.h"
class WebRTCPeerConnectionJS : public WebRTCPeerConnection {
-
private:
int _js_id;
ConnectionState _conn_state;
diff --git a/modules/websocket/editor_debugger_server_websocket.cpp b/modules/websocket/editor_debugger_server_websocket.cpp
new file mode 100644
index 0000000000..95ea7ceafa
--- /dev/null
+++ b/modules/websocket/editor_debugger_server_websocket.cpp
@@ -0,0 +1,93 @@
+/*************************************************************************/
+/* editor_debugger_server_websocket.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "editor_debugger_server_websocket.h"
+
+#include "core/project_settings.h"
+#include "editor/editor_settings.h"
+#include "modules/websocket/remote_debugger_peer_websocket.h"
+
+void EditorDebuggerServerWebSocket::_peer_connected(int p_id, String _protocol) {
+ pending_peers.push_back(p_id);
+}
+
+void EditorDebuggerServerWebSocket::_peer_disconnected(int p_id, bool p_was_clean) {
+ if (pending_peers.find(p_id)) {
+ pending_peers.erase(p_id);
+ }
+}
+
+void EditorDebuggerServerWebSocket::poll() {
+ server->poll();
+}
+
+Error EditorDebuggerServerWebSocket::start() {
+ int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
+ Vector<String> protocols;
+ protocols.push_back("binary"); // compatibility with EMSCRIPTEN TCP-to-WebSocket layer.
+ return server->listen(remote_port, protocols);
+}
+
+void EditorDebuggerServerWebSocket::stop() {
+ server->stop();
+ pending_peers.clear();
+}
+
+bool EditorDebuggerServerWebSocket::is_active() const {
+ return server->is_listening();
+}
+
+bool EditorDebuggerServerWebSocket::is_connection_available() const {
+ return pending_peers.size() > 0;
+}
+
+Ref<RemoteDebuggerPeer> EditorDebuggerServerWebSocket::take_connection() {
+ ERR_FAIL_COND_V(!is_connection_available(), Ref<RemoteDebuggerPeer>());
+ RemoteDebuggerPeer *peer = memnew(RemoteDebuggerPeerWebSocket(server->get_peer(pending_peers[0])));
+ pending_peers.pop_front();
+ return peer;
+}
+
+EditorDebuggerServerWebSocket::EditorDebuggerServerWebSocket() {
+ server = Ref<WebSocketServer>(WebSocketServer::create());
+ int max_pkts = (int)GLOBAL_GET("network/limits/debugger/max_queued_messages");
+ server->set_buffers(8192, max_pkts, 8192, max_pkts);
+ server->connect("client_connected", callable_mp(this, &EditorDebuggerServerWebSocket::_peer_connected));
+ server->connect("client_disconnected", callable_mp(this, &EditorDebuggerServerWebSocket::_peer_disconnected));
+}
+
+EditorDebuggerServerWebSocket::~EditorDebuggerServerWebSocket() {
+ stop();
+}
+
+EditorDebuggerServer *EditorDebuggerServerWebSocket::create(const String &p_protocol) {
+ ERR_FAIL_COND_V(p_protocol != "ws://", nullptr);
+ return memnew(EditorDebuggerServerWebSocket);
+}
diff --git a/modules/websocket/editor_debugger_server_websocket.h b/modules/websocket/editor_debugger_server_websocket.h
new file mode 100644
index 0000000000..c66db1b72a
--- /dev/null
+++ b/modules/websocket/editor_debugger_server_websocket.h
@@ -0,0 +1,62 @@
+/*************************************************************************/
+/* editor_debugger_server_websocket.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef SCRIPT_EDITOR_DEBUGGER_WEBSOCKET_H
+#define SCRIPT_EDITOR_DEBUGGER_WEBSOCKET_H
+
+#include "modules/websocket/websocket_server.h"
+
+#include "editor/debugger/editor_debugger_server.h"
+
+class EditorDebuggerServerWebSocket : public EditorDebuggerServer {
+ GDCLASS(EditorDebuggerServerWebSocket, EditorDebuggerServer);
+
+private:
+ Ref<WebSocketServer> server;
+ List<int> pending_peers;
+
+public:
+ static EditorDebuggerServer *create(const String &p_protocol);
+
+ void _peer_connected(int p_peer, String p_protocol);
+ void _peer_disconnected(int p_peer, bool p_was_clean);
+
+ void poll();
+ Error start();
+ void stop();
+ bool is_active() const;
+ bool is_connection_available() const;
+ Ref<RemoteDebuggerPeer> take_connection();
+
+ EditorDebuggerServerWebSocket();
+ ~EditorDebuggerServerWebSocket();
+};
+
+#endif // SCRIPT_EDITOR_DEBUGGER_WEBSOCKET_H
diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp
index bbe4d6dc5b..7c31449709 100644
--- a/modules/websocket/emws_client.cpp
+++ b/modules/websocket/emws_client.cpp
@@ -65,7 +65,6 @@ EMSCRIPTEN_KEEPALIVE void _esws_on_close(void *obj, int code, char *reason, int
}
Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector<String> p_protocols, const Vector<String> p_custom_headers) {
-
String proto_string;
for (int i = 0; i < p_protocols.size(); i++) {
if (i != 0)
@@ -142,14 +141,14 @@ Error EMWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
}
var len = buffer.length*buffer.BYTES_PER_ELEMENT;
- var out = Module._malloc(len);
- Module.HEAPU8.set(buffer, out);
+ var out = _malloc(len);
+ HEAPU8.set(buffer, out);
ccall("_esws_on_message",
"void",
["number", "number", "number", "number"],
[c_ptr, out, len, is_string]
);
- Module._free(out);
+ _free(out);
});
socket.addEventListener("error", function (event) {
@@ -190,12 +189,10 @@ void EMWSClient::poll() {
}
Ref<WebSocketPeer> EMWSClient::get_peer(int p_peer_id) const {
-
return _peer;
}
NetworkedMultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() const {
-
if (_peer->is_connected_to_host()) {
if (_is_connecting)
return CONNECTION_CONNECTING;
@@ -206,17 +203,14 @@ NetworkedMultiplayerPeer::ConnectionStatus EMWSClient::get_connection_status() c
};
void EMWSClient::disconnect_from_host(int p_code, String p_reason) {
-
_peer->close(p_code, p_reason);
};
IP_Address EMWSClient::get_connected_host() const {
-
ERR_FAIL_V_MSG(IP_Address(), "Not supported in HTML5 export.");
};
uint16_t EMWSClient::get_connected_port() const {
-
ERR_FAIL_V_MSG(0, "Not supported in HTML5 export.");
};
@@ -231,8 +225,9 @@ Error EMWSClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffe
}
EMWSClient::EMWSClient() {
- _in_buf_size = nearest_shift((int)GLOBAL_GET(WSC_IN_BUF) - 1) + 10;
- _in_pkt_size = nearest_shift((int)GLOBAL_GET(WSC_IN_PKT) - 1);
+ _in_buf_size = DEF_BUF_SHIFT;
+ _in_pkt_size = DEF_PKT_SHIFT;
+
_is_connecting = false;
_peer = Ref<EMWSPeer>(memnew(EMWSPeer));
/* clang-format off */
@@ -243,7 +238,6 @@ EMWSClient::EMWSClient() {
};
EMWSClient::~EMWSClient() {
-
disconnect_from_host();
_peer = Ref<EMWSPeer>();
/* clang-format off */
diff --git a/modules/websocket/emws_client.h b/modules/websocket/emws_client.h
index 9f1c220ed4..ab8a0612bb 100644
--- a/modules/websocket/emws_client.h
+++ b/modules/websocket/emws_client.h
@@ -38,7 +38,6 @@
#include "websocket_client.h"
class EMWSClient : public WebSocketClient {
-
GDCIIMPL(EMWSClient, WebSocketClient);
private:
diff --git a/modules/websocket/emws_peer.cpp b/modules/websocket/emws_peer.cpp
index 9472daa620..749f45451a 100644
--- a/modules/websocket/emws_peer.cpp
+++ b/modules/websocket/emws_peer.cpp
@@ -34,7 +34,6 @@
#include "core/io/ip.h"
void EMWSPeer::set_sock(int p_sock, unsigned int p_in_buf_size, unsigned int p_in_pkt_size) {
-
peer_sock = p_sock;
_in_buffer.resize(p_in_pkt_size, p_in_buf_size);
_packet_buffer.resize((1 << p_in_buf_size));
@@ -49,13 +48,11 @@ EMWSPeer::WriteMode EMWSPeer::get_write_mode() const {
}
Error EMWSPeer::read_msg(uint8_t *p_data, uint32_t p_size, bool p_is_string) {
-
uint8_t is_string = p_is_string ? 1 : 0;
return _in_buffer.write_packet(p_data, p_size, &is_string);
}
Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
-
int is_bin = write_mode == WebSocketPeer::WRITE_MODE_BINARY ? 1 : 0;
/* clang-format off */
@@ -86,7 +83,6 @@ Error EMWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
};
Error EMWSPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
-
if (_in_buffer.packets_left() == 0)
return ERR_UNAVAILABLE;
@@ -101,22 +97,18 @@ Error EMWSPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
};
int EMWSPeer::get_available_packet_count() const {
-
return _in_buffer.packets_left();
};
bool EMWSPeer::was_string_packet() const {
-
return _is_string;
};
bool EMWSPeer::is_connected_to_host() const {
-
return peer_sock != -1;
};
void EMWSPeer::close(int p_code, String p_reason) {
-
if (peer_sock != -1) {
/* clang-format off */
EM_ASM({
@@ -134,17 +126,14 @@ void EMWSPeer::close(int p_code, String p_reason) {
};
IP_Address EMWSPeer::get_connected_host() const {
-
ERR_FAIL_V_MSG(IP_Address(), "Not supported in HTML5 export.");
};
uint16_t EMWSPeer::get_connected_port() const {
-
ERR_FAIL_V_MSG(0, "Not supported in HTML5 export.");
};
void EMWSPeer::set_no_delay(bool p_enabled) {
-
ERR_FAIL_MSG("'set_no_delay' is not supported in HTML5 export.");
}
@@ -155,7 +144,6 @@ EMWSPeer::EMWSPeer() {
};
EMWSPeer::~EMWSPeer() {
-
close();
};
diff --git a/modules/websocket/emws_peer.h b/modules/websocket/emws_peer.h
index 6308ebe490..9c00f2d58b 100644
--- a/modules/websocket/emws_peer.h
+++ b/modules/websocket/emws_peer.h
@@ -41,7 +41,6 @@
#include "websocket_peer.h"
class EMWSPeer : public WebSocketPeer {
-
GDCIIMPL(EMWSPeer, WebSocketPeer);
private:
diff --git a/modules/websocket/emws_server.cpp b/modules/websocket/emws_server.cpp
index 95cffb4775..9d43283d3e 100644
--- a/modules/websocket/emws_server.cpp
+++ b/modules/websocket/emws_server.cpp
@@ -34,7 +34,6 @@
#include "core/os/os.h"
Error EMWSServer::listen(int p_port, Vector<String> p_protocols, bool gd_mp_api) {
-
return FAILED;
}
@@ -60,12 +59,10 @@ Vector<String> EMWSServer::get_protocols() const {
}
IP_Address EMWSServer::get_peer_address(int p_peer_id) const {
-
return IP_Address();
}
int EMWSServer::get_peer_port(int p_peer_id) const {
-
return 0;
}
diff --git a/modules/websocket/emws_server.h b/modules/websocket/emws_server.h
index f273fd078f..bb6f35a711 100644
--- a/modules/websocket/emws_server.h
+++ b/modules/websocket/emws_server.h
@@ -38,7 +38,6 @@
#include "websocket_server.h"
class EMWSServer : public WebSocketServer {
-
GDCIIMPL(EMWSServer, WebSocketServer);
public:
diff --git a/modules/websocket/packet_buffer.h b/modules/websocket/packet_buffer.h
index 5f5f0e20cd..9973efe297 100644
--- a/modules/websocket/packet_buffer.h
+++ b/modules/websocket/packet_buffer.h
@@ -36,7 +36,6 @@
template <class T>
class PacketBuffer {
-
private:
typedef struct {
uint32_t size;
diff --git a/modules/websocket/register_types.cpp b/modules/websocket/register_types.cpp
index e389d75ffd..bc50de414e 100644
--- a/modules/websocket/register_types.cpp
+++ b/modules/websocket/register_types.cpp
@@ -40,24 +40,19 @@
#include "wsl_client.h"
#include "wsl_server.h"
#endif
+#ifdef TOOLS_ENABLED
+#include "editor/debugger/editor_debugger_server.h"
+#include "editor/editor_node.h"
+#include "editor_debugger_server_websocket.h"
+#endif
-void register_websocket_types() {
-#define _SET_HINT(NAME, _VAL_, _MAX_) \
- GLOBAL_DEF(NAME, _VAL_); \
- ProjectSettings::get_singleton()->set_custom_property_info(NAME, PropertyInfo(Variant::INT, NAME, PROPERTY_HINT_RANGE, "2," #_MAX_ ",1,or_greater"));
-
- // Client buffers project settings
- _SET_HINT(WSC_IN_BUF, 64, 4096);
- _SET_HINT(WSC_IN_PKT, 1024, 16384);
- _SET_HINT(WSC_OUT_BUF, 64, 4096);
- _SET_HINT(WSC_OUT_PKT, 1024, 16384);
-
- // Server buffers project settings
- _SET_HINT(WSS_IN_BUF, 64, 4096);
- _SET_HINT(WSS_IN_PKT, 1024, 16384);
- _SET_HINT(WSS_OUT_BUF, 64, 4096);
- _SET_HINT(WSS_OUT_PKT, 1024, 16384);
+#ifdef TOOLS_ENABLED
+static void _editor_init_callback() {
+ EditorDebuggerServer::register_protocol_handler("ws://", EditorDebuggerServerWebSocket::create);
+}
+#endif
+void register_websocket_types() {
#ifdef JAVASCRIPT_ENABLED
EMWSPeer::make_default();
EMWSClient::make_default();
@@ -72,6 +67,10 @@ void register_websocket_types() {
ClassDB::register_custom_instance_class<WebSocketServer>();
ClassDB::register_custom_instance_class<WebSocketClient>();
ClassDB::register_custom_instance_class<WebSocketPeer>();
+
+#ifdef TOOLS_ENABLED
+ EditorNode::add_init_callback(&_editor_init_callback);
+#endif
}
void unregister_websocket_types() {}
diff --git a/modules/websocket/remote_debugger_peer_websocket.cpp b/modules/websocket/remote_debugger_peer_websocket.cpp
new file mode 100644
index 0000000000..a67a959e31
--- /dev/null
+++ b/modules/websocket/remote_debugger_peer_websocket.cpp
@@ -0,0 +1,133 @@
+/*************************************************************************/
+/* remote_debugger_peer_websocket.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "remote_debugger_peer_websocket.h"
+
+#include "core/project_settings.h"
+
+Error RemoteDebuggerPeerWebSocket::connect_to_host(const String &p_uri) {
+ Vector<String> protocols;
+ protocols.push_back("binary"); // Compatibility for emscripten TCP-to-WebSocket.
+
+ ws_client->connect_to_url(p_uri, protocols);
+ ws_client->poll();
+
+ if (ws_client->get_connection_status() == WebSocketClient::CONNECTION_DISCONNECTED) {
+ ERR_PRINT("Remote Debugger: Unable to connect. Status: " + String::num(ws_client->get_connection_status()) + ".");
+ return FAILED;
+ }
+
+ ws_peer = ws_client->get_peer(1);
+
+ return OK;
+}
+
+bool RemoteDebuggerPeerWebSocket::is_peer_connected() {
+ return ws_peer.is_valid() && ws_peer->is_connected_to_host();
+}
+
+void RemoteDebuggerPeerWebSocket::poll() {
+ ws_client->poll();
+
+ while (ws_peer->is_connected_to_host() && ws_peer->get_available_packet_count() > 0 && in_queue.size() < max_queued_messages) {
+ Variant var;
+ Error err = ws_peer->get_var(var);
+ ERR_CONTINUE(err != OK);
+ ERR_CONTINUE(var.get_type() != Variant::ARRAY);
+ in_queue.push_back(var);
+ }
+
+ while (ws_peer->is_connected_to_host() && out_queue.size() > 0) {
+ Array var = out_queue[0];
+ Error err = ws_peer->put_var(var);
+ ERR_BREAK(err != OK); // Peer buffer full?
+ out_queue.pop_front();
+ }
+}
+
+int RemoteDebuggerPeerWebSocket::get_max_message_size() const {
+ return 8 << 20; // 8 Mib
+}
+
+bool RemoteDebuggerPeerWebSocket::has_message() {
+ return in_queue.size() > 0;
+}
+
+Array RemoteDebuggerPeerWebSocket::get_message() {
+ ERR_FAIL_COND_V(in_queue.size() < 1, Array());
+ Array msg = in_queue[0];
+ in_queue.pop_front();
+ return msg;
+}
+
+Error RemoteDebuggerPeerWebSocket::put_message(const Array &p_arr) {
+ if (out_queue.size() >= max_queued_messages) {
+ return ERR_OUT_OF_MEMORY;
+ }
+ out_queue.push_back(p_arr);
+ return OK;
+}
+
+void RemoteDebuggerPeerWebSocket::close() {
+ if (ws_peer.is_valid()) {
+ ws_peer.unref();
+ }
+ ws_client->disconnect_from_host();
+}
+
+bool RemoteDebuggerPeerWebSocket::can_block() const {
+#ifdef JAVASCRIPT_ENABLED
+ return false;
+#else
+ return true;
+#endif
+}
+
+RemoteDebuggerPeerWebSocket::RemoteDebuggerPeerWebSocket(Ref<WebSocketPeer> p_peer) {
+#ifdef JAVASCRIPT_ENABLED
+ ws_client = Ref<WebSocketClient>(memnew(EMWSClient));
+#else
+ ws_client = Ref<WebSocketClient>(memnew(WSLClient));
+#endif
+ max_queued_messages = (int)GLOBAL_GET("network/limits/debugger/max_queued_messages");
+ ws_client->set_buffers(8192, max_queued_messages, 8192, max_queued_messages);
+ ws_peer = p_peer;
+}
+
+RemoteDebuggerPeer *RemoteDebuggerPeerWebSocket::create(const String &p_uri) {
+ ERR_FAIL_COND_V(!p_uri.begins_with("ws://") && !p_uri.begins_with("wss://"), nullptr);
+ RemoteDebuggerPeerWebSocket *peer = memnew(RemoteDebuggerPeerWebSocket);
+ Error err = peer->connect_to_host(p_uri);
+ if (err != OK) {
+ memdelete(peer);
+ return nullptr;
+ }
+ return peer;
+}
diff --git a/modules/websocket/remote_debugger_peer_websocket.h b/modules/websocket/remote_debugger_peer_websocket.h
new file mode 100644
index 0000000000..bb03e5e892
--- /dev/null
+++ b/modules/websocket/remote_debugger_peer_websocket.h
@@ -0,0 +1,65 @@
+/*************************************************************************/
+/* remote_debugger_peer_websocket.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef SCRIPT_DEBUGGER_WEBSOCKET_H
+#define SCRIPT_DEBUGGER_WEBSOCKET_H
+
+#ifdef JAVASCRIPT_ENABLED
+#include "modules/websocket/emws_client.h"
+#else
+#include "modules/websocket/wsl_client.h"
+#endif
+#include "core/debugger/remote_debugger_peer.h"
+
+class RemoteDebuggerPeerWebSocket : public RemoteDebuggerPeer {
+ Ref<WebSocketClient> ws_client;
+ Ref<WebSocketPeer> ws_peer;
+ List<Array> in_queue;
+ List<Array> out_queue;
+
+ int max_queued_messages;
+
+public:
+ static RemoteDebuggerPeer *create(const String &p_uri);
+
+ Error connect_to_host(const String &p_uri);
+ bool is_peer_connected();
+ int get_max_message_size() const;
+ bool has_message();
+ Error put_message(const Array &p_arr);
+ Array get_message();
+ void close();
+ void poll();
+ bool can_block() const;
+
+ RemoteDebuggerPeerWebSocket(Ref<WebSocketPeer> p_peer = Ref<WebSocketPeer>());
+};
+
+#endif // SCRIPT_DEBUGGER_WEBSOCKET_H
diff --git a/modules/websocket/websocket_client.cpp b/modules/websocket/websocket_client.cpp
index 7ee4b990b5..3900180739 100644
--- a/modules/websocket/websocket_client.cpp
+++ b/modules/websocket/websocket_client.cpp
@@ -33,7 +33,6 @@
GDCINULL(WebSocketClient);
WebSocketClient::WebSocketClient() {
-
verify_ssl = true;
}
@@ -54,8 +53,9 @@ Error WebSocketClient::connect_to_url(String p_url, const Vector<String> p_proto
port = 443;
} else {
ssl = false;
- if (host.begins_with("ws://"))
+ if (host.begins_with("ws://")) {
host = host.substr(5, host.length() - 5);
+ }
}
// Path
@@ -76,33 +76,27 @@ Error WebSocketClient::connect_to_url(String p_url, const Vector<String> p_proto
}
void WebSocketClient::set_verify_ssl_enabled(bool p_verify_ssl) {
-
verify_ssl = p_verify_ssl;
}
bool WebSocketClient::is_verify_ssl_enabled() const {
-
return verify_ssl;
}
Ref<X509Certificate> WebSocketClient::get_trusted_ssl_certificate() const {
-
return ssl_cert;
}
void WebSocketClient::set_trusted_ssl_certificate(Ref<X509Certificate> p_cert) {
-
ERR_FAIL_COND(get_connection_status() != CONNECTION_DISCONNECTED);
ssl_cert = p_cert;
}
bool WebSocketClient::is_server() const {
-
return false;
}
void WebSocketClient::_on_peer_packet() {
-
if (_is_multiplayer) {
_process_multiplayer(get_peer(1), 1);
} else {
@@ -111,7 +105,6 @@ void WebSocketClient::_on_peer_packet() {
}
void WebSocketClient::_on_connect(String p_protocol) {
-
if (_is_multiplayer) {
// need to wait for ID confirmation...
} else {
@@ -120,12 +113,10 @@ void WebSocketClient::_on_connect(String p_protocol) {
}
void WebSocketClient::_on_close_request(int p_code, String p_reason) {
-
emit_signal("server_close_request", p_code, p_reason);
}
void WebSocketClient::_on_disconnect(bool p_was_clean) {
-
if (_is_multiplayer) {
emit_signal("connection_failed");
} else {
@@ -134,7 +125,6 @@ void WebSocketClient::_on_disconnect(bool p_was_clean) {
}
void WebSocketClient::_on_error() {
-
if (_is_multiplayer) {
emit_signal("connection_failed");
} else {
diff --git a/modules/websocket/websocket_client.h b/modules/websocket/websocket_client.h
index 4dc1224066..ba8e21aed6 100644
--- a/modules/websocket/websocket_client.h
+++ b/modules/websocket/websocket_client.h
@@ -37,7 +37,6 @@
#include "websocket_peer.h"
class WebSocketClient : public WebSocketMultiplayerPeer {
-
GDCLASS(WebSocketClient, WebSocketMultiplayerPeer);
GDCICLASS(WebSocketClient);
diff --git a/modules/websocket/websocket_macros.h b/modules/websocket/websocket_macros.h
index f7eafcff1f..cf4545b435 100644
--- a/modules/websocket/websocket_macros.h
+++ b/modules/websocket/websocket_macros.h
@@ -31,15 +31,9 @@
#ifndef WEBSOCKETMACTOS_H
#define WEBSOCKETMACTOS_H
-#define WSC_IN_BUF "network/limits/websocket_client/max_in_buffer_kb"
-#define WSC_IN_PKT "network/limits/websocket_client/max_in_packets"
-#define WSC_OUT_BUF "network/limits/websocket_client/max_out_buffer_kb"
-#define WSC_OUT_PKT "network/limits/websocket_client/max_out_packets"
-
-#define WSS_IN_BUF "network/limits/websocket_server/max_in_buffer_kb"
-#define WSS_IN_PKT "network/limits/websocket_server/max_in_packets"
-#define WSS_OUT_BUF "network/limits/websocket_server/max_out_buffer_kb"
-#define WSS_OUT_PKT "network/limits/websocket_server/max_out_packets"
+// Defaults per peer buffers, 1024 packets with a shared 65536 bytes payload.
+#define DEF_PKT_SHIFT 10
+#define DEF_BUF_SHIFT 16
/* clang-format off */
#define GDCICLASS(CNAME) \
diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp
index 9b71b32e33..fa2fe891a5 100644
--- a/modules/websocket/websocket_multiplayer_peer.cpp
+++ b/modules/websocket/websocket_multiplayer_peer.cpp
@@ -33,7 +33,6 @@
#include "core/os/os.h"
WebSocketMultiplayerPeer::WebSocketMultiplayerPeer() {
-
_is_multiplayer = false;
_peer_id = 0;
_target_peer = 0;
@@ -46,16 +45,13 @@ WebSocketMultiplayerPeer::WebSocketMultiplayerPeer() {
}
WebSocketMultiplayerPeer::~WebSocketMultiplayerPeer() {
-
_clear();
}
int WebSocketMultiplayerPeer::_gen_unique_id() const {
-
uint32_t hash = 0;
while (hash == 0 || hash == 1) {
-
hash = hash_djb2_one_32(
(uint32_t)OS::get_singleton()->get_ticks_usec());
hash = hash_djb2_one_32(
@@ -71,11 +67,12 @@ int WebSocketMultiplayerPeer::_gen_unique_id() const {
return hash;
}
-void WebSocketMultiplayerPeer::_clear() {
+void WebSocketMultiplayerPeer::_clear() {
_peer_map.clear();
- if (_current_packet.data != nullptr)
+ if (_current_packet.data != nullptr) {
memfree(_current_packet.data);
+ }
for (List<Packet>::Element *E = _incoming_packets.front(); E; E = E->next()) {
memfree(E->get().data);
@@ -86,7 +83,6 @@ void WebSocketMultiplayerPeer::_clear() {
}
void WebSocketMultiplayerPeer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_buffers", "input_buffer_size_kb", "input_max_packets", "output_buffer_size_kb", "output_max_packets"), &WebSocketMultiplayerPeer::set_buffers);
ClassDB::bind_method(D_METHOD("get_peer", "peer_id"), &WebSocketMultiplayerPeer::get_peer);
@@ -97,14 +93,12 @@ void WebSocketMultiplayerPeer::_bind_methods() {
// PacketPeer
//
int WebSocketMultiplayerPeer::get_available_packet_count() const {
-
ERR_FAIL_COND_V_MSG(!_is_multiplayer, 0, "Please use get_peer(ID).get_available_packet_count to get available packet count from peers when not using the MultiplayerAPI.");
return _incoming_packets.size();
}
Error WebSocketMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
-
ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).get_packet/var to communicate with peers when not using the MultiplayerAPI.");
r_buffer_size = 0;
@@ -124,7 +118,6 @@ Error WebSocketMultiplayerPeer::get_packet(const uint8_t **r_buffer, int &r_buff
}
Error WebSocketMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
-
ERR_FAIL_COND_V_MSG(!_is_multiplayer, ERR_UNCONFIGURED, "Please use get_peer(ID).put_packet/var to communicate with peers when not using the MultiplayerAPI.");
Vector<uint8_t> buffer = _make_pkt(SYS_NONE, get_unique_id(), _target_peer, p_buffer, p_buffer_size);
@@ -140,23 +133,19 @@ Error WebSocketMultiplayerPeer::put_packet(const uint8_t *p_buffer, int p_buffer
// NetworkedMultiplayerPeer
//
void WebSocketMultiplayerPeer::set_transfer_mode(TransferMode p_mode) {
-
// Websocket uses TCP, reliable
}
NetworkedMultiplayerPeer::TransferMode WebSocketMultiplayerPeer::get_transfer_mode() const {
-
// Websocket uses TCP, reliable
return TRANSFER_MODE_RELIABLE;
}
void WebSocketMultiplayerPeer::set_target_peer(int p_target_peer) {
-
_target_peer = p_target_peer;
}
int WebSocketMultiplayerPeer::get_packet_peer() const {
-
ERR_FAIL_COND_V_MSG(!_is_multiplayer, 1, "This function is not available when not using the MultiplayerAPI.");
ERR_FAIL_COND_V(_incoming_packets.size() == 0, 1);
@@ -164,22 +153,18 @@ int WebSocketMultiplayerPeer::get_packet_peer() const {
}
int WebSocketMultiplayerPeer::get_unique_id() const {
-
return _peer_id;
}
void WebSocketMultiplayerPeer::set_refuse_new_connections(bool p_enable) {
-
_refusing = p_enable;
}
bool WebSocketMultiplayerPeer::is_refusing_new_connections() const {
-
return _refusing;
}
void WebSocketMultiplayerPeer::_send_sys(Ref<WebSocketPeer> p_peer, uint8_t p_type, int32_t p_peer_id) {
-
ERR_FAIL_COND(!p_peer.is_valid());
ERR_FAIL_COND(!p_peer->is_connected_to_host());
@@ -188,7 +173,6 @@ void WebSocketMultiplayerPeer::_send_sys(Ref<WebSocketPeer> p_peer, uint8_t p_ty
}
Vector<uint8_t> WebSocketMultiplayerPeer::_make_pkt(uint8_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size) {
-
Vector<uint8_t> out;
out.resize(PROTO_SIZE + p_data_size);
@@ -202,7 +186,6 @@ Vector<uint8_t> WebSocketMultiplayerPeer::_make_pkt(uint8_t p_type, int32_t p_fr
}
void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) {
-
// First of all, confirm the ID!
_send_sys(get_peer(p_peer_id), SYS_ID, p_peer_id);
@@ -211,8 +194,9 @@ void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) {
for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) {
int32_t id = E->key();
- if (p_peer_id == id)
+ if (p_peer_id == id) {
continue; // Skip the newwly added peer (already confirmed)
+ }
// Send new peer to others
_send_sys(get_peer(id), SYS_ADD, p_peer_id);
@@ -224,8 +208,9 @@ void WebSocketMultiplayerPeer::_send_add(int32_t p_peer_id) {
void WebSocketMultiplayerPeer::_send_del(int32_t p_peer_id) {
for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) {
int32_t id = E->key();
- if (p_peer_id != id)
+ if (p_peer_id != id) {
_send_sys(get_peer(id), SYS_DEL, p_peer_id);
+ }
}
}
@@ -242,27 +227,25 @@ void WebSocketMultiplayerPeer::_store_pkt(int32_t p_source, int32_t p_dest, cons
Error WebSocketMultiplayerPeer::_server_relay(int32_t p_from, int32_t p_to, const uint8_t *p_buffer, uint32_t p_buffer_size) {
if (p_to == 1) {
-
return OK; // Will not send to self
} else if (p_to == 0) {
-
for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) {
- if (E->key() != p_from)
+ if (E->key() != p_from) {
E->get()->put_packet(p_buffer, p_buffer_size);
+ }
}
return OK; // Sent to all but sender
} else if (p_to < 0) {
-
for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) {
- if (E->key() != p_from && E->key() != -p_to)
+ if (E->key() != p_from && E->key() != -p_to) {
E->get()->put_packet(p_buffer, p_buffer_size);
+ }
}
return OK; // Sent to all but sender and excluded
} else {
-
ERR_FAIL_COND_V(p_to == p_from, FAILED);
Ref<WebSocketPeer> peer_to = get_peer(p_to);
@@ -273,7 +256,6 @@ Error WebSocketMultiplayerPeer::_server_relay(int32_t p_from, int32_t p_to, cons
}
void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, uint32_t p_peer_id) {
-
ERR_FAIL_COND(!p_peer.is_valid());
const uint8_t *in_buffer;
@@ -304,21 +286,19 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u
_store_pkt(from, to, in_buffer, data_size);
} else if (to == 0) {
-
// Broadcast, for us too
_store_pkt(from, to, in_buffer, data_size);
} else if (to < 0) {
-
// All but one, for us if not excluded
- if (_peer_id != -(int32_t)p_peer_id)
+ if (_peer_id != -(int32_t)p_peer_id) {
_store_pkt(from, to, in_buffer, data_size);
+ }
}
// Relay if needed (i.e. "to" includes a peer that is not the server)
_server_relay(from, to, in_buffer, size);
} else {
-
if (type == SYS_NONE) { // Payload message
_store_pkt(from, to, in_buffer, data_size);
@@ -331,12 +311,12 @@ void WebSocketMultiplayerPeer::_process_multiplayer(Ref<WebSocketPeer> p_peer, u
copymem(&id, &in_buffer[PROTO_SIZE], 4);
switch (type) {
-
case SYS_ADD: // Add peer
_peer_map[id] = Ref<WebSocketPeer>();
emit_signal("peer_connected", id);
- if (id == 1) // We just connected to the server
+ if (id == 1) { // We just connected to the server
emit_signal("connection_succeeded");
+ }
break;
case SYS_DEL: // Remove peer
diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h
index c6669c730c..3ee26e2c5b 100644
--- a/modules/websocket/websocket_multiplayer_peer.h
+++ b/modules/websocket/websocket_multiplayer_peer.h
@@ -37,7 +37,6 @@
#include "websocket_peer.h"
class WebSocketMultiplayerPeer : public NetworkedMultiplayerPeer {
-
GDCLASS(WebSocketMultiplayerPeer, NetworkedMultiplayerPeer);
private:
diff --git a/modules/websocket/websocket_peer.h b/modules/websocket/websocket_peer.h
index d4173600ec..5f7d1c768b 100644
--- a/modules/websocket/websocket_peer.h
+++ b/modules/websocket/websocket_peer.h
@@ -36,7 +36,6 @@
#include "websocket_macros.h"
class WebSocketPeer : public PacketPeer {
-
GDCLASS(WebSocketPeer, PacketPeer);
GDCICLASS(WebSocketPeer);
diff --git a/modules/websocket/websocket_server.cpp b/modules/websocket/websocket_server.cpp
index a7ced65543..b20b925dec 100644
--- a/modules/websocket/websocket_server.cpp
+++ b/modules/websocket/websocket_server.cpp
@@ -41,7 +41,6 @@ WebSocketServer::~WebSocketServer() {
}
void WebSocketServer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("is_listening"), &WebSocketServer::is_listening);
ClassDB::bind_method(D_METHOD("listen", "port", "protocols", "gd_mp_api"), &WebSocketServer::listen, DEFVAL(Vector<String>()), DEFVAL(false));
ClassDB::bind_method(D_METHOD("stop"), &WebSocketServer::stop);
@@ -110,19 +109,18 @@ void WebSocketServer::set_ca_chain(Ref<X509Certificate> p_ca_chain) {
}
NetworkedMultiplayerPeer::ConnectionStatus WebSocketServer::get_connection_status() const {
- if (is_listening())
+ if (is_listening()) {
return CONNECTION_CONNECTED;
+ }
return CONNECTION_DISCONNECTED;
}
bool WebSocketServer::is_server() const {
-
return true;
}
void WebSocketServer::_on_peer_packet(int32_t p_peer_id) {
-
if (_is_multiplayer) {
_process_multiplayer(get_peer(p_peer_id), p_peer_id);
} else {
@@ -131,7 +129,6 @@ void WebSocketServer::_on_peer_packet(int32_t p_peer_id) {
}
void WebSocketServer::_on_connect(int32_t p_peer_id, String p_protocol) {
-
if (_is_multiplayer) {
// Send add to clients
_send_add(p_peer_id);
@@ -142,7 +139,6 @@ void WebSocketServer::_on_connect(int32_t p_peer_id, String p_protocol) {
}
void WebSocketServer::_on_disconnect(int32_t p_peer_id, bool p_was_clean) {
-
if (_is_multiplayer) {
// Send delete to clients
_send_del(p_peer_id);
@@ -153,6 +149,5 @@ void WebSocketServer::_on_disconnect(int32_t p_peer_id, bool p_was_clean) {
}
void WebSocketServer::_on_close_request(int32_t p_peer_id, int p_code, String p_reason) {
-
emit_signal("client_close_request", p_peer_id, p_code, p_reason);
}
diff --git a/modules/websocket/websocket_server.h b/modules/websocket/websocket_server.h
index 3ce4dbe711..5df0a37945 100644
--- a/modules/websocket/websocket_server.h
+++ b/modules/websocket/websocket_server.h
@@ -37,7 +37,6 @@
#include "websocket_peer.h"
class WebSocketServer : public WebSocketMultiplayerPeer {
-
GDCLASS(WebSocketServer, WebSocketMultiplayerPeer);
GDCICLASS(WebSocketServer);
diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp
index 9f05500eb9..7d16c2e99f 100644
--- a/modules/websocket/wsl_client.cpp
+++ b/modules/websocket/wsl_client.cpp
@@ -117,10 +117,11 @@ bool WSLClient::_verify_headers(String &r_protocol) {
ERR_FAIL_COND_V_MSG(header.size() != 2, false, "Invalid header -> " + psa[i] + ".");
String name = header[0].to_lower();
String value = header[1].strip_edges();
- if (headers.has(name))
+ if (headers.has(name)) {
headers[name] += "," + value;
- else
+ } else {
headers[name] = value;
+ }
}
#define _WSL_CHECK(NAME, VALUE) \
@@ -142,19 +143,20 @@ bool WSLClient::_verify_headers(String &r_protocol) {
r_protocol = headers["sec-websocket-protocol"];
bool valid = false;
for (int i = 0; i < _protocols.size(); i++) {
- if (_protocols[i] != r_protocol)
+ if (_protocols[i] != r_protocol) {
continue;
+ }
valid = true;
break;
}
- if (!valid)
+ if (!valid) {
return false;
+ }
}
return true;
}
Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, const Vector<String> p_protocols, const Vector<String> p_custom_headers) {
-
ERR_FAIL_COND_V(_connection.is_valid(), ERR_ALREADY_IN_USE);
_peer = Ref<WSLPeer>(memnew(WSLPeer));
@@ -200,8 +202,9 @@ Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port,
if (p_protocols.size() > 0) {
request += "Sec-WebSocket-Protocol: ";
for (int i = 0; i < p_protocols.size(); i++) {
- if (i != 0)
+ if (i != 0) {
request += ",";
+ }
request += p_protocols[i];
}
request += "\r\n";
@@ -229,8 +232,9 @@ void WSLClient::poll() {
return;
}
- if (_connection.is_null())
+ if (_connection.is_null()) {
return; // Not connected.
+ }
switch (_tcp->get_status()) {
case StreamPeerTCP::STATUS_NONE:
@@ -257,9 +261,9 @@ void WSLClient::poll() {
ERR_FAIL_COND(ssl.is_null()); // Bug?
ssl->poll();
}
- if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING)
+ if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING) {
return; // Need more polling.
- else if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED) {
+ } else if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED) {
disconnect_from_host();
_on_error();
return; // Error.
@@ -278,25 +282,24 @@ void WSLClient::poll() {
}
Ref<WebSocketPeer> WSLClient::get_peer(int p_peer_id) const {
-
ERR_FAIL_COND_V(p_peer_id != 1, nullptr);
return _peer;
}
NetworkedMultiplayerPeer::ConnectionStatus WSLClient::get_connection_status() const {
-
- if (_peer->is_connected_to_host())
+ if (_peer->is_connected_to_host()) {
return CONNECTION_CONNECTED;
+ }
- if (_tcp->is_connected_to_host())
+ if (_tcp->is_connected_to_host()) {
return CONNECTION_CONNECTING;
+ }
return CONNECTION_DISCONNECTED;
}
void WSLClient::disconnect_from_host(int p_code, String p_reason) {
-
_peer->close(p_code, p_reason);
_connection = Ref<StreamPeer>(nullptr);
_tcp = Ref<StreamPeerTCP>(memnew(StreamPeerTCP));
@@ -314,13 +317,11 @@ void WSLClient::disconnect_from_host(int p_code, String p_reason) {
}
IP_Address WSLClient::get_connected_host() const {
-
ERR_FAIL_COND_V(!_peer->is_connected_to_host(), IP_Address());
return _peer->get_connected_host();
}
uint16_t WSLClient::get_connected_port() const {
-
ERR_FAIL_COND_V(!_peer->is_connected_to_host(), 0);
return _peer->get_connected_port();
}
@@ -336,10 +337,10 @@ Error WSLClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer
}
WSLClient::WSLClient() {
- _in_buf_size = nearest_shift((int)GLOBAL_GET(WSC_IN_BUF) - 1) + 10;
- _in_pkt_size = nearest_shift((int)GLOBAL_GET(WSC_IN_PKT) - 1);
- _out_buf_size = nearest_shift((int)GLOBAL_GET(WSC_OUT_BUF) - 1) + 10;
- _out_pkt_size = nearest_shift((int)GLOBAL_GET(WSC_OUT_PKT) - 1);
+ _in_buf_size = DEF_BUF_SHIFT;
+ _in_pkt_size = DEF_PKT_SHIFT;
+ _out_buf_size = DEF_BUF_SHIFT;
+ _out_pkt_size = DEF_PKT_SHIFT;
_peer.instance();
_tcp.instance();
@@ -347,7 +348,6 @@ WSLClient::WSLClient() {
}
WSLClient::~WSLClient() {
-
_peer->close_now();
_peer->invalidate();
disconnect_from_host();
diff --git a/modules/websocket/wsl_client.h b/modules/websocket/wsl_client.h
index 2cecfd97ee..8355a5a737 100644
--- a/modules/websocket/wsl_client.h
+++ b/modules/websocket/wsl_client.h
@@ -41,7 +41,6 @@
#include "wslay/wslay.h"
class WSLClient : public WebSocketClient {
-
GDCIIMPL(WSLClient, WebSocketClient);
private:
diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp
index 44b71f70f4..bf1ba43f8a 100644
--- a/modules/websocket/wsl_peer.cpp
+++ b/modules/websocket/wsl_peer.cpp
@@ -60,8 +60,9 @@ String WSLPeer::compute_key_response(String p_key) {
}
void WSLPeer::_wsl_destroy(struct PeerData **p_data) {
- if (!p_data || !(*p_data))
+ if (!p_data || !(*p_data)) {
return;
+ }
struct PeerData *data = *p_data;
if (data->polling) {
data->destroy = true;
@@ -147,8 +148,9 @@ void wsl_msg_recv_callback(wslay_event_context_ptr ctx, const struct wslay_event
}
WSLPeer *peer = (WSLPeer *)peer_data->peer;
- if (peer->parse_message(arg) != OK)
+ if (peer->parse_message(arg) != OK) {
return;
+ }
if (peer_data->is_server) {
WSLServer *helper = (WSLServer *)peer_data->obj;
@@ -209,10 +211,11 @@ void WSLPeer::make_context(PeerData *p_data, unsigned int p_in_buf_size, unsigne
_data->peer = this;
_data->valid = true;
- if (_data->is_server)
+ if (_data->is_server) {
wslay_event_context_server_init(&(_data->ctx), &wsl_callbacks, _data);
- else
+ } else {
wslay_event_context_client_init(&(_data->ctx), &wsl_callbacks, _data);
+ }
wslay_event_config_set_max_recv_msg_length(_data->ctx, (1ULL << p_in_buf_size));
}
@@ -225,8 +228,9 @@ WSLPeer::WriteMode WSLPeer::get_write_mode() const {
}
void WSLPeer::poll() {
- if (!_data)
+ if (!_data) {
return;
+ }
if (_wsl_poll(_data)) {
_data = nullptr;
@@ -234,7 +238,6 @@ void WSLPeer::poll() {
}
Error WSLPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
-
ERR_FAIL_COND_V(!is_connected_to_host(), FAILED);
struct wslay_event_msg msg; // Should I use fragmented?
@@ -251,13 +254,13 @@ Error WSLPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
}
Error WSLPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
-
r_buffer_size = 0;
ERR_FAIL_COND_V(!is_connected_to_host(), FAILED);
- if (_in_buffer.packets_left() == 0)
+ if (_in_buffer.packets_left() == 0) {
return ERR_UNAVAILABLE;
+ }
int read = 0;
uint8_t *rw = _packet_buffer.ptrw();
@@ -270,20 +273,18 @@ Error WSLPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) {
}
int WSLPeer::get_available_packet_count() const {
-
- if (!is_connected_to_host())
+ if (!is_connected_to_host()) {
return 0;
+ }
return _in_buffer.packets_left();
}
bool WSLPeer::was_string_packet() const {
-
return _is_string;
}
bool WSLPeer::is_connected_to_host() const {
-
return _data != nullptr;
}
@@ -305,28 +306,26 @@ void WSLPeer::close(int p_code, String p_reason) {
}
IP_Address WSLPeer::get_connected_host() const {
-
ERR_FAIL_COND_V(!is_connected_to_host() || _data->tcp.is_null(), IP_Address());
return _data->tcp->get_connected_host();
}
uint16_t WSLPeer::get_connected_port() const {
-
ERR_FAIL_COND_V(!is_connected_to_host() || _data->tcp.is_null(), 0);
return _data->tcp->get_connected_port();
}
void WSLPeer::set_no_delay(bool p_enabled) {
-
ERR_FAIL_COND(!is_connected_to_host() || _data->tcp.is_null());
_data->tcp->set_no_delay(p_enabled);
}
void WSLPeer::invalidate() {
- if (_data)
+ if (_data) {
_data->valid = false;
+ }
}
WSLPeer::WSLPeer() {
@@ -337,7 +336,6 @@ WSLPeer::WSLPeer() {
}
WSLPeer::~WSLPeer() {
-
close();
invalidate();
_wsl_destroy(&_data);
diff --git a/modules/websocket/wsl_peer.h b/modules/websocket/wsl_peer.h
index 3b0639831a..fe4abfb64c 100644
--- a/modules/websocket/wsl_peer.h
+++ b/modules/websocket/wsl_peer.h
@@ -44,7 +44,6 @@
#define WSL_MAX_HEADER_SIZE 4096
class WSLPeer : public WebSocketPeer {
-
GDCIIMPL(WSLPeer, WebSocketPeer);
public:
diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp
index 6f155a6ffa..da7bfc70c0 100644
--- a/modules/websocket/wsl_server.cpp
+++ b/modules/websocket/wsl_server.cpp
@@ -60,10 +60,11 @@ bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols) {
ERR_FAIL_COND_V_MSG(header.size() != 2, false, "Invalid header -> " + psa[i]);
String name = header[0].to_lower();
String value = header[1].strip_edges();
- if (headers.has(name))
+ if (headers.has(name)) {
headers[name] += "," + value;
- else
+ } else {
headers[name] = value;
+ }
}
#define _WSL_CHECK(NAME, VALUE) \
ERR_FAIL_COND_V_MSG(!headers.has(NAME) || headers[NAME].to_lower() != VALUE, false, \
@@ -83,44 +84,52 @@ bool WSLServer::PendingPeer::_parse_request(const Vector<String> p_protocols) {
String proto = protos[i].strip_edges();
// Check if we have the given protocol
for (int j = 0; j < p_protocols.size(); j++) {
- if (proto != p_protocols[j])
+ if (proto != p_protocols[j]) {
continue;
+ }
protocol = proto;
break;
}
// Found a protocol
- if (protocol != "")
+ if (protocol != "") {
break;
+ }
}
- if (protocol == "") // Invalid protocol(s) requested
+ if (protocol == "") { // Invalid protocol(s) requested
return false;
- } else if (p_protocols.size() > 0) // No protocol requested, but we need one
+ }
+ } else if (p_protocols.size() > 0) { // No protocol requested, but we need one
return false;
+ }
return true;
}
Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols) {
- if (OS::get_singleton()->get_ticks_msec() - time > WSL_SERVER_TIMEOUT)
+ if (OS::get_singleton()->get_ticks_msec() - time > WSL_SERVER_TIMEOUT) {
return ERR_TIMEOUT;
+ }
if (use_ssl) {
Ref<StreamPeerSSL> ssl = static_cast<Ref<StreamPeerSSL>>(connection);
- if (ssl.is_null())
+ if (ssl.is_null()) {
return FAILED;
+ }
ssl->poll();
- if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING)
+ if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING) {
return ERR_BUSY;
- else if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED)
+ } else if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED) {
return FAILED;
+ }
}
if (!has_request) {
int read = 0;
while (true) {
ERR_FAIL_COND_V_MSG(req_pos >= WSL_MAX_HEADER_SIZE, ERR_OUT_OF_MEMORY, "Response headers too big.");
Error err = connection->get_partial_data(&req_buf[req_pos], 1, read);
- if (err != OK) // Got an error
+ if (err != OK) { // Got an error
return FAILED;
- else if (read != 1) // Busy, wait next poll
+ } else if (read != 1) { // Busy, wait next poll
return ERR_BUSY;
+ }
char *r = (char *)req_buf;
int l = req_pos;
if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') {
@@ -132,8 +141,9 @@ Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols) {
s += "Upgrade: websocket\r\n";
s += "Connection: Upgrade\r\n";
s += "Sec-WebSocket-Accept: " + WSLPeer::compute_key_response(key) + "\r\n";
- if (protocol != "")
+ if (protocol != "") {
s += "Sec-WebSocket-Protocol: " + protocol + "\r\n";
+ }
s += "\r\n";
response = s.utf8();
has_request = true;
@@ -150,8 +160,9 @@ Error WSLServer::PendingPeer::do_handshake(const Vector<String> p_protocols) {
}
response_sent += sent;
}
- if (response_sent < response.size() - 1)
+ if (response_sent < response.size() - 1) {
return ERR_BUSY;
+ }
return OK;
}
@@ -169,7 +180,6 @@ Error WSLServer::listen(int p_port, const Vector<String> p_protocols, bool gd_mp
}
void WSLServer::poll() {
-
List<int> remove_ids;
for (Map<int, Ref<WebSocketPeer>>::Element *E = _peer_map.front(); E; E = E->next()) {
Ref<WSLPeer> peer = (WSLPeer *)E->get().ptr();
@@ -217,13 +227,15 @@ void WSLServer::poll() {
}
remove_peers.clear();
- if (!_server->is_listening())
+ if (!_server->is_listening()) {
return;
+ }
while (_server->is_connection_available()) {
Ref<StreamPeerTCP> conn = _server->take_connection();
- if (is_refusing_new_connections())
+ if (is_refusing_new_connections()) {
continue; // Conn will go out-of-scope and be closed.
+ }
Ref<PendingPeer> peer = memnew(PendingPeer);
if (private_key.is_valid() && ssl_cert.is_valid()) {
@@ -298,10 +310,10 @@ Error WSLServer::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer
}
WSLServer::WSLServer() {
- _in_buf_size = nearest_shift((int)GLOBAL_GET(WSS_IN_BUF) - 1) + 10;
- _in_pkt_size = nearest_shift((int)GLOBAL_GET(WSS_IN_PKT) - 1);
- _out_buf_size = nearest_shift((int)GLOBAL_GET(WSS_OUT_BUF) - 1) + 10;
- _out_pkt_size = nearest_shift((int)GLOBAL_GET(WSS_OUT_PKT) - 1);
+ _in_buf_size = DEF_BUF_SHIFT;
+ _in_pkt_size = DEF_PKT_SHIFT;
+ _out_buf_size = DEF_BUF_SHIFT;
+ _out_pkt_size = DEF_PKT_SHIFT;
_server.instance();
}
diff --git a/modules/websocket/wsl_server.h b/modules/websocket/wsl_server.h
index 2e893d6727..f86de02797 100644
--- a/modules/websocket/wsl_server.h
+++ b/modules/websocket/wsl_server.h
@@ -43,12 +43,10 @@
#define WSL_SERVER_TIMEOUT 1000
class WSLServer : public WebSocketServer {
-
GDCIIMPL(WSLServer, WebSocketServer);
private:
class PendingPeer : public Reference {
-
private:
bool _parse_request(const Vector<String> p_protocols);
diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp
index e293dfd50c..6242009f67 100644
--- a/modules/xatlas_unwrap/register_types.cpp
+++ b/modules/xatlas_unwrap/register_types.cpp
@@ -32,14 +32,90 @@
#include "core/error_macros.h"
+#include "core/crypto/crypto_core.h"
+
#include "thirdparty/xatlas/xatlas.h"
#include <stdio.h>
#include <stdlib.h>
-extern bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y);
+extern bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y, int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache);
+
+bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, int p_index_count, float **r_uvs, int **r_vertices, int *r_vertex_count, int **r_indices, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y, int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache) {
+ CryptoCore::MD5Context ctx;
+ ctx.start();
+
+ ctx.update((unsigned char *)&p_texel_size, sizeof(float));
+ ctx.update((unsigned char *)p_indices, sizeof(int) * p_index_count);
+ ctx.update((unsigned char *)p_vertices, sizeof(float) * p_vertex_count);
+ ctx.update((unsigned char *)p_normals, sizeof(float) * p_vertex_count);
+
+ unsigned char hash[16];
+ ctx.finish(hash);
+
+ bool cached = false;
+ unsigned int cache_idx = 0;
+
+ if (r_used_cache && r_cache_size) {
+ //Check if hash is in cache data
+
+ int *cache_data = r_cache_data;
+ int n_entries = cache_data[0];
+ unsigned int r_idx = 1;
+ for (int i = 0; i < n_entries; ++i) {
+ if (memcmp(&cache_data[r_idx], hash, 16) == 0) {
+ cached = true;
+ cache_idx = r_idx;
+ break;
+ }
+
+ r_idx += 4; // hash
+ r_idx += 2; // size hint
+
+ int vertex_count = cache_data[r_idx];
+ r_idx += 1; // vertex count
+ r_idx += vertex_count; // vertex
+ r_idx += vertex_count * 2; // uvs
+
+ int index_count = cache_data[r_idx];
+ r_idx += 1; // index count
+ r_idx += index_count; // indices
+ }
+ }
+
+ if (r_used_cache && cached) {
+ int *cache_data = r_cache_data;
-bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) {
+ // Return cache data pointer to the caller
+ r_cache_data = &cache_data[cache_idx];
+
+ cache_idx += 4;
+
+ // Load size
+ *r_size_hint_x = cache_data[cache_idx];
+ *r_size_hint_y = cache_data[cache_idx + 1];
+ cache_idx += 2;
+
+ // Load vertices
+ *r_vertex_count = cache_data[cache_idx];
+ cache_idx++;
+ *r_vertices = &cache_data[cache_idx];
+ cache_idx += *r_vertex_count;
+
+ // Load UVs
+ *r_uvs = (float *)&cache_data[cache_idx];
+ cache_idx += *r_vertex_count * 2;
+
+ // Load indices
+ *r_index_count = cache_data[cache_idx];
+ cache_idx++;
+ *r_indices = &cache_data[cache_idx];
+
+ // Return cache data size to the caller
+ r_cache_size = sizeof(int) * (4 + 2 + 1 + *r_vertex_count + (*r_vertex_count * 2) + 1 + *r_index_count); // hash + size hint + vertex_count + vertices + uvs + index_count + indices
+ r_used_cache = true;
+ return true;
+ }
//set up input mesh
xatlas::MeshDecl input_mesh;
@@ -60,6 +136,7 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
pack_options.maxChartSize = 4096;
pack_options.blockAlign = true;
+ pack_options.padding = 1;
pack_options.texelsPerUnit = 1.0 / p_texel_size;
xatlas::Atlas *atlas = xatlas::Create();
@@ -68,7 +145,7 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
ERR_FAIL_COND_V_MSG(err != xatlas::AddMeshError::Enum::Success, false, xatlas::StringForEnum(err));
printf("Generate..\n");
- xatlas::Generate(atlas, chart_options, nullptr, pack_options);
+ xatlas::Generate(atlas, chart_options, xatlas::ParameterizeOptions(), pack_options);
*r_size_hint_x = atlas->width;
*r_size_hint_y = atlas->height;
@@ -82,16 +159,16 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
const xatlas::Mesh &output = atlas->meshes[0];
- *r_vertex = (int *)malloc(sizeof(int) * output.vertexCount);
- *r_uv = (float *)malloc(sizeof(float) * output.vertexCount * 2);
- *r_index = (int *)malloc(sizeof(int) * output.indexCount);
+ *r_vertices = (int *)malloc(sizeof(int) * output.vertexCount);
+ *r_uvs = (float *)malloc(sizeof(float) * output.vertexCount * 2);
+ *r_indices = (int *)malloc(sizeof(int) * output.indexCount);
float max_x = 0;
float max_y = 0;
for (uint32_t i = 0; i < output.vertexCount; i++) {
- (*r_vertex)[i] = output.vertexArray[i].xref;
- (*r_uv)[i * 2 + 0] = output.vertexArray[i].uv[0] / w;
- (*r_uv)[i * 2 + 1] = output.vertexArray[i].uv[1] / h;
+ (*r_vertices)[i] = output.vertexArray[i].xref;
+ (*r_uvs)[i * 2 + 0] = output.vertexArray[i].uv[0] / w;
+ (*r_uvs)[i * 2 + 1] = output.vertexArray[i].uv[1] / h;
max_x = MAX(max_x, output.vertexArray[i].uv[0]);
max_y = MAX(max_y, output.vertexArray[i].uv[1]);
}
@@ -100,18 +177,58 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver
*r_vertex_count = output.vertexCount;
for (uint32_t i = 0; i < output.indexCount; i++) {
- (*r_index)[i] = output.indexArray[i];
+ (*r_indices)[i] = output.indexArray[i];
}
*r_index_count = output.indexCount;
xatlas::Destroy(atlas);
- printf("Done\n");
+
+ if (r_used_cache) {
+ unsigned int new_cache_size = 4 + 2 + 1 + *r_vertex_count + (*r_vertex_count * 2) + 1 + *r_index_count; // hash + size hint + vertex_count + vertices + uvs + index_count + indices
+ new_cache_size *= sizeof(int);
+ int *new_cache_data = (int *)memalloc(new_cache_size);
+ unsigned int new_cache_idx = 0;
+
+ // hash
+ memcpy(&new_cache_data[new_cache_idx], hash, 16);
+ new_cache_idx += 4;
+
+ // size hint
+ new_cache_data[new_cache_idx] = *r_size_hint_x;
+ new_cache_data[new_cache_idx + 1] = *r_size_hint_y;
+ new_cache_idx += 2;
+
+ // vertex count
+ new_cache_data[new_cache_idx] = *r_vertex_count;
+ new_cache_idx++;
+
+ // vertices
+ memcpy(&new_cache_data[new_cache_idx], *r_vertices, sizeof(int) * *r_vertex_count);
+ new_cache_idx += *r_vertex_count;
+
+ // uvs
+ memcpy(&new_cache_data[new_cache_idx], *r_uvs, sizeof(float) * *r_vertex_count * 2);
+ new_cache_idx += *r_vertex_count * 2;
+
+ // index count
+ new_cache_data[new_cache_idx] = *r_index_count;
+ new_cache_idx++;
+
+ // indices
+ memcpy(&new_cache_data[new_cache_idx], *r_indices, sizeof(int) * *r_index_count);
+ new_cache_idx += *r_index_count;
+
+ // Return cache data to the caller
+ r_cache_data = new_cache_data;
+ r_cache_size = new_cache_size;
+ r_used_cache = false;
+ }
+
return true;
}
void register_xatlas_unwrap_types() {
-
array_mesh_lightmap_unwrap_callback = xatlas_mesh_lightmap_unwrap_callback;
}
diff --git a/platform/android/android_keys_utils.cpp b/platform/android/android_keys_utils.cpp
index 88874ba2c7..b5b4fb9a4b 100644
--- a/platform/android/android_keys_utils.cpp
+++ b/platform/android/android_keys_utils.cpp
@@ -32,9 +32,7 @@
unsigned int android_get_keysym(unsigned int p_code) {
for (int i = 0; _ak_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
-
if (_ak_to_keycode[i].keycode == p_code) {
-
return _ak_to_keycode[i].keysym;
}
}
diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h
index f076688ac8..fb442f4c54 100644
--- a/platform/android/android_keys_utils.h
+++ b/platform/android/android_keys_utils.h
@@ -154,7 +154,6 @@ enum {
};
struct _WinTranslatePair {
-
unsigned int keysym;
unsigned int keycode;
};
diff --git a/platform/android/api/api.cpp b/platform/android/api/api.cpp
index 4fe868d4f0..1f140f7119 100644
--- a/platform/android/api/api.cpp
+++ b/platform/android/api/api.cpp
@@ -39,7 +39,6 @@ static JavaClassWrapper *java_class_wrapper = nullptr;
#endif
void register_android_api() {
-
#if !defined(ANDROID_ENABLED)
// On Android platforms, the `java_class_wrapper` instantiation and the
// `JNISingleton` registration occurs in
@@ -54,14 +53,12 @@ void register_android_api() {
}
void unregister_android_api() {
-
#if !defined(ANDROID_ENABLED)
memdelete(java_class_wrapper);
#endif
}
void JavaClassWrapper::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("wrap", "name"), &JavaClassWrapper::wrap);
}
diff --git a/platform/android/api/java_class_wrapper.h b/platform/android/api/java_class_wrapper.h
index 59fcd94b4d..e34f2a9f69 100644
--- a/platform/android/api/java_class_wrapper.h
+++ b/platform/android/api/java_class_wrapper.h
@@ -43,7 +43,6 @@ class JavaObject;
#endif
class JavaClass : public Reference {
-
GDCLASS(JavaClass, Reference);
#ifdef ANDROID_ENABLED
@@ -68,7 +67,6 @@ class JavaClass : public Reference {
Map<StringName, Variant> constant_map;
struct MethodInfo {
-
bool _static;
Vector<uint32_t> param_types;
Vector<StringName> param_sigs;
@@ -77,15 +75,17 @@ class JavaClass : public Reference {
};
_FORCE_INLINE_ static void _convert_to_variant_type(int p_sig, Variant::Type &r_type, float &likelihood) {
-
likelihood = 1.0;
r_type = Variant::NIL;
switch (p_sig) {
-
- case ARG_TYPE_VOID: r_type = Variant::NIL; break;
+ case ARG_TYPE_VOID:
+ r_type = Variant::NIL;
+ break;
case ARG_TYPE_BOOLEAN | ARG_NUMBER_CLASS_BIT:
- case ARG_TYPE_BOOLEAN: r_type = Variant::BOOL; break;
+ case ARG_TYPE_BOOLEAN:
+ r_type = Variant::BOOL;
+ break;
case ARG_TYPE_BYTE | ARG_NUMBER_CLASS_BIT:
case ARG_TYPE_BYTE:
r_type = Variant::INT;
@@ -121,10 +121,18 @@ class JavaClass : public Reference {
r_type = Variant::FLOAT;
likelihood = 0.5;
break;
- case ARG_TYPE_STRING: r_type = Variant::STRING; break;
- case ARG_TYPE_CLASS: r_type = Variant::OBJECT; break;
- case ARG_ARRAY_BIT | ARG_TYPE_VOID: r_type = Variant::NIL; break;
- case ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN: r_type = Variant::ARRAY; break;
+ case ARG_TYPE_STRING:
+ r_type = Variant::STRING;
+ break;
+ case ARG_TYPE_CLASS:
+ r_type = Variant::OBJECT;
+ break;
+ case ARG_ARRAY_BIT | ARG_TYPE_VOID:
+ r_type = Variant::NIL;
+ break;
+ case ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN:
+ r_type = Variant::ARRAY;
+ break;
case ARG_ARRAY_BIT | ARG_TYPE_BYTE:
r_type = Variant::PACKED_BYTE_ARRAY;
likelihood = 1.0;
@@ -153,8 +161,12 @@ class JavaClass : public Reference {
r_type = Variant::PACKED_FLOAT32_ARRAY;
likelihood = 0.5;
break;
- case ARG_ARRAY_BIT | ARG_TYPE_STRING: r_type = Variant::PACKED_STRING_ARRAY; break;
- case ARG_ARRAY_BIT | ARG_TYPE_CLASS: r_type = Variant::ARRAY; break;
+ case ARG_ARRAY_BIT | ARG_TYPE_STRING:
+ r_type = Variant::PACKED_STRING_ARRAY;
+ break;
+ case ARG_ARRAY_BIT | ARG_TYPE_CLASS:
+ r_type = Variant::ARRAY;
+ break;
}
}
@@ -174,7 +186,6 @@ public:
};
class JavaObject : public Reference {
-
GDCLASS(JavaObject, Reference);
#ifdef ANDROID_ENABLED
@@ -194,7 +205,6 @@ public:
};
class JavaClassWrapper : public Object {
-
GDCLASS(JavaClassWrapper, Object);
#ifdef ANDROID_ENABLED
diff --git a/platform/android/api/jni_singleton.h b/platform/android/api/jni_singleton.h
index 917c3f5029..ed69f8d6e4 100644
--- a/platform/android/api/jni_singleton.h
+++ b/platform/android/api/jni_singleton.h
@@ -38,12 +38,10 @@
#endif
class JNISingleton : public Object {
-
GDCLASS(JNISingleton, Object);
#ifdef ANDROID_ENABLED
struct MethodData {
-
jmethodID method;
Variant::Type ret_type;
Vector<Variant::Type> argtypes;
@@ -63,7 +61,6 @@ public:
bool call_error = !E || E->get().argtypes.size() != p_argcount;
if (!call_error) {
for (int i = 0; i < p_argcount; i++) {
-
if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) {
call_error = true;
break;
@@ -83,7 +80,6 @@ public:
jvalue *v = nullptr;
if (p_argcount) {
-
v = (jvalue *)alloca(sizeof(jvalue) * p_argcount);
}
@@ -95,7 +91,6 @@ public:
List<jobject> to_erase;
for (int i = 0; i < p_argcount; i++) {
-
jvalret vr = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]);
v[i] = vr.val;
if (vr.obj)
@@ -105,31 +100,24 @@ public:
Variant ret;
switch (E->get().ret_type) {
-
case Variant::NIL: {
-
env->CallVoidMethodA(instance, E->get().method, v);
} break;
case Variant::BOOL: {
-
ret = env->CallBooleanMethodA(instance, E->get().method, v) == JNI_TRUE;
} break;
case Variant::INT: {
-
ret = env->CallIntMethodA(instance, E->get().method, v);
} break;
case Variant::FLOAT: {
-
ret = env->CallFloatMethodA(instance, E->get().method, v);
} break;
case Variant::STRING: {
-
jobject o = env->CallObjectMethodA(instance, E->get().method, v);
ret = jstring_to_string((jstring)o, env);
env->DeleteLocalRef(o);
} break;
case Variant::PACKED_STRING_ARRAY: {
-
jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance, E->get().method, v);
ret = _jobject_to_variant(env, arr);
@@ -137,7 +125,6 @@ public:
env->DeleteLocalRef(arr);
} break;
case Variant::PACKED_INT32_ARRAY: {
-
jintArray arr = (jintArray)env->CallObjectMethodA(instance, E->get().method, v);
int fCount = env->GetArrayLength(arr);
@@ -150,7 +137,6 @@ public:
env->DeleteLocalRef(arr);
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
-
jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance, E->get().method, v);
int fCount = env->GetArrayLength(arr);
@@ -167,14 +153,12 @@ public:
#warning This is missing 64 bits arrays, I have no idea how to do it in JNI
#endif
case Variant::DICTIONARY: {
-
jobject obj = env->CallObjectMethodA(instance, E->get().method, v);
ret = _jobject_to_variant(env, obj);
env->DeleteLocalRef(obj);
} break;
default: {
-
env->PopLocalFrame(nullptr);
ERR_FAIL_V(Variant());
} break;
@@ -197,17 +181,14 @@ public:
#ifdef ANDROID_ENABLED
jobject get_instance() const {
-
return instance;
}
void set_instance(jobject p_instance) {
-
instance = p_instance;
}
void add_method(const StringName &p_name, jmethodID p_method, const Vector<Variant::Type> &p_args, Variant::Type p_ret_type) {
-
MethodData md;
md.method = p_method;
md.argtypes = p_args;
diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp
index 802d85e7be..09c981b3fa 100644
--- a/platform/android/audio_driver_jandroid.cpp
+++ b/platform/android/audio_driver_jandroid.cpp
@@ -52,12 +52,10 @@ Mutex AudioDriverAndroid::mutex;
int32_t *AudioDriverAndroid::audioBuffer32 = nullptr;
const char *AudioDriverAndroid::get_name() const {
-
return "Android";
}
Error AudioDriverAndroid::init() {
-
/*
// TODO: pass in/return a (Java) device ID, also whether we're opening for input or output
this->spec.samples = Android_JNI_OpenAudioDevice(this->spec.freq, this->spec.format == AUDIO_U8 ? 0 : 1, this->spec.channels, this->spec.samples);
@@ -75,9 +73,9 @@ Error AudioDriverAndroid::init() {
// __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
JNIEnv *env = ThreadAndroid::get_env();
- int mix_rate = GLOBAL_DEF_RST("audio/mix_rate", 44100);
+ int mix_rate = GLOBAL_GET("audio/mix_rate");
- int latency = GLOBAL_DEF_RST("audio/output_latency", 25);
+ int latency = GLOBAL_GET("audio/output_latency");
unsigned int buffer_size = next_power_of_2(latency * mix_rate / 1000);
print_verbose("Audio buffer size: " + itos(buffer_size));
@@ -100,7 +98,6 @@ void AudioDriverAndroid::start() {
}
void AudioDriverAndroid::setup(jobject p_io) {
-
JNIEnv *env = ThreadAndroid::get_env();
io = p_io;
@@ -114,10 +111,8 @@ void AudioDriverAndroid::setup(jobject p_io) {
}
void AudioDriverAndroid::thread_func(JNIEnv *env) {
-
jclass cls = env->FindClass("org/godotengine/godot/Godot");
if (cls) {
-
cls = (jclass)env->NewGlobalRef(cls);
}
jfieldID fid = env->GetStaticFieldID(cls, "io", "Lorg/godotengine/godot/GodotIO;");
@@ -128,24 +123,20 @@ void AudioDriverAndroid::thread_func(JNIEnv *env) {
_write_buffer = env->GetMethodID(lcls, "audioWriteShortBuffer", "([S)V");
while (!quit) {
-
int16_t *ptr = (int16_t *)audioBufferPinned;
int fc = audioBufferFrames;
if (!s_ad->active || mutex.try_lock() != OK) {
-
for (int i = 0; i < fc; i++) {
ptr[i] = 0;
}
} else {
-
s_ad->audio_server_process(fc / 2, audioBuffer32);
mutex.unlock();
for (int i = 0; i < fc; i++) {
-
ptr[i] = audioBuffer32[i] >> 16;
}
}
@@ -155,27 +146,22 @@ void AudioDriverAndroid::thread_func(JNIEnv *env) {
}
int AudioDriverAndroid::get_mix_rate() const {
-
return mix_rate;
}
AudioDriver::SpeakerMode AudioDriverAndroid::get_speaker_mode() const {
-
return SPEAKER_MODE_STEREO;
}
void AudioDriverAndroid::lock() {
-
mutex.lock();
}
void AudioDriverAndroid::unlock() {
-
mutex.unlock();
}
void AudioDriverAndroid::finish() {
-
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(io, _quit);
@@ -189,13 +175,11 @@ void AudioDriverAndroid::finish() {
}
void AudioDriverAndroid::set_pause(bool p_pause) {
-
JNIEnv *env = ThreadAndroid::get_env();
env->CallVoidMethod(io, _pause, p_pause);
}
AudioDriverAndroid::AudioDriverAndroid() {
-
s_ad = this;
active = false;
}
diff --git a/platform/android/audio_driver_jandroid.h b/platform/android/audio_driver_jandroid.h
index b1cc3f9aa0..953ade9311 100644
--- a/platform/android/audio_driver_jandroid.h
+++ b/platform/android/audio_driver_jandroid.h
@@ -36,7 +36,6 @@
#include "java_godot_lib_jni.h"
class AudioDriverAndroid : public AudioDriver {
-
static Mutex mutex;
static AudioDriverAndroid *s_ad;
static jobject io;
diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp
index e59850e016..740e9a3132 100644
--- a/platform/android/audio_driver_opensl.cpp
+++ b/platform/android/audio_driver_opensl.cpp
@@ -39,7 +39,6 @@
void AudioDriverOpenSL::_buffer_callback(
SLAndroidSimpleBufferQueueItf queueItf) {
-
bool mix = true;
if (pause) {
@@ -51,7 +50,6 @@ void AudioDriverOpenSL::_buffer_callback(
if (mix) {
audio_server_process(buffer_size, mixdown_buffer);
} else {
-
int32_t *src_buff = mixdown_buffer;
for (unsigned int i = 0; i < buffer_size * 2; i++) {
src_buff[i] = 0;
@@ -67,7 +65,6 @@ void AudioDriverOpenSL::_buffer_callback(
last_free = (last_free + 1) % BUFFER_COUNT;
for (unsigned int i = 0; i < buffer_size * 2; i++) {
-
ptr[i] = src_buff[i] >> 16;
}
@@ -77,7 +74,6 @@ void AudioDriverOpenSL::_buffer_callback(
void AudioDriverOpenSL::_buffer_callbacks(
SLAndroidSimpleBufferQueueItf queueItf,
void *pContext) {
-
AudioDriverOpenSL *ad = (AudioDriverOpenSL *)pContext;
ad->_buffer_callback(queueItf);
@@ -86,12 +82,10 @@ void AudioDriverOpenSL::_buffer_callbacks(
AudioDriverOpenSL *AudioDriverOpenSL::s_ad = nullptr;
const char *AudioDriverOpenSL::get_name() const {
-
return "Android";
}
Error AudioDriverOpenSL::init() {
-
SLresult res;
SLEngineOption EngineOption[] = {
{ (SLuint32)SL_ENGINEOPTION_THREADSAFE, (SLuint32)SL_BOOLEAN_TRUE }
@@ -106,7 +100,6 @@ Error AudioDriverOpenSL::init() {
}
void AudioDriverOpenSL::start() {
-
active = false;
SLresult res;
@@ -114,7 +107,6 @@ void AudioDriverOpenSL::start() {
buffer_size = 1024;
for (int i = 0; i < BUFFER_COUNT; i++) {
-
buffers[i] = memnew_arr(int16_t, buffer_size * 2);
memset(buffers[i], 0, buffer_size * 4);
}
@@ -204,7 +196,6 @@ void AudioDriverOpenSL::start() {
}
void AudioDriverOpenSL::_record_buffer_callback(SLAndroidSimpleBufferQueueItf queueItf) {
-
for (int i = 0; i < rec_buffer.size(); i++) {
int32_t sample = rec_buffer[i] << 16;
input_buffer_write(sample);
@@ -216,14 +207,12 @@ void AudioDriverOpenSL::_record_buffer_callback(SLAndroidSimpleBufferQueueItf qu
}
void AudioDriverOpenSL::_record_buffer_callbacks(SLAndroidSimpleBufferQueueItf queueItf, void *pContext) {
-
AudioDriverOpenSL *ad = (AudioDriverOpenSL *)pContext;
ad->_record_buffer_callback(queueItf);
}
Error AudioDriverOpenSL::capture_init_device() {
-
SLDataLocator_IODevice loc_dev = {
SL_DATALOCATOR_IODEVICE,
SL_IODEVICE_AUDIOINPUT,
@@ -291,7 +280,6 @@ Error AudioDriverOpenSL::capture_init_device() {
}
Error AudioDriverOpenSL::capture_start() {
-
if (OS::get_singleton()->request_permission("RECORD_AUDIO")) {
return capture_init_device();
}
@@ -300,7 +288,6 @@ Error AudioDriverOpenSL::capture_start() {
}
Error AudioDriverOpenSL::capture_stop() {
-
SLuint32 state;
SLresult res = (*recordItf)->GetRecordState(recordItf, &state);
ERR_FAIL_COND_V(res != SL_RESULT_SUCCESS, ERR_CANT_OPEN);
@@ -317,34 +304,28 @@ Error AudioDriverOpenSL::capture_stop() {
}
int AudioDriverOpenSL::get_mix_rate() const {
-
return 44100; // hardcoded for Android, as selected by SL_SAMPLINGRATE_44_1
}
AudioDriver::SpeakerMode AudioDriverOpenSL::get_speaker_mode() const {
-
return SPEAKER_MODE_STEREO;
}
void AudioDriverOpenSL::lock() {
-
if (active)
mutex.lock();
}
void AudioDriverOpenSL::unlock() {
-
if (active)
mutex.unlock();
}
void AudioDriverOpenSL::finish() {
-
(*sl)->Destroy(sl);
}
void AudioDriverOpenSL::set_pause(bool p_pause) {
-
pause = p_pause;
if (active) {
diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h
index 569e2aa54b..9858a40822 100644
--- a/platform/android/audio_driver_opensl.h
+++ b/platform/android/audio_driver_opensl.h
@@ -38,7 +38,6 @@
#include <SLES/OpenSLES_Android.h>
class AudioDriverOpenSL : public AudioDriver {
-
bool active;
Mutex mutex;
diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp
index f8571e6277..ca312b427f 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -42,12 +42,10 @@ jmethodID DirAccessJAndroid::_dir_close = nullptr;
jmethodID DirAccessJAndroid::_dir_is_dir = nullptr;
DirAccess *DirAccessJAndroid::create_fs() {
-
return memnew(DirAccessJAndroid);
}
Error DirAccessJAndroid::list_dir_begin() {
-
list_dir_end();
JNIEnv *env = ThreadAndroid::get_env();
@@ -62,7 +60,6 @@ Error DirAccessJAndroid::list_dir_begin() {
}
String DirAccessJAndroid::get_next() {
-
ERR_FAIL_COND_V(id == 0, "");
JNIEnv *env = ThreadAndroid::get_env();
@@ -76,19 +73,16 @@ String DirAccessJAndroid::get_next() {
}
bool DirAccessJAndroid::current_is_dir() const {
-
JNIEnv *env = ThreadAndroid::get_env();
return env->CallBooleanMethod(io, _dir_is_dir, id);
}
bool DirAccessJAndroid::current_is_hidden() const {
-
return current != "." && current != ".." && current.begins_with(".");
}
void DirAccessJAndroid::list_dir_end() {
-
if (id == 0)
return;
@@ -98,17 +92,14 @@ void DirAccessJAndroid::list_dir_end() {
}
int DirAccessJAndroid::get_drive_count() {
-
return 0;
}
String DirAccessJAndroid::get_drive(int p_drive) {
-
return "";
}
Error DirAccessJAndroid::change_dir(String p_dir) {
-
JNIEnv *env = ThreadAndroid::get_env();
if (p_dir == "" || p_dir == "." || (p_dir == ".." && current_dir == ""))
@@ -145,12 +136,10 @@ Error DirAccessJAndroid::change_dir(String p_dir) {
}
String DirAccessJAndroid::get_current_dir(bool p_include_drive) {
-
return "res://" + current_dir;
}
bool DirAccessJAndroid::file_exists(String p_file) {
-
String sd;
if (current_dir == "")
sd = p_file;
@@ -165,7 +154,6 @@ bool DirAccessJAndroid::file_exists(String p_file) {
}
bool DirAccessJAndroid::dir_exists(String p_dir) {
-
JNIEnv *env = ThreadAndroid::get_env();
String sd;
@@ -198,33 +186,27 @@ bool DirAccessJAndroid::dir_exists(String p_dir) {
}
Error DirAccessJAndroid::make_dir(String p_dir) {
-
ERR_FAIL_V(ERR_UNAVAILABLE);
}
Error DirAccessJAndroid::rename(String p_from, String p_to) {
-
ERR_FAIL_V(ERR_UNAVAILABLE);
}
Error DirAccessJAndroid::remove(String p_name) {
-
ERR_FAIL_V(ERR_UNAVAILABLE);
}
String DirAccessJAndroid::get_filesystem_type() const {
-
return "APK";
}
//FileType get_file_type() const;
size_t DirAccessJAndroid::get_space_left() {
-
return 0;
}
void DirAccessJAndroid::setup(jobject p_io) {
-
JNIEnv *env = ThreadAndroid::get_env();
io = p_io;
@@ -240,11 +222,9 @@ void DirAccessJAndroid::setup(jobject p_io) {
}
DirAccessJAndroid::DirAccessJAndroid() {
-
id = 0;
}
DirAccessJAndroid::~DirAccessJAndroid() {
-
list_dir_end();
}
diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h
index 8dab3e50ce..7d0def137a 100644
--- a/platform/android/dir_access_jandroid.h
+++ b/platform/android/dir_access_jandroid.h
@@ -36,7 +36,6 @@
#include <stdio.h>
class DirAccessJAndroid : public DirAccess {
-
//AAssetDir* aad;
static jobject io;
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 9534387d35..1436d832de 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -155,12 +155,12 @@ bool DisplayServerAndroid::screen_is_touchscreen(int p_screen) const {
return true;
}
-void DisplayServerAndroid::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_length) {
+void DisplayServerAndroid::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_length, int p_cursor_start, int p_cursor_end) {
GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
ERR_FAIL_COND(!godot_io_java);
if (godot_io_java->has_vk()) {
- godot_io_java->show_vk(p_existing_text, p_max_length);
+ godot_io_java->show_vk(p_existing_text, p_max_length, p_cursor_start, p_cursor_end);
} else {
ERR_PRINT("Virtual keyboard not available");
}
@@ -367,6 +367,25 @@ void DisplayServerAndroid::register_android_driver() {
register_create_function("android", create_func, get_rendering_drivers_func);
}
+void DisplayServerAndroid::reset_window() {
+#if defined(VULKAN_ENABLED)
+ if (rendering_driver == "vulkan") {
+ ANativeWindow *native_window = OS_Android::get_singleton()->get_native_window();
+ ERR_FAIL_COND(!native_window);
+
+ ERR_FAIL_COND(!context_vulkan);
+ context_vulkan->window_destroy(MAIN_WINDOW_ID);
+
+ Size2i display_size = OS_Android::get_singleton()->get_display_size();
+ if (context_vulkan->window_create(native_window, display_size.width, display_size.height) == -1) {
+ memdelete(context_vulkan);
+ context_vulkan = nullptr;
+ ERR_FAIL_MSG("Failed to reset Vulkan window.");
+ }
+ }
+#endif
+}
+
DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
rendering_driver = p_rendering_driver;
@@ -424,7 +443,7 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis
}
#endif
- InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
+ Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
}
DisplayServerAndroid::~DisplayServerAndroid() {
@@ -445,16 +464,16 @@ DisplayServerAndroid::~DisplayServerAndroid() {
void DisplayServerAndroid::process_joy_event(DisplayServerAndroid::JoypadEvent p_event) {
switch (p_event.type) {
case JOY_EVENT_BUTTON:
- InputFilter::get_singleton()->joy_button(p_event.device, p_event.index, p_event.pressed);
+ Input::get_singleton()->joy_button(p_event.device, p_event.index, p_event.pressed);
break;
case JOY_EVENT_AXIS:
- InputFilter::JoyAxis value;
+ Input::JoyAxis value;
value.min = -1;
value.value = p_event.value;
- InputFilter::get_singleton()->joy_axis(p_event.device, p_event.index, value);
+ Input::get_singleton()->joy_axis(p_event.device, p_event.index, value);
break;
case JOY_EVENT_HAT:
- InputFilter::get_singleton()->joy_hat(p_event.device, p_event.hat);
+ Input::get_singleton()->joy_hat(p_event.device, p_event.hat);
break;
default:
return;
@@ -484,7 +503,7 @@ void DisplayServerAndroid::process_key_event(int p_keycode, int p_scancode, int
OS_Android::get_singleton()->main_loop_request_go_back();
}
- InputFilter::get_singleton()->parse_input_event(ev);
+ Input::get_singleton()->parse_input_event(ev);
}
void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector<DisplayServerAndroid::TouchPos> &p_points) {
@@ -493,13 +512,12 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
if (touch.size()) {
//end all if exist
for (int i = 0; i < touch.size(); i++) {
-
Ref<InputEventScreenTouch> ev;
ev.instance();
ev->set_index(touch[i].id);
ev->set_pressed(false);
ev->set_position(touch[i].pos);
- InputFilter::get_singleton()->parse_input_event(ev);
+ Input::get_singleton()->parse_input_event(ev);
}
}
@@ -511,13 +529,12 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
//send touch
for (int i = 0; i < touch.size(); i++) {
-
Ref<InputEventScreenTouch> ev;
ev.instance();
ev->set_index(touch[i].id);
ev->set_pressed(true);
ev->set_position(touch[i].pos);
- InputFilter::get_singleton()->parse_input_event(ev);
+ Input::get_singleton()->parse_input_event(ev);
}
} break;
@@ -525,10 +542,8 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
ERR_FAIL_COND(touch.size() != p_points.size());
for (int i = 0; i < touch.size(); i++) {
-
int idx = -1;
for (int j = 0; j < p_points.size(); j++) {
-
if (touch[i].id == p_points[j].id) {
idx = j;
break;
@@ -545,7 +560,7 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
ev->set_index(touch[i].id);
ev->set_position(p_points[idx].pos);
ev->set_relative(p_points[idx].pos - touch[i].pos);
- InputFilter::get_singleton()->parse_input_event(ev);
+ Input::get_singleton()->parse_input_event(ev);
touch.write[i].pos = p_points[idx].pos;
}
@@ -554,13 +569,12 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
if (touch.size()) {
//end all if exist
for (int i = 0; i < touch.size(); i++) {
-
Ref<InputEventScreenTouch> ev;
ev.instance();
ev->set_index(touch[i].id);
ev->set_pressed(false);
ev->set_position(touch[i].pos);
- InputFilter::get_singleton()->parse_input_event(ev);
+ Input::get_singleton()->parse_input_event(ev);
}
touch.clear();
}
@@ -577,7 +591,7 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
ev->set_index(tp.id);
ev->set_pressed(true);
ev->set_position(tp.pos);
- InputFilter::get_singleton()->parse_input_event(ev);
+ Input::get_singleton()->parse_input_event(ev);
break;
}
@@ -586,13 +600,12 @@ void DisplayServerAndroid::process_touch(int p_what, int p_pointer, const Vector
case 4: { // remove touch
for (int i = 0; i < touch.size(); i++) {
if (touch[i].id == p_pointer) {
-
Ref<InputEventScreenTouch> ev;
ev.instance();
ev->set_index(touch[i].id);
ev->set_pressed(false);
ev->set_position(touch[i].pos);
- InputFilter::get_singleton()->parse_input_event(ev);
+ Input::get_singleton()->parse_input_event(ev);
touch.remove(i);
break;
@@ -613,7 +626,7 @@ void DisplayServerAndroid::process_hover(int p_type, Point2 p_pos) {
ev->set_position(p_pos);
ev->set_global_position(p_pos);
ev->set_relative(p_pos - hover_prev_pos);
- InputFilter::get_singleton()->parse_input_event(ev);
+ Input::get_singleton()->parse_input_event(ev);
hover_prev_pos = p_pos;
} break;
}
@@ -626,7 +639,7 @@ void DisplayServerAndroid::process_double_tap(Point2 p_pos) {
ev->set_global_position(p_pos);
ev->set_pressed(false);
ev->set_doubleclick(true);
- InputFilter::get_singleton()->parse_input_event(ev);
+ Input::get_singleton()->parse_input_event(ev);
}
void DisplayServerAndroid::process_scroll(Point2 p_pos) {
@@ -634,22 +647,22 @@ void DisplayServerAndroid::process_scroll(Point2 p_pos) {
ev.instance();
ev->set_position(p_pos);
ev->set_delta(p_pos - scroll_prev_pos);
- InputFilter::get_singleton()->parse_input_event(ev);
+ Input::get_singleton()->parse_input_event(ev);
scroll_prev_pos = p_pos;
}
void DisplayServerAndroid::process_accelerometer(const Vector3 &p_accelerometer) {
- InputFilter::get_singleton()->set_accelerometer(p_accelerometer);
+ Input::get_singleton()->set_accelerometer(p_accelerometer);
}
void DisplayServerAndroid::process_gravity(const Vector3 &p_gravity) {
- InputFilter::get_singleton()->set_gravity(p_gravity);
+ Input::get_singleton()->set_gravity(p_gravity);
}
void DisplayServerAndroid::process_magnetometer(const Vector3 &p_magnetometer) {
- InputFilter::get_singleton()->set_magnetometer(p_magnetometer);
+ Input::get_singleton()->set_magnetometer(p_magnetometer);
}
void DisplayServerAndroid::process_gyroscope(const Vector3 &p_gyroscope) {
- InputFilter::get_singleton()->set_gyroscope(p_gyroscope);
+ Input::get_singleton()->set_gyroscope(p_gyroscope);
}
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index 2096ba68f1..d64542df58 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -52,7 +52,6 @@ public:
};
struct JoypadEvent {
-
int device;
int type;
int index;
@@ -107,7 +106,7 @@ public:
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
- virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_length = -1);
+ virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
virtual void virtual_keyboard_hide();
virtual int virtual_keyboard_get_height() const;
@@ -167,6 +166,8 @@ public:
static Vector<String> get_rendering_drivers_func();
static void register_android_driver();
+ void reset_window();
+
DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
~DisplayServerAndroid();
};
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 1eb1ee0d29..dfaaf68b69 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -44,6 +44,7 @@
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
#include "platform/android/logo.gen.h"
+#include "platform/android/plugin/godot_plugin_config.h"
#include "platform/android/run_icon.gen.h"
#include <string.h>
@@ -235,14 +236,12 @@ static const LauncherIcon launcher_adaptive_icon_backgrounds[icon_densities_coun
};
class EditorExportPlatformAndroid : public EditorExportPlatform {
-
GDCLASS(EditorExportPlatformAndroid, EditorExportPlatform);
Ref<ImageTexture> logo;
Ref<ImageTexture> run_icon;
struct Device {
-
String id;
String name;
String description;
@@ -250,26 +249,51 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
};
struct APKExportData {
-
zipFile apk;
EditorProgress *ep;
};
+ Vector<PluginConfig> plugins;
+ volatile bool plugins_changed;
+ Mutex plugins_lock;
Vector<Device> devices;
volatile bool devices_changed;
Mutex device_lock;
- Thread *device_thread;
+ Thread *check_for_changes_thread;
volatile bool quit_request;
- static void _device_poll_thread(void *ud) {
-
+ static void _check_for_changes_poll_thread(void *ud) {
EditorExportPlatformAndroid *ea = (EditorExportPlatformAndroid *)ud;
while (!ea->quit_request) {
+ // Check for plugins updates
+ {
+ // Nothing to do if we already know the plugins have changed.
+ if (!ea->plugins_changed) {
+ Vector<PluginConfig> loaded_plugins = get_plugins();
+
+ MutexLock lock(ea->plugins_lock);
+
+ if (ea->plugins.size() != loaded_plugins.size()) {
+ ea->plugins_changed = true;
+ } else {
+ for (int i = 0; i < ea->plugins.size(); i++) {
+ if (ea->plugins[i].name != loaded_plugins[i].name) {
+ ea->plugins_changed = true;
+ break;
+ }
+ }
+ }
+ if (ea->plugins_changed) {
+ ea->plugins = loaded_plugins;
+ }
+ }
+ }
+
+ // Check for devices updates
String adb = EditorSettings::get_singleton()->get("export/android/adb");
if (FileAccess::exists(adb)) {
-
String devices;
List<String> args;
args.push_back("devices");
@@ -279,11 +303,11 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
Vector<String> ds = devices.split("\n");
Vector<String> ldevices;
for (int i = 1; i < ds.size(); i++) {
-
String d = ds[i];
int dpos = d.find("device");
- if (dpos == -1)
+ if (dpos == -1) {
continue;
+ }
d = d.substr(0, dpos).strip_edges();
ldevices.push_back(d);
}
@@ -293,12 +317,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
bool different = false;
if (ea->devices.size() != ldevices.size()) {
-
different = true;
} else {
-
for (int i = 0; i < ea->devices.size(); i++) {
-
if (ea->devices[i].id != ldevices[i]) {
different = true;
break;
@@ -307,11 +328,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
if (different) {
-
Vector<Device> ndevices;
for (int i = 0; i < ldevices.size(); i++) {
-
Device d;
d.id = ldevices[i];
for (int j = 0; j < ea->devices.size(); j++) {
@@ -340,7 +359,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
d.description = "Device ID: " + d.id + "\n";
d.api_level = 0;
for (int j = 0; j < props.size(); j++) {
-
// got information by `shell cat /system/build.prop` before and its format is "property=value"
// it's now changed to use `shell getporp` because of permission issue with Android 8.0 and above
// its format is "[property]: [value]" so changed it as like build.prop
@@ -372,7 +390,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
d.name = vendor + " " + device;
- if (device == String()) continue;
+ if (device == String()) {
+ continue;
+ }
}
ndevices.push_back(d);
@@ -388,8 +408,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
uint64_t time = OS::get_singleton()->get_ticks_usec();
while (OS::get_singleton()->get_ticks_usec() - time < wait) {
OS::get_singleton()->delay_usec(1000 * sleep);
- if (ea->quit_request)
+ if (ea->quit_request) {
break;
+ }
}
}
@@ -406,7 +427,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
String get_project_name(const String &p_name) const {
-
String aname;
if (p_name != "") {
aname = p_name;
@@ -422,7 +442,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
String get_package_name(const String &p_package) const {
-
String pname = p_package;
String basename = ProjectSettings::get_singleton()->get("application/config/name");
basename = basename.to_lower();
@@ -439,8 +458,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
first = false;
}
}
- if (name == "")
+ if (name == "") {
name = "noname";
+ }
pname = pname.replace("$genname", name);
@@ -448,7 +468,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
bool is_package_name_valid(const String &p_package, String *r_error = nullptr) const {
-
String pname = p_package;
if (pname.length() == 0) {
@@ -512,7 +531,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
static bool _should_compress_asset(const String &p_path, const Vector<uint8_t> &p_data) {
-
/*
* By not compressing files with little or not benefit in doing so,
* a performance gain is expected attime. Moreover, if the APK is
@@ -559,7 +577,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
static zip_fileinfo get_zip_fileinfo() {
-
OS::Time time = OS::get_singleton()->get_time();
OS::Date date = OS::get_singleton()->get_date();
@@ -586,6 +603,73 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
return abis;
}
+ /// List the gdap files in the directory specified by the p_path parameter.
+ static Vector<String> list_gdap_files(const String &p_path) {
+ Vector<String> dir_files;
+ DirAccessRef da = DirAccess::open(p_path);
+ if (da) {
+ da->list_dir_begin();
+ while (true) {
+ String file = da->get_next();
+ if (file == "") {
+ break;
+ }
+
+ if (da->current_is_dir() || da->current_is_hidden()) {
+ continue;
+ }
+
+ if (file.ends_with(PLUGIN_CONFIG_EXT)) {
+ dir_files.push_back(file);
+ }
+ }
+ da->list_dir_end();
+ }
+
+ return dir_files;
+ }
+
+ static Vector<PluginConfig> get_plugins() {
+ Vector<PluginConfig> loaded_plugins;
+
+ String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().plus_file("android/plugins");
+
+ // Add the prebuilt plugins
+ loaded_plugins.append_array(get_prebuilt_plugins(plugins_dir));
+
+ if (DirAccess::exists(plugins_dir)) {
+ Vector<String> plugins_filenames = list_gdap_files(plugins_dir);
+
+ if (!plugins_filenames.empty()) {
+ Ref<ConfigFile> config_file = memnew(ConfigFile);
+ for (int i = 0; i < plugins_filenames.size(); i++) {
+ PluginConfig config = load_plugin_config(config_file, plugins_dir.plus_file(plugins_filenames[i]));
+ if (config.valid_config) {
+ loaded_plugins.push_back(config);
+ } else {
+ print_error("Invalid plugin config file " + plugins_filenames[i]);
+ }
+ }
+ }
+ }
+
+ return loaded_plugins;
+ }
+
+ static Vector<PluginConfig> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) {
+ Vector<PluginConfig> enabled_plugins;
+ Vector<PluginConfig> all_plugins = get_plugins();
+ for (int i = 0; i < all_plugins.size(); i++) {
+ PluginConfig plugin = all_plugins[i];
+ bool enabled = p_presets->get("plugins/" + plugin.name);
+ if (enabled) {
+ enabled_plugins.push_back(plugin);
+ }
+ }
+
+ return enabled_plugins;
+ }
+
static Error store_in_apk(APKExportData *ed, const String &p_path, const Vector<uint8_t> &p_data, int compression_method = Z_DEFLATED) {
zip_fileinfo zipfi = get_zip_fileinfo();
zipOpenNewFileInZip(ed->apk,
@@ -648,7 +732,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
void _fix_manifest(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest, bool p_give_internet) {
-
// Leaving the unused types commented because looking these constants up
// again later would be annoying
// const int CHUNK_AXML_FILE = 0x00080003;
@@ -688,16 +771,16 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
int xr_mode_index = p_preset->get("xr_features/xr_mode");
- String plugins = p_preset->get("custom_template/plugins");
+ String plugins_names = get_plugins_names(get_enabled_plugins(p_preset));
Vector<String> perms;
const char **aperms = android_perms;
while (*aperms) {
-
bool enabled = p_preset->get("permissions/" + String(*aperms).to_lower());
- if (enabled)
+ if (enabled) {
perms.push_back("android.permission." + String(*aperms));
+ }
aperms++;
}
@@ -711,19 +794,17 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
if (p_give_internet) {
- if (perms.find("android.permission.INTERNET") == -1)
+ if (perms.find("android.permission.INTERNET") == -1) {
perms.push_back("android.permission.INTERNET");
+ }
}
while (ofs < (uint32_t)p_manifest.size()) {
-
uint32_t chunk = decode_uint32(&p_manifest[ofs]);
uint32_t size = decode_uint32(&p_manifest[ofs + 4]);
switch (chunk) {
-
case CHUNK_STRINGS: {
-
int iofs = ofs + 8;
string_count = decode_uint32(&p_manifest[iofs]);
@@ -744,14 +825,12 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
string_table_begins = st_offset;
for (uint32_t i = 0; i < string_count; i++) {
-
uint32_t string_at = decode_uint32(&p_manifest[st_offset + i * 4]);
string_at += st_offset + string_count * 4;
ERR_FAIL_COND_MSG(string_flags & UTF8_FLAG, "Unimplemented, can't read UTF-8 string table.");
if (string_flags & UTF8_FLAG) {
-
} else {
uint32_t len = decode_uint16(&p_manifest[string_at]);
Vector<CharType> ucstring;
@@ -774,7 +853,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
} break;
case CHUNK_XML_START_TAG: {
-
int iofs = ofs + 8;
uint32_t name = decode_uint32(&p_manifest[iofs + 12]);
@@ -804,8 +882,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
if (tname == "manifest" && attrname == "versionName") {
if (attr_value == 0xFFFFFFFF) {
WARN_PRINT("Version name in a resource, should be plain text");
- } else
+ } else {
string_table.write[attr_value] = version_name;
+ }
}
if (tname == "instrumentation" && attrname == "targetPackage") {
@@ -813,26 +892,20 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
if (tname == "activity" && attrname == "screenOrientation") {
-
encode_uint32(orientation == 0 ? 0 : 1, &p_manifest.write[iofs + 16]);
}
if (tname == "supports-screens") {
-
if (attrname == "smallScreens") {
-
encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
} else if (attrname == "normalScreens") {
-
encode_uint32(screen_support_normal ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
} else if (attrname == "largeScreens") {
-
encode_uint32(screen_support_large ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
} else if (attrname == "xlargeScreens") {
-
encode_uint32(screen_support_xlarge ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
}
}
@@ -853,9 +926,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
}
- if (tname == "meta-data" && attrname == "value" && value == "custom_template_plugins_value") {
+ if (tname == "meta-data" && attrname == "value" && value == "plugins_value" && !plugins_names.empty()) {
// Update the meta-data 'android:value' attribute with the list of enabled plugins.
- string_table.write[attr_value] = plugins;
+ string_table.write[attr_value] = plugins_names;
}
iofs += 20;
@@ -889,8 +962,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
feature_required_list.push_back(hand_tracking_index == 2);
feature_versions.push_back(-1); // no version attribute should be added.
- if (perms.find("oculus.permission.handtracking") == -1) {
- perms.push_back("oculus.permission.handtracking");
+ if (perms.find("com.oculus.permission.HAND_TRACKING") == -1) {
+ perms.push_back("com.oculus.permission.HAND_TRACKING");
}
}
}
@@ -1037,7 +1110,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
}
if (tname == "manifest") {
-
// save manifest ending so we can restore it
Vector<uint8_t> manifest_end;
uint32_t manifest_cur_size = p_manifest.size();
@@ -1123,13 +1195,11 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
ret.resize(string_table_begins + string_table.size() * 4);
for (uint32_t i = 0; i < string_table_begins; i++) {
-
ret.write[i] = p_manifest[i];
}
ofs = 0;
for (int i = 0; i < string_table.size(); i++) {
-
encode_uint32(ofs, &ret.write[string_table_begins + i * 4]);
ofs += string_table[i].length() * 2 + 2 + 2;
}
@@ -1138,7 +1208,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
string_data_offset = ret.size() - ofs;
uint8_t *chars = &ret.write[string_data_offset];
for (int i = 0; i < string_table.size(); i++) {
-
String s = string_table[i];
encode_uint16(s.length(), chars);
chars += 2;
@@ -1155,18 +1224,21 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
//pad
- while (ret.size() % 4)
+ while (ret.size() % 4) {
ret.push_back(0);
+ }
uint32_t new_stable_end = ret.size();
uint32_t extra = (p_manifest.size() - string_table_ends);
ret.resize(new_stable_end + extra);
- for (uint32_t i = 0; i < extra; i++)
+ for (uint32_t i = 0; i < extra; i++) {
ret.write[new_stable_end + i] = p_manifest[string_table_ends + i];
+ }
- while (ret.size() % 4)
+ while (ret.size() % 4) {
ret.push_back(0);
+ }
encode_uint32(ret.size(), &ret.write[4]); //update new file size
encode_uint32(new_stable_end - 8, &ret.write[12]); //update new string table size
@@ -1177,19 +1249,36 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
static String _parse_string(const uint8_t *p_bytes, bool p_utf8) {
-
uint32_t offset = 0;
- uint32_t len = decode_uint16(&p_bytes[offset]);
+ uint32_t len = 0;
if (p_utf8) {
- //don't know how to read extended utf8, this will have to be for now
- len >>= 8;
+ uint8_t byte = p_bytes[offset];
+ if (byte & 0x80) {
+ offset += 2;
+ } else {
+ offset += 1;
+ }
+ byte = p_bytes[offset];
+ offset++;
+ if (byte & 0x80) {
+ len = byte & 0x7F;
+ len = (len << 8) + p_bytes[offset];
+ offset++;
+ } else {
+ len = byte;
+ }
+ } else {
+ len = decode_uint16(&p_bytes[offset]);
+ offset += 2;
+ if (len & 0x8000) {
+ len &= 0x7FFF;
+ len = (len << 16) + decode_uint16(&p_bytes[offset]);
+ offset += 2;
+ }
}
- offset += 2;
- //printf("len %i, unicode: %i\n",len,int(p_utf8));
if (p_utf8) {
-
Vector<uint8_t> str8;
str8.resize(len + 1);
for (uint32_t i = 0; i < len; i++) {
@@ -1200,19 +1289,18 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
str.parse_utf8((const char *)str8.ptr());
return str;
} else {
-
String str;
for (uint32_t i = 0; i < len; i++) {
CharType c = decode_uint16(&p_bytes[offset + i * 2]);
- if (c == 0)
+ if (c == 0) {
break;
+ }
str += String::chr(c);
}
return str;
}
}
void _fix_resources(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest) {
-
const int UTF8_FLAG = 0x00000100;
uint32_t string_block_len = decode_uint32(&p_manifest[16]);
@@ -1225,20 +1313,17 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
String package_name = p_preset->get("package/name");
for (uint32_t i = 0; i < string_count; i++) {
-
uint32_t offset = decode_uint32(&p_manifest[string_table_begins + i * 4]);
offset += string_table_begins + string_count * 4;
String str = _parse_string(&p_manifest[offset], string_flags & UTF8_FLAG);
if (str.begins_with("godot-project-name")) {
-
if (str == "godot-project-name") {
//project name
str = get_project_name(package_name);
} else {
-
String lang = str.substr(str.find_last("-") + 1, str.length()).replace("-", "_");
String prop = "application/config/name_" + lang;
if (ProjectSettings::get_singleton()->has_setting(prop)) {
@@ -1257,13 +1342,11 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
ret.resize(string_table_begins + string_table.size() * 4);
for (uint32_t i = 0; i < string_table_begins; i++) {
-
ret.write[i] = p_manifest[i];
}
int ofs = 0;
for (int i = 0; i < string_table.size(); i++) {
-
encode_uint32(ofs, &ret.write[string_table_begins + i * 4]);
ofs += string_table[i].length() * 2 + 2 + 2;
}
@@ -1271,7 +1354,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
ret.resize(ret.size() + ofs);
uint8_t *chars = &ret.write[ret.size() - ofs];
for (int i = 0; i < string_table.size(); i++) {
-
String s = string_table[i];
encode_uint16(s.length(), chars);
chars += 2;
@@ -1284,8 +1366,9 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
}
//pad
- while (ret.size() % 4)
+ while (ret.size() % 4) {
ret.push_back(0);
+ }
//change flags to not use utf8
encode_uint32(string_flags & ~0x100, &ret.write[28]);
@@ -1344,7 +1427,6 @@ public:
public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
-
String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
if (driver == "GLES2") {
r_features->push_back("etc");
@@ -1361,7 +1443,6 @@ public:
}
virtual void get_export_options(List<ExportOption> *r_options) {
-
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/degrees_of_freedom", PROPERTY_HINT_ENUM, "None,3DOF and 6DOF,6DOF"), 0));
@@ -1370,7 +1451,14 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_template/use_custom_build"), false));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/plugins", PROPERTY_HINT_PLACEHOLDER_TEXT, "Plugin1,Plugin2,..."), ""));
+
+ Vector<PluginConfig> plugins_configs = get_plugins();
+ for (int i = 0; i < plugins_configs.size(); i++) {
+ print_verbose("Found Android plugin " + plugins_configs[i].name);
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "plugins/" + plugins_configs[i].name), false));
+ }
+ plugins_changed = false;
+
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
@@ -1408,7 +1496,6 @@ public:
const char **perms = android_perms;
while (*perms) {
-
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "permissions/" + String(*perms).to_lower()), false));
perms++;
}
@@ -1426,8 +1513,16 @@ public:
return logo;
}
- virtual bool poll_export() {
+ virtual bool should_update_export_options() {
+ bool export_options_changed = plugins_changed;
+ if (export_options_changed) {
+ // don't clear unless we're reporting true, to avoid race
+ plugins_changed = false;
+ }
+ return export_options_changed;
+ }
+ virtual bool poll_export() {
bool dc = devices_changed;
if (dc) {
// don't clear unless we're reporting true, to avoid race
@@ -1437,25 +1532,21 @@ public:
}
virtual int get_options_count() const {
-
MutexLock lock(device_lock);
return devices.size();
}
virtual String get_options_tooltip() const {
-
return TTR("Select device from the list");
}
virtual String get_option_label(int p_index) const {
-
ERR_FAIL_INDEX_V(p_index, devices.size(), "");
MutexLock lock(device_lock);
return devices[p_index].name;
}
virtual String get_option_tooltip(int p_index) const {
-
ERR_FAIL_INDEX_V(p_index, devices.size(), "");
MutexLock lock(device_lock);
String s = devices[p_index].description;
@@ -1469,7 +1560,6 @@ public:
}
virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) {
-
ERR_FAIL_INDEX_V(p_device, devices.size(), ERR_INVALID_PARAMETER);
String can_export_error;
@@ -1493,8 +1583,9 @@ public:
const bool use_remote = (p_debug_flags & DEBUG_FLAG_REMOTE_DEBUG) || (p_debug_flags & DEBUG_FLAG_DUMB_CLIENT);
const bool use_reverse = devices[p_device].api_level >= 21;
- if (use_reverse)
+ if (use_reverse) {
p_debug_flags |= DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST;
+ }
String tmp_export_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmpexport.apk");
@@ -1553,7 +1644,6 @@ public:
if (use_remote) {
if (use_reverse) {
-
static const char *const msg = "--- Device API >= 21; debugging over USB ---";
EditorNode::get_singleton()->get_log()->add_message(msg, EditorLog::MSG_TYPE_EDITOR);
print_line(String(msg).to_upper());
@@ -1566,7 +1656,6 @@ public:
OS::get_singleton()->execute(adb, args, true, nullptr, nullptr, &rv);
if (p_debug_flags & DEBUG_FLAG_REMOTE_DEBUG) {
-
int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port");
args.clear();
args.push_back("-s");
@@ -1580,7 +1669,6 @@ public:
}
if (p_debug_flags & DEBUG_FLAG_DUMB_CLIENT) {
-
int fs_port = EditorSettings::get_singleton()->get("filesystem/file_server/port");
args.clear();
@@ -1594,7 +1682,6 @@ public:
print_line("Reverse result2: " + itos(rv));
}
} else {
-
static const char *const msg = "--- Device API < 21; debugging over Wi-Fi ---";
EditorNode::get_singleton()->get_log()->add_message(msg, EditorLog::MSG_TYPE_EDITOR);
print_line(String(msg).to_upper());
@@ -1634,7 +1721,6 @@ public:
}
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
-
String err;
bool valid = false;
@@ -1668,7 +1754,6 @@ public:
String adb = EditorSettings::get_singleton()->get("export/android/adb");
if (!FileAccess::exists(adb)) {
-
valid = false;
err += TTR("ADB executable not configured in the Editor Settings.") + "\n";
}
@@ -1676,7 +1761,6 @@ public:
String js = EditorSettings::get_singleton()->get("export/android/jarsigner");
if (!FileAccess::exists(js)) {
-
valid = false;
err += TTR("OpenJDK jarsigner not configured in the Editor Settings.") + "\n";
}
@@ -1684,7 +1768,6 @@ public:
String dk = p_preset->get("keystore/debug");
if (!FileAccess::exists(dk)) {
-
dk = EditorSettings::get_singleton()->get("export/android/debug_keystore");
if (!FileAccess::exists(dk)) {
valid = false;
@@ -1699,7 +1782,7 @@ public:
valid = false;
} else {
Error errn;
- DirAccessRef da = DirAccess::open(sdk_path.plus_file("tools"), &errn);
+ DirAccessRef da = DirAccess::open(sdk_path.plus_file("platform-tools"), &errn);
if (errn != OK) {
err += TTR("Invalid Android SDK path for custom build in Editor Settings.") + "\n";
valid = false;
@@ -1707,7 +1790,6 @@ public:
}
if (!FileAccess::exists("res://android/build/build.gradle")) {
-
err += TTR("Android build template not installed in the project. Install it from the Project menu.") + "\n";
valid = false;
}
@@ -1716,7 +1798,6 @@ public:
bool apk_expansion = p_preset->get("apk_expansion/enable");
if (apk_expansion) {
-
String apk_expansion_pkey = p_preset->get("apk_expansion/public_key");
if (apk_expansion_pkey == "") {
@@ -1730,7 +1811,6 @@ public:
String pn_err;
if (!is_package_name_valid(get_package_name(pn), &pn_err)) {
-
valid = false;
err += TTR("Invalid package name:") + " " + pn_err + "\n";
}
@@ -1752,7 +1832,6 @@ public:
}
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) {
-
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
String src_apk;
@@ -1789,18 +1868,22 @@ public:
#endif
String build_path = ProjectSettings::get_singleton()->get_resource_path().plus_file("android/build");
- String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().plus_file("android/plugins");
build_command = build_path.plus_file(build_command);
String package_name = get_package_name(p_preset->get("package/unique_name"));
- String plugins = p_preset->get("custom_template/plugins");
+
+ Vector<PluginConfig> enabled_plugins = get_enabled_plugins(p_preset);
+ String local_plugins_binaries = get_plugins_binaries(BINARY_TYPE_LOCAL, enabled_plugins);
+ String remote_plugins_binaries = get_plugins_binaries(BINARY_TYPE_REMOTE, enabled_plugins);
+ String custom_maven_repos = get_plugins_custom_maven_repos(enabled_plugins);
List<String> cmdline;
cmdline.push_back("build");
cmdline.push_back("-Pexport_package_name=" + package_name); // argument to specify the package name.
- cmdline.push_back("-Pcustom_template_plugins_dir=" + plugins_dir); // argument to specify the plugins directory.
- cmdline.push_back("-Pcustom_template_plugins=" + plugins); // argument to specify the list of plugins to enable.
+ cmdline.push_back("-Pplugins_local_binaries=" + local_plugins_binaries); // argument to specify the list of plugins local dependencies.
+ cmdline.push_back("-Pplugins_remote_binaries=" + remote_plugins_binaries); // argument to specify the list of plugins remote dependencies.
+ cmdline.push_back("-Pplugins_maven_repos=" + custom_maven_repos); // argument to specify the list of custom maven repos for the plugins dependencies.
cmdline.push_back("-p"); // argument to specify the start directory.
cmdline.push_back(build_path); // start directory.
/*{ used for debug
@@ -1827,11 +1910,11 @@ public:
}
} else {
-
- if (p_debug)
+ if (p_debug) {
src_apk = p_preset->get("custom_template/debug");
- else
+ } else {
src_apk = p_preset->get("custom_template/release");
+ }
src_apk = src_apk.strip_edges();
if (src_apk == "") {
@@ -1860,7 +1943,6 @@ public:
unzFile pkg = unzOpen2(src_apk.utf8().get_data(), &io);
if (!pkg) {
-
EditorNode::add_io_error("Could not find template APK to export:\n" + src_apk);
return ERR_FILE_NOT_FOUND;
}
@@ -1934,7 +2016,6 @@ public:
Vector<String> invalid_abis(enabled_abis);
while (ret == UNZ_OK) {
-
//get filename
unz_file_info info;
char fname[16384];
@@ -2040,7 +2121,6 @@ public:
gen_export_flags(cl, p_flags);
if (p_flags & DEBUG_FLAG_DUMB_CLIENT) {
-
APKExportData ed;
ed.ep = &ep;
ed.apk = unaligned_apk;
@@ -2049,7 +2129,6 @@ public:
//all files
if (apk_expansion) {
-
String apkfname = "main." + itos(version_code) + "." + get_package_name(package_name) + ".obb";
String fullpath = p_path.get_base_dir().plus_file(apkfname);
err = save_pack(p_preset, fullpath);
@@ -2068,7 +2147,6 @@ public:
cl.push_back(apk_expansion_pkey.strip_edges());
} else {
-
APKExportData ed;
ed.ep = &ep;
ed.apk = unaligned_apk;
@@ -2085,14 +2163,17 @@ public:
cl.push_back("--xr_mode_regular");
}
- if (use_32_fb)
+ if (use_32_fb) {
cl.push_back("--use_depth_32");
+ }
- if (immersive)
+ if (immersive) {
cl.push_back("--use_immersive");
+ }
- if (debug_opengl)
+ if (debug_opengl) {
cl.push_back("--debug_opengl");
+ }
if (cl.size()) {
//add comandline
@@ -2100,13 +2181,13 @@ public:
clf.resize(4);
encode_uint32(cl.size(), &clf.write[0]);
for (int i = 0; i < cl.size(); i++) {
-
print_line(itos(i) + " param: " + cl[i]);
CharString txt = cl[i].utf8();
int base = clf.size();
int length = txt.length();
- if (!length)
+ if (!length) {
continue;
+ }
clf.resize(base + 4 + length);
encode_uint32(length, &clf.write[base]);
copymem(&clf.write[base + 4], txt.ptr(), length);
@@ -2137,7 +2218,6 @@ public:
}
if (_signed) {
-
String jarsigner = EditorSettings::get_singleton()->get("export/android/jarsigner");
if (!FileAccess::exists(jarsigner)) {
EditorNode::add_io_error("'jarsigner' could not be found.\nPlease supply a path in the Editor Settings.\nThe resulting APK is unsigned.");
@@ -2148,13 +2228,11 @@ public:
String password;
String user;
if (p_debug) {
-
keystore = p_preset->get("keystore/debug");
password = p_preset->get("keystore/debug_password");
user = p_preset->get("keystore/debug_user");
if (keystore.empty()) {
-
keystore = EditorSettings::get_singleton()->get("export/android/debug_keystore");
password = EditorSettings::get_singleton()->get("export/android/debug_keystore_pass");
user = EditorSettings::get_singleton()->get("export/android/debug_keystore_user");
@@ -2231,7 +2309,6 @@ public:
unzFile tmp_unaligned = unzOpen2(tmp_unaligned_path.utf8().get_data(), &io);
if (!tmp_unaligned) {
-
EditorNode::add_io_error("Could not unzip temporary unaligned APK.");
CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND);
}
@@ -2248,7 +2325,6 @@ public:
// following what is done in https://github.com/android/platform_build/blob/master/tools/zipalign/ZipAlign.cpp
int bias = 0;
while (ret == UNZ_OK) {
-
unz_file_info info;
memset(&info, 0, sizeof(info));
@@ -2307,7 +2383,6 @@ public:
}
virtual void get_platform_features(List<String> *r_features) {
-
r_features->push_back("mobile");
r_features->push_back("Android");
}
@@ -2316,7 +2391,6 @@ public:
}
EditorExportPlatformAndroid() {
-
Ref<Image> img = memnew(Image(_android_logo));
logo.instance();
logo->create_from_image(img);
@@ -2326,19 +2400,19 @@ public:
run_icon->create_from_image(img);
devices_changed = true;
+ plugins_changed = true;
quit_request = false;
- device_thread = Thread::create(_device_poll_thread, this);
+ check_for_changes_thread = Thread::create(_check_for_changes_poll_thread, this);
}
~EditorExportPlatformAndroid() {
quit_request = true;
- Thread::wait_to_finish(device_thread);
- memdelete(device_thread);
+ Thread::wait_to_finish(check_for_changes_thread);
+ memdelete(check_for_changes_thread);
}
};
void register_android_exporter() {
-
String exe_ext;
if (OS::get_singleton()->get_name() == "Windows") {
exe_ext = "*.exe";
diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp
index fa805ec4f3..05d5fb576d 100644
--- a/platform/android/file_access_android.cpp
+++ b/platform/android/file_access_android.cpp
@@ -39,12 +39,10 @@ AAssetManager *FileAccessAndroid::asset_manager = nullptr;
}*/
FileAccess *FileAccessAndroid::create_android() {
-
return memnew(FileAccessAndroid);
}
Error FileAccessAndroid::_open(const String &p_path, int p_mode_flags) {
-
String path = fix_path(p_path).simplify_path();
if (path.begins_with("/"))
path = path.substr(1, path.length());
@@ -64,7 +62,6 @@ Error FileAccessAndroid::_open(const String &p_path, int p_mode_flags) {
}
void FileAccessAndroid::close() {
-
if (!a)
return;
AAsset_close(a);
@@ -72,12 +69,10 @@ void FileAccessAndroid::close() {
}
bool FileAccessAndroid::is_open() const {
-
return a != nullptr;
}
void FileAccessAndroid::seek(size_t p_position) {
-
ERR_FAIL_COND(!a);
AAsset_seek(a, p_position, SEEK_SET);
pos = p_position;
@@ -90,29 +85,24 @@ void FileAccessAndroid::seek(size_t p_position) {
}
void FileAccessAndroid::seek_end(int64_t p_position) {
-
ERR_FAIL_COND(!a);
AAsset_seek(a, p_position, SEEK_END);
pos = len + p_position;
}
size_t FileAccessAndroid::get_position() const {
-
return pos;
}
size_t FileAccessAndroid::get_len() const {
-
return len;
}
bool FileAccessAndroid::eof_reached() const {
-
return eof;
}
uint8_t FileAccessAndroid::get_8() const {
-
if (pos >= len) {
eof = true;
return 0;
@@ -125,7 +115,6 @@ uint8_t FileAccessAndroid::get_8() const {
}
int FileAccessAndroid::get_buffer(uint8_t *p_dst, int p_length) const {
-
off_t r = AAsset_read(a, p_dst, p_length);
if (pos + p_length > len) {
@@ -133,7 +122,6 @@ int FileAccessAndroid::get_buffer(uint8_t *p_dst, int p_length) const {
}
if (r >= 0) {
-
pos += r;
if (pos > len) {
pos = len;
@@ -143,22 +131,18 @@ int FileAccessAndroid::get_buffer(uint8_t *p_dst, int p_length) const {
}
Error FileAccessAndroid::get_error() const {
-
return eof ? ERR_FILE_EOF : OK; //not sure what else it may happen
}
void FileAccessAndroid::flush() {
-
ERR_FAIL();
}
void FileAccessAndroid::store_8(uint8_t p_dest) {
-
ERR_FAIL();
}
bool FileAccessAndroid::file_exists(const String &p_path) {
-
String path = fix_path(p_path).simplify_path();
if (path.begins_with("/"))
path = path.substr(1, path.length());
diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h
index 6b5ec541fd..a347c63ffb 100644
--- a/platform/android/file_access_android.h
+++ b/platform/android/file_access_android.h
@@ -38,7 +38,6 @@
//#include <android_native_app_glue.h>
class FileAccessAndroid : public FileAccess {
-
static FileAccess *create_android();
mutable AAsset *a;
mutable size_t len;
diff --git a/platform/android/file_access_jandroid.cpp b/platform/android/file_access_jandroid.cpp
index e088eca8ef..df8b57fd3a 100644
--- a/platform/android/file_access_jandroid.cpp
+++ b/platform/android/file_access_jandroid.cpp
@@ -44,12 +44,10 @@ jmethodID FileAccessJAndroid::_file_eof = 0;
jmethodID FileAccessJAndroid::_file_close = 0;
FileAccess *FileAccessJAndroid::create_jandroid() {
-
return memnew(FileAccessJAndroid);
}
Error FileAccessJAndroid::_open(const String &p_path, int p_mode_flags) {
-
if (is_open())
close();
@@ -75,7 +73,6 @@ Error FileAccessJAndroid::_open(const String &p_path, int p_mode_flags) {
}
void FileAccessJAndroid::close() {
-
if (!is_open())
return;
@@ -86,12 +83,10 @@ void FileAccessJAndroid::close() {
}
bool FileAccessJAndroid::is_open() const {
-
return id != 0;
}
void FileAccessJAndroid::seek(size_t p_position) {
-
JNIEnv *env = ThreadAndroid::get_env();
ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
@@ -99,42 +94,37 @@ void FileAccessJAndroid::seek(size_t p_position) {
}
void FileAccessJAndroid::seek_end(int64_t p_position) {
-
ERR_FAIL_COND_MSG(!is_open(), "File must be opened before use.");
seek(get_len());
}
size_t FileAccessJAndroid::get_position() const {
-
JNIEnv *env = ThreadAndroid::get_env();
ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
return env->CallIntMethod(io, _file_tell, id);
}
size_t FileAccessJAndroid::get_len() const {
-
JNIEnv *env = ThreadAndroid::get_env();
ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
return env->CallIntMethod(io, _file_get_size, id);
}
bool FileAccessJAndroid::eof_reached() const {
-
JNIEnv *env = ThreadAndroid::get_env();
ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
return env->CallIntMethod(io, _file_eof, id);
}
uint8_t FileAccessJAndroid::get_8() const {
-
ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
uint8_t byte;
get_buffer(&byte, 1);
return byte;
}
-int FileAccessJAndroid::get_buffer(uint8_t *p_dst, int p_length) const {
+int FileAccessJAndroid::get_buffer(uint8_t *p_dst, int p_length) const {
ERR_FAIL_COND_V_MSG(!is_open(), 0, "File must be opened before use.");
if (p_length == 0)
return 0;
@@ -150,7 +140,6 @@ int FileAccessJAndroid::get_buffer(uint8_t *p_dst, int p_length) const {
}
Error FileAccessJAndroid::get_error() const {
-
if (eof_reached())
return ERR_FILE_EOF;
return OK;
@@ -163,7 +152,6 @@ void FileAccessJAndroid::store_8(uint8_t p_dest) {
}
bool FileAccessJAndroid::file_exists(const String &p_path) {
-
JNIEnv *env = ThreadAndroid::get_env();
String path = fix_path(p_path).simplify_path();
@@ -184,7 +172,6 @@ bool FileAccessJAndroid::file_exists(const String &p_path) {
}
void FileAccessJAndroid::setup(jobject p_io) {
-
io = p_io;
JNIEnv *env = ThreadAndroid::get_env();
@@ -201,12 +188,10 @@ void FileAccessJAndroid::setup(jobject p_io) {
}
FileAccessJAndroid::FileAccessJAndroid() {
-
id = 0;
}
FileAccessJAndroid::~FileAccessJAndroid() {
-
if (is_open())
close();
}
diff --git a/platform/android/file_access_jandroid.h b/platform/android/file_access_jandroid.h
index b361c64922..e252a4d3ac 100644
--- a/platform/android/file_access_jandroid.h
+++ b/platform/android/file_access_jandroid.h
@@ -34,7 +34,6 @@
#include "core/os/file_access.h"
#include "java_godot_lib_jni.h"
class FileAccessJAndroid : public FileAccess {
-
static jobject io;
static jclass cls;
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
index cc480d1c84..f5b1d29f22 100644
--- a/platform/android/java/app/AndroidManifest.xml
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -32,8 +32,8 @@
<!-- Metadata populated at export time and used by Godot to figure out which plugins must be enabled. -->
<meta-data
- android:name="custom_template_plugins"
- android:value="custom_template_plugins_value"/>
+ android:name="plugins"
+ android:value="plugins_value"/>
<activity
android:name=".GodotApp"
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle
index 99080eeb3c..ea341b37b1 100644
--- a/platform/android/java/app/build.gradle
+++ b/platform/android/java/app/build.gradle
@@ -21,6 +21,16 @@ allprojects {
mavenCentral()
google()
jcenter()
+
+ // Godot user plugins custom maven repos
+ String[] mavenRepos = getGodotPluginsMavenRepos()
+ if (mavenRepos != null && mavenRepos.size() > 0) {
+ for (String repoUrl : mavenRepos) {
+ maven {
+ url repoUrl
+ }
+ }
+ }
}
}
@@ -40,15 +50,18 @@ dependencies {
releaseImplementation fileTree(dir: 'libs/release', include: ['*.jar', '*.aar'])
}
- // Godot prebuilt plugins
- implementation fileTree(dir: 'libs/plugins', include: ["GodotPayment*.aar"])
+ // Godot user plugins remote dependencies
+ String[] remoteDeps = getGodotPluginsRemoteBinaries()
+ if (remoteDeps != null && remoteDeps.size() > 0) {
+ for (String dep : remoteDeps) {
+ implementation dep
+ }
+ }
- // Godot user plugins dependencies
- String pluginsDir = getGodotPluginsDirectory()
- String[] pluginsBinaries = getGodotPluginsBinaries()
- if (pluginsDir != null && !pluginsDir.isEmpty() &&
- pluginsBinaries != null && pluginsBinaries.size() > 0) {
- implementation fileTree(dir: pluginsDir, include: pluginsBinaries)
+ // Godot user plugins local dependencies
+ String[] pluginsBinaries = getGodotPluginsLocalBinaries()
+ if (pluginsBinaries != null && pluginsBinaries.size() > 0) {
+ implementation files(pluginsBinaries)
}
}
@@ -76,7 +89,9 @@ android {
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
- doNotStrip '**/*.so'
+
+ // Should be uncommented for development purpose within Android Studio
+ // doNotStrip '**/*.so'
}
// Both signing and zip-aligning will be done at export time
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index aa98194a10..5251bc3066 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -4,18 +4,18 @@ ext.versions = [
minSdk : 18,
targetSdk : 29,
buildTools : '29.0.3',
- supportCoreUtils : '28.0.0',
+ supportCoreUtils : '1.0.0',
kotlinVersion : '1.3.61',
- v4Support : '28.0.0'
+ v4Support : '1.0.0'
]
ext.libraries = [
androidGradlePlugin: "com.android.tools.build:gradle:$versions.androidGradlePlugin",
- supportCoreUtils : "com.android.support:support-core-utils:$versions.supportCoreUtils",
+ supportCoreUtils : "androidx.legacy:legacy-support-core-utils:$versions.supportCoreUtils",
kotlinGradlePlugin : "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlinVersion",
kotlinStdLib : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlinVersion",
- v4Support : "com.android.support:support-v4:$versions.v4Support"
+ v4Support : "androidx.legacy:legacy-support-v4:$versions.v4Support"
]
ext.getExportPackageName = { ->
@@ -28,39 +28,68 @@ ext.getExportPackageName = { ->
return appId
}
+final String PLUGIN_VALUE_SEPARATOR_REGEX = "\\|"
+
/**
- * Parse the project properties for the 'custom_template_plugins' property and return
- * their binaries for inclusion in the build dependencies.
- *
- * The listed plugins must have their binaries in the project plugins directory.
+ * Parse the project properties for the 'plugins_maven_repos' property and return the list
+ * of maven repos.
*/
-ext.getGodotPluginsBinaries = { ->
- String[] binDeps = []
+ext.getGodotPluginsMavenRepos = { ->
+ Set<String> mavenRepos = []
- // Retrieve the list of enabled plugins.
- if (project.hasProperty("custom_template_plugins")) {
- String pluginsList = project.property("custom_template_plugins")
- if (pluginsList != null && !pluginsList.trim().isEmpty()) {
- for (String plugin : pluginsList.split(",")) {
- binDeps += plugin.trim() + "*.aar"
+ // Retrieve the list of maven repos.
+ if (project.hasProperty("plugins_maven_repos")) {
+ String mavenReposProperty = project.property("plugins_maven_repos")
+ if (mavenReposProperty != null && !mavenReposProperty.trim().isEmpty()) {
+ for (String mavenRepoUrl : mavenReposProperty.split(PLUGIN_VALUE_SEPARATOR_REGEX)) {
+ mavenRepos += mavenRepoUrl.trim()
}
}
}
- return binDeps
+ return mavenRepos
+}
+
+/**
+ * Parse the project properties for the 'plugins_remote_binaries' property and return
+ * it for inclusion in the build dependencies.
+ */
+ext.getGodotPluginsRemoteBinaries = { ->
+ Set<String> remoteDeps = []
+
+ // Retrieve the list of remote plugins binaries.
+ if (project.hasProperty("plugins_remote_binaries")) {
+ String remoteDepsList = project.property("plugins_remote_binaries")
+ if (remoteDepsList != null && !remoteDepsList.trim().isEmpty()) {
+ for (String dep: remoteDepsList.split(PLUGIN_VALUE_SEPARATOR_REGEX)) {
+ remoteDeps += dep.trim()
+ }
+ }
+ }
+ return remoteDeps
}
/**
- * Parse the project properties for the 'custom_template_plugins_dir' property and return
- * its value.
+ * Parse the project properties for the 'plugins_local_binaries' property and return
+ * their binaries for inclusion in the build dependencies.
*
- * The returned value is the directory containing user plugins.
+ * Returns the prebuilt plugins if the 'plugins_local_binaries' property is unavailable.
*/
-ext.getGodotPluginsDirectory = { ->
- // The plugins directory is provided by the 'custom_template_plugins_dir' property.
- String pluginsDir = project.hasProperty("custom_template_plugins_dir")
- ? project.property("custom_template_plugins_dir")
- : ""
+ext.getGodotPluginsLocalBinaries = { ->
+ // Set the prebuilt plugins as default. If custom build is enabled,
+ // the 'plugins_local_binaries' will be defined so we can use it instead.
+ Set<String> binDeps = ["libs/plugins/GodotPayment.release.aar"]
+
+ // Retrieve the list of local plugins binaries.
+ if (project.hasProperty("plugins_local_binaries")) {
+ binDeps.clear()
+ String pluginsList = project.property("plugins_local_binaries")
+ if (pluginsList != null && !pluginsList.trim().isEmpty()) {
+ for (String plugin : pluginsList.split(PLUGIN_VALUE_SEPARATOR_REGEX)) {
+ binDeps += plugin.trim()
+ }
+ }
+ }
- return pluginsDir
+ return binDeps
}
diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle
index 865b61956c..01a3607b20 100644
--- a/platform/android/java/build.gradle
+++ b/platform/android/java/build.gradle
@@ -140,7 +140,7 @@ task generateGodotTemplates(type: GradleBuild) {
startParameter.excludedTaskNames += ":lib:" + getSconsTaskName(buildType)
}
- tasks = ["copyGodotPaymentPluginToAppModule"]
+ tasks = []
// Only build the apks and aar files for which we have native shared libraries.
for (String target : supportedTargets) {
@@ -161,6 +161,7 @@ task generateGodotTemplates(type: GradleBuild) {
}
}
+ dependsOn 'copyGodotPaymentPluginToAppModule'
finalizedBy 'zipCustomBuild'
}
diff --git a/platform/android/java/gradle.properties b/platform/android/java/gradle.properties
index aac7c9b461..e14cd5ba5c 100644
--- a/platform/android/java/gradle.properties
+++ b/platform/android/java/gradle.properties
@@ -7,6 +7,9 @@
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
+android.enableJetifier=true
+android.useAndroidX=true
+
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle
index 6bb438c249..19eee5a315 100644
--- a/platform/android/java/lib/build.gradle
+++ b/platform/android/java/lib/build.gradle
@@ -26,7 +26,9 @@ android {
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
- doNotStrip '**/*.so'
+
+ // Should be uncommented for development purpose within Android Studio
+ // doNotStrip '**/*.so'
}
sourceSets {
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
index 0abaf2e052..d481c22204 100644
--- a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java
@@ -29,9 +29,9 @@ import com.google.android.vending.expansion.downloader.IDownloaderClient;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
-import android.os.Build;
import android.os.Messenger;
-import android.support.v4.app.NotificationCompat;
+
+import androidx.core.app.NotificationCompat;
/**
* This class handles displaying the notification associated with the download
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java
index 594cae774b..8b7a9c6c74 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java
@@ -34,16 +34,13 @@ import java.util.HashMap;
import java.util.Set;
public class Dictionary extends HashMap<String, Object> {
-
protected String[] keys_cache;
public String[] get_keys() {
-
String[] ret = new String[size()];
int i = 0;
Set<String> keys = keySet();
for (String key : keys) {
-
ret[i] = key;
i++;
};
@@ -52,12 +49,10 @@ public class Dictionary extends HashMap<String, Object> {
};
public Object[] get_values() {
-
Object[] ret = new Object[size()];
int i = 0;
Set<String> keys = keySet();
for (String key : keys) {
-
ret[i] = get(key);
i++;
};
@@ -70,7 +65,6 @@ public class Dictionary extends HashMap<String, Object> {
};
public void set_values(Object[] vals) {
-
int i = 0;
for (String key : keys_cache) {
put(key, vals[i]);
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index bf0d1c6273..f27d8620ec 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -30,6 +30,13 @@
package org.godotengine.godot;
+import org.godotengine.godot.input.GodotEditText;
+import org.godotengine.godot.plugin.GodotPlugin;
+import org.godotengine.godot.plugin.GodotPluginRegistry;
+import org.godotengine.godot.utils.GodotNetUtils;
+import org.godotengine.godot.utils.PermissionsUtil;
+import org.godotengine.godot.xr.XRMode;
+
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
@@ -59,10 +66,6 @@ import android.os.Messenger;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.provider.Settings.Secure;
-import android.support.annotation.CallSuper;
-import android.support.annotation.Keep;
-import android.support.annotation.NonNull;
-import android.support.v4.app.FragmentActivity;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -77,6 +80,12 @@ import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
+
+import androidx.annotation.CallSuper;
+import androidx.annotation.Keep;
+import androidx.annotation.NonNull;
+import androidx.fragment.app.FragmentActivity;
+
import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
import com.google.android.vending.expansion.downloader.DownloaderServiceMarshaller;
@@ -84,6 +93,7 @@ import com.google.android.vending.expansion.downloader.Helpers;
import com.google.android.vending.expansion.downloader.IDownloaderClient;
import com.google.android.vending.expansion.downloader.IDownloaderService;
import com.google.android.vending.expansion.downloader.IStub;
+
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
@@ -91,15 +101,8 @@ import java.security.MessageDigest;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
-import org.godotengine.godot.input.GodotEditText;
-import org.godotengine.godot.plugin.GodotPlugin;
-import org.godotengine.godot.plugin.GodotPluginRegistry;
-import org.godotengine.godot.utils.GodotNetUtils;
-import org.godotengine.godot.utils.PermissionsUtil;
-import org.godotengine.godot.xr.XRMode;
public abstract class Godot extends FragmentActivity implements SensorEventListener, IDownloaderClient {
-
private IStub mDownloaderClientStub;
private TextView mStatusText;
private TextView mProgressFraction;
@@ -248,7 +251,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
mRenderView.queueOnRenderThread(new Runnable() {
@Override
public void run() {
-
// Must occur after GodotLib.setup has completed.
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
plugin.onRegisterPluginWithGodotNative();
@@ -358,7 +360,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
for (int i = 0; i < argc; i++) {
r = is.read(len);
if (r < 4) {
-
return new String[0];
}
int strlen = ((int)(len[3] & 0xFF) << 24) | ((int)(len[2] & 0xFF) << 16) | ((int)(len[1] & 0xFF) << 8) | ((int)(len[0] & 0xFF));
@@ -406,9 +407,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
String expansion_pack_path;
private void initializeGodot() {
-
if (expansion_pack_path != null) {
-
String[] new_cmdline;
int cll = 0;
if (command_line != null) {
@@ -455,7 +454,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
@Override
protected void onCreate(Bundle icicle) {
-
super.onCreate(icicle);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
@@ -472,7 +470,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
List<String> new_args = new LinkedList<String>();
for (int i = 0; i < command_line.length; i++) {
-
boolean has_extra = i < command_line.length - 1;
if (command_line[i].equals(XRMode.REGULAR.cmdLineArg)) {
xrMode = XRMode.REGULAR;
@@ -516,7 +513,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
if (new_args.isEmpty()) {
command_line = null;
} else {
-
command_line = new_args.toArray(new String[new_args.size()]);
}
if (use_apk_expansion && main_pack_md5 != null && main_pack_key != null) {
@@ -538,7 +534,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
boolean pack_valid = true;
if (!f.exists()) {
-
pack_valid = false;
} else if (obbIsCorrupted(expansion_pack_path, main_pack_md5)) {
@@ -550,7 +545,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
}
if (!pack_valid) {
-
Intent notifierIntent = new Intent(this, this.getClass());
notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP);
@@ -599,7 +593,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
@Override
protected void onDestroy() {
-
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
plugin.onMainDestroy();
}
@@ -634,7 +627,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
}
public String getClipboard() {
-
String copiedText = "";
if (mClipboard.getPrimaryClip() != null) {
@@ -646,7 +638,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
}
public void setClipboard(String p_text) {
-
ClipData clip = ClipData.newPlainText("myLabel", p_text);
mClipboard.setPrimaryClip(clip);
}
@@ -806,9 +797,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
}
private boolean obbIsCorrupted(String f, String main_pack_md5) {
-
try {
-
InputStream fis = new FileInputStream(f);
// Create MD5 Hash
@@ -849,7 +838,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
}
public boolean gotTouchEvent(final MotionEvent event) {
-
final int evcount = event.getPointerCount();
if (evcount == 0)
return true;
@@ -858,7 +846,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
final int[] arr = new int[event.getPointerCount() * 3];
for (int i = 0; i < event.getPointerCount(); i++) {
-
arr[i * 3 + 0] = (int)event.getPointerId(i);
arr[i * 3 + 1] = (int)event.getX(i);
arr[i * 3 + 2] = (int)event.getY(i);
@@ -917,7 +904,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe
int cnt = 0;
for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0)
;
- if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event);
+ if (cnt == 0)
+ return super.onKeyMultiple(inKeyCode, repeatCount, event);
mRenderView.queueOnRenderThread(new Runnable() {
// This method will be called on the rendering thread:
public void run() {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
index 1fb242d0bc..a3dae15980 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
@@ -35,6 +35,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.Log;
+
import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
/**
@@ -45,7 +46,6 @@ import com.google.android.vending.expansion.downloader.DownloaderClientMarshalle
* <receiver android:name=".GodotDownloaderAlarmReceiver"/>
*/
public class GodotDownloaderAlarmReceiver extends BroadcastReceiver {
-
@Override
public void onReceive(Context context, Intent intent) {
Log.d("GODOT", "Alarma recivida");
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
index 7e74e8a80d..434da95bc0 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java
@@ -33,6 +33,7 @@ package org.godotengine.godot;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
+
import com.google.android.vending.expansion.downloader.impl.DownloaderService;
/**
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
index 9be93243b8..14dd893faa 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
@@ -29,13 +29,7 @@
/*************************************************************************/
package org.godotengine.godot;
-import android.annotation.SuppressLint;
-import android.graphics.PixelFormat;
-import android.opengl.GLSurfaceView;
-import android.view.GestureDetector;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.SurfaceView;
+
import org.godotengine.godot.input.GodotGestureHandler;
import org.godotengine.godot.input.GodotInputHandler;
import org.godotengine.godot.utils.GLUtils;
@@ -47,6 +41,14 @@ import org.godotengine.godot.xr.regular.RegularConfigChooser;
import org.godotengine.godot.xr.regular.RegularContextFactory;
import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser;
+import android.annotation.SuppressLint;
+import android.graphics.PixelFormat;
+import android.opengl.GLSurfaceView;
+import android.view.GestureDetector;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.SurfaceView;
+
/**
* A simple GLSurfaceView sub-class that demonstrate how to perform
* OpenGL ES 2.0 rendering into a GL Surface. Note the following important
@@ -66,7 +68,6 @@ import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser;
* bit depths). Failure to do so would result in an EGL_BAD_MATCH error.
*/
public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView {
-
private final Godot activity;
private final GodotInputHandler inputHandler;
private final GestureDetector detector;
@@ -138,11 +139,9 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView
}
private void init(XRMode xrMode, boolean translucent, int depth, int stencil) {
-
setPreserveEGLContextOnPause(true);
setFocusableInTouchMode(true);
switch (xrMode) {
-
case OVR:
// Replace the default egl config chooser.
setEGLConfigChooser(new OvrConfigChooser());
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index 016a3a8d18..93f4786e83 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -29,6 +29,9 @@
/*************************************************************************/
package org.godotengine.godot;
+
+import org.godotengine.godot.input.*;
+
import android.content.*;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -39,16 +42,14 @@ import android.os.*;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseArray;
+
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
-import org.godotengine.godot.input.*;
-//android.os.Build
// Wrapper for native library
public class GodotIO {
-
AssetManager am;
Godot activity;
GodotEditText edit;
@@ -68,7 +69,6 @@ public class GodotIO {
public int last_file_id = 1;
class AssetData {
-
public boolean eof = false;
public String path;
public InputStream is;
@@ -79,7 +79,6 @@ public class GodotIO {
SparseArray<AssetData> streams;
public int file_open(String path, boolean write) {
-
//System.out.printf("file_open: Attempt to Open %s\n",path);
//Log.v("MyApp", "TRYING TO OPEN FILE: " + path);
@@ -92,7 +91,6 @@ public class GodotIO {
ad.is = am.open(path);
} catch (Exception e) {
-
//System.out.printf("Exception on file_open: %s\n",path);
return -1;
}
@@ -100,7 +98,6 @@ public class GodotIO {
try {
ad.len = ad.is.available();
} catch (Exception e) {
-
System.out.printf("Exception availabling on file_open: %s\n", path);
return -1;
}
@@ -113,7 +110,6 @@ public class GodotIO {
return last_file_id;
}
public int file_get_size(int id) {
-
if (streams.get(id) == null) {
System.out.printf("file_get_size: Invalid file id: %d\n", id);
return -1;
@@ -122,7 +118,6 @@ public class GodotIO {
return streams.get(id).len;
}
public void file_seek(int id, int bytes) {
-
if (streams.get(id) == null) {
System.out.printf("file_get_size: Invalid file id: %d\n", id);
return;
@@ -135,7 +130,6 @@ public class GodotIO {
bytes = 0;
try {
-
if (bytes > (int)ad.pos) {
int todo = bytes - (int)ad.pos;
while (todo > 0) {
@@ -143,7 +137,6 @@ public class GodotIO {
}
ad.pos = bytes;
} else if (bytes < (int)ad.pos) {
-
ad.is = am.open(ad.path);
ad.pos = bytes;
@@ -155,14 +148,12 @@ public class GodotIO {
ad.eof = false;
} catch (IOException e) {
-
System.out.printf("Exception on file_seek: %s\n", e);
return;
}
}
public int file_tell(int id) {
-
if (streams.get(id) == null) {
System.out.printf("file_read: Can't tell eof for invalid file id: %d\n", id);
return 0;
@@ -172,7 +163,6 @@ public class GodotIO {
return ad.pos;
}
public boolean file_eof(int id) {
-
if (streams.get(id) == null) {
System.out.printf("file_read: Can't check eof for invalid file id: %d\n", id);
return false;
@@ -183,7 +173,6 @@ public class GodotIO {
}
public byte[] file_read(int id, int bytes) {
-
if (streams.get(id) == null) {
System.out.printf("file_read: Can't read invalid file id: %d\n", id);
return new byte[0];
@@ -192,13 +181,11 @@ public class GodotIO {
AssetData ad = streams.get(id);
if (ad.pos + bytes > ad.len) {
-
bytes = ad.len - ad.pos;
ad.eof = true;
}
if (bytes == 0) {
-
return new byte[0];
}
@@ -207,7 +194,6 @@ public class GodotIO {
try {
r = ad.is.read(buf1);
} catch (IOException e) {
-
System.out.printf("Exception on file_read: %s\n", e);
return new byte[bytes];
}
@@ -219,19 +205,16 @@ public class GodotIO {
ad.pos += r;
if (r < bytes) {
-
byte[] buf2 = new byte[r];
for (int i = 0; i < r; i++)
buf2[i] = buf1[i];
return buf2;
} else {
-
return buf1;
}
}
public void file_close(int id) {
-
if (streams.get(id) == null) {
System.out.printf("file_close: Can't close invalid file id: %d\n", id);
return;
@@ -245,7 +228,6 @@ public class GodotIO {
/////////////////////////
class AssetDir {
-
public String[] files;
public int current;
public String path;
@@ -256,7 +238,6 @@ public class GodotIO {
SparseArray<AssetDir> dirs;
public int dir_open(String path) {
-
AssetDir ad = new AssetDir();
ad.current = 0;
ad.path = path;
@@ -269,7 +250,6 @@ public class GodotIO {
return -1;
}
} catch (IOException e) {
-
System.out.printf("Exception on dir_open: %s\n", e);
return -1;
}
@@ -308,7 +288,6 @@ public class GodotIO {
}
public String dir_next(int id) {
-
if (dirs.get(id) == null) {
System.out.printf("dir_next: invalid dir id: %d\n", id);
return "";
@@ -327,7 +306,6 @@ public class GodotIO {
}
public void dir_close(int id) {
-
if (dirs.get(id) == null) {
System.out.printf("dir_close: invalid dir id: %d\n", id);
return;
@@ -337,7 +315,6 @@ public class GodotIO {
}
GodotIO(Godot p_activity) {
-
am = p_activity.getAssets();
activity = p_activity;
//streams = new HashMap<Integer, AssetData>();
@@ -428,7 +405,6 @@ public class GodotIO {
}
public void audioPause(boolean p_pause) {
-
if (p_pause)
mAudioTrack.pause();
else
@@ -440,7 +416,6 @@ public class GodotIO {
/////////////////////////
public int openURI(String p_uri) {
-
try {
Log.v("MyApp", "TRYING TO OPEN URI: " + p_uri);
String path = p_uri;
@@ -449,7 +424,6 @@ public class GodotIO {
//absolute path to filesystem, prepend file://
path = "file://" + path;
if (p_uri.endsWith(".png") || p_uri.endsWith(".jpg") || p_uri.endsWith(".gif") || p_uri.endsWith(".webp")) {
-
type = "image/*";
}
}
@@ -465,18 +439,15 @@ public class GodotIO {
activity.startActivity(intent);
return 0;
} catch (ActivityNotFoundException e) {
-
return 1;
}
}
public String getDataDir() {
-
return activity.getFilesDir().getAbsolutePath();
}
public String getLocale() {
-
return Locale.getDefault().toString();
}
@@ -489,9 +460,9 @@ public class GodotIO {
return (int)(metrics.density * 160f);
}
- public void showKeyboard(String p_existing_text, int p_max_input_length) {
+ public void showKeyboard(String p_existing_text, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
if (edit != null)
- edit.showKeyboard(p_existing_text, p_max_input_length);
+ edit.showKeyboard(p_existing_text, p_max_input_length, p_cursor_start, p_cursor_end);
//InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
//inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
@@ -503,9 +474,7 @@ public class GodotIO {
};
public void setScreenOrientation(int p_orientation) {
-
switch (p_orientation) {
-
case SCREEN_LANDSCAPE: {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} break;
@@ -548,7 +517,6 @@ public class GodotIO {
public static final int SYSTEM_DIR_RINGTONES = 7;
public String getSystemDir(int idx) {
-
String what = "";
switch (idx) {
case SYSTEM_DIR_DESKTOP: {
@@ -593,7 +561,6 @@ public class GodotIO {
public static String unique_id = "";
public String getUniqueID() {
-
return unique_id;
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 71fe822233..3693f36557 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -33,6 +33,7 @@ package org.godotengine.godot;
import android.app.Activity;
import android.hardware.SensorEvent;
import android.view.Surface;
+
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
@@ -40,7 +41,6 @@ import javax.microedition.khronos.opengles.GL10;
* Wrapper for native library
*/
public class GodotLib {
-
public static GodotIO io;
static {
@@ -66,11 +66,12 @@ public class GodotLib {
/**
* Invoked on the GL thread when the underlying Android surface has changed size.
- * @param width
- * @param height
+ * @param p_surface
+ * @param p_width
+ * @param p_height
* @see android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(GL10, int, int)
*/
- public static native void resize(int width, int height);
+ public static native void resize(Surface p_surface, int p_width, int p_height);
/**
* Invoked on the render thread when the underlying Android surface is created or recreated.
@@ -189,7 +190,7 @@ public class GodotLib {
* @param p_method Name of the method to invoke
* @param p_params Parameters to use for method invocation
*/
- public static native void callobject(int p_id, String p_method, Object[] p_params);
+ public static native void callobject(long p_id, String p_method, Object[] p_params);
/**
* Invoke method |p_method| on the Godot object specified by |p_id| during idle time.
@@ -197,7 +198,7 @@ public class GodotLib {
* @param p_method Name of the method to invoke
* @param p_params Parameters to use for method invocation
*/
- public static native void calldeferred(int p_id, String p_method, Object[] p_params);
+ public static native void calldeferred(long p_id, String p_method, Object[] p_params);
/**
* Forward the results from a permission request.
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
index 170c433c9c..27e63f3a66 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java
@@ -33,7 +33,6 @@ package org.godotengine.godot;
import android.view.SurfaceView;
public interface GodotRenderView {
-
abstract public SurfaceView getView();
abstract public void initInputDevices();
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
index 3e5bb4a4c9..64395f7d1e 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java
@@ -30,19 +30,20 @@
package org.godotengine.godot;
+import org.godotengine.godot.plugin.GodotPlugin;
+import org.godotengine.godot.plugin.GodotPluginRegistry;
+import org.godotengine.godot.utils.GLUtils;
+
import android.content.Context;
import android.opengl.GLSurfaceView;
+
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
-import org.godotengine.godot.plugin.GodotPlugin;
-import org.godotengine.godot.plugin.GodotPluginRegistry;
-import org.godotengine.godot.utils.GLUtils;
/**
* Godot's renderer implementation.
*/
class GodotRenderer implements GLSurfaceView.Renderer {
-
private final GodotPluginRegistry pluginRegistry;
private boolean activityJustResumed = false;
@@ -63,7 +64,7 @@ class GodotRenderer implements GLSurfaceView.Renderer {
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
- GodotLib.resize(width, height);
+ GodotLib.resize(null, width, height);
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
plugin.onGLSurfaceChanged(gl, width, height);
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
index 30197d5729..e9872b58ff 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
@@ -30,18 +30,18 @@
package org.godotengine.godot;
+import org.godotengine.godot.input.GodotGestureHandler;
+import org.godotengine.godot.input.GodotInputHandler;
+import org.godotengine.godot.vulkan.VkRenderer;
+import org.godotengine.godot.vulkan.VkSurfaceView;
+
import android.annotation.SuppressLint;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceView;
-import org.godotengine.godot.input.GodotGestureHandler;
-import org.godotengine.godot.input.GodotInputHandler;
-import org.godotengine.godot.vulkan.VkRenderer;
-import org.godotengine.godot.vulkan.VkSurfaceView;
public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderView {
-
private final Godot mActivity;
private final GodotInputHandler mInputHandler;
private final GestureDetector mGestureDetector;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
index 92bb118e44..7f596575a8 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java
@@ -29,6 +29,9 @@
/*************************************************************************/
package org.godotengine.godot.input;
+
+import org.godotengine.godot.*;
+
import android.content.Context;
import android.os.Handler;
import android.os.Message;
@@ -38,8 +41,8 @@ import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
+
import java.lang.ref.WeakReference;
-import org.godotengine.godot.*;
public class GodotEditText extends EditText {
// ===========================================================
@@ -55,6 +58,7 @@ public class GodotEditText extends EditText {
private GodotTextInputWrapper mInputWrapper;
private EditHandler sHandler = new EditHandler(this);
private String mOriginText;
+ private int mMaxInputLength;
private static class EditHandler extends Handler {
private final WeakReference<GodotEditText> mEdit;
@@ -101,11 +105,18 @@ public class GodotEditText extends EditText {
String text = edit.mOriginText;
if (edit.requestFocus()) {
edit.removeTextChangedListener(edit.mInputWrapper);
+ setMaxInputLength(edit);
edit.setText("");
edit.append(text);
+ if (msg.arg2 != -1) {
+ edit.setSelection(msg.arg1, msg.arg2);
+ edit.mInputWrapper.setSelection(true);
+ } else {
+ edit.mInputWrapper.setSelection(false);
+ }
+
edit.mInputWrapper.setOriginText(text);
edit.addTextChangedListener(edit.mInputWrapper);
- setMaxInputLength(edit, msg.arg1);
final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(edit, 0);
}
@@ -122,14 +133,10 @@ public class GodotEditText extends EditText {
}
}
- private void setMaxInputLength(EditText p_edit_text, int p_max_input_length) {
- if (p_max_input_length > 0) {
- InputFilter[] filters = new InputFilter[1];
- filters[0] = new InputFilter.LengthFilter(p_max_input_length);
- p_edit_text.setFilters(filters);
- } else {
- p_edit_text.setFilters(new InputFilter[] {});
- }
+ private void setMaxInputLength(EditText p_edit_text) {
+ InputFilter[] filters = new InputFilter[1];
+ filters[0] = new InputFilter.LengthFilter(this.mMaxInputLength);
+ p_edit_text.setFilters(filters);
}
// ===========================================================
@@ -161,13 +168,24 @@ public class GodotEditText extends EditText {
// ===========================================================
// Methods
// ===========================================================
- public void showKeyboard(String p_existing_text, int p_max_input_length) {
- mOriginText = p_existing_text;
+ public void showKeyboard(String p_existing_text, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+ int maxInputLength = (p_max_input_length <= 0) ? Integer.MAX_VALUE : p_max_input_length;
+ if (p_cursor_start == -1) { // cursor position not given
+ this.mOriginText = p_existing_text;
+ this.mMaxInputLength = maxInputLength;
+ } else if (p_cursor_end == -1) { // not text selection
+ this.mOriginText = p_existing_text.substring(0, p_cursor_start);
+ this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_start);
+ } else {
+ this.mOriginText = p_existing_text.substring(0, p_cursor_end);
+ this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_end);
+ }
final Message msg = new Message();
msg.what = HANDLER_OPEN_IME_KEYBOARD;
msg.obj = this;
- msg.arg1 = p_max_input_length;
+ msg.arg1 = p_cursor_start;
+ msg.arg2 = p_cursor_end;
sHandler.sendMessage(msg);
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
index b1e0f66373..1c9a683bbd 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java
@@ -30,18 +30,18 @@
package org.godotengine.godot.input;
+import org.godotengine.godot.GodotLib;
+import org.godotengine.godot.GodotRenderView;
+
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
-import org.godotengine.godot.GodotLib;
-import org.godotengine.godot.GodotRenderView;
/**
* Handles gesture input related events for the {@link GodotRenderView} view.
* https://developer.android.com/reference/android/view/GestureDetector.SimpleOnGestureListener
*/
public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener {
-
private final GodotRenderView mRenderView;
public GodotGestureHandler(GodotRenderView godotView) {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index 0e4fc65119..9abd65cc67 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -32,24 +32,25 @@ package org.godotengine.godot.input;
import static org.godotengine.godot.utils.GLUtils.DEBUG;
+import org.godotengine.godot.GodotLib;
+import org.godotengine.godot.GodotRenderView;
+import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener;
+
import android.util.Log;
import android.view.InputDevice;
import android.view.InputDevice.MotionRange;
import android.view.KeyEvent;
import android.view.MotionEvent;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
-import org.godotengine.godot.GodotLib;
-import org.godotengine.godot.GodotRenderView;
-import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener;
/**
* Handles input related events for the {@link GodotRenderView} view.
*/
public class GodotInputHandler implements InputDeviceListener {
-
private final ArrayList<Joystick> mJoysticksDevices = new ArrayList<Joystick>();
private final GodotRenderView mRenderView;
@@ -84,7 +85,6 @@ public class GodotInputHandler implements InputDeviceListener {
int source = event.getSource();
if (isKeyEvent_GameDevice(source)) {
-
final int button = getGodotButton(keyCode);
final int device_id = findJoystickDevice(event.getDeviceId());
@@ -127,7 +127,6 @@ public class GodotInputHandler implements InputDeviceListener {
//Log.e(TAG, String.format("Key down! source %d, device %d, joystick %d, %d, %d", event.getDeviceId(), source, (source & InputDevice.SOURCE_JOYSTICK), (source & InputDevice.SOURCE_DPAD), (source & InputDevice.SOURCE_GAMEPAD)));
if (isKeyEvent_GameDevice(source)) {
-
if (event.getRepeatCount() > 0) // ignore key echo
return true;
@@ -159,7 +158,6 @@ public class GodotInputHandler implements InputDeviceListener {
public boolean onGenericMotionEvent(MotionEvent event) {
if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) {
-
final int device_id = findJoystickDevice(event.getDeviceId());
// Check if the device exists
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
index e12ff266bf..9c7cf9f341 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -29,6 +29,9 @@
/*************************************************************************/
package org.godotengine.godot.input;
+
+import org.godotengine.godot.*;
+
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
@@ -37,7 +40,6 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
-import org.godotengine.godot.*;
public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListener {
// ===========================================================
@@ -51,6 +53,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
private final GodotRenderView mRenderView;
private final GodotEditText mEdit;
private String mOriginText;
+ private boolean mHasSelection;
// ===========================================================
// Constructors
@@ -75,6 +78,10 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
mOriginText = originText;
}
+ public void setSelection(boolean selection) {
+ mHasSelection = selection;
+ }
+
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@@ -93,6 +100,11 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
for (int i = 0; i < count; ++i) {
GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true);
GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false);
+
+ if (mHasSelection) {
+ mHasSelection = false;
+ break;
+ }
}
}
});
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java
index 4042c42e9d..62810ad3a4 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java
@@ -120,7 +120,6 @@ public interface InputManagerCompat {
* Use this to construct a compatible InputManager.
*/
public static class Factory {
-
/**
* Constructs and returns a compatible InputManger
*
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java
index e4bafa7ff9..61828dccae 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java
@@ -23,12 +23,12 @@ import android.os.Build;
import android.os.Handler;
import android.view.InputDevice;
import android.view.MotionEvent;
+
import java.util.HashMap;
import java.util.Map;
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class InputManagerV16 implements InputManagerCompat {
-
private final InputManager mInputManager;
private final Map<InputManagerCompat.InputDeviceListener, V16InputDeviceListener> mListeners;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java
index 0c1bdb32aa..1f3fe1e527 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java
@@ -31,6 +31,7 @@
package org.godotengine.godot.input;
import android.view.InputDevice.MotionRange;
+
import java.util.ArrayList;
/**
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
index a051164d15..431bd4f5f9 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
@@ -30,24 +30,27 @@
package org.godotengine.godot.plugin;
+import org.godotengine.godot.BuildConfig;
+import org.godotengine.godot.Godot;
+
import android.app.Activity;
import android.content.Intent;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.text.TextUtils;
import android.util.Log;
import android.view.Surface;
import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
-import org.godotengine.godot.BuildConfig;
-import org.godotengine.godot.Godot;
/**
* Base class for the Godot Android plugins.
@@ -73,7 +76,6 @@ import org.godotengine.godot.Godot;
* 'godot/plugin/v1/[PluginName]/'
*/
public abstract class GodotPlugin {
-
private static final String TAG = GodotPlugin.class.getSimpleName();
private final Godot godot;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
index e13a9c15d8..12d2ed09fb 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java
@@ -30,26 +30,27 @@
package org.godotengine.godot.plugin;
+import org.godotengine.godot.Godot;
+
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
-import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
+
+import androidx.annotation.Nullable;
+
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import org.godotengine.godot.Godot;
/**
* Registry used to load and access the registered Godot Android plugins.
*/
public final class GodotPluginRegistry {
-
private static final String TAG = GodotPluginRegistry.class.getSimpleName();
private static final String GODOT_PLUGIN_V1_NAME_PREFIX = "org.godotengine.plugin.v1.";
@@ -57,7 +58,9 @@ public final class GodotPluginRegistry {
/**
* Name for the metadata containing the list of Godot plugins to enable.
*/
- private static final String GODOT_ENABLED_PLUGINS_LABEL = "custom_template_plugins";
+ private static final String GODOT_ENABLED_PLUGINS_LABEL = "plugins";
+
+ private static final String PLUGIN_VALUE_SEPARATOR_REGEX = "\\|";
private static GodotPluginRegistry instance;
private final ConcurrentHashMap<String, GodotPlugin> registry;
@@ -127,13 +130,13 @@ public final class GodotPluginRegistry {
}
// When using the Godot editor for building and exporting the apk, this is used to check
- // which plugins to enable since the custom build template may contain prebuilt plugins.
+ // which plugins to enable.
// When using a custom process to generate the apk, the metadata is not needed since
// it's assumed that the developer is aware of the dependencies included in the apk.
final Set<String> enabledPluginsSet;
if (metaData.containsKey(GODOT_ENABLED_PLUGINS_LABEL)) {
String enabledPlugins = metaData.getString(GODOT_ENABLED_PLUGINS_LABEL, "");
- String[] enabledPluginsList = enabledPlugins.split(",");
+ String[] enabledPluginsList = enabledPlugins.split(PLUGIN_VALUE_SEPARATOR_REGEX);
if (enabledPluginsList.length == 0) {
// No plugins to enable. Aborting early.
return;
@@ -157,6 +160,8 @@ public final class GodotPluginRegistry {
continue;
}
+ Log.i(TAG, "Initializing Godot plugin " + pluginName);
+
// Retrieve the plugin class full name.
String pluginHandleClassFullName = metaData.getString(metaDataName);
if (!TextUtils.isEmpty(pluginHandleClassFullName)) {
@@ -176,6 +181,7 @@ public final class GodotPluginRegistry {
"Meta-data plugin name does not match the value returned by the plugin handle: " + pluginName + " =/= " + pluginHandle.getPluginName());
}
registry.put(pluginName, pluginHandle);
+ Log.i(TAG, "Completed initialization for Godot plugin " + pluginHandle.getPluginName());
} catch (ClassNotFoundException e) {
Log.w(TAG, "Unable to load Godot plugin " + pluginName, e);
} catch (IllegalAccessException e) {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
index f907706889..f82c4d3fa0 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -30,15 +30,16 @@
package org.godotengine.godot.plugin;
-import android.support.annotation.NonNull;
import android.text.TextUtils;
+
+import androidx.annotation.NonNull;
+
import java.util.Arrays;
/**
* Store information about a {@link GodotPlugin}'s signal.
*/
public final class SignalInfo {
-
private final String name;
private final Class<?>[] paramTypes;
private final String[] paramTypesNames;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java
index bc0e565774..acc9c4981b 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java
@@ -34,7 +34,6 @@ import java.security.MessageDigest;
import java.util.Random;
public class Crypt {
-
public static String md5(String input) {
try {
// Create MD5 Hash
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java
index 9d29551f89..82420eda79 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java
@@ -31,6 +31,7 @@
package org.godotengine.godot.utils;
import android.util.Log;
+
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
@@ -39,7 +40,6 @@ import javax.microedition.khronos.egl.EGLDisplay;
* Contains GL utilities methods.
*/
public class GLUtils {
-
private static final String TAG = GLUtils.class.getSimpleName();
public static final boolean DEBUG = false;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java
index 011d426c7e..0832a9b965 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java
@@ -30,10 +30,11 @@
package org.godotengine.godot.utils;
+import org.godotengine.godot.Godot;
+
import android.content.Context;
import android.net.wifi.WifiManager;
import android.util.Log;
-import org.godotengine.godot.Godot;
/**
* This class handles Android-specific networking functions.
@@ -41,7 +42,6 @@ import org.godotengine.godot.Godot;
* to receive broadcast and multicast packets.
*/
public class GodotNetUtils {
-
/* A single, reference counted, multicast lock, or null if permission CHANGE_WIFI_MULTICAST_STATE is missing */
private WifiManager.MulticastLock multicastLock;
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
index 7cf32b00fe..6837e4f147 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
@@ -30,21 +30,26 @@
package org.godotengine.godot.utils;
+import org.godotengine.godot.Godot;
+
import android.Manifest;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
import android.os.Build;
-import android.support.v4.content.ContextCompat;
+import android.util.Log;
+
+import androidx.core.content.ContextCompat;
+
import java.util.ArrayList;
import java.util.List;
-import org.godotengine.godot.Godot;
/**
* This class includes utility functions for Android permissions related operations.
* @author Cagdas Caglak <cagdascaglak@gmail.com>
*/
public final class PermissionsUtil {
+ private static final String TAG = PermissionsUtil.class.getSimpleName();
static final int REQUEST_RECORD_AUDIO_PERMISSION = 1;
static final int REQUEST_CAMERA_PERMISSION = 2;
@@ -113,8 +118,8 @@ public final class PermissionsUtil {
dangerousPermissions.add(manifestPermission);
}
} catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- return false;
+ // Skip this permission and continue.
+ Log.w(TAG, "Unable to identify permission " + manifestPermission, e);
}
}
@@ -153,8 +158,8 @@ public final class PermissionsUtil {
dangerousPermissions.add(manifestPermission);
}
} catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- return new String[0];
+ // Skip this permission and continue.
+ Log.w(TAG, "Unable to identify permission " + manifestPermission, e);
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
index 608ad48df9..aeb4628d5d 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt
@@ -59,9 +59,7 @@ internal class VkRenderer {
* Called when the surface is created and signals the beginning of rendering.
*/
fun onVkSurfaceCreated(surface: Surface) {
- // TODO: properly implement surface re-creation:
- // GodotLib.newcontext should be called here once it's done.
- //GodotLib.newcontext(surface, false)
+ GodotLib.newcontext(surface, false)
for (plugin in pluginRegistry.getAllPlugins()) {
plugin.onVkSurfaceCreated(surface)
@@ -72,12 +70,7 @@ internal class VkRenderer {
* Called after the surface is created and whenever its size changes.
*/
fun onVkSurfaceChanged(surface: Surface, width: Int, height: Int) {
- GodotLib.resize(width, height)
-
- // TODO: properly implement surface re-creation:
- // Update the native renderer instead of restarting the app.
- // GodotLib.newcontext should not be called here once it's done.
- GodotLib.newcontext(surface, false)
+ GodotLib.resize(surface, width, height)
for (plugin in pluginRegistry.getAllPlugins()) {
plugin.onVkSurfaceChanged(surface, width, height)
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
index 9209d6ccf2..819bcccdf1 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java
@@ -32,6 +32,7 @@ package org.godotengine.godot.xr.ovr;
import android.opengl.EGLExt;
import android.opengl.GLSurfaceView;
+
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
@@ -40,7 +41,6 @@ import javax.microedition.khronos.egl.EGLDisplay;
* EGL config chooser for the Oculus Mobile VR SDK.
*/
public class OvrConfigChooser implements GLSurfaceView.EGLConfigChooser {
-
private static final int[] CONFIG_ATTRIBS = {
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
index 36f4416df2..2d9b921466 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java
@@ -32,6 +32,7 @@ package org.godotengine.godot.xr.ovr;
import android.opengl.EGL14;
import android.opengl.GLSurfaceView;
+
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
@@ -41,7 +42,6 @@ import javax.microedition.khronos.egl.EGLDisplay;
* EGL Context factory for the Oculus mobile VR SDK.
*/
public class OvrContextFactory implements GLSurfaceView.EGLContextFactory {
-
private static final int[] CONTEXT_ATTRIBS = {
EGL14.EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE
};
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
index b2aa130f37..43c7f0f966 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java
@@ -31,6 +31,7 @@
package org.godotengine.godot.xr.ovr;
import android.opengl.GLSurfaceView;
+
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
@@ -40,7 +41,6 @@ import javax.microedition.khronos.egl.EGLSurface;
* EGL window surface factory for the Oculus mobile VR SDK.
*/
public class OvrWindowSurfaceFactory implements GLSurfaceView.EGLWindowSurfaceFactory {
-
private final static int[] SURFACE_ATTRIBS = {
EGL10.EGL_WIDTH, 16,
EGL10.EGL_HEIGHT, 16,
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
index 8409e37f8f..54672db282 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java
@@ -30,17 +30,18 @@
package org.godotengine.godot.xr.regular;
+import org.godotengine.godot.utils.GLUtils;
+
import android.opengl.GLSurfaceView;
+
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
-import org.godotengine.godot.utils.GLUtils;
/**
* Used to select the egl config for pancake games.
*/
public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser {
-
private static final String TAG = RegularConfigChooser.class.getSimpleName();
private int[] mValue = new int[1];
@@ -72,7 +73,6 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser {
}
public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
-
/* Get the number of minimally matching EGL configurations
*/
int[] num_config = new int[1];
@@ -127,7 +127,6 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser {
private int findConfigAttrib(EGL10 egl, EGLDisplay display,
EGLConfig config, int attribute, int defaultValue) {
-
if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) {
return mValue[0];
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
index 31cf696195..126f3ad5f5 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java
@@ -30,14 +30,16 @@
package org.godotengine.godot.xr.regular;
+import org.godotengine.godot.GodotLib;
+import org.godotengine.godot.utils.GLUtils;
+
import android.opengl.GLSurfaceView;
import android.util.Log;
+
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
-import org.godotengine.godot.GodotLib;
-import org.godotengine.godot.utils.GLUtils;
/**
* Factory used to setup the opengl context for pancake games.
diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
index 71fcf06020..c83c47bed7 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java
@@ -30,15 +30,16 @@
package org.godotengine.godot.xr.regular;
+import org.godotengine.godot.utils.GLUtils;
+
import android.util.Log;
+
import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLDisplay;
-import org.godotengine.godot.utils.GLUtils;
/* Fallback if 32bit View is not supported*/
public class RegularFallbackConfigChooser extends RegularConfigChooser {
-
private static final String TAG = RegularFallbackConfigChooser.class.getSimpleName();
private RegularConfigChooser fallback;
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ConsumeTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ConsumeTask.java
index c15bc232ce..de009f6d16 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ConsumeTask.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ConsumeTask.java
@@ -33,11 +33,12 @@ package org.godotengine.godot.plugin.payment;
import android.content.Context;
import android.os.AsyncTask;
import android.os.RemoteException;
+
import com.android.vending.billing.IInAppBillingService;
+
import java.lang.ref.WeakReference;
abstract public class ConsumeTask {
-
private Context context;
private IInAppBillingService mService;
@@ -45,7 +46,6 @@ abstract public class ConsumeTask {
private String mToken;
private static class ConsumeAsyncTask extends AsyncTask<String, String, String> {
-
private WeakReference<ConsumeTask> mTask;
ConsumeAsyncTask(ConsumeTask consume) {
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/GodotPayment.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/GodotPayment.java
index c7d0a5de65..e2b12c94a4 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/GodotPayment.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/GodotPayment.java
@@ -30,22 +30,25 @@
package org.godotengine.godot.plugin.payment;
+import org.godotengine.godot.Dictionary;
+import org.godotengine.godot.Godot;
+import org.godotengine.godot.GodotLib;
+import org.godotengine.godot.plugin.GodotPlugin;
+
import android.content.Intent;
-import android.support.annotation.NonNull;
import android.util.Log;
+
+import androidx.annotation.NonNull;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import org.godotengine.godot.Dictionary;
-import org.godotengine.godot.Godot;
-import org.godotengine.godot.GodotLib;
-import org.godotengine.godot.plugin.GodotPlugin;
+
import org.json.JSONException;
import org.json.JSONObject;
public class GodotPayment extends GodotPlugin {
-
- private Integer purchaseCallbackId = 0;
+ private Long purchaseCallbackId = 0L;
private String accessToken;
private String purchaseValidationUrlPrefix;
private String transactionId;
@@ -126,11 +129,11 @@ public class GodotPayment extends GodotPlugin {
GodotLib.calldeferred(purchaseCallbackId, "purchase_owned", new Object[] { sku });
}
- public int getPurchaseCallbackId() {
+ public long getPurchaseCallbackId() {
return purchaseCallbackId;
}
- public void setPurchaseCallbackId(int purchaseCallbackId) {
+ public void setPurchaseCallbackId(long purchaseCallbackId) {
this.purchaseCallbackId = purchaseCallbackId;
}
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/HandlePurchaseTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/HandlePurchaseTask.java
index fe5685288b..00e216e8c0 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/HandlePurchaseTask.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/HandlePurchaseTask.java
@@ -32,11 +32,11 @@ package org.godotengine.godot.plugin.payment;
import android.app.Activity;
import android.content.Intent;
+
import org.json.JSONException;
import org.json.JSONObject;
abstract public class HandlePurchaseTask {
-
private Activity context;
public HandlePurchaseTask(Activity context) {
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsCache.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsCache.java
index d5919e3d9d..435f43c49d 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsCache.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsCache.java
@@ -34,7 +34,6 @@ import android.content.Context;
import android.content.SharedPreferences;
public class PaymentsCache {
-
public Context context;
public PaymentsCache(Context context) {
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsManager.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsManager.java
index bded1f452f..9b3a338866 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsManager.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PaymentsManager.java
@@ -40,14 +40,16 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Log;
+
import com.android.vending.billing.IInAppBillingService;
+
import java.util.ArrayList;
import java.util.Arrays;
+
import org.json.JSONException;
import org.json.JSONObject;
public class PaymentsManager {
-
public static final int BILLING_RESPONSE_RESULT_OK = 0;
public static final int REQUEST_CODE_FOR_PURCHASE = 0x1001;
private static boolean auto_consume = true;
@@ -155,7 +157,6 @@ public class PaymentsManager {
Bundle bundle = mService.getPurchases(3, activity.getPackageName(), "inapp", continueToken);
if (bundle.getInt("RESPONSE_CODE") == 0) {
-
final ArrayList<String> myPurchases = bundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
final ArrayList<String> mySignatures = bundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
@@ -165,7 +166,6 @@ public class PaymentsManager {
}
for (int i = 0; i < myPurchases.size(); i++) {
-
try {
String receipt = myPurchases.get(i);
JSONObject inappPurchaseData = new JSONObject(receipt);
@@ -226,11 +226,9 @@ public class PaymentsManager {
}
public void validatePurchase(String purchaseToken, final String sku) {
-
new ValidateTask(activity, godotPayment) {
@Override
protected void success() {
-
new ConsumeTask(mService, activity) {
@Override
protected void success(String ticket) {
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PurchaseTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PurchaseTask.java
index eecd1d2151..f894bd5132 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PurchaseTask.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/PurchaseTask.java
@@ -37,10 +37,10 @@ import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.os.RemoteException;
import android.util.Log;
+
import com.android.vending.billing.IInAppBillingService;
abstract public class PurchaseTask {
-
private Activity context;
private IInAppBillingService mService;
@@ -56,7 +56,7 @@ abstract public class PurchaseTask {
PaymentsCache pc = new PaymentsCache(context);
Boolean isBlocked = pc.getConsumableFlag("block", sku);
/*
- if(isBlocked){
+ if(isBlocked) {
Log.d("XXX", "Is awaiting payment confirmation");
error("Awaiting payment confirmation");
return;
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ReleaseAllConsumablesTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ReleaseAllConsumablesTask.java
index b7bd638feb..1d52cf0fa5 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ReleaseAllConsumablesTask.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ReleaseAllConsumablesTask.java
@@ -34,19 +34,20 @@ import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
+
import com.android.vending.billing.IInAppBillingService;
+
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+
import org.json.JSONException;
import org.json.JSONObject;
abstract public class ReleaseAllConsumablesTask {
-
private Context context;
private IInAppBillingService mService;
private static class ReleaseAllConsumablesAsyncTask extends AsyncTask<String, String, String> {
-
private WeakReference<ReleaseAllConsumablesTask> mTask;
private String mSku;
private String mReceipt;
@@ -91,7 +92,6 @@ abstract public class ReleaseAllConsumablesTask {
Bundle bundle = mService.getPurchases(3, context.getPackageName(), "inapp", null);
if (bundle.getInt("RESPONSE_CODE") == 0) {
-
final ArrayList<String> myPurchases = bundle.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
final ArrayList<String> mySignatures = bundle.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
@@ -103,7 +103,6 @@ abstract public class ReleaseAllConsumablesTask {
//Log.d("godot", "# products to be consumed:" + myPurchases.size());
for (int i = 0; i < myPurchases.size(); i++) {
-
try {
String receipt = myPurchases.get(i);
JSONObject inappPurchaseData = new JSONObject(receipt);
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java
index d42ded0c9b..a7156152ce 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/ValidateTask.java
@@ -30,17 +30,19 @@
package org.godotengine.godot.plugin.payment;
+import org.godotengine.godot.plugin.payment.utils.HttpRequester;
+import org.godotengine.godot.plugin.payment.utils.RequestParams;
+
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
+
import java.lang.ref.WeakReference;
-import org.godotengine.godot.plugin.payment.utils.HttpRequester;
-import org.godotengine.godot.plugin.payment.utils.RequestParams;
+
import org.json.JSONException;
import org.json.JSONObject;
abstract public class ValidateTask {
-
private Activity context;
private GodotPayment godotPayments;
private ProgressDialog dialog;
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/CustomSSLSocketFactory.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/CustomSSLSocketFactory.java
index 9571769cd3..55b87b49e5 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/CustomSSLSocketFactory.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/CustomSSLSocketFactory.java
@@ -38,8 +38,10 @@ import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
+
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
+
import org.apache.http.conn.ssl.SSLSocketFactory;
/**
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/HttpRequester.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/HttpRequester.java
index dcb983201e..0afcf60f38 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/HttpRequester.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/HttpRequester.java
@@ -30,9 +30,12 @@
package org.godotengine.godot.plugin.payment.utils;
+import org.godotengine.godot.utils.Crypt;
+
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
+
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
@@ -40,6 +43,7 @@ import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.security.KeyStore;
import java.util.Date;
+
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
@@ -61,14 +65,12 @@ import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
-import org.godotengine.godot.utils.Crypt;
/**
*
* @author Luis Linietsky <luis.linietsky@gmail.com>
*/
public class HttpRequester {
-
private Context context;
private static final int TTL = 600000; // 10 minutos
private long cttl = 0;
diff --git a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/RequestParams.java b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/RequestParams.java
index 4be8b37473..6b66c7e474 100644
--- a/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/RequestParams.java
+++ b/platform/android/java/plugins/godotpayment/src/main/java/org/godotengine/godot/plugin/payment/utils/RequestParams.java
@@ -33,6 +33,7 @@ package org.godotengine.godot.plugin.payment.utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
+
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
@@ -41,7 +42,6 @@ import org.apache.http.message.BasicNameValuePair;
* @author Luis Linietsky <luis.linietsky@gmail.com>
*/
public class RequestParams {
-
private HashMap<String, String> params;
private String url;
diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp
index 6b9105b8e5..39de3cb642 100644
--- a/platform/android/java_class_wrapper.cpp
+++ b/platform/android/java_class_wrapper.cpp
@@ -33,7 +33,6 @@
#include "thread_jandroid.h"
bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret) {
-
Map<StringName, List<MethodInfo>>::Element *M = methods.find(p_method);
if (!M)
return false;
@@ -42,7 +41,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
MethodInfo *method = nullptr;
for (List<MethodInfo>::Element *E = M->get().front(); E; E = E->next()) {
-
if (!p_instance && !E->get()._static) {
r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL;
continue;
@@ -50,13 +48,11 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
int pc = E->get().param_types.size();
if (pc > p_argcount) {
-
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = pc;
continue;
}
if (pc < p_argcount) {
-
r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
r_error.argument = pc;
continue;
@@ -65,10 +61,8 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
bool valid = true;
for (int i = 0; i < pc; i++) {
-
Variant::Type arg_expected = Variant::NIL;
switch (ptypes[i]) {
-
case ARG_TYPE_VOID: {
//bug?
} break;
@@ -86,7 +80,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
case ARG_TYPE_SHORT:
case ARG_TYPE_INT:
case ARG_TYPE_LONG: {
-
if (!p_args[i]->is_num())
arg_expected = Variant::INT;
@@ -95,32 +88,26 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
case ARG_NUMBER_CLASS_BIT | ARG_TYPE_DOUBLE:
case ARG_TYPE_FLOAT:
case ARG_TYPE_DOUBLE: {
-
if (!p_args[i]->is_num())
arg_expected = Variant::FLOAT;
} break;
case ARG_TYPE_STRING: {
-
if (p_args[i]->get_type() != Variant::STRING)
arg_expected = Variant::STRING;
} break;
case ARG_TYPE_CLASS: {
-
if (p_args[i]->get_type() != Variant::OBJECT)
arg_expected = Variant::OBJECT;
else {
-
Ref<Reference> ref = *p_args[i];
if (!ref.is_null()) {
if (Object::cast_to<JavaObject>(ref.ptr())) {
-
Ref<JavaObject> jo = ref;
//could be faster
jclass c = env->FindClass(E->get().param_sigs[i].operator String().utf8().get_data());
if (!c || !env->IsInstanceOf(jo->instance, c)) {
-
arg_expected = Variant::OBJECT;
} else {
//ok
@@ -133,7 +120,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
default: {
-
if (p_args[i]->get_type() != Variant::ARRAY)
arg_expected = Variant::ARRAY;
@@ -163,13 +149,11 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
jvalue *argv = nullptr;
if (method->param_types.size()) {
-
argv = (jvalue *)alloca(sizeof(jvalue) * method->param_types.size());
}
List<jobject> to_free;
for (int i = 0; i < method->param_types.size(); i++) {
-
switch (method->param_types[i]) {
case ARG_TYPE_VOID: {
//can't happen
@@ -279,10 +263,8 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
to_free.push_back(jStr);
} break;
case ARG_TYPE_CLASS: {
-
Ref<JavaObject> jo = *p_args[i];
if (jo.is_valid()) {
-
argv[i].l = jo->instance;
} else {
argv[i].l = nullptr; //I hope this works
@@ -290,7 +272,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN: {
-
Array arr = *p_args[i];
jbooleanArray a = env->NewBooleanArray(arr.size());
for (int j = 0; j < arr.size(); j++) {
@@ -302,7 +283,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_ARRAY_BIT | ARG_TYPE_BYTE: {
-
Array arr = *p_args[i];
jbyteArray a = env->NewByteArray(arr.size());
for (int j = 0; j < arr.size(); j++) {
@@ -314,7 +294,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_ARRAY_BIT | ARG_TYPE_CHAR: {
-
Array arr = *p_args[i];
jcharArray a = env->NewCharArray(arr.size());
for (int j = 0; j < arr.size(); j++) {
@@ -326,7 +305,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_ARRAY_BIT | ARG_TYPE_SHORT: {
-
Array arr = *p_args[i];
jshortArray a = env->NewShortArray(arr.size());
for (int j = 0; j < arr.size(); j++) {
@@ -338,7 +316,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_ARRAY_BIT | ARG_TYPE_INT: {
-
Array arr = *p_args[i];
jintArray a = env->NewIntArray(arr.size());
for (int j = 0; j < arr.size(); j++) {
@@ -360,7 +337,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: {
-
Array arr = *p_args[i];
jfloatArray a = env->NewFloatArray(arr.size());
for (int j = 0; j < arr.size(); j++) {
@@ -372,7 +348,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: {
-
Array arr = *p_args[i];
jdoubleArray a = env->NewDoubleArray(arr.size());
for (int j = 0; j < arr.size(); j++) {
@@ -384,11 +359,9 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_ARRAY_BIT | ARG_TYPE_STRING: {
-
Array arr = *p_args[i];
jobjectArray a = env->NewObjectArray(arr.size(), env->FindClass("java/lang/String"), nullptr);
for (int j = 0; j < arr.size(); j++) {
-
String s = arr[j];
jstring jStr = env->NewStringUTF(s.utf8().get_data());
env->SetObjectArrayElement(a, j, jStr);
@@ -399,7 +372,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
to_free.push_back(a);
} break;
case ARG_ARRAY_BIT | ARG_TYPE_CLASS: {
-
argv[i].l = nullptr;
} break;
}
@@ -409,7 +381,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
bool success = true;
switch (method->return_type) {
-
case ARG_TYPE_VOID: {
if (method->_static) {
env->CallStaticVoidMethodA(_class, method->method, argv);
@@ -434,7 +405,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
}
} break;
case ARG_TYPE_CHAR: {
-
if (method->_static) {
ret = env->CallStaticCharMethodA(_class, method->method, argv);
} else {
@@ -442,7 +412,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
}
} break;
case ARG_TYPE_SHORT: {
-
if (method->_static) {
ret = env->CallStaticShortMethodA(_class, method->method, argv);
} else {
@@ -451,7 +420,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_TYPE_INT: {
-
if (method->_static) {
ret = env->CallStaticIntMethodA(_class, method->method, argv);
} else {
@@ -460,7 +428,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_TYPE_LONG: {
-
if (method->_static) {
ret = (int64_t)env->CallStaticLongMethodA(_class, method->method, argv);
} else {
@@ -469,7 +436,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_TYPE_FLOAT: {
-
if (method->_static) {
ret = env->CallStaticFloatMethodA(_class, method->method, argv);
} else {
@@ -478,7 +444,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
case ARG_TYPE_DOUBLE: {
-
if (method->_static) {
ret = env->CallStaticDoubleMethodA(_class, method->method, argv);
} else {
@@ -487,7 +452,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
} break;
default: {
-
jobject obj;
if (method->_static) {
obj = env->CallStaticObjectMethodA(_class, method->method, argv);
@@ -498,7 +462,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
if (!obj) {
ret = Variant();
} else {
-
if (!_convert_object_to_variant(env, obj, ret, method->return_type)) {
ret = Variant();
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -518,7 +481,6 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
}
Variant JavaClass::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
Variant ret;
bool found = _call_method(nullptr, p_method, p_args, p_argcount, r_error, ret);
if (found) {
@@ -534,7 +496,6 @@ JavaClass::JavaClass() {
/////////////////////
Variant JavaObject::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
return Variant();
}
@@ -547,14 +508,12 @@ JavaObject::~JavaObject() {
////////////////////
bool JavaClassWrapper::_get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig) {
-
jstring name2 = (jstring)env->CallObjectMethod(obj, Class_getName);
String str_type = jstring_to_string(name2, env);
env->DeleteLocalRef(name2);
uint32_t t = 0;
if (str_type.begins_with("[")) {
-
t = JavaClass::ARG_ARRAY_BIT;
strsig = "[";
str_type = str_type.substr(1, str_type.length() - 1);
@@ -633,87 +592,71 @@ bool JavaClassWrapper::_get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, St
}
bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &var, uint32_t p_sig) {
-
if (!obj) {
var = Variant(); //seems null is just null...
return true;
}
switch (p_sig) {
-
case ARG_TYPE_VOID: {
-
return Variant();
} break;
case ARG_TYPE_BOOLEAN | ARG_NUMBER_CLASS_BIT: {
-
var = env->CallBooleanMethod(obj, JavaClassWrapper::singleton->Boolean_booleanValue);
return true;
} break;
case ARG_TYPE_BYTE | ARG_NUMBER_CLASS_BIT: {
-
var = env->CallByteMethod(obj, JavaClassWrapper::singleton->Byte_byteValue);
return true;
} break;
case ARG_TYPE_CHAR | ARG_NUMBER_CLASS_BIT: {
-
var = env->CallCharMethod(obj, JavaClassWrapper::singleton->Character_characterValue);
return true;
} break;
case ARG_TYPE_SHORT | ARG_NUMBER_CLASS_BIT: {
-
var = env->CallShortMethod(obj, JavaClassWrapper::singleton->Short_shortValue);
return true;
} break;
case ARG_TYPE_INT | ARG_NUMBER_CLASS_BIT: {
-
var = env->CallIntMethod(obj, JavaClassWrapper::singleton->Integer_integerValue);
return true;
} break;
case ARG_TYPE_LONG | ARG_NUMBER_CLASS_BIT: {
-
var = (int64_t)env->CallLongMethod(obj, JavaClassWrapper::singleton->Long_longValue);
return true;
} break;
case ARG_TYPE_FLOAT | ARG_NUMBER_CLASS_BIT: {
-
var = env->CallFloatMethod(obj, JavaClassWrapper::singleton->Float_floatValue);
return true;
} break;
case ARG_TYPE_DOUBLE | ARG_NUMBER_CLASS_BIT: {
-
var = env->CallDoubleMethod(obj, JavaClassWrapper::singleton->Double_doubleValue);
return true;
} break;
case ARG_TYPE_STRING: {
-
var = jstring_to_string((jstring)obj, env);
return true;
} break;
case ARG_TYPE_CLASS: {
-
return false;
} break;
case ARG_ARRAY_BIT | ARG_TYPE_VOID: {
-
var = Array(); // ?
return true;
} break;
case ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN: {
-
Array ret;
jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jboolean val;
env->GetBooleanArrayRegion((jbooleanArray)arr, 0, 1, &val);
ret.push_back(val);
@@ -724,14 +667,12 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
} break;
case ARG_ARRAY_BIT | ARG_TYPE_BYTE: {
-
Array ret;
jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jbyte val;
env->GetByteArrayRegion((jbyteArray)arr, 0, 1, &val);
ret.push_back(val);
@@ -747,7 +688,6 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jchar val;
env->GetCharArrayRegion((jcharArray)arr, 0, 1, &val);
ret.push_back(val);
@@ -763,7 +703,6 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jshort val;
env->GetShortArrayRegion((jshortArray)arr, 0, 1, &val);
ret.push_back(val);
@@ -779,7 +718,6 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jint val;
env->GetIntArrayRegion((jintArray)arr, 0, 1, &val);
ret.push_back(val);
@@ -795,7 +733,6 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jlong val;
env->GetLongArrayRegion((jlongArray)arr, 0, 1, &val);
ret.push_back((int64_t)val);
@@ -811,7 +748,6 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jfloat val;
env->GetFloatArrayRegion((jfloatArray)arr, 0, 1, &val);
ret.push_back(val);
@@ -827,7 +763,6 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jdouble val;
env->GetDoubleArrayRegion((jdoubleArray)arr, 0, 1, &val);
ret.push_back(val);
@@ -837,14 +772,12 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true;
} break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN: {
-
Array ret;
jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jobject o = env->GetObjectArrayElement(arr, i);
if (!o)
ret.push_back(Variant());
@@ -860,14 +793,12 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
} break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_BYTE: {
-
Array ret;
jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jobject o = env->GetObjectArrayElement(arr, i);
if (!o)
ret.push_back(Variant());
@@ -882,14 +813,12 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true;
} break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_CHAR: {
-
Array ret;
jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jobject o = env->GetObjectArrayElement(arr, i);
if (!o)
ret.push_back(Variant());
@@ -904,14 +833,12 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true;
} break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_SHORT: {
-
Array ret;
jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jobject o = env->GetObjectArrayElement(arr, i);
if (!o)
ret.push_back(Variant());
@@ -926,14 +853,12 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true;
} break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_INT: {
-
Array ret;
jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jobject o = env->GetObjectArrayElement(arr, i);
if (!o)
ret.push_back(Variant());
@@ -948,14 +873,12 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true;
} break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_LONG: {
-
Array ret;
jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jobject o = env->GetObjectArrayElement(arr, i);
if (!o)
ret.push_back(Variant());
@@ -970,14 +893,12 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true;
} break;
case ARG_NUMBER_CLASS_BIT | ARG_ARRAY_BIT | ARG_TYPE_FLOAT: {
-
Array ret;
jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jobject o = env->GetObjectArrayElement(arr, i);
if (!o)
ret.push_back(Variant());
@@ -998,7 +919,6 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jobject o = env->GetObjectArrayElement(arr, i);
if (!o)
ret.push_back(Variant());
@@ -1014,14 +934,12 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
} break;
case ARG_ARRAY_BIT | ARG_TYPE_STRING: {
-
Array ret;
jobjectArray arr = (jobjectArray)obj;
int count = env->GetArrayLength(arr);
for (int i = 0; i < count; i++) {
-
jobject o = env->GetObjectArrayElement(arr, i);
if (!o)
ret.push_back(Variant());
@@ -1036,7 +954,6 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
return true;
} break;
case ARG_ARRAY_BIT | ARG_TYPE_CLASS: {
-
} break;
}
@@ -1044,7 +961,6 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
}
Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
-
if (class_cache.has(p_class))
return class_cache[p_class];
@@ -1066,7 +982,6 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
int count = env->GetArrayLength(methods);
for (int i = 0; i < count; i++) {
-
jobject obj = env->GetObjectArrayElement(methods, i);
ERR_CONTINUE(!obj);
@@ -1096,7 +1011,6 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
String signature = "(";
for (int j = 0; j < count2; j++) {
-
jobject obj2 = env->GetObjectArrayElement(param_types, j);
String strsig;
uint32_t sig = 0;
@@ -1138,7 +1052,6 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
bool discard = false;
for (List<JavaClass::MethodInfo>::Element *E = java_class->methods[str_method].front(); E; E = E->next()) {
-
float new_likeliness = 0;
float existing_likeliness = 0;
@@ -1146,7 +1059,6 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
continue;
bool valid = true;
for (int j = 0; j < E->get().param_types.size(); j++) {
-
Variant::Type _new;
float new_l;
Variant::Type existing;
@@ -1195,7 +1107,6 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
count = env->GetArrayLength(fields);
for (int i = 0; i < count; i++) {
-
jobject obj = env->GetObjectArrayElement(fields, i);
ERR_CONTINUE(!obj);
@@ -1207,17 +1118,13 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
jobject objc = env->CallObjectMethod(obj, Field_get, nullptr);
if (objc) {
-
uint32_t sig;
String strsig;
jclass cl = env->GetObjectClass(objc);
if (JavaClassWrapper::_get_type_sig(env, cl, sig, strsig)) {
-
if ((sig & JavaClass::ARG_TYPE_MASK) <= JavaClass::ARG_TYPE_STRING) {
-
Variant value;
if (JavaClass::_convert_object_to_variant(env, objc, value, sig)) {
-
java_class->constant_map[str_field] = value;
}
}
@@ -1239,7 +1146,6 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
JavaClassWrapper *JavaClassWrapper::singleton = nullptr;
JavaClassWrapper::JavaClassWrapper(jobject p_activity) {
-
singleton = this;
JNIEnv *env = ThreadAndroid::get_env();
diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp
index 0da0bd6387..0a42adeaf2 100644
--- a/platform/android/java_godot_io_wrapper.cpp
+++ b/platform/android/java_godot_io_wrapper.cpp
@@ -53,7 +53,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc
_get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;");
_get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I");
_get_unique_id = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;");
- _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;I)V");
+ _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;III)V");
_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
_set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V");
_get_screen_orientation = p_env->GetMethodID(cls, "getScreenOrientation", "()I");
@@ -132,11 +132,11 @@ bool GodotIOJavaWrapper::has_vk() {
return (_show_keyboard != 0) && (_hide_keyboard != 0);
}
-void GodotIOJavaWrapper::show_vk(const String &p_existing, int p_max_input_length) {
+void GodotIOJavaWrapper::show_vk(const String &p_existing, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
if (_show_keyboard) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStr = env->NewStringUTF(p_existing.utf8().get_data());
- env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_max_input_length);
+ env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_max_input_length, p_cursor_start, p_cursor_end);
}
}
diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h
index dbb3b564f6..1742021379 100644
--- a/platform/android/java_godot_io_wrapper.h
+++ b/platform/android/java_godot_io_wrapper.h
@@ -70,7 +70,7 @@ public:
int get_screen_dpi();
String get_unique_id();
bool has_vk();
- void show_vk(const String &p_existing, int p_max_input_length);
+ void show_vk(const String &p_existing, int p_max_input_length, int p_cursor_start, int p_cursor_end);
void hide_vk();
int get_vk_height();
void set_vk_height(int p_height);
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index 8b38113e09..1f61c4a805 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -38,7 +38,7 @@
#include "api/jni_singleton.h"
#include "audio_driver_jandroid.h"
#include "core/engine.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/project_settings.h"
#include "dir_access_jandroid.h"
#include "display_server_android.h"
@@ -78,7 +78,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHei
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion) {
-
initialized = true;
JavaVM *jvm;
@@ -137,7 +136,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jc
j_cmdline = (jstring *)malloc(cmdlen * sizeof(jstring));
for (int i = 0; i < cmdlen; i++) {
-
jstring string = (jstring)env->GetObjectArrayElement(p_cmdline, i);
const char *rawString = env->GetStringUTFChars(string, 0);
@@ -166,10 +164,20 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jc
ClassDB::register_class<JNISingleton>();
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height) {
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jobject p_surface, jint p_width, jint p_height) {
+ if (os_android) {
+ os_android->set_display_size(Size2i(p_width, p_height));
- if (os_android)
- os_android->set_display_size(Size2i(width, height));
+ // No need to reset the surface during startup
+ if (step > 0) {
+ if (p_surface) {
+ ANativeWindow *native_window = ANativeWindow_fromSurface(env, p_surface);
+ os_android->set_native_window(native_window);
+
+ DisplayServerAndroid::get_singleton()->reset_window();
+ }
+ }
+ }
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits) {
@@ -225,19 +233,16 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jcl
DisplayServerAndroid::get_singleton()->process_gyroscope(gyroscope);
if (os_android->main_loop_iterate()) {
-
godot_java->force_quit(env);
}
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jclass clazz, jint ev, jint pointer, jint count, jintArray positions) {
-
if (step == 0)
return;
Vector<DisplayServerAndroid::TouchPos> points;
for (int i = 0; i < count; i++) {
-
jint p[3];
env->GetIntArrayRegion(positions, i * 3, 3, p);
DisplayServerAndroid::TouchPos tp;
@@ -311,15 +316,15 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j
int hat = 0;
if (p_hat_x != 0) {
if (p_hat_x < 0)
- hat |= InputFilter::HAT_MASK_LEFT;
+ hat |= Input::HAT_MASK_LEFT;
else
- hat |= InputFilter::HAT_MASK_RIGHT;
+ hat |= Input::HAT_MASK_RIGHT;
}
if (p_hat_y != 0) {
if (p_hat_y < 0)
- hat |= InputFilter::HAT_MASK_UP;
+ hat |= Input::HAT_MASK_UP;
else
- hat |= InputFilter::HAT_MASK_DOWN;
+ hat |= Input::HAT_MASK_DOWN;
}
jevent.hat = hat;
@@ -329,7 +334,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv *env, jclass clazz, jint p_device, jboolean p_connected, jstring p_name) {
if (os_android) {
String name = jstring_to_string(p_name, env);
- InputFilter::get_singleton()->joy_connection_changed(p_device, p_connected, name);
+ Input::get_singleton()->joy_connection_changed(p_device, p_connected, name);
}
}
@@ -357,7 +362,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jclass clazz) {
-
if (step == 0)
return;
@@ -365,7 +369,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env,
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jclass clazz) {
-
if (step == 0)
return;
@@ -373,21 +376,18 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env,
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jclass clazz) {
-
ThreadAndroid::setup_thread();
AudioDriverAndroid::thread_func(env);
}
JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getGlobal(JNIEnv *env, jclass clazz, jstring path) {
-
String js = jstring_to_string(path, env);
return env->NewStringUTF(ProjectSettings::get_singleton()->get(js).operator String().utf8().get_data());
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *env, jclass clazz, jint ID, jstring method, jobjectArray params) {
-
- Object *obj = ObjectDB::get_instance(ObjectID((uint64_t)ID));
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *env, jclass clazz, jlong ID, jstring method, jobjectArray params) {
+ Object *obj = ObjectDB::get_instance(ObjectID(ID));
ERR_FAIL_COND(!obj);
int res = env->PushLocalFrame(16);
@@ -399,7 +399,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *en
Variant *vlist = (Variant *)alloca(sizeof(Variant) * count);
Variant **vptr = (Variant **)alloca(sizeof(Variant *) * count);
for (int i = 0; i < count; i++) {
-
jobject obj = env->GetObjectArrayElement(params, i);
Variant v;
if (obj)
@@ -417,9 +416,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *en
env->PopLocalFrame(nullptr);
}
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jclass clazz, jint ID, jstring method, jobjectArray params) {
-
- Object *obj = ObjectDB::get_instance(ObjectID((uint64_t)ID));
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jclass clazz, jlong ID, jstring method, jobjectArray params) {
+ Object *obj = ObjectDB::get_instance(ObjectID(ID));
ERR_FAIL_COND(!obj);
int res = env->PushLocalFrame(16);
@@ -431,7 +429,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *
Variant args[VARIANT_ARG_MAX];
for (int i = 0; i < MIN(count, VARIANT_ARG_MAX); i++) {
-
jobject obj = env->GetObjectArrayElement(params, i);
if (obj)
args[i] = _jobject_to_variant(env, obj);
diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h
index 221d701e2b..e8be7be0d0 100644
--- a/platform/android/java_godot_lib_jni.h
+++ b/platform/android/java_godot_lib_jni.h
@@ -40,7 +40,7 @@ extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz, jobject activity);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jobject p_surface, jint p_width, jint p_height);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jobject p_surface, jboolean p_32_bits);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jclass clazz);
@@ -61,8 +61,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jclass clazz);
JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getGlobal(JNIEnv *env, jclass clazz, jstring path);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *env, jclass clazz, jint ID, jstring method, jobjectArray params);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jclass clazz, jint ID, jstring method, jobjectArray params);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *env, jclass clazz, jlong ID, jstring method, jobjectArray params);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jclass clazz, jlong ID, jstring method, jobjectArray params);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jclass clazz, jint p_height);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResult(JNIEnv *env, jclass clazz, jstring p_permission, jboolean p_result);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNIEnv *env, jclass clazz);
diff --git a/platform/android/jni_utils.cpp b/platform/android/jni_utils.cpp
index ded79a668f..8e1ae53b78 100644
--- a/platform/android/jni_utils.cpp
+++ b/platform/android/jni_utils.cpp
@@ -31,13 +31,10 @@
#include "jni_utils.h"
jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_arg, bool force_jobject) {
-
jvalret v;
switch (p_type) {
-
case Variant::BOOL: {
-
if (force_jobject) {
jclass bclass = env->FindClass("java/lang/Boolean");
jmethodID ctor = env->GetMethodID(bclass, "<init>", "(Z)V");
@@ -52,9 +49,7 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
};
} break;
case Variant::INT: {
-
if (force_jobject) {
-
jclass bclass = env->FindClass("java/lang/Integer");
jmethodID ctor = env->GetMethodID(bclass, "<init>", "(I)V");
jvalue val;
@@ -69,9 +64,7 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
};
} break;
case Variant::FLOAT: {
-
if (force_jobject) {
-
jclass bclass = env->FindClass("java/lang/Double");
jmethodID ctor = env->GetMethodID(bclass, "<init>", "(D)V");
jvalue val;
@@ -86,19 +79,16 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
};
} break;
case Variant::STRING: {
-
String s = *p_arg;
jstring jStr = env->NewStringUTF(s.utf8().get_data());
v.val.l = jStr;
v.obj = jStr;
} break;
case Variant::PACKED_STRING_ARRAY: {
-
Vector<String> sarray = *p_arg;
jobjectArray arr = env->NewObjectArray(sarray.size(), env->FindClass("java/lang/String"), env->NewStringUTF(""));
for (int j = 0; j < sarray.size(); j++) {
-
jstring str = env->NewStringUTF(sarray[j].utf8().get_data());
env->SetObjectArrayElement(arr, j, str);
env->DeleteLocalRef(str);
@@ -109,7 +99,6 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
} break;
case Variant::DICTIONARY: {
-
Dictionary dict = *p_arg;
jclass dclass = env->FindClass("org/godotengine/godot/Dictionary");
jmethodID ctor = env->GetMethodID(dclass, "<init>", "()V");
@@ -152,7 +141,6 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
} break;
case Variant::PACKED_INT32_ARRAY: {
-
Vector<int> array = *p_arg;
jintArray arr = env->NewIntArray(array.size());
const int *r = array.ptr();
@@ -171,7 +159,6 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
} break;
case Variant::PACKED_FLOAT32_ARRAY: {
-
Vector<float> array = *p_arg;
jfloatArray arr = env->NewFloatArray(array.size());
const float *r = array.ptr();
@@ -185,7 +172,6 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
#endif
default: {
-
v.val.i = 0;
} break;
}
@@ -193,7 +179,6 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a
}
String _get_class_name(JNIEnv *env, jclass cls, bool *array) {
-
jclass cclass = env->FindClass("java/lang/Class");
jmethodID getName = env->GetMethodID(cclass, "getName", "()Ljava/lang/String;");
jstring clsName = (jstring)env->CallObjectMethod(cls, getName);
@@ -210,7 +195,6 @@ String _get_class_name(JNIEnv *env, jclass cls, bool *array) {
}
Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
-
if (obj == nullptr) {
return Variant();
}
@@ -220,12 +204,10 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
String name = _get_class_name(env, c, &array);
if (name == "java.lang.String") {
-
return jstring_to_string((jstring)obj, env);
};
if (name == "[Ljava.lang.String;") {
-
jobjectArray arr = (jobjectArray)obj;
int stringCount = env->GetArrayLength(arr);
Vector<String> sarr;
@@ -240,14 +222,12 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
};
if (name == "java.lang.Boolean") {
-
jmethodID boolValue = env->GetMethodID(c, "booleanValue", "()Z");
bool ret = env->CallBooleanMethod(obj, boolValue);
return ret;
};
if (name == "java.lang.Integer" || name == "java.lang.Long") {
-
jclass nclass = env->FindClass("java/lang/Number");
jmethodID longValue = env->GetMethodID(nclass, "longValue", "()J");
jlong ret = env->CallLongMethod(obj, longValue);
@@ -255,7 +235,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
};
if (name == "[I") {
-
jintArray arr = (jintArray)obj;
int fCount = env->GetArrayLength(arr);
Vector<int> sarr;
@@ -267,7 +246,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
};
if (name == "[B") {
-
jbyteArray arr = (jbyteArray)obj;
int fCount = env->GetArrayLength(arr);
Vector<uint8_t> sarr;
@@ -279,7 +257,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
};
if (name == "java.lang.Float" || name == "java.lang.Double") {
-
jclass nclass = env->FindClass("java/lang/Number");
jmethodID doubleValue = env->GetMethodID(nclass, "doubleValue", "()D");
double ret = env->CallDoubleMethod(obj, doubleValue);
@@ -287,7 +264,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
};
if (name == "[D") {
-
jdoubleArray arr = (jdoubleArray)obj;
int fCount = env->GetArrayLength(arr);
PackedFloat32Array sarr;
@@ -296,7 +272,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
real_t *w = sarr.ptrw();
for (int i = 0; i < fCount; i++) {
-
double n;
env->GetDoubleArrayRegion(arr, i, 1, &n);
w[i] = n;
@@ -305,7 +280,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
};
if (name == "[F") {
-
jfloatArray arr = (jfloatArray)obj;
int fCount = env->GetArrayLength(arr);
PackedFloat32Array sarr;
@@ -314,7 +288,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
real_t *w = sarr.ptrw();
for (int i = 0; i < fCount; i++) {
-
float n;
env->GetFloatArrayRegion(arr, i, 1, &n);
w[i] = n;
@@ -323,7 +296,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
};
if (name == "[Ljava.lang.Object;") {
-
jobjectArray arr = (jobjectArray)obj;
int objCount = env->GetArrayLength(arr);
Array varr;
@@ -339,7 +311,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
};
if (name == "java.util.HashMap" || name == "org.godotengine.godot.Dictionary") {
-
Dictionary ret;
jclass oclass = c;
jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;");
@@ -355,7 +326,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
env->DeleteLocalRef(arr);
for (int i = 0; i < keys.size(); i++) {
-
ret[keys[i]] = vals[i];
};
@@ -368,7 +338,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) {
}
Variant::Type get_jni_type(const String &p_type) {
-
static struct {
const char *name;
Variant::Type type;
@@ -390,7 +359,6 @@ Variant::Type get_jni_type(const String &p_type) {
int idx = 0;
while (_type_to_vtype[idx].name) {
-
if (p_type == _type_to_vtype[idx].name)
return _type_to_vtype[idx].type;
@@ -401,7 +369,6 @@ Variant::Type get_jni_type(const String &p_type) {
}
const char *get_jni_sig(const String &p_type) {
-
static struct {
const char *name;
const char *sig;
@@ -423,7 +390,6 @@ const char *get_jni_sig(const String &p_type) {
int idx = 0;
while (_type_to_vtype[idx].name) {
-
if (p_type == _type_to_vtype[idx].name)
return _type_to_vtype[idx].sig;
diff --git a/platform/android/jni_utils.h b/platform/android/jni_utils.h
index c2baa51b4a..5320715853 100644
--- a/platform/android/jni_utils.h
+++ b/platform/android/jni_utils.h
@@ -37,7 +37,6 @@
#include <jni.h>
struct jvalret {
-
jobject obj;
jvalue val;
jvalret() { obj = nullptr; }
diff --git a/platform/android/net_socket_android.cpp b/platform/android/net_socket_android.cpp
index 320bdd3817..0341ef3ec6 100644
--- a/platform/android/net_socket_android.cpp
+++ b/platform/android/net_socket_android.cpp
@@ -38,7 +38,6 @@ jmethodID NetSocketAndroid::_multicast_lock_acquire = 0;
jmethodID NetSocketAndroid::_multicast_lock_release = 0;
void NetSocketAndroid::setup(jobject p_net_utils) {
-
JNIEnv *env = ThreadAndroid::get_env();
net_utils = env->NewGlobalRef(p_net_utils);
@@ -72,11 +71,6 @@ void NetSocketAndroid::make_default() {
_create = _create_func;
}
-NetSocketAndroid::NetSocketAndroid() :
- wants_broadcast(false),
- multicast_groups(0) {
-}
-
NetSocketAndroid::~NetSocketAndroid() {
close();
}
diff --git a/platform/android/net_socket_android.h b/platform/android/net_socket_android.h
index 4fc80d2de1..955d906535 100644
--- a/platform/android/net_socket_android.h
+++ b/platform/android/net_socket_android.h
@@ -45,15 +45,14 @@
* joins/leaves a multicast group.
*/
class NetSocketAndroid : public NetSocketPosix {
-
private:
static jobject net_utils;
static jclass cls;
static jmethodID _multicast_lock_acquire;
static jmethodID _multicast_lock_release;
- bool wants_broadcast;
- int multicast_groups;
+ bool wants_broadcast = false;
+ int multicast_groups = 0;
static void multicast_lock_acquire();
static void multicast_lock_release();
@@ -71,7 +70,7 @@ public:
virtual Error join_multicast_group(const IP_Address &p_multi_address, String p_if_name);
virtual Error leave_multicast_group(const IP_Address &p_multi_address, String p_if_name);
- NetSocketAndroid();
+ NetSocketAndroid() {}
~NetSocketAndroid();
};
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 760157595c..baf6ee952a 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -57,7 +57,6 @@ public:
};
void OS_Android::initialize_core() {
-
OS_Unix::initialize_core();
if (use_apk_expansion)
@@ -88,7 +87,7 @@ void OS_Android::initialize() {
}
void OS_Android::initialize_joypads() {
- InputFilter::get_singleton()->set_fallback_mapping(godot_java->get_input_fallback_mapping());
+ Input::get_singleton()->set_fallback_mapping(godot_java->get_input_fallback_mapping());
// This queries/updates the currently connected devices/joypads.
godot_java->init_input_devices();
@@ -121,17 +120,14 @@ GodotIOJavaWrapper *OS_Android::get_godot_io_java() {
}
bool OS_Android::request_permission(const String &p_name) {
-
return godot_java->request_permission(p_name);
}
bool OS_Android::request_permissions() {
-
return godot_java->request_permissions();
}
Vector<String> OS_Android::get_granted_permissions() const {
-
return godot_java->get_granted_permissions();
}
@@ -142,30 +138,25 @@ Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_han
}
String OS_Android::get_name() const {
-
return "Android";
}
MainLoop *OS_Android::get_main_loop() const {
-
return main_loop;
}
void OS_Android::main_loop_begin() {
-
if (main_loop)
main_loop->init();
}
bool OS_Android::main_loop_iterate() {
-
if (!main_loop)
return false;
return Main::iteration();
}
void OS_Android::main_loop_end() {
-
if (main_loop)
main_loop->finish();
}
@@ -185,17 +176,14 @@ void OS_Android::main_loop_request_go_back() {
}
Error OS_Android::shell_open(String p_uri) {
-
return godot_io_java->open_uri(p_uri);
}
String OS_Android::get_resource_dir() const {
-
return "/"; //android has its own filesystem for resources inside the APK
}
String OS_Android::get_locale() const {
-
String locale = godot_io_java->get_locale();
if (locale != "") {
return locale;
@@ -205,7 +193,6 @@ String OS_Android::get_locale() const {
}
String OS_Android::get_model_name() const {
-
String model = godot_io_java->get_model();
if (model != "")
return model;
@@ -214,13 +201,11 @@ String OS_Android::get_model_name() const {
}
String OS_Android::get_user_data_dir() const {
-
if (data_dir_cache != String())
return data_dir_cache;
String data_dir = godot_io_java->get_user_data_dir();
if (data_dir != "") {
-
//store current dir
char real_current_dir_name[2048];
getcwd(real_current_dir_name, 2048);
@@ -245,7 +230,6 @@ String OS_Android::get_user_data_dir() const {
}
String OS_Android::get_unique_id() const {
-
String unique_id = godot_io_java->get_unique_id();
if (unique_id != "")
return unique_id;
@@ -254,7 +238,6 @@ String OS_Android::get_unique_id() const {
}
String OS_Android::get_system_dir(SystemDir p_dir) const {
-
return godot_io_java->get_system_dir(p_dir);
}
diff --git a/platform/android/plugin/godot_plugin_config.h b/platform/android/plugin/godot_plugin_config.h
new file mode 100644
index 0000000000..9ad7de1202
--- /dev/null
+++ b/platform/android/plugin/godot_plugin_config.h
@@ -0,0 +1,251 @@
+/*************************************************************************/
+/* godot_plugin_config.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef GODOT_PLUGIN_CONFIG_H
+#define GODOT_PLUGIN_CONFIG_H
+
+#include "core/error_list.h"
+#include "core/io/config_file.h"
+#include "core/ustring.h"
+
+static const char *PLUGIN_CONFIG_EXT = ".gdap";
+
+static const char *CONFIG_SECTION = "config";
+static const char *CONFIG_NAME_KEY = "name";
+static const char *CONFIG_BINARY_TYPE_KEY = "binary_type";
+static const char *CONFIG_BINARY_KEY = "binary";
+
+static const char *DEPENDENCIES_SECTION = "dependencies";
+static const char *DEPENDENCIES_LOCAL_KEY = "local";
+static const char *DEPENDENCIES_REMOTE_KEY = "remote";
+static const char *DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY = "custom_maven_repos";
+
+static const char *BINARY_TYPE_LOCAL = "local";
+static const char *BINARY_TYPE_REMOTE = "remote";
+
+static const char *PLUGIN_VALUE_SEPARATOR = "|";
+
+/*
+ The `config` section and fields are required and defined as follow:
+- **name**: name of the plugin
+- **binary_type**: can be either `local` or `remote`. The type affects the **binary** field
+- **binary**:
+ - if **binary_type** is `local`, then this should be the filename of the plugin `aar` file in the `res://android/plugins` directory (e.g: `MyPlugin.aar`).
+ - if **binary_type** is `remote`, then this should be a declaration for a remote gradle binary (e.g: "org.godot.example:my-plugin:0.0.0").
+
+The `dependencies` section and fields are optional and defined as follow:
+- **local**: contains a list of local `.aar` binary files the plugin depends on. The local binary dependencies must also be located in the `res://android/plugins` directory.
+- **remote**: contains a list of remote binary gradle dependencies for the plugin.
+- **custom_maven_repos**: contains a list of urls specifying custom maven repos required for the plugin's dependencies.
+
+ See https://github.com/godotengine/godot/issues/38157#issuecomment-618773871
+ */
+struct PluginConfig {
+ // Set to true when the config file is properly loaded.
+ bool valid_config = false;
+
+ // Required config section
+ String name;
+ String binary_type;
+ String binary;
+
+ // Optional dependencies section
+ Vector<String> local_dependencies;
+ Vector<String> remote_dependencies;
+ Vector<String> custom_maven_repos;
+};
+
+/*
+ * Set of prebuilt plugins.
+ */
+static const PluginConfig GODOT_PAYMENT = {
+ /*.valid_config =*/true,
+ /*.name =*/"GodotPayment",
+ /*.binary_type =*/"local",
+ /*.binary =*/"res://android/build/libs/plugins/GodotPayment.release.aar",
+ /*.local_dependencies =*/{},
+ /*.remote_dependencies =*/{},
+ /*.custom_maven_repos =*/{}
+};
+
+static inline String resolve_local_dependency_path(String plugin_config_dir, String dependency_path) {
+ String absolute_path;
+ if (!dependency_path.empty()) {
+ if (dependency_path.is_abs_path()) {
+ absolute_path = ProjectSettings::get_singleton()->globalize_path(dependency_path);
+ } else {
+ absolute_path = plugin_config_dir.plus_file(dependency_path);
+ }
+ }
+
+ return absolute_path;
+}
+
+static inline PluginConfig resolve_prebuilt_plugin(PluginConfig prebuilt_plugin, String plugin_config_dir) {
+ PluginConfig resolved = prebuilt_plugin;
+ resolved.binary = resolved.binary_type == BINARY_TYPE_LOCAL ? resolve_local_dependency_path(plugin_config_dir, prebuilt_plugin.binary) : prebuilt_plugin.binary;
+ if (!prebuilt_plugin.local_dependencies.empty()) {
+ resolved.local_dependencies.clear();
+ for (int i = 0; i < prebuilt_plugin.local_dependencies.size(); i++) {
+ resolved.local_dependencies.push_back(resolve_local_dependency_path(plugin_config_dir, prebuilt_plugin.local_dependencies[i]));
+ }
+ }
+ return resolved;
+}
+
+static inline Vector<PluginConfig> get_prebuilt_plugins(String plugins_base_dir) {
+ Vector<PluginConfig> prebuilt_plugins;
+ prebuilt_plugins.push_back(resolve_prebuilt_plugin(GODOT_PAYMENT, plugins_base_dir));
+ return prebuilt_plugins;
+}
+
+static inline bool is_plugin_config_valid(PluginConfig plugin_config) {
+ bool valid_name = !plugin_config.name.empty();
+ bool valid_binary_type = plugin_config.binary_type == BINARY_TYPE_LOCAL ||
+ plugin_config.binary_type == BINARY_TYPE_REMOTE;
+
+ bool valid_binary = false;
+ if (valid_binary_type) {
+ valid_binary = !plugin_config.binary.empty() &&
+ (plugin_config.binary_type == BINARY_TYPE_REMOTE ||
+ FileAccess::exists(plugin_config.binary));
+ }
+
+ bool valid_local_dependencies = true;
+ if (!plugin_config.local_dependencies.empty()) {
+ for (int i = 0; i < plugin_config.local_dependencies.size(); i++) {
+ if (!FileAccess::exists(plugin_config.local_dependencies[i])) {
+ valid_local_dependencies = false;
+ break;
+ }
+ }
+ }
+ return valid_name && valid_binary && valid_binary_type && valid_local_dependencies;
+}
+
+static inline PluginConfig load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
+ PluginConfig plugin_config = {};
+
+ if (config_file.is_valid()) {
+ Error err = config_file->load(path);
+ if (err == OK) {
+ String config_base_dir = path.get_base_dir();
+
+ plugin_config.name = config_file->get_value(CONFIG_SECTION, CONFIG_NAME_KEY, String());
+ plugin_config.binary_type = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_TYPE_KEY, String());
+
+ String binary_path = config_file->get_value(CONFIG_SECTION, CONFIG_BINARY_KEY, String());
+ plugin_config.binary = plugin_config.binary_type == BINARY_TYPE_LOCAL ? resolve_local_dependency_path(config_base_dir, binary_path) : binary_path;
+
+ if (config_file->has_section(DEPENDENCIES_SECTION)) {
+ Vector<String> local_dependencies_paths = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_LOCAL_KEY, Vector<String>());
+ if (!local_dependencies_paths.empty()) {
+ for (int i = 0; i < local_dependencies_paths.size(); i++) {
+ plugin_config.local_dependencies.push_back(resolve_local_dependency_path(config_base_dir, local_dependencies_paths[i]));
+ }
+ }
+
+ plugin_config.remote_dependencies = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_REMOTE_KEY, Vector<String>());
+ plugin_config.custom_maven_repos = config_file->get_value(DEPENDENCIES_SECTION, DEPENDENCIES_CUSTOM_MAVEN_REPOS_KEY, Vector<String>());
+ }
+
+ plugin_config.valid_config = is_plugin_config_valid(plugin_config);
+ }
+ }
+
+ return plugin_config;
+}
+
+static inline String get_plugins_binaries(String binary_type, Vector<PluginConfig> plugins_configs) {
+ String plugins_binaries;
+ if (!plugins_configs.empty()) {
+ Vector<String> binaries;
+ for (int i = 0; i < plugins_configs.size(); i++) {
+ PluginConfig config = plugins_configs[i];
+ if (!config.valid_config) {
+ continue;
+ }
+
+ if (config.binary_type == binary_type) {
+ binaries.push_back(config.binary);
+ }
+
+ if (binary_type == BINARY_TYPE_LOCAL) {
+ binaries.append_array(config.local_dependencies);
+ }
+
+ if (binary_type == BINARY_TYPE_REMOTE) {
+ binaries.append_array(config.remote_dependencies);
+ }
+ }
+
+ plugins_binaries = String(PLUGIN_VALUE_SEPARATOR).join(binaries);
+ }
+
+ return plugins_binaries;
+}
+
+static inline String get_plugins_custom_maven_repos(Vector<PluginConfig> plugins_configs) {
+ String custom_maven_repos;
+ if (!plugins_configs.empty()) {
+ Vector<String> repos_urls;
+ for (int i = 0; i < plugins_configs.size(); i++) {
+ PluginConfig config = plugins_configs[i];
+ if (!config.valid_config) {
+ continue;
+ }
+
+ repos_urls.append_array(config.custom_maven_repos);
+ }
+
+ custom_maven_repos = String(PLUGIN_VALUE_SEPARATOR).join(repos_urls);
+ }
+ return custom_maven_repos;
+}
+
+static inline String get_plugins_names(Vector<PluginConfig> plugins_configs) {
+ String plugins_names;
+ if (!plugins_configs.empty()) {
+ Vector<String> names;
+ for (int i = 0; i < plugins_configs.size(); i++) {
+ PluginConfig config = plugins_configs[i];
+ if (!config.valid_config) {
+ continue;
+ }
+
+ names.push_back(config.name);
+ }
+ plugins_names = String(PLUGIN_VALUE_SEPARATOR).join(names);
+ }
+
+ return plugins_names;
+}
+
+#endif // GODOT_PLUGIN_CONFIG_H
diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp
index c3bfb2f2ed..557743fa73 100644
--- a/platform/android/plugin/godot_plugin_jni.cpp
+++ b/platform/android/plugin/godot_plugin_jni.cpp
@@ -42,7 +42,6 @@ static HashMap<String, JNISingleton *> jni_singletons;
extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jobject obj, jstring name) {
-
String singname = jstring_to_string(name, env);
JNISingleton *s = (JNISingleton *)ClassDB::instance("JNISingleton");
s->set_instance(env->NewGlobalRef(obj));
@@ -53,7 +52,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args) {
-
String singname = jstring_to_string(sname, env);
ERR_FAIL_COND(!jni_singletons.has(singname));
@@ -68,7 +66,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
int stringCount = env->GetArrayLength(args);
for (int i = 0; i < stringCount; i++) {
-
jstring string = (jstring)env->GetObjectArrayElement(args, i);
const String rawString = jstring_to_string(string, env);
types.push_back(get_jni_type(rawString));
@@ -80,7 +77,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
jclass cls = env->GetObjectClass(s->get_instance());
jmethodID mid = env->GetMethodID(cls, mname.ascii().get_data(), cs.ascii().get_data());
if (!mid) {
-
print_line("Failed getting method ID " + mname);
}
@@ -100,7 +96,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
int stringCount = env->GetArrayLength(j_signal_param_types);
for (int i = 0; i < stringCount; i++) {
-
jstring j_signal_param_type = (jstring)env->GetObjectArrayElement(j_signal_param_types, i);
const String signal_param_type = jstring_to_string(j_signal_param_type, env);
types.push_back(get_jni_type(signal_param_type));
@@ -122,7 +117,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitS
const Variant *args[count];
for (int i = 0; i < count; i++) {
-
jobject j_param = env->GetObjectArrayElement(j_signal_params, i);
Variant variant = _jobject_to_variant(env, j_param);
args[i] = &variant;
diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp
index 729327f6f0..13aa313ebf 100644
--- a/platform/android/thread_jandroid.cpp
+++ b/platform/android/thread_jandroid.cpp
@@ -48,17 +48,14 @@ pthread_key_t ThreadAndroid::thread_id_key = _create_thread_id_key();
Thread::ID ThreadAndroid::next_thread_id = 0;
Thread::ID ThreadAndroid::get_id() const {
-
return id;
}
Thread *ThreadAndroid::create_thread_jandroid() {
-
return memnew(ThreadAndroid);
}
void *ThreadAndroid::thread_callback(void *userdata) {
-
ThreadAndroid *t = reinterpret_cast<ThreadAndroid *>(userdata);
setup_thread();
ScriptServer::thread_enter(); //scripts may need to attach a stack
@@ -70,7 +67,6 @@ void *ThreadAndroid::thread_callback(void *userdata) {
}
Thread *ThreadAndroid::create_func_jandroid(ThreadCreateCallback p_callback, void *p_user, const Settings &) {
-
ThreadAndroid *tr = memnew(ThreadAndroid);
tr->callback = p_callback;
tr->user = p_user;
@@ -83,7 +79,6 @@ Thread *ThreadAndroid::create_func_jandroid(ThreadCreateCallback p_callback, voi
}
Thread::ID ThreadAndroid::get_thread_id_func_jandroid() {
-
void *value = pthread_getspecific(thread_id_key);
if (value)
@@ -95,7 +90,6 @@ Thread::ID ThreadAndroid::get_thread_id_func_jandroid() {
}
void ThreadAndroid::wait_to_finish_func_jandroid(Thread *p_thread) {
-
ThreadAndroid *tp = static_cast<ThreadAndroid *>(p_thread);
ERR_FAIL_COND(!tp);
ERR_FAIL_COND(tp->pthread == 0);
@@ -105,7 +99,6 @@ void ThreadAndroid::wait_to_finish_func_jandroid(Thread *p_thread) {
}
void ThreadAndroid::_thread_destroyed(void *value) {
-
/* The thread is being destroyed, detach it from the Java VM and set the mThreadKey value to NULL as required */
JNIEnv *env = (JNIEnv *)value;
if (env != nullptr) {
@@ -118,7 +111,6 @@ pthread_key_t ThreadAndroid::jvm_key;
JavaVM *ThreadAndroid::java_vm = nullptr;
void ThreadAndroid::setup_thread() {
-
if (pthread_getspecific(jvm_key))
return; //already setup
JNIEnv *env;
@@ -127,7 +119,6 @@ void ThreadAndroid::setup_thread() {
}
void ThreadAndroid::make_default(JavaVM *p_java_vm) {
-
java_vm = p_java_vm;
create_func = create_func_jandroid;
get_thread_id_func = get_thread_id_func_jandroid;
@@ -137,7 +128,6 @@ void ThreadAndroid::make_default(JavaVM *p_java_vm) {
}
JNIEnv *ThreadAndroid::get_env() {
-
if (!pthread_getspecific(jvm_key)) {
setup_thread();
}
@@ -148,7 +138,6 @@ JNIEnv *ThreadAndroid::get_env() {
}
ThreadAndroid::ThreadAndroid() {
-
pthread = 0;
}
diff --git a/platform/android/thread_jandroid.h b/platform/android/thread_jandroid.h
index eb4725ae68..9cfcc64813 100644
--- a/platform/android/thread_jandroid.h
+++ b/platform/android/thread_jandroid.h
@@ -37,7 +37,6 @@
#include <sys/types.h>
class ThreadAndroid : public Thread {
-
static pthread_key_t thread_id_key;
static ID next_thread_id;
diff --git a/platform/android/vulkan/vulkan_context_android.h b/platform/android/vulkan/vulkan_context_android.h
index 7e698ada4f..6bd3cbee36 100644
--- a/platform/android/vulkan/vulkan_context_android.h
+++ b/platform/android/vulkan/vulkan_context_android.h
@@ -36,7 +36,6 @@
struct ANativeWindow;
class VulkanContextAndroid : public VulkanContext {
-
virtual const char *_get_platform_surface_extension() const;
public:
diff --git a/platform/haiku/audio_driver_media_kit.cpp b/platform/haiku/audio_driver_media_kit.cpp
index 94c9e83368..2fbbeeb176 100644
--- a/platform/haiku/audio_driver_media_kit.cpp
+++ b/platform/haiku/audio_driver_media_kit.cpp
@@ -39,11 +39,11 @@ int32_t *AudioDriverMediaKit::samples_in = nullptr;
Error AudioDriverMediaKit::init() {
active = false;
- mix_rate = GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+ mix_rate = GLOBAL_GET("audio/mix_rate");
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
- int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ int latency = GLOBAL_GET("audio/output_latency");
buffer_size = next_power_of_2(latency * mix_rate / 1000);
samples_in = memnew_arr(int32_t, buffer_size * channels);
diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h
index 925bb9ac5d..4817abbb7a 100644
--- a/platform/haiku/haiku_direct_window.h
+++ b/platform/haiku/haiku_direct_window.h
@@ -35,7 +35,7 @@
#include <DirectWindow.h>
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/os.h"
#include "haiku_gl_view.h"
diff --git a/platform/haiku/key_mapping_haiku.h b/platform/haiku/key_mapping_haiku.h
index a0e85e3390..e735108e44 100644
--- a/platform/haiku/key_mapping_haiku.h
+++ b/platform/haiku/key_mapping_haiku.h
@@ -32,7 +32,7 @@
#define KEY_MAPPING_HAIKU_H
class KeyMappingHaiku {
- KeyMappingHaiku(){};
+ KeyMappingHaiku() {}
public:
static unsigned int get_keysym(int32 raw_char, int32 key);
diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp
index 07cb18d7cd..7a2591784f 100644
--- a/platform/haiku/os_haiku.cpp
+++ b/platform/haiku/os_haiku.cpp
@@ -324,12 +324,10 @@ String OS_Haiku::get_executable_path() const {
}
bool OS_Haiku::_check_internal_feature_support(const String &p_feature) {
-
return p_feature == "pc";
}
String OS_Haiku::get_config_path() const {
-
if (has_environment("XDG_CONFIG_HOME")) {
return get_environment("XDG_CONFIG_HOME");
} else if (has_environment("HOME")) {
@@ -340,7 +338,6 @@ String OS_Haiku::get_config_path() const {
}
String OS_Haiku::get_data_path() const {
-
if (has_environment("XDG_DATA_HOME")) {
return get_environment("XDG_DATA_HOME");
} else if (has_environment("HOME")) {
@@ -351,7 +348,6 @@ String OS_Haiku::get_data_path() const {
}
String OS_Haiku::get_cache_path() const {
-
if (has_environment("XDG_CACHE_HOME")) {
return get_environment("XDG_CACHE_HOME");
} else if (has_environment("HOME")) {
diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h
index 64f5690dd1..d3ef9400d4 100644
--- a/platform/haiku/os_haiku.h
+++ b/platform/haiku/os_haiku.h
@@ -33,7 +33,7 @@
#include "audio_driver_media_kit.h"
#include "context_gl_haiku.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "drivers/unix/os_unix.h"
#include "haiku_application.h"
#include "haiku_direct_window.h"
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index 0ac8bb7a56..c4ef185bf1 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -247,37 +247,31 @@ static void on_focus_in(ViewController *view_controller, bool *is_focus_out) {
int joy_id = [self getJoyIdForController:controller];
if (element == gamepad.buttonA) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_A,
gamepad.buttonA.isPressed);
} else if (element == gamepad.buttonB) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_1,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_B,
gamepad.buttonB.isPressed);
} else if (element == gamepad.buttonX) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_X,
gamepad.buttonX.isPressed);
} else if (element == gamepad.buttonY) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_3,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_Y,
gamepad.buttonY.isPressed);
} else if (element == gamepad.leftShoulder) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_L,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_LEFT_SHOULDER,
gamepad.leftShoulder.isPressed);
} else if (element == gamepad.rightShoulder) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_R,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_RIGHT_SHOULDER,
gamepad.rightShoulder.isPressed);
- } else if (element == gamepad.leftTrigger) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_L2,
- gamepad.leftTrigger.isPressed);
- } else if (element == gamepad.rightTrigger) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_R2,
- gamepad.rightTrigger.isPressed);
} else if (element == gamepad.dpad) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_UP,
gamepad.dpad.up.isPressed);
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_DOWN,
gamepad.dpad.down.isPressed);
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_LEFT,
gamepad.dpad.left.isPressed);
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_RIGHT,
gamepad.dpad.right.isPressed);
};
@@ -285,20 +279,20 @@ static void on_focus_in(ViewController *view_controller, bool *is_focus_out) {
jx.min = -1;
if (element == gamepad.leftThumbstick) {
jx.value = gamepad.leftThumbstick.xAxis.value;
- OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LX, jx);
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_AXIS_LEFT_X, jx);
jx.value = -gamepad.leftThumbstick.yAxis.value;
- OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LY, jx);
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_AXIS_LEFT_Y, jx);
} else if (element == gamepad.rightThumbstick) {
jx.value = gamepad.rightThumbstick.xAxis.value;
- OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RX, jx);
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_AXIS_RIGHT_X, jx);
jx.value = -gamepad.rightThumbstick.yAxis.value;
- OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RY, jx);
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_AXIS_RIGHT_Y, jx);
} else if (element == gamepad.leftTrigger) {
jx.value = gamepad.leftTrigger.value;
- OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_L2, jx);
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_AXIS_TRIGGER_LEFT, jx);
} else if (element == gamepad.rightTrigger) {
jx.value = gamepad.rightTrigger.value;
- OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_R2, jx);
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_AXIS_TRIGGER_RIGHT, jx);
};
};
} else if (controller.gamepad != nil) {
@@ -309,31 +303,31 @@ static void on_focus_in(ViewController *view_controller, bool *is_focus_out) {
int joy_id = [self getJoyIdForController:controller];
if (element == gamepad.buttonA) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_A,
gamepad.buttonA.isPressed);
} else if (element == gamepad.buttonB) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_1,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_B,
gamepad.buttonB.isPressed);
} else if (element == gamepad.buttonX) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_X,
gamepad.buttonX.isPressed);
} else if (element == gamepad.buttonY) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_3,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_Y,
gamepad.buttonY.isPressed);
} else if (element == gamepad.leftShoulder) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_L,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_LEFT_SHOULDER,
gamepad.leftShoulder.isPressed);
} else if (element == gamepad.rightShoulder) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_R,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_RIGHT_SHOULDER,
gamepad.rightShoulder.isPressed);
} else if (element == gamepad.dpad) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_UP,
gamepad.dpad.up.isPressed);
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_DOWN,
gamepad.dpad.down.isPressed);
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_LEFT,
gamepad.dpad.left.isPressed);
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_RIGHT,
gamepad.dpad.right.isPressed);
};
};
@@ -347,19 +341,19 @@ static void on_focus_in(ViewController *view_controller, bool *is_focus_out) {
int joy_id = [self getJoyIdForController:controller];
if (element == gamepad.buttonA) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_A,
gamepad.buttonA.isPressed);
} else if (element == gamepad.buttonX) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_X,
gamepad.buttonX.isPressed);
} else if (element == gamepad.dpad) {
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_UP,
gamepad.dpad.up.isPressed);
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_DOWN,
gamepad.dpad.down.isPressed);
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_LEFT,
gamepad.dpad.left.isPressed);
- OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_DPAD_RIGHT,
gamepad.dpad.right.isPressed);
};
};
@@ -432,7 +426,6 @@ OS::VideoMode _get_video_mode() {
static int frame_count = 0;
- (void)drawView:(UIView *)view;
{
-
switch (frame_count) {
case 0: {
OS::get_singleton()->set_video_mode(_get_video_mode());
@@ -469,7 +462,6 @@ static int frame_count = 0;
}; break;
case 1: {
-
Main::setup2();
++frame_count;
@@ -496,7 +488,6 @@ static int frame_count = 0;
ProjectSettings::get_singleton()->set("Info.plist/" + ukey, uval);
} else if ([value isKindOfClass:[NSNumber class]]) {
-
NSNumber *n = (NSNumber *)value;
double dval = [n doubleValue];
@@ -508,7 +499,6 @@ static int frame_count = 0;
}; break;
case 2: {
-
Main::start();
++frame_count;
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index 3efe338ac7..63c3cb8c23 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "export.h"
+
#include "core/io/image_loader.h"
#include "core/io/marshalls.h"
#include "core/io/resource_saver.h"
@@ -47,7 +48,6 @@
#include <sys/stat.h>
class EditorExportPlatformIOS : public EditorExportPlatform {
-
GDCLASS(EditorExportPlatformIOS, EditorExportPlatform);
int version_code;
@@ -72,14 +72,10 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
String modules_buildgrp;
};
struct ExportArchitecture {
-
String name;
- bool is_default;
+ bool is_default = false;
- ExportArchitecture() :
- name(""),
- is_default(false) {
- }
+ ExportArchitecture() {}
ExportArchitecture(String p_name, bool p_is_default) {
name = p_name;
@@ -107,7 +103,6 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
Error _export_additional_assets(const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets);
bool is_package_name_valid(const String &p_package, String *r_error = nullptr) const {
-
String pname = p_package;
if (pname.length() == 0) {
@@ -150,7 +145,6 @@ public:
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const;
virtual void get_platform_features(List<String> *r_features) {
-
r_features->push_back("mobile");
r_features->push_back("iOS");
}
@@ -163,7 +157,6 @@ public:
};
void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
-
String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name");
if (driver == "GLES2") {
r_features->push_back("etc");
@@ -209,7 +202,6 @@ static const LoadingScreenInfo loading_screen_infos[] = {
};
void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) {
-
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
@@ -423,7 +415,9 @@ String EditorExportPlatformIOS::_get_linker_flags() {
String result;
for (int i = 0; i < export_plugins.size(); ++i) {
String flags = export_plugins[i]->get_ios_linker_flags();
- if (flags.length() == 0) continue;
+ if (flags.length() == 0) {
+ continue;
+ }
if (result.length() > 0) {
result += ' ';
}
@@ -443,7 +437,6 @@ String EditorExportPlatformIOS::_get_cpp_code() {
}
void EditorExportPlatformIOS::_blend_and_rotate(Ref<Image> &p_dst, Ref<Image> &p_src, bool p_rot) {
-
ERR_FAIL_COND(p_dst.is_null());
ERR_FAIL_COND(p_src.is_null());
@@ -456,8 +449,12 @@ void EditorExportPlatformIOS::_blend_and_rotate(Ref<Image> &p_dst, Ref<Image> &p
int xs = (x_pos >= 0) ? 0 : -x_pos;
int ys = (y_pos >= 0) ? 0 : -y_pos;
- if (sw + x_pos > p_dst->get_width()) sw = p_dst->get_width() - x_pos;
- if (sh + y_pos > p_dst->get_height()) sh = p_dst->get_height() - y_pos;
+ if (sw + x_pos > p_dst->get_width()) {
+ sw = p_dst->get_width() - x_pos;
+ }
+ if (sh + y_pos > p_dst->get_height()) {
+ sh = p_dst->get_height() - y_pos;
+ }
for (int y = ys; y < sh; y++) {
for (int x = xs; x < sw; x++) {
@@ -927,8 +924,9 @@ Error EditorExportPlatformIOS::_export_additional_assets(const String &p_out_dir
ERR_FAIL_COND_V(err, err);
Vector<String> project_static_libs = export_plugins[i]->get_ios_project_static_libs();
- for (int j = 0; j < project_static_libs.size(); j++)
+ for (int j = 0; j < project_static_libs.size(); j++) {
project_static_libs.write[j] = project_static_libs[j].get_file(); // Only the file name as it's copied to the project
+ }
err = _export_additional_assets(p_out_dir, project_static_libs, true, r_exported_assets);
ERR_FAIL_COND_V(err, err);
@@ -987,10 +985,11 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
String team_id = p_preset->get("application/app_store_team_id");
ERR_FAIL_COND_V_MSG(team_id.length() == 0, ERR_CANT_OPEN, "App Store Team ID not specified - cannot configure the project.");
- if (p_debug)
+ if (p_debug) {
src_pkg_name = p_preset->get("custom_template/debug");
- else
+ } else {
src_pkg_name = p_preset->get("custom_template/release");
+ }
if (src_pkg_name == "") {
String err;
@@ -1036,8 +1035,9 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
String pack_path = dest_dir + binary_name + ".pck";
Vector<SharedObject> libraries;
Error err = save_pack(p_preset, pack_path, &libraries);
- if (err)
+ if (err) {
return err;
+ }
if (ep.step("Extracting and configuring Xcode project", 1)) {
return ERR_SKIP;
@@ -1047,12 +1047,13 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
print_line("Static library: " + library_to_use);
String pkg_name;
- if (p_preset->get("application/name") != "")
+ if (p_preset->get("application/name") != "") {
pkg_name = p_preset->get("application/name"); // app_name
- else if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "")
+ } else if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") {
pkg_name = String(ProjectSettings::get_singleton()->get("application/config/name"));
- else
+ } else {
pkg_name = "Unnamed";
+ }
bool found_library = false;
int total_size = 0;
@@ -1231,16 +1232,19 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
err = tmp_app_path->make_dir_recursive(iconset_dir);
}
memdelete(tmp_app_path);
- if (err)
+ if (err) {
return err;
+ }
err = _export_icons(p_preset, iconset_dir);
- if (err)
+ if (err) {
return err;
+ }
err = _export_loading_screens(p_preset, dest_dir + binary_name + "/Images.xcassets/LaunchImage.launchimage/");
- if (err)
+ if (err) {
return err;
+ }
print_line("Exporting additional assets");
Vector<IOSExportAsset> assets;
@@ -1310,7 +1314,6 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
}
bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
-
String err;
bool valid = false;
@@ -1368,14 +1371,14 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset
err += etc_error;
}
- if (!err.empty())
+ if (!err.empty()) {
r_error = err;
+ }
return valid;
}
EditorExportPlatformIOS::EditorExportPlatformIOS() {
-
Ref<Image> img = memnew(Image(_iphone_logo));
logo.instance();
logo->create_from_image(img);
@@ -1385,7 +1388,6 @@ EditorExportPlatformIOS::~EditorExportPlatformIOS() {
}
void register_iphone_exporter() {
-
Ref<EditorExportPlatformIOS> platform;
platform.instance();
diff --git a/platform/iphone/game_center.h b/platform/iphone/game_center.h
index d35cc4b87c..0d3ef5b696 100644
--- a/platform/iphone/game_center.h
+++ b/platform/iphone/game_center.h
@@ -36,7 +36,6 @@
#include "core/object.h"
class GameCenter : public Object {
-
GDCLASS(GameCenter, Object);
static GameCenter *instance;
diff --git a/platform/iphone/game_center.mm b/platform/iphone/game_center.mm
index 99d539d4ff..8d470da1a8 100644
--- a/platform/iphone/game_center.mm
+++ b/platform/iphone/game_center.mm
@@ -75,7 +75,6 @@ void GameCenter::return_connect_error(const char *p_error_description) {
}
void GameCenter::connect() {
-
//if this class isn't available, game center isn't implemented
if ((NSClassFromString(@"GKLocalPlayer")) == nil) {
return_connect_error("GameCenter not available");
@@ -125,7 +124,6 @@ bool GameCenter::is_authenticated() {
};
Error GameCenter::post_score(Variant p_score) {
-
Dictionary params = p_score;
ERR_FAIL_COND_V(!params.has("score") || !params.has("category"), ERR_INVALID_PARAMETER);
float score = params["score"];
@@ -156,7 +154,6 @@ Error GameCenter::post_score(Variant p_score) {
};
Error GameCenter::award_achievement(Variant p_params) {
-
Dictionary params = p_params;
ERR_FAIL_COND_V(!params.has("name") || !params.has("progress"), ERR_INVALID_PARAMETER);
String name = params["name"];
@@ -192,7 +189,6 @@ Error GameCenter::award_achievement(Variant p_params) {
};
void GameCenter::request_achievement_descriptions() {
-
[GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:^(NSArray *descriptions, NSError *error) {
Dictionary ret;
ret["type"] = "achievement_descriptions";
@@ -207,7 +203,6 @@ void GameCenter::request_achievement_descriptions() {
Array replayable;
for (int i = 0; i < [descriptions count]; i++) {
-
GKAchievementDescription *description = [descriptions objectAtIndex:i];
const char *str = [description.identifier UTF8String];
@@ -247,7 +242,6 @@ void GameCenter::request_achievement_descriptions() {
};
void GameCenter::request_achievements() {
-
[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) {
Dictionary ret;
ret["type"] = "achievements";
@@ -257,7 +251,6 @@ void GameCenter::request_achievements() {
PackedFloat32Array percentages;
for (int i = 0; i < [achievements count]; i++) {
-
GKAchievement *achievement = [achievements objectAtIndex:i];
const char *str = [achievement.identifier UTF8String];
names.push_back(String::utf8(str != NULL ? str : ""));
@@ -278,7 +271,6 @@ void GameCenter::request_achievements() {
};
void GameCenter::reset_achievements() {
-
[GKAchievement resetAchievementsWithCompletionHandler:^(NSError *error) {
Dictionary ret;
ret["type"] = "reset_achievements";
@@ -294,7 +286,6 @@ void GameCenter::reset_achievements() {
};
Error GameCenter::show_game_center(Variant p_params) {
-
ERR_FAIL_COND_V(!NSProtocolFromString(@"GKGameCenterControllerDelegate"), FAILED);
Dictionary params = p_params;
@@ -338,7 +329,6 @@ Error GameCenter::show_game_center(Variant p_params) {
};
Error GameCenter::request_identity_verification_signature() {
-
ERR_FAIL_COND_V(!is_authenticated(), ERR_UNAUTHORIZED);
GKLocalPlayer *player = [GKLocalPlayer localPlayer];
@@ -365,7 +355,6 @@ Error GameCenter::request_identity_verification_signature() {
};
void GameCenter::game_center_closed() {
-
Dictionary ret;
ret["type"] = "show_game_center";
ret["result"] = "ok";
@@ -373,12 +362,10 @@ void GameCenter::game_center_closed() {
}
int GameCenter::get_pending_event_count() {
-
return pending_events.size();
};
Variant GameCenter::pop_pending_event() {
-
Variant front = pending_events.front()->get();
pending_events.pop_front();
@@ -395,6 +382,6 @@ GameCenter::GameCenter() {
authenticated = false;
};
-GameCenter::~GameCenter(){};
+GameCenter::~GameCenter() {}
#endif
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index ede60a502d..1169ebc6b4 100644
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -174,7 +174,6 @@ void _focus_out_video() {
};
void _unpause_video() {
-
[_instance.avPlayer play];
video_playing = true;
};
@@ -207,14 +206,12 @@ static const int max_touches = 8;
static UITouch *touches[max_touches];
static void init_touches() {
-
for (int i = 0; i < max_touches; i++) {
touches[i] = NULL;
};
};
static int get_touch_id(UITouch *p_touch) {
-
int first = -1;
for (int i = 0; i < max_touches; i++) {
if (first == -1 && touches[i] == NULL) {
@@ -234,10 +231,8 @@ static int get_touch_id(UITouch *p_touch) {
};
static int remove_touch(UITouch *p_touch) {
-
int remaining = 0;
for (int i = 0; i < max_touches; i++) {
-
if (touches[i] == NULL)
continue;
if (touches[i] == p_touch)
@@ -249,9 +244,7 @@ static int remove_touch(UITouch *p_touch) {
};
static void clear_touches() {
-
for (int i = 0; i < max_touches; i++) {
-
touches[i] = NULL;
};
};
@@ -396,7 +389,6 @@ static void clear_touches() {
active = TRUE;
printf("start animation!\n");
if (useCADisplayLink) {
-
// Approximate frame rate
// assumes device refreshes at 60 fps
int frameInterval = (int)floor(animationInterval * 60.0f);
@@ -446,7 +438,6 @@ static void clear_touches() {
// Updates the OpenGL view when the timer fires
- (void)drawView {
-
if (!active) {
printf("draw view not active!\n");
return;
@@ -489,9 +480,7 @@ static void clear_touches() {
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSArray *tlist = [[event allTouches] allObjects];
for (unsigned int i = 0; i < [tlist count]; i++) {
-
if ([touches containsObject:[tlist objectAtIndex:i]]) {
-
UITouch *touch = [tlist objectAtIndex:i];
if (touch.phase != UITouchPhaseBegan)
continue;
@@ -504,12 +493,9 @@ static void clear_touches() {
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
-
NSArray *tlist = [[event allTouches] allObjects];
for (unsigned int i = 0; i < [tlist count]; i++) {
-
if ([touches containsObject:[tlist objectAtIndex:i]]) {
-
UITouch *touch = [tlist objectAtIndex:i];
if (touch.phase != UITouchPhaseMoved)
continue;
@@ -525,9 +511,7 @@ static void clear_touches() {
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSArray *tlist = [[event allTouches] allObjects];
for (unsigned int i = 0; i < [tlist count]; i++) {
-
if ([touches containsObject:[tlist objectAtIndex:i]]) {
-
UITouch *touch = [tlist objectAtIndex:i];
if (touch.phase != UITouchPhaseEnded)
continue;
@@ -541,7 +525,6 @@ static void clear_touches() {
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
-
OSIPhone::get_singleton()->touches_cancelled();
clear_touches();
};
@@ -599,7 +582,6 @@ static void clear_touches() {
NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
switch (routeChangeReason) {
-
case AVAudioSessionRouteChangeReasonNewDeviceAvailable: {
NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable");
NSLog(@"Headphone/Line plugged in");
@@ -609,7 +591,6 @@ static void clear_touches() {
NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable");
NSLog(@"Headphone/Line was pulled. Resuming video play....");
if (_is_video_playing()) {
-
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
[_instance.avPlayer play]; // NOTE: change this line according your current player implementation
NSLog(@"resumed play");
@@ -685,7 +666,6 @@ static void clear_touches() {
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
-
if (object == _instance.avPlayerItem && [keyPath isEqualToString:@"status"]) {
if (_instance.avPlayerItem.status == AVPlayerStatusFailed || _instance.avPlayer.status == AVPlayerStatusFailed) {
_stop_video();
@@ -695,7 +675,6 @@ static void clear_touches() {
if (_instance.avPlayer.status == AVPlayerStatusReadyToPlay &&
_instance.avPlayerItem.status == AVPlayerItemStatusReadyToPlay &&
CMTIME_COMPARE_INLINE(video_current_time, ==, kCMTimeZero)) {
-
//NSLog(@"time: %@", video_current_time);
[_instance.avPlayer seekToTime:video_current_time];
diff --git a/platform/iphone/godot_iphone.cpp b/platform/iphone/godot_iphone.cpp
index 3e67362e16..b9d217c9d2 100644
--- a/platform/iphone/godot_iphone.cpp
+++ b/platform/iphone/godot_iphone.cpp
@@ -46,11 +46,11 @@ int add_cmdline(int p_argc, char **p_args);
int iphone_main(int, int, int, char **, String);
int iphone_main(int width, int height, int argc, char **argv, String data_dir) {
-
size_t len = strlen(argv[0]);
while (len--) {
- if (argv[0][len] == '/') break;
+ if (argv[0][len] == '/')
+ break;
}
if (len >= 0) {
@@ -85,7 +85,6 @@ int iphone_main(int width, int height, int argc, char **argv, String data_dir) {
};
void iphone_finish() {
-
printf("iphone_finish\n");
Main::cleanup();
delete os;
diff --git a/platform/iphone/icloud.h b/platform/iphone/icloud.h
index 401a6cbeb8..b11e22fec6 100644
--- a/platform/iphone/icloud.h
+++ b/platform/iphone/icloud.h
@@ -36,7 +36,6 @@
#include "core/object.h"
class ICloud : public Object {
-
GDCLASS(ICloud, Object);
static ICloud *instance;
diff --git a/platform/iphone/icloud.mm b/platform/iphone/icloud.mm
index 251f78f2da..c768274b1f 100644
--- a/platform/iphone/icloud.mm
+++ b/platform/iphone/icloud.mm
@@ -58,12 +58,10 @@ void ICloud::_bind_methods() {
};
int ICloud::get_pending_event_count() {
-
return pending_events.size();
};
Variant ICloud::pop_pending_event() {
-
Variant front = pending_events.front()->get();
pending_events.pop_front();
@@ -284,6 +282,7 @@ Error ICloud::synchronize_key_values() {
return FAILED;
}
}
+
/*
Error ICloud::initial_sync() {
//you sometimes have to write something to the store to get it to download new data. go apple!
@@ -298,6 +297,7 @@ Error ICloud::initial_sync() {
}
return synchronize();
}
+
*/
ICloud::ICloud() {
ERR_FAIL_COND(instance != NULL);
@@ -354,6 +354,6 @@ ICloud::ICloud() {
}];
}
-ICloud::~ICloud(){};
+ICloud::~ICloud() {}
#endif
diff --git a/platform/iphone/in_app_store.h b/platform/iphone/in_app_store.h
index 493877a5a7..44e65e77ed 100644
--- a/platform/iphone/in_app_store.h
+++ b/platform/iphone/in_app_store.h
@@ -36,7 +36,6 @@
#include "core/object.h"
class InAppStore : public Object {
-
GDCLASS(InAppStore, Object);
static InAppStore *instance;
diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm
index a8a887824f..a2efd6691b 100644
--- a/platform/iphone/in_app_store.mm
+++ b/platform/iphone/in_app_store.mm
@@ -57,6 +57,7 @@ NSMutableDictionary *pending_transactions = [NSMutableDictionary dictionary];
[numberFormatter release];
return formattedString;
}
+
@end
InAppStore *InAppStore::instance = NULL;
@@ -80,7 +81,6 @@ void InAppStore::_bind_methods() {
@implementation ProductsDelegate
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
-
NSArray *products = response.products;
Dictionary ret;
ret["type"] = "product_info";
@@ -93,7 +93,6 @@ void InAppStore::_bind_methods() {
PackedStringArray currency_codes;
for (NSUInteger i = 0; i < [products count]; i++) {
-
SKProduct *product = [products objectAtIndex:i];
const char *str = [product.localizedTitle UTF8String];
@@ -116,7 +115,6 @@ void InAppStore::_bind_methods() {
PackedStringArray invalid_ids;
for (NSString *ipid in response.invalidProductIdentifiers) {
-
invalid_ids.push_back(String::utf8([ipid UTF8String]));
};
ret["invalid_ids"] = invalid_ids;
@@ -129,7 +127,6 @@ void InAppStore::_bind_methods() {
@end
Error InAppStore::request_product_info(Variant p_params) {
-
Dictionary params = p_params;
ERR_FAIL_COND_V(!params.has("product_ids"), ERR_INVALID_PARAMETER);
@@ -155,7 +152,6 @@ Error InAppStore::request_product_info(Variant p_params) {
};
Error InAppStore::restore_purchases() {
-
printf("restoring purchases!\n");
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
@@ -169,10 +165,8 @@ Error InAppStore::restore_purchases() {
@implementation TransObserver
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
-
printf("transactions updated!\n");
for (SKPaymentTransaction *transaction in transactions) {
-
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased: {
printf("status purchased!\n");
@@ -189,11 +183,9 @@ Error InAppStore::restore_purchases() {
int sdk_version = 6;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
-
NSURL *receiptFileURL = nil;
NSBundle *bundle = [NSBundle mainBundle];
if ([bundle respondsToSelector:@selector(appStoreReceiptURL)]) {
-
// Get the transaction receipt file path location in the app bundle.
receiptFileURL = [bundle appStoreReceiptURL];
@@ -263,7 +255,6 @@ Error InAppStore::restore_purchases() {
@end
Error InAppStore::purchase(Variant p_params) {
-
ERR_FAIL_COND_V(![SKPaymentQueue canMakePayments], ERR_UNAVAILABLE);
if (![SKPaymentQueue canMakePayments])
return ERR_UNAVAILABLE;
@@ -286,7 +277,6 @@ int InAppStore::get_pending_event_count() {
};
Variant InAppStore::pop_pending_event() {
-
Variant front = pending_events.front()->get();
pending_events.pop_front();
@@ -294,12 +284,10 @@ Variant InAppStore::pop_pending_event() {
};
void InAppStore::_post_event(Variant p_event) {
-
pending_events.push_back(p_event);
};
void InAppStore::_record_purchase(String product_id) {
-
String skey = "purchased/" + product_id;
NSString *key = [[[NSString alloc] initWithUTF8String:skey.utf8().get_data()] autorelease];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:key];
@@ -307,7 +295,6 @@ void InAppStore::_record_purchase(String product_id) {
};
InAppStore *InAppStore::get_singleton() {
-
return instance;
};
@@ -334,6 +321,6 @@ void InAppStore::set_auto_finish_transaction(bool b) {
auto_finish_transactions = b;
}
-InAppStore::~InAppStore(){};
+InAppStore::~InAppStore() {}
#endif
diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h
index 1378fdbbc5..2b29e6f268 100644
--- a/platform/iphone/ios.h
+++ b/platform/iphone/ios.h
@@ -34,7 +34,6 @@
#include "core/object.h"
class iOS : public Object {
-
GDCLASS(iOS, Object);
static void _bind_methods();
diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm
index 2656f125b9..5923f558a5 100644
--- a/platform/iphone/ios.mm
+++ b/platform/iphone/ios.mm
@@ -34,7 +34,6 @@
#import <UIKit/UIKit.h>
void iOS::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_rate_url", "app_id"), &iOS::get_rate_url);
};
@@ -81,4 +80,4 @@ String iOS::get_rate_url(int p_app_id) const {
return ret;
};
-iOS::iOS(){};
+iOS::iOS() {}
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index 3ef521a61a..41dd623e69 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -58,12 +58,10 @@
#include <dlfcn.h>
int OSIPhone::get_video_driver_count() const {
-
return 2;
};
const char *OSIPhone::get_video_driver_name(int p_driver) const {
-
switch (p_driver) {
case VIDEO_DRIVER_GLES2:
return "GLES2";
@@ -72,14 +70,12 @@ const char *OSIPhone::get_video_driver_name(int p_driver) const {
};
OSIPhone *OSIPhone::get_singleton() {
-
return (OSIPhone *)OS::get_singleton();
};
extern int gl_view_base_fb; // from gl_view.mm
void OSIPhone::set_data_dir(String p_dir) {
-
DirAccess *da = DirAccess::open(p_dir);
data_dir = da->get_current_dir();
@@ -88,17 +84,14 @@ void OSIPhone::set_data_dir(String p_dir) {
};
void OSIPhone::set_unique_id(String p_id) {
-
unique_id = p_id;
};
String OSIPhone::get_unique_id() const {
-
return unique_id;
};
void OSIPhone::initialize_core() {
-
OS_Unix::initialize_core();
set_data_dir(data_dir);
@@ -174,12 +167,10 @@ Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p
};
MainLoop *OSIPhone::get_main_loop() const {
-
return main_loop;
};
void OSIPhone::set_main_loop(MainLoop *p_main_loop) {
-
main_loop = p_main_loop;
if (main_loop) {
@@ -189,13 +180,11 @@ void OSIPhone::set_main_loop(MainLoop *p_main_loop) {
};
bool OSIPhone::iterate() {
-
if (!main_loop)
return true;
if (main_loop) {
for (int i = 0; i < event_count; i++) {
-
input->parse_input_event(event_queue[i]);
};
};
@@ -205,7 +194,6 @@ bool OSIPhone::iterate() {
};
void OSIPhone::key(uint32_t p_key, bool p_pressed) {
-
Ref<InputEventKey> ev;
ev.instance();
ev->set_echo(false);
@@ -217,7 +205,6 @@ void OSIPhone::key(uint32_t p_key, bool p_pressed) {
};
void OSIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick) {
-
if (!GLOBAL_DEF("debug/disable_touch", false)) {
Ref<InputEventScreenTouch> ev;
ev.instance();
@@ -232,9 +219,7 @@ void OSIPhone::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_d
};
void OSIPhone::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y) {
-
if (!GLOBAL_DEF("debug/disable_touch", false)) {
-
Ref<InputEventScreenDrag> ev;
ev.instance();
ev->set_index(p_idx);
@@ -245,18 +230,14 @@ void OSIPhone::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_
};
void OSIPhone::queue_event(const Ref<InputEvent> &p_event) {
-
ERR_FAIL_INDEX(event_count, MAX_EVENTS);
event_queue[event_count++] = p_event;
};
void OSIPhone::touches_cancelled() {
-
for (int i = 0; i < MAX_MOUSE_COUNT; i++) {
-
if (touch_list.pressed[i]) {
-
// send a mouse_up outside the screen
touch_press(i, -1, -1, false, false);
};
@@ -270,7 +251,6 @@ void OSIPhone::update_gravity(float p_x, float p_y, float p_z) {
};
void OSIPhone::update_accelerometer(float p_x, float p_y, float p_z) {
-
// Found out the Z should not be negated! Pass as is!
input->set_accelerometer(Vector3(p_x / (float)ACCEL_RANGE, p_y / (float)ACCEL_RANGE, p_z / (float)ACCEL_RANGE));
@@ -333,7 +313,6 @@ void OSIPhone::joy_axis(int p_device, int p_axis, const InputDefault::JoyAxis &p
};
void OSIPhone::delete_main_loop() {
-
if (main_loop) {
main_loop->finish();
memdelete(main_loop);
@@ -343,7 +322,6 @@ void OSIPhone::delete_main_loop() {
};
void OSIPhone::finalize() {
-
delete_main_loop();
memdelete(input);
@@ -372,28 +350,24 @@ void OSIPhone::finalize() {
event_count = 0;
};
-void OSIPhone::set_mouse_show(bool p_show){};
-void OSIPhone::set_mouse_grab(bool p_grab){};
+void OSIPhone::set_mouse_show(bool p_show) {}
+void OSIPhone::set_mouse_grab(bool p_grab) {}
bool OSIPhone::is_mouse_grab_enabled() const {
-
return true;
};
Point2 OSIPhone::get_mouse_position() const {
-
return Point2();
};
int OSIPhone::get_mouse_button_state() const {
-
return 0;
};
-void OSIPhone::set_window_title(const String &p_title){};
+void OSIPhone::set_window_title(const String &p_title) {}
void OSIPhone::alert(const String &p_alert, const String &p_title) {
-
const CharString utf8_alert = p_alert.utf8();
const CharString utf8_title = p_title.utf8();
iOS::alert(utf8_alert.get_data(), utf8_title.get_data());
@@ -431,22 +405,18 @@ Error OSIPhone::get_dynamic_library_symbol_handle(void *p_library_handle, const
}
void OSIPhone::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
-
video_mode = p_video_mode;
};
OS::VideoMode OSIPhone::get_video_mode(int p_screen) const {
-
return video_mode;
};
void OSIPhone::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
-
p_list->push_back(video_mode);
};
bool OSIPhone::can_draw() const {
-
if (native_video_is_playing())
return false;
return true;
@@ -471,7 +441,7 @@ extern Error _shell_open(String p_uri);
extern void _set_keep_screen_on(bool p_enabled);
extern void _vibrate();
-void OSIPhone::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) {
+void OSIPhone::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
_show_keyboard(p_existing_text);
};
@@ -497,17 +467,14 @@ void OSIPhone::set_keep_screen_on(bool p_enabled) {
};
String OSIPhone::get_user_data_dir() const {
-
return data_dir;
};
String OSIPhone::get_name() const {
-
return "iOS";
};
String OSIPhone::get_model_name() const {
-
String model = ios->get_model();
if (model != "")
return model;
@@ -516,7 +483,6 @@ String OSIPhone::get_model_name() const {
}
Size2 OSIPhone::get_window_size() const {
-
return Vector2(video_mode.width, video_mode.height);
}
@@ -527,7 +493,6 @@ Rect2 OSIPhone::get_window_safe_area() const {
}
bool OSIPhone::has_touchscreen_ui_hint() const {
-
return true;
}
@@ -600,7 +565,6 @@ void OSIPhone::vibrate_handheld(int p_duration_ms) {
}
bool OSIPhone::_check_internal_feature_support(const String &p_feature) {
-
return p_feature == "mobile";
}
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 96cf041c37..955eb15d57 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -33,7 +33,7 @@
#ifndef OS_IPHONE_H
#define OS_IPHONE_H
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "drivers/coreaudio/audio_driver_coreaudio.h"
#include "drivers/unix/os_unix.h"
#include "game_center.h"
@@ -50,7 +50,6 @@
#endif
class OSIPhone : public OS_Unix {
-
private:
enum {
MAX_MOUSE_COUNT = 8,
@@ -99,7 +98,6 @@ private:
virtual void finalize();
struct MouseList {
-
bool pressed[MAX_MOUSE_COUNT];
MouseList() {
for (int i = 0; i < MAX_MOUSE_COUNT; i++)
@@ -172,7 +170,7 @@ public:
virtual bool can_draw() const;
virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1);
+ virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
virtual void hide_virtual_keyboard();
virtual int get_virtual_keyboard_height() const;
diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm
index 465e38e45e..279bcc1226 100644
--- a/platform/iphone/view_controller.mm
+++ b/platform/iphone/view_controller.mm
@@ -40,7 +40,6 @@ int add_path(int, char **);
int add_cmdline(int, char **);
int add_path(int p_argc, char **p_args) {
-
NSString *str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"];
if (!str)
return p_argc;
@@ -54,13 +53,11 @@ int add_path(int p_argc, char **p_args) {
};
int add_cmdline(int p_argc, char **p_args) {
-
NSArray *arr = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_cmdline"];
if (!arr)
return p_argc;
for (int i = 0; i < [arr count]; i++) {
-
NSString *str = [arr objectAtIndex:i];
if (!str)
continue;
@@ -81,7 +78,6 @@ int add_cmdline(int p_argc, char **p_args) {
@implementation ViewController
- (void)didReceiveMemoryWarning {
-
printf("*********** did receive memory warning!\n");
};
diff --git a/platform/iphone/vulkan_context_iphone.h b/platform/iphone/vulkan_context_iphone.h
index 625e41f4b9..cadd701636 100644
--- a/platform/iphone/vulkan_context_iphone.h
+++ b/platform/iphone/vulkan_context_iphone.h
@@ -35,7 +35,6 @@
// #import <UIKit/UIKit.h>
class VulkanContextIPhone : public VulkanContext {
-
virtual const char *_get_platform_surface_extension() const;
public:
diff --git a/platform/iphone/vulkan_context_iphone.mm b/platform/iphone/vulkan_context_iphone.mm
index 701ac0d9bb..44c940dc3a 100644
--- a/platform/iphone/vulkan_context_iphone.mm
+++ b/platform/iphone/vulkan_context_iphone.mm
@@ -36,7 +36,6 @@ const char *VulkanContextIPhone::_get_platform_surface_extension() const {
}
int VulkanContextIPhone::window_create(void *p_window, int p_width, int p_height) {
-
VkIOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = NULL;
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index 7239648937..dcf9a46bf9 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -4,6 +4,7 @@ Import("env")
javascript_files = [
"audio_driver_javascript.cpp",
+ "display_server_javascript.cpp",
"http_client_javascript.cpp",
"javascript_eval.cpp",
"javascript_main.cpp",
@@ -17,22 +18,22 @@ if env["threads_enabled"]:
build = env.add_program(build_targets, javascript_files)
js_libraries = [
- "http_request.js",
+ "native/http_request.js",
]
for lib in js_libraries:
env.Append(LINKFLAGS=["--js-library", env.File(lib).path])
env.Depends(build, js_libraries)
-js_modules = [
- "id_handler.js",
+js_pre = [
+ "native/id_handler.js",
+ "native/utils.js",
]
-for module in js_modules:
- env.Append(LINKFLAGS=["--pre-js", env.File(module).path])
-env.Depends(build, js_modules)
+for js in js_pre:
+ env.Append(LINKFLAGS=["--pre-js", env.File(js).path])
+env.Depends(build, js_pre)
engine = [
"engine/preloader.js",
- "engine/loader.js",
"engine/utils.js",
"engine/engine.js",
]
@@ -47,11 +48,17 @@ wrap_list = [
js_wrapped = env.Textfile("#bin/godot", [env.File(f) for f in wrap_list], TEXTFILESUFFIX="${PROGSUFFIX}.wrapped.js")
zip_dir = env.Dir("#bin/.javascript_zip")
-out_files = [zip_dir.File("godot.js"), zip_dir.File("godot.wasm"), zip_dir.File("godot.html")]
-in_files = [js_wrapped, build[1], "#misc/dist/html/full-size.html"]
+binary_name = "godot.tools" if env["tools"] else "godot"
+out_files = [
+ zip_dir.File(binary_name + ".js"),
+ zip_dir.File(binary_name + ".wasm"),
+ zip_dir.File(binary_name + ".html"),
+]
+html_file = "#misc/dist/html/full-size.html"
+in_files = [js_wrapped, build[1], html_file]
if env["threads_enabled"]:
in_files.append(build[2])
- out_files.append(zip_dir.File("godot.worker.js"))
+ out_files.append(zip_dir.File(binary_name + ".worker.js"))
zip_files = env.InstallAs(out_files, in_files)
env.Zip(
diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp
index 45cb82b351..9c73e5c4c4 100644
--- a/platform/javascript/api/api.cpp
+++ b/platform/javascript/api/api.cpp
@@ -35,26 +35,22 @@
static JavaScript *javascript_eval;
void register_javascript_api() {
-
ClassDB::register_virtual_class<JavaScript>();
javascript_eval = memnew(JavaScript);
Engine::get_singleton()->add_singleton(Engine::Singleton("JavaScript", javascript_eval));
}
void unregister_javascript_api() {
-
memdelete(javascript_eval);
}
JavaScript *JavaScript::singleton = nullptr;
JavaScript *JavaScript::get_singleton() {
-
return singleton;
}
JavaScript::JavaScript() {
-
ERR_FAIL_COND_MSG(singleton != nullptr, "JavaScript singleton already exist.");
singleton = this;
}
@@ -62,13 +58,11 @@ JavaScript::JavaScript() {
JavaScript::~JavaScript() {}
void JavaScript::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("eval", "code", "use_global_execution_context"), &JavaScript::eval, DEFVAL(false));
}
#if !defined(JAVASCRIPT_ENABLED) || !defined(JAVASCRIPT_EVAL_ENABLED)
Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
-
return Variant();
}
#endif
diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp
index 8f857478e5..b52bd4ce60 100644
--- a/platform/javascript/audio_driver_javascript.cpp
+++ b/platform/javascript/audio_driver_javascript.cpp
@@ -30,27 +30,25 @@
#include "audio_driver_javascript.h"
+#include "core/project_settings.h"
+
#include <emscripten.h>
AudioDriverJavaScript *AudioDriverJavaScript::singleton = nullptr;
const char *AudioDriverJavaScript::get_name() const {
-
return "JavaScript";
}
extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_js_mix() {
-
AudioDriverJavaScript::singleton->mix_to_js();
}
extern "C" EMSCRIPTEN_KEEPALIVE void audio_driver_process_capture(float sample) {
-
AudioDriverJavaScript::singleton->process_capture(sample);
}
void AudioDriverJavaScript::mix_to_js() {
-
int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode());
int sample_count = memarr_len(internal_buffer) / channel_count;
int32_t *stream_buffer = reinterpret_cast<int32_t *>(internal_buffer);
@@ -61,17 +59,20 @@ void AudioDriverJavaScript::mix_to_js() {
}
void AudioDriverJavaScript::process_capture(float sample) {
-
int32_t sample32 = int32_t(sample * 32768.f) * (1U << 16);
input_buffer_write(sample32);
}
Error AudioDriverJavaScript::init() {
+ int mix_rate = GLOBAL_GET("audio/mix_rate");
+ int latency = GLOBAL_GET("audio/output_latency");
/* clang-format off */
_driver_id = EM_ASM_INT({
+ const MIX_RATE = $0;
+ const LATENCY = $1;
return Module.IDHandler.add({
- 'context': new (window.AudioContext || window.webkitAudioContext),
+ 'context': new (window.AudioContext || window.webkitAudioContext)({ sampleRate: MIX_RATE, latencyHint: LATENCY}),
'input': null,
'stream': null,
'script': null
@@ -80,26 +81,19 @@ Error AudioDriverJavaScript::init() {
/* clang-format on */
int channel_count = get_total_channels_by_speaker_mode(get_speaker_mode());
+ buffer_length = closest_power_of_2((latency * mix_rate / 1000) * channel_count);
/* clang-format off */
buffer_length = EM_ASM_INT({
var ref = Module.IDHandler.get($0);
- var ctx = ref['context'];
- var CHANNEL_COUNT = $1;
-
- var channelCount = ctx.destination.channelCount;
- var script = null;
- try {
- // Try letting the browser recommend a buffer length.
- script = ctx.createScriptProcessor(0, 2, channelCount);
- } catch (e) {
- // ...otherwise, default to 4096.
- script = ctx.createScriptProcessor(4096, 2, channelCount);
- }
+ const ctx = ref['context'];
+ const BUFFER_LENGTH = $1;
+ const CHANNEL_COUNT = $2;
+
+ var script = ctx.createScriptProcessor(BUFFER_LENGTH, 2, CHANNEL_COUNT);
script.connect(ctx.destination);
ref['script'] = script;
-
return script.bufferSize;
- }, _driver_id, channel_count);
+ }, _driver_id, buffer_length, channel_count);
/* clang-format on */
if (!buffer_length) {
return FAILED;
@@ -115,7 +109,6 @@ Error AudioDriverJavaScript::init() {
}
void AudioDriverJavaScript::start() {
-
/* clang-format off */
EM_ASM({
const ref = Module.IDHandler.get($0);
@@ -163,8 +156,26 @@ void AudioDriverJavaScript::resume() {
/* clang-format on */
}
-int AudioDriverJavaScript::get_mix_rate() const {
+float AudioDriverJavaScript::get_latency() {
+ /* clang-format off */
+ return EM_ASM_DOUBLE({
+ const ref = Module.IDHandler.get($0);
+ var latency = 0;
+ if (ref && ref['context']) {
+ const ctx = ref['context'];
+ if (ctx.baseLatency) {
+ latency += ctx.baseLatency;
+ }
+ if (ctx.outputLatency) {
+ latency += ctx.outputLatency;
+ }
+ }
+ return latency;
+ }, _driver_id);
+ /* clang-format on */
+}
+int AudioDriverJavaScript::get_mix_rate() const {
/* clang-format off */
return EM_ASM_INT({
const ref = Module.IDHandler.get($0);
@@ -174,7 +185,6 @@ int AudioDriverJavaScript::get_mix_rate() const {
}
AudioDriver::SpeakerMode AudioDriverJavaScript::get_speaker_mode() const {
-
/* clang-format off */
return get_speaker_mode_by_total_channels(EM_ASM_INT({
const ref = Module.IDHandler.get($0);
@@ -190,23 +200,45 @@ void AudioDriverJavaScript::lock() {
void AudioDriverJavaScript::unlock() {
}
-void AudioDriverJavaScript::finish() {
+void AudioDriverJavaScript::finish_async() {
+ // Close the context, add the operation to the async_finish list in module.
+ int id = _driver_id;
+ _driver_id = 0;
/* clang-format off */
EM_ASM({
+ var ref = Module.IDHandler.get($0);
+ Module.async_finish.push(new Promise(function(accept, reject) {
+ if (!ref) {
+ console.log("Ref not found!", $0, Module.IDHandler);
+ setTimeout(accept, 0);
+ } else {
+ const context = ref['context'];
+ // Disconnect script and input.
+ ref['script'].disconnect();
+ if (ref['input'])
+ ref['input'].disconnect();
+ ref = null;
+ context.close().then(function() {
+ accept();
+ }).catch(function(e) {
+ accept();
+ });
+ }
+ }));
Module.IDHandler.remove($0);
- }, _driver_id);
+ }, id);
/* clang-format on */
+}
+void AudioDriverJavaScript::finish() {
if (internal_buffer) {
memdelete_arr(internal_buffer);
internal_buffer = nullptr;
}
- _driver_id = 0;
}
Error AudioDriverJavaScript::capture_start() {
-
input_buffer_init(buffer_length);
/* clang-format off */
@@ -236,7 +268,6 @@ Error AudioDriverJavaScript::capture_start() {
}
Error AudioDriverJavaScript::capture_stop() {
-
/* clang-format off */
EM_ASM({
var ref = Module.IDHandler.get($0);
@@ -262,7 +293,6 @@ Error AudioDriverJavaScript::capture_stop() {
}
AudioDriverJavaScript::AudioDriverJavaScript() {
-
_driver_id = 0;
internal_buffer = nullptr;
buffer_length = 0;
diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h
index f6f2dacd4e..9b26be001e 100644
--- a/platform/javascript/audio_driver_javascript.h
+++ b/platform/javascript/audio_driver_javascript.h
@@ -34,7 +34,6 @@
#include "servers/audio_server.h"
class AudioDriverJavaScript : public AudioDriver {
-
float *internal_buffer;
int _driver_id;
@@ -51,11 +50,13 @@ public:
virtual Error init();
virtual void start();
void resume();
+ virtual float get_latency();
virtual int get_mix_rate() const;
virtual SpeakerMode get_speaker_mode() const;
virtual void lock();
virtual void unlock();
virtual void finish();
+ void finish_async();
virtual Error capture_start();
virtual Error capture_stop();
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 9486e10717..81287cead8 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -22,7 +22,7 @@ def get_opts():
# eval() can be a security concern, so it can be disabled.
BoolVariable("javascript_eval", "Enable JavaScript eval interface", True),
BoolVariable("threads_enabled", "Enable WebAssembly Threads support (limited browser support)", False),
- BoolVariable("use_closure_compiler", "Use closure compiler to minimize Javascript code", False),
+ BoolVariable("use_closure_compiler", "Use closure compiler to minimize JavaScript code", False),
]
@@ -57,7 +57,7 @@ def configure(env):
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
# Retain function names for backtraces at the cost of file size.
env.Append(LINKFLAGS=["--profiling-funcs"])
- else: # 'debug'
+ else: # "debug"
env.Append(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(CCFLAGS=["-O1", "-g"])
env.Append(LINKFLAGS=["-O1", "-g"])
@@ -150,7 +150,7 @@ def configure(env):
env.Append(LIBS=["idbfs.js"])
env.Append(LINKFLAGS=["-s", "BINARYEN=1"])
- env.Append(LINKFLAGS=["-s", "MODULARIZE=1", "-s", 'EXPORT_NAME="Godot"'])
+ env.Append(LINKFLAGS=["-s", "MODULARIZE=1", "-s", "EXPORT_NAME='Godot'"])
# Allow increasing memory buffer size during runtime. This is efficient
# when using WebAssembly (in comparison to asm.js) and works well for
@@ -162,5 +162,10 @@ def configure(env):
env.Append(LINKFLAGS=["-s", "INVOKE_RUN=0"])
- # callMain for manual start, FS for preloading.
- env.Append(LINKFLAGS=["-s", 'EXTRA_EXPORTED_RUNTIME_METHODS=["callMain", "FS"]'])
+ # Allow use to take control of swapping WebGL buffers.
+ env.Append(LINKFLAGS=["-s", "OFFSCREEN_FRAMEBUFFER=1"])
+
+ # callMain for manual start, FS for preloading, PATH and ERRNO_CODES for BrowserFS.
+ env.Append(LINKFLAGS=["-s", "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain', 'FS', 'PATH']"])
+ # Add code that allow exiting runtime.
+ env.Append(LINKFLAGS=["-s", "EXIT_RUNTIME=1"])
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
new file mode 100644
index 0000000000..b95674efc3
--- /dev/null
+++ b/platform/javascript/display_server_javascript.cpp
@@ -0,0 +1,1193 @@
+/*************************************************************************/
+/* display_server_javascript.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "platform/javascript/display_server_javascript.h"
+
+#include "drivers/dummy/rasterizer_dummy.h"
+#include "platform/javascript/os_javascript.h"
+
+#include <emscripten.h>
+#include <png.h>
+
+#include "dom_keys.inc"
+
+#define DOM_BUTTON_LEFT 0
+#define DOM_BUTTON_MIDDLE 1
+#define DOM_BUTTON_RIGHT 2
+#define DOM_BUTTON_XBUTTON1 3
+#define DOM_BUTTON_XBUTTON2 4
+
+DisplayServerJavaScript *DisplayServerJavaScript::get_singleton() {
+ return static_cast<DisplayServerJavaScript *>(DisplayServer::get_singleton());
+}
+
+// Window (canvas)
+extern "C" EMSCRIPTEN_KEEPALIVE void _set_canvas_id(uint8_t *p_data, int p_data_size) {
+ DisplayServerJavaScript *display = DisplayServerJavaScript::get_singleton();
+ display->canvas_id.parse_utf8((const char *)p_data, p_data_size);
+ display->canvas_id = "#" + display->canvas_id;
+}
+
+static void focus_canvas() {
+ /* clang-format off */
+ EM_ASM(
+ Module['canvas'].focus();
+ );
+ /* clang-format on */
+}
+
+static bool is_canvas_focused() {
+ /* clang-format off */
+ return EM_ASM_INT_V(
+ return document.activeElement == Module['canvas'];
+ );
+ /* clang-format on */
+}
+
+static Point2 compute_position_in_canvas(int x, int y) {
+ DisplayServerJavaScript *display = DisplayServerJavaScript::get_singleton();
+ int canvas_x = EM_ASM_INT({
+ return Module['canvas'].getBoundingClientRect().x;
+ });
+ int canvas_y = EM_ASM_INT({
+ return Module['canvas'].getBoundingClientRect().y;
+ });
+ int canvas_width;
+ int canvas_height;
+ emscripten_get_canvas_element_size(display->canvas_id.utf8().get_data(), &canvas_width, &canvas_height);
+
+ double element_width;
+ double element_height;
+ emscripten_get_element_css_size(display->canvas_id.utf8().get_data(), &element_width, &element_height);
+
+ return Point2((int)(canvas_width / element_width * (x - canvas_x)),
+ (int)(canvas_height / element_height * (y - canvas_y)));
+}
+
+static bool cursor_inside_canvas = true;
+
+EM_BOOL DisplayServerJavaScript::fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data) {
+ DisplayServerJavaScript *display = get_singleton();
+ // Empty ID is canvas.
+ String target_id = String::utf8(p_event->id);
+ if (target_id.empty() || "#" + target_id == display->canvas_id) {
+ // This event property is the only reliable data on
+ // browser fullscreen state.
+ if (p_event->isFullscreen) {
+ display->window_mode = WINDOW_MODE_FULLSCREEN;
+ } else {
+ display->window_mode = WINDOW_MODE_WINDOWED;
+ }
+ }
+ return false;
+}
+
+// Drag and drop callback (see native/utils.js).
+extern "C" EMSCRIPTEN_KEEPALIVE void _drop_files_callback(char *p_filev[], int p_filec) {
+ DisplayServerJavaScript *ds = DisplayServerJavaScript::get_singleton();
+ if (!ds) {
+ ERR_FAIL_MSG("Unable to drop files because the DisplayServer is not active");
+ }
+ if (ds->drop_files_callback.is_null())
+ return;
+ Vector<String> files;
+ for (int i = 0; i < p_filec; i++) {
+ files.push_back(String::utf8(p_filev[i]));
+ }
+ Variant v = files;
+ Variant *vp = &v;
+ Variant ret;
+ Callable::CallError ce;
+ ds->drop_files_callback.call((const Variant **)&vp, 1, ret, ce);
+}
+
+// Keys
+
+template <typename T>
+static void dom2godot_mod(T *emscripten_event_ptr, Ref<InputEventWithModifiers> godot_event) {
+ godot_event->set_shift(emscripten_event_ptr->shiftKey);
+ godot_event->set_alt(emscripten_event_ptr->altKey);
+ godot_event->set_control(emscripten_event_ptr->ctrlKey);
+ godot_event->set_metakey(emscripten_event_ptr->metaKey);
+}
+
+static Ref<InputEventKey> setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) {
+ Ref<InputEventKey> ev;
+ ev.instance();
+ ev->set_echo(emscripten_event->repeat);
+ dom2godot_mod(emscripten_event, ev);
+ ev->set_keycode(dom2godot_keycode(emscripten_event->keyCode));
+ ev->set_physical_keycode(dom2godot_keycode(emscripten_event->keyCode));
+
+ String unicode = String::utf8(emscripten_event->key);
+ // Check if empty or multi-character (e.g. `CapsLock`).
+ if (unicode.length() != 1) {
+ // Might be empty as well, but better than nonsense.
+ unicode = String::utf8(emscripten_event->charValue);
+ }
+ if (unicode.length() == 1) {
+ ev->set_unicode(unicode[0]);
+ }
+
+ return ev;
+}
+
+EM_BOOL DisplayServerJavaScript::keydown_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) {
+ DisplayServerJavaScript *display = get_singleton();
+ Ref<InputEventKey> ev = setup_key_event(p_event);
+ ev->set_pressed(true);
+ if (ev->get_unicode() == 0 && keycode_has_unicode(ev->get_keycode())) {
+ // Defer to keypress event for legacy unicode retrieval.
+ display->deferred_key_event = ev;
+ // Do not suppress keypress event.
+ return false;
+ }
+ Input::get_singleton()->parse_input_event(ev);
+ return true;
+}
+
+EM_BOOL DisplayServerJavaScript::keypress_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) {
+ DisplayServerJavaScript *display = get_singleton();
+ display->deferred_key_event->set_unicode(p_event->charCode);
+ Input::get_singleton()->parse_input_event(display->deferred_key_event);
+ return true;
+}
+
+EM_BOOL DisplayServerJavaScript::keyup_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) {
+ Ref<InputEventKey> ev = setup_key_event(p_event);
+ ev->set_pressed(false);
+ Input::get_singleton()->parse_input_event(ev);
+ return ev->get_keycode() != KEY_UNKNOWN && ev->get_keycode() != 0;
+}
+
+// Mouse
+
+EM_BOOL DisplayServerJavaScript::mouse_button_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data) {
+ DisplayServerJavaScript *display = get_singleton();
+
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_MOUSEDOWN);
+ ev->set_position(compute_position_in_canvas(p_event->clientX, p_event->clientY));
+ ev->set_global_position(ev->get_position());
+ dom2godot_mod(p_event, ev);
+
+ switch (p_event->button) {
+ case DOM_BUTTON_LEFT:
+ ev->set_button_index(BUTTON_LEFT);
+ break;
+ case DOM_BUTTON_MIDDLE:
+ ev->set_button_index(BUTTON_MIDDLE);
+ break;
+ case DOM_BUTTON_RIGHT:
+ ev->set_button_index(BUTTON_RIGHT);
+ break;
+ case DOM_BUTTON_XBUTTON1:
+ ev->set_button_index(BUTTON_XBUTTON1);
+ break;
+ case DOM_BUTTON_XBUTTON2:
+ ev->set_button_index(BUTTON_XBUTTON2);
+ break;
+ default:
+ return false;
+ }
+
+ if (ev->is_pressed()) {
+ double diff = emscripten_get_now() - display->last_click_ms;
+
+ if (ev->get_button_index() == display->last_click_button_index) {
+ if (diff < 400 && Point2(display->last_click_pos).distance_to(ev->get_position()) < 5) {
+ display->last_click_ms = 0;
+ display->last_click_pos = Point2(-100, -100);
+ display->last_click_button_index = -1;
+ ev->set_doubleclick(true);
+ }
+
+ } else {
+ display->last_click_button_index = ev->get_button_index();
+ }
+
+ if (!ev->is_doubleclick()) {
+ display->last_click_ms += diff;
+ display->last_click_pos = ev->get_position();
+ }
+ }
+
+ Input *input = Input::get_singleton();
+ int mask = input->get_mouse_button_mask();
+ int button_flag = 1 << (ev->get_button_index() - 1);
+ if (ev->is_pressed()) {
+ // Since the event is consumed, focus manually. The containing iframe,
+ // if exists, may not have focus yet, so focus even if already focused.
+ focus_canvas();
+ mask |= button_flag;
+ } else if (mask & button_flag) {
+ mask &= ~button_flag;
+ } else {
+ // Received release event, but press was outside the canvas, so ignore.
+ return false;
+ }
+ ev->set_button_mask(mask);
+
+ input->parse_input_event(ev);
+ // Prevent multi-click text selection and wheel-click scrolling anchor.
+ // Context menu is prevented through contextmenu event.
+ return true;
+}
+
+EM_BOOL DisplayServerJavaScript::mousemove_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data) {
+ Input *input = Input::get_singleton();
+ int input_mask = input->get_mouse_button_mask();
+ Point2 pos = compute_position_in_canvas(p_event->clientX, p_event->clientY);
+ // For motion outside the canvas, only read mouse movement if dragging
+ // started inside the canvas; imitating desktop app behaviour.
+ if (!cursor_inside_canvas && !input_mask)
+ return false;
+
+ Ref<InputEventMouseMotion> ev;
+ ev.instance();
+ dom2godot_mod(p_event, ev);
+ ev->set_button_mask(input_mask);
+
+ ev->set_position(pos);
+ ev->set_global_position(ev->get_position());
+
+ ev->set_relative(Vector2(p_event->movementX, p_event->movementY));
+ input->set_mouse_position(ev->get_position());
+ ev->set_speed(input->get_last_mouse_speed());
+
+ input->parse_input_event(ev);
+ // Don't suppress mouseover/-leave events.
+ return false;
+}
+
+// Cursor
+static const char *godot2dom_cursor(DisplayServer::CursorShape p_shape) {
+ switch (p_shape) {
+ case DisplayServer::CURSOR_ARROW:
+ return "auto";
+ case DisplayServer::CURSOR_IBEAM:
+ return "text";
+ case DisplayServer::CURSOR_POINTING_HAND:
+ return "pointer";
+ case DisplayServer::CURSOR_CROSS:
+ return "crosshair";
+ case DisplayServer::CURSOR_WAIT:
+ return "progress";
+ case DisplayServer::CURSOR_BUSY:
+ return "wait";
+ case DisplayServer::CURSOR_DRAG:
+ return "grab";
+ case DisplayServer::CURSOR_CAN_DROP:
+ return "grabbing";
+ case DisplayServer::CURSOR_FORBIDDEN:
+ return "no-drop";
+ case DisplayServer::CURSOR_VSIZE:
+ return "ns-resize";
+ case DisplayServer::CURSOR_HSIZE:
+ return "ew-resize";
+ case DisplayServer::CURSOR_BDIAGSIZE:
+ return "nesw-resize";
+ case DisplayServer::CURSOR_FDIAGSIZE:
+ return "nwse-resize";
+ case DisplayServer::CURSOR_MOVE:
+ return "move";
+ case DisplayServer::CURSOR_VSPLIT:
+ return "row-resize";
+ case DisplayServer::CURSOR_HSPLIT:
+ return "col-resize";
+ case DisplayServer::CURSOR_HELP:
+ return "help";
+ default:
+ return "auto";
+ }
+}
+
+static void set_css_cursor(const char *p_cursor) {
+ /* clang-format off */
+ EM_ASM_({
+ Module['canvas'].style.cursor = UTF8ToString($0);
+ }, p_cursor);
+ /* clang-format on */
+}
+
+static bool is_css_cursor_hidden() {
+ /* clang-format off */
+ return EM_ASM_INT({
+ return Module['canvas'].style.cursor === 'none';
+ });
+ /* clang-format on */
+}
+
+void DisplayServerJavaScript::cursor_set_shape(CursorShape p_shape) {
+ ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
+
+ if (mouse_get_mode() == MOUSE_MODE_VISIBLE) {
+ if (cursors[p_shape] != "") {
+ Vector<String> url = cursors[p_shape].split("?");
+ set_css_cursor(("url(\"" + url[0] + "\") " + url[1] + ", auto").utf8());
+ } else {
+ set_css_cursor(godot2dom_cursor(p_shape));
+ }
+ }
+
+ cursor_shape = p_shape;
+}
+
+DisplayServer::CursorShape DisplayServerJavaScript::cursor_get_shape() const {
+ return cursor_shape;
+}
+
+void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+ if (p_cursor.is_valid()) {
+ Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape);
+
+ if (cursor_c) {
+ if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) {
+ cursor_set_shape(p_shape);
+ return;
+ }
+
+ cursors_cache.erase(p_shape);
+ }
+
+ Ref<Texture2D> texture = p_cursor;
+ Ref<AtlasTexture> atlas_texture = p_cursor;
+ Ref<Image> image;
+ Size2 texture_size;
+ Rect2 atlas_rect;
+
+ if (texture.is_valid()) {
+ image = texture->get_data();
+ }
+
+ if (!image.is_valid() && atlas_texture.is_valid()) {
+ texture = atlas_texture->get_atlas();
+
+ atlas_rect.size.width = texture->get_width();
+ atlas_rect.size.height = texture->get_height();
+ atlas_rect.position.x = atlas_texture->get_region().position.x;
+ atlas_rect.position.y = atlas_texture->get_region().position.y;
+
+ texture_size.width = atlas_texture->get_region().size.x;
+ texture_size.height = atlas_texture->get_region().size.y;
+ } else if (image.is_valid()) {
+ texture_size.width = texture->get_width();
+ texture_size.height = texture->get_height();
+ }
+
+ ERR_FAIL_COND(!texture.is_valid());
+ ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0);
+ ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
+ ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
+
+ image = texture->get_data();
+
+ ERR_FAIL_COND(!image.is_valid());
+
+ image = image->duplicate();
+
+ if (atlas_texture.is_valid())
+ image->crop_from_point(
+ atlas_rect.position.x,
+ atlas_rect.position.y,
+ texture_size.width,
+ texture_size.height);
+
+ if (image->get_format() != Image::FORMAT_RGBA8) {
+ image->convert(Image::FORMAT_RGBA8);
+ }
+
+ png_image png_meta;
+ memset(&png_meta, 0, sizeof png_meta);
+ png_meta.version = PNG_IMAGE_VERSION;
+ png_meta.width = texture_size.width;
+ png_meta.height = texture_size.height;
+ png_meta.format = PNG_FORMAT_RGBA;
+
+ PackedByteArray png;
+ size_t len;
+ PackedByteArray data = image->get_data();
+ ERR_FAIL_COND(!png_image_write_get_memory_size(png_meta, len, 0, data.ptr(), 0, nullptr));
+
+ png.resize(len);
+ ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, png.ptrw(), &len, 0, data.ptr(), 0, nullptr));
+
+ char *object_url;
+ /* clang-format off */
+ EM_ASM({
+ var PNG_PTR = $0;
+ var PNG_LEN = $1;
+ var PTR = $2;
+
+ var png = new Blob([HEAPU8.slice(PNG_PTR, PNG_PTR + PNG_LEN)], { type: 'image/png' });
+ var url = URL.createObjectURL(png);
+ var length_bytes = lengthBytesUTF8(url) + 1;
+ var string_on_wasm_heap = _malloc(length_bytes);
+ setValue(PTR, string_on_wasm_heap, '*');
+ stringToUTF8(url, string_on_wasm_heap, length_bytes);
+ }, png.ptr(), len, &object_url);
+ /* clang-format on */
+
+ String url = String::utf8(object_url) + "?" + itos(p_hotspot.x) + " " + itos(p_hotspot.y);
+
+ /* clang-format off */
+ EM_ASM({ _free($0); }, object_url);
+ /* clang-format on */
+
+ if (cursors[p_shape] != "") {
+ /* clang-format off */
+ EM_ASM({
+ URL.revokeObjectURL(UTF8ToString($0).split('?')[0]);
+ }, cursors[p_shape].utf8().get_data());
+ /* clang-format on */
+ cursors[p_shape] = "";
+ }
+
+ cursors[p_shape] = url;
+
+ Vector<Variant> params;
+ params.push_back(p_cursor);
+ params.push_back(p_hotspot);
+ cursors_cache.insert(p_shape, params);
+
+ } else if (cursors[p_shape] != "") {
+ /* clang-format off */
+ EM_ASM({
+ URL.revokeObjectURL(UTF8ToString($0).split('?')[0]);
+ }, cursors[p_shape].utf8().get_data());
+ /* clang-format on */
+ cursors[p_shape] = "";
+
+ cursors_cache.erase(p_shape);
+ }
+
+ cursor_set_shape(cursor_shape);
+}
+
+// Mouse mode
+void DisplayServerJavaScript::mouse_set_mode(MouseMode p_mode) {
+ ERR_FAIL_COND_MSG(p_mode == MOUSE_MODE_CONFINED, "MOUSE_MODE_CONFINED is not supported for the HTML5 platform.");
+ if (p_mode == mouse_get_mode())
+ return;
+
+ if (p_mode == MOUSE_MODE_VISIBLE) {
+ // set_css_cursor must be called before set_cursor_shape to make the cursor visible
+ set_css_cursor(godot2dom_cursor(cursor_shape));
+ cursor_set_shape(cursor_shape);
+ emscripten_exit_pointerlock();
+
+ } else if (p_mode == MOUSE_MODE_HIDDEN) {
+ set_css_cursor("none");
+ emscripten_exit_pointerlock();
+
+ } else if (p_mode == MOUSE_MODE_CAPTURED) {
+ EMSCRIPTEN_RESULT result = emscripten_request_pointerlock("canvas", false);
+ ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback.");
+ ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback.");
+ // set_css_cursor must be called before cursor_set_shape to make the cursor visible
+ set_css_cursor(godot2dom_cursor(cursor_shape));
+ cursor_set_shape(cursor_shape);
+ }
+}
+
+DisplayServer::MouseMode DisplayServerJavaScript::mouse_get_mode() const {
+ if (is_css_cursor_hidden())
+ return MOUSE_MODE_HIDDEN;
+
+ EmscriptenPointerlockChangeEvent ev;
+ emscripten_get_pointerlock_status(&ev);
+ return (ev.isActive && String::utf8(ev.id) == "canvas") ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE;
+}
+
+// Wheel
+
+EM_BOOL DisplayServerJavaScript::wheel_callback(int p_event_type, const EmscriptenWheelEvent *p_event, void *p_user_data) {
+ ERR_FAIL_COND_V(p_event_type != EMSCRIPTEN_EVENT_WHEEL, false);
+ if (!is_canvas_focused()) {
+ if (cursor_inside_canvas) {
+ focus_canvas();
+ } else {
+ return false;
+ }
+ }
+
+ Input *input = Input::get_singleton();
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_position(input->get_mouse_position());
+ ev->set_global_position(ev->get_position());
+
+ ev->set_shift(input->is_key_pressed(KEY_SHIFT));
+ ev->set_alt(input->is_key_pressed(KEY_ALT));
+ ev->set_control(input->is_key_pressed(KEY_CONTROL));
+ ev->set_metakey(input->is_key_pressed(KEY_META));
+
+ if (p_event->deltaY < 0)
+ ev->set_button_index(BUTTON_WHEEL_UP);
+ else if (p_event->deltaY > 0)
+ ev->set_button_index(BUTTON_WHEEL_DOWN);
+ else if (p_event->deltaX > 0)
+ ev->set_button_index(BUTTON_WHEEL_LEFT);
+ else if (p_event->deltaX < 0)
+ ev->set_button_index(BUTTON_WHEEL_RIGHT);
+ else
+ return false;
+
+ // Different browsers give wildly different delta values, and we can't
+ // interpret deltaMode, so use default value for wheel events' factor.
+
+ int button_flag = 1 << (ev->get_button_index() - 1);
+
+ ev->set_pressed(true);
+ ev->set_button_mask(input->get_mouse_button_mask() | button_flag);
+ input->parse_input_event(ev);
+
+ ev->set_pressed(false);
+ ev->set_button_mask(input->get_mouse_button_mask() & ~button_flag);
+ input->parse_input_event(ev);
+
+ return true;
+}
+
+// Touch
+EM_BOOL DisplayServerJavaScript::touch_press_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data) {
+ DisplayServerJavaScript *display = get_singleton();
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ int lowest_id_index = -1;
+ for (int i = 0; i < p_event->numTouches; ++i) {
+ const EmscriptenTouchPoint &touch = p_event->touches[i];
+ if (lowest_id_index == -1 || touch.identifier < p_event->touches[lowest_id_index].identifier)
+ lowest_id_index = i;
+ if (!touch.isChanged)
+ continue;
+ ev->set_index(touch.identifier);
+ ev->set_position(compute_position_in_canvas(touch.clientX, touch.clientY));
+ display->touches[i] = ev->get_position();
+ ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_TOUCHSTART);
+
+ Input::get_singleton()->parse_input_event(ev);
+ }
+ // Resume audio context after input in case autoplay was denied.
+ return true;
+}
+
+EM_BOOL DisplayServerJavaScript::touchmove_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data) {
+ DisplayServerJavaScript *display = get_singleton();
+ Ref<InputEventScreenDrag> ev;
+ ev.instance();
+ int lowest_id_index = -1;
+ for (int i = 0; i < p_event->numTouches; ++i) {
+ const EmscriptenTouchPoint &touch = p_event->touches[i];
+ if (lowest_id_index == -1 || touch.identifier < p_event->touches[lowest_id_index].identifier)
+ lowest_id_index = i;
+ if (!touch.isChanged)
+ continue;
+ ev->set_index(touch.identifier);
+ ev->set_position(compute_position_in_canvas(touch.clientX, touch.clientY));
+ Point2 &prev = display->touches[i];
+ ev->set_relative(ev->get_position() - prev);
+ prev = ev->get_position();
+
+ Input::get_singleton()->parse_input_event(ev);
+ }
+ return true;
+}
+
+bool DisplayServerJavaScript::screen_is_touchscreen(int p_screen) const {
+ return EM_ASM_INT({ return 'ontouchstart' in window; });
+}
+
+// Gamepad
+
+EM_BOOL DisplayServerJavaScript::gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data) {
+ Input *input = Input::get_singleton();
+ if (p_event_type == EMSCRIPTEN_EVENT_GAMEPADCONNECTED) {
+ String guid = "";
+ if (String::utf8(p_event->mapping) == "standard")
+ guid = "Default HTML5 Gamepad";
+ input->joy_connection_changed(p_event->index, true, String::utf8(p_event->id), guid);
+ } else {
+ input->joy_connection_changed(p_event->index, false, "");
+ }
+ return true;
+}
+
+void DisplayServerJavaScript::process_joypads() {
+ int joypad_count = emscripten_get_num_gamepads();
+ Input *input = Input::get_singleton();
+ for (int joypad = 0; joypad < joypad_count; joypad++) {
+ EmscriptenGamepadEvent state;
+ EMSCRIPTEN_RESULT query_result = emscripten_get_gamepad_status(joypad, &state);
+ // Chromium reserves gamepads slots, so NO_DATA is an expected result.
+ ERR_CONTINUE(query_result != EMSCRIPTEN_RESULT_SUCCESS &&
+ query_result != EMSCRIPTEN_RESULT_NO_DATA);
+ if (query_result == EMSCRIPTEN_RESULT_SUCCESS && state.connected) {
+ int button_count = MIN(state.numButtons, 18);
+ int axis_count = MIN(state.numAxes, 8);
+ for (int button = 0; button < button_count; button++) {
+ float value = state.analogButton[button];
+ input->joy_button(joypad, button, value);
+ }
+ for (int axis = 0; axis < axis_count; axis++) {
+ Input::JoyAxis joy_axis;
+ joy_axis.min = -1;
+ joy_axis.value = state.axis[axis];
+ input->joy_axis(joypad, axis, joy_axis);
+ }
+ }
+ }
+}
+
+#if 0
+bool DisplayServerJavaScript::is_joy_known(int p_device) {
+
+ return Input::get_singleton()->is_joy_mapped(p_device);
+}
+
+
+String DisplayServerJavaScript::get_joy_guid(int p_device) const {
+
+ return Input::get_singleton()->get_joy_guid_remapped(p_device);
+}
+#endif
+
+Vector<String> DisplayServerJavaScript::get_rendering_drivers_func() {
+ Vector<String> drivers;
+ drivers.push_back("dummy");
+ return drivers;
+}
+
+// Clipboard
+extern "C" EMSCRIPTEN_KEEPALIVE void update_clipboard(const char *p_text) {
+ // Only call set_clipboard from OS (sets local clipboard)
+ DisplayServerJavaScript::get_singleton()->clipboard = p_text;
+}
+
+void DisplayServerJavaScript::clipboard_set(const String &p_text) {
+ /* clang-format off */
+ int err = EM_ASM_INT({
+ var text = UTF8ToString($0);
+ if (!navigator.clipboard || !navigator.clipboard.writeText)
+ return 1;
+ navigator.clipboard.writeText(text).catch(function(e) {
+ // Setting OS clipboard is only possible from an input callback.
+ console.error("Setting OS clipboard is only possible from an input callback for the HTML5 plafrom. Exception:", e);
+ });
+ return 0;
+ }, p_text.utf8().get_data());
+ /* clang-format on */
+ ERR_FAIL_COND_MSG(err, "Clipboard API is not supported.");
+}
+
+String DisplayServerJavaScript::clipboard_get() const {
+ /* clang-format off */
+ EM_ASM({
+ try {
+ navigator.clipboard.readText().then(function (result) {
+ ccall('update_clipboard', 'void', ['string'], [result]);
+ }).catch(function (e) {
+ // Fail graciously.
+ });
+ } catch (e) {
+ // Fail graciously.
+ }
+ });
+ /* clang-format on */
+ return clipboard;
+}
+
+extern "C" EMSCRIPTEN_KEEPALIVE void send_window_event(int p_notification) {
+ if (p_notification == DisplayServer::WINDOW_EVENT_MOUSE_ENTER || p_notification == DisplayServer::WINDOW_EVENT_MOUSE_EXIT) {
+ cursor_inside_canvas = p_notification == DisplayServer::WINDOW_EVENT_MOUSE_ENTER;
+ }
+ OS_JavaScript *os = OS_JavaScript::get_singleton();
+ if (os->is_finalizing())
+ return; // We don't want events anymore.
+ DisplayServerJavaScript *ds = DisplayServerJavaScript::get_singleton();
+ if (ds && !ds->window_event_callback.is_null()) {
+ Variant event = int(p_notification);
+ Variant *eventp = &event;
+ Variant ret;
+ Callable::CallError ce;
+ ds->window_event_callback.call((const Variant **)&eventp, 1, ret, ce);
+ }
+}
+
+void DisplayServerJavaScript::alert(const String &p_alert, const String &p_title) {
+ /* clang-format off */
+ EM_ASM_({
+ window.alert(UTF8ToString($0));
+ }, p_alert.utf8().get_data());
+ /* clang-format on */
+}
+
+void DisplayServerJavaScript::set_icon(const Ref<Image> &p_icon) {
+ ERR_FAIL_COND(p_icon.is_null());
+ Ref<Image> icon = p_icon;
+ if (icon->is_compressed()) {
+ icon = icon->duplicate();
+ ERR_FAIL_COND(icon->decompress() != OK);
+ }
+ if (icon->get_format() != Image::FORMAT_RGBA8) {
+ if (icon == p_icon)
+ icon = icon->duplicate();
+ icon->convert(Image::FORMAT_RGBA8);
+ }
+
+ png_image png_meta;
+ memset(&png_meta, 0, sizeof png_meta);
+ png_meta.version = PNG_IMAGE_VERSION;
+ png_meta.width = icon->get_width();
+ png_meta.height = icon->get_height();
+ png_meta.format = PNG_FORMAT_RGBA;
+
+ PackedByteArray png;
+ size_t len;
+ PackedByteArray data = icon->get_data();
+ ERR_FAIL_COND(!png_image_write_get_memory_size(png_meta, len, 0, data.ptr(), 0, nullptr));
+
+ png.resize(len);
+ ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, png.ptrw(), &len, 0, data.ptr(), 0, nullptr));
+
+ /* clang-format off */
+ EM_ASM({
+ var PNG_PTR = $0;
+ var PNG_LEN = $1;
+
+ var png = new Blob([HEAPU8.slice(PNG_PTR, PNG_PTR + PNG_LEN)], { type: "image/png" });
+ var url = URL.createObjectURL(png);
+ var link = document.getElementById('-gd-engine-icon');
+ if (link === null) {
+ link = document.createElement('link');
+ link.rel = 'icon';
+ link.id = '-gd-engine-icon';
+ document.head.appendChild(link);
+ }
+ link.href = url;
+ }, png.ptr(), len);
+ /* clang-format on */
+}
+
+void DisplayServerJavaScript::_dispatch_input_event(const Ref<InputEvent> &p_event) {
+ OS_JavaScript *os = OS_JavaScript::get_singleton();
+ if (os->is_finalizing())
+ return; // We don't want events anymore.
+
+ // Resume audio context after input in case autoplay was denied.
+ os->resume_audio();
+
+ Callable cb = get_singleton()->input_event_callback;
+ if (!cb.is_null()) {
+ Variant ev = p_event;
+ Variant *evp = &ev;
+ Variant ret;
+ Callable::CallError ce;
+ cb.call((const Variant **)&evp, 1, ret, ce);
+ }
+}
+
+DisplayServer *DisplayServerJavaScript::create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ return memnew(DisplayServerJavaScript(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
+}
+
+DisplayServerJavaScript::DisplayServerJavaScript(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
+ /* clang-format off */
+ EM_ASM({
+ const canvas = Module['canvas'];
+ var enc = new TextEncoder("utf-8");
+ var buffer = new Uint8Array(enc.encode(canvas.id));
+ var len = buffer.byteLength;
+ var out = _malloc(len);
+ HEAPU8.set(buffer, out);
+ ccall("_set_canvas_id",
+ "void",
+ ["number", "number"],
+ [out, len]
+ );
+ _free(out);
+ });
+ /* clang-format on */
+
+ RasterizerDummy::make_current(); // TODO GLES2 in Godot 4.0... or webgpu?
+#if 0
+ EmscriptenWebGLContextAttributes attributes;
+ emscripten_webgl_init_context_attributes(&attributes);
+ attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed");
+ attributes.antialias = false;
+ ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER);
+
+ if (p_desired.layered) {
+ set_window_per_pixel_transparency_enabled(true);
+ }
+
+ bool gl_initialization_error = false;
+
+ if (RasterizerGLES2::is_viable() == OK) {
+ attributes.majorVersion = 1;
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ } else {
+ gl_initialization_error = true;
+ }
+
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(canvas_id.utf8().get_data(), &attributes);
+ if (emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS) {
+ gl_initialization_error = true;
+ }
+
+ if (gl_initialization_error) {
+ OS::get_singleton()->alert("Your browser does not seem to support WebGL. Please update your browser version.",
+ "Unable to initialize video driver");
+ return ERR_UNAVAILABLE;
+ }
+
+ video_driver_index = p_video_driver;
+#endif
+
+ /* clang-format off */
+ window_set_mode(p_mode);
+ if (EM_ASM_INT_V({ return Module['resizeCanvasOnStart'] })) {
+ /* clang-format on */
+ window_set_size(p_resolution);
+ }
+
+ EMSCRIPTEN_RESULT result;
+ CharString id = canvas_id.utf8();
+#define EM_CHECK(ev) \
+ if (result != EMSCRIPTEN_RESULT_SUCCESS) \
+ ERR_PRINT("Error while setting " #ev " callback: Code " + itos(result));
+#define SET_EM_CALLBACK(target, ev, cb) \
+ result = emscripten_set_##ev##_callback(target, nullptr, true, &cb); \
+ EM_CHECK(ev)
+#define SET_EM_CALLBACK_NOTARGET(ev, cb) \
+ result = emscripten_set_##ev##_callback(nullptr, true, &cb); \
+ EM_CHECK(ev)
+ // These callbacks from Emscripten's html5.h suffice to access most
+ // JavaScript APIs. For APIs that are not (sufficiently) exposed, EM_ASM
+ // is used below.
+ SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, mousemove, mousemove_callback)
+ SET_EM_CALLBACK(id.get_data(), mousedown, mouse_button_callback)
+ SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, mouseup, mouse_button_callback)
+ SET_EM_CALLBACK(id.get_data(), wheel, wheel_callback)
+ SET_EM_CALLBACK(id.get_data(), touchstart, touch_press_callback)
+ SET_EM_CALLBACK(id.get_data(), touchmove, touchmove_callback)
+ SET_EM_CALLBACK(id.get_data(), touchend, touch_press_callback)
+ SET_EM_CALLBACK(id.get_data(), touchcancel, touch_press_callback)
+ SET_EM_CALLBACK(id.get_data(), keydown, keydown_callback)
+ SET_EM_CALLBACK(id.get_data(), keypress, keypress_callback)
+ SET_EM_CALLBACK(id.get_data(), keyup, keyup_callback)
+ SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, fullscreenchange, fullscreen_change_callback)
+ SET_EM_CALLBACK_NOTARGET(gamepadconnected, gamepad_change_callback)
+ SET_EM_CALLBACK_NOTARGET(gamepaddisconnected, gamepad_change_callback)
+#undef SET_EM_CALLBACK_NOTARGET
+#undef SET_EM_CALLBACK
+#undef EM_CHECK
+
+ /* clang-format off */
+ EM_ASM_ARGS({
+ Module.listeners = {};
+ const canvas = Module['canvas'];
+ const send_window_event = cwrap('send_window_event', null, ['number']);
+ const notifications = arguments;
+ (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, index) {
+ Module.listeners[event] = send_window_event.bind(null, notifications[index]);
+ canvas.addEventListener(event, Module.listeners[event]);
+ });
+ // Clipboard
+ const update_clipboard = cwrap('update_clipboard', null, ['string']);
+ Module.listeners['paste'] = function(evt) {
+ update_clipboard(evt.clipboardData.getData('text'));
+ };
+ window.addEventListener('paste', Module.listeners['paste'], false);
+ Module.listeners['dragover'] = function(ev) {
+ // Prevent default behavior (which would try to open the file(s))
+ ev.preventDefault();
+ };
+ Module.listeners['drop'] = Module.drop_handler; // Defined in native/utils.js
+ canvas.addEventListener('dragover', Module.listeners['dragover'], false);
+ canvas.addEventListener('drop', Module.listeners['drop'], false);
+ },
+ WINDOW_EVENT_MOUSE_ENTER,
+ WINDOW_EVENT_MOUSE_EXIT,
+ WINDOW_EVENT_FOCUS_IN,
+ WINDOW_EVENT_FOCUS_OUT
+ );
+ /* clang-format on */
+
+ Input::get_singleton()->set_event_dispatch_function(_dispatch_input_event);
+}
+
+DisplayServerJavaScript::~DisplayServerJavaScript() {
+ EM_ASM({
+ Object.entries(Module.listeners).forEach(function(kv) {
+ if (kv[0] == 'paste') {
+ window.removeEventListener(kv[0], kv[1], true);
+ } else {
+ Module['canvas'].removeEventListener(kv[0], kv[1]);
+ }
+ });
+ Module.listeners = {};
+ });
+ //emscripten_webgl_commit_frame();
+ //emscripten_webgl_destroy_context(webgl_ctx);
+}
+
+bool DisplayServerJavaScript::has_feature(Feature p_feature) const {
+ switch (p_feature) {
+ //case FEATURE_CONSOLE_WINDOW:
+ //case FEATURE_GLOBAL_MENU:
+ //case FEATURE_HIDPI:
+ //case FEATURE_IME:
+ case FEATURE_ICON:
+ case FEATURE_CLIPBOARD:
+ case FEATURE_CURSOR_SHAPE:
+ case FEATURE_CUSTOM_CURSOR_SHAPE:
+ case FEATURE_MOUSE:
+ case FEATURE_TOUCHSCREEN:
+ return true;
+ //case FEATURE_MOUSE_WARP:
+ //case FEATURE_NATIVE_DIALOG:
+ //case FEATURE_NATIVE_ICON:
+ //case FEATURE_NATIVE_VIDEO:
+ //case FEATURE_WINDOW_TRANSPARENCY:
+ //case FEATURE_KEEP_SCREEN_ON:
+ //case FEATURE_ORIENTATION:
+ //case FEATURE_VIRTUAL_KEYBOARD:
+ default:
+ return false;
+ }
+}
+
+void DisplayServerJavaScript::register_javascript_driver() {
+ register_create_function("javascript", create_func, get_rendering_drivers_func);
+}
+
+String DisplayServerJavaScript::get_name() const {
+ return "javascript";
+}
+
+int DisplayServerJavaScript::get_screen_count() const {
+ return 1;
+}
+
+Point2i DisplayServerJavaScript::screen_get_position(int p_screen) const {
+ return Point2i(); // TODO offsetX/Y?
+}
+
+Size2i DisplayServerJavaScript::screen_get_size(int p_screen) const {
+ EmscriptenFullscreenChangeEvent ev;
+ EMSCRIPTEN_RESULT result = emscripten_get_fullscreen_status(&ev);
+ ERR_FAIL_COND_V(result != EMSCRIPTEN_RESULT_SUCCESS, Size2i());
+ return Size2i(ev.screenWidth, ev.screenHeight);
+}
+
+Rect2i DisplayServerJavaScript::screen_get_usable_rect(int p_screen) const {
+ int canvas[2];
+ emscripten_get_canvas_element_size(canvas_id.utf8().get_data(), canvas, canvas + 1);
+ return Rect2i(0, 0, canvas[0], canvas[1]);
+}
+
+int DisplayServerJavaScript::screen_get_dpi(int p_screen) const {
+ return 96; // TODO maybe check pixel ratio via window.devicePixelRatio * 96? Inexact.
+}
+
+Vector<DisplayServer::WindowID> DisplayServerJavaScript::get_window_list() const {
+ Vector<WindowID> ret;
+ ret.push_back(MAIN_WINDOW_ID);
+ return ret;
+}
+
+DisplayServerJavaScript::WindowID DisplayServerJavaScript::get_window_at_screen_position(const Point2i &p_position) const {
+ return MAIN_WINDOW_ID;
+}
+
+void DisplayServerJavaScript::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
+ window_attached_instance_id = p_instance;
+}
+
+ObjectID DisplayServerJavaScript::window_get_attached_instance_id(WindowID p_window) const {
+ return window_attached_instance_id;
+}
+
+void DisplayServerJavaScript::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
+ // Not supported.
+}
+
+void DisplayServerJavaScript::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
+ window_event_callback = p_callable;
+}
+
+void DisplayServerJavaScript::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
+ input_event_callback = p_callable;
+}
+
+void DisplayServerJavaScript::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
+ input_text_callback = p_callable; // TODO unused... do I need this?
+}
+
+void DisplayServerJavaScript::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
+ drop_files_callback = p_callable;
+}
+
+void DisplayServerJavaScript::window_set_title(const String &p_title, WindowID p_window) {
+ /* clang-format off */
+ EM_ASM_({
+ document.title = UTF8ToString($0);
+ }, p_title.utf8().get_data());
+ /* clang-format on */
+}
+
+int DisplayServerJavaScript::window_get_current_screen(WindowID p_window) const {
+ return 1;
+}
+
+void DisplayServerJavaScript::window_set_current_screen(int p_screen, WindowID p_window) {
+ // Not implemented.
+}
+
+Point2i DisplayServerJavaScript::window_get_position(WindowID p_window) const {
+ return Point2i(); // TODO Does this need implementation?
+}
+
+void DisplayServerJavaScript::window_set_position(const Point2i &p_position, WindowID p_window) {
+ // Not supported.
+}
+
+void DisplayServerJavaScript::window_set_transient(WindowID p_window, WindowID p_parent) {
+ // Not supported.
+}
+
+void DisplayServerJavaScript::window_set_max_size(const Size2i p_size, WindowID p_window) {
+ // Not supported.
+}
+
+Size2i DisplayServerJavaScript::window_get_max_size(WindowID p_window) const {
+ return Size2i();
+}
+
+void DisplayServerJavaScript::window_set_min_size(const Size2i p_size, WindowID p_window) {
+ // Not supported.
+}
+
+Size2i DisplayServerJavaScript::window_get_min_size(WindowID p_window) const {
+ return Size2i();
+}
+
+void DisplayServerJavaScript::window_set_size(const Size2i p_size, WindowID p_window) {
+ emscripten_set_canvas_element_size(canvas_id.utf8().get_data(), p_size.x, p_size.y);
+}
+
+Size2i DisplayServerJavaScript::window_get_size(WindowID p_window) const {
+ int canvas[2];
+ emscripten_get_canvas_element_size(canvas_id.utf8().get_data(), canvas, canvas + 1);
+ return Size2(canvas[0], canvas[1]);
+}
+
+Size2i DisplayServerJavaScript::window_get_real_size(WindowID p_window) const {
+ return window_get_size(p_window);
+}
+
+void DisplayServerJavaScript::window_set_mode(WindowMode p_mode, WindowID p_window) {
+ if (window_mode == p_mode)
+ return;
+
+ switch (p_mode) {
+ case WINDOW_MODE_WINDOWED: {
+ if (window_mode == WINDOW_MODE_FULLSCREEN) {
+ emscripten_exit_fullscreen();
+ }
+ window_mode = WINDOW_MODE_WINDOWED;
+ window_set_size(windowed_size);
+ } break;
+ case WINDOW_MODE_FULLSCREEN: {
+ EmscriptenFullscreenStrategy strategy;
+ strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
+ strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
+ strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
+ strategy.canvasResizedCallback = nullptr;
+ EMSCRIPTEN_RESULT result = emscripten_request_fullscreen_strategy(canvas_id.utf8().get_data(), false, &strategy);
+ ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
+ ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
+ } break;
+ case WINDOW_MODE_MAXIMIZED:
+ case WINDOW_MODE_MINIMIZED:
+ WARN_PRINT("WindowMode MAXIMIZED and MINIMIZED are not supported in HTML5 platform.");
+ break;
+ default:
+ break;
+ }
+}
+
+DisplayServerJavaScript::WindowMode DisplayServerJavaScript::window_get_mode(WindowID p_window) const {
+ return window_mode;
+}
+
+bool DisplayServerJavaScript::window_is_maximize_allowed(WindowID p_window) const {
+ return false;
+}
+
+void DisplayServerJavaScript::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
+ // Not supported.
+}
+
+bool DisplayServerJavaScript::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
+ return false;
+}
+
+void DisplayServerJavaScript::window_request_attention(WindowID p_window) {
+ // Not supported.
+}
+
+void DisplayServerJavaScript::window_move_to_foreground(WindowID p_window) {
+ // Not supported.
+}
+
+bool DisplayServerJavaScript::window_can_draw(WindowID p_window) const {
+ return true;
+}
+
+bool DisplayServerJavaScript::can_any_window_draw() const {
+ return true;
+}
+
+void DisplayServerJavaScript::process_events() {
+ if (emscripten_sample_gamepad_data() == EMSCRIPTEN_RESULT_SUCCESS)
+ process_joypads();
+}
+
+int DisplayServerJavaScript::get_current_video_driver() const {
+ return 1;
+}
+
+void DisplayServerJavaScript::swap_buffers() {
+ //emscripten_webgl_commit_frame();
+}
diff --git a/platform/javascript/display_server_javascript.h b/platform/javascript/display_server_javascript.h
new file mode 100644
index 0000000000..9860ecdf98
--- /dev/null
+++ b/platform/javascript/display_server_javascript.h
@@ -0,0 +1,187 @@
+/*************************************************************************/
+/* display_server_javascript.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef DISPLAY_SERVER_JAVASCRIPT_H
+#define DISPLAY_SERVER_JAVASCRIPT_H
+
+#include "servers/display_server.h"
+
+#include <emscripten.h>
+#include <emscripten/html5.h>
+
+class DisplayServerJavaScript : public DisplayServer {
+ //int video_driver_index;
+
+ Vector2 windowed_size;
+
+ ObjectID window_attached_instance_id = {};
+
+ Ref<InputEventKey> deferred_key_event;
+ CursorShape cursor_shape = CURSOR_ARROW;
+ String cursors[CURSOR_MAX];
+ Map<CursorShape, Vector<Variant>> cursors_cache;
+ Point2 touches[32];
+
+ Point2i last_click_pos = Point2(-100, -100); // TODO check this again.
+ double last_click_ms = 0;
+ int last_click_button_index = -1;
+
+ static EM_BOOL fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data);
+
+ static EM_BOOL keydown_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
+ static EM_BOOL keypress_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
+ static EM_BOOL keyup_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
+
+ static EM_BOOL mousemove_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data);
+ static EM_BOOL mouse_button_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data);
+
+ static EM_BOOL wheel_callback(int p_event_type, const EmscriptenWheelEvent *p_event, void *p_user_data);
+
+ static EM_BOOL touch_press_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data);
+ static EM_BOOL touchmove_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data);
+
+ static EM_BOOL gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data);
+ void process_joypads();
+
+ static Vector<String> get_rendering_drivers_func();
+ static DisplayServer *create_func(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+
+ static void _dispatch_input_event(const Ref<InputEvent> &p_event);
+
+protected:
+ virtual int get_current_video_driver() const;
+
+public:
+ // Override return type to make writing static callbacks less tedious.
+ static DisplayServerJavaScript *get_singleton();
+
+ WindowMode window_mode = WINDOW_MODE_WINDOWED;
+
+ String clipboard;
+ String canvas_id;
+
+ Callable window_event_callback;
+ Callable input_event_callback;
+ Callable input_text_callback;
+ Callable drop_files_callback;
+
+ // from DisplayServer
+ virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
+ virtual bool has_feature(Feature p_feature) const;
+ virtual String get_name() const;
+
+ // cursor
+ virtual void cursor_set_shape(CursorShape p_shape);
+ virtual CursorShape cursor_get_shape() const;
+ virtual void cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape = CURSOR_ARROW, const Vector2 &p_hotspot = Vector2());
+
+ // mouse
+ virtual void mouse_set_mode(MouseMode p_mode);
+ virtual MouseMode mouse_get_mode() const;
+
+ // touch
+ virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+
+ // clipboard
+ virtual void clipboard_set(const String &p_text);
+ virtual String clipboard_get() const;
+
+ // screen
+ virtual int get_screen_count() const;
+ virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+
+ // windows
+ virtual Vector<DisplayServer::WindowID> get_window_list() const;
+ virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;
+
+ virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID);
+ virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const;
+
+ virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+
+ virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+
+ virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID);
+
+ virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID);
+
+ virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID);
+
+ virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID);
+
+ virtual void window_set_transient(WindowID p_window, WindowID p_parent);
+
+ virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const;
+
+ virtual void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const;
+
+ virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID);
+ virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const;
+ virtual Size2i window_get_real_size(WindowID p_window = MAIN_WINDOW_ID) const; // FIXME: Find clearer name for this.
+
+ virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID);
+ virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const;
+
+ virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const;
+
+ virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID);
+ virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const;
+
+ virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID);
+ virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID);
+
+ virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const;
+
+ virtual bool can_any_window_draw() const;
+
+ // events
+ virtual void process_events();
+
+ // icon
+ virtual void set_icon(const Ref<Image> &p_icon);
+
+ // others
+ virtual void swap_buffers();
+
+ static void register_javascript_driver();
+ DisplayServerJavaScript(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error);
+ ~DisplayServerJavaScript();
+};
+
+#endif // DISPLAY_SERVER_JAVASCRIPT_H
diff --git a/platform/javascript/dom_keys.inc b/platform/javascript/dom_keys.inc
index fd9df765d2..882e943471 100644
--- a/platform/javascript/dom_keys.inc
+++ b/platform/javascript/dom_keys.inc
@@ -219,7 +219,6 @@
#define DOM_VK_WIN_OEM_CLEAR 0xFE
int dom2godot_keycode(int dom_keycode) {
-
if (DOM_VK_0 <= dom_keycode && dom_keycode <= DOM_VK_Z) {
// ASCII intersection
return dom_keycode;
@@ -237,9 +236,12 @@ int dom2godot_keycode(int dom_keycode) {
switch (dom_keycode) {
//case DOM_VK_CANCEL: return KEY_UNKNOWN;
- case DOM_VK_HELP: return KEY_HELP;
- case DOM_VK_BACK_SPACE: return KEY_BACKSPACE;
- case DOM_VK_TAB: return KEY_TAB;
+ case DOM_VK_HELP:
+ return KEY_HELP;
+ case DOM_VK_BACK_SPACE:
+ return KEY_BACKSPACE;
+ case DOM_VK_TAB:
+ return KEY_TAB;
case DOM_VK_CLEAR:
case DOM_VK_WIN_OEM_CLEAR: // OEM duplicate
@@ -249,14 +251,17 @@ int dom2godot_keycode(int dom_keycode) {
case DOM_VK_ENTER: // unused according to MDN
return KEY_ENTER;
- case DOM_VK_SHIFT: return KEY_SHIFT;
- case DOM_VK_CONTROL: return KEY_CONTROL;
+ case DOM_VK_SHIFT:
+ return KEY_SHIFT;
+ case DOM_VK_CONTROL:
+ return KEY_CONTROL;
case DOM_VK_ALT:
case DOM_VK_ALTGR:
return KEY_ALT;
- case DOM_VK_PAUSE: return KEY_PAUSE;
+ case DOM_VK_PAUSE:
+ return KEY_PAUSE;
case DOM_VK_CAPS_LOCK:
return KEY_CAPSLOCK;
@@ -279,14 +284,22 @@ int dom2godot_keycode(int dom_keycode) {
case DOM_VK_MODECHANGE: return KEY_UNKNOWN;
*/
- case DOM_VK_SPACE: return KEY_SPACE;
- case DOM_VK_PAGE_UP: return KEY_PAGEUP;
- case DOM_VK_PAGE_DOWN: return KEY_PAGEDOWN;
- case DOM_VK_END: return KEY_END;
- case DOM_VK_HOME: return KEY_HOME;
- case DOM_VK_LEFT: return KEY_LEFT;
- case DOM_VK_UP: return KEY_UP;
- case DOM_VK_RIGHT: return KEY_RIGHT;
+ case DOM_VK_SPACE:
+ return KEY_SPACE;
+ case DOM_VK_PAGE_UP:
+ return KEY_PAGEUP;
+ case DOM_VK_PAGE_DOWN:
+ return KEY_PAGEDOWN;
+ case DOM_VK_END:
+ return KEY_END;
+ case DOM_VK_HOME:
+ return KEY_HOME;
+ case DOM_VK_LEFT:
+ return KEY_LEFT;
+ case DOM_VK_UP:
+ return KEY_UP;
+ case DOM_VK_RIGHT:
+ return KEY_RIGHT;
case DOM_VK_DOWN:
return KEY_DOWN;
@@ -297,24 +310,31 @@ int dom2godot_keycode(int dom_keycode) {
return KEY_PRINT;
//case DOM_VK_EXECUTE: return KEY_UNKNOWN;
- case DOM_VK_INSERT: return KEY_INSERT;
- case DOM_VK_DELETE: return KEY_DELETE;
+ case DOM_VK_INSERT:
+ return KEY_INSERT;
+ case DOM_VK_DELETE:
+ return KEY_DELETE;
case DOM_VK_META:
case DOM_VK_WIN:
return KEY_META;
- case DOM_VK_CONTEXT_MENU: return KEY_MENU;
+ case DOM_VK_CONTEXT_MENU:
+ return KEY_MENU;
case DOM_VK_SLEEP:
return KEY_STANDBY;
// Numpad keys
- case DOM_VK_MULTIPLY: return KEY_KP_MULTIPLY;
- case DOM_VK_ADD: return KEY_KP_ADD;
+ case DOM_VK_MULTIPLY:
+ return KEY_KP_MULTIPLY;
+ case DOM_VK_ADD:
+ return KEY_KP_ADD;
case DOM_VK_SEPARATOR:
return KEY_KP_PERIOD; // Good enough?
- case DOM_VK_SUBTRACT: return KEY_KP_SUBTRACT;
- case DOM_VK_DECIMAL: return KEY_KP_PERIOD;
+ case DOM_VK_SUBTRACT:
+ return KEY_KP_SUBTRACT;
+ case DOM_VK_DECIMAL:
+ return KEY_KP_PERIOD;
case DOM_VK_DIVIDE:
return KEY_KP_DIVIDE;
@@ -329,7 +349,8 @@ int dom2godot_keycode(int dom_keycode) {
case DOM_VK_F24: return KEY_UNKNOWN;
*/
- case DOM_VK_NUM_LOCK: return KEY_NUMLOCK;
+ case DOM_VK_NUM_LOCK:
+ return KEY_NUMLOCK;
case DOM_VK_SCROLL_LOCK:
return KEY_SCROLLLOCK;
@@ -341,40 +362,68 @@ int dom2godot_keycode(int dom_keycode) {
case DOM_VK_WIN_OEM_FJ_ROYA: return KEY_UNKNOWN;
*/
- case DOM_VK_CIRCUMFLEX: return KEY_ASCIICIRCUM;
- case DOM_VK_EXCLAMATION: return KEY_EXCLAM;
- case DOM_VK_DOUBLE_QUOTE: return KEY_QUOTEDBL;
- case DOM_VK_HASH: return KEY_NUMBERSIGN;
- case DOM_VK_DOLLAR: return KEY_DOLLAR;
- case DOM_VK_PERCENT: return KEY_PERCENT;
- case DOM_VK_AMPERSAND: return KEY_AMPERSAND;
- case DOM_VK_UNDERSCORE: return KEY_UNDERSCORE;
- case DOM_VK_OPEN_PAREN: return KEY_PARENLEFT;
- case DOM_VK_CLOSE_PAREN: return KEY_PARENRIGHT;
- case DOM_VK_ASTERISK: return KEY_ASTERISK;
- case DOM_VK_PLUS: return KEY_PLUS;
- case DOM_VK_PIPE: return KEY_BAR;
- case DOM_VK_HYPHEN_MINUS: return KEY_MINUS;
- case DOM_VK_OPEN_CURLY_BRACKET: return KEY_BRACELEFT;
- case DOM_VK_CLOSE_CURLY_BRACKET: return KEY_BRACERIGHT;
- case DOM_VK_TILDE: return KEY_ASCIITILDE;
+ case DOM_VK_CIRCUMFLEX:
+ return KEY_ASCIICIRCUM;
+ case DOM_VK_EXCLAMATION:
+ return KEY_EXCLAM;
+ case DOM_VK_DOUBLE_QUOTE:
+ return KEY_QUOTEDBL;
+ case DOM_VK_HASH:
+ return KEY_NUMBERSIGN;
+ case DOM_VK_DOLLAR:
+ return KEY_DOLLAR;
+ case DOM_VK_PERCENT:
+ return KEY_PERCENT;
+ case DOM_VK_AMPERSAND:
+ return KEY_AMPERSAND;
+ case DOM_VK_UNDERSCORE:
+ return KEY_UNDERSCORE;
+ case DOM_VK_OPEN_PAREN:
+ return KEY_PARENLEFT;
+ case DOM_VK_CLOSE_PAREN:
+ return KEY_PARENRIGHT;
+ case DOM_VK_ASTERISK:
+ return KEY_ASTERISK;
+ case DOM_VK_PLUS:
+ return KEY_PLUS;
+ case DOM_VK_PIPE:
+ return KEY_BAR;
+ case DOM_VK_HYPHEN_MINUS:
+ return KEY_MINUS;
+ case DOM_VK_OPEN_CURLY_BRACKET:
+ return KEY_BRACELEFT;
+ case DOM_VK_CLOSE_CURLY_BRACKET:
+ return KEY_BRACERIGHT;
+ case DOM_VK_TILDE:
+ return KEY_ASCIITILDE;
- case DOM_VK_VOLUME_MUTE: return KEY_VOLUMEMUTE;
- case DOM_VK_VOLUME_DOWN: return KEY_VOLUMEDOWN;
- case DOM_VK_VOLUME_UP: return KEY_VOLUMEUP;
+ case DOM_VK_VOLUME_MUTE:
+ return KEY_VOLUMEMUTE;
+ case DOM_VK_VOLUME_DOWN:
+ return KEY_VOLUMEDOWN;
+ case DOM_VK_VOLUME_UP:
+ return KEY_VOLUMEUP;
- case DOM_VK_COMMA: return KEY_COMMA;
- case DOM_VK_PERIOD: return KEY_PERIOD;
- case DOM_VK_SLASH: return KEY_SLASH;
- case DOM_VK_BACK_QUOTE: return KEY_QUOTELEFT;
- case DOM_VK_OPEN_BRACKET: return KEY_BRACKETLEFT;
- case DOM_VK_BACK_SLASH: return KEY_BACKSLASH;
- case DOM_VK_CLOSE_BRACKET: return KEY_BRACKETRIGHT;
+ case DOM_VK_COMMA:
+ return KEY_COMMA;
+ case DOM_VK_PERIOD:
+ return KEY_PERIOD;
+ case DOM_VK_SLASH:
+ return KEY_SLASH;
+ case DOM_VK_BACK_QUOTE:
+ return KEY_QUOTELEFT;
+ case DOM_VK_OPEN_BRACKET:
+ return KEY_BRACKETLEFT;
+ case DOM_VK_BACK_SLASH:
+ return KEY_BACKSLASH;
+ case DOM_VK_CLOSE_BRACKET:
+ return KEY_BRACKETRIGHT;
case DOM_VK_QUOTE:
return KEY_APOSTROPHE;
// The rest is OEM/unusual.
- default: return KEY_UNKNOWN;
+ default:
+ return KEY_UNKNOWN;
};
}
diff --git a/platform/javascript/engine/engine.js b/platform/javascript/engine/engine.js
index 6d7509377f..d709422abb 100644
--- a/platform/javascript/engine/engine.js
+++ b/platform/javascript/engine/engine.js
@@ -1,16 +1,8 @@
Function('return this')()['Engine'] = (function() {
-
- var unloadAfterInit = true;
- var canvas = null;
- var resizeCanvasOnStart = false;
- var customLocale = 'en_US';
- var wasmExt = '.wasm';
-
var preloader = new Preloader();
- var loader = new Loader();
- var rtenv = null;
- var executableName = '';
+ var wasmExt = '.wasm';
+ var unloadAfterInit = true;
var loadPath = '';
var loadPromise = null;
var initPromise = null;
@@ -33,31 +25,43 @@ Function('return this')()['Engine'] = (function() {
};
/** @constructor */
- function Engine() {};
+ function Engine() {
+ this.canvas = null;
+ this.executableName = '';
+ this.rtenv = null;
+ this.customLocale = null;
+ this.resizeCanvasOnStart = false;
+ this.onExecute = null;
+ this.onExit = null;
+ };
Engine.prototype.init = /** @param {string=} basePath */ function(basePath) {
if (initPromise) {
return initPromise;
}
- if (!loadPromise) {
+ if (loadPromise == null) {
if (!basePath) {
initPromise = Promise.reject(new Error("A base path must be provided when calling `init` and the engine is not loaded."));
return initPromise;
}
load(basePath);
}
- var config = {}
+ var config = {};
if (typeof stdout === 'function')
config.print = stdout;
if (typeof stderr === 'function')
config.printErr = stderr;
- initPromise = loader.init(loadPromise, loadPath, config).then(function() {
- return new Promise(function(resolve, reject) {
- rtenv = loader.env;
+ var me = this;
+ initPromise = new Promise(function(resolve, reject) {
+ config['locateFile'] = Utils.createLocateRewrite(loadPath);
+ config['instantiateWasm'] = Utils.createInstantiatePromise(loadPromise);
+ Godot(config).then(function(module) {
+ me.rtenv = module;
if (unloadAfterInit) {
- loadPromise = null;
+ unload();
}
resolve();
+ config = null;
});
});
return initPromise;
@@ -76,33 +80,72 @@ Function('return this')()['Engine'] = (function() {
args.push(arguments[i]);
}
var me = this;
- return new Promise(function(resolve, reject) {
- return me.init().then(function() {
- if (!(canvas instanceof HTMLCanvasElement)) {
- canvas = Utils.findCanvas();
- }
- rtenv['locale'] = customLocale;
- rtenv['canvas'] = canvas;
- rtenv['thisProgram'] = executableName;
- rtenv['resizeCanvasOnStart'] = resizeCanvasOnStart;
- loader.start(preloader.preloadedFiles, args).then(function() {
- loader = null;
- initPromise = null;
- resolve();
+ return me.init().then(function() {
+ if (!me.rtenv) {
+ return Promise.reject(new Error('The engine must be initialized before it can be started'));
+ }
+
+ if (!(me.canvas instanceof HTMLCanvasElement)) {
+ me.canvas = Utils.findCanvas();
+ }
+
+ // Canvas can grab focus on click, or key events won't work.
+ if (me.canvas.tabIndex < 0) {
+ me.canvas.tabIndex = 0;
+ }
+
+ // Disable right-click context menu.
+ me.canvas.addEventListener('contextmenu', function(ev) {
+ ev.preventDefault();
+ }, false);
+
+ // Until context restoration is implemented warn the user of context loss.
+ me.canvas.addEventListener('webglcontextlost', function(ev) {
+ alert("WebGL context lost, please reload the page");
+ ev.preventDefault();
+ }, false);
+
+ // Browser locale, or custom one if defined.
+ var locale = me.customLocale;
+ if (!locale) {
+ locale = navigator.languages ? navigator.languages[0] : navigator.language;
+ locale = locale.split('.')[0];
+ }
+ me.rtenv['locale'] = locale;
+ me.rtenv['canvas'] = me.canvas;
+ me.rtenv['thisProgram'] = me.executableName;
+ me.rtenv['resizeCanvasOnStart'] = me.resizeCanvasOnStart;
+ me.rtenv['noExitRuntime'] = true;
+ me.rtenv['onExecute'] = me.onExecute;
+ me.rtenv['onExit'] = function(code) {
+ if (me.onExit)
+ me.onExit(code);
+ me.rtenv = null;
+ }
+ return new Promise(function(resolve, reject) {
+ preloader.preloadedFiles.forEach(function(file) {
+ me.rtenv['copyToFS'](file.path, file.buffer);
});
+ preloader.preloadedFiles.length = 0; // Clear memory
+ me.rtenv['callMain'](args);
+ initPromise = null;
+ resolve();
});
});
};
- Engine.prototype.startGame = function(execName, mainPack) {
+ Engine.prototype.startGame = function(execName, mainPack, extraArgs) {
// Start and init with execName as loadPath if not inited.
- executableName = execName;
+ this.executableName = execName;
var me = this;
return Promise.all([
this.init(execName),
this.preloadFile(mainPack, mainPack)
]).then(function() {
- return me.start('--main-pack', mainPack);
+ var args = ['--main-pack', mainPack];
+ if (extraArgs)
+ args = args.concat(extraArgs);
+ return me.start.apply(me, args);
});
};
@@ -118,67 +161,85 @@ Function('return this')()['Engine'] = (function() {
};
Engine.prototype.setCanvas = function(canvasElem) {
- canvas = canvasElem;
+ this.canvas = canvasElem;
};
Engine.prototype.setCanvasResizedOnStart = function(enabled) {
- resizeCanvasOnStart = enabled;
+ this.resizeCanvasOnStart = enabled;
};
Engine.prototype.setLocale = function(locale) {
- customLocale = locale;
+ this.customLocale = locale;
};
Engine.prototype.setExecutableName = function(newName) {
- executableName = newName;
+ this.executableName = newName;
};
Engine.prototype.setProgressFunc = function(func) {
progressFunc = func;
- }
+ };
Engine.prototype.setStdoutFunc = function(func) {
-
var print = function(text) {
if (arguments.length > 1) {
text = Array.prototype.slice.call(arguments).join(" ");
}
func(text);
};
- if (rtenv)
- rtenv.print = print;
+ if (this.rtenv)
+ this.rtenv.print = print;
stdout = print;
};
Engine.prototype.setStderrFunc = function(func) {
-
var printErr = function(text) {
if (arguments.length > 1)
text = Array.prototype.slice.call(arguments).join(" ");
func(text);
};
- if (rtenv)
- rtenv.printErr = printErr;
+ if (this.rtenv)
+ this.rtenv.printErr = printErr;
stderr = printErr;
};
+ Engine.prototype.setOnExecute = function(onExecute) {
+ if (this.rtenv)
+ this.rtenv.onExecute = onExecute;
+ this.onExecute = onExecute;
+ }
+
+ Engine.prototype.setOnExit = function(onExit) {
+ this.onExit = onExit;
+ }
+
+ Engine.prototype.copyToFS = function(path, buffer) {
+ if (this.rtenv == null) {
+ throw new Error("Engine must be inited before copying files");
+ }
+ this.rtenv['copyToFS'](path, buffer);
+ }
+
// Closure compiler exported engine methods.
/** @export */
Engine['isWebGLAvailable'] = Utils.isWebGLAvailable;
Engine['load'] = load;
Engine['unload'] = unload;
- Engine.prototype['init'] = Engine.prototype.init
- Engine.prototype['preloadFile'] = Engine.prototype.preloadFile
- Engine.prototype['start'] = Engine.prototype.start
- Engine.prototype['startGame'] = Engine.prototype.startGame
- Engine.prototype['setWebAssemblyFilenameExtension'] = Engine.prototype.setWebAssemblyFilenameExtension
- Engine.prototype['setUnloadAfterInit'] = Engine.prototype.setUnloadAfterInit
- Engine.prototype['setCanvas'] = Engine.prototype.setCanvas
- Engine.prototype['setCanvasResizedOnStart'] = Engine.prototype.setCanvasResizedOnStart
- Engine.prototype['setLocale'] = Engine.prototype.setLocale
- Engine.prototype['setExecutableName'] = Engine.prototype.setExecutableName
- Engine.prototype['setProgressFunc'] = Engine.prototype.setProgressFunc
- Engine.prototype['setStdoutFunc'] = Engine.prototype.setStdoutFunc
- Engine.prototype['setStderrFunc'] = Engine.prototype.setStderrFunc
+ Engine.prototype['init'] = Engine.prototype.init;
+ Engine.prototype['preloadFile'] = Engine.prototype.preloadFile;
+ Engine.prototype['start'] = Engine.prototype.start;
+ Engine.prototype['startGame'] = Engine.prototype.startGame;
+ Engine.prototype['setWebAssemblyFilenameExtension'] = Engine.prototype.setWebAssemblyFilenameExtension;
+ Engine.prototype['setUnloadAfterInit'] = Engine.prototype.setUnloadAfterInit;
+ Engine.prototype['setCanvas'] = Engine.prototype.setCanvas;
+ Engine.prototype['setCanvasResizedOnStart'] = Engine.prototype.setCanvasResizedOnStart;
+ Engine.prototype['setLocale'] = Engine.prototype.setLocale;
+ Engine.prototype['setExecutableName'] = Engine.prototype.setExecutableName;
+ Engine.prototype['setProgressFunc'] = Engine.prototype.setProgressFunc;
+ Engine.prototype['setStdoutFunc'] = Engine.prototype.setStdoutFunc;
+ Engine.prototype['setStderrFunc'] = Engine.prototype.setStderrFunc;
+ Engine.prototype['setOnExecute'] = Engine.prototype.setOnExecute;
+ Engine.prototype['setOnExit'] = Engine.prototype.setOnExit;
+ Engine.prototype['copyToFS'] = Engine.prototype.copyToFS;
return Engine;
})();
diff --git a/platform/javascript/engine/loader.js b/platform/javascript/engine/loader.js
deleted file mode 100644
index d27fbf612e..0000000000
--- a/platform/javascript/engine/loader.js
+++ /dev/null
@@ -1,33 +0,0 @@
-var Loader = /** @constructor */ function() {
-
- this.env = null;
-
- this.init = function(loadPromise, basePath, config) {
- var me = this;
- return new Promise(function(resolve, reject) {
- var cfg = config || {};
- cfg['locateFile'] = Utils.createLocateRewrite(basePath);
- cfg['instantiateWasm'] = Utils.createInstantiatePromise(loadPromise);
- loadPromise = null;
- Godot(cfg).then(function(module) {
- me.env = module;
- resolve();
- });
- });
- }
-
- this.start = function(preloadedFiles, args) {
- var me = this;
- return new Promise(function(resolve, reject) {
- if (!me.env) {
- reject(new Error('The engine must be initialized before it can be started'));
- }
- preloadedFiles.forEach(function(file) {
- Utils.copyToFS(me.env['FS'], file.path, file.buffer);
- });
- preloadedFiles.length = 0; // Clear memory
- me.env['callMain'](args);
- resolve();
- });
- }
-};
diff --git a/platform/javascript/engine/utils.js b/platform/javascript/engine/utils.js
index fdff90a923..0c97b38199 100644
--- a/platform/javascript/engine/utils.js
+++ b/platform/javascript/engine/utils.js
@@ -27,24 +27,6 @@ var Utils = {
return instantiateWasm;
},
- copyToFS: function(fs, path, buffer) {
- var p = path.lastIndexOf("/");
- var dir = "/";
- if (p > 0) {
- dir = path.slice(0, path.lastIndexOf("/"));
- }
- try {
- fs.stat(dir);
- } catch (e) {
- if (e.errno !== 44) { // 'ENOENT', see https://github.com/emscripten-core/emscripten/blob/master/system/lib/libc/musl/arch/emscripten/bits/errno.h
- throw e;
- }
- fs['mkdirTree'](dir);
- }
- // With memory growth, canOwn should be false.
- fs['writeFile'](path, new Uint8Array(buffer), {'flags': 'wx+'});
- },
-
findCanvas: function() {
var nodes = document.getElementsByTagName('canvas');
if (nodes.length && nodes[0] instanceof HTMLCanvasElement) {
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index 39faae2d17..3573ddac95 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#include "core/io/json.h"
#include "core/io/tcp_server.h"
#include "core/io/zip_io.h"
#include "editor/editor_export.h"
@@ -40,7 +41,6 @@
#define EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG "webassembly_debug.zip"
class EditorHTTPServer : public Reference {
-
private:
Ref<TCP_Server> server;
Ref<StreamPeerTCP> connection;
@@ -148,11 +148,13 @@ public:
}
void poll() {
- if (!server->is_listening())
+ if (!server->is_listening()) {
return;
+ }
if (connection.is_null()) {
- if (!server->is_connection_available())
+ if (!server->is_connection_available()) {
return;
+ }
connection = server->take_connection();
time = OS::get_singleton()->get_ticks_usec();
}
@@ -160,11 +162,11 @@ public:
_clear_client();
return;
}
- if (connection->get_status() != StreamPeerTCP::STATUS_CONNECTED)
+ if (connection->get_status() != StreamPeerTCP::STATUS_CONNECTED) {
return;
+ }
while (true) {
-
char *r = (char *)req_buf;
int l = req_pos - 1;
if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') {
@@ -190,7 +192,6 @@ public:
};
class EditorExportPlatformJavaScript : public EditorExportPlatform {
-
GDCLASS(EditorExportPlatformJavaScript, EditorExportPlatform);
Ref<ImageTexture> logo;
@@ -198,7 +199,7 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform {
Ref<ImageTexture> stop_icon;
int menu_options;
- void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug);
+ void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags);
private:
Ref<EditorHTTPServer> server;
@@ -230,7 +231,6 @@ public:
virtual Ref<Texture2D> get_run_icon() const;
virtual void get_platform_features(List<String> *r_features) {
-
r_features->push_back("web");
r_features->push_back(get_os_name());
}
@@ -238,22 +238,28 @@ public:
virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, Set<String> &p_features) {
}
+ String get_debug_protocol() const { return "ws://"; }
+
EditorExportPlatformJavaScript();
~EditorExportPlatformJavaScript();
};
-void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug) {
-
+void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug, int p_flags) {
String str_template = String::utf8(reinterpret_cast<const char *>(p_html.ptr()), p_html.size());
String str_export;
Vector<String> lines = str_template.split("\n");
+ Vector<String> flags;
+ String flags_json;
+ gen_export_flags(flags, p_flags);
+ flags_json = JSON::print(flags);
for (int i = 0; i < lines.size(); i++) {
-
String current_line = lines[i];
current_line = current_line.replace("$GODOT_BASENAME", p_name);
+ current_line = current_line.replace("$GODOT_PROJECT_NAME", ProjectSettings::get_singleton()->get_setting("application/config/name"));
current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include"));
current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false");
+ current_line = current_line.replace("$GODOT_ARGS", flags_json);
str_export += current_line + "\n";
}
@@ -265,7 +271,6 @@ void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Re
}
void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
-
if (p_preset->get("vram_texture_compression/for_desktop")) {
r_features->push_back("s3tc");
}
@@ -282,7 +287,6 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP
}
void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_options) {
-
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_desktop"), true)); // S3TC
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "vram_texture_compression/for_mobile"), false)); // ETC or ETC2, depending on renderer
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/custom_html_shell", PROPERTY_HINT_FILE, "*.html"), ""));
@@ -292,22 +296,18 @@ void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_op
}
String EditorExportPlatformJavaScript::get_name() const {
-
return "HTML5";
}
String EditorExportPlatformJavaScript::get_os_name() const {
-
return "HTML5";
}
Ref<Texture2D> EditorExportPlatformJavaScript::get_logo() const {
-
return logo;
}
bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
-
String err;
bool valid = false;
@@ -342,14 +342,14 @@ bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p
}
}
- if (!err.empty())
+ if (!err.empty()) {
r_error = err;
+ }
return valid;
}
List<String> EditorExportPlatformJavaScript::get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const {
-
List<String> list;
list.push_back("html");
return list;
@@ -367,11 +367,11 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
template_path = template_path.strip_edges();
if (template_path == String()) {
-
- if (p_debug)
+ if (p_debug) {
template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG);
- else
+ } else {
template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE);
+ }
}
if (!DirAccess::exists(p_path.get_base_dir())) {
@@ -395,7 +395,6 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
unzFile pkg = unzOpen2(template_path.utf8().get_data(), &io);
if (!pkg) {
-
EditorNode::get_singleton()->show_warning(TTR("Could not open template for export:") + "\n" + template_path);
return ERR_FILE_NOT_FOUND;
}
@@ -425,22 +424,18 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
//write
if (file == "godot.html") {
-
if (!custom_html.empty()) {
continue;
}
- _fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug);
+ _fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug, p_flags);
file = p_path.get_file();
} else if (file == "godot.js") {
-
file = p_path.get_file().get_basename() + ".js";
} else if (file == "godot.worker.js") {
-
file = p_path.get_file().get_basename() + ".worker.js";
} else if (file == "godot.wasm") {
-
file = p_path.get_file().get_basename() + ".wasm";
}
@@ -458,7 +453,6 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
unzClose(pkg);
if (!custom_html.empty()) {
-
FileAccess *f = FileAccess::open(custom_html, FileAccess::READ);
if (!f) {
EditorNode::get_singleton()->show_warning(TTR("Could not read custom HTML shell:") + "\n" + custom_html);
@@ -468,7 +462,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
buf.resize(f->get_len());
f->get_buffer(buf.ptrw(), buf.size());
memdelete(f);
- _fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug);
+ _fix_html(buf, p_preset, p_path.get_file().get_basename(), p_debug, p_flags);
f = FileAccess::open(p_path, FileAccess::WRITE);
if (!f) {
@@ -522,11 +516,9 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
}
bool EditorExportPlatformJavaScript::poll_export() {
-
Ref<EditorExportPreset> preset;
for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
-
Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i);
if (ep->is_runnable() && ep->get_platform() == this) {
preset = ep;
@@ -552,12 +544,10 @@ Ref<ImageTexture> EditorExportPlatformJavaScript::get_option_icon(int p_index) c
}
int EditorExportPlatformJavaScript::get_options_count() const {
-
return menu_options;
}
Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags) {
-
if (p_option == 1) {
MutexLock lock(server_lock);
server->stop();
@@ -605,7 +595,6 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
}
Ref<Texture2D> EditorExportPlatformJavaScript::get_run_icon() const {
-
return run_icon;
}
@@ -621,7 +610,6 @@ void EditorExportPlatformJavaScript::_server_thread_poll(void *data) {
}
EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
-
server.instance();
server_quit = false;
server_thread = Thread::create(_server_thread_poll, this);
@@ -635,10 +623,11 @@ EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
run_icon->create_from_image(img);
Ref<Theme> theme = EditorNode::get_singleton()->get_editor_theme();
- if (theme.is_valid())
+ if (theme.is_valid()) {
stop_icon = theme->get_icon("Stop", "EditorIcons");
- else
+ } else {
stop_icon.instance();
+ }
menu_options = 0;
}
@@ -651,7 +640,6 @@ EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() {
}
void register_javascript_exporter() {
-
EDITOR_DEF("export/web/http_host", "localhost");
EDITOR_DEF("export/web/http_port", 8060);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "export/web/http_port", PROPERTY_HINT_RANGE, "1,65535,1"));
diff --git a/platform/javascript/http_client.h.inc b/platform/javascript/http_client.h.inc
index ac275aadbc..4d5ff88bdd 100644
--- a/platform/javascript/http_client.h.inc
+++ b/platform/javascript/http_client.h.inc
@@ -33,21 +33,21 @@
Error prepare_request(Method p_method, const String &p_url, const Vector<String> &p_headers);
int xhr_id;
-int read_limit;
-int response_read_offset;
-Status status;
+int read_limit = 4096;
+int response_read_offset = 0;
+Status status = STATUS_DISCONNECTED;
String host;
-int port;
-bool use_tls;
+int port = -1;
+bool use_tls = false;
String username;
String password;
-int polled_response_code;
+int polled_response_code = 0;
String polled_response_header;
PackedByteArray polled_response;
#ifdef DEBUG_ENABLED
-bool has_polled;
-uint64_t last_polling_frame;
+bool has_polled = false;
+uint64_t last_polling_frame = 0;
#endif
diff --git a/platform/javascript/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp
index 863c207896..cb0e48b8a9 100644
--- a/platform/javascript/http_client_javascript.cpp
+++ b/platform/javascript/http_client_javascript.cpp
@@ -29,10 +29,10 @@
/*************************************************************************/
#include "core/io/http_client.h"
+
#include "http_request.h"
Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl, bool p_verify_host) {
-
close();
if (p_ssl && !p_verify_host) {
WARN_PRINT("Disabling HTTPClient's host verification is not supported for the HTML5 platform, host will be verified");
@@ -67,17 +67,14 @@ Error HTTPClient::connect_to_host(const String &p_host, int p_port, bool p_ssl,
}
void HTTPClient::set_connection(const Ref<StreamPeer> &p_connection) {
-
ERR_FAIL_MSG("Accessing an HTTPClient's StreamPeer is not supported for the HTML5 platform.");
}
Ref<StreamPeer> HTTPClient::get_connection() const {
-
ERR_FAIL_V_MSG(REF(), "Accessing an HTTPClient's StreamPeer is not supported for the HTML5 platform.");
}
Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Vector<String> &p_headers) {
-
ERR_FAIL_INDEX_V(p_method, METHOD_MAX, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V_MSG(p_method == METHOD_TRACE || p_method == METHOD_CONNECT, ERR_UNAVAILABLE, "HTTP methods TRACE and CONNECT are not supported for the HTML5 platform.");
ERR_FAIL_COND_V(status != STATUS_CONNECTED, ERR_INVALID_PARAMETER);
@@ -104,7 +101,6 @@ Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Ve
}
Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) {
-
Error err = prepare_request(p_method, p_url, p_headers);
if (err != OK)
return err;
@@ -113,7 +109,6 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector
}
Error HTTPClient::request(Method p_method, const String &p_url, const Vector<String> &p_headers, const String &p_body) {
-
Error err = prepare_request(p_method, p_url, p_headers);
if (err != OK)
return err;
@@ -122,7 +117,6 @@ Error HTTPClient::request(Method p_method, const String &p_url, const Vector<Str
}
void HTTPClient::close() {
-
host = "";
port = -1;
use_tls = false;
@@ -134,28 +128,23 @@ void HTTPClient::close() {
}
HTTPClient::Status HTTPClient::get_status() const {
-
return status;
}
bool HTTPClient::has_response() const {
-
return !polled_response_header.empty();
}
bool HTTPClient::is_response_chunked() const {
-
// TODO evaluate using moz-chunked-arraybuffer, fetch & ReadableStream
return false;
}
int HTTPClient::get_response_code() const {
-
return polled_response_code;
}
Error HTTPClient::get_response_headers(List<String> *r_response) {
-
if (polled_response_header.empty())
return ERR_INVALID_PARAMETER;
@@ -168,12 +157,10 @@ Error HTTPClient::get_response_headers(List<String> *r_response) {
}
int HTTPClient::get_response_body_length() const {
-
return polled_response.size();
}
PackedByteArray HTTPClient::read_response_body_chunk() {
-
ERR_FAIL_COND_V(status != STATUS_BODY, PackedByteArray());
int to_read = MIN(read_limit, polled_response.size() - response_read_offset);
@@ -192,17 +179,14 @@ PackedByteArray HTTPClient::read_response_body_chunk() {
}
void HTTPClient::set_blocking_mode(bool p_enable) {
-
ERR_FAIL_COND_MSG(p_enable, "HTTPClient blocking mode is not supported for the HTML5 platform.");
}
bool HTTPClient::is_blocking_mode_enabled() const {
-
return false;
}
void HTTPClient::set_read_chunk_size(int p_size) {
-
read_limit = p_size;
}
@@ -211,9 +195,7 @@ int HTTPClient::get_read_chunk_size() const {
}
Error HTTPClient::poll() {
-
switch (status) {
-
case STATUS_DISCONNECTED:
return ERR_UNCONFIGURED;
@@ -233,7 +215,6 @@ Error HTTPClient::poll() {
return ERR_CONNECTION_ERROR;
case STATUS_REQUESTING: {
-
#ifdef DEBUG_ENABLED
if (!has_polled) {
has_polled = true;
@@ -279,20 +260,9 @@ Error HTTPClient::poll() {
}
HTTPClient::HTTPClient() {
-
xhr_id = godot_xhr_new();
- read_limit = 4096;
- status = STATUS_DISCONNECTED;
- port = -1;
- use_tls = false;
- polled_response_code = 0;
-#ifdef DEBUG_ENABLED
- has_polled = false;
- last_polling_frame = 0;
-#endif
}
HTTPClient::~HTTPClient() {
-
godot_xhr_free(xhr_id);
}
diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp
index db8050b90e..3a72b10dd4 100644
--- a/platform/javascript/javascript_eval.cpp
+++ b/platform/javascript/javascript_eval.cpp
@@ -34,14 +34,12 @@
#include "emscripten.h"
extern "C" EMSCRIPTEN_KEEPALIVE uint8_t *resize_PackedByteArray_and_open_write(PackedByteArray *p_arr, VectorWriteProxy<uint8_t> *r_write, int p_len) {
-
p_arr->resize(p_len);
*r_write = p_arr->write;
return p_arr->ptrw();
}
Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
-
union {
bool b;
double d;
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index 815bc7e456..740a72fafa 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -34,21 +34,59 @@
#include <emscripten/emscripten.h>
-extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) {
+static OS_JavaScript *os = nullptr;
+
+void exit_callback() {
+ emscripten_cancel_main_loop(); // After this, we can exit!
+ Main::cleanup();
+ int exit_code = OS_JavaScript::get_singleton()->get_exit_code();
+ memdelete(os);
+ os = nullptr;
+ emscripten_force_exit(exit_code); // No matter that we call cancel_main_loop, regular "exit" will not work, forcing.
+}
+
+void main_loop_callback() {
+ if (os->main_loop_iterate()) {
+ emscripten_cancel_main_loop(); // Cancel current loop and wait for finalize_async.
+ EM_ASM({
+ // This will contain the list of operations that need to complete before cleanup.
+ Module.async_finish = [];
+ });
+ os->get_main_loop()->finish();
+ os->finalize_async(); // Will add all the async finish functions.
+ EM_ASM({
+ Promise.all(Module.async_finish).then(function() {
+ Module.async_finish = [];
+ ccall("cleanup_after_sync", null, []);
+ });
+ });
+ }
+}
+extern "C" EMSCRIPTEN_KEEPALIVE void cleanup_after_sync() {
+ emscripten_set_main_loop(exit_callback, -1, false);
+}
+
+extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) {
String idbfs_err = String::utf8(p_idbfs_err);
if (!idbfs_err.empty()) {
print_line("IndexedDB not available: " + idbfs_err);
}
- OS_JavaScript *os = OS_JavaScript::get_singleton();
os->set_idb_available(idbfs_err.empty());
+ // TODO: Check error return value.
+ Main::setup2(); // Manual second phase.
// Ease up compatibility.
ResourceLoader::set_abort_on_missing_resources(false);
Main::start();
- os->run_async();
+ os->get_main_loop()->init();
+ emscripten_resume_main_loop();
}
int main(int argc, char *argv[]) {
+ os = new OS_JavaScript();
+ Main::setup(argv[0], argc - 1, &argv[1], false);
+ emscripten_set_main_loop(main_loop_callback, -1, false);
+ emscripten_pause_main_loop(); // Will need to wait for FS sync.
// Sync from persistent state into memory and then
// run the 'main_after_fs_sync' function.
@@ -59,13 +97,10 @@ int main(int argc, char *argv[]) {
FS.syncfs(true, function(err) {
ccall('main_after_fs_sync', null, ['string'], [err ? err.message : ""])
});
+
);
/* clang-format on */
- new OS_JavaScript(argc, argv);
- // TODO: Check error return value.
- Main::setup(argv[0], argc - 1, &argv[1]);
-
return 0;
// Continued async in main_after_fs_sync() from the syncfs() callback.
}
diff --git a/platform/javascript/http_request.js b/platform/javascript/native/http_request.js
index f621689f9d..f621689f9d 100644
--- a/platform/javascript/http_request.js
+++ b/platform/javascript/native/http_request.js
diff --git a/platform/javascript/id_handler.js b/platform/javascript/native/id_handler.js
index 67d29075b8..67d29075b8 100644
--- a/platform/javascript/id_handler.js
+++ b/platform/javascript/native/id_handler.js
diff --git a/platform/javascript/native/utils.js b/platform/javascript/native/utils.js
new file mode 100644
index 0000000000..95585d26ae
--- /dev/null
+++ b/platform/javascript/native/utils.js
@@ -0,0 +1,204 @@
+/*************************************************************************/
+/* utils.js */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+Module['copyToFS'] = function(path, buffer) {
+ var p = path.lastIndexOf("/");
+ var dir = "/";
+ if (p > 0) {
+ dir = path.slice(0, path.lastIndexOf("/"));
+ }
+ try {
+ FS.stat(dir);
+ } catch (e) {
+ if (e.errno !== ERRNO_CODES.ENOENT) { // 'ENOENT', see https://github.com/emscripten-core/emscripten/blob/master/system/lib/libc/musl/arch/emscripten/bits/errno.h
+ throw e;
+ }
+ FS.mkdirTree(dir);
+ }
+ // With memory growth, canOwn should be false.
+ FS.writeFile(path, new Uint8Array(buffer), {'flags': 'wx+'});
+}
+
+Module.drop_handler = (function() {
+ var upload = [];
+ var uploadPromises = [];
+ var uploadCallback = null;
+
+ function readFilePromise(entry, path) {
+ return new Promise(function(resolve, reject) {
+ entry.file(function(file) {
+ var reader = new FileReader();
+ reader.onload = function() {
+ var f = {
+ "path": file.relativePath || file.webkitRelativePath,
+ "name": file.name,
+ "type": file.type,
+ "size": file.size,
+ "data": reader.result
+ };
+ if (!f['path'])
+ f['path'] = f['name'];
+ upload.push(f);
+ resolve()
+ };
+ reader.onerror = function() {
+ console.log("Error reading file");
+ reject();
+ }
+
+ reader.readAsArrayBuffer(file);
+
+ }, function(err) {
+ console.log("Error!");
+ reject();
+ });
+ });
+ }
+
+ function readDirectoryPromise(entry) {
+ return new Promise(function(resolve, reject) {
+ var reader = entry.createReader();
+ reader.readEntries(function(entries) {
+ for (var i = 0; i < entries.length; i++) {
+ var ent = entries[i];
+ if (ent.isDirectory) {
+ uploadPromises.push(readDirectoryPromise(ent));
+ } else if (ent.isFile) {
+ uploadPromises.push(readFilePromise(ent));
+ }
+ }
+ resolve();
+ });
+ });
+ }
+
+ function processUploadsPromises(resolve, reject) {
+ if (uploadPromises.length == 0) {
+ resolve();
+ return;
+ }
+ uploadPromises.pop().then(function() {
+ setTimeout(function() {
+ processUploadsPromises(resolve, reject);
+ //processUploadsPromises.bind(null, resolve, reject)
+ }, 0);
+ });
+ }
+
+ function dropFiles(files) {
+ var args = files || [];
+ var argc = args.length;
+ var argv = stackAlloc((argc + 1) * 4);
+ for (var i = 0; i < argc; i++) {
+ HEAP32[(argv >> 2) + i] = allocateUTF8OnStack(args[i]);
+ }
+ HEAP32[(argv >> 2) + argc] = 0;
+ // Defined in display_server_javascript.cpp
+ ccall('_drop_files_callback', 'void', ['number', 'number'], [argv, argc]);
+ }
+
+ return function(ev) {
+ ev.preventDefault();
+ if (ev.dataTransfer.items) {
+ // Use DataTransferItemList interface to access the file(s)
+ for (var i = 0; i < ev.dataTransfer.items.length; i++) {
+ const item = ev.dataTransfer.items[i];
+ var entry = null;
+ if ("getAsEntry" in item) {
+ entry = item.getAsEntry();
+ } else if ("webkitGetAsEntry" in item) {
+ entry = item.webkitGetAsEntry();
+ }
+ if (!entry) {
+ console.error("File upload not supported");
+ } else if (entry.isDirectory) {
+ uploadPromises.push(readDirectoryPromise(entry));
+ } else if (entry.isFile) {
+ uploadPromises.push(readFilePromise(entry));
+ } else {
+ console.error("Unrecognized entry...", entry);
+ }
+ }
+ } else {
+ console.error("File upload not supported");
+ }
+ uploadCallback = new Promise(processUploadsPromises).then(function() {
+ const DROP = "/tmp/drop-" + parseInt(Math.random() * Math.pow(2, 31)) + "/";
+ var drops = [];
+ var files = [];
+ upload.forEach((elem) => {
+ var path = elem['path'];
+ Module['copyToFS'](DROP + path, elem['data']);
+ var idx = path.indexOf("/");
+ if (idx == -1) {
+ // Root file
+ drops.push(DROP + path);
+ } else {
+ // Subdir
+ var sub = path.substr(0, idx);
+ idx = sub.indexOf("/");
+ if (idx < 0 && drops.indexOf(DROP + sub) == -1) {
+ drops.push(DROP + sub);
+ }
+ }
+ files.push(DROP + path);
+ });
+ uploadPromises = [];
+ upload = [];
+ dropFiles(drops);
+ var dirs = [DROP.substr(0, DROP.length -1)];
+ files.forEach(function (file) {
+ FS.unlink(file);
+ var dir = file.replace(DROP, "");
+ var idx = dir.lastIndexOf("/");
+ while (idx > 0) {
+ dir = dir.substr(0, idx);
+ if (dirs.indexOf(DROP + dir) == -1) {
+ dirs.push(DROP + dir);
+ }
+ idx = dir.lastIndexOf("/");
+ }
+ });
+ // Remove dirs.
+ dirs = dirs.sort(function(a, b) {
+ var al = (a.match(/\//g) || []).length;
+ var bl = (b.match(/\//g) || []).length;
+ if (al > bl)
+ return -1;
+ else if (al < bl)
+ return 1;
+ return 0;
+ });
+ dirs.forEach(function(dir) {
+ FS.rmdir(dir);
+ });
+ });
+ }
+})();
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index ad06aef86e..ad4b5a5afa 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -30,668 +30,23 @@
#include "os_javascript.h"
+#include "core/debugger/engine_debugger.h"
#include "core/io/file_access_buffered_fa.h"
-//#include "drivers/gles2/rasterizer_gles2.h"
-#include "drivers/dummy/rasterizer_dummy.h"
+#include "core/io/json.h"
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
#include "main/main.h"
-#include "servers/rendering/rendering_server_raster.h"
+#include "modules/modules_enabled.gen.h"
+#include "platform/javascript/display_server_javascript.h"
+
+#ifdef MODULE_WEBSOCKET_ENABLED
+#include "modules/websocket/remote_debugger_peer_websocket.h"
+#endif
#include <emscripten.h>
-#include <png.h>
#include <stdlib.h>
-#include "dom_keys.inc"
-
-#define DOM_BUTTON_LEFT 0
-#define DOM_BUTTON_MIDDLE 1
-#define DOM_BUTTON_RIGHT 2
-#define DOM_BUTTON_XBUTTON1 3
-#define DOM_BUTTON_XBUTTON2 4
-#define GODOT_CANVAS_SELECTOR "#canvas"
-
-// Window (canvas)
-
-static void focus_canvas() {
-
- /* clang-format off */
- EM_ASM(
- Module.canvas.focus();
- );
- /* clang-format on */
-}
-
-static bool is_canvas_focused() {
-
- /* clang-format off */
- return EM_ASM_INT_V(
- return document.activeElement == Module.canvas;
- );
- /* clang-format on */
-}
-
-static Point2 compute_position_in_canvas(int x, int y) {
- int canvas_x = EM_ASM_INT({
- return document.getElementById('canvas').getBoundingClientRect().x;
- });
- int canvas_y = EM_ASM_INT({
- return document.getElementById('canvas').getBoundingClientRect().y;
- });
- int canvas_width;
- int canvas_height;
- emscripten_get_canvas_element_size(GODOT_CANVAS_SELECTOR, &canvas_width, &canvas_height);
-
- double element_width;
- double element_height;
- emscripten_get_element_css_size(GODOT_CANVAS_SELECTOR, &element_width, &element_height);
-
- return Point2((int)(canvas_width / element_width * (x - canvas_x)),
- (int)(canvas_height / element_height * (y - canvas_y)));
-}
-
-static bool cursor_inside_canvas = true;
-
-EM_BOOL OS_JavaScript::fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data) {
-
- OS_JavaScript *os = get_singleton();
- // Empty ID is canvas.
- String target_id = String::utf8(p_event->id);
- if (target_id.empty() || target_id == "canvas") {
- // This event property is the only reliable data on
- // browser fullscreen state.
- os->video_mode.fullscreen = p_event->isFullscreen;
- if (os->video_mode.fullscreen) {
- os->entering_fullscreen = false;
- } else {
- // Restoring maximized window now will cause issues,
- // so delay until main_loop_iterate.
- os->just_exited_fullscreen = true;
- }
- }
- return false;
-}
-
-void OS_JavaScript::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
-
- video_mode = p_video_mode;
-}
-
-OS::VideoMode OS_JavaScript::get_video_mode(int p_screen) const {
-
- return video_mode;
-}
-
-Size2 OS_JavaScript::get_screen_size(int p_screen) const {
-
- EmscriptenFullscreenChangeEvent ev;
- EMSCRIPTEN_RESULT result = emscripten_get_fullscreen_status(&ev);
- ERR_FAIL_COND_V(result != EMSCRIPTEN_RESULT_SUCCESS, Size2());
- return Size2(ev.screenWidth, ev.screenHeight);
-}
-
-void OS_JavaScript::set_window_size(const Size2 p_size) {
-
- windowed_size = p_size;
- if (video_mode.fullscreen) {
- window_maximized = false;
- set_window_fullscreen(false);
- } else {
- if (window_maximized) {
- emscripten_exit_soft_fullscreen();
- window_maximized = false;
- }
- emscripten_set_canvas_element_size(GODOT_CANVAS_SELECTOR, p_size.x, p_size.y);
- }
-}
-
-Size2 OS_JavaScript::get_window_size() const {
-
- int canvas[2];
- emscripten_get_canvas_element_size(GODOT_CANVAS_SELECTOR, canvas, canvas + 1);
- return Size2(canvas[0], canvas[1]);
-}
-
-void OS_JavaScript::set_window_maximized(bool p_enabled) {
-
- if (video_mode.fullscreen) {
- window_maximized = p_enabled;
- set_window_fullscreen(false);
- } else if (!p_enabled) {
- emscripten_exit_soft_fullscreen();
- window_maximized = false;
- } else if (!window_maximized) {
- // Prevent calling emscripten_enter_soft_fullscreen mutltiple times,
- // this would hide page elements permanently.
- EmscriptenFullscreenStrategy strategy;
- strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
- strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
- strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
- strategy.canvasResizedCallback = nullptr;
- emscripten_enter_soft_fullscreen(GODOT_CANVAS_SELECTOR, &strategy);
- window_maximized = p_enabled;
- }
-}
-
-bool OS_JavaScript::is_window_maximized() const {
-
- return window_maximized;
-}
-
-void OS_JavaScript::set_window_fullscreen(bool p_enabled) {
-
- if (p_enabled == video_mode.fullscreen) {
- return;
- }
-
- // Just request changes here, if successful, logic continues in
- // fullscreen_change_callback.
- if (p_enabled) {
- if (window_maximized) {
- // Soft fullsreen during real fullscreen can cause issues, so exit.
- // This must be called before requesting full screen.
- emscripten_exit_soft_fullscreen();
- }
- EmscriptenFullscreenStrategy strategy;
- strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
- strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
- strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
- strategy.canvasResizedCallback = nullptr;
- EMSCRIPTEN_RESULT result = emscripten_request_fullscreen_strategy(GODOT_CANVAS_SELECTOR, false, &strategy);
- ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
- ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "Enabling fullscreen is only possible from an input callback for the HTML5 platform.");
- // Not fullscreen yet, so prevent "windowed" canvas dimensions from
- // being overwritten.
- entering_fullscreen = true;
- } else {
- // No logic allowed here, since exiting w/ ESC key won't use this function.
- ERR_FAIL_COND(emscripten_exit_fullscreen() != EMSCRIPTEN_RESULT_SUCCESS);
- }
-}
-
-bool OS_JavaScript::is_window_fullscreen() const {
-
- return video_mode.fullscreen;
-}
-
-void OS_JavaScript::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
-
- Size2 screen = get_screen_size();
- p_list->push_back(OS::VideoMode(screen.width, screen.height, true));
-}
-
-bool OS_JavaScript::get_window_per_pixel_transparency_enabled() const {
- if (!is_layered_allowed()) {
- return false;
- }
- return transparency_enabled;
-}
-
-void OS_JavaScript::set_window_per_pixel_transparency_enabled(bool p_enabled) {
- if (!is_layered_allowed()) {
- return;
- }
- transparency_enabled = p_enabled;
-}
-
-// Keys
-
-template <typename T>
-static void dom2godot_mod(T *emscripten_event_ptr, Ref<InputEventWithModifiers> godot_event) {
-
- godot_event->set_shift(emscripten_event_ptr->shiftKey);
- godot_event->set_alt(emscripten_event_ptr->altKey);
- godot_event->set_control(emscripten_event_ptr->ctrlKey);
- godot_event->set_metakey(emscripten_event_ptr->metaKey);
-}
-
-static Ref<InputEventKey> setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) {
-
- Ref<InputEventKey> ev;
- ev.instance();
- ev->set_echo(emscripten_event->repeat);
- dom2godot_mod(emscripten_event, ev);
- ev->set_keycode(dom2godot_keycode(emscripten_event->keyCode));
- ev->set_physical_keycode(dom2godot_keycode(emscripten_event->keyCode));
-
- String unicode = String::utf8(emscripten_event->key);
- // Check if empty or multi-character (e.g. `CapsLock`).
- if (unicode.length() != 1) {
- // Might be empty as well, but better than nonsense.
- unicode = String::utf8(emscripten_event->charValue);
- }
- if (unicode.length() == 1) {
- ev->set_unicode(unicode[0]);
- }
-
- return ev;
-}
-
-EM_BOOL OS_JavaScript::keydown_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) {
-
- OS_JavaScript *os = get_singleton();
- Ref<InputEventKey> ev = setup_key_event(p_event);
- ev->set_pressed(true);
- if (ev->get_unicode() == 0 && keycode_has_unicode(ev->get_keycode())) {
- // Defer to keypress event for legacy unicode retrieval.
- os->deferred_key_event = ev;
- // Do not suppress keypress event.
- return false;
- }
- os->input->parse_input_event(ev);
- // Resume audio context after input in case autoplay was denied.
- os->audio_driver_javascript.resume();
- return true;
-}
-
-EM_BOOL OS_JavaScript::keypress_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) {
-
- OS_JavaScript *os = get_singleton();
- os->deferred_key_event->set_unicode(p_event->charCode);
- os->input->parse_input_event(os->deferred_key_event);
- return true;
-}
-
-EM_BOOL OS_JavaScript::keyup_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) {
-
- Ref<InputEventKey> ev = setup_key_event(p_event);
- ev->set_pressed(false);
- get_singleton()->input->parse_input_event(ev);
- return ev->get_keycode() != KEY_UNKNOWN && ev->get_keycode() != 0;
-}
-
-// Mouse
-
-Point2 OS_JavaScript::get_mouse_position() const {
-
- return input->get_mouse_position();
-}
-
-int OS_JavaScript::get_mouse_button_state() const {
-
- return input->get_mouse_button_mask();
-}
-
-EM_BOOL OS_JavaScript::mouse_button_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data) {
-
- OS_JavaScript *os = get_singleton();
-
- Ref<InputEventMouseButton> ev;
- ev.instance();
- ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_MOUSEDOWN);
- ev->set_position(compute_position_in_canvas(p_event->clientX, p_event->clientY));
- ev->set_global_position(ev->get_position());
- dom2godot_mod(p_event, ev);
-
- switch (p_event->button) {
- case DOM_BUTTON_LEFT: ev->set_button_index(BUTTON_LEFT); break;
- case DOM_BUTTON_MIDDLE: ev->set_button_index(BUTTON_MIDDLE); break;
- case DOM_BUTTON_RIGHT: ev->set_button_index(BUTTON_RIGHT); break;
- case DOM_BUTTON_XBUTTON1: ev->set_button_index(BUTTON_XBUTTON1); break;
- case DOM_BUTTON_XBUTTON2: ev->set_button_index(BUTTON_XBUTTON2); break;
- default: return false;
- }
-
- if (ev->is_pressed()) {
-
- double diff = emscripten_get_now() - os->last_click_ms;
-
- if (ev->get_button_index() == os->last_click_button_index) {
-
- if (diff < 400 && Point2(os->last_click_pos).distance_to(ev->get_position()) < 5) {
-
- os->last_click_ms = 0;
- os->last_click_pos = Point2(-100, -100);
- os->last_click_button_index = -1;
- ev->set_doubleclick(true);
- }
-
- } else {
- os->last_click_button_index = ev->get_button_index();
- }
-
- if (!ev->is_doubleclick()) {
- os->last_click_ms += diff;
- os->last_click_pos = ev->get_position();
- }
- }
-
- int mask = os->input->get_mouse_button_mask();
- int button_flag = 1 << (ev->get_button_index() - 1);
- if (ev->is_pressed()) {
- // Since the event is consumed, focus manually. The containing iframe,
- // if exists, may not have focus yet, so focus even if already focused.
- focus_canvas();
- mask |= button_flag;
- } else if (mask & button_flag) {
- mask &= ~button_flag;
- } else {
- // Received release event, but press was outside the canvas, so ignore.
- return false;
- }
- ev->set_button_mask(mask);
-
- os->input->parse_input_event(ev);
- // Resume audio context after input in case autoplay was denied.
- os->audio_driver_javascript.resume();
- // Prevent multi-click text selection and wheel-click scrolling anchor.
- // Context menu is prevented through contextmenu event.
- return true;
-}
-
-EM_BOOL OS_JavaScript::mousemove_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data) {
-
- OS_JavaScript *os = get_singleton();
-
- int input_mask = os->input->get_mouse_button_mask();
- Point2 pos = compute_position_in_canvas(p_event->clientX, p_event->clientY);
- // For motion outside the canvas, only read mouse movement if dragging
- // started inside the canvas; imitating desktop app behaviour.
- if (!cursor_inside_canvas && !input_mask)
- return false;
-
- Ref<InputEventMouseMotion> ev;
- ev.instance();
- dom2godot_mod(p_event, ev);
- ev->set_button_mask(input_mask);
-
- ev->set_position(pos);
- ev->set_global_position(ev->get_position());
-
- ev->set_relative(Vector2(p_event->movementX, p_event->movementY));
- os->input->set_mouse_position(ev->get_position());
- ev->set_speed(os->input->get_last_mouse_speed());
-
- os->input->parse_input_event(ev);
- // Don't suppress mouseover/-leave events.
- return false;
-}
-
-static const char *godot2dom_cursor(OS::CursorShape p_shape) {
-
- switch (p_shape) {
- case OS::CURSOR_ARROW:
- default:
- return "auto";
- case OS::CURSOR_IBEAM: return "text";
- case OS::CURSOR_POINTING_HAND: return "pointer";
- case OS::CURSOR_CROSS: return "crosshair";
- case OS::CURSOR_WAIT: return "progress";
- case OS::CURSOR_BUSY: return "wait";
- case OS::CURSOR_DRAG: return "grab";
- case OS::CURSOR_CAN_DROP: return "grabbing";
- case OS::CURSOR_FORBIDDEN: return "no-drop";
- case OS::CURSOR_VSIZE: return "ns-resize";
- case OS::CURSOR_HSIZE: return "ew-resize";
- case OS::CURSOR_BDIAGSIZE: return "nesw-resize";
- case OS::CURSOR_FDIAGSIZE: return "nwse-resize";
- case OS::CURSOR_MOVE: return "move";
- case OS::CURSOR_VSPLIT: return "row-resize";
- case OS::CURSOR_HSPLIT: return "col-resize";
- case OS::CURSOR_HELP: return "help";
- }
-}
-
-static void set_css_cursor(const char *p_cursor) {
-
- /* clang-format off */
- EM_ASM_({
- Module.canvas.style.cursor = UTF8ToString($0);
- }, p_cursor);
- /* clang-format on */
-}
-
-static bool is_css_cursor_hidden() {
-
- /* clang-format off */
- return EM_ASM_INT({
- return Module.canvas.style.cursor === 'none';
- });
- /* clang-format on */
-}
-
-void OS_JavaScript::set_cursor_shape(CursorShape p_shape) {
-
- ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
-
- if (get_mouse_mode() == MOUSE_MODE_VISIBLE) {
- if (cursors[p_shape] != "") {
- Vector<String> url = cursors[p_shape].split("?");
- set_css_cursor(("url(\"" + url[0] + "\") " + url[1] + ", auto").utf8());
- } else {
- set_css_cursor(godot2dom_cursor(p_shape));
- }
- }
-
- cursor_shape = p_shape;
-}
-
-void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
-
- if (p_cursor.is_valid()) {
-
- Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape);
-
- if (cursor_c) {
- if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) {
- set_cursor_shape(p_shape);
- return;
- }
-
- cursors_cache.erase(p_shape);
- }
-
- Ref<Texture2D> texture = p_cursor;
- Ref<AtlasTexture> atlas_texture = p_cursor;
- Ref<Image> image;
- Size2 texture_size;
- Rect2 atlas_rect;
-
- if (texture.is_valid()) {
- image = texture->get_data();
- if (image.is_valid()) {
- image->duplicate();
- }
- }
-
- if (!image.is_valid() && atlas_texture.is_valid()) {
- texture = atlas_texture->get_atlas();
-
- atlas_rect.size.width = texture->get_width();
- atlas_rect.size.height = texture->get_height();
- atlas_rect.position.x = atlas_texture->get_region().position.x;
- atlas_rect.position.y = atlas_texture->get_region().position.y;
-
- texture_size.width = atlas_texture->get_region().size.x;
- texture_size.height = atlas_texture->get_region().size.y;
- } else if (image.is_valid()) {
- texture_size.width = texture->get_width();
- texture_size.height = texture->get_height();
- }
-
- ERR_FAIL_COND(!texture.is_valid());
- ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0);
- ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
- ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
-
- image = texture->get_data();
-
- ERR_FAIL_COND(!image.is_valid());
-
- image = image->duplicate();
-
- if (atlas_texture.is_valid())
- image->crop_from_point(
- atlas_rect.position.x,
- atlas_rect.position.y,
- texture_size.width,
- texture_size.height);
-
- if (image->get_format() != Image::FORMAT_RGBA8) {
- image->convert(Image::FORMAT_RGBA8);
- }
-
- png_image png_meta;
- memset(&png_meta, 0, sizeof png_meta);
- png_meta.version = PNG_IMAGE_VERSION;
- png_meta.width = texture_size.width;
- png_meta.height = texture_size.height;
- png_meta.format = PNG_FORMAT_RGBA;
-
- PackedByteArray png;
- size_t len;
- PackedByteArray data = image->get_data();
- ERR_FAIL_COND(!png_image_write_get_memory_size(png_meta, len, 0, data.ptr(), 0, nullptr));
-
- png.resize(len);
- ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, png.ptrw(), &len, 0, data.ptr(), 0, nullptr));
-
- char *object_url;
- /* clang-format off */
- EM_ASM({
- var PNG_PTR = $0;
- var PNG_LEN = $1;
- var PTR = $2;
-
- var png = new Blob([HEAPU8.slice(PNG_PTR, PNG_PTR + PNG_LEN)], { type: 'image/png' });
- var url = URL.createObjectURL(png);
- var length_bytes = lengthBytesUTF8(url) + 1;
- var string_on_wasm_heap = _malloc(length_bytes);
- setValue(PTR, string_on_wasm_heap, '*');
- stringToUTF8(url, string_on_wasm_heap, length_bytes);
- }, png.ptr(), len, &object_url);
- /* clang-format on */
-
- String url = String::utf8(object_url) + "?" + itos(p_hotspot.x) + " " + itos(p_hotspot.y);
-
- /* clang-format off */
- EM_ASM({ _free($0); }, object_url);
- /* clang-format on */
-
- if (cursors[p_shape] != "") {
- /* clang-format off */
- EM_ASM({
- URL.revokeObjectURL(UTF8ToString($0).split('?')[0]);
- }, cursors[p_shape].utf8().get_data());
- /* clang-format on */
- cursors[p_shape] = "";
- }
-
- cursors[p_shape] = url;
-
- Vector<Variant> params;
- params.push_back(p_cursor);
- params.push_back(p_hotspot);
- cursors_cache.insert(p_shape, params);
-
- } else if (cursors[p_shape] != "") {
- /* clang-format off */
- EM_ASM({
- URL.revokeObjectURL(UTF8ToString($0).split('?')[0]);
- }, cursors[p_shape].utf8().get_data());
- /* clang-format on */
- cursors[p_shape] = "";
-
- cursors_cache.erase(p_shape);
- }
-
- set_cursor_shape(cursor_shape);
-}
-
-void OS_JavaScript::set_mouse_mode(OS::MouseMode p_mode) {
-
- ERR_FAIL_COND_MSG(p_mode == MOUSE_MODE_CONFINED, "MOUSE_MODE_CONFINED is not supported for the HTML5 platform.");
- if (p_mode == get_mouse_mode())
- return;
-
- if (p_mode == MOUSE_MODE_VISIBLE) {
-
- // set_css_cursor must be called before set_cursor_shape to make the cursor visible
- set_css_cursor(godot2dom_cursor(cursor_shape));
- set_cursor_shape(cursor_shape);
- emscripten_exit_pointerlock();
-
- } else if (p_mode == MOUSE_MODE_HIDDEN) {
-
- set_css_cursor("none");
- emscripten_exit_pointerlock();
-
- } else if (p_mode == MOUSE_MODE_CAPTURED) {
-
- EMSCRIPTEN_RESULT result = emscripten_request_pointerlock("canvas", false);
- ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback.");
- ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback.");
- // set_css_cursor must be called before set_cursor_shape to make the cursor visible
- set_css_cursor(godot2dom_cursor(cursor_shape));
- set_cursor_shape(cursor_shape);
- }
-}
-
-OS::MouseMode OS_JavaScript::get_mouse_mode() const {
-
- if (is_css_cursor_hidden())
- return MOUSE_MODE_HIDDEN;
-
- EmscriptenPointerlockChangeEvent ev;
- emscripten_get_pointerlock_status(&ev);
- return (ev.isActive && String::utf8(ev.id) == "canvas") ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE;
-}
-
-// Wheel
-
-EM_BOOL OS_JavaScript::wheel_callback(int p_event_type, const EmscriptenWheelEvent *p_event, void *p_user_data) {
-
- ERR_FAIL_COND_V(p_event_type != EMSCRIPTEN_EVENT_WHEEL, false);
- if (!is_canvas_focused()) {
- if (cursor_inside_canvas) {
- focus_canvas();
- } else {
- return false;
- }
- }
-
- InputDefault *input = get_singleton()->input;
- Ref<InputEventMouseButton> ev;
- ev.instance();
- ev->set_position(input->get_mouse_position());
- ev->set_global_position(ev->get_position());
-
- ev->set_shift(input->is_key_pressed(KEY_SHIFT));
- ev->set_alt(input->is_key_pressed(KEY_ALT));
- ev->set_control(input->is_key_pressed(KEY_CONTROL));
- ev->set_metakey(input->is_key_pressed(KEY_META));
-
- if (p_event->deltaY < 0)
- ev->set_button_index(BUTTON_WHEEL_UP);
- else if (p_event->deltaY > 0)
- ev->set_button_index(BUTTON_WHEEL_DOWN);
- else if (p_event->deltaX > 0)
- ev->set_button_index(BUTTON_WHEEL_LEFT);
- else if (p_event->deltaX < 0)
- ev->set_button_index(BUTTON_WHEEL_RIGHT);
- else
- return false;
-
- // Different browsers give wildly different delta values, and we can't
- // interpret deltaMode, so use default value for wheel events' factor.
-
- int button_flag = 1 << (ev->get_button_index() - 1);
-
- ev->set_pressed(true);
- ev->set_button_mask(input->get_mouse_button_mask() | button_flag);
- input->parse_input_event(ev);
-
- ev->set_pressed(false);
- ev->set_button_mask(input->get_mouse_button_mask() & ~button_flag);
- input->parse_input_event(ev);
-
- return true;
-}
-
-// Touch
-
bool OS_JavaScript::has_touchscreen_ui_hint() const {
-
/* clang-format off */
return EM_ASM_INT_V(
return 'ontouchstart' in window;
@@ -699,352 +54,53 @@ bool OS_JavaScript::has_touchscreen_ui_hint() const {
/* clang-format on */
}
-EM_BOOL OS_JavaScript::touch_press_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data) {
-
- OS_JavaScript *os = get_singleton();
- Ref<InputEventScreenTouch> ev;
- ev.instance();
- int lowest_id_index = -1;
- for (int i = 0; i < p_event->numTouches; ++i) {
-
- const EmscriptenTouchPoint &touch = p_event->touches[i];
- if (lowest_id_index == -1 || touch.identifier < p_event->touches[lowest_id_index].identifier)
- lowest_id_index = i;
- if (!touch.isChanged)
- continue;
- ev->set_index(touch.identifier);
- ev->set_position(compute_position_in_canvas(touch.clientX, touch.clientY));
- os->touches[i] = ev->get_position();
- ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_TOUCHSTART);
-
- os->input->parse_input_event(ev);
- }
- // Resume audio context after input in case autoplay was denied.
- os->audio_driver_javascript.resume();
- return true;
-}
-
-EM_BOOL OS_JavaScript::touchmove_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data) {
-
- OS_JavaScript *os = get_singleton();
- Ref<InputEventScreenDrag> ev;
- ev.instance();
- int lowest_id_index = -1;
- for (int i = 0; i < p_event->numTouches; ++i) {
-
- const EmscriptenTouchPoint &touch = p_event->touches[i];
- if (lowest_id_index == -1 || touch.identifier < p_event->touches[lowest_id_index].identifier)
- lowest_id_index = i;
- if (!touch.isChanged)
- continue;
- ev->set_index(touch.identifier);
- ev->set_position(compute_position_in_canvas(touch.clientX, touch.clientY));
- Point2 &prev = os->touches[i];
- ev->set_relative(ev->get_position() - prev);
- prev = ev->get_position();
-
- os->input->parse_input_event(ev);
- }
- return true;
-}
-
-// Gamepad
-
-EM_BOOL OS_JavaScript::gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data) {
-
- InputDefault *input = get_singleton()->input;
- if (p_event_type == EMSCRIPTEN_EVENT_GAMEPADCONNECTED) {
-
- String guid = "";
- if (String::utf8(p_event->mapping) == "standard")
- guid = "Default HTML5 Gamepad";
- input->joy_connection_changed(p_event->index, true, String::utf8(p_event->id), guid);
- } else {
- input->joy_connection_changed(p_event->index, false, "");
- }
- return true;
-}
-
-void OS_JavaScript::process_joypads() {
-
- int joypad_count = emscripten_get_num_gamepads();
- for (int joypad = 0; joypad < joypad_count; joypad++) {
- EmscriptenGamepadEvent state;
- EMSCRIPTEN_RESULT query_result = emscripten_get_gamepad_status(joypad, &state);
- // Chromium reserves gamepads slots, so NO_DATA is an expected result.
- ERR_CONTINUE(query_result != EMSCRIPTEN_RESULT_SUCCESS &&
- query_result != EMSCRIPTEN_RESULT_NO_DATA);
- if (query_result == EMSCRIPTEN_RESULT_SUCCESS && state.connected) {
-
- int button_count = MIN(state.numButtons, 18);
- int axis_count = MIN(state.numAxes, 8);
- for (int button = 0; button < button_count; button++) {
-
- float value = state.analogButton[button];
- if (String::utf8(state.mapping) == "standard" && (button == JOY_ANALOG_L2 || button == JOY_ANALOG_R2)) {
- InputDefault::JoyAxis joy_axis;
- joy_axis.min = 0;
- joy_axis.value = value;
- input->joy_axis(joypad, button, joy_axis);
- } else {
- input->joy_button(joypad, button, value);
- }
- }
- for (int axis = 0; axis < axis_count; axis++) {
-
- InputDefault::JoyAxis joy_axis;
- joy_axis.min = -1;
- joy_axis.value = state.axis[axis];
- input->joy_axis(joypad, axis, joy_axis);
- }
- }
- }
-}
-
-bool OS_JavaScript::is_joy_known(int p_device) {
-
- return input->is_joy_mapped(p_device);
-}
-
-String OS_JavaScript::get_joy_guid(int p_device) const {
-
- return input->get_joy_guid_remapped(p_device);
-}
-
-// Video
-
-int OS_JavaScript::get_video_driver_count() const {
-
- return VIDEO_DRIVER_MAX;
-}
-
-const char *OS_JavaScript::get_video_driver_name(int p_driver) const {
-
- switch (p_driver) {
- case VIDEO_DRIVER_GLES2:
- return "GLES2";
- }
- ERR_FAIL_V_MSG(nullptr, "Invalid video driver index: " + itos(p_driver) + ".");
-}
-
// Audio
int OS_JavaScript::get_audio_driver_count() const {
-
return 1;
}
const char *OS_JavaScript::get_audio_driver_name(int p_driver) const {
-
return "JavaScript";
}
-// Clipboard
-extern "C" EMSCRIPTEN_KEEPALIVE void update_clipboard(const char *p_text) {
- // Only call set_clipboard from OS (sets local clipboard)
- OS::get_singleton()->OS::set_clipboard(p_text);
-}
-
-void OS_JavaScript::set_clipboard(const String &p_text) {
- OS::set_clipboard(p_text);
- /* clang-format off */
- int err = EM_ASM_INT({
- var text = UTF8ToString($0);
- if (!navigator.clipboard || !navigator.clipboard.writeText)
- return 1;
- navigator.clipboard.writeText(text).catch(function(e) {
- // Setting OS clipboard is only possible from an input callback.
- console.error("Setting OS clipboard is only possible from an input callback for the HTML5 plafrom. Exception:", e);
- });
- return 0;
- }, p_text.utf8().get_data());
- /* clang-format on */
- ERR_FAIL_COND_MSG(err, "Clipboard API is not supported.");
-}
-
-String OS_JavaScript::get_clipboard() const {
- /* clang-format off */
- EM_ASM({
- try {
- navigator.clipboard.readText().then(function (result) {
- ccall('update_clipboard', 'void', ['string'], [result]);
- }).catch(function (e) {
- // Fail graciously.
- });
- } catch (e) {
- // Fail graciously.
- }
- });
- /* clang-format on */
- return this->OS::get_clipboard();
-}
-
// Lifecycle
-int OS_JavaScript::get_current_video_driver() const {
- return video_driver_index;
-}
-
-void OS_JavaScript::initialize_core() {
-
+void OS_JavaScript::initialize() {
OS_Unix::initialize_core();
FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix>>(FileAccess::ACCESS_RESOURCES);
-}
-
-Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
-
-#if 0
- EmscriptenWebGLContextAttributes attributes;
- emscripten_webgl_init_context_attributes(&attributes);
- attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed");
- attributes.antialias = false;
- ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER);
-
- if (p_desired.layered) {
- set_window_per_pixel_transparency_enabled(true);
- }
+ DisplayServerJavaScript::register_javascript_driver();
- bool gl_initialization_error = false;
-
- if (RasterizerGLES2::is_viable() == OK) {
- attributes.majorVersion = 1;
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } else {
- gl_initialization_error = true;
- }
-
- EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(GODOT_CANVAS_SELECTOR, &attributes);
- if (emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS) {
- gl_initialization_error = true;
- }
-
- if (gl_initialization_error) {
- OS::get_singleton()->alert("Your browser does not seem to support WebGL. Please update your browser version.",
- "Unable to initialize video driver");
- return ERR_UNAVAILABLE;
- }
-
- video_driver_index = p_video_driver;
-
- video_mode = p_desired;
- // fullscreen_change_callback will correct this if the request is successful.
- video_mode.fullscreen = false;
- // Emscripten only attempts fullscreen requests if the user input callback
- // was registered through one its own functions, so request manually for
- // start-up fullscreen.
- if (p_desired.fullscreen) {
- /* clang-format off */
- EM_ASM({
- const canvas = Module.canvas;
- (canvas.requestFullscreen || canvas.msRequestFullscreen ||
- canvas.mozRequestFullScreen || canvas.mozRequestFullscreen ||
- canvas.webkitRequestFullscreen
- ).call(canvas);
- });
- /* clang-format on */
- }
- /* clang-format off */
- if (EM_ASM_INT_V({ return Module.resizeCanvasOnStart })) {
- /* clang-format on */
- set_window_size(Size2(video_mode.width, video_mode.height));
- } else {
- set_window_size(get_window_size());
- }
+#ifdef MODULE_WEBSOCKET_ENABLED
+ EngineDebugger::register_uri_handler("ws://", RemoteDebuggerPeerWebSocket::create);
+ EngineDebugger::register_uri_handler("wss://", RemoteDebuggerPeerWebSocket::create);
#endif
- RasterizerDummy::make_current(); // TODO GLES2 in Godot 4.0... or webgpu?
char locale_ptr[16];
/* clang-format off */
- EM_ASM_ARGS({
- stringToUTF8(Module.locale, $0, 16);
+ EM_ASM({
+ stringToUTF8(Module['locale'], $0, 16);
}, locale_ptr);
/* clang-format on */
setenv("LANG", locale_ptr, true);
+}
- AudioDriverManager::initialize(p_audio_driver);
- RenderingServer *rendering_server = memnew(RenderingServerRaster());
- input = memnew(InputDefault);
-
- EMSCRIPTEN_RESULT result;
-#define EM_CHECK(ev) \
- if (result != EMSCRIPTEN_RESULT_SUCCESS) \
- ERR_PRINT("Error while setting " #ev " callback: Code " + itos(result));
-#define SET_EM_CALLBACK(target, ev, cb) \
- result = emscripten_set_##ev##_callback(target, nullptr, true, &cb); \
- EM_CHECK(ev)
-#define SET_EM_CALLBACK_NOTARGET(ev, cb) \
- result = emscripten_set_##ev##_callback(nullptr, true, &cb); \
- EM_CHECK(ev)
- // These callbacks from Emscripten's html5.h suffice to access most
- // JavaScript APIs. For APIs that are not (sufficiently) exposed, EM_ASM
- // is used below.
- SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, mousemove, mousemove_callback)
- SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, mousedown, mouse_button_callback)
- SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, mouseup, mouse_button_callback)
- SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, wheel, wheel_callback)
- SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, touchstart, touch_press_callback)
- SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, touchmove, touchmove_callback)
- SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, touchend, touch_press_callback)
- SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, touchcancel, touch_press_callback)
- SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, keydown, keydown_callback)
- SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, keypress, keypress_callback)
- SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, keyup, keyup_callback)
- SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, fullscreenchange, fullscreen_change_callback)
- SET_EM_CALLBACK_NOTARGET(gamepadconnected, gamepad_change_callback)
- SET_EM_CALLBACK_NOTARGET(gamepaddisconnected, gamepad_change_callback)
-#undef SET_EM_CALLBACK_NOTARGET
-#undef SET_EM_CALLBACK
-#undef EM_CHECK
-
- /* clang-format off */
- EM_ASM_ARGS({
- const send_notification = cwrap('send_notification', null, ['number']);
- const notifications = arguments;
- (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, index) {
- Module.canvas.addEventListener(event, send_notification.bind(null, notifications[index]));
- });
- // Clipboard
- const update_clipboard = cwrap('update_clipboard', null, ['string']);
- window.addEventListener('paste', function(evt) {
- update_clipboard(evt.clipboardData.getData('text'));
- }, true);
- },
- NOTIFICATION_WM_MOUSE_ENTER,
- NOTIFICATION_WM_MOUSE_EXIT,
- NOTIFICATION_WM_FOCUS_IN,
- NOTIFICATION_WM_FOCUS_OUT
- );
- /* clang-format on */
-
- rendering_server->init();
-
- return OK;
+void OS_JavaScript::resume_audio() {
+ audio_driver_javascript.resume();
}
void OS_JavaScript::set_main_loop(MainLoop *p_main_loop) {
-
main_loop = p_main_loop;
- input->set_main_loop(p_main_loop);
}
MainLoop *OS_JavaScript::get_main_loop() const {
-
return main_loop;
}
-void OS_JavaScript::run_async() {
-
- main_loop->init();
- emscripten_set_main_loop(main_loop_callback, -1, false);
-}
-
void OS_JavaScript::main_loop_callback() {
-
get_singleton()->main_loop_iterate();
}
bool OS_JavaScript::main_loop_iterate() {
-
if (is_userfs_persistent() && sync_wait_time >= 0) {
int64_t current_time = get_ticks_msec();
int64_t elapsed_time = current_time - last_sync_check_time;
@@ -1063,72 +119,59 @@ bool OS_JavaScript::main_loop_iterate() {
}
}
- if (emscripten_sample_gamepad_data() == EMSCRIPTEN_RESULT_SUCCESS)
- process_joypads();
-
- if (just_exited_fullscreen) {
- if (window_maximized) {
- EmscriptenFullscreenStrategy strategy;
- strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
- strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
- strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
- strategy.canvasResizedCallback = nullptr;
- emscripten_enter_soft_fullscreen(GODOT_CANVAS_SELECTOR, &strategy);
- } else {
- emscripten_set_canvas_element_size(GODOT_CANVAS_SELECTOR, windowed_size.width, windowed_size.height);
- }
- just_exited_fullscreen = false;
- }
-
- int canvas[2];
- emscripten_get_canvas_element_size(GODOT_CANVAS_SELECTOR, canvas, canvas + 1);
- video_mode.width = canvas[0];
- video_mode.height = canvas[1];
- if (!window_maximized && !video_mode.fullscreen && !just_exited_fullscreen && !entering_fullscreen) {
- windowed_size.width = canvas[0];
- windowed_size.height = canvas[1];
- }
+ DisplayServer::get_singleton()->process_events();
return Main::iteration();
}
void OS_JavaScript::delete_main_loop() {
+ if (main_loop) {
+ memdelete(main_loop);
+ }
+ main_loop = nullptr;
+}
- memdelete(main_loop);
+void OS_JavaScript::finalize_async() {
+ finalizing = true;
+ audio_driver_javascript.finish_async();
}
void OS_JavaScript::finalize() {
-
- memdelete(input);
+ delete_main_loop();
}
// Miscellaneous
Error OS_JavaScript::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
-
- ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "OS::execute() is not available on the HTML5 platform.");
+ Array args;
+ for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
+ args.push_back(E->get());
+ }
+ String json_args = JSON::print(args);
+ /* clang-format off */
+ int failed = EM_ASM_INT({
+ const json_args = UTF8ToString($0);
+ const args = JSON.parse(json_args);
+ if (Module["onExecute"]) {
+ Module["onExecute"](args);
+ return 0;
+ }
+ return 1;
+ }, json_args.utf8().get_data());
+ /* clang-format on */
+ ERR_FAIL_COND_V_MSG(failed, ERR_UNAVAILABLE, "OS::execute() must be implemented in JavaScript via 'engine.setOnExecute' if required.");
+ return OK;
}
Error OS_JavaScript::kill(const ProcessID &p_pid) {
-
ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "OS::kill() is not available on the HTML5 platform.");
}
int OS_JavaScript::get_process_id() const {
-
ERR_FAIL_V_MSG(0, "OS::get_process_id() is not available on the HTML5 platform.");
}
-extern "C" EMSCRIPTEN_KEEPALIVE void send_notification(int p_notification) {
-
- if (p_notification == NOTIFICATION_WM_MOUSE_ENTER || p_notification == NOTIFICATION_WM_MOUSE_EXIT) {
- cursor_inside_canvas = p_notification == NOTIFICATION_WM_MOUSE_ENTER;
- }
- OS_JavaScript::get_singleton()->get_main_loop()->notification(p_notification);
-}
-
bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) {
-
if (p_feature == "HTML5" || p_feature == "web")
return true;
@@ -1140,79 +183,11 @@ bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) {
return false;
}
-void OS_JavaScript::alert(const String &p_alert, const String &p_title) {
-
- /* clang-format off */
- EM_ASM_({
- window.alert(UTF8ToString($0));
- }, p_alert.utf8().get_data());
- /* clang-format on */
-}
-
-void OS_JavaScript::set_window_title(const String &p_title) {
-
- /* clang-format off */
- EM_ASM_({
- document.title = UTF8ToString($0);
- }, p_title.utf8().get_data());
- /* clang-format on */
-}
-
-void OS_JavaScript::set_icon(const Ref<Image> &p_icon) {
-
- ERR_FAIL_COND(p_icon.is_null());
- Ref<Image> icon = p_icon;
- if (icon->is_compressed()) {
- icon = icon->duplicate();
- ERR_FAIL_COND(icon->decompress() != OK);
- }
- if (icon->get_format() != Image::FORMAT_RGBA8) {
- if (icon == p_icon)
- icon = icon->duplicate();
- icon->convert(Image::FORMAT_RGBA8);
- }
-
- png_image png_meta;
- memset(&png_meta, 0, sizeof png_meta);
- png_meta.version = PNG_IMAGE_VERSION;
- png_meta.width = icon->get_width();
- png_meta.height = icon->get_height();
- png_meta.format = PNG_FORMAT_RGBA;
-
- PackedByteArray png;
- size_t len;
- PackedByteArray data = icon->get_data();
- ERR_FAIL_COND(!png_image_write_get_memory_size(png_meta, len, 0, data.ptr(), 0, nullptr));
-
- png.resize(len);
- ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, png.ptrw(), &len, 0, data.ptr(), 0, nullptr));
-
- /* clang-format off */
- EM_ASM_ARGS({
- var PNG_PTR = $0;
- var PNG_LEN = $1;
-
- var png = new Blob([HEAPU8.slice(PNG_PTR, PNG_PTR + PNG_LEN)], { type: "image/png" });
- var url = URL.createObjectURL(png);
- var link = document.getElementById('-gd-engine-icon');
- if (link === null) {
- link = document.createElement('link');
- link.rel = 'icon';
- link.id = '-gd-engine-icon';
- document.head.appendChild(link);
- }
- link.href = url;
- }, png.ptr(), len);
- /* clang-format on */
-}
-
String OS_JavaScript::get_executable_path() const {
-
return OS::get_executable_path();
}
Error OS_JavaScript::shell_open(String p_uri) {
-
// Open URI in a new tab, browser will deal with it by protocol.
/* clang-format off */
EM_ASM_({
@@ -1223,27 +198,30 @@ Error OS_JavaScript::shell_open(String p_uri) {
}
String OS_JavaScript::get_name() const {
-
return "HTML5";
}
bool OS_JavaScript::can_draw() const {
-
return true; // Always?
}
String OS_JavaScript::get_user_data_dir() const {
-
return "/userfs";
};
-String OS_JavaScript::get_resource_dir() const {
+String OS_JavaScript::get_cache_path() const {
+ return "/home/web_user/.cache";
+}
+
+String OS_JavaScript::get_config_path() const {
+ return "/home/web_user/.config";
+}
- return "/";
+String OS_JavaScript::get_data_path() const {
+ return "/home/web_user/.local/share";
}
void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags) {
-
OS_JavaScript *os = get_singleton();
if (os->is_userfs_persistent() && p_file.begins_with("/userfs") && p_flags & FileAccess::WRITE) {
os->last_sync_check_time = OS::get_singleton()->get_ticks_msec();
@@ -1253,42 +231,21 @@ void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags
}
void OS_JavaScript::set_idb_available(bool p_idb_available) {
-
idb_available = p_idb_available;
}
bool OS_JavaScript::is_userfs_persistent() const {
-
return idb_available;
}
OS_JavaScript *OS_JavaScript::get_singleton() {
-
return static_cast<OS_JavaScript *>(OS::get_singleton());
}
-OS_JavaScript::OS_JavaScript(int p_argc, char *p_argv[]) {
-
- List<String> arguments;
- for (int i = 1; i < p_argc; i++) {
- arguments.push_back(String::utf8(p_argv[i]));
- }
- set_cmdline(p_argv[0], arguments);
-
- last_click_button_index = -1;
- last_click_ms = 0;
- last_click_pos = Point2(-100, -100);
-
- window_maximized = false;
- entering_fullscreen = false;
- just_exited_fullscreen = false;
- transparency_enabled = false;
-
- main_loop = nullptr;
-
- idb_available = false;
- sync_wait_time = -1;
+void OS_JavaScript::initialize_joypads() {
+}
+OS_JavaScript::OS_JavaScript() {
AudioDriverManager::add_driver(&audio_driver_javascript);
Vector<Logger *> loggers;
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 81fe4cf0cc..f0f18b44f8 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -32,67 +32,27 @@
#define OS_JAVASCRIPT_H
#include "audio_driver_javascript.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "drivers/unix/os_unix.h"
#include "servers/audio_server.h"
-#include "servers/rendering/rasterizer.h"
#include <emscripten/html5.h>
class OS_JavaScript : public OS_Unix {
-
- VideoMode video_mode;
- Vector2 windowed_size;
- bool window_maximized;
- bool entering_fullscreen;
- bool just_exited_fullscreen;
- bool transparency_enabled;
-
- InputDefault *input;
- Ref<InputEventKey> deferred_key_event;
- CursorShape cursor_shape;
- String cursors[CURSOR_MAX];
- Map<CursorShape, Vector<Variant>> cursors_cache;
- Point2 touches[32];
-
- Point2i last_click_pos;
- double last_click_ms;
- int last_click_button_index;
-
- MainLoop *main_loop;
- int video_driver_index;
+ MainLoop *main_loop = nullptr;
AudioDriverJavaScript audio_driver_javascript;
- bool idb_available;
- int64_t sync_wait_time;
- int64_t last_sync_check_time;
-
- static EM_BOOL fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data);
-
- static EM_BOOL keydown_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
- static EM_BOOL keypress_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
- static EM_BOOL keyup_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
-
- static EM_BOOL mousemove_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data);
- static EM_BOOL mouse_button_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data);
-
- static EM_BOOL wheel_callback(int p_event_type, const EmscriptenWheelEvent *p_event, void *p_user_data);
-
- static EM_BOOL touch_press_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data);
- static EM_BOOL touchmove_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data);
-
- static EM_BOOL gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data);
- void process_joypads();
+ bool finalizing = false;
+ bool idb_available = false;
+ int64_t sync_wait_time = -1;
+ int64_t last_sync_check_time = -1;
static void main_loop_callback();
static void file_access_close_callback(const String &p_file, int p_flags);
protected:
- virtual int get_current_video_driver() const;
-
- virtual void initialize_core();
- virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
+ virtual void initialize();
virtual void set_main_loop(MainLoop *p_main_loop);
virtual void delete_main_loop();
@@ -105,65 +65,38 @@ public:
// Override return type to make writing static callbacks less tedious.
static OS_JavaScript *get_singleton();
- virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0);
- virtual VideoMode get_video_mode(int p_screen = 0) const;
- virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
-
- virtual void set_window_size(const Size2);
- virtual Size2 get_window_size() const;
- virtual void set_window_maximized(bool p_enabled);
- virtual bool is_window_maximized() const;
- virtual void set_window_fullscreen(bool p_enabled);
- virtual bool is_window_fullscreen() const;
- virtual Size2 get_screen_size(int p_screen = -1) const;
-
- virtual Point2 get_mouse_position() const;
- virtual int get_mouse_button_state() const;
- virtual void set_cursor_shape(CursorShape p_shape);
- virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
- virtual void set_mouse_mode(MouseMode p_mode);
- virtual MouseMode get_mouse_mode() const;
-
- virtual bool get_window_per_pixel_transparency_enabled() const;
- virtual void set_window_per_pixel_transparency_enabled(bool p_enabled);
+ virtual void initialize_joypads();
virtual bool has_touchscreen_ui_hint() const;
- virtual bool is_joy_known(int p_device);
- virtual String get_joy_guid(int p_device) const;
-
- virtual int get_video_driver_count() const;
- virtual const char *get_video_driver_name(int p_driver) const;
-
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
- virtual void set_clipboard(const String &p_text);
- virtual String get_clipboard() const;
-
virtual MainLoop *get_main_loop() const;
- void run_async();
+ void finalize_async();
bool main_loop_iterate();
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = nullptr, String *r_pipe = nullptr, int *r_exitcode = nullptr, bool read_stderr = false, Mutex *p_pipe_mutex = nullptr);
virtual Error kill(const ProcessID &p_pid);
virtual int get_process_id() const;
- virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
- virtual void set_window_title(const String &p_title);
- virtual void set_icon(const Ref<Image> &p_icon);
String get_executable_path() const;
virtual Error shell_open(String p_uri);
virtual String get_name() const;
virtual bool can_draw() const;
- virtual String get_resource_dir() const;
+ virtual String get_cache_path() const;
+ virtual String get_config_path() const;
+ virtual String get_data_path() const;
virtual String get_user_data_dir() const;
void set_idb_available(bool p_idb_available);
virtual bool is_userfs_persistent() const;
- OS_JavaScript(int p_argc, char *p_argv[]);
+ void resume_audio();
+ bool is_finalizing() { return finalizing; }
+
+ OS_JavaScript();
};
#endif
diff --git a/platform/linuxbsd/context_gl_x11.cpp b/platform/linuxbsd/context_gl_x11.cpp
index 308d68521a..71dc9602b3 100644
--- a/platform/linuxbsd/context_gl_x11.cpp
+++ b/platform/linuxbsd/context_gl_x11.cpp
@@ -46,22 +46,18 @@
typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLXContext, Bool, const int *);
struct ContextGL_X11_Private {
-
::GLXContext glx_context;
};
void ContextGL_X11::release_current() {
-
glXMakeCurrent(x11_display, None, nullptr);
}
void ContextGL_X11::make_current() {
-
glXMakeCurrent(x11_display, x11_window, p->glx_context);
}
void ContextGL_X11::swap_buffers() {
-
glXSwapBuffers(x11_display, x11_window);
}
@@ -85,7 +81,6 @@ static void set_class_hint(Display *p_display, Window p_window) {
}
Error ContextGL_X11::initialize() {
-
//const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display));
GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte *)"glXCreateContextAttribsARB");
@@ -167,7 +162,6 @@ Error ContextGL_X11::initialize() {
switch (context_type) {
case GLES_2_0_COMPATIBLE: {
-
p->glx_context = glXCreateNewContext(x11_display, fbconfig, GLX_RGBA_TYPE, 0, true);
ERR_FAIL_COND_V(!p->glx_context, ERR_UNCONFIGURED);
} break;
@@ -192,7 +186,6 @@ Error ContextGL_X11::initialize() {
}
int ContextGL_X11::get_window_width() {
-
XWindowAttributes xwa;
XGetWindowAttributes(x11_display, x11_window, &xwa);
@@ -234,14 +227,13 @@ void ContextGL_X11::set_use_vsync(bool p_use) {
return;
use_vsync = p_use;
}
-bool ContextGL_X11::is_using_vsync() const {
+bool ContextGL_X11::is_using_vsync() const {
return use_vsync;
}
ContextGL_X11::ContextGL_X11(::Display *p_x11_display, ::Window &p_x11_window, const OS::VideoMode &p_default_video_mode, ContextType p_context_type) :
x11_window(p_x11_window) {
-
default_video_mode = p_default_video_mode;
x11_display = p_x11_display;
diff --git a/platform/linuxbsd/context_gl_x11.h b/platform/linuxbsd/context_gl_x11.h
index 2c0643c95a..7aed280c98 100644
--- a/platform/linuxbsd/context_gl_x11.h
+++ b/platform/linuxbsd/context_gl_x11.h
@@ -42,7 +42,6 @@
struct ContextGL_X11_Private;
class ContextGL_X11 {
-
public:
enum ContextType {
GLES_2_0_COMPATIBLE,
diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp
index dbdb15918e..b3553e961a 100644
--- a/platform/linuxbsd/crash_handler_linuxbsd.cpp
+++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp
@@ -63,8 +63,9 @@ static void handle_crash(int sig) {
// Dump the backtrace to stderr with a message to the user
fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig);
- if (OS::get_singleton()->get_main_loop())
+ if (OS::get_singleton()->get_main_loop()) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
+ }
fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
char **strings = backtrace_symbols(bt_buffer, size);
@@ -85,8 +86,9 @@ static void handle_crash(int sig) {
snprintf(fname, 1024, "%s", demangled);
}
- if (demangled)
+ if (demangled) {
free(demangled);
+ }
}
}
@@ -128,8 +130,9 @@ CrashHandler::~CrashHandler() {
}
void CrashHandler::disable() {
- if (disabled)
+ if (disabled) {
return;
+ }
#ifdef CRASH_HANDLER_ENABLED
signal(SIGSEGV, nullptr);
diff --git a/platform/linuxbsd/crash_handler_linuxbsd.h b/platform/linuxbsd/crash_handler_linuxbsd.h
index 94b4649690..9bb03579bc 100644
--- a/platform/linuxbsd/crash_handler_linuxbsd.h
+++ b/platform/linuxbsd/crash_handler_linuxbsd.h
@@ -32,7 +32,6 @@
#define CRASH_HANDLER_X11_H
class CrashHandler {
-
bool disabled;
public:
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 5d8b4fba48..07fa06bc06 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -217,15 +217,17 @@ def configure(env):
env.ParseConfig("pkg-config libpng16 --cflags --libs")
if not env["builtin_bullet"]:
- # We need at least version 2.89
+ # We need at least version 2.90
+ min_bullet_version = "2.90"
+
import subprocess
bullet_version = subprocess.check_output(["pkg-config", "bullet", "--modversion"]).strip()
- if str(bullet_version) < "2.89":
+ if str(bullet_version) < min_bullet_version:
# Abort as system bullet was requested but too old
print(
"Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(
- bullet_version, "2.89"
+ bullet_version, min_bullet_version
)
)
sys.exit(255)
diff --git a/platform/linuxbsd/detect_prime_x11.cpp b/platform/linuxbsd/detect_prime_x11.cpp
index 1bec65ff04..1e46d3222d 100644
--- a/platform/linuxbsd/detect_prime_x11.cpp
+++ b/platform/linuxbsd/detect_prime_x11.cpp
@@ -178,7 +178,8 @@ int detect_prime() {
close(fdset[0]);
- if (i) setenv("DRI_PRIME", "1", 1);
+ if (i)
+ setenv("DRI_PRIME", "1", 1);
create_context();
const char *vendor = (const char *)glGetString(GL_VENDOR);
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 78ddef5ff6..ef5ac66b34 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -127,6 +127,7 @@ bool DisplayServerX11::has_feature(Feature p_feature) const {
return false;
}
+
String DisplayServerX11::get_name() const {
return "X11";
}
@@ -148,8 +149,9 @@ void DisplayServerX11::alert(const String &p_alert, const String &p_title) {
}
}
- if (program.length())
+ if (program.length()) {
break;
+ }
}
List<String> args;
@@ -204,11 +206,10 @@ void DisplayServerX11::_update_real_mouse_position(const WindowData &wd) {
if (xquerypointer_result) {
if (win_x > 0 && win_y > 0 && win_x <= wd.size.width && win_y <= wd.size.height) {
-
last_mouse_pos.x = win_x;
last_mouse_pos.y = win_y;
last_mouse_pos_valid = true;
- InputFilter::get_singleton()->set_mouse_position(last_mouse_pos);
+ Input::get_singleton()->set_mouse_position(last_mouse_pos);
}
}
}
@@ -245,22 +246,27 @@ bool DisplayServerX11::_refresh_device_info() {
for (int i = 0; i < dev_count; i++) {
XIDeviceInfo *dev = &info[i];
- if (!dev->enabled)
+ if (!dev->enabled) {
continue;
- if (!(dev->use == XIMasterPointer || dev->use == XIFloatingSlave))
+ }
+ if (!(dev->use == XIMasterPointer || dev->use == XIFloatingSlave)) {
continue;
+ }
bool direct_touch = false;
bool absolute_mode = false;
int resolution_x = 0;
int resolution_y = 0;
- double range_min_x = 0;
- double range_min_y = 0;
- double range_max_x = 0;
- double range_max_y = 0;
- int pressure_resolution = 0;
- int tilt_resolution_x = 0;
- int tilt_resolution_y = 0;
+ double abs_x_min = 0;
+ double abs_x_max = 0;
+ double abs_y_min = 0;
+ double abs_y_max = 0;
+ double pressure_min = 0;
+ double pressure_max = 0;
+ double tilt_x_min = 0;
+ double tilt_x_max = 0;
+ double tilt_y_min = 0;
+ double tilt_y_max = 0;
for (int j = 0; j < dev->num_classes; j++) {
#ifdef TOUCH_ENABLED
if (dev->classes[j]->type == XITouchClass && ((XITouchClassInfo *)dev->classes[j])->mode == XIDirectTouch) {
@@ -272,23 +278,23 @@ bool DisplayServerX11::_refresh_device_info() {
if (class_info->number == VALUATOR_ABSX && class_info->mode == XIModeAbsolute) {
resolution_x = class_info->resolution;
- range_min_x = class_info->min;
- range_max_x = class_info->max;
+ abs_x_min = class_info->min;
+ abs_y_max = class_info->max;
absolute_mode = true;
} else if (class_info->number == VALUATOR_ABSY && class_info->mode == XIModeAbsolute) {
resolution_y = class_info->resolution;
- range_min_y = class_info->min;
- range_max_y = class_info->max;
+ abs_y_min = class_info->min;
+ abs_y_max = class_info->max;
absolute_mode = true;
} else if (class_info->number == VALUATOR_PRESSURE && class_info->mode == XIModeAbsolute) {
- pressure_resolution = (class_info->max - class_info->min);
- if (pressure_resolution == 0) pressure_resolution = 1;
+ pressure_min = class_info->min;
+ pressure_max = class_info->max;
} else if (class_info->number == VALUATOR_TILTX && class_info->mode == XIModeAbsolute) {
- tilt_resolution_x = (class_info->max - class_info->min);
- if (tilt_resolution_x == 0) tilt_resolution_x = 1;
+ tilt_x_min = class_info->min;
+ tilt_x_max = class_info->max;
} else if (class_info->number == VALUATOR_TILTY && class_info->mode == XIModeAbsolute) {
- tilt_resolution_y = (class_info->max - class_info->min);
- if (tilt_resolution_y == 0) tilt_resolution_y = 1;
+ tilt_x_min = class_info->min;
+ tilt_x_max = class_info->max;
}
}
}
@@ -299,18 +305,19 @@ bool DisplayServerX11::_refresh_device_info() {
if (absolute_mode) {
// If no resolution was reported, use the min/max ranges.
if (resolution_x <= 0) {
- resolution_x = (range_max_x - range_min_x) * abs_resolution_range_mult;
+ resolution_x = (abs_x_max - abs_x_min) * abs_resolution_range_mult;
}
if (resolution_y <= 0) {
- resolution_y = (range_max_y - range_min_y) * abs_resolution_range_mult;
+ resolution_y = (abs_y_max - abs_y_min) * abs_resolution_range_mult;
}
-
xi.absolute_devices[dev->deviceid] = Vector2(abs_resolution_mult / resolution_x, abs_resolution_mult / resolution_y);
print_verbose("XInput: Absolute pointing device: " + String(dev->name));
}
xi.pressure = 0;
- xi.pen_devices[dev->deviceid] = Vector3(pressure_resolution, tilt_resolution_x, tilt_resolution_y);
+ xi.pen_pressure_range[dev->deviceid] = Vector2(pressure_min, pressure_max);
+ xi.pen_tilt_x_range[dev->deviceid] = Vector2(tilt_x_min, tilt_x_max);
+ xi.pen_tilt_y_range[dev->deviceid] = Vector2(tilt_y_min, tilt_y_max);
}
XIFreeDeviceInfo(info);
@@ -350,20 +357,20 @@ void DisplayServerX11::_flush_mouse_motion() {
}
void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
-
_THREAD_SAFE_METHOD_
- if (p_mode == mouse_mode)
+ if (p_mode == mouse_mode) {
return;
+ }
- if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED)
+ if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) {
XUngrabPointer(x11_display, CurrentTime);
+ }
// The only modes that show a cursor are VISIBLE and CONFINED
bool showCursor = (p_mode == MOUSE_MODE_VISIBLE || p_mode == MOUSE_MODE_CONFINED);
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
-
if (showCursor) {
XDefineCursor(x11_display, E->get().x11_window, cursors[current_cursor]); // show cursor
} else {
@@ -373,7 +380,6 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
mouse_mode = p_mode;
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) {
-
//flush pending motion events
_flush_mouse_motion();
WindowData &main_window = windows[MAIN_WINDOW_ID];
@@ -392,7 +398,7 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
XWarpPointer(x11_display, None, main_window.x11_window,
0, 0, 0, 0, (int)center.x, (int)center.y);
- InputFilter::get_singleton()->set_mouse_position(center);
+ Input::get_singleton()->set_mouse_position(center);
}
} else {
do_mouse_warp = false;
@@ -400,19 +406,17 @@ void DisplayServerX11::mouse_set_mode(MouseMode p_mode) {
XFlush(x11_display);
}
+
DisplayServerX11::MouseMode DisplayServerX11::mouse_get_mode() const {
return mouse_mode;
}
void DisplayServerX11::mouse_warp_to_position(const Point2i &p_to) {
-
_THREAD_SAFE_METHOD_
if (mouse_mode == MOUSE_MODE_CAPTURED) {
-
last_mouse_pos = p_to;
} else {
-
/*XWindowAttributes xwa;
XGetWindowAttributes(x11_display, x11_window, &xwa);
printf("%d %d\n", xwa.x, xwa.y); needed? */
@@ -447,7 +451,6 @@ int DisplayServerX11::mouse_get_button_state() const {
}
void DisplayServerX11::clipboard_set(const String &p_text) {
-
_THREAD_SAFE_METHOD_
internal_clipboard = p_text;
@@ -456,7 +459,6 @@ void DisplayServerX11::clipboard_set(const String &p_text) {
}
static String _clipboard_get_impl(Atom p_source, Window x11_window, ::Display *x11_display, String p_internal_clipboard, Atom target) {
-
String ret;
Atom type;
@@ -467,7 +469,6 @@ static String _clipboard_get_impl(Atom p_source, Window x11_window, ::Display *x
Window Sown = XGetSelectionOwner(x11_display, p_source);
if (Sown == x11_window) {
-
return p_internal_clipboard;
};
@@ -503,8 +504,9 @@ static String _clipboard_get_impl(Atom p_source, Window x11_window, ::Display *x
&len, &dummy, &data);
if (result == Success) {
ret.parse_utf8((const char *)data);
- } else
+ } else {
printf("FAIL\n");
+ }
if (data) {
XFree(data);
}
@@ -527,7 +529,6 @@ static String _clipboard_get(Atom p_source, Window x11_window, ::Display *x11_di
}
String DisplayServerX11::clipboard_get() const {
-
_THREAD_SAFE_METHOD_
String ret;
@@ -541,21 +542,22 @@ String DisplayServerX11::clipboard_get() const {
}
int DisplayServerX11::get_screen_count() const {
-
_THREAD_SAFE_METHOD_
// Using Xinerama Extension
int event_base, error_base;
const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
- if (!ext_okay) return 0;
+ if (!ext_okay) {
+ return 0;
+ }
int count;
XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
XFree(xsi);
return count;
}
-Point2i DisplayServerX11::screen_get_position(int p_screen) const {
+Point2i DisplayServerX11::screen_get_position(int p_screen) const {
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -596,11 +598,15 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
// Using Xinerama Extension
int event_base, error_base;
const Bool ext_okay = XineramaQueryExtension(x11_display, &event_base, &error_base);
- if (!ext_okay) return Rect2i(0, 0, 0, 0);
+ if (!ext_okay) {
+ return Rect2i(0, 0, 0, 0);
+ }
int count;
XineramaScreenInfo *xsi = XineramaQueryScreens(x11_display, &count);
- if (p_screen >= count) return Rect2i(0, 0, 0, 0);
+ if (p_screen >= count) {
+ return Rect2i(0, 0, 0, 0);
+ }
Rect2i rect = Rect2i(xsi[p_screen].x_org, xsi[p_screen].y_org, xsi[p_screen].width, xsi[p_screen].height);
XFree(xsi);
@@ -608,7 +614,6 @@ Rect2i DisplayServerX11::screen_get_usable_rect(int p_screen) const {
}
int DisplayServerX11::screen_get_dpi(int p_screen) const {
-
_THREAD_SAFE_METHOD_
if (p_screen == SCREEN_OF_MAIN_WINDOW) {
@@ -645,14 +650,15 @@ int DisplayServerX11::screen_get_dpi(int p_screen) const {
int height_mm = DisplayHeightMM(x11_display, p_screen);
double xdpi = (width_mm ? sc.width / (double)width_mm * 25.4 : 0);
double ydpi = (height_mm ? sc.height / (double)height_mm * 25.4 : 0);
- if (xdpi || ydpi)
+ if (xdpi || ydpi) {
return (xdpi + ydpi) / (xdpi && ydpi ? 2 : 1);
+ }
//could not get dpi
return 96;
}
-bool DisplayServerX11::screen_is_touchscreen(int p_screen) const {
+bool DisplayServerX11::screen_is_touchscreen(int p_screen) const {
_THREAD_SAFE_METHOD_
#ifndef _MSC_VER
@@ -673,7 +679,6 @@ Vector<DisplayServer::WindowID> DisplayServerX11::get_window_list() const {
}
DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
-
_THREAD_SAFE_METHOD_
WindowID id = _create_window(p_mode, p_flags, p_rect);
@@ -687,7 +692,6 @@ DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, u
}
void DisplayServerX11::delete_sub_window(WindowID p_id) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_id));
@@ -718,7 +722,6 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) {
}
void DisplayServerX11::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
-
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
@@ -726,19 +729,16 @@ void DisplayServerX11::window_attach_instance_id(ObjectID p_instance, WindowID p
}
ObjectID DisplayServerX11::window_get_attached_instance_id(WindowID p_window) const {
-
ERR_FAIL_COND_V(!windows.has(p_window), ObjectID());
const WindowData &wd = windows[p_window];
return wd.instance_id;
}
DisplayServerX11::WindowID DisplayServerX11::get_window_at_screen_position(const Point2i &p_position) const {
-
return INVALID_WINDOW_ID;
}
void DisplayServerX11::window_set_title(const String &p_title, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -752,7 +752,6 @@ void DisplayServerX11::window_set_title(const String &p_title, WindowID p_window
}
void DisplayServerX11::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -761,7 +760,6 @@ void DisplayServerX11::window_set_rect_changed_callback(const Callable &p_callab
}
void DisplayServerX11::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -770,15 +768,14 @@ void DisplayServerX11::window_set_window_event_callback(const Callable &p_callab
}
void DisplayServerX11::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
wd.input_event_callback = p_callable;
}
-void DisplayServerX11::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerX11::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -787,7 +784,6 @@ void DisplayServerX11::window_set_input_text_callback(const Callable &p_callable
}
void DisplayServerX11::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -796,7 +792,6 @@ void DisplayServerX11::window_set_drop_files_callback(const Callable &p_callable
}
int DisplayServerX11::window_get_current_screen(WindowID p_window) const {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), -1);
@@ -810,20 +805,23 @@ int DisplayServerX11::window_get_current_screen(WindowID p_window) const {
for (int i = 0; i < count; i++) {
Point2i pos = screen_get_position(i);
Size2i size = screen_get_size(i);
- if ((x >= pos.x && x < pos.x + size.width) && (y >= pos.y && y < pos.y + size.height))
+ if ((x >= pos.x && x < pos.x + size.width) && (y >= pos.y && y < pos.y + size.height)) {
return i;
+ }
}
return 0;
}
-void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window) {
+void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
int count = get_screen_count();
- if (p_screen >= count) return;
+ if (p_screen >= count) {
+ return;
+ }
if (window_get_mode(p_window) == WINDOW_MODE_FULLSCREEN) {
Point2i position = screen_get_position(p_screen);
@@ -839,7 +837,6 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window
}
void DisplayServerX11::window_set_transient(WindowID p_window, WindowID p_parent) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(p_window == p_parent);
@@ -875,7 +872,6 @@ void DisplayServerX11::window_set_transient(WindowID p_window, WindowID p_parent
}
Point2i DisplayServerX11::window_get_position(WindowID p_window) const {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Point2i());
@@ -885,7 +881,6 @@ Point2i DisplayServerX11::window_get_position(WindowID p_window) const {
}
void DisplayServerX11::window_set_position(const Point2i &p_position, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -918,7 +913,6 @@ void DisplayServerX11::window_set_position(const Point2i &p_position, WindowID p
}
void DisplayServerX11::window_set_max_size(const Size2i p_size, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -950,8 +944,8 @@ void DisplayServerX11::window_set_max_size(const Size2i p_size, WindowID p_windo
XFlush(x11_display);
}
}
-Size2i DisplayServerX11::window_get_max_size(WindowID p_window) const {
+Size2i DisplayServerX11::window_get_max_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -961,7 +955,6 @@ Size2i DisplayServerX11::window_get_max_size(WindowID p_window) const {
}
void DisplayServerX11::window_set_min_size(const Size2i p_size, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -993,8 +986,8 @@ void DisplayServerX11::window_set_min_size(const Size2i p_size, WindowID p_windo
XFlush(x11_display);
}
}
-Size2i DisplayServerX11::window_get_min_size(WindowID p_window) const {
+Size2i DisplayServerX11::window_get_min_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -1004,7 +997,6 @@ Size2i DisplayServerX11::window_get_min_size(WindowID p_window) const {
}
void DisplayServerX11::window_set_size(const Size2i p_size, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1015,8 +1007,9 @@ void DisplayServerX11::window_set_size(const Size2i p_size, WindowID p_window) {
WindowData &wd = windows[p_window];
- if (wd.size.width == size.width && wd.size.height == size.height)
+ if (wd.size.width == size.width && wd.size.height == size.height) {
return;
+ }
XWindowAttributes xwa;
XSync(x11_display, False);
@@ -1059,22 +1052,23 @@ void DisplayServerX11::window_set_size(const Size2i p_size, WindowID p_window) {
XSync(x11_display, False);
XGetWindowAttributes(x11_display, wd.x11_window, &xwa);
- if (old_w != xwa.width || old_h != xwa.height)
+ if (old_w != xwa.width || old_h != xwa.height) {
break;
+ }
usleep(10000);
}
}
-Size2i DisplayServerX11::window_get_size(WindowID p_window) const {
+Size2i DisplayServerX11::window_get_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
const WindowData &wd = windows[p_window];
return wd.size;
}
-Size2i DisplayServerX11::window_get_real_size(WindowID p_window) const {
+Size2i DisplayServerX11::window_get_real_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -1105,7 +1099,6 @@ Size2i DisplayServerX11::window_get_real_size(WindowID p_window) const {
}
bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), false);
@@ -1140,13 +1133,16 @@ bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const {
bool found_wm_act_max_vert = false;
for (uint64_t i = 0; i < len; i++) {
- if (atoms[i] == wm_act_max_horz)
+ if (atoms[i] == wm_act_max_horz) {
found_wm_act_max_horz = true;
- if (atoms[i] == wm_act_max_vert)
+ }
+ if (atoms[i] == wm_act_max_vert) {
found_wm_act_max_vert = true;
+ }
- if (found_wm_act_max_horz || found_wm_act_max_vert)
+ if (found_wm_act_max_horz || found_wm_act_max_vert) {
return true;
+ }
}
XFree(atoms);
}
@@ -1155,7 +1151,6 @@ bool DisplayServerX11::window_is_maximize_allowed(WindowID p_window) const {
}
void DisplayServerX11::_set_wm_maximized(WindowID p_window, bool p_enabled) {
-
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
@@ -1187,7 +1182,6 @@ void DisplayServerX11::_set_wm_maximized(WindowID p_window, bool p_enabled) {
}
void DisplayServerX11::_set_wm_fullscreen(WindowID p_window, bool p_enabled) {
-
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
@@ -1272,7 +1266,6 @@ void DisplayServerX11::_set_wm_fullscreen(WindowID p_window, bool p_enabled) {
}
void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1333,7 +1326,6 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
} break;
case WINDOW_MODE_MAXIMIZED: {
-
_set_wm_maximized(p_window, false);
} break;
}
@@ -1378,7 +1370,6 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
wd.fullscreen = true;
} break;
case WINDOW_MODE_MAXIMIZED: {
-
_set_wm_maximized(p_window, true);
} break;
@@ -1386,7 +1377,6 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
}
DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) const {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), WINDOW_MODE_WINDOWED);
@@ -1427,10 +1417,12 @@ DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) c
bool found_wm_max_vert = false;
for (uint64_t i = 0; i < len; i++) {
- if (atoms[i] == wm_max_horz)
+ if (atoms[i] == wm_max_horz) {
found_wm_max_horz = true;
- if (atoms[i] == wm_max_vert)
+ }
+ if (atoms[i] == wm_max_vert) {
found_wm_max_vert = true;
+ }
if (found_wm_max_horz && found_wm_max_vert) {
retval = true;
@@ -1485,7 +1477,6 @@ DisplayServer::WindowMode DisplayServerX11::window_get_mode(WindowID p_window) c
}
void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1526,7 +1517,6 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
} break;
case WINDOW_FLAG_BORDERLESS: {
-
Hints hints;
Atom property;
hints.flags = 2;
@@ -1540,7 +1530,6 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
wd.borderless = p_enabled;
} break;
case WINDOW_FLAG_ALWAYS_ON_TOP: {
-
ERR_FAIL_COND_MSG(wd.transient_parent != INVALID_WINDOW_ID, "Can't make a window transient if the 'on top' flag is active.");
if (p_enabled && wd.fullscreen) {
_set_wm_maximized(p_window, true);
@@ -1573,8 +1562,8 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo
}
}
}
-bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
+bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), false);
@@ -1582,15 +1571,12 @@ bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) co
switch (p_flag) {
case WINDOW_FLAG_RESIZE_DISABLED: {
-
return wd.resize_disabled;
} break;
case WINDOW_FLAG_BORDERLESS: {
-
bool borderless = wd.borderless;
Atom prop = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
if (prop != None) {
-
Atom type;
int format;
unsigned long len;
@@ -1608,7 +1594,6 @@ bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) co
return borderless;
} break;
case WINDOW_FLAG_ALWAYS_ON_TOP: {
-
return wd.on_top;
} break;
case WINDOW_FLAG_TRANSPARENT: {
@@ -1622,7 +1607,6 @@ bool DisplayServerX11::window_get_flag(WindowFlags p_flag, WindowID p_window) co
}
void DisplayServerX11::window_request_attention(WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1649,7 +1633,6 @@ void DisplayServerX11::window_request_attention(WindowID p_window) {
}
void DisplayServerX11::window_move_to_foreground(WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1671,12 +1654,11 @@ void DisplayServerX11::window_move_to_foreground(WindowID p_window) {
}
bool DisplayServerX11::window_can_draw(WindowID p_window) const {
-
//this seems to be all that is provided by X11
return window_get_mode(p_window) != WINDOW_MODE_MINIMIZED;
}
-bool DisplayServerX11::can_any_window_draw() const {
+bool DisplayServerX11::can_any_window_draw() const {
_THREAD_SAFE_METHOD_
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
@@ -1689,7 +1671,6 @@ bool DisplayServerX11::can_any_window_draw() const {
}
void DisplayServerX11::window_set_ime_active(const bool p_active, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1697,8 +1678,9 @@ void DisplayServerX11::window_set_ime_active(const bool p_active, WindowID p_win
wd.im_active = p_active;
- if (!wd.xic)
+ if (!wd.xic) {
return;
+ }
if (p_active) {
XSetICFocus(wd.xic);
@@ -1707,8 +1689,8 @@ void DisplayServerX11::window_set_ime_active(const bool p_active, WindowID p_win
XUnsetICFocus(wd.xic);
}
}
-void DisplayServerX11::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
+void DisplayServerX11::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1716,8 +1698,9 @@ void DisplayServerX11::window_set_ime_position(const Point2i &p_pos, WindowID p_
wd.im_position = p_pos;
- if (!wd.xic)
+ if (!wd.xic) {
return;
+ }
::XPoint spot;
spot.x = short(p_pos.x);
@@ -1728,7 +1711,6 @@ void DisplayServerX11::window_set_ime_position(const Point2i &p_pos, WindowID p_
}
void DisplayServerX11::cursor_set_shape(CursorShape p_shape) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
@@ -1751,15 +1733,15 @@ void DisplayServerX11::cursor_set_shape(CursorShape p_shape) {
current_cursor = p_shape;
}
+
DisplayServerX11::CursorShape DisplayServerX11::cursor_get_shape() const {
return current_cursor;
}
-void DisplayServerX11::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+void DisplayServerX11::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
_THREAD_SAFE_METHOD_
if (p_cursor.is_valid()) {
-
Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape);
if (cursor_c) {
@@ -1898,7 +1880,6 @@ DisplayServerX11::LatinKeyboardVariant DisplayServerX11::get_latin_keyboard_vari
}
DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display, Window p_window, Atom p_property) {
-
Atom actual_type;
int actual_format;
unsigned long nitems;
@@ -1910,8 +1891,9 @@ DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display,
//Keep trying to read the property until there are no
//bytes unread.
do {
- if (ret != nullptr)
+ if (ret != nullptr) {
XFree(ret);
+ }
XGetWindowProperty(p_display, p_window, p_property, 0, read_bytes, False, AnyPropertyType,
&actual_type, &actual_format, &nitems, &bytes_after,
@@ -1927,36 +1909,36 @@ DisplayServerX11::Property DisplayServerX11::_read_property(Display *p_display,
}
static Atom pick_target_from_list(Display *p_display, Atom *p_list, int p_count) {
-
static const char *target_type = "text/uri-list";
for (int i = 0; i < p_count; i++) {
-
Atom atom = p_list[i];
- if (atom != None && String(XGetAtomName(p_display, atom)) == target_type)
+ if (atom != None && String(XGetAtomName(p_display, atom)) == target_type) {
return atom;
+ }
}
return None;
}
static Atom pick_target_from_atoms(Display *p_disp, Atom p_t1, Atom p_t2, Atom p_t3) {
-
static const char *target_type = "text/uri-list";
- if (p_t1 != None && String(XGetAtomName(p_disp, p_t1)) == target_type)
+ if (p_t1 != None && String(XGetAtomName(p_disp, p_t1)) == target_type) {
return p_t1;
+ }
- if (p_t2 != None && String(XGetAtomName(p_disp, p_t2)) == target_type)
+ if (p_t2 != None && String(XGetAtomName(p_disp, p_t2)) == target_type) {
return p_t2;
+ }
- if (p_t3 != None && String(XGetAtomName(p_disp, p_t3)) == target_type)
+ if (p_t3 != None && String(XGetAtomName(p_disp, p_t3)) == target_type) {
return p_t3;
+ }
return None;
}
void DisplayServerX11::_get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state) {
-
state->set_shift((p_x11_state & ShiftMask));
state->set_control((p_x11_state & ControlMask));
state->set_alt((p_x11_state & Mod1Mask /*|| p_x11_state&Mod5Mask*/)); //altgr should not count as alt
@@ -1964,7 +1946,6 @@ void DisplayServerX11::_get_key_modifier_state(unsigned int p_x11_state, Ref<Inp
}
unsigned int DisplayServerX11::_get_mouse_button_state(unsigned int p_x11_button, int p_x11_type) {
-
unsigned int mask = 1 << (p_x11_button - 1);
if (p_x11_type == ButtonPress) {
@@ -1977,7 +1958,6 @@ unsigned int DisplayServerX11::_get_mouse_button_state(unsigned int p_x11_button
}
void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event, bool p_echo) {
-
WindowData wd = windows[p_window];
// X11 functions don't know what const is
XKeyEvent *xkeyevent = p_event;
@@ -2021,7 +2001,6 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
}
if (xkeyevent->type == KeyPress && wd.xic) {
-
Status status;
#ifdef X_HAVE_UTF8_STRING
int utf8len = 8;
@@ -2041,8 +2020,9 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode);
unsigned int physical_keycode = KeyMappingX11::get_scancode(xkeyevent->keycode);
- if (keycode >= 'a' && keycode <= 'z')
+ if (keycode >= 'a' && keycode <= 'z') {
keycode -= 'a' - 'A';
+ }
String tmp;
tmp.parse_utf8(utf8string, utf8bytes);
@@ -2077,7 +2057,7 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
k->set_shift(true);
}
- InputFilter::get_singleton()->accumulate_input_event(k);
+ Input::get_singleton()->accumulate_input_event(k);
}
memfree(utf8string);
return;
@@ -2085,7 +2065,6 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
memfree(utf8string);
#else
do {
-
int mnbytes = XmbLookupString(xic, xkeyevent, xmbstring, xmblen - 1, &keysym_unicode, &status);
xmbstring[mnbytes] = '\0';
@@ -2153,7 +2132,6 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
// difference in time is below a threshold.
if (xkeyevent->type != KeyPress) {
-
p_echo = false;
// make sure there are events pending,
@@ -2192,8 +2170,9 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
k->set_pressed(keypress);
- if (keycode >= 'a' && keycode <= 'z')
+ if (keycode >= 'a' && keycode <= 'z') {
keycode -= 'a' - 'A';
+ }
k->set_keycode(keycode);
k->set_physical_keycode(physical_keycode);
@@ -2210,29 +2189,29 @@ void DisplayServerX11::_handle_key_event(WindowID p_window, XKeyEvent *p_event,
//don't set mod state if modifier keys are released by themselves
//else event.is_action() will not work correctly here
if (!k->is_pressed()) {
- if (k->get_keycode() == KEY_SHIFT)
+ if (k->get_keycode() == KEY_SHIFT) {
k->set_shift(false);
- else if (k->get_keycode() == KEY_CONTROL)
+ } else if (k->get_keycode() == KEY_CONTROL) {
k->set_control(false);
- else if (k->get_keycode() == KEY_ALT)
+ } else if (k->get_keycode() == KEY_ALT) {
k->set_alt(false);
- else if (k->get_keycode() == KEY_META)
+ } else if (k->get_keycode() == KEY_META) {
k->set_metakey(false);
+ }
}
- bool last_is_pressed = InputFilter::get_singleton()->is_key_pressed(k->get_keycode());
+ bool last_is_pressed = Input::get_singleton()->is_key_pressed(k->get_keycode());
if (k->is_pressed()) {
if (last_is_pressed) {
k->set_echo(true);
}
}
- InputFilter::get_singleton()->accumulate_input_event(k);
+ Input::get_singleton()->accumulate_input_event(k);
}
void DisplayServerX11::_xim_destroy_callback(::XIM im, ::XPointer client_data,
::XPointer call_data) {
-
WARN_PRINT("Input method stopped");
DisplayServerX11 *ds = reinterpret_cast<DisplayServerX11 *>(client_data);
ds->xim = nullptr;
@@ -2243,7 +2222,6 @@ void DisplayServerX11::_xim_destroy_callback(::XIM im, ::XPointer client_data,
}
void DisplayServerX11::_window_changed(XEvent *event) {
-
WindowID window_id = MAIN_WINDOW_ID;
// Assign the event to the relevant window
@@ -2308,7 +2286,6 @@ void DisplayServerX11::_dispatch_input_events(const Ref<InputEvent> &p_event) {
}
void DisplayServerX11::_dispatch_input_event(const Ref<InputEvent> &p_event) {
-
Variant ev = p_event;
Variant *evp = &ev;
Variant ret;
@@ -2344,8 +2321,8 @@ void DisplayServerX11::_send_window_event(const WindowData &wd, WindowEvent p_ev
wd.event_callback.call((const Variant **)&eventp, 1, ret, ce);
}
}
-void DisplayServerX11::process_events() {
+void DisplayServerX11::process_events() {
_THREAD_SAFE_METHOD_
do_mouse_warp = false;
@@ -2353,6 +2330,10 @@ void DisplayServerX11::process_events() {
// Is the current mouse mode one where it needs to be grabbed.
bool mouse_mode_grab = mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED;
+ xi.pressure = 0;
+ xi.tilt = Vector2();
+ xi.pressure_supported = false;
+
while (XPending(x11_display) > 0) {
XEvent event;
XNextEvent(x11_display, &event);
@@ -2372,9 +2353,7 @@ void DisplayServerX11::process_events() {
}
if (XGetEventData(x11_display, &event.xcookie)) {
-
if (event.xcookie.type == GenericEvent && event.xcookie.extension == xi.opcode) {
-
XIDeviceEvent *event_data = (XIDeviceEvent *)event.xcookie.data;
int index = event_data->detail;
Vector2 pos = Vector2(event_data->event_x, event_data->event_y);
@@ -2399,9 +2378,6 @@ void DisplayServerX11::process_events() {
double rel_x = 0.0;
double rel_y = 0.0;
- double pressure = 0.0;
- double tilt_x = 0.0;
- double tilt_y = 0.0;
if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_ABSX)) {
rel_x = *values;
@@ -2414,24 +2390,41 @@ void DisplayServerX11::process_events() {
}
if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_PRESSURE)) {
- pressure = *values;
+ Map<int, Vector2>::Element *pen_pressure = xi.pen_pressure_range.find(device_id);
+ if (pen_pressure) {
+ Vector2 pen_pressure_range = pen_pressure->value();
+ if (pen_pressure_range != Vector2()) {
+ xi.pressure_supported = true;
+ xi.pressure = (*values - pen_pressure_range[0]) /
+ (pen_pressure_range[1] - pen_pressure_range[0]);
+ }
+ }
+
values++;
}
if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_TILTX)) {
- tilt_x = *values;
+ Map<int, Vector2>::Element *pen_tilt_x = xi.pen_tilt_x_range.find(device_id);
+ if (pen_tilt_x) {
+ Vector2 pen_tilt_x_range = pen_tilt_x->value();
+ if (pen_tilt_x_range != Vector2()) {
+ xi.tilt.x = ((*values - pen_tilt_x_range[0]) / (pen_tilt_x_range[1] - pen_tilt_x_range[0])) * 2 - 1;
+ }
+ }
+
values++;
}
if (XIMaskIsSet(raw_event->valuators.mask, VALUATOR_TILTY)) {
- tilt_y = *values;
- }
+ Map<int, Vector2>::Element *pen_tilt_y = xi.pen_tilt_y_range.find(device_id);
+ if (pen_tilt_y) {
+ Vector2 pen_tilt_y_range = pen_tilt_y->value();
+ if (pen_tilt_y_range != Vector2()) {
+ xi.tilt.y = ((*values - pen_tilt_y_range[0]) / (pen_tilt_y_range[1] - pen_tilt_y_range[0])) * 2 - 1;
+ }
+ }
- Map<int, Vector3>::Element *pen_info = xi.pen_devices.find(device_id);
- if (pen_info) {
- Vector3 mult = pen_info->value();
- if (mult.x != 0.0) xi.pressure = pressure / mult.x;
- if ((mult.y != 0.0) && (mult.z != 0.0)) xi.tilt = Vector2(tilt_x / mult.y, tilt_y / mult.z);
+ values++;
}
// https://bugs.freedesktop.org/show_bug.cgi?id=71609
@@ -2467,7 +2460,6 @@ void DisplayServerX11::process_events() {
//XIAllowTouchEvents(x11_display, event_data->deviceid, event_data->detail, x11_window, XIAcceptTouch);
case XI_TouchEnd: {
-
bool is_begin = event_data->evtype == XI_TouchBegin;
Ref<InputEventScreenTouch> st;
@@ -2478,39 +2470,39 @@ void DisplayServerX11::process_events() {
st->set_pressed(is_begin);
if (is_begin) {
- if (xi.state.has(index)) // Defensive
+ if (xi.state.has(index)) { // Defensive
break;
+ }
xi.state[index] = pos;
if (xi.state.size() == 1) {
// X11 may send a motion event when a touch gesture begins, that would result
// in a spurious mouse motion event being sent to Godot; remember it to be able to filter it out
xi.mouse_pos_to_filter = pos;
}
- InputFilter::get_singleton()->accumulate_input_event(st);
+ Input::get_singleton()->accumulate_input_event(st);
} else {
- if (!xi.state.has(index)) // Defensive
+ if (!xi.state.has(index)) { // Defensive
break;
+ }
xi.state.erase(index);
- InputFilter::get_singleton()->accumulate_input_event(st);
+ Input::get_singleton()->accumulate_input_event(st);
}
} break;
case XI_TouchUpdate: {
-
Map<int, Vector2>::Element *curr_pos_elem = xi.state.find(index);
if (!curr_pos_elem) { // Defensive
break;
}
if (curr_pos_elem->value() != pos) {
-
Ref<InputEventScreenDrag> sd;
sd.instance();
sd->set_window_id(window_id);
sd->set_index(index);
sd->set_position(pos);
sd->set_relative(pos - curr_pos_elem->value());
- InputFilter::get_singleton()->accumulate_input_event(sd);
+ Input::get_singleton()->accumulate_input_event(sd);
curr_pos_elem->value() = pos;
}
@@ -2555,11 +2547,11 @@ void DisplayServerX11::process_events() {
// Show and update the cursor if confined and the window regained focus.
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
-
- if (mouse_mode == MOUSE_MODE_CONFINED)
+ if (mouse_mode == MOUSE_MODE_CONFINED) {
XUndefineCursor(x11_display, E->get().x11_window);
- else if (mouse_mode == MOUSE_MODE_CAPTURED) // or re-hide it in captured mode
+ } else if (mouse_mode == MOUSE_MODE_CAPTURED) { // or re-hide it in captured mode
XDefineCursor(x11_display, E->get().x11_window, null_cursor);
+ }
XGrabPointer(
x11_display, E->get().x11_window, True,
@@ -2580,13 +2572,12 @@ void DisplayServerX11::process_events() {
case FocusOut:
window_has_focus = false;
- InputFilter::get_singleton()->release_pressed_events();
+ Input::get_singleton()->release_pressed_events();
_send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT);
window_focused = false;
if (mouse_mode_grab) {
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
-
//dear X11, I try, I really try, but you never work, you do whathever you want.
if (mouse_mode == MOUSE_MODE_CAPTURED) {
// Show the cursor if we're in captured mode so it doesn't look weird.
@@ -2603,13 +2594,12 @@ void DisplayServerX11::process_events() {
// Release every pointer to avoid sticky points
for (Map<int, Vector2>::Element *E = xi.state.front(); E; E = E->next()) {
-
Ref<InputEventScreenTouch> st;
st.instance();
st->set_index(E->key());
st->set_window_id(window_id);
st->set_position(E->get());
- InputFilter::get_singleton()->accumulate_input_event(st);
+ Input::get_singleton()->accumulate_input_event(st);
}
xi.state.clear();
#endif
@@ -2623,7 +2613,6 @@ void DisplayServerX11::process_events() {
break;
case ButtonPress:
case ButtonRelease: {
-
/* exit in case of a mouse button press */
last_timestamp = event.xbutton.time;
if (mouse_mode == MOUSE_MODE_CAPTURED) {
@@ -2637,10 +2626,11 @@ void DisplayServerX11::process_events() {
mb->set_window_id(window_id);
_get_key_modifier_state(event.xbutton.state, mb);
mb->set_button_index(event.xbutton.button);
- if (mb->get_button_index() == 2)
+ if (mb->get_button_index() == 2) {
mb->set_button_index(3);
- else if (mb->get_button_index() == 3)
+ } else if (mb->get_button_index() == 3) {
mb->set_button_index(2);
+ }
mb->set_button_mask(_get_mouse_button_state(mb->get_button_index(), event.xbutton.type));
mb->set_position(Vector2(event.xbutton.x, event.xbutton.y));
mb->set_global_position(mb->get_position());
@@ -2648,13 +2638,10 @@ void DisplayServerX11::process_events() {
mb->set_pressed((event.type == ButtonPress));
if (event.type == ButtonPress) {
-
uint64_t diff = OS::get_singleton()->get_ticks_usec() / 1000 - last_click_ms;
if (mb->get_button_index() == last_click_button_index) {
-
if (diff < 400 && Vector2(last_click_pos).distance_to(Vector2(event.xbutton.x, event.xbutton.y)) < 5) {
-
last_click_ms = 0;
last_click_pos = Point2i(-100, -100);
last_click_button_index = -1;
@@ -2671,11 +2658,10 @@ void DisplayServerX11::process_events() {
}
}
- InputFilter::get_singleton()->accumulate_input_event(mb);
+ Input::get_singleton()->accumulate_input_event(mb);
} break;
case MotionNotify: {
-
// The X11 API requires filtering one-by-one through the motion
// notify events, in order to figure out which event is the one
// generated by warping the mouse pointer.
@@ -2731,7 +2717,6 @@ void DisplayServerX11::process_events() {
}
if (!last_mouse_pos_valid) {
-
last_mouse_pos = pos;
last_mouse_pos_valid = true;
}
@@ -2763,7 +2748,11 @@ void DisplayServerX11::process_events() {
mm.instance();
mm->set_window_id(window_id);
- mm->set_pressure(xi.pressure);
+ if (xi.pressure_supported) {
+ mm->set_pressure(xi.pressure);
+ } else {
+ mm->set_pressure((mouse_get_button_state() & (1 << (BUTTON_LEFT - 1))) ? 1.0f : 0.0f);
+ }
mm->set_tilt(xi.tilt);
// Make the absolute position integral so it doesn't look _too_ weird :)
@@ -2773,8 +2762,8 @@ void DisplayServerX11::process_events() {
mm->set_button_mask(mouse_get_button_state());
mm->set_position(posi);
mm->set_global_position(posi);
- InputFilter::get_singleton()->set_mouse_position(posi);
- mm->set_speed(InputFilter::get_singleton()->get_last_mouse_speed());
+ Input::get_singleton()->set_mouse_position(posi);
+ mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
mm->set_relative(rel);
@@ -2784,13 +2773,13 @@ void DisplayServerX11::process_events() {
// Don't propagate the motion event unless we have focus
// this is so that the relative motion doesn't get messed up
// after we regain focus.
- if (window_has_focus || !mouse_mode_grab)
- InputFilter::get_singleton()->accumulate_input_event(mm);
+ if (window_has_focus || !mouse_mode_grab) {
+ Input::get_singleton()->accumulate_input_event(mm);
+ }
} break;
case KeyPress:
case KeyRelease: {
-
last_timestamp = event.xkey.time;
// key event is a little complex, so
@@ -2798,7 +2787,6 @@ void DisplayServerX11::process_events() {
_handle_key_event(window_id, (XKeyEvent *)&event);
} break;
case SelectionRequest: {
-
XSelectionRequestEvent *req;
XEvent e, respond;
e = event;
@@ -2821,7 +2809,6 @@ void DisplayServerX11::process_events() {
clip.length());
respond.xselection.property = req->property;
} else if (req->target == XInternAtom(x11_display, "TARGETS", 0)) {
-
Atom data[7];
data[0] = XInternAtom(x11_display, "TARGETS", 0);
data[1] = XInternAtom(x11_display, "UTF8_STRING", 0);
@@ -2844,8 +2831,9 @@ void DisplayServerX11::process_events() {
} else {
char *targetname = XGetAtomName(x11_display, req->target);
printf("No Target '%s'\n", targetname);
- if (targetname)
+ if (targetname) {
XFree(targetname);
+ }
respond.xselection.property = None;
}
@@ -2862,7 +2850,6 @@ void DisplayServerX11::process_events() {
case SelectionNotify:
if (event.xselection.target == requested) {
-
Property p = _read_property(x11_display, windows[window_id].x11_window, XInternAtom(x11_display, "PRIMARY", 0));
Vector<String> files = String((char *)p.data).split("\n", false);
@@ -2901,7 +2888,6 @@ void DisplayServerX11::process_events() {
}
else if ((unsigned int)event.xclient.message_type == (unsigned int)xdnd_enter) {
-
//File(s) have been dragged over the window, check for supported target (text/uri-list)
xdnd_version = (event.xclient.data.l[1] >> 24);
Window source = event.xclient.data.l[0];
@@ -2909,10 +2895,10 @@ void DisplayServerX11::process_events() {
if (more_than_3) {
Property p = _read_property(x11_display, source, XInternAtom(x11_display, "XdndTypeList", False));
requested = pick_target_from_list(x11_display, (Atom *)p.data, p.nitems);
- } else
+ } else {
requested = pick_target_from_atoms(x11_display, event.xclient.data.l[2], event.xclient.data.l[3], event.xclient.data.l[4]);
+ }
} else if ((unsigned int)event.xclient.message_type == (unsigned int)xdnd_position) {
-
//xdnd position event, reply with an XDND status message
//just depending on type of data for now
XClientMessageEvent m;
@@ -2931,13 +2917,13 @@ void DisplayServerX11::process_events() {
XSendEvent(x11_display, event.xclient.data.l[0], False, NoEventMask, (XEvent *)&m);
XFlush(x11_display);
} else if ((unsigned int)event.xclient.message_type == (unsigned int)xdnd_drop) {
-
if (requested != None) {
xdnd_source_window = event.xclient.data.l[0];
- if (xdnd_version >= 1)
+ if (xdnd_version >= 1) {
XConvertSelection(x11_display, xdnd_selection, requested, XInternAtom(x11_display, "PRIMARY", 0), windows[window_id].x11_window, event.xclient.data.l[2]);
- else
+ } else {
XConvertSelection(x11_display, xdnd_selection, requested, XInternAtom(x11_display, "PRIMARY", 0), windows[window_id].x11_window, CurrentTime);
+ }
} else {
//Reply that we're not interested.
XClientMessageEvent m;
@@ -2962,7 +2948,6 @@ void DisplayServerX11::process_events() {
XFlush(x11_display);
if (do_mouse_warp) {
-
XWarpPointer(x11_display, None, windows[MAIN_WINDOW_ID].x11_window,
0, 0, 0, 0, (int)windows[MAIN_WINDOW_ID].size.width / 2, (int)windows[MAIN_WINDOW_ID].size.height / 2);
@@ -2978,7 +2963,7 @@ void DisplayServerX11::process_events() {
*/
}
- InputFilter::get_singleton()->flush_accumulated_events();
+ Input::get_singleton()->flush_accumulated_events();
}
void DisplayServerX11::release_rendering_thread() {
@@ -2994,7 +2979,6 @@ void DisplayServerX11::_update_context(WindowData &wd) {
XClassHint *classHint = XAllocClassHint();
if (classHint) {
-
CharString name_str;
switch (context) {
case CONTEXT_EDITOR:
@@ -3027,8 +3011,8 @@ void DisplayServerX11::_update_context(WindowData &wd) {
XFree(classHint);
}
}
-void DisplayServerX11::set_context(Context p_context) {
+void DisplayServerX11::set_context(Context p_context) {
_THREAD_SAFE_METHOD_
context = p_context;
@@ -3037,6 +3021,7 @@ void DisplayServerX11::set_context(Context p_context) {
_update_context(E->get());
}
}
+
void DisplayServerX11::set_native_icon(const String &p_filename) {
WARN_PRINT("Native icon not supported by this display server.");
}
@@ -3112,8 +3097,9 @@ void DisplayServerX11::set_icon(const Ref<Image> &p_icon) {
XChangeProperty(x11_display, wd.x11_window, net_wm_icon, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)pd.ptr(), pd.size());
- if (!g_set_icon_error)
+ if (!g_set_icon_error) {
break;
+ }
}
} else {
XDeleteProperty(x11_display, wd.x11_window, net_wm_icon);
@@ -3137,12 +3123,10 @@ Vector<String> DisplayServerX11::get_rendering_drivers_func() {
}
DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
-
return memnew(DisplayServerX11(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
}
DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
-
//Create window
long visualMask = VisualScreenMask;
@@ -3224,7 +3208,6 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
XChangeProperty(x11_display, wd.x11_window, xdnd_aware, XA_ATOM, 32, PropModeReplace, (unsigned char *)&xdnd_version, 1);
if (xim && xim_style) {
-
wd.xic = XCreateIC(xim, XNInputStyle, xim_style, XNClientWindow, wd.x11_window, XNFocusWindow, wd.x11_window, (char *)nullptr);
if (XGetICValues(wd.xic, XNFilterEvents, &im_event_mask, nullptr) != nullptr) {
WARN_PRINT("XGetICValues couldn't obtain XNFilterEvents value");
@@ -3237,7 +3220,6 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
WARN_PRINT("XCreateIC couldn't create wd.xic");
}
} else {
-
wd.xic = nullptr;
WARN_PRINT("XCreateIC couldn't create wd.xic");
}
@@ -3249,9 +3231,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
windows[id] = wd;
{
-
if (p_flags & WINDOW_FLAG_RESIZE_DISABLED_BIT) {
-
XSizeHints *xsh;
xsh = XAllocSizeHints();
@@ -3315,7 +3295,6 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
}
if (id != MAIN_WINDOW_ID) {
-
XSizeHints my_hints = XSizeHints();
my_hints.flags = PPosition | PSize; /* I want to specify position and size */
@@ -3365,15 +3344,13 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
//set cursor
if (cursors[current_cursor] != None) {
-
XDefineCursor(x11_display, wd.x11_window, cursors[current_cursor]);
}
return id;
}
DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
-
- InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
+ Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
r_error = OK;
@@ -3381,7 +3358,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
mouse_mode = MOUSE_MODE_VISIBLE;
for (int i = 0; i < CURSOR_MAX; i++) {
-
cursors[i] = None;
img[i] = nullptr;
}
@@ -3416,7 +3392,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
// Try to support IME if detectable auto-repeat is supported
if (xkb_dar == True) {
-
#ifdef X_HAVE_UTF8_STRING
// Xutf8LookupString will be used later instead of XmbLookupString before
// the multibyte sequences can be converted to unicode string.
@@ -3493,10 +3468,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
if (xim_styles) {
xim_style = 0L;
for (int i = 0; i < xim_styles->count_styles; i++) {
-
if (xim_styles->supported_styles[i] ==
(XIMPreeditNothing | XIMStatusNothing)) {
-
xim_style = xim_styles->supported_styles[i];
break;
}
@@ -3531,7 +3504,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
-
context_vulkan = memnew(VulkanContextX11);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
@@ -3553,7 +3525,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
getenv("PRIMUS_libGL") ||
getenv("PRIMUS_LOAD_GLOBAL") ||
getenv("BUMBLEBEE_SOCKET")) {
-
print_verbose("Optirun/primusrun detected. Skipping GPU detection");
use_prime = 0;
}
@@ -3565,7 +3536,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
for (int i = 0; i < libraries.size(); ++i) {
if (FileAccess::exists(libraries[i] + "/libGL.so.1") ||
FileAccess::exists(libraries[i] + "/libGL.so")) {
-
print_verbose("Custom libGL override detected. Skipping GPU detection");
use_prime = 0;
}
@@ -3606,8 +3576,10 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
}
#endif
-
- WindowID main_window = _create_window(p_mode, p_flags, Rect2i(Point2(), p_resolution));
+ Point2i window_position(
+ (screen_get_size(0).width - p_resolution.width) / 2,
+ (screen_get_size(0).height - p_resolution.height) / 2);
+ WindowID main_window = _create_window(p_mode, p_flags, Rect2i(window_position, p_resolution));
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, main_window);
@@ -3617,7 +3589,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
//create RenderingDevice if used
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
-
//temporary
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
@@ -3663,7 +3634,6 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
}
for (int i = 0; i < CURSOR_MAX; i++) {
-
static const char *cursor_file[] = {
"left_ptr",
"xterm",
@@ -3798,8 +3768,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
r_error = OK;
}
-DisplayServerX11::~DisplayServerX11() {
+DisplayServerX11::~DisplayServerX11() {
//destroy all windows
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
#ifdef VULKAN_ENABLED
@@ -3818,25 +3788,28 @@ DisplayServerX11::~DisplayServerX11() {
//destroy drivers
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
-
if (rendering_device_vulkan) {
rendering_device_vulkan->finalize();
memdelete(rendering_device_vulkan);
}
- if (context_vulkan)
+ if (context_vulkan) {
memdelete(context_vulkan);
+ }
}
#endif
- if (xrandr_handle)
+ if (xrandr_handle) {
dlclose(xrandr_handle);
+ }
for (int i = 0; i < CURSOR_MAX; i++) {
- if (cursors[i] != None)
+ if (cursors[i] != None) {
XFreeCursor(x11_display, cursors[i]);
- if (img[i] != nullptr)
+ }
+ if (img[i] != nullptr) {
XcursorImageDestroy(img[i]);
+ }
};
if (xim) {
@@ -3844,12 +3817,12 @@ DisplayServerX11::~DisplayServerX11() {
}
XCloseDisplay(x11_display);
- if (xmbstring)
+ if (xmbstring) {
memfree(xmbstring);
+ }
}
void DisplayServerX11::register_x11_driver() {
-
register_create_function("x11", create_func, get_rendering_drivers_func);
}
diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h
index 113e504e9b..b5ea71f72a 100644
--- a/platform/linuxbsd/display_server_x11.h
+++ b/platform/linuxbsd/display_server_x11.h
@@ -35,7 +35,7 @@
#include "servers/display_server.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "drivers/alsa/audio_driver_alsa.h"
#include "drivers/alsamidi/midi_driver_alsamidi.h"
@@ -170,10 +170,13 @@ class DisplayServerX11 : public DisplayServer {
int opcode;
Vector<int> touch_devices;
Map<int, Vector2> absolute_devices;
- Map<int, Vector3> pen_devices;
+ Map<int, Vector2> pen_pressure_range;
+ Map<int, Vector2> pen_tilt_x_range;
+ Map<int, Vector2> pen_tilt_y_range;
XIEventMask all_event_mask;
Map<int, Vector2> state;
double pressure;
+ bool pressure_supported;
Vector2 tilt;
Vector2 mouse_pos_to_filter;
Vector2 relative_motion;
diff --git a/platform/linuxbsd/export/export.cpp b/platform/linuxbsd/export/export.cpp
index 53e3ce8f85..86ea95c563 100644
--- a/platform/linuxbsd/export/export.cpp
+++ b/platform/linuxbsd/export/export.cpp
@@ -38,7 +38,6 @@
static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size);
void register_linuxbsd_exporter() {
-
Ref<EditorExportPlatformPC> platform;
platform.instance();
@@ -62,7 +61,6 @@ void register_linuxbsd_exporter() {
}
static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) {
-
// Patch the header of the "pck" section in the ELF file so that it corresponds to the embedded data
FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE);
@@ -139,7 +137,6 @@ static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start,
bool found = false;
for (int i = 0; i < num_sections; ++i) {
-
int64_t section_header_pos = section_table_pos + i * section_header_size;
f->seek(section_header_pos);
diff --git a/platform/linuxbsd/godot_linuxbsd.cpp b/platform/linuxbsd/godot_linuxbsd.cpp
index 710ba3ca40..3ed64e9d46 100644
--- a/platform/linuxbsd/godot_linuxbsd.cpp
+++ b/platform/linuxbsd/godot_linuxbsd.cpp
@@ -37,7 +37,6 @@
#include "os_linuxbsd.h"
int main(int argc, char *argv[]) {
-
OS_LinuxBSD os;
setlocale(LC_CTYPE, "");
@@ -52,8 +51,9 @@ int main(int argc, char *argv[]) {
return 255;
}
- if (Main::start())
+ if (Main::start()) {
os.run(); // it is actually the OS that decides how to run
+ }
Main::cleanup();
if (ret) { // Previous getcwd was successful
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 381eb909ba..5edaf35c50 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -59,7 +59,6 @@ JoypadLinux::Joypad::Joypad() {
}
JoypadLinux::Joypad::~Joypad() {
-
for (int i = 0; i < MAX_ABS; i++) {
if (abs_info[i]) {
memdelete(abs_info[i]);
@@ -71,7 +70,7 @@ void JoypadLinux::Joypad::reset() {
dpad = 0;
fd = -1;
- InputFilter::JoyAxis jx;
+ Input::JoyAxis jx;
jx.min = -1;
jx.value = 0.0f;
for (int i = 0; i < MAX_ABS; i++) {
@@ -80,7 +79,7 @@ void JoypadLinux::Joypad::reset() {
}
}
-JoypadLinux::JoypadLinux(InputFilter *in) {
+JoypadLinux::JoypadLinux(Input *in) {
exit_udev = false;
input = in;
joy_thread = Thread::create(joy_thread_func, this);
@@ -94,7 +93,6 @@ JoypadLinux::~JoypadLinux() {
}
void JoypadLinux::joy_thread_func(void *p_user) {
-
if (p_user) {
JoypadLinux *joy = (JoypadLinux *)p_user;
joy->run_joypad_thread();
@@ -115,7 +113,6 @@ void JoypadLinux::run_joypad_thread() {
#ifdef UDEV_ENABLED
void JoypadLinux::enumerate_joypads(udev *p_udev) {
-
udev_enumerate *enumerate;
udev_list_entry *devices, *dev_list_entry;
udev_device *dev;
@@ -126,13 +123,11 @@ void JoypadLinux::enumerate_joypads(udev *p_udev) {
udev_enumerate_scan_devices(enumerate);
devices = udev_enumerate_get_list_entry(enumerate);
udev_list_entry_foreach(dev_list_entry, devices) {
-
const char *path = udev_list_entry_get_name(dev_list_entry);
dev = udev_device_new_from_syspath(p_udev, path);
const char *devnode = udev_device_get_devnode(dev);
if (devnode) {
-
String devnode_str = devnode;
if (devnode_str.find(ignore_str) == -1) {
MutexLock lock(joy_mutex);
@@ -145,7 +140,6 @@ void JoypadLinux::enumerate_joypads(udev *p_udev) {
}
void JoypadLinux::monitor_joypads(udev *p_udev) {
-
udev_device *dev = nullptr;
udev_monitor *mon = udev_monitor_new_from_netlink(p_udev, "udev");
udev_monitor_filter_add_match_subsystem_devtype(mon, "input", nullptr);
@@ -153,7 +147,6 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
int fd = udev_monitor_get_fd(mon);
while (!exit_udev) {
-
fd_set fds;
struct timeval tv;
int ret;
@@ -172,15 +165,12 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
dev = udev_monitor_receive_device(mon);
if (dev && udev_device_get_devnode(dev) != 0) {
-
MutexLock lock(joy_mutex);
String action = udev_device_get_action(dev);
const char *devnode = udev_device_get_devnode(dev);
if (devnode) {
-
String devnode_str = devnode;
if (devnode_str.find(ignore_str) == -1) {
-
if (action == "add")
open_joypad(devnode);
else if (String(action) == "remove")
@@ -198,7 +188,6 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
#endif
void JoypadLinux::monitor_joypads() {
-
while (!exit_udev) {
{
MutexLock lock(joy_mutex);
@@ -216,9 +205,7 @@ void JoypadLinux::monitor_joypads() {
}
int JoypadLinux::get_joy_from_path(String p_path) const {
-
for (int i = 0; i < JOYPADS_MAX; i++) {
-
if (joypads[i].devpath == p_path) {
return i;
}
@@ -229,17 +216,16 @@ int JoypadLinux::get_joy_from_path(String p_path) const {
void JoypadLinux::close_joypad(int p_id) {
if (p_id == -1) {
for (int i = 0; i < JOYPADS_MAX; i++) {
-
close_joypad(i);
};
return;
- } else if (p_id < 0)
+ } else if (p_id < 0) {
return;
+ }
Joypad &joy = joypads[p_id];
if (joy.fd != -1) {
-
close(joy.fd);
joy.fd = -1;
attached_devices.remove(attached_devices.find(joy.devpath));
@@ -248,7 +234,6 @@ void JoypadLinux::close_joypad(int p_id) {
}
static String _hex_str(uint8_t p_byte) {
-
static const char *dict = "0123456789abcdef";
char ret[3];
ret[2] = 0;
@@ -260,7 +245,6 @@ static String _hex_str(uint8_t p_byte) {
}
void JoypadLinux::setup_joypad_properties(int p_id) {
-
Joypad *joy = &joypads[p_id];
unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
@@ -274,16 +258,12 @@ void JoypadLinux::setup_joypad_properties(int p_id) {
return;
}
for (int i = BTN_JOYSTICK; i < KEY_MAX; ++i) {
-
if (test_bit(i, keybit)) {
-
joy->key_map[i] = num_buttons++;
}
}
for (int i = BTN_MISC; i < BTN_JOYSTICK; ++i) {
-
if (test_bit(i, keybit)) {
-
joy->key_map[i] = num_buttons++;
}
}
@@ -294,7 +274,6 @@ void JoypadLinux::setup_joypad_properties(int p_id) {
continue;
}
if (test_bit(i, absbit)) {
-
joy->abs_map[i] = num_axes++;
joy->abs_info[i] = memnew(input_absinfo);
if (ioctl(joy->fd, EVIOCGABS(i), joy->abs_info[i]) < 0) {
@@ -315,11 +294,9 @@ void JoypadLinux::setup_joypad_properties(int p_id) {
}
void JoypadLinux::open_joypad(const char *p_path) {
-
int joy_num = input->get_unused_joy_id();
int fd = open(p_path, O_RDWR | O_NONBLOCK);
if (fd != -1 && joy_num != -1) {
-
unsigned long evbit[NBITS(EV_MAX)] = { 0 };
unsigned long keybit[NBITS(KEY_MAX)] = { 0 };
unsigned long absbit[NBITS(ABS_MAX)] = { 0 };
@@ -369,7 +346,6 @@ void JoypadLinux::open_joypad(const char *p_path) {
setup_joypad_properties(joy_num);
sprintf(uid, "%04x%04x", BSWAP16(inpid.bustype), 0);
if (inpid.vendor && inpid.product && inpid.version) {
-
uint16_t vendor = BSWAP16(inpid.vendor);
uint16_t product = BSWAP16(inpid.product);
uint16_t version = BSWAP16(inpid.version);
@@ -380,7 +356,6 @@ void JoypadLinux::open_joypad(const char *p_path) {
String uidname = uid;
int uidlen = MIN(name.length(), 11);
for (int i = 0; i < uidlen; i++) {
-
uidname = uidname + _hex_str(name[i]);
}
uidname += "00";
@@ -436,11 +411,10 @@ void JoypadLinux::joypad_vibration_stop(int p_id, uint64_t p_timestamp) {
joy.ff_effect_timestamp = p_timestamp;
}
-InputFilter::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value) const {
-
+Input::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int p_value) const {
int min = p_abs->minimum;
int max = p_abs->maximum;
- InputFilter::JoyAxis jx;
+ Input::JoyAxis jx;
if (min < 0) {
jx.min = -1;
@@ -457,13 +431,13 @@ InputFilter::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int p
}
void JoypadLinux::process_joypads() {
-
if (joy_mutex.try_lock() != OK) {
return;
}
for (int i = 0; i < JOYPADS_MAX; i++) {
-
- if (joypads[i].fd == -1) continue;
+ if (joypads[i].fd == -1) {
+ continue;
+ }
input_event events[32];
Joypad *joy = &joypads[i];
@@ -473,13 +447,13 @@ void JoypadLinux::process_joypads() {
while ((len = read(joy->fd, events, (sizeof events))) > 0) {
len /= sizeof(events[0]);
for (int j = 0; j < len; j++) {
-
input_event &ev = events[j];
// ev may be tainted and out of MAX_KEY range, which will cause
// joy->key_map[ev.code] to crash
- if (ev.code >= MAX_KEY)
+ if (ev.code >= MAX_KEY) {
return;
+ }
switch (ev.type) {
case EV_KEY:
@@ -491,33 +465,38 @@ void JoypadLinux::process_joypads() {
switch (ev.code) {
case ABS_HAT0X:
if (ev.value != 0) {
- if (ev.value < 0)
- joy->dpad |= InputFilter::HAT_MASK_LEFT;
- else
- joy->dpad |= InputFilter::HAT_MASK_RIGHT;
- } else
- joy->dpad &= ~(InputFilter::HAT_MASK_LEFT | InputFilter::HAT_MASK_RIGHT);
+ if (ev.value < 0) {
+ joy->dpad |= Input::HAT_MASK_LEFT;
+ } else {
+ joy->dpad |= Input::HAT_MASK_RIGHT;
+ }
+ } else {
+ joy->dpad &= ~(Input::HAT_MASK_LEFT | Input::HAT_MASK_RIGHT);
+ }
input->joy_hat(i, joy->dpad);
break;
case ABS_HAT0Y:
if (ev.value != 0) {
- if (ev.value < 0)
- joy->dpad |= InputFilter::HAT_MASK_UP;
- else
- joy->dpad |= InputFilter::HAT_MASK_DOWN;
- } else
- joy->dpad &= ~(InputFilter::HAT_MASK_UP | InputFilter::HAT_MASK_DOWN);
+ if (ev.value < 0) {
+ joy->dpad |= Input::HAT_MASK_UP;
+ } else {
+ joy->dpad |= Input::HAT_MASK_DOWN;
+ }
+ } else {
+ joy->dpad &= ~(Input::HAT_MASK_UP | Input::HAT_MASK_DOWN);
+ }
input->joy_hat(i, joy->dpad);
break;
default:
- if (ev.code >= MAX_ABS)
+ if (ev.code >= MAX_ABS) {
return;
+ }
if (joy->abs_map[ev.code] != -1 && joy->abs_info[ev.code]) {
- InputFilter::JoyAxis value = axis_correct(joy->abs_info[ev.code], ev.value);
+ Input::JoyAxis value = axis_correct(joy->abs_info[ev.code], ev.value);
joy->curr_axis[joy->abs_map[ev.code]] = value;
}
break;
diff --git a/platform/linuxbsd/joypad_linux.h b/platform/linuxbsd/joypad_linux.h
index 1d2ed5bbc1..0d175193a5 100644
--- a/platform/linuxbsd/joypad_linux.h
+++ b/platform/linuxbsd/joypad_linux.h
@@ -33,7 +33,7 @@
#define JOYPAD_LINUX_H
#ifdef JOYDEV_ENABLED
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/mutex.h"
#include "core/os/thread.h"
@@ -41,7 +41,7 @@ struct input_absinfo;
class JoypadLinux {
public:
- JoypadLinux(InputFilter *in);
+ JoypadLinux(Input *in);
~JoypadLinux();
void process_joypads();
@@ -53,7 +53,7 @@ private:
};
struct Joypad {
- InputFilter::JoyAxis curr_axis[MAX_ABS];
+ Input::JoyAxis curr_axis[MAX_ABS];
int key_map[MAX_KEY];
int abs_map[MAX_ABS];
int dpad;
@@ -74,7 +74,7 @@ private:
bool exit_udev;
Mutex joy_mutex;
Thread *joy_thread;
- InputFilter *input;
+ Input *input;
Joypad joypads[JOYPADS_MAX];
Vector<String> attached_devices;
@@ -95,7 +95,7 @@ private:
void joypad_vibration_start(int p_id, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
void joypad_vibration_stop(int p_id, uint64_t p_timestamp);
- InputFilter::JoyAxis axis_correct(const input_absinfo *p_abs, int p_value) const;
+ Input::JoyAxis axis_correct(const input_absinfo *p_abs, int p_value) const;
};
#endif
diff --git a/platform/linuxbsd/key_mapping_x11.cpp b/platform/linuxbsd/key_mapping_x11.cpp
index 78bd2b71a0..77512b1a9e 100644
--- a/platform/linuxbsd/key_mapping_x11.cpp
+++ b/platform/linuxbsd/key_mapping_x11.cpp
@@ -33,7 +33,6 @@
/***** SCAN CODE CONVERSION ******/
struct _XTranslatePair {
-
KeySym keysym;
unsigned int keycode;
};
@@ -181,7 +180,6 @@ static _XTranslatePair _xkeysym_to_keycode[] = {
};
struct _TranslatePair {
-
unsigned int keysym;
unsigned int keycode;
};
@@ -301,10 +299,8 @@ static _TranslatePair _scancode_to_keycode[] = {
};
unsigned int KeyMappingX11::get_scancode(unsigned int p_code) {
-
unsigned int keycode = KEY_UNKNOWN;
for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
-
if (_scancode_to_keycode[i].keycode == p_code) {
keycode = _scancode_to_keycode[i].keysym;
break;
@@ -315,34 +311,34 @@ unsigned int KeyMappingX11::get_scancode(unsigned int p_code) {
}
unsigned int KeyMappingX11::get_keycode(KeySym p_keysym) {
-
// kinda bruteforce.. could optimize.
- if (p_keysym < 0x100) // Latin 1, maps 1-1
+ if (p_keysym < 0x100) { // Latin 1, maps 1-1
return p_keysym;
+ }
// look for special key
for (int idx = 0; _xkeysym_to_keycode[idx].keysym != 0; idx++) {
-
- if (_xkeysym_to_keycode[idx].keysym == p_keysym)
+ if (_xkeysym_to_keycode[idx].keysym == p_keysym) {
return _xkeysym_to_keycode[idx].keycode;
+ }
}
return 0;
}
KeySym KeyMappingX11::get_keysym(unsigned int p_code) {
-
// kinda bruteforce.. could optimize.
- if (p_code < 0x100) // Latin 1, maps 1-1
+ if (p_code < 0x100) { // Latin 1, maps 1-1
return p_code;
+ }
// look for special key
for (int idx = 0; _xkeysym_to_keycode[idx].keysym != 0; idx++) {
-
- if (_xkeysym_to_keycode[idx].keycode == p_code)
+ if (_xkeysym_to_keycode[idx].keycode == p_code) {
return _xkeysym_to_keycode[idx].keysym;
+ }
}
return 0;
@@ -353,7 +349,6 @@ KeySym KeyMappingX11::get_keysym(unsigned int p_code) {
// Tables taken from FOX toolkit
struct _XTranslateUnicodePair {
-
KeySym keysym;
unsigned int unicode;
};
@@ -1125,37 +1120,41 @@ static _XTranslateUnicodePair _xkeysym_to_unicode[_KEYSYM_MAX] = {
};
unsigned int KeyMappingX11::get_unicode_from_keysym(KeySym p_keysym) {
-
/* Latin-1 */
- if (p_keysym >= 0x20 && p_keysym <= 0x7e)
+ if (p_keysym >= 0x20 && p_keysym <= 0x7e) {
return p_keysym;
- if (p_keysym >= 0xa0 && p_keysym <= 0xff)
+ }
+ if (p_keysym >= 0xa0 && p_keysym <= 0xff) {
return p_keysym;
+ }
// keypad to latin1 is easy
- if (p_keysym >= 0xffaa && p_keysym <= 0xffb9)
+ if (p_keysym >= 0xffaa && p_keysym <= 0xffb9) {
return p_keysym - 0xff80;
+ }
/* Unicode (may be present)*/
- if ((p_keysym & 0xff000000) == 0x01000000)
+ if ((p_keysym & 0xff000000) == 0x01000000) {
return p_keysym & 0x00ffffff;
+ }
int middle, low = 0, high = _KEYSYM_MAX - 1;
do {
middle = (high + low) / 2;
- if (_xkeysym_to_unicode[middle].keysym == p_keysym)
+ if (_xkeysym_to_unicode[middle].keysym == p_keysym) {
return _xkeysym_to_unicode[middle].unicode;
- if (_xkeysym_to_unicode[middle].keysym <= p_keysym)
+ }
+ if (_xkeysym_to_unicode[middle].keysym <= p_keysym) {
low = middle + 1;
- else
+ } else {
high = middle - 1;
+ }
} while (high >= low);
return 0;
}
struct _XTranslateUnicodePairReverse {
-
unsigned int unicode;
KeySym keysym;
};
@@ -1919,24 +1918,27 @@ static _XTranslateUnicodePairReverse _unicode_to_xkeysym[_UNICODE_MAX] = {
};
KeySym KeyMappingX11::get_keysym_from_unicode(unsigned int p_unicode) {
-
/* Latin 1 */
- if (p_unicode >= 0x20 && p_unicode <= 0x7e)
+ if (p_unicode >= 0x20 && p_unicode <= 0x7e) {
return p_unicode;
+ }
- if (p_unicode >= 0xa0 && p_unicode <= 0xff)
+ if (p_unicode >= 0xa0 && p_unicode <= 0xff) {
return p_unicode;
+ }
int middle, low = 0, high = _UNICODE_MAX - 1;
do {
middle = (high + low) / 2;
- if (_unicode_to_xkeysym[middle].keysym == p_unicode)
+ if (_unicode_to_xkeysym[middle].keysym == p_unicode) {
return _unicode_to_xkeysym[middle].keysym;
- if (_unicode_to_xkeysym[middle].keysym <= p_unicode)
+ }
+ if (_unicode_to_xkeysym[middle].keysym <= p_unicode) {
low = middle + 1;
- else
+ } else {
high = middle - 1;
+ }
} while (high >= low);
// if not found, let's hope X understands it as unicode
diff --git a/platform/linuxbsd/key_mapping_x11.h b/platform/linuxbsd/key_mapping_x11.h
index 10db43bcc4..8f5e01a3c2 100644
--- a/platform/linuxbsd/key_mapping_x11.h
+++ b/platform/linuxbsd/key_mapping_x11.h
@@ -41,7 +41,7 @@
#include "core/os/keyboard.h"
class KeyMappingX11 {
- KeyMappingX11(){};
+ KeyMappingX11() {}
public:
static unsigned int get_keycode(KeySym p_keysym);
diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp
index 5b9a25bd8b..09a5eca914 100644
--- a/platform/linuxbsd/os_linuxbsd.cpp
+++ b/platform/linuxbsd/os_linuxbsd.cpp
@@ -55,21 +55,18 @@
#endif
void OS_LinuxBSD::initialize() {
-
crash_handler.initialize();
OS_Unix::initialize_core();
}
void OS_LinuxBSD::initialize_joypads() {
-
#ifdef JOYDEV_ENABLED
- joypad = memnew(JoypadLinux(InputFilter::get_singleton()));
+ joypad = memnew(JoypadLinux(Input::get_singleton()));
#endif
}
String OS_LinuxBSD::get_unique_id() const {
-
static String machine_id;
if (machine_id.empty()) {
if (FileAccess *f = FileAccess::open("/etc/machine-id", FileAccess::READ)) {
@@ -84,9 +81,9 @@ String OS_LinuxBSD::get_unique_id() const {
}
void OS_LinuxBSD::finalize() {
-
- if (main_loop)
+ if (main_loop) {
memdelete(main_loop);
+ }
main_loop = nullptr;
#ifdef ALSAMIDI_ENABLED
@@ -99,24 +96,21 @@ void OS_LinuxBSD::finalize() {
}
MainLoop *OS_LinuxBSD::get_main_loop() const {
-
return main_loop;
}
void OS_LinuxBSD::delete_main_loop() {
-
- if (main_loop)
+ if (main_loop) {
memdelete(main_loop);
+ }
main_loop = nullptr;
}
void OS_LinuxBSD::set_main_loop(MainLoop *p_main_loop) {
-
main_loop = p_main_loop;
}
String OS_LinuxBSD::get_name() const {
-
#ifdef __linux__
return "Linux";
#elif defined(__FreeBSD__)
@@ -129,27 +123,26 @@ String OS_LinuxBSD::get_name() const {
}
Error OS_LinuxBSD::shell_open(String p_uri) {
-
Error ok;
List<String> args;
args.push_back(p_uri);
ok = execute("xdg-open", args, false);
- if (ok == OK)
+ if (ok == OK) {
return OK;
+ }
ok = execute("gnome-open", args, false);
- if (ok == OK)
+ if (ok == OK) {
return OK;
+ }
ok = execute("kde-open", args, false);
return ok;
}
bool OS_LinuxBSD::_check_internal_feature_support(const String &p_feature) {
-
return p_feature == "pc";
}
String OS_LinuxBSD::get_config_path() const {
-
if (has_environment("XDG_CONFIG_HOME")) {
return get_environment("XDG_CONFIG_HOME");
} else if (has_environment("HOME")) {
@@ -160,7 +153,6 @@ String OS_LinuxBSD::get_config_path() const {
}
String OS_LinuxBSD::get_data_path() const {
-
if (has_environment("XDG_DATA_HOME")) {
return get_environment("XDG_DATA_HOME");
} else if (has_environment("HOME")) {
@@ -171,7 +163,6 @@ String OS_LinuxBSD::get_data_path() const {
}
String OS_LinuxBSD::get_cache_path() const {
-
if (has_environment("XDG_CACHE_HOME")) {
return get_environment("XDG_CACHE_HOME");
} else if (has_environment("HOME")) {
@@ -182,46 +173,37 @@ String OS_LinuxBSD::get_cache_path() const {
}
String OS_LinuxBSD::get_system_dir(SystemDir p_dir) const {
-
String xdgparam;
switch (p_dir) {
case SYSTEM_DIR_DESKTOP: {
-
xdgparam = "DESKTOP";
} break;
case SYSTEM_DIR_DCIM: {
-
xdgparam = "PICTURES";
} break;
case SYSTEM_DIR_DOCUMENTS: {
-
xdgparam = "DOCUMENTS";
} break;
case SYSTEM_DIR_DOWNLOADS: {
-
xdgparam = "DOWNLOAD";
} break;
case SYSTEM_DIR_MOVIES: {
-
xdgparam = "VIDEOS";
} break;
case SYSTEM_DIR_MUSIC: {
-
xdgparam = "MUSIC";
} break;
case SYSTEM_DIR_PICTURES: {
-
xdgparam = "PICTURES";
} break;
case SYSTEM_DIR_RINGTONES: {
-
xdgparam = "MUSIC";
} break;
@@ -231,17 +213,18 @@ String OS_LinuxBSD::get_system_dir(SystemDir p_dir) const {
List<String> arg;
arg.push_back(xdgparam);
Error err = const_cast<OS_LinuxBSD *>(this)->execute("xdg-user-dir", arg, true, nullptr, &pipe);
- if (err != OK)
+ if (err != OK) {
return ".";
+ }
return pipe.strip_edges();
}
void OS_LinuxBSD::run() {
-
force_quit = false;
- if (!main_loop)
+ if (!main_loop) {
return;
+ }
main_loop->init();
@@ -251,13 +234,13 @@ void OS_LinuxBSD::run() {
//uint64_t frame=0;
while (!force_quit) {
-
DisplayServer::get_singleton()->process_events(); // get rid of pending events
#ifdef JOYDEV_ENABLED
joypad->process_joypads();
#endif
- if (Main::iteration())
+ if (Main::iteration()) {
break;
+ }
};
main_loop->finish();
@@ -363,7 +346,6 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) {
}
OS_LinuxBSD::OS_LinuxBSD() {
-
main_loop = nullptr;
force_quit = false;
diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h
index 100cb53ba3..4295721c68 100644
--- a/platform/linuxbsd/os_linuxbsd.h
+++ b/platform/linuxbsd/os_linuxbsd.h
@@ -31,7 +31,7 @@
#ifndef OS_LINUXBSD_H
#define OS_LINUXBSD_H
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "crash_handler_linuxbsd.h"
#include "drivers/alsa/audio_driver_alsa.h"
#include "drivers/alsamidi/midi_driver_alsamidi.h"
@@ -43,7 +43,6 @@
#include "servers/rendering_server.h"
class OS_LinuxBSD : public OS_Unix {
-
virtual void delete_main_loop();
bool force_quit;
diff --git a/platform/linuxbsd/vulkan_context_x11.cpp b/platform/linuxbsd/vulkan_context_x11.cpp
index 1798a7026e..2eaa9f9446 100644
--- a/platform/linuxbsd/vulkan_context_x11.cpp
+++ b/platform/linuxbsd/vulkan_context_x11.cpp
@@ -36,7 +36,6 @@ const char *VulkanContextX11::_get_platform_surface_extension() const {
}
Error VulkanContextX11::window_create(DisplayServer::WindowID p_window_id, ::Window p_window, Display *p_display, int p_width, int p_height) {
-
VkXlibSurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
diff --git a/platform/linuxbsd/vulkan_context_x11.h b/platform/linuxbsd/vulkan_context_x11.h
index 6e144ab2d9..af3d923cfe 100644
--- a/platform/linuxbsd/vulkan_context_x11.h
+++ b/platform/linuxbsd/vulkan_context_x11.h
@@ -35,7 +35,6 @@
#include <X11/Xlib.h>
class VulkanContextX11 : public VulkanContext {
-
virtual const char *_get_platform_surface_extension() const;
public:
diff --git a/platform/osx/context_gl_osx.h b/platform/osx/context_gl_osx.h
index 7e436c5e36..cce00fb35f 100644
--- a/platform/osx/context_gl_osx.h
+++ b/platform/osx/context_gl_osx.h
@@ -41,7 +41,6 @@
#include <CoreVideo/CoreVideo.h>
class ContextGL_OSX {
-
bool opengl_3_context;
bool use_vsync;
diff --git a/platform/osx/context_gl_osx.mm b/platform/osx/context_gl_osx.mm
index 91d1332d24..2319e9eb1f 100644
--- a/platform/osx/context_gl_osx.mm
+++ b/platform/osx/context_gl_osx.mm
@@ -33,42 +33,34 @@
#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED)
void ContextGL_OSX::release_current() {
-
[NSOpenGLContext clearCurrentContext];
}
void ContextGL_OSX::make_current() {
-
[context makeCurrentContext];
}
void ContextGL_OSX::update() {
-
[context update];
}
void ContextGL_OSX::set_opacity(GLint p_opacity) {
-
[context setValues:&p_opacity forParameter:NSOpenGLCPSurfaceOpacity];
}
int ContextGL_OSX::get_window_width() {
-
return OS::get_singleton()->get_video_mode().width;
}
int ContextGL_OSX::get_window_height() {
-
return OS::get_singleton()->get_video_mode().height;
}
void ContextGL_OSX::swap_buffers() {
-
[context flushBuffer];
}
void ContextGL_OSX::set_use_vsync(bool p_use) {
-
CGLContextObj ctx = CGLGetCurrentContext();
if (ctx) {
GLint swapInterval = p_use ? 1 : 0;
@@ -78,12 +70,10 @@ void ContextGL_OSX::set_use_vsync(bool p_use) {
}
bool ContextGL_OSX::is_using_vsync() const {
-
return use_vsync;
}
Error ContextGL_OSX::initialize() {
-
framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
ERR_FAIL_COND_V(!framework, ERR_CANT_CREATE);
@@ -161,7 +151,6 @@ Error ContextGL_OSX::initialize() {
}
ContextGL_OSX::ContextGL_OSX(id p_view, bool p_opengl_3_context) {
-
opengl_3_context = p_opengl_3_context;
window_view = p_view;
use_vsync = false;
diff --git a/platform/osx/crash_handler_osx.h b/platform/osx/crash_handler_osx.h
index abd9812596..9970f6045a 100644
--- a/platform/osx/crash_handler_osx.h
+++ b/platform/osx/crash_handler_osx.h
@@ -32,7 +32,6 @@
#define CRASH_HANDLER_OSX_H
class CrashHandler {
-
bool disabled;
public:
diff --git a/platform/osx/dir_access_osx.mm b/platform/osx/dir_access_osx.mm
index 66ea380903..7791ba5407 100644
--- a/platform/osx/dir_access_osx.mm
+++ b/platform/osx/dir_access_osx.mm
@@ -38,7 +38,6 @@
#include <Foundation/Foundation.h>
String DirAccessOSX::fix_unicode_name(const char *p_name) const {
-
String fname;
NSString *nsstr = [[NSString stringWithUTF8String:p_name] precomposedStringWithCanonicalMapping];
diff --git a/platform/osx/display_server_osx.h b/platform/osx/display_server_osx.h
index 86ceb51763..8133dfe2c4 100644
--- a/platform/osx/display_server_osx.h
+++ b/platform/osx/display_server_osx.h
@@ -33,7 +33,7 @@
#define BitMap _QDBitMap // Suppress deprecated QuickDraw definition.
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "servers/display_server.h"
#if defined(OPENGL_ENABLED)
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 074fc3be0d..9a1191490c 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -55,6 +55,10 @@
#include <QuartzCore/CAMetalLayer.h>
#endif
+#ifndef NSAppKitVersionNumber10_14
+#define NSAppKitVersionNumber10_14 1671
+#endif
+
#define DS_OSX ((DisplayServerOSX *)(DisplayServerOSX::get_singleton()))
static void _get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> r_state) {
@@ -70,7 +74,7 @@ static Vector2i _get_mouse_pos(DisplayServerOSX::WindowData &p_wd, NSPoint p_loc
p_wd.mouse_pos.x = p.x * p_backingScaleFactor;
p_wd.mouse_pos.y = (contentRect.size.height - p.y) * p_backingScaleFactor;
DS_OSX->last_mouse_pos = p_wd.mouse_pos;
- InputFilter::get_singleton()->set_mouse_position(p_wd.mouse_pos);
+ Input::get_singleton()->set_mouse_position(p_wd.mouse_pos);
return p_wd.mouse_pos;
}
@@ -120,7 +124,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
k->set_physical_keycode(KEY_PERIOD);
k->set_echo([event isARepeat]);
- InputFilter::get_singleton()->accumulate_input_event(k);
+ Input::get_singleton()->accumulate_input_event(k);
}
}
@@ -145,6 +149,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
Variant meta;
bool checkable;
}
+
@end
@implementation GlobalMenuItem
@@ -273,13 +278,17 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (BOOL)windowShouldClose:(id)sender {
- ERR_FAIL_COND_V(!DS_OSX->windows.has(window_id), YES);
+ if (!DS_OSX || !DS_OSX->windows.has(window_id)) {
+ return YES;
+ }
DS_OSX->_send_window_event(DS_OSX->windows[window_id], DisplayServerOSX::WINDOW_EVENT_CLOSE_REQUEST);
return NO;
}
- (void)windowWillClose:(NSNotification *)notification {
- ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
+ if (!DS_OSX || !DS_OSX->windows.has(window_id)) {
+ return;
+ }
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
while (wd.transient_children.size()) {
@@ -305,7 +314,9 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (void)windowDidEnterFullScreen:(NSNotification *)notification {
- ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
+ if (!DS_OSX || !DS_OSX->windows.has(window_id)) {
+ return;
+ }
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
wd.fullscreen = true;
@@ -315,8 +326,9 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (void)windowDidExitFullScreen:(NSNotification *)notification {
- if (!DS_OSX || !DS_OSX->windows.has(window_id))
+ if (!DS_OSX || !DS_OSX->windows.has(window_id)) {
return;
+ }
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
wd.fullscreen = false;
@@ -378,8 +390,9 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (void)windowDidResize:(NSNotification *)notification {
- if (!DS_OSX || !DS_OSX->windows.has(window_id))
+ if (!DS_OSX || !DS_OSX->windows.has(window_id)) {
return;
+ }
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
#if defined(OPENGL_ENABLED)
@@ -420,23 +433,40 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (void)windowDidMove:(NSNotification *)notification {
+ if (!DS_OSX || !DS_OSX->windows.has(window_id)) {
+ return;
+ }
+ DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
+
DS_OSX->_release_pressed_events();
+
+ if (!wd.rect_changed_callback.is_null()) {
+ Variant size = Rect2i(DS_OSX->window_get_position(window_id), DS_OSX->window_get_size(window_id));
+ Variant *sizep = &size;
+ Variant ret;
+ Callable::CallError ce;
+ wd.rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce);
+ }
}
- (void)windowDidBecomeKey:(NSNotification *)notification {
- ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
+ if (!DS_OSX || !DS_OSX->windows.has(window_id)) {
+ return;
+ }
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
const CGFloat backingScaleFactor = (OS::get_singleton()->is_hidpi_allowed()) ? [wd.window_view backingScaleFactor] : 1.0;
_get_mouse_pos(wd, [wd.window_object mouseLocationOutsideOfEventStream], backingScaleFactor);
- InputFilter::get_singleton()->set_mouse_position(wd.mouse_pos);
+ Input::get_singleton()->set_mouse_position(wd.mouse_pos);
DS_OSX->window_focused = true;
DS_OSX->_send_window_event(wd, DisplayServerOSX::WINDOW_EVENT_FOCUS_IN);
}
- (void)windowDidResignKey:(NSNotification *)notification {
- ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
+ if (!DS_OSX || !DS_OSX->windows.has(window_id)) {
+ return;
+ }
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
DS_OSX->window_focused = false;
@@ -446,7 +476,9 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (void)windowDidMiniaturize:(NSNotification *)notification {
- ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
+ if (!DS_OSX || !DS_OSX->windows.has(window_id)) {
+ return;
+ }
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
DS_OSX->window_focused = false;
@@ -456,7 +488,9 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) {
}
- (void)windowDidDeminiaturize:(NSNotification *)notification {
- ERR_FAIL_COND(!DS_OSX->windows.has(window_id));
+ if (!DS_OSX || !DS_OSX->windows.has(window_id)) {
+ return;
+ }
DisplayServerOSX::WindowData &wd = DS_OSX->windows[window_id];
DS_OSX->window_focused = true;
@@ -755,7 +789,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
mb->set_doubleclick([event clickCount] == 2);
}
- InputFilter::get_singleton()->accumulate_input_event(mb);
+ Input::get_singleton()->accumulate_input_event(mb);
}
- (void)mouseDown:(NSEvent *)event {
@@ -804,15 +838,15 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
mm->set_tilt(Vector2(p.x, p.y));
}
mm->set_global_position(pos);
- mm->set_speed(InputFilter::get_singleton()->get_last_mouse_speed());
+ mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
Vector2i relativeMotion = Vector2i();
relativeMotion.x = [event deltaX] * backingScaleFactor;
relativeMotion.y = [event deltaY] * backingScaleFactor;
mm->set_relative(relativeMotion);
_get_key_modifier_state([event modifierFlags], mm);
- InputFilter::get_singleton()->set_mouse_position(wd.mouse_pos);
- InputFilter::get_singleton()->accumulate_input_event(mm);
+ Input::get_singleton()->set_mouse_position(wd.mouse_pos);
+ Input::get_singleton()->accumulate_input_event(mm);
}
- (void)rightMouseDown:(NSEvent *)event {
@@ -887,7 +921,7 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
ev->set_position(_get_mouse_pos(wd, [event locationInWindow], backingScaleFactor));
ev->set_factor([event magnification] + 1.0);
- InputFilter::get_singleton()->accumulate_input_event(ev);
+ Input::get_singleton()->accumulate_input_event(ev);
}
- (void)viewDidChangeBackingProperties {
@@ -917,7 +951,6 @@ static void _mouseDownEvent(DisplayServer::WindowID window_id, NSEvent *event, i
}
static bool isNumpadKey(unsigned int key) {
-
static const unsigned int table[] = {
0x41, /* kVK_ANSI_KeypadDecimal */
0x43, /* kVK_ANSI_KeypadMultiply */
@@ -950,7 +983,6 @@ static bool isNumpadKey(unsigned int key) {
// Translates a OS X keycode to a Godot keycode
//
static int translateKey(unsigned int key) {
-
// Keyboard symbol translation table
static const unsigned int table[128] = {
/* 00 */ KEY_A,
@@ -1353,7 +1385,7 @@ inline void sendScrollEvent(DisplayServer::WindowID window_id, int button, doubl
DS_OSX->last_button_state |= mask;
sc->set_button_mask(DS_OSX->last_button_state);
- InputFilter::get_singleton()->accumulate_input_event(sc);
+ Input::get_singleton()->accumulate_input_event(sc);
sc.instance();
sc->set_window_id(window_id);
@@ -1365,7 +1397,7 @@ inline void sendScrollEvent(DisplayServer::WindowID window_id, int button, doubl
DS_OSX->last_button_state &= ~mask;
sc->set_button_mask(DS_OSX->last_button_state);
- InputFilter::get_singleton()->accumulate_input_event(sc);
+ Input::get_singleton()->accumulate_input_event(sc);
}
inline void sendPanEvent(DisplayServer::WindowID window_id, double dx, double dy, int modifierFlags) {
@@ -1380,7 +1412,7 @@ inline void sendPanEvent(DisplayServer::WindowID window_id, double dx, double dy
pg->set_position(wd.mouse_pos);
pg->set_delta(Vector2(-dx, -dy));
- InputFilter::get_singleton()->accumulate_input_event(pg);
+ Input::get_singleton()->accumulate_input_event(pg);
}
- (void)scrollWheel:(NSEvent *)event {
@@ -1420,6 +1452,7 @@ inline void sendPanEvent(DisplayServer::WindowID window_id, double dx, double dy
@interface GodotWindow : NSWindow {
}
+
@end
@implementation GodotWindow
@@ -1652,7 +1685,8 @@ String DisplayServerOSX::global_menu_get_item_submenu(const String &p_menu_root,
const NSMenu *sub_menu = [menu_item submenu];
if (sub_menu) {
for (Map<String, NSMenu *>::Element *E = submenu.front(); E; E = E->next()) {
- if (E->get() == sub_menu) return E->key();
+ if (E->get() == sub_menu)
+ return E->key();
}
}
}
@@ -2143,7 +2177,7 @@ Rect2i DisplayServerOSX::screen_get_usable_rect(int p_screen) const {
Point2i position = Point2i(nsrect.origin.x, nsrect.origin.y + nsrect.size.height) * displayScale - _get_screens_origin();
position.y *= -1;
- Size2i size = Size2i(nsrect.size.width, nsrect.size.height) / displayScale;
+ Size2i size = Size2i(nsrect.size.width, nsrect.size.height) * displayScale;
return Rect2i(position, size);
}
@@ -2475,7 +2509,8 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
- if (!OS_OSX::get_singleton()->is_layered_allowed()) return;
+ if (!OS_OSX::get_singleton()->is_layered_allowed())
+ return;
if (wd.layered_window != p_enabled) {
if (p_enabled) {
[wd.window_object setBackgroundColor:[NSColor clearColor]];
@@ -2770,23 +2805,57 @@ void DisplayServerOSX::cursor_set_shape(CursorShape p_shape) {
[cursors[p_shape] set];
} else {
switch (p_shape) {
- case CURSOR_ARROW: [[NSCursor arrowCursor] set]; break;
- case CURSOR_IBEAM: [[NSCursor IBeamCursor] set]; break;
- case CURSOR_POINTING_HAND: [[NSCursor pointingHandCursor] set]; break;
- case CURSOR_CROSS: [[NSCursor crosshairCursor] set]; break;
- case CURSOR_WAIT: [[NSCursor arrowCursor] set]; break;
- case CURSOR_BUSY: [[NSCursor arrowCursor] set]; break;
- case CURSOR_DRAG: [[NSCursor closedHandCursor] set]; break;
- case CURSOR_CAN_DROP: [[NSCursor openHandCursor] set]; break;
- case CURSOR_FORBIDDEN: [[NSCursor operationNotAllowedCursor] set]; break;
- case CURSOR_VSIZE: [_cursorFromSelector(@selector(_windowResizeNorthSouthCursor), @selector(resizeUpDownCursor)) set]; break;
- case CURSOR_HSIZE: [_cursorFromSelector(@selector(_windowResizeEastWestCursor), @selector(resizeLeftRightCursor)) set]; break;
- case CURSOR_BDIAGSIZE: [_cursorFromSelector(@selector(_windowResizeNorthEastSouthWestCursor)) set]; break;
- case CURSOR_FDIAGSIZE: [_cursorFromSelector(@selector(_windowResizeNorthWestSouthEastCursor)) set]; break;
- case CURSOR_MOVE: [[NSCursor arrowCursor] set]; break;
- case CURSOR_VSPLIT: [[NSCursor resizeUpDownCursor] set]; break;
- case CURSOR_HSPLIT: [[NSCursor resizeLeftRightCursor] set]; break;
- case CURSOR_HELP: [_cursorFromSelector(@selector(_helpCursor)) set]; break;
+ case CURSOR_ARROW:
+ [[NSCursor arrowCursor] set];
+ break;
+ case CURSOR_IBEAM:
+ [[NSCursor IBeamCursor] set];
+ break;
+ case CURSOR_POINTING_HAND:
+ [[NSCursor pointingHandCursor] set];
+ break;
+ case CURSOR_CROSS:
+ [[NSCursor crosshairCursor] set];
+ break;
+ case CURSOR_WAIT:
+ [[NSCursor arrowCursor] set];
+ break;
+ case CURSOR_BUSY:
+ [[NSCursor arrowCursor] set];
+ break;
+ case CURSOR_DRAG:
+ [[NSCursor closedHandCursor] set];
+ break;
+ case CURSOR_CAN_DROP:
+ [[NSCursor openHandCursor] set];
+ break;
+ case CURSOR_FORBIDDEN:
+ [[NSCursor operationNotAllowedCursor] set];
+ break;
+ case CURSOR_VSIZE:
+ [_cursorFromSelector(@selector(_windowResizeNorthSouthCursor), @selector(resizeUpDownCursor)) set];
+ break;
+ case CURSOR_HSIZE:
+ [_cursorFromSelector(@selector(_windowResizeEastWestCursor), @selector(resizeLeftRightCursor)) set];
+ break;
+ case CURSOR_BDIAGSIZE:
+ [_cursorFromSelector(@selector(_windowResizeNorthEastSouthWestCursor)) set];
+ break;
+ case CURSOR_FDIAGSIZE:
+ [_cursorFromSelector(@selector(_windowResizeNorthWestSouthEastCursor)) set];
+ break;
+ case CURSOR_MOVE:
+ [[NSCursor arrowCursor] set];
+ break;
+ case CURSOR_VSPLIT:
+ [[NSCursor resizeUpDownCursor] set];
+ break;
+ case CURSOR_HSPLIT:
+ [[NSCursor resizeLeftRightCursor] set];
+ break;
+ case CURSOR_HELP:
+ [_cursorFromSelector(@selector(_helpCursor)) set];
+ break;
default: {
}
}
@@ -2971,7 +3040,6 @@ DisplayServerOSX::LatinKeyboardVariant DisplayServerOSX::get_latin_keyboard_vari
static LatinKeyboardVariant layout = LATIN_KEYBOARD_QWERTY;
if (keyboard_layout_dirty) {
-
layout = LATIN_KEYBOARD_QWERTY;
CGKeyCode keys[] = { kVK_ANSI_Q, kVK_ANSI_W, kVK_ANSI_E, kVK_ANSI_R, kVK_ANSI_T, kVK_ANSI_Y };
@@ -3002,13 +3070,13 @@ DisplayServerOSX::LatinKeyboardVariant DisplayServerOSX::get_latin_keyboard_vari
void DisplayServerOSX::_push_input(const Ref<InputEvent> &p_event) {
Ref<InputEvent> ev = p_event;
- InputFilter::get_singleton()->accumulate_input_event(ev);
+ Input::get_singleton()->accumulate_input_event(ev);
}
void DisplayServerOSX::_release_pressed_events() {
_THREAD_SAFE_METHOD_
- if (InputFilter::get_singleton()) {
- InputFilter::get_singleton()->release_pressed_events();
+ if (Input::get_singleton()) {
+ Input::get_singleton()->release_pressed_events();
}
}
@@ -3084,7 +3152,7 @@ void DisplayServerOSX::process_events() {
if (!drop_events) {
_process_key_events();
- InputFilter::get_singleton()->flush_accumulated_events();
+ Input::get_singleton()->flush_accumulated_events();
}
[autoreleasePool drain];
@@ -3393,7 +3461,7 @@ bool DisplayServerOSX::is_console_visible() const {
}
DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
- InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
+ Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
r_error = OK;
drop_events = false;
@@ -3513,7 +3581,6 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
#endif
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
-
context_vulkan = memnew(VulkanContextOSX);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
@@ -3524,7 +3591,10 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
}
#endif
- WindowID main_window = _create_window(p_mode, Rect2i(Point2i(), p_resolution));
+ Point2i window_position(
+ (screen_get_size(0).width - p_resolution.width) / 2,
+ (screen_get_size(0).height - p_resolution.height) / 2);
+ WindowID main_window = _create_window(p_mode, Rect2i(window_position, p_resolution));
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, main_window);
@@ -3570,7 +3640,6 @@ DisplayServerOSX::~DisplayServerOSX() {
//destroy drivers
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
-
if (rendering_device_vulkan) {
rendering_device_vulkan->finalize();
memdelete(rendering_device_vulkan);
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index c2df9c7082..784fba75ec 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -46,7 +46,6 @@
#include <sys/stat.h>
class EditorExportPlatformOSX : public EditorExportPlatform {
-
GDCLASS(EditorExportPlatformOSX, EditorExportPlatform);
int version_code;
@@ -58,6 +57,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform {
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path);
Error _create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name);
+ void _zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name);
#ifdef OSX_ENABLED
bool use_codesign() const { return true; }
@@ -89,7 +89,6 @@ public:
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const;
virtual void get_platform_features(List<String> *r_features) {
-
r_features->push_back("pc");
r_features->push_back("s3tc");
r_features->push_back("OSX");
@@ -117,7 +116,6 @@ void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset>
}
void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) {
-
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), ""));
@@ -148,7 +146,6 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options)
}
void _rgba8_to_packbits_encode(int p_ch, int p_size, Vector<uint8_t> &p_source, Vector<uint8_t> &p_dest) {
-
int src_len = p_size * p_size;
Vector<uint8_t> result;
@@ -163,7 +160,6 @@ void _rgba8_to_packbits_encode(int p_ch, int p_size, Vector<uint8_t> &p_source,
uint8_t cur = p_source.ptr()[i * 4 + p_ch];
if (i < src_len - 2) {
-
if ((p_source.ptr()[(i + 1) * 4 + p_ch] == cur) && (p_source.ptr()[(i + 2) * 4 + p_ch] == cur)) {
if (buf_size > 0) {
result.write[res_size++] = (uint8_t)(buf_size - 1);
@@ -215,7 +211,6 @@ void _rgba8_to_packbits_encode(int p_ch, int p_size, Vector<uint8_t> &p_source,
}
void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) {
-
Ref<ImageTexture> it = memnew(ImageTexture);
Vector<uint8_t> data;
@@ -320,7 +315,6 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_
}
void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary) {
-
String str;
String strnew;
str.parse_utf8((const char *)plist.ptr(), plist.size());
@@ -370,6 +364,7 @@ void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset
**/
Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
+#ifdef OSX_ENABLED
List<String> args;
if (p_preset->get("codesign/timestamp")) {
@@ -380,8 +375,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
args.push_back("runtime");
}
- if (p_preset->get("codesign/entitlements") != "") {
- /* this should point to our entitlements.plist file that sandboxes our application, I don't know if this should also be placed in our app bundle */
+ if ((p_preset->get("codesign/entitlements") != "") && (p_path.get_extension() != "dmg")) {
args.push_back("--entitlements");
args.push_back(p_preset->get("codesign/entitlements"));
}
@@ -414,6 +408,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
EditorNode::add_io_error("codesign: invalid entitlements file");
return FAILED;
}
+#endif
return OK;
}
@@ -458,10 +453,11 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
EditorProgress ep("export", "Exporting for OSX", 3, true);
- if (p_debug)
+ if (p_debug) {
src_pkg_name = p_preset->get("custom_template/debug");
- else
+ } else {
src_pkg_name = p_preset->get("custom_template/release");
+ }
if (src_pkg_name == "") {
String err;
@@ -485,7 +481,6 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io);
if (!src_pkg_zip) {
-
EditorNode::add_io_error("Could not find template app to export:\n" + src_pkg_name);
return ERR_FILE_NOT_FOUND;
}
@@ -495,64 +490,54 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
String binary_to_use = "godot_osx_" + String(p_debug ? "debug" : "release") + ".64";
String pkg_name;
- if (p_preset->get("application/name") != "")
+ if (p_preset->get("application/name") != "") {
pkg_name = p_preset->get("application/name"); // app_name
- else if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "")
+ } else if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") {
pkg_name = String(ProjectSettings::get_singleton()->get("application/config/name"));
- else
+ } else {
pkg_name = "Unnamed";
+ }
String pkg_name_safe = OS::get_singleton()->get_safe_dir_name(pkg_name);
Error err = OK;
String tmp_app_path_name = "";
- zlib_filefunc_def io2 = io;
- FileAccess *dst_f = nullptr;
- io2.opaque = &dst_f;
- zipFile dst_pkg_zip = nullptr;
DirAccess *tmp_app_path = nullptr;
String export_format = use_dmg() && p_path.ends_with("dmg") ? "dmg" : "zip";
- if (export_format == "dmg") {
- // We're on OSX so we can export to DMG, but first we create our application bundle
- tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".app");
- print_line("Exporting to " + tmp_app_path_name);
- tmp_app_path = DirAccess::create_for_path(tmp_app_path_name);
- if (!tmp_app_path) {
- err = ERR_CANT_CREATE;
- }
- // Create our folder structure or rely on unzip?
- if (err == OK) {
- print_line("Creating " + tmp_app_path_name + "/Contents/MacOS");
- err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS");
- }
+ // Create our application bundle.
+ tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".app");
+ print_line("Exporting to " + tmp_app_path_name);
+ tmp_app_path = DirAccess::create_for_path(tmp_app_path_name);
+ if (!tmp_app_path) {
+ err = ERR_CANT_CREATE;
+ }
- if (err == OK) {
- print_line("Creating " + tmp_app_path_name + "/Contents/Frameworks");
- err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks");
- }
+ // Create our folder structure.
+ if (err == OK) {
+ print_line("Creating " + tmp_app_path_name + "/Contents/MacOS");
+ err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS");
+ }
- if (err == OK) {
- print_line("Creating " + tmp_app_path_name + "/Contents/Resources");
- err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Resources");
- }
- } else {
- // Open our destination zip file
- dst_pkg_zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io2);
- if (!dst_pkg_zip) {
- err = ERR_CANT_CREATE;
- }
+ if (err == OK) {
+ print_line("Creating " + tmp_app_path_name + "/Contents/Frameworks");
+ err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Frameworks");
}
- // Now process our template
+ if (err == OK) {
+ print_line("Creating " + tmp_app_path_name + "/Contents/Resources");
+ err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Resources");
+ }
+
+ // Now process our template.
bool found_binary = false;
int total_size = 0;
while (ret == UNZ_OK && err == OK) {
bool is_execute = false;
- //get filename
+ // Get filename.
unz_file_info info;
char fname[16384];
ret = unzGetCurrentFileInfo(src_pkg_zip, &info, fname, 16384, nullptr, 0, nullptr, 0);
@@ -562,13 +547,12 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
- //read
+ // Read.
unzOpenCurrentFile(src_pkg_zip);
unzReadCurrentFile(src_pkg_zip, data.ptrw(), data.size());
unzCloseCurrentFile(src_pkg_zip);
- //write
-
+ // Write.
file = file.replace_first("osx_template.app/", "");
if (file == "Contents/Info.plist") {
@@ -578,7 +562,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (file.begins_with("Contents/MacOS/godot_")) {
if (file != "Contents/MacOS/" + binary_to_use) {
ret = unzGoToNextFile(src_pkg_zip);
- continue; //ignore!
+ continue; // skip
}
found_binary = true;
is_execute = true;
@@ -586,12 +570,13 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
if (file == "Contents/Resources/icon.icns") {
- //see if there is an icon
+ // See if there is an icon.
String iconpath;
- if (p_preset->get("application/icon") != "")
+ if (p_preset->get("application/icon") != "") {
iconpath = p_preset->get("application/icon");
- else
+ } else {
iconpath = ProjectSettings::get_singleton()->get("application/config/icon");
+ }
if (iconpath != "") {
if (iconpath.get_extension() == "icns") {
@@ -614,18 +599,17 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
if (data.size() > 0) {
-
if (file.find("/data.mono.osx.64.release_debug/") != -1) {
if (!p_debug) {
ret = unzGoToNextFile(src_pkg_zip);
- continue; //skip
+ continue; // skip
}
file = file.replace("/data.mono.osx.64.release_debug/", "/data_" + pkg_name_safe + "/");
}
if (file.find("/data.mono.osx.64.release/") != -1) {
if (p_debug) {
ret = unzGoToNextFile(src_pkg_zip);
- continue; //skip
+ continue; // skip
}
file = file.replace("/data.mono.osx.64.release/", "/data_" + pkg_name_safe + "/");
}
@@ -633,62 +617,31 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
print_line("ADDING: " + file + " size: " + itos(data.size()));
total_size += data.size();
- if (export_format == "dmg") {
- // write it into our application bundle
- file = tmp_app_path_name.plus_file(file);
- if (err == OK) {
- err = tmp_app_path->make_dir_recursive(file.get_base_dir());
- }
- if (err == OK) {
- // write the file, need to add chmod
- FileAccess *f = FileAccess::open(file, FileAccess::WRITE);
- if (f) {
- f->store_buffer(data.ptr(), data.size());
- f->close();
- if (is_execute) {
- // Chmod with 0755 if the file is executable
- FileAccess::set_unix_permissions(file, 0755);
- }
- memdelete(f);
- } else {
- err = ERR_CANT_CREATE;
+ // Write it into our application bundle.
+ file = tmp_app_path_name.plus_file(file);
+ if (err == OK) {
+ err = tmp_app_path->make_dir_recursive(file.get_base_dir());
+ }
+ if (err == OK) {
+ FileAccess *f = FileAccess::open(file, FileAccess::WRITE);
+ if (f) {
+ f->store_buffer(data.ptr(), data.size());
+ f->close();
+ if (is_execute) {
+ // chmod with 0755 if the file is executable.
+ FileAccess::set_unix_permissions(file, 0755);
}
+ memdelete(f);
+ } else {
+ err = ERR_CANT_CREATE;
}
- } else {
- // add it to our zip file
- file = pkg_name + ".app/" + file;
-
- zip_fileinfo fi;
- fi.tmz_date.tm_hour = info.tmu_date.tm_hour;
- fi.tmz_date.tm_min = info.tmu_date.tm_min;
- fi.tmz_date.tm_sec = info.tmu_date.tm_sec;
- fi.tmz_date.tm_mon = info.tmu_date.tm_mon;
- fi.tmz_date.tm_mday = info.tmu_date.tm_mday;
- fi.tmz_date.tm_year = info.tmu_date.tm_year;
- fi.dosDate = info.dosDate;
- fi.internal_fa = info.internal_fa;
- fi.external_fa = info.external_fa;
-
- zipOpenNewFileInZip(dst_pkg_zip,
- file.utf8().get_data(),
- &fi,
- nullptr,
- 0,
- nullptr,
- 0,
- nullptr,
- Z_DEFLATED,
- Z_DEFAULT_COMPRESSION);
-
- zipWriteInFileInZip(dst_pkg_zip, data.ptr(), data.size());
- zipCloseFileInZip(dst_pkg_zip);
}
}
ret = unzGoToNextFile(src_pkg_zip);
}
- // we're done with our source zip
+ // We're done with our source zip.
unzClose(src_pkg_zip);
if (!found_binary) {
@@ -701,124 +654,131 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
return ERR_SKIP;
}
- if (export_format == "dmg") {
- String pack_path = tmp_app_path_name + "/Contents/Resources/" + pkg_name + ".pck";
- Vector<SharedObject> shared_objects;
- err = save_pack(p_preset, pack_path, &shared_objects);
+ String pack_path = tmp_app_path_name + "/Contents/Resources/" + pkg_name + ".pck";
+ Vector<SharedObject> shared_objects;
+ err = save_pack(p_preset, pack_path, &shared_objects);
- // see if we can code sign our new package
- bool sign_enabled = p_preset->get("codesign/enable");
+ // See if we can code sign our new package.
+ bool sign_enabled = p_preset->get("codesign/enable");
- if (err == OK) {
- DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- for (int i = 0; i < shared_objects.size(); i++) {
- err = da->copy(shared_objects[i].path, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file());
- if (err == OK && sign_enabled) {
- err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file());
- }
+ if (err == OK) {
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
+ for (int i = 0; i < shared_objects.size(); i++) {
+ err = da->copy(shared_objects[i].path, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file());
+ if (err == OK && sign_enabled) {
+ err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Frameworks/" + shared_objects[i].path.get_file());
}
- memdelete(da);
}
+ memdelete(da);
+ }
- if (err == OK && sign_enabled) {
- if (ep.step("Code signing bundle", 2)) {
- return ERR_SKIP;
- }
-
- // the order in which we code sign is important, this is a bit of a shame or we could do this in our loop that extracts the files from our ZIP
-
- // start with our application
- err = _code_sign(p_preset, tmp_app_path_name + "/Contents/MacOS/" + pkg_name);
-
- ///@TODO we should check the contents of /Contents/Frameworks for frameworks to sign
+ if (err == OK && sign_enabled) {
+ if (ep.step("Code signing bundle", 2)) {
+ return ERR_SKIP;
}
+ err = _code_sign(p_preset, tmp_app_path_name + "/Contents/MacOS/" + pkg_name);
+ }
- // and finally create a DMG
+ if (export_format == "dmg") {
+ // Create a DMG.
if (err == OK) {
if (ep.step("Making DMG", 3)) {
return ERR_SKIP;
}
err = _create_dmg(p_path, pkg_name, tmp_app_path_name);
}
-
- // Clean up temporary .app dir
- OS::get_singleton()->move_to_trash(tmp_app_path_name);
-
- } else { // pck
-
- String pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".pck");
-
- Vector<SharedObject> shared_objects;
- err = save_pack(p_preset, pack_path, &shared_objects);
-
- if (err == OK) {
- zipOpenNewFileInZip(dst_pkg_zip,
- (pkg_name + ".app/Contents/Resources/" + pkg_name + ".pck").utf8().get_data(),
- nullptr,
- nullptr,
- 0,
- nullptr,
- 0,
- nullptr,
- Z_DEFLATED,
- Z_DEFAULT_COMPRESSION);
-
- FileAccess *pf = FileAccess::open(pack_path, FileAccess::READ);
- if (pf) {
- const int BSIZE = 16384;
- uint8_t buf[BSIZE];
-
- while (true) {
-
- int r = pf->get_buffer(buf, BSIZE);
- if (r <= 0)
- break;
- zipWriteInFileInZip(dst_pkg_zip, buf, r);
- }
-
- zipCloseFileInZip(dst_pkg_zip);
- memdelete(pf);
- } else {
- err = ERR_CANT_OPEN;
+ // Sign DMG.
+ if (err == OK && sign_enabled) {
+ if (ep.step("Code signing DMG", 3)) {
+ return ERR_SKIP;
}
+ err = _code_sign(p_preset, p_path);
}
-
+ } else {
+ // Create ZIP.
if (err == OK) {
- //add shared objects
- for (int i = 0; i < shared_objects.size(); i++) {
- Vector<uint8_t> file = FileAccess::get_file_as_array(shared_objects[i].path);
- ERR_CONTINUE(file.empty());
-
- zipOpenNewFileInZip(dst_pkg_zip,
- (pkg_name + ".app/Contents/Frameworks/").plus_file(shared_objects[i].path.get_file()).utf8().get_data(),
- nullptr,
- nullptr,
- 0,
- nullptr,
- 0,
- nullptr,
- Z_DEFLATED,
- Z_DEFAULT_COMPRESSION);
-
- zipWriteInFileInZip(dst_pkg_zip, file.ptr(), file.size());
- zipCloseFileInZip(dst_pkg_zip);
+ if (ep.step("Making ZIP", 3)) {
+ return ERR_SKIP;
+ }
+ if (FileAccess::exists(p_path)) {
+ OS::get_singleton()->move_to_trash(p_path);
}
- }
- // Clean up generated file.
- DirAccess::remove_file_or_error(pack_path);
+ FileAccess *dst_f = nullptr;
+ zlib_filefunc_def io_dst = zipio_create_io_from_file(&dst_f);
+ zipFile zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io_dst);
+
+ _zip_folder_recursive(zip, EditorSettings::get_singleton()->get_cache_dir(), pkg_name + ".app", pkg_name);
+
+ zipClose(zip, nullptr);
+ }
}
- }
- if (dst_pkg_zip) {
- zipClose(dst_pkg_zip, nullptr);
+ // Clean up temporary .app dir.
+ OS::get_singleton()->move_to_trash(tmp_app_path_name);
}
return err;
}
-bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
+void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String &p_root_path, const String &p_folder, const String &p_pkg_name) {
+ String dir = p_root_path.plus_file(p_folder);
+ DirAccess *da = DirAccess::open(dir);
+ da->list_dir_begin();
+ String f;
+ while ((f = da->get_next()) != "") {
+ if (f == "." || f == "..") {
+ continue;
+ }
+ if (da->current_is_dir()) {
+ _zip_folder_recursive(p_zip, p_root_path, p_folder.plus_file(f), p_pkg_name);
+ } else {
+ bool is_executable = (p_folder.ends_with("MacOS") && (f == p_pkg_name));
+
+ OS::Time time = OS::get_singleton()->get_time();
+ OS::Date date = OS::get_singleton()->get_date();
+
+ zip_fileinfo zipfi;
+ zipfi.tmz_date.tm_hour = time.hour;
+ zipfi.tmz_date.tm_mday = date.day;
+ zipfi.tmz_date.tm_min = time.min;
+ zipfi.tmz_date.tm_mon = date.month;
+ zipfi.tmz_date.tm_sec = time.sec;
+ zipfi.tmz_date.tm_year = date.year;
+ zipfi.dosDate = 0;
+ zipfi.external_fa = (is_executable ? 0755 : 0644) << 16L;
+ zipfi.internal_fa = 0;
+
+ zipOpenNewFileInZip4(p_zip,
+ p_folder.plus_file(f).utf8().get_data(),
+ &zipfi,
+ nullptr,
+ 0,
+ nullptr,
+ 0,
+ nullptr,
+ Z_DEFLATED,
+ Z_DEFAULT_COMPRESSION,
+ 0,
+ -MAX_WBITS,
+ DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY,
+ nullptr,
+ 0,
+ 0x0314, // "version made by", 0x03 - Unix, 0x14 - ZIP specification version 2.0, required to store Unix file permissions
+ 0);
+
+ Vector<uint8_t> array = FileAccess::get_file_as_array(dir.plus_file(f));
+ zipWriteInFileInZip(p_zip, array.ptr(), array.size());
+ zipCloseFileInZip(p_zip);
+ }
+ }
+ da->list_dir_end();
+ memdelete(da);
+}
+
+bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
String err;
bool valid = false;
@@ -843,13 +803,13 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
valid = dvalid || rvalid;
r_missing_templates = !valid;
- if (!err.empty())
+ if (!err.empty()) {
r_error = err;
+ }
return valid;
}
EditorExportPlatformOSX::EditorExportPlatformOSX() {
-
Ref<Image> img = memnew(Image(_osx_logo));
logo.instance();
logo->create_from_image(img);
@@ -859,7 +819,6 @@ EditorExportPlatformOSX::~EditorExportPlatformOSX() {
}
void register_osx_exporter() {
-
Ref<EditorExportPlatformOSX> platform;
platform.instance();
diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm
index eacd2b5cc6..93d0d6168c 100644
--- a/platform/osx/godot_main_osx.mm
+++ b/platform/osx/godot_main_osx.mm
@@ -36,7 +36,6 @@
#include <unistd.h>
int main(int argc, char **argv) {
-
#if defined(VULKAN_ENABLED)
//MoltenVK - enable full component swizzling support
setenv("MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE", "1", 1);
diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp
index 643acd8944..d342d30097 100644
--- a/platform/osx/joypad_osx.cpp
+++ b/platform/osx/joypad_osx.cpp
@@ -98,6 +98,7 @@ int joypad::get_hid_element_state(rec_element *p_element) const {
}
return value;
}
+
void joypad::add_hid_element(IOHIDElementRef p_element) {
const CFTypeID elementTypeID = p_element ? CFGetTypeID(p_element) : 0;
@@ -240,7 +241,6 @@ static bool is_joypad(IOHIDDeviceRef p_device_ref) {
}
void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) {
-
if (p_res != kIOReturnSuccess || have_device(p_device)) {
return;
}
@@ -264,7 +264,6 @@ void JoypadOSX::_device_added(IOReturn p_res, IOHIDDeviceRef p_device) {
}
void JoypadOSX::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) {
-
int device = get_joy_ref(p_device);
ERR_FAIL_COND(device == -1);
@@ -274,7 +273,6 @@ void JoypadOSX::_device_removed(IOReturn p_res, IOHIDDeviceRef p_device) {
}
static String _hex_str(uint8_t p_byte) {
-
static const char *dict = "0123456789abcdef";
char ret[3];
ret[2] = 0;
@@ -286,7 +284,6 @@ static String _hex_str(uint8_t p_byte) {
}
bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) {
-
p_joy->device_ref = p_device_ref;
/* get device name */
String name;
@@ -346,7 +343,6 @@ bool JoypadOSX::configure_joypad(IOHIDDeviceRef p_device_ref, joypad *p_joy) {
} \
}
bool joypad::config_force_feedback(io_service_t p_service) {
-
HRESULT ret = FFCreateDevice(p_service, &ff_device);
ERR_FAIL_COND_V(ret != FF_OK, false);
@@ -368,13 +364,13 @@ bool joypad::config_force_feedback(io_service_t p_service) {
#define TEST_FF(ff) (features.supportedEffects & (ff))
bool joypad::check_ff_features() {
-
FFCAPABILITIES features;
HRESULT ret = FFDeviceGetForceFeedbackCapabilities(ff_device, &features);
if (ret == FF_OK && (features.supportedEffects & FFCAP_ET_CONSTANTFORCE)) {
uint32_t val;
ret = FFDeviceGetForceFeedbackProperty(ff_device, FFPROP_FFGAIN, &val, sizeof(val));
- if (ret != FF_OK) return false;
+ if (ret != FF_OK)
+ return false;
int num_axes = features.numFfAxes;
ff_axes = (DWORD *)memalloc(sizeof(DWORD) * num_axes);
ff_directions = (LONG *)memalloc(sizeof(LONG) * num_axes);
@@ -395,38 +391,38 @@ bool joypad::check_ff_features() {
static int process_hat_value(int p_min, int p_max, int p_value) {
int range = (p_max - p_min + 1);
int value = p_value - p_min;
- int hat_value = InputFilter::HAT_MASK_CENTER;
+ int hat_value = Input::HAT_MASK_CENTER;
if (range == 4) {
value *= 2;
}
switch (value) {
case 0:
- hat_value = InputFilter::HAT_MASK_UP;
+ hat_value = Input::HAT_MASK_UP;
break;
case 1:
- hat_value = InputFilter::HAT_MASK_UP | InputFilter::HAT_MASK_RIGHT;
+ hat_value = Input::HAT_MASK_UP | Input::HAT_MASK_RIGHT;
break;
case 2:
- hat_value = InputFilter::HAT_MASK_RIGHT;
+ hat_value = Input::HAT_MASK_RIGHT;
break;
case 3:
- hat_value = InputFilter::HAT_MASK_DOWN | InputFilter::HAT_MASK_RIGHT;
+ hat_value = Input::HAT_MASK_DOWN | Input::HAT_MASK_RIGHT;
break;
case 4:
- hat_value = InputFilter::HAT_MASK_DOWN;
+ hat_value = Input::HAT_MASK_DOWN;
break;
case 5:
- hat_value = InputFilter::HAT_MASK_DOWN | InputFilter::HAT_MASK_LEFT;
+ hat_value = Input::HAT_MASK_DOWN | Input::HAT_MASK_LEFT;
break;
case 6:
- hat_value = InputFilter::HAT_MASK_LEFT;
+ hat_value = Input::HAT_MASK_LEFT;
break;
case 7:
- hat_value = InputFilter::HAT_MASK_UP | InputFilter::HAT_MASK_LEFT;
+ hat_value = Input::HAT_MASK_UP | Input::HAT_MASK_LEFT;
break;
default:
- hat_value = InputFilter::HAT_MASK_CENTER;
+ hat_value = Input::HAT_MASK_CENTER;
break;
}
return hat_value;
@@ -438,8 +434,8 @@ void JoypadOSX::poll_joypads() const {
}
}
-static const InputFilter::JoyAxis axis_correct(int p_value, int p_min, int p_max) {
- InputFilter::JoyAxis jx;
+static const Input::JoyAxis axis_correct(int p_value, int p_min, int p_max) {
+ Input::JoyAxis jx;
if (p_min < 0) {
jx.min = -1;
if (p_value < 0) {
@@ -509,14 +505,16 @@ void JoypadOSX::joypad_vibration_stop(int p_id, uint64_t p_timestamp) {
int JoypadOSX::get_joy_index(int p_id) const {
for (int i = 0; i < device_list.size(); i++) {
- if (device_list[i].id == p_id) return i;
+ if (device_list[i].id == p_id)
+ return i;
}
return -1;
}
int JoypadOSX::get_joy_ref(IOHIDDeviceRef p_device) const {
for (int i = 0; i < device_list.size(); i++) {
- if (device_list[i].device_ref == p_device) return i;
+ if (device_list[i].device_ref == p_device)
+ return i;
}
return -1;
}
@@ -556,7 +554,6 @@ static CFDictionaryRef create_match_dictionary(const UInt32 page, const UInt32 u
}
void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const {
-
CFRunLoopRef runloop = CFRunLoopGetCurrent();
IOReturn ret = IOHIDManagerOpen(hid_manager, kIOHIDOptionsTypeNone);
ERR_FAIL_COND(ret != kIOReturnSuccess);
@@ -571,7 +568,7 @@ void JoypadOSX::config_hid_manager(CFArrayRef p_matching_array) const {
}
}
-JoypadOSX::JoypadOSX(InputFilter *in) {
+JoypadOSX::JoypadOSX(Input *in) {
self = this;
input = in;
@@ -600,7 +597,6 @@ JoypadOSX::JoypadOSX(InputFilter *in) {
}
JoypadOSX::~JoypadOSX() {
-
for (int i = 0; i < device_list.size(); i++) {
device_list.write[i].free();
}
diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h
index 62027c6a30..dc238e68e4 100644
--- a/platform/osx/joypad_osx.h
+++ b/platform/osx/joypad_osx.h
@@ -40,7 +40,7 @@
#include <ForceFeedback/ForceFeedbackConstants.h>
#include <IOKit/hid/IOHIDLib.h>
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
struct rec_element {
IOHIDElementRef ref;
@@ -88,13 +88,12 @@ struct joypad {
};
class JoypadOSX {
-
enum {
JOYPADS_MAX = 16,
};
private:
- InputFilter *input;
+ Input *input;
IOHIDManagerRef hid_manager;
Vector<joypad> device_list;
@@ -118,7 +117,7 @@ public:
void _device_added(IOReturn p_res, IOHIDDeviceRef p_device);
void _device_removed(IOReturn p_res, IOHIDDeviceRef p_device);
- JoypadOSX(InputFilter *in);
+ JoypadOSX(Input *in);
~JoypadOSX();
};
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index d2c67cff9f..9204a145bf 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -31,7 +31,7 @@
#ifndef OS_OSX_H
#define OS_OSX_H
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "crash_handler_osx.h"
#include "drivers/coreaudio/audio_driver_coreaudio.h"
#include "drivers/coremidi/midi_driver_coremidi.h"
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 49cb056c9f..dba96ccfcd 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -60,39 +60,31 @@ public:
switch (p_type) {
case ERR_WARNING:
- if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) {
- os_log_info(OS_LOG_DEFAULT,
- "WARNING: %{public}s\nat: %{public}s (%{public}s:%i)",
- err_details, p_function, p_file, p_line);
- }
+ os_log_info(OS_LOG_DEFAULT,
+ "WARNING: %{public}s\nat: %{public}s (%{public}s:%i)",
+ err_details, p_function, p_file, p_line);
logf_error("\E[1;33mWARNING:\E[0;93m %s\n", err_details);
logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line);
break;
case ERR_SCRIPT:
- if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) {
- os_log_error(OS_LOG_DEFAULT,
- "SCRIPT ERROR: %{public}s\nat: %{public}s (%{public}s:%i)",
- err_details, p_function, p_file, p_line);
- }
+ os_log_error(OS_LOG_DEFAULT,
+ "SCRIPT ERROR: %{public}s\nat: %{public}s (%{public}s:%i)",
+ err_details, p_function, p_file, p_line);
logf_error("\E[1;35mSCRIPT ERROR:\E[0;95m %s\n", err_details);
logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line);
break;
case ERR_SHADER:
- if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) {
- os_log_error(OS_LOG_DEFAULT,
- "SHADER ERROR: %{public}s\nat: %{public}s (%{public}s:%i)",
- err_details, p_function, p_file, p_line);
- }
+ os_log_error(OS_LOG_DEFAULT,
+ "SHADER ERROR: %{public}s\nat: %{public}s (%{public}s:%i)",
+ err_details, p_function, p_file, p_line);
logf_error("\E[1;36mSHADER ERROR:\E[0;96m %s\n", err_details);
logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line);
break;
case ERR_ERROR:
default:
- if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) {
- os_log_error(OS_LOG_DEFAULT,
- "ERROR: %{public}s\nat: %{public}s (%{public}s:%i)",
- err_details, p_function, p_file, p_line);
- }
+ os_log_error(OS_LOG_DEFAULT,
+ "ERROR: %{public}s\nat: %{public}s (%{public}s:%i)",
+ err_details, p_function, p_file, p_line);
logf_error("\E[1;31mERROR:\E[0;91m %s\n", err_details);
logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line);
break;
@@ -136,7 +128,7 @@ void OS_OSX::initialize_core() {
}
void OS_OSX::initialize_joypads() {
- joypad_osx = memnew(JoypadOSX(InputFilter::get_singleton()));
+ joypad_osx = memnew(JoypadOSX(Input::get_singleton()));
}
void OS_OSX::initialize() {
@@ -147,7 +139,6 @@ void OS_OSX::initialize() {
}
void OS_OSX::finalize() {
-
#ifdef COREMIDI_ENABLED
midi_driver.close();
#endif
@@ -269,10 +260,8 @@ String OS_OSX::get_system_dir(SystemDir p_dir) const {
String ret;
if (found) {
-
NSArray *paths = NSSearchPathForDirectoriesInDomains(id, NSUserDomainMask, YES);
if (paths && [paths count] >= 1) {
-
char *utfs = strdup([[paths firstObject] UTF8String]);
ret.parse_utf8(utfs);
free(utfs);
diff --git a/platform/osx/vulkan_context_osx.h b/platform/osx/vulkan_context_osx.h
index 09a5494ae8..e996f176a9 100644
--- a/platform/osx/vulkan_context_osx.h
+++ b/platform/osx/vulkan_context_osx.h
@@ -35,7 +35,6 @@
#include <AppKit/AppKit.h>
class VulkanContextOSX : public VulkanContext {
-
virtual const char *_get_platform_surface_extension() const;
public:
diff --git a/platform/osx/vulkan_context_osx.mm b/platform/osx/vulkan_context_osx.mm
index 320401cdcb..ec8745ff01 100644
--- a/platform/osx/vulkan_context_osx.mm
+++ b/platform/osx/vulkan_context_osx.mm
@@ -36,7 +36,6 @@ const char *VulkanContextOSX::_get_platform_surface_extension() const {
}
Error VulkanContextOSX::window_create(DisplayServer::WindowID p_window_id, id p_window, int p_width, int p_height) {
-
VkMacOSSurfaceCreateInfoMVK createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK;
createInfo.pNext = NULL;
diff --git a/platform/server/godot_server.cpp b/platform/server/godot_server.cpp
index df49bfaebf..32bd943ac3 100644
--- a/platform/server/godot_server.cpp
+++ b/platform/server/godot_server.cpp
@@ -32,7 +32,6 @@
#include "os_server.h"
int main(int argc, char *argv[]) {
-
OS_Server os;
Error err = Main::setup(argv[0], argc - 1, &argv[1]);
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index 0fda0663a2..fbe526ef6d 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -42,11 +42,10 @@
#include <unistd.h>
int OS_Server::get_video_driver_count() const {
-
return 1;
}
-const char *OS_Server::get_video_driver_name(int p_driver) const {
+const char *OS_Server::get_video_driver_name(int p_driver) const {
return "Dummy";
}
@@ -55,7 +54,6 @@ int OS_Server::get_audio_driver_count() const {
}
const char *OS_Server::get_audio_driver_name(int p_driver) const {
-
return "Dummy";
}
@@ -64,14 +62,12 @@ int OS_Server::get_current_video_driver() const {
}
void OS_Server::initialize_core() {
-
crash_handler.initialize();
OS_Unix::initialize_core();
}
Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
-
args = OS::get_singleton()->get_cmdline_args();
current_videomode = p_desired;
main_loop = nullptr;
@@ -96,7 +92,6 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int
}
void OS_Server::finalize() {
-
if (main_loop)
memdelete(main_loop);
main_loop = nullptr;
@@ -116,22 +111,18 @@ void OS_Server::set_mouse_show(bool p_show) {
}
void OS_Server::set_mouse_grab(bool p_grab) {
-
grab = p_grab;
}
bool OS_Server::is_mouse_grab_enabled() const {
-
return grab;
}
int OS_Server::get_mouse_button_state() const {
-
return 0;
}
Point2 OS_Server::get_mouse_position() const {
-
return Point2();
}
@@ -142,12 +133,10 @@ void OS_Server::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
}
OS::VideoMode OS_Server::get_video_mode(int p_screen) const {
-
return current_videomode;
}
Size2 OS_Server::get_window_size() const {
-
return Vector2(current_videomode.width, current_videomode.height);
}
@@ -155,30 +144,25 @@ void OS_Server::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen)
}
MainLoop *OS_Server::get_main_loop() const {
-
return main_loop;
}
void OS_Server::delete_main_loop() {
-
if (main_loop)
memdelete(main_loop);
main_loop = nullptr;
}
void OS_Server::set_main_loop(MainLoop *p_main_loop) {
-
main_loop = p_main_loop;
input->set_main_loop(p_main_loop);
}
bool OS_Server::can_draw() const {
-
return false; //can never draw
};
String OS_Server::get_name() const {
-
return "Server";
}
@@ -190,7 +174,6 @@ bool OS_Server::_check_internal_feature_support(const String &p_feature) {
}
void OS_Server::run() {
-
force_quit = false;
if (!main_loop)
@@ -199,7 +182,6 @@ void OS_Server::run() {
main_loop->init();
while (!force_quit) {
-
if (Main::iteration())
break;
};
@@ -208,7 +190,6 @@ void OS_Server::run() {
}
String OS_Server::get_config_path() const {
-
if (has_environment("XDG_CONFIG_HOME")) {
return get_environment("XDG_CONFIG_HOME");
} else if (has_environment("HOME")) {
@@ -219,7 +200,6 @@ String OS_Server::get_config_path() const {
}
String OS_Server::get_data_path() const {
-
if (has_environment("XDG_DATA_HOME")) {
return get_environment("XDG_DATA_HOME");
} else if (has_environment("HOME")) {
@@ -230,7 +210,6 @@ String OS_Server::get_data_path() const {
}
String OS_Server::get_cache_path() const {
-
if (has_environment("XDG_CACHE_HOME")) {
return get_environment("XDG_CACHE_HOME");
} else if (has_environment("HOME")) {
@@ -241,46 +220,37 @@ String OS_Server::get_cache_path() const {
}
String OS_Server::get_system_dir(SystemDir p_dir) const {
-
String xdgparam;
switch (p_dir) {
case SYSTEM_DIR_DESKTOP: {
-
xdgparam = "DESKTOP";
} break;
case SYSTEM_DIR_DCIM: {
-
xdgparam = "PICTURES";
} break;
case SYSTEM_DIR_DOCUMENTS: {
-
xdgparam = "DOCUMENTS";
} break;
case SYSTEM_DIR_DOWNLOADS: {
-
xdgparam = "DOWNLOAD";
} break;
case SYSTEM_DIR_MOVIES: {
-
xdgparam = "VIDEOS";
} break;
case SYSTEM_DIR_MUSIC: {
-
xdgparam = "MUSIC";
} break;
case SYSTEM_DIR_PICTURES: {
-
xdgparam = "PICTURES";
} break;
case SYSTEM_DIR_RINGTONES: {
-
xdgparam = "MUSIC";
} break;
@@ -304,7 +274,6 @@ bool OS_Server::is_disable_crash_handler() const {
}
OS_Server::OS_Server() {
-
//adriver here
grab = false;
};
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index 62028b26e4..06ea483fd4 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -31,7 +31,7 @@
#ifndef OS_SERVER_H
#define OS_SERVER_H
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "drivers/dummy/texture_loader_dummy.h"
#include "drivers/unix/os_unix.h"
#ifdef __APPLE__
@@ -47,7 +47,6 @@
#undef CursorShape
class OS_Server : public OS_Unix {
-
RenderingServer *rendering_server;
VideoMode current_videomode;
List<String> args;
diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp
index d3870b0b6c..6090d13854 100644
--- a/platform/uwp/app.cpp
+++ b/platform/uwp/app.cpp
@@ -78,16 +78,6 @@ public:
return 0;
}
-App::App() :
- mWindowClosed(false),
- mWindowVisible(true),
- mWindowWidth(0),
- mWindowHeight(0),
- mEglDisplay(EGL_NO_DISPLAY),
- mEglContext(EGL_NO_CONTEXT),
- mEglSurface(EGL_NO_SURFACE) {
-}
-
// The first method called when the IFrameworkView is being created.
void App::Initialize(CoreApplicationView ^ applicationView) {
// Register event handlers for app lifecycle. This example includes Activated, so that we
@@ -156,7 +146,6 @@ void App::SetWindow(CoreWindow ^ p_window) {
}
static int _get_button(Windows::UI::Input::PointerPoint ^ pt) {
-
using namespace Windows::UI::Input;
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
@@ -207,7 +196,6 @@ static bool _is_touch(Windows::UI::Input::PointerPoint ^ pointerPoint) {
}
static Windows::Foundation::Point _get_pixel_position(CoreWindow ^ window, Windows::Foundation::Point rawPosition, OS *os) {
-
Windows::Foundation::Point outputPosition;
// Compute coordinates normalized from 0..1.
@@ -247,17 +235,14 @@ static Windows::Foundation::Point _get_pixel_position(CoreWindow ^ window, Windo
};
static int _get_finger(uint32_t p_touch_id) {
-
return p_touch_id % 31; // for now
};
void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args, bool p_pressed, bool p_is_wheel) {
-
Windows::UI::Input::PointerPoint ^ point = args->CurrentPoint;
Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os);
int but = _get_button(point);
if (_is_touch(point)) {
-
Ref<InputEventScreenTouch> screen_touch;
screen_touch.instance();
screen_touch->set_device(0);
@@ -270,7 +255,6 @@ void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Cor
os->input_event(screen_touch);
} else {
-
Ref<InputEventMouseButton> mouse_button;
mouse_button.instance();
mouse_button->set_device(0);
@@ -301,22 +285,18 @@ void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Cor
};
void App::OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
-
pointer_event(sender, args, true);
};
void App::OnPointerReleased(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
-
pointer_event(sender, args, false);
};
void App::OnPointerWheelChanged(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
-
pointer_event(sender, args, true, true);
}
void App::OnMouseModeChanged(Windows::System::Threading::Core::SignalNotifier ^ signalNotifier, bool timedOut) {
-
OS::MouseMode mode = os->get_mouse_mode();
SignalNotifier ^ notifier = mouseChangedNotifier;
@@ -325,12 +305,10 @@ void App::OnMouseModeChanged(Windows::System::Threading::Core::SignalNotifier ^
ref new DispatchedHandler(
[mode, notifier, this]() {
if (mode == OS::MOUSE_MODE_CAPTURED) {
-
this->MouseMovedToken = MouseDevice::GetForCurrentView()->MouseMoved +=
ref new TypedEventHandler<MouseDevice ^, MouseEventArgs ^>(this, &App::OnMouseMoved);
} else {
-
MouseDevice::GetForCurrentView()->MouseMoved -= MouseMovedToken;
}
@@ -341,12 +319,10 @@ void App::OnMouseModeChanged(Windows::System::Threading::Core::SignalNotifier ^
}
void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
-
Windows::UI::Input::PointerPoint ^ point = args->CurrentPoint;
Windows::Foundation::Point pos = _get_pixel_position(window, point->Position, os);
if (_is_touch(point)) {
-
Ref<InputEventScreenDrag> screen_drag;
screen_drag.instance();
screen_drag->set_device(0);
@@ -356,7 +332,6 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co
os->input_event(screen_drag);
} else {
-
// In case the mouse grabbed, MouseMoved will handle this
if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED)
return;
@@ -375,7 +350,6 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co
}
void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
-
// In case the mouse isn't grabbed, PointerMoved will handle this
if (os->get_mouse_mode() != OS::MouseMode::MOUSE_MODE_CAPTURED)
return;
@@ -397,7 +371,6 @@ void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
}
void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Windows::UI::Core::KeyEventArgs ^ key_args, Windows::UI::Core::CharacterReceivedEventArgs ^ char_args) {
-
OS_UWP::KeyEvent ke;
ke.control = sender->GetAsyncKeyState(VirtualKey::Control) == CoreVirtualKeyStates::Down;
@@ -407,7 +380,6 @@ void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Wind
ke.pressed = p_pressed;
if (key_args != nullptr) {
-
ke.type = OS_UWP::KeyEvent::MessageType::KEY_EVENT_MESSAGE;
ke.unicode = 0;
ke.keycode = KeyMappingWindows::get_keysym((unsigned int)key_args->VirtualKey);
@@ -415,7 +387,6 @@ void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Wind
ke.echo = (!p_pressed && !key_args->KeyStatus.IsKeyReleased) || (p_pressed && key_args->KeyStatus.WasKeyDown);
} else {
-
ke.type = OS_UWP::KeyEvent::MessageType::CHAR_EVENT_MESSAGE;
ke.unicode = char_args->KeyCode;
ke.keycode = 0;
@@ -425,6 +396,7 @@ void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Wind
os->queue_key_event(ke);
}
+
void App::OnKeyDown(CoreWindow ^ sender, KeyEventArgs ^ args) {
key_event(sender, true, args);
}
@@ -506,14 +478,12 @@ void App::UpdateWindowSize(Size size) {
}
char **App::get_command_line(unsigned int *out_argc) {
-
static char *fail_cl[] = { "--path", "game", nullptr };
*out_argc = 2;
FILE *f = _wfopen(L"__cl__.cl", L"rb");
if (f == nullptr) {
-
wprintf(L"Couldn't open command line file.\n");
return fail_cl;
}
@@ -535,7 +505,6 @@ char **App::get_command_line(unsigned int *out_argc) {
int argc = READ_LE_4(len);
for (int i = 0; i < argc; i++) {
-
r = fread(len, sizeof(uint8_t), 4, f);
if (r < 4) {
@@ -557,7 +526,6 @@ char **App::get_command_line(unsigned int *out_argc) {
arg[strlen] = '\0';
if (r == strlen) {
-
int warg_size = MultiByteToWideChar(CP_UTF8, 0, arg, -1, nullptr, 0);
wchar_t *warg = new wchar_t[warg_size];
@@ -566,7 +534,6 @@ char **App::get_command_line(unsigned int *out_argc) {
cl.Append(ref new Platform::String(warg, warg_size));
} else {
-
delete[] arg;
fclose(f);
wprintf(L"Error reading command.\n");
@@ -582,7 +549,6 @@ char **App::get_command_line(unsigned int *out_argc) {
char **ret = new char *[cl.Size + 1];
for (int i = 0; i < cl.Size; i++) {
-
int arg_size = WideCharToMultiByte(CP_UTF8, 0, cl.GetAt(i)->Data(), -1, nullptr, 0, nullptr, nullptr);
char *arg = new char[arg_size];
diff --git a/platform/uwp/app.h b/platform/uwp/app.h
index b7265ad086..5cffe378b1 100644
--- a/platform/uwp/app.h
+++ b/platform/uwp/app.h
@@ -45,7 +45,7 @@ namespace GodotUWP
ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView
{
public:
- App();
+ App() {}
// IFrameworkView Methods.
virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView);
@@ -92,14 +92,14 @@ namespace GodotUWP
char** get_command_line(unsigned int* out_argc);
- bool mWindowClosed;
- bool mWindowVisible;
- GLsizei mWindowWidth;
- GLsizei mWindowHeight;
+ bool mWindowClosed = false;
+ bool mWindowVisible = true;
+ GLsizei mWindowWidth = 0;
+ GLsizei mWindowHeight = 0;
- EGLDisplay mEglDisplay;
- EGLContext mEglContext;
- EGLSurface mEglSurface;
+ EGLDisplay mEglDisplay = EGL_NO_DISPLAY;
+ EGLContext mEglContext = EGL_NO_CONTEXT;
+ EGLSurface mEglSurface = EGL_NO_SURFACE;
CoreWindow^ window;
OS_UWP* os;
diff --git a/platform/uwp/context_egl_uwp.cpp b/platform/uwp/context_egl_uwp.cpp
index bc8ca2e36c..2da6c5897a 100644
--- a/platform/uwp/context_egl_uwp.cpp
+++ b/platform/uwp/context_egl_uwp.cpp
@@ -35,27 +35,22 @@
using Platform::Exception;
void ContextEGL_UWP::release_current() {
-
eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEglContext);
};
void ContextEGL_UWP::make_current() {
-
eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext);
};
int ContextEGL_UWP::get_window_width() {
-
return width;
};
int ContextEGL_UWP::get_window_height() {
-
return height;
};
void ContextEGL_UWP::reset() {
-
cleanup();
window = CoreWindow::GetForCurrentThread();
@@ -63,7 +58,6 @@ void ContextEGL_UWP::reset() {
};
void ContextEGL_UWP::swap_buffers() {
-
if (eglSwapBuffers(mEglDisplay, mEglSurface) != EGL_TRUE) {
cleanup();
@@ -75,7 +69,6 @@ void ContextEGL_UWP::swap_buffers() {
};
Error ContextEGL_UWP::initialize() {
-
EGLint configAttribList[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
@@ -115,7 +108,6 @@ Error ContextEGL_UWP::initialize() {
}
try {
-
const EGLint displayAttributes[] = {
/*EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, 9,
@@ -191,7 +183,6 @@ Error ContextEGL_UWP::initialize() {
};
void ContextEGL_UWP::cleanup() {
-
if (mEglDisplay != EGL_NO_DISPLAY && mEglSurface != EGL_NO_SURFACE) {
eglDestroySurface(mEglDisplay, mEglSurface);
mEglSurface = EGL_NO_SURFACE;
@@ -216,6 +207,5 @@ ContextEGL_UWP::ContextEGL_UWP(CoreWindow ^ p_window, Driver p_driver) :
window(p_window) {}
ContextEGL_UWP::~ContextEGL_UWP() {
-
cleanup();
};
diff --git a/platform/uwp/context_egl_uwp.h b/platform/uwp/context_egl_uwp.h
index fa61cf50c6..6f333b8e6a 100644
--- a/platform/uwp/context_egl_uwp.h
+++ b/platform/uwp/context_egl_uwp.h
@@ -41,7 +41,6 @@
using namespace Windows::UI::Core;
class ContextEGL_UWP {
-
public:
enum Driver {
GLES_2_0,
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index 06bf738dc1..db42908f89 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -83,7 +83,6 @@ static const char *uwp_device_capabilities[] = {
};
class AppxPackager {
-
enum {
FILE_HEADER_MAGIC = 0x04034b50,
DATA_DESCRIPTOR_MAGIC = 0x08074b50,
@@ -107,29 +106,21 @@ class AppxPackager {
};
struct BlockHash {
-
String base64_hash;
size_t compressed_size;
};
struct FileMeta {
-
String name;
- int lfh_size;
- bool compressed;
- size_t compressed_size;
- size_t uncompressed_size;
+ int lfh_size = 0;
+ bool compressed = false;
+ size_t compressed_size = 0;
+ size_t uncompressed_size = 0;
Vector<BlockHash> hashes;
- uLong file_crc32;
- ZPOS64_T zip_offset;
-
- FileMeta() :
- lfh_size(0),
- compressed(false),
- compressed_size(0),
- uncompressed_size(0),
- file_crc32(0),
- zip_offset(0) {}
+ uLong file_crc32 = 0;
+ ZPOS64_T zip_offset = 0;
+
+ FileMeta() {}
};
String progress_task;
@@ -195,7 +186,6 @@ public:
///////////////////////////////////////////////////////////////////////////
String AppxPackager::hash_block(const uint8_t *p_block_data, size_t p_block_len) {
-
unsigned char hash[32];
char base64[45];
@@ -208,24 +198,22 @@ String AppxPackager::hash_block(const uint8_t *p_block_data, size_t p_block_len)
}
void AppxPackager::make_block_map(const String &p_path) {
-
FileAccess *tmp_file = FileAccess::open(p_path, FileAccess::WRITE);
tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
tmp_file->store_string("<BlockMap xmlns=\"http://schemas.microsoft.com/appx/2010/blockmap\" HashMethod=\"http://www.w3.org/2001/04/xmlenc#sha256\">");
for (int i = 0; i < file_metadata.size(); i++) {
-
FileMeta file = file_metadata[i];
tmp_file->store_string(
"<File Name=\"" + file.name.replace("/", "\\") + "\" Size=\"" + itos(file.uncompressed_size) + "\" LfhSize=\"" + itos(file.lfh_size) + "\">");
for (int j = 0; j < file.hashes.size(); j++) {
-
tmp_file->store_string("<Block Hash=\"" + file.hashes[j].base64_hash + "\" ");
- if (file.compressed)
+ if (file.compressed) {
tmp_file->store_string("Size=\"" + itos(file.hashes[j].compressed_size) + "\" ");
+ }
tmp_file->store_string("/>");
}
@@ -239,21 +227,20 @@ void AppxPackager::make_block_map(const String &p_path) {
}
String AppxPackager::content_type(String p_extension) {
-
- if (p_extension == "png")
+ if (p_extension == "png") {
return "image/png";
- else if (p_extension == "jpg")
+ } else if (p_extension == "jpg") {
return "image/jpg";
- else if (p_extension == "xml")
+ } else if (p_extension == "xml") {
return "application/xml";
- else if (p_extension == "exe" || p_extension == "dll")
+ } else if (p_extension == "exe" || p_extension == "dll") {
return "application/x-msdownload";
- else
+ } else {
return "application/octet-stream";
+ }
}
void AppxPackager::make_content_types(const String &p_path) {
-
FileAccess *tmp_file = FileAccess::open(p_path, FileAccess::WRITE);
tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
@@ -262,10 +249,11 @@ void AppxPackager::make_content_types(const String &p_path) {
Map<String, String> types;
for (int i = 0; i < file_metadata.size(); i++) {
-
String ext = file_metadata[i].name.get_extension();
- if (types.has(ext)) continue;
+ if (types.has(ext)) {
+ continue;
+ }
types[ext] = content_type(ext);
@@ -288,7 +276,6 @@ void AppxPackager::make_content_types(const String &p_path) {
}
Vector<uint8_t> AppxPackager::make_file_header(FileMeta p_file_meta) {
-
Vector<uint8_t> buf;
buf.resize(BASE_FILE_HEADER_SIZE + p_file_meta.name.length());
@@ -331,7 +318,6 @@ Vector<uint8_t> AppxPackager::make_file_header(FileMeta p_file_meta) {
}
void AppxPackager::store_central_dir_header(const FileMeta &p_file, bool p_do_hash) {
-
Vector<uint8_t> &buf = central_dir_data;
int offs = buf.size();
buf.resize(buf.size() + BASE_CENTRAL_DIR_SIZE + p_file.name.length());
@@ -383,7 +369,6 @@ void AppxPackager::store_central_dir_header(const FileMeta &p_file, bool p_do_ha
}
Vector<uint8_t> AppxPackager::make_end_of_central_record() {
-
Vector<uint8_t> buf;
buf.resize(ZIP64_END_OF_CENTRAL_DIR_SIZE + 12 + END_OF_CENTRAL_DIR_SIZE); // Size plus magic
@@ -453,14 +438,12 @@ Vector<uint8_t> AppxPackager::make_end_of_central_record() {
}
void AppxPackager::init(FileAccess *p_fa) {
-
package = p_fa;
central_dir_offset = 0;
end_of_central_dir_offset = 0;
}
Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t p_len, int p_file_no, int p_total_files, bool p_compress) {
-
if (p_file_no >= 1 && p_total_files >= 1) {
if (EditorNode::progress_task_step(progress_task, "File: " + p_file_name, (p_file_no * 100) / p_total_files)) {
return ERR_SKIP;
@@ -484,7 +467,6 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
Vector<uint8_t> strm_out;
if (p_compress) {
-
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = &strm_f;
@@ -497,7 +479,6 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
int step = 0;
while (p_len - step > 0) {
-
size_t block_size = (p_len - step) > BLOCK_SIZE ? (size_t)BLOCK_SIZE : (p_len - step);
for (uint64_t i = 0; i < block_size; i++) {
@@ -508,7 +489,6 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
bh.base64_hash = hash_block(strm_in.ptr(), block_size);
if (p_compress) {
-
strm.avail_in = block_size;
strm.avail_out = strm_out.size();
strm.next_in = (uint8_t *)strm_in.ptr();
@@ -524,15 +504,17 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
//package->store_buffer(strm_out.ptr(), strm.total_out - total_out_before);
int start = file_buffer.size();
file_buffer.resize(file_buffer.size() + bh.compressed_size);
- for (uint64_t i = 0; i < bh.compressed_size; i++)
+ for (uint64_t i = 0; i < bh.compressed_size; i++) {
file_buffer.write[start + i] = strm_out[i];
+ }
} else {
bh.compressed_size = block_size;
//package->store_buffer(strm_in.ptr(), block_size);
int start = file_buffer.size();
file_buffer.resize(file_buffer.size() + block_size);
- for (uint64_t i = 0; i < bh.compressed_size; i++)
+ for (uint64_t i = 0; i < bh.compressed_size; i++) {
file_buffer.write[start + i] = strm_in[i];
+ }
}
meta.hashes.push_back(bh);
@@ -541,7 +523,6 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
}
if (p_compress) {
-
strm.avail_in = 0;
strm.avail_out = strm_out.size();
strm.next_in = (uint8_t *)strm_in.ptr();
@@ -554,14 +535,14 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
//package->store_buffer(strm_out.ptr(), strm.total_out - total_out_before);
int start = file_buffer.size();
file_buffer.resize(file_buffer.size() + (strm.total_out - total_out_before));
- for (uint64_t i = 0; i < (strm.total_out - total_out_before); i++)
+ for (uint64_t i = 0; i < (strm.total_out - total_out_before); i++) {
file_buffer.write[start + i] = strm_out[i];
+ }
deflateEnd(&strm);
meta.compressed_size = strm.total_out;
} else {
-
meta.compressed_size = p_len;
}
@@ -584,7 +565,6 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t
}
void AppxPackager::finish() {
-
// Create and add block map file
EditorNode::progress_task_step("export", "Creating block map...", 4);
@@ -651,7 +631,6 @@ AppxPackager::~AppxPackager() {}
////////////////////////////////////////////////////////////////////
class EditorExportPlatformUWP : public EditorExportPlatform {
-
GDCLASS(EditorExportPlatformUWP, EditorExportPlatform);
Ref<ImageTexture> logo;
@@ -663,9 +642,12 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
};
bool _valid_resource_name(const String &p_name) const {
-
- if (p_name.empty()) return false;
- if (p_name.ends_with(".")) return false;
+ if (p_name.empty()) {
+ return false;
+ }
+ if (p_name.ends_with(".")) {
+ return false;
+ }
static const char *invalid_names[] = {
"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7",
@@ -675,7 +657,9 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
const char **t = invalid_names;
while (*t) {
- if (p_name == *t) return false;
+ if (p_name == *t) {
+ return false;
+ }
t++;
}
@@ -683,22 +667,33 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
}
bool _valid_guid(const String &p_guid) const {
-
Vector<String> parts = p_guid.split("-");
- if (parts.size() != 5) return false;
- if (parts[0].length() != 8) return false;
- for (int i = 1; i < 4; i++)
- if (parts[i].length() != 4) return false;
- if (parts[4].length() != 12) return false;
+ if (parts.size() != 5) {
+ return false;
+ }
+ if (parts[0].length() != 8) {
+ return false;
+ }
+ for (int i = 1; i < 4; i++) {
+ if (parts[i].length() != 4) {
+ return false;
+ }
+ }
+ if (parts[4].length() != 12) {
+ return false;
+ }
return true;
}
bool _valid_bgcolor(const String &p_color) const {
-
- if (p_color.empty()) return true;
- if (p_color.begins_with("#") && p_color.is_valid_html_color()) return true;
+ if (p_color.empty()) {
+ return true;
+ }
+ if (p_color.begins_with("#") && p_color.is_valid_html_color()) {
+ return true;
+ }
// Colors from https://msdn.microsoft.com/en-us/library/windows/apps/dn934817.aspx
static const char *valid_colors[] = {
@@ -732,15 +727,16 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
const char **color = valid_colors;
while (*color) {
- if (p_color == *color) return true;
+ if (p_color == *color) {
+ return true;
+ }
color++;
}
return false;
}
- bool _valid_image(const StreamTexture *p_image, int p_width, int p_height) const {
-
+ bool _valid_image(const StreamTexture2D *p_image, int p_width, int p_height) const {
if (!p_image) {
return false;
}
@@ -752,21 +748,21 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
bool valid_h = false;
for (int i = 0; i < 1; i++) {
-
int w = ceil(p_width * scales[i]);
int h = ceil(p_height * scales[i]);
- if (w == p_image->get_width())
+ if (w == p_image->get_width()) {
valid_w = true;
- if (h == p_image->get_height())
+ }
+ if (h == p_image->get_height()) {
valid_h = true;
+ }
}
return valid_w && valid_h;
}
Vector<uint8_t> _fix_manifest(const Ref<EditorExportPreset> &p_preset, const Vector<uint8_t> &p_template, bool p_give_internet) const {
-
String result = String::utf8((const char *)p_template.ptr(), p_template.size());
result = result.replace("$godot_version$", VERSION_FULL_NAME);
@@ -867,43 +863,44 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
Vector<uint8_t> r_ret;
r_ret.resize(result.length());
- for (int i = 0; i < result.length(); i++)
+ for (int i = 0; i < result.length(); i++) {
r_ret.write[i] = result.utf8().get(i);
+ }
return r_ret;
}
Vector<uint8_t> _get_image_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
-
Vector<uint8_t> data;
- StreamTexture *image = nullptr;
+ StreamTexture2D *image = nullptr;
if (p_path.find("StoreLogo") != -1) {
- image = p_preset->get("images/store_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture>(((Object *)p_preset->get("images/store_logo")));
+ image = p_preset->get("images/store_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/store_logo")));
} else if (p_path.find("Square44x44Logo") != -1) {
- image = p_preset->get("images/square44x44_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture>(((Object *)p_preset->get("images/square44x44_logo")));
+ image = p_preset->get("images/square44x44_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square44x44_logo")));
} else if (p_path.find("Square71x71Logo") != -1) {
- image = p_preset->get("images/square71x71_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture>(((Object *)p_preset->get("images/square71x71_logo")));
+ image = p_preset->get("images/square71x71_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square71x71_logo")));
} else if (p_path.find("Square150x150Logo") != -1) {
- image = p_preset->get("images/square150x150_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture>(((Object *)p_preset->get("images/square150x150_logo")));
+ image = p_preset->get("images/square150x150_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square150x150_logo")));
} else if (p_path.find("Square310x310Logo") != -1) {
- image = p_preset->get("images/square310x310_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture>(((Object *)p_preset->get("images/square310x310_logo")));
+ image = p_preset->get("images/square310x310_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square310x310_logo")));
} else if (p_path.find("Wide310x150Logo") != -1) {
- image = p_preset->get("images/wide310x150_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture>(((Object *)p_preset->get("images/wide310x150_logo")));
+ image = p_preset->get("images/wide310x150_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/wide310x150_logo")));
} else if (p_path.find("SplashScreen") != -1) {
- image = p_preset->get("images/splash_screen").is_zero() ? nullptr : Object::cast_to<StreamTexture>(((Object *)p_preset->get("images/splash_screen")));
+ image = p_preset->get("images/splash_screen").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/splash_screen")));
} else {
ERR_PRINT("Unable to load logo");
}
- if (!image) return data;
+ if (!image) {
+ return data;
+ }
String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("uwp_tmp_logo.png");
Error err = image->get_data()->save_png(tmp_path);
if (err != OK) {
-
String err_string = "Couldn't save temp logo file.";
EditorNode::add_io_error(err_string);
@@ -913,7 +910,6 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
FileAccess *f = FileAccess::open(tmp_path, FileAccess::READ, &err);
if (err != OK) {
-
String err_string = "Couldn't open temp logo file.";
// Cleanup generated file.
DirAccess::remove_file_or_error(tmp_path);
@@ -932,17 +928,16 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
}
static bool _should_compress_asset(const String &p_path, const Vector<uint8_t> &p_data) {
-
/* TODO: This was copied verbatim from Android export. It should be
- * refactored to the parent class and also be used for .zip export.
- */
+ * refactored to the parent class and also be used for .zip export.
+ */
/*
- * By not compressing files with little or not benefit in doing so,
- * a performance gain is expected at runtime. Moreover, if the APK is
- * zip-aligned, assets stored as they are can be efficiently read by
- * Android by memory-mapping them.
- */
+ * By not compressing files with little or not benefit in doing so,
+ * a performance gain is expected at runtime. Moreover, if the APK is
+ * zip-aligned, assets stored as they are can be efficiently read by
+ * Android by memory-mapping them.
+ */
// -- Unconditional uncompress to mimic AAPT plus some other
@@ -983,7 +978,6 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
}
static Error save_appx_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
-
AppxPackager *packager = (AppxPackager *)p_userdata;
String dst_path = p_path.replace_first("res://", "game/");
@@ -1054,13 +1048,13 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/portrait_flipped"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "images/background_color"), "transparent"));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/store_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square44x44_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square71x71_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square150x150_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square310x310_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/wide310x150_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
- r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/splash_screen", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/store_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture2D"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square44x44_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture2D"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square71x71_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture2D"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square150x150_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture2D"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square310x310_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture2D"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/wide310x150_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture2D"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/splash_screen", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture2D"), Variant()));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_square150x150"), false));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_wide310x150"), false));
@@ -1090,7 +1084,6 @@ public:
}
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
-
String err;
bool valid = false;
@@ -1161,37 +1154,37 @@ public:
err += TTR("Invalid background color.") + "\n";
}
- if (!p_preset->get("images/store_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/store_logo"))), 50, 50)) {
+ if (!p_preset->get("images/store_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture2D>((Object *)p_preset->get("images/store_logo"))), 50, 50)) {
valid = false;
err += TTR("Invalid Store Logo image dimensions (should be 50x50).") + "\n";
}
- if (!p_preset->get("images/square44x44_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/square44x44_logo"))), 44, 44)) {
+ if (!p_preset->get("images/square44x44_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture2D>((Object *)p_preset->get("images/square44x44_logo"))), 44, 44)) {
valid = false;
err += TTR("Invalid square 44x44 logo image dimensions (should be 44x44).") + "\n";
}
- if (!p_preset->get("images/square71x71_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/square71x71_logo"))), 71, 71)) {
+ if (!p_preset->get("images/square71x71_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture2D>((Object *)p_preset->get("images/square71x71_logo"))), 71, 71)) {
valid = false;
err += TTR("Invalid square 71x71 logo image dimensions (should be 71x71).") + "\n";
}
- if (!p_preset->get("images/square150x150_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/square150x150_logo"))), 150, 150)) {
+ if (!p_preset->get("images/square150x150_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture2D>((Object *)p_preset->get("images/square150x150_logo"))), 150, 150)) {
valid = false;
err += TTR("Invalid square 150x150 logo image dimensions (should be 150x150).") + "\n";
}
- if (!p_preset->get("images/square310x310_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/square310x310_logo"))), 310, 310)) {
+ if (!p_preset->get("images/square310x310_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture2D>((Object *)p_preset->get("images/square310x310_logo"))), 310, 310)) {
valid = false;
err += TTR("Invalid square 310x310 logo image dimensions (should be 310x310).") + "\n";
}
- if (!p_preset->get("images/wide310x150_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/wide310x150_logo"))), 310, 150)) {
+ if (!p_preset->get("images/wide310x150_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture2D>((Object *)p_preset->get("images/wide310x150_logo"))), 310, 150)) {
valid = false;
err += TTR("Invalid wide 310x150 logo image dimensions (should be 310x150).") + "\n";
}
- if (!p_preset->get("images/splash_screen").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/splash_screen"))), 620, 300)) {
+ if (!p_preset->get("images/splash_screen").is_zero() && !_valid_image((Object::cast_to<StreamTexture2D>((Object *)p_preset->get("images/splash_screen"))), 620, 300)) {
valid = false;
err += TTR("Invalid splash screen image dimensions (should be 620x300).") + "\n";
}
@@ -1201,15 +1194,15 @@ public:
}
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) {
-
String src_appx;
EditorProgress ep("export", "Exporting for Windows Universal", 7, true);
- if (p_debug)
+ if (p_debug) {
src_appx = p_preset->get("custom_template/debug");
- else
+ } else {
src_appx = p_preset->get("custom_template/release");
+ }
src_appx = src_appx.strip_edges();
@@ -1261,7 +1254,6 @@ public:
unzFile pkg = unzOpen2(src_appx.utf8().get_data(), &io);
if (!pkg) {
-
EditorNode::add_io_error("Could not find template appx to export:\n" + src_appx);
return ERR_FILE_NOT_FOUND;
}
@@ -1279,7 +1271,6 @@ public:
int template_file_no = 1;
while (ret == UNZ_OK) {
-
// get file name
unz_file_info info;
char fname[16834];
@@ -1297,11 +1288,12 @@ public:
bool do_read = true;
if (path.begins_with("Assets/")) {
-
path = path.replace(".scale-100", "");
data = _get_image_data(p_preset, path);
- if (data.size() > 0) do_read = false;
+ if (data.size() > 0) {
+ do_read = false;
+ }
}
//read
@@ -1313,7 +1305,6 @@ public:
}
if (path == "AppxManifest.xml") {
-
data = _fix_manifest(p_preset, data, p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG));
}
@@ -1356,7 +1347,6 @@ public:
encode_uint32(cl.size(), clf.ptrw());
for (int i = 0; i < cl.size(); i++) {
-
CharString txt = cl[i].utf8();
int base = clf.size();
clf.resize(base + 4 + txt.length());
@@ -1445,7 +1435,6 @@ public:
}
virtual void get_platform_features(List<String> *r_features) {
-
r_features->push_back("pc");
r_features->push_back("UWP");
}
@@ -1461,7 +1450,6 @@ public:
};
void register_uwp_exporter() {
-
#ifdef WINDOWS_ENABLED
EDITOR_DEF("export/uwp/signtool", "");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/uwp/signtool", PROPERTY_HINT_GLOBAL_FILE, "*.exe"));
diff --git a/platform/uwp/joypad_uwp.cpp b/platform/uwp/joypad_uwp.cpp
index 90df6fe5d7..4fdfde9673 100644
--- a/platform/uwp/joypad_uwp.cpp
+++ b/platform/uwp/joypad_uwp.cpp
@@ -35,7 +35,6 @@ using namespace Windows::Gaming::Input;
using namespace Windows::Foundation;
void JoypadUWP::register_events() {
-
Gamepad::GamepadAdded +=
ref new EventHandler<Gamepad ^>(this, &JoypadUWP::OnGamepadAdded);
Gamepad::GamepadRemoved +=
@@ -43,32 +42,28 @@ void JoypadUWP::register_events() {
}
void JoypadUWP::process_controllers() {
-
for (int i = 0; i < MAX_CONTROLLERS; i++) {
-
ControllerDevice &joy = controllers[i];
- if (!joy.connected) break;
+ if (!joy.connected)
+ break;
switch (joy.type) {
-
case ControllerType::GAMEPAD_CONTROLLER: {
-
GamepadReading reading = ((Gamepad ^) joy.controller_reference)->GetCurrentReading();
int button_mask = (int)GamepadButtons::Menu;
for (int j = 0; j < 14; j++) {
-
input->joy_button(joy.id, j, (int)reading.Buttons & button_mask);
button_mask *= 2;
}
- input->joy_axis(joy.id, JOY_AXIS_0, axis_correct(reading.LeftThumbstickX));
- input->joy_axis(joy.id, JOY_AXIS_1, axis_correct(reading.LeftThumbstickY, true));
- input->joy_axis(joy.id, JOY_AXIS_2, axis_correct(reading.RightThumbstickX));
- input->joy_axis(joy.id, JOY_AXIS_3, axis_correct(reading.RightThumbstickY, true));
- input->joy_axis(joy.id, JOY_AXIS_4, axis_correct(reading.LeftTrigger, false, true));
- input->joy_axis(joy.id, JOY_AXIS_5, axis_correct(reading.RightTrigger, false, true));
+ input->joy_axis(joy.id, JOY_AXIS_LEFT_X, axis_correct(reading.LeftThumbstickX));
+ input->joy_axis(joy.id, JOY_AXIS_LEFT_Y, axis_correct(reading.LeftThumbstickY, true));
+ input->joy_axis(joy.id, JOY_AXIS_RIGHT_X, axis_correct(reading.RightThumbstickX));
+ input->joy_axis(joy.id, JOY_AXIS_RIGHT_Y, axis_correct(reading.RightThumbstickY, true));
+ input->joy_axis(joy.id, JOY_AXIS_TRIGGER_LEFT, axis_correct(reading.LeftTrigger, false, true));
+ input->joy_axis(joy.id, JOY_AXIS_TRIGGER_RIGHT, axis_correct(reading.RightTrigger, false, true));
uint64_t timestamp = input->get_joy_vibration_timestamp(joy.id);
if (timestamp > joy.ff_timestamp) {
@@ -92,24 +87,20 @@ void JoypadUWP::process_controllers() {
}
JoypadUWP::JoypadUWP() {
-
for (int i = 0; i < MAX_CONTROLLERS; i++)
controllers[i].id = i;
}
JoypadUWP::JoypadUWP(InputDefault *p_input) {
-
input = p_input;
JoypadUWP();
}
void JoypadUWP::OnGamepadAdded(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value) {
-
short idx = -1;
for (int i = 0; i < MAX_CONTROLLERS; i++) {
-
if (!controllers[i].connected) {
idx = i;
break;
@@ -127,11 +118,9 @@ void JoypadUWP::OnGamepadAdded(Platform::Object ^ sender, Windows::Gaming::Input
}
void JoypadUWP::OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value) {
-
short idx = -1;
for (int i = 0; i < MAX_CONTROLLERS; i++) {
-
if (controllers[i].controller_reference == value) {
idx = i;
break;
@@ -146,7 +135,6 @@ void JoypadUWP::OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Inp
}
InputDefault::JoyAxis JoypadUWP::axis_correct(double p_val, bool p_negate, bool p_trigger) const {
-
InputDefault::JoyAxis jx;
jx.min = p_trigger ? 0 : -1;
diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h
index 054b67ddc8..13f246a438 100644
--- a/platform/uwp/joypad_uwp.h
+++ b/platform/uwp/joypad_uwp.h
@@ -31,10 +31,9 @@
#ifndef JOYPAD_UWP_H
#define JOYPAD_UWP_H
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
ref class JoypadUWP sealed {
-
/** clang-format breaks this, it does not understand this token. */
/* clang-format off */
internal:
@@ -57,7 +56,6 @@ private:
};
struct ControllerDevice {
-
Windows::Gaming::Input::IGameController ^ controller_reference;
int id;
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index f5e989b370..7bd67d3726 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -82,7 +82,6 @@ int OS_UWP::get_current_video_driver() const {
}
void OS_UWP::set_window_size(const Size2 p_size) {
-
Windows::Foundation::Size new_size;
new_size.Width = p_size.width;
new_size.Height = p_size.height;
@@ -90,14 +89,12 @@ void OS_UWP::set_window_size(const Size2 p_size) {
ApplicationView ^ view = ApplicationView::GetForCurrentView();
if (view->TryResizeView(new_size)) {
-
video_mode.width = p_size.width;
video_mode.height = p_size.height;
}
}
void OS_UWP::set_window_fullscreen(bool p_enabled) {
-
ApplicationView ^ view = ApplicationView::GetForCurrentView();
video_mode.fullscreen = view->IsFullScreenMode;
@@ -106,24 +103,21 @@ void OS_UWP::set_window_fullscreen(bool p_enabled) {
return;
if (p_enabled) {
-
video_mode.fullscreen = view->TryEnterFullScreenMode();
} else {
-
view->ExitFullScreenMode();
video_mode.fullscreen = false;
}
}
bool OS_UWP::is_window_fullscreen() const {
-
return ApplicationView::GetForCurrentView()->IsFullScreenMode;
}
void OS_UWP::set_keep_screen_on(bool p_enabled) {
-
- if (is_keep_screen_on() == p_enabled) return;
+ if (is_keep_screen_on() == p_enabled)
+ return;
if (p_enabled)
display_request->RequestActive();
@@ -134,7 +128,6 @@ void OS_UWP::set_keep_screen_on(bool p_enabled) {
}
void OS_UWP::initialize_core() {
-
last_button_state = 0;
//RedirectIOToConsole();
@@ -165,7 +158,6 @@ void OS_UWP::initialize_core() {
}
bool OS_UWP::can_draw() const {
-
return !minimized;
};
@@ -174,12 +166,10 @@ void OS_UWP::set_window(Windows::UI::Core::CoreWindow ^ p_window) {
}
void OS_UWP::screen_size_changed() {
-
gl_context->reset();
};
Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
-
main_loop = nullptr;
outside = true;
@@ -230,11 +220,9 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
if (p_desired.fullscreen != view->IsFullScreenMode) {
if (p_desired.fullscreen) {
-
vm.fullscreen = view->TryEnterFullScreenMode();
} else {
-
view->ExitFullScreenMode();
vm.fullscreen = false;
}
@@ -247,7 +235,6 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
view->PreferredLaunchViewSize = desired;
if (view->TryResizeView(desired)) {
-
vm.width = view->VisibleBounds.Width;
vm.height = view->VisibleBounds.Height;
}
@@ -308,7 +295,6 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
}
void OS_UWP::set_clipboard(const String &p_text) {
-
DataPackage ^ clip = ref new DataPackage();
clip->RequestedOperation = DataPackageOperation::Copy;
clip->SetText(ref new Platform::String((const wchar_t *)p_text.c_str()));
@@ -317,7 +303,6 @@ void OS_UWP::set_clipboard(const String &p_text) {
};
String OS_UWP::get_clipboard() const {
-
if (managed_object->clipboard != nullptr)
return managed_object->clipboard->Data();
else
@@ -325,25 +310,21 @@ String OS_UWP::get_clipboard() const {
};
void OS_UWP::input_event(const Ref<InputEvent> &p_event) {
-
input->parse_input_event(p_event);
};
void OS_UWP::delete_main_loop() {
-
if (main_loop)
memdelete(main_loop);
main_loop = nullptr;
}
void OS_UWP::set_main_loop(MainLoop *p_main_loop) {
-
input->set_main_loop(p_main_loop);
main_loop = p_main_loop;
}
void OS_UWP::finalize() {
-
if (main_loop)
memdelete(main_loop);
@@ -362,12 +343,10 @@ void OS_UWP::finalize() {
}
void OS_UWP::finalize_core() {
-
NetSocketPosix::cleanup();
}
void OS_UWP::alert(const String &p_alert, const String &p_title) {
-
Platform::String ^ alert = ref new Platform::String(p_alert.c_str());
Platform::String ^ title = ref new Platform::String(p_title.c_str());
@@ -383,21 +362,17 @@ void OS_UWP::alert(const String &p_alert, const String &p_title) {
}
void OS_UWP::ManagedType::alert_close(IUICommand ^ command) {
-
alert_close_handle = false;
}
void OS_UWP::ManagedType::on_clipboard_changed(Platform::Object ^ sender, Platform::Object ^ ev) {
-
update_clipboard();
}
void OS_UWP::ManagedType::update_clipboard() {
-
DataPackageView ^ data = Clipboard::GetContent();
if (data->Contains(StandardDataFormats::Text)) {
-
create_task(data->GetTextAsync()).then([this](Platform::String ^ clipboard_content) {
this->clipboard = clipboard_content;
});
@@ -405,7 +380,6 @@ void OS_UWP::ManagedType::update_clipboard() {
}
void OS_UWP::ManagedType::on_accelerometer_reading_changed(Accelerometer ^ sender, AccelerometerReadingChangedEventArgs ^ args) {
-
AccelerometerReading ^ reading = args->Reading;
os->input->set_accelerometer(Vector3(
@@ -415,7 +389,6 @@ void OS_UWP::ManagedType::on_accelerometer_reading_changed(Accelerometer ^ sende
}
void OS_UWP::ManagedType::on_magnetometer_reading_changed(Magnetometer ^ sender, MagnetometerReadingChangedEventArgs ^ args) {
-
MagnetometerReading ^ reading = args->Reading;
os->input->set_magnetometer(Vector3(
@@ -425,7 +398,6 @@ void OS_UWP::ManagedType::on_magnetometer_reading_changed(Magnetometer ^ sender,
}
void OS_UWP::ManagedType::on_gyroscope_reading_changed(Gyrometer ^ sender, GyrometerReadingChangedEventArgs ^ args) {
-
GyrometerReading ^ reading = args->Reading;
os->input->set_magnetometer(Vector3(
@@ -435,22 +407,17 @@ void OS_UWP::ManagedType::on_gyroscope_reading_changed(Gyrometer ^ sender, Gyrom
}
void OS_UWP::set_mouse_mode(MouseMode p_mode) {
-
if (p_mode == MouseMode::MOUSE_MODE_CAPTURED) {
-
CoreWindow::GetForCurrentThread()->SetPointerCapture();
} else {
-
CoreWindow::GetForCurrentThread()->ReleasePointerCapture();
}
if (p_mode == MouseMode::MOUSE_MODE_CAPTURED || p_mode == MouseMode::MOUSE_MODE_HIDDEN) {
-
CoreWindow::GetForCurrentThread()->PointerCursor = nullptr;
} else {
-
CoreWindow::GetForCurrentThread()->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
}
@@ -460,17 +427,14 @@ void OS_UWP::set_mouse_mode(MouseMode p_mode) {
}
OS_UWP::MouseMode OS_UWP::get_mouse_mode() const {
-
return mouse_mode;
}
Point2 OS_UWP::get_mouse_position() const {
-
return Point2(old_x, old_y);
}
int OS_UWP::get_mouse_button_state() const {
-
return last_button_state;
}
@@ -478,23 +442,21 @@ void OS_UWP::set_window_title(const String &p_title) {
}
void OS_UWP::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
-
video_mode = p_video_mode;
}
-OS::VideoMode OS_UWP::get_video_mode(int p_screen) const {
+OS::VideoMode OS_UWP::get_video_mode(int p_screen) const {
return video_mode;
}
+
void OS_UWP::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
}
String OS_UWP::get_name() const {
-
return "UWP";
}
OS::Date OS_UWP::get_date(bool utc) const {
-
SYSTEMTIME systemtime;
if (utc)
GetSystemTime(&systemtime);
@@ -509,8 +471,8 @@ OS::Date OS_UWP::get_date(bool utc) const {
date.dst = false;
return date;
}
-OS::Time OS_UWP::get_time(bool utc) const {
+OS::Time OS_UWP::get_time(bool utc) const {
SYSTEMTIME systemtime;
if (utc)
GetSystemTime(&systemtime);
@@ -544,7 +506,6 @@ OS::TimeZoneInfo OS_UWP::get_time_zone_info() const {
}
uint64_t OS_UWP::get_unix_time() const {
-
FILETIME ft;
SYSTEMTIME st;
GetSystemTime(&st);
@@ -566,14 +527,13 @@ uint64_t OS_UWP::get_unix_time() const {
};
void OS_UWP::delay_usec(uint32_t p_usec) const {
-
int msec = p_usec < 1000 ? 1 : p_usec / 1000;
// no Sleep()
WaitForSingleObjectEx(GetCurrentThread(), msec, false);
}
-uint64_t OS_UWP::get_ticks_usec() const {
+uint64_t OS_UWP::get_ticks_usec() const {
uint64_t ticks;
uint64_t time;
// This is the number of clock ticks since start
@@ -587,15 +547,12 @@ uint64_t OS_UWP::get_ticks_usec() const {
}
void OS_UWP::process_events() {
-
joypad->process_controllers();
process_key_events();
}
void OS_UWP::process_key_events() {
-
for (int i = 0; i < key_event_pos; i++) {
-
KeyEvent &kev = key_event_buffer[i];
Ref<InputEventKey> key_event;
@@ -618,7 +575,6 @@ void OS_UWP::queue_key_event(KeyEvent &p_event) {
// This merges Char events with the previous Key event, so
// the unicode can be retrieved without sending duplicate events.
if (p_event.type == KeyEvent::MessageType::CHAR_EVENT_MESSAGE && key_event_pos > 0) {
-
KeyEvent &old = key_event_buffer[key_event_pos - 1];
ERR_FAIL_COND(old.type != KeyEvent::MessageType::KEY_EVENT_MESSAGE);
@@ -632,7 +588,6 @@ void OS_UWP::queue_key_event(KeyEvent &p_event) {
}
void OS_UWP::set_cursor_shape(CursorShape p_shape) {
-
ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
if (cursor_shape == p_shape)
@@ -664,7 +619,6 @@ void OS_UWP::set_cursor_shape(CursorShape p_shape) {
}
OS::CursorShape OS_UWP::get_cursor_shape() const {
-
return cursor_shape;
}
@@ -673,22 +627,18 @@ void OS_UWP::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
}
Error OS_UWP::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
-
return FAILED;
};
Error OS_UWP::kill(const ProcessID &p_pid) {
-
return FAILED;
};
Error OS_UWP::set_cwd(const String &p_cwd) {
-
return FAILED;
}
String OS_UWP::get_executable_path() const {
-
return "";
}
@@ -696,22 +646,18 @@ void OS_UWP::set_icon(const Ref<Image> &p_icon) {
}
bool OS_UWP::has_environment(const String &p_var) const {
-
return false;
};
String OS_UWP::get_environment(const String &p_var) const {
-
return "";
};
bool OS_UWP::set_environment(const String &p_var, const String &p_value) const {
-
return false;
}
String OS_UWP::get_stdin_string(bool p_block) {
-
return String();
}
@@ -719,12 +665,10 @@ void OS_UWP::move_window_to_foreground() {
}
Error OS_UWP::shell_open(String p_uri) {
-
return FAILED;
}
String OS_UWP::get_locale() const {
-
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP // this should work on phone 8.1, but it doesn't
return "en";
#else
@@ -734,45 +678,37 @@ String OS_UWP::get_locale() const {
}
void OS_UWP::release_rendering_thread() {
-
gl_context->release_current();
}
void OS_UWP::make_rendering_thread() {
-
gl_context->make_current();
}
void OS_UWP::swap_buffers() {
-
gl_context->swap_buffers();
}
bool OS_UWP::has_touchscreen_ui_hint() const {
-
TouchCapabilities ^ tc = ref new TouchCapabilities();
return tc->TouchPresent != 0 || UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
}
bool OS_UWP::has_virtual_keyboard() const {
-
return UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
}
-void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) {
-
+void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
InputPane ^ pane = InputPane::GetForCurrentView();
pane->TryShow();
}
void OS_UWP::hide_virtual_keyboard() {
-
InputPane ^ pane = InputPane::GetForCurrentView();
pane->TryHide();
}
static String format_error_message(DWORD id) {
-
LPWSTR messageBuffer = nullptr;
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, nullptr);
@@ -785,7 +721,6 @@ static String format_error_message(DWORD id) {
}
Error OS_UWP::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
-
String full_path = "game/" + p_path;
p_library_handle = (void *)LoadPackagedLibrary(full_path.c_str(), 0);
ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + full_path + ", error: " + format_error_message(GetLastError()) + ".");
@@ -812,7 +747,6 @@ Error OS_UWP::get_dynamic_library_symbol_handle(void *p_library_handle, const St
}
void OS_UWP::run() {
-
if (!main_loop)
return;
@@ -824,9 +758,9 @@ void OS_UWP::run() {
uint64_t frame = 0;
while (!force_quit) {
-
CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
- if (managed_object->alert_close_handle) continue;
+ if (managed_object->alert_close_handle)
+ continue;
process_events(); // get rid of pending events
if (Main::iteration())
break;
@@ -836,12 +770,10 @@ void OS_UWP::run() {
}
MainLoop *OS_UWP::get_main_loop() const {
-
return main_loop;
}
String OS_UWP::get_user_data_dir() const {
-
Windows::Storage::StorageFolder ^ data_folder = Windows::Storage::ApplicationData::Current->LocalFolder;
return String(data_folder->Path->Data()).replace("\\", "/");
@@ -852,7 +784,6 @@ bool OS_UWP::_check_internal_feature_support(const String &p_feature) {
}
OS_UWP::OS_UWP() {
-
key_event_pos = 0;
force_quit = false;
alt_mem = false;
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index ad0efa1d03..95359c68b0 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -32,7 +32,7 @@
#define OS_UWP_H
#include "context_egl_uwp.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/math/transform_2d.h"
#include "core/os/os.h"
#include "core/ustring.h"
@@ -48,10 +48,8 @@
#include <windows.h>
class OS_UWP : public OS {
-
public:
struct KeyEvent {
-
enum MessageType {
KEY_EVENT_MESSAGE,
CHAR_EVENT_MESSAGE
@@ -236,7 +234,7 @@ public:
virtual bool has_touchscreen_ui_hint() const;
virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1);
+ virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
virtual void hide_virtual_keyboard();
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
diff --git a/platform/uwp/thread_uwp.cpp b/platform/uwp/thread_uwp.cpp
index 9dc20a74e8..8e7bb144be 100644
--- a/platform/uwp/thread_uwp.cpp
+++ b/platform/uwp/thread_uwp.cpp
@@ -33,7 +33,6 @@
#include "core/os/memory.h"
Thread *ThreadUWP::create_func_uwp(ThreadCreateCallback p_callback, void *p_user, const Settings &) {
-
ThreadUWP *thread = memnew(ThreadUWP);
std::thread new_thread(p_callback, p_user);
@@ -43,18 +42,15 @@ Thread *ThreadUWP::create_func_uwp(ThreadCreateCallback p_callback, void *p_user
};
Thread::ID ThreadUWP::get_thread_id_func_uwp() {
-
return std::hash<std::thread::id>()(std::this_thread::get_id());
};
void ThreadUWP::wait_to_finish_func_uwp(Thread *p_thread) {
-
ThreadUWP *tp = static_cast<ThreadUWP *>(p_thread);
tp->thread.join();
};
Thread::ID ThreadUWP::get_id() const {
-
return std::hash<std::thread::id>()(thread.get_id());
};
@@ -63,11 +59,3 @@ void ThreadUWP::make_default() {
get_thread_id_func = get_thread_id_func_uwp;
wait_to_finish_func = wait_to_finish_func_uwp;
};
-
-ThreadUWP::ThreadUWP(){
-
-};
-
-ThreadUWP::~ThreadUWP(){
-
-};
diff --git a/platform/uwp/thread_uwp.h b/platform/uwp/thread_uwp.h
index a2d367ae2f..9b2a2590a8 100644
--- a/platform/uwp/thread_uwp.h
+++ b/platform/uwp/thread_uwp.h
@@ -38,23 +38,22 @@
#include <thread>
class ThreadUWP : public Thread {
-
std::thread thread;
static Thread *create_func_uwp(ThreadCreateCallback p_callback, void *, const Settings &);
static ID get_thread_id_func_uwp();
static void wait_to_finish_func_uwp(Thread *p_thread);
- ThreadUWP();
+ ThreadUWP() {}
public:
virtual ID get_id() const;
static void make_default();
- ~ThreadUWP();
+ ~ThreadUWP() {}
};
-#endif
+#endif // UWP_ENABLED
-#endif
+#endif // THREAD_UWP_H
diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp
index 5a36b5546d..1c32639a38 100644
--- a/platform/windows/context_gl_windows.cpp
+++ b/platform/windows/context_gl_windows.cpp
@@ -51,27 +51,22 @@
typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int *);
void ContextGL_Windows::release_current() {
-
wglMakeCurrent(hDC, nullptr);
}
void ContextGL_Windows::make_current() {
-
wglMakeCurrent(hDC, hRC);
}
int ContextGL_Windows::get_window_width() {
-
return OS::get_singleton()->get_video_mode().width;
}
int ContextGL_Windows::get_window_height() {
-
return OS::get_singleton()->get_video_mode().height;
}
bool ContextGL_Windows::should_vsync_via_compositor() {
-
if (OS::get_singleton()->is_window_fullscreen() || !OS::get_singleton()->is_vsync_via_compositor_enabled()) {
return false;
}
@@ -88,7 +83,6 @@ bool ContextGL_Windows::should_vsync_via_compositor() {
}
void ContextGL_Windows::swap_buffers() {
-
SwapBuffers(hDC);
if (use_vsync) {
@@ -108,7 +102,6 @@ void ContextGL_Windows::swap_buffers() {
}
void ContextGL_Windows::set_use_vsync(bool p_use) {
-
vsync_via_compositor = p_use && should_vsync_via_compositor();
if (wglSwapIntervalEXT) {
@@ -120,14 +113,12 @@ void ContextGL_Windows::set_use_vsync(bool p_use) {
}
bool ContextGL_Windows::is_using_vsync() const {
-
return use_vsync;
}
#define _WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
Error ContextGL_Windows::initialize() {
-
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1,
@@ -175,7 +166,6 @@ Error ContextGL_Windows::initialize() {
wglMakeCurrent(hDC, hRC);
if (opengl_3_context) {
-
int attribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 3, //we want a 3.3 context
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
@@ -217,7 +207,6 @@ Error ContextGL_Windows::initialize() {
}
ContextGL_Windows::ContextGL_Windows(HWND hwnd, bool p_opengl_3_context) {
-
opengl_3_context = p_opengl_3_context;
hWnd = hwnd;
use_vsync = false;
diff --git a/platform/windows/context_gl_windows.h b/platform/windows/context_gl_windows.h
index 280c5a1e3c..046e3437ea 100644
--- a/platform/windows/context_gl_windows.h
+++ b/platform/windows/context_gl_windows.h
@@ -44,7 +44,6 @@ typedef bool(APIENTRY *PFNWGLSWAPINTERVALEXTPROC)(int interval);
typedef int(APIENTRY *PFNWGLGETSWAPINTERVALEXTPROC)(void);
class ContextGL_Windows {
-
HDC hDC;
HGLRC hRC;
unsigned int pixel_format;
diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp
index 1d9eba22d8..996d9722f5 100644
--- a/platform/windows/crash_handler_windows.cpp
+++ b/platform/windows/crash_handler_windows.cpp
@@ -38,11 +38,13 @@
// Backtrace code code based on: https://stackoverflow.com/questions/6205981/windows-c-stack-trace-from-a-running-app
-#include <psapi.h>
#include <algorithm>
#include <iterator>
+#include <string>
#include <vector>
+#include <psapi.h>
+
#pragma comment(lib, "psapi.lib")
#pragma comment(lib, "dbghelp.lib")
diff --git a/platform/windows/crash_handler_windows.h b/platform/windows/crash_handler_windows.h
index adc548073c..66a4cac296 100644
--- a/platform/windows/crash_handler_windows.h
+++ b/platform/windows/crash_handler_windows.h
@@ -41,7 +41,6 @@ extern DWORD CrashHandlerException(EXCEPTION_POINTERS *ep);
#endif
class CrashHandler {
-
bool disabled;
public:
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index ebe9a7d27a..9d8344fa7e 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -36,13 +36,8 @@
#include <avrt.h>
-#ifndef WM_POINTERUPDATE
-#define WM_POINTERUPDATE 0x0245
-#endif
-
#ifdef DEBUG_ENABLED
static String format_error_message(DWORD id) {
-
LPWSTR messageBuffer = nullptr;
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, nullptr);
@@ -87,7 +82,6 @@ void DisplayServerWindows::alert(const String &p_alert, const String &p_title) {
}
void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) {
-
if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED) {
WindowData &wd = windows[MAIN_WINDOW_ID];
@@ -97,7 +91,6 @@ void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) {
ClientToScreen(wd.hWnd, (POINT *)&clipRect.right);
ClipCursor(&clipRect);
if (p_mode == MOUSE_MODE_CAPTURED) {
-
center = window_get_size() / 2;
POINT pos = { (int)center.x, (int)center.y };
ClientToScreen(wd.hWnd, &pos);
@@ -117,8 +110,8 @@ void DisplayServerWindows::_set_mouse_mode_impl(MouseMode p_mode) {
cursor_set_shape(c);
}
}
-void DisplayServerWindows::mouse_set_mode(MouseMode p_mode) {
+void DisplayServerWindows::mouse_set_mode(MouseMode p_mode) {
_THREAD_SAFE_METHOD_
if (mouse_mode == p_mode)
@@ -128,12 +121,12 @@ void DisplayServerWindows::mouse_set_mode(MouseMode p_mode) {
mouse_mode = p_mode;
}
+
DisplayServer::MouseMode DisplayServerWindows::mouse_get_mode() const {
return mouse_mode;
}
void DisplayServerWindows::mouse_warp_to_position(const Point2i &p_to) {
-
_THREAD_SAFE_METHOD_
if (!windows.has(last_focused_window)) {
@@ -141,11 +134,9 @@ void DisplayServerWindows::mouse_warp_to_position(const Point2i &p_to) {
}
if (mouse_mode == MOUSE_MODE_CAPTURED) {
-
old_x = p_to.x;
old_y = p_to.y;
} else {
-
POINT p;
p.x = p_to.x;
p.y = p_to.y;
@@ -154,18 +145,19 @@ void DisplayServerWindows::mouse_warp_to_position(const Point2i &p_to) {
SetCursorPos(p.x, p.y);
}
}
+
Point2i DisplayServerWindows::mouse_get_position() const {
POINT p;
GetCursorPos(&p);
return Point2i(p.x, p.y);
//return Point2(old_x, old_y);
}
+
int DisplayServerWindows::mouse_get_button_state() const {
return last_button_state;
}
void DisplayServerWindows::clipboard_set(const String &p_text) {
-
_THREAD_SAFE_METHOD_
if (!windows.has(last_focused_window)) {
@@ -204,8 +196,8 @@ void DisplayServerWindows::clipboard_set(const String &p_text) {
CloseClipboard();
}
-String DisplayServerWindows::clipboard_get() const {
+String DisplayServerWindows::clipboard_get() const {
_THREAD_SAFE_METHOD_
if (!windows.has(last_focused_window)) {
@@ -218,26 +210,20 @@ String DisplayServerWindows::clipboard_get() const {
};
if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
-
HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
if (mem != nullptr) {
-
LPWSTR ptr = (LPWSTR)GlobalLock(mem);
if (ptr != nullptr) {
-
ret = String((CharType *)ptr);
GlobalUnlock(mem);
};
};
} else if (IsClipboardFormatAvailable(CF_TEXT)) {
-
HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
if (mem != nullptr) {
-
LPTSTR ptr = (LPTSTR)GlobalLock(mem);
if (ptr != nullptr) {
-
ret.parse_utf8((const char *)ptr);
GlobalUnlock(mem);
};
@@ -256,7 +242,6 @@ typedef struct {
} EnumScreenData;
static BOOL CALLBACK _MonitorEnumProcScreen(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
-
EnumScreenData *data = (EnumScreenData *)dwData;
if (data->monitor == hMonitor) {
data->screen = data->count;
@@ -267,7 +252,6 @@ static BOOL CALLBACK _MonitorEnumProcScreen(HMONITOR hMonitor, HDC hdcMonitor, L
}
static BOOL CALLBACK _MonitorEnumProcCount(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
-
int *data = (int *)dwData;
(*data)++;
return TRUE;
@@ -288,7 +272,6 @@ typedef struct {
} EnumPosData;
static BOOL CALLBACK _MonitorEnumProcPos(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
-
EnumPosData *data = (EnumPosData *)dwData;
if (data->count == data->screen) {
data->pos.x = lprcMonitor->left;
@@ -298,8 +281,8 @@ static BOOL CALLBACK _MonitorEnumProcPos(HMONITOR hMonitor, HDC hdcMonitor, LPRE
data->count++;
return TRUE;
}
-Point2i DisplayServerWindows::screen_get_position(int p_screen) const {
+Point2i DisplayServerWindows::screen_get_position(int p_screen) const {
_THREAD_SAFE_METHOD_
EnumPosData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, Point2() };
@@ -320,7 +303,6 @@ typedef struct {
} EnumRectData;
static BOOL CALLBACK _MonitorEnumProcSize(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
-
EnumSizeData *data = (EnumSizeData *)dwData;
if (data->count == data->screen) {
data->size.x = lprcMonitor->right - lprcMonitor->left;
@@ -332,7 +314,6 @@ static BOOL CALLBACK _MonitorEnumProcSize(HMONITOR hMonitor, HDC hdcMonitor, LPR
}
Size2i DisplayServerWindows::screen_get_size(int p_screen) const {
-
_THREAD_SAFE_METHOD_
EnumSizeData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, Size2() };
@@ -341,7 +322,6 @@ Size2i DisplayServerWindows::screen_get_size(int p_screen) const {
}
static BOOL CALLBACK _MonitorEnumProcUsableSize(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
-
EnumRectData *data = (EnumRectData *)dwData;
if (data->count == data->screen) {
MONITORINFO minfo;
@@ -360,7 +340,6 @@ static BOOL CALLBACK _MonitorEnumProcUsableSize(HMONITOR hMonitor, HDC hdcMonito
}
Rect2i DisplayServerWindows::screen_get_usable_rect(int p_screen) const {
-
_THREAD_SAFE_METHOD_
EnumRectData data = { 0, p_screen == SCREEN_OF_MAIN_WINDOW ? window_get_current_screen() : p_screen, Rect2i() };
@@ -382,7 +361,6 @@ enum _MonitorDpiType {
};
static int QueryDpiForMonitor(HMONITOR hmon, _MonitorDpiType dpiType = MDT_Default) {
-
int dpiX = 96, dpiY = 96;
static HMODULE Shcore = nullptr;
@@ -405,7 +383,6 @@ static int QueryDpiForMonitor(HMONITOR hmon, _MonitorDpiType dpiType = MDT_Defau
if (hmon && (Shcore != (HMODULE)INVALID_HANDLE_VALUE)) {
hr = getDPIForMonitor(hmon, dpiType /*MDT_Effective_DPI*/, &x, &y);
if (SUCCEEDED(hr) && (x > 0) && (y > 0)) {
-
dpiX = (int)x;
dpiY = (int)y;
}
@@ -429,7 +406,6 @@ static int QueryDpiForMonitor(HMONITOR hmon, _MonitorDpiType dpiType = MDT_Defau
}
static BOOL CALLBACK _MonitorEnumProcDpi(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
-
EnumDpiData *data = (EnumDpiData *)dwData;
if (data->count == data->screen) {
data->dpi = QueryDpiForMonitor(hMonitor);
@@ -446,6 +422,7 @@ int DisplayServerWindows::screen_get_dpi(int p_screen) const {
EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcDpi, (LPARAM)&data);
return data.dpi;
}
+
bool DisplayServerWindows::screen_is_touchscreen(int p_screen) const {
#ifndef _MSC_VER
#warning touchscreen not working
@@ -455,18 +432,19 @@ bool DisplayServerWindows::screen_is_touchscreen(int p_screen) const {
void DisplayServerWindows::screen_set_orientation(ScreenOrientation p_orientation, int p_screen) {
}
+
DisplayServer::ScreenOrientation DisplayServerWindows::screen_get_orientation(int p_screen) const {
return SCREEN_LANDSCAPE;
}
void DisplayServerWindows::screen_set_keep_on(bool p_enable) {
}
+
bool DisplayServerWindows::screen_is_kept_on() const {
return false;
}
Vector<DisplayServer::WindowID> DisplayServerWindows::get_window_list() const {
-
_THREAD_SAFE_METHOD_
Vector<DisplayServer::WindowID> ret;
@@ -477,7 +455,6 @@ Vector<DisplayServer::WindowID> DisplayServerWindows::get_window_list() const {
}
DisplayServer::WindowID DisplayServerWindows::get_window_at_screen_position(const Point2i &p_position) const {
-
POINT p;
p.x = p_position.x;
p.y = p_position.y;
@@ -492,7 +469,6 @@ DisplayServer::WindowID DisplayServerWindows::get_window_at_screen_position(cons
}
DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
-
_THREAD_SAFE_METHOD_
WindowID window_id = _create_window(p_mode, p_flags, p_rect);
@@ -522,8 +498,8 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
return window_id;
}
-void DisplayServerWindows::delete_sub_window(WindowID p_window) {
+void DisplayServerWindows::delete_sub_window(WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -545,12 +521,15 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) {
}
#endif
+ if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[p_window].wtctx) {
+ wintab_WTClose(windows[p_window].wtctx);
+ windows[p_window].wtctx = 0;
+ }
DestroyWindow(windows[p_window].hWnd);
windows.erase(p_window);
}
void DisplayServerWindows::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -558,7 +537,6 @@ void DisplayServerWindows::window_attach_instance_id(ObjectID p_instance, Window
}
ObjectID DisplayServerWindows::window_get_attached_instance_id(WindowID p_window) const {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), ObjectID());
@@ -566,7 +544,6 @@ ObjectID DisplayServerWindows::window_get_attached_instance_id(WindowID p_window
}
void DisplayServerWindows::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -574,21 +551,20 @@ void DisplayServerWindows::window_set_rect_changed_callback(const Callable &p_ca
}
void DisplayServerWindows::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
windows[p_window].event_callback = p_callable;
}
-void DisplayServerWindows::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerWindows::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
windows[p_window].input_event_callback = p_callable;
}
-void DisplayServerWindows::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
+void DisplayServerWindows::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -596,7 +572,6 @@ void DisplayServerWindows::window_set_input_text_callback(const Callable &p_call
}
void DisplayServerWindows::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -604,7 +579,6 @@ void DisplayServerWindows::window_set_drop_files_callback(const Callable &p_call
}
void DisplayServerWindows::window_set_title(const String &p_title, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -612,7 +586,6 @@ void DisplayServerWindows::window_set_title(const String &p_title, WindowID p_wi
}
int DisplayServerWindows::window_get_current_screen(WindowID p_window) const {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), -1);
@@ -621,8 +594,8 @@ int DisplayServerWindows::window_get_current_screen(WindowID p_window) const {
EnumDisplayMonitors(nullptr, nullptr, _MonitorEnumProcScreen, (LPARAM)&data);
return data.screen;
}
-void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_window) {
+void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -633,7 +606,6 @@ void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_wi
}
Point2i DisplayServerWindows::window_get_position(WindowID p_window) const {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Point2i());
@@ -658,26 +630,27 @@ Point2i DisplayServerWindows::window_get_position(WindowID p_window) const {
return Point2(r.left, r.top);
#endif
}
-void DisplayServerWindows::_update_real_mouse_position(WindowID p_window) {
+void DisplayServerWindows::_update_real_mouse_position(WindowID p_window) {
POINT mouse_pos;
if (GetCursorPos(&mouse_pos) && ScreenToClient(windows[p_window].hWnd, &mouse_pos)) {
if (mouse_pos.x > 0 && mouse_pos.y > 0 && mouse_pos.x <= windows[p_window].width && mouse_pos.y <= windows[p_window].height) {
old_x = mouse_pos.x;
old_y = mouse_pos.y;
old_invalid = false;
- InputFilter::get_singleton()->set_mouse_position(Point2i(mouse_pos.x, mouse_pos.y));
+ Input::get_singleton()->set_mouse_position(Point2i(mouse_pos.x, mouse_pos.y));
}
}
}
-void DisplayServerWindows::window_set_position(const Point2i &p_position, WindowID p_window) {
+void DisplayServerWindows::window_set_position(const Point2i &p_position, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
- if (wd.fullscreen) return;
+ if (wd.fullscreen)
+ return;
#if 0
//wrong needs to account properly for decorations
RECT r;
@@ -711,7 +684,6 @@ void DisplayServerWindows::window_set_position(const Point2i &p_position, Window
}
void DisplayServerWindows::window_set_transient(WindowID p_window, WindowID p_parent) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(p_window == p_parent);
@@ -748,7 +720,6 @@ void DisplayServerWindows::window_set_transient(WindowID p_window, WindowID p_pa
}
void DisplayServerWindows::window_set_max_size(const Size2i p_size, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -760,8 +731,8 @@ void DisplayServerWindows::window_set_max_size(const Size2i p_size, WindowID p_w
}
wd.max_size = p_size;
}
-Size2i DisplayServerWindows::window_get_max_size(WindowID p_window) const {
+Size2i DisplayServerWindows::window_get_max_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -770,7 +741,6 @@ Size2i DisplayServerWindows::window_get_max_size(WindowID p_window) const {
}
void DisplayServerWindows::window_set_min_size(const Size2i p_size, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -782,8 +752,8 @@ void DisplayServerWindows::window_set_min_size(const Size2i p_size, WindowID p_w
}
wd.min_size = p_size;
}
-Size2i DisplayServerWindows::window_get_min_size(WindowID p_window) const {
+Size2i DisplayServerWindows::window_get_min_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -792,7 +762,6 @@ Size2i DisplayServerWindows::window_get_min_size(WindowID p_window) const {
}
void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -836,8 +805,8 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo
ClipCursor(&crect);
}
}
-Size2i DisplayServerWindows::window_get_size(WindowID p_window) const {
+Size2i DisplayServerWindows::window_get_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -853,8 +822,8 @@ Size2i DisplayServerWindows::window_get_size(WindowID p_window) const {
}
return Size2();
}
-Size2i DisplayServerWindows::window_get_real_size(WindowID p_window) const {
+Size2i DisplayServerWindows::window_get_real_size(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
@@ -868,7 +837,6 @@ Size2i DisplayServerWindows::window_get_real_size(WindowID p_window) const {
}
void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscreen, bool p_borderless, bool p_resizable, bool p_maximized, bool p_no_activate_focus, DWORD &r_style, DWORD &r_style_ex) {
-
r_style = 0;
r_style_ex = WS_EX_WINDOWEDGE;
if (p_main_window) {
@@ -881,7 +849,6 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre
// r_style_ex |= WS_EX_TOOLWINDOW;
//}
} else {
-
if (p_resizable) {
if (p_maximized) {
r_style = WS_OVERLAPPEDWINDOW | WS_MAXIMIZE;
@@ -900,7 +867,6 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre
}
void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repaint, bool p_maximized) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -924,14 +890,12 @@ void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repain
}
void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
if (wd.fullscreen && p_mode != WINDOW_MODE_FULLSCREEN) {
-
RECT rect;
wd.fullscreen = false;
@@ -953,21 +917,18 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
}
if (p_mode == WINDOW_MODE_MAXIMIZED) {
-
ShowWindow(wd.hWnd, SW_MAXIMIZE);
wd.maximized = true;
wd.minimized = false;
}
if (p_mode == WINDOW_MODE_WINDOWED) {
-
ShowWindow(wd.hWnd, SW_RESTORE);
wd.maximized = false;
wd.minimized = false;
}
if (p_mode == WINDOW_MODE_MINIMIZED) {
-
ShowWindow(wd.hWnd, SW_MINIMIZE);
wd.maximized = false;
wd.minimized = true;
@@ -996,8 +957,8 @@ void DisplayServerWindows::window_set_mode(WindowMode p_mode, WindowID p_window)
MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE);
}
}
-DisplayServer::WindowMode DisplayServerWindows::window_get_mode(WindowID p_window) const {
+DisplayServer::WindowMode DisplayServerWindows::window_get_mode(WindowID p_window) const {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), WINDOW_MODE_WINDOWED);
@@ -1015,7 +976,6 @@ DisplayServer::WindowMode DisplayServerWindows::window_get_mode(WindowID p_windo
}
bool DisplayServerWindows::window_is_maximize_allowed(WindowID p_window) const {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), false);
@@ -1026,76 +986,65 @@ bool DisplayServerWindows::window_is_maximize_allowed(WindowID p_window) const {
}
void DisplayServerWindows::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
WindowData &wd = windows[p_window];
switch (p_flag) {
case WINDOW_FLAG_RESIZE_DISABLED: {
-
wd.resizable = !p_enabled;
_update_window_style(p_window);
} break;
case WINDOW_FLAG_BORDERLESS: {
-
wd.borderless = p_enabled;
_update_window_style(p_window);
} break;
case WINDOW_FLAG_ALWAYS_ON_TOP: {
-
ERR_FAIL_COND_MSG(wd.transient_parent != INVALID_WINDOW_ID && p_enabled, "Transient windows can't become on top");
wd.always_on_top = p_enabled;
_update_window_style(p_window);
} break;
case WINDOW_FLAG_TRANSPARENT: {
-
// FIXME: Implement.
} break;
case WINDOW_FLAG_NO_FOCUS: {
-
wd.no_focus = p_enabled;
_update_window_style(p_window);
} break;
- case WINDOW_FLAG_MAX: break;
+ case WINDOW_FLAG_MAX:
+ break;
}
}
bool DisplayServerWindows::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), false);
const WindowData &wd = windows[p_window];
switch (p_flag) {
case WINDOW_FLAG_RESIZE_DISABLED: {
-
return !wd.resizable;
} break;
case WINDOW_FLAG_BORDERLESS: {
-
return wd.borderless;
} break;
case WINDOW_FLAG_ALWAYS_ON_TOP: {
-
return wd.always_on_top;
} break;
case WINDOW_FLAG_TRANSPARENT: {
-
// FIXME: Implement.
} break;
case WINDOW_FLAG_NO_FOCUS: {
-
return wd.no_focus;
} break;
- case WINDOW_FLAG_MAX: break;
+ case WINDOW_FLAG_MAX:
+ break;
}
return false;
}
void DisplayServerWindows::window_request_attention(WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1109,8 +1058,8 @@ void DisplayServerWindows::window_request_attention(WindowID p_window) {
info.uCount = 2;
FlashWindowEx(&info);
}
-void DisplayServerWindows::window_move_to_foreground(WindowID p_window) {
+void DisplayServerWindows::window_move_to_foreground(WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1120,7 +1069,6 @@ void DisplayServerWindows::window_move_to_foreground(WindowID p_window) {
}
bool DisplayServerWindows::window_can_draw(WindowID p_window) const {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND_V(!windows.has(p_window), false);
@@ -1129,7 +1077,6 @@ bool DisplayServerWindows::window_can_draw(WindowID p_window) const {
}
bool DisplayServerWindows::can_any_window_draw() const {
-
_THREAD_SAFE_METHOD_
for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
@@ -1142,7 +1089,6 @@ bool DisplayServerWindows::can_any_window_draw() const {
}
void DisplayServerWindows::window_set_ime_active(const bool p_active, WindowID p_window) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1156,8 +1102,8 @@ void DisplayServerWindows::window_set_ime_active(const bool p_active, WindowID p
ImmAssociateContext(wd.hWnd, (HIMC)0);
}
}
-void DisplayServerWindows::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
+void DisplayServerWindows::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!windows.has(p_window));
@@ -1178,7 +1124,6 @@ void DisplayServerWindows::window_set_ime_position(const Point2i &p_pos, WindowI
}
void DisplayServerWindows::console_set_visible(bool p_enabled) {
-
_THREAD_SAFE_METHOD_
if (console_visible == p_enabled)
@@ -1186,12 +1131,12 @@ void DisplayServerWindows::console_set_visible(bool p_enabled) {
ShowWindow(GetConsoleWindow(), p_enabled ? SW_SHOW : SW_HIDE);
console_visible = p_enabled;
}
+
bool DisplayServerWindows::is_console_visible() const {
return console_visible;
}
void DisplayServerWindows::cursor_set_shape(CursorShape p_shape) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
@@ -1232,12 +1177,12 @@ void DisplayServerWindows::cursor_set_shape(CursorShape p_shape) {
cursor_shape = p_shape;
}
+
DisplayServer::CursorShape DisplayServerWindows::cursor_get_shape() const {
return cursor_shape;
}
void DisplayServerWindows::GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, OUT HBITMAP &hAndMaskBitmap, OUT HBITMAP &hXorMaskBitmap) {
-
// Get the system display DC
HDC hDC = GetDC(nullptr);
@@ -1287,11 +1232,9 @@ void DisplayServerWindows::GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTra
}
void DisplayServerWindows::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
-
_THREAD_SAFE_METHOD_
if (p_cursor.is_valid()) {
-
Map<CursorShape, Vector<Variant>>::Element *cursor_c = cursors_cache.find(p_shape);
if (cursor_c) {
@@ -1430,7 +1373,6 @@ void DisplayServerWindows::enable_for_stealing_focus(OS::ProcessID pid) {
}
DisplayServer::LatinKeyboardVariant DisplayServerWindows::get_latin_keyboard_variant() const {
-
_THREAD_SAFE_METHOD_
unsigned long azerty[] = {
@@ -1474,19 +1416,22 @@ DisplayServer::LatinKeyboardVariant DisplayServerWindows::get_latin_keyboard_var
int i = 0;
while (azerty[i] != 0) {
- if (azerty[i] == hex) return LATIN_KEYBOARD_AZERTY;
+ if (azerty[i] == hex)
+ return LATIN_KEYBOARD_AZERTY;
i++;
}
i = 0;
while (qwertz[i] != 0) {
- if (qwertz[i] == hex) return LATIN_KEYBOARD_QWERTZ;
+ if (qwertz[i] == hex)
+ return LATIN_KEYBOARD_QWERTZ;
i++;
}
i = 0;
while (dvorak[i] != 0) {
- if (dvorak[i] == hex) return LATIN_KEYBOARD_DVORAK;
+ if (dvorak[i] == hex)
+ return LATIN_KEYBOARD_DVORAK;
i++;
}
@@ -1494,7 +1439,6 @@ DisplayServer::LatinKeyboardVariant DisplayServerWindows::get_latin_keyboard_var
}
void DisplayServerWindows::process_events() {
-
_THREAD_SAFE_METHOD_
MSG msg;
@@ -1504,19 +1448,17 @@ void DisplayServerWindows::process_events() {
}
while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) {
-
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
if (!drop_events) {
_process_key_events();
- InputFilter::get_singleton()->flush_accumulated_events();
+ Input::get_singleton()->flush_accumulated_events();
}
}
void DisplayServerWindows::force_process_and_drop_events() {
-
_THREAD_SAFE_METHOD_
drop_events = true;
@@ -1526,13 +1468,14 @@ void DisplayServerWindows::force_process_and_drop_events() {
void DisplayServerWindows::release_rendering_thread() {
}
+
void DisplayServerWindows::make_rendering_thread() {
}
+
void DisplayServerWindows::swap_buffers() {
}
void DisplayServerWindows::set_native_icon(const String &p_filename) {
-
_THREAD_SAFE_METHOD_
FileAccess *f = FileAccess::open(p_filename, FileAccess::READ);
@@ -1625,8 +1568,8 @@ void DisplayServerWindows::set_native_icon(const String &p_filename) {
memdelete(f);
memdelete(icon_dir);
}
-void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
+void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
_THREAD_SAFE_METHOD_
ERR_FAIL_COND(!p_icon.is_valid());
@@ -1658,9 +1601,7 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
const uint8_t *r = icon->get_data().ptr();
for (int i = 0; i < h; i++) {
-
for (int j = 0; j < w; j++) {
-
const uint8_t *rpx = &r[((h - i - 1) * w + j) * 4];
uint8_t *wpx = &wr[(i * w + j) * 4];
wpx[0] = rpx[2];
@@ -1681,6 +1622,7 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) {
void DisplayServerWindows::vsync_set_use_via_compositor(bool p_enable) {
}
+
bool DisplayServerWindows::vsync_is_using_via_compositor() const {
return false;
}
@@ -1697,7 +1639,6 @@ void DisplayServerWindows::set_context(Context p_context) {
#define IsTouchEvent(dw) (IsPenEvent(dw) && ((dw)&0x80))
void DisplayServerWindows::_touch_event(WindowID p_window, bool p_pressed, float p_x, float p_y, int idx) {
-
// Defensive
if (touch_state.has(idx) == p_pressed)
return;
@@ -1715,11 +1656,10 @@ void DisplayServerWindows::_touch_event(WindowID p_window, bool p_pressed, float
event->set_pressed(p_pressed);
event->set_position(Vector2(p_x, p_y));
- InputFilter::get_singleton()->accumulate_input_event(event);
+ Input::get_singleton()->accumulate_input_event(event);
}
void DisplayServerWindows::_drag_event(WindowID p_window, float p_x, float p_y, int idx) {
-
Map<int, Vector2>::Element *curr = touch_state.find(idx);
// Defensive
if (!curr)
@@ -1735,13 +1675,12 @@ void DisplayServerWindows::_drag_event(WindowID p_window, float p_x, float p_y,
event->set_position(Vector2(p_x, p_y));
event->set_relative(Vector2(p_x, p_y) - curr->get());
- InputFilter::get_singleton()->accumulate_input_event(event);
+ Input::get_singleton()->accumulate_input_event(event);
curr->get() = Vector2(p_x, p_y);
}
void DisplayServerWindows::_send_window_event(const WindowData &wd, WindowEvent p_event) {
-
if (!wd.event_callback.is_null()) {
Variant event = int(p_event);
Variant *eventp = &event;
@@ -1756,7 +1695,12 @@ void DisplayServerWindows::_dispatch_input_events(const Ref<InputEvent> &p_event
}
void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event) {
+ _THREAD_SAFE_METHOD_
+ if (in_dispatch_input_event) {
+ return;
+ }
+ in_dispatch_input_event = true;
Variant ev = p_event;
Variant *evp = &ev;
Variant ret;
@@ -1768,6 +1712,7 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event)
ERR_FAIL_COND(!windows.has(event_from_window->get_window_id()));
Callable callable = windows[event_from_window->get_window_id()].input_event_callback;
if (callable.is_null()) {
+ in_dispatch_input_event = false;
return;
}
callable.call((const Variant **)&evp, 1, ret, ce);
@@ -1781,14 +1726,13 @@ void DisplayServerWindows::_dispatch_input_event(const Ref<InputEvent> &p_event)
callable.call((const Variant **)&evp, 1, ret, ce);
}
}
+
+ in_dispatch_input_event = false;
}
LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
-
if (drop_events) {
-
if (user_proc) {
-
return CallWindowProcW(user_proc, hWnd, uMsg, wParam, lParam);
} else {
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
@@ -1807,7 +1751,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
switch (uMsg) // Check For Windows Messages
{
case WM_SETFOCUS: {
-
windows[window_id].window_has_focus = true;
last_focused_window = window_id;
@@ -1836,20 +1779,23 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
windows[window_id].minimized = HIWORD(wParam) != 0;
if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) {
-
_send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_IN);
windows[window_id].window_focused = true;
alt_mem = false;
control_mem = false;
shift_mem = false;
} else { // WM_INACTIVE
- InputFilter::get_singleton()->release_pressed_events();
+ Input::get_singleton()->release_pressed_events();
_send_window_event(windows[window_id], WINDOW_EVENT_FOCUS_OUT);
windows[window_id].window_focused = false;
alt_mem = false;
};
- return 0; // Return To The Message Loop
+ if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
+ wintab_WTEnable(windows[window_id].wtctx, GET_WM_ACTIVATE_STATE(wParam, lParam));
+ }
+
+ return 0; // Return To The Message Loop
}
case WM_GETMINMAXINFO: {
if (windows[window_id].resizable && !windows[window_id].fullscreen) {
@@ -1889,13 +1835,11 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
case WM_CLOSE: // Did We Receive A Close Message?
{
-
_send_window_event(windows[window_id], WINDOW_EVENT_CLOSE_REQUEST);
return 0; // Jump Back
}
case WM_MOUSELEAVE: {
-
old_invalid = true;
outside = true;
@@ -1929,6 +1873,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_shift(shift_mem);
mm->set_alt(alt_mem);
+ mm->set_pressure((raw->data.mouse.ulButtons & RI_MOUSE_LEFT_BUTTON_DOWN) ? 1.0f : 0.0f);
+
mm->set_button_mask(last_button_state);
Point2i c(windows[window_id].width / 2, windows[window_id].height / 2);
@@ -1940,14 +1886,13 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_position(c);
mm->set_global_position(c);
- InputFilter::get_singleton()->set_mouse_position(c);
+ Input::get_singleton()->set_mouse_position(c);
mm->set_speed(Vector2(0, 0));
if (raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE) {
mm->set_relative(Vector2(raw->data.mouse.lLastX, raw->data.mouse.lLastY));
} else if (raw->data.mouse.usFlags == MOUSE_MOVE_ABSOLUTE) {
-
int nScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
int nScreenLeft = GetSystemMetrics(SM_XVIRTUALSCREEN);
@@ -1973,16 +1918,132 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
if (windows[window_id].window_has_focus && mm->get_relative() != Vector2())
- InputFilter::get_singleton()->accumulate_input_event(mm);
+ Input::get_singleton()->accumulate_input_event(mm);
}
delete[] lpb;
} break;
+ case WT_CSRCHANGE:
+ case WT_PROXIMITY: {
+ if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
+ AXIS pressure;
+ if (wintab_WTInfo(WTI_DEVICES + windows[window_id].wtlc.lcDevice, DVC_NPRESSURE, &pressure)) {
+ windows[window_id].min_pressure = int(pressure.axMin);
+ windows[window_id].max_pressure = int(pressure.axMax);
+ }
+ AXIS orientation[3];
+ if (wintab_WTInfo(WTI_DEVICES + windows[window_id].wtlc.lcDevice, DVC_ORIENTATION, &orientation)) {
+ windows[window_id].tilt_supported = orientation[0].axResolution && orientation[1].axResolution;
+ }
+ return 0;
+ }
+ } break;
+ case WT_PACKET: {
+ if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
+ PACKET packet;
+ if (wintab_WTPacket(windows[window_id].wtctx, wParam, &packet)) {
+ float pressure = float(packet.pkNormalPressure - windows[window_id].min_pressure) / float(windows[window_id].max_pressure - windows[window_id].min_pressure);
+ windows[window_id].last_pressure = pressure;
+ windows[window_id].last_pressure_update = 0;
+
+ double azim = (packet.pkOrientation.orAzimuth / 10.0f) * (Math_PI / 180);
+ double alt = Math::tan((Math::abs(packet.pkOrientation.orAltitude / 10.0f)) * (Math_PI / 180));
+
+ if (windows[window_id].tilt_supported) {
+ windows[window_id].last_tilt = Vector2(Math::atan(Math::sin(azim) / alt), Math::atan(Math::cos(azim) / alt));
+ } else {
+ windows[window_id].last_tilt = Vector2();
+ }
+
+ POINT coords;
+ GetCursorPos(&coords);
+ ScreenToClient(windows[window_id].hWnd, &coords);
+
+ // Don't calculate relative mouse movement if we don't have focus in CAPTURED mode.
+ if (!windows[window_id].window_has_focus && mouse_mode == MOUSE_MODE_CAPTURED)
+ break;
+
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
+ mm->set_window_id(window_id);
+ mm->set_control(GetKeyState(VK_CONTROL) != 0);
+ mm->set_shift(GetKeyState(VK_SHIFT) != 0);
+ mm->set_alt(alt_mem);
+
+ mm->set_pressure(windows[window_id].last_pressure);
+ mm->set_tilt(windows[window_id].last_tilt);
+
+ mm->set_button_mask(last_button_state);
+
+ mm->set_position(Vector2(coords.x, coords.y));
+ mm->set_global_position(Vector2(coords.x, coords.y));
+
+ if (mouse_mode == MOUSE_MODE_CAPTURED) {
+ Point2i c(windows[window_id].width / 2, windows[window_id].height / 2);
+ old_x = c.x;
+ old_y = c.y;
+
+ if (mm->get_position() == c) {
+ center = c;
+ return 0;
+ }
+
+ Point2i ncenter = mm->get_position();
+ center = ncenter;
+ POINT pos = { (int)c.x, (int)c.y };
+ ClientToScreen(windows[window_id].hWnd, &pos);
+ SetCursorPos(pos.x, pos.y);
+ }
+
+ Input::get_singleton()->set_mouse_position(mm->get_position());
+ mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
+
+ if (old_invalid) {
+ old_x = mm->get_position().x;
+ old_y = mm->get_position().y;
+ old_invalid = false;
+ }
+
+ mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
+ old_x = mm->get_position().x;
+ old_y = mm->get_position().y;
+ if (windows[window_id].window_has_focus)
+ Input::get_singleton()->accumulate_input_event(mm);
+ }
+ return 0;
+ }
+ } break;
+ case WM_POINTERENTER: {
+ if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) {
+ break;
+ }
+
+ if ((OS::get_singleton()->get_current_tablet_driver() != "winink") || !winink_available) {
+ break;
+ }
+
+ uint32_t pointer_id = LOWORD(wParam);
+ POINTER_INPUT_TYPE pointer_type = PT_POINTER;
+ if (!win8p_GetPointerType(pointer_id, &pointer_type)) {
+ break;
+ }
+
+ if (pointer_type != PT_PEN) {
+ break;
+ }
+
+ windows[window_id].block_mm = true;
+ return 0;
+ } break;
+ case WM_POINTERLEAVE: {
+ windows[window_id].block_mm = false;
+ return 0;
+ } break;
case WM_POINTERUPDATE: {
if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) {
break;
}
- if (!win8p_GetPointerType || !win8p_GetPointerPenInfo) {
+ if ((OS::get_singleton()->get_current_tablet_driver() != "winink") || !winink_available) {
break;
}
@@ -2001,7 +2062,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
break;
}
- if (InputFilter::get_singleton()->is_emulating_mouse_from_touch()) {
+ if (Input::get_singleton()->is_emulating_mouse_from_touch()) {
// Universal translation enabled; ignore OS translation
LPARAM extra = GetMessageExtraInfo();
if (IsTouchEvent(extra)) {
@@ -2038,8 +2099,14 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm.instance();
mm->set_window_id(window_id);
- mm->set_pressure(pen_info.pressure ? (float)pen_info.pressure / 1024 : 0);
- mm->set_tilt(Vector2(pen_info.tiltX ? (float)pen_info.tiltX / 90 : 0, pen_info.tiltY ? (float)pen_info.tiltY / 90 : 0));
+ if (pen_info.penMask & PEN_MASK_PRESSURE) {
+ mm->set_pressure((float)pen_info.pressure / 1024);
+ } else {
+ mm->set_pressure((HIWORD(wParam) & POINTER_MESSAGE_FLAG_FIRSTBUTTON) ? 1.0f : 0.0f);
+ }
+ if ((pen_info.penMask & PEN_MASK_TILT_X) && (pen_info.penMask & PEN_MASK_TILT_Y)) {
+ mm->set_tilt(Vector2((float)pen_info.tiltX / 90, (float)pen_info.tiltY / 90));
+ }
mm->set_control((wParam & MK_CONTROL) != 0);
mm->set_shift((wParam & MK_SHIFT) != 0);
@@ -2057,7 +2124,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_global_position(Vector2(coords.x, coords.y));
if (mouse_mode == MOUSE_MODE_CAPTURED) {
-
Point2i c(windows[window_id].width / 2, windows[window_id].height / 2);
old_x = c.x;
old_y = c.y;
@@ -2074,11 +2140,10 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
SetCursorPos(pos.x, pos.y);
}
- InputFilter::get_singleton()->set_mouse_position(mm->get_position());
- mm->set_speed(InputFilter::get_singleton()->get_last_mouse_speed());
+ Input::get_singleton()->set_mouse_position(mm->get_position());
+ mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
if (old_invalid) {
-
old_x = mm->get_position().x;
old_y = mm->get_position().y;
old_invalid = false;
@@ -2088,17 +2153,21 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
old_x = mm->get_position().x;
old_y = mm->get_position().y;
if (windows[window_id].window_has_focus) {
- InputFilter::get_singleton()->parse_input_event(mm);
+ Input::get_singleton()->accumulate_input_event(mm);
}
return 0; //Pointer event handled return 0 to avoid duplicate WM_MOUSEMOVE event
} break;
case WM_MOUSEMOVE: {
+ if (windows[window_id].block_mm) {
+ break;
+ }
+
if (mouse_mode == MOUSE_MODE_CAPTURED && use_raw_input) {
break;
}
- if (InputFilter::get_singleton()->is_emulating_mouse_from_touch()) {
+ if (Input::get_singleton()->is_emulating_mouse_from_touch()) {
// Universal translation enabled; ignore OS translation
LPARAM extra = GetMessageExtraInfo();
if (IsTouchEvent(extra)) {
@@ -2138,13 +2207,28 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mm->set_shift((wParam & MK_SHIFT) != 0);
mm->set_alt(alt_mem);
+ if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available && windows[window_id].wtctx) {
+ // Note: WinTab sends both WT_PACKET and WM_xBUTTONDOWN/UP/MOUSEMOVE events, use mouse 1/0 pressure only when last_pressure was not update recently.
+ if (windows[window_id].last_pressure_update < 10) {
+ windows[window_id].last_pressure_update++;
+ } else {
+ windows[window_id].last_tilt = Vector2();
+ windows[window_id].last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f;
+ }
+ } else {
+ windows[window_id].last_tilt = Vector2();
+ windows[window_id].last_pressure = (wParam & MK_LBUTTON) ? 1.0f : 0.0f;
+ }
+
+ mm->set_pressure(windows[window_id].last_pressure);
+ mm->set_tilt(windows[window_id].last_tilt);
+
mm->set_button_mask(last_button_state);
mm->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
mm->set_global_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
if (mouse_mode == MOUSE_MODE_CAPTURED) {
-
Point2i c(windows[window_id].width / 2, windows[window_id].height / 2);
old_x = c.x;
old_y = c.y;
@@ -2161,11 +2245,10 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
SetCursorPos(pos.x, pos.y);
}
- InputFilter::get_singleton()->set_mouse_position(mm->get_position());
- mm->set_speed(InputFilter::get_singleton()->get_last_mouse_speed());
+ Input::get_singleton()->set_mouse_position(mm->get_position());
+ mm->set_speed(Input::get_singleton()->get_last_mouse_speed());
if (old_invalid) {
-
old_x = mm->get_position().x;
old_y = mm->get_position().y;
old_invalid = false;
@@ -2175,12 +2258,12 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
old_x = mm->get_position().x;
old_y = mm->get_position().y;
if (windows[window_id].window_has_focus)
- InputFilter::get_singleton()->accumulate_input_event(mm);
+ Input::get_singleton()->accumulate_input_event(mm);
} break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
- if (InputFilter::get_singleton()->is_emulating_mouse_from_touch()) {
+ if (Input::get_singleton()->is_emulating_mouse_from_touch()) {
// Universal translation enabled; ignore OS translations for left button
LPARAM extra = GetMessageExtraInfo();
if (IsTouchEvent(extra)) {
@@ -2200,7 +2283,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
case WM_XBUTTONDBLCLK:
case WM_XBUTTONDOWN:
case WM_XBUTTONUP: {
-
Ref<InputEventMouseButton> mb;
mb.instance();
mb->set_window_id(window_id);
@@ -2246,7 +2328,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mb->set_doubleclick(true);
} break;
case WM_MOUSEWHEEL: {
-
mb->set_pressed(true);
int motion = (short)HIWORD(wParam);
if (!motion)
@@ -2259,7 +2340,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break;
case WM_MOUSEHWHEEL: {
-
mb->set_pressed(true);
int motion = (short)HIWORD(wParam);
if (!motion)
@@ -2274,7 +2354,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
} break;
case WM_XBUTTONDOWN: {
-
mb->set_pressed(true);
if (HIWORD(wParam) == XBUTTON1)
mb->set_button_index(BUTTON_XBUTTON1);
@@ -2282,7 +2361,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mb->set_button_index(BUTTON_XBUTTON2);
} break;
case WM_XBUTTONUP: {
-
mb->set_pressed(false);
if (HIWORD(wParam) == XBUTTON1)
mb->set_button_index(BUTTON_XBUTTON1);
@@ -2290,7 +2368,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mb->set_button_index(BUTTON_XBUTTON2);
} break;
case WM_XBUTTONDBLCLK: {
-
mb->set_pressed(true);
if (HIWORD(wParam) == XBUTTON1)
mb->set_button_index(BUTTON_XBUTTON1);
@@ -2316,17 +2393,14 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mb->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
if (mouse_mode == MOUSE_MODE_CAPTURED && !use_raw_input) {
-
mb->set_position(Vector2(old_x, old_y));
}
if (uMsg != WM_MOUSEWHEEL && uMsg != WM_MOUSEHWHEEL) {
if (mb->is_pressed()) {
-
if (++pressrc > 0 && mouse_mode != MOUSE_MODE_CAPTURED)
SetCapture(hWnd);
} else {
-
if (--pressrc <= 0) {
if (mouse_mode != MOUSE_MODE_CAPTURED) {
ReleaseCapture();
@@ -2347,7 +2421,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
mb->set_global_position(mb->get_position());
- InputFilter::get_singleton()->accumulate_input_event(mb);
+ Input::get_singleton()->accumulate_input_event(mb);
if (mb->is_pressed() && mb->get_button_index() > 3 && mb->get_button_index() < 8) {
//send release for mouse wheel
Ref<InputEventMouseButton> mbd = mb->duplicate();
@@ -2355,7 +2429,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
last_button_state &= ~(1 << (mbd->get_button_index() - 1));
mbd->set_button_mask(last_button_state);
mbd->set_pressed(false);
- InputFilter::get_singleton()->accumulate_input_event(mbd);
+ Input::get_singleton()->accumulate_input_event(mbd);
}
} break;
@@ -2367,7 +2441,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
windows[window_id].last_pos = Point2(x, y);
if (!windows[window_id].rect_changed_callback.is_null()) {
-
Variant size = Rect2i(windows[window_id].last_pos.x, windows[window_id].last_pos.y, windows[window_id].width, windows[window_id].height);
Variant *sizep = &size;
Variant ret;
@@ -2399,7 +2472,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
if (!windows[window_id].rect_changed_callback.is_null()) {
-
Variant size = Rect2i(windows[window_id].last_pos.x, windows[window_id].last_pos.y, windows[window_id].width, windows[window_id].height);
Variant *sizep = &size;
Variant ret;
@@ -2444,7 +2516,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break;
case WM_ENTERSIZEMOVE: {
- InputFilter::get_singleton()->release_pressed_events();
+ Input::get_singleton()->release_pressed_events();
move_timer_id = SetTimer(windows[window_id].hWnd, 1, USER_TIMER_MINIMUM, (TIMERPROC) nullptr);
} break;
case WM_EXITSIZEMOVE: {
@@ -2463,7 +2535,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
case WM_SYSKEYUP:
case WM_KEYUP:
case WM_KEYDOWN: {
-
if (wParam == VK_SHIFT)
shift_mem = uMsg == WM_KEYDOWN;
if (wParam == VK_CONTROL)
@@ -2487,7 +2558,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
[[fallthrough]];
}
case WM_CHAR: {
-
ERR_BREAK(key_event_pos >= KEY_EVENT_BUFFER_SIZE);
// Make sure we don't include modifiers for the modifier key itself.
@@ -2510,12 +2580,10 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break;
case WM_INPUTLANGCHANGEREQUEST: {
-
// FIXME: Do something?
} break;
case WM_TOUCH: {
-
BOOL bHandled = FALSE;
UINT cInputs = LOWORD(wParam);
PTOUCHINPUT pInputs = memnew_arr(TOUCHINPUT, cInputs);
@@ -2530,10 +2598,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
ScreenToClient(hWnd, &touch_pos);
//do something with each touch input entry
if (ti.dwFlags & TOUCHEVENTF_MOVE) {
-
_drag_event(window_id, touch_pos.x, touch_pos.y, ti.dwID);
} else if (ti.dwFlags & (TOUCHEVENTF_UP | TOUCHEVENTF_DOWN)) {
-
_touch_event(window_id, ti.dwFlags & TOUCHEVENTF_DOWN, touch_pos.x, touch_pos.y, ti.dwID);
};
}
@@ -2553,7 +2619,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break;
case WM_DEVICECHANGE: {
-
joypad->probe_joypads();
} break;
case WM_SETCURSOR: {
@@ -2576,7 +2641,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break;
case WM_DROPFILES: {
-
HDROP hDropInfo = (HDROP)wParam;
const int buffsize = 4096;
wchar_t buf[buffsize];
@@ -2586,7 +2650,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
Vector<String> files;
for (int i = 0; i < fcount; i++) {
-
DragQueryFileW(hDropInfo, i, buf, buffsize);
String file = buf;
files.push_back(file);
@@ -2603,9 +2666,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break;
default: {
-
if (user_proc) {
-
return CallWindowProcW(user_proc, hWnd, uMsg, wParam, lParam);
};
};
@@ -2615,7 +2676,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
-
DisplayServerWindows *ds_win = static_cast<DisplayServerWindows *>(DisplayServer::get_singleton());
if (ds_win)
return ds_win->WndProc(hWnd, uMsg, wParam, lParam);
@@ -2624,14 +2684,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
}
void DisplayServerWindows::_process_key_events() {
-
for (int i = 0; i < key_event_pos; i++) {
-
KeyEvent &ke = key_event_buffer[i];
switch (ke.uMsg) {
-
case WM_CHAR: {
- if ((i == 0 && ke.uMsg == WM_CHAR) || (i > 0 && key_event_buffer[i - 1].uMsg == WM_CHAR)) {
+ // extended keys should only be processed as WM_KEYDOWN message.
+ if (!KeyMappingWindows::is_extended_key(ke.wParam) && ((i == 0 && ke.uMsg == WM_CHAR) || (i > 0 && key_event_buffer[i - 1].uMsg == WM_CHAR))) {
Ref<InputEventKey> k;
k.instance();
@@ -2652,14 +2710,13 @@ void DisplayServerWindows::_process_key_events() {
if (k->get_unicode() < 32)
k->set_unicode(0);
- InputFilter::get_singleton()->accumulate_input_event(k);
+ Input::get_singleton()->accumulate_input_event(k);
}
//do nothing
} break;
case WM_KEYUP:
case WM_KEYDOWN: {
-
Ref<InputEventKey> k;
k.instance();
@@ -2693,7 +2750,7 @@ void DisplayServerWindows::_process_key_events() {
k->set_echo((ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30))));
- InputFilter::get_singleton()->accumulate_input_event(k);
+ Input::get_singleton()->accumulate_input_event(k);
} break;
}
@@ -2702,8 +2759,46 @@ void DisplayServerWindows::_process_key_events() {
key_event_pos = 0;
}
-DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
+void DisplayServerWindows::_update_tablet_ctx(const String &p_old_driver, const String &p_new_driver) {
+ for (Map<WindowID, WindowData>::Element *E = windows.front(); E; E = E->next()) {
+ WindowData &wd = E->get();
+ wd.block_mm = false;
+ if ((p_old_driver == "wintab") && wintab_available && wd.wtctx) {
+ wintab_WTEnable(wd.wtctx, false);
+ wintab_WTClose(wd.wtctx);
+ wd.wtctx = 0;
+ }
+ if ((p_new_driver == "wintab") && wintab_available) {
+ wintab_WTInfo(WTI_DEFSYSCTX, 0, &wd.wtlc);
+ wd.wtlc.lcOptions |= CXO_MESSAGES;
+ wd.wtlc.lcPktData = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
+ wd.wtlc.lcMoveMask = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
+ wd.wtlc.lcPktMode = 0;
+ wd.wtlc.lcOutOrgX = 0;
+ wd.wtlc.lcOutExtX = wd.wtlc.lcInExtX;
+ wd.wtlc.lcOutOrgY = 0;
+ wd.wtlc.lcOutExtY = -wd.wtlc.lcInExtY;
+ wd.wtctx = wintab_WTOpen(wd.hWnd, &wd.wtlc, false);
+ if (wd.wtctx) {
+ wintab_WTEnable(wd.wtctx, true);
+ AXIS pressure;
+ if (wintab_WTInfo(WTI_DEVICES + wd.wtlc.lcDevice, DVC_NPRESSURE, &pressure)) {
+ wd.min_pressure = int(pressure.axMin);
+ wd.max_pressure = int(pressure.axMax);
+ }
+ AXIS orientation[3];
+ if (wintab_WTInfo(WTI_DEVICES + wd.wtlc.lcDevice, DVC_ORIENTATION, &orientation)) {
+ wd.tilt_supported = orientation[0].axResolution && orientation[1].axResolution;
+ }
+ wintab_WTEnable(wd.wtctx, true);
+ } else {
+ print_verbose("WinTab context creation failed.");
+ }
+ }
+ }
+}
+DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect) {
DWORD dwExStyle;
DWORD dwStyle;
@@ -2759,6 +2854,39 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
DragAcceptFiles(wd.hWnd, true);
+ if ((OS::get_singleton()->get_current_tablet_driver() == "wintab") && wintab_available) {
+ wintab_WTInfo(WTI_DEFSYSCTX, 0, &wd.wtlc);
+ wd.wtlc.lcOptions |= CXO_MESSAGES;
+ wd.wtlc.lcPktData = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE | PK_ORIENTATION;
+ wd.wtlc.lcMoveMask = PK_NORMAL_PRESSURE | PK_TANGENT_PRESSURE;
+ wd.wtlc.lcPktMode = 0;
+ wd.wtlc.lcOutOrgX = 0;
+ wd.wtlc.lcOutExtX = wd.wtlc.lcInExtX;
+ wd.wtlc.lcOutOrgY = 0;
+ wd.wtlc.lcOutExtY = -wd.wtlc.lcInExtY;
+ wd.wtctx = wintab_WTOpen(wd.hWnd, &wd.wtlc, false);
+ if (wd.wtctx) {
+ wintab_WTEnable(wd.wtctx, true);
+ AXIS pressure;
+ if (wintab_WTInfo(WTI_DEVICES + wd.wtlc.lcDevice, DVC_NPRESSURE, &pressure)) {
+ wd.min_pressure = int(pressure.axMin);
+ wd.max_pressure = int(pressure.axMax);
+ }
+ AXIS orientation[3];
+ if (wintab_WTInfo(WTI_DEVICES + wd.wtlc.lcDevice, DVC_ORIENTATION, &orientation)) {
+ wd.tilt_supported = orientation[0].axResolution && orientation[1].axResolution;
+ }
+ } else {
+ print_verbose("WinTab context creation failed.");
+ }
+ } else {
+ wd.wtctx = 0;
+ }
+
+ wd.last_pressure = 0;
+ wd.last_pressure_update = 0;
+ wd.last_tilt = Vector2();
+
// IME
wd.im_himc = ImmGetContext(wd.hWnd);
ImmReleaseContext(wd.hWnd, wd.im_himc);
@@ -2776,6 +2904,16 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode,
return id;
}
+// WinTab API
+bool DisplayServerWindows::wintab_available = false;
+WTOpenPtr DisplayServerWindows::wintab_WTOpen = nullptr;
+WTClosePtr DisplayServerWindows::wintab_WTClose = nullptr;
+WTInfoPtr DisplayServerWindows::wintab_WTInfo = nullptr;
+WTPacketPtr DisplayServerWindows::wintab_WTPacket = nullptr;
+WTEnablePtr DisplayServerWindows::wintab_WTEnable = nullptr;
+
+// Windows Ink API
+bool DisplayServerWindows::winink_available = false;
GetPointerTypePtr DisplayServerWindows::win8p_GetPointerType = nullptr;
GetPointerPenInfoPtr DisplayServerWindows::win8p_GetPointerPenInfo = nullptr;
@@ -2786,14 +2924,6 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS {
} SHC_PROCESS_DPI_AWARENESS;
DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
-
- //Note: Functions for pen input, available on Windows 8+
- HMODULE user32_lib = LoadLibraryW(L"user32.dll");
- if (user32_lib) {
- win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType");
- win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo");
- }
-
drop_events = false;
key_event_pos = 0;
@@ -2863,7 +2993,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
-
context_vulkan = memnew(VulkanContextWindows);
if (context_vulkan->initialize() != OK) {
memdelete(context_vulkan);
@@ -2875,7 +3004,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
#endif
#if defined(OPENGL_ENABLED)
if (rendering_driver_index == VIDEO_DRIVER_GLES2) {
-
context_gles2 = memnew(ContextGL_Windows(hWnd, false));
if (context_gles2->initialize() != OK) {
@@ -2897,7 +3025,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
}
}
#endif
- WindowID main_window = _create_window(p_mode, 0, Rect2i(Point2i(), p_resolution));
+ Point2i window_position(
+ (screen_get_size(0).width - p_resolution.width) / 2,
+ (screen_get_size(0).height - p_resolution.height) / 2);
+ WindowID main_window = _create_window(p_mode, 0, Rect2i(window_position, p_resolution));
for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
if (p_flags & (1 << i)) {
window_set_flag(WindowFlags(i), true, main_window);
@@ -2911,7 +3042,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
#if defined(VULKAN_ENABLED)
if (rendering_driver == "vulkan") {
-
rendering_device_vulkan = memnew(RenderingDeviceVulkan);
rendering_device_vulkan->initialize(context_vulkan);
@@ -2945,7 +3075,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
r_error = OK;
((OS_Windows *)OS::get_singleton())->set_main_window(windows[MAIN_WINDOW_ID].hWnd);
- InputFilter::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
+ Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
}
Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
@@ -2962,35 +3092,19 @@ Vector<String> DisplayServerWindows::get_rendering_drivers_func() {
}
DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, uint32_t p_flags, const Vector2i &p_resolution, Error &r_error) {
-
return memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_flags, p_resolution, r_error));
}
void DisplayServerWindows::register_windows_driver() {
-
register_create_function("windows", create_func, get_rendering_drivers_func);
}
DisplayServerWindows::~DisplayServerWindows() {
-
delete joypad;
touch_state.clear();
cursors_cache.clear();
-#if defined(VULKAN_ENABLED)
- if (rendering_driver == "vulkan") {
-
- if (rendering_device_vulkan) {
- rendering_device_vulkan->finalize();
- memdelete(rendering_device_vulkan);
- }
-
- if (context_vulkan)
- memdelete(context_vulkan);
- }
-#endif
-
if (user_proc) {
SetWindowLongPtr(windows[MAIN_WINDOW_ID].hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc);
};
@@ -3001,7 +3115,22 @@ DisplayServerWindows::~DisplayServerWindows() {
context_vulkan->window_destroy(MAIN_WINDOW_ID);
}
#endif
-
+ if (wintab_available && windows[MAIN_WINDOW_ID].wtctx) {
+ wintab_WTClose(windows[MAIN_WINDOW_ID].wtctx);
+ windows[MAIN_WINDOW_ID].wtctx = 0;
+ }
DestroyWindow(windows[MAIN_WINDOW_ID].hWnd);
}
+
+#if defined(VULKAN_ENABLED)
+ if (rendering_driver == "vulkan") {
+ if (rendering_device_vulkan) {
+ rendering_device_vulkan->finalize();
+ memdelete(rendering_device_vulkan);
+ }
+
+ if (context_vulkan)
+ memdelete(context_vulkan);
+ }
+#endif
}
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 5cd240ffb0..caf8598dc2 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -33,7 +33,7 @@
#include "servers/display_server.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "crash_handler_windows.h"
@@ -66,6 +66,87 @@
#include <windows.h>
#include <windowsx.h>
+// WinTab API
+#define WT_PACKET 0x7FF0
+#define WT_PROXIMITY 0x7FF5
+#define WT_INFOCHANGE 0x7FF6
+#define WT_CSRCHANGE 0x7FF7
+
+#define WTI_DEFSYSCTX 4
+#define WTI_DEVICES 100
+#define DVC_NPRESSURE 15
+#define DVC_TPRESSURE 16
+#define DVC_ORIENTATION 17
+#define DVC_ROTATION 18
+
+#define CXO_MESSAGES 0x0004
+#define PK_NORMAL_PRESSURE 0x0400
+#define PK_TANGENT_PRESSURE 0x0800
+#define PK_ORIENTATION 0x1000
+
+typedef struct tagLOGCONTEXTW {
+ WCHAR lcName[40];
+ UINT lcOptions;
+ UINT lcStatus;
+ UINT lcLocks;
+ UINT lcMsgBase;
+ UINT lcDevice;
+ UINT lcPktRate;
+ DWORD lcPktData;
+ DWORD lcPktMode;
+ DWORD lcMoveMask;
+ DWORD lcBtnDnMask;
+ DWORD lcBtnUpMask;
+ LONG lcInOrgX;
+ LONG lcInOrgY;
+ LONG lcInOrgZ;
+ LONG lcInExtX;
+ LONG lcInExtY;
+ LONG lcInExtZ;
+ LONG lcOutOrgX;
+ LONG lcOutOrgY;
+ LONG lcOutOrgZ;
+ LONG lcOutExtX;
+ LONG lcOutExtY;
+ LONG lcOutExtZ;
+ DWORD lcSensX;
+ DWORD lcSensY;
+ DWORD lcSensZ;
+ BOOL lcSysMode;
+ int lcSysOrgX;
+ int lcSysOrgY;
+ int lcSysExtX;
+ int lcSysExtY;
+ DWORD lcSysSensX;
+ DWORD lcSysSensY;
+} LOGCONTEXTW;
+
+typedef struct tagAXIS {
+ LONG axMin;
+ LONG axMax;
+ UINT axUnits;
+ DWORD axResolution;
+} AXIS;
+
+typedef struct tagORIENTATION {
+ int orAzimuth;
+ int orAltitude;
+ int orTwist;
+} ORIENTATION;
+
+typedef struct tagPACKET {
+ int pkNormalPressure;
+ int pkTangentPressure;
+ ORIENTATION pkOrientation;
+} PACKET;
+
+typedef HANDLE(WINAPI *WTOpenPtr)(HWND p_window, LOGCONTEXTW *p_ctx, BOOL p_enable);
+typedef BOOL(WINAPI *WTClosePtr)(HANDLE p_ctx);
+typedef UINT(WINAPI *WTInfoPtr)(UINT p_category, UINT p_index, LPVOID p_output);
+typedef BOOL(WINAPI *WTPacketPtr)(HANDLE p_ctx, UINT p_param, LPVOID p_packets);
+typedef BOOL(WINAPI *WTEnablePtr)(HANDLE p_ctx, BOOL p_enable);
+
+// Windows Ink API
#ifndef POINTER_STRUCTURES
#define POINTER_STRUCTURES
@@ -75,6 +156,22 @@ typedef UINT32 POINTER_FLAGS;
typedef UINT32 PEN_FLAGS;
typedef UINT32 PEN_MASK;
+#ifndef PEN_MASK_PRESSURE
+#define PEN_MASK_PRESSURE 0x00000001
+#endif
+
+#ifndef PEN_MASK_TILT_X
+#define PEN_MASK_TILT_X 0x00000004
+#endif
+
+#ifndef PEN_MASK_TILT_Y
+#define PEN_MASK_TILT_Y 0x00000008
+#endif
+
+#ifndef POINTER_MESSAGE_FLAG_FIRSTBUTTON
+#define POINTER_MESSAGE_FLAG_FIRSTBUTTON 0x00000010
+#endif
+
enum tagPOINTER_INPUT_TYPE {
PT_POINTER = 0x00000001,
PT_TOUCH = 0x00000002,
@@ -128,6 +225,18 @@ typedef struct tagPOINTER_PEN_INFO {
#endif //POINTER_STRUCTURES
+#ifndef WM_POINTERUPDATE
+#define WM_POINTERUPDATE 0x0245
+#endif
+
+#ifndef WM_POINTERENTER
+#define WM_POINTERENTER 0x0249
+#endif
+
+#ifndef WM_POINTERLEAVE
+#define WM_POINTERLEAVE 0x024A
+#endif
+
typedef BOOL(WINAPI *GetPointerTypePtr)(uint32_t p_id, POINTER_INPUT_TYPE *p_type);
typedef BOOL(WINAPI *GetPointerPenInfoPtr)(uint32_t p_id, POINTER_PEN_INFO *p_pen_info);
@@ -155,9 +264,23 @@ class DisplayServerWindows : public DisplayServer {
_THREAD_SAFE_CLASS_
+public:
+ // WinTab API
+ static bool wintab_available;
+ static WTOpenPtr wintab_WTOpen;
+ static WTClosePtr wintab_WTClose;
+ static WTInfoPtr wintab_WTInfo;
+ static WTPacketPtr wintab_WTPacket;
+ static WTEnablePtr wintab_WTEnable;
+
+ // Windows Ink API
+ static bool winink_available;
static GetPointerTypePtr win8p_GetPointerType;
static GetPointerPenInfoPtr win8p_GetPointerPenInfo;
+ void _update_tablet_ctx(const String &p_old_driver, const String &p_new_driver);
+
+private:
void GetMaskBitmaps(HBITMAP hSourceBitmap, COLORREF clrTransparent, OUT HBITMAP &hAndMaskBitmap, OUT HBITMAP &hXorMaskBitmap);
enum {
@@ -165,7 +288,6 @@ class DisplayServerWindows : public DisplayServer {
};
struct KeyEvent {
-
WindowID window_id;
bool alt, shift, control, meta;
UINT uMsg;
@@ -214,6 +336,17 @@ class DisplayServerWindows : public DisplayServer {
bool no_focus = false;
bool window_has_focus = false;
+ HANDLE wtctx;
+ LOGCONTEXTW wtlc;
+ int min_pressure;
+ int max_pressure;
+ bool tilt_supported;
+ bool block_mm = false;
+
+ int last_pressure_update;
+ float last_pressure;
+ Vector2 last_tilt;
+
HBITMAP hBitmap; //DIB section for layered window
uint8_t *dib_data = nullptr;
Size2 dib_size;
@@ -269,6 +402,7 @@ class DisplayServerWindows : public DisplayServer {
uint32_t last_button_state = 0;
bool use_raw_input = false;
bool drop_events = false;
+ bool in_dispatch_input_event = false;
bool console_visible = false;
WNDCLASSEXW wc;
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index d63067587c..c2436e8b64 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -38,7 +38,6 @@
static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size);
class EditorExportPlatformWindows : public EditorExportPlatformPC {
-
void _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path);
Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path);
@@ -331,7 +330,6 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p
}
void register_windows_exporter() {
-
EDITOR_DEF("export/windows/rcedit", "");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/windows/rcedit", PROPERTY_HINT_GLOBAL_FILE, "*.exe"));
#ifdef WINDOWS_ENABLED
@@ -366,7 +364,6 @@ void register_windows_exporter() {
}
static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) {
-
// Patch the header of the "pck" section in the PE file so that it corresponds to the embedded data
FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE);
@@ -408,7 +405,6 @@ static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start,
bool found = false;
for (int i = 0; i < num_sections; ++i) {
-
int64_t section_header_pos = section_table_pos + i * 40;
f->seek(section_header_pos);
diff --git a/platform/windows/godot_windows.cpp b/platform/windows/godot_windows.cpp
index 2aa928c2a7..910059a9fc 100644
--- a/platform/windows/godot_windows.cpp
+++ b/platform/windows/godot_windows.cpp
@@ -136,7 +136,6 @@ char *wc_to_utf8(const wchar_t *wc) {
}
int widechar_main(int argc, wchar_t **argv) {
-
OS_Windows os(nullptr);
setlocale(LC_CTYPE, "");
diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp
index 437c3b733d..0cff12ca8c 100644
--- a/platform/windows/joypad_windows.cpp
+++ b/platform/windows/joypad_windows.cpp
@@ -45,6 +45,7 @@
DWORD WINAPI _xinput_get_state(DWORD dwUserIndex, XINPUT_STATE *pState) {
return ERROR_DEVICE_NOT_CONNECTED;
}
+
DWORD WINAPI _xinput_set_state(DWORD dwUserIndex, XINPUT_VIBRATION *pVibration) {
return ERROR_DEVICE_NOT_CONNECTED;
}
@@ -53,8 +54,7 @@ JoypadWindows::JoypadWindows() {
}
JoypadWindows::JoypadWindows(HWND *hwnd) {
-
- input = InputFilter::get_singleton();
+ input = Input::get_singleton();
hWnd = hwnd;
joypad_count = 0;
dinput = nullptr;
@@ -76,18 +76,14 @@ JoypadWindows::JoypadWindows(HWND *hwnd) {
}
JoypadWindows::~JoypadWindows() {
-
close_joypad();
dinput->Release();
unload_xinput();
}
bool JoypadWindows::have_device(const GUID &p_guid) {
-
for (int i = 0; i < JOYPADS_MAX; i++) {
-
if (d_joypads[i].guid == p_guid) {
-
d_joypads[i].confirmed = true;
return true;
}
@@ -97,7 +93,6 @@ bool JoypadWindows::have_device(const GUID &p_guid) {
// adapted from SDL2, works a lot better than the MSDN version
bool JoypadWindows::is_xinput_device(const GUID *p_guid) {
-
static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
@@ -112,14 +107,14 @@ bool JoypadWindows::is_xinput_device(const GUID *p_guid) {
return false;
}
dev_list = (PRAWINPUTDEVICELIST)malloc(sizeof(RAWINPUTDEVICELIST) * dev_list_count);
- if (!dev_list) return false;
+ if (!dev_list)
+ return false;
if (GetRawInputDeviceList(dev_list, &dev_list_count, sizeof(RAWINPUTDEVICELIST)) == (UINT)-1) {
free(dev_list);
return false;
}
for (unsigned int i = 0; i < dev_list_count; i++) {
-
RID_DEVICE_INFO rdi;
char dev_name[128];
UINT rdiSize = sizeof(rdi);
@@ -131,7 +126,6 @@ bool JoypadWindows::is_xinput_device(const GUID *p_guid) {
(MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) == (LONG)p_guid->Data1) &&
(GetRawInputDeviceInfoA(dev_list[i].hDevice, RIDI_DEVICENAME, &dev_name, &nameSize) != (UINT)-1) &&
(strstr(dev_name, "IG_") != nullptr)) {
-
free(dev_list);
return true;
}
@@ -141,7 +135,6 @@ bool JoypadWindows::is_xinput_device(const GUID *p_guid) {
}
bool JoypadWindows::setup_dinput_joypad(const DIDEVICEINSTANCE *instance) {
-
HRESULT hr;
int num = input->get_unused_joy_id();
@@ -188,9 +181,7 @@ bool JoypadWindows::setup_dinput_joypad(const DIDEVICEINSTANCE *instance) {
}
void JoypadWindows::setup_joypad_object(const DIDEVICEOBJECTINSTANCE *ob, int p_joy_id) {
-
if (ob->dwType & DIDFT_AXIS) {
-
HRESULT res;
DIPROPRANGE prop_range;
DIPROPDWORD dilong;
@@ -239,7 +230,6 @@ void JoypadWindows::setup_joypad_object(const DIDEVICEOBJECTINSTANCE *ob, int p_
}
BOOL CALLBACK JoypadWindows::enumCallback(const DIDEVICEINSTANCE *p_instance, void *p_context) {
-
JoypadWindows *self = (JoypadWindows *)p_context;
if (self->is_xinput_device(&p_instance->guidProduct)) {
return DIENUM_CONTINUE;
@@ -249,7 +239,6 @@ BOOL CALLBACK JoypadWindows::enumCallback(const DIDEVICEINSTANCE *p_instance, vo
}
BOOL CALLBACK JoypadWindows::objectsCallback(const DIDEVICEOBJECTINSTANCE *instance, void *context) {
-
JoypadWindows *self = (JoypadWindows *)context;
self->setup_joypad_object(instance, self->id_to_change);
@@ -257,17 +246,15 @@ BOOL CALLBACK JoypadWindows::objectsCallback(const DIDEVICEOBJECTINSTANCE *insta
}
void JoypadWindows::close_joypad(int id) {
-
if (id == -1) {
-
for (int i = 0; i < JOYPADS_MAX; i++) {
-
close_joypad(i);
}
return;
}
- if (!d_joypads[id].attached) return;
+ if (!d_joypads[id].attached)
+ return;
d_joypads[id].di_joy->Unacquire();
d_joypads[id].di_joy->Release();
@@ -279,18 +266,14 @@ void JoypadWindows::close_joypad(int id) {
}
void JoypadWindows::probe_joypads() {
-
DWORD dwResult;
for (DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
-
ZeroMemory(&x_joypads[i].state, sizeof(XINPUT_STATE));
dwResult = xinput_get_state(i, &x_joypads[i].state);
if (dwResult == ERROR_SUCCESS) {
-
int id = input->get_unused_joy_id();
if (id != -1 && !x_joypads[i].attached) {
-
x_joypads[i].attached = true;
x_joypads[i].id = id;
x_joypads[i].ff_timestamp = 0;
@@ -300,7 +283,6 @@ void JoypadWindows::probe_joypads() {
input->joy_connection_changed(id, true, "XInput Gamepad", "__XINPUT_DEVICE__");
}
} else if (x_joypads[i].attached) {
-
x_joypads[i].attached = false;
attached_joypads[x_joypads[i].id] = false;
input->joy_connection_changed(x_joypads[i].id, false, "");
@@ -308,27 +290,22 @@ void JoypadWindows::probe_joypads() {
}
for (int i = 0; i < joypad_count; i++) {
-
d_joypads[i].confirmed = false;
}
dinput->EnumDevices(DI8DEVCLASS_GAMECTRL, enumCallback, this, DIEDFL_ATTACHEDONLY);
for (int i = 0; i < joypad_count; i++) {
-
if (!d_joypads[i].confirmed) {
-
close_joypad(i);
}
}
}
void JoypadWindows::process_joypads() {
-
HRESULT hr;
for (int i = 0; i < XUSER_MAX_COUNT; i++) {
-
xinput_gamepad &joy = x_joypads[i];
if (!joy.attached) {
continue;
@@ -337,20 +314,18 @@ void JoypadWindows::process_joypads() {
xinput_get_state(i, &joy.state);
if (joy.state.dwPacketNumber != joy.last_packet) {
-
int button_mask = XINPUT_GAMEPAD_DPAD_UP;
for (int j = 0; j <= 16; j++) {
-
input->joy_button(joy.id, j, joy.state.Gamepad.wButtons & button_mask);
button_mask = button_mask * 2;
}
- input->joy_axis(joy.id, JOY_AXIS_0, axis_correct(joy.state.Gamepad.sThumbLX, true));
- input->joy_axis(joy.id, JOY_AXIS_1, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true));
- input->joy_axis(joy.id, JOY_AXIS_2, axis_correct(joy.state.Gamepad.sThumbRX, true));
- input->joy_axis(joy.id, JOY_AXIS_3, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true));
- input->joy_axis(joy.id, JOY_AXIS_4, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true));
- input->joy_axis(joy.id, JOY_AXIS_5, axis_correct(joy.state.Gamepad.bRightTrigger, true, true));
+ input->joy_axis(joy.id, JOY_AXIS_LEFT_X, axis_correct(joy.state.Gamepad.sThumbLX, true));
+ input->joy_axis(joy.id, JOY_AXIS_LEFT_Y, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true));
+ input->joy_axis(joy.id, JOY_AXIS_RIGHT_X, axis_correct(joy.state.Gamepad.sThumbRX, true));
+ input->joy_axis(joy.id, JOY_AXIS_RIGHT_Y, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true));
+ input->joy_axis(joy.id, JOY_AXIS_TRIGGER_LEFT, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true));
+ input->joy_axis(joy.id, JOY_AXIS_TRIGGER_RIGHT, axis_correct(joy.state.Gamepad.bRightTrigger, true, true));
joy.last_packet = joy.state.dwPacketNumber;
}
uint64_t timestamp = input->get_joy_vibration_timestamp(joy.id);
@@ -370,7 +345,6 @@ void JoypadWindows::process_joypads() {
}
for (int i = 0; i < JOYPADS_MAX; i++) {
-
dinput_gamepad *joy = &d_joypads[i];
if (!joy->attached)
@@ -391,18 +365,13 @@ void JoypadWindows::process_joypads() {
post_hat(joy->id, js.rgdwPOV[0]);
for (int j = 0; j < 128; j++) {
-
if (js.rgbButtons[j] & 0x80) {
-
if (!joy->last_buttons[j]) {
-
input->joy_button(joy->id, j, true);
joy->last_buttons[j] = true;
}
} else {
-
if (joy->last_buttons[j]) {
-
input->joy_button(joy->id, j, false);
joy->last_buttons[j] = false;
}
@@ -415,7 +384,6 @@ void JoypadWindows::process_joypads() {
int values[] = { js.lX, js.lY, js.lZ, js.lRx, js.lRy, js.lRz };
for (int j = 0; j < joy->joy_axis.size(); j++) {
-
for (int k = 0; k < count; k++) {
if (joy->joy_axis[j] == axes[k]) {
input->joy_axis(joy->id, j, axis_correct(values[k]));
@@ -428,7 +396,6 @@ void JoypadWindows::process_joypads() {
}
void JoypadWindows::post_hat(int p_device, DWORD p_dpad) {
-
int dpad_val = 0;
// Should be -1 when centered, but according to docs:
@@ -436,53 +403,43 @@ void JoypadWindows::post_hat(int p_device, DWORD p_dpad) {
// BOOL POVCentered = (LOWORD(dwPOV) == 0xFFFF);"
// https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee416628(v%3Dvs.85)#remarks
if (LOWORD(p_dpad) == 0xFFFF) {
- dpad_val = InputFilter::HAT_MASK_CENTER;
+ dpad_val = Input::HAT_MASK_CENTER;
}
if (p_dpad == 0) {
-
- dpad_val = InputFilter::HAT_MASK_UP;
+ dpad_val = Input::HAT_MASK_UP;
} else if (p_dpad == 4500) {
-
- dpad_val = (InputFilter::HAT_MASK_UP | InputFilter::HAT_MASK_RIGHT);
+ dpad_val = (Input::HAT_MASK_UP | Input::HAT_MASK_RIGHT);
} else if (p_dpad == 9000) {
-
- dpad_val = InputFilter::HAT_MASK_RIGHT;
+ dpad_val = Input::HAT_MASK_RIGHT;
} else if (p_dpad == 13500) {
-
- dpad_val = (InputFilter::HAT_MASK_RIGHT | InputFilter::HAT_MASK_DOWN);
+ dpad_val = (Input::HAT_MASK_RIGHT | Input::HAT_MASK_DOWN);
} else if (p_dpad == 18000) {
-
- dpad_val = InputFilter::HAT_MASK_DOWN;
+ dpad_val = Input::HAT_MASK_DOWN;
} else if (p_dpad == 22500) {
-
- dpad_val = (InputFilter::HAT_MASK_DOWN | InputFilter::HAT_MASK_LEFT);
+ dpad_val = (Input::HAT_MASK_DOWN | Input::HAT_MASK_LEFT);
} else if (p_dpad == 27000) {
-
- dpad_val = InputFilter::HAT_MASK_LEFT;
+ dpad_val = Input::HAT_MASK_LEFT;
} else if (p_dpad == 31500) {
-
- dpad_val = (InputFilter::HAT_MASK_LEFT | InputFilter::HAT_MASK_UP);
+ dpad_val = (Input::HAT_MASK_LEFT | Input::HAT_MASK_UP);
}
input->joy_hat(p_device, dpad_val);
};
-InputFilter::JoyAxis JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const {
-
- InputFilter::JoyAxis jx;
+Input::JoyAxis JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const {
+ Input::JoyAxis jx;
if (Math::abs(p_val) < MIN_JOY_AXIS) {
jx.min = p_trigger ? 0 : -1;
jx.value = 0.0f;
return jx;
}
if (p_xinput) {
-
if (p_trigger) {
jx.min = 0;
jx.value = (float)p_val / MAX_TRIGGER;
@@ -532,7 +489,6 @@ void JoypadWindows::joypad_vibration_stop_xinput(int p_device, uint64_t p_timest
}
void JoypadWindows::load_xinput() {
-
xinput_get_state = &_xinput_get_state;
xinput_set_state = &_xinput_set_state;
xinput_dll = LoadLibrary("XInput1_4.dll");
@@ -559,9 +515,7 @@ void JoypadWindows::load_xinput() {
}
void JoypadWindows::unload_xinput() {
-
if (xinput_dll) {
-
FreeLibrary((HMODULE)xinput_dll);
}
}
diff --git a/platform/windows/joypad_windows.h b/platform/windows/joypad_windows.h
index 0db789c335..6c06b3f6f0 100644
--- a/platform/windows/joypad_windows.h
+++ b/platform/windows/joypad_windows.h
@@ -70,7 +70,6 @@ private:
};
struct dinput_gamepad {
-
int id;
bool attached;
bool confirmed;
@@ -93,7 +92,6 @@ private:
};
struct xinput_gamepad {
-
int id;
bool attached;
bool vibrating;
@@ -117,7 +115,7 @@ private:
HWND *hWnd;
HANDLE xinput_dll;
LPDIRECTINPUT8 dinput;
- InputFilter *input;
+ Input *input;
int id_to_change;
int joypad_count;
@@ -141,7 +139,7 @@ private:
void joypad_vibration_start_xinput(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
void joypad_vibration_stop_xinput(int p_device, uint64_t p_timestamp);
- InputFilter::JoyAxis axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const;
+ Input::JoyAxis axis_correct(int p_val, bool p_xinput = false, bool p_trigger = false, bool p_negate = false) const;
XInputGetState_t xinput_get_state;
XInputSetState_t xinput_set_state;
};
diff --git a/platform/windows/key_mapping_windows.cpp b/platform/windows/key_mapping_windows.cpp
index da63e92622..d8d0b13068 100644
--- a/platform/windows/key_mapping_windows.cpp
+++ b/platform/windows/key_mapping_windows.cpp
@@ -33,7 +33,6 @@
#include <stdio.h>
struct _WinTranslatePair {
-
unsigned int keysym;
unsigned int keycode;
};
@@ -130,7 +129,7 @@ static _WinTranslatePair _vk_to_keycode[] = {
{ KEY_MASK_META, VK_LWIN }, //(0x5B)
{ KEY_MASK_META, VK_RWIN }, //(0x5C)
- //VK_APPS (0x5D)
+ { KEY_MENU, VK_APPS }, //(0x5D)
{ KEY_STANDBY, VK_SLEEP }, //(0x5F)
{ KEY_KP_0, VK_NUMPAD0 }, //(0x60)
{ KEY_KP_1, VK_NUMPAD1 }, //(0x61)
@@ -337,9 +336,7 @@ static _WinTranslatePair _scancode_to_keycode[] = {
};
unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) {
-
for (int i = 0; _vk_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
-
if (_vk_to_keycode[i].keycode == p_code) {
//printf("outcode: %x\n",_vk_to_keycode[i].keysym);
@@ -353,7 +350,6 @@ unsigned int KeyMappingWindows::get_keysym(unsigned int p_code) {
unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended) {
unsigned int keycode = KEY_UNKNOWN;
for (int i = 0; _scancode_to_keycode[i].keysym != KEY_UNKNOWN; i++) {
-
if (_scancode_to_keycode[i].keycode == p_code) {
keycode = _scancode_to_keycode[i].keysym;
break;
@@ -415,3 +411,16 @@ unsigned int KeyMappingWindows::get_scansym(unsigned int p_code, bool p_extended
return keycode;
}
+
+bool KeyMappingWindows::is_extended_key(unsigned int p_code) {
+ return p_code == VK_INSERT ||
+ p_code == VK_DELETE ||
+ p_code == VK_HOME ||
+ p_code == VK_END ||
+ p_code == VK_PRIOR ||
+ p_code == VK_NEXT ||
+ p_code == VK_LEFT ||
+ p_code == VK_UP ||
+ p_code == VK_RIGHT ||
+ p_code == VK_DOWN;
+}
diff --git a/platform/windows/key_mapping_windows.h b/platform/windows/key_mapping_windows.h
index 3361ad397f..f64f1feb9f 100644
--- a/platform/windows/key_mapping_windows.h
+++ b/platform/windows/key_mapping_windows.h
@@ -38,12 +38,12 @@
#include <winuser.h>
class KeyMappingWindows {
-
- KeyMappingWindows(){};
+ KeyMappingWindows() {}
public:
static unsigned int get_keysym(unsigned int p_code);
static unsigned int get_scansym(unsigned int p_code, bool p_extended);
+ static bool is_extended_key(unsigned int p_code);
};
#endif // KEY_MAPPING_WINDOWS_H
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 0a67a591b7..f11888b26c 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -80,7 +80,6 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
#ifdef DEBUG_ENABLED
static String format_error_message(DWORD id) {
-
LPWSTR messageBuffer = nullptr;
size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, nullptr);
@@ -94,7 +93,6 @@ static String format_error_message(DWORD id) {
#endif // DEBUG_ENABLED
void RedirectIOToConsole() {
-
int hConHandle;
intptr_t lStdHandle;
@@ -175,12 +173,10 @@ BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) {
}
void OS_Windows::initialize_debugging() {
-
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
}
void OS_Windows::initialize() {
-
crash_handler.initialize();
//RedirectIOToConsole();
@@ -217,19 +213,16 @@ void OS_Windows::initialize() {
}
void OS_Windows::delete_main_loop() {
-
if (main_loop)
memdelete(main_loop);
main_loop = nullptr;
}
void OS_Windows::set_main_loop(MainLoop *p_main_loop) {
-
main_loop = p_main_loop;
}
void OS_Windows::finalize() {
-
#ifdef WINMIDI_ENABLED
driver_midi.close();
#endif
@@ -241,7 +234,6 @@ void OS_Windows::finalize() {
}
void OS_Windows::finalize_core() {
-
timeEndPeriod(1);
memdelete(process_map);
@@ -249,7 +241,6 @@ void OS_Windows::finalize_core() {
}
Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
-
String path = p_path;
if (!FileAccess::exists(path)) {
@@ -300,12 +291,10 @@ Error OS_Windows::get_dynamic_library_symbol_handle(void *p_library_handle, cons
}
String OS_Windows::get_name() const {
-
return "Windows";
}
OS::Date OS_Windows::get_date(bool utc) const {
-
SYSTEMTIME systemtime;
if (utc)
GetSystemTime(&systemtime);
@@ -320,8 +309,8 @@ OS::Date OS_Windows::get_date(bool utc) const {
date.dst = false;
return date;
}
-OS::Time OS_Windows::get_time(bool utc) const {
+OS::Time OS_Windows::get_time(bool utc) const {
SYSTEMTIME systemtime;
if (utc)
GetSystemTime(&systemtime);
@@ -355,7 +344,6 @@ OS::TimeZoneInfo OS_Windows::get_time_zone_info() const {
}
uint64_t OS_Windows::get_unix_time() const {
-
FILETIME ft;
SYSTEMTIME st;
GetSystemTime(&st);
@@ -387,12 +375,10 @@ uint64_t OS_Windows::get_unix_time() const {
};
uint64_t OS_Windows::get_system_time_secs() const {
-
return get_system_time_msecs() / 1000;
}
uint64_t OS_Windows::get_system_time_msecs() const {
-
const uint64_t WINDOWS_TICK = 10000;
const uint64_t MSEC_TO_UNIX_EPOCH = 11644473600000LL;
@@ -409,14 +395,13 @@ uint64_t OS_Windows::get_system_time_msecs() const {
}
void OS_Windows::delay_usec(uint32_t p_usec) const {
-
if (p_usec < 1000)
Sleep(1);
else
Sleep(p_usec / 1000);
}
-uint64_t OS_Windows::get_ticks_usec() const {
+uint64_t OS_Windows::get_ticks_usec() const {
uint64_t ticks;
uint64_t time;
// This is the number of clock ticks since start
@@ -430,31 +415,34 @@ uint64_t OS_Windows::get_ticks_usec() const {
return time;
}
-Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
+String OS_Windows::_quote_command_line_argument(const String &p_text) const {
+ for (int i = 0; i < p_text.size(); i++) {
+ CharType c = p_text[i];
+ if (c == ' ' || c == '&' || c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}' || c == '^' || c == '=' || c == ';' || c == '!' || c == '\'' || c == '+' || c == ',' || c == '`' || c == '~') {
+ return "\"" + p_text + "\"";
+ }
+ }
+ return p_text;
+}
+Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex) {
if (p_blocking && r_pipe) {
-
- String argss;
- argss = "\"\"" + p_path + "\"";
-
+ String argss = _quote_command_line_argument(p_path);
for (const List<String>::Element *E = p_arguments.front(); E; E = E->next()) {
-
- argss += " \"" + E->get() + "\"";
+ argss += " " + _quote_command_line_argument(E->get());
}
- argss += "\"";
-
if (read_stderr) {
argss += " 2>&1"; // Read stderr too
}
+ // Note: _wpopen is calling command as "cmd.exe /c argss", instead of executing it directly, add extra quotes around full command, to prevent it from stripping quotes in the command.
+ argss = _quote_command_line_argument(argss);
FILE *f = _wpopen(argss.c_str(), L"r");
-
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
char buf[65535];
while (fgets(buf, 65535, f)) {
-
if (p_pipe_mutex) {
p_pipe_mutex->lock();
}
@@ -465,20 +453,19 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
}
int rv = _pclose(f);
- if (r_exitcode)
+ if (r_exitcode) {
*r_exitcode = rv;
+ }
return OK;
}
- String cmdline = "\"" + p_path + "\"";
+ String cmdline = _quote_command_line_argument(p_path);
const List<String>::Element *I = p_arguments.front();
while (I) {
-
- cmdline += " \"" + I->get() + "\"";
-
+ cmdline += " " + _quote_command_line_argument(I->get());
I = I->next();
- };
+ }
ProcessInfo pi;
ZeroMemory(&pi.si, sizeof(pi.si));
@@ -486,34 +473,34 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
ZeroMemory(&pi.pi, sizeof(pi.pi));
LPSTARTUPINFOW si_w = (LPSTARTUPINFOW)&pi.si;
- Vector<CharType> modstr; //windows wants to change this no idea why
+ Vector<CharType> modstr; // Windows wants to change this no idea why.
modstr.resize(cmdline.size());
- for (int i = 0; i < cmdline.size(); i++)
+ for (int i = 0; i < cmdline.size(); i++) {
modstr.write[i] = cmdline[i];
+ }
+
int ret = CreateProcessW(nullptr, modstr.ptrw(), nullptr, nullptr, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, nullptr, nullptr, si_w, &pi.pi);
ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK);
if (p_blocking) {
-
DWORD ret2 = WaitForSingleObject(pi.pi.hProcess, INFINITE);
- if (r_exitcode)
+ if (r_exitcode) {
*r_exitcode = ret2;
+ }
CloseHandle(pi.pi.hProcess);
CloseHandle(pi.pi.hThread);
} else {
-
ProcessID pid = pi.pi.dwProcessId;
if (r_child_id) {
*r_child_id = pid;
- };
+ }
process_map->insert(pid, pi);
- };
+ }
return OK;
};
Error OS_Windows::kill(const ProcessID &p_pid) {
-
ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED);
const PROCESS_INFORMATION pi = (*process_map)[p_pid].pi;
@@ -532,7 +519,6 @@ int OS_Windows::get_process_id() const {
}
Error OS_Windows::set_cwd(const String &p_cwd) {
-
if (_wchdir(p_cwd.c_str()) != 0)
return ERR_CANT_OPEN;
@@ -540,7 +526,6 @@ Error OS_Windows::set_cwd(const String &p_cwd) {
}
String OS_Windows::get_executable_path() const {
-
wchar_t bufname[4096];
GetModuleFileNameW(nullptr, bufname, 4096);
String s = bufname;
@@ -548,7 +533,6 @@ String OS_Windows::get_executable_path() const {
}
bool OS_Windows::has_environment(const String &p_var) const {
-
#ifdef MINGW_ENABLED
return _wgetenv(p_var.c_str()) != nullptr;
#else
@@ -562,7 +546,6 @@ bool OS_Windows::has_environment(const String &p_var) const {
};
String OS_Windows::get_environment(const String &p_var) const {
-
wchar_t wval[0x7Fff]; // MSDN says 32767 char is the maximum
int wlen = GetEnvironmentVariableW(p_var.c_str(), wval, 0x7Fff);
if (wlen > 0) {
@@ -572,12 +555,10 @@ String OS_Windows::get_environment(const String &p_var) const {
}
bool OS_Windows::set_environment(const String &p_var, const String &p_value) const {
-
return (bool)SetEnvironmentVariableW(p_var.c_str(), p_value.c_str());
}
String OS_Windows::get_stdin_string(bool p_block) {
-
if (p_block) {
char buff[1024];
return fgets(buff, 1024, stdin);
@@ -587,13 +568,11 @@ String OS_Windows::get_stdin_string(bool p_block) {
}
Error OS_Windows::shell_open(String p_uri) {
-
ShellExecuteW(nullptr, nullptr, p_uri.c_str(), nullptr, nullptr, SW_SHOWNORMAL);
return OK;
}
String OS_Windows::get_locale() const {
-
const _WinLocale *wl = &_win_locales[0];
LANGID langid = GetUserDefaultUILanguage();
@@ -602,7 +581,6 @@ String OS_Windows::get_locale() const {
int sublang = langid & ~((1 << 9) - 1);
while (wl->locale) {
-
if (wl->main_lang == lang && wl->sublang == SUBLANG_NEUTRAL)
neutral = wl->locale;
@@ -649,14 +627,12 @@ int OS_Windows::get_processor_count() const {
}
void OS_Windows::run() {
-
if (!main_loop)
return;
main_loop->init();
while (!force_quit) {
-
DisplayServer::get_singleton()->process_events(); // get rid of pending events
if (Main::iteration())
break;
@@ -666,12 +642,10 @@ void OS_Windows::run() {
}
MainLoop *OS_Windows::get_main_loop() const {
-
return main_loop;
}
String OS_Windows::get_config_path() const {
-
if (has_environment("XDG_CONFIG_HOME")) { // unlikely, but after all why not?
return get_environment("XDG_CONFIG_HOME");
} else if (has_environment("APPDATA")) {
@@ -682,7 +656,6 @@ String OS_Windows::get_config_path() const {
}
String OS_Windows::get_data_path() const {
-
if (has_environment("XDG_DATA_HOME")) {
return get_environment("XDG_DATA_HOME");
} else {
@@ -691,7 +664,6 @@ String OS_Windows::get_data_path() const {
}
String OS_Windows::get_cache_path() const {
-
if (has_environment("XDG_CACHE_HOME")) {
return get_environment("XDG_CACHE_HOME");
} else if (has_environment("TEMP")) {
@@ -703,12 +675,10 @@ String OS_Windows::get_cache_path() const {
// Get properly capitalized engine name for system paths
String OS_Windows::get_godot_dir_name() const {
-
return String(VERSION_SHORT_NAME).capitalize();
}
String OS_Windows::get_system_dir(SystemDir p_dir) const {
-
KNOWNFOLDERID id;
switch (p_dir) {
@@ -747,7 +717,6 @@ String OS_Windows::get_system_dir(SystemDir p_dir) const {
}
String OS_Windows::get_user_data_dir() const {
-
String appname = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name"));
if (appname != "") {
bool use_custom_dir = ProjectSettings::get_singleton()->get("application/config/use_custom_user_dir");
@@ -766,14 +735,12 @@ String OS_Windows::get_user_data_dir() const {
}
String OS_Windows::get_unique_id() const {
-
HW_PROFILE_INFO HwProfInfo;
ERR_FAIL_COND_V(!GetCurrentHwProfile(&HwProfInfo), "");
return String(HwProfInfo.szHwProfileGuid);
}
bool OS_Windows::_check_internal_feature_support(const String &p_feature) {
-
return p_feature == "pc";
}
@@ -811,7 +778,68 @@ Error OS_Windows::move_to_trash(const String &p_path) {
return OK;
}
+int OS_Windows::get_tablet_driver_count() const {
+ return tablet_drivers.size();
+}
+
+String OS_Windows::get_tablet_driver_name(int p_driver) const {
+ if (p_driver < 0 || p_driver >= tablet_drivers.size()) {
+ return "";
+ } else {
+ return tablet_drivers[p_driver];
+ }
+}
+
+String OS_Windows::get_current_tablet_driver() const {
+ return tablet_driver;
+}
+
+void OS_Windows::set_current_tablet_driver(const String &p_driver) {
+ bool found = false;
+ for (int i = 0; i < get_tablet_driver_count(); i++) {
+ if (p_driver == get_tablet_driver_name(i)) {
+ found = true;
+ }
+ }
+ if (found) {
+ if (DisplayServerWindows::get_singleton()) {
+ ((DisplayServerWindows *)DisplayServerWindows::get_singleton())->_update_tablet_ctx(tablet_driver, p_driver);
+ }
+ tablet_driver = p_driver;
+ } else {
+ ERR_PRINT("Unknown tablet driver " + p_driver + ".");
+ }
+}
+
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
+ //Note: Wacom WinTab driver API for pen input, for devices incompatible with Windows Ink.
+ HMODULE wintab_lib = LoadLibraryW(L"wintab32.dll");
+ if (wintab_lib) {
+ DisplayServerWindows::wintab_WTOpen = (WTOpenPtr)GetProcAddress(wintab_lib, "WTOpenW");
+ DisplayServerWindows::wintab_WTClose = (WTClosePtr)GetProcAddress(wintab_lib, "WTClose");
+ DisplayServerWindows::wintab_WTInfo = (WTInfoPtr)GetProcAddress(wintab_lib, "WTInfoW");
+ DisplayServerWindows::wintab_WTPacket = (WTPacketPtr)GetProcAddress(wintab_lib, "WTPacket");
+ DisplayServerWindows::wintab_WTEnable = (WTEnablePtr)GetProcAddress(wintab_lib, "WTEnable");
+
+ DisplayServerWindows::wintab_available = DisplayServerWindows::wintab_WTOpen && DisplayServerWindows::wintab_WTClose && DisplayServerWindows::wintab_WTInfo && DisplayServerWindows::wintab_WTPacket && DisplayServerWindows::wintab_WTEnable;
+ }
+
+ if (DisplayServerWindows::wintab_available) {
+ tablet_drivers.push_back("wintab");
+ }
+
+ //Note: Windows Ink API for pen input, available on Windows 8+ only.
+ HMODULE user32_lib = LoadLibraryW(L"user32.dll");
+ if (user32_lib) {
+ DisplayServerWindows::win8p_GetPointerType = (GetPointerTypePtr)GetProcAddress(user32_lib, "GetPointerType");
+ DisplayServerWindows::win8p_GetPointerPenInfo = (GetPointerPenInfoPtr)GetProcAddress(user32_lib, "GetPointerPenInfo");
+
+ DisplayServerWindows::winink_available = DisplayServerWindows::win8p_GetPointerType && DisplayServerWindows::win8p_GetPointerPenInfo;
+ }
+
+ if (DisplayServerWindows::winink_available) {
+ tablet_drivers.push_back("winink");
+ }
force_quit = false;
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 6bdfc75ebb..11e3533bfd 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -31,7 +31,7 @@
#ifndef OS_WINDOWS_H
#define OS_WINDOWS_H
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "crash_handler_windows.h"
@@ -63,7 +63,6 @@
class JoypadWindows;
class OS_Windows : public OS {
-
#ifdef STDOUT_FILE
FILE *stdo;
#endif
@@ -74,6 +73,9 @@ class OS_Windows : public OS {
HINSTANCE hInstance;
MainLoop *main_loop;
+ String tablet_driver;
+ Vector<String> tablet_drivers;
+
#ifdef WASAPI_ENABLED
AudioDriverWASAPI driver_wasapi;
#endif
@@ -100,8 +102,9 @@ protected:
virtual void finalize_core();
virtual String get_stdin_string(bool p_block);
- struct ProcessInfo {
+ String _quote_command_line_argument(const String &p_text) const;
+ struct ProcessInfo {
STARTUPINFO si;
PROCESS_INFORMATION pi;
};
@@ -116,6 +119,11 @@ public:
virtual String get_name() const;
+ virtual int get_tablet_driver_count() const;
+ virtual String get_tablet_driver_name(int p_driver) const;
+ virtual String get_current_tablet_driver() const;
+ virtual void set_current_tablet_driver(const String &p_driver);
+
virtual void initialize_joypads() {}
virtual Date get_date(bool utc) const;
diff --git a/platform/windows/vulkan_context_win.cpp b/platform/windows/vulkan_context_win.cpp
index 98aa21411f..2c63281c49 100644
--- a/platform/windows/vulkan_context_win.cpp
+++ b/platform/windows/vulkan_context_win.cpp
@@ -36,7 +36,6 @@ const char *VulkanContextWindows::_get_platform_surface_extension() const {
}
int VulkanContextWindows::window_create(DisplayServer::WindowID p_window_id, HWND p_window, HINSTANCE p_instance, int p_width, int p_height) {
-
VkWin32SurfaceCreateInfoKHR createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
createInfo.pNext = nullptr;
diff --git a/platform/windows/vulkan_context_win.h b/platform/windows/vulkan_context_win.h
index c9fea9369b..6e80db0286 100644
--- a/platform/windows/vulkan_context_win.h
+++ b/platform/windows/vulkan_context_win.h
@@ -35,7 +35,6 @@
#include <windows.h>
class VulkanContextWindows : public VulkanContext {
-
virtual const char *_get_platform_surface_extension() const;
public:
diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp
index 884d95e082..0938b65b04 100644
--- a/platform/windows/windows_terminal_logger.cpp
+++ b/platform/windows/windows_terminal_logger.cpp
@@ -81,7 +81,6 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file
StdLogger::log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
#ifndef UWP_ENABLED
} else {
-
CONSOLE_SCREEN_BUFFER_INFO sbi; //original
GetConsoleScreenBufferInfo(hCon, &sbi);
@@ -89,20 +88,36 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file
uint32_t basecol = 0;
switch (p_type) {
- case ERR_ERROR: basecol = FOREGROUND_RED; break;
- case ERR_WARNING: basecol = FOREGROUND_RED | FOREGROUND_GREEN; break;
- case ERR_SCRIPT: basecol = FOREGROUND_RED | FOREGROUND_BLUE; break;
- case ERR_SHADER: basecol = FOREGROUND_GREEN | FOREGROUND_BLUE; break;
+ case ERR_ERROR:
+ basecol = FOREGROUND_RED;
+ break;
+ case ERR_WARNING:
+ basecol = FOREGROUND_RED | FOREGROUND_GREEN;
+ break;
+ case ERR_SCRIPT:
+ basecol = FOREGROUND_RED | FOREGROUND_BLUE;
+ break;
+ case ERR_SHADER:
+ basecol = FOREGROUND_GREEN | FOREGROUND_BLUE;
+ break;
}
basecol |= current_bg;
SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY);
switch (p_type) {
- case ERR_ERROR: logf("ERROR:"); break;
- case ERR_WARNING: logf("WARNING:"); break;
- case ERR_SCRIPT: logf("SCRIPT ERROR:"); break;
- case ERR_SHADER: logf("SHADER ERROR:"); break;
+ case ERR_ERROR:
+ logf("ERROR:");
+ break;
+ case ERR_WARNING:
+ logf("WARNING:");
+ break;
+ case ERR_SCRIPT:
+ logf("SCRIPT ERROR:");
+ break;
+ case ERR_SHADER:
+ logf("SHADER ERROR:");
+ break;
}
SetConsoleTextAttribute(hCon, basecol);
@@ -115,10 +130,18 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file
// `FOREGROUND_INTENSITY` alone results in gray text.
SetConsoleTextAttribute(hCon, FOREGROUND_INTENSITY);
switch (p_type) {
- case ERR_ERROR: logf(" at: "); break;
- case ERR_WARNING: logf(" at: "); break;
- case ERR_SCRIPT: logf(" at: "); break;
- case ERR_SHADER: logf(" at: "); break;
+ case ERR_ERROR:
+ logf(" at: ");
+ break;
+ case ERR_WARNING:
+ logf(" at: ");
+ break;
+ case ERR_SCRIPT:
+ logf(" at: ");
+ break;
+ case ERR_SHADER:
+ logf(" at: ");
+ break;
}
if (p_rationale && p_rationale[0]) {
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index fc34f967ce..3268544519 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -70,8 +70,9 @@ bool AnimatedSprite2D::_edit_use_rect() const {
return false;
}
Ref<Texture2D> t;
- if (animation)
+ if (animation) {
t = frames->get_frame(animation, frame);
+ }
return t.is_valid();
}
#endif
@@ -86,31 +87,35 @@ Rect2 AnimatedSprite2D::_get_rect() const {
}
Ref<Texture2D> t;
- if (animation)
+ if (animation) {
t = frames->get_frame(animation, frame);
- if (t.is_null())
+ }
+ if (t.is_null()) {
return Rect2();
+ }
Size2 s = t->get_size();
Point2 ofs = offset;
- if (centered)
+ if (centered) {
ofs -= Size2(s) / 2;
+ }
- if (s == Size2(0, 0))
+ if (s == Size2(0, 0)) {
s = Size2(1, 1);
+ }
return Rect2(ofs, s);
}
void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos) {
-
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
- if (p_at_pos >= 0 && p_at_pos < E->get().frames.size())
+ if (p_at_pos >= 0 && p_at_pos < E->get().frames.size()) {
E->get().frames.insert(p_at_pos, p_frame);
- else
+ } else {
E->get().frames.push_back(p_frame);
+ }
emit_changed();
}
@@ -123,15 +128,14 @@ int SpriteFrames::get_frame_count(const StringName &p_anim) const {
}
void SpriteFrames::remove_frame(const StringName &p_anim, int p_idx) {
-
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
E->get().frames.remove(p_idx);
emit_changed();
}
-void SpriteFrames::clear(const StringName &p_anim) {
+void SpriteFrames::clear(const StringName &p_anim) {
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
@@ -140,13 +144,11 @@ void SpriteFrames::clear(const StringName &p_anim) {
}
void SpriteFrames::clear_all() {
-
animations.clear();
add_animation("default");
}
void SpriteFrames::add_animation(const StringName &p_anim) {
-
ERR_FAIL_COND_MSG(animations.has(p_anim), "SpriteFrames already has animation '" + p_anim + "'.");
animations[p_anim] = Anim();
@@ -155,16 +157,14 @@ void SpriteFrames::add_animation(const StringName &p_anim) {
}
bool SpriteFrames::has_animation(const StringName &p_anim) const {
-
return animations.has(p_anim);
}
-void SpriteFrames::remove_animation(const StringName &p_anim) {
+void SpriteFrames::remove_animation(const StringName &p_anim) {
animations.erase(p_anim);
}
void SpriteFrames::rename_animation(const StringName &p_prev, const StringName &p_next) {
-
ERR_FAIL_COND_MSG(!animations.has(p_prev), "SpriteFrames doesn't have animation '" + String(p_prev) + "'.");
ERR_FAIL_COND_MSG(animations.has(p_next), "Animation '" + String(p_next) + "' already exists.");
@@ -176,12 +176,10 @@ void SpriteFrames::rename_animation(const StringName &p_prev, const StringName &
}
Vector<String> SpriteFrames::_get_animation_list() const {
-
Vector<String> ret;
List<StringName> al;
get_animation_list(&al);
for (List<StringName>::Element *E = al.front(); E; E = E->next()) {
-
ret.push_back(E->get());
}
@@ -189,14 +187,12 @@ Vector<String> SpriteFrames::_get_animation_list() const {
}
void SpriteFrames::get_animation_list(List<StringName> *r_animations) const {
-
for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
r_animations->push_back(E->key());
}
}
Vector<String> SpriteFrames::get_animation_names() const {
-
Vector<String> names;
for (const Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
names.push_back(E->key());
@@ -206,14 +202,13 @@ Vector<String> SpriteFrames::get_animation_names() const {
}
void SpriteFrames::set_animation_speed(const StringName &p_anim, float p_fps) {
-
ERR_FAIL_COND_MSG(p_fps < 0, "Animation speed cannot be negative (" + itos(p_fps) + ").");
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
E->get().speed = p_fps;
}
-float SpriteFrames::get_animation_speed(const StringName &p_anim) const {
+float SpriteFrames::get_animation_speed(const StringName &p_anim) const {
const Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_V_MSG(!E, 0, "Animation '" + String(p_anim) + "' doesn't exist.");
return E->get().speed;
@@ -224,6 +219,7 @@ void SpriteFrames::set_animation_loop(const StringName &p_anim, bool p_loop) {
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
E->get().loop = p_loop;
}
+
bool SpriteFrames::get_animation_loop(const StringName &p_anim) const {
const Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_V_MSG(!E, false, "Animation '" + String(p_anim) + "' doesn't exist.");
@@ -231,22 +227,21 @@ bool SpriteFrames::get_animation_loop(const StringName &p_anim) const {
}
void SpriteFrames::_set_frames(const Array &p_frames) {
-
clear_all();
Map<StringName, Anim>::Element *E = animations.find(SceneStringNames::get_singleton()->_default);
ERR_FAIL_COND(!E);
E->get().frames.resize(p_frames.size());
- for (int i = 0; i < E->get().frames.size(); i++)
+ for (int i = 0; i < E->get().frames.size(); i++) {
E->get().frames.write[i] = p_frames[i];
+ }
}
-Array SpriteFrames::_get_frames() const {
+Array SpriteFrames::_get_frames() const {
return Array();
}
Array SpriteFrames::_get_animations() const {
-
Array anims;
for (Map<StringName, Anim>::Element *E = animations.front(); E; E = E->next()) {
Dictionary d;
@@ -263,11 +258,10 @@ Array SpriteFrames::_get_animations() const {
return anims;
}
-void SpriteFrames::_set_animations(const Array &p_animations) {
+void SpriteFrames::_set_animations(const Array &p_animations) {
animations.clear();
for (int i = 0; i < p_animations.size(); i++) {
-
Dictionary d = p_animations[i];
ERR_CONTINUE(!d.has("name"));
@@ -280,7 +274,6 @@ void SpriteFrames::_set_animations(const Array &p_animations) {
anim.loop = d["loop"];
Array frames = d["frames"];
for (int j = 0; j < frames.size(); j++) {
-
RES res = frames[j];
anim.frames.push_back(res);
}
@@ -290,7 +283,6 @@ void SpriteFrames::_set_animations(const Array &p_animations) {
}
void SpriteFrames::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_animation", "anim"), &SpriteFrames::add_animation);
ClassDB::bind_method(D_METHOD("has_animation", "anim"), &SpriteFrames::has_animation);
ClassDB::bind_method(D_METHOD("remove_animation", "anim"), &SpriteFrames::remove_animation);
@@ -324,16 +316,14 @@ void SpriteFrames::_bind_methods() {
}
SpriteFrames::SpriteFrames() {
-
add_animation(SceneStringNames::get_singleton()->_default);
}
void AnimatedSprite2D::_validate_property(PropertyInfo &property) const {
-
- if (!frames.is_valid())
+ if (!frames.is_valid()) {
return;
+ }
if (property.name == "animation") {
-
property.hint = PROPERTY_HINT_ENUM;
List<StringName> names;
frames->get_animation_list(&names);
@@ -371,43 +361,45 @@ void AnimatedSprite2D::_validate_property(PropertyInfo &property) const {
}
void AnimatedSprite2D::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_INTERNAL_PROCESS: {
-
- if (frames.is_null())
+ if (frames.is_null()) {
return;
- if (!frames->has_animation(animation))
+ }
+ if (!frames->has_animation(animation)) {
return;
- if (frame < 0)
+ }
+ if (frame < 0) {
return;
+ }
float speed = frames->get_animation_speed(animation) * speed_scale;
- if (speed == 0)
+ if (speed == 0) {
return; //do nothing
+ }
float remaining = get_process_delta_time();
while (remaining) {
-
if (timeout <= 0) {
-
timeout = _get_frame_duration();
int fc = frames->get_frame_count(animation);
if ((!backwards && frame >= fc - 1) || (backwards && frame <= 0)) {
if (frames->get_animation_loop(animation)) {
- if (backwards)
+ if (backwards) {
frame = fc - 1;
- else
+ } else {
frame = 0;
+ }
emit_signal(SceneStringNames::get_singleton()->animation_finished);
} else {
- if (backwards)
+ if (backwards) {
frame = 0;
- else
+ } else {
frame = fc - 1;
+ }
if (!is_over) {
is_over = true;
@@ -415,10 +407,11 @@ void AnimatedSprite2D::_notification(int p_what) {
}
}
} else {
- if (backwards)
+ if (backwards) {
frame--;
- else
+ } else {
frame++;
+ }
}
update();
@@ -433,17 +426,20 @@ void AnimatedSprite2D::_notification(int p_what) {
} break;
case NOTIFICATION_DRAW: {
-
- if (frames.is_null())
+ if (frames.is_null()) {
return;
- if (frame < 0)
+ }
+ if (frame < 0) {
return;
- if (!frames->has_animation(animation))
+ }
+ if (!frames->has_animation(animation)) {
return;
+ }
Ref<Texture2D> texture = frames->get_frame(animation, frame);
- if (texture.is_null())
+ if (texture.is_null()) {
return;
+ }
Ref<Texture2D> normal = frames->get_normal_frame(animation, frame);
Ref<Texture2D> specular = frames->get_specular_frame(animation, frame);
@@ -453,18 +449,21 @@ void AnimatedSprite2D::_notification(int p_what) {
Size2i s;
s = texture->get_size();
Point2 ofs = offset;
- if (centered)
+ if (centered) {
ofs -= s / 2;
+ }
if (Engine::get_singleton()->get_use_pixel_snap()) {
ofs = ofs.floor();
}
Rect2 dst_rect(ofs, s);
- if (hflip)
+ if (hflip) {
dst_rect.size.x = -dst_rect.size.x;
- if (vflip)
+ }
+ if (vflip) {
dst_rect.size.y = -dst_rect.size.y;
+ }
texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false, normal, specular, Color(specular_color.r, specular_color.g, specular_color.b, shininess));
@@ -473,12 +472,13 @@ void AnimatedSprite2D::_notification(int p_what) {
}
void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
-
- if (frames.is_valid())
+ if (frames.is_valid()) {
frames->disconnect("changed", callable_mp(this, &AnimatedSprite2D::_res_changed));
+ }
frames = p_frames;
- if (frames.is_valid())
+ if (frames.is_valid()) {
frames->connect("changed", callable_mp(this, &AnimatedSprite2D::_res_changed));
+ }
if (!frames.is_valid()) {
frame = 0;
@@ -493,27 +493,28 @@ void AnimatedSprite2D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
}
Ref<SpriteFrames> AnimatedSprite2D::get_sprite_frames() const {
-
return frames;
}
void AnimatedSprite2D::set_frame(int p_frame) {
-
if (!frames.is_valid()) {
return;
}
if (frames->has_animation(animation)) {
int limit = frames->get_frame_count(animation);
- if (p_frame >= limit)
+ if (p_frame >= limit) {
p_frame = limit - 1;
+ }
}
- if (p_frame < 0)
+ if (p_frame < 0) {
p_frame = 0;
+ }
- if (frame == p_frame)
+ if (frame == p_frame) {
return;
+ }
frame = p_frame;
_reset_timeout();
@@ -521,13 +522,12 @@ void AnimatedSprite2D::set_frame(int p_frame) {
_change_notify("frame");
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
-int AnimatedSprite2D::get_frame() const {
+int AnimatedSprite2D::get_frame() const {
return frame;
}
void AnimatedSprite2D::set_speed_scale(float p_speed_scale) {
-
float elapsed = _get_frame_duration() - timeout;
speed_scale = MAX(p_speed_scale, 0.0f);
@@ -538,56 +538,49 @@ void AnimatedSprite2D::set_speed_scale(float p_speed_scale) {
}
float AnimatedSprite2D::get_speed_scale() const {
-
return speed_scale;
}
void AnimatedSprite2D::set_centered(bool p_center) {
-
centered = p_center;
update();
item_rect_changed();
}
bool AnimatedSprite2D::is_centered() const {
-
return centered;
}
void AnimatedSprite2D::set_offset(const Point2 &p_offset) {
-
offset = p_offset;
update();
item_rect_changed();
_change_notify("offset");
}
-Point2 AnimatedSprite2D::get_offset() const {
+Point2 AnimatedSprite2D::get_offset() const {
return offset;
}
void AnimatedSprite2D::set_flip_h(bool p_flip) {
-
hflip = p_flip;
update();
}
-bool AnimatedSprite2D::is_flipped_h() const {
+bool AnimatedSprite2D::is_flipped_h() const {
return hflip;
}
void AnimatedSprite2D::set_flip_v(bool p_flip) {
-
vflip = p_flip;
update();
}
-bool AnimatedSprite2D::is_flipped_v() const {
+bool AnimatedSprite2D::is_flipped_v() const {
return vflip;
}
void AnimatedSprite2D::_res_changed() {
-
set_frame(frame);
_change_notify("frame");
_change_notify("animation");
@@ -595,39 +588,36 @@ void AnimatedSprite2D::_res_changed() {
}
void AnimatedSprite2D::_set_playing(bool p_playing) {
-
- if (playing == p_playing)
+ if (playing == p_playing) {
return;
+ }
playing = p_playing;
_reset_timeout();
set_process_internal(playing);
}
bool AnimatedSprite2D::_is_playing() const {
-
return playing;
}
void AnimatedSprite2D::play(const StringName &p_animation, const bool p_backwards) {
-
backwards = p_backwards;
if (p_animation) {
set_animation(p_animation);
- if (backwards && get_frame() == 0)
+ if (backwards && get_frame() == 0) {
set_frame(frames->get_frame_count(p_animation) - 1);
+ }
}
_set_playing(true);
}
void AnimatedSprite2D::stop() {
-
_set_playing(false);
}
bool AnimatedSprite2D::is_playing() const {
-
return playing;
}
@@ -642,21 +632,21 @@ float AnimatedSprite2D::_get_frame_duration() {
}
void AnimatedSprite2D::_reset_timeout() {
-
- if (!playing)
+ if (!playing) {
return;
+ }
timeout = _get_frame_duration();
is_over = false;
}
void AnimatedSprite2D::set_animation(const StringName &p_animation) {
-
ERR_FAIL_COND_MSG(frames == nullptr, vformat("There is no animation with name '%s'.", p_animation));
ERR_FAIL_COND_MSG(frames->get_animation_names().find(p_animation) == -1, vformat("There is no animation with name '%s'.", p_animation));
- if (animation == p_animation)
+ if (animation == p_animation) {
return;
+ }
animation = p_animation;
_reset_timeout();
@@ -664,13 +654,12 @@ void AnimatedSprite2D::set_animation(const StringName &p_animation) {
_change_notify();
update();
}
-StringName AnimatedSprite2D::get_animation() const {
+StringName AnimatedSprite2D::get_animation() const {
return animation;
}
String AnimatedSprite2D::get_configuration_warning() const {
-
if (frames.is_null()) {
return TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite to display frames.");
}
@@ -697,7 +686,6 @@ float AnimatedSprite2D::get_shininess() const {
}
void AnimatedSprite2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_sprite_frames", "sprite_frames"), &AnimatedSprite2D::set_sprite_frames);
ClassDB::bind_method(D_METHOD("get_sprite_frames"), &AnimatedSprite2D::get_sprite_frames);
@@ -755,7 +743,6 @@ void AnimatedSprite2D::_bind_methods() {
}
AnimatedSprite2D::AnimatedSprite2D() {
-
centered = true;
hflip = false;
vflip = false;
diff --git a/scene/2d/animated_sprite_2d.h b/scene/2d/animated_sprite_2d.h
index 726ecefd32..5e8344ec4c 100644
--- a/scene/2d/animated_sprite_2d.h
+++ b/scene/2d/animated_sprite_2d.h
@@ -35,11 +35,9 @@
#include "scene/resources/texture.h"
class SpriteFrames : public Resource {
-
GDCLASS(SpriteFrames, Resource);
struct Anim {
-
float speed;
bool loop;
Vector<Ref<Texture2D>> frames;
@@ -87,40 +85,40 @@ public:
void add_frame(const StringName &p_anim, const Ref<Texture2D> &p_frame, int p_at_pos = -1);
int get_frame_count(const StringName &p_anim) const;
_FORCE_INLINE_ Ref<Texture2D> get_frame(const StringName &p_anim, int p_idx) const {
-
const Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_V_MSG(!E, Ref<Texture2D>(), "Animation '" + String(p_anim) + "' doesn't exist.");
ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>());
- if (p_idx >= E->get().frames.size())
+ if (p_idx >= E->get().frames.size()) {
return Ref<Texture2D>();
+ }
return E->get().frames[p_idx];
}
_FORCE_INLINE_ Ref<Texture2D> get_normal_frame(const StringName &p_anim, int p_idx) const {
-
const Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_V_MSG(!E, Ref<Texture2D>(), "Animation '" + String(p_anim) + "' doesn't exist.");
ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>());
const Map<StringName, Anim>::Element *EN = animations.find(E->get().normal_name);
- if (!EN || p_idx >= EN->get().frames.size())
+ if (!EN || p_idx >= EN->get().frames.size()) {
return Ref<Texture2D>();
+ }
return EN->get().frames[p_idx];
}
_FORCE_INLINE_ Ref<Texture2D> get_specular_frame(const StringName &p_anim, int p_idx) const {
-
const Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_V(!E, Ref<Texture2D>());
ERR_FAIL_COND_V(p_idx < 0, Ref<Texture2D>());
const Map<StringName, Anim>::Element *EN = animations.find(E->get().specular_name);
- if (!EN || p_idx >= EN->get().frames.size())
+ if (!EN || p_idx >= EN->get().frames.size()) {
return Ref<Texture2D>();
+ }
return EN->get().frames[p_idx];
}
@@ -129,8 +127,9 @@ public:
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND_MSG(!E, "Animation '" + String(p_anim) + "' doesn't exist.");
ERR_FAIL_COND(p_idx < 0);
- if (p_idx >= E->get().frames.size())
+ if (p_idx >= E->get().frames.size()) {
return;
+ }
E->get().frames.write[p_idx] = p_frame;
}
void remove_frame(const StringName &p_anim, int p_idx);
@@ -141,7 +140,6 @@ public:
};
class AnimatedSprite2D : public Node2D {
-
GDCLASS(AnimatedSprite2D, Node2D);
Ref<SpriteFrames> frames;
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index c46b6eeb5c..ebfcb9cad6 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -35,27 +35,24 @@
#include "servers/physics_server_2d.h"
void Area2D::set_space_override_mode(SpaceOverride p_mode) {
-
space_override = p_mode;
PhysicsServer2D::get_singleton()->area_set_space_override_mode(get_rid(), PhysicsServer2D::AreaSpaceOverrideMode(p_mode));
}
-Area2D::SpaceOverride Area2D::get_space_override_mode() const {
+Area2D::SpaceOverride Area2D::get_space_override_mode() const {
return space_override;
}
void Area2D::set_gravity_is_point(bool p_enabled) {
-
gravity_is_point = p_enabled;
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_IS_POINT, p_enabled);
}
-bool Area2D::is_gravity_a_point() const {
+bool Area2D::is_gravity_a_point() const {
return gravity_is_point;
}
void Area2D::set_gravity_distance_scale(real_t p_scale) {
-
gravity_distance_scale = p_scale;
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE, p_scale);
}
@@ -65,58 +62,51 @@ real_t Area2D::get_gravity_distance_scale() const {
}
void Area2D::set_gravity_vector(const Vector2 &p_vec) {
-
gravity_vec = p_vec;
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR, p_vec);
}
-Vector2 Area2D::get_gravity_vector() const {
+Vector2 Area2D::get_gravity_vector() const {
return gravity_vec;
}
void Area2D::set_gravity(real_t p_gravity) {
-
gravity = p_gravity;
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_GRAVITY, p_gravity);
}
-real_t Area2D::get_gravity() const {
+real_t Area2D::get_gravity() const {
return gravity;
}
void Area2D::set_linear_damp(real_t p_linear_damp) {
-
linear_damp = p_linear_damp;
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_LINEAR_DAMP, p_linear_damp);
}
-real_t Area2D::get_linear_damp() const {
+real_t Area2D::get_linear_damp() const {
return linear_damp;
}
void Area2D::set_angular_damp(real_t p_angular_damp) {
-
angular_damp = p_angular_damp;
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP, p_angular_damp);
}
real_t Area2D::get_angular_damp() const {
-
return angular_damp;
}
void Area2D::set_priority(real_t p_priority) {
-
priority = p_priority;
PhysicsServer2D::get_singleton()->area_set_param(get_rid(), PhysicsServer2D::AREA_PARAM_PRIORITY, p_priority);
}
-real_t Area2D::get_priority() const {
+real_t Area2D::get_priority() const {
return priority;
}
void Area2D::_body_enter_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -128,13 +118,11 @@ void Area2D::_body_enter_tree(ObjectID p_id) {
E->get().in_tree = true;
emit_signal(SceneStringNames::get_singleton()->body_entered, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
}
}
void Area2D::_body_exit_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -144,13 +132,11 @@ void Area2D::_body_exit_tree(ObjectID p_id) {
E->get().in_tree = false;
emit_signal(SceneStringNames::get_singleton()->body_exited, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
}
}
void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape) {
-
bool body_in = p_status == PhysicsServer2D::AREA_BODY_ADDED;
ObjectID objid = p_instance;
@@ -167,7 +153,6 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
if (body_in) {
if (!E) {
-
E = body_map.insert(objid, BodyState());
E->get().rc = 0;
E->get().in_tree = node && node->is_inside_tree();
@@ -180,29 +165,30 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
}
}
E->get().rc++;
- if (node)
+ if (node) {
E->get().shapes.insert(ShapePair(p_body_shape, p_area_shape));
+ }
if (!node || E->get().in_tree) {
emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_area_shape);
}
} else {
-
E->get().rc--;
- if (node)
+ if (node) {
E->get().shapes.erase(ShapePair(p_body_shape, p_area_shape));
+ }
bool eraseit = false;
if (E->get().rc == 0) {
-
if (node) {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree));
- if (E->get().in_tree)
+ if (E->get().in_tree) {
emit_signal(SceneStringNames::get_singleton()->body_exited, obj);
+ }
}
eraseit = true;
@@ -211,15 +197,15 @@ void Area2D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
emit_signal(SceneStringNames::get_singleton()->body_shape_exited, objid, obj, p_body_shape, p_area_shape);
}
- if (eraseit)
+ if (eraseit) {
body_map.erase(E);
+ }
}
locked = false;
}
void Area2D::_area_enter_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -231,13 +217,11 @@ void Area2D::_area_enter_tree(ObjectID p_id) {
E->get().in_tree = true;
emit_signal(SceneStringNames::get_singleton()->area_entered, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
}
}
void Area2D::_area_exit_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -247,13 +231,11 @@ void Area2D::_area_exit_tree(ObjectID p_id) {
E->get().in_tree = false;
emit_signal(SceneStringNames::get_singleton()->area_exited, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
}
}
void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape) {
-
bool area_in = p_status == PhysicsServer2D::AREA_BODY_ADDED;
ObjectID objid = p_instance;
@@ -269,7 +251,6 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
if (area_in) {
if (!E) {
-
E = area_map.insert(objid, AreaState());
E->get().rc = 0;
E->get().in_tree = node && node->is_inside_tree();
@@ -282,29 +263,30 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
}
}
E->get().rc++;
- if (node)
+ if (node) {
E->get().shapes.insert(AreaShapePair(p_area_shape, p_self_shape));
+ }
if (!node || E->get().in_tree) {
emit_signal(SceneStringNames::get_singleton()->area_shape_entered, objid, node, p_area_shape, p_self_shape);
}
} else {
-
E->get().rc--;
- if (node)
+ if (node) {
E->get().shapes.erase(AreaShapePair(p_area_shape, p_self_shape));
+ }
bool eraseit = false;
if (E->get().rc == 0) {
-
if (node) {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree));
- if (E->get().in_tree)
+ if (E->get().in_tree) {
emit_signal(SceneStringNames::get_singleton()->area_exited, obj);
+ }
}
eraseit = true;
@@ -313,15 +295,15 @@ void Area2D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
emit_signal(SceneStringNames::get_singleton()->area_shape_exited, objid, obj, p_area_shape, p_self_shape);
}
- if (eraseit)
+ if (eraseit) {
area_map.erase(E);
+ }
}
locked = false;
}
void Area2D::_clear_monitoring() {
-
ERR_FAIL_COND_MSG(locked, "This function can't be used during the in/out signal.");
{
@@ -330,21 +312,21 @@ void Area2D::_clear_monitoring() {
//disconnect all monitored stuff
for (Map<ObjectID, BodyState>::Element *E = bmcopy.front(); E; E = E->next()) {
-
Object *obj = ObjectDB::get_instance(E->key());
Node *node = Object::cast_to<Node>(obj);
- if (!node) //node may have been deleted in previous frame or at other legitimate point
+ if (!node) { //node may have been deleted in previous frame or at other legitimate point
continue;
+ }
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_body_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_body_exit_tree));
- if (!E->get().in_tree)
+ if (!E->get().in_tree) {
continue;
+ }
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->key(), node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
}
@@ -353,27 +335,26 @@ void Area2D::_clear_monitoring() {
}
{
-
Map<ObjectID, AreaState> bmcopy = area_map;
area_map.clear();
//disconnect all monitored stuff
for (Map<ObjectID, AreaState>::Element *E = bmcopy.front(); E; E = E->next()) {
-
Object *obj = ObjectDB::get_instance(E->key());
Node *node = Object::cast_to<Node>(obj);
- if (!node) //node may have been deleted in previous frame or at other legitimate point
+ if (!node) { //node may have been deleted in previous frame or at other legitimate point
continue;
+ }
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area2D::_area_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area2D::_area_exit_tree));
- if (!E->get().in_tree)
+ if (!E->get().in_tree) {
continue;
+ }
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->key(), node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
}
@@ -383,26 +364,22 @@ void Area2D::_clear_monitoring() {
}
void Area2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_EXIT_TREE: {
-
_clear_monitoring();
} break;
}
}
void Area2D::set_monitoring(bool p_enable) {
-
- if (p_enable == monitoring)
+ if (p_enable == monitoring) {
return;
+ }
ERR_FAIL_COND_MSG(locked, "Function blocked during in/out signal. Use set_deferred(\"monitoring\", true/false).");
monitoring = p_enable;
if (monitoring) {
-
PhysicsServer2D::get_singleton()->area_set_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_body_inout);
PhysicsServer2D::get_singleton()->area_set_area_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_area_inout);
@@ -414,16 +391,15 @@ void Area2D::set_monitoring(bool p_enable) {
}
bool Area2D::is_monitoring() const {
-
return monitoring;
}
void Area2D::set_monitorable(bool p_enable) {
-
ERR_FAIL_COND_MSG(locked || (is_inside_tree() && PhysicsServer2D::get_singleton()->is_flushing_queries()), "Function blocked during in/out signal. Use set_deferred(\"monitorable\", true/false).");
- if (p_enable == monitorable)
+ if (p_enable == monitorable) {
return;
+ }
monitorable = p_enable;
@@ -431,14 +407,12 @@ void Area2D::set_monitorable(bool p_enable) {
}
bool Area2D::is_monitorable() const {
-
return monitorable;
}
-Array Area2D::get_overlapping_bodies() const {
-
+TypedArray<Node2D> Area2D::get_overlapping_bodies() const {
ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off.");
- Array ret;
+ TypedArray<Node2D> ret;
ret.resize(body_map.size());
int idx = 0;
for (const Map<ObjectID, BodyState>::Element *E = body_map.front(); E; E = E->next()) {
@@ -453,10 +427,9 @@ Array Area2D::get_overlapping_bodies() const {
return ret;
}
-Array Area2D::get_overlapping_areas() const {
-
+TypedArray<Area2D> Area2D::get_overlapping_areas() const {
ERR_FAIL_COND_V_MSG(!monitoring, Array(), "Can't find overlapping bodies when monitoring is off.");
- Array ret;
+ TypedArray<Area2D> ret;
ret.resize(area_map.size());
int idx = 0;
for (const Map<ObjectID, AreaState>::Element *E = area_map.front(); E; E = E->next()) {
@@ -472,92 +445,82 @@ Array Area2D::get_overlapping_areas() const {
}
bool Area2D::overlaps_area(Node *p_area) const {
-
ERR_FAIL_NULL_V(p_area, false);
const Map<ObjectID, AreaState>::Element *E = area_map.find(p_area->get_instance_id());
- if (!E)
+ if (!E) {
return false;
+ }
return E->get().in_tree;
}
bool Area2D::overlaps_body(Node *p_body) const {
-
ERR_FAIL_NULL_V(p_body, false);
const Map<ObjectID, BodyState>::Element *E = body_map.find(p_body->get_instance_id());
- if (!E)
+ if (!E) {
return false;
+ }
return E->get().in_tree;
}
void Area2D::set_collision_mask(uint32_t p_mask) {
-
collision_mask = p_mask;
PhysicsServer2D::get_singleton()->area_set_collision_mask(get_rid(), p_mask);
}
uint32_t Area2D::get_collision_mask() const {
-
return collision_mask;
}
void Area2D::set_collision_layer(uint32_t p_layer) {
-
collision_layer = p_layer;
PhysicsServer2D::get_singleton()->area_set_collision_layer(get_rid(), p_layer);
}
uint32_t Area2D::get_collision_layer() const {
-
return collision_layer;
}
void Area2D::set_collision_mask_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
bool Area2D::get_collision_mask_bit(int p_bit) const {
-
return get_collision_mask() & (1 << p_bit);
}
void Area2D::set_collision_layer_bit(int p_bit, bool p_value) {
-
uint32_t layer = get_collision_layer();
- if (p_value)
+ if (p_value) {
layer |= 1 << p_bit;
- else
+ } else {
layer &= ~(1 << p_bit);
+ }
set_collision_layer(layer);
}
bool Area2D::get_collision_layer_bit(int p_bit) const {
-
return get_collision_layer() & (1 << p_bit);
}
void Area2D::set_audio_bus_override(bool p_override) {
-
audio_bus_override = p_override;
}
bool Area2D::is_overriding_audio_bus() const {
-
return audio_bus_override;
}
void Area2D::set_audio_bus_name(const StringName &p_audio_bus) {
-
audio_bus = p_audio_bus;
}
StringName Area2D::get_audio_bus_name() const {
-
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
if (AudioServer::get_singleton()->get_bus_name(i) == audio_bus) {
return audio_bus;
@@ -567,13 +530,12 @@ StringName Area2D::get_audio_bus_name() const {
}
void Area2D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "audio_bus_name") {
-
String options;
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
- if (i > 0)
+ if (i > 0) {
options += ",";
+ }
String name = AudioServer::get_singleton()->get_bus_name(i);
options += name;
}
@@ -677,7 +639,6 @@ void Area2D::_bind_methods() {
Area2D::Area2D() :
CollisionObject2D(PhysicsServer2D::get_singleton()->area_create(), true) {
-
space_override = SPACE_OVERRIDE_DISABLED;
set_gravity(98);
set_gravity_vector(Vector2(0, 1));
diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h
index c5e6635412..0d0293dd12 100644
--- a/scene/2d/area_2d.h
+++ b/scene/2d/area_2d.h
@@ -35,7 +35,6 @@
#include "scene/2d/collision_object_2d.h"
class Area2D : public CollisionObject2D {
-
GDCLASS(Area2D, CollisionObject2D);
public:
@@ -68,14 +67,14 @@ private:
void _body_exit_tree(ObjectID p_id);
struct ShapePair {
-
int body_shape;
int area_shape;
bool operator<(const ShapePair &p_sp) const {
- if (body_shape == p_sp.body_shape)
+ if (body_shape == p_sp.body_shape) {
return area_shape < p_sp.area_shape;
- else
+ } else {
return body_shape < p_sp.body_shape;
+ }
}
ShapePair() {}
@@ -86,7 +85,6 @@ private:
};
struct BodyState {
-
int rc;
bool in_tree;
VSet<ShapePair> shapes;
@@ -100,14 +98,14 @@ private:
void _area_exit_tree(ObjectID p_id);
struct AreaShapePair {
-
int area_shape;
int self_shape;
bool operator<(const AreaShapePair &p_sp) const {
- if (area_shape == p_sp.area_shape)
+ if (area_shape == p_sp.area_shape) {
return self_shape < p_sp.self_shape;
- else
+ } else {
return area_shape < p_sp.area_shape;
+ }
}
AreaShapePair() {}
@@ -118,7 +116,6 @@ private:
};
struct AreaState {
-
int rc;
bool in_tree;
VSet<AreaShapePair> shapes;
@@ -178,8 +175,8 @@ public:
void set_collision_layer_bit(int p_bit, bool p_value);
bool get_collision_layer_bit(int p_bit) const;
- Array get_overlapping_bodies() const; //function for script
- Array get_overlapping_areas() const; //function for script
+ TypedArray<Node2D> get_overlapping_bodies() const; //function for script
+ TypedArray<Area2D> get_overlapping_areas() const; //function for script
bool overlaps_area(Node *p_area) const;
bool overlaps_body(Node *p_body) const;
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index 55d111439a..5b89ac15b1 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -35,7 +35,6 @@
#include "scene/main/window.h"
void AudioStreamPlayer2D::_mix_audio() {
-
if (!stream_playback.is_valid() || !active ||
(stream_paused && !stream_paused_fade_out)) {
return;
@@ -59,7 +58,6 @@ void AudioStreamPlayer2D::_mix_audio() {
//write all outputs
for (int i = 0; i < output_count; i++) {
-
Output current = outputs[i];
//see if current output exists, to keep volume ramp
@@ -92,13 +90,13 @@ void AudioStreamPlayer2D::_mix_audio() {
int cc = AudioServer::get_singleton()->get_channel_count();
if (cc == 1) {
- if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, 0))
+ if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, 0)) {
continue; //may have been removed
+ }
AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 0);
for (int j = 0; j < buffer_size; j++) {
-
target[j] += buffer[j] * vol;
vol += vol_inc;
}
@@ -116,11 +114,11 @@ void AudioStreamPlayer2D::_mix_audio() {
targets[k] = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k);
}
- if (!valid)
+ if (!valid) {
continue;
+ }
for (int j = 0; j < buffer_size; j++) {
-
AudioFrame frame = buffer[j] * vol;
for (int k = 0; k < cc; k++) {
targets[k][j] += frame;
@@ -145,9 +143,7 @@ void AudioStreamPlayer2D::_mix_audio() {
}
void AudioStreamPlayer2D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
AudioServer::get_singleton()->add_callback(_mix_audios, this);
if (autoplay && !Engine::get_singleton()->is_editor_hint()) {
play();
@@ -155,7 +151,6 @@ void AudioStreamPlayer2D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
AudioServer::get_singleton()->remove_callback(_mix_audios, this);
}
@@ -171,7 +166,6 @@ void AudioStreamPlayer2D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
-
//update anything related to position first, if possible of course
if (!output_ready) {
@@ -194,13 +188,14 @@ void AudioStreamPlayer2D::_notification(int p_what) {
int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask, false, true);
for (int i = 0; i < areas; i++) {
-
Area2D *area2d = Object::cast_to<Area2D>(sr[i].collider);
- if (!area2d)
+ if (!area2d) {
continue;
+ }
- if (!area2d->is_overriding_audio_bus())
+ if (!area2d->is_overriding_audio_bus()) {
continue;
+ }
StringName bus_name = area2d->get_audio_bus_name();
bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);
@@ -209,10 +204,8 @@ void AudioStreamPlayer2D::_notification(int p_what) {
world_2d->get_viewport_list(&viewports);
for (List<Viewport *>::Element *E = viewports.front(); E; E = E->next()) {
-
Viewport *vp = E->get();
if (vp->is_audio_listener_2d()) {
-
//compute matrix to convert to screen
Transform2D to_screen = vp->get_global_canvas_transform() * vp->get_canvas_transform();
Vector2 screen_size = vp->get_visible_rect().size;
@@ -222,8 +215,9 @@ void AudioStreamPlayer2D::_notification(int p_what) {
float dist = global_pos.distance_to(screen_in_global); //distance to screen center
- if (dist > max_distance)
+ if (dist > max_distance) {
continue; //can't hear this sound in this viewport
+ }
float multiplier = Math::pow(1.0f - dist / max_distance, attenuation);
multiplier *= Math::db2linear(volume_db); //also apply player volume!
@@ -240,8 +234,9 @@ void AudioStreamPlayer2D::_notification(int p_what) {
outputs[new_output_count].bus_index = bus_index;
outputs[new_output_count].viewport = vp; //keep pointer only for reference
new_output_count++;
- if (new_output_count == MAX_OUTPUTS)
+ if (new_output_count == MAX_OUTPUTS) {
break;
+ }
}
}
@@ -269,7 +264,6 @@ void AudioStreamPlayer2D::_notification(int p_what) {
}
void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) {
-
AudioServer::get_singleton()->lock();
mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size());
@@ -294,16 +288,14 @@ void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) {
}
Ref<AudioStream> AudioStreamPlayer2D::get_stream() const {
-
return stream;
}
void AudioStreamPlayer2D::set_volume_db(float p_volume) {
-
volume_db = p_volume;
}
-float AudioStreamPlayer2D::get_volume_db() const {
+float AudioStreamPlayer2D::get_volume_db() const {
return volume_db;
}
@@ -311,12 +303,12 @@ void AudioStreamPlayer2D::set_pitch_scale(float p_pitch_scale) {
ERR_FAIL_COND(p_pitch_scale <= 0.0);
pitch_scale = p_pitch_scale;
}
+
float AudioStreamPlayer2D::get_pitch_scale() const {
return pitch_scale;
}
void AudioStreamPlayer2D::play(float p_from_pos) {
-
if (!is_playing()) {
// Reset the prev_output_count if the stream is stopped
prev_output_count = 0;
@@ -331,14 +323,12 @@ void AudioStreamPlayer2D::play(float p_from_pos) {
}
void AudioStreamPlayer2D::seek(float p_seconds) {
-
if (stream_playback.is_valid()) {
setseek = p_seconds;
}
}
void AudioStreamPlayer2D::stop() {
-
if (stream_playback.is_valid()) {
active = false;
set_physics_process_internal(false);
@@ -347,7 +337,6 @@ void AudioStreamPlayer2D::stop() {
}
bool AudioStreamPlayer2D::is_playing() const {
-
if (stream_playback.is_valid()) {
return active; // && stream_playback->is_playing();
}
@@ -356,7 +345,6 @@ bool AudioStreamPlayer2D::is_playing() const {
}
float AudioStreamPlayer2D::get_playback_position() {
-
if (stream_playback.is_valid()) {
return stream_playback->get_playback_position();
}
@@ -365,14 +353,13 @@ float AudioStreamPlayer2D::get_playback_position() {
}
void AudioStreamPlayer2D::set_bus(const StringName &p_bus) {
-
//if audio is active, must lock this
AudioServer::get_singleton()->lock();
bus = p_bus;
AudioServer::get_singleton()->unlock();
}
-StringName AudioStreamPlayer2D::get_bus() const {
+StringName AudioStreamPlayer2D::get_bus() const {
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
if (AudioServer::get_singleton()->get_bus_name(i) == bus) {
return bus;
@@ -382,34 +369,32 @@ StringName AudioStreamPlayer2D::get_bus() const {
}
void AudioStreamPlayer2D::set_autoplay(bool p_enable) {
-
autoplay = p_enable;
}
-bool AudioStreamPlayer2D::is_autoplay_enabled() {
+bool AudioStreamPlayer2D::is_autoplay_enabled() {
return autoplay;
}
void AudioStreamPlayer2D::_set_playing(bool p_enable) {
-
- if (p_enable)
+ if (p_enable) {
play();
- else
+ } else {
stop();
+ }
}
-bool AudioStreamPlayer2D::_is_active() const {
+bool AudioStreamPlayer2D::_is_active() const {
return active;
}
void AudioStreamPlayer2D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "bus") {
-
String options;
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
- if (i > 0)
+ if (i > 0) {
options += ",";
+ }
String name = AudioServer::get_singleton()->get_bus_name(i);
options += name;
}
@@ -419,42 +404,35 @@ void AudioStreamPlayer2D::_validate_property(PropertyInfo &property) const {
}
void AudioStreamPlayer2D::_bus_layout_changed() {
-
_change_notify();
}
void AudioStreamPlayer2D::set_max_distance(float p_pixels) {
-
ERR_FAIL_COND(p_pixels <= 0.0);
max_distance = p_pixels;
}
float AudioStreamPlayer2D::get_max_distance() const {
-
return max_distance;
}
void AudioStreamPlayer2D::set_attenuation(float p_curve) {
-
attenuation = p_curve;
}
-float AudioStreamPlayer2D::get_attenuation() const {
+float AudioStreamPlayer2D::get_attenuation() const {
return attenuation;
}
void AudioStreamPlayer2D::set_area_mask(uint32_t p_mask) {
-
area_mask = p_mask;
}
uint32_t AudioStreamPlayer2D::get_area_mask() const {
-
return area_mask;
}
void AudioStreamPlayer2D::set_stream_paused(bool p_pause) {
-
if (p_pause != stream_paused) {
stream_paused = p_pause;
stream_paused_fade_in = !p_pause;
@@ -463,7 +441,6 @@ void AudioStreamPlayer2D::set_stream_paused(bool p_pause) {
}
bool AudioStreamPlayer2D::get_stream_paused() const {
-
return stream_paused;
}
@@ -472,7 +449,6 @@ Ref<AudioStreamPlayback> AudioStreamPlayer2D::get_stream_playback() {
}
void AudioStreamPlayer2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer2D::set_stream);
ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer2D::get_stream);
@@ -527,7 +503,6 @@ void AudioStreamPlayer2D::_bind_methods() {
}
AudioStreamPlayer2D::AudioStreamPlayer2D() {
-
volume_db = 0;
pitch_scale = 1.0;
autoplay = false;
diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h
index 86e931b3c6..7f0b6f5897 100644
--- a/scene/2d/audio_stream_player_2d.h
+++ b/scene/2d/audio_stream_player_2d.h
@@ -36,7 +36,6 @@
#include "servers/audio_server.h"
class AudioStreamPlayer2D : public Node2D {
-
GDCLASS(AudioStreamPlayer2D, Node2D);
private:
@@ -47,7 +46,6 @@ private:
};
struct Output {
-
AudioFrame vol;
int bus_index;
Viewport *viewport; //pointer only used for reference to previous mix
diff --git a/scene/2d/back_buffer_copy.cpp b/scene/2d/back_buffer_copy.cpp
index 4c952b7ca6..a36e0a86e1 100644
--- a/scene/2d/back_buffer_copy.cpp
+++ b/scene/2d/back_buffer_copy.cpp
@@ -31,19 +31,14 @@
#include "back_buffer_copy.h"
void BackBufferCopy::_update_copy_mode() {
-
switch (copy_mode) {
-
case COPY_MODE_DISABLED: {
-
RS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(), false, Rect2());
} break;
case COPY_MODE_RECT: {
-
RS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(), true, rect);
} break;
case COPY_MODE_VIEWPORT: {
-
RS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(), true, Rect2());
} break;
@@ -52,7 +47,6 @@ void BackBufferCopy::_update_copy_mode() {
#ifdef TOOLS_ENABLED
Rect2 BackBufferCopy::_edit_get_rect() const {
-
return rect;
}
@@ -62,12 +56,10 @@ bool BackBufferCopy::_edit_use_rect() const {
#endif
Rect2 BackBufferCopy::get_anchorable_rect() const {
-
return rect;
}
void BackBufferCopy::set_rect(const Rect2 &p_rect) {
-
rect = p_rect;
_update_copy_mode();
}
@@ -77,17 +69,15 @@ Rect2 BackBufferCopy::get_rect() const {
}
void BackBufferCopy::set_copy_mode(CopyMode p_mode) {
-
copy_mode = p_mode;
_update_copy_mode();
}
-BackBufferCopy::CopyMode BackBufferCopy::get_copy_mode() const {
+BackBufferCopy::CopyMode BackBufferCopy::get_copy_mode() const {
return copy_mode;
}
void BackBufferCopy::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_rect", "rect"), &BackBufferCopy::set_rect);
ClassDB::bind_method(D_METHOD("get_rect"), &BackBufferCopy::get_rect);
@@ -103,10 +93,10 @@ void BackBufferCopy::_bind_methods() {
}
BackBufferCopy::BackBufferCopy() {
-
rect = Rect2(-100, -100, 200, 200);
copy_mode = COPY_MODE_RECT;
_update_copy_mode();
}
+
BackBufferCopy::~BackBufferCopy() {
}
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index d8af14a3fb..8f69676da4 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -36,20 +36,20 @@
#include "servers/rendering_server.h"
void Camera2D::_update_scroll() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
if (Engine::get_singleton()->is_editor_hint()) {
update(); //will just be drawn
return;
}
- if (!viewport)
+ if (!viewport) {
return;
+ }
if (current) {
-
ERR_FAIL_COND(custom_viewport && !ObjectDB::get_instance(custom_viewport_id));
Transform2D xform = get_camera_transform();
@@ -64,7 +64,6 @@ void Camera2D::_update_scroll() {
}
void Camera2D::_update_process_mode() {
-
if (Engine::get_singleton()->is_editor_hint()) {
set_process_internal(false);
set_physics_process_internal(false);
@@ -78,7 +77,6 @@ void Camera2D::_update_process_mode() {
}
void Camera2D::set_zoom(const Vector2 &p_zoom) {
-
zoom = p_zoom;
Point2 old_smoothed_camera_pos = smoothed_camera_pos;
_update_scroll();
@@ -86,14 +84,13 @@ void Camera2D::set_zoom(const Vector2 &p_zoom) {
};
Vector2 Camera2D::get_zoom() const {
-
return zoom;
};
Transform2D Camera2D::get_camera_transform() {
-
- if (!get_tree())
+ if (!get_tree()) {
return Transform2D();
+ }
ERR_FAIL_COND_V(custom_viewport && !ObjectDB::get_instance(custom_viewport_id), Transform2D());
@@ -103,14 +100,11 @@ Transform2D Camera2D::get_camera_transform() {
Point2 ret_camera_pos;
if (!first) {
-
if (anchor_mode == ANCHOR_MODE_DRAG_CENTER) {
-
if (h_drag_enabled && !Engine::get_singleton()->is_editor_hint() && !h_offset_changed) {
camera_pos.x = MIN(camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * zoom.x * drag_margin[MARGIN_LEFT]));
camera_pos.x = MAX(camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * zoom.x * drag_margin[MARGIN_RIGHT]));
} else {
-
if (h_ofs < 0) {
camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT] * h_ofs;
} else {
@@ -121,12 +115,10 @@ Transform2D Camera2D::get_camera_transform() {
}
if (v_drag_enabled && !Engine::get_singleton()->is_editor_hint() && !v_offset_changed) {
-
camera_pos.y = MIN(camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * zoom.y * drag_margin[MARGIN_TOP]));
camera_pos.y = MAX(camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * zoom.y * drag_margin[MARGIN_BOTTOM]));
} else {
-
if (v_ofs < 0) {
camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs;
} else {
@@ -137,7 +129,6 @@ Transform2D Camera2D::get_camera_transform() {
}
} else if (anchor_mode == ANCHOR_MODE_FIXED_TOP_LEFT) {
-
camera_pos = new_camera_pos;
}
@@ -145,27 +136,29 @@ Transform2D Camera2D::get_camera_transform() {
Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom);
if (limit_smoothing_enabled) {
- if (screen_rect.position.x < limit[MARGIN_LEFT])
+ if (screen_rect.position.x < limit[MARGIN_LEFT]) {
camera_pos.x -= screen_rect.position.x - limit[MARGIN_LEFT];
+ }
- if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT])
+ if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT]) {
camera_pos.x -= screen_rect.position.x + screen_rect.size.x - limit[MARGIN_RIGHT];
+ }
- if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM])
+ if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM]) {
camera_pos.y -= screen_rect.position.y + screen_rect.size.y - limit[MARGIN_BOTTOM];
+ }
- if (screen_rect.position.y < limit[MARGIN_TOP])
+ if (screen_rect.position.y < limit[MARGIN_TOP]) {
camera_pos.y -= screen_rect.position.y - limit[MARGIN_TOP];
+ }
}
if (smoothing_enabled && !Engine::get_singleton()->is_editor_hint()) {
-
float c = smoothing * (process_mode == CAMERA2D_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
smoothed_camera_pos = ((camera_pos - smoothed_camera_pos) * c) + smoothed_camera_pos;
ret_camera_pos = smoothed_camera_pos;
//camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing;
} else {
-
ret_camera_pos = smoothed_camera_pos = camera_pos;
}
@@ -182,20 +175,25 @@ Transform2D Camera2D::get_camera_transform() {
}
Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom);
- if (screen_rect.position.x < limit[MARGIN_LEFT])
+ if (screen_rect.position.x < limit[MARGIN_LEFT]) {
screen_rect.position.x = limit[MARGIN_LEFT];
+ }
- if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT])
+ if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT]) {
screen_rect.position.x = limit[MARGIN_RIGHT] - screen_rect.size.x;
+ }
- if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM])
+ if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM]) {
screen_rect.position.y = limit[MARGIN_BOTTOM] - screen_rect.size.y;
+ }
- if (screen_rect.position.y < limit[MARGIN_TOP])
+ if (screen_rect.position.y < limit[MARGIN_TOP]) {
screen_rect.position.y = limit[MARGIN_TOP];
+ }
- if (offset != Vector2())
+ if (offset != Vector2()) {
screen_rect.position += offset;
+ }
camera_screen_center = screen_rect.position + screen_rect.size * 0.5;
@@ -218,23 +216,19 @@ Transform2D Camera2D::get_camera_transform() {
}
void Camera2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_INTERNAL_PROCESS:
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
-
_update_scroll();
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
- if (!is_processing_internal() && !is_physics_processing_internal())
+ if (!is_processing_internal() && !is_physics_processing_internal()) {
_update_scroll();
+ }
} break;
case NOTIFICATION_ENTER_TREE: {
-
if (custom_viewport && ObjectDB::get_instance(custom_viewport_id)) {
viewport = custom_viewport;
} else {
@@ -256,7 +250,6 @@ void Camera2D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
-
if (is_current()) {
if (viewport && !(custom_viewport && !ObjectDB::get_instance(custom_viewport_id))) {
viewport->set_canvas_transform(Transform2D());
@@ -268,9 +261,9 @@ void Camera2D::_notification(int p_what) {
} break;
case NOTIFICATION_DRAW: {
-
- if (!is_inside_tree() || !Engine::get_singleton()->is_editor_hint())
+ if (!is_inside_tree() || !Engine::get_singleton()->is_editor_hint()) {
break;
+ }
if (screen_drawing_enabled) {
Color area_axis_color(0.5, 0.42, 0.87, 0.63);
@@ -349,56 +342,47 @@ void Camera2D::_notification(int p_what) {
}
void Camera2D::set_offset(const Vector2 &p_offset) {
-
offset = p_offset;
_update_scroll();
}
Vector2 Camera2D::get_offset() const {
-
return offset;
}
void Camera2D::set_anchor_mode(AnchorMode p_anchor_mode) {
-
anchor_mode = p_anchor_mode;
_update_scroll();
}
Camera2D::AnchorMode Camera2D::get_anchor_mode() const {
-
return anchor_mode;
}
void Camera2D::set_rotating(bool p_rotating) {
-
rotating = p_rotating;
_update_scroll();
}
bool Camera2D::is_rotating() const {
-
return rotating;
}
void Camera2D::set_process_mode(Camera2DProcessMode p_mode) {
-
- if (process_mode == p_mode)
+ if (process_mode == p_mode) {
return;
+ }
process_mode = p_mode;
_update_process_mode();
}
Camera2D::Camera2DProcessMode Camera2D::get_process_mode() const {
-
return process_mode;
}
void Camera2D::_make_current(Object *p_which) {
-
if (p_which == this) {
-
current = true;
} else {
current = false;
@@ -406,21 +390,19 @@ void Camera2D::_make_current(Object *p_which) {
}
void Camera2D::_set_current(bool p_current) {
-
- if (p_current)
+ if (p_current) {
make_current();
+ }
current = p_current;
update();
}
bool Camera2D::is_current() const {
-
return current;
}
void Camera2D::make_current() {
-
if (!is_inside_tree()) {
current = true;
} else {
@@ -430,7 +412,6 @@ void Camera2D::make_current() {
}
void Camera2D::clear_current() {
-
current = false;
if (is_inside_tree()) {
get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, group_name, "_make_current", (Object *)nullptr);
@@ -438,60 +419,50 @@ void Camera2D::clear_current() {
}
void Camera2D::set_limit(Margin p_margin, int p_limit) {
-
ERR_FAIL_INDEX((int)p_margin, 4);
limit[p_margin] = p_limit;
update();
}
int Camera2D::get_limit(Margin p_margin) const {
-
ERR_FAIL_INDEX_V((int)p_margin, 4, 0);
return limit[p_margin];
}
void Camera2D::set_limit_smoothing_enabled(bool enable) {
-
limit_smoothing_enabled = enable;
_update_scroll();
}
bool Camera2D::is_limit_smoothing_enabled() const {
-
return limit_smoothing_enabled;
}
void Camera2D::set_drag_margin(Margin p_margin, float p_drag_margin) {
-
ERR_FAIL_INDEX((int)p_margin, 4);
drag_margin[p_margin] = p_drag_margin;
update();
}
float Camera2D::get_drag_margin(Margin p_margin) const {
-
ERR_FAIL_INDEX_V((int)p_margin, 4, 0);
return drag_margin[p_margin];
}
Vector2 Camera2D::get_camera_position() const {
-
return camera_pos;
}
void Camera2D::force_update_scroll() {
-
_update_scroll();
}
void Camera2D::reset_smoothing() {
-
smoothed_camera_pos = camera_pos;
_update_scroll();
}
void Camera2D::align() {
-
ERR_FAIL_COND(custom_viewport && !ObjectDB::get_instance(custom_viewport_id));
Size2 screen_size = viewport->get_visible_rect().size;
@@ -509,7 +480,6 @@ void Camera2D::align() {
camera_pos.y = current_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs;
}
} else if (anchor_mode == ANCHOR_MODE_FIXED_TOP_LEFT) {
-
camera_pos = current_camera_pos;
}
@@ -517,64 +487,55 @@ void Camera2D::align() {
}
void Camera2D::set_follow_smoothing(float p_speed) {
-
smoothing = p_speed;
- if (smoothing > 0 && !(is_inside_tree() && Engine::get_singleton()->is_editor_hint()))
+ if (smoothing > 0 && !(is_inside_tree() && Engine::get_singleton()->is_editor_hint())) {
set_process_internal(true);
- else
+ } else {
set_process_internal(false);
+ }
}
float Camera2D::get_follow_smoothing() const {
-
return smoothing;
}
Point2 Camera2D::get_camera_screen_center() const {
-
return camera_screen_center;
}
void Camera2D::set_h_drag_enabled(bool p_enabled) {
-
h_drag_enabled = p_enabled;
}
bool Camera2D::is_h_drag_enabled() const {
-
return h_drag_enabled;
}
void Camera2D::set_v_drag_enabled(bool p_enabled) {
-
v_drag_enabled = p_enabled;
}
bool Camera2D::is_v_drag_enabled() const {
-
return v_drag_enabled;
}
void Camera2D::set_v_offset(float p_offset) {
-
v_ofs = p_offset;
v_offset_changed = true;
_update_scroll();
}
float Camera2D::get_v_offset() const {
-
return v_ofs;
}
void Camera2D::set_h_offset(float p_offset) {
-
h_ofs = p_offset;
h_offset_changed = true;
_update_scroll();
}
-float Camera2D::get_h_offset() const {
+float Camera2D::get_h_offset() const {
return h_ofs;
}
@@ -587,12 +548,10 @@ void Camera2D::_set_old_smoothing(float p_enable) {
}
void Camera2D::set_enable_follow_smoothing(bool p_enabled) {
-
smoothing_enabled = p_enabled;
}
bool Camera2D::is_follow_smoothing_enabled() const {
-
return smoothing_enabled;
}
@@ -612,11 +571,11 @@ void Camera2D::set_custom_viewport(Node *p_viewport) {
}
if (is_inside_tree()) {
-
- if (custom_viewport)
+ if (custom_viewport) {
viewport = custom_viewport;
- else
+ } else {
viewport = get_viewport();
+ }
RID vp = viewport->get_viewport_rid();
group_name = "__cameras_" + itos(vp.get_id());
@@ -627,7 +586,6 @@ void Camera2D::set_custom_viewport(Node *p_viewport) {
}
Node *Camera2D::get_custom_viewport() const {
-
return custom_viewport;
}
@@ -659,7 +617,6 @@ bool Camera2D::is_margin_drawing_enabled() const {
}
void Camera2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &Camera2D::set_offset);
ClassDB::bind_method(D_METHOD("get_offset"), &Camera2D::get_offset);
@@ -777,7 +734,6 @@ void Camera2D::_bind_methods() {
}
Camera2D::Camera2D() {
-
anchor_mode = ANCHOR_MODE_DRAG_CENTER;
rotating = false;
current = false;
diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h
index 7a106ef79a..0a4e269c40 100644
--- a/scene/2d/camera_2d.h
+++ b/scene/2d/camera_2d.h
@@ -35,7 +35,6 @@
#include "scene/main/window.h"
class Camera2D : public Node2D {
-
GDCLASS(Camera2D, Node2D);
public:
diff --git a/scene/2d/canvas_modulate.cpp b/scene/2d/canvas_modulate.cpp
index 05f8804e2a..56643542a8 100644
--- a/scene/2d/canvas_modulate.cpp
+++ b/scene/2d/canvas_modulate.cpp
@@ -31,22 +31,18 @@
#include "canvas_modulate.h"
void CanvasModulate::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_CANVAS) {
-
if (is_visible_in_tree()) {
RS::get_singleton()->canvas_set_modulate(get_canvas(), color);
add_to_group("_canvas_modulate_" + itos(get_canvas().get_id()));
}
} else if (p_what == NOTIFICATION_EXIT_CANVAS) {
-
if (is_visible_in_tree()) {
RS::get_singleton()->canvas_set_modulate(get_canvas(), Color(1, 1, 1, 1));
remove_from_group("_canvas_modulate_" + itos(get_canvas().get_id()));
}
} else if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
if (is_visible_in_tree()) {
RS::get_singleton()->canvas_set_modulate(get_canvas(), color);
add_to_group("_canvas_modulate_" + itos(get_canvas().get_id()));
@@ -60,7 +56,6 @@ void CanvasModulate::_notification(int p_what) {
}
void CanvasModulate::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_color", "color"), &CanvasModulate::set_color);
ClassDB::bind_method(D_METHOD("get_color"), &CanvasModulate::get_color);
@@ -68,21 +63,20 @@ void CanvasModulate::_bind_methods() {
}
void CanvasModulate::set_color(const Color &p_color) {
-
color = p_color;
if (is_visible_in_tree()) {
RS::get_singleton()->canvas_set_modulate(get_canvas(), color);
}
}
-Color CanvasModulate::get_color() const {
+Color CanvasModulate::get_color() const {
return color;
}
String CanvasModulate::get_configuration_warning() const {
-
- if (!is_visible_in_tree() || !is_inside_tree())
+ if (!is_visible_in_tree() || !is_inside_tree()) {
return String();
+ }
List<Node *> nodes;
get_tree()->get_nodes_in_group("_canvas_modulate_" + itos(get_canvas().get_id()), &nodes);
diff --git a/scene/2d/canvas_modulate.h b/scene/2d/canvas_modulate.h
index ada6e27760..a0b61f43ba 100644
--- a/scene/2d/canvas_modulate.h
+++ b/scene/2d/canvas_modulate.h
@@ -34,7 +34,6 @@
#include "scene/2d/node_2d.h"
class CanvasModulate : public Node2D {
-
GDCLASS(CanvasModulate, Node2D);
Color color;
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index d82f4a2f2b..fe16d4089a 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -34,23 +34,22 @@
#include "servers/physics_server_2d.h"
void CollisionObject2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
Transform2D global_transform = get_global_transform();
- if (area)
+ if (area) {
PhysicsServer2D::get_singleton()->area_set_transform(rid, global_transform);
- else
+ } else {
PhysicsServer2D::get_singleton()->body_set_state(rid, PhysicsServer2D::BODY_STATE_TRANSFORM, global_transform);
+ }
RID space = get_world_2d()->get_space();
if (area) {
PhysicsServer2D::get_singleton()->area_set_space(rid, space);
- } else
+ } else {
PhysicsServer2D::get_singleton()->body_set_space(rid, space);
+ }
_update_pickable();
@@ -58,52 +57,50 @@ void CollisionObject2D::_notification(int p_what) {
} break;
case NOTIFICATION_ENTER_CANVAS: {
-
- if (area)
+ if (area) {
PhysicsServer2D::get_singleton()->area_attach_canvas_instance_id(rid, get_canvas_layer_instance_id());
- else
+ } else {
PhysicsServer2D::get_singleton()->body_attach_canvas_instance_id(rid, get_canvas_layer_instance_id());
+ }
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
_update_pickable();
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
if (only_update_transform_changes) {
return;
}
Transform2D global_transform = get_global_transform();
- if (area)
+ if (area) {
PhysicsServer2D::get_singleton()->area_set_transform(rid, global_transform);
- else
+ } else {
PhysicsServer2D::get_singleton()->body_set_state(rid, PhysicsServer2D::BODY_STATE_TRANSFORM, global_transform);
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
-
if (area) {
PhysicsServer2D::get_singleton()->area_set_space(rid, RID());
- } else
+ } else {
PhysicsServer2D::get_singleton()->body_set_space(rid, RID());
+ }
} break;
case NOTIFICATION_EXIT_CANVAS: {
-
- if (area)
+ if (area) {
PhysicsServer2D::get_singleton()->area_attach_canvas_instance_id(rid, ObjectID());
- else
+ } else {
PhysicsServer2D::get_singleton()->body_attach_canvas_instance_id(rid, ObjectID());
+ }
} break;
}
}
uint32_t CollisionObject2D::create_shape_owner(Object *p_owner) {
-
ShapeData sd;
uint32_t id;
@@ -121,7 +118,6 @@ uint32_t CollisionObject2D::create_shape_owner(Object *p_owner) {
}
void CollisionObject2D::remove_shape_owner(uint32_t owner) {
-
ERR_FAIL_COND(!shapes.has(owner));
shape_owner_clear_shapes(owner);
@@ -144,16 +140,15 @@ void CollisionObject2D::shape_owner_set_disabled(uint32_t p_owner, bool p_disabl
}
bool CollisionObject2D::is_shape_owner_disabled(uint32_t p_owner) const {
-
ERR_FAIL_COND_V(!shapes.has(p_owner), false);
return shapes[p_owner].disabled;
}
void CollisionObject2D::shape_owner_set_one_way_collision(uint32_t p_owner, bool p_enable) {
-
- if (area)
+ if (area) {
return; //not for areas
+ }
ERR_FAIL_COND(!shapes.has(p_owner));
@@ -165,16 +160,15 @@ void CollisionObject2D::shape_owner_set_one_way_collision(uint32_t p_owner, bool
}
bool CollisionObject2D::is_shape_owner_one_way_collision_enabled(uint32_t p_owner) const {
-
ERR_FAIL_COND_V(!shapes.has(p_owner), false);
return shapes[p_owner].one_way_collision;
}
void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owner, float p_margin) {
-
- if (area)
+ if (area) {
return; //not for areas
+ }
ERR_FAIL_COND(!shapes.has(p_owner));
@@ -186,21 +180,18 @@ void CollisionObject2D::shape_owner_set_one_way_collision_margin(uint32_t p_owne
}
float CollisionObject2D::get_shape_owner_one_way_collision_margin(uint32_t p_owner) const {
-
ERR_FAIL_COND_V(!shapes.has(p_owner), 0);
return shapes[p_owner].one_way_collision_margin;
}
void CollisionObject2D::get_shape_owners(List<uint32_t> *r_owners) {
-
for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
r_owners->push_back(E->key());
}
}
Array CollisionObject2D::_get_shape_owners() {
-
Array ret;
for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
ret.push_back(E->key());
@@ -210,7 +201,6 @@ Array CollisionObject2D::_get_shape_owners() {
}
void CollisionObject2D::shape_owner_set_transform(uint32_t p_owner, const Transform2D &p_transform) {
-
ERR_FAIL_COND(!shapes.has(p_owner));
ShapeData &sd = shapes[p_owner];
@@ -224,22 +214,20 @@ void CollisionObject2D::shape_owner_set_transform(uint32_t p_owner, const Transf
}
}
}
-Transform2D CollisionObject2D::shape_owner_get_transform(uint32_t p_owner) const {
+Transform2D CollisionObject2D::shape_owner_get_transform(uint32_t p_owner) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), Transform2D());
return shapes[p_owner].xform;
}
Object *CollisionObject2D::shape_owner_get_owner(uint32_t p_owner) const {
-
ERR_FAIL_COND_V(!shapes.has(p_owner), nullptr);
return shapes[p_owner].owner;
}
void CollisionObject2D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2D> &p_shape) {
-
ERR_FAIL_COND(!shapes.has(p_owner));
ERR_FAIL_COND(p_shape.is_null());
@@ -256,21 +244,21 @@ void CollisionObject2D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape2
total_subshapes++;
}
-int CollisionObject2D::shape_owner_get_shape_count(uint32_t p_owner) const {
+int CollisionObject2D::shape_owner_get_shape_count(uint32_t p_owner) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), 0);
return shapes[p_owner].shapes.size();
}
-Ref<Shape2D> CollisionObject2D::shape_owner_get_shape(uint32_t p_owner, int p_shape) const {
+Ref<Shape2D> CollisionObject2D::shape_owner_get_shape(uint32_t p_owner, int p_shape) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), Ref<Shape2D>());
ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), Ref<Shape2D>());
return shapes[p_owner].shapes[p_shape].shape;
}
-int CollisionObject2D::shape_owner_get_shape_index(uint32_t p_owner, int p_shape) const {
+int CollisionObject2D::shape_owner_get_shape_index(uint32_t p_owner, int p_shape) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), -1);
ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), -1);
@@ -278,7 +266,6 @@ int CollisionObject2D::shape_owner_get_shape_index(uint32_t p_owner, int p_shape
}
void CollisionObject2D::shape_owner_remove_shape(uint32_t p_owner, int p_shape) {
-
ERR_FAIL_COND(!shapes.has(p_owner));
ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size());
@@ -303,7 +290,6 @@ void CollisionObject2D::shape_owner_remove_shape(uint32_t p_owner, int p_shape)
}
void CollisionObject2D::shape_owner_clear_shapes(uint32_t p_owner) {
-
ERR_FAIL_COND(!shapes.has(p_owner));
while (shape_owner_get_shape_count(p_owner) > 0) {
@@ -312,7 +298,6 @@ void CollisionObject2D::shape_owner_clear_shapes(uint32_t p_owner) {
}
uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const {
-
ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0);
for (const Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
@@ -328,21 +313,19 @@ uint32_t CollisionObject2D::shape_find_owner(int p_shape_index) const {
}
void CollisionObject2D::set_pickable(bool p_enabled) {
-
- if (pickable == p_enabled)
+ if (pickable == p_enabled) {
return;
+ }
pickable = p_enabled;
_update_pickable();
}
bool CollisionObject2D::is_pickable() const {
-
return pickable;
}
void CollisionObject2D::_input_event(Node *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape) {
-
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_input_event, p_viewport, p_input_event, p_shape);
}
@@ -350,7 +333,6 @@ void CollisionObject2D::_input_event(Node *p_viewport, const Ref<InputEvent> &p_
}
void CollisionObject2D::_mouse_enter() {
-
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_mouse_enter);
}
@@ -358,7 +340,6 @@ void CollisionObject2D::_mouse_enter() {
}
void CollisionObject2D::_mouse_exit() {
-
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_mouse_exit);
}
@@ -370,18 +351,19 @@ void CollisionObject2D::set_only_update_transform_changes(bool p_enable) {
}
void CollisionObject2D::_update_pickable() {
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
bool is_pickable = pickable && is_visible_in_tree();
- if (area)
+ if (area) {
PhysicsServer2D::get_singleton()->area_set_pickable(rid, is_pickable);
- else
+ } else {
PhysicsServer2D::get_singleton()->body_set_pickable(rid, is_pickable);
+ }
}
String CollisionObject2D::get_configuration_warning() const {
-
String warning = Node2D::get_configuration_warning();
if (shapes.empty()) {
@@ -395,7 +377,6 @@ String CollisionObject2D::get_configuration_warning() const {
}
void CollisionObject2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_rid"), &CollisionObject2D::get_rid);
ClassDB::bind_method(D_METHOD("set_pickable", "enabled"), &CollisionObject2D::set_pickable);
@@ -432,7 +413,6 @@ void CollisionObject2D::_bind_methods() {
}
CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) {
-
rid = p_rid;
area = p_area;
pickable = true;
@@ -441,7 +421,6 @@ CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) {
only_update_transform_changes = false;
if (p_area) {
-
PhysicsServer2D::get_singleton()->area_attach_object_instance_id(rid, get_instance_id());
} else {
PhysicsServer2D::get_singleton()->body_attach_object_instance_id(rid, get_instance_id());
@@ -449,13 +428,11 @@ CollisionObject2D::CollisionObject2D(RID p_rid, bool p_area) {
}
CollisionObject2D::CollisionObject2D() {
-
//owner=
set_notify_transform(true);
}
CollisionObject2D::~CollisionObject2D() {
-
PhysicsServer2D::get_singleton()->free(rid);
}
diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h
index e931f20f40..d7af2f3a2a 100644
--- a/scene/2d/collision_object_2d.h
+++ b/scene/2d/collision_object_2d.h
@@ -35,7 +35,6 @@
#include "scene/resources/shape_2d.h"
class CollisionObject2D : public Node2D {
-
GDCLASS(CollisionObject2D, Node2D);
bool area;
@@ -43,7 +42,6 @@ class CollisionObject2D : public Node2D {
bool pickable;
struct ShapeData {
-
Object *owner;
Transform2D xform;
struct Shape {
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index 1e48b2d67f..4919ef8304 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -38,16 +38,15 @@
#include "thirdparty/misc/triangulator.h"
void CollisionPolygon2D::_build_polygon() {
-
parent->shape_owner_clear_shapes(owner_id);
- if (polygon.size() == 0)
+ if (polygon.size() == 0) {
return;
+ }
bool solids = build_mode == BUILD_SOLIDS;
if (solids) {
-
//here comes the sun, lalalala
//decompose concave into multiple convex polygons and add them
Vector<Vector<Vector2>> decomp = _decompose_in_convex();
@@ -58,7 +57,6 @@ void CollisionPolygon2D::_build_polygon() {
}
} else {
-
Ref<ConcavePolygonShape2D> concave = memnew(ConcavePolygonShape2D);
Vector<Vector2> segments;
@@ -82,20 +80,18 @@ Vector<Vector<Vector2>> CollisionPolygon2D::_decompose_in_convex() {
}
void CollisionPolygon2D::_update_in_shape_owner(bool p_xform_only) {
-
parent->shape_owner_set_transform(owner_id, get_transform());
- if (p_xform_only)
+ if (p_xform_only) {
return;
+ }
parent->shape_owner_set_disabled(owner_id, disabled);
parent->shape_owner_set_one_way_collision(owner_id, one_way_collision);
parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin);
}
void CollisionPolygon2D::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_PARENTED: {
-
parent = Object::cast_to<CollisionObject2D>(get_parent());
if (parent) {
owner_id = parent->create_shape_owner(this);
@@ -111,14 +107,12 @@ void CollisionPolygon2D::_notification(int p_what) {
} break;
case NOTIFICATION_ENTER_TREE: {
-
if (parent) {
_update_in_shape_owner();
}
} break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
-
if (parent) {
_update_in_shape_owner(true);
}
@@ -133,13 +127,11 @@ void CollisionPolygon2D::_notification(int p_what) {
} break;
case NOTIFICATION_DRAW: {
-
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) {
break;
}
for (int i = 0; i < polygon.size(); i++) {
-
Vector2 p = polygon[i];
Vector2 n = polygon[(i + 1) % polygon.size()];
// draw line with width <= 1, so it does not scale with zoom and break pixel exact editing
@@ -152,7 +144,6 @@ void CollisionPolygon2D::_notification(int p_what) {
Color c(0.4, 0.9, 0.1);
for (int i = 0; i < decomp.size(); i++) {
-
c.set_hsv(Math::fmod(c.get_h() + 0.738, 1), c.get_s(), c.get_v(), 0.5);
draw_colored_polygon(decomp[i], c);
}
@@ -171,8 +162,9 @@ void CollisionPolygon2D::_notification(int p_what) {
pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0)));
pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0)));
Vector<Color> cols;
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++) {
cols.push_back(dcol);
+ }
draw_primitive(pts, cols, Vector<Vector2>()); //small arrow
}
@@ -181,18 +173,17 @@ void CollisionPolygon2D::_notification(int p_what) {
}
void CollisionPolygon2D::set_polygon(const Vector<Point2> &p_polygon) {
-
polygon = p_polygon;
{
for (int i = 0; i < polygon.size(); i++) {
- if (i == 0)
+ if (i == 0) {
aabb = Rect2(polygon[i], Size2());
- else
+ } else {
aabb.expand_to(polygon[i]);
+ }
}
if (aabb == Rect2()) {
-
aabb = Rect2(-10, -10, 20, 20);
} else {
aabb.position -= aabb.size * 0.3;
@@ -208,12 +199,10 @@ void CollisionPolygon2D::set_polygon(const Vector<Point2> &p_polygon) {
}
Vector<Point2> CollisionPolygon2D::get_polygon() const {
-
return polygon;
}
void CollisionPolygon2D::set_build_mode(BuildMode p_mode) {
-
ERR_FAIL_INDEX((int)p_mode, 2);
build_mode = p_mode;
if (parent) {
@@ -222,13 +211,11 @@ void CollisionPolygon2D::set_build_mode(BuildMode p_mode) {
}
CollisionPolygon2D::BuildMode CollisionPolygon2D::get_build_mode() const {
-
return build_mode;
}
#ifdef TOOLS_ENABLED
Rect2 CollisionPolygon2D::_edit_get_rect() const {
-
return aabb;
}
@@ -237,13 +224,11 @@ bool CollisionPolygon2D::_edit_use_rect() const {
}
bool CollisionPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
return Geometry::is_point_in_polygon(p_point, Variant(polygon));
}
#endif
String CollisionPolygon2D::get_configuration_warning() const {
-
if (!Object::cast_to<CollisionObject2D>(get_parent())) {
return TTR("CollisionPolygon2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape.");
}
@@ -276,7 +261,6 @@ void CollisionPolygon2D::set_one_way_collision(bool p_enable) {
}
bool CollisionPolygon2D::is_one_way_collision_enabled() const {
-
return one_way_collision;
}
@@ -290,8 +274,8 @@ void CollisionPolygon2D::set_one_way_collision_margin(float p_margin) {
float CollisionPolygon2D::get_one_way_collision_margin() const {
return one_way_collision_margin;
}
-void CollisionPolygon2D::_bind_methods() {
+void CollisionPolygon2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &CollisionPolygon2D::set_polygon);
ClassDB::bind_method(D_METHOD("get_polygon"), &CollisionPolygon2D::get_polygon);
@@ -315,7 +299,6 @@ void CollisionPolygon2D::_bind_methods() {
}
CollisionPolygon2D::CollisionPolygon2D() {
-
aabb = Rect2(-10, -10, 20, 20);
build_mode = BUILD_SOLIDS;
set_notify_local_transform(true);
diff --git a/scene/2d/collision_polygon_2d.h b/scene/2d/collision_polygon_2d.h
index 92a2758813..bf3e560a93 100644
--- a/scene/2d/collision_polygon_2d.h
+++ b/scene/2d/collision_polygon_2d.h
@@ -37,7 +37,6 @@
class CollisionObject2D;
class CollisionPolygon2D : public Node2D {
-
GDCLASS(CollisionPolygon2D, Node2D);
public:
diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp
index b1dbc57c94..88d124536c 100644
--- a/scene/2d/collision_shape_2d.cpp
+++ b/scene/2d/collision_shape_2d.cpp
@@ -41,26 +41,22 @@
#include "scene/resources/segment_shape_2d.h"
void CollisionShape2D::_shape_changed() {
-
update();
}
void CollisionShape2D::_update_in_shape_owner(bool p_xform_only) {
-
parent->shape_owner_set_transform(owner_id, get_transform());
- if (p_xform_only)
+ if (p_xform_only) {
return;
+ }
parent->shape_owner_set_disabled(owner_id, disabled);
parent->shape_owner_set_one_way_collision(owner_id, one_way_collision);
parent->shape_owner_set_one_way_collision_margin(owner_id, one_way_collision_margin);
}
void CollisionShape2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_PARENTED: {
-
parent = Object::cast_to<CollisionObject2D>(get_parent());
if (parent) {
owner_id = parent->create_shape_owner(this);
@@ -78,14 +74,12 @@ void CollisionShape2D::_notification(int p_what) {
} break;
case NOTIFICATION_ENTER_TREE: {
-
if (parent) {
_update_in_shape_owner();
}
} break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
-
if (parent) {
_update_in_shape_owner(true);
}
@@ -100,7 +94,6 @@ void CollisionShape2D::_notification(int p_what) {
} break;
case NOTIFICATION_DRAW: {
-
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) {
break;
}
@@ -137,8 +130,9 @@ void CollisionShape2D::_notification(int p_what) {
pts.push_back(line_to + (Vector2(Math_SQRT12 * tsize, 0)));
pts.push_back(line_to + (Vector2(-Math_SQRT12 * tsize, 0)));
Vector<Color> cols;
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++) {
cols.push_back(draw_col);
+ }
draw_primitive(pts, cols, Vector<Vector2>());
}
@@ -147,9 +141,9 @@ void CollisionShape2D::_notification(int p_what) {
}
void CollisionShape2D::set_shape(const Ref<Shape2D> &p_shape) {
-
- if (shape.is_valid())
+ if (shape.is_valid()) {
shape->disconnect("changed", callable_mp(this, &CollisionShape2D::_shape_changed));
+ }
shape = p_shape;
update();
if (parent) {
@@ -159,27 +153,26 @@ void CollisionShape2D::set_shape(const Ref<Shape2D> &p_shape) {
}
}
- if (shape.is_valid())
+ if (shape.is_valid()) {
shape->connect("changed", callable_mp(this, &CollisionShape2D::_shape_changed));
+ }
update_configuration_warning();
}
Ref<Shape2D> CollisionShape2D::get_shape() const {
-
return shape;
}
bool CollisionShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
- if (!shape.is_valid())
+ if (!shape.is_valid()) {
return false;
+ }
return shape->_edit_is_selected_on_click(p_point, p_tolerance);
}
String CollisionShape2D::get_configuration_warning() const {
-
if (!Object::cast_to<CollisionObject2D>(get_parent())) {
return TTR("CollisionShape2D only serves to provide a collision shape to a CollisionObject2D derived node. Please only use it as a child of Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape.");
}
@@ -212,7 +205,6 @@ void CollisionShape2D::set_one_way_collision(bool p_enable) {
}
bool CollisionShape2D::is_one_way_collision_enabled() const {
-
return one_way_collision;
}
@@ -228,7 +220,6 @@ float CollisionShape2D::get_one_way_collision_margin() const {
}
void CollisionShape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_shape", "shape"), &CollisionShape2D::set_shape);
ClassDB::bind_method(D_METHOD("get_shape"), &CollisionShape2D::get_shape);
ClassDB::bind_method(D_METHOD("set_disabled", "disabled"), &CollisionShape2D::set_disabled);
@@ -245,7 +236,6 @@ void CollisionShape2D::_bind_methods() {
}
CollisionShape2D::CollisionShape2D() {
-
rect = Rect2(-Point2(10, 10), Point2(20, 20));
set_notify_local_transform(true);
owner_id = 0;
diff --git a/scene/2d/collision_shape_2d.h b/scene/2d/collision_shape_2d.h
index 80bea0a979..ec7808ee7c 100644
--- a/scene/2d/collision_shape_2d.h
+++ b/scene/2d/collision_shape_2d.h
@@ -37,7 +37,6 @@
class CollisionObject2D;
class CollisionShape2D : public Node2D {
-
GDCLASS(CollisionShape2D, Node2D);
Ref<Shape2D> shape;
Rect2 rect;
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 0a6b091a51..526951976e 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -37,17 +37,17 @@
#include "servers/rendering_server.h"
void CPUParticles2D::set_emitting(bool p_emitting) {
-
- if (emitting == p_emitting)
+ if (emitting == p_emitting) {
return;
+ }
emitting = p_emitting;
- if (emitting)
+ if (emitting) {
set_process_internal(true);
+ }
}
void CPUParticles2D::set_amount(int p_amount) {
-
ERR_FAIL_COND_MSG(p_amount < 1, "Amount of particles must be greater than 0.");
particles.resize(p_amount);
@@ -64,100 +64,90 @@ void CPUParticles2D::set_amount(int p_amount) {
particle_order.resize(p_amount);
}
-void CPUParticles2D::set_lifetime(float p_lifetime) {
+void CPUParticles2D::set_lifetime(float p_lifetime) {
ERR_FAIL_COND_MSG(p_lifetime <= 0, "Particles lifetime must be greater than 0.");
lifetime = p_lifetime;
}
void CPUParticles2D::set_one_shot(bool p_one_shot) {
-
one_shot = p_one_shot;
}
void CPUParticles2D::set_pre_process_time(float p_time) {
-
pre_process_time = p_time;
}
-void CPUParticles2D::set_explosiveness_ratio(float p_ratio) {
+void CPUParticles2D::set_explosiveness_ratio(float p_ratio) {
explosiveness_ratio = p_ratio;
}
-void CPUParticles2D::set_randomness_ratio(float p_ratio) {
+void CPUParticles2D::set_randomness_ratio(float p_ratio) {
randomness_ratio = p_ratio;
}
-void CPUParticles2D::set_lifetime_randomness(float p_random) {
+void CPUParticles2D::set_lifetime_randomness(float p_random) {
lifetime_randomness = p_random;
}
-void CPUParticles2D::set_use_local_coordinates(bool p_enable) {
+void CPUParticles2D::set_use_local_coordinates(bool p_enable) {
local_coords = p_enable;
set_notify_transform(!p_enable);
}
void CPUParticles2D::set_speed_scale(float p_scale) {
-
speed_scale = p_scale;
}
bool CPUParticles2D::is_emitting() const {
-
return emitting;
}
-int CPUParticles2D::get_amount() const {
+int CPUParticles2D::get_amount() const {
return particles.size();
}
-float CPUParticles2D::get_lifetime() const {
+float CPUParticles2D::get_lifetime() const {
return lifetime;
}
-bool CPUParticles2D::get_one_shot() const {
+bool CPUParticles2D::get_one_shot() const {
return one_shot;
}
float CPUParticles2D::get_pre_process_time() const {
-
return pre_process_time;
}
-float CPUParticles2D::get_explosiveness_ratio() const {
+float CPUParticles2D::get_explosiveness_ratio() const {
return explosiveness_ratio;
}
-float CPUParticles2D::get_randomness_ratio() const {
+float CPUParticles2D::get_randomness_ratio() const {
return randomness_ratio;
}
-float CPUParticles2D::get_lifetime_randomness() const {
+float CPUParticles2D::get_lifetime_randomness() const {
return lifetime_randomness;
}
bool CPUParticles2D::get_use_local_coordinates() const {
-
return local_coords;
}
float CPUParticles2D::get_speed_scale() const {
-
return speed_scale;
}
void CPUParticles2D::set_draw_order(DrawOrder p_order) {
-
draw_order = p_order;
}
CPUParticles2D::DrawOrder CPUParticles2D::get_draw_order() const {
-
return draw_order;
}
void CPUParticles2D::_update_mesh_texture() {
-
Size2 tex_size;
if (texture.is_valid()) {
tex_size = texture->get_size();
@@ -209,23 +199,25 @@ void CPUParticles2D::_update_mesh_texture() {
}
void CPUParticles2D::set_texture(const Ref<Texture2D> &p_texture) {
- if (p_texture == texture)
+ if (p_texture == texture) {
return;
+ }
- if (texture.is_valid())
+ if (texture.is_valid()) {
texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CPUParticles2D::_texture_changed));
+ }
texture = p_texture;
- if (texture.is_valid())
+ if (texture.is_valid()) {
texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &CPUParticles2D::_texture_changed));
+ }
update();
_update_mesh_texture();
}
void CPUParticles2D::_texture_changed() {
-
if (texture.is_valid()) {
update();
_update_mesh_texture();
@@ -233,18 +225,15 @@ void CPUParticles2D::_texture_changed() {
}
Ref<Texture2D> CPUParticles2D::get_texture() const {
-
return texture;
}
void CPUParticles2D::set_normalmap(const Ref<Texture2D> &p_normalmap) {
-
normalmap = p_normalmap;
update();
}
Ref<Texture2D> CPUParticles2D::get_normalmap() const {
-
return normalmap;
}
@@ -265,7 +254,6 @@ bool CPUParticles2D::get_fractional_delta() const {
}
String CPUParticles2D::get_configuration_warning() const {
-
String warnings;
CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr());
@@ -273,8 +261,9 @@ String CPUParticles2D::get_configuration_warning() const {
if (get_material().is_null() || (mat && !mat->get_particles_animation())) {
if (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 ||
get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid()) {
- if (warnings != String())
+ if (warnings != String()) {
warnings += "\n";
+ }
warnings += "- " + TTR("CPUParticles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled.");
}
}
@@ -283,7 +272,6 @@ String CPUParticles2D::get_configuration_warning() const {
}
void CPUParticles2D::restart() {
-
time = 0;
inactive_time = 0;
frame_remainder = 0;
@@ -303,62 +291,55 @@ void CPUParticles2D::restart() {
}
void CPUParticles2D::set_direction(Vector2 p_direction) {
-
direction = p_direction;
}
Vector2 CPUParticles2D::get_direction() const {
-
return direction;
}
void CPUParticles2D::set_spread(float p_spread) {
-
spread = p_spread;
}
float CPUParticles2D::get_spread() const {
-
return spread;
}
void CPUParticles2D::set_param(Parameter p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
parameters[p_param] = p_value;
}
-float CPUParticles2D::get_param(Parameter p_param) const {
+float CPUParticles2D::get_param(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return parameters[p_param];
}
void CPUParticles2D::set_param_randomness(Parameter p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
randomness[p_param] = p_value;
}
-float CPUParticles2D::get_param_randomness(Parameter p_param) const {
+float CPUParticles2D::get_param_randomness(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return randomness[p_param];
}
static void _adjust_curve_range(const Ref<Curve> &p_curve, float p_min, float p_max) {
-
Ref<Curve> curve = p_curve;
- if (!curve.is_valid())
+ if (!curve.is_valid()) {
return;
+ }
curve->ensure_default_setup(p_min, p_max);
}
void CPUParticles2D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curve) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
curve_parameters[p_param] = p_curve;
@@ -389,7 +370,6 @@ void CPUParticles2D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv
_adjust_curve_range(p_curve, -360, 360);
} break;
case PARAM_SCALE: {
-
} break;
case PARAM_HUE_VARIATION: {
_adjust_curve_range(p_curve, -1, 1);
@@ -403,30 +383,26 @@ void CPUParticles2D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv
}
}
}
-Ref<Curve> CPUParticles2D::get_param_curve(Parameter p_param) const {
+Ref<Curve> CPUParticles2D::get_param_curve(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Curve>());
return curve_parameters[p_param];
}
void CPUParticles2D::set_color(const Color &p_color) {
-
color = p_color;
}
Color CPUParticles2D::get_color() const {
-
return color;
}
void CPUParticles2D::set_color_ramp(const Ref<Gradient> &p_ramp) {
-
color_ramp = p_ramp;
}
Ref<Gradient> CPUParticles2D::get_color_ramp() const {
-
return color_ramp;
}
@@ -447,67 +423,58 @@ void CPUParticles2D::set_emission_shape(EmissionShape p_shape) {
}
void CPUParticles2D::set_emission_sphere_radius(float p_radius) {
-
emission_sphere_radius = p_radius;
}
void CPUParticles2D::set_emission_rect_extents(Vector2 p_extents) {
-
emission_rect_extents = p_extents;
}
void CPUParticles2D::set_emission_points(const Vector<Vector2> &p_points) {
-
emission_points = p_points;
}
void CPUParticles2D::set_emission_normals(const Vector<Vector2> &p_normals) {
-
emission_normals = p_normals;
}
void CPUParticles2D::set_emission_colors(const Vector<Color> &p_colors) {
-
emission_colors = p_colors;
}
float CPUParticles2D::get_emission_sphere_radius() const {
-
return emission_sphere_radius;
}
-Vector2 CPUParticles2D::get_emission_rect_extents() const {
+Vector2 CPUParticles2D::get_emission_rect_extents() const {
return emission_rect_extents;
}
-Vector<Vector2> CPUParticles2D::get_emission_points() const {
+Vector<Vector2> CPUParticles2D::get_emission_points() const {
return emission_points;
}
-Vector<Vector2> CPUParticles2D::get_emission_normals() const {
+Vector<Vector2> CPUParticles2D::get_emission_normals() const {
return emission_normals;
}
Vector<Color> CPUParticles2D::get_emission_colors() const {
-
return emission_colors;
}
CPUParticles2D::EmissionShape CPUParticles2D::get_emission_shape() const {
return emission_shape;
}
-void CPUParticles2D::set_gravity(const Vector2 &p_gravity) {
+void CPUParticles2D::set_gravity(const Vector2 &p_gravity) {
gravity = p_gravity;
}
Vector2 CPUParticles2D::get_gravity() const {
-
return gravity;
}
void CPUParticles2D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "color" && color_ramp.is_valid()) {
property.usage = 0;
}
@@ -538,7 +505,6 @@ void CPUParticles2D::_validate_property(PropertyInfo &property) const {
}
static uint32_t idhash(uint32_t x) {
-
x = ((x >> uint32_t(16)) ^ x) * uint32_t(0x45d9f3b);
x = ((x >> uint32_t(16)) ^ x) * uint32_t(0x45d9f3b);
x = (x >> uint32_t(16)) ^ x;
@@ -548,18 +514,19 @@ static uint32_t idhash(uint32_t x) {
static float rand_from_seed(uint32_t &seed) {
int k;
int s = int(seed);
- if (s == 0)
+ if (s == 0) {
s = 305420679;
+ }
k = s / 127773;
s = 16807 * (s - k * 127773) - 2836 * k;
- if (s < 0)
+ if (s < 0) {
s += 2147483647;
+ }
seed = uint32_t(s);
return float(seed % uint32_t(65536)) / 65535.0;
}
void CPUParticles2D::_update_internal() {
-
if (particles.size() == 0 || !is_visible_in_tree()) {
_set_redraw(false);
return;
@@ -585,12 +552,12 @@ void CPUParticles2D::_update_internal() {
_set_redraw(true);
if (time == 0 && pre_process_time > 0.0) {
-
float frame_time;
- if (fixed_fps > 0)
+ if (fixed_fps > 0) {
frame_time = 1.0 / fixed_fps;
- else
+ } else {
frame_time = 1.0 / 30.0;
+ }
float todo = pre_process_time;
@@ -627,7 +594,6 @@ void CPUParticles2D::_update_internal() {
}
void CPUParticles2D::_particles_process(float p_delta) {
-
p_delta *= speed_scale;
int pcount = particles.size();
@@ -657,11 +623,11 @@ void CPUParticles2D::_particles_process(float p_delta) {
float system_phase = time / lifetime;
for (int i = 0; i < pcount; i++) {
-
Particle &p = parray[i];
- if (!emitting && !p.active)
+ if (!emitting && !p.active) {
continue;
+ }
float local_delta = p_delta;
@@ -715,7 +681,6 @@ void CPUParticles2D::_particles_process(float p_delta) {
}
if (restart) {
-
if (!emitting) {
p.active = false;
continue;
@@ -774,10 +739,10 @@ void CPUParticles2D::_particles_process(float p_delta) {
} break;
case EMISSION_SHAPE_POINTS:
case EMISSION_SHAPE_DIRECTED_POINTS: {
-
int pc = emission_points.size();
- if (pc == 0)
+ if (pc == 0) {
break;
+ }
int random_idx = Math::rand() % pc;
@@ -806,7 +771,6 @@ void CPUParticles2D::_particles_process(float p_delta) {
} else if (p.time > p.lifetime) {
p.active = false;
} else {
-
uint32_t alt_seed = p.seed;
p.time += local_delta;
@@ -890,7 +854,6 @@ void CPUParticles2D::_particles_process(float p_delta) {
}
if (parameters[PARAM_DAMPING] + tex_damping > 0.0) {
-
float v = p.velocity.length();
float damp = (parameters[PARAM_DAMPING] + tex_damping) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_DAMPING]);
v -= damp * local_delta;
@@ -949,7 +912,6 @@ void CPUParticles2D::_particles_process(float p_delta) {
if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) {
if (p.velocity.length() > 0.0) {
-
p.transform.elements[1] = p.velocity.normalized();
p.transform.elements[0] = p.transform.elements[1].tangent();
}
@@ -961,7 +923,9 @@ void CPUParticles2D::_particles_process(float p_delta) {
//scale by scale
float base_scale = tex_scale * Math::lerp(parameters[PARAM_SCALE], 1.0f, p.scale_rand * randomness[PARAM_SCALE]);
- if (base_scale < 0.000001) base_scale = 0.000001;
+ if (base_scale < 0.000001) {
+ base_scale = 0.000001;
+ }
p.transform.elements[0] *= base_scale;
p.transform.elements[1] *= base_scale;
@@ -997,7 +961,6 @@ void CPUParticles2D::_update_particle_data_buffer() {
}
for (int i = 0; i < pc; i++) {
-
int idx = order ? order[i] : i;
Transform2D t = r[idx].transform;
@@ -1007,7 +970,6 @@ void CPUParticles2D::_update_particle_data_buffer() {
}
if (r[idx].active) {
-
ptr[0] = t.elements[0][0];
ptr[1] = t.elements[1][0];
ptr[2] = 0;
@@ -1038,8 +1000,9 @@ void CPUParticles2D::_update_particle_data_buffer() {
}
void CPUParticles2D::_set_redraw(bool p_redraw) {
- if (redraw == p_redraw)
+ if (redraw == p_redraw) {
return;
+ }
redraw = p_redraw;
{
@@ -1064,14 +1027,12 @@ void CPUParticles2D::_set_redraw(bool p_redraw) {
}
void CPUParticles2D::_update_render_thread() {
-
MutexLock lock(update_mutex);
RS::get_singleton()->multimesh_set_buffer(multimesh, particle_data);
}
void CPUParticles2D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
set_process_internal(emitting);
}
@@ -1082,11 +1043,13 @@ void CPUParticles2D::_notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) {
// first update before rendering to avoid one frame delay after emitting starts
- if (emitting && (time == 0))
+ if (emitting && (time == 0)) {
_update_internal();
+ }
- if (!redraw)
+ if (!redraw) {
return; // don't add to render list
+ }
RID texrid;
if (texture.is_valid()) {
@@ -1106,11 +1069,9 @@ void CPUParticles2D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
-
inv_emission_transform = get_global_transform().affine_inverse();
if (!local_coords) {
-
int pc = particles.size();
float *w = particle_data.ptrw();
@@ -1118,11 +1079,9 @@ void CPUParticles2D::_notification(int p_what) {
float *ptr = w;
for (int i = 0; i < pc; i++) {
-
Transform2D t = inv_emission_transform * r[i].transform;
if (r[i].active) {
-
ptr[0] = t.elements[0][0];
ptr[1] = t.elements[1][0];
ptr[2] = 0;
@@ -1143,7 +1102,6 @@ void CPUParticles2D::_notification(int p_what) {
}
void CPUParticles2D::convert_from_particles(Node *p_particles) {
-
GPUParticles2D *particles = Object::cast_to<GPUParticles2D>(p_particles);
ERR_FAIL_COND_MSG(!particles, "Only GPUParticles2D nodes can be converted to CPUParticles2D.");
@@ -1167,8 +1125,9 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) {
}
Ref<ParticlesMaterial> material = particles->get_process_material();
- if (material.is_null())
+ if (material.is_null()) {
return;
+ }
Vector3 dir = material->get_direction();
set_direction(Vector2(dir.x, dir.y));
@@ -1196,7 +1155,8 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) {
set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \
{ \
Ref<CurveTexture> ctex = material->get_param_texture(ParticlesMaterial::m_param); \
- if (ctex.is_valid()) set_param_curve(m_param, ctex->get_curve()); \
+ if (ctex.is_valid()) \
+ set_param_curve(m_param, ctex->get_curve()); \
} \
set_param_randomness(m_param, material->get_param_randomness(ParticlesMaterial::m_param));
@@ -1217,7 +1177,6 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) {
}
void CPUParticles2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &CPUParticles2D::set_emitting);
ClassDB::bind_method(D_METHOD("set_amount", "amount"), &CPUParticles2D::set_amount);
ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &CPUParticles2D::set_lifetime);
@@ -1420,7 +1379,6 @@ void CPUParticles2D::_bind_methods() {
}
CPUParticles2D::CPUParticles2D() {
-
time = 0;
inactive_time = 0;
frame_remainder = 0;
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 18d0caceed..747f06b90d 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -124,7 +124,6 @@ private:
const Particle *particles;
Vector2 axis;
bool operator()(int p_a, int p_b) const {
-
return axis.dot(particles[p_a].transform[2]) < axis.dot(particles[p_b].transform[2]);
}
};
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index de3f8fa09e..0814fbb549 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -39,7 +39,6 @@
#endif
void GPUParticles2D::set_emitting(bool p_emitting) {
-
RS::get_singleton()->particles_set_emitting(particles, p_emitting);
if (p_emitting && one_shot) {
@@ -50,50 +49,49 @@ void GPUParticles2D::set_emitting(bool p_emitting) {
}
void GPUParticles2D::set_amount(int p_amount) {
-
ERR_FAIL_COND_MSG(p_amount < 1, "Amount of particles cannot be smaller than 1.");
amount = p_amount;
RS::get_singleton()->particles_set_amount(particles, amount);
}
-void GPUParticles2D::set_lifetime(float p_lifetime) {
+void GPUParticles2D::set_lifetime(float p_lifetime) {
ERR_FAIL_COND_MSG(p_lifetime <= 0, "Particles lifetime must be greater than 0.");
lifetime = p_lifetime;
RS::get_singleton()->particles_set_lifetime(particles, lifetime);
}
void GPUParticles2D::set_one_shot(bool p_enable) {
-
one_shot = p_enable;
RS::get_singleton()->particles_set_one_shot(particles, one_shot);
if (is_emitting()) {
-
set_process_internal(true);
- if (!one_shot)
+ if (!one_shot) {
RenderingServer::get_singleton()->particles_restart(particles);
+ }
}
- if (!one_shot)
+ if (!one_shot) {
set_process_internal(false);
+ }
}
-void GPUParticles2D::set_pre_process_time(float p_time) {
+void GPUParticles2D::set_pre_process_time(float p_time) {
pre_process_time = p_time;
RS::get_singleton()->particles_set_pre_process_time(particles, pre_process_time);
}
-void GPUParticles2D::set_explosiveness_ratio(float p_ratio) {
+void GPUParticles2D::set_explosiveness_ratio(float p_ratio) {
explosiveness_ratio = p_ratio;
RS::get_singleton()->particles_set_explosiveness_ratio(particles, explosiveness_ratio);
}
-void GPUParticles2D::set_randomness_ratio(float p_ratio) {
+void GPUParticles2D::set_randomness_ratio(float p_ratio) {
randomness_ratio = p_ratio;
RS::get_singleton()->particles_set_randomness_ratio(particles, randomness_ratio);
}
-void GPUParticles2D::set_visibility_rect(const Rect2 &p_visibility_rect) {
+void GPUParticles2D::set_visibility_rect(const Rect2 &p_visibility_rect) {
visibility_rect = p_visibility_rect;
AABB aabb;
aabb.position.x = p_visibility_rect.position.x;
@@ -106,8 +104,8 @@ void GPUParticles2D::set_visibility_rect(const Rect2 &p_visibility_rect) {
_change_notify("visibility_rect");
update();
}
-void GPUParticles2D::set_use_local_coordinates(bool p_enable) {
+void GPUParticles2D::set_use_local_coordinates(bool p_enable) {
local_coords = p_enable;
RS::get_singleton()->particles_set_use_local_coordinates(particles, local_coords);
set_notify_transform(!p_enable);
@@ -117,7 +115,6 @@ void GPUParticles2D::set_use_local_coordinates(bool p_enable) {
}
void GPUParticles2D::_update_particle_emission_transform() {
-
Transform2D xf2d = get_global_transform();
Transform xf;
xf.basis.set_axis(0, Vector3(xf2d.get_axis(0).x, xf2d.get_axis(0).y, 0));
@@ -128,7 +125,6 @@ void GPUParticles2D::_update_particle_emission_transform() {
}
void GPUParticles2D::set_process_material(const Ref<Material> &p_material) {
-
process_material = p_material;
Ref<ParticlesMaterial> pm = p_material;
if (pm.is_valid() && !pm->get_flag(ParticlesMaterial::FLAG_DISABLE_Z) && pm->get_gravity() == Vector3(0, -9.8, 0)) {
@@ -137,74 +133,69 @@ void GPUParticles2D::set_process_material(const Ref<Material> &p_material) {
pm->set_gravity(Vector3(0, 98, 0));
}
RID material_rid;
- if (process_material.is_valid())
+ if (process_material.is_valid()) {
material_rid = process_material->get_rid();
+ }
RS::get_singleton()->particles_set_process_material(particles, material_rid);
update_configuration_warning();
}
void GPUParticles2D::set_speed_scale(float p_scale) {
-
speed_scale = p_scale;
RS::get_singleton()->particles_set_speed_scale(particles, p_scale);
}
bool GPUParticles2D::is_emitting() const {
-
return RS::get_singleton()->particles_get_emitting(particles);
}
-int GPUParticles2D::get_amount() const {
+int GPUParticles2D::get_amount() const {
return amount;
}
-float GPUParticles2D::get_lifetime() const {
+float GPUParticles2D::get_lifetime() const {
return lifetime;
}
bool GPUParticles2D::get_one_shot() const {
-
return one_shot;
}
-float GPUParticles2D::get_pre_process_time() const {
+float GPUParticles2D::get_pre_process_time() const {
return pre_process_time;
}
-float GPUParticles2D::get_explosiveness_ratio() const {
+float GPUParticles2D::get_explosiveness_ratio() const {
return explosiveness_ratio;
}
-float GPUParticles2D::get_randomness_ratio() const {
+float GPUParticles2D::get_randomness_ratio() const {
return randomness_ratio;
}
-Rect2 GPUParticles2D::get_visibility_rect() const {
+Rect2 GPUParticles2D::get_visibility_rect() const {
return visibility_rect;
}
-bool GPUParticles2D::get_use_local_coordinates() const {
+bool GPUParticles2D::get_use_local_coordinates() const {
return local_coords;
}
-Ref<Material> GPUParticles2D::get_process_material() const {
+Ref<Material> GPUParticles2D::get_process_material() const {
return process_material;
}
float GPUParticles2D::get_speed_scale() const {
-
return speed_scale;
}
void GPUParticles2D::set_draw_order(DrawOrder p_order) {
-
draw_order = p_order;
RS::get_singleton()->particles_set_draw_order(particles, RS::ParticlesDrawOrder(p_order));
}
GPUParticles2D::DrawOrder GPUParticles2D::get_draw_order() const {
-
return draw_order;
}
@@ -227,7 +218,6 @@ bool GPUParticles2D::get_fractional_delta() const {
}
String GPUParticles2D::get_configuration_warning() const {
-
if (RenderingServer::get_singleton()->is_low_end()) {
return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles2D node instead. You can use the \"Convert to CPUParticles2D\" option for this purpose.");
}
@@ -235,11 +225,11 @@ String GPUParticles2D::get_configuration_warning() const {
String warnings;
if (process_material.is_null()) {
- if (warnings != String())
+ if (warnings != String()) {
warnings += "\n";
+ }
warnings += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted.");
} else {
-
CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr());
if (get_material().is_null() || (mat && !mat->get_particles_animation())) {
@@ -247,8 +237,9 @@ String GPUParticles2D::get_configuration_warning() const {
if (process &&
(process->get_param(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 ||
process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) {
- if (warnings != String())
+ if (warnings != String()) {
warnings += "\n";
+ }
warnings += "- " + TTR("Particles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled.");
}
}
@@ -258,7 +249,6 @@ String GPUParticles2D::get_configuration_warning() const {
}
Rect2 GPUParticles2D::capture_rect() const {
-
AABB aabb = RS::get_singleton()->particles_get_current_aabb(particles);
Rect2 r;
r.position.x = aabb.position.x;
@@ -278,7 +268,6 @@ Ref<Texture2D> GPUParticles2D::get_texture() const {
}
void GPUParticles2D::set_normal_map(const Ref<Texture2D> &p_normal_map) {
-
normal_map = p_normal_map;
update();
}
@@ -296,21 +285,20 @@ void GPUParticles2D::restart() {
}
void GPUParticles2D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
-
RID texture_rid;
- if (texture.is_valid())
+ if (texture.is_valid()) {
texture_rid = texture->get_rid();
+ }
RID normal_rid;
- if (normal_map.is_valid())
+ if (normal_map.is_valid()) {
normal_rid = normal_map->get_rid();
+ }
RS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid, normal_rid);
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && (this == get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->is_a_parent_of(this))) {
-
draw_rect(visibility_rect, Color(0, 0.7, 0.9, 0.4), false);
}
#endif
@@ -320,7 +308,6 @@ void GPUParticles2D::_notification(int p_what) {
if (can_process()) {
RS::get_singleton()->particles_set_speed_scale(particles, speed_scale);
} else {
-
RS::get_singleton()->particles_set_speed_scale(particles, 0);
}
}
@@ -330,7 +317,6 @@ void GPUParticles2D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
-
if (one_shot && !is_emitting()) {
_change_notify();
set_process_internal(false);
@@ -339,7 +325,6 @@ void GPUParticles2D::_notification(int p_what) {
}
void GPUParticles2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &GPUParticles2D::set_emitting);
ClassDB::bind_method(D_METHOD("set_amount", "amount"), &GPUParticles2D::set_amount);
ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &GPUParticles2D::set_lifetime);
@@ -407,7 +392,6 @@ void GPUParticles2D::_bind_methods() {
}
GPUParticles2D::GPUParticles2D() {
-
particles = RS::get_singleton()->particles_create();
one_shot = false; // Needed so that set_emitting doesn't access uninitialized values
@@ -427,6 +411,5 @@ GPUParticles2D::GPUParticles2D() {
}
GPUParticles2D::~GPUParticles2D() {
-
RS::get_singleton()->free(particles);
}
diff --git a/scene/2d/joints_2d.cpp b/scene/2d/joints_2d.cpp
index 4d49f4762f..0d126b949d 100644
--- a/scene/2d/joints_2d.cpp
+++ b/scene/2d/joints_2d.cpp
@@ -35,10 +35,10 @@
#include "servers/physics_server_2d.h"
void Joint2D::_update_joint(bool p_only_free) {
-
if (joint.is_valid()) {
- if (ba.is_valid() && bb.is_valid() && exclude_from_collision)
+ if (ba.is_valid() && bb.is_valid() && exclude_from_collision) {
PhysicsServer2D::get_singleton()->joint_disable_collisions_between_bodies(joint, false);
+ }
PhysicsServer2D::get_singleton()->free(joint);
joint = RID();
@@ -46,25 +46,29 @@ void Joint2D::_update_joint(bool p_only_free) {
bb = RID();
}
- if (p_only_free || !is_inside_tree())
+ if (p_only_free || !is_inside_tree()) {
return;
+ }
Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)nullptr;
Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)nullptr;
- if (!node_a || !node_b)
+ if (!node_a || !node_b) {
return;
+ }
PhysicsBody2D *body_a = Object::cast_to<PhysicsBody2D>(node_a);
PhysicsBody2D *body_b = Object::cast_to<PhysicsBody2D>(node_b);
- if (!body_a || !body_b)
+ if (!body_a || !body_b) {
return;
+ }
joint = _configure_joint(body_a, body_b);
- if (!joint.is_valid())
+ if (!joint.is_valid()) {
return;
+ }
PhysicsServer2D::get_singleton()->get_singleton()->joint_set_param(joint, PhysicsServer2D::JOINT_PARAM_BIAS, bias);
@@ -75,35 +79,32 @@ void Joint2D::_update_joint(bool p_only_free) {
}
void Joint2D::set_node_a(const NodePath &p_node_a) {
-
- if (a == p_node_a)
+ if (a == p_node_a) {
return;
+ }
a = p_node_a;
_update_joint();
}
NodePath Joint2D::get_node_a() const {
-
return a;
}
void Joint2D::set_node_b(const NodePath &p_node_b) {
-
- if (b == p_node_b)
+ if (b == p_node_b) {
return;
+ }
b = p_node_b;
_update_joint();
}
-NodePath Joint2D::get_node_b() const {
+NodePath Joint2D::get_node_b() const {
return b;
}
void Joint2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_READY: {
_update_joint();
} break;
@@ -116,21 +117,20 @@ void Joint2D::_notification(int p_what) {
}
void Joint2D::set_bias(real_t p_bias) {
-
bias = p_bias;
- if (joint.is_valid())
+ if (joint.is_valid()) {
PhysicsServer2D::get_singleton()->get_singleton()->joint_set_param(joint, PhysicsServer2D::JOINT_PARAM_BIAS, bias);
+ }
}
real_t Joint2D::get_bias() const {
-
return bias;
}
void Joint2D::set_exclude_nodes_from_collision(bool p_enable) {
-
- if (exclude_from_collision == p_enable)
+ if (exclude_from_collision == p_enable) {
return;
+ }
_update_joint(true);
exclude_from_collision = p_enable;
@@ -138,12 +138,10 @@ void Joint2D::set_exclude_nodes_from_collision(bool p_enable) {
}
bool Joint2D::get_exclude_nodes_from_collision() const {
-
return exclude_from_collision;
}
void Joint2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_node_a", "node"), &Joint2D::set_node_a);
ClassDB::bind_method(D_METHOD("get_node_a"), &Joint2D::get_node_a);
@@ -163,7 +161,6 @@ void Joint2D::_bind_methods() {
}
Joint2D::Joint2D() {
-
bias = 0;
exclude_from_collision = true;
}
@@ -173,12 +170,11 @@ Joint2D::Joint2D() {
///////////////////////////////////////////////////////////////////////////////
void PinJoint2D::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_DRAW: {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
break;
+ }
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) {
break;
@@ -191,27 +187,24 @@ void PinJoint2D::_notification(int p_what) {
}
RID PinJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
-
RID pj = PhysicsServer2D::get_singleton()->pin_joint_create(get_global_transform().get_origin(), body_a->get_rid(), body_b ? body_b->get_rid() : RID());
PhysicsServer2D::get_singleton()->pin_joint_set_param(pj, PhysicsServer2D::PIN_JOINT_SOFTNESS, softness);
return pj;
}
void PinJoint2D::set_softness(real_t p_softness) {
-
softness = p_softness;
update();
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer2D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer2D::PIN_JOINT_SOFTNESS, p_softness);
+ }
}
real_t PinJoint2D::get_softness() const {
-
return softness;
}
void PinJoint2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_softness", "softness"), &PinJoint2D::set_softness);
ClassDB::bind_method(D_METHOD("get_softness"), &PinJoint2D::get_softness);
@@ -219,7 +212,6 @@ void PinJoint2D::_bind_methods() {
}
PinJoint2D::PinJoint2D() {
-
softness = 0;
}
@@ -228,11 +220,11 @@ PinJoint2D::PinJoint2D() {
///////////////////////////////////////////////////////////////////////////////
void GrooveJoint2D::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_DRAW: {
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
break;
+ }
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) {
break;
@@ -247,7 +239,6 @@ void GrooveJoint2D::_notification(int p_what) {
}
RID GrooveJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
-
Transform2D gt = get_global_transform();
Vector2 groove_A1 = gt.get_origin();
Vector2 groove_A2 = gt.xform(Vector2(0, length));
@@ -257,29 +248,24 @@ RID GrooveJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b
}
void GrooveJoint2D::set_length(real_t p_length) {
-
length = p_length;
update();
}
real_t GrooveJoint2D::get_length() const {
-
return length;
}
void GrooveJoint2D::set_initial_offset(real_t p_initial_offset) {
-
initial_offset = p_initial_offset;
update();
}
real_t GrooveJoint2D::get_initial_offset() const {
-
return initial_offset;
}
void GrooveJoint2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_length", "length"), &GrooveJoint2D::set_length);
ClassDB::bind_method(D_METHOD("get_length"), &GrooveJoint2D::get_length);
ClassDB::bind_method(D_METHOD("set_initial_offset", "offset"), &GrooveJoint2D::set_initial_offset);
@@ -290,7 +276,6 @@ void GrooveJoint2D::_bind_methods() {
}
GrooveJoint2D::GrooveJoint2D() {
-
length = 50;
initial_offset = 25;
}
@@ -300,12 +285,11 @@ GrooveJoint2D::GrooveJoint2D() {
///////////////////////////////////////////////////////////////////////////////
void DampedSpringJoint2D::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_DRAW: {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
break;
+ }
if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) {
break;
@@ -319,14 +303,14 @@ void DampedSpringJoint2D::_notification(int p_what) {
}
RID DampedSpringJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *body_b) {
-
Transform2D gt = get_global_transform();
Vector2 anchor_A = gt.get_origin();
Vector2 anchor_B = gt.xform(Vector2(0, length));
RID dsj = PhysicsServer2D::get_singleton()->damped_spring_joint_create(anchor_A, anchor_B, body_a->get_rid(), body_b->get_rid());
- if (rest_length)
+ if (rest_length) {
PhysicsServer2D::get_singleton()->damped_string_joint_set_param(dsj, PhysicsServer2D::DAMPED_STRING_REST_LENGTH, rest_length);
+ }
PhysicsServer2D::get_singleton()->damped_string_joint_set_param(dsj, PhysicsServer2D::DAMPED_STRING_STIFFNESS, stiffness);
PhysicsServer2D::get_singleton()->damped_string_joint_set_param(dsj, PhysicsServer2D::DAMPED_STRING_DAMPING, damping);
@@ -334,57 +318,51 @@ RID DampedSpringJoint2D::_configure_joint(PhysicsBody2D *body_a, PhysicsBody2D *
}
void DampedSpringJoint2D::set_length(real_t p_length) {
-
length = p_length;
update();
}
real_t DampedSpringJoint2D::get_length() const {
-
return length;
}
void DampedSpringJoint2D::set_rest_length(real_t p_rest_length) {
-
rest_length = p_rest_length;
update();
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer2D::get_singleton()->damped_string_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_STRING_REST_LENGTH, p_rest_length ? p_rest_length : length);
+ }
}
real_t DampedSpringJoint2D::get_rest_length() const {
-
return rest_length;
}
void DampedSpringJoint2D::set_stiffness(real_t p_stiffness) {
-
stiffness = p_stiffness;
update();
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer2D::get_singleton()->damped_string_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_STRING_STIFFNESS, p_stiffness);
+ }
}
real_t DampedSpringJoint2D::get_stiffness() const {
-
return stiffness;
}
void DampedSpringJoint2D::set_damping(real_t p_damping) {
-
damping = p_damping;
update();
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer2D::get_singleton()->damped_string_joint_set_param(get_joint(), PhysicsServer2D::DAMPED_STRING_DAMPING, p_damping);
+ }
}
real_t DampedSpringJoint2D::get_damping() const {
-
return damping;
}
void DampedSpringJoint2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_length", "length"), &DampedSpringJoint2D::set_length);
ClassDB::bind_method(D_METHOD("get_length"), &DampedSpringJoint2D::get_length);
ClassDB::bind_method(D_METHOD("set_rest_length", "rest_length"), &DampedSpringJoint2D::set_rest_length);
@@ -401,7 +379,6 @@ void DampedSpringJoint2D::_bind_methods() {
}
DampedSpringJoint2D::DampedSpringJoint2D() {
-
length = 50;
rest_length = 0;
stiffness = 20;
diff --git a/scene/2d/joints_2d.h b/scene/2d/joints_2d.h
index f1750e56b6..9a3bea4407 100644
--- a/scene/2d/joints_2d.h
+++ b/scene/2d/joints_2d.h
@@ -36,7 +36,6 @@
class PhysicsBody2D;
class Joint2D : public Node2D {
-
GDCLASS(Joint2D, Node2D);
RID joint;
@@ -74,7 +73,6 @@ public:
};
class PinJoint2D : public Joint2D {
-
GDCLASS(PinJoint2D, Joint2D);
real_t softness;
@@ -92,7 +90,6 @@ public:
};
class GrooveJoint2D : public Joint2D {
-
GDCLASS(GrooveJoint2D, Joint2D);
real_t length;
@@ -114,7 +111,6 @@ public:
};
class DampedSpringJoint2D : public Joint2D {
-
GDCLASS(DampedSpringJoint2D, Joint2D);
real_t stiffness;
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index b3d54b81f8..1e7e9f6b6a 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -59,8 +59,9 @@ bool Light2D::_edit_use_pivot() const {
}
Rect2 Light2D::_edit_get_rect() const {
- if (texture.is_null())
+ if (texture.is_null()) {
return Rect2();
+ }
Size2 s = texture->get_size() * _scale;
return Rect2(texture_offset - s / 2.0, s);
@@ -72,17 +73,18 @@ bool Light2D::_edit_use_rect() const {
#endif
Rect2 Light2D::get_anchorable_rect() const {
- if (texture.is_null())
+ if (texture.is_null()) {
return Rect2();
+ }
Size2 s = texture->get_size() * _scale;
return Rect2(texture_offset - s / 2.0, s);
}
void Light2D::_update_light_visibility() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
bool editor_ok = true;
@@ -104,45 +106,39 @@ void Light2D::_update_light_visibility() {
}
void Light2D::set_enabled(bool p_enabled) {
-
enabled = p_enabled;
_update_light_visibility();
}
bool Light2D::is_enabled() const {
-
return enabled;
}
void Light2D::set_editor_only(bool p_editor_only) {
-
editor_only = p_editor_only;
_update_light_visibility();
}
bool Light2D::is_editor_only() const {
-
return editor_only;
}
void Light2D::set_texture(const Ref<Texture2D> &p_texture) {
-
texture = p_texture;
- if (texture.is_valid())
+ if (texture.is_valid()) {
RS::get_singleton()->canvas_light_set_texture(canvas_light, texture->get_rid());
- else
+ } else {
RS::get_singleton()->canvas_light_set_texture(canvas_light, RID());
+ }
update_configuration_warning();
}
Ref<Texture2D> Light2D::get_texture() const {
-
return texture;
}
void Light2D::set_texture_offset(const Vector2 &p_offset) {
-
texture_offset = p_offset;
RS::get_singleton()->canvas_light_set_texture_offset(canvas_light, texture_offset);
item_rect_changed();
@@ -150,44 +146,37 @@ void Light2D::set_texture_offset(const Vector2 &p_offset) {
}
Vector2 Light2D::get_texture_offset() const {
-
return texture_offset;
}
void Light2D::set_color(const Color &p_color) {
-
color = p_color;
RS::get_singleton()->canvas_light_set_color(canvas_light, color);
}
-Color Light2D::get_color() const {
+Color Light2D::get_color() const {
return color;
}
void Light2D::set_height(float p_height) {
-
height = p_height;
RS::get_singleton()->canvas_light_set_height(canvas_light, height);
}
float Light2D::get_height() const {
-
return height;
}
void Light2D::set_energy(float p_energy) {
-
energy = p_energy;
RS::get_singleton()->canvas_light_set_energy(canvas_light, energy);
}
float Light2D::get_energy() const {
-
return energy;
}
void Light2D::set_texture_scale(float p_scale) {
-
_scale = p_scale;
// Avoid having 0 scale values, can lead to errors in physics and rendering.
if (_scale == 0) {
@@ -198,101 +187,87 @@ void Light2D::set_texture_scale(float p_scale) {
}
float Light2D::get_texture_scale() const {
-
return _scale;
}
void Light2D::set_z_range_min(int p_min_z) {
-
z_min = p_min_z;
RS::get_singleton()->canvas_light_set_z_range(canvas_light, z_min, z_max);
}
-int Light2D::get_z_range_min() const {
+int Light2D::get_z_range_min() const {
return z_min;
}
void Light2D::set_z_range_max(int p_max_z) {
-
z_max = p_max_z;
RS::get_singleton()->canvas_light_set_z_range(canvas_light, z_min, z_max);
}
-int Light2D::get_z_range_max() const {
+int Light2D::get_z_range_max() const {
return z_max;
}
void Light2D::set_layer_range_min(int p_min_layer) {
-
layer_min = p_min_layer;
RS::get_singleton()->canvas_light_set_layer_range(canvas_light, layer_min, layer_max);
}
-int Light2D::get_layer_range_min() const {
+int Light2D::get_layer_range_min() const {
return layer_min;
}
void Light2D::set_layer_range_max(int p_max_layer) {
-
layer_max = p_max_layer;
RS::get_singleton()->canvas_light_set_layer_range(canvas_light, layer_min, layer_max);
}
-int Light2D::get_layer_range_max() const {
+int Light2D::get_layer_range_max() const {
return layer_max;
}
void Light2D::set_item_cull_mask(int p_mask) {
-
item_mask = p_mask;
RS::get_singleton()->canvas_light_set_item_cull_mask(canvas_light, item_mask);
}
int Light2D::get_item_cull_mask() const {
-
return item_mask;
}
void Light2D::set_item_shadow_cull_mask(int p_mask) {
-
item_shadow_mask = p_mask;
RS::get_singleton()->canvas_light_set_item_shadow_cull_mask(canvas_light, item_shadow_mask);
}
int Light2D::get_item_shadow_cull_mask() const {
-
return item_shadow_mask;
}
void Light2D::set_mode(Mode p_mode) {
-
mode = p_mode;
RS::get_singleton()->canvas_light_set_mode(canvas_light, RS::CanvasLightMode(p_mode));
}
Light2D::Mode Light2D::get_mode() const {
-
return mode;
}
void Light2D::set_shadow_enabled(bool p_enabled) {
-
shadow = p_enabled;
RS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light, shadow);
}
-bool Light2D::is_shadow_enabled() const {
+bool Light2D::is_shadow_enabled() const {
return shadow;
}
void Light2D::set_shadow_buffer_size(int p_size) {
-
shadow_buffer_size = p_size;
RS::get_singleton()->canvas_light_set_shadow_buffer_size(canvas_light, shadow_buffer_size);
}
int Light2D::get_shadow_buffer_size() const {
-
return shadow_buffer_size;
}
@@ -303,7 +278,6 @@ void Light2D::set_shadow_filter(ShadowFilter p_filter) {
}
Light2D::ShadowFilter Light2D::get_shadow_filter() const {
-
return shadow_filter;
}
@@ -317,31 +291,25 @@ Color Light2D::get_shadow_color() const {
}
void Light2D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
RS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, get_canvas());
_update_light_visibility();
}
if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
-
RS::get_singleton()->canvas_light_set_transform(canvas_light, get_global_transform());
}
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
_update_light_visibility();
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
RS::get_singleton()->canvas_light_attach_to_canvas(canvas_light, RID());
_update_light_visibility();
}
}
String Light2D::get_configuration_warning() const {
-
if (!texture.is_valid()) {
return TTR("A texture with the shape of the light must be supplied to the \"Texture\" property.");
}
@@ -350,18 +318,15 @@ String Light2D::get_configuration_warning() const {
}
void Light2D::set_shadow_smooth(float p_amount) {
-
shadow_smooth = p_amount;
RS::get_singleton()->canvas_light_set_shadow_smooth(canvas_light, shadow_smooth);
}
float Light2D::get_shadow_smooth() const {
-
return shadow_smooth;
}
void Light2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Light2D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &Light2D::is_enabled);
@@ -457,7 +422,6 @@ void Light2D::_bind_methods() {
}
Light2D::Light2D() {
-
canvas_light = RenderingServer::get_singleton()->canvas_light_create();
enabled = true;
editor_only = false;
@@ -482,6 +446,5 @@ Light2D::Light2D() {
}
Light2D::~Light2D() {
-
RenderingServer::get_singleton()->free(canvas_light);
}
diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h
index 7134029441..0d5e8d674a 100644
--- a/scene/2d/light_2d.h
+++ b/scene/2d/light_2d.h
@@ -34,7 +34,6 @@
#include "scene/2d/node_2d.h"
class Light2D : public Node2D {
-
GDCLASS(Light2D, Node2D);
public:
diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp
index bd1a820aec..0f4880f69a 100644
--- a/scene/2d/light_occluder_2d.cpp
+++ b/scene/2d/light_occluder_2d.cpp
@@ -36,17 +36,17 @@
#ifdef TOOLS_ENABLED
Rect2 OccluderPolygon2D::_edit_get_rect() const {
-
if (rect_cache_dirty) {
if (closed) {
const Vector2 *r = polygon.ptr();
item_rect = Rect2();
for (int i = 0; i < polygon.size(); i++) {
Vector2 pos = r[i];
- if (i == 0)
+ if (i == 0) {
item_rect.position = pos;
- else
+ } else {
item_rect.expand_to(pos);
+ }
}
rect_cache_dirty = false;
} else {
@@ -67,7 +67,6 @@ Rect2 OccluderPolygon2D::_edit_get_rect() const {
}
bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
if (closed) {
return Geometry::is_point_in_polygon(p_point, Variant(polygon));
} else {
@@ -75,8 +74,9 @@ bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double
const Vector2 *points = polygon.ptr();
for (int i = 0; i < polygon.size() - 1; i++) {
Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, &points[i]);
- if (p.distance_to(p_point) <= d)
+ if (p.distance_to(p_point) <= d) {
return true;
+ }
}
return false;
@@ -85,7 +85,6 @@ bool OccluderPolygon2D::_edit_is_selected_on_click(const Point2 &p_point, double
#endif
void OccluderPolygon2D::set_polygon(const Vector<Vector2> &p_polygon) {
-
polygon = p_polygon;
rect_cache_dirty = true;
RS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon, p_polygon, closed);
@@ -93,43 +92,38 @@ void OccluderPolygon2D::set_polygon(const Vector<Vector2> &p_polygon) {
}
Vector<Vector2> OccluderPolygon2D::get_polygon() const {
-
return polygon;
}
void OccluderPolygon2D::set_closed(bool p_closed) {
-
- if (closed == p_closed)
+ if (closed == p_closed) {
return;
+ }
closed = p_closed;
- if (polygon.size())
+ if (polygon.size()) {
RS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon, polygon, closed);
+ }
emit_changed();
}
bool OccluderPolygon2D::is_closed() const {
-
return closed;
}
void OccluderPolygon2D::set_cull_mode(CullMode p_mode) {
-
cull = p_mode;
RS::get_singleton()->canvas_occluder_polygon_set_cull_mode(occ_polygon, RS::CanvasOccluderPolygonCullMode(p_mode));
}
OccluderPolygon2D::CullMode OccluderPolygon2D::get_cull_mode() const {
-
return cull;
}
RID OccluderPolygon2D::get_rid() const {
-
return occ_polygon;
}
void OccluderPolygon2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_closed", "closed"), &OccluderPolygon2D::set_closed);
ClassDB::bind_method(D_METHOD("is_closed"), &OccluderPolygon2D::is_closed);
@@ -149,7 +143,6 @@ void OccluderPolygon2D::_bind_methods() {
}
OccluderPolygon2D::OccluderPolygon2D() {
-
occ_polygon = RS::get_singleton()->canvas_occluder_polygon_create();
closed = true;
cull = CULL_DISABLED;
@@ -157,40 +150,31 @@ OccluderPolygon2D::OccluderPolygon2D() {
}
OccluderPolygon2D::~OccluderPolygon2D() {
-
RS::get_singleton()->free(occ_polygon);
}
void LightOccluder2D::_poly_changed() {
-
#ifdef DEBUG_ENABLED
update();
#endif
}
void LightOccluder2D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_CANVAS) {
-
RS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder, get_canvas());
RS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform());
RS::get_singleton()->canvas_light_occluder_set_enabled(occluder, is_visible_in_tree());
}
if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
-
RS::get_singleton()->canvas_light_occluder_set_transform(occluder, get_global_transform());
}
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
RS::get_singleton()->canvas_light_occluder_set_enabled(occluder, is_visible_in_tree());
}
if (p_what == NOTIFICATION_DRAW) {
-
if (Engine::get_singleton()->is_editor_hint()) {
-
if (occluder_polygon.is_valid()) {
-
Vector<Vector2> poly = occluder_polygon->get_polygon();
if (poly.size()) {
@@ -199,11 +183,9 @@ void LightOccluder2D::_notification(int p_what) {
color.push_back(Color(0, 0, 0, 0.6));
draw_polygon(Variant(poly), color);
} else {
-
int ps = poly.size();
const Vector2 *r = poly.ptr();
for (int i = 0; i < ps - 1; i++) {
-
draw_line(r[i], r[i + 1], Color(0, 0, 0, 0.6), 3);
}
}
@@ -213,61 +195,56 @@ void LightOccluder2D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_EXIT_CANVAS) {
-
RS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder, RID());
}
}
#ifdef TOOLS_ENABLED
Rect2 LightOccluder2D::_edit_get_rect() const {
-
return occluder_polygon.is_valid() ? occluder_polygon->_edit_get_rect() : Rect2();
}
bool LightOccluder2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
return occluder_polygon.is_valid() ? occluder_polygon->_edit_is_selected_on_click(p_point, p_tolerance) : false;
}
#endif
void LightOccluder2D::set_occluder_polygon(const Ref<OccluderPolygon2D> &p_polygon) {
-
#ifdef DEBUG_ENABLED
- if (occluder_polygon.is_valid())
+ if (occluder_polygon.is_valid()) {
occluder_polygon->disconnect("changed", callable_mp(this, &LightOccluder2D::_poly_changed));
+ }
#endif
occluder_polygon = p_polygon;
- if (occluder_polygon.is_valid())
+ if (occluder_polygon.is_valid()) {
RS::get_singleton()->canvas_light_occluder_set_polygon(occluder, occluder_polygon->get_rid());
- else
+ } else {
RS::get_singleton()->canvas_light_occluder_set_polygon(occluder, RID());
+ }
#ifdef DEBUG_ENABLED
- if (occluder_polygon.is_valid())
+ if (occluder_polygon.is_valid()) {
occluder_polygon->connect("changed", callable_mp(this, &LightOccluder2D::_poly_changed));
+ }
update();
#endif
}
Ref<OccluderPolygon2D> LightOccluder2D::get_occluder_polygon() const {
-
return occluder_polygon;
}
void LightOccluder2D::set_occluder_light_mask(int p_mask) {
-
mask = p_mask;
RS::get_singleton()->canvas_light_occluder_set_light_mask(occluder, mask);
}
int LightOccluder2D::get_occluder_light_mask() const {
-
return mask;
}
String LightOccluder2D::get_configuration_warning() const {
-
if (!occluder_polygon.is_valid()) {
return TTR("An occluder polygon must be set (or drawn) for this occluder to take effect.");
}
@@ -280,7 +257,6 @@ String LightOccluder2D::get_configuration_warning() const {
}
void LightOccluder2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_occluder_polygon", "polygon"), &LightOccluder2D::set_occluder_polygon);
ClassDB::bind_method(D_METHOD("get_occluder_polygon"), &LightOccluder2D::get_occluder_polygon);
@@ -292,13 +268,11 @@ void LightOccluder2D::_bind_methods() {
}
LightOccluder2D::LightOccluder2D() {
-
occluder = RS::get_singleton()->canvas_light_occluder_create();
mask = 1;
set_notify_transform(true);
}
LightOccluder2D::~LightOccluder2D() {
-
RS::get_singleton()->free(occluder);
}
diff --git a/scene/2d/light_occluder_2d.h b/scene/2d/light_occluder_2d.h
index 83702f2875..eba67edfe4 100644
--- a/scene/2d/light_occluder_2d.h
+++ b/scene/2d/light_occluder_2d.h
@@ -34,7 +34,6 @@
#include "scene/2d/node_2d.h"
class OccluderPolygon2D : public Resource {
-
GDCLASS(OccluderPolygon2D, Resource);
public:
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index c45eab70df..28183403f2 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -43,7 +43,7 @@ Line2D::Line2D() {
_begin_cap_mode = LINE_CAP_NONE;
_end_cap_mode = LINE_CAP_NONE;
_width = 10;
- _default_color = Color(0.4, 0.5, 1);
+ _default_color = Color(1, 1, 1);
_texture_mode = LINE_TEXTURE_NONE;
_sharp_limit = 2.f;
_round_precision = 8;
@@ -52,9 +52,9 @@ Line2D::Line2D() {
#ifdef TOOLS_ENABLED
Rect2 Line2D::_edit_get_rect() const {
-
- if (_points.size() == 0)
+ if (_points.size() == 0) {
return Rect2(0, 0, 0, 0);
+ }
Vector2 d = Vector2(_width, _width);
Rect2 aabb = Rect2(_points[0] - d, 2 * d);
for (int i = 1; i < _points.size(); i++) {
@@ -69,13 +69,13 @@ bool Line2D::_edit_use_rect() const {
}
bool Line2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
const real_t d = _width / 2 + p_tolerance;
const Vector2 *points = _points.ptr();
for (int i = 0; i < _points.size() - 1; i++) {
Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, &points[i]);
- if (p.distance_to(p_point) <= d)
+ if (p.distance_to(p_point) <= d) {
return true;
+ }
}
return false;
@@ -88,8 +88,9 @@ void Line2D::set_points(const Vector<Vector2> &p_points) {
}
void Line2D::set_width(float p_width) {
- if (p_width < 0.0)
+ if (p_width < 0.0) {
p_width = 0.0;
+ }
_width = p_width;
update();
}
@@ -168,7 +169,6 @@ Color Line2D::get_default_color() const {
}
void Line2D::set_gradient(const Ref<Gradient> &p_gradient) {
-
// Cleanup previous connection if any
if (_gradient.is_valid()) {
_gradient->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Line2D::_gradient_changed));
@@ -242,8 +242,9 @@ void Line2D::_notification(int p_what) {
}
void Line2D::set_sharp_limit(float p_limit) {
- if (p_limit < 0.f)
+ if (p_limit < 0.f) {
p_limit = 0.f;
+ }
_sharp_limit = p_limit;
update();
}
@@ -253,8 +254,9 @@ float Line2D::get_sharp_limit() const {
}
void Line2D::set_round_precision(int p_precision) {
- if (p_precision < 1)
+ if (p_precision < 1) {
p_precision = 1;
+ }
_round_precision = p_precision;
update();
}
@@ -273,8 +275,9 @@ bool Line2D::get_antialiased() const {
}
void Line2D::_draw() {
- if (_points.size() <= 1 || _width == 0.f)
+ if (_points.size() <= 1 || _width == 0.f) {
return;
+ }
// TODO Is this really needed?
// Copy points for faster access
@@ -350,7 +353,6 @@ void Line2D::_curve_changed() {
// static
void Line2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_points", "points"), &Line2D::set_points);
ClassDB::bind_method(D_METHOD("get_points"), &Line2D::get_points);
diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h
index 51706befdb..bccbcbdcb9 100644
--- a/scene/2d/line_2d.h
+++ b/scene/2d/line_2d.h
@@ -34,7 +34,6 @@
#include "node_2d.h"
class Line2D : public Node2D {
-
GDCLASS(Line2D, Node2D);
public:
diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp
index 6b06f2227a..f1522dbaeb 100644
--- a/scene/2d/line_builder.cpp
+++ b/scene/2d/line_builder.cpp
@@ -53,8 +53,9 @@ static SegmentIntersectionResult segment_intersection(
float ub = (ab.x * (a.y - c.y) - ab.y * (a.x - c.x)) / div;
*out_intersection = a + ua * ab;
if (ua >= 0.f && ua <= 1.f &&
- ub >= 0.f && ub <= 1.f)
+ ub >= 0.f && ub <= 1.f) {
return SEGMENT_INTERSECT;
+ }
return SEGMENT_NO_INTERSECT;
}
@@ -117,7 +118,6 @@ void LineBuilder::clear_output() {
}
void LineBuilder::build() {
-
// Need at least 2 points to draw a line
if (points.size() < 2) {
clear_output();
@@ -158,28 +158,32 @@ void LineBuilder::build() {
//Adjust totalDistance.
// The line's outer length will be a little higher due to begin and end caps
if (begin_cap_mode == Line2D::LINE_CAP_BOX || begin_cap_mode == Line2D::LINE_CAP_ROUND) {
- if (retrieve_curve)
+ if (retrieve_curve) {
total_distance += width * curve->interpolate_baked(0.f) * 0.5f;
- else
+ } else {
total_distance += width * 0.5f;
+ }
}
if (end_cap_mode == Line2D::LINE_CAP_BOX || end_cap_mode == Line2D::LINE_CAP_ROUND) {
- if (retrieve_curve)
+ if (retrieve_curve) {
total_distance += width * curve->interpolate_baked(1.f) * 0.5f;
- else
+ } else {
total_distance += width * 0.5f;
+ }
}
}
- if (_interpolate_color)
+ if (_interpolate_color) {
color0 = gradient->get_color(0);
- else
+ } else {
colors.push_back(default_color);
+ }
float uvx0 = 0.f;
float uvx1 = 0.f;
- if (retrieve_curve)
+ if (retrieve_curve) {
width_factor = curve->interpolate_baked(0.f);
+ }
pos_up0 += u0 * hw * width_factor;
pos_down0 -= u0 * hw * width_factor;
@@ -220,7 +224,6 @@ void LineBuilder::build() {
// For each additional segment
for (int i = 1; i < len - 1; ++i) {
-
pos1 = points[i];
Vector2 pos2 = points[i + 1];
@@ -271,10 +274,10 @@ void LineBuilder::build() {
pos1 + inner_normal1, pos2 + inner_normal1,
&corner_pos_in);
- if (intersection_result == SEGMENT_INTERSECT)
+ if (intersection_result == SEGMENT_INTERSECT) {
// Inner parts of the segments intersect
corner_pos_out = 2.f * pos1 - corner_pos_in;
- else {
+ } else {
// No intersection, segments are either parallel or too sharp
corner_pos_in = pos1 + inner_normal0;
corner_pos_out = pos1 - inner_normal0;
@@ -359,7 +362,6 @@ void LineBuilder::build() {
// Add joint geometry
if (current_joint_mode != Line2D::LINE_JOINT_SHARP) {
-
/* ________________ cbegin
* / \
* / \
@@ -386,10 +388,11 @@ void LineBuilder::build() {
strip_add_arc(pos1, vbegin.angle_to(vend), orientation);
}
- if (intersection_result != SEGMENT_INTERSECT)
+ if (intersection_result != SEGMENT_INTERSECT) {
// In this case the joint is too corrputed to be re-used,
// start again the strip with fallback points
strip_begin(pos_up0, pos_down0, color1, uvx1);
+ }
}
}
// Last (or only) segment
@@ -541,7 +544,6 @@ void LineBuilder::strip_add_tri(Vector2 up, Orientation orientation) {
}
void LineBuilder::strip_add_arc(Vector2 center, float angle_delta, Orientation orientation) {
-
// Take the two last vertices and extrude an arc made of triangles
// that all share one of the initial vertices
@@ -551,8 +553,9 @@ void LineBuilder::strip_add_arc(Vector2 center, float angle_delta, Orientation o
float angle_step = Math_PI / static_cast<float>(round_precision);
float steps = Math::abs(angle_delta) / angle_step;
- if (angle_delta < 0.f)
+ if (angle_delta < 0.f) {
angle_step = -angle_step;
+ }
float t = Vector2(1, 0).angle_to(vbegin);
float end_angle = t + angle_delta;
@@ -570,7 +573,6 @@ void LineBuilder::strip_add_arc(Vector2 center, float angle_delta, Orientation o
}
void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Color color, Rect2 uv_rect) {
-
// Make a standalone arc that doesn't use existing vertices,
// with undistorted UVs from within a square section
@@ -578,8 +580,9 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col
float angle_step = Math_PI / static_cast<float>(round_precision);
float steps = Math::abs(angle_delta) / angle_step;
- if (angle_delta < 0.f)
+ if (angle_delta < 0.f) {
angle_step = -angle_step;
+ }
float t = Vector2(1, 0).angle_to(vbegin);
float end_angle = t + angle_delta;
@@ -590,10 +593,12 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col
// Center vertice
int vi = vertices.size();
vertices.push_back(center);
- if (_interpolate_color)
+ if (_interpolate_color) {
colors.push_back(color);
- if (texture_mode != Line2D::LINE_TEXTURE_NONE)
+ }
+ if (texture_mode != Line2D::LINE_TEXTURE_NONE) {
uvs.push_back(interpolate(uv_rect, Vector2(0.5f, 0.5f)));
+ }
// Arc vertices
for (int ti = 0; ti < steps; ++ti, t += angle_step) {
@@ -601,8 +606,9 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col
rpos = center + sc * radius;
vertices.push_back(rpos);
- if (_interpolate_color)
+ if (_interpolate_color) {
colors.push_back(color);
+ }
if (texture_mode != Line2D::LINE_TEXTURE_NONE) {
Vector2 tsc = Vector2(Math::cos(tt), Math::sin(tt));
uvs.push_back(interpolate(uv_rect, 0.5f * (tsc + Vector2(1.f, 1.f))));
@@ -614,8 +620,9 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col
Vector2 sc = Vector2(Math::cos(end_angle), Math::sin(end_angle));
rpos = center + sc * radius;
vertices.push_back(rpos);
- if (_interpolate_color)
+ if (_interpolate_color) {
colors.push_back(color);
+ }
if (texture_mode != Line2D::LINE_TEXTURE_NONE) {
tt = tt_begin + angle_delta;
Vector2 tsc = Vector2(Math::cos(tt), Math::sin(tt));
diff --git a/scene/2d/mesh_instance_2d.cpp b/scene/2d/mesh_instance_2d.cpp
index 5e258be700..897595ad1f 100644
--- a/scene/2d/mesh_instance_2d.cpp
+++ b/scene/2d/mesh_instance_2d.cpp
@@ -31,7 +31,6 @@
#include "mesh_instance_2d.h"
void MeshInstance2D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
if (mesh.is_valid()) {
draw_mesh(mesh, texture, normal_map);
@@ -40,7 +39,6 @@ void MeshInstance2D::_notification(int p_what) {
}
void MeshInstance2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MeshInstance2D::set_mesh);
ClassDB::bind_method(D_METHOD("get_mesh"), &MeshInstance2D::get_mesh);
@@ -58,20 +56,18 @@ void MeshInstance2D::_bind_methods() {
}
void MeshInstance2D::set_mesh(const Ref<Mesh> &p_mesh) {
-
mesh = p_mesh;
update();
}
Ref<Mesh> MeshInstance2D::get_mesh() const {
-
return mesh;
}
void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) {
-
- if (p_texture == texture)
+ if (p_texture == texture) {
return;
+ }
texture = p_texture;
update();
emit_signal("texture_changed");
@@ -79,24 +75,20 @@ void MeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) {
}
void MeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) {
-
normal_map = p_texture;
update();
}
Ref<Texture2D> MeshInstance2D::get_normal_map() const {
-
return normal_map;
}
Ref<Texture2D> MeshInstance2D::get_texture() const {
-
return texture;
}
#ifdef TOOLS_ENABLED
Rect2 MeshInstance2D::_edit_get_rect() const {
-
if (mesh.is_valid()) {
AABB aabb = mesh->get_aabb();
return Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp
index 6620027020..b99c0a3fa9 100644
--- a/scene/2d/multimesh_instance_2d.cpp
+++ b/scene/2d/multimesh_instance_2d.cpp
@@ -31,7 +31,6 @@
#include "multimesh_instance_2d.h"
void MultiMeshInstance2D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
if (multimesh.is_valid()) {
draw_multimesh(multimesh, texture, normal_map);
@@ -40,7 +39,6 @@ void MultiMeshInstance2D::_notification(int p_what) {
}
void MultiMeshInstance2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_multimesh", "multimesh"), &MultiMeshInstance2D::set_multimesh);
ClassDB::bind_method(D_METHOD("get_multimesh"), &MultiMeshInstance2D::get_multimesh);
@@ -58,20 +56,18 @@ void MultiMeshInstance2D::_bind_methods() {
}
void MultiMeshInstance2D::set_multimesh(const Ref<MultiMesh> &p_multimesh) {
-
multimesh = p_multimesh;
update();
}
Ref<MultiMesh> MultiMeshInstance2D::get_multimesh() const {
-
return multimesh;
}
void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) {
-
- if (p_texture == texture)
+ if (p_texture == texture) {
return;
+ }
texture = p_texture;
update();
emit_signal("texture_changed");
@@ -79,24 +75,20 @@ void MultiMeshInstance2D::set_texture(const Ref<Texture2D> &p_texture) {
}
Ref<Texture2D> MultiMeshInstance2D::get_texture() const {
-
return texture;
}
void MultiMeshInstance2D::set_normal_map(const Ref<Texture2D> &p_texture) {
-
normal_map = p_texture;
update();
}
Ref<Texture2D> MultiMeshInstance2D::get_normal_map() const {
-
return normal_map;
}
#ifdef TOOLS_ENABLED
Rect2 MultiMeshInstance2D::_edit_get_rect() const {
-
if (multimesh.is_valid()) {
AABB aabb = multimesh->get_aabb();
return Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
diff --git a/scene/2d/navigation_2d.cpp b/scene/2d/navigation_2d.cpp
index ae9fc0f32c..039c6f2e53 100644
--- a/scene/2d/navigation_2d.cpp
+++ b/scene/2d/navigation_2d.cpp
@@ -54,7 +54,6 @@ void Navigation2D::_notification(int p_what) {
NavigationServer2D::get_singleton()->map_set_active(map, true);
} break;
case NOTIFICATION_EXIT_TREE: {
-
NavigationServer2D::get_singleton()->map_set_active(map, false);
} break;
}
@@ -83,7 +82,6 @@ RID Navigation2D::get_closest_point_owner(const Vector2 &p_point) const {
}
Navigation2D::Navigation2D() {
-
map = NavigationServer2D::get_singleton()->map_create();
set_cell_size(10); // Ten pixels
set_edge_connection_margin(100);
diff --git a/scene/2d/navigation_2d.h b/scene/2d/navigation_2d.h
index 1da13fc78a..6046bddb32 100644
--- a/scene/2d/navigation_2d.h
+++ b/scene/2d/navigation_2d.h
@@ -35,7 +35,6 @@
#include "scene/2d/node_2d.h"
class Navigation2D : public Node2D {
-
GDCLASS(Navigation2D, Node2D);
RID map;
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 32da46e8a8..cb2dbba0fe 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -35,7 +35,6 @@
#include "servers/navigation_server_2d.h"
void NavigationAgent2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent2D::set_target_desired_distance);
ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent2D::get_target_desired_distance);
@@ -91,7 +90,6 @@ void NavigationAgent2D::_bind_methods() {
void NavigationAgent2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
-
agent_parent = Object::cast_to<Node2D>(get_parent());
NavigationServer2D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
@@ -102,10 +100,11 @@ void NavigationAgent2D::_notification(int p_what) {
Node *p = get_parent();
while (p != nullptr) {
nav = Object::cast_to<Navigation2D>(p);
- if (nav != nullptr)
+ if (nav != nullptr) {
p = nullptr;
- else
+ } else {
p = p->get_parent();
+ }
}
set_navigation(nav);
@@ -120,7 +119,6 @@ void NavigationAgent2D::_notification(int p_what) {
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (agent_parent) {
-
NavigationServer2D::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().get_origin());
if (!target_reached) {
if (distance_to_target() < target_desired_distance) {
@@ -133,15 +131,7 @@ void NavigationAgent2D::_notification(int p_what) {
}
}
-NavigationAgent2D::NavigationAgent2D() :
- agent_parent(nullptr),
- navigation(nullptr),
- agent(RID()),
- target_desired_distance(1.0),
- path_max_distance(3.0),
- velocity_submitted(false),
- target_reached(false),
- navigation_finished(true) {
+NavigationAgent2D::NavigationAgent2D() {
agent = NavigationServer2D::get_singleton()->agent_create();
set_neighbor_dist(500.0);
set_max_neighbors(10);
@@ -156,8 +146,9 @@ NavigationAgent2D::~NavigationAgent2D() {
}
void NavigationAgent2D::set_navigation(Navigation2D *p_nav) {
- if (navigation == p_nav)
+ if (navigation == p_nav) {
return; // Pointless
+ }
navigation = p_nav;
NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
@@ -287,10 +278,15 @@ String NavigationAgent2D::get_configuration_warning() const {
}
void NavigationAgent2D::update_navigation() {
-
- if (agent_parent == nullptr) return;
- if (navigation == nullptr) return;
- if (update_frame_id == Engine::get_singleton()->get_physics_frames()) return;
+ if (agent_parent == nullptr) {
+ return;
+ }
+ if (navigation == nullptr) {
+ return;
+ }
+ if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
+ return;
+ }
update_frame_id = Engine::get_singleton()->get_physics_frames();
@@ -323,8 +319,9 @@ void NavigationAgent2D::update_navigation() {
emit_signal("path_changed");
}
- if (navigation_path.size() == 0)
+ if (navigation_path.size() == 0) {
return;
+ }
// Check if we can advance the navigation path
if (navigation_finished == false) {
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
index 26eccfc949..796a85f3f2 100644
--- a/scene/2d/navigation_agent_2d.h
+++ b/scene/2d/navigation_agent_2d.h
@@ -40,29 +40,29 @@ class Navigation2D;
class NavigationAgent2D : public Node {
GDCLASS(NavigationAgent2D, Node);
- Node2D *agent_parent;
- Navigation2D *navigation;
+ Node2D *agent_parent = nullptr;
+ Navigation2D *navigation = nullptr;
RID agent;
- real_t target_desired_distance;
+ real_t target_desired_distance = 1.0;
real_t radius;
real_t neighbor_dist;
int max_neighbors;
real_t time_horizon;
real_t max_speed;
- real_t path_max_distance;
+ real_t path_max_distance = 3.0;
Vector2 target_location;
Vector<Vector2> navigation_path;
int nav_path_index;
- bool velocity_submitted;
+ bool velocity_submitted = false;
Vector2 prev_safe_velocity;
/// The submitted target velocity
Vector2 target_velocity;
- bool target_reached;
- bool navigation_finished;
+ bool target_reached = false;
+ bool navigation_finished = true;
// No initialized on purpose
uint32_t update_frame_id;
diff --git a/scene/2d/navigation_obstacle_2d.cpp b/scene/2d/navigation_obstacle_2d.cpp
index 50d02ca507..568023bbe2 100644
--- a/scene/2d/navigation_obstacle_2d.cpp
+++ b/scene/2d/navigation_obstacle_2d.cpp
@@ -36,7 +36,6 @@
#include "servers/navigation_server_2d.h"
void NavigationObstacle2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle2D::set_navigation_node);
ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle2D::get_navigation_node);
}
@@ -44,7 +43,6 @@ void NavigationObstacle2D::_bind_methods() {
void NavigationObstacle2D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
-
update_agent_shape();
// Search the navigation node and set it
@@ -53,10 +51,11 @@ void NavigationObstacle2D::_notification(int p_what) {
Node *p = get_parent();
while (p != nullptr) {
nav = Object::cast_to<Navigation2D>(p);
- if (nav != nullptr)
+ if (nav != nullptr) {
p = nullptr;
- else
+ } else {
p = p->get_parent();
+ }
}
set_navigation(nav);
@@ -78,9 +77,7 @@ void NavigationObstacle2D::_notification(int p_what) {
}
}
-NavigationObstacle2D::NavigationObstacle2D() :
- navigation(nullptr),
- agent(RID()) {
+NavigationObstacle2D::NavigationObstacle2D() {
agent = NavigationServer2D::get_singleton()->agent_create();
}
@@ -90,8 +87,9 @@ NavigationObstacle2D::~NavigationObstacle2D() {
}
void NavigationObstacle2D::set_navigation(Navigation2D *p_nav) {
- if (navigation == p_nav)
+ if (navigation == p_nav) {
return; // Pointless
+ }
navigation = p_nav;
NavigationServer2D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
@@ -142,8 +140,9 @@ void NavigationObstacle2D::update_agent_shape() {
radius *= MAX(s.x, s.y);
}
- if (radius == 0.0)
+ if (radius == 0.0) {
radius = 1.0; // Never a 0 radius
+ }
// Initialize the Agent as an object
NavigationServer2D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
diff --git a/scene/2d/navigation_obstacle_2d.h b/scene/2d/navigation_obstacle_2d.h
index 3935fe1bc5..bdef6f2843 100644
--- a/scene/2d/navigation_obstacle_2d.h
+++ b/scene/2d/navigation_obstacle_2d.h
@@ -38,7 +38,7 @@ class Navigation2D;
class NavigationObstacle2D : public Node {
GDCLASS(NavigationObstacle2D, Node);
- Navigation2D *navigation;
+ Navigation2D *navigation = nullptr;
RID agent;
diff --git a/scene/2d/navigation_region_2d.cpp b/scene/2d/navigation_region_2d.cpp
index d77fd5b097..72bde17428 100644
--- a/scene/2d/navigation_region_2d.cpp
+++ b/scene/2d/navigation_region_2d.cpp
@@ -40,7 +40,6 @@
#ifdef TOOLS_ENABLED
Rect2 NavigationPolygon::_edit_get_rect() const {
-
if (rect_cache_dirty) {
item_rect = Rect2();
bool first = true;
@@ -48,8 +47,9 @@ Rect2 NavigationPolygon::_edit_get_rect() const {
for (int i = 0; i < outlines.size(); i++) {
const Vector<Vector2> &outline = outlines[i];
const int outline_size = outline.size();
- if (outline_size < 3)
+ if (outline_size < 3) {
continue;
+ }
const Vector2 *p = outline.ptr();
for (int j = 0; j < outline_size; j++) {
if (first) {
@@ -67,21 +67,21 @@ Rect2 NavigationPolygon::_edit_get_rect() const {
}
bool NavigationPolygon::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
for (int i = 0; i < outlines.size(); i++) {
const Vector<Vector2> &outline = outlines[i];
const int outline_size = outline.size();
- if (outline_size < 3)
+ if (outline_size < 3) {
continue;
- if (Geometry::is_point_in_polygon(p_point, Variant(outline)))
+ }
+ if (Geometry::is_point_in_polygon(p_point, Variant(outline))) {
return true;
+ }
}
return false;
}
#endif
void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) {
-
{
MutexLock lock(navmesh_generation);
navmesh.unref();
@@ -91,12 +91,10 @@ void NavigationPolygon::set_vertices(const Vector<Vector2> &p_vertices) {
}
Vector<Vector2> NavigationPolygon::get_vertices() const {
-
return vertices;
}
-void NavigationPolygon::_set_polygons(const Array &p_array) {
-
+void NavigationPolygon::_set_polygons(const TypedArray<Vector<int32_t>> &p_array) {
{
MutexLock lock(navmesh_generation);
navmesh.unref();
@@ -108,7 +106,6 @@ void NavigationPolygon::_set_polygons(const Array &p_array) {
}
Array NavigationPolygon::_get_polygons() const {
-
Array ret;
ret.resize(polygons.size());
for (int i = 0; i < ret.size(); i++) {
@@ -118,8 +115,7 @@ Array NavigationPolygon::_get_polygons() const {
return ret;
}
-void NavigationPolygon::_set_outlines(const Array &p_array) {
-
+void NavigationPolygon::_set_outlines(const TypedArray<Vector<Vector2>> &p_array) {
outlines.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
outlines.write[i] = p_array[i];
@@ -128,7 +124,6 @@ void NavigationPolygon::_set_outlines(const Array &p_array) {
}
Array NavigationPolygon::_get_outlines() const {
-
Array ret;
ret.resize(outlines.size());
for (int i = 0; i < ret.size(); i++) {
@@ -139,7 +134,6 @@ Array NavigationPolygon::_get_outlines() const {
}
void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) {
-
Polygon polygon;
polygon.indices = p_polygon;
polygons.push_back(polygon);
@@ -150,22 +144,20 @@ void NavigationPolygon::add_polygon(const Vector<int> &p_polygon) {
}
void NavigationPolygon::add_outline_at_index(const Vector<Vector2> &p_outline, int p_index) {
-
outlines.insert(p_index, p_outline);
rect_cache_dirty = true;
}
int NavigationPolygon::get_polygon_count() const {
-
return polygons.size();
}
-Vector<int> NavigationPolygon::get_polygon(int p_idx) {
+Vector<int> NavigationPolygon::get_polygon(int p_idx) {
ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>());
return polygons[p_idx].indices;
}
-void NavigationPolygon::clear_polygons() {
+void NavigationPolygon::clear_polygons() {
polygons.clear();
{
MutexLock lock(navmesh_generation);
@@ -200,13 +192,11 @@ Ref<NavigationMesh> NavigationPolygon::get_mesh() {
}
void NavigationPolygon::add_outline(const Vector<Vector2> &p_outline) {
-
outlines.push_back(p_outline);
rect_cache_dirty = true;
}
int NavigationPolygon::get_outline_count() const {
-
return outlines.size();
}
@@ -217,7 +207,6 @@ void NavigationPolygon::set_outline(int p_idx, const Vector<Vector2> &p_outline)
}
void NavigationPolygon::remove_outline(int p_idx) {
-
ERR_FAIL_INDEX(p_idx, outlines.size());
outlines.remove(p_idx);
rect_cache_dirty = true;
@@ -229,12 +218,11 @@ Vector<Vector2> NavigationPolygon::get_outline(int p_idx) const {
}
void NavigationPolygon::clear_outlines() {
-
outlines.clear();
rect_cache_dirty = true;
}
-void NavigationPolygon::make_polygons_from_outlines() {
+void NavigationPolygon::make_polygons_from_outlines() {
{
MutexLock lock(navmesh_generation);
navmesh.unref();
@@ -244,11 +232,11 @@ void NavigationPolygon::make_polygons_from_outlines() {
Vector2 outside_point(-1e10, -1e10);
for (int i = 0; i < outlines.size(); i++) {
-
Vector<Vector2> ol = outlines[i];
int olsize = ol.size();
- if (olsize < 3)
+ if (olsize < 3) {
continue;
+ }
const Vector2 *r = ol.ptr();
for (int j = 0; j < olsize; j++) {
outside_point.x = MAX(r[j].x, outside_point.x);
@@ -259,28 +247,28 @@ void NavigationPolygon::make_polygons_from_outlines() {
outside_point += Vector2(0.7239784, 0.819238); //avoid precision issues
for (int i = 0; i < outlines.size(); i++) {
-
Vector<Vector2> ol = outlines[i];
int olsize = ol.size();
- if (olsize < 3)
+ if (olsize < 3) {
continue;
+ }
const Vector2 *r = ol.ptr();
int interscount = 0;
//test if this is an outer outline
for (int k = 0; k < outlines.size(); k++) {
-
- if (i == k)
+ if (i == k) {
continue; //no self intersect
+ }
Vector<Vector2> ol2 = outlines[k];
int olsize2 = ol2.size();
- if (olsize2 < 3)
+ if (olsize2 < 3) {
continue;
+ }
const Vector2 *r2 = ol2.ptr();
for (int l = 0; l < olsize2; l++) {
-
if (Geometry::segment_intersects_segment_2d(r[0], outside_point, r2[l], r2[(l + 1) % olsize2], nullptr)) {
interscount++;
}
@@ -295,9 +283,9 @@ void NavigationPolygon::make_polygons_from_outlines() {
tp[j] = r[j];
}
- if (outer)
+ if (outer) {
tp.SetOrientation(TRIANGULATOR_CCW);
- else {
+ } else {
tp.SetOrientation(TRIANGULATOR_CW);
tp.SetHole(true);
}
@@ -316,13 +304,11 @@ void NavigationPolygon::make_polygons_from_outlines() {
Map<Vector2, int> points;
for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) {
-
TriangulatorPoly &tp = I->get();
struct Polygon p;
for (int64_t i = 0; i < tp.GetNumPoints(); i++) {
-
Map<Vector2, int>::Element *E = points.find(tp[i]);
if (!E) {
E = points.insert(tp[i], vertices.size());
@@ -338,7 +324,6 @@ void NavigationPolygon::make_polygons_from_outlines() {
}
void NavigationPolygon::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_vertices", "vertices"), &NavigationPolygon::set_vertices);
ClassDB::bind_method(D_METHOD("get_vertices"), &NavigationPolygon::get_vertices);
@@ -367,68 +352,52 @@ void NavigationPolygon::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "outlines", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_outlines", "_get_outlines");
}
-NavigationPolygon::NavigationPolygon() :
- rect_cache_dirty(true) {
-}
-
-NavigationPolygon::~NavigationPolygon() {
-}
-
void NavigationRegion2D::set_enabled(bool p_enabled) {
-
- if (enabled == p_enabled)
+ if (enabled == p_enabled) {
return;
+ }
enabled = p_enabled;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
if (!enabled) {
-
NavigationServer2D::get_singleton()->region_set_map(region, RID());
} else {
-
if (navigation) {
-
NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
}
}
- if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())
+ if (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) {
update();
+ }
}
bool NavigationRegion2D::is_enabled() const {
-
return enabled;
}
/////////////////////////////
#ifdef TOOLS_ENABLED
Rect2 NavigationRegion2D::_edit_get_rect() const {
-
return navpoly.is_valid() ? navpoly->_edit_get_rect() : Rect2();
}
bool NavigationRegion2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
return navpoly.is_valid() ? navpoly->_edit_is_selected_on_click(p_point, p_tolerance) : false;
}
#endif
void NavigationRegion2D::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
-
Node2D *c = this;
while (c) {
-
navigation = Object::cast_to<Navigation2D>(c);
if (navigation) {
-
if (enabled) {
-
NavigationServer2D::get_singleton()->region_set_map(region, navigation->get_rid());
}
break;
@@ -439,26 +408,22 @@ void NavigationRegion2D::_notification(int p_what) {
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
NavigationServer2D::get_singleton()->region_set_transform(region, get_global_transform());
} break;
case NOTIFICATION_EXIT_TREE: {
-
if (navigation) {
-
NavigationServer2D::get_singleton()->region_set_map(region, RID());
}
navigation = nullptr;
} break;
case NOTIFICATION_DRAW: {
-
if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()) && navpoly.is_valid()) {
-
Vector<Vector2> verts = navpoly->get_vertices();
int vsize = verts.size();
- if (vsize < 3)
+ if (vsize < 3) {
return;
+ }
Color color;
if (enabled) {
@@ -484,10 +449,8 @@ void NavigationRegion2D::_notification(int p_what) {
Vector<int> polygon = navpoly->get_polygon(i);
for (int j = 2; j < polygon.size(); j++) {
-
int kofs[3] = { 0, j - 1, j };
for (int k = 0; k < 3; k++) {
-
int idx = polygon[kofs[k]];
ERR_FAIL_INDEX(idx, vsize);
indices.push_back(idx);
@@ -501,7 +464,6 @@ void NavigationRegion2D::_notification(int p_what) {
}
void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_navpoly) {
-
if (p_navpoly == navpoly) {
return;
}
@@ -523,27 +485,25 @@ void NavigationRegion2D::set_navigation_polygon(const Ref<NavigationPolygon> &p_
}
Ref<NavigationPolygon> NavigationRegion2D::get_navigation_polygon() const {
-
return navpoly;
}
void NavigationRegion2D::_navpoly_changed() {
-
- if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint()))
+ if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_navigation_hint())) {
update();
+ }
}
String NavigationRegion2D::get_configuration_warning() const {
-
- if (!is_visible_in_tree() || !is_inside_tree())
+ if (!is_visible_in_tree() || !is_inside_tree()) {
return String();
+ }
if (!navpoly.is_valid()) {
return TTR("A NavigationPolygon resource must be set or created for this node to work. Please set a property or draw a polygon.");
}
const Node2D *c = this;
while (c) {
-
if (Object::cast_to<Navigation2D>(c)) {
return String();
}
@@ -555,7 +515,6 @@ String NavigationRegion2D::get_configuration_warning() const {
}
void NavigationRegion2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_navigation_polygon", "navpoly"), &NavigationRegion2D::set_navigation_polygon);
ClassDB::bind_method(D_METHOD("get_navigation_polygon"), &NavigationRegion2D::get_navigation_polygon);
@@ -569,12 +528,8 @@ void NavigationRegion2D::_bind_methods() {
}
NavigationRegion2D::NavigationRegion2D() {
-
- enabled = true;
set_notify_transform(true);
region = NavigationServer2D::get_singleton()->region_create();
-
- navigation = nullptr;
}
NavigationRegion2D::~NavigationRegion2D() {
diff --git a/scene/2d/navigation_region_2d.h b/scene/2d/navigation_region_2d.h
index 73e056a353..07cf4d6668 100644
--- a/scene/2d/navigation_region_2d.h
+++ b/scene/2d/navigation_region_2d.h
@@ -35,7 +35,6 @@
#include "scene/resources/navigation_mesh.h"
class NavigationPolygon : public Resource {
-
GDCLASS(NavigationPolygon, Resource);
Vector<Vector2> vertices;
@@ -46,7 +45,7 @@ class NavigationPolygon : public Resource {
Vector<Vector<Vector2>> outlines;
mutable Rect2 item_rect;
- mutable bool rect_cache_dirty;
+ mutable bool rect_cache_dirty = true;
Mutex navmesh_generation;
// Navigation mesh
@@ -55,10 +54,10 @@ class NavigationPolygon : public Resource {
protected:
static void _bind_methods();
- void _set_polygons(const Array &p_array);
+ void _set_polygons(const TypedArray<Vector<int32_t>> &p_array);
Array _get_polygons() const;
- void _set_outlines(const Array &p_array);
+ void _set_outlines(const TypedArray<Vector<Vector2>> &p_array);
Array _get_outlines() const;
public:
@@ -88,19 +87,18 @@ public:
Ref<NavigationMesh> get_mesh();
- NavigationPolygon();
- ~NavigationPolygon();
+ NavigationPolygon() {}
+ ~NavigationPolygon() {}
};
class Navigation2D;
class NavigationRegion2D : public Node2D {
-
GDCLASS(NavigationRegion2D, Node2D);
- bool enabled;
+ bool enabled = true;
RID region;
- Navigation2D *navigation;
+ Navigation2D *navigation = nullptr;
Ref<NavigationPolygon> navpoly;
void _navpoly_changed();
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index ac8a77b6cb..72250e96b3 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -37,25 +37,27 @@
#ifdef TOOLS_ENABLED
Dictionary Node2D::_edit_get_state() const {
-
Dictionary state;
state["position"] = get_position();
state["rotation"] = get_rotation();
state["scale"] = get_scale();
+ state["skew"] = get_skew();
return state;
}
void Node2D::_edit_set_state(const Dictionary &p_state) {
-
pos = p_state["position"];
angle = p_state["rotation"];
_scale = p_state["scale"];
+ skew = p_state["skew"];
_update_transform();
_change_notify("rotation");
_change_notify("rotation_degrees");
_change_notify("scale");
+ _change_notify("skew");
+ _change_notify("skew_degrees");
_change_notify("position");
}
@@ -96,22 +98,26 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) {
Rect2 r = _edit_get_rect();
Vector2 zero_offset;
- if (r.size.x != 0)
+ if (r.size.x != 0) {
zero_offset.x = -r.position.x / r.size.x;
- if (r.size.y != 0)
+ }
+ if (r.size.y != 0) {
zero_offset.y = -r.position.y / r.size.y;
+ }
Size2 new_scale(1, 1);
- if (r.size.x != 0)
+ if (r.size.x != 0) {
new_scale.x = p_edit_rect.size.x / r.size.x;
- if (r.size.y != 0)
+ }
+ if (r.size.y != 0) {
new_scale.y = p_edit_rect.size.y / r.size.y;
+ }
Point2 new_pos = p_edit_rect.position + p_edit_rect.size * zero_offset;
Transform2D postxf;
- postxf.set_rotation_and_scale(angle, _scale);
+ postxf.set_rotation_scale_and_skew(angle, _scale, skew);
new_pos = postxf.xform(new_pos);
pos += new_pos;
@@ -124,140 +130,161 @@ void Node2D::_edit_set_rect(const Rect2 &p_edit_rect) {
#endif
void Node2D::_update_xform_values() {
-
pos = _mat.elements[2];
angle = _mat.get_rotation();
_scale = _mat.get_scale();
+ skew = _mat.get_skew();
_xform_dirty = false;
}
void Node2D::_update_transform() {
-
- _mat.set_rotation_and_scale(angle, _scale);
+ _mat.set_rotation_scale_and_skew(angle, _scale, skew);
_mat.elements[2] = pos;
RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), _mat);
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_notify_transform();
}
void Node2D::set_position(const Point2 &p_pos) {
-
- if (_xform_dirty)
+ if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
+ }
pos = p_pos;
_update_transform();
_change_notify("position");
}
void Node2D::set_rotation(float p_radians) {
-
- if (_xform_dirty)
+ if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
+ }
angle = p_radians;
_update_transform();
_change_notify("rotation");
_change_notify("rotation_degrees");
}
-void Node2D::set_rotation_degrees(float p_degrees) {
+void Node2D::set_skew(float p_radians) {
+ if (_xform_dirty) {
+ ((Node2D *)this)->_update_xform_values();
+ }
+ skew = p_radians;
+ _update_transform();
+ _change_notify("skew");
+ _change_notify("skew_degrees");
+}
+void Node2D::set_rotation_degrees(float p_degrees) {
set_rotation(Math::deg2rad(p_degrees));
}
-void Node2D::set_scale(const Size2 &p_scale) {
+void Node2D::set_skew_degrees(float p_degrees) {
+ set_skew(Math::deg2rad(p_degrees));
+}
- if (_xform_dirty)
+void Node2D::set_scale(const Size2 &p_scale) {
+ if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
+ }
_scale = p_scale;
// Avoid having 0 scale values, can lead to errors in physics and rendering.
- if (_scale.x == 0)
+ if (_scale.x == 0) {
_scale.x = CMP_EPSILON;
- if (_scale.y == 0)
+ }
+ if (_scale.y == 0) {
_scale.y = CMP_EPSILON;
+ }
_update_transform();
_change_notify("scale");
}
Point2 Node2D::get_position() const {
-
- if (_xform_dirty)
+ if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
+ }
return pos;
}
float Node2D::get_rotation() const {
- if (_xform_dirty)
+ if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
+ }
return angle;
}
-float Node2D::get_rotation_degrees() const {
+float Node2D::get_skew() const {
+ if (_xform_dirty) {
+ ((Node2D *)this)->_update_xform_values();
+ }
+ return skew;
+}
+
+float Node2D::get_rotation_degrees() const {
return Math::rad2deg(get_rotation());
}
+float Node2D::get_skew_degrees() const {
+ return Math::rad2deg(get_skew());
+}
+
Size2 Node2D::get_scale() const {
- if (_xform_dirty)
+ if (_xform_dirty) {
((Node2D *)this)->_update_xform_values();
+ }
return _scale;
}
Transform2D Node2D::get_transform() const {
-
return _mat;
}
void Node2D::rotate(float p_radians) {
-
set_rotation(get_rotation() + p_radians);
}
void Node2D::translate(const Vector2 &p_amount) {
-
set_position(get_position() + p_amount);
}
void Node2D::global_translate(const Vector2 &p_amount) {
-
set_global_position(get_global_position() + p_amount);
}
void Node2D::apply_scale(const Size2 &p_amount) {
-
set_scale(get_scale() * p_amount);
}
void Node2D::move_x(float p_delta, bool p_scaled) {
-
Transform2D t = get_transform();
Vector2 m = t[0];
- if (!p_scaled)
+ if (!p_scaled) {
m.normalize();
+ }
set_position(t[2] + m * p_delta);
}
void Node2D::move_y(float p_delta, bool p_scaled) {
-
Transform2D t = get_transform();
Vector2 m = t[1];
- if (!p_scaled)
+ if (!p_scaled) {
m.normalize();
+ }
set_position(t[2] + m * p_delta);
}
Point2 Node2D::get_global_position() const {
-
return get_global_transform().get_origin();
}
void Node2D::set_global_position(const Point2 &p_pos) {
-
Transform2D inv;
CanvasItem *pi = get_parent_item();
if (pi) {
@@ -269,12 +296,10 @@ void Node2D::set_global_position(const Point2 &p_pos) {
}
float Node2D::get_global_rotation() const {
-
return get_global_transform().get_rotation();
}
void Node2D::set_global_rotation(float p_radians) {
-
CanvasItem *pi = get_parent_item();
if (pi) {
const float parent_global_rot = pi->get_global_transform().get_rotation();
@@ -285,22 +310,18 @@ void Node2D::set_global_rotation(float p_radians) {
}
float Node2D::get_global_rotation_degrees() const {
-
return Math::rad2deg(get_global_rotation());
}
void Node2D::set_global_rotation_degrees(float p_degrees) {
-
set_global_rotation(Math::deg2rad(p_degrees));
}
Size2 Node2D::get_global_scale() const {
-
return get_global_transform().get_scale();
}
void Node2D::set_global_scale(const Size2 &p_scale) {
-
CanvasItem *pi = get_parent_item();
if (pi) {
const Size2 parent_global_scale = pi->get_global_transform().get_scale();
@@ -311,29 +332,28 @@ void Node2D::set_global_scale(const Size2 &p_scale) {
}
void Node2D::set_transform(const Transform2D &p_transform) {
-
_mat = p_transform;
_xform_dirty = true;
RenderingServer::get_singleton()->canvas_item_set_transform(get_canvas_item(), _mat);
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_notify_transform();
}
void Node2D::set_global_transform(const Transform2D &p_transform) {
-
CanvasItem *pi = get_parent_item();
- if (pi)
+ if (pi) {
set_transform(pi->get_global_transform().affine_inverse() * p_transform);
- else
+ } else {
set_transform(p_transform);
+ }
}
void Node2D::set_z_index(int p_z) {
-
ERR_FAIL_COND(p_z < RS::CANVAS_ITEM_Z_MIN);
ERR_FAIL_COND(p_z > RS::CANVAS_ITEM_Z_MAX);
z_index = p_z;
@@ -342,67 +362,65 @@ void Node2D::set_z_index(int p_z) {
}
void Node2D::set_z_as_relative(bool p_enabled) {
-
- if (z_relative == p_enabled)
+ if (z_relative == p_enabled) {
return;
+ }
z_relative = p_enabled;
RS::get_singleton()->canvas_item_set_z_as_relative_to_parent(get_canvas_item(), p_enabled);
}
bool Node2D::is_z_relative() const {
-
return z_relative;
}
int Node2D::get_z_index() const {
-
return z_index;
}
Transform2D Node2D::get_relative_transform_to_parent(const Node *p_parent) const {
-
- if (p_parent == this)
+ if (p_parent == this) {
return Transform2D();
+ }
Node2D *parent_2d = Object::cast_to<Node2D>(get_parent());
ERR_FAIL_COND_V(!parent_2d, Transform2D());
- if (p_parent == parent_2d)
+ if (p_parent == parent_2d) {
return get_transform();
- else
+ } else {
return parent_2d->get_relative_transform_to_parent(p_parent) * get_transform();
+ }
}
void Node2D::look_at(const Vector2 &p_pos) {
-
rotate(get_angle_to(p_pos));
}
float Node2D::get_angle_to(const Vector2 &p_pos) const {
-
return (to_local(p_pos) * get_scale()).angle();
}
Point2 Node2D::to_local(Point2 p_global) const {
-
return get_global_transform().affine_inverse().xform(p_global);
}
Point2 Node2D::to_global(Point2 p_local) const {
-
return get_global_transform().xform(p_local);
}
void Node2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_position", "position"), &Node2D::set_position);
ClassDB::bind_method(D_METHOD("set_rotation", "radians"), &Node2D::set_rotation);
ClassDB::bind_method(D_METHOD("set_rotation_degrees", "degrees"), &Node2D::set_rotation_degrees);
+ ClassDB::bind_method(D_METHOD("set_skew", "radians"), &Node2D::set_skew);
+ ClassDB::bind_method(D_METHOD("set_skew_degrees", "degrees"), &Node2D::set_skew_degrees);
ClassDB::bind_method(D_METHOD("set_scale", "scale"), &Node2D::set_scale);
ClassDB::bind_method(D_METHOD("get_position"), &Node2D::get_position);
ClassDB::bind_method(D_METHOD("get_rotation"), &Node2D::get_rotation);
ClassDB::bind_method(D_METHOD("get_rotation_degrees"), &Node2D::get_rotation_degrees);
+ ClassDB::bind_method(D_METHOD("get_skew"), &Node2D::get_skew);
+ ClassDB::bind_method(D_METHOD("get_skew_degrees"), &Node2D::get_skew_degrees);
ClassDB::bind_method(D_METHOD("get_scale"), &Node2D::get_scale);
ClassDB::bind_method(D_METHOD("rotate", "radians"), &Node2D::rotate);
@@ -443,6 +461,8 @@ void Node2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_rotation", "get_rotation");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rotation_degrees", PROPERTY_HINT_RANGE, "-360,360,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scale"), "set_scale", "get_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "skew", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_skew", "get_skew");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "skew_degrees", PROPERTY_HINT_RANGE, "-89.9,89.9,0.1", PROPERTY_USAGE_EDITOR), "set_skew_degrees", "get_skew_degrees");
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "transform", PROPERTY_HINT_NONE, "", 0), "set_transform", "get_transform");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position", PROPERTY_HINT_NONE, "", 0), "set_global_position", "get_global_position");
@@ -457,9 +477,9 @@ void Node2D::_bind_methods() {
}
Node2D::Node2D() {
-
angle = 0;
_scale = Vector2(1, 1);
+ skew = 0;
_xform_dirty = false;
z_index = 0;
z_relative = true;
diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h
index abed05ed0c..827c192585 100644
--- a/scene/2d/node_2d.h
+++ b/scene/2d/node_2d.h
@@ -34,12 +34,12 @@
#include "scene/main/canvas_item.h"
class Node2D : public CanvasItem {
-
GDCLASS(Node2D, CanvasItem);
Point2 pos;
float angle;
Size2 _scale;
+ float skew;
int z_index;
bool z_relative;
@@ -75,6 +75,8 @@ public:
void set_position(const Point2 &p_pos);
void set_rotation(float p_radians);
void set_rotation_degrees(float p_degrees);
+ void set_skew(float p_radians);
+ void set_skew_degrees(float p_radians);
void set_scale(const Size2 &p_scale);
void rotate(float p_radians);
@@ -86,7 +88,9 @@ public:
Point2 get_position() const;
float get_rotation() const;
+ float get_skew() const;
float get_rotation_degrees() const;
+ float get_skew_degrees() const;
Size2 get_scale() const;
Point2 get_global_position() const;
diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp
index 0d5f74a265..416622e6d5 100644
--- a/scene/2d/parallax_background.cpp
+++ b/scene/2d/parallax_background.cpp
@@ -32,24 +32,19 @@
#include "parallax_layer.h"
void ParallaxBackground::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
group_name = "__cameras_" + itos(get_viewport().get_id());
add_to_group(group_name);
} break;
case NOTIFICATION_EXIT_TREE: {
-
remove_from_group(group_name);
} break;
}
}
void ParallaxBackground::_camera_moved(const Transform2D &p_transform, const Point2 &p_screen_offset) {
-
screen_offset = p_screen_offset;
set_scroll_scale(p_transform.get_scale().dot(Vector2(0.5, 0.5)));
@@ -57,26 +52,23 @@ void ParallaxBackground::_camera_moved(const Transform2D &p_transform, const Poi
}
void ParallaxBackground::set_scroll_scale(float p_scale) {
-
scale = p_scale;
}
float ParallaxBackground::get_scroll_scale() const {
-
return scale;
}
void ParallaxBackground::set_scroll_offset(const Point2 &p_ofs) {
-
offset = p_ofs;
_update_scroll();
}
void ParallaxBackground::_update_scroll() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
Vector2 ofs = base_offset + offset * base_scale;
@@ -84,103 +76,91 @@ void ParallaxBackground::_update_scroll() {
ofs = -ofs;
if (limit_begin.x < limit_end.x) {
-
- if (ofs.x < limit_begin.x)
+ if (ofs.x < limit_begin.x) {
ofs.x = limit_begin.x;
- else if (ofs.x + vps.x > limit_end.x)
+ } else if (ofs.x + vps.x > limit_end.x) {
ofs.x = limit_end.x - vps.x;
+ }
}
if (limit_begin.y < limit_end.y) {
-
- if (ofs.y < limit_begin.y)
+ if (ofs.y < limit_begin.y) {
ofs.y = limit_begin.y;
- else if (ofs.y + vps.y > limit_end.y)
+ } else if (ofs.y + vps.y > limit_end.y) {
ofs.y = limit_end.y - vps.y;
+ }
}
ofs = -ofs;
final_offset = ofs;
for (int i = 0; i < get_child_count(); i++) {
-
ParallaxLayer *l = Object::cast_to<ParallaxLayer>(get_child(i));
- if (!l)
+ if (!l) {
continue;
+ }
- if (ignore_camera_zoom)
+ if (ignore_camera_zoom) {
l->set_base_offset_and_scale(ofs, 1.0, screen_offset);
- else
+ } else {
l->set_base_offset_and_scale(ofs, scale, screen_offset);
+ }
}
}
Point2 ParallaxBackground::get_scroll_offset() const {
-
return offset;
}
void ParallaxBackground::set_scroll_base_offset(const Point2 &p_ofs) {
-
base_offset = p_ofs;
_update_scroll();
}
Point2 ParallaxBackground::get_scroll_base_offset() const {
-
return base_offset;
}
void ParallaxBackground::set_scroll_base_scale(const Point2 &p_ofs) {
-
base_scale = p_ofs;
_update_scroll();
}
Point2 ParallaxBackground::get_scroll_base_scale() const {
-
return base_scale;
}
void ParallaxBackground::set_limit_begin(const Point2 &p_ofs) {
-
limit_begin = p_ofs;
_update_scroll();
}
Point2 ParallaxBackground::get_limit_begin() const {
-
return limit_begin;
}
void ParallaxBackground::set_limit_end(const Point2 &p_ofs) {
-
limit_end = p_ofs;
_update_scroll();
}
Point2 ParallaxBackground::get_limit_end() const {
-
return limit_end;
}
void ParallaxBackground::set_ignore_camera_zoom(bool ignore) {
-
ignore_camera_zoom = ignore;
}
bool ParallaxBackground::is_ignore_camera_zoom() {
-
return ignore_camera_zoom;
}
Vector2 ParallaxBackground::get_final_offset() const {
-
return final_offset;
}
void ParallaxBackground::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_camera_moved"), &ParallaxBackground::_camera_moved);
ClassDB::bind_method(D_METHOD("set_scroll_offset", "ofs"), &ParallaxBackground::set_scroll_offset);
ClassDB::bind_method(D_METHOD("get_scroll_offset"), &ParallaxBackground::get_scroll_offset);
@@ -205,7 +185,6 @@ void ParallaxBackground::_bind_methods() {
}
ParallaxBackground::ParallaxBackground() {
-
scale = 1.0;
set_layer(-100); //behind all by default
diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h
index 25ccd910d1..1667880ddb 100644
--- a/scene/2d/parallax_background.h
+++ b/scene/2d/parallax_background.h
@@ -36,7 +36,6 @@
#include "scene/main/canvas_layer.h"
class ParallaxBackground : public CanvasLayer {
-
GDCLASS(ParallaxBackground, CanvasLayer);
Point2 offset;
diff --git a/scene/2d/parallax_layer.cpp b/scene/2d/parallax_layer.cpp
index 181f0f158c..4ed335dec8 100644
--- a/scene/2d/parallax_layer.cpp
+++ b/scene/2d/parallax_layer.cpp
@@ -34,7 +34,6 @@
#include "parallax_background.h"
void ParallaxLayer::set_motion_scale(const Size2 &p_scale) {
-
motion_scale = p_scale;
ParallaxBackground *pb = Object::cast_to<ParallaxBackground>(get_parent());
@@ -46,12 +45,10 @@ void ParallaxLayer::set_motion_scale(const Size2 &p_scale) {
}
Size2 ParallaxLayer::get_motion_scale() const {
-
return motion_scale;
}
void ParallaxLayer::set_motion_offset(const Size2 &p_offset) {
-
motion_offset = p_offset;
ParallaxBackground *pb = Object::cast_to<ParallaxBackground>(get_parent());
@@ -63,18 +60,16 @@ void ParallaxLayer::set_motion_offset(const Size2 &p_offset) {
}
Size2 ParallaxLayer::get_motion_offset() const {
-
return motion_offset;
}
void ParallaxLayer::_update_mirroring() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
ParallaxBackground *pb = Object::cast_to<ParallaxBackground>(get_parent());
if (pb) {
-
RID c = pb->get_canvas();
RID ci = get_canvas_item();
Point2 mirrorScale = mirroring * get_scale();
@@ -83,33 +78,29 @@ void ParallaxLayer::_update_mirroring() {
}
void ParallaxLayer::set_mirroring(const Size2 &p_mirroring) {
-
mirroring = p_mirroring;
- if (mirroring.x < 0)
+ if (mirroring.x < 0) {
mirroring.x = 0;
- if (mirroring.y < 0)
+ }
+ if (mirroring.y < 0) {
mirroring.y = 0;
+ }
_update_mirroring();
}
Size2 ParallaxLayer::get_mirroring() const {
-
return mirroring;
}
void ParallaxLayer::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
orig_offset = get_position();
orig_scale = get_scale();
_update_mirroring();
} break;
case NOTIFICATION_EXIT_TREE: {
-
set_position(orig_offset);
set_scale(orig_scale);
} break;
@@ -119,10 +110,12 @@ void ParallaxLayer::_notification(int p_what) {
void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_scale, const Point2 &p_screen_offset) {
screen_offset = p_screen_offset;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
- if (Engine::get_singleton()->is_editor_hint())
+ }
+ if (Engine::get_singleton()->is_editor_hint()) {
return;
+ }
Point2 new_ofs = (screen_offset + (p_offset - screen_offset) * motion_scale) + motion_offset * p_scale + orig_offset * p_scale;
@@ -143,7 +136,6 @@ void ParallaxLayer::set_base_offset_and_scale(const Point2 &p_offset, float p_sc
}
String ParallaxLayer::get_configuration_warning() const {
-
if (!Object::cast_to<ParallaxBackground>(get_parent())) {
return TTR("ParallaxLayer node only works when set as child of a ParallaxBackground node.");
}
@@ -152,7 +144,6 @@ String ParallaxLayer::get_configuration_warning() const {
}
void ParallaxLayer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_motion_scale", "scale"), &ParallaxLayer::set_motion_scale);
ClassDB::bind_method(D_METHOD("get_motion_scale"), &ParallaxLayer::get_motion_scale);
ClassDB::bind_method(D_METHOD("set_motion_offset", "offset"), &ParallaxLayer::set_motion_offset);
diff --git a/scene/2d/parallax_layer.h b/scene/2d/parallax_layer.h
index ba59184649..1f001943b5 100644
--- a/scene/2d/parallax_layer.h
+++ b/scene/2d/parallax_layer.h
@@ -34,7 +34,6 @@
#include "scene/2d/node_2d.h"
class ParallaxLayer : public Node2D {
-
GDCLASS(ParallaxLayer, Node2D);
Point2 orig_offset;
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index ed8481db4a..046e4dbd41 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -39,16 +39,14 @@
#ifdef TOOLS_ENABLED
Rect2 Path2D::_edit_get_rect() const {
-
- if (!curve.is_valid() || curve->get_point_count() == 0)
+ if (!curve.is_valid() || curve->get_point_count() == 0) {
return Rect2(0, 0, 0, 0);
+ }
Rect2 aabb = Rect2(curve->get_point_position(0), Vector2(0, 0));
for (int i = 0; i < curve->get_point_count(); i++) {
-
for (int j = 0; j <= 8; j++) {
-
real_t frac = j / 8.0;
Vector2 p = curve->interpolate(i, frac);
aabb.expand_to(p);
@@ -63,7 +61,6 @@ bool Path2D::_edit_use_rect() const {
}
bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
if (curve.is_null()) {
return false;
}
@@ -77,8 +74,9 @@ bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
s[1] = curve->interpolate(i, frac);
Vector2 p = Geometry::get_closest_point_to_segment_2d(p_point, s);
- if (p.distance_to(p_point) <= p_tolerance)
+ if (p.distance_to(p_point) <= p_tolerance) {
return true;
+ }
s[0] = s[1];
}
@@ -89,7 +87,6 @@ bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_toleranc
#endif
void Path2D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW && curve.is_valid()) {
//draw the curve!!
@@ -102,14 +99,12 @@ void Path2D::_notification(int p_what) {
#else
const float line_width = 2;
#endif
- const Color color = Color(1.0, 1.0, 1.0, 1.0);
+ const Color color = Color(0.5, 0.6, 1.0, 0.7);
for (int i = 0; i < curve->get_point_count(); i++) {
-
Vector2 prev_p = curve->get_point_position(i);
for (int j = 1; j <= 8; j++) {
-
real_t frac = j / 8.0;
Vector2 p = curve->interpolate(i, frac);
draw_line(prev_p, p, color, line_width);
@@ -132,7 +127,6 @@ void Path2D::_curve_changed() {
}
void Path2D::set_curve(const Ref<Curve2D> &p_curve) {
-
if (curve.is_valid()) {
curve->disconnect("changed", callable_mp(this, &Path2D::_curve_changed));
}
@@ -147,12 +141,10 @@ void Path2D::set_curve(const Ref<Curve2D> &p_curve) {
}
Ref<Curve2D> Path2D::get_curve() const {
-
return curve;
}
void Path2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_curve", "curve"), &Path2D::set_curve);
ClassDB::bind_method(D_METHOD("get_curve"), &Path2D::get_curve);
@@ -160,21 +152,20 @@ void Path2D::_bind_methods() {
}
Path2D::Path2D() {
-
set_curve(Ref<Curve2D>(memnew(Curve2D))); //create one by default
- set_self_modulate(Color(0.5, 0.6, 1.0, 0.7));
}
/////////////////////////////////////////////////////////////////////////////////
void PathFollow2D::_update_transform() {
-
- if (!path)
+ if (!path) {
return;
+ }
Ref<Curve2D> c = path->get_curve();
- if (!c.is_valid())
+ if (!c.is_valid()) {
return;
+ }
float path_length = c->get_baked_length();
if (path_length == 0) {
@@ -220,7 +211,6 @@ void PathFollow2D::_update_transform() {
set_rotation(tangent_to_curve.angle());
} else {
-
pos.x += h_offset;
pos.y += v_offset;
}
@@ -229,11 +219,8 @@ void PathFollow2D::_update_transform() {
}
void PathFollow2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
path = Object::cast_to<Path2D>(get_parent());
if (path) {
_update_transform();
@@ -241,38 +228,34 @@ void PathFollow2D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
-
path = nullptr;
} break;
}
}
void PathFollow2D::set_cubic_interpolation(bool p_enable) {
-
cubic = p_enable;
}
bool PathFollow2D::get_cubic_interpolation() const {
-
return cubic;
}
void PathFollow2D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "offset") {
-
float max = 10000;
- if (path && path->get_curve().is_valid())
+ if (path && path->get_curve().is_valid()) {
max = path->get_curve()->get_baked_length();
+ }
property.hint_string = "0," + rtos(max) + ",0.01,or_lesser,or_greater";
}
}
String PathFollow2D::get_configuration_warning() const {
-
- if (!is_visible_in_tree() || !is_inside_tree())
+ if (!is_visible_in_tree() || !is_inside_tree()) {
return String();
+ }
if (!Object::cast_to<Path2D>(get_parent())) {
return TTR("PathFollow2D only works when set as a child of a Path2D node.");
@@ -282,7 +265,6 @@ String PathFollow2D::get_configuration_warning() const {
}
void PathFollow2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &PathFollow2D::set_offset);
ClassDB::bind_method(D_METHOD("get_offset"), &PathFollow2D::get_offset);
@@ -318,7 +300,6 @@ void PathFollow2D::_bind_methods() {
}
void PathFollow2D::set_offset(float p_offset) {
-
offset = p_offset;
if (path) {
if (path->get_curve().is_valid()) {
@@ -341,81 +322,71 @@ void PathFollow2D::set_offset(float p_offset) {
}
void PathFollow2D::set_h_offset(float p_h_offset) {
-
h_offset = p_h_offset;
- if (path)
+ if (path) {
_update_transform();
+ }
}
float PathFollow2D::get_h_offset() const {
-
return h_offset;
}
void PathFollow2D::set_v_offset(float p_v_offset) {
-
v_offset = p_v_offset;
- if (path)
+ if (path) {
_update_transform();
+ }
}
float PathFollow2D::get_v_offset() const {
-
return v_offset;
}
float PathFollow2D::get_offset() const {
-
return offset;
}
void PathFollow2D::set_unit_offset(float p_unit_offset) {
-
- if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length())
+ if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) {
set_offset(p_unit_offset * path->get_curve()->get_baked_length());
+ }
}
float PathFollow2D::get_unit_offset() const {
-
- if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length())
+ if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) {
return get_offset() / path->get_curve()->get_baked_length();
- else
+ } else {
return 0;
+ }
}
void PathFollow2D::set_lookahead(float p_lookahead) {
-
lookahead = p_lookahead;
}
float PathFollow2D::get_lookahead() const {
-
return lookahead;
}
void PathFollow2D::set_rotate(bool p_rotate) {
-
rotate = p_rotate;
_update_transform();
}
bool PathFollow2D::is_rotating() const {
-
return rotate;
}
void PathFollow2D::set_loop(bool p_loop) {
-
loop = p_loop;
}
bool PathFollow2D::has_loop() const {
-
return loop;
}
PathFollow2D::PathFollow2D() {
-
offset = 0;
h_offset = 0;
v_offset = 0;
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index 35cf8211f4..288ef698e7 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -35,7 +35,6 @@
#include "scene/resources/curve.h"
class Path2D : public Node2D {
-
GDCLASS(Path2D, Node2D);
Ref<Curve2D> curve;
@@ -60,7 +59,6 @@ public:
};
class PathFollow2D : public Node2D {
-
GDCLASS(PathFollow2D, Node2D);
public:
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 21dc9537ec..ae448129bc 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -43,18 +43,15 @@ void PhysicsBody2D::_notification(int p_what) {
}
void PhysicsBody2D::_set_layers(uint32_t p_mask) {
-
set_collision_layer(p_mask);
set_collision_mask(p_mask);
}
uint32_t PhysicsBody2D::_get_layers() const {
-
return get_collision_layer();
}
void PhysicsBody2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &PhysicsBody2D::set_collision_layer);
ClassDB::bind_method(D_METHOD("get_collision_layer"), &PhysicsBody2D::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &PhysicsBody2D::set_collision_mask);
@@ -80,66 +77,60 @@ void PhysicsBody2D::_bind_methods() {
}
void PhysicsBody2D::set_collision_layer(uint32_t p_layer) {
-
collision_layer = p_layer;
PhysicsServer2D::get_singleton()->body_set_collision_layer(get_rid(), p_layer);
}
uint32_t PhysicsBody2D::get_collision_layer() const {
-
return collision_layer;
}
void PhysicsBody2D::set_collision_mask(uint32_t p_mask) {
-
collision_mask = p_mask;
PhysicsServer2D::get_singleton()->body_set_collision_mask(get_rid(), p_mask);
}
uint32_t PhysicsBody2D::get_collision_mask() const {
-
return collision_mask;
}
void PhysicsBody2D::set_collision_mask_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
-bool PhysicsBody2D::get_collision_mask_bit(int p_bit) const {
+bool PhysicsBody2D::get_collision_mask_bit(int p_bit) const {
return get_collision_mask() & (1 << p_bit);
}
void PhysicsBody2D::set_collision_layer_bit(int p_bit, bool p_value) {
-
uint32_t collision_layer = get_collision_layer();
- if (p_value)
+ if (p_value) {
collision_layer |= 1 << p_bit;
- else
+ } else {
collision_layer &= ~(1 << p_bit);
+ }
set_collision_layer(collision_layer);
}
bool PhysicsBody2D::get_collision_layer_bit(int p_bit) const {
-
return get_collision_layer() & (1 << p_bit);
}
PhysicsBody2D::PhysicsBody2D(PhysicsServer2D::BodyMode p_mode) :
CollisionObject2D(PhysicsServer2D::get_singleton()->body_create(), false) {
-
PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), p_mode);
collision_layer = 1;
collision_mask = 1;
set_pickable(false);
}
-Array PhysicsBody2D::get_collision_exceptions() {
+TypedArray<PhysicsBody2D> PhysicsBody2D::get_collision_exceptions() {
List<RID> exceptions;
PhysicsServer2D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions);
Array ret;
@@ -154,7 +145,6 @@ Array PhysicsBody2D::get_collision_exceptions() {
}
void PhysicsBody2D::add_collision_exception_with(Node *p_node) {
-
ERR_FAIL_NULL(p_node);
PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(p_node);
ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody2D type.");
@@ -162,7 +152,6 @@ void PhysicsBody2D::add_collision_exception_with(Node *p_node) {
}
void PhysicsBody2D::remove_collision_exception_with(Node *p_node) {
-
ERR_FAIL_NULL(p_node);
PhysicsBody2D *physics_body = Object::cast_to<PhysicsBody2D>(p_node);
ERR_FAIL_COND_MSG(!physics_body, "Collision exception only works between two objects of PhysicsBody2D type.");
@@ -170,23 +159,20 @@ void PhysicsBody2D::remove_collision_exception_with(Node *p_node) {
}
void StaticBody2D::set_constant_linear_velocity(const Vector2 &p_vel) {
-
constant_linear_velocity = p_vel;
PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity);
}
void StaticBody2D::set_constant_angular_velocity(real_t p_vel) {
-
constant_angular_velocity = p_vel;
PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity);
}
Vector2 StaticBody2D::get_constant_linear_velocity() const {
-
return constant_linear_velocity;
}
-real_t StaticBody2D::get_constant_angular_velocity() const {
+real_t StaticBody2D::get_constant_angular_velocity() const {
return constant_angular_velocity;
}
@@ -210,7 +196,6 @@ Ref<PhysicsMaterial> StaticBody2D::get_physics_material_override() const {
}
void StaticBody2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "vel"), &StaticBody2D::set_constant_linear_velocity);
ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "vel"), &StaticBody2D::set_constant_angular_velocity);
ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody2D::get_constant_linear_velocity);
@@ -226,7 +211,6 @@ void StaticBody2D::_bind_methods() {
StaticBody2D::StaticBody2D() :
PhysicsBody2D(PhysicsServer2D::BODY_MODE_STATIC) {
-
constant_angular_velocity = 0;
}
@@ -244,7 +228,6 @@ void StaticBody2D::_reload_physics_characteristics() {
}
void RigidBody2D::_body_enter_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -260,7 +243,6 @@ void RigidBody2D::_body_enter_tree(ObjectID p_id) {
emit_signal(SceneStringNames::get_singleton()->body_entered, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape);
}
@@ -268,7 +250,6 @@ void RigidBody2D::_body_enter_tree(ObjectID p_id) {
}
void RigidBody2D::_body_exit_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -283,7 +264,6 @@ void RigidBody2D::_body_exit_tree(ObjectID p_id) {
emit_signal(SceneStringNames::get_singleton()->body_exited, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape);
}
@@ -291,7 +271,6 @@ void RigidBody2D::_body_exit_tree(ObjectID p_id) {
}
void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape) {
-
bool body_in = p_status == 1;
ObjectID objid = p_instance;
@@ -305,7 +284,6 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
if (body_in) {
if (!E) {
-
E = contact_monitor->body_map.insert(objid, BodyState());
//E->get().rc=0;
E->get().in_scene = node && node->is_inside_tree();
@@ -320,29 +298,30 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
//E->get().rc++;
}
- if (node)
+ if (node) {
E->get().shapes.insert(ShapePair(p_body_shape, p_local_shape));
+ }
if (E->get().in_scene) {
emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_local_shape);
}
} else {
-
//E->get().rc--;
- if (node)
+ if (node) {
E->get().shapes.erase(ShapePair(p_body_shape, p_local_shape));
+ }
bool in_scene = E->get().in_scene;
if (E->get().shapes.empty()) {
-
if (node) {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody2D::_body_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody2D::_body_exit_tree));
- if (in_scene)
+ if (in_scene) {
emit_signal(SceneStringNames::get_singleton()->body_exited, node);
+ }
}
contact_monitor->body_map.erase(E);
@@ -354,22 +333,20 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
}
struct _RigidBody2DInOut {
-
ObjectID id;
int shape;
int local_shape;
};
bool RigidBody2D::_test_motion(const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) {
-
PhysicsServer2D::MotionResult *r = nullptr;
- if (p_result.is_valid())
+ if (p_result.is_valid()) {
r = p_result->get_result_ptr();
+ }
return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), get_global_transform(), p_motion, p_infinite_inertia, p_margin, r);
}
void RigidBody2D::_direct_state_changed(Object *p_state) {
-
#ifdef DEBUG_ENABLED
state = Object::cast_to<PhysicsDirectBodyState2D>(p_state);
#else
@@ -377,28 +354,27 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
#endif
set_block_transform_notify(true); // don't want notify (would feedback loop)
- if (mode != MODE_KINEMATIC)
+ if (mode != MODE_KINEMATIC) {
set_global_transform(state->get_transform());
+ }
linear_velocity = state->get_linear_velocity();
angular_velocity = state->get_angular_velocity();
if (sleeping != state->is_sleeping()) {
sleeping = state->is_sleeping();
emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed);
}
- if (get_script_instance())
+ if (get_script_instance()) {
get_script_instance()->call("_integrate_forces", state);
+ }
set_block_transform_notify(false); // want it back
if (contact_monitor) {
-
contact_monitor->locked = true;
//untag all
int rc = 0;
for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
-
for (int i = 0; i < E->get().shapes.size(); i++) {
-
E->get().shapes[i].tagged = false;
rc++;
}
@@ -412,7 +388,6 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
//put the ones to add
for (int i = 0; i < state->get_contact_count(); i++) {
-
ObjectID obj = state->get_contact_collider_id(i);
int local_shape = state->get_contact_local_shape(i);
int shape = state->get_contact_collider_shape(i);
@@ -431,7 +406,6 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
ShapePair sp(shape, local_shape);
int idx = E->get().shapes.find(sp);
if (idx == -1) {
-
toadd[toadd_count].local_shape = local_shape;
toadd[toadd_count].id = obj;
toadd[toadd_count].shape = shape;
@@ -445,11 +419,8 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
//put the ones to remove
for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
-
for (int i = 0; i < E->get().shapes.size(); i++) {
-
if (!E->get().shapes[i].tagged) {
-
toremove[toremove_count].body_id = E->key();
toremove[toremove_count].pair = E->get().shapes[i];
toremove_count++;
@@ -460,14 +431,12 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
//process remotions
for (int i = 0; i < toremove_count; i++) {
-
_body_inout(0, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape);
}
//process aditions
for (int i = 0; i < toadd_count; i++) {
-
_body_inout(1, toadd[i].id, toadd[i].shape, toadd[i].local_shape);
}
@@ -478,21 +447,16 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
}
void RigidBody2D::set_mode(Mode p_mode) {
-
mode = p_mode;
switch (p_mode) {
-
case MODE_RIGID: {
-
PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_RIGID);
} break;
case MODE_STATIC: {
-
PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_STATIC);
} break;
case MODE_KINEMATIC: {
-
PhysicsServer2D::get_singleton()->body_set_mode(get_rid(), PhysicsServer2D::BODY_MODE_KINEMATIC);
} break;
@@ -504,41 +468,35 @@ void RigidBody2D::set_mode(Mode p_mode) {
}
RigidBody2D::Mode RigidBody2D::get_mode() const {
-
return mode;
}
void RigidBody2D::set_mass(real_t p_mass) {
-
ERR_FAIL_COND(p_mass <= 0);
mass = p_mass;
_change_notify("mass");
_change_notify("weight");
PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_MASS, mass);
}
-real_t RigidBody2D::get_mass() const {
+real_t RigidBody2D::get_mass() const {
return mass;
}
void RigidBody2D::set_inertia(real_t p_inertia) {
-
ERR_FAIL_COND(p_inertia < 0);
PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_INERTIA, p_inertia);
}
real_t RigidBody2D::get_inertia() const {
-
return PhysicsServer2D::get_singleton()->body_get_param(get_rid(), PhysicsServer2D::BODY_PARAM_INERTIA);
}
void RigidBody2D::set_weight(real_t p_weight) {
-
set_mass(p_weight / (real_t(GLOBAL_DEF("physics/2d/default_gravity", 98)) / 10));
}
real_t RigidBody2D::get_weight() const {
-
return mass * (real_t(GLOBAL_DEF("physics/2d/default_gravity", 98)) / 10);
}
@@ -562,39 +520,35 @@ Ref<PhysicsMaterial> RigidBody2D::get_physics_material_override() const {
}
void RigidBody2D::set_gravity_scale(real_t p_gravity_scale) {
-
gravity_scale = p_gravity_scale;
PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_GRAVITY_SCALE, gravity_scale);
}
-real_t RigidBody2D::get_gravity_scale() const {
+real_t RigidBody2D::get_gravity_scale() const {
return gravity_scale;
}
void RigidBody2D::set_linear_damp(real_t p_linear_damp) {
-
ERR_FAIL_COND(p_linear_damp < -1);
linear_damp = p_linear_damp;
PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_LINEAR_DAMP, linear_damp);
}
-real_t RigidBody2D::get_linear_damp() const {
+real_t RigidBody2D::get_linear_damp() const {
return linear_damp;
}
void RigidBody2D::set_angular_damp(real_t p_angular_damp) {
-
ERR_FAIL_COND(p_angular_damp < -1);
angular_damp = p_angular_damp;
PhysicsServer2D::get_singleton()->body_set_param(get_rid(), PhysicsServer2D::BODY_PARAM_ANGULAR_DAMP, angular_damp);
}
-real_t RigidBody2D::get_angular_damp() const {
+real_t RigidBody2D::get_angular_damp() const {
return angular_damp;
}
void RigidBody2D::set_axis_velocity(const Vector2 &p_axis) {
-
Vector2 v = state ? state->get_linear_velocity() : linear_velocity;
Vector2 axis = p_axis.normalized();
v -= axis * axis.dot(v);
@@ -608,77 +562,68 @@ void RigidBody2D::set_axis_velocity(const Vector2 &p_axis) {
}
void RigidBody2D::set_linear_velocity(const Vector2 &p_velocity) {
-
linear_velocity = p_velocity;
- if (state)
+ if (state) {
state->set_linear_velocity(linear_velocity);
- else {
-
+ } else {
PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY, linear_velocity);
}
}
Vector2 RigidBody2D::get_linear_velocity() const {
-
return linear_velocity;
}
void RigidBody2D::set_angular_velocity(real_t p_velocity) {
-
angular_velocity = p_velocity;
- if (state)
+ if (state) {
state->set_angular_velocity(angular_velocity);
- else
+ } else {
PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_ANGULAR_VELOCITY, angular_velocity);
+ }
}
-real_t RigidBody2D::get_angular_velocity() const {
+real_t RigidBody2D::get_angular_velocity() const {
return angular_velocity;
}
void RigidBody2D::set_use_custom_integrator(bool p_enable) {
-
- if (custom_integrator == p_enable)
+ if (custom_integrator == p_enable) {
return;
+ }
custom_integrator = p_enable;
PhysicsServer2D::get_singleton()->body_set_omit_force_integration(get_rid(), p_enable);
}
-bool RigidBody2D::is_using_custom_integrator() {
+bool RigidBody2D::is_using_custom_integrator() {
return custom_integrator;
}
void RigidBody2D::set_sleeping(bool p_sleeping) {
-
sleeping = p_sleeping;
PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_SLEEPING, sleeping);
}
void RigidBody2D::set_can_sleep(bool p_active) {
-
can_sleep = p_active;
PhysicsServer2D::get_singleton()->body_set_state(get_rid(), PhysicsServer2D::BODY_STATE_CAN_SLEEP, p_active);
}
bool RigidBody2D::is_able_to_sleep() const {
-
return can_sleep;
}
bool RigidBody2D::is_sleeping() const {
-
return sleeping;
}
void RigidBody2D::set_max_contacts_reported(int p_amount) {
-
max_contacts_reported = p_amount;
PhysicsServer2D::get_singleton()->body_set_max_contacts_reported(get_rid(), p_amount);
}
int RigidBody2D::get_max_contacts_reported() const {
-
return max_contacts_reported;
}
@@ -687,7 +632,6 @@ void RigidBody2D::apply_central_impulse(const Vector2 &p_impulse) {
}
void RigidBody2D::apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse) {
-
PhysicsServer2D::get_singleton()->body_apply_impulse(get_rid(), p_offset, p_impulse);
}
@@ -696,22 +640,18 @@ void RigidBody2D::apply_torque_impulse(float p_torque) {
}
void RigidBody2D::set_applied_force(const Vector2 &p_force) {
-
PhysicsServer2D::get_singleton()->body_set_applied_force(get_rid(), p_force);
};
Vector2 RigidBody2D::get_applied_force() const {
-
return PhysicsServer2D::get_singleton()->body_get_applied_force(get_rid());
};
void RigidBody2D::set_applied_torque(const float p_torque) {
-
PhysicsServer2D::get_singleton()->body_set_applied_torque(get_rid(), p_torque);
};
float RigidBody2D::get_applied_torque() const {
-
return PhysicsServer2D::get_singleton()->body_get_applied_torque(get_rid());
};
@@ -720,7 +660,6 @@ void RigidBody2D::add_central_force(const Vector2 &p_force) {
}
void RigidBody2D::add_force(const Vector2 &p_offset, const Vector2 &p_force) {
-
PhysicsServer2D::get_singleton()->body_add_force(get_rid(), p_offset, p_force);
}
@@ -729,21 +668,18 @@ void RigidBody2D::add_torque(const float p_torque) {
}
void RigidBody2D::set_continuous_collision_detection_mode(CCDMode p_mode) {
-
ccd_mode = p_mode;
PhysicsServer2D::get_singleton()->body_set_continuous_collision_detection_mode(get_rid(), PhysicsServer2D::CCDMode(p_mode));
}
RigidBody2D::CCDMode RigidBody2D::get_continuous_collision_detection_mode() const {
-
return ccd_mode;
}
-Array RigidBody2D::get_colliding_bodies() const {
-
+TypedArray<Node2D> RigidBody2D::get_colliding_bodies() const {
ERR_FAIL_COND_V(!contact_monitor, Array());
- Array ret;
+ TypedArray<Node2D> ret;
ret.resize(contact_monitor->body_map.size());
int idx = 0;
for (const Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
@@ -759,16 +695,14 @@ Array RigidBody2D::get_colliding_bodies() const {
}
void RigidBody2D::set_contact_monitor(bool p_enabled) {
-
- if (p_enabled == is_contact_monitor_enabled())
+ if (p_enabled == is_contact_monitor_enabled()) {
return;
+ }
if (!p_enabled) {
-
ERR_FAIL_COND_MSG(contact_monitor->locked, "Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\", false) instead.");
for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
-
//clean up mess
Object *obj = ObjectDB::get_instance(E->key());
Node *node = Object::cast_to<Node>(obj);
@@ -782,19 +716,16 @@ void RigidBody2D::set_contact_monitor(bool p_enabled) {
memdelete(contact_monitor);
contact_monitor = nullptr;
} else {
-
contact_monitor = memnew(ContactMonitor);
contact_monitor->locked = false;
}
}
bool RigidBody2D::is_contact_monitor_enabled() const {
-
return contact_monitor != nullptr;
}
void RigidBody2D::_notification(int p_what) {
-
#ifdef TOOLS_ENABLED
if (p_what == NOTIFICATION_ENTER_TREE) {
if (Engine::get_singleton()->is_editor_hint()) {
@@ -812,7 +743,6 @@ void RigidBody2D::_notification(int p_what) {
}
String RigidBody2D::get_configuration_warning() const {
-
Transform2D t = get_transform();
String warning = CollisionObject2D::get_configuration_warning();
@@ -828,7 +758,6 @@ String RigidBody2D::get_configuration_warning() const {
}
void RigidBody2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_mode", "mode"), &RigidBody2D::set_mode);
ClassDB::bind_method(D_METHOD("get_mode"), &RigidBody2D::get_mode);
@@ -940,7 +869,6 @@ void RigidBody2D::_bind_methods() {
RigidBody2D::RigidBody2D() :
PhysicsBody2D(PhysicsServer2D::BODY_MODE_RIGID) {
-
mode = MODE_RIGID;
mass = 1;
@@ -964,9 +892,9 @@ RigidBody2D::RigidBody2D() :
}
RigidBody2D::~RigidBody2D() {
-
- if (contact_monitor)
+ if (contact_monitor) {
memdelete(contact_monitor);
+ }
}
void RigidBody2D::_reload_physics_characteristics() {
@@ -982,7 +910,6 @@ void RigidBody2D::_reload_physics_characteristics() {
//////////////////////////
Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) {
-
Collision col;
if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) {
@@ -1000,7 +927,6 @@ Ref<KinematicCollision2D> KinematicBody2D::_move(const Vector2 &p_motion, bool p
}
bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) {
-
PhysicsServer2D::SeparationResult sep_res[8]; //max 8 rays
Transform2D gt = get_global_transform();
@@ -1037,7 +963,6 @@ bool KinematicBody2D::separate_raycast_shapes(bool p_infinite_inertia, Collision
}
bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) {
-
if (sync_to_physics) {
ERR_PRINT("Functions move_and_slide and move_and_collide do not work together with 'sync to physics' option. Please read the documentation.");
}
@@ -1070,7 +995,6 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
#define FLOOR_ANGLE_THRESHOLD 0.01
Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
-
Vector2 body_velocity = p_linear_velocity;
Vector2 body_velocity_normal = body_velocity.normalized();
@@ -1095,7 +1019,6 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
floor_velocity = Vector2();
while (p_max_slides) {
-
Collision collision;
bool found_collision = false;
@@ -1151,8 +1074,9 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
}
}
- if (!found_collision || motion == Vector2())
+ if (!found_collision || motion == Vector2()) {
break;
+ }
--p_max_slides;
}
@@ -1161,7 +1085,6 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
}
Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_velocity, const Vector2 &p_snap, const Vector2 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
-
bool was_on_floor = on_floor;
Vector2 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
@@ -1201,47 +1124,40 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci
}
bool KinematicBody2D::is_on_floor() const {
-
return on_floor;
}
-bool KinematicBody2D::is_on_wall() const {
+bool KinematicBody2D::is_on_wall() const {
return on_wall;
}
-bool KinematicBody2D::is_on_ceiling() const {
+bool KinematicBody2D::is_on_ceiling() const {
return on_ceiling;
}
Vector2 KinematicBody2D::get_floor_normal() const {
-
return floor_normal;
}
Vector2 KinematicBody2D::get_floor_velocity() const {
-
return floor_velocity;
}
bool KinematicBody2D::test_move(const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia) {
-
ERR_FAIL_COND_V(!is_inside_tree(), false);
return PhysicsServer2D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia, margin);
}
void KinematicBody2D::set_safe_margin(float p_margin) {
-
margin = p_margin;
}
float KinematicBody2D::get_safe_margin() const {
-
return margin;
}
int KinematicBody2D::get_slide_count() const {
-
return colliders.size();
}
@@ -1251,7 +1167,6 @@ KinematicBody2D::Collision KinematicBody2D::get_slide_collision(int p_bounce) co
}
Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) {
-
ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision2D>());
if (p_bounce >= slide_colliders.size()) {
slide_colliders.resize(p_bounce + 1);
@@ -1267,14 +1182,14 @@ Ref<KinematicCollision2D> KinematicBody2D::_get_slide_collision(int p_bounce) {
}
void KinematicBody2D::set_sync_to_physics(bool p_enable) {
-
if (sync_to_physics == p_enable) {
return;
}
sync_to_physics = p_enable;
- if (Engine::get_singleton()->is_editor_hint())
+ if (Engine::get_singleton()->is_editor_hint()) {
return;
+ }
if (p_enable) {
PhysicsServer2D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
@@ -1292,9 +1207,9 @@ bool KinematicBody2D::is_sync_to_physics_enabled() const {
}
void KinematicBody2D::_direct_state_changed(Object *p_state) {
-
- if (!sync_to_physics)
+ if (!sync_to_physics) {
return;
+ }
PhysicsDirectBodyState2D *state = Object::cast_to<PhysicsDirectBodyState2D>(p_state);
@@ -1327,8 +1242,8 @@ void KinematicBody2D::_notification(int p_what) {
set_notify_local_transform(true);
}
}
-void KinematicBody2D::_bind_methods() {
+void KinematicBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody2D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
ClassDB::bind_method(D_METHOD("move_and_slide_with_snap", "linear_velocity", "snap", "up_direction", "stop_on_slope", "max_slides", "floor_max_angle", "infinite_inertia"), &KinematicBody2D::move_and_slide_with_snap, DEFVAL(Vector2(0, 0)), DEFVAL(false), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(true));
@@ -1358,7 +1273,6 @@ void KinematicBody2D::_bind_methods() {
KinematicBody2D::KinematicBody2D() :
PhysicsBody2D(PhysicsServer2D::BODY_MODE_KINEMATIC) {
-
margin = 0.08;
on_floor = false;
@@ -1366,6 +1280,7 @@ KinematicBody2D::KinematicBody2D() :
on_wall = false;
sync_to_physics = false;
}
+
KinematicBody2D::~KinematicBody2D() {
if (motion_cache.is_valid()) {
motion_cache->owner = nullptr;
@@ -1381,38 +1296,42 @@ KinematicBody2D::~KinematicBody2D() {
////////////////////////
Vector2 KinematicCollision2D::get_position() const {
-
return collision.collision;
}
+
Vector2 KinematicCollision2D::get_normal() const {
return collision.normal;
}
+
Vector2 KinematicCollision2D::get_travel() const {
return collision.travel;
}
+
Vector2 KinematicCollision2D::get_remainder() const {
return collision.remainder;
}
+
Object *KinematicCollision2D::get_local_shape() const {
- if (!owner) return nullptr;
+ if (!owner) {
+ return nullptr;
+ }
uint32_t ownerid = owner->shape_find_owner(collision.local_shape);
return owner->shape_owner_get_owner(ownerid);
}
Object *KinematicCollision2D::get_collider() const {
-
if (collision.collider.is_valid()) {
return ObjectDB::get_instance(collision.collider);
}
return nullptr;
}
-ObjectID KinematicCollision2D::get_collider_id() const {
+ObjectID KinematicCollision2D::get_collider_id() const {
return collision.collider;
}
-Object *KinematicCollision2D::get_collider_shape() const {
+Object *KinematicCollision2D::get_collider_shape() const {
Object *collider = get_collider();
if (collider) {
CollisionObject2D *obj2d = Object::cast_to<CollisionObject2D>(collider);
@@ -1424,21 +1343,20 @@ Object *KinematicCollision2D::get_collider_shape() const {
return nullptr;
}
-int KinematicCollision2D::get_collider_shape_index() const {
+int KinematicCollision2D::get_collider_shape_index() const {
return collision.collider_shape;
}
-Vector2 KinematicCollision2D::get_collider_velocity() const {
+Vector2 KinematicCollision2D::get_collider_velocity() const {
return collision.collider_vel;
}
-Variant KinematicCollision2D::get_collider_metadata() const {
+Variant KinematicCollision2D::get_collider_metadata() const {
return Variant();
}
void KinematicCollision2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision2D::get_position);
ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision2D::get_normal);
ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision2D::get_travel);
@@ -1465,7 +1383,6 @@ void KinematicCollision2D::_bind_methods() {
}
KinematicCollision2D::KinematicCollision2D() {
-
collision.collider_shape = 0;
collision.local_shape = 0;
owner = nullptr;
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 0d92a820e3..cde4398ad3 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -39,7 +39,6 @@
class KinematicCollision2D;
class PhysicsBody2D : public CollisionObject2D {
-
GDCLASS(PhysicsBody2D, CollisionObject2D);
uint32_t collision_layer;
@@ -67,7 +66,7 @@ public:
void set_collision_layer_bit(int p_bit, bool p_value);
bool get_collision_layer_bit(int p_bit) const;
- Array get_collision_exceptions();
+ TypedArray<PhysicsBody2D> get_collision_exceptions();
void add_collision_exception_with(Node *p_node); //must be physicsbody
void remove_collision_exception_with(Node *p_node);
@@ -75,7 +74,6 @@ public:
};
class StaticBody2D : public PhysicsBody2D {
-
GDCLASS(StaticBody2D, PhysicsBody2D);
Vector2 constant_linear_velocity;
@@ -104,7 +102,6 @@ private:
};
class RigidBody2D : public PhysicsBody2D {
-
GDCLASS(RigidBody2D, PhysicsBody2D);
public:
@@ -143,13 +140,13 @@ private:
CCDMode ccd_mode;
struct ShapePair {
-
int body_shape;
int local_shape;
bool tagged;
bool operator<(const ShapePair &p_sp) const {
- if (body_shape == p_sp.body_shape)
+ if (body_shape == p_sp.body_shape) {
return local_shape < p_sp.local_shape;
+ }
return body_shape < p_sp.body_shape;
}
@@ -161,19 +158,16 @@ private:
}
};
struct RigidBody2D_RemoveAction {
-
ObjectID body_id;
ShapePair pair;
};
struct BodyState {
-
//int rc;
bool in_scene;
VSet<ShapePair> shapes;
};
struct ContactMonitor {
-
bool locked;
Map<ObjectID, BodyState> body_map;
};
@@ -256,7 +250,7 @@ public:
void add_force(const Vector2 &p_offset, const Vector2 &p_force);
void add_torque(float p_torque);
- Array get_colliding_bodies() const; //function for script
+ TypedArray<Node2D> get_colliding_bodies() const; //function for script
virtual String get_configuration_warning() const;
@@ -271,7 +265,6 @@ VARIANT_ENUM_CAST(RigidBody2D::Mode);
VARIANT_ENUM_CAST(RigidBody2D::CCDMode);
class KinematicBody2D : public PhysicsBody2D {
-
GDCLASS(KinematicBody2D, PhysicsBody2D);
public:
@@ -344,7 +337,6 @@ public:
};
class KinematicCollision2D : public Reference {
-
GDCLASS(KinematicCollision2D, Reference);
KinematicBody2D *owner;
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index 84c1828b47..62c66dbb29 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -65,10 +65,11 @@ Rect2 Polygon2D::_edit_get_rect() const {
item_rect = Rect2();
for (int i = 0; i < l; i++) {
Vector2 pos = r[i] + offset;
- if (i == 0)
+ if (i == 0) {
item_rect.position = pos;
- else
+ } else {
item_rect.expand_to(pos);
+ }
}
rect_cache_dirty = false;
}
@@ -81,7 +82,6 @@ bool Polygon2D::_edit_use_rect() const {
}
bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
Vector<Vector2> polygon2d = Variant(polygon);
if (internal_vertices > 0) {
polygon2d.resize(polygon2d.size() - internal_vertices);
@@ -95,13 +95,11 @@ void Polygon2D::_skeleton_bone_setup_changed() {
}
void Polygon2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_DRAW: {
-
- if (polygon.size() < 3)
+ if (polygon.size() < 3) {
return;
+ }
Skeleton2D *skeleton_node = nullptr;
if (has_node(skeleton)) {
@@ -147,7 +145,6 @@ void Polygon2D::_notification(int p_what) {
points.resize(len);
{
-
const Vector2 *polyr = polygon.ptr();
for (int i = 0; i < len; i++) {
points.write[i] = polyr[i] + offset;
@@ -155,17 +152,17 @@ void Polygon2D::_notification(int p_what) {
}
if (invert) {
-
Rect2 bounds;
int highest_idx = -1;
float highest_y = -1e20;
float sum = 0;
for (int i = 0; i < len; i++) {
- if (i == 0)
+ if (i == 0) {
bounds.position = points[i];
- else
+ } else {
bounds.expand_to(points[i]);
+ }
if (points[i].y > highest_y) {
highest_idx = i;
highest_y = points[i].y;
@@ -195,12 +192,10 @@ void Polygon2D::_notification(int p_what) {
points.resize(points.size() + 7);
for (int i = points.size() - 1; i >= highest_idx + 7; i--) {
-
points.write[i] = points[i - 7];
}
for (int i = 0; i < 7; i++) {
-
points.write[highest_idx + i + 1] = ep[i];
}
@@ -208,7 +203,6 @@ void Polygon2D::_notification(int p_what) {
}
if (texture.is_valid()) {
-
Transform2D texmat(tex_rot, tex_ofs);
texmat.scale(tex_scale);
Size2 tex_size = texture->get_size();
@@ -216,7 +210,6 @@ void Polygon2D::_notification(int p_what) {
uvs.resize(len);
if (points.size() == uv.size()) {
-
const Vector2 *uvr = uv.ptr();
for (int i = 0; i < len; i++) {
@@ -259,8 +252,9 @@ void Polygon2D::_notification(int p_what) {
int bone_index = bone->get_index_in_skeleton();
const float *r = bone_weights[i].weights.ptr();
for (int j = 0; j < vc; j++) {
- if (r[j] == 0.0)
+ if (r[j] == 0.0) {
continue; //weight is unpainted, skip
+ }
//find an index with a weight
for (int k = 0; k < 4; k++) {
if (weightsw[j * 4 + k] < r[j]) {
@@ -283,8 +277,9 @@ void Polygon2D::_notification(int p_what) {
for (int j = 0; j < 4; j++) {
tw += weightsw[i * 4 + j];
}
- if (tw == 0)
+ if (tw == 0) {
continue; //unpainted, do nothing
+ }
//normalize
for (int j = 0; j < 4; j++) {
@@ -315,8 +310,9 @@ void Polygon2D::_notification(int p_what) {
for (int i = 0; i < polygons.size(); i++) {
Vector<int> src_indices = polygons[i];
int ic = src_indices.size();
- if (ic < 3)
+ if (ic < 3) {
continue;
+ }
const int *r = src_indices.ptr();
Vector<Vector2> tmp_points;
@@ -356,12 +352,10 @@ void Polygon2D::set_polygon(const Vector<Vector2> &p_polygon) {
}
Vector<Vector2> Polygon2D::get_polygon() const {
-
return polygon;
}
void Polygon2D::set_internal_vertex_count(int p_count) {
-
internal_vertices = p_count;
}
@@ -370,49 +364,42 @@ int Polygon2D::get_internal_vertex_count() const {
}
void Polygon2D::set_uv(const Vector<Vector2> &p_uv) {
-
uv = p_uv;
update();
}
Vector<Vector2> Polygon2D::get_uv() const {
-
return uv;
}
void Polygon2D::set_polygons(const Array &p_polygons) {
-
polygons = p_polygons;
update();
}
Array Polygon2D::get_polygons() const {
-
return polygons;
}
void Polygon2D::set_color(const Color &p_color) {
-
color = p_color;
update();
}
-Color Polygon2D::get_color() const {
+Color Polygon2D::get_color() const {
return color;
}
void Polygon2D::set_vertex_colors(const Vector<Color> &p_colors) {
-
vertex_colors = p_colors;
update();
}
-Vector<Color> Polygon2D::get_vertex_colors() const {
+Vector<Color> Polygon2D::get_vertex_colors() const {
return vertex_colors;
}
void Polygon2D::set_texture(const Ref<Texture2D> &p_texture) {
-
texture = p_texture;
/*if (texture.is_valid()) {
@@ -425,8 +412,8 @@ void Polygon2D::set_texture(const Ref<Texture2D> &p_texture) {
}*/
update();
}
-Ref<Texture2D> Polygon2D::get_texture() const {
+Ref<Texture2D> Polygon2D::get_texture() const {
return texture;
}
@@ -467,76 +454,68 @@ float Polygon2D::get_shininess() const {
}
void Polygon2D::set_texture_offset(const Vector2 &p_offset) {
-
tex_ofs = p_offset;
update();
}
-Vector2 Polygon2D::get_texture_offset() const {
+Vector2 Polygon2D::get_texture_offset() const {
return tex_ofs;
}
void Polygon2D::set_texture_rotation(float p_rot) {
-
tex_rot = p_rot;
update();
}
-float Polygon2D::get_texture_rotation() const {
+float Polygon2D::get_texture_rotation() const {
return tex_rot;
}
void Polygon2D::set_texture_rotation_degrees(float p_rot) {
-
set_texture_rotation(Math::deg2rad(p_rot));
}
-float Polygon2D::get_texture_rotation_degrees() const {
+float Polygon2D::get_texture_rotation_degrees() const {
return Math::rad2deg(get_texture_rotation());
}
void Polygon2D::set_texture_scale(const Size2 &p_scale) {
-
tex_scale = p_scale;
update();
}
-Size2 Polygon2D::get_texture_scale() const {
+Size2 Polygon2D::get_texture_scale() const {
return tex_scale;
}
void Polygon2D::set_invert(bool p_invert) {
-
invert = p_invert;
update();
}
-bool Polygon2D::get_invert() const {
+bool Polygon2D::get_invert() const {
return invert;
}
void Polygon2D::set_antialiased(bool p_antialiased) {
-
antialiased = p_antialiased;
update();
}
-bool Polygon2D::get_antialiased() const {
+bool Polygon2D::get_antialiased() const {
return antialiased;
}
void Polygon2D::set_invert_border(float p_invert_border) {
-
invert_border = p_invert_border;
update();
}
-float Polygon2D::get_invert_border() const {
+float Polygon2D::get_invert_border() const {
return invert_border;
}
void Polygon2D::set_offset(const Vector2 &p_offset) {
-
offset = p_offset;
rect_cache_dirty = true;
update();
@@ -544,31 +523,31 @@ void Polygon2D::set_offset(const Vector2 &p_offset) {
}
Vector2 Polygon2D::get_offset() const {
-
return offset;
}
void Polygon2D::add_bone(const NodePath &p_path, const Vector<float> &p_weights) {
-
Bone bone;
bone.path = p_path;
bone.weights = p_weights;
bone_weights.push_back(bone);
}
+
int Polygon2D::get_bone_count() const {
return bone_weights.size();
}
+
NodePath Polygon2D::get_bone_path(int p_index) const {
ERR_FAIL_INDEX_V(p_index, bone_weights.size(), NodePath());
return bone_weights[p_index].path;
}
-Vector<float> Polygon2D::get_bone_weights(int p_index) const {
+Vector<float> Polygon2D::get_bone_weights(int p_index) const {
ERR_FAIL_INDEX_V(p_index, bone_weights.size(), Vector<float>());
return bone_weights[p_index].weights;
}
-void Polygon2D::erase_bone(int p_idx) {
+void Polygon2D::erase_bone(int p_idx) {
ERR_FAIL_INDEX(p_idx, bone_weights.size());
bone_weights.remove(p_idx);
}
@@ -582,6 +561,7 @@ void Polygon2D::set_bone_weights(int p_index, const Vector<float> &p_weights) {
bone_weights.write[p_index].weights = p_weights;
update();
}
+
void Polygon2D::set_bone_path(int p_index, const NodePath &p_path) {
ERR_FAIL_INDEX(p_index, bone_weights.size());
bone_weights.write[p_index].path = p_path;
@@ -596,8 +576,8 @@ Array Polygon2D::_get_bones() const {
}
return bones;
}
-void Polygon2D::_set_bones(const Array &p_bones) {
+void Polygon2D::_set_bones(const Array &p_bones) {
ERR_FAIL_COND(p_bones.size() & 1);
clear_bones();
for (int i = 0; i < p_bones.size(); i += 2) {
@@ -606,8 +586,9 @@ void Polygon2D::_set_bones(const Array &p_bones) {
}
void Polygon2D::set_skeleton(const NodePath &p_skeleton) {
- if (skeleton == p_skeleton)
+ if (skeleton == p_skeleton) {
return;
+ }
skeleton = p_skeleton;
update();
}
@@ -617,7 +598,6 @@ NodePath Polygon2D::get_skeleton() const {
}
void Polygon2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &Polygon2D::set_polygon);
ClassDB::bind_method(D_METHOD("get_polygon"), &Polygon2D::get_polygon);
@@ -722,8 +702,7 @@ void Polygon2D::_bind_methods() {
}
Polygon2D::Polygon2D() {
-
- invert = 0;
+ invert = false;
invert_border = 100;
antialiased = false;
tex_rot = 0;
diff --git a/scene/2d/polygon_2d.h b/scene/2d/polygon_2d.h
index 777c1f82f3..dafec1c343 100644
--- a/scene/2d/polygon_2d.h
+++ b/scene/2d/polygon_2d.h
@@ -34,7 +34,6 @@
#include "scene/2d/node_2d.h"
class Polygon2D : public Node2D {
-
GDCLASS(Polygon2D, Node2D);
Vector<Vector2> polygon;
diff --git a/scene/2d/position_2d.cpp b/scene/2d/position_2d.cpp
index 9e95a55d9f..a94a9f7085 100644
--- a/scene/2d/position_2d.cpp
+++ b/scene/2d/position_2d.cpp
@@ -36,7 +36,6 @@
const float DEFAULT_GIZMO_EXTENTS = 10.0;
void Position2D::_draw_cross() {
-
float extents = get_gizmo_extents();
// Colors taken from `axis_x_color` and `axis_y_color` (defined in `editor/editor_themes.cpp`)
draw_line(Point2(-extents, 0), Point2(+extents, 0), Color(0.96, 0.20, 0.32));
@@ -45,7 +44,6 @@ void Position2D::_draw_cross() {
#ifdef TOOLS_ENABLED
Rect2 Position2D::_edit_get_rect() const {
-
float extents = get_gizmo_extents();
return Rect2(Point2(-extents, -extents), Size2(extents * 2, extents * 2));
}
@@ -56,18 +54,17 @@ bool Position2D::_edit_use_rect() const {
#endif
void Position2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
update();
} break;
case NOTIFICATION_DRAW: {
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
break;
- if (Engine::get_singleton()->is_editor_hint())
+ }
+ if (Engine::get_singleton()->is_editor_hint()) {
_draw_cross();
+ }
} break;
}
@@ -92,7 +89,6 @@ float Position2D::get_gizmo_extents() const {
}
void Position2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_set_gizmo_extents", "extents"), &Position2D::set_gizmo_extents);
ClassDB::bind_method(D_METHOD("_get_gizmo_extents"), &Position2D::get_gizmo_extents);
diff --git a/scene/2d/position_2d.h b/scene/2d/position_2d.h
index 3ea636171d..b53fa4c0e2 100644
--- a/scene/2d/position_2d.h
+++ b/scene/2d/position_2d.h
@@ -34,7 +34,6 @@
#include "scene/2d/node_2d.h"
class Position2D : public Node2D {
-
GDCLASS(Position2D, Node2D);
void _draw_cross();
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 9d6c7304ce..5020940c5c 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -36,134 +36,129 @@
#include "servers/physics_server_2d.h"
void RayCast2D::set_cast_to(const Vector2 &p_point) {
-
cast_to = p_point;
- if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint()))
+ if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) {
update();
+ }
}
Vector2 RayCast2D::get_cast_to() const {
-
return cast_to;
}
void RayCast2D::set_collision_mask(uint32_t p_mask) {
-
collision_mask = p_mask;
}
uint32_t RayCast2D::get_collision_mask() const {
-
return collision_mask;
}
void RayCast2D::set_collision_mask_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
bool RayCast2D::get_collision_mask_bit(int p_bit) const {
-
return get_collision_mask() & (1 << p_bit);
}
bool RayCast2D::is_colliding() const {
-
return collided;
}
-Object *RayCast2D::get_collider() const {
- if (against.is_null())
+Object *RayCast2D::get_collider() const {
+ if (against.is_null()) {
return nullptr;
+ }
return ObjectDB::get_instance(against);
}
int RayCast2D::get_collider_shape() const {
-
return against_shape;
}
-Vector2 RayCast2D::get_collision_point() const {
+Vector2 RayCast2D::get_collision_point() const {
return collision_point;
}
-Vector2 RayCast2D::get_collision_normal() const {
+Vector2 RayCast2D::get_collision_normal() const {
return collision_normal;
}
void RayCast2D::set_enabled(bool p_enabled) {
-
enabled = p_enabled;
update();
- if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint())
+ if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) {
set_physics_process_internal(p_enabled);
- if (!p_enabled)
+ }
+ if (!p_enabled) {
collided = false;
+ }
}
bool RayCast2D::is_enabled() const {
-
return enabled;
}
void RayCast2D::set_exclude_parent_body(bool p_exclude_parent_body) {
-
- if (exclude_parent_body == p_exclude_parent_body)
+ if (exclude_parent_body == p_exclude_parent_body) {
return;
+ }
exclude_parent_body = p_exclude_parent_body;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
if (Object::cast_to<CollisionObject2D>(get_parent())) {
- if (exclude_parent_body)
+ if (exclude_parent_body) {
exclude.insert(Object::cast_to<CollisionObject2D>(get_parent())->get_rid());
- else
+ } else {
exclude.erase(Object::cast_to<CollisionObject2D>(get_parent())->get_rid());
+ }
}
}
bool RayCast2D::get_exclude_parent_body() const {
-
return exclude_parent_body;
}
void RayCast2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
- if (enabled && !Engine::get_singleton()->is_editor_hint())
+ if (enabled && !Engine::get_singleton()->is_editor_hint()) {
set_physics_process_internal(true);
- else
+ } else {
set_physics_process_internal(false);
+ }
if (Object::cast_to<CollisionObject2D>(get_parent())) {
- if (exclude_parent_body)
+ if (exclude_parent_body) {
exclude.insert(Object::cast_to<CollisionObject2D>(get_parent())->get_rid());
- else
+ } else {
exclude.erase(Object::cast_to<CollisionObject2D>(get_parent())->get_rid());
+ }
}
} break;
case NOTIFICATION_EXIT_TREE: {
-
- if (enabled)
+ if (enabled) {
set_physics_process_internal(false);
+ }
} break;
case NOTIFICATION_DRAW: {
-
- if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint())
+ if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) {
break;
+ }
Transform2D xf;
xf.rotate(cast_to.angle());
xf.translate(Vector2(cast_to.length(), 0));
@@ -183,17 +178,18 @@ void RayCast2D::_notification(int p_what) {
pts.push_back(xf.xform(Vector2(0, Math_SQRT12 * tsize)));
pts.push_back(xf.xform(Vector2(0, -Math_SQRT12 * tsize)));
Vector<Color> cols;
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++) {
cols.push_back(draw_col);
+ }
draw_primitive(pts, cols, Vector<Vector2>());
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
-
- if (!enabled)
+ if (!enabled) {
break;
+ }
_update_raycast_state();
@@ -211,13 +207,13 @@ void RayCast2D::_update_raycast_state() {
Transform2D gt = get_global_transform();
Vector2 to = cast_to;
- if (to == Vector2())
+ if (to == Vector2()) {
to = Vector2(0, 0.01);
+ }
PhysicsDirectSpaceState2D::RayResult rr;
if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask, collide_with_bodies, collide_with_areas)) {
-
collided = true;
against = rr.collider_id;
collision_point = rr.position;
@@ -235,60 +231,52 @@ void RayCast2D::force_raycast_update() {
}
void RayCast2D::add_exception_rid(const RID &p_rid) {
-
exclude.insert(p_rid);
}
void RayCast2D::add_exception(const Object *p_object) {
-
ERR_FAIL_NULL(p_object);
const CollisionObject2D *co = Object::cast_to<CollisionObject2D>(p_object);
- if (!co)
+ if (!co) {
return;
+ }
add_exception_rid(co->get_rid());
}
void RayCast2D::remove_exception_rid(const RID &p_rid) {
-
exclude.erase(p_rid);
}
void RayCast2D::remove_exception(const Object *p_object) {
-
ERR_FAIL_NULL(p_object);
const CollisionObject2D *co = Object::cast_to<CollisionObject2D>(p_object);
- if (!co)
+ if (!co) {
return;
+ }
remove_exception_rid(co->get_rid());
}
void RayCast2D::clear_exceptions() {
-
exclude.clear();
}
void RayCast2D::set_collide_with_areas(bool p_clip) {
-
collide_with_areas = p_clip;
}
bool RayCast2D::is_collide_with_areas_enabled() const {
-
return collide_with_areas;
}
void RayCast2D::set_collide_with_bodies(bool p_clip) {
-
collide_with_bodies = p_clip;
}
bool RayCast2D::is_collide_with_bodies_enabled() const {
-
return collide_with_bodies;
}
void RayCast2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast2D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &RayCast2D::is_enabled);
@@ -337,7 +325,6 @@ void RayCast2D::_bind_methods() {
}
RayCast2D::RayCast2D() {
-
enabled = false;
collided = false;
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index 20f05e7525..6accc264a0 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -34,7 +34,6 @@
#include "scene/2d/node_2d.h"
class RayCast2D : public Node2D {
-
GDCLASS(RayCast2D, Node2D);
bool enabled;
diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp
index ec50f5f922..3104436dbe 100644
--- a/scene/2d/remote_transform_2d.cpp
+++ b/scene/2d/remote_transform_2d.cpp
@@ -32,7 +32,6 @@
#include "scene/scene_string_names.h"
void RemoteTransform2D::_update_cache() {
-
cache = ObjectID();
if (has_node(remote_node)) {
Node *node = get_node(remote_node);
@@ -45,23 +44,25 @@ void RemoteTransform2D::_update_cache() {
}
void RemoteTransform2D::_update_remote() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
- if (cache.is_null())
+ if (cache.is_null()) {
return;
+ }
Node2D *n = Object::cast_to<Node2D>(ObjectDB::get_instance(cache));
- if (!n)
+ if (!n) {
return;
+ }
- if (!n->is_inside_tree())
+ if (!n->is_inside_tree()) {
return;
+ }
//todo make faster
if (use_global_coordinates) {
-
if (update_remote_position && update_remote_rotation && update_remote_scale) {
n->set_global_transform(get_global_transform());
} else {
@@ -69,21 +70,23 @@ void RemoteTransform2D::_update_remote() {
Transform2D our_trans = get_global_transform();
Vector2 n_scale = n->get_scale();
- if (!update_remote_position)
+ if (!update_remote_position) {
our_trans.set_origin(n_trans.get_origin());
- if (!update_remote_rotation)
+ }
+ if (!update_remote_rotation) {
our_trans.set_rotation(n_trans.get_rotation());
+ }
n->set_global_transform(our_trans);
- if (update_remote_scale)
+ if (update_remote_scale) {
n->set_scale(get_global_scale());
- else
+ } else {
n->set_scale(n_scale);
+ }
}
} else {
-
if (update_remote_position && update_remote_rotation && update_remote_scale) {
n->set_transform(get_transform());
} else {
@@ -91,36 +94,36 @@ void RemoteTransform2D::_update_remote() {
Transform2D our_trans = get_transform();
Vector2 n_scale = n->get_scale();
- if (!update_remote_position)
+ if (!update_remote_position) {
our_trans.set_origin(n_trans.get_origin());
- if (!update_remote_rotation)
+ }
+ if (!update_remote_rotation) {
our_trans.set_rotation(n_trans.get_rotation());
+ }
n->set_transform(our_trans);
- if (update_remote_scale)
+ if (update_remote_scale) {
n->set_scale(get_scale());
- else
+ } else {
n->set_scale(n_scale);
+ }
}
}
}
void RemoteTransform2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
_update_cache();
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
break;
+ }
if (cache.is_valid()) {
-
_update_remote();
}
@@ -129,7 +132,6 @@ void RemoteTransform2D::_notification(int p_what) {
}
void RemoteTransform2D::set_remote_node(const NodePath &p_remote_node) {
-
remote_node = p_remote_node;
if (is_inside_tree()) {
_update_cache();
@@ -140,7 +142,6 @@ void RemoteTransform2D::set_remote_node(const NodePath &p_remote_node) {
}
NodePath RemoteTransform2D::get_remote_node() const {
-
return remote_node;
}
@@ -185,7 +186,6 @@ void RemoteTransform2D::force_update_cache() {
}
String RemoteTransform2D::get_configuration_warning() const {
-
if (!has_node(remote_node) || !Object::cast_to<Node2D>(get_node(remote_node))) {
return TTR("Path property must point to a valid Node2D node to work.");
}
@@ -194,7 +194,6 @@ String RemoteTransform2D::get_configuration_warning() const {
}
void RemoteTransform2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_remote_node", "path"), &RemoteTransform2D::set_remote_node);
ClassDB::bind_method(D_METHOD("get_remote_node"), &RemoteTransform2D::get_remote_node);
ClassDB::bind_method(D_METHOD("force_update_cache"), &RemoteTransform2D::force_update_cache);
@@ -219,7 +218,6 @@ void RemoteTransform2D::_bind_methods() {
}
RemoteTransform2D::RemoteTransform2D() {
-
use_global_coordinates = true;
update_remote_position = true;
update_remote_rotation = true;
diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h
index f5b949d10b..caaa0394f2 100644
--- a/scene/2d/remote_transform_2d.h
+++ b/scene/2d/remote_transform_2d.h
@@ -34,7 +34,6 @@
#include "scene/2d/node_2d.h"
class RemoteTransform2D : public Node2D {
-
GDCLASS(RemoteTransform2D, Node2D);
NodePath remote_node;
diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp
index 86c9ff6076..ea37c8dfe7 100644
--- a/scene/2d/skeleton_2d.cpp
+++ b/scene/2d/skeleton_2d.cpp
@@ -31,17 +31,18 @@
#include "skeleton_2d.h"
void Bone2D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
Node *parent = get_parent();
parent_bone = Object::cast_to<Bone2D>(parent);
skeleton = nullptr;
while (parent) {
skeleton = Object::cast_to<Skeleton2D>(parent);
- if (skeleton)
+ if (skeleton) {
break;
- if (!Object::cast_to<Bone2D>(parent))
+ }
+ if (!Object::cast_to<Bone2D>(parent)) {
break; //skeletons must be chained to Bone2Ds.
+ }
parent = parent->get_parent();
}
@@ -78,8 +79,8 @@ void Bone2D::_notification(int p_what) {
parent_bone = nullptr;
}
}
-void Bone2D::_bind_methods() {
+void Bone2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_rest", "rest"), &Bone2D::set_rest);
ClassDB::bind_method(D_METHOD("get_rest"), &Bone2D::get_rest);
ClassDB::bind_method(D_METHOD("apply_rest"), &Bone2D::apply_rest);
@@ -95,8 +96,9 @@ void Bone2D::_bind_methods() {
void Bone2D::set_rest(const Transform2D &p_rest) {
rest = p_rest;
- if (skeleton)
+ if (skeleton) {
skeleton->_make_bone_setup_dirty();
+ }
update_configuration_warning();
}
@@ -106,7 +108,6 @@ Transform2D Bone2D::get_rest() const {
}
Transform2D Bone2D::get_skeleton_rest() const {
-
if (parent_bone) {
return parent_bone->get_skeleton_rest() * rest;
} else {
@@ -119,7 +120,6 @@ void Bone2D::apply_rest() {
}
void Bone2D::set_default_length(float p_length) {
-
default_length = p_length;
}
@@ -132,8 +132,8 @@ int Bone2D::get_index_in_skeleton() const {
skeleton->_update_bone_setup();
return skeleton_index;
}
-String Bone2D::get_configuration_warning() const {
+String Bone2D::get_configuration_warning() const {
String warning = Node2D::get_configuration_warning();
if (!skeleton) {
if (warning != String()) {
@@ -171,9 +171,9 @@ Bone2D::Bone2D() {
//////////////////////////////////////
void Skeleton2D::_make_bone_setup_dirty() {
-
- if (bone_setup_dirty)
+ if (bone_setup_dirty) {
return;
+ }
bone_setup_dirty = true;
if (is_inside_tree()) {
call_deferred("_update_bone_setup");
@@ -181,9 +181,9 @@ void Skeleton2D::_make_bone_setup_dirty() {
}
void Skeleton2D::_update_bone_setup() {
-
- if (!bone_setup_dirty)
+ if (!bone_setup_dirty) {
return;
+ }
bone_setup_dirty = false;
RS::get_singleton()->skeleton_allocate(skeleton, bones.size(), true);
@@ -207,9 +207,9 @@ void Skeleton2D::_update_bone_setup() {
}
void Skeleton2D::_make_transform_dirty() {
-
- if (transform_dirty)
+ if (transform_dirty) {
return;
+ }
transform_dirty = true;
if (is_inside_tree()) {
call_deferred("_update_transform");
@@ -217,18 +217,17 @@ void Skeleton2D::_make_transform_dirty() {
}
void Skeleton2D::_update_transform() {
-
if (bone_setup_dirty) {
_update_bone_setup();
return; //above will update transform anyway
}
- if (!transform_dirty)
+ if (!transform_dirty) {
return;
+ }
transform_dirty = false;
for (int i = 0; i < bones.size(); i++) {
-
ERR_CONTINUE(bones[i].parent_index >= i);
if (bones[i].parent_index >= 0) {
bones.write[i].accum_transform = bones[bones[i].parent_index].accum_transform * bones[i].bone->get_transform();
@@ -238,14 +237,12 @@ void Skeleton2D::_update_transform() {
}
for (int i = 0; i < bones.size(); i++) {
-
Transform2D final_xform = bones[i].accum_transform * bones[i].rest_inverse;
RS::get_singleton()->skeleton_bone_set_transform_2d(skeleton, i, final_xform);
}
}
int Skeleton2D::get_bone_count() const {
-
ERR_FAIL_COND_V(!is_inside_tree(), 0);
if (bone_setup_dirty) {
@@ -256,7 +253,6 @@ int Skeleton2D::get_bone_count() const {
}
Bone2D *Skeleton2D::get_bone(int p_idx) {
-
ERR_FAIL_COND_V(!is_inside_tree(), nullptr);
ERR_FAIL_INDEX_V(p_idx, bones.size(), nullptr);
@@ -264,13 +260,13 @@ Bone2D *Skeleton2D::get_bone(int p_idx) {
}
void Skeleton2D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_READY) {
-
- if (bone_setup_dirty)
+ if (bone_setup_dirty) {
_update_bone_setup();
- if (transform_dirty)
+ }
+ if (transform_dirty) {
_update_transform();
+ }
request_ready();
}
@@ -283,8 +279,8 @@ void Skeleton2D::_notification(int p_what) {
RID Skeleton2D::get_skeleton() const {
return skeleton;
}
-void Skeleton2D::_bind_methods() {
+void Skeleton2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_bone_setup"), &Skeleton2D::_update_bone_setup);
ClassDB::bind_method(D_METHOD("_update_transform"), &Skeleton2D::_update_transform);
@@ -305,6 +301,5 @@ Skeleton2D::Skeleton2D() {
}
Skeleton2D::~Skeleton2D() {
-
RS::get_singleton()->free(skeleton);
}
diff --git a/scene/2d/sprite_2d.cpp b/scene/2d/sprite_2d.cpp
index df8859bd9a..7e07019578 100644
--- a/scene/2d/sprite_2d.cpp
+++ b/scene/2d/sprite_2d.cpp
@@ -61,7 +61,6 @@ bool Sprite2D::_edit_use_pivot() const {
}
bool Sprite2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
return is_pixel_opaque(p_point);
}
@@ -79,7 +78,6 @@ Rect2 Sprite2D::get_anchorable_rect() const {
}
void Sprite2D::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_clip) const {
-
Rect2 base_rect;
if (region) {
@@ -98,28 +96,29 @@ void Sprite2D::_get_rects(Rect2 &r_src_rect, Rect2 &r_dst_rect, bool &r_filter_c
r_src_rect.position = base_rect.position + frame_offset;
Point2 dest_offset = offset;
- if (centered)
+ if (centered) {
dest_offset -= frame_size / 2;
+ }
if (Engine::get_singleton()->get_use_pixel_snap()) {
dest_offset = dest_offset.floor();
}
r_dst_rect = Rect2(dest_offset, frame_size);
- if (hflip)
+ if (hflip) {
r_dst_rect.size.x = -r_dst_rect.size.x;
- if (vflip)
+ }
+ if (vflip) {
r_dst_rect.size.y = -r_dst_rect.size.y;
+ }
}
void Sprite2D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_DRAW: {
-
- if (texture.is_null())
+ if (texture.is_null()) {
return;
+ }
RID ci = get_canvas_item();
@@ -138,17 +137,19 @@ void Sprite2D::_notification(int p_what) {
}
void Sprite2D::set_texture(const Ref<Texture2D> &p_texture) {
-
- if (p_texture == texture)
+ if (p_texture == texture) {
return;
+ }
- if (texture.is_valid())
+ if (texture.is_valid()) {
texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite2D::_texture_changed));
+ }
texture = p_texture;
- if (texture.is_valid())
+ if (texture.is_valid()) {
texture->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite2D::_texture_changed));
+ }
update();
emit_signal("texture_changed");
@@ -157,24 +158,20 @@ void Sprite2D::set_texture(const Ref<Texture2D> &p_texture) {
}
void Sprite2D::set_normal_map(const Ref<Texture2D> &p_texture) {
-
normal_map = p_texture;
update();
}
Ref<Texture2D> Sprite2D::get_normal_map() const {
-
return normal_map;
}
void Sprite2D::set_specular_map(const Ref<Texture2D> &p_texture) {
-
specular = p_texture;
update();
}
Ref<Texture2D> Sprite2D::get_specular_map() const {
-
return specular;
}
@@ -197,83 +194,76 @@ float Sprite2D::get_shininess() const {
}
Ref<Texture2D> Sprite2D::get_texture() const {
-
return texture;
}
void Sprite2D::set_centered(bool p_center) {
-
centered = p_center;
update();
item_rect_changed();
}
bool Sprite2D::is_centered() const {
-
return centered;
}
void Sprite2D::set_offset(const Point2 &p_offset) {
-
offset = p_offset;
update();
item_rect_changed();
_change_notify("offset");
}
-Point2 Sprite2D::get_offset() const {
+Point2 Sprite2D::get_offset() const {
return offset;
}
void Sprite2D::set_flip_h(bool p_flip) {
-
hflip = p_flip;
update();
}
-bool Sprite2D::is_flipped_h() const {
+bool Sprite2D::is_flipped_h() const {
return hflip;
}
void Sprite2D::set_flip_v(bool p_flip) {
-
vflip = p_flip;
update();
}
-bool Sprite2D::is_flipped_v() const {
+bool Sprite2D::is_flipped_v() const {
return vflip;
}
void Sprite2D::set_region(bool p_region) {
-
- if (p_region == region)
+ if (p_region == region) {
return;
+ }
region = p_region;
update();
}
bool Sprite2D::is_region() const {
-
return region;
}
void Sprite2D::set_region_rect(const Rect2 &p_region_rect) {
-
- if (region_rect == p_region_rect)
+ if (region_rect == p_region_rect) {
return;
+ }
region_rect = p_region_rect;
- if (region)
+ if (region) {
item_rect_changed();
+ }
_change_notify("region_rect");
}
Rect2 Sprite2D::get_region_rect() const {
-
return region_rect;
}
@@ -287,11 +277,11 @@ bool Sprite2D::is_region_filter_clip_enabled() const {
}
void Sprite2D::set_frame(int p_frame) {
-
ERR_FAIL_INDEX(p_frame, vframes * hframes);
- if (frame != p_frame)
+ if (frame != p_frame) {
item_rect_changed();
+ }
frame = p_frame;
@@ -301,7 +291,6 @@ void Sprite2D::set_frame(int p_frame) {
}
int Sprite2D::get_frame() const {
-
return frame;
}
@@ -317,52 +306,54 @@ Vector2 Sprite2D::get_frame_coords() const {
}
void Sprite2D::set_vframes(int p_amount) {
-
ERR_FAIL_COND_MSG(p_amount < 1, "Amount of vframes cannot be smaller than 1.");
vframes = p_amount;
update();
item_rect_changed();
_change_notify();
}
-int Sprite2D::get_vframes() const {
+int Sprite2D::get_vframes() const {
return vframes;
}
void Sprite2D::set_hframes(int p_amount) {
-
ERR_FAIL_COND_MSG(p_amount < 1, "Amount of hframes cannot be smaller than 1.");
hframes = p_amount;
update();
item_rect_changed();
_change_notify();
}
-int Sprite2D::get_hframes() const {
+int Sprite2D::get_hframes() const {
return hframes;
}
bool Sprite2D::is_pixel_opaque(const Point2 &p_point) const {
-
- if (texture.is_null())
+ if (texture.is_null()) {
return false;
+ }
- if (texture->get_size().width == 0 || texture->get_size().height == 0)
+ if (texture->get_size().width == 0 || texture->get_size().height == 0) {
return false;
+ }
Rect2 src_rect, dst_rect;
bool filter_clip;
_get_rects(src_rect, dst_rect, filter_clip);
dst_rect.size = dst_rect.size.abs();
- if (!dst_rect.has_point(p_point))
+ if (!dst_rect.has_point(p_point)) {
return false;
+ }
Vector2 q = (p_point - dst_rect.position) / dst_rect.size;
- if (hflip)
+ if (hflip) {
q.x = 1.0f - q.x;
- if (vflip)
+ }
+ if (vflip) {
q.y = 1.0f - q.y;
+ }
q = q * src_rect.size + src_rect.position;
#ifndef _MSC_VER
#warning this need to be obtained from CanvasItem new repeat mode (but it needs to guess it from hierarchy, need to add a function for that)
@@ -393,9 +384,9 @@ bool Sprite2D::is_pixel_opaque(const Point2 &p_point) const {
}
Rect2 Sprite2D::get_rect() const {
-
- if (texture.is_null())
+ if (texture.is_null()) {
return Rect2(0, 0, 1, 1);
+ }
Size2i s;
@@ -408,17 +399,18 @@ Rect2 Sprite2D::get_rect() const {
s = s / Point2(hframes, vframes);
Point2 ofs = offset;
- if (centered)
+ if (centered) {
ofs -= Size2(s) / 2;
+ }
- if (s == Size2(0, 0))
+ if (s == Size2(0, 0)) {
s = Size2(1, 1);
+ }
return Rect2(ofs, s);
}
void Sprite2D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "frame") {
property.hint = PROPERTY_HINT_RANGE;
property.hint_string = "0," + itos(vframes * hframes - 1) + ",1";
@@ -431,7 +423,6 @@ void Sprite2D::_validate_property(PropertyInfo &property) const {
}
void Sprite2D::_texture_changed() {
-
// Changes to the texture need to trigger an update to make
// the editor redraw the sprite with the updated texture.
if (texture.is_valid()) {
@@ -440,7 +431,6 @@ void Sprite2D::_texture_changed() {
}
void Sprite2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Sprite2D::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &Sprite2D::get_texture);
@@ -520,7 +510,6 @@ void Sprite2D::_bind_methods() {
}
Sprite2D::Sprite2D() {
-
centered = true;
hflip = false;
vflip = false;
diff --git a/scene/2d/sprite_2d.h b/scene/2d/sprite_2d.h
index 599a9e937e..c72e956307 100644
--- a/scene/2d/sprite_2d.h
+++ b/scene/2d/sprite_2d.h
@@ -35,7 +35,6 @@
#include "scene/resources/texture.h"
class Sprite2D : public Node2D {
-
GDCLASS(Sprite2D, Node2D);
Ref<Texture2D> texture;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 1cf12e4421..c7a809f6d8 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -39,22 +39,18 @@
#include "servers/physics_server_2d.h"
int TileMap::_get_quadrant_size() const {
-
- if (y_sort_mode)
+ if (use_y_sort) {
return 1;
- else
+ } else {
return quadrant_size;
+ }
}
void TileMap::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
Node2D *c = this;
while (c) {
-
navigation = Object::cast_to<Navigation2D>(c);
if (navigation) {
break;
@@ -79,14 +75,11 @@ void TileMap::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
-
_update_quadrant_space(RID());
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
Quadrant &q = E->get();
if (navigation) {
for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
-
NavigationServer2D::get_singleton()->region_set_map(F->get().region, RID());
}
q.navpoly_ids.clear();
@@ -109,13 +102,11 @@ void TileMap::_notification(int p_what) {
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
//move stuff
_update_quadrant_transform();
} break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
-
if (use_parent) {
_recreate_quadrants();
}
@@ -125,10 +116,8 @@ void TileMap::_notification(int p_what) {
}
void TileMap::_update_quadrant_space(const RID &p_space) {
-
if (!use_parent) {
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
Quadrant &q = E->get();
PhysicsServer2D::get_singleton()->body_set_space(q.body, p_space);
}
@@ -136,22 +125,23 @@ void TileMap::_update_quadrant_space(const RID &p_space) {
}
void TileMap::_update_quadrant_transform() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
Transform2D global_transform = get_global_transform();
Transform2D local_transform;
- if (collision_parent)
+ if (collision_parent) {
local_transform = get_transform();
+ }
Transform2D nav_rel;
- if (navigation)
+ if (navigation) {
nav_rel = get_relative_transform_to_parent(navigation);
+ }
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
Quadrant &q = E->get();
Transform2D xform;
xform.set_origin(q.pos);
@@ -163,7 +153,6 @@ void TileMap::_update_quadrant_transform() {
if (navigation) {
for (Map<PosKey, Quadrant::NavPoly>::Element *F = q.navpoly_ids.front(); F; F = F->next()) {
-
NavigationServer2D::get_singleton()->region_set_transform(F->get().region, nav_rel * F->get().xform);
}
}
@@ -175,7 +164,6 @@ void TileMap::_update_quadrant_transform() {
}
void TileMap::set_tileset(const Ref<TileSet> &p_tileset) {
-
if (tile_set.is_valid()) {
tile_set->disconnect("changed", callable_mp(this, &TileMap::_recreate_quadrants));
tile_set->remove_change_receptor(this);
@@ -196,12 +184,10 @@ void TileMap::set_tileset(const Ref<TileSet> &p_tileset) {
}
Ref<TileSet> TileMap::get_tileset() const {
-
return tile_set;
}
void TileMap::set_cell_size(Size2 p_size) {
-
ERR_FAIL_COND(p_size.x < 1 || p_size.y < 1);
_clear_quadrants();
@@ -211,12 +197,10 @@ void TileMap::set_cell_size(Size2 p_size) {
}
Size2 TileMap::get_cell_size() const {
-
return cell_size;
}
void TileMap::set_quadrant_size(int p_size) {
-
ERR_FAIL_COND_MSG(p_size < 1, "Quadrant size cannot be smaller than 1.");
_clear_quadrants();
@@ -226,17 +210,14 @@ void TileMap::set_quadrant_size(int p_size) {
}
int TileMap::get_quadrant_size() const {
-
return quadrant_size;
}
void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Vector2 &p_offset, const Size2 &p_sc) {
-
Size2 s = p_sc;
Vector2 offset = p_offset;
if (compatibility_mode && !centered_textures) {
-
if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) {
offset.y += cell_size.y;
} else if (tile_origin == TILE_ORIGIN_CENTER) {
@@ -326,9 +307,9 @@ void TileMap::_add_shape(int &shape_idx, const Quadrant &p_q, const Ref<Shape2D>
}
void TileMap::update_dirty_quadrants() {
-
- if (!pending_update)
+ if (!pending_update) {
return;
+ }
if (!is_inside_tree() || !tile_set.is_valid()) {
pending_update = false;
return;
@@ -338,8 +319,9 @@ void TileMap::update_dirty_quadrants() {
PhysicsServer2D *ps = PhysicsServer2D::get_singleton();
Vector2 tofs = get_cell_draw_offset();
Transform2D nav_rel;
- if (navigation)
+ if (navigation) {
nav_rel = get_relative_transform_to_parent(navigation);
+ }
Vector2 qofs;
@@ -358,11 +340,9 @@ void TileMap::update_dirty_quadrants() {
}
while (dirty_quadrant_list.first()) {
-
Quadrant &q = *dirty_quadrant_list.first()->self();
for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) {
-
vs->free(E->get());
}
@@ -377,7 +357,6 @@ void TileMap::update_dirty_quadrants() {
if (navigation) {
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
-
NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
}
q.navpoly_ids.clear();
@@ -393,20 +372,21 @@ void TileMap::update_dirty_quadrants() {
RID prev_debug_canvas_item;
for (int i = 0; i < q.cells.size(); i++) {
-
Map<PosKey, Cell>::Element *E = tile_map.find(q.cells[i]);
Cell &c = E->get();
//moment of truth
- if (!tile_set->has_tile(c.id))
+ if (!tile_set->has_tile(c.id)) {
continue;
+ }
Ref<Texture2D> tex = tile_set->tile_get_texture(c.id);
Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id);
Vector2 wofs = _map_to_world(E->key().x, E->key().y);
Vector2 offset = wofs - q.pos + tofs;
- if (!tex.is_valid())
+ if (!tex.is_valid()) {
continue;
+ }
Ref<ShaderMaterial> mat = tile_set->tile_get_material(c.id);
int z_index = tile_set->tile_get_z_index(c.id);
@@ -420,10 +400,10 @@ void TileMap::update_dirty_quadrants() {
RID debug_canvas_item;
if (prev_canvas_item == RID() || prev_material != mat || prev_z_index != z_index) {
-
canvas_item = vs->canvas_item_create();
- if (mat.is_valid())
+ if (mat.is_valid()) {
vs->canvas_item_set_material(canvas_item, mat->get_rid());
+ }
vs->canvas_item_set_parent(canvas_item, get_canvas_item());
_update_item_material_state(canvas_item);
Transform2D xform;
@@ -435,7 +415,6 @@ void TileMap::update_dirty_quadrants() {
q.canvas_items.push_back(canvas_item);
if (debug_shapes) {
-
debug_canvas_item = vs->canvas_item_create();
vs->canvas_item_set_parent(debug_canvas_item, canvas_item);
vs->canvas_item_set_z_as_relative_to_parent(debug_canvas_item, false);
@@ -463,10 +442,11 @@ void TileMap::update_dirty_quadrants() {
}
Size2 s;
- if (r == Rect2())
+ if (r == Rect2()) {
s = tex->get_size();
- else
+ } else {
s = r.size;
+ }
Rect2 rect;
rect.position = offset.floor();
@@ -476,11 +456,13 @@ void TileMap::update_dirty_quadrants() {
if (compatibility_mode && !centered_textures) {
if (rect.size.y > rect.size.x) {
- if ((c.flip_h && (c.flip_v || c.transpose)) || (c.flip_v && !c.transpose))
+ if ((c.flip_h && (c.flip_v || c.transpose)) || (c.flip_v && !c.transpose)) {
tile_ofs.y += rect.size.y - rect.size.x;
+ }
} else if (rect.size.y < rect.size.x) {
- if ((c.flip_v && (c.flip_h || c.transpose)) || (c.flip_h && !c.transpose))
+ if ((c.flip_v && (c.flip_h || c.transpose)) || (c.flip_h && !c.transpose)) {
tile_ofs.x += rect.size.x - rect.size.y;
+ }
}
}
@@ -509,34 +491,36 @@ void TileMap::update_dirty_quadrants() {
rect.position += tile_ofs;
} else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) {
-
rect.position += tile_ofs;
if (c.transpose) {
- if (c.flip_h)
+ if (c.flip_h) {
rect.position.x -= cell_size.x;
- else
+ } else {
rect.position.x += cell_size.x;
+ }
} else {
- if (c.flip_v)
+ if (c.flip_v) {
rect.position.y -= cell_size.y;
- else
+ } else {
rect.position.y += cell_size.y;
+ }
}
} else if (tile_origin == TILE_ORIGIN_CENTER) {
-
rect.position += tile_ofs;
- if (c.flip_h)
+ if (c.flip_h) {
rect.position.x -= cell_size.x / 2;
- else
+ } else {
rect.position.x += cell_size.x / 2;
+ }
- if (c.flip_v)
+ if (c.flip_v) {
rect.position.y -= cell_size.y / 2;
- else
+ } else {
rect.position.y += cell_size.y / 2;
+ }
}
} else {
rect.position += tile_ofs;
@@ -651,10 +635,8 @@ void TileMap::update_dirty_quadrants() {
Vector<int> polygon = navpoly->get_polygon(j);
for (int k = 2; k < polygon.size(); k++) {
-
int kofs[3] = { 0, k - 1, k };
for (int l = 0; l < 3; l++) {
-
int idx = polygon[kofs[l]];
ERR_FAIL_INDEX(idx, vsize);
indices.push_back(idx);
@@ -704,13 +686,10 @@ void TileMap::update_dirty_quadrants() {
pending_update = false;
if (quadrant_order_dirty) {
-
int index = -(int64_t)0x80000000; //always must be drawn below children
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
Quadrant &q = E->get();
for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) {
-
RS::get_singleton()->canvas_item_set_draw_index(F->get(), index++);
}
}
@@ -722,24 +701,24 @@ void TileMap::update_dirty_quadrants() {
}
void TileMap::_recompute_rect_cache() {
-
#ifdef DEBUG_ENABLED
- if (!rect_cache_dirty)
+ if (!rect_cache_dirty) {
return;
+ }
Rect2 r_total;
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
Rect2 r;
r.position = _map_to_world(E->key().x * _get_quadrant_size(), E->key().y * _get_quadrant_size());
r.expand_to(_map_to_world(E->key().x * _get_quadrant_size() + _get_quadrant_size(), E->key().y * _get_quadrant_size()));
r.expand_to(_map_to_world(E->key().x * _get_quadrant_size() + _get_quadrant_size(), E->key().y * _get_quadrant_size() + _get_quadrant_size()));
r.expand_to(_map_to_world(E->key().x * _get_quadrant_size(), E->key().y * _get_quadrant_size() + _get_quadrant_size()));
- if (E == quadrant_map.front())
+ if (E == quadrant_map.front()) {
r_total = r;
- else
+ } else {
r_total = r_total.merge(r);
+ }
}
rect_cache = r_total;
@@ -751,16 +730,16 @@ void TileMap::_recompute_rect_cache() {
}
Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(const PosKey &p_qk) {
-
Transform2D xform;
//xform.set_origin(Point2(p_qk.x,p_qk.y)*cell_size*quadrant_size);
Quadrant q;
q.pos = _map_to_world(p_qk.x * _get_quadrant_size(), p_qk.y * _get_quadrant_size());
q.pos += get_cell_draw_offset();
- if (tile_origin == TILE_ORIGIN_CENTER)
+ if (tile_origin == TILE_ORIGIN_CENTER) {
q.pos += cell_size / 2;
- else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT)
+ } else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) {
q.pos.y += cell_size.y;
+ }
xform.set_origin(q.pos);
//q.canvas_item = RenderingServer::get_singleton()->canvas_item_create();
@@ -794,7 +773,6 @@ Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(cons
}
void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) {
-
Quadrant &q = Q->get();
if (!use_parent) {
PhysicsServer2D::get_singleton()->free(q.body);
@@ -803,16 +781,15 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) {
}
for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) {
-
RenderingServer::get_singleton()->free(E->get());
}
q.canvas_items.clear();
- if (q.dirty_list.in_list())
+ if (q.dirty_list.in_list()) {
dirty_quadrant_list.remove(&q.dirty_list);
+ }
if (navigation) {
for (Map<PosKey, Quadrant::NavPoly>::Element *E = q.navpoly_ids.front(); E; E = E->next()) {
-
NavigationServer2D::get_singleton()->region_set_map(E->get().region, RID());
}
q.navpoly_ids.clear();
@@ -828,16 +805,18 @@ void TileMap::_erase_quadrant(Map<PosKey, Quadrant>::Element *Q) {
}
void TileMap::_make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool update) {
-
Quadrant &q = Q->get();
- if (!q.dirty_list.in_list())
+ if (!q.dirty_list.in_list()) {
dirty_quadrant_list.add(&q.dirty_list);
+ }
- if (pending_update)
+ if (pending_update) {
return;
+ }
pending_update = true;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
if (update) {
call_deferred("update_dirty_quadrants");
@@ -845,12 +824,10 @@ void TileMap::_make_quadrant_dirty(Map<PosKey, Quadrant>::Element *Q, bool updat
}
void TileMap::set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose) {
-
set_cell(p_pos.x, p_pos.y, p_tile, p_flip_x, p_flip_y, p_transpose);
}
void TileMap::_set_celld(const Vector2 &p_pos, const Dictionary &p_data) {
-
Variant v_pos_x = p_pos.x, v_pos_y = p_pos.y, v_tile = p_data["id"], v_flip_h = p_data["flip_h"], v_flip_v = p_data["flip_y"], v_transpose = p_data["transpose"], v_autotile_coord = p_data["auto_coord"];
const Variant *args[7] = { &v_pos_x, &v_pos_y, &v_tile, &v_flip_h, &v_flip_v, &v_transpose, &v_autotile_coord };
Callable::CallError ce;
@@ -858,12 +835,12 @@ void TileMap::_set_celld(const Vector2 &p_pos, const Dictionary &p_data) {
}
void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_y, bool p_transpose, Vector2 p_autotile_coord) {
-
PosKey pk(p_x, p_y);
Map<PosKey, Cell>::Element *E = tile_map.find(pk);
- if (!E && p_tile == INVALID_CELL)
+ if (!E && p_tile == INVALID_CELL) {
return; //nothing to do
+ }
PosKey qk = pk.to_quadrant(_get_quadrant_size());
if (p_tile == INVALID_CELL) {
@@ -873,10 +850,11 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_
ERR_FAIL_COND(!Q);
Quadrant &q = Q->get();
q.cells.erase(pk);
- if (q.cells.size() == 0)
+ if (q.cells.size() == 0) {
_erase_quadrant(Q);
- else
+ } else {
_make_quadrant_dirty(Q);
+ }
used_size_cache_dirty = true;
return;
@@ -894,8 +872,9 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_
} else {
ERR_FAIL_COND(!Q); // quadrant should exist...
- if (E->get().id == p_tile && E->get().flip_h == p_flip_x && E->get().flip_v == p_flip_y && E->get().transpose == p_transpose && E->get().autotile_coord_x == (uint16_t)p_autotile_coord.x && E->get().autotile_coord_y == (uint16_t)p_autotile_coord.y)
+ if (E->get().id == p_tile && E->get().flip_h == p_flip_x && E->get().flip_v == p_flip_y && E->get().transpose == p_transpose && E->get().autotile_coord_x == (uint16_t)p_autotile_coord.x && E->get().autotile_coord_y == (uint16_t)p_autotile_coord.y) {
return; //nothing changed
+ }
}
Cell &c = E->get();
@@ -912,12 +891,10 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_
}
int TileMap::get_cellv(const Vector2 &p_pos) const {
-
return get_cell(p_pos.x, p_pos.y);
}
void TileMap::make_bitmask_area_dirty(const Vector2 &p_pos) {
-
for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) {
for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) {
PosKey p(x, y);
@@ -929,7 +906,6 @@ void TileMap::make_bitmask_area_dirty(const Vector2 &p_pos) {
}
void TileMap::update_bitmask_area(const Vector2 &p_pos) {
-
for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) {
for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) {
update_cell_bitmask(x, y);
@@ -938,15 +914,11 @@ void TileMap::update_bitmask_area(const Vector2 &p_pos) {
}
void TileMap::update_bitmask_region(const Vector2 &p_start, const Vector2 &p_end) {
-
if ((p_end.x < p_start.x || p_end.y < p_start.y) || (p_end.x == p_start.x && p_end.y == p_start.y)) {
- int i;
Array a = get_used_cells();
- for (i = 0; i < a.size(); i++) {
- // update_bitmask_area() in order to update cells adjacent to the
- // current cell, since ordering in array may not be reliable
+ for (int i = 0; i < a.size(); i++) {
Vector2 vector = (Vector2)a[i];
- update_bitmask_area(Vector2(vector.x, vector.y));
+ update_cell_bitmask(vector.x, vector.y);
}
return;
}
@@ -958,7 +930,6 @@ void TileMap::update_bitmask_region(const Vector2 &p_start, const Vector2 &p_end
}
void TileMap::update_cell_bitmask(int p_x, int p_y) {
-
ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot update cell bitmask if Tileset is not open.");
PosKey p(p_x, p_y);
Map<PosKey, Cell>::Element *E = tile_map.find(p);
@@ -1030,11 +1001,9 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) {
_make_quadrant_dirty(Q);
} else if (tile_set->tile_get_tile_mode(id) == TileSet::SINGLE_TILE) {
-
E->get().autotile_coord_x = 0;
E->get().autotile_coord_y = 0;
} else if (tile_set->tile_get_tile_mode(id) == TileSet::ATLAS_TILE) {
-
if (tile_set->autotile_get_bitmask(id, Vector2(p_x, p_y)) == TileSet::BIND_CENTER) {
Vector2 coord = tile_set->atlastile_get_subtile_by_priority(id, this, Vector2(p_x, p_y));
@@ -1046,7 +1015,6 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) {
}
void TileMap::update_dirty_bitmask() {
-
while (dirty_bitmask.size() > 0) {
update_cell_bitmask(dirty_bitmask[0].x, dirty_bitmask[0].y);
dirty_bitmask.pop_front();
@@ -1054,10 +1022,8 @@ void TileMap::update_dirty_bitmask() {
}
void TileMap::fix_invalid_tiles() {
-
ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot fix invalid tiles if Tileset is not open.");
for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
-
if (!tile_set->has_tile(get_cell(E->key().x, E->key().y))) {
set_cell(E->key().x, E->key().y, INVALID_CELL);
}
@@ -1065,58 +1031,61 @@ void TileMap::fix_invalid_tiles() {
}
int TileMap::get_cell(int p_x, int p_y) const {
-
PosKey pk(p_x, p_y);
const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
- if (!E)
+ if (!E) {
return INVALID_CELL;
+ }
return E->get().id;
}
-bool TileMap::is_cell_x_flipped(int p_x, int p_y) const {
+bool TileMap::is_cell_x_flipped(int p_x, int p_y) const {
PosKey pk(p_x, p_y);
const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
- if (!E)
+ if (!E) {
return false;
+ }
return E->get().flip_h;
}
-bool TileMap::is_cell_y_flipped(int p_x, int p_y) const {
+bool TileMap::is_cell_y_flipped(int p_x, int p_y) const {
PosKey pk(p_x, p_y);
const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
- if (!E)
+ if (!E) {
return false;
+ }
return E->get().flip_v;
}
-bool TileMap::is_cell_transposed(int p_x, int p_y) const {
+bool TileMap::is_cell_transposed(int p_x, int p_y) const {
PosKey pk(p_x, p_y);
const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
- if (!E)
+ if (!E) {
return false;
+ }
return E->get().transpose;
}
void TileMap::set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord) {
-
PosKey pk(p_x, p_y);
const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
- if (!E)
+ if (!E) {
return;
+ }
Cell c = E->get();
c.autotile_coord_x = p_coord.x;
@@ -1126,30 +1095,29 @@ void TileMap::set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord)
PosKey qk = pk.to_quadrant(_get_quadrant_size());
Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
- if (!Q)
+ if (!Q) {
return;
+ }
_make_quadrant_dirty(Q);
}
Vector2 TileMap::get_cell_autotile_coord(int p_x, int p_y) const {
-
PosKey pk(p_x, p_y);
const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
- if (!E)
+ if (!E) {
return Vector2();
+ }
return Vector2(E->get().autotile_coord_x, E->get().autotile_coord_y);
}
void TileMap::_recreate_quadrants() {
-
_clear_quadrants();
for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
-
PosKey qk = PosKey(E->key().x, E->key().y).to_quadrant(_get_quadrant_size());
Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
@@ -1165,50 +1133,41 @@ void TileMap::_recreate_quadrants() {
}
void TileMap::_clear_quadrants() {
-
while (quadrant_map.size()) {
_erase_quadrant(quadrant_map.front());
}
}
void TileMap::set_material(const Ref<Material> &p_material) {
-
CanvasItem::set_material(p_material);
_update_all_items_material_state();
}
void TileMap::set_use_parent_material(bool p_use_parent_material) {
-
CanvasItem::set_use_parent_material(p_use_parent_material);
_update_all_items_material_state();
}
void TileMap::_update_all_items_material_state() {
-
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
Quadrant &q = E->get();
for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) {
-
_update_item_material_state(F->get());
}
}
}
void TileMap::_update_item_material_state(const RID &p_canvas_item) {
-
RS::get_singleton()->canvas_item_set_use_parent_material(p_canvas_item, get_use_parent_material() || get_material().is_valid());
}
void TileMap::clear() {
-
_clear_quadrants();
tile_map.clear();
used_size_cache_dirty = true;
}
void TileMap::_set_tile_data(const Vector<int> &p_data) {
-
ERR_FAIL_COND(format > FORMAT_2);
int c = p_data.size();
@@ -1218,11 +1177,11 @@ void TileMap::_set_tile_data(const Vector<int> &p_data) {
clear();
for (int i = 0; i < c; i += offset) {
-
const uint8_t *ptr = (const uint8_t *)&r[i];
uint8_t local[12];
- for (int j = 0; j < ((format == FORMAT_2) ? 12 : 8); j++)
+ for (int j = 0; j < ((format == FORMAT_2) ? 12 : 8); j++) {
local[j] = ptr[j];
+ }
#ifdef BIG_ENDIAN_ENABLED
@@ -1256,7 +1215,6 @@ void TileMap::_set_tile_data(const Vector<int> &p_data) {
}
Vector<int> TileMap::_get_tile_data() const {
-
Vector<int> data;
data.resize(tile_map.size() * 3);
int *w = data.ptrw();
@@ -1269,12 +1227,15 @@ Vector<int> TileMap::_get_tile_data() const {
encode_uint16(E->key().x, &ptr[0]);
encode_uint16(E->key().y, &ptr[2]);
uint32_t val = E->get().id;
- if (E->get().flip_h)
+ if (E->get().flip_h) {
val |= (1 << 29);
- if (E->get().flip_v)
+ }
+ if (E->get().flip_v) {
val |= (1 << 30);
- if (E->get().transpose)
+ }
+ if (E->get().transpose) {
val |= (1 << 31);
+ }
encode_uint32(val, &ptr[4]);
encode_uint16(E->get().autotile_coord_x, &ptr[8]);
encode_uint16(E->get().autotile_coord_y, &ptr[10]);
@@ -1296,11 +1257,9 @@ Rect2 TileMap::_edit_get_rect() const {
#endif
void TileMap::set_collision_layer(uint32_t p_layer) {
-
collision_layer = p_layer;
if (!use_parent) {
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
Quadrant &q = E->get();
PhysicsServer2D::get_singleton()->body_set_collision_layer(q.body, collision_layer);
}
@@ -1308,11 +1267,9 @@ void TileMap::set_collision_layer(uint32_t p_layer) {
}
void TileMap::set_collision_mask(uint32_t p_mask) {
-
collision_mask = p_mask;
if (!use_parent) {
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
Quadrant &q = E->get();
PhysicsServer2D::get_singleton()->body_set_collision_mask(q.body, collision_mask);
}
@@ -1320,45 +1277,43 @@ void TileMap::set_collision_mask(uint32_t p_mask) {
}
void TileMap::set_collision_layer_bit(int p_bit, bool p_value) {
-
uint32_t layer = get_collision_layer();
- if (p_value)
+ if (p_value) {
layer |= 1 << p_bit;
- else
+ } else {
layer &= ~(1 << p_bit);
+ }
set_collision_layer(layer);
}
void TileMap::set_collision_mask_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
bool TileMap::get_collision_use_kinematic() const {
-
return use_kinematic;
}
void TileMap::set_collision_use_kinematic(bool p_use_kinematic) {
-
_clear_quadrants();
use_kinematic = p_use_kinematic;
_recreate_quadrants();
}
bool TileMap::get_collision_use_parent() const {
-
return use_parent;
}
void TileMap::set_collision_use_parent(bool p_use_parent) {
-
- if (use_parent == p_use_parent) return;
+ if (use_parent == p_use_parent) {
+ return;
+ }
_clear_quadrants();
@@ -1377,11 +1332,9 @@ void TileMap::set_collision_use_parent(bool p_use_parent) {
}
void TileMap::set_collision_friction(float p_friction) {
-
friction = p_friction;
if (!use_parent) {
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
Quadrant &q = E->get();
PhysicsServer2D::get_singleton()->body_set_param(q.body, PhysicsServer2D::BODY_PARAM_FRICTION, p_friction);
}
@@ -1389,48 +1342,40 @@ void TileMap::set_collision_friction(float p_friction) {
}
float TileMap::get_collision_friction() const {
-
return friction;
}
void TileMap::set_collision_bounce(float p_bounce) {
-
bounce = p_bounce;
if (!use_parent) {
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
Quadrant &q = E->get();
PhysicsServer2D::get_singleton()->body_set_param(q.body, PhysicsServer2D::BODY_PARAM_BOUNCE, p_bounce);
}
}
}
-float TileMap::get_collision_bounce() const {
+float TileMap::get_collision_bounce() const {
return bounce;
}
uint32_t TileMap::get_collision_layer() const {
-
return collision_layer;
}
uint32_t TileMap::get_collision_mask() const {
-
return collision_mask;
}
bool TileMap::get_collision_layer_bit(int p_bit) const {
-
return get_collision_layer() & (1 << p_bit);
}
bool TileMap::get_collision_mask_bit(int p_bit) const {
-
return get_collision_mask() & (1 << p_bit);
}
void TileMap::set_mode(Mode p_mode) {
-
_clear_quadrants();
mode = p_mode;
_recreate_quadrants();
@@ -1442,7 +1387,6 @@ TileMap::Mode TileMap::get_mode() const {
}
void TileMap::set_half_offset(HalfOffset p_half_offset) {
-
_clear_quadrants();
half_offset = p_half_offset;
_recreate_quadrants();
@@ -1450,7 +1394,6 @@ void TileMap::set_half_offset(HalfOffset p_half_offset) {
}
void TileMap::set_tile_origin(TileOrigin p_tile_origin) {
-
_clear_quadrants();
tile_origin = p_tile_origin;
_recreate_quadrants();
@@ -1458,25 +1401,19 @@ void TileMap::set_tile_origin(TileOrigin p_tile_origin) {
}
TileMap::TileOrigin TileMap::get_tile_origin() const {
-
return tile_origin;
}
Vector2 TileMap::get_cell_draw_offset() const {
-
switch (mode) {
-
case MODE_SQUARE: {
-
return Vector2();
} break;
case MODE_ISOMETRIC: {
-
return Vector2(-cell_size.x * 0.5, 0);
} break;
case MODE_CUSTOM: {
-
Vector2 min;
min.x = MIN(custom_transform[0].x, min.x);
min.y = MIN(custom_transform[0].y, min.y);
@@ -1494,18 +1431,14 @@ TileMap::HalfOffset TileMap::get_half_offset() const {
}
Transform2D TileMap::get_cell_transform() const {
-
switch (mode) {
-
case MODE_SQUARE: {
-
Transform2D m;
m[0] *= cell_size.x;
m[1] *= cell_size.y;
return m;
} break;
case MODE_ISOMETRIC: {
-
//isometric only makes sense when y is positive in both x and y vectors, otherwise
//the drawing of tiles will overlap
Transform2D m;
@@ -1515,7 +1448,6 @@ Transform2D TileMap::get_cell_transform() const {
} break;
case MODE_CUSTOM: {
-
return custom_transform;
} break;
}
@@ -1524,7 +1456,6 @@ Transform2D TileMap::get_cell_transform() const {
}
void TileMap::set_custom_transform(const Transform2D &p_xform) {
-
_clear_quadrants();
custom_transform = p_xform;
_recreate_quadrants();
@@ -1532,20 +1463,16 @@ void TileMap::set_custom_transform(const Transform2D &p_xform) {
}
Transform2D TileMap::get_custom_transform() const {
-
return custom_transform;
}
Vector2 TileMap::_map_to_world(int p_x, int p_y, bool p_ignore_ofs) const {
-
Vector2 ret = get_cell_transform().xform(Vector2(p_x, p_y));
if (!p_ignore_ofs) {
switch (half_offset) {
-
case HALF_OFFSET_X:
case HALF_OFFSET_NEGATIVE_X: {
if (ABS(p_y) & 1) {
-
ret += get_cell_transform()[0] * (half_offset == HALF_OFFSET_X ? 0.5 : -0.5);
}
} break;
@@ -1564,7 +1491,6 @@ Vector2 TileMap::_map_to_world(int p_x, int p_y, bool p_ignore_ofs) const {
}
bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
-
if (p_name == "format") {
if (p_value.get_type() == Variant::INT) {
format = (DataFormat)(p_value.operator int64_t()); // Set format used for loading
@@ -1581,7 +1507,6 @@ bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
}
bool TileMap::_get(const StringName &p_name, Variant &r_ret) const {
-
if (p_name == "format") {
r_ret = FORMAT_2; // When saving, always save highest format
return true;
@@ -1593,7 +1518,6 @@ bool TileMap::_get(const StringName &p_name, Variant &r_ret) const {
}
void TileMap::_get_property_list(List<PropertyInfo> *p_list) const {
-
PropertyInfo p(Variant::INT, "format", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL);
p_list->push_back(p);
@@ -1608,16 +1532,13 @@ void TileMap::_validate_property(PropertyInfo &property) const {
}
Vector2 TileMap::map_to_world(const Vector2 &p_pos, bool p_ignore_ofs) const {
-
return _map_to_world(p_pos.x, p_pos.y, p_ignore_ofs);
}
Vector2 TileMap::world_to_map(const Vector2 &p_pos) const {
-
Vector2 ret = get_cell_transform().affine_inverse().xform(p_pos);
switch (half_offset) {
-
case HALF_OFFSET_X: {
if (int(floor(ret.y)) & 1) {
ret.x -= 0.5;
@@ -1651,22 +1572,19 @@ Vector2 TileMap::world_to_map(const Vector2 &p_pos) const {
return ret.floor();
}
-void TileMap::set_y_sort_mode(bool p_enable) {
-
+void TileMap::set_y_sort_enabled(bool p_enable) {
_clear_quadrants();
- y_sort_mode = p_enable;
- RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), y_sort_mode);
+ use_y_sort = p_enable;
+ RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), use_y_sort);
_recreate_quadrants();
emit_signal("settings_changed");
}
-bool TileMap::is_y_sort_mode_enabled() const {
-
- return y_sort_mode;
+bool TileMap::is_y_sort_enabled() const {
+ return use_y_sort;
}
void TileMap::set_compatibility_mode(bool p_enable) {
-
_clear_quadrants();
compatibility_mode = p_enable;
_recreate_quadrants();
@@ -1674,12 +1592,10 @@ void TileMap::set_compatibility_mode(bool p_enable) {
}
bool TileMap::is_compatibility_mode_enabled() const {
-
return compatibility_mode;
}
void TileMap::set_centered_textures(bool p_enable) {
-
_clear_quadrants();
centered_textures = p_enable;
_recreate_quadrants();
@@ -1687,31 +1603,26 @@ void TileMap::set_centered_textures(bool p_enable) {
}
bool TileMap::is_centered_textures_enabled() const {
-
return centered_textures;
}
-Array TileMap::get_used_cells() const {
-
- Array a;
+TypedArray<Vector2i> TileMap::get_used_cells() const {
+ TypedArray<Vector2i> a;
a.resize(tile_map.size());
int i = 0;
for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
-
- Vector2 p(E->key().x, E->key().y);
+ Vector2i p(E->key().x, E->key().y);
a[i++] = p;
}
return a;
}
-Array TileMap::get_used_cells_by_id(int p_id) const {
-
- Array a;
+TypedArray<Vector2i> TileMap::get_used_cells_by_index(int p_id) const {
+ TypedArray<Vector2i> a;
for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) {
-
if (E->value().id == p_id) {
- Vector2 p(E->key().x, E->key().y);
+ Vector2i p(E->key().x, E->key().y);
a.push_back(p);
}
}
@@ -1741,10 +1652,8 @@ Rect2 TileMap::get_used_rect() { // Not const because of cache
}
void TileMap::set_occluder_light_mask(int p_mask) {
-
occluder_light_mask = p_mask;
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
for (Map<PosKey, Quadrant::Occluder>::Element *F = E->get().occluder_instances.front(); F; F = F->next()) {
RenderingServer::get_singleton()->canvas_light_occluder_set_light_mask(F->get().id, occluder_light_mask);
}
@@ -1752,15 +1661,12 @@ void TileMap::set_occluder_light_mask(int p_mask) {
}
int TileMap::get_occluder_light_mask() const {
-
return occluder_light_mask;
}
void TileMap::set_light_mask(int p_light_mask) {
-
CanvasItem::set_light_mask(p_light_mask);
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
-
for (List<RID>::Element *F = E->get().canvas_items.front(); F; F = F->next()) {
RenderingServer::get_singleton()->canvas_item_set_light_mask(F->get(), get_light_mask());
}
@@ -1768,9 +1674,9 @@ void TileMap::set_light_mask(int p_light_mask) {
}
void TileMap::set_clip_uv(bool p_enable) {
-
- if (clip_uv == p_enable)
+ if (clip_uv == p_enable) {
return;
+ }
_clear_quadrants();
clip_uv = p_enable;
@@ -1778,12 +1684,10 @@ void TileMap::set_clip_uv(bool p_enable) {
}
bool TileMap::get_clip_uv() const {
-
return clip_uv;
}
String TileMap::get_configuration_warning() const {
-
String warning = Node2D::get_configuration_warning();
if (use_parent && !collision_parent) {
@@ -1797,7 +1701,6 @@ String TileMap::get_configuration_warning() const {
}
void TileMap::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_tileset", "tileset"), &TileMap::set_tileset);
ClassDB::bind_method(D_METHOD("get_tileset"), &TileMap::get_tileset);
@@ -1825,8 +1728,8 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_clip_uv", "enable"), &TileMap::set_clip_uv);
ClassDB::bind_method(D_METHOD("get_clip_uv"), &TileMap::get_clip_uv);
- ClassDB::bind_method(D_METHOD("set_y_sort_mode", "enable"), &TileMap::set_y_sort_mode);
- ClassDB::bind_method(D_METHOD("is_y_sort_mode_enabled"), &TileMap::is_y_sort_mode_enabled);
+ ClassDB::bind_method(D_METHOD("set_y_sort_enabled", "enable"), &TileMap::set_y_sort_enabled);
+ ClassDB::bind_method(D_METHOD("is_y_sort_enabled"), &TileMap::is_y_sort_enabled);
ClassDB::bind_method(D_METHOD("set_compatibility_mode", "enable"), &TileMap::set_compatibility_mode);
ClassDB::bind_method(D_METHOD("is_compatibility_mode_enabled"), &TileMap::is_compatibility_mode_enabled);
@@ -1876,7 +1779,7 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear);
ClassDB::bind_method(D_METHOD("get_used_cells"), &TileMap::get_used_cells);
- ClassDB::bind_method(D_METHOD("get_used_cells_by_id", "id"), &TileMap::get_used_cells_by_id);
+ ClassDB::bind_method(D_METHOD("get_used_cells_by_index", "index"), &TileMap::get_used_cells_by_index);
ClassDB::bind_method(D_METHOD("get_used_rect"), &TileMap::get_used_rect);
ClassDB::bind_method(D_METHOD("map_to_world", "map_position", "ignore_half_ofs"), &TileMap::map_to_world, DEFVAL(false));
@@ -1900,7 +1803,7 @@ void TileMap::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "cell_custom_transform"), "set_custom_transform", "get_custom_transform");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_half_offset", PROPERTY_HINT_ENUM, "Offset X,Offset Y,Disabled,Offset Negative X,Offset Negative Y"), "set_half_offset", "get_half_offset");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_tile_origin", PROPERTY_HINT_ENUM, "Top Left,Center,Bottom Left"), "set_tile_origin", "get_tile_origin");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_y_sort"), "set_y_sort_mode", "is_y_sort_mode_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_y_sort"), "set_y_sort_enabled", "is_y_sort_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "compatibility_mode"), "set_compatibility_mode", "is_compatibility_mode_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered_textures"), "set_centered_textures", "is_centered_textures_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_clip_uv"), "set_clip_uv", "get_clip_uv");
@@ -1944,7 +1847,6 @@ void TileMap::_changed_callback(Object *p_changed, const char *p_prop) {
}
TileMap::TileMap() {
-
rect_cache_dirty = true;
used_size_cache_dirty = true;
pending_update = false;
@@ -1962,7 +1864,7 @@ TileMap::TileMap() {
collision_parent = nullptr;
use_kinematic = false;
navigation = nullptr;
- y_sort_mode = false;
+ use_y_sort = false;
compatibility_mode = false;
centered_textures = false;
occluder_light_mask = 1;
@@ -1976,9 +1878,9 @@ TileMap::TileMap() {
}
TileMap::~TileMap() {
-
- if (tile_set.is_valid())
+ if (tile_set.is_valid()) {
tile_set->remove_change_receptor(this);
+ }
clear();
}
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index d9490aae13..24d4dc09db 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -40,7 +40,6 @@
class CollisionObject2D;
class TileMap : public Node2D {
-
GDCLASS(TileMap, Node2D);
public:
@@ -82,7 +81,6 @@ private:
Navigation2D *navigation;
union PosKey {
-
struct {
int16_t x;
int16_t y;
@@ -112,7 +110,6 @@ private:
};
union Cell {
-
struct {
int32_t id : 24;
bool flip_h : 1;
@@ -130,7 +127,6 @@ private:
List<PosKey> dirty_bitmask;
struct Quadrant {
-
Vector2 pos;
List<RID> canvas_items;
RID body;
@@ -187,7 +183,7 @@ private:
Rect2 used_size_cache;
bool used_size_cache_dirty;
bool quadrant_order_dirty;
- bool y_sort_mode;
+ bool use_y_sort;
bool compatibility_mode;
bool centered_textures;
bool clip_uv;
@@ -319,8 +315,8 @@ public:
Vector2 map_to_world(const Vector2 &p_pos, bool p_ignore_ofs = false) const;
Vector2 world_to_map(const Vector2 &p_pos) const;
- void set_y_sort_mode(bool p_enable);
- bool is_y_sort_mode_enabled() const;
+ void set_y_sort_enabled(bool p_enable);
+ bool is_y_sort_enabled() const;
void set_compatibility_mode(bool p_enable);
bool is_compatibility_mode_enabled() const;
@@ -328,8 +324,8 @@ public:
void set_centered_textures(bool p_enable);
bool is_centered_textures_enabled() const;
- Array get_used_cells() const;
- Array get_used_cells_by_id(int p_id) const;
+ TypedArray<Vector2i> get_used_cells() const;
+ TypedArray<Vector2i> get_used_cells_by_index(int p_index) const;
Rect2 get_used_rect(); // Not const because of cache
void set_occluder_light_mask(int p_mask);
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index 2cb979a0e0..4597300db8 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -30,110 +30,102 @@
#include "touch_screen_button.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/input/input_map.h"
#include "core/os/os.h"
#include "scene/main/window.h"
#
void TouchScreenButton::set_texture(const Ref<Texture2D> &p_texture) {
-
texture = p_texture;
update();
}
Ref<Texture2D> TouchScreenButton::get_texture() const {
-
return texture;
}
void TouchScreenButton::set_texture_pressed(const Ref<Texture2D> &p_texture_pressed) {
-
texture_pressed = p_texture_pressed;
update();
}
Ref<Texture2D> TouchScreenButton::get_texture_pressed() const {
-
return texture_pressed;
}
void TouchScreenButton::set_bitmask(const Ref<BitMap> &p_bitmask) {
-
bitmask = p_bitmask;
}
Ref<BitMap> TouchScreenButton::get_bitmask() const {
-
return bitmask;
}
void TouchScreenButton::set_shape(const Ref<Shape2D> &p_shape) {
-
- if (shape.is_valid())
+ if (shape.is_valid()) {
shape->disconnect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update));
+ }
shape = p_shape;
- if (shape.is_valid())
+ if (shape.is_valid()) {
shape->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update));
+ }
update();
}
Ref<Shape2D> TouchScreenButton::get_shape() const {
-
return shape;
}
void TouchScreenButton::set_shape_centered(bool p_shape_centered) {
-
shape_centered = p_shape_centered;
update();
}
bool TouchScreenButton::is_shape_visible() const {
-
return shape_visible;
}
void TouchScreenButton::set_shape_visible(bool p_shape_visible) {
-
shape_visible = p_shape_visible;
update();
}
bool TouchScreenButton::is_shape_centered() const {
-
return shape_centered;
}
void TouchScreenButton::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_DRAW: {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
- if (!Engine::get_singleton()->is_editor_hint() && !!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id())) && visibility == VISIBILITY_TOUCHSCREEN_ONLY)
+ }
+ if (!Engine::get_singleton()->is_editor_hint() && !!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id())) && visibility == VISIBILITY_TOUCHSCREEN_ONLY) {
return;
+ }
if (finger_pressed != -1) {
-
- if (texture_pressed.is_valid())
+ if (texture_pressed.is_valid()) {
draw_texture(texture_pressed, Point2());
- else if (texture.is_valid())
+ } else if (texture.is_valid()) {
draw_texture(texture, Point2());
+ }
} else {
- if (texture.is_valid())
+ if (texture.is_valid()) {
draw_texture(texture, Point2());
+ }
}
- if (!shape_visible)
+ if (!shape_visible) {
return;
- if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint())
+ }
+ if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) {
return;
+ }
if (shape.is_valid()) {
Color draw_col = get_tree()->get_debug_collisions_color();
@@ -145,80 +137,79 @@ void TouchScreenButton::_notification(int p_what) {
} break;
case NOTIFICATION_ENTER_TREE: {
-
- if (!Engine::get_singleton()->is_editor_hint() && !!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id())) && visibility == VISIBILITY_TOUCHSCREEN_ONLY)
+ if (!Engine::get_singleton()->is_editor_hint() && !!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id())) && visibility == VISIBILITY_TOUCHSCREEN_ONLY) {
return;
+ }
update();
- if (!Engine::get_singleton()->is_editor_hint())
+ if (!Engine::get_singleton()->is_editor_hint()) {
set_process_input(is_visible_in_tree());
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
- if (is_pressed())
+ if (is_pressed()) {
_release(true);
+ }
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
- if (Engine::get_singleton()->is_editor_hint())
+ if (Engine::get_singleton()->is_editor_hint()) {
break;
+ }
if (is_visible_in_tree()) {
set_process_input(true);
} else {
set_process_input(false);
- if (is_pressed())
+ if (is_pressed()) {
_release();
+ }
}
} break;
case NOTIFICATION_PAUSED: {
- if (is_pressed())
+ if (is_pressed()) {
_release();
+ }
} break;
}
}
bool TouchScreenButton::is_pressed() const {
-
return finger_pressed != -1;
}
void TouchScreenButton::set_action(const String &p_action) {
-
action = p_action;
}
String TouchScreenButton::get_action() const {
-
return action;
}
void TouchScreenButton::_input(const Ref<InputEvent> &p_event) {
-
- if (!get_tree())
+ if (!get_tree()) {
return;
+ }
- if (p_event->get_device() != 0)
+ if (p_event->get_device() != 0) {
return;
+ }
ERR_FAIL_COND(!is_visible_in_tree());
const InputEventScreenTouch *st = Object::cast_to<InputEventScreenTouch>(*p_event);
if (passby_press) {
-
const InputEventScreenDrag *sd = Object::cast_to<InputEventScreenDrag>(*p_event);
if (st && !st->is_pressed() && finger_pressed == st->get_index()) {
-
_release();
}
if ((st && st->is_pressed()) || sd) {
-
int index = st ? st->get_index() : sd->get_index();
Point2 coord = st ? st->get_position() : sd->get_position();
if (finger_pressed == -1 || index == finger_pressed) {
-
if (_is_point_inside(coord)) {
if (finger_pressed == -1) {
_press(index);
@@ -232,14 +223,12 @@ void TouchScreenButton::_input(const Ref<InputEvent> &p_event) {
}
} else {
-
if (st) {
-
if (st->is_pressed()) {
-
const bool can_press = finger_pressed == -1;
- if (!can_press)
+ if (!can_press) {
return; //already fingering
+ }
if (_is_point_inside(st->get_position())) {
_press(st->get_index());
@@ -260,37 +249,36 @@ bool TouchScreenButton::_is_point_inside(const Point2 &p_point) {
bool check_rect = true;
if (shape.is_valid()) {
-
check_rect = false;
- Transform2D xform = shape_centered ? Transform2D().translated(shape->get_rect().size * 0.5f) : Transform2D();
+
+ Vector2 size = texture.is_null() ? shape->get_rect().size : texture->get_size();
+ Transform2D xform = shape_centered ? Transform2D().translated(size * 0.5f) : Transform2D();
touched = shape->collide(xform, unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5)));
}
if (bitmask.is_valid()) {
-
check_rect = false;
if (!touched && Rect2(Point2(), bitmask->get_size()).has_point(coord)) {
-
- if (bitmask->get_bit(coord))
+ if (bitmask->get_bit(coord)) {
touched = true;
+ }
}
}
if (!touched && check_rect) {
- if (texture.is_valid())
+ if (texture.is_valid()) {
touched = Rect2(Size2(), texture->get_size()).has_point(coord);
+ }
}
return touched;
}
void TouchScreenButton::_press(int p_finger_pressed) {
-
finger_pressed = p_finger_pressed;
if (action != StringName()) {
-
- InputFilter::get_singleton()->action_press(action);
+ Input::get_singleton()->action_press(action);
Ref<InputEventAction> iea;
iea.instance();
iea->set_action(action);
@@ -303,14 +291,11 @@ void TouchScreenButton::_press(int p_finger_pressed) {
}
void TouchScreenButton::_release(bool p_exiting_tree) {
-
finger_pressed = -1;
if (action != StringName()) {
-
- InputFilter::get_singleton()->action_release(action);
+ Input::get_singleton()->action_release(action);
if (!p_exiting_tree) {
-
Ref<InputEventAction> iea;
iea.instance();
iea->set_action(action);
@@ -327,8 +312,9 @@ void TouchScreenButton::_release(bool p_exiting_tree) {
#ifdef TOOLS_ENABLED
Rect2 TouchScreenButton::_edit_get_rect() const {
- if (texture.is_null())
+ if (texture.is_null()) {
return CanvasItem::_edit_get_rect();
+ }
return Rect2(Size2(), texture->get_size());
}
@@ -339,8 +325,9 @@ bool TouchScreenButton::_edit_use_rect() const {
#endif
Rect2 TouchScreenButton::get_anchorable_rect() const {
- if (texture.is_null())
+ if (texture.is_null()) {
return CanvasItem::get_anchorable_rect();
+ }
return Rect2(Size2(), texture->get_size());
}
@@ -351,22 +338,18 @@ void TouchScreenButton::set_visibility_mode(VisibilityMode p_mode) {
}
TouchScreenButton::VisibilityMode TouchScreenButton::get_visibility_mode() const {
-
return visibility;
}
void TouchScreenButton::set_passby_press(bool p_enable) {
-
passby_press = p_enable;
}
bool TouchScreenButton::is_passby_press_enabled() const {
-
return passby_press;
}
void TouchScreenButton::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &TouchScreenButton::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &TouchScreenButton::get_texture);
@@ -416,7 +399,6 @@ void TouchScreenButton::_bind_methods() {
}
TouchScreenButton::TouchScreenButton() {
-
finger_pressed = -1;
passby_press = false;
visibility = VISIBILITY_ALWAYS;
diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h
index 42e93f7048..d9c7ef7034 100644
--- a/scene/2d/touch_screen_button.h
+++ b/scene/2d/touch_screen_button.h
@@ -37,7 +37,6 @@
#include "scene/resources/texture.h"
class TouchScreenButton : public Node2D {
-
GDCLASS(TouchScreenButton, Node2D);
public:
diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp
index c374dd5faa..75154c7acb 100644
--- a/scene/2d/visibility_notifier_2d.cpp
+++ b/scene/2d/visibility_notifier_2d.cpp
@@ -49,12 +49,12 @@ bool VisibilityNotifier2D::_edit_use_rect() const {
#endif
void VisibilityNotifier2D::_enter_viewport(Viewport *p_viewport) {
-
ERR_FAIL_COND(viewports.has(p_viewport));
viewports.insert(p_viewport);
- if (is_inside_tree() && Engine::get_singleton()->is_editor_hint())
+ if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
return;
+ }
if (viewports.size() == 1) {
emit_signal(SceneStringNames::get_singleton()->screen_entered);
@@ -65,12 +65,12 @@ void VisibilityNotifier2D::_enter_viewport(Viewport *p_viewport) {
}
void VisibilityNotifier2D::_exit_viewport(Viewport *p_viewport) {
-
ERR_FAIL_COND(!viewports.has(p_viewport));
viewports.erase(p_viewport);
- if (is_inside_tree() && Engine::get_singleton()->is_editor_hint())
+ if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
return;
+ }
emit_signal(SceneStringNames::get_singleton()->viewport_exited, p_viewport);
if (viewports.size() == 0) {
@@ -81,7 +81,6 @@ void VisibilityNotifier2D::_exit_viewport(Viewport *p_viewport) {
}
void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) {
-
rect = p_rect;
if (is_inside_tree()) {
get_world_2d()->_update_notifier(this, get_global_transform().xform(rect));
@@ -95,44 +94,35 @@ void VisibilityNotifier2D::set_rect(const Rect2 &p_rect) {
}
Rect2 VisibilityNotifier2D::get_rect() const {
-
return rect;
}
void VisibilityNotifier2D::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
-
//get_world_2d()->
get_world_2d()->_register_notifier(this, get_global_transform().xform(rect));
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
//get_world_2d()->
get_world_2d()->_update_notifier(this, get_global_transform().xform(rect));
} break;
case NOTIFICATION_DRAW: {
-
if (Engine::get_singleton()->is_editor_hint()) {
-
draw_rect(rect, Color(1, 0.5, 1, 0.2));
}
} break;
case NOTIFICATION_EXIT_TREE: {
-
get_world_2d()->_remove_notifier(this);
} break;
}
}
bool VisibilityNotifier2D::is_on_screen() const {
-
return viewports.size() > 0;
}
void VisibilityNotifier2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_rect", "rect"), &VisibilityNotifier2D::set_rect);
ClassDB::bind_method(D_METHOD("get_rect"), &VisibilityNotifier2D::get_rect);
ClassDB::bind_method(D_METHOD("is_on_screen"), &VisibilityNotifier2D::is_on_screen);
@@ -146,7 +136,6 @@ void VisibilityNotifier2D::_bind_methods() {
}
VisibilityNotifier2D::VisibilityNotifier2D() {
-
rect = Rect2(-10, -10, 20, 20);
set_notify_transform(true);
}
@@ -154,44 +143,42 @@ VisibilityNotifier2D::VisibilityNotifier2D() {
//////////////////////////////////////
void VisibilityEnabler2D::_screen_enter() {
-
for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
-
_change_node_state(E->key(), true);
}
- if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent())
+ if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) {
get_parent()->set_physics_process(true);
- if (enabler[ENABLER_PARENT_PROCESS] && get_parent())
+ }
+ if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) {
get_parent()->set_process(true);
+ }
visible = true;
}
void VisibilityEnabler2D::_screen_exit() {
-
for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
-
_change_node_state(E->key(), false);
}
- if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent())
+ if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) {
get_parent()->set_physics_process(false);
- if (enabler[ENABLER_PARENT_PROCESS] && get_parent())
+ }
+ if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) {
get_parent()->set_process(false);
+ }
visible = false;
}
void VisibilityEnabler2D::_find_nodes(Node *p_node) {
-
bool add = false;
Variant meta;
{
RigidBody2D *rb2d = Object::cast_to<RigidBody2D>(p_node);
if (rb2d && ((rb2d->get_mode() == RigidBody2D::MODE_CHARACTER || rb2d->get_mode() == RigidBody2D::MODE_RIGID))) {
-
add = true;
meta = rb2d->get_mode();
}
@@ -219,7 +206,6 @@ void VisibilityEnabler2D::_find_nodes(Node *p_node) {
}
if (add) {
-
p_node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler2D::_node_removed), varray(p_node), CONNECT_ONESHOT);
nodes[p_node] = meta;
_change_node_state(p_node, false);
@@ -227,42 +213,52 @@ void VisibilityEnabler2D::_find_nodes(Node *p_node) {
for (int i = 0; i < p_node->get_child_count(); i++) {
Node *c = p_node->get_child(i);
- if (c->get_filename() != String())
+ if (c->get_filename() != String()) {
continue; //skip, instance
+ }
_find_nodes(c);
}
}
void VisibilityEnabler2D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
- if (Engine::get_singleton()->is_editor_hint())
+ if (Engine::get_singleton()->is_editor_hint()) {
return;
+ }
Node *from = this;
//find where current scene starts
- while (from->get_parent() && from->get_filename() == String())
+ while (from->get_parent() && from->get_filename() == String()) {
from = from->get_parent();
+ }
_find_nodes(from);
- if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent())
- get_parent()->set_physics_process(false);
- if (enabler[ENABLER_PARENT_PROCESS] && get_parent())
- get_parent()->set_process(false);
+ // We need to defer the call of set_process and set_physics_process,
+ // otherwise they are overwritten inside NOTIFICATION_READY.
+ // We can't use call_deferred, because it happens after a physics frame.
+ // The ready signal works as it's emitted immediately after NOTIFICATION_READY.
+
+ if (enabler[ENABLER_PARENT_PHYSICS_PROCESS] && get_parent()) {
+ get_parent()->connect(SceneStringNames::get_singleton()->ready,
+ callable_mp(get_parent(), &Node::set_physics_process), varray(false), CONNECT_ONESHOT);
+ }
+ if (enabler[ENABLER_PARENT_PROCESS] && get_parent()) {
+ get_parent()->connect(SceneStringNames::get_singleton()->ready,
+ callable_mp(get_parent(), &Node::set_process), varray(false), CONNECT_ONESHOT);
+ }
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
- if (Engine::get_singleton()->is_editor_hint())
+ if (Engine::get_singleton()->is_editor_hint()) {
return;
+ }
for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
-
- if (!visible)
+ if (!visible) {
_change_node_state(E->key(), true);
+ }
E->key()->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler2D::_node_removed));
}
@@ -271,13 +267,11 @@ void VisibilityEnabler2D::_notification(int p_what) {
}
void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) {
-
ERR_FAIL_COND(!nodes.has(p_node));
if (enabler[ENABLER_FREEZE_BODIES]) {
RigidBody2D *rb = Object::cast_to<RigidBody2D>(p_node);
if (rb) {
-
rb->set_sleeping(!p_enabled);
}
}
@@ -286,7 +280,6 @@ void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) {
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
if (ap) {
-
ap->set_active(p_enabled);
}
}
@@ -295,11 +288,11 @@ void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) {
AnimatedSprite2D *as = Object::cast_to<AnimatedSprite2D>(p_node);
if (as) {
-
- if (p_enabled)
+ if (p_enabled) {
as->play();
- else
+ } else {
as->stop();
+ }
}
}
@@ -307,16 +300,15 @@ void VisibilityEnabler2D::_change_node_state(Node *p_node, bool p_enabled) {
GPUParticles2D *ps = Object::cast_to<GPUParticles2D>(p_node);
if (ps) {
-
ps->set_emitting(p_enabled);
}
}
}
void VisibilityEnabler2D::_node_removed(Node *p_node) {
-
- if (!visible)
+ if (!visible) {
_change_node_state(p_node, true);
+ }
nodes.erase(p_node);
}
@@ -330,7 +322,6 @@ String VisibilityEnabler2D::get_configuration_warning() const {
}
void VisibilityEnabler2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_enabler", "enabler", "enabled"), &VisibilityEnabler2D::set_enabler);
ClassDB::bind_method(D_METHOD("is_enabler_enabled", "enabler"), &VisibilityEnabler2D::is_enabler_enabled);
ClassDB::bind_method(D_METHOD("_node_removed"), &VisibilityEnabler2D::_node_removed);
@@ -352,20 +343,19 @@ void VisibilityEnabler2D::_bind_methods() {
}
void VisibilityEnabler2D::set_enabler(Enabler p_enabler, bool p_enable) {
-
ERR_FAIL_INDEX(p_enabler, ENABLER_MAX);
enabler[p_enabler] = p_enable;
}
-bool VisibilityEnabler2D::is_enabler_enabled(Enabler p_enabler) const {
+bool VisibilityEnabler2D::is_enabler_enabled(Enabler p_enabler) const {
ERR_FAIL_INDEX_V(p_enabler, ENABLER_MAX, false);
return enabler[p_enabler];
}
VisibilityEnabler2D::VisibilityEnabler2D() {
-
- for (int i = 0; i < ENABLER_MAX; i++)
+ for (int i = 0; i < ENABLER_MAX; i++) {
enabler[i] = true;
+ }
enabler[ENABLER_PARENT_PROCESS] = false;
enabler[ENABLER_PARENT_PHYSICS_PROCESS] = false;
diff --git a/scene/2d/visibility_notifier_2d.h b/scene/2d/visibility_notifier_2d.h
index a3b79d29e9..fb6e48f5e8 100644
--- a/scene/2d/visibility_notifier_2d.h
+++ b/scene/2d/visibility_notifier_2d.h
@@ -35,7 +35,6 @@
class Viewport;
class VisibilityNotifier2D : public Node2D {
-
GDCLASS(VisibilityNotifier2D, Node2D);
Set<Viewport *> viewports;
@@ -69,7 +68,6 @@ public:
};
class VisibilityEnabler2D : public VisibilityNotifier2D {
-
GDCLASS(VisibilityEnabler2D, VisibilityNotifier2D);
public:
diff --git a/scene/2d/y_sort.cpp b/scene/2d/y_sort.cpp
index 15d97eeaa0..7c2b41db70 100644
--- a/scene/2d/y_sort.cpp
+++ b/scene/2d/y_sort.cpp
@@ -31,18 +31,15 @@
#include "y_sort.h"
void YSort::set_sort_enabled(bool p_enabled) {
-
sort_enabled = p_enabled;
RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), sort_enabled);
}
bool YSort::is_sort_enabled() const {
-
return sort_enabled;
}
void YSort::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_sort_enabled", "enabled"), &YSort::set_sort_enabled);
ClassDB::bind_method(D_METHOD("is_sort_enabled"), &YSort::is_sort_enabled);
@@ -51,7 +48,6 @@ void YSort::_bind_methods() {
}
YSort::YSort() {
-
sort_enabled = true;
RS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(), true);
}
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index 17ae553e5e..a024757927 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -35,27 +35,24 @@
#include "servers/physics_server_3d.h"
void Area3D::set_space_override_mode(SpaceOverride p_mode) {
-
space_override = p_mode;
PhysicsServer3D::get_singleton()->area_set_space_override_mode(get_rid(), PhysicsServer3D::AreaSpaceOverrideMode(p_mode));
}
-Area3D::SpaceOverride Area3D::get_space_override_mode() const {
+Area3D::SpaceOverride Area3D::get_space_override_mode() const {
return space_override;
}
void Area3D::set_gravity_is_point(bool p_enabled) {
-
gravity_is_point = p_enabled;
PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT, p_enabled);
}
-bool Area3D::is_gravity_a_point() const {
+bool Area3D::is_gravity_a_point() const {
return gravity_is_point;
}
void Area3D::set_gravity_distance_scale(real_t p_scale) {
-
gravity_distance_scale = p_scale;
PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE, p_scale);
}
@@ -65,57 +62,51 @@ real_t Area3D::get_gravity_distance_scale() const {
}
void Area3D::set_gravity_vector(const Vector3 &p_vec) {
-
gravity_vec = p_vec;
PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR, p_vec);
}
-Vector3 Area3D::get_gravity_vector() const {
+Vector3 Area3D::get_gravity_vector() const {
return gravity_vec;
}
void Area3D::set_gravity(real_t p_gravity) {
-
gravity = p_gravity;
PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_GRAVITY, p_gravity);
}
-real_t Area3D::get_gravity() const {
+real_t Area3D::get_gravity() const {
return gravity;
}
-void Area3D::set_linear_damp(real_t p_linear_damp) {
+void Area3D::set_linear_damp(real_t p_linear_damp) {
linear_damp = p_linear_damp;
PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_LINEAR_DAMP, p_linear_damp);
}
-real_t Area3D::get_linear_damp() const {
+real_t Area3D::get_linear_damp() const {
return linear_damp;
}
void Area3D::set_angular_damp(real_t p_angular_damp) {
-
angular_damp = p_angular_damp;
PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP, p_angular_damp);
}
real_t Area3D::get_angular_damp() const {
-
return angular_damp;
}
void Area3D::set_priority(real_t p_priority) {
-
priority = p_priority;
PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_PRIORITY, p_priority);
}
-real_t Area3D::get_priority() const {
+real_t Area3D::get_priority() const {
return priority;
}
void Area3D::_body_enter_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -127,13 +118,11 @@ void Area3D::_body_enter_tree(ObjectID p_id) {
E->get().in_tree = true;
emit_signal(SceneStringNames::get_singleton()->body_entered, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
}
}
void Area3D::_body_exit_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -143,13 +132,11 @@ void Area3D::_body_exit_tree(ObjectID p_id) {
E->get().in_tree = false;
emit_signal(SceneStringNames::get_singleton()->body_exited, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
}
}
void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, int p_body_shape, int p_area_shape) {
-
bool body_in = p_status == PhysicsServer3D::AREA_BODY_ADDED;
ObjectID objid = p_instance;
@@ -166,7 +153,6 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
if (body_in) {
if (!E) {
-
E = body_map.insert(objid, BodyState());
E->get().rc = 0;
E->get().in_tree = node && node->is_inside_tree();
@@ -179,29 +165,30 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
}
}
E->get().rc++;
- if (node)
+ if (node) {
E->get().shapes.insert(ShapePair(p_body_shape, p_area_shape));
+ }
if (E->get().in_tree) {
emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_area_shape);
}
} else {
-
E->get().rc--;
- if (node)
+ if (node) {
E->get().shapes.erase(ShapePair(p_body_shape, p_area_shape));
+ }
bool eraseit = false;
if (E->get().rc == 0) {
-
if (node) {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_body_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_body_exit_tree));
- if (E->get().in_tree)
+ if (E->get().in_tree) {
emit_signal(SceneStringNames::get_singleton()->body_exited, obj);
+ }
}
eraseit = true;
@@ -210,15 +197,15 @@ void Area3D::_body_inout(int p_status, const RID &p_body, ObjectID p_instance, i
emit_signal(SceneStringNames::get_singleton()->body_shape_exited, objid, obj, p_body_shape, p_area_shape);
}
- if (eraseit)
+ if (eraseit) {
body_map.erase(E);
+ }
}
locked = false;
}
void Area3D::_clear_monitoring() {
-
ERR_FAIL_COND_MSG(locked, "This function can't be used during the in/out signal.");
{
@@ -227,19 +214,19 @@ void Area3D::_clear_monitoring() {
//disconnect all monitored stuff
for (Map<ObjectID, BodyState>::Element *E = bmcopy.front(); E; E = E->next()) {
-
Object *obj = ObjectDB::get_instance(E->key());
Node *node = Object::cast_to<Node>(obj);
- if (!node) //node may have been deleted in previous frame or at other legiminate point
+ if (!node) { //node may have been deleted in previous frame or at other legiminate point
continue;
+ }
//ERR_CONTINUE(!node);
- if (!E->get().in_tree)
+ if (!E->get().in_tree) {
continue;
+ }
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->body_shape_exited, E->key(), node, E->get().shapes[i].body_shape, E->get().shapes[i].area_shape);
}
@@ -251,25 +238,24 @@ void Area3D::_clear_monitoring() {
}
{
-
Map<ObjectID, AreaState> bmcopy = area_map;
area_map.clear();
//disconnect all monitored stuff
for (Map<ObjectID, AreaState>::Element *E = bmcopy.front(); E; E = E->next()) {
-
Object *obj = ObjectDB::get_instance(E->key());
Node *node = Object::cast_to<Node>(obj);
- if (!node) //node may have been deleted in previous frame or at other legiminate point
+ if (!node) { //node may have been deleted in previous frame or at other legiminate point
continue;
+ }
//ERR_CONTINUE(!node);
- if (!E->get().in_tree)
+ if (!E->get().in_tree) {
continue;
+ }
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->area_shape_exited, E->key(), node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
}
@@ -280,24 +266,23 @@ void Area3D::_clear_monitoring() {
}
}
}
-void Area3D::_notification(int p_what) {
+void Area3D::_notification(int p_what) {
if (p_what == NOTIFICATION_EXIT_TREE) {
_clear_monitoring();
}
}
void Area3D::set_monitoring(bool p_enable) {
-
ERR_FAIL_COND_MSG(locked, "Function blocked during in/out signal. Use set_deferred(\"monitoring\", true/false).");
- if (p_enable == monitoring)
+ if (p_enable == monitoring) {
return;
+ }
monitoring = p_enable;
if (monitoring) {
-
PhysicsServer3D::get_singleton()->area_set_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_body_inout);
PhysicsServer3D::get_singleton()->area_set_area_monitor_callback(get_rid(), this, SceneStringNames::get_singleton()->_area_inout);
} else {
@@ -308,7 +293,6 @@ void Area3D::set_monitoring(bool p_enable) {
}
void Area3D::_area_enter_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -320,13 +304,11 @@ void Area3D::_area_enter_tree(ObjectID p_id) {
E->get().in_tree = true;
emit_signal(SceneStringNames::get_singleton()->area_entered, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->area_shape_entered, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
}
}
void Area3D::_area_exit_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -336,13 +318,11 @@ void Area3D::_area_exit_tree(ObjectID p_id) {
E->get().in_tree = false;
emit_signal(SceneStringNames::get_singleton()->area_exited, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->area_shape_exited, p_id, node, E->get().shapes[i].area_shape, E->get().shapes[i].self_shape);
}
}
void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, int p_area_shape, int p_self_shape) {
-
bool area_in = p_status == PhysicsServer3D::AREA_BODY_ADDED;
ObjectID objid = p_instance;
@@ -359,7 +339,6 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
if (area_in) {
if (!E) {
-
E = area_map.insert(objid, AreaState());
E->get().rc = 0;
E->get().in_tree = node && node->is_inside_tree();
@@ -372,24 +351,24 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
}
}
E->get().rc++;
- if (node)
+ if (node) {
E->get().shapes.insert(AreaShapePair(p_area_shape, p_self_shape));
+ }
if (!node || E->get().in_tree) {
emit_signal(SceneStringNames::get_singleton()->area_shape_entered, objid, node, p_area_shape, p_self_shape);
}
} else {
-
E->get().rc--;
- if (node)
+ if (node) {
E->get().shapes.erase(AreaShapePair(p_area_shape, p_self_shape));
+ }
bool eraseit = false;
if (E->get().rc == 0) {
-
if (node) {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &Area3D::_area_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &Area3D::_area_exit_tree));
@@ -404,20 +383,19 @@ void Area3D::_area_inout(int p_status, const RID &p_area, ObjectID p_instance, i
emit_signal(SceneStringNames::get_singleton()->area_shape_exited, objid, obj, p_area_shape, p_self_shape);
}
- if (eraseit)
+ if (eraseit) {
area_map.erase(E);
+ }
}
locked = false;
}
bool Area3D::is_monitoring() const {
-
return monitoring;
}
-Array Area3D::get_overlapping_bodies() const {
-
+TypedArray<Node3D> Area3D::get_overlapping_bodies() const {
ERR_FAIL_COND_V(!monitoring, Array());
Array ret;
ret.resize(body_map.size());
@@ -435,11 +413,11 @@ Array Area3D::get_overlapping_bodies() const {
}
void Area3D::set_monitorable(bool p_enable) {
-
ERR_FAIL_COND_MSG(locked || (is_inside_tree() && PhysicsServer3D::get_singleton()->is_flushing_queries()), "Function blocked during in/out signal. Use set_deferred(\"monitorable\", true/false).");
- if (p_enable == monitorable)
+ if (p_enable == monitorable) {
return;
+ }
monitorable = p_enable;
@@ -447,12 +425,10 @@ void Area3D::set_monitorable(bool p_enable) {
}
bool Area3D::is_monitorable() const {
-
return monitorable;
}
-Array Area3D::get_overlapping_areas() const {
-
+TypedArray<Area3D> Area3D::get_overlapping_areas() const {
ERR_FAIL_COND_V(!monitoring, Array());
Array ret;
ret.resize(area_map.size());
@@ -470,89 +446,82 @@ Array Area3D::get_overlapping_areas() const {
}
bool Area3D::overlaps_area(Node *p_area) const {
-
ERR_FAIL_NULL_V(p_area, false);
const Map<ObjectID, AreaState>::Element *E = area_map.find(p_area->get_instance_id());
- if (!E)
+ if (!E) {
return false;
+ }
return E->get().in_tree;
}
bool Area3D::overlaps_body(Node *p_body) const {
-
ERR_FAIL_NULL_V(p_body, false);
const Map<ObjectID, BodyState>::Element *E = body_map.find(p_body->get_instance_id());
- if (!E)
+ if (!E) {
return false;
+ }
return E->get().in_tree;
}
-void Area3D::set_collision_mask(uint32_t p_mask) {
+void Area3D::set_collision_mask(uint32_t p_mask) {
collision_mask = p_mask;
PhysicsServer3D::get_singleton()->area_set_collision_mask(get_rid(), p_mask);
}
uint32_t Area3D::get_collision_mask() const {
-
return collision_mask;
}
-void Area3D::set_collision_layer(uint32_t p_layer) {
+void Area3D::set_collision_layer(uint32_t p_layer) {
collision_layer = p_layer;
PhysicsServer3D::get_singleton()->area_set_collision_layer(get_rid(), p_layer);
}
uint32_t Area3D::get_collision_layer() const {
-
return collision_layer;
}
void Area3D::set_collision_mask_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
bool Area3D::get_collision_mask_bit(int p_bit) const {
-
return get_collision_mask() & (1 << p_bit);
}
void Area3D::set_collision_layer_bit(int p_bit, bool p_value) {
-
uint32_t layer = get_collision_layer();
- if (p_value)
+ if (p_value) {
layer |= 1 << p_bit;
- else
+ } else {
layer &= ~(1 << p_bit);
+ }
set_collision_layer(layer);
}
bool Area3D::get_collision_layer_bit(int p_bit) const {
-
return get_collision_layer() & (1 << p_bit);
}
void Area3D::set_audio_bus_override(bool p_override) {
-
audio_bus_override = p_override;
}
bool Area3D::is_overriding_audio_bus() const {
-
return audio_bus_override;
}
void Area3D::set_audio_bus(const StringName &p_audio_bus) {
-
audio_bus = p_audio_bus;
}
-StringName Area3D::get_audio_bus() const {
+StringName Area3D::get_audio_bus() const {
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
if (AudioServer::get_singleton()->get_bus_name(i) == audio_bus) {
return audio_bus;
@@ -562,20 +531,18 @@ StringName Area3D::get_audio_bus() const {
}
void Area3D::set_use_reverb_bus(bool p_enable) {
-
use_reverb_bus = p_enable;
}
-bool Area3D::is_using_reverb_bus() const {
+bool Area3D::is_using_reverb_bus() const {
return use_reverb_bus;
}
void Area3D::set_reverb_bus(const StringName &p_audio_bus) {
-
reverb_bus = p_audio_bus;
}
-StringName Area3D::get_reverb_bus() const {
+StringName Area3D::get_reverb_bus() const {
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
if (AudioServer::get_singleton()->get_bus_name(i) == reverb_bus) {
return reverb_bus;
@@ -585,31 +552,28 @@ StringName Area3D::get_reverb_bus() const {
}
void Area3D::set_reverb_amount(float p_amount) {
-
reverb_amount = p_amount;
}
-float Area3D::get_reverb_amount() const {
+float Area3D::get_reverb_amount() const {
return reverb_amount;
}
void Area3D::set_reverb_uniformity(float p_uniformity) {
-
reverb_uniformity = p_uniformity;
}
-float Area3D::get_reverb_uniformity() const {
+float Area3D::get_reverb_uniformity() const {
return reverb_uniformity;
}
void Area3D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "audio_bus_name" || property.name == "reverb_bus_name") {
-
String options;
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
- if (i > 0)
+ if (i > 0) {
options += ",";
+ }
String name = AudioServer::get_singleton()->get_bus_name(i);
options += name;
}
@@ -729,7 +693,6 @@ void Area3D::_bind_methods() {
Area3D::Area3D() :
CollisionObject3D(PhysicsServer3D::get_singleton()->area_create(), true) {
-
space_override = SPACE_OVERRIDE_DISABLED;
set_gravity(9.8);
locked = false;
diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h
index ff6c0b6b08..98f337d3e4 100644
--- a/scene/3d/area_3d.h
+++ b/scene/3d/area_3d.h
@@ -35,7 +35,6 @@
#include "scene/3d/collision_object_3d.h"
class Area3D : public CollisionObject3D {
-
GDCLASS(Area3D, CollisionObject3D);
public:
@@ -68,14 +67,14 @@ private:
void _body_exit_tree(ObjectID p_id);
struct ShapePair {
-
int body_shape;
int area_shape;
bool operator<(const ShapePair &p_sp) const {
- if (body_shape == p_sp.body_shape)
+ if (body_shape == p_sp.body_shape) {
return area_shape < p_sp.area_shape;
- else
+ } else {
return body_shape < p_sp.body_shape;
+ }
}
ShapePair() {}
@@ -86,7 +85,6 @@ private:
};
struct BodyState {
-
int rc;
bool in_tree;
VSet<ShapePair> shapes;
@@ -100,14 +98,14 @@ private:
void _area_exit_tree(ObjectID p_id);
struct AreaShapePair {
-
int area_shape;
int self_shape;
bool operator<(const AreaShapePair &p_sp) const {
- if (area_shape == p_sp.area_shape)
+ if (area_shape == p_sp.area_shape) {
return self_shape < p_sp.self_shape;
- else
+ } else {
return area_shape < p_sp.area_shape;
+ }
}
AreaShapePair() {}
@@ -118,7 +116,6 @@ private:
};
struct AreaState {
-
int rc;
bool in_tree;
VSet<AreaShapePair> shapes;
@@ -184,8 +181,8 @@ public:
void set_collision_layer_bit(int p_bit, bool p_value);
bool get_collision_layer_bit(int p_bit) const;
- Array get_overlapping_bodies() const;
- Array get_overlapping_areas() const; //function for script
+ TypedArray<Node3D> get_overlapping_bodies() const;
+ TypedArray<Area3D> get_overlapping_areas() const; //function for script
bool overlaps_area(Node *p_area) const;
bool overlaps_body(Node *p_body) const;
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index 097368853e..6e4db8f382 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -138,7 +138,6 @@ void AudioStreamPlayer3D::_calc_output_vol(const Vector3 &source_dir, real_t tig
}
void AudioStreamPlayer3D::_mix_audio() {
-
if (!stream_playback.is_valid() || !active ||
(stream_paused && !stream_paused_fade_out)) {
return;
@@ -162,7 +161,6 @@ void AudioStreamPlayer3D::_mix_audio() {
// Mix if we're not paused or we're fading out
if ((output_count > 0 || out_of_range_mode == OUT_OF_RANGE_MIX)) {
-
float output_pitch_scale = 0.0;
if (output_count) {
//used for doppler, not realistic but good enough
@@ -179,7 +177,6 @@ void AudioStreamPlayer3D::_mix_audio() {
//write all outputs
for (int i = 0; i < output_count; i++) {
-
Output current = outputs[i];
//see if current output exists, to keep volume ramp
@@ -216,8 +213,9 @@ void AudioStreamPlayer3D::_mix_audio() {
AudioFrame vol_inc = (target_volume - vol_prev) / float(buffer_size);
AudioFrame vol = vol_prev;
- if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, k))
+ if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.bus_index, k)) {
continue; //may have been deleted, will be updated on process
+ }
AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, k);
current.filter.set_mode(AudioFilterSW::HIGHSHELF);
@@ -228,7 +226,6 @@ void AudioStreamPlayer3D::_mix_audio() {
current.filter.set_gain(current.filter_gain);
if (interpolate_filter) {
-
current.filter_process[k * 2 + 0] = prev_outputs[i].filter_process[k * 2 + 0];
current.filter_process[k * 2 + 1] = prev_outputs[i].filter_process[k * 2 + 1];
@@ -238,7 +235,6 @@ void AudioStreamPlayer3D::_mix_audio() {
current.filter_process[k * 2 + 0].update_coeffs(buffer_size);
current.filter_process[k * 2 + 1].update_coeffs(buffer_size);
for (int j = 0; j < buffer_size; j++) {
-
AudioFrame f = buffer[j] * vol;
current.filter_process[k * 2 + 0].process_one_interp(f.l);
current.filter_process[k * 2 + 1].process_one_interp(f.r);
@@ -253,7 +249,6 @@ void AudioStreamPlayer3D::_mix_audio() {
current.filter_process[k * 2 + 0].update_coeffs();
current.filter_process[k * 2 + 1].update_coeffs();
for (int j = 0; j < buffer_size; j++) {
-
AudioFrame f = buffer[j] * vol;
current.filter_process[k * 2 + 0].process_one(f.l);
current.filter_process[k * 2 + 1].process_one(f.r);
@@ -264,9 +259,9 @@ void AudioStreamPlayer3D::_mix_audio() {
}
if (current.reverb_bus_index >= 0) {
-
- if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.reverb_bus_index, k))
+ if (!AudioServer::get_singleton()->thread_has_channel_mix_buffer(current.reverb_bus_index, k)) {
continue; //may have been deleted, will be updated on process
+ }
AudioFrame *rtarget = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.reverb_bus_index, k);
@@ -275,15 +270,12 @@ void AudioStreamPlayer3D::_mix_audio() {
AudioFrame rvol = prev_outputs[i].reverb_vol[k];
for (int j = 0; j < buffer_size; j++) {
-
rtarget[j] += buffer[j] * rvol;
rvol += rvol_inc;
}
} else {
-
AudioFrame rvol = current.reverb_vol[k];
for (int j = 0; j < buffer_size; j++) {
-
rtarget[j] += buffer[j] * rvol;
}
}
@@ -306,7 +298,6 @@ void AudioStreamPlayer3D::_mix_audio() {
}
float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const {
-
float att = 0;
switch (attenuation_model) {
case ATTENUATION_INVERSE_DISTANCE: {
@@ -320,7 +311,8 @@ float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const {
case ATTENUATION_LOGARITHMIC: {
att = -20 * Math::log(p_distance / unit_size + CMP_EPSILON);
} break;
- case ATTENUATION_DISABLED: break;
+ case ATTENUATION_DISABLED:
+ break;
default: {
ERR_PRINT("Unknown attenuation type");
break;
@@ -339,9 +331,7 @@ void _update_sound() {
}
void AudioStreamPlayer3D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
velocity_tracker->reset(get_global_transform().origin);
AudioServer::get_singleton()->add_callback(_mix_audios, this);
if (autoplay && !Engine::get_singleton()->is_editor_hint()) {
@@ -350,7 +340,6 @@ void AudioStreamPlayer3D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
AudioServer::get_singleton()->remove_callback(_mix_audios, this);
}
@@ -366,18 +355,15 @@ void AudioStreamPlayer3D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
-
if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
velocity_tracker->update_position(get_global_transform().origin);
}
}
if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
-
//update anything related to position first, if possible of course
if (!output_ready) {
-
Vector3 linear_velocity;
//compute linear velocity for doppler
@@ -385,8 +371,8 @@ void AudioStreamPlayer3D::_notification(int p_what) {
linear_velocity = velocity_tracker->get_tracked_linear_velocity();
}
- Ref<World3D> world = get_world();
- ERR_FAIL_COND(world.is_null());
+ Ref<World3D> world_3d = get_world_3d();
+ ERR_FAIL_COND(world_3d.is_null());
int new_output_count = 0;
@@ -396,7 +382,7 @@ void AudioStreamPlayer3D::_notification(int p_what) {
//check if any area is diverting sound into a bus
- PhysicsDirectSpaceState3D *space_state = PhysicsServer3D::get_singleton()->space_get_direct_state(world->get_space());
+ PhysicsDirectSpaceState3D *space_state = PhysicsServer3D::get_singleton()->space_get_direct_state(world_3d->get_space());
PhysicsDirectSpaceState3D::ShapeResult sr[MAX_INTERSECT_AREAS];
@@ -404,29 +390,32 @@ void AudioStreamPlayer3D::_notification(int p_what) {
Area3D *area = nullptr;
for (int i = 0; i < areas; i++) {
- if (!sr[i].collider)
+ if (!sr[i].collider) {
continue;
+ }
Area3D *tarea = Object::cast_to<Area3D>(sr[i].collider);
- if (!tarea)
+ if (!tarea) {
continue;
+ }
- if (!tarea->is_overriding_audio_bus() && !tarea->is_using_reverb_bus())
+ if (!tarea->is_overriding_audio_bus() && !tarea->is_using_reverb_bus()) {
continue;
+ }
area = tarea;
break;
}
List<Camera3D *> cameras;
- world->get_camera_list(&cameras);
+ world_3d->get_camera_list(&cameras);
for (List<Camera3D *>::Element *E = cameras.front(); E; E = E->next()) {
-
Camera3D *camera = E->get();
Viewport *vp = camera->get_viewport();
- if (!vp->is_audio_listener())
+ if (!vp->is_audio_listener()) {
continue;
+ }
bool listener_is_camera = true;
Node3D *listener_node = camera;
@@ -450,7 +439,6 @@ void AudioStreamPlayer3D::_notification(int p_what) {
}
if (max_distance > 0) {
-
float total_max = max_distance;
if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) {
@@ -477,8 +465,9 @@ void AudioStreamPlayer3D::_notification(int p_what) {
Vector3 listenertopos = global_pos - listener_node->get_global_transform().origin;
float c = listenertopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative
float angle = Math::rad2deg(Math::acos(c));
- if (angle > emission_angle)
+ if (angle > emission_angle) {
db_att -= -emission_angle_filter_attenuation_db;
+ }
}
output.filter_gain = Math::db2linear(db_att);
@@ -496,7 +485,6 @@ void AudioStreamPlayer3D::_notification(int p_what) {
int vol_index_max = AudioServer::get_singleton()->get_speaker_mode() + 1;
if (area) {
-
if (area->is_overriding_audio_bus()) {
//override audio bus
StringName bus_name = area->get_audio_bus();
@@ -504,7 +492,6 @@ void AudioStreamPlayer3D::_notification(int p_what) {
}
if (area->is_using_reverb_bus()) {
-
filled_reverb = true;
StringName bus_name = area->get_reverb_bus();
output.reverb_bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);
@@ -513,7 +500,6 @@ void AudioStreamPlayer3D::_notification(int p_what) {
float area_send = area->get_reverb_amount();
if (uniformity > 0.0) {
-
float distance = listener_area_pos.length();
float attenuation = Math::db2linear(_get_attenuation_db(distance));
@@ -555,26 +541,21 @@ void AudioStreamPlayer3D::_notification(int p_what) {
}
for (int i = 0; i < vol_index_max; i++) {
-
- output.reverb_vol[i] = output.reverb_vol[i].linear_interpolate(center_frame, attenuation);
+ output.reverb_vol[i] = output.reverb_vol[i].lerp(center_frame, attenuation);
}
} else {
for (int i = 0; i < vol_index_max; i++) {
-
output.reverb_vol[i] = center_frame;
}
}
for (int i = 0; i < vol_index_max; i++) {
-
- output.reverb_vol[i] = output.vol[i].linear_interpolate(output.reverb_vol[i] * attenuation, uniformity);
+ output.reverb_vol[i] = output.vol[i].lerp(output.reverb_vol[i] * attenuation, uniformity);
output.reverb_vol[i] *= area_send;
}
} else {
-
for (int i = 0; i < vol_index_max; i++) {
-
output.reverb_vol[i] = output.vol[i] * area_send;
}
}
@@ -582,7 +563,6 @@ void AudioStreamPlayer3D::_notification(int p_what) {
}
if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
-
Vector3 listener_velocity;
if (listener_is_camera) {
@@ -607,17 +587,16 @@ void AudioStreamPlayer3D::_notification(int p_what) {
}
if (!filled_reverb) {
-
for (int i = 0; i < vol_index_max; i++) {
-
output.reverb_vol[i] = AudioFrame(0, 0);
}
}
outputs[new_output_count] = output;
new_output_count++;
- if (new_output_count == MAX_OUTPUTS)
+ if (new_output_count == MAX_OUTPUTS) {
break;
+ }
}
output_count = new_output_count;
@@ -644,7 +623,6 @@ void AudioStreamPlayer3D::_notification(int p_what) {
}
void AudioStreamPlayer3D::set_stream(Ref<AudioStream> p_stream) {
-
AudioServer::get_singleton()->lock();
mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size());
@@ -669,34 +647,30 @@ void AudioStreamPlayer3D::set_stream(Ref<AudioStream> p_stream) {
}
Ref<AudioStream> AudioStreamPlayer3D::get_stream() const {
-
return stream;
}
void AudioStreamPlayer3D::set_unit_db(float p_volume) {
-
unit_db = p_volume;
}
-float AudioStreamPlayer3D::get_unit_db() const {
+float AudioStreamPlayer3D::get_unit_db() const {
return unit_db;
}
void AudioStreamPlayer3D::set_unit_size(float p_volume) {
-
unit_size = p_volume;
}
-float AudioStreamPlayer3D::get_unit_size() const {
+float AudioStreamPlayer3D::get_unit_size() const {
return unit_size;
}
void AudioStreamPlayer3D::set_max_db(float p_boost) {
-
max_db = p_boost;
}
-float AudioStreamPlayer3D::get_max_db() const {
+float AudioStreamPlayer3D::get_max_db() const {
return max_db;
}
@@ -704,11 +678,16 @@ void AudioStreamPlayer3D::set_pitch_scale(float p_pitch_scale) {
ERR_FAIL_COND(p_pitch_scale <= 0.0);
pitch_scale = p_pitch_scale;
}
+
float AudioStreamPlayer3D::get_pitch_scale() const {
return pitch_scale;
}
void AudioStreamPlayer3D::play(float p_from_pos) {
+ if (!is_playing()) {
+ // Reset the prev_output_count if the stream is stopped
+ prev_output_count = 0;
+ }
if (stream_playback.is_valid()) {
active = true;
@@ -719,14 +698,12 @@ void AudioStreamPlayer3D::play(float p_from_pos) {
}
void AudioStreamPlayer3D::seek(float p_seconds) {
-
if (stream_playback.is_valid()) {
setseek = p_seconds;
}
}
void AudioStreamPlayer3D::stop() {
-
if (stream_playback.is_valid()) {
active = false;
set_physics_process_internal(false);
@@ -735,7 +712,6 @@ void AudioStreamPlayer3D::stop() {
}
bool AudioStreamPlayer3D::is_playing() const {
-
if (stream_playback.is_valid()) {
return active; // && stream_playback->is_playing();
}
@@ -744,7 +720,6 @@ bool AudioStreamPlayer3D::is_playing() const {
}
float AudioStreamPlayer3D::get_playback_position() {
-
if (stream_playback.is_valid()) {
return stream_playback->get_playback_position();
}
@@ -753,14 +728,13 @@ float AudioStreamPlayer3D::get_playback_position() {
}
void AudioStreamPlayer3D::set_bus(const StringName &p_bus) {
-
//if audio is active, must lock this
AudioServer::get_singleton()->lock();
bus = p_bus;
AudioServer::get_singleton()->unlock();
}
-StringName AudioStreamPlayer3D::get_bus() const {
+StringName AudioStreamPlayer3D::get_bus() const {
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
if (AudioServer::get_singleton()->get_bus_name(i) == bus) {
return bus;
@@ -770,34 +744,32 @@ StringName AudioStreamPlayer3D::get_bus() const {
}
void AudioStreamPlayer3D::set_autoplay(bool p_enable) {
-
autoplay = p_enable;
}
-bool AudioStreamPlayer3D::is_autoplay_enabled() {
+bool AudioStreamPlayer3D::is_autoplay_enabled() {
return autoplay;
}
void AudioStreamPlayer3D::_set_playing(bool p_enable) {
-
- if (p_enable)
+ if (p_enable) {
play();
- else
+ } else {
stop();
+ }
}
-bool AudioStreamPlayer3D::_is_active() const {
+bool AudioStreamPlayer3D::_is_active() const {
return active;
}
void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "bus") {
-
String options;
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
- if (i > 0)
+ if (i > 0) {
options += ",";
+ }
String name = AudioServer::get_singleton()->get_bus_name(i);
options += name;
}
@@ -807,28 +779,23 @@ void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const {
}
void AudioStreamPlayer3D::_bus_layout_changed() {
-
_change_notify();
}
void AudioStreamPlayer3D::set_max_distance(float p_metres) {
-
ERR_FAIL_COND(p_metres < 0.0);
max_distance = p_metres;
}
float AudioStreamPlayer3D::get_max_distance() const {
-
return max_distance;
}
void AudioStreamPlayer3D::set_area_mask(uint32_t p_mask) {
-
area_mask = p_mask;
}
uint32_t AudioStreamPlayer3D::get_area_mask() const {
-
return area_mask;
}
@@ -853,30 +820,26 @@ float AudioStreamPlayer3D::get_emission_angle() const {
}
void AudioStreamPlayer3D::set_emission_angle_filter_attenuation_db(float p_angle_attenuation_db) {
-
emission_angle_filter_attenuation_db = p_angle_attenuation_db;
}
float AudioStreamPlayer3D::get_emission_angle_filter_attenuation_db() const {
-
return emission_angle_filter_attenuation_db;
}
void AudioStreamPlayer3D::set_attenuation_filter_cutoff_hz(float p_hz) {
-
attenuation_filter_cutoff_hz = p_hz;
}
-float AudioStreamPlayer3D::get_attenuation_filter_cutoff_hz() const {
+float AudioStreamPlayer3D::get_attenuation_filter_cutoff_hz() const {
return attenuation_filter_cutoff_hz;
}
void AudioStreamPlayer3D::set_attenuation_filter_db(float p_db) {
-
attenuation_filter_db = p_db;
}
-float AudioStreamPlayer3D::get_attenuation_filter_db() const {
+float AudioStreamPlayer3D::get_attenuation_filter_db() const {
return attenuation_filter_db;
}
@@ -890,20 +853,18 @@ AudioStreamPlayer3D::AttenuationModel AudioStreamPlayer3D::get_attenuation_model
}
void AudioStreamPlayer3D::set_out_of_range_mode(OutOfRangeMode p_mode) {
-
ERR_FAIL_INDEX((int)p_mode, 2);
out_of_range_mode = p_mode;
}
AudioStreamPlayer3D::OutOfRangeMode AudioStreamPlayer3D::get_out_of_range_mode() const {
-
return out_of_range_mode;
}
void AudioStreamPlayer3D::set_doppler_tracking(DopplerTracking p_tracking) {
-
- if (doppler_tracking == p_tracking)
+ if (doppler_tracking == p_tracking) {
return;
+ }
doppler_tracking = p_tracking;
@@ -919,12 +880,10 @@ void AudioStreamPlayer3D::set_doppler_tracking(DopplerTracking p_tracking) {
}
AudioStreamPlayer3D::DopplerTracking AudioStreamPlayer3D::get_doppler_tracking() const {
-
return doppler_tracking;
}
void AudioStreamPlayer3D::set_stream_paused(bool p_pause) {
-
if (p_pause != stream_paused) {
stream_paused = p_pause;
stream_paused_fade_in = !stream_paused;
@@ -933,7 +892,6 @@ void AudioStreamPlayer3D::set_stream_paused(bool p_pause) {
}
bool AudioStreamPlayer3D::get_stream_paused() const {
-
return stream_paused;
}
@@ -942,7 +900,6 @@ Ref<AudioStreamPlayback> AudioStreamPlayer3D::get_stream_playback() {
}
void AudioStreamPlayer3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer3D::set_stream);
ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer3D::get_stream);
@@ -1048,7 +1005,6 @@ void AudioStreamPlayer3D::_bind_methods() {
}
AudioStreamPlayer3D::AudioStreamPlayer3D() {
-
unit_db = 0;
unit_size = 1;
attenuation_model = ATTENUATION_INVERSE_DISTANCE;
@@ -1078,5 +1034,6 @@ AudioStreamPlayer3D::AudioStreamPlayer3D() {
AudioServer::get_singleton()->connect("bus_layout_changed", callable_mp(this, &AudioStreamPlayer3D::_bus_layout_changed));
set_disable_scale(true);
}
+
AudioStreamPlayer3D::~AudioStreamPlayer3D() {
}
diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
index 13e08339e2..9f261c54b4 100644
--- a/scene/3d/audio_stream_player_3d.h
+++ b/scene/3d/audio_stream_player_3d.h
@@ -39,7 +39,6 @@
class Camera3D;
class AudioStreamPlayer3D : public Node3D {
-
GDCLASS(AudioStreamPlayer3D, Node3D);
public:
@@ -69,7 +68,6 @@ private:
};
struct Output {
-
AudioFilterSW filter;
AudioFilterSW::Processor filter_process[8];
AudioFrame vol[4];
diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp
index 6bde56104e..e2f1b3807d 100644
--- a/scene/3d/baked_lightmap.cpp
+++ b/scene/3d/baked_lightmap.cpp
@@ -28,94 +28,49 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if 0
#include "baked_lightmap.h"
+
#include "core/io/config_file.h"
#include "core/io/resource_saver.h"
+#include "core/math/camera_matrix.h"
+#include "core/math/delaunay_3d.h"
#include "core/os/dir_access.h"
+#include "core/os/file_access.h"
#include "core/os/os.h"
-#include "voxel_light_baker.h"
-
-void BakedLightmapData::set_bounds(const AABB &p_bounds) {
-
- bounds = p_bounds;
- RS::get_singleton()->lightmap_capture_set_bounds(baked_light, p_bounds);
-}
-
-AABB BakedLightmapData::get_bounds() const {
-
- return bounds;
-}
-
-void BakedLightmapData::set_octree(const Vector<uint8_t> &p_octree) {
-
- RS::get_singleton()->lightmap_capture_set_octree(baked_light, p_octree);
-}
-
-Vector<uint8_t> BakedLightmapData::get_octree() const {
-
- return RS::get_singleton()->lightmap_capture_get_octree(baked_light);
-}
-
-void BakedLightmapData::set_cell_space_transform(const Transform &p_xform) {
-
- cell_space_xform = p_xform;
- RS::get_singleton()->lightmap_capture_set_octree_cell_transform(baked_light, p_xform);
-}
-
-Transform BakedLightmapData::get_cell_space_transform() const {
- return cell_space_xform;
-}
-
-void BakedLightmapData::set_cell_subdiv(int p_cell_subdiv) {
- cell_subdiv = p_cell_subdiv;
- RS::get_singleton()->lightmap_capture_set_octree_cell_subdiv(baked_light, p_cell_subdiv);
-}
-
-int BakedLightmapData::get_cell_subdiv() const {
- return cell_subdiv;
-}
+#include "core/sort_array.h"
+#include "lightmap_probe.h"
-void BakedLightmapData::set_energy(float p_energy) {
-
- energy = p_energy;
- RS::get_singleton()->lightmap_capture_set_energy(baked_light, energy);
-}
-
-float BakedLightmapData::get_energy() const {
-
- return energy;
-}
-
-void BakedLightmapData::add_user(const NodePath &p_path, const Ref<Texture2D> &p_lightmap, int p_instance) {
-
- ERR_FAIL_COND_MSG(p_lightmap.is_null(), "It's not a reference to a valid Texture object.");
+void BakedLightmapData::add_user(const NodePath &p_path, const Rect2 &p_uv_scale, int p_slice_index, int32_t p_sub_instance) {
User user;
user.path = p_path;
- user.lightmap = p_lightmap;
- user.instance_index = p_instance;
+ user.uv_scale = p_uv_scale;
+ user.slice_index = p_slice_index;
+ user.sub_instance = p_sub_instance;
users.push_back(user);
}
int BakedLightmapData::get_user_count() const {
-
return users.size();
}
-NodePath BakedLightmapData::get_user_path(int p_user) const {
+NodePath BakedLightmapData::get_user_path(int p_user) const {
ERR_FAIL_INDEX_V(p_user, users.size(), NodePath());
return users[p_user].path;
}
-Ref<Texture2D> BakedLightmapData::get_user_lightmap(int p_user) const {
- ERR_FAIL_INDEX_V(p_user, users.size(), Ref<Texture2D>());
- return users[p_user].lightmap;
+int32_t BakedLightmapData::get_user_sub_instance(int p_user) const {
+ ERR_FAIL_INDEX_V(p_user, users.size(), -1);
+ return users[p_user].sub_instance;
}
-int BakedLightmapData::get_user_instance(int p_user) const {
+Rect2 BakedLightmapData::get_user_lightmap_uv_scale(int p_user) const {
+ ERR_FAIL_INDEX_V(p_user, users.size(), Rect2());
+ return users[p_user].uv_scale;
+}
+int BakedLightmapData::get_user_lightmap_slice_index(int p_user) const {
ERR_FAIL_INDEX_V(p_user, users.size(), -1);
- return users[p_user].instance_index;
+ return users[p_user].slice_index;
}
void BakedLightmapData::clear_users() {
@@ -123,539 +78,1122 @@ void BakedLightmapData::clear_users() {
}
void BakedLightmapData::_set_user_data(const Array &p_data) {
+ ERR_FAIL_COND((p_data.size() % 4) != 0);
- ERR_FAIL_COND((p_data.size() % 3) != 0);
-
- for (int i = 0; i < p_data.size(); i += 3) {
- add_user(p_data[i], p_data[i + 1], p_data[i + 2]);
+ for (int i = 0; i < p_data.size(); i += 4) {
+ add_user(p_data[i + 0], p_data[i + 1], p_data[i + 2], p_data[i + 3]);
}
}
Array BakedLightmapData::_get_user_data() const {
-
Array ret;
for (int i = 0; i < users.size(); i++) {
ret.push_back(users[i].path);
- ret.push_back(users[i].lightmap);
- ret.push_back(users[i].instance_index);
+ ret.push_back(users[i].uv_scale);
+ ret.push_back(users[i].slice_index);
+ ret.push_back(users[i].sub_instance);
}
return ret;
}
RID BakedLightmapData::get_rid() const {
- return baked_light;
+ return lightmap;
}
-void BakedLightmapData::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("_set_user_data", "data"), &BakedLightmapData::_set_user_data);
- ClassDB::bind_method(D_METHOD("_get_user_data"), &BakedLightmapData::_get_user_data);
- ClassDB::bind_method(D_METHOD("set_bounds", "bounds"), &BakedLightmapData::set_bounds);
- ClassDB::bind_method(D_METHOD("get_bounds"), &BakedLightmapData::get_bounds);
-
- ClassDB::bind_method(D_METHOD("set_cell_space_transform", "xform"), &BakedLightmapData::set_cell_space_transform);
- ClassDB::bind_method(D_METHOD("get_cell_space_transform"), &BakedLightmapData::get_cell_space_transform);
-
- ClassDB::bind_method(D_METHOD("set_cell_subdiv", "cell_subdiv"), &BakedLightmapData::set_cell_subdiv);
- ClassDB::bind_method(D_METHOD("get_cell_subdiv"), &BakedLightmapData::get_cell_subdiv);
-
- ClassDB::bind_method(D_METHOD("set_octree", "octree"), &BakedLightmapData::set_octree);
- ClassDB::bind_method(D_METHOD("get_octree"), &BakedLightmapData::get_octree);
-
- ClassDB::bind_method(D_METHOD("set_energy", "energy"), &BakedLightmapData::set_energy);
- ClassDB::bind_method(D_METHOD("get_energy"), &BakedLightmapData::get_energy);
+void BakedLightmapData::clear() {
+ users.clear();
+}
- ClassDB::bind_method(D_METHOD("add_user", "path", "lightmap", "instance"), &BakedLightmapData::add_user);
- ClassDB::bind_method(D_METHOD("get_user_count"), &BakedLightmapData::get_user_count);
- ClassDB::bind_method(D_METHOD("get_user_path", "user_idx"), &BakedLightmapData::get_user_path);
- ClassDB::bind_method(D_METHOD("get_user_lightmap", "user_idx"), &BakedLightmapData::get_user_lightmap);
- ClassDB::bind_method(D_METHOD("clear_users"), &BakedLightmapData::clear_users);
+void BakedLightmapData::set_light_texture(const Ref<TextureLayered> &p_light_texture) {
+ light_texture = p_light_texture;
+ RS::get_singleton()->lightmap_set_textures(lightmap, light_texture.is_valid() ? light_texture->get_rid() : RID(), uses_spherical_harmonics);
+}
- ADD_PROPERTY(PropertyInfo(Variant::AABB, "bounds", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_bounds", "get_bounds");
- ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "cell_space_transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_cell_space_transform", "get_cell_space_transform");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_subdiv", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_cell_subdiv", "get_cell_subdiv");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_energy", "get_energy");
- ADD_PROPERTY(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "octree", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_octree", "get_octree");
- ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "user_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_user_data", "_get_user_data");
+Ref<TextureLayered> BakedLightmapData::get_light_texture() const {
+ return light_texture;
}
-BakedLightmapData::BakedLightmapData() {
+void BakedLightmapData::set_uses_spherical_harmonics(bool p_enable) {
+ uses_spherical_harmonics = p_enable;
+ RS::get_singleton()->lightmap_set_textures(lightmap, light_texture.is_valid() ? light_texture->get_rid() : RID(), uses_spherical_harmonics);
+}
- baked_light = RS::get_singleton()->lightmap_capture_create();
- energy = 1;
- cell_subdiv = 1;
+bool BakedLightmapData::is_using_spherical_harmonics() const {
+ return uses_spherical_harmonics;
}
-BakedLightmapData::~BakedLightmapData() {
+void BakedLightmapData::set_capture_data(const AABB &p_bounds, bool p_interior, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {
+ if (p_points.size()) {
+ int pc = p_points.size();
+ ERR_FAIL_COND(pc * 9 != p_point_sh.size());
+ ERR_FAIL_COND((p_tetrahedra.size() % 4) != 0);
+ ERR_FAIL_COND((p_bsp_tree.size() % 6) != 0);
+ RS::get_singleton()->lightmap_set_probe_capture_data(lightmap, p_points, p_point_sh, p_tetrahedra, p_bsp_tree);
+ RS::get_singleton()->lightmap_set_probe_bounds(lightmap, p_bounds);
+ RS::get_singleton()->lightmap_set_probe_interior(lightmap, p_interior);
+ } else {
+ RS::get_singleton()->lightmap_set_probe_capture_data(lightmap, PackedVector3Array(), PackedColorArray(), PackedInt32Array(), PackedInt32Array());
+ RS::get_singleton()->lightmap_set_probe_bounds(lightmap, AABB());
+ RS::get_singleton()->lightmap_set_probe_interior(lightmap, false);
+ }
+ interior = p_interior;
+ bounds = p_bounds;
+}
- RS::get_singleton()->free(baked_light);
+PackedVector3Array BakedLightmapData::get_capture_points() const {
+ return RS::get_singleton()->lightmap_get_probe_capture_points(lightmap);
}
-///////////////////////////
+PackedColorArray BakedLightmapData::get_capture_sh() const {
+ return RS::get_singleton()->lightmap_get_probe_capture_sh(lightmap);
+}
-BakedLightmap::BakeBeginFunc BakedLightmap::bake_begin_function = nullptr;
-BakedLightmap::BakeStepFunc BakedLightmap::bake_step_function = nullptr;
-BakedLightmap::BakeEndFunc BakedLightmap::bake_end_function = nullptr;
+PackedInt32Array BakedLightmapData::get_capture_tetrahedra() const {
+ return RS::get_singleton()->lightmap_get_probe_capture_tetrahedra(lightmap);
+}
-void BakedLightmap::set_bake_cell_size(float p_cell_size) {
- bake_cell_size = p_cell_size;
+PackedInt32Array BakedLightmapData::get_capture_bsp_tree() const {
+ return RS::get_singleton()->lightmap_get_probe_capture_bsp_tree(lightmap);
}
-float BakedLightmap::get_bake_cell_size() const {
- return bake_cell_size;
+AABB BakedLightmapData::get_capture_bounds() const {
+ return bounds;
}
-void BakedLightmap::set_capture_cell_size(float p_cell_size) {
- capture_cell_size = p_cell_size;
+bool BakedLightmapData::is_interior() const {
+ return interior;
}
-float BakedLightmap::get_capture_cell_size() const {
- return capture_cell_size;
+void BakedLightmapData::_set_probe_data(const Dictionary &p_data) {
+ ERR_FAIL_COND(!p_data.has("bounds"));
+ ERR_FAIL_COND(!p_data.has("points"));
+ ERR_FAIL_COND(!p_data.has("tetrahedra"));
+ ERR_FAIL_COND(!p_data.has("bsp"));
+ ERR_FAIL_COND(!p_data.has("sh"));
+ ERR_FAIL_COND(!p_data.has("interior"));
+ set_capture_data(p_data["bounds"], p_data["interior"], p_data["points"], p_data["sh"], p_data["tetrahedra"], p_data["bsp"]);
}
-void BakedLightmap::set_extents(const Vector3 &p_extents) {
- extents = p_extents;
- update_gizmo();
- _change_notify("bake_extents");
+Dictionary BakedLightmapData::_get_probe_data() const {
+ Dictionary d;
+ d["bounds"] = get_capture_bounds();
+ d["points"] = get_capture_points();
+ d["tetrahedra"] = get_capture_tetrahedra();
+ d["bsp"] = get_capture_bsp_tree();
+ d["sh"] = get_capture_sh();
+ d["interior"] = is_interior();
+ return d;
}
-Vector3 BakedLightmap::get_extents() const {
- return extents;
+void BakedLightmapData::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_set_user_data", "data"), &BakedLightmapData::_set_user_data);
+ ClassDB::bind_method(D_METHOD("_get_user_data"), &BakedLightmapData::_get_user_data);
+
+ ClassDB::bind_method(D_METHOD("set_light_texture", "light_texture"), &BakedLightmapData::set_light_texture);
+ ClassDB::bind_method(D_METHOD("get_light_texture"), &BakedLightmapData::get_light_texture);
+
+ ClassDB::bind_method(D_METHOD("set_uses_spherical_harmonics", "uses_spherical_harmonics"), &BakedLightmapData::set_uses_spherical_harmonics);
+ ClassDB::bind_method(D_METHOD("is_using_spherical_harmonics"), &BakedLightmapData::is_using_spherical_harmonics);
+
+ ClassDB::bind_method(D_METHOD("add_user", "path", "lightmap", "offset"), &BakedLightmapData::add_user);
+ ClassDB::bind_method(D_METHOD("get_user_count"), &BakedLightmapData::get_user_count);
+ ClassDB::bind_method(D_METHOD("get_user_path", "user_idx"), &BakedLightmapData::get_user_path);
+ ClassDB::bind_method(D_METHOD("clear_users"), &BakedLightmapData::clear_users);
+
+ ClassDB::bind_method(D_METHOD("_set_probe_data", "data"), &BakedLightmapData::_set_probe_data);
+ ClassDB::bind_method(D_METHOD("_get_probe_data"), &BakedLightmapData::_get_probe_data);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_texture", PROPERTY_HINT_RESOURCE_TYPE, "TextureLayered"), "set_light_texture", "get_light_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "uses_spherical_harmonics", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_uses_spherical_harmonics", "is_using_spherical_harmonics");
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "user_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_user_data", "_get_user_data");
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "probe_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_probe_data", "_get_probe_data");
}
-void BakedLightmap::set_bake_default_texels_per_unit(const float &p_bake_texels_per_unit) {
- bake_default_texels_per_unit = p_bake_texels_per_unit;
- update_gizmo();
+BakedLightmapData::BakedLightmapData() {
+ lightmap = RS::get_singleton()->lightmap_create();
}
-float BakedLightmap::get_bake_default_texels_per_unit() const {
- return bake_default_texels_per_unit;
+BakedLightmapData::~BakedLightmapData() {
+ RS::get_singleton()->free(lightmap);
}
-void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, List<PlotMesh> &plot_meshes, List<PlotLight> &plot_lights) {
+///////////////////////////
- MeshInstance *mi = Object::cast_to<MeshInstance>(p_at_node);
- if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT) && mi->is_visible_in_tree()) {
+void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> &meshes, Vector<LightsFound> &lights, Vector<Vector3> &probes) {
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_at_node);
+ if (mi && mi->get_gi_mode() == GeometryInstance3D::GI_MODE_BAKED && mi->is_visible_in_tree()) {
Ref<Mesh> mesh = mi->get_mesh();
if (mesh.is_valid()) {
-
- bool all_have_uv2 = true;
+ bool all_have_uv2_and_normal = true;
+ bool surfaces_found = false;
for (int i = 0; i < mesh->get_surface_count(); i++) {
+ if (mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
+ continue;
+ }
if (!(mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_TEX_UV2)) {
- all_have_uv2 = false;
+ all_have_uv2_and_normal = false;
+ break;
+ }
+ if (!(mesh->surface_get_format(i) & Mesh::ARRAY_FORMAT_NORMAL)) {
+ all_have_uv2_and_normal = false;
break;
}
+ surfaces_found = true;
}
- if (all_have_uv2) {
+ if (surfaces_found && all_have_uv2_and_normal) {
//READY TO BAKE! size hint could be computed if not found, actually..
- AABB aabb = mesh->get_aabb();
-
- Transform xf = get_global_transform().affine_inverse() * mi->get_global_transform();
-
- if (AABB(-extents, extents * 2).intersects(xf.xform(aabb))) {
- PlotMesh pm;
- pm.local_xform = xf;
- pm.mesh = mesh;
- pm.path = get_path_to(mi);
- pm.instance_idx = -1;
- for (int i = 0; i < mesh->get_surface_count(); i++) {
- pm.instance_materials.push_back(mi->get_surface_material(i));
+ MeshesFound mf;
+ mf.xform = get_global_transform().affine_inverse() * mi->get_global_transform();
+ mf.node_path = get_path_to(mi);
+ mf.subindex = -1;
+ mf.mesh = mesh;
+
+ static const int lightmap_scale[GeometryInstance3D::LIGHTMAP_SCALE_MAX] = { 1, 2, 4, 8 };
+ mf.lightmap_scale = lightmap_scale[mi->get_lightmap_scale()];
+
+ Ref<Material> all_override = mi->get_material_override();
+ for (int i = 0; i < mesh->get_surface_count(); i++) {
+ if (all_override.is_valid()) {
+ mf.overrides.push_back(all_override);
+ } else {
+ mf.overrides.push_back(mi->get_surface_material(i));
}
- pm.override_material = mi->get_material_override();
- plot_meshes.push_back(pm);
}
+
+ meshes.push_back(mf);
}
}
}
- Spatial *s = Object::cast_to<Spatial>(p_at_node);
+ Node3D *s = Object::cast_to<Node3D>(p_at_node);
if (!mi && s) {
- Array meshes = p_at_node->call("get_bake_meshes");
- if (meshes.size() && (meshes.size() & 1) == 0) {
+ Array bmeshes = p_at_node->call("get_bake_bmeshes");
+ if (bmeshes.size() && (bmeshes.size() & 1) == 0) {
Transform xf = get_global_transform().affine_inverse() * s->get_global_transform();
- for (int i = 0; i < meshes.size(); i += 2) {
- PlotMesh pm;
- Transform mesh_xf = meshes[i + 1];
- pm.local_xform = xf * mesh_xf;
- pm.mesh = meshes[i];
- pm.instance_idx = i / 2;
- if (!pm.mesh.is_valid())
+ for (int i = 0; i < bmeshes.size(); i += 2) {
+ Ref<Mesh> mesh = bmeshes[i];
+ if (!mesh.is_valid()) {
continue;
- pm.path = get_path_to(s);
- plot_meshes.push_back(pm);
+ }
+
+ MeshesFound mf;
+
+ Transform mesh_xf = bmeshes[i + 1];
+ mf.xform = xf * mesh_xf;
+ mf.node_path = get_path_to(s);
+ mf.subindex = i / 2;
+ mf.lightmap_scale = 1;
+ mf.mesh = mesh;
+
+ meshes.push_back(mf);
}
}
}
- Light *light = Object::cast_to<Light>(p_at_node);
+ Light3D *light = Object::cast_to<Light3D>(p_at_node);
- if (light && light->get_bake_mode() != Light::BAKE_DISABLED) {
- PlotLight pl;
- Transform xf = get_global_transform().affine_inverse() * light->get_global_transform();
+ if (light && light->get_bake_mode() != Light3D::BAKE_DISABLED) {
+ LightsFound lf;
+ lf.xform = get_global_transform().affine_inverse() * light->get_global_transform();
+ lf.light = light;
+ lights.push_back(lf);
+ }
+
+ LightmapProbe *probe = Object::cast_to<LightmapProbe>(p_at_node);
- pl.local_xform = xf;
- pl.light = light;
- plot_lights.push_back(pl);
+ if (probe) {
+ Transform xf = get_global_transform().affine_inverse() * probe->get_global_transform();
+ probes.push_back(xf.origin);
}
- for (int i = 0; i < p_at_node->get_child_count(); i++) {
+ for (int i = 0; i < p_at_node->get_child_count(); i++) {
Node *child = p_at_node->get_child(i);
- if (!child->get_owner())
+ if (!child->get_owner()) {
continue; //maybe a helper
+ }
- _find_meshes_and_lights(child, plot_meshes, plot_lights);
+ _find_meshes_and_lights(child, meshes, lights, probes);
}
}
-void BakedLightmap::set_hdr(bool p_enable) {
- hdr = p_enable;
-}
+int BakedLightmap::_bsp_get_simplex_side(const Vector<Vector3> &p_points, const LocalVector<BSPSimplex> &p_simplices, const Plane &p_plane, uint32_t p_simplex) const {
+ int over = 0;
+ int under = 0;
+ int coplanar = 0;
+ const BSPSimplex &s = p_simplices[p_simplex];
+ for (int i = 0; i < 4; i++) {
+ const Vector3 v = p_points[s.vertices[i]];
+ if (p_plane.has_point(v)) { //coplanar
+ coplanar++;
+ } else if (p_plane.is_point_over(v)) {
+ over++;
+ } else {
+ under++;
+ }
+ }
-bool BakedLightmap::is_hdr() const {
- return hdr;
+ ERR_FAIL_COND_V(under == 0 && over == 0, -2); //should never happen, we discarded flat simplices before, but in any case drop it from the bsp tree and throw an error
+ if (under == 0) {
+ return 1; // all over
+ } else if (over == 0) {
+ return -1; // all under
+ } else {
+ return 0; // crossing
+ }
}
-bool BakedLightmap::_bake_time(void *ud, float p_secs, float p_progress) {
+//#define DEBUG_BSP
- uint64_t time = OS::get_singleton()->get_ticks_usec();
- BakeTimeData *btd = (BakeTimeData *)ud;
+int32_t BakedLightmap::_compute_bsp_tree(const Vector<Vector3> &p_points, const LocalVector<Plane> &p_planes, LocalVector<int32_t> &planes_tested, const LocalVector<BSPSimplex> &p_simplices, const LocalVector<int32_t> &p_simplex_indices, LocalVector<BSPNode> &bsp_nodes) {
+ //if we reach here, it means there is more than one simplex
+ int32_t node_index = (int32_t)bsp_nodes.size();
+ bsp_nodes.push_back(BSPNode());
- if (time - btd->last_step > 1000000) {
+ //test with all the simplex planes
+ Plane best_plane;
+ float best_plane_score = -1.0;
- int mins_left = p_secs / 60;
- int secs_left = Math::fmod(p_secs, 60.0f);
- int percent = p_progress * 100;
- bool abort = bake_step_function(btd->pass + percent, btd->text + " " + vformat(RTR("%d%%"), percent) + " " + vformat(RTR("(Time Left: %d:%02d s)"), mins_left, secs_left));
- btd->last_step = time;
- if (abort)
- return true;
- }
+ for (uint32_t i = 0; i < p_simplex_indices.size(); i++) {
+ const BSPSimplex &s = p_simplices[p_simplex_indices[i]];
+ for (int j = 0; j < 4; j++) {
+ uint32_t plane_index = s.planes[j];
+ if (planes_tested[plane_index] == node_index) {
+ continue; //tested this plane already
+ }
- return false;
-}
+ planes_tested[plane_index] = node_index;
+
+ static const int face_order[4][3] = {
+ { 0, 1, 2 },
+ { 0, 2, 3 },
+ { 0, 1, 3 },
+ { 1, 2, 3 }
+ };
+
+ // despite getting rid of plane duplicates, we should still use here the actual plane to avoid numerical error
+ // from thinking this same simplex is intersecting rather than on a side
+ Vector3 v0 = p_points[s.vertices[face_order[j][0]]];
+ Vector3 v1 = p_points[s.vertices[face_order[j][1]]];
+ Vector3 v2 = p_points[s.vertices[face_order[j][2]]];
+
+ Plane plane(v0, v1, v2);
+
+ //test with all the simplices
+ int over_count = 0;
+ int under_count = 0;
+
+ for (uint32_t k = 0; k < p_simplex_indices.size(); k++) {
+ int side = _bsp_get_simplex_side(p_points, p_simplices, plane, p_simplex_indices[k]);
+ if (side == -2) {
+ continue; //this simplex is invalid, skip for now
+ } else if (side < 0) {
+ under_count++;
+ } else if (side > 0) {
+ over_count++;
+ }
+ }
-BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_visual_debug) {
+ if (under_count == 0 && over_count == 0) {
+ continue; //most likely precision issue with a flat simplex, do not try this plane
+ }
- String save_path;
+ if (under_count > over_count) { //make sure under is always less than over, so we can compute the same ratio
+ SWAP(under_count, over_count);
+ }
- if (image_path.begins_with("res://")) {
- save_path = image_path;
- } else {
- if (get_filename() != "") {
- save_path = get_filename().get_base_dir();
- } else if (get_owner() && get_owner()->get_filename() != "") {
- save_path = get_owner()->get_filename().get_base_dir();
+ float score = 0; //by default, score is 0 (worst)
+ if (over_count > 0) {
+ //give score mainly based on ratio (under / over), this means that this plane is splitting simplices a lot, but its balanced
+ score = float(under_count) / over_count;
+ }
+
+ //adjusting priority over least splits, probably not a great idea
+ //score *= Math::sqrt(float(over_count + under_count) / p_simplex_indices.size()); //also multiply score
+
+ if (score > best_plane_score) {
+ best_plane = plane;
+ best_plane_score = score;
+ }
}
+ }
- if (save_path == "") {
- return BAKE_ERROR_NO_SAVE_PATH;
+ LocalVector<int32_t> indices_over;
+ LocalVector<int32_t> indices_under;
+
+ //split again, but add to list
+ for (uint32_t i = 0; i < p_simplex_indices.size(); i++) {
+ uint32_t index = p_simplex_indices[i];
+ int side = _bsp_get_simplex_side(p_points, p_simplices, best_plane, index);
+
+ if (side == -2) {
+ continue; //simplex sits on the plane, does not make sense to use it
}
- if (image_path != "") {
- save_path.plus_file(image_path);
+ if (side <= 0) {
+ indices_under.push_back(index);
}
- }
- {
- //check for valid save path
- DirAccessRef d = DirAccess::open(save_path);
- if (!d) {
- ERR_PRINT("Invalid Save Path '" + save_path + "'.");
- return BAKE_ERROR_NO_SAVE_PATH;
+
+ if (side >= 0) {
+ indices_over.push_back(index);
}
}
- Ref<BakedLightmapData> new_light_data;
- new_light_data.instance();
+#ifdef DEBUG_BSP
+ print_line("node " + itos(node_index) + " found plane: " + best_plane + " score:" + rtos(best_plane_score) + " - over " + itos(indices_over.size()) + " under " + itos(indices_under.size()) + " intersecting " + itos(intersecting));
+#endif
+
+ if (best_plane_score < 0.0 || indices_over.size() == p_simplex_indices.size() || indices_under.size() == p_simplex_indices.size()) {
+ ERR_FAIL_COND_V(p_simplex_indices.size() <= 1, 0); //should not happen, this is a bug
- Voxelizer baker;
+ // Failed to separate the tetrahedrons using planes
+ // this means Delaunay borked at some point.
+ // Luckily, because we are using tetrahedrons, we can resort to
+ // less precise but still working ways to generate the separating plane
+ // this will most likely look bad when interpolating, but at least it will not crash.
+ // and the arctifact will most likely also be very small, so too difficult to notice.
- int bake_subdiv;
- int capture_subdiv;
- AABB bake_bounds;
- {
- bake_bounds = AABB(-extents, extents * 2.0);
- int subdiv = nearest_power_of_2_templated(int(bake_bounds.get_longest_axis_size() / bake_cell_size));
- bake_bounds.size[bake_bounds.get_longest_axis_index()] = subdiv * bake_cell_size;
- bake_subdiv = nearest_shift(subdiv) + 1;
+ //find the longest axis
+
+ WARN_PRINT("Inconsistency found in triangulation while building BSP, probe interpolation quality may degrade a bit.");
+
+ LocalVector<Vector3> centers;
+ AABB bounds_all;
+ for (uint32_t i = 0; i < p_simplex_indices.size(); i++) {
+ AABB bounds;
+ for (uint32_t j = 0; j < 4; j++) {
+ Vector3 p = p_points[p_simplices[p_simplex_indices[i]].vertices[j]];
+ if (j == 0) {
+ bounds.position = p;
+ } else {
+ bounds.expand_to(p);
+ }
+ }
+ if (i == 0) {
+ centers.push_back(bounds.position + bounds.size * 0.5);
+ } else {
+ bounds_all.merge_with(bounds);
+ }
+ }
+ Vector3::Axis longest_axis = Vector3::Axis(bounds_all.get_longest_axis_index());
+
+ //find the simplex that will go under
+ uint32_t min_d_idx = 0xFFFFFFFF;
+ float min_d_dist = 1e20;
+
+ for (uint32_t i = 0; i < centers.size(); i++) {
+ if (centers[i][longest_axis] < min_d_dist) {
+ min_d_idx = i;
+ min_d_dist = centers[i][longest_axis];
+ }
+ }
+ //rebuild best_plane and over/under arrays
+ best_plane = Plane();
+ best_plane.normal[longest_axis] = 1.0;
+ best_plane.d = min_d_dist;
- capture_subdiv = bake_subdiv;
- float css = bake_cell_size;
- while (css < capture_cell_size && capture_subdiv > 2) {
- capture_subdiv--;
- css *= 2.0;
+ indices_under.clear();
+ indices_under.push_back(min_d_idx);
+
+ indices_over.clear();
+
+ for (uint32_t i = 0; i < p_simplex_indices.size(); i++) {
+ if (i == min_d_idx) {
+ continue;
+ }
+ indices_over.push_back(p_simplex_indices[i]);
}
}
- baker.begin_bake(bake_subdiv, bake_bounds);
+ BSPNode node;
+ node.plane = best_plane;
+
+ if (indices_under.size() == 0) {
+ //noting to do here
+ node.under = BSPNode::EMPTY_LEAF;
+ } else if (indices_under.size() == 1) {
+ node.under = -(indices_under[0] + 1);
+ } else {
+ node.under = _compute_bsp_tree(p_points, p_planes, planes_tested, p_simplices, indices_under, bsp_nodes);
+ }
+
+ if (indices_over.size() == 0) {
+ //noting to do here
+ node.over = BSPNode::EMPTY_LEAF;
+ } else if (indices_over.size() == 1) {
+ node.over = -(indices_over[0] + 1);
+ } else {
+ node.over = _compute_bsp_tree(p_points, p_planes, planes_tested, p_simplices, indices_over, bsp_nodes);
+ }
- List<PlotMesh> mesh_list;
- List<PlotLight> light_list;
+ bsp_nodes[node_index] = node;
- _find_meshes_and_lights(p_from_node ? p_from_node : get_parent(), mesh_list, light_list);
+ return node_index;
+}
- if (bake_begin_function) {
- bake_begin_function(mesh_list.size() + light_list.size() + 1 + mesh_list.size() * 100);
+bool BakedLightmap::_lightmap_bake_step_function(float p_completion, const String &p_text, void *ud, bool p_refresh) {
+ BakeStepUD *bsud = (BakeStepUD *)ud;
+ bool ret = false;
+ if (bsud->func) {
+ ret = bsud->func(bsud->from_percent + p_completion * (bsud->to_percent - bsud->from_percent), p_text, bsud->ud, p_refresh);
}
+ return ret;
+}
- int step = 0;
+void BakedLightmap::_plot_triangle_into_octree(GenProbesOctree *p_cell, float p_cell_size, const Vector3 *p_triangle) {
+ for (int i = 0; i < 8; i++) {
+ Vector3i pos = p_cell->offset;
+ uint32_t half_size = p_cell->size / 2;
+ if (i & 1) {
+ pos.x += half_size;
+ }
+ if (i & 2) {
+ pos.y += half_size;
+ }
+ if (i & 4) {
+ pos.z += half_size;
+ }
- int pmc = 0;
+ AABB subcell;
+ subcell.position = Vector3(pos) * p_cell_size;
+ subcell.size = Vector3(half_size, half_size, half_size) * p_cell_size;
- for (List<PlotMesh>::Element *E = mesh_list.front(); E; E = E->next()) {
+ if (!Geometry::triangle_box_overlap(subcell.position + subcell.size * 0.5, subcell.size * 0.5, p_triangle)) {
+ continue;
+ }
- if (bake_step_function) {
- bake_step_function(step++, RTR("Plotting Meshes: ") + " (" + itos(pmc + 1) + "/" + itos(mesh_list.size()) + ")");
+ if (p_cell->children[i] == nullptr) {
+ GenProbesOctree *child = memnew(GenProbesOctree);
+ child->offset = pos;
+ child->size = half_size;
+ p_cell->children[i] = child;
}
- pmc++;
- baker.plot_mesh(E->get().local_xform, E->get().mesh, E->get().instance_materials, E->get().override_material);
+ if (half_size > 1) {
+ //still levels missing
+ _plot_triangle_into_octree(p_cell->children[i], p_cell_size, p_triangle);
+ }
}
+}
+
+void BakedLightmap::_gen_new_positions_from_octree(const GenProbesOctree *p_cell, float p_cell_size, const Vector<Vector3> &probe_positions, LocalVector<Vector3> &new_probe_positions, HashMap<Vector3i, bool, Vector3iHash> &positions_used, const AABB &p_bounds) {
+ for (int i = 0; i < 8; i++) {
+ Vector3i pos = p_cell->offset;
+ if (i & 1) {
+ pos.x += p_cell->size;
+ }
+ if (i & 2) {
+ pos.y += p_cell->size;
+ }
+ if (i & 4) {
+ pos.z += p_cell->size;
+ }
+
+ if (p_cell->size == 1 && !positions_used.has(pos)) {
+ //new position to insert!
+ Vector3 real_pos = p_bounds.position + Vector3(pos) * p_cell_size;
+ //see if a user submitted probe is too close
+ int ppcount = probe_positions.size();
+ const Vector3 *pp = probe_positions.ptr();
+ bool exists = false;
+ for (int j = 0; j < ppcount; j++) {
+ if (pp[j].distance_to(real_pos) < CMP_EPSILON) {
+ exists = true;
+ break;
+ }
+ }
- pmc = 0;
- baker.begin_bake_light(Voxelizer::BakeQuality(bake_quality), Voxelizer::BakeMode(bake_mode), propagation, energy);
+ if (!exists) {
+ new_probe_positions.push_back(real_pos);
+ }
- for (List<PlotLight>::Element *E = light_list.front(); E; E = E->next()) {
+ positions_used[pos] = true;
+ }
- if (bake_step_function) {
- bake_step_function(step++, RTR("Plotting Lights:") + " (" + itos(pmc + 1) + "/" + itos(light_list.size()) + ")");
+ if (p_cell->children[i] != nullptr) {
+ _gen_new_positions_from_octree(p_cell->children[i], p_cell_size, probe_positions, new_probe_positions, positions_used, p_bounds);
}
+ }
+}
- pmc++;
- PlotLight pl = E->get();
- switch (pl.light->get_light_type()) {
- case RS::LIGHT_DIRECTIONAL: {
- baker.plot_light_directional(-pl.local_xform.basis.get_axis(2), pl.light->get_color(), pl.light->get_param(Light::PARAM_ENERGY), pl.light->get_param(Light::PARAM_INDIRECT_ENERGY), pl.light->get_bake_mode() == Light::BAKE_ALL);
- } break;
- case RS::LIGHT_OMNI: {
- baker.plot_light_omni(pl.local_xform.origin, pl.light->get_color(), pl.light->get_param(Light::PARAM_ENERGY), pl.light->get_param(Light::PARAM_INDIRECT_ENERGY), pl.light->get_param(Light::PARAM_RANGE), pl.light->get_param(Light::PARAM_ATTENUATION), pl.light->get_bake_mode() == Light::BAKE_ALL);
- } break;
- case RS::LIGHT_SPOT: {
- baker.plot_light_spot(pl.local_xform.origin, pl.local_xform.basis.get_axis(2), pl.light->get_color(), pl.light->get_param(Light::PARAM_ENERGY), pl.light->get_param(Light::PARAM_INDIRECT_ENERGY), pl.light->get_param(Light::PARAM_RANGE), pl.light->get_param(Light::PARAM_ATTENUATION), pl.light->get_param(Light::PARAM_SPOT_ANGLE), pl.light->get_param(Light::PARAM_SPOT_ATTENUATION), pl.light->get_bake_mode() == Light::BAKE_ALL);
+BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, String p_image_data_path, Lightmapper::BakeStepFunc p_bake_step, void *p_bake_userdata) {
+ if (p_image_data_path == "" && (get_light_data().is_null() || !get_light_data()->get_path().is_resource_file())) {
+ return BAKE_ERROR_NO_SAVE_PATH;
+ }
- } break;
+ if (p_image_data_path == "") {
+ if (get_light_data().is_null()) {
+ return BAKE_ERROR_NO_SAVE_PATH;
+ }
+
+ p_image_data_path = get_light_data()->get_path();
+ if (!p_image_data_path.is_resource_file()) {
+ return BAKE_ERROR_NO_SAVE_PATH;
}
}
- /*if (bake_step_function) {
- bake_step_function(pmc++, RTR("Finishing Plot"));
- }*/
- baker.end_bake();
+ Ref<Lightmapper> lightmapper = Lightmapper::create();
+ ERR_FAIL_COND_V(lightmapper.is_null(), BAKE_ERROR_NO_LIGHTMAPPER);
- Set<String> used_mesh_names;
+ BakeStepUD bsud;
+ bsud.func = p_bake_step;
+ bsud.ud = p_bake_userdata;
+ bsud.from_percent = 0.2;
+ bsud.to_percent = 0.8;
- pmc = 0;
- for (List<PlotMesh>::Element *E = mesh_list.front(); E; E = E->next()) {
+ if (p_bake_step) {
+ p_bake_step(0.0, TTR("Finding meshes, lights and probes"), p_bake_userdata, true);
+ }
+ /* STEP 1, FIND MESHES, LIGHTS AND PROBES */
+ Vector<Lightmapper::MeshData> mesh_data;
+ Vector<LightsFound> lights_found;
+ Vector<Vector3> probes_found;
+ AABB bounds;
+ {
+ Vector<MeshesFound> meshes_found;
+ _find_meshes_and_lights(p_from_node ? p_from_node : get_parent(), meshes_found, lights_found, probes_found);
- String mesh_name = E->get().mesh->get_name();
- if (mesh_name == "" || mesh_name.find(":") != -1 || mesh_name.find("/") != -1) {
- mesh_name = "LightMap";
+ if (meshes_found.size() == 0) {
+ return BAKE_ERROR_NO_MESHES;
}
+ // create mesh data for insert
- if (used_mesh_names.has(mesh_name)) {
- int idx = 2;
- String base = mesh_name;
- while (true) {
- mesh_name = base + itos(idx);
- if (!used_mesh_names.has(mesh_name))
- break;
- idx++;
+ //get the base material textures, help compute altlas size and bounds
+ for (int m_i = 0; m_i < meshes_found.size(); m_i++) {
+ if (p_bake_step) {
+ float p = (float)(m_i) / meshes_found.size();
+ p_bake_step(p * 0.1, vformat(TTR("Preparing geometry %d/%d"), m_i, meshes_found.size()), p_bake_userdata, false);
}
- }
- used_mesh_names.insert(mesh_name);
- pmc++;
- Voxelizer::LightMapData lm;
+ MeshesFound &mf = meshes_found.write[m_i];
- Error err;
- if (bake_step_function) {
- BakeTimeData btd;
- btd.text = RTR("Lighting Meshes: ") + mesh_name + " (" + itos(pmc) + "/" + itos(mesh_list.size()) + ")";
- btd.pass = step;
- btd.last_step = 0;
- err = baker.make_lightmap(E->get().local_xform, E->get().mesh, bake_default_texels_per_unit, lm, _bake_time, &btd);
- if (err != OK) {
- bake_end_function();
- if (err == ERR_SKIP)
- return BAKE_ERROR_USER_ABORTED;
- return BAKE_ERROR_CANT_CREATE_IMAGE;
+ Size2i lightmap_size = mf.mesh->get_lightmap_size_hint() * mf.lightmap_scale;
+ Vector<RID> overrides;
+ overrides.resize(mf.overrides.size());
+ for (int i = 0; i < mf.overrides.size(); i++) {
+ if (mf.overrides[i].is_valid()) {
+ overrides.write[i] = mf.overrides[i]->get_rid();
+ }
}
- step += 100;
- } else {
+ TypedArray<Image> images = RS::get_singleton()->bake_render_uv2(mf.mesh->get_rid(), overrides, lightmap_size);
- err = baker.make_lightmap(E->get().local_xform, E->get().mesh, bake_default_texels_per_unit, lm);
- }
+ ERR_FAIL_COND_V(images.empty(), BAKE_ERROR_CANT_CREATE_IMAGE);
- if (err == OK) {
+ Ref<Image> albedo = images[RS::BAKE_CHANNEL_ALBEDO_ALPHA];
+ Ref<Image> orm = images[RS::BAKE_CHANNEL_ORM];
- Ref<Image> image;
- image.instance();
+ //multiply albedo by metal
- if (hdr) {
+ Lightmapper::MeshData md;
- //just save a regular image
- Vector<uint8_t> data;
- int s = lm.light.size();
- data.resize(lm.light.size() * 2);
- {
+ {
+ Dictionary d;
+ d["path"] = mf.node_path;
+ if (mf.subindex >= 0) {
+ d["subindex"] = mf.subindex;
+ }
+ md.userdata = d;
+ }
- uint8_t* w = data.ptrw();
- const float* r = lm.light.ptr();
- uint16_t *hfw = (uint16_t *)w.ptr();
- for (int i = 0; i < s; i++) {
- hfw[i] = Math::make_half_float(r[i]);
- }
+ {
+ if (albedo->get_format() != Image::FORMAT_RGBA8) {
+ albedo->convert(Image::FORMAT_RGBA8);
+ }
+ if (orm->get_format() != Image::FORMAT_RGBA8) {
+ orm->convert(Image::FORMAT_RGBA8);
+ }
+ Vector<uint8_t> albedo_alpha = albedo->get_data();
+ Vector<uint8_t> orm_data = orm->get_data();
+
+ Vector<uint8_t> albedom;
+ uint32_t len = albedo_alpha.size();
+ albedom.resize(len);
+ const uint8_t *r_aa = albedo_alpha.ptr();
+ const uint8_t *r_orm = orm_data.ptr();
+ uint8_t *w_albedo = albedom.ptrw();
+
+ for (uint32_t i = 0; i < len; i += 4) {
+ w_albedo[i + 0] = uint8_t(CLAMP(float(r_aa[i + 0]) * (1.0 - float(r_orm[i + 2] / 255.0)), 0, 255));
+ w_albedo[i + 1] = uint8_t(CLAMP(float(r_aa[i + 1]) * (1.0 - float(r_orm[i + 2] / 255.0)), 0, 255));
+ w_albedo[i + 2] = uint8_t(CLAMP(float(r_aa[i + 2]) * (1.0 - float(r_orm[i + 2] / 255.0)), 0, 255));
+ w_albedo[i + 3] = 255;
}
- image->create(lm.width, lm.height, false, Image::FORMAT_RGBH, data);
+ md.albedo_on_uv2.instance();
+ md.albedo_on_uv2->create(lightmap_size.width, lightmap_size.height, false, Image::FORMAT_RGBA8, albedom);
+ }
- } else {
+ md.emission_on_uv2 = images[RS::BAKE_CHANNEL_EMISSION];
+ if (md.emission_on_uv2->get_format() != Image::FORMAT_RGBAH) {
+ md.emission_on_uv2->convert(Image::FORMAT_RGBAH);
+ }
- //just save a regular image
- Vector<uint8_t> data;
- int s = lm.light.size();
- data.resize(lm.light.size());
- {
-
- uint8_t* w = data.ptrw();
- const float* r = lm.light.ptr();
- for (int i = 0; i < s; i += 3) {
- Color c(r[i + 0], r[i + 1], r[i + 2]);
- c = c.to_srgb();
- w[i + 0] = CLAMP(c.r * 255, 0, 255);
- w[i + 1] = CLAMP(c.g * 255, 0, 255);
- w[i + 2] = CLAMP(c.b * 255, 0, 255);
- }
+ //get geometry
+
+ Basis normal_xform = mf.xform.basis.inverse().transposed();
+
+ for (int i = 0; i < mf.mesh->get_surface_count(); i++) {
+ if (mf.mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
+ continue;
}
+ Array a = mf.mesh->surface_get_arrays(i);
- image->create(lm.width, lm.height, false, Image::FORMAT_RGB8, data);
+ Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
+ const Vector3 *vr = vertices.ptr();
+ Vector<Vector2> uv = a[Mesh::ARRAY_TEX_UV2];
+ const Vector2 *uvr = nullptr;
+ Vector<Vector3> normals = a[Mesh::ARRAY_NORMAL];
+ const Vector3 *nr = nullptr;
+ Vector<int> index = a[Mesh::ARRAY_INDEX];
- //This texture is saved to SRGB for two reasons:
- // 1) first is so it looks better when doing the LINEAR->SRGB conversion (more accurate)
- // 2) So it can be used in the GLES2 backend, which does not support linkear workflow
- }
+ ERR_CONTINUE(uv.size() == 0);
+ ERR_CONTINUE(normals.size() == 0);
- String image_path = save_path.plus_file(mesh_name);
- Ref<Texture2D> texture;
+ uvr = uv.ptr();
+ nr = normals.ptr();
- if (ResourceLoader::import) {
+ int facecount;
+ const int *ir = nullptr;
- bool srgb = false;
- if (false && hdr) {
- //save hdr
+ if (index.size()) {
+ facecount = index.size() / 3;
+ ir = index.ptr();
} else {
- image_path += ".png";
- print_line("image path saving png: " + image_path);
- image->save_png(image_path);
- srgb = true;
+ facecount = vertices.size() / 3;
}
- if (!FileAccess::exists(image_path + ".import")) {
- Ref<ConfigFile> config;
- config.instance();
- config->set_value("remap", "importer", "texture");
- config->set_value("remap", "type", "StreamTexture");
- config->set_value("params", "compress/mode", 2);
- config->set_value("params", "detect_3d", false);
- config->set_value("params", "flags/repeat", false);
- config->set_value("params", "flags/filter", true);
- config->set_value("params", "flags/mipmaps", false);
- config->set_value("params", "flags/srgb", srgb);
-
- config->save(image_path + ".import");
+ for (int j = 0; j < facecount; j++) {
+ uint32_t vidx[3];
+
+ if (ir) {
+ for (int k = 0; k < 3; k++) {
+ vidx[k] = ir[j * 3 + k];
+ }
+ } else {
+ for (int k = 0; k < 3; k++) {
+ vidx[k] = j * 3 + k;
+ }
+ }
+
+ for (int k = 0; k < 3; k++) {
+ Vector3 v = mf.xform.xform(vr[vidx[k]]);
+ if (bounds == AABB()) {
+ bounds.position = v;
+ } else {
+ bounds.expand_to(v);
+ }
+ md.points.push_back(v);
+
+ md.uv2.push_back(uvr[vidx[k]]);
+ md.normal.push_back(normal_xform.xform(nr[vidx[k]]).normalized());
+ }
}
+ }
- ResourceLoader::import(image_path);
- texture = ResourceLoader::load(image_path); //if already loaded, it will be updated on refocus?
- } else {
+ mesh_data.push_back(md);
+ }
+ }
- image_path += ".text";
- Ref<ImageTexture> tex;
- bool set_path = true;
- if (ResourceCache::has(image_path)) {
- tex = Ref<Resource>((Resource *)ResourceCache::get(image_path));
- set_path = false;
- }
+ /* STEP 2, CREATE PROBES */
- if (!tex.is_valid()) {
- tex.instance();
- }
+ if (p_bake_step) {
+ p_bake_step(0.3, TTR("Creating probes"), p_bake_userdata, true);
+ }
- tex->create_from_image(image);
+ //bounds need to include the user probes
+ for (int i = 0; i < probes_found.size(); i++) {
+ bounds.expand_to(probes_found[i]);
+ }
- err = ResourceSaver::save(image_path, tex, ResourceSaver::FLAG_CHANGE_PATH);
- if (set_path) {
- tex->set_path(image_path);
- }
- texture = tex;
+ bounds.grow_by(bounds.size.length() * 0.001);
+
+ if (gen_probes == GENERATE_PROBES_DISABLED) {
+ // generate 8 probes on bound endpoints
+ for (int i = 0; i < 8; i++) {
+ probes_found.push_back(bounds.get_endpoint(i));
+ }
+ } else {
+ // detect probes from geometry
+ static const int subdiv_values[6] = { 0, 4, 8, 16, 32 };
+ int subdiv = subdiv_values[gen_probes];
+
+ float subdiv_cell_size;
+ Vector3i bound_limit;
+ {
+ int longest_axis = bounds.get_longest_axis_index();
+ subdiv_cell_size = bounds.size[longest_axis] / subdiv;
+ int axis_n1 = (longest_axis + 1) % 3;
+ int axis_n2 = (longest_axis + 2) % 3;
+
+ bound_limit[longest_axis] = subdiv;
+ bound_limit[axis_n1] = int(Math::ceil(bounds.size[axis_n1] / subdiv_cell_size));
+ bound_limit[axis_n2] = int(Math::ceil(bounds.size[axis_n2] / subdiv_cell_size));
+ //compensate bounds
+ bounds.size[axis_n1] = bound_limit[axis_n1] * subdiv_cell_size;
+ bounds.size[axis_n2] = bound_limit[axis_n2] * subdiv_cell_size;
+ }
+
+ GenProbesOctree octree;
+ octree.size = subdiv;
+
+ for (int i = 0; i < mesh_data.size(); i++) {
+ if (p_bake_step) {
+ float p = (float)(i) / mesh_data.size();
+ p_bake_step(0.3 + p * 0.1, vformat(TTR("Creating probes from mesh %d/%d"), i, mesh_data.size()), p_bake_userdata, false);
}
- if (err != OK) {
- if (bake_end_function) {
- bake_end_function();
- }
- ERR_FAIL_COND_V(err != OK, BAKE_ERROR_CANT_CREATE_IMAGE);
+
+ for (int j = 0; j < mesh_data[i].points.size(); j += 3) {
+ Vector3 points[3] = { mesh_data[i].points[j + 0] - bounds.position, mesh_data[i].points[j + 1] - bounds.position, mesh_data[i].points[j + 2] - bounds.position };
+ _plot_triangle_into_octree(&octree, subdiv_cell_size, points);
}
+ }
- new_light_data->add_user(E->get().path, texture, E->get().instance_idx);
+ LocalVector<Vector3> new_probe_positions;
+ HashMap<Vector3i, bool, Vector3iHash> positions_used;
+ for (uint32_t i = 0; i < 8; i++) { //insert bounding endpoints
+ Vector3i pos;
+ if (i & 1) {
+ pos.x += bound_limit.x;
+ }
+ if (i & 2) {
+ pos.y += bound_limit.y;
+ }
+ if (i & 4) {
+ pos.z += bound_limit.z;
+ }
+
+ positions_used[pos] = true;
+ Vector3 real_pos = bounds.position + Vector3(pos) * subdiv_cell_size; //use same formula for numerical stability
+ new_probe_positions.push_back(real_pos);
+ }
+ //skip first level, since probes are always added at bounds endpoints anyway (code above this)
+ for (int i = 0; i < 8; i++) {
+ if (octree.children[i]) {
+ _gen_new_positions_from_octree(octree.children[i], subdiv_cell_size, probes_found, new_probe_positions, positions_used, bounds);
+ }
+ }
+
+ for (uint32_t i = 0; i < new_probe_positions.size(); i++) {
+ probes_found.push_back(new_probe_positions[i]);
}
}
- AABB bounds = AABB(-extents, extents * 2);
- new_light_data->set_cell_subdiv(capture_subdiv);
- new_light_data->set_bounds(bounds);
- new_light_data->set_octree(baker.create_capture_octree(capture_subdiv));
+ // Add everything to lightmapper
+ if (p_bake_step) {
+ p_bake_step(0.4, TTR("Preparing Lightmapper"), p_bake_userdata, true);
+ }
+
{
+ for (int i = 0; i < mesh_data.size(); i++) {
+ lightmapper->add_mesh(mesh_data[i]);
+ }
+ for (int i = 0; i < lights_found.size(); i++) {
+ Light3D *light = lights_found[i].light;
+ Transform xf = lights_found[i].xform;
+
+ if (Object::cast_to<DirectionalLight3D>(light)) {
+ DirectionalLight3D *l = Object::cast_to<DirectionalLight3D>(light);
+ lightmapper->add_directional_light(light->get_bake_mode() == Light3D::BAKE_ALL, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_SIZE));
+ } else if (Object::cast_to<OmniLight3D>(light)) {
+ OmniLight3D *l = Object::cast_to<OmniLight3D>(light);
+ lightmapper->add_omni_light(light->get_bake_mode() == Light3D::BAKE_ALL, xf.origin, l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SIZE));
+ } else if (Object::cast_to<SpotLight3D>(light)) {
+ SpotLight3D *l = Object::cast_to<SpotLight3D>(light);
+ lightmapper->add_spot_light(light->get_bake_mode() == Light3D::BAKE_ALL, xf.origin, -xf.basis.get_axis(Vector3::AXIS_Z).normalized(), l->get_color(), l->get_param(Light3D::PARAM_ENERGY), l->get_param(Light3D::PARAM_RANGE), l->get_param(Light3D::PARAM_ATTENUATION), l->get_param(Light3D::PARAM_SPOT_ANGLE), l->get_param(Light3D::PARAM_SPOT_ATTENUATION), l->get_param(Light3D::PARAM_SIZE));
+ }
+ }
+ for (int i = 0; i < probes_found.size(); i++) {
+ lightmapper->add_probe(probes_found[i]);
+ }
+ }
+
+ Ref<Image> environment_image;
+ Basis environment_transform;
+
+ // Add everything to lightmapper
+ if (environment_mode != ENVIRONMENT_MODE_DISABLED) {
+ if (p_bake_step) {
+ p_bake_step(4.1, TTR("Preparing Environment"), p_bake_userdata, true);
+ }
+
+ environment_transform = get_global_transform().basis;
- float bake_bound_size = bake_bounds.get_longest_axis_size();
- Transform to_bounds;
- to_bounds.basis.scale(Vector3(bake_bound_size, bake_bound_size, bake_bound_size));
- to_bounds.origin = bounds.position;
+ switch (environment_mode) {
+ case ENVIRONMENT_MODE_DISABLED: {
+ //nothing
+ } break;
+ case ENVIRONMENT_MODE_SCENE: {
+ Ref<World3D> world = get_world_3d();
+ if (world.is_valid()) {
+ Ref<Environment> env = world->get_environment();
+ if (env.is_null()) {
+ env = world->get_fallback_environment();
+ }
- Transform to_grid;
- to_grid.basis.scale(Vector3(1 << (capture_subdiv - 1), 1 << (capture_subdiv - 1), 1 << (capture_subdiv - 1)));
+ if (env.is_valid()) {
+ environment_image = RS::get_singleton()->environment_bake_panorama(env->get_rid(), true, Size2i(128, 64));
+ }
+ }
+ } break;
+ case ENVIRONMENT_MODE_CUSTOM_SKY: {
+ if (environment_custom_sky.is_valid()) {
+ environment_image = RS::get_singleton()->sky_bake_panorama(environment_custom_sky->get_rid(), environment_custom_energy, true, Size2i(128, 64));
+ }
- Transform to_cell_space = to_grid * to_bounds.affine_inverse();
- new_light_data->set_cell_space_transform(to_cell_space);
+ } break;
+ case ENVIRONMENT_MODE_CUSTOM_COLOR: {
+ environment_image.instance();
+ environment_image->create(128, 64, false, Image::FORMAT_RGBAF);
+ Color c = environment_custom_color;
+ c.r *= environment_custom_energy;
+ c.g *= environment_custom_energy;
+ c.b *= environment_custom_energy;
+ for (int i = 0; i < 128; i++) {
+ for (int j = 0; j < 64; j++) {
+ environment_image->set_pixel(i, j, c);
+ }
+ }
+
+ } break;
+ }
}
- if (bake_end_function) {
- bake_end_function();
+ Lightmapper::BakeError bake_err = lightmapper->bake(Lightmapper::BakeQuality(bake_quality), use_denoiser, bounces, bias, max_texture_size, directional, Lightmapper::GenerateProbes(gen_probes), environment_image, environment_transform, _lightmap_bake_step_function, &bsud);
+
+ if (bake_err == Lightmapper::BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES) {
+ return BAKE_ERROR_MESHES_INVALID;
}
- //create the data for visual server
+ /* POSTBAKE: Save Textures */
- if (p_create_visual_debug) {
- MultiMeshInstance *mmi = memnew(MultiMeshInstance);
- mmi->set_multimesh(baker.create_debug_multimesh(Voxelizer::DEBUG_LIGHT));
- add_child(mmi);
-#ifdef TOOLS_ENABLED
- if (get_tree()->get_edited_scene_root() == this) {
- mmi->set_owner(this);
- } else {
- mmi->set_owner(get_owner());
+ Ref<TextureLayered> texture;
+ {
+ Vector<Ref<Image>> images;
+ for (int i = 0; i < lightmapper->get_bake_texture_count(); i++) {
+ images.push_back(lightmapper->get_bake_texture(i));
+ }
+ //we assume they are all the same, so lets create a large one for saving
+ Ref<Image> large_image;
+ large_image.instance();
+
+ large_image->create(images[0]->get_width(), images[0]->get_height() * images.size(), false, images[0]->get_format());
+
+ for (int i = 0; i < lightmapper->get_bake_texture_count(); i++) {
+ large_image->blit_rect(images[i], Rect2(0, 0, images[i]->get_width(), images[i]->get_height()), Point2(0, images[i]->get_height() * i));
+ }
+
+ String base_path = p_image_data_path.get_basename() + ".exr";
+
+ Ref<ConfigFile> config;
+
+ config.instance();
+ if (FileAccess::exists(base_path + ".import")) {
+ config->load(base_path + ".import");
+ }
+
+ config->set_value("remap", "importer", "2d_array_texture");
+ config->set_value("remap", "type", "StreamTexture2DArray");
+ if (!config->has_section_key("params", "compress/mode")) {
+ config->set_value("params", "compress/mode", 2); //user may want another compression, so leave it be
+ }
+ config->set_value("params", "compress/channel_pack", 1);
+ config->set_value("params", "mipmaps/generate", false);
+ config->set_value("params", "slices/horizontal", 1);
+ config->set_value("params", "slices/vertical", images.size());
+
+ config->save(base_path + ".import");
+
+ Error err = large_image->save_exr(base_path, false);
+ ERR_FAIL_COND_V(err, BAKE_ERROR_CANT_CREATE_IMAGE);
+ ResourceLoader::import(base_path);
+ Ref<Texture> t = ResourceLoader::load(base_path); //if already loaded, it will be updated on refocus?
+ ERR_FAIL_COND_V(t.is_null(), BAKE_ERROR_CANT_CREATE_IMAGE);
+ texture = t;
+ }
+
+ /* POSTBAKE: Save Light Data */
+
+ Ref<BakedLightmapData> data;
+ if (get_light_data().is_valid()) {
+ data = get_light_data();
+ set_light_data(Ref<BakedLightmapData>()); //clear
+ data->clear();
+ } else {
+ data.instance();
+ }
+
+ data->set_light_texture(texture);
+ data->set_uses_spherical_harmonics(directional);
+
+ for (int i = 0; i < lightmapper->get_bake_mesh_count(); i++) {
+ Dictionary d = lightmapper->get_bake_mesh_userdata(i);
+ NodePath np = d["path"];
+ int32_t subindex = -1;
+ if (d.has("subindex")) {
+ subindex = d["subindex"];
+ }
+
+ Rect2 uv_scale = lightmapper->get_bake_mesh_uv_scale(i);
+ int slice_index = lightmapper->get_bake_mesh_texture_slice(i);
+ data->add_user(np, uv_scale, slice_index, subindex);
+ }
+
+ {
+ // create tetrahedrons
+ Vector<Vector3> points;
+ Vector<Color> sh;
+ points.resize(lightmapper->get_bake_probe_count());
+ sh.resize(lightmapper->get_bake_probe_count() * 9);
+ for (int i = 0; i < lightmapper->get_bake_probe_count(); i++) {
+ points.write[i] = lightmapper->get_bake_probe_point(i);
+ Vector<Color> colors = lightmapper->get_bake_probe_sh(i);
+ ERR_CONTINUE(colors.size() != 9);
+ for (int j = 0; j < 9; j++) {
+ sh.write[i * 9 + j] = colors[j];
+ }
+ }
+
+ //Obtain solved simplices
+
+ if (p_bake_step) {
+ p_bake_step(0.8, TTR("Generating Probe Volumes"), p_bake_userdata, true);
}
-#else
- mmi->set_owner(get_owner());
+ Vector<Delaunay3D::OutputSimplex> solved_simplices = Delaunay3D::tetrahedralize(points);
+
+ LocalVector<BSPSimplex> bsp_simplices;
+ LocalVector<Plane> bsp_planes;
+ LocalVector<int32_t> bsp_simplex_indices;
+ PackedInt32Array tetrahedrons;
+
+ for (int i = 0; i < solved_simplices.size(); i++) {
+ //Prepare a special representation of the simplex, which uses a BSP Tree
+ BSPSimplex bsp_simplex;
+ for (int j = 0; j < 4; j++) {
+ bsp_simplex.vertices[j] = solved_simplices[i].points[j];
+ }
+ for (int j = 0; j < 4; j++) {
+ static const int face_order[4][3] = {
+ { 0, 1, 2 },
+ { 0, 2, 3 },
+ { 0, 1, 3 },
+ { 1, 2, 3 }
+ };
+ Vector3 a = points[solved_simplices[i].points[face_order[j][0]]];
+ Vector3 b = points[solved_simplices[i].points[face_order[j][1]]];
+ Vector3 c = points[solved_simplices[i].points[face_order[j][2]]];
+
+ //store planes in an array, but ensure they are reused, to speed up processing
+
+ Plane p(a, b, c);
+ int plane_index = -1;
+ for (uint32_t k = 0; k < bsp_planes.size(); k++) {
+ if (bsp_planes[k].is_equal_approx_any_side(p)) {
+ plane_index = k;
+ break;
+ }
+ }
+
+ if (plane_index == -1) {
+ plane_index = bsp_planes.size();
+ bsp_planes.push_back(p);
+ }
+
+ bsp_simplex.planes[j] = plane_index;
+
+ //also fill simplex array
+ tetrahedrons.push_back(solved_simplices[i].points[j]);
+ }
+
+ bsp_simplex_indices.push_back(bsp_simplices.size());
+ bsp_simplices.push_back(bsp_simplex);
+ }
+
+//#define DEBUG_SIMPLICES_AS_OBJ_FILE
+#ifdef DEBUG_SIMPLICES_AS_OBJ_FILE
+ {
+ FileAccessRef f = FileAccess::open("res://bsp.obj", FileAccess::WRITE);
+ for (uint32_t i = 0; i < bsp_simplices.size(); i++) {
+ f->store_line("o Simplex" + itos(i));
+ for (int j = 0; j < 4; j++) {
+ f->store_line(vformat("v %f %f %f", points[bsp_simplices[i].vertices[j]].x, points[bsp_simplices[i].vertices[j]].y, points[bsp_simplices[i].vertices[j]].z));
+ }
+ static const int face_order[4][3] = {
+ { 1, 2, 3 },
+ { 1, 3, 4 },
+ { 1, 2, 4 },
+ { 2, 3, 4 }
+ };
+
+ for (int j = 0; j < 4; j++) {
+ f->store_line(vformat("f %d %d %d", 4 * i + face_order[j][0], 4 * i + face_order[j][1], 4 * i + face_order[j][2]));
+ }
+ }
+ f->close();
+ }
+#endif
+
+ LocalVector<BSPNode> bsp_nodes;
+ LocalVector<int32_t> planes_tested;
+ planes_tested.resize(bsp_planes.size());
+ for (uint32_t i = 0; i < planes_tested.size(); i++) {
+ planes_tested[i] = 0x7FFFFFFF;
+ }
+
+ if (p_bake_step) {
+ p_bake_step(0.9, TTR("Generating Probe Acceleration Structures"), p_bake_userdata, true);
+ }
+
+ _compute_bsp_tree(points, bsp_planes, planes_tested, bsp_simplices, bsp_simplex_indices, bsp_nodes);
+
+ PackedInt32Array bsp_array;
+ bsp_array.resize(bsp_nodes.size() * 6); // six 32 bits values used for each BSP node
+ {
+ float *fptr = (float *)bsp_array.ptrw();
+ int32_t *iptr = (int32_t *)bsp_array.ptrw();
+ for (uint32_t i = 0; i < bsp_nodes.size(); i++) {
+ fptr[i * 6 + 0] = bsp_nodes[i].plane.normal.x;
+ fptr[i * 6 + 1] = bsp_nodes[i].plane.normal.y;
+ fptr[i * 6 + 2] = bsp_nodes[i].plane.normal.z;
+ fptr[i * 6 + 3] = bsp_nodes[i].plane.d;
+ iptr[i * 6 + 4] = bsp_nodes[i].over;
+ iptr[i * 6 + 5] = bsp_nodes[i].under;
+ }
+//#define DEBUG_BSP_TREE
+#ifdef DEBUG_BSP_TREE
+ FileAccessRef f = FileAccess::open("res://bsp.txt", FileAccess::WRITE);
+ for (uint32_t i = 0; i < bsp_nodes.size(); i++) {
+ f->store_line(itos(i) + " - plane: " + bsp_nodes[i].plane + " over: " + itos(bsp_nodes[i].over) + " under: " + itos(bsp_nodes[i].under));
+ }
#endif
+ }
+
+ /* Obtain the colors from the images, they will be re-created as cubemaps on the server, depending on the driver */
+
+ data->set_capture_data(bounds, interior, points, sh, tetrahedrons, bsp_array);
+ /* Compute a BSP tree of the simplices, so it's easy to find the exact one */
+ }
+
+ Error err = ResourceSaver::save(p_image_data_path, data);
+ data->set_path(p_image_data_path);
+
+ if (err != OK) {
+ return BAKE_ERROR_CANT_CREATE_IMAGE;
}
- set_light_data(new_light_data);
+ set_light_data(data);
return BAKE_ERROR_OK;
}
void BakedLightmap::_notification(int p_what) {
- if (p_what == NOTIFICATION_READY) {
-
+ if (p_what == NOTIFICATION_POST_ENTER_TREE) {
if (light_data.is_valid()) {
_assign_lightmaps();
}
- request_ready(); //will need ready again if re-enters tree
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
if (light_data.is_valid()) {
_clear_lightmaps();
}
@@ -663,24 +1201,20 @@ void BakedLightmap::_notification(int p_what) {
}
void BakedLightmap::_assign_lightmaps() {
-
ERR_FAIL_COND(!light_data.is_valid());
for (int i = 0; i < light_data->get_user_count(); i++) {
- Ref<Texture2D> lightmap = light_data->get_user_lightmap(i);
- ERR_CONTINUE(!lightmap.is_valid());
-
Node *node = get_node(light_data->get_user_path(i));
- int instance_idx = light_data->get_user_instance(i);
+ int instance_idx = light_data->get_user_sub_instance(i);
if (instance_idx >= 0) {
RID instance = node->call("get_bake_mesh_instance", instance_idx);
if (instance.is_valid()) {
- RS::get_singleton()->instance_set_use_lightmap(instance, get_instance(), lightmap->get_rid());
+ RS::get_singleton()->instance_geometry_set_lightmap(instance, get_instance(), light_data->get_user_lightmap_uv_scale(i), light_data->get_user_lightmap_slice_index(i));
}
} else {
- VisualInstance *vi = Object::cast_to<VisualInstance>(node);
+ VisualInstance3D *vi = Object::cast_to<VisualInstance3D>(node);
ERR_CONTINUE(!vi);
- RS::get_singleton()->instance_set_use_lightmap(vi->get_instance(), get_instance(), lightmap->get_rid());
+ RS::get_singleton()->instance_geometry_set_lightmap(vi->get_instance(), get_instance(), light_data->get_user_lightmap_uv_scale(i), light_data->get_user_lightmap_slice_index(i));
}
}
}
@@ -689,22 +1223,21 @@ void BakedLightmap::_clear_lightmaps() {
ERR_FAIL_COND(!light_data.is_valid());
for (int i = 0; i < light_data->get_user_count(); i++) {
Node *node = get_node(light_data->get_user_path(i));
- int instance_idx = light_data->get_user_instance(i);
+ int instance_idx = light_data->get_user_sub_instance(i);
if (instance_idx >= 0) {
RID instance = node->call("get_bake_mesh_instance", instance_idx);
if (instance.is_valid()) {
- RS::get_singleton()->instance_set_use_lightmap(instance, get_instance(), RID());
+ RS::get_singleton()->instance_geometry_set_lightmap(instance, RID(), Rect2(), 0);
}
} else {
- VisualInstance *vi = Object::cast_to<VisualInstance>(node);
+ VisualInstance3D *vi = Object::cast_to<VisualInstance3D>(node);
ERR_CONTINUE(!vi);
- RS::get_singleton()->instance_set_use_lightmap(vi->get_instance(), get_instance(), RID());
+ RS::get_singleton()->instance_geometry_set_lightmap(vi->get_instance(), RID(), Rect2(), 0);
}
}
}
void BakedLightmap::set_light_data(const Ref<BakedLightmapData> &p_data) {
-
if (light_data.is_valid()) {
if (is_inside_tree()) {
_clear_lightmaps();
@@ -719,146 +1252,231 @@ void BakedLightmap::set_light_data(const Ref<BakedLightmapData> &p_data) {
_assign_lightmaps();
}
}
+
+ update_gizmo();
}
Ref<BakedLightmapData> BakedLightmap::get_light_data() const {
-
return light_data;
}
-void BakedLightmap::_debug_bake() {
- bake(get_parent(), true);
+void BakedLightmap::set_bake_quality(BakeQuality p_quality) {
+ bake_quality = p_quality;
+}
+
+BakedLightmap::BakeQuality BakedLightmap::get_bake_quality() const {
+ return bake_quality;
+}
+
+AABB BakedLightmap::get_aabb() const {
+ return AABB();
+}
+
+Vector<Face3> BakedLightmap::get_faces(uint32_t p_usage_flags) const {
+ return Vector<Face3>();
}
-void BakedLightmap::set_propagation(float p_propagation) {
- propagation = p_propagation;
+void BakedLightmap::set_use_denoiser(bool p_enable) {
+ use_denoiser = p_enable;
}
-float BakedLightmap::get_propagation() const {
+bool BakedLightmap::is_using_denoiser() const {
+ return use_denoiser;
+}
- return propagation;
+void BakedLightmap::set_directional(bool p_enable) {
+ directional = p_enable;
}
-void BakedLightmap::set_energy(float p_energy) {
- energy = p_energy;
+bool BakedLightmap::is_directional() const {
+ return directional;
}
-float BakedLightmap::get_energy() const {
+void BakedLightmap::set_interior(bool p_enable) {
+ interior = p_enable;
+}
- return energy;
+bool BakedLightmap::is_interior() const {
+ return interior;
}
-void BakedLightmap::set_bake_quality(BakeQuality p_quality) {
- bake_quality = p_quality;
+void BakedLightmap::set_environment_mode(EnvironmentMode p_mode) {
+ environment_mode = p_mode;
+ _change_notify();
}
-BakedLightmap::BakeQuality BakedLightmap::get_bake_quality() const {
- return bake_quality;
+BakedLightmap::EnvironmentMode BakedLightmap::get_environment_mode() const {
+ return environment_mode;
}
-void BakedLightmap::set_bake_mode(BakeMode p_mode) {
- bake_mode = p_mode;
+void BakedLightmap::set_environment_custom_sky(const Ref<Sky> &p_sky) {
+ environment_custom_sky = p_sky;
}
-BakedLightmap::BakeMode BakedLightmap::get_bake_mode() const {
- return bake_mode;
+Ref<Sky> BakedLightmap::get_environment_custom_sky() const {
+ return environment_custom_sky;
}
-void BakedLightmap::set_image_path(const String &p_path) {
- image_path = p_path;
+void BakedLightmap::set_environment_custom_color(const Color &p_color) {
+ environment_custom_color = p_color;
}
-String BakedLightmap::get_image_path() const {
- return image_path;
+Color BakedLightmap::get_environment_custom_color() const {
+ return environment_custom_color;
}
-AABB BakedLightmap::get_aabb() const {
- return AABB(-extents, extents * 2);
+void BakedLightmap::set_environment_custom_energy(float p_energy) {
+ environment_custom_energy = p_energy;
}
-Vector<Face3> BakedLightmap::get_faces(uint32_t p_usage_flags) const {
- return Vector<Face3>();
+
+float BakedLightmap::get_environment_custom_energy() const {
+ return environment_custom_energy;
}
-void BakedLightmap::_bind_methods() {
+void BakedLightmap::set_bounces(int p_bounces) {
+ ERR_FAIL_COND(p_bounces < 0 || p_bounces > 16);
+ bounces = p_bounces;
+}
- ClassDB::bind_method(D_METHOD("set_light_data", "data"), &BakedLightmap::set_light_data);
- ClassDB::bind_method(D_METHOD("get_light_data"), &BakedLightmap::get_light_data);
+int BakedLightmap::get_bounces() const {
+ return bounces;
+}
+
+void BakedLightmap::set_bias(float p_bias) {
+ ERR_FAIL_COND(p_bias < 0.00001);
+ bias = p_bias;
+}
+
+float BakedLightmap::get_bias() const {
+ return bias;
+}
- ClassDB::bind_method(D_METHOD("set_bake_cell_size", "bake_cell_size"), &BakedLightmap::set_bake_cell_size);
- ClassDB::bind_method(D_METHOD("get_bake_cell_size"), &BakedLightmap::get_bake_cell_size);
+void BakedLightmap::set_max_texture_size(int p_size) {
+ ERR_FAIL_COND(p_size < 2048);
+ max_texture_size = p_size;
+}
+
+int BakedLightmap::get_max_texture_size() const {
+ return max_texture_size;
+}
+
+void BakedLightmap::set_generate_probes(GenerateProbes p_generate_probes) {
+ gen_probes = p_generate_probes;
+}
+
+BakedLightmap::GenerateProbes BakedLightmap::get_generate_probes() const {
+ return gen_probes;
+}
- ClassDB::bind_method(D_METHOD("set_capture_cell_size", "capture_cell_size"), &BakedLightmap::set_capture_cell_size);
- ClassDB::bind_method(D_METHOD("get_capture_cell_size"), &BakedLightmap::get_capture_cell_size);
+void BakedLightmap::_validate_property(PropertyInfo &property) const {
+ if (property.name == "environment_custom_sky" && environment_mode != ENVIRONMENT_MODE_CUSTOM_SKY) {
+ property.usage = 0;
+ }
+ if (property.name == "environment_custom_color" && environment_mode != ENVIRONMENT_MODE_CUSTOM_COLOR) {
+ property.usage = 0;
+ }
+ if (property.name == "environment_custom_energy" && environment_mode != ENVIRONMENT_MODE_CUSTOM_COLOR && environment_mode != ENVIRONMENT_MODE_CUSTOM_SKY) {
+ property.usage = 0;
+ }
+}
+
+void BakedLightmap::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_light_data", "data"), &BakedLightmap::set_light_data);
+ ClassDB::bind_method(D_METHOD("get_light_data"), &BakedLightmap::get_light_data);
ClassDB::bind_method(D_METHOD("set_bake_quality", "bake_quality"), &BakedLightmap::set_bake_quality);
ClassDB::bind_method(D_METHOD("get_bake_quality"), &BakedLightmap::get_bake_quality);
- ClassDB::bind_method(D_METHOD("set_bake_mode", "bake_mode"), &BakedLightmap::set_bake_mode);
- ClassDB::bind_method(D_METHOD("get_bake_mode"), &BakedLightmap::get_bake_mode);
+ ClassDB::bind_method(D_METHOD("set_bounces", "bounces"), &BakedLightmap::set_bounces);
+ ClassDB::bind_method(D_METHOD("get_bounces"), &BakedLightmap::get_bounces);
+
+ ClassDB::bind_method(D_METHOD("set_generate_probes", "subdivision"), &BakedLightmap::set_generate_probes);
+ ClassDB::bind_method(D_METHOD("get_generate_probes"), &BakedLightmap::get_generate_probes);
+
+ ClassDB::bind_method(D_METHOD("set_bias", "bias"), &BakedLightmap::set_bias);
+ ClassDB::bind_method(D_METHOD("get_bias"), &BakedLightmap::get_bias);
+
+ ClassDB::bind_method(D_METHOD("set_environment_mode", "mode"), &BakedLightmap::set_environment_mode);
+ ClassDB::bind_method(D_METHOD("get_environment_mode"), &BakedLightmap::get_environment_mode);
- ClassDB::bind_method(D_METHOD("set_extents", "extents"), &BakedLightmap::set_extents);
- ClassDB::bind_method(D_METHOD("get_extents"), &BakedLightmap::get_extents);
+ ClassDB::bind_method(D_METHOD("set_environment_custom_sky", "sky"), &BakedLightmap::set_environment_custom_sky);
+ ClassDB::bind_method(D_METHOD("get_environment_custom_sky"), &BakedLightmap::get_environment_custom_sky);
- ClassDB::bind_method(D_METHOD("set_bake_default_texels_per_unit", "texels"), &BakedLightmap::set_bake_default_texels_per_unit);
- ClassDB::bind_method(D_METHOD("get_bake_default_texels_per_unit"), &BakedLightmap::get_bake_default_texels_per_unit);
+ ClassDB::bind_method(D_METHOD("set_environment_custom_color", "color"), &BakedLightmap::set_environment_custom_color);
+ ClassDB::bind_method(D_METHOD("get_environment_custom_color"), &BakedLightmap::get_environment_custom_color);
- ClassDB::bind_method(D_METHOD("set_propagation", "propagation"), &BakedLightmap::set_propagation);
- ClassDB::bind_method(D_METHOD("get_propagation"), &BakedLightmap::get_propagation);
+ ClassDB::bind_method(D_METHOD("set_environment_custom_energy", "energy"), &BakedLightmap::set_environment_custom_energy);
+ ClassDB::bind_method(D_METHOD("get_environment_custom_energy"), &BakedLightmap::get_environment_custom_energy);
- ClassDB::bind_method(D_METHOD("set_energy", "energy"), &BakedLightmap::set_energy);
- ClassDB::bind_method(D_METHOD("get_energy"), &BakedLightmap::get_energy);
+ ClassDB::bind_method(D_METHOD("set_max_texture_size", "max_texture_size"), &BakedLightmap::set_max_texture_size);
+ ClassDB::bind_method(D_METHOD("get_max_texture_size"), &BakedLightmap::get_max_texture_size);
- ClassDB::bind_method(D_METHOD("set_hdr", "hdr"), &BakedLightmap::set_hdr);
- ClassDB::bind_method(D_METHOD("is_hdr"), &BakedLightmap::is_hdr);
+ ClassDB::bind_method(D_METHOD("set_use_denoiser", "use_denoiser"), &BakedLightmap::set_use_denoiser);
+ ClassDB::bind_method(D_METHOD("is_using_denoiser"), &BakedLightmap::is_using_denoiser);
- ClassDB::bind_method(D_METHOD("set_image_path", "image_path"), &BakedLightmap::set_image_path);
- ClassDB::bind_method(D_METHOD("get_image_path"), &BakedLightmap::get_image_path);
+ ClassDB::bind_method(D_METHOD("set_interior", "enable"), &BakedLightmap::set_interior);
+ ClassDB::bind_method(D_METHOD("is_interior"), &BakedLightmap::is_interior);
- ClassDB::bind_method(D_METHOD("bake", "from_node", "create_visual_debug"), &BakedLightmap::bake, DEFVAL(Variant()), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("debug_bake"), &BakedLightmap::_debug_bake);
- ClassDB::set_method_flags(get_class_static(), _scs_create("debug_bake"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
+ ClassDB::bind_method(D_METHOD("set_directional", "directional"), &BakedLightmap::set_directional);
+ ClassDB::bind_method(D_METHOD("is_directional"), &BakedLightmap::is_directional);
- ADD_GROUP("Bake", "bake_");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_bake_cell_size", "get_bake_cell_size");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), "set_bake_quality", "get_bake_quality");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "bake_mode", PROPERTY_HINT_ENUM, "ConeTrace,RayTrace"), "set_bake_mode", "get_bake_mode");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_propagation", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_propagation", "get_propagation");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_energy", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_energy", "get_energy");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_hdr"), "set_hdr", "is_hdr");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "bake_extents"), "set_extents", "get_extents");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bake_default_texels_per_unit"), "set_bake_default_texels_per_unit", "get_bake_default_texels_per_unit");
- ADD_GROUP("Capture", "capture_");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "capture_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_capture_cell_size", "get_capture_cell_size");
+ // ClassDB::bind_method(D_METHOD("bake", "from_node"), &BakedLightmap::bake, DEFVAL(Variant()));
+
+ ADD_GROUP("Tweaks", "");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "quality", PROPERTY_HINT_ENUM, "Low,Medium,High,Ultra"), "set_bake_quality", "get_bake_quality");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "bounces", PROPERTY_HINT_RANGE, "0,16,1"), "set_bounces", "get_bounces");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional"), "set_directional", "is_directional");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_denoiser"), "set_use_denoiser", "is_using_denoiser");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bias", PROPERTY_HINT_RANGE, "0.00001,0.1,0.00001,or_greater"), "set_bias", "get_bias");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "max_texture_size"), "set_max_texture_size", "get_max_texture_size");
+ ADD_GROUP("Environment", "environment_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "environment_mode", PROPERTY_HINT_ENUM, "Disabled,Scene,Custom Sky,Custom Color"), "set_environment_mode", "get_environment_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment_custom_sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_environment_custom_sky", "get_environment_custom_sky");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "environment_custom_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_environment_custom_color", "get_environment_custom_color");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "environment_custom_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_environment_custom_energy", "get_environment_custom_energy");
+ ADD_GROUP("Gen Probes", "generate_probes_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "generate_probes_subdiv", PROPERTY_HINT_ENUM, "Disabled,4,8,16,32"), "set_generate_probes", "get_generate_probes");
ADD_GROUP("Data", "");
- ADD_PROPERTY(PropertyInfo(Variant::STRING, "image_path", PROPERTY_HINT_DIR), "set_image_path", "get_image_path");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "light_data", PROPERTY_HINT_RESOURCE_TYPE, "BakedLightmapData"), "set_light_data", "get_light_data");
BIND_ENUM_CONSTANT(BAKE_QUALITY_LOW);
BIND_ENUM_CONSTANT(BAKE_QUALITY_MEDIUM);
BIND_ENUM_CONSTANT(BAKE_QUALITY_HIGH);
- BIND_ENUM_CONSTANT(BAKE_MODE_CONE_TRACE);
- BIND_ENUM_CONSTANT(BAKE_MODE_RAY_TRACE);
+ BIND_ENUM_CONSTANT(BAKE_QUALITY_ULTRA);
+
+ BIND_ENUM_CONSTANT(GENERATE_PROBES_DISABLED);
+ BIND_ENUM_CONSTANT(GENERATE_PROBES_SUBDIV_4);
+ BIND_ENUM_CONSTANT(GENERATE_PROBES_SUBDIV_8);
+ BIND_ENUM_CONSTANT(GENERATE_PROBES_SUBDIV_16);
+ BIND_ENUM_CONSTANT(GENERATE_PROBES_SUBDIV_32);
BIND_ENUM_CONSTANT(BAKE_ERROR_OK);
+ BIND_ENUM_CONSTANT(BAKE_ERROR_NO_LIGHTMAPPER);
BIND_ENUM_CONSTANT(BAKE_ERROR_NO_SAVE_PATH);
BIND_ENUM_CONSTANT(BAKE_ERROR_NO_MESHES);
+ BIND_ENUM_CONSTANT(BAKE_ERROR_MESHES_INVALID);
BIND_ENUM_CONSTANT(BAKE_ERROR_CANT_CREATE_IMAGE);
BIND_ENUM_CONSTANT(BAKE_ERROR_USER_ABORTED);
+
+ BIND_ENUM_CONSTANT(ENVIRONMENT_MODE_DISABLED);
+ BIND_ENUM_CONSTANT(ENVIRONMENT_MODE_SCENE);
+ BIND_ENUM_CONSTANT(ENVIRONMENT_MODE_CUSTOM_SKY);
+ BIND_ENUM_CONSTANT(ENVIRONMENT_MODE_CUSTOM_COLOR);
}
BakedLightmap::BakedLightmap() {
-
- extents = Vector3(10, 10, 10);
- bake_default_texels_per_unit = 20;
- bake_cell_size = 0.25;
- capture_cell_size = 0.5;
+ environment_mode = ENVIRONMENT_MODE_DISABLED;
+ environment_custom_color = Color(0.2, 0.7, 1.0);
+ environment_custom_energy = 1.0;
bake_quality = BAKE_QUALITY_MEDIUM;
- bake_mode = BAKE_MODE_CONE_TRACE;
- energy = 1;
- propagation = 1;
- hdr = false;
- image_path = ".";
- set_disable_scale(true);
+ interior = false;
+ directional = false;
+
+ gen_probes = GENERATE_PROBES_DISABLED;
+ use_denoiser = true;
+ bounces = 1;
+ bias = 0.0005;
+ max_texture_size = 16384;
}
-#endif
diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h
index bc9e3f55ea..08098c3d5d 100644
--- a/scene/3d/baked_lightmap.h
+++ b/scene/3d/baked_lightmap.h
@@ -28,189 +28,256 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if 0
-#ifndef BAKED_INDIRECT_LIGHT_H
-#define BAKED_INDIRECT_LIGHT_H
+#ifndef BAKED_LIGHTMAP_H
+#define BAKED_LIGHTMAP_H
-#include "multimesh_instance.h"
-#include "scene/3d/light.h"
-#include "scene/3d/visual_instance.h"
+#include "core/local_vector.h"
+#include "scene/3d/light_3d.h"
+#include "scene/3d/lightmapper.h"
+#include "scene/3d/mesh_instance_3d.h"
+#include "scene/3d/multimesh_instance_3d.h"
+#include "scene/3d/visual_instance_3d.h"
+#include "scene/resources/sky.h"
class BakedLightmapData : public Resource {
GDCLASS(BakedLightmapData, Resource);
+ RES_BASE_EXTENSION("lmbake")
- RID baked_light;
+ Ref<TextureLayered> light_texture;
+
+ bool uses_spherical_harmonics = false;
+ bool interior = false;
+
+ RID lightmap;
AABB bounds;
- float energy;
- int cell_subdiv;
- Transform cell_space_xform;
struct User {
-
NodePath path;
- Ref<Texture2D> lightmap;
- int instance_index;
+ int32_t sub_instance;
+ Rect2 uv_scale;
+ int slice_index;
};
Vector<User> users;
void _set_user_data(const Array &p_data);
Array _get_user_data() const;
+ void _set_probe_data(const Dictionary &p_data);
+ Dictionary _get_probe_data() const;
protected:
static void _bind_methods();
public:
- void set_bounds(const AABB &p_bounds);
- AABB get_bounds() const;
+ void add_user(const NodePath &p_path, const Rect2 &p_uv_scale, int p_slice_index, int32_t p_sub_instance = -1);
+ int get_user_count() const;
+ NodePath get_user_path(int p_user) const;
+ int32_t get_user_sub_instance(int p_user) const;
+ Rect2 get_user_lightmap_uv_scale(int p_user) const;
+ int get_user_lightmap_slice_index(int p_user) const;
+ void clear_users();
- void set_octree(const Vector<uint8_t> &p_octree);
- Vector<uint8_t> get_octree() const;
+ void set_light_texture(const Ref<TextureLayered> &p_light_texture);
+ Ref<TextureLayered> get_light_texture() const;
- void set_cell_space_transform(const Transform &p_xform);
- Transform get_cell_space_transform() const;
+ void set_uses_spherical_harmonics(bool p_enable);
+ bool is_using_spherical_harmonics() const;
- void set_cell_subdiv(int p_cell_subdiv);
- int get_cell_subdiv() const;
+ bool is_interior() const;
- void set_energy(float p_energy);
- float get_energy() const;
+ void set_capture_data(const AABB &p_bounds, bool p_interior, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree);
+ PackedVector3Array get_capture_points() const;
+ PackedColorArray get_capture_sh() const;
+ PackedInt32Array get_capture_tetrahedra() const;
+ PackedInt32Array get_capture_bsp_tree() const;
+ AABB get_capture_bounds() const;
- void add_user(const NodePath &p_path, const Ref<Texture2D> &p_lightmap, int p_instance = -1);
- int get_user_count() const;
- NodePath get_user_path(int p_user) const;
- Ref<Texture2D> get_user_lightmap(int p_user) const;
- int get_user_instance(int p_user) const;
- void clear_users();
+ void clear();
virtual RID get_rid() const;
BakedLightmapData();
~BakedLightmapData();
};
-class BakedLightmap : public VisualInstance {
- GDCLASS(BakedLightmap, VisualInstance);
+class BakedLightmap : public VisualInstance3D {
+ GDCLASS(BakedLightmap, VisualInstance3D);
public:
enum BakeQuality {
BAKE_QUALITY_LOW,
BAKE_QUALITY_MEDIUM,
- BAKE_QUALITY_HIGH
+ BAKE_QUALITY_HIGH,
+ BAKE_QUALITY_ULTRA,
};
- enum BakeMode {
- BAKE_MODE_CONE_TRACE,
- BAKE_MODE_RAY_TRACE,
+ enum GenerateProbes {
+ GENERATE_PROBES_DISABLED,
+ GENERATE_PROBES_SUBDIV_4,
+ GENERATE_PROBES_SUBDIV_8,
+ GENERATE_PROBES_SUBDIV_16,
+ GENERATE_PROBES_SUBDIV_32,
};
enum BakeError {
BAKE_ERROR_OK,
+ BAKE_ERROR_NO_LIGHTMAPPER,
BAKE_ERROR_NO_SAVE_PATH,
BAKE_ERROR_NO_MESHES,
+ BAKE_ERROR_MESHES_INVALID,
BAKE_ERROR_CANT_CREATE_IMAGE,
- BAKE_ERROR_USER_ABORTED
-
+ BAKE_ERROR_USER_ABORTED,
};
- typedef void (*BakeBeginFunc)(int);
- typedef bool (*BakeStepFunc)(int, const String &);
- typedef void (*BakeEndFunc)();
+ enum EnvironmentMode {
+ ENVIRONMENT_MODE_DISABLED,
+ ENVIRONMENT_MODE_SCENE,
+ ENVIRONMENT_MODE_CUSTOM_SKY,
+ ENVIRONMENT_MODE_CUSTOM_COLOR,
+ };
private:
- float bake_cell_size;
- float capture_cell_size;
- Vector3 extents;
- float bake_default_texels_per_unit;
- float propagation;
- float energy;
BakeQuality bake_quality;
- BakeMode bake_mode;
- bool hdr;
- String image_path;
+ bool use_denoiser;
+ int bounces;
+ float bias;
+ int max_texture_size;
+ bool interior;
+ EnvironmentMode environment_mode;
+ Ref<Sky> environment_custom_sky;
+ Color environment_custom_color;
+ float environment_custom_energy;
+ bool directional;
+ GenerateProbes gen_probes;
Ref<BakedLightmapData> light_data;
- struct PlotMesh {
- Ref<Material> override_material;
- Vector<Ref<Material> > instance_materials;
- Ref<Mesh> mesh;
- Transform local_xform;
- NodePath path;
- int instance_idx;
+ struct LightsFound {
+ Transform xform;
+ Light3D *light;
};
- struct PlotLight {
- Light *light;
- Transform local_xform;
+ struct MeshesFound {
+ Transform xform;
+ NodePath node_path;
+ int32_t subindex;
+ Ref<Mesh> mesh;
+ int32_t lightmap_scale;
+ Vector<Ref<Material>> overrides;
};
- void _find_meshes_and_lights(Node *p_at_node, List<PlotMesh> &plot_meshes, List<PlotLight> &plot_lights);
-
- void _debug_bake();
+ void _find_meshes_and_lights(Node *p_at_node, Vector<MeshesFound> &meshes, Vector<LightsFound> &lights, Vector<Vector3> &probes);
void _assign_lightmaps();
void _clear_lightmaps();
- static bool _bake_time(void *ud, float p_secs, float p_progress);
-
struct BakeTimeData {
String text;
int pass;
uint64_t last_step;
};
+ struct BSPSimplex {
+ int vertices[4];
+ int planes[4];
+ };
+
+ struct BSPNode {
+ static const int32_t EMPTY_LEAF = INT32_MIN;
+ Plane plane;
+ int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
+ };
+
+ int _bsp_get_simplex_side(const Vector<Vector3> &p_points, const LocalVector<BSPSimplex> &p_simplices, const Plane &p_plane, uint32_t p_simplex) const;
+ int32_t _compute_bsp_tree(const Vector<Vector3> &p_points, const LocalVector<Plane> &p_planes, LocalVector<int32_t> &planes_tested, const LocalVector<BSPSimplex> &p_simplices, const LocalVector<int32_t> &p_simplex_indices, LocalVector<BSPNode> &bsp_nodes);
+
+ struct BakeStepUD {
+ Lightmapper::BakeStepFunc func;
+ void *ud;
+ float from_percent;
+ float to_percent;
+ };
+
+ static bool _lightmap_bake_step_function(float p_completion, const String &p_text, void *ud, bool p_refresh);
+
+ struct GenProbesOctree {
+ Vector3i offset;
+ uint32_t size;
+ GenProbesOctree *children[8] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr };
+ ~GenProbesOctree() {
+ for (int i = 0; i < 8; i++) {
+ if (children[i] != nullptr) {
+ memdelete(children[i]);
+ }
+ }
+ }
+ };
+
+ struct Vector3iHash {
+ _FORCE_INLINE_ static uint32_t hash(const Vector3i &p_vtx) {
+ uint32_t h = hash_djb2_one_32(p_vtx.x);
+ h = hash_djb2_one_32(p_vtx.y, h);
+ return hash_djb2_one_32(p_vtx.z, h);
+ }
+ };
+
+ void _plot_triangle_into_octree(GenProbesOctree *p_cell, float p_cell_size, const Vector3 *p_triangle);
+ void _gen_new_positions_from_octree(const GenProbesOctree *p_cell, float p_cell_size, const Vector<Vector3> &probe_positions, LocalVector<Vector3> &new_probe_positions, HashMap<Vector3i, bool, Vector3iHash> &positions_used, const AABB &p_bounds);
+
protected:
+ void _validate_property(PropertyInfo &property) const;
static void _bind_methods();
void _notification(int p_what);
public:
- static BakeBeginFunc bake_begin_function;
- static BakeStepFunc bake_step_function;
- static BakeEndFunc bake_end_function;
-
void set_light_data(const Ref<BakedLightmapData> &p_data);
Ref<BakedLightmapData> get_light_data() const;
- void set_bake_cell_size(float p_cell_size);
- float get_bake_cell_size() const;
+ void set_bake_quality(BakeQuality p_quality);
+ BakeQuality get_bake_quality() const;
+
+ void set_use_denoiser(bool p_enable);
+ bool is_using_denoiser() const;
- void set_capture_cell_size(float p_cell_size);
- float get_capture_cell_size() const;
+ void set_directional(bool p_enable);
+ bool is_directional() const;
- void set_extents(const Vector3 &p_extents);
- Vector3 get_extents() const;
+ void set_interior(bool p_interior);
+ bool is_interior() const;
- void set_bake_default_texels_per_unit(const float &p_bake_texels_per_unit);
- float get_bake_default_texels_per_unit() const;
+ void set_environment_mode(EnvironmentMode p_mode);
+ EnvironmentMode get_environment_mode() const;
- void set_propagation(float p_propagation);
- float get_propagation() const;
+ void set_environment_custom_sky(const Ref<Sky> &p_sky);
+ Ref<Sky> get_environment_custom_sky() const;
- void set_energy(float p_energy);
- float get_energy() const;
+ void set_environment_custom_color(const Color &p_color);
+ Color get_environment_custom_color() const;
- void set_bake_quality(BakeQuality p_quality);
- BakeQuality get_bake_quality() const;
+ void set_environment_custom_energy(float p_energy);
+ float get_environment_custom_energy() const;
+
+ void set_bounces(int p_bounces);
+ int get_bounces() const;
- void set_bake_mode(BakeMode p_mode);
- BakeMode get_bake_mode() const;
+ void set_bias(float p_bias);
+ float get_bias() const;
- void set_hdr(bool p_enable);
- bool is_hdr() const;
+ void set_max_texture_size(int p_size);
+ int get_max_texture_size() const;
- void set_image_path(const String &p_path);
- String get_image_path() const;
+ void set_generate_probes(GenerateProbes p_generate_probes);
+ GenerateProbes get_generate_probes() const;
AABB get_aabb() const;
Vector<Face3> get_faces(uint32_t p_usage_flags) const;
- BakeError bake(Node *p_from_node, bool p_create_visual_debug = false);
+ BakeError bake(Node *p_from_node, String p_image_data_path = "", Lightmapper::BakeStepFunc p_bake_step = nullptr, void *p_bake_userdata = nullptr);
BakedLightmap();
};
VARIANT_ENUM_CAST(BakedLightmap::BakeQuality);
-VARIANT_ENUM_CAST(BakedLightmap::BakeMode);
+VARIANT_ENUM_CAST(BakedLightmap::GenerateProbes);
VARIANT_ENUM_CAST(BakedLightmap::BakeError);
+VARIANT_ENUM_CAST(BakedLightmap::EnvironmentMode);
-#endif
-#endif // BAKED_INDIRECT_LIGHT_H
+#endif // BAKED_LIGHTMAP_H
diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp
index 825cb39e2d..68303bbfe5 100644
--- a/scene/3d/bone_attachment_3d.cpp
+++ b/scene/3d/bone_attachment_3d.cpp
@@ -31,23 +31,21 @@
#include "bone_attachment_3d.h"
void BoneAttachment3D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "bone_name") {
Skeleton3D *parent = Object::cast_to<Skeleton3D>(get_parent());
if (parent) {
-
String names;
for (int i = 0; i < parent->get_bone_count(); i++) {
- if (i > 0)
+ if (i > 0) {
names += ",";
+ }
names += parent->get_bone_name(i);
}
property.hint = PROPERTY_HINT_ENUM;
property.hint_string = names;
} else {
-
property.hint = PROPERTY_HINT_NONE;
property.hint_string = "";
}
@@ -55,10 +53,8 @@ void BoneAttachment3D::_validate_property(PropertyInfo &property) const {
}
void BoneAttachment3D::_check_bind() {
-
Skeleton3D *sk = Object::cast_to<Skeleton3D>(get_parent());
if (sk) {
-
int idx = sk->find_bone(bone_name);
if (idx != -1) {
sk->bind_child_node_to_bone(idx, this);
@@ -69,12 +65,9 @@ void BoneAttachment3D::_check_bind() {
}
void BoneAttachment3D::_check_unbind() {
-
if (bound) {
-
Skeleton3D *sk = Object::cast_to<Skeleton3D>(get_parent());
if (sk) {
-
int idx = sk->find_bone(bone_name);
if (idx != -1) {
sk->unbind_child_node_from_bone(idx, this);
@@ -85,31 +78,27 @@ void BoneAttachment3D::_check_unbind() {
}
void BoneAttachment3D::set_bone_name(const String &p_name) {
-
- if (is_inside_tree())
+ if (is_inside_tree()) {
_check_unbind();
+ }
bone_name = p_name;
- if (is_inside_tree())
+ if (is_inside_tree()) {
_check_bind();
+ }
}
String BoneAttachment3D::get_bone_name() const {
-
return bone_name;
}
void BoneAttachment3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
_check_bind();
} break;
case NOTIFICATION_EXIT_TREE: {
-
_check_unbind();
} break;
}
diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h
index d2a3ffec90..fec59217d2 100644
--- a/scene/3d/bone_attachment_3d.h
+++ b/scene/3d/bone_attachment_3d.h
@@ -34,7 +34,6 @@
#include "scene/3d/skeleton_3d.h"
class BoneAttachment3D : public Node3D {
-
GDCLASS(BoneAttachment3D, Node3D);
bool bound;
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp
index 706c49b43b..8dc5cd4aba 100644
--- a/scene/3d/camera_3d.cpp
+++ b/scene/3d/camera_3d.cpp
@@ -39,16 +39,13 @@ void Camera3D::_update_audio_listener_state() {
}
void Camera3D::_request_camera_update() {
-
_update_camera();
}
void Camera3D::_update_camera_mode() {
-
force_change = true;
switch (mode) {
case PROJECTION_PERSPECTIVE: {
-
set_perspective(fov, near, far);
} break;
@@ -78,9 +75,9 @@ void Camera3D::_validate_property(PropertyInfo &p_property) const {
}
void Camera3D::_update_camera() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
RenderingServer::get_singleton()->camera_set_transform(camera, get_camera_transform());
@@ -90,22 +87,20 @@ void Camera3D::_update_camera() {
get_viewport()->_camera_transform_changed_notify();
*/
- if (get_tree()->is_node_being_edited(this) || !is_current())
+ if (get_tree()->is_node_being_edited(this) || !is_current()) {
return;
+ }
get_viewport()->_camera_transform_changed_notify();
- if (get_world().is_valid()) {
- get_world()->_update_camera(this);
+ if (get_world_3d().is_valid()) {
+ get_world_3d()->_update_camera(this);
}
}
void Camera3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_WORLD: {
-
// Needs to track the Viewport because it's needed on NOTIFICATION_EXIT_WORLD
// and Spatial will handle it first, including clearing its reference to the Viewport,
// therefore making it impossible to subclasses to access it
@@ -113,19 +108,18 @@ void Camera3D::_notification(int p_what) {
ERR_FAIL_COND(!viewport);
bool first_camera = viewport->_camera_add(this);
- if (current || first_camera)
+ if (current || first_camera) {
viewport->_camera_set(this);
+ }
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
_request_camera_update();
if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
velocity_tracker->update_position(get_global_transform().origin);
}
} break;
case NOTIFICATION_EXIT_WORLD: {
-
if (!get_tree()->is_node_being_edited(this)) {
if (is_current()) {
clear_current();
@@ -144,19 +138,18 @@ void Camera3D::_notification(int p_what) {
} break;
case NOTIFICATION_BECAME_CURRENT: {
if (viewport) {
- viewport->find_world()->_register_camera(this);
+ viewport->find_world_3d()->_register_camera(this);
}
} break;
case NOTIFICATION_LOST_CURRENT: {
if (viewport) {
- viewport->find_world()->_remove_camera(this);
+ viewport->find_world_3d()->_remove_camera(this);
}
} break;
}
}
Transform Camera3D::get_camera_transform() const {
-
Transform tr = get_global_transform().orthonormalized();
tr.origin += tr.basis.get_axis(1) * v_offset;
tr.origin += tr.basis.get_axis(0) * h_offset;
@@ -164,9 +157,9 @@ Transform Camera3D::get_camera_transform() const {
}
void Camera3D::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) {
-
- if (!force_change && fov == p_fovy_degrees && p_z_near == near && p_z_far == far && mode == PROJECTION_PERSPECTIVE)
+ if (!force_change && fov == p_fovy_degrees && p_z_near == near && p_z_far == far && mode == PROJECTION_PERSPECTIVE) {
return;
+ }
fov = p_fovy_degrees;
near = p_z_near;
@@ -177,10 +170,11 @@ void Camera3D::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_f
update_gizmo();
force_change = false;
}
-void Camera3D::set_orthogonal(float p_size, float p_z_near, float p_z_far) {
- if (!force_change && size == p_size && p_z_near == near && p_z_far == far && mode == PROJECTION_ORTHOGONAL)
+void Camera3D::set_orthogonal(float p_size, float p_z_near, float p_z_far) {
+ if (!force_change && size == p_size && p_z_near == near && p_z_far == far && mode == PROJECTION_ORTHOGONAL) {
return;
+ }
size = p_size;
@@ -194,8 +188,9 @@ void Camera3D::set_orthogonal(float p_size, float p_z_near, float p_z_far) {
}
void Camera3D::set_frustum(float p_size, Vector2 p_offset, float p_z_near, float p_z_far) {
- if (!force_change && size == p_size && frustum_offset == p_offset && p_z_near == near && p_z_far == far && mode == PROJECTION_FRUSTUM)
+ if (!force_change && size == p_size && frustum_offset == p_offset && p_z_near == near && p_z_far == far && mode == PROJECTION_FRUSTUM) {
return;
+ }
size = p_size;
frustum_offset = p_offset;
@@ -218,16 +213,15 @@ void Camera3D::set_projection(Camera3D::Projection p_mode) {
}
RID Camera3D::get_camera() const {
-
return camera;
};
void Camera3D::make_current() {
-
current = true;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
get_viewport()->_camera_set(this);
@@ -235,10 +229,10 @@ void Camera3D::make_current() {
}
void Camera3D::clear_current(bool p_enable_next) {
-
current = false;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
if (get_viewport()->get_camera() == this) {
get_viewport()->_camera_set(nullptr);
@@ -258,27 +252,23 @@ void Camera3D::set_current(bool p_current) {
}
bool Camera3D::is_current() const {
-
if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) {
-
return get_viewport()->get_camera() == this;
- } else
+ } else {
return current;
+ }
}
bool Camera3D::_can_gizmo_scale() const {
-
return false;
}
Vector3 Camera3D::project_ray_normal(const Point2 &p_pos) const {
-
Vector3 ray = project_local_ray_normal(p_pos);
return get_camera_transform().basis.xform(ray).normalized();
};
Vector3 Camera3D::project_local_ray_normal(const Point2 &p_pos) const {
-
ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
Size2 viewport_size = get_viewport()->get_camera_rect_size();
@@ -286,7 +276,6 @@ Vector3 Camera3D::project_local_ray_normal(const Point2 &p_pos) const {
Vector3 ray;
if (mode == PROJECTION_ORTHOGONAL) {
-
ray = Vector3(0, 0, -1);
} else {
CameraMatrix cm;
@@ -299,7 +288,6 @@ Vector3 Camera3D::project_local_ray_normal(const Point2 &p_pos) const {
};
Vector3 Camera3D::project_ray_origin(const Point2 &p_pos) const {
-
ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
Size2 viewport_size = get_viewport()->get_camera_rect_size();
@@ -307,10 +295,8 @@ Vector3 Camera3D::project_ray_origin(const Point2 &p_pos) const {
ERR_FAIL_COND_V(viewport_size.y == 0, Vector3());
if (mode == PROJECTION_PERSPECTIVE) {
-
return get_camera_transform().origin;
} else {
-
Vector2 pos = cpos / viewport_size;
float vsize, hsize;
if (keep_aspect == KEEP_WIDTH) {
@@ -331,7 +317,6 @@ Vector3 Camera3D::project_ray_origin(const Point2 &p_pos) const {
};
bool Camera3D::is_position_behind(const Vector3 &p_pos) const {
-
Transform t = get_global_transform();
Vector3 eyedir = -get_global_transform().basis.get_axis(2).normalized();
return eyedir.dot(p_pos) < (eyedir.dot(t.origin) + near);
@@ -344,10 +329,11 @@ Vector<Vector3> Camera3D::get_near_plane_points() const {
CameraMatrix cm;
- if (mode == PROJECTION_ORTHOGONAL)
+ if (mode == PROJECTION_ORTHOGONAL) {
cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
- else
+ } else {
cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
+ }
Vector3 endpoints[8];
cm.get_endpoints(Transform(), endpoints);
@@ -361,17 +347,17 @@ Vector<Vector3> Camera3D::get_near_plane_points() const {
}
Point2 Camera3D::unproject_position(const Vector3 &p_pos) const {
-
ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector2(), "Camera is not inside scene.");
Size2 viewport_size = get_viewport()->get_visible_rect().size;
CameraMatrix cm;
- if (mode == PROJECTION_ORTHOGONAL)
+ if (mode == PROJECTION_ORTHOGONAL) {
cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
- else
+ } else {
cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
+ }
Plane p(get_camera_transform().xform_inv(p_pos), 1.0);
@@ -386,7 +372,6 @@ Point2 Camera3D::unproject_position(const Vector3 &p_pos) const {
}
Vector3 Camera3D::project_position(const Point2 &p_point, float p_z_depth) const {
-
ERR_FAIL_COND_V_MSG(!is_inside_tree(), Vector3(), "Camera is not inside scene.");
if (p_z_depth == 0 && mode != PROJECTION_ORTHOGONAL) {
@@ -396,10 +381,11 @@ Vector3 Camera3D::project_position(const Point2 &p_point, float p_z_depth) const
CameraMatrix cm;
- if (mode == PROJECTION_ORTHOGONAL)
+ if (mode == PROJECTION_ORTHOGONAL) {
cm.set_orthogonal(size, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH);
- else
+ } else {
cm.set_perspective(fov, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH);
+ }
Vector2 vp_he = cm.get_viewport_half_extents();
@@ -414,32 +400,30 @@ Vector3 Camera3D::project_position(const Point2 &p_point, float p_z_depth) const
}
void Camera3D::set_environment(const Ref<Environment> &p_environment) {
-
environment = p_environment;
- if (environment.is_valid())
+ if (environment.is_valid()) {
RS::get_singleton()->camera_set_environment(camera, environment->get_rid());
- else
+ } else {
RS::get_singleton()->camera_set_environment(camera, RID());
+ }
_update_camera_mode();
}
Ref<Environment> Camera3D::get_environment() const {
-
return environment;
}
void Camera3D::set_effects(const Ref<CameraEffects> &p_effects) {
-
effects = p_effects;
- if (effects.is_valid())
+ if (effects.is_valid()) {
RS::get_singleton()->camera_set_camera_effects(camera, effects->get_rid());
- else
+ } else {
RS::get_singleton()->camera_set_camera_effects(camera, RID());
+ }
_update_camera_mode();
}
Ref<CameraEffects> Camera3D::get_effects() const {
-
return effects;
}
@@ -451,14 +435,13 @@ void Camera3D::set_keep_aspect_mode(KeepAspect p_aspect) {
}
Camera3D::KeepAspect Camera3D::get_keep_aspect_mode() const {
-
return keep_aspect;
}
void Camera3D::set_doppler_tracking(DopplerTracking p_tracking) {
-
- if (doppler_tracking == p_tracking)
+ if (doppler_tracking == p_tracking) {
return;
+ }
doppler_tracking = p_tracking;
if (p_tracking != DOPPLER_TRACKING_DISABLED) {
@@ -475,7 +458,6 @@ Camera3D::DopplerTracking Camera3D::get_doppler_tracking() const {
}
void Camera3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("project_ray_normal", "screen_point"), &Camera3D::project_ray_normal);
ClassDB::bind_method(D_METHOD("project_local_ray_normal", "screen_point"), &Camera3D::project_local_ray_normal);
ClassDB::bind_method(D_METHOD("project_ray_origin", "screen_point"), &Camera3D::project_ray_origin);
@@ -552,17 +534,14 @@ void Camera3D::_bind_methods() {
}
float Camera3D::get_fov() const {
-
return fov;
}
float Camera3D::get_size() const {
-
return size;
}
float Camera3D::get_znear() const {
-
return near;
}
@@ -571,12 +550,10 @@ Vector2 Camera3D::get_frustum_offset() const {
}
float Camera3D::get_zfar() const {
-
return far;
}
Camera3D::Projection Camera3D::get_projection() const {
-
return mode;
}
@@ -616,7 +593,6 @@ void Camera3D::set_cull_mask(uint32_t p_layers) {
}
uint32_t Camera3D::get_cull_mask() const {
-
return layers;
}
@@ -635,27 +611,25 @@ bool Camera3D::get_cull_mask_bit(int p_layer) const {
}
Vector<Plane> Camera3D::get_frustum() const {
-
ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>());
Size2 viewport_size = get_viewport()->get_visible_rect().size;
CameraMatrix cm;
- if (mode == PROJECTION_PERSPECTIVE)
+ if (mode == PROJECTION_PERSPECTIVE) {
cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
- else
+ } else {
cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH);
+ }
return cm.get_projection_planes(get_camera_transform());
}
void Camera3D::set_v_offset(float p_offset) {
-
v_offset = p_offset;
_update_camera();
}
float Camera3D::get_v_offset() const {
-
return v_offset;
}
@@ -665,20 +639,18 @@ void Camera3D::set_h_offset(float p_offset) {
}
float Camera3D::get_h_offset() const {
-
return h_offset;
}
Vector3 Camera3D::get_doppler_tracked_velocity() const {
-
if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
return velocity_tracker->get_tracked_linear_velocity();
} else {
return Vector3();
}
}
-Camera3D::Camera3D() {
+Camera3D::Camera3D() {
camera = RenderingServer::get_singleton()->camera_create();
size = 1;
fov = 0;
@@ -689,7 +661,7 @@ Camera3D::Camera3D() {
viewport = nullptr;
force_change = false;
mode = PROJECTION_PERSPECTIVE;
- set_perspective(70.0, 0.05, 100.0);
+ set_perspective(75.0, 0.05, 100.0);
keep_aspect = KEEP_HEIGHT;
layers = 0xfffff;
v_offset = 0;
@@ -703,7 +675,6 @@ Camera3D::Camera3D() {
}
Camera3D::~Camera3D() {
-
RenderingServer::get_singleton()->free(camera);
}
@@ -712,11 +683,12 @@ Camera3D::~Camera3D() {
void ClippedCamera3D::set_margin(float p_margin) {
margin = p_margin;
}
+
float ClippedCamera3D::get_margin() const {
return margin;
}
-void ClippedCamera3D::set_process_mode(ProcessMode p_mode) {
+void ClippedCamera3D::set_process_mode(ProcessMode p_mode) {
if (process_mode == p_mode) {
return;
}
@@ -724,12 +696,12 @@ void ClippedCamera3D::set_process_mode(ProcessMode p_mode) {
set_process_internal(process_mode == CLIP_PROCESS_IDLE);
set_physics_process_internal(process_mode == CLIP_PROCESS_PHYSICS);
}
+
ClippedCamera3D::ProcessMode ClippedCamera3D::get_process_mode() const {
return process_mode;
}
Transform ClippedCamera3D::get_camera_transform() const {
-
Transform t = Camera3D::get_camera_transform();
t.origin += -t.basis.get_axis(Vector3::AXIS_Z).normalized() * clip_offset;
return t;
@@ -737,13 +709,12 @@ Transform ClippedCamera3D::get_camera_transform() const {
void ClippedCamera3D::_notification(int p_what) {
if (p_what == NOTIFICATION_INTERNAL_PROCESS || p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
-
Node3D *parent = Object::cast_to<Node3D>(get_parent());
if (!parent) {
return;
}
- PhysicsDirectSpaceState3D *dspace = get_world()->get_direct_space_state();
+ PhysicsDirectSpaceState3D *dspace = get_world_3d()->get_direct_space_state();
ERR_FAIL_COND(!dspace); // most likely physics set to threads
Vector3 cam_fw = -get_global_transform().basis.get_axis(Vector3::AXIS_Z).normalized();
@@ -797,90 +768,78 @@ void ClippedCamera3D::_notification(int p_what) {
}
void ClippedCamera3D::set_collision_mask(uint32_t p_mask) {
-
collision_mask = p_mask;
}
uint32_t ClippedCamera3D::get_collision_mask() const {
-
return collision_mask;
}
void ClippedCamera3D::set_collision_mask_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
bool ClippedCamera3D::get_collision_mask_bit(int p_bit) const {
-
return get_collision_mask() & (1 << p_bit);
}
void ClippedCamera3D::add_exception_rid(const RID &p_rid) {
-
exclude.insert(p_rid);
}
void ClippedCamera3D::add_exception(const Object *p_object) {
-
ERR_FAIL_NULL(p_object);
const CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_object);
- if (!co)
+ if (!co) {
return;
+ }
add_exception_rid(co->get_rid());
}
void ClippedCamera3D::remove_exception_rid(const RID &p_rid) {
-
exclude.erase(p_rid);
}
void ClippedCamera3D::remove_exception(const Object *p_object) {
-
ERR_FAIL_NULL(p_object);
const CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_object);
- if (!co)
+ if (!co) {
return;
+ }
remove_exception_rid(co->get_rid());
}
void ClippedCamera3D::clear_exceptions() {
-
exclude.clear();
}
float ClippedCamera3D::get_clip_offset() const {
-
return clip_offset;
}
void ClippedCamera3D::set_clip_to_areas(bool p_clip) {
-
clip_to_areas = p_clip;
}
bool ClippedCamera3D::is_clip_to_areas_enabled() const {
-
return clip_to_areas;
}
void ClippedCamera3D::set_clip_to_bodies(bool p_clip) {
-
clip_to_bodies = p_clip;
}
bool ClippedCamera3D::is_clip_to_bodies_enabled() const {
-
return clip_to_bodies;
}
void ClippedCamera3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &ClippedCamera3D::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &ClippedCamera3D::get_margin);
@@ -920,6 +879,7 @@ void ClippedCamera3D::_bind_methods() {
BIND_ENUM_CONSTANT(CLIP_PROCESS_PHYSICS);
BIND_ENUM_CONSTANT(CLIP_PROCESS_IDLE);
}
+
ClippedCamera3D::ClippedCamera3D() {
margin = 0;
clip_offset = 0;
@@ -932,6 +892,7 @@ ClippedCamera3D::ClippedCamera3D() {
clip_to_areas = false;
clip_to_bodies = true;
}
+
ClippedCamera3D::~ClippedCamera3D() {
PhysicsServer3D::get_singleton()->free(pyramid_shape);
}
diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h
index 9a005226cb..138b1b8a7a 100644
--- a/scene/3d/camera_3d.h
+++ b/scene/3d/camera_3d.h
@@ -37,7 +37,6 @@
#include "scene/resources/environment.h"
class Camera3D : public Node3D {
-
GDCLASS(Camera3D, Node3D);
public:
@@ -184,7 +183,6 @@ VARIANT_ENUM_CAST(Camera3D::KeepAspect);
VARIANT_ENUM_CAST(Camera3D::DopplerTracking);
class ClippedCamera3D : public Camera3D {
-
GDCLASS(ClippedCamera3D, Camera3D);
public:
diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp
index e6cd7bfe7e..356992e922 100644
--- a/scene/3d/collision_object_3d.cpp
+++ b/scene/3d/collision_object_3d.cpp
@@ -34,52 +34,49 @@
#include "servers/physics_server_3d.h"
void CollisionObject3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_WORLD: {
-
- if (area)
+ if (area) {
PhysicsServer3D::get_singleton()->area_set_transform(rid, get_global_transform());
- else
+ } else {
PhysicsServer3D::get_singleton()->body_set_state(rid, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
+ }
- RID space = get_world()->get_space();
+ RID space = get_world_3d()->get_space();
if (area) {
PhysicsServer3D::get_singleton()->area_set_space(rid, space);
- } else
+ } else {
PhysicsServer3D::get_singleton()->body_set_space(rid, space);
+ }
_update_pickable();
//get space
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
- if (area)
+ if (area) {
PhysicsServer3D::get_singleton()->area_set_transform(rid, get_global_transform());
- else
+ } else {
PhysicsServer3D::get_singleton()->body_set_state(rid, PhysicsServer3D::BODY_STATE_TRANSFORM, get_global_transform());
+ }
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
_update_pickable();
} break;
case NOTIFICATION_EXIT_WORLD: {
-
if (area) {
PhysicsServer3D::get_singleton()->area_set_space(rid, RID());
- } else
+ } else {
PhysicsServer3D::get_singleton()->body_set_space(rid, RID());
+ }
} break;
}
}
void CollisionObject3D::_input_event(Node *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
-
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_input_event, p_camera, p_input_event, p_pos, p_normal, p_shape);
}
@@ -87,7 +84,6 @@ void CollisionObject3D::_input_event(Node *p_camera, const Ref<InputEvent> &p_in
}
void CollisionObject3D::_mouse_enter() {
-
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_mouse_enter);
}
@@ -95,7 +91,6 @@ void CollisionObject3D::_mouse_enter() {
}
void CollisionObject3D::_mouse_exit() {
-
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_mouse_exit);
}
@@ -103,29 +98,28 @@ void CollisionObject3D::_mouse_exit() {
}
void CollisionObject3D::_update_pickable() {
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
bool pickable = ray_pickable && is_visible_in_tree();
- if (area)
+ if (area) {
PhysicsServer3D::get_singleton()->area_set_ray_pickable(rid, pickable);
- else
+ } else {
PhysicsServer3D::get_singleton()->body_set_ray_pickable(rid, pickable);
+ }
}
void CollisionObject3D::set_ray_pickable(bool p_ray_pickable) {
-
ray_pickable = p_ray_pickable;
_update_pickable();
}
bool CollisionObject3D::is_ray_pickable() const {
-
return ray_pickable;
}
void CollisionObject3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_ray_pickable", "ray_pickable"), &CollisionObject3D::set_ray_pickable);
ClassDB::bind_method(D_METHOD("is_ray_pickable"), &CollisionObject3D::is_ray_pickable);
ClassDB::bind_method(D_METHOD("set_capture_input_on_drag", "enable"), &CollisionObject3D::set_capture_input_on_drag);
@@ -158,7 +152,6 @@ void CollisionObject3D::_bind_methods() {
}
uint32_t CollisionObject3D::create_shape_owner(Object *p_owner) {
-
ShapeData sd;
uint32_t id;
@@ -176,7 +169,6 @@ uint32_t CollisionObject3D::create_shape_owner(Object *p_owner) {
}
void CollisionObject3D::remove_shape_owner(uint32_t owner) {
-
ERR_FAIL_COND(!shapes.has(owner));
shape_owner_clear_shapes(owner);
@@ -199,21 +191,18 @@ void CollisionObject3D::shape_owner_set_disabled(uint32_t p_owner, bool p_disabl
}
bool CollisionObject3D::is_shape_owner_disabled(uint32_t p_owner) const {
-
ERR_FAIL_COND_V(!shapes.has(p_owner), false);
return shapes[p_owner].disabled;
}
void CollisionObject3D::get_shape_owners(List<uint32_t> *r_owners) {
-
for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
r_owners->push_back(E->key());
}
}
Array CollisionObject3D::_get_shape_owners() {
-
Array ret;
for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
ret.push_back(E->key());
@@ -223,7 +212,6 @@ Array CollisionObject3D::_get_shape_owners() {
}
void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transform &p_transform) {
-
ERR_FAIL_COND(!shapes.has(p_owner));
ShapeData &sd = shapes[p_owner];
@@ -236,22 +224,20 @@ void CollisionObject3D::shape_owner_set_transform(uint32_t p_owner, const Transf
}
}
}
-Transform CollisionObject3D::shape_owner_get_transform(uint32_t p_owner) const {
+Transform CollisionObject3D::shape_owner_get_transform(uint32_t p_owner) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), Transform());
return shapes[p_owner].xform;
}
Object *CollisionObject3D::shape_owner_get_owner(uint32_t p_owner) const {
-
ERR_FAIL_COND_V(!shapes.has(p_owner), nullptr);
return shapes[p_owner].owner;
}
void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape3D> &p_shape) {
-
ERR_FAIL_COND(!shapes.has(p_owner));
ERR_FAIL_COND(p_shape.is_null());
@@ -268,21 +254,21 @@ void CollisionObject3D::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape3
total_subshapes++;
}
-int CollisionObject3D::shape_owner_get_shape_count(uint32_t p_owner) const {
+int CollisionObject3D::shape_owner_get_shape_count(uint32_t p_owner) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), 0);
return shapes[p_owner].shapes.size();
}
-Ref<Shape3D> CollisionObject3D::shape_owner_get_shape(uint32_t p_owner, int p_shape) const {
+Ref<Shape3D> CollisionObject3D::shape_owner_get_shape(uint32_t p_owner, int p_shape) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), Ref<Shape3D>());
ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), Ref<Shape3D>());
return shapes[p_owner].shapes[p_shape].shape;
}
-int CollisionObject3D::shape_owner_get_shape_index(uint32_t p_owner, int p_shape) const {
+int CollisionObject3D::shape_owner_get_shape_index(uint32_t p_owner, int p_shape) const {
ERR_FAIL_COND_V(!shapes.has(p_owner), -1);
ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), -1);
@@ -290,7 +276,6 @@ int CollisionObject3D::shape_owner_get_shape_index(uint32_t p_owner, int p_shape
}
void CollisionObject3D::shape_owner_remove_shape(uint32_t p_owner, int p_shape) {
-
ERR_FAIL_COND(!shapes.has(p_owner));
ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size());
@@ -315,7 +300,6 @@ void CollisionObject3D::shape_owner_remove_shape(uint32_t p_owner, int p_shape)
}
void CollisionObject3D::shape_owner_clear_shapes(uint32_t p_owner) {
-
ERR_FAIL_COND(!shapes.has(p_owner));
while (shape_owner_get_shape_count(p_owner) > 0) {
@@ -324,7 +308,6 @@ void CollisionObject3D::shape_owner_clear_shapes(uint32_t p_owner) {
}
uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const {
-
ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0);
for (const Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
@@ -340,7 +323,6 @@ uint32_t CollisionObject3D::shape_find_owner(int p_shape_index) const {
}
CollisionObject3D::CollisionObject3D(RID p_rid, bool p_area) {
-
rid = p_rid;
area = p_area;
capture_input_on_drag = false;
@@ -357,17 +339,14 @@ CollisionObject3D::CollisionObject3D(RID p_rid, bool p_area) {
}
void CollisionObject3D::set_capture_input_on_drag(bool p_capture) {
-
capture_input_on_drag = p_capture;
}
bool CollisionObject3D::get_capture_input_on_drag() const {
-
return capture_input_on_drag;
}
String CollisionObject3D::get_configuration_warning() const {
-
String warning = Node3D::get_configuration_warning();
if (shapes.empty()) {
@@ -381,7 +360,6 @@ String CollisionObject3D::get_configuration_warning() const {
}
CollisionObject3D::CollisionObject3D() {
-
capture_input_on_drag = false;
ray_pickable = true;
set_notify_transform(true);
@@ -391,6 +369,5 @@ CollisionObject3D::CollisionObject3D() {
}
CollisionObject3D::~CollisionObject3D() {
-
PhysicsServer3D::get_singleton()->free(rid);
}
diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h
index 67d3aed3c8..8bcbef0e98 100644
--- a/scene/3d/collision_object_3d.h
+++ b/scene/3d/collision_object_3d.h
@@ -35,7 +35,6 @@
#include "scene/resources/shape_3d.h"
class CollisionObject3D : public Node3D {
-
GDCLASS(CollisionObject3D, Node3D);
bool area;
@@ -43,7 +42,6 @@ class CollisionObject3D : public Node3D {
RID rid;
struct ShapeData {
-
Object *owner;
Transform xform;
struct ShapeBase {
diff --git a/scene/3d/collision_polygon_3d.cpp b/scene/3d/collision_polygon_3d.cpp
index 66bd903eeb..bad4a1fddd 100644
--- a/scene/3d/collision_polygon_3d.cpp
+++ b/scene/3d/collision_polygon_3d.cpp
@@ -35,18 +35,20 @@
#include "scene/resources/convex_polygon_shape_3d.h"
void CollisionPolygon3D::_build_polygon() {
-
- if (!parent)
+ if (!parent) {
return;
+ }
parent->shape_owner_clear_shapes(owner_id);
- if (polygon.size() == 0)
+ if (polygon.size() == 0) {
return;
+ }
Vector<Vector<Vector2>> decomp = Geometry::decompose_polygon_in_convex(polygon);
- if (decomp.size() == 0)
+ if (decomp.size() == 0) {
return;
+ }
//here comes the sun, lalalala
//decompose concave into multiple convex polygons and add them
@@ -60,7 +62,6 @@ void CollisionPolygon3D::_build_polygon() {
Vector3 *w = cp.ptrw();
int idx = 0;
for (int j = 0; j < cs; j++) {
-
Vector2 d = decomp[i][j];
w[idx++] = Vector3(d.x, d.y, depth * 0.5);
w[idx++] = Vector3(d.x, d.y, -depth * 0.5);
@@ -74,17 +75,15 @@ void CollisionPolygon3D::_build_polygon() {
}
void CollisionPolygon3D::_update_in_shape_owner(bool p_xform_only) {
-
parent->shape_owner_set_transform(owner_id, get_transform());
- if (p_xform_only)
+ if (p_xform_only) {
return;
+ }
parent->shape_owner_set_disabled(owner_id, disabled);
}
void CollisionPolygon3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_PARENTED: {
parent = Object::cast_to<CollisionObject3D>(get_parent());
if (parent) {
@@ -94,14 +93,12 @@ void CollisionPolygon3D::_notification(int p_what) {
}
} break;
case NOTIFICATION_ENTER_TREE: {
-
if (parent) {
_update_in_shape_owner();
}
} break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
-
if (parent) {
_update_in_shape_owner(true);
}
@@ -118,7 +115,6 @@ void CollisionPolygon3D::_notification(int p_what) {
}
void CollisionPolygon3D::set_polygon(const Vector<Point2> &p_polygon) {
-
polygon = p_polygon;
if (parent) {
_build_polygon();
@@ -128,24 +124,20 @@ void CollisionPolygon3D::set_polygon(const Vector<Point2> &p_polygon) {
}
Vector<Point2> CollisionPolygon3D::get_polygon() const {
-
return polygon;
}
AABB CollisionPolygon3D::get_item_rect() const {
-
return aabb;
}
void CollisionPolygon3D::set_depth(float p_depth) {
-
depth = p_depth;
_build_polygon();
update_gizmo();
}
float CollisionPolygon3D::get_depth() const {
-
return depth;
}
@@ -163,7 +155,6 @@ bool CollisionPolygon3D::is_disabled() const {
}
String CollisionPolygon3D::get_configuration_warning() const {
-
if (!Object::cast_to<CollisionObject3D>(get_parent())) {
return TTR("CollisionPolygon3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
}
@@ -178,8 +169,8 @@ String CollisionPolygon3D::get_configuration_warning() const {
bool CollisionPolygon3D::_is_editable_3d_polygon() const {
return true;
}
-void CollisionPolygon3D::_bind_methods() {
+void CollisionPolygon3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_depth", "depth"), &CollisionPolygon3D::set_depth);
ClassDB::bind_method(D_METHOD("get_depth"), &CollisionPolygon3D::get_depth);
@@ -197,7 +188,6 @@ void CollisionPolygon3D::_bind_methods() {
}
CollisionPolygon3D::CollisionPolygon3D() {
-
aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
depth = 1.0;
set_notify_local_transform(true);
diff --git a/scene/3d/collision_polygon_3d.h b/scene/3d/collision_polygon_3d.h
index 256aee3d7e..0cd9aee111 100644
--- a/scene/3d/collision_polygon_3d.h
+++ b/scene/3d/collision_polygon_3d.h
@@ -36,7 +36,6 @@
class CollisionObject3D;
class CollisionPolygon3D : public Node3D {
-
GDCLASS(CollisionPolygon3D, Node3D);
protected:
diff --git a/scene/3d/collision_shape_3d.cpp b/scene/3d/collision_shape_3d.cpp
index a66e84ac3c..56367e9bdd 100644
--- a/scene/3d/collision_shape_3d.cpp
+++ b/scene/3d/collision_shape_3d.cpp
@@ -45,20 +45,17 @@
//TODO: Implement CylinderShape and HeightMapShape?
void CollisionShape3D::make_convex_from_brothers() {
-
Node *p = get_parent();
- if (!p)
+ if (!p) {
return;
+ }
for (int i = 0; i < p->get_child_count(); i++) {
-
Node *n = p->get_child(i);
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(n);
if (mi) {
-
Ref<Mesh> m = mi->get_mesh();
if (m.is_valid()) {
-
Ref<Shape3D> s = m->create_convex_shape();
set_shape(s);
}
@@ -68,15 +65,14 @@ void CollisionShape3D::make_convex_from_brothers() {
void CollisionShape3D::_update_in_shape_owner(bool p_xform_only) {
parent->shape_owner_set_transform(owner_id, get_transform());
- if (p_xform_only)
+ if (p_xform_only) {
return;
+ }
parent->shape_owner_set_disabled(owner_id, disabled);
}
void CollisionShape3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_PARENTED: {
parent = Object::cast_to<CollisionObject3D>(get_parent());
if (parent) {
@@ -111,12 +107,10 @@ void CollisionShape3D::_notification(int p_what) {
}
void CollisionShape3D::resource_changed(RES res) {
-
update_gizmo();
}
String CollisionShape3D::get_configuration_warning() const {
-
if (!Object::cast_to<CollisionObject3D>(get_parent())) {
return TTR("CollisionShape3D only serves to provide a collision shape to a CollisionObject3D derived node. Please only use it as a child of Area3D, StaticBody3D, RigidBody3D, KinematicBody3D, etc. to give them a shape.");
}
@@ -137,7 +131,6 @@ String CollisionShape3D::get_configuration_warning() const {
}
void CollisionShape3D::_bind_methods() {
-
//not sure if this should do anything
ClassDB::bind_method(D_METHOD("resource_changed", "resource"), &CollisionShape3D::resource_changed);
ClassDB::bind_method(D_METHOD("set_shape", "shape"), &CollisionShape3D::set_shape);
@@ -154,7 +147,6 @@ void CollisionShape3D::_bind_methods() {
}
void CollisionShape3D::set_shape(const Ref<Shape3D> &p_shape) {
-
if (!shape.is_null()) {
shape->unregister_owner(this);
shape->disconnect("changed", callable_mp(this, &CollisionShape3D::_shape_changed));
@@ -172,18 +164,17 @@ void CollisionShape3D::set_shape(const Ref<Shape3D> &p_shape) {
}
}
- if (is_inside_tree())
+ if (is_inside_tree()) {
_shape_changed();
+ }
update_configuration_warning();
}
Ref<Shape3D> CollisionShape3D::get_shape() const {
-
return shape;
}
void CollisionShape3D::set_disabled(bool p_disabled) {
-
disabled = p_disabled;
update_gizmo();
if (parent) {
@@ -192,12 +183,10 @@ void CollisionShape3D::set_disabled(bool p_disabled) {
}
bool CollisionShape3D::is_disabled() const {
-
return disabled;
}
CollisionShape3D::CollisionShape3D() {
-
//indicator = RenderingServer::get_singleton()->mesh_create();
disabled = false;
debug_shape = nullptr;
@@ -207,8 +196,9 @@ CollisionShape3D::CollisionShape3D() {
}
CollisionShape3D::~CollisionShape3D() {
- if (!shape.is_null())
+ if (!shape.is_null()) {
shape->unregister_owner(this);
+ }
//RenderingServer::get_singleton()->free(indicator);
}
@@ -221,8 +211,9 @@ void CollisionShape3D::_update_debug_shape() {
}
Ref<Shape3D> s = get_shape();
- if (s.is_null())
+ if (s.is_null()) {
return;
+ }
Ref<Mesh> mesh = s->get_debug_mesh();
MeshInstance3D *mi = memnew(MeshInstance3D);
diff --git a/scene/3d/collision_shape_3d.h b/scene/3d/collision_shape_3d.h
index 8515d292af..4ed2f4007b 100644
--- a/scene/3d/collision_shape_3d.h
+++ b/scene/3d/collision_shape_3d.h
@@ -35,7 +35,6 @@
#include "scene/resources/shape_3d.h"
class CollisionObject3D;
class CollisionShape3D : public Node3D {
-
GDCLASS(CollisionShape3D, Node3D);
OBJ_CATEGORY("3D Physics Nodes");
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index 12c105b0f4..4244a11592 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -36,31 +36,30 @@
#include "servers/rendering_server.h"
AABB CPUParticles3D::get_aabb() const {
-
return AABB();
}
-Vector<Face3> CPUParticles3D::get_faces(uint32_t p_usage_flags) const {
+Vector<Face3> CPUParticles3D::get_faces(uint32_t p_usage_flags) const {
return Vector<Face3>();
}
void CPUParticles3D::set_emitting(bool p_emitting) {
-
- if (emitting == p_emitting)
+ if (emitting == p_emitting) {
return;
+ }
emitting = p_emitting;
if (emitting) {
set_process_internal(true);
// first update before rendering to avoid one frame delay after emitting starts
- if (time == 0)
+ if (time == 0) {
_update_internal();
+ }
}
}
void CPUParticles3D::set_amount(int p_amount) {
-
ERR_FAIL_COND_MSG(p_amount < 1, "Amount of particles must be greater than 0.");
particles.resize(p_amount);
@@ -69,6 +68,7 @@ void CPUParticles3D::set_amount(int p_amount) {
for (int i = 0; i < p_amount; i++) {
w[i].active = false;
+ w[i].custom[3] = 0.0; // Make sure w component isn't garbage data
}
}
@@ -77,98 +77,89 @@ void CPUParticles3D::set_amount(int p_amount) {
particle_order.resize(p_amount);
}
-void CPUParticles3D::set_lifetime(float p_lifetime) {
+void CPUParticles3D::set_lifetime(float p_lifetime) {
ERR_FAIL_COND_MSG(p_lifetime <= 0, "Particles lifetime must be greater than 0.");
lifetime = p_lifetime;
}
void CPUParticles3D::set_one_shot(bool p_one_shot) {
-
one_shot = p_one_shot;
}
void CPUParticles3D::set_pre_process_time(float p_time) {
-
pre_process_time = p_time;
}
-void CPUParticles3D::set_explosiveness_ratio(float p_ratio) {
+void CPUParticles3D::set_explosiveness_ratio(float p_ratio) {
explosiveness_ratio = p_ratio;
}
-void CPUParticles3D::set_randomness_ratio(float p_ratio) {
+void CPUParticles3D::set_randomness_ratio(float p_ratio) {
randomness_ratio = p_ratio;
}
-void CPUParticles3D::set_lifetime_randomness(float p_random) {
+void CPUParticles3D::set_lifetime_randomness(float p_random) {
lifetime_randomness = p_random;
}
-void CPUParticles3D::set_use_local_coordinates(bool p_enable) {
+void CPUParticles3D::set_use_local_coordinates(bool p_enable) {
local_coords = p_enable;
}
-void CPUParticles3D::set_speed_scale(float p_scale) {
+void CPUParticles3D::set_speed_scale(float p_scale) {
speed_scale = p_scale;
}
bool CPUParticles3D::is_emitting() const {
-
return emitting;
}
-int CPUParticles3D::get_amount() const {
+int CPUParticles3D::get_amount() const {
return particles.size();
}
-float CPUParticles3D::get_lifetime() const {
+float CPUParticles3D::get_lifetime() const {
return lifetime;
}
-bool CPUParticles3D::get_one_shot() const {
+bool CPUParticles3D::get_one_shot() const {
return one_shot;
}
float CPUParticles3D::get_pre_process_time() const {
-
return pre_process_time;
}
-float CPUParticles3D::get_explosiveness_ratio() const {
+float CPUParticles3D::get_explosiveness_ratio() const {
return explosiveness_ratio;
}
-float CPUParticles3D::get_randomness_ratio() const {
+float CPUParticles3D::get_randomness_ratio() const {
return randomness_ratio;
}
-float CPUParticles3D::get_lifetime_randomness() const {
+float CPUParticles3D::get_lifetime_randomness() const {
return lifetime_randomness;
}
bool CPUParticles3D::get_use_local_coordinates() const {
-
return local_coords;
}
float CPUParticles3D::get_speed_scale() const {
-
return speed_scale;
}
void CPUParticles3D::set_draw_order(DrawOrder p_order) {
-
draw_order = p_order;
}
CPUParticles3D::DrawOrder CPUParticles3D::get_draw_order() const {
-
return draw_order;
}
void CPUParticles3D::set_mesh(const Ref<Mesh> &p_mesh) {
-
mesh = p_mesh;
if (mesh.is_valid()) {
RS::get_singleton()->multimesh_set_mesh(multimesh, mesh->get_rid());
@@ -178,7 +169,6 @@ void CPUParticles3D::set_mesh(const Ref<Mesh> &p_mesh) {
}
Ref<Mesh> CPUParticles3D::get_mesh() const {
-
return mesh;
}
@@ -199,7 +189,6 @@ bool CPUParticles3D::get_fractional_delta() const {
}
String CPUParticles3D::get_configuration_warning() const {
-
String warnings;
bool mesh_found = false;
@@ -219,15 +208,17 @@ String CPUParticles3D::get_configuration_warning() const {
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES);
if (!mesh_found) {
- if (warnings != String())
+ if (warnings != String()) {
warnings += "\n";
+ }
warnings += "- " + TTR("Nothing is visible because no mesh has been assigned.");
}
if (!anim_material_found && (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 ||
get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid())) {
- if (warnings != String())
+ if (warnings != String()) {
warnings += "\n";
+ }
warnings += "- " + TTR("CPUParticles3D animation requires the usage of a StandardMaterial3D whose Billboard Mode is set to \"Particle Billboard\".");
}
@@ -235,7 +226,6 @@ String CPUParticles3D::get_configuration_warning() const {
}
void CPUParticles3D::restart() {
-
time = 0;
inactive_time = 0;
frame_remainder = 0;
@@ -255,71 +245,63 @@ void CPUParticles3D::restart() {
}
void CPUParticles3D::set_direction(Vector3 p_direction) {
-
direction = p_direction;
}
Vector3 CPUParticles3D::get_direction() const {
-
return direction;
}
void CPUParticles3D::set_spread(float p_spread) {
-
spread = p_spread;
}
float CPUParticles3D::get_spread() const {
-
return spread;
}
void CPUParticles3D::set_flatness(float p_flatness) {
-
flatness = p_flatness;
}
-float CPUParticles3D::get_flatness() const {
+float CPUParticles3D::get_flatness() const {
return flatness;
}
void CPUParticles3D::set_param(Parameter p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
parameters[p_param] = p_value;
}
-float CPUParticles3D::get_param(Parameter p_param) const {
+float CPUParticles3D::get_param(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return parameters[p_param];
}
void CPUParticles3D::set_param_randomness(Parameter p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
randomness[p_param] = p_value;
}
-float CPUParticles3D::get_param_randomness(Parameter p_param) const {
+float CPUParticles3D::get_param_randomness(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return randomness[p_param];
}
static void _adjust_curve_range(const Ref<Curve> &p_curve, float p_min, float p_max) {
-
Ref<Curve> curve = p_curve;
- if (!curve.is_valid())
+ if (!curve.is_valid()) {
return;
+ }
curve->ensure_default_setup(p_min, p_max);
}
void CPUParticles3D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curve) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
curve_parameters[p_param] = p_curve;
@@ -350,7 +332,6 @@ void CPUParticles3D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv
_adjust_curve_range(p_curve, -360, 360);
} break;
case PARAM_SCALE: {
-
} break;
case PARAM_HUE_VARIATION: {
_adjust_curve_range(p_curve, -1, 1);
@@ -364,30 +345,26 @@ void CPUParticles3D::set_param_curve(Parameter p_param, const Ref<Curve> &p_curv
}
}
}
-Ref<Curve> CPUParticles3D::get_param_curve(Parameter p_param) const {
+Ref<Curve> CPUParticles3D::get_param_curve(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Curve>());
return curve_parameters[p_param];
}
void CPUParticles3D::set_color(const Color &p_color) {
-
color = p_color;
}
Color CPUParticles3D::get_color() const {
-
return color;
}
void CPUParticles3D::set_color_ramp(const Ref<Gradient> &p_ramp) {
-
color_ramp = p_ramp;
}
Ref<Gradient> CPUParticles3D::get_color_ramp() const {
-
return color_ramp;
}
@@ -410,67 +387,58 @@ void CPUParticles3D::set_emission_shape(EmissionShape p_shape) {
}
void CPUParticles3D::set_emission_sphere_radius(float p_radius) {
-
emission_sphere_radius = p_radius;
}
void CPUParticles3D::set_emission_box_extents(Vector3 p_extents) {
-
emission_box_extents = p_extents;
}
void CPUParticles3D::set_emission_points(const Vector<Vector3> &p_points) {
-
emission_points = p_points;
}
void CPUParticles3D::set_emission_normals(const Vector<Vector3> &p_normals) {
-
emission_normals = p_normals;
}
void CPUParticles3D::set_emission_colors(const Vector<Color> &p_colors) {
-
emission_colors = p_colors;
}
float CPUParticles3D::get_emission_sphere_radius() const {
-
return emission_sphere_radius;
}
-Vector3 CPUParticles3D::get_emission_box_extents() const {
+Vector3 CPUParticles3D::get_emission_box_extents() const {
return emission_box_extents;
}
-Vector<Vector3> CPUParticles3D::get_emission_points() const {
+Vector<Vector3> CPUParticles3D::get_emission_points() const {
return emission_points;
}
-Vector<Vector3> CPUParticles3D::get_emission_normals() const {
+Vector<Vector3> CPUParticles3D::get_emission_normals() const {
return emission_normals;
}
Vector<Color> CPUParticles3D::get_emission_colors() const {
-
return emission_colors;
}
CPUParticles3D::EmissionShape CPUParticles3D::get_emission_shape() const {
return emission_shape;
}
-void CPUParticles3D::set_gravity(const Vector3 &p_gravity) {
+void CPUParticles3D::set_gravity(const Vector3 &p_gravity) {
gravity = p_gravity;
}
Vector3 CPUParticles3D::get_gravity() const {
-
return gravity;
}
void CPUParticles3D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "color" && color_ramp.is_valid()) {
property.usage = 0;
}
@@ -497,7 +465,6 @@ void CPUParticles3D::_validate_property(PropertyInfo &property) const {
}
static uint32_t idhash(uint32_t x) {
-
x = ((x >> uint32_t(16)) ^ x) * uint32_t(0x45d9f3b);
x = ((x >> uint32_t(16)) ^ x) * uint32_t(0x45d9f3b);
x = (x >> uint32_t(16)) ^ x;
@@ -507,18 +474,19 @@ static uint32_t idhash(uint32_t x) {
static float rand_from_seed(uint32_t &seed) {
int k;
int s = int(seed);
- if (s == 0)
+ if (s == 0) {
s = 305420679;
+ }
k = s / 127773;
s = 16807 * (s - k * 127773) - 2836 * k;
- if (s < 0)
+ if (s < 0) {
s += 2147483647;
+ }
seed = uint32_t(s);
return float(seed % uint32_t(65536)) / 65535.0;
}
void CPUParticles3D::_update_internal() {
-
if (particles.size() == 0 || !is_visible_in_tree()) {
_set_redraw(false);
return;
@@ -546,12 +514,12 @@ void CPUParticles3D::_update_internal() {
bool processed = false;
if (time == 0 && pre_process_time > 0.0) {
-
float frame_time;
- if (fixed_fps > 0)
+ if (fixed_fps > 0) {
frame_time = 1.0 / fixed_fps;
- else
+ } else {
frame_time = 1.0 / 30.0;
+ }
float todo = pre_process_time;
@@ -593,7 +561,6 @@ void CPUParticles3D::_update_internal() {
}
void CPUParticles3D::_particles_process(float p_delta) {
-
p_delta *= speed_scale;
int pcount = particles.size();
@@ -622,11 +589,11 @@ void CPUParticles3D::_particles_process(float p_delta) {
float system_phase = time / lifetime;
for (int i = 0; i < pcount; i++) {
-
Particle &p = parray[i];
- if (!emitting && !p.active)
+ if (!emitting && !p.active) {
continue;
+ }
float local_delta = p_delta;
@@ -680,7 +647,6 @@ void CPUParticles3D::_particles_process(float p_delta) {
}
if (restart) {
-
if (!emitting) {
p.active = false;
continue;
@@ -749,10 +715,10 @@ void CPUParticles3D::_particles_process(float p_delta) {
} break;
case EMISSION_SHAPE_POINTS:
case EMISSION_SHAPE_DIRECTED_POINTS: {
-
int pc = emission_points.size();
- if (pc == 0)
+ if (pc == 0) {
break;
+ }
int random_idx = Math::rand() % pc;
@@ -804,7 +770,6 @@ void CPUParticles3D::_particles_process(float p_delta) {
} else if (p.time > p.lifetime) {
p.active = false;
} else {
-
uint32_t alt_seed = p.seed;
p.time += local_delta;
@@ -874,7 +839,6 @@ void CPUParticles3D::_particles_process(float p_delta) {
force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector3();
//apply tangential acceleration;
if (flags[FLAG_DISABLE_Z]) {
-
Vector2 yx = Vector2(diff.y, diff.x);
Vector2 yx2 = (yx * Vector2(-1.0, 1.0)).normalized();
force += yx.length() > 0.0 ? Vector3(yx2.x, yx2.y, 0.0) * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3();
@@ -902,7 +866,6 @@ void CPUParticles3D::_particles_process(float p_delta) {
p.velocity = p.velocity.normalized() * tex_linear_velocity;
}
if (parameters[PARAM_DAMPING] + tex_damping > 0.0) {
-
float v = p.velocity.length();
float damp = (parameters[PARAM_DAMPING] + tex_damping) * Math::lerp(1.0f, rand_from_seed(alt_seed), randomness[PARAM_DAMPING]);
v -= damp * local_delta;
@@ -959,7 +922,6 @@ void CPUParticles3D::_particles_process(float p_delta) {
p.color *= p.base_color;
if (flags[FLAG_DISABLE_Z]) {
-
if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) {
if (p.velocity.length() > 0.0) {
p.transform.basis.set_axis(1, p.velocity.normalized());
@@ -1003,7 +965,9 @@ void CPUParticles3D::_particles_process(float p_delta) {
//scale by scale
float base_scale = tex_scale * Math::lerp(parameters[PARAM_SCALE], 1.0f, p.scale_rand * randomness[PARAM_SCALE]);
- if (base_scale < 0.000001) base_scale = 0.000001;
+ if (base_scale < 0.000001) {
+ base_scale = 0.000001;
+ }
p.transform.basis.scale(Vector3(1, 1, 1) * base_scale);
@@ -1045,7 +1009,6 @@ void CPUParticles3D::_update_particle_data_buffer() {
Vector3 dir = c->get_global_transform().basis.get_axis(2); //far away to close
if (local_coords) {
-
// will look different from Particles in editor as this is based on the camera in the scenetree
// and not the editor camera
dir = inv_emission_transform.xform(dir).normalized();
@@ -1062,7 +1025,6 @@ void CPUParticles3D::_update_particle_data_buffer() {
}
for (int i = 0; i < pc; i++) {
-
int idx = order ? order[i] : i;
Transform t = r[idx].transform;
@@ -1107,8 +1069,9 @@ void CPUParticles3D::_update_particle_data_buffer() {
}
void CPUParticles3D::_set_redraw(bool p_redraw) {
- if (redraw == p_redraw)
+ if (redraw == p_redraw) {
return;
+ }
redraw = p_redraw;
{
@@ -1129,7 +1092,6 @@ void CPUParticles3D::_set_redraw(bool p_redraw) {
}
void CPUParticles3D::_update_render_thread() {
-
MutexLock lock(update_mutex);
if (can_update) {
@@ -1139,13 +1101,13 @@ void CPUParticles3D::_update_render_thread() {
}
void CPUParticles3D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
set_process_internal(emitting);
// first update before rendering to avoid one frame delay after emitting starts
- if (emitting && (time == 0))
+ if (emitting && (time == 0)) {
_update_internal();
+ }
}
if (p_what == NOTIFICATION_EXIT_TREE) {
@@ -1154,8 +1116,9 @@ void CPUParticles3D::_notification(int p_what) {
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
// first update before rendering to avoid one frame delay after emitting starts
- if (emitting && (time == 0))
+ if (emitting && (time == 0)) {
_update_internal();
+ }
}
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
@@ -1163,11 +1126,9 @@ void CPUParticles3D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
-
inv_emission_transform = get_global_transform().affine_inverse();
if (!local_coords) {
-
int pc = particles.size();
float *w = particle_data.ptrw();
@@ -1175,7 +1136,6 @@ void CPUParticles3D::_notification(int p_what) {
float *ptr = w;
for (int i = 0; i < pc; i++) {
-
Transform t = inv_emission_transform * r[i].transform;
if (r[i].active) {
@@ -1204,7 +1164,6 @@ void CPUParticles3D::_notification(int p_what) {
}
void CPUParticles3D::convert_from_particles(Node *p_particles) {
-
GPUParticles3D *particles = Object::cast_to<GPUParticles3D>(p_particles);
ERR_FAIL_COND_MSG(!particles, "Only GPUParticles3D nodes can be converted to CPUParticles3D.");
@@ -1223,8 +1182,9 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) {
set_mesh(particles->get_draw_pass_mesh(0));
Ref<ParticlesMaterial> material = particles->get_process_material();
- if (material.is_null())
+ if (material.is_null()) {
return;
+ }
set_direction(material->get_direction());
set_spread(material->get_spread());
@@ -1252,7 +1212,8 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) {
set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \
{ \
Ref<CurveTexture> ctex = material->get_param_texture(ParticlesMaterial::m_param); \
- if (ctex.is_valid()) set_param_curve(m_param, ctex->get_curve()); \
+ if (ctex.is_valid()) \
+ set_param_curve(m_param, ctex->get_curve()); \
} \
set_param_randomness(m_param, material->get_param_randomness(ParticlesMaterial::m_param));
@@ -1273,7 +1234,6 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) {
}
void CPUParticles3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &CPUParticles3D::set_emitting);
ClassDB::bind_method(D_METHOD("set_amount", "amount"), &CPUParticles3D::set_amount);
ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &CPUParticles3D::set_lifetime);
@@ -1478,7 +1438,6 @@ void CPUParticles3D::_bind_methods() {
}
CPUParticles3D::CPUParticles3D() {
-
time = 0;
inactive_time = 0;
frame_remainder = 0;
diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h
index ffe0ecc9a9..2afb6846c0 100644
--- a/scene/3d/cpu_particles_3d.h
+++ b/scene/3d/cpu_particles_3d.h
@@ -122,7 +122,6 @@ private:
const Particle *particles;
Vector3 axis;
bool operator()(int p_a, int p_b) const {
-
return axis.dot(particles[p_a].transform.origin) < axis.dot(particles[p_b].transform.origin);
}
};
diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp
index 4c824aedc4..fb72e10171 100644
--- a/scene/3d/decal.cpp
+++ b/scene/3d/decal.cpp
@@ -47,6 +47,7 @@ void Decal::set_texture(DecalTexture p_type, const Ref<Texture2D> &p_texture) {
RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RS::get_singleton()->decal_set_texture(decal, RS::DecalTexture(p_type), texture_rid);
}
+
Ref<Texture2D> Decal::get_texture(DecalTexture p_type) const {
ERR_FAIL_INDEX_V(p_type, TEXTURE_MAX, Ref<Texture2D>());
return textures[p_type];
@@ -56,6 +57,7 @@ void Decal::set_emission_energy(float p_energy) {
emission_energy = p_energy;
RS::get_singleton()->decal_set_emission_energy(decal, emission_energy);
}
+
float Decal::get_emission_energy() const {
return emission_energy;
}
@@ -64,6 +66,7 @@ void Decal::set_albedo_mix(float p_mix) {
albedo_mix = p_mix;
RS::get_singleton()->decal_set_albedo_mix(decal, albedo_mix);
}
+
float Decal::get_albedo_mix() const {
return albedo_mix;
}
@@ -72,6 +75,7 @@ void Decal::set_upper_fade(float p_fade) {
upper_fade = p_fade;
RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade);
}
+
float Decal::get_upper_fade() const {
return upper_fade;
}
@@ -80,6 +84,7 @@ void Decal::set_lower_fade(float p_fade) {
lower_fade = p_fade;
RS::get_singleton()->decal_set_fade(decal, upper_fade, lower_fade);
}
+
float Decal::get_lower_fade() const {
return lower_fade;
}
@@ -88,6 +93,7 @@ void Decal::set_normal_fade(float p_fade) {
normal_fade = p_fade;
RS::get_singleton()->decal_set_normal_fade(decal, normal_fade);
}
+
float Decal::get_normal_fade() const {
return normal_fade;
}
@@ -105,6 +111,7 @@ void Decal::set_enable_distance_fade(bool p_enable) {
distance_fade_enabled = p_enable;
RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length);
}
+
bool Decal::is_distance_fade_enabled() const {
return distance_fade_enabled;
}
@@ -113,6 +120,7 @@ void Decal::set_distance_fade_begin(float p_distance) {
distance_fade_begin = p_distance;
RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length);
}
+
float Decal::get_distance_fade_begin() const {
return distance_fade_begin;
}
@@ -121,6 +129,7 @@ void Decal::set_distance_fade_length(float p_length) {
distance_fade_length = p_length;
RS::get_singleton()->decal_set_distance_fade(decal, distance_fade_enabled, distance_fade_begin, distance_fade_length);
}
+
float Decal::get_distance_fade_length() const {
return distance_fade_length;
}
@@ -129,24 +138,23 @@ void Decal::set_cull_mask(uint32_t p_layers) {
cull_mask = p_layers;
RS::get_singleton()->decal_set_cull_mask(decal, cull_mask);
}
+
uint32_t Decal::get_cull_mask() const {
return cull_mask;
}
AABB Decal::get_aabb() const {
-
AABB aabb;
aabb.position = -extents;
aabb.size = extents * 2.0;
return aabb;
}
-Vector<Face3> Decal::get_faces(uint32_t p_usage_flags) const {
+Vector<Face3> Decal::get_faces(uint32_t p_usage_flags) const {
return Vector<Face3>();
}
void Decal::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_extents", "extents"), &Decal::set_extents);
ClassDB::bind_method(D_METHOD("get_extents"), &Decal::get_extents);
@@ -212,7 +220,6 @@ void Decal::_bind_methods() {
}
Decal::Decal() {
-
extents = Vector3(1, 1, 1);
emission_energy = 1.0;
modulate = Color(1, 1, 1, 1);
@@ -230,6 +237,5 @@ Decal::Decal() {
}
Decal::~Decal() {
-
RS::get_singleton()->free(decal);
}
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index 6d571ee4f2..1b6f9b45b9 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -101,15 +101,19 @@ void GIProbeData::allocate(const Transform &p_to_cell_xform, const AABB &p_aabb,
AABB GIProbeData::get_bounds() const {
return bounds;
}
+
Vector3 GIProbeData::get_octree_size() const {
return octree_size;
}
+
Vector<uint8_t> GIProbeData::get_octree_cells() const {
return RS::get_singleton()->gi_probe_get_octree_cells(probe);
}
+
Vector<uint8_t> GIProbeData::get_data_cells() const {
return RS::get_singleton()->gi_probe_get_data_cells(probe);
}
+
Vector<uint8_t> GIProbeData::get_distance_field() const {
return RS::get_singleton()->gi_probe_get_distance_field(probe);
}
@@ -117,6 +121,7 @@ Vector<uint8_t> GIProbeData::get_distance_field() const {
Vector<int> GIProbeData::get_level_counts() const {
return RS::get_singleton()->gi_probe_get_level_counts(probe);
}
+
Transform GIProbeData::get_to_cell_xform() const {
return to_cell_xform;
}
@@ -212,7 +217,6 @@ bool GIProbeData::is_using_two_bounces() const {
}
RID GIProbeData::get_rid() const {
-
return probe;
}
@@ -283,7 +287,6 @@ void GIProbeData::_bind_methods() {
}
GIProbeData::GIProbeData() {
-
ao = 0.0;
ao_size = 0.5;
dynamic_range = 4;
@@ -299,7 +302,6 @@ GIProbeData::GIProbeData() {
}
GIProbeData::~GIProbeData() {
-
RS::get_singleton()->free(probe);
}
@@ -307,7 +309,6 @@ GIProbeData::~GIProbeData() {
//////////////////////
void GIProbe::set_probe_data(const Ref<GIProbeData> &p_data) {
-
if (p_data.is_valid()) {
RS::get_singleton()->instance_set_base(get_instance(), p_data->get_rid());
} else {
@@ -318,41 +319,34 @@ void GIProbe::set_probe_data(const Ref<GIProbeData> &p_data) {
}
Ref<GIProbeData> GIProbe::get_probe_data() const {
-
return probe_data;
}
void GIProbe::set_subdiv(Subdiv p_subdiv) {
-
ERR_FAIL_INDEX(p_subdiv, SUBDIV_MAX);
subdiv = p_subdiv;
update_gizmo();
}
GIProbe::Subdiv GIProbe::get_subdiv() const {
-
return subdiv;
}
void GIProbe::set_extents(const Vector3 &p_extents) {
-
extents = p_extents;
update_gizmo();
_change_notify("extents");
}
Vector3 GIProbe::get_extents() const {
-
return extents;
}
void GIProbe::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) {
-
MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_at_node);
- if (mi && mi->get_flag(GeometryInstance3D::FLAG_USE_BAKED_LIGHT) && mi->is_visible_in_tree()) {
+ if (mi && mi->get_gi_mode() == GeometryInstance3D::GI_MODE_BAKED && mi->is_visible_in_tree()) {
Ref<Mesh> mesh = mi->get_mesh();
if (mesh.is_valid()) {
-
AABB aabb = mesh->get_aabb();
Transform xf = get_global_transform().affine_inverse() * mi->get_global_transform();
@@ -372,16 +366,14 @@ void GIProbe::_find_meshes(Node *p_at_node, List<PlotMesh> &plot_meshes) {
Node3D *s = Object::cast_to<Node3D>(p_at_node);
if (s) {
-
if (s->is_visible_in_tree()) {
-
Array meshes = p_at_node->call("get_meshes");
for (int i = 0; i < meshes.size(); i += 2) {
-
Transform mxf = meshes[i];
Ref<Mesh> mesh = meshes[i + 1];
- if (!mesh.is_valid())
+ if (!mesh.is_valid()) {
continue;
+ }
AABB aabb = mesh->get_aabb();
@@ -416,9 +408,9 @@ Vector3i GIProbe::get_estimated_cell_size() const {
axis_cell_size[longest_axis] = 1 << cell_subdiv;
for (int i = 0; i < 3; i++) {
-
- if (i == longest_axis)
+ if (i == longest_axis) {
continue;
+ }
axis_cell_size[i] = axis_cell_size[longest_axis];
float axis_size = bounds.size[longest_axis];
@@ -432,8 +424,8 @@ Vector3i GIProbe::get_estimated_cell_size() const {
return Vector3i(axis_cell_size[0], axis_cell_size[1], axis_cell_size[2]);
}
-void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
+void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
static const int subdiv_value[SUBDIV_MAX] = { 6, 7, 8, 9 };
Voxelizer baker;
@@ -451,7 +443,6 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
int pmc = 0;
for (List<PlotMesh>::Element *E = mesh_list.front(); E; E = E->next()) {
-
if (bake_step_function) {
bake_step_function(pmc, RTR("Plotting Meshes") + " " + itos(pmc) + "/" + itos(mesh_list.size()));
}
@@ -483,11 +474,11 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
#endif
} else {
-
Ref<GIProbeData> probe_data = get_probe_data();
- if (probe_data.is_null())
+ if (probe_data.is_null()) {
probe_data.instance();
+ }
if (bake_step_function) {
bake_step_function(pmc++, RTR("Generating Distance Field"));
@@ -511,22 +502,18 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
}
void GIProbe::_debug_bake() {
-
bake(nullptr, true);
}
AABB GIProbe::get_aabb() const {
-
return AABB(-extents, extents * 2);
}
Vector<Face3> GIProbe::get_faces(uint32_t p_usage_flags) const {
-
return Vector<Face3>();
}
String GIProbe::get_configuration_warning() const {
-
if (RenderingServer::get_singleton()->is_low_end()) {
return TTR("GIProbes are not supported by the GLES2 video driver.\nUse a BakedLightmap instead.");
}
@@ -534,7 +521,6 @@ String GIProbe::get_configuration_warning() const {
}
void GIProbe::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_probe_data", "data"), &GIProbe::set_probe_data);
ClassDB::bind_method(D_METHOD("get_probe_data"), &GIProbe::get_probe_data);
@@ -560,7 +546,6 @@ void GIProbe::_bind_methods() {
}
GIProbe::GIProbe() {
-
subdiv = SUBDIV_128;
extents = Vector3(10, 10, 10);
diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h
index 28b533e82d..b7abfbd01b 100644
--- a/scene/3d/gi_probe.h
+++ b/scene/3d/gi_probe.h
@@ -35,7 +35,6 @@
#include "scene/3d/visual_instance_3d.h"
class GIProbeData : public Resource {
-
GDCLASS(GIProbeData, Resource);
RID probe;
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index 7744c477cb..c4480e3ed2 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -36,16 +36,14 @@
#include "servers/rendering_server.h"
AABB GPUParticles3D::get_aabb() const {
-
return AABB();
}
-Vector<Face3> GPUParticles3D::get_faces(uint32_t p_usage_flags) const {
+Vector<Face3> GPUParticles3D::get_faces(uint32_t p_usage_flags) const {
return Vector<Face3>();
}
void GPUParticles3D::set_emitting(bool p_emitting) {
-
RS::get_singleton()->particles_set_emitting(particles, p_emitting);
if (p_emitting && one_shot) {
@@ -56,157 +54,149 @@ void GPUParticles3D::set_emitting(bool p_emitting) {
}
void GPUParticles3D::set_amount(int p_amount) {
-
ERR_FAIL_COND_MSG(p_amount < 1, "Amount of particles cannot be smaller than 1.");
amount = p_amount;
RS::get_singleton()->particles_set_amount(particles, amount);
}
-void GPUParticles3D::set_lifetime(float p_lifetime) {
+void GPUParticles3D::set_lifetime(float p_lifetime) {
ERR_FAIL_COND_MSG(p_lifetime <= 0, "Particles lifetime must be greater than 0.");
lifetime = p_lifetime;
RS::get_singleton()->particles_set_lifetime(particles, lifetime);
}
void GPUParticles3D::set_one_shot(bool p_one_shot) {
-
one_shot = p_one_shot;
RS::get_singleton()->particles_set_one_shot(particles, one_shot);
if (is_emitting()) {
-
set_process_internal(true);
- if (!one_shot)
+ if (!one_shot) {
RenderingServer::get_singleton()->particles_restart(particles);
+ }
}
- if (!one_shot)
+ if (!one_shot) {
set_process_internal(false);
+ }
}
void GPUParticles3D::set_pre_process_time(float p_time) {
-
pre_process_time = p_time;
RS::get_singleton()->particles_set_pre_process_time(particles, pre_process_time);
}
-void GPUParticles3D::set_explosiveness_ratio(float p_ratio) {
+void GPUParticles3D::set_explosiveness_ratio(float p_ratio) {
explosiveness_ratio = p_ratio;
RS::get_singleton()->particles_set_explosiveness_ratio(particles, explosiveness_ratio);
}
-void GPUParticles3D::set_randomness_ratio(float p_ratio) {
+void GPUParticles3D::set_randomness_ratio(float p_ratio) {
randomness_ratio = p_ratio;
RS::get_singleton()->particles_set_randomness_ratio(particles, randomness_ratio);
}
-void GPUParticles3D::set_visibility_aabb(const AABB &p_aabb) {
+void GPUParticles3D::set_visibility_aabb(const AABB &p_aabb) {
visibility_aabb = p_aabb;
RS::get_singleton()->particles_set_custom_aabb(particles, visibility_aabb);
update_gizmo();
_change_notify("visibility_aabb");
}
-void GPUParticles3D::set_use_local_coordinates(bool p_enable) {
+void GPUParticles3D::set_use_local_coordinates(bool p_enable) {
local_coords = p_enable;
RS::get_singleton()->particles_set_use_local_coordinates(particles, local_coords);
}
-void GPUParticles3D::set_process_material(const Ref<Material> &p_material) {
+void GPUParticles3D::set_process_material(const Ref<Material> &p_material) {
process_material = p_material;
RID material_rid;
- if (process_material.is_valid())
+ if (process_material.is_valid()) {
material_rid = process_material->get_rid();
+ }
RS::get_singleton()->particles_set_process_material(particles, material_rid);
update_configuration_warning();
}
void GPUParticles3D::set_speed_scale(float p_scale) {
-
speed_scale = p_scale;
RS::get_singleton()->particles_set_speed_scale(particles, p_scale);
}
bool GPUParticles3D::is_emitting() const {
-
return RS::get_singleton()->particles_get_emitting(particles);
}
-int GPUParticles3D::get_amount() const {
+int GPUParticles3D::get_amount() const {
return amount;
}
-float GPUParticles3D::get_lifetime() const {
+float GPUParticles3D::get_lifetime() const {
return lifetime;
}
-bool GPUParticles3D::get_one_shot() const {
+bool GPUParticles3D::get_one_shot() const {
return one_shot;
}
float GPUParticles3D::get_pre_process_time() const {
-
return pre_process_time;
}
-float GPUParticles3D::get_explosiveness_ratio() const {
+float GPUParticles3D::get_explosiveness_ratio() const {
return explosiveness_ratio;
}
-float GPUParticles3D::get_randomness_ratio() const {
+float GPUParticles3D::get_randomness_ratio() const {
return randomness_ratio;
}
-AABB GPUParticles3D::get_visibility_aabb() const {
+AABB GPUParticles3D::get_visibility_aabb() const {
return visibility_aabb;
}
-bool GPUParticles3D::get_use_local_coordinates() const {
+bool GPUParticles3D::get_use_local_coordinates() const {
return local_coords;
}
-Ref<Material> GPUParticles3D::get_process_material() const {
+Ref<Material> GPUParticles3D::get_process_material() const {
return process_material;
}
float GPUParticles3D::get_speed_scale() const {
-
return speed_scale;
}
void GPUParticles3D::set_draw_order(DrawOrder p_order) {
-
draw_order = p_order;
RS::get_singleton()->particles_set_draw_order(particles, RS::ParticlesDrawOrder(p_order));
}
GPUParticles3D::DrawOrder GPUParticles3D::get_draw_order() const {
-
return draw_order;
}
void GPUParticles3D::set_draw_passes(int p_count) {
-
ERR_FAIL_COND(p_count < 1);
draw_passes.resize(p_count);
RS::get_singleton()->particles_set_draw_passes(particles, p_count);
_change_notify();
}
-int GPUParticles3D::get_draw_passes() const {
+int GPUParticles3D::get_draw_passes() const {
return draw_passes.size();
}
void GPUParticles3D::set_draw_pass_mesh(int p_pass, const Ref<Mesh> &p_mesh) {
-
ERR_FAIL_INDEX(p_pass, draw_passes.size());
draw_passes.write[p_pass] = p_mesh;
RID mesh_rid;
- if (p_mesh.is_valid())
+ if (p_mesh.is_valid()) {
mesh_rid = p_mesh->get_rid();
+ }
RS::get_singleton()->particles_set_draw_pass_mesh(particles, p_pass, mesh_rid);
@@ -214,7 +204,6 @@ void GPUParticles3D::set_draw_pass_mesh(int p_pass, const Ref<Mesh> &p_mesh) {
}
Ref<Mesh> GPUParticles3D::get_draw_pass_mesh(int p_pass) const {
-
ERR_FAIL_INDEX_V(p_pass, draw_passes.size(), Ref<Mesh>());
return draw_passes[p_pass];
@@ -239,7 +228,6 @@ bool GPUParticles3D::get_fractional_delta() const {
}
String GPUParticles3D::get_configuration_warning() const {
-
if (RenderingServer::get_singleton()->is_low_end()) {
return TTR("GPU-based particles are not supported by the GLES2 video driver.\nUse the CPUParticles3D node instead. You can use the \"Convert to CPUParticles3D\" option for this purpose.");
}
@@ -257,7 +245,9 @@ String GPUParticles3D::get_configuration_warning() const {
StandardMaterial3D *spat = Object::cast_to<StandardMaterial3D>(draw_passes[i]->surface_get_material(j).ptr());
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES);
}
- if (anim_material_found) break;
+ if (anim_material_found) {
+ break;
+ }
}
}
@@ -266,22 +256,25 @@ String GPUParticles3D::get_configuration_warning() const {
anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == StandardMaterial3D::BILLBOARD_PARTICLES);
if (!meshes_found) {
- if (warnings != String())
+ if (warnings != String()) {
warnings += "\n";
+ }
warnings += "- " + TTR("Nothing is visible because meshes have not been assigned to draw passes.");
}
if (process_material.is_null()) {
- if (warnings != String())
+ if (warnings != String()) {
warnings += "\n";
+ }
warnings += "- " + TTR("A material to process the particles is not assigned, so no behavior is imprinted.");
} else {
const ParticlesMaterial *process = Object::cast_to<ParticlesMaterial>(process_material.ptr());
if (!anim_material_found && process &&
(process->get_param(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 ||
process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) {
- if (warnings != String())
+ if (warnings != String()) {
warnings += "\n";
+ }
warnings += "- " + TTR("Particles animation requires the usage of a StandardMaterial3D whose Billboard Mode is set to \"Particle Billboard\".");
}
}
@@ -290,18 +283,15 @@ String GPUParticles3D::get_configuration_warning() const {
}
void GPUParticles3D::restart() {
-
RenderingServer::get_singleton()->particles_restart(particles);
RenderingServer::get_singleton()->particles_set_emitting(particles, true);
}
AABB GPUParticles3D::capture_aabb() const {
-
return RS::get_singleton()->particles_get_current_aabb(particles);
}
void GPUParticles3D::_validate_property(PropertyInfo &property) const {
-
if (property.name.begins_with("draw_pass_")) {
int index = property.name.get_slicec('_', 2).to_int() - 1;
if (index >= draw_passes.size()) {
@@ -312,12 +302,10 @@ void GPUParticles3D::_validate_property(PropertyInfo &property) const {
}
void GPUParticles3D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_PAUSED || p_what == NOTIFICATION_UNPAUSED) {
if (can_process()) {
RS::get_singleton()->particles_set_speed_scale(particles, speed_scale);
} else {
-
RS::get_singleton()->particles_set_speed_scale(particles, 0);
}
}
@@ -325,7 +313,6 @@ void GPUParticles3D::_notification(int p_what) {
// Use internal process when emitting and one_shot are on so that when
// the shot ends the editor can properly update
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
-
if (one_shot && !is_emitting()) {
_change_notify();
set_process_internal(false);
@@ -341,7 +328,6 @@ void GPUParticles3D::_notification(int p_what) {
}
void GPUParticles3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_emitting", "emitting"), &GPUParticles3D::set_emitting);
ClassDB::bind_method(D_METHOD("set_amount", "amount"), &GPUParticles3D::set_amount);
ClassDB::bind_method(D_METHOD("set_lifetime", "secs"), &GPUParticles3D::set_lifetime);
@@ -403,7 +389,6 @@ void GPUParticles3D::_bind_methods() {
ADD_GROUP("Draw Passes", "draw_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "draw_passes", PROPERTY_HINT_RANGE, "0," + itos(MAX_DRAW_PASSES) + ",1"), "set_draw_passes", "get_draw_passes");
for (int i = 0; i < MAX_DRAW_PASSES; i++) {
-
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "draw_pass_" + itos(i + 1), PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_draw_pass_mesh", "get_draw_pass_mesh", i);
}
@@ -415,7 +400,6 @@ void GPUParticles3D::_bind_methods() {
}
GPUParticles3D::GPUParticles3D() {
-
particles = RS::get_singleton()->particles_create();
set_base(particles);
one_shot = false; // Needed so that set_emitting doesn't access uninitialized values
@@ -436,6 +420,5 @@ GPUParticles3D::GPUParticles3D() {
}
GPUParticles3D::~GPUParticles3D() {
-
RS::get_singleton()->free(particles);
}
diff --git a/scene/3d/immediate_geometry_3d.cpp b/scene/3d/immediate_geometry_3d.cpp
index 63d4b1ac84..7ccfd527a1 100644
--- a/scene/3d/immediate_geometry_3d.cpp
+++ b/scene/3d/immediate_geometry_3d.cpp
@@ -31,39 +31,33 @@
#include "immediate_geometry_3d.h"
void ImmediateGeometry3D::begin(Mesh::PrimitiveType p_primitive, const Ref<Texture2D> &p_texture) {
-
RS::get_singleton()->immediate_begin(im, (RS::PrimitiveType)p_primitive, p_texture.is_valid() ? p_texture->get_rid() : RID());
- if (p_texture.is_valid())
+ if (p_texture.is_valid()) {
cached_textures.push_back(p_texture);
+ }
}
void ImmediateGeometry3D::set_normal(const Vector3 &p_normal) {
-
RS::get_singleton()->immediate_normal(im, p_normal);
}
void ImmediateGeometry3D::set_tangent(const Plane &p_tangent) {
-
RS::get_singleton()->immediate_tangent(im, p_tangent);
}
void ImmediateGeometry3D::set_color(const Color &p_color) {
-
RS::get_singleton()->immediate_color(im, p_color);
}
void ImmediateGeometry3D::set_uv(const Vector2 &p_uv) {
-
RS::get_singleton()->immediate_uv(im, p_uv);
}
void ImmediateGeometry3D::set_uv2(const Vector2 &p_uv2) {
-
RS::get_singleton()->immediate_uv2(im, p_uv2);
}
void ImmediateGeometry3D::add_vertex(const Vector3 &p_vertex) {
-
RS::get_singleton()->immediate_vertex(im, p_vertex);
if (empty) {
aabb.position = p_vertex;
@@ -75,28 +69,24 @@ void ImmediateGeometry3D::add_vertex(const Vector3 &p_vertex) {
}
void ImmediateGeometry3D::end() {
-
RS::get_singleton()->immediate_end(im);
}
void ImmediateGeometry3D::clear() {
-
RS::get_singleton()->immediate_clear(im);
empty = true;
cached_textures.clear();
}
AABB ImmediateGeometry3D::get_aabb() const {
-
return aabb;
}
-Vector<Face3> ImmediateGeometry3D::get_faces(uint32_t p_usage_flags) const {
+Vector<Face3> ImmediateGeometry3D::get_faces(uint32_t p_usage_flags) const {
return Vector<Face3>();
}
void ImmediateGeometry3D::add_sphere(int p_lats, int p_lons, float p_radius, bool p_add_uv) {
-
for (int i = 1; i <= p_lats; i++) {
double lat0 = Math_PI * (-0.5 + (double)(i - 1) / p_lats);
double z0 = Math::sin(lat0);
@@ -107,7 +97,6 @@ void ImmediateGeometry3D::add_sphere(int p_lats, int p_lons, float p_radius, boo
double zr1 = Math::cos(lat1);
for (int j = p_lons; j >= 1; j--) {
-
double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons;
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
@@ -143,7 +132,6 @@ void ImmediateGeometry3D::add_sphere(int p_lats, int p_lons, float p_radius, boo
}
void ImmediateGeometry3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("begin", "primitive", "texture"), &ImmediateGeometry3D::begin, DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("set_normal", "normal"), &ImmediateGeometry3D::set_normal);
ClassDB::bind_method(D_METHOD("set_tangent", "tangent"), &ImmediateGeometry3D::set_tangent);
@@ -157,13 +145,11 @@ void ImmediateGeometry3D::_bind_methods() {
}
ImmediateGeometry3D::ImmediateGeometry3D() {
-
im = RenderingServer::get_singleton()->immediate_create();
set_base(im);
empty = true;
}
ImmediateGeometry3D::~ImmediateGeometry3D() {
-
RenderingServer::get_singleton()->free(im);
}
diff --git a/scene/3d/immediate_geometry_3d.h b/scene/3d/immediate_geometry_3d.h
index 6e15450a5b..7c9e8851a2 100644
--- a/scene/3d/immediate_geometry_3d.h
+++ b/scene/3d/immediate_geometry_3d.h
@@ -35,7 +35,6 @@
#include "scene/resources/mesh.h"
class ImmediateGeometry3D : public GeometryInstance3D {
-
GDCLASS(ImmediateGeometry3D, GeometryInstance3D);
RID im;
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index 9928246d2b..814e911372 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -35,12 +35,10 @@
#include "scene/resources/surface_tool.h"
bool Light3D::_can_gizmo_scale() const {
-
return false;
}
void Light3D::set_param(Param p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
param[p_param] = p_value;
@@ -60,13 +58,11 @@ void Light3D::set_param(Param p_param, float p_value) {
}
float Light3D::get_param(Param p_param) const {
-
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return param[p_param];
}
void Light3D::set_shadow(bool p_enable) {
-
shadow = p_enable;
RS::get_singleton()->light_set_shadow(light, p_enable);
@@ -74,51 +70,46 @@ void Light3D::set_shadow(bool p_enable) {
update_configuration_warning();
}
}
-bool Light3D::has_shadow() const {
+bool Light3D::has_shadow() const {
return shadow;
}
void Light3D::set_negative(bool p_enable) {
-
negative = p_enable;
RS::get_singleton()->light_set_negative(light, p_enable);
}
-bool Light3D::is_negative() const {
+bool Light3D::is_negative() const {
return negative;
}
void Light3D::set_cull_mask(uint32_t p_cull_mask) {
-
cull_mask = p_cull_mask;
RS::get_singleton()->light_set_cull_mask(light, p_cull_mask);
}
-uint32_t Light3D::get_cull_mask() const {
+uint32_t Light3D::get_cull_mask() const {
return cull_mask;
}
void Light3D::set_color(const Color &p_color) {
-
color = p_color;
RS::get_singleton()->light_set_color(light, p_color);
// The gizmo color depends on the light color, so update it.
update_gizmo();
}
-Color Light3D::get_color() const {
+Color Light3D::get_color() const {
return color;
}
void Light3D::set_shadow_color(const Color &p_shadow_color) {
-
shadow_color = p_shadow_color;
RS::get_singleton()->light_set_shadow_color(light, p_shadow_color);
}
Color Light3D::get_shadow_color() const {
-
return shadow_color;
}
@@ -128,22 +119,17 @@ void Light3D::set_shadow_reverse_cull_face(bool p_enable) {
}
bool Light3D::get_shadow_reverse_cull_face() const {
-
return reverse_cull;
}
AABB Light3D::get_aabb() const {
-
if (type == RenderingServer::LIGHT_DIRECTIONAL) {
-
return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
} else if (type == RenderingServer::LIGHT_OMNI) {
-
return AABB(Vector3(-1, -1, -1) * param[PARAM_RANGE], Vector3(2, 2, 2) * param[PARAM_RANGE]);
} else if (type == RenderingServer::LIGHT_SPOT) {
-
float len = param[PARAM_RANGE];
float size = Math::tan(Math::deg2rad(param[PARAM_SPOT_ANGLE])) * len;
return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
@@ -153,7 +139,6 @@ AABB Light3D::get_aabb() const {
}
Vector<Face3> Light3D::get_faces(uint32_t p_usage_flags) const {
-
return Vector<Face3>();
}
@@ -167,7 +152,6 @@ Light3D::BakeMode Light3D::get_bake_mode() const {
}
void Light3D::set_projector(const Ref<Texture2D> &p_texture) {
-
projector = p_texture;
RID tex_id = projector.is_valid() ? projector->get_rid() : RID();
RS::get_singleton()->light_set_projector(light, tex_id);
@@ -179,9 +163,9 @@ Ref<Texture2D> Light3D::get_projector() const {
}
void Light3D::_update_visibility() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
bool editor_ok = true;
@@ -205,9 +189,7 @@ void Light3D::_update_visibility() {
}
void Light3D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
_update_visibility();
}
@@ -217,18 +199,15 @@ void Light3D::_notification(int p_what) {
}
void Light3D::set_editor_only(bool p_editor_only) {
-
editor_only = p_editor_only;
_update_visibility();
}
bool Light3D::is_editor_only() const {
-
return editor_only;
}
void Light3D::_validate_property(PropertyInfo &property) const {
-
if (get_light_type() == RS::LIGHT_DIRECTIONAL && property.name == "light_size") {
property.usage = 0;
}
@@ -243,7 +222,6 @@ void Light3D::_validate_property(PropertyInfo &property) const {
}
void Light3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_editor_only", "editor_only"), &Light3D::set_editor_only);
ClassDB::bind_method(D_METHOD("is_editor_only"), &Light3D::is_editor_only);
@@ -301,6 +279,7 @@ void Light3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_INDIRECT_ENERGY);
BIND_ENUM_CONSTANT(PARAM_SPECULAR);
BIND_ENUM_CONSTANT(PARAM_RANGE);
+ BIND_ENUM_CONSTANT(PARAM_SIZE);
BIND_ENUM_CONSTANT(PARAM_ATTENUATION);
BIND_ENUM_CONSTANT(PARAM_SPOT_ANGLE);
BIND_ENUM_CONSTANT(PARAM_SPOT_ATTENUATION);
@@ -322,12 +301,17 @@ void Light3D::_bind_methods() {
}
Light3D::Light3D(RenderingServer::LightType p_type) {
-
type = p_type;
switch (p_type) {
- case RS::LIGHT_DIRECTIONAL: light = RenderingServer::get_singleton()->directional_light_create(); break;
- case RS::LIGHT_OMNI: light = RenderingServer::get_singleton()->omni_light_create(); break;
- case RS::LIGHT_SPOT: light = RenderingServer::get_singleton()->spot_light_create(); break;
+ case RS::LIGHT_DIRECTIONAL:
+ light = RenderingServer::get_singleton()->directional_light_create();
+ break;
+ case RS::LIGHT_OMNI:
+ light = RenderingServer::get_singleton()->omni_light_create();
+ break;
+ case RS::LIGHT_SPOT:
+ light = RenderingServer::get_singleton()->spot_light_create();
+ break;
default: {
};
}
@@ -366,28 +350,26 @@ Light3D::Light3D(RenderingServer::LightType p_type) {
}
Light3D::Light3D() {
-
type = RenderingServer::LIGHT_DIRECTIONAL;
ERR_PRINT("Light3D should not be instanced directly; use the DirectionalLight3D, OmniLight3D or SpotLight3D subtypes instead.");
}
Light3D::~Light3D() {
-
RS::get_singleton()->instance_set_base(get_instance(), RID());
- if (light.is_valid())
+ if (light.is_valid()) {
RenderingServer::get_singleton()->free(light);
+ }
}
+
/////////////////////////////////////////
void DirectionalLight3D::set_shadow_mode(ShadowMode p_mode) {
-
shadow_mode = p_mode;
RS::get_singleton()->light_directional_set_shadow_mode(light, RS::LightDirectionalShadowMode(p_mode));
}
DirectionalLight3D::ShadowMode DirectionalLight3D::get_shadow_mode() const {
-
return shadow_mode;
}
@@ -397,23 +379,19 @@ void DirectionalLight3D::set_shadow_depth_range(ShadowDepthRange p_range) {
}
DirectionalLight3D::ShadowDepthRange DirectionalLight3D::get_shadow_depth_range() const {
-
return shadow_depth_range;
}
void DirectionalLight3D::set_blend_splits(bool p_enable) {
-
blend_splits = p_enable;
RS::get_singleton()->light_directional_set_blend_splits(light, p_enable);
}
bool DirectionalLight3D::is_blend_splits_enabled() const {
-
return blend_splits;
}
void DirectionalLight3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &DirectionalLight3D::set_shadow_mode);
ClassDB::bind_method(D_METHOD("get_shadow_mode"), &DirectionalLight3D::get_shadow_mode);
@@ -444,7 +422,6 @@ void DirectionalLight3D::_bind_methods() {
DirectionalLight3D::DirectionalLight3D() :
Light3D(RenderingServer::LIGHT_DIRECTIONAL) {
-
set_param(PARAM_SHADOW_MAX_DISTANCE, 100);
set_param(PARAM_SHADOW_FADE_START, 0.8);
set_shadow_mode(SHADOW_PARALLEL_4_SPLITS);
@@ -454,13 +431,11 @@ DirectionalLight3D::DirectionalLight3D() :
}
void OmniLight3D::set_shadow_mode(ShadowMode p_mode) {
-
shadow_mode = p_mode;
RS::get_singleton()->light_omni_set_shadow_mode(light, RS::LightOmniShadowMode(p_mode));
}
OmniLight3D::ShadowMode OmniLight3D::get_shadow_mode() const {
-
return shadow_mode;
}
@@ -478,7 +453,6 @@ String OmniLight3D::get_configuration_warning() const {
}
void OmniLight3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_shadow_mode", "mode"), &OmniLight3D::set_shadow_mode);
ClassDB::bind_method(D_METHOD("get_shadow_mode"), &OmniLight3D::get_shadow_mode);
@@ -493,7 +467,6 @@ void OmniLight3D::_bind_methods() {
OmniLight3D::OmniLight3D() :
Light3D(RenderingServer::LIGHT_OMNI) {
-
set_shadow_mode(SHADOW_CUBE);
}
@@ -519,7 +492,6 @@ String SpotLight3D::get_configuration_warning() const {
}
void SpotLight3D::_bind_methods() {
-
ADD_GROUP("Spot", "spot_");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_range", PROPERTY_HINT_EXP_RANGE, "0,4096,0.1,or_greater"), "set_param", "get_param", PARAM_RANGE);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_ATTENUATION);
diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h
index 6e78217342..f16773f6ae 100644
--- a/scene/3d/light_3d.h
+++ b/scene/3d/light_3d.h
@@ -36,7 +36,6 @@
#include "servers/rendering_server.h"
class Light3D : public VisualInstance3D {
-
GDCLASS(Light3D, VisualInstance3D);
OBJ_CATEGORY("3D Light Nodes");
@@ -140,7 +139,6 @@ VARIANT_ENUM_CAST(Light3D::Param);
VARIANT_ENUM_CAST(Light3D::BakeMode);
class DirectionalLight3D : public Light3D {
-
GDCLASS(DirectionalLight3D, Light3D);
public:
@@ -180,7 +178,6 @@ VARIANT_ENUM_CAST(DirectionalLight3D::ShadowMode)
VARIANT_ENUM_CAST(DirectionalLight3D::ShadowDepthRange)
class OmniLight3D : public Light3D {
-
GDCLASS(OmniLight3D, Light3D);
public:
@@ -208,7 +205,6 @@ public:
VARIANT_ENUM_CAST(OmniLight3D::ShadowMode)
class SpotLight3D : public Light3D {
-
GDCLASS(SpotLight3D, Light3D);
protected:
diff --git a/core/math/disjoint_set.cpp b/scene/3d/lightmap_probe.cpp
index a508151ad3..ee21934b80 100644
--- a/core/math/disjoint_set.cpp
+++ b/scene/3d/lightmap_probe.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* disjoint_set.cpp */
+/* lightmap_probe.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,4 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "disjoint_set.h"
+#include "lightmap_probe.h"
+
+LightmapProbe::LightmapProbe() {
+}
diff --git a/scene/3d/lightmap_probe.h b/scene/3d/lightmap_probe.h
new file mode 100644
index 0000000000..c4bd33556f
--- /dev/null
+++ b/scene/3d/lightmap_probe.h
@@ -0,0 +1,42 @@
+/*************************************************************************/
+/* lightmap_probe.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef LIGHTMAP_PROBE_H
+#define LIGHTMAP_PROBE_H
+
+#include "scene/3d/node_3d.h"
+
+class LightmapProbe : public Node3D {
+ GDCLASS(LightmapProbe, Node3D)
+public:
+ LightmapProbe();
+};
+
+#endif // LIGHTMAP_PROBE_H
diff --git a/scene/3d/lightmapper.cpp b/scene/3d/lightmapper.cpp
new file mode 100644
index 0000000000..26faf5154c
--- /dev/null
+++ b/scene/3d/lightmapper.cpp
@@ -0,0 +1,67 @@
+/*************************************************************************/
+/* lightmapper.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "lightmapper.h"
+
+LightmapDenoiser *(*LightmapDenoiser::create_function)() = nullptr;
+
+Ref<LightmapDenoiser> LightmapDenoiser::create() {
+ if (create_function) {
+ return Ref<LightmapDenoiser>(create_function());
+ }
+ return Ref<LightmapDenoiser>();
+}
+
+Lightmapper::CreateFunc Lightmapper::create_custom = nullptr;
+Lightmapper::CreateFunc Lightmapper::create_gpu = nullptr;
+Lightmapper::CreateFunc Lightmapper::create_cpu = nullptr;
+
+Ref<Lightmapper> Lightmapper::create() {
+ Lightmapper *lm = nullptr;
+ if (create_custom) {
+ lm = create_custom();
+ }
+
+ if (!lm && create_gpu) {
+ lm = create_gpu();
+ }
+
+ if (!lm && create_cpu) {
+ lm = create_cpu();
+ }
+ if (!lm) {
+ return Ref<Lightmapper>();
+ } else {
+ return Ref<Lightmapper>(lm);
+ }
+}
+
+Lightmapper::Lightmapper() {
+}
diff --git a/scene/3d/lightmapper.h b/scene/3d/lightmapper.h
new file mode 100644
index 0000000000..ccf9bde279
--- /dev/null
+++ b/scene/3d/lightmapper.h
@@ -0,0 +1,120 @@
+/*************************************************************************/
+/* lightmapper.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef LIGHTMAPPER_H
+#define LIGHTMAPPER_H
+
+#include "scene/resources/mesh.h"
+#include "servers/rendering/rendering_device.h"
+
+class LightmapDenoiser : public Reference {
+ GDCLASS(LightmapDenoiser, Reference)
+protected:
+ static LightmapDenoiser *(*create_function)();
+
+public:
+ virtual Ref<Image> denoise_image(const Ref<Image> &p_image) = 0;
+ static Ref<LightmapDenoiser> create();
+};
+
+class Lightmapper : public Reference {
+ GDCLASS(Lightmapper, Reference)
+public:
+ enum GenerateProbes {
+ GENERATE_PROBES_DISABLED,
+ GENERATE_PROBES_SUBDIV_4,
+ GENERATE_PROBES_SUBDIV_8,
+ GENERATE_PROBES_SUBDIV_16,
+ GENERATE_PROBES_SUBDIV_32,
+
+ };
+
+ enum LightType {
+ LIGHT_TYPE_DIRECTIONAL,
+ LIGHT_TYPE_OMNI,
+ LIGHT_TYPE_SPOT
+ };
+
+ enum BakeError {
+ BAKE_ERROR_LIGHTMAP_TOO_SMALL,
+ BAKE_ERROR_LIGHTMAP_CANT_PRE_BAKE_MESHES,
+ BAKE_OK
+ };
+
+ enum BakeQuality {
+ BAKE_QUALITY_LOW,
+ BAKE_QUALITY_MEDIUM,
+ BAKE_QUALITY_HIGH,
+ BAKE_QUALITY_ULTRA,
+ };
+
+ typedef Lightmapper *(*CreateFunc)();
+
+ static CreateFunc create_custom;
+ static CreateFunc create_gpu;
+ static CreateFunc create_cpu;
+
+protected:
+public:
+ typedef bool (*BakeStepFunc)(float, const String &, void *, bool); //step index, step total, step description, userdata
+
+ struct MeshData {
+ //triangle data
+ Vector<Vector3> points;
+ Vector<Vector2> uv2;
+ Vector<Vector3> normal;
+ Ref<Image> albedo_on_uv2;
+ Ref<Image> emission_on_uv2;
+ Variant userdata;
+ };
+
+ virtual void add_mesh(const MeshData &p_mesh) = 0;
+ virtual void add_directional_light(bool p_static, const Vector3 &p_direction, const Color &p_color, float p_energy, float p_angular_distance) = 0;
+ virtual void add_omni_light(bool p_static, const Vector3 &p_position, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_size) = 0;
+ virtual void add_spot_light(bool p_static, const Vector3 &p_position, const Vector3 p_direction, const Color &p_color, float p_energy, float p_range, float p_attenuation, float p_spot_angle, float p_spot_attenuation, float p_size) = 0;
+ virtual void add_probe(const Vector3 &p_position) = 0;
+ virtual BakeError bake(BakeQuality p_quality, bool p_use_denoiser, int p_bounces, float p_bias, int p_max_texture_size, bool p_bake_sh, GenerateProbes p_generate_probes, const Ref<Image> &p_environment_panorama, const Basis &p_environment_transform, BakeStepFunc p_step_function = nullptr, void *p_step_userdata = nullptr) = 0;
+
+ virtual int get_bake_texture_count() const = 0;
+ virtual Ref<Image> get_bake_texture(int p_index) const = 0;
+ virtual int get_bake_mesh_count() const = 0;
+ virtual Variant get_bake_mesh_userdata(int p_index) const = 0;
+ virtual Rect2 get_bake_mesh_uv_scale(int p_index) const = 0;
+ virtual int get_bake_mesh_texture_slice(int p_index) const = 0;
+ virtual int get_bake_probe_count() const = 0;
+ virtual Vector3 get_bake_probe_point(int p_probe) const = 0;
+ virtual Vector<Color> get_bake_probe_sh(int p_probe) const = 0;
+
+ static Ref<Lightmapper> create();
+
+ Lightmapper();
+};
+
+#endif // LIGHTMAPPER_H
diff --git a/scene/3d/listener_3d.cpp b/scene/3d/listener_3d.cpp
index 426e34ea80..0a5b9ad09f 100644
--- a/scene/3d/listener_3d.cpp
+++ b/scene/3d/listener_3d.cpp
@@ -36,63 +36,59 @@ void Listener3D::_update_audio_listener_state() {
}
void Listener3D::_request_listener_update() {
-
_update_listener();
}
bool Listener3D::_set(const StringName &p_name, const Variant &p_value) {
-
if (p_name == "current") {
if (p_value.operator bool()) {
make_current();
} else {
clear_current();
}
- } else
+ } else {
return false;
+ }
return true;
}
-bool Listener3D::_get(const StringName &p_name, Variant &r_ret) const {
+bool Listener3D::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name == "current") {
if (is_inside_tree() && get_tree()->is_node_being_edited(this)) {
r_ret = current;
} else {
r_ret = is_current();
}
- } else
+ } else {
return false;
+ }
return true;
}
void Listener3D::_get_property_list(List<PropertyInfo> *p_list) const {
-
p_list->push_back(PropertyInfo(Variant::BOOL, "current"));
}
void Listener3D::_update_listener() {
-
if (is_inside_tree() && is_current()) {
get_viewport()->_listener_transform_changed_notify();
}
}
void Listener3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_WORLD: {
bool first_listener = get_viewport()->_listener_add(this);
- if (!get_tree()->is_node_being_edited(this) && (current || first_listener))
+ if (!get_tree()->is_node_being_edited(this) && (current || first_listener)) {
make_current();
+ }
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
_request_listener_update();
} break;
case NOTIFICATION_EXIT_WORLD: {
-
if (!get_tree()->is_node_being_edited(this)) {
if (is_current()) {
clear_current();
@@ -110,25 +106,24 @@ void Listener3D::_notification(int p_what) {
}
Transform Listener3D::get_listener_transform() const {
-
return get_global_transform().orthonormalized();
}
void Listener3D::make_current() {
-
current = true;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
get_viewport()->_listener_set(this);
}
void Listener3D::clear_current() {
-
current = false;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
if (get_viewport()->get_listener() == this) {
get_viewport()->_listener_set(nullptr);
@@ -137,18 +132,16 @@ void Listener3D::clear_current() {
}
bool Listener3D::is_current() const {
-
if (is_inside_tree() && !get_tree()->is_node_being_edited(this)) {
-
return get_viewport()->get_listener() == this;
- } else
+ } else {
return current;
+ }
return false;
}
bool Listener3D::_can_gizmo_scale() const {
-
return false;
}
@@ -159,7 +152,6 @@ RES Listener3D::_get_gizmo_geometry() const {
}
void Listener3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("make_current"), &Listener3D::make_current);
ClassDB::bind_method(D_METHOD("clear_current"), &Listener3D::clear_current);
ClassDB::bind_method(D_METHOD("is_current"), &Listener3D::is_current);
@@ -167,7 +159,6 @@ void Listener3D::_bind_methods() {
}
Listener3D::Listener3D() {
-
current = false;
force_change = false;
set_notify_transform(true);
diff --git a/scene/3d/listener_3d.h b/scene/3d/listener_3d.h
index 3383d6725e..4b6923d6e8 100644
--- a/scene/3d/listener_3d.h
+++ b/scene/3d/listener_3d.h
@@ -35,7 +35,6 @@
#include "scene/main/window.h"
class Listener3D : public Node3D {
-
GDCLASS(Listener3D, Node3D);
private:
diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp
index d56a095a5b..13f40aed4f 100644
--- a/scene/3d/mesh_instance_3d.cpp
+++ b/scene/3d/mesh_instance_3d.cpp
@@ -37,12 +37,12 @@
#include "skeleton_3d.h"
bool MeshInstance3D::_set(const StringName &p_name, const Variant &p_value) {
-
//this is not _too_ bad performance wise, really. it only arrives here if the property was not set anywhere else.
//add to it that it's probably found on first call to _set anyway.
- if (!get_instance().is_valid())
+ if (!get_instance().is_valid()) {
return false;
+ }
Map<StringName, BlendShapeTrack>::Element *E = blend_shape_tracks.find(p_name);
if (E) {
@@ -53,8 +53,9 @@ bool MeshInstance3D::_set(const StringName &p_name, const Variant &p_value) {
if (p_name.operator String().begins_with("material/")) {
int idx = p_name.operator String().get_slicec('/', 1).to_int();
- if (idx >= materials.size() || idx < 0)
+ if (idx >= materials.size() || idx < 0) {
return false;
+ }
set_surface_material(idx, p_value);
return true;
@@ -64,9 +65,9 @@ bool MeshInstance3D::_set(const StringName &p_name, const Variant &p_value) {
}
bool MeshInstance3D::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (!get_instance().is_valid())
+ if (!get_instance().is_valid()) {
return false;
+ }
const Map<StringName, BlendShapeTrack>::Element *E = blend_shape_tracks.find(p_name);
if (E) {
@@ -76,8 +77,9 @@ bool MeshInstance3D::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name.operator String().begins_with("material/")) {
int idx = p_name.operator String().get_slicec('/', 1).to_int();
- if (idx >= materials.size() || idx < 0)
+ if (idx >= materials.size() || idx < 0) {
return false;
+ }
r_ret = materials[idx];
return true;
}
@@ -85,10 +87,8 @@ bool MeshInstance3D::_get(const StringName &p_name, Variant &r_ret) const {
}
void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const {
-
List<String> ls;
for (const Map<StringName, BlendShapeTrack>::Element *E = blend_shape_tracks.front(); E; E = E->next()) {
-
ls.push_back(E->key());
}
@@ -106,9 +106,9 @@ void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const {
}
void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) {
-
- if (mesh == p_mesh)
+ if (mesh == p_mesh) {
return;
+ }
if (mesh.is_valid()) {
mesh->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &MeshInstance3D::_mesh_changed));
@@ -119,9 +119,7 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) {
blend_shape_tracks.clear();
if (mesh.is_valid()) {
-
for (int i = 0; i < mesh->get_blend_shape_count(); i++) {
-
BlendShapeTrack mt;
mt.idx = i;
mt.value = 0;
@@ -133,7 +131,6 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) {
set_base(mesh->get_rid());
} else {
-
set_base(RID());
}
@@ -141,13 +138,12 @@ void MeshInstance3D::set_mesh(const Ref<Mesh> &p_mesh) {
_change_notify();
}
-Ref<Mesh> MeshInstance3D::get_mesh() const {
+Ref<Mesh> MeshInstance3D::get_mesh() const {
return mesh;
}
void MeshInstance3D::_resolve_skeleton_path() {
-
Ref<SkinReference> new_skin_reference;
if (!skeleton_path.is_empty()) {
@@ -174,8 +170,9 @@ void MeshInstance3D::_resolve_skeleton_path() {
void MeshInstance3D::set_skin(const Ref<Skin> &p_skin) {
skin_internal = p_skin;
skin = p_skin;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_resolve_skeleton_path();
}
@@ -184,10 +181,10 @@ Ref<Skin> MeshInstance3D::get_skin() const {
}
void MeshInstance3D::set_skeleton_path(const NodePath &p_skeleton) {
-
skeleton_path = p_skeleton;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_resolve_skeleton_path();
}
@@ -196,32 +193,34 @@ NodePath MeshInstance3D::get_skeleton_path() {
}
AABB MeshInstance3D::get_aabb() const {
-
- if (!mesh.is_null())
+ if (!mesh.is_null()) {
return mesh->get_aabb();
+ }
return AABB();
}
Vector<Face3> MeshInstance3D::get_faces(uint32_t p_usage_flags) const {
-
- if (!(p_usage_flags & (FACES_SOLID | FACES_ENCLOSING)))
+ if (!(p_usage_flags & (FACES_SOLID | FACES_ENCLOSING))) {
return Vector<Face3>();
+ }
- if (mesh.is_null())
+ if (mesh.is_null()) {
return Vector<Face3>();
+ }
return mesh->get_faces();
}
Node *MeshInstance3D::create_trimesh_collision_node() {
-
- if (mesh.is_null())
+ if (mesh.is_null()) {
return nullptr;
+ }
Ref<Shape3D> shape = mesh->create_trimesh_shape();
- if (shape.is_null())
+ if (shape.is_null()) {
return nullptr;
+ }
StaticBody3D *static_body = memnew(StaticBody3D);
CollisionShape3D *cshape = memnew(CollisionShape3D);
@@ -231,7 +230,6 @@ Node *MeshInstance3D::create_trimesh_collision_node() {
}
void MeshInstance3D::create_trimesh_collision() {
-
StaticBody3D *static_body = Object::cast_to<StaticBody3D>(create_trimesh_collision_node());
ERR_FAIL_COND(!static_body);
static_body->set_name(String(get_name()) + "_col");
@@ -245,13 +243,14 @@ void MeshInstance3D::create_trimesh_collision() {
}
Node *MeshInstance3D::create_convex_collision_node() {
-
- if (mesh.is_null())
+ if (mesh.is_null()) {
return nullptr;
+ }
Ref<Shape3D> shape = mesh->create_convex_shape();
- if (shape.is_null())
+ if (shape.is_null()) {
return nullptr;
+ }
StaticBody3D *static_body = memnew(StaticBody3D);
CollisionShape3D *cshape = memnew(CollisionShape3D);
@@ -261,7 +260,6 @@ Node *MeshInstance3D::create_convex_collision_node() {
}
void MeshInstance3D::create_convex_collision() {
-
StaticBody3D *static_body = Object::cast_to<StaticBody3D>(create_convex_collision_node());
ERR_FAIL_COND(!static_body);
static_body->set_name(String(get_name()) + "_col");
@@ -275,76 +273,76 @@ void MeshInstance3D::create_convex_collision() {
}
void MeshInstance3D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
_resolve_skeleton_path();
}
}
int MeshInstance3D::get_surface_material_count() const {
-
return materials.size();
}
void MeshInstance3D::set_surface_material(int p_surface, const Ref<Material> &p_material) {
-
ERR_FAIL_INDEX(p_surface, materials.size());
materials.write[p_surface] = p_material;
- if (materials[p_surface].is_valid())
+ if (materials[p_surface].is_valid()) {
RS::get_singleton()->instance_set_surface_material(get_instance(), p_surface, materials[p_surface]->get_rid());
- else
+ } else {
RS::get_singleton()->instance_set_surface_material(get_instance(), p_surface, RID());
+ }
}
Ref<Material> MeshInstance3D::get_surface_material(int p_surface) const {
-
ERR_FAIL_INDEX_V(p_surface, materials.size(), Ref<Material>());
return materials[p_surface];
}
Ref<Material> MeshInstance3D::get_active_material(int p_surface) const {
+ Ref<Material> material_override = get_material_override();
+ if (material_override.is_valid()) {
+ return material_override;
+ }
- if (get_material_override() != Ref<Material>()) {
- return get_material_override();
- } else if (p_surface < materials.size()) {
- return materials[p_surface];
- } else {
- Ref<Mesh> mesh = get_mesh();
-
- if (mesh.is_null() || p_surface >= mesh->get_surface_count()) {
- return Ref<Material>();
- }
+ Ref<Material> surface_material = get_surface_material(p_surface);
+ if (surface_material.is_valid()) {
+ return surface_material;
+ }
+ Ref<Mesh> mesh = get_mesh();
+ if (mesh.is_valid()) {
return mesh->surface_get_material(p_surface);
}
+
+ return Ref<Material>();
}
void MeshInstance3D::_mesh_changed() {
-
materials.resize(mesh->get_surface_count());
}
void MeshInstance3D::create_debug_tangents() {
-
Vector<Vector3> lines;
Vector<Color> colors;
Ref<Mesh> mesh = get_mesh();
- if (!mesh.is_valid())
+ if (!mesh.is_valid()) {
return;
+ }
for (int i = 0; i < mesh->get_surface_count(); i++) {
Array arrays = mesh->surface_get_arrays(i);
Vector<Vector3> verts = arrays[Mesh::ARRAY_VERTEX];
Vector<Vector3> norms = arrays[Mesh::ARRAY_NORMAL];
- if (norms.size() == 0)
+ if (norms.size() == 0) {
continue;
+ }
Vector<float> tangents = arrays[Mesh::ARRAY_TANGENT];
- if (tangents.size() == 0)
+ if (tangents.size() == 0) {
continue;
+ }
for (int j = 0; j < verts.size(); j++) {
Vector3 v = verts[j];
@@ -370,7 +368,6 @@ void MeshInstance3D::create_debug_tangents() {
}
if (lines.size()) {
-
Ref<StandardMaterial3D> sm;
sm.instance();
@@ -394,16 +391,16 @@ void MeshInstance3D::create_debug_tangents() {
add_child(mi);
#ifdef TOOLS_ENABLED
- if (this == get_tree()->get_edited_scene_root())
+ if (this == get_tree()->get_edited_scene_root()) {
mi->set_owner(this);
- else
+ } else {
mi->set_owner(get_owner());
+ }
#endif
}
}
void MeshInstance3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MeshInstance3D::set_mesh);
ClassDB::bind_method(D_METHOD("get_mesh"), &MeshInstance3D::get_mesh);
ClassDB::bind_method(D_METHOD("set_skeleton_path", "skeleton_path"), &MeshInstance3D::set_skeleton_path);
diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h
index 914148f427..e29204f702 100644
--- a/scene/3d/mesh_instance_3d.h
+++ b/scene/3d/mesh_instance_3d.h
@@ -37,7 +37,6 @@
#include "scene/resources/skin.h"
class MeshInstance3D : public GeometryInstance3D {
-
GDCLASS(MeshInstance3D, GeometryInstance3D);
protected:
@@ -48,7 +47,6 @@ protected:
NodePath skeleton_path;
struct BlendShapeTrack {
-
int idx;
float value;
BlendShapeTrack() {
diff --git a/scene/3d/multimesh_instance_3d.cpp b/scene/3d/multimesh_instance_3d.cpp
index a625a34283..88dff111f7 100644
--- a/scene/3d/multimesh_instance_3d.cpp
+++ b/scene/3d/multimesh_instance_3d.cpp
@@ -31,37 +31,34 @@
#include "multimesh_instance_3d.h"
void MultiMeshInstance3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_multimesh", "multimesh"), &MultiMeshInstance3D::set_multimesh);
ClassDB::bind_method(D_METHOD("get_multimesh"), &MultiMeshInstance3D::get_multimesh);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "multimesh", PROPERTY_HINT_RESOURCE_TYPE, "MultiMesh"), "set_multimesh", "get_multimesh");
}
void MultiMeshInstance3D::set_multimesh(const Ref<MultiMesh> &p_multimesh) {
-
multimesh = p_multimesh;
- if (multimesh.is_valid())
+ if (multimesh.is_valid()) {
set_base(multimesh->get_rid());
- else
+ } else {
set_base(RID());
+ }
}
Ref<MultiMesh> MultiMeshInstance3D::get_multimesh() const {
-
return multimesh;
}
Vector<Face3> MultiMeshInstance3D::get_faces(uint32_t p_usage_flags) const {
-
return Vector<Face3>();
}
AABB MultiMeshInstance3D::get_aabb() const {
-
- if (multimesh.is_null())
+ if (multimesh.is_null()) {
return AABB();
- else
+ } else {
return multimesh->get_aabb();
+ }
}
MultiMeshInstance3D::MultiMeshInstance3D() {
diff --git a/scene/3d/navigation_3d.cpp b/scene/3d/navigation_3d.cpp
index f880f65d37..07a4824c28 100644
--- a/scene/3d/navigation_3d.cpp
+++ b/scene/3d/navigation_3d.cpp
@@ -33,7 +33,6 @@
#include "servers/navigation_server_3d.h"
Vector<Vector3> Navigation3D::get_simple_path(const Vector3 &p_start, const Vector3 &p_end, bool p_optimize) const {
-
return NavigationServer3D::get_singleton()->map_get_path(map, p_start, p_end, p_optimize);
}
@@ -54,13 +53,11 @@ RID Navigation3D::get_closest_point_owner(const Vector3 &p_point) const {
}
void Navigation3D::set_up_vector(const Vector3 &p_up) {
-
up = p_up;
NavigationServer3D::get_singleton()->map_set_up(map, up);
}
Vector3 Navigation3D::get_up_vector() const {
-
return up;
}
@@ -75,7 +72,6 @@ void Navigation3D::set_edge_connection_margin(float p_edge_connection_margin) {
}
void Navigation3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_rid"), &Navigation3D::get_rid);
ClassDB::bind_method(D_METHOD("get_simple_path", "start", "end", "optimize"), &Navigation3D::get_simple_path, DEFVAL(true));
@@ -104,14 +100,12 @@ void Navigation3D::_notification(int p_what) {
NavigationServer3D::get_singleton()->map_set_active(map, true);
} break;
case NOTIFICATION_EXIT_TREE: {
-
NavigationServer3D::get_singleton()->map_set_active(map, false);
} break;
}
}
Navigation3D::Navigation3D() {
-
map = NavigationServer3D::get_singleton()->map_create();
set_cell_size(0.3);
diff --git a/scene/3d/navigation_3d.h b/scene/3d/navigation_3d.h
index daa9558125..890caed171 100644
--- a/scene/3d/navigation_3d.h
+++ b/scene/3d/navigation_3d.h
@@ -35,7 +35,6 @@
#include "scene/3d/node_3d.h"
class Navigation3D : public Node3D {
-
GDCLASS(Navigation3D, Node3D);
RID map;
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index 0449ab15b7..f8d44506b6 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -35,7 +35,6 @@
#include "servers/navigation_server_3d.h"
void NavigationAgent3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_target_desired_distance", "desired_distance"), &NavigationAgent3D::set_target_desired_distance);
ClassDB::bind_method(D_METHOD("get_target_desired_distance"), &NavigationAgent3D::get_target_desired_distance);
@@ -99,7 +98,6 @@ void NavigationAgent3D::_bind_methods() {
void NavigationAgent3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
-
agent_parent = Object::cast_to<Node3D>(get_parent());
NavigationServer3D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
@@ -110,10 +108,11 @@ void NavigationAgent3D::_notification(int p_what) {
Node *p = get_parent();
while (p != nullptr) {
nav = Object::cast_to<Navigation3D>(p);
- if (nav != nullptr)
+ if (nav != nullptr) {
p = nullptr;
- else
+ } else {
p = p->get_parent();
+ }
}
set_navigation(nav);
@@ -128,7 +127,6 @@ void NavigationAgent3D::_notification(int p_what) {
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
if (agent_parent) {
-
NavigationServer3D::get_singleton()->agent_set_position(agent, agent_parent->get_global_transform().origin);
if (!target_reached) {
if (distance_to_target() < target_desired_distance) {
@@ -141,16 +139,7 @@ void NavigationAgent3D::_notification(int p_what) {
}
}
-NavigationAgent3D::NavigationAgent3D() :
- agent_parent(nullptr),
- navigation(nullptr),
- agent(RID()),
- target_desired_distance(1.0),
- navigation_height_offset(0.0),
- path_max_distance(3.0),
- velocity_submitted(false),
- target_reached(false),
- navigation_finished(true) {
+NavigationAgent3D::NavigationAgent3D() {
agent = NavigationServer3D::get_singleton()->agent_create();
set_neighbor_dist(50.0);
set_max_neighbors(10);
@@ -166,8 +155,9 @@ NavigationAgent3D::~NavigationAgent3D() {
}
void NavigationAgent3D::set_navigation(Navigation3D *p_nav) {
- if (navigation == p_nav)
+ if (navigation == p_nav) {
return; // Pointless
+ }
navigation = p_nav;
NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
@@ -305,10 +295,15 @@ String NavigationAgent3D::get_configuration_warning() const {
}
void NavigationAgent3D::update_navigation() {
-
- if (agent_parent == nullptr) return;
- if (navigation == nullptr) return;
- if (update_frame_id == Engine::get_singleton()->get_physics_frames()) return;
+ if (agent_parent == nullptr) {
+ return;
+ }
+ if (navigation == nullptr) {
+ return;
+ }
+ if (update_frame_id == Engine::get_singleton()->get_physics_frames()) {
+ return;
+ }
update_frame_id = Engine::get_singleton()->get_physics_frames();
@@ -343,8 +338,9 @@ void NavigationAgent3D::update_navigation() {
emit_signal("path_changed");
}
- if (navigation_path.size() == 0)
+ if (navigation_path.size() == 0) {
return;
+ }
// Check if we can advance the navigation path
if (navigation_finished == false) {
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index 3558b4e51b..6dc375ef24 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -40,31 +40,31 @@ class Navigation3D;
class NavigationAgent3D : public Node {
GDCLASS(NavigationAgent3D, Node);
- Node3D *agent_parent;
- Navigation3D *navigation;
+ Node3D *agent_parent = nullptr;
+ Navigation3D *navigation = nullptr;
RID agent;
- real_t target_desired_distance;
+ real_t target_desired_distance = 1.0;
real_t radius;
- real_t navigation_height_offset;
+ real_t navigation_height_offset = 0.0;
bool ignore_y;
real_t neighbor_dist;
int max_neighbors;
real_t time_horizon;
real_t max_speed;
- real_t path_max_distance;
+ real_t path_max_distance = 3.0;
Vector3 target_location;
Vector<Vector3> navigation_path;
int nav_path_index;
- bool velocity_submitted;
+ bool velocity_submitted = false;
Vector3 prev_safe_velocity;
/// The submitted target velocity
Vector3 target_velocity;
- bool target_reached;
- bool navigation_finished;
+ bool target_reached = false;
+ bool navigation_finished = true;
// No initialized on purpose
uint32_t update_frame_id;
diff --git a/scene/3d/navigation_obstacle_3d.cpp b/scene/3d/navigation_obstacle_3d.cpp
index 2ee2008799..69fd5b02fc 100644
--- a/scene/3d/navigation_obstacle_3d.cpp
+++ b/scene/3d/navigation_obstacle_3d.cpp
@@ -36,7 +36,6 @@
#include "servers/navigation_server_3d.h"
void NavigationObstacle3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_navigation", "navigation"), &NavigationObstacle3D::set_navigation_node);
ClassDB::bind_method(D_METHOD("get_navigation"), &NavigationObstacle3D::get_navigation_node);
}
@@ -44,7 +43,6 @@ void NavigationObstacle3D::_bind_methods() {
void NavigationObstacle3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_READY: {
-
update_agent_shape();
// Search the navigation node and set it
@@ -53,10 +51,11 @@ void NavigationObstacle3D::_notification(int p_what) {
Node *p = get_parent();
while (p != nullptr) {
nav = Object::cast_to<Navigation3D>(p);
- if (nav != nullptr)
+ if (nav != nullptr) {
p = nullptr;
- else
+ } else {
p = p->get_parent();
+ }
}
set_navigation(nav);
@@ -76,7 +75,6 @@ void NavigationObstacle3D::_notification(int p_what) {
PhysicsBody3D *rigid = Object::cast_to<PhysicsBody3D>(get_parent());
if (rigid) {
-
Vector3 v = rigid->get_linear_velocity();
NavigationServer3D::get_singleton()->agent_set_velocity(agent, v);
NavigationServer3D::get_singleton()->agent_set_target_velocity(agent, v);
@@ -86,9 +84,7 @@ void NavigationObstacle3D::_notification(int p_what) {
}
}
-NavigationObstacle3D::NavigationObstacle3D() :
- navigation(nullptr),
- agent(RID()) {
+NavigationObstacle3D::NavigationObstacle3D() {
agent = NavigationServer3D::get_singleton()->agent_create();
}
@@ -98,8 +94,9 @@ NavigationObstacle3D::~NavigationObstacle3D() {
}
void NavigationObstacle3D::set_navigation(Navigation3D *p_nav) {
- if (navigation == p_nav)
+ if (navigation == p_nav) {
return; // Pointless
+ }
navigation = p_nav;
NavigationServer3D::get_singleton()->agent_set_map(agent, navigation == nullptr ? RID() : navigation->get_rid());
@@ -117,7 +114,6 @@ Node *NavigationObstacle3D::get_navigation_node() const {
String NavigationObstacle3D::get_configuration_warning() const {
if (!Object::cast_to<Node3D>(get_parent())) {
-
return TTR("The NavigationObstacle3D only serves to provide collision avoidance to a spatial object.");
}
@@ -151,8 +147,9 @@ void NavigationObstacle3D::update_agent_shape() {
radius *= MAX(s.x, MAX(s.y, s.z));
}
- if (radius == 0.0)
+ if (radius == 0.0) {
radius = 1.0; // Never a 0 radius
+ }
// Initialize the Agent as an object
NavigationServer3D::get_singleton()->agent_set_neighbor_dist(agent, 0.0);
diff --git a/scene/3d/navigation_obstacle_3d.h b/scene/3d/navigation_obstacle_3d.h
index b58d7c4991..c7d2b556af 100644
--- a/scene/3d/navigation_obstacle_3d.h
+++ b/scene/3d/navigation_obstacle_3d.h
@@ -38,7 +38,7 @@ class Navigation3D;
class NavigationObstacle3D : public Node {
GDCLASS(NavigationObstacle3D, Node);
- Navigation3D *navigation;
+ Navigation3D *navigation = nullptr;
RID agent;
diff --git a/scene/3d/navigation_region_3d.cpp b/scene/3d/navigation_region_3d.cpp
index 043b816033..15ed448a65 100644
--- a/scene/3d/navigation_region_3d.cpp
+++ b/scene/3d/navigation_region_3d.cpp
@@ -36,21 +36,19 @@
#include "servers/navigation_server_3d.h"
void NavigationRegion3D::set_enabled(bool p_enabled) {
-
- if (enabled == p_enabled)
+ if (enabled == p_enabled) {
return;
+ }
enabled = p_enabled;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
if (!enabled) {
-
NavigationServer3D::get_singleton()->region_set_map(region, RID());
} else {
-
if (navigation) {
-
NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
}
}
@@ -68,25 +66,19 @@ void NavigationRegion3D::set_enabled(bool p_enabled) {
}
bool NavigationRegion3D::is_enabled() const {
-
return enabled;
}
/////////////////////////////
void NavigationRegion3D::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
-
Node3D *c = this;
while (c) {
-
navigation = Object::cast_to<Navigation3D>(c);
if (navigation) {
-
if (enabled) {
-
NavigationServer3D::get_singleton()->region_set_map(region, navigation->get_rid());
}
break;
@@ -96,7 +88,6 @@ void NavigationRegion3D::_notification(int p_what) {
}
if (navmesh.is_valid() && get_tree()->is_debugging_navigation_hint()) {
-
MeshInstance3D *dm = memnew(MeshInstance3D);
dm->set_mesh(navmesh->get_debug_mesh());
if (is_enabled()) {
@@ -110,14 +101,11 @@ void NavigationRegion3D::_notification(int p_what) {
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
NavigationServer3D::get_singleton()->region_set_transform(region, get_global_transform());
} break;
case NOTIFICATION_EXIT_TREE: {
-
if (navigation) {
-
NavigationServer3D::get_singleton()->region_set_map(region, RID());
}
@@ -131,9 +119,9 @@ void NavigationRegion3D::_notification(int p_what) {
}
void NavigationRegion3D::set_navigation_mesh(const Ref<NavigationMesh> &p_navmesh) {
-
- if (p_navmesh == navmesh)
+ if (p_navmesh == navmesh) {
return;
+ }
if (navmesh.is_valid()) {
navmesh->remove_change_receptor(this);
@@ -158,7 +146,6 @@ void NavigationRegion3D::set_navigation_mesh(const Ref<NavigationMesh> &p_navmes
}
Ref<NavigationMesh> NavigationRegion3D::get_navigation_mesh() const {
-
return navmesh;
}
@@ -176,7 +163,6 @@ void _bake_navigation_mesh(void *p_user_data) {
args->nav_region->call_deferred("_bake_finished", nav_mesh);
memdelete(args);
} else {
-
ERR_PRINT("Can't bake the navigation mesh if the `NavigationMesh` resource doesn't exist");
args->nav_region->call_deferred("_bake_finished", Ref<NavigationMesh>());
memdelete(args);
@@ -199,18 +185,18 @@ void NavigationRegion3D::_bake_finished(Ref<NavigationMesh> p_nav_mesh) {
}
String NavigationRegion3D::get_configuration_warning() const {
-
- if (!is_visible_in_tree() || !is_inside_tree())
+ if (!is_visible_in_tree() || !is_inside_tree()) {
return String();
+ }
if (!navmesh.is_valid()) {
return TTR("A NavigationMesh resource must be set or created for this node to work.");
}
const Node3D *c = this;
while (c) {
-
- if (Object::cast_to<Navigation3D>(c))
+ if (Object::cast_to<Navigation3D>(c)) {
return String();
+ }
c = Object::cast_to<Node3D>(c->get_parent());
}
@@ -219,7 +205,6 @@ String NavigationRegion3D::get_configuration_warning() const {
}
void NavigationRegion3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_navigation_mesh", "navmesh"), &NavigationRegion3D::set_navigation_mesh);
ClassDB::bind_method(D_METHOD("get_navigation_mesh"), &NavigationRegion3D::get_navigation_mesh);
@@ -242,18 +227,13 @@ void NavigationRegion3D::_changed_callback(Object *p_changed, const char *p_prop
}
NavigationRegion3D::NavigationRegion3D() {
-
- enabled = true;
set_notify_transform(true);
region = NavigationServer3D::get_singleton()->region_create();
-
- navigation = nullptr;
- debug_view = nullptr;
- bake_thread = nullptr;
}
NavigationRegion3D::~NavigationRegion3D() {
- if (navmesh.is_valid())
+ if (navmesh.is_valid()) {
navmesh->remove_change_receptor(this);
+ }
NavigationServer3D::get_singleton()->free(region);
}
diff --git a/scene/3d/navigation_region_3d.h b/scene/3d/navigation_region_3d.h
index ae071e6b7a..fcd2efd4ef 100644
--- a/scene/3d/navigation_region_3d.h
+++ b/scene/3d/navigation_region_3d.h
@@ -38,16 +38,15 @@
class Navigation3D;
class NavigationRegion3D : public Node3D {
-
GDCLASS(NavigationRegion3D, Node3D);
- bool enabled;
+ bool enabled = true;
RID region;
Ref<NavigationMesh> navmesh;
- Navigation3D *navigation;
- Node *debug_view;
- Thread *bake_thread;
+ Navigation3D *navigation = nullptr;
+ Node *debug_view = nullptr;
+ Thread *bake_thread = nullptr;
protected:
void _notification(int p_what);
diff --git a/scene/3d/node_3d.cpp b/scene/3d/node_3d.cpp
index 0b7407e049..73f17060df 100644
--- a/scene/3d/node_3d.cpp
+++ b/scene/3d/node_3d.cpp
@@ -74,7 +74,6 @@ Node3DGizmo::Node3DGizmo() {
}
void Node3D::_notify_dirty() {
-
#ifdef TOOLS_ENABLED
if ((data.gizmo.is_valid() || data.notify_transform) && !data.ignore_notification && !xform_change.in_list()) {
#else
@@ -90,8 +89,8 @@ void Node3D::_update_local_transform() const {
data.dirty &= ~DIRTY_LOCAL;
}
-void Node3D::_propagate_transform_changed(Node3D *p_origin) {
+void Node3D::_propagate_transform_changed(Node3D *p_origin) {
if (!is_inside_tree()) {
return;
}
@@ -104,9 +103,9 @@ void Node3D::_propagate_transform_changed(Node3D *p_origin) {
data.children_lock++;
for (List<Node3D *>::Element *E = data.children.front(); E; E = E->next()) {
-
- if (E->get()->data.toplevel_active)
+ if (E->get()->data.toplevel_active) {
continue; //don't propagate to a toplevel
+ }
E->get()->_propagate_transform_changed(p_origin);
}
#ifdef TOOLS_ENABLED
@@ -122,22 +121,22 @@ void Node3D::_propagate_transform_changed(Node3D *p_origin) {
}
void Node3D::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
ERR_FAIL_COND(!get_tree());
Node *p = get_parent();
- if (p)
+ if (p) {
data.parent = Object::cast_to<Node3D>(p);
+ }
- if (data.parent)
+ if (data.parent) {
data.C = data.parent->data.children.push_back(this);
- else
+ } else {
data.C = nullptr;
+ }
if (data.toplevel && !Engine::get_singleton()->is_editor_hint()) {
-
if (data.parent) {
data.local_transform = data.parent->get_global_transform() * get_transform();
data.dirty = DIRTY_VECTORS; //global is always dirty upon entering a scene
@@ -152,18 +151,18 @@ void Node3D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
-
notification(NOTIFICATION_EXIT_WORLD, true);
- if (xform_change.in_list())
+ if (xform_change.in_list()) {
get_tree()->xform_change_list.remove(&xform_change);
- if (data.C)
+ }
+ if (data.C) {
data.parent->data.children.erase(data.C);
+ }
data.parent = nullptr;
data.C = nullptr;
data.toplevel_active = false;
} break;
case NOTIFICATION_ENTER_WORLD: {
-
data.inside_world = true;
data.viewport = nullptr;
Node *parent = get_parent();
@@ -175,16 +174,13 @@ void Node3D::_notification(int p_what) {
ERR_FAIL_COND(!data.viewport);
if (get_script_instance()) {
-
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_enter_world, nullptr, 0);
}
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint() && get_tree()->is_node_being_edited(this)) {
-
//get_scene()->call_group(SceneMainLoop::GROUP_CALL_REALTIME,SceneStringNames::get_singleton()->_spatial_editor_group,SceneStringNames::get_singleton()->_request_gizmo,this);
get_tree()->call_group_flags(0, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this);
if (!data.gizmo_disabled) {
-
if (data.gizmo.is_valid()) {
data.gizmo->create();
if (is_visible_in_tree()) {
@@ -198,7 +194,6 @@ void Node3D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_WORLD: {
-
#ifdef TOOLS_ENABLED
if (data.gizmo.is_valid()) {
data.gizmo->free();
@@ -207,7 +202,6 @@ void Node3D::_notification(int p_what) {
#endif
if (get_script_instance()) {
-
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_world, nullptr, 0);
}
@@ -217,7 +211,6 @@ void Node3D::_notification(int p_what) {
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
#ifdef TOOLS_ENABLED
if (data.gizmo.is_valid()) {
data.gizmo->transform();
@@ -231,7 +224,6 @@ void Node3D::_notification(int p_what) {
}
void Node3D::set_transform(const Transform &p_transform) {
-
data.local_transform = p_transform;
data.dirty |= DIRTY_VECTORS;
_change_notify("translation");
@@ -245,7 +237,6 @@ void Node3D::set_transform(const Transform &p_transform) {
}
void Node3D::set_global_transform(const Transform &p_transform) {
-
Transform xform =
(data.parent && !data.toplevel_active) ?
data.parent->get_global_transform().affine_inverse() * p_transform :
@@ -255,30 +246,24 @@ void Node3D::set_global_transform(const Transform &p_transform) {
}
Transform Node3D::get_transform() const {
-
if (data.dirty & DIRTY_LOCAL) {
-
_update_local_transform();
}
return data.local_transform;
}
-Transform Node3D::get_global_transform() const {
+Transform Node3D::get_global_transform() const {
ERR_FAIL_COND_V(!is_inside_tree(), Transform());
if (data.dirty & DIRTY_GLOBAL) {
-
if (data.dirty & DIRTY_LOCAL) {
-
_update_local_transform();
}
if (data.parent && !data.toplevel_active) {
-
data.global_transform = data.parent->get_global_transform() * data.local_transform;
} else {
-
data.global_transform = data.local_transform;
}
@@ -303,25 +288,24 @@ Transform Node3D::get_local_gizmo_transform() const {
#endif
Node3D *Node3D::get_parent_spatial() const {
-
return data.parent;
}
Transform Node3D::get_relative_transform(const Node *p_parent) const {
-
- if (p_parent == this)
+ if (p_parent == this) {
return Transform();
+ }
ERR_FAIL_COND_V(!data.parent, Transform());
- if (p_parent == data.parent)
+ if (p_parent == data.parent) {
return get_transform();
- else
+ } else {
return data.parent->get_relative_transform(p_parent) * get_transform();
+ }
}
void Node3D::set_translation(const Vector3 &p_translation) {
-
data.local_transform.origin = p_translation;
_change_notify("transform");
_propagate_transform_changed(this);
@@ -331,7 +315,6 @@ void Node3D::set_translation(const Vector3 &p_translation) {
}
void Node3D::set_rotation(const Vector3 &p_euler_rad) {
-
if (data.dirty & DIRTY_VECTORS) {
data.scale = data.local_transform.basis.get_scale();
data.dirty &= ~DIRTY_VECTORS;
@@ -347,12 +330,10 @@ void Node3D::set_rotation(const Vector3 &p_euler_rad) {
}
void Node3D::set_rotation_degrees(const Vector3 &p_euler_deg) {
-
set_rotation(p_euler_deg * Math_PI / 180.0);
}
void Node3D::set_scale(const Vector3 &p_scale) {
-
if (data.dirty & DIRTY_VECTORS) {
data.rotation = data.local_transform.basis.get_rotation();
data.dirty &= ~DIRTY_VECTORS;
@@ -368,12 +349,10 @@ void Node3D::set_scale(const Vector3 &p_scale) {
}
Vector3 Node3D::get_translation() const {
-
return data.local_transform.origin;
}
Vector3 Node3D::get_rotation() const {
-
if (data.dirty & DIRTY_VECTORS) {
data.scale = data.local_transform.basis.get_scale();
data.rotation = data.local_transform.basis.get_rotation();
@@ -385,12 +364,10 @@ Vector3 Node3D::get_rotation() const {
}
Vector3 Node3D::get_rotation_degrees() const {
-
return get_rotation() * 180.0 / Math_PI;
}
Vector3 Node3D::get_scale() const {
-
if (data.dirty & DIRTY_VECTORS) {
data.scale = data.local_transform.basis.get_scale();
data.rotation = data.local_transform.basis.get_rotation();
@@ -402,32 +379,35 @@ Vector3 Node3D::get_scale() const {
}
void Node3D::update_gizmo() {
-
#ifdef TOOLS_ENABLED
- if (!is_inside_world())
+ if (!is_inside_world()) {
return;
- if (!data.gizmo.is_valid())
+ }
+ if (!data.gizmo.is_valid()) {
get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this);
- if (!data.gizmo.is_valid())
+ }
+ if (!data.gizmo.is_valid()) {
return;
- if (data.gizmo_dirty)
+ }
+ if (data.gizmo_dirty) {
return;
+ }
data.gizmo_dirty = true;
MessageQueue::get_singleton()->push_call(this, "_update_gizmo");
#endif
}
void Node3D::set_gizmo(const Ref<Node3DGizmo> &p_gizmo) {
-
#ifdef TOOLS_ENABLED
- if (data.gizmo_disabled)
+ if (data.gizmo_disabled) {
return;
- if (data.gizmo.is_valid() && is_inside_world())
+ }
+ if (data.gizmo.is_valid() && is_inside_world()) {
data.gizmo->free();
+ }
data.gizmo = p_gizmo;
if (data.gizmo.is_valid() && is_inside_world()) {
-
data.gizmo->create();
if (is_visible_in_tree()) {
data.gizmo->redraw();
@@ -439,7 +419,6 @@ void Node3D::set_gizmo(const Ref<Node3DGizmo> &p_gizmo) {
}
Ref<Node3DGizmo> Node3D::get_gizmo() const {
-
#ifdef TOOLS_ENABLED
return data.gizmo;
@@ -450,32 +429,32 @@ Ref<Node3DGizmo> Node3D::get_gizmo() const {
}
void Node3D::_update_gizmo() {
-
#ifdef TOOLS_ENABLED
- if (!is_inside_world())
+ if (!is_inside_world()) {
return;
+ }
data.gizmo_dirty = false;
if (data.gizmo.is_valid()) {
- if (is_visible_in_tree())
+ if (is_visible_in_tree()) {
data.gizmo->redraw();
- else
+ } else {
data.gizmo->clear();
+ }
}
#endif
}
#ifdef TOOLS_ENABLED
void Node3D::set_disable_gizmo(bool p_enabled) {
-
data.gizmo_disabled = p_enabled;
- if (!p_enabled && data.gizmo.is_valid())
+ if (!p_enabled && data.gizmo.is_valid()) {
data.gizmo = Ref<Node3DGizmo>();
+ }
}
#endif
void Node3D::set_disable_scale(bool p_enabled) {
-
data.disable_scale = p_enabled;
}
@@ -484,15 +463,15 @@ bool Node3D::is_scale_disabled() const {
}
void Node3D::set_as_toplevel(bool p_enabled) {
-
- if (data.toplevel == p_enabled)
+ if (data.toplevel == p_enabled) {
return;
+ }
if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) {
-
- if (p_enabled)
+ if (p_enabled) {
set_transform(get_global_transform());
- else if (data.parent)
+ } else if (data.parent) {
set_transform(data.parent->get_global_transform().affine_inverse() * get_global_transform());
+ }
data.toplevel = p_enabled;
data.toplevel_active = p_enabled;
@@ -503,65 +482,64 @@ void Node3D::set_as_toplevel(bool p_enabled) {
}
bool Node3D::is_set_as_toplevel() const {
-
return data.toplevel;
}
-Ref<World3D> Node3D::get_world() const {
-
+Ref<World3D> Node3D::get_world_3d() const {
ERR_FAIL_COND_V(!is_inside_world(), Ref<World3D>());
ERR_FAIL_COND_V(!data.viewport, Ref<World3D>());
- return data.viewport->find_world();
+ return data.viewport->find_world_3d();
}
void Node3D::_propagate_visibility_changed() {
-
notification(NOTIFICATION_VISIBILITY_CHANGED);
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
_change_notify("visible");
#ifdef TOOLS_ENABLED
- if (data.gizmo.is_valid())
+ if (data.gizmo.is_valid()) {
_update_gizmo();
+ }
#endif
for (List<Node3D *>::Element *E = data.children.front(); E; E = E->next()) {
-
Node3D *c = E->get();
- if (!c || !c->data.visible)
+ if (!c || !c->data.visible) {
continue;
+ }
c->_propagate_visibility_changed();
}
}
void Node3D::show() {
-
- if (data.visible)
+ if (data.visible) {
return;
+ }
data.visible = true;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_propagate_visibility_changed();
}
void Node3D::hide() {
-
- if (!data.visible)
+ if (!data.visible) {
return;
+ }
data.visible = false;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_propagate_visibility_changed();
}
bool Node3D::is_visible_in_tree() const {
-
const Node3D *s = this;
while (s) {
@@ -575,15 +553,14 @@ bool Node3D::is_visible_in_tree() const {
}
void Node3D::set_visible(bool p_visible) {
-
- if (p_visible)
+ if (p_visible) {
show();
- else
+ } else {
hide();
+ }
}
bool Node3D::is_visible() const {
-
return data.visible;
}
@@ -594,34 +571,30 @@ void Node3D::rotate_object_local(const Vector3 &p_axis, float p_angle) {
}
void Node3D::rotate(const Vector3 &p_axis, float p_angle) {
-
Transform t = get_transform();
t.basis.rotate(p_axis, p_angle);
set_transform(t);
}
void Node3D::rotate_x(float p_angle) {
-
Transform t = get_transform();
t.basis.rotate(Vector3(1, 0, 0), p_angle);
set_transform(t);
}
void Node3D::rotate_y(float p_angle) {
-
Transform t = get_transform();
t.basis.rotate(Vector3(0, 1, 0), p_angle);
set_transform(t);
}
-void Node3D::rotate_z(float p_angle) {
+void Node3D::rotate_z(float p_angle) {
Transform t = get_transform();
t.basis.rotate(Vector3(0, 0, 1), p_angle);
set_transform(t);
}
void Node3D::translate(const Vector3 &p_offset) {
-
Transform t = get_transform();
t.translate(p_offset);
set_transform(t);
@@ -636,7 +609,6 @@ void Node3D::translate_object_local(const Vector3 &p_offset) {
}
void Node3D::scale(const Vector3 &p_ratio) {
-
Transform t = get_transform();
t.basis.scale(p_ratio);
set_transform(t);
@@ -649,14 +621,12 @@ void Node3D::scale_object_local(const Vector3 &p_scale) {
}
void Node3D::global_rotate(const Vector3 &p_axis, float p_angle) {
-
Transform t = get_global_transform();
t.basis.rotate(p_axis, p_angle);
set_global_transform(t);
}
void Node3D::global_scale(const Vector3 &p_scale) {
-
Transform t = get_global_transform();
t.basis.scale(p_scale);
set_global_transform(t);
@@ -669,25 +639,21 @@ void Node3D::global_translate(const Vector3 &p_offset) {
}
void Node3D::orthonormalize() {
-
Transform t = get_transform();
t.orthonormalize();
set_transform(t);
}
void Node3D::set_identity() {
-
set_transform(Transform());
}
void Node3D::look_at(const Vector3 &p_target, const Vector3 &p_up) {
-
Vector3 origin(get_global_transform().origin);
look_at_from_position(origin, p_target, p_up);
}
void Node3D::look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target, const Vector3 &p_up) {
-
ERR_FAIL_COND_MSG(p_pos == p_target, "Node origin and target are in the same position, look_at() failed.");
ERR_FAIL_COND_MSG(p_up.cross(p_target - p_pos) == Vector3(), "Up vector and direction between node origin and target are aligned, look_at() failed.");
@@ -701,12 +667,10 @@ void Node3D::look_at_from_position(const Vector3 &p_pos, const Vector3 &p_target
}
Vector3 Node3D::to_local(Vector3 p_global) const {
-
return get_global_transform().affine_inverse().xform(p_global);
}
Vector3 Node3D::to_global(Vector3 p_local) const {
-
return get_global_transform().xform(p_local);
}
@@ -737,7 +701,6 @@ void Node3D::force_update_transform() {
}
void Node3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_transform", "local"), &Node3D::set_transform);
ClassDB::bind_method(D_METHOD("get_transform"), &Node3D::get_transform);
ClassDB::bind_method(D_METHOD("set_translation", "translation"), &Node3D::set_translation);
@@ -756,7 +719,7 @@ void Node3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_set_as_toplevel"), &Node3D::is_set_as_toplevel);
ClassDB::bind_method(D_METHOD("set_disable_scale", "disable"), &Node3D::set_disable_scale);
ClassDB::bind_method(D_METHOD("is_scale_disabled"), &Node3D::is_scale_disabled);
- ClassDB::bind_method(D_METHOD("get_world"), &Node3D::get_world);
+ ClassDB::bind_method(D_METHOD("get_world_3d"), &Node3D::get_world_3d);
ClassDB::bind_method(D_METHOD("force_update_transform"), &Node3D::force_update_transform);
@@ -821,7 +784,6 @@ void Node3D::_bind_methods() {
Node3D::Node3D() :
xform_change(this) {
-
data.dirty = DIRTY_NONE;
data.children_lock = 0;
diff --git a/scene/3d/node_3d.h b/scene/3d/node_3d.h
index f97a8a97dc..327d4671e9 100644
--- a/scene/3d/node_3d.h
+++ b/scene/3d/node_3d.h
@@ -35,7 +35,6 @@
#include "scene/main/scene_tree.h"
class Node3DGizmo : public Reference {
-
GDCLASS(Node3DGizmo, Reference);
public:
@@ -50,7 +49,6 @@ public:
};
class Node3D : public Node {
-
GDCLASS(Node3D, Node);
OBJ_CATEGORY("3D");
@@ -64,7 +62,6 @@ class Node3D : public Node {
mutable SelfList<Node> xform_change;
struct Data {
-
mutable Transform global_transform;
mutable Transform local_transform;
mutable Vector3 rotation;
@@ -124,7 +121,7 @@ public:
Node3D *get_parent_spatial() const;
- Ref<World3D> get_world() const;
+ Ref<World3D> get_world_3d() const;
void set_translation(const Vector3 &p_translation);
void set_rotation(const Vector3 &p_euler_rad);
diff --git a/scene/3d/path_3d.cpp b/scene/3d/path_3d.cpp
index 4a425d1e0e..dcfdf8efcf 100644
--- a/scene/3d/path_3d.cpp
+++ b/scene/3d/path_3d.cpp
@@ -37,9 +37,9 @@ void Path3D::_notification(int p_what) {
}
void Path3D::_curve_changed() {
-
- if (is_inside_tree() && Engine::get_singleton()->is_editor_hint())
+ if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
update_gizmo();
+ }
if (is_inside_tree()) {
emit_signal("curve_changed");
}
@@ -57,7 +57,6 @@ void Path3D::_curve_changed() {
}
void Path3D::set_curve(const Ref<Curve3D> &p_curve) {
-
if (curve.is_valid()) {
curve->disconnect("changed", callable_mp(this, &Path3D::_curve_changed));
}
@@ -71,12 +70,10 @@ void Path3D::set_curve(const Ref<Curve3D> &p_curve) {
}
Ref<Curve3D> Path3D::get_curve() const {
-
return curve;
}
void Path3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_curve", "curve"), &Path3D::set_curve);
ClassDB::bind_method(D_METHOD("get_curve"), &Path3D::get_curve);
@@ -86,20 +83,20 @@ void Path3D::_bind_methods() {
}
Path3D::Path3D() {
-
set_curve(Ref<Curve3D>(memnew(Curve3D))); //create one by default
}
//////////////
void PathFollow3D::_update_transform() {
-
- if (!path)
+ if (!path) {
return;
+ }
Ref<Curve3D> c = path->get_curve();
- if (!c.is_valid())
+ if (!c.is_valid()) {
return;
+ }
if (delta_offset == 0) {
return;
@@ -124,13 +121,13 @@ void PathFollow3D::_update_transform() {
// will be replaced by "Vector3(h_offset, v_offset, 0)" where it was formerly used
if (rotation_mode == ROTATION_ORIENTED) {
-
Vector3 forward = c->interpolate_baked(o_next, cubic) - pos;
- if (forward.length_squared() < CMP_EPSILON2)
+ if (forward.length_squared() < CMP_EPSILON2) {
forward = Vector3(0, 0, 1);
- else
+ } else {
forward.normalize();
+ }
Vector3 up = c->interpolate_baked_up_vector(offset, true);
@@ -138,10 +135,11 @@ void PathFollow3D::_update_transform() {
Vector3 up1 = c->interpolate_baked_up_vector(o_next, true);
Vector3 axis = up.cross(up1);
- if (axis.length_squared() < CMP_EPSILON2)
+ if (axis.length_squared() < CMP_EPSILON2) {
axis = forward;
- else
+ } else {
axis.normalize();
+ }
up.rotate(axis, up.angle_to(up1) * 0.5f);
}
@@ -213,11 +211,8 @@ void PathFollow3D::_update_transform() {
}
void PathFollow3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
Node *parent = get_parent();
if (parent) {
path = Object::cast_to<Path3D>(parent);
@@ -228,38 +223,34 @@ void PathFollow3D::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
-
path = nullptr;
} break;
}
}
void PathFollow3D::set_cubic_interpolation(bool p_enable) {
-
cubic = p_enable;
}
bool PathFollow3D::get_cubic_interpolation() const {
-
return cubic;
}
void PathFollow3D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "offset") {
-
float max = 10000;
- if (path && path->get_curve().is_valid())
+ if (path && path->get_curve().is_valid()) {
max = path->get_curve()->get_baked_length();
+ }
property.hint_string = "0," + rtos(max) + ",0.01,or_lesser,or_greater";
}
}
String PathFollow3D::get_configuration_warning() const {
-
- if (!is_visible_in_tree() || !is_inside_tree())
+ if (!is_visible_in_tree() || !is_inside_tree()) {
return String();
+ }
if (!Object::cast_to<Path3D>(get_parent())) {
return TTR("PathFollow3D only works when set as a child of a Path3D node.");
@@ -274,7 +265,6 @@ String PathFollow3D::get_configuration_warning() const {
}
void PathFollow3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_offset", "offset"), &PathFollow3D::set_offset);
ClassDB::bind_method(D_METHOD("get_offset"), &PathFollow3D::get_offset);
@@ -336,50 +326,46 @@ void PathFollow3D::set_offset(float p_offset) {
}
void PathFollow3D::set_h_offset(float p_h_offset) {
-
h_offset = p_h_offset;
- if (path)
+ if (path) {
_update_transform();
+ }
}
float PathFollow3D::get_h_offset() const {
-
return h_offset;
}
void PathFollow3D::set_v_offset(float p_v_offset) {
-
v_offset = p_v_offset;
- if (path)
+ if (path) {
_update_transform();
+ }
}
float PathFollow3D::get_v_offset() const {
-
return v_offset;
}
float PathFollow3D::get_offset() const {
-
return offset;
}
void PathFollow3D::set_unit_offset(float p_unit_offset) {
-
- if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length())
+ if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) {
set_offset(p_unit_offset * path->get_curve()->get_baked_length());
+ }
}
float PathFollow3D::get_unit_offset() const {
-
- if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length())
+ if (path && path->get_curve().is_valid() && path->get_curve()->get_baked_length()) {
return get_offset() / path->get_curve()->get_baked_length();
- else
+ } else {
return 0;
+ }
}
void PathFollow3D::set_rotation_mode(RotationMode p_rotation_mode) {
-
rotation_mode = p_rotation_mode;
update_configuration_warning();
@@ -387,22 +373,18 @@ void PathFollow3D::set_rotation_mode(RotationMode p_rotation_mode) {
}
PathFollow3D::RotationMode PathFollow3D::get_rotation_mode() const {
-
return rotation_mode;
}
void PathFollow3D::set_loop(bool p_loop) {
-
loop = p_loop;
}
bool PathFollow3D::has_loop() const {
-
return loop;
}
PathFollow3D::PathFollow3D() {
-
offset = 0;
delta_offset = 0;
h_offset = 0;
diff --git a/scene/3d/path_3d.h b/scene/3d/path_3d.h
index 6f0db8c5c2..5a33016bc6 100644
--- a/scene/3d/path_3d.h
+++ b/scene/3d/path_3d.h
@@ -35,7 +35,6 @@
#include "scene/resources/curve.h"
class Path3D : public Node3D {
-
GDCLASS(Path3D, Node3D);
Ref<Curve3D> curve;
@@ -54,7 +53,6 @@ public:
};
class PathFollow3D : public Node3D {
-
GDCLASS(PathFollow3D, Node3D);
public:
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index 72d1762ab5..de8f1eea2e 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -45,72 +45,64 @@
#endif
Vector3 PhysicsBody3D::get_linear_velocity() const {
-
return Vector3();
}
-Vector3 PhysicsBody3D::get_angular_velocity() const {
+Vector3 PhysicsBody3D::get_angular_velocity() const {
return Vector3();
}
float PhysicsBody3D::get_inverse_mass() const {
-
return 0;
}
void PhysicsBody3D::set_collision_layer(uint32_t p_layer) {
-
collision_layer = p_layer;
PhysicsServer3D::get_singleton()->body_set_collision_layer(get_rid(), p_layer);
}
uint32_t PhysicsBody3D::get_collision_layer() const {
-
return collision_layer;
}
void PhysicsBody3D::set_collision_mask(uint32_t p_mask) {
-
collision_mask = p_mask;
PhysicsServer3D::get_singleton()->body_set_collision_mask(get_rid(), p_mask);
}
uint32_t PhysicsBody3D::get_collision_mask() const {
-
return collision_mask;
}
void PhysicsBody3D::set_collision_mask_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
bool PhysicsBody3D::get_collision_mask_bit(int p_bit) const {
-
return get_collision_mask() & (1 << p_bit);
}
void PhysicsBody3D::set_collision_layer_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_layer();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_layer(mask);
}
bool PhysicsBody3D::get_collision_layer_bit(int p_bit) const {
-
return get_collision_layer() & (1 << p_bit);
}
-Array PhysicsBody3D::get_collision_exceptions() {
+TypedArray<PhysicsBody3D> PhysicsBody3D::get_collision_exceptions() {
List<RID> exceptions;
PhysicsServer3D::get_singleton()->body_get_collision_exceptions(get_rid(), &exceptions);
Array ret;
@@ -125,7 +117,6 @@ Array PhysicsBody3D::get_collision_exceptions() {
}
void PhysicsBody3D::add_collision_exception_with(Node *p_node) {
-
ERR_FAIL_NULL(p_node);
CollisionObject3D *collision_object = Object::cast_to<CollisionObject3D>(p_node);
ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject3Ds.");
@@ -133,7 +124,6 @@ void PhysicsBody3D::add_collision_exception_with(Node *p_node) {
}
void PhysicsBody3D::remove_collision_exception_with(Node *p_node) {
-
ERR_FAIL_NULL(p_node);
CollisionObject3D *collision_object = Object::cast_to<CollisionObject3D>(p_node);
ERR_FAIL_COND_MSG(!collision_object, "Collision exception only works between two CollisionObject3Ds.");
@@ -146,7 +136,6 @@ void PhysicsBody3D::_set_layers(uint32_t p_mask) {
}
uint32_t PhysicsBody3D::_get_layers() const {
-
return get_collision_layer();
}
@@ -173,7 +162,6 @@ void PhysicsBody3D::_bind_methods() {
PhysicsBody3D::PhysicsBody3D(PhysicsServer3D::BodyMode p_mode) :
CollisionObject3D(PhysicsServer3D::get_singleton()->body_create(p_mode), false) {
-
collision_layer = 1;
collision_mask = 1;
}
@@ -198,28 +186,24 @@ Ref<PhysicsMaterial> StaticBody3D::get_physics_material_override() const {
}
void StaticBody3D::set_constant_linear_velocity(const Vector3 &p_vel) {
-
constant_linear_velocity = p_vel;
PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, constant_linear_velocity);
}
void StaticBody3D::set_constant_angular_velocity(const Vector3 &p_vel) {
-
constant_angular_velocity = p_vel;
PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, constant_angular_velocity);
}
Vector3 StaticBody3D::get_constant_linear_velocity() const {
-
return constant_linear_velocity;
}
-Vector3 StaticBody3D::get_constant_angular_velocity() const {
+Vector3 StaticBody3D::get_constant_angular_velocity() const {
return constant_angular_velocity;
}
void StaticBody3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant_linear_velocity", "vel"), &StaticBody3D::set_constant_linear_velocity);
ClassDB::bind_method(D_METHOD("set_constant_angular_velocity", "vel"), &StaticBody3D::set_constant_angular_velocity);
ClassDB::bind_method(D_METHOD("get_constant_linear_velocity"), &StaticBody3D::get_constant_linear_velocity);
@@ -254,7 +238,6 @@ void StaticBody3D::_reload_physics_characteristics() {
}
void RigidBody3D::_body_enter_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -271,7 +254,6 @@ void RigidBody3D::_body_enter_tree(ObjectID p_id) {
emit_signal(SceneStringNames::get_singleton()->body_entered, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->body_shape_entered, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape);
}
@@ -279,7 +261,6 @@ void RigidBody3D::_body_enter_tree(ObjectID p_id) {
}
void RigidBody3D::_body_exit_tree(ObjectID p_id) {
-
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
ERR_FAIL_COND(!node);
@@ -294,7 +275,6 @@ void RigidBody3D::_body_exit_tree(ObjectID p_id) {
emit_signal(SceneStringNames::get_singleton()->body_exited, node);
for (int i = 0; i < E->get().shapes.size(); i++) {
-
emit_signal(SceneStringNames::get_singleton()->body_shape_exited, p_id, node, E->get().shapes[i].body_shape, E->get().shapes[i].local_shape);
}
@@ -302,7 +282,6 @@ void RigidBody3D::_body_exit_tree(ObjectID p_id) {
}
void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, int p_local_shape) {
-
bool body_in = p_status == 1;
ObjectID objid = p_instance;
@@ -316,7 +295,6 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
if (body_in) {
if (!E) {
-
E = contact_monitor->body_map.insert(objid, BodyState());
//E->get().rc=0;
E->get().in_tree = node && node->is_inside_tree();
@@ -329,29 +307,30 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
}
}
//E->get().rc++;
- if (node)
+ if (node) {
E->get().shapes.insert(ShapePair(p_body_shape, p_local_shape));
+ }
if (E->get().in_tree) {
emit_signal(SceneStringNames::get_singleton()->body_shape_entered, objid, node, p_body_shape, p_local_shape);
}
} else {
-
//E->get().rc--;
- if (node)
+ if (node) {
E->get().shapes.erase(ShapePair(p_body_shape, p_local_shape));
+ }
bool in_tree = E->get().in_tree;
if (E->get().shapes.empty()) {
-
if (node) {
node->disconnect(SceneStringNames::get_singleton()->tree_entered, callable_mp(this, &RigidBody3D::_body_enter_tree));
node->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &RigidBody3D::_body_exit_tree));
- if (in_tree)
+ if (in_tree) {
emit_signal(SceneStringNames::get_singleton()->body_exited, node);
+ }
}
contact_monitor->body_map.erase(E);
@@ -363,14 +342,12 @@ void RigidBody3D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap
}
struct _RigidBodyInOut {
-
ObjectID id;
int shape;
int local_shape;
};
void RigidBody3D::_direct_state_changed(Object *p_state) {
-
#ifdef DEBUG_ENABLED
state = Object::cast_to<PhysicsDirectBodyState3D>(p_state);
#else
@@ -385,20 +362,18 @@ void RigidBody3D::_direct_state_changed(Object *p_state) {
sleeping = state->is_sleeping();
emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed);
}
- if (get_script_instance())
+ if (get_script_instance()) {
get_script_instance()->call("_integrate_forces", state);
+ }
set_ignore_transform_notification(false);
if (contact_monitor) {
-
contact_monitor->locked = true;
//untag all
int rc = 0;
for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
-
for (int i = 0; i < E->get().shapes.size(); i++) {
-
E->get().shapes[i].tagged = false;
rc++;
}
@@ -412,7 +387,6 @@ void RigidBody3D::_direct_state_changed(Object *p_state) {
//put the ones to add
for (int i = 0; i < state->get_contact_count(); i++) {
-
ObjectID obj = state->get_contact_collider_id(i);
int local_shape = state->get_contact_local_shape(i);
int shape = state->get_contact_collider_shape(i);
@@ -431,7 +405,6 @@ void RigidBody3D::_direct_state_changed(Object *p_state) {
ShapePair sp(shape, local_shape);
int idx = E->get().shapes.find(sp);
if (idx == -1) {
-
toadd[toadd_count].local_shape = local_shape;
toadd[toadd_count].id = obj;
toadd[toadd_count].shape = shape;
@@ -445,11 +418,8 @@ void RigidBody3D::_direct_state_changed(Object *p_state) {
//put the ones to remove
for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
-
for (int i = 0; i < E->get().shapes.size(); i++) {
-
if (!E->get().shapes[i].tagged) {
-
toremove[toremove_count].body_id = E->key();
toremove[toremove_count].pair = E->get().shapes[i];
toremove_count++;
@@ -460,14 +430,12 @@ void RigidBody3D::_direct_state_changed(Object *p_state) {
//process remotions
for (int i = 0; i < toremove_count; i++) {
-
_body_inout(0, toremove[i].body_id, toremove[i].pair.body_shape, toremove[i].pair.local_shape);
}
//process aditions
for (int i = 0; i < toadd_count; i++) {
-
_body_inout(1, toadd[i].id, toadd[i].shape, toadd[i].local_shape);
}
@@ -478,7 +446,6 @@ void RigidBody3D::_direct_state_changed(Object *p_state) {
}
void RigidBody3D::_notification(int p_what) {
-
#ifdef TOOLS_ENABLED
if (p_what == NOTIFICATION_ENTER_TREE) {
if (Engine::get_singleton()->is_editor_hint()) {
@@ -496,16 +463,12 @@ void RigidBody3D::_notification(int p_what) {
}
void RigidBody3D::set_mode(Mode p_mode) {
-
mode = p_mode;
switch (p_mode) {
-
case MODE_RIGID: {
-
PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_RIGID);
} break;
case MODE_STATIC: {
-
PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_STATIC);
} break;
@@ -514,7 +477,6 @@ void RigidBody3D::set_mode(Mode p_mode) {
} break;
case MODE_KINEMATIC: {
-
PhysicsServer3D::get_singleton()->body_set_mode(get_rid(), PhysicsServer3D::BODY_MODE_KINEMATIC);
} break;
}
@@ -522,29 +484,26 @@ void RigidBody3D::set_mode(Mode p_mode) {
}
RigidBody3D::Mode RigidBody3D::get_mode() const {
-
return mode;
}
void RigidBody3D::set_mass(real_t p_mass) {
-
ERR_FAIL_COND(p_mass <= 0);
mass = p_mass;
_change_notify("mass");
_change_notify("weight");
PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_MASS, mass);
}
-real_t RigidBody3D::get_mass() const {
+real_t RigidBody3D::get_mass() const {
return mass;
}
void RigidBody3D::set_weight(real_t p_weight) {
-
set_mass(p_weight / real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8)));
}
-real_t RigidBody3D::get_weight() const {
+real_t RigidBody3D::get_weight() const {
return mass * real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8));
}
@@ -568,39 +527,35 @@ Ref<PhysicsMaterial> RigidBody3D::get_physics_material_override() const {
}
void RigidBody3D::set_gravity_scale(real_t p_gravity_scale) {
-
gravity_scale = p_gravity_scale;
PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE, gravity_scale);
}
-real_t RigidBody3D::get_gravity_scale() const {
+real_t RigidBody3D::get_gravity_scale() const {
return gravity_scale;
}
void RigidBody3D::set_linear_damp(real_t p_linear_damp) {
-
ERR_FAIL_COND(p_linear_damp < -1);
linear_damp = p_linear_damp;
PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_LINEAR_DAMP, linear_damp);
}
-real_t RigidBody3D::get_linear_damp() const {
+real_t RigidBody3D::get_linear_damp() const {
return linear_damp;
}
void RigidBody3D::set_angular_damp(real_t p_angular_damp) {
-
ERR_FAIL_COND(p_angular_damp < -1);
angular_damp = p_angular_damp;
PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP, angular_damp);
}
-real_t RigidBody3D::get_angular_damp() const {
+real_t RigidBody3D::get_angular_damp() const {
return angular_damp;
}
void RigidBody3D::set_axis_velocity(const Vector3 &p_axis) {
-
Vector3 v = state ? state->get_linear_velocity() : linear_velocity;
Vector3 axis = p_axis.normalized();
v -= axis * axis.dot(v);
@@ -614,75 +569,68 @@ void RigidBody3D::set_axis_velocity(const Vector3 &p_axis) {
}
void RigidBody3D::set_linear_velocity(const Vector3 &p_velocity) {
-
linear_velocity = p_velocity;
- if (state)
+ if (state) {
state->set_linear_velocity(linear_velocity);
- else
+ } else {
PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY, linear_velocity);
+ }
}
Vector3 RigidBody3D::get_linear_velocity() const {
-
return linear_velocity;
}
void RigidBody3D::set_angular_velocity(const Vector3 &p_velocity) {
-
angular_velocity = p_velocity;
- if (state)
+ if (state) {
state->set_angular_velocity(angular_velocity);
- else
+ } else {
PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_ANGULAR_VELOCITY, angular_velocity);
+ }
}
-Vector3 RigidBody3D::get_angular_velocity() const {
+Vector3 RigidBody3D::get_angular_velocity() const {
return angular_velocity;
}
void RigidBody3D::set_use_custom_integrator(bool p_enable) {
-
- if (custom_integrator == p_enable)
+ if (custom_integrator == p_enable) {
return;
+ }
custom_integrator = p_enable;
PhysicsServer3D::get_singleton()->body_set_omit_force_integration(get_rid(), p_enable);
}
-bool RigidBody3D::is_using_custom_integrator() {
+bool RigidBody3D::is_using_custom_integrator() {
return custom_integrator;
}
void RigidBody3D::set_sleeping(bool p_sleeping) {
-
sleeping = p_sleeping;
PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_SLEEPING, sleeping);
}
void RigidBody3D::set_can_sleep(bool p_active) {
-
can_sleep = p_active;
PhysicsServer3D::get_singleton()->body_set_state(get_rid(), PhysicsServer3D::BODY_STATE_CAN_SLEEP, p_active);
}
bool RigidBody3D::is_able_to_sleep() const {
-
return can_sleep;
}
bool RigidBody3D::is_sleeping() const {
-
return sleeping;
}
void RigidBody3D::set_max_contacts_reported(int p_amount) {
-
max_contacts_reported = p_amount;
PhysicsServer3D::get_singleton()->body_set_max_contacts_reported(get_rid(), p_amount);
}
int RigidBody3D::get_max_contacts_reported() const {
-
return max_contacts_reported;
}
@@ -703,7 +651,6 @@ void RigidBody3D::apply_central_impulse(const Vector3 &p_impulse) {
}
void RigidBody3D::apply_impulse(const Vector3 &p_pos, const Vector3 &p_impulse) {
-
PhysicsServer3D::get_singleton()->body_apply_impulse(get_rid(), p_pos, p_impulse);
}
@@ -712,27 +659,23 @@ void RigidBody3D::apply_torque_impulse(const Vector3 &p_impulse) {
}
void RigidBody3D::set_use_continuous_collision_detection(bool p_enable) {
-
ccd = p_enable;
PhysicsServer3D::get_singleton()->body_set_enable_continuous_collision_detection(get_rid(), p_enable);
}
bool RigidBody3D::is_using_continuous_collision_detection() const {
-
return ccd;
}
void RigidBody3D::set_contact_monitor(bool p_enabled) {
-
- if (p_enabled == is_contact_monitor_enabled())
+ if (p_enabled == is_contact_monitor_enabled()) {
return;
+ }
if (!p_enabled) {
-
ERR_FAIL_COND_MSG(contact_monitor->locked, "Can't disable contact monitoring during in/out callback. Use call_deferred(\"set_contact_monitor\", false) instead.");
for (Map<ObjectID, BodyState>::Element *E = contact_monitor->body_map.front(); E; E = E->next()) {
-
//clean up mess
Object *obj = ObjectDB::get_instance(E->key());
Node *node = Object::cast_to<Node>(obj);
@@ -746,14 +689,12 @@ void RigidBody3D::set_contact_monitor(bool p_enabled) {
memdelete(contact_monitor);
contact_monitor = nullptr;
} else {
-
contact_monitor = memnew(ContactMonitor);
contact_monitor->locked = false;
}
}
bool RigidBody3D::is_contact_monitor_enabled() const {
-
return contact_monitor != nullptr;
}
@@ -766,7 +707,6 @@ bool RigidBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const {
}
Array RigidBody3D::get_colliding_bodies() const {
-
ERR_FAIL_COND_V(!contact_monitor, Array());
Array ret;
@@ -785,7 +725,6 @@ Array RigidBody3D::get_colliding_bodies() const {
}
String RigidBody3D::get_configuration_warning() const {
-
Transform t = get_transform();
String warning = CollisionObject3D::get_configuration_warning();
@@ -801,7 +740,6 @@ String RigidBody3D::get_configuration_warning() const {
}
void RigidBody3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_mode", "mode"), &RigidBody3D::set_mode);
ClassDB::bind_method(D_METHOD("get_mode"), &RigidBody3D::get_mode);
@@ -905,7 +843,6 @@ void RigidBody3D::_bind_methods() {
RigidBody3D::RigidBody3D() :
PhysicsBody3D(PhysicsServer3D::BODY_MODE_RIGID) {
-
mode = MODE_RIGID;
mass = 1;
@@ -928,9 +865,9 @@ RigidBody3D::RigidBody3D() :
}
RigidBody3D::~RigidBody3D() {
-
- if (contact_monitor)
+ if (contact_monitor) {
memdelete(contact_monitor);
+ }
}
void RigidBody3D::_reload_physics_characteristics() {
@@ -947,7 +884,6 @@ void RigidBody3D::_reload_physics_characteristics() {
//////////////////////////
Ref<KinematicCollision3D> KinematicBody3D::_move(const Vector3 &p_motion, bool p_infinite_inertia, bool p_exclude_raycast_shapes, bool p_test_only) {
-
Collision col;
if (move_and_collide(p_motion, p_infinite_inertia, col, p_exclude_raycast_shapes, p_test_only)) {
if (motion_cache.is_null()) {
@@ -972,7 +908,6 @@ Vector3 KinematicBody3D::get_angular_velocity() const {
}
bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_inertia, Collision &r_collision, bool p_exclude_raycast_shapes, bool p_test_only) {
-
Transform gt = get_global_transform();
PhysicsServer3D::MotionResult result;
bool colliding = PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), gt, p_motion, p_infinite_inertia, &result, p_exclude_raycast_shapes);
@@ -1008,7 +943,6 @@ bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_
#define FLOOR_ANGLE_THRESHOLD 0.01
Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
-
Vector3 body_velocity = p_linear_velocity;
Vector3 body_velocity_normal = body_velocity.normalized();
@@ -1030,7 +964,6 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
floor_velocity = Vector3();
while (p_max_slides) {
-
Collision collision;
bool found_collision = false;
@@ -1092,8 +1025,9 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
}
}
- if (!found_collision || motion == Vector3())
+ if (!found_collision || motion == Vector3()) {
break;
+ }
--p_max_slides;
}
@@ -1102,7 +1036,6 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
}
Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_velocity, const Vector3 &p_snap, const Vector3 &p_up_direction, bool p_stop_on_slope, int p_max_slides, float p_floor_max_angle, bool p_infinite_inertia) {
-
bool was_on_floor = on_floor;
Vector3 ret = move_and_slide(p_linear_velocity, p_up_direction, p_stop_on_slope, p_max_slides, p_floor_max_angle, p_infinite_inertia);
@@ -1114,7 +1047,6 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci
Transform gt = get_global_transform();
if (move_and_collide(p_snap, p_infinite_inertia, col, false, true)) {
-
bool apply = true;
if (p_up_direction != Vector3()) {
if (Math::acos(p_up_direction.normalized().dot(col.normal)) < p_floor_max_angle) {
@@ -1141,38 +1073,32 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci
}
bool KinematicBody3D::is_on_floor() const {
-
return on_floor;
}
bool KinematicBody3D::is_on_wall() const {
-
return on_wall;
}
-bool KinematicBody3D::is_on_ceiling() const {
+bool KinematicBody3D::is_on_ceiling() const {
return on_ceiling;
}
Vector3 KinematicBody3D::get_floor_normal() const {
-
return floor_normal;
}
Vector3 KinematicBody3D::get_floor_velocity() const {
-
return floor_velocity;
}
bool KinematicBody3D::test_move(const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia) {
-
ERR_FAIL_COND_V(!is_inside_tree(), false);
return PhysicsServer3D::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, p_infinite_inertia);
}
bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision &r_collision) {
-
PhysicsServer3D::SeparationResult sep_res[8]; //max 8 rays
Transform gt = get_global_transform();
@@ -1209,6 +1135,11 @@ bool KinematicBody3D::separate_raycast_shapes(bool p_infinite_inertia, Collision
}
void KinematicBody3D::set_axis_lock(PhysicsServer3D::BodyAxis p_axis, bool p_lock) {
+ if (p_lock) {
+ locked_axis |= p_axis;
+ } else {
+ locked_axis &= (~p_axis);
+ }
PhysicsServer3D::get_singleton()->body_set_axis_lock(get_rid(), p_axis, p_lock);
}
@@ -1217,17 +1148,15 @@ bool KinematicBody3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const {
}
void KinematicBody3D::set_safe_margin(float p_margin) {
-
margin = p_margin;
PhysicsServer3D::get_singleton()->body_set_kinematic_safe_margin(get_rid(), margin);
}
float KinematicBody3D::get_safe_margin() const {
-
return margin;
}
-int KinematicBody3D::get_slide_count() const {
+int KinematicBody3D::get_slide_count() const {
return colliders.size();
}
@@ -1237,7 +1166,6 @@ KinematicBody3D::Collision KinematicBody3D::get_slide_collision(int p_bounce) co
}
Ref<KinematicCollision3D> KinematicBody3D::_get_slide_collision(int p_bounce) {
-
ERR_FAIL_INDEX_V(p_bounce, colliders.size(), Ref<KinematicCollision3D>());
if (p_bounce >= slide_colliders.size()) {
slide_colliders.resize(p_bounce + 1);
@@ -1265,7 +1193,6 @@ void KinematicBody3D::_notification(int p_what) {
}
void KinematicBody3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_direct_state_changed"), &KinematicBody3D::_direct_state_changed);
ClassDB::bind_method(D_METHOD("move_and_collide", "rel_vec", "infinite_inertia", "exclude_raycast_shapes", "test_only"), &KinematicBody3D::_move, DEFVAL(true), DEFVAL(true), DEFVAL(false));
@@ -1289,9 +1216,10 @@ void KinematicBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_slide_count"), &KinematicBody3D::get_slide_count);
ClassDB::bind_method(D_METHOD("get_slide_collision", "slide_idx"), &KinematicBody3D::_get_slide_collision);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_x", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_y", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "move_lock_z", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z);
+ ADD_GROUP("Axis Lock", "axis_lock_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_x"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_X);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_y"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Y);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "axis_lock_motion_z"), "set_axis_lock", "get_axis_lock", PhysicsServer3D::BODY_AXIS_LINEAR_Z);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
}
@@ -1309,7 +1237,6 @@ void KinematicBody3D::_direct_state_changed(Object *p_state) {
KinematicBody3D::KinematicBody3D() :
PhysicsBody3D(PhysicsServer3D::BODY_MODE_KINEMATIC) {
-
margin = 0.001;
locked_axis = 0;
on_floor = false;
@@ -1318,8 +1245,8 @@ KinematicBody3D::KinematicBody3D() :
PhysicsServer3D::get_singleton()->body_set_force_integration_callback(get_rid(), this, "_direct_state_changed");
}
-KinematicBody3D::~KinematicBody3D() {
+KinematicBody3D::~KinematicBody3D() {
if (motion_cache.is_valid()) {
motion_cache->owner = nullptr;
}
@@ -1330,41 +1257,46 @@ KinematicBody3D::~KinematicBody3D() {
}
}
}
+
///////////////////////////////////////
Vector3 KinematicCollision3D::get_position() const {
-
return collision.collision;
}
+
Vector3 KinematicCollision3D::get_normal() const {
return collision.normal;
}
+
Vector3 KinematicCollision3D::get_travel() const {
return collision.travel;
}
+
Vector3 KinematicCollision3D::get_remainder() const {
return collision.remainder;
}
+
Object *KinematicCollision3D::get_local_shape() const {
- if (!owner) return nullptr;
+ if (!owner) {
+ return nullptr;
+ }
uint32_t ownerid = owner->shape_find_owner(collision.local_shape);
return owner->shape_owner_get_owner(ownerid);
}
Object *KinematicCollision3D::get_collider() const {
-
if (collision.collider.is_valid()) {
return ObjectDB::get_instance(collision.collider);
}
return nullptr;
}
-ObjectID KinematicCollision3D::get_collider_id() const {
+ObjectID KinematicCollision3D::get_collider_id() const {
return collision.collider;
}
-Object *KinematicCollision3D::get_collider_shape() const {
+Object *KinematicCollision3D::get_collider_shape() const {
Object *collider = get_collider();
if (collider) {
CollisionObject3D *obj2d = Object::cast_to<CollisionObject3D>(collider);
@@ -1376,21 +1308,20 @@ Object *KinematicCollision3D::get_collider_shape() const {
return nullptr;
}
-int KinematicCollision3D::get_collider_shape_index() const {
+int KinematicCollision3D::get_collider_shape_index() const {
return collision.collider_shape;
}
-Vector3 KinematicCollision3D::get_collider_velocity() const {
+Vector3 KinematicCollision3D::get_collider_velocity() const {
return collision.collider_vel;
}
-Variant KinematicCollision3D::get_collider_metadata() const {
+Variant KinematicCollision3D::get_collider_metadata() const {
return Variant();
}
void KinematicCollision3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_position"), &KinematicCollision3D::get_position);
ClassDB::bind_method(D_METHOD("get_normal"), &KinematicCollision3D::get_normal);
ClassDB::bind_method(D_METHOD("get_travel"), &KinematicCollision3D::get_travel);
@@ -1417,7 +1348,6 @@ void KinematicCollision3D::_bind_methods() {
}
KinematicCollision3D::KinematicCollision3D() {
-
collision.collider_shape = 0;
collision.local_shape = 0;
owner = nullptr;
@@ -1469,18 +1399,21 @@ bool PhysicalBone3D::PinJointData::_set(const StringName &p_name, const Variant
if ("joint_constraints/bias" == p_name) {
bias = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->pin_joint_set_param(j, PhysicsServer3D::PIN_JOINT_BIAS, bias);
+ }
} else if ("joint_constraints/damping" == p_name) {
damping = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->pin_joint_set_param(j, PhysicsServer3D::PIN_JOINT_DAMPING, damping);
+ }
} else if ("joint_constraints/impulse_clamp" == p_name) {
impulse_clamp = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->pin_joint_set_param(j, PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP, impulse_clamp);
+ }
} else {
return false;
@@ -1522,28 +1455,33 @@ bool PhysicalBone3D::ConeJointData::_set(const StringName &p_name, const Variant
if ("joint_constraints/swing_span" == p_name) {
swing_span = Math::deg2rad(real_t(p_value));
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN, swing_span);
+ }
} else if ("joint_constraints/twist_span" == p_name) {
twist_span = Math::deg2rad(real_t(p_value));
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN, twist_span);
+ }
} else if ("joint_constraints/bias" == p_name) {
bias = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_BIAS, bias);
+ }
} else if ("joint_constraints/softness" == p_name) {
softness = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_SOFTNESS, softness);
+ }
} else if ("joint_constraints/relaxation" == p_name) {
relaxation = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(j, PhysicsServer3D::CONE_TWIST_JOINT_RELAXATION, relaxation);
+ }
} else {
return false;
@@ -1591,33 +1529,39 @@ bool PhysicalBone3D::HingeJointData::_set(const StringName &p_name, const Varian
if ("joint_constraints/angular_limit_enabled" == p_name) {
angular_limit_enabled = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_flag(j, PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT, angular_limit_enabled);
+ }
} else if ("joint_constraints/angular_limit_upper" == p_name) {
angular_limit_upper = Math::deg2rad(real_t(p_value));
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER, angular_limit_upper);
+ }
} else if ("joint_constraints/angular_limit_lower" == p_name) {
angular_limit_lower = Math::deg2rad(real_t(p_value));
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER, angular_limit_lower);
+ }
} else if ("joint_constraints/angular_limit_bias" == p_name) {
angular_limit_bias = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS, angular_limit_bias);
+ }
} else if ("joint_constraints/angular_limit_softness" == p_name) {
angular_limit_softness = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS, angular_limit_softness);
+ }
} else if ("joint_constraints/angular_limit_relaxation" == p_name) {
angular_limit_relaxation = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_param(j, PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION, angular_limit_relaxation);
+ }
} else {
return false;
@@ -1668,53 +1612,63 @@ bool PhysicalBone3D::SliderJointData::_set(const StringName &p_name, const Varia
if ("joint_constraints/linear_limit_upper" == p_name) {
linear_limit_upper = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER, linear_limit_upper);
+ }
} else if ("joint_constraints/linear_limit_lower" == p_name) {
linear_limit_lower = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER, linear_limit_lower);
+ }
} else if ("joint_constraints/linear_limit_softness" == p_name) {
linear_limit_softness = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS, linear_limit_softness);
+ }
} else if ("joint_constraints/linear_limit_restitution" == p_name) {
linear_limit_restitution = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION, linear_limit_restitution);
+ }
} else if ("joint_constraints/linear_limit_damping" == p_name) {
linear_limit_damping = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING, linear_limit_restitution);
+ }
} else if ("joint_constraints/angular_limit_upper" == p_name) {
angular_limit_upper = Math::deg2rad(real_t(p_value));
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER, angular_limit_upper);
+ }
} else if ("joint_constraints/angular_limit_lower" == p_name) {
angular_limit_lower = Math::deg2rad(real_t(p_value));
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER, angular_limit_lower);
+ }
} else if ("joint_constraints/angular_limit_softness" == p_name) {
angular_limit_softness = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS, angular_limit_softness);
+ }
} else if ("joint_constraints/angular_limit_restitution" == p_name) {
angular_limit_restitution = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS, angular_limit_softness);
+ }
} else if ("joint_constraints/angular_limit_damping" == p_name) {
angular_limit_damping = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(j, PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING, angular_limit_damping);
+ }
} else {
return false;
@@ -1796,108 +1750,129 @@ bool PhysicalBone3D::SixDOFJointData::_set(const StringName &p_name, const Varia
if ("linear_limit_enabled" == var_name) {
axis_data[axis].linear_limit_enabled = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT, axis_data[axis].linear_limit_enabled);
+ }
} else if ("linear_limit_upper" == var_name) {
axis_data[axis].linear_limit_upper = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_UPPER_LIMIT, axis_data[axis].linear_limit_upper);
+ }
} else if ("linear_limit_lower" == var_name) {
axis_data[axis].linear_limit_lower = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT, axis_data[axis].linear_limit_lower);
+ }
} else if ("linear_limit_softness" == var_name) {
axis_data[axis].linear_limit_softness = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS, axis_data[axis].linear_limit_softness);
+ }
} else if ("linear_spring_enabled" == var_name) {
axis_data[axis].linear_spring_enabled = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_SPRING, axis_data[axis].linear_spring_enabled);
+ }
} else if ("linear_spring_stiffness" == var_name) {
axis_data[axis].linear_spring_stiffness = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_STIFFNESS, axis_data[axis].linear_spring_stiffness);
+ }
} else if ("linear_spring_damping" == var_name) {
axis_data[axis].linear_spring_damping = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_DAMPING, axis_data[axis].linear_spring_damping);
+ }
} else if ("linear_equilibrium_point" == var_name) {
axis_data[axis].linear_equilibrium_point = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_SPRING_EQUILIBRIUM_POINT, axis_data[axis].linear_equilibrium_point);
+ }
} else if ("linear_restitution" == var_name) {
axis_data[axis].linear_restitution = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_RESTITUTION, axis_data[axis].linear_restitution);
+ }
} else if ("linear_damping" == var_name) {
axis_data[axis].linear_damping = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_LINEAR_DAMPING, axis_data[axis].linear_damping);
+ }
} else if ("angular_limit_enabled" == var_name) {
axis_data[axis].angular_limit_enabled = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT, axis_data[axis].angular_limit_enabled);
+ }
} else if ("angular_limit_upper" == var_name) {
axis_data[axis].angular_limit_upper = Math::deg2rad(real_t(p_value));
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_UPPER_LIMIT, axis_data[axis].angular_limit_upper);
+ }
} else if ("angular_limit_lower" == var_name) {
axis_data[axis].angular_limit_lower = Math::deg2rad(real_t(p_value));
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_LOWER_LIMIT, axis_data[axis].angular_limit_lower);
+ }
} else if ("angular_limit_softness" == var_name) {
axis_data[axis].angular_limit_softness = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS, axis_data[axis].angular_limit_softness);
+ }
} else if ("angular_restitution" == var_name) {
axis_data[axis].angular_restitution = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_RESTITUTION, axis_data[axis].angular_restitution);
+ }
} else if ("angular_damping" == var_name) {
axis_data[axis].angular_damping = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_DAMPING, axis_data[axis].angular_damping);
+ }
} else if ("erp" == var_name) {
axis_data[axis].erp = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_ERP, axis_data[axis].erp);
+ }
} else if ("angular_spring_enabled" == var_name) {
axis_data[axis].angular_spring_enabled = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(j, axis, PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING, axis_data[axis].angular_spring_enabled);
+ }
} else if ("angular_spring_stiffness" == var_name) {
axis_data[axis].angular_spring_stiffness = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_STIFFNESS, axis_data[axis].angular_spring_stiffness);
+ }
} else if ("angular_spring_damping" == var_name) {
axis_data[axis].angular_spring_damping = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_DAMPING, axis_data[axis].angular_spring_damping);
+ }
} else if ("angular_equilibrium_point" == var_name) {
axis_data[axis].angular_equilibrium_point = p_value;
- if (j.is_valid())
+ if (j.is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(j, axis, PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT, axis_data[axis].angular_equilibrium_point);
+ }
} else {
return false;
@@ -2014,8 +1989,9 @@ bool PhysicalBone3D::_set(const StringName &p_name, const Variant &p_value) {
if (joint_data) {
if (joint_data->_set(p_name, p_value)) {
#ifdef TOOLS_ENABLED
- if (get_gizmo().is_valid())
+ if (get_gizmo().is_valid()) {
get_gizmo()->redraw();
+ }
#endif
return true;
}
@@ -2038,21 +2014,19 @@ bool PhysicalBone3D::_get(const StringName &p_name, Variant &r_ret) const {
}
void PhysicalBone3D::_get_property_list(List<PropertyInfo> *p_list) const {
-
Skeleton3D *parent = find_skeleton_parent(get_parent());
if (parent) {
-
String names;
for (int i = 0; i < parent->get_bone_count(); i++) {
- if (i > 0)
+ if (i > 0) {
names += ",";
+ }
names += parent->get_bone_name(i);
}
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "bone_name", PROPERTY_HINT_ENUM, names));
} else {
-
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "bone_name"));
}
@@ -2086,7 +2060,6 @@ void PhysicalBone3D::_notification(int p_what) {
break;
case NOTIFICATION_TRANSFORM_CHANGED:
if (Engine::get_singleton()->is_editor_hint()) {
-
update_offset();
}
break;
@@ -2094,7 +2067,6 @@ void PhysicalBone3D::_notification(int p_what) {
}
void PhysicalBone3D::_direct_state_changed(Object *p_state) {
-
if (!simulate_physics || !_internal_simulate_physics) {
return;
}
@@ -2224,8 +2196,9 @@ void PhysicalBone3D::_update_joint_offset() {
set_ignore_transform_notification(false);
#ifdef TOOLS_ENABLED
- if (get_gizmo().is_valid())
+ if (get_gizmo().is_valid()) {
get_gizmo()->redraw();
+ }
#endif
}
@@ -2237,7 +2210,6 @@ void PhysicalBone3D::_fix_joint_offset() {
}
void PhysicalBone3D::_reload_joint() {
-
if (joint.is_valid()) {
PhysicsServer3D::get_singleton()->free(joint);
joint = RID();
@@ -2258,7 +2230,6 @@ void PhysicalBone3D::_reload_joint() {
switch (get_joint_type()) {
case JOINT_TYPE_PIN: {
-
joint = PhysicsServer3D::get_singleton()->joint_create_pin(body_a->get_rid(), local_a.origin, get_rid(), joint_offset.origin);
const PinJointData *pjd(static_cast<const PinJointData *>(joint_data));
PhysicsServer3D::get_singleton()->pin_joint_set_param(joint, PhysicsServer3D::PIN_JOINT_BIAS, pjd->bias);
@@ -2267,7 +2238,6 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_CONE: {
-
joint = PhysicsServer3D::get_singleton()->joint_create_cone_twist(body_a->get_rid(), local_a, get_rid(), joint_offset);
const ConeJointData *cjd(static_cast<const ConeJointData *>(joint_data));
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(joint, PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN, cjd->swing_span);
@@ -2278,7 +2248,6 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_HINGE: {
-
joint = PhysicsServer3D::get_singleton()->joint_create_hinge(body_a->get_rid(), local_a, get_rid(), joint_offset);
const HingeJointData *hjd(static_cast<const HingeJointData *>(joint_data));
PhysicsServer3D::get_singleton()->hinge_joint_set_flag(joint, PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT, hjd->angular_limit_enabled);
@@ -2290,7 +2259,6 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_SLIDER: {
-
joint = PhysicsServer3D::get_singleton()->joint_create_slider(body_a->get_rid(), local_a, get_rid(), joint_offset);
const SliderJointData *sjd(static_cast<const SliderJointData *>(joint_data));
PhysicsServer3D::get_singleton()->slider_joint_set_param(joint, PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER, sjd->linear_limit_upper);
@@ -2306,7 +2274,6 @@ void PhysicalBone3D::_reload_joint() {
} break;
case JOINT_TYPE_6DOF: {
-
joint = PhysicsServer3D::get_singleton()->joint_create_generic_6dof(body_a->get_rid(), local_a, get_rid(), joint_offset);
const SixDOFJointData *g6dofjd(static_cast<const SixDOFJointData *>(joint_data));
for (int axis = 0; axis < 3; ++axis) {
@@ -2369,12 +2336,13 @@ Skeleton3D *PhysicalBone3D::find_skeleton_parent() {
}
void PhysicalBone3D::set_joint_type(JointType p_joint_type) {
-
- if (p_joint_type == get_joint_type())
+ if (p_joint_type == get_joint_type()) {
return;
+ }
- if (joint_data)
+ if (joint_data) {
memdelete(joint_data);
+ }
joint_data = nullptr;
switch (p_joint_type) {
case JOINT_TYPE_PIN:
@@ -2400,8 +2368,9 @@ void PhysicalBone3D::set_joint_type(JointType p_joint_type) {
#ifdef TOOLS_ENABLED
_change_notify();
- if (get_gizmo().is_valid())
+ if (get_gizmo().is_valid()) {
get_gizmo()->redraw();
+ }
#endif
}
@@ -2468,7 +2437,6 @@ bool PhysicalBone3D::is_simulating_physics() {
}
void PhysicalBone3D::set_bone_name(const String &p_name) {
-
bone_name = p_name;
bone_id = -1;
@@ -2477,34 +2445,28 @@ void PhysicalBone3D::set_bone_name(const String &p_name) {
}
const String &PhysicalBone3D::get_bone_name() const {
-
return bone_name;
}
void PhysicalBone3D::set_mass(real_t p_mass) {
-
ERR_FAIL_COND(p_mass <= 0);
mass = p_mass;
PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_MASS, mass);
}
real_t PhysicalBone3D::get_mass() const {
-
return mass;
}
void PhysicalBone3D::set_weight(real_t p_weight) {
-
set_mass(p_weight / real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8)));
}
real_t PhysicalBone3D::get_weight() const {
-
return mass * real_t(GLOBAL_DEF("physics/3d/default_gravity", 9.8));
}
void PhysicalBone3D::set_friction(real_t p_friction) {
-
ERR_FAIL_COND(p_friction < 0 || p_friction > 1);
friction = p_friction;
@@ -2512,12 +2474,10 @@ void PhysicalBone3D::set_friction(real_t p_friction) {
}
real_t PhysicalBone3D::get_friction() const {
-
return friction;
}
void PhysicalBone3D::set_bounce(real_t p_bounce) {
-
ERR_FAIL_COND(p_bounce < 0 || p_bounce > 1);
bounce = p_bounce;
@@ -2525,18 +2485,15 @@ void PhysicalBone3D::set_bounce(real_t p_bounce) {
}
real_t PhysicalBone3D::get_bounce() const {
-
return bounce;
}
void PhysicalBone3D::set_gravity_scale(real_t p_gravity_scale) {
-
gravity_scale = p_gravity_scale;
PhysicsServer3D::get_singleton()->body_set_param(get_rid(), PhysicsServer3D::BODY_PARAM_GRAVITY_SCALE, gravity_scale);
}
real_t PhysicalBone3D::get_gravity_scale() const {
-
return gravity_scale;
}
@@ -2578,30 +2535,14 @@ bool PhysicalBone3D::get_axis_lock(PhysicsServer3D::BodyAxis p_axis) const {
}
PhysicalBone3D::PhysicalBone3D() :
- PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC),
-#ifdef TOOLS_ENABLED
- gizmo_move_joint(false),
-#endif
- joint_data(nullptr),
- parent_skeleton(nullptr),
- simulate_physics(false),
- _internal_simulate_physics(false),
- bone_id(-1),
- bone_name(""),
- bounce(0),
- mass(1),
- friction(1),
- gravity_scale(1),
- linear_damp(-1),
- angular_damp(-1),
- can_sleep(true) {
-
+ PhysicsBody3D(PhysicsServer3D::BODY_MODE_STATIC) {
reset_physics_simulation_state();
}
PhysicalBone3D::~PhysicalBone3D() {
- if (joint_data)
+ if (joint_data) {
memdelete(joint_data);
+ }
}
void PhysicalBone3D::update_bone_id() {
@@ -2630,10 +2571,10 @@ void PhysicalBone3D::update_bone_id() {
void PhysicalBone3D::update_offset() {
#ifdef TOOLS_ENABLED
if (parent_skeleton) {
-
Transform bone_transform(parent_skeleton->get_global_transform());
- if (-1 != bone_id)
+ if (-1 != bone_id) {
bone_transform *= parent_skeleton->get_bone_global_pose(bone_id);
+ }
if (gizmo_move_joint) {
bone_transform *= body_offset;
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index 2e71020233..4c58c73942 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -38,7 +38,6 @@
#include "skeleton_3d.h"
class PhysicsBody3D : public CollisionObject3D {
-
GDCLASS(PhysicsBody3D, CollisionObject3D);
uint32_t collision_layer;
@@ -68,7 +67,7 @@ public:
void set_collision_mask_bit(int p_bit, bool p_value);
bool get_collision_mask_bit(int p_bit) const;
- Array get_collision_exceptions();
+ TypedArray<PhysicsBody3D> get_collision_exceptions();
void add_collision_exception_with(Node *p_node); //must be physicsbody
void remove_collision_exception_with(Node *p_node);
@@ -76,7 +75,6 @@ public:
};
class StaticBody3D : public PhysicsBody3D {
-
GDCLASS(StaticBody3D, PhysicsBody3D);
Vector3 constant_linear_velocity;
@@ -105,7 +103,6 @@ private:
};
class RigidBody3D : public PhysicsBody3D {
-
GDCLASS(RigidBody3D, PhysicsBody3D);
public:
@@ -138,15 +135,15 @@ protected:
bool custom_integrator;
struct ShapePair {
-
int body_shape;
int local_shape;
bool tagged;
bool operator<(const ShapePair &p_sp) const {
- if (body_shape == p_sp.body_shape)
+ if (body_shape == p_sp.body_shape) {
return local_shape < p_sp.local_shape;
- else
+ } else {
return body_shape < p_sp.body_shape;
+ }
}
ShapePair() {}
@@ -157,19 +154,16 @@ protected:
}
};
struct RigidBody3D_RemoveAction {
-
ObjectID body_id;
ShapePair pair;
};
struct BodyState {
-
//int rc;
bool in_tree;
VSet<ShapePair> shapes;
};
struct ContactMonitor {
-
bool locked;
Map<ObjectID, BodyState> body_map;
};
@@ -261,7 +255,6 @@ VARIANT_ENUM_CAST(RigidBody3D::Mode);
class KinematicCollision3D;
class KinematicBody3D : public PhysicsBody3D {
-
GDCLASS(KinematicBody3D, PhysicsBody3D);
public:
@@ -338,7 +331,6 @@ public:
};
class KinematicCollision3D : public Reference {
-
GDCLASS(KinematicCollision3D, Reference);
KinematicBody3D *owner;
@@ -365,7 +357,6 @@ public:
};
class PhysicalBone3D : public PhysicsBody3D {
-
GDCLASS(PhysicalBone3D, PhysicsBody3D);
public:
@@ -396,14 +387,11 @@ public:
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
- real_t bias;
- real_t damping;
- real_t impulse_clamp;
+ real_t bias = 0.3;
+ real_t damping = 1.;
+ real_t impulse_clamp = 0;
- PinJointData() :
- bias(0.3),
- damping(1.),
- impulse_clamp(0) {}
+ PinJointData() {}
};
struct ConeJointData : public JointData {
@@ -414,17 +402,13 @@ public:
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
real_t swing_span;
- real_t twist_span;
- real_t bias;
- real_t softness;
- real_t relaxation;
+ real_t twist_span = Math_PI;
+ real_t bias = 0.3;
+ real_t softness = 0.8;
+ real_t relaxation = 1.;
ConeJointData() :
- swing_span(Math_PI * 0.25),
- twist_span(Math_PI),
- bias(0.3),
- softness(0.8),
- relaxation(1.) {}
+ swing_span(Math_PI * 0.25) {}
};
struct HingeJointData : public JointData {
@@ -434,20 +418,17 @@ public:
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
- bool angular_limit_enabled;
+ bool angular_limit_enabled = false;
real_t angular_limit_upper;
real_t angular_limit_lower;
- real_t angular_limit_bias;
- real_t angular_limit_softness;
- real_t angular_limit_relaxation;
+ real_t angular_limit_bias = 0.3;
+ real_t angular_limit_softness = 0.9;
+ real_t angular_limit_relaxation = 1.;
HingeJointData() :
- angular_limit_enabled(false),
+
angular_limit_upper(Math_PI * 0.5),
- angular_limit_lower(-Math_PI * 0.5),
- angular_limit_bias(0.3),
- angular_limit_softness(0.9),
- angular_limit_relaxation(1.) {}
+ angular_limit_lower(-Math_PI * 0.5) {}
};
struct SliderJointData : public JointData {
@@ -457,76 +438,45 @@ public:
virtual bool _get(const StringName &p_name, Variant &r_ret) const;
virtual void _get_property_list(List<PropertyInfo> *p_list) const;
- real_t linear_limit_upper;
- real_t linear_limit_lower;
- real_t linear_limit_softness;
- real_t linear_limit_restitution;
- real_t linear_limit_damping;
- real_t angular_limit_upper;
- real_t angular_limit_lower;
- real_t angular_limit_softness;
- real_t angular_limit_restitution;
- real_t angular_limit_damping;
-
- SliderJointData() :
- linear_limit_upper(1.),
- linear_limit_lower(-1.),
- linear_limit_softness(1.),
- linear_limit_restitution(0.7),
- linear_limit_damping(1.),
- angular_limit_upper(0),
- angular_limit_lower(0),
- angular_limit_softness(1.),
- angular_limit_restitution(0.7),
- angular_limit_damping(1.) {}
+ real_t linear_limit_upper = 1.;
+ real_t linear_limit_lower = -1.;
+ real_t linear_limit_softness = 1.;
+ real_t linear_limit_restitution = 0.7;
+ real_t linear_limit_damping = 1.;
+ real_t angular_limit_upper = 0;
+ real_t angular_limit_lower = 0;
+ real_t angular_limit_softness = 1.;
+ real_t angular_limit_restitution = 0.7;
+ real_t angular_limit_damping = 1.;
+
+ SliderJointData() {}
};
struct SixDOFJointData : public JointData {
struct SixDOFAxisData {
- bool linear_limit_enabled;
- real_t linear_limit_upper;
- real_t linear_limit_lower;
- real_t linear_limit_softness;
- real_t linear_restitution;
- real_t linear_damping;
- bool linear_spring_enabled;
- real_t linear_spring_stiffness;
- real_t linear_spring_damping;
- real_t linear_equilibrium_point;
- bool angular_limit_enabled;
- real_t angular_limit_upper;
- real_t angular_limit_lower;
- real_t angular_limit_softness;
- real_t angular_restitution;
- real_t angular_damping;
- real_t erp;
- bool angular_spring_enabled;
- real_t angular_spring_stiffness;
- real_t angular_spring_damping;
- real_t angular_equilibrium_point;
-
- SixDOFAxisData() :
- linear_limit_enabled(true),
- linear_limit_upper(0),
- linear_limit_lower(0),
- linear_limit_softness(0.7),
- linear_restitution(0.5),
- linear_damping(1.),
- linear_spring_enabled(false),
- linear_spring_stiffness(0),
- linear_spring_damping(0),
- linear_equilibrium_point(0),
- angular_limit_enabled(true),
- angular_limit_upper(0),
- angular_limit_lower(0),
- angular_limit_softness(0.5),
- angular_restitution(0),
- angular_damping(1.),
- erp(0.5),
- angular_spring_enabled(false),
- angular_spring_stiffness(0),
- angular_spring_damping(0.),
- angular_equilibrium_point(0) {}
+ bool linear_limit_enabled = true;
+ real_t linear_limit_upper = 0;
+ real_t linear_limit_lower = 0;
+ real_t linear_limit_softness = 0.7;
+ real_t linear_restitution = 0.5;
+ real_t linear_damping = 1.;
+ bool linear_spring_enabled = false;
+ real_t linear_spring_stiffness = 0;
+ real_t linear_spring_damping = 0;
+ real_t linear_equilibrium_point = 0;
+ bool angular_limit_enabled = true;
+ real_t angular_limit_upper = 0;
+ real_t angular_limit_lower = 0;
+ real_t angular_limit_softness = 0.5;
+ real_t angular_restitution = 0;
+ real_t angular_damping = 1.;
+ real_t erp = 0.5;
+ bool angular_spring_enabled = false;
+ real_t angular_spring_stiffness = 0;
+ real_t angular_spring_damping = 0.;
+ real_t angular_equilibrium_point = 0;
+
+ SixDOFAxisData() {}
};
virtual JointType get_joint_type() { return JOINT_TYPE_6DOF; }
@@ -543,28 +493,28 @@ public:
private:
#ifdef TOOLS_ENABLED
// if false gizmo move body
- bool gizmo_move_joint;
+ bool gizmo_move_joint = false;
#endif
- JointData *joint_data;
+ JointData *joint_data = nullptr;
Transform joint_offset;
RID joint;
- Skeleton3D *parent_skeleton;
+ Skeleton3D *parent_skeleton = nullptr;
Transform body_offset;
Transform body_offset_inverse;
- bool simulate_physics;
- bool _internal_simulate_physics;
- int bone_id;
+ bool simulate_physics = false;
+ bool _internal_simulate_physics = false;
+ int bone_id = -1;
String bone_name;
- real_t bounce;
- real_t mass;
- real_t friction;
- real_t gravity_scale;
- real_t linear_damp;
- real_t angular_damp;
- bool can_sleep;
+ real_t bounce = 0;
+ real_t mass = 1;
+ real_t friction = 1;
+ real_t gravity_scale = 1;
+ real_t linear_damp = -1;
+ real_t angular_damp = -1;
+ bool can_sleep = true;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
diff --git a/scene/3d/physics_joint_3d.cpp b/scene/3d/physics_joint_3d.cpp
index 591c17a91e..af4d6ae152 100644
--- a/scene/3d/physics_joint_3d.cpp
+++ b/scene/3d/physics_joint_3d.cpp
@@ -31,10 +31,10 @@
#include "physics_joint_3d.h"
void Joint3D::_update_joint(bool p_only_free) {
-
if (joint.is_valid()) {
- if (ba.is_valid() && bb.is_valid())
+ if (ba.is_valid() && bb.is_valid()) {
PhysicsServer3D::get_singleton()->body_remove_collision_exception(ba, bb);
+ }
PhysicsServer3D::get_singleton()->free(joint);
joint = RID();
@@ -42,8 +42,9 @@ void Joint3D::_update_joint(bool p_only_free) {
bb = RID();
}
- if (p_only_free || !is_inside_tree())
+ if (p_only_free || !is_inside_tree()) {
return;
+ }
Node *node_a = has_node(get_node_a()) ? get_node(get_node_a()) : (Node *)nullptr;
Node *node_b = has_node(get_node_b()) ? get_node(get_node_b()) : (Node *)nullptr;
@@ -51,68 +52,68 @@ void Joint3D::_update_joint(bool p_only_free) {
PhysicsBody3D *body_a = Object::cast_to<PhysicsBody3D>(node_a);
PhysicsBody3D *body_b = Object::cast_to<PhysicsBody3D>(node_b);
- if (!body_a && body_b)
+ if (!body_a && body_b) {
SWAP(body_a, body_b);
+ }
- if (!body_a)
+ if (!body_a) {
return;
+ }
joint = _configure_joint(body_a, body_b);
- if (!joint.is_valid())
+ if (!joint.is_valid()) {
return;
+ }
PhysicsServer3D::get_singleton()->joint_set_solver_priority(joint, solver_priority);
ba = body_a->get_rid();
- if (body_b)
+ if (body_b) {
bb = body_b->get_rid();
+ }
PhysicsServer3D::get_singleton()->joint_disable_collisions_between_bodies(joint, exclude_from_collision);
}
void Joint3D::set_node_a(const NodePath &p_node_a) {
-
- if (a == p_node_a)
+ if (a == p_node_a) {
return;
+ }
a = p_node_a;
_update_joint();
}
NodePath Joint3D::get_node_a() const {
-
return a;
}
void Joint3D::set_node_b(const NodePath &p_node_b) {
-
- if (b == p_node_b)
+ if (b == p_node_b) {
return;
+ }
b = p_node_b;
_update_joint();
}
-NodePath Joint3D::get_node_b() const {
+NodePath Joint3D::get_node_b() const {
return b;
}
void Joint3D::set_solver_priority(int p_priority) {
-
solver_priority = p_priority;
- if (joint.is_valid())
+ if (joint.is_valid()) {
PhysicsServer3D::get_singleton()->joint_set_solver_priority(joint, solver_priority);
+ }
}
int Joint3D::get_solver_priority() const {
-
return solver_priority;
}
void Joint3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_READY: {
_update_joint();
} break;
@@ -125,20 +126,18 @@ void Joint3D::_notification(int p_what) {
}
void Joint3D::set_exclude_nodes_from_collision(bool p_enable) {
-
- if (exclude_from_collision == p_enable)
+ if (exclude_from_collision == p_enable) {
return;
+ }
exclude_from_collision = p_enable;
_update_joint();
}
bool Joint3D::get_exclude_nodes_from_collision() const {
-
return exclude_from_collision;
}
void Joint3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_node_a", "node"), &Joint3D::set_node_a);
ClassDB::bind_method(D_METHOD("get_node_a"), &Joint3D::get_node_a);
@@ -159,7 +158,6 @@ void Joint3D::_bind_methods() {
}
Joint3D::Joint3D() {
-
exclude_from_collision = true;
solver_priority = 1;
set_notify_transform(true);
@@ -168,7 +166,6 @@ Joint3D::Joint3D() {
///////////////////////////////////
void PinJoint3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &PinJoint3D::set_param);
ClassDB::bind_method(D_METHOD("get_param", "param"), &PinJoint3D::get_param);
@@ -182,28 +179,28 @@ void PinJoint3D::_bind_methods() {
}
void PinJoint3D::set_param(Param p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, 3);
params[p_param] = p_value;
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer3D::get_singleton()->pin_joint_set_param(get_joint(), PhysicsServer3D::PinJointParam(p_param), p_value);
+ }
}
-float PinJoint3D::get_param(Param p_param) const {
+float PinJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, 3, 0);
return params[p_param];
}
RID PinJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
-
Vector3 pinpos = get_global_transform().origin;
Vector3 local_a = body_a->get_global_transform().affine_inverse().xform(pinpos);
Vector3 local_b;
- if (body_b)
+ if (body_b) {
local_b = body_b->get_global_transform().affine_inverse().xform(pinpos);
- else
+ } else {
local_b = pinpos;
+ }
RID j = PhysicsServer3D::get_singleton()->joint_create_pin(body_a->get_rid(), local_a, body_b ? body_b->get_rid() : RID(), local_b);
for (int i = 0; i < 3; i++) {
@@ -213,7 +210,6 @@ RID PinJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
}
PinJoint3D::PinJoint3D() {
-
params[PARAM_BIAS] = 0.3;
params[PARAM_DAMPING] = 1;
params[PARAM_IMPULSE_CLAMP] = 0;
@@ -224,27 +220,22 @@ PinJoint3D::PinJoint3D() {
///////////////////////////////////
void HingeJoint3D::_set_upper_limit(float p_limit) {
-
set_param(PARAM_LIMIT_UPPER, Math::deg2rad(p_limit));
}
float HingeJoint3D::_get_upper_limit() const {
-
return Math::rad2deg(get_param(PARAM_LIMIT_UPPER));
}
void HingeJoint3D::_set_lower_limit(float p_limit) {
-
set_param(PARAM_LIMIT_LOWER, Math::deg2rad(p_limit));
}
float HingeJoint3D::_get_lower_limit() const {
-
return Math::rad2deg(get_param(PARAM_LIMIT_LOWER));
}
void HingeJoint3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &HingeJoint3D::set_param);
ClassDB::bind_method(D_METHOD("get_param", "param"), &HingeJoint3D::get_param);
@@ -286,37 +277,36 @@ void HingeJoint3D::_bind_methods() {
}
void HingeJoint3D::set_param(Param p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params[p_param] = p_value;
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_param(get_joint(), PhysicsServer3D::HingeJointParam(p_param), p_value);
+ }
update_gizmo();
}
-float HingeJoint3D::get_param(Param p_param) const {
+float HingeJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params[p_param];
}
void HingeJoint3D::set_flag(Flag p_flag, bool p_value) {
-
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags[p_flag] = p_value;
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer3D::get_singleton()->hinge_joint_set_flag(get_joint(), PhysicsServer3D::HingeJointFlag(p_flag), p_value);
+ }
update_gizmo();
}
-bool HingeJoint3D::get_flag(Flag p_flag) const {
+bool HingeJoint3D::get_flag(Flag p_flag) const {
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
return flags[p_flag];
}
RID HingeJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
-
Transform gt = get_global_transform();
Transform ainv = body_a->get_global_transform().affine_inverse();
@@ -343,7 +333,6 @@ RID HingeJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b)
}
HingeJoint3D::HingeJoint3D() {
-
params[PARAM_BIAS] = 0.3;
params[PARAM_LIMIT_UPPER] = Math_PI * 0.5;
params[PARAM_LIMIT_LOWER] = -Math_PI * 0.5;
@@ -362,27 +351,22 @@ HingeJoint3D::HingeJoint3D() {
//////////////////////////////////
void SliderJoint3D::_set_upper_limit_angular(float p_limit_angular) {
-
set_param(PARAM_ANGULAR_LIMIT_UPPER, Math::deg2rad(p_limit_angular));
}
float SliderJoint3D::_get_upper_limit_angular() const {
-
return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_UPPER));
}
void SliderJoint3D::_set_lower_limit_angular(float p_limit_angular) {
-
set_param(PARAM_ANGULAR_LIMIT_LOWER, Math::deg2rad(p_limit_angular));
}
float SliderJoint3D::_get_lower_limit_angular() const {
-
return Math::rad2deg(get_param(PARAM_ANGULAR_LIMIT_LOWER));
}
void SliderJoint3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &SliderJoint3D::set_param);
ClassDB::bind_method(D_METHOD("get_param", "param"), &SliderJoint3D::get_param);
@@ -444,21 +428,20 @@ void SliderJoint3D::_bind_methods() {
}
void SliderJoint3D::set_param(Param p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params[p_param] = p_value;
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer3D::get_singleton()->slider_joint_set_param(get_joint(), PhysicsServer3D::SliderJointParam(p_param), p_value);
+ }
update_gizmo();
}
-float SliderJoint3D::get_param(Param p_param) const {
+float SliderJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params[p_param];
}
RID SliderJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
-
Transform gt = get_global_transform();
Transform ainv = body_a->get_global_transform().affine_inverse();
@@ -482,7 +465,6 @@ RID SliderJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b
}
SliderJoint3D::SliderJoint3D() {
-
params[PARAM_LINEAR_LIMIT_UPPER] = 1.0;
params[PARAM_LINEAR_LIMIT_LOWER] = -1.0;
params[PARAM_LINEAR_LIMIT_SOFTNESS] = 1.0;
@@ -511,27 +493,22 @@ SliderJoint3D::SliderJoint3D() {
//////////////////////////////////
void ConeTwistJoint3D::_set_swing_span(float p_limit_angular) {
-
set_param(PARAM_SWING_SPAN, Math::deg2rad(p_limit_angular));
}
float ConeTwistJoint3D::_get_swing_span() const {
-
return Math::rad2deg(get_param(PARAM_SWING_SPAN));
}
void ConeTwistJoint3D::_set_twist_span(float p_limit_angular) {
-
set_param(PARAM_TWIST_SPAN, Math::deg2rad(p_limit_angular));
}
float ConeTwistJoint3D::_get_twist_span() const {
-
return Math::rad2deg(get_param(PARAM_TWIST_SPAN));
}
void ConeTwistJoint3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &ConeTwistJoint3D::set_param);
ClassDB::bind_method(D_METHOD("get_param", "param"), &ConeTwistJoint3D::get_param);
@@ -557,22 +534,21 @@ void ConeTwistJoint3D::_bind_methods() {
}
void ConeTwistJoint3D::set_param(Param p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params[p_param] = p_value;
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer3D::get_singleton()->cone_twist_joint_set_param(get_joint(), PhysicsServer3D::ConeTwistJointParam(p_param), p_value);
+ }
update_gizmo();
}
-float ConeTwistJoint3D::get_param(Param p_param) const {
+float ConeTwistJoint3D::get_param(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params[p_param];
}
RID ConeTwistJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
-
Transform gt = get_global_transform();
//Vector3 cone_twistpos = gt.origin;
//Vector3 cone_twistdir = gt.basis.get_axis(2);
@@ -599,7 +575,6 @@ RID ConeTwistJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *bod
}
ConeTwistJoint3D::ConeTwistJoint3D() {
-
params[PARAM_SWING_SPAN] = Math_PI * 0.25;
params[PARAM_TWIST_SPAN] = Math_PI;
params[PARAM_BIAS] = 0.3;
@@ -610,67 +585,54 @@ ConeTwistJoint3D::ConeTwistJoint3D() {
/////////////////////////////////////////////////////////////////////
void Generic6DOFJoint3D::_set_angular_hi_limit_x(float p_limit_angular) {
-
set_param_x(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular));
}
float Generic6DOFJoint3D::_get_angular_hi_limit_x() const {
-
return Math::rad2deg(get_param_x(PARAM_ANGULAR_UPPER_LIMIT));
}
void Generic6DOFJoint3D::_set_angular_lo_limit_x(float p_limit_angular) {
-
set_param_x(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular));
}
float Generic6DOFJoint3D::_get_angular_lo_limit_x() const {
-
return Math::rad2deg(get_param_x(PARAM_ANGULAR_LOWER_LIMIT));
}
void Generic6DOFJoint3D::_set_angular_hi_limit_y(float p_limit_angular) {
-
set_param_y(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular));
}
float Generic6DOFJoint3D::_get_angular_hi_limit_y() const {
-
return Math::rad2deg(get_param_y(PARAM_ANGULAR_UPPER_LIMIT));
}
void Generic6DOFJoint3D::_set_angular_lo_limit_y(float p_limit_angular) {
-
set_param_y(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular));
}
float Generic6DOFJoint3D::_get_angular_lo_limit_y() const {
-
return Math::rad2deg(get_param_y(PARAM_ANGULAR_LOWER_LIMIT));
}
void Generic6DOFJoint3D::_set_angular_hi_limit_z(float p_limit_angular) {
-
set_param_z(PARAM_ANGULAR_UPPER_LIMIT, Math::deg2rad(p_limit_angular));
}
float Generic6DOFJoint3D::_get_angular_hi_limit_z() const {
-
return Math::rad2deg(get_param_z(PARAM_ANGULAR_UPPER_LIMIT));
}
void Generic6DOFJoint3D::_set_angular_lo_limit_z(float p_limit_angular) {
-
set_param_z(PARAM_ANGULAR_LOWER_LIMIT, Math::deg2rad(p_limit_angular));
}
float Generic6DOFJoint3D::_get_angular_lo_limit_z() const {
-
return Math::rad2deg(get_param_z(PARAM_ANGULAR_LOWER_LIMIT));
}
void Generic6DOFJoint3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_set_angular_hi_limit_x", "angle"), &Generic6DOFJoint3D::_set_angular_hi_limit_x);
ClassDB::bind_method(D_METHOD("_get_angular_hi_limit_x"), &Generic6DOFJoint3D::_get_angular_hi_limit_x);
@@ -807,6 +769,9 @@ void Generic6DOFJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_LINEAR_DAMPING);
BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTOR_TARGET_VELOCITY);
BIND_ENUM_CONSTANT(PARAM_LINEAR_MOTOR_FORCE_LIMIT);
+ BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_STIFFNESS);
+ BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_DAMPING);
+ BIND_ENUM_CONSTANT(PARAM_LINEAR_SPRING_EQUILIBRIUM_POINT);
BIND_ENUM_CONSTANT(PARAM_ANGULAR_LOWER_LIMIT);
BIND_ENUM_CONSTANT(PARAM_ANGULAR_UPPER_LIMIT);
BIND_ENUM_CONSTANT(PARAM_ANGULAR_LIMIT_SOFTNESS);
@@ -816,6 +781,9 @@ void Generic6DOFJoint3D::_bind_methods() {
BIND_ENUM_CONSTANT(PARAM_ANGULAR_ERP);
BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTOR_TARGET_VELOCITY);
BIND_ENUM_CONSTANT(PARAM_ANGULAR_MOTOR_FORCE_LIMIT);
+ BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_STIFFNESS);
+ BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_DAMPING);
+ BIND_ENUM_CONSTANT(PARAM_ANGULAR_SPRING_EQUILIBRIUM_POINT);
BIND_ENUM_CONSTANT(PARAM_MAX);
BIND_ENUM_CONSTANT(FLAG_ENABLE_LINEAR_LIMIT);
@@ -828,86 +796,86 @@ void Generic6DOFJoint3D::_bind_methods() {
}
void Generic6DOFJoint3D::set_param_x(Param p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params_x[p_param] = p_value;
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
+ }
update_gizmo();
}
-float Generic6DOFJoint3D::get_param_x(Param p_param) const {
+float Generic6DOFJoint3D::get_param_x(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params_x[p_param];
}
void Generic6DOFJoint3D::set_param_y(Param p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params_y[p_param] = p_value;
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
+ }
update_gizmo();
}
-float Generic6DOFJoint3D::get_param_y(Param p_param) const {
+float Generic6DOFJoint3D::get_param_y(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params_y[p_param];
}
void Generic6DOFJoint3D::set_param_z(Param p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
params_z[p_param] = p_value;
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_param(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisParam(p_param), p_value);
+ }
update_gizmo();
}
-float Generic6DOFJoint3D::get_param_z(Param p_param) const {
+float Generic6DOFJoint3D::get_param_z(Param p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return params_z[p_param];
}
void Generic6DOFJoint3D::set_flag_x(Flag p_flag, bool p_enabled) {
-
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags_x[p_flag] = p_enabled;
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_X, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
+ }
update_gizmo();
}
-bool Generic6DOFJoint3D::get_flag_x(Flag p_flag) const {
+bool Generic6DOFJoint3D::get_flag_x(Flag p_flag) const {
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
return flags_x[p_flag];
}
void Generic6DOFJoint3D::set_flag_y(Flag p_flag, bool p_enabled) {
-
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags_y[p_flag] = p_enabled;
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Y, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
+ }
update_gizmo();
}
-bool Generic6DOFJoint3D::get_flag_y(Flag p_flag) const {
+bool Generic6DOFJoint3D::get_flag_y(Flag p_flag) const {
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
return flags_y[p_flag];
}
void Generic6DOFJoint3D::set_flag_z(Flag p_flag, bool p_enabled) {
-
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags_z[p_flag] = p_enabled;
- if (get_joint().is_valid())
+ if (get_joint().is_valid()) {
PhysicsServer3D::get_singleton()->generic_6dof_joint_set_flag(get_joint(), Vector3::AXIS_Z, PhysicsServer3D::G6DOFJointAxisFlag(p_flag), p_enabled);
+ }
update_gizmo();
}
-bool Generic6DOFJoint3D::get_flag_z(Flag p_flag) const {
+bool Generic6DOFJoint3D::get_flag_z(Flag p_flag) const {
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
return flags_z[p_flag];
}
@@ -921,7 +889,6 @@ void Generic6DOFJoint3D::set_precision(int p_precision) {
}
RID Generic6DOFJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b) {
-
Transform gt = get_global_transform();
//Vector3 cone_twistpos = gt.origin;
//Vector3 cone_twistdir = gt.basis.get_axis(2);
@@ -954,9 +921,7 @@ RID Generic6DOFJoint3D::_configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *b
return j;
}
-Generic6DOFJoint3D::Generic6DOFJoint3D() :
- precision(1) {
-
+Generic6DOFJoint3D::Generic6DOFJoint3D() {
set_param_x(PARAM_LINEAR_LOWER_LIMIT, 0);
set_param_x(PARAM_LINEAR_UPPER_LIMIT, 0);
set_param_x(PARAM_LINEAR_LIMIT_SOFTNESS, 0.7);
diff --git a/scene/3d/physics_joint_3d.h b/scene/3d/physics_joint_3d.h
index ce0c7af5d1..a3225ab01c 100644
--- a/scene/3d/physics_joint_3d.h
+++ b/scene/3d/physics_joint_3d.h
@@ -35,7 +35,6 @@
#include "scene/3d/physics_body_3d.h"
class Joint3D : public Node3D {
-
GDCLASS(Joint3D, Node3D);
RID ba, bb;
@@ -77,7 +76,6 @@ public:
///////////////////////////////////////////
class PinJoint3D : public Joint3D {
-
GDCLASS(PinJoint3D, Joint3D);
public:
@@ -102,7 +100,6 @@ public:
VARIANT_ENUM_CAST(PinJoint3D::Param);
class HingeJoint3D : public Joint3D {
-
GDCLASS(HingeJoint3D, Joint3D);
public:
@@ -150,7 +147,6 @@ VARIANT_ENUM_CAST(HingeJoint3D::Param);
VARIANT_ENUM_CAST(HingeJoint3D::Flag);
class SliderJoint3D : public Joint3D {
-
GDCLASS(SliderJoint3D, Joint3D);
public:
@@ -203,7 +199,6 @@ public:
VARIANT_ENUM_CAST(SliderJoint3D::Param);
class ConeTwistJoint3D : public Joint3D {
-
GDCLASS(ConeTwistJoint3D, Joint3D);
public:
@@ -238,7 +233,6 @@ public:
VARIANT_ENUM_CAST(ConeTwistJoint3D::Param);
class Generic6DOFJoint3D : public Joint3D {
-
GDCLASS(Generic6DOFJoint3D, Joint3D);
public:
@@ -305,7 +299,7 @@ protected:
float params_z[PARAM_MAX];
bool flags_z[FLAG_MAX];
- int precision;
+ int precision = 1;
virtual RID _configure_joint(PhysicsBody3D *body_a, PhysicsBody3D *body_b);
static void _bind_methods();
diff --git a/scene/3d/position_3d.h b/scene/3d/position_3d.h
index 9c806723fb..1c5f05ef95 100644
--- a/scene/3d/position_3d.h
+++ b/scene/3d/position_3d.h
@@ -34,7 +34,6 @@
#include "scene/3d/node_3d.h"
class Position3D : public Node3D {
-
GDCLASS(Position3D, Node3D);
public:
diff --git a/scene/3d/proximity_group_3d.cpp b/scene/3d/proximity_group_3d.cpp
index 44ffabb655..1a0677c603 100644
--- a/scene/3d/proximity_group_3d.cpp
+++ b/scene/3d/proximity_group_3d.cpp
@@ -33,7 +33,6 @@
#include "core/math/math_funcs.h"
void ProximityGroup3D::clear_groups() {
-
Map<StringName, uint32_t>::Element *E;
{
@@ -42,7 +41,6 @@ void ProximityGroup3D::clear_groups() {
E = groups.front();
int num = 0;
while (E && num < size) {
-
if (E->get() != group_version) {
remove_list[num++] = E->key();
};
@@ -50,7 +48,6 @@ void ProximityGroup3D::clear_groups() {
E = E->next();
};
for (int i = 0; i < num; i++) {
-
groups.erase(remove_list[i]);
};
};
@@ -61,9 +58,9 @@ void ProximityGroup3D::clear_groups() {
};
void ProximityGroup3D::update_groups() {
-
- if (grid_radius == Vector3(0, 0, 0))
+ if (grid_radius == Vector3(0, 0, 0)) {
return;
+ }
++group_version;
@@ -77,10 +74,8 @@ void ProximityGroup3D::update_groups() {
};
void ProximityGroup3D::add_groups(int *p_cell, String p_base, int p_depth) {
-
p_base = p_base + "|";
if (grid_radius[p_depth] == 0) {
-
if (p_depth == 2) {
_new_group(p_base);
} else {
@@ -92,7 +87,6 @@ void ProximityGroup3D::add_groups(int *p_cell, String p_base, int p_depth) {
int end = p_cell[p_depth] + grid_radius[p_depth];
for (int i = start; i <= end; i++) {
-
String gname = p_base + itos(i);
if (p_depth == 2) {
_new_group(gname);
@@ -103,7 +97,6 @@ void ProximityGroup3D::add_groups(int *p_cell, String p_base, int p_depth) {
};
void ProximityGroup3D::_new_group(StringName p_name) {
-
const Map<StringName, uint32_t>::Element *E = groups.find(p_name);
if (!E) {
add_to_group(p_name);
@@ -113,9 +106,7 @@ void ProximityGroup3D::_new_group(StringName p_name) {
};
void ProximityGroup3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_EXIT_TREE:
++group_version;
clear_groups();
@@ -127,59 +118,47 @@ void ProximityGroup3D::_notification(int p_what) {
};
void ProximityGroup3D::broadcast(String p_name, Variant p_params) {
-
Map<StringName, uint32_t>::Element *E;
E = groups.front();
while (E) {
-
get_tree()->call_group_flags(SceneTree::GROUP_CALL_DEFAULT, E->key(), "_proximity_group_broadcast", p_name, p_params);
E = E->next();
};
};
void ProximityGroup3D::_proximity_group_broadcast(String p_name, Variant p_params) {
-
if (dispatch_mode == MODE_PROXY) {
-
get_parent()->call(p_name, p_params);
} else {
-
emit_signal("broadcast", p_name, p_params);
};
};
void ProximityGroup3D::set_group_name(const String &p_group_name) {
-
group_name = p_group_name;
};
String ProximityGroup3D::get_group_name() const {
-
return group_name;
};
void ProximityGroup3D::set_dispatch_mode(DispatchMode p_mode) {
-
dispatch_mode = p_mode;
};
ProximityGroup3D::DispatchMode ProximityGroup3D::get_dispatch_mode() const {
-
return dispatch_mode;
};
void ProximityGroup3D::set_grid_radius(const Vector3 &p_radius) {
-
grid_radius = p_radius;
};
Vector3 ProximityGroup3D::get_grid_radius() const {
-
return grid_radius;
};
void ProximityGroup3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_group_name", "name"), &ProximityGroup3D::set_group_name);
ClassDB::bind_method(D_METHOD("get_group_name"), &ProximityGroup3D::get_group_name);
ClassDB::bind_method(D_METHOD("set_dispatch_mode", "mode"), &ProximityGroup3D::set_dispatch_mode);
@@ -200,15 +179,5 @@ void ProximityGroup3D::_bind_methods() {
};
ProximityGroup3D::ProximityGroup3D() {
-
- group_version = 0;
- dispatch_mode = MODE_PROXY;
-
- cell_size = 1.0;
- grid_radius = Vector3(1, 1, 1);
set_notify_transform(true);
};
-
-ProximityGroup3D::~ProximityGroup3D(){
-
-};
diff --git a/scene/3d/proximity_group_3d.h b/scene/3d/proximity_group_3d.h
index 751bfbdb52..dd3a2f0a87 100644
--- a/scene/3d/proximity_group_3d.h
+++ b/scene/3d/proximity_group_3d.h
@@ -34,7 +34,6 @@
#include "node_3d.h"
class ProximityGroup3D : public Node3D {
-
GDCLASS(ProximityGroup3D, Node3D);
OBJ_CATEGORY("3D");
@@ -50,14 +49,14 @@ public:
void _notification(int p_what);
- DispatchMode dispatch_mode;
+ DispatchMode dispatch_mode = MODE_PROXY;
Map<StringName, uint32_t> groups;
String group_name;
- float cell_size;
- Vector3 grid_radius;
- uint32_t group_version;
+ float cell_size = 1.0;
+ Vector3 grid_radius = Vector3(1, 1, 1);
+ uint32_t group_version = 0;
void add_groups(int *p_cell, String p_base, int p_depth);
void _new_group(StringName p_name);
@@ -79,7 +78,7 @@ public:
void broadcast(String p_name, Variant p_params);
ProximityGroup3D();
- ~ProximityGroup3D();
+ ~ProximityGroup3D() {}
};
VARIANT_ENUM_CAST(ProximityGroup3D::DispatchMode);
diff --git a/scene/3d/ray_cast_3d.cpp b/scene/3d/ray_cast_3d.cpp
index a18da61656..68f4b3132c 100644
--- a/scene/3d/ray_cast_3d.cpp
+++ b/scene/3d/ray_cast_3d.cpp
@@ -36,151 +36,149 @@
#include "servers/physics_server_3d.h"
void RayCast3D::set_cast_to(const Vector3 &p_point) {
-
cast_to = p_point;
- if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint()))
+ if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) {
update_gizmo();
- if (is_inside_tree() && get_tree()->is_debugging_collisions_hint())
+ }
+ if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) {
_update_debug_shape();
+ }
}
Vector3 RayCast3D::get_cast_to() const {
-
return cast_to;
}
void RayCast3D::set_collision_mask(uint32_t p_mask) {
-
collision_mask = p_mask;
}
uint32_t RayCast3D::get_collision_mask() const {
-
return collision_mask;
}
void RayCast3D::set_collision_mask_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
bool RayCast3D::get_collision_mask_bit(int p_bit) const {
-
return get_collision_mask() & (1 << p_bit);
}
bool RayCast3D::is_colliding() const {
-
return collided;
}
-Object *RayCast3D::get_collider() const {
- if (against.is_null())
+Object *RayCast3D::get_collider() const {
+ if (against.is_null()) {
return nullptr;
+ }
return ObjectDB::get_instance(against);
}
int RayCast3D::get_collider_shape() const {
-
return against_shape;
}
-Vector3 RayCast3D::get_collision_point() const {
+Vector3 RayCast3D::get_collision_point() const {
return collision_point;
}
-Vector3 RayCast3D::get_collision_normal() const {
+Vector3 RayCast3D::get_collision_normal() const {
return collision_normal;
}
void RayCast3D::set_enabled(bool p_enabled) {
-
enabled = p_enabled;
update_gizmo();
- if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint())
+ if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) {
set_physics_process_internal(p_enabled);
- if (!p_enabled)
+ }
+ if (!p_enabled) {
collided = false;
+ }
if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) {
- if (p_enabled)
+ if (p_enabled) {
_update_debug_shape();
- else
+ } else {
_clear_debug_shape();
+ }
}
}
bool RayCast3D::is_enabled() const {
-
return enabled;
}
void RayCast3D::set_exclude_parent_body(bool p_exclude_parent_body) {
-
- if (exclude_parent_body == p_exclude_parent_body)
+ if (exclude_parent_body == p_exclude_parent_body) {
return;
+ }
exclude_parent_body = p_exclude_parent_body;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
if (Object::cast_to<CollisionObject3D>(get_parent())) {
- if (exclude_parent_body)
+ if (exclude_parent_body) {
exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
- else
+ } else {
exclude.erase(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
+ }
}
}
bool RayCast3D::get_exclude_parent_body() const {
-
return exclude_parent_body;
}
void RayCast3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
if (enabled && !Engine::get_singleton()->is_editor_hint()) {
set_physics_process_internal(true);
- if (get_tree()->is_debugging_collisions_hint())
+ if (get_tree()->is_debugging_collisions_hint()) {
_update_debug_shape();
- } else
+ }
+ } else {
set_physics_process_internal(false);
+ }
if (Object::cast_to<CollisionObject3D>(get_parent())) {
- if (exclude_parent_body)
+ if (exclude_parent_body) {
exclude.insert(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
- else
+ } else {
exclude.erase(Object::cast_to<CollisionObject3D>(get_parent())->get_rid());
+ }
}
} break;
case NOTIFICATION_EXIT_TREE: {
-
if (enabled) {
set_physics_process_internal(false);
}
- if (debug_shape)
+ if (debug_shape) {
_clear_debug_shape();
+ }
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
-
- if (!enabled)
+ if (!enabled) {
break;
+ }
bool prev_collision_state = collided;
_update_raycast_state();
@@ -196,7 +194,7 @@ void RayCast3D::_notification(int p_what) {
}
void RayCast3D::_update_raycast_state() {
- Ref<World3D> w3d = get_world();
+ Ref<World3D> w3d = get_world_3d();
ERR_FAIL_COND(w3d.is_null());
PhysicsDirectSpaceState3D *dss = PhysicsServer3D::get_singleton()->space_get_direct_state(w3d->get_space());
@@ -205,13 +203,13 @@ void RayCast3D::_update_raycast_state() {
Transform gt = get_global_transform();
Vector3 to = cast_to;
- if (to == Vector3())
+ if (to == Vector3()) {
to = Vector3(0, 0.01, 0);
+ }
PhysicsDirectSpaceState3D::RayResult rr;
if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_mask, collide_with_bodies, collide_with_areas)) {
-
collided = true;
against = rr.collider_id;
collision_point = rr.position;
@@ -229,60 +227,52 @@ void RayCast3D::force_raycast_update() {
}
void RayCast3D::add_exception_rid(const RID &p_rid) {
-
exclude.insert(p_rid);
}
void RayCast3D::add_exception(const Object *p_object) {
-
ERR_FAIL_NULL(p_object);
const CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_object);
- if (!co)
+ if (!co) {
return;
+ }
add_exception_rid(co->get_rid());
}
void RayCast3D::remove_exception_rid(const RID &p_rid) {
-
exclude.erase(p_rid);
}
void RayCast3D::remove_exception(const Object *p_object) {
-
ERR_FAIL_NULL(p_object);
const CollisionObject3D *co = Object::cast_to<CollisionObject3D>(p_object);
- if (!co)
+ if (!co) {
return;
+ }
remove_exception_rid(co->get_rid());
}
void RayCast3D::clear_exceptions() {
-
exclude.clear();
}
void RayCast3D::set_collide_with_areas(bool p_clip) {
-
collide_with_areas = p_clip;
}
bool RayCast3D::is_collide_with_areas_enabled() const {
-
return collide_with_areas;
}
void RayCast3D::set_collide_with_bodies(bool p_clip) {
-
collide_with_bodies = p_clip;
}
bool RayCast3D::is_collide_with_bodies_enabled() const {
-
return collide_with_bodies;
}
void RayCast3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast3D::set_enabled);
ClassDB::bind_method(D_METHOD("is_enabled"), &RayCast3D::is_enabled);
@@ -331,7 +321,6 @@ void RayCast3D::_bind_methods() {
}
void RayCast3D::_create_debug_shape() {
-
if (!debug_material.is_valid()) {
debug_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
@@ -350,16 +339,18 @@ void RayCast3D::_create_debug_shape() {
}
void RayCast3D::_update_debug_shape() {
-
- if (!enabled)
+ if (!enabled) {
return;
+ }
- if (!debug_shape)
+ if (!debug_shape) {
_create_debug_shape();
+ }
MeshInstance3D *mi = static_cast<MeshInstance3D *>(debug_shape);
- if (!mi->get_mesh().is_valid())
+ if (!mi->get_mesh().is_valid()) {
return;
+ }
Ref<ArrayMesh> mesh = mi->get_mesh();
mesh->clear_surfaces();
@@ -377,21 +368,21 @@ void RayCast3D::_update_debug_shape() {
}
void RayCast3D::_clear_debug_shape() {
-
- if (!debug_shape)
+ if (!debug_shape) {
return;
+ }
MeshInstance3D *mi = static_cast<MeshInstance3D *>(debug_shape);
- if (mi->is_inside_tree())
+ if (mi->is_inside_tree()) {
mi->queue_delete();
- else
+ } else {
memdelete(mi);
+ }
debug_shape = nullptr;
}
RayCast3D::RayCast3D() {
-
enabled = false;
collided = false;
diff --git a/scene/3d/ray_cast_3d.h b/scene/3d/ray_cast_3d.h
index f8bfb7846a..8f617e5491 100644
--- a/scene/3d/ray_cast_3d.h
+++ b/scene/3d/ray_cast_3d.h
@@ -34,7 +34,6 @@
#include "scene/3d/node_3d.h"
class RayCast3D : public Node3D {
-
GDCLASS(RayCast3D, Node3D);
bool enabled;
diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp
index 24bf8b43d1..b1f19053d9 100644
--- a/scene/3d/reflection_probe.cpp
+++ b/scene/3d/reflection_probe.cpp
@@ -31,18 +31,15 @@
#include "reflection_probe.h"
void ReflectionProbe::set_intensity(float p_intensity) {
-
intensity = p_intensity;
RS::get_singleton()->reflection_probe_set_intensity(probe, p_intensity);
}
float ReflectionProbe::get_intensity() const {
-
return intensity;
}
void ReflectionProbe::set_interior_ambient(Color p_ambient) {
-
interior_ambient = p_ambient;
RS::get_singleton()->reflection_probe_set_interior_ambient(probe, p_ambient);
}
@@ -57,33 +54,28 @@ float ReflectionProbe::get_interior_ambient_energy() const {
}
Color ReflectionProbe::get_interior_ambient() const {
-
return interior_ambient;
}
void ReflectionProbe::set_interior_ambient_probe_contribution(float p_contribution) {
-
interior_ambient_probe_contribution = p_contribution;
RS::get_singleton()->reflection_probe_set_interior_ambient_probe_contribution(probe, p_contribution);
}
float ReflectionProbe::get_interior_ambient_probe_contribution() const {
-
return interior_ambient_probe_contribution;
}
void ReflectionProbe::set_max_distance(float p_distance) {
-
max_distance = p_distance;
RS::get_singleton()->reflection_probe_set_max_distance(probe, p_distance);
}
-float ReflectionProbe::get_max_distance() const {
+float ReflectionProbe::get_max_distance() const {
return max_distance;
}
void ReflectionProbe::set_extents(const Vector3 &p_extents) {
-
extents = p_extents;
for (int i = 0; i < 3; i++) {
@@ -102,17 +94,15 @@ void ReflectionProbe::set_extents(const Vector3 &p_extents) {
_change_notify("extents");
update_gizmo();
}
-Vector3 ReflectionProbe::get_extents() const {
+Vector3 ReflectionProbe::get_extents() const {
return extents;
}
void ReflectionProbe::set_origin_offset(const Vector3 &p_extents) {
-
origin_offset = p_extents;
for (int i = 0; i < 3; i++) {
-
if (extents[i] - 0.01 < ABS(origin_offset[i])) {
origin_offset[i] = SGN(origin_offset[i]) * (extents[i] - 0.01);
}
@@ -123,50 +113,45 @@ void ReflectionProbe::set_origin_offset(const Vector3 &p_extents) {
_change_notify("origin_offset");
update_gizmo();
}
-Vector3 ReflectionProbe::get_origin_offset() const {
+Vector3 ReflectionProbe::get_origin_offset() const {
return origin_offset;
}
void ReflectionProbe::set_enable_box_projection(bool p_enable) {
-
box_projection = p_enable;
RS::get_singleton()->reflection_probe_set_enable_box_projection(probe, p_enable);
}
-bool ReflectionProbe::is_box_projection_enabled() const {
+bool ReflectionProbe::is_box_projection_enabled() const {
return box_projection;
}
void ReflectionProbe::set_as_interior(bool p_enable) {
-
interior = p_enable;
RS::get_singleton()->reflection_probe_set_as_interior(probe, interior);
_change_notify();
}
bool ReflectionProbe::is_set_as_interior() const {
-
return interior;
}
void ReflectionProbe::set_enable_shadows(bool p_enable) {
-
enable_shadows = p_enable;
RS::get_singleton()->reflection_probe_set_enable_shadows(probe, p_enable);
}
-bool ReflectionProbe::are_shadows_enabled() const {
+bool ReflectionProbe::are_shadows_enabled() const {
return enable_shadows;
}
void ReflectionProbe::set_cull_mask(uint32_t p_layers) {
-
cull_mask = p_layers;
RS::get_singleton()->reflection_probe_set_cull_mask(probe, p_layers);
}
-uint32_t ReflectionProbe::get_cull_mask() const {
+uint32_t ReflectionProbe::get_cull_mask() const {
return cull_mask;
}
@@ -180,19 +165,17 @@ ReflectionProbe::UpdateMode ReflectionProbe::get_update_mode() const {
}
AABB ReflectionProbe::get_aabb() const {
-
AABB aabb;
aabb.position = -origin_offset;
aabb.size = origin_offset + extents;
return aabb;
}
-Vector<Face3> ReflectionProbe::get_faces(uint32_t p_usage_flags) const {
+Vector<Face3> ReflectionProbe::get_faces(uint32_t p_usage_flags) const {
return Vector<Face3>();
}
void ReflectionProbe::_validate_property(PropertyInfo &property) const {
-
if (property.name == "interior/ambient_color" || property.name == "interior/ambient_energy" || property.name == "interior/ambient_contrib") {
if (!interior) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
@@ -201,7 +184,6 @@ void ReflectionProbe::_validate_property(PropertyInfo &property) const {
}
void ReflectionProbe::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_intensity", "intensity"), &ReflectionProbe::set_intensity);
ClassDB::bind_method(D_METHOD("get_intensity"), &ReflectionProbe::get_intensity);
@@ -258,7 +240,6 @@ void ReflectionProbe::_bind_methods() {
}
ReflectionProbe::ReflectionProbe() {
-
intensity = 1.0;
interior_ambient = Color(0, 0, 0);
interior_ambient_probe_contribution = 0;
@@ -278,6 +259,5 @@ ReflectionProbe::ReflectionProbe() {
}
ReflectionProbe::~ReflectionProbe() {
-
RS::get_singleton()->free(probe);
}
diff --git a/scene/3d/remote_transform_3d.cpp b/scene/3d/remote_transform_3d.cpp
index 38792bbb58..95fce6b802 100644
--- a/scene/3d/remote_transform_3d.cpp
+++ b/scene/3d/remote_transform_3d.cpp
@@ -43,33 +43,37 @@ void RemoteTransform3D::_update_cache() {
}
void RemoteTransform3D::_update_remote() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
- if (cache.is_null())
+ if (cache.is_null()) {
return;
+ }
Node3D *n = Object::cast_to<Node3D>(ObjectDB::get_instance(cache));
- if (!n)
+ if (!n) {
return;
+ }
- if (!n->is_inside_tree())
+ if (!n->is_inside_tree()) {
return;
+ }
//todo make faster
if (use_global_coordinates) {
-
if (update_remote_position && update_remote_rotation && update_remote_scale) {
n->set_global_transform(get_global_transform());
} else {
Transform our_trans = get_global_transform();
- if (update_remote_rotation)
+ if (update_remote_rotation) {
n->set_rotation(our_trans.basis.get_rotation());
+ }
- if (update_remote_scale)
+ if (update_remote_scale) {
n->set_scale(our_trans.basis.get_scale());
+ }
if (update_remote_position) {
Transform n_trans = n->get_global_transform();
@@ -85,11 +89,13 @@ void RemoteTransform3D::_update_remote() {
} else {
Transform our_trans = get_transform();
- if (update_remote_rotation)
+ if (update_remote_rotation) {
n->set_rotation(our_trans.basis.get_rotation());
+ }
- if (update_remote_scale)
+ if (update_remote_scale) {
n->set_scale(our_trans.basis.get_scale());
+ }
if (update_remote_position) {
Transform n_trans = n->get_transform();
@@ -102,20 +108,17 @@ void RemoteTransform3D::_update_remote() {
}
void RemoteTransform3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
_update_cache();
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
break;
+ }
if (cache.is_valid()) {
-
_update_remote();
}
@@ -124,7 +127,6 @@ void RemoteTransform3D::_notification(int p_what) {
}
void RemoteTransform3D::set_remote_node(const NodePath &p_remote_node) {
-
remote_node = p_remote_node;
if (is_inside_tree()) {
_update_cache();
@@ -135,7 +137,6 @@ void RemoteTransform3D::set_remote_node(const NodePath &p_remote_node) {
}
NodePath RemoteTransform3D::get_remote_node() const {
-
return remote_node;
}
@@ -179,7 +180,6 @@ void RemoteTransform3D::force_update_cache() {
}
String RemoteTransform3D::get_configuration_warning() const {
-
if (!has_node(remote_node) || !Object::cast_to<Node3D>(get_node(remote_node))) {
return TTR("The \"Remote Path\" property must point to a valid Node3D or Node3D-derived node to work.");
}
@@ -188,7 +188,6 @@ String RemoteTransform3D::get_configuration_warning() const {
}
void RemoteTransform3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_remote_node", "path"), &RemoteTransform3D::set_remote_node);
ClassDB::bind_method(D_METHOD("get_remote_node"), &RemoteTransform3D::get_remote_node);
ClassDB::bind_method(D_METHOD("force_update_cache"), &RemoteTransform3D::force_update_cache);
@@ -213,7 +212,6 @@ void RemoteTransform3D::_bind_methods() {
}
RemoteTransform3D::RemoteTransform3D() {
-
use_global_coordinates = true;
update_remote_position = true;
update_remote_rotation = true;
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index 59a6e23005..7516cf95b0 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -33,6 +33,7 @@
#include "core/engine.h"
#include "core/message_queue.h"
#include "core/project_settings.h"
+#include "core/type_info.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/resources/surface_tool.h"
@@ -66,39 +67,37 @@ SkinReference::~SkinReference() {
}
bool Skeleton3D::_set(const StringName &p_path, const Variant &p_value) {
-
String path = p_path;
- if (!path.begins_with("bones/"))
+ if (!path.begins_with("bones/")) {
return false;
+ }
int which = path.get_slicec('/', 1).to_int();
String what = path.get_slicec('/', 2);
if (which == bones.size() && what == "name") {
-
add_bone(p_value);
return true;
}
ERR_FAIL_INDEX_V(which, bones.size(), false);
- if (what == "parent")
+ if (what == "parent") {
set_bone_parent(which, p_value);
- else if (what == "rest")
+ } else if (what == "rest") {
set_bone_rest(which, p_value);
- else if (what == "enabled")
+ } else if (what == "enabled") {
set_bone_enabled(which, p_value);
- else if (what == "pose")
+ } else if (what == "pose") {
set_bone_pose(which, p_value);
- else if (what == "bound_children") {
+ } else if (what == "bound_children") {
Array children = p_value;
if (is_inside_tree()) {
bones.write[which].nodes_bound.clear();
for (int i = 0; i < children.size(); i++) {
-
NodePath npath = children[i];
ERR_CONTINUE(npath.operator String() == "");
Node *node = get_node(npath);
@@ -114,32 +113,31 @@ bool Skeleton3D::_set(const StringName &p_path, const Variant &p_value) {
}
bool Skeleton3D::_get(const StringName &p_path, Variant &r_ret) const {
-
String path = p_path;
- if (!path.begins_with("bones/"))
+ if (!path.begins_with("bones/")) {
return false;
+ }
int which = path.get_slicec('/', 1).to_int();
String what = path.get_slicec('/', 2);
ERR_FAIL_INDEX_V(which, bones.size(), false);
- if (what == "name")
+ if (what == "name") {
r_ret = get_bone_name(which);
- else if (what == "parent")
+ } else if (what == "parent") {
r_ret = get_bone_parent(which);
- else if (what == "rest")
+ } else if (what == "rest") {
r_ret = get_bone_rest(which);
- else if (what == "enabled")
+ } else if (what == "enabled") {
r_ret = is_bone_enabled(which);
- else if (what == "pose")
+ } else if (what == "pose") {
r_ret = get_bone_pose(which);
- else if (what == "bound_children") {
+ } else if (what == "bound_children") {
Array children;
for (const List<ObjectID>::Element *E = bones[which].nodes_bound.front(); E; E = E->next()) {
-
Object *obj = ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
Node *node = Object::cast_to<Node>(obj);
@@ -149,15 +147,15 @@ bool Skeleton3D::_get(const StringName &p_path, Variant &r_ret) const {
}
r_ret = children;
- } else
+ } else {
return false;
+ }
return true;
}
-void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const {
+void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < bones.size(); i++) {
-
String prep = "bones/" + itos(i) + "/";
p_list->push_back(PropertyInfo(Variant::STRING, prep + "name"));
p_list->push_back(PropertyInfo(Variant::INT, prep + "parent", PROPERTY_HINT_RANGE, "-1," + itos(bones.size() - 1) + ",1"));
@@ -169,9 +167,9 @@ void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const {
}
void Skeleton3D::_update_process_order() {
-
- if (!process_order_dirty)
+ if (!process_order_dirty) {
return;
+ }
Bone *bonesptr = bones.ptrw();
int len = bones.size();
@@ -179,7 +177,6 @@ void Skeleton3D::_update_process_order() {
process_order.resize(len);
int *order = process_order.ptrw();
for (int i = 0; i < len; i++) {
-
if (bonesptr[i].parent >= len) {
//validate this just in case
ERR_PRINT("Bone " + itos(i) + " has invalid parent: " + itos(bonesptr[i].parent));
@@ -196,8 +193,9 @@ void Skeleton3D::_update_process_order() {
bool swapped = false;
for (int i = 0; i < len; i++) {
int parent_idx = bonesptr[order[i]].parent;
- if (parent_idx < 0)
+ if (parent_idx < 0) {
continue; //do nothing because it has no parent
+ }
//swap indices
int parent_order = bonesptr[parent_idx].sort_index;
if (parent_order > i) {
@@ -209,8 +207,9 @@ void Skeleton3D::_update_process_order() {
}
}
- if (!swapped)
+ if (!swapped) {
break;
+ }
pass_count++;
}
@@ -222,11 +221,8 @@ void Skeleton3D::_update_process_order() {
}
void Skeleton3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_UPDATE_SKELETON: {
-
RenderingServer *vs = RenderingServer::get_singleton();
Bone *bonesptr = bones.ptrw();
int len = bones.size();
@@ -236,7 +232,6 @@ void Skeleton3D::_notification(int p_what) {
const int *order = process_order.ptr();
for (int i = 0; i < len; i++) {
-
Bone &b = bonesptr[order[i]];
if (b.global_pose_override_amount >= 0.999) {
@@ -244,50 +239,38 @@ void Skeleton3D::_notification(int p_what) {
} else {
if (b.disable_rest) {
if (b.enabled) {
-
Transform pose = b.pose;
if (b.custom_pose_enable) {
pose = b.custom_pose * pose;
}
if (b.parent >= 0) {
-
b.pose_global = bonesptr[b.parent].pose_global * pose;
} else {
-
b.pose_global = pose;
}
} else {
-
if (b.parent >= 0) {
-
b.pose_global = bonesptr[b.parent].pose_global;
} else {
-
b.pose_global = Transform();
}
}
} else {
if (b.enabled) {
-
Transform pose = b.pose;
if (b.custom_pose_enable) {
pose = b.custom_pose * pose;
}
if (b.parent >= 0) {
-
b.pose_global = bonesptr[b.parent].pose_global * (b.rest * pose);
} else {
-
b.pose_global = b.rest * pose;
}
} else {
-
if (b.parent >= 0) {
-
b.pose_global = bonesptr[b.parent].pose_global * b.rest;
} else {
-
b.pose_global = b.rest;
}
}
@@ -303,7 +286,6 @@ void Skeleton3D::_notification(int p_what) {
}
for (List<ObjectID>::Element *E = b.nodes_bound.front(); E; E = E->next()) {
-
Object *obj = ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
Node3D *sp = Object::cast_to<Node3D>(obj);
@@ -314,7 +296,6 @@ void Skeleton3D::_notification(int p_what) {
//update skins
for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) {
-
const Skin *skin = E->get()->skin.operator->();
RID skeleton = E->get()->skeleton;
uint32_t bind_count = skin->get_bind_count();
@@ -327,7 +308,6 @@ void Skeleton3D::_notification(int p_what) {
}
if (E->get()->skeleton_version != version) {
-
for (uint32_t i = 0; i < bind_count; i++) {
StringName bind_name = skin->get_bind_name(i);
@@ -404,7 +384,6 @@ void Skeleton3D::clear_bones_global_pose_override() {
}
void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform &p_pose, float p_amount, bool p_persistent) {
-
ERR_FAIL_INDEX(p_bone, bones.size());
bones.write[p_bone].global_pose_override_amount = p_amount;
bones.write[p_bone].global_pose_override = p_pose;
@@ -413,20 +392,18 @@ void Skeleton3D::set_bone_global_pose_override(int p_bone, const Transform &p_po
}
Transform Skeleton3D::get_bone_global_pose(int p_bone) const {
-
ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
- if (dirty)
+ if (dirty) {
const_cast<Skeleton3D *>(this)->notification(NOTIFICATION_UPDATE_SKELETON);
+ }
return bones[p_bone].pose_global;
}
// skeleton creation api
void Skeleton3D::add_bone(const String &p_name) {
-
ERR_FAIL_COND(p_name == "" || p_name.find(":") != -1 || p_name.find("/") != -1);
for (int i = 0; i < bones.size(); i++) {
-
ERR_FAIL_COND(bones[i].name == p_name);
}
@@ -438,43 +415,42 @@ void Skeleton3D::add_bone(const String &p_name) {
_make_dirty();
update_gizmo();
}
-int Skeleton3D::find_bone(const String &p_name) const {
+int Skeleton3D::find_bone(const String &p_name) const {
for (int i = 0; i < bones.size(); i++) {
-
- if (bones[i].name == p_name)
+ if (bones[i].name == p_name) {
return i;
+ }
}
return -1;
}
-String Skeleton3D::get_bone_name(int p_bone) const {
+String Skeleton3D::get_bone_name(int p_bone) const {
ERR_FAIL_INDEX_V(p_bone, bones.size(), "");
return bones[p_bone].name;
}
bool Skeleton3D::is_bone_parent_of(int p_bone, int p_parent_bone_id) const {
-
int parent_of_bone = get_bone_parent(p_bone);
- if (-1 == parent_of_bone)
+ if (-1 == parent_of_bone) {
return false;
+ }
- if (parent_of_bone == p_parent_bone_id)
+ if (parent_of_bone == p_parent_bone_id) {
return true;
+ }
return is_bone_parent_of(parent_of_bone, p_parent_bone_id);
}
int Skeleton3D::get_bone_count() const {
-
return bones.size();
}
void Skeleton3D::set_bone_parent(int p_bone, int p_parent) {
-
ERR_FAIL_INDEX(p_bone, bones.size());
ERR_FAIL_COND(p_parent != -1 && (p_parent < 0));
@@ -484,7 +460,6 @@ void Skeleton3D::set_bone_parent(int p_bone, int p_parent) {
}
void Skeleton3D::unparent_bone_and_rest(int p_bone) {
-
ERR_FAIL_INDEX(p_bone, bones.size());
_update_process_order();
@@ -502,80 +477,73 @@ void Skeleton3D::unparent_bone_and_rest(int p_bone) {
}
void Skeleton3D::set_bone_disable_rest(int p_bone, bool p_disable) {
-
ERR_FAIL_INDEX(p_bone, bones.size());
bones.write[p_bone].disable_rest = p_disable;
}
bool Skeleton3D::is_bone_rest_disabled(int p_bone) const {
-
ERR_FAIL_INDEX_V(p_bone, bones.size(), false);
return bones[p_bone].disable_rest;
}
int Skeleton3D::get_bone_parent(int p_bone) const {
-
ERR_FAIL_INDEX_V(p_bone, bones.size(), -1);
return bones[p_bone].parent;
}
void Skeleton3D::set_bone_rest(int p_bone, const Transform &p_rest) {
-
ERR_FAIL_INDEX(p_bone, bones.size());
bones.write[p_bone].rest = p_rest;
_make_dirty();
}
-Transform Skeleton3D::get_bone_rest(int p_bone) const {
+Transform Skeleton3D::get_bone_rest(int p_bone) const {
ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
return bones[p_bone].rest;
}
void Skeleton3D::set_bone_enabled(int p_bone, bool p_enabled) {
-
ERR_FAIL_INDEX(p_bone, bones.size());
bones.write[p_bone].enabled = p_enabled;
_make_dirty();
}
-bool Skeleton3D::is_bone_enabled(int p_bone) const {
+bool Skeleton3D::is_bone_enabled(int p_bone) const {
ERR_FAIL_INDEX_V(p_bone, bones.size(), false);
return bones[p_bone].enabled;
}
void Skeleton3D::bind_child_node_to_bone(int p_bone, Node *p_node) {
-
ERR_FAIL_NULL(p_node);
ERR_FAIL_INDEX(p_bone, bones.size());
ObjectID id = p_node->get_instance_id();
for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
-
- if (E->get() == id)
+ if (E->get() == id) {
return; // already here
+ }
}
bones.write[p_bone].nodes_bound.push_back(id);
}
-void Skeleton3D::unbind_child_node_from_bone(int p_bone, Node *p_node) {
+void Skeleton3D::unbind_child_node_from_bone(int p_bone, Node *p_node) {
ERR_FAIL_NULL(p_node);
ERR_FAIL_INDEX(p_bone, bones.size());
ObjectID id = p_node->get_instance_id();
bones.write[p_bone].nodes_bound.erase(id);
}
-void Skeleton3D::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const {
+void Skeleton3D::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const {
ERR_FAIL_INDEX(p_bone, bones.size());
for (const List<ObjectID>::Element *E = bones[p_bone].nodes_bound.front(); E; E = E->next()) {
-
Object *obj = ObjectDB::get_instance(E->get());
ERR_CONTINUE(!obj);
p_bound->push_back(Object::cast_to<Node>(obj));
@@ -583,7 +551,6 @@ void Skeleton3D::get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound
}
void Skeleton3D::clear_bones() {
-
bones.clear();
process_order_dirty = true;
version++;
@@ -593,7 +560,6 @@ void Skeleton3D::clear_bones() {
// posing api
void Skeleton3D::set_bone_pose(int p_bone, const Transform &p_pose) {
-
ERR_FAIL_INDEX(p_bone, bones.size());
bones.write[p_bone].pose = p_pose;
@@ -601,14 +567,13 @@ void Skeleton3D::set_bone_pose(int p_bone, const Transform &p_pose) {
_make_dirty();
}
}
-Transform Skeleton3D::get_bone_pose(int p_bone) const {
+Transform Skeleton3D::get_bone_pose(int p_bone) const {
ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
return bones[p_bone].pose;
}
void Skeleton3D::set_bone_custom_pose(int p_bone, const Transform &p_custom_pose) {
-
ERR_FAIL_INDEX(p_bone, bones.size());
//ERR_FAIL_COND( !is_inside_scene() );
@@ -619,15 +584,14 @@ void Skeleton3D::set_bone_custom_pose(int p_bone, const Transform &p_custom_pose
}
Transform Skeleton3D::get_bone_custom_pose(int p_bone) const {
-
ERR_FAIL_INDEX_V(p_bone, bones.size(), Transform());
return bones[p_bone].custom_pose;
}
void Skeleton3D::_make_dirty() {
-
- if (dirty)
+ if (dirty) {
return;
+ }
MessageQueue::get_singleton()->push_notification(this, NOTIFICATION_UPDATE_SKELETON);
dirty = true;
@@ -640,7 +604,6 @@ int Skeleton3D::get_process_order(int p_idx) {
}
void Skeleton3D::localize_rests() {
-
_update_process_order();
for (int i = bones.size() - 1; i >= 0; i--) {
@@ -728,14 +691,14 @@ void Skeleton3D::_rebuild_physical_bones_cache() {
PhysicalBone3D *parent_pb = _get_physical_bone_parent(i);
if (parent_pb != bones[i].physical_bone) {
bones.write[i].cache_parent_physical_bone = parent_pb;
- if (bones[i].physical_bone)
+ if (bones[i].physical_bone) {
bones[i].physical_bone->_on_bone_parent_changed();
+ }
}
}
}
void _pb_stop_simulation(Node *p_node) {
-
for (int i = p_node->get_child_count() - 1; 0 <= i; --i) {
_pb_stop_simulation(p_node->get_child(i));
}
@@ -754,7 +717,6 @@ void Skeleton3D::physical_bones_stop_simulation() {
}
void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vector<int> &p_sim_bones) {
-
for (int i = p_node->get_child_count() - 1; 0 <= i; --i) {
_pb_start_simulation(p_skeleton, p_node->get_child(i), p_sim_bones);
}
@@ -770,7 +732,7 @@ void _pb_start_simulation(const Skeleton3D *p_skeleton, Node *p_node, const Vect
}
}
-void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) {
+void Skeleton3D::physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones) {
set_physics_process_internal(false);
Vector<int> sim_bones;
@@ -780,11 +742,9 @@ void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) {
sim_bones.resize(p_bones.size());
int c = 0;
for (int i = sim_bones.size() - 1; 0 <= i; --i) {
- Variant::Type type = p_bones.get(i).get_type();
- if (Variant::STRING == type || Variant::STRING_NAME == type) {
- int bone_id = find_bone(p_bones.get(i));
- if (bone_id != -1)
- sim_bones.write[c++] = bone_id;
+ int bone_id = find_bone(p_bones[i]);
+ if (bone_id != -1) {
+ sim_bones.write[c++] = bone_id;
}
}
sim_bones.resize(c);
@@ -794,7 +754,6 @@ void Skeleton3D::physical_bones_start_simulation_on(const Array &p_bones) {
}
void _physical_bones_add_remove_collision_exception(bool p_add, Node *p_node, RID p_exception) {
-
for (int i = p_node->get_child_count() - 1; 0 <= i; --i) {
_physical_bones_add_remove_collision_exception(p_add, p_node->get_child(i), p_exception);
}
@@ -824,7 +783,6 @@ void Skeleton3D::_skin_changed() {
}
Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) {
-
for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) {
if (E->get()->skin == p_skin) {
return Ref<SkinReference>(E->get());
@@ -885,7 +843,6 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) {
}
void Skeleton3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_bone", "name"), &Skeleton3D::add_bone);
ClassDB::bind_method(D_METHOD("find_bone", "name"), &Skeleton3D::find_bone);
ClassDB::bind_method(D_METHOD("get_bone_name", "bone_idx"), &Skeleton3D::get_bone_name);
@@ -940,7 +897,6 @@ void Skeleton3D::_bind_methods() {
}
Skeleton3D::Skeleton3D() {
-
animate_physical_bones = true;
dirty = false;
version = 1;
@@ -948,7 +904,6 @@ Skeleton3D::Skeleton3D() {
}
Skeleton3D::~Skeleton3D() {
-
//some skins may remain bound
for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) {
E->get()->skeleton_node = nullptr;
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index 08b8691658..1e864c1c48 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -66,7 +66,6 @@ public:
};
class Skeleton3D : public Node3D {
-
GDCLASS(Skeleton3D, Node3D);
private:
@@ -77,7 +76,6 @@ private:
void _skin_changed();
struct Bone {
-
String name;
bool enabled;
@@ -130,13 +128,11 @@ private:
// bind helpers
Array _get_bound_child_nodes_to_bone(int p_bone) const {
-
Array bound;
List<Node *> children;
get_bound_child_nodes_to_bone(p_bone, &children);
for (int i = 0; i < children.size(); i++) {
-
bound.push_back(children[i]);
}
return bound;
@@ -222,7 +218,7 @@ private:
public:
void physical_bones_stop_simulation();
- void physical_bones_start_simulation_on(const Array &p_bones);
+ void physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones);
void physical_bones_add_collision_exception(RID p_exception);
void physical_bones_remove_collision_exception(RID p_exception);
#endif // _3D_DISABLED
diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp
index 7366290ed3..9023f3c68a 100644
--- a/scene/3d/skeleton_ik_3d.cpp
+++ b/scene/3d/skeleton_ik_3d.cpp
@@ -55,7 +55,6 @@ FabrikInverseKinematic::ChainItem *FabrikInverseKinematic::ChainItem::add_child(
/// Build a chain that starts from the root to tip
bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain) {
-
ERR_FAIL_COND_V(-1 == p_task->root_bone, false);
Chain &chain(p_task->chain);
@@ -75,7 +74,6 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain
chain_ids.resize(p_task->skeleton->get_bone_count());
for (int x = p_task->end_effectors.size() - 1; 0 <= x; --x) {
-
const EndEffector *ee(&p_task->end_effectors[x]);
ERR_FAIL_COND_V(p_task->root_bone >= ee->tip_bone, false);
ERR_FAIL_INDEX_V(ee->tip_bone, p_task->skeleton->get_bone_count(), false);
@@ -84,7 +82,6 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain
// Picks all IDs that composing a single chain in reverse order (except the root)
BoneId chain_sub_tip(ee->tip_bone);
while (chain_sub_tip > p_task->root_bone) {
-
chain_ids.write[sub_chain_size++] = chain_sub_tip;
chain_sub_tip = p_task->skeleton->get_bone_parent(chain_sub_tip);
}
@@ -95,10 +92,8 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain
// For each chain item id will be created a ChainItem if doesn't exists
ChainItem *sub_chain(&chain.chain_root);
for (int i = sub_chain_size - 1; 0 <= i; --i) {
-
ChainItem *child_ci(sub_chain->find_child(chain_ids[i]));
if (!child_ci) {
-
child_ci = sub_chain->add_child(chain_ids[i]);
child_ci->pb = p_task->skeleton->get_physical_bone(child_ci->bone);
@@ -118,8 +113,9 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain
}
}
- if (!middle_chain_item_id)
+ if (!middle_chain_item_id) {
chain.middle_chain_item = nullptr;
+ }
// Initialize current tip
chain.tips.write[x].chain_item = sub_chain;
@@ -137,9 +133,9 @@ bool FabrikInverseKinematic::build_chain(Task *p_task, bool p_force_simple_chain
}
void FabrikInverseKinematic::update_chain(const Skeleton3D *p_sk, ChainItem *p_chain_item) {
-
- if (!p_chain_item)
+ if (!p_chain_item) {
return;
+ }
p_chain_item->initial_transform = p_sk->get_bone_global_pose(p_chain_item->bone);
p_chain_item->current_pos = p_chain_item->initial_transform.origin;
@@ -151,7 +147,6 @@ void FabrikInverseKinematic::update_chain(const Skeleton3D *p_sk, ChainItem *p_c
}
void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet) {
-
real_t distance_to_goal(1e4);
real_t previous_distance_to_goal(0);
int can_solve(p_task->max_iterations);
@@ -167,7 +162,6 @@ void FabrikInverseKinematic::solve_simple(Task *p_task, bool p_solve_magnet) {
}
void FabrikInverseKinematic::solve_simple_backwards(Chain &r_chain, bool p_solve_magnet) {
-
if (p_solve_magnet && !r_chain.middle_chain_item) {
return;
}
@@ -200,7 +194,6 @@ void FabrikInverseKinematic::solve_simple_backwards(Chain &r_chain, bool p_solve
}
void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_magnet) {
-
if (p_solve_magnet && !r_chain.middle_chain_item) {
return;
}
@@ -212,7 +205,6 @@ void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_
sub_chain_root->current_pos = origin;
if (!sub_chain_root->children.empty()) {
-
ChainItem &child(sub_chain_root->children.write[0]);
// Is not tip
@@ -231,7 +223,6 @@ void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_
sub_chain_root = &child;
}
} else {
-
// Is tip
sub_chain_root = nullptr;
}
@@ -239,7 +230,6 @@ void FabrikInverseKinematic::solve_simple_forwards(Chain &r_chain, bool p_solve_
}
FabrikInverseKinematic::Task *FabrikInverseKinematic::create_simple_task(Skeleton3D *p_sk, BoneId root_bone, BoneId tip_bone, const Transform &goal_transform) {
-
FabrikInverseKinematic::EndEffector ee;
ee.tip_bone = tip_bone;
@@ -258,8 +248,9 @@ FabrikInverseKinematic::Task *FabrikInverseKinematic::create_simple_task(Skeleto
}
void FabrikInverseKinematic::free_task(Task *p_task) {
- if (p_task)
+ if (p_task) {
memdelete(p_task);
+ }
}
void FabrikInverseKinematic::set_goal(Task *p_task, const Transform &p_goal) {
@@ -267,12 +258,10 @@ void FabrikInverseKinematic::set_goal(Task *p_task, const Transform &p_goal) {
}
void FabrikInverseKinematic::make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta) {
-
if (blending_delta >= 0.99f) {
// Update the end_effector (local transform) without blending
p_task->end_effectors.write[0].goal_transform = p_inverse_transf * p_task->goal_global_transform;
} else {
-
// End effector in local transform
const Transform end_effector_pose(p_task->skeleton->get_bone_global_pose(p_task->end_effectors.write[0].tip_bone));
@@ -282,19 +271,26 @@ void FabrikInverseKinematic::make_goal(Task *p_task, const Transform &p_inverse_
}
void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position) {
-
if (blending_delta <= 0.01f) {
return; // Skip solving
}
- p_task->skeleton->clear_bones_global_pose_override();
+ p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform(), 0.0, true);
+
+ if (p_task->chain.middle_chain_item) {
+ p_task->skeleton->set_bone_global_pose_override(p_task->chain.middle_chain_item->bone, Transform(), 0.0, true);
+ }
+
+ for (int i = 0; i < p_task->chain.tips.size(); i += 1) {
+ p_task->skeleton->set_bone_global_pose_override(p_task->chain.tips[i].chain_item->bone, Transform(), 0.0, true);
+ }
make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse().scaled(p_task->skeleton->get_global_transform().get_basis().get_scale()), blending_delta);
update_chain(p_task->skeleton, &p_task->chain.chain_root);
if (p_use_magnet && p_task->chain.middle_chain_item) {
- p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.linear_interpolate(p_magnet_position, blending_delta);
+ p_task->chain.magnet_position = p_task->chain.middle_chain_item->initial_transform.origin.lerp(p_magnet_position, blending_delta);
solve_simple(p_task, true);
}
solve_simple(p_task, false);
@@ -306,7 +302,6 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
new_bone_pose.origin = ci->current_pos;
if (!ci->children.empty()) {
-
/// Rotate basis
const Vector3 initial_ori((ci->children[0].initial_transform.origin - ci->initial_transform.origin).normalized());
const Vector3 rot_axis(initial_ori.cross(ci->current_ori).normalized());
@@ -317,38 +312,37 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
}
} else {
// Set target orientation to tip
- if (override_tip_basis)
+ if (override_tip_basis) {
new_bone_pose.basis = p_task->chain.tips[0].end_effector->goal_transform.basis;
- else
+ } else {
new_bone_pose.basis = new_bone_pose.basis * p_task->chain.tips[0].end_effector->goal_transform.basis;
+ }
}
p_task->skeleton->set_bone_global_pose_override(ci->bone, new_bone_pose, 1.0, true);
- if (!ci->children.empty())
+ if (!ci->children.empty()) {
ci = &ci->children.write[0];
- else
+ } else {
ci = nullptr;
+ }
}
}
void SkeletonIK3D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "root_bone" || property.name == "tip_bone") {
-
if (skeleton) {
-
String names("--,");
for (int i = 0; i < skeleton->get_bone_count(); i++) {
- if (i > 0)
+ if (i > 0) {
names += ",";
+ }
names += skeleton->get_bone_name(i);
}
property.hint = PROPERTY_HINT_ENUM;
property.hint_string = names;
} else {
-
property.hint = PROPERTY_HINT_NONE;
property.hint_string = "";
}
@@ -356,7 +350,6 @@ void SkeletonIK3D::_validate_property(PropertyInfo &property) const {
}
void SkeletonIK3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_root_bone", "root_bone"), &SkeletonIK3D::set_root_bone);
ClassDB::bind_method(D_METHOD("get_root_bone"), &SkeletonIK3D::get_root_bone);
@@ -413,9 +406,9 @@ void SkeletonIK3D::_notification(int p_what) {
reload_chain();
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
-
- if (target_node_override)
+ if (target_node_override) {
reload_goal();
+ }
_solve_chain();
@@ -426,15 +419,7 @@ void SkeletonIK3D::_notification(int p_what) {
}
}
-SkeletonIK3D::SkeletonIK3D() :
- interpolation(1),
- override_tip_basis(true),
- use_magnet(false),
- min_distance(0.01),
- max_iterations(10),
- skeleton(nullptr),
- target_node_override(nullptr),
- task(nullptr) {
+SkeletonIK3D::SkeletonIK3D() {
}
SkeletonIK3D::~SkeletonIK3D() {
@@ -537,23 +522,24 @@ void SkeletonIK3D::stop() {
}
Transform SkeletonIK3D::_get_target_transform() {
-
- if (!target_node_override && !target_node_path_override.is_empty())
+ if (!target_node_override && !target_node_path_override.is_empty()) {
target_node_override = Object::cast_to<Node3D>(get_node(target_node_path_override));
+ }
- if (target_node_override)
+ if (target_node_override) {
return target_node_override->get_global_transform();
- else
+ } else {
return target;
+ }
}
void SkeletonIK3D::reload_chain() {
-
FabrikInverseKinematic::free_task(task);
task = nullptr;
- if (!skeleton)
+ if (!skeleton) {
return;
+ }
task = FabrikInverseKinematic::create_simple_task(skeleton, skeleton->find_bone(root_bone), skeleton->find_bone(tip_bone), _get_target_transform());
if (task) {
@@ -563,15 +549,17 @@ void SkeletonIK3D::reload_chain() {
}
void SkeletonIK3D::reload_goal() {
- if (!task)
+ if (!task) {
return;
+ }
FabrikInverseKinematic::set_goal(task, _get_target_transform());
}
void SkeletonIK3D::_solve_chain() {
- if (!task)
+ if (!task) {
return;
+ }
FabrikInverseKinematic::solve(task, interpolation, override_tip_basis, use_magnet, magnet_position);
}
diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h
index 5fbbe6e9e7..0d948f13a9 100644
--- a/scene/3d/skeleton_ik_3d.h
+++ b/scene/3d/skeleton_ik_3d.h
@@ -41,45 +41,37 @@
#include "scene/3d/skeleton_3d.h"
class FabrikInverseKinematic {
-
struct EndEffector {
BoneId tip_bone;
Transform goal_transform;
};
struct ChainItem {
-
Vector<ChainItem> children;
- ChainItem *parent_item;
+ ChainItem *parent_item = nullptr;
// Bone info
- BoneId bone;
- PhysicalBone3D *pb;
+ BoneId bone = -1;
+ PhysicalBone3D *pb = nullptr;
- real_t length;
+ real_t length = 0;
/// Positions relative to root bone
Transform initial_transform;
Vector3 current_pos;
// Direction from this bone to child
Vector3 current_ori;
- ChainItem() :
- parent_item(nullptr),
- bone(-1),
- pb(nullptr),
- length(0) {}
+ ChainItem() {}
ChainItem *find_child(const BoneId p_bone_id);
ChainItem *add_child(const BoneId p_bone_id);
};
struct ChainTip {
- ChainItem *chain_item;
- const EndEffector *end_effector;
+ ChainItem *chain_item = nullptr;
+ const EndEffector *end_effector = nullptr;
- ChainTip() :
- chain_item(nullptr),
- end_effector(nullptr) {}
+ ChainTip() {}
ChainTip(ChainItem *p_chain_item, const EndEffector *p_end_effector) :
chain_item(p_chain_item),
@@ -100,25 +92,21 @@ class FabrikInverseKinematic {
public:
struct Task {
RID self;
- Skeleton3D *skeleton;
+ Skeleton3D *skeleton = nullptr;
Chain chain;
// Settings
- real_t min_distance;
- int max_iterations;
+ real_t min_distance = 0.01;
+ int max_iterations = 10;
// Bone data
- BoneId root_bone;
+ BoneId root_bone = -1;
Vector<EndEffector> end_effectors;
Transform goal_global_transform;
- Task() :
- skeleton(nullptr),
- min_distance(0.01),
- max_iterations(10),
- root_bone(-1) {}
+ Task() {}
};
private:
@@ -146,19 +134,19 @@ class SkeletonIK3D : public Node {
StringName root_bone;
StringName tip_bone;
- real_t interpolation;
+ real_t interpolation = 1;
Transform target;
NodePath target_node_path_override;
- bool override_tip_basis;
- bool use_magnet;
+ bool override_tip_basis = true;
+ bool use_magnet = false;
Vector3 magnet_position;
- real_t min_distance;
- int max_iterations;
+ real_t min_distance = 0.01;
+ int max_iterations = 10;
- Skeleton3D *skeleton;
- Node3D *target_node_override;
- FabrikInverseKinematic::Task *task;
+ Skeleton3D *skeleton = nullptr;
+ Node3D *target_node_override = nullptr;
+ FabrikInverseKinematic::Task *task = nullptr;
protected:
virtual void
diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp
index 6092818252..a267c57f5e 100644
--- a/scene/3d/soft_body_3d.cpp
+++ b/scene/3d/soft_body_3d.cpp
@@ -65,7 +65,6 @@ void SoftBodyRenderingServerHandler::prepare(RID p_mesh, int p_surface) {
}
void SoftBodyRenderingServerHandler::clear() {
-
if (mesh.is_valid()) {
buffer.resize(0);
}
@@ -97,9 +96,7 @@ void SoftBodyRenderingServerHandler::set_aabb(const AABB &p_aabb) {
RS::get_singleton()->mesh_set_custom_aabb(mesh, p_aabb);
}
-SoftBody3D::PinnedPoint::PinnedPoint() :
- point_index(-1),
- spatial_attachment(nullptr) {
+SoftBody3D::PinnedPoint::PinnedPoint() {
}
SoftBody3D::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) {
@@ -118,8 +115,9 @@ SoftBody3D::PinnedPoint SoftBody3D::PinnedPoint::operator=(const PinnedPoint &ob
}
void SoftBody3D::_update_pickable() {
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
bool pickable = ray_pickable && is_visible_in_tree();
PhysicsServer3D::get_singleton()->soft_body_set_ray_pickable(physics_rid, pickable);
}
@@ -129,11 +127,9 @@ bool SoftBody3D::_set(const StringName &p_name, const Variant &p_value) {
String which = name.get_slicec('/', 0);
if ("pinned_points" == which) {
-
return _set_property_pinned_points_indices(p_value);
} else if ("attachments" == which) {
-
int idx = name.get_slicec('/', 1).to_int();
String what = name.get_slicec('/', 2);
@@ -161,7 +157,6 @@ bool SoftBody3D::_get(const StringName &p_name, Variant &r_ret) const {
return true;
} else if ("attachments" == which) {
-
int idx = name.get_slicec('/', 1).to_int();
String what = name.get_slicec('/', 2);
@@ -172,7 +167,6 @@ bool SoftBody3D::_get(const StringName &p_name, Variant &r_ret) const {
}
void SoftBody3D::_get_property_list(List<PropertyInfo> *p_list) const {
-
const int pinned_points_indices_size = pinned_points.size();
p_list->push_back(PropertyInfo(Variant::PACKED_INT32_ARRAY, "pinned_points"));
@@ -185,7 +179,6 @@ void SoftBody3D::_get_property_list(List<PropertyInfo> *p_list) const {
}
bool SoftBody3D::_set_property_pinned_points_indices(const Array &p_indices) {
-
const int p_indices_size = p_indices.size();
{ // Remove the pined points on physics server that will be removed by resize
@@ -204,8 +197,9 @@ bool SoftBody3D::_set_property_pinned_points_indices(const Array &p_indices) {
for (int i = 0; i < p_indices_size; ++i) {
point_index = p_indices.get(i);
if (w[i].point_index != point_index) {
- if (-1 != w[i].point_index)
+ if (-1 != w[i].point_index) {
pin_point(w[i].point_index, false);
+ }
w[i].point_index = point_index;
pin_point(w[i].point_index, true);
}
@@ -264,23 +258,21 @@ void SoftBody3D::_changed_callback(Object *p_changed, const char *p_prop) {
void SoftBody3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_WORLD: {
-
if (Engine::get_singleton()->is_editor_hint()) {
-
add_change_receptor(this);
}
- RID space = get_world()->get_space();
+ RID space = get_world_3d()->get_space();
PhysicsServer3D::get_singleton()->soft_body_set_space(physics_rid, space);
prepare_physics_server();
} break;
case NOTIFICATION_READY: {
- if (!parent_collision_ignore.is_empty())
+ if (!parent_collision_ignore.is_empty()) {
add_collision_exception_with(get_node(parent_collision_ignore));
+ }
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
if (Engine::get_singleton()->is_editor_hint()) {
_reset_points_offsets();
return;
@@ -296,12 +288,10 @@ void SoftBody3D::_notification(int p_what) {
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
_update_pickable();
} break;
case NOTIFICATION_EXIT_WORLD: {
-
PhysicsServer3D::get_singleton()->soft_body_set_space(physics_rid, RID());
} break;
@@ -319,7 +309,6 @@ void SoftBody3D::_notification(int p_what) {
}
void SoftBody3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &SoftBody3D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &SoftBody3D::get_collision_mask);
@@ -388,20 +377,21 @@ void SoftBody3D::_bind_methods() {
}
String SoftBody3D::get_configuration_warning() const {
-
String warning = MeshInstance3D::get_configuration_warning();
if (get_mesh().is_null()) {
- if (!warning.empty())
+ if (!warning.empty()) {
warning += "\n\n";
+ }
warning += TTR("This body will be ignored until you set a mesh.");
}
Transform t = get_transform();
if ((ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) {
- if (!warning.empty())
+ if (!warning.empty()) {
warning += "\n\n";
+ }
warning += TTR("Size changes to SoftBody3D will be overridden by the physics engine when running.\nChange the size in children collision shapes instead.");
}
@@ -410,8 +400,9 @@ String SoftBody3D::get_configuration_warning() const {
}
void SoftBody3D::_update_physics_server() {
- if (!simulation_started)
+ if (!simulation_started) {
return;
+ }
_update_cache_pin_points_datas();
// Submit bone attachment
@@ -425,11 +416,11 @@ void SoftBody3D::_update_physics_server() {
}
void SoftBody3D::_draw_soft_mesh() {
- if (get_mesh().is_null())
+ if (get_mesh().is_null()) {
return;
+ }
if (!rendering_server_handler.is_ready()) {
-
rendering_server_handler.prepare(get_mesh()->get_rid(), 0);
/// Necessary in order to render the mesh correctly (Soft body nodes are in global space)
@@ -448,24 +439,21 @@ void SoftBody3D::_draw_soft_mesh() {
}
void SoftBody3D::prepare_physics_server() {
-
if (Engine::get_singleton()->is_editor_hint()) {
-
- if (get_mesh().is_valid())
+ if (get_mesh().is_valid()) {
PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh());
- else
+ } else {
PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, nullptr);
+ }
return;
}
if (get_mesh().is_valid()) {
-
become_mesh_owner();
PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, get_mesh());
RS::get_singleton()->connect("frame_pre_draw", callable_mp(this, &SoftBody3D::_draw_soft_mesh));
} else {
-
PhysicsServer3D::get_singleton()->soft_body_set_mesh(physics_rid, nullptr);
if (RS::get_singleton()->is_connected("frame_pre_draw", callable_mp(this, &SoftBody3D::_draw_soft_mesh))) {
RS::get_singleton()->disconnect("frame_pre_draw", callable_mp(this, &SoftBody3D::_draw_soft_mesh));
@@ -474,8 +462,9 @@ void SoftBody3D::prepare_physics_server() {
}
void SoftBody3D::become_mesh_owner() {
- if (mesh.is_null())
+ if (mesh.is_null()) {
return;
+ }
if (!mesh_owner) {
mesh_owner = true;
@@ -515,6 +504,7 @@ void SoftBody3D::set_collision_mask(uint32_t p_mask) {
uint32_t SoftBody3D::get_collision_mask() const {
return collision_mask;
}
+
void SoftBody3D::set_collision_layer(uint32_t p_layer) {
collision_layer = p_layer;
PhysicsServer3D::get_singleton()->soft_body_set_collision_layer(physics_rid, p_layer);
@@ -526,10 +516,11 @@ uint32_t SoftBody3D::get_collision_layer() const {
void SoftBody3D::set_collision_mask_bit(int p_bit, bool p_value) {
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
@@ -539,10 +530,11 @@ bool SoftBody3D::get_collision_mask_bit(int p_bit) const {
void SoftBody3D::set_collision_layer_bit(int p_bit, bool p_value) {
uint32_t layer = get_collision_layer();
- if (p_value)
+ if (p_value) {
layer |= 1 << p_bit;
- else
+ } else {
layer &= ~(1 << p_bit);
+ }
set_collision_layer(layer);
}
@@ -691,25 +683,16 @@ bool SoftBody3D::is_point_pinned(int p_point_index) const {
}
void SoftBody3D::set_ray_pickable(bool p_ray_pickable) {
-
ray_pickable = p_ray_pickable;
_update_pickable();
}
bool SoftBody3D::is_ray_pickable() const {
-
return ray_pickable;
}
SoftBody3D::SoftBody3D() :
- physics_rid(PhysicsServer3D::get_singleton()->soft_body_create()),
- mesh_owner(false),
- collision_mask(1),
- collision_layer(1),
- simulation_started(false),
- pinned_points_cache_dirty(true),
- ray_pickable(true) {
-
+ physics_rid(PhysicsServer3D::get_singleton()->soft_body_create()) {
PhysicsServer3D::get_singleton()->body_attach_object_instance_id(physics_rid, get_instance_id());
}
@@ -730,14 +713,14 @@ void SoftBody3D::_make_cache_dirty() {
}
void SoftBody3D::_update_cache_pin_points_datas() {
- if (!pinned_points_cache_dirty)
+ if (!pinned_points_cache_dirty) {
return;
+ }
pinned_points_cache_dirty = false;
PinnedPoint *w = pinned_points.ptrw();
for (int i = pinned_points.size() - 1; 0 <= i; --i) {
-
if (!w[i].spatial_attachment_path.is_empty()) {
w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(w[i].spatial_attachment_path));
}
@@ -754,7 +737,6 @@ void SoftBody3D::_pin_point_on_physics_server(int p_point_index, bool pin) {
void SoftBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_attachment_path) {
SoftBody3D::PinnedPoint *pinned_point;
if (-1 == _get_pinned_point(p_point_index, pinned_point)) {
-
// Create new
PinnedPoint pp;
pp.point_index = p_point_index;
@@ -768,7 +750,6 @@ void SoftBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_
pinned_points.push_back(pp);
} else {
-
pinned_point->point_index = p_point_index;
pinned_point->spatial_attachment_path = p_spatial_attachment_path;
@@ -780,19 +761,20 @@ void SoftBody3D::_add_pinned_point(int p_point_index, const NodePath &p_spatial_
}
void SoftBody3D::_reset_points_offsets() {
-
- if (!Engine::get_singleton()->is_editor_hint())
+ if (!Engine::get_singleton()->is_editor_hint()) {
return;
+ }
const PinnedPoint *r = pinned_points.ptr();
PinnedPoint *w = pinned_points.ptrw();
for (int i = pinned_points.size() - 1; 0 <= i; --i) {
-
- if (!r[i].spatial_attachment)
+ if (!r[i].spatial_attachment) {
w[i].spatial_attachment = Object::cast_to<Node3D>(get_node(r[i].spatial_attachment_path));
+ }
- if (!r[i].spatial_attachment)
+ if (!r[i].spatial_attachment) {
continue;
+ }
w[i].offset = (r[i].spatial_attachment->get_global_transform().affine_inverse() * get_global_transform()).xform(PhysicsServer3D::get_singleton()->soft_body_get_point_global_position(physics_rid, r[i].point_index));
}
diff --git a/scene/3d/soft_body_3d.h b/scene/3d/soft_body_3d.h
index 7dd5880985..0063e342f2 100644
--- a/scene/3d/soft_body_3d.h
+++ b/scene/3d/soft_body_3d.h
@@ -36,7 +36,6 @@
class SoftBody3D;
class SoftBodyRenderingServerHandler {
-
friend class SoftBody3D;
RID mesh;
@@ -68,9 +67,9 @@ class SoftBody3D : public MeshInstance3D {
public:
struct PinnedPoint {
- int point_index;
+ int point_index = -1;
NodePath spatial_attachment_path;
- Node3D *spatial_attachment; // Cache
+ Node3D *spatial_attachment = nullptr; // Cache
Vector3 offset;
PinnedPoint();
@@ -83,19 +82,19 @@ private:
RID physics_rid;
- bool mesh_owner;
- uint32_t collision_mask;
- uint32_t collision_layer;
+ bool mesh_owner = false;
+ uint32_t collision_mask = 1;
+ uint32_t collision_layer = 1;
NodePath parent_collision_ignore;
Vector<PinnedPoint> pinned_points;
- bool simulation_started;
- bool pinned_points_cache_dirty;
+ bool simulation_started = false;
+ bool pinned_points_cache_dirty = true;
Ref<ArrayMesh> debug_mesh_cache;
class MeshInstance3D *debug_mesh;
bool capture_input_on_drag;
- bool ray_pickable;
+ bool ray_pickable = true;
void _update_pickable();
diff --git a/scene/3d/spring_arm_3d.cpp b/scene/3d/spring_arm_3d.cpp
index 0ffde7aa8f..9775ecc6c6 100644
--- a/scene/3d/spring_arm_3d.cpp
+++ b/scene/3d/spring_arm_3d.cpp
@@ -29,18 +29,12 @@
/*************************************************************************/
#include "spring_arm_3d.h"
+
#include "core/engine.h"
#include "scene/3d/collision_object_3d.h"
#include "scene/resources/sphere_shape_3d.h"
#include "servers/physics_server_3d.h"
-SpringArm3D::SpringArm3D() :
- spring_length(1),
- current_spring_length(0),
- keep_child_basis(false),
- mask(1),
- margin(0.01) {}
-
void SpringArm3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
@@ -60,7 +54,6 @@ void SpringArm3D::_notification(int p_what) {
}
void SpringArm3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_hit_length"), &SpringArm3D::get_hit_length);
ClassDB::bind_method(D_METHOD("set_length", "length"), &SpringArm3D::set_length);
@@ -90,8 +83,9 @@ float SpringArm3D::get_length() const {
}
void SpringArm3D::set_length(float p_length) {
- if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint()))
+ if (is_inside_tree() && (Engine::get_singleton()->is_editor_hint() || get_tree()->is_debugging_collisions_hint())) {
update_gizmo();
+ }
spring_length = p_length;
}
@@ -147,7 +141,7 @@ void SpringArm3D::process_spring() {
if (shape.is_null()) {
motion = Vector3(cast_direction * (spring_length));
PhysicsDirectSpaceState3D::RayResult r;
- bool intersected = get_world()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask);
+ bool intersected = get_world_3d()->get_direct_space_state()->intersect_ray(get_global_transform().origin, get_global_transform().origin + motion, r, excluded_objects, mask);
if (intersected) {
float dist = get_global_transform().origin.distance_to(r.position);
dist -= margin;
@@ -155,7 +149,7 @@ void SpringArm3D::process_spring() {
}
} else {
motion = Vector3(cast_direction * spring_length);
- get_world()->get_direct_space_state()->cast_motion(shape->get_rid(), get_global_transform(), motion, 0, motion_delta, motion_delta_unsafe, excluded_objects, mask);
+ get_world_3d()->get_direct_space_state()->cast_motion(shape->get_rid(), get_global_transform(), motion, 0, motion_delta, motion_delta_unsafe, excluded_objects, mask);
}
current_spring_length = spring_length * motion_delta;
@@ -163,7 +157,6 @@ void SpringArm3D::process_spring() {
childs_transform.origin = get_global_transform().origin + cast_direction * (spring_length * motion_delta);
for (int i = get_child_count() - 1; 0 <= i; --i) {
-
Node3D *child = Object::cast_to<Node3D>(get_child(i));
if (child) {
childs_transform.basis = child->get_global_transform().basis;
diff --git a/scene/3d/spring_arm_3d.h b/scene/3d/spring_arm_3d.h
index cb8a00ecf9..7f6fe2f1a2 100644
--- a/scene/3d/spring_arm_3d.h
+++ b/scene/3d/spring_arm_3d.h
@@ -38,11 +38,11 @@ class SpringArm3D : public Node3D {
Ref<Shape3D> shape;
Set<RID> excluded_objects;
- float spring_length;
- float current_spring_length;
- bool keep_child_basis;
- uint32_t mask;
- float margin;
+ float spring_length = 1;
+ float current_spring_length = 0;
+ bool keep_child_basis = false;
+ uint32_t mask = 1;
+ float margin = 0.01;
protected:
void _notification(int p_what);
@@ -62,7 +62,7 @@ public:
void set_margin(float p_margin);
float get_margin();
- SpringArm3D();
+ SpringArm3D() {}
private:
void process_spring();
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 85e5ebc475..3b76cb6499 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -34,14 +34,15 @@
#include "scene/scene_string_names.h"
Color SpriteBase3D::_get_color_accum() {
-
- if (!color_dirty)
+ if (!color_dirty) {
return color_accum;
+ }
- if (parent_sprite)
+ if (parent_sprite) {
color_accum = parent_sprite->_get_color_accum();
- else
+ } else {
color_accum = Color(1, 1, 1, 1);
+ }
color_accum.r *= modulate.r;
color_accum.g *= modulate.g;
@@ -52,25 +53,23 @@ Color SpriteBase3D::_get_color_accum() {
}
void SpriteBase3D::_propagate_color_changed() {
-
- if (color_dirty)
+ if (color_dirty) {
return;
+ }
color_dirty = true;
_queue_update();
for (List<SpriteBase3D *>::Element *E = children.front(); E; E = E->next()) {
-
E->get()->_propagate_color_changed();
}
}
void SpriteBase3D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
- if (!pending_update)
+ if (!pending_update) {
_im_update();
+ }
parent_sprite = Object::cast_to<SpriteBase3D>(get_parent());
if (parent_sprite) {
@@ -79,9 +78,7 @@ void SpriteBase3D::_notification(int p_what) {
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
if (parent_sprite) {
-
parent_sprite->children.erase(pI);
pI = nullptr;
parent_sprite = nullptr;
@@ -90,100 +87,89 @@ void SpriteBase3D::_notification(int p_what) {
}
void SpriteBase3D::set_centered(bool p_center) {
-
centered = p_center;
_queue_update();
}
bool SpriteBase3D::is_centered() const {
-
return centered;
}
void SpriteBase3D::set_offset(const Point2 &p_offset) {
-
offset = p_offset;
_queue_update();
}
-Point2 SpriteBase3D::get_offset() const {
+Point2 SpriteBase3D::get_offset() const {
return offset;
}
void SpriteBase3D::set_flip_h(bool p_flip) {
-
hflip = p_flip;
_queue_update();
}
-bool SpriteBase3D::is_flipped_h() const {
+bool SpriteBase3D::is_flipped_h() const {
return hflip;
}
void SpriteBase3D::set_flip_v(bool p_flip) {
-
vflip = p_flip;
_queue_update();
}
-bool SpriteBase3D::is_flipped_v() const {
+bool SpriteBase3D::is_flipped_v() const {
return vflip;
}
void SpriteBase3D::set_modulate(const Color &p_color) {
-
modulate = p_color;
_propagate_color_changed();
_queue_update();
}
Color SpriteBase3D::get_modulate() const {
-
return modulate;
}
void SpriteBase3D::set_pixel_size(float p_amount) {
-
pixel_size = p_amount;
_queue_update();
}
-float SpriteBase3D::get_pixel_size() const {
+float SpriteBase3D::get_pixel_size() const {
return pixel_size;
}
void SpriteBase3D::set_opacity(float p_amount) {
-
opacity = p_amount;
_queue_update();
}
-float SpriteBase3D::get_opacity() const {
+float SpriteBase3D::get_opacity() const {
return opacity;
}
void SpriteBase3D::set_axis(Vector3::Axis p_axis) {
-
ERR_FAIL_INDEX(p_axis, 3);
axis = p_axis;
_queue_update();
}
-Vector3::Axis SpriteBase3D::get_axis() const {
+Vector3::Axis SpriteBase3D::get_axis() const {
return axis;
}
void SpriteBase3D::_im_update() {
-
_draw();
pending_update = false;
}
void SpriteBase3D::_queue_update() {
-
- if (pending_update)
+ if (pending_update) {
return;
+ }
triangle_mesh.unref();
update_gizmo();
@@ -193,17 +179,17 @@ void SpriteBase3D::_queue_update() {
}
AABB SpriteBase3D::get_aabb() const {
-
return aabb;
}
-Vector<Face3> SpriteBase3D::get_faces(uint32_t p_usage_flags) const {
+Vector<Face3> SpriteBase3D::get_faces(uint32_t p_usage_flags) const {
return Vector<Face3>();
}
Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const {
- if (triangle_mesh.is_valid())
+ if (triangle_mesh.is_valid()) {
return triangle_mesh;
+ }
Vector<Vector3> faces;
faces.resize(6);
@@ -211,8 +197,9 @@ Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const {
Rect2 final_rect = get_item_rect();
- if (final_rect.size.x == 0 || final_rect.size.y == 0)
+ if (final_rect.size.x == 0 || final_rect.size.y == 0) {
return Ref<TriangleMesh>();
+ }
float pixel_size = get_pixel_size();
@@ -260,7 +247,6 @@ Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const {
}
void SpriteBase3D::set_draw_flag(DrawFlags p_flag, bool p_enable) {
-
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
flags[p_flag] = p_enable;
_queue_update();
@@ -272,31 +258,26 @@ bool SpriteBase3D::get_draw_flag(DrawFlags p_flag) const {
}
void SpriteBase3D::set_alpha_cut_mode(AlphaCutMode p_mode) {
-
ERR_FAIL_INDEX(p_mode, 3);
alpha_cut = p_mode;
_queue_update();
}
SpriteBase3D::AlphaCutMode SpriteBase3D::get_alpha_cut_mode() const {
-
return alpha_cut;
}
void SpriteBase3D::set_billboard_mode(StandardMaterial3D::BillboardMode p_mode) {
-
ERR_FAIL_INDEX(p_mode, 3);
billboard_mode = p_mode;
_queue_update();
}
StandardMaterial3D::BillboardMode SpriteBase3D::get_billboard_mode() const {
-
return billboard_mode;
}
void SpriteBase3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_centered", "centered"), &SpriteBase3D::set_centered);
ClassDB::bind_method(D_METHOD("is_centered"), &SpriteBase3D::is_centered);
@@ -359,7 +340,6 @@ void SpriteBase3D::_bind_methods() {
}
SpriteBase3D::SpriteBase3D() {
-
color_dirty = true;
centered = true;
hflip = false;
@@ -367,8 +347,9 @@ SpriteBase3D::SpriteBase3D() {
parent_sprite = nullptr;
pI = nullptr;
- for (int i = 0; i < FLAG_MAX; i++)
+ for (int i = 0; i < FLAG_MAX; i++) {
flags[i] = i == FLAG_TRANSPARENT || i == FLAG_DOUBLE_SIDED;
+ }
alpha_cut = ALPHA_CUT_DISABLED;
billboard_mode = StandardMaterial3D::BILLBOARD_DISABLED;
@@ -382,46 +363,50 @@ SpriteBase3D::SpriteBase3D() {
}
SpriteBase3D::~SpriteBase3D() {
-
RenderingServer::get_singleton()->free(immediate);
}
///////////////////////////////////////////
void Sprite3D::_draw() {
-
RID immediate = get_immediate();
RS::get_singleton()->immediate_clear(immediate);
- if (!texture.is_valid())
+ if (!texture.is_valid()) {
return;
+ }
Vector2 tsize = texture->get_size();
- if (tsize.x == 0 || tsize.y == 0)
+ if (tsize.x == 0 || tsize.y == 0) {
return;
+ }
Rect2 base_rect;
- if (region)
+ if (region) {
base_rect = region_rect;
- else
+ } else {
base_rect = Rect2(0, 0, texture->get_width(), texture->get_height());
+ }
Size2 frame_size = base_rect.size / Size2(hframes, vframes);
Point2 frame_offset = Point2(frame % hframes, frame / hframes);
frame_offset *= frame_size;
Point2 dest_offset = get_offset();
- if (is_centered())
+ if (is_centered()) {
dest_offset -= frame_size / 2;
+ }
Rect2 src_rect(base_rect.position + frame_offset, frame_size);
Rect2 final_dst_rect(dest_offset, frame_size);
Rect2 final_rect;
Rect2 final_src_rect;
- if (!texture->get_rect_region(final_dst_rect, src_rect, final_rect, final_src_rect))
+ if (!texture->get_rect_region(final_dst_rect, src_rect, final_rect, final_src_rect)) {
return;
+ }
- if (final_rect.size.x == 0 || final_rect.size.y == 0)
+ if (final_rect.size.x == 0 || final_rect.size.y == 0) {
return;
+ }
Color color = _get_color_accum();
color.a *= get_opacity();
@@ -458,7 +443,6 @@ void Sprite3D::_draw() {
SWAP(uvs[2], uvs[3]);
}
if (is_flipped_v()) {
-
SWAP(uvs[0], uvs[3]);
SWAP(uvs[1], uvs[2]);
}
@@ -499,7 +483,6 @@ void Sprite3D::_draw() {
AABB aabb;
for (int i = 0; i < 6; i++) {
-
static const int index[6] = { 0, 1, 2, 0, 2, 3 };
RS::get_singleton()->immediate_normal(immediate, normal);
@@ -527,9 +510,9 @@ void Sprite3D::_texture_changed() {
}
void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) {
-
- if (p_texture == texture)
+ if (p_texture == texture) {
return;
+ }
if (texture.is_valid()) {
texture->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Sprite3D::_texture_changed));
}
@@ -541,26 +524,23 @@ void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) {
}
Ref<Texture2D> Sprite3D::get_texture() const {
-
return texture;
}
void Sprite3D::set_region(bool p_region) {
-
- if (p_region == region)
+ if (p_region == region) {
return;
+ }
region = p_region;
_queue_update();
}
bool Sprite3D::is_region() const {
-
return region;
}
void Sprite3D::set_region_rect(const Rect2 &p_region_rect) {
-
bool changed = region_rect != p_region_rect;
region_rect = p_region_rect;
if (region && changed) {
@@ -569,12 +549,10 @@ void Sprite3D::set_region_rect(const Rect2 &p_region_rect) {
}
Rect2 Sprite3D::get_region_rect() const {
-
return region_rect;
}
void Sprite3D::set_frame(int p_frame) {
-
ERR_FAIL_INDEX(p_frame, int64_t(vframes) * hframes);
frame = p_frame;
@@ -587,7 +565,6 @@ void Sprite3D::set_frame(int p_frame) {
}
int Sprite3D::get_frame() const {
-
return frame;
}
@@ -603,33 +580,31 @@ Vector2 Sprite3D::get_frame_coords() const {
}
void Sprite3D::set_vframes(int p_amount) {
-
ERR_FAIL_COND(p_amount < 1);
vframes = p_amount;
_queue_update();
_change_notify();
}
-int Sprite3D::get_vframes() const {
+int Sprite3D::get_vframes() const {
return vframes;
}
void Sprite3D::set_hframes(int p_amount) {
-
ERR_FAIL_COND(p_amount < 1);
hframes = p_amount;
_queue_update();
_change_notify();
}
-int Sprite3D::get_hframes() const {
+int Sprite3D::get_hframes() const {
return hframes;
}
Rect2 Sprite3D::get_item_rect() const {
-
- if (texture.is_null())
+ if (texture.is_null()) {
return Rect2(0, 0, 1, 1);
+ }
/*
if (texture.is_null())
return CanvasItem::get_item_rect();
@@ -638,7 +613,6 @@ Rect2 Sprite3D::get_item_rect() const {
Size2i s;
if (region) {
-
s = region_rect.size;
} else {
s = texture->get_size();
@@ -646,17 +620,18 @@ Rect2 Sprite3D::get_item_rect() const {
}
Point2 ofs = get_offset();
- if (is_centered())
+ if (is_centered()) {
ofs -= s / 2;
+ }
- if (s == Size2(0, 0))
+ if (s == Size2(0, 0)) {
s = Size2(1, 1);
+ }
return Rect2(ofs, s);
}
void Sprite3D::_validate_property(PropertyInfo &property) const {
-
if (property.name == "frame") {
property.hint = PROPERTY_HINT_RANGE;
property.hint_string = "0," + itos(vframes * hframes - 1) + ",1";
@@ -669,7 +644,6 @@ void Sprite3D::_validate_property(PropertyInfo &property) const {
}
void Sprite3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &Sprite3D::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &Sprite3D::get_texture);
@@ -705,7 +679,6 @@ void Sprite3D::_bind_methods() {
}
Sprite3D::Sprite3D() {
-
region = false;
frame = 0;
vframes = 1;
@@ -715,7 +688,6 @@ Sprite3D::Sprite3D() {
////////////////////////////////////////
void AnimatedSprite3D::_draw() {
-
RID immediate = get_immediate();
RS::get_singleton()->immediate_clear(immediate);
@@ -732,11 +704,13 @@ void AnimatedSprite3D::_draw() {
}
Ref<Texture2D> texture = frames->get_frame(animation, frame);
- if (!texture.is_valid())
+ if (!texture.is_valid()) {
return; //no texuture no life
+ }
Vector2 tsize = texture->get_size();
- if (tsize.x == 0 || tsize.y == 0)
+ if (tsize.x == 0 || tsize.y == 0) {
return;
+ }
Size2i s = tsize;
Rect2 src_rect;
@@ -744,18 +718,21 @@ void AnimatedSprite3D::_draw() {
src_rect.size = s;
Point2 ofs = get_offset();
- if (is_centered())
+ if (is_centered()) {
ofs -= s / 2;
+ }
Rect2 dst_rect(ofs, s);
Rect2 final_rect;
Rect2 final_src_rect;
- if (!texture->get_rect_region(dst_rect, src_rect, final_rect, final_src_rect))
+ if (!texture->get_rect_region(dst_rect, src_rect, final_rect, final_src_rect)) {
return;
+ }
- if (final_rect.size.x == 0 || final_rect.size.y == 0)
+ if (final_rect.size.x == 0 || final_rect.size.y == 0) {
return;
+ }
Color color = _get_color_accum();
color.a *= get_opacity();
@@ -792,7 +769,6 @@ void AnimatedSprite3D::_draw() {
SWAP(uvs[2], uvs[3]);
}
if (is_flipped_v()) {
-
SWAP(uvs[0], uvs[3]);
SWAP(uvs[1], uvs[2]);
}
@@ -834,7 +810,6 @@ void AnimatedSprite3D::_draw() {
AABB aabb;
for (int i = 0; i < 6; i++) {
-
static const int indices[6] = {
0, 1, 2,
0, 2, 3
@@ -861,11 +836,10 @@ void AnimatedSprite3D::_draw() {
}
void AnimatedSprite3D::_validate_property(PropertyInfo &property) const {
-
- if (!frames.is_valid())
+ if (!frames.is_valid()) {
return;
+ }
if (property.name == "animation") {
-
property.hint = PROPERTY_HINT_ENUM;
List<StringName> names;
frames->get_animation_list(&names);
@@ -903,27 +877,27 @@ void AnimatedSprite3D::_validate_property(PropertyInfo &property) const {
}
void AnimatedSprite3D::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_INTERNAL_PROCESS: {
-
- if (frames.is_null())
+ if (frames.is_null()) {
return;
- if (!frames->has_animation(animation))
+ }
+ if (!frames->has_animation(animation)) {
return;
- if (frame < 0)
+ }
+ if (frame < 0) {
return;
+ }
float speed = frames->get_animation_speed(animation);
- if (speed == 0)
+ if (speed == 0) {
return; //do nothing
+ }
float remaining = get_process_delta_time();
while (remaining) {
-
if (timeout <= 0) {
-
timeout = 1.0 / speed;
int fc = frames->get_frame_count(animation);
@@ -950,12 +924,13 @@ void AnimatedSprite3D::_notification(int p_what) {
}
void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
-
- if (frames.is_valid())
+ if (frames.is_valid()) {
frames->disconnect("changed", callable_mp(this, &AnimatedSprite3D::_res_changed));
+ }
frames = p_frames;
- if (frames.is_valid())
+ if (frames.is_valid()) {
frames->connect("changed", callable_mp(this, &AnimatedSprite3D::_res_changed));
+ }
if (!frames.is_valid()) {
frame = 0;
@@ -970,27 +945,28 @@ void AnimatedSprite3D::set_sprite_frames(const Ref<SpriteFrames> &p_frames) {
}
Ref<SpriteFrames> AnimatedSprite3D::get_sprite_frames() const {
-
return frames;
}
void AnimatedSprite3D::set_frame(int p_frame) {
-
if (!frames.is_valid()) {
return;
}
if (frames->has_animation(animation)) {
int limit = frames->get_frame_count(animation);
- if (p_frame >= limit)
+ if (p_frame >= limit) {
p_frame = limit - 1;
+ }
}
- if (p_frame < 0)
+ if (p_frame < 0) {
p_frame = 0;
+ }
- if (frame == p_frame)
+ if (frame == p_frame) {
return;
+ }
frame = p_frame;
_reset_timeout();
@@ -998,36 +974,38 @@ void AnimatedSprite3D::set_frame(int p_frame) {
_change_notify("frame");
emit_signal(SceneStringNames::get_singleton()->frame_changed);
}
-int AnimatedSprite3D::get_frame() const {
+int AnimatedSprite3D::get_frame() const {
return frame;
}
Rect2 AnimatedSprite3D::get_item_rect() const {
-
if (!frames.is_valid() || !frames->has_animation(animation) || frame < 0 || frame >= frames->get_frame_count(animation)) {
return Rect2(0, 0, 1, 1);
}
Ref<Texture2D> t;
- if (animation)
+ if (animation) {
t = frames->get_frame(animation, frame);
- if (t.is_null())
+ }
+ if (t.is_null()) {
return Rect2(0, 0, 1, 1);
+ }
Size2i s = t->get_size();
Point2 ofs = get_offset();
- if (centered)
+ if (centered) {
ofs -= s / 2;
+ }
- if (s == Size2(0, 0))
+ if (s == Size2(0, 0)) {
s = Size2(1, 1);
+ }
return Rect2(ofs, s);
}
void AnimatedSprite3D::_res_changed() {
-
set_frame(frame);
_change_notify("frame");
_change_notify("animation");
@@ -1035,40 +1013,37 @@ void AnimatedSprite3D::_res_changed() {
}
void AnimatedSprite3D::_set_playing(bool p_playing) {
-
- if (playing == p_playing)
+ if (playing == p_playing) {
return;
+ }
playing = p_playing;
_reset_timeout();
set_process_internal(playing);
}
bool AnimatedSprite3D::_is_playing() const {
-
return playing;
}
void AnimatedSprite3D::play(const StringName &p_animation) {
-
- if (p_animation)
+ if (p_animation) {
set_animation(p_animation);
+ }
_set_playing(true);
}
void AnimatedSprite3D::stop() {
-
_set_playing(false);
}
bool AnimatedSprite3D::is_playing() const {
-
return is_processing();
}
void AnimatedSprite3D::_reset_timeout() {
-
- if (!playing)
+ if (!playing) {
return;
+ }
if (frames.is_valid() && frames->has_animation(animation)) {
float speed = frames->get_animation_speed(animation);
@@ -1083,9 +1058,9 @@ void AnimatedSprite3D::_reset_timeout() {
}
void AnimatedSprite3D::set_animation(const StringName &p_animation) {
-
- if (animation == p_animation)
+ if (animation == p_animation) {
return;
+ }
animation = p_animation;
_reset_timeout();
@@ -1093,13 +1068,12 @@ void AnimatedSprite3D::set_animation(const StringName &p_animation) {
_change_notify();
_queue_update();
}
-StringName AnimatedSprite3D::get_animation() const {
+StringName AnimatedSprite3D::get_animation() const {
return animation;
}
String AnimatedSprite3D::get_configuration_warning() const {
-
if (frames.is_null()) {
return TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames.");
}
@@ -1108,7 +1082,6 @@ String AnimatedSprite3D::get_configuration_warning() const {
}
void AnimatedSprite3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_sprite_frames", "sprite_frames"), &AnimatedSprite3D::set_sprite_frames);
ClassDB::bind_method(D_METHOD("get_sprite_frames"), &AnimatedSprite3D::get_sprite_frames);
@@ -1134,7 +1107,6 @@ void AnimatedSprite3D::_bind_methods() {
}
AnimatedSprite3D::AnimatedSprite3D() {
-
frame = 0;
playing = false;
animation = "default";
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index 64bef41fd8..721bed56f1 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -35,7 +35,6 @@
#include "scene/3d/visual_instance_3d.h"
class SpriteBase3D : public GeometryInstance3D {
-
GDCLASS(SpriteBase3D, GeometryInstance3D);
mutable Ref<TriangleMesh> triangle_mesh; //cached
@@ -145,7 +144,6 @@ public:
};
class Sprite3D : public SpriteBase3D {
-
GDCLASS(Sprite3D, SpriteBase3D);
Ref<Texture2D> texture;
@@ -194,7 +192,6 @@ public:
};
class AnimatedSprite3D : public SpriteBase3D {
-
GDCLASS(AnimatedSprite3D, SpriteBase3D);
Ref<SpriteFrames> frames;
diff --git a/scene/3d/vehicle_body_3d.cpp b/scene/3d/vehicle_body_3d.cpp
index 5c2fa59a21..9c6b940b00 100644
--- a/scene/3d/vehicle_body_3d.cpp
+++ b/scene/3d/vehicle_body_3d.cpp
@@ -44,7 +44,7 @@ public:
real_t getDiagonal() const { return m_Adiag; }
- btVehicleJacobianEntry(){};
+ btVehicleJacobianEntry() {}
//constraint between two different rigidbodies
btVehicleJacobianEntry(
const Basis &world2A,
@@ -79,12 +79,11 @@ public:
};
void VehicleWheel3D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
VehicleBody3D *cb = Object::cast_to<VehicleBody3D>(get_parent());
- if (!cb)
+ if (!cb) {
return;
+ }
body = cb;
local_xform = get_transform();
cb->wheels.push_back(this);
@@ -94,10 +93,10 @@ void VehicleWheel3D::_notification(int p_what) {
m_wheelAxleCS = get_transform().basis.get_axis(Vector3::AXIS_X).normalized();
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
VehicleBody3D *cb = Object::cast_to<VehicleBody3D>(get_parent());
- if (!cb)
+ if (!cb) {
return;
+ }
cb->wheels.erase(this);
body = nullptr;
}
@@ -112,7 +111,6 @@ String VehicleWheel3D::get_configuration_warning() const {
}
void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) {
-
if (m_raycastInfo.m_isInContact)
{
@@ -145,77 +143,68 @@ void VehicleWheel3D::_update(PhysicsDirectBodyState3D *s) {
}
void VehicleWheel3D::set_radius(float p_radius) {
-
m_wheelRadius = p_radius;
update_gizmo();
}
float VehicleWheel3D::get_radius() const {
-
return m_wheelRadius;
}
void VehicleWheel3D::set_suspension_rest_length(float p_length) {
-
m_suspensionRestLength = p_length;
update_gizmo();
}
-float VehicleWheel3D::get_suspension_rest_length() const {
+float VehicleWheel3D::get_suspension_rest_length() const {
return m_suspensionRestLength;
}
void VehicleWheel3D::set_suspension_travel(float p_length) {
-
m_maxSuspensionTravelCm = p_length / 0.01;
}
-float VehicleWheel3D::get_suspension_travel() const {
+float VehicleWheel3D::get_suspension_travel() const {
return m_maxSuspensionTravelCm * 0.01;
}
void VehicleWheel3D::set_suspension_stiffness(float p_value) {
-
m_suspensionStiffness = p_value;
}
-float VehicleWheel3D::get_suspension_stiffness() const {
+float VehicleWheel3D::get_suspension_stiffness() const {
return m_suspensionStiffness;
}
void VehicleWheel3D::set_suspension_max_force(float p_value) {
-
m_maxSuspensionForce = p_value;
}
-float VehicleWheel3D::get_suspension_max_force() const {
+float VehicleWheel3D::get_suspension_max_force() const {
return m_maxSuspensionForce;
}
void VehicleWheel3D::set_damping_compression(float p_value) {
-
m_wheelsDampingCompression = p_value;
}
-float VehicleWheel3D::get_damping_compression() const {
+float VehicleWheel3D::get_damping_compression() const {
return m_wheelsDampingCompression;
}
void VehicleWheel3D::set_damping_relaxation(float p_value) {
-
m_wheelsDampingRelaxation = p_value;
}
-float VehicleWheel3D::get_damping_relaxation() const {
+float VehicleWheel3D::get_damping_relaxation() const {
return m_wheelsDampingRelaxation;
}
void VehicleWheel3D::set_friction_slip(float p_value) {
-
m_frictionSlip = p_value;
}
-float VehicleWheel3D::get_friction_slip() const {
+float VehicleWheel3D::get_friction_slip() const {
return m_frictionSlip;
}
@@ -232,7 +221,6 @@ bool VehicleWheel3D::is_in_contact() const {
}
void VehicleWheel3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_radius", "length"), &VehicleWheel3D::set_radius);
ClassDB::bind_method(D_METHOD("get_radius"), &VehicleWheel3D::get_radius);
@@ -303,65 +291,54 @@ void VehicleWheel3D::_bind_methods() {
}
void VehicleWheel3D::set_engine_force(float p_engine_force) {
-
m_engineForce = p_engine_force;
}
float VehicleWheel3D::get_engine_force() const {
-
return m_engineForce;
}
void VehicleWheel3D::set_brake(float p_brake) {
-
m_brake = p_brake;
}
-float VehicleWheel3D::get_brake() const {
+float VehicleWheel3D::get_brake() const {
return m_brake;
}
void VehicleWheel3D::set_steering(float p_steering) {
-
m_steering = p_steering;
}
-float VehicleWheel3D::get_steering() const {
+float VehicleWheel3D::get_steering() const {
return m_steering;
}
void VehicleWheel3D::set_use_as_traction(bool p_enable) {
-
engine_traction = p_enable;
}
bool VehicleWheel3D::is_used_as_traction() const {
-
return engine_traction;
}
void VehicleWheel3D::set_use_as_steering(bool p_enabled) {
-
steers = p_enabled;
}
bool VehicleWheel3D::is_used_as_steering() const {
-
return steers;
}
float VehicleWheel3D::get_skidinfo() const {
-
return m_skidInfo;
}
float VehicleWheel3D::get_rpm() const {
-
return m_rpm;
}
VehicleWheel3D::VehicleWheel3D() {
-
steers = false;
engine_traction = false;
m_steering = real_t(0.);
@@ -389,7 +366,6 @@ VehicleWheel3D::VehicleWheel3D() {
}
void VehicleBody3D::_update_wheel_transform(VehicleWheel3D &wheel, PhysicsDirectBodyState3D *s) {
-
wheel.m_raycastInfo.m_isInContact = false;
Transform chassisTrans = s->get_transform();
@@ -406,7 +382,6 @@ void VehicleBody3D::_update_wheel_transform(VehicleWheel3D &wheel, PhysicsDirect
}
void VehicleBody3D::_update_wheel(int p_idx, PhysicsDirectBodyState3D *s) {
-
VehicleWheel3D &wheel = *wheels[p_idx];
_update_wheel_transform(wheel, s);
@@ -431,7 +406,6 @@ void VehicleBody3D::_update_wheel(int p_idx, PhysicsDirectBodyState3D *s) {
}
real_t VehicleBody3D::_ray_cast(int p_idx, PhysicsDirectBodyState3D *s) {
-
VehicleWheel3D &wheel = *wheels[p_idx];
_update_wheel_transform(wheel, s);
@@ -462,8 +436,9 @@ real_t VehicleBody3D::_ray_cast(int p_idx, PhysicsDirectBodyState3D *s) {
wheel.m_raycastInfo.m_contactNormalWS = rr.normal;
wheel.m_raycastInfo.m_isInContact = true;
- if (rr.collider)
+ if (rr.collider) {
wheel.m_raycastInfo.m_groundObject = Object::cast_to<PhysicsBody3D>(rr.collider);
+ }
real_t hitDistance = param * raylen;
wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelRadius;
@@ -514,7 +489,6 @@ real_t VehicleBody3D::_ray_cast(int p_idx, PhysicsDirectBodyState3D *s) {
}
void VehicleBody3D::_update_suspension(PhysicsDirectBodyState3D *s) {
-
real_t chassisMass = mass;
for (int w_it = 0; w_it < wheels.size(); w_it++) {
@@ -560,7 +534,6 @@ void VehicleBody3D::_update_suspension(PhysicsDirectBodyState3D *s) {
//bilateral constraint between two dynamic objects
void VehicleBody3D::_resolve_single_bilateral(PhysicsDirectBodyState3D *s, const Vector3 &pos1,
PhysicsBody3D *body2, const Vector3 &pos2, const Vector3 &normal, real_t &impulse, const real_t p_rollInfluence) {
-
real_t normalLenSqr = normal.length_squared();
//ERR_FAIL_COND( normalLenSqr < real_t(1.1));
@@ -571,15 +544,17 @@ void VehicleBody3D::_resolve_single_bilateral(PhysicsDirectBodyState3D *s, const
Vector3 rel_pos1 = pos1 - s->get_transform().origin;
Vector3 rel_pos2;
- if (body2)
+ if (body2) {
rel_pos2 = pos2 - body2->get_global_transform().origin;
+ }
//this jacobian entry could be re-used for all iterations
Vector3 vel1 = s->get_linear_velocity() + (s->get_angular_velocity()).cross(rel_pos1); // * mPos);
Vector3 vel2;
- if (body2)
+ if (body2) {
vel2 = body2->get_linear_velocity() + body2->get_angular_velocity().cross(rel_pos2);
+ }
Vector3 vel = vel1 - vel2;
@@ -668,15 +643,15 @@ VehicleBody3D::btVehicleWheelContactPoint::btVehicleWheelContactPoint(PhysicsDir
}
real_t VehicleBody3D::_calc_rolling_friction(btVehicleWheelContactPoint &contactPoint) {
-
real_t j1 = 0.f;
const Vector3 &contactPosWorld = contactPoint.m_frictionPositionWorld;
Vector3 rel_pos1 = contactPosWorld - contactPoint.m_s->get_transform().origin;
Vector3 rel_pos2;
- if (contactPoint.m_body1)
+ if (contactPoint.m_body1) {
rel_pos2 = contactPosWorld - contactPoint.m_body1->get_global_transform().origin;
+ }
real_t maxImpulse = contactPoint.m_maxImpulse;
@@ -699,11 +674,11 @@ real_t VehicleBody3D::_calc_rolling_friction(btVehicleWheelContactPoint &contact
static const real_t sideFrictionStiffness2 = real_t(1.0);
void VehicleBody3D::_update_friction(PhysicsDirectBodyState3D *s) {
-
//calculate the impulse, so that the wheels don't move sidewards
int numWheel = wheels.size();
- if (!numWheel)
+ if (!numWheel) {
return;
+ }
m_forwardWS.resize(numWheel);
m_axle.resize(numWheel);
@@ -717,13 +692,10 @@ void VehicleBody3D::_update_friction(PhysicsDirectBodyState3D *s) {
}
{
-
for (int i = 0; i < wheels.size(); i++) {
-
VehicleWheel3D &wheelInfo = *wheels[i];
if (wheelInfo.m_raycastInfo.m_isInContact) {
-
//const btTransform& wheelTrans = getWheelTransformWS( i );
Basis wheelBasis0 = wheelInfo.m_worldTransform.basis; //get_global_transform().basis;
@@ -851,7 +823,6 @@ void VehicleBody3D::_update_friction(PhysicsDirectBodyState3D *s) {
}
void VehicleBody3D::_direct_state_changed(Object *p_state) {
-
RigidBody3D::_direct_state_changed(p_state);
state = Object::cast_to<PhysicsDirectBodyState3D>(p_state);
@@ -859,12 +830,10 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) {
float step = state->get_step();
for (int i = 0; i < wheels.size(); i++) {
-
_update_wheel(i, state);
}
for (int i = 0; i < wheels.size(); i++) {
-
_ray_cast(i, state);
wheels[i]->set_transform(state->get_transform().inverse() * wheels[i]->m_worldTransform);
}
@@ -872,7 +841,6 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) {
_update_suspension(state);
for (int i = 0; i < wheels.size(); i++) {
-
//apply suspension force
VehicleWheel3D &wheel = *wheels[i];
@@ -921,49 +889,46 @@ void VehicleBody3D::_direct_state_changed(Object *p_state) {
}
void VehicleBody3D::set_engine_force(float p_engine_force) {
-
engine_force = p_engine_force;
for (int i = 0; i < wheels.size(); i++) {
VehicleWheel3D &wheelInfo = *wheels[i];
- if (wheelInfo.engine_traction)
+ if (wheelInfo.engine_traction) {
wheelInfo.m_engineForce = p_engine_force;
+ }
}
}
float VehicleBody3D::get_engine_force() const {
-
return engine_force;
}
void VehicleBody3D::set_brake(float p_brake) {
-
brake = p_brake;
for (int i = 0; i < wheels.size(); i++) {
VehicleWheel3D &wheelInfo = *wheels[i];
wheelInfo.m_brake = p_brake;
}
}
-float VehicleBody3D::get_brake() const {
+float VehicleBody3D::get_brake() const {
return brake;
}
void VehicleBody3D::set_steering(float p_steering) {
-
m_steeringValue = p_steering;
for (int i = 0; i < wheels.size(); i++) {
VehicleWheel3D &wheelInfo = *wheels[i];
- if (wheelInfo.steers)
+ if (wheelInfo.steers) {
wheelInfo.m_steering = p_steering;
+ }
}
}
-float VehicleBody3D::get_steering() const {
+float VehicleBody3D::get_steering() const {
return m_steeringValue;
}
void VehicleBody3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_engine_force", "engine_force"), &VehicleBody3D::set_engine_force);
ClassDB::bind_method(D_METHOD("get_engine_force"), &VehicleBody3D::get_engine_force);
@@ -980,7 +945,6 @@ void VehicleBody3D::_bind_methods() {
}
VehicleBody3D::VehicleBody3D() {
-
m_pitchControl = 0;
m_currentVehicleSpeedKmHour = real_t(0.);
m_steeringValue = real_t(0.);
diff --git a/scene/3d/vehicle_body_3d.h b/scene/3d/vehicle_body_3d.h
index d5e896263d..e76f44acfd 100644
--- a/scene/3d/vehicle_body_3d.h
+++ b/scene/3d/vehicle_body_3d.h
@@ -36,7 +36,6 @@
class VehicleBody3D;
class VehicleWheel3D : public Node3D {
-
GDCLASS(VehicleWheel3D, Node3D);
friend class VehicleBody3D;
@@ -152,7 +151,6 @@ public:
};
class VehicleBody3D : public RigidBody3D {
-
GDCLASS(VehicleBody3D, RigidBody3D);
float engine_force;
diff --git a/scene/3d/velocity_tracker_3d.cpp b/scene/3d/velocity_tracker_3d.cpp
index c9b95e6397..db10f3273b 100644
--- a/scene/3d/velocity_tracker_3d.cpp
+++ b/scene/3d/velocity_tracker_3d.cpp
@@ -32,16 +32,14 @@
#include "core/engine.h"
void VelocityTracker3D::set_track_physics_step(bool p_track_physics_step) {
-
physics_step = p_track_physics_step;
}
bool VelocityTracker3D::is_tracking_physics_step() const {
-
return physics_step;
}
-void VelocityTracker3D::update_position(const Vector3 &p_position) {
+void VelocityTracker3D::update_position(const Vector3 &p_position) {
PositionHistory ph;
ph.position = p_position;
if (physics_step) {
@@ -59,8 +57,8 @@ void VelocityTracker3D::update_position(const Vector3 &p_position) {
position_history.write[0] = ph;
}
-Vector3 VelocityTracker3D::get_tracked_linear_velocity() const {
+Vector3 VelocityTracker3D::get_tracked_linear_velocity() const {
Vector3 linear_velocity;
float max_time = 1 / 5.0; //maximum time to interpolate a velocity
@@ -90,8 +88,9 @@ Vector3 VelocityTracker3D::get_tracked_linear_velocity() const {
delta = double(diff) / 1000000.0;
}
- if (base_time + time_accum + delta > max_time)
+ if (base_time + time_accum + delta > max_time) {
break;
+ }
distance_accum += distance;
time_accum += delta;
@@ -105,7 +104,6 @@ Vector3 VelocityTracker3D::get_tracked_linear_velocity() const {
}
void VelocityTracker3D::reset(const Vector3 &p_new_pos) {
-
PositionHistory ph;
ph.position = p_new_pos;
if (physics_step) {
@@ -119,7 +117,6 @@ void VelocityTracker3D::reset(const Vector3 &p_new_pos) {
}
void VelocityTracker3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_track_physics_step", "enable"), &VelocityTracker3D::set_track_physics_step);
ClassDB::bind_method(D_METHOD("is_tracking_physics_step"), &VelocityTracker3D::is_tracking_physics_step);
ClassDB::bind_method(D_METHOD("update_position", "position"), &VelocityTracker3D::update_position);
diff --git a/scene/3d/visibility_notifier_3d.cpp b/scene/3d/visibility_notifier_3d.cpp
index 2f657fe7b1..a64b0df1cc 100644
--- a/scene/3d/visibility_notifier_3d.cpp
+++ b/scene/3d/visibility_notifier_3d.cpp
@@ -37,7 +37,6 @@
#include "scene/scene_string_names.h"
void VisibilityNotifier3D::_enter_camera(Camera3D *p_camera) {
-
ERR_FAIL_COND(cameras.has(p_camera));
cameras.insert(p_camera);
if (cameras.size() == 1) {
@@ -49,7 +48,6 @@ void VisibilityNotifier3D::_enter_camera(Camera3D *p_camera) {
}
void VisibilityNotifier3D::_exit_camera(Camera3D *p_camera) {
-
ERR_FAIL_COND(!cameras.has(p_camera));
cameras.erase(p_camera);
@@ -62,13 +60,13 @@ void VisibilityNotifier3D::_exit_camera(Camera3D *p_camera) {
}
void VisibilityNotifier3D::set_aabb(const AABB &p_aabb) {
-
- if (aabb == p_aabb)
+ if (aabb == p_aabb) {
return;
+ }
aabb = p_aabb;
if (is_inside_world()) {
- get_world()->_update_notifier(this, get_global_transform().xform(aabb));
+ get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb));
}
_change_notify("aabb");
@@ -76,35 +74,28 @@ void VisibilityNotifier3D::set_aabb(const AABB &p_aabb) {
}
AABB VisibilityNotifier3D::get_aabb() const {
-
return aabb;
}
void VisibilityNotifier3D::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_WORLD: {
-
- get_world()->_register_notifier(this, get_global_transform().xform(aabb));
+ get_world_3d()->_register_notifier(this, get_global_transform().xform(aabb));
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
- get_world()->_update_notifier(this, get_global_transform().xform(aabb));
+ get_world_3d()->_update_notifier(this, get_global_transform().xform(aabb));
} break;
case NOTIFICATION_EXIT_WORLD: {
-
- get_world()->_remove_notifier(this);
+ get_world_3d()->_remove_notifier(this);
} break;
}
}
bool VisibilityNotifier3D::is_on_screen() const {
-
return cameras.size() != 0;
}
void VisibilityNotifier3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_aabb", "rect"), &VisibilityNotifier3D::set_aabb);
ClassDB::bind_method(D_METHOD("get_aabb"), &VisibilityNotifier3D::get_aabb);
ClassDB::bind_method(D_METHOD("is_on_screen"), &VisibilityNotifier3D::is_on_screen);
@@ -118,7 +109,6 @@ void VisibilityNotifier3D::_bind_methods() {
}
VisibilityNotifier3D::VisibilityNotifier3D() {
-
aabb = AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
set_notify_transform(true);
}
@@ -126,9 +116,7 @@ VisibilityNotifier3D::VisibilityNotifier3D() {
//////////////////////////////////////
void VisibilityEnabler3D::_screen_enter() {
-
for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
-
_change_node_state(E->key(), true);
}
@@ -136,9 +124,7 @@ void VisibilityEnabler3D::_screen_enter() {
}
void VisibilityEnabler3D::_screen_exit() {
-
for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
-
_change_node_state(E->key(), false);
}
@@ -146,14 +132,12 @@ void VisibilityEnabler3D::_screen_exit() {
}
void VisibilityEnabler3D::_find_nodes(Node *p_node) {
-
bool add = false;
Variant meta;
{
RigidBody3D *rb = Object::cast_to<RigidBody3D>(p_node);
if (rb && ((rb->get_mode() == RigidBody3D::MODE_CHARACTER || rb->get_mode() == RigidBody3D::MODE_RIGID))) {
-
add = true;
meta = rb->get_mode();
}
@@ -167,7 +151,6 @@ void VisibilityEnabler3D::_find_nodes(Node *p_node) {
}
if (add) {
-
p_node->connect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler3D::_node_removed), varray(p_node), CONNECT_ONESHOT);
nodes[p_node] = meta;
_change_node_state(p_node, false);
@@ -175,37 +158,38 @@ void VisibilityEnabler3D::_find_nodes(Node *p_node) {
for (int i = 0; i < p_node->get_child_count(); i++) {
Node *c = p_node->get_child(i);
- if (c->get_filename() != String())
+ if (c->get_filename() != String()) {
continue; //skip, instance
+ }
_find_nodes(c);
}
}
void VisibilityEnabler3D::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
- if (Engine::get_singleton()->is_editor_hint())
+ if (Engine::get_singleton()->is_editor_hint()) {
return;
+ }
Node *from = this;
//find where current scene starts
- while (from->get_parent() && from->get_filename() == String())
+ while (from->get_parent() && from->get_filename() == String()) {
from = from->get_parent();
+ }
_find_nodes(from);
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
- if (Engine::get_singleton()->is_editor_hint())
+ if (Engine::get_singleton()->is_editor_hint()) {
return;
+ }
for (Map<Node *, Variant>::Element *E = nodes.front(); E; E = E->next()) {
-
- if (!visible)
+ if (!visible) {
_change_node_state(E->key(), true);
+ }
E->key()->disconnect(SceneStringNames::get_singleton()->tree_exiting, callable_mp(this, &VisibilityEnabler3D::_node_removed));
}
@@ -214,35 +198,32 @@ void VisibilityEnabler3D::_notification(int p_what) {
}
void VisibilityEnabler3D::_change_node_state(Node *p_node, bool p_enabled) {
-
ERR_FAIL_COND(!nodes.has(p_node));
if (enabler[ENABLER_FREEZE_BODIES]) {
RigidBody3D *rb = Object::cast_to<RigidBody3D>(p_node);
- if (rb)
-
+ if (rb) {
rb->set_sleeping(!p_enabled);
+ }
}
if (enabler[ENABLER_PAUSE_ANIMATIONS]) {
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
if (ap) {
-
ap->set_active(p_enabled);
}
}
}
void VisibilityEnabler3D::_node_removed(Node *p_node) {
-
- if (!visible)
+ if (!visible) {
_change_node_state(p_node, true);
+ }
nodes.erase(p_node);
}
void VisibilityEnabler3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_enabler", "enabler", "enabled"), &VisibilityEnabler3D::set_enabler);
ClassDB::bind_method(D_METHOD("is_enabler_enabled", "enabler"), &VisibilityEnabler3D::is_enabler_enabled);
@@ -255,20 +236,19 @@ void VisibilityEnabler3D::_bind_methods() {
}
void VisibilityEnabler3D::set_enabler(Enabler p_enabler, bool p_enable) {
-
ERR_FAIL_INDEX(p_enabler, ENABLER_MAX);
enabler[p_enabler] = p_enable;
}
-bool VisibilityEnabler3D::is_enabler_enabled(Enabler p_enabler) const {
+bool VisibilityEnabler3D::is_enabler_enabled(Enabler p_enabler) const {
ERR_FAIL_INDEX_V(p_enabler, ENABLER_MAX, false);
return enabler[p_enabler];
}
VisibilityEnabler3D::VisibilityEnabler3D() {
-
- for (int i = 0; i < ENABLER_MAX; i++)
+ for (int i = 0; i < ENABLER_MAX; i++) {
enabler[i] = true;
+ }
visible = false;
}
diff --git a/scene/3d/visibility_notifier_3d.h b/scene/3d/visibility_notifier_3d.h
index 19204a6a4e..3864b398f4 100644
--- a/scene/3d/visibility_notifier_3d.h
+++ b/scene/3d/visibility_notifier_3d.h
@@ -35,7 +35,6 @@
class Camera3D;
class VisibilityNotifier3D : public Node3D {
-
GDCLASS(VisibilityNotifier3D, Node3D);
Set<Camera3D *> cameras;
@@ -62,7 +61,6 @@ public:
};
class VisibilityEnabler3D : public VisibilityNotifier3D {
-
GDCLASS(VisibilityEnabler3D, VisibilityNotifier3D);
public:
diff --git a/scene/3d/visual_instance_3d.cpp b/scene/3d/visual_instance_3d.cpp
index 604bc53422..a1c498e8ab 100644
--- a/scene/3d/visual_instance_3d.cpp
+++ b/scene/3d/visual_instance_3d.cpp
@@ -35,73 +35,62 @@
#include "skeleton_3d.h"
AABB VisualInstance3D::get_transformed_aabb() const {
-
return get_global_transform().xform(get_aabb());
}
void VisualInstance3D::_update_visibility() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_change_notify("visible");
RS::get_singleton()->instance_set_visible(get_instance(), is_visible_in_tree());
}
void VisualInstance3D::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_WORLD: {
-
// CHECK SKELETON => moving skeleton attaching logic to MeshInstance
/*
Skeleton *skeleton=Object::cast_to<Skeleton>(get_parent());
if (skeleton)
RenderingServer::get_singleton()->instance_attach_skeleton( instance, skeleton->get_skeleton() );
*/
- ERR_FAIL_COND(get_world().is_null());
- RenderingServer::get_singleton()->instance_set_scenario(instance, get_world()->get_scenario());
+ ERR_FAIL_COND(get_world_3d().is_null());
+ RenderingServer::get_singleton()->instance_set_scenario(instance, get_world_3d()->get_scenario());
_update_visibility();
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
-
Transform gt = get_global_transform();
RenderingServer::get_singleton()->instance_set_transform(instance, gt);
} break;
case NOTIFICATION_EXIT_WORLD: {
-
RenderingServer::get_singleton()->instance_set_scenario(instance, RID());
RenderingServer::get_singleton()->instance_attach_skeleton(instance, RID());
//RS::get_singleton()->instance_geometry_set_baked_light_sampler(instance, RID() );
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
_update_visibility();
} break;
}
}
RID VisualInstance3D::get_instance() const {
-
return instance;
}
RID VisualInstance3D::_get_visual_instance_rid() const {
-
return instance;
}
void VisualInstance3D::set_layer_mask(uint32_t p_mask) {
-
layers = p_mask;
RenderingServer::get_singleton()->instance_set_layer_mask(instance, p_mask);
}
uint32_t VisualInstance3D::get_layer_mask() const {
-
return layers;
}
@@ -120,7 +109,6 @@ bool VisualInstance3D::get_layer_mask_bit(int p_layer) const {
}
void VisualInstance3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_get_visual_instance_rid"), &VisualInstance3D::_get_visual_instance_rid);
ClassDB::bind_method(D_METHOD("set_base", "base"), &VisualInstance3D::set_base);
ClassDB::bind_method(D_METHOD("get_base"), &VisualInstance3D::get_base);
@@ -136,18 +124,15 @@ void VisualInstance3D::_bind_methods() {
}
void VisualInstance3D::set_base(const RID &p_base) {
-
RenderingServer::get_singleton()->instance_set_base(instance, p_base);
base = p_base;
}
RID VisualInstance3D::get_base() const {
-
return base;
}
VisualInstance3D::VisualInstance3D() {
-
instance = RenderingServer::get_singleton()->instance_create();
RenderingServer::get_singleton()->instance_attach_object_instance_id(instance, get_instance_id());
layers = 1;
@@ -155,62 +140,51 @@ VisualInstance3D::VisualInstance3D() {
}
VisualInstance3D::~VisualInstance3D() {
-
RenderingServer::get_singleton()->free(instance);
}
void GeometryInstance3D::set_material_override(const Ref<Material> &p_material) {
-
material_override = p_material;
RS::get_singleton()->instance_geometry_set_material_override(get_instance(), p_material.is_valid() ? p_material->get_rid() : RID());
}
Ref<Material> GeometryInstance3D::get_material_override() const {
-
return material_override;
}
void GeometryInstance3D::set_lod_min_distance(float p_dist) {
-
lod_min_distance = p_dist;
RS::get_singleton()->instance_geometry_set_draw_range(get_instance(), lod_min_distance, lod_max_distance, lod_min_hysteresis, lod_max_hysteresis);
}
float GeometryInstance3D::get_lod_min_distance() const {
-
return lod_min_distance;
}
void GeometryInstance3D::set_lod_max_distance(float p_dist) {
-
lod_max_distance = p_dist;
RS::get_singleton()->instance_geometry_set_draw_range(get_instance(), lod_min_distance, lod_max_distance, lod_min_hysteresis, lod_max_hysteresis);
}
float GeometryInstance3D::get_lod_max_distance() const {
-
return lod_max_distance;
}
void GeometryInstance3D::set_lod_min_hysteresis(float p_dist) {
-
lod_min_hysteresis = p_dist;
RS::get_singleton()->instance_geometry_set_draw_range(get_instance(), lod_min_distance, lod_max_distance, lod_min_hysteresis, lod_max_hysteresis);
}
float GeometryInstance3D::get_lod_min_hysteresis() const {
-
return lod_min_hysteresis;
}
void GeometryInstance3D::set_lod_max_hysteresis(float p_dist) {
-
lod_max_hysteresis = p_dist;
RS::get_singleton()->instance_geometry_set_draw_range(get_instance(), lod_min_distance, lod_max_distance, lod_min_hysteresis, lod_max_hysteresis);
}
float GeometryInstance3D::get_lod_max_hysteresis() const {
-
return lod_max_hysteresis;
}
@@ -239,7 +213,17 @@ bool GeometryInstance3D::_set(const StringName &p_name, const Variant &p_value)
set_shader_instance_uniform(*r, p_value);
return true;
}
+#ifndef DISABLE_DEPRECATED
+ if (p_name == SceneStringNames::get_singleton()->use_in_baked_light && bool(p_value)) {
+ set_gi_mode(GI_MODE_BAKED);
+ return true;
+ }
+ if (p_name == SceneStringNames::get_singleton()->use_dynamic_gi && bool(p_value)) {
+ set_gi_mode(GI_MODE_DYNAMIC);
+ return true;
+ }
+#endif
return false;
}
@@ -252,6 +236,7 @@ bool GeometryInstance3D::_get(const StringName &p_name, Variant &r_ret) const {
return false;
}
+
void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const {
List<PropertyInfo> pinfo;
RS::get_singleton()->instance_geometry_get_shader_parameter_list(get_instance(), &pinfo);
@@ -273,49 +258,27 @@ void GeometryInstance3D::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
-void GeometryInstance3D::set_flag(Flags p_flag, bool p_value) {
-
- ERR_FAIL_INDEX(p_flag, FLAG_MAX);
- if (flags[p_flag] == p_value)
- return;
-
- flags[p_flag] = p_value;
- RS::get_singleton()->instance_geometry_set_flag(get_instance(), (RS::InstanceFlags)p_flag, p_value);
-}
-
-bool GeometryInstance3D::get_flag(Flags p_flag) const {
-
- ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
-
- return flags[p_flag];
-}
-
void GeometryInstance3D::set_cast_shadows_setting(ShadowCastingSetting p_shadow_casting_setting) {
-
shadow_casting_setting = p_shadow_casting_setting;
RS::get_singleton()->instance_geometry_set_cast_shadows_setting(get_instance(), (RS::ShadowCastingSetting)p_shadow_casting_setting);
}
GeometryInstance3D::ShadowCastingSetting GeometryInstance3D::get_cast_shadows_setting() const {
-
return shadow_casting_setting;
}
void GeometryInstance3D::set_extra_cull_margin(float p_margin) {
-
ERR_FAIL_COND(p_margin < 0);
extra_cull_margin = p_margin;
RS::get_singleton()->instance_set_extra_visibility_margin(get_instance(), extra_cull_margin);
}
float GeometryInstance3D::get_extra_cull_margin() const {
-
return extra_cull_margin;
}
void GeometryInstance3D::set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value) {
-
if (p_value.get_type() == Variant::NIL) {
Variant def_value = RS::get_singleton()->instance_geometry_get_shader_parameter_default_value(get_instance(), p_uniform);
RS::get_singleton()->instance_geometry_set_shader_parameter(get_instance(), p_uniform, def_value);
@@ -327,22 +290,50 @@ void GeometryInstance3D::set_shader_instance_uniform(const StringName &p_uniform
}
Variant GeometryInstance3D::get_shader_instance_uniform(const StringName &p_uniform) const {
-
return RS::get_singleton()->instance_geometry_get_shader_parameter(get_instance(), p_uniform);
}
-void GeometryInstance3D::set_custom_aabb(AABB aabb) {
+void GeometryInstance3D::set_custom_aabb(AABB aabb) {
RS::get_singleton()->instance_set_custom_aabb(get_instance(), aabb);
}
-void GeometryInstance3D::_bind_methods() {
+void GeometryInstance3D::set_lightmap_scale(LightmapScale p_scale) {
+ ERR_FAIL_INDEX(p_scale, LIGHTMAP_SCALE_MAX);
+ lightmap_scale = p_scale;
+}
+GeometryInstance3D::LightmapScale GeometryInstance3D::get_lightmap_scale() const {
+ return lightmap_scale;
+}
+
+void GeometryInstance3D::set_gi_mode(GIMode p_mode) {
+ switch (p_mode) {
+ case GI_MODE_DISABLED: {
+ RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
+ RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_DYNAMIC_GI, false);
+ } break;
+ case GI_MODE_BAKED: {
+ RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_BAKED_LIGHT, true);
+ RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_DYNAMIC_GI, false);
+
+ } break;
+ case GI_MODE_DYNAMIC: {
+ RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_BAKED_LIGHT, false);
+ RS::get_singleton()->instance_geometry_set_flag(get_instance(), RS::INSTANCE_FLAG_USE_DYNAMIC_GI, true);
+ } break;
+ }
+
+ gi_mode = p_mode;
+}
+
+GeometryInstance3D::GIMode GeometryInstance3D::get_gi_mode() const {
+ return gi_mode;
+}
+
+void GeometryInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_material_override", "material"), &GeometryInstance3D::set_material_override);
ClassDB::bind_method(D_METHOD("get_material_override"), &GeometryInstance3D::get_material_override);
- ClassDB::bind_method(D_METHOD("set_flag", "flag", "value"), &GeometryInstance3D::set_flag);
- ClassDB::bind_method(D_METHOD("get_flag", "flag"), &GeometryInstance3D::get_flag);
-
ClassDB::bind_method(D_METHOD("set_cast_shadows_setting", "shadow_casting_setting"), &GeometryInstance3D::set_cast_shadows_setting);
ClassDB::bind_method(D_METHOD("get_cast_shadows_setting"), &GeometryInstance3D::get_cast_shadows_setting);
@@ -364,6 +355,12 @@ void GeometryInstance3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_extra_cull_margin", "margin"), &GeometryInstance3D::set_extra_cull_margin);
ClassDB::bind_method(D_METHOD("get_extra_cull_margin"), &GeometryInstance3D::get_extra_cull_margin);
+ ClassDB::bind_method(D_METHOD("set_lightmap_scale", "scale"), &GeometryInstance3D::set_lightmap_scale);
+ ClassDB::bind_method(D_METHOD("get_lightmap_scale"), &GeometryInstance3D::get_lightmap_scale);
+
+ ClassDB::bind_method(D_METHOD("set_gi_mode", "mode"), &GeometryInstance3D::set_gi_mode);
+ ClassDB::bind_method(D_METHOD("get_gi_mode"), &GeometryInstance3D::get_gi_mode);
+
ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &GeometryInstance3D::set_custom_aabb);
ClassDB::bind_method(D_METHOD("get_aabb"), &GeometryInstance3D::get_aabb);
@@ -372,8 +369,9 @@ void GeometryInstance3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material_override", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,StandardMaterial3D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE), "set_material_override", "get_material_override");
ADD_PROPERTY(PropertyInfo(Variant::INT, "cast_shadow", PROPERTY_HINT_ENUM, "Off,On,Double-Sided,Shadows Only"), "set_cast_shadows_setting", "get_cast_shadows_setting");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "extra_cull_margin", PROPERTY_HINT_RANGE, "0,16384,0.01"), "set_extra_cull_margin", "get_extra_cull_margin");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_in_baked_light"), "set_flag", "get_flag", FLAG_USE_BAKED_LIGHT);
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "use_dynamic_gi"), "set_flag", "get_flag", FLAG_USE_DYNAMIC_GI);
+ ADD_GROUP("Global Illumination", "gi_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_mode", PROPERTY_HINT_ENUM, "Disabled,Baked,Dynamic"), "set_gi_mode", "get_gi_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "gi_lightmap_scale", PROPERTY_HINT_ENUM, "1x,2x,4x,8x"), "set_lightmap_scale", "get_lightmap_scale");
ADD_GROUP("LOD", "lod_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "lod_min_distance", PROPERTY_HINT_RANGE, "0,32768,0.01"), "set_lod_min_distance", "get_lod_min_distance");
@@ -388,10 +386,15 @@ void GeometryInstance3D::_bind_methods() {
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_DOUBLE_SIDED);
BIND_ENUM_CONSTANT(SHADOW_CASTING_SETTING_SHADOWS_ONLY);
- BIND_ENUM_CONSTANT(FLAG_USE_BAKED_LIGHT);
- BIND_ENUM_CONSTANT(FLAG_USE_DYNAMIC_GI);
- BIND_ENUM_CONSTANT(FLAG_DRAW_NEXT_FRAME_IF_VISIBLE);
- BIND_ENUM_CONSTANT(FLAG_MAX);
+ BIND_ENUM_CONSTANT(GI_MODE_DISABLED);
+ BIND_ENUM_CONSTANT(GI_MODE_BAKED);
+ BIND_ENUM_CONSTANT(GI_MODE_DYNAMIC);
+
+ BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_1X);
+ BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_2X);
+ BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_4X);
+ BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_8X);
+ BIND_ENUM_CONSTANT(LIGHTMAP_SCALE_MAX);
}
GeometryInstance3D::GeometryInstance3D() {
@@ -400,9 +403,8 @@ GeometryInstance3D::GeometryInstance3D() {
lod_min_hysteresis = 0;
lod_max_hysteresis = 0;
- for (int i = 0; i < FLAG_MAX; i++) {
- flags[i] = false;
- }
+ gi_mode = GI_MODE_DISABLED;
+ lightmap_scale = LIGHTMAP_SCALE_1X;
shadow_casting_setting = SHADOW_CASTING_SETTING_ON;
extra_cull_margin = 0;
diff --git a/scene/3d/visual_instance_3d.h b/scene/3d/visual_instance_3d.h
index cc5f92066f..195674f62d 100644
--- a/scene/3d/visual_instance_3d.h
+++ b/scene/3d/visual_instance_3d.h
@@ -37,7 +37,6 @@
#include "scene/resources/material.h"
class VisualInstance3D : public Node3D {
-
GDCLASS(VisualInstance3D, Node3D);
OBJ_CATEGORY("3D Visual Nodes");
@@ -81,17 +80,9 @@ public:
};
class GeometryInstance3D : public VisualInstance3D {
-
GDCLASS(GeometryInstance3D, VisualInstance3D);
public:
- enum Flags {
- FLAG_USE_BAKED_LIGHT = RS::INSTANCE_FLAG_USE_BAKED_LIGHT,
- FLAG_USE_DYNAMIC_GI = RS::INSTANCE_FLAG_USE_DYNAMIC_GI,
- FLAG_DRAW_NEXT_FRAME_IF_VISIBLE = RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE,
- FLAG_MAX = RS::INSTANCE_FLAG_MAX,
- };
-
enum ShadowCastingSetting {
SHADOW_CASTING_SETTING_OFF = RS::SHADOW_CASTING_SETTING_OFF,
SHADOW_CASTING_SETTING_ON = RS::SHADOW_CASTING_SETTING_ON,
@@ -99,8 +90,21 @@ public:
SHADOW_CASTING_SETTING_SHADOWS_ONLY = RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY
};
+ enum GIMode {
+ GI_MODE_DISABLED,
+ GI_MODE_BAKED,
+ GI_MODE_DYNAMIC
+ };
+
+ enum LightmapScale {
+ LIGHTMAP_SCALE_1X,
+ LIGHTMAP_SCALE_2X,
+ LIGHTMAP_SCALE_4X,
+ LIGHTMAP_SCALE_8X,
+ LIGHTMAP_SCALE_MAX,
+ };
+
private:
- bool flags[FLAG_MAX];
ShadowCastingSetting shadow_casting_setting;
Ref<Material> material_override;
float lod_min_distance;
@@ -112,6 +116,8 @@ private:
mutable HashMap<StringName, StringName> instance_uniform_property_remap;
float extra_cull_margin;
+ LightmapScale lightmap_scale;
+ GIMode gi_mode;
const StringName *_instance_uniform_get_remap(const StringName p_name) const;
@@ -124,9 +130,6 @@ protected:
static void _bind_methods();
public:
- void set_flag(Flags p_flag, bool p_value);
- bool get_flag(Flags p_flag) const;
-
void set_cast_shadows_setting(ShadowCastingSetting p_shadow_casting_setting);
ShadowCastingSetting get_cast_shadows_setting() const;
@@ -148,6 +151,12 @@ public:
void set_extra_cull_margin(float p_margin);
float get_extra_cull_margin() const;
+ void set_gi_mode(GIMode p_mode);
+ GIMode get_gi_mode() const;
+
+ void set_lightmap_scale(LightmapScale p_scale);
+ LightmapScale get_lightmap_scale() const;
+
void set_shader_instance_uniform(const StringName &p_uniform, const Variant &p_value);
Variant get_shader_instance_uniform(const StringName &p_uniform) const;
@@ -156,7 +165,8 @@ public:
GeometryInstance3D();
};
-VARIANT_ENUM_CAST(GeometryInstance3D::Flags);
VARIANT_ENUM_CAST(GeometryInstance3D::ShadowCastingSetting);
+VARIANT_ENUM_CAST(GeometryInstance3D::LightmapScale);
+VARIANT_ENUM_CAST(GeometryInstance3D::GIMode);
#endif
diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp
index 203c3cd812..9fc3feb49a 100644
--- a/scene/3d/voxelizer.cpp
+++ b/scene/3d/voxelizer.cpp
@@ -29,194 +29,13 @@
/*************************************************************************/
#include "voxelizer.h"
+#include "core/math/geometry.h"
#include "core/os/os.h"
#include "core/os/threaded_array_processor.h"
#include <stdlib.h>
-#define FINDMINMAX(x0, x1, x2, min, max) \
- min = max = x0; \
- if (x1 < min) min = x1; \
- if (x1 > max) max = x1; \
- if (x2 < min) min = x2; \
- if (x2 > max) max = x2;
-
-static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) {
- int q;
- Vector3 vmin, vmax;
- for (q = 0; q <= 2; q++) {
- if (normal[q] > 0.0f) {
- vmin[q] = -maxbox[q];
- vmax[q] = maxbox[q];
- } else {
- vmin[q] = maxbox[q];
- vmax[q] = -maxbox[q];
- }
- }
- if (normal.dot(vmin) + d > 0.0f) return false;
- if (normal.dot(vmax) + d >= 0.0f) return true;
-
- return false;
-}
-
-/*======================== X-tests ========================*/
-#define AXISTEST_X01(a, b, fa, fb) \
- p0 = a * v0.y - b * v0.z; \
- p2 = a * v2.y - b * v2.z; \
- if (p0 < p2) { \
- min = p0; \
- max = p2; \
- } else { \
- min = p2; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-#define AXISTEST_X2(a, b, fa, fb) \
- p0 = a * v0.y - b * v0.z; \
- p1 = a * v1.y - b * v1.z; \
- if (p0 < p1) { \
- min = p0; \
- max = p1; \
- } else { \
- min = p1; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-/*======================== Y-tests ========================*/
-#define AXISTEST_Y02(a, b, fa, fb) \
- p0 = -a * v0.x + b * v0.z; \
- p2 = -a * v2.x + b * v2.z; \
- if (p0 < p2) { \
- min = p0; \
- max = p2; \
- } else { \
- min = p2; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-#define AXISTEST_Y1(a, b, fa, fb) \
- p0 = -a * v0.x + b * v0.z; \
- p1 = -a * v1.x + b * v1.z; \
- if (p0 < p1) { \
- min = p0; \
- max = p1; \
- } else { \
- min = p1; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-/*======================== Z-tests ========================*/
-
-#define AXISTEST_Z12(a, b, fa, fb) \
- p1 = a * v1.x - b * v1.y; \
- p2 = a * v2.x - b * v2.y; \
- if (p2 < p1) { \
- min = p2; \
- max = p1; \
- } else { \
- min = p1; \
- max = p2; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
- if (min > rad || max < -rad) return false;
-
-#define AXISTEST_Z0(a, b, fa, fb) \
- p0 = a * v0.x - b * v0.y; \
- p1 = a * v1.x - b * v1.y; \
- if (p0 < p1) { \
- min = p0; \
- max = p1; \
- } else { \
- min = p1; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
- if (min > rad || max < -rad) return false;
-
-static bool fast_tri_box_overlap(const Vector3 &boxcenter, const Vector3 boxhalfsize, const Vector3 *triverts) {
-
- /* use separating axis theorem to test overlap between triangle and box */
- /* need to test for overlap in these directions: */
- /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */
- /* we do not even need to test these) */
- /* 2) normal of the triangle */
- /* 3) crossproduct(edge from tri, {x,y,z}-directin) */
- /* this gives 3x3=9 more tests */
- Vector3 v0, v1, v2;
- float min, max, d, p0, p1, p2, rad, fex, fey, fez;
- Vector3 normal, e0, e1, e2;
-
- /* This is the fastest branch on Sun */
- /* move everything so that the boxcenter is in (0,0,0) */
-
- v0 = triverts[0] - boxcenter;
- v1 = triverts[1] - boxcenter;
- v2 = triverts[2] - boxcenter;
-
- /* compute triangle edges */
- e0 = v1 - v0; /* tri edge 0 */
- e1 = v2 - v1; /* tri edge 1 */
- e2 = v0 - v2; /* tri edge 2 */
-
- /* Bullet 3: */
- /* test the 9 tests first (this was faster) */
- fex = Math::abs(e0.x);
- fey = Math::abs(e0.y);
- fez = Math::abs(e0.z);
- AXISTEST_X01(e0.z, e0.y, fez, fey);
- AXISTEST_Y02(e0.z, e0.x, fez, fex);
- AXISTEST_Z12(e0.y, e0.x, fey, fex);
-
- fex = Math::abs(e1.x);
- fey = Math::abs(e1.y);
- fez = Math::abs(e1.z);
- AXISTEST_X01(e1.z, e1.y, fez, fey);
- AXISTEST_Y02(e1.z, e1.x, fez, fex);
- AXISTEST_Z0(e1.y, e1.x, fey, fex);
-
- fex = Math::abs(e2.x);
- fey = Math::abs(e2.y);
- fez = Math::abs(e2.z);
- AXISTEST_X2(e2.z, e2.y, fez, fey);
- AXISTEST_Y1(e2.z, e2.x, fez, fex);
- AXISTEST_Z12(e2.y, e2.x, fey, fex);
-
- /* Bullet 1: */
- /* first test overlap in the {x,y,z}-directions */
- /* find min, max of the triangle each direction, and test for overlap in */
- /* that direction -- this is equivalent to testing a minimal AABB around */
- /* the triangle against the AABB */
-
- /* test in X-direction */
- FINDMINMAX(v0.x, v1.x, v2.x, min, max);
- if (min > boxhalfsize.x || max < -boxhalfsize.x) return false;
-
- /* test in Y-direction */
- FINDMINMAX(v0.y, v1.y, v2.y, min, max);
- if (min > boxhalfsize.y || max < -boxhalfsize.y) return false;
-
- /* test in Z-direction */
- FINDMINMAX(v0.z, v1.z, v2.z, min, max);
- if (min > boxhalfsize.z || max < -boxhalfsize.z) return false;
-
- /* Bullet 2: */
- /* test if the box intersects the plane of the triangle */
- /* compute plane equation of triangle: normal*x+d=0 */
- normal = e0.cross(e1);
- d = -normal.dot(v0); /* plane eq: normal.x+d=0 */
- return planeBoxOverlap(normal, d, boxhalfsize); /* if true, box and triangle overlaps */
-}
-
static _FORCE_INLINE_ void get_uv_and_normal(const Vector3 &p_pos, const Vector3 *p_vtx, const Vector2 *p_uv, const Vector3 *p_normal, Vector2 &r_uv, Vector3 &r_normal) {
-
if (p_pos.distance_squared_to(p_vtx[0]) < CMP_EPSILON2) {
r_uv = p_uv[0];
r_normal = p_normal[0];
@@ -257,7 +76,6 @@ static _FORCE_INLINE_ void get_uv_and_normal(const Vector3 &p_pos, const Vector3
}
void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector3 *p_normal, const Vector2 *p_uv, const MaterialCache &p_material, const AABB &p_aabb) {
-
if (p_level == cell_subdiv) {
//plot the face by guessing its albedo and emission value
@@ -269,7 +87,6 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
Vector3 normal = plane.normal;
for (int i = 0; i < 3; i++) {
-
Vector3 axis;
axis[i] = 1.0;
float dot = ABS(normal.dot(axis));
@@ -297,11 +114,9 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
//map to a grid average in the best axis for this face
for (int i = 0; i < color_scan_cell_width; i++) {
-
Vector3 ofs_i = float(i) * t1;
for (int j = 0; j < color_scan_cell_width; j++) {
-
Vector3 ofs_j = float(j) * t2;
Vector3 from = p_aabb.position + ofs_i + ofs_j;
@@ -309,7 +124,7 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
Vector3 half = (to - from) * 0.5;
//is in this cell?
- if (!fast_tri_box_overlap(from + half, half, p_vtx)) {
+ if (!Geometry::triangle_box_overlap(from + half, half, p_vtx)) {
continue; //face does not span this cell
}
@@ -327,7 +142,6 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
if (ABS(plane.distance_to(ray_from)) < ABS(plane.distance_to(ray_to))) {
intersection = plane.project(ray_from);
} else {
-
intersection = plane.project(ray_to);
}
}
@@ -337,8 +151,9 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
Vector2 uv;
Vector3 lnormal;
get_uv_and_normal(intersection, p_vtx, p_uv, p_normal, uv, lnormal);
- if (lnormal == Vector3()) //just in case normal as nor provided
+ if (lnormal == Vector3()) { //just in case normal as nor provided
lnormal = normal;
+ }
int uv_x = CLAMP(int(Math::fposmod(uv.x, 1.0f) * bake_texture_size), 0, bake_texture_size - 1);
int uv_y = CLAMP(int(Math::fposmod(uv.y, 1.0f) * bake_texture_size), 0, bake_texture_size - 1);
@@ -368,8 +183,9 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
Vector3 lnormal;
Vector2 uv;
get_uv_and_normal(inters, p_vtx, p_uv, p_normal, uv, normal);
- if (lnormal == Vector3()) //just in case normal as nor provided
+ if (lnormal == Vector3()) { //just in case normal as nor provided
lnormal = normal;
+ }
int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
@@ -390,7 +206,6 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
normal_accum = lnormal * alpha;
} else {
-
float accdiv = 1.0 / (color_scan_cell_width * color_scan_cell_width);
alpha *= accdiv;
@@ -423,7 +238,6 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
int half = (1 << cell_subdiv) >> (p_level + 1);
for (int i = 0; i < 8; i++) {
-
AABB aabb = p_aabb;
aabb.size *= 0.5;
@@ -444,15 +258,16 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
nz += half;
}
//make sure to not plot beyond limits
- if (nx < 0 || nx >= axis_cell_size[0] || ny < 0 || ny >= axis_cell_size[1] || nz < 0 || nz >= axis_cell_size[2])
+ if (nx < 0 || nx >= axis_cell_size[0] || ny < 0 || ny >= axis_cell_size[1] || nz < 0 || nz >= axis_cell_size[2]) {
continue;
+ }
{
AABB test_aabb = aabb;
//test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time
Vector3 qsize = test_aabb.size * 0.5; //quarter size, for fast aabb test
- if (!fast_tri_box_overlap(test_aabb.position + qsize, qsize, p_vtx)) {
+ if (!Geometry::triangle_box_overlap(test_aabb.position + qsize, qsize, p_vtx)) {
//if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) {
//does not fit in child, go on
continue;
@@ -477,11 +292,9 @@ void Voxelizer::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, co
}
Vector<Color> Voxelizer::_get_bake_texture(Ref<Image> p_image, const Color &p_color_mul, const Color &p_color_add) {
-
Vector<Color> ret;
if (p_image.is_null() || p_image->empty()) {
-
ret.resize(bake_texture_size * bake_texture_size);
for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
ret.write[i] = p_color_add;
@@ -515,7 +328,6 @@ Vector<Color> Voxelizer::_get_bake_texture(Ref<Image> p_image, const Color &p_co
}
Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material) {
-
//this way of obtaining materials is inaccurate and also does not support some compressed formats very well
Ref<StandardMaterial3D> mat = p_material;
@@ -528,12 +340,10 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material
MaterialCache mc;
if (mat.is_valid()) {
-
Ref<Texture2D> albedo_tex = mat->get_texture(StandardMaterial3D::TEXTURE_ALBEDO);
Ref<Image> img_albedo;
if (albedo_tex.is_valid()) {
-
img_albedo = albedo_tex->get_data();
mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo(), Color(0, 0, 0)); // albedo texture, color is multiplicative
} else {
@@ -548,7 +358,6 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material
Ref<Image> img_emission;
if (emission_tex.is_valid()) {
-
img_emission = emission_tex->get_data();
}
@@ -570,11 +379,10 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material
}
void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vector<Ref<Material>> &p_materials, const Ref<Material> &p_override_material) {
-
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
-
- if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
+ if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
continue; //only triangles
+ }
Ref<Material> src_material;
@@ -592,32 +400,24 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec
Vector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
const Vector3 *vr = vertices.ptr();
Vector<Vector2> uv = a[Mesh::ARRAY_TEX_UV];
- const Vector2 *uvr;
+ const Vector2 *uvr = nullptr;
Vector<Vector3> normals = a[Mesh::ARRAY_NORMAL];
- const Vector3 *nr;
+ const Vector3 *nr = nullptr;
Vector<int> index = a[Mesh::ARRAY_INDEX];
- bool read_uv = false;
- bool read_normals = false;
-
if (uv.size()) {
-
uvr = uv.ptr();
- read_uv = true;
}
if (normals.size()) {
- read_normals = true;
nr = normals.ptr();
}
if (index.size()) {
-
int facecount = index.size() / 3;
const int *ir = index.ptr();
for (int j = 0; j < facecount; j++) {
-
Vector3 vtxs[3];
Vector2 uvs[3];
Vector3 normal[3];
@@ -626,31 +426,30 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec
vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]);
}
- if (read_uv) {
+ if (uvr) {
for (int k = 0; k < 3; k++) {
uvs[k] = uvr[ir[j * 3 + k]];
}
}
- if (read_normals) {
+ if (nr) {
for (int k = 0; k < 3; k++) {
normal[k] = nr[ir[j * 3 + k]];
}
}
//test against original bounds
- if (!fast_tri_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs))
+ if (!Geometry::triangle_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) {
continue;
+ }
//plot
_plot_face(0, 0, 0, 0, 0, vtxs, normal, uvs, material, po2_bounds);
}
} else {
-
int facecount = vertices.size() / 3;
for (int j = 0; j < facecount; j++) {
-
Vector3 vtxs[3];
Vector2 uvs[3];
Vector3 normal[3];
@@ -659,21 +458,22 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec
vtxs[k] = p_xform.xform(vr[j * 3 + k]);
}
- if (read_uv) {
+ if (uvr) {
for (int k = 0; k < 3; k++) {
uvs[k] = uvr[j * 3 + k];
}
}
- if (read_normals) {
+ if (nr) {
for (int k = 0; k < 3; k++) {
normal[k] = nr[j * 3 + k];
}
}
//test against original bounds
- if (!fast_tri_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs))
+ if (!Geometry::triangle_box_overlap(original_bounds.position + original_bounds.size * 0.5, original_bounds.size * 0.5, vtxs)) {
continue;
+ }
//plot face
_plot_face(0, 0, 0, 0, 0, vtxs, normal, uvs, material, po2_bounds);
}
@@ -684,7 +484,6 @@ void Voxelizer::plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, const Vec
}
void Voxelizer::_sort() {
-
// cells need to be sorted by level and coordinates
// it is important that level has more priority (for compute), and that Z has the least,
// given it may aid older implementations plot using GPU
@@ -693,7 +492,6 @@ void Voxelizer::_sort() {
uint32_t cell_count = bake_cells.size();
sorted_cells.resize(cell_count);
{
-
CellSort *sort_cellsp = sorted_cells.ptrw();
const Cell *bake_cellsp = bake_cells.ptr();
@@ -726,7 +524,6 @@ void Voxelizer::_sort() {
}
{
-
const CellSort *sort_cellsp = sorted_cells.ptr();
const Cell *bake_cellsp = bake_cells.ptr();
const uint32_t *reverse_mapp = reverse_map.ptr();
@@ -749,9 +546,7 @@ void Voxelizer::_sort() {
}
void Voxelizer::_fixup_plot(int p_idx, int p_level) {
-
if (p_level == cell_subdiv) {
-
leaf_voxel_count++;
float alpha = bake_cells[p_idx].alpha;
@@ -790,7 +585,6 @@ void Voxelizer::_fixup_plot(int p_idx, int p_level) {
}*/
} else {
-
//go down
bake_cells.write[p_idx].emission[0] = 0;
@@ -807,11 +601,11 @@ void Voxelizer::_fixup_plot(int p_idx, int p_level) {
int children_found = 0;
for (int i = 0; i < 8; i++) {
-
uint32_t child = bake_cells[p_idx].children[i];
- if (child == CHILD_EMPTY)
+ if (child == CHILD_EMPTY) {
continue;
+ }
_fixup_plot(child, p_level + 1);
alpha_average += bake_cells[child].alpha;
@@ -824,7 +618,6 @@ void Voxelizer::_fixup_plot(int p_idx, int p_level) {
}
void Voxelizer::begin_bake(int p_subdiv, const AABB &p_bounds) {
-
sorted = false;
original_bounds = p_bounds;
cell_subdiv = p_subdiv;
@@ -839,9 +632,9 @@ void Voxelizer::begin_bake(int p_subdiv, const AABB &p_bounds) {
leaf_voxel_count = 0;
for (int i = 0; i < 3; i++) {
-
- if (i == longest_axis)
+ if (i == longest_axis) {
continue;
+ }
axis_cell_size[i] = axis_cell_size[longest_axis];
float axis_size = po2_bounds.size[longest_axis];
@@ -879,9 +672,11 @@ void Voxelizer::end_bake() {
int Voxelizer::get_gi_probe_octree_depth() const {
return cell_subdiv;
}
+
Vector3i Voxelizer::get_giprobe_octree_size() const {
return Vector3i(axis_cell_size[0], axis_cell_size[1], axis_cell_size[2]);
}
+
int Voxelizer::get_giprobe_cell_count() const {
return bake_cells.size();
}
@@ -897,7 +692,6 @@ Vector<uint8_t> Voxelizer::get_giprobe_octree_cells() const {
uint32_t cell_count = bake_cells.size();
for (uint32_t i = 0; i < cell_count; i++) {
-
for (uint32_t j = 0; j < 8; j++) {
children_cells[i * 8 + j] = cells[i].children[j];
}
@@ -906,6 +700,7 @@ Vector<uint8_t> Voxelizer::get_giprobe_octree_cells() const {
return data;
}
+
Vector<uint8_t> Voxelizer::get_giprobe_data_cells() const {
Vector<uint8_t> data;
data.resize((4 * 4) * bake_cells.size()); //8 uint32t values
@@ -917,7 +712,6 @@ Vector<uint8_t> Voxelizer::get_giprobe_data_cells() const {
uint32_t cell_count = bake_cells.size();
for (uint32_t i = 0; i < cell_count; i++) {
-
{ //position
uint32_t x = cells[i].x;
@@ -989,7 +783,6 @@ Vector<int> Voxelizer::get_giprobe_level_cell_count() const {
/* dt of 1d function using squared distance */
static void edt(float *f, int stride, int n) {
-
float *d = (float *)alloca(sizeof(float) * n + sizeof(int) * n + sizeof(float) * (n + 1));
int *v = (int *)&(d[n]);
float *z = (float *)&v[n];
@@ -1013,8 +806,9 @@ static void edt(float *f, int stride, int n) {
k = 0;
for (int q = 0; q <= n - 1; q++) {
- while (z[k + 1] < q)
+ while (z[k + 1] < q) {
k++;
+ }
d[q] = square(q - v[k]) + f[v[k] * stride];
}
@@ -1026,7 +820,6 @@ static void edt(float *f, int stride, int n) {
#undef square
Vector<uint8_t> Voxelizer::get_sdf_3d_image() const {
-
Vector3i octree_size = get_giprobe_octree_size();
uint32_t float_count = octree_size.x * octree_size.y * octree_size.z;
@@ -1044,7 +837,6 @@ Vector<uint8_t> Voxelizer::get_sdf_3d_image() const {
uint32_t cell_count = bake_cells.size();
for (uint32_t i = 0; i < cell_count; i++) {
-
if (cells[i].level < (cell_subdiv - 1)) {
continue; //do not care about this level
}
@@ -1098,9 +890,7 @@ Vector<uint8_t> Voxelizer::get_sdf_3d_image() const {
#undef INF
void Voxelizer::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<MultiMesh> &p_multimesh, int &idx) {
-
if (p_level == cell_subdiv - 1) {
-
Vector3 center = p_aabb.position + p_aabb.size * 0.5;
Transform xform;
xform.origin = center;
@@ -1114,23 +904,25 @@ void Voxelizer::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<Mult
idx++;
} else {
-
for (int i = 0; i < 8; i++) {
-
uint32_t child = bake_cells[p_idx].children[i];
- if (child == CHILD_EMPTY || child >= (uint32_t)max_original_cells)
+ if (child == CHILD_EMPTY || child >= (uint32_t)max_original_cells) {
continue;
+ }
AABB aabb = p_aabb;
aabb.size *= 0.5;
- if (i & 1)
+ if (i & 1) {
aabb.position.x += aabb.size.x;
- if (i & 2)
+ }
+ if (i & 2) {
aabb.position.y += aabb.size.y;
- if (i & 4)
+ }
+ if (i & 4) {
aabb.position.z += aabb.size.z;
+ }
_debug_mesh(bake_cells[p_idx].children[i], p_level + 1, aabb, p_multimesh, idx);
}
@@ -1138,7 +930,6 @@ void Voxelizer::_debug_mesh(int p_idx, int p_level, const AABB &p_aabb, Ref<Mult
}
Ref<MultiMesh> Voxelizer::create_debug_multimesh() {
-
Ref<MultiMesh> mm;
mm.instance();
@@ -1161,22 +952,20 @@ Ref<MultiMesh> Voxelizer::create_debug_multimesh() {
colors.push_back(Color(1, 1, 1, 1));
for (int i = 0; i < 6; i++) {
-
Vector3 face_points[4];
for (int j = 0; j < 4; j++) {
-
float v[3];
v[0] = 1.0;
v[1] = 1 - 2 * ((j >> 1) & 1);
v[2] = v[1] * (1 - 2 * (j & 1));
for (int k = 0; k < 3; k++) {
-
- if (i < 3)
+ if (i < 3) {
face_points[j][(i + k) % 3] = v[k];
- else
+ } else {
face_points[3 - j][(i + k) % 3] = -v[k];
+ }
}
}
@@ -1217,6 +1006,7 @@ Ref<MultiMesh> Voxelizer::create_debug_multimesh() {
Transform Voxelizer::get_to_cell_space_xform() const {
return to_cell_space;
}
+
Voxelizer::Voxelizer() {
sorted = false;
color_scan_cell_width = 4;
diff --git a/scene/3d/voxelizer.h b/scene/3d/voxelizer.h
index 1fde6237a2..3546fd7729 100644
--- a/scene/3d/voxelizer.h
+++ b/scene/3d/voxelizer.h
@@ -43,7 +43,6 @@ private:
};
struct Cell {
-
uint32_t children[8];
float albedo[3]; //albedo in RGB24
float emission[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp
index 8cf4554653..24071f31f3 100644
--- a/scene/3d/world_environment.cpp
+++ b/scene/3d/world_environment.cpp
@@ -32,100 +32,93 @@
#include "scene/main/window.h"
void WorldEnvironment::_notification(int p_what) {
-
if (p_what == Node3D::NOTIFICATION_ENTER_WORLD || p_what == Node3D::NOTIFICATION_ENTER_TREE) {
-
if (environment.is_valid()) {
- if (get_viewport()->find_world()->get_environment().is_valid()) {
+ if (get_viewport()->find_world_3d()->get_environment().is_valid()) {
WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
}
- get_viewport()->find_world()->set_environment(environment);
- add_to_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ get_viewport()->find_world_3d()->set_environment(environment);
+ add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
if (camera_effects.is_valid()) {
- if (get_viewport()->find_world()->get_camera_effects().is_valid()) {
+ if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) {
WARN_PRINT("World already has a camera effects (Another WorldEnvironment?), overriding.");
}
- get_viewport()->find_world()->set_camera_effects(camera_effects);
- add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ get_viewport()->find_world_3d()->set_camera_effects(camera_effects);
+ add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
} else if (p_what == Node3D::NOTIFICATION_EXIT_WORLD || p_what == Node3D::NOTIFICATION_EXIT_TREE) {
-
- if (environment.is_valid() && get_viewport()->find_world()->get_environment() == environment) {
- get_viewport()->find_world()->set_environment(Ref<Environment>());
- remove_from_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ if (environment.is_valid() && get_viewport()->find_world_3d()->get_environment() == environment) {
+ get_viewport()->find_world_3d()->set_environment(Ref<Environment>());
+ remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
- if (camera_effects.is_valid() && get_viewport()->find_world()->get_camera_effects() == camera_effects) {
- get_viewport()->find_world()->set_camera_effects(Ref<CameraEffects>());
- remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ if (camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) {
+ get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>());
+ remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
}
}
void WorldEnvironment::set_environment(const Ref<Environment> &p_environment) {
-
- if (is_inside_tree() && environment.is_valid() && get_viewport()->find_world()->get_environment() == environment) {
- get_viewport()->find_world()->set_environment(Ref<Environment>());
- remove_from_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ if (is_inside_tree() && environment.is_valid() && get_viewport()->find_world_3d()->get_environment() == environment) {
+ get_viewport()->find_world_3d()->set_environment(Ref<Environment>());
+ remove_from_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
//clean up
}
environment = p_environment;
if (is_inside_tree() && environment.is_valid()) {
- if (get_viewport()->find_world()->get_environment().is_valid()) {
+ if (get_viewport()->find_world_3d()->get_environment().is_valid()) {
WARN_PRINT("World already has an environment (Another WorldEnvironment?), overriding.");
}
- get_viewport()->find_world()->set_environment(environment);
- add_to_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ get_viewport()->find_world_3d()->set_environment(environment);
+ add_to_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
update_configuration_warning();
}
Ref<Environment> WorldEnvironment::get_environment() const {
-
return environment;
}
void WorldEnvironment::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) {
-
- if (is_inside_tree() && camera_effects.is_valid() && get_viewport()->find_world()->get_camera_effects() == camera_effects) {
- get_viewport()->find_world()->set_camera_effects(Ref<CameraEffects>());
- remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ if (is_inside_tree() && camera_effects.is_valid() && get_viewport()->find_world_3d()->get_camera_effects() == camera_effects) {
+ get_viewport()->find_world_3d()->set_camera_effects(Ref<CameraEffects>());
+ remove_from_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
//clean up
}
camera_effects = p_camera_effects;
if (is_inside_tree() && camera_effects.is_valid()) {
- if (get_viewport()->find_world()->get_camera_effects().is_valid()) {
+ if (get_viewport()->find_world_3d()->get_camera_effects().is_valid()) {
WARN_PRINT("World already has an camera_effects (Another WorldEnvironment?), overriding.");
}
- get_viewport()->find_world()->set_camera_effects(camera_effects);
- add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world()->get_scenario().get_id()));
+ get_viewport()->find_world_3d()->set_camera_effects(camera_effects);
+ add_to_group("_world_camera_effects_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()));
}
update_configuration_warning();
}
Ref<CameraEffects> WorldEnvironment::get_camera_effects() const {
-
return camera_effects;
}
String WorldEnvironment::get_configuration_warning() const {
-
if (!environment.is_valid()) {
return TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect.");
}
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return String();
+ }
List<Node *> nodes;
- get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world()->get_scenario().get_id()), &nodes);
+ get_tree()->get_nodes_in_group("_world_environment_" + itos(get_viewport()->find_world_3d()->get_scenario().get_id()), &nodes);
if (nodes.size() > 1) {
return TTR("Only one WorldEnvironment is allowed per scene (or set of instanced scenes).");
@@ -135,7 +128,6 @@ String WorldEnvironment::get_configuration_warning() const {
}
void WorldEnvironment::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_environment", "env"), &WorldEnvironment::set_environment);
ClassDB::bind_method(D_METHOD("get_environment"), &WorldEnvironment::get_environment);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment");
diff --git a/scene/3d/world_environment.h b/scene/3d/world_environment.h
index e4c9fc071d..ddb2af7bd3 100644
--- a/scene/3d/world_environment.h
+++ b/scene/3d/world_environment.h
@@ -34,7 +34,6 @@
#include "scene/3d/node_3d.h"
class WorldEnvironment : public Node {
-
GDCLASS(WorldEnvironment, Node);
Ref<Environment> environment;
diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp
index 0373114e7d..f4a514cdd6 100644
--- a/scene/3d/xr_nodes.cpp
+++ b/scene/3d/xr_nodes.cpp
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "xr_nodes.h"
-#include "core/input/input_filter.h"
+
+#include "core/input/input.h"
#include "servers/xr/xr_interface.h"
#include "servers/xr_server.h"
@@ -55,8 +56,9 @@ void XRCamera3D::_notification(int p_what) {
};
String XRCamera3D::get_configuration_warning() const {
- if (!is_visible() || !is_inside_tree())
+ if (!is_visible() || !is_inside_tree()) {
return String();
+ }
// must be child node of XROrigin3D!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
@@ -167,14 +169,6 @@ Vector<Plane> XRCamera3D::get_frustum() const {
return cm.get_projection_planes(get_camera_transform());
};
-XRCamera3D::XRCamera3D(){
- // nothing to do here yet for now..
-};
-
-XRCamera3D::~XRCamera3D(){
- // nothing to do here yet for now..
-};
-
////////////////////////////////////////////////////////////////////////////////////////////////////
void XRController3D::_notification(int p_what) {
@@ -206,7 +200,7 @@ void XRController3D::_notification(int p_what) {
// check button states
for (int i = 0; i < 16; i++) {
bool was_pressed = (button_states & mask) == mask;
- bool is_pressed = InputFilter::get_singleton()->is_joy_button_pressed(joy_id, i);
+ bool is_pressed = Input::get_singleton()->is_joy_button_pressed(joy_id, i);
if (!was_pressed && is_pressed) {
emit_signal("button_pressed", i);
@@ -269,11 +263,11 @@ void XRController3D::set_controller_id(int p_controller_id) {
update_configuration_warning();
};
-int XRController3D::get_controller_id(void) const {
+int XRController3D::get_controller_id() const {
return controller_id;
};
-String XRController3D::get_controller_name(void) const {
+String XRController3D::get_controller_name() const {
// get our XRServer
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, String());
@@ -306,7 +300,7 @@ bool XRController3D::is_button_pressed(int p_button) const {
return false;
};
- return InputFilter::get_singleton()->is_joy_button_pressed(joy_id, p_button);
+ return Input::get_singleton()->is_joy_button_pressed(joy_id, p_button);
};
float XRController3D::get_joystick_axis(int p_axis) const {
@@ -315,7 +309,7 @@ float XRController3D::get_joystick_axis(int p_axis) const {
return 0.0;
};
- return InputFilter::get_singleton()->get_joy_axis(joy_id, p_axis);
+ return Input::get_singleton()->get_joy_axis(joy_id, p_axis);
};
real_t XRController3D::get_rumble() const {
@@ -364,8 +358,9 @@ XRPositionalTracker::TrackerHand XRController3D::get_hand() const {
};
String XRController3D::get_configuration_warning() const {
- if (!is_visible() || !is_inside_tree())
+ if (!is_visible() || !is_inside_tree()) {
return String();
+ }
// must be child node of XROrigin!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
@@ -380,16 +375,6 @@ String XRController3D::get_configuration_warning() const {
return String();
};
-XRController3D::XRController3D() {
- controller_id = 1;
- is_active = true;
- button_states = 0;
-};
-
-XRController3D::~XRController3D(){
- // nothing to do here yet for now..
-};
-
////////////////////////////////////////////////////////////////////////////////////////////////////
void XRAnchor3D::_notification(int p_what) {
@@ -443,7 +428,6 @@ void XRAnchor3D::_notification(int p_what) {
};
void XRAnchor3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_anchor_id", "anchor_id"), &XRAnchor3D::set_anchor_id);
ClassDB::bind_method(D_METHOD("get_anchor_id"), &XRAnchor3D::get_anchor_id);
ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_id", PROPERTY_HINT_RANGE, "0,32,1"), "set_anchor_id", "get_anchor_id");
@@ -465,7 +449,7 @@ void XRAnchor3D::set_anchor_id(int p_anchor_id) {
update_configuration_warning();
};
-int XRAnchor3D::get_anchor_id(void) const {
+int XRAnchor3D::get_anchor_id() const {
return anchor_id;
};
@@ -473,7 +457,7 @@ Vector3 XRAnchor3D::get_size() const {
return size;
};
-String XRAnchor3D::get_anchor_name(void) const {
+String XRAnchor3D::get_anchor_name() const {
// get our XRServer
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, String());
@@ -491,8 +475,9 @@ bool XRAnchor3D::get_is_active() const {
};
String XRAnchor3D::get_configuration_warning() const {
- if (!is_visible() || !is_inside_tree())
+ if (!is_visible() || !is_inside_tree()) {
return String();
+ }
// must be child node of XROrigin3D!
XROrigin3D *origin = Object::cast_to<XROrigin3D>(get_parent());
@@ -520,23 +505,16 @@ Ref<Mesh> XRAnchor3D::get_mesh() const {
return mesh;
}
-XRAnchor3D::XRAnchor3D() {
- anchor_id = 1;
- is_active = true;
-};
-
-XRAnchor3D::~XRAnchor3D(){
- // nothing to do here yet for now..
-};
-
////////////////////////////////////////////////////////////////////////////////////////////////////
String XROrigin3D::get_configuration_warning() const {
- if (!is_visible() || !is_inside_tree())
+ if (!is_visible() || !is_inside_tree()) {
return String();
+ }
- if (tracked_camera == nullptr)
+ if (tracked_camera == nullptr) {
return TTR("XROrigin3D requires an XRCamera3D child node.");
+ }
return String();
};
@@ -611,11 +589,3 @@ void XROrigin3D::_notification(int p_what) {
}
}
};
-
-XROrigin3D::XROrigin3D() {
- tracked_camera = nullptr;
-};
-
-XROrigin3D::~XROrigin3D(){
- // nothing to do here yet for now..
-};
diff --git a/scene/3d/xr_nodes.h b/scene/3d/xr_nodes.h
index a2f16545d1..4d4f82aa38 100644
--- a/scene/3d/xr_nodes.h
+++ b/scene/3d/xr_nodes.h
@@ -44,7 +44,6 @@
XRCamera is a subclass of camera which will register itself with its parent XROrigin and as a result is automatically positioned
*/
class XRCamera3D : public Camera3D {
-
GDCLASS(XRCamera3D, Camera3D);
protected:
@@ -58,8 +57,8 @@ public:
virtual Vector3 project_position(const Point2 &p_point, float p_z_depth) const;
virtual Vector<Plane> get_frustum() const;
- XRCamera3D();
- ~XRCamera3D();
+ XRCamera3D() {}
+ ~XRCamera3D() {}
};
/*
@@ -69,13 +68,12 @@ public:
*/
class XRController3D : public Node3D {
-
GDCLASS(XRController3D, Node3D);
private:
- int controller_id;
- bool is_active;
- int button_states;
+ int controller_id = 1;
+ bool is_active = true;
+ int button_states = 0;
Ref<Mesh> mesh;
protected:
@@ -84,8 +82,8 @@ protected:
public:
void set_controller_id(int p_controller_id);
- int get_controller_id(void) const;
- String get_controller_name(void) const;
+ int get_controller_id() const;
+ String get_controller_name() const;
int get_joystick_id() const;
bool is_button_pressed(int p_button) const;
@@ -97,12 +95,12 @@ public:
bool get_is_active() const;
XRPositionalTracker::TrackerHand get_hand() const;
- Ref<Mesh> get_mesh(void) const;
+ Ref<Mesh> get_mesh() const;
String get_configuration_warning() const;
- XRController3D();
- ~XRController3D();
+ XRController3D() {}
+ ~XRController3D() {}
};
/*
@@ -114,8 +112,8 @@ class XRAnchor3D : public Node3D {
GDCLASS(XRAnchor3D, Node3D);
private:
- int anchor_id;
- bool is_active;
+ int anchor_id = 1;
+ bool is_active = true;
Vector3 size;
Ref<Mesh> mesh;
@@ -125,20 +123,20 @@ protected:
public:
void set_anchor_id(int p_anchor_id);
- int get_anchor_id(void) const;
- String get_anchor_name(void) const;
+ int get_anchor_id() const;
+ String get_anchor_name() const;
bool get_is_active() const;
Vector3 get_size() const;
Plane get_plane() const;
- Ref<Mesh> get_mesh(void) const;
+ Ref<Mesh> get_mesh() const;
String get_configuration_warning() const;
- XRAnchor3D();
- ~XRAnchor3D();
+ XRAnchor3D() {}
+ ~XRAnchor3D() {}
};
/*
@@ -150,11 +148,10 @@ public:
This node will automatically locate any camera child nodes and update its position while our XRController3D node will handle tracked controllers.
*/
class XROrigin3D : public Node3D {
-
GDCLASS(XROrigin3D, Node3D);
private:
- XRCamera3D *tracked_camera;
+ XRCamera3D *tracked_camera = nullptr;
protected:
void _notification(int p_what);
@@ -169,8 +166,8 @@ public:
float get_world_scale() const;
void set_world_scale(float p_world_scale);
- XROrigin3D();
- ~XROrigin3D();
+ XROrigin3D() {}
+ ~XROrigin3D() {}
};
#endif /* XR_NODES_H */
diff --git a/scene/animation/animation_blend_space_1d.cpp b/scene/animation/animation_blend_space_1d.cpp
index 3502f5e961..e426e98def 100644
--- a/scene/animation/animation_blend_space_1d.cpp
+++ b/scene/animation/animation_blend_space_1d.cpp
@@ -33,6 +33,7 @@
void AnimationNodeBlendSpace1D::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::FLOAT, blend_position));
}
+
Variant AnimationNodeBlendSpace1D::get_parameter_default_value(const StringName &p_parameter) const {
return 0;
}
@@ -167,7 +168,6 @@ void AnimationNodeBlendSpace1D::remove_blend_point(int p_point) {
}
int AnimationNodeBlendSpace1D::get_blend_point_count() const {
-
return blend_points_used;
}
@@ -220,7 +220,6 @@ void AnimationNodeBlendSpace1D::_add_blend_point(int p_index, const Ref<Animatio
}
float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) {
-
if (blend_points_used == 0) {
return 0.0;
}
@@ -241,7 +240,6 @@ float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) {
// find the closest two points to blend between
for (int i = 0; i < blend_points_used; i++) {
-
float pos = blend_points[i].position;
if (pos <= blend_pos) {
@@ -276,7 +274,6 @@ float AnimationNodeBlendSpace1D::process(float p_time, bool p_seek) {
weights[point_lower] = 1.0;
} else {
-
// we are between two points.
// figure out weights, then blend the animations
@@ -311,7 +308,6 @@ String AnimationNodeBlendSpace1D::get_caption() const {
}
AnimationNodeBlendSpace1D::AnimationNodeBlendSpace1D() {
-
for (int i = 0; i < MAX_BLEND_POINTS; i++) {
blend_points[i].name = itos(i);
}
diff --git a/scene/animation/animation_blend_space_2d.cpp b/scene/animation/animation_blend_space_2d.cpp
index 638531df41..003a4fad90 100644
--- a/scene/animation/animation_blend_space_2d.cpp
+++ b/scene/animation/animation_blend_space_2d.cpp
@@ -29,13 +29,15 @@
/*************************************************************************/
#include "animation_blend_space_2d.h"
-#include "core/math/delaunay.h"
+
+#include "core/math/delaunay_2d.h"
void AnimationNodeBlendSpace2D::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::VECTOR2, blend_position));
r_list->push_back(PropertyInfo(Variant::INT, closest, PROPERTY_HINT_NONE, "", 0));
r_list->push_back(PropertyInfo(Variant::FLOAT, length_internal, PROPERTY_HINT_NONE, "", 0));
}
+
Variant AnimationNodeBlendSpace2D::get_parameter_default_value(const StringName &p_parameter) const {
if (p_parameter == closest) {
return -1;
@@ -90,6 +92,7 @@ void AnimationNodeBlendSpace2D::set_blend_point_position(int p_point, const Vect
blend_points[p_point].position = p_position;
_queue_auto_triangles();
}
+
void AnimationNodeBlendSpace2D::set_blend_point_node(int p_point, const Ref<AnimationRootNode> &p_node) {
ERR_FAIL_INDEX(p_point, blend_points_used);
ERR_FAIL_COND(p_node.is_null());
@@ -102,14 +105,17 @@ void AnimationNodeBlendSpace2D::set_blend_point_node(int p_point, const Ref<Anim
emit_signal("tree_changed");
}
+
Vector2 AnimationNodeBlendSpace2D::get_blend_point_position(int p_point) const {
ERR_FAIL_INDEX_V(p_point, blend_points_used, Vector2());
return blend_points[p_point].position;
}
+
Ref<AnimationRootNode> AnimationNodeBlendSpace2D::get_blend_point_node(int p_point) const {
ERR_FAIL_INDEX_V(p_point, blend_points_used, Ref<AnimationRootNode>());
return blend_points[p_point].node;
}
+
void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
ERR_FAIL_INDEX(p_point, blend_points_used);
@@ -141,12 +147,10 @@ void AnimationNodeBlendSpace2D::remove_blend_point(int p_point) {
}
int AnimationNodeBlendSpace2D::get_blend_point_count() const {
-
return blend_points_used;
}
bool AnimationNodeBlendSpace2D::has_triangle(int p_x, int p_y, int p_z) const {
-
ERR_FAIL_INDEX_V(p_x, blend_points_used, false);
ERR_FAIL_INDEX_V(p_y, blend_points_used, false);
ERR_FAIL_INDEX_V(p_z, blend_points_used, false);
@@ -167,15 +171,15 @@ bool AnimationNodeBlendSpace2D::has_triangle(int p_x, int p_y, int p_z) const {
break;
}
}
- if (all_equal)
+ if (all_equal) {
return true;
+ }
}
return false;
}
void AnimationNodeBlendSpace2D::add_triangle(int p_x, int p_y, int p_z, int p_at_index) {
-
ERR_FAIL_INDEX(p_x, blend_points_used);
ERR_FAIL_INDEX(p_y, blend_points_used);
ERR_FAIL_INDEX(p_z, blend_points_used);
@@ -207,14 +211,15 @@ void AnimationNodeBlendSpace2D::add_triangle(int p_x, int p_y, int p_z, int p_at
triangles.insert(p_at_index, t);
}
}
-int AnimationNodeBlendSpace2D::get_triangle_point(int p_triangle, int p_point) {
+int AnimationNodeBlendSpace2D::get_triangle_point(int p_triangle, int p_point) {
_update_triangles();
ERR_FAIL_INDEX_V(p_point, 3, -1);
ERR_FAIL_INDEX_V(p_triangle, triangles.size(), -1);
return triangles[p_triangle].points[p_point];
}
+
void AnimationNodeBlendSpace2D::remove_triangle(int p_triangle) {
ERR_FAIL_INDEX(p_triangle, triangles.size());
@@ -226,7 +231,6 @@ int AnimationNodeBlendSpace2D::get_triangle_count() const {
}
void AnimationNodeBlendSpace2D::set_min_space(const Vector2 &p_min) {
-
min_space = p_min;
if (min_space.x >= max_space.x) {
min_space.x = max_space.x - 1;
@@ -235,12 +239,12 @@ void AnimationNodeBlendSpace2D::set_min_space(const Vector2 &p_min) {
min_space.y = max_space.y - 1;
}
}
+
Vector2 AnimationNodeBlendSpace2D::get_min_space() const {
return min_space;
}
void AnimationNodeBlendSpace2D::set_max_space(const Vector2 &p_max) {
-
max_space = p_max;
if (max_space.x <= min_space.x) {
max_space.x = min_space.x + 1;
@@ -249,6 +253,7 @@ void AnimationNodeBlendSpace2D::set_max_space(const Vector2 &p_max) {
max_space.y = min_space.y + 1;
}
}
+
Vector2 AnimationNodeBlendSpace2D::get_max_space() const {
return max_space;
}
@@ -256,6 +261,7 @@ Vector2 AnimationNodeBlendSpace2D::get_max_space() const {
void AnimationNodeBlendSpace2D::set_snap(const Vector2 &p_snap) {
snap = p_snap;
}
+
Vector2 AnimationNodeBlendSpace2D::get_snap() const {
return snap;
}
@@ -263,6 +269,7 @@ Vector2 AnimationNodeBlendSpace2D::get_snap() const {
void AnimationNodeBlendSpace2D::set_x_label(const String &p_label) {
x_label = p_label;
}
+
String AnimationNodeBlendSpace2D::get_x_label() const {
return x_label;
}
@@ -270,6 +277,7 @@ String AnimationNodeBlendSpace2D::get_x_label() const {
void AnimationNodeBlendSpace2D::set_y_label(const String &p_label) {
y_label = p_label;
}
+
String AnimationNodeBlendSpace2D::get_y_label() const {
return y_label;
}
@@ -283,9 +291,9 @@ void AnimationNodeBlendSpace2D::_add_blend_point(int p_index, const Ref<Animatio
}
void AnimationNodeBlendSpace2D::_set_triangles(const Vector<int> &p_triangles) {
-
- if (auto_triangles)
+ if (auto_triangles) {
return;
+ }
ERR_FAIL_COND(p_triangles.size() % 3 != 0);
for (int i = 0; i < p_triangles.size(); i += 3) {
add_triangle(p_triangles[i + 0], p_triangles[i + 1], p_triangles[i + 2]);
@@ -293,10 +301,10 @@ void AnimationNodeBlendSpace2D::_set_triangles(const Vector<int> &p_triangles) {
}
Vector<int> AnimationNodeBlendSpace2D::_get_triangles() const {
-
Vector<int> t;
- if (auto_triangles && trianges_dirty)
+ if (auto_triangles && trianges_dirty) {
return t;
+ }
t.resize(triangles.size() * 3);
for (int i = 0; i < triangles.size(); i++) {
@@ -317,9 +325,9 @@ void AnimationNodeBlendSpace2D::_queue_auto_triangles() {
}
void AnimationNodeBlendSpace2D::_update_triangles() {
-
- if (!auto_triangles || !trianges_dirty)
+ if (!auto_triangles || !trianges_dirty) {
return;
+ }
trianges_dirty = false;
triangles.clear();
@@ -343,11 +351,11 @@ void AnimationNodeBlendSpace2D::_update_triangles() {
}
Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) {
-
_update_triangles();
- if (triangles.size() == 0)
+ if (triangles.size() == 0) {
return Vector2();
+ }
Vector2 best_point;
bool first = true;
@@ -359,7 +367,6 @@ Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) {
}
if (Geometry::is_point_in_triangle(p_point, points[0], points[1], points[2])) {
-
return p_point;
}
@@ -380,7 +387,6 @@ Vector2 AnimationNodeBlendSpace2D::get_closest_point(const Vector2 &p_point) {
}
void AnimationNodeBlendSpace2D::_blend_triangle(const Vector2 &p_pos, const Vector2 *p_points, float *r_weights) {
-
if (p_pos.distance_squared_to(p_points[0]) < CMP_EPSILON2) {
r_weights[0] = 1;
r_weights[1] = 0;
@@ -426,7 +432,6 @@ void AnimationNodeBlendSpace2D::_blend_triangle(const Vector2 &p_pos, const Vect
}
float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
-
_update_triangles();
Vector2 blend_pos = get_parameter(blend_position);
@@ -435,9 +440,9 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
float mind = 0; //time of min distance point
if (blend_mode == BLEND_MODE_INTERPOLATED) {
-
- if (triangles.size() == 0)
+ if (triangles.size() == 0) {
return 0;
+ }
Vector2 best_point;
bool first = true;
@@ -451,7 +456,6 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
}
if (Geometry::is_point_in_triangle(blend_pos, points[0], points[1], points[2])) {
-
blend_triangle = i;
_blend_triangle(blend_pos, points, blend_weights);
break;
@@ -493,7 +497,6 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
first = true;
for (int i = 0; i < blend_points_used; i++) {
-
bool found = false;
for (int j = 0; j < 3; j++) {
if (i == triangle_points[j]) {
@@ -514,22 +517,18 @@ float AnimationNodeBlendSpace2D::process(float p_time, bool p_seek) {
}
}
} else {
-
int new_closest = -1;
float new_closest_dist = 1e20;
for (int i = 0; i < blend_points_used; i++) {
-
float d = blend_points[i].position.distance_squared_to(blend_pos);
if (d < new_closest_dist) {
-
new_closest = i;
new_closest_dist = d;
}
}
if (new_closest != closest && new_closest != -1) {
-
float from = 0;
if (blend_mode == BLEND_MODE_DISCRETE_CARRY && closest != -1) {
//see how much animation remains
@@ -556,7 +555,6 @@ String AnimationNodeBlendSpace2D::get_caption() const {
}
void AnimationNodeBlendSpace2D::_validate_property(PropertyInfo &property) const {
-
if (auto_triangles && property.name == "triangles") {
property.usage = 0;
}
@@ -600,7 +598,6 @@ AnimationNodeBlendSpace2D::BlendMode AnimationNodeBlendSpace2D::get_blend_mode()
}
void AnimationNodeBlendSpace2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_blend_point", "node", "pos", "at_index"), &AnimationNodeBlendSpace2D::add_blend_point, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("set_blend_point_position", "point", "pos"), &AnimationNodeBlendSpace2D::set_blend_point_position);
ClassDB::bind_method(D_METHOD("get_blend_point_position", "point"), &AnimationNodeBlendSpace2D::get_blend_point_position);
@@ -665,7 +662,6 @@ void AnimationNodeBlendSpace2D::_bind_methods() {
}
AnimationNodeBlendSpace2D::AnimationNodeBlendSpace2D() {
-
for (int i = 0; i < MAX_BLEND_POINTS; i++) {
blend_points[i].name = itos(i);
}
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 570735ad87..56995c0c13 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -46,13 +46,12 @@ Vector<String> (*AnimationNodeAnimation::get_editable_animation_list)() = nullpt
void AnimationNodeAnimation::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::FLOAT, time, PROPERTY_HINT_NONE, "", 0));
}
-void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const {
+void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const {
if (property.name == "animation" && get_editable_animation_list) {
Vector<String> names = get_editable_animation_list();
String anims;
for (int i = 0; i < names.size(); i++) {
-
if (i > 0) {
anims += ",";
}
@@ -66,14 +65,12 @@ void AnimationNodeAnimation::_validate_property(PropertyInfo &property) const {
}
float AnimationNodeAnimation::process(float p_time, bool p_seek) {
-
AnimationPlayer *ap = state->player;
ERR_FAIL_COND_V(!ap, 0);
float time = get_parameter(this->time);
if (!ap->has_animation(animation)) {
-
AnimationNodeBlendTree *tree = Object::cast_to<AnimationNodeBlendTree>(parent);
if (tree) {
String name = tree->get_node_name(Ref<AnimationNodeAnimation>(this));
@@ -101,13 +98,11 @@ float AnimationNodeAnimation::process(float p_time, bool p_seek) {
float anim_size = anim->get_length();
if (anim->has_loop()) {
-
if (anim_size) {
time = Math::fposmod(time, anim_size);
}
} else if (time > anim_size) {
-
time = anim_size;
}
@@ -156,56 +151,50 @@ Variant AnimationNodeOneShot::get_parameter_default_value(const StringName &p_pa
}
void AnimationNodeOneShot::set_fadein_time(float p_time) {
-
fade_in = p_time;
}
void AnimationNodeOneShot::set_fadeout_time(float p_time) {
-
fade_out = p_time;
}
float AnimationNodeOneShot::get_fadein_time() const {
-
return fade_in;
}
-float AnimationNodeOneShot::get_fadeout_time() const {
+float AnimationNodeOneShot::get_fadeout_time() const {
return fade_out;
}
void AnimationNodeOneShot::set_autorestart(bool p_active) {
-
autorestart = p_active;
}
-void AnimationNodeOneShot::set_autorestart_delay(float p_time) {
+void AnimationNodeOneShot::set_autorestart_delay(float p_time) {
autorestart_delay = p_time;
}
-void AnimationNodeOneShot::set_autorestart_random_delay(float p_time) {
+void AnimationNodeOneShot::set_autorestart_random_delay(float p_time) {
autorestart_random_delay = p_time;
}
bool AnimationNodeOneShot::has_autorestart() const {
-
return autorestart;
}
-float AnimationNodeOneShot::get_autorestart_delay() const {
+float AnimationNodeOneShot::get_autorestart_delay() const {
return autorestart_delay;
}
-float AnimationNodeOneShot::get_autorestart_random_delay() const {
+float AnimationNodeOneShot::get_autorestart_random_delay() const {
return autorestart_random_delay;
}
void AnimationNodeOneShot::set_mix_mode(MixMode p_mix) {
-
mix = p_mix;
}
-AnimationNodeOneShot::MixMode AnimationNodeOneShot::get_mix_mode() const {
+AnimationNodeOneShot::MixMode AnimationNodeOneShot::get_mix_mode() const {
return mix;
}
@@ -218,7 +207,6 @@ bool AnimationNodeOneShot::has_filter() const {
}
float AnimationNodeOneShot::process(float p_time, bool p_seek) {
-
bool active = get_parameter(this->active);
bool prev_active = get_parameter(this->prev_active);
float time = get_parameter(this->time);
@@ -247,8 +235,9 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) {
bool os_seek = p_seek;
- if (p_seek)
+ if (p_seek) {
time = p_time;
+ }
bool do_start = !prev_active;
if (do_start) {
@@ -260,20 +249,21 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) {
float blend;
if (time < fade_in) {
-
- if (fade_in > 0)
+ if (fade_in > 0) {
blend = time / fade_in;
- else
+ } else {
blend = 0; //wtf
+ }
} else if (!do_start && remaining < fade_out) {
-
- if (fade_out)
+ if (fade_out) {
blend = (remaining / fade_out);
- else
+ } else {
blend = 1.0;
- } else
+ }
+ } else {
blend = 1.0;
+ }
float main_rem;
if (mix == MIX_MODE_ADD) {
@@ -306,18 +296,16 @@ float AnimationNodeOneShot::process(float p_time, bool p_seek) {
return MAX(main_rem, remaining);
}
-void AnimationNodeOneShot::set_use_sync(bool p_sync) {
+void AnimationNodeOneShot::set_use_sync(bool p_sync) {
sync = p_sync;
}
bool AnimationNodeOneShot::is_using_sync() const {
-
return sync;
}
void AnimationNodeOneShot::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_fadein_time", "time"), &AnimationNodeOneShot::set_fadein_time);
ClassDB::bind_method(D_METHOD("get_fadein_time"), &AnimationNodeOneShot::get_fadein_time);
@@ -356,7 +344,6 @@ void AnimationNodeOneShot::_bind_methods() {
}
AnimationNodeOneShot::AnimationNodeOneShot() {
-
add_input("in");
add_input("shot");
@@ -381,6 +368,7 @@ AnimationNodeOneShot::AnimationNodeOneShot() {
void AnimationNodeAdd2::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::FLOAT, add_amount, PROPERTY_HINT_RANGE, "0,1,0.01"));
}
+
Variant AnimationNodeAdd2::get_parameter_default_value(const StringName &p_parameter) const {
return 0;
}
@@ -388,23 +376,20 @@ Variant AnimationNodeAdd2::get_parameter_default_value(const StringName &p_param
String AnimationNodeAdd2::get_caption() const {
return "Add2";
}
-void AnimationNodeAdd2::set_use_sync(bool p_sync) {
+void AnimationNodeAdd2::set_use_sync(bool p_sync) {
sync = p_sync;
}
bool AnimationNodeAdd2::is_using_sync() const {
-
return sync;
}
bool AnimationNodeAdd2::has_filter() const {
-
return true;
}
float AnimationNodeAdd2::process(float p_time, bool p_seek) {
-
float amount = get_parameter(add_amount);
float rem0 = blend_input(0, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
blend_input(1, p_time, p_seek, amount, FILTER_PASS, !sync);
@@ -413,7 +398,6 @@ float AnimationNodeAdd2::process(float p_time, bool p_seek) {
}
void AnimationNodeAdd2::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd2::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd2::is_using_sync);
@@ -421,7 +405,6 @@ void AnimationNodeAdd2::_bind_methods() {
}
AnimationNodeAdd2::AnimationNodeAdd2() {
-
add_amount = "add_amount";
add_input("in");
add_input("add");
@@ -433,6 +416,7 @@ AnimationNodeAdd2::AnimationNodeAdd2() {
void AnimationNodeAdd3::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::FLOAT, add_amount, PROPERTY_HINT_RANGE, "-1,1,0.01"));
}
+
Variant AnimationNodeAdd3::get_parameter_default_value(const StringName &p_parameter) const {
return 0;
}
@@ -440,23 +424,20 @@ Variant AnimationNodeAdd3::get_parameter_default_value(const StringName &p_param
String AnimationNodeAdd3::get_caption() const {
return "Add3";
}
-void AnimationNodeAdd3::set_use_sync(bool p_sync) {
+void AnimationNodeAdd3::set_use_sync(bool p_sync) {
sync = p_sync;
}
bool AnimationNodeAdd3::is_using_sync() const {
-
return sync;
}
bool AnimationNodeAdd3::has_filter() const {
-
return true;
}
float AnimationNodeAdd3::process(float p_time, bool p_seek) {
-
float amount = get_parameter(add_amount);
blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_PASS, !sync);
float rem0 = blend_input(1, p_time, p_seek, 1.0, FILTER_IGNORE, !sync);
@@ -466,7 +447,6 @@ float AnimationNodeAdd3::process(float p_time, bool p_seek) {
}
void AnimationNodeAdd3::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeAdd3::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeAdd3::is_using_sync);
@@ -474,18 +454,19 @@ void AnimationNodeAdd3::_bind_methods() {
}
AnimationNodeAdd3::AnimationNodeAdd3() {
-
add_amount = "add_amount";
add_input("-add");
add_input("in");
add_input("+add");
sync = false;
}
+
/////////////////////////////////////////////
void AnimationNodeBlend2::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::FLOAT, blend_amount, PROPERTY_HINT_RANGE, "0,1,0.01"));
}
+
Variant AnimationNodeBlend2::get_parameter_default_value(const StringName &p_parameter) const {
return 0; //for blend amount
}
@@ -495,7 +476,6 @@ String AnimationNodeBlend2::get_caption() const {
}
float AnimationNodeBlend2::process(float p_time, bool p_seek) {
-
float amount = get_parameter(blend_amount);
float rem0 = blend_input(0, p_time, p_seek, 1.0 - amount, FILTER_BLEND, !sync);
@@ -505,26 +485,24 @@ float AnimationNodeBlend2::process(float p_time, bool p_seek) {
}
void AnimationNodeBlend2::set_use_sync(bool p_sync) {
-
sync = p_sync;
}
bool AnimationNodeBlend2::is_using_sync() const {
-
return sync;
}
bool AnimationNodeBlend2::has_filter() const {
-
return true;
}
-void AnimationNodeBlend2::_bind_methods() {
+void AnimationNodeBlend2::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeBlend2::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeBlend2::is_using_sync);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
+
AnimationNodeBlend2::AnimationNodeBlend2() {
blend_amount = "blend_amount";
add_input("in");
@@ -537,6 +515,7 @@ AnimationNodeBlend2::AnimationNodeBlend2() {
void AnimationNodeBlend3::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::FLOAT, blend_amount, PROPERTY_HINT_RANGE, "-1,1,0.01"));
}
+
Variant AnimationNodeBlend3::get_parameter_default_value(const StringName &p_parameter) const {
return 0; //for blend amount
}
@@ -546,17 +525,14 @@ String AnimationNodeBlend3::get_caption() const {
}
void AnimationNodeBlend3::set_use_sync(bool p_sync) {
-
sync = p_sync;
}
bool AnimationNodeBlend3::is_using_sync() const {
-
return sync;
}
float AnimationNodeBlend3::process(float p_time, bool p_seek) {
-
float amount = get_parameter(blend_amount);
float rem0 = blend_input(0, p_time, p_seek, MAX(0, -amount), FILTER_IGNORE, !sync);
float rem1 = blend_input(1, p_time, p_seek, 1.0 - ABS(amount), FILTER_IGNORE, !sync);
@@ -566,12 +542,12 @@ float AnimationNodeBlend3::process(float p_time, bool p_seek) {
}
void AnimationNodeBlend3::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_use_sync", "enable"), &AnimationNodeBlend3::set_use_sync);
ClassDB::bind_method(D_METHOD("is_using_sync"), &AnimationNodeBlend3::is_using_sync);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sync"), "set_use_sync", "is_using_sync");
}
+
AnimationNodeBlend3::AnimationNodeBlend3() {
blend_amount = "blend_amount";
add_input("-blend");
@@ -585,6 +561,7 @@ AnimationNodeBlend3::AnimationNodeBlend3() {
void AnimationNodeTimeScale::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::FLOAT, scale, PROPERTY_HINT_RANGE, "0,32,0.01,or_greater"));
}
+
Variant AnimationNodeTimeScale::get_parameter_default_value(const StringName &p_parameter) const {
return 1.0; //initial timescale
}
@@ -594,7 +571,6 @@ String AnimationNodeTimeScale::get_caption() const {
}
float AnimationNodeTimeScale::process(float p_time, bool p_seek) {
-
float scale = get_parameter(this->scale);
if (p_seek) {
return blend_input(0, p_time, true, 1.0, FILTER_IGNORE, false);
@@ -605,6 +581,7 @@ float AnimationNodeTimeScale::process(float p_time, bool p_seek) {
void AnimationNodeTimeScale::_bind_methods() {
}
+
AnimationNodeTimeScale::AnimationNodeTimeScale() {
scale = "scale";
add_input("in");
@@ -615,6 +592,7 @@ AnimationNodeTimeScale::AnimationNodeTimeScale() {
void AnimationNodeTimeSeek::get_parameter_list(List<PropertyInfo> *r_list) const {
r_list->push_back(PropertyInfo(Variant::FLOAT, seek_pos, PROPERTY_HINT_RANGE, "-1,3600,0.01,or_greater"));
}
+
Variant AnimationNodeTimeSeek::get_parameter_default_value(const StringName &p_parameter) const {
return 1.0; //initial timescale
}
@@ -624,7 +602,6 @@ String AnimationNodeTimeSeek::get_caption() const {
}
float AnimationNodeTimeSeek::process(float p_time, bool p_seek) {
-
float seek_pos = get_parameter(this->seek_pos);
if (p_seek) {
return blend_input(0, p_time, true, 1.0, FILTER_IGNORE, false);
@@ -649,7 +626,6 @@ AnimationNodeTimeSeek::AnimationNodeTimeSeek() {
/////////////////////////////////////////////////
void AnimationNodeTransition::get_parameter_list(List<PropertyInfo> *r_list) const {
-
String anims;
for (int i = 0; i < enabled_inputs; i++) {
if (i > 0) {
@@ -664,6 +640,7 @@ void AnimationNodeTransition::get_parameter_list(List<PropertyInfo> *r_list) con
r_list->push_back(PropertyInfo(Variant::FLOAT, time, PROPERTY_HINT_NONE, "", 0));
r_list->push_back(PropertyInfo(Variant::FLOAT, prev_xfading, PROPERTY_HINT_NONE, "", 0));
}
+
Variant AnimationNodeTransition::get_parameter_default_value(const StringName &p_parameter) const {
if (p_parameter == time || p_parameter == prev_xfading) {
return 0.0;
@@ -728,7 +705,6 @@ float AnimationNodeTransition::get_cross_fade_time() const {
}
float AnimationNodeTransition::process(float p_time, bool p_seek) {
-
int current = get_parameter(this->current);
int prev = get_parameter(this->prev);
int prev_current = get_parameter(this->prev_current);
@@ -758,13 +734,13 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) {
rem = blend_input(current, p_time, p_seek, 1.0, FILTER_IGNORE, false);
- if (p_seek)
+ if (p_seek) {
time = p_time;
- else
+ } else {
time += p_time;
+ }
if (inputs[current].auto_advance && rem <= xfade) {
-
set_parameter(this->current, (current + 1) % enabled_inputs);
}
@@ -776,7 +752,6 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) {
rem = blend_input(current, 0, true, 1.0 - blend, FILTER_IGNORE, false);
} else {
-
rem = blend_input(current, p_time, p_seek, 1.0 - blend, FILTER_IGNORE, false);
}
@@ -800,7 +775,6 @@ float AnimationNodeTransition::process(float p_time, bool p_seek) {
}
void AnimationNodeTransition::_validate_property(PropertyInfo &property) const {
-
if (property.name.begins_with("input_")) {
String n = property.name.get_slicec('/', 0).get_slicec('_', 1);
if (n != "count") {
@@ -815,7 +789,6 @@ void AnimationNodeTransition::_validate_property(PropertyInfo &property) const {
}
void AnimationNodeTransition::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_enabled_inputs", "amount"), &AnimationNodeTransition::set_enabled_inputs);
ClassDB::bind_method(D_METHOD("get_enabled_inputs"), &AnimationNodeTransition::get_enabled_inputs);
@@ -838,7 +811,6 @@ void AnimationNodeTransition::_bind_methods() {
}
AnimationNodeTransition::AnimationNodeTransition() {
-
prev_xfading = "prev_xfading";
prev = "prev";
time = "time";
@@ -869,7 +841,6 @@ AnimationNodeOutput::AnimationNodeOutput() {
///////////////////////////////////////////////////////
void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) {
-
ERR_FAIL_COND(nodes.has(p_name));
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output);
@@ -889,7 +860,6 @@ void AnimationNodeBlendTree::add_node(const StringName &p_name, Ref<AnimationNod
}
Ref<AnimationNode> AnimationNodeBlendTree::get_node(const StringName &p_name) const {
-
ERR_FAIL_COND_V(!nodes.has(p_name), Ref<AnimationNode>());
return nodes[p_name].node;
@@ -935,13 +905,13 @@ void AnimationNodeBlendTree::get_child_nodes(List<ChildNode> *r_child_nodes) {
bool AnimationNodeBlendTree::has_node(const StringName &p_name) const {
return nodes.has(p_name);
}
-Vector<StringName> AnimationNodeBlendTree::get_node_connection_array(const StringName &p_name) const {
+Vector<StringName> AnimationNodeBlendTree::get_node_connection_array(const StringName &p_name) const {
ERR_FAIL_COND_V(!nodes.has(p_name), Vector<StringName>());
return nodes[p_name].connections;
}
-void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
+void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
ERR_FAIL_COND(!nodes.has(p_name));
ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output); //can't delete output
@@ -967,7 +937,6 @@ void AnimationNodeBlendTree::remove_node(const StringName &p_name) {
}
void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringName &p_new_name) {
-
ERR_FAIL_COND(!nodes.has(p_name));
ERR_FAIL_COND(nodes.has(p_new_name));
ERR_FAIL_COND(p_name == SceneStringNames::get_singleton()->output);
@@ -980,7 +949,6 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN
//rename connections
for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
-
for (int i = 0; i < E->get().connections.size(); i++) {
if (E->get().connections[i] == p_name) {
E->get().connections.write[i] = p_new_name;
@@ -994,7 +962,6 @@ void AnimationNodeBlendTree::rename_node(const StringName &p_name, const StringN
}
void AnimationNodeBlendTree::connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) {
-
ERR_FAIL_COND(!nodes.has(p_output_node));
ERR_FAIL_COND(!nodes.has(p_input_node));
ERR_FAIL_COND(p_output_node == SceneStringNames::get_singleton()->output);
@@ -1016,7 +983,6 @@ void AnimationNodeBlendTree::connect_node(const StringName &p_input_node, int p_
}
void AnimationNodeBlendTree::disconnect_node(const StringName &p_node, int p_input_index) {
-
ERR_FAIL_COND(!nodes.has(p_node));
Ref<AnimationNode> input = nodes[p_node].node;
@@ -1026,7 +992,6 @@ void AnimationNodeBlendTree::disconnect_node(const StringName &p_node, int p_inp
}
AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node(const StringName &p_input_node, int p_input_index, const StringName &p_output_node) const {
-
if (!nodes.has(p_output_node) || p_output_node == SceneStringNames::get_singleton()->output) {
return CONNECTION_ERROR_NO_OUTPUT;
}
@@ -1061,7 +1026,6 @@ AnimationNodeBlendTree::ConnectionError AnimationNodeBlendTree::can_connect_node
}
void AnimationNodeBlendTree::get_node_connections(List<NodeConnection> *r_connections) const {
-
for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
for (int i = 0; i < E->get().connections.size(); i++) {
StringName output = E->get().connections[i];
@@ -1081,25 +1045,21 @@ String AnimationNodeBlendTree::get_caption() const {
}
float AnimationNodeBlendTree::process(float p_time, bool p_seek) {
-
Ref<AnimationNodeOutput> output = nodes[SceneStringNames::get_singleton()->output].node;
return _blend_node("output", nodes[SceneStringNames::get_singleton()->output].connections, this, output, p_time, p_seek, 1.0);
}
void AnimationNodeBlendTree::get_node_list(List<StringName> *r_list) {
-
for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
r_list->push_back(E->key());
}
}
void AnimationNodeBlendTree::set_graph_offset(const Vector2 &p_graph_offset) {
-
graph_offset = p_graph_offset;
}
Vector2 AnimationNodeBlendTree::get_graph_offset() const {
-
return graph_offset;
}
@@ -1108,10 +1068,8 @@ Ref<AnimationNode> AnimationNodeBlendTree::get_child_by_name(const StringName &p
}
bool AnimationNodeBlendTree::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name.begins_with("nodes/")) {
-
String node_name = name.get_slicec('/', 1);
String what = name.get_slicec('/', 2);
@@ -1124,14 +1082,12 @@ bool AnimationNodeBlendTree::_set(const StringName &p_name, const Variant &p_val
}
if (what == "position") {
-
if (nodes.has(node_name)) {
nodes[node_name].position = p_value;
}
return true;
}
} else if (name == "node_connections") {
-
Array conns = p_value;
ERR_FAIL_COND_V(conns.size() % 3 != 0, false);
@@ -1145,7 +1101,6 @@ bool AnimationNodeBlendTree::_set(const StringName &p_name, const Variant &p_val
}
bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name.begins_with("nodes/")) {
String node_name = name.get_slicec('/', 1);
@@ -1159,7 +1114,6 @@ bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) cons
}
if (what == "position") {
-
if (nodes.has(node_name)) {
r_ret = nodes[node_name].position;
return true;
@@ -1185,8 +1139,8 @@ bool AnimationNodeBlendTree::_get(const StringName &p_name, Variant &r_ret) cons
return false;
}
-void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) const {
+void AnimationNodeBlendTree::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
for (Map<StringName, Node>::Element *E = nodes.front(); E; E = E->next()) {
names.push_back(E->key());
@@ -1209,13 +1163,11 @@ void AnimationNodeBlendTree::_tree_changed() {
}
void AnimationNodeBlendTree::_node_changed(const StringName &p_node) {
-
ERR_FAIL_COND(!nodes.has(p_node));
nodes[p_node].connections.resize(nodes[p_node].node->get_input_count());
}
void AnimationNodeBlendTree::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_node", "name", "node", "position"), &AnimationNodeBlendTree::add_node, DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("get_node", "name"), &AnimationNodeBlendTree::get_node);
ClassDB::bind_method(D_METHOD("remove_node", "name"), &AnimationNodeBlendTree::remove_node);
@@ -1241,7 +1193,6 @@ void AnimationNodeBlendTree::_bind_methods() {
}
AnimationNodeBlendTree::AnimationNodeBlendTree() {
-
Ref<AnimationNodeOutput> output;
output.instance();
Node n;
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 7ebe3f5444..5c722d00f9 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -34,7 +34,6 @@
#include "scene/animation/animation_tree.h"
class AnimationNodeAnimation : public AnimationRootNode {
-
GDCLASS(AnimationNodeAnimation, AnimationRootNode);
StringName animation;
@@ -268,7 +267,6 @@ class AnimationNodeTransition : public AnimationNode {
MAX_INPUTS = 32
};
struct InputData {
-
String name;
bool auto_advance;
InputData() { auto_advance = false; }
diff --git a/scene/animation/animation_cache.cpp b/scene/animation/animation_cache.cpp
index ab8be47b4d..abb2cf1b65 100644
--- a/scene/animation/animation_cache.cpp
+++ b/scene/animation/animation_cache.cpp
@@ -31,7 +31,6 @@
#include "animation_cache.h"
void AnimationCache::_node_exit_tree(Node *p_node) {
-
//it is one shot, so it disconnects upon arrival
ERR_FAIL_COND(!connected_nodes.has(p_node));
@@ -39,23 +38,20 @@ void AnimationCache::_node_exit_tree(Node *p_node) {
connected_nodes.erase(p_node);
for (int i = 0; i < path_cache.size(); i++) {
-
- if (path_cache[i].node != p_node)
+ if (path_cache[i].node != p_node) {
continue;
+ }
path_cache.write[i].valid = false; //invalidate path cache
}
}
void AnimationCache::_animation_changed() {
-
_clear_cache();
}
void AnimationCache::_clear_cache() {
-
while (connected_nodes.size()) {
-
connected_nodes.front()->get()->disconnect("tree_exiting", callable_mp(this, &AnimationCache::_node_exit_tree));
connected_nodes.erase(connected_nodes.front());
}
@@ -65,7 +61,6 @@ void AnimationCache::_clear_cache() {
}
void AnimationCache::_update_cache() {
-
cache_valid = false;
ERR_FAIL_COND(!root);
@@ -73,12 +68,10 @@ void AnimationCache::_update_cache() {
ERR_FAIL_COND(animation.is_null());
for (int i = 0; i < animation->get_track_count(); i++) {
-
NodePath np = animation->track_get_path(i);
Node *node = root->get_node(np);
if (!node) {
-
path_cache.push_back(Path());
ERR_CONTINUE_MSG(!node, "Invalid track path in animation '" + np + "'.");
}
@@ -88,7 +81,6 @@ void AnimationCache::_update_cache() {
Ref<Resource> res;
if (animation->track_get_type(i) == Animation::TYPE_TRANSFORM) {
-
if (np.get_subname_count() > 1) {
path_cache.push_back(Path());
ERR_CONTINUE_MSG(animation->track_get_type(i) == Animation::TYPE_TRANSFORM, "Transform tracks can't have a subpath '" + np + "'.");
@@ -97,7 +89,6 @@ void AnimationCache::_update_cache() {
Node3D *sp = Object::cast_to<Node3D>(node);
if (!sp) {
-
path_cache.push_back(Path());
ERR_CONTINUE_MSG(!sp, "Transform track not of type Node3D '" + np + "'.");
}
@@ -108,7 +99,6 @@ void AnimationCache::_update_cache() {
Skeleton3D *sk = Object::cast_to<Skeleton3D>(node);
if (!sk) {
-
path_cache.push_back(Path());
ERR_CONTINUE_MSG(!sk, "Property defined in Transform track, but not a Skeleton! '" + np + "'.");
}
@@ -127,7 +117,6 @@ void AnimationCache::_update_cache() {
} else {
if (np.get_subname_count() > 0) {
-
RES res2;
Vector<StringName> leftover_subpath;
@@ -144,7 +133,6 @@ void AnimationCache::_update_cache() {
path.subpath = leftover_subpath;
} else {
-
path.node = node;
path.object = node;
path.subpath = np.get_subnames();
@@ -152,15 +140,12 @@ void AnimationCache::_update_cache() {
}
if (animation->track_get_type(i) == Animation::TYPE_VALUE) {
-
if (np.get_subname_count() == 0) {
-
path_cache.push_back(Path());
ERR_CONTINUE_MSG(np.get_subname_count() == 0, "Value Track lacks property: " + np + ".");
}
} else if (animation->track_get_type(i) == Animation::TYPE_METHOD) {
-
if (path.subpath.size() != 0) { // Trying to call a method of a non-resource
path_cache.push_back(Path());
@@ -183,15 +168,16 @@ void AnimationCache::_update_cache() {
}
void AnimationCache::set_track_transform(int p_idx, const Transform &p_transform) {
-
- if (cache_dirty)
+ if (cache_dirty) {
_update_cache();
+ }
ERR_FAIL_COND(!cache_valid);
ERR_FAIL_INDEX(p_idx, path_cache.size());
Path &p = path_cache.write[p_idx];
- if (!p.valid)
+ if (!p.valid) {
return;
+ }
ERR_FAIL_COND(!p.node);
ERR_FAIL_COND(!p.spatial);
@@ -204,49 +190,48 @@ void AnimationCache::set_track_transform(int p_idx, const Transform &p_transform
}
void AnimationCache::set_track_value(int p_idx, const Variant &p_value) {
-
- if (cache_dirty)
+ if (cache_dirty) {
_update_cache();
+ }
ERR_FAIL_COND(!cache_valid);
ERR_FAIL_INDEX(p_idx, path_cache.size());
Path &p = path_cache.write[p_idx];
- if (!p.valid)
+ if (!p.valid) {
return;
+ }
ERR_FAIL_COND(!p.object);
p.object->set_indexed(p.subpath, p_value);
}
void AnimationCache::call_track(int p_idx, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
- if (cache_dirty)
+ if (cache_dirty) {
_update_cache();
+ }
ERR_FAIL_COND(!cache_valid);
ERR_FAIL_INDEX(p_idx, path_cache.size());
Path &p = path_cache.write[p_idx];
- if (!p.valid)
+ if (!p.valid) {
return;
+ }
ERR_FAIL_COND(!p.object);
p.object->call(p_method, p_args, p_argcount, r_error);
}
void AnimationCache::set_all(float p_time, float p_delta) {
-
- if (cache_dirty)
+ if (cache_dirty) {
_update_cache();
+ }
ERR_FAIL_COND(!cache_valid);
int tc = animation->get_track_count();
for (int i = 0; i < tc; i++) {
-
switch (animation->track_get_type(i)) {
-
case Animation::TYPE_TRANSFORM: {
-
Vector3 loc, scale;
Quat rot;
animation->transform_track_interpolate(i, p_time, &loc, &rot, &scale);
@@ -257,17 +242,14 @@ void AnimationCache::set_all(float p_time, float p_delta) {
} break;
case Animation::TYPE_VALUE: {
-
if (animation->value_track_get_update_mode(i) == Animation::UPDATE_CONTINUOUS || (animation->value_track_get_update_mode(i) == Animation::UPDATE_DISCRETE && p_delta == 0)) {
Variant v = animation->value_track_interpolate(i, p_time);
set_track_value(i, v);
} else {
-
List<int> indices;
animation->value_track_get_key_indices(i, p_time, p_delta, &indices);
for (List<int>::Element *E = indices.front(); E; E = E->next()) {
-
Variant v = animation->track_get_key_value(i, E->get());
set_track_value(i, v);
}
@@ -275,25 +257,20 @@ void AnimationCache::set_all(float p_time, float p_delta) {
} break;
case Animation::TYPE_METHOD: {
-
List<int> indices;
animation->method_track_get_key_indices(i, p_time, p_delta, &indices);
for (List<int>::Element *E = indices.front(); E; E = E->next()) {
-
Vector<Variant> args = animation->method_track_get_params(i, E->get());
StringName name = animation->method_track_get_name(i, E->get());
Callable::CallError err;
if (!args.size()) {
-
call_track(i, name, nullptr, 0, err);
} else {
-
Vector<const Variant *> argptrs;
argptrs.resize(args.size());
for (int j = 0; j < args.size(); j++) {
-
argptrs.write[j] = &args.write[j];
}
@@ -309,29 +286,28 @@ void AnimationCache::set_all(float p_time, float p_delta) {
}
void AnimationCache::set_animation(const Ref<Animation> &p_animation) {
-
_clear_cache();
- if (animation.is_valid())
+ if (animation.is_valid()) {
animation->disconnect("changed", callable_mp(this, &AnimationCache::_animation_changed));
+ }
animation = p_animation;
- if (animation.is_valid())
+ if (animation.is_valid()) {
animation->connect("changed", callable_mp(this, &AnimationCache::_animation_changed));
+ }
}
void AnimationCache::_bind_methods() {
}
void AnimationCache::set_root(Node *p_root) {
-
_clear_cache();
root = p_root;
}
AnimationCache::AnimationCache() {
-
root = nullptr;
cache_dirty = true;
cache_valid = false;
diff --git a/scene/animation/animation_cache.h b/scene/animation/animation_cache.h
index 23312ca7ec..feff1d364a 100644
--- a/scene/animation/animation_cache.h
+++ b/scene/animation/animation_cache.h
@@ -35,11 +35,9 @@
#include "scene/resources/animation.h"
class AnimationCache : public Object {
-
GDCLASS(AnimationCache, Object);
struct Path {
-
RES resource;
Object *object;
Skeleton3D *skeleton; // haxor
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 9f5e06c43d..17ce05f130 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -33,12 +33,10 @@
/////////////////////////////////////////////////
void AnimationNodeStateMachineTransition::set_switch_mode(SwitchMode p_mode) {
-
switch_mode = p_mode;
}
AnimationNodeStateMachineTransition::SwitchMode AnimationNodeStateMachineTransition::get_switch_mode() const {
-
return switch_mode;
}
@@ -71,7 +69,6 @@ StringName AnimationNodeStateMachineTransition::get_advance_condition_name() con
}
void AnimationNodeStateMachineTransition::set_xfade_time(float p_xfade) {
-
ERR_FAIL_COND(p_xfade < 0);
xfade = p_xfade;
emit_changed();
@@ -133,7 +130,6 @@ void AnimationNodeStateMachineTransition::_bind_methods() {
}
AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() {
-
switch_mode = SWITCH_MODE_IMMEDIATE;
auto_advance = false;
xfade = 0;
@@ -144,7 +140,6 @@ AnimationNodeStateMachineTransition::AnimationNodeStateMachineTransition() {
////////////////////////////////////////////////////////
void AnimationNodeStateMachinePlayback::travel(const StringName &p_state) {
-
start_request_travel = true;
start_request = p_state;
stop_request = false;
@@ -155,39 +150,45 @@ void AnimationNodeStateMachinePlayback::start(const StringName &p_state) {
start_request = p_state;
stop_request = false;
}
-void AnimationNodeStateMachinePlayback::stop() {
+void AnimationNodeStateMachinePlayback::stop() {
stop_request = true;
}
+
bool AnimationNodeStateMachinePlayback::is_playing() const {
return playing;
}
+
StringName AnimationNodeStateMachinePlayback::get_current_node() const {
return current;
}
+
StringName AnimationNodeStateMachinePlayback::get_blend_from_node() const {
return fading_from;
}
+
Vector<StringName> AnimationNodeStateMachinePlayback::get_travel_path() const {
return path;
}
+
float AnimationNodeStateMachinePlayback::get_current_play_pos() const {
return pos_current;
}
+
float AnimationNodeStateMachinePlayback::get_current_length() const {
return len_current;
}
bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_state_machine, const StringName &p_travel) {
-
ERR_FAIL_COND_V(!playing, false);
ERR_FAIL_COND_V(!p_state_machine->states.has(p_travel), false);
ERR_FAIL_COND_V(!p_state_machine->states.has(current), false);
path.clear(); //a new one will be needed
- if (current == p_travel)
+ if (current == p_travel) {
return true; //nothing to do
+ }
loops_current = 0; // reset loops, so fade does not happen immediately
@@ -219,7 +220,6 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta
//begin astar
bool found_route = false;
while (!found_route) {
-
if (open_list.size() == 0) {
return false; //no path found
}
@@ -229,7 +229,6 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta
float least_cost = 1e20;
for (List<int>::Element *E = open_list.front(); E; E = E->next()) {
-
float cost = cost_map[p_state_machine->transitions[E->get()].to].distance;
cost += p_state_machine->states[p_state_machine->transitions[E->get()].to].position.distance_to(target_pos);
@@ -293,7 +292,6 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta
}
float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_state_machine, float p_time, bool p_seek) {
-
//if not playing and it can restart, then restart
if (!playing && start_request == StringName()) {
if (!stop_request && p_state_machine->start_node) {
@@ -347,7 +345,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
bool do_start = (p_seek && p_time == 0) || play_start || current == StringName();
if (do_start) {
-
if (p_state_machine->start_node != StringName() && p_seek && p_time == 0) {
current = p_state_machine->start_node;
}
@@ -365,7 +362,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
float fade_blend = 1.0;
if (fading_from != StringName()) {
-
if (!p_state_machine->states.has(fading_from)) {
fading_from = StringName();
} else {
@@ -382,7 +378,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
float rem = p_state_machine->blend_node(current, p_state_machine->states[current].node, p_time, p_seek, fade_blend, AnimationNode::FILTER_IGNORE, false);
if (fading_from != StringName()) {
-
p_state_machine->blend_node(fading_from, p_state_machine->states[fading_from].node, p_time, p_seek, 1.0 - fade_blend, AnimationNode::FILTER_IGNORE, false);
}
@@ -407,7 +402,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
AnimationNodeStateMachineTransition::SwitchMode switch_mode = AnimationNodeStateMachineTransition::SWITCH_MODE_IMMEDIATE;
if (path.size()) {
-
for (int i = 0; i < p_state_machine->transitions.size(); i++) {
if (p_state_machine->transitions[i].from == current && p_state_machine->transitions[i].to == path[0]) {
next_xfade = p_state_machine->transitions[i].transition->get_xfade_time();
@@ -419,7 +413,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
float priority_best = 1e20;
int auto_advance_to = -1;
for (int i = 0; i < p_state_machine->transitions.size(); i++) {
-
bool auto_advance = false;
if (p_state_machine->transitions[i].transition->has_auto_advance()) {
auto_advance = true;
@@ -430,7 +423,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
}
if (p_state_machine->transitions[i].from == current && auto_advance) {
-
if (p_state_machine->transitions[i].transition->get_priority() <= priority_best) {
priority_best = p_state_machine->transitions[i].transition->get_priority();
auto_advance_to = i;
@@ -447,7 +439,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
//if next, see when to transition
if (next != StringName()) {
-
bool goto_next = false;
if (switch_mode == AnimationNodeStateMachineTransition::SWITCH_MODE_AT_END) {
@@ -492,7 +483,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
//compute time left for transitions by using the end node
if (p_state_machine->end_node != StringName() && p_state_machine->end_node != current) {
-
rem = p_state_machine->blend_node(p_state_machine->end_node, p_state_machine->states[p_state_machine->end_node].node, 0, true, 0, AnimationNode::FILTER_IGNORE, false);
}
@@ -500,7 +490,6 @@ float AnimationNodeStateMachinePlayback::process(AnimationNodeStateMachine *p_st
}
void AnimationNodeStateMachinePlayback::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("travel", "to_node"), &AnimationNodeStateMachinePlayback::travel);
ClassDB::bind_method(D_METHOD("start", "node"), &AnimationNodeStateMachinePlayback::start);
ClassDB::bind_method(D_METHOD("stop"), &AnimationNodeStateMachinePlayback::stop);
@@ -542,7 +531,6 @@ void AnimationNodeStateMachine::get_parameter_list(List<PropertyInfo> *r_list) c
}
Variant AnimationNodeStateMachine::get_parameter_default_value(const StringName &p_parameter) const {
-
if (p_parameter == playback) {
Ref<AnimationNodeStateMachinePlayback> p;
p.instance();
@@ -553,7 +541,6 @@ Variant AnimationNodeStateMachine::get_parameter_default_value(const StringName
}
void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<AnimationNode> p_node, const Vector2 &p_position) {
-
ERR_FAIL_COND(states.has(p_name));
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(String(p_name).find("/") != -1);
@@ -571,7 +558,6 @@ void AnimationNodeStateMachine::add_node(const StringName &p_name, Ref<Animation
}
void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<AnimationNode> p_node) {
-
ERR_FAIL_COND(states.has(p_name) == false);
ERR_FAIL_COND(p_node.is_null());
ERR_FAIL_COND(String(p_name).find("/") != -1);
@@ -592,7 +578,6 @@ void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<Anima
}
Ref<AnimationNode> AnimationNodeStateMachine::get_node(const StringName &p_name) const {
-
ERR_FAIL_COND_V(!states.has(p_name), Ref<AnimationNode>());
return states[p_name].node;
@@ -628,8 +613,8 @@ void AnimationNodeStateMachine::get_child_nodes(List<ChildNode> *r_child_nodes)
bool AnimationNodeStateMachine::has_node(const StringName &p_name) const {
return states.has(p_name);
}
-void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
+void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
ERR_FAIL_COND(!states.has(p_name));
{
@@ -668,7 +653,6 @@ void AnimationNodeStateMachine::remove_node(const StringName &p_name) {
}
void AnimationNodeStateMachine::rename_node(const StringName &p_name, const StringName &p_new_name) {
-
ERR_FAIL_COND(!states.has(p_name));
ERR_FAIL_COND(states.has(p_new_name));
@@ -702,7 +686,6 @@ void AnimationNodeStateMachine::rename_node(const StringName &p_name, const Stri
}
void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const {
-
List<StringName> nodes;
for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
nodes.push_back(E->key());
@@ -715,25 +698,24 @@ void AnimationNodeStateMachine::get_node_list(List<StringName> *r_nodes) const {
}
bool AnimationNodeStateMachine::has_transition(const StringName &p_from, const StringName &p_to) const {
-
for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == p_from && transitions[i].to == p_to)
+ if (transitions[i].from == p_from && transitions[i].to == p_to) {
return true;
+ }
}
return false;
}
int AnimationNodeStateMachine::find_transition(const StringName &p_from, const StringName &p_to) const {
-
for (int i = 0; i < transitions.size(); i++) {
- if (transitions[i].from == p_from && transitions[i].to == p_to)
+ if (transitions[i].from == p_from && transitions[i].to == p_to) {
return i;
+ }
}
return -1;
}
void AnimationNodeStateMachine::add_transition(const StringName &p_from, const StringName &p_to, const Ref<AnimationNodeStateMachineTransition> &p_transition) {
-
ERR_FAIL_COND(p_from == p_to);
ERR_FAIL_COND(!states.has(p_from));
ERR_FAIL_COND(!states.has(p_to));
@@ -757,23 +739,22 @@ Ref<AnimationNodeStateMachineTransition> AnimationNodeStateMachine::get_transiti
ERR_FAIL_INDEX_V(p_transition, transitions.size(), Ref<AnimationNodeStateMachineTransition>());
return transitions[p_transition].transition;
}
-StringName AnimationNodeStateMachine::get_transition_from(int p_transition) const {
+StringName AnimationNodeStateMachine::get_transition_from(int p_transition) const {
ERR_FAIL_INDEX_V(p_transition, transitions.size(), StringName());
return transitions[p_transition].from;
}
-StringName AnimationNodeStateMachine::get_transition_to(int p_transition) const {
+StringName AnimationNodeStateMachine::get_transition_to(int p_transition) const {
ERR_FAIL_INDEX_V(p_transition, transitions.size(), StringName());
return transitions[p_transition].to;
}
int AnimationNodeStateMachine::get_transition_count() const {
-
return transitions.size();
}
-void AnimationNodeStateMachine::remove_transition(const StringName &p_from, const StringName &p_to) {
+void AnimationNodeStateMachine::remove_transition(const StringName &p_from, const StringName &p_to) {
for (int i = 0; i < transitions.size(); i++) {
if (transitions[i].from == p_from && transitions[i].to == p_to) {
transitions.write[i].transition->disconnect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed));
@@ -788,7 +769,6 @@ void AnimationNodeStateMachine::remove_transition(const StringName &p_from, cons
}
void AnimationNodeStateMachine::remove_transition_by_index(int p_transition) {
-
ERR_FAIL_INDEX(p_transition, transitions.size());
transitions.write[p_transition].transition->disconnect("advance_condition_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed));
transitions.remove(p_transition);
@@ -798,24 +778,20 @@ void AnimationNodeStateMachine::remove_transition_by_index(int p_transition) {
}
void AnimationNodeStateMachine::set_start_node(const StringName &p_node) {
-
ERR_FAIL_COND(p_node != StringName() && !states.has(p_node));
start_node = p_node;
}
String AnimationNodeStateMachine::get_start_node() const {
-
return start_node;
}
void AnimationNodeStateMachine::set_end_node(const StringName &p_node) {
-
ERR_FAIL_COND(p_node != StringName() && !states.has(p_node));
end_node = p_node;
}
String AnimationNodeStateMachine::get_end_node() const {
-
return end_node;
}
@@ -828,7 +804,6 @@ Vector2 AnimationNodeStateMachine::get_graph_offset() const {
}
float AnimationNodeStateMachine::process(float p_time, bool p_seek) {
-
Ref<AnimationNodeStateMachinePlayback> playback = get_parameter(this->playback);
ERR_FAIL_COND_V(playback.is_null(), 0.0);
@@ -847,7 +822,6 @@ Ref<AnimationNode> AnimationNodeStateMachine::get_child_by_name(const StringName
}
bool AnimationNodeStateMachine::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name.begins_with("states/")) {
String node_name = name.get_slicec('/', 1);
@@ -862,14 +836,12 @@ bool AnimationNodeStateMachine::_set(const StringName &p_name, const Variant &p_
}
if (what == "position") {
-
if (states.has(node_name)) {
states[node_name].position = p_value;
}
return true;
}
} else if (name == "transitions") {
-
Array trans = p_value;
ERR_FAIL_COND_V(trans.size() % 3 != 0, false);
@@ -892,7 +864,6 @@ bool AnimationNodeStateMachine::_set(const StringName &p_name, const Variant &p_
}
bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name.begins_with("states/")) {
String node_name = name.get_slicec('/', 1);
@@ -906,7 +877,6 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c
}
if (what == "position") {
-
if (states.has(node_name)) {
r_ret = states[node_name].position;
return true;
@@ -937,8 +907,8 @@ bool AnimationNodeStateMachine::_get(const StringName &p_name, Variant &r_ret) c
return false;
}
-void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) const {
+void AnimationNodeStateMachine::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
for (Map<StringName, State>::Element *E = states.front(); E; E = E->next()) {
names.push_back(E->key());
@@ -963,7 +933,6 @@ void AnimationNodeStateMachine::set_node_position(const StringName &p_name, cons
}
Vector2 AnimationNodeStateMachine::get_node_position(const StringName &p_name) const {
-
ERR_FAIL_COND_V(!states.has(p_name), Vector2());
return states[p_name].position;
}
@@ -973,7 +942,6 @@ void AnimationNodeStateMachine::_tree_changed() {
}
void AnimationNodeStateMachine::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_node", "name", "node", "position"), &AnimationNodeStateMachine::add_node, DEFVAL(Vector2()));
ClassDB::bind_method(D_METHOD("replace_node", "name", "node"), &AnimationNodeStateMachine::replace_node);
ClassDB::bind_method(D_METHOD("get_node", "name"), &AnimationNodeStateMachine::get_node);
@@ -1005,6 +973,5 @@ void AnimationNodeStateMachine::_bind_methods() {
}
AnimationNodeStateMachine::AnimationNodeStateMachine() {
-
playback = "playback";
}
diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h
index 27a4451f08..72fa6f77d0 100644
--- a/scene/animation/animation_node_state_machine.h
+++ b/scene/animation/animation_node_state_machine.h
@@ -134,7 +134,6 @@ public:
};
class AnimationNodeStateMachine : public AnimationRootNode {
-
GDCLASS(AnimationNodeStateMachine, AnimationRootNode);
private:
@@ -148,7 +147,6 @@ private:
Map<StringName, State> states;
struct Transition {
-
StringName from;
StringName to;
Ref<AnimationNodeStateMachineTransition> transition;
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index b657833a3b..4e56f1acf0 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -40,7 +40,6 @@
#include "scene/2d/skeleton_2d.h"
void AnimatedValuesBackup::update_skeletons() {
-
for (int i = 0; i < entries.size(); i++) {
if (entries[i].bone_idx != -1) {
// 3D bone
@@ -57,7 +56,6 @@ void AnimatedValuesBackup::update_skeletons() {
#endif
bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name.begins_with("playback/play")) { // bw compatibility
@@ -65,23 +63,19 @@ bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
set_current_animation(p_value);
} else if (name.begins_with("anims/")) {
-
String which = name.get_slicec('/', 1);
add_animation(which, p_value);
} else if (name.begins_with("next/")) {
-
String which = name.get_slicec('/', 1);
animation_set_next(which, p_value);
} else if (p_name == SceneStringNames::get_singleton()->blend_times) {
-
Array array = p_value;
int len = array.size();
ERR_FAIL_COND_V(len % 3, false);
for (int i = 0; i < len / 3; i++) {
-
StringName from = array[i * 3 + 0];
StringName to = array[i * 3 + 1];
float time = array[i * 3 + 2];
@@ -89,14 +83,14 @@ bool AnimationPlayer::_set(const StringName &p_name, const Variant &p_value) {
set_blend_time(from, to, time);
}
- } else
+ } else {
return false;
+ }
return true;
}
bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name == "playback/play") { // bw compatibility
@@ -104,41 +98,36 @@ bool AnimationPlayer::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = get_current_animation();
} else if (name.begins_with("anims/")) {
-
String which = name.get_slicec('/', 1);
r_ret = get_animation(which);
} else if (name.begins_with("next/")) {
-
String which = name.get_slicec('/', 1);
r_ret = animation_get_next(which);
} else if (name == "blend_times") {
-
Vector<BlendKey> keys;
for (Map<BlendKey, float>::Element *E = blend_times.front(); E; E = E->next()) {
-
keys.ordered_insert(E->key());
}
Array array;
for (int i = 0; i < keys.size(); i++) {
-
array.push_back(keys[i].from);
array.push_back(keys[i].to);
array.push_back(blend_times[keys[i]]);
}
r_ret = array;
- } else
+ } else {
return false;
+ }
return true;
}
void AnimationPlayer::_validate_property(PropertyInfo &property) const {
-
if (property.name == "current_animation") {
List<String> names;
@@ -149,9 +138,9 @@ void AnimationPlayer::_validate_property(PropertyInfo &property) const {
names.push_front("[stop]");
String hint;
for (List<String>::Element *E = names.front(); E; E = E->next()) {
-
- if (E != names.front())
+ if (E != names.front()) {
hint += ",";
+ }
hint += E->get();
}
@@ -160,14 +149,13 @@ void AnimationPlayer::_validate_property(PropertyInfo &property) const {
}
void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const {
-
List<PropertyInfo> anim_names;
for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
-
anim_names.push_back(PropertyInfo(Variant::OBJECT, "anims/" + String(E->key()), PROPERTY_HINT_RESOURCE_TYPE, "Animation", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
- if (E->get().next != StringName())
+ if (E->get().next != StringName()) {
anim_names.push_back(PropertyInfo(Variant::STRING, "next/" + String(E->key()), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+ }
}
anim_names.sort();
@@ -180,16 +168,12 @@ void AnimationPlayer::_get_property_list(List<PropertyInfo> *p_list) const {
}
void AnimationPlayer::advance(float p_time) {
-
_animation_process(p_time);
}
void AnimationPlayer::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
if (!processing) {
//make sure that a previous process state was not saved
//only process if "processing" is set
@@ -200,39 +184,40 @@ void AnimationPlayer::_notification(int p_what) {
clear_caches();
} break;
case NOTIFICATION_READY: {
-
if (!Engine::get_singleton()->is_editor_hint() && animation_set.has(autoplay)) {
play(autoplay);
_animation_process(0);
}
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
- if (animation_process_mode == ANIMATION_PROCESS_PHYSICS)
+ if (animation_process_mode == ANIMATION_PROCESS_PHYSICS) {
break;
+ }
- if (processing)
+ if (processing) {
_animation_process(get_process_delta_time());
+ }
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
-
- if (animation_process_mode == ANIMATION_PROCESS_IDLE)
+ if (animation_process_mode == ANIMATION_PROCESS_IDLE) {
break;
+ }
- if (processing)
+ if (processing) {
_animation_process(get_physics_process_delta_time());
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
-
clear_caches();
} break;
}
}
void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
-
// Already cached?
- if (p_anim->node_cache.size() == p_anim->animation->get_track_count())
+ if (p_anim->node_cache.size() == p_anim->animation->get_track_count()) {
return;
+ }
Node *parent = get_node(root);
@@ -243,7 +228,6 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
p_anim->node_cache.resize(a->get_track_count());
for (int i = 0; i < a->get_track_count(); i++) {
-
p_anim->node_cache.write[i] = nullptr;
RES resource;
Vector<StringName> leftover_path;
@@ -253,26 +237,26 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
int bone_idx = -1;
if (a->track_get_path(i).get_subname_count() == 1 && Object::cast_to<Skeleton3D>(child)) {
-
Skeleton3D *sk = Object::cast_to<Skeleton3D>(child);
bone_idx = sk->find_bone(a->track_get_path(i).get_subname(0));
if (bone_idx == -1) {
-
continue;
}
}
{
- if (!child->is_connected("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed)))
+ if (!child->is_connected("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed))) {
child->connect("tree_exiting", callable_mp(this, &AnimationPlayer::_node_removed), make_binds(child), CONNECT_ONESHOT);
+ }
}
TrackNodeCacheKey key;
key.id = id;
key.bone_idx = bone_idx;
- if (!node_cache_map.has(key))
+ if (!node_cache_map.has(key)) {
node_cache_map[key] = TrackNodeCache();
+ }
p_anim->node_cache.write[i] = &node_cache_map[key];
p_anim->node_cache[i]->path = a->track_get_path(i);
@@ -305,31 +289,27 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
}
if (a->track_get_type(i) == Animation::TYPE_VALUE) {
-
if (!p_anim->node_cache[i]->property_anim.has(a->track_get_path(i).get_concatenated_subnames())) {
-
TrackNodeCache::PropertyAnim pa;
pa.subpath = leftover_path;
pa.object = resource.is_valid() ? (Object *)resource.ptr() : (Object *)child;
pa.special = SP_NONE;
pa.owner = p_anim->node_cache[i];
if (false && p_anim->node_cache[i]->node_2d) {
-
- if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_pos)
+ if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_pos) {
pa.special = SP_NODE2D_POS;
- else if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_rot)
+ } else if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_rot) {
pa.special = SP_NODE2D_ROT;
- else if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_scale)
+ } else if (leftover_path.size() == 1 && leftover_path[0] == SceneStringNames::get_singleton()->transform_scale) {
pa.special = SP_NODE2D_SCALE;
+ }
}
p_anim->node_cache[i]->property_anim[a->track_get_path(i).get_concatenated_subnames()] = pa;
}
}
if (a->track_get_type(i) == Animation::TYPE_BEZIER && leftover_path.size()) {
-
if (!p_anim->node_cache[i]->bezier_anim.has(a->track_get_path(i).get_concatenated_subnames())) {
-
TrackNodeCache::BezierAnim ba;
ba.bezier_property = leftover_path;
ba.object = resource.is_valid() ? (Object *)resource.ptr() : (Object *)child;
@@ -342,7 +322,6 @@ void AnimationPlayer::_ensure_node_caches(AnimationData *p_anim) {
}
void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float p_time, float p_delta, float p_interp, bool p_is_current, bool p_seeked, bool p_started) {
-
_ensure_node_caches(p_anim);
ERR_FAIL_COND(p_anim->node_cache.size() != p_anim->animation->get_track_count());
@@ -350,7 +329,6 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint();
for (int i = 0; i < a->get_track_count(); i++) {
-
// If an animation changes this animation (or it animates itself)
// we need to recreate our animation cache
if (p_anim->node_cache.size() != a->get_track_count()) {
@@ -359,21 +337,23 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
TrackNodeCache *nc = p_anim->node_cache[i];
- if (!nc)
+ if (!nc) {
continue; // no node cache for this track, skip it
+ }
- if (!a->track_is_enabled(i))
+ if (!a->track_is_enabled(i)) {
continue; // do nothing if the track is disabled
+ }
- if (a->track_get_key_count(i) == 0)
+ if (a->track_get_key_count(i) == 0) {
continue; // do nothing if track is empty
+ }
switch (a->track_get_type(i)) {
-
case Animation::TYPE_TRANSFORM: {
-
- if (!nc->spatial)
+ if (!nc->spatial) {
continue;
+ }
Vector3 loc;
Quat rot;
@@ -382,8 +362,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
Error err = a->transform_track_interpolate(i, p_time, &loc, &rot, &scale);
//ERR_CONTINUE(err!=OK); //used for testing, should be removed
- if (err != OK)
+ if (err != OK) {
continue;
+ }
if (nc->accum_pass != accum_pass) {
ERR_CONTINUE(cache_update_size >= NODE_CACHE_UPDATE_MAX);
@@ -394,17 +375,16 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
nc->scale_accum = scale;
} else {
-
- nc->loc_accum = nc->loc_accum.linear_interpolate(loc, p_interp);
+ nc->loc_accum = nc->loc_accum.lerp(loc, p_interp);
nc->rot_accum = nc->rot_accum.slerp(rot, p_interp);
- nc->scale_accum = nc->scale_accum.linear_interpolate(scale, p_interp);
+ nc->scale_accum = nc->scale_accum.lerp(scale, p_interp);
}
} break;
case Animation::TYPE_VALUE: {
-
- if (!nc->node)
+ if (!nc->node) {
continue;
+ }
//StringName property=a->track_get_path(i).get_property();
@@ -416,14 +396,14 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
Animation::UpdateMode update_mode = a->value_track_get_update_mode(i);
if (update_mode == Animation::UPDATE_CAPTURE) {
-
if (p_started) {
pa->capture = pa->object->get_indexed(pa->subpath);
}
int key_count = a->track_get_key_count(i);
- if (key_count == 0)
+ if (key_count == 0) {
continue; //eeh not worth it
+ }
float first_key_time = a->track_get_key_time(i, 0);
float transition = 1.0;
@@ -431,8 +411,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
if (first_key_time == 0.0) {
//ignore, use for transition
- if (key_count == 1)
+ if (key_count == 1) {
continue; //with one key we can't do anything
+ }
transition = a->track_get_key_transition(i, 0);
first_key_time = a->track_get_key_time(i, 1);
first_key = 1;
@@ -461,8 +442,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
Variant value = a->value_track_interpolate(i, p_time);
- if (value == Variant())
+ if (value == Variant()) {
continue;
+ }
//thanks to trigger mode, this should be solved now..
/*
@@ -479,15 +461,12 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
}
} else if (p_is_current && p_delta != 0) {
-
List<int> indices;
a->value_track_get_key_indices(i, p_time, p_delta, &indices);
for (List<int>::Element *F = indices.front(); F; F = F->next()) {
-
Variant value = a->track_get_key_value(i, F->get());
switch (pa->special) {
-
case SP_NONE: {
bool valid;
pa->object->set_indexed(pa->subpath, value, &valid); //you are not speshul
@@ -530,21 +509,21 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
} break;
case Animation::TYPE_METHOD: {
-
- if (!nc->node)
+ if (!nc->node) {
continue;
+ }
if (p_delta == 0) {
continue;
}
- if (!p_is_current)
+ if (!p_is_current) {
break;
+ }
List<int> indices;
a->method_track_get_key_indices(i, p_time, p_delta, &indices);
for (List<int>::Element *E = indices.front(); E; E = E->next()) {
-
StringName method = a->method_track_get_name(i, E->get());
Vector<Variant> params = a->method_track_get_params(i, E->get());
@@ -581,9 +560,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
} break;
case Animation::TYPE_BEZIER: {
-
- if (!nc->node)
+ if (!nc->node) {
continue;
+ }
Map<StringName, TrackNodeCache::BezierAnim>::Element *E = nc->bezier_anim.find(a->track_get_path(i).get_concatenated_subnames());
ERR_CONTINUE(!E); //should it continue, or create a new one?
@@ -602,9 +581,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
} break;
case Animation::TYPE_AUDIO: {
-
- if (!nc->node)
+ if (!nc->node) {
continue;
+ }
if (p_delta == 0) {
continue;
}
@@ -612,8 +591,9 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
if (p_seeked) {
//find whathever should be playing
int idx = a->track_find_key(i, p_time);
- if (idx < 0)
+ if (idx < 0) {
continue;
+ }
Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
if (!stream.is_valid()) {
@@ -678,7 +658,6 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
nc->audio_start = p_time;
}
} else if (nc->audio_playing) {
-
bool loop = a->has_loop();
bool stop = false;
@@ -704,22 +683,24 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
} break;
case Animation::TYPE_ANIMATION: {
-
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(nc->node);
- if (!player)
+ if (!player) {
continue;
+ }
if (p_delta == 0 || p_seeked) {
//seek
int idx = a->track_find_key(i, p_time);
- if (idx < 0)
+ if (idx < 0) {
continue;
+ }
float pos = a->track_get_key_time(i, idx);
StringName anim_name = a->animation_track_get_key_animation(i, idx);
- if (String(anim_name) == "[stop]" || !player->has_animation(anim_name))
+ if (String(anim_name) == "[stop]" || !player->has_animation(anim_name)) {
continue;
+ }
Ref<Animation> anim = player->get_animation(anim_name);
@@ -749,7 +730,6 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
StringName anim_name = a->animation_track_get_key_animation(i, idx);
if (String(anim_name) == "[stop]" || !player->has_animation(anim_name)) {
-
if (playing_caches.has(nc)) {
playing_caches.erase(nc);
player->stop();
@@ -769,7 +749,6 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
}
void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, float p_blend, bool p_seeked, bool p_started) {
-
float delta = p_delta * speed_scale * cd.speed_scale;
float next_pos = cd.pos + delta;
@@ -777,17 +756,16 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f
bool loop = cd.from->animation->has_loop();
if (!loop) {
-
- if (next_pos < 0)
+ if (next_pos < 0) {
next_pos = 0;
- else if (next_pos > len)
+ } else if (next_pos > len) {
next_pos = len;
+ }
// fix delta
delta = next_pos - cd.pos;
if (&cd == &playback.current) {
-
bool backwards = delta < 0;
if (!backwards && cd.pos <= len && next_pos == len /*&& playback.blend.empty()*/) {
@@ -804,7 +782,6 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f
}
} else {
-
float looped_next_pos = Math::fposmod(next_pos, len);
if (looped_next_pos == 0 && next_pos != 0) {
// Loop multiples of the length to it, rather than 0
@@ -819,8 +796,8 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f
_animation_process_animation(cd.from, cd.pos, delta, p_blend, &cd == &playback.current, p_seeked, p_started);
}
-void AnimationPlayer::_animation_process2(float p_delta, bool p_started) {
+void AnimationPlayer::_animation_process2(float p_delta, bool p_started) {
Playback &c = playback;
accum_pass++;
@@ -832,7 +809,6 @@ void AnimationPlayer::_animation_process2(float p_delta, bool p_started) {
List<Blend>::Element *prev = nullptr;
for (List<Blend>::Element *E = c.blend.back(); E; E = prev) {
-
Blend &b = E->get();
float blend = b.blend_left / b.blend_time;
_animation_process_data(b.data, p_delta, blend, false, false);
@@ -841,7 +817,6 @@ void AnimationPlayer::_animation_process2(float p_delta, bool p_started) {
prev = E->prev();
if (b.blend_left < 0) {
-
c.blend.erase(E);
}
}
@@ -851,7 +826,6 @@ void AnimationPlayer::_animation_update_transforms() {
{
Transform t;
for (int i = 0; i < cache_update_size; i++) {
-
TrackNodeCache *nc = cache_update[i];
ERR_CONTINUE(nc->accum_pass != accum_pass);
@@ -859,11 +833,9 @@ void AnimationPlayer::_animation_update_transforms() {
t.origin = nc->loc_accum;
t.basis.set_quat_scale(nc->rot_accum, nc->scale_accum);
if (nc->skeleton && nc->bone_idx >= 0) {
-
nc->skeleton->set_bone_pose(nc->bone_idx, t);
} else if (nc->spatial) {
-
nc->spatial->set_transform(t);
}
}
@@ -872,13 +844,11 @@ void AnimationPlayer::_animation_update_transforms() {
cache_update_size = 0;
for (int i = 0; i < cache_update_prop_size; i++) {
-
TrackNodeCache::PropertyAnim *pa = cache_update_prop[i];
ERR_CONTINUE(pa->accum_pass != accum_pass);
switch (pa->special) {
-
case SP_NONE: {
bool valid;
pa->object->set_indexed(pa->subpath, pa->value_accum, &valid); //you are not speshul
@@ -921,7 +891,6 @@ void AnimationPlayer::_animation_update_transforms() {
cache_update_prop_size = 0;
for (int i = 0; i < cache_update_bezier_size; i++) {
-
TrackNodeCache::BezierAnim *ba = cache_update_bezier[i];
ERR_CONTINUE(ba->accum_pass != accum_pass);
@@ -932,9 +901,7 @@ void AnimationPlayer::_animation_update_transforms() {
}
void AnimationPlayer::_animation_process(float p_delta) {
-
if (playback.current.from) {
-
end_reached = false;
end_notify = false;
_animation_process2(p_delta, playback.started);
@@ -950,14 +917,16 @@ void AnimationPlayer::_animation_process(float p_delta) {
play(queued.front()->get());
String new_name = playback.assigned;
queued.pop_front();
- if (end_notify)
+ if (end_notify) {
emit_signal(SceneStringNames::get_singleton()->animation_changed, old, new_name);
+ }
} else {
//stop();
playing = false;
_set_process(false);
- if (end_notify)
+ if (end_notify) {
emit_signal(SceneStringNames::get_singleton()->animation_finished, playback.assigned);
+ }
}
end_reached = false;
}
@@ -968,7 +937,6 @@ void AnimationPlayer::_animation_process(float p_delta) {
}
Error AnimationPlayer::add_animation(const StringName &p_name, const Ref<Animation> &p_animation) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_V_MSG(String(p_name).find("/") != -1 || String(p_name).find(":") != -1 || String(p_name).find(",") != -1 || String(p_name).find("[") != -1, ERR_INVALID_PARAMETER, "Invalid animation name: " + String(p_name) + ".");
#endif
@@ -976,12 +944,10 @@ Error AnimationPlayer::add_animation(const StringName &p_name, const Ref<Animati
ERR_FAIL_COND_V(p_animation.is_null(), ERR_INVALID_PARAMETER);
if (animation_set.has(p_name)) {
-
_unref_anim(animation_set[p_name].animation);
animation_set[p_name].animation = p_animation;
clear_caches();
} else {
-
AnimationData ad;
ad.animation = p_animation;
ad.name = p_name;
@@ -994,7 +960,6 @@ Error AnimationPlayer::add_animation(const StringName &p_name, const Ref<Animati
}
void AnimationPlayer::remove_animation(const StringName &p_name) {
-
ERR_FAIL_COND(!animation_set.has(p_name));
stop();
@@ -1006,17 +971,14 @@ void AnimationPlayer::remove_animation(const StringName &p_name) {
}
void AnimationPlayer::_ref_anim(const Ref<Animation> &p_anim) {
-
Ref<Animation>(p_anim)->connect(SceneStringNames::get_singleton()->tracks_changed, callable_mp(this, &AnimationPlayer::_animation_changed), varray(), CONNECT_REFERENCE_COUNTED);
}
void AnimationPlayer::_unref_anim(const Ref<Animation> &p_anim) {
-
Ref<Animation>(p_anim)->disconnect(SceneStringNames::get_singleton()->tracks_changed, callable_mp(this, &AnimationPlayer::_animation_changed));
}
void AnimationPlayer::rename_animation(const StringName &p_name, const StringName &p_new_name) {
-
ERR_FAIL_COND(!animation_set.has(p_name));
ERR_FAIL_COND(String(p_new_name).find("/") != -1 || String(p_new_name).find(":") != -1);
ERR_FAIL_COND(animation_set.has(p_new_name));
@@ -1030,7 +992,6 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam
List<BlendKey> to_erase;
Map<BlendKey, float> to_insert;
for (Map<BlendKey, float>::Element *E = blend_times.front(); E; E = E->next()) {
-
BlendKey bk = E->key();
BlendKey new_bk = bk;
bool erase = false;
@@ -1050,7 +1011,6 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam
}
while (to_erase.size()) {
-
blend_times.erase(to_erase.front()->get());
to_erase.pop_front();
}
@@ -1060,73 +1020,71 @@ void AnimationPlayer::rename_animation(const StringName &p_name, const StringNam
to_insert.erase(to_insert.front());
}
- if (autoplay == p_name)
+ if (autoplay == p_name) {
autoplay = p_new_name;
+ }
clear_caches();
_change_notify();
}
bool AnimationPlayer::has_animation(const StringName &p_name) const {
-
return animation_set.has(p_name);
}
-Ref<Animation> AnimationPlayer::get_animation(const StringName &p_name) const {
+Ref<Animation> AnimationPlayer::get_animation(const StringName &p_name) const {
ERR_FAIL_COND_V(!animation_set.has(p_name), Ref<Animation>());
const AnimationData &data = animation_set[p_name];
return data.animation;
}
-void AnimationPlayer::get_animation_list(List<StringName> *p_animations) const {
+void AnimationPlayer::get_animation_list(List<StringName> *p_animations) const {
List<String> anims;
for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
-
anims.push_back(E->key());
}
anims.sort();
for (List<String>::Element *E = anims.front(); E; E = E->next()) {
-
p_animations->push_back(E->get());
}
}
void AnimationPlayer::set_blend_time(const StringName &p_animation1, const StringName &p_animation2, float p_time) {
-
ERR_FAIL_COND_MSG(p_time < 0, "Blend time cannot be smaller than 0.");
BlendKey bk;
bk.from = p_animation1;
bk.to = p_animation2;
- if (p_time == 0)
+ if (p_time == 0) {
blend_times.erase(bk);
- else
+ } else {
blend_times[bk] = p_time;
+ }
}
float AnimationPlayer::get_blend_time(const StringName &p_animation1, const StringName &p_animation2) const {
-
BlendKey bk;
bk.from = p_animation1;
bk.to = p_animation2;
- if (blend_times.has(bk))
+ if (blend_times.has(bk)) {
return blend_times[bk];
- else
+ } else {
return 0;
+ }
}
void AnimationPlayer::queue(const StringName &p_name) {
-
- if (!is_playing())
+ if (!is_playing()) {
play(p_name);
- else
+ } else {
queued.push_back(p_name);
+ }
}
Vector<String> AnimationPlayer::get_queue() {
@@ -1143,23 +1101,21 @@ void AnimationPlayer::clear_queue() {
}
void AnimationPlayer::play_backwards(const StringName &p_name, float p_custom_blend) {
-
play(p_name, p_custom_blend, -1, true);
}
void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float p_custom_scale, bool p_from_end) {
-
StringName name = p_name;
- if (String(name) == "")
+ if (String(name) == "") {
name = playback.assigned;
+ }
ERR_FAIL_COND_MSG(!animation_set.has(name), "Animation not found: " + name + ".");
Playback &c = playback;
if (c.current.from) {
-
float blend_time = 0;
// find if it can blend
BlendKey bk;
@@ -1169,30 +1125,25 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
if (p_custom_blend >= 0) {
blend_time = p_custom_blend;
} else if (blend_times.has(bk)) {
-
blend_time = blend_times[bk];
} else {
-
bk.from = "*";
if (blend_times.has(bk)) {
-
blend_time = blend_times[bk];
} else {
-
bk.from = c.current.from->name;
bk.to = "*";
if (blend_times.has(bk)) {
-
blend_time = blend_times[bk];
}
}
}
- if (p_custom_blend < 0 && blend_time == 0 && default_blend_time)
+ if (p_custom_blend < 0 && blend_time == 0 && default_blend_time) {
blend_time = default_blend_time;
+ }
if (blend_time > 0) {
-
Blend b;
b.data = c.current;
b.blend_time = b.blend_left = blend_time;
@@ -1223,15 +1174,17 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
c.seeked = false;
c.started = true;
- if (!end_reached)
+ if (!end_reached) {
queued.clear();
+ }
_set_process(true); // always process when starting an animation
playing = true;
emit_signal(SceneStringNames::get_singleton()->animation_started, c.assigned);
- if (is_inside_tree() && Engine::get_singleton()->is_editor_hint())
+ if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
return; // no next in this case
+ }
StringName next = animation_get_next(p_name);
if (next != StringName() && animation_set.has(next)) {
@@ -1240,12 +1193,10 @@ void AnimationPlayer::play(const StringName &p_name, float p_custom_blend, float
}
bool AnimationPlayer::is_playing() const {
-
return playing;
}
void AnimationPlayer::set_current_animation(const String &p_anim) {
-
if (p_anim == "[stop]" || p_anim == "") {
stop();
} else if (!is_playing() || playback.assigned != p_anim) {
@@ -1256,12 +1207,10 @@ void AnimationPlayer::set_current_animation(const String &p_anim) {
}
String AnimationPlayer::get_current_animation() const {
-
return (is_playing() ? playback.assigned : "");
}
void AnimationPlayer::set_assigned_animation(const String &p_anim) {
-
if (is_playing()) {
play(p_anim);
} else {
@@ -1273,12 +1222,10 @@ void AnimationPlayer::set_assigned_animation(const String &p_anim) {
}
String AnimationPlayer::get_assigned_animation() const {
-
return playback.assigned;
}
void AnimationPlayer::stop(bool p_reset) {
-
_stop_playing_caches();
Playback &c = playback;
c.blend.clear();
@@ -1293,15 +1240,14 @@ void AnimationPlayer::stop(bool p_reset) {
}
void AnimationPlayer::set_speed_scale(float p_speed) {
-
speed_scale = p_speed;
}
-float AnimationPlayer::get_speed_scale() const {
+float AnimationPlayer::get_speed_scale() const {
return speed_scale;
}
-float AnimationPlayer::get_playing_speed() const {
+float AnimationPlayer::get_playing_speed() const {
if (!playing) {
return 0;
}
@@ -1309,7 +1255,6 @@ float AnimationPlayer::get_playing_speed() const {
}
void AnimationPlayer::seek(float p_time, bool p_update) {
-
if (!playback.current.from) {
if (playback.assigned) {
ERR_FAIL_COND(!animation_set.has(playback.assigned));
@@ -1326,7 +1271,6 @@ void AnimationPlayer::seek(float p_time, bool p_update) {
}
void AnimationPlayer::seek_delta(float p_time, float p_delta) {
-
if (!playback.current.from) {
if (playback.assigned) {
ERR_FAIL_COND(!animation_set.has(playback.assigned));
@@ -1336,31 +1280,28 @@ void AnimationPlayer::seek_delta(float p_time, float p_delta) {
}
playback.current.pos = p_time - p_delta;
- if (speed_scale != 0.0)
+ if (speed_scale != 0.0) {
p_delta /= speed_scale;
+ }
_animation_process(p_delta);
//playback.current.pos=p_time;
}
bool AnimationPlayer::is_valid() const {
-
return (playback.current.from);
}
float AnimationPlayer::get_current_animation_position() const {
-
ERR_FAIL_COND_V(!playback.current.from, 0);
return playback.current.pos;
}
float AnimationPlayer::get_current_animation_length() const {
-
ERR_FAIL_COND_V(!playback.current.from, 0);
return playback.current.from->animation->get_length();
}
void AnimationPlayer::_animation_changed() {
-
clear_caches();
emit_signal("caches_cleared");
if (is_playing()) {
@@ -1369,16 +1310,15 @@ void AnimationPlayer::_animation_changed() {
}
void AnimationPlayer::_stop_playing_caches() {
-
for (Set<TrackNodeCache *>::Element *E = playing_caches.front(); E; E = E->next()) {
-
if (E->get()->node && E->get()->audio_playing) {
E->get()->node->call("stop");
}
if (E->get()->node && E->get()->animation_playing) {
AnimationPlayer *player = Object::cast_to<AnimationPlayer>(E->get()->node);
- if (!player)
+ if (!player) {
continue;
+ }
player->stop();
}
}
@@ -1387,18 +1327,15 @@ void AnimationPlayer::_stop_playing_caches() {
}
void AnimationPlayer::_node_removed(Node *p_node) {
-
clear_caches(); // nodes contained here ar being removed, clear the caches
}
void AnimationPlayer::clear_caches() {
-
_stop_playing_caches();
node_cache_map.clear();
for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
-
E->get().node_cache.clear();
}
@@ -1408,121 +1345,116 @@ void AnimationPlayer::clear_caches() {
}
void AnimationPlayer::set_active(bool p_active) {
-
- if (active == p_active)
+ if (active == p_active) {
return;
+ }
active = p_active;
_set_process(processing, true);
}
bool AnimationPlayer::is_active() const {
-
return active;
}
StringName AnimationPlayer::find_animation(const Ref<Animation> &p_animation) const {
-
for (Map<StringName, AnimationData>::Element *E = animation_set.front(); E; E = E->next()) {
-
- if (E->get().animation == p_animation)
+ if (E->get().animation == p_animation) {
return E->key();
+ }
}
return "";
}
void AnimationPlayer::set_autoplay(const String &p_name) {
- if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint())
+ if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) {
WARN_PRINT("Setting autoplay after the node has been added to the scene has no effect.");
+ }
autoplay = p_name;
}
String AnimationPlayer::get_autoplay() const {
-
return autoplay;
}
void AnimationPlayer::set_animation_process_mode(AnimationProcessMode p_mode) {
-
- if (animation_process_mode == p_mode)
+ if (animation_process_mode == p_mode) {
return;
+ }
bool pr = processing;
- if (pr)
+ if (pr) {
_set_process(false);
+ }
animation_process_mode = p_mode;
- if (pr)
+ if (pr) {
_set_process(true);
+ }
}
AnimationPlayer::AnimationProcessMode AnimationPlayer::get_animation_process_mode() const {
-
return animation_process_mode;
}
void AnimationPlayer::set_method_call_mode(AnimationMethodCallMode p_mode) {
-
method_call_mode = p_mode;
}
AnimationPlayer::AnimationMethodCallMode AnimationPlayer::get_method_call_mode() const {
-
return method_call_mode;
}
void AnimationPlayer::_set_process(bool p_process, bool p_force) {
-
- if (processing == p_process && !p_force)
+ if (processing == p_process && !p_force) {
return;
+ }
switch (animation_process_mode) {
-
- case ANIMATION_PROCESS_PHYSICS: set_physics_process_internal(p_process && active); break;
- case ANIMATION_PROCESS_IDLE: set_process_internal(p_process && active); break;
- case ANIMATION_PROCESS_MANUAL: break;
+ case ANIMATION_PROCESS_PHYSICS:
+ set_physics_process_internal(p_process && active);
+ break;
+ case ANIMATION_PROCESS_IDLE:
+ set_process_internal(p_process && active);
+ break;
+ case ANIMATION_PROCESS_MANUAL:
+ break;
}
processing = p_process;
}
void AnimationPlayer::animation_set_next(const StringName &p_animation, const StringName &p_next) {
-
ERR_FAIL_COND(!animation_set.has(p_animation));
animation_set[p_animation].next = p_next;
}
StringName AnimationPlayer::animation_get_next(const StringName &p_animation) const {
-
- if (!animation_set.has(p_animation))
+ if (!animation_set.has(p_animation)) {
return StringName();
+ }
return animation_set[p_animation].next;
}
void AnimationPlayer::set_default_blend_time(float p_default) {
-
default_blend_time = p_default;
}
float AnimationPlayer::get_default_blend_time() const {
-
return default_blend_time;
}
void AnimationPlayer::set_root(const NodePath &p_root) {
-
root = p_root;
clear_caches();
}
NodePath AnimationPlayer::get_root() const {
-
return root;
}
void AnimationPlayer::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-
#ifdef TOOLS_ENABLED
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\"";
#else
@@ -1534,7 +1466,6 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i
List<StringName> al;
get_animation_list(&al);
for (List<StringName>::Element *E = al.front(); E; E = E->next()) {
-
r_options->push_back(quote_style + String(E->get()) + quote_style);
}
}
@@ -1543,9 +1474,9 @@ void AnimationPlayer::get_argument_options(const StringName &p_function, int p_i
#ifdef TOOLS_ENABLED
AnimatedValuesBackup AnimationPlayer::backup_animated_values() {
-
- if (!playback.current.from)
+ if (!playback.current.from) {
return AnimatedValuesBackup();
+ }
_ensure_node_caches(playback.current.from);
@@ -1553,12 +1484,14 @@ AnimatedValuesBackup AnimationPlayer::backup_animated_values() {
for (int i = 0; i < playback.current.from->node_cache.size(); i++) {
TrackNodeCache *nc = playback.current.from->node_cache[i];
- if (!nc)
+ if (!nc) {
continue;
+ }
if (nc->skeleton) {
- if (nc->bone_idx == -1)
+ if (nc->bone_idx == -1) {
continue;
+ }
AnimatedValuesBackup::Entry entry;
entry.object = nc->skeleton;
@@ -1581,8 +1514,9 @@ AnimatedValuesBackup AnimationPlayer::backup_animated_values() {
bool valid;
entry.value = E->value().object->get_indexed(E->value().subpath, &valid);
entry.bone_idx = -1;
- if (valid)
+ if (valid) {
backup.entries.push_back(entry);
+ }
}
}
}
@@ -1592,9 +1526,7 @@ AnimatedValuesBackup AnimationPlayer::backup_animated_values() {
}
void AnimationPlayer::restore_animated_values(const AnimatedValuesBackup &p_backup) {
-
for (int i = 0; i < p_backup.entries.size(); i++) {
-
const AnimatedValuesBackup::Entry *entry = &p_backup.entries[i];
if (entry->bone_idx == -1) {
entry->object->set_indexed(entry->subpath, entry->value);
@@ -1692,7 +1624,6 @@ void AnimationPlayer::_bind_methods() {
}
AnimationPlayer::AnimationPlayer() {
-
accum_pass = 1;
cache_update_size = 0;
cache_update_prop_size = 0;
diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h
index c134aff707..1a66665803 100644
--- a/scene/animation/animation_player.h
+++ b/scene/animation/animation_player.h
@@ -85,89 +85,66 @@ private:
};
struct TrackNodeCache {
-
NodePath path;
- uint32_t id;
+ uint32_t id = 0;
RES resource;
- Node *node;
- Node3D *spatial;
- Node2D *node_2d;
- Skeleton3D *skeleton;
- int bone_idx;
+ Node *node = nullptr;
+ Node3D *spatial = nullptr;
+ Node2D *node_2d = nullptr;
+ Skeleton3D *skeleton = nullptr;
+ int bone_idx = -1;
// accumulated transforms
Vector3 loc_accum;
Quat rot_accum;
Vector3 scale_accum;
- uint64_t accum_pass;
+ uint64_t accum_pass = 0;
- bool audio_playing;
- float audio_start;
- float audio_len;
+ bool audio_playing = false;
+ float audio_start = 0.0;
+ float audio_len = 0.0;
- bool animation_playing;
+ bool animation_playing = false;
struct PropertyAnim {
-
- TrackNodeCache *owner;
- SpecialProperty special; //small optimization
+ TrackNodeCache *owner = nullptr;
+ SpecialProperty special = SP_NONE; //small optimization
Vector<StringName> subpath;
- Object *object;
+ Object *object = nullptr;
Variant value_accum;
- uint64_t accum_pass;
+ uint64_t accum_pass = 0;
Variant capture;
- PropertyAnim() :
- owner(nullptr),
- special(SP_NONE),
- object(nullptr),
- accum_pass(0) {}
+ PropertyAnim() {}
};
Map<StringName, PropertyAnim> property_anim;
struct BezierAnim {
-
Vector<StringName> bezier_property;
- TrackNodeCache *owner;
- float bezier_accum;
- Object *object;
- uint64_t accum_pass;
-
- BezierAnim() :
- owner(nullptr),
- bezier_accum(0.0),
- object(nullptr),
- accum_pass(0) {}
+ TrackNodeCache *owner = nullptr;
+ float bezier_accum = 0.0;
+ Object *object = nullptr;
+ uint64_t accum_pass = 0;
+
+ BezierAnim() {}
};
Map<StringName, BezierAnim> bezier_anim;
- TrackNodeCache() :
- id(0),
- node(nullptr),
- spatial(nullptr),
- node_2d(nullptr),
- skeleton(nullptr),
- bone_idx(-1),
- accum_pass(0),
- audio_playing(false),
- audio_start(0.0),
- audio_len(0.0),
- animation_playing(false) {}
+ TrackNodeCache() {}
};
struct TrackNodeCacheKey {
-
ObjectID id;
int bone_idx;
inline bool operator<(const TrackNodeCacheKey &p_right) const {
-
- if (id == p_right.id)
+ if (id == p_right.id) {
return bone_idx < p_right.bone_idx;
- else
+ } else {
return id < p_right.id;
+ }
}
};
@@ -194,7 +171,6 @@ private:
Map<StringName, AnimationData> animation_set;
struct BlendKey {
-
StringName from;
StringName to;
bool operator<(const BlendKey &bk) const { return from == bk.from ? String(to) < String(bk.to) : String(from) < String(bk.from); }
@@ -203,13 +179,11 @@ private:
Map<BlendKey, float> blend_times;
struct PlaybackData {
-
AnimationData *from;
float pos;
float speed_scale;
PlaybackData() {
-
pos = 0;
speed_scale = 1.0;
from = nullptr;
@@ -217,21 +191,18 @@ private:
};
struct Blend {
-
PlaybackData data;
float blend_time;
float blend_left;
Blend() {
-
blend_left = 0;
blend_time = 0;
}
};
struct Playback {
-
List<Blend> blend;
PlaybackData current;
StringName assigned;
@@ -265,12 +236,10 @@ private:
// bind helpers
Vector<String> _get_animation_list() const {
-
List<StringName> animations;
get_animation_list(&animations);
Vector<String> ret;
while (animations.size()) {
-
ret.push_back(animations.front()->get());
animations.pop_front();
}
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index f8b3ca291b..466536db10 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -73,7 +73,6 @@ Variant AnimationNode::get_parameter(const StringName &p_name) const {
}
void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
-
if (get_script_instance()) {
Dictionary cn = get_script_instance()->call("get_child_nodes");
List<Variant> keys;
@@ -88,14 +87,12 @@ void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
}
void AnimationNode::blend_animation(const StringName &p_animation, float p_time, float p_delta, bool p_seeked, float p_blend) {
-
ERR_FAIL_COND(!state);
ERR_FAIL_COND(!state->player->has_animation(p_animation));
Ref<Animation> animation = state->player->get_animation(p_animation);
if (animation.is_null()) {
-
AnimationNodeBlendTree *btree = Object::cast_to<AnimationNodeBlendTree>(parent);
if (btree) {
String name = btree->get_node_name(Ref<AnimationNodeAnimation>(this));
@@ -120,7 +117,6 @@ void AnimationNode::blend_animation(const StringName &p_animation, float p_time,
}
float AnimationNode::_pre_process(const StringName &p_base_path, AnimationNode *p_parent, State *p_state, float p_time, bool p_seek, const Vector<StringName> &p_connections) {
-
base_path = p_base_path;
parent = p_parent;
connections = p_connections;
@@ -176,12 +172,10 @@ float AnimationNode::blend_input(int p_input, float p_time, bool p_seek, float p
}
float AnimationNode::blend_node(const StringName &p_sub_path, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize) {
-
return _blend_node(p_sub_path, Vector<StringName>(), this, p_node, p_time, p_seek, p_blend, p_filter, p_optimize);
}
float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<StringName> &p_connections, AnimationNode *p_new_parent, Ref<AnimationNode> p_node, float p_time, bool p_seek, float p_blend, FilterAction p_filter, bool p_optimize, float *r_max) {
-
ERR_FAIL_COND_V(!p_node.is_valid(), 0);
ERR_FAIL_COND_V(!state, 0);
@@ -197,7 +191,6 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
bool any_valid = false;
if (has_filter() && is_filter_enabled() && p_filter != FILTER_IGNORE) {
-
for (int i = 0; i < blend_count; i++) {
blendw[i] = 0.0; //all to zero by default
}
@@ -217,8 +210,9 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
case FILTER_PASS: {
//values filtered pass, the rest don't
for (int i = 0; i < blend_count; i++) {
- if (blendw[i] == 0) //not filtered, does not pass
+ if (blendw[i] == 0) { //not filtered, does not pass
continue;
+ }
blendw[i] = blendr[i] * p_blend;
if (blendw[i] > CMP_EPSILON) {
@@ -228,12 +222,12 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
} break;
case FILTER_STOP: {
-
//values filtered don't pass, the rest are blended
for (int i = 0; i < blend_count; i++) {
- if (blendw[i] > 0) //filtered, does not pass
+ if (blendw[i] > 0) { //filtered, does not pass
continue;
+ }
blendw[i] = blendr[i] * p_blend;
if (blendw[i] > CMP_EPSILON) {
@@ -243,7 +237,6 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
} break;
case FILTER_BLEND: {
-
//filtered values are blended, the rest are passed without blending
for (int i = 0; i < blend_count; i++) {
@@ -262,7 +255,6 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
}
} else {
for (int i = 0; i < blend_count; i++) {
-
//regular blend
blendw[i] = blendr[i] * p_blend;
if (blendw[i] > CMP_EPSILON) {
@@ -278,8 +270,9 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
}
}
- if (!p_seek && p_optimize && !any_valid) //pointless to go on, all are zero
+ if (!p_seek && p_optimize && !any_valid) { //pointless to go on, all are zero
return 0;
+ }
String new_path;
AnimationNode *new_parent;
@@ -297,16 +290,15 @@ float AnimationNode::_blend_node(const StringName &p_subpath, const Vector<Strin
}
int AnimationNode::get_input_count() const {
-
return inputs.size();
}
+
String AnimationNode::get_input_name(int p_input) {
ERR_FAIL_INDEX_V(p_input, inputs.size(), String());
return inputs[p_input].name;
}
String AnimationNode::get_caption() const {
-
if (get_script_instance()) {
return get_script_instance()->call("get_caption");
}
@@ -338,7 +330,6 @@ void AnimationNode::remove_input(int p_index) {
}
float AnimationNode::process(float p_time, bool p_seek) {
-
if (get_script_instance()) {
return get_script_instance()->call("process", p_time, p_seek);
}
@@ -371,7 +362,6 @@ bool AnimationNode::has_filter() const {
}
Array AnimationNode::_get_filters() const {
-
Array paths;
const NodePath *K = nullptr;
@@ -382,6 +372,7 @@ Array AnimationNode::_get_filters() const {
return paths;
}
+
void AnimationNode::_set_filters(const Array &p_filters) {
filter.clear();
for (int i = 0; i < p_filters.size(); i++) {
@@ -403,7 +394,6 @@ Ref<AnimationNode> AnimationNode::get_child_by_name(const StringName &p_name) {
}
void AnimationNode::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_input_count"), &AnimationNode::get_input_count);
ClassDB::bind_method(D_METHOD("get_input_name", "input"), &AnimationNode::get_input_name);
@@ -452,7 +442,6 @@ void AnimationNode::_bind_methods() {
}
AnimationNode::AnimationNode() {
-
state = nullptr;
parent = nullptr;
filter_enabled = false;
@@ -461,7 +450,6 @@ AnimationNode::AnimationNode() {
////////////////////
void AnimationTree::set_tree_root(const Ref<AnimationNode> &p_root) {
-
if (root.is_valid()) {
root->disconnect("tree_changed", callable_mp(this, &AnimationTree::_tree_changed));
}
@@ -482,9 +470,9 @@ Ref<AnimationNode> AnimationTree::get_tree_root() const {
}
void AnimationTree::set_active(bool p_active) {
-
- if (active == p_active)
+ if (active == p_active) {
return;
+ }
active = p_active;
started = active;
@@ -492,13 +480,11 @@ void AnimationTree::set_active(bool p_active) {
if (process_mode == ANIMATION_PROCESS_IDLE) {
set_process_internal(active);
} else {
-
set_physics_process_internal(active);
}
if (!active && is_inside_tree()) {
for (Set<TrackCache *>::Element *E = playing_caches.front(); E; E = E->next()) {
-
if (ObjectDB::get_instance(E->get()->object_id)) {
E->get()->object->call("stop");
}
@@ -509,14 +495,13 @@ void AnimationTree::set_active(bool p_active) {
}
bool AnimationTree::is_active() const {
-
return active;
}
void AnimationTree::set_process_mode(AnimationProcessMode p_mode) {
-
- if (process_mode == p_mode)
+ if (process_mode == p_mode) {
return;
+ }
bool was_active = is_active();
if (was_active) {
@@ -539,7 +524,6 @@ void AnimationTree::_node_removed(Node *p_node) {
}
bool AnimationTree::_update_caches(AnimationPlayer *player) {
-
setup_pass++;
if (!player->has_node(player->get_root())) {
@@ -572,7 +556,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
}
if (!track) {
-
RES resource;
Vector<StringName> leftover_path;
Node *child = parent->get_node_and_resource(path, resource, leftover_path);
@@ -588,7 +571,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
switch (track_type) {
case Animation::TYPE_VALUE: {
-
TrackCacheValue *track_value = memnew(TrackCacheValue);
if (resource.is_valid()) {
@@ -604,7 +586,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
} break;
case Animation::TYPE_TRANSFORM: {
-
Node3D *spatial = Object::cast_to<Node3D>(child);
if (!spatial) {
@@ -619,11 +600,9 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
track_xform->bone_idx = -1;
if (path.get_subname_count() == 1 && Object::cast_to<Skeleton3D>(spatial)) {
-
Skeleton3D *sk = Object::cast_to<Skeleton3D>(spatial);
int bone_idx = sk->find_bone(path.get_subname(0));
if (bone_idx != -1) {
-
track_xform->skeleton = sk;
track_xform->bone_idx = bone_idx;
}
@@ -636,7 +615,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
} break;
case Animation::TYPE_METHOD: {
-
TrackCacheMethod *track_method = memnew(TrackCacheMethod);
if (resource.is_valid()) {
@@ -651,7 +629,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
} break;
case Animation::TYPE_BEZIER: {
-
TrackCacheBezier *track_bezier = memnew(TrackCacheBezier);
if (resource.is_valid()) {
@@ -666,7 +643,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
track = track_bezier;
} break;
case Animation::TYPE_AUDIO: {
-
TrackCacheAudio *track_audio = memnew(TrackCacheAudio);
track_audio->object = child;
@@ -676,7 +652,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
} break;
case Animation::TYPE_ANIMATION: {
-
TrackCacheAnimation *track_animation = memnew(TrackCacheAnimation);
track_animation->object = child;
@@ -732,7 +707,6 @@ bool AnimationTree::_update_caches(AnimationPlayer *player) {
}
void AnimationTree::_clear_caches() {
-
const NodePath *K = nullptr;
while ((K = track_cache.next(K))) {
memdelete(track_cache[*K]);
@@ -744,7 +718,6 @@ void AnimationTree::_clear_caches() {
}
void AnimationTree::_process_graph(float p_delta) {
-
_update_properties(); //if properties need updating, update them
//check all tracks, see if they need modification
@@ -774,7 +747,6 @@ void AnimationTree::_process_graph(float p_delta) {
}
if (last_animation_player != current_animation_player) {
-
if (last_animation_player.is_valid()) {
Object *old_player = ObjectDB::get_instance(last_animation_player);
if (old_player) {
@@ -826,7 +798,6 @@ void AnimationTree::_process_graph(float p_delta) {
//process
{
-
if (started) {
//if started, seek
root->_pre_process(SceneStringNames::get_singleton()->parameters_base_path, nullptr, &state, 0, true, Vector<StringName>());
@@ -842,11 +813,9 @@ void AnimationTree::_process_graph(float p_delta) {
//apply value/transform/bezier blends to track caches and execute method/audio/animation tracks
{
-
bool can_call = is_inside_tree() && !Engine::get_singleton()->is_editor_hint();
for (List<AnimationNode::AnimationState>::Element *E = state.animation_states.front(); E; E = E->next()) {
-
const AnimationNode::AnimationState &as = E->get();
Ref<Animation> a = as.animation;
@@ -855,7 +824,6 @@ void AnimationTree::_process_graph(float p_delta) {
bool seeked = as.seeked;
for (int i = 0; i < a->get_track_count(); i++) {
-
NodePath path = a->track_get_path(i);
ERR_CONTINUE(!track_cache.has(path));
@@ -874,19 +842,16 @@ void AnimationTree::_process_graph(float p_delta) {
float blend = (*as.track_blends)[blend_idx];
- if (blend < CMP_EPSILON)
+ if (blend < CMP_EPSILON) {
continue; //nothing to blend
+ }
switch (track->type) {
-
case Animation::TYPE_TRANSFORM: {
-
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
if (track->root_motion) {
-
if (t->process_pass != process_pass) {
-
t->process_pass = process_pass;
t->loc = Vector3();
t->rot = Quat();
@@ -908,7 +873,6 @@ void AnimationTree::_process_graph(float p_delta) {
Vector3 scale[2];
if (prev_time > time) {
-
Error err = a->transform_track_interpolate(i, prev_time, &loc[0], &rot[0], &scale[0]);
if (err != OK) {
continue;
@@ -947,7 +911,6 @@ void AnimationTree::_process_graph(float p_delta) {
//ERR_CONTINUE(err!=OK); //used for testing, should be removed
if (t->process_pass != process_pass) {
-
t->process_pass = process_pass;
t->loc = loc;
t->rot = rot;
@@ -955,10 +918,11 @@ void AnimationTree::_process_graph(float p_delta) {
t->scale = scale;
}
- if (err != OK)
+ if (err != OK) {
continue;
+ }
- t->loc = t->loc.linear_interpolate(loc, blend);
+ t->loc = t->loc.lerp(loc, blend);
if (t->rot_blend_accum == 0) {
t->rot = rot;
t->rot_blend_accum = blend;
@@ -967,12 +931,11 @@ void AnimationTree::_process_graph(float p_delta) {
t->rot = rot.slerp(t->rot, t->rot_blend_accum / rot_total).normalized();
t->rot_blend_accum = rot_total;
}
- t->scale = t->scale.linear_interpolate(scale, blend);
+ t->scale = t->scale.lerp(scale, blend);
}
} break;
case Animation::TYPE_VALUE: {
-
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
Animation::UpdateMode update_mode = a->value_track_get_update_mode(i);
@@ -981,8 +944,9 @@ void AnimationTree::_process_graph(float p_delta) {
Variant value = a->value_track_interpolate(i, time);
- if (value == Variant())
+ if (value == Variant()) {
continue;
+ }
if (t->process_pass != process_pass) {
t->value = value;
@@ -992,12 +956,10 @@ void AnimationTree::_process_graph(float p_delta) {
Variant::interpolate(t->value, value, blend, t->value);
} else if (delta != 0) {
-
List<int> indices;
a->value_track_get_key_indices(i, time, delta, &indices);
for (List<int>::Element *F = indices.front(); F; F = F->next()) {
-
Variant value = a->track_get_key_value(i, F->get());
t->object->set_indexed(t->subpath, value);
}
@@ -1005,7 +967,6 @@ void AnimationTree::_process_graph(float p_delta) {
} break;
case Animation::TYPE_METHOD: {
-
if (delta == 0) {
continue;
}
@@ -1016,7 +977,6 @@ void AnimationTree::_process_graph(float p_delta) {
a->method_track_get_key_indices(i, time, delta, &indices);
for (List<int>::Element *F = indices.front(); F; F = F->next()) {
-
StringName method = a->method_track_get_name(i, F->get());
Vector<Variant> params = a->method_track_get_params(i, F->get());
@@ -1036,7 +996,6 @@ void AnimationTree::_process_graph(float p_delta) {
} break;
case Animation::TYPE_BEZIER: {
-
TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
float bezier = a->bezier_track_interpolate(i, time);
@@ -1050,14 +1009,14 @@ void AnimationTree::_process_graph(float p_delta) {
} break;
case Animation::TYPE_AUDIO: {
-
TrackCacheAudio *t = static_cast<TrackCacheAudio *>(track);
if (seeked) {
//find whathever should be playing
int idx = a->track_find_key(i, time);
- if (idx < 0)
+ if (idx < 0) {
continue;
+ }
Ref<AudioStream> stream = a->audio_track_get_key_stream(i, idx);
if (!stream.is_valid()) {
@@ -1122,7 +1081,6 @@ void AnimationTree::_process_graph(float p_delta) {
t->start = time;
}
} else if (t->playing) {
-
bool loop = a->has_loop();
bool stop = false;
@@ -1154,25 +1112,27 @@ void AnimationTree::_process_graph(float p_delta) {
}
} break;
case Animation::TYPE_ANIMATION: {
-
TrackCacheAnimation *t = static_cast<TrackCacheAnimation *>(track);
AnimationPlayer *player2 = Object::cast_to<AnimationPlayer>(t->object);
- if (!player2)
+ if (!player2) {
continue;
+ }
if (delta == 0 || seeked) {
//seek
int idx = a->track_find_key(i, time);
- if (idx < 0)
+ if (idx < 0) {
continue;
+ }
float pos = a->track_get_key_time(i, idx);
StringName anim_name = a->animation_track_get_key_animation(i, idx);
- if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name))
+ if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) {
continue;
+ }
Ref<Animation> anim = player2->get_animation(anim_name);
@@ -1202,7 +1162,6 @@ void AnimationTree::_process_graph(float p_delta) {
StringName anim_name = a->animation_track_get_key_animation(i, idx);
if (String(anim_name) == "[stop]" || !player2->has_animation(anim_name)) {
-
if (playing_caches.has(t)) {
playing_caches.erase(t);
player2->stop();
@@ -1227,13 +1186,12 @@ void AnimationTree::_process_graph(float p_delta) {
const NodePath *K = nullptr;
while ((K = track_cache.next(K))) {
TrackCache *track = track_cache[*K];
- if (track->process_pass != process_pass)
+ if (track->process_pass != process_pass) {
continue; //not processed, ignore
+ }
switch (track->type) {
-
case Animation::TYPE_TRANSFORM: {
-
TrackCacheTransform *t = static_cast<TrackCacheTransform *>(track);
Transform xform;
@@ -1242,31 +1200,26 @@ void AnimationTree::_process_graph(float p_delta) {
xform.basis.set_quat_scale(t->rot, t->scale);
if (t->root_motion) {
-
root_motion_transform = xform;
if (t->skeleton && t->bone_idx >= 0) {
root_motion_transform = (t->skeleton->get_bone_rest(t->bone_idx) * root_motion_transform) * t->skeleton->get_bone_rest(t->bone_idx).affine_inverse();
}
} else if (t->skeleton && t->bone_idx >= 0) {
-
t->skeleton->set_bone_pose(t->bone_idx, xform);
} else {
-
t->spatial->set_transform(xform);
}
} break;
case Animation::TYPE_VALUE: {
-
TrackCacheValue *t = static_cast<TrackCacheValue *>(track);
t->object->set_indexed(t->subpath, t->value);
} break;
case Animation::TYPE_BEZIER: {
-
TrackCacheBezier *t = static_cast<TrackCacheBezier *>(track);
t->object->set_indexed(t->subpath, t->value);
@@ -1280,12 +1233,10 @@ void AnimationTree::_process_graph(float p_delta) {
}
void AnimationTree::advance(float p_time) {
-
_process_graph(p_time);
}
void AnimationTree::_notification(int p_what) {
-
if (active && p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS && process_mode == ANIMATION_PROCESS_PHYSICS) {
_process_graph(get_physics_process_delta_time());
}
@@ -1297,7 +1248,6 @@ void AnimationTree::_notification(int p_what) {
if (p_what == NOTIFICATION_EXIT_TREE) {
_clear_caches();
if (last_animation_player.is_valid()) {
-
Object *player = ObjectDB::get_instance(last_animation_player);
if (player) {
player->disconnect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches));
@@ -1305,7 +1255,6 @@ void AnimationTree::_notification(int p_what) {
}
} else if (p_what == NOTIFICATION_ENTER_TREE) {
if (last_animation_player.is_valid()) {
-
Object *player = ObjectDB::get_instance(last_animation_player);
if (player) {
player->connect("caches_cleared", callable_mp(this, &AnimationTree::_clear_caches));
@@ -1324,11 +1273,10 @@ NodePath AnimationTree::get_animation_player() const {
}
bool AnimationTree::is_state_invalid() const {
-
return !state.valid;
}
-String AnimationTree::get_invalid_state_reason() const {
+String AnimationTree::get_invalid_state_reason() const {
return state.invalid_reasons;
}
@@ -1337,7 +1285,6 @@ uint64_t AnimationTree::get_last_process_pass() const {
}
String AnimationTree::get_configuration_warning() const {
-
String warning = Node::get_configuration_warning();
if (!root.is_valid()) {
@@ -1348,7 +1295,6 @@ String AnimationTree::get_configuration_warning() const {
}
if (!has_node(animation_player)) {
-
if (warning != String()) {
warning += "\n\n";
}
@@ -1402,13 +1348,11 @@ void AnimationTree::_tree_changed() {
}
void AnimationTree::_update_properties_for_node(const String &p_base_path, Ref<AnimationNode> node) {
-
if (!property_parent_map.has(p_base_path)) {
property_parent_map[p_base_path] = HashMap<StringName, StringName>();
}
if (node->get_input_count() && !input_activity_map.has(p_base_path)) {
-
Vector<Activity> activity;
for (int i = 0; i < node->get_input_count(); i++) {
Activity a;
@@ -1492,6 +1436,7 @@ bool AnimationTree::_get(const StringName &p_name, Variant &r_ret) const {
return false;
}
+
void AnimationTree::_get_property_list(List<PropertyInfo> *p_list) const {
if (properties_dirty) {
const_cast<AnimationTree *>(this)->_update_properties();
@@ -1503,7 +1448,6 @@ void AnimationTree::_get_property_list(List<PropertyInfo> *p_list) const {
}
void AnimationTree::rename_parameter(const String &p_base, const String &p_new_base) {
-
//rename values first
for (const List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
if (E->get().name.begins_with(p_base)) {
@@ -1518,7 +1462,6 @@ void AnimationTree::rename_parameter(const String &p_base, const String &p_new_b
}
float AnimationTree::get_connection_activity(const StringName &p_path, int p_connection) const {
-
if (!input_activity_map_get.has(p_path)) {
return 0;
}
@@ -1572,7 +1515,6 @@ void AnimationTree::_bind_methods() {
}
AnimationTree::AnimationTree() {
-
process_mode = ANIMATION_PROCESS_IDLE;
active = false;
cache_valid = false;
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index d558170f23..8fe01fac8f 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -52,7 +52,6 @@ public:
};
struct Input {
-
String name;
};
@@ -63,7 +62,6 @@ public:
friend class AnimationTree;
struct AnimationState {
-
Ref<Animation> animation;
float time;
float delta;
@@ -73,7 +71,6 @@ public:
};
struct State {
-
int track_count;
HashMap<NodePath, int> track_map;
List<AnimationState> animation_states;
@@ -174,7 +171,6 @@ public:
private:
struct TrackCache {
-
bool root_motion;
uint64_t setup_pass;
uint64_t process_pass;
@@ -209,19 +205,16 @@ private:
};
struct TrackCacheValue : public TrackCache {
-
Variant value;
Vector<StringName> subpath;
TrackCacheValue() { type = Animation::TYPE_VALUE; }
};
struct TrackCacheMethod : public TrackCache {
-
TrackCacheMethod() { type = Animation::TYPE_METHOD; }
};
struct TrackCacheBezier : public TrackCache {
-
float value;
Vector<StringName> subpath;
TrackCacheBezier() {
@@ -231,7 +224,6 @@ private:
};
struct TrackCacheAudio : public TrackCache {
-
bool playing;
float start;
float len;
@@ -245,7 +237,6 @@ private:
};
struct TrackCacheAnimation : public TrackCache {
-
bool playing;
TrackCacheAnimation() {
diff --git a/scene/animation/root_motion_view.cpp b/scene/animation/root_motion_view.cpp
index f993127b07..cbf2e4a6ff 100644
--- a/scene/animation/root_motion_view.cpp
+++ b/scene/animation/root_motion_view.cpp
@@ -76,9 +76,7 @@ bool RootMotionView::get_zero_y() const {
}
void RootMotionView::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
RS::get_singleton()->immediate_set_material(immediate, StandardMaterial3D::get_material_rid_for_2d(false, true, false, false, false));
first = true;
}
@@ -87,7 +85,6 @@ void RootMotionView::_notification(int p_what) {
Transform transform;
if (has_node(path)) {
-
Node *node = get_node(path);
AnimationTree *tree = Object::cast_to<AnimationTree>(node);
@@ -129,7 +126,6 @@ void RootMotionView::_notification(int p_what) {
RS::get_singleton()->immediate_begin(immediate, RS::PRIMITIVE_LINES);
for (int i = -cells_in_radius; i < cells_in_radius; i++) {
for (int j = -cells_in_radius; j < cells_in_radius; j++) {
-
Vector3 from(i * cell_size, 0, j * cell_size);
Vector3 from_i((i + 1) * cell_size, 0, j * cell_size);
Vector3 from_j(i * cell_size, 0, (j + 1) * cell_size);
@@ -161,15 +157,14 @@ void RootMotionView::_notification(int p_what) {
}
AABB RootMotionView::get_aabb() const {
-
return AABB(Vector3(-radius, 0, -radius), Vector3(radius * 2, 0.001, radius * 2));
}
+
Vector<Face3> RootMotionView::get_faces(uint32_t p_usage_flags) const {
return Vector<Face3>();
}
void RootMotionView::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_animation_path", "path"), &RootMotionView::set_animation_path);
ClassDB::bind_method(D_METHOD("get_animation_path"), &RootMotionView::get_animation_path);
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index bc28c38e2c..854db5fee2 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -33,7 +33,6 @@
#include "core/method_bind_ext.gen.inc"
void Tween::_add_pending_command(StringName p_key, const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5, const Variant &p_arg6, const Variant &p_arg7, const Variant &p_arg8, const Variant &p_arg9, const Variant &p_arg10) {
-
// Add a new pending command and reference it
pending_commands.push_back(PendingCommand());
PendingCommand &cmd = pending_commands.back()->get();
@@ -43,57 +42,66 @@ void Tween::_add_pending_command(StringName p_key, const Variant &p_arg1, const
// Determine command argument count
int &count = cmd.args;
- if (p_arg10.get_type() != Variant::NIL)
+ if (p_arg10.get_type() != Variant::NIL) {
count = 10;
- else if (p_arg9.get_type() != Variant::NIL)
+ } else if (p_arg9.get_type() != Variant::NIL) {
count = 9;
- else if (p_arg8.get_type() != Variant::NIL)
+ } else if (p_arg8.get_type() != Variant::NIL) {
count = 8;
- else if (p_arg7.get_type() != Variant::NIL)
+ } else if (p_arg7.get_type() != Variant::NIL) {
count = 7;
- else if (p_arg6.get_type() != Variant::NIL)
+ } else if (p_arg6.get_type() != Variant::NIL) {
count = 6;
- else if (p_arg5.get_type() != Variant::NIL)
+ } else if (p_arg5.get_type() != Variant::NIL) {
count = 5;
- else if (p_arg4.get_type() != Variant::NIL)
+ } else if (p_arg4.get_type() != Variant::NIL) {
count = 4;
- else if (p_arg3.get_type() != Variant::NIL)
+ } else if (p_arg3.get_type() != Variant::NIL) {
count = 3;
- else if (p_arg2.get_type() != Variant::NIL)
+ } else if (p_arg2.get_type() != Variant::NIL) {
count = 2;
- else if (p_arg1.get_type() != Variant::NIL)
+ } else if (p_arg1.get_type() != Variant::NIL) {
count = 1;
- else
+ } else {
count = 0;
+ }
// Add the specified arguments to the command
- if (count > 0)
+ if (count > 0) {
cmd.arg[0] = p_arg1;
- if (count > 1)
+ }
+ if (count > 1) {
cmd.arg[1] = p_arg2;
- if (count > 2)
+ }
+ if (count > 2) {
cmd.arg[2] = p_arg3;
- if (count > 3)
+ }
+ if (count > 3) {
cmd.arg[3] = p_arg4;
- if (count > 4)
+ }
+ if (count > 4) {
cmd.arg[4] = p_arg5;
- if (count > 5)
+ }
+ if (count > 5) {
cmd.arg[5] = p_arg6;
- if (count > 6)
+ }
+ if (count > 6) {
cmd.arg[6] = p_arg7;
- if (count > 7)
+ }
+ if (count > 7) {
cmd.arg[7] = p_arg8;
- if (count > 8)
+ }
+ if (count > 8) {
cmd.arg[8] = p_arg9;
- if (count > 9)
+ }
+ if (count > 9) {
cmd.arg[9] = p_arg10;
+ }
}
void Tween::_process_pending_commands() {
-
// For each pending command...
for (List<PendingCommand>::Element *E = pending_commands.front(); E; E = E->next()) {
-
// Get the command
PendingCommand &cmd = E->get();
Callable::CallError err;
@@ -121,35 +129,39 @@ void Tween::_process_pending_commands() {
}
bool Tween::_set(const StringName &p_name, const Variant &p_value) {
-
// Set the correct attribute based on the given name
String name = p_name;
if (name == "playback/speed" || name == "speed") { // Backwards compatibility
set_speed_scale(p_value);
+ return true;
} else if (name == "playback/active") {
set_active(p_value);
+ return true;
} else if (name == "playback/repeat") {
set_repeat(p_value);
+ return true;
}
- return true;
+ return false;
}
bool Tween::_get(const StringName &p_name, Variant &r_ret) const {
-
// Get the correct attribute based on the given name
String name = p_name;
if (name == "playback/speed") { // Backwards compatibility
r_ret = speed_scale;
+ return true;
} else if (name == "playback/active") {
r_ret = is_active();
+ return true;
} else if (name == "playback/repeat") {
r_ret = is_repeat();
+ return true;
}
- return true;
+ return false;
}
void Tween::_get_property_list(List<PropertyInfo> *p_list) const {
@@ -162,7 +174,6 @@ void Tween::_get_property_list(List<PropertyInfo> *p_list) const {
void Tween::_notification(int p_what) {
// What notification did we receive?
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
// Are we not already active?
if (!is_active()) {
@@ -179,26 +190,30 @@ void Tween::_notification(int p_what) {
case NOTIFICATION_INTERNAL_PROCESS: {
// Are we processing during physics time?
- if (tween_process_mode == TWEEN_PROCESS_PHYSICS)
+ if (tween_process_mode == TWEEN_PROCESS_PHYSICS) {
// Do nothing since we aren't aligned with physics when we should be
break;
+ }
// Should we update?
- if (is_active())
+ if (is_active()) {
// Update the tweens
_tween_process(get_process_delta_time());
+ }
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
// Are we processing during 'regular' time?
- if (tween_process_mode == TWEEN_PROCESS_IDLE)
+ if (tween_process_mode == TWEEN_PROCESS_IDLE) {
// Do nothing since we would only process during idle time
break;
+ }
// Should we update?
- if (is_active())
+ if (is_active()) {
// Update the tweens
_tween_process(get_physics_process_delta_time());
+ }
} break;
case NOTIFICATION_EXIT_TREE: {
@@ -283,7 +298,6 @@ void Tween::_bind_methods() {
}
Variant Tween::_get_initial_val(const InterpolateData &p_data) const {
-
// What type of data are we interpolating?
switch (p_data.type) {
case INTER_PROPERTY:
@@ -347,7 +361,9 @@ Variant Tween::_get_final_val(const InterpolateData &p_data) const {
// If we're looking at an INT value, instead convert it to a FLOAT
// This is better for interpolation
- if (final_val.get_type() == Variant::INT) final_val = final_val.operator real_t();
+ if (final_val.get_type() == Variant::INT) {
+ final_val = final_val.operator real_t();
+ }
return final_val;
}
@@ -359,7 +375,6 @@ Variant Tween::_get_final_val(const InterpolateData &p_data) const {
}
Variant &Tween::_get_delta_val(InterpolateData &p_data) {
-
// What kind of data are we interpolating?
switch (p_data.type) {
case INTER_PROPERTY:
@@ -389,7 +404,9 @@ Variant &Tween::_get_delta_val(InterpolateData &p_data) {
// If we're looking at an INT value, instead convert it to a FLOAT
// This is better for interpolation
- if (final_val.get_type() == Variant::INT) final_val = final_val.operator real_t();
+ if (final_val.get_type() == Variant::INT) {
+ final_val = final_val.operator real_t();
+ }
// Calculate the delta based on the initial value and the final value
_calc_delta_val(p_data.initial_val, final_val, p_data.delta_val);
@@ -403,7 +420,9 @@ Variant &Tween::_get_delta_val(InterpolateData &p_data) {
// If we're looking at an INT value, instead convert it to a FLOAT
// This is better for interpolation
- if (initial_val.get_type() == Variant::INT) initial_val = initial_val.operator real_t();
+ if (initial_val.get_type() == Variant::INT) {
+ initial_val = initial_val.operator real_t();
+ }
// Calculate the delta based on the initial value and the final value
_calc_delta_val(initial_val, p_data.final_val, p_data.delta_val);
@@ -429,7 +448,6 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
// What type of data are we interpolating?
switch (initial_val.get_type()) {
-
case Variant::BOOL:
// Run the boolean specific equation (checking if it is at least 0.5)
result = (_run_equation(p_data.trans_type, p_data.ease_type, p_data.elapsed - p_data.delay, initial_val, delta_val, p_data.duration)) >= 0.5;
@@ -604,14 +622,12 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
}
bool Tween::_apply_tween_value(InterpolateData &p_data, Variant &value) {
-
// Get the object we want to apply the new value to
Object *object = ObjectDB::get_instance(p_data.id);
ERR_FAIL_COND_V(object == nullptr, false);
// What kind of data are we mutating?
switch (p_data.type) {
-
case INTER_PROPERTY:
case FOLLOW_PROPERTY:
case TARGETING_PROPERTY: {
@@ -654,8 +670,9 @@ void Tween::_tween_process(float p_delta) {
_process_pending_commands();
// If the scale is 0, make no progress on the tweens
- if (speed_scale == 0)
+ if (speed_scale == 0) {
return;
+ }
// Update the delta and whether we are pending an update
p_delta *= speed_scale;
@@ -678,8 +695,9 @@ void Tween::_tween_process(float p_delta) {
}
// If we are all finished, we can reset all of the tweens
- if (repeats_finished)
+ if (repeats_finished) {
reset_all();
+ }
}
// Are all of the tweens complete?
@@ -687,7 +705,6 @@ void Tween::_tween_process(float p_delta) {
// For each tween we wish to interpolate...
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
-
// Get the data from it
InterpolateData &data = E->get();
@@ -695,20 +712,22 @@ void Tween::_tween_process(float p_delta) {
all_finished = all_finished && data.finish;
// Is the data not active or already finished? No need to go any further
- if (!data.active || data.finish)
+ if (!data.active || data.finish) {
continue;
+ }
// Get the target object for this interpolation
Object *object = ObjectDB::get_instance(data.id);
- if (object == nullptr)
+ if (object == nullptr) {
continue;
+ }
// Are we still delaying this tween?
bool prev_delaying = data.elapsed <= data.delay;
data.elapsed += p_delta;
- if (data.elapsed < data.delay)
+ if (data.elapsed < data.delay) {
continue;
- else if (prev_delaying) {
+ } else if (prev_delaying) {
// We can apply the tween's value to the data and emit that the tween has started
_apply_tween_value(data, data.initial_val);
emit_signal("tween_started", object, NodePath(Vector<StringName>(), data.key, false));
@@ -781,8 +800,9 @@ void Tween::_tween_process(float p_delta) {
emit_signal("tween_completed", object, NodePath(Vector<StringName>(), data.key, false));
// If we are not repeating the tween, remove it
- if (!repeat)
+ if (!repeat) {
call_deferred("_remove_by_uid", data.uid);
+ }
} else if (!repeat) {
// Check whether all tweens are finished
all_finished = all_finished && data.finish;
@@ -812,13 +832,18 @@ bool Tween::is_active() const {
void Tween::set_active(bool p_active) {
// Do nothing if it's the same active mode that we currently are
- if (is_active() == p_active)
+ if (is_active() == p_active) {
return;
+ }
// Depending on physics or idle, set processing
switch (tween_process_mode) {
- case TWEEN_PROCESS_IDLE: set_process_internal(p_active); break;
- case TWEEN_PROCESS_PHYSICS: set_physics_process_internal(p_active); break;
+ case TWEEN_PROCESS_IDLE:
+ set_process_internal(p_active);
+ break;
+ case TWEEN_PROCESS_PHYSICS:
+ set_physics_process_internal(p_active);
+ break;
}
}
@@ -839,7 +864,6 @@ float Tween::get_speed_scale() const {
}
void Tween::start() {
-
ERR_FAIL_COND_MSG(!is_inside_tree(), "Tween was not added to the SceneTree!");
// Are there any pending updates?
@@ -860,8 +884,9 @@ void Tween::reset(Object *p_object, StringName p_key) {
// Get the target object
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == nullptr)
+ if (object == nullptr) {
continue;
+ }
// Do we have the correct object and key?
if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
@@ -870,8 +895,9 @@ void Tween::reset(Object *p_object, StringName p_key) {
data.finish = false;
// Also apply the initial state if there isn't a delay
- if (data.delay == 0)
+ if (data.delay == 0) {
_apply_tween_value(data, data.initial_val);
+ }
}
}
pending_update--;
@@ -887,8 +913,9 @@ void Tween::reset_all() {
data.finish = false;
// If there isn't a delay, apply the value to the object
- if (data.delay == 0)
+ if (data.delay == 0) {
_apply_tween_value(data, data.initial_val);
+ }
}
pending_update--;
}
@@ -897,17 +924,18 @@ void Tween::stop(Object *p_object, StringName p_key) {
// Find the tween that has the given target object and string key
pending_update++;
for (List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
-
// Get the object the tween is targeting
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == nullptr)
+ if (object == nullptr) {
continue;
+ }
// Is this the correct object and does it have the given key?
- if (object == p_object && (data.concatenated_key == p_key || p_key == ""))
+ if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
// Disable the tween
data.active = false;
+ }
}
pending_update--;
}
@@ -937,12 +965,14 @@ void Tween::resume(Object *p_object, StringName p_key) {
// Grab the object
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == nullptr)
+ if (object == nullptr) {
continue;
+ }
// If the object and string key match, activate it
- if (object == p_object && (data.concatenated_key == p_key || p_key == ""))
+ if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
data.active = true;
+ }
}
pending_update--;
}
@@ -975,8 +1005,9 @@ void Tween::remove(Object *p_object, StringName p_key) {
// Get the target object
InterpolateData &data = E->get();
Object *object = ObjectDB::get_instance(data.id);
- if (object == nullptr)
+ if (object == nullptr) {
continue;
+ }
// If the target object and string key match, queue it for removal
if (object == p_object && (data.concatenated_key == p_key || p_key == "")) {
@@ -1077,9 +1108,10 @@ real_t Tween::tell() const {
for (const List<InterpolateData>::Element *E = interpolates.front(); E; E = E->next()) {
// Get the data and figure out if it's position is further along than the previous ones
const InterpolateData &data = E->get();
- if (data.elapsed > pos)
+ if (data.elapsed > pos) {
// Save it if so
pos = data.elapsed;
+ }
}
pending_update--;
return pos;
@@ -1099,9 +1131,10 @@ real_t Tween::get_runtime() const {
// Get the tween data and see if it's runtime is greater than the previous tweens
const InterpolateData &data = E->get();
real_t t = data.delay + data.duration;
- if (t > runtime)
+ if (t > runtime) {
// This is the longest running tween
runtime = t;
+ }
}
pending_update--;
@@ -1110,7 +1143,6 @@ real_t Tween::get_runtime() const {
}
bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final_val, Variant &p_delta_val) {
-
// Get the initial, final, and delta values
const Variant &initial_val = p_initial_val;
const Variant &final_val = p_final_val;
@@ -1118,7 +1150,6 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final
// What kind of data are we interpolating?
switch (initial_val.get_type()) {
-
case Variant::BOOL:
// We'll treat booleans just like integers
case Variant::INT:
@@ -1250,7 +1281,6 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final
}
void Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p_object, NodePath *p_property, StringName *p_method, Variant p_initial_val, Variant p_final_val, real_t p_duration, TransitionType p_trans_type, EaseType p_ease_type, real_t p_delay) {
-
// TODO: Add initialization+implementation for remaining interpolation types
// TODO: Fix this method's organization to take advantage of the type
@@ -1309,8 +1339,9 @@ void Tween::_build_interpolation(InterpolateType p_interpolation_type, Object *p
}
// Is there not a valid delta?
- if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val))
+ if (!_calc_delta_val(data.initial_val, data.final_val, data.delta_val)) {
return;
+ }
// Add this interpolation to the total
_push_interpolate_data(data);
@@ -1328,11 +1359,17 @@ void Tween::interpolate_property(Object *p_object, NodePath p_property, Variant
// If no initial value given, grab the initial value from the object
// TODO: Is this documented? This is very useful and removes a lot of clutter from tweens!
- if (p_initial_val.get_type() == Variant::NIL) p_initial_val = p_object->get_indexed(p_property.get_subnames());
+ if (p_initial_val.get_type() == Variant::NIL) {
+ p_initial_val = p_object->get_indexed(p_property.get_subnames());
+ }
// Convert any integers into REALs as they are better for interpolation
- if (p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
- if (p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
+ if (p_initial_val.get_type() == Variant::INT) {
+ p_initial_val = p_initial_val.operator real_t();
+ }
+ if (p_final_val.get_type() == Variant::INT) {
+ p_final_val = p_final_val.operator real_t();
+ }
// Build the interpolation data
_build_interpolation(INTER_PROPERTY, p_object, &p_property, nullptr, p_initial_val, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
@@ -1346,8 +1383,12 @@ void Tween::interpolate_method(Object *p_object, StringName p_method, Variant p_
}
// Convert any integers into REALs as they are better for interpolation
- if (p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
- if (p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
+ if (p_initial_val.get_type() == Variant::INT) {
+ p_initial_val = p_initial_val.operator real_t();
+ }
+ if (p_final_val.get_type() == Variant::INT) {
+ p_final_val = p_final_val.operator real_t();
+ }
// Build the interpolation data
_build_interpolation(INTER_METHOD, p_object, nullptr, &p_method, p_initial_val, p_final_val, p_duration, p_trans_type, p_ease_type, p_delay);
@@ -1386,18 +1427,19 @@ void Tween::interpolate_callback(Object *p_object, real_t p_duration, String p_c
// Add arguments to the interpolation
int args = 0;
- if (p_arg5.get_type() != Variant::NIL)
+ if (p_arg5.get_type() != Variant::NIL) {
args = 5;
- else if (p_arg4.get_type() != Variant::NIL)
+ } else if (p_arg4.get_type() != Variant::NIL) {
args = 4;
- else if (p_arg3.get_type() != Variant::NIL)
+ } else if (p_arg3.get_type() != Variant::NIL) {
args = 3;
- else if (p_arg2.get_type() != Variant::NIL)
+ } else if (p_arg2.get_type() != Variant::NIL) {
args = 2;
- else if (p_arg1.get_type() != Variant::NIL)
+ } else if (p_arg1.get_type() != Variant::NIL) {
args = 1;
- else
+ } else {
args = 0;
+ }
data.args = args;
data.arg[0] = p_arg1;
@@ -1443,18 +1485,19 @@ void Tween::interpolate_deferred_callback(Object *p_object, real_t p_duration, S
// Collect arguments for the callback
int args = 0;
- if (p_arg5.get_type() != Variant::NIL)
+ if (p_arg5.get_type() != Variant::NIL) {
args = 5;
- else if (p_arg4.get_type() != Variant::NIL)
+ } else if (p_arg4.get_type() != Variant::NIL) {
args = 4;
- else if (p_arg3.get_type() != Variant::NIL)
+ } else if (p_arg3.get_type() != Variant::NIL) {
args = 3;
- else if (p_arg2.get_type() != Variant::NIL)
+ } else if (p_arg2.get_type() != Variant::NIL) {
args = 2;
- else if (p_arg1.get_type() != Variant::NIL)
+ } else if (p_arg1.get_type() != Variant::NIL) {
args = 1;
- else
+ } else {
args = 0;
+ }
data.args = args;
data.arg[0] = p_arg1;
@@ -1480,10 +1523,14 @@ void Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini
// If no initial value is given, grab it from the source object
// TODO: Is this documented? It's really helpful for decluttering tweens
- if (p_initial_val.get_type() == Variant::NIL) p_initial_val = p_object->get_indexed(p_property.get_subnames());
+ if (p_initial_val.get_type() == Variant::NIL) {
+ p_initial_val = p_object->get_indexed(p_property.get_subnames());
+ }
// Convert initial INT values to FLOAT as they are better for interpolation
- if (p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
+ if (p_initial_val.get_type() == Variant::INT) {
+ p_initial_val = p_initial_val.operator real_t();
+ }
// Confirm the source and target objects are valid
ERR_FAIL_COND(p_object == nullptr);
@@ -1509,7 +1556,9 @@ void Tween::follow_property(Object *p_object, NodePath p_property, Variant p_ini
ERR_FAIL_COND(!target_prop_valid);
// Convert target INT to FLOAT since it is better for interpolation
- if (target_val.get_type() == Variant::INT) target_val = target_val.operator real_t();
+ if (target_val.get_type() == Variant::INT) {
+ target_val = target_val.operator real_t();
+ }
// Verify that the target value and initial value are the same type
ERR_FAIL_COND(target_val.get_type() != p_initial_val.get_type());
@@ -1544,7 +1593,9 @@ void Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi
return;
}
// Convert initial INT values to FLOAT as they are better for interpolation
- if (p_initial_val.get_type() == Variant::INT) p_initial_val = p_initial_val.operator real_t();
+ if (p_initial_val.get_type() == Variant::INT) {
+ p_initial_val = p_initial_val.operator real_t();
+ }
// Verify the source and target objects are valid
ERR_FAIL_COND(p_object == nullptr);
@@ -1570,7 +1621,9 @@ void Tween::follow_method(Object *p_object, StringName p_method, Variant p_initi
ERR_FAIL_COND(error.error != Callable::CallError::CALL_OK);
// Convert target INT values to FLOAT as they are better for interpolation
- if (target_val.get_type() == Variant::INT) target_val = target_val.operator real_t();
+ if (target_val.get_type() == Variant::INT) {
+ target_val = target_val.operator real_t();
+ }
ERR_FAIL_COND(target_val.get_type() != p_initial_val.get_type());
// Make the new InterpolateData for the method follow
@@ -1607,7 +1660,9 @@ void Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_
p_initial_property = p_initial_property.get_as_property_path();
// Convert the initial INT values to FLOAT as they are better for Interpolation
- if (p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
+ if (p_final_val.get_type() == Variant::INT) {
+ p_final_val = p_final_val.operator real_t();
+ }
// Verify both objects are valid
ERR_FAIL_COND(p_object == nullptr);
@@ -1633,7 +1688,9 @@ void Tween::targeting_property(Object *p_object, NodePath p_property, Object *p_
ERR_FAIL_COND(!initial_prop_valid);
// Convert the initial INT value to FLOAT as it is better for interpolation
- if (initial_val.get_type() == Variant::INT) initial_val = initial_val.operator real_t();
+ if (initial_val.get_type() == Variant::INT) {
+ initial_val = initial_val.operator real_t();
+ }
ERR_FAIL_COND(initial_val.get_type() != p_final_val.get_type());
// Build the InterpolateData object
@@ -1673,7 +1730,9 @@ void Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in
}
// Convert final INT values to FLOAT as they are better for interpolation
- if (p_final_val.get_type() == Variant::INT) p_final_val = p_final_val.operator real_t();
+ if (p_final_val.get_type() == Variant::INT) {
+ p_final_val = p_final_val.operator real_t();
+ }
// Make sure the given objects are valid
ERR_FAIL_COND(p_object == nullptr);
@@ -1699,7 +1758,9 @@ void Tween::targeting_method(Object *p_object, StringName p_method, Object *p_in
ERR_FAIL_COND(error.error != Callable::CallError::CALL_OK);
// Convert initial INT values to FLOAT as they aer better for interpolation
- if (initial_val.get_type() == Variant::INT) initial_val = initial_val.operator real_t();
+ if (initial_val.get_type() == Variant::INT) {
+ initial_val = initial_val.operator real_t();
+ }
ERR_FAIL_COND(initial_val.get_type() != p_final_val.get_type());
// Build the new InterpolateData object
diff --git a/scene/animation/tween.h b/scene/animation/tween.h
index f74df50f68..668870c526 100644
--- a/scene/animation/tween.h
+++ b/scene/animation/tween.h
@@ -34,7 +34,6 @@
#include "scene/main/node.h"
class Tween : public Node {
-
GDCLASS(Tween, Node);
public:
diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp
index f612944a62..48f70e88cb 100644
--- a/scene/audio/audio_stream_player.cpp
+++ b/scene/audio/audio_stream_player.cpp
@@ -33,7 +33,6 @@
#include "core/engine.h"
void AudioStreamPlayer::_mix_to_bus(const AudioFrame *p_frames, int p_amount) {
-
int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus);
AudioFrame *targets[4] = { nullptr, nullptr, nullptr, nullptr };
@@ -57,8 +56,9 @@ void AudioStreamPlayer::_mix_to_bus(const AudioFrame *p_frames, int p_amount) {
}
for (int c = 0; c < 4; c++) {
- if (!targets[c])
+ if (!targets[c]) {
break;
+ }
for (int i = 0; i < p_amount; i++) {
targets[c][i] += p_frames[i];
}
@@ -66,7 +66,6 @@ void AudioStreamPlayer::_mix_to_bus(const AudioFrame *p_frames, int p_amount) {
}
void AudioStreamPlayer::_mix_internal(bool p_fadeout) {
-
//get data
AudioFrame *buffer = mix_buffer.ptrw();
int buffer_size = mix_buffer.size();
@@ -95,7 +94,6 @@ void AudioStreamPlayer::_mix_internal(bool p_fadeout) {
}
void AudioStreamPlayer::_mix_audio() {
-
if (use_fadeout) {
_mix_to_bus(fadeout_buffer.ptr(), fadeout_buffer.size());
use_fadeout = false;
@@ -122,7 +120,6 @@ void AudioStreamPlayer::_mix_audio() {
if (setseek >= 0.0 && !stop_has_priority) {
if (stream_playback->is_playing()) {
-
//fade out to avoid pops
_mix_internal(true);
}
@@ -138,9 +135,7 @@ void AudioStreamPlayer::_mix_audio() {
}
void AudioStreamPlayer::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
-
AudioServer::get_singleton()->add_callback(_mix_audios, this);
if (autoplay && !Engine::get_singleton()->is_editor_hint()) {
play();
@@ -148,7 +143,6 @@ void AudioStreamPlayer::_notification(int p_what) {
}
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
-
if (!active || (setseek < 0 && !stream_playback->is_playing())) {
active = false;
set_process_internal(false);
@@ -157,7 +151,6 @@ void AudioStreamPlayer::_notification(int p_what) {
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
AudioServer::get_singleton()->remove_callback(_mix_audios, this);
}
@@ -174,7 +167,6 @@ void AudioStreamPlayer::_notification(int p_what) {
}
void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) {
-
AudioServer::get_singleton()->lock();
if (active && stream_playback.is_valid() && !stream_paused) {
@@ -222,16 +214,14 @@ void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) {
}
Ref<AudioStream> AudioStreamPlayer::get_stream() const {
-
return stream;
}
void AudioStreamPlayer::set_volume_db(float p_volume) {
-
volume_db = p_volume;
}
-float AudioStreamPlayer::get_volume_db() const {
+float AudioStreamPlayer::get_volume_db() const {
return volume_db;
}
@@ -239,12 +229,12 @@ void AudioStreamPlayer::set_pitch_scale(float p_pitch_scale) {
ERR_FAIL_COND(p_pitch_scale <= 0.0);
pitch_scale = p_pitch_scale;
}
+
float AudioStreamPlayer::get_pitch_scale() const {
return pitch_scale;
}
void AudioStreamPlayer::play(float p_from_pos) {
-
if (stream_playback.is_valid()) {
//mix_volume_db = volume_db; do not reset volume ramp here, can cause clicks
setseek = p_from_pos;
@@ -255,14 +245,12 @@ void AudioStreamPlayer::play(float p_from_pos) {
}
void AudioStreamPlayer::seek(float p_seconds) {
-
if (stream_playback.is_valid()) {
setseek = p_seconds;
}
}
void AudioStreamPlayer::stop() {
-
if (stream_playback.is_valid() && active) {
setstop = true;
stop_has_priority = true;
@@ -270,7 +258,6 @@ void AudioStreamPlayer::stop() {
}
bool AudioStreamPlayer::is_playing() const {
-
if (stream_playback.is_valid()) {
return active && !setstop; //&& stream_playback->is_playing();
}
@@ -279,7 +266,6 @@ bool AudioStreamPlayer::is_playing() const {
}
float AudioStreamPlayer::get_playback_position() {
-
if (stream_playback.is_valid()) {
return stream_playback->get_playback_position();
}
@@ -288,14 +274,13 @@ float AudioStreamPlayer::get_playback_position() {
}
void AudioStreamPlayer::set_bus(const StringName &p_bus) {
-
//if audio is active, must lock this
AudioServer::get_singleton()->lock();
bus = p_bus;
AudioServer::get_singleton()->unlock();
}
-StringName AudioStreamPlayer::get_bus() const {
+StringName AudioStreamPlayer::get_bus() const {
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
if (AudioServer::get_singleton()->get_bus_name(i) == bus) {
return bus;
@@ -305,38 +290,34 @@ StringName AudioStreamPlayer::get_bus() const {
}
void AudioStreamPlayer::set_autoplay(bool p_enable) {
-
autoplay = p_enable;
}
-bool AudioStreamPlayer::is_autoplay_enabled() {
+bool AudioStreamPlayer::is_autoplay_enabled() {
return autoplay;
}
void AudioStreamPlayer::set_mix_target(MixTarget p_target) {
-
mix_target = p_target;
}
AudioStreamPlayer::MixTarget AudioStreamPlayer::get_mix_target() const {
-
return mix_target;
}
void AudioStreamPlayer::_set_playing(bool p_enable) {
-
- if (p_enable)
+ if (p_enable) {
play();
- else
+ } else {
stop();
+ }
}
-bool AudioStreamPlayer::_is_active() const {
+bool AudioStreamPlayer::_is_active() const {
return active;
}
void AudioStreamPlayer::set_stream_paused(bool p_pause) {
-
if (p_pause != stream_paused) {
stream_paused = p_pause;
stream_paused_fade = p_pause;
@@ -344,18 +325,16 @@ void AudioStreamPlayer::set_stream_paused(bool p_pause) {
}
bool AudioStreamPlayer::get_stream_paused() const {
-
return stream_paused;
}
void AudioStreamPlayer::_validate_property(PropertyInfo &property) const {
-
if (property.name == "bus") {
-
String options;
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
- if (i > 0)
+ if (i > 0) {
options += ",";
+ }
String name = AudioServer::get_singleton()->get_bus_name(i);
options += name;
}
@@ -365,7 +344,6 @@ void AudioStreamPlayer::_validate_property(PropertyInfo &property) const {
}
void AudioStreamPlayer::_bus_layout_changed() {
-
_change_notify();
}
@@ -374,7 +352,6 @@ Ref<AudioStreamPlayback> AudioStreamPlayer::get_stream_playback() {
}
void AudioStreamPlayer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_stream", "stream"), &AudioStreamPlayer::set_stream);
ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer::get_stream);
@@ -425,7 +402,6 @@ void AudioStreamPlayer::_bind_methods() {
}
AudioStreamPlayer::AudioStreamPlayer() {
-
mix_volume_db = 0;
pitch_scale = 1.0;
volume_db = 0;
diff --git a/scene/audio/audio_stream_player.h b/scene/audio/audio_stream_player.h
index 0f6d855d0e..6769f1bb48 100644
--- a/scene/audio/audio_stream_player.h
+++ b/scene/audio/audio_stream_player.h
@@ -35,7 +35,6 @@
#include "servers/audio/audio_stream.h"
class AudioStreamPlayer : public Node {
-
GDCLASS(AudioStreamPlayer, Node);
public:
diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp
index 8cb63c4ab5..f57c8e58db 100644
--- a/scene/debugger/scene_debugger.cpp
+++ b/scene/debugger/scene_debugger.cpp
@@ -48,8 +48,9 @@ void SceneDebugger::deinitialize() {
#ifdef DEBUG_ENABLED
if (LiveEditor::singleton) {
// Should be removed automatically when deiniting debugger, but just in case
- if (EngineDebugger::has_capture("scene"))
+ if (EngineDebugger::has_capture("scene")) {
EngineDebugger::unregister_message_capture("scene");
+ }
memdelete(LiveEditor::singleton);
LiveEditor::singleton = nullptr;
}
@@ -59,11 +60,13 @@ void SceneDebugger::deinitialize() {
#ifdef DEBUG_ENABLED
Error SceneDebugger::parse_message(void *p_user, const String &p_msg, const Array &p_args, bool &r_captured) {
SceneTree *scene_tree = SceneTree::get_singleton();
- if (!scene_tree)
+ if (!scene_tree) {
return ERR_UNCONFIGURED;
+ }
LiveEditor *live_editor = LiveEditor::get_singleton();
- if (!live_editor)
+ if (!live_editor) {
return ERR_UNCONFIGURED;
+ }
r_captured = true;
if (p_msg == "request_scene_tree") { // Scene tree
@@ -193,8 +196,9 @@ void SceneDebugger::_save_node(ObjectID id, const String &p_path) {
void SceneDebugger::_send_object_id(ObjectID p_id, int p_max_size) {
SceneDebuggerObject obj(p_id);
- if (obj.id.is_null())
+ if (obj.id.is_null()) {
return;
+ }
Array arr;
obj.serialize(arr);
@@ -202,10 +206,10 @@ void SceneDebugger::_send_object_id(ObjectID p_id, int p_max_size) {
}
void SceneDebugger::_set_object_property(ObjectID p_id, const String &p_property, const Variant &p_value) {
-
Object *obj = ObjectDB::get_instance(p_id);
- if (!obj)
+ if (!obj) {
return;
+ }
String prop_name = p_property;
if (p_property.begins_with("Members/")) {
@@ -218,17 +222,20 @@ void SceneDebugger::_set_object_property(ObjectID p_id, const String &p_property
void SceneDebugger::add_to_cache(const String &p_filename, Node *p_node) {
LiveEditor *debugger = LiveEditor::get_singleton();
- if (!debugger)
+ if (!debugger) {
return;
+ }
if (EngineDebugger::get_script_debugger() && p_filename != String()) {
debugger->live_scene_edit_cache[p_filename].insert(p_node);
}
}
+
void SceneDebugger::remove_from_cache(const String &p_filename, Node *p_node) {
LiveEditor *debugger = LiveEditor::get_singleton();
- if (!debugger)
+ if (!debugger) {
return;
+ }
Map<String, Set<Node *>> &edit_cache = debugger->live_scene_edit_cache;
Map<String, Set<Node *>>::Element *E = edit_cache.find(p_filename);
@@ -243,7 +250,6 @@ void SceneDebugger::remove_from_cache(const String &p_filename, Node *p_node) {
Map<Node *, Map<ObjectID, Node *>>::Element *F = remove_list.find(p_node);
if (F) {
for (Map<ObjectID, Node *>::Element *G = F->get().front(); G; G = G->next()) {
-
memdelete(G->get());
}
remove_list.erase(F);
@@ -254,8 +260,9 @@ void SceneDebugger::remove_from_cache(const String &p_filename, Node *p_node) {
SceneDebuggerObject::SceneDebuggerObject(ObjectID p_id) {
id = ObjectID();
Object *obj = ObjectDB::get_instance(p_id);
- if (!obj)
+ if (!obj) {
return;
+ }
id = p_id;
class_name = obj->get_class();
@@ -354,15 +361,6 @@ void SceneDebuggerObject::serialize(Array &r_arr, int p_max_size) {
RES res = var;
- if (var.get_type() == Variant::OBJECT && var.is_ref()) {
- REF r = var;
- if (r.is_valid()) {
- res = *r;
- } else {
- res = RES();
- }
- }
-
Array prop;
prop.push_back(pi.name);
prop.push_back(pi.type);
@@ -403,7 +401,6 @@ void SceneDebuggerObject::deserialize(const Array &p_arr) {
Array props = p_arr[2];
for (int i = 0; i < props.size(); i++) {
-
CHECK_TYPE(props[i], ARRAY);
Array prop = props[i];
@@ -485,8 +482,9 @@ LiveEditor *LiveEditor::get_singleton() {
void LiveEditor::_send_tree() {
SceneTree *scene_tree = SceneTree::get_singleton();
- if (!scene_tree)
+ if (!scene_tree) {
return;
+ }
Array arr;
// Encoded as a flat list depth fist.
@@ -496,42 +494,44 @@ void LiveEditor::_send_tree() {
}
void LiveEditor::_node_path_func(const NodePath &p_path, int p_id) {
-
live_edit_node_path_cache[p_id] = p_path;
}
void LiveEditor::_res_path_func(const String &p_path, int p_id) {
-
live_edit_resource_cache[p_id] = p_path;
}
void LiveEditor::_node_set_func(int p_id, const StringName &p_prop, const Variant &p_value) {
-
SceneTree *scene_tree = SceneTree::get_singleton();
- if (!scene_tree)
+ if (!scene_tree) {
return;
+ }
- if (!live_edit_node_path_cache.has(p_id))
+ if (!live_edit_node_path_cache.has(p_id)) {
return;
+ }
NodePath np = live_edit_node_path_cache[p_id];
Node *base = nullptr;
- if (scene_tree->root->has_node(live_edit_root))
+ if (scene_tree->root->has_node(live_edit_root)) {
base = scene_tree->root->get_node(live_edit_root);
+ }
Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene);
- if (!E)
+ if (!E) {
return; //scene not editable
+ }
for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) {
-
Node *n = F->get();
- if (base && !base->is_a_parent_of(n))
+ if (base && !base->is_a_parent_of(n)) {
continue;
+ }
- if (!n->has_node(np))
+ if (!n->has_node(np)) {
continue;
+ }
Node *n2 = n->get_node(np);
n2->set(p_prop, p_value);
@@ -539,110 +539,126 @@ void LiveEditor::_node_set_func(int p_id, const StringName &p_prop, const Varian
}
void LiveEditor::_node_set_res_func(int p_id, const StringName &p_prop, const String &p_value) {
-
RES r = ResourceLoader::load(p_value);
- if (!r.is_valid())
+ if (!r.is_valid()) {
return;
+ }
_node_set_func(p_id, p_prop, r);
}
+
void LiveEditor::_node_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) {
SceneTree *scene_tree = SceneTree::get_singleton();
- if (!scene_tree)
+ if (!scene_tree) {
return;
- if (!live_edit_node_path_cache.has(p_id))
+ }
+ if (!live_edit_node_path_cache.has(p_id)) {
return;
+ }
NodePath np = live_edit_node_path_cache[p_id];
Node *base = nullptr;
- if (scene_tree->root->has_node(live_edit_root))
+ if (scene_tree->root->has_node(live_edit_root)) {
base = scene_tree->root->get_node(live_edit_root);
+ }
Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene);
- if (!E)
+ if (!E) {
return; //scene not editable
+ }
for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) {
-
Node *n = F->get();
- if (base && !base->is_a_parent_of(n))
+ if (base && !base->is_a_parent_of(n)) {
continue;
+ }
- if (!n->has_node(np))
+ if (!n->has_node(np)) {
continue;
+ }
Node *n2 = n->get_node(np);
n2->call(p_method, VARIANT_ARG_PASS);
}
}
-void LiveEditor::_res_set_func(int p_id, const StringName &p_prop, const Variant &p_value) {
- if (!live_edit_resource_cache.has(p_id))
+void LiveEditor::_res_set_func(int p_id, const StringName &p_prop, const Variant &p_value) {
+ if (!live_edit_resource_cache.has(p_id)) {
return;
+ }
String resp = live_edit_resource_cache[p_id];
- if (!ResourceCache::has(resp))
+ if (!ResourceCache::has(resp)) {
return;
+ }
RES r = ResourceCache::get(resp);
- if (!r.is_valid())
+ if (!r.is_valid()) {
return;
+ }
r->set(p_prop, p_value);
}
-void LiveEditor::_res_set_res_func(int p_id, const StringName &p_prop, const String &p_value) {
+void LiveEditor::_res_set_res_func(int p_id, const StringName &p_prop, const String &p_value) {
RES r = ResourceLoader::load(p_value);
- if (!r.is_valid())
+ if (!r.is_valid()) {
return;
+ }
_res_set_func(p_id, p_prop, r);
}
-void LiveEditor::_res_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) {
- if (!live_edit_resource_cache.has(p_id))
+void LiveEditor::_res_call_func(int p_id, const StringName &p_method, VARIANT_ARG_DECLARE) {
+ if (!live_edit_resource_cache.has(p_id)) {
return;
+ }
String resp = live_edit_resource_cache[p_id];
- if (!ResourceCache::has(resp))
+ if (!ResourceCache::has(resp)) {
return;
+ }
RES r = ResourceCache::get(resp);
- if (!r.is_valid())
+ if (!r.is_valid()) {
return;
+ }
r->call(p_method, VARIANT_ARG_PASS);
}
void LiveEditor::_root_func(const NodePath &p_scene_path, const String &p_scene_from) {
-
live_edit_root = p_scene_path;
live_edit_scene = p_scene_from;
}
void LiveEditor::_create_node_func(const NodePath &p_parent, const String &p_type, const String &p_name) {
SceneTree *scene_tree = SceneTree::get_singleton();
- if (!scene_tree)
+ if (!scene_tree) {
return;
+ }
Node *base = nullptr;
- if (scene_tree->root->has_node(live_edit_root))
+ if (scene_tree->root->has_node(live_edit_root)) {
base = scene_tree->root->get_node(live_edit_root);
+ }
Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene);
- if (!E)
+ if (!E) {
return; //scene not editable
+ }
for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) {
-
Node *n = F->get();
- if (base && !base->is_a_parent_of(n))
+ if (base && !base->is_a_parent_of(n)) {
continue;
+ }
- if (!n->has_node(p_parent))
+ if (!n->has_node(p_parent)) {
continue;
+ }
Node *n2 = n->get_node(p_parent);
Node *no = Object::cast_to<Node>(ClassDB::instance(p_type));
@@ -654,33 +670,39 @@ void LiveEditor::_create_node_func(const NodePath &p_parent, const String &p_typ
n2->add_child(no);
}
}
+
void LiveEditor::_instance_node_func(const NodePath &p_parent, const String &p_path, const String &p_name) {
SceneTree *scene_tree = SceneTree::get_singleton();
- if (!scene_tree)
+ if (!scene_tree) {
return;
+ }
Ref<PackedScene> ps = ResourceLoader::load(p_path);
- if (!ps.is_valid())
+ if (!ps.is_valid()) {
return;
+ }
Node *base = nullptr;
- if (scene_tree->root->has_node(live_edit_root))
+ if (scene_tree->root->has_node(live_edit_root)) {
base = scene_tree->root->get_node(live_edit_root);
+ }
Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene);
- if (!E)
+ if (!E) {
return; //scene not editable
+ }
for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) {
-
Node *n = F->get();
- if (base && !base->is_a_parent_of(n))
+ if (base && !base->is_a_parent_of(n)) {
continue;
+ }
- if (!n->has_node(p_parent))
+ if (!n->has_node(p_parent)) {
continue;
+ }
Node *n2 = n->get_node(p_parent);
Node *no = ps->instance();
@@ -692,30 +714,35 @@ void LiveEditor::_instance_node_func(const NodePath &p_parent, const String &p_p
n2->add_child(no);
}
}
+
void LiveEditor::_remove_node_func(const NodePath &p_at) {
SceneTree *scene_tree = SceneTree::get_singleton();
- if (!scene_tree)
+ if (!scene_tree) {
return;
+ }
Node *base = nullptr;
- if (scene_tree->root->has_node(live_edit_root))
+ if (scene_tree->root->has_node(live_edit_root)) {
base = scene_tree->root->get_node(live_edit_root);
+ }
Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene);
- if (!E)
+ if (!E) {
return; //scene not editable
+ }
for (Set<Node *>::Element *F = E->get().front(); F;) {
-
Set<Node *>::Element *N = F->next();
Node *n = F->get();
- if (base && !base->is_a_parent_of(n))
+ if (base && !base->is_a_parent_of(n)) {
continue;
+ }
- if (!n->has_node(p_at))
+ if (!n->has_node(p_at)) {
continue;
+ }
Node *n2 = n->get_node(p_at);
memdelete(n2);
@@ -723,30 +750,35 @@ void LiveEditor::_remove_node_func(const NodePath &p_at) {
F = N;
}
}
+
void LiveEditor::_remove_and_keep_node_func(const NodePath &p_at, ObjectID p_keep_id) {
SceneTree *scene_tree = SceneTree::get_singleton();
- if (!scene_tree)
+ if (!scene_tree) {
return;
+ }
Node *base = nullptr;
- if (scene_tree->root->has_node(live_edit_root))
+ if (scene_tree->root->has_node(live_edit_root)) {
base = scene_tree->root->get_node(live_edit_root);
+ }
Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene);
- if (!E)
+ if (!E) {
return; //scene not editable
+ }
for (Set<Node *>::Element *F = E->get().front(); F;) {
-
Set<Node *>::Element *N = F->next();
Node *n = F->get();
- if (base && !base->is_a_parent_of(n))
+ if (base && !base->is_a_parent_of(n)) {
continue;
+ }
- if (!n->has_node(p_at))
+ if (!n->has_node(p_at)) {
continue;
+ }
Node *n2 = n->get_node(p_at);
@@ -757,41 +789,48 @@ void LiveEditor::_remove_and_keep_node_func(const NodePath &p_at, ObjectID p_kee
F = N;
}
}
+
void LiveEditor::_restore_node_func(ObjectID p_id, const NodePath &p_at, int p_at_pos) {
SceneTree *scene_tree = SceneTree::get_singleton();
- if (!scene_tree)
+ if (!scene_tree) {
return;
+ }
Node *base = nullptr;
- if (scene_tree->root->has_node(live_edit_root))
+ if (scene_tree->root->has_node(live_edit_root)) {
base = scene_tree->root->get_node(live_edit_root);
+ }
Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene);
- if (!E)
+ if (!E) {
return; //scene not editable
+ }
for (Set<Node *>::Element *F = E->get().front(); F;) {
-
Set<Node *>::Element *N = F->next();
Node *n = F->get();
- if (base && !base->is_a_parent_of(n))
+ if (base && !base->is_a_parent_of(n)) {
continue;
+ }
- if (!n->has_node(p_at))
+ if (!n->has_node(p_at)) {
continue;
+ }
Node *n2 = n->get_node(p_at);
Map<Node *, Map<ObjectID, Node *>>::Element *EN = live_edit_remove_list.find(n);
- if (!EN)
+ if (!EN) {
continue;
+ }
Map<ObjectID, Node *>::Element *FN = EN->get().find(p_id);
- if (!FN)
+ if (!FN) {
continue;
+ }
n2->add_child(FN->get());
EN->get().erase(FN);
@@ -803,73 +842,86 @@ void LiveEditor::_restore_node_func(ObjectID p_id, const NodePath &p_at, int p_a
F = N;
}
}
+
void LiveEditor::_duplicate_node_func(const NodePath &p_at, const String &p_new_name) {
SceneTree *scene_tree = SceneTree::get_singleton();
- if (!scene_tree)
+ if (!scene_tree) {
return;
+ }
Node *base = nullptr;
- if (scene_tree->root->has_node(live_edit_root))
+ if (scene_tree->root->has_node(live_edit_root)) {
base = scene_tree->root->get_node(live_edit_root);
+ }
Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene);
- if (!E)
+ if (!E) {
return; //scene not editable
+ }
for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) {
-
Node *n = F->get();
- if (base && !base->is_a_parent_of(n))
+ if (base && !base->is_a_parent_of(n)) {
continue;
+ }
- if (!n->has_node(p_at))
+ if (!n->has_node(p_at)) {
continue;
+ }
Node *n2 = n->get_node(p_at);
Node *dup = n2->duplicate(Node::DUPLICATE_SIGNALS | Node::DUPLICATE_GROUPS | Node::DUPLICATE_SCRIPTS);
- if (!dup)
+ if (!dup) {
continue;
+ }
dup->set_name(p_new_name);
n2->get_parent()->add_child(dup);
}
}
+
void LiveEditor::_reparent_node_func(const NodePath &p_at, const NodePath &p_new_place, const String &p_new_name, int p_at_pos) {
SceneTree *scene_tree = SceneTree::get_singleton();
- if (!scene_tree)
+ if (!scene_tree) {
return;
+ }
Node *base = nullptr;
- if (scene_tree->root->has_node(live_edit_root))
+ if (scene_tree->root->has_node(live_edit_root)) {
base = scene_tree->root->get_node(live_edit_root);
+ }
Map<String, Set<Node *>>::Element *E = live_scene_edit_cache.find(live_edit_scene);
- if (!E)
+ if (!E) {
return; //scene not editable
+ }
for (Set<Node *>::Element *F = E->get().front(); F; F = F->next()) {
-
Node *n = F->get();
- if (base && !base->is_a_parent_of(n))
+ if (base && !base->is_a_parent_of(n)) {
continue;
+ }
- if (!n->has_node(p_at))
+ if (!n->has_node(p_at)) {
continue;
+ }
Node *nfrom = n->get_node(p_at);
- if (!n->has_node(p_new_place))
+ if (!n->has_node(p_new_place)) {
continue;
+ }
Node *nto = n->get_node(p_new_place);
nfrom->get_parent()->remove_child(nfrom);
nfrom->set_name(p_new_name);
nto->add_child(nfrom);
- if (p_at_pos >= 0)
+ if (p_at_pos >= 0) {
nto->move_child(nfrom, p_at_pos);
+ }
}
}
diff --git a/scene/debugger/scene_debugger.h b/scene/debugger/scene_debugger.h
index e295510960..a2bafde039 100644
--- a/scene/debugger/scene_debugger.h
+++ b/scene/debugger/scene_debugger.h
@@ -39,7 +39,6 @@
class Script;
class SceneDebugger {
-
public:
static void initialize();
static void deinitialize();
@@ -59,7 +58,6 @@ public:
#ifdef DEBUG_ENABLED
class SceneDebuggerObject {
-
private:
void _parse_script_properties(Script *p_script, ScriptInstance *p_instance);
@@ -77,7 +75,6 @@ public:
};
class SceneDebuggerTree {
-
public:
struct RemoteNode {
int child_count;
@@ -100,11 +97,10 @@ public:
void serialize(Array &r_arr);
void deserialize(const Array &p_arr);
SceneDebuggerTree(Node *p_root);
- SceneDebuggerTree(){};
+ SceneDebuggerTree() {}
};
class LiveEditor {
-
private:
friend class SceneDebugger;
Map<int, NodePath> live_edit_node_path_cache;
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 1cdc6f8057..d8229b5f43 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -35,26 +35,27 @@
#include "scene/scene_string_names.h"
void BaseButton::_unpress_group() {
-
- if (!button_group.is_valid())
+ if (!button_group.is_valid()) {
return;
+ }
if (toggle_mode) {
status.pressed = true;
}
for (Set<BaseButton *>::Element *E = button_group->buttons.front(); E; E = E->next()) {
- if (E->get() == this)
+ if (E->get() == this) {
continue;
+ }
E->get()->set_pressed(false);
}
}
void BaseButton::_gui_input(Ref<InputEvent> p_event) {
-
- if (status.disabled) // no interaction with disabled button
+ if (status.disabled) { // no interaction with disabled button
return;
+ }
Ref<InputEventMouseButton> mouse_button = p_event;
bool ui_accept = p_event->is_action("ui_accept") && !p_event->is_echo();
@@ -78,9 +79,7 @@ void BaseButton::_gui_input(Ref<InputEvent> p_event) {
}
void BaseButton::_notification(int p_what) {
-
if (p_what == NOTIFICATION_MOUSE_ENTER) {
-
status.hovering = true;
update();
}
@@ -90,7 +89,6 @@ void BaseButton::_notification(int p_what) {
update();
}
if (p_what == NOTIFICATION_DRAG_BEGIN || p_what == NOTIFICATION_SCROLL_BEGIN) {
-
if (status.press_attempt) {
status.press_attempt = false;
update();
@@ -98,13 +96,11 @@ void BaseButton::_notification(int p_what) {
}
if (p_what == NOTIFICATION_FOCUS_ENTER) {
-
status.hovering = true;
update();
}
if (p_what == NOTIFICATION_FOCUS_EXIT) {
-
if (status.press_attempt) {
status.press_attempt = false;
status.hovering = false;
@@ -116,7 +112,6 @@ void BaseButton::_notification(int p_what) {
}
if (p_what == NOTIFICATION_EXIT_TREE || (p_what == NOTIFICATION_VISIBILITY_CHANGED && !is_visible_in_tree())) {
-
if (!toggle_mode) {
status.pressed = false;
}
@@ -127,7 +122,6 @@ void BaseButton::_notification(int p_what) {
}
void BaseButton::_pressed() {
-
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_pressed);
}
@@ -136,7 +130,6 @@ void BaseButton::_pressed() {
}
void BaseButton::_toggled(bool p_pressed) {
-
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_toggled, p_pressed);
}
@@ -145,7 +138,6 @@ void BaseButton::_toggled(bool p_pressed) {
}
void BaseButton::on_action_event(Ref<InputEvent> p_event) {
-
if (p_event->is_pressed()) {
status.press_attempt = true;
status.pressing_inside = true;
@@ -194,8 +186,9 @@ void BaseButton::toggled(bool p_pressed) {
}
void BaseButton::set_disabled(bool p_disabled) {
- if (status.disabled == p_disabled)
+ if (status.disabled == p_disabled) {
return;
+ }
status.disabled = p_disabled;
if (p_disabled) {
@@ -210,16 +203,16 @@ void BaseButton::set_disabled(bool p_disabled) {
}
bool BaseButton::is_disabled() const {
-
return status.disabled;
}
void BaseButton::set_pressed(bool p_pressed) {
-
- if (!toggle_mode)
+ if (!toggle_mode) {
return;
- if (status.pressed == p_pressed)
+ }
+ if (status.pressed == p_pressed) {
return;
+ }
_change_notify("pressed");
status.pressed = p_pressed;
@@ -232,29 +225,26 @@ void BaseButton::set_pressed(bool p_pressed) {
}
bool BaseButton::is_pressing() const {
-
return status.press_attempt;
}
bool BaseButton::is_pressed() const {
-
return toggle_mode ? status.pressed : status.press_attempt;
}
bool BaseButton::is_hovered() const {
-
return status.hovering;
}
BaseButton::DrawMode BaseButton::get_draw_mode() const {
-
if (status.disabled) {
return DRAW_DISABLED;
};
if (!status.press_attempt && status.hovering) {
- if (status.pressed)
+ if (status.pressed) {
return DRAW_HOVER_PRESSED;
+ }
return DRAW_HOVER;
} else {
@@ -262,66 +252,57 @@ BaseButton::DrawMode BaseButton::get_draw_mode() const {
bool pressing;
if (status.press_attempt) {
-
pressing = (status.pressing_inside || keep_pressed_outside);
- if (status.pressed)
+ if (status.pressed) {
pressing = !pressing;
+ }
} else {
-
pressing = status.pressed;
}
- if (pressing)
+ if (pressing) {
return DRAW_PRESSED;
- else
+ } else {
return DRAW_NORMAL;
+ }
}
return DRAW_NORMAL;
}
void BaseButton::set_toggle_mode(bool p_on) {
-
toggle_mode = p_on;
}
bool BaseButton::is_toggle_mode() const {
-
return toggle_mode;
}
void BaseButton::set_shortcut_in_tooltip(bool p_on) {
-
shortcut_in_tooltip = p_on;
}
bool BaseButton::is_shortcut_in_tooltip_enabled() const {
-
return shortcut_in_tooltip;
}
void BaseButton::set_action_mode(ActionMode p_mode) {
-
action_mode = p_mode;
}
BaseButton::ActionMode BaseButton::get_action_mode() const {
-
return action_mode;
}
void BaseButton::set_button_mask(int p_mask) {
-
button_mask = p_mask;
}
int BaseButton::get_button_mask() const {
-
return button_mask;
}
void BaseButton::set_enabled_focus_mode(FocusMode p_mode) {
-
enabled_focus_mode = p_mode;
if (!status.disabled) {
set_focus_mode(p_mode);
@@ -329,22 +310,18 @@ void BaseButton::set_enabled_focus_mode(FocusMode p_mode) {
}
Control::FocusMode BaseButton::get_enabled_focus_mode() const {
-
return enabled_focus_mode;
}
void BaseButton::set_keep_pressed_outside(bool p_on) {
-
keep_pressed_outside = p_on;
}
bool BaseButton::is_keep_pressed_outside() const {
-
return keep_pressed_outside;
}
void BaseButton::set_shortcut(const Ref<ShortCut> &p_shortcut) {
-
shortcut = p_shortcut;
set_process_unhandled_input(shortcut.is_valid());
}
@@ -354,15 +331,12 @@ Ref<ShortCut> BaseButton::get_shortcut() const {
}
void BaseButton::_unhandled_input(Ref<InputEvent> p_event) {
-
if (!is_disabled() && is_visible_in_tree() && !p_event->is_echo() && shortcut.is_valid() && shortcut->is_shortcut(p_event)) {
-
on_action_event(p_event);
}
}
String BaseButton::get_tooltip(const Point2 &p_pos) const {
-
String tooltip = Control::get_tooltip(p_pos);
if (shortcut_in_tooltip && shortcut.is_valid() && shortcut->is_valid()) {
String text = shortcut->get_name() + " (" + shortcut->get_as_text() + ")";
@@ -375,7 +349,6 @@ String BaseButton::get_tooltip(const Point2 &p_pos) const {
}
void BaseButton::set_button_group(const Ref<ButtonGroup> &p_group) {
-
if (button_group.is_valid()) {
button_group->buttons.erase(this);
}
@@ -390,12 +363,10 @@ void BaseButton::set_button_group(const Ref<ButtonGroup> &p_group) {
}
Ref<ButtonGroup> BaseButton::get_button_group() const {
-
return button_group;
}
void BaseButton::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &BaseButton::_gui_input);
ClassDB::bind_method(D_METHOD("_unhandled_input"), &BaseButton::_unhandled_input);
ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &BaseButton::set_pressed);
@@ -452,7 +423,6 @@ void BaseButton::_bind_methods() {
}
BaseButton::BaseButton() {
-
toggle_mode = false;
shortcut_in_tooltip = true;
keep_pressed_outside = false;
@@ -468,21 +438,18 @@ BaseButton::BaseButton() {
}
BaseButton::~BaseButton() {
-
if (button_group.is_valid()) {
button_group->buttons.erase(this);
}
}
void ButtonGroup::get_buttons(List<BaseButton *> *r_buttons) {
-
for (Set<BaseButton *>::Element *E = buttons.front(); E; E = E->next()) {
r_buttons->push_back(E->get());
}
}
Array ButtonGroup::_get_buttons() {
-
Array btns;
for (Set<BaseButton *>::Element *E = buttons.front(); E; E = E->next()) {
btns.push_back(E->get());
@@ -492,22 +459,20 @@ Array ButtonGroup::_get_buttons() {
}
BaseButton *ButtonGroup::get_pressed_button() {
-
for (Set<BaseButton *>::Element *E = buttons.front(); E; E = E->next()) {
- if (E->get()->is_pressed())
+ if (E->get()->is_pressed()) {
return E->get();
+ }
}
return nullptr;
}
void ButtonGroup::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_pressed_button"), &ButtonGroup::get_pressed_button);
ClassDB::bind_method(D_METHOD("get_buttons"), &ButtonGroup::_get_buttons);
}
ButtonGroup::ButtonGroup() {
-
set_local_to_scene(true);
}
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index 21757488a6..05a975e266 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -36,7 +36,6 @@
class ButtonGroup;
class BaseButton : public Control {
-
GDCLASS(BaseButton, Control);
public:
@@ -55,7 +54,6 @@ private:
ActionMode action_mode;
struct Status {
-
bool pressed;
bool hovering;
bool press_attempt;
@@ -136,7 +134,6 @@ VARIANT_ENUM_CAST(BaseButton::DrawMode)
VARIANT_ENUM_CAST(BaseButton::ActionMode)
class ButtonGroup : public Resource {
-
GDCLASS(ButtonGroup, Resource);
friend class BaseButton;
Set<BaseButton *> buttons;
diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp
index 0da6e0fdfa..75d04dba61 100644
--- a/scene/gui/box_container.cpp
+++ b/scene/gui/box_container.cpp
@@ -33,14 +33,12 @@
#include "margin_container.h"
struct _MinSizeCache {
-
int min_size;
bool will_stretch;
int final_size;
};
void BoxContainer::_resort() {
-
/** First pass, determine minimum size AND amount of stretchable elements */
Size2i new_size = get_size();
@@ -56,10 +54,12 @@ void BoxContainer::_resort() {
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible_in_tree())
+ if (!c || !c->is_visible_in_tree()) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
Size2i size = c->get_combined_minimum_size();
_MinSizeCache msc;
@@ -84,8 +84,9 @@ void BoxContainer::_resort() {
children_count++;
}
- if (children_count == 0)
+ if (children_count == 0) {
return;
+ }
int stretch_max = (vertical ? new_size.height : new_size.width) - (children_count - 1) * sep;
int stretch_diff = stretch_max - stretch_min;
@@ -105,12 +106,13 @@ void BoxContainer::_resort() {
bool refit_successful = true; //assume refit-test will go well
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible_in_tree())
+ if (!c || !c->is_visible_in_tree()) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
ERR_FAIL_COND(!min_size_cache.has(c));
_MinSizeCache &msc = min_size_cache[c];
@@ -134,8 +136,9 @@ void BoxContainer::_resort() {
}
}
- if (refit_successful) //uf refit went well, break
+ if (refit_successful) { //uf refit went well, break
break;
+ }
}
/** Final pass, draw and stretch elements **/
@@ -158,19 +161,21 @@ void BoxContainer::_resort() {
int idx = 0;
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible_in_tree())
+ if (!c || !c->is_visible_in_tree()) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
_MinSizeCache &msc = min_size_cache[c];
- if (first)
+ if (first) {
first = false;
- else
+ } else {
ofs += sep;
+ }
int from = ofs;
int to = ofs + msc.final_size;
@@ -187,10 +192,8 @@ void BoxContainer::_resort() {
Rect2 rect;
if (vertical) {
-
rect = Rect2(0, from, new_size.width, size);
} else {
-
rect = Rect2(from, 0, size, new_size.height);
}
@@ -202,7 +205,6 @@ void BoxContainer::_resort() {
}
Size2 BoxContainer::get_minimum_size() const {
-
/* Calculate MINIMUM SIZE */
Size2i minimum;
@@ -212,10 +214,12 @@ Size2 BoxContainer::get_minimum_size() const {
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
if (!c->is_visible()) {
continue;
@@ -247,15 +251,11 @@ Size2 BoxContainer::get_minimum_size() const {
}
void BoxContainer::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_SORT_CHILDREN: {
-
_resort();
} break;
case NOTIFICATION_THEME_CHANGED: {
-
minimum_size_changed();
} break;
}
@@ -271,28 +271,27 @@ BoxContainer::AlignMode BoxContainer::get_alignment() const {
}
void BoxContainer::add_spacer(bool p_begin) {
-
Control *c = memnew(Control);
c->set_mouse_filter(MOUSE_FILTER_PASS); //allow spacer to pass mouse events
- if (vertical)
+ if (vertical) {
c->set_v_size_flags(SIZE_EXPAND_FILL);
- else
+ } else {
c->set_h_size_flags(SIZE_EXPAND_FILL);
+ }
add_child(c);
- if (p_begin)
+ if (p_begin) {
move_child(c, 0);
+ }
}
BoxContainer::BoxContainer(bool p_vertical) {
-
vertical = p_vertical;
align = ALIGN_BEGIN;
}
void BoxContainer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_spacer", "begin"), &BoxContainer::add_spacer);
ClassDB::bind_method(D_METHOD("get_alignment"), &BoxContainer::get_alignment);
ClassDB::bind_method(D_METHOD("set_alignment", "alignment"), &BoxContainer::set_alignment);
@@ -305,7 +304,6 @@ void BoxContainer::_bind_methods() {
}
MarginContainer *VBoxContainer::add_margin_child(const String &p_label, Control *p_control, bool p_expand) {
-
Label *l = memnew(Label);
l->set_text(p_label);
add_child(l);
@@ -313,8 +311,9 @@ MarginContainer *VBoxContainer::add_margin_child(const String &p_label, Control
mc->add_theme_constant_override("margin_left", 0);
mc->add_child(p_control);
add_child(mc);
- if (p_expand)
+ if (p_expand) {
mc->set_v_size_flags(SIZE_EXPAND_FILL);
+ }
return mc;
}
diff --git a/scene/gui/box_container.h b/scene/gui/box_container.h
index 0d7deda364..cc6f6349df 100644
--- a/scene/gui/box_container.h
+++ b/scene/gui/box_container.h
@@ -34,7 +34,6 @@
#include "scene/gui/container.h"
class BoxContainer : public Container {
-
GDCLASS(BoxContainer, Container);
public:
@@ -67,7 +66,6 @@ public:
};
class HBoxContainer : public BoxContainer {
-
GDCLASS(HBoxContainer, BoxContainer);
public:
@@ -77,7 +75,6 @@ public:
class MarginContainer;
class VBoxContainer : public BoxContainer {
-
GDCLASS(VBoxContainer, BoxContainer);
public:
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index 1f8487c173..e400801b66 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -34,24 +34,25 @@
#include "servers/rendering_server.h"
Size2 Button::get_minimum_size() const {
-
Size2 minsize = get_theme_font("font")->get_string_size(xl_text);
- if (clip_text)
+ if (clip_text) {
minsize.width = 0;
+ }
if (!expand_icon) {
Ref<Texture2D> _icon;
- if (icon.is_null() && has_theme_icon("icon"))
+ if (icon.is_null() && has_theme_icon("icon")) {
_icon = Control::get_theme_icon("icon");
- else
+ } else {
_icon = icon;
+ }
if (!_icon.is_null()) {
-
minsize.height = MAX(minsize.height, _icon->get_height());
minsize.width += _icon->get_width();
- if (xl_text != "")
+ if (xl_text != "") {
minsize.width += get_theme_constant("hseparation");
+ }
}
}
@@ -59,21 +60,17 @@ Size2 Button::get_minimum_size() const {
}
void Button::_set_internal_margin(Margin p_margin, float p_value) {
-
_internal_margin[p_margin] = p_value;
}
void Button::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_TRANSLATION_CHANGED: {
-
xl_text = tr(text);
minimum_size_changed();
update();
} break;
case NOTIFICATION_DRAW: {
-
RID ci = get_canvas_item();
Size2 size = get_size();
Color color;
@@ -83,82 +80,88 @@ void Button::_notification(int p_what) {
switch (get_draw_mode()) {
case DRAW_NORMAL: {
-
style = get_theme_stylebox("normal");
- if (!flat)
+ if (!flat) {
style->draw(ci, Rect2(Point2(0, 0), size));
+ }
color = get_theme_color("font_color");
- if (has_theme_color("icon_color_normal"))
+ if (has_theme_color("icon_color_normal")) {
color_icon = get_theme_color("icon_color_normal");
+ }
} break;
case DRAW_HOVER_PRESSED: {
-
if (has_theme_stylebox("hover_pressed") && has_theme_stylebox_override("hover_pressed")) {
style = get_theme_stylebox("hover_pressed");
- if (!flat)
+ if (!flat) {
style->draw(ci, Rect2(Point2(0, 0), size));
- if (has_theme_color("font_color_hover_pressed"))
+ }
+ if (has_theme_color("font_color_hover_pressed")) {
color = get_theme_color("font_color_hover_pressed");
- else
+ } else {
color = get_theme_color("font_color");
- if (has_theme_color("icon_color_hover_pressed"))
+ }
+ if (has_theme_color("icon_color_hover_pressed")) {
color_icon = get_theme_color("icon_color_hover_pressed");
+ }
break;
}
[[fallthrough]];
}
case DRAW_PRESSED: {
-
style = get_theme_stylebox("pressed");
- if (!flat)
+ if (!flat) {
style->draw(ci, Rect2(Point2(0, 0), size));
- if (has_theme_color("font_color_pressed"))
+ }
+ if (has_theme_color("font_color_pressed")) {
color = get_theme_color("font_color_pressed");
- else
+ } else {
color = get_theme_color("font_color");
- if (has_theme_color("icon_color_pressed"))
+ }
+ if (has_theme_color("icon_color_pressed")) {
color_icon = get_theme_color("icon_color_pressed");
+ }
} break;
case DRAW_HOVER: {
-
style = get_theme_stylebox("hover");
- if (!flat)
+ if (!flat) {
style->draw(ci, Rect2(Point2(0, 0), size));
+ }
color = get_theme_color("font_color_hover");
- if (has_theme_color("icon_color_hover"))
+ if (has_theme_color("icon_color_hover")) {
color_icon = get_theme_color("icon_color_hover");
+ }
} break;
case DRAW_DISABLED: {
-
style = get_theme_stylebox("disabled");
- if (!flat)
+ if (!flat) {
style->draw(ci, Rect2(Point2(0, 0), size));
+ }
color = get_theme_color("font_color_disabled");
- if (has_theme_color("icon_color_disabled"))
+ if (has_theme_color("icon_color_disabled")) {
color_icon = get_theme_color("icon_color_disabled");
+ }
} break;
}
if (has_focus()) {
-
Ref<StyleBox> style2 = get_theme_stylebox("focus");
style2->draw(ci, Rect2(Point2(), size));
}
Ref<Font> font = get_theme_font("font");
Ref<Texture2D> _icon;
- if (icon.is_null() && has_theme_icon("icon"))
+ if (icon.is_null() && has_theme_icon("icon")) {
_icon = Control::get_theme_icon("icon");
- else
+ } else {
_icon = icon;
+ }
Rect2 icon_region = Rect2();
if (!_icon.is_null()) {
-
int valign = size.height - style->get_minimum_size().y;
if (is_disabled()) {
color_icon.a = 0.4;
@@ -172,8 +175,9 @@ void Button::_notification(int p_what) {
if (expand_icon) {
Size2 _size = get_size() - style->get_offset() * 2;
_size.width -= get_theme_constant("hseparation") + icon_ofs_region;
- if (!clip_text)
+ if (!clip_text) {
_size.width -= get_theme_font("font")->get_string_size(xl_text).width;
+ }
float icon_width = _icon->get_width() * _size.height / _icon->get_height();
float icon_height = _size.height;
@@ -209,8 +213,9 @@ void Button::_notification(int p_what) {
text_ofs.y += style->get_offset().y;
} break;
case ALIGN_CENTER: {
- if (text_ofs.x < 0)
+ if (text_ofs.x < 0) {
text_ofs.x = 0;
+ }
text_ofs += icon_ofs;
text_ofs += style->get_offset();
} break;
@@ -235,24 +240,24 @@ void Button::_notification(int p_what) {
}
void Button::set_text(const String &p_text) {
-
- if (text == p_text)
+ if (text == p_text) {
return;
+ }
text = p_text;
xl_text = tr(p_text);
update();
_change_notify("text");
minimum_size_changed();
}
-String Button::get_text() const {
+String Button::get_text() const {
return text;
}
void Button::set_icon(const Ref<Texture2D> &p_icon) {
-
- if (icon == p_icon)
+ if (icon == p_icon) {
return;
+ }
icon = p_icon;
update();
_change_notify("icon");
@@ -260,59 +265,49 @@ void Button::set_icon(const Ref<Texture2D> &p_icon) {
}
Ref<Texture2D> Button::get_icon() const {
-
return icon;
}
void Button::set_expand_icon(bool p_expand_icon) {
-
expand_icon = p_expand_icon;
update();
minimum_size_changed();
}
bool Button::is_expand_icon() const {
-
return expand_icon;
}
void Button::set_flat(bool p_flat) {
-
flat = p_flat;
update();
_change_notify("flat");
}
bool Button::is_flat() const {
-
return flat;
}
void Button::set_clip_text(bool p_clip_text) {
-
clip_text = p_clip_text;
update();
minimum_size_changed();
}
bool Button::get_clip_text() const {
-
return clip_text;
}
void Button::set_text_align(TextAlign p_align) {
-
align = p_align;
update();
}
Button::TextAlign Button::get_text_align() const {
-
return align;
}
void Button::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_text", "text"), &Button::set_text);
ClassDB::bind_method(D_METHOD("get_text"), &Button::get_text);
ClassDB::bind_method(D_METHOD("set_button_icon", "texture"), &Button::set_icon);
@@ -339,7 +334,6 @@ void Button::_bind_methods() {
}
Button::Button(const String &p_text) {
-
flat = false;
clip_text = false;
expand_icon = false;
diff --git a/scene/gui/button.h b/scene/gui/button.h
index 3135b98578..e757badd3e 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -34,7 +34,6 @@
#include "scene/gui/base_button.h"
class Button : public BaseButton {
-
GDCLASS(Button, BaseButton);
public:
diff --git a/scene/gui/center_container.cpp b/scene/gui/center_container.cpp
index 64d6885bc8..f8f9bec3d7 100644
--- a/scene/gui/center_container.cpp
+++ b/scene/gui/center_container.cpp
@@ -31,19 +31,21 @@
#include "center_container.h"
Size2 CenterContainer::get_minimum_size() const {
-
- if (use_top_left)
+ if (use_top_left) {
return Size2();
+ }
Size2 ms;
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
- if (!c->is_visible())
+ }
+ if (!c->is_visible()) {
continue;
+ }
Size2 minsize = c->get_combined_minimum_size();
ms.width = MAX(ms.width, minsize.width);
ms.height = MAX(ms.height, minsize.height);
@@ -53,7 +55,6 @@ Size2 CenterContainer::get_minimum_size() const {
}
void CenterContainer::set_use_top_left(bool p_enable) {
-
if (use_top_left == p_enable) {
return;
}
@@ -65,22 +66,20 @@ void CenterContainer::set_use_top_left(bool p_enable) {
}
bool CenterContainer::is_using_top_left() const {
-
return use_top_left;
}
void CenterContainer::_notification(int p_what) {
-
if (p_what == NOTIFICATION_SORT_CHILDREN) {
-
Size2 size = get_size();
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
Size2 minsize = c->get_combined_minimum_size();
Point2 ofs = use_top_left ? (-minsize * 0.5).floor() : ((size - minsize) / 2.0).floor();
@@ -90,7 +89,6 @@ void CenterContainer::_notification(int p_what) {
}
void CenterContainer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_use_top_left", "enable"), &CenterContainer::set_use_top_left);
ClassDB::bind_method(D_METHOD("is_using_top_left"), &CenterContainer::is_using_top_left);
@@ -98,6 +96,5 @@ void CenterContainer::_bind_methods() {
}
CenterContainer::CenterContainer() {
-
use_top_left = false;
}
diff --git a/scene/gui/center_container.h b/scene/gui/center_container.h
index 98733f384d..ae9f87db16 100644
--- a/scene/gui/center_container.h
+++ b/scene/gui/center_container.h
@@ -34,7 +34,6 @@
#include "scene/gui/container.h"
class CenterContainer : public Container {
-
GDCLASS(CenterContainer, Container);
bool use_top_left;
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index 470450e3ed..df6f38f65d 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -39,19 +39,22 @@ Size2 CheckBox::get_icon_size() const {
Ref<Texture2D> radio_unchecked = Control::get_theme_icon("radio_unchecked");
Size2 tex_size = Size2(0, 0);
- if (!checked.is_null())
+ if (!checked.is_null()) {
tex_size = Size2(checked->get_width(), checked->get_height());
- if (!unchecked.is_null())
+ }
+ if (!unchecked.is_null()) {
tex_size = Size2(MAX(tex_size.width, unchecked->get_width()), MAX(tex_size.height, unchecked->get_height()));
- if (!radio_checked.is_null())
+ }
+ if (!radio_checked.is_null()) {
tex_size = Size2(MAX(tex_size.width, radio_checked->get_width()), MAX(tex_size.height, radio_checked->get_height()));
- if (!radio_unchecked.is_null())
+ }
+ if (!radio_unchecked.is_null()) {
tex_size = Size2(MAX(tex_size.width, radio_unchecked->get_width()), MAX(tex_size.height, radio_unchecked->get_height()));
+ }
return tex_size;
}
Size2 CheckBox::get_minimum_size() const {
-
Size2 minsize = Button::get_minimum_size();
Size2 tex_size = get_icon_size();
minsize.width += tex_size.width;
@@ -65,12 +68,9 @@ Size2 CheckBox::get_minimum_size() const {
}
void CheckBox::_notification(int p_what) {
-
if (p_what == NOTIFICATION_THEME_CHANGED) {
-
_set_internal_margin(MARGIN_LEFT, get_icon_size().width);
} else if (p_what == NOTIFICATION_DRAW) {
-
RID ci = get_canvas_item();
Ref<Texture2D> on = Control::get_theme_icon(is_radio() ? "radio_checked" : "checked");
@@ -81,15 +81,15 @@ void CheckBox::_notification(int p_what) {
ofs.x = sb->get_margin(MARGIN_LEFT);
ofs.y = int((get_size().height - get_icon_size().height) / 2) + get_theme_constant("check_vadjust");
- if (is_pressed())
+ if (is_pressed()) {
on->draw(ci, ofs);
- else
+ } else {
off->draw(ci, ofs);
+ }
}
}
bool CheckBox::is_radio() {
-
return get_button_group().is_valid();
}
diff --git a/scene/gui/check_box.h b/scene/gui/check_box.h
index 7c8f8c11d6..58f7cce55e 100644
--- a/scene/gui/check_box.h
+++ b/scene/gui/check_box.h
@@ -36,7 +36,6 @@
@author Mariano Suligoy <marianognu.esyrpg@gmail.com>
*/
class CheckBox : public Button {
-
GDCLASS(CheckBox, Button);
protected:
diff --git a/scene/gui/check_button.cpp b/scene/gui/check_button.cpp
index 96484424f8..1ddc730dd1 100644
--- a/scene/gui/check_button.cpp
+++ b/scene/gui/check_button.cpp
@@ -34,25 +34,26 @@
#include "servers/rendering_server.h"
Size2 CheckButton::get_icon_size() const {
-
Ref<Texture2D> on = Control::get_theme_icon(is_disabled() ? "on_disabled" : "on");
Ref<Texture2D> off = Control::get_theme_icon(is_disabled() ? "off_disabled" : "off");
Size2 tex_size = Size2(0, 0);
- if (!on.is_null())
+ if (!on.is_null()) {
tex_size = Size2(on->get_width(), on->get_height());
- if (!off.is_null())
+ }
+ if (!off.is_null()) {
tex_size = Size2(MAX(tex_size.width, off->get_width()), MAX(tex_size.height, off->get_height()));
+ }
return tex_size;
}
Size2 CheckButton::get_minimum_size() const {
-
Size2 minsize = Button::get_minimum_size();
Size2 tex_size = get_icon_size();
minsize.width += tex_size.width;
- if (get_text().length() > 0)
+ if (get_text().length() > 0) {
minsize.width += get_theme_constant("hseparation");
+ }
Ref<StyleBox> sb = get_theme_stylebox("normal");
minsize.height = MAX(minsize.height, tex_size.height + sb->get_margin(MARGIN_TOP) + sb->get_margin(MARGIN_BOTTOM));
@@ -60,12 +61,9 @@ Size2 CheckButton::get_minimum_size() const {
}
void CheckButton::_notification(int p_what) {
-
if (p_what == NOTIFICATION_THEME_CHANGED) {
-
_set_internal_margin(MARGIN_RIGHT, get_icon_size().width);
} else if (p_what == NOTIFICATION_DRAW) {
-
RID ci = get_canvas_item();
Ref<Texture2D> on = Control::get_theme_icon(is_disabled() ? "on_disabled" : "on");
@@ -78,15 +76,15 @@ void CheckButton::_notification(int p_what) {
ofs.x = get_size().width - (tex_size.width + sb->get_margin(MARGIN_RIGHT));
ofs.y = (get_size().height - tex_size.height) / 2 + get_theme_constant("check_vadjust");
- if (is_pressed())
+ if (is_pressed()) {
on->draw(ci, ofs);
- else
+ } else {
off->draw(ci, ofs);
+ }
}
}
CheckButton::CheckButton() {
-
set_toggle_mode(true);
set_text_align(ALIGN_LEFT);
diff --git a/scene/gui/check_button.h b/scene/gui/check_button.h
index 3599c26a4c..8bbad0b4b3 100644
--- a/scene/gui/check_button.h
+++ b/scene/gui/check_button.h
@@ -36,7 +36,6 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
class CheckButton : public Button {
-
GDCLASS(CheckButton, Button);
protected:
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 5e0f4c91e8..88710289c7 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -30,7 +30,7 @@
#include "color_picker.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
@@ -41,17 +41,14 @@
#include "scene/main/window.h"
void ColorPicker::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
-
btn_pick->set_icon(get_theme_icon("screen_picker", "ColorPicker"));
bt_add_preset->set_icon(get_theme_icon("add_preset"));
_update_controls();
} break;
case NOTIFICATION_ENTER_TREE: {
-
btn_pick->set_icon(get_theme_icon("screen_picker", "ColorPicker"));
bt_add_preset->set_icon(get_theme_icon("add_preset"));
@@ -68,40 +65,40 @@ void ColorPicker::_notification(int p_what) {
#endif
} break;
case NOTIFICATION_PARENTED: {
-
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++) {
set_margin((Margin)i, get_theme_constant("margin"));
+ }
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
Popup *p = Object::cast_to<Popup>(get_parent());
- if (p)
+ if (p) {
p->set_size(Size2(get_combined_minimum_size().width + get_theme_constant("margin") * 2, get_combined_minimum_size().height + get_theme_constant("margin") * 2));
+ }
} break;
case NOTIFICATION_WM_CLOSE_REQUEST: {
-
- if (screen != nullptr && screen->is_visible())
+ if (screen != nullptr && screen->is_visible()) {
screen->hide();
+ }
} break;
}
}
void ColorPicker::set_focus_on_line_edit() {
-
c_text->call_deferred("grab_focus");
}
void ColorPicker::_update_controls() {
-
const char *rgb[3] = { "R", "G", "B" };
const char *hsv[3] = { "H", "S", "V" };
if (hsv_mode_enabled) {
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++) {
labels[i]->set_text(hsv[i]);
+ }
} else {
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++) {
labels[i]->set_text(rgb[i]);
+ }
}
if (hsv_mode_enabled) {
@@ -127,7 +124,6 @@ void ColorPicker::_update_controls() {
}
void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) {
-
color = p_color;
if (color != last_hsv) {
h = color.get_h();
@@ -136,38 +132,37 @@ void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) {
last_hsv = color;
}
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_update_color(p_update_sliders);
}
void ColorPicker::set_pick_color(const Color &p_color) {
-
_set_pick_color(p_color, true); //because setters can't have more arguments
}
void ColorPicker::set_edit_alpha(bool p_show) {
-
edit_alpha = p_show;
_update_controls();
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_update_color();
sample->update();
}
bool ColorPicker::is_editing_alpha() const {
-
return edit_alpha;
}
void ColorPicker::_value_changed(double) {
-
- if (updating)
+ if (updating) {
return;
+ }
if (hsv_mode_enabled) {
color.set_hsv(scroll[0]->get_value() / 360.0,
@@ -185,28 +180,28 @@ void ColorPicker::_value_changed(double) {
}
void ColorPicker::_html_entered(const String &p_html) {
-
- if (updating || text_is_constructor || !c_text->is_visible())
+ if (updating || text_is_constructor || !c_text->is_visible()) {
return;
+ }
float last_alpha = color.a;
color = Color::html(p_html);
- if (!is_editing_alpha())
+ if (!is_editing_alpha()) {
color.a = last_alpha;
+ }
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
set_pick_color(color);
emit_signal("color_changed", color);
}
void ColorPicker::_update_color(bool p_update_sliders) {
-
updating = true;
if (p_update_sliders) {
-
if (hsv_mode_enabled) {
for (int i = 0; i < 4; i++) {
scroll[i]->set_step(1.0);
@@ -225,8 +220,9 @@ void ColorPicker::_update_color(bool p_update_sliders) {
if (raw_mode_enabled) {
scroll[i]->set_step(0.01);
scroll[i]->set_max(100);
- if (i == 3)
+ if (i == 3) {
scroll[i]->set_max(1);
+ }
scroll[i]->set_value(color.components[i]);
} else {
scroll[i]->set_step(1);
@@ -266,7 +262,6 @@ void ColorPicker::_update_presets() {
}
void ColorPicker::_text_type_toggled() {
-
text_is_constructor = !text_is_constructor;
if (text_is_constructor) {
text_type->set_text("");
@@ -283,12 +278,10 @@ void ColorPicker::_text_type_toggled() {
}
Color ColorPicker::get_pick_color() const {
-
return color;
}
void ColorPicker::add_preset(const Color &p_color) {
-
if (presets.find(p_color)) {
presets.move_to_back(presets.find(p_color));
} else {
@@ -305,7 +298,6 @@ void ColorPicker::add_preset(const Color &p_color) {
}
void ColorPicker::erase_preset(const Color &p_color) {
-
if (presets.find(p_color)) {
presets.erase(presets.find(p_color));
preset->update();
@@ -320,7 +312,6 @@ void ColorPicker::erase_preset(const Color &p_color) {
}
PackedColorArray ColorPicker::get_presets() const {
-
PackedColorArray arr;
arr.resize(presets.size());
for (int i = 0; i < presets.size(); i++) {
@@ -330,42 +321,44 @@ PackedColorArray ColorPicker::get_presets() const {
}
void ColorPicker::set_hsv_mode(bool p_enabled) {
-
- if (hsv_mode_enabled == p_enabled || raw_mode_enabled)
+ if (hsv_mode_enabled == p_enabled || raw_mode_enabled) {
return;
+ }
hsv_mode_enabled = p_enabled;
- if (btn_hsv->is_pressed() != p_enabled)
+ if (btn_hsv->is_pressed() != p_enabled) {
btn_hsv->set_pressed(p_enabled);
+ }
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_update_controls();
_update_color();
}
bool ColorPicker::is_hsv_mode() const {
-
return hsv_mode_enabled;
}
void ColorPicker::set_raw_mode(bool p_enabled) {
-
- if (raw_mode_enabled == p_enabled || hsv_mode_enabled)
+ if (raw_mode_enabled == p_enabled || hsv_mode_enabled) {
return;
+ }
raw_mode_enabled = p_enabled;
- if (btn_raw->is_pressed() != p_enabled)
+ if (btn_raw->is_pressed() != p_enabled) {
btn_raw->set_pressed(p_enabled);
+ }
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_update_controls();
_update_color();
}
bool ColorPicker::is_raw_mode() const {
-
return raw_mode_enabled;
}
@@ -381,10 +374,11 @@ void ColorPicker::_update_text_value() {
bool visible = true;
if (text_is_constructor) {
String t = "Color(" + String::num(color.r) + ", " + String::num(color.g) + ", " + String::num(color.b);
- if (edit_alpha && color.a < 1)
+ if (edit_alpha && color.a < 1) {
t += ", " + String::num(color.a) + ")";
- else
+ } else {
t += ")";
+ }
c_text->set_text(t);
}
@@ -414,8 +408,9 @@ void ColorPicker::_sample_draw() {
}
void ColorPicker::_hsv_draw(int p_which, Control *c) {
- if (!c)
+ if (!c) {
return;
+ }
if (p_which == 0) {
Vector<Point2> points;
points.push_back(Vector2());
@@ -458,7 +453,6 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
}
void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid()) {
@@ -472,8 +466,9 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
last_hsv = color;
set_pick_color(color);
_update_color();
- if (!deferred_mode_enabled)
+ if (!deferred_mode_enabled) {
emit_signal("color_changed", color);
+ }
} else if (deferred_mode_enabled && !bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
emit_signal("color_changed", color);
changing_color = false;
@@ -485,8 +480,9 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mev = p_event;
if (mev.is_valid()) {
- if (!changing_color)
+ if (!changing_color) {
return;
+ }
float x = CLAMP((float)mev->get_position().x, 0, uv_edit->get_size().width);
float y = CLAMP((float)mev->get_position().y, 0, uv_edit->get_size().height);
s = x / uv_edit->get_size().width;
@@ -495,17 +491,16 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
last_hsv = color;
set_pick_color(color);
_update_color();
- if (!deferred_mode_enabled)
+ if (!deferred_mode_enabled) {
emit_signal("color_changed", color);
+ }
}
}
void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid()) {
-
if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
changing_color = true;
float y = CLAMP((float)bev->get_position().y, 0, w_edit->get_size().height);
@@ -517,31 +512,32 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
last_hsv = color;
set_pick_color(color);
_update_color();
- if (!deferred_mode_enabled)
+ if (!deferred_mode_enabled) {
emit_signal("color_changed", color);
- else if (!bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT)
+ } else if (!bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
emit_signal("color_changed", color);
+ }
}
Ref<InputEventMouseMotion> mev = p_event;
if (mev.is_valid()) {
-
- if (!changing_color)
+ if (!changing_color) {
return;
+ }
float y = CLAMP((float)mev->get_position().y, 0, w_edit->get_size().height);
h = y / w_edit->get_size().height;
color.set_hsv(h, s, v, color.a);
last_hsv = color;
set_pick_color(color);
_update_color();
- if (!deferred_mode_enabled)
+ if (!deferred_mode_enabled) {
emit_signal("color_changed", color);
+ }
}
}
void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid()) {
@@ -569,19 +565,18 @@ void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mev = p_event;
if (mev.is_valid()) {
-
int index = mev->get_position().x * presets.size();
if (preset->get_size().x != 0) {
index /= preset->get_size().x;
}
- if (index < 0 || index >= presets.size())
+ if (index < 0 || index >= presets.size()) {
return;
+ }
preset->set_tooltip(vformat(RTR("Color: #%s\nLMB: Set color\nRMB: Remove preset"), presets[index].to_html(presets[index].a < 1)));
}
}
void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid() && bev->get_button_index() == BUTTON_LEFT && !bev->is_pressed()) {
emit_signal("color_changed", color);
@@ -591,12 +586,12 @@ void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mev = p_event;
if (mev.is_valid()) {
Viewport *r = get_tree()->get_root();
- if (!r->get_visible_rect().has_point(Point2(mev->get_global_position().x, mev->get_global_position().y)))
+ if (!r->get_visible_rect().has_point(Point2(mev->get_global_position().x, mev->get_global_position().y))) {
return;
+ }
Ref<Image> img = r->get_texture()->get_data();
if (img.is_valid() && !img->empty()) {
-
Vector2 ofs = mev->get_global_position() - r->get_visible_rect().get_position();
Color c = img->get_pixel(ofs.x, r->get_visible_rect().size.height - ofs.y);
@@ -648,15 +643,17 @@ void ColorPicker::_focus_enter() {
void ColorPicker::_focus_exit() {
for (int i = 0; i < 4; i++) {
- if (!values[i]->get_line_edit()->get_menu()->is_visible())
+ if (!values[i]->get_line_edit()->get_menu()->is_visible()) {
values[i]->get_line_edit()->select(0, 0);
+ }
}
c_text->select(0, 0);
}
void ColorPicker::_html_focus_exit() {
- if (c_text->get_menu()->is_visible())
+ if (c_text->get_menu()->is_visible()) {
return;
+ }
_html_entered(c_text->get_text());
_focus_exit();
}
@@ -688,7 +685,6 @@ bool ColorPicker::are_presets_visible() const {
}
void ColorPicker::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_pick_color", "color"), &ColorPicker::set_pick_color);
ClassDB::bind_method(D_METHOD("get_pick_color"), &ColorPicker::get_pick_color);
ClassDB::bind_method(D_METHOD("set_hsv_mode"), &ColorPicker::set_hsv_mode);
@@ -722,7 +718,6 @@ void ColorPicker::_bind_methods() {
ColorPicker::ColorPicker() :
BoxContainer(true) {
-
updating = true;
edit_alpha = true;
text_is_constructor = false;
@@ -779,7 +774,6 @@ ColorPicker::ColorPicker() :
vbr->set_h_size_flags(SIZE_EXPAND_FILL);
for (int i = 0; i < 4; i++) {
-
HBoxContainer *hbc = memnew(HBoxContainer);
labels[i] = memnew(Label());
@@ -826,13 +820,11 @@ ColorPicker::ColorPicker() :
text_type->set_text("#");
text_type->set_tooltip(TTR("Switch between hexadecimal and code values."));
if (Engine::get_singleton()->is_editor_hint()) {
-
#ifdef TOOLS_ENABLED
text_type->set_custom_minimum_size(Size2(28 * EDSCALE, 0)); // Adjust for the width of the "Script" icon.
#endif
text_type->connect("pressed", callable_mp(this, &ColorPicker::_text_type_toggled));
} else {
-
text_type->set_flat(true);
text_type->set_mouse_filter(MOUSE_FILTER_IGNORE);
}
@@ -873,19 +865,16 @@ ColorPicker::ColorPicker() :
/////////////////
void ColorPickerButton::_color_changed(const Color &p_color) {
-
color = p_color;
update();
emit_signal("color_changed", color);
}
void ColorPickerButton::_modal_closed() {
-
emit_signal("popup_closed");
}
void ColorPickerButton::pressed() {
-
_update_picker();
popup->set_as_minsize();
@@ -904,7 +893,6 @@ void ColorPickerButton::pressed() {
if (i & 1) {
cp_rect.position.x = get_screen_position().x;
} else {
-
cp_rect.position.x = get_screen_position().x - MAX(0, (cp_rect.size.x - get_size().x));
}
@@ -918,10 +906,8 @@ void ColorPickerButton::pressed() {
}
void ColorPickerButton::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_DRAW: {
-
const Ref<StyleBox> normal = get_theme_stylebox("normal");
const Rect2 r = Rect2(normal->get_offset(), get_size() - normal->get_minimum_size());
draw_texture_rect(Control::get_theme_icon("bg", "ColorPickerButton"), r, true);
@@ -933,9 +919,9 @@ void ColorPickerButton::_notification(int p_what) {
}
} break;
case NOTIFICATION_WM_CLOSE_REQUEST: {
-
- if (popup)
+ if (popup) {
popup->hide();
+ }
} break;
}
@@ -947,7 +933,6 @@ void ColorPickerButton::_notification(int p_what) {
}
void ColorPickerButton::set_pick_color(const Color &p_color) {
-
color = p_color;
if (picker) {
picker->set_pick_color(p_color);
@@ -955,13 +940,12 @@ void ColorPickerButton::set_pick_color(const Color &p_color) {
update();
}
-Color ColorPickerButton::get_pick_color() const {
+Color ColorPickerButton::get_pick_color() const {
return color;
}
void ColorPickerButton::set_edit_alpha(bool p_show) {
-
edit_alpha = p_show;
if (picker) {
picker->set_edit_alpha(p_show);
@@ -969,18 +953,15 @@ void ColorPickerButton::set_edit_alpha(bool p_show) {
}
bool ColorPickerButton::is_editing_alpha() const {
-
return edit_alpha;
}
ColorPicker *ColorPickerButton::get_picker() {
-
_update_picker();
return picker;
}
PopupPanel *ColorPickerButton::get_popup() {
-
_update_picker();
return popup;
}
@@ -1004,7 +985,6 @@ void ColorPickerButton::_update_picker() {
}
void ColorPickerButton::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_pick_color", "color"), &ColorPickerButton::set_pick_color);
ClassDB::bind_method(D_METHOD("get_pick_color"), &ColorPickerButton::get_pick_color);
ClassDB::bind_method(D_METHOD("get_picker"), &ColorPickerButton::get_picker);
@@ -1020,7 +1000,6 @@ void ColorPickerButton::_bind_methods() {
}
ColorPickerButton::ColorPickerButton() {
-
// Initialization is now done deferred,
// this improves performance in the inspector as the color picker
// can be expensive to initialize.
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index dde2f37135..31ae92f4e4 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -44,7 +44,6 @@
#include "scene/gui/tool_button.h"
class ColorPicker : public BoxContainer {
-
GDCLASS(ColorPicker, BoxContainer);
private:
@@ -139,7 +138,6 @@ public:
};
class ColorPickerButton : public Button {
-
GDCLASS(ColorPickerButton, Button);
PopupPanel *popup;
diff --git a/scene/gui/color_rect.cpp b/scene/gui/color_rect.cpp
index 61260e153c..627e589c02 100644
--- a/scene/gui/color_rect.cpp
+++ b/scene/gui/color_rect.cpp
@@ -31,25 +31,21 @@
#include "color_rect.h"
void ColorRect::set_frame_color(const Color &p_color) {
-
color = p_color;
update();
}
Color ColorRect::get_frame_color() const {
-
return color;
}
void ColorRect::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
draw_rect(Rect2(Point2(), get_size()), color);
}
}
void ColorRect::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_frame_color", "color"), &ColorRect::set_frame_color);
ClassDB::bind_method(D_METHOD("get_frame_color"), &ColorRect::get_frame_color);
@@ -57,6 +53,5 @@ void ColorRect::_bind_methods() {
}
ColorRect::ColorRect() {
-
color = Color(1, 1, 1);
}
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index 41f33bb719..a89eef6209 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -33,7 +33,6 @@
#include "scene/scene_string_names.h"
void Container::_child_minsize_changed() {
-
//Size2 ms = get_combined_minimum_size();
//if (ms.width > get_size().width || ms.height > get_size().height) {
minimum_size_changed();
@@ -41,12 +40,12 @@ void Container::_child_minsize_changed() {
}
void Container::add_child_notify(Node *p_child) {
-
Control::add_child_notify(p_child);
Control *control = Object::cast_to<Control>(p_child);
- if (!control)
+ if (!control) {
return;
+ }
control->connect("size_flags_changed", callable_mp(this, &Container::queue_sort));
control->connect("minimum_size_changed", callable_mp(this, &Container::_child_minsize_changed));
@@ -57,23 +56,23 @@ void Container::add_child_notify(Node *p_child) {
}
void Container::move_child_notify(Node *p_child) {
-
Control::move_child_notify(p_child);
- if (!Object::cast_to<Control>(p_child))
+ if (!Object::cast_to<Control>(p_child)) {
return;
+ }
minimum_size_changed();
queue_sort();
}
void Container::remove_child_notify(Node *p_child) {
-
Control::remove_child_notify(p_child);
Control *control = Object::cast_to<Control>(p_child);
- if (!control)
+ if (!control) {
return;
+ }
control->disconnect("size_flags_changed", callable_mp(this, &Container::queue_sort));
control->disconnect("minimum_size_changed", callable_mp(this, &Container::_child_minsize_changed));
@@ -84,9 +83,9 @@ void Container::remove_child_notify(Node *p_child) {
}
void Container::_sort_children() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
notification(NOTIFICATION_SORT_CHILDREN);
emit_signal(SceneStringNames::get_singleton()->sort_children);
@@ -94,7 +93,6 @@ void Container::_sort_children() {
}
void Container::fit_child_in_rect(Control *p_child, const Rect2 &p_rect) {
-
ERR_FAIL_COND(!p_child);
ERR_FAIL_COND(p_child->get_parent() != this);
@@ -123,8 +121,9 @@ void Container::fit_child_in_rect(Control *p_child, const Rect2 &p_rect) {
}
}
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++) {
p_child->set_anchor(Margin(i), ANCHOR_BEGIN);
+ }
p_child->set_position(r.position);
p_child->set_size(r.size);
@@ -133,35 +132,31 @@ void Container::fit_child_in_rect(Control *p_child, const Rect2 &p_rect) {
}
void Container::queue_sort() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
- if (pending_sort)
+ if (pending_sort) {
return;
+ }
- MessageQueue::get_singleton()->push_call(this, "_sort_children");
+ MessageQueue::get_singleton()->push_callable(callable_mp(this, &Container::_sort_children));
pending_sort = true;
}
void Container::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
pending_sort = false;
queue_sort();
} break;
case NOTIFICATION_RESIZED: {
-
queue_sort();
} break;
case NOTIFICATION_THEME_CHANGED: {
-
queue_sort();
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
if (is_visible_in_tree()) {
queue_sort();
}
@@ -170,7 +165,6 @@ void Container::_notification(int p_what) {
}
String Container::get_configuration_warning() const {
-
String warning = Control::get_configuration_warning();
if (get_class() == "Container" && get_script().is_null()) {
@@ -183,9 +177,6 @@ String Container::get_configuration_warning() const {
}
void Container::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("_sort_children"), &Container::_sort_children);
-
ClassDB::bind_method(D_METHOD("queue_sort"), &Container::queue_sort);
ClassDB::bind_method(D_METHOD("fit_child_in_rect", "child", "rect"), &Container::fit_child_in_rect);
@@ -194,7 +185,6 @@ void Container::_bind_methods() {
}
Container::Container() {
-
pending_sort = false;
// All containers should let mouse events pass by default.
set_mouse_filter(MOUSE_FILTER_PASS);
diff --git a/scene/gui/container.h b/scene/gui/container.h
index 0b736d9790..c8db5ee28f 100644
--- a/scene/gui/container.h
+++ b/scene/gui/container.h
@@ -34,7 +34,6 @@
#include "scene/gui/control.h"
class Container : public Control {
-
GDCLASS(Container, Control);
bool pending_sort;
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index b4dc37c74f..96aaec6ae9 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -49,7 +49,6 @@
#ifdef TOOLS_ENABLED
Dictionary Control::_edit_get_state() const {
-
Dictionary s;
s["rotation"] = get_rotation();
s["scale"] = get_scale();
@@ -70,7 +69,6 @@ Dictionary Control::_edit_get_state() const {
}
void Control::_edit_set_state(const Dictionary &p_state) {
-
Dictionary state = p_state;
set_rotation(state["rotation"]);
@@ -162,37 +160,36 @@ Size2 Control::_edit_get_minimum_size() const {
#endif
void Control::set_custom_minimum_size(const Size2 &p_custom) {
-
- if (p_custom == data.custom_minimum_size)
+ if (p_custom == data.custom_minimum_size) {
return;
+ }
data.custom_minimum_size = p_custom;
minimum_size_changed();
}
Size2 Control::get_custom_minimum_size() const {
-
return data.custom_minimum_size;
}
void Control::_update_minimum_size_cache() {
-
Size2 minsize = get_minimum_size();
minsize.x = MAX(minsize.x, data.custom_minimum_size.x);
minsize.y = MAX(minsize.y, data.custom_minimum_size.y);
bool size_changed = false;
- if (data.minimum_size_cache != minsize)
+ if (data.minimum_size_cache != minsize) {
size_changed = true;
+ }
data.minimum_size_cache = minsize;
data.minimum_size_valid = true;
- if (size_changed)
+ if (size_changed) {
minimum_size_changed();
+ }
}
Size2 Control::get_combined_minimum_size() const {
-
if (!data.minimum_size_valid) {
const_cast<Control *>(this)->_update_minimum_size_cache();
}
@@ -200,7 +197,6 @@ Size2 Control::get_combined_minimum_size() const {
}
Transform2D Control::_get_internal_transform() const {
-
Transform2D rot_scale;
rot_scale.set_rotation_and_scale(data.rotation, data.scale);
Transform2D offset;
@@ -210,14 +206,12 @@ Transform2D Control::_get_internal_transform() const {
}
bool Control::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (!name.begins_with("custom")) {
return false;
}
if (p_value.get_type() == Variant::NIL) {
-
if (name.begins_with("custom_icons/")) {
String dname = name.get_slicec('/', 1);
if (data.icon_override.has(dname)) {
@@ -254,8 +248,9 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) {
String dname = name.get_slicec('/', 1);
data.constant_override.erase(dname);
notification(NOTIFICATION_THEME_CHANGED);
- } else
+ } else {
return false;
+ }
} else {
if (name.begins_with("custom_icons/")) {
@@ -276,16 +271,17 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) {
} else if (name.begins_with("custom_constants/")) {
String dname = name.get_slicec('/', 1);
add_theme_constant_override(dname, p_value);
- } else
+ } else {
return false;
+ }
}
return true;
}
void Control::_update_minimum_size() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
Size2 minsize = get_combined_minimum_size();
if (minsize.x > data.size_cache.x ||
@@ -302,7 +298,6 @@ void Control::_update_minimum_size() {
}
bool Control::_get(const StringName &p_name, Variant &r_ret) const {
-
String sname = p_name;
if (!sname.begins_with("custom")) {
@@ -332,13 +327,14 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const {
String name = sname.get_slicec('/', 1);
r_ret = data.constant_override.has(name) ? Variant(data.constant_override[name]) : Variant();
- } else
+ } else {
return false;
+ }
return true;
}
-void Control::_get_property_list(List<PropertyInfo> *p_list) const {
+void Control::_get_property_list(List<PropertyInfo> *p_list) const {
Ref<Theme> theme = Theme::get_default();
/* Using the default theme since the properties below are meant for editor only
if (data.theme.is_valid()) {
@@ -353,10 +349,10 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
theme->get_icon_list(get_class_name(), &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
-
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.icon_override.has(E->get()))
+ if (data.icon_override.has(E->get())) {
hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_icons/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", hint));
}
@@ -365,10 +361,10 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
theme->get_shader_list(get_class_name(), &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
-
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.shader_override.has(E->get()))
+ if (data.shader_override.has(E->get())) {
hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_shaders/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Shader,VisualShader", hint));
}
@@ -377,10 +373,10 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
theme->get_stylebox_list(get_class_name(), &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
-
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.style_override.has(E->get()))
+ if (data.style_override.has(E->get())) {
hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_styles/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", hint));
}
@@ -389,10 +385,10 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
theme->get_font_list(get_class_name(), &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
-
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.font_override.has(E->get()))
+ if (data.font_override.has(E->get())) {
hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
p_list->push_back(PropertyInfo(Variant::OBJECT, "custom_fonts/" + E->get(), PROPERTY_HINT_RESOURCE_TYPE, "Font", hint));
}
@@ -401,10 +397,10 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
theme->get_color_list(get_class_name(), &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
-
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.color_override.has(E->get()))
+ if (data.color_override.has(E->get())) {
hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
p_list->push_back(PropertyInfo(Variant::COLOR, "custom_colors/" + E->get(), PROPERTY_HINT_NONE, "", hint));
}
@@ -413,10 +409,10 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
List<StringName> names;
theme->get_constant_list(get_class_name(), &names);
for (List<StringName>::Element *E = names.front(); E; E = E->next()) {
-
uint32_t hint = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.constant_override.has(E->get()))
+ if (data.constant_override.has(E->get())) {
hint |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
p_list->push_back(PropertyInfo(Variant::INT, "custom_constants/" + E->get(), PROPERTY_HINT_RANGE, "-16384,16384", hint));
}
@@ -424,19 +420,16 @@ void Control::_get_property_list(List<PropertyInfo> *p_list) const {
}
Control *Control::get_parent_control() const {
-
return data.parent;
}
void Control::_resize(const Size2 &p_size) {
-
_size_changed();
}
//moved theme configuration here, so controls can set up even if still not inside active scene
void Control::add_child_notify(Node *p_child) {
-
Control *child_c = Object::cast_to<Control>(p_child);
if (child_c && child_c->data.theme.is_null() && (data.theme_owner || data.theme_owner_window)) {
@@ -451,7 +444,6 @@ void Control::add_child_notify(Node *p_child) {
}
void Control::remove_child_notify(Node *p_child) {
-
Control *child_c = Object::cast_to<Control>(p_child);
if (child_c && (child_c->data.theme_owner || child_c->data.theme_owner_window) && child_c->data.theme.is_null()) {
@@ -466,7 +458,6 @@ void Control::remove_child_notify(Node *p_child) {
}
void Control::_update_canvas_item_transform() {
-
Transform2D xform = _get_internal_transform();
xform[2] += get_position();
@@ -474,24 +465,19 @@ void Control::_update_canvas_item_transform() {
}
void Control::_notification(int p_notification) {
-
switch (p_notification) {
-
case NOTIFICATION_ENTER_TREE: {
-
} break;
case NOTIFICATION_POST_ENTER_TREE: {
data.minimum_size_valid = false;
_size_changed();
} break;
case NOTIFICATION_EXIT_TREE: {
-
get_viewport()->_gui_remove_control(this);
} break;
case NOTIFICATION_ENTER_CANVAS: {
-
data.parent = Object::cast_to<Control>(get_parent());
Node *parent = this; //meh
@@ -499,11 +485,11 @@ void Control::_notification(int p_notification) {
bool subwindow = false;
while (parent) {
-
parent = parent->get_parent();
- if (!parent)
+ if (!parent) {
break;
+ }
CanvasItem *ci = Object::cast_to<CanvasItem>(parent);
if (ci && ci->is_set_as_toplevel()) {
@@ -516,7 +502,6 @@ void Control::_notification(int p_notification) {
if (parent_control) {
break;
} else if (ci) {
-
} else {
break;
}
@@ -536,7 +521,6 @@ void Control::_notification(int p_notification) {
data.parent_canvas_item = get_parent_item();
if (data.parent_canvas_item) {
-
data.parent_canvas_item->connect("item_rect_changed", callable_mp(this, &Control::_size_changed));
} else {
//connect viewport
@@ -544,9 +528,7 @@ void Control::_notification(int p_notification) {
}
} break;
case NOTIFICATION_EXIT_CANVAS: {
-
if (data.parent_canvas_item) {
-
data.parent_canvas_item->disconnect("item_rect_changed", callable_mp(this, &Control::_size_changed));
data.parent_canvas_item = nullptr;
} else if (!is_set_as_toplevel()) {
@@ -566,8 +548,9 @@ void Control::_notification(int p_notification) {
case NOTIFICATION_MOVED_IN_PARENT: {
// some parents need to know the order of the childrens to draw (like TabContainer)
// update if necessary
- if (data.parent)
+ if (data.parent) {
data.parent->update();
+ }
update();
if (data.RI) {
@@ -576,11 +559,9 @@ void Control::_notification(int p_notification) {
} break;
case NOTIFICATION_RESIZED: {
-
emit_signal(SceneStringNames::get_singleton()->resized);
} break;
case NOTIFICATION_DRAW: {
-
_update_canvas_item_transform();
RenderingServer::get_singleton()->canvas_item_set_custom_rect(get_canvas_item(), !data.disable_visibility_clip, Rect2(Point2(), get_size()));
RenderingServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), data.clip_contents);
@@ -588,35 +569,29 @@ void Control::_notification(int p_notification) {
} break;
case NOTIFICATION_MOUSE_ENTER: {
-
emit_signal(SceneStringNames::get_singleton()->mouse_entered);
} break;
case NOTIFICATION_MOUSE_EXIT: {
-
emit_signal(SceneStringNames::get_singleton()->mouse_exited);
} break;
case NOTIFICATION_FOCUS_ENTER: {
-
emit_signal(SceneStringNames::get_singleton()->focus_entered);
update();
} break;
case NOTIFICATION_FOCUS_EXIT: {
-
emit_signal(SceneStringNames::get_singleton()->focus_exited);
update();
} break;
case NOTIFICATION_THEME_CHANGED: {
-
minimum_size_changed();
update();
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
if (!is_visible_in_tree()) {
-
- if (get_viewport() != nullptr)
+ if (get_viewport() != nullptr) {
get_viewport()->_gui_hid_control(this);
+ }
//remove key focus
@@ -630,14 +605,13 @@ void Control::_notification(int p_notification) {
}
bool Control::clips_input() const {
-
if (get_script_instance()) {
return get_script_instance()->call(SceneStringNames::get_singleton()->_clips_input);
}
return false;
}
-bool Control::has_point(const Point2 &p_point) const {
+bool Control::has_point(const Point2 &p_point) const {
if (get_script_instance()) {
Variant v = p_point;
const Variant *p = &v;
@@ -655,15 +629,14 @@ bool Control::has_point(const Point2 &p_point) const {
}
void Control::set_drag_forwarding(Control *p_target) {
-
- if (p_target)
+ if (p_target) {
data.drag_owner = p_target->get_instance_id();
- else
+ } else {
data.drag_owner = ObjectID();
+ }
}
Variant Control::get_drag_data(const Point2 &p_point) {
-
if (data.drag_owner.is_valid()) {
Object *obj = ObjectDB::get_instance(data.drag_owner);
if (obj) {
@@ -677,15 +650,15 @@ Variant Control::get_drag_data(const Point2 &p_point) {
const Variant *p = &v;
Callable::CallError ce;
Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->get_drag_data, &p, 1, ce);
- if (ce.error == Callable::CallError::CALL_OK)
+ if (ce.error == Callable::CallError::CALL_OK) {
return ret;
+ }
}
return Variant();
}
bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
-
if (data.drag_owner.is_valid()) {
Object *obj = ObjectDB::get_instance(data.drag_owner);
if (obj) {
@@ -699,14 +672,15 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const
const Variant *p[2] = { &v, &p_data };
Callable::CallError ce;
Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->can_drop_data, p, 2, ce);
- if (ce.error == Callable::CallError::CALL_OK)
+ if (ce.error == Callable::CallError::CALL_OK) {
return ret;
+ }
}
return Variant();
}
-void Control::drop_data(const Point2 &p_point, const Variant &p_data) {
+void Control::drop_data(const Point2 &p_point, const Variant &p_data) {
if (data.drag_owner.is_valid()) {
Object *obj = ObjectDB::get_instance(data.drag_owner);
if (obj) {
@@ -721,13 +695,13 @@ void Control::drop_data(const Point2 &p_point, const Variant &p_data) {
const Variant *p[2] = { &v, &p_data };
Callable::CallError ce;
Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->drop_data, p, 2, ce);
- if (ce.error == Callable::CallError::CALL_OK)
+ if (ce.error == Callable::CallError::CALL_OK) {
return;
+ }
}
}
void Control::force_drag(const Variant &p_data, Control *p_control) {
-
ERR_FAIL_COND(!is_inside_tree());
ERR_FAIL_COND(p_data.get_type() == Variant::NIL);
@@ -735,34 +709,30 @@ void Control::force_drag(const Variant &p_data, Control *p_control) {
}
void Control::set_drag_preview(Control *p_control) {
-
ERR_FAIL_COND(!is_inside_tree());
ERR_FAIL_COND(!get_viewport()->gui_is_dragging());
get_viewport()->_gui_set_drag_preview(this, p_control);
}
Size2 Control::get_minimum_size() const {
-
ScriptInstance *si = const_cast<Control *>(this)->get_script_instance();
if (si) {
-
Callable::CallError ce;
Variant s = si->call(SceneStringNames::get_singleton()->_get_minimum_size, nullptr, 0, ce);
- if (ce.error == Callable::CallError::CALL_OK)
+ if (ce.error == Callable::CallError::CALL_OK) {
return s;
+ }
}
return Size2();
}
template <class T>
bool Control::_find_theme_item(Control *p_theme_owner, Window *p_theme_owner_window, T &r_ret, T (Theme::*get_func)(const StringName &, const StringName &) const, bool (Theme::*has_func)(const StringName &, const StringName &) const, const StringName &p_name, const StringName &p_type) {
-
// try with custom themes
Control *theme_owner = p_theme_owner;
Window *theme_owner_window = p_theme_owner_window;
while (theme_owner || theme_owner_window) {
-
StringName class_name = p_type;
while (class_name != StringName()) {
@@ -792,7 +762,6 @@ bool Control::_find_theme_item(Control *p_theme_owner, Window *p_theme_owner_win
theme_owner = parent_w->theme_owner;
theme_owner_window = parent_w->theme_owner_window;
} else {
-
theme_owner = nullptr;
theme_owner_window = nullptr;
}
@@ -802,13 +771,11 @@ bool Control::_find_theme_item(Control *p_theme_owner, Window *p_theme_owner_win
}
bool Control::_has_theme_item(Control *p_theme_owner, Window *p_theme_owner_window, bool (Theme::*has_func)(const StringName &, const StringName &) const, const StringName &p_name, const StringName &p_type) {
-
// try with custom themes
Control *theme_owner = p_theme_owner;
Window *theme_owner_window = p_theme_owner_window;
while (theme_owner || theme_owner_window) {
-
StringName class_name = p_type;
while (class_name != StringName()) {
@@ -836,7 +803,6 @@ bool Control::_has_theme_item(Control *p_theme_owner, Window *p_theme_owner_wind
theme_owner = parent_w->theme_owner;
theme_owner_window = parent_w->theme_owner_window;
} else {
-
theme_owner = nullptr;
theme_owner_window = nullptr;
}
@@ -846,12 +812,11 @@ bool Control::_has_theme_item(Control *p_theme_owner, Window *p_theme_owner_wind
}
Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
-
const Ref<Texture2D> *tex = data.icon_override.getptr(p_name);
- if (tex)
+ if (tex) {
return *tex;
+ }
}
StringName type = p_type ? p_type : get_class_name();
@@ -860,7 +825,6 @@ Ref<Texture2D> Control::get_theme_icon(const StringName &p_name, const StringNam
}
Ref<Texture2D> Control::get_icons(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
-
Ref<Texture2D> icon;
if (_find_theme_item(p_theme_owner, p_theme_owner_window, icon, &Theme::get_icon, &Theme::has_icon, p_name, p_type)) {
@@ -877,12 +841,11 @@ Ref<Texture2D> Control::get_icons(Control *p_theme_owner, Window *p_theme_owner_
}
Ref<Shader> Control::get_theme_shader(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
-
const Ref<Shader> *sdr = data.shader_override.getptr(p_name);
- if (sdr)
+ if (sdr) {
return *sdr;
+ }
}
StringName type = p_type ? p_type : get_class_name();
@@ -891,7 +854,6 @@ Ref<Shader> Control::get_theme_shader(const StringName &p_name, const StringName
}
Ref<Shader> Control::get_shaders(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
-
Ref<Shader> shader;
if (_find_theme_item(p_theme_owner, p_theme_owner_window, shader, &Theme::get_shader, &Theme::has_shader, p_name, p_type)) {
@@ -908,11 +870,11 @@ Ref<Shader> Control::get_shaders(Control *p_theme_owner, Window *p_theme_owner_w
}
Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
const Ref<StyleBox> *style = data.style_override.getptr(p_name);
- if (style)
+ if (style) {
return *style;
+ }
}
StringName type = p_type ? p_type : get_class_name();
@@ -921,7 +883,6 @@ Ref<StyleBox> Control::get_theme_stylebox(const StringName &p_name, const String
}
Ref<StyleBox> Control::get_styleboxs(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
-
Ref<StyleBox> stylebox;
if (_find_theme_item(p_theme_owner, p_theme_owner_window, stylebox, &Theme::get_stylebox, &Theme::has_stylebox, p_name, p_type)) {
@@ -938,11 +899,11 @@ Ref<StyleBox> Control::get_styleboxs(Control *p_theme_owner, Window *p_theme_own
}
Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
const Ref<Font> *font = data.font_override.getptr(p_name);
- if (font)
+ if (font) {
return *font;
+ }
}
StringName type = p_type ? p_type : get_class_name();
@@ -951,7 +912,6 @@ Ref<Font> Control::get_theme_font(const StringName &p_name, const StringName &p_
}
Ref<Font> Control::get_fonts(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
-
Ref<Font> font;
if (_find_theme_item(p_theme_owner, p_theme_owner_window, font, &Theme::get_font, &Theme::has_font, p_name, p_type)) {
@@ -968,11 +928,11 @@ Ref<Font> Control::get_fonts(Control *p_theme_owner, Window *p_theme_owner_windo
}
Color Control::get_theme_color(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
const Color *color = data.color_override.getptr(p_name);
- if (color)
+ if (color) {
return *color;
+ }
}
StringName type = p_type ? p_type : get_class_name();
@@ -981,7 +941,6 @@ Color Control::get_theme_color(const StringName &p_name, const StringName &p_typ
}
Color Control::get_colors(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
-
Color color;
if (_find_theme_item(p_theme_owner, p_theme_owner_window, color, &Theme::get_color, &Theme::has_color, p_name, p_type)) {
@@ -997,11 +956,11 @@ Color Control::get_colors(Control *p_theme_owner, Window *p_theme_owner_window,
}
int Control::get_theme_constant(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
const int *constant = data.constant_override.getptr(p_name);
- if (constant)
+ if (constant) {
return *constant;
+ }
}
StringName type = p_type ? p_type : get_class_name();
@@ -1010,7 +969,6 @@ int Control::get_theme_constant(const StringName &p_name, const StringName &p_ty
}
int Control::get_constants(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
-
int constant;
if (_find_theme_item(p_theme_owner, p_theme_owner_window, constant, &Theme::get_constant, &Theme::has_constant, p_name, p_type)) {
@@ -1026,46 +984,40 @@ int Control::get_constants(Control *p_theme_owner, Window *p_theme_owner_window,
}
bool Control::has_theme_icon_override(const StringName &p_name) const {
-
const Ref<Texture2D> *tex = data.icon_override.getptr(p_name);
return tex != nullptr;
}
bool Control::has_theme_shader_override(const StringName &p_name) const {
-
const Ref<Shader> *sdr = data.shader_override.getptr(p_name);
return sdr != nullptr;
}
bool Control::has_theme_stylebox_override(const StringName &p_name) const {
-
const Ref<StyleBox> *style = data.style_override.getptr(p_name);
return style != nullptr;
}
bool Control::has_theme_font_override(const StringName &p_name) const {
-
const Ref<Font> *font = data.font_override.getptr(p_name);
return font != nullptr;
}
bool Control::has_theme_color_override(const StringName &p_name) const {
-
const Color *color = data.color_override.getptr(p_name);
return color != nullptr;
}
bool Control::has_theme_constant_override(const StringName &p_name) const {
-
const int *constant = data.constant_override.getptr(p_name);
return constant != nullptr;
}
bool Control::has_theme_icon(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
- if (has_theme_icon_override(p_name))
+ if (has_theme_icon_override(p_name)) {
return true;
+ }
}
StringName type = p_type ? p_type : get_class_name();
@@ -1074,7 +1026,6 @@ bool Control::has_theme_icon(const StringName &p_name, const StringName &p_type)
}
bool Control::has_icons(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
-
if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_icon, p_name, p_type)) {
return true;
}
@@ -1088,18 +1039,18 @@ bool Control::has_icons(Control *p_theme_owner, Window *p_theme_owner_window, co
}
bool Control::has_theme_shader(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
- if (has_theme_shader_override(p_name))
+ if (has_theme_shader_override(p_name)) {
return true;
+ }
}
StringName type = p_type ? p_type : get_class_name();
return has_shaders(data.theme_owner, data.theme_owner_window, p_name, type);
}
-bool Control::has_shaders(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
+bool Control::has_shaders(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_shader, p_name, p_type)) {
return true;
}
@@ -1113,10 +1064,10 @@ bool Control::has_shaders(Control *p_theme_owner, Window *p_theme_owner_window,
}
bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
- if (has_theme_stylebox_override(p_name))
+ if (has_theme_stylebox_override(p_name)) {
return true;
+ }
}
StringName type = p_type ? p_type : get_class_name();
@@ -1125,7 +1076,6 @@ bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_t
}
bool Control::has_styleboxs(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
-
if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_stylebox, p_name, p_type)) {
return true;
}
@@ -1139,18 +1089,18 @@ bool Control::has_styleboxs(Control *p_theme_owner, Window *p_theme_owner_window
}
bool Control::has_theme_font(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
- if (has_theme_font_override(p_name))
+ if (has_theme_font_override(p_name)) {
return true;
+ }
}
StringName type = p_type ? p_type : get_class_name();
return has_fonts(data.theme_owner, data.theme_owner_window, p_name, type);
}
-bool Control::has_fonts(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
+bool Control::has_fonts(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_font, p_name, p_type)) {
return true;
}
@@ -1164,18 +1114,18 @@ bool Control::has_fonts(Control *p_theme_owner, Window *p_theme_owner_window, co
}
bool Control::has_theme_color(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
- if (has_theme_color_override(p_name))
+ if (has_theme_color_override(p_name)) {
return true;
+ }
}
StringName type = p_type ? p_type : get_class_name();
return has_colors(data.theme_owner, data.theme_owner_window, p_name, type);
}
-bool Control::has_colors(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
+bool Control::has_colors(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_color, p_name, p_type)) {
return true;
}
@@ -1189,10 +1139,10 @@ bool Control::has_colors(Control *p_theme_owner, Window *p_theme_owner_window, c
}
bool Control::has_theme_constant(const StringName &p_name, const StringName &p_type) const {
-
if (p_type == StringName() || p_type == get_class_name()) {
- if (has_theme_constant_override(p_name))
+ if (has_theme_constant_override(p_name)) {
return true;
+ }
}
StringName type = p_type ? p_type : get_class_name();
@@ -1201,7 +1151,6 @@ bool Control::has_theme_constant(const StringName &p_name, const StringName &p_t
}
bool Control::has_constants(Control *p_theme_owner, Window *p_theme_owner_window, const StringName &p_name, const StringName &p_type) {
-
if (_has_theme_item(p_theme_owner, p_theme_owner_window, &Theme::has_constant, p_name, p_type)) {
return true;
}
@@ -1215,8 +1164,9 @@ bool Control::has_constants(Control *p_theme_owner, Window *p_theme_owner_window
}
Rect2 Control::get_parent_anchorable_rect() const {
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return Rect2();
+ }
Rect2 parent_rect;
if (data.parent_canvas_item) {
@@ -1229,18 +1179,15 @@ Rect2 Control::get_parent_anchorable_rect() const {
}
Size2 Control::get_parent_area_size() const {
-
return get_parent_anchorable_rect().size;
}
void Control::_size_changed() {
-
Rect2 parent_rect = get_parent_anchorable_rect();
float margin_pos[4];
for (int i = 0; i < 4; i++) {
-
float area = parent_rect.size[i & 1];
margin_pos[i] = data.margin[i] + (data.anchor[i] * area);
}
@@ -1293,7 +1240,6 @@ void Control::_size_changed() {
}
void Control::set_anchor(Margin p_margin, float p_anchor, bool p_keep_margin, bool p_push_opposite_anchor) {
-
ERR_FAIL_INDEX((int)p_margin, 4);
Rect2 parent_rect = get_parent_anchorable_rect();
@@ -1334,13 +1280,11 @@ void Control::_set_anchor(Margin p_margin, float p_anchor) {
}
void Control::set_anchor_and_margin(Margin p_margin, float p_anchor, float p_pos, bool p_push_opposite_anchor) {
-
set_anchor(p_margin, p_anchor, false, p_push_opposite_anchor);
set_margin(p_margin, p_pos);
}
void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_margins) {
-
ERR_FAIL_INDEX((int)p_preset, 16);
//Left
@@ -1457,7 +1401,6 @@ void Control::set_anchors_preset(LayoutPreset p_preset, bool p_keep_margins) {
}
void Control::set_margins_preset(LayoutPreset p_preset, LayoutPresetMode p_resize_mode, int p_margin) {
-
ERR_FAIL_INDEX((int)p_preset, 16);
ERR_FAIL_INDEX((int)p_resize_mode, 4);
@@ -1594,14 +1537,12 @@ void Control::set_anchors_and_margins_preset(LayoutPreset p_preset, LayoutPreset
}
float Control::get_anchor(Margin p_margin) const {
-
ERR_FAIL_INDEX_V(int(p_margin), 4, 0.0);
return data.anchor[p_margin];
}
void Control::_change_notify_margins() {
-
// this avoids sending the whole object data again on a change
_change_notify("margin_left");
_change_notify("margin_top");
@@ -1612,7 +1553,6 @@ void Control::_change_notify_margins() {
}
void Control::set_margin(Margin p_margin, float p_value) {
-
ERR_FAIL_INDEX((int)p_margin, 4);
data.margin[p_margin] = p_value;
@@ -1620,37 +1560,32 @@ void Control::set_margin(Margin p_margin, float p_value) {
}
void Control::set_begin(const Size2 &p_point) {
-
data.margin[0] = p_point.x;
data.margin[1] = p_point.y;
_size_changed();
}
void Control::set_end(const Size2 &p_point) {
-
data.margin[2] = p_point.x;
data.margin[3] = p_point.y;
_size_changed();
}
float Control::get_margin(Margin p_margin) const {
-
ERR_FAIL_INDEX_V((int)p_margin, 4, 0);
return data.margin[p_margin];
}
Size2 Control::get_begin() const {
-
return Size2(data.margin[0], data.margin[1]);
}
-Size2 Control::get_end() const {
+Size2 Control::get_end() const {
return Size2(data.margin[2], data.margin[3]);
}
Point2 Control::get_global_position() const {
-
return get_global_transform().get_origin();
}
@@ -1670,11 +1605,9 @@ void Control::_set_global_position(const Point2 &p_point) {
}
void Control::set_global_position(const Point2 &p_point, bool p_keep_margins) {
-
Transform2D inv;
if (data.parent_canvas_item) {
-
inv = data.parent_canvas_item->get_global_transform().affine_inverse();
}
@@ -1682,7 +1615,6 @@ void Control::set_global_position(const Point2 &p_point, bool p_keep_margins) {
}
void Control::_compute_anchors(Rect2 p_rect, const float p_margins[4], float (&r_anchors)[4]) {
-
Size2 parent_rect_size = get_parent_anchorable_rect().size;
ERR_FAIL_COND(parent_rect_size.x == 0.0);
ERR_FAIL_COND(parent_rect_size.y == 0.0);
@@ -1694,7 +1626,6 @@ void Control::_compute_anchors(Rect2 p_rect, const float p_margins[4], float (&r
}
void Control::_compute_margins(Rect2 p_rect, const float p_anchors[4], float (&r_margins)[4]) {
-
Size2 parent_rect_size = get_parent_anchorable_rect().size;
r_margins[0] = p_rect.position.x - (p_anchors[0] * parent_rect_size.x);
r_margins[1] = p_rect.position.y - (p_anchors[1] * parent_rect_size.y);
@@ -1724,13 +1655,14 @@ void Control::_set_size(const Size2 &p_size) {
}
void Control::set_size(const Size2 &p_size, bool p_keep_margins) {
-
Size2 new_size = p_size;
Size2 min = get_combined_minimum_size();
- if (new_size.x < min.x)
+ if (new_size.x < min.x) {
new_size.x = min.x;
- if (new_size.y < min.y)
+ }
+ if (new_size.y < min.y) {
new_size.y = min.y;
+ }
if (p_keep_margins) {
_compute_anchors(Rect2(data.pos_cache, new_size), data.margin, data.anchor);
@@ -1745,22 +1677,18 @@ void Control::set_size(const Size2 &p_size, bool p_keep_margins) {
}
Size2 Control::get_position() const {
-
return data.pos_cache;
}
Size2 Control::get_size() const {
-
return data.size_cache;
}
Rect2 Control::get_global_rect() const {
-
return Rect2(get_global_position(), get_size());
}
Rect2 Control::get_screen_rect() const {
-
ERR_FAIL_COND_V(!is_inside_tree(), Rect2());
Rect2 r(get_global_position(), get_size());
@@ -1781,17 +1709,14 @@ Rect2 Control::get_window_rect() const {
}
Rect2 Control::get_rect() const {
-
return Rect2(get_position(), get_size());
}
Rect2 Control::get_anchorable_rect() const {
-
return Rect2(Point2(), get_size());
}
void Control::add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) {
-
if (data.icon_override.has(p_name)) {
data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
}
@@ -1809,7 +1734,6 @@ void Control::add_theme_icon_override(const StringName &p_name, const Ref<Textur
}
void Control::add_theme_shader_override(const StringName &p_name, const Ref<Shader> &p_shader) {
-
if (data.shader_override.has(p_name)) {
data.shader_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
}
@@ -1825,8 +1749,8 @@ void Control::add_theme_shader_override(const StringName &p_name, const Ref<Shad
}
notification(NOTIFICATION_THEME_CHANGED);
}
-void Control::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) {
+void Control::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) {
if (data.style_override.has(p_name)) {
data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
}
@@ -1844,7 +1768,6 @@ void Control::add_theme_style_override(const StringName &p_name, const Ref<Style
}
void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font) {
-
if (data.font_override.has(p_name)) {
data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
}
@@ -1860,46 +1783,45 @@ void Control::add_theme_font_override(const StringName &p_name, const Ref<Font>
}
notification(NOTIFICATION_THEME_CHANGED);
}
-void Control::add_theme_color_override(const StringName &p_name, const Color &p_color) {
+void Control::add_theme_color_override(const StringName &p_name, const Color &p_color) {
data.color_override[p_name] = p_color;
notification(NOTIFICATION_THEME_CHANGED);
}
-void Control::add_theme_constant_override(const StringName &p_name, int p_constant) {
+void Control::add_theme_constant_override(const StringName &p_name, int p_constant) {
data.constant_override[p_name] = p_constant;
notification(NOTIFICATION_THEME_CHANGED);
}
void Control::set_focus_mode(FocusMode p_focus_mode) {
-
ERR_FAIL_INDEX((int)p_focus_mode, 3);
- if (is_inside_tree() && p_focus_mode == FOCUS_NONE && data.focus_mode != FOCUS_NONE && has_focus())
+ if (is_inside_tree() && p_focus_mode == FOCUS_NONE && data.focus_mode != FOCUS_NONE && has_focus()) {
release_focus();
+ }
data.focus_mode = p_focus_mode;
}
static Control *_next_control(Control *p_from) {
-
- if (p_from->is_set_as_toplevel())
+ if (p_from->is_set_as_toplevel()) {
return nullptr; // can't go above
+ }
Control *parent = Object::cast_to<Control>(p_from->get_parent());
if (!parent) {
-
return nullptr;
}
int next = p_from->get_index();
ERR_FAIL_INDEX_V(next, parent->get_child_count(), nullptr);
for (int i = (next + 1); i < parent->get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(parent->get_child(i));
- if (!c || !c->is_visible_in_tree() || c->is_set_as_toplevel())
+ if (!c || !c->is_visible_in_tree() || c->is_set_as_toplevel()) {
continue;
+ }
return c;
}
@@ -1909,11 +1831,9 @@ static Control *_next_control(Control *p_from) {
}
Control *Control::find_next_valid_focus() const {
-
Control *from = const_cast<Control *>(this);
while (true) {
-
// If the focus property is manually overwritten, attempt to use it.
if (!data.focus_next.is_empty()) {
@@ -1925,8 +1845,9 @@ Control *Control::find_next_valid_focus() const {
} else {
return nullptr;
}
- if (c->is_visible() && c->get_focus_mode() != FOCUS_NONE)
+ if (c->is_visible() && c->get_focus_mode() != FOCUS_NONE) {
return c;
+ }
}
// find next child
@@ -1934,7 +1855,6 @@ Control *Control::find_next_valid_focus() const {
Control *next_child = nullptr;
for (int i = 0; i < from->get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(from->get_child(i));
if (!c || !c->is_visible_in_tree() || c->is_set_as_toplevel()) {
continue;
@@ -1945,56 +1865,56 @@ Control *Control::find_next_valid_focus() const {
}
if (!next_child) {
-
next_child = _next_control(from);
if (!next_child) { //nothing else.. go up and find either window or subwindow
next_child = const_cast<Control *>(this);
while (next_child && !next_child->is_set_as_toplevel()) {
-
next_child = cast_to<Control>(next_child->get_parent());
}
if (!next_child) {
-
next_child = const_cast<Control *>(this);
while (next_child) {
-
- if (next_child->data.RI)
+ if (next_child->data.RI) {
break;
+ }
next_child = next_child->get_parent_control();
}
}
}
}
- if (next_child == this) // no next control->
+ if (next_child == this) { // no next control->
return (get_focus_mode() == FOCUS_ALL) ? next_child : nullptr;
+ }
if (next_child) {
- if (next_child->get_focus_mode() == FOCUS_ALL)
+ if (next_child->get_focus_mode() == FOCUS_ALL) {
return next_child;
+ }
from = next_child;
- } else
+ } else {
break;
+ }
}
return nullptr;
}
static Control *_prev_control(Control *p_from) {
-
Control *child = nullptr;
for (int i = p_from->get_child_count() - 1; i >= 0; i--) {
-
Control *c = Object::cast_to<Control>(p_from->get_child(i));
- if (!c || !c->is_visible_in_tree() || c->is_set_as_toplevel())
+ if (!c || !c->is_visible_in_tree() || c->is_set_as_toplevel()) {
continue;
+ }
child = c;
break;
}
- if (!child)
+ if (!child) {
return p_from;
+ }
//no prev in parent, try the same in parent
return _prev_control(child);
@@ -2004,7 +1924,6 @@ Control *Control::find_prev_valid_focus() const {
Control *from = const_cast<Control *>(this);
while (true) {
-
// If the focus property is manually overwritten, attempt to use it.
if (!data.focus_prev.is_empty()) {
@@ -2016,8 +1935,9 @@ Control *Control::find_prev_valid_focus() const {
} else {
return nullptr;
}
- if (c->is_visible() && c->get_focus_mode() != FOCUS_NONE)
+ if (c->is_visible() && c->get_focus_mode() != FOCUS_NONE) {
return c;
+ }
}
// find prev child
@@ -2025,15 +1945,12 @@ Control *Control::find_prev_valid_focus() const {
Control *prev_child = nullptr;
if (from->is_set_as_toplevel() || !Object::cast_to<Control>(from->get_parent())) {
-
//find last of the children
prev_child = _prev_control(from);
} else {
-
for (int i = (from->get_index() - 1); i >= 0; i--) {
-
Control *c = Object::cast_to<Control>(from->get_parent()->get_child(i));
if (!c || !c->is_visible_in_tree() || c->is_set_as_toplevel()) {
@@ -2045,19 +1962,19 @@ Control *Control::find_prev_valid_focus() const {
}
if (!prev_child) {
-
prev_child = Object::cast_to<Control>(from->get_parent());
} else {
-
prev_child = _prev_control(prev_child);
}
}
- if (prev_child == this) // no prev control->
+ if (prev_child == this) { // no prev control->
return (get_focus_mode() == FOCUS_ALL) ? prev_child : nullptr;
+ }
- if (prev_child->get_focus_mode() == FOCUS_ALL)
+ if (prev_child->get_focus_mode() == FOCUS_ALL) {
return prev_child;
+ }
from = prev_child;
}
@@ -2066,16 +1983,14 @@ Control *Control::find_prev_valid_focus() const {
}
Control::FocusMode Control::get_focus_mode() const {
-
return data.focus_mode;
}
-bool Control::has_focus() const {
+bool Control::has_focus() const {
return is_inside_tree() && get_viewport()->_gui_control_has_focus(this);
}
void Control::grab_focus() {
-
ERR_FAIL_COND(!is_inside_tree());
if (data.focus_mode == FOCUS_NONE) {
@@ -2087,40 +2002,38 @@ void Control::grab_focus() {
}
void Control::release_focus() {
-
ERR_FAIL_COND(!is_inside_tree());
- if (!has_focus())
+ if (!has_focus()) {
return;
+ }
get_viewport()->_gui_remove_focus();
update();
}
bool Control::is_toplevel_control() const {
-
return is_inside_tree() && (!data.parent_canvas_item && !data.RI && is_set_as_toplevel());
}
void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_assign) {
-
Control *c = Object::cast_to<Control>(p_at);
- if (c && c != p_owner && c->data.theme.is_valid()) // has a theme, this can't be propagated
+ if (c && c != p_owner && c->data.theme.is_valid()) { // has a theme, this can't be propagated
return;
+ }
Window *w = c == nullptr ? Object::cast_to<Window>(p_at) : nullptr;
- if (w && w != p_owner_window && w->theme.is_valid()) // has a theme, this can't be propagated
+ if (w && w != p_owner_window && w->theme.is_valid()) { // has a theme, this can't be propagated
return;
+ }
for (int i = 0; i < p_at->get_child_count(); i++) {
-
CanvasItem *child = Object::cast_to<CanvasItem>(p_at->get_child(i));
if (child) {
_propagate_theme_changed(child, p_owner, p_owner_window, p_assign);
} else {
-
Window *window = Object::cast_to<Window>(p_at->get_child(i));
if (window) {
_propagate_theme_changed(window, p_owner, p_owner_window, p_assign);
@@ -2129,7 +2042,6 @@ void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_o
}
if (c) {
-
if (p_assign) {
c->data.theme_owner = p_owner;
c->data.theme_owner_window = p_owner_window;
@@ -2139,7 +2051,6 @@ void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_o
}
if (w) {
-
if (p_assign) {
w->theme_owner = p_owner;
w->theme_owner_window = p_owner_window;
@@ -2150,14 +2061,13 @@ void Control::_propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_o
}
void Control::_theme_changed() {
-
_propagate_theme_changed(this, this, nullptr, false);
}
void Control::set_theme(const Ref<Theme> &p_theme) {
-
- if (data.theme == p_theme)
+ if (data.theme == p_theme) {
return;
+ }
if (data.theme.is_valid()) {
data.theme->disconnect("changed", callable_mp(this, &Control::_theme_changed));
@@ -2165,12 +2075,10 @@ void Control::set_theme(const Ref<Theme> &p_theme) {
data.theme = p_theme;
if (!p_theme.is_null()) {
-
data.theme_owner = this;
data.theme_owner_window = nullptr;
_propagate_theme_changed(this, this, nullptr);
} else {
-
Control *parent_c = Object::cast_to<Control>(get_parent());
if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) {
@@ -2191,26 +2099,24 @@ void Control::set_theme(const Ref<Theme> &p_theme) {
}
void Control::accept_event() {
-
- if (is_inside_tree())
+ if (is_inside_tree()) {
get_viewport()->_gui_accept_event();
+ }
}
Ref<Theme> Control::get_theme() const {
-
return data.theme;
}
void Control::set_tooltip(const String &p_tooltip) {
-
data.tooltip = p_tooltip;
update_configuration_warning();
}
String Control::get_tooltip(const Point2 &p_pos) const {
-
return data.tooltip;
}
+
Control *Control::make_custom_tooltip(const String &p_text) const {
if (get_script_instance()) {
return const_cast<Control *>(this)->call("_make_custom_tooltip", p_text);
@@ -2219,75 +2125,64 @@ Control *Control::make_custom_tooltip(const String &p_text) const {
}
void Control::set_default_cursor_shape(CursorShape p_shape) {
-
ERR_FAIL_INDEX(int(p_shape), CURSOR_MAX);
data.default_cursor = p_shape;
}
Control::CursorShape Control::get_default_cursor_shape() const {
-
return data.default_cursor;
}
-Control::CursorShape Control::get_cursor_shape(const Point2 &p_pos) const {
+Control::CursorShape Control::get_cursor_shape(const Point2 &p_pos) const {
return data.default_cursor;
}
Transform2D Control::get_transform() const {
-
Transform2D xform = _get_internal_transform();
xform[2] += get_position();
return xform;
}
String Control::_get_tooltip() const {
-
return data.tooltip;
}
void Control::set_focus_neighbour(Margin p_margin, const NodePath &p_neighbour) {
-
ERR_FAIL_INDEX((int)p_margin, 4);
data.focus_neighbour[p_margin] = p_neighbour;
}
NodePath Control::get_focus_neighbour(Margin p_margin) const {
-
ERR_FAIL_INDEX_V((int)p_margin, 4, NodePath());
return data.focus_neighbour[p_margin];
}
void Control::set_focus_next(const NodePath &p_next) {
-
data.focus_next = p_next;
}
NodePath Control::get_focus_next() const {
-
return data.focus_next;
}
void Control::set_focus_previous(const NodePath &p_prev) {
-
data.focus_prev = p_prev;
}
NodePath Control::get_focus_previous() const {
-
return data.focus_prev;
}
#define MAX_NEIGHBOUR_SEARCH_COUNT 512
Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) {
-
ERR_FAIL_INDEX_V((int)p_margin, 4, nullptr);
- if (p_count >= MAX_NEIGHBOUR_SEARCH_COUNT)
+ if (p_count >= MAX_NEIGHBOUR_SEARCH_COUNT) {
return nullptr;
+ }
if (!data.focus_neighbour[p_margin].is_empty()) {
-
Control *c = nullptr;
Node *n = get_node(data.focus_neighbour[p_margin]);
if (n) {
@@ -2297,12 +2192,15 @@ Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) {
return nullptr;
}
bool valid = true;
- if (!c->is_visible())
+ if (!c->is_visible()) {
valid = false;
- if (c->get_focus_mode() == FOCUS_NONE)
+ }
+ if (c->get_focus_mode() == FOCUS_NONE) {
valid = false;
- if (valid)
+ }
+ if (valid) {
return c;
+ }
c = c->_get_focus_neighbour(p_margin, p_count + 1);
return c;
@@ -2332,26 +2230,27 @@ Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) {
float maxd = -1e7;
for (int i = 0; i < 4; i++) {
-
float d = vdir.dot(points[i]);
- if (d > maxd)
+ if (d > maxd) {
maxd = d;
+ }
}
Node *base = this;
while (base) {
-
Control *c = Object::cast_to<Control>(base);
if (c) {
- if (c->data.RI)
+ if (c->data.RI) {
break;
+ }
}
base = base->get_parent();
}
- if (!base)
+ if (!base) {
return nullptr;
+ }
_window_find_focus_neighbour(vdir, base, points, maxd, dist, &result);
@@ -2359,14 +2258,13 @@ Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) {
}
void Control::_window_find_focus_neighbour(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, float p_min, float &r_closest_dist, Control **r_closest) {
-
- if (Object::cast_to<Viewport>(p_at))
+ if (Object::cast_to<Viewport>(p_at)) {
return; //bye
+ }
Control *c = Object::cast_to<Control>(p_at);
if (c && c != this && c->get_focus_mode() == FOCUS_ALL && c->is_visible_in_tree()) {
-
Point2 points[4];
Transform2D xform = c->get_global_transform();
@@ -2379,21 +2277,18 @@ void Control::_window_find_focus_neighbour(const Vector2 &p_dir, Node *p_at, con
float min = 1e7;
for (int i = 0; i < 4; i++) {
-
float d = p_dir.dot(points[i]);
- if (d < min)
+ if (d < min) {
min = d;
+ }
}
if (min > (p_min - CMP_EPSILON)) {
-
for (int i = 0; i < 4; i++) {
-
Vector2 la = p_points[i];
Vector2 lb = p_points[(i + 1) % 4];
for (int j = 0; j < 4; j++) {
-
Vector2 fa = points[j];
Vector2 fb = points[(j + 1) % 4];
@@ -2410,19 +2305,19 @@ void Control::_window_find_focus_neighbour(const Vector2 &p_dir, Node *p_at, con
}
for (int i = 0; i < p_at->get_child_count(); i++) {
-
Node *child = p_at->get_child(i);
Control *childc = Object::cast_to<Control>(child);
- if (childc && childc->data.RI)
+ if (childc && childc->data.RI) {
continue; //subwindow, ignore
+ }
_window_find_focus_neighbour(p_dir, p_at->get_child(i), p_points, p_min, r_closest_dist, r_closest);
}
}
void Control::set_h_size_flags(int p_flags) {
-
- if (data.h_size_flags == p_flags)
+ if (data.h_size_flags == p_flags) {
return;
+ }
data.h_size_flags = p_flags;
emit_signal(SceneStringNames::get_singleton()->size_flags_changed);
}
@@ -2430,47 +2325,47 @@ void Control::set_h_size_flags(int p_flags) {
int Control::get_h_size_flags() const {
return data.h_size_flags;
}
-void Control::set_v_size_flags(int p_flags) {
- if (data.v_size_flags == p_flags)
+void Control::set_v_size_flags(int p_flags) {
+ if (data.v_size_flags == p_flags) {
return;
+ }
data.v_size_flags = p_flags;
emit_signal(SceneStringNames::get_singleton()->size_flags_changed);
}
void Control::set_stretch_ratio(float p_ratio) {
-
- if (data.expand == p_ratio)
+ if (data.expand == p_ratio) {
return;
+ }
data.expand = p_ratio;
emit_signal(SceneStringNames::get_singleton()->size_flags_changed);
}
float Control::get_stretch_ratio() const {
-
return data.expand;
}
void Control::grab_click_focus() {
-
ERR_FAIL_COND(!is_inside_tree());
get_viewport()->_gui_grab_click_focus(this);
}
void Control::minimum_size_changed() {
-
- if (!is_inside_tree() || data.block_minimum_size_adjust)
+ if (!is_inside_tree() || data.block_minimum_size_adjust) {
return;
+ }
Control *invalidate = this;
//invalidate cache upwards
while (invalidate && invalidate->data.minimum_size_valid) {
invalidate->data.minimum_size_valid = false;
- if (invalidate->is_set_as_toplevel())
+ if (invalidate->is_set_as_toplevel()) {
break; // do not go further up
+ }
if (!invalidate->data.parent && get_parent()) {
Window *parent_window = Object::cast_to<Window>(get_parent());
if (parent_window && parent_window->is_wrapping_controls()) {
@@ -2480,11 +2375,13 @@ void Control::minimum_size_changed() {
invalidate = invalidate->data.parent;
}
- if (!is_visible_in_tree())
+ if (!is_visible_in_tree()) {
return;
+ }
- if (data.updating_last_minimum_size)
+ if (data.updating_last_minimum_size) {
return;
+ }
data.updating_last_minimum_size = true;
@@ -2496,19 +2393,16 @@ int Control::get_v_size_flags() const {
}
void Control::set_mouse_filter(MouseFilter p_filter) {
-
ERR_FAIL_INDEX(p_filter, 3);
data.mouse_filter = p_filter;
update_configuration_warning();
}
Control::MouseFilter Control::get_mouse_filter() const {
-
return data.mouse_filter;
}
Control *Control::get_focus_owner() const {
-
ERR_FAIL_COND_V(!is_inside_tree(), nullptr);
return get_viewport()->_gui_get_focus_owner();
}
@@ -2533,7 +2427,6 @@ bool Control::is_text_field() const {
}
void Control::set_rotation(float p_radians) {
-
data.rotation = p_radians;
update();
_notify_transform();
@@ -2541,7 +2434,6 @@ void Control::set_rotation(float p_radians) {
}
float Control::get_rotation() const {
-
return data.rotation;
}
@@ -2554,14 +2446,12 @@ float Control::get_rotation_degrees() const {
}
void Control::_override_changed() {
-
notification(NOTIFICATION_THEME_CHANGED);
emit_signal(SceneStringNames::get_singleton()->theme_changed);
minimum_size_changed(); // overrides are likely to affect minimum size
}
void Control::set_pivot_offset(const Vector2 &p_pivot) {
-
data.pivot_offset = p_pivot;
update();
_notify_transform();
@@ -2569,39 +2459,38 @@ void Control::set_pivot_offset(const Vector2 &p_pivot) {
}
Vector2 Control::get_pivot_offset() const {
-
return data.pivot_offset;
}
void Control::set_scale(const Vector2 &p_scale) {
-
data.scale = p_scale;
// Avoid having 0 scale values, can lead to errors in physics and rendering.
- if (data.scale.x == 0)
+ if (data.scale.x == 0) {
data.scale.x = CMP_EPSILON;
- if (data.scale.y == 0)
+ }
+ if (data.scale.y == 0) {
data.scale.y = CMP_EPSILON;
+ }
update();
_notify_transform();
}
-Vector2 Control::get_scale() const {
+Vector2 Control::get_scale() const {
return data.scale;
}
Control *Control::get_root_parent_control() const {
-
const CanvasItem *ci = this;
const Control *root = this;
while (ci) {
-
const Control *c = Object::cast_to<Control>(ci);
if (c) {
root = c;
- if (c->data.RI || c->is_toplevel_control())
+ if (c->data.RI || c->is_toplevel_control()) {
break;
+ }
}
ci = ci->get_parent_item();
@@ -2615,23 +2504,19 @@ void Control::set_block_minimum_size_adjust(bool p_block) {
}
bool Control::is_minimum_size_adjust_blocked() const {
-
return data.block_minimum_size_adjust;
}
void Control::set_disable_visibility_clip(bool p_ignore) {
-
data.disable_visibility_clip = p_ignore;
update();
}
bool Control::is_visibility_clip_disabled() const {
-
return data.disable_visibility_clip;
}
void Control::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-
#ifdef TOOLS_ENABLED
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\"";
#else
@@ -2674,18 +2559,15 @@ String Control::get_configuration_warning() const {
}
void Control::set_clip_contents(bool p_clip) {
-
data.clip_contents = p_clip;
update();
}
bool Control::is_clipping_contents() {
-
return data.clip_contents;
}
void Control::set_h_grow_direction(GrowDirection p_direction) {
-
ERR_FAIL_INDEX((int)p_direction, 3);
data.h_grow = p_direction;
@@ -2693,24 +2575,21 @@ void Control::set_h_grow_direction(GrowDirection p_direction) {
}
Control::GrowDirection Control::get_h_grow_direction() const {
-
return data.h_grow;
}
void Control::set_v_grow_direction(GrowDirection p_direction) {
-
ERR_FAIL_INDEX((int)p_direction, 3);
data.v_grow = p_direction;
_size_changed();
}
-Control::GrowDirection Control::get_v_grow_direction() const {
+Control::GrowDirection Control::get_v_grow_direction() const {
return data.v_grow;
}
void Control::_bind_methods() {
-
//ClassDB::bind_method(D_METHOD("_window_resize_event"),&Control::_window_resize_event);
ClassDB::bind_method(D_METHOD("_update_minimum_size"), &Control::_update_minimum_size);
@@ -2896,7 +2775,7 @@ void Control::_bind_methods() {
ADD_GROUP("Size Flags", "size_flags_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_horizontal", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_h_size_flags", "get_h_size_flags");
ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_vertical", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_v_size_flags", "get_v_size_flags");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_stretch_ratio", "get_stretch_ratio");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,20,0.01,or_greater"), "set_stretch_ratio", "get_stretch_ratio");
ADD_GROUP("Theme", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme");
ADD_GROUP("", "");
@@ -2983,8 +2862,8 @@ void Control::_bind_methods() {
BIND_VMETHOD(MethodInfo(Variant::BOOL, "has_point", PropertyInfo(Variant::VECTOR2, "point")));
}
-Control::Control() {
+Control::Control() {
data.parent = nullptr;
data.mouse_filter = MOUSE_FILTER_STOP;
diff --git a/scene/gui/control.h b/scene/gui/control.h
index d02fea20a6..10d6ad168f 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -44,7 +44,6 @@ class Label;
class Panel;
class Control : public CanvasItem {
-
GDCLASS(Control, CanvasItem);
OBJ_CATEGORY("GUI Nodes");
@@ -132,17 +131,16 @@ public:
private:
struct CComparator {
-
bool operator()(const Control *p_a, const Control *p_b) const {
- if (p_a->get_canvas_layer() == p_b->get_canvas_layer())
+ if (p_a->get_canvas_layer() == p_b->get_canvas_layer()) {
return p_b->is_greater_than(p_a);
+ }
return p_a->get_canvas_layer() < p_b->get_canvas_layer();
}
};
struct Data {
-
Point2 pos_cache;
Size2 size_cache;
Size2 minimum_size_cache;
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index 5654219a3e..c6897fc684 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -55,11 +55,9 @@ void AcceptDialog::_parent_focused() {
}
void AcceptDialog::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
-
get_ok()->grab_focus();
_update_child_rects();
parent_visible = get_parent_visible_window();
@@ -98,20 +96,18 @@ void AcceptDialog::_notification(int p_what) {
}
void AcceptDialog::_text_entered(const String &p_text) {
-
_ok_pressed();
}
void AcceptDialog::_ok_pressed() {
-
- if (hide_on_ok)
+ if (hide_on_ok) {
set_visible(false);
+ }
ok_pressed();
emit_signal("confirmed");
}
void AcceptDialog::_cancel_pressed() {
-
Window *parent_window = parent_visible;
if (parent_visible) {
parent_visible->disconnect("focus_entered", callable_mp(this, &AcceptDialog::_parent_focused));
@@ -130,11 +126,10 @@ void AcceptDialog::_cancel_pressed() {
}
String AcceptDialog::get_text() const {
-
return label->get_text();
}
-void AcceptDialog::set_text(String p_text) {
+void AcceptDialog::set_text(String p_text) {
label->set_text(p_text);
child_controls_changed();
if (is_visible()) {
@@ -143,33 +138,30 @@ void AcceptDialog::set_text(String p_text) {
}
void AcceptDialog::set_hide_on_ok(bool p_hide) {
-
hide_on_ok = p_hide;
}
-bool AcceptDialog::get_hide_on_ok() const {
+bool AcceptDialog::get_hide_on_ok() const {
return hide_on_ok;
}
void AcceptDialog::set_autowrap(bool p_autowrap) {
-
label->set_autowrap(p_autowrap);
}
-bool AcceptDialog::has_autowrap() {
+bool AcceptDialog::has_autowrap() {
return label->has_autowrap();
}
void AcceptDialog::register_text_enter(Node *p_line_edit) {
-
ERR_FAIL_NULL(p_line_edit);
LineEdit *line_edit = Object::cast_to<LineEdit>(p_line_edit);
- if (line_edit)
+ if (line_edit) {
line_edit->connect("text_entered", callable_mp(this, &AcceptDialog::_text_entered));
+ }
}
void AcceptDialog::_update_child_rects() {
-
Size2 label_size = label->get_minimum_size();
if (label->get_text().empty()) {
label_size.height = 0;
@@ -183,11 +175,13 @@ void AcceptDialog::_update_child_rects() {
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
+ }
- if (c == hbc || c == label || c == bg || c->is_set_as_toplevel())
+ if (c == hbc || c == label || c == bg || c->is_set_as_toplevel()) {
continue;
+ }
c->set_position(cpos);
c->set_size(csize);
@@ -204,17 +198,18 @@ void AcceptDialog::_update_child_rects() {
}
Size2 AcceptDialog::_get_contents_minimum_size() const {
-
int margin = hbc->get_theme_constant("margin", "Dialogs");
Size2 minsize = label->get_combined_minimum_size();
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
+ }
- if (c == hbc || c == label || c->is_set_as_toplevel())
+ if (c == hbc || c == label || c->is_set_as_toplevel()) {
continue;
+ }
Size2 cminsize = c->get_combined_minimum_size();
minsize.x = MAX(cminsize.x, minsize.x);
@@ -233,20 +228,17 @@ Size2 AcceptDialog::_get_contents_minimum_size() const {
}
void AcceptDialog::_custom_action(const String &p_action) {
-
emit_signal("custom_action", p_action);
custom_action(p_action);
}
Button *AcceptDialog::add_button(const String &p_text, bool p_right, const String &p_action) {
-
Button *button = memnew(Button);
button->set_text(p_text);
if (p_right) {
hbc->add_child(button);
hbc->add_spacer();
} else {
-
hbc->add_child(button);
hbc->move_child(button, 0);
hbc->add_spacer(true);
@@ -260,17 +252,16 @@ Button *AcceptDialog::add_button(const String &p_text, bool p_right, const Strin
}
Button *AcceptDialog::add_cancel(const String &p_cancel) {
-
String c = p_cancel;
- if (p_cancel == "")
+ if (p_cancel == "") {
c = RTR("Cancel");
+ }
Button *b = swap_ok_cancel ? add_button(c, true) : add_button(c);
b->connect("pressed", callable_mp(this, &AcceptDialog::_cancel_pressed));
return b;
}
void AcceptDialog::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_ok"), &AcceptDialog::get_ok);
ClassDB::bind_method(D_METHOD("get_label"), &AcceptDialog::get_label);
ClassDB::bind_method(D_METHOD("set_hide_on_ok", "enabled"), &AcceptDialog::set_hide_on_ok);
@@ -295,12 +286,10 @@ void AcceptDialog::_bind_methods() {
bool AcceptDialog::swap_ok_cancel = false;
void AcceptDialog::set_swap_ok_cancel(bool p_swap) {
-
swap_ok_cancel = p_swap;
}
AcceptDialog::AcceptDialog() {
-
parent_visible = nullptr;
set_wrap_controls(true);
@@ -344,17 +333,14 @@ AcceptDialog::~AcceptDialog() {
// ConfirmationDialog
void ConfirmationDialog::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_cancel"), &ConfirmationDialog::get_cancel);
}
Button *ConfirmationDialog::get_cancel() {
-
return cancel;
}
ConfirmationDialog::ConfirmationDialog() {
-
set_title(RTR("Please Confirm..."));
#ifdef TOOLS_ENABLED
set_min_size(Size2(200, 70) * EDSCALE);
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index b68b4297d7..5d7b6272bf 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -42,7 +42,6 @@
class LineEdit;
class AcceptDialog : public Window {
-
GDCLASS(AcceptDialog, Window);
Window *parent_visible;
@@ -98,7 +97,6 @@ public:
};
class ConfirmationDialog : public AcceptDialog {
-
GDCLASS(ConfirmationDialog, AcceptDialog);
Button *cancel;
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 89d13ecd7f..be6b542ae1 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -45,7 +45,6 @@ VBoxContainer *FileDialog::get_vbox() {
}
void FileDialog::_theme_changed() {
-
Color font_color = vbox->get_theme_color("font_color", "ToolButton");
Color font_color_hover = vbox->get_theme_color("font_color_hover", "ToolButton");
Color font_color_pressed = vbox->get_theme_color("font_color_pressed", "ToolButton");
@@ -64,15 +63,12 @@ void FileDialog::_theme_changed() {
}
void FileDialog::_notification(int p_what) {
-
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
if (!is_visible()) {
-
set_process_unhandled_input(false);
}
}
if (p_what == NOTIFICATION_ENTER_TREE) {
-
dir_up->set_icon(vbox->get_theme_icon("parent_folder", "FileDialog"));
refresh->set_icon(vbox->get_theme_icon("reload", "FileDialog"));
show_hidden->set_icon(vbox->get_theme_icon("toggle_hidden", "FileDialog"));
@@ -81,18 +77,13 @@ void FileDialog::_notification(int p_what) {
}
void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventKey> k = p_event;
if (k.is_valid() && has_focus()) {
-
if (k->is_pressed()) {
-
bool handled = true;
switch (k->get_keycode()) {
-
case KEY_H: {
-
if (k->get_command()) {
set_show_hidden_files(!show_hidden_files);
} else {
@@ -101,11 +92,9 @@ void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
} break;
case KEY_F5: {
-
invalidate();
} break;
case KEY_BACKSPACE: {
-
_dir_entered("..");
} break;
default: {
@@ -113,24 +102,22 @@ void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
}
}
- if (handled)
+ if (handled) {
set_input_as_handled();
+ }
}
}
}
void FileDialog::set_enable_multiple_selection(bool p_enable) {
-
tree->set_select_mode(p_enable ? Tree::SELECT_MULTI : Tree::SELECT_SINGLE);
};
Vector<String> FileDialog::get_selected_files() const {
-
Vector<String> list;
TreeItem *item = tree->get_root();
while ((item = tree->get_next_selected(item))) {
-
list.push_back(dir_access->get_current_dir().plus_file(item->get_text(0)));
};
@@ -138,7 +125,6 @@ Vector<String> FileDialog::get_selected_files() const {
};
void FileDialog::update_dir() {
-
dir->set_text(dir_access->get_current_dir(false));
if (drives->is_visible()) {
@@ -150,7 +136,6 @@ void FileDialog::update_dir() {
}
void FileDialog::_dir_entered(String p_dir) {
-
dir_access->change_dir(p_dir);
file->set_text("");
invalidate();
@@ -158,7 +143,6 @@ void FileDialog::_dir_entered(String p_dir) {
}
void FileDialog::_file_entered(const String &p_file) {
-
_action_pressed();
}
@@ -169,16 +153,16 @@ void FileDialog::_save_confirm_pressed() {
}
void FileDialog::_post_popup() {
-
ConfirmationDialog::_post_popup();
if (invalidated) {
update_file_list();
invalidated = false;
}
- if (mode == FILE_MODE_SAVE_FILE)
+ if (mode == FILE_MODE_SAVE_FILE) {
file->grab_focus();
- else
+ } else {
tree->grab_focus();
+ }
set_process_unhandled_input(true);
@@ -192,15 +176,12 @@ void FileDialog::_post_popup() {
}
void FileDialog::_action_pressed() {
-
if (mode == FILE_MODE_OPEN_FILES) {
-
TreeItem *ti = tree->get_next_selected(nullptr);
String fbase = dir_access->get_current_dir();
Vector<String> files;
while (ti) {
-
files.push_back(fbase.plus_file(ti->get_text(0)));
ti = tree->get_next_selected(ti);
}
@@ -219,7 +200,6 @@ void FileDialog::_action_pressed() {
emit_signal("file_selected", f);
hide();
} else if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_OPEN_DIR) {
-
String path = dir_access->get_current_dir();
path = path.replace("\\", "/");
@@ -236,7 +216,6 @@ void FileDialog::_action_pressed() {
}
if (mode == FILE_MODE_SAVE_FILE) {
-
bool valid = false;
if (filter->get_selected() == filter->get_item_count() - 1) {
@@ -244,29 +223,27 @@ void FileDialog::_action_pressed() {
} else if (filters.size() > 1 && filter->get_selected() == 0) {
// match all filters
for (int i = 0; i < filters.size(); i++) {
-
String flt = filters[i].get_slice(";", 0);
for (int j = 0; j < flt.get_slice_count(","); j++) {
-
String str = flt.get_slice(",", j).strip_edges();
if (f.match(str)) {
valid = true;
break;
}
}
- if (valid)
+ if (valid) {
break;
+ }
}
} else {
int idx = filter->get_selected();
- if (filters.size() > 1)
+ if (filters.size() > 1) {
idx--;
+ }
if (idx >= 0 && idx < filters.size()) {
-
String flt = filters[idx].get_slice(";", 0);
int filterSliceCount = flt.get_slice_count(",");
for (int j = 0; j < filterSliceCount; j++) {
-
String str = (flt.get_slice(",", j).strip_edges());
if (f.match(str)) {
valid = true;
@@ -286,7 +263,6 @@ void FileDialog::_action_pressed() {
}
if (!valid) {
-
exterr->popup_centered(Size2(250, 80));
return;
}
@@ -295,7 +271,6 @@ void FileDialog::_action_pressed() {
confirm_save->set_text(RTR("File Exists, Overwrite?"));
confirm_save->popup_centered(Size2(200, 80));
} else {
-
emit_signal("file_selected", f);
hide();
}
@@ -303,27 +278,28 @@ void FileDialog::_action_pressed() {
}
void FileDialog::_cancel_pressed() {
-
file->set_text("");
invalidate();
hide();
}
bool FileDialog::_is_open_should_be_disabled() {
-
- if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_SAVE_FILE)
+ if (mode == FILE_MODE_OPEN_ANY || mode == FILE_MODE_SAVE_FILE) {
return false;
+ }
TreeItem *ti = tree->get_next_selected(tree->get_root());
while (ti) {
TreeItem *prev_ti = ti;
ti = tree->get_next_selected(tree->get_root());
- if (ti == prev_ti)
+ if (ti == prev_ti) {
break;
+ }
}
// We have something that we can't select?
- if (!ti)
+ if (!ti) {
return mode != FILE_MODE_OPEN_DIR; // In "Open folder" mode, having nothing selected picks the current folder.
+ }
Dictionary d = ti->get_metadata(0);
@@ -333,14 +309,12 @@ bool FileDialog::_is_open_should_be_disabled() {
}
void FileDialog::_go_up() {
-
dir_access->change_dir("..");
update_file_list();
update_dir();
}
void FileDialog::deselect_items() {
-
// Clear currently selected items in file manager.
tree->deselect_all();
@@ -349,7 +323,6 @@ void FileDialog::deselect_items() {
get_ok()->set_disabled(_is_open_should_be_disabled());
switch (mode) {
-
case FILE_MODE_OPEN_FILE:
case FILE_MODE_OPEN_FILES:
get_ok()->set_text(RTR("Open"));
@@ -370,14 +343,13 @@ void FileDialog::_tree_multi_selected(Object *p_object, int p_cell, bool p_selec
}
void FileDialog::_tree_selected() {
-
TreeItem *ti = tree->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
Dictionary d = ti->get_metadata(0);
if (!d["dir"]) {
-
file->set_text(d["name"]);
} else if (mode == FILE_MODE_OPEN_DIR) {
get_ok()->set_text(RTR("Select This Folder"));
@@ -387,22 +359,21 @@ void FileDialog::_tree_selected() {
}
void FileDialog::_tree_item_activated() {
-
TreeItem *ti = tree->get_selected();
- if (!ti)
+ if (!ti) {
return;
+ }
Dictionary d = ti->get_metadata(0);
if (d["dir"]) {
-
dir_access->change_dir(d["name"]);
- if (mode == FILE_MODE_OPEN_FILE || mode == FILE_MODE_OPEN_FILES || mode == FILE_MODE_OPEN_DIR || mode == FILE_MODE_OPEN_ANY)
+ if (mode == FILE_MODE_OPEN_FILE || mode == FILE_MODE_OPEN_FILES || mode == FILE_MODE_OPEN_DIR || mode == FILE_MODE_OPEN_ANY) {
file->set_text("");
+ }
call_deferred("_update_file_list");
call_deferred("_update_dir");
} else {
-
_action_pressed();
}
}
@@ -410,7 +381,9 @@ void FileDialog::_tree_item_activated() {
void FileDialog::update_file_name() {
int idx = filter->get_selected() - 1;
if ((idx == -1 && filter->get_item_count() == 2) || (filter->get_item_count() > 2 && idx >= 0 && idx < filter->get_item_count() - 2)) {
- if (idx == -1) idx += 1;
+ if (idx == -1) {
+ idx += 1;
+ }
String filter_str = filters[idx];
String file_str = file->get_text();
String base_name = file_str.get_basename();
@@ -420,7 +393,6 @@ void FileDialog::update_file_name() {
}
void FileDialog::update_file_list() {
-
tree->clear();
// Scroll back to the top after opening a directory
@@ -438,17 +410,18 @@ void FileDialog::update_file_list() {
String item;
while ((item = dir_access->get_next()) != "") {
-
- if (item == "." || item == "..")
+ if (item == "." || item == "..") {
continue;
+ }
is_hidden = dir_access->current_is_hidden();
if (show_hidden_files || !is_hidden) {
- if (!dir_access->current_is_dir())
+ if (!dir_access->current_is_dir()) {
files.push_back(item);
- else
+ } else {
dirs.push_back(item);
+ }
}
}
@@ -474,28 +447,24 @@ void FileDialog::update_file_list() {
List<String> patterns;
// build filter
if (filter->get_selected() == filter->get_item_count() - 1) {
-
// match all
} else if (filters.size() > 1 && filter->get_selected() == 0) {
// match all filters
for (int i = 0; i < filters.size(); i++) {
-
String f = filters[i].get_slice(";", 0);
for (int j = 0; j < f.get_slice_count(","); j++) {
-
patterns.push_back(f.get_slice(",", j).strip_edges());
}
}
} else {
int idx = filter->get_selected();
- if (filters.size() > 1)
+ if (filters.size() > 1) {
idx--;
+ }
if (idx >= 0 && idx < filters.size()) {
-
String f = filters[idx].get_slice(";", 0);
for (int j = 0; j < f.get_slice_count(","); j++) {
-
patterns.push_back(f.get_slice(",", j).strip_edges());
}
}
@@ -504,12 +473,10 @@ void FileDialog::update_file_list() {
String base_dir = dir_access->get_current_dir();
while (!files.empty()) {
-
bool match = patterns.empty();
String match_str;
for (List<String>::Element *E = patterns.front(); E; E = E->next()) {
-
if (files.front()->get().matchn(E->get())) {
match_str = E->get();
match = true;
@@ -522,7 +489,6 @@ void FileDialog::update_file_list() {
ti->set_text(0, files.front()->get());
if (get_icon_func) {
-
Ref<Texture2D> icon = get_icon_func(base_dir.plus_file(files.front()->get()));
ti->set_icon(0, icon);
}
@@ -536,25 +502,25 @@ void FileDialog::update_file_list() {
d["dir"] = false;
ti->set_metadata(0, d);
- if (file->get_text() == files.front()->get() || match_str == files.front()->get())
+ if (file->get_text() == files.front()->get() || match_str == files.front()->get()) {
ti->select(0);
+ }
}
files.pop_front();
}
- if (tree->get_root() && tree->get_root()->get_children() && tree->get_selected() == nullptr)
+ if (tree->get_root() && tree->get_root()->get_children() && tree->get_selected() == nullptr) {
tree->get_root()->get_children()->select(0);
+ }
}
void FileDialog::_filter_selected(int) {
-
update_file_name();
update_file_list();
}
void FileDialog::update_filters() {
-
filter->clear();
if (filters.size() > 1) {
@@ -564,37 +530,38 @@ void FileDialog::update_filters() {
for (int i = 0; i < MIN(max_filters, filters.size()); i++) {
String flt = filters[i].get_slice(";", 0).strip_edges();
- if (i > 0)
+ if (i > 0) {
all_filters += ", ";
+ }
all_filters += flt;
}
- if (max_filters < filters.size())
+ if (max_filters < filters.size()) {
all_filters += ", ...";
+ }
filter->add_item(RTR("All Recognized") + " (" + all_filters + ")");
}
for (int i = 0; i < filters.size(); i++) {
-
String flt = filters[i].get_slice(";", 0).strip_edges();
String desc = filters[i].get_slice(";", 1).strip_edges();
- if (desc.length())
+ if (desc.length()) {
filter->add_item(String(tr(desc)) + " (" + flt + ")");
- else
+ } else {
filter->add_item("(" + flt + ")");
+ }
}
filter->add_item(RTR("All Files (*)"));
}
void FileDialog::clear_filters() {
-
filters.clear();
update_filters();
invalidate();
}
-void FileDialog::add_filter(const String &p_filter) {
+void FileDialog::add_filter(const String &p_filter) {
filters.push_back(p_filter);
update_filters();
invalidate();
@@ -611,45 +578,44 @@ Vector<String> FileDialog::get_filters() const {
}
String FileDialog::get_current_dir() const {
-
return dir->get_text();
}
-String FileDialog::get_current_file() const {
+String FileDialog::get_current_file() const {
return file->get_text();
}
-String FileDialog::get_current_path() const {
+String FileDialog::get_current_path() const {
return dir->get_text().plus_file(file->get_text());
}
-void FileDialog::set_current_dir(const String &p_dir) {
+void FileDialog::set_current_dir(const String &p_dir) {
dir_access->change_dir(p_dir);
update_dir();
invalidate();
}
-void FileDialog::set_current_file(const String &p_file) {
+void FileDialog::set_current_file(const String &p_file) {
file->set_text(p_file);
update_dir();
invalidate();
int lp = p_file.find_last(".");
if (lp != -1) {
file->select(0, lp);
- if (file->is_inside_tree() && !get_tree()->is_node_being_edited(file))
+ if (file->is_inside_tree() && !get_tree()->is_node_being_edited(file)) {
file->grab_focus();
+ }
}
}
-void FileDialog::set_current_path(const String &p_path) {
- if (!p_path.size())
+void FileDialog::set_current_path(const String &p_path) {
+ if (!p_path.size()) {
return;
+ }
int pos = MAX(p_path.find_last("/"), p_path.find_last("\\"));
if (pos == -1) {
-
set_current_file(p_path);
} else {
-
String dir = p_path.substr(0, pos);
String file = p_path.substr(pos + 1, p_path.length());
set_current_dir(dir);
@@ -666,40 +632,43 @@ bool FileDialog::is_mode_overriding_title() const {
}
void FileDialog::set_file_mode(FileMode p_mode) {
-
ERR_FAIL_INDEX((int)p_mode, 5);
mode = p_mode;
switch (mode) {
-
case FILE_MODE_OPEN_FILE:
get_ok()->set_text(RTR("Open"));
- if (mode_overrides_title)
+ if (mode_overrides_title) {
set_title(RTR("Open a File"));
+ }
makedir->hide();
break;
case FILE_MODE_OPEN_FILES:
get_ok()->set_text(RTR("Open"));
- if (mode_overrides_title)
+ if (mode_overrides_title) {
set_title(RTR("Open File(s)"));
+ }
makedir->hide();
break;
case FILE_MODE_OPEN_DIR:
get_ok()->set_text(RTR("Select Current Folder"));
- if (mode_overrides_title)
+ if (mode_overrides_title) {
set_title(RTR("Open a Directory"));
+ }
makedir->show();
break;
case FILE_MODE_OPEN_ANY:
get_ok()->set_text(RTR("Open"));
- if (mode_overrides_title)
+ if (mode_overrides_title) {
set_title(RTR("Open a File or Directory"));
+ }
makedir->show();
break;
case FILE_MODE_SAVE_FILE:
get_ok()->set_text(RTR("Save"));
- if (mode_overrides_title)
+ if (mode_overrides_title) {
set_title(RTR("Save a File"));
+ }
makedir->show();
break;
}
@@ -712,27 +681,23 @@ void FileDialog::set_file_mode(FileMode p_mode) {
}
FileDialog::FileMode FileDialog::get_file_mode() const {
-
return mode;
}
void FileDialog::set_access(Access p_access) {
-
ERR_FAIL_INDEX(p_access, 3);
- if (access == p_access)
+ if (access == p_access) {
return;
+ }
memdelete(dir_access);
switch (p_access) {
case ACCESS_FILESYSTEM: {
-
dir_access = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
} break;
case ACCESS_RESOURCES: {
-
dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
} break;
case ACCESS_USERDATA: {
-
dir_access = DirAccess::create(DirAccess::ACCESS_USERDATA);
} break;
}
@@ -744,7 +709,6 @@ void FileDialog::set_access(Access p_access) {
}
void FileDialog::invalidate() {
-
if (is_visible()) {
update_file_list();
invalidated = false;
@@ -754,12 +718,10 @@ void FileDialog::invalidate() {
}
FileDialog::Access FileDialog::get_access() const {
-
return access;
}
void FileDialog::_make_dir_confirm() {
-
Error err = dir_access->make_dir(makedirname->get_text());
if (err == OK) {
dir_access->change_dir(makedirname->get_text());
@@ -773,13 +735,11 @@ void FileDialog::_make_dir_confirm() {
}
void FileDialog::_make_dir() {
-
makedialog->popup_centered(Size2(250, 80));
makedirname->grab_focus();
}
void FileDialog::_select_drive(int p_idx) {
-
String d = drives->get_item_text(p_idx);
dir_access->change_dir(d);
file->set_text("");
@@ -788,7 +748,6 @@ void FileDialog::_select_drive(int p_idx) {
}
void FileDialog::_update_drives() {
-
int dc = dir_access->get_drive_count();
if (dc == 0 || access != ACCESS_FILESYSTEM) {
drives->hide();
@@ -813,7 +772,6 @@ void FileDialog::_update_drives() {
bool FileDialog::default_show_hidden_files = false;
void FileDialog::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_unhandled_input"), &FileDialog::_unhandled_input);
ClassDB::bind_method(D_METHOD("_cancel_pressed"), &FileDialog::_cancel_pressed);
@@ -883,7 +841,6 @@ void FileDialog::set_default_show_hidden_files(bool p_show) {
}
FileDialog::FileDialog() {
-
show_hidden_files = default_show_hidden_files;
mode_overrides_title = true;
@@ -996,13 +953,14 @@ FileDialog::FileDialog() {
set_hide_on_ok(false);
invalidated = true;
- if (register_func)
+ if (register_func) {
register_func(this);
+ }
}
FileDialog::~FileDialog() {
-
- if (unregister_func)
+ if (unregister_func) {
unregister_func(this);
+ }
memdelete(dir_access);
}
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index ac0e733abc..8bc536d576 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -40,7 +40,6 @@
#include "scene/gui/tree.h"
class FileDialog : public ConfirmationDialog {
-
GDCLASS(FileDialog, ConfirmationDialog);
public:
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 88107f754c..ecd4ad17ea 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -73,8 +73,9 @@ int GradientEdit::_get_point_from_pos(int x) {
}
void GradientEdit::_show_color_picker() {
- if (grabbed == -1)
+ if (grabbed == -1) {
return;
+ }
picker->set_pick_color(points[grabbed].color);
Size2 minsize = popup->get_contents_minimum_size();
bool show_above = false;
@@ -93,11 +94,9 @@ GradientEdit::~GradientEdit() {
}
void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed() && k->get_keycode() == KEY_DELETE && grabbed != -1) {
-
points.remove(grabbed);
grabbed = -1;
grabbing = false;
@@ -129,7 +128,6 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
//Hold alt key to duplicate selected color
if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed() && mb->get_alt()) {
-
int x = mb->get_position().x;
grabbed = _get_point_from_pos(x);
@@ -154,7 +152,6 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
//select
if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
-
update();
int x = mb->get_position().x;
int total_w = get_size().width - get_size().height - SPACING;
@@ -182,12 +179,12 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
int pos = -1;
for (int i = 0; i < points.size(); i++) {
- if (points[i].offset < newPoint.offset)
+ if (points[i].offset < newPoint.offset) {
pos = i;
+ }
}
if (pos == -1) {
-
prev.color = Color(0, 0, 0);
prev.offset = 0;
if (points.size()) {
@@ -197,7 +194,6 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
next.offset = 1.0;
}
} else {
-
if (pos == points.size() - 1) {
next.color = Color(1, 1, 1);
next.offset = 1.0;
@@ -207,7 +203,7 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
prev = points[pos];
}
- newPoint.color = prev.color.linear_interpolate(next.color, (newPoint.offset - prev.offset) / (next.offset - prev.offset));
+ newPoint.color = prev.color.lerp(next.color, (newPoint.offset - prev.offset) / (next.offset - prev.offset));
points.push_back(newPoint);
points.sort();
@@ -222,7 +218,6 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) {
-
if (grabbing) {
grabbing = false;
emit_signal("ramp_changed");
@@ -233,7 +228,6 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && grabbing) {
-
int total_w = get_size().width - get_size().height - SPACING;
int x = mm->get_position().x;
@@ -256,24 +250,25 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
if (temp_ofs < smallest_ofs) {
smallest_ofs = temp_ofs;
nearest_point = i;
- if (found)
+ if (found) {
break;
+ }
found = true;
}
}
}
if (found) {
- if (points[nearest_point].offset < newofs)
+ if (points[nearest_point].offset < newofs) {
newofs = points[nearest_point].offset + 0.00001;
- else
+ } else {
newofs = points[nearest_point].offset - 0.00001;
+ }
newofs = CLAMP(newofs, 0, 1);
}
}
bool valid = true;
for (int i = 0; i < points.size(); i++) {
-
if (points[i].offset == newofs && i != grabbed) {
valid = false;
break;
@@ -300,19 +295,18 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
}
void GradientEdit::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
if (!picker->is_connected("color_changed", callable_mp(this, &GradientEdit::_color_changed))) {
picker->connect("color_changed", callable_mp(this, &GradientEdit::_color_changed));
}
}
if (p_what == NOTIFICATION_DRAW) {
-
int w = get_size().x;
int h = get_size().y;
- if (w == 0 || h == 0)
+ if (w == 0 || h == 0) {
return; //Safety check. We have division by 'h'. And in any case there is nothing to draw with such size
+ }
int total_w = get_size().width - get_size().height - SPACING;
@@ -322,20 +316,21 @@ void GradientEdit::_notification(int p_what) {
//Draw color ramp
Gradient::Point prev;
prev.offset = 0;
- if (points.size() == 0)
+ if (points.size() == 0) {
prev.color = Color(0, 0, 0); //Draw black rectangle if we have no points
- else
+ } else {
prev.color = points[0].color; //Extend color of first point to the beginning.
+ }
for (int i = -1; i < points.size(); i++) {
-
Gradient::Point next;
//If there is no next point
if (i + 1 == points.size()) {
- if (points.size() == 0)
+ if (points.size() == 0) {
next.color = Color(0, 0, 0); //Draw black rectangle if we have no points
- else
+ } else {
next.color = points[i].color; //Extend color of last point to the end.
+ }
next.offset = 1;
} else {
next = points[i + 1];
@@ -362,7 +357,6 @@ void GradientEdit::_notification(int p_what) {
//Draw point markers
for (int i = 0; i < points.size(); i++) {
-
Color col = points[i].color.contrasted();
col.a = 0.9;
@@ -397,7 +391,6 @@ void GradientEdit::_notification(int p_what) {
//Draw borders around color ramp if in focus
if (has_focus()) {
-
draw_line(Vector2(-1, -1), Vector2(total_w + 1, -1), Color(1, 1, 1, 0.6));
draw_line(Vector2(total_w + 1, -1), Vector2(total_w + 1, h + 1), Color(1, 1, 1, 0.6));
draw_line(Vector2(total_w + 1, h + 1), Vector2(-1, h + 1), Color(1, 1, 1, 0.6));
@@ -406,7 +399,6 @@ void GradientEdit::_notification(int p_what) {
}
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
if (!is_visible()) {
grabbing = false;
}
@@ -435,21 +427,19 @@ void GradientEdit::_draw_checker(int x, int y, int w, int h) {
}
Size2 GradientEdit::get_minimum_size() const {
-
return Vector2(0, 16);
}
void GradientEdit::_color_changed(const Color &p_color) {
-
- if (grabbed == -1)
+ if (grabbed == -1) {
return;
+ }
points.write[grabbed].color = p_color;
update();
emit_signal("ramp_changed");
}
void GradientEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors) {
-
ERR_FAIL_COND(p_offsets.size() != p_colors.size());
points.clear();
for (int i = 0; i < p_offsets.size(); i++) {
@@ -465,21 +455,24 @@ void GradientEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color>
Vector<float> GradientEdit::get_offsets() const {
Vector<float> ret;
- for (int i = 0; i < points.size(); i++)
+ for (int i = 0; i < points.size(); i++) {
ret.push_back(points[i].offset);
+ }
return ret;
}
Vector<Color> GradientEdit::get_colors() const {
Vector<Color> ret;
- for (int i = 0; i < points.size(); i++)
+ for (int i = 0; i < points.size(); i++) {
ret.push_back(points[i].color);
+ }
return ret;
}
void GradientEdit::set_points(Vector<Gradient::Point> &p_points) {
- if (points.size() != p_points.size())
+ if (points.size() != p_points.size()) {
grabbed = -1;
+ }
points.clear();
points = p_points;
}
diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h
index a38a3dde47..376837b66c 100644
--- a/scene/gui/gradient_edit.h
+++ b/scene/gui/gradient_edit.h
@@ -37,7 +37,6 @@
#include "scene/resources/gradient.h"
class GradientEdit : public Control {
-
GDCLASS(GradientEdit, Control);
PopupPanel *popup;
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 0fe65462e4..5080ba74e2 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -30,7 +30,7 @@
#include "graph_edit.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/keyboard.h"
#include "scene/gui/box_container.h"
@@ -44,19 +44,17 @@
#define MAX_ZOOM (1 * ZOOM_SCALE * ZOOM_SCALE * ZOOM_SCALE)
bool GraphEditFilter::has_point(const Point2 &p_point) const {
-
return ge->_filter_input(p_point);
}
GraphEditFilter::GraphEditFilter(GraphEdit *p_edit) {
-
ge = p_edit;
}
Error GraphEdit::connect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port) {
-
- if (is_node_connected(p_from, p_from_port, p_to, p_to_port))
+ if (is_node_connected(p_from, p_from_port, p_to, p_to_port)) {
return OK;
+ }
Connection c;
c.from = p_from;
c.from_port = p_from_port;
@@ -72,22 +70,18 @@ Error GraphEdit::connect_node(const StringName &p_from, int p_from_port, const S
}
bool GraphEdit::is_node_connected(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port) {
-
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
-
- if (E->get().from == p_from && E->get().from_port == p_from_port && E->get().to == p_to && E->get().to_port == p_to_port)
+ if (E->get().from == p_from && E->get().from_port == p_from_port && E->get().to == p_to && E->get().to_port == p_to_port) {
return true;
+ }
}
return false;
}
void GraphEdit::disconnect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port) {
-
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
-
if (E->get().from == p_from && E->get().from_port == p_from_port && E->get().to == p_to && E->get().to_port == p_to_port) {
-
connections.erase(E);
top_layer->update();
update();
@@ -98,17 +92,14 @@ void GraphEdit::disconnect_node(const StringName &p_from, int p_from_port, const
}
bool GraphEdit::clips_input() const {
-
return true;
}
void GraphEdit::get_connection_list(List<Connection> *r_connections) const {
-
*r_connections = connections;
}
void GraphEdit::set_scroll_ofs(const Vector2 &p_ofs) {
-
setting_scroll_ofs = true;
h_scroll->set_value(p_ofs.x);
v_scroll->set_value(p_ofs.y);
@@ -117,12 +108,10 @@ void GraphEdit::set_scroll_ofs(const Vector2 &p_ofs) {
}
Vector2 GraphEdit::get_scroll_ofs() const {
-
return Vector2(h_scroll->get_value(), v_scroll->get_value());
}
void GraphEdit::_scroll_moved(double) {
-
if (!awaiting_scroll_offset_update) {
call_deferred("_update_scroll_offset");
awaiting_scroll_offset_update = true;
@@ -136,14 +125,13 @@ void GraphEdit::_scroll_moved(double) {
}
void GraphEdit::_update_scroll_offset() {
-
set_block_minimum_size_adjust(true);
for (int i = 0; i < get_child_count(); i++) {
-
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
- if (!gn)
+ if (!gn) {
continue;
+ }
Point2 pos = gn->get_offset() * zoom;
pos -= Point2(h_scroll->get_value(), v_scroll->get_value());
@@ -159,9 +147,9 @@ void GraphEdit::_update_scroll_offset() {
}
void GraphEdit::_update_scroll() {
-
- if (updating)
+ if (updating) {
return;
+ }
updating = true;
@@ -169,10 +157,10 @@ void GraphEdit::_update_scroll() {
Rect2 screen;
for (int i = 0; i < get_child_count(); i++) {
-
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
- if (!gn)
+ if (!gn) {
continue;
+ }
Rect2 r;
r.position = gn->get_offset() * zoom;
@@ -186,19 +174,21 @@ void GraphEdit::_update_scroll() {
h_scroll->set_min(screen.position.x);
h_scroll->set_max(screen.position.x + screen.size.x);
h_scroll->set_page(get_size().x);
- if (h_scroll->get_max() - h_scroll->get_min() <= h_scroll->get_page())
+ if (h_scroll->get_max() - h_scroll->get_min() <= h_scroll->get_page()) {
h_scroll->hide();
- else
+ } else {
h_scroll->show();
+ }
v_scroll->set_min(screen.position.y);
v_scroll->set_max(screen.position.y + screen.size.y);
v_scroll->set_page(get_size().y);
- if (v_scroll->get_max() - v_scroll->get_min() <= v_scroll->get_page())
+ if (v_scroll->get_max() - v_scroll->get_min() <= v_scroll->get_page()) {
v_scroll->hide();
- else
+ } else {
v_scroll->show();
+ }
Size2 hmin = h_scroll->get_combined_minimum_size();
Size2 vmin = v_scroll->get_combined_minimum_size();
@@ -218,7 +208,6 @@ void GraphEdit::_update_scroll() {
}
void GraphEdit::_graph_node_raised(Node *p_gn) {
-
GraphNode *gn = Object::cast_to<GraphNode>(p_gn);
ERR_FAIL_COND(!gn);
if (gn->is_comment()) {
@@ -241,7 +230,6 @@ void GraphEdit::_graph_node_raised(Node *p_gn) {
}
void GraphEdit::_graph_node_moved(Node *p_gn) {
-
GraphNode *gn = Object::cast_to<GraphNode>(p_gn);
ERR_FAIL_COND(!gn);
top_layer->update();
@@ -250,7 +238,6 @@ void GraphEdit::_graph_node_moved(Node *p_gn) {
}
void GraphEdit::add_child_notify(Node *p_child) {
-
Control::add_child_notify(p_child);
top_layer->call_deferred("raise"); //top layer always on top!
@@ -266,7 +253,6 @@ void GraphEdit::add_child_notify(Node *p_child) {
}
void GraphEdit::remove_child_notify(Node *p_child) {
-
Control::remove_child_notify(p_child);
if (is_inside_tree()) {
top_layer->call_deferred("raise"); //top layer always on top!
@@ -279,7 +265,6 @@ void GraphEdit::remove_child_notify(Node *p_child) {
}
void GraphEdit::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
port_grab_distance_horizontal = get_theme_constant("port_grab_distance_horizontal");
port_grab_distance_vertical = get_theme_constant("port_grab_distance_vertical");
@@ -304,7 +289,6 @@ void GraphEdit::_notification(int p_what) {
v_scroll->set_anchor_and_margin(MARGIN_BOTTOM, ANCHOR_END, 0);
}
if (p_what == NOTIFICATION_DRAW) {
-
draw_style_box(get_theme_stylebox("bg"), Rect2(Point2(), get_size()));
if (is_using_snap()) {
@@ -322,26 +306,26 @@ void GraphEdit::_notification(int p_what) {
Color grid_major = get_theme_color("grid_major");
for (int i = from.x; i < from.x + len.x; i++) {
-
Color color;
- if (ABS(i) % 10 == 0)
+ if (ABS(i) % 10 == 0) {
color = grid_major;
- else
+ } else {
color = grid_minor;
+ }
float base_ofs = i * snap * zoom - offset.x * zoom;
draw_line(Vector2(base_ofs, 0), Vector2(base_ofs, get_size().height), color);
}
for (int i = from.y; i < from.y + len.y; i++) {
-
Color color;
- if (ABS(i) % 10 == 0)
+ if (ABS(i) % 10 == 0) {
color = grid_major;
- else
+ } else {
color = grid_minor;
+ }
float base_ofs = i * snap * zoom - offset.y * zoom;
draw_line(Vector2(0, base_ofs), Vector2(get_size().width, base_ofs), color);
@@ -356,24 +340,22 @@ void GraphEdit::_notification(int p_what) {
}
bool GraphEdit::_filter_input(const Point2 &p_point) {
-
Ref<Texture2D> port = get_theme_icon("port", "GraphNode");
for (int i = get_child_count() - 1; i >= 0; i--) {
-
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
- if (!gn)
+ if (!gn) {
continue;
+ }
for (int j = 0; j < gn->get_connection_output_count(); j++) {
-
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
- if (is_in_hot_zone(pos, p_point))
+ if (is_in_hot_zone(pos, p_point)) {
return true;
+ }
}
for (int j = 0; j < gn->get_connection_input_count(); j++) {
-
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
if (is_in_hot_zone(pos, p_point)) {
return true;
@@ -385,32 +367,25 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
}
void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
-
Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
-
Ref<Texture2D> port = get_theme_icon("port", "GraphNode");
Vector2 mpos(mb->get_position().x, mb->get_position().y);
for (int i = get_child_count() - 1; i >= 0; i--) {
-
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
- if (!gn)
+ if (!gn) {
continue;
+ }
for (int j = 0; j < gn->get_connection_output_count(); j++) {
-
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
if (is_in_hot_zone(pos, mpos)) {
-
if (valid_left_disconnect_types.has(gn->get_connection_output_type(j))) {
//check disconnect
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
-
if (E->get().from == gn->get_name() && E->get().from_port == j) {
-
Node *to = get_node(String(E->get().to));
if (Object::cast_to<GraphNode>(to)) {
-
connecting_from = E->get().to;
connecting_index = E->get().to_port;
connecting_out = false;
@@ -445,19 +420,14 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
}
for (int j = 0; j < gn->get_connection_input_count(); j++) {
-
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
if (is_in_hot_zone(pos, mpos)) {
-
if (right_disconnects || valid_right_disconnect_types.has(gn->get_connection_input_type(j))) {
//check disconnect
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
-
if (E->get().to == gn->get_name() && E->get().to_port == j) {
-
Node *fr = get_node(String(E->get().from));
if (Object::cast_to<GraphNode>(fr)) {
-
connecting_from = E->get().from;
connecting_index = E->get().from_port;
connecting_out = true;
@@ -496,7 +466,6 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseMotion> mm = p_ev;
if (mm.is_valid() && connecting) {
-
connecting_to = mm->get_position();
connecting_target = false;
top_layer->update();
@@ -504,18 +473,16 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
Ref<Texture2D> port = get_theme_icon("port", "GraphNode");
Vector2 mpos = mm->get_position();
for (int i = get_child_count() - 1; i >= 0; i--) {
-
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
- if (!gn)
+ if (!gn) {
continue;
+ }
if (!connecting_out) {
for (int j = 0; j < gn->get_connection_output_count(); j++) {
-
Vector2 pos = gn->get_connection_output_position(j) + gn->get_position();
int type = gn->get_connection_output_type(j);
if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) {
-
connecting_target = true;
connecting_to = pos;
connecting_target_to = gn->get_name();
@@ -524,9 +491,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
}
}
} else {
-
for (int j = 0; j < gn->get_connection_input_count(); j++) {
-
Vector2 pos = gn->get_connection_input_position(j) + gn->get_position();
int type = gn->get_connection_input_type(j);
if ((type == connecting_type || valid_connection_types.has(ConnType(type, connecting_type))) && is_in_hot_zone(pos, mpos)) {
@@ -542,9 +507,7 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
}
if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) {
-
if (connecting && connecting_target) {
-
String from = connecting_from;
int from_slot = connecting_index;
String to = connecting_target_to;
@@ -557,7 +520,6 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
emit_signal("connection_request", from, from_slot, to, to_slot);
} else if (!just_disconnected) {
-
String from = connecting_from;
int from_slot = connecting_index;
Vector2 ofs = Vector2(mb->get_position().x, mb->get_position().y);
@@ -577,16 +539,17 @@ void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
}
bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &pos) {
-
- if (p_control->is_set_as_toplevel() || !p_control->is_visible())
+ if (p_control->is_set_as_toplevel() || !p_control->is_visible()) {
return false;
+ }
if (!p_control->has_point(pos) || p_control->get_mouse_filter() == MOUSE_FILTER_IGNORE) {
//test children
for (int i = 0; i < p_control->get_child_count(); i++) {
Control *subchild = Object::cast_to<Control>(p_control->get_child(i));
- if (!subchild)
+ if (!subchild) {
continue;
+ }
if (_check_clickable_control(subchild, pos - subchild->get_position())) {
return true;
}
@@ -599,23 +562,25 @@ bool GraphEdit::_check_clickable_control(Control *p_control, const Vector2 &pos)
}
bool GraphEdit::is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos) {
- if (!Rect2(pos.x - port_grab_distance_horizontal, pos.y - port_grab_distance_vertical, port_grab_distance_horizontal * 2, port_grab_distance_vertical * 2).has_point(p_mouse_pos))
+ if (!Rect2(pos.x - port_grab_distance_horizontal, pos.y - port_grab_distance_vertical, port_grab_distance_horizontal * 2, port_grab_distance_vertical * 2).has_point(p_mouse_pos)) {
return false;
+ }
for (int i = 0; i < get_child_count(); i++) {
Control *child = Object::cast_to<Control>(get_child(i));
- if (!child)
+ if (!child) {
continue;
+ }
Rect2 rect = child->get_rect();
if (rect.has_point(p_mouse_pos)) {
-
//check sub-controls
Vector2 subpos = p_mouse_pos - rect.position;
for (int j = 0; j < child->get_child_count(); j++) {
Control *subchild = Object::cast_to<Control>(child->get_child(j));
- if (!subchild)
+ if (!subchild) {
continue;
+ }
if (_check_clickable_control(subchild, subpos - subchild->get_position())) {
return false;
@@ -640,7 +605,6 @@ static _FORCE_INLINE_ Vector2 _bezier_interp(real_t t, Vector2 start, Vector2 co
}
void GraphEdit::_bake_segment2d(Vector<Vector2> &points, Vector<Color> &colors, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_min_depth, int p_max_depth, float p_tol, const Color &p_color, const Color &p_to_color, int &lines) const {
-
float mp = p_begin + (p_end - p_begin) * 0.5;
Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
Vector2 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
@@ -651,9 +615,8 @@ void GraphEdit::_bake_segment2d(Vector<Vector2> &points, Vector<Color> &colors,
float dp = Math::rad2deg(Math::acos(na.dot(nb)));
if (p_depth >= p_min_depth && (dp < p_tol || p_depth >= p_max_depth)) {
-
points.push_back((beg + end) * 0.5);
- colors.push_back(p_color.linear_interpolate(p_to_color, mp));
+ colors.push_back(p_color.lerp(p_to_color, mp));
lines++;
} else {
_bake_segment2d(points, colors, p_begin, mp, p_a, p_out, p_b, p_in, p_depth + 1, p_min_depth, p_max_depth, p_tol, p_color, p_to_color, lines);
@@ -662,7 +625,6 @@ void GraphEdit::_bake_segment2d(Vector<Vector2> &points, Vector<Color> &colors,
}
void GraphEdit::_draw_cos_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color) {
-
//cubic bezier code
float diff = p_to.x - p_from.x;
float cp_offset;
@@ -696,12 +658,10 @@ void GraphEdit::_draw_cos_line(CanvasItem *p_where, const Vector2 &p_from, const
}
void GraphEdit::_connections_layer_draw() {
-
Color activity_color = get_theme_color("activity");
//draw connections
List<List<Connection>::Element *> to_erase;
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
-
NodePath fromnp(E->get().from);
Node *from = get_node(fromnp);
@@ -737,8 +697,8 @@ void GraphEdit::_connections_layer_draw() {
Color tocolor = gto->get_connection_input_color(E->get().to_port);
if (E->get().activity > 0) {
- color = color.linear_interpolate(activity_color, E->get().activity);
- tocolor = tocolor.linear_interpolate(activity_color, E->get().activity);
+ color = color.lerp(activity_color, E->get().activity);
+ tocolor = tocolor.lerp(activity_color, E->get().activity);
}
_draw_cos_line(connections_layer, frompos, topos, color, tocolor);
}
@@ -750,20 +710,19 @@ void GraphEdit::_connections_layer_draw() {
}
void GraphEdit::_top_layer_draw() {
-
_update_scroll();
if (connecting) {
-
Node *fromn = get_node(connecting_from);
ERR_FAIL_COND(!fromn);
GraphNode *from = Object::cast_to<GraphNode>(fromn);
ERR_FAIL_COND(!from);
Vector2 pos;
- if (connecting_out)
+ if (connecting_out) {
pos = from->get_connection_output_position(connecting_index);
- else
+ } else {
pos = from->get_connection_input_position(connecting_index);
+ }
pos += from->get_position();
Vector2 topos;
@@ -790,40 +749,34 @@ void GraphEdit::_top_layer_draw() {
}
void GraphEdit::set_selected(Node *p_child) {
-
for (int i = get_child_count() - 1; i >= 0; i--) {
-
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
- if (!gn)
+ if (!gn) {
continue;
+ }
gn->set_selected(gn == p_child);
}
}
void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
-
Ref<InputEventMouseMotion> mm = p_ev;
- if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && InputFilter::get_singleton()->is_key_pressed(KEY_SPACE)))) {
+ if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) {
h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x);
v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y);
}
if (mm.is_valid() && dragging) {
-
just_selected = true;
- // TODO: Remove local mouse pos hack if/when InputEventMouseMotion is fixed to support floats
- //drag_accum+=Vector2(mm->get_relative().x,mm->get_relative().y);
- drag_accum = get_local_mouse_position() - drag_origin;
+ drag_accum += mm->get_relative();
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
if (gn && gn->is_selected()) {
-
Vector2 pos = (gn->get_drag_from() * zoom + drag_accum) / zoom;
// Snapping can be toggled temporarily by holding down Ctrl.
// This is done here as to not toggle the grid when holding down Ctrl.
- if (is_using_snap() ^ InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+ if (is_using_snap() ^ Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
const int snap = get_snap();
pos = pos.snapped(Vector2(snap, snap));
}
@@ -834,7 +787,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
}
if (mm.is_valid() && box_selecting) {
- box_selecting_to = get_local_mouse_position();
+ box_selecting_to = mm->get_position();
box_selecting_rect = Rect2(MIN(box_selecting_from.x, box_selecting_to.x),
MIN(box_selecting_from.y, box_selecting_to.y),
@@ -842,19 +795,20 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
ABS(box_selecting_from.y - box_selecting_to.y));
for (int i = get_child_count() - 1; i >= 0; i--) {
-
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
- if (!gn)
+ if (!gn) {
continue;
+ }
Rect2 r = gn->get_rect();
r.size *= zoom;
bool in_box = r.intersects(box_selecting_rect);
- if (in_box)
+ if (in_box) {
gn->set_selected(box_selection_mode_additive);
- else
+ } else {
gn->set_selected(previus_selected.find(gn) != nullptr);
+ }
}
top_layer->update();
@@ -862,15 +816,14 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMouseButton> b = p_ev;
if (b.is_valid()) {
-
if (b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) {
if (box_selecting) {
box_selecting = false;
for (int i = get_child_count() - 1; i >= 0; i--) {
-
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
- if (!gn)
+ if (!gn) {
continue;
+ }
gn->set_selected(previus_selected.find(gn) != nullptr);
}
@@ -886,7 +839,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
}
if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && dragging) {
- if (!just_selected && drag_accum == Vector2() && InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+ if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
//deselect current node
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
@@ -894,20 +847,21 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
if (gn) {
Rect2 r = gn->get_rect();
r.size *= zoom;
- if (r.has_point(get_local_mouse_position()))
+ if (r.has_point(b->get_position())) {
gn->set_selected(false);
+ }
}
}
}
if (drag_accum != Vector2()) {
-
emit_signal("_begin_node_move");
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn = Object::cast_to<GraphNode>(get_child(i));
- if (gn && gn->is_selected())
+ if (gn && gn->is_selected()) {
gn->set_drag(false);
+ }
}
emit_signal("_end_node_move");
@@ -921,18 +875,17 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
}
if (b->get_button_index() == BUTTON_LEFT && b->is_pressed()) {
-
GraphNode *gn = nullptr;
for (int i = get_child_count() - 1; i >= 0; i--) {
-
GraphNode *gn_selected = Object::cast_to<GraphNode>(get_child(i));
if (gn_selected) {
- if (gn_selected->is_resizing())
+ if (gn_selected->is_resizing()) {
continue;
+ }
- if (gn_selected->has_point(gn_selected->get_local_mouse_position())) {
+ if (gn_selected->has_point(b->get_position() - gn_selected->get_position())) {
gn = gn_selected;
break;
}
@@ -940,15 +893,14 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
}
if (gn) {
-
- if (_filter_input(b->get_position()))
+ if (_filter_input(b->get_position())) {
return;
+ }
dragging = true;
drag_accum = Vector2();
- drag_origin = get_local_mouse_position();
just_selected = !gn->is_selected();
- if (!gn->is_selected() && !InputFilter::get_singleton()->is_key_pressed(KEY_CONTROL)) {
+ if (!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
for (int i = 0; i < get_child_count(); i++) {
GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i));
if (o_gn) {
@@ -967,28 +919,32 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
gn->set_selected(true);
for (int i = 0; i < get_child_count(); i++) {
GraphNode *o_gn = Object::cast_to<GraphNode>(get_child(i));
- if (!o_gn)
+ if (!o_gn) {
continue;
- if (o_gn->is_selected())
+ }
+ if (o_gn->is_selected()) {
o_gn->set_drag(true);
+ }
}
} else {
- if (_filter_input(b->get_position()))
+ if (_filter_input(b->get_position())) {
return;
- if (InputFilter::get_singleton()->is_key_pressed(KEY_SPACE))
+ }
+ if (Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
return;
+ }
box_selecting = true;
- box_selecting_from = get_local_mouse_position();
+ box_selecting_from = b->get_position();
if (b->get_control()) {
box_selection_mode_additive = true;
previus_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
-
GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
- if (!gn2 || !gn2->is_selected())
+ if (!gn2 || !gn2->is_selected()) {
continue;
+ }
previus_selected.push_back(gn2);
}
@@ -996,10 +952,10 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
box_selection_mode_additive = false;
previus_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
-
GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
- if (!gn2 || !gn2->is_selected())
+ if (!gn2 || !gn2->is_selected()) {
continue;
+ }
previus_selected.push_back(gn2);
}
@@ -1007,10 +963,10 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
box_selection_mode_additive = true;
previus_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
-
GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
- if (!gn2)
+ if (!gn2) {
continue;
+ }
if (gn2->is_selected()) {
emit_signal("node_unselected", gn2);
}
@@ -1035,16 +991,16 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
//too difficult to get right
//set_zoom(zoom/ZOOM_SCALE);
}
- if (b->get_button_index() == BUTTON_WHEEL_UP && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (b->get_button_index() == BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8);
}
- if (b->get_button_index() == BUTTON_WHEEL_DOWN && !InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT)) {
+ if (b->get_button_index() == BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8);
}
- if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT))) {
+ if (b->get_button_index() == BUTTON_WHEEL_RIGHT || (b->get_button_index() == BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) {
h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * b->get_factor() / 8);
}
- if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && InputFilter::get_singleton()->is_key_pressed(KEY_SHIFT))) {
+ if (b->get_button_index() == BUTTON_WHEEL_LEFT || (b->get_button_index() == BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_SHIFT))) {
h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * b->get_factor() / 8);
}
}
@@ -1052,7 +1008,6 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventKey> k = p_ev;
if (k.is_valid()) {
-
if (k->get_keycode() == KEY_D && k->is_pressed() && k->get_command()) {
emit_signal("duplicate_nodes_request");
accept_event();
@@ -1076,24 +1031,19 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
Ref<InputEventMagnifyGesture> magnify_gesture = p_ev;
if (magnify_gesture.is_valid()) {
-
set_zoom_custom(zoom * magnify_gesture->get_factor(), magnify_gesture->get_position());
}
Ref<InputEventPanGesture> pan_gesture = p_ev;
if (pan_gesture.is_valid()) {
-
h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * pan_gesture->get_delta().x / 8);
v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * pan_gesture->get_delta().y / 8);
}
}
void GraphEdit::set_connection_activity(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port, float p_activity) {
-
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
-
if (E->get().from == p_from && E->get().from_port == p_from_port && E->get().to == p_to && E->get().to_port == p_to_port) {
-
if (Math::is_equal_approx(E->get().activity, p_activity)) {
//update only if changed
top_layer->update();
@@ -1106,22 +1056,20 @@ void GraphEdit::set_connection_activity(const StringName &p_from, int p_from_por
}
void GraphEdit::clear_connections() {
-
connections.clear();
update();
connections_layer->update();
}
void GraphEdit::set_zoom(float p_zoom) {
-
set_zoom_custom(p_zoom, get_size() / 2);
}
void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) {
-
p_zoom = CLAMP(p_zoom, MIN_ZOOM, MAX_ZOOM);
- if (zoom == p_zoom)
+ if (zoom == p_zoom) {
return;
+ }
zoom_minus->set_disabled(zoom == MIN_ZOOM);
zoom_plus->set_disabled(zoom == MAX_ZOOM);
@@ -1135,7 +1083,6 @@ void GraphEdit::set_zoom_custom(float p_zoom, const Vector2 &p_center) {
connections_layer->update();
if (is_visible_in_tree()) {
-
Vector2 ofs = sbofs * zoom - p_center;
h_scroll->set_value(ofs.x);
v_scroll->set_value(ofs.y);
@@ -1149,37 +1096,30 @@ float GraphEdit::get_zoom() const {
}
void GraphEdit::set_right_disconnects(bool p_enable) {
-
right_disconnects = p_enable;
}
bool GraphEdit::is_right_disconnects_enabled() const {
-
return right_disconnects;
}
void GraphEdit::add_valid_right_disconnect_type(int p_type) {
-
valid_right_disconnect_types.insert(p_type);
}
void GraphEdit::remove_valid_right_disconnect_type(int p_type) {
-
valid_right_disconnect_types.erase(p_type);
}
void GraphEdit::add_valid_left_disconnect_type(int p_type) {
-
valid_left_disconnect_types.insert(p_type);
}
void GraphEdit::remove_valid_left_disconnect_type(int p_type) {
-
valid_left_disconnect_types.erase(p_type);
}
Array GraphEdit::_get_connection_list() const {
-
List<Connection> conns;
get_connection_list(&conns);
Array arr;
@@ -1195,21 +1135,18 @@ Array GraphEdit::_get_connection_list() const {
}
void GraphEdit::_zoom_minus() {
-
set_zoom(zoom / ZOOM_SCALE);
}
-void GraphEdit::_zoom_reset() {
+void GraphEdit::_zoom_reset() {
set_zoom(1);
}
void GraphEdit::_zoom_plus() {
-
set_zoom(zoom * ZOOM_SCALE);
}
void GraphEdit::add_valid_connection_type(int p_type, int p_with_type) {
-
ConnType ct;
ct.type_a = p_type;
ct.type_b = p_with_type;
@@ -1218,7 +1155,6 @@ void GraphEdit::add_valid_connection_type(int p_type, int p_with_type) {
}
void GraphEdit::remove_valid_connection_type(int p_type, int p_with_type) {
-
ConnType ct;
ct.type_a = p_type;
ct.type_b = p_with_type;
@@ -1227,7 +1163,6 @@ void GraphEdit::remove_valid_connection_type(int p_type, int p_with_type) {
}
bool GraphEdit::is_valid_connection_type(int p_type, int p_with_type) const {
-
ConnType ct;
ct.type_a = p_type;
ct.type_b = p_with_type;
@@ -1236,33 +1171,29 @@ bool GraphEdit::is_valid_connection_type(int p_type, int p_with_type) const {
}
void GraphEdit::set_use_snap(bool p_enable) {
-
snap_button->set_pressed(p_enable);
update();
}
bool GraphEdit::is_using_snap() const {
-
return snap_button->is_pressed();
}
int GraphEdit::get_snap() const {
-
return snap_amount->get_value();
}
void GraphEdit::set_snap(int p_snap) {
-
ERR_FAIL_COND(p_snap < 5);
snap_amount->set_value(p_snap);
update();
}
+
void GraphEdit::_snap_toggled() {
update();
}
void GraphEdit::_snap_value_changed(double) {
-
update();
}
@@ -1271,7 +1202,6 @@ HBoxContainer *GraphEdit::get_zoom_hbox() {
}
void GraphEdit::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("connect_node", "from", "from_port", "to", "to_port"), &GraphEdit::connect_node);
ClassDB::bind_method(D_METHOD("is_node_connected", "from", "from_port", "to", "to_port"), &GraphEdit::is_node_connected);
ClassDB::bind_method(D_METHOD("disconnect_node", "from", "from_port", "to", "to_port"), &GraphEdit::disconnect_node);
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index f675f8c7f3..c632490855 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -42,7 +42,6 @@
class GraphEdit;
class GraphEditFilter : public Control {
-
GDCLASS(GraphEditFilter, Control);
friend class GraphEdit;
@@ -54,7 +53,6 @@ public:
};
class GraphEdit : public Control {
-
GDCLASS(GraphEdit, Control);
public:
@@ -99,7 +97,6 @@ private:
bool dragging;
bool just_selected;
Vector2 drag_accum;
- Point2 drag_origin; // Workaround for GH-5907
float zoom;
@@ -142,7 +139,6 @@ private:
bool lines_on_bg;
struct ConnType {
-
union {
struct {
uint32_t type_a;
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 5dbc5bc50d..b6a96238dc 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -33,31 +33,33 @@
#include "core/method_bind_ext.gen.inc"
bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
-
- if (!p_name.operator String().begins_with("slot/"))
+ if (!p_name.operator String().begins_with("slot/")) {
return false;
+ }
int idx = p_name.operator String().get_slice("/", 1).to_int();
String what = p_name.operator String().get_slice("/", 2);
Slot si;
- if (slot_info.has(idx))
+ if (slot_info.has(idx)) {
si = slot_info[idx];
+ }
- if (what == "left_enabled")
+ if (what == "left_enabled") {
si.enable_left = p_value;
- else if (what == "left_type")
+ } else if (what == "left_type") {
si.type_left = p_value;
- else if (what == "left_color")
+ } else if (what == "left_color") {
si.color_left = p_value;
- else if (what == "right_enabled")
+ } else if (what == "right_enabled") {
si.enable_right = p_value;
- else if (what == "right_type")
+ } else if (what == "right_type") {
si.type_right = p_value;
- else if (what == "right_color")
+ } else if (what == "right_color") {
si.color_right = p_value;
- else
+ } else {
return false;
+ }
set_slot(idx, si.enable_left, si.type_left, si.color_left, si.enable_right, si.type_right, si.color_right);
update();
@@ -65,7 +67,6 @@ bool GraphNode::_set(const StringName &p_name, const Variant &p_value) {
}
bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
-
if (!p_name.operator String().begins_with("slot/")) {
return false;
}
@@ -74,33 +75,36 @@ bool GraphNode::_get(const StringName &p_name, Variant &r_ret) const {
String what = p_name.operator String().get_slice("/", 2);
Slot si;
- if (slot_info.has(idx))
+ if (slot_info.has(idx)) {
si = slot_info[idx];
+ }
- if (what == "left_enabled")
+ if (what == "left_enabled") {
r_ret = si.enable_left;
- else if (what == "left_type")
+ } else if (what == "left_type") {
r_ret = si.type_left;
- else if (what == "left_color")
+ } else if (what == "left_color") {
r_ret = si.color_left;
- else if (what == "right_enabled")
+ } else if (what == "right_enabled") {
r_ret = si.enable_right;
- else if (what == "right_type")
+ } else if (what == "right_type") {
r_ret = si.type_right;
- else if (what == "right_color")
+ } else if (what == "right_color") {
r_ret = si.color_right;
- else
+ } else {
return false;
+ }
return true;
}
-void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
+void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
int idx = 0;
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || c->is_set_as_toplevel())
+ if (!c || c->is_set_as_toplevel()) {
continue;
+ }
String base = "slot/" + itos(idx) + "/";
@@ -116,7 +120,6 @@ void GraphNode::_get_property_list(List<PropertyInfo> *p_list) const {
}
void GraphNode::_resort() {
-
int sep = get_theme_constant("separation");
Ref<StyleBox> sb = get_theme_stylebox("frame");
bool first = true;
@@ -125,20 +128,23 @@ void GraphNode::_resort() {
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
Size2i size = c->get_combined_minimum_size();
minsize.y += size.y;
minsize.x = MAX(minsize.x, size.x);
- if (first)
+ if (first) {
first = false;
- else
+ } else {
minsize.y += sep;
+ }
}
int vofs = 0;
@@ -147,10 +153,12 @@ void GraphNode::_resort() {
cache_y.clear();
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
Size2i size = c->get_combined_minimum_size();
@@ -167,7 +175,6 @@ void GraphNode::_resort() {
}
bool GraphNode::has_point(const Point2 &p_point) const {
-
if (comment) {
Ref<StyleBox> comment = get_theme_stylebox("comment");
Ref<Texture2D> resizer = get_theme_icon("resizer");
@@ -188,17 +195,14 @@ bool GraphNode::has_point(const Point2 &p_point) const {
}
void GraphNode::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_DRAW: {
-
Ref<StyleBox> sb;
if (comment) {
sb = get_theme_stylebox(selected ? "commentfocus" : "comment");
} else {
-
sb = get_theme_stylebox(selected ? "selectedframe" : "frame");
}
@@ -223,10 +227,8 @@ void GraphNode::_notification(int p_what) {
switch (overlay) {
case OVERLAY_DISABLED: {
-
} break;
case OVERLAY_BREAKPOINT: {
-
draw_style_box(get_theme_stylebox("breakpoint"), Rect2(Point2(), get_size()));
} break;
case OVERLAY_POSITION: {
@@ -237,8 +239,9 @@ void GraphNode::_notification(int p_what) {
int w = get_size().width - sb->get_minimum_size().x;
- if (show_close)
+ if (show_close) {
w -= close->get_width();
+ }
draw_string(title_font, Point2(sb->get_margin(MARGIN_LEFT) + title_h_offset, -title_font->get_height() + title_font->get_ascent() + title_offset), title, title_color, w);
if (show_close) {
@@ -251,11 +254,12 @@ void GraphNode::_notification(int p_what) {
}
for (Map<int, Slot>::Element *E = slot_info.front(); E; E = E->next()) {
-
- if (E->key() < 0 || E->key() >= cache_y.size())
+ if (E->key() < 0 || E->key() >= cache_y.size()) {
continue;
- if (!slot_info.has(E->key()))
+ }
+ if (!slot_info.has(E->key())) {
continue;
+ }
const Slot &s = slot_info[E->key()];
//left
if (s.enable_left) {
@@ -280,19 +284,16 @@ void GraphNode::_notification(int p_what) {
} break;
case NOTIFICATION_SORT_CHILDREN: {
-
_resort();
} break;
case NOTIFICATION_THEME_CHANGED: {
-
minimum_size_changed();
} break;
}
}
void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const Color &p_color_left, bool p_enable_right, int p_type_right, const Color &p_color_right, const Ref<Texture2D> &p_custom_left, const Ref<Texture2D> &p_custom_right) {
-
ERR_FAIL_COND(p_idx < 0);
if (!p_enable_left && p_type_left == 0 && p_color_left == Color(1, 1, 1, 1) && !p_enable_right && p_type_right == 0 && p_color_right == Color(1, 1, 1, 1)) {
@@ -315,61 +316,60 @@ void GraphNode::set_slot(int p_idx, bool p_enable_left, int p_type_left, const C
}
void GraphNode::clear_slot(int p_idx) {
-
slot_info.erase(p_idx);
update();
connpos_dirty = true;
}
-void GraphNode::clear_all_slots() {
+void GraphNode::clear_all_slots() {
slot_info.clear();
update();
connpos_dirty = true;
}
-bool GraphNode::is_slot_enabled_left(int p_idx) const {
- if (!slot_info.has(p_idx))
+bool GraphNode::is_slot_enabled_left(int p_idx) const {
+ if (!slot_info.has(p_idx)) {
return false;
+ }
return slot_info[p_idx].enable_left;
}
int GraphNode::get_slot_type_left(int p_idx) const {
-
- if (!slot_info.has(p_idx))
+ if (!slot_info.has(p_idx)) {
return 0;
+ }
return slot_info[p_idx].type_left;
}
Color GraphNode::get_slot_color_left(int p_idx) const {
-
- if (!slot_info.has(p_idx))
+ if (!slot_info.has(p_idx)) {
return Color(1, 1, 1, 1);
+ }
return slot_info[p_idx].color_left;
}
bool GraphNode::is_slot_enabled_right(int p_idx) const {
-
- if (!slot_info.has(p_idx))
+ if (!slot_info.has(p_idx)) {
return false;
+ }
return slot_info[p_idx].enable_right;
}
int GraphNode::get_slot_type_right(int p_idx) const {
-
- if (!slot_info.has(p_idx))
+ if (!slot_info.has(p_idx)) {
return 0;
+ }
return slot_info[p_idx].type_right;
}
Color GraphNode::get_slot_color_right(int p_idx) const {
-
- if (!slot_info.has(p_idx))
+ if (!slot_info.has(p_idx)) {
return Color(1, 1, 1, 1);
+ }
return slot_info[p_idx].color_right;
}
Size2 GraphNode::get_minimum_size() const {
-
Ref<Font> title_font = get_theme_font("title_font");
int sep = get_theme_constant("separation");
@@ -384,31 +384,33 @@ Size2 GraphNode::get_minimum_size() const {
}
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
Size2i size = c->get_combined_minimum_size();
minsize.y += size.y;
minsize.x = MAX(minsize.x, size.x);
- if (first)
+ if (first) {
first = false;
- else
+ } else {
minsize.y += sep;
+ }
}
return minsize + sb->get_minimum_size();
}
void GraphNode::set_title(const String &p_title) {
-
- if (title == p_title)
+ if (title == p_title) {
return;
+ }
title = p_title;
update();
_change_notify("title");
@@ -416,19 +418,16 @@ void GraphNode::set_title(const String &p_title) {
}
String GraphNode::get_title() const {
-
return title;
}
void GraphNode::set_offset(const Vector2 &p_offset) {
-
offset = p_offset;
emit_signal("offset_changed");
update();
}
Vector2 GraphNode::get_offset() const {
-
return offset;
}
@@ -442,10 +441,11 @@ bool GraphNode::is_selected() {
}
void GraphNode::set_drag(bool p_drag) {
- if (p_drag)
+ if (p_drag) {
drag_from = get_offset();
- else
+ } else {
emit_signal("dragged", drag_from, get_offset()); //useful for undo/redo
+ }
}
Vector2 GraphNode::get_drag_from() {
@@ -453,17 +453,15 @@ Vector2 GraphNode::get_drag_from() {
}
void GraphNode::set_show_close_button(bool p_enable) {
-
show_close = p_enable;
update();
}
-bool GraphNode::is_close_button_visible() const {
+bool GraphNode::is_close_button_visible() const {
return show_close;
}
void GraphNode::_connpos_update() {
-
int edgeofs = get_theme_constant("port_offset");
int sep = get_theme_constant("separation");
@@ -476,10 +474,12 @@ void GraphNode::_connpos_update() {
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
Size2i size = c->get_combined_minimum_size();
@@ -487,7 +487,6 @@ void GraphNode::_connpos_update() {
int h = size.y;
if (slot_info.has(idx)) {
-
if (slot_info[idx].enable_left) {
ConnCache cc;
cc.pos = Point2i(edgeofs, y + h / 2);
@@ -504,8 +503,9 @@ void GraphNode::_connpos_update() {
}
}
- if (vofs > 0)
+ if (vofs > 0) {
vofs += sep;
+ }
vofs += size.y;
idx++;
}
@@ -514,24 +514,25 @@ void GraphNode::_connpos_update() {
}
int GraphNode::get_connection_input_count() {
-
- if (connpos_dirty)
+ if (connpos_dirty) {
_connpos_update();
+ }
return conn_input_cache.size();
}
-int GraphNode::get_connection_output_count() {
- if (connpos_dirty)
+int GraphNode::get_connection_output_count() {
+ if (connpos_dirty) {
_connpos_update();
+ }
return conn_output_cache.size();
}
Vector2 GraphNode::get_connection_input_position(int p_idx) {
-
- if (connpos_dirty)
+ if (connpos_dirty) {
_connpos_update();
+ }
ERR_FAIL_INDEX_V(p_idx, conn_input_cache.size(), Vector2());
Vector2 pos = conn_input_cache[p_idx].pos;
@@ -541,27 +542,27 @@ Vector2 GraphNode::get_connection_input_position(int p_idx) {
}
int GraphNode::get_connection_input_type(int p_idx) {
-
- if (connpos_dirty)
+ if (connpos_dirty) {
_connpos_update();
+ }
ERR_FAIL_INDEX_V(p_idx, conn_input_cache.size(), 0);
return conn_input_cache[p_idx].type;
}
Color GraphNode::get_connection_input_color(int p_idx) {
-
- if (connpos_dirty)
+ if (connpos_dirty) {
_connpos_update();
+ }
ERR_FAIL_INDEX_V(p_idx, conn_input_cache.size(), Color());
return conn_input_cache[p_idx].color;
}
Vector2 GraphNode::get_connection_output_position(int p_idx) {
-
- if (connpos_dirty)
+ if (connpos_dirty) {
_connpos_update();
+ }
ERR_FAIL_INDEX_V(p_idx, conn_output_cache.size(), Vector2());
Vector2 pos = conn_output_cache[p_idx].pos;
@@ -571,32 +572,29 @@ Vector2 GraphNode::get_connection_output_position(int p_idx) {
}
int GraphNode::get_connection_output_type(int p_idx) {
-
- if (connpos_dirty)
+ if (connpos_dirty) {
_connpos_update();
+ }
ERR_FAIL_INDEX_V(p_idx, conn_output_cache.size(), 0);
return conn_output_cache[p_idx].type;
}
Color GraphNode::get_connection_output_color(int p_idx) {
-
- if (connpos_dirty)
+ if (connpos_dirty) {
_connpos_update();
+ }
ERR_FAIL_INDEX_V(p_idx, conn_output_cache.size(), Color());
return conn_output_cache[p_idx].color;
}
void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) {
-
Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid()) {
-
ERR_FAIL_COND_MSG(get_parent_control() == nullptr, "GraphNode must be the child of a GraphEdit node.");
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
Vector2 mpos = Vector2(mb->get_position().x, mb->get_position().y);
if (close_rect.size != Size2() && close_rect.has_point(mpos)) {
//send focus to parent
@@ -609,7 +607,6 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) {
Ref<Texture2D> resizer = get_theme_icon("resizer");
if (resizable && mpos.x > get_size().x - resizer->get_width() && mpos.y > get_size().y - resizer->get_height()) {
-
resizing = true;
resizing_from = mpos;
resizing_from_size = get_size();
@@ -636,40 +633,33 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) {
}
void GraphNode::set_overlay(Overlay p_overlay) {
-
overlay = p_overlay;
update();
}
GraphNode::Overlay GraphNode::get_overlay() const {
-
return overlay;
}
void GraphNode::set_comment(bool p_enable) {
-
comment = p_enable;
update();
}
bool GraphNode::is_comment() const {
-
return comment;
}
void GraphNode::set_resizable(bool p_enable) {
-
resizable = p_enable;
update();
}
bool GraphNode::is_resizable() const {
-
return resizable;
}
void GraphNode::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_title", "title"), &GraphNode::set_title);
ClassDB::bind_method(D_METHOD("get_title"), &GraphNode::get_title);
ClassDB::bind_method(D_METHOD("_gui_input"), &GraphNode::_gui_input);
@@ -732,7 +722,6 @@ void GraphNode::_bind_methods() {
}
GraphNode::GraphNode() {
-
overlay = OVERLAY_DISABLED;
show_close = false;
connpos_dirty = true;
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index a3eb8ed152..6372833e6f 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -34,7 +34,6 @@
#include "scene/gui/container.h"
class GraphNode : public Container {
-
GDCLASS(GraphNode, Container);
public:
diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp
index 16f6fd0111..2f37461c4d 100644
--- a/scene/gui/grid_container.cpp
+++ b/scene/gui/grid_container.cpp
@@ -31,11 +31,8 @@
#include "grid_container.h"
void GridContainer::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_SORT_CHILDREN: {
-
Map<int, int> col_minw; // Max of min_width of all controls in each col (indexed by col).
Map<int, int> row_minh; // Max of min_height of all controls in each row (indexed by row).
Set<int> col_expanded; // Columns which have the SIZE_EXPAND flag set.
@@ -50,22 +47,25 @@ void GridContainer::_notification(int p_what) {
int valid_controls_index = 0;
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible_in_tree())
+ if (!c || !c->is_visible_in_tree()) {
continue;
+ }
int row = valid_controls_index / columns;
int col = valid_controls_index % columns;
valid_controls_index++;
Size2i ms = c->get_combined_minimum_size();
- if (col_minw.has(col))
+ if (col_minw.has(col)) {
col_minw[col] = MAX(col_minw[col], ms.width);
- else
+ } else {
col_minw[col] = ms.width;
- if (row_minh.has(row))
+ }
+ if (row_minh.has(row)) {
row_minh[row] = MAX(row_minh[row], ms.height);
- else
+ } else {
row_minh[row] = ms.height;
+ }
if (c->get_h_size_flags() & SIZE_EXPAND) {
col_expanded.insert(col);
@@ -83,13 +83,15 @@ void GridContainer::_notification(int p_what) {
// Evaluate the remaining space for expanded columns/rows.
Size2 remaining_space = get_size();
for (Map<int, int>::Element *E = col_minw.front(); E; E = E->next()) {
- if (!col_expanded.has(E->key()))
+ if (!col_expanded.has(E->key())) {
remaining_space.width -= E->get();
+ }
}
for (Map<int, int>::Element *E = row_minh.front(); E; E = E->next()) {
- if (!row_expanded.has(E->key()))
+ if (!row_expanded.has(E->key())) {
remaining_space.height -= E->get();
+ }
}
remaining_space.height -= vsep * MAX(max_row - 1, 0);
remaining_space.width -= hsep * MAX(max_col - 1, 0);
@@ -146,16 +148,18 @@ void GridContainer::_notification(int p_what) {
valid_controls_index = 0;
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible_in_tree())
+ if (!c || !c->is_visible_in_tree()) {
continue;
+ }
int row = valid_controls_index / columns;
int col = valid_controls_index % columns;
valid_controls_index++;
if (col == 0) {
col_ofs = 0;
- if (row > 0)
+ if (row > 0) {
row_ofs += (row_expanded.has(row - 1) ? row_expand : row_minh[row - 1]) + vsep;
+ }
}
Point2 p(col_ofs, row_ofs);
@@ -168,14 +172,12 @@ void GridContainer::_notification(int p_what) {
} break;
case NOTIFICATION_THEME_CHANGED: {
-
minimum_size_changed();
} break;
}
}
void GridContainer::set_columns(int p_columns) {
-
ERR_FAIL_COND(p_columns < 1);
columns = p_columns;
queue_sort();
@@ -183,12 +185,10 @@ void GridContainer::set_columns(int p_columns) {
}
int GridContainer::get_columns() const {
-
return columns;
}
void GridContainer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_columns", "columns"), &GridContainer::set_columns);
ClassDB::bind_method(D_METHOD("get_columns"), &GridContainer::get_columns);
@@ -196,7 +196,6 @@ void GridContainer::_bind_methods() {
}
Size2 GridContainer::get_minimum_size() const {
-
Map<int, int> col_minw;
Map<int, int> row_minh;
@@ -208,24 +207,26 @@ Size2 GridContainer::get_minimum_size() const {
int valid_controls_index = 0;
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible())
+ if (!c || !c->is_visible()) {
continue;
+ }
int row = valid_controls_index / columns;
int col = valid_controls_index % columns;
valid_controls_index++;
Size2i ms = c->get_combined_minimum_size();
- if (col_minw.has(col))
+ if (col_minw.has(col)) {
col_minw[col] = MAX(col_minw[col], ms.width);
- else
+ } else {
col_minw[col] = ms.width;
+ }
- if (row_minh.has(row))
+ if (row_minh.has(row)) {
row_minh[row] = MAX(row_minh[row], ms.height);
- else
+ } else {
row_minh[row] = ms.height;
+ }
max_col = MAX(col, max_col);
max_row = MAX(row, max_row);
}
diff --git a/scene/gui/grid_container.h b/scene/gui/grid_container.h
index 0ed8863196..0a1bd6751a 100644
--- a/scene/gui/grid_container.h
+++ b/scene/gui/grid_container.h
@@ -34,7 +34,6 @@
#include "scene/gui/container.h"
class GridContainer : public Container {
-
GDCLASS(GridContainer, Container);
int columns;
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 47a5ac68d2..54150d130d 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -33,7 +33,6 @@
#include "core/project_settings.h"
void ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, bool p_selectable) {
-
Item item;
item.icon = p_texture;
item.icon_transposed = false;
@@ -52,7 +51,6 @@ void ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, b
}
void ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) {
-
Item item;
item.icon = p_item;
item.icon_transposed = false;
@@ -71,7 +69,6 @@ void ItemList::add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable) {
}
void ItemList::set_item_text(int p_idx, const String &p_text) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].text = p_text;
@@ -80,7 +77,6 @@ void ItemList::set_item_text(int p_idx, const String &p_text) {
}
String ItemList::get_item_text(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), String());
return items[p_idx].text;
}
@@ -96,7 +92,6 @@ bool ItemList::is_item_tooltip_enabled(int p_idx) const {
}
void ItemList::set_item_tooltip(int p_idx, const String &p_tooltip) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].tooltip = p_tooltip;
@@ -105,13 +100,11 @@ void ItemList::set_item_tooltip(int p_idx, const String &p_tooltip) {
}
String ItemList::get_item_tooltip(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), String());
return items[p_idx].tooltip;
}
void ItemList::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].icon = p_icon;
@@ -120,14 +113,12 @@ void ItemList::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
}
Ref<Texture2D> ItemList::get_item_icon(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture2D>());
return items[p_idx].icon;
}
void ItemList::set_item_icon_transposed(int p_idx, const bool p_transposed) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].icon_transposed = p_transposed;
@@ -136,14 +127,12 @@ void ItemList::set_item_icon_transposed(int p_idx, const bool p_transposed) {
}
bool ItemList::is_item_icon_transposed(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), false);
return items[p_idx].icon_transposed;
}
void ItemList::set_item_icon_region(int p_idx, const Rect2 &p_region) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].icon_region = p_region;
@@ -152,14 +141,12 @@ void ItemList::set_item_icon_region(int p_idx, const Rect2 &p_region) {
}
Rect2 ItemList::get_item_icon_region(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), Rect2());
return items[p_idx].icon_region;
}
void ItemList::set_item_icon_modulate(int p_idx, const Color &p_modulate) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].icon_modulate = p_modulate;
@@ -167,70 +154,61 @@ void ItemList::set_item_icon_modulate(int p_idx, const Color &p_modulate) {
}
Color ItemList::get_item_icon_modulate(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), Color());
return items[p_idx].icon_modulate;
}
void ItemList::set_item_custom_bg_color(int p_idx, const Color &p_custom_bg_color) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].custom_bg = p_custom_bg_color;
}
Color ItemList::get_item_custom_bg_color(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), Color());
return items[p_idx].custom_bg;
}
void ItemList::set_item_custom_fg_color(int p_idx, const Color &p_custom_fg_color) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].custom_fg = p_custom_fg_color;
}
Color ItemList::get_item_custom_fg_color(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), Color());
return items[p_idx].custom_fg;
}
void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture2D> &p_tag_icon) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].tag_icon = p_tag_icon;
update();
shape_changed = true;
}
-Ref<Texture2D> ItemList::get_item_tag_icon(int p_idx) const {
+Ref<Texture2D> ItemList::get_item_tag_icon(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture2D>());
return items[p_idx].tag_icon;
}
void ItemList::set_item_selectable(int p_idx, bool p_selectable) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].selectable = p_selectable;
}
bool ItemList::is_item_selectable(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), false);
return items[p_idx].selectable;
}
void ItemList::set_item_disabled(int p_idx, bool p_disabled) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].disabled = p_disabled;
@@ -238,13 +216,11 @@ void ItemList::set_item_disabled(int p_idx, bool p_disabled) {
}
bool ItemList::is_item_disabled(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), false);
return items[p_idx].disabled;
}
void ItemList::set_item_metadata(int p_idx, const Variant &p_metadata) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].metadata = p_metadata;
@@ -253,16 +229,14 @@ void ItemList::set_item_metadata(int p_idx, const Variant &p_metadata) {
}
Variant ItemList::get_item_metadata(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), Variant());
return items[p_idx].metadata;
}
-void ItemList::select(int p_idx, bool p_single) {
+void ItemList::select(int p_idx, bool p_single) {
ERR_FAIL_INDEX(p_idx, items.size());
if (p_single || select_mode == SELECT_SINGLE) {
-
if (!items[p_idx].selectable || items[p_idx].disabled) {
return;
}
@@ -274,15 +248,14 @@ void ItemList::select(int p_idx, bool p_single) {
current = p_idx;
ensure_selected_visible = false;
} else {
-
if (items[p_idx].selectable && !items[p_idx].disabled) {
items.write[p_idx].selected = true;
}
}
update();
}
-void ItemList::unselect(int p_idx) {
+void ItemList::unselect(int p_idx) {
ERR_FAIL_INDEX(p_idx, items.size());
if (select_mode != SELECT_MULTI) {
@@ -295,12 +268,11 @@ void ItemList::unselect(int p_idx) {
}
void ItemList::unselect_all() {
-
- if (items.size() < 1)
+ if (items.size() < 1) {
return;
+ }
for (int i = 0; i < items.size(); i++) {
-
items.write[i].selected = false;
}
current = -1;
@@ -308,7 +280,6 @@ void ItemList::unselect_all() {
}
bool ItemList::is_selected(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), false);
return items[p_idx].selected;
@@ -317,21 +288,19 @@ bool ItemList::is_selected(int p_idx) const {
void ItemList::set_current(int p_current) {
ERR_FAIL_INDEX(p_current, items.size());
- if (select_mode == SELECT_SINGLE)
+ if (select_mode == SELECT_SINGLE) {
select(p_current, true);
- else {
+ } else {
current = p_current;
update();
}
}
int ItemList::get_current() const {
-
return current;
}
void ItemList::move_item(int p_from_idx, int p_to_idx) {
-
ERR_FAIL_INDEX(p_from_idx, items.size());
ERR_FAIL_INDEX(p_to_idx, items.size());
@@ -348,11 +317,10 @@ void ItemList::move_item(int p_from_idx, int p_to_idx) {
}
int ItemList::get_item_count() const {
-
return items.size();
}
-void ItemList::remove_item(int p_idx) {
+void ItemList::remove_item(int p_idx) {
ERR_FAIL_INDEX(p_idx, items.size());
items.remove(p_idx);
@@ -362,7 +330,6 @@ void ItemList::remove_item(int p_idx) {
}
void ItemList::clear() {
-
items.clear();
current = -1;
ensure_selected_visible = false;
@@ -372,65 +339,58 @@ void ItemList::clear() {
}
void ItemList::set_fixed_column_width(int p_size) {
-
ERR_FAIL_COND(p_size < 0);
fixed_column_width = p_size;
update();
shape_changed = true;
}
-int ItemList::get_fixed_column_width() const {
+int ItemList::get_fixed_column_width() const {
return fixed_column_width;
}
void ItemList::set_same_column_width(bool p_enable) {
-
same_column_width = p_enable;
update();
shape_changed = true;
}
-bool ItemList::is_same_column_width() const {
+bool ItemList::is_same_column_width() const {
return same_column_width;
}
void ItemList::set_max_text_lines(int p_lines) {
-
ERR_FAIL_COND(p_lines < 1);
max_text_lines = p_lines;
update();
shape_changed = true;
}
-int ItemList::get_max_text_lines() const {
+int ItemList::get_max_text_lines() const {
return max_text_lines;
}
void ItemList::set_max_columns(int p_amount) {
-
ERR_FAIL_COND(p_amount < 0);
max_columns = p_amount;
update();
shape_changed = true;
}
-int ItemList::get_max_columns() const {
+int ItemList::get_max_columns() const {
return max_columns;
}
void ItemList::set_select_mode(SelectMode p_mode) {
-
select_mode = p_mode;
update();
}
ItemList::SelectMode ItemList::get_select_mode() const {
-
return select_mode;
}
void ItemList::set_icon_mode(IconMode p_mode) {
-
ERR_FAIL_INDEX((int)p_mode, 2);
icon_mode = p_mode;
update();
@@ -438,28 +398,27 @@ void ItemList::set_icon_mode(IconMode p_mode) {
}
ItemList::IconMode ItemList::get_icon_mode() const {
-
return icon_mode;
}
void ItemList::set_fixed_icon_size(const Size2 &p_size) {
-
fixed_icon_size = p_size;
update();
}
Size2 ItemList::get_fixed_icon_size() const {
-
return fixed_icon_size;
}
-Size2 ItemList::Item::get_icon_size() const {
- if (icon.is_null())
+Size2 ItemList::Item::get_icon_size() const {
+ if (icon.is_null()) {
return Size2();
+ }
Size2 size_result = Size2(icon_region.size).abs();
- if (icon_region.size.x == 0 || icon_region.size.y == 0)
+ if (icon_region.size.x == 0 || icon_region.size.y == 0) {
size_result = icon->get_size();
+ }
if (icon_transposed) {
Size2 size_tmp = size_result;
@@ -471,7 +430,6 @@ Size2 ItemList::Item::get_icon_size() const {
}
void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
-
double prev_scroll = scroll_bar->get_value();
Ref<InputEventMouseMotion> mm = p_event;
@@ -483,7 +441,6 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (defer_select_single >= 0 && mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) {
-
select(defer_select_single, true);
emit_signal("multi_selected", defer_select_single, true);
@@ -492,7 +449,6 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
}
if (mb.is_valid() && (mb->get_button_index() == BUTTON_LEFT || (allow_rmb_select && mb->get_button_index() == BUTTON_RIGHT)) && mb->is_pressed()) {
-
search_string = ""; //any mousepress cancels
Vector2 pos = mb->get_position();
Ref<StyleBox> bg = get_theme_stylebox("bg");
@@ -502,7 +458,6 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
int closest = -1;
for (int i = 0; i < items.size(); i++) {
-
Rect2 rc = items[i].rect_cache;
if (i % current_columns == current_columns - 1) {
rc.size.width = get_size().width; //not right but works
@@ -515,7 +470,6 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
}
if (closest != -1) {
-
int i = closest;
if (select_mode == SELECT_MULTI && items[i].selected && mb->get_command()) {
@@ -523,7 +477,6 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
emit_signal("multi_selected", i, false);
} else if (select_mode == SELECT_MULTI && mb->get_shift() && current >= 0 && current < items.size() && current != i) {
-
int from = current;
int to = i;
if (i < current) {
@@ -532,23 +485,21 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
for (int j = from; j <= to; j++) {
bool selected = !items[j].selected;
select(j, false);
- if (selected)
+ if (selected) {
emit_signal("multi_selected", j, true);
+ }
}
if (mb->get_button_index() == BUTTON_RIGHT) {
-
emit_signal("item_rmb_selected", i, get_local_mouse_position());
}
} else {
-
if (!mb->is_doubleclick() && !mb->get_command() && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && mb->get_button_index() == BUTTON_LEFT) {
defer_select_single = i;
return;
}
if (items[i].selected && mb->get_button_index() == BUTTON_RIGHT) {
-
emit_signal("item_rmb_selected", i, get_local_mouse_position());
} else {
bool selected = items[i].selected;
@@ -558,15 +509,14 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
if (!selected || allow_reselect) {
if (select_mode == SELECT_SINGLE) {
emit_signal("item_selected", i);
- } else
+ } else {
emit_signal("multi_selected", i, true);
+ }
}
if (mb->get_button_index() == BUTTON_RIGHT) {
-
emit_signal("item_rmb_selected", i, get_local_mouse_position());
} else if (/*select_mode==SELECT_SINGLE &&*/ mb->is_doubleclick()) {
-
emit_signal("item_activated", i);
}
}
@@ -584,28 +534,21 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
emit_signal("nothing_selected");
}
if (mb.is_valid() && mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
-
scroll_bar->set_value(scroll_bar->get_value() - scroll_bar->get_page() * mb->get_factor() / 8);
}
if (mb.is_valid() && mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) {
-
scroll_bar->set_value(scroll_bar->get_value() + scroll_bar->get_page() * mb->get_factor() / 8);
}
if (p_event->is_pressed() && items.size() > 0) {
if (p_event->is_action("ui_up")) {
-
if (search_string != "") {
-
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - search_time_msec;
if (diff < uint64_t(ProjectSettings::get_singleton()->get("gui/timers/incremental_search_max_interval_msec")) * 2) {
-
for (int i = current - 1; i >= 0; i--) {
-
if (items[i].text.begins_with(search_string)) {
-
set_current(i);
ensure_current_is_visible();
if (select_mode == SELECT_SINGLE) {
@@ -629,18 +572,13 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
accept_event();
}
} else if (p_event->is_action("ui_down")) {
-
if (search_string != "") {
-
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - search_time_msec;
if (diff < uint64_t(ProjectSettings::get_singleton()->get("gui/timers/incremental_search_max_interval_msec")) * 2) {
-
for (int i = current + 1; i < items.size(); i++) {
-
if (items[i].text.begins_with(search_string)) {
-
set_current(i);
ensure_current_is_visible();
if (select_mode == SELECT_SINGLE) {
@@ -663,7 +601,6 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
accept_event();
}
} else if (p_event->is_action("ui_page_up")) {
-
search_string = ""; //any mousepress cancels
for (int i = 4; i > 0; i--) {
@@ -678,7 +615,6 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
}
}
} else if (p_event->is_action("ui_page_down")) {
-
search_string = ""; //any mousepress cancels
for (int i = 4; i > 0; i--) {
@@ -694,7 +630,6 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
}
}
} else if (p_event->is_action("ui_left")) {
-
search_string = ""; //any mousepress cancels
if (current % current_columns != 0) {
@@ -706,7 +641,6 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
accept_event();
}
} else if (p_event->is_action("ui_right")) {
-
search_string = ""; //any mousepress cancels
if (current % current_columns != (current_columns - 1) && current + 1 < items.size()) {
@@ -720,7 +654,6 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
} else if (p_event->is_action("ui_cancel")) {
search_string = "";
} else if (p_event->is_action("ui_select") && select_mode == SELECT_MULTI) {
-
if (current >= 0 && current < items.size()) {
if (items[current].selectable && !items[current].disabled && !items[current].selected) {
select(current, false);
@@ -737,11 +670,9 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
emit_signal("item_activated", current);
}
} else {
-
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->get_unicode()) {
-
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - search_time_msec;
uint64_t max_interval = uint64_t(GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000));
@@ -751,19 +682,22 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
search_string = "";
}
- if (String::chr(k->get_unicode()) != search_string)
+ if (String::chr(k->get_unicode()) != search_string) {
search_string += String::chr(k->get_unicode());
+ }
for (int i = current + 1; i <= items.size(); i++) {
if (i == items.size()) {
- if (current == 0 || current == -1)
+ if (current == 0 || current == -1) {
break;
- else
+ } else {
i = 0;
+ }
}
- if (i == current)
+ if (i == current) {
break;
+ }
if (items[i].text.findn(search_string) == 0) {
set_current(i);
@@ -780,22 +714,20 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventPanGesture> pan_gesture = p_event;
if (pan_gesture.is_valid()) {
-
scroll_bar->set_value(scroll_bar->get_value() + scroll_bar->get_page() * pan_gesture->get_delta().y / 8);
}
- if (scroll_bar->get_value() != prev_scroll)
+ if (scroll_bar->get_value() != prev_scroll) {
accept_event(); //accept event if scroll changed
+ }
}
void ItemList::ensure_current_is_visible() {
-
ensure_selected_visible = true;
update();
}
static Rect2 _adjust_to_max_size(Size2 p_size, Size2 p_max_size) {
-
Size2 size = p_max_size;
int tex_width = p_size.width * size.height / p_size.height;
int tex_height = size.height;
@@ -812,14 +744,12 @@ static Rect2 _adjust_to_max_size(Size2 p_size, Size2 p_max_size) {
}
void ItemList::_notification(int p_what) {
-
if (p_what == NOTIFICATION_RESIZED) {
shape_changed = true;
update();
}
if (p_what == NOTIFICATION_DRAW) {
-
Ref<StyleBox> bg = get_theme_stylebox("bg");
int mw = scroll_bar->get_minimum_size().x;
@@ -865,15 +795,12 @@ void ItemList::_notification(int p_what) {
}
if (shape_changed) {
-
float max_column_width = 0;
//1- compute item minimum sizes
for (int i = 0; i < items.size(); i++) {
-
Size2 minsize;
if (items[i].icon.is_valid()) {
-
if (fixed_icon_size.x > 0 && fixed_icon_size.y > 0) {
minsize = fixed_icon_size * icon_scale;
} else {
@@ -890,7 +817,6 @@ void ItemList::_notification(int p_what) {
}
if (items[i].text != "") {
-
Size2 s = font->get_string_size(items[i].text);
//s.width=MIN(s.width,fixed_column_width);
@@ -908,8 +834,9 @@ void ItemList::_notification(int p_what) {
}
}
- if (fixed_column_width > 0)
+ if (fixed_column_width > 0) {
minsize.x = fixed_column_width;
+ }
max_column_width = MAX(max_column_width, minsize.x);
// elements need to adapt to the selected size
@@ -923,8 +850,9 @@ void ItemList::_notification(int p_what) {
//2-attempt best fit
current_columns = 0x7FFFFFFF;
- if (max_columns > 0)
+ if (max_columns > 0) {
current_columns = max_columns;
+ }
while (true) {
//repeat until all fits
@@ -934,7 +862,6 @@ void ItemList::_notification(int p_what) {
int max_h = 0;
separators.clear();
for (int i = 0; i < items.size(); i++) {
-
if (current_columns > 1 && items[i].rect_cache.size.width + ofs.x > fit_size) {
//went past
current_columns = MAX(col, 1);
@@ -942,16 +869,17 @@ void ItemList::_notification(int p_what) {
break;
}
- if (same_column_width)
+ if (same_column_width) {
items.write[i].rect_cache.size.x = max_column_width;
+ }
items.write[i].rect_cache.position = ofs;
max_h = MAX(max_h, items[i].rect_cache.size.y);
ofs.x += items[i].rect_cache.size.x + hseparation;
col++;
if (col == current_columns) {
-
- if (i < items.size() - 1)
+ if (i < items.size() - 1) {
separators.push_back(ofs.y + max_h + vseparation / 2);
+ }
for (int j = i; j >= 0 && col > 0; j--, col--) {
items.write[j].rect_cache.size.y = max_h;
@@ -971,8 +899,9 @@ void ItemList::_notification(int p_what) {
if (all_fit) {
float page = MAX(0, size.height - bg->get_minimum_size().height);
float max = MAX(page, ofs.y + max_h);
- if (auto_height)
+ if (auto_height) {
auto_height_value = ofs.y + max_h + bg->get_minimum_size().height;
+ }
scroll_bar->set_max(max);
scroll_bar->set_page(page);
if (max <= page) {
@@ -981,8 +910,9 @@ void ItemList::_notification(int p_what) {
} else {
scroll_bar->show();
- if (do_autoscroll_to_bottom)
+ if (do_autoscroll_to_bottom) {
scroll_bar->set_value(max);
+ }
}
break;
}
@@ -994,7 +924,6 @@ void ItemList::_notification(int p_what) {
//ensure_selected_visible needs to be checked before we draw the list.
if (ensure_selected_visible && current >= 0 && current < items.size()) {
-
Rect2 r = items[current].rect_cache;
int from = scroll_bar->get_value();
int to = from + scroll_bar->get_page();
@@ -1035,14 +964,15 @@ void ItemList::_notification(int p_what) {
}
for (int i = first_item_visible; i < items.size(); i++) {
-
Rect2 rcache = items[i].rect_cache;
- if (rcache.position.y > clip.position.y + clip.size.y)
+ if (rcache.position.y > clip.position.y + clip.size.y) {
break; // done
+ }
- if (!clip.intersects(rcache))
+ if (!clip.intersects(rcache)) {
continue;
+ }
if (current_columns == 1) {
rcache.size.width = width - rcache.position.x;
@@ -1073,7 +1003,6 @@ void ItemList::_notification(int p_what) {
Vector2 text_ofs;
if (items[i].icon.is_valid()) {
-
Size2 icon_size;
//= _adjust_to_max_size(items[i].get_icon_size(),fixed_icon_size) * icon_scale;
@@ -1088,7 +1017,6 @@ void ItemList::_notification(int p_what) {
Point2 pos = items[i].rect_cache.position + icon_ofs + base_ofs;
if (icon_mode == ICON_MODE_TOP) {
-
pos.x += Math::floor((items[i].rect_cache.size.width - icon_size.width) / 2);
pos.y += MIN(
Math::floor((items[i].rect_cache.size.height - icon_size.height) / 2),
@@ -1096,7 +1024,6 @@ void ItemList::_notification(int p_what) {
text_ofs.y = icon_size.height + icon_margin;
text_ofs.y += items[i].rect_cache.size.height - items[i].min_rect_cache.size.height;
} else {
-
pos.y += Math::floor((items[i].rect_cache.size.height - icon_size.height) / 2);
text_ofs.x = icon_size.width + icon_margin;
}
@@ -1110,8 +1037,9 @@ void ItemList::_notification(int p_what) {
}
Color modulate = items[i].icon_modulate;
- if (items[i].disabled)
+ if (items[i].disabled) {
modulate.a *= 0.5;
+ }
// If the icon is transposed, we have to switch the size so that it is drawn correctly
if (items[i].icon_transposed) {
@@ -1125,41 +1053,40 @@ void ItemList::_notification(int p_what) {
}
if (items[i].tag_icon.is_valid()) {
-
draw_texture(items[i].tag_icon, items[i].rect_cache.position + base_ofs);
}
if (items[i].text != "") {
-
int max_len = -1;
Vector2 size2 = font->get_string_size(items[i].text);
- if (fixed_column_width)
+ if (fixed_column_width) {
max_len = fixed_column_width;
- else if (same_column_width)
+ } else if (same_column_width) {
max_len = items[i].rect_cache.size.x;
- else
+ } else {
max_len = size2.x;
+ }
Color modulate = items[i].selected ? font_color_selected : (items[i].custom_fg != Color() ? items[i].custom_fg : font_color);
- if (items[i].disabled)
+ if (items[i].disabled) {
modulate.a *= 0.5;
+ }
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
-
int ss = items[i].text.length();
float ofs = 0;
int line = 0;
for (int j = 0; j <= ss; j++) {
-
int cs = j < ss ? font->get_char_size(items[i].text[j], items[i].text[j + 1]).x : 0;
if (ofs + cs > max_len || j == ss) {
line_limit_cache.write[line] = j;
line_size_cache.write[line] = ofs;
line++;
ofs = 0;
- if (line >= max_text_lines)
+ if (line >= max_text_lines) {
break;
+ }
} else {
ofs += cs;
}
@@ -1175,21 +1102,21 @@ void ItemList::_notification(int p_what) {
FontDrawer drawer(font, Color(1, 1, 1));
for (int j = 0; j < ss; j++) {
-
if (j == line_limit_cache[line]) {
line++;
ofs = 0;
- if (line >= max_text_lines)
+ if (line >= max_text_lines) {
break;
+ }
}
ofs += drawer.draw_char(get_canvas_item(), text_ofs + Vector2(ofs + (max_len - line_size_cache[line]) / 2, line * (font_height + line_separation)).floor(), items[i].text[j], items[i].text[j + 1], modulate);
}
//special multiline mode
} else {
-
- if (fixed_column_width > 0)
+ if (fixed_column_width > 0) {
size2.x = MIN(size2.x, fixed_column_width);
+ }
if (icon_mode == ICON_MODE_TOP) {
text_ofs.x += (items[i].rect_cache.size.width - size2.x) / 2;
@@ -1207,7 +1134,6 @@ void ItemList::_notification(int p_what) {
}
if (select_mode == SELECT_MULTI && i == current) {
-
Rect2 r = rcache;
r.position += base_ofs;
r.position.y -= vseparation / 2;
@@ -1235,8 +1161,9 @@ void ItemList::_notification(int p_what) {
}
for (int i = first_visible_separator; i < separators.size(); i++) {
- if (separators[i] > clip.position.y + clip.size.y)
+ if (separators[i] > clip.position.y + clip.size.y) {
break; // done
+ }
const int y = base_ofs.y + separators[i];
draw_line(Vector2(bg->get_margin(MARGIN_LEFT), y), Vector2(width, y), guide_color);
@@ -1249,7 +1176,6 @@ void ItemList::_scroll_changed(double) {
}
int ItemList::get_item_at_position(const Point2 &p_pos, bool p_exact) const {
-
Vector2 pos = p_pos;
Ref<StyleBox> bg = get_theme_stylebox("bg");
pos -= bg->get_offset();
@@ -1259,7 +1185,6 @@ int ItemList::get_item_at_position(const Point2 &p_pos, bool p_exact) const {
int closest_dist = 0x7FFFFFFF;
for (int i = 0; i < items.size(); i++) {
-
Rect2 rc = items[i].rect_cache;
if (i % current_columns == current_columns - 1) {
rc.size.width = get_size().width - rc.position.x; //make sure you can still select the last item when clicking past the column
@@ -1281,9 +1206,9 @@ int ItemList::get_item_at_position(const Point2 &p_pos, bool p_exact) const {
}
bool ItemList::is_pos_at_end_of_items(const Point2 &p_pos) const {
-
- if (items.empty())
+ if (items.empty()) {
return true;
+ }
Vector2 pos = p_pos;
Ref<StyleBox> bg = get_theme_stylebox("bg");
@@ -1295,7 +1220,6 @@ bool ItemList::is_pos_at_end_of_items(const Point2 &p_pos) const {
}
String ItemList::get_tooltip(const Point2 &p_pos) const {
-
int closest = get_item_at_position(p_pos, true);
if (closest != -1) {
@@ -1314,7 +1238,6 @@ String ItemList::get_tooltip(const Point2 &p_pos) const {
}
void ItemList::sort_items_by_text() {
-
items.sort();
update();
shape_changed = true;
@@ -1330,7 +1253,6 @@ void ItemList::sort_items_by_text() {
}
int ItemList::find_metadata(const Variant &p_metadata) const {
-
for (int i = 0; i < items.size(); i++) {
if (items[i].metadata == p_metadata) {
return i;
@@ -1341,22 +1263,18 @@ int ItemList::find_metadata(const Variant &p_metadata) const {
}
void ItemList::set_allow_rmb_select(bool p_allow) {
-
allow_rmb_select = p_allow;
}
bool ItemList::get_allow_rmb_select() const {
-
return allow_rmb_select;
}
void ItemList::set_allow_reselect(bool p_allow) {
-
allow_reselect = p_allow;
}
bool ItemList::get_allow_reselect() const {
-
return allow_reselect;
}
@@ -1383,20 +1301,19 @@ Vector<int> ItemList::get_selected_items() {
bool ItemList::is_anything_selected() {
for (int i = 0; i < items.size(); i++) {
- if (items[i].selected)
+ if (items[i].selected) {
return true;
+ }
}
return false;
}
void ItemList::_set_items(const Array &p_items) {
-
ERR_FAIL_COND(p_items.size() % 3);
clear();
for (int i = 0; i < p_items.size(); i += 3) {
-
String text = p_items[i + 0];
Ref<Texture2D> icon = p_items[i + 1];
bool disabled = p_items[i + 2];
@@ -1408,10 +1325,8 @@ void ItemList::_set_items(const Array &p_items) {
}
Array ItemList::_get_items() const {
-
Array items;
for (int i = 0; i < get_item_count(); i++) {
-
items.push_back(get_item_text(i));
items.push_back(get_item_icon(i));
items.push_back(is_item_disabled(i));
@@ -1421,7 +1336,6 @@ Array ItemList::_get_items() const {
}
Size2 ItemList::get_minimum_size() const {
-
if (auto_height) {
return Size2(0, auto_height_value);
}
@@ -1429,24 +1343,20 @@ Size2 ItemList::get_minimum_size() const {
}
void ItemList::set_autoscroll_to_bottom(const bool p_enable) {
-
do_autoscroll_to_bottom = p_enable;
}
void ItemList::set_auto_height(bool p_enable) {
-
auto_height = p_enable;
shape_changed = true;
update();
}
bool ItemList::has_auto_height() const {
-
return auto_height;
}
void ItemList::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_item", "text", "icon", "selectable"), &ItemList::add_item, DEFVAL(Variant()), DEFVAL(true));
ClassDB::bind_method(D_METHOD("add_icon_item", "icon", "selectable"), &ItemList::add_icon_item, DEFVAL(true));
@@ -1581,7 +1491,6 @@ void ItemList::_bind_methods() {
}
ItemList::ItemList() {
-
current = -1;
select_mode = SELECT_SINGLE;
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index da9851dd7d..4cdef40184 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -35,7 +35,6 @@
#include "scene/gui/scroll_bar.h"
class ItemList : public Control {
-
GDCLASS(ItemList, Control);
public:
@@ -51,7 +50,6 @@ public:
private:
struct Item {
-
Ref<Texture2D> icon;
bool icon_transposed;
Rect2i icon_region;
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index bedcef2df2..f49acc1b96 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -29,12 +29,12 @@
/*************************************************************************/
#include "label.h"
+
#include "core/print_string.h"
#include "core/project_settings.h"
#include "core/translation.h"
void Label::set_autowrap(bool p_autowrap) {
-
if (autowrap == p_autowrap) {
return;
}
@@ -47,34 +47,31 @@ void Label::set_autowrap(bool p_autowrap) {
minimum_size_changed();
}
}
-bool Label::has_autowrap() const {
+bool Label::has_autowrap() const {
return autowrap;
}
void Label::set_uppercase(bool p_uppercase) {
-
uppercase = p_uppercase;
word_cache_dirty = true;
update();
}
-bool Label::is_uppercase() const {
+bool Label::is_uppercase() const {
return uppercase;
}
int Label::get_line_height() const {
-
return get_theme_font("font")->get_height();
}
void Label::_notification(int p_what) {
-
if (p_what == NOTIFICATION_TRANSLATION_CHANGED) {
-
String new_text = tr(text);
- if (new_text == xl_text)
+ if (new_text == xl_text) {
return; //nothing new
+ }
xl_text = new_text;
regenerate_word_cache();
@@ -82,13 +79,13 @@ void Label::_notification(int p_what) {
}
if (p_what == NOTIFICATION_DRAW) {
-
if (clip) {
RenderingServer::get_singleton()->canvas_item_set_clip(get_canvas_item(), true);
}
- if (word_cache_dirty)
+ if (word_cache_dirty) {
regenerate_word_cache();
+ }
RID ci = get_canvas_item();
@@ -125,9 +122,7 @@ void Label::_notification(int p_what) {
}
if (lines_visible > 0) {
-
switch (valign) {
-
case VALIGN_TOP: {
//nothing
} break;
@@ -154,22 +149,25 @@ void Label::_notification(int p_what) {
}
WordCache *wc = word_cache;
- if (!wc)
+ if (!wc) {
return;
+ }
int line = 0;
int line_to = lines_skipped + (lines_visible > 0 ? lines_visible : 1);
FontDrawer drawer(font, font_outline_modulate);
while (wc) {
/* handle lines not meant to be drawn quickly */
- if (line >= line_to)
+ if (line >= line_to) {
break;
+ }
if (line < lines_skipped) {
-
- while (wc && wc->char_pos >= 0)
+ while (wc && wc->char_pos >= 0) {
wc = wc->next;
- if (wc)
+ }
+ if (wc) {
wc = wc->next;
+ }
line++;
continue;
}
@@ -189,7 +187,6 @@ void Label::_notification(int p_what) {
int taken = 0;
int spaces = 0;
while (to && to->char_pos >= 0) {
-
taken += to->pixel_width;
if (to != from && to->space_count) {
spaces += to->space_count;
@@ -202,18 +199,14 @@ void Label::_notification(int p_what) {
float x_ofs = 0;
switch (align) {
-
case ALIGN_FILL:
case ALIGN_LEFT: {
-
x_ofs = style->get_offset().x;
} break;
case ALIGN_CENTER: {
-
x_ofs = int(size.width - (taken + spaces * space_w)) / 2;
} break;
case ALIGN_RIGHT: {
-
x_ofs = int(size.width - style->get_margin(MARGIN_RIGHT) - (taken + spaces * space_w));
} break;
}
@@ -223,11 +216,9 @@ void Label::_notification(int p_what) {
y_ofs += vbegin + line * vsep;
while (from != to) {
-
// draw a word
int pos = from->char_pos;
if (from->char_pos < 0) {
-
ERR_PRINT("BUG");
return;
}
@@ -235,17 +226,14 @@ void Label::_notification(int p_what) {
/* spacing */
x_ofs += space_w * from->space_count;
if (can_fill && align == ALIGN_FILL && spaces) {
-
x_ofs += int((size.width - (taken + space_w * spaces)) / spaces);
}
}
if (font_color_shadow.a > 0) {
-
int chars_total_shadow = chars_total; //save chars drawn
float x_ofs_shadow = x_ofs;
for (int i = 0; i < from->word_len; i++) {
-
if (visible_chars < 0 || chars_total_shadow < visible_chars) {
CharType c = xl_text[i + pos];
CharType n = xl_text[i + pos + 1];
@@ -266,7 +254,6 @@ void Label::_notification(int p_what) {
}
}
for (int i = 0; i < from->word_len; i++) {
-
if (visible_chars < 0 || chars_total < visible_chars) {
CharType c = xl_text[i + pos];
CharType n = xl_text[i + pos + 1];
@@ -288,18 +275,15 @@ void Label::_notification(int p_what) {
}
if (p_what == NOTIFICATION_THEME_CHANGED) {
-
word_cache_dirty = true;
update();
}
if (p_what == NOTIFICATION_RESIZED) {
-
word_cache_dirty = true;
}
}
Size2 Label::get_minimum_size() const {
-
Size2 min_style = get_theme_stylebox("normal")->get_minimum_size();
// don't want to mutable everything
@@ -307,79 +291,78 @@ Size2 Label::get_minimum_size() const {
const_cast<Label *>(this)->regenerate_word_cache();
}
- if (autowrap)
+ if (autowrap) {
return Size2(1, clip ? 1 : minsize.height) + min_style;
- else {
+ } else {
Size2 ms = minsize;
- if (clip)
+ if (clip) {
ms.width = 1;
+ }
return ms + min_style;
}
}
int Label::get_longest_line_width() const {
-
Ref<Font> font = get_theme_font("font");
real_t max_line_width = 0;
real_t line_width = 0;
for (int i = 0; i < xl_text.size(); i++) {
-
CharType current = xl_text[i];
- if (uppercase)
+ if (uppercase) {
current = String::char_uppercase(current);
+ }
if (current < 32) {
-
if (current == '\n') {
-
- if (line_width > max_line_width)
+ if (line_width > max_line_width) {
max_line_width = line_width;
+ }
line_width = 0;
}
} else {
-
real_t char_width = font->get_char_size(current, xl_text[i + 1]).width;
line_width += char_width;
}
}
- if (line_width > max_line_width)
+ if (line_width > max_line_width) {
max_line_width = line_width;
+ }
// ceiling to ensure autowrapping does not cut text
return Math::ceil(max_line_width);
}
int Label::get_line_count() const {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return 1;
- if (word_cache_dirty)
+ }
+ if (word_cache_dirty) {
const_cast<Label *>(this)->regenerate_word_cache();
+ }
return line_count;
}
int Label::get_visible_line_count() const {
-
int line_spacing = get_theme_constant("line_spacing");
int font_h = get_theme_font("font")->get_height() + line_spacing;
int lines_visible = (get_size().height - get_theme_stylebox("normal")->get_minimum_size().height + line_spacing) / font_h;
- if (lines_visible > line_count)
+ if (lines_visible > line_count) {
lines_visible = line_count;
+ }
- if (max_lines_visible >= 0 && lines_visible > max_lines_visible)
+ if (max_lines_visible >= 0 && lines_visible > max_lines_visible) {
lines_visible = max_lines_visible;
+ }
return lines_visible;
}
void Label::regenerate_word_cache() {
-
while (word_cache) {
-
WordCache *current = word_cache;
word_cache = current->next;
memdelete(current);
@@ -407,11 +390,11 @@ void Label::regenerate_word_cache() {
WordCache *last = nullptr;
for (int i = 0; i <= xl_text.length(); i++) {
-
CharType current = i < xl_text.length() ? xl_text[i] : L' '; //always a space at the end, so the algo works
- if (uppercase)
+ if (uppercase) {
current = String::char_uppercase(current);
+ }
// ranges taken from http://www.unicodemap.org/
// if your language is not well supported, consider helping improve
@@ -422,7 +405,6 @@ void Label::regenerate_word_cache() {
real_t char_width = 0;
if (current < 33) {
-
if (current_word_size > 0) {
WordCache *wc = memnew(WordCache);
if (word_cache) {
@@ -508,8 +490,9 @@ void Label::regenerate_word_cache() {
}
}
- if (!autowrap)
+ if (!autowrap) {
minsize.width = width;
+ }
if (max_lines_visible > 0 && line_count > max_lines_visible) {
minsize.height = (font->get_height() * max_lines_visible) + (line_spacing * (max_lines_visible - 1));
@@ -525,60 +508,53 @@ void Label::regenerate_word_cache() {
}
void Label::set_align(Align p_align) {
-
ERR_FAIL_INDEX((int)p_align, 4);
align = p_align;
update();
}
Label::Align Label::get_align() const {
-
return align;
}
void Label::set_valign(VAlign p_align) {
-
ERR_FAIL_INDEX((int)p_align, 4);
valign = p_align;
update();
}
Label::VAlign Label::get_valign() const {
-
return valign;
}
void Label::set_text(const String &p_string) {
-
- if (text == p_string)
+ if (text == p_string) {
return;
+ }
text = p_string;
xl_text = tr(p_string);
word_cache_dirty = true;
- if (percent_visible < 1)
+ if (percent_visible < 1) {
visible_chars = get_total_character_count() * percent_visible;
+ }
update();
}
void Label::set_clip_text(bool p_clip) {
-
clip = p_clip;
update();
minimum_size_changed();
}
bool Label::is_clipping_text() const {
-
return clip;
}
String Label::get_text() const {
-
return text;
}
void Label::set_visible_characters(int p_amount) {
-
visible_chars = p_amount;
if (get_total_character_count() > 0) {
percent_visible = (float)p_amount / (float)total_char_cache;
@@ -588,19 +564,15 @@ void Label::set_visible_characters(int p_amount) {
}
int Label::get_visible_characters() const {
-
return visible_chars;
}
void Label::set_percent_visible(float p_percent) {
-
if (p_percent < 0 || p_percent >= 1) {
-
visible_chars = -1;
percent_visible = 1;
} else {
-
visible_chars = get_total_character_count() * p_percent;
percent_visible = p_percent;
}
@@ -609,42 +581,36 @@ void Label::set_percent_visible(float p_percent) {
}
float Label::get_percent_visible() const {
-
return percent_visible;
}
void Label::set_lines_skipped(int p_lines) {
-
lines_skipped = p_lines;
update();
}
int Label::get_lines_skipped() const {
-
return lines_skipped;
}
void Label::set_max_lines_visible(int p_lines) {
-
max_lines_visible = p_lines;
update();
}
int Label::get_max_lines_visible() const {
-
return max_lines_visible;
}
int Label::get_total_character_count() const {
-
- if (word_cache_dirty)
+ if (word_cache_dirty) {
const_cast<Label *>(this)->regenerate_word_cache();
+ }
return total_char_cache;
}
void Label::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_align", "align"), &Label::set_align);
ClassDB::bind_method(D_METHOD("get_align"), &Label::get_align);
ClassDB::bind_method(D_METHOD("set_valign", "valign"), &Label::set_valign);
@@ -693,31 +659,13 @@ void Label::_bind_methods() {
}
Label::Label(const String &p_text) {
-
- align = ALIGN_LEFT;
- valign = VALIGN_TOP;
- xl_text = "";
- word_cache = nullptr;
- word_cache_dirty = true;
- autowrap = false;
- line_count = 0;
- set_v_size_flags(0);
- clip = false;
set_mouse_filter(MOUSE_FILTER_IGNORE);
- total_char_cache = 0;
- visible_chars = -1;
- percent_visible = 1;
- lines_skipped = 0;
- max_lines_visible = -1;
set_text(p_text);
- uppercase = false;
set_v_size_flags(SIZE_SHRINK_CENTER);
}
Label::~Label() {
-
while (word_cache) {
-
WordCache *current = word_cache;
word_cache = current->next;
memdelete(current);
diff --git a/scene/gui/label.h b/scene/gui/label.h
index ba6e627c58..670db69dce 100644
--- a/scene/gui/label.h
+++ b/scene/gui/label.h
@@ -34,7 +34,6 @@
#include "scene/gui/control.h"
class Label : public Control {
-
GDCLASS(Label, Control);
public:
@@ -55,48 +54,40 @@ public:
};
private:
- Align align;
- VAlign valign;
+ Align align = ALIGN_LEFT;
+ VAlign valign = VALIGN_TOP;
String text;
String xl_text;
- bool autowrap;
- bool clip;
+ bool autowrap = false;
+ bool clip = false;
Size2 minsize;
- int line_count;
- bool uppercase;
+ int line_count = 0;
+ bool uppercase = false;
int get_longest_line_width() const;
struct WordCache {
-
enum {
CHAR_NEWLINE = -1,
CHAR_WRAPLINE = -2
};
- int char_pos; // if -1, then newline
- int word_len;
- int pixel_width;
- int space_count;
- WordCache *next;
- WordCache() {
- char_pos = 0;
- word_len = 0;
- pixel_width = 0;
- next = 0;
- space_count = 0;
- }
+ int char_pos = 0; // if -1, then newline
+ int word_len = 0;
+ int pixel_width = 0;
+ int space_count = 0;
+ WordCache *next = nullptr;
};
- bool word_cache_dirty;
+ bool word_cache_dirty = true;
void regenerate_word_cache();
- float percent_visible;
+ float percent_visible = 1;
- WordCache *word_cache;
- int total_char_cache;
- int visible_chars;
- int lines_skipped;
- int max_lines_visible;
+ WordCache *word_cache = nullptr;
+ int total_char_cache = 0;
+ int visible_chars = -1;
+ int lines_skipped = 0;
+ int max_lines_visible = -1;
protected:
void _notification(int p_what);
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index b9b7560f2e..fbacb3ed9e 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -43,16 +43,13 @@
#endif
#include "scene/main/window.h"
static bool _is_text_char(CharType c) {
-
return !is_symbol(c);
}
void LineEdit::_gui_input(Ref<InputEvent> p_event) {
-
Ref<InputEventMouseButton> b = p_event;
if (b.is_valid()) {
-
if (b->is_pressed() && b->get_button_index() == BUTTON_RIGHT && context_menu_enabled) {
menu->set_position(get_global_transform().xform(get_local_mouse_position()));
menu->set_size(Vector2(1, 1));
@@ -63,12 +60,12 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
return;
}
- if (b->get_button_index() != BUTTON_LEFT)
+ if (b->get_button_index() != BUTTON_LEFT) {
return;
+ }
_reset_caret_blink_timer();
if (b->is_pressed()) {
-
accept_event(); //don't pass event further when clicked on text field
if (!text.empty() && is_editable() && _is_over_clear_button(b->get_position())) {
clear_button_status.press_attempt = true;
@@ -81,14 +78,11 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
set_cursor_at_pixel_pos(b->get_position().x);
if (b->get_shift()) {
-
selection_fill_at_cursor();
selection.creating = true;
} else {
-
if (b->is_doubleclick() && selecting_enabled) {
-
selection.enabled = true;
selection.begin = 0;
selection.end = text.length();
@@ -98,12 +92,10 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
selection.drag_attempt = false;
if ((cursor_pos < selection.begin) || (cursor_pos > selection.end) || !selection.enabled) {
-
deselect();
selection.cursor_start = cursor_pos;
selection.creating = true;
} else if (selection.enabled) {
-
selection.drag_attempt = true;
}
}
@@ -111,7 +103,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
update();
} else {
-
if (!text.empty() && is_editable() && clear_button_enabled) {
bool press_attempt = clear_button_status.press_attempt;
clear_button_status.press_attempt = false;
@@ -127,8 +118,13 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
selection.creating = false;
selection.doubleclick = false;
- if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
- DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length);
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) {
+ if (selection.enabled) {
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, selection.begin, selection.end);
+ } else {
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, cursor_pos);
+ }
+ }
}
update();
@@ -137,7 +133,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventMouseMotion> m = p_event;
if (m.is_valid()) {
-
if (!text.empty() && is_editable() && clear_button_enabled) {
bool last_press_inside = clear_button_status.pressing_inside;
clear_button_status.pressing_inside = clear_button_status.press_attempt && _is_over_clear_button(m->get_position());
@@ -147,7 +142,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
}
if (m->get_button_mask() & BUTTON_LEFT) {
-
if (selection.creating) {
set_cursor_at_pixel_pos(m->get_position().x);
selection_fill_at_cursor();
@@ -158,9 +152,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
-
- if (!k->is_pressed())
+ if (!k->is_pressed()) {
return;
+ }
#ifdef APPLE_STYLE_KEYS
if (k->get_control() && !k->get_shift() && !k->get_alt() && !k->get_command()) {
@@ -202,11 +196,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
unsigned int code = k->get_keycode();
if (k->get_command() && is_shortcut_keys_enabled()) {
-
bool handled = true;
switch (code) {
-
case (KEY_X): { // CUT.
if (editable) {
@@ -224,7 +216,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
case (KEY_V): { // PASTE.
if (editable) {
-
paste_text();
}
@@ -243,7 +234,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
case (KEY_U): { // Delete from start to cursor.
if (editable) {
-
deselect();
text = text.substr(cursor_pos, text.length() - cursor_pos);
update_cached_width();
@@ -256,7 +246,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
case (KEY_Y): { // PASTE (Yank for unix users).
if (editable) {
-
paste_text();
}
@@ -264,7 +253,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
case (KEY_K): { // Delete from cursor_pos to end.
if (editable) {
-
deselect();
text = text.substr(0, cursor_pos);
_text_changed();
@@ -277,10 +265,14 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} break;
#ifdef APPLE_STYLE_KEYS
case (KEY_LEFT): { // Go to start of text - like HOME key.
+ shift_selection_check_pre(k->get_shift());
set_cursor_position(0);
+ shift_selection_check_post(k->get_shift());
} break;
case (KEY_RIGHT): { // Go to end of text - like END key.
+ shift_selection_check_pre(k->get_shift());
set_cursor_position(text.length());
+ shift_selection_check_post(k->get_shift());
} break;
#endif
default: {
@@ -296,23 +288,21 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
_reset_caret_blink_timer();
if (!k->get_metakey()) {
-
bool handled = true;
switch (code) {
-
case KEY_KP_ENTER:
case KEY_ENTER: {
-
emit_signal("text_entered", text);
- if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) {
DisplayServer::get_singleton()->virtual_keyboard_hide();
+ }
} break;
case KEY_BACKSPACE: {
-
- if (!editable)
+ if (!editable) {
break;
+ }
if (selection.enabled) {
selection_delete();
@@ -333,8 +323,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
while (cc > 0) {
bool ischar = _is_text_char(text[cc - 1]);
- if (prev_char && !ischar)
+ if (prev_char && !ischar) {
break;
+ }
prev_char = ischar;
cc--;
@@ -376,7 +367,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (k->get_command()) {
set_cursor_position(0);
} else if (k->get_alt()) {
-
#else
if (k->get_alt()) {
handled = false;
@@ -389,8 +379,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
while (cc > 0) {
bool ischar = _is_text_char(text[cc - 1]);
- if (prev_char && !ischar)
+ if (prev_char && !ischar) {
break;
+ }
prev_char = ischar;
cc--;
@@ -444,8 +435,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
while (cc < text.length()) {
bool ischar = _is_text_char(text[cc]);
- if (prev_char && !ischar)
+ if (prev_char && !ischar) {
break;
+ }
prev_char = ischar;
cc++;
@@ -461,23 +453,25 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} break;
case KEY_UP: {
-
shift_selection_check_pre(k->get_shift());
- if (get_cursor_position() == 0) handled = false;
+ if (get_cursor_position() == 0) {
+ handled = false;
+ }
set_cursor_position(0);
shift_selection_check_post(k->get_shift());
} break;
case KEY_DOWN: {
-
shift_selection_check_pre(k->get_shift());
- if (get_cursor_position() == text.length()) handled = false;
+ if (get_cursor_position() == text.length()) {
+ handled = false;
+ }
set_cursor_position(text.length());
shift_selection_check_post(k->get_shift());
} break;
case KEY_DELETE: {
-
- if (!editable)
+ if (!editable) {
break;
+ }
if (k->get_shift() && !k->get_command() && !k->get_alt()) {
cut_text();
@@ -491,8 +485,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
int text_len = text.length();
- if (cursor_pos == text_len)
+ if (cursor_pos == text_len) {
break; // Nothing to do.
+ }
#ifdef APPLE_STYLE_KEYS
if (k->get_alt()) {
@@ -507,11 +502,11 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
bool prev_char = false;
while (cc < text.length()) {
-
bool ischar = _is_text_char(text[cc]);
- if (prev_char && !ischar)
+ if (prev_char && !ischar) {
break;
+ }
prev_char = ischar;
cc++;
}
@@ -532,7 +527,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
[[fallthrough]];
}
case KEY_HOME: {
-
shift_selection_check_pre(k->get_shift());
set_cursor_position(0);
shift_selection_check_post(k->get_shift());
@@ -545,7 +539,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
[[fallthrough]];
}
case KEY_END: {
-
shift_selection_check_pre(k->get_shift());
set_cursor_position(text.length());
shift_selection_check_post(k->get_shift());
@@ -562,7 +555,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
} break;
default: {
-
handled = false;
} break;
}
@@ -571,7 +563,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
accept_event();
} else if (!k->get_command()) {
if (k->get_unicode() >= 32 && k->get_keycode() != KEY_DELETE) {
-
if (editable) {
selection_delete();
CharType ucodestr[2] = { (CharType)k->get_unicode(), 0 };
@@ -596,19 +587,16 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
}
void LineEdit::set_align(Align p_align) {
-
ERR_FAIL_INDEX((int)p_align, 4);
align = p_align;
update();
}
LineEdit::Align LineEdit::get_align() const {
-
return align;
}
Variant LineEdit::get_drag_data(const Point2 &p_point) {
-
if (selection.drag_attempt && selection.enabled) {
String t = text.substr(selection.begin, selection.end - selection.begin);
Label *l = memnew(Label);
@@ -619,20 +607,21 @@ Variant LineEdit::get_drag_data(const Point2 &p_point) {
return Variant();
}
-bool LineEdit::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
+bool LineEdit::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
return p_data.get_type() == Variant::STRING;
}
-void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
+void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
if (p_data.get_type() == Variant::STRING) {
set_cursor_at_pixel_pos(p_point.x);
int selected = selection.end - selection.begin;
Ref<Font> font = get_theme_font("font");
if (font != nullptr) {
- for (int i = selection.begin; i < selection.end; i++)
+ for (int i = selection.begin; i < selection.end; i++) {
cached_width -= font->get_char_size(pass ? secret_character[0] : text[i]).width;
+ }
}
text.erase(selection.begin, selected);
@@ -660,7 +649,6 @@ bool LineEdit::_is_over_clear_button(const Point2 &p_pos) const {
}
void LineEdit::_notification(int p_what) {
-
switch (p_what) {
#ifdef TOOLS_ENABLED
case NOTIFICATION_ENTER_TREE: {
@@ -675,7 +663,6 @@ void LineEdit::_notification(int p_what) {
} break;
#endif
case NOTIFICATION_RESIZED: {
-
window_pos = 0;
set_cursor_position(get_cursor_position());
@@ -696,7 +683,6 @@ void LineEdit::_notification(int p_what) {
update();
} break;
case NOTIFICATION_DRAW: {
-
if ((!has_focus() && !menu->has_focus()) || !window_has_focus) {
draw_caret = false;
}
@@ -720,7 +706,6 @@ void LineEdit::_notification(int p_what) {
style->draw(ci, Rect2(Point2(), size));
if (has_focus()) {
-
get_theme_stylebox("focus")->draw(ci, Rect2(Point2(), size));
}
@@ -729,21 +714,18 @@ void LineEdit::_notification(int p_what) {
int cached_text_width = using_placeholder ? cached_placeholder_width : cached_width;
switch (align) {
-
case ALIGN_FILL:
case ALIGN_LEFT: {
-
x_ofs = style->get_offset().x;
} break;
case ALIGN_CENTER: {
-
- if (window_pos != 0)
+ if (window_pos != 0) {
x_ofs = style->get_offset().x;
- else
+ } else {
x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - (cached_text_width)) / 2);
+ }
} break;
case ALIGN_RIGHT: {
-
x_ofs = MAX(style->get_margin(MARGIN_LEFT), int(size.width - style->get_margin(MARGIN_RIGHT) - (cached_text_width)));
} break;
}
@@ -763,8 +745,9 @@ void LineEdit::_notification(int p_what) {
const String &t = using_placeholder ? placeholder_translated : text;
// Draw placeholder color.
- if (using_placeholder)
+ if (using_placeholder) {
font_color.a *= placeholder_alpha;
+ }
bool display_clear_icon = !using_placeholder && is_editable() && clear_button_enabled;
if (right_icon.is_valid() || display_clear_icon) {
@@ -794,24 +777,26 @@ void LineEdit::_notification(int p_what) {
int caret_height = font->get_height() > y_area ? y_area : font->get_height();
FontDrawer drawer(font, Color(1, 1, 1));
while (true) {
-
// End of string, break.
- if (char_ofs >= t.length())
+ if (char_ofs >= t.length()) {
break;
+ }
if (char_ofs == cursor_pos) {
if (ime_text.length() > 0) {
int ofs = 0;
while (true) {
- if (ofs >= ime_text.length())
+ if (ofs >= ime_text.length()) {
break;
+ }
CharType cchar = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs];
CharType next = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs + 1];
int im_char_width = font->get_char_size(cchar, next).width;
- if ((x_ofs + im_char_width) > ofs_max)
+ if ((x_ofs + im_char_width) > ofs_max) {
break;
+ }
bool selected = ofs >= ime_selection.x && ofs < ime_selection.x + ime_selection.y;
if (selected) {
@@ -833,13 +818,15 @@ void LineEdit::_notification(int p_what) {
int char_width = font->get_char_size(cchar, next).width;
// End of widget, break.
- if ((x_ofs + char_width) > ofs_max)
+ if ((x_ofs + char_width) > ofs_max) {
break;
+ }
bool selected = selection.enabled && char_ofs >= selection.begin && char_ofs < selection.end;
- if (selected)
+ if (selected) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(x_ofs, y_ofs), Size2(char_width, caret_height)), selection_color);
+ }
int yofs = y_ofs + (caret_height - font->get_height()) / 2;
drawer.draw_char(ci, Point2(x_ofs, yofs + font_ascent), cchar, next, selected ? font_color_selected : font_color);
@@ -862,15 +849,17 @@ void LineEdit::_notification(int p_what) {
if (ime_text.length() > 0) {
int ofs = 0;
while (true) {
- if (ofs >= ime_text.length())
+ if (ofs >= ime_text.length()) {
break;
+ }
CharType cchar = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs];
CharType next = (pass && !text.empty()) ? secret_character[0] : ime_text[ofs + 1];
int im_char_width = font->get_char_size(cchar, next).width;
- if ((x_ofs + im_char_width) > ofs_max)
+ if ((x_ofs + im_char_width) > ofs_max) {
break;
+ }
bool selected = ofs >= ime_selection.x && ofs < ime_selection.x + ime_selection.y;
if (selected) {
@@ -920,7 +909,6 @@ void LineEdit::_notification(int p_what) {
}
} break;
case NOTIFICATION_FOCUS_ENTER: {
-
if (caret_blink_enabled) {
caret_blink_timer->start();
} else {
@@ -933,12 +921,16 @@ void LineEdit::_notification(int p_what) {
DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + cursor_pos, get_viewport()->get_window_id());
}
- if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
- DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length);
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) {
+ if (selection.enabled) {
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, selection.begin, selection.end);
+ } else {
+ DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, cursor_pos);
+ }
+ }
} break;
case NOTIFICATION_FOCUS_EXIT: {
-
if (caret_blink_enabled) {
caret_blink_timer->stop();
}
@@ -950,12 +942,12 @@ void LineEdit::_notification(int p_what) {
ime_text = "";
ime_selection = Point2();
- if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) {
DisplayServer::get_singleton()->virtual_keyboard_hide();
+ }
} break;
case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
-
if (has_focus()) {
ime_text = DisplayServer::get_singleton()->ime_get_text();
ime_selection = DisplayServer::get_singleton()->ime_get_selection();
@@ -966,14 +958,12 @@ void LineEdit::_notification(int p_what) {
}
void LineEdit::copy_text() {
-
if (selection.enabled && !pass) {
DisplayServer::get_singleton()->clipboard_set(text.substr(selection.begin, selection.end - selection.begin));
}
}
void LineEdit::cut_text() {
-
if (selection.enabled && !pass) {
DisplayServer::get_singleton()->clipboard_set(text.substr(selection.begin, selection.end - selection.begin));
selection_delete();
@@ -981,14 +971,14 @@ void LineEdit::cut_text() {
}
void LineEdit::paste_text() {
-
// Strip escape characters like \n and \t as they can't be displayed on LineEdit.
String paste_buffer = DisplayServer::get_singleton()->clipboard_get().strip_escapes();
if (paste_buffer != "") {
-
int prev_len = text.length();
- if (selection.enabled) selection_delete();
+ if (selection.enabled) {
+ selection_delete();
+ }
append_at_cursor(paste_buffer);
if (!text_changed_dirty) {
@@ -1016,8 +1006,9 @@ void LineEdit::undo() {
window_pos = op.window_pos;
set_cursor_position(op.cursor_pos);
- if (expand_to_text_length)
+ if (expand_to_text_length) {
minimum_size_changed();
+ }
_emit_text_change();
}
@@ -1036,29 +1027,29 @@ void LineEdit::redo() {
window_pos = op.window_pos;
set_cursor_position(op.cursor_pos);
- if (expand_to_text_length)
+ if (expand_to_text_length) {
minimum_size_changed();
+ }
_emit_text_change();
}
void LineEdit::shift_selection_check_pre(bool p_shift) {
-
if (!selection.enabled && p_shift) {
selection.cursor_start = cursor_pos;
}
- if (!p_shift)
+ if (!p_shift) {
deselect();
+ }
}
void LineEdit::shift_selection_check_post(bool p_shift) {
-
- if (p_shift)
+ if (p_shift) {
selection_fill_at_cursor();
+ }
}
void LineEdit::set_cursor_at_pixel_pos(int p_x) {
-
Ref<Font> font = get_theme_font("font");
int ofs = window_pos;
Ref<StyleBox> style = get_theme_stylebox("normal");
@@ -1068,33 +1059,31 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
int r_icon_width = Control::get_theme_icon("clear")->get_width();
switch (align) {
-
case ALIGN_FILL:
case ALIGN_LEFT: {
-
pixel_ofs = int(style->get_offset().x);
} break;
case ALIGN_CENTER: {
-
- if (window_pos != 0)
+ if (window_pos != 0) {
pixel_ofs = int(style->get_offset().x);
- else
+ } else {
pixel_ofs = int(size.width - (cached_width)) / 2;
+ }
- if (display_clear_icon)
+ if (display_clear_icon) {
pixel_ofs -= int(r_icon_width / 2 + style->get_margin(MARGIN_RIGHT));
+ }
} break;
case ALIGN_RIGHT: {
-
pixel_ofs = int(size.width - style->get_margin(MARGIN_RIGHT) - (cached_width));
- if (display_clear_icon)
+ if (display_clear_icon) {
pixel_ofs -= int(r_icon_width + style->get_margin(MARGIN_RIGHT));
+ }
} break;
}
while (ofs < text.length()) {
-
int char_w = 0;
if (font != nullptr) {
char_w = font->get_char_size(pass ? secret_character[0] : text[ofs]).width;
@@ -1112,7 +1101,6 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) {
}
int LineEdit::get_cursor_pixel_pos() {
-
Ref<Font> font = get_theme_font("font");
int ofs = window_pos;
Ref<StyleBox> style = get_theme_stylebox("normal");
@@ -1122,28 +1110,27 @@ int LineEdit::get_cursor_pixel_pos() {
int r_icon_width = Control::get_theme_icon("clear")->get_width();
switch (align) {
-
case ALIGN_FILL:
case ALIGN_LEFT: {
-
pixel_ofs = int(style->get_offset().x);
} break;
case ALIGN_CENTER: {
-
- if (window_pos != 0)
+ if (window_pos != 0) {
pixel_ofs = int(style->get_offset().x);
- else
+ } else {
pixel_ofs = int(size.width - (cached_width)) / 2;
+ }
- if (display_clear_icon)
+ if (display_clear_icon) {
pixel_ofs -= int(r_icon_width / 2 + style->get_margin(MARGIN_RIGHT));
+ }
} break;
case ALIGN_RIGHT: {
-
pixel_ofs = int(size.width - style->get_margin(MARGIN_RIGHT) - (cached_width));
- if (display_clear_icon)
+ if (display_clear_icon) {
pixel_ofs -= int(r_icon_width + style->get_margin(MARGIN_RIGHT));
+ }
} break;
}
@@ -1203,8 +1190,9 @@ void LineEdit::_toggle_draw_caret() {
}
void LineEdit::delete_char() {
-
- if ((text.length() <= 0) || (cursor_pos == 0)) return;
+ if ((text.length() <= 0) || (cursor_pos == 0)) {
+ return;
+ }
Ref<Font> font = get_theme_font("font");
if (font != nullptr) {
@@ -1223,12 +1211,12 @@ void LineEdit::delete_char() {
}
void LineEdit::delete_text(int p_from_column, int p_to_column) {
-
if (text.size() > 0) {
Ref<Font> font = get_theme_font("font");
if (font != nullptr) {
- for (int i = p_from_column; i < p_to_column; i++)
+ for (int i = p_from_column; i < p_to_column; i++) {
cached_width -= font->get_char_size(pass ? secret_character[0] : text[i]).width;
+ }
}
} else {
cached_width = 0;
@@ -1238,11 +1226,9 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) {
cursor_pos -= CLAMP(cursor_pos - p_from_column, 0, p_to_column - p_from_column);
if (cursor_pos >= text.length()) {
-
cursor_pos = text.length();
}
if (window_pos > cursor_pos) {
-
window_pos = cursor_pos;
}
@@ -1259,7 +1245,6 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) {
}
void LineEdit::set_text(String p_text) {
-
clear_internal();
append_at_cursor(p_text);
@@ -1273,18 +1258,15 @@ void LineEdit::set_text(String p_text) {
}
void LineEdit::clear() {
-
clear_internal();
_text_changed();
}
String LineEdit::get_text() const {
-
return text;
}
void LineEdit::set_placeholder(String p_text) {
-
placeholder = p_text;
placeholder_translated = tr(placeholder);
update_placeholder_width();
@@ -1292,33 +1274,30 @@ void LineEdit::set_placeholder(String p_text) {
}
String LineEdit::get_placeholder() const {
-
return placeholder;
}
void LineEdit::set_placeholder_alpha(float p_alpha) {
-
placeholder_alpha = p_alpha;
update();
}
float LineEdit::get_placeholder_alpha() const {
-
return placeholder_alpha;
}
void LineEdit::set_cursor_position(int p_pos) {
-
- if (p_pos > (int)text.length())
+ if (p_pos > (int)text.length()) {
p_pos = text.length();
+ }
- if (p_pos < 0)
+ if (p_pos < 0) {
p_pos = 0;
+ }
cursor_pos = p_pos;
if (!is_inside_tree()) {
-
window_pos = cursor_pos;
return;
}
@@ -1338,16 +1317,15 @@ void LineEdit::set_cursor_position(int p_pos) {
window_width -= r_icon->get_width();
}
- if (window_width < 0)
+ if (window_width < 0) {
return;
+ }
int wp = window_pos;
if (font.is_valid()) {
-
int accum_width = 0;
for (int i = cursor_pos; i >= window_pos; i--) {
-
if (i >= text.length()) {
// Do not do this, because if the cursor is at the end, its just fine that it takes no space.
// accum_width = font->get_char_size(' ').width;
@@ -1358,32 +1336,33 @@ void LineEdit::set_cursor_position(int p_pos) {
accum_width += font->get_char_size(text[i], i + 1 < text.length() ? text[i + 1] : 0).width; // Anything should do.
}
}
- if (accum_width > window_width)
+ if (accum_width > window_width) {
break;
+ }
wp = i;
}
}
- if (wp != window_pos)
+ if (wp != window_pos) {
set_window_pos(wp);
+ }
}
update();
}
int LineEdit::get_cursor_position() const {
-
return cursor_pos;
}
void LineEdit::set_window_pos(int p_pos) {
-
window_pos = p_pos;
- if (window_pos < 0) window_pos = 0;
+ if (window_pos < 0) {
+ window_pos = 0;
+ }
}
void LineEdit::append_at_cursor(String p_text) {
-
if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) {
String pre = text.substr(0, cursor_pos);
String post = text.substr(cursor_pos, text.length() - cursor_pos);
@@ -1396,7 +1375,6 @@ void LineEdit::append_at_cursor(String p_text) {
}
void LineEdit::clear_internal() {
-
deselect();
_clear_undo_stack();
cached_width = 0;
@@ -1408,7 +1386,6 @@ void LineEdit::clear_internal() {
}
Size2 LineEdit::get_minimum_size() const {
-
Ref<StyleBox> style = get_theme_stylebox("normal");
Ref<Font> font = get_theme_font("font");
@@ -1439,7 +1416,6 @@ Size2 LineEdit::get_minimum_size() const {
}
void LineEdit::deselect() {
-
selection.begin = 0;
selection.end = 0;
selection.cursor_start = 0;
@@ -1450,28 +1426,27 @@ void LineEdit::deselect() {
}
void LineEdit::selection_delete() {
-
- if (selection.enabled)
+ if (selection.enabled) {
delete_text(selection.begin, selection.end);
+ }
deselect();
}
void LineEdit::set_max_length(int p_max_length) {
-
ERR_FAIL_COND(p_max_length < 0);
max_length = p_max_length;
set_text(text);
}
int LineEdit::get_max_length() const {
-
return max_length;
}
void LineEdit::selection_fill_at_cursor() {
- if (!selecting_enabled)
+ if (!selecting_enabled) {
return;
+ }
selection.begin = cursor_pos;
selection.end = selection.cursor_start;
@@ -1486,11 +1461,13 @@ void LineEdit::selection_fill_at_cursor() {
}
void LineEdit::select_all() {
- if (!selecting_enabled)
+ if (!selecting_enabled) {
return;
+ }
- if (!text.length())
+ if (!text.length()) {
return;
+ }
selection.begin = 0;
selection.end = text.length();
@@ -1499,9 +1476,9 @@ void LineEdit::select_all() {
}
void LineEdit::set_editable(bool p_editable) {
-
- if (editable == p_editable)
+ if (editable == p_editable) {
return;
+ }
editable = p_editable;
_generate_context_menu();
@@ -1511,24 +1488,20 @@ void LineEdit::set_editable(bool p_editable) {
}
bool LineEdit::is_editable() const {
-
return editable;
}
void LineEdit::set_secret(bool p_secret) {
-
pass = p_secret;
update_cached_width();
update();
}
bool LineEdit::is_secret() const {
-
return pass;
}
void LineEdit::set_secret_character(const String &p_string) {
-
// An empty string as the secret character would crash the engine.
// It also wouldn't make sense to use multiple characters as the secret character.
ERR_FAIL_COND_MSG(p_string.length() != 1, "Secret character must be exactly one character long (" + itos(p_string.length()) + " characters given).");
@@ -1543,8 +1516,9 @@ String LineEdit::get_secret_character() const {
}
void LineEdit::select(int p_from, int p_to) {
- if (!selecting_enabled)
+ if (!selecting_enabled) {
return;
+ }
if (p_from == 0 && p_to == 0) {
deselect();
@@ -1552,15 +1526,19 @@ void LineEdit::select(int p_from, int p_to) {
}
int len = text.length();
- if (p_from < 0)
+ if (p_from < 0) {
p_from = 0;
- if (p_from > len)
+ }
+ if (p_from > len) {
p_from = len;
- if (p_to < 0 || p_to > len)
+ }
+ if (p_to < 0 || p_to > len) {
p_to = len;
+ }
- if (p_from >= p_to)
+ if (p_from >= p_to) {
return;
+ }
selection.enabled = true;
selection.begin = p_from;
@@ -1571,12 +1549,10 @@ void LineEdit::select(int p_from, int p_to) {
}
bool LineEdit::is_text_field() const {
-
return true;
}
void LineEdit::menu_option(int p_option) {
-
switch (p_option) {
case MENU_CUT: {
if (editable) {
@@ -1584,7 +1560,6 @@ void LineEdit::menu_option(int p_option) {
}
} break;
case MENU_COPY: {
-
copy_text();
} break;
case MENU_PASTE: {
@@ -1633,7 +1608,6 @@ void LineEdit::_editor_settings_changed() {
}
void LineEdit::set_expand_to_text_length(bool p_enabled) {
-
expand_to_text_length = p_enabled;
minimum_size_changed();
set_window_pos(0);
@@ -1669,8 +1643,9 @@ bool LineEdit::is_shortcut_keys_enabled() const {
void LineEdit::set_selecting_enabled(bool p_enabled) {
selecting_enabled = p_enabled;
- if (!selecting_enabled)
+ if (!selecting_enabled) {
deselect();
+ }
_generate_context_menu();
}
@@ -1693,8 +1668,9 @@ Ref<Texture2D> LineEdit::get_right_icon() {
}
void LineEdit::_text_changed() {
- if (expand_to_text_length)
+ if (expand_to_text_length) {
minimum_size_changed();
+ }
_emit_text_change();
_clear_redo();
@@ -1760,14 +1736,17 @@ void LineEdit::_create_undo_state() {
void LineEdit::_generate_context_menu() {
// Reorganize context menu.
menu->clear();
- if (editable)
+ if (editable) {
menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_X : 0);
+ }
menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_C : 0);
- if (editable)
+ if (editable) {
menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_V : 0);
+ }
menu->add_separator();
- if (is_selecting_enabled())
+ if (is_selecting_enabled()) {
menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_A : 0);
+ }
if (editable) {
menu->add_item(RTR("Clear"), MENU_CLEAR);
menu->add_separator();
@@ -1777,7 +1756,6 @@ void LineEdit::_generate_context_menu() {
}
void LineEdit::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_text_changed"), &LineEdit::_text_changed);
ClassDB::bind_method(D_METHOD("set_align", "align"), &LineEdit::set_align);
@@ -1864,7 +1842,6 @@ void LineEdit::_bind_methods() {
}
LineEdit::LineEdit() {
-
undo_stack_pos = nullptr;
_create_undo_state();
align = ALIGN_LEFT;
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 938974453a..d31a5cb8d8 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -35,7 +35,6 @@
#include "scene/gui/popup_menu.h"
class LineEdit : public Control {
-
GDCLASS(LineEdit, Control);
public:
@@ -94,7 +93,6 @@ private:
Ref<Texture2D> right_icon;
struct Selection {
-
int begin;
int end;
int cursor_start;
diff --git a/scene/gui/link_button.cpp b/scene/gui/link_button.cpp
index 3dffa06b49..f8c8bd4caf 100644
--- a/scene/gui/link_button.cpp
+++ b/scene/gui/link_button.cpp
@@ -31,7 +31,6 @@
#include "link_button.h"
void LinkButton::set_text(const String &p_text) {
-
text = p_text;
update();
minimum_size_changed();
@@ -42,58 +41,48 @@ String LinkButton::get_text() const {
}
void LinkButton::set_underline_mode(UnderlineMode p_underline_mode) {
-
underline_mode = p_underline_mode;
update();
}
LinkButton::UnderlineMode LinkButton::get_underline_mode() const {
-
return underline_mode;
}
Size2 LinkButton::get_minimum_size() const {
-
return get_theme_font("font")->get_string_size(text);
}
void LinkButton::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_DRAW: {
-
RID ci = get_canvas_item();
Size2 size = get_size();
Color color;
bool do_underline = false;
switch (get_draw_mode()) {
-
case DRAW_NORMAL: {
-
color = get_theme_color("font_color");
do_underline = underline_mode == UNDERLINE_MODE_ALWAYS;
} break;
case DRAW_HOVER_PRESSED:
case DRAW_PRESSED: {
-
- if (has_theme_color("font_color_pressed"))
+ if (has_theme_color("font_color_pressed")) {
color = get_theme_color("font_color_pressed");
- else
+ } else {
color = get_theme_color("font_color");
+ }
do_underline = underline_mode != UNDERLINE_MODE_NEVER;
} break;
case DRAW_HOVER: {
-
color = get_theme_color("font_color_hover");
do_underline = underline_mode != UNDERLINE_MODE_NEVER;
} break;
case DRAW_DISABLED: {
-
color = get_theme_color("font_color_disabled");
do_underline = underline_mode == UNDERLINE_MODE_ALWAYS;
@@ -101,7 +90,6 @@ void LinkButton::_notification(int p_what) {
}
if (has_focus()) {
-
Ref<StyleBox> style = get_theme_stylebox("focus");
style->draw(ci, Rect2(Point2(), size));
}
@@ -111,11 +99,11 @@ void LinkButton::_notification(int p_what) {
draw_string(font, Vector2(0, font->get_ascent()), text, color);
if (do_underline) {
- int underline_spacing = get_theme_constant("underline_spacing");
+ int underline_spacing = get_theme_constant("underline_spacing") + font->get_underline_position();
int width = font->get_string_size(text).width;
int y = font->get_ascent() + underline_spacing;
- draw_line(Vector2(0, y), Vector2(width, y), color);
+ draw_line(Vector2(0, y), Vector2(width, y), color, font->get_underline_thickness());
}
} break;
@@ -123,7 +111,6 @@ void LinkButton::_notification(int p_what) {
}
void LinkButton::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_text", "text"), &LinkButton::set_text);
ClassDB::bind_method(D_METHOD("get_text"), &LinkButton::get_text);
diff --git a/scene/gui/link_button.h b/scene/gui/link_button.h
index 3bef25e249..ee37a29f9d 100644
--- a/scene/gui/link_button.h
+++ b/scene/gui/link_button.h
@@ -35,7 +35,6 @@
#include "scene/resources/bit_map.h"
class LinkButton : public BaseButton {
-
GDCLASS(LinkButton, BaseButton);
public:
diff --git a/scene/gui/margin_container.cpp b/scene/gui/margin_container.cpp
index 1cd4ff4ff8..0299065f77 100644
--- a/scene/gui/margin_container.cpp
+++ b/scene/gui/margin_container.cpp
@@ -31,7 +31,6 @@
#include "margin_container.h"
Size2 MarginContainer::get_minimum_size() const {
-
int margin_left = get_theme_constant("margin_left");
int margin_top = get_theme_constant("margin_top");
int margin_right = get_theme_constant("margin_right");
@@ -40,20 +39,24 @@ Size2 MarginContainer::get_minimum_size() const {
Size2 max;
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
- if (!c->is_visible())
+ }
+ if (!c->is_visible()) {
continue;
+ }
Size2 s = c->get_combined_minimum_size();
- if (s.width > max.width)
+ if (s.width > max.width) {
max.width = s.width;
- if (s.height > max.height)
+ }
+ if (s.height > max.height) {
max.height = s.height;
+ }
}
max.width += (margin_left + margin_right);
@@ -63,10 +66,8 @@ Size2 MarginContainer::get_minimum_size() const {
}
void MarginContainer::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_SORT_CHILDREN: {
-
int margin_left = get_theme_constant("margin_left");
int margin_top = get_theme_constant("margin_top");
int margin_right = get_theme_constant("margin_right");
@@ -75,12 +76,13 @@ void MarginContainer::_notification(int p_what) {
Size2 s = get_size();
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
int w = s.width - margin_left - margin_right;
int h = s.height - margin_top - margin_bottom;
@@ -88,7 +90,6 @@ void MarginContainer::_notification(int p_what) {
}
} break;
case NOTIFICATION_THEME_CHANGED: {
-
minimum_size_changed();
} break;
}
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index a7d1f64e93..aa69fb39e7 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -34,25 +34,25 @@
#include "scene/main/window.h"
void MenuButton::_unhandled_key_input(Ref<InputEvent> p_event) {
-
- if (disable_shortcuts)
+ if (disable_shortcuts) {
return;
+ }
if (p_event->is_pressed() && !p_event->is_echo() && (Object::cast_to<InputEventKey>(p_event.ptr()) || Object::cast_to<InputEventJoypadButton>(p_event.ptr()) || Object::cast_to<InputEventAction>(*p_event))) {
-
- if (!get_parent() || !is_visible_in_tree() || is_disabled())
+ if (!get_parent() || !is_visible_in_tree() || is_disabled()) {
return;
+ }
//bool global_only = (get_viewport()->get_modal_stack_top() && !get_viewport()->get_modal_stack_top()->is_a_parent_of(this));
//if (popup->activate_item_by_event(p_event, global_only))
// accept_event();
- if (popup->activate_item_by_event(p_event, false))
+ if (popup->activate_item_by_event(p_event, false)) {
accept_event();
+ }
}
}
void MenuButton::pressed() {
-
{
Window *w = Object::cast_to<Window>(get_viewport());
if (w && !w->is_embedding_subwindows()) {
@@ -75,39 +75,31 @@ void MenuButton::pressed() {
}
void MenuButton::_gui_input(Ref<InputEvent> p_event) {
-
BaseButton::_gui_input(p_event);
}
PopupMenu *MenuButton::get_popup() const {
-
return popup;
}
void MenuButton::_set_items(const Array &p_items) {
-
popup->set("items", p_items);
}
Array MenuButton::_get_items() const {
-
return popup->get("items");
}
void MenuButton::set_switch_on_hover(bool p_enabled) {
-
switch_on_hover = p_enabled;
}
bool MenuButton::is_switch_on_hover() {
-
return switch_on_hover;
}
void MenuButton::_notification(int p_what) {
-
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
if (!is_visible_in_tree()) {
popup->hide();
}
@@ -115,7 +107,6 @@ void MenuButton::_notification(int p_what) {
}
void MenuButton::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_popup"), &MenuButton::get_popup);
ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &MenuButton::_unhandled_key_input);
ClassDB::bind_method(D_METHOD("_set_items"), &MenuButton::_set_items);
@@ -131,12 +122,10 @@ void MenuButton::_bind_methods() {
}
void MenuButton::set_disable_shortcuts(bool p_disabled) {
-
disable_shortcuts = p_disabled;
}
MenuButton::MenuButton() {
-
switch_on_hover = false;
set_flat(true);
set_toggle_mode(true);
diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h
index 9abd11632f..0cd161c1f0 100644
--- a/scene/gui/menu_button.h
+++ b/scene/gui/menu_button.h
@@ -35,7 +35,6 @@
#include "scene/gui/popup_menu.h"
class MenuButton : public Button {
-
GDCLASS(MenuButton, Button);
bool clicked;
diff --git a/scene/gui/nine_patch_rect.cpp b/scene/gui/nine_patch_rect.cpp
index cf10c4cfbd..bc71ae94f5 100644
--- a/scene/gui/nine_patch_rect.cpp
+++ b/scene/gui/nine_patch_rect.cpp
@@ -33,11 +33,10 @@
#include "servers/rendering_server.h"
void NinePatchRect::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
-
- if (texture.is_null())
+ if (texture.is_null()) {
return;
+ }
Rect2 rect = Rect2(Point2(), get_size());
Rect2 src_rect = region_rect;
@@ -50,11 +49,10 @@ void NinePatchRect::_notification(int p_what) {
}
Size2 NinePatchRect::get_minimum_size() const {
-
return Size2(margin[MARGIN_LEFT] + margin[MARGIN_RIGHT], margin[MARGIN_TOP] + margin[MARGIN_BOTTOM]);
}
-void NinePatchRect::_bind_methods() {
+void NinePatchRect::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &NinePatchRect::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &NinePatchRect::get_texture);
ClassDB::bind_method(D_METHOD("set_patch_margin", "margin", "value"), &NinePatchRect::set_patch_margin);
@@ -89,9 +87,9 @@ void NinePatchRect::_bind_methods() {
}
void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) {
-
- if (texture == p_tex)
+ if (texture == p_tex) {
return;
+ }
texture = p_tex;
update();
/*
@@ -104,12 +102,10 @@ void NinePatchRect::set_texture(const Ref<Texture2D> &p_tex) {
}
Ref<Texture2D> NinePatchRect::get_texture() const {
-
return texture;
}
void NinePatchRect::set_patch_margin(Margin p_margin, int p_size) {
-
ERR_FAIL_INDEX((int)p_margin, 4);
margin[p_margin] = p_size;
update();
@@ -131,15 +127,14 @@ void NinePatchRect::set_patch_margin(Margin p_margin, int p_size) {
}
int NinePatchRect::get_patch_margin(Margin p_margin) const {
-
ERR_FAIL_INDEX_V((int)p_margin, 4, 0);
return margin[p_margin];
}
void NinePatchRect::set_region_rect(const Rect2 &p_region_rect) {
-
- if (region_rect == p_region_rect)
+ if (region_rect == p_region_rect) {
return;
+ }
region_rect = p_region_rect;
@@ -148,18 +143,15 @@ void NinePatchRect::set_region_rect(const Rect2 &p_region_rect) {
}
Rect2 NinePatchRect::get_region_rect() const {
-
return region_rect;
}
void NinePatchRect::set_draw_center(bool p_enabled) {
-
draw_center = p_enabled;
update();
}
bool NinePatchRect::is_draw_center_enabled() const {
-
return draw_center;
}
@@ -173,18 +165,15 @@ NinePatchRect::AxisStretchMode NinePatchRect::get_h_axis_stretch_mode() const {
}
void NinePatchRect::set_v_axis_stretch_mode(AxisStretchMode p_mode) {
-
axis_v = p_mode;
update();
}
NinePatchRect::AxisStretchMode NinePatchRect::get_v_axis_stretch_mode() const {
-
return axis_v;
}
NinePatchRect::NinePatchRect() {
-
margin[MARGIN_LEFT] = 0;
margin[MARGIN_RIGHT] = 0;
margin[MARGIN_BOTTOM] = 0;
diff --git a/scene/gui/nine_patch_rect.h b/scene/gui/nine_patch_rect.h
index 0ef7f6b299..23a40fb64b 100644
--- a/scene/gui/nine_patch_rect.h
+++ b/scene/gui/nine_patch_rect.h
@@ -34,7 +34,6 @@
#include "scene/gui/control.h"
class NinePatchRect : public Control {
-
GDCLASS(NinePatchRect, Control);
public:
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index a03d6d0cdc..5780cc5e71 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -33,7 +33,6 @@
#include "core/print_string.h"
Size2 OptionButton::get_minimum_size() const {
-
Size2 minsize = Button::get_minimum_size();
if (has_theme_icon("arrow")) {
@@ -51,12 +50,11 @@ Size2 OptionButton::get_minimum_size() const {
}
void OptionButton::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_DRAW: {
-
- if (!has_theme_icon("arrow"))
+ if (!has_theme_icon("arrow")) {
return;
+ }
RID ci = get_canvas_item();
Ref<Texture2D> arrow = Control::get_theme_icon("arrow");
@@ -83,13 +81,11 @@ void OptionButton::_notification(int p_what) {
arrow->draw(ci, ofs, clr);
} break;
case NOTIFICATION_THEME_CHANGED: {
-
if (has_theme_icon("arrow")) {
_set_internal_margin(MARGIN_RIGHT, Control::get_theme_icon("arrow")->get_width());
}
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
if (!is_visible_in_tree()) {
popup->hide();
}
@@ -102,12 +98,10 @@ void OptionButton::_focused(int p_which) {
}
void OptionButton::_selected(int p_which) {
-
_select(p_which, true);
}
void OptionButton::pressed() {
-
Size2 size = get_size();
popup->set_position(get_screen_position() + Size2(0, size.height * get_global_transform().get_scale().y));
popup->set_size(Size2(size.width, 0));
@@ -115,105 +109,96 @@ void OptionButton::pressed() {
}
void OptionButton::add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id) {
-
popup->add_icon_radio_check_item(p_icon, p_label, p_id);
- if (popup->get_item_count() == 1)
+ if (popup->get_item_count() == 1) {
select(0);
+ }
}
-void OptionButton::add_item(const String &p_label, int p_id) {
+void OptionButton::add_item(const String &p_label, int p_id) {
popup->add_radio_check_item(p_label, p_id);
- if (popup->get_item_count() == 1)
+ if (popup->get_item_count() == 1) {
select(0);
+ }
}
void OptionButton::set_item_text(int p_idx, const String &p_text) {
-
popup->set_item_text(p_idx, p_text);
- if (current == p_idx)
+ if (current == p_idx) {
set_text(p_text);
+ }
}
-void OptionButton::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
+void OptionButton::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
popup->set_item_icon(p_idx, p_icon);
- if (current == p_idx)
+ if (current == p_idx) {
set_icon(p_icon);
+ }
}
-void OptionButton::set_item_id(int p_idx, int p_id) {
+void OptionButton::set_item_id(int p_idx, int p_id) {
popup->set_item_id(p_idx, p_id);
}
void OptionButton::set_item_metadata(int p_idx, const Variant &p_metadata) {
-
popup->set_item_metadata(p_idx, p_metadata);
}
void OptionButton::set_item_disabled(int p_idx, bool p_disabled) {
-
popup->set_item_disabled(p_idx, p_disabled);
}
String OptionButton::get_item_text(int p_idx) const {
-
return popup->get_item_text(p_idx);
}
Ref<Texture2D> OptionButton::get_item_icon(int p_idx) const {
-
return popup->get_item_icon(p_idx);
}
int OptionButton::get_item_id(int p_idx) const {
-
return popup->get_item_id(p_idx);
}
int OptionButton::get_item_index(int p_id) const {
-
return popup->get_item_index(p_id);
}
Variant OptionButton::get_item_metadata(int p_idx) const {
-
return popup->get_item_metadata(p_idx);
}
bool OptionButton::is_item_disabled(int p_idx) const {
-
return popup->is_item_disabled(p_idx);
}
int OptionButton::get_item_count() const {
-
return popup->get_item_count();
}
void OptionButton::add_separator() {
-
popup->add_separator();
}
void OptionButton::clear() {
-
popup->clear();
set_text("");
current = -1;
}
void OptionButton::_select(int p_which, bool p_emit) {
-
- if (p_which < 0)
+ if (p_which < 0) {
return;
- if (p_which == current)
+ }
+ if (p_which == current) {
return;
+ }
ERR_FAIL_INDEX(p_which, popup->get_item_count());
for (int i = 0; i < popup->get_item_count(); i++) {
-
popup->set_item_checked(i, i == p_which);
}
@@ -221,57 +206,53 @@ void OptionButton::_select(int p_which, bool p_emit) {
set_text(popup->get_item_text(current));
set_icon(popup->get_item_icon(current));
- if (is_inside_tree() && p_emit)
+ if (is_inside_tree() && p_emit) {
emit_signal("item_selected", current);
+ }
}
void OptionButton::_select_int(int p_which) {
-
- if (p_which < 0 || p_which >= popup->get_item_count())
+ if (p_which < 0 || p_which >= popup->get_item_count()) {
return;
+ }
_select(p_which, false);
}
void OptionButton::select(int p_idx) {
-
_select(p_idx, false);
}
int OptionButton::get_selected() const {
-
return current;
}
int OptionButton::get_selected_id() const {
-
int idx = get_selected();
- if (idx < 0)
+ if (idx < 0) {
return 0;
+ }
return get_item_id(current);
}
-Variant OptionButton::get_selected_metadata() const {
+Variant OptionButton::get_selected_metadata() const {
int idx = get_selected();
- if (idx < 0)
+ if (idx < 0) {
return Variant();
+ }
return get_item_metadata(current);
}
void OptionButton::remove_item(int p_idx) {
-
popup->remove_item(p_idx);
}
PopupMenu *OptionButton::get_popup() const {
-
return popup;
}
Array OptionButton::_get_items() const {
-
Array items;
for (int i = 0; i < get_item_count(); i++) {
-
items.push_back(get_item_text(i));
items.push_back(get_item_icon(i));
items.push_back(is_item_disabled(i));
@@ -281,13 +262,12 @@ Array OptionButton::_get_items() const {
return items;
}
-void OptionButton::_set_items(const Array &p_items) {
+void OptionButton::_set_items(const Array &p_items) {
ERR_FAIL_COND(p_items.size() % 5);
clear();
for (int i = 0; i < p_items.size(); i += 5) {
-
String text = p_items[i + 0];
Ref<Texture2D> icon = p_items[i + 1];
bool disabled = p_items[i + 2];
@@ -303,12 +283,10 @@ void OptionButton::_set_items(const Array &p_items) {
}
void OptionButton::get_translatable_strings(List<String> *p_strings) const {
-
popup->get_translatable_strings(p_strings);
}
void OptionButton::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_item", "label", "id"), &OptionButton::add_item, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("add_icon_item", "texture", "label", "id"), &OptionButton::add_icon_item, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("set_item_text", "idx", "text"), &OptionButton::set_item_text);
@@ -345,7 +323,6 @@ void OptionButton::_bind_methods() {
}
OptionButton::OptionButton() {
-
current = -1;
set_toggle_mode(true);
set_text_align(ALIGN_LEFT);
@@ -357,9 +334,6 @@ OptionButton::OptionButton() {
popup = memnew(PopupMenu);
popup->hide();
add_child(popup);
- // popup->set_pass_on_modal_close_click(false);
- // popup->set_notify_transform(true);
- popup->set_allow_search(true);
popup->connect("index_pressed", callable_mp(this, &OptionButton::_selected));
popup->connect("id_focused", callable_mp(this, &OptionButton::_focused));
popup->connect("popup_hide", callable_mp((BaseButton *)this, &BaseButton::set_pressed), varray(false));
diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h
index 9658e1fea8..69a94a34f3 100644
--- a/scene/gui/option_button.h
+++ b/scene/gui/option_button.h
@@ -35,7 +35,6 @@
#include "scene/gui/popup_menu.h"
class OptionButton : public Button {
-
GDCLASS(OptionButton, Button);
PopupMenu *popup;
diff --git a/scene/gui/panel.cpp b/scene/gui/panel.cpp
index a17d0eb9c6..d8d9beca2b 100644
--- a/scene/gui/panel.cpp
+++ b/scene/gui/panel.cpp
@@ -33,9 +33,7 @@
#include "core/print_string.h"
void Panel::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
-
RID ci = get_canvas_item();
Ref<StyleBox> style = mode == MODE_BACKGROUND ? get_theme_stylebox("panel") : get_theme_stylebox("panel_fg");
style->draw(ci, Rect2(Point2(), get_size()));
@@ -46,6 +44,7 @@ void Panel::set_mode(Mode p_mode) {
mode = p_mode;
update();
}
+
Panel::Mode Panel::get_mode() const {
return mode;
}
diff --git a/scene/gui/panel.h b/scene/gui/panel.h
index 75e266b6a6..a68c3d3f0c 100644
--- a/scene/gui/panel.h
+++ b/scene/gui/panel.h
@@ -34,7 +34,6 @@
#include "scene/gui/control.h"
class Panel : public Control {
-
GDCLASS(Panel, Control);
public:
diff --git a/scene/gui/panel_container.cpp b/scene/gui/panel_container.cpp
index 62b9296409..9abdfac009 100644
--- a/scene/gui/panel_container.cpp
+++ b/scene/gui/panel_container.cpp
@@ -31,56 +31,57 @@
#include "panel_container.h"
Size2 PanelContainer::get_minimum_size() const {
-
Ref<StyleBox> style;
- if (has_theme_stylebox("panel"))
+ if (has_theme_stylebox("panel")) {
style = get_theme_stylebox("panel");
- else
+ } else {
style = get_theme_stylebox("panel", "PanelContainer");
+ }
Size2 ms;
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible())
+ if (!c || !c->is_visible()) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
Size2 minsize = c->get_combined_minimum_size();
ms.width = MAX(ms.width, minsize.width);
ms.height = MAX(ms.height, minsize.height);
}
- if (style.is_valid())
+ if (style.is_valid()) {
ms += style->get_minimum_size();
+ }
return ms;
}
void PanelContainer::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
-
RID ci = get_canvas_item();
Ref<StyleBox> style;
- if (has_theme_stylebox("panel"))
+ if (has_theme_stylebox("panel")) {
style = get_theme_stylebox("panel");
- else
+ } else {
style = get_theme_stylebox("panel", "PanelContainer");
+ }
style->draw(ci, Rect2(Point2(), get_size()));
}
if (p_what == NOTIFICATION_SORT_CHILDREN) {
-
Ref<StyleBox> style;
- if (has_theme_stylebox("panel"))
+ if (has_theme_stylebox("panel")) {
style = get_theme_stylebox("panel");
- else
+ } else {
style = get_theme_stylebox("panel", "PanelContainer");
+ }
Size2 size = get_size();
Point2 ofs;
@@ -90,12 +91,13 @@ void PanelContainer::_notification(int p_what) {
}
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible_in_tree())
+ if (!c || !c->is_visible_in_tree()) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
fit_child_in_rect(c, Rect2(ofs, size));
}
diff --git a/scene/gui/panel_container.h b/scene/gui/panel_container.h
index 5623c3484b..b68bc223dc 100644
--- a/scene/gui/panel_container.h
+++ b/scene/gui/panel_container.h
@@ -34,7 +34,6 @@
#include "scene/gui/container.h"
class PanelContainer : public Container {
-
GDCLASS(PanelContainer, Container);
protected:
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 6edafc65a0..5fc5f9b669 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -42,15 +42,13 @@ void Popup::_input_from_window(const Ref<InputEvent> &p_event) {
}
void Popup::_parent_focused() {
-
_close_pressed();
}
-void Popup::_notification(int p_what) {
+void Popup::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
-
parent_visible = get_parent_visible_window();
if (parent_visible) {
parent_visible->connect("focus_entered", callable_mp(this, &Popup::_parent_focused));
@@ -79,7 +77,6 @@ void Popup::_notification(int p_what) {
}
void Popup::_close_pressed() {
-
Window *parent_window = parent_visible;
if (parent_visible) {
parent_visible->disconnect("focus_entered", callable_mp(this, &Popup::_parent_focused));
@@ -98,8 +95,8 @@ void Popup::_close_pressed() {
void Popup::set_as_minsize() {
set_size(get_contents_minimum_size());
}
-void Popup::_bind_methods() {
+void Popup::_bind_methods() {
ADD_SIGNAL(MethodInfo("popup_hide"));
}
@@ -133,7 +130,6 @@ Rect2i Popup::_popup_adjust_rect() const {
}
Popup::Popup() {
-
parent_visible = nullptr;
set_wrap_controls(true);
@@ -149,18 +145,19 @@ Popup::~Popup() {
}
Size2 PopupPanel::_get_contents_minimum_size() const {
-
Ref<StyleBox> p = get_theme_stylebox("panel", get_class_name());
Size2 ms;
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || c == panel)
+ if (!c || c == panel) {
continue;
+ }
- if (c->is_set_as_toplevel())
+ if (c->is_set_as_toplevel()) {
continue;
+ }
Size2 cms = c->get_combined_minimum_size();
ms.x = MAX(cms.x, ms.x);
@@ -171,7 +168,6 @@ Size2 PopupPanel::_get_contents_minimum_size() const {
}
void PopupPanel::_update_child_rects() {
-
Ref<StyleBox> p = get_theme_stylebox("panel", get_class_name());
Vector2 cpos(p->get_offset());
@@ -179,11 +175,13 @@ void PopupPanel::_update_child_rects() {
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
+ }
- if (c->is_set_as_toplevel())
+ if (c->is_set_as_toplevel()) {
continue;
+ }
if (c == panel) {
c->set_position(Vector2());
@@ -196,21 +194,17 @@ void PopupPanel::_update_child_rects() {
}
void PopupPanel::_notification(int p_what) {
-
if (p_what == NOTIFICATION_THEME_CHANGED) {
panel->add_theme_style_override("panel", get_theme_stylebox("panel", get_class_name()));
} else if (p_what == NOTIFICATION_READY || p_what == NOTIFICATION_ENTER_TREE) {
-
panel->add_theme_style_override("panel", get_theme_stylebox("panel", get_class_name()));
_update_child_rects();
} else if (p_what == NOTIFICATION_WM_SIZE_CHANGED) {
-
_update_child_rects();
}
}
PopupPanel::PopupPanel() {
-
panel = memnew(Panel);
add_child(panel);
}
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index 6cd2b4028f..0e32d55cb6 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -34,7 +34,6 @@
#include "scene/main/window.h"
class Popup : public Window {
-
GDCLASS(Popup, Window);
Window *parent_visible;
@@ -56,7 +55,6 @@ public:
};
class PopupPanel : public Popup {
-
GDCLASS(PopupPanel, Popup);
Panel *panel;
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 1e933c9aa1..6e19b820e0 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -30,7 +30,7 @@
#include "popup_menu.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
#include "core/print_string.h"
@@ -38,18 +38,17 @@
#include "scene/gui/control.h"
String PopupMenu::_get_accel_text(int p_item) const {
-
ERR_FAIL_INDEX_V(p_item, items.size(), String());
- if (items[p_item].shortcut.is_valid())
+ if (items[p_item].shortcut.is_valid()) {
return items[p_item].shortcut->get_as_text();
- else if (items[p_item].accel)
+ } else if (items[p_item].accel) {
return keycode_get_string(items[p_item].accel);
+ }
return String();
}
Size2 PopupMenu::_get_contents_minimum_size() const {
-
int vseparation = get_theme_constant("vseparation");
int hseparation = get_theme_constant("hseparation");
@@ -64,37 +63,36 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
bool has_check = false;
for (int i = 0; i < items.size(); i++) {
-
Size2 size;
if (!items[i].icon.is_null()) {
-
Size2 icon_size = items[i].icon->get_size();
size.height = MAX(icon_size.height, font_h);
icon_w = MAX(icon_size.width + hseparation, icon_w);
} else {
-
size.height = font_h;
}
size.width += items[i].h_ofs;
- if (items[i].checkable_type)
+ if (items[i].checkable_type) {
has_check = true;
+ }
String text = items[i].xl_text;
size.width += font->get_string_size(text).width;
- if (i > 0)
+ if (i > 0) {
size.height += vseparation;
+ }
if (items[i].accel || (items[i].shortcut.is_valid() && items[i].shortcut->is_valid())) {
-
int accel_w = hseparation * 2;
accel_w += font->get_string_size(_get_accel_text(i)).width;
accel_max_w = MAX(accel_w, accel_max_w);
}
- if (items[i].submenu != "")
+ if (items[i].submenu != "") {
size.width += get_theme_icon("submenu")->get_width();
+ }
max_w = MAX(max_w, size.width);
@@ -102,39 +100,38 @@ Size2 PopupMenu::_get_contents_minimum_size() const {
}
minsize.width += max_w + icon_w + accel_max_w;
- if (has_check)
+ if (has_check) {
minsize.width += check_w;
+ }
return minsize;
}
int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
-
- if (p_over.x < 0 || p_over.x >= get_size().width)
+ if (p_over.x < 0 || p_over.x >= get_size().width) {
return -1;
+ }
Ref<StyleBox> style = get_theme_stylebox("panel");
Point2 ofs = style->get_offset();
- if (ofs.y > p_over.y)
+ if (ofs.y > p_over.y) {
return -1;
+ }
Ref<Font> font = get_theme_font("font");
int vseparation = get_theme_constant("vseparation");
float font_h = font->get_height();
for (int i = 0; i < items.size(); i++) {
-
ofs.y += vseparation;
float h;
if (!items[i].icon.is_null()) {
-
Size2 icon_size = items[i].icon->get_size();
h = MAX(icon_size.height, font_h);
} else {
-
h = font_h;
}
@@ -148,13 +145,13 @@ int PopupMenu::_get_mouse_over(const Point2 &p_over) const {
}
void PopupMenu::_activate_submenu(int over) {
-
Node *n = get_node(items[over].submenu);
ERR_FAIL_COND_MSG(!n, "Item subnode does not exist: " + items[over].submenu + ".");
Popup *pm = Object::cast_to<Popup>(n);
ERR_FAIL_COND_MSG(!pm, "Item subnode is not a Popup: " + items[over].submenu + ".");
- if (pm->is_visible())
+ if (pm->is_visible()) {
return; //already visible!
+ }
Point2 p = get_position();
Rect2 pr(p, get_size());
@@ -163,8 +160,9 @@ void PopupMenu::_activate_submenu(int over) {
Point2 pos = p + Point2(get_size().width, items[over]._ofs_cache - style->get_offset().y);
Size2 size = pm->get_size();
// fix pos
- if (pos.x + size.width > get_parent_rect().size.width)
+ if (pos.x + size.width > get_parent_rect().size.width) {
pos.x = p.x - size.width;
+ }
pm->set_position(pos);
// pm->set_scale(get_global_transform().get_scale());
@@ -172,7 +170,6 @@ void PopupMenu::_activate_submenu(int over) {
PopupMenu *pum = Object::cast_to<PopupMenu>(pm);
if (pum) {
-
pr.position -= pum->get_position();
pum->clear_autohide_areas();
pum->add_autohide_area(Rect2(pr.position.x, pr.position.y, pr.size.x, items[over]._ofs_cache));
@@ -184,18 +181,17 @@ void PopupMenu::_activate_submenu(int over) {
}
void PopupMenu::_submenu_timeout() {
-
//if (!has_focus()) {
// return; //do not activate if not has focus
//}
- if (mouse_over == submenu_over)
+ if (mouse_over == submenu_over) {
_activate_submenu(mouse_over);
+ }
submenu_over = -1;
}
void PopupMenu::_scroll(float p_factor, const Point2 &p_over) {
-
int vseparation = get_theme_constant("vseparation");
Ref<Font> font = get_theme_font("font");
@@ -226,20 +222,18 @@ void PopupMenu::_scroll(float p_factor, const Point2 &p_over) {
}
void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
-
if (p_event->is_action("ui_down") && p_event->is_pressed()) {
-
int search_from = mouse_over + 1;
- if (search_from >= items.size())
+ if (search_from >= items.size()) {
search_from = 0;
+ }
for (int i = search_from; i < items.size(); i++) {
-
- if (i < 0 || i >= items.size())
+ if (i < 0 || i >= items.size()) {
continue;
+ }
if (!items[i].separator && !items[i].disabled) {
-
mouse_over = i;
emit_signal("id_focused", i);
control->update();
@@ -248,18 +242,17 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
}
}
} else if (p_event->is_action("ui_up") && p_event->is_pressed()) {
-
int search_from = mouse_over - 1;
- if (search_from < 0)
+ if (search_from < 0) {
search_from = items.size() - 1;
+ }
for (int i = search_from; i >= 0; i--) {
-
- if (i >= items.size())
+ if (i >= items.size()) {
continue;
+ }
if (!items[i].separator && !items[i].disabled) {
-
mouse_over = i;
emit_signal("id_focused", i);
control->update();
@@ -268,22 +261,18 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
}
}
} else if (p_event->is_action("ui_left") && p_event->is_pressed()) {
-
Node *n = get_parent();
if (n && Object::cast_to<PopupMenu>(n)) {
hide();
set_input_as_handled();
}
} else if (p_event->is_action("ui_right") && p_event->is_pressed()) {
-
if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator && items[mouse_over].submenu != "" && submenu_over != mouse_over) {
_activate_submenu(mouse_over);
set_input_as_handled();
}
} else if (p_event->is_action("ui_accept") && p_event->is_pressed()) {
-
if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) {
-
if (items[mouse_over].submenu != "" && submenu_over != mouse_over) {
_activate_submenu(mouse_over);
} else {
@@ -296,25 +285,21 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> b = p_event;
if (b.is_valid()) {
-
- if (b->is_pressed())
+ if (b->is_pressed()) {
return;
+ }
int button_idx = b->get_button_index();
switch (button_idx) {
-
case BUTTON_WHEEL_DOWN: {
-
_scroll(-b->get_factor(), b->get_position());
} break;
case BUTTON_WHEEL_UP: {
-
_scroll(b->get_factor(), b->get_position());
} break;
default: {
// Allow activating item by releasing the LMB or any that was down when the popup appeared
if (button_idx == BUTTON_LEFT || (initial_button_mask & (1 << (button_idx - 1)))) {
-
bool was_during_grabbed_click = during_grabbed_click;
during_grabbed_click = false;
initial_button_mask = 0;
@@ -332,11 +317,11 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
break; //non-activable
}
- if (items[over].separator || items[over].disabled)
+ if (items[over].separator || items[over].disabled) {
break;
+ }
if (items[over].submenu != "") {
-
_activate_submenu(over);
return;
}
@@ -351,17 +336,15 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> m = p_event;
if (m.is_valid()) {
-
if (invalidated_click) {
moved += m->get_relative();
- if (moved.length() > 4)
+ if (moved.length() > 4) {
invalidated_click = false;
+ }
}
for (List<Rect2>::Element *E = autohide_areas.front(); E; E = E->next()) {
-
if (!Rect2(Point2(), get_size()).has_point(m->get_position()) && E->get().has_point(m->get_position())) {
-
_close_pressed();
return;
}
@@ -395,7 +378,6 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> k = p_event;
if (allow_search && k.is_valid() && k->get_unicode() && k->is_pressed()) {
-
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - search_time_msec;
uint64_t max_interval = uint64_t(GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000));
@@ -405,19 +387,22 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
search_string = "";
}
- if (String::chr(k->get_unicode()) != search_string)
+ if (String::chr(k->get_unicode()) != search_string) {
search_string += String::chr(k->get_unicode());
+ }
for (int i = mouse_over + 1; i <= items.size(); i++) {
if (i == items.size()) {
- if (mouse_over <= 0)
+ if (mouse_over <= 0) {
break;
- else
+ } else {
i = 0;
+ }
}
- if (i == mouse_over)
+ if (i == mouse_over) {
break;
+ }
if (items[i].text.findn(search_string) == 0) {
mouse_over = i;
@@ -431,7 +416,6 @@ void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
}
void PopupMenu::_draw() {
-
RID ci = control->get_canvas_item();
Size2 size = get_size();
@@ -460,39 +444,39 @@ void PopupMenu::_draw() {
float icon_ofs = 0.0;
bool has_check = false;
for (int i = 0; i < items.size(); i++) {
-
- if (!items[i].icon.is_null())
+ if (!items[i].icon.is_null()) {
icon_ofs = MAX(items[i].icon->get_size().width, icon_ofs);
+ }
- if (items[i].checkable_type)
+ if (items[i].checkable_type) {
has_check = true;
+ }
}
- if (icon_ofs > 0.0)
+ if (icon_ofs > 0.0) {
icon_ofs += hseparation;
+ }
float check_ofs = 0.0;
- if (has_check)
+ if (has_check) {
check_ofs = MAX(get_theme_icon("checked")->get_width(), get_theme_icon("radio_checked")->get_width()) + hseparation;
+ }
for (int i = 0; i < items.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
ofs.y += vseparation;
+ }
Point2 item_ofs = ofs;
Size2 icon_size;
float h;
if (!items[i].icon.is_null()) {
-
icon_size = items[i].icon->get_size();
h = MAX(icon_size.height, font_h);
} else {
-
h = font_h;
}
if (i == mouse_over) {
-
hover->draw(ci, Rect2(item_ofs + Point2(-hseparation, -vseparation / 2), Size2(get_size().width - style->get_minimum_size().width + hseparation * 2, h + vseparation)));
}
@@ -500,7 +484,6 @@ void PopupMenu::_draw() {
item_ofs.x += items[i].h_ofs;
if (items[i].separator) {
-
int sep_h = separator->get_center_size().height + separator->get_minimum_size().height;
if (text != String()) {
int ss = font->get_string_size(text).width;
@@ -535,13 +518,11 @@ void PopupMenu::_draw() {
item_ofs.y += font->get_ascent();
if (items[i].separator) {
-
if (text != String()) {
int center = (get_size().width - font->get_string_size(text).width) / 2;
font->draw(ci, Point2(center, item_ofs.y + Math::floor((h - font_h) / 2.0)), text, font_color_disabled);
}
} else {
-
item_ofs.x += icon_ofs + check_ofs;
font->draw(ci, item_ofs + Point2(0, Math::floor((h - font_h) / 2.0)), text, items[i].disabled ? font_color_disabled : (i == mouse_over ? font_color_hover : font_color));
}
@@ -560,11 +541,8 @@ void PopupMenu::_draw() {
}
void PopupMenu::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
PopupMenu *pm = Object::cast_to<PopupMenu>(get_parent());
if (pm) {
// Inherit submenu's popup delay time from parent menu
@@ -573,7 +551,6 @@ void PopupMenu::_notification(int p_what) {
}
} break;
case NOTIFICATION_TRANSLATION_CHANGED: {
-
for (int i = 0; i < items.size(); i++) {
items.write[i].xl_text = tr(items[i].text);
}
@@ -582,23 +559,19 @@ void PopupMenu::_notification(int p_what) {
control->update();
} break;
case NOTIFICATION_WM_MOUSE_ENTER: {
-
//grab_focus();
} break;
case NOTIFICATION_WM_MOUSE_EXIT: {
-
if (mouse_over >= 0 && (items[mouse_over].submenu == "" || submenu_over != -1)) {
mouse_over = -1;
control->update();
}
} break;
case NOTIFICATION_POST_POPUP: {
-
- initial_button_mask = InputFilter::get_singleton()->get_mouse_button_mask();
+ initial_button_mask = Input::get_singleton()->get_mouse_button_mask();
during_grabbed_click = (bool)initial_button_mask;
} break;
case NOTIFICATION_WM_SIZE_CHANGED: {
-
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
//only used when using operating system windows
@@ -607,7 +580,6 @@ void PopupMenu::_notification(int p_what) {
mouse_pos -= get_position();
for (List<Rect2>::Element *E = autohide_areas.front(); E; E = E->next()) {
-
if (!Rect2(Point2(), get_size()).has_point(mouse_pos) && E->get().has_point(mouse_pos)) {
_close_pressed();
return;
@@ -616,7 +588,6 @@ void PopupMenu::_notification(int p_what) {
}
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
if (!is_visible()) {
if (mouse_over >= 0) {
mouse_over = -1;
@@ -624,16 +595,19 @@ void PopupMenu::_notification(int p_what) {
}
for (int i = 0; i < items.size(); i++) {
- if (items[i].submenu == "")
+ if (items[i].submenu == "") {
continue;
+ }
Node *n = get_node(items[i].submenu);
- if (!n)
+ if (!n) {
continue;
+ }
PopupMenu *pm = Object::cast_to<PopupMenu>(n);
- if (!pm || !pm->is_visible())
+ if (!pm || !pm->is_visible()) {
continue;
+ }
pm->hide();
}
@@ -659,7 +633,6 @@ void PopupMenu::_notification(int p_what) {
item.accel = p_accel;
void PopupMenu::add_item(const String &p_label, int p_id, uint32_t p_accel) {
-
Item item;
ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel);
items.push_back(item);
@@ -668,7 +641,6 @@ void PopupMenu::add_item(const String &p_label, int p_id, uint32_t p_accel) {
}
void PopupMenu::add_icon_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id, uint32_t p_accel) {
-
Item item;
ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel);
item.icon = p_icon;
@@ -678,7 +650,6 @@ void PopupMenu::add_icon_item(const Ref<Texture2D> &p_icon, const String &p_labe
}
void PopupMenu::add_check_item(const String &p_label, int p_id, uint32_t p_accel) {
-
Item item;
ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel);
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
@@ -688,7 +659,6 @@ void PopupMenu::add_check_item(const String &p_label, int p_id, uint32_t p_accel
}
void PopupMenu::add_icon_check_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id, uint32_t p_accel) {
-
Item item;
ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel);
item.icon = p_icon;
@@ -699,7 +669,6 @@ void PopupMenu::add_icon_check_item(const Ref<Texture2D> &p_icon, const String &
}
void PopupMenu::add_radio_check_item(const String &p_label, int p_id, uint32_t p_accel) {
-
Item item;
ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel);
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
@@ -709,7 +678,6 @@ void PopupMenu::add_radio_check_item(const String &p_label, int p_id, uint32_t p
}
void PopupMenu::add_icon_radio_check_item(const Ref<Texture2D> &p_icon, const String &p_label, int p_id, uint32_t p_accel) {
-
Item item;
ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel);
item.icon = p_icon;
@@ -720,7 +688,6 @@ void PopupMenu::add_icon_radio_check_item(const Ref<Texture2D> &p_icon, const St
}
void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int p_default_state, int p_id, uint32_t p_accel) {
-
Item item;
ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel);
item.max_states = p_max_states;
@@ -740,7 +707,6 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int
item.shortcut_is_global = p_global;
void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
-
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
items.push_back(item);
@@ -749,7 +715,6 @@ void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_g
}
void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
-
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.icon = p_icon;
@@ -759,7 +724,6 @@ void PopupMenu::add_icon_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortC
}
void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
-
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX;
@@ -769,7 +733,6 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bo
}
void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
-
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.icon = p_icon;
@@ -780,7 +743,6 @@ void PopupMenu::add_icon_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<
}
void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
-
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON;
@@ -790,7 +752,6 @@ void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_
}
void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) {
-
Item item;
ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global);
item.icon = p_icon;
@@ -801,7 +762,6 @@ void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, cons
}
void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu, int p_id) {
-
Item item;
item.text = p_label;
item.xl_text = tr(p_label);
@@ -818,7 +778,6 @@ void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu,
/* Methods to modify existing items. */
void PopupMenu::set_item_text(int p_idx, const String &p_text) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].text = p_text;
items.write[p_idx].xl_text = tr(p_text);
@@ -826,16 +785,16 @@ void PopupMenu::set_item_text(int p_idx, const String &p_text) {
control->update();
child_controls_changed();
}
-void PopupMenu::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
+void PopupMenu::set_item_icon(int p_idx, const Ref<Texture2D> &p_icon) {
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].icon = p_icon;
control->update();
child_controls_changed();
}
-void PopupMenu::set_item_checked(int p_idx, bool p_checked) {
+void PopupMenu::set_item_checked(int p_idx, bool p_checked) {
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].checked = p_checked;
@@ -843,8 +802,8 @@ void PopupMenu::set_item_checked(int p_idx, bool p_checked) {
control->update();
child_controls_changed();
}
-void PopupMenu::set_item_id(int p_idx, int p_id) {
+void PopupMenu::set_item_id(int p_idx, int p_id) {
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].id = p_id;
@@ -853,7 +812,6 @@ void PopupMenu::set_item_id(int p_idx, int p_id) {
}
void PopupMenu::set_item_accelerator(int p_idx, uint32_t p_accel) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].accel = p_accel;
@@ -862,7 +820,6 @@ void PopupMenu::set_item_accelerator(int p_idx, uint32_t p_accel) {
}
void PopupMenu::set_item_metadata(int p_idx, const Variant &p_meta) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].metadata = p_meta;
control->update();
@@ -870,7 +827,6 @@ void PopupMenu::set_item_metadata(int p_idx, const Variant &p_meta) {
}
void PopupMenu::set_item_disabled(int p_idx, bool p_disabled) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].disabled = p_disabled;
control->update();
@@ -878,7 +834,6 @@ void PopupMenu::set_item_disabled(int p_idx, bool p_disabled) {
}
void PopupMenu::set_item_submenu(int p_idx, const String &p_submenu) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].submenu = p_submenu;
control->update();
@@ -886,7 +841,6 @@ void PopupMenu::set_item_submenu(int p_idx, const String &p_submenu) {
}
void PopupMenu::toggle_item_checked(int p_idx) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].checked = !items[p_idx].checked;
control->update();
@@ -894,82 +848,71 @@ void PopupMenu::toggle_item_checked(int p_idx) {
}
String PopupMenu::get_item_text(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), "");
return items[p_idx].text;
}
int PopupMenu::get_item_idx_from_text(const String &text) const {
-
for (int idx = 0; idx < items.size(); idx++) {
- if (items[idx].text == text)
+ if (items[idx].text == text) {
return idx;
+ }
}
return -1;
}
Ref<Texture2D> PopupMenu::get_item_icon(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture2D>());
return items[p_idx].icon;
}
uint32_t PopupMenu::get_item_accelerator(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), 0);
return items[p_idx].accel;
}
Variant PopupMenu::get_item_metadata(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), Variant());
return items[p_idx].metadata;
}
bool PopupMenu::is_item_disabled(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), false);
return items[p_idx].disabled;
}
bool PopupMenu::is_item_checked(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), false);
return items[p_idx].checked;
}
int PopupMenu::get_item_id(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), 0);
return items[p_idx].id;
}
int PopupMenu::get_item_index(int p_id) const {
-
for (int i = 0; i < items.size(); i++) {
-
- if (items[i].id == p_id)
+ if (items[i].id == p_id) {
return i;
+ }
}
return -1;
}
String PopupMenu::get_item_submenu(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), "");
return items[p_idx].submenu;
}
String PopupMenu::get_item_tooltip(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), "");
return items[p_idx].tooltip;
}
Ref<ShortCut> PopupMenu::get_item_shortcut(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<ShortCut>());
return items[p_idx].shortcut;
}
@@ -980,7 +923,6 @@ int PopupMenu::get_item_state(int p_idx) const {
}
void PopupMenu::set_item_as_separator(int p_idx, bool p_separator) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].separator = p_separator;
control->update();
@@ -992,21 +934,18 @@ bool PopupMenu::is_item_separator(int p_idx) const {
}
void PopupMenu::set_item_as_checkable(int p_idx, bool p_checkable) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].checkable_type = p_checkable ? Item::CHECKABLE_TYPE_CHECK_BOX : Item::CHECKABLE_TYPE_NONE;
control->update();
}
void PopupMenu::set_item_as_radio_checkable(int p_idx, bool p_radio_checkable) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].checkable_type = p_radio_checkable ? Item::CHECKABLE_TYPE_RADIO_BUTTON : Item::CHECKABLE_TYPE_NONE;
control->update();
}
void PopupMenu::set_item_tooltip(int p_idx, const String &p_tooltip) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].tooltip = p_tooltip;
control->update();
@@ -1028,7 +967,6 @@ void PopupMenu::set_item_shortcut(int p_idx, const Ref<ShortCut> &p_shortcut, bo
}
void PopupMenu::set_item_h_offset(int p_idx, int p_offset) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].h_ofs = p_offset;
control->update();
@@ -1036,29 +974,27 @@ void PopupMenu::set_item_h_offset(int p_idx, int p_offset) {
}
void PopupMenu::set_item_multistate(int p_idx, int p_state) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].state = p_state;
control->update();
}
void PopupMenu::set_item_shortcut_disabled(int p_idx, bool p_disabled) {
-
ERR_FAIL_INDEX(p_idx, items.size());
items.write[p_idx].shortcut_is_disabled = p_disabled;
control->update();
}
void PopupMenu::toggle_item_multistate(int p_idx) {
-
ERR_FAIL_INDEX(p_idx, items.size());
if (0 >= items[p_idx].max_states) {
return;
}
++items.write[p_idx].state;
- if (items.write[p_idx].max_states <= items[p_idx].state)
+ if (items.write[p_idx].max_states <= items[p_idx].state) {
items.write[p_idx].state = 0;
+ }
control->update();
}
@@ -1074,38 +1010,45 @@ bool PopupMenu::is_item_radio_checkable(int p_idx) const {
}
bool PopupMenu::is_item_shortcut_disabled(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, items.size(), false);
return items[p_idx].shortcut_is_disabled;
}
-int PopupMenu::get_item_count() const {
+int PopupMenu::get_current_index() const {
+ return mouse_over;
+}
+int PopupMenu::get_item_count() const {
return items.size();
}
bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_for_global_only) {
-
uint32_t code = 0;
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
code = k->get_keycode();
- if (code == 0)
+ if (code == 0) {
code = k->get_unicode();
- if (k->get_control())
+ }
+ if (k->get_control()) {
code |= KEY_MASK_CTRL;
- if (k->get_alt())
+ }
+ if (k->get_alt()) {
code |= KEY_MASK_ALT;
- if (k->get_metakey())
+ }
+ if (k->get_metakey()) {
code |= KEY_MASK_META;
- if (k->get_shift())
+ }
+ if (k->get_shift()) {
code |= KEY_MASK_SHIFT;
+ }
}
for (int i = 0; i < items.size(); i++) {
- if (is_item_disabled(i) || items[i].shortcut_is_disabled)
+ if (is_item_disabled(i) || items[i].shortcut_is_disabled) {
continue;
+ }
if (items[i].shortcut.is_valid() && items[i].shortcut->is_shortcut(p_event) && (items[i].shortcut_is_global || !p_for_global_only)) {
activate_item(i);
@@ -1119,12 +1062,14 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo
if (items[i].submenu != "") {
Node *n = get_node(items[i].submenu);
- if (!n)
+ if (!n) {
continue;
+ }
PopupMenu *pm = Object::cast_to<PopupMenu>(n);
- if (!pm)
+ if (!pm) {
continue;
+ }
if (pm->activate_item_by_event(p_event, p_for_global_only)) {
return true;
@@ -1135,7 +1080,6 @@ bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_fo
}
void PopupMenu::activate_item(int p_item) {
-
ERR_FAIL_INDEX(p_item, items.size());
ERR_FAIL_COND(items[p_item].separator);
int id = items[p_item].id >= 0 ? items[p_item].id : p_item;
@@ -1148,13 +1092,16 @@ void PopupMenu::activate_item(int p_item) {
// with hide_on_item_selection enabled
if (items[p_item].checkable_type) {
- if (!hide_on_checkable_item_selection || !pop->is_hide_on_checkable_item_selection())
+ if (!hide_on_checkable_item_selection || !pop->is_hide_on_checkable_item_selection()) {
break;
+ }
} else if (0 < items[p_item].max_states) {
- if (!hide_on_multistate_item_selection || !pop->is_hide_on_multistate_item_selection())
+ if (!hide_on_multistate_item_selection || !pop->is_hide_on_multistate_item_selection()) {
break;
- } else if (!hide_on_item_selection || !pop->is_hide_on_item_selection())
+ }
+ } else if (!hide_on_item_selection || !pop->is_hide_on_item_selection()) {
break;
+ }
pop->hide();
next = next->get_parent();
@@ -1167,13 +1114,16 @@ void PopupMenu::activate_item(int p_item) {
bool need_hide = true;
if (items[p_item].checkable_type) {
- if (!hide_on_checkable_item_selection)
+ if (!hide_on_checkable_item_selection) {
need_hide = false;
+ }
} else if (0 < items[p_item].max_states) {
- if (!hide_on_multistate_item_selection)
+ if (!hide_on_multistate_item_selection) {
need_hide = false;
- } else if (!hide_on_item_selection)
+ }
+ } else if (!hide_on_item_selection) {
need_hide = false;
+ }
emit_signal("id_pressed", id);
emit_signal("index_pressed", p_item);
@@ -1184,7 +1134,6 @@ void PopupMenu::activate_item(int p_item) {
}
void PopupMenu::remove_item(int p_idx) {
-
ERR_FAIL_INDEX(p_idx, items.size());
if (items[p_idx].shortcut.is_valid()) {
@@ -1197,7 +1146,6 @@ void PopupMenu::remove_item(int p_idx) {
}
void PopupMenu::add_separator(const String &p_text) {
-
Item sep;
sep.separator = true;
sep.id = -1;
@@ -1210,7 +1158,6 @@ void PopupMenu::add_separator(const String &p_text) {
}
void PopupMenu::clear() {
-
for (int i = 0; i < items.size(); i++) {
if (items[i].shortcut.is_valid()) {
_unref_shortcut(items[i].shortcut);
@@ -1223,10 +1170,8 @@ void PopupMenu::clear() {
}
Array PopupMenu::_get_items() const {
-
Array items;
for (int i = 0; i < get_item_count(); i++) {
-
items.push_back(get_item_text(i));
items.push_back(get_item_icon(i));
// For compatibility, use false/true for no/checkbox and integers for other values
@@ -1246,7 +1191,6 @@ Array PopupMenu::_get_items() const {
}
void PopupMenu::_ref_shortcut(Ref<ShortCut> p_sc) {
-
if (!shortcut_refcount.has(p_sc)) {
shortcut_refcount[p_sc] = 1;
p_sc->connect("changed", callable_mp((CanvasItem *)this, &CanvasItem::update));
@@ -1256,7 +1200,6 @@ void PopupMenu::_ref_shortcut(Ref<ShortCut> p_sc) {
}
void PopupMenu::_unref_shortcut(Ref<ShortCut> p_sc) {
-
ERR_FAIL_COND(!shortcut_refcount.has(p_sc));
shortcut_refcount[p_sc]--;
if (shortcut_refcount[p_sc] == 0) {
@@ -1266,12 +1209,10 @@ void PopupMenu::_unref_shortcut(Ref<ShortCut> p_sc) {
}
void PopupMenu::_set_items(const Array &p_items) {
-
ERR_FAIL_COND(p_items.size() % 10);
clear();
for (int i = 0; i < p_items.size(); i += 10) {
-
String text = p_items[i + 0];
Ref<Texture2D> icon = p_items[i + 1];
// For compatibility, use false/true for no/checkbox and integers for other values
@@ -1308,87 +1249,74 @@ void PopupMenu::_set_items(const Array &p_items) {
// Hide on item selection determines whether or not the popup will close after item selection
void PopupMenu::set_hide_on_item_selection(bool p_enabled) {
-
hide_on_item_selection = p_enabled;
}
bool PopupMenu::is_hide_on_item_selection() const {
-
return hide_on_item_selection;
}
void PopupMenu::set_hide_on_checkable_item_selection(bool p_enabled) {
-
hide_on_checkable_item_selection = p_enabled;
}
bool PopupMenu::is_hide_on_checkable_item_selection() const {
-
return hide_on_checkable_item_selection;
}
void PopupMenu::set_hide_on_multistate_item_selection(bool p_enabled) {
-
hide_on_multistate_item_selection = p_enabled;
}
bool PopupMenu::is_hide_on_multistate_item_selection() const {
-
return hide_on_multistate_item_selection;
}
void PopupMenu::set_submenu_popup_delay(float p_time) {
-
- if (p_time <= 0)
+ if (p_time <= 0) {
p_time = 0.01;
+ }
submenu_timer->set_wait_time(p_time);
}
float PopupMenu::get_submenu_popup_delay() const {
-
return submenu_timer->get_wait_time();
}
void PopupMenu::set_allow_search(bool p_allow) {
-
allow_search = p_allow;
}
bool PopupMenu::get_allow_search() const {
-
return allow_search;
}
String PopupMenu::get_tooltip(const Point2 &p_pos) const {
-
int over = _get_mouse_over(p_pos);
- if (over < 0 || over >= items.size())
+ if (over < 0 || over >= items.size()) {
return "";
+ }
return items[over].tooltip;
}
void PopupMenu::set_parent_rect(const Rect2 &p_rect) {
-
parent_rect = p_rect;
}
void PopupMenu::get_translatable_strings(List<String> *p_strings) const {
-
for (int i = 0; i < items.size(); i++) {
-
- if (items[i].xl_text != "")
+ if (items[i].xl_text != "") {
p_strings->push_back(items[i].xl_text);
+ }
}
}
void PopupMenu::add_autohide_area(const Rect2 &p_area) {
-
autohide_areas.push_back(p_area);
}
void PopupMenu::clear_autohide_areas() {
-
autohide_areas.clear();
}
@@ -1401,7 +1329,6 @@ void PopupMenu::take_mouse_focus() {
}
void PopupMenu::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &PopupMenu::_gui_input);
ClassDB::bind_method(D_METHOD("add_item", "label", "id", "accel"), &PopupMenu::add_item, DEFVAL(-1), DEFVAL(0));
@@ -1457,6 +1384,7 @@ void PopupMenu::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_item_tooltip", "idx"), &PopupMenu::get_item_tooltip);
ClassDB::bind_method(D_METHOD("get_item_shortcut", "idx"), &PopupMenu::get_item_shortcut);
+ ClassDB::bind_method(D_METHOD("get_current_index"), &PopupMenu::get_current_index);
ClassDB::bind_method(D_METHOD("get_item_count"), &PopupMenu::get_item_count);
ClassDB::bind_method(D_METHOD("remove_item", "idx"), &PopupMenu::remove_item);
@@ -1495,14 +1423,12 @@ void PopupMenu::_bind_methods() {
}
void PopupMenu::popup(const Rect2 &p_bounds) {
-
moved = Vector2();
invalidated_click = true;
Popup::popup(p_bounds);
}
PopupMenu::PopupMenu() {
-
control = memnew(Control);
add_child(control);
@@ -1516,7 +1442,7 @@ PopupMenu::PopupMenu() {
during_grabbed_click = false;
invalidated_click = false;
- allow_search = false;
+ allow_search = true;
search_time_msec = 0;
search_string = "";
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index 2eef1f009d..d03a14d6e4 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -35,7 +35,6 @@
#include "scene/gui/shortcut.h"
class PopupMenu : public Popup {
-
GDCLASS(PopupMenu, Popup);
struct Item {
@@ -178,6 +177,7 @@ public:
Ref<ShortCut> get_item_shortcut(int p_idx) const;
int get_item_state(int p_idx) const;
+ int get_current_index() const;
int get_item_count() const;
bool activate_item_by_event(const Ref<InputEvent> &p_event, bool p_for_global_only = false);
diff --git a/scene/gui/progress_bar.cpp b/scene/gui/progress_bar.cpp
index 362c45453d..9246f1723d 100644
--- a/scene/gui/progress_bar.cpp
+++ b/scene/gui/progress_bar.cpp
@@ -31,7 +31,6 @@
#include "progress_bar.h"
Size2 ProgressBar::get_minimum_size() const {
-
Ref<StyleBox> bg = get_theme_stylebox("bg");
Ref<StyleBox> fg = get_theme_stylebox("fg");
Ref<Font> font = get_theme_font("font");
@@ -49,9 +48,7 @@ Size2 ProgressBar::get_minimum_size() const {
}
void ProgressBar::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
-
Ref<StyleBox> bg = get_theme_stylebox("bg");
Ref<StyleBox> fg = get_theme_stylebox("fg");
Ref<Font> font = get_theme_font("font");
@@ -62,7 +59,6 @@ void ProgressBar::_notification(int p_what) {
int mp = fg->get_minimum_size().width;
int p = r * (get_size().width - mp);
if (p > 0) {
-
draw_style_box(fg, Rect2(Point2(), Size2(p + fg->get_minimum_size().width, get_size().height)));
}
@@ -74,18 +70,15 @@ void ProgressBar::_notification(int p_what) {
}
void ProgressBar::set_percent_visible(bool p_visible) {
-
percent_visible = p_visible;
update();
}
bool ProgressBar::is_percent_visible() const {
-
return percent_visible;
}
void ProgressBar::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_percent_visible", "visible"), &ProgressBar::set_percent_visible);
ClassDB::bind_method(D_METHOD("is_percent_visible"), &ProgressBar::is_percent_visible);
ADD_GROUP("Percent", "percent_");
@@ -93,7 +86,6 @@ void ProgressBar::_bind_methods() {
}
ProgressBar::ProgressBar() {
-
set_v_size_flags(0);
set_step(0.01);
percent_visible = true;
diff --git a/scene/gui/progress_bar.h b/scene/gui/progress_bar.h
index 371d0370f6..d8eba921a3 100644
--- a/scene/gui/progress_bar.h
+++ b/scene/gui/progress_bar.h
@@ -34,7 +34,6 @@
#include "scene/gui/range.h"
class ProgressBar : public Range {
-
GDCLASS(ProgressBar, Range);
bool percent_visible;
diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp
index ab2f64e1b4..59e26d9e38 100644
--- a/scene/gui/range.cpp
+++ b/scene/gui/range.cpp
@@ -44,7 +44,6 @@ String Range::get_configuration_warning() const {
}
void Range::_value_changed_notify() {
-
_value_changed(shared->val);
emit_signal("value_changed", shared->val);
update();
@@ -52,53 +51,57 @@ void Range::_value_changed_notify() {
}
void Range::Shared::emit_value_changed() {
-
for (Set<Range *>::Element *E = owners.front(); E; E = E->next()) {
Range *r = E->get();
- if (!r->is_inside_tree())
+ if (!r->is_inside_tree()) {
continue;
+ }
r->_value_changed_notify();
}
}
void Range::_changed_notify(const char *p_what) {
-
emit_signal("changed");
update();
_change_notify(p_what);
}
void Range::Shared::emit_changed(const char *p_what) {
-
for (Set<Range *>::Element *E = owners.front(); E; E = E->next()) {
Range *r = E->get();
- if (!r->is_inside_tree())
+ if (!r->is_inside_tree()) {
continue;
+ }
r->_changed_notify(p_what);
}
}
void Range::set_value(double p_val) {
-
- if (shared->step > 0)
+ if (shared->step > 0) {
p_val = Math::round(p_val / shared->step) * shared->step;
+ }
- if (_rounded_values)
+ if (_rounded_values) {
p_val = Math::round(p_val);
+ }
- if (!shared->allow_greater && p_val > shared->max - shared->page)
+ if (!shared->allow_greater && p_val > shared->max - shared->page) {
p_val = shared->max - shared->page;
+ }
- if (!shared->allow_lesser && p_val < shared->min)
+ if (!shared->allow_lesser && p_val < shared->min) {
p_val = shared->min;
+ }
- if (shared->val == p_val)
+ if (shared->val == p_val) {
return;
+ }
shared->val = p_val;
shared->emit_value_changed();
}
+
void Range::set_min(double p_min) {
shared->min = p_min;
set_value(shared->val);
@@ -107,19 +110,20 @@ void Range::set_min(double p_min) {
update_configuration_warning();
}
+
void Range::set_max(double p_max) {
shared->max = p_max;
set_value(shared->val);
shared->emit_changed("max");
}
-void Range::set_step(double p_step) {
+void Range::set_step(double p_step) {
shared->step = p_step;
shared->emit_changed("step");
}
-void Range::set_page(double p_page) {
+void Range::set_page(double p_page) {
shared->page = p_page;
set_value(shared->val);
@@ -127,37 +131,33 @@ void Range::set_page(double p_page) {
}
double Range::get_value() const {
-
return shared->val;
}
-double Range::get_min() const {
+double Range::get_min() const {
return shared->min;
}
-double Range::get_max() const {
+double Range::get_max() const {
return shared->max;
}
-double Range::get_step() const {
+double Range::get_step() const {
return shared->step;
}
-double Range::get_page() const {
+double Range::get_page() const {
return shared->page;
}
void Range::set_as_ratio(double p_value) {
-
double v;
if (shared->exp_ratio && get_min() >= 0) {
-
double exp_min = get_min() == 0 ? 0.0 : Math::log(get_min()) / Math::log((double)2);
double exp_max = Math::log(get_max()) / Math::log((double)2);
v = Math::pow(2, exp_min + (exp_max - exp_min) * p_value);
} else {
-
double percent = (get_max() - get_min()) * p_value;
if (get_step() > 0) {
double steps = round(percent / get_step());
@@ -169,12 +169,11 @@ void Range::set_as_ratio(double p_value) {
v = CLAMP(v, get_min(), get_max());
set_value(v);
}
-double Range::get_as_ratio() const {
+double Range::get_as_ratio() const {
ERR_FAIL_COND_V_MSG(Math::is_equal_approx(get_max(), get_min()), 0.0, "Cannot get ratio when minimum and maximum value are equal.");
if (shared->exp_ratio && get_min() >= 0) {
-
double exp_min = get_min() == 0 ? 0.0 : Math::log(get_min()) / Math::log((double)2);
double exp_max = Math::log(get_max()) / Math::log((double)2);
float value = CLAMP(get_value(), shared->min, shared->max);
@@ -183,21 +182,18 @@ double Range::get_as_ratio() const {
return CLAMP((v - exp_min) / (exp_max - exp_min), 0, 1);
} else {
-
float value = CLAMP(get_value(), shared->min, shared->max);
return CLAMP((value - get_min()) / (get_max() - get_min()), 0, 1);
}
}
void Range::_share(Node *p_range) {
-
Range *r = Object::cast_to<Range>(p_range);
ERR_FAIL_COND(!r);
share(r);
}
void Range::share(Range *p_range) {
-
ERR_FAIL_NULL(p_range);
p_range->_ref_shared(shared);
@@ -206,7 +202,6 @@ void Range::share(Range *p_range) {
}
void Range::unshare() {
-
Shared *nshared = memnew(Shared);
nshared->min = shared->min;
nshared->max = shared->max;
@@ -221,9 +216,9 @@ void Range::unshare() {
}
void Range::_ref_shared(Shared *p_shared) {
-
- if (shared && p_shared == shared)
+ if (shared && p_shared == shared) {
return;
+ }
_unref_shared();
shared = p_shared;
@@ -231,7 +226,6 @@ void Range::_ref_shared(Shared *p_shared) {
}
void Range::_unref_shared() {
-
if (shared) {
shared->owners.erase(this);
if (shared->owners.size() == 0) {
@@ -242,7 +236,6 @@ void Range::_unref_shared() {
}
void Range::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_value"), &Range::get_value);
ClassDB::bind_method(D_METHOD("get_min"), &Range::get_min);
ClassDB::bind_method(D_METHOD("get_max"), &Range::get_max);
@@ -283,49 +276,40 @@ void Range::_bind_methods() {
}
void Range::set_use_rounded_values(bool p_enable) {
-
_rounded_values = p_enable;
}
bool Range::is_using_rounded_values() const {
-
return _rounded_values;
}
void Range::set_exp_ratio(bool p_enable) {
-
shared->exp_ratio = p_enable;
update_configuration_warning();
}
bool Range::is_ratio_exp() const {
-
return shared->exp_ratio;
}
void Range::set_allow_greater(bool p_allow) {
-
shared->allow_greater = p_allow;
}
bool Range::is_greater_allowed() const {
-
return shared->allow_greater;
}
void Range::set_allow_lesser(bool p_allow) {
-
shared->allow_lesser = p_allow;
}
bool Range::is_lesser_allowed() const {
-
return shared->allow_lesser;
}
Range::Range() {
-
shared = memnew(Shared);
shared->min = 0;
shared->max = 100;
@@ -341,6 +325,5 @@ Range::Range() {
}
Range::~Range() {
-
_unref_shared();
}
diff --git a/scene/gui/range.h b/scene/gui/range.h
index 819d76941b..fe43985d0d 100644
--- a/scene/gui/range.h
+++ b/scene/gui/range.h
@@ -34,7 +34,6 @@
#include "scene/gui/control.h"
class Range : public Control {
-
GDCLASS(Range, Control);
struct Shared {
diff --git a/scene/gui/reference_rect.cpp b/scene/gui/reference_rect.cpp
index 0765e5d882..27c57c684a 100644
--- a/scene/gui/reference_rect.cpp
+++ b/scene/gui/reference_rect.cpp
@@ -33,13 +33,13 @@
#include "core/engine.h"
void ReferenceRect::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
- if (Engine::get_singleton()->is_editor_hint() || !editor_only)
+ }
+ if (Engine::get_singleton()->is_editor_hint() || !editor_only) {
draw_rect(Rect2(Point2(), get_size()), border_color, false);
+ }
}
}
diff --git a/scene/gui/reference_rect.h b/scene/gui/reference_rect.h
index c25c54f271..db2f4269f3 100644
--- a/scene/gui/reference_rect.h
+++ b/scene/gui/reference_rect.h
@@ -34,7 +34,6 @@
#include "scene/gui/control.h"
class ReferenceRect : public Control {
-
GDCLASS(ReferenceRect, Control);
Color border_color;
bool editor_only;
diff --git a/scene/gui/rich_text_effect.cpp b/scene/gui/rich_text_effect.cpp
index 0f5926ea1c..2628e5ab0f 100644
--- a/scene/gui/rich_text_effect.cpp
+++ b/scene/gui/rich_text_effect.cpp
@@ -64,7 +64,6 @@ RichTextEffect::RichTextEffect() {
}
void CharFXTransform::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_relative_index"), &CharFXTransform::get_relative_index);
ClassDB::bind_method(D_METHOD("set_relative_index", "index"), &CharFXTransform::set_relative_index);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 9fab9005f9..a57408b83b 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -46,16 +46,12 @@
#endif
RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) {
-
if (p_free) {
-
if (p_item->subitems.size()) {
-
return p_item->subitems.front()->get();
} else if (!p_item->parent) {
return nullptr;
} else if (p_item->E->next()) {
-
return p_item->E->next()->get();
} else {
//go up until something with a next is found
@@ -63,20 +59,19 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) {
p_item = p_item->parent;
}
- if (p_item->parent)
+ if (p_item->parent) {
return p_item->E->next()->get();
- else
+ } else {
return nullptr;
+ }
}
} else {
if (p_item->subitems.size() && p_item->type != ITEM_TABLE) {
-
return p_item->subitems.front()->get();
} else if (p_item->type == ITEM_FRAME) {
return nullptr;
} else if (p_item->E->next()) {
-
return p_item->E->next()->get();
} else {
//go up until something with a next is found
@@ -84,10 +79,11 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) {
p_item = p_item->parent;
}
- if (p_item->type != ITEM_FRAME)
+ if (p_item->type != ITEM_FRAME) {
return p_item->E->next()->get();
- else
+ } else {
return nullptr;
+ }
}
}
@@ -96,14 +92,11 @@ RichTextLabel::Item *RichTextLabel::_get_next_item(Item *p_item, bool p_free) {
RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) {
if (p_free) {
-
if (p_item->subitems.size()) {
-
return p_item->subitems.back()->get();
} else if (!p_item->parent) {
return nullptr;
} else if (p_item->E->prev()) {
-
return p_item->E->prev()->get();
} else {
//go back until something with a prev is found
@@ -111,20 +104,19 @@ RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) {
p_item = p_item->parent;
}
- if (p_item->parent)
+ if (p_item->parent) {
return p_item->E->prev()->get();
- else
+ } else {
return nullptr;
+ }
}
} else {
if (p_item->subitems.size() && p_item->type != ITEM_TABLE) {
-
return p_item->subitems.back()->get();
} else if (p_item->type == ITEM_FRAME) {
return nullptr;
} else if (p_item->E->prev()) {
-
return p_item->E->prev()->get();
} else {
//go back until something with a prev is found
@@ -132,10 +124,11 @@ RichTextLabel::Item *RichTextLabel::_get_prev_item(Item *p_item, bool p_free) {
p_item = p_item->parent;
}
- if (p_item->type != ITEM_FRAME)
+ if (p_item->type != ITEM_FRAME) {
return p_item->E->prev()->get();
- else
+ } else {
return nullptr;
+ }
}
}
@@ -148,17 +141,18 @@ Rect2 RichTextLabel::_get_text_rect() {
}
int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &y, int p_width, int p_line, ProcessMode p_mode, const Ref<Font> &p_base_font, const Color &p_base_color, const Color &p_font_color_shadow, bool p_shadow_as_outline, const Point2 &shadow_ofs, const Point2i &p_click_pos, Item **r_click_item, int *r_click_char, bool *r_outside, int p_char_count) {
-
ERR_FAIL_INDEX_V((int)p_mode, 3, 0);
RID ci;
- if (r_outside)
+ if (r_outside) {
*r_outside = false;
+ }
if (p_mode == PROCESS_DRAW) {
ci = get_canvas_item();
- if (r_click_item)
+ if (r_click_item) {
*r_click_item = nullptr;
+ }
}
Line &l = p_frame->lines.write[p_line];
Item *it = l.from;
@@ -172,7 +166,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int height = get_size().y;
if (p_mode != PROCESS_CACHE) {
-
ERR_FAIL_INDEX_V(line, l.offset_caches.size(), 0);
line_ofs = l.offset_caches[line];
}
@@ -191,14 +184,16 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int spaces_size = 0;
int align_ofs = 0;
- if (p_mode != PROCESS_CACHE && align != ALIGN_FILL)
+ if (p_mode != PROCESS_CACHE && align != ALIGN_FILL) {
wofs += line_ofs;
+ }
int begin = wofs;
Ref<Font> cfont = _find_font(it);
- if (cfont.is_null())
+ if (cfont.is_null()) {
cfont = p_base_font;
+ }
//line height should be the font height for the first time, this ensures that an empty line will never have zero height and successive newlines are displayed
int line_height = cfont->get_height();
@@ -230,10 +225,18 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
} else { \
int used = wofs - margin; \
switch (align) { \
- case ALIGN_LEFT: l.offset_caches.push_back(0); break; \
- case ALIGN_CENTER: l.offset_caches.push_back(((p_width - margin) - used) / 2); break; \
- case ALIGN_RIGHT: l.offset_caches.push_back(((p_width - margin) - used)); break; \
- case ALIGN_FILL: l.offset_caches.push_back(line_wrapped ? ((p_width - margin) - used) : 0); break; \
+ case ALIGN_LEFT: \
+ l.offset_caches.push_back(0); \
+ break; \
+ case ALIGN_CENTER: \
+ l.offset_caches.push_back(((p_width - margin) - used) / 2); \
+ break; \
+ case ALIGN_RIGHT: \
+ l.offset_caches.push_back(((p_width - margin) - used)); \
+ break; \
+ case ALIGN_FILL: \
+ l.offset_caches.push_back(line_wrapped ? ((p_width - margin) - used) : 0); \
+ break; \
} \
l.height_caches.push_back(line_height); \
l.ascent_caches.push_back(line_ascent); \
@@ -255,7 +258,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
line_descent = line < l.descent_caches.size() ? l.descent_caches[line] : 1; \
} \
if (p_mode == PROCESS_POINTER && r_click_item && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh && p_click_pos.x < p_ofs.x + wofs) { \
- if (r_outside) *r_outside = true; \
+ if (r_outside) \
+ *r_outside = true; \
*r_click_item = it; \
*r_click_char = rchar; \
RETURN; \
@@ -275,7 +279,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
} \
const bool x_in_range = (p_click_pos.x > p_ofs.x + wofs) && (!p_frame->cell || p_click_pos.x < p_ofs.x + p_width); \
if (p_mode == PROCESS_POINTER && r_click_item && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh && x_in_range) { \
- if (r_outside) *r_outside = true; \
+ if (r_outside) \
+ *r_outside = true; \
*r_click_item = it; \
*r_click_char = rchar; \
RETURN; \
@@ -286,7 +291,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
#define ADVANCE(m_width) \
{ \
if (p_mode == PROCESS_POINTER && r_click_item && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh && p_click_pos.x >= p_ofs.x + wofs && p_click_pos.x < p_ofs.x + wofs + m_width) { \
- if (r_outside) *r_outside = false; \
+ if (r_outside) \
+ *r_outside = false; \
*r_click_item = it; \
*r_click_char = rchar; \
RETURN; \
@@ -317,18 +323,14 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int fh = 0;
while (it) {
-
switch (it->type) {
-
case ITEM_ALIGN: {
-
ItemAlign *align_it = static_cast<ItemAlign *>(it);
align = align_it->align;
} break;
case ITEM_INDENT: {
-
if (it != l.from) {
ItemIndent *indent_it = static_cast<ItemIndent *>(it);
@@ -340,12 +342,12 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
} break;
case ITEM_TEXT: {
-
ItemText *text = static_cast<ItemText *>(it);
Ref<Font> font = _find_font(it);
- if (font.is_null())
+ if (font.is_null()) {
font = p_base_font;
+ }
const CharType *c = text->text.c_str();
const CharType *cf = c;
@@ -388,7 +390,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
rchar = 0;
FontDrawer drawer(font, Color(1, 1, 1));
while (*c) {
-
int end = 0;
int w = 0;
int fw = 0;
@@ -401,7 +402,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
line_descent = line < l.descent_caches.size() ? l.descent_caches[line] : 1;
}
while (c[end] != 0 && !(end && c[end - 1] == ' ' && c[end] != ' ')) {
-
int cw = font->get_char_size(c[end], c[end + 1]).width;
if (c[end] == '\t') {
cw = tab_size * font->get_char_size(' ').width;
@@ -435,14 +435,12 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
}
{
-
int ofs = 0 - backtrack;
for (int i = 0; i < end; i++) {
int pofs = wofs + ofs;
if (p_mode == PROCESS_POINTER && r_click_char && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh) {
-
int cw = font->get_char_size(c[i], c[i + 1]).x;
if (c[i] == '\t') {
@@ -450,7 +448,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
}
if (p_click_pos.x - cw / 2 > p_ofs.x + align_ofs + pofs) {
-
rchar = int((&c[i]) - cf);
}
@@ -462,7 +459,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
CharType fx_char = c[i];
if (selection.active) {
-
int cofs = (&c[i]) - cf;
if ((text->index > selection.from->index || (text->index == selection.from->index && cofs >= selection.from_char)) && (text->index < selection.to->index || (text->index == selection.to->index && cofs <= selection.to_char))) {
selected = true;
@@ -487,7 +483,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
const bool previously_visible = visible;
for (int j = 0; j < fx_stack.size(); j++) {
-
ItemFX *item_fx = fx_stack[j];
if (item_fx->type == ITEM_CUSTOMFX && custom_fx_ok) {
@@ -556,11 +551,11 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
w += font->get_char_size(c[i], c[i + 1]).x;
}
- if (c[i] == '\t')
+ if (c[i] == '\t') {
visible = false;
+ }
if (visible) {
-
if (selected) {
cw = font->get_char_size(fx_char, c[i + 1]).x;
draw_rect(Rect2(p_ofs.x + pofs, p_ofs.y + y, cw, lh), selection_bg);
@@ -600,8 +595,8 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
if (underline) {
Color uc = color;
uc.a *= 0.5;
- int uy = y + lh - line_descent + 2;
- float underline_width = 1.0;
+ int uy = y + lh - line_descent + font->get_underline_position();
+ float underline_width = font->get_underline_thickness();
#ifdef TOOLS_ENABLED
underline_width *= EDSCALE;
#endif
@@ -610,7 +605,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
Color uc = color;
uc.a *= 0.5;
int uy = y + lh - (line_ascent + line_descent) / 2;
- float strikethrough_width = 1.0;
+ float strikethrough_width = font->get_underline_thickness();
#ifdef TOOLS_ENABLED
strikethrough_width *= EDSCALE;
#endif
@@ -625,27 +620,30 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
} break;
case ITEM_IMAGE: {
-
lh = 0;
- if (p_mode != PROCESS_CACHE)
+ if (p_mode != PROCESS_CACHE) {
lh = line < l.height_caches.size() ? l.height_caches[line] : 1;
- else
+ } else {
l.char_count += 1; //images count as chars too
+ }
ItemImage *img = static_cast<ItemImage *>(it);
Ref<Font> font = _find_font(it);
- if (font.is_null())
+ if (font.is_null()) {
font = p_base_font;
+ }
- if (p_mode == PROCESS_POINTER && r_click_char)
+ if (p_mode == PROCESS_POINTER && r_click_char) {
*r_click_char = 0;
+ }
ENSURE_WIDTH(img->size.width);
bool visible = visible_characters < 0 || (p_char_count < visible_characters && YRANGE_VISIBLE(y + lh - font->get_descent() - img->size.height, img->size.height));
- if (visible)
+ if (visible) {
line_is_blank = false;
+ }
if (p_mode == PROCESS_DRAW && visible) {
img->image->draw_rect(ci, Rect2(p_ofs + Point2(align_ofs + wofs, y + lh - font->get_descent() - img->size.height), img->size));
@@ -657,7 +655,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
} break;
case ITEM_NEWLINE: {
-
lh = 0;
if (p_mode != PROCESS_CACHE) {
@@ -667,7 +664,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
} break;
case ITEM_TABLE: {
-
lh = 0;
ItemTable *table = static_cast<ItemTable *>(it);
int hseparation = get_theme_constant("table_hseparation");
@@ -679,7 +675,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
Point2 shadow_ofs2(get_theme_constant("shadow_offset_x"), get_theme_constant("shadow_offset_y"));
if (p_mode == PROCESS_CACHE) {
-
int idx = 0;
//set minimums to zero
for (int i = 0; i < table->columns.size(); i++) {
@@ -699,7 +694,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int ly = 0;
for (int i = 0; i < frame->lines.size(); i++) {
-
_process_line(frame, Point2(), ly, available_width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs2);
table->columns.write[column].min_width = MAX(table->columns[column].min_width, frame->lines[i].minimum_width);
table->columns.write[column].max_width = MAX(table->columns[column].max_width, frame->lines[i].maximum_width);
@@ -715,17 +709,20 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
for (int i = 0; i < table->columns.size(); i++) {
remaining_width -= table->columns[i].min_width;
- if (table->columns[i].max_width > table->columns[i].min_width)
+ if (table->columns[i].max_width > table->columns[i].min_width) {
table->columns.write[i].expand = true;
- if (table->columns[i].expand)
+ }
+ if (table->columns[i].expand) {
total_ratio += table->columns[i].expand_ratio;
+ }
}
//assign actual widths
for (int i = 0; i < table->columns.size(); i++) {
table->columns.write[i].width = table->columns[i].min_width;
- if (table->columns[i].expand && total_ratio > 0)
+ if (table->columns[i].expand && total_ratio > 0) {
table->columns.write[i].width += table->columns[i].expand_ratio * remaining_width / total_ratio;
+ }
table->total_width += table->columns[i].width + hseparation;
}
@@ -735,8 +732,9 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
table_need_fit = false;
//fit slim
for (int i = 0; i < table->columns.size(); i++) {
- if (!table->columns[i].expand)
+ if (!table->columns[i].expand) {
continue;
+ }
int dif = table->columns[i].width - table->columns[i].max_width;
if (dif > 0) {
table_need_fit = true;
@@ -771,7 +769,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int column = idx % table->columns.size();
for (int i = 0; i < frame->lines.size(); i++) {
-
int ly = 0;
_process_line(frame, Point2(), ly, table->columns[column].width, i, PROCESS_CACHE, cfont, Color(), font_color_shadow, use_outline, shadow_ofs2);
frame->lines.write[i].height_cache = ly; //actual height
@@ -799,11 +796,11 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
int lines_ofs = p_ofs.y + offset.y + draw_ofs.y;
bool visible = lines_ofs < get_size().height && lines_ofs + lines_h >= 0;
- if (visible)
+ if (visible) {
line_is_blank = false;
+ }
for (int i = 0; i < frame->lines.size(); i++) {
-
if (visible) {
if (p_mode == PROCESS_DRAW) {
nonblank_line_count += _process_line(frame, p_ofs + offset + draw_ofs + Vector2(0, yofs), ly, table->columns[column].width, i, PROCESS_DRAW, cfont, ccolor, font_color_shadow, use_outline, shadow_ofs2);
@@ -825,7 +822,6 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
offset.x += table->columns[column].width + hseparation;
if (column == table->columns.size() - 1) {
-
offset.y += row_height + vseparation;
offset.x = hseparation;
row_height = 0;
@@ -852,10 +848,11 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
it = _get_next_item(it);
if (it && (p_line + 1 < p_frame->lines.size()) && p_frame->lines[p_line + 1].from == it) {
-
if (p_mode == PROCESS_POINTER && r_click_item && p_click_pos.y >= p_ofs.y + y && p_click_pos.y <= p_ofs.y + y + lh) {
//went to next line, but pointer was on the previous one
- if (r_outside) *r_outside = true;
+ if (r_outside) {
+ *r_outside = true;
+ }
*r_click_item = itp;
*r_click_char = rchar;
RETURN;
@@ -876,14 +873,15 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
}
void RichTextLabel::_scroll_changed(double) {
-
- if (updating_scroll || !scroll_active)
+ if (updating_scroll || !scroll_active) {
return;
+ }
- if (scroll_follow && vscroll->get_value() >= (vscroll->get_max() - vscroll->get_page()))
+ if (scroll_follow && vscroll->get_value() >= (vscroll->get_max() - vscroll->get_page())) {
scroll_following = true;
- else
+ } else {
scroll_following = false;
+ }
scroll_updated = true;
@@ -891,13 +889,11 @@ void RichTextLabel::_scroll_changed(double) {
}
void RichTextLabel::_update_scroll() {
-
int total_height = get_content_height();
bool exceeds = total_height > get_size().height && scroll_active;
if (exceeds != scroll_visible) {
-
if (exceeds) {
scroll_visible = true;
scroll_w = vscroll->get_combined_minimum_size().width;
@@ -949,9 +945,7 @@ void RichTextLabel::_update_fx(RichTextLabel::ItemFrame *p_frame, float p_delta_
}
void RichTextLabel::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_MOUSE_EXIT: {
if (meta_hovering) {
meta_hovering = nullptr;
@@ -961,27 +955,24 @@ void RichTextLabel::_notification(int p_what) {
}
} break;
case NOTIFICATION_RESIZED: {
-
main->first_invalid_line = 0; //invalidate ALL
update();
} break;
case NOTIFICATION_ENTER_TREE: {
-
- if (bbcode != "")
+ if (bbcode != "") {
set_bbcode(bbcode);
+ }
main->first_invalid_line = 0; //invalidate ALL
update();
} break;
case NOTIFICATION_THEME_CHANGED: {
-
update();
} break;
case NOTIFICATION_DRAW: {
-
_validate_line_caches(main);
_update_scroll();
@@ -1005,15 +996,16 @@ void RichTextLabel::_notification(int p_what) {
int from_line = 0;
int total_chars = 0;
while (from_line < main->lines.size()) {
-
- if (main->lines[from_line].height_accum_cache + _get_text_rect().get_position().y >= ofs)
+ if (main->lines[from_line].height_accum_cache + _get_text_rect().get_position().y >= ofs) {
break;
+ }
total_chars += main->lines[from_line].char_count;
from_line++;
}
- if (from_line >= main->lines.size())
+ if (from_line >= main->lines.size()) {
break; //nothing to draw
+ }
int y = (main->lines[from_line].height_accum_cache - main->lines[from_line].height_cache) - ofs;
Ref<Font> base_font = get_theme_font("normal_font");
Color base_color = get_theme_color("default_color");
@@ -1023,7 +1015,6 @@ void RichTextLabel::_notification(int p_what) {
visible_line_count = 0;
while (y < size.height && from_line < main->lines.size()) {
-
visible_line_count += _process_line(main, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, from_line, PROCESS_DRAW, base_font, base_color, font_color_shadow, use_outline, shadow_ofs, Point2i(), nullptr, nullptr, nullptr, total_chars);
total_chars += main->lines[from_line].char_count;
@@ -1040,9 +1031,9 @@ void RichTextLabel::_notification(int p_what) {
}
void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item **r_click_item, int *r_click_char, bool *r_outside) {
-
- if (r_click_item)
+ if (r_click_item) {
*r_click_item = nullptr;
+ }
Rect2 text_rect = _get_text_rect();
int ofs = vscroll->get_value();
@@ -1054,57 +1045,61 @@ void RichTextLabel::_find_click(ItemFrame *p_frame, const Point2i &p_click, Item
int from_line = 0;
while (from_line < p_frame->lines.size()) {
-
- if (p_frame->lines[from_line].height_accum_cache >= ofs)
+ if (p_frame->lines[from_line].height_accum_cache >= ofs) {
break;
+ }
from_line++;
}
- if (from_line >= p_frame->lines.size())
+ if (from_line >= p_frame->lines.size()) {
return;
+ }
int y = (p_frame->lines[from_line].height_accum_cache - p_frame->lines[from_line].height_cache) - ofs;
Ref<Font> base_font = get_theme_font("normal_font");
Color base_color = get_theme_color("default_color");
while (y < text_rect.get_size().height && from_line < p_frame->lines.size()) {
-
_process_line(p_frame, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, from_line, PROCESS_POINTER, base_font, base_color, font_color_shadow, use_outline, shadow_ofs, p_click, r_click_item, r_click_char, r_outside);
- if (r_click_item && *r_click_item)
+ if (r_click_item && *r_click_item) {
return;
+ }
from_line++;
}
}
Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const {
-
- if (!underline_meta)
+ if (!underline_meta) {
return CURSOR_ARROW;
+ }
- if (selection.click)
+ if (selection.click) {
return CURSOR_IBEAM;
+ }
- if (main->first_invalid_line < main->lines.size())
+ if (main->first_invalid_line < main->lines.size()) {
return CURSOR_ARROW; //invalid
+ }
int line = 0;
Item *item = nullptr;
bool outside;
((RichTextLabel *)(this))->_find_click(main, p_pos, &item, &line, &outside);
- if (item && !outside && ((RichTextLabel *)(this))->_find_meta(item, nullptr))
+ if (item && !outside && ((RichTextLabel *)(this))->_find_meta(item, nullptr)) {
return CURSOR_POINTING_HAND;
+ }
return CURSOR_ARROW;
}
void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
-
Ref<InputEventMouseButton> b = p_event;
if (b.is_valid()) {
- if (main->first_invalid_line < main->lines.size())
+ if (main->first_invalid_line < main->lines.size()) {
return;
+ }
if (b->get_button_index() == BUTTON_LEFT) {
if (b->is_pressed() && !b->is_doubleclick()) {
@@ -1116,9 +1111,7 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
_find_click(main, b->get_position(), &item, &line, &outside);
if (item) {
-
if (selection.enabled) {
-
selection.click = item;
selection.click_char = line;
@@ -1135,7 +1128,6 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
}
}
} else if (b->is_pressed() && b->is_doubleclick() && selection.enabled) {
-
//doubleclick: select word
int line = 0;
Item *item = nullptr;
@@ -1144,17 +1136,14 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
_find_click(main, b->get_position(), &item, &line, &outside);
while (item && item->type != ITEM_TEXT) {
-
item = _get_next_item(item, true);
}
if (item && item->type == ITEM_TEXT) {
-
String itext = static_cast<ItemText *>(item)->text;
int beg, end;
if (select_word(itext, line, beg, end)) {
-
selection.from = item;
selection.to = item;
selection.from_char = beg;
@@ -1164,7 +1153,6 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
}
}
} else if (!b->is_pressed()) {
-
selection.click = nullptr;
if (!b->is_doubleclick() && !scroll_updated) {
@@ -1175,7 +1163,6 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
_find_click(main, b->get_position(), &item, &line, &outside);
if (item) {
-
Variant meta;
if (!outside && _find_meta(item, &meta)) {
//meta clicked
@@ -1188,21 +1175,22 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
}
if (b->get_button_index() == BUTTON_WHEEL_UP) {
- if (scroll_active)
+ if (scroll_active) {
vscroll->set_value(vscroll->get_value() - vscroll->get_page() * b->get_factor() * 0.5 / 8);
+ }
}
if (b->get_button_index() == BUTTON_WHEEL_DOWN) {
- if (scroll_active)
+ if (scroll_active) {
vscroll->set_value(vscroll->get_value() + vscroll->get_page() * b->get_factor() * 0.5 / 8);
+ }
}
}
Ref<InputEventPanGesture> pan_gesture = p_event;
if (pan_gesture.is_valid()) {
-
- if (scroll_active)
-
+ if (scroll_active) {
vscroll->set_value(vscroll->get_value() + vscroll->get_page() * pan_gesture->get_delta().y * 0.5 / 8);
+ }
return;
}
@@ -1214,42 +1202,36 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
bool handled = false;
switch (k->get_keycode()) {
case KEY_PAGEUP: {
-
if (vscroll->is_visible_in_tree()) {
vscroll->set_value(vscroll->get_value() - vscroll->get_page());
handled = true;
}
} break;
case KEY_PAGEDOWN: {
-
if (vscroll->is_visible_in_tree()) {
vscroll->set_value(vscroll->get_value() + vscroll->get_page());
handled = true;
}
} break;
case KEY_UP: {
-
if (vscroll->is_visible_in_tree()) {
vscroll->set_value(vscroll->get_value() - get_theme_font("normal_font")->get_height());
handled = true;
}
} break;
case KEY_DOWN: {
-
if (vscroll->is_visible_in_tree()) {
vscroll->set_value(vscroll->get_value() + get_theme_font("normal_font")->get_height());
handled = true;
}
} break;
case KEY_HOME: {
-
if (vscroll->is_visible_in_tree()) {
vscroll->set_value(0);
handled = true;
}
} break;
case KEY_END: {
-
if (vscroll->is_visible_in_tree()) {
vscroll->set_value(vscroll->get_max());
handled = true;
@@ -1257,7 +1239,6 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
} break;
case KEY_INSERT:
case KEY_C: {
-
if (k->get_command()) {
selection_copy();
handled = true;
@@ -1266,16 +1247,18 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
} break;
}
- if (handled)
+ if (handled) {
accept_event();
+ }
}
}
Ref<InputEventMouseMotion> m = p_event;
if (m.is_valid()) {
- if (main->first_invalid_line < main->lines.size())
+ if (main->first_invalid_line < main->lines.size()) {
return;
+ }
int line = 0;
Item *item = nullptr;
@@ -1283,9 +1266,9 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
_find_click(main, m->get_position(), &item, &line, &outside);
if (selection.click) {
-
- if (!item)
+ if (!item) {
return; // do not update
+ }
selection.from = selection.click;
selection.from_char = selection.click_char;
@@ -1294,13 +1277,12 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
selection.to_char = line;
bool swap = false;
- if (selection.from->index > selection.to->index)
+ if (selection.from->index > selection.to->index) {
swap = true;
- else if (selection.from->index == selection.to->index) {
- if (selection.from_char > selection.to_char)
+ } else if (selection.from->index == selection.to->index) {
+ if (selection.from_char > selection.to_char) {
swap = true;
- else if (selection.from_char == selection.to_char) {
-
+ } else if (selection.from_char == selection.to_char) {
selection.active = false;
return;
}
@@ -1335,13 +1317,10 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
}
Ref<Font> RichTextLabel::_find_font(Item *p_item) {
-
Item *fontitem = p_item;
while (fontitem) {
-
if (fontitem->type == ITEM_FONT) {
-
ItemFont *fi = static_cast<ItemFont *>(fontitem);
return fi->font;
}
@@ -1353,28 +1332,26 @@ Ref<Font> RichTextLabel::_find_font(Item *p_item) {
}
int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font) {
-
Item *item = p_item;
int margin = 0;
while (item) {
-
if (item->type == ITEM_INDENT) {
-
Ref<Font> font = _find_font(item);
- if (font.is_null())
+ if (font.is_null()) {
font = p_base_font;
+ }
ItemIndent *indent = static_cast<ItemIndent *>(item);
margin += indent->level * tab_size * font->get_char_size(' ').width;
} else if (item->type == ITEM_LIST) {
-
Ref<Font> font = _find_font(item);
- if (font.is_null())
+ if (font.is_null()) {
font = p_base_font;
+ }
}
item = item->parent;
@@ -1384,13 +1361,10 @@ int RichTextLabel::_find_margin(Item *p_item, const Ref<Font> &p_base_font) {
}
RichTextLabel::Align RichTextLabel::_find_align(Item *p_item) {
-
Item *item = p_item;
while (item) {
-
if (item->type == ITEM_ALIGN) {
-
ItemAlign *align = static_cast<ItemAlign *>(item);
return align->align;
}
@@ -1402,13 +1376,10 @@ RichTextLabel::Align RichTextLabel::_find_align(Item *p_item) {
}
Color RichTextLabel::_find_color(Item *p_item, const Color &p_default_color) {
-
Item *item = p_item;
while (item) {
-
if (item->type == ITEM_COLOR) {
-
ItemColor *color = static_cast<ItemColor *>(item);
return color->color;
}
@@ -1420,13 +1391,10 @@ Color RichTextLabel::_find_color(Item *p_item, const Color &p_default_color) {
}
bool RichTextLabel::_find_underline(Item *p_item) {
-
Item *item = p_item;
while (item) {
-
if (item->type == ITEM_UNDERLINE) {
-
return true;
}
@@ -1437,13 +1405,10 @@ bool RichTextLabel::_find_underline(Item *p_item) {
}
bool RichTextLabel::_find_strikethrough(Item *p_item) {
-
Item *item = p_item;
while (item) {
-
if (item->type == ITEM_STRIKETHROUGH) {
-
return true;
}
@@ -1454,7 +1419,6 @@ bool RichTextLabel::_find_strikethrough(Item *p_item) {
}
bool RichTextLabel::_find_by_type(Item *p_item, ItemType p_type) {
-
ERR_FAIL_INDEX_V((int)p_type, 19, false);
Item *item = p_item;
@@ -1483,14 +1447,14 @@ bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item)
Item *item = p_item;
while (item) {
-
if (item->type == ITEM_META) {
-
ItemMeta *meta = static_cast<ItemMeta *>(item);
- if (r_meta)
+ if (r_meta) {
*r_meta = meta->meta;
- if (r_item)
+ }
+ if (r_item) {
*r_item = meta;
+ }
return true;
}
@@ -1501,16 +1465,17 @@ bool RichTextLabel::_find_meta(Item *p_item, Variant *r_meta, ItemMeta **r_item)
}
bool RichTextLabel::_find_layout_subitem(Item *from, Item *to) {
-
if (from && from != to) {
- if (from->type != ITEM_FONT && from->type != ITEM_COLOR && from->type != ITEM_UNDERLINE && from->type != ITEM_STRIKETHROUGH)
+ if (from->type != ITEM_FONT && from->type != ITEM_COLOR && from->type != ITEM_UNDERLINE && from->type != ITEM_STRIKETHROUGH) {
return true;
+ }
for (List<Item *>::Element *E = from->subitems.front(); E; E = E->next()) {
bool layout = _find_layout_subitem(E->get(), to);
- if (layout)
+ if (layout) {
return true;
+ }
}
}
@@ -1518,9 +1483,9 @@ bool RichTextLabel::_find_layout_subitem(Item *from, Item *to) {
}
void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
-
- if (p_frame->first_invalid_line == p_frame->lines.size())
+ if (p_frame->first_invalid_line == p_frame->lines.size()) {
return;
+ }
//validate invalid lines
Size2 size = get_size();
@@ -1535,67 +1500,64 @@ void RichTextLabel::_validate_line_caches(ItemFrame *p_frame) {
Ref<Font> base_font = get_theme_font("normal_font");
for (int i = p_frame->first_invalid_line; i < p_frame->lines.size(); i++) {
-
int y = 0;
_process_line(p_frame, text_rect.get_position(), y, text_rect.get_size().width - scroll_w, i, PROCESS_CACHE, base_font, Color(), font_color_shadow, use_outline, shadow_ofs);
p_frame->lines.write[i].height_cache = y;
p_frame->lines.write[i].height_accum_cache = y;
- if (i > 0)
+ if (i > 0) {
p_frame->lines.write[i].height_accum_cache += p_frame->lines[i - 1].height_accum_cache;
+ }
}
int total_height = 0;
- if (p_frame->lines.size())
+ if (p_frame->lines.size()) {
total_height = p_frame->lines[p_frame->lines.size() - 1].height_accum_cache + get_theme_stylebox("normal")->get_minimum_size().height;
+ }
main->first_invalid_line = p_frame->lines.size();
updating_scroll = true;
vscroll->set_max(total_height);
vscroll->set_page(size.height);
- if (scroll_follow && scroll_following)
+ if (scroll_follow && scroll_following) {
vscroll->set_value(total_height - size.height);
+ }
updating_scroll = false;
}
void RichTextLabel::_invalidate_current_line(ItemFrame *p_frame) {
-
if (p_frame->lines.size() - 1 <= p_frame->first_invalid_line) {
-
p_frame->first_invalid_line = p_frame->lines.size() - 1;
update();
}
}
void RichTextLabel::add_text(const String &p_text) {
-
- if (current->type == ITEM_TABLE)
+ if (current->type == ITEM_TABLE) {
return; //can't add anything here
+ }
int pos = 0;
while (pos < p_text.length()) {
-
int end = p_text.find("\n", pos);
String line;
bool eol = false;
if (end == -1) {
-
end = p_text.length();
} else {
-
eol = true;
}
- if (pos == 0 && end == p_text.length())
+ if (pos == 0 && end == p_text.length()) {
line = p_text;
- else
+ } else {
line = p_text.substr(pos, end - pos);
+ }
if (line.length() > 0) {
-
if (current->subitems.size() && current->subitems.back()->get()->type == ITEM_TEXT) {
//append text condition!
ItemText *ti = static_cast<ItemText *>(current->subitems.back()->get());
@@ -1611,13 +1573,13 @@ void RichTextLabel::add_text(const String &p_text) {
}
if (eol) {
-
ItemNewline *item = memnew(ItemNewline);
item->line = current_frame->lines.size();
_add_item(item, false);
current_frame->lines.resize(current_frame->lines.size() + 1);
- if (item->type != ITEM_NEWLINE)
+ if (item->type != ITEM_NEWLINE) {
current_frame->lines.write[current_frame->lines.size() - 1].from = item;
+ }
_invalidate_current_line(current_frame);
}
@@ -1626,13 +1588,13 @@ void RichTextLabel::add_text(const String &p_text) {
}
void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline) {
-
p_item->parent = current;
p_item->E = current->subitems.push_back(p_item);
p_item->index = current_idx++;
- if (p_enter)
+ if (p_enter) {
current = p_item;
+ }
if (p_ensure_newline) {
Item *from = current_frame->lines[current_frame->lines.size() - 1].from;
@@ -1656,15 +1618,15 @@ void RichTextLabel::_add_item(Item *p_item, bool p_enter, bool p_ensure_newline)
}
void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_subitem_line) {
-
int size = p_item->subitems.size();
if (size == 0) {
p_item->parent->subitems.erase(p_item);
if (p_item->type == ITEM_NEWLINE) {
current_frame->lines.remove(p_line);
for (int i = p_subitem_line; i < current->subitems.size(); i++) {
- if (current->subitems[i]->line > 0)
+ if (current->subitems[i]->line > 0) {
current->subitems[i]->line--;
+ }
}
}
} else {
@@ -1675,9 +1637,9 @@ void RichTextLabel::_remove_item(Item *p_item, const int p_line, const int p_sub
}
void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width, const int p_height) {
-
- if (current->type == ITEM_TABLE)
+ if (current->type == ITEM_TABLE) {
return;
+ }
ERR_FAIL_COND(p_image.is_null());
ItemImage *item = memnew(ItemImage);
@@ -1711,9 +1673,9 @@ void RichTextLabel::add_image(const Ref<Texture2D> &p_image, const int p_width,
}
void RichTextLabel::add_newline() {
-
- if (current->type == ITEM_TABLE)
+ if (current->type == ITEM_TABLE) {
return;
+ }
ItemNewline *item = memnew(ItemNewline);
item->line = current_frame->lines.size();
_add_item(item, false);
@@ -1722,9 +1684,9 @@ void RichTextLabel::add_newline() {
}
bool RichTextLabel::remove_line(const int p_line) {
-
- if (p_line >= current_frame->lines.size() || p_line < 0)
+ if (p_line >= current_frame->lines.size() || p_line < 0) {
return false;
+ }
int i = 0;
while (i < current->subitems.size() && current->subitems[i]->line < p_line) {
@@ -1735,8 +1697,9 @@ bool RichTextLabel::remove_line(const int p_line) {
while (i < current->subitems.size()) {
was_newline = current->subitems[i]->type == ITEM_NEWLINE;
_remove_item(current->subitems[i], current->subitems[i]->line, p_line);
- if (was_newline)
+ if (was_newline) {
break;
+ }
}
if (!was_newline) {
@@ -1746,8 +1709,9 @@ bool RichTextLabel::remove_line(const int p_line) {
}
}
- if (p_line == 0 && current->subitems.size() > 0)
+ if (p_line == 0 && current->subitems.size() > 0) {
main->lines.write[0].from = main;
+ }
main->first_invalid_line = 0;
@@ -1755,7 +1719,6 @@ bool RichTextLabel::remove_line(const int p_line) {
}
void RichTextLabel::push_font(const Ref<Font> &p_font) {
-
ERR_FAIL_COND(current->type == ITEM_TABLE);
ERR_FAIL_COND(p_font.is_null());
ItemFont *item = memnew(ItemFont);
@@ -1800,7 +1763,6 @@ void RichTextLabel::push_mono() {
}
void RichTextLabel::push_color(const Color &p_color) {
-
ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemColor *item = memnew(ItemColor);
@@ -1809,7 +1771,6 @@ void RichTextLabel::push_color(const Color &p_color) {
}
void RichTextLabel::push_underline() {
-
ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemUnderline *item = memnew(ItemUnderline);
@@ -1817,7 +1778,6 @@ void RichTextLabel::push_underline() {
}
void RichTextLabel::push_strikethrough() {
-
ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemStrikethrough *item = memnew(ItemStrikethrough);
@@ -1825,7 +1785,6 @@ void RichTextLabel::push_strikethrough() {
}
void RichTextLabel::push_align(Align p_align) {
-
ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemAlign *item = memnew(ItemAlign);
@@ -1834,7 +1793,6 @@ void RichTextLabel::push_align(Align p_align) {
}
void RichTextLabel::push_indent(int p_level) {
-
ERR_FAIL_COND(current->type == ITEM_TABLE);
ERR_FAIL_COND(p_level < 0);
@@ -1844,7 +1802,6 @@ void RichTextLabel::push_indent(int p_level) {
}
void RichTextLabel::push_list(ListType p_list) {
-
ERR_FAIL_COND(current->type == ITEM_TABLE);
ERR_FAIL_INDEX(p_list, 3);
@@ -1855,7 +1812,6 @@ void RichTextLabel::push_list(ListType p_list) {
}
void RichTextLabel::push_meta(const Variant &p_meta) {
-
ERR_FAIL_COND(current->type == ITEM_TABLE);
ItemMeta *item = memnew(ItemMeta);
@@ -1864,7 +1820,6 @@ void RichTextLabel::push_meta(const Variant &p_meta) {
}
void RichTextLabel::push_table(int p_columns) {
-
ERR_FAIL_COND(p_columns < 1);
ItemTable *item = memnew(ItemTable);
@@ -1921,7 +1876,6 @@ void RichTextLabel::push_customfx(Ref<RichTextEffect> p_custom_effect, Dictionar
}
void RichTextLabel::set_table_column_expand(int p_column, bool p_expand, int p_ratio) {
-
ERR_FAIL_COND(current->type != ITEM_TABLE);
ItemTable *table = static_cast<ItemTable *>(current);
ERR_FAIL_INDEX(p_column, table->columns.size());
@@ -1930,7 +1884,6 @@ void RichTextLabel::set_table_column_expand(int p_column, bool p_expand, int p_r
}
void RichTextLabel::push_cell() {
-
ERR_FAIL_COND(current->type != ITEM_TABLE);
ItemFrame *item = memnew(ItemFrame);
@@ -1945,7 +1898,6 @@ void RichTextLabel::push_cell() {
}
int RichTextLabel::get_current_table_column() const {
-
ERR_FAIL_COND_V(current->type != ITEM_TABLE, -1);
ItemTable *table = static_cast<ItemTable *>(current);
@@ -1954,7 +1906,6 @@ int RichTextLabel::get_current_table_column() const {
}
void RichTextLabel::pop() {
-
ERR_FAIL_COND(!current->parent);
if (current->type == ITEM_FRAME) {
current_frame = static_cast<ItemFrame *>(current)->parent_frame;
@@ -1963,7 +1914,6 @@ void RichTextLabel::pop() {
}
void RichTextLabel::clear() {
-
main->_clear_children();
current = main;
current_frame = main;
@@ -1981,77 +1931,66 @@ void RichTextLabel::clear() {
}
void RichTextLabel::set_tab_size(int p_spaces) {
-
tab_size = p_spaces;
main->first_invalid_line = 0;
update();
}
int RichTextLabel::get_tab_size() const {
-
return tab_size;
}
void RichTextLabel::set_meta_underline(bool p_underline) {
-
underline_meta = p_underline;
update();
}
bool RichTextLabel::is_meta_underlined() const {
-
return underline_meta;
}
void RichTextLabel::set_override_selected_font_color(bool p_override_selected_font_color) {
-
override_selected_font_color = p_override_selected_font_color;
}
bool RichTextLabel::is_overriding_selected_font_color() const {
-
return override_selected_font_color;
}
void RichTextLabel::set_offset(int p_pixel) {
-
vscroll->set_value(p_pixel);
}
void RichTextLabel::set_scroll_active(bool p_active) {
-
- if (scroll_active == p_active)
+ if (scroll_active == p_active) {
return;
+ }
scroll_active = p_active;
update();
}
bool RichTextLabel::is_scroll_active() const {
-
return scroll_active;
}
void RichTextLabel::set_scroll_follow(bool p_follow) {
-
scroll_follow = p_follow;
- if (!vscroll->is_visible_in_tree() || vscroll->get_value() >= (vscroll->get_max() - vscroll->get_page()))
+ if (!vscroll->is_visible_in_tree() || vscroll->get_value() >= (vscroll->get_max() - vscroll->get_page())) {
scroll_following = true;
+ }
}
bool RichTextLabel::is_scroll_following() const {
-
return scroll_follow;
}
Error RichTextLabel::parse_bbcode(const String &p_bbcode) {
-
clear();
return append_bbcode(p_bbcode);
}
Error RichTextLabel::append_bbcode(const String &p_bbcode) {
-
int pos = 0;
List<String> tag_stack;
@@ -2071,18 +2010,19 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
set_process_internal(false);
while (pos < p_bbcode.length()) {
-
int brk_pos = p_bbcode.find("[", pos);
- if (brk_pos < 0)
+ if (brk_pos < 0) {
brk_pos = p_bbcode.length();
+ }
if (brk_pos > pos) {
add_text(p_bbcode.substr(pos, brk_pos - pos));
}
- if (brk_pos == p_bbcode.length())
+ if (brk_pos == p_bbcode.length()) {
break; //nothing else to add
+ }
int brk_end = p_bbcode.find("]", brk_pos + 1);
@@ -2093,16 +2033,20 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
}
String tag = p_bbcode.substr(brk_pos + 1, brk_end - brk_pos - 1);
+ Vector<String> split_tag_block = tag.split(" ", false);
+ String bbcode = !split_tag_block.empty() ? split_tag_block[0] : "";
if (tag.begins_with("/") && tag_stack.size()) {
-
bool tag_ok = tag_stack.size() && tag_stack.front()->get() == tag.substr(1, tag.length());
- if (tag_stack.front()->get() == "b")
+ if (tag_stack.front()->get() == "b") {
in_bold = false;
- if (tag_stack.front()->get() == "i")
+ }
+ if (tag_stack.front()->get() == "i") {
in_italics = false;
- if (tag_stack.front()->get() == "indent")
+ }
+ if (tag_stack.front()->get() == "indent") {
indent_level--;
+ }
if (!tag_ok) {
add_text("[" + tag);
@@ -2112,108 +2056,99 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
tag_stack.pop_front();
pos = brk_end + 1;
- if (tag != "/img")
+ if (tag != "/img") {
pop();
+ }
} else if (tag == "b") {
-
//use bold font
in_bold = true;
- if (in_italics)
+ if (in_italics) {
push_font(bold_italics_font);
- else
+ } else {
push_font(bold_font);
+ }
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "i") {
-
//use italics font
in_italics = true;
- if (in_bold)
+ if (in_bold) {
push_font(bold_italics_font);
- else
+ } else {
push_font(italics_font);
+ }
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "code") {
-
//use monospace font
push_font(mono_font);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag.begins_with("table=")) {
-
int columns = tag.substr(6, tag.length()).to_int();
- if (columns < 1)
+ if (columns < 1) {
columns = 1;
+ }
push_table(columns);
pos = brk_end + 1;
tag_stack.push_front("table");
} else if (tag == "cell") {
-
push_cell();
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag.begins_with("cell=")) {
-
int ratio = tag.substr(5, tag.length()).to_int();
- if (ratio < 1)
+ if (ratio < 1) {
ratio = 1;
+ }
set_table_column_expand(get_current_table_column(), true, ratio);
push_cell();
pos = brk_end + 1;
tag_stack.push_front("cell");
} else if (tag == "u") {
-
//use underline
push_underline();
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "s") {
-
//use strikethrough
push_strikethrough();
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "center") {
-
push_align(ALIGN_CENTER);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "fill") {
-
push_align(ALIGN_FILL);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "right") {
-
push_align(ALIGN_RIGHT);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "ul") {
-
push_list(LIST_DOTS);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "ol") {
-
push_list(LIST_NUMBERS);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "indent") {
-
indent_level++;
push_indent(indent_level);
pos = brk_end + 1;
tag_stack.push_front(tag);
} else if (tag == "url") {
-
int end = p_bbcode.find("[", brk_end);
- if (end == -1)
+ if (end == -1) {
end = p_bbcode.length();
+ }
String url = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
push_meta(url);
@@ -2221,27 +2156,26 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
tag_stack.push_front(tag);
} else if (tag.begins_with("url=")) {
-
String url = tag.substr(4, tag.length());
push_meta(url);
pos = brk_end + 1;
tag_stack.push_front("url");
} else if (tag == "img") {
-
int end = p_bbcode.find("[", brk_end);
- if (end == -1)
+ if (end == -1) {
end = p_bbcode.length();
+ }
String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
Ref<Texture2D> texture = ResourceLoader::load(image, "Texture2D");
- if (texture.is_valid())
+ if (texture.is_valid()) {
add_image(texture);
+ }
pos = end;
tag_stack.push_front(tag);
} else if (tag.begins_with("img=")) {
-
int width = 0;
int height = 0;
@@ -2255,85 +2189,86 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
}
int end = p_bbcode.find("[", brk_end);
- if (end == -1)
+ if (end == -1) {
end = p_bbcode.length();
+ }
String image = p_bbcode.substr(brk_end + 1, end - brk_end - 1);
Ref<Texture2D> texture = ResourceLoader::load(image, "Texture");
- if (texture.is_valid())
+ if (texture.is_valid()) {
add_image(texture, width, height);
+ }
pos = end;
tag_stack.push_front("img");
} else if (tag.begins_with("color=")) {
-
String col = tag.substr(6, tag.length());
Color color;
- if (col.begins_with("#"))
+ if (col.begins_with("#")) {
color = Color::html(col);
- else if (col == "aqua")
+ } else if (col == "aqua") {
color = Color(0, 1, 1);
- else if (col == "black")
+ } else if (col == "black") {
color = Color(0, 0, 0);
- else if (col == "blue")
+ } else if (col == "blue") {
color = Color(0, 0, 1);
- else if (col == "fuchsia")
+ } else if (col == "fuchsia") {
color = Color(1, 0, 1);
- else if (col == "gray" || col == "grey")
+ } else if (col == "gray" || col == "grey") {
color = Color(0.5, 0.5, 0.5);
- else if (col == "green")
+ } else if (col == "green") {
color = Color(0, 0.5, 0);
- else if (col == "lime")
+ } else if (col == "lime") {
color = Color(0, 1, 0);
- else if (col == "maroon")
+ } else if (col == "maroon") {
color = Color(0.5, 0, 0);
- else if (col == "navy")
+ } else if (col == "navy") {
color = Color(0, 0, 0.5);
- else if (col == "olive")
+ } else if (col == "olive") {
color = Color(0.5, 0.5, 0);
- else if (col == "purple")
+ } else if (col == "purple") {
color = Color(0.5, 0, 0.5);
- else if (col == "red")
+ } else if (col == "red") {
color = Color(1, 0, 0);
- else if (col == "silver")
+ } else if (col == "silver") {
color = Color(0.75, 0.75, 0.75);
- else if (col == "teal")
+ } else if (col == "teal") {
color = Color(0, 0.5, 0.5);
- else if (col == "white")
+ } else if (col == "white") {
color = Color(1, 1, 1);
- else if (col == "yellow")
+ } else if (col == "yellow") {
color = Color(1, 1, 0);
- else
+ } else {
color = base_color;
+ }
push_color(color);
pos = brk_end + 1;
tag_stack.push_front("color");
} else if (tag.begins_with("font=")) {
-
String fnt = tag.substr(5, tag.length());
Ref<Font> font = ResourceLoader::load(fnt, "Font");
- if (font.is_valid())
+ if (font.is_valid()) {
push_font(font);
- else
+ } else {
push_font(normal_font);
+ }
pos = brk_end + 1;
tag_stack.push_front("font");
- } else if (tag.begins_with("fade")) {
- Vector<String> tags = tag.split(" ", false);
+ } else if (bbcode == "fade") {
int startIndex = 0;
int length = 10;
- if (tags.size() > 1) {
- tags.remove(0);
- for (int i = 0; i < tags.size(); i++) {
- String expr = tags[i];
+ if (split_tag_block.size() > 1) {
+ split_tag_block.remove(0);
+ for (int i = 0; i < split_tag_block.size(); i++) {
+ String expr = split_tag_block[i];
if (expr.begins_with("start=")) {
String start_str = expr.substr(6, expr.length());
startIndex = start_str.to_int();
@@ -2347,15 +2282,14 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
push_fade(startIndex, length);
pos = brk_end + 1;
tag_stack.push_front("fade");
- } else if (tag.begins_with("shake")) {
- Vector<String> tags = tag.split(" ", false);
+ } else if (bbcode == "shake") {
int strength = 5;
float rate = 20.0f;
- if (tags.size() > 1) {
- tags.remove(0);
- for (int i = 0; i < tags.size(); i++) {
- String expr = tags[i];
+ if (split_tag_block.size() > 1) {
+ split_tag_block.remove(0);
+ for (int i = 0; i < split_tag_block.size(); i++) {
+ String expr = split_tag_block[i];
if (expr.begins_with("level=")) {
String str_str = expr.substr(6, expr.length());
strength = str_str.to_int();
@@ -2370,15 +2304,14 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
pos = brk_end + 1;
tag_stack.push_front("shake");
set_process_internal(true);
- } else if (tag.begins_with("wave")) {
- Vector<String> tags = tag.split(" ", false);
+ } else if (bbcode == "wave") {
float amplitude = 20.0f;
float period = 5.0f;
- if (tags.size() > 1) {
- tags.remove(0);
- for (int i = 0; i < tags.size(); i++) {
- String expr = tags[i];
+ if (split_tag_block.size() > 1) {
+ split_tag_block.remove(0);
+ for (int i = 0; i < split_tag_block.size(); i++) {
+ String expr = split_tag_block[i];
if (expr.begins_with("amp=")) {
String amp_str = expr.substr(4, expr.length());
amplitude = amp_str.to_float();
@@ -2393,15 +2326,14 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
pos = brk_end + 1;
tag_stack.push_front("wave");
set_process_internal(true);
- } else if (tag.begins_with("tornado")) {
- Vector<String> tags = tag.split(" ", false);
+ } else if (bbcode == "tornado") {
float radius = 10.0f;
float frequency = 1.0f;
- if (tags.size() > 1) {
- tags.remove(0);
- for (int i = 0; i < tags.size(); i++) {
- String expr = tags[i];
+ if (split_tag_block.size() > 1) {
+ split_tag_block.remove(0);
+ for (int i = 0; i < split_tag_block.size(); i++) {
+ String expr = split_tag_block[i];
if (expr.begins_with("radius=")) {
String amp_str = expr.substr(7, expr.length());
radius = amp_str.to_float();
@@ -2416,16 +2348,15 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
pos = brk_end + 1;
tag_stack.push_front("tornado");
set_process_internal(true);
- } else if (tag.begins_with("rainbow")) {
- Vector<String> tags = tag.split(" ", false);
+ } else if (bbcode == "rainbow") {
float saturation = 0.8f;
float value = 0.8f;
float frequency = 1.0f;
- if (tags.size() > 1) {
- tags.remove(0);
- for (int i = 0; i < tags.size(); i++) {
- String expr = tags[i];
+ if (split_tag_block.size() > 1) {
+ split_tag_block.remove(0);
+ for (int i = 0; i < split_tag_block.size(); i++) {
+ String expr = split_tag_block[i];
if (expr.begins_with("sat=")) {
String sat_str = expr.substr(4, expr.length());
saturation = sat_str.to_float();
@@ -2444,7 +2375,7 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
tag_stack.push_front("rainbow");
set_process_internal(true);
} else {
- Vector<String> expr = tag.split(" ", false);
+ Vector<String> &expr = split_tag_block;
if (expr.size() < 1) {
add_text("[");
pos = brk_pos + 1;
@@ -2471,25 +2402,23 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) {
}
void RichTextLabel::scroll_to_line(int p_line) {
-
ERR_FAIL_INDEX(p_line, main->lines.size());
_validate_line_caches(main);
vscroll->set_value(main->lines[p_line].height_accum_cache - main->lines[p_line].height_cache);
}
int RichTextLabel::get_line_count() const {
-
return current_frame->lines.size();
}
int RichTextLabel::get_visible_line_count() const {
- if (!is_visible())
+ if (!is_visible()) {
return 0;
+ }
return visible_line_count;
}
void RichTextLabel::set_selection_enabled(bool p_enabled) {
-
selection.enabled = p_enabled;
if (!p_enabled) {
if (selection.active) {
@@ -2503,7 +2432,6 @@ void RichTextLabel::set_selection_enabled(bool p_enabled) {
}
bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p_search_previous) {
-
ERR_FAIL_COND_V(!selection.enabled, false);
Item *it = main;
int charidx = 0;
@@ -2514,9 +2442,7 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
}
while (it) {
-
if (it->type == ITEM_TEXT) {
-
ItemText *t = static_cast<ItemText *>(it);
int sp = t->text.findn(p_string, charidx);
if (sp != -1) {
@@ -2551,10 +2477,11 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
}
}
- if (p_search_previous)
+ if (p_search_previous) {
it = _get_prev_item(it, true);
- else
+ } else {
it = _get_next_item(it, true);
+ }
charidx = 0;
}
@@ -2562,18 +2489,16 @@ bool RichTextLabel::search(const String &p_string, bool p_from_selection, bool p
}
void RichTextLabel::selection_copy() {
-
- if (!selection.active || !selection.enabled)
+ if (!selection.active || !selection.enabled) {
return;
+ }
String text;
RichTextLabel::Item *item = selection.from;
while (item) {
-
if (item->type == ITEM_TEXT) {
-
String itext = static_cast<ItemText *>(item)->text;
if (item == selection.from && item == selection.to) {
text += itext.substr(selection.from_char, selection.to_char - selection.from_char + 1);
@@ -2588,8 +2513,9 @@ void RichTextLabel::selection_copy() {
} else if (item->type == ITEM_NEWLINE) {
text += "\n";
}
- if (item == selection.to)
+ if (item == selection.to) {
break;
+ }
item = _get_next_item(item, true);
}
@@ -2600,34 +2526,32 @@ void RichTextLabel::selection_copy() {
}
bool RichTextLabel::is_selection_enabled() const {
-
return selection.enabled;
}
void RichTextLabel::set_bbcode(const String &p_bbcode) {
bbcode = p_bbcode;
- if (is_inside_tree() && use_bbcode)
+ if (is_inside_tree() && use_bbcode) {
parse_bbcode(p_bbcode);
- else { // raw text
+ } else { // raw text
clear();
add_text(p_bbcode);
}
}
String RichTextLabel::get_bbcode() const {
-
return bbcode;
}
void RichTextLabel::set_use_bbcode(bool p_enable) {
- if (use_bbcode == p_enable)
+ if (use_bbcode == p_enable) {
return;
+ }
use_bbcode = p_enable;
set_bbcode(bbcode);
}
bool RichTextLabel::is_using_bbcode() const {
-
return use_bbcode;
}
@@ -2654,14 +2578,11 @@ void RichTextLabel::set_text(const String &p_string) {
}
void RichTextLabel::set_percent_visible(float p_percent) {
-
if (p_percent < 0 || p_percent >= 1) {
-
visible_characters = -1;
percent_visible = 1;
} else {
-
visible_characters = get_total_character_count() * p_percent;
percent_visible = p_percent;
}
@@ -2702,13 +2623,13 @@ void RichTextLabel::install_effect(const Variant effect) {
int RichTextLabel::get_content_height() {
int total_height = 0;
- if (main->lines.size())
+ if (main->lines.size()) {
total_height = main->lines[main->lines.size() - 1].height_accum_cache + get_theme_stylebox("normal")->get_minimum_size().height;
+ }
return total_height;
}
void RichTextLabel::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &RichTextLabel::_gui_input);
ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text);
ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text);
@@ -2847,11 +2768,12 @@ void RichTextLabel::set_visible_characters(int p_visible) {
int RichTextLabel::get_visible_characters() const {
return visible_characters;
}
-int RichTextLabel::get_total_character_count() const {
+int RichTextLabel::get_total_character_count() const {
int tc = 0;
- for (int i = 0; i < current_frame->lines.size(); i++)
+ for (int i = 0; i < current_frame->lines.size(); i++) {
tc += current_frame->lines[i].char_count;
+ }
return tc;
}
@@ -2862,7 +2784,6 @@ void RichTextLabel::set_fixed_size_to_width(int p_width) {
}
Size2 RichTextLabel::get_minimum_size() const {
-
if (fixed_width != -1) {
const_cast<RichTextLabel *>(this)->_validate_line_caches(main);
return Size2(fixed_width, const_cast<RichTextLabel *>(this)->get_content_height());
@@ -2873,8 +2794,9 @@ Size2 RichTextLabel::get_minimum_size() const {
Ref<RichTextEffect> RichTextLabel::_get_custom_effect_by_code(String p_bbcode_identifier) {
for (int i = 0; i < custom_effects.size(); i++) {
- if (!custom_effects[i].is_valid())
+ if (!custom_effects[i].is_valid()) {
continue;
+ }
if (custom_effects[i]->get_bbcode() == p_bbcode_identifier) {
return custom_effects[i];
@@ -2944,7 +2866,6 @@ Dictionary RichTextLabel::parse_expressions_for_values(Vector<String> p_expressi
}
RichTextLabel::RichTextLabel() {
-
main = memnew(ItemFrame);
main->index = 0;
current = main;
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 7f2b5facb9..019edf5d45 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -35,7 +35,6 @@
#include "scene/gui/scroll_bar.h"
class RichTextLabel : public Control {
-
GDCLASS(RichTextLabel, Control);
public:
@@ -84,7 +83,6 @@ private:
struct Item;
struct Line {
-
Item *from;
Vector<int> offset_caches;
Vector<int> height_caches;
@@ -352,7 +350,6 @@ private:
};
struct Selection {
-
Item *click;
int click_char;
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index 1c63c25e28..e7950bec98 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -38,12 +38,10 @@
bool ScrollBar::focus_by_default = false;
void ScrollBar::set_can_focus_by_default(bool p_can_focus) {
-
focus_by_default = p_can_focus;
}
void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
-
Ref<InputEventMouseMotion> m = p_event;
if (!m.is_valid() || drag.active) {
emit_signal("scrolling");
@@ -55,22 +53,20 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
accept_event();
if (b->get_button_index() == BUTTON_WHEEL_DOWN && b->is_pressed()) {
-
set_value(get_value() + get_page() / 4.0);
accept_event();
}
if (b->get_button_index() == BUTTON_WHEEL_UP && b->is_pressed()) {
-
set_value(get_value() - get_page() / 4.0);
accept_event();
}
- if (b->get_button_index() != BUTTON_LEFT)
+ if (b->get_button_index() != BUTTON_LEFT) {
return;
+ }
if (b->is_pressed()) {
-
double ofs = orientation == VERTICAL ? b->get_position().y : b->get_position().x;
Ref<Texture2D> decr = get_theme_icon("decrement");
Ref<Texture2D> incr = get_theme_icon("increment");
@@ -82,13 +78,11 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
double total = orientation == VERTICAL ? get_size().height : get_size().width;
if (ofs < decr_size) {
-
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
return;
}
if (ofs > total - incr_size) {
-
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
return;
}
@@ -96,7 +90,6 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
ofs -= decr_size;
if (ofs < grabber_ofs) {
-
if (scrolling) {
target_scroll = CLAMP(target_scroll - get_page(), get_min(), get_max() - get_page());
} else {
@@ -115,7 +108,6 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
ofs -= grabber_ofs;
if (ofs < grabber_size) {
-
drag.active = true;
drag.pos_at_click = grabber_ofs + ofs;
drag.value_at_click = get_as_ratio();
@@ -136,18 +128,15 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
}
} else {
-
drag.active = false;
update();
}
}
if (m.is_valid()) {
-
accept_event();
if (drag.active) {
-
double ofs = orientation == VERTICAL ? m->get_position().y : m->get_position().x;
Ref<Texture2D> decr = get_theme_icon("decrement");
@@ -158,7 +147,6 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
set_as_ratio(drag.value_at_click + diff);
} else {
-
double ofs = orientation == VERTICAL ? m->get_position().y : m->get_position().x;
Ref<Texture2D> decr = get_theme_icon("decrement");
Ref<Texture2D> incr = get_theme_icon("increment");
@@ -170,20 +158,16 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
HighlightStatus new_hilite;
if (ofs < decr_size) {
-
new_hilite = HIGHLIGHT_DECR;
} else if (ofs > total - incr_size) {
-
new_hilite = HIGHLIGHT_INCR;
} else {
-
new_hilite = HIGHLIGHT_RANGE;
}
if (new_hilite != highlight) {
-
highlight = new_hilite;
update();
}
@@ -191,47 +175,42 @@ void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
}
if (p_event->is_pressed()) {
-
if (p_event->is_action("ui_left")) {
-
- if (orientation != HORIZONTAL)
+ if (orientation != HORIZONTAL) {
return;
+ }
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
} else if (p_event->is_action("ui_right")) {
-
- if (orientation != HORIZONTAL)
+ if (orientation != HORIZONTAL) {
return;
+ }
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
} else if (p_event->is_action("ui_up")) {
-
- if (orientation != VERTICAL)
+ if (orientation != VERTICAL) {
return;
+ }
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
} else if (p_event->is_action("ui_down")) {
-
- if (orientation != VERTICAL)
+ if (orientation != VERTICAL) {
return;
+ }
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
} else if (p_event->is_action("ui_home")) {
-
set_value(get_min());
} else if (p_event->is_action("ui_end")) {
-
set_value(get_max());
}
}
}
void ScrollBar::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
-
RID ci = get_canvas_item();
Ref<Texture2D> decr = highlight == HIGHLIGHT_DECR ? get_theme_icon("decrement_highlight") : get_theme_icon("decrement");
@@ -239,47 +218,49 @@ void ScrollBar::_notification(int p_what) {
Ref<StyleBox> bg = has_focus() ? get_theme_stylebox("scroll_focus") : get_theme_stylebox("scroll");
Ref<StyleBox> grabber;
- if (drag.active)
+ if (drag.active) {
grabber = get_theme_stylebox("grabber_pressed");
- else if (highlight == HIGHLIGHT_RANGE)
+ } else if (highlight == HIGHLIGHT_RANGE) {
grabber = get_theme_stylebox("grabber_highlight");
- else
+ } else {
grabber = get_theme_stylebox("grabber");
+ }
Point2 ofs;
decr->draw(ci, Point2());
- if (orientation == HORIZONTAL)
+ if (orientation == HORIZONTAL) {
ofs.x += decr->get_width();
- else
+ } else {
ofs.y += decr->get_height();
+ }
Size2 area = get_size();
- if (orientation == HORIZONTAL)
+ if (orientation == HORIZONTAL) {
area.width -= incr->get_width() + decr->get_width();
- else
+ } else {
area.height -= incr->get_height() + decr->get_height();
+ }
bg->draw(ci, Rect2(ofs, area));
- if (orientation == HORIZONTAL)
+ if (orientation == HORIZONTAL) {
ofs.width += area.width;
- else
+ } else {
ofs.height += area.height;
+ }
incr->draw(ci, ofs);
Rect2 grabber_rect;
if (orientation == HORIZONTAL) {
-
grabber_rect.size.width = get_grabber_size();
grabber_rect.size.height = get_size().height;
grabber_rect.position.y = 0;
grabber_rect.position.x = get_grabber_offset() + decr->get_width() + bg->get_margin(MARGIN_LEFT);
} else {
-
grabber_rect.size.width = get_size().width;
grabber_rect.size.height = get_grabber_size();
grabber_rect.position.y = get_grabber_offset() + decr->get_height() + bg->get_margin(MARGIN_TOP);
@@ -290,7 +271,6 @@ void ScrollBar::_notification(int p_what) {
}
if (p_what == NOTIFICATION_ENTER_TREE) {
-
if (has_node(drag_node_path)) {
Node *n = get_node(drag_node_path);
drag_node = Object::cast_to<Control>(n);
@@ -302,7 +282,6 @@ void ScrollBar::_notification(int p_what) {
}
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
if (drag_node) {
drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input));
drag_node->disconnect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit));
@@ -312,7 +291,6 @@ void ScrollBar::_notification(int p_what) {
}
if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
-
if (scrolling) {
if (get_value() != target_scroll) {
double target = target_scroll - get_value();
@@ -332,16 +310,13 @@ void ScrollBar::_notification(int p_what) {
}
} else if (drag_node_touching) {
-
if (drag_node_touching_deaccel) {
-
Vector2 pos = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0);
pos += drag_node_speed * get_physics_process_delta_time();
bool turnoff = false;
if (orientation == HORIZONTAL) {
-
if (pos.x < 0) {
pos.x = 0;
turnoff = true;
@@ -365,7 +340,6 @@ void ScrollBar::_notification(int p_what) {
drag_node_speed.x = sgn_x * val_x;
} else {
-
if (pos.y < 0) {
pos.y = 0;
turnoff = true;
@@ -395,9 +369,7 @@ void ScrollBar::_notification(int p_what) {
}
} else {
-
if (time_since_motion == 0 || time_since_motion > 0.1) {
-
Vector2 diff = drag_node_accum - last_drag_node_accum;
last_drag_node_accum = drag_node_accum;
drag_node_speed = diff / get_physics_process_delta_time();
@@ -409,24 +381,22 @@ void ScrollBar::_notification(int p_what) {
}
if (p_what == NOTIFICATION_MOUSE_EXIT) {
-
highlight = HIGHLIGHT_NONE;
update();
}
}
double ScrollBar::get_grabber_min_size() const {
-
Ref<StyleBox> grabber = get_theme_stylebox("grabber");
Size2 gminsize = grabber->get_minimum_size() + grabber->get_center_size();
return (orientation == VERTICAL) ? gminsize.height : gminsize.width;
}
double ScrollBar::get_grabber_size() const {
-
float range = get_max() - get_min();
- if (range <= 0)
+ if (range <= 0) {
return 0;
+ }
float page = (get_page() > 0) ? get_page() : 0;
/*
@@ -464,17 +434,14 @@ double ScrollBar::get_area_size() const {
}
double ScrollBar::get_area_offset() const {
-
double ofs = 0;
if (orientation == VERTICAL) {
-
ofs += get_theme_stylebox("hscroll")->get_margin(MARGIN_TOP);
ofs += get_theme_icon("decrement")->get_height();
}
if (orientation == HORIZONTAL) {
-
ofs += get_theme_stylebox("hscroll")->get_margin(MARGIN_LEFT);
ofs += get_theme_icon("decrement")->get_width();
}
@@ -483,31 +450,28 @@ double ScrollBar::get_area_offset() const {
}
double ScrollBar::get_click_pos(const Point2 &p_pos) const {
-
float pos = (orientation == VERTICAL) ? p_pos.y : p_pos.x;
pos -= get_area_offset();
float area = get_area_size();
- if (area == 0)
+ if (area == 0) {
return 0;
- else
+ } else {
return pos / area;
+ }
}
double ScrollBar::get_grabber_offset() const {
-
return (get_area_size()) * get_as_ratio();
}
Size2 ScrollBar::get_minimum_size() const {
-
Ref<Texture2D> incr = get_theme_icon("increment");
Ref<Texture2D> decr = get_theme_icon("decrement");
Ref<StyleBox> bg = get_theme_stylebox("scroll");
Size2 minsize;
if (orientation == VERTICAL) {
-
minsize.width = MAX(incr->get_size().width, (bg->get_minimum_size() + bg->get_center_size()).width);
minsize.height += incr->get_size().height;
minsize.height += decr->get_size().height;
@@ -516,7 +480,6 @@ Size2 ScrollBar::get_minimum_size() const {
}
if (orientation == HORIZONTAL) {
-
minsize.height = MAX(incr->get_size().height, (bg->get_center_size() + bg->get_minimum_size()).height);
minsize.width += incr->get_size().width;
minsize.width += decr->get_size().width;
@@ -528,17 +491,14 @@ Size2 ScrollBar::get_minimum_size() const {
}
void ScrollBar::set_custom_step(float p_custom_step) {
-
custom_step = p_custom_step;
}
float ScrollBar::get_custom_step() const {
-
return custom_step;
}
void ScrollBar::_drag_node_exit() {
-
if (drag_node) {
drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input));
}
@@ -546,16 +506,14 @@ void ScrollBar::_drag_node_exit() {
}
void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) {
-
Ref<InputEventMouseButton> mb = p_input;
if (mb.is_valid()) {
-
- if (mb->get_button_index() != 1)
+ if (mb->get_button_index() != 1) {
return;
+ }
if (mb->is_pressed()) {
-
drag_node_speed = Vector2();
drag_node_accum = Vector2();
last_drag_node_accum = Vector2();
@@ -570,9 +528,7 @@ void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) {
}
} else {
-
if (drag_node_touching) {
-
if (drag_node_speed == Vector2()) {
drag_node_touching_deaccel = false;
drag_node_touching = false;
@@ -587,19 +543,19 @@ void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) {
Ref<InputEventMouseMotion> mm = p_input;
if (mm.is_valid()) {
-
if (drag_node_touching && !drag_node_touching_deaccel) {
-
Vector2 motion = Vector2(mm->get_relative().x, mm->get_relative().y);
drag_node_accum -= motion;
Vector2 diff = drag_node_from + drag_node_accum;
- if (orientation == HORIZONTAL)
+ if (orientation == HORIZONTAL) {
set_value(diff.x);
+ }
- if (orientation == VERTICAL)
+ if (orientation == VERTICAL) {
set_value(diff.y);
+ }
time_since_motion = 0;
}
@@ -607,9 +563,7 @@ void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) {
}
void ScrollBar::set_drag_node(const NodePath &p_path) {
-
if (is_inside_tree()) {
-
if (drag_node) {
drag_node->disconnect("gui_input", callable_mp(this, &ScrollBar::_drag_node_input));
drag_node->disconnect("tree_exiting", callable_mp(this, &ScrollBar::_drag_node_exit));
@@ -620,7 +574,6 @@ void ScrollBar::set_drag_node(const NodePath &p_path) {
drag_node_path = p_path;
if (is_inside_tree()) {
-
if (has_node(p_path)) {
Node *n = get_node(p_path);
drag_node = Object::cast_to<Control>(n);
@@ -634,7 +587,6 @@ void ScrollBar::set_drag_node(const NodePath &p_path) {
}
NodePath ScrollBar::get_drag_node() const {
-
return drag_node_path;
}
@@ -647,7 +599,6 @@ bool ScrollBar::is_smooth_scroll_enabled() const {
}
void ScrollBar::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollBar::_gui_input);
ClassDB::bind_method(D_METHOD("set_custom_step", "step"), &ScrollBar::set_custom_step);
ClassDB::bind_method(D_METHOD("get_custom_step"), &ScrollBar::get_custom_step);
@@ -658,7 +609,6 @@ void ScrollBar::_bind_methods() {
}
ScrollBar::ScrollBar(Orientation p_orientation) {
-
orientation = p_orientation;
highlight = HIGHLIGHT_NONE;
custom_step = -1;
@@ -674,8 +624,9 @@ ScrollBar::ScrollBar(Orientation p_orientation) {
target_scroll = 0;
smooth_scroll_enabled = false;
- if (focus_by_default)
+ if (focus_by_default) {
set_focus_mode(FOCUS_ALL);
+ }
set_step(0);
}
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index ee5e7140cf..d2641b14f3 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -34,7 +34,6 @@
#include "scene/gui/range.h"
class ScrollBar : public Range {
-
GDCLASS(ScrollBar, Range);
enum HighlightStatus {
@@ -53,7 +52,6 @@ class ScrollBar : public Range {
HighlightStatus highlight;
struct Drag {
-
bool active;
float pos_at_click;
float value_at_click;
@@ -111,7 +109,6 @@ public:
};
class HScrollBar : public ScrollBar {
-
GDCLASS(HScrollBar, ScrollBar);
public:
@@ -120,7 +117,6 @@ public:
};
class VScrollBar : public ScrollBar {
-
GDCLASS(VScrollBar, ScrollBar);
public:
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index fb17adf96e..b72b913af0 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -33,24 +33,24 @@
#include "scene/main/window.h"
bool ScrollContainer::clips_input() const {
-
return true;
}
Size2 ScrollContainer::get_minimum_size() const {
-
Ref<StyleBox> sb = get_theme_stylebox("bg");
Size2 min_size;
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
- if (c == h_scroll || c == v_scroll)
+ }
+ if (c == h_scroll || c == v_scroll) {
continue;
+ }
Size2 minsize = c->get_combined_minimum_size();
if (!scroll_h) {
@@ -88,14 +88,12 @@ void ScrollContainer::_cancel_drag() {
}
void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
-
double prev_v_scroll = v_scroll->get_value();
double prev_h_scroll = h_scroll->get_value();
Ref<InputEventMouseButton> mb = p_gui_input;
if (mb.is_valid()) {
-
if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
// only horizontal is enabled, scroll horizontally
if (h_scroll->is_visible() && (!v_scroll->is_visible() || mb->get_shift())) {
@@ -126,17 +124,19 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll)
+ if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll) {
accept_event(); //accept event if scroll changed
+ }
- if (!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id())))
+ if (!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id()))) {
return;
+ }
- if (mb->get_button_index() != BUTTON_LEFT)
+ if (mb->get_button_index() != BUTTON_LEFT) {
return;
+ }
if (mb->is_pressed()) {
-
if (drag_touching) {
_cancel_drag();
}
@@ -156,11 +156,9 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
} else {
if (drag_touching) {
-
if (drag_speed == Vector2()) {
_cancel_drag();
} else {
-
drag_touching_deaccel = true;
}
}
@@ -170,9 +168,7 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
Ref<InputEventMouseMotion> mm = p_gui_input;
if (mm.is_valid()) {
-
if (drag_touching && !drag_touching_deaccel) {
-
Vector2 motion = Vector2(mm->get_relative().x, mm->get_relative().y);
drag_accum -= motion;
@@ -186,14 +182,16 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
drag_accum = -motion;
}
Vector2 diff = drag_from + drag_accum;
- if (scroll_h)
+ if (scroll_h) {
h_scroll->set_value(diff.x);
- else
+ } else {
drag_accum.x = 0;
- if (scroll_v)
+ }
+ if (scroll_v) {
v_scroll->set_value(diff.y);
- else
+ } else {
drag_accum.y = 0;
+ }
time_since_motion = 0;
}
}
@@ -201,7 +199,6 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
Ref<InputEventPanGesture> pan_gesture = p_gui_input;
if (pan_gesture.is_valid()) {
-
if (h_scroll->is_visible_in_tree()) {
h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * pan_gesture->get_delta().x / 8);
}
@@ -210,12 +207,12 @@ void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll)
+ if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll) {
accept_event(); //accept event if scroll changed
+ }
}
void ScrollContainer::_update_scrollbar_position() {
-
Size2 hmin = h_scroll->get_combined_minimum_size();
Size2 vmin = v_scroll->get_combined_minimum_size();
@@ -234,7 +231,6 @@ void ScrollContainer::_update_scrollbar_position() {
}
void ScrollContainer::_ensure_focused_visible(Control *p_control) {
-
if (!follow_focus) {
return;
}
@@ -259,19 +255,15 @@ void ScrollContainer::_ensure_focused_visible(Control *p_control) {
}
void ScrollContainer::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) {
-
call_deferred("_update_scrollbar_position");
};
if (p_what == NOTIFICATION_READY) {
-
get_viewport()->connect("gui_focus_changed", callable_mp(this, &ScrollContainer::_ensure_focused_visible));
}
if (p_what == NOTIFICATION_SORT_CHILDREN) {
-
child_max_size = Size2(0, 0);
Size2 size = get_size();
Point2 ofs;
@@ -280,21 +272,25 @@ void ScrollContainer::_notification(int p_what) {
size -= sb->get_minimum_size();
ofs += sb->get_offset();
- if (h_scroll->is_visible_in_tree() && h_scroll->get_parent() == this) //scrolls may have been moved out for reasons
+ if (h_scroll->is_visible_in_tree() && h_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
size.y -= h_scroll->get_minimum_size().y;
+ }
- if (v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) //scrolls may have been moved out for reasons
+ if (v_scroll->is_visible_in_tree() && v_scroll->get_parent() == this) { //scrolls may have been moved out for reasons
size.x -= v_scroll->get_minimum_size().x;
+ }
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
- if (c == h_scroll || c == v_scroll)
+ }
+ if (c == h_scroll || c == v_scroll) {
continue;
+ }
Size2 minsize = c->get_combined_minimum_size();
child_max_size.x = MAX(child_max_size.x, minsize.x);
child_max_size.y = MAX(child_max_size.y, minsize.y);
@@ -302,17 +298,19 @@ void ScrollContainer::_notification(int p_what) {
Rect2 r = Rect2(-scroll, minsize);
if (!scroll_h || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) {
r.position.x = 0;
- if (c->get_h_size_flags() & SIZE_EXPAND)
+ if (c->get_h_size_flags() & SIZE_EXPAND) {
r.size.width = MAX(size.width, minsize.width);
- else
+ } else {
r.size.width = minsize.width;
+ }
}
if (!scroll_v || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) {
r.position.y = 0;
- if (c->get_v_size_flags() & SIZE_EXPAND)
+ if (c->get_v_size_flags() & SIZE_EXPAND) {
r.size.height = MAX(size.height, minsize.height);
- else
+ } else {
r.size.height = minsize.height;
+ }
}
r.position += ofs;
fit_child_in_rect(c, r);
@@ -322,7 +320,6 @@ void ScrollContainer::_notification(int p_what) {
};
if (p_what == NOTIFICATION_DRAW) {
-
Ref<StyleBox> sb = get_theme_stylebox("bg");
draw_style_box(sb, Rect2(Vector2(), get_size()));
@@ -330,11 +327,8 @@ void ScrollContainer::_notification(int p_what) {
}
if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
-
if (drag_touching) {
-
if (drag_touching_deaccel) {
-
Vector2 pos = Vector2(h_scroll->get_value(), v_scroll->get_value());
pos += drag_speed * get_physics_process_delta_time();
@@ -359,10 +353,12 @@ void ScrollContainer::_notification(int p_what) {
turnoff_v = true;
}
- if (scroll_h)
+ if (scroll_h) {
h_scroll->set_value(pos.x);
- if (scroll_v)
+ }
+ if (scroll_v) {
v_scroll->set_value(pos.y);
+ }
float sgn_x = drag_speed.x < 0 ? -1 : 1;
float val_x = Math::abs(drag_speed.x);
@@ -387,9 +383,7 @@ void ScrollContainer::_notification(int p_what) {
}
} else {
-
if (time_since_motion == 0 || time_since_motion > 0.1) {
-
Vector2 diff = drag_accum - last_drag_accum;
last_drag_accum = drag_accum;
drag_speed = diff / get_physics_process_delta_time();
@@ -402,7 +396,6 @@ void ScrollContainer::_notification(int p_what) {
};
void ScrollContainer::update_scrollbars() {
-
Size2 size = get_size();
Ref<StyleBox> sb = get_theme_stylebox("bg");
size -= sb->get_minimum_size();
@@ -422,11 +415,9 @@ void ScrollContainer::update_scrollbars() {
bool hide_scroll_h = !scroll_h || min.width <= size.width;
if (hide_scroll_v) {
-
v_scroll->hide();
scroll.y = 0;
} else {
-
v_scroll->show();
v_scroll->set_max(min.height);
if (hide_scroll_h) {
@@ -439,11 +430,9 @@ void ScrollContainer::update_scrollbars() {
}
if (hide_scroll_h) {
-
h_scroll->hide();
scroll.x = 0;
} else {
-
h_scroll->show();
h_scroll->set_max(min.width);
if (hide_scroll_v) {
@@ -461,7 +450,6 @@ void ScrollContainer::update_scrollbars() {
}
void ScrollContainer::_scroll_moved(float) {
-
scroll.x = h_scroll->get_value();
scroll.y = v_scroll->get_value();
queue_sort();
@@ -480,7 +468,6 @@ void ScrollContainer::set_enable_h_scroll(bool p_enable) {
}
bool ScrollContainer::is_h_scroll_enabled() const {
-
return scroll_h;
}
@@ -495,26 +482,23 @@ void ScrollContainer::set_enable_v_scroll(bool p_enable) {
}
bool ScrollContainer::is_v_scroll_enabled() const {
-
return scroll_v;
}
int ScrollContainer::get_v_scroll() const {
-
return v_scroll->get_value();
}
-void ScrollContainer::set_v_scroll(int p_pos) {
+void ScrollContainer::set_v_scroll(int p_pos) {
v_scroll->set_value(p_pos);
_cancel_drag();
}
int ScrollContainer::get_h_scroll() const {
-
return h_scroll->get_value();
}
-void ScrollContainer::set_h_scroll(int p_pos) {
+void ScrollContainer::set_h_scroll(int p_pos) {
h_scroll->set_value(p_pos);
_cancel_drag();
}
@@ -536,40 +520,39 @@ void ScrollContainer::set_follow_focus(bool p_follow) {
}
String ScrollContainer::get_configuration_warning() const {
-
int found = 0;
for (int i = 0; i < get_child_count(); i++) {
-
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c)
+ if (!c) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
- if (c == h_scroll || c == v_scroll)
+ }
+ if (c == h_scroll || c == v_scroll) {
continue;
+ }
found++;
}
- if (found != 1)
+ if (found != 1) {
return TTR("ScrollContainer is intended to work with a single child control.\nUse a container as child (VBox, HBox, etc.), or a Control and set the custom minimum size manually.");
- else
+ } else {
return "";
+ }
}
HScrollBar *ScrollContainer::get_h_scrollbar() {
-
return h_scroll;
}
VScrollBar *ScrollContainer::get_v_scrollbar() {
-
return v_scroll;
}
void ScrollContainer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollContainer::_gui_input);
ClassDB::bind_method(D_METHOD("set_enable_h_scroll", "enable"), &ScrollContainer::set_enable_h_scroll);
ClassDB::bind_method(D_METHOD("is_h_scroll_enabled"), &ScrollContainer::is_h_scroll_enabled);
@@ -604,7 +587,6 @@ void ScrollContainer::_bind_methods() {
};
ScrollContainer::ScrollContainer() {
-
h_scroll = memnew(HScrollBar);
h_scroll->set_name("_h_scroll");
add_child(h_scroll);
diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h
index 6423b36fcc..321e0e2c5a 100644
--- a/scene/gui/scroll_container.h
+++ b/scene/gui/scroll_container.h
@@ -36,7 +36,6 @@
#include "scroll_bar.h"
class ScrollContainer : public Container {
-
GDCLASS(ScrollContainer, Container);
HScrollBar *h_scroll;
diff --git a/scene/gui/separator.cpp b/scene/gui/separator.cpp
index 75c4b7cce9..4f7e5720b8 100644
--- a/scene/gui/separator.cpp
+++ b/scene/gui/separator.cpp
@@ -31,7 +31,6 @@
#include "separator.h"
Size2 Separator::get_minimum_size() const {
-
Size2 ms(3, 3);
if (orientation == VERTICAL) {
ms.x = get_theme_constant("separation");
@@ -42,20 +41,15 @@ Size2 Separator::get_minimum_size() const {
}
void Separator::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_DRAW: {
-
Size2i size = get_size();
Ref<StyleBox> style = get_theme_stylebox("separator");
Size2i ssize = style->get_minimum_size() + style->get_center_size();
if (orientation == VERTICAL) {
-
style->draw(get_canvas_item(), Rect2((size.x - ssize.x) / 2, 0, ssize.x, size.y));
} else {
-
style->draw(get_canvas_item(), Rect2(0, (size.y - ssize.y) / 2, size.x, ssize.y));
}
@@ -70,11 +64,9 @@ Separator::~Separator() {
}
HSeparator::HSeparator() {
-
orientation = HORIZONTAL;
}
VSeparator::VSeparator() {
-
orientation = VERTICAL;
}
diff --git a/scene/gui/separator.h b/scene/gui/separator.h
index 9a64d6ba99..f7e5ef2c6b 100644
--- a/scene/gui/separator.h
+++ b/scene/gui/separator.h
@@ -33,7 +33,6 @@
#include "scene/gui/control.h"
class Separator : public Control {
-
GDCLASS(Separator, Control);
protected:
@@ -48,7 +47,6 @@ public:
};
class VSeparator : public Separator {
-
GDCLASS(VSeparator, Separator);
public:
@@ -56,7 +54,6 @@ public:
};
class HSeparator : public Separator {
-
GDCLASS(HSeparator, Separator);
public:
diff --git a/scene/gui/shortcut.cpp b/scene/gui/shortcut.cpp
index 262d8076f3..9f5b9c40c2 100644
--- a/scene/gui/shortcut.cpp
+++ b/scene/gui/shortcut.cpp
@@ -33,36 +33,31 @@
#include "core/os/keyboard.h"
void ShortCut::set_shortcut(const Ref<InputEvent> &p_shortcut) {
-
shortcut = p_shortcut;
emit_changed();
}
Ref<InputEvent> ShortCut::get_shortcut() const {
-
return shortcut;
}
bool ShortCut::is_shortcut(const Ref<InputEvent> &p_event) const {
-
return shortcut.is_valid() && shortcut->shortcut_match(p_event);
}
String ShortCut::get_as_text() const {
-
- if (shortcut.is_valid())
+ if (shortcut.is_valid()) {
return shortcut->as_text();
- else
+ } else {
return "None";
+ }
}
bool ShortCut::is_valid() const {
-
return shortcut.is_valid();
}
void ShortCut::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_shortcut", "event"), &ShortCut::set_shortcut);
ClassDB::bind_method(D_METHOD("get_shortcut"), &ShortCut::get_shortcut);
diff --git a/scene/gui/shortcut.h b/scene/gui/shortcut.h
index b22c3441c5..063d4e43dc 100644
--- a/scene/gui/shortcut.h
+++ b/scene/gui/shortcut.h
@@ -35,7 +35,6 @@
#include "core/resource.h"
class ShortCut : public Resource {
-
GDCLASS(ShortCut, Resource);
Ref<InputEvent> shortcut;
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 1f135163d4..3dd5e022f0 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -32,21 +32,20 @@
#include "core/os/keyboard.h"
Size2 Slider::get_minimum_size() const {
-
Ref<StyleBox> style = get_theme_stylebox("slider");
Size2i ss = style->get_minimum_size() + style->get_center_size();
Ref<Texture2D> grabber = get_theme_icon("grabber");
Size2i rs = grabber->get_size();
- if (orientation == HORIZONTAL)
+ if (orientation == HORIZONTAL) {
return Size2i(ss.width, MAX(ss.height, rs.height));
- else
+ } else {
return Size2i(MAX(ss.width, rs.width), ss.height);
+ }
}
void Slider::_gui_input(Ref<InputEvent> p_event) {
-
if (!editable) {
return;
}
@@ -55,7 +54,6 @@ void Slider::_gui_input(Ref<InputEvent> p_event) {
if (mb.is_valid()) {
if (mb->get_button_index() == BUTTON_LEFT) {
-
if (mb->is_pressed()) {
Ref<Texture2D> grabber = get_theme_icon(mouse_inside || has_focus() ? "grabber_highlight" : "grabber");
grab.pos = orientation == VERTICAL ? mb->get_position().y : mb->get_position().x;
@@ -63,10 +61,11 @@ void Slider::_gui_input(Ref<InputEvent> p_event) {
double grab_width = (double)grabber->get_size().width;
double grab_height = (double)grabber->get_size().height;
double max = orientation == VERTICAL ? get_size().height - grab_height : get_size().width - grab_width;
- if (orientation == VERTICAL)
+ if (orientation == VERTICAL) {
set_as_ratio(1 - (((double)grab.pos - (grab_height / 2.0)) / max));
- else
+ } else {
set_as_ratio(((double)grab.pos - (grab_width / 2.0)) / max);
+ }
grab.active = true;
grab.uvalue = get_as_ratio();
} else {
@@ -85,53 +84,51 @@ void Slider::_gui_input(Ref<InputEvent> p_event) {
if (mm.is_valid()) {
if (grab.active) {
-
Size2i size = get_size();
Ref<Texture2D> grabber = get_theme_icon("grabber");
float motion = (orientation == VERTICAL ? mm->get_position().y : mm->get_position().x) - grab.pos;
- if (orientation == VERTICAL)
+ if (orientation == VERTICAL) {
motion = -motion;
+ }
float areasize = orientation == VERTICAL ? size.height - grabber->get_size().height : size.width - grabber->get_size().width;
- if (areasize <= 0)
+ if (areasize <= 0) {
return;
+ }
float umotion = motion / float(areasize);
set_as_ratio(grab.uvalue + umotion);
}
}
if (!mm.is_valid() && !mb.is_valid()) {
-
if (p_event->is_action_pressed("ui_left", true)) {
-
- if (orientation != HORIZONTAL)
+ if (orientation != HORIZONTAL) {
return;
+ }
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
accept_event();
} else if (p_event->is_action_pressed("ui_right", true)) {
-
- if (orientation != HORIZONTAL)
+ if (orientation != HORIZONTAL) {
return;
+ }
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
accept_event();
} else if (p_event->is_action_pressed("ui_up", true)) {
-
- if (orientation != VERTICAL)
+ if (orientation != VERTICAL) {
return;
+ }
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
accept_event();
} else if (p_event->is_action_pressed("ui_down", true)) {
-
- if (orientation != VERTICAL)
+ if (orientation != VERTICAL) {
return;
+ }
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
accept_event();
} else if (p_event->is_action("ui_home") && p_event->is_pressed()) {
-
set_value(get_min());
accept_event();
} else if (p_event->is_action("ui_end") && p_event->is_pressed()) {
-
set_value(get_max());
accept_event();
}
@@ -139,26 +136,21 @@ void Slider::_gui_input(Ref<InputEvent> p_event) {
}
void Slider::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
-
minimum_size_changed();
update();
} break;
case NOTIFICATION_MOUSE_ENTER: {
-
mouse_inside = true;
update();
} break;
case NOTIFICATION_MOUSE_EXIT: {
-
mouse_inside = false;
update();
} break;
case NOTIFICATION_VISIBILITY_CHANGED: // fallthrough
case NOTIFICATION_EXIT_TREE: {
-
mouse_inside = false;
grab.active = false;
} break;
@@ -173,7 +165,6 @@ void Slider::_notification(int p_what) {
double ratio = Math::is_nan(get_as_ratio()) ? 0 : get_as_ratio();
if (orientation == VERTICAL) {
-
int widget_width = style->get_minimum_size().width + style->get_center_size().width;
float areasize = size.height - grabber->get_size().height;
style->draw(ci, Rect2i(Point2i(size.width / 2 - widget_width / 2, 0), Size2i(widget_width, size.height)));
@@ -182,14 +173,15 @@ void Slider::_notification(int p_what) {
if (ticks > 1) {
int grabber_offset = (grabber->get_size().height / 2 - tick->get_height() / 2);
for (int i = 0; i < ticks; i++) {
- if (!ticks_on_borders && (i == 0 || i + 1 == ticks)) continue;
+ if (!ticks_on_borders && (i == 0 || i + 1 == ticks)) {
+ continue;
+ }
int ofs = (i * areasize / (ticks - 1)) + grabber_offset;
tick->draw(ci, Point2i((size.width - widget_width) / 2, ofs));
}
}
grabber->draw(ci, Point2i(size.width / 2 - grabber->get_size().width / 2, size.height - ratio * areasize - grabber->get_size().height));
} else {
-
int widget_height = style->get_minimum_size().height + style->get_center_size().height;
float areasize = size.width - grabber->get_size().width;
@@ -199,7 +191,9 @@ void Slider::_notification(int p_what) {
if (ticks > 1) {
int grabber_offset = (grabber->get_size().width / 2 - tick->get_width() / 2);
for (int i = 0; i < ticks; i++) {
- if ((!ticks_on_borders) && ((i == 0) || ((i + 1) == ticks))) continue;
+ if ((!ticks_on_borders) && ((i == 0) || ((i + 1) == ticks))) {
+ continue;
+ }
int ofs = (i * areasize / (ticks - 1)) + grabber_offset;
tick->draw(ci, Point2i(ofs, (size.height - widget_height) / 2));
}
@@ -212,23 +206,19 @@ void Slider::_notification(int p_what) {
}
void Slider::set_custom_step(float p_custom_step) {
-
custom_step = p_custom_step;
}
float Slider::get_custom_step() const {
-
return custom_step;
}
void Slider::set_ticks(int p_count) {
-
ticks = p_count;
update();
}
int Slider::get_ticks() const {
-
return ticks;
}
@@ -242,28 +232,23 @@ void Slider::set_ticks_on_borders(bool _tob) {
}
void Slider::set_editable(bool p_editable) {
-
editable = p_editable;
update();
}
bool Slider::is_editable() const {
-
return editable;
}
void Slider::set_scrollable(bool p_scrollable) {
-
scrollable = p_scrollable;
}
bool Slider::is_scrollable() const {
-
return scrollable;
}
void Slider::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &Slider::_gui_input);
ClassDB::bind_method(D_METHOD("set_ticks", "count"), &Slider::set_ticks);
ClassDB::bind_method(D_METHOD("get_ticks"), &Slider::get_ticks);
diff --git a/scene/gui/slider.h b/scene/gui/slider.h
index 1248044ec4..6f8f7cc7d8 100644
--- a/scene/gui/slider.h
+++ b/scene/gui/slider.h
@@ -34,7 +34,6 @@
#include "scene/gui/range.h"
class Slider : public Range {
-
GDCLASS(Slider, Range);
struct Grab {
@@ -78,7 +77,6 @@ public:
};
class HSlider : public Slider {
-
GDCLASS(HSlider, Slider);
public:
@@ -87,7 +85,6 @@ public:
};
class VSlider : public Slider {
-
GDCLASS(VSlider, Slider);
public:
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 8572d570fb..3670f13705 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -30,28 +30,27 @@
#include "spin_box.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/math/expression.h"
Size2 SpinBox::get_minimum_size() const {
-
Size2 ms = line_edit->get_combined_minimum_size();
ms.width += last_w;
return ms;
}
void SpinBox::_value_changed(double) {
-
String value = String::num(get_value(), Math::range_step_decimals(get_step()));
- if (prefix != "")
+ if (prefix != "") {
value = prefix + " " + value;
- if (suffix != "")
+ }
+ if (suffix != "") {
value += " " + suffix;
+ }
line_edit->set_text(value);
}
void SpinBox::_text_entered(const String &p_string) {
-
Ref<Expression> expr;
expr.instance();
// Ignore the prefix and suffix in the expression
@@ -68,7 +67,6 @@ void SpinBox::_text_entered(const String &p_string) {
}
LineEdit *SpinBox::get_line_edit() {
-
return line_edit;
}
@@ -76,9 +74,7 @@ void SpinBox::_line_edit_input(const Ref<InputEvent> &p_event) {
}
void SpinBox::_range_click_timeout() {
-
- if (!drag.enabled && InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
-
+ if (!drag.enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
bool up = get_local_mouse_position().y < (get_size().height / 2);
set_value(get_value() + (up ? get_step() : -get_step()));
@@ -94,7 +90,6 @@ void SpinBox::_range_click_timeout() {
}
void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
-
if (!is_editable()) {
return;
}
@@ -102,13 +97,10 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed()) {
-
bool up = mb->get_position().y < (get_size().height / 2);
switch (mb->get_button_index()) {
-
case BUTTON_LEFT: {
-
line_edit->grab_focus();
set_value(get_value() + (up ? get_step() : -get_step()));
@@ -121,20 +113,17 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
drag.capture_pos = mb->get_position();
} break;
case BUTTON_RIGHT: {
-
line_edit->grab_focus();
set_value((up ? get_max() : get_min()));
} break;
case BUTTON_WHEEL_UP: {
if (line_edit->has_focus()) {
-
set_value(get_value() + get_step() * mb->get_factor());
accept_event();
}
} break;
case BUTTON_WHEEL_DOWN: {
if (line_edit->has_focus()) {
-
set_value(get_value() - get_step() * mb->get_factor());
accept_event();
}
@@ -143,13 +132,12 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
}
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
//set_default_cursor_shape(CURSOR_ARROW);
range_click_timer->stop();
if (drag.enabled) {
drag.enabled = false;
- InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
warp_mouse(drag.capture_pos);
}
drag.allowed = false;
@@ -158,15 +146,12 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
-
if (drag.enabled) {
-
drag.diff_y += mm->get_relative().y;
float diff_y = -0.01 * Math::pow(ABS(drag.diff_y), 1.8f) * SGN(drag.diff_y);
set_value(CLAMP(drag.base_val + get_step() * diff_y, get_min(), get_max()));
} else if (drag.allowed && drag.capture_pos.distance_to(mm->get_position()) > 2) {
-
- InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_CAPTURED);
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
drag.enabled = true;
drag.base_val = get_value();
drag.diff_y = 0;
@@ -175,16 +160,15 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
}
void SpinBox::_line_edit_focus_exit() {
-
// discontinue because the focus_exit was caused by right-click context menu
- if (line_edit->get_menu()->is_visible())
+ if (line_edit->get_menu()->is_visible()) {
return;
+ }
_text_entered(line_edit->get_text());
}
inline void SpinBox::_adjust_width_for_icon(const Ref<Texture2D> &icon) {
-
int w = icon->get_width();
if (w != last_w) {
line_edit->set_margin(MARGIN_RIGHT, -w);
@@ -193,9 +177,7 @@ inline void SpinBox::_adjust_width_for_icon(const Ref<Texture2D> &icon) {
}
void SpinBox::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
-
Ref<Texture2D> updown = get_theme_icon("updown");
_adjust_width_for_icon(updown);
@@ -206,48 +188,39 @@ void SpinBox::_notification(int p_what) {
updown->draw(ci, Point2i(size.width - updown->get_width(), (size.height - updown->get_height()) / 2));
} else if (p_what == NOTIFICATION_FOCUS_EXIT) {
-
//_value_changed(0);
} else if (p_what == NOTIFICATION_ENTER_TREE) {
-
_adjust_width_for_icon(get_theme_icon("updown"));
_value_changed(0);
} else if (p_what == NOTIFICATION_THEME_CHANGED) {
-
call_deferred("minimum_size_changed");
get_line_edit()->call_deferred("minimum_size_changed");
}
}
void SpinBox::set_align(LineEdit::Align p_align) {
-
line_edit->set_align(p_align);
}
LineEdit::Align SpinBox::get_align() const {
-
return line_edit->get_align();
}
void SpinBox::set_suffix(const String &p_suffix) {
-
suffix = p_suffix;
_value_changed(0);
}
String SpinBox::get_suffix() const {
-
return suffix;
}
void SpinBox::set_prefix(const String &p_prefix) {
-
prefix = p_prefix;
_value_changed(0);
}
String SpinBox::get_prefix() const {
-
return prefix;
}
@@ -256,7 +229,6 @@ void SpinBox::set_editable(bool p_editable) {
}
bool SpinBox::is_editable() const {
-
return line_edit->is_editable();
}
@@ -265,7 +237,6 @@ void SpinBox::apply() {
}
void SpinBox::_bind_methods() {
-
//ClassDB::bind_method(D_METHOD("_value_changed"),&SpinBox::_value_changed);
ClassDB::bind_method(D_METHOD("_gui_input"), &SpinBox::_gui_input);
ClassDB::bind_method(D_METHOD("set_align", "align"), &SpinBox::set_align);
@@ -286,7 +257,6 @@ void SpinBox::_bind_methods() {
}
SpinBox::SpinBox() {
-
last_w = 0;
line_edit = memnew(LineEdit);
add_child(line_edit);
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index d3a3d8fe3d..3200480cf5 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -36,7 +36,6 @@
#include "scene/main/timer.h"
class SpinBox : public Range {
-
GDCLASS(SpinBox, Range);
LineEdit *line_edit;
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index de892a4fb9..5c60153d91 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -34,18 +34,20 @@
#include "margin_container.h"
Control *SplitContainer::_getch(int p_idx) const {
-
int idx = 0;
for (int i = 0; i < get_child_count(); i++) {
Control *c = Object::cast_to<Control>(get_child(i));
- if (!c || !c->is_visible_in_tree())
+ if (!c || !c->is_visible_in_tree()) {
continue;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
continue;
+ }
- if (idx == p_idx)
+ if (idx == p_idx) {
return c;
+ }
idx++;
}
@@ -119,7 +121,6 @@ void SplitContainer::_resort() {
}
Size2 SplitContainer::get_minimum_size() const {
-
/* Calculate MINIMUM SIZE */
Size2i minimum;
@@ -128,26 +129,24 @@ Size2 SplitContainer::get_minimum_size() const {
sep = (dragger_visibility != DRAGGER_HIDDEN_COLLAPSED) ? MAX(sep, vertical ? g->get_height() : g->get_width()) : 0;
for (int i = 0; i < 2; i++) {
-
- if (!_getch(i))
+ if (!_getch(i)) {
break;
+ }
if (i == 1) {
-
- if (vertical)
+ if (vertical) {
minimum.height += sep;
- else
+ } else {
minimum.width += sep;
+ }
}
Size2 ms = _getch(i)->get_combined_minimum_size();
if (vertical) {
-
minimum.height += ms.height;
minimum.width = MAX(minimum.width, ms.width);
} else {
-
minimum.width += ms.width;
minimum.height = MAX(minimum.height, ms.height);
}
@@ -157,80 +156,71 @@ Size2 SplitContainer::get_minimum_size() const {
}
void SplitContainer::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_SORT_CHILDREN: {
-
_resort();
} break;
case NOTIFICATION_MOUSE_EXIT: {
-
mouse_inside = false;
- if (get_theme_constant("autohide"))
+ if (get_theme_constant("autohide")) {
update();
+ }
} break;
case NOTIFICATION_DRAW: {
-
- if (!_getch(0) || !_getch(1))
+ if (!_getch(0) || !_getch(1)) {
return;
+ }
- if (collapsed || (!dragging && !mouse_inside && get_theme_constant("autohide")))
+ if (collapsed || (!dragging && !mouse_inside && get_theme_constant("autohide"))) {
return;
+ }
- if (dragger_visibility != DRAGGER_VISIBLE)
+ if (dragger_visibility != DRAGGER_VISIBLE) {
return;
+ }
int sep = dragger_visibility != DRAGGER_HIDDEN_COLLAPSED ? get_theme_constant("separation") : 0;
Ref<Texture2D> tex = get_theme_icon("grabber");
Size2 size = get_size();
- if (vertical)
+ if (vertical) {
draw_texture(tex, Point2i((size.x - tex->get_width()) / 2, middle_sep + (sep - tex->get_height()) / 2));
- else
+ } else {
draw_texture(tex, Point2i(middle_sep + (sep - tex->get_width()) / 2, (size.y - tex->get_height()) / 2));
+ }
} break;
case NOTIFICATION_THEME_CHANGED: {
-
minimum_size_changed();
} break;
}
}
void SplitContainer::_gui_input(const Ref<InputEvent> &p_event) {
-
- if (collapsed || !_getch(0) || !_getch(1) || dragger_visibility != DRAGGER_VISIBLE)
+ if (collapsed || !_getch(0) || !_getch(1) || dragger_visibility != DRAGGER_VISIBLE) {
return;
+ }
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
-
if (mb->get_button_index() == BUTTON_LEFT) {
-
if (mb->is_pressed()) {
-
int sep = get_theme_constant("separation");
if (vertical) {
-
if (mb->get_position().y > middle_sep && mb->get_position().y < middle_sep + sep) {
-
dragging = true;
drag_from = mb->get_position().y;
drag_ofs = split_offset;
}
} else {
-
if (mb->get_position().x > middle_sep && mb->get_position().x < middle_sep + sep) {
-
dragging = true;
drag_from = mb->get_position().x;
drag_ofs = split_offset;
}
}
} else {
-
dragging = false;
}
}
@@ -239,22 +229,23 @@ void SplitContainer::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
bool mouse_inside_state = false;
- if (vertical)
+ if (vertical) {
mouse_inside_state = mm->get_position().y > middle_sep && mm->get_position().y < middle_sep + get_theme_constant("separation");
- else
+ } else {
mouse_inside_state = mm->get_position().x > middle_sep && mm->get_position().x < middle_sep + get_theme_constant("separation");
+ }
if (mouse_inside != mouse_inside_state) {
-
mouse_inside = mouse_inside_state;
- if (get_theme_constant("autohide"))
+ if (get_theme_constant("autohide")) {
update();
+ }
}
- if (!dragging)
+ if (!dragging) {
return;
+ }
split_offset = drag_ofs + ((vertical ? mm->get_position().y : mm->get_position().x) - drag_from);
should_clamp_split_offset = true;
@@ -264,22 +255,21 @@ void SplitContainer::_gui_input(const Ref<InputEvent> &p_event) {
}
Control::CursorShape SplitContainer::get_cursor_shape(const Point2 &p_pos) const {
-
- if (dragging)
+ if (dragging) {
return (vertical ? CURSOR_VSPLIT : CURSOR_HSPLIT);
+ }
if (!collapsed && _getch(0) && _getch(1) && dragger_visibility == DRAGGER_VISIBLE) {
-
int sep = get_theme_constant("separation");
if (vertical) {
-
- if (p_pos.y > middle_sep && p_pos.y < middle_sep + sep)
+ if (p_pos.y > middle_sep && p_pos.y < middle_sep + sep) {
return CURSOR_VSPLIT;
+ }
} else {
-
- if (p_pos.x > middle_sep && p_pos.x < middle_sep + sep)
+ if (p_pos.x > middle_sep && p_pos.x < middle_sep + sep) {
return CURSOR_HSPLIT;
+ }
}
}
@@ -287,9 +277,9 @@ Control::CursorShape SplitContainer::get_cursor_shape(const Point2 &p_pos) const
}
void SplitContainer::set_split_offset(int p_offset) {
-
- if (split_offset == p_offset)
+ if (split_offset == p_offset) {
return;
+ }
split_offset = p_offset;
@@ -297,7 +287,6 @@ void SplitContainer::set_split_offset(int p_offset) {
}
int SplitContainer::get_split_offset() const {
-
return split_offset;
}
@@ -308,33 +297,29 @@ void SplitContainer::clamp_split_offset() {
}
void SplitContainer::set_collapsed(bool p_collapsed) {
-
- if (collapsed == p_collapsed)
+ if (collapsed == p_collapsed) {
return;
+ }
collapsed = p_collapsed;
queue_sort();
}
void SplitContainer::set_dragger_visibility(DraggerVisibility p_visibility) {
-
dragger_visibility = p_visibility;
queue_sort();
update();
}
SplitContainer::DraggerVisibility SplitContainer::get_dragger_visibility() const {
-
return dragger_visibility;
}
bool SplitContainer::is_collapsed() const {
-
return collapsed;
}
void SplitContainer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &SplitContainer::_gui_input);
ClassDB::bind_method(D_METHOD("set_split_offset", "offset"), &SplitContainer::set_split_offset);
@@ -359,7 +344,6 @@ void SplitContainer::_bind_methods() {
}
SplitContainer::SplitContainer(bool p_vertical) {
-
mouse_inside = false;
split_offset = 0;
should_clamp_split_offset = false;
diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h
index d759c6ad35..6dbd316a46 100644
--- a/scene/gui/split_container.h
+++ b/scene/gui/split_container.h
@@ -34,7 +34,6 @@
#include "scene/gui/container.h"
class SplitContainer : public Container {
-
GDCLASS(SplitContainer, Container);
public:
@@ -86,7 +85,6 @@ public:
VARIANT_ENUM_CAST(SplitContainer::DraggerVisibility);
class HSplitContainer : public SplitContainer {
-
GDCLASS(HSplitContainer, SplitContainer);
public:
@@ -95,7 +93,6 @@ public:
};
class VSplitContainer : public SplitContainer {
-
GDCLASS(VSplitContainer, SplitContainer);
public:
diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp
index 50f468741d..4e1ad2ae05 100644
--- a/scene/gui/subviewport_container.cpp
+++ b/scene/gui/subviewport_container.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* subviewport_container.cpp */
+/* subviewport_container.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -34,15 +34,15 @@
#include "scene/main/viewport.h"
Size2 SubViewportContainer::get_minimum_size() const {
-
- if (stretch)
+ if (stretch) {
return Size2();
+ }
Size2 ms;
for (int i = 0; i < get_child_count(); i++) {
-
SubViewport *c = Object::cast_to<SubViewport>(get_child(i));
- if (!c)
+ if (!c) {
continue;
+ }
Size2 minsize = c->get_size();
ms.width = MAX(ms.width, minsize.width);
@@ -53,33 +53,32 @@ Size2 SubViewportContainer::get_minimum_size() const {
}
void SubViewportContainer::set_stretch(bool p_enable) {
-
stretch = p_enable;
queue_sort();
update();
}
bool SubViewportContainer::is_stretch_enabled() const {
-
return stretch;
}
void SubViewportContainer::set_stretch_shrink(int p_shrink) {
-
ERR_FAIL_COND(p_shrink < 1);
- if (shrink == p_shrink)
+ if (shrink == p_shrink) {
return;
+ }
shrink = p_shrink;
- if (!stretch)
+ if (!stretch) {
return;
+ }
for (int i = 0; i < get_child_count(); i++) {
-
SubViewport *c = Object::cast_to<SubViewport>(get_child(i));
- if (!c)
+ if (!c) {
continue;
+ }
c->set_size(get_size() / shrink);
}
@@ -88,64 +87,62 @@ void SubViewportContainer::set_stretch_shrink(int p_shrink) {
}
int SubViewportContainer::get_stretch_shrink() const {
-
return shrink;
}
void SubViewportContainer::_notification(int p_what) {
-
if (p_what == NOTIFICATION_RESIZED) {
-
- if (!stretch)
+ if (!stretch) {
return;
+ }
for (int i = 0; i < get_child_count(); i++) {
-
SubViewport *c = Object::cast_to<SubViewport>(get_child(i));
- if (!c)
+ if (!c) {
continue;
+ }
c->set_size(get_size() / shrink);
}
}
if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
for (int i = 0; i < get_child_count(); i++) {
-
SubViewport *c = Object::cast_to<SubViewport>(get_child(i));
- if (!c)
+ if (!c) {
continue;
+ }
- if (is_visible_in_tree())
+ if (is_visible_in_tree()) {
c->set_update_mode(SubViewport::UPDATE_ALWAYS);
- else
+ } else {
c->set_update_mode(SubViewport::UPDATE_DISABLED);
+ }
c->set_handle_input_locally(false); //do not handle input locally here
}
}
if (p_what == NOTIFICATION_DRAW) {
-
for (int i = 0; i < get_child_count(); i++) {
-
SubViewport *c = Object::cast_to<SubViewport>(get_child(i));
- if (!c)
+ if (!c) {
continue;
+ }
- if (stretch)
+ if (stretch) {
draw_texture_rect(c->get_texture(), Rect2(Vector2(), get_size()));
- else
+ } else {
draw_texture_rect(c->get_texture(), Rect2(Vector2(), c->get_size()));
+ }
}
}
}
void SubViewportContainer::_input(const Ref<InputEvent> &p_event) {
-
- if (Engine::get_singleton()->is_editor_hint())
+ if (Engine::get_singleton()->is_editor_hint()) {
return;
+ }
Transform2D xform = get_global_transform();
@@ -158,19 +155,19 @@ void SubViewportContainer::_input(const Ref<InputEvent> &p_event) {
Ref<InputEvent> ev = p_event->xformed_by(xform.affine_inverse());
for (int i = 0; i < get_child_count(); i++) {
-
SubViewport *c = Object::cast_to<SubViewport>(get_child(i));
- if (!c || c->is_input_disabled())
+ if (!c || c->is_input_disabled()) {
continue;
+ }
c->input(ev);
}
}
void SubViewportContainer::_unhandled_input(const Ref<InputEvent> &p_event) {
-
- if (Engine::get_singleton()->is_editor_hint())
+ if (Engine::get_singleton()->is_editor_hint()) {
return;
+ }
Transform2D xform = get_global_transform();
@@ -183,17 +180,16 @@ void SubViewportContainer::_unhandled_input(const Ref<InputEvent> &p_event) {
Ref<InputEvent> ev = p_event->xformed_by(xform.affine_inverse());
for (int i = 0; i < get_child_count(); i++) {
-
SubViewport *c = Object::cast_to<SubViewport>(get_child(i));
- if (!c || c->is_input_disabled())
+ if (!c || c->is_input_disabled()) {
continue;
+ }
c->unhandled_input(ev);
}
}
void SubViewportContainer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_unhandled_input", "event"), &SubViewportContainer::_unhandled_input);
ClassDB::bind_method(D_METHOD("_input", "event"), &SubViewportContainer::_input);
ClassDB::bind_method(D_METHOD("set_stretch", "enable"), &SubViewportContainer::set_stretch);
@@ -207,7 +203,6 @@ void SubViewportContainer::_bind_methods() {
}
SubViewportContainer::SubViewportContainer() {
-
stretch = false;
shrink = 1;
set_process_input(true);
diff --git a/scene/gui/subviewport_container.h b/scene/gui/subviewport_container.h
index 6ff3d188e2..fc4c9f925a 100644
--- a/scene/gui/subviewport_container.h
+++ b/scene/gui/subviewport_container.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* subviewport_container.h */
+/* subviewport_container.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -34,7 +34,6 @@
#include "scene/gui/container.h"
class SubViewportContainer : public Container {
-
GDCLASS(SubViewportContainer, Container);
bool stretch;
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 3a128cf8e6..8c4d9a5ece 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -36,9 +36,9 @@
#include "scene/gui/texture_rect.h"
int TabContainer::_get_top_margin() const {
-
- if (!tabs_visible)
+ if (!tabs_visible) {
return 0;
+ }
// Respect the minimum tab height.
Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg");
@@ -53,14 +53,15 @@ int TabContainer::_get_top_margin() const {
Vector<Control *> tabs = _get_tabs();
for (int i = 0; i < tabs.size(); i++) {
-
Control *c = tabs[i];
- if (!c->has_meta("_tab_icon"))
+ if (!c->has_meta("_tab_icon")) {
continue;
+ }
Ref<Texture2D> tex = c->get_meta("_tab_icon");
- if (!tex.is_valid())
+ if (!tex.is_valid()) {
continue;
+ }
content_height = MAX(content_height, tex->get_size().height);
}
@@ -68,17 +69,16 @@ int TabContainer::_get_top_margin() const {
}
void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
Point2 pos(mb->get_position().x, mb->get_position().y);
Size2 size = get_size();
// Click must be on tabs in the tab header area.
- if (pos.x < tabs_ofs_cache || pos.y > _get_top_margin())
+ if (pos.x < tabs_ofs_cache || pos.y > _get_top_margin()) {
return;
+ }
// Handle menu button.
Ref<Texture2D> menu = get_theme_icon("menu");
@@ -95,8 +95,9 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
}
// Do not activate tabs when tabs is empty.
- if (get_tab_count() == 0)
+ if (get_tab_count() == 0) {
return;
+ }
Vector<Control *> tabs = _get_tabs();
@@ -144,13 +145,11 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
Point2 pos(mm->get_position().x, mm->get_position().y);
Size2 size = get_size();
// Mouse must be on tabs in the tab header area.
if (pos.x < tabs_ofs_cache || pos.y > _get_top_margin()) {
-
if (menu_hovered || highlight_arrow > -1) {
menu_hovered = false;
highlight_arrow = -1;
@@ -161,7 +160,6 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
Ref<Texture2D> menu = get_theme_icon("menu");
if (popup) {
-
if (pos.x >= size.width - menu->get_width()) {
if (!menu_hovered) {
menu_hovered = true;
@@ -194,13 +192,11 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
Ref<Texture2D> increment = get_theme_icon("increment");
Ref<Texture2D> decrement = get_theme_icon("decrement");
if (pos.x >= size.width - increment->get_width() - popup_ofs) {
-
if (highlight_arrow != 1) {
highlight_arrow = 1;
update();
}
} else if (pos.x >= size.width - increment->get_width() - decrement->get_width() - popup_ofs) {
-
if (highlight_arrow != 0) {
highlight_arrow = 0;
update();
@@ -213,16 +209,12 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
}
void TabContainer::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_TRANSLATION_CHANGED: {
-
minimum_size_changed();
update();
} break;
case NOTIFICATION_RESIZED: {
-
Vector<Control *> tabs = _get_tabs();
int side_margin = get_theme_constant("side_margin");
Ref<Texture2D> menu = get_theme_icon("menu");
@@ -231,12 +223,15 @@ void TabContainer::_notification(int p_what) {
int header_width = get_size().width - side_margin * 2;
// Find the width of the header area.
- if (popup)
+ if (popup) {
header_width -= menu->get_width();
- if (buttons_visible_cache)
+ }
+ if (buttons_visible_cache) {
header_width -= increment->get_width() + decrement->get_width();
- if (popup || buttons_visible_cache)
+ }
+ if (popup || buttons_visible_cache) {
header_width += side_margin;
+ }
// Find the width of all tabs after first_tab_cache.
int all_tabs_width = 0;
@@ -249,15 +244,15 @@ void TabContainer::_notification(int p_what) {
for (int i = first_tab_cache - 1; i >= 0; i--) {
int tab_width = _get_tab_width(i);
- if (all_tabs_width + tab_width > header_width)
+ if (all_tabs_width + tab_width > header_width) {
break;
+ }
all_tabs_width += tab_width;
first_tab_cache--;
}
} break;
case NOTIFICATION_DRAW: {
-
RID canvas = get_canvas_item();
Size2 size = get_size();
@@ -283,14 +278,15 @@ void TabContainer::_notification(int p_what) {
Color font_color_bg = get_theme_color("font_color_bg");
Color font_color_disabled = get_theme_color("font_color_disabled");
int side_margin = get_theme_constant("side_margin");
- int icon_text_distance = get_theme_constant("hseparation");
+ int icon_text_distance = get_theme_constant("icon_separation");
// Find out start and width of the header area.
int header_x = side_margin;
int header_width = size.width - side_margin * 2;
int header_height = _get_top_margin();
- if (popup)
+ if (popup) {
header_width -= menu->get_width();
+ }
// Check if all tabs would fit into the header area.
int all_tabs_width = 0;
@@ -327,8 +323,9 @@ void TabContainer::_notification(int p_what) {
continue;
}
int tab_width = _get_tab_width(i);
- if (all_tabs_width + tab_width > header_width && tab_widths.size() > 0)
+ if (all_tabs_width + tab_width > header_width && tab_widths.size() > 0) {
break;
+ }
all_tabs_width += tab_width;
tab_widths.push_back(tab_width);
}
@@ -387,8 +384,9 @@ void TabContainer::_notification(int p_what) {
if (icon.is_valid()) {
int y = y_center - (icon->get_height() / 2);
icon->draw(canvas, Point2i(x_content, y));
- if (text != "")
+ if (text != "") {
x_content += icon->get_width() + icon_text_distance;
+ }
}
}
@@ -404,15 +402,15 @@ void TabContainer::_notification(int p_what) {
x = get_size().width;
if (popup) {
x -= menu->get_width();
- if (menu_hovered)
+ if (menu_hovered) {
menu_hl->draw(get_canvas_item(), Size2(x, (header_height - menu_hl->get_height()) / 2));
- else
+ } else {
menu->draw(get_canvas_item(), Size2(x, (header_height - menu->get_height()) / 2));
+ }
}
// Draw the navigation buttons.
if (buttons_visible_cache) {
-
x -= increment->get_width();
if (last_tab_cache < tabs.size() - 1) {
draw_texture(highlight_arrow == 1 ? increment_hl : increment, Point2(x, (header_height - increment->get_height()) / 2));
@@ -429,7 +427,6 @@ void TabContainer::_notification(int p_what) {
}
} break;
case NOTIFICATION_THEME_CHANGED: {
-
minimum_size_changed();
call_deferred("_on_theme_changed"); // Wait until all changed theme.
} break;
@@ -451,11 +448,11 @@ void TabContainer::_on_mouse_exited() {
}
int TabContainer::_get_tab_width(int p_index) const {
-
ERR_FAIL_INDEX_V(p_index, get_tab_count(), 0);
Control *control = Object::cast_to<Control>(_get_tabs()[p_index]);
- if (!control || control->is_set_as_toplevel() || get_tab_hidden(p_index))
+ if (!control || control->is_set_as_toplevel() || get_tab_hidden(p_index)) {
return 0;
+ }
// Get the width of the text displayed on the tab.
Ref<Font> font = get_theme_font("font");
@@ -467,8 +464,9 @@ int TabContainer::_get_tab_width(int p_index) const {
Ref<Texture2D> icon = control->get_meta("_tab_icon");
if (icon.is_valid()) {
width += icon->get_width();
- if (text != "")
- width += get_theme_constant("hseparation");
+ if (text != "") {
+ width += get_theme_constant("icon_separation");
+ }
}
}
@@ -488,13 +486,12 @@ int TabContainer::_get_tab_width(int p_index) const {
}
Vector<Control *> TabContainer::_get_tabs() const {
-
Vector<Control *> controls;
for (int i = 0; i < get_child_count(); i++) {
-
Control *control = Object::cast_to<Control>(get_child(i));
- if (!control || control->is_toplevel_control())
+ if (!control || control->is_toplevel_control()) {
continue;
+ }
controls.push_back(control);
}
@@ -502,25 +499,25 @@ Vector<Control *> TabContainer::_get_tabs() const {
}
void TabContainer::_child_renamed_callback() {
-
update();
}
void TabContainer::add_child_notify(Node *p_child) {
-
Container::add_child_notify(p_child);
Control *c = Object::cast_to<Control>(p_child);
- if (!c)
+ if (!c) {
return;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
return;
+ }
bool first = false;
- if (get_tab_count() != 1)
+ if (get_tab_count() != 1) {
c->hide();
- else {
+ } else {
c->show();
//call_deferred("set_current_tab",0);
first = true;
@@ -528,8 +525,9 @@ void TabContainer::add_child_notify(Node *p_child) {
previous = 0;
}
c->set_anchors_and_margins_preset(Control::PRESET_WIDE);
- if (tabs_visible)
+ if (tabs_visible) {
c->set_margin(MARGIN_TOP, _get_top_margin());
+ }
Ref<StyleBox> sb = get_theme_stylebox("panel");
c->set_margin(Margin(MARGIN_TOP), c->get_margin(Margin(MARGIN_TOP)) + sb->get_margin(Margin(MARGIN_TOP)));
c->set_margin(Margin(MARGIN_LEFT), c->get_margin(Margin(MARGIN_LEFT)) + sb->get_margin(Margin(MARGIN_LEFT)));
@@ -538,17 +536,16 @@ void TabContainer::add_child_notify(Node *p_child) {
update();
p_child->connect("renamed", callable_mp(this, &TabContainer::_child_renamed_callback));
- if (first && is_inside_tree())
+ if (first && is_inside_tree()) {
emit_signal("tab_changed", current);
+ }
}
int TabContainer::get_tab_count() const {
-
return _get_tabs().size();
}
void TabContainer::set_current_tab(int p_current) {
-
ERR_FAIL_INDEX(p_current, get_tab_count());
int pending_previous = current;
@@ -557,27 +554,28 @@ void TabContainer::set_current_tab(int p_current) {
Ref<StyleBox> sb = get_theme_stylebox("panel");
Vector<Control *> tabs = _get_tabs();
for (int i = 0; i < tabs.size(); i++) {
-
Control *c = tabs[i];
if (i == current) {
c->show();
c->set_anchors_and_margins_preset(Control::PRESET_WIDE);
- if (tabs_visible)
+ if (tabs_visible) {
c->set_margin(MARGIN_TOP, _get_top_margin());
+ }
c->set_margin(Margin(MARGIN_TOP), c->get_margin(Margin(MARGIN_TOP)) + sb->get_margin(Margin(MARGIN_TOP)));
c->set_margin(Margin(MARGIN_LEFT), c->get_margin(Margin(MARGIN_LEFT)) + sb->get_margin(Margin(MARGIN_LEFT)));
c->set_margin(Margin(MARGIN_RIGHT), c->get_margin(Margin(MARGIN_RIGHT)) - sb->get_margin(Margin(MARGIN_RIGHT)));
c->set_margin(Margin(MARGIN_BOTTOM), c->get_margin(Margin(MARGIN_BOTTOM)) - sb->get_margin(Margin(MARGIN_BOTTOM)));
- } else
+ } else {
c->hide();
+ }
}
_change_notify("current_tab");
- if (pending_previous == current)
+ if (pending_previous == current) {
emit_signal("tab_selected", current);
- else {
+ } else {
previous = pending_previous;
emit_signal("tab_selected", current);
emit_signal("tab_changed", current);
@@ -587,35 +585,32 @@ void TabContainer::set_current_tab(int p_current) {
}
int TabContainer::get_current_tab() const {
-
return current;
}
int TabContainer::get_previous_tab() const {
-
return previous;
}
Control *TabContainer::get_tab_control(int p_idx) const {
-
Vector<Control *> tabs = _get_tabs();
- if (p_idx >= 0 && p_idx < tabs.size())
+ if (p_idx >= 0 && p_idx < tabs.size()) {
return tabs[p_idx];
- else
+ } else {
return nullptr;
+ }
}
Control *TabContainer::get_current_tab_control() const {
-
Vector<Control *> tabs = _get_tabs();
- if (current >= 0 && current < tabs.size())
+ if (current >= 0 && current < tabs.size()) {
return tabs[current];
- else
+ } else {
return nullptr;
+ }
}
void TabContainer::remove_child_notify(Node *p_child) {
-
Container::remove_child_notify(p_child);
call_deferred("_update_current_tab");
@@ -626,25 +621,27 @@ void TabContainer::remove_child_notify(Node *p_child) {
}
void TabContainer::_update_current_tab() {
-
int tc = get_tab_count();
- if (current >= tc)
+ if (current >= tc) {
current = tc - 1;
- if (current < 0)
+ }
+ if (current < 0) {
current = 0;
- else
+ } else {
set_current_tab(current);
+ }
}
Variant TabContainer::get_drag_data(const Point2 &p_point) {
-
- if (!drag_to_rearrange_enabled)
+ if (!drag_to_rearrange_enabled) {
return Variant();
+ }
int tab_over = get_tab_idx_at_point(p_point);
- if (tab_over < 0)
+ if (tab_over < 0) {
return Variant();
+ }
HBoxContainer *drag_preview = memnew(HBoxContainer);
@@ -666,16 +663,16 @@ Variant TabContainer::get_drag_data(const Point2 &p_point) {
}
bool TabContainer::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
-
- if (!drag_to_rearrange_enabled)
+ if (!drag_to_rearrange_enabled) {
return false;
+ }
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return false;
+ }
if (String(d["type"]) == "tabc_element") {
-
NodePath from_path = d["from_path"];
NodePath to_path = get_path();
if (from_path == to_path) {
@@ -693,24 +690,25 @@ bool TabContainer::can_drop_data(const Point2 &p_point, const Variant &p_data) c
}
void TabContainer::drop_data(const Point2 &p_point, const Variant &p_data) {
-
- if (!drag_to_rearrange_enabled)
+ if (!drag_to_rearrange_enabled) {
return;
+ }
int hover_now = get_tab_idx_at_point(p_point);
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return;
+ }
if (String(d["type"]) == "tabc_element") {
-
int tab_from_id = d["tabc_element"];
NodePath from_path = d["from_path"];
NodePath to_path = get_path();
if (from_path == to_path) {
- if (hover_now < 0)
+ if (hover_now < 0) {
hover_now = get_tab_count() - 1;
+ }
move_child(get_tab_control(tab_from_id), hover_now);
set_current_tab(hover_now);
} else if (get_tabs_rearrange_group() != -1) {
@@ -721,8 +719,9 @@ void TabContainer::drop_data(const Point2 &p_point, const Variant &p_data) {
Control *moving_tabc = from_tabc->get_tab_control(tab_from_id);
from_tabc->remove_child(moving_tabc);
add_child(moving_tabc);
- if (hover_now < 0)
+ if (hover_now < 0) {
hover_now = get_tab_count() - 1;
+ }
move_child(moving_tabc, hover_now);
set_current_tab(hover_now);
emit_signal("tab_changed", hover_now);
@@ -733,13 +732,14 @@ void TabContainer::drop_data(const Point2 &p_point, const Variant &p_data) {
}
int TabContainer::get_tab_idx_at_point(const Point2 &p_point) const {
-
- if (get_tab_count() == 0)
+ if (get_tab_count() == 0) {
return -1;
+ }
// must be on tabs in the tab header area.
- if (p_point.x < tabs_ofs_cache || p_point.y > _get_top_margin())
+ if (p_point.x < tabs_ofs_cache || p_point.y > _get_top_margin()) {
return -1;
+ }
Size2 size = get_size();
int right_ofs = 0;
@@ -772,7 +772,6 @@ int TabContainer::get_tab_idx_at_point(const Point2 &p_point) const {
}
void TabContainer::set_tab_align(TabAlign p_align) {
-
ERR_FAIL_INDEX(p_align, 3);
align = p_align;
update();
@@ -781,25 +780,24 @@ void TabContainer::set_tab_align(TabAlign p_align) {
}
TabContainer::TabAlign TabContainer::get_tab_align() const {
-
return align;
}
void TabContainer::set_tabs_visible(bool p_visible) {
-
- if (p_visible == tabs_visible)
+ if (p_visible == tabs_visible) {
return;
+ }
tabs_visible = p_visible;
Vector<Control *> tabs = _get_tabs();
for (int i = 0; i < tabs.size(); i++) {
-
Control *c = tabs[i];
- if (p_visible)
+ if (p_visible) {
c->set_margin(MARGIN_TOP, _get_top_margin());
- else
+ } else {
c->set_margin(MARGIN_TOP, 0);
+ }
}
update();
@@ -807,17 +805,14 @@ void TabContainer::set_tabs_visible(bool p_visible) {
}
bool TabContainer::are_tabs_visible() const {
-
return tabs_visible;
}
Control *TabContainer::_get_tab(int p_idx) const {
-
return get_tab_control(p_idx);
}
void TabContainer::set_tab_title(int p_tab, const String &p_title) {
-
Control *child = _get_tab(p_tab);
ERR_FAIL_COND(!child);
child->set_meta("_tab_name", p_title);
@@ -825,34 +820,33 @@ void TabContainer::set_tab_title(int p_tab, const String &p_title) {
}
String TabContainer::get_tab_title(int p_tab) const {
-
Control *child = _get_tab(p_tab);
ERR_FAIL_COND_V(!child, "");
- if (child->has_meta("_tab_name"))
+ if (child->has_meta("_tab_name")) {
return child->get_meta("_tab_name");
- else
+ } else {
return child->get_name();
+ }
}
void TabContainer::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) {
-
Control *child = _get_tab(p_tab);
ERR_FAIL_COND(!child);
child->set_meta("_tab_icon", p_icon);
update();
}
-Ref<Texture2D> TabContainer::get_tab_icon(int p_tab) const {
+Ref<Texture2D> TabContainer::get_tab_icon(int p_tab) const {
Control *child = _get_tab(p_tab);
ERR_FAIL_COND_V(!child, Ref<Texture2D>());
- if (child->has_meta("_tab_icon"))
+ if (child->has_meta("_tab_icon")) {
return child->get_meta("_tab_icon");
- else
+ } else {
return Ref<Texture2D>();
+ }
}
void TabContainer::set_tab_disabled(int p_tab, bool p_disabled) {
-
Control *child = _get_tab(p_tab);
ERR_FAIL_COND(!child);
child->set_meta("_tab_disabled", p_disabled);
@@ -860,17 +854,16 @@ void TabContainer::set_tab_disabled(int p_tab, bool p_disabled) {
}
bool TabContainer::get_tab_disabled(int p_tab) const {
-
Control *child = _get_tab(p_tab);
ERR_FAIL_COND_V(!child, false);
- if (child->has_meta("_tab_disabled"))
+ if (child->has_meta("_tab_disabled")) {
return child->get_meta("_tab_disabled");
- else
+ } else {
return false;
+ }
}
void TabContainer::set_tab_hidden(int p_tab, bool p_hidden) {
-
Control *child = _get_tab(p_tab);
ERR_FAIL_COND(!child);
child->set_meta("_tab_hidden", p_hidden);
@@ -890,43 +883,42 @@ void TabContainer::set_tab_hidden(int p_tab, bool p_hidden) {
}
bool TabContainer::get_tab_hidden(int p_tab) const {
-
Control *child = _get_tab(p_tab);
ERR_FAIL_COND_V(!child, false);
- if (child->has_meta("_tab_hidden"))
+ if (child->has_meta("_tab_hidden")) {
return child->get_meta("_tab_hidden");
- else
+ } else {
return false;
+ }
}
void TabContainer::get_translatable_strings(List<String> *p_strings) const {
-
Vector<Control *> tabs = _get_tabs();
for (int i = 0; i < tabs.size(); i++) {
-
Control *c = tabs[i];
- if (!c->has_meta("_tab_name"))
+ if (!c->has_meta("_tab_name")) {
continue;
+ }
String name = c->get_meta("_tab_name");
- if (name != "")
+ if (name != "") {
p_strings->push_back(name);
+ }
}
}
Size2 TabContainer::get_minimum_size() const {
-
Size2 ms;
Vector<Control *> tabs = _get_tabs();
for (int i = 0; i < tabs.size(); i++) {
-
Control *c = tabs[i];
- if (!c->is_visible_in_tree() && !use_hidden_tabs_for_min_size)
+ if (!c->is_visible_in_tree() && !use_hidden_tabs_for_min_size) {
continue;
+ }
Size2 cms = c->get_combined_minimum_size();
ms.x = MAX(ms.x, cms.x);
@@ -966,6 +958,7 @@ void TabContainer::set_drag_to_rearrange_enabled(bool p_enabled) {
bool TabContainer::get_drag_to_rearrange_enabled() const {
return drag_to_rearrange_enabled;
}
+
void TabContainer::set_tabs_rearrange_group(int p_group_id) {
tabs_rearrange_group = p_group_id;
}
@@ -983,7 +976,6 @@ bool TabContainer::get_use_hidden_tabs_for_min_size() const {
}
void TabContainer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &TabContainer::_gui_input);
ClassDB::bind_method(D_METHOD("get_tab_count"), &TabContainer::get_tab_count);
ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &TabContainer::set_current_tab);
@@ -1030,7 +1022,6 @@ void TabContainer::_bind_methods() {
}
TabContainer::TabContainer() {
-
first_tab_cache = 0;
last_tab_cache = 0;
buttons_visible_cache = false;
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index 38c029475c..e8cde74c83 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -34,7 +34,6 @@
#include "scene/gui/container.h"
#include "scene/gui/popup.h"
class TabContainer : public Container {
-
GDCLASS(TabContainer, Container);
public:
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index 1a3b53f489..8f71aa7cab 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -36,7 +36,6 @@
#include "scene/gui/texture_rect.h"
Size2 Tabs::get_minimum_size() const {
-
Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg");
Ref<StyleBox> tab_fg = get_theme_stylebox("tab_fg");
Ref<StyleBox> tab_disabled = get_theme_stylebox("tab_disabled");
@@ -45,22 +44,23 @@ Size2 Tabs::get_minimum_size() const {
Size2 ms(0, MAX(MAX(tab_bg->get_minimum_size().height, tab_fg->get_minimum_size().height), tab_disabled->get_minimum_size().height) + font->get_height());
for (int i = 0; i < tabs.size(); i++) {
-
Ref<Texture2D> tex = tabs[i].icon;
if (tex.is_valid()) {
ms.height = MAX(ms.height, tex->get_size().height);
- if (tabs[i].text != "")
+ if (tabs[i].text != "") {
ms.width += get_theme_constant("hseparation");
+ }
}
ms.width += Math::ceil(font->get_string_size(tabs[i].xl_text).width);
- if (tabs[i].disabled)
+ if (tabs[i].disabled) {
ms.width += tab_disabled->get_minimum_size().width;
- else if (current == i)
+ } else if (current == i) {
ms.width += tab_fg->get_minimum_size().width;
- else
+ } else {
ms.width += tab_bg->get_minimum_size().width;
+ }
if (tabs[i].right_button.is_valid()) {
Ref<Texture2D> rb = tabs[i].right_button;
@@ -84,16 +84,13 @@ Size2 Tabs::get_minimum_size() const {
}
void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
-
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
Point2 pos = mm->get_position();
highlight_arrow = -1;
if (buttons_visible) {
-
Ref<Texture2D> incr = get_theme_icon("increment");
Ref<Texture2D> decr = get_theme_icon("decrement");
@@ -114,9 +111,7 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
-
if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP && !mb->get_command()) {
-
if (scrolling_enabled && buttons_visible) {
if (offset > 0) {
offset--;
@@ -135,7 +130,6 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
}
if (rb_pressing && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
if (rb_hover != -1) {
//pressed
emit_signal("right_button_pressed", rb_hover);
@@ -146,7 +140,6 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
}
if (cb_pressing && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
if (cb_hover != -1) {
//pressed
emit_signal("tab_close", cb_hover);
@@ -157,12 +150,10 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
}
if (mb->is_pressed() && (mb->get_button_index() == BUTTON_LEFT || (select_with_rmb && mb->get_button_index() == BUTTON_RIGHT))) {
-
// clicks
Point2 pos(mb->get_position().x, mb->get_position().y);
if (buttons_visible) {
-
Ref<Texture2D> incr = get_theme_icon("increment");
Ref<Texture2D> decr = get_theme_icon("decrement");
@@ -185,7 +176,6 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
int found = -1;
for (int i = offset; i < tabs.size(); i++) {
-
if (tabs[i].rb_rect.has_point(pos)) {
rb_pressing = true;
update();
@@ -207,7 +197,6 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
}
if (found != -1) {
-
set_current_tab(found);
emit_signal("tab_clicked", found);
}
@@ -216,9 +205,7 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
}
void Tabs::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_TRANSLATION_CHANGED: {
for (int i = 0; i < tabs.size(); ++i) {
tabs.write[i].xl_text = tr(tabs[i].text);
@@ -249,7 +236,6 @@ void Tabs::_notification(int p_what) {
int mw = 0;
for (int i = 0; i < tabs.size(); i++) {
-
tabs.write[i].ofs_cache = mw;
mw += get_tab_width(i);
}
@@ -274,7 +260,6 @@ void Tabs::_notification(int p_what) {
missing_right = false;
for (int i = offset; i < tabs.size(); i++) {
-
tabs.write[i].ofs_cache = w;
int lsize = tabs[i].size_cache;
@@ -309,10 +294,10 @@ void Tabs::_notification(int p_what) {
Size2i sb_ms = sb->get_minimum_size();
Ref<Texture2D> icon = tabs[i].icon;
if (icon.is_valid()) {
-
icon->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2));
- if (tabs[i].text != "")
+ if (tabs[i].text != "") {
w += icon->get_width() + get_theme_constant("hseparation");
+ }
}
font->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - font->get_height()) / 2 + font->get_ascent()), tabs[i].xl_text, col, tabs[i].size_text);
@@ -320,7 +305,6 @@ void Tabs::_notification(int p_what) {
w += tabs[i].size_text;
if (tabs[i].right_button.is_valid()) {
-
Ref<StyleBox> style = get_theme_stylebox("button");
Ref<Texture2D> rb = tabs[i].right_button;
@@ -332,10 +316,11 @@ void Tabs::_notification(int p_what) {
rb_rect.position.y = sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - (rb_rect.size.y)) / 2;
if (rb_hover == i) {
- if (rb_pressing)
+ if (rb_pressing) {
get_theme_stylebox("button_pressed")->draw(ci, rb_rect);
- else
+ } else {
style->draw(ci, rb_rect);
+ }
}
rb->draw(ci, Point2i(w + style->get_margin(MARGIN_LEFT), rb_rect.position.y + style->get_margin(MARGIN_TOP)));
@@ -344,7 +329,6 @@ void Tabs::_notification(int p_what) {
}
if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) {
-
Ref<StyleBox> style = get_theme_stylebox("button");
Ref<Texture2D> cb = close;
@@ -356,10 +340,11 @@ void Tabs::_notification(int p_what) {
cb_rect.position.y = sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - (cb_rect.size.y)) / 2;
if (!tabs[i].disabled && cb_hover == i) {
- if (cb_pressing)
+ if (cb_pressing) {
get_theme_stylebox("button_pressed")->draw(ci, cb_rect);
- else
+ } else {
style->draw(ci, cb_rect);
+ }
}
cb->draw(ci, Point2i(w + style->get_margin(MARGIN_LEFT), cb_rect.position.y + style->get_margin(MARGIN_TOP)));
@@ -371,18 +356,19 @@ void Tabs::_notification(int p_what) {
}
if (offset > 0 || missing_right) {
-
int vofs = (get_size().height - incr->get_size().height) / 2;
- if (offset > 0)
+ if (offset > 0) {
draw_texture(highlight_arrow == 0 ? decr_hl : decr, Point2(limit, vofs));
- else
+ } else {
draw_texture(decr, Point2(limit, vofs), Color(1, 1, 1, 0.5));
+ }
- if (missing_right)
+ if (missing_right) {
draw_texture(highlight_arrow == 1 ? incr_hl : incr, Point2(limit + decr->get_size().width, vofs));
- else
+ } else {
draw_texture(incr, Point2(limit + decr->get_size().width, vofs), Color(1, 1, 1, 0.5));
+ }
buttons_visible = true;
} else {
@@ -393,13 +379,13 @@ void Tabs::_notification(int p_what) {
}
int Tabs::get_tab_count() const {
-
return tabs.size();
}
void Tabs::set_current_tab(int p_current) {
-
- if (current == p_current) return;
+ if (current == p_current) {
+ return;
+ }
ERR_FAIL_INDEX(p_current, get_tab_count());
current = p_current;
@@ -412,7 +398,6 @@ void Tabs::set_current_tab(int p_current) {
}
int Tabs::get_current_tab() const {
-
return current;
}
@@ -429,7 +414,6 @@ bool Tabs::get_offset_buttons_visible() const {
}
void Tabs::set_tab_title(int p_tab, const String &p_title) {
-
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].text = p_title;
tabs.write[p_tab].xl_text = tr(p_title);
@@ -438,13 +422,11 @@ void Tabs::set_tab_title(int p_tab, const String &p_title) {
}
String Tabs::get_tab_title(int p_tab) const {
-
ERR_FAIL_INDEX_V(p_tab, tabs.size(), "");
return tabs[p_tab].text;
}
void Tabs::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) {
-
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].icon = p_icon;
update();
@@ -452,39 +434,35 @@ void Tabs::set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon) {
}
Ref<Texture2D> Tabs::get_tab_icon(int p_tab) const {
-
ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture2D>());
return tabs[p_tab].icon;
}
void Tabs::set_tab_disabled(int p_tab, bool p_disabled) {
-
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].disabled = p_disabled;
update();
}
-bool Tabs::get_tab_disabled(int p_tab) const {
+bool Tabs::get_tab_disabled(int p_tab) const {
ERR_FAIL_INDEX_V(p_tab, tabs.size(), false);
return tabs[p_tab].disabled;
}
void Tabs::set_tab_right_button(int p_tab, const Ref<Texture2D> &p_right_button) {
-
ERR_FAIL_INDEX(p_tab, tabs.size());
tabs.write[p_tab].right_button = p_right_button;
_update_cache();
update();
minimum_size_changed();
}
-Ref<Texture2D> Tabs::get_tab_right_button(int p_tab) const {
+Ref<Texture2D> Tabs::get_tab_right_button(int p_tab) const {
ERR_FAIL_INDEX_V(p_tab, tabs.size(), Ref<Texture2D>());
return tabs[p_tab].right_button;
}
void Tabs::_update_hover() {
-
if (!is_inside_tree()) {
return;
}
@@ -494,7 +472,6 @@ void Tabs::_update_hover() {
int hover_now = -1;
int hover_buttons = -1;
for (int i = offset; i < tabs.size(); i++) {
-
Rect2 rect = get_tab_rect(i);
if (rect.has_point(pos)) {
hover_now = i;
@@ -551,7 +528,6 @@ void Tabs::_update_cache() {
m_width = MAX((limit - size_fixed) / count_resize, min_width);
}
for (int i = offset; i < tabs.size(); i++) {
-
Ref<StyleBox> sb;
if (tabs[i].disabled) {
sb = tab_disabled;
@@ -586,7 +562,6 @@ void Tabs::_update_cache() {
}
void Tabs::_on_mouse_exited() {
-
rb_hover = -1;
cb_hover = -1;
hover = -1;
@@ -595,7 +570,6 @@ void Tabs::_on_mouse_exited() {
}
void Tabs::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) {
-
Tab t;
t.text = p_str;
t.xl_text = tr(p_str);
@@ -619,33 +593,36 @@ void Tabs::clear_tabs() {
}
void Tabs::remove_tab(int p_idx) {
-
ERR_FAIL_INDEX(p_idx, tabs.size());
tabs.remove(p_idx);
- if (current >= p_idx)
+ if (current >= p_idx) {
current--;
+ }
_update_cache();
call_deferred("_update_hover");
update();
minimum_size_changed();
- if (current < 0)
+ if (current < 0) {
current = 0;
- if (current >= tabs.size())
+ }
+ if (current >= tabs.size()) {
current = tabs.size() - 1;
+ }
_ensure_no_over_offset();
}
Variant Tabs::get_drag_data(const Point2 &p_point) {
-
- if (!drag_to_rearrange_enabled)
+ if (!drag_to_rearrange_enabled) {
return Variant();
+ }
int tab_over = get_tab_idx_at_point(p_point);
- if (tab_over < 0)
+ if (tab_over < 0) {
return Variant();
+ }
HBoxContainer *drag_preview = memnew(HBoxContainer);
@@ -671,16 +648,16 @@ Variant Tabs::get_drag_data(const Point2 &p_point) {
}
bool Tabs::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
-
- if (!drag_to_rearrange_enabled)
+ if (!drag_to_rearrange_enabled) {
return false;
+ }
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return false;
+ }
if (String(d["type"]) == "tab_element") {
-
NodePath from_path = d["from_path"];
NodePath to_path = get_path();
if (from_path == to_path) {
@@ -698,24 +675,25 @@ bool Tabs::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
}
void Tabs::drop_data(const Point2 &p_point, const Variant &p_data) {
-
- if (!drag_to_rearrange_enabled)
+ if (!drag_to_rearrange_enabled) {
return;
+ }
int hover_now = get_tab_idx_at_point(p_point);
Dictionary d = p_data;
- if (!d.has("type"))
+ if (!d.has("type")) {
return;
+ }
if (String(d["type"]) == "tab_element") {
-
int tab_from_id = d["tab_element"];
NodePath from_path = d["from_path"];
NodePath to_path = get_path();
if (from_path == to_path) {
- if (hover_now < 0)
+ if (hover_now < 0) {
hover_now = get_tab_count() - 1;
+ }
move_tab(tab_from_id, hover_now);
emit_signal("reposition_active_tab_request", hover_now);
set_current_tab(hover_now);
@@ -724,11 +702,13 @@ void Tabs::drop_data(const Point2 &p_point, const Variant &p_data) {
Node *from_node = get_node(from_path);
Tabs *from_tabs = Object::cast_to<Tabs>(from_node);
if (from_tabs && from_tabs->get_tabs_rearrange_group() == get_tabs_rearrange_group()) {
- if (tab_from_id >= from_tabs->get_tab_count())
+ if (tab_from_id >= from_tabs->get_tab_count()) {
return;
+ }
Tab moving_tab = from_tabs->tabs[tab_from_id];
- if (hover_now < 0)
+ if (hover_now < 0) {
hover_now = get_tab_count();
+ }
tabs.insert(hover_now, moving_tab);
from_tabs->remove_tab(tab_from_id);
set_current_tab(hover_now);
@@ -741,10 +721,8 @@ void Tabs::drop_data(const Point2 &p_point, const Variant &p_data) {
}
int Tabs::get_tab_idx_at_point(const Point2 &p_point) const {
-
int hover_now = -1;
for (int i = offset; i < tabs.size(); i++) {
-
Rect2 rect = get_tab_rect(i);
if (rect.has_point(p_point)) {
hover_now = i;
@@ -755,21 +733,19 @@ int Tabs::get_tab_idx_at_point(const Point2 &p_point) const {
}
void Tabs::set_tab_align(TabAlign p_align) {
-
ERR_FAIL_INDEX(p_align, ALIGN_MAX);
tab_align = p_align;
update();
}
Tabs::TabAlign Tabs::get_tab_align() const {
-
return tab_align;
}
void Tabs::move_tab(int from, int to) {
-
- if (from == to)
+ if (from == to) {
return;
+ }
ERR_FAIL_INDEX(from, tabs.size());
ERR_FAIL_INDEX(to, tabs.size());
@@ -783,7 +759,6 @@ void Tabs::move_tab(int from, int to) {
}
int Tabs::get_tab_width(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, tabs.size(), 0);
Ref<StyleBox> tab_bg = get_theme_stylebox("tab_bg");
@@ -796,18 +771,20 @@ int Tabs::get_tab_width(int p_idx) const {
Ref<Texture2D> tex = tabs[p_idx].icon;
if (tex.is_valid()) {
x += tex->get_width();
- if (tabs[p_idx].text != "")
+ if (tabs[p_idx].text != "") {
x += get_theme_constant("hseparation");
+ }
}
x += Math::ceil(font->get_string_size(tabs[p_idx].xl_text).width);
- if (tabs[p_idx].disabled)
+ if (tabs[p_idx].disabled) {
x += tab_disabled->get_minimum_size().width;
- else if (current == p_idx)
+ } else if (current == p_idx) {
x += tab_fg->get_minimum_size().width;
- else
+ } else {
x += tab_bg->get_minimum_size().width;
+ }
if (tabs[p_idx].right_button.is_valid()) {
Ref<Texture2D> rb = tabs[p_idx].right_button;
@@ -825,9 +802,9 @@ int Tabs::get_tab_width(int p_idx) const {
}
void Tabs::_ensure_no_over_offset() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
Ref<Texture2D> incr = get_theme_icon("increment");
Ref<Texture2D> decr = get_theme_icon("decrement");
@@ -835,10 +812,8 @@ void Tabs::_ensure_no_over_offset() {
int limit = get_size().width - incr->get_width() - decr->get_width();
while (offset > 0) {
-
int total_w = 0;
for (int i = offset - 1; i < tabs.size(); i++) {
-
total_w += tabs[i].size_cache;
}
@@ -852,11 +827,13 @@ void Tabs::_ensure_no_over_offset() {
}
void Tabs::ensure_tab_visible(int p_idx) {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
- if (tabs.size() == 0) return;
+ if (tabs.size() == 0) {
+ return;
+ }
ERR_FAIL_INDEX(p_idx, tabs.size());
if (p_idx == offset) {
@@ -884,20 +861,17 @@ void Tabs::ensure_tab_visible(int p_idx) {
}
Rect2 Tabs::get_tab_rect(int p_tab) const {
-
ERR_FAIL_INDEX_V(p_tab, tabs.size(), Rect2());
return Rect2(tabs[p_tab].ofs_cache, 0, tabs[p_tab].size_cache, get_size().height);
}
void Tabs::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) {
-
ERR_FAIL_INDEX(p_policy, CLOSE_BUTTON_MAX);
cb_displaypolicy = p_policy;
update();
}
Tabs::CloseButtonDisplayPolicy Tabs::get_tab_close_display_policy() const {
-
return cb_displaypolicy;
}
@@ -920,6 +894,7 @@ void Tabs::set_drag_to_rearrange_enabled(bool p_enabled) {
bool Tabs::get_drag_to_rearrange_enabled() const {
return drag_to_rearrange_enabled;
}
+
void Tabs::set_tabs_rearrange_group(int p_group_id) {
tabs_rearrange_group = p_group_id;
}
@@ -937,7 +912,6 @@ bool Tabs::get_select_with_rmb() const {
}
void Tabs::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &Tabs::_gui_input);
ClassDB::bind_method(D_METHOD("_update_hover"), &Tabs::_update_hover);
ClassDB::bind_method(D_METHOD("get_tab_count"), &Tabs::get_tab_count);
@@ -995,7 +969,6 @@ void Tabs::_bind_methods() {
}
Tabs::Tabs() {
-
current = 0;
tab_align = ALIGN_CENTER;
rb_hover = -1;
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index 3170acb46f..8757f70ebe 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -34,7 +34,6 @@
#include "scene/gui/control.h"
class Tabs : public Control {
-
GDCLASS(Tabs, Control);
public:
@@ -56,7 +55,6 @@ public:
private:
struct Tab {
-
String text;
String xl_text;
Ref<Texture2D> icon;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 36e35897d1..e050b3f174 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -30,7 +30,7 @@
#include "text_edit.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/message_queue.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
@@ -45,12 +45,10 @@
#define TAB_PIXELS
inline bool _is_symbol(CharType c) {
-
return is_symbol(c);
}
static bool _is_text_char(CharType c) {
-
return !is_symbol(c);
}
@@ -59,7 +57,6 @@ static bool _is_whitespace(CharType c) {
}
static bool _is_char(CharType c) {
-
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
}
@@ -92,38 +89,41 @@ static bool _is_pair_symbol(CharType c) {
}
static CharType _get_right_pair_symbol(CharType c) {
- if (c == '"')
+ if (c == '"') {
return '"';
- if (c == '\'')
+ }
+ if (c == '\'') {
return '\'';
- if (c == '(')
+ }
+ if (c == '(') {
return ')';
- if (c == '[')
+ }
+ if (c == '[') {
return ']';
- if (c == '{')
+ }
+ if (c == '{') {
return '}';
+ }
return 0;
}
static int _find_first_non_whitespace_column_of_line(const String &line) {
int left = 0;
- while (left < line.length() && _is_whitespace(line[left]))
+ while (left < line.length() && _is_whitespace(line[left])) {
left++;
+ }
return left;
}
void TextEdit::Text::set_font(const Ref<Font> &p_font) {
-
font = p_font;
}
void TextEdit::Text::set_indent_size(int p_indent_size) {
-
indent_size = p_indent_size;
}
void TextEdit::Text::_update_line_cache(int p_line) const {
-
int w = 0;
int len = text[p_line].data.length();
@@ -144,9 +144,9 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
text.write[p_line].region_info.clear();
for (int i = 0; i < len; i++) {
-
- if (!_is_symbol(str[i]))
+ if (!_is_symbol(str[i])) {
continue;
+ }
if (str[i] == '\\') {
i++; // Skip quoted anything.
continue;
@@ -155,7 +155,6 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
int left = len - i;
for (int j = 0; j < color_regions->size(); j++) {
-
const ColorRegion &cr = color_regions->operator[](j);
/* BEGIN */
@@ -177,7 +176,6 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
}
if (match) {
-
ColorRegionInfo cri;
cri.end = false;
cri.region = j;
@@ -204,7 +202,6 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
}
if (match) {
-
ColorRegionInfo cri;
cri.end = true;
cri.region = j;
@@ -219,7 +216,6 @@ void TextEdit::Text::_update_line_cache(int p_line) const {
}
const Map<int, TextEdit::Text::ColorRegionInfo> &TextEdit::Text::get_color_region_info(int p_line) const {
-
static Map<int, ColorRegionInfo> cri;
ERR_FAIL_INDEX_V(p_line, text.size(), cri);
@@ -231,7 +227,6 @@ const Map<int, TextEdit::Text::ColorRegionInfo> &TextEdit::Text::get_color_regio
}
int TextEdit::Text::get_line_width(int p_line) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), -1);
if (text[p_line].width_cache == -1) {
@@ -242,28 +237,24 @@ int TextEdit::Text::get_line_width(int p_line) const {
}
void TextEdit::Text::set_line_wrap_amount(int p_line, int p_wrap_amount) const {
-
ERR_FAIL_INDEX(p_line, text.size());
text.write[p_line].wrap_amount_cache = p_wrap_amount;
}
int TextEdit::Text::get_line_wrap_amount(int p_line) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), -1);
return text[p_line].wrap_amount_cache;
}
void TextEdit::Text::clear_width_cache() {
-
for (int i = 0; i < text.size(); i++) {
text.write[i].width_cache = -1;
}
}
void TextEdit::Text::clear_wrap_cache() {
-
for (int i = 0; i < text.size(); i++) {
text.write[i].wrap_amount_cache = -1;
}
@@ -276,7 +267,6 @@ void TextEdit::Text::clear_info_icons() {
}
void TextEdit::Text::clear() {
-
text.clear();
insert(0, "");
}
@@ -286,14 +276,14 @@ int TextEdit::Text::get_max_width(bool p_exclude_hidden) const {
int max = 0;
for (int i = 0; i < text.size(); i++) {
- if (!p_exclude_hidden || !is_hidden(i))
+ if (!p_exclude_hidden || !is_hidden(i)) {
max = MAX(max, get_line_width(i));
+ }
}
return max;
}
void TextEdit::Text::set(int p_line, const String &p_text) {
-
ERR_FAIL_INDEX(p_line, text.size());
text.write[p_line].width_cache = -1;
@@ -302,7 +292,6 @@ void TextEdit::Text::set(int p_line, const String &p_text) {
}
void TextEdit::Text::insert(int p_at, const String &p_text) {
-
Line line;
line.marked = false;
line.safe = false;
@@ -315,32 +304,29 @@ void TextEdit::Text::insert(int p_at, const String &p_text) {
line.data = p_text;
text.insert(p_at, line);
}
-void TextEdit::Text::remove(int p_at) {
+void TextEdit::Text::remove(int p_at) {
text.remove(p_at);
}
int TextEdit::Text::get_char_width(CharType c, CharType next_c, int px) const {
-
int tab_w = font->get_char_size(' ').width * indent_size;
int w = 0;
if (c == '\t') {
-
int left = px % tab_w;
- if (left == 0)
+ if (left == 0) {
w = tab_w;
- else
+ } else {
w = tab_w - px % tab_w; // Is right.
+ }
} else {
-
w = font->get_char_size(c, next_c).width;
}
return w;
}
void TextEdit::_update_scrollbars() {
-
Size2 size = get_size();
Size2 hmin = h_scroll->get_combined_minimum_size();
Size2 vmin = v_scroll->get_combined_minimum_size();
@@ -360,8 +346,9 @@ void TextEdit::_update_scrollbars() {
int visible_width = size.width - cache.style_normal->get_minimum_size().width;
int total_width = text.get_max_width(true) + vmin.x;
- if (line_numbers)
+ if (line_numbers) {
total_width += cache.line_number_w;
+ }
if (draw_breakpoint_gutter || draw_bookmark_gutter) {
total_width += cache.breakpoint_gutter_width;
@@ -384,11 +371,9 @@ void TextEdit::_update_scrollbars() {
// Thanks yessopie for this clever bit of logic.
if (total_rows <= visible_rows && total_width <= visible_width) {
-
use_hscroll = false;
use_vscroll = false;
} else {
-
if (total_rows > visible_rows && total_width <= visible_width) {
use_hscroll = false;
}
@@ -401,7 +386,6 @@ void TextEdit::_update_scrollbars() {
updating_scrolls = true;
if (use_vscroll) {
-
v_scroll->show();
v_scroll->set_max(total_rows + get_visible_rows_offset());
v_scroll->set_page(visible_rows + get_visible_rows_offset());
@@ -413,7 +397,6 @@ void TextEdit::_update_scrollbars() {
set_v_scroll(get_v_scroll());
} else {
-
cursor.line_ofs = 0;
cursor.wrap_ofs = 0;
v_scroll->set_value(0);
@@ -421,18 +404,17 @@ void TextEdit::_update_scrollbars() {
}
if (use_hscroll && !is_wrap_enabled()) {
-
h_scroll->show();
h_scroll->set_max(total_width);
h_scroll->set_page(visible_width);
- if (cursor.x_ofs > (total_width - visible_width))
+ if (cursor.x_ofs > (total_width - visible_width)) {
cursor.x_ofs = (total_width - visible_width);
+ }
if (fabs(h_scroll->get_value() - (double)cursor.x_ofs) >= 1) {
h_scroll->set_value(cursor.x_ofs);
}
} else {
-
cursor.x_ofs = 0;
h_scroll->set_value(0);
h_scroll->hide();
@@ -442,11 +424,10 @@ void TextEdit::_update_scrollbars() {
}
void TextEdit::_click_selection_held() {
-
// Warning: is_mouse_button_pressed(BUTTON_LEFT) returns false for double+ clicks, so this doesn't work for MODE_WORD
// and MODE_LINE. However, moving the mouse triggers _gui_input, which calls these functions too, so that's not a huge problem.
// I'm unsure if there's an actual fix that doesn't have a ton of side effects.
- if (InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != Selection::MODE_NONE) {
+ if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT) && selection.selecting_mode != Selection::MODE_NONE) {
switch (selection.selecting_mode) {
case Selection::MODE_POINTER: {
_update_selection_mode_pointer();
@@ -597,7 +578,6 @@ void TextEdit::_update_minimap_click() {
}
void TextEdit::_update_minimap_drag() {
-
if (!can_drag_minimap) {
return;
}
@@ -614,14 +594,15 @@ void TextEdit::_update_minimap_drag() {
}
void TextEdit::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
_update_caches();
- if (cursor_changed_dirty)
+ if (cursor_changed_dirty) {
MessageQueue::get_singleton()->push_call(this, "_cursor_changed_emit");
- if (text_changed_dirty)
+ }
+ if (text_changed_dirty) {
MessageQueue::get_singleton()->push_call(this, "_text_changed_emit");
+ }
_update_wrap_at();
} break;
case NOTIFICATION_RESIZED: {
@@ -718,7 +699,6 @@ void TextEdit::_notification(int p_what) {
};
if (line_numbers) {
-
line_number_char_count = cache.line_number_w;
cache.line_number_w = (cache.line_number_w + 1) * cache.font->get_char_size('0').width;
} else {
@@ -738,8 +718,9 @@ void TextEdit::_notification(int p_what) {
cache.style_readonly->draw(ci, Rect2(Point2(), size));
draw_caret = false;
}
- if (has_focus())
+ if (has_focus()) {
cache.style_focus->draw(ci, Rect2(Point2(), size));
+ }
int ascent = cache.font->get_ascent();
@@ -778,7 +759,6 @@ void TextEdit::_notification(int p_what) {
bool brace_close_mismatch = false;
if (brace_matching_enabled && cursor.line >= 0 && cursor.line < text.size() && cursor.column >= 0) {
-
if (cursor.column < text[cursor.line].length()) {
// Check for open.
CharType c = text[cursor.line][cursor.column];
@@ -793,14 +773,11 @@ void TextEdit::_notification(int p_what) {
}
if (closec != 0) {
-
int stack = 1;
for (int i = cursor.line; i < text.size(); i++) {
-
int from = i == cursor.line ? cursor.column + 1 : 0;
for (int j = from; j < text[i].length(); j++) {
-
CharType cc = text[i][j];
// Ignore any brackets inside a string.
if (cc == '"' || cc == '\'') {
@@ -824,10 +801,11 @@ void TextEdit::_notification(int p_what) {
}
}
} while (cc != quotation);
- } else if (cc == c)
+ } else if (cc == c) {
stack++;
- else if (cc == closec)
+ } else if (cc == closec) {
stack--;
+ }
if (stack == 0) {
brace_open_match_line = i;
@@ -837,12 +815,14 @@ void TextEdit::_notification(int p_what) {
break;
}
}
- if (brace_open_match_line != -1)
+ if (brace_open_match_line != -1) {
break;
+ }
}
- if (!brace_open_matching)
+ if (!brace_open_matching) {
brace_open_mismatch = true;
+ }
}
}
@@ -859,14 +839,11 @@ void TextEdit::_notification(int p_what) {
}
if (closec != 0) {
-
int stack = 1;
for (int i = cursor.line; i >= 0; i--) {
-
int from = i == cursor.line ? cursor.column - 2 : text[i].length() - 1;
for (int j = from; j >= 0; j--) {
-
CharType cc = text[i][j];
// Ignore any brackets inside a string.
if (cc == '"' || cc == '\'') {
@@ -890,10 +867,11 @@ void TextEdit::_notification(int p_what) {
}
}
} while (cc != quotation);
- } else if (cc == c)
+ } else if (cc == c) {
stack++;
- else if (cc == closec)
+ } else if (cc == closec) {
stack--;
+ }
if (stack == 0) {
brace_close_match_line = i;
@@ -903,12 +881,14 @@ void TextEdit::_notification(int p_what) {
break;
}
}
- if (brace_close_match_line != -1)
+ if (brace_close_match_line != -1) {
break;
+ }
}
- if (!brace_close_matching)
+ if (!brace_close_matching) {
brace_close_mismatch = true;
+ }
}
}
}
@@ -941,7 +921,7 @@ void TextEdit::_notification(int p_what) {
// calculate viewport size and y offset
int viewport_height = (draw_amount - 1) * minimap_line_height;
int control_height = _get_control_height() - viewport_height;
- int viewport_offset_y = round(get_scroll_pos_for_line(first_visible_line) * control_height) / ((v_scroll->get_max() <= minimap_visible_lines) ? (minimap_visible_lines - draw_amount) : (v_scroll->get_max() - draw_amount));
+ int viewport_offset_y = round(get_scroll_pos_for_line(first_visible_line + 1) * control_height) / ((v_scroll->get_max() <= minimap_visible_lines) ? (minimap_visible_lines - draw_amount) : (v_scroll->get_max() - draw_amount));
// calculate the first line.
int num_lines_before = round((viewport_offset_y) / minimap_line_height);
@@ -957,7 +937,6 @@ void TextEdit::_notification(int p_what) {
Color viewport_color = (cache.background_color.get_v() < 0.5) ? Color(1, 1, 1, 0.1) : Color(0, 0, 0, 0.1);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2((xmargin_end + 2), viewport_offset_y, cache.minimap_width, viewport_height), viewport_color);
for (int i = 0; i < minimap_draw_amount; i++) {
-
minimap_line++;
if (minimap_line < 0 || minimap_line >= (int)text.size()) {
@@ -992,8 +971,9 @@ void TextEdit::_notification(int p_what) {
for (int line_wrap_index = 0; line_wrap_index < line_wrap_amount + 1; line_wrap_index++) {
if (line_wrap_index != 0) {
i++;
- if (i >= minimap_draw_amount)
+ if (i >= minimap_draw_amount) {
break;
+ }
}
const String &str = wrap_rows[line_wrap_index];
@@ -1064,11 +1044,6 @@ void TextEdit::_notification(int p_what) {
break;
}
- // re-adjust if we went backwards.
- if (color != previous_color && !is_whitespace) {
- characters++;
- }
-
if (str[j] == '\t') {
tabs += minimap_tab_size;
}
@@ -1083,11 +1058,11 @@ void TextEdit::_notification(int p_what) {
// draw main text
int line = first_visible_line;
for (int i = 0; i < draw_amount; i++) {
-
line++;
- if (line < 0 || line >= (int)text.size())
+ if (line < 0 || line >= (int)text.size()) {
continue;
+ }
while (is_line_hidden(line)) {
line++;
@@ -1096,8 +1071,9 @@ void TextEdit::_notification(int p_what) {
}
}
- if (line < 0 || line >= (int)text.size())
+ if (line < 0 || line >= (int)text.size()) {
continue;
+ }
const String &fullstr = text[line];
@@ -1117,8 +1093,9 @@ void TextEdit::_notification(int p_what) {
for (int line_wrap_index = 0; line_wrap_index < line_wrap_amount + 1; line_wrap_index++) {
if (line_wrap_index != 0) {
i++;
- if (i >= draw_amount)
+ if (i >= draw_amount) {
break;
+ }
}
const String &str = wrap_rows[line_wrap_index];
@@ -1127,8 +1104,9 @@ void TextEdit::_notification(int p_what) {
indent_px = 0;
}
- if (line_wrap_index > 0)
+ if (line_wrap_index > 0) {
last_wrap_column += wrap_rows[line_wrap_index - 1].length();
+ }
int char_margin = xmargin_beg - cursor.x_ofs;
char_margin += indent_px;
@@ -1143,22 +1121,23 @@ void TextEdit::_notification(int p_what) {
int ofs_y = (i * get_row_height() + cache.line_spacing / 2) + ofs_readonly;
ofs_y -= cursor.wrap_ofs * get_row_height();
- if (smooth_scroll_enabled)
- ofs_y += (-get_v_scroll_offset()) * get_row_height();
+ ofs_y -= get_v_scroll_offset() * get_row_height();
// Check if line contains highlighted word.
int highlighted_text_col = -1;
int search_text_col = -1;
int highlighted_word_col = -1;
- if (!search_text.empty())
+ if (!search_text.empty()) {
search_text_col = _get_column_pos_of_word(search_text, str, search_flags, 0);
+ }
- if (highlighted_text.length() != 0 && highlighted_text != search_text)
+ if (highlighted_text.length() != 0 && highlighted_text != search_text) {
highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
+ }
if (select_identifiers_enabled && highlighted_word.length() != 0) {
- if (_is_char(highlighted_word[0])) {
+ if (_is_char(highlighted_word[0]) || highlighted_word[0] == '.') {
highlighted_word_col = _get_column_pos_of_word(highlighted_word, fullstr, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
}
}
@@ -1291,7 +1270,6 @@ void TextEdit::_notification(int p_what) {
// Loop through characters in one line.
int j = 0;
for (; j < str.length(); j++) {
-
if (syntax_coloring) {
if (color_map.has(last_wrap_column + j)) {
current_color = color_map[last_wrap_column + j].color;
@@ -1312,7 +1290,6 @@ void TextEdit::_notification(int p_what) {
// Line highlighting handle horizontal clipping.
if (line == cursor.line && cursor_wrap_index == line_wrap_index && highlight_current_line) {
-
if (j == str.length() - 1) {
// End of line when last char is skipped.
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg + ofs_x, ofs_y, xmargin_end - (char_ofs + char_margin + char_w), get_row_height()), cache.current_line_color);
@@ -1332,8 +1309,9 @@ void TextEdit::_notification(int p_what) {
if (search_text_col != -1) {
// If we are at the end check for new search result on same line.
- if (j >= search_text_col + search_text.length())
+ if (j >= search_text_col + search_text.length()) {
search_text_col = _get_column_pos_of_word(search_text, str, search_flags, j);
+ }
in_search_result = j >= search_text_col && j < search_text_col + search_text.length();
@@ -1370,15 +1348,16 @@ void TextEdit::_notification(int p_what) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin + ofs_x, ofs_y), Size2i(char_w, 1)), border_color);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin + ofs_x, ofs_y + get_row_height() - 1), Size2i(char_w, 1)), border_color);
- if (j == search_text_col)
+ if (j == search_text_col) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin + ofs_x, ofs_y), Size2i(1, get_row_height())), border_color);
- if (j == search_text_col + search_text.length() - 1)
+ }
+ if (j == search_text_col + search_text.length() - 1) {
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin + char_w + ofs_x - 1, ofs_y), Size2i(1, get_row_height())), border_color);
+ }
}
if (highlight_all_occurrences && !only_whitespaces_highlighted) {
if (highlighted_text_col != -1) {
-
// If we are at the end check for new word on same line.
if (j > highlighted_text_col + highlighted_text.length()) {
highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, j);
@@ -1408,23 +1387,22 @@ void TextEdit::_notification(int p_what) {
int yofs = ofs_y + (get_row_height() - cache.font->get_height()) / 2;
if ((brace_open_match_line == line && brace_open_match_column == last_wrap_column + j) ||
(cursor.column == last_wrap_column + j && cursor.line == line && cursor_wrap_index == line_wrap_index && (brace_open_matching || brace_open_mismatch))) {
-
- if (brace_open_mismatch)
+ if (brace_open_mismatch) {
color = cache.brace_mismatch_color;
+ }
drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), '_', str[j + 1], in_selection && override_selected_font_color ? cache.font_color_selected : color);
}
if ((brace_close_match_line == line && brace_close_match_column == last_wrap_column + j) ||
(cursor.column == last_wrap_column + j + 1 && cursor.line == line && cursor_wrap_index == line_wrap_index && (brace_close_matching || brace_close_mismatch))) {
-
- if (brace_close_mismatch)
+ if (brace_close_mismatch) {
color = cache.brace_mismatch_color;
+ }
drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), '_', str[j + 1], in_selection && override_selected_font_color ? cache.font_color_selected : color);
}
}
if (cursor.column == last_wrap_column + j && cursor.line == line && cursor_wrap_index == line_wrap_index) {
-
cursor_pos = Point2i(char_ofs + char_margin + ofs_x, ofs_y);
cursor_pos.y += (get_row_height() - cache.font->get_height()) / 2;
@@ -1437,15 +1415,17 @@ void TextEdit::_notification(int p_what) {
if (ime_text.length() > 0) {
int ofs = 0;
while (true) {
- if (ofs >= ime_text.length())
+ if (ofs >= ime_text.length()) {
break;
+ }
CharType cchar = ime_text[ofs];
CharType next = ime_text[ofs + 1];
int im_char_width = cache.font->get_char_size(cchar, next).width;
- if ((char_ofs + char_margin + im_char_width) >= xmargin_end)
+ if ((char_ofs + char_margin + im_char_width) >= xmargin_end) {
break;
+ }
bool selected = ofs >= ime_selection.x && ofs < ime_selection.x + ime_selection.y;
if (selected) {
@@ -1492,12 +1472,12 @@ void TextEdit::_notification(int p_what) {
int yofs = ofs_y + (get_row_height() - cache.font->get_height()) / 2;
int w = drawer.draw_char(ci, Point2i(char_ofs + char_margin + ofs_x, yofs + ascent), str[j], str[j + 1], in_selection && override_selected_font_color ? cache.font_color_selected : color);
if (underlined) {
- float line_width = 1.0;
+ float line_width = cache.font->get_underline_thickness();
#ifdef TOOLS_ENABLED
line_width *= EDSCALE;
#endif
- draw_rect(Rect2(char_ofs + char_margin + ofs_x, yofs + ascent + 2, w, line_width), in_selection && override_selected_font_color ? cache.font_color_selected : color);
+ draw_rect(Rect2(char_ofs + char_margin + ofs_x, yofs + ascent + cache.font->get_underline_position(), w, line_width), in_selection && override_selected_font_color ? cache.font_color_selected : color);
}
} else if (draw_tabs && str[j] == '\t') {
int yofs = (get_row_height() - cache.tab_icon->get_height()) / 2;
@@ -1521,7 +1501,6 @@ void TextEdit::_notification(int p_what) {
}
if (cursor.column == (last_wrap_column + j) && cursor.line == line && cursor_wrap_index == line_wrap_index && (char_ofs + char_margin) >= xmargin_beg) {
-
cursor_pos = Point2i(char_ofs + char_margin + ofs_x, ofs_y);
cursor_pos.y += (get_row_height() - cache.font->get_height()) / 2;
@@ -1532,15 +1511,17 @@ void TextEdit::_notification(int p_what) {
if (ime_text.length() > 0) {
int ofs = 0;
while (true) {
- if (ofs >= ime_text.length())
+ if (ofs >= ime_text.length()) {
break;
+ }
CharType cchar = ime_text[ofs];
CharType next = ime_text[ofs + 1];
int im_char_width = cache.font->get_char_size(cchar, next).width;
- if ((char_ofs + char_margin + im_char_width) >= xmargin_end)
+ if ((char_ofs + char_margin + im_char_width) >= xmargin_end) {
break;
+ }
bool selected = ofs >= ime_selection.x && ofs < ime_selection.x + ime_selection.y;
if (selected) {
@@ -1599,8 +1580,9 @@ void TextEdit::_notification(int p_what) {
if (completion_options_size < 50) {
for (int i = 0; i < completion_options_size; i++) {
int w2 = MIN(cache.font->get_string_size(completion_options[i].display).x, cmax_width);
- if (w2 > w)
+ if (w2 > w) {
w = w2;
+ }
}
} else {
w = cmax_width;
@@ -1628,8 +1610,9 @@ void TextEdit::_notification(int p_what) {
completion_rect.size.width = w + 2;
completion_rect.size.height = h;
- if (completion_options_size <= maxlines)
+ if (completion_options_size <= maxlines) {
scrollw = 0;
+ }
draw_style_box(csb, Rect2(completion_rect.position - csb->get_offset(), completion_rect.size + csb->get_minimum_size() + Size2(scrollw, 0)));
@@ -1641,7 +1624,6 @@ void TextEdit::_notification(int p_what) {
draw_rect(Rect2(completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(nofs, completion_rect.size.width - (icon_area_size.x + icon_hsep)), completion_rect.size.height)), cache.completion_existing_color);
for (int i = 0; i < lines; i++) {
-
int l = line_from + i;
ERR_CONTINUE(l < 0 || l >= completion_options_size);
Color text_color = cache.completion_font_color;
@@ -1693,7 +1675,6 @@ void TextEdit::_notification(int p_what) {
}
if (show_hint) {
-
Ref<StyleBox> sb = get_theme_stylebox("panel", "TooltipPanel");
Ref<Font> font = cache.font;
Color font_color = get_theme_color("font_color", "TooltipLabel");
@@ -1703,7 +1684,6 @@ void TextEdit::_notification(int p_what) {
int offset = 0;
int spacing = 0;
for (int i = 0; i < sc; i++) {
-
String l = completion_hint.get_slice("\n", i);
int len = font->get_string_size(l).x;
max_w = MAX(len, max_w);
@@ -1761,7 +1741,6 @@ void TextEdit::_notification(int p_what) {
}
} break;
case NOTIFICATION_FOCUS_ENTER: {
-
if (caret_blink_enabled) {
caret_blink_timer->start();
} else {
@@ -1774,11 +1753,11 @@ void TextEdit::_notification(int p_what) {
DisplayServer::get_singleton()->window_set_ime_position(get_global_position() + cursor_pos, get_viewport()->get_window_id());
}
- if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) {
DisplayServer::get_singleton()->virtual_keyboard_show(get_text(), get_global_rect());
+ }
} break;
case NOTIFICATION_FOCUS_EXIT: {
-
if (caret_blink_enabled) {
caret_blink_timer->stop();
}
@@ -1790,11 +1769,11 @@ void TextEdit::_notification(int p_what) {
ime_text = "";
ime_selection = Point2();
- if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD))
+ if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) {
DisplayServer::get_singleton()->virtual_keyboard_hide();
+ }
} break;
case MainLoop::NOTIFICATION_OS_IME_UPDATE: {
-
if (has_focus()) {
ime_text = DisplayServer::get_singleton()->ime_get_text();
ime_selection = DisplayServer::get_singleton()->ime_get_selection();
@@ -1805,7 +1784,6 @@ void TextEdit::_notification(int p_what) {
}
void TextEdit::_consume_pair_symbol(CharType ch) {
-
int cursor_position_to_move = cursor_get_column() + 1;
CharType ch_single[2] = { ch, 0 };
@@ -1813,7 +1791,6 @@ void TextEdit::_consume_pair_symbol(CharType ch) {
CharType ch_pair[3] = { ch, _get_right_pair_symbol(ch), 0 };
if (is_selection_active()) {
-
int new_column, new_line;
begin_complex_operation();
@@ -1822,8 +1799,9 @@ void TextEdit::_consume_pair_symbol(CharType ch) {
&new_line, &new_column);
int to_col_offset = 0;
- if (get_selection_from_line() == get_selection_to_line())
+ if (get_selection_from_line() == get_selection_to_line()) {
to_col_offset = 1;
+ }
_insert_text(get_selection_to_line(),
get_selection_to_column() + to_col_offset,
@@ -1912,11 +1890,9 @@ void TextEdit::_consume_pair_symbol(CharType ch) {
}
void TextEdit::_consume_backspace_for_pair_symbol(int prev_line, int prev_column) {
-
bool remove_right_symbol = false;
if (cursor.column < text[cursor.line].length() && cursor.column > 0) {
-
CharType left_char = text[cursor.line][cursor.column - 1];
CharType right_char = text[cursor.line][cursor.column];
@@ -1932,20 +1908,24 @@ void TextEdit::_consume_backspace_for_pair_symbol(int prev_line, int prev_column
}
void TextEdit::backspace_at_cursor() {
- if (readonly)
+ if (readonly) {
return;
+ }
- if (cursor.column == 0 && cursor.line == 0)
+ if (cursor.column == 0 && cursor.line == 0) {
return;
+ }
int prev_line = cursor.column ? cursor.line : cursor.line - 1;
int prev_column = cursor.column ? (cursor.column - 1) : (text[cursor.line - 1].length());
- if (is_line_hidden(cursor.line))
+ if (is_line_hidden(cursor.line)) {
set_line_as_hidden(prev_line, true);
+ }
if (is_line_set_as_breakpoint(cursor.line)) {
- if (!text.is_breakpoint(prev_line))
+ if (!text.is_breakpoint(prev_line)) {
emit_signal("breakpoint_toggled", prev_line);
+ }
set_line_as_breakpoint(prev_line, true);
}
@@ -1990,7 +1970,6 @@ void TextEdit::backspace_at_cursor() {
}
void TextEdit::indent_right() {
-
int start_line;
int end_line;
@@ -2021,8 +2000,9 @@ void TextEdit::indent_right() {
int spaces_to_add = _calculate_spaces_till_next_right_indent(left);
// Since we will add this much spaces we want move whole selection and cursor by this much.
selection_offset = spaces_to_add;
- for (int j = 0; j < spaces_to_add; j++)
+ for (int j = 0; j < spaces_to_add; j++) {
line_text = ' ' + line_text;
+ }
} else {
line_text = '\t' + line_text;
}
@@ -2039,7 +2019,6 @@ void TextEdit::indent_right() {
}
void TextEdit::indent_left() {
-
int start_line;
int end_line;
@@ -2100,8 +2079,9 @@ void TextEdit::indent_left() {
int TextEdit::_calculate_spaces_till_next_left_indent(int column) {
int spaces_till_indent = column % indent_size;
- if (spaces_till_indent == 0)
+ if (spaces_till_indent == 0) {
spaces_till_indent = indent_size;
+ }
return spaces_till_indent;
}
@@ -2110,7 +2090,6 @@ int TextEdit::_calculate_spaces_till_next_right_indent(int column) {
}
void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) const {
-
float rows = p_mouse.y;
rows -= cache.style_normal->get_margin(MARGIN_TOP);
rows /= get_row_height();
@@ -2120,25 +2099,24 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
int wrap_index = 0;
if (is_wrap_enabled() || is_hiding_enabled()) {
-
int f_ofs = num_lines_from_rows(first_vis_line, cursor.wrap_ofs, rows + (1 * SGN(rows)), wrap_index) - 1;
- if (rows < 0)
+ if (rows < 0) {
row = first_vis_line - f_ofs;
- else
+ } else {
row = first_vis_line + f_ofs;
+ }
}
- if (row < 0)
+ if (row < 0) {
row = 0; // TODO.
+ }
int col = 0;
if (row >= text.size()) {
-
row = text.size() - 1;
col = text[row].size();
} else {
-
int colx = p_mouse.x - (cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width);
colx += cursor.x_ofs;
col = get_char_pos_for_line(colx, row, wrap_index);
@@ -2149,8 +2127,9 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
for (int i = 0; i < wrap_index + 1; i++) {
row_end_col += rows2[i].length();
}
- if (col >= row_end_col)
+ if (col >= row_end_col) {
col -= 1;
+ }
}
}
@@ -2197,7 +2176,6 @@ Vector2i TextEdit::_get_cursor_pixel_pos() {
}
void TextEdit::_get_minimap_mouse_row(const Point2i &p_mouse, int &r_row) const {
-
float rows = p_mouse.y;
rows -= cache.style_normal->get_margin(MARGIN_TOP);
rows /= (minimap_char_size.y + minimap_line_spacing);
@@ -2231,7 +2209,6 @@ void TextEdit::_get_minimap_mouse_row(const Point2i &p_mouse, int &r_row) const
int wrap_index = 0;
if (is_wrap_enabled() || is_hiding_enabled()) {
-
int f_ofs = num_lines_from_rows(minimap_line, cursor.wrap_ofs, rows + (1 * SGN(rows)), wrap_index) - 1;
if (rows < 0) {
row = minimap_line - f_ofs;
@@ -2252,7 +2229,6 @@ void TextEdit::_get_minimap_mouse_row(const Point2i &p_mouse, int &r_row) const
}
void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
-
double prev_v_scroll = v_scroll->get_value();
double prev_h_scroll = h_scroll->get_value();
@@ -2260,9 +2236,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (mb.is_valid()) {
if (completion_active && completion_rect.has_point(mb->get_position())) {
-
- if (!mb->is_pressed())
+ if (!mb->is_pressed()) {
return;
+ }
if (mb->get_button_index() == BUTTON_WHEEL_UP) {
if (completion_index > 0) {
@@ -2272,7 +2248,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
if (mb->get_button_index() == BUTTON_WHEEL_DOWN) {
-
if (completion_index < completion_options.size() - 1) {
completion_index++;
completion_current = completion_options[completion_index];
@@ -2281,13 +2256,13 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (mb->get_button_index() == BUTTON_LEFT) {
-
completion_index = CLAMP(completion_line_ofs + (mb->get_position().y - completion_rect.position.y) / get_row_height(), 0, completion_options.size() - 1);
completion_current = completion_options[completion_index];
update();
- if (mb->is_doubleclick())
+ if (mb->is_doubleclick()) {
_confirm_completion();
+ }
}
return;
} else {
@@ -2296,7 +2271,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (mb->is_pressed()) {
-
if (mb->get_button_index() == BUTTON_WHEEL_UP && !mb->get_command()) {
if (mb->get_shift()) {
h_scroll->set_value(h_scroll->get_value() - (100 * mb->get_factor()));
@@ -2318,7 +2292,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
h_scroll->set_value(h_scroll->get_value() + (100 * mb->get_factor()));
}
if (mb->get_button_index() == BUTTON_LEFT) {
-
_reset_caret_blink_timer();
int row, col;
@@ -2346,7 +2319,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
// Toggle fold on gutter click if can.
if (draw_fold_gutter) {
-
int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
int gutter_left = left_margin + cache.breakpoint_gutter_width + cache.line_number_w + cache.info_gutter_width;
if (mb->get_position().x > gutter_left - 6 && mb->get_position().x <= gutter_left + cache.fold_gutter_width - 3) {
@@ -2384,7 +2356,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
cursor_set_column(col);
if (mb->get_shift() && (cursor.column != prev_col || cursor.line != prev_line)) {
-
if (!selection.active) {
selection.active = true;
selection.selecting_mode = Selection::MODE_POINTER;
@@ -2404,9 +2375,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
selection.selecting_column = prev_col;
update();
} else {
-
if (cursor.line < selection.selecting_line || (cursor.line == selection.selecting_line && cursor.column < selection.selecting_column)) {
-
if (selection.shiftclick_left) {
SWAP(selection.from_column, selection.to_column);
SWAP(selection.from_line, selection.to_line);
@@ -2416,7 +2385,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
selection.from_line = cursor.line;
} else if (cursor.line > selection.selecting_line || (cursor.line == selection.selecting_line && cursor.column > selection.selecting_column)) {
-
if (!selection.shiftclick_left) {
SWAP(selection.from_column, selection.to_column);
SWAP(selection.from_line, selection.to_line);
@@ -2433,7 +2401,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
} else {
-
selection.active = false;
selection.selecting_mode = Selection::MODE_POINTER;
selection.selecting_line = row;
@@ -2441,13 +2408,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (!mb->is_doubleclick() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < 600 && cursor.line == prev_line) {
-
// Triple-click select line.
selection.selecting_mode = Selection::MODE_LINE;
_update_selection_mode_line();
last_dblclk = 0;
} else if (mb->is_doubleclick() && text[cursor.line].length()) {
-
// Double-click select word.
selection.selecting_mode = Selection::MODE_WORD;
_update_selection_mode_word();
@@ -2458,7 +2423,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (mb->get_button_index() == BUTTON_RIGHT && context_menu_enabled) {
-
_reset_caret_blink_timer();
int row, col;
@@ -2466,7 +2430,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (is_right_click_moving_caret()) {
if (is_selection_active()) {
-
int from_line = get_selection_from_line();
int to_line = get_selection_to_line();
int from_column = get_selection_from_column();
@@ -2490,7 +2453,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
grab_focus();
}
} else {
-
if (mb->get_button_index() == BUTTON_LEFT) {
if (mb->get_command() && highlighted_word != String()) {
int row, col;
@@ -2513,7 +2475,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
const Ref<InputEventPanGesture> pan_gesture = p_gui_input;
if (pan_gesture.is_valid()) {
-
const real_t delta = pan_gesture->get_delta().y;
if (delta < 0) {
_scroll_up(-delta);
@@ -2521,8 +2482,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
_scroll_down(delta);
}
h_scroll->set_value(h_scroll->get_value() + pan_gesture->get_delta().x * 100);
- if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll)
+ if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll) {
accept_event(); // Accept event if scroll changed.
+ }
return;
}
@@ -2530,10 +2492,8 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
Ref<InputEventMouseMotion> mm = p_gui_input;
if (mm.is_valid()) {
-
if (select_identifiers_enabled) {
if (!dragging_minimap && !dragging_selection && mm->get_command() && mm->get_button_mask() == 0) {
-
String new_word = get_word_at_pos(mm->get_position());
if (new_word != highlighted_word) {
emit_signal("symbol_validate", new_word);
@@ -2571,13 +2531,13 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll)
+ if (v_scroll->get_value() != prev_v_scroll || h_scroll->get_value() != prev_h_scroll) {
accept_event(); // Accept event if scroll changed.
+ }
Ref<InputEventKey> k = p_gui_input;
if (k.is_valid()) {
-
k = k->duplicate(); // It will be modified later on.
#ifdef OSX_ENABLED
@@ -2587,7 +2547,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
#endif
if (select_identifiers_enabled) {
-
if (k->is_pressed() && !dragging_minimap && !dragging_selection) {
emit_signal("symbol_validate", get_word_at_pos(get_local_mouse_position()));
} else {
@@ -2596,22 +2555,23 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (!k->is_pressed())
+ if (!k->is_pressed()) {
return;
+ }
if (completion_active) {
- if (readonly)
+ if (readonly) {
return;
+ }
bool valid = true;
- if (k->get_command() || k->get_metakey())
+ if (k->get_command() || k->get_metakey()) {
valid = false;
+ }
if (valid) {
-
if (!k->get_alt()) {
if (k->get_keycode() == KEY_UP) {
-
if (completion_index > 0) {
completion_index--;
} else {
@@ -2625,7 +2585,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (k->get_keycode() == KEY_DOWN) {
-
if (completion_index < completion_options.size() - 1) {
completion_index++;
} else {
@@ -2639,10 +2598,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (k->get_keycode() == KEY_PAGEUP) {
-
completion_index -= get_theme_constant("completion_lines");
- if (completion_index < 0)
+ if (completion_index < 0) {
completion_index = 0;
+ }
completion_current = completion_options[completion_index];
update();
accept_event();
@@ -2650,10 +2609,10 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (k->get_keycode() == KEY_PAGEDOWN) {
-
completion_index += get_theme_constant("completion_lines");
- if (completion_index >= completion_options.size())
+ if (completion_index >= completion_options.size()) {
completion_index = completion_options.size() - 1;
+ }
completion_current = completion_options[completion_index];
update();
accept_event();
@@ -2661,7 +2620,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (k->get_keycode() == KEY_HOME && completion_index > 0) {
-
completion_index = 0;
completion_current = completion_options[completion_index];
update();
@@ -2670,7 +2628,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (k->get_keycode() == KEY_END && completion_index < completion_options.size() - 1) {
-
completion_index = completion_options.size() - 1;
completion_current = completion_options[completion_index];
update();
@@ -2679,14 +2636,12 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (k->get_keycode() == KEY_KP_ENTER || k->get_keycode() == KEY_ENTER || k->get_keycode() == KEY_TAB) {
-
_confirm_completion();
accept_event();
return;
}
if (k->get_keycode() == KEY_BACKSPACE) {
-
_reset_caret_blink_timer();
backspace_at_cursor();
@@ -2702,14 +2657,12 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (k->get_unicode() > 32) {
-
_reset_caret_blink_timer();
const CharType chr[2] = { (CharType)k->get_unicode(), 0 };
if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
_consume_pair_symbol(chr[0]);
} else {
-
// Remove the old character if in insert mode.
if (insert_mode) {
begin_complex_operation();
@@ -2740,11 +2693,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
// Some remaps for duplicate functions.
if (k->get_command() && !k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_keycode() == KEY_INSERT) {
-
k->set_keycode(KEY_C);
}
if (!k->get_command() && k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_keycode() == KEY_INSERT) {
-
k->set_keycode(KEY_V);
k->set_command(true);
k->set_shift(false);
@@ -2787,13 +2738,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
// Stuff to do when selection is active.
if (!readonly && selection.active) {
-
bool clear = false;
bool unselect = false;
bool dobreak = false;
switch (k->get_keycode()) {
-
case KEY_TAB: {
if (k->get_shift()) {
indent_left();
@@ -2831,16 +2780,19 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
case KEY_HOME:
case KEY_END:
// Ignore arrows if any modifiers are held (shift = selecting, others may be used for editor hotkeys).
- if (k->get_command() || k->get_shift() || k->get_alt())
+ if (k->get_command() || k->get_shift() || k->get_alt()) {
break;
+ }
unselect = true;
break;
default:
- if (k->get_unicode() >= 32 && !k->get_command() && !k->get_alt() && !k->get_metakey())
+ if (k->get_unicode() >= 32 && !k->get_command() && !k->get_alt() && !k->get_metakey()) {
clear = true;
- if (auto_brace_completion_enabled && _is_pair_left_symbol(k->get_unicode()))
+ }
+ if (auto_brace_completion_enabled && _is_pair_left_symbol(k->get_unicode())) {
clear = false;
+ }
}
if (unselect) {
@@ -2849,7 +2801,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
update();
}
if (clear) {
-
if (!dobreak) {
begin_complex_operation();
}
@@ -2860,8 +2811,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
cursor_set_column(selection.from_column);
update();
}
- if (dobreak)
+ if (dobreak) {
return;
+ }
}
selection.selecting_text = false;
@@ -2871,12 +2823,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
// Special keycode test.
switch (k->get_keycode()) {
-
case KEY_KP_ENTER:
case KEY_ENTER: {
-
- if (readonly)
+ if (readonly) {
break;
+ }
String ins = "\n";
@@ -2906,8 +2857,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (is_folded(cursor.line))
+ if (is_folded(cursor.line)) {
unfold_line(cursor.line);
+ }
bool brace_indent = false;
@@ -2936,7 +2888,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (indent_char_found && cri_map.has(i) && (color_regions[cri_map[i].region].begin_key == "#" || color_regions[cri_map[i].region].begin_key == "//")) {
-
should_indent = true;
break;
} else if (indent_char_found && !_is_whitespace(c)) {
@@ -2996,10 +2947,13 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
} break;
case KEY_TAB: {
- if (k->get_command()) break; // Avoid tab when command.
+ if (k->get_command()) {
+ break; // Avoid tab when command.
+ }
- if (readonly)
+ if (readonly) {
break;
+ }
if (is_selection_active()) {
if (k->get_shift()) {
@@ -3009,7 +2963,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
} else {
if (k->get_shift()) {
-
// Simple unindent.
int cc = cursor.column;
const String &line = text[cursor.line];
@@ -3017,23 +2970,26 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int left = _find_first_non_whitespace_column_of_line(line);
cc = MIN(cc, left);
- while (cc < indent_size && cc < left && line[cc] == ' ')
+ while (cc < indent_size && cc < left && line[cc] == ' ') {
cc++;
+ }
if (cc > 0 && cc <= text[cursor.line].length()) {
if (text[cursor.line][cc - 1] == '\t') {
// Tabs unindentation.
_remove_text(cursor.line, cc - 1, cursor.line, cc);
- if (cursor.column >= left)
+ if (cursor.column >= left) {
cursor_set_column(MAX(0, cursor.column - 1));
+ }
update();
} else {
// Spaces unindentation.
int spaces_to_remove = _calculate_spaces_till_next_left_indent(cc);
if (spaces_to_remove > 0) {
_remove_text(cursor.line, cc - spaces_to_remove, cursor.line, cc);
- if (cursor.column > left - spaces_to_remove) // Inside text?
+ if (cursor.column > left - spaces_to_remove) { // Inside text?
cursor_set_column(MAX(0, cursor.column - spaces_to_remove));
+ }
update();
}
}
@@ -3047,8 +3003,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
// Insert only as much spaces as needed till next indentation level.
int spaces_to_add = _calculate_spaces_till_next_right_indent(cursor.column);
String indent_to_insert = String();
- for (int i = 0; i < spaces_to_add; i++)
+ for (int i = 0; i < spaces_to_add; i++) {
indent_to_insert = ' ' + indent_to_insert;
+ }
_insert_text_at_cursor(indent_to_insert);
} else {
_insert_text_at_cursor("\t");
@@ -3058,8 +3015,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} break;
case KEY_BACKSPACE: {
- if (readonly)
+ if (readonly) {
break;
+ }
#ifdef APPLE_STYLE_KEYS
if (k->get_alt() && cursor.column > 1) {
@@ -3114,8 +3072,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
_remove_text(cursor.line, 0, cursor.line, cursor_current_column);
#endif
} else {
- if (cursor.line > 0 && is_line_hidden(cursor.line - 1))
+ if (cursor.line > 0 && is_line_hidden(cursor.line - 1)) {
unfold_line(cursor.line - 1);
+ }
backspace_at_cursor();
}
@@ -3128,15 +3087,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
[[fallthrough]];
}
case KEY_LEFT: {
-
- if (k->get_shift())
+ if (k->get_shift()) {
_pre_shift_selection();
#ifdef APPLE_STYLE_KEYS
- else
+ } else {
#else
- else if (!k->get_alt())
+ } else if (!k->get_alt()) {
#endif
deselect();
+ }
#ifdef APPLE_STYLE_KEYS
if (k->get_command()) {
@@ -3173,8 +3132,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
while (cc > 0) {
bool ischar = _is_text_char(text[cursor.line][cc - 1]);
- if (prev_char && !ischar)
+ if (prev_char && !ischar) {
break;
+ }
prev_char = ischar;
cc--;
@@ -3183,7 +3143,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
} else if (cursor.column == 0) {
-
if (cursor.line > 0) {
cursor_set_line(cursor.line - num_lines_from(CLAMP(cursor.line - 1, 0, text.size() - 1), -1));
cursor_set_column(text[cursor.line].length());
@@ -3192,8 +3151,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
cursor_set_column(cursor_get_column() - 1);
}
- if (k->get_shift())
+ if (k->get_shift()) {
_post_shift_selection();
+ }
} break;
case KEY_KP_6: {
@@ -3204,15 +3164,15 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
[[fallthrough]];
}
case KEY_RIGHT: {
-
- if (k->get_shift())
+ if (k->get_shift()) {
_pre_shift_selection();
#ifdef APPLE_STYLE_KEYS
- else
+ } else {
#else
- else if (!k->get_alt())
+ } else if (!k->get_alt()) {
#endif
deselect();
+ }
#ifdef APPLE_STYLE_KEYS
if (k->get_command()) {
@@ -3235,8 +3195,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
while (cc < text[cursor.line].length()) {
bool ischar = _is_text_char(text[cursor.line][cc]);
- if (prev_char && !ischar)
+ if (prev_char && !ischar) {
break;
+ }
prev_char = ischar;
cc++;
}
@@ -3244,7 +3205,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
} else if (cursor.column == text[cursor.line].length()) {
-
if (cursor.line < text.size() - 1) {
cursor_set_line(cursor_get_line() + num_lines_from(CLAMP(cursor.line + 1, 0, text.size() - 1), 1), true, false);
cursor_set_column(0);
@@ -3253,8 +3213,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
cursor_set_column(cursor_get_column() + 1);
}
- if (k->get_shift())
+ if (k->get_shift()) {
_post_shift_selection();
+ }
} break;
case KEY_KP_8: {
@@ -3265,7 +3226,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
[[fallthrough]];
}
case KEY_UP: {
-
if (k->get_alt()) {
keycode_handled = false;
break;
@@ -3285,7 +3245,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
#ifdef APPLE_STYLE_KEYS
if (k->get_command()) {
-
cursor_set_line(0);
} else
#endif
@@ -3305,8 +3264,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (k->get_shift())
+ if (k->get_shift()) {
_post_shift_selection();
+ }
_cancel_code_hint();
} break;
@@ -3318,7 +3278,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
[[fallthrough]];
}
case KEY_DOWN: {
-
if (k->get_alt()) {
keycode_handled = false;
break;
@@ -3353,15 +3312,16 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- if (k->get_shift())
+ if (k->get_shift()) {
_post_shift_selection();
+ }
_cancel_code_hint();
} break;
case KEY_DELETE: {
-
- if (readonly)
+ if (readonly) {
break;
+ }
if (k->get_shift() && !k->get_command() && !k->get_alt() && is_shortcut_keys_enabled()) {
cut();
@@ -3370,8 +3330,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int curline_len = text[cursor.line].length();
- if (cursor.line == text.size() - 1 && cursor.column == curline_len)
+ if (cursor.line == text.size() - 1 && cursor.column == curline_len) {
break; // Nothing to do.
+ }
int next_line = cursor.column < curline_len ? cursor.line : cursor.line + 1;
int next_column;
@@ -3452,14 +3413,14 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
else if (k->get_command() || k->get_control())
deselect();
#else
- if (k->get_shift())
+ if (k->get_shift()) {
_pre_shift_selection();
+ }
if (k->get_command()) {
cursor_set_line(0);
cursor_set_column(0);
} else {
-
// Move cursor column to start of wrapped row and then to start of text.
Vector<String> rows = get_wrap_rows_text(cursor.line);
int wi = get_cursor_wrap_index();
@@ -3472,24 +3433,27 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
int current_line_whitespace_len = 0;
while (current_line_whitespace_len < text[cursor.line].length()) {
CharType c = text[cursor.line][current_line_whitespace_len];
- if (c != '\t' && c != ' ')
+ if (c != '\t' && c != ' ') {
break;
+ }
current_line_whitespace_len++;
}
- if (cursor_get_column() == current_line_whitespace_len)
+ if (cursor_get_column() == current_line_whitespace_len) {
cursor_set_column(0);
- else
+ } else {
cursor_set_column(current_line_whitespace_len);
+ }
} else {
cursor_set_column(row_start_col);
}
}
- if (k->get_shift())
+ if (k->get_shift()) {
_post_shift_selection();
- else if (k->get_command() || k->get_control())
+ } else if (k->get_command() || k->get_control()) {
deselect();
+ }
_cancel_completion();
completion_hint = "";
#endif
@@ -3513,11 +3477,13 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
else if (k->get_command() || k->get_control())
deselect();
#else
- if (k->get_shift())
+ if (k->get_shift()) {
_pre_shift_selection();
+ }
- if (k->get_command())
+ if (k->get_command()) {
cursor_set_line(get_last_unhidden_line(), true, false, 9999);
+ }
// Move cursor column to end of wrapped row and then to end of text.
Vector<String> rows = get_wrap_rows_text(cursor.line);
@@ -3532,10 +3498,11 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
cursor_set_column(row_end_col);
}
- if (k->get_shift())
+ if (k->get_shift()) {
_post_shift_selection();
- else if (k->get_command() || k->get_control())
+ } else if (k->get_command() || k->get_control()) {
deselect();
+ }
_cancel_completion();
completion_hint = "";
@@ -3549,16 +3516,17 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
[[fallthrough]];
}
case KEY_PAGEUP: {
-
- if (k->get_shift())
+ if (k->get_shift()) {
_pre_shift_selection();
+ }
int wi;
int n_line = cursor.line - num_lines_from_rows(cursor.line, get_cursor_wrap_index(), -get_visible_rows(), wi) + 1;
cursor_set_line(n_line, true, false, wi);
- if (k->get_shift())
+ if (k->get_shift()) {
_post_shift_selection();
+ }
_cancel_completion();
completion_hint = "";
@@ -3572,23 +3540,23 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
[[fallthrough]];
}
case KEY_PAGEDOWN: {
-
- if (k->get_shift())
+ if (k->get_shift()) {
_pre_shift_selection();
+ }
int wi;
int n_line = cursor.line + num_lines_from_rows(cursor.line, get_cursor_wrap_index(), get_visible_rows(), wi) - 1;
cursor_set_line(n_line, true, false, wi);
- if (k->get_shift())
+ if (k->get_shift()) {
_post_shift_selection();
+ }
_cancel_completion();
completion_hint = "";
} break;
case KEY_A: {
-
#ifndef APPLE_STYLE_KEYS
if (!k->get_control() || k->get_shift() || k->get_alt()) {
keycode_handled = false;
@@ -3628,7 +3596,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
} break;
case KEY_E: {
-
if (!k->get_control() || k->get_command() || k->get_alt()) {
keycode_handled = false;
break;
@@ -3664,7 +3631,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} break;
case KEY_C: {
-
if (!k->get_command() || k->get_shift() || k->get_alt()) {
keycode_handled = false;
break;
@@ -3676,7 +3642,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} break;
case KEY_Z: {
-
if (readonly) {
break;
}
@@ -3687,14 +3652,14 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (is_shortcut_keys_enabled()) {
- if (k->get_shift())
+ if (k->get_shift()) {
redo();
- else
+ } else {
undo();
+ }
}
} break;
case KEY_Y: {
-
if (readonly) {
break;
}
@@ -3748,13 +3713,13 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
} break;
default: {
-
keycode_handled = false;
} break;
}
- if (keycode_handled)
+ if (keycode_handled) {
accept_event();
+ }
if (k->get_keycode() == KEY_INSERT) {
set_insert_mode(!insert_mode);
@@ -3765,9 +3730,9 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
if (!keycode_handled && !k->get_command()) { // For German keyboards.
if (k->get_unicode() >= 32) {
-
- if (readonly)
+ if (readonly) {
return;
+ }
// Remove the old character if in insert mode and no selection.
if (insert_mode && !had_selection) {
@@ -3806,7 +3771,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
void TextEdit::_scroll_up(real_t p_delta) {
-
if (scrolling && smooth_scroll_enabled && SGN(target_v_scroll - v_scroll->get_value()) != SGN(-p_delta)) {
scrolling = false;
minimap_clicked = false;
@@ -3834,7 +3798,6 @@ void TextEdit::_scroll_up(real_t p_delta) {
}
void TextEdit::_scroll_down(real_t p_delta) {
-
if (scrolling && smooth_scroll_enabled && SGN(target_v_scroll - v_scroll->get_value()) != SGN(p_delta)) {
scrolling = false;
minimap_clicked = false;
@@ -3863,9 +3826,7 @@ void TextEdit::_scroll_down(real_t p_delta) {
}
void TextEdit::_pre_shift_selection() {
-
if (!selection.active || selection.selecting_mode == Selection::MODE_NONE) {
-
selection.selecting_line = cursor.line;
selection.selecting_column = cursor.column;
selection.active = true;
@@ -3875,9 +3836,7 @@ void TextEdit::_pre_shift_selection() {
}
void TextEdit::_post_shift_selection() {
-
if (selection.active && selection.selecting_mode == Selection::MODE_SHIFT) {
-
select(selection.selecting_line, selection.selecting_column, cursor.line, cursor.column);
update();
}
@@ -3928,7 +3887,6 @@ void TextEdit::_scroll_lines_down() {
/**** TEXT EDIT CORE API ****/
void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, int &r_end_line, int &r_end_column) {
-
// Save for undo.
ERR_FAIL_INDEX(p_line, text.size());
ERR_FAIL_COND(p_char < 0);
@@ -3946,16 +3904,17 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
int lines = substrings.size() - 1;
for (; i < text.size(); i++) {
if (text.is_breakpoint(i)) {
- if ((i - lines < p_line || !text.is_breakpoint(i - lines)) || (i - lines == p_line && !shift_first_line))
+ if ((i - lines < p_line || !text.is_breakpoint(i - lines)) || (i - lines == p_line && !shift_first_line)) {
emit_signal("breakpoint_toggled", i);
- if (i + lines >= text.size() || !text.is_breakpoint(i + lines))
+ }
+ if (i + lines >= text.size() || !text.is_breakpoint(i + lines)) {
emit_signal("breakpoint_toggled", i + lines);
+ }
}
}
/* STEP 3: Add spaces if the char is greater than the end of the line. */
while (p_char > text[p_line].length()) {
-
text.set(p_line, text[p_line] + String::chr(' '));
}
@@ -3968,15 +3927,12 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
// Insert the substrings.
if (j == 0) {
-
text.set(p_line, preinsert_text + substrings[j]);
} else {
-
text.insert(p_line + j, substrings[j]);
}
if (j == substrings.size() - 1) {
-
text.set(p_line + j, text[p_line + j] + postinsert_text);
}
}
@@ -3999,15 +3955,15 @@ void TextEdit::_base_insert_text(int p_line, int p_char, const String &p_text, i
r_end_column = text[r_end_line].length() - postinsert_text.length();
if (!text_changed_dirty && !setting_text) {
- if (is_inside_tree())
+ if (is_inside_tree()) {
MessageQueue::get_singleton()->push_call(this, "_text_changed_emit");
+ }
text_changed_dirty = true;
}
_line_edited_from(p_line);
}
String TextEdit::_base_get_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column) const {
-
ERR_FAIL_INDEX_V(p_from_line, text.size(), String());
ERR_FAIL_INDEX_V(p_from_column, text[p_from_line].length() + 1, String());
ERR_FAIL_INDEX_V(p_to_line, text.size(), String());
@@ -4018,12 +3974,12 @@ String TextEdit::_base_get_text(int p_from_line, int p_from_column, int p_to_lin
String ret;
for (int i = p_from_line; i <= p_to_line; i++) {
-
int begin = (i == p_from_line) ? p_from_column : 0;
int end = (i == p_to_line) ? p_to_column : text[i].length();
- if (i > p_from_line)
+ if (i > p_from_line) {
ret += "\n";
+ }
ret += text[i].substr(begin, end - begin);
}
@@ -4031,7 +3987,6 @@ String TextEdit::_base_get_text(int p_from_line, int p_from_column, int p_to_lin
}
void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column) {
-
ERR_FAIL_INDEX(p_from_line, text.size());
ERR_FAIL_INDEX(p_from_column, text[p_from_line].length() + 1);
ERR_FAIL_INDEX(p_to_line, text.size());
@@ -4046,10 +4001,12 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
for (int i = p_from_line + 1; i < text.size(); i++) {
if (text.is_breakpoint(i)) {
- if (i + lines >= text.size() || !text.is_breakpoint(i + lines))
+ if (i + lines >= text.size() || !text.is_breakpoint(i + lines)) {
emit_signal("breakpoint_toggled", i);
- if (i > p_to_line && (i - lines < 0 || !text.is_breakpoint(i - lines)))
+ }
+ if (i > p_to_line && (i - lines < 0 || !text.is_breakpoint(i - lines))) {
emit_signal("breakpoint_toggled", i - lines);
+ }
}
}
@@ -4061,17 +4018,18 @@ void TextEdit::_base_remove_text(int p_from_line, int p_from_column, int p_to_li
text.set_line_wrap_amount(p_from_line, -1);
if (!text_changed_dirty && !setting_text) {
- if (is_inside_tree())
+ if (is_inside_tree()) {
MessageQueue::get_singleton()->push_call(this, "_text_changed_emit");
+ }
text_changed_dirty = true;
}
_line_edited_from(p_from_line);
}
void TextEdit::_insert_text(int p_line, int p_char, const String &p_text, int *r_end_line, int *r_end_char) {
-
- if (!setting_text && idle_detect->is_inside_tree())
+ if (!setting_text && idle_detect->is_inside_tree()) {
idle_detect->start();
+ }
if (undo_enabled) {
_clear_redo();
@@ -4079,13 +4037,16 @@ void TextEdit::_insert_text(int p_line, int p_char, const String &p_text, int *r
int retline, retchar;
_base_insert_text(p_line, p_char, p_text, retline, retchar);
- if (r_end_line)
+ if (r_end_line) {
*r_end_line = retline;
- if (r_end_char)
+ }
+ if (r_end_char) {
*r_end_char = retchar;
+ }
- if (!undo_enabled)
+ if (!undo_enabled) {
return;
+ }
/* UNDO!! */
TextOperation op;
@@ -4123,9 +4084,9 @@ void TextEdit::_insert_text(int p_line, int p_char, const String &p_text, int *r
}
void TextEdit::_remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column) {
-
- if (!setting_text && idle_detect->is_inside_tree())
+ if (!setting_text && idle_detect->is_inside_tree()) {
idle_detect->start();
+ }
String text;
if (undo_enabled) {
@@ -4135,8 +4096,9 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column, int p_to_line, i
_base_remove_text(p_from_line, p_from_column, p_to_line, p_to_column);
- if (!undo_enabled)
+ if (!undo_enabled) {
return;
+ }
/* UNDO! */
TextOperation op;
@@ -4172,7 +4134,6 @@ void TextEdit::_remove_text(int p_from_line, int p_from_column, int p_to_line, i
}
void TextEdit::_insert_text_at_cursor(const String &p_text) {
-
int new_column, new_line;
_insert_text(cursor.line, cursor.column, p_text, &new_line, &new_column);
_update_scrollbars();
@@ -4199,13 +4160,12 @@ void TextEdit::_line_edited_from(int p_line) {
}
int TextEdit::get_char_count() {
-
int totalsize = 0;
for (int i = 0; i < text.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
totalsize++; // Include \n.
+ }
totalsize += text[i].length();
}
@@ -4213,7 +4173,6 @@ int TextEdit::get_char_count() {
}
Size2 TextEdit::get_minimum_size() const {
-
return cache.style_normal->get_minimum_size();
}
@@ -4229,14 +4188,17 @@ int TextEdit::_get_control_height() const {
void TextEdit::_generate_context_menu() {
// Reorganize context menu.
menu->clear();
- if (!readonly)
+ if (!readonly) {
menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_X : 0);
+ }
menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_C : 0);
- if (!readonly)
+ if (!readonly) {
menu->add_item(RTR("Paste"), MENU_PASTE, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_V : 0);
+ }
menu->add_separator();
- if (is_selecting_enabled())
+ if (is_selecting_enabled()) {
menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? KEY_MASK_CMD | KEY_A : 0);
+ }
if (!readonly) {
menu->add_item(RTR("Clear"), MENU_CLEAR);
menu->add_separator();
@@ -4254,11 +4216,11 @@ int TextEdit::_get_minimap_visible_rows() const {
}
int TextEdit::get_total_visible_rows() const {
-
// Returns the total amount of rows we need in the editor.
// This skips hidden lines and counts each wrapping of a line.
- if (!is_hiding_enabled() && !is_wrap_enabled())
+ if (!is_hiding_enabled() && !is_wrap_enabled()) {
return text.size();
+ }
int total_rows = 0;
for (int i = 0; i < text.size(); i++) {
@@ -4271,22 +4233,21 @@ int TextEdit::get_total_visible_rows() const {
}
void TextEdit::_update_wrap_at() {
-
wrap_at = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width - wrap_right_offset;
update_cursor_wrap_offset();
text.clear_wrap_cache();
for (int i = 0; i < text.size(); i++) {
// Update all values that wrap.
- if (!line_wraps(i))
+ if (!line_wraps(i)) {
continue;
+ }
Vector<String> rows = get_wrap_rows_text(i);
text.set_line_wrap_amount(i, rows.size() - 1);
}
}
void TextEdit::adjust_viewport_to_cursor() {
-
// Make sure cursor is visible on the screen.
scrolling = false;
minimap_clicked = false;
@@ -4308,19 +4269,22 @@ void TextEdit::adjust_viewport_to_cursor() {
}
int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width;
- if (v_scroll->is_visible_in_tree())
+ if (v_scroll->is_visible_in_tree()) {
visible_width -= v_scroll->get_combined_minimum_size().width;
+ }
visible_width -= 20; // Give it a little more space.
if (!is_wrap_enabled()) {
// Adjust x offset.
int cursor_x = get_column_x_offset(cursor.column, text[cursor.line]);
- if (cursor_x > (cursor.x_ofs + visible_width))
+ if (cursor_x > (cursor.x_ofs + visible_width)) {
cursor.x_ofs = cursor_x - visible_width + 1;
+ }
- if (cursor_x < cursor.x_ofs)
+ if (cursor_x < cursor.x_ofs) {
cursor.x_ofs = cursor_x;
+ }
} else {
cursor.x_ofs = 0;
}
@@ -4330,29 +4294,32 @@ void TextEdit::adjust_viewport_to_cursor() {
}
void TextEdit::center_viewport_to_cursor() {
-
// Move viewport so the cursor is in the center of the screen.
scrolling = false;
minimap_clicked = false;
- if (is_line_hidden(cursor.line))
+ if (is_line_hidden(cursor.line)) {
unfold_line(cursor.line);
+ }
set_line_as_center_visible(cursor.line, get_cursor_wrap_index());
int visible_width = get_size().width - cache.style_normal->get_minimum_size().width - cache.line_number_w - cache.breakpoint_gutter_width - cache.fold_gutter_width - cache.info_gutter_width - cache.minimap_width;
- if (v_scroll->is_visible_in_tree())
+ if (v_scroll->is_visible_in_tree()) {
visible_width -= v_scroll->get_combined_minimum_size().width;
+ }
visible_width -= 20; // Give it a little more space.
if (is_wrap_enabled()) {
// Center x offset.
int cursor_x = get_column_x_offset_for_line(cursor.column, cursor.line);
- if (cursor_x > (cursor.x_ofs + visible_width))
+ if (cursor_x > (cursor.x_ofs + visible_width)) {
cursor.x_ofs = cursor_x - visible_width + 1;
+ }
- if (cursor_x < cursor.x_ofs)
+ if (cursor_x < cursor.x_ofs) {
cursor.x_ofs = cursor_x;
+ }
} else {
cursor.x_ofs = 0;
}
@@ -4372,18 +4339,18 @@ void TextEdit::update_cursor_wrap_offset() {
}
bool TextEdit::line_wraps(int line) const {
-
ERR_FAIL_INDEX_V(line, text.size(), 0);
- if (!is_wrap_enabled())
+ if (!is_wrap_enabled()) {
return false;
+ }
return text.get_line_width(line) > wrap_at;
}
int TextEdit::times_line_wraps(int line) const {
-
ERR_FAIL_INDEX_V(line, text.size(), 0);
- if (!line_wraps(line))
+ if (!line_wraps(line)) {
return 0;
+ }
int wrap_amount = text.get_line_wrap_amount(line);
if (wrap_amount == -1) {
@@ -4397,7 +4364,6 @@ int TextEdit::times_line_wraps(int line) const {
}
Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), Vector<String>());
Vector<String> lines;
@@ -4470,16 +4436,15 @@ Vector<String> TextEdit::get_wrap_rows_text(int p_line) const {
}
int TextEdit::get_cursor_wrap_index() const {
-
return get_line_wrap_index_at_col(cursor.line, cursor.column);
}
int TextEdit::get_line_wrap_index_at_col(int p_line, int p_column) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
- if (!line_wraps(p_line))
+ if (!line_wraps(p_line)) {
return 0;
+ }
// Loop through wraps in the line text until we get to the column.
int wrap_index = 0;
@@ -4489,43 +4454,50 @@ int TextEdit::get_line_wrap_index_at_col(int p_line, int p_column) const {
wrap_index = i;
String s = rows[wrap_index];
col += s.length();
- if (col > p_column)
+ if (col > p_column) {
break;
+ }
}
return wrap_index;
}
void TextEdit::cursor_set_column(int p_col, bool p_adjust_viewport) {
- if (p_col < 0)
+ if (p_col < 0) {
p_col = 0;
+ }
cursor.column = p_col;
- if (cursor.column > get_line(cursor.line).length())
+ if (cursor.column > get_line(cursor.line).length()) {
cursor.column = get_line(cursor.line).length();
+ }
cursor.last_fit_x = get_column_x_offset_for_line(cursor.column, cursor.line);
- if (p_adjust_viewport)
+ if (p_adjust_viewport) {
adjust_viewport_to_cursor();
+ }
if (!cursor_changed_dirty) {
- if (is_inside_tree())
+ if (is_inside_tree()) {
MessageQueue::get_singleton()->push_call(this, "_cursor_changed_emit");
+ }
cursor_changed_dirty = true;
}
}
void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport, bool p_can_be_hidden, int p_wrap_index) {
-
- if (setting_row)
+ if (setting_row) {
return;
+ }
setting_row = true;
- if (p_row < 0)
+ if (p_row < 0) {
p_row = 0;
+ }
- if (p_row >= text.size())
+ if (p_row >= text.size()) {
p_row = text.size() - 1;
+ }
if (!p_can_be_hidden) {
if (is_line_hidden(CLAMP(p_row, 0, text.size() - 1))) {
@@ -4551,30 +4523,31 @@ void TextEdit::cursor_set_line(int p_row, bool p_adjust_viewport, bool p_can_be_
for (int i = 0; i < p_wrap_index + 1; i++) {
row_end_col += rows[i].length();
}
- if (n_col >= row_end_col)
+ if (n_col >= row_end_col) {
n_col -= 1;
+ }
}
cursor.column = n_col;
- if (p_adjust_viewport)
+ if (p_adjust_viewport) {
adjust_viewport_to_cursor();
+ }
setting_row = false;
if (!cursor_changed_dirty) {
- if (is_inside_tree())
+ if (is_inside_tree()) {
MessageQueue::get_singleton()->push_call(this, "_cursor_changed_emit");
+ }
cursor_changed_dirty = true;
}
}
int TextEdit::cursor_get_column() const {
-
return cursor.column;
}
int TextEdit::cursor_get_line() const {
-
return cursor.line;
}
@@ -4628,14 +4601,14 @@ void TextEdit::_v_scroll_input() {
}
void TextEdit::_scroll_moved(double p_to_val) {
-
- if (updating_scrolls)
+ if (updating_scrolls) {
return;
+ }
- if (h_scroll->is_visible_in_tree())
+ if (h_scroll->is_visible_in_tree()) {
cursor.x_ofs = h_scroll->get_value();
+ }
if (v_scroll->is_visible_in_tree()) {
-
// Set line ofs and wrap ofs.
int v_scroll_i = floor(get_v_scroll());
int sc = 0;
@@ -4644,8 +4617,9 @@ void TextEdit::_scroll_moved(double p_to_val) {
if (!is_line_hidden(n_line)) {
sc++;
sc += times_line_wraps(n_line);
- if (sc > v_scroll_i)
+ if (sc > v_scroll_i) {
break;
+ }
}
}
n_line = MIN(n_line, text.size() - 1);
@@ -4660,27 +4634,26 @@ void TextEdit::_scroll_moved(double p_to_val) {
}
int TextEdit::get_row_height() const {
-
return cache.font->get_height() + cache.line_spacing;
}
int TextEdit::get_char_pos_for_line(int p_px, int p_line, int p_wrap_index) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
if (line_wraps(p_line)) {
-
int line_wrap_amount = times_line_wraps(p_line);
int wrap_offset_px = get_indent_level(p_line) * cache.font->get_char_size(' ').width;
if (wrap_offset_px >= wrap_at) {
wrap_offset_px = 0;
}
- if (p_wrap_index > line_wrap_amount)
+ if (p_wrap_index > line_wrap_amount) {
p_wrap_index = line_wrap_amount;
- if (p_wrap_index > 0)
+ }
+ if (p_wrap_index > 0) {
p_px -= wrap_offset_px;
- else
+ } else {
p_wrap_index = 0;
+ }
Vector<String> rows = get_wrap_rows_text(p_line);
int c_pos = get_char_pos_for(p_px, rows[p_wrap_index]);
for (int i = 0; i < p_wrap_index; i++) {
@@ -4690,17 +4663,14 @@ int TextEdit::get_char_pos_for_line(int p_px, int p_line, int p_wrap_index) cons
return c_pos;
} else {
-
return get_char_pos_for(p_px, text[p_line]);
}
}
int TextEdit::get_column_x_offset_for_line(int p_char, int p_line) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
if (line_wraps(p_line)) {
-
int n_char = p_char;
int col = 0;
Vector<String> rows = get_wrap_rows_text(p_line);
@@ -4709,8 +4679,9 @@ int TextEdit::get_column_x_offset_for_line(int p_char, int p_line) const {
wrap_index = i;
String s = rows[wrap_index];
col += s.length();
- if (col > p_char)
+ if (col > p_char) {
break;
+ }
n_char -= s.length();
}
int px = get_column_x_offset(n_char, rows[wrap_index]);
@@ -4719,27 +4690,26 @@ int TextEdit::get_column_x_offset_for_line(int p_char, int p_line) const {
if (wrap_offset_px >= wrap_at) {
wrap_offset_px = 0;
}
- if (wrap_index != 0)
+ if (wrap_index != 0) {
px += wrap_offset_px;
+ }
return px;
} else {
-
return get_column_x_offset(p_char, text[p_line]);
}
}
int TextEdit::get_char_pos_for(int p_px, String p_str) const {
-
int px = 0;
int c = 0;
while (c < p_str.length()) {
-
int w = text.get_char_width(p_str[c], p_str[c + 1], px);
- if (p_px < (px + w / 2))
+ if (p_px < (px + w / 2)) {
break;
+ }
px += w;
c++;
}
@@ -4748,13 +4718,12 @@ int TextEdit::get_char_pos_for(int p_px, String p_str) const {
}
int TextEdit::get_column_x_offset(int p_char, String p_str) const {
-
int px = 0;
for (int i = 0; i < p_char; i++) {
-
- if (i >= p_str.length())
+ if (i >= p_str.length()) {
break;
+ }
px += text.get_char_width(p_str[i], p_str[i + 1], px);
}
@@ -4763,9 +4732,7 @@ int TextEdit::get_column_x_offset(int p_char, String p_str) const {
}
void TextEdit::insert_text_at_cursor(const String &p_text) {
-
if (selection.active) {
-
cursor_set_line(selection.from_line);
cursor_set_column(selection.from_column);
@@ -4779,15 +4746,15 @@ void TextEdit::insert_text_at_cursor(const String &p_text) {
}
Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
- if (highlighted_word != String())
+ if (highlighted_word != String()) {
return CURSOR_POINTING_HAND;
+ }
int gutter = cache.style_normal->get_margin(MARGIN_LEFT) + cache.line_number_w + cache.breakpoint_gutter_width + cache.fold_gutter_width + cache.info_gutter_width;
if ((completion_active && completion_rect.has_point(p_pos))) {
return CURSOR_ARROW;
}
if (p_pos.x < gutter) {
-
int row, col;
_get_mouse_pos(p_pos, row, col);
int left_margin = cache.style_normal->get_margin(MARGIN_LEFT);
@@ -4808,10 +4775,11 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
// Fold icon.
if (draw_fold_gutter && p_pos.x > gutter_left + cache.line_number_w - 6 && p_pos.x <= gutter_left + cache.line_number_w + cache.fold_gutter_width - 3) {
- if (is_folded(row) || can_fold(row))
+ if (is_folded(row) || can_fold(row)) {
return CURSOR_POINTING_HAND;
- else
+ } else {
return CURSOR_ARROW;
+ }
}
return CURSOR_ARROW;
@@ -4837,7 +4805,6 @@ Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
}
void TextEdit::set_text(String p_text) {
-
setting_text = true;
if (!undo_enabled) {
_clear();
@@ -4866,72 +4833,67 @@ String TextEdit::get_text() {
String longthing;
int len = text.size();
for (int i = 0; i < len; i++) {
-
longthing += text[i];
- if (i != len - 1)
+ if (i != len - 1) {
longthing += "\n";
+ }
}
return longthing;
};
String TextEdit::get_text_for_lookup_completion() {
-
int row, col;
_get_mouse_pos(get_local_mouse_position(), row, col);
String longthing;
int len = text.size();
for (int i = 0; i < len; i++) {
-
if (i == row) {
longthing += text[i].substr(0, col);
longthing += String::chr(0xFFFF); // Not unicode, represents the cursor.
longthing += text[i].substr(col, text[i].size());
} else {
-
longthing += text[i];
}
- if (i != len - 1)
+ if (i != len - 1) {
longthing += "\n";
+ }
}
return longthing;
}
String TextEdit::get_text_for_completion() {
-
String longthing;
int len = text.size();
for (int i = 0; i < len; i++) {
-
if (i == cursor.line) {
longthing += text[i].substr(0, cursor.column);
longthing += String::chr(0xFFFF); // Not unicode, represents the cursor.
longthing += text[i].substr(cursor.column, text[i].size());
} else {
-
longthing += text[i];
}
- if (i != len - 1)
+ if (i != len - 1) {
longthing += "\n";
+ }
}
return longthing;
};
String TextEdit::get_line(int line) const {
-
- if (line < 0 || line >= text.size())
+ if (line < 0 || line >= text.size()) {
return "";
+ }
return text[line];
};
void TextEdit::_clear() {
-
clear_undo_history();
text.clear();
cursor.column = 0;
@@ -4944,16 +4906,15 @@ void TextEdit::_clear() {
}
void TextEdit::clear() {
-
setting_text = true;
_clear();
setting_text = false;
};
void TextEdit::set_readonly(bool p_readonly) {
-
- if (readonly == p_readonly)
+ if (readonly == p_readonly) {
return;
+ }
readonly = p_readonly;
_generate_context_menu();
@@ -4988,27 +4949,22 @@ void TextEdit::set_readonly(bool p_readonly) {
}
bool TextEdit::is_readonly() const {
-
return readonly;
}
void TextEdit::set_wrap_enabled(bool p_wrap_enabled) {
-
wrap_enabled = p_wrap_enabled;
}
bool TextEdit::is_wrap_enabled() const {
-
return wrap_enabled;
}
void TextEdit::set_max_chars(int p_max_chars) {
-
max_chars = p_max_chars;
}
int TextEdit::get_max_chars() const {
-
return max_chars;
}
@@ -5031,7 +4987,6 @@ void TextEdit::_toggle_draw_caret() {
}
void TextEdit::_update_caches() {
-
cache.style_normal = get_theme_stylebox("normal");
cache.style_focus = get_theme_stylebox("focus");
cache.style_readonly = get_theme_stylebox("read_only");
@@ -5099,7 +5054,6 @@ void TextEdit::_set_syntax_highlighting(SyntaxHighlighter *p_syntax_highlighter)
}
int TextEdit::_is_line_in_region(int p_line) {
-
// Do we have in cache?
if (color_region_cache.has(p_line)) {
return color_region_cache[p_line];
@@ -5157,7 +5111,6 @@ Map<int, TextEdit::Text::ColorRegionInfo> TextEdit::_get_line_color_region_info(
}
void TextEdit::clear_colors() {
-
keywords.clear();
member_keywords.clear();
color_regions.clear();
@@ -5168,7 +5121,6 @@ void TextEdit::clear_colors() {
}
void TextEdit::add_keyword_color(const String &p_keyword, const Color &p_color) {
-
keywords[p_keyword] = p_color;
syntax_highlighting_cache.clear();
update();
@@ -5179,13 +5131,11 @@ bool TextEdit::has_keyword_color(String p_keyword) const {
}
Color TextEdit::get_keyword_color(String p_keyword) const {
-
ERR_FAIL_COND_V(!keywords.has(p_keyword), Color());
return keywords[p_keyword];
}
void TextEdit::add_color_region(const String &p_begin_key, const String &p_end_key, const Color &p_color, bool p_line_only) {
-
color_regions.push_back(ColorRegion(p_begin_key, p_end_key, p_color, p_line_only));
syntax_highlighting_cache.clear();
text.clear_width_cache();
@@ -5213,13 +5163,11 @@ void TextEdit::clear_member_keywords() {
}
void TextEdit::set_syntax_coloring(bool p_enabled) {
-
syntax_coloring = p_enabled;
update();
}
bool TextEdit::is_syntax_coloring_enabled() const {
-
return syntax_coloring;
}
@@ -5228,9 +5176,7 @@ void TextEdit::set_auto_indent(bool p_auto_indent) {
}
void TextEdit::cut() {
-
if (!selection.active) {
-
String clipboard = text[cursor.line];
DisplayServer::get_singleton()->clipboard_set(clipboard);
cursor_set_line(cursor.line);
@@ -5248,7 +5194,6 @@ void TextEdit::cut() {
cut_copy_line = clipboard;
} else {
-
String clipboard = _base_get_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
DisplayServer::get_singleton()->clipboard_set(clipboard);
@@ -5264,11 +5209,8 @@ void TextEdit::cut() {
}
void TextEdit::copy() {
-
if (!selection.active) {
-
if (text[cursor.line].length() != 0) {
-
String clipboard = _base_get_text(cursor.line, 0, cursor.line, text[cursor.line].length());
DisplayServer::get_singleton()->clipboard_set(clipboard);
cut_copy_line = clipboard;
@@ -5281,12 +5223,10 @@ void TextEdit::copy() {
}
void TextEdit::paste() {
-
String clipboard = DisplayServer::get_singleton()->clipboard_get();
begin_complex_operation();
if (selection.active) {
-
selection.active = false;
selection.selecting_mode = Selection::MODE_NONE;
_remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
@@ -5294,7 +5234,6 @@ void TextEdit::paste() {
cursor_set_column(selection.from_column);
} else if (!cut_copy_line.empty() && cut_copy_line == clipboard) {
-
cursor_set_column(0);
String ins = "\n";
clipboard += ins;
@@ -5307,11 +5246,13 @@ void TextEdit::paste() {
}
void TextEdit::select_all() {
- if (!selecting_enabled)
+ if (!selecting_enabled) {
return;
+ }
- if (text.size() == 1 && text[0].length() == 0)
+ if (text.size() == 1 && text[0].length() == 0) {
return;
+ }
selection.active = true;
selection.from_line = 0;
selection.from_column = 0;
@@ -5327,32 +5268,38 @@ void TextEdit::select_all() {
}
void TextEdit::deselect() {
-
selection.active = false;
update();
}
void TextEdit::select(int p_from_line, int p_from_column, int p_to_line, int p_to_column) {
- if (!selecting_enabled)
+ if (!selecting_enabled) {
return;
+ }
- if (p_from_line < 0)
+ if (p_from_line < 0) {
p_from_line = 0;
- else if (p_from_line >= text.size())
+ } else if (p_from_line >= text.size()) {
p_from_line = text.size() - 1;
- if (p_from_column >= text[p_from_line].length())
+ }
+ if (p_from_column >= text[p_from_line].length()) {
p_from_column = text[p_from_line].length();
- if (p_from_column < 0)
+ }
+ if (p_from_column < 0) {
p_from_column = 0;
+ }
- if (p_to_line < 0)
+ if (p_to_line < 0) {
p_to_line = 0;
- else if (p_to_line >= text.size())
+ } else if (p_to_line >= text.size()) {
p_to_line = text.size() - 1;
- if (p_to_column >= text[p_to_line].length())
+ }
+ if (p_to_column >= text[p_to_line].length()) {
p_to_column = text[p_to_line].length();
- if (p_to_column < 0)
+ }
+ if (p_to_column < 0) {
p_to_column = 0;
+ }
selection.from_line = p_from_line;
selection.from_column = p_from_column;
@@ -5362,89 +5309,86 @@ void TextEdit::select(int p_from_line, int p_from_column, int p_to_line, int p_t
selection.active = true;
if (selection.from_line == selection.to_line) {
-
if (selection.from_column == selection.to_column) {
-
selection.active = false;
} else if (selection.from_column > selection.to_column) {
-
selection.shiftclick_left = false;
SWAP(selection.from_column, selection.to_column);
} else {
-
selection.shiftclick_left = true;
}
} else if (selection.from_line > selection.to_line) {
-
selection.shiftclick_left = false;
SWAP(selection.from_line, selection.to_line);
SWAP(selection.from_column, selection.to_column);
} else {
-
selection.shiftclick_left = true;
}
update();
}
+
void TextEdit::swap_lines(int line1, int line2) {
String tmp = get_line(line1);
String tmp2 = get_line(line2);
set_line(line2, tmp);
set_line(line1, tmp2);
}
-bool TextEdit::is_selection_active() const {
+bool TextEdit::is_selection_active() const {
return selection.active;
}
-int TextEdit::get_selection_from_line() const {
+int TextEdit::get_selection_from_line() const {
ERR_FAIL_COND_V(!selection.active, -1);
return selection.from_line;
}
-int TextEdit::get_selection_from_column() const {
+int TextEdit::get_selection_from_column() const {
ERR_FAIL_COND_V(!selection.active, -1);
return selection.from_column;
}
-int TextEdit::get_selection_to_line() const {
+int TextEdit::get_selection_to_line() const {
ERR_FAIL_COND_V(!selection.active, -1);
return selection.to_line;
}
-int TextEdit::get_selection_to_column() const {
+int TextEdit::get_selection_to_column() const {
ERR_FAIL_COND_V(!selection.active, -1);
return selection.to_column;
}
String TextEdit::get_selection_text() const {
-
- if (!selection.active)
+ if (!selection.active) {
return "";
+ }
return _base_get_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
}
String TextEdit::get_word_under_cursor() const {
-
int prev_cc = cursor.column;
while (prev_cc > 0) {
bool is_char = _is_text_char(text[cursor.line][prev_cc - 1]);
- if (!is_char)
+ if (!is_char) {
break;
+ }
--prev_cc;
}
int next_cc = cursor.column;
while (next_cc < text[cursor.line].length()) {
bool is_char = _is_text_char(text[cursor.line][next_cc]);
- if (!is_char)
+ if (!is_char) {
break;
+ }
++next_cc;
}
- if (prev_cc == cursor.column || next_cc == cursor.column)
+ if (prev_cc == cursor.column || next_cc == cursor.column) {
return "";
+ }
return text[cursor.line].substr(prev_cc, next_cc - prev_cc);
}
@@ -5503,26 +5447,23 @@ int TextEdit::_get_column_pos_of_word(const String &p_key, const String &p_searc
return col;
}
-Vector<int> TextEdit::_search_bind(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const {
-
+Dictionary TextEdit::_search_bind(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const {
int col, line;
if (search(p_key, p_search_flags, p_from_line, p_from_column, line, col)) {
- Vector<int> result;
- result.resize(2);
- result.set(SEARCH_RESULT_COLUMN, col);
- result.set(SEARCH_RESULT_LINE, line);
+ Dictionary result;
+ result["line"] = line;
+ result["column"] = col;
return result;
} else {
-
- return Vector<int>();
+ return Dictionary();
}
}
bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column, int &r_line, int &r_column) const {
-
- if (p_key.length() == 0)
+ if (p_key.length() == 0) {
return false;
+ }
ERR_FAIL_INDEX_V(p_from_line, text.size(), false);
ERR_FAIL_INDEX_V(p_from_column, text[p_from_line].length() + 1, false);
@@ -5532,7 +5473,6 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
int pos = -1;
for (int i = 0; i < text.size() + 1; i++) {
-
if (line < 0) {
line = text.size() - 1;
}
@@ -5543,7 +5483,6 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
String text_line = text[line];
int from_column = 0;
if (line == p_from_line) {
-
if (i == text.size()) {
// Wrapped.
@@ -5554,15 +5493,15 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
}
} else {
-
from_column = p_from_column;
}
} else {
- if (p_search_flags & SEARCH_BACKWARDS)
+ if (p_search_flags & SEARCH_BACKWARDS) {
from_column = text_line.length() - 1;
- else
+ } else {
from_column = 0;
+ }
}
pos = -1;
@@ -5571,7 +5510,6 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
int last_pos = -1;
while (true) {
-
if (p_search_flags & SEARCH_BACKWARDS) {
while ((last_pos = (p_search_flags & SEARCH_MATCH_CASE) ? text_line.rfind(p_key, pos_from) : text_line.rfindn(p_key, pos_from)) != -1) {
if (last_pos <= from_column) {
@@ -5597,10 +5535,11 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
if (pos != -1 && (p_search_flags & SEARCH_WHOLE_WORDS)) {
// Validate for whole words.
- if (pos > 0 && _is_text_char(text_line[pos - 1]))
+ if (pos > 0 && _is_text_char(text_line[pos - 1])) {
is_match = false;
- else if (pos + p_key.length() < text_line.length() && _is_text_char(text_line[pos + p_key.length()]))
+ } else if (pos + p_key.length() < text_line.length() && _is_text_char(text_line[pos + p_key.length()])) {
is_match = false;
+ }
}
if (pos_from == -1) {
@@ -5615,13 +5554,15 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
pos = -1;
}
- if (pos != -1)
+ if (pos != -1) {
break;
+ }
- if (p_search_flags & SEARCH_BACKWARDS)
+ if (p_search_flags & SEARCH_BACKWARDS) {
line--;
- else
+ } else {
line++;
+ }
}
if (pos == -1) {
@@ -5637,19 +5578,16 @@ bool TextEdit::search(const String &p_key, uint32_t p_search_flags, int p_from_l
}
void TextEdit::_cursor_changed_emit() {
-
emit_signal("cursor_changed");
cursor_changed_dirty = false;
}
void TextEdit::_text_changed_emit() {
-
emit_signal("text_changed");
text_changed_dirty = false;
}
void TextEdit::set_line_as_marked(int p_line, bool p_marked) {
-
ERR_FAIL_INDEX(p_line, text.size());
text.set_marked(p_line, p_marked);
update();
@@ -5678,72 +5616,69 @@ void TextEdit::clear_executing_line() {
}
bool TextEdit::is_line_set_as_bookmark(int p_line) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), false);
return text.is_bookmark(p_line);
}
void TextEdit::set_line_as_bookmark(int p_line, bool p_bookmark) {
-
ERR_FAIL_INDEX(p_line, text.size());
text.set_bookmark(p_line, p_bookmark);
update();
}
void TextEdit::get_bookmarks(List<int> *p_bookmarks) const {
-
for (int i = 0; i < text.size(); i++) {
- if (text.is_bookmark(i))
+ if (text.is_bookmark(i)) {
p_bookmarks->push_back(i);
+ }
}
}
Array TextEdit::get_bookmarks_array() const {
-
Array arr;
for (int i = 0; i < text.size(); i++) {
- if (text.is_bookmark(i))
+ if (text.is_bookmark(i)) {
arr.append(i);
+ }
}
return arr;
}
bool TextEdit::is_line_set_as_breakpoint(int p_line) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), false);
return text.is_breakpoint(p_line);
}
void TextEdit::set_line_as_breakpoint(int p_line, bool p_breakpoint) {
-
ERR_FAIL_INDEX(p_line, text.size());
text.set_breakpoint(p_line, p_breakpoint);
update();
}
void TextEdit::get_breakpoints(List<int> *p_breakpoints) const {
-
for (int i = 0; i < text.size(); i++) {
- if (text.is_breakpoint(i))
+ if (text.is_breakpoint(i)) {
p_breakpoints->push_back(i);
+ }
}
}
Array TextEdit::get_breakpoints_array() const {
-
Array arr;
for (int i = 0; i < text.size(); i++) {
- if (text.is_breakpoint(i))
+ if (text.is_breakpoint(i)) {
arr.append(i);
+ }
}
return arr;
}
void TextEdit::remove_breakpoints() {
for (int i = 0; i < text.size(); i++) {
- if (text.is_breakpoint(i))
+ if (text.is_breakpoint(i)) {
/* Should "breakpoint_toggled" be fired when breakpoints are removed this way? */
text.set_breakpoint(i, false);
+ }
}
}
@@ -5759,21 +5694,19 @@ void TextEdit::clear_info_icons() {
}
void TextEdit::set_line_as_hidden(int p_line, bool p_hidden) {
-
ERR_FAIL_INDEX(p_line, text.size());
- if (is_hiding_enabled() || !p_hidden)
+ if (is_hiding_enabled() || !p_hidden) {
text.set_hidden(p_line, p_hidden);
+ }
update();
}
bool TextEdit::is_line_hidden(int p_line) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), false);
return text.is_hidden(p_line);
}
void TextEdit::fold_all_lines() {
-
for (int i = 0; i < text.size(); i++) {
fold_line(i);
}
@@ -5782,7 +5715,6 @@ void TextEdit::fold_all_lines() {
}
void TextEdit::unhide_all_lines() {
-
for (int i = 0; i < text.size(); i++) {
text.set_hidden(i, false);
}
@@ -5791,12 +5723,12 @@ void TextEdit::unhide_all_lines() {
}
int TextEdit::num_lines_from(int p_line_from, int visible_amount) const {
-
// Returns the number of lines (hidden and unhidden) from p_line_from to (p_line_from + visible_amount of unhidden lines).
ERR_FAIL_INDEX_V(p_line_from, text.size(), ABS(visible_amount));
- if (!is_hiding_enabled())
+ if (!is_hiding_enabled()) {
return ABS(visible_amount);
+ }
int num_visible = 0;
int num_total = 0;
@@ -5806,8 +5738,9 @@ int TextEdit::num_lines_from(int p_line_from, int visible_amount) const {
if (!is_line_hidden(i)) {
num_visible++;
}
- if (num_visible >= visible_amount)
+ if (num_visible >= visible_amount) {
break;
+ }
}
} else {
visible_amount = ABS(visible_amount);
@@ -5816,22 +5749,23 @@ int TextEdit::num_lines_from(int p_line_from, int visible_amount) const {
if (!is_line_hidden(i)) {
num_visible++;
}
- if (num_visible >= visible_amount)
+ if (num_visible >= visible_amount) {
break;
+ }
}
}
return num_total;
}
int TextEdit::num_lines_from_rows(int p_line_from, int p_wrap_index_from, int visible_amount, int &wrap_index) const {
-
// Returns the number of lines (hidden and unhidden) from (p_line_from + p_wrap_index_from) row to (p_line_from + visible_amount of unhidden and wrapped rows).
// Wrap index is set to the wrap index of the last line.
wrap_index = 0;
ERR_FAIL_INDEX_V(p_line_from, text.size(), ABS(visible_amount));
- if (!is_hiding_enabled() && !is_wrap_enabled())
+ if (!is_hiding_enabled() && !is_wrap_enabled()) {
return ABS(visible_amount);
+ }
int num_visible = 0;
int num_total = 0;
@@ -5847,8 +5781,9 @@ int TextEdit::num_lines_from_rows(int p_line_from, int p_wrap_index_from, int vi
num_visible++;
num_visible += times_line_wraps(i);
}
- if (num_visible >= visible_amount)
+ if (num_visible >= visible_amount) {
break;
+ }
}
wrap_index = times_line_wraps(MIN(i, text.size() - 1)) - (num_visible - visible_amount);
} else {
@@ -5861,8 +5796,9 @@ int TextEdit::num_lines_from_rows(int p_line_from, int p_wrap_index_from, int vi
num_visible++;
num_visible += times_line_wraps(i);
}
- if (num_visible >= visible_amount)
+ if (num_visible >= visible_amount) {
break;
+ }
}
wrap_index = (num_visible - visible_amount);
}
@@ -5871,10 +5807,10 @@ int TextEdit::num_lines_from_rows(int p_line_from, int p_wrap_index_from, int vi
}
int TextEdit::get_last_unhidden_line() const {
-
// Returns the last line in the text that is not hidden.
- if (!is_hiding_enabled())
+ if (!is_hiding_enabled()) {
return text.size() - 1;
+ }
int last_line;
for (last_line = text.size() - 1; last_line > 0; last_line--) {
@@ -5886,7 +5822,6 @@ int TextEdit::get_last_unhidden_line() const {
}
int TextEdit::get_indent_level(int p_line) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), 0);
// Counts number of tabs and spaces before line starts.
@@ -5906,7 +5841,6 @@ int TextEdit::get_indent_level(int p_line) const {
}
bool TextEdit::is_line_comment(int p_line) const {
-
// Checks to see if this line is the start of a comment.
ERR_FAIL_INDEX_V(p_line, text.size(), false);
@@ -5927,26 +5861,32 @@ bool TextEdit::is_line_comment(int p_line) const {
}
bool TextEdit::can_fold(int p_line) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), false);
- if (!is_hiding_enabled())
+ if (!is_hiding_enabled()) {
return false;
- if (p_line + 1 >= text.size())
+ }
+ if (p_line + 1 >= text.size()) {
return false;
- if (text[p_line].strip_edges().size() == 0)
+ }
+ if (text[p_line].strip_edges().size() == 0) {
return false;
- if (is_folded(p_line))
+ }
+ if (is_folded(p_line)) {
return false;
- if (is_line_hidden(p_line))
+ }
+ if (is_line_hidden(p_line)) {
return false;
- if (is_line_comment(p_line))
+ }
+ if (is_line_comment(p_line)) {
return false;
+ }
int start_indent = get_indent_level(p_line);
for (int i = p_line + 1; i < text.size(); i++) {
- if (text[i].strip_edges().size() == 0)
+ if (text[i].strip_edges().size() == 0) {
continue;
+ }
int next_indent = get_indent_level(i);
if (is_line_comment(i)) {
continue;
@@ -5961,10 +5901,10 @@ bool TextEdit::can_fold(int p_line) const {
}
bool TextEdit::is_folded(int p_line) const {
-
ERR_FAIL_INDEX_V(p_line, text.size(), false);
- if (p_line + 1 >= text.size())
+ if (p_line + 1 >= text.size()) {
return false;
+ }
return !is_line_hidden(p_line) && is_line_hidden(p_line + 1);
}
@@ -5980,12 +5920,13 @@ Vector<int> TextEdit::get_folded_lines() const {
}
void TextEdit::fold_line(int p_line) {
-
ERR_FAIL_INDEX(p_line, text.size());
- if (!is_hiding_enabled())
+ if (!is_hiding_enabled()) {
return;
- if (!can_fold(p_line))
+ }
+ if (!can_fold(p_line)) {
return;
+ }
// Hide lines below this one.
int start_indent = get_indent_level(p_line);
@@ -6026,15 +5967,16 @@ void TextEdit::fold_line(int p_line) {
}
void TextEdit::unfold_line(int p_line) {
-
ERR_FAIL_INDEX(p_line, text.size());
- if (!is_folded(p_line) && !is_line_hidden(p_line))
+ if (!is_folded(p_line) && !is_line_hidden(p_line)) {
return;
+ }
int fold_start;
for (fold_start = p_line; fold_start > 0; fold_start--) {
- if (is_folded(fold_start))
+ if (is_folded(fold_start)) {
break;
+ }
}
fold_start = is_folded(fold_start) ? fold_start : p_line;
@@ -6050,45 +5992,42 @@ void TextEdit::unfold_line(int p_line) {
}
void TextEdit::toggle_fold_line(int p_line) {
-
ERR_FAIL_INDEX(p_line, text.size());
- if (!is_folded(p_line))
+ if (!is_folded(p_line)) {
fold_line(p_line);
- else
+ } else {
unfold_line(p_line);
+ }
}
int TextEdit::get_line_count() const {
-
return text.size();
}
void TextEdit::_do_text_op(const TextOperation &p_op, bool p_reverse) {
-
ERR_FAIL_COND(p_op.type == TextOperation::TYPE_NONE);
bool insert = p_op.type == TextOperation::TYPE_INSERT;
- if (p_reverse)
+ if (p_reverse) {
insert = !insert;
+ }
if (insert) {
-
int check_line;
int check_column;
_base_insert_text(p_op.from_line, p_op.from_column, p_op.text, check_line, check_column);
ERR_FAIL_COND(check_line != p_op.to_line); // BUG.
ERR_FAIL_COND(check_column != p_op.to_column); // BUG.
} else {
-
_base_remove_text(p_op.from_line, p_op.from_column, p_op.to_line, p_op.to_column);
}
}
void TextEdit::_clear_redo() {
-
- if (undo_stack_pos == nullptr)
+ if (undo_stack_pos == nullptr) {
return; // Nothing to clear.
+ }
_push_current_op();
@@ -6100,27 +6039,28 @@ void TextEdit::_clear_redo() {
}
void TextEdit::undo() {
-
_push_current_op();
if (undo_stack_pos == nullptr) {
-
- if (!undo_stack.size())
+ if (!undo_stack.size()) {
return; // Nothing to undo.
+ }
undo_stack_pos = undo_stack.back();
- } else if (undo_stack_pos == undo_stack.front())
+ } else if (undo_stack_pos == undo_stack.front()) {
return; // At the bottom of the undo stack.
- else
+ } else {
undo_stack_pos = undo_stack_pos->prev();
+ }
deselect();
TextOperation op = undo_stack_pos->get();
_do_text_op(op, true);
- if (op.type != TextOperation::TYPE_INSERT && (op.from_line != op.to_line || op.to_column != op.from_column + 1))
+ if (op.type != TextOperation::TYPE_INSERT && (op.from_line != op.to_line || op.to_column != op.from_column + 1)) {
select(op.from_line, op.from_column, op.to_line, op.to_column);
+ }
current_op.version = op.prev_version;
if (undo_stack_pos->get().chain_backward) {
@@ -6149,11 +6089,11 @@ void TextEdit::undo() {
}
void TextEdit::redo() {
-
_push_current_op();
- if (undo_stack_pos == nullptr)
+ if (undo_stack_pos == nullptr) {
return; // Nothing to do.
+ }
deselect();
@@ -6161,15 +6101,15 @@ void TextEdit::redo() {
_do_text_op(op, false);
current_op.version = op.version;
if (undo_stack_pos->get().chain_forward) {
-
while (true) {
ERR_BREAK(!undo_stack_pos->next());
undo_stack_pos = undo_stack_pos->next();
op = undo_stack_pos->get();
_do_text_op(op, false);
current_op.version = op.version;
- if (undo_stack_pos->get().chain_backward)
+ if (undo_stack_pos->get().chain_backward) {
break;
+ }
}
}
@@ -6181,7 +6121,6 @@ void TextEdit::redo() {
}
void TextEdit::clear_undo_history() {
-
saved_version = 0;
current_op.type = TextOperation::TYPE_NONE;
undo_stack_pos = nullptr;
@@ -6194,7 +6133,6 @@ void TextEdit::begin_complex_operation() {
}
void TextEdit::end_complex_operation() {
-
_push_current_op();
ERR_FAIL_COND(undo_stack.size() == 0);
@@ -6207,9 +6145,9 @@ void TextEdit::end_complex_operation() {
}
void TextEdit::_push_current_op() {
-
- if (current_op.type == TextOperation::TYPE_NONE)
+ if (current_op.type == TextOperation::TYPE_NONE) {
return; // Nothing to do.
+ }
if (next_operation_is_complex) {
current_op.chain_forward = true;
@@ -6220,6 +6158,10 @@ void TextEdit::_push_current_op() {
current_op.type = TextOperation::TYPE_NONE;
current_op.text = "";
current_op.chain_forward = false;
+
+ if (undo_stack.size() > undo_stack_max_size) {
+ undo_stack.pop_front();
+ }
}
void TextEdit::set_indent_using_spaces(const bool p_use_spaces) {
@@ -6244,28 +6186,23 @@ void TextEdit::set_indent_size(const int p_size) {
}
int TextEdit::get_indent_size() {
-
return indent_size;
}
void TextEdit::set_draw_tabs(bool p_draw) {
-
draw_tabs = p_draw;
update();
}
bool TextEdit::is_drawing_tabs() const {
-
return draw_tabs;
}
void TextEdit::set_draw_spaces(bool p_draw) {
-
draw_spaces = p_draw;
}
bool TextEdit::is_drawing_spaces() const {
-
return draw_spaces;
}
@@ -6295,19 +6232,17 @@ uint32_t TextEdit::get_version() const {
}
uint32_t TextEdit::get_saved_version() const {
-
return saved_version;
}
void TextEdit::tag_saved_version() {
-
saved_version = get_version();
}
double TextEdit::get_scroll_pos_for_line(int p_line, int p_wrap_index) const {
-
- if (!is_wrap_enabled() && !is_hiding_enabled())
+ if (!is_wrap_enabled() && !is_hiding_enabled()) {
return p_line;
+ }
// Count the number of visible lines up to this line.
double new_line_scroll_pos = 0;
@@ -6323,12 +6258,10 @@ double TextEdit::get_scroll_pos_for_line(int p_line, int p_wrap_index) const {
}
void TextEdit::set_line_as_first_visible(int p_line, int p_wrap_index) {
-
set_v_scroll(get_scroll_pos_for_line(p_line, p_wrap_index));
}
void TextEdit::set_line_as_center_visible(int p_line, int p_wrap_index) {
-
int visible_rows = get_visible_rows();
int wi;
int first_line = p_line - num_lines_from_rows(p_line, p_wrap_index, -visible_rows / 2, wi) + 1;
@@ -6337,7 +6270,6 @@ void TextEdit::set_line_as_center_visible(int p_line, int p_wrap_index) {
}
void TextEdit::set_line_as_last_visible(int p_line, int p_wrap_index) {
-
int wi;
int first_line = p_line - num_lines_from_rows(p_line, p_wrap_index, -get_visible_rows() - 1, wi) + 1;
@@ -6345,12 +6277,10 @@ void TextEdit::set_line_as_last_visible(int p_line, int p_wrap_index) {
}
int TextEdit::get_first_visible_line() const {
-
return CLAMP(cursor.line_ofs, 0, text.size() - 1);
}
int TextEdit::get_last_visible_line() const {
-
int first_vis_line = get_first_visible_line();
int last_vis_line = 0;
int wi;
@@ -6360,7 +6290,6 @@ int TextEdit::get_last_visible_line() const {
}
int TextEdit::get_last_visible_line_wrap_index() const {
-
int first_vis_line = get_first_visible_line();
int wi;
num_lines_from_rows(first_vis_line, cursor.wrap_ofs, get_visible_rows() + 1, wi);
@@ -6368,7 +6297,6 @@ int TextEdit::get_last_visible_line_wrap_index() const {
}
double TextEdit::get_visible_rows_offset() const {
-
double total = _get_control_height();
total /= (double)get_row_height();
total = total - floor(total);
@@ -6377,31 +6305,27 @@ double TextEdit::get_visible_rows_offset() const {
}
double TextEdit::get_v_scroll_offset() const {
-
double val = get_v_scroll() - floor(get_v_scroll());
return CLAMP(val, 0, 1);
}
double TextEdit::get_v_scroll() const {
-
return v_scroll->get_value();
}
void TextEdit::set_v_scroll(double p_scroll) {
-
v_scroll->set_value(p_scroll);
int max_v_scroll = v_scroll->get_max() - v_scroll->get_page();
- if (p_scroll >= max_v_scroll - 1.0)
+ if (p_scroll >= max_v_scroll - 1.0) {
_scroll_moved(v_scroll->get_value());
+ }
}
int TextEdit::get_h_scroll() const {
-
return h_scroll->get_value();
}
void TextEdit::set_h_scroll(int p_scroll) {
-
if (p_scroll < 0) {
p_scroll = 0;
}
@@ -6409,36 +6333,31 @@ void TextEdit::set_h_scroll(int p_scroll) {
}
void TextEdit::set_smooth_scroll_enabled(bool p_enable) {
-
v_scroll->set_smooth_scroll_enabled(p_enable);
smooth_scroll_enabled = p_enable;
}
bool TextEdit::is_smooth_scroll_enabled() const {
-
return smooth_scroll_enabled;
}
void TextEdit::set_v_scroll_speed(float p_speed) {
-
v_scroll_speed = p_speed;
}
float TextEdit::get_v_scroll_speed() const {
-
return v_scroll_speed;
}
void TextEdit::set_completion(bool p_enabled, const Vector<String> &p_prefixes) {
-
completion_prefixes.clear();
completion_enabled = p_enabled;
- for (int i = 0; i < p_prefixes.size(); i++)
+ for (int i = 0; i < p_prefixes.size(); i++) {
completion_prefixes.insert(p_prefixes[i]);
+ }
}
void TextEdit::_confirm_completion() {
-
begin_complex_operation();
_remove_text(cursor.line, cursor.column - completion_base.length(), cursor.line, cursor.column);
@@ -6456,7 +6375,6 @@ void TextEdit::_confirm_completion() {
}
if (last_completion_char == '(') {
-
if (next_char == last_completion_char) {
_base_remove_text(cursor.line, cursor.column - 1, cursor.line, cursor.column);
} else if (auto_brace_completion_enabled) {
@@ -6464,7 +6382,6 @@ void TextEdit::_confirm_completion() {
cursor.column--;
}
} else if (last_completion_char == ')' && next_char == '(') {
-
_base_remove_text(cursor.line, cursor.column - 2, cursor.line, cursor.column);
if (line[cursor.column + 1] != ')') {
cursor.column--;
@@ -6481,15 +6398,14 @@ void TextEdit::_confirm_completion() {
}
void TextEdit::_cancel_code_hint() {
-
completion_hint = "";
update();
}
void TextEdit::_cancel_completion() {
-
- if (!completion_active)
+ if (!completion_active) {
return;
+ }
completion_active = false;
completion_forced = false;
@@ -6497,12 +6413,10 @@ void TextEdit::_cancel_completion() {
}
static bool _is_completable(CharType c) {
-
return !_is_symbol(c) || c == '"' || c == '\'';
}
void TextEdit::_update_completion_candidates() {
-
String l = text[cursor.line];
int cofs = CLAMP(cursor.column, 0, l.length());
@@ -6518,8 +6432,9 @@ void TextEdit::_update_completion_candidates() {
while (c >= 0) {
if (l[c] == '"' || l[c] == '\'') {
inquote = !inquote;
- if (first_quote == -1)
+ if (first_quote == -1) {
first_quote = c;
+ }
restore_quotes = 0;
} else if (restore_quotes == 0 && l[c] == '$') {
restore_quotes = 1;
@@ -6536,13 +6451,13 @@ void TextEdit::_update_completion_candidates() {
// No completion here.
cancel = true;
} else if (inquote && first_quote != -1) {
-
s = l.substr(first_quote, cofs - first_quote);
} else if (cofs > 0 && l[cofs - 1] == ' ') {
int kofs = cofs - 1;
String kw;
- while (kofs >= 0 && l[kofs] == ' ')
+ while (kofs >= 0 && l[kofs] == ' ') {
kofs--;
+ }
while (kofs >= 0 && l[kofs] > 32 && _is_completable(l[kofs])) {
kw = String::chr(l[kofs]) + kw;
@@ -6552,11 +6467,11 @@ void TextEdit::_update_completion_candidates() {
pre_keyword = keywords.has(kw);
} else {
-
while (cofs > 0 && l[cofs - 1] > 32 && (l[cofs - 1] == '/' || _is_completable(l[cofs - 1]))) {
s = String::chr(l[cofs - 1]) + s;
- if (l[cofs - 1] == '\'' || l[cofs - 1] == '"' || l[cofs - 1] == '$')
+ if (l[cofs - 1] == '\'' || l[cofs - 1] == '"' || l[cofs - 1] == '$') {
break;
+ }
cofs--;
}
@@ -6569,11 +6484,13 @@ void TextEdit::_update_completion_candidates() {
update();
bool prev_is_prefix = false;
- if (cofs > 0 && completion_prefixes.has(String::chr(l[cofs - 1])))
+ if (cofs > 0 && completion_prefixes.has(String::chr(l[cofs - 1]))) {
prev_is_prefix = true;
+ }
// Check with one space before prefix, to allow indent.
- if (cofs > 1 && l[cofs - 1] == ' ' && completion_prefixes.has(String::chr(l[cofs - 2])))
+ if (cofs > 1 && l[cofs - 1] == ' ' && completion_prefixes.has(String::chr(l[cofs - 2]))) {
prev_is_prefix = true;
+ }
if (cancel || (!pre_keyword && s == "" && (cofs == 0 || !prev_is_prefix))) {
// None to complete, cancel.
@@ -6610,7 +6527,6 @@ void TextEdit::_update_completion_candidates() {
} else if (s.length() == 0) {
completion_options.push_back(option);
} else {
-
// This code works the same as:
/*
if (option.display.begins_with(s)) {
@@ -6685,7 +6601,6 @@ void TextEdit::_update_completion_candidates() {
}
void TextEdit::query_code_comple() {
-
String l = text[cursor.line];
int ofs = CLAMP(cursor.column, 0, l.length());
@@ -6693,8 +6608,9 @@ void TextEdit::query_code_comple() {
int c = ofs - 1;
while (c >= 0) {
- if (l[c] == '"' || l[c] == '\'')
+ if (l[c] == '"' || l[c] == '\'') {
inquote = !inquote;
+ }
c--;
}
@@ -6717,22 +6633,21 @@ void TextEdit::query_code_comple() {
}
if (!ignored) {
- if (ofs > 0 && (inquote || _is_completable(l[ofs - 1]) || completion_prefixes.has(String::chr(l[ofs - 1]))))
+ if (ofs > 0 && (inquote || _is_completable(l[ofs - 1]) || completion_prefixes.has(String::chr(l[ofs - 1])))) {
emit_signal("request_completion");
- else if (ofs > 1 && l[ofs - 1] == ' ' && completion_prefixes.has(String::chr(l[ofs - 2]))) // Make it work with a space too, it's good enough.
+ } else if (ofs > 1 && l[ofs - 1] == ' ' && completion_prefixes.has(String::chr(l[ofs - 2]))) { // Make it work with a space too, it's good enough.
emit_signal("request_completion");
+ }
}
}
void TextEdit::set_code_hint(const String &p_hint) {
-
completion_hint = p_hint;
completion_hint_offset = -0xFFFF;
update();
}
void TextEdit::code_complete(const List<ScriptCodeCompletionOption> &p_strings, bool p_forced) {
-
completion_sources = p_strings;
completion_active = true;
completion_forced = p_forced;
@@ -6742,16 +6657,15 @@ void TextEdit::code_complete(const List<ScriptCodeCompletionOption> &p_strings,
}
String TextEdit::get_word_at_pos(const Vector2 &p_pos) const {
-
int row, col;
_get_mouse_pos(p_pos, row, col);
String s = text[row];
- if (s.length() == 0)
+ if (s.length() == 0) {
return "";
+ }
int beg, end;
if (select_word(s, col, beg, end)) {
-
bool inside_quotes = false;
CharType selected_quote = '\0';
int qbegin = 0, qend = 0;
@@ -6781,18 +6695,18 @@ String TextEdit::get_word_at_pos(const Vector2 &p_pos) const {
}
String TextEdit::get_tooltip(const Point2 &p_pos) const {
-
- if (!tooltip_obj)
+ if (!tooltip_obj) {
return Control::get_tooltip(p_pos);
+ }
int row, col;
_get_mouse_pos(p_pos, row, col);
String s = text[row];
- if (s.length() == 0)
+ if (s.length() == 0) {
return Control::get_tooltip(p_pos);
+ }
int beg, end;
if (select_word(s, col, beg, end)) {
-
String tt = tooltip_obj->call(tooltip_func, s.substr(beg, end - beg), tooltip_ud);
return tt;
@@ -6802,15 +6716,15 @@ String TextEdit::get_tooltip(const Point2 &p_pos) const {
}
void TextEdit::set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata) {
-
tooltip_obj = p_obj;
tooltip_func = p_function;
tooltip_ud = p_udata;
}
void TextEdit::set_line(int line, String new_text) {
- if (line < 0 || line > text.size())
+ if (line < 0 || line > text.size()) {
return;
+ }
_remove_text(line, 0, line, text[line].length());
_insert_text(line, 0, new_text);
if (cursor.line == line) {
@@ -6840,13 +6754,11 @@ void TextEdit::insert_at(const String &p_text, int at) {
}
void TextEdit::set_show_line_numbers(bool p_show) {
-
line_numbers = p_show;
update();
}
void TextEdit::set_line_numbers_zero_padded(bool p_zero_padded) {
-
line_numbers_zero_padded = p_zero_padded;
update();
}
@@ -6952,8 +6864,9 @@ int TextEdit::get_minimap_width() const {
}
void TextEdit::set_hiding_enabled(bool p_enabled) {
- if (!p_enabled)
+ if (!p_enabled) {
unhide_all_lines();
+ }
hiding_enabled = p_enabled;
update();
}
@@ -6972,12 +6885,10 @@ bool TextEdit::is_highlight_current_line_enabled() const {
}
bool TextEdit::is_text_field() const {
-
return true;
}
void TextEdit::menu_option(int p_option) {
-
switch (p_option) {
case MENU_CUT: {
if (!readonly) {
@@ -7015,12 +6926,10 @@ void TextEdit::set_highlighted_word(const String &new_word) {
}
void TextEdit::set_select_identifiers_on_hover(bool p_enable) {
-
select_identifiers_enabled = p_enable;
}
bool TextEdit::is_selecting_identifiers_on_hover_enabled() const {
-
return select_identifiers_enabled;
}
@@ -7041,8 +6950,9 @@ void TextEdit::set_shortcut_keys_enabled(bool p_enabled) {
void TextEdit::set_selecting_enabled(bool p_enabled) {
selecting_enabled = p_enabled;
- if (!selecting_enabled)
+ if (!selecting_enabled) {
deselect();
+ }
_generate_context_menu();
}
@@ -7060,7 +6970,6 @@ PopupMenu *TextEdit::get_menu() const {
}
void TextEdit::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &TextEdit::_gui_input);
ClassDB::bind_method(D_METHOD("_cursor_changed_emit"), &TextEdit::_cursor_changed_emit);
ClassDB::bind_method(D_METHOD("_text_changed_emit"), &TextEdit::_text_changed_emit);
@@ -7070,9 +6979,6 @@ void TextEdit::_bind_methods() {
BIND_ENUM_CONSTANT(SEARCH_WHOLE_WORDS);
BIND_ENUM_CONSTANT(SEARCH_BACKWARDS);
- BIND_ENUM_CONSTANT(SEARCH_RESULT_COLUMN);
- BIND_ENUM_CONSTANT(SEARCH_RESULT_LINE);
-
/*
ClassDB::bind_method(D_METHOD("delete_char"),&TextEdit::delete_char);
ClassDB::bind_method(D_METHOD("delete_line"),&TextEdit::delete_line);
@@ -7084,6 +6990,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_line_count"), &TextEdit::get_line_count);
ClassDB::bind_method(D_METHOD("get_text"), &TextEdit::get_text);
ClassDB::bind_method(D_METHOD("get_line", "line"), &TextEdit::get_line);
+ ClassDB::bind_method(D_METHOD("set_line", "line", "new_text"), &TextEdit::set_line);
ClassDB::bind_method(D_METHOD("center_viewport_to_cursor"), &TextEdit::center_viewport_to_cursor);
ClassDB::bind_method(D_METHOD("cursor_set_column", "column", "adjust_viewport"), &TextEdit::cursor_set_column, DEFVAL(true));
@@ -7244,10 +7151,11 @@ void TextEdit::_bind_methods() {
GLOBAL_DEF("gui/timers/text_edit_idle_detect_sec", 3);
ProjectSettings::get_singleton()->set_custom_property_info("gui/timers/text_edit_idle_detect_sec", PropertyInfo(Variant::FLOAT, "gui/timers/text_edit_idle_detect_sec", PROPERTY_HINT_RANGE, "0,10,0.01,or_greater")); // No negative numbers.
+ GLOBAL_DEF("gui/common/text_edit_undo_stack_max_size", 1024);
+ ProjectSettings::get_singleton()->set_custom_property_info("gui/common/text_edit_undo_stack_max_size", PropertyInfo(Variant::INT, "gui/common/text_edit_undo_stack_max_size", PROPERTY_HINT_RANGE, "0,10000,1,or_greater")); // No negative numbers.
}
TextEdit::TextEdit() {
-
setting_row = false;
draw_tabs = false;
draw_spaces = false;
@@ -7323,6 +7231,7 @@ TextEdit::TextEdit() {
current_op.type = TextOperation::TYPE_NONE;
undo_enabled = true;
+ undo_stack_max_size = GLOBAL_GET("gui/common/text_edit_undo_stack_max_size");
undo_stack_pos = nullptr;
setting_text = false;
last_dblclk = 0;
@@ -7492,10 +7401,10 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
}
if (in_region == -1 && !in_keyword && is_char && !prev_is_char) {
-
int to = j;
- while (to < str.length() && _is_text_char(str[to]))
+ while (to < str.length() && _is_text_char(str[to])) {
to++;
+ }
uint32_t hash = String::hash(&str[j], to - j);
StrRange range(&str[j], to - j);
@@ -7524,7 +7433,6 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
}
if (!in_function_name && in_word && !in_keyword) {
-
int k = j;
while (k < str.length() && !_is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') {
k++;
@@ -7556,18 +7464,19 @@ Map<int, TextEdit::HighlighterInfo> TextEdit::_get_line_syntax_highlighting(int
in_member_variable = false;
}
- if (in_region >= 0)
+ if (in_region >= 0) {
color = color_regions[in_region].color;
- else if (in_keyword)
+ } else if (in_keyword) {
color = keyword_color;
- else if (in_member_variable)
+ } else if (in_member_variable) {
color = cache.member_variable_color;
- else if (in_function_name)
+ } else if (in_function_name) {
color = cache.function_color;
- else if (is_symbol)
+ } else if (is_symbol) {
color = cache.symbol_color;
- else if (is_number)
+ } else if (is_number) {
color = cache.number_color;
+ }
prev_is_char = is_char;
prev_is_number = is_number;
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index ef8c39d32f..ab78f77d94 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -39,7 +39,6 @@
class SyntaxHighlighter;
class TextEdit : public Control {
-
GDCLASS(TextEdit, Control);
public:
@@ -48,7 +47,6 @@ public:
};
struct ColorRegion {
-
Color color;
String begin_key;
String end_key;
@@ -66,7 +64,6 @@ public:
class Text {
public:
struct ColorRegionInfo {
-
int region;
bool end;
ColorRegionInfo() {
@@ -168,7 +165,6 @@ private:
} cursor;
struct Selection {
-
enum Mode {
MODE_NONE,
@@ -207,7 +203,6 @@ private:
} selection;
struct Cache {
-
Ref<Texture2D> tab_icon;
Ref<Texture2D> space_icon;
Ref<Texture2D> can_fold_icon;
@@ -256,7 +251,6 @@ private:
int info_gutter_width;
int minimap_width;
Cache() {
-
row_height = 0;
line_spacing = 0;
line_number_w = 0;
@@ -271,7 +265,6 @@ private:
Map<int, Map<int, HighlighterInfo>> syntax_highlighting_cache;
struct TextOperation {
-
enum Type {
TYPE_NONE,
TYPE_INSERT,
@@ -306,6 +299,7 @@ private:
List<TextOperation> undo_stack;
List<TextOperation>::Element *undo_stack_pos;
+ int undo_stack_max_size;
void _clear_redo();
void _do_text_op(const TextOperation &p_op, bool p_reverse);
@@ -514,7 +508,7 @@ private:
int _get_column_pos_of_word(const String &p_key, const String &p_search, uint32_t p_search_flags, int p_from_column);
- Vector<int> _search_bind(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const;
+ Dictionary _search_bind(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const;
PopupMenu *menu;
@@ -567,11 +561,6 @@ public:
SEARCH_BACKWARDS = 4
};
- enum SearchResult {
- SEARCH_RESULT_COLUMN,
- SEARCH_RESULT_LINE,
- };
-
virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const;
void _get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) const;
@@ -832,7 +821,6 @@ public:
VARIANT_ENUM_CAST(TextEdit::MenuItems);
VARIANT_ENUM_CAST(TextEdit::SearchFlags);
-VARIANT_ENUM_CAST(TextEdit::SearchResult);
class SyntaxHighlighter {
protected:
diff --git a/scene/gui/texture_button.cpp b/scene/gui/texture_button.cpp
index 5f2e4cf58e..6e86f0f299 100644
--- a/scene/gui/texture_button.cpp
+++ b/scene/gui/texture_button.cpp
@@ -33,33 +33,34 @@
#include <stdlib.h>
Size2 TextureButton::get_minimum_size() const {
-
Size2 rscale = Control::get_minimum_size();
if (!expand) {
if (normal.is_null()) {
if (pressed.is_null()) {
- if (hover.is_null())
- if (click_mask.is_null())
+ if (hover.is_null()) {
+ if (click_mask.is_null()) {
rscale = Size2();
- else
+ } else {
rscale = click_mask->get_size();
- else
+ }
+ } else {
rscale = hover->get_size();
- } else
+ }
+ } else {
rscale = pressed->get_size();
+ }
- } else
+ } else {
rscale = normal->get_size();
+ }
}
return rscale.abs();
}
bool TextureButton::has_point(const Point2 &p_point) const {
-
if (click_mask.is_valid()) {
-
Point2 point = p_point;
Rect2 rect = Rect2();
Size2 mask_size = click_mask->get_size();
@@ -116,9 +117,7 @@ bool TextureButton::has_point(const Point2 &p_point) const {
}
void TextureButton::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_DRAW: {
DrawMode draw_mode = get_draw_mode();
@@ -126,40 +125,44 @@ void TextureButton::_notification(int p_what) {
switch (draw_mode) {
case DRAW_NORMAL: {
-
- if (normal.is_valid())
+ if (normal.is_valid()) {
texdraw = normal;
+ }
} break;
case DRAW_HOVER_PRESSED:
case DRAW_PRESSED: {
-
if (pressed.is_null()) {
if (hover.is_null()) {
- if (normal.is_valid())
+ if (normal.is_valid()) {
texdraw = normal;
- } else
+ }
+ } else {
texdraw = hover;
+ }
- } else
+ } else {
texdraw = pressed;
+ }
} break;
case DRAW_HOVER: {
-
if (hover.is_null()) {
- if (pressed.is_valid() && is_pressed())
+ if (pressed.is_valid() && is_pressed()) {
texdraw = pressed;
- else if (normal.is_valid())
+ } else if (normal.is_valid()) {
texdraw = normal;
- } else
+ }
+ } else {
texdraw = hover;
+ }
} break;
case DRAW_DISABLED: {
-
if (disabled.is_null()) {
- if (normal.is_valid())
+ if (normal.is_valid()) {
texdraw = normal;
- } else
+ }
+ } else {
texdraw = disabled;
+ }
} break;
}
@@ -232,7 +235,6 @@ void TextureButton::_notification(int p_what) {
}
void TextureButton::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_normal_texture", "texture"), &TextureButton::set_normal_texture);
ClassDB::bind_method(D_METHOD("set_pressed_texture", "texture"), &TextureButton::set_pressed_texture);
ClassDB::bind_method(D_METHOD("set_hover_texture", "texture"), &TextureButton::set_hover_texture);
@@ -271,61 +273,56 @@ void TextureButton::_bind_methods() {
}
void TextureButton::set_normal_texture(const Ref<Texture2D> &p_normal) {
-
normal = p_normal;
update();
minimum_size_changed();
}
void TextureButton::set_pressed_texture(const Ref<Texture2D> &p_pressed) {
-
pressed = p_pressed;
update();
}
-void TextureButton::set_hover_texture(const Ref<Texture2D> &p_hover) {
+void TextureButton::set_hover_texture(const Ref<Texture2D> &p_hover) {
hover = p_hover;
update();
}
-void TextureButton::set_disabled_texture(const Ref<Texture2D> &p_disabled) {
+void TextureButton::set_disabled_texture(const Ref<Texture2D> &p_disabled) {
disabled = p_disabled;
update();
}
-void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) {
+void TextureButton::set_click_mask(const Ref<BitMap> &p_click_mask) {
click_mask = p_click_mask;
update();
}
Ref<Texture2D> TextureButton::get_normal_texture() const {
-
return normal;
}
-Ref<Texture2D> TextureButton::get_pressed_texture() const {
+Ref<Texture2D> TextureButton::get_pressed_texture() const {
return pressed;
}
-Ref<Texture2D> TextureButton::get_hover_texture() const {
+Ref<Texture2D> TextureButton::get_hover_texture() const {
return hover;
}
-Ref<Texture2D> TextureButton::get_disabled_texture() const {
+Ref<Texture2D> TextureButton::get_disabled_texture() const {
return disabled;
}
-Ref<BitMap> TextureButton::get_click_mask() const {
+Ref<BitMap> TextureButton::get_click_mask() const {
return click_mask;
}
Ref<Texture2D> TextureButton::get_focused_texture() const {
-
return focused;
};
void TextureButton::set_focused_texture(const Ref<Texture2D> &p_focused) {
-
focused = p_focused;
};
diff --git a/scene/gui/texture_button.h b/scene/gui/texture_button.h
index 43b10a8e8b..a1e66203d3 100644
--- a/scene/gui/texture_button.h
+++ b/scene/gui/texture_button.h
@@ -34,7 +34,6 @@
#include "scene/gui/base_button.h"
#include "scene/resources/bit_map.h"
class TextureButton : public BaseButton {
-
GDCLASS(TextureButton, BaseButton);
public:
diff --git a/scene/gui/texture_progress.cpp b/scene/gui/texture_progress.cpp
index 0dd43e4a35..484b14d11c 100644
--- a/scene/gui/texture_progress.cpp
+++ b/scene/gui/texture_progress.cpp
@@ -33,19 +33,16 @@
#include "core/engine.h"
void TextureProgress::set_under_texture(const Ref<Texture2D> &p_texture) {
-
under = p_texture;
update();
minimum_size_changed();
}
Ref<Texture2D> TextureProgress::get_under_texture() const {
-
return under;
}
void TextureProgress::set_over_texture(const Ref<Texture2D> &p_texture) {
-
over = p_texture;
update();
if (under.is_null()) {
@@ -54,7 +51,6 @@ void TextureProgress::set_over_texture(const Ref<Texture2D> &p_texture) {
}
Ref<Texture2D> TextureProgress::get_over_texture() const {
-
return over;
}
@@ -81,28 +77,26 @@ bool TextureProgress::get_nine_patch_stretch() const {
}
Size2 TextureProgress::get_minimum_size() const {
-
- if (nine_patch_stretch)
+ if (nine_patch_stretch) {
return Size2(stretch_margin[MARGIN_LEFT] + stretch_margin[MARGIN_RIGHT], stretch_margin[MARGIN_TOP] + stretch_margin[MARGIN_BOTTOM]);
- else if (under.is_valid())
+ } else if (under.is_valid()) {
return under->get_size();
- else if (over.is_valid())
+ } else if (over.is_valid()) {
return over->get_size();
- else if (progress.is_valid())
+ } else if (progress.is_valid()) {
return progress->get_size();
+ }
return Size2(1, 1);
}
void TextureProgress::set_progress_texture(const Ref<Texture2D> &p_texture) {
-
progress = p_texture;
update();
minimum_size_changed();
}
Ref<Texture2D> TextureProgress::get_progress_texture() const {
-
return progress;
}
@@ -134,13 +128,16 @@ Color TextureProgress::get_tint_over() const {
}
Point2 TextureProgress::unit_val_to_uv(float val) {
- if (progress.is_null())
+ if (progress.is_null()) {
return Point2();
+ }
- if (val < 0)
+ if (val < 0) {
val += 1;
- if (val > 1)
+ }
+ if (val > 1) {
val -= 1;
+ }
Point2 p = get_relative_center();
@@ -158,40 +155,46 @@ Point2 TextureProgress::unit_val_to_uv(float val) {
for (int edge = 0; edge < 4; edge++) {
if (edge == 0) {
- if (dir.x > 0)
+ if (dir.x > 0) {
continue;
+ }
cq = -(edgeLeft - p.x);
dir.x *= 2.0 * cq;
cp = -dir.x;
} else if (edge == 1) {
- if (dir.x < 0)
+ if (dir.x < 0) {
continue;
+ }
cq = (edgeRight - p.x);
dir.x *= 2.0 * cq;
cp = dir.x;
} else if (edge == 2) {
- if (dir.y > 0)
+ if (dir.y > 0) {
continue;
+ }
cq = -(edgeBottom - p.y);
dir.y *= 2.0 * cq;
cp = -dir.y;
} else if (edge == 3) {
- if (dir.y < 0)
+ if (dir.y < 0) {
continue;
+ }
cq = (edgeTop - p.y);
dir.y *= 2.0 * cq;
cp = dir.y;
}
cr = cq / cp;
- if (cr >= 0 && cr < t1)
+ if (cr >= 0 && cr < t1) {
t1 = cr;
+ }
}
return (p + t1 * dir);
}
Point2 TextureProgress::get_relative_center() {
- if (progress.is_null())
+ if (progress.is_null()) {
return Point2();
+ }
Point2 p = progress->get_size() / 2;
p += rad_center_off;
p.x /= progress->get_width();
@@ -306,9 +309,7 @@ void TextureProgress::draw_nine_patch_stretched(const Ref<Texture2D> &p_texture,
void TextureProgress::_notification(int p_what) {
const float corners[12] = { -0.125, -0.375, -0.625, -0.875, 0.125, 0.375, 0.625, 0.875, 1.125, 1.375, 1.625, 1.875 };
switch (p_what) {
-
case NOTIFICATION_DRAW: {
-
if (nine_patch_stretch && (mode == FILL_LEFT_TO_RIGHT || mode == FILL_RIGHT_TO_LEFT || mode == FILL_TOP_TO_BOTTOM || mode == FILL_BOTTOM_TO_TOP)) {
if (under.is_valid()) {
draw_nine_patch_stretched(under, FILL_LEFT_TO_RIGHT, 1.0, tint_under);
@@ -320,8 +321,9 @@ void TextureProgress::_notification(int p_what) {
draw_nine_patch_stretched(over, FILL_LEFT_TO_RIGHT, 1.0, tint_over);
}
} else {
- if (under.is_valid())
+ if (under.is_valid()) {
draw_texture(under, Point2(), tint_under);
+ }
if (progress.is_valid()) {
Size2 s = progress->get_size();
switch (mode) {
@@ -344,8 +346,9 @@ void TextureProgress::_notification(int p_what) {
case FILL_CLOCKWISE:
case FILL_COUNTER_CLOCKWISE:
case FILL_CLOCKWISE_AND_COUNTER_CLOCKWISE: {
- if (nine_patch_stretch)
+ if (nine_patch_stretch) {
s = get_size();
+ }
float val = get_as_ratio() * rad_max_degrees / 360;
if (val == 1) {
@@ -367,9 +370,11 @@ void TextureProgress::_notification(int p_what) {
pts.append(end);
float from = MIN(start, end);
float to = MAX(start, end);
- for (int i = 0; i < 12; i++)
- if (corners[i] > from && corners[i] < to)
+ for (int i = 0; i < 12; i++) {
+ if (corners[i] > from && corners[i] < to) {
pts.append(corners[i]);
+ }
+ }
pts.sort();
Vector<Point2> uvs;
Vector<Point2> points;
@@ -377,8 +382,9 @@ void TextureProgress::_notification(int p_what) {
points.push_back(Point2(s.x * get_relative_center().x, s.y * get_relative_center().y));
for (int i = 0; i < pts.size(); i++) {
Point2 uv = unit_val_to_uv(pts[i]);
- if (uvs.find(uv) >= 0)
+ if (uvs.find(uv) >= 0) {
continue;
+ }
uvs.push_back(uv);
points.push_back(Point2(uv.x * s.x, uv.y * s.y));
}
@@ -389,10 +395,11 @@ void TextureProgress::_notification(int p_what) {
if (Engine::get_singleton()->is_editor_hint()) {
Point2 p;
- if (nine_patch_stretch)
+ if (nine_patch_stretch) {
p = get_size();
- else
+ } else {
p = progress->get_size();
+ }
p.x *= get_relative_center().x;
p.y *= get_relative_center().y;
@@ -413,10 +420,10 @@ void TextureProgress::_notification(int p_what) {
draw_texture_rect_region(progress, Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), Rect2(Point2(), Size2(s.x * get_as_ratio(), s.y)), tint_progress);
}
}
- if (over.is_valid())
+ if (over.is_valid()) {
draw_texture(over, Point2(), tint_over);
+ }
}
-
} break;
}
}
@@ -432,10 +439,12 @@ int TextureProgress::get_fill_mode() {
}
void TextureProgress::set_radial_initial_angle(float p_angle) {
- while (p_angle > 360)
+ while (p_angle > 360) {
p_angle -= 360;
- while (p_angle < 0)
+ }
+ while (p_angle < 0) {
p_angle += 360;
+ }
rad_init_angle = p_angle;
update();
}
@@ -463,7 +472,6 @@ Point2 TextureProgress::get_radial_center_offset() {
}
void TextureProgress::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_under_texture", "tex"), &TextureProgress::set_under_texture);
ClassDB::bind_method(D_METHOD("get_under_texture"), &TextureProgress::get_under_texture);
diff --git a/scene/gui/texture_progress.h b/scene/gui/texture_progress.h
index e05f89aa3e..e56454f866 100644
--- a/scene/gui/texture_progress.h
+++ b/scene/gui/texture_progress.h
@@ -34,7 +34,6 @@
#include "scene/gui/range.h"
class TextureProgress : public Range {
-
GDCLASS(TextureProgress, Range);
Ref<Texture2D> under;
diff --git a/scene/gui/texture_rect.cpp b/scene/gui/texture_rect.cpp
index 92f3c5b5d9..58e7249284 100644
--- a/scene/gui/texture_rect.cpp
+++ b/scene/gui/texture_rect.cpp
@@ -33,9 +33,7 @@
#include "servers/rendering_server.h"
void TextureRect::_notification(int p_what) {
-
if (p_what == NOTIFICATION_DRAW) {
-
if (texture.is_null()) {
return;
}
@@ -116,7 +114,6 @@ void TextureRect::_notification(int p_what) {
}
Size2 TextureRect::get_minimum_size() const {
-
if (!expand && !texture.is_null()) {
return texture->get_size();
} else {
@@ -125,7 +122,6 @@ Size2 TextureRect::get_minimum_size() const {
}
void TextureRect::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &TextureRect::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &TextureRect::get_texture);
ClassDB::bind_method(D_METHOD("set_expand", "enable"), &TextureRect::set_expand);
@@ -154,7 +150,6 @@ void TextureRect::_bind_methods() {
}
void TextureRect::_texture_changed() {
-
if (texture.is_valid()) {
update();
minimum_size_changed();
@@ -162,7 +157,6 @@ void TextureRect::_texture_changed() {
}
void TextureRect::set_texture(const Ref<Texture2D> &p_tex) {
-
if (p_tex == texture) {
return;
}
@@ -182,57 +176,47 @@ void TextureRect::set_texture(const Ref<Texture2D> &p_tex) {
}
Ref<Texture2D> TextureRect::get_texture() const {
-
return texture;
}
void TextureRect::set_expand(bool p_expand) {
-
expand = p_expand;
update();
minimum_size_changed();
}
bool TextureRect::has_expand() const {
-
return expand;
}
void TextureRect::set_stretch_mode(StretchMode p_mode) {
-
stretch_mode = p_mode;
update();
}
TextureRect::StretchMode TextureRect::get_stretch_mode() const {
-
return stretch_mode;
}
void TextureRect::set_flip_h(bool p_flip) {
-
hflip = p_flip;
update();
}
bool TextureRect::is_flipped_h() const {
-
return hflip;
}
void TextureRect::set_flip_v(bool p_flip) {
-
vflip = p_flip;
update();
}
bool TextureRect::is_flipped_v() const {
-
return vflip;
}
TextureRect::TextureRect() {
-
expand = false;
hflip = false;
vflip = false;
diff --git a/scene/gui/texture_rect.h b/scene/gui/texture_rect.h
index 77a2828fd4..727ab95776 100644
--- a/scene/gui/texture_rect.h
+++ b/scene/gui/texture_rect.h
@@ -34,7 +34,6 @@
#include "scene/gui/control.h"
class TextureRect : public Control {
-
GDCLASS(TextureRect, Control);
public:
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 509a52d36a..45fcb448f8 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -30,7 +30,7 @@
#include "tree.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/math/math_funcs.h"
#include "core/os/keyboard.h"
#include "core/os/os.h"
@@ -47,9 +47,9 @@
#include <limits.h>
void TreeItem::move_to_top() {
-
- if (!parent || parent->children == this)
+ if (!parent || parent->children == this) {
return; //already on top
+ }
TreeItem *prev = get_prev();
prev->next = next;
next = parent->children;
@@ -57,13 +57,15 @@ void TreeItem::move_to_top() {
}
void TreeItem::move_to_bottom() {
- if (!parent || !next)
+ if (!parent || !next) {
return;
+ }
TreeItem *prev = get_prev();
TreeItem *last = next;
- while (last->next)
+ while (last->next) {
last = last->next;
+ }
if (prev) {
prev->next = next;
@@ -75,54 +77,48 @@ void TreeItem::move_to_bottom() {
}
Size2 TreeItem::Cell::get_icon_size() const {
-
- if (icon.is_null())
+ if (icon.is_null()) {
return Size2();
- if (icon_region == Rect2i())
+ }
+ if (icon_region == Rect2i()) {
return icon->get_size();
- else
+ } else {
return icon_region.size;
+ }
}
void TreeItem::Cell::draw_icon(const RID &p_where, const Point2 &p_pos, const Size2 &p_size, const Color &p_color) const {
-
- if (icon.is_null())
+ if (icon.is_null()) {
return;
+ }
Size2i dsize = (p_size == Size2()) ? icon->get_size() : p_size;
if (icon_region == Rect2i()) {
-
icon->draw_rect_region(p_where, Rect2(p_pos, dsize), Rect2(Point2(), icon->get_size()), p_color);
} else {
-
icon->draw_rect_region(p_where, Rect2(p_pos, dsize), icon_region, p_color);
}
}
void TreeItem::_changed_notify(int p_cell) {
-
tree->item_changed(p_cell, this);
}
void TreeItem::_changed_notify() {
-
tree->item_changed(-1, this);
}
void TreeItem::_cell_selected(int p_cell) {
-
tree->item_selected(p_cell, this);
}
void TreeItem::_cell_deselected(int p_cell) {
-
tree->item_deselected(p_cell, this);
}
/* cell mode */
void TreeItem::set_cell_mode(int p_column, TreeCellMode p_mode) {
-
ERR_FAIL_INDEX(p_column, cells.size());
Cell &c = cells.write[p_column];
c.mode = p_mode;
@@ -138,32 +134,27 @@ void TreeItem::set_cell_mode(int p_column, TreeCellMode p_mode) {
}
TreeItem::TreeCellMode TreeItem::get_cell_mode(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), TreeItem::CELL_MODE_STRING);
return cells[p_column].mode;
}
/* check mode */
void TreeItem::set_checked(int p_column, bool p_checked) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].checked = p_checked;
_changed_notify(p_column);
}
bool TreeItem::is_checked(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), false);
return cells[p_column].checked;
}
void TreeItem::set_text(int p_column, String p_text) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].text = p_text;
if (cells[p_column].mode == TreeItem::CELL_MODE_RANGE) {
-
Vector<String> strings = p_text.split(",");
cells.write[p_column].min = INT_MAX;
cells.write[p_column].max = INT_MIN;
@@ -181,13 +172,11 @@ void TreeItem::set_text(int p_column, String p_text) {
}
String TreeItem::get_text(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), "");
return cells[p_column].text;
}
void TreeItem::set_suffix(int p_column, String p_suffix) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].suffix = p_suffix;
@@ -195,91 +184,82 @@ void TreeItem::set_suffix(int p_column, String p_suffix) {
}
String TreeItem::get_suffix(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), "");
return cells[p_column].suffix;
}
void TreeItem::set_icon(int p_column, const Ref<Texture2D> &p_icon) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].icon = p_icon;
_changed_notify(p_column);
}
Ref<Texture2D> TreeItem::get_icon(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), Ref<Texture2D>());
return cells[p_column].icon;
}
void TreeItem::set_icon_region(int p_column, const Rect2 &p_icon_region) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].icon_region = p_icon_region;
_changed_notify(p_column);
}
Rect2 TreeItem::get_icon_region(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), Rect2());
return cells[p_column].icon_region;
}
void TreeItem::set_icon_modulate(int p_column, const Color &p_modulate) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].icon_color = p_modulate;
_changed_notify(p_column);
}
Color TreeItem::get_icon_modulate(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), Color());
return cells[p_column].icon_color;
}
void TreeItem::set_icon_max_width(int p_column, int p_max) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].icon_max_w = p_max;
_changed_notify(p_column);
}
int TreeItem::get_icon_max_width(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), 0);
return cells[p_column].icon_max_w;
}
/* range works for mode number or mode combo */
void TreeItem::set_range(int p_column, double p_value) {
-
ERR_FAIL_INDEX(p_column, cells.size());
- if (cells[p_column].step > 0)
+ if (cells[p_column].step > 0) {
p_value = Math::stepify(p_value, cells[p_column].step);
- if (p_value < cells[p_column].min)
+ }
+ if (p_value < cells[p_column].min) {
p_value = cells[p_column].min;
- if (p_value > cells[p_column].max)
+ }
+ if (p_value > cells[p_column].max) {
p_value = cells[p_column].max;
+ }
cells.write[p_column].val = p_value;
_changed_notify(p_column);
}
double TreeItem::get_range(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), 0);
return cells[p_column].val;
}
bool TreeItem::is_range_exponential(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), false);
return cells[p_column].expr;
}
-void TreeItem::set_range_config(int p_column, double p_min, double p_max, double p_step, bool p_exp) {
+void TreeItem::set_range_config(int p_column, double p_min, double p_max, double p_step, bool p_exp) {
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].min = p_min;
cells.write[p_column].max = p_max;
@@ -289,7 +269,6 @@ void TreeItem::set_range_config(int p_column, double p_min, double p_max, double
}
void TreeItem::get_range_config(int p_column, double &r_min, double &r_max, double &r_step) const {
-
ERR_FAIL_INDEX(p_column, cells.size());
r_min = cells[p_column].min;
r_max = cells[p_column].max;
@@ -297,20 +276,17 @@ void TreeItem::get_range_config(int p_column, double &r_min, double &r_max, doub
}
void TreeItem::set_metadata(int p_column, const Variant &p_meta) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].meta = p_meta;
}
Variant TreeItem::get_metadata(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), Variant());
return cells[p_column].meta;
}
void TreeItem::set_custom_draw(int p_column, Object *p_object, const StringName &p_callback) {
-
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_NULL(p_object);
@@ -319,25 +295,21 @@ void TreeItem::set_custom_draw(int p_column, Object *p_object, const StringName
}
void TreeItem::set_collapsed(bool p_collapsed) {
-
- if (collapsed == p_collapsed || !tree)
+ if (collapsed == p_collapsed || !tree) {
return;
+ }
collapsed = p_collapsed;
TreeItem *ci = tree->selected_item;
if (ci) {
-
while (ci && ci != this) {
-
ci = ci->parent;
}
if (ci) { // collapsing cursor/selected, move it!
if (tree->select_mode == Tree::SELECT_MULTI) {
-
tree->selected_item = this;
emit_signal("cell_selected");
} else {
-
select(tree->selected_col);
}
@@ -350,7 +322,6 @@ void TreeItem::set_collapsed(bool p_collapsed) {
}
bool TreeItem::is_collapsed() {
-
return collapsed;
}
@@ -364,40 +335,36 @@ int TreeItem::get_custom_minimum_height() const {
}
TreeItem *TreeItem::get_next() {
-
return next;
}
TreeItem *TreeItem::get_prev() {
-
- if (!parent || parent->children == this)
+ if (!parent || parent->children == this) {
return nullptr;
+ }
TreeItem *prev = parent->children;
- while (prev && prev->next != this)
+ while (prev && prev->next != this) {
prev = prev->next;
+ }
return prev;
}
TreeItem *TreeItem::get_parent() {
-
return parent;
}
TreeItem *TreeItem::get_children() {
-
return children;
}
TreeItem *TreeItem::get_prev_visible(bool p_wrap) {
-
TreeItem *current = this;
TreeItem *prev = current->get_prev();
if (!prev) {
-
current = current->parent;
if (current == tree->root && tree->hide_root) {
return nullptr;
@@ -414,14 +381,14 @@ TreeItem *TreeItem::get_prev_visible(bool p_wrap) {
}
}
} else {
-
current = prev;
while (!current->collapsed && current->children) {
//go to the very end
current = current->children;
- while (current->next)
+ while (current->next) {
current = current->next;
+ }
}
}
@@ -429,28 +396,24 @@ TreeItem *TreeItem::get_prev_visible(bool p_wrap) {
}
TreeItem *TreeItem::get_next_visible(bool p_wrap) {
-
TreeItem *current = this;
if (!current->collapsed && current->children) {
-
current = current->children;
} else if (current->next) {
-
current = current->next;
} else {
-
while (current && !current->next) {
-
current = current->parent;
}
if (!current) {
- if (p_wrap)
+ if (p_wrap) {
return tree->root;
- else
+ } else {
return nullptr;
+ }
} else {
current = current->next;
}
@@ -460,14 +423,11 @@ TreeItem *TreeItem::get_next_visible(bool p_wrap) {
}
void TreeItem::remove_child(TreeItem *p_item) {
-
ERR_FAIL_NULL(p_item);
TreeItem **c = &children;
while (*c) {
-
if ((*c) == p_item) {
-
TreeItem *aux = *c;
*c = (*c)->next;
@@ -483,55 +443,51 @@ void TreeItem::remove_child(TreeItem *p_item) {
}
void TreeItem::set_selectable(int p_column, bool p_selectable) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].selectable = p_selectable;
}
bool TreeItem::is_selectable(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), false);
return cells[p_column].selectable;
}
bool TreeItem::is_selected(int p_column) {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), false);
return cells[p_column].selectable && cells[p_column].selected;
}
void TreeItem::set_as_cursor(int p_column) {
-
ERR_FAIL_INDEX(p_column, cells.size());
- if (!tree)
+ if (!tree) {
return;
- if (tree->select_mode != Tree::SELECT_MULTI)
+ }
+ if (tree->select_mode != Tree::SELECT_MULTI) {
return;
+ }
tree->selected_item = this;
tree->selected_col = p_column;
tree->update();
}
void TreeItem::select(int p_column) {
-
ERR_FAIL_INDEX(p_column, cells.size());
_cell_selected(p_column);
}
void TreeItem::deselect(int p_column) {
-
ERR_FAIL_INDEX(p_column, cells.size());
_cell_deselected(p_column);
}
void TreeItem::add_button(int p_column, const Ref<Texture2D> &p_button, int p_id, bool p_disabled, const String &p_tooltip) {
-
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_COND(!p_button.is_valid());
TreeItem::Cell::Button button;
button.texture = p_button;
- if (p_id < 0)
+ if (p_id < 0) {
p_id = cells[p_column].buttons.size();
+ }
button.id = p_id;
button.disabled = p_disabled;
button.tooltip = p_tooltip;
@@ -540,27 +496,29 @@ void TreeItem::add_button(int p_column, const Ref<Texture2D> &p_button, int p_id
}
int TreeItem::get_button_count(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), -1);
return cells[p_column].buttons.size();
}
+
Ref<Texture2D> TreeItem::get_button(int p_column, int p_idx) const {
ERR_FAIL_INDEX_V(p_column, cells.size(), Ref<Texture2D>());
ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), Ref<Texture2D>());
return cells[p_column].buttons[p_idx].texture;
}
+
String TreeItem::get_button_tooltip(int p_column, int p_idx) const {
ERR_FAIL_INDEX_V(p_column, cells.size(), String());
ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), String());
return cells[p_column].buttons[p_idx].tooltip;
}
+
int TreeItem::get_button_id(int p_column, int p_idx) const {
ERR_FAIL_INDEX_V(p_column, cells.size(), -1);
ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), -1);
return cells[p_column].buttons[p_idx].id;
}
-void TreeItem::erase_button(int p_column, int p_idx) {
+void TreeItem::erase_button(int p_column, int p_idx) {
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size());
cells.write[p_column].buttons.remove(p_idx);
@@ -568,19 +526,17 @@ void TreeItem::erase_button(int p_column, int p_idx) {
}
int TreeItem::get_button_by_id(int p_column, int p_id) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), -1);
for (int i = 0; i < cells[p_column].buttons.size(); i++) {
-
- if (cells[p_column].buttons[i].id == p_id)
+ if (cells[p_column].buttons[i].id == p_id) {
return i;
+ }
}
return -1;
}
void TreeItem::set_button(int p_column, int p_idx, const Ref<Texture2D> &p_button) {
-
ERR_FAIL_COND(p_button.is_null());
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size());
@@ -589,7 +545,6 @@ void TreeItem::set_button(int p_column, int p_idx, const Ref<Texture2D> &p_butto
}
void TreeItem::set_button_color(int p_column, int p_idx, const Color &p_color) {
-
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size());
cells.write[p_column].buttons.write[p_idx].color = p_color;
@@ -597,7 +552,6 @@ void TreeItem::set_button_color(int p_column, int p_idx, const Color &p_color) {
}
void TreeItem::set_button_disabled(int p_column, int p_idx, bool p_disabled) {
-
ERR_FAIL_INDEX(p_column, cells.size());
ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size());
@@ -606,7 +560,6 @@ void TreeItem::set_button_disabled(int p_column, int p_idx, bool p_disabled) {
}
bool TreeItem::is_button_disabled(int p_column, int p_idx) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), false);
ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), false);
@@ -614,34 +567,32 @@ bool TreeItem::is_button_disabled(int p_column, int p_idx) const {
}
void TreeItem::set_editable(int p_column, bool p_editable) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].editable = p_editable;
_changed_notify(p_column);
}
bool TreeItem::is_editable(int p_column) {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), false);
return cells[p_column].editable;
}
void TreeItem::set_custom_color(int p_column, const Color &p_color) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].custom_color = true;
cells.write[p_column].color = p_color;
_changed_notify(p_column);
}
-Color TreeItem::get_custom_color(int p_column) const {
+Color TreeItem::get_custom_color(int p_column) const {
ERR_FAIL_INDEX_V(p_column, cells.size(), Color());
- if (!cells[p_column].custom_color)
+ if (!cells[p_column].custom_color) {
return Color();
+ }
return cells[p_column].color;
}
-void TreeItem::clear_custom_color(int p_column) {
+void TreeItem::clear_custom_color(int p_column) {
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].custom_color = false;
cells.write[p_column].color = Color();
@@ -649,19 +600,16 @@ void TreeItem::clear_custom_color(int p_column) {
}
void TreeItem::set_tooltip(int p_column, const String &p_tooltip) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].tooltip = p_tooltip;
}
String TreeItem::get_tooltip(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), "");
return cells[p_column].tooltip;
}
void TreeItem::set_custom_bg_color(int p_column, const Color &p_color, bool p_bg_outline) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].custom_bg_color = true;
cells.write[p_column].custom_bg_outline = p_bg_outline;
@@ -670,7 +618,6 @@ void TreeItem::set_custom_bg_color(int p_column, const Color &p_color, bool p_bg
}
void TreeItem::clear_custom_bg_color(int p_column) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].custom_bg_color = false;
cells.write[p_column].bg_color = Color();
@@ -678,21 +625,19 @@ void TreeItem::clear_custom_bg_color(int p_column) {
}
Color TreeItem::get_custom_bg_color(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), Color());
- if (!cells[p_column].custom_bg_color)
+ if (!cells[p_column].custom_bg_color) {
return Color();
+ }
return cells[p_column].bg_color;
}
void TreeItem::set_custom_as_button(int p_column, bool p_button) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].custom_button = p_button;
}
bool TreeItem::is_custom_set_as_button(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), false);
return cells[p_column].custom_button;
}
@@ -709,20 +654,17 @@ TreeItem::TextAlign TreeItem::get_text_align(int p_column) const {
}
void TreeItem::set_expand_right(int p_column, bool p_enable) {
-
ERR_FAIL_INDEX(p_column, cells.size());
cells.write[p_column].expand_right = p_enable;
_changed_notify(p_column);
}
bool TreeItem::get_expand_right(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, cells.size(), false);
return cells[p_column].expand_right;
}
void TreeItem::set_disable_folding(bool p_disable) {
-
disable_folding = p_disable;
_changed_notify(0);
}
@@ -732,7 +674,6 @@ bool TreeItem::is_folding_disabled() const {
}
Variant TreeItem::_call_recursive_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (p_argcount < 1) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 0;
@@ -769,7 +710,6 @@ void TreeItem::call_recursive(const StringName &p_method, const Variant **p_args
}
void TreeItem::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_cell_mode", "column", "mode"), &TreeItem::set_cell_mode);
ClassDB::bind_method(D_METHOD("get_cell_mode", "column"), &TreeItem::get_cell_mode);
@@ -779,6 +719,9 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_text", "column", "text"), &TreeItem::set_text);
ClassDB::bind_method(D_METHOD("get_text", "column"), &TreeItem::get_text);
+ ClassDB::bind_method(D_METHOD("set_suffix", "column", "text"), &TreeItem::set_suffix);
+ ClassDB::bind_method(D_METHOD("get_suffix", "column"), &TreeItem::get_suffix);
+
ClassDB::bind_method(D_METHOD("set_icon", "column", "texture"), &TreeItem::set_icon);
ClassDB::bind_method(D_METHOD("get_icon", "column"), &TreeItem::get_icon);
@@ -884,10 +827,8 @@ void TreeItem::_bind_methods() {
}
void TreeItem::clear_children() {
-
TreeItem *c = children;
while (c) {
-
TreeItem *aux = c;
c = c->get_next();
aux->parent = nullptr; // so it won't try to recursively autoremove from me in here
@@ -898,7 +839,6 @@ void TreeItem::clear_children() {
};
TreeItem::TreeItem(Tree *p_tree) {
-
tree = p_tree;
collapsed = false;
disable_folding = false;
@@ -910,14 +850,13 @@ TreeItem::TreeItem(Tree *p_tree) {
}
TreeItem::~TreeItem() {
-
clear_children();
- if (parent)
+ if (parent) {
parent->remove_child(this);
+ }
if (tree && tree->root == this) {
-
tree->root = nullptr;
}
@@ -930,14 +869,17 @@ TreeItem::~TreeItem() {
tree->cache.hover_item = nullptr;
}
- if (tree && tree->selected_item == this)
+ if (tree && tree->selected_item == this) {
tree->selected_item = nullptr;
+ }
- if (tree && tree->drop_mode_over == this)
+ if (tree && tree->drop_mode_over == this) {
tree->drop_mode_over = nullptr;
+ }
- if (tree && tree->single_select_defer == this)
+ if (tree && tree->single_select_defer == this) {
tree->single_select_defer = nullptr;
+ }
if (tree && tree->edited_item == this) {
tree->edited_item = nullptr;
@@ -953,7 +895,6 @@ TreeItem::~TreeItem() {
/**********************************************/
void Tree::update_cache() {
-
cache.font = get_theme_font("font");
cache.tb_font = get_theme_font("title_button_font");
cache.bg = get_theme_stylebox("bg");
@@ -998,45 +939,42 @@ void Tree::update_cache() {
}
int Tree::compute_item_height(TreeItem *p_item) const {
-
- if (p_item == root && hide_root)
+ if (p_item == root && hide_root) {
return 0;
+ }
ERR_FAIL_COND_V(cache.font.is_null(), 0);
int height = cache.font->get_height();
for (int i = 0; i < columns.size(); i++) {
-
for (int j = 0; j < p_item->cells[i].buttons.size(); j++) {
-
Size2i s; // = cache.button_pressed->get_minimum_size();
s += p_item->cells[i].buttons[j].texture->get_size();
- if (s.height > height)
+ if (s.height > height) {
height = s.height;
+ }
}
switch (p_item->cells[i].mode) {
-
case TreeItem::CELL_MODE_CHECK: {
-
int check_icon_h = cache.checked->get_height();
- if (height < check_icon_h)
+ if (height < check_icon_h) {
height = check_icon_h;
+ }
[[fallthrough]];
}
case TreeItem::CELL_MODE_STRING:
case TreeItem::CELL_MODE_CUSTOM:
case TreeItem::CELL_MODE_ICON: {
-
Ref<Texture2D> icon = p_item->cells[i].icon;
if (!icon.is_null()) {
-
Size2i s = p_item->cells[i].get_icon_size();
if (p_item->cells[i].icon_max_w > 0 && s.width > p_item->cells[i].icon_max_w) {
s.height = s.height * p_item->cells[i].icon_max_w / s.width;
}
- if (s.height > height)
+ if (s.height > height) {
height = s.height;
+ }
}
if (p_item->cells[i].mode == TreeItem::CELL_MODE_CUSTOM && p_item->cells[i].custom_button) {
height += cache.custom_button->get_minimum_size().height;
@@ -1048,8 +986,9 @@ int Tree::compute_item_height(TreeItem *p_item) const {
}
}
int item_min_height = p_item->get_custom_minimum_height();
- if (height < item_min_height)
+ if (height < item_min_height) {
height = item_min_height;
+ }
height += cache.vseparation;
@@ -1057,7 +996,6 @@ int Tree::compute_item_height(TreeItem *p_item) const {
}
int Tree::get_item_height(TreeItem *p_item) const {
-
int height = compute_item_height(p_item);
height += cache.vseparation;
@@ -1066,7 +1004,6 @@ int Tree::get_item_height(TreeItem *p_item) const {
TreeItem *c = p_item->children;
while (c) {
-
height += get_item_height(c);
c = c->next;
@@ -1077,14 +1014,14 @@ int Tree::get_item_height(TreeItem *p_item) const {
}
void Tree::draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color, const Color &p_icon_color) {
-
ERR_FAIL_COND(cache.font.is_null());
Rect2i rect = p_rect;
Ref<Font> font = cache.font;
String text = p_cell.text;
- if (p_cell.suffix != String())
+ if (p_cell.suffix != String()) {
text += " " + p_cell.suffix;
+ }
int w = 0;
if (!p_cell.icon.is_null()) {
@@ -1127,9 +1064,9 @@ void Tree::draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, co
}
int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item) {
-
- if (p_pos.y - cache.offset.y > (p_draw_size.height))
+ if (p_pos.y - cache.offset.y > (p_draw_size.height)) {
return -1; //draw no more!
+ }
RID ci = get_canvas_item();
@@ -1145,7 +1082,6 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
bool skip = (p_item == root && hide_root);
if (!skip && (p_pos.y + label_h - cache.offset.y) > 0) {
-
//draw separation.
//if (p_item->get_parent()!=root || !hide_root)
@@ -1157,7 +1093,6 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
int ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin);
int skip2 = 0;
for (int i = 0; i < columns.size(); i++) {
-
if (skip2) {
skip2--;
continue;
@@ -1166,22 +1101,18 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
int w = get_column_width(i);
if (i == 0) {
-
w -= ofs;
if (w <= 0) {
-
ofs = get_column_width(0);
continue;
}
} else {
-
ofs += cache.hseparation;
w -= cache.hseparation;
}
if (p_item->cells[i].expand_right) {
-
int plus = 1;
while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text == "" && p_item->cells[i + plus].icon.is_null()) {
w += get_column_width(i + plus);
@@ -1194,8 +1125,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
for (int j = p_item->cells[i].buttons.size() - 1; j >= 0; j--) {
Ref<Texture2D> b = p_item->cells[i].buttons[j].texture;
Size2 s = b->get_size() + cache.button_pressed->get_minimum_size();
- if (s.height < label_h)
+ if (s.height < label_h) {
s.height = label_h;
+ }
Point2i o = Point2i(ofs + w - s.width, p_pos.y) - cache.offset + p_draw_ofs;
@@ -1224,15 +1156,15 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
if (i == 0) {
-
if (p_item->cells[0].selected && select_mode == SELECT_ROW) {
Rect2i row_rect = Rect2i(Point2i(cache.bg->get_margin(MARGIN_LEFT), item_rect.position.y), Size2i(get_size().width - cache.bg->get_minimum_size().width, item_rect.size.y));
//Rect2 r = Rect2i(row_rect.pos,row_rect.size);
//r.grow(cache.selected->get_margin(MARGIN_LEFT));
- if (has_focus())
+ if (has_focus()) {
cache.selected_focus->draw(ci, row_rect);
- else
+ } else {
cache.selected->draw(ci, row_rect);
+ }
}
}
@@ -1256,7 +1188,6 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
if (p_item->cells[i].custom_bg_color) {
-
Rect2 r = cell_rect;
if (i == 0) {
r.position.x = p_draw_ofs.x;
@@ -1276,7 +1207,6 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
if (drop_mode_flags && drop_mode_over == p_item) {
-
Rect2 r = cell_rect;
if (drop_mode_section == -1 || drop_mode_section == 0) {
@@ -1300,13 +1230,10 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
text_pos.y += Math::floor((item_rect.size.y - font->get_height()) / 2) + font_ascent;
switch (p_item->cells[i].mode) {
-
case TreeItem::CELL_MODE_STRING: {
-
draw_item_rect(p_item->cells[i], item_rect, col, icon_col);
} break;
case TreeItem::CELL_MODE_CHECK: {
-
Ref<Texture2D> checked = cache.checked;
Ref<Texture2D> unchecked = cache.unchecked;
Point2i check_ofs = item_rect.position;
@@ -1330,9 +1257,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
} break;
case TreeItem::CELL_MODE_RANGE: {
if (p_item->cells[i].text != "") {
-
- if (!p_item->cells[i].editable)
+ if (!p_item->cells[i].editable) {
break;
+ }
int option = (int)p_item->cells[i].val;
@@ -1349,8 +1276,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
}
- if (p_item->cells[i].suffix != String())
+ if (p_item->cells[i].suffix != String()) {
s += " " + p_item->cells[i].suffix;
+ }
Ref<Texture2D> downarrow = cache.select_arrow;
@@ -1362,18 +1290,19 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
downarrow->draw(ci, arrow_pos);
} else {
-
Ref<Texture2D> updown = cache.updown;
String valtext = String::num(p_item->cells[i].val, Math::range_step_decimals(p_item->cells[i].step));
- if (p_item->cells[i].suffix != String())
+ if (p_item->cells[i].suffix != String()) {
valtext += " " + p_item->cells[i].suffix;
+ }
font->draw(ci, text_pos, valtext, col, item_rect.size.x - updown->get_width());
- if (!p_item->cells[i].editable)
+ if (!p_item->cells[i].editable) {
break;
+ }
Point2i updown_pos = item_rect.position;
updown_pos.x += item_rect.size.x - updown->get_width();
@@ -1384,9 +1313,9 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
} break;
case TreeItem::CELL_MODE_ICON: {
-
- if (p_item->cells[i].icon.is_null())
+ if (p_item->cells[i].icon.is_null()) {
break;
+ }
Size2i icon_size = p_item->cells[i].get_icon_size();
if (p_item->cells[i].icon_max_w > 0 && icon_size.width > p_item->cells[i].icon_max_w) {
icon_size.height = icon_size.height * p_item->cells[i].icon_max_w / icon_size.width;
@@ -1400,16 +1329,14 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
} break;
case TreeItem::CELL_MODE_CUSTOM: {
-
if (p_item->cells[i].custom_draw_obj.is_valid()) {
-
Object *cdo = ObjectDB::get_instance(p_item->cells[i].custom_draw_obj);
- if (cdo)
+ if (cdo) {
cdo->call(p_item->cells[i].custom_draw_callback, p_item, Rect2(item_rect));
+ }
}
if (!p_item->cells[i].editable) {
-
draw_item_rect(p_item->cells[i], item_rect, col, icon_col);
break;
}
@@ -1425,7 +1352,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
if (p_item->cells[i].custom_button) {
if (cache.hover_item == p_item && cache.hover_cell == i) {
- if (InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
+ if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
draw_style_box(cache.custom_button_pressed, ir);
} else {
draw_style_box(cache.custom_button_hover, ir);
@@ -1446,19 +1373,17 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
if (i == 0) {
-
ofs = get_column_width(0);
} else {
-
ofs += w + bw;
}
if (select_mode == SELECT_MULTI && selected_item == p_item && selected_col == i) {
-
- if (has_focus())
+ if (has_focus()) {
cache.cursor->draw(ci, cell_rect);
- else
+ } else {
cache.cursor_unfocus->draw(ci, cell_rect);
+ }
}
}
@@ -1467,7 +1392,6 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
Ref<Texture2D> arrow;
if (p_item->collapsed) {
-
arrow = cache.arrow_collapsed;
} else {
arrow = cache.arrow;
@@ -1492,14 +1416,14 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
int prev_ofs = children_pos.y - cache.offset.y + p_draw_ofs.y;
while (c) {
-
if (cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root)) {
int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin);
int parent_ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin);
Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h / 2) - cache.offset + p_draw_ofs;
- if (c->get_children() != nullptr)
+ if (c->get_children() != nullptr) {
root_pos -= Point2i(cache.arrow->get_width(), 0);
+ }
float line_width = 1.0;
#ifdef TOOLS_ENABLED
@@ -1543,11 +1467,11 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
int Tree::_count_selected_items(TreeItem *p_from) const {
-
int count = 0;
for (int i = 0; i < columns.size(); i++) {
- if (p_from->is_selected(i))
+ if (p_from->is_selected(i)) {
count++;
+ }
}
if (p_from->get_children()) {
@@ -1560,8 +1484,8 @@ int Tree::_count_selected_items(TreeItem *p_from) const {
return count;
}
-void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev, bool *r_in_range, bool p_force_deselect) {
+void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev, bool *r_in_range, bool p_force_deselect) {
TreeItem::Cell &selected_cell = p_selected->cells.write[p_col];
bool switched = false;
@@ -1573,14 +1497,13 @@ void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_c
bool emitted_row = false;
for (int i = 0; i < columns.size(); i++) {
-
TreeItem::Cell &c = p_current->cells.write[i];
- if (!c.selectable)
+ if (!c.selectable) {
continue;
+ }
if (select_mode == SELECT_ROW) {
-
if (p_selected == p_current && (!c.selected || allow_reselect)) {
c.selected = true;
selected_item = p_selected;
@@ -1595,45 +1518,40 @@ void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_c
*/
} else if (c.selected) {
-
c.selected = false;
//p_current->deselected_signal.call(p_col);
}
} else if (select_mode == SELECT_SINGLE || select_mode == SELECT_MULTI) {
-
if (!r_in_range && &selected_cell == &c) {
-
if (!selected_cell.selected || allow_reselect) {
-
selected_cell.selected = true;
selected_item = p_selected;
selected_col = i;
emit_signal("cell_selected");
- if (select_mode == SELECT_MULTI)
+ if (select_mode == SELECT_MULTI) {
emit_signal("multi_selected", p_current, i, true);
- else if (select_mode == SELECT_SINGLE)
+ } else if (select_mode == SELECT_SINGLE) {
emit_signal("item_selected");
+ }
} else if (select_mode == SELECT_MULTI && (selected_item != p_selected || selected_col != i)) {
-
selected_item = p_selected;
selected_col = i;
emit_signal("cell_selected");
}
} else {
-
if (r_in_range && *r_in_range && !p_force_deselect) {
-
if (!c.selected && c.selectable) {
c.selected = true;
emit_signal("multi_selected", p_current, i, true);
}
} else if (!r_in_range || p_force_deselect) {
- if (select_mode == SELECT_MULTI && c.selected)
+ if (select_mode == SELECT_MULTI && c.selected) {
emit_signal("multi_selected", p_current, i, false);
+ }
c.selected = false;
}
//p_current->deselected_signal.call(p_col);
@@ -1648,21 +1566,17 @@ void Tree::select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_c
TreeItem *c = p_current->children;
while (c) {
-
select_single_item(p_selected, c, p_col, p_prev, r_in_range, p_current->is_collapsed() || p_force_deselect);
c = c->next;
}
}
Rect2 Tree::search_item_rect(TreeItem *p_from, TreeItem *p_item) {
-
return Rect2();
}
void Tree::_range_click_timeout() {
-
- if (range_item_last && !range_drag_enabled && InputFilter::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
-
+ if (range_item_last && !range_drag_enabled && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
Point2 pos = get_local_mouse_position() - cache.bg->get_offset();
if (show_column_titles) {
pos.y -= _get_title_button_height();
@@ -1689,8 +1603,9 @@ void Tree::_range_click_timeout() {
range_click_timer->start();
}
- if (!click_handled)
+ if (!click_handled) {
range_click_timer->stop();
+ }
if (propagate_mouse_activated) {
emit_signal("item_activated");
@@ -1703,7 +1618,6 @@ void Tree::_range_click_timeout() {
}
int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_doubleclick, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod) {
-
int item_h = compute_item_height(p_item) + cache.vseparation;
bool skip = (p_item == root && hide_root);
@@ -1716,9 +1630,9 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
}
if (!p_item->disable_folding && !hide_folding && (p_pos.x >= x_ofs && p_pos.x < (x_ofs + cache.item_margin))) {
-
- if (p_item->children)
+ if (p_item->children) {
p_item->set_collapsed(!p_item->is_collapsed());
+ }
return -1; //handled!
}
@@ -1729,11 +1643,9 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
int col_ofs = 0;
int col_width = 0;
for (int i = 0; i < columns.size(); i++) {
-
col_width = get_column_width(i);
if (p_item->cells[i].expand_right) {
-
int plus = 1;
while (i + plus < columns.size() && !p_item->cells[i + plus].editable && p_item->cells[i + plus].mode == TreeItem::CELL_MODE_STRING && p_item->cells[i + plus].text == "" && p_item->cells[i + plus].icon.is_null()) {
col_width += cache.hseparation;
@@ -1752,16 +1664,15 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
break;
}
- if (col == -1)
+ if (col == -1) {
return -1;
- else if (col == 0) {
+ } else if (col == 0) {
int margin = x_ofs + cache.item_margin; //-cache.hseparation;
//int lm = cache.bg->get_margin(MARGIN_LEFT);
col_width -= margin;
col_ofs += margin;
x -= margin;
} else {
-
col_width -= cache.hseparation;
x -= cache.hseparation;
}
@@ -1812,9 +1723,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
}
if (select_mode == SELECT_MULTI && p_mod->get_command() && c.selectable) {
-
if (!c.selected || p_button == BUTTON_RIGHT) {
-
p_item->select(col);
emit_signal("multi_selected", p_item, col, true);
if (p_button == BUTTON_RIGHT) {
@@ -1823,18 +1732,14 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
//p_item->selected_signal.call(col);
} else {
-
p_item->deselect(col);
emit_signal("multi_selected", p_item, col, false);
//p_item->deselected_signal.call(col);
}
} else {
-
if (c.selectable) {
-
if (select_mode == SELECT_MULTI && p_mod->get_shift() && selected_item && selected_item != p_item) {
-
bool inrange = false;
select_single_item(p_item, root, col, selected_item, &inrange);
@@ -1842,14 +1747,12 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
emit_signal("item_rmb_selected", get_local_mouse_position());
}
} else {
-
int icount = _count_selected_items(root);
if (select_mode == SELECT_MULTI && icount > 1 && p_button != BUTTON_RIGHT) {
single_select_defer = p_item;
single_select_defer_column = col;
} else {
-
if (p_button != BUTTON_RIGHT || !c.selected) {
select_single_item(p_item, root, col);
}
@@ -1870,8 +1773,9 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
}
}
- if (!c.editable)
+ if (!c.editable) {
return -1; // if cell is not editable, don't bother
+ }
/* editing */
@@ -1879,7 +1783,6 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
String editor_text = c.text;
switch (c.mode) {
-
case TreeItem::CELL_MODE_STRING: {
//nothing in particular
@@ -1889,7 +1792,6 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
} break;
case TreeItem::CELL_MODE_CHECK: {
-
bring_up_editor = false; //checkboxes are not edited with editor
if (force_edit_checkbox_only_on_checkbox) {
if (x < cache.checked->get_width()) {
@@ -1910,7 +1812,6 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
popup_menu->clear();
for (int i = 0; i < c.text.get_slice_count(","); i++) {
-
String s = c.text.get_slicec(',', i);
popup_menu->add_item(s.get_slicec(':', 0), s.get_slicec(':', 1).empty() ? i : s.get_slicec(':', 1).to_int());
}
@@ -1923,16 +1824,12 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
//}
bring_up_editor = false;
} else {
-
if (x >= (col_width - item_h / 2)) {
-
/* touching the combo */
bool up = p_pos.y < (item_h / 2);
if (p_button == BUTTON_LEFT) {
-
if (range_click_timer->get_time_left() == 0) {
-
range_item_last = p_item;
range_up_last = up;
@@ -1941,7 +1838,6 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
range_click_timer->start();
} else if (up != range_up_last) {
-
return -1; // break. avoid changing direction on mouse held
}
@@ -1950,15 +1846,12 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
item_edited(col, p_item);
} else if (p_button == BUTTON_RIGHT) {
-
p_item->set_range(col, (up ? c.max : c.min));
item_edited(col, p_item);
} else if (p_button == BUTTON_WHEEL_UP) {
-
p_item->set_range(col, c.val + c.step);
item_edited(col, p_item);
} else if (p_button == BUTTON_WHEEL_DOWN) {
-
p_item->set_range(col, c.val - c.step);
item_edited(col, p_item);
}
@@ -1967,10 +1860,10 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
bring_up_editor = false;
} else {
-
editor_text = String::num(p_item->cells[col].val, Math::range_step_decimals(p_item->cells[col].step));
- if (select_mode == SELECT_MULTI && get_tree()->get_event_count() == focus_in_id)
+ if (select_mode == SELECT_MULTI && get_tree()->get_event_count() == focus_in_id) {
bring_up_editor = false;
+ }
}
}
click_handled = true;
@@ -1998,8 +1891,9 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
} break;
};
- if (!bring_up_editor || p_button != BUTTON_LEFT)
+ if (!bring_up_editor || p_button != BUTTON_LEFT) {
return -1;
+ }
click_handled = true;
popup_edited_item = p_item;
@@ -2011,7 +1905,6 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
return -1; //select
} else {
-
Point2i new_pos = p_pos;
if (!skip) {
@@ -2026,11 +1919,11 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
TreeItem *c = p_item->children;
while (c) {
-
int child_h = propagate_mouse_event(new_pos, x_ofs, y_ofs, p_doubleclick, c, p_button, p_mod);
- if (child_h < 0)
+ if (child_h < 0) {
return -1; // break, stop propagating, no need to anymore
+ }
new_pos.y -= child_h;
y_ofs += child_h;
@@ -2047,47 +1940,46 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
}
void Tree::_text_editor_modal_close() {
-
- if (InputFilter::get_singleton()->is_key_pressed(KEY_ESCAPE) ||
- InputFilter::get_singleton()->is_key_pressed(KEY_KP_ENTER) ||
- InputFilter::get_singleton()->is_key_pressed(KEY_ENTER)) {
-
+ if (Input::get_singleton()->is_key_pressed(KEY_ESCAPE) ||
+ Input::get_singleton()->is_key_pressed(KEY_KP_ENTER) ||
+ Input::get_singleton()->is_key_pressed(KEY_ENTER)) {
return;
}
- if (value_editor->has_point(value_editor->get_local_mouse_position()))
+ if (value_editor->has_point(value_editor->get_local_mouse_position())) {
return;
+ }
_text_editor_enter(text_editor->get_text());
}
void Tree::_text_editor_enter(String p_text) {
-
popup_editor->hide();
- if (!popup_edited_item)
+ if (!popup_edited_item) {
return;
+ }
- if (popup_edited_item_col < 0 || popup_edited_item_col > columns.size())
+ if (popup_edited_item_col < 0 || popup_edited_item_col > columns.size()) {
return;
+ }
TreeItem::Cell &c = popup_edited_item->cells.write[popup_edited_item_col];
switch (c.mode) {
-
case TreeItem::CELL_MODE_STRING: {
-
c.text = p_text;
//popup_edited_item->edited_signal.call( popup_edited_item_col );
} break;
case TreeItem::CELL_MODE_RANGE: {
-
c.val = p_text.to_double();
- if (c.step > 0)
+ if (c.step > 0) {
c.val = Math::stepify(c.val, c.step);
- if (c.val < c.min)
+ }
+ if (c.val < c.min) {
c.val = c.min;
- else if (c.val > c.max)
+ } else if (c.val > c.max) {
c.val = c.max;
+ }
//popup_edited_item->edited_signal.call( popup_edited_item_col );
} break;
@@ -2101,7 +1993,6 @@ void Tree::_text_editor_enter(String p_text) {
}
void Tree::value_editor_changed(double p_value) {
-
if (updating_value_editor) {
return;
}
@@ -2116,12 +2007,13 @@ void Tree::value_editor_changed(double p_value) {
}
void Tree::popup_select(int p_option) {
-
- if (!popup_edited_item)
+ if (!popup_edited_item) {
return;
+ }
- if (popup_edited_item_col < 0 || popup_edited_item_col > columns.size())
+ if (popup_edited_item_col < 0 || popup_edited_item_col > columns.size()) {
return;
+ }
popup_edited_item->cells.write[popup_edited_item_col].val = p_option;
//popup_edited_item->edited_signal.call( popup_edited_item_col );
@@ -2149,7 +2041,6 @@ void Tree::_go_left() {
selected_col--;
emit_signal("cell_selected");
} else {
-
selected_item->select(selected_col - 1);
}
}
@@ -2171,7 +2062,6 @@ void Tree::_go_right() {
selected_col++;
emit_signal("cell_selected");
} else {
-
selected_item->select(selected_col + 1);
}
}
@@ -2186,7 +2076,6 @@ void Tree::_go_up() {
prev = get_last_item();
selected_col = 0;
} else {
-
prev = selected_item->get_prev_visible();
if (last_keypress != 0) {
//incr search next
@@ -2200,19 +2089,20 @@ void Tree::_go_up() {
}
if (select_mode == SELECT_MULTI) {
-
- if (!prev)
+ if (!prev) {
return;
+ }
selected_item = prev;
emit_signal("cell_selected");
update();
} else {
-
int col = selected_col < 0 ? 0 : selected_col;
- while (prev && !prev->cells[col].selectable)
+ while (prev && !prev->cells[col].selectable) {
prev = prev->get_prev_visible();
- if (!prev)
+ }
+ if (!prev) {
return; // do nothing..
+ }
prev->select(col);
}
@@ -2223,12 +2113,10 @@ void Tree::_go_up() {
void Tree::_go_down() {
TreeItem *next = nullptr;
if (!selected_item) {
-
if (root) {
next = hide_root ? root->get_next_visible() : root;
}
} else {
-
next = selected_item->get_next_visible();
if (last_keypress != 0) {
@@ -2243,7 +2131,6 @@ void Tree::_go_down() {
}
if (select_mode == SELECT_MULTI) {
-
if (!next) {
return;
}
@@ -2252,11 +2139,11 @@ void Tree::_go_down() {
emit_signal("cell_selected");
update();
} else {
-
int col = selected_col < 0 ? 0 : selected_col;
- while (next && !next->cells[col].selectable)
+ while (next && !next->cells[col].selectable) {
next = next->get_next_visible();
+ }
if (!next) {
return; // do nothing..
}
@@ -2268,13 +2155,13 @@ void Tree::_go_down() {
}
void Tree::_gui_input(Ref<InputEvent> p_event) {
-
Ref<InputEventKey> k = p_event;
bool is_command = k.is_valid() && k->get_command();
if (p_event->is_action("ui_right") && p_event->is_pressed()) {
-
- if (!cursor_can_exit_tree) accept_event();
+ if (!cursor_can_exit_tree) {
+ accept_event();
+ }
if (!selected_item || select_mode == SELECT_ROW || selected_col > (columns.size() - 1)) {
return;
@@ -2290,8 +2177,9 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
_go_right();
}
} else if (p_event->is_action("ui_left") && p_event->is_pressed()) {
-
- if (!cursor_can_exit_tree) accept_event();
+ if (!cursor_can_exit_tree) {
+ accept_event();
+ }
if (!selected_item || select_mode == SELECT_ROW || selected_col < 0) {
return;
@@ -2309,48 +2197,50 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
} else if (p_event->is_action("ui_up") && p_event->is_pressed() && !is_command) {
-
- if (!cursor_can_exit_tree) accept_event();
+ if (!cursor_can_exit_tree) {
+ accept_event();
+ }
_go_up();
} else if (p_event->is_action("ui_down") && p_event->is_pressed() && !is_command) {
-
- if (!cursor_can_exit_tree) accept_event();
+ if (!cursor_can_exit_tree) {
+ accept_event();
+ }
_go_down();
} else if (p_event->is_action("ui_page_down") && p_event->is_pressed()) {
-
- if (!cursor_can_exit_tree) accept_event();
+ if (!cursor_can_exit_tree) {
+ accept_event();
+ }
TreeItem *next = nullptr;
- if (!selected_item)
+ if (!selected_item) {
return;
+ }
next = selected_item;
for (int i = 0; i < 10; i++) {
-
TreeItem *_n = next->get_next_visible();
if (_n) {
next = _n;
} else {
-
break;
}
}
- if (next == selected_item)
+ if (next == selected_item) {
return;
+ }
if (select_mode == SELECT_MULTI) {
-
selected_item = next;
emit_signal("cell_selected");
update();
} else {
-
- while (next && !next->cells[selected_col].selectable)
+ while (next && !next->cells[selected_col].selectable) {
next = next->get_next_visible();
+ }
if (!next) {
return; // do nothing..
}
@@ -2359,36 +2249,36 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
ensure_cursor_is_visible();
} else if (p_event->is_action("ui_page_up") && p_event->is_pressed()) {
-
- if (!cursor_can_exit_tree) accept_event();
+ if (!cursor_can_exit_tree) {
+ accept_event();
+ }
TreeItem *prev = nullptr;
- if (!selected_item)
+ if (!selected_item) {
return;
+ }
prev = selected_item;
for (int i = 0; i < 10; i++) {
-
TreeItem *_n = prev->get_prev_visible();
if (_n) {
prev = _n;
} else {
-
break;
}
}
- if (prev == selected_item)
+ if (prev == selected_item) {
return;
+ }
if (select_mode == SELECT_MULTI) {
-
selected_item = prev;
emit_signal("cell_selected");
update();
} else {
-
- while (prev && !prev->cells[selected_col].selectable)
+ while (prev && !prev->cells[selected_col].selectable) {
prev = prev->get_prev_visible();
+ }
if (!prev) {
return; // do nothing..
}
@@ -2396,7 +2286,6 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
ensure_cursor_is_visible();
} else if (p_event->is_action("ui_accept") && p_event->is_pressed()) {
-
if (selected_item) {
//bring up editor if possible
if (!edit_selected()) {
@@ -2406,10 +2295,10 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
accept_event();
} else if (p_event->is_action("ui_select") && p_event->is_pressed()) {
-
if (select_mode == SELECT_MULTI) {
- if (!selected_item)
+ if (!selected_item) {
return;
+ }
if (selected_item->is_selected(selected_col)) {
selected_item->deselect(selected_col);
emit_signal("multi_selected", selected_item, selected_col, false);
@@ -2423,34 +2312,38 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
if (k.is_valid()) { // Incremental search
- if (!k->is_pressed())
+ if (!k->is_pressed()) {
return;
- if (k->get_command() || (k->get_shift() && k->get_unicode() == 0) || k->get_metakey())
+ }
+ if (k->get_command() || (k->get_shift() && k->get_unicode() == 0) || k->get_metakey()) {
return;
- if (!root)
+ }
+ if (!root) {
return;
+ }
- if (hide_root && !root->get_next_visible())
+ if (hide_root && !root->get_next_visible()) {
return;
+ }
if (k->get_unicode() > 0) {
-
_do_incr_search(String::chr(k->get_unicode()));
accept_event();
return;
} else {
- if (k->get_keycode() != KEY_SHIFT)
+ if (k->get_keycode() != KEY_SHIFT) {
last_keypress = 0;
+ }
}
}
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
- if (cache.font.is_null()) // avoid a strange case that may corrupt stuff
+ if (cache.font.is_null()) { // avoid a strange case that may corrupt stuff
update_cache();
+ }
Ref<StyleBox> bg = cache.bg;
@@ -2467,10 +2360,8 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
pos.x += cache.offset.x;
int len = 0;
for (int i = 0; i < columns.size(); i++) {
-
len += get_column_width(i);
if (pos.x < len) {
-
cache.hover_type = Cache::CLICK_TITLE;
cache.hover_index = i;
update();
@@ -2481,16 +2372,16 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
if (root) {
-
Point2 mpos = mm->get_position();
mpos -= cache.bg->get_offset();
mpos.y -= _get_title_button_height();
if (mpos.y >= 0) {
-
- if (h_scroll->is_visible_in_tree())
+ if (h_scroll->is_visible_in_tree()) {
mpos.x += h_scroll->get_value();
- if (v_scroll->is_visible_in_tree())
+ }
+ if (v_scroll->is_visible_in_tree()) {
mpos.y += v_scroll->get_value();
+ }
int col, h, section;
TreeItem *it = _find_item_at_pos(root, mpos, col, h, section);
@@ -2526,16 +2417,14 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
//range drag
if (!range_drag_enabled) {
-
Vector2 cpos = mm->get_position();
if (cpos.distance_to(pressing_pos) > 2) {
range_drag_enabled = true;
range_drag_capture_pos = cpos;
range_drag_base = popup_edited_item->get_range(popup_edited_item_col);
- InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_CAPTURED);
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
}
} else {
-
const TreeItem::Cell &c = popup_edited_item->cells[popup_edited_item_col];
float diff_y = -mm->get_relative().y;
diff_y = Math::pow(ABS(diff_y), 1.8f) * SGN(diff_y);
@@ -2547,7 +2436,6 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
if (drag_touching && !drag_touching_deaccel) {
-
drag_accum -= mm->get_relative().y;
v_scroll->set_value(drag_from + drag_accum);
drag_speed = -mm->get_speed().y;
@@ -2557,13 +2445,12 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventMouseButton> b = p_event;
if (b.is_valid()) {
- if (cache.font.is_null()) // avoid a strange case that may corrupt stuff
+ if (cache.font.is_null()) { // avoid a strange case that may corrupt stuff
update_cache();
+ }
if (!b->is_pressed()) {
-
if (b->get_button_index() == BUTTON_LEFT) {
-
Point2 pos = b->get_position() - cache.bg->get_offset();
if (show_column_titles) {
pos.y -= _get_title_button_height();
@@ -2572,7 +2459,6 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
pos.x += cache.offset.x;
int len = 0;
for (int i = 0; i < columns.size(); i++) {
-
len += get_column_width(i);
if (pos.x < len) {
emit_signal("column_title_pressed", i);
@@ -2590,11 +2476,9 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
range_click_timer->stop();
if (pressing_for_editor) {
-
if (range_drag_enabled) {
-
range_drag_enabled = false;
- InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
warp_mouse(range_drag_capture_pos);
} else {
Rect2 rect = get_selected()->get_meta("__focus_rect");
@@ -2621,13 +2505,11 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
cache.click_column = 0;
if (drag_touching) {
-
if (drag_speed == 0) {
drag_touching_deaccel = false;
drag_touching = false;
set_physics_process_internal(false);
} else {
-
drag_touching_deaccel = true;
}
}
@@ -2636,8 +2518,9 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
return;
}
- if (range_drag_enabled)
+ if (range_drag_enabled) {
return;
+ }
switch (b->get_button_index()) {
case BUTTON_RIGHT:
@@ -2654,10 +2537,8 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
pos.x += cache.offset.x;
int len = 0;
for (int i = 0; i < columns.size(); i++) {
-
len += get_column_width(i);
if (pos.x < len) {
-
cache.click_type = Cache::CLICK_TITLE;
cache.click_index = i;
//cache.click_id=;
@@ -2688,8 +2569,9 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
pressing_pos = b->get_position();
}
- if (b->get_button_index() == BUTTON_RIGHT)
+ if (b->get_button_index() == BUTTON_RIGHT) {
break;
+ }
if (drag_touching) {
set_physics_process_internal(false);
@@ -2711,8 +2593,9 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
if (b->get_button_index() == BUTTON_LEFT) {
- if (get_item_at_position(b->get_position()) == nullptr && !b->get_shift() && !b->get_control() && !b->get_command())
+ if (get_item_at_position(b->get_position()) == nullptr && !b->get_shift() && !b->get_control() && !b->get_command()) {
emit_signal("nothing_selected");
+ }
}
}
@@ -2723,7 +2606,6 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
} break;
case BUTTON_WHEEL_UP: {
-
double prev_value = v_scroll->get_value();
v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8);
if (v_scroll->get_value() != prev_value) {
@@ -2732,7 +2614,6 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
} break;
case BUTTON_WHEEL_DOWN: {
-
double prev_value = v_scroll->get_value();
v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8);
if (v_scroll->get_value() != prev_value) {
@@ -2745,7 +2626,6 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventPanGesture> pan_gesture = p_event;
if (pan_gesture.is_valid()) {
-
double prev_v = v_scroll->get_value();
v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * pan_gesture->get_delta().y / 8);
@@ -2759,15 +2639,15 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
}
bool Tree::edit_selected() {
-
TreeItem *s = get_selected();
ERR_FAIL_COND_V_MSG(!s, false, "No item selected.");
ensure_cursor_is_visible();
int col = get_selected_column();
ERR_FAIL_INDEX_V_MSG(col, columns.size(), false, "No item column selected.");
- if (!s->cells[col].editable)
+ if (!s->cells[col].editable) {
return false;
+ }
Rect2 rect = s->get_meta("__focus_rect");
popup_edited_item = s;
@@ -2776,12 +2656,10 @@ bool Tree::edit_selected() {
const TreeItem::Cell &c = s->cells[col];
if (c.mode == TreeItem::CELL_MODE_CHECK) {
-
s->set_checked(col, !c.checked);
item_edited(col, s);
return true;
} else if (c.mode == TreeItem::CELL_MODE_CUSTOM) {
-
edited_item = s;
edited_col = col;
custom_popup_rect = Rect2i(get_global_position() + rect.position, rect.size);
@@ -2790,10 +2668,8 @@ bool Tree::edit_selected() {
return true;
} else if (c.mode == TreeItem::CELL_MODE_RANGE && c.text != "") {
-
popup_menu->clear();
for (int i = 0; i < c.text.get_slice_count(","); i++) {
-
String s2 = c.text.get_slicec(',', i);
popup_menu->add_item(s2.get_slicec(':', 0), s2.get_slicec(':', 1).empty() ? i : s2.get_slicec(':', 1).to_int());
}
@@ -2806,7 +2682,6 @@ bool Tree::edit_selected() {
return true;
} else if (c.mode == TreeItem::CELL_MODE_STRING || c.mode == TreeItem::CELL_MODE_RANGE) {
-
Rect2 popup_rect;
Vector2 ofs(0, (text_editor->get_size().height - rect.size.height) / 2);
@@ -2820,7 +2695,6 @@ bool Tree::edit_selected() {
text_editor->select_all();
if (c.mode == TreeItem::CELL_MODE_RANGE) {
-
popup_rect.size.y += value_editor->get_minimum_size().height;
value_editor->show();
@@ -2849,12 +2723,11 @@ bool Tree::edit_selected() {
}
Size2 Tree::get_internal_min_size() const {
-
Size2i size = cache.bg->get_offset();
- if (root)
+ if (root) {
size.height += get_item_height(root);
+ }
for (int i = 0; i < columns.size(); i++) {
-
size.width += columns[i].min_width;
}
@@ -2862,13 +2735,11 @@ Size2 Tree::get_internal_min_size() const {
}
void Tree::update_scrollbars() {
-
Size2 size = get_size();
int tbh;
if (show_column_titles) {
tbh = _get_title_button_height();
} else {
-
tbh = 0;
}
@@ -2884,11 +2755,9 @@ void Tree::update_scrollbars() {
Size2 min = get_internal_min_size();
if (min.height < size.height - hmin.height) {
-
v_scroll->hide();
cache.offset.y = 0;
} else {
-
v_scroll->show();
v_scroll->set_max(min.height);
v_scroll->set_page(size.height - hmin.height - tbh);
@@ -2896,11 +2765,9 @@ void Tree::update_scrollbars() {
}
if (min.width < size.width - vmin.width) {
-
h_scroll->hide();
cache.offset.x = 0;
} else {
-
h_scroll->show();
h_scroll->set_max(min.width);
h_scroll->set_page(size.width - vmin.width);
@@ -2909,19 +2776,15 @@ void Tree::update_scrollbars() {
}
int Tree::_get_title_button_height() const {
-
ERR_FAIL_COND_V(cache.font.is_null() || cache.title_button.is_null(), 0);
return show_column_titles ? cache.font->get_height() + cache.title_button->get_minimum_size().height : 0;
}
void Tree::_notification(int p_what) {
-
if (p_what == NOTIFICATION_FOCUS_ENTER) {
-
focus_in_id = get_tree()->get_event_count();
}
if (p_what == NOTIFICATION_MOUSE_EXIT) {
-
if (cache.hover_type != Cache::CLICK_NONE) {
cache.hover_type = Cache::CLICK_NONE;
update();
@@ -2929,23 +2792,19 @@ void Tree::_notification(int p_what) {
}
if (p_what == NOTIFICATION_VISIBILITY_CHANGED) {
-
drag_touching = false;
}
if (p_what == NOTIFICATION_ENTER_TREE) {
-
update_cache();
}
if (p_what == NOTIFICATION_DRAG_END) {
-
drop_mode_flags = 0;
scrolling = false;
set_physics_process_internal(false);
update();
}
if (p_what == NOTIFICATION_DRAG_BEGIN) {
-
single_select_defer = nullptr;
if (cache.scroll_speed > 0) {
scrolling = true;
@@ -2953,11 +2812,8 @@ void Tree::_notification(int p_what) {
}
}
if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) {
-
if (drag_touching) {
-
if (drag_touching_deaccel) {
-
float pos = v_scroll->get_value();
pos += drag_speed * get_physics_process_delta_time();
@@ -3016,7 +2872,6 @@ void Tree::_notification(int p_what) {
}
if (p_what == NOTIFICATION_DRAW) {
-
update_cache();
update_scrollbars();
RID ci = get_canvas_item();
@@ -3041,16 +2896,13 @@ void Tree::_notification(int p_what) {
draw_size.y -= tbh;
if (root) {
-
draw_item(Point2(), draw_ofs, draw_size, root);
}
if (show_column_titles) {
-
//title buttons
int ofs2 = cache.bg->get_margin(MARGIN_LEFT);
for (int i = 0; i < columns.size(); i++) {
-
Ref<StyleBox> sb = (cache.click_type == Cache::CLICK_TITLE && cache.click_index == i) ? cache.title_button_pressed : ((cache.hover_type == Cache::CLICK_TITLE && cache.hover_index == i) ? cache.title_button_hover : cache.title_button);
Ref<Font> f = cache.tb_font;
Rect2 tbrect = Rect2(ofs2 - cache.offset.x, bg->get_margin(MARGIN_TOP), get_column_width(i), tbh);
@@ -3068,7 +2920,6 @@ void Tree::_notification(int p_what) {
}
if (p_what == NOTIFICATION_RESIZED || p_what == NOTIFICATION_TRANSFORM_CHANGED) {
-
if (popup_edited_item != nullptr) {
Rect2 rect = popup_edited_item->get_meta("__focus_rect");
Vector2 ofs(0, (text_editor->get_size().height - rect.size.height) / 2);
@@ -3084,18 +2935,15 @@ void Tree::_notification(int p_what) {
}
Size2 Tree::get_minimum_size() const {
-
return Size2(1, 1);
}
TreeItem *Tree::create_item(TreeItem *p_parent, int p_idx) {
-
ERR_FAIL_COND_V(blocked > 0, nullptr);
TreeItem *ti = nullptr;
if (p_parent) {
-
// Append or insert a new item to the given parent.
ti = memnew(TreeItem(this));
ERR_FAIL_COND_V(!ti, nullptr);
@@ -3114,14 +2962,14 @@ TreeItem *Tree::create_item(TreeItem *p_parent, int p_idx) {
c = c->next;
}
- if (prev)
+ if (prev) {
prev->next = ti;
- else
+ } else {
p_parent->children = ti;
+ }
ti->parent = p_parent;
} else {
-
if (!root) {
// No root exists, make the given item the new root.
ti = memnew(TreeItem(this));
@@ -3139,61 +2987,56 @@ TreeItem *Tree::create_item(TreeItem *p_parent, int p_idx) {
}
TreeItem *Tree::get_root() {
-
return root;
}
-TreeItem *Tree::get_last_item() {
+TreeItem *Tree::get_last_item() {
TreeItem *last = root;
while (last) {
-
- if (last->next)
+ if (last->next) {
last = last->next;
- else if (last->children)
+ } else if (last->children) {
last = last->children;
- else
+ } else {
break;
+ }
}
return last;
}
void Tree::item_edited(int p_column, TreeItem *p_item, bool p_lmb) {
-
edited_item = p_item;
edited_col = p_column;
- if (p_lmb)
+ if (p_lmb) {
emit_signal("item_edited");
- else
+ } else {
emit_signal("item_rmb_edited");
+ }
}
void Tree::item_changed(int p_column, TreeItem *p_item) {
-
update();
}
void Tree::item_selected(int p_column, TreeItem *p_item) {
-
if (select_mode == SELECT_MULTI) {
-
- if (!p_item->cells[p_column].selectable)
+ if (!p_item->cells[p_column].selectable) {
return;
+ }
p_item->cells.write[p_column].selected = true;
//emit_signal("multi_selected",p_item,p_column,true); - NO this is for TreeItem::select
selected_col = p_column;
} else {
-
select_single_item(p_item, root, p_column);
}
update();
}
void Tree::item_deselected(int p_column, TreeItem *p_item) {
-
if (select_mode == SELECT_MULTI || select_mode == SELECT_SINGLE) {
p_item->cells.write[p_column].selected = false;
}
@@ -3201,17 +3044,14 @@ void Tree::item_deselected(int p_column, TreeItem *p_item) {
}
void Tree::set_select_mode(SelectMode p_mode) {
-
select_mode = p_mode;
}
Tree::SelectMode Tree::get_select_mode() const {
-
return select_mode;
}
void Tree::deselect_all() {
-
TreeItem *item = get_next_selected(get_root());
while (item) {
item->deselect(selected_col);
@@ -3227,18 +3067,16 @@ void Tree::deselect_all() {
}
bool Tree::is_anything_selected() {
-
return (selected_item != nullptr);
}
void Tree::clear() {
-
ERR_FAIL_COND(blocked > 0);
if (pressing_for_editor) {
if (range_drag_enabled) {
range_drag_enabled = false;
- InputFilter::get_singleton()->set_mouse_mode(InputFilter::MOUSE_MODE_VISIBLE);
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
warp_mouse(range_drag_capture_pos);
}
pressing_for_editor = false;
@@ -3257,27 +3095,25 @@ void Tree::clear() {
};
void Tree::set_hide_root(bool p_enabled) {
-
hide_root = p_enabled;
update();
}
bool Tree::is_root_hidden() const {
-
return hide_root;
}
void Tree::set_column_min_width(int p_column, int p_min_width) {
-
ERR_FAIL_INDEX(p_column, columns.size());
- if (p_min_width < 1)
+ if (p_min_width < 1) {
return;
+ }
columns.write[p_column].min_width = p_min_width;
update();
}
-void Tree::set_column_expand(int p_column, bool p_expand) {
+void Tree::set_column_expand(int p_column, bool p_expand) {
ERR_FAIL_INDEX(p_column, columns.size());
columns.write[p_column].expand = p_expand;
@@ -3285,87 +3121,80 @@ void Tree::set_column_expand(int p_column, bool p_expand) {
}
TreeItem *Tree::get_selected() const {
-
return selected_item;
}
int Tree::get_selected_column() const {
-
return selected_col;
}
TreeItem *Tree::get_edited() const {
-
return edited_item;
}
int Tree::get_edited_column() const {
-
return edited_col;
}
TreeItem *Tree::get_next_selected(TreeItem *p_item) {
-
/*
if (!p_item)
return nullptr;
*/
- if (!root)
+ if (!root) {
return nullptr;
+ }
while (true) {
-
if (!p_item) {
p_item = root;
} else {
-
if (p_item->children) {
-
p_item = p_item->children;
} else if (p_item->next) {
-
p_item = p_item->next;
} else {
-
while (!p_item->next) {
-
p_item = p_item->parent;
- if (p_item == nullptr)
+ if (p_item == nullptr) {
return nullptr;
+ }
}
p_item = p_item->next;
}
}
- for (int i = 0; i < columns.size(); i++)
- if (p_item->cells[i].selected)
+ for (int i = 0; i < columns.size(); i++) {
+ if (p_item->cells[i].selected) {
return p_item;
+ }
+ }
}
return nullptr;
}
int Tree::get_column_width(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, columns.size(), -1);
- if (!columns[p_column].expand)
+ if (!columns[p_column].expand) {
return columns[p_column].min_width;
+ }
Ref<StyleBox> bg = cache.bg;
int expand_area = get_size().width - (bg->get_margin(MARGIN_LEFT) + bg->get_margin(MARGIN_RIGHT));
- if (v_scroll->is_visible_in_tree())
+ if (v_scroll->is_visible_in_tree()) {
expand_area -= v_scroll->get_combined_minimum_size().width;
+ }
int expanding_columns = 0;
int expanding_total = 0;
for (int i = 0; i < columns.size(); i++) {
-
if (!columns[i].expand) {
expand_area -= columns[i].min_width;
} else {
@@ -3374,8 +3203,9 @@ int Tree::get_column_width(int p_column) const {
}
}
- if (expand_area < expanding_total)
+ if (expand_area < expanding_total) {
return columns[p_column].min_width;
+ }
ERR_FAIL_COND_V(expanding_columns == 0, -1); // shouldn't happen
@@ -3383,56 +3213,52 @@ int Tree::get_column_width(int p_column) const {
}
void Tree::propagate_set_columns(TreeItem *p_item) {
-
p_item->cells.resize(columns.size());
TreeItem *c = p_item->get_children();
while (c) {
-
propagate_set_columns(c);
c = c->get_next();
}
}
void Tree::set_columns(int p_columns) {
-
ERR_FAIL_COND(p_columns < 1);
ERR_FAIL_COND(blocked > 0);
columns.resize(p_columns);
- if (root)
+ if (root) {
propagate_set_columns(root);
- if (selected_col >= p_columns)
+ }
+ if (selected_col >= p_columns) {
selected_col = p_columns - 1;
+ }
update();
}
int Tree::get_columns() const {
-
return columns.size();
}
void Tree::_scroll_moved(float) {
-
update();
}
Rect2 Tree::get_custom_popup_rect() const {
-
return custom_popup_rect;
}
int Tree::get_item_offset(TreeItem *p_item) const {
-
TreeItem *it = root;
int ofs = _get_title_button_height();
- if (!it)
+ if (!it) {
return 0;
+ }
while (true) {
-
- if (it == p_item)
+ if (it == p_item) {
return ofs;
+ }
ofs += compute_item_height(it);
if (it != root || !hide_root) {
@@ -3440,19 +3266,16 @@ int Tree::get_item_offset(TreeItem *p_item) const {
}
if (it->children && !it->collapsed) {
-
it = it->children;
} else if (it->next) {
-
it = it->next;
} else {
-
while (!it->next) {
-
it = it->parent;
- if (it == nullptr)
+ if (it == nullptr) {
return 0;
+ }
}
it = it->next;
@@ -3509,12 +3332,10 @@ void Tree::ensure_cursor_is_visible() {
}
int Tree::get_pressed_button() const {
-
return pressed_button;
}
Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column) const {
-
ERR_FAIL_NULL_V(p_item, Rect2());
ERR_FAIL_COND_V(p_item->tree != this, Rect2());
if (p_column != -1) {
@@ -3531,7 +3352,6 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column) const {
r.position.x = 0;
r.size.x = get_size().width;
} else {
-
int accum = 0;
for (int i = 0; i < p_column; i++) {
accum += get_column_width(i);
@@ -3544,43 +3364,38 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column) const {
}
void Tree::set_column_titles_visible(bool p_show) {
-
show_column_titles = p_show;
update();
}
bool Tree::are_column_titles_visible() const {
-
return show_column_titles;
}
void Tree::set_column_title(int p_column, const String &p_title) {
-
ERR_FAIL_INDEX(p_column, columns.size());
columns.write[p_column].title = p_title;
update();
}
String Tree::get_column_title(int p_column) const {
-
ERR_FAIL_INDEX_V(p_column, columns.size(), "");
return columns[p_column].title;
}
Point2 Tree::get_scroll() const {
-
Point2 ofs;
- if (h_scroll->is_visible_in_tree())
+ if (h_scroll->is_visible_in_tree()) {
ofs.x = h_scroll->get_value();
- if (v_scroll->is_visible_in_tree())
+ }
+ if (v_scroll->is_visible_in_tree()) {
ofs.y = v_scroll->get_value();
+ }
return ofs;
}
void Tree::scroll_to_item(TreeItem *p_item) {
-
if (!is_visible_in_tree()) {
-
// hack to work around crash in get_item_rect() if Tree is not in tree.
return;
}
@@ -3598,38 +3413,40 @@ void Tree::scroll_to_item(TreeItem *p_item) {
}
TreeItem *Tree::_search_item_text(TreeItem *p_at, const String &p_find, int *r_col, bool p_selectable, bool p_backwards) {
-
TreeItem *from = p_at;
while (p_at) {
-
for (int i = 0; i < columns.size(); i++) {
if (p_at->get_text(i).findn(p_find) == 0 && (!p_selectable || p_at->is_selectable(i))) {
- if (r_col)
+ if (r_col) {
*r_col = i;
+ }
return p_at;
}
}
- if (p_backwards)
+ if (p_backwards) {
p_at = p_at->get_prev_visible(true);
- else
+ } else {
p_at = p_at->get_next_visible(true);
+ }
- if ((p_at) == from)
+ if ((p_at) == from) {
break;
+ }
}
return nullptr;
}
TreeItem *Tree::search_item_text(const String &p_find, int *r_col, bool p_selectable) {
-
TreeItem *from = get_selected();
- if (!from)
+ if (!from) {
from = root;
- if (!from)
+ }
+ if (!from) {
return nullptr;
+ }
return _search_item_text(from->get_next_visible(true), p_find, r_col, p_selectable);
}
@@ -3646,33 +3463,31 @@ TreeItem *Tree::get_item_with_text(const String &p_find) const {
}
void Tree::_do_incr_search(const String &p_add) {
-
uint64_t time = OS::get_singleton()->get_ticks_usec() / 1000; // convert to msec
uint64_t diff = time - last_keypress;
- if (diff > uint64_t(GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000)))
+ if (diff > uint64_t(GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000))) {
incr_search = p_add;
- else if (incr_search != p_add)
+ } else if (incr_search != p_add) {
incr_search += p_add;
+ }
last_keypress = time;
int col;
TreeItem *item = search_item_text(incr_search, &col, true);
- if (!item)
+ if (!item) {
return;
+ }
item->select(col);
ensure_cursor_is_visible();
}
TreeItem *Tree::_find_item_at_pos(TreeItem *p_item, const Point2 &p_pos, int &r_column, int &h, int &section) const {
-
Point2 pos = p_pos;
if (root != p_item || !hide_root) {
-
h = compute_item_height(p_item) + cache.vseparation;
if (pos.y < h) {
-
if (drop_mode_flags == DROP_MODE_ON_ITEM) {
section = 0;
} else if (drop_mode_flags == DROP_MODE_INBETWEEN) {
@@ -3686,7 +3501,6 @@ TreeItem *Tree::_find_item_at_pos(TreeItem *p_item, const Point2 &p_pos, int &r_
}
for (int i = 0; i < columns.size(); i++) {
-
int w = get_column_width(i);
if (pos.x < w) {
r_column = i;
@@ -3698,26 +3512,25 @@ TreeItem *Tree::_find_item_at_pos(TreeItem *p_item, const Point2 &p_pos, int &r_
return nullptr;
} else {
-
pos.y -= h;
}
} else {
-
h = 0;
}
- if (p_item->is_collapsed())
+ if (p_item->is_collapsed()) {
return nullptr; // do not try children, it's collapsed
+ }
TreeItem *n = p_item->get_children();
while (n) {
-
int ch;
TreeItem *r = _find_item_at_pos(n, pos, r_column, ch, section);
pos.y -= ch;
h += ch;
- if (r)
+ if (r) {
return r;
+ }
n = n->get_next();
}
@@ -3725,19 +3538,20 @@ TreeItem *Tree::_find_item_at_pos(TreeItem *p_item, const Point2 &p_pos, int &r_
}
int Tree::get_column_at_position(const Point2 &p_pos) const {
-
if (root) {
-
Point2 pos = p_pos;
pos -= cache.bg->get_offset();
pos.y -= _get_title_button_height();
- if (pos.y < 0)
+ if (pos.y < 0) {
return -1;
+ }
- if (h_scroll->is_visible_in_tree())
+ if (h_scroll->is_visible_in_tree()) {
pos.x += h_scroll->get_value();
- if (v_scroll->is_visible_in_tree())
+ }
+ if (v_scroll->is_visible_in_tree()) {
pos.y += v_scroll->get_value();
+ }
int col, h, section;
TreeItem *it = _find_item_at_pos(root, pos, col, h, section);
@@ -3751,19 +3565,20 @@ int Tree::get_column_at_position(const Point2 &p_pos) const {
}
int Tree::get_drop_section_at_position(const Point2 &p_pos) const {
-
if (root) {
-
Point2 pos = p_pos;
pos -= cache.bg->get_offset();
pos.y -= _get_title_button_height();
- if (pos.y < 0)
+ if (pos.y < 0) {
return -100;
+ }
- if (h_scroll->is_visible_in_tree())
+ if (h_scroll->is_visible_in_tree()) {
pos.x += h_scroll->get_value();
- if (v_scroll->is_visible_in_tree())
+ }
+ if (v_scroll->is_visible_in_tree()) {
pos.y += v_scroll->get_value();
+ }
int col, h, section;
TreeItem *it = _find_item_at_pos(root, pos, col, h, section);
@@ -3775,26 +3590,27 @@ int Tree::get_drop_section_at_position(const Point2 &p_pos) const {
return -100;
}
-TreeItem *Tree::get_item_at_position(const Point2 &p_pos) const {
+TreeItem *Tree::get_item_at_position(const Point2 &p_pos) const {
if (root) {
-
Point2 pos = p_pos;
pos -= cache.bg->get_offset();
pos.y -= _get_title_button_height();
- if (pos.y < 0)
+ if (pos.y < 0) {
return nullptr;
+ }
- if (h_scroll->is_visible_in_tree())
+ if (h_scroll->is_visible_in_tree()) {
pos.x += h_scroll->get_value();
- if (v_scroll->is_visible_in_tree())
+ }
+ if (v_scroll->is_visible_in_tree()) {
pos.y += v_scroll->get_value();
+ }
int col, h, section;
TreeItem *it = _find_item_at_pos(root, pos, col, h, section);
if (it) {
-
return it;
}
}
@@ -3803,30 +3619,31 @@ TreeItem *Tree::get_item_at_position(const Point2 &p_pos) const {
}
String Tree::get_tooltip(const Point2 &p_pos) const {
-
if (root) {
-
Point2 pos = p_pos;
pos -= cache.bg->get_offset();
pos.y -= _get_title_button_height();
- if (pos.y < 0)
+ if (pos.y < 0) {
return Control::get_tooltip(p_pos);
+ }
- if (h_scroll->is_visible_in_tree())
+ if (h_scroll->is_visible_in_tree()) {
pos.x += h_scroll->get_value();
- if (v_scroll->is_visible_in_tree())
+ }
+ if (v_scroll->is_visible_in_tree()) {
pos.y += v_scroll->get_value();
+ }
int col, h, section;
TreeItem *it = _find_item_at_pos(root, pos, col, h, section);
if (it) {
-
const TreeItem::Cell &c = it->cells[col];
int col_width = get_column_width(col);
- for (int i = 0; i < col; i++)
+ for (int i = 0; i < col; i++) {
pos.x -= get_column_width(i);
+ }
for (int j = c.buttons.size() - 1; j >= 0; j--) {
Ref<Texture2D> b = c.buttons[j].texture;
@@ -3840,10 +3657,11 @@ String Tree::get_tooltip(const Point2 &p_pos) const {
col_width -= size.width;
}
String ret;
- if (it->get_tooltip(col) == "")
+ if (it->get_tooltip(col) == "") {
ret = it->get_text(col);
- else
+ } else {
ret = it->get_tooltip(col);
+ }
return ret;
}
}
@@ -3852,12 +3670,10 @@ String Tree::get_tooltip(const Point2 &p_pos) const {
}
void Tree::set_cursor_can_exit_tree(bool p_enable) {
-
cursor_can_exit_tree = p_enable;
}
bool Tree::can_cursor_exit_tree() const {
-
return cursor_can_exit_tree;
}
@@ -3867,13 +3683,13 @@ void Tree::set_hide_folding(bool p_hide) {
}
bool Tree::is_folding_hidden() const {
-
return hide_folding;
}
void Tree::set_drop_mode_flags(int p_flags) {
- if (drop_mode_flags == p_flags)
+ if (drop_mode_flags == p_flags) {
return;
+ }
drop_mode_flags = p_flags;
if (drop_mode_flags == 0) {
drop_mode_over = nullptr;
@@ -3883,27 +3699,22 @@ void Tree::set_drop_mode_flags(int p_flags) {
}
int Tree::get_drop_mode_flags() const {
-
return drop_mode_flags;
}
void Tree::set_edit_checkbox_cell_only_when_checkbox_is_pressed(bool p_enable) {
-
force_edit_checkbox_only_on_checkbox = p_enable;
}
bool Tree::get_edit_checkbox_cell_only_when_checkbox_is_pressed() const {
-
return force_edit_checkbox_only_on_checkbox;
}
void Tree::set_allow_rmb_select(bool p_allow) {
-
allow_rmb_select = p_allow;
}
bool Tree::get_allow_rmb_select() const {
-
return allow_rmb_select;
}
@@ -3912,12 +3723,10 @@ void Tree::set_allow_reselect(bool p_allow) {
}
bool Tree::get_allow_reselect() const {
-
return allow_reselect;
}
void Tree::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_gui_input"), &Tree::_gui_input);
ClassDB::bind_method(D_METHOD("clear"), &Tree::clear);
@@ -4005,7 +3814,6 @@ void Tree::_bind_methods() {
}
Tree::Tree() {
-
selected_col = 0;
columns.resize(1);
selected_item = nullptr;
@@ -4109,7 +3917,6 @@ Tree::Tree() {
}
Tree::~Tree() {
-
if (root) {
memdelete(root);
}
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 87c2588a12..46842e78a0 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -40,7 +40,6 @@
class Tree;
class TreeItem : public Object {
-
GDCLASS(TreeItem, Object);
public:
@@ -63,7 +62,6 @@ private:
friend class Tree;
struct Cell {
-
TreeCellMode mode;
Ref<Texture2D> icon;
@@ -111,7 +109,6 @@ private:
Vector<Button> buttons;
Cell() {
-
custom_draw_obj = ObjectID();
custom_button = false;
mode = TreeItem::CELL_MODE_STRING;
@@ -293,7 +290,6 @@ VARIANT_ENUM_CAST(TreeItem::TextAlign);
class VBoxContainer;
class Tree : public Control {
-
GDCLASS(Tree, Control);
public:
@@ -350,7 +346,6 @@ private:
int drop_mode_flags;
struct ColumnInfo {
-
int min_width;
bool expand;
String title;
@@ -404,7 +399,6 @@ private:
void propagate_set_columns(TreeItem *p_item);
struct Cache {
-
Ref<Font> font;
Ref<Font> tb_font;
Ref<StyleBox> bg;
@@ -544,7 +538,7 @@ public:
void clear();
- TreeItem *create_item(TreeItem *p_parent = 0, int p_idx = -1);
+ TreeItem *create_item(TreeItem *p_parent = nullptr, int p_idx = -1);
TreeItem *get_root();
TreeItem *get_last_item();
diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp
index ac1e4a5629..881df06d8f 100644
--- a/scene/gui/video_player.cpp
+++ b/scene/gui/video_player.cpp
@@ -35,7 +35,6 @@
#include "servers/audio_server.h"
int VideoPlayer::sp_get_channel_count() const {
-
if (playback.is_null()) {
return 0;
}
@@ -44,7 +43,6 @@ int VideoPlayer::sp_get_channel_count() const {
}
bool VideoPlayer::mix(AudioFrame *p_buffer, int p_frames) {
-
// Check the amount resampler can really handle.
// If it cannot, wait "wait_resampler_phase_limit" times.
// This mechanism contributes to smoother pause/unpause operation.
@@ -59,7 +57,6 @@ bool VideoPlayer::mix(AudioFrame *p_buffer, int p_frames) {
// Called from main thread (eg VideoStreamPlaybackWebm::update)
int VideoPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_frames) {
-
ERR_FAIL_NULL_V(p_udata, 0);
ERR_FAIL_NULL_V(p_data, 0);
@@ -79,14 +76,12 @@ int VideoPlayer::_audio_mix_callback(void *p_udata, const float *p_data, int p_f
}
void VideoPlayer::_mix_audios(void *p_self) {
-
ERR_FAIL_NULL(p_self);
reinterpret_cast<VideoPlayer *>(p_self)->_mix_audio();
}
// Called from audio thread
void VideoPlayer::_mix_audio() {
-
if (!stream.is_valid()) {
return;
}
@@ -98,8 +93,9 @@ void VideoPlayer::_mix_audio() {
int buffer_size = mix_buffer.size();
// Resample
- if (!mix(buffer, buffer_size))
+ if (!mix(buffer, buffer_size)) {
return;
+ }
AudioFrame vol = AudioFrame(volume, volume);
@@ -110,7 +106,6 @@ void VideoPlayer::_mix_audio() {
ERR_FAIL_COND(!target);
for (int j = 0; j < buffer_size; j++) {
-
target[j] += buffer[j] * vol;
}
@@ -123,7 +118,6 @@ void VideoPlayer::_mix_audio() {
}
for (int j = 0; j < buffer_size; j++) {
-
AudioFrame frame = buffer[j] * vol;
for (int k = 0; k < cc; k++) {
targets[k][j] += frame;
@@ -133,11 +127,8 @@ void VideoPlayer::_mix_audio() {
}
void VideoPlayer::_notification(int p_notification) {
-
switch (p_notification) {
-
case NOTIFICATION_ENTER_TREE: {
-
AudioServer::get_singleton()->add_callback(_mix_audios, this);
if (stream.is_valid() && autoplay && !Engine::get_singleton()->is_editor_hint()) {
@@ -147,25 +138,25 @@ void VideoPlayer::_notification(int p_notification) {
} break;
case NOTIFICATION_EXIT_TREE: {
-
AudioServer::get_singleton()->remove_callback(_mix_audios, this);
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
-
bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus);
- if (stream.is_null() || paused || playback.is_null() || !playback->is_playing())
+ if (stream.is_null() || paused || playback.is_null() || !playback->is_playing()) {
return;
+ }
double audio_time = USEC_TO_SEC(OS::get_singleton()->get_ticks_usec());
double delta = last_audio_time == 0 ? 0 : audio_time - last_audio_time;
last_audio_time = audio_time;
- if (delta == 0)
+ if (delta == 0) {
return;
+ }
playback->update(delta); // playback->is_playing() returns false in the last video frame
@@ -176,11 +167,12 @@ void VideoPlayer::_notification(int p_notification) {
} break;
case NOTIFICATION_DRAW: {
-
- if (texture.is_null())
+ if (texture.is_null()) {
return;
- if (texture->get_width() == 0)
+ }
+ if (texture->get_width() == 0) {
return;
+ }
Size2 s = expand ? get_size() : texture->get_size();
draw_texture_rect(texture, Rect2(Point2(), s), false);
@@ -190,27 +182,24 @@ void VideoPlayer::_notification(int p_notification) {
};
Size2 VideoPlayer::get_minimum_size() const {
-
- if (!expand && !texture.is_null())
+ if (!expand && !texture.is_null()) {
return texture->get_size();
- else
+ } else {
return Size2();
+ }
}
void VideoPlayer::set_expand(bool p_expand) {
-
expand = p_expand;
update();
minimum_size_changed();
}
bool VideoPlayer::has_expand() const {
-
return expand;
}
void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) {
-
stop();
AudioServer::get_singleton()->lock();
mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size());
@@ -232,14 +221,16 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) {
const int channels = playback->get_channels();
AudioServer::get_singleton()->lock();
- if (channels > 0)
+ if (channels > 0) {
resampler.setup(channels, playback->get_mix_rate(), AudioServer::get_singleton()->get_mix_rate(), buffering_ms, 0);
- else
+ } else {
resampler.clear();
+ }
AudioServer::get_singleton()->unlock();
- if (channels > 0)
+ if (channels > 0) {
playback->set_mix_callback(_audio_mix_callback, this);
+ }
} else {
texture.unref();
@@ -256,15 +247,14 @@ void VideoPlayer::set_stream(const Ref<VideoStream> &p_stream) {
};
Ref<VideoStream> VideoPlayer::get_stream() const {
-
return stream;
};
void VideoPlayer::play() {
-
ERR_FAIL_COND(!is_inside_tree());
- if (playback.is_null())
+ if (playback.is_null()) {
return;
+ }
playback->stop();
playback->play();
set_process_internal(true);
@@ -274,11 +264,12 @@ void VideoPlayer::play() {
};
void VideoPlayer::stop() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
- if (playback.is_null())
+ }
+ if (playback.is_null()) {
return;
+ }
playback->stop();
// AudioServer::get_singleton()->stream_set_active(stream_rid,false);
@@ -288,15 +279,14 @@ void VideoPlayer::stop() {
};
bool VideoPlayer::is_playing() const {
-
- if (playback.is_null())
+ if (playback.is_null()) {
return false;
+ }
return playback->is_playing();
};
void VideoPlayer::set_paused(bool p_paused) {
-
paused = p_paused;
if (playback.is_valid()) {
playback->set_paused(p_paused);
@@ -306,17 +296,14 @@ void VideoPlayer::set_paused(bool p_paused) {
};
bool VideoPlayer::is_paused() const {
-
return paused;
}
void VideoPlayer::set_buffering_msec(int p_msec) {
-
buffering_ms = p_msec;
}
int VideoPlayer::get_buffering_msec() const {
-
return buffering_ms;
}
@@ -325,76 +312,70 @@ void VideoPlayer::set_audio_track(int p_track) {
}
int VideoPlayer::get_audio_track() const {
-
return audio_track;
}
void VideoPlayer::set_volume(float p_vol) {
-
volume = p_vol;
};
float VideoPlayer::get_volume() const {
-
return volume;
};
void VideoPlayer::set_volume_db(float p_db) {
-
- if (p_db < -79)
+ if (p_db < -79) {
set_volume(0);
- else
+ } else {
set_volume(Math::db2linear(p_db));
+ }
};
float VideoPlayer::get_volume_db() const {
-
- if (volume == 0)
+ if (volume == 0) {
return -80;
- else
+ } else {
return Math::linear2db(volume);
+ }
};
String VideoPlayer::get_stream_name() const {
-
- if (stream.is_null())
+ if (stream.is_null()) {
return "<No Stream>";
+ }
return stream->get_name();
};
float VideoPlayer::get_stream_position() const {
-
- if (playback.is_null())
+ if (playback.is_null()) {
return 0;
+ }
return playback->get_playback_position();
};
void VideoPlayer::set_stream_position(float p_position) {
-
- if (playback.is_valid())
+ if (playback.is_valid()) {
playback->seek(p_position);
+ }
}
Ref<Texture2D> VideoPlayer::get_video_texture() const {
-
- if (playback.is_valid())
+ if (playback.is_valid()) {
return playback->get_texture();
+ }
return Ref<Texture2D>();
}
void VideoPlayer::set_autoplay(bool p_enable) {
-
autoplay = p_enable;
};
bool VideoPlayer::has_autoplay() const {
-
return autoplay;
};
void VideoPlayer::set_bus(const StringName &p_bus) {
-
//if audio is active, must lock this
AudioServer::get_singleton()->lock();
bus = p_bus;
@@ -402,7 +383,6 @@ void VideoPlayer::set_bus(const StringName &p_bus) {
}
StringName VideoPlayer::get_bus() const {
-
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
if (AudioServer::get_singleton()->get_bus_name(i) == bus) {
return bus;
@@ -412,13 +392,12 @@ StringName VideoPlayer::get_bus() const {
}
void VideoPlayer::_validate_property(PropertyInfo &p_property) const {
-
if (p_property.name == "bus") {
-
String options;
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
- if (i > 0)
+ if (i > 0) {
options += ",";
+ }
String name = AudioServer::get_singleton()->get_bus_name(i);
options += name;
}
@@ -428,7 +407,6 @@ void VideoPlayer::_validate_property(PropertyInfo &p_property) const {
}
void VideoPlayer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_stream", "stream"), &VideoPlayer::set_stream);
ClassDB::bind_method(D_METHOD("get_stream"), &VideoPlayer::get_stream);
@@ -485,7 +463,6 @@ void VideoPlayer::_bind_methods() {
}
VideoPlayer::VideoPlayer() {
-
volume = 1;
loops = false;
paused = false;
@@ -506,7 +483,6 @@ VideoPlayer::VideoPlayer() {
};
VideoPlayer::~VideoPlayer() {
-
// if (stream_rid.is_valid())
// AudioServer::get_singleton()->free(stream_rid);
resampler.clear(); //Not necessary here, but make in consistent with other "stream_player" classes
diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h
index 78e7fa05f8..551c079b3c 100644
--- a/scene/gui/video_player.h
+++ b/scene/gui/video_player.h
@@ -37,11 +37,9 @@
#include "servers/audio_server.h"
class VideoPlayer : public Control {
-
GDCLASS(VideoPlayer, Control);
struct Output {
-
AudioFrame vol;
int bus_index;
Viewport *viewport; //pointer only used for reference to previous mix
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index 2eacad68c3..524ff346d1 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -30,7 +30,7 @@
#include "canvas_item.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/message_queue.h"
#include "core/method_bind_ext.gen.inc"
#include "scene/main/canvas_layer.h"
@@ -48,7 +48,6 @@ Map<CanvasItemMaterial::MaterialKey, CanvasItemMaterial::ShaderData> CanvasItemM
CanvasItemMaterial::ShaderNames *CanvasItemMaterial::shader_names = nullptr;
void CanvasItemMaterial::init_shaders() {
-
dirty_materials = memnew(SelfList<CanvasItemMaterial>::List);
shader_names = memnew(ShaderNames);
@@ -59,19 +58,18 @@ void CanvasItemMaterial::init_shaders() {
}
void CanvasItemMaterial::finish_shaders() {
-
memdelete(dirty_materials);
memdelete(shader_names);
dirty_materials = nullptr;
}
void CanvasItemMaterial::_update_shader() {
-
dirty_materials->remove(&element);
MaterialKey mk = _compute_key();
- if (mk.key == current_key.key)
+ if (mk.key == current_key.key) {
return; //no update required in the end
+ }
if (shader_map.has(current_key)) {
shader_map[current_key].users--;
@@ -85,7 +83,6 @@ void CanvasItemMaterial::_update_shader() {
current_key = mk;
if (shader_map.has(mk)) {
-
RS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader);
shader_map[mk].users++;
return;
@@ -95,24 +92,40 @@ void CanvasItemMaterial::_update_shader() {
String code = "shader_type canvas_item;\nrender_mode ";
switch (blend_mode) {
- case BLEND_MODE_MIX: code += "blend_mix"; break;
- case BLEND_MODE_ADD: code += "blend_add"; break;
- case BLEND_MODE_SUB: code += "blend_sub"; break;
- case BLEND_MODE_MUL: code += "blend_mul"; break;
- case BLEND_MODE_PREMULT_ALPHA: code += "blend_premul_alpha"; break;
- case BLEND_MODE_DISABLED: code += "blend_disabled"; break;
+ case BLEND_MODE_MIX:
+ code += "blend_mix";
+ break;
+ case BLEND_MODE_ADD:
+ code += "blend_add";
+ break;
+ case BLEND_MODE_SUB:
+ code += "blend_sub";
+ break;
+ case BLEND_MODE_MUL:
+ code += "blend_mul";
+ break;
+ case BLEND_MODE_PREMULT_ALPHA:
+ code += "blend_premul_alpha";
+ break;
+ case BLEND_MODE_DISABLED:
+ code += "blend_disabled";
+ break;
}
switch (light_mode) {
- case LIGHT_MODE_NORMAL: break;
- case LIGHT_MODE_UNSHADED: code += ",unshaded"; break;
- case LIGHT_MODE_LIGHT_ONLY: code += ",light_only"; break;
+ case LIGHT_MODE_NORMAL:
+ break;
+ case LIGHT_MODE_UNSHADED:
+ code += ",unshaded";
+ break;
+ case LIGHT_MODE_LIGHT_ONLY:
+ code += ",light_only";
+ break;
}
code += ";\n";
if (particles_animation) {
-
code += "uniform int particles_anim_h_frames;\n";
code += "uniform int particles_anim_v_frames;\n";
code += "uniform bool particles_anim_loop;\n";
@@ -148,17 +161,14 @@ void CanvasItemMaterial::_update_shader() {
}
void CanvasItemMaterial::flush_changes() {
-
MutexLock lock(material_mutex);
while (dirty_materials->first()) {
-
dirty_materials->first()->self()->_update_shader();
}
}
void CanvasItemMaterial::_queue_shader_change() {
-
MutexLock lock(material_mutex);
if (!element.in_list()) {
@@ -167,13 +177,12 @@ void CanvasItemMaterial::_queue_shader_change() {
}
bool CanvasItemMaterial::_is_shader_dirty() const {
-
MutexLock lock(material_mutex);
return element.in_list();
}
-void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) {
+void CanvasItemMaterial::set_blend_mode(BlendMode p_blend_mode) {
blend_mode = p_blend_mode;
_queue_shader_change();
}
@@ -183,13 +192,11 @@ CanvasItemMaterial::BlendMode CanvasItemMaterial::get_blend_mode() const {
}
void CanvasItemMaterial::set_light_mode(LightMode p_light_mode) {
-
light_mode = p_light_mode;
_queue_shader_change();
}
CanvasItemMaterial::LightMode CanvasItemMaterial::get_light_mode() const {
-
return light_mode;
}
@@ -204,34 +211,29 @@ bool CanvasItemMaterial::get_particles_animation() const {
}
void CanvasItemMaterial::set_particles_anim_h_frames(int p_frames) {
-
particles_anim_h_frames = p_frames;
RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames);
}
int CanvasItemMaterial::get_particles_anim_h_frames() const {
-
return particles_anim_h_frames;
}
-void CanvasItemMaterial::set_particles_anim_v_frames(int p_frames) {
+void CanvasItemMaterial::set_particles_anim_v_frames(int p_frames) {
particles_anim_v_frames = p_frames;
RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames);
}
int CanvasItemMaterial::get_particles_anim_v_frames() const {
-
return particles_anim_v_frames;
}
void CanvasItemMaterial::set_particles_anim_loop(bool p_loop) {
-
particles_anim_loop = p_loop;
RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop);
}
bool CanvasItemMaterial::get_particles_anim_loop() const {
-
return particles_anim_loop;
}
@@ -242,18 +244,15 @@ void CanvasItemMaterial::_validate_property(PropertyInfo &property) const {
}
RID CanvasItemMaterial::get_shader_rid() const {
-
ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
return shader_map[current_key].shader;
}
Shader::Mode CanvasItemMaterial::get_shader_mode() const {
-
return Shader::MODE_CANVAS_ITEM;
}
void CanvasItemMaterial::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_blend_mode", "blend_mode"), &CanvasItemMaterial::set_blend_mode);
ClassDB::bind_method(D_METHOD("get_blend_mode"), &CanvasItemMaterial::get_blend_mode);
@@ -293,7 +292,6 @@ void CanvasItemMaterial::_bind_methods() {
CanvasItemMaterial::CanvasItemMaterial() :
element(this) {
-
blend_mode = BLEND_MODE_MIX;
light_mode = LIGHT_MODE_NORMAL;
particles_animation = false;
@@ -308,7 +306,6 @@ CanvasItemMaterial::CanvasItemMaterial() :
}
CanvasItemMaterial::~CanvasItemMaterial() {
-
MutexLock lock(material_mutex);
if (shader_map.has(current_key)) {
@@ -339,15 +336,16 @@ Transform2D CanvasItem::_edit_get_transform() const {
#endif
bool CanvasItem::is_visible_in_tree() const {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return false;
+ }
const CanvasItem *p = this;
while (p) {
- if (!p->visible)
+ if (!p->visible) {
return false;
+ }
if (p->window && !p->window->is_visible()) {
return false;
}
@@ -358,54 +356,56 @@ bool CanvasItem::is_visible_in_tree() const {
}
void CanvasItem::_propagate_visibility_changed(bool p_visible) {
-
if (p_visible && first_draw) { //avoid propagating it twice
first_draw = false;
}
notification(NOTIFICATION_VISIBILITY_CHANGED);
- if (p_visible)
+ if (p_visible) {
update(); //todo optimize
- else
+ } else {
emit_signal(SceneStringNames::get_singleton()->hide);
+ }
_block();
for (int i = 0; i < get_child_count(); i++) {
-
CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i));
- if (c && c->visible) //should the toplevels stop propagation? i think so but..
+ if (c && c->visible) { //should the toplevels stop propagation? i think so but..
c->_propagate_visibility_changed(p_visible);
+ }
}
_unblock();
}
void CanvasItem::show() {
-
- if (visible)
+ if (visible) {
return;
+ }
visible = true;
RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, true);
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_propagate_visibility_changed(true);
_change_notify("visible");
}
void CanvasItem::hide() {
-
- if (!visible)
+ if (!visible) {
return;
+ }
visible = false;
RenderingServer::get_singleton()->canvas_item_set_visible(canvas_item, false);
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_propagate_visibility_changed(false);
_change_notify("visible");
@@ -417,7 +417,6 @@ CanvasItem *CanvasItem::get_current_item_drawn() {
}
void CanvasItem::_update_callback() {
-
if (!is_inside_tree()) {
pending_update = false;
return;
@@ -445,13 +444,13 @@ void CanvasItem::_update_callback() {
}
Transform2D CanvasItem::get_global_transform_with_canvas() const {
-
- if (canvas_layer)
+ if (canvas_layer) {
return canvas_layer->get_transform() * get_global_transform();
- else if (is_inside_tree())
+ } else if (is_inside_tree()) {
return get_viewport()->get_canvas_transform() * get_global_transform();
- else
+ } else {
return get_global_transform();
+ }
}
Transform2D CanvasItem::get_screen_transform() const {
@@ -474,12 +473,12 @@ Transform2D CanvasItem::get_global_transform() const {
ERR_FAIL_COND_V(!is_inside_tree(), get_transform());
#endif
if (global_invalid) {
-
const CanvasItem *pi = get_parent_item();
- if (pi)
+ if (pi) {
global_transform = pi->get_global_transform() * get_transform();
- else
+ } else {
global_transform = get_transform();
+ }
global_invalid = false;
}
@@ -488,26 +487,24 @@ Transform2D CanvasItem::get_global_transform() const {
}
void CanvasItem::_toplevel_raise_self() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
- if (canvas_layer)
+ if (canvas_layer) {
RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, canvas_layer->get_sort_index());
- else
+ } else {
RenderingServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_viewport()->gui_get_canvas_sort_index());
+ }
}
void CanvasItem::_enter_canvas() {
-
if ((!Object::cast_to<CanvasItem>(get_parent())) || toplevel) {
-
Node *n = this;
canvas_layer = nullptr;
while (n) {
-
canvas_layer = Object::cast_to<CanvasLayer>(n);
if (canvas_layer) {
break;
@@ -519,25 +516,26 @@ void CanvasItem::_enter_canvas() {
}
RID canvas;
- if (canvas_layer)
+ if (canvas_layer) {
canvas = canvas_layer->get_canvas();
- else
+ } else {
canvas = get_viewport()->find_world_2d()->get_canvas();
+ }
RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, canvas);
group = "root_canvas" + itos(canvas.get_id());
add_to_group(group);
- if (canvas_layer)
+ if (canvas_layer) {
canvas_layer->reset_sort_index();
- else
+ } else {
get_viewport()->gui_reset_canvas_sort_index();
+ }
get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE, group, "_toplevel_raise_self");
} else {
-
CanvasItem *parent = get_parent_item();
canvas_layer = parent->canvas_layer;
RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, parent->get_canvas_item());
@@ -551,7 +549,6 @@ void CanvasItem::_enter_canvas() {
}
void CanvasItem::_exit_canvas() {
-
notification(NOTIFICATION_EXIT_CANVAS, true); //reverse the notification
RenderingServer::get_singleton()->canvas_item_set_parent(canvas_item, RID());
canvas_layer = nullptr;
@@ -559,10 +556,8 @@ void CanvasItem::_exit_canvas() {
}
void CanvasItem::_notification(int p_what) {
-
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
-
_update_texture_filter_changed(false);
_update_texture_repeat_changed(false);
@@ -570,8 +565,9 @@ void CanvasItem::_notification(int p_what) {
Node *parent = get_parent();
if (parent) {
CanvasItem *ci = Object::cast_to<CanvasItem>(parent);
- if (ci)
+ if (ci) {
C = ci->children_items.push_back(this);
+ }
if (!ci) {
//look for a window
Viewport *viewport = nullptr;
@@ -598,9 +594,9 @@ void CanvasItem::_notification(int p_what) {
}
} break;
case NOTIFICATION_MOVED_IN_PARENT: {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
break;
+ }
if (group != "") {
get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE, group, "_toplevel_raise_self");
@@ -612,8 +608,9 @@ void CanvasItem::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
- if (xform_change.in_list())
+ if (xform_change.in_list()) {
get_tree()->xform_change_list.remove(&xform_change);
+ }
_exit_canvas();
if (C) {
Object::cast_to<CanvasItem>(get_parent())->children_items.erase(C);
@@ -626,41 +623,38 @@ void CanvasItem::_notification(int p_what) {
} break;
case NOTIFICATION_DRAW:
case NOTIFICATION_TRANSFORM_CHANGED: {
-
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
-
emit_signal(SceneStringNames::get_singleton()->visibility_changed);
} break;
}
}
void CanvasItem::set_visible(bool p_visible) {
-
- if (p_visible)
+ if (p_visible) {
show();
- else
+ } else {
hide();
+ }
}
void CanvasItem::_window_visibility_changed() {
-
if (visible) {
_propagate_visibility_changed(window->is_visible());
}
}
bool CanvasItem::is_visible() const {
-
return visible;
}
void CanvasItem::update() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
- if (pending_update)
+ }
+ if (pending_update) {
return;
+ }
pending_update = true;
@@ -668,22 +662,22 @@ void CanvasItem::update() {
}
void CanvasItem::set_modulate(const Color &p_modulate) {
-
- if (modulate == p_modulate)
+ if (modulate == p_modulate) {
return;
+ }
modulate = p_modulate;
RenderingServer::get_singleton()->canvas_item_set_modulate(canvas_item, modulate);
}
-Color CanvasItem::get_modulate() const {
+Color CanvasItem::get_modulate() const {
return modulate;
}
void CanvasItem::set_as_toplevel(bool p_toplevel) {
-
- if (toplevel == p_toplevel)
+ if (toplevel == p_toplevel) {
return;
+ }
if (!is_inside_tree()) {
toplevel = p_toplevel;
@@ -696,61 +690,57 @@ void CanvasItem::set_as_toplevel(bool p_toplevel) {
}
bool CanvasItem::is_set_as_toplevel() const {
-
return toplevel;
}
CanvasItem *CanvasItem::get_parent_item() const {
-
- if (toplevel)
+ if (toplevel) {
return nullptr;
+ }
return Object::cast_to<CanvasItem>(get_parent());
}
void CanvasItem::set_self_modulate(const Color &p_self_modulate) {
-
- if (self_modulate == p_self_modulate)
+ if (self_modulate == p_self_modulate) {
return;
+ }
self_modulate = p_self_modulate;
RenderingServer::get_singleton()->canvas_item_set_self_modulate(canvas_item, self_modulate);
}
-Color CanvasItem::get_self_modulate() const {
+Color CanvasItem::get_self_modulate() const {
return self_modulate;
}
void CanvasItem::set_light_mask(int p_light_mask) {
-
- if (light_mask == p_light_mask)
+ if (light_mask == p_light_mask) {
return;
+ }
light_mask = p_light_mask;
RS::get_singleton()->canvas_item_set_light_mask(canvas_item, p_light_mask);
}
int CanvasItem::get_light_mask() const {
-
return light_mask;
}
void CanvasItem::item_rect_changed(bool p_size_changed) {
-
- if (p_size_changed)
+ if (p_size_changed) {
update();
+ }
emit_signal(SceneStringNames::get_singleton()->item_rect_changed);
}
void CanvasItem::draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RenderingServer::get_singleton()->canvas_item_add_line(canvas_item, p_from, p_to, p_color, p_width);
}
void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_color, float p_width) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
@@ -759,14 +749,12 @@ void CanvasItem::draw_polyline(const Vector<Point2> &p_points, const Color &p_co
}
void CanvasItem::draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RenderingServer::get_singleton()->canvas_item_add_polyline(canvas_item, p_points, p_colors, p_width);
}
void CanvasItem::draw_arc(const Vector2 &p_center, float p_radius, float p_start_angle, float p_end_angle, int p_point_count, const Color &p_color, float p_width) {
-
Vector<Point2> points;
points.resize(p_point_count);
const float delta_angle = p_end_angle - p_start_angle;
@@ -779,7 +767,6 @@ void CanvasItem::draw_arc(const Vector2 &p_center, float p_radius, float p_start
}
void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
@@ -788,14 +775,12 @@ void CanvasItem::draw_multiline(const Vector<Point2> &p_points, const Color &p_c
}
void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RenderingServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width);
}
void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, float p_width) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
if (p_filled) {
@@ -842,14 +827,12 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil
}
void CanvasItem::draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RenderingServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color);
}
void CanvasItem::draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_pos, const Color &p_modulate, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
@@ -858,14 +841,13 @@ void CanvasItem::draw_texture(const Ref<Texture2D> &p_texture, const Point2 &p_p
}
void CanvasItem::draw_texture_rect(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, RS::CanvasItemTextureFilter(p_texture_filter), RS::CanvasItemTextureRepeat(p_texture_repeat));
}
-void CanvasItem::draw_texture_rect_region(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, bool p_clip_uv, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
+void CanvasItem::draw_texture_rect_region(const Ref<Texture2D> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, bool p_clip_uv, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_texture.is_null());
p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, RS::CanvasItemTextureFilter(p_texture_filter), RS::CanvasItemTextureRepeat(p_texture_repeat), p_clip_uv);
@@ -878,8 +860,8 @@ void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p
p_style_box->draw(canvas_item, p_rect);
}
-void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, float p_width, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
+void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, float p_width, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
@@ -888,8 +870,8 @@ void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Col
RenderingServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width, rid_normal, rid_specular, p_specular_color_shininess, RS::CanvasItemTextureFilter(p_texture_filter), RS::CanvasItemTextureRepeat(p_texture_repeat));
}
-void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale) {
+void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale) {
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Transform2D xform(p_rot, p_offset);
@@ -898,14 +880,12 @@ void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const S
}
void CanvasItem::draw_set_transform_matrix(const Transform2D &p_matrix) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RenderingServer::get_singleton()->canvas_item_add_set_transform(canvas_item, p_matrix);
}
void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
@@ -916,7 +896,6 @@ void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color
}
void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
Vector<Color> colors;
@@ -929,7 +908,6 @@ void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Colo
}
void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, const Transform2D &p_transform, const Color &p_modulate, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
-
ERR_FAIL_COND(p_mesh.is_null());
RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
@@ -937,8 +915,8 @@ void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture2D> &p_text
RenderingServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), p_transform, p_modulate, texture_rid, normal_map_rid, specular_map_rid, p_specular_color_shininess, RS::CanvasItemTextureFilter(p_texture_filter), RS::CanvasItemTextureRepeat(p_texture_repeat));
}
-void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
+void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture2D> &p_texture, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, TextureFilter p_texture_filter, TextureRepeat p_texture_repeat) {
ERR_FAIL_COND(p_multimesh.is_null());
RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
@@ -948,7 +926,6 @@ void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Tex
}
void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w) {
-
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND(p_font.is_null());
@@ -956,7 +933,6 @@ void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const
}
float CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next, const Color &p_modulate) {
-
ERR_FAIL_COND_V_MSG(!drawing, 0, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL_COND_V(p_char.length() != 1, 0);
@@ -969,7 +945,6 @@ float CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const
}
void CanvasItem::_notify_transform(CanvasItem *p_node) {
-
/* This check exists to avoid re-propagating the transform
* notification down the tree on dirty nodes. It provides
* optimization by avoiding redundancy (nodes are dirty, will get the
@@ -984,38 +959,37 @@ void CanvasItem::_notify_transform(CanvasItem *p_node) {
if (p_node->notify_transform && !p_node->xform_change.in_list()) {
if (!p_node->block_transform_notify) {
- if (p_node->is_inside_tree())
+ if (p_node->is_inside_tree()) {
get_tree()->xform_change_list.add(&p_node->xform_change);
+ }
}
}
for (List<CanvasItem *>::Element *E = p_node->children_items.front(); E; E = E->next()) {
-
CanvasItem *ci = E->get();
- if (ci->toplevel)
+ if (ci->toplevel) {
continue;
+ }
_notify_transform(ci);
}
}
Rect2 CanvasItem::get_viewport_rect() const {
-
ERR_FAIL_COND_V(!is_inside_tree(), Rect2());
return get_viewport()->get_visible_rect();
}
RID CanvasItem::get_canvas() const {
-
ERR_FAIL_COND_V(!is_inside_tree(), RID());
- if (canvas_layer)
+ if (canvas_layer) {
return canvas_layer->get_canvas();
- else
+ } else {
return get_viewport()->find_world_2d()->get_canvas();
+ }
}
ObjectID CanvasItem::get_canvas_layer_instance_id() const {
-
if (canvas_layer) {
return canvas_layer->get_instance_id();
} else {
@@ -1024,7 +998,6 @@ ObjectID CanvasItem::get_canvas_layer_instance_id() const {
}
CanvasItem *CanvasItem::get_toplevel() const {
-
CanvasItem *ci = const_cast<CanvasItem *>(this);
while (!ci->toplevel && Object::cast_to<CanvasItem>(ci->get_parent())) {
ci = Object::cast_to<CanvasItem>(ci->get_parent());
@@ -1034,7 +1007,6 @@ CanvasItem *CanvasItem::get_toplevel() const {
}
Ref<World2D> CanvasItem::get_world_2d() const {
-
ERR_FAIL_COND_V(!is_inside_tree(), Ref<World2D>());
CanvasItem *tl = get_toplevel();
@@ -1047,7 +1019,6 @@ Ref<World2D> CanvasItem::get_world_2d() const {
}
RID CanvasItem::get_viewport_rid() const {
-
ERR_FAIL_COND_V(!is_inside_tree(), RID());
return get_viewport()->get_viewport_rid();
}
@@ -1057,51 +1028,45 @@ void CanvasItem::set_block_transform_notify(bool p_enable) {
}
bool CanvasItem::is_block_transform_notify_enabled() const {
-
return block_transform_notify;
}
void CanvasItem::set_draw_behind_parent(bool p_enable) {
-
- if (behind == p_enable)
+ if (behind == p_enable) {
return;
+ }
behind = p_enable;
RenderingServer::get_singleton()->canvas_item_set_draw_behind_parent(canvas_item, behind);
}
bool CanvasItem::is_draw_behind_parent_enabled() const {
-
return behind;
}
void CanvasItem::set_material(const Ref<Material> &p_material) {
-
material = p_material;
RID rid;
- if (material.is_valid())
+ if (material.is_valid()) {
rid = material->get_rid();
+ }
RS::get_singleton()->canvas_item_set_material(canvas_item, rid);
_change_notify(); //properties for material exposed
}
void CanvasItem::set_use_parent_material(bool p_use_parent_material) {
-
use_parent_material = p_use_parent_material;
RS::get_singleton()->canvas_item_set_use_parent_material(canvas_item, p_use_parent_material);
}
bool CanvasItem::get_use_parent_material() const {
-
return use_parent_material;
}
Ref<Material> CanvasItem::get_material() const {
-
return material;
}
Vector2 CanvasItem::make_canvas_position_local(const Vector2 &screen_point) const {
-
ERR_FAIL_COND_V(!is_inside_tree(), screen_point);
Transform2D local_matrix = (get_canvas_transform() * get_global_transform()).affine_inverse();
@@ -1110,7 +1075,6 @@ Vector2 CanvasItem::make_canvas_position_local(const Vector2 &screen_point) cons
}
Ref<InputEvent> CanvasItem::make_input_local(const Ref<InputEvent> &p_event) const {
-
ERR_FAIL_COND_V(p_event.is_null(), p_event);
ERR_FAIL_COND_V(!is_inside_tree(), p_event);
@@ -1118,13 +1082,11 @@ Ref<InputEvent> CanvasItem::make_input_local(const Ref<InputEvent> &p_event) con
}
Vector2 CanvasItem::get_global_mouse_position() const {
-
ERR_FAIL_COND_V(!get_viewport(), Vector2());
return get_canvas_transform().affine_inverse().xform(get_viewport()->get_mouse_position());
}
Vector2 CanvasItem::get_local_mouse_position() const {
-
ERR_FAIL_COND_V(!get_viewport(), Vector2());
return get_global_transform().affine_inverse().xform(get_global_mouse_position());
@@ -1142,7 +1104,6 @@ void CanvasItem::force_update_transform() {
}
void CanvasItem::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_toplevel_raise_self"), &CanvasItem::_toplevel_raise_self);
ClassDB::bind_method(D_METHOD("_update_callback"), &CanvasItem::_update_callback);
@@ -1299,23 +1260,21 @@ void CanvasItem::_bind_methods() {
}
Transform2D CanvasItem::get_canvas_transform() const {
-
ERR_FAIL_COND_V(!is_inside_tree(), Transform2D());
- if (canvas_layer)
+ if (canvas_layer) {
return canvas_layer->get_transform();
- else if (Object::cast_to<CanvasItem>(get_parent()))
+ } else if (Object::cast_to<CanvasItem>(get_parent())) {
return Object::cast_to<CanvasItem>(get_parent())->get_canvas_transform();
- else
+ } else {
return get_viewport()->get_canvas_transform();
+ }
}
Transform2D CanvasItem::get_viewport_transform() const {
-
ERR_FAIL_COND_V(!is_inside_tree(), Transform2D());
if (canvas_layer) {
-
if (get_viewport()) {
return get_viewport()->get_final_transform() * canvas_layer->get_transform();
} else {
@@ -1336,8 +1295,9 @@ bool CanvasItem::is_local_transform_notification_enabled() const {
}
void CanvasItem::set_notify_transform(bool p_enable) {
- if (notify_transform == p_enable)
+ if (notify_transform == p_enable) {
return;
+ }
notify_transform = p_enable;
@@ -1352,15 +1312,14 @@ bool CanvasItem::is_transform_notification_enabled() const {
}
int CanvasItem::get_canvas_layer() const {
-
- if (canvas_layer)
+ if (canvas_layer) {
return canvas_layer->get_layer();
- else
+ } else {
return 0;
+ }
}
void CanvasItem::_update_texture_filter_changed(bool p_propagate) {
-
if (!is_inside_tree()) {
return;
}
@@ -1372,10 +1331,18 @@ void CanvasItem::_update_texture_filter_changed(bool p_propagate) {
} else {
//from viewport
switch (get_viewport()->get_default_canvas_item_texture_filter()) {
- case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST: texture_filter_cache = RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST; break;
- case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR: texture_filter_cache = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR; break;
- case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: texture_filter_cache = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS; break;
- case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: texture_filter_cache = RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS; break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST:
+ texture_filter_cache = RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST;
+ break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR:
+ texture_filter_cache = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR;
+ break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS:
+ texture_filter_cache = RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS;
+ break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS:
+ texture_filter_cache = RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS;
+ break;
default: {
}
}
@@ -1409,7 +1376,6 @@ CanvasItem::TextureFilter CanvasItem::get_texture_filter() const {
}
void CanvasItem::_update_texture_repeat_changed(bool p_propagate) {
-
if (!is_inside_tree()) {
return;
}
@@ -1421,9 +1387,15 @@ void CanvasItem::_update_texture_repeat_changed(bool p_propagate) {
} else {
//from viewport
switch (get_viewport()->get_default_canvas_item_texture_repeat()) {
- case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED: texture_repeat_cache = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED; break;
- case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED: texture_repeat_cache = RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED; break;
- case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR: texture_repeat_cache = RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR; break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED:
+ texture_repeat_cache = RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED;
+ break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED:
+ texture_repeat_cache = RS::CANVAS_ITEM_TEXTURE_REPEAT_ENABLED;
+ break;
+ case Viewport::DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR:
+ texture_repeat_cache = RS::CANVAS_ITEM_TEXTURE_REPEAT_MIRROR;
+ break;
default: {
}
}
@@ -1457,7 +1429,6 @@ CanvasItem::TextureRepeat CanvasItem::get_texture_repeat() const {
CanvasItem::CanvasItem() :
xform_change(this) {
-
window = nullptr;
canvas_item = RenderingServer::get_singleton()->canvas_item_create();
visible = true;
@@ -1484,6 +1455,5 @@ CanvasItem::CanvasItem() :
}
CanvasItem::~CanvasItem() {
-
RenderingServer::get_singleton()->free(canvas_item);
}
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index dc17c5283b..31edd424a1 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -45,7 +45,6 @@ class Font;
class StyleBox;
class CanvasItemMaterial : public Material {
-
GDCLASS(CanvasItemMaterial, Material);
public:
@@ -66,7 +65,6 @@ public:
private:
union MaterialKey {
-
struct {
uint32_t blend_mode : 4;
uint32_t light_mode : 4;
@@ -99,7 +97,6 @@ private:
MaterialKey current_key;
_FORCE_INLINE_ MaterialKey _compute_key() const {
-
MaterialKey mk;
mk.key = 0;
mk.blend_mode = blend_mode;
@@ -162,7 +159,6 @@ VARIANT_ENUM_CAST(CanvasItemMaterial::BlendMode)
VARIANT_ENUM_CAST(CanvasItemMaterial::LightMode)
class CanvasItem : public Node {
-
GDCLASS(CanvasItem, Node);
public:
@@ -247,9 +243,13 @@ private:
protected:
_FORCE_INLINE_ void _notify_transform() {
- if (!is_inside_tree()) return;
+ if (!is_inside_tree()) {
+ return;
+ }
_notify_transform(this);
- if (!block_transform_notify && notify_local_transform) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
+ if (!block_transform_notify && notify_local_transform) {
+ notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED);
+ }
}
void item_rect_changed(bool p_size_changed = true);
@@ -275,7 +275,7 @@ public:
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
// Save and restore a CanvasItem state
- virtual void _edit_set_state(const Dictionary &p_state){};
+ virtual void _edit_set_state(const Dictionary &p_state) {}
virtual Dictionary _edit_get_state() const { return Dictionary(); };
// Used to move the node
@@ -288,18 +288,18 @@ public:
// Used to rotate the node
virtual bool _edit_use_rotation() const { return false; };
- virtual void _edit_set_rotation(float p_rotation){};
+ virtual void _edit_set_rotation(float p_rotation) {}
virtual float _edit_get_rotation() const { return 0.0; };
// Used to resize/move the node
virtual bool _edit_use_rect() const { return false; }; // MAYBE REPLACE BY A _edit_get_editmode()
- virtual void _edit_set_rect(const Rect2 &p_rect){};
+ virtual void _edit_set_rect(const Rect2 &p_rect) {}
virtual Rect2 _edit_get_rect() const { return Rect2(0, 0, 0, 0); };
virtual Size2 _edit_get_minimum_size() const { return Size2(-1, -1); }; // LOOKS WEIRD
// Used to set a pivot
virtual bool _edit_use_pivot() const { return false; };
- virtual void _edit_set_pivot(const Point2 &p_pivot){};
+ virtual void _edit_set_pivot(const Point2 &p_pivot) {}
virtual Point2 _edit_get_pivot() const { return Point2(); };
virtual Transform2D _edit_get_transform() const;
diff --git a/scene/main/canvas_layer.cpp b/scene/main/canvas_layer.cpp
index c1caa943e3..46cfb968f8 100644
--- a/scene/main/canvas_layer.cpp
+++ b/scene/main/canvas_layer.cpp
@@ -32,40 +32,37 @@
#include "viewport.h"
void CanvasLayer::set_layer(int p_xform) {
-
layer = p_xform;
- if (viewport.is_valid())
+ if (viewport.is_valid()) {
RenderingServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_index());
+ }
}
int CanvasLayer::get_layer() const {
-
return layer;
}
void CanvasLayer::set_transform(const Transform2D &p_xform) {
-
transform = p_xform;
locrotscale_dirty = true;
- if (viewport.is_valid())
+ if (viewport.is_valid()) {
RenderingServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
+ }
}
Transform2D CanvasLayer::get_transform() const {
-
return transform;
}
void CanvasLayer::_update_xform() {
-
transform.set_rotation_and_scale(rot, scale);
transform.set_origin(ofs);
- if (viewport.is_valid())
+ if (viewport.is_valid()) {
RenderingServer::get_singleton()->viewport_set_canvas_transform(viewport, canvas, transform);
+ }
}
void CanvasLayer::_update_locrotscale() {
-
ofs = transform.elements[2];
rot = transform.get_rotation();
scale = transform.get_scale();
@@ -73,74 +70,68 @@ void CanvasLayer::_update_locrotscale() {
}
void CanvasLayer::set_offset(const Vector2 &p_offset) {
-
- if (locrotscale_dirty)
+ if (locrotscale_dirty) {
_update_locrotscale();
+ }
ofs = p_offset;
_update_xform();
}
Vector2 CanvasLayer::get_offset() const {
-
- if (locrotscale_dirty)
+ if (locrotscale_dirty) {
const_cast<CanvasLayer *>(this)->_update_locrotscale();
+ }
return ofs;
}
void CanvasLayer::set_rotation(real_t p_radians) {
-
- if (locrotscale_dirty)
+ if (locrotscale_dirty) {
_update_locrotscale();
+ }
rot = p_radians;
_update_xform();
}
real_t CanvasLayer::get_rotation() const {
-
- if (locrotscale_dirty)
+ if (locrotscale_dirty) {
const_cast<CanvasLayer *>(this)->_update_locrotscale();
+ }
return rot;
}
void CanvasLayer::set_rotation_degrees(real_t p_degrees) {
-
set_rotation(Math::deg2rad(p_degrees));
}
real_t CanvasLayer::get_rotation_degrees() const {
-
return Math::rad2deg(get_rotation());
}
void CanvasLayer::set_scale(const Vector2 &p_scale) {
-
- if (locrotscale_dirty)
+ if (locrotscale_dirty) {
_update_locrotscale();
+ }
scale = p_scale;
_update_xform();
}
Vector2 CanvasLayer::get_scale() const {
-
- if (locrotscale_dirty)
+ if (locrotscale_dirty) {
const_cast<CanvasLayer *>(this)->_update_locrotscale();
+ }
return scale;
}
void CanvasLayer::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
if (custom_viewport && ObjectDB::get_instance(custom_viewport_id)) {
-
vp = custom_viewport;
} else {
vp = Node::get_viewport();
@@ -157,7 +148,6 @@ void CanvasLayer::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
-
vp->_canvas_layer_remove(this);
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, canvas);
viewport = RID();
@@ -165,25 +155,24 @@ void CanvasLayer::_notification(int p_what) {
} break;
case NOTIFICATION_MOVED_IN_PARENT: {
-
- if (is_inside_tree())
+ if (is_inside_tree()) {
RenderingServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_index());
+ }
} break;
}
}
Size2 CanvasLayer::get_viewport_size() const {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return Size2(1, 1);
+ }
Rect2 r = vp->get_visible_rect();
return r.size;
}
RID CanvasLayer::get_viewport() const {
-
return viewport;
}
@@ -204,11 +193,11 @@ void CanvasLayer::set_custom_viewport(Node *p_viewport) {
}
if (is_inside_tree()) {
-
- if (custom_viewport)
+ if (custom_viewport) {
vp = custom_viewport;
- else
+ } else {
vp = Node::get_viewport();
+ }
vp->_canvas_layer_add(this);
viewport = vp->get_viewport_rid();
@@ -220,7 +209,6 @@ void CanvasLayer::set_custom_viewport(Node *p_viewport) {
}
Node *CanvasLayer::get_custom_viewport() const {
-
return custom_viewport;
}
@@ -229,12 +217,10 @@ void CanvasLayer::reset_sort_index() {
}
int CanvasLayer::get_sort_index() {
-
return sort_index++;
}
RID CanvasLayer::get_canvas() const {
-
return canvas;
}
@@ -261,7 +247,6 @@ float CanvasLayer::get_follow_viewport_scale() const {
}
void CanvasLayer::_update_follow_viewport(bool p_force_exit) {
-
if (!is_inside_tree()) {
return;
}
@@ -273,7 +258,6 @@ void CanvasLayer::_update_follow_viewport(bool p_force_exit) {
}
void CanvasLayer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_layer", "layer"), &CanvasLayer::set_layer);
ClassDB::bind_method(D_METHOD("get_layer"), &CanvasLayer::get_layer);
@@ -319,7 +303,6 @@ void CanvasLayer::_bind_methods() {
}
CanvasLayer::CanvasLayer() {
-
vp = nullptr;
scale = Vector2(1, 1);
rot = 0;
@@ -334,6 +317,5 @@ CanvasLayer::CanvasLayer() {
}
CanvasLayer::~CanvasLayer() {
-
RS::get_singleton()->free(canvas);
}
diff --git a/scene/main/canvas_layer.h b/scene/main/canvas_layer.h
index 91ddbca3b9..0c68b1ab69 100644
--- a/scene/main/canvas_layer.h
+++ b/scene/main/canvas_layer.h
@@ -36,7 +36,6 @@
class Viewport;
class CanvasLayer : public Node {
-
GDCLASS(CanvasLayer, Node);
bool locrotscale_dirty;
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index dc0da015ac..82ee4dde50 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -34,12 +34,10 @@ void HTTPRequest::_redirect_request(const String &p_new_url) {
}
Error HTTPRequest::_request() {
-
return client->connect_to_host(url, port, use_ssl, validate_ssl);
}
Error HTTPRequest::_parse_url(const String &p_url) {
-
url = p_url;
use_ssl = false;
@@ -85,7 +83,6 @@ Error HTTPRequest::_parse_url(const String &p_url) {
}
Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_headers, bool p_ssl_validate_domain, HTTPClient::Method p_method, const String &p_request_data) {
-
ERR_FAIL_COND_V(!is_inside_tree(), ERR_UNCONFIGURED);
ERR_FAIL_COND_V_MSG(requesting, ERR_BUSY, "HTTPRequest is processing a request. Wait for completion or cancel it before attempting a new one.");
@@ -97,8 +94,9 @@ Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_h
method = p_method;
Error err = _parse_url(p_url);
- if (err)
+ if (err) {
return err;
+ }
validate_ssl = p_ssl_validate_domain;
@@ -109,7 +107,6 @@ Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_h
requesting = true;
if (use_threads) {
-
thread_done = false;
thread_request_quit = false;
client->set_blocking_mode(true);
@@ -129,7 +126,6 @@ Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_h
}
void HTTPRequest::_thread_func(void *p_userdata) {
-
HTTPRequest *hr = (HTTPRequest *)p_userdata;
Error err = hr->_request();
@@ -138,10 +134,10 @@ void HTTPRequest::_thread_func(void *p_userdata) {
hr->call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
} else {
while (!hr->thread_request_quit) {
-
bool exit = hr->_update_connection();
- if (exit)
+ if (exit) {
break;
+ }
OS::get_singleton()->delay_usec(1);
}
}
@@ -150,11 +146,11 @@ void HTTPRequest::_thread_func(void *p_userdata) {
}
void HTTPRequest::cancel_request() {
-
timer->stop();
- if (!requesting)
+ if (!requesting) {
return;
+ }
if (!use_threads) {
set_process_internal(false);
@@ -178,7 +174,6 @@ void HTTPRequest::cancel_request() {
}
bool HTTPRequest::_handle_response(bool *ret_value) {
-
if (!client->has_response()) {
call_deferred("_request_done", RESULT_NO_RESPONSE, 0, PackedStringArray(), PackedByteArray());
*ret_value = true;
@@ -199,7 +194,6 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
// Handle redirect
if (max_redirects >= 0 && redirections >= max_redirects) {
-
call_deferred("_request_done", RESULT_REDIRECT_LIMIT_REACHED, response_code, response_headers, PackedByteArray());
*ret_value = true;
return true;
@@ -243,7 +237,6 @@ bool HTTPRequest::_handle_response(bool *ret_value) {
}
bool HTTPRequest::_update_connection() {
-
switch (client->get_status()) {
case HTTPClient::STATUS_DISCONNECTED: {
call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
@@ -265,23 +258,20 @@ bool HTTPRequest::_update_connection() {
return false;
} break; // Connecting to IP
case HTTPClient::STATUS_CANT_CONNECT: {
-
call_deferred("_request_done", RESULT_CANT_CONNECT, 0, PackedStringArray(), PackedByteArray());
return true;
} break;
case HTTPClient::STATUS_CONNECTED: {
-
if (request_sent) {
-
if (!got_response) {
-
// No body
bool ret_value;
- if (_handle_response(&ret_value))
+ if (_handle_response(&ret_value)) {
return ret_value;
+ }
call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, PackedByteArray());
return true;
@@ -315,16 +305,14 @@ bool HTTPRequest::_update_connection() {
} break; // Request in progress
case HTTPClient::STATUS_BODY: {
-
if (!got_response) {
-
bool ret_value;
- if (_handle_response(&ret_value))
+ if (_handle_response(&ret_value)) {
return ret_value;
+ }
if (!client->is_response_chunked() && client->get_response_body_length() == 0) {
-
call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, PackedByteArray());
return true;
}
@@ -341,7 +329,6 @@ bool HTTPRequest::_update_connection() {
if (download_to_file != String()) {
file = FileAccess::open(download_to_file, FileAccess::WRITE);
if (!file) {
-
call_deferred("_request_done", RESULT_DOWNLOAD_FILE_CANT_OPEN, response_code, response_headers, PackedByteArray());
return true;
}
@@ -370,7 +357,6 @@ bool HTTPRequest::_update_connection() {
}
if (body_len >= 0) {
-
if (downloaded == body_len) {
call_deferred("_request_done", RESULT_SUCCESS, response_code, response_headers, body);
return true;
@@ -397,20 +383,17 @@ bool HTTPRequest::_update_connection() {
}
void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArray &headers, const PackedByteArray &p_data) {
-
cancel_request();
emit_signal("request_completed", p_status, p_code, headers, p_data);
}
void HTTPRequest::_notification(int p_what) {
-
if (p_what == NOTIFICATION_INTERNAL_PROCESS) {
-
- if (use_threads)
+ if (use_threads) {
return;
+ }
bool done = _update_connection();
if (done) {
-
set_process_internal(false);
// cancel_request(); called from _request done now
}
@@ -424,42 +407,35 @@ void HTTPRequest::_notification(int p_what) {
}
void HTTPRequest::set_use_threads(bool p_use) {
-
ERR_FAIL_COND(get_http_client_status() != HTTPClient::STATUS_DISCONNECTED);
use_threads = p_use;
}
bool HTTPRequest::is_using_threads() const {
-
return use_threads;
}
void HTTPRequest::set_body_size_limit(int p_bytes) {
-
ERR_FAIL_COND(get_http_client_status() != HTTPClient::STATUS_DISCONNECTED);
body_size_limit = p_bytes;
}
int HTTPRequest::get_body_size_limit() const {
-
return body_size_limit;
}
void HTTPRequest::set_download_file(const String &p_file) {
-
ERR_FAIL_COND(get_http_client_status() != HTTPClient::STATUS_DISCONNECTED);
download_to_file = p_file;
}
String HTTPRequest::get_download_file() const {
-
return download_to_file;
}
void HTTPRequest::set_download_chunk_size(int p_chunk_size) {
-
ERR_FAIL_COND(get_http_client_status() != HTTPClient::STATUS_DISCONNECTED);
client->set_read_chunk_size(p_chunk_size);
@@ -474,42 +450,36 @@ HTTPClient::Status HTTPRequest::get_http_client_status() const {
}
void HTTPRequest::set_max_redirects(int p_max) {
-
max_redirects = p_max;
}
int HTTPRequest::get_max_redirects() const {
-
return max_redirects;
}
int HTTPRequest::get_downloaded_bytes() const {
-
return downloaded;
}
+
int HTTPRequest::get_body_size() const {
return body_len;
}
void HTTPRequest::set_timeout(int p_timeout) {
-
ERR_FAIL_COND(p_timeout < 0);
timeout = p_timeout;
}
int HTTPRequest::get_timeout() {
-
return timeout;
}
void HTTPRequest::_timeout() {
-
cancel_request();
call_deferred("_request_done", RESULT_TIMEOUT, 0, PackedStringArray(), PackedByteArray());
}
void HTTPRequest::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("request", "url", "custom_headers", "ssl_validate_domain", "method", "request_data"), &HTTPRequest::request, DEFVAL(PackedStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(String()));
ClassDB::bind_method(D_METHOD("cancel_request"), &HTTPRequest::cancel_request);
@@ -565,7 +535,6 @@ void HTTPRequest::_bind_methods() {
}
HTTPRequest::HTTPRequest() {
-
thread = nullptr;
port = 80;
@@ -593,6 +562,7 @@ HTTPRequest::HTTPRequest() {
}
HTTPRequest::~HTTPRequest() {
- if (file)
+ if (file) {
memdelete(file);
+ }
}
diff --git a/scene/main/http_request.h b/scene/main/http_request.h
index a3d95cd652..1409965d45 100644
--- a/scene/main/http_request.h
+++ b/scene/main/http_request.h
@@ -38,7 +38,6 @@
#include "scene/main/timer.h"
class HTTPRequest : public Node {
-
GDCLASS(HTTPRequest, Node);
public:
diff --git a/scene/main/instance_placeholder.cpp b/scene/main/instance_placeholder.cpp
index 062b221c84..ca8d5a2ca0 100644
--- a/scene/main/instance_placeholder.cpp
+++ b/scene/main/instance_placeholder.cpp
@@ -34,7 +34,6 @@
#include "scene/resources/packed_scene.h"
bool InstancePlaceholder::_set(const StringName &p_name, const Variant &p_value) {
-
PropSet ps;
ps.name = p_name;
ps.value = p_value;
@@ -43,7 +42,6 @@ bool InstancePlaceholder::_set(const StringName &p_name, const Variant &p_value)
}
bool InstancePlaceholder::_get(const StringName &p_name, Variant &r_ret) const {
-
for (const List<PropSet>::Element *E = stored_values.front(); E; E = E->next()) {
if (E->get().name == p_name) {
r_ret = E->get().value;
@@ -54,7 +52,6 @@ bool InstancePlaceholder::_get(const StringName &p_name, Variant &r_ret) const {
}
void InstancePlaceholder::_get_property_list(List<PropertyInfo> *p_list) const {
-
for (const List<PropSet>::Element *E = stored_values.front(); E; E = E->next()) {
PropertyInfo pi;
pi.name = E->get().name;
@@ -66,34 +63,35 @@ void InstancePlaceholder::_get_property_list(List<PropertyInfo> *p_list) const {
}
void InstancePlaceholder::set_instance_path(const String &p_name) {
-
path = p_name;
}
String InstancePlaceholder::get_instance_path() const {
-
return path;
}
Node *InstancePlaceholder::create_instance(bool p_replace, const Ref<PackedScene> &p_custom_scene) {
-
ERR_FAIL_COND_V(!is_inside_tree(), nullptr);
Node *base = get_parent();
- if (!base)
+ if (!base) {
return nullptr;
+ }
Ref<PackedScene> ps;
- if (p_custom_scene.is_valid())
+ if (p_custom_scene.is_valid()) {
ps = p_custom_scene;
- else
+ } else {
ps = ResourceLoader::load(path, "PackedScene");
+ }
- if (!ps.is_valid())
+ if (!ps.is_valid()) {
return nullptr;
+ }
Node *scene = ps->instance();
- if (!scene)
+ if (!scene) {
return nullptr;
+ }
scene->set_name(get_name());
int pos = get_index();
@@ -113,24 +111,24 @@ Node *InstancePlaceholder::create_instance(bool p_replace, const Ref<PackedScene
}
Dictionary InstancePlaceholder::get_stored_values(bool p_with_order) {
-
Dictionary ret;
PackedStringArray order;
for (List<PropSet>::Element *E = stored_values.front(); E; E = E->next()) {
ret[E->get().name] = E->get().value;
- if (p_with_order)
+ if (p_with_order) {
order.push_back(E->get().name);
+ }
};
- if (p_with_order)
+ if (p_with_order) {
ret[".order"] = order;
+ }
return ret;
};
void InstancePlaceholder::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_stored_values", "with_order"), &InstancePlaceholder::get_stored_values, DEFVAL(false));
ClassDB::bind_method(D_METHOD("create_instance", "replace", "custom_scene"), &InstancePlaceholder::create_instance, DEFVAL(false), DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("get_instance_path"), &InstancePlaceholder::get_instance_path);
diff --git a/scene/main/instance_placeholder.h b/scene/main/instance_placeholder.h
index 9f7b84716d..ec1f8a9b09 100644
--- a/scene/main/instance_placeholder.h
+++ b/scene/main/instance_placeholder.h
@@ -36,7 +36,6 @@
class PackedScene;
class InstancePlaceholder : public Node {
-
GDCLASS(InstancePlaceholder, Node);
String path;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 50f3bf834f..c9d430c656 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -51,22 +51,16 @@ VARIANT_ENUM_CAST(Node::PauseMode);
int Node::orphan_node_count = 0;
void Node::_notification(int p_notification) {
-
switch (p_notification) {
-
case NOTIFICATION_PROCESS: {
-
if (get_script_instance()) {
-
Variant time = get_process_delta_time();
const Variant *ptr[1] = { &time };
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_process, ptr, 1);
}
} break;
case NOTIFICATION_PHYSICS_PROCESS: {
-
if (get_script_instance()) {
-
Variant time = get_physics_process_delta_time();
const Variant *ptr[1] = { &time };
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_physics_process, ptr, 1);
@@ -78,21 +72,24 @@ void Node::_notification(int p_notification) {
ERR_FAIL_COND(!get_tree());
if (data.pause_mode == PAUSE_MODE_INHERIT) {
-
- if (data.parent)
+ if (data.parent) {
data.pause_owner = data.parent->data.pause_owner;
- else
+ } else {
data.pause_owner = nullptr;
+ }
} else {
data.pause_owner = this;
}
- if (data.input)
+ if (data.input) {
add_to_group("_vp_input" + itos(get_viewport()->get_instance_id()));
- if (data.unhandled_input)
+ }
+ if (data.unhandled_input) {
add_to_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id()));
- if (data.unhandled_key_input)
+ }
+ if (data.unhandled_key_input) {
add_to_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id()));
+ }
get_tree()->node_count++;
orphan_node_count--;
@@ -105,12 +102,15 @@ void Node::_notification(int p_notification) {
get_tree()->node_count--;
orphan_node_count++;
- if (data.input)
+ if (data.input) {
remove_from_group("_vp_input" + itos(get_viewport()->get_instance_id()));
- if (data.unhandled_input)
+ }
+ if (data.unhandled_input) {
remove_from_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id()));
- if (data.unhandled_key_input)
+ }
+ if (data.unhandled_key_input) {
remove_from_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id()));
+ }
data.pause_owner = nullptr;
if (data.path_cache) {
@@ -119,16 +119,13 @@ void Node::_notification(int p_notification) {
}
} break;
case NOTIFICATION_PATH_CHANGED: {
-
if (data.path_cache) {
memdelete(data.path_cache);
data.path_cache = nullptr;
}
} break;
case NOTIFICATION_READY: {
-
if (get_script_instance()) {
-
if (get_script_instance()->has_method(SceneStringNames::get_singleton()->_input)) {
set_process_input(true);
}
@@ -157,22 +154,18 @@ void Node::_notification(int p_notification) {
data.in_constructor = false;
} break;
case NOTIFICATION_PREDELETE: {
-
set_owner(nullptr);
while (data.owned.size()) {
-
data.owned.front()->get()->set_owner(nullptr);
}
if (data.parent) {
-
data.parent->remove_child(this);
}
// kill children as cleanly as possible
while (data.children.size()) {
-
Node *child = data.children[data.children.size() - 1]; //begin from the end because its faster and more consistent with creation
remove_child(child);
memdelete(child);
@@ -183,11 +176,9 @@ void Node::_notification(int p_notification) {
}
void Node::_propagate_ready() {
-
data.ready_notified = true;
data.blocked++;
for (int i = 0; i < data.children.size(); i++) {
-
data.children[i]->_propagate_ready();
}
data.blocked--;
@@ -208,13 +199,13 @@ void Node::_propagate_enter_tree() {
data.tree = data.parent->data.tree;
data.depth = data.parent->data.depth + 1;
} else {
-
data.depth = 1;
}
data.viewport = Object::cast_to<Viewport>(this);
- if (!data.viewport && data.parent)
+ if (!data.viewport && data.parent) {
data.viewport = data.parent->data.viewport;
+ }
data.inside_tree = true;
@@ -225,7 +216,6 @@ void Node::_propagate_enter_tree() {
notification(NOTIFICATION_ENTER_TREE);
if (get_script_instance()) {
-
get_script_instance()->call_multilevel_reversed(SceneStringNames::get_singleton()->_enter_tree, nullptr, 0);
}
@@ -237,9 +227,9 @@ void Node::_propagate_enter_tree() {
//block while adding children
for (int i = 0; i < data.children.size(); i++) {
-
- if (!data.children[i]->is_inside_tree()) // could have been added in enter_tree
+ if (!data.children[i]->is_inside_tree()) { // could have been added in enter_tree
data.children[i]->_propagate_enter_tree();
+ }
}
data.blocked--;
@@ -251,7 +241,6 @@ void Node::_propagate_enter_tree() {
}
void Node::_propagate_after_exit_tree() {
-
data.blocked++;
for (int i = 0; i < data.children.size(); i++) {
data.children[i]->_propagate_after_exit_tree();
@@ -261,7 +250,6 @@ void Node::_propagate_after_exit_tree() {
}
void Node::_propagate_exit_tree() {
-
//block while removing children
#ifdef DEBUG_ENABLED
@@ -270,21 +258,20 @@ void Node::_propagate_exit_tree() {
data.blocked++;
for (int i = data.children.size() - 1; i >= 0; i--) {
-
data.children[i]->_propagate_exit_tree();
}
data.blocked--;
if (get_script_instance()) {
-
get_script_instance()->call_multilevel(SceneStringNames::get_singleton()->_exit_tree, nullptr, 0);
}
emit_signal(SceneStringNames::get_singleton()->tree_exiting);
notification(NOTIFICATION_EXIT_TREE, true);
- if (data.tree)
+ if (data.tree) {
data.tree->node_removed(this);
+ }
// exit groups
@@ -295,8 +282,9 @@ void Node::_propagate_exit_tree() {
data.viewport = nullptr;
- if (data.tree)
+ if (data.tree) {
data.tree->tree_changed();
+ }
data.inside_tree = false;
data.ready_notified = false;
@@ -305,7 +293,6 @@ void Node::_propagate_exit_tree() {
}
void Node::move_child(Node *p_child, int p_pos) {
-
ERR_FAIL_NULL(p_child);
ERR_FAIL_INDEX_MSG(p_pos, data.children.size() + 1, "Invalid new child position: " + itos(p_pos) + ".");
ERR_FAIL_COND_MSG(p_child->data.parent != this, "Child is not a child of this node.");
@@ -313,11 +300,13 @@ void Node::move_child(Node *p_child, int p_pos) {
// Specifying one place beyond the end
// means the same as moving to the last position
- if (p_pos == data.children.size())
+ if (p_pos == data.children.size()) {
p_pos--;
+ }
- if (p_child->data.pos == p_pos)
+ if (p_child->data.pos == p_pos) {
return; //do nothing
+ }
int motion_from = MIN(p_pos, p_child->data.pos);
int motion_to = MAX(p_pos, p_child->data.pos);
@@ -332,7 +321,6 @@ void Node::move_child(Node *p_child, int p_pos) {
data.blocked++;
//new pos first
for (int i = motion_from; i <= motion_to; i++) {
-
data.children[i]->data.pos = i;
}
// notification second
@@ -341,94 +329,94 @@ void Node::move_child(Node *p_child, int p_pos) {
data.children[i]->notification(NOTIFICATION_MOVED_IN_PARENT);
}
for (const Map<StringName, GroupData>::Element *E = p_child->data.grouped.front(); E; E = E->next()) {
- if (E->get().group)
+ if (E->get().group) {
E->get().group->changed = true;
+ }
}
data.blocked--;
}
void Node::raise() {
-
- if (!data.parent)
+ if (!data.parent) {
return;
+ }
data.parent->move_child(this, data.parent->data.children.size() - 1);
}
void Node::add_child_notify(Node *p_child) {
-
// to be used when not wanted
}
void Node::remove_child_notify(Node *p_child) {
-
// to be used when not wanted
}
void Node::move_child_notify(Node *p_child) {
-
// to be used when not wanted
}
void Node::set_physics_process(bool p_process) {
-
- if (data.physics_process == p_process)
+ if (data.physics_process == p_process) {
return;
+ }
data.physics_process = p_process;
- if (data.physics_process)
+ if (data.physics_process) {
add_to_group("physics_process", false);
- else
+ } else {
remove_from_group("physics_process");
+ }
_change_notify("physics_process");
}
bool Node::is_physics_processing() const {
-
return data.physics_process;
}
void Node::set_physics_process_internal(bool p_process_internal) {
-
- if (data.physics_process_internal == p_process_internal)
+ if (data.physics_process_internal == p_process_internal) {
return;
+ }
data.physics_process_internal = p_process_internal;
- if (data.physics_process_internal)
+ if (data.physics_process_internal) {
add_to_group("physics_process_internal", false);
- else
+ } else {
remove_from_group("physics_process_internal");
+ }
_change_notify("physics_process_internal");
}
bool Node::is_physics_processing_internal() const {
-
return data.physics_process_internal;
}
void Node::set_pause_mode(PauseMode p_mode) {
-
- if (data.pause_mode == p_mode)
+ if (data.pause_mode == p_mode) {
return;
+ }
bool prev_inherits = data.pause_mode == PAUSE_MODE_INHERIT;
data.pause_mode = p_mode;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return; //pointless
- if ((data.pause_mode == PAUSE_MODE_INHERIT) == prev_inherits)
+ }
+ if ((data.pause_mode == PAUSE_MODE_INHERIT) == prev_inherits) {
return; ///nothing changed
+ }
Node *owner = nullptr;
if (data.pause_mode == PAUSE_MODE_INHERIT) {
-
- if (data.parent)
+ if (data.parent) {
owner = data.parent->data.pause_owner;
+ }
} else {
owner = this;
}
@@ -437,40 +425,34 @@ void Node::set_pause_mode(PauseMode p_mode) {
}
Node::PauseMode Node::get_pause_mode() const {
-
return data.pause_mode;
}
void Node::_propagate_pause_owner(Node *p_owner) {
-
- if (this != p_owner && data.pause_mode != PAUSE_MODE_INHERIT)
+ if (this != p_owner && data.pause_mode != PAUSE_MODE_INHERIT) {
return;
+ }
data.pause_owner = p_owner;
for (int i = 0; i < data.children.size(); i++) {
-
data.children[i]->_propagate_pause_owner(p_owner);
}
}
void Node::set_network_master(int p_peer_id, bool p_recursive) {
-
data.network_master = p_peer_id;
if (p_recursive) {
for (int i = 0; i < data.children.size(); i++) {
-
data.children[i]->set_network_master(p_peer_id, true);
}
}
}
int Node::get_network_master() const {
-
return data.network_master;
}
bool Node::is_network_master() const {
-
ERR_FAIL_COND_V(!is_inside_tree(), false);
return get_multiplayer()->get_network_unique_id() == data.network_master;
@@ -479,7 +461,6 @@ bool Node::is_network_master() const {
/***** RPC CONFIG ********/
uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_mode) {
-
uint16_t mid = get_node_rpc_method_id(p_method);
if (mid == UINT16_MAX) {
// It's new
@@ -496,7 +477,6 @@ uint16_t Node::rpc_config(const StringName &p_method, MultiplayerAPI::RPCMode p_
}
uint16_t Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode p_mode) {
-
uint16_t pid = get_node_rset_property_id(p_property);
if (pid == UINT16_MAX) {
// It's new
@@ -515,13 +495,13 @@ uint16_t Node::rset_config(const StringName &p_property, MultiplayerAPI::RPCMode
/***** RPC FUNCTIONS ********/
void Node::rpc(const StringName &p_method, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS;
int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
argc++;
}
@@ -529,13 +509,13 @@ void Node::rpc(const StringName &p_method, VARIANT_ARG_DECLARE) {
}
void Node::rpc_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS;
int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
argc++;
}
@@ -543,13 +523,13 @@ void Node::rpc_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_DECLARE
}
void Node::rpc_unreliable(const StringName &p_method, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS;
int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
argc++;
}
@@ -557,13 +537,13 @@ void Node::rpc_unreliable(const StringName &p_method, VARIANT_ARG_DECLARE) {
}
void Node::rpc_unreliable_id(int p_peer_id, const StringName &p_method, VARIANT_ARG_DECLARE) {
-
VARIANT_ARGPTRS;
int argc = 0;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
argc++;
}
@@ -571,7 +551,6 @@ void Node::rpc_unreliable_id(int p_peer_id, const StringName &p_method, VARIANT_
}
Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (p_argcount < 1) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 1;
@@ -594,7 +573,6 @@ Variant Node::_rpc_bind(const Variant **p_args, int p_argcount, Callable::CallEr
}
Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (p_argcount < 2) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 2;
@@ -625,7 +603,6 @@ Variant Node::_rpc_id_bind(const Variant **p_args, int p_argcount, Callable::Cal
}
Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (p_argcount < 1) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 1;
@@ -648,7 +625,6 @@ Variant Node::_rpc_unreliable_bind(const Variant **p_args, int p_argcount, Calla
}
Variant Node::_rpc_unreliable_id_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
if (p_argcount < 2) {
r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
r_error.argument = 2;
@@ -690,31 +666,29 @@ void Node::rsetp(int p_peer_id, bool p_unreliable, const StringName &p_property,
/******** RSET *********/
void Node::rset(const StringName &p_property, const Variant &p_value) {
-
rsetp(0, false, p_property, p_value);
}
void Node::rset_id(int p_peer_id, const StringName &p_property, const Variant &p_value) {
-
rsetp(p_peer_id, false, p_property, p_value);
}
void Node::rset_unreliable(const StringName &p_property, const Variant &p_value) {
-
rsetp(0, true, p_property, p_value);
}
void Node::rset_unreliable_id(int p_peer_id, const StringName &p_property, const Variant &p_value) {
-
rsetp(p_peer_id, true, p_property, p_value);
}
//////////// end of rpc
Ref<MultiplayerAPI> Node::get_multiplayer() const {
- if (multiplayer.is_valid())
+ if (multiplayer.is_valid()) {
return multiplayer;
- if (!is_inside_tree())
+ }
+ if (!is_inside_tree()) {
return Ref<MultiplayerAPI>();
+ }
return get_tree()->get_multiplayer();
}
@@ -723,7 +697,6 @@ Ref<MultiplayerAPI> Node::get_custom_multiplayer() const {
}
void Node::set_custom_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
-
multiplayer = p_multiplayer;
}
@@ -742,8 +715,9 @@ StringName Node::get_node_rpc_method(const uint16_t p_rpc_method_id) const {
// Make sure this is a node generated ID.
if (((1 << 15) & p_rpc_method_id) > 0) {
int mid = (~(1 << 15)) & p_rpc_method_id;
- if (mid < data.rpc_methods.size())
+ if (mid < data.rpc_methods.size()) {
return data.rpc_methods[mid].name;
+ }
}
return StringName();
}
@@ -752,8 +726,9 @@ MultiplayerAPI::RPCMode Node::get_node_rpc_mode_by_id(const uint16_t p_rpc_metho
// Make sure this is a node generated ID.
if (((1 << 15) & p_rpc_method_id) > 0) {
int mid = (~(1 << 15)) & p_rpc_method_id;
- if (mid < data.rpc_methods.size())
+ if (mid < data.rpc_methods.size()) {
return data.rpc_methods[mid].mode;
+ }
}
return MultiplayerAPI::RPC_MODE_DISABLED;
}
@@ -777,8 +752,9 @@ StringName Node::get_node_rset_property(const uint16_t p_rset_property_id) const
// Make sure this is a node generated ID.
if (((1 << 15) & p_rset_property_id) > 0) {
int mid = (~(1 << 15)) & p_rset_property_id;
- if (mid < data.rpc_properties.size())
+ if (mid < data.rpc_properties.size()) {
return data.rpc_properties[mid].name;
+ }
}
return StringName();
}
@@ -786,8 +762,9 @@ StringName Node::get_node_rset_property(const uint16_t p_rset_property_id) const
MultiplayerAPI::RPCMode Node::get_node_rset_mode_by_id(const uint16_t p_rset_property_id) const {
if (((1 << 15) & p_rset_property_id) > 0) {
int mid = (~(1 << 15)) & p_rset_property_id;
- if (mid < data.rpc_properties.size())
+ if (mid < data.rpc_properties.size()) {
return data.rpc_properties[mid].mode;
+ }
}
return MultiplayerAPI::RPC_MODE_DISABLED;
}
@@ -819,35 +796,41 @@ String Node::get_rpc_md5() const {
bool Node::can_process_notification(int p_what) const {
switch (p_what) {
- case NOTIFICATION_PHYSICS_PROCESS: return data.physics_process;
- case NOTIFICATION_PROCESS: return data.idle_process;
- case NOTIFICATION_INTERNAL_PROCESS: return data.idle_process_internal;
- case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: return data.physics_process_internal;
+ case NOTIFICATION_PHYSICS_PROCESS:
+ return data.physics_process;
+ case NOTIFICATION_PROCESS:
+ return data.idle_process;
+ case NOTIFICATION_INTERNAL_PROCESS:
+ return data.idle_process_internal;
+ case NOTIFICATION_INTERNAL_PHYSICS_PROCESS:
+ return data.physics_process_internal;
}
return true;
}
bool Node::can_process() const {
-
ERR_FAIL_COND_V(!is_inside_tree(), false);
if (get_tree()->is_paused()) {
-
- if (data.pause_mode == PAUSE_MODE_STOP)
+ if (data.pause_mode == PAUSE_MODE_STOP) {
return false;
- if (data.pause_mode == PAUSE_MODE_PROCESS)
+ }
+ if (data.pause_mode == PAUSE_MODE_PROCESS) {
return true;
+ }
if (data.pause_mode == PAUSE_MODE_INHERIT) {
-
- if (!data.pause_owner)
+ if (!data.pause_owner) {
return false; //clearly no pause owner by default
+ }
- if (data.pause_owner->data.pause_mode == PAUSE_MODE_PROCESS)
+ if (data.pause_owner->data.pause_mode == PAUSE_MODE_PROCESS) {
return true;
+ }
- if (data.pause_owner->data.pause_mode == PAUSE_MODE_STOP)
+ if (data.pause_owner->data.pause_mode == PAUSE_MODE_STOP) {
return false;
+ }
}
}
@@ -855,58 +838,58 @@ bool Node::can_process() const {
}
float Node::get_physics_process_delta_time() const {
-
- if (data.tree)
+ if (data.tree) {
return data.tree->get_physics_process_time();
- else
+ } else {
return 0;
+ }
}
float Node::get_process_delta_time() const {
-
- if (data.tree)
+ if (data.tree) {
return data.tree->get_idle_process_time();
- else
+ } else {
return 0;
+ }
}
void Node::set_process(bool p_idle_process) {
-
- if (data.idle_process == p_idle_process)
+ if (data.idle_process == p_idle_process) {
return;
+ }
data.idle_process = p_idle_process;
- if (data.idle_process)
+ if (data.idle_process) {
add_to_group("idle_process", false);
- else
+ } else {
remove_from_group("idle_process");
+ }
_change_notify("idle_process");
}
bool Node::is_processing() const {
-
return data.idle_process;
}
void Node::set_process_internal(bool p_idle_process_internal) {
-
- if (data.idle_process_internal == p_idle_process_internal)
+ if (data.idle_process_internal == p_idle_process_internal) {
return;
+ }
data.idle_process_internal = p_idle_process_internal;
- if (data.idle_process_internal)
+ if (data.idle_process_internal) {
add_to_group("idle_process_internal", false);
- else
+ } else {
remove_from_group("idle_process_internal");
+ }
_change_notify("idle_process_internal");
}
bool Node::is_processing_internal() const {
-
return data.idle_process_internal;
}
@@ -936,23 +919,24 @@ void Node::set_process_priority(int p_priority) {
}
int Node::get_process_priority() const {
-
return data.process_priority;
}
void Node::set_process_input(bool p_enable) {
-
- if (p_enable == data.input)
+ if (p_enable == data.input) {
return;
+ }
data.input = p_enable;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
- if (p_enable)
+ if (p_enable) {
add_to_group("_vp_input" + itos(get_viewport()->get_instance_id()));
- else
+ } else {
remove_from_group("_vp_input" + itos(get_viewport()->get_instance_id()));
+ }
}
bool Node::is_processing_input() const {
@@ -960,17 +944,19 @@ bool Node::is_processing_input() const {
}
void Node::set_process_unhandled_input(bool p_enable) {
-
- if (p_enable == data.unhandled_input)
+ if (p_enable == data.unhandled_input) {
return;
+ }
data.unhandled_input = p_enable;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
- if (p_enable)
+ if (p_enable) {
add_to_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id()));
- else
+ } else {
remove_from_group("_vp_unhandled_input" + itos(get_viewport()->get_instance_id()));
+ }
}
bool Node::is_processing_unhandled_input() const {
@@ -978,17 +964,19 @@ bool Node::is_processing_unhandled_input() const {
}
void Node::set_process_unhandled_key_input(bool p_enable) {
-
- if (p_enable == data.unhandled_key_input)
+ if (p_enable == data.unhandled_key_input) {
return;
+ }
data.unhandled_key_input = p_enable;
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
- if (p_enable)
+ if (p_enable) {
add_to_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id()));
- else
+ } else {
remove_from_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id()));
+ }
}
bool Node::is_processing_unhandled_key_input() const {
@@ -996,12 +984,10 @@ bool Node::is_processing_unhandled_key_input() const {
}
StringName Node::get_name() const {
-
return data.name;
}
void Node::_set_name_nocheck(const StringName &p_name) {
-
data.name = p_name;
}
@@ -1019,7 +1005,6 @@ bool Node::_validate_node_name(String &p_name) {
}
void Node::set_name(const String &p_name) {
-
String name = p_name;
_validate_node_name(name);
@@ -1027,14 +1012,12 @@ void Node::set_name(const String &p_name) {
data.name = name;
if (data.parent) {
-
data.parent->_validate_child_name(this);
}
propagate_notification(NOTIFICATION_PATH_CHANGED);
if (is_inside_tree()) {
-
emit_signal("renamed");
get_tree()->node_renamed(this);
get_tree()->tree_changed();
@@ -1049,13 +1032,11 @@ void Node::init_node_hrcr() {
}
void Node::set_human_readable_collision_renaming(bool p_enabled) {
-
node_hrcr = p_enabled;
}
#ifdef TOOLS_ENABLED
String Node::validate_child_name(Node *p_child) {
-
StringName name = p_child->data.name;
_generate_serial_child_name(p_child, name);
return name;
@@ -1063,11 +1044,9 @@ String Node::validate_child_name(Node *p_child) {
#endif
void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
-
/* Make sure the name is unique */
if (node_hrcr || p_force_human_readable) {
-
//this approach to autoset node names is human readable but very slow
//it's turned on while running in the editor
@@ -1076,7 +1055,6 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
p_child->data.name = name;
} else {
-
//this approach to autoset node names is fast but not as readable
//it's the default and reserves the '@' character for unique names.
@@ -1091,8 +1069,9 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
int cc = data.children.size();
for (int i = 0; i < cc; i++) {
- if (children[i] == p_child)
+ if (children[i] == p_child) {
continue;
+ }
if (children[i]->data.name == p_child->data.name) {
unique = false;
break;
@@ -1101,7 +1080,6 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
}
if (!unique) {
-
ERR_FAIL_COND(!node_hrcr_count.ref());
String name = "@" + String(p_child->get_name()) + "@" + itos(node_hrcr_count.get());
p_child->data.name = name;
@@ -1111,7 +1089,6 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
// Return s + 1 as if it were an integer
String increase_numeric_string(const String &s) {
-
String res = s;
bool carry = res.length() > 0;
@@ -1136,7 +1113,6 @@ String increase_numeric_string(const String &s) {
}
void Node::_generate_serial_child_name(const Node *p_child, StringName &name) const {
-
if (name == StringName()) {
//no name and a new nade is needed, create one.
@@ -1161,7 +1137,6 @@ void Node::_generate_serial_child_name(const Node *p_child, StringName &name) co
const Node *const *children_ptr = data.children.ptr();
{
-
bool exists = false;
for (int i = 0; i < cc; i++) {
@@ -1248,7 +1223,6 @@ void Node::_add_child_nocheck(Node *p_child, const StringName &p_name) {
}
void Node::add_child(Node *p_child, bool p_legible_unique_name) {
-
ERR_FAIL_NULL(p_child);
ERR_FAIL_COND_MSG(p_child == this, "Can't add child '" + p_child->get_name() + "' to itself."); // adding to itself!
ERR_FAIL_COND_MSG(p_child->data.parent, "Can't add child '" + p_child->get_name() + "' to '" + get_name() + "', already has a parent '" + p_child->data.parent->get_name() + "'."); //Fail if node has a parent
@@ -1260,31 +1234,22 @@ void Node::add_child(Node *p_child, bool p_legible_unique_name) {
_add_child_nocheck(p_child, p_child->data.name);
}
-void Node::add_child_below_node(Node *p_node, Node *p_child, bool p_legible_unique_name) {
+void Node::add_sibling(Node *p_sibling, bool p_legible_unique_name) {
+ ERR_FAIL_NULL(p_sibling);
+ ERR_FAIL_COND_MSG(p_sibling == this, "Can't add sibling '" + p_sibling->get_name() + "' to itself."); // adding to itself!
+ ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, add_sibling() failed. Consider using call_deferred(\"add_sibling\", sibling) instead.");
- ERR_FAIL_NULL(p_node);
- ERR_FAIL_NULL(p_child);
-
- add_child(p_child, p_legible_unique_name);
-
- if (is_a_parent_of(p_node)) {
- move_child(p_child, p_node->get_index() + 1);
- } else {
- WARN_PRINT("Cannot move under node " + p_node->get_name() + " as " + p_child->get_name() + " does not share a parent.");
- }
+ get_parent()->add_child(p_sibling, p_legible_unique_name);
+ get_parent()->move_child(p_sibling, this->get_index() + 1);
}
void Node::_propagate_validate_owner() {
-
if (data.owner) {
-
bool found = false;
Node *parent = data.parent;
while (parent) {
-
if (parent == data.owner) {
-
found = true;
break;
}
@@ -1293,20 +1258,17 @@ void Node::_propagate_validate_owner() {
}
if (!found) {
-
data.owner->data.owned.erase(data.OW);
data.owner = nullptr;
}
}
for (int i = 0; i < data.children.size(); i++) {
-
data.children[i]->_propagate_validate_owner();
}
}
void Node::remove_child(Node *p_child) {
-
ERR_FAIL_NULL(p_child);
ERR_FAIL_COND_MSG(data.blocked > 0, "Parent node is busy setting up children, remove_node() failed. Consider using call_deferred(\"remove_child\", child) instead.");
@@ -1322,9 +1284,7 @@ void Node::remove_child(Node *p_child) {
if (idx == -1) { //maybe removed while unparenting or something and index was not updated, so just in case the above fails, try this.
for (int i = 0; i < child_count; i++) {
-
if (children[i] == p_child) {
-
idx = i;
break;
}
@@ -1349,7 +1309,6 @@ void Node::remove_child(Node *p_child) {
children = data.children.ptrw();
for (int i = idx; i < child_count; i++) {
-
children[i]->data.pos = i;
children[i]->notification(NOTIFICATION_MOVED_IN_PARENT);
}
@@ -1366,31 +1325,29 @@ void Node::remove_child(Node *p_child) {
}
int Node::get_child_count() const {
-
return data.children.size();
}
-Node *Node::get_child(int p_index) const {
+Node *Node::get_child(int p_index) const {
ERR_FAIL_INDEX_V(p_index, data.children.size(), nullptr);
return data.children[p_index];
}
Node *Node::_get_child_by_name(const StringName &p_name) const {
-
int cc = data.children.size();
Node *const *cd = data.children.ptr();
for (int i = 0; i < cc; i++) {
- if (cd[i]->data.name == p_name)
+ if (cd[i]->data.name == p_name) {
return cd[i];
+ }
}
return nullptr;
}
Node *Node::get_node_or_null(const NodePath &p_path) const {
-
if (p_path.is_empty()) {
return nullptr;
}
@@ -1403,14 +1360,13 @@ Node *Node::get_node_or_null(const NodePath &p_path) const {
if (!p_path.is_absolute()) {
current = const_cast<Node *>(this); //start from this
} else {
-
root = const_cast<Node *>(this);
- while (root->data.parent)
+ while (root->data.parent) {
root = root->data.parent; //start from root
+ }
}
for (int i = 0; i < p_path.get_name_count(); i++) {
-
StringName name = p_path.get_name(i);
Node *next = nullptr;
@@ -1420,25 +1376,23 @@ Node *Node::get_node_or_null(const NodePath &p_path) const {
} else if (name == SceneStringNames::get_singleton()->doubledot) { // ..
- if (current == nullptr || !current->data.parent)
+ if (current == nullptr || !current->data.parent) {
return nullptr;
+ }
next = current->data.parent;
} else if (current == nullptr) {
-
- if (name == root->get_name())
+ if (name == root->get_name()) {
next = root;
+ }
} else {
-
next = nullptr;
for (int j = 0; j < current->data.children.size(); j++) {
-
Node *child = current->data.children[j];
if (child->data.name == name) {
-
next = child;
break;
}
@@ -1454,49 +1408,48 @@ Node *Node::get_node_or_null(const NodePath &p_path) const {
}
Node *Node::get_node(const NodePath &p_path) const {
-
Node *node = get_node_or_null(p_path);
ERR_FAIL_COND_V_MSG(!node, nullptr, "Node not found: " + p_path + ".");
return node;
}
bool Node::has_node(const NodePath &p_path) const {
-
return get_node_or_null(p_path) != nullptr;
}
Node *Node::find_node(const String &p_mask, bool p_recursive, bool p_owned) const {
-
Node *const *cptr = data.children.ptr();
int ccount = data.children.size();
for (int i = 0; i < ccount; i++) {
- if (p_owned && !cptr[i]->data.owner)
+ if (p_owned && !cptr[i]->data.owner) {
continue;
- if (cptr[i]->data.name.operator String().match(p_mask))
+ }
+ if (cptr[i]->data.name.operator String().match(p_mask)) {
return cptr[i];
+ }
- if (!p_recursive)
+ if (!p_recursive) {
continue;
+ }
Node *ret = cptr[i]->find_node(p_mask, true, p_owned);
- if (ret)
+ if (ret) {
return ret;
+ }
}
return nullptr;
}
Node *Node::get_parent() const {
-
return data.parent;
}
Node *Node::find_parent(const String &p_mask) const {
-
Node *p = data.parent;
while (p) {
-
- if (p->data.name.operator String().match(p_mask))
+ if (p->data.name.operator String().match(p_mask)) {
return p;
+ }
p = p->data.parent;
}
@@ -1504,13 +1457,12 @@ Node *Node::find_parent(const String &p_mask) const {
}
bool Node::is_a_parent_of(const Node *p_node) const {
-
ERR_FAIL_NULL_V(p_node, false);
Node *p = p_node->data.parent;
while (p) {
-
- if (p == this)
+ if (p == this) {
return true;
+ }
p = p->data.parent;
}
@@ -1518,7 +1470,6 @@ bool Node::is_a_parent_of(const Node *p_node) const {
}
bool Node::is_greater_than(const Node *p_node) const {
-
ERR_FAIL_NULL_V(p_node, false);
ERR_FAIL_COND_V(!data.inside_tree, false);
ERR_FAIL_COND_V(!p_node->data.inside_tree, false);
@@ -1561,7 +1512,6 @@ bool Node::is_greater_than(const Node *p_node) const {
bool res;
while (true) {
-
// using -2 since out-of-tree or nonroot nodes have -1
int this_idx = (idx >= data.depth) ? -2 : this_stack[idx];
int that_idx = (idx >= p_node->data.depth) ? -2 : that_stack[idx];
@@ -1583,18 +1533,19 @@ bool Node::is_greater_than(const Node *p_node) const {
}
void Node::get_owned_by(Node *p_by, List<Node *> *p_owned) {
-
- if (data.owner == p_by)
+ if (data.owner == p_by) {
p_owned->push_back(this);
+ }
- for (int i = 0; i < get_child_count(); i++)
+ for (int i = 0; i < get_child_count(); i++) {
get_child(i)->get_owned_by(p_by, p_owned);
+ }
}
void Node::_set_owner_nocheck(Node *p_owner) {
-
- if (data.owner == p_owner)
+ if (data.owner == p_owner) {
return;
+ }
ERR_FAIL_COND(data.owner);
data.owner = p_owner;
@@ -1603,9 +1554,7 @@ void Node::_set_owner_nocheck(Node *p_owner) {
}
void Node::set_owner(Node *p_owner) {
-
if (data.owner) {
-
data.owner->data.owned.erase(data.OW);
data.OW = nullptr;
data.owner = nullptr;
@@ -1613,14 +1562,14 @@ void Node::set_owner(Node *p_owner) {
ERR_FAIL_COND(p_owner == this);
- if (!p_owner)
+ if (!p_owner) {
return;
+ }
Node *check = this->get_parent();
bool owner_valid = false;
while (check) {
-
if (check == p_owner) {
owner_valid = true;
break;
@@ -1633,22 +1582,21 @@ void Node::set_owner(Node *p_owner) {
_set_owner_nocheck(p_owner);
}
-Node *Node::get_owner() const {
+Node *Node::get_owner() const {
return data.owner;
}
Node *Node::find_common_parent_with(const Node *p_node) const {
-
- if (this == p_node)
+ if (this == p_node) {
return const_cast<Node *>(p_node);
+ }
Set<const Node *> visited;
const Node *n = this;
while (n) {
-
visited.insert(n);
n = n->data.parent;
}
@@ -1656,31 +1604,31 @@ Node *Node::find_common_parent_with(const Node *p_node) const {
const Node *common_parent = p_node;
while (common_parent) {
-
- if (visited.has(common_parent))
+ if (visited.has(common_parent)) {
break;
+ }
common_parent = common_parent->data.parent;
}
- if (!common_parent)
+ if (!common_parent) {
return nullptr;
+ }
return const_cast<Node *>(common_parent);
}
NodePath Node::get_path_to(const Node *p_node) const {
-
ERR_FAIL_NULL_V(p_node, NodePath());
- if (this == p_node)
+ if (this == p_node) {
return NodePath(".");
+ }
Set<const Node *> visited;
const Node *n = this;
while (n) {
-
visited.insert(n);
n = n->data.parent;
}
@@ -1688,9 +1636,9 @@ NodePath Node::get_path_to(const Node *p_node) const {
const Node *common_parent = p_node;
while (common_parent) {
-
- if (visited.has(common_parent))
+ if (visited.has(common_parent)) {
break;
+ }
common_parent = common_parent->data.parent;
}
@@ -1703,7 +1651,6 @@ NodePath Node::get_path_to(const Node *p_node) const {
n = p_node;
while (n != common_parent) {
-
path.push_back(n->get_name());
n = n->data.parent;
}
@@ -1712,7 +1659,6 @@ NodePath Node::get_path_to(const Node *p_node) const {
StringName up = String("..");
while (n != common_parent) {
-
path.push_back(up);
n = n->data.parent;
}
@@ -1723,11 +1669,11 @@ NodePath Node::get_path_to(const Node *p_node) const {
}
NodePath Node::get_path() const {
-
ERR_FAIL_COND_V_MSG(!is_inside_tree(), NodePath(), "Cannot get path of node as it is not in a scene tree.");
- if (data.path_cache)
+ if (data.path_cache) {
return *data.path_cache;
+ }
const Node *n = this;
@@ -1746,16 +1692,15 @@ NodePath Node::get_path() const {
}
bool Node::is_in_group(const StringName &p_identifier) const {
-
return data.grouped.has(p_identifier);
}
void Node::add_to_group(const StringName &p_identifier, bool p_persistent) {
-
ERR_FAIL_COND(!p_identifier.operator String().length());
- if (data.grouped.has(p_identifier))
+ if (data.grouped.has(p_identifier)) {
return;
+ }
GroupData gd;
@@ -1771,21 +1716,20 @@ void Node::add_to_group(const StringName &p_identifier, bool p_persistent) {
}
void Node::remove_from_group(const StringName &p_identifier) {
-
ERR_FAIL_COND(!data.grouped.has(p_identifier));
Map<StringName, GroupData>::Element *E = data.grouped.find(p_identifier);
ERR_FAIL_COND(!E);
- if (data.tree)
+ if (data.tree) {
data.tree->remove_from_group(E->key(), this);
+ }
data.grouped.erase(E);
}
Array Node::_get_groups() const {
-
Array groups;
List<GroupInfo> gi;
get_groups(&gi);
@@ -1797,7 +1741,6 @@ Array Node::_get_groups() const {
}
void Node::get_groups(List<GroupInfo> *p_groups) const {
-
for (const Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
GroupInfo gi;
gi.name = E->key();
@@ -1807,7 +1750,6 @@ void Node::get_groups(List<GroupInfo> *p_groups) const {
}
int Node::get_persistent_group_count() const {
-
int count = 0;
for (const Map<StringName, GroupData>::Element *E = data.grouped.front(); E; E = E->next()) {
@@ -1818,8 +1760,8 @@ int Node::get_persistent_group_count() const {
return count;
}
-void Node::_print_tree_pretty(const String &prefix, const bool last) {
+void Node::_print_tree_pretty(const String &prefix, const bool last) {
String new_prefix = last ? String::utf8(" â”–â•´") : String::utf8(" â” â•´");
print_line(prefix + new_prefix + String(get_name()));
for (int i = 0; i < data.children.size(); i++) {
@@ -1833,21 +1775,19 @@ void Node::print_tree_pretty() {
}
void Node::print_tree() {
-
_print_tree(this);
}
void Node::_print_tree(const Node *p_node) {
print_line(String(p_node->get_path_to(this)));
- for (int i = 0; i < data.children.size(); i++)
+ for (int i = 0; i < data.children.size(); i++) {
data.children[i]->_print_tree(p_node);
+ }
}
void Node::_propagate_reverse_notification(int p_notification) {
-
data.blocked++;
for (int i = data.children.size() - 1; i >= 0; i--) {
-
data.children[i]->_propagate_reverse_notification(p_notification);
}
@@ -1856,71 +1796,70 @@ void Node::_propagate_reverse_notification(int p_notification) {
}
void Node::_propagate_deferred_notification(int p_notification, bool p_reverse) {
-
ERR_FAIL_COND(!is_inside_tree());
data.blocked++;
- if (!p_reverse)
+ if (!p_reverse) {
MessageQueue::get_singleton()->push_notification(this, p_notification);
+ }
for (int i = 0; i < data.children.size(); i++) {
-
data.children[i]->_propagate_deferred_notification(p_notification, p_reverse);
}
- if (p_reverse)
+ if (p_reverse) {
MessageQueue::get_singleton()->push_notification(this, p_notification);
+ }
data.blocked--;
}
void Node::propagate_notification(int p_notification) {
-
data.blocked++;
notification(p_notification);
for (int i = 0; i < data.children.size(); i++) {
-
data.children[i]->propagate_notification(p_notification);
}
data.blocked--;
}
void Node::propagate_call(const StringName &p_method, const Array &p_args, const bool p_parent_first) {
-
data.blocked++;
- if (p_parent_first && has_method(p_method))
+ if (p_parent_first && has_method(p_method)) {
callv(p_method, p_args);
+ }
for (int i = 0; i < data.children.size(); i++) {
data.children[i]->propagate_call(p_method, p_args, p_parent_first);
}
- if (!p_parent_first && has_method(p_method))
+ if (!p_parent_first && has_method(p_method)) {
callv(p_method, p_args);
+ }
data.blocked--;
}
void Node::_propagate_replace_owner(Node *p_owner, Node *p_by_owner) {
- if (get_owner() == p_owner)
+ if (get_owner() == p_owner) {
set_owner(p_by_owner);
+ }
data.blocked++;
- for (int i = 0; i < data.children.size(); i++)
+ for (int i = 0; i < data.children.size(); i++) {
data.children[i]->_propagate_replace_owner(p_owner, p_by_owner);
+ }
data.blocked--;
}
int Node::get_index() const {
-
return data.pos;
}
void Node::remove_and_skip() {
-
ERR_FAIL_COND(!data.parent);
Node *new_owner = get_owner();
@@ -1928,12 +1867,12 @@ void Node::remove_and_skip() {
List<Node *> children;
while (true) {
-
bool clear = true;
for (int i = 0; i < data.children.size(); i++) {
Node *c_node = data.children[i];
- if (!c_node->get_owner())
+ if (!c_node->get_owner()) {
continue;
+ }
remove_child(c_node);
c_node->_propagate_replace_owner(this, nullptr);
@@ -1942,12 +1881,12 @@ void Node::remove_and_skip() {
break;
}
- if (clear)
+ if (clear) {
break;
+ }
}
while (!children.empty()) {
-
Node *c_node = children.front()->get();
data.parent->add_child(c_node);
c_node->_propagate_replace_owner(nullptr, new_owner);
@@ -1958,20 +1897,18 @@ void Node::remove_and_skip() {
}
void Node::set_filename(const String &p_filename) {
-
data.filename = p_filename;
}
-String Node::get_filename() const {
+String Node::get_filename() const {
return data.filename;
}
void Node::set_editor_description(const String &p_editor_description) {
-
set_meta("_editor_description_", p_editor_description);
}
-String Node::get_editor_description() const {
+String Node::get_editor_description() const {
if (has_meta("_editor_description_")) {
return get_meta("_editor_description_");
} else {
@@ -1980,7 +1917,6 @@ String Node::get_editor_description() const {
}
void Node::set_editable_instance(Node *p_node, bool p_editable) {
-
ERR_FAIL_NULL(p_node);
ERR_FAIL_COND(!is_a_parent_of(p_node));
NodePath p = get_path_to(p_node);
@@ -1995,75 +1931,65 @@ void Node::set_editable_instance(Node *p_node, bool p_editable) {
}
bool Node::is_editable_instance(const Node *p_node) const {
-
- if (!p_node)
+ if (!p_node) {
return false; //easier, null is never editable :)
+ }
ERR_FAIL_COND_V(!is_a_parent_of(p_node), false);
NodePath p = get_path_to(p_node);
return data.editable_instances.has(p);
}
void Node::set_editable_instances(const HashMap<NodePath, int> &p_editable_instances) {
-
data.editable_instances = p_editable_instances;
}
HashMap<NodePath, int> Node::get_editable_instances() const {
-
return data.editable_instances;
}
void Node::set_scene_instance_state(const Ref<SceneState> &p_state) {
-
data.instance_state = p_state;
}
Ref<SceneState> Node::get_scene_instance_state() const {
-
return data.instance_state;
}
void Node::set_scene_inherited_state(const Ref<SceneState> &p_state) {
-
data.inherited_state = p_state;
}
Ref<SceneState> Node::get_scene_inherited_state() const {
-
return data.inherited_state;
}
void Node::set_scene_instance_load_placeholder(bool p_enable) {
-
data.use_placeholder = p_enable;
}
bool Node::get_scene_instance_load_placeholder() const {
-
return data.use_placeholder;
}
Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const {
-
Node *node = nullptr;
bool instanced = false;
if (Object::cast_to<InstancePlaceholder>(this)) {
-
const InstancePlaceholder *ip = Object::cast_to<const InstancePlaceholder>(this);
InstancePlaceholder *nip = memnew(InstancePlaceholder);
nip->set_instance_path(ip->get_instance_path());
node = nip;
} else if ((p_flags & DUPLICATE_USE_INSTANCING) && get_filename() != String()) {
-
Ref<PackedScene> res = ResourceLoader::load(get_filename());
ERR_FAIL_COND_V(res.is_null(), nullptr);
PackedScene::GenEditState ges = PackedScene::GEN_EDIT_STATE_DISABLED;
#ifdef TOOLS_ENABLED
- if (p_flags & DUPLICATE_FROM_EDITOR)
+ if (p_flags & DUPLICATE_FROM_EDITOR) {
ges = PackedScene::GEN_EDIT_STATE_INSTANCE;
+ }
#endif
node = res->instance(ges);
ERR_FAIL_COND_V(!node, nullptr);
@@ -2071,12 +1997,12 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
instanced = true;
} else {
-
Object *obj = ClassDB::instance(get_class());
ERR_FAIL_COND_V(!obj, nullptr);
node = Object::cast_to<Node>(obj);
- if (!node)
+ if (!node) {
memdelete(obj);
+ }
ERR_FAIL_COND_V(!node, nullptr);
}
@@ -2096,13 +2022,13 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
for (int i = 0; i < N->get()->get_child_count(); ++i) {
-
Node *descendant = N->get()->get_child(i);
// Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later
// but remember non-instanced nodes that are hidden below instanced ones
if (descendant->data.owner != this) {
- if (descendant->get_parent() && descendant->get_parent() != this && descendant->get_parent()->data.owner == this && descendant->data.owner != descendant->get_parent())
+ if (descendant->get_parent() && descendant->get_parent() != this && descendant->get_parent()->data.owner == this && descendant->data.owner != descendant->get_parent()) {
hidden_roots.push_back(descendant);
+ }
continue;
}
@@ -2112,7 +2038,6 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
}
for (List<const Node *>::Element *N = node_tree.front(); N; N = N->next()) {
-
Node *current_node = node->get_node(get_path_to(N->get()));
ERR_CONTINUE(!current_node);
@@ -2128,24 +2053,23 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
N->get()->get_property_list(&plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
String name = E->get().name;
- if (name == script_property_name)
+ if (name == script_property_name) {
continue;
+ }
Variant value = N->get()->get(name).duplicate(true);
if (E->get().usage & PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE) {
-
Resource *res = Object::cast_to<Resource>(value);
if (res) { // Duplicate only if it's a resource
current_node->set(name, res->duplicate());
}
} else {
-
current_node->set(name, value);
}
}
@@ -2156,18 +2080,19 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
}
#ifdef TOOLS_ENABLED
- if ((p_flags & DUPLICATE_FROM_EDITOR) && r_duplimap)
+ if ((p_flags & DUPLICATE_FROM_EDITOR) && r_duplimap) {
r_duplimap->insert(this, node);
+ }
#endif
if (p_flags & DUPLICATE_GROUPS) {
List<GroupInfo> gi;
get_groups(&gi);
for (List<GroupInfo>::Element *E = gi.front(); E; E = E->next()) {
-
#ifdef TOOLS_ENABLED
- if ((p_flags & DUPLICATE_FROM_EDITOR) && !E->get().persistent)
+ if ((p_flags & DUPLICATE_FROM_EDITOR) && !E->get().persistent) {
continue;
+ }
#endif
node->add_to_group(E->get().name, E->get().persistent);
@@ -2175,15 +2100,15 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
}
for (int i = 0; i < get_child_count(); i++) {
-
- if (get_child(i)->data.parent_owned)
+ if (get_child(i)->data.parent_owned) {
continue;
- if (instanced && get_child(i)->data.owner == this)
+ }
+ if (instanced && get_child(i)->data.owner == this) {
continue; //part of instance
+ }
Node *dup = get_child(i)->_duplicate(p_flags, r_duplimap);
if (!dup) {
-
memdelete(node);
return nullptr;
}
@@ -2195,17 +2120,14 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
}
for (List<const Node *>::Element *E = hidden_roots.front(); E; E = E->next()) {
-
Node *parent = node->get_node(get_path_to(E->get()->data.parent));
if (!parent) {
-
memdelete(node);
return nullptr;
}
Node *dup = E->get()->_duplicate(p_flags, r_duplimap);
if (!dup) {
-
memdelete(node);
return nullptr;
}
@@ -2214,7 +2136,6 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
int pos = E->get()->get_index();
if (pos < parent->get_child_count() - 1) {
-
parent->move_child(dup, pos);
}
}
@@ -2223,7 +2144,6 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
}
Node *Node::duplicate(int p_flags) const {
-
Node *dupe = _duplicate(p_flags);
if (dupe && (p_flags & DUPLICATE_SIGNALS)) {
@@ -2235,7 +2155,6 @@ Node *Node::duplicate(int p_flags) const {
#ifdef TOOLS_ENABLED
Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const {
-
Node *dupe = _duplicate(DUPLICATE_SIGNALS | DUPLICATE_GROUPS | DUPLICATE_SCRIPTS | DUPLICATE_USE_INSTANCING | DUPLICATE_FROM_EDITOR, &r_duplimap);
// Duplication of signals must happen after all the node descendants have been copied,
@@ -2248,20 +2167,18 @@ Node *Node::duplicate_from_editor(Map<const Node *, Node *> &r_duplimap) const {
#endif
void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const {
-
- if (get_owner() != get_parent()->get_owner())
+ if (get_owner() != get_parent()->get_owner()) {
return;
+ }
Node *node = nullptr;
if (get_filename() != "") {
-
Ref<PackedScene> res = ResourceLoader::load(get_filename());
ERR_FAIL_COND_MSG(res.is_null(), "Cannot load scene: " + get_filename());
node = res->instance();
ERR_FAIL_COND(!node);
} else {
-
Object *obj = ClassDB::instance(get_class());
ERR_FAIL_COND_MSG(!obj, "Node: Could not duplicate: " + String(get_class()) + ".");
node = Object::cast_to<Node>(obj);
@@ -2276,9 +2193,9 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p
get_property_list(&plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
String name = E->get().name;
Variant value = get(name).duplicate(true);
@@ -2289,16 +2206,18 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p
List<GroupInfo> groups;
get_groups(&groups);
- for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next())
+ for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) {
node->add_to_group(E->get().name, E->get().persistent);
+ }
node->set_name(get_name());
p_new_parent->add_child(node);
Node *owner = get_owner();
- if (p_reown_map.has(owner))
+ if (p_reown_map.has(owner)) {
owner = p_reown_map[owner];
+ }
if (owner) {
NodePath p = get_path_to(owner);
@@ -2311,7 +2230,6 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p
}
for (int i = 0; i < get_child_count(); i++) {
-
get_child(i)->_duplicate_and_reown(node, p_reown_map);
}
}
@@ -2320,15 +2238,14 @@ void Node::_duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p
// because re-targeting of connections from some descendant to another is not possible
// if the emitter node comes later in tree order than the receiver
void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const {
-
- if (this != p_original && (get_owner() != p_original && get_owner() != p_original->get_owner()))
+ if (this != p_original && (get_owner() != p_original && get_owner() != p_original->get_owner())) {
return;
+ }
List<Connection> conns;
get_all_signal_connections(&conns);
for (List<Connection>::Element *E = conns.front(); E; E = E->next()) {
-
if (E->get().flags & CONNECT_PERSIST) {
//user connected
NodePath p = p_original->get_path_to(this);
@@ -2346,8 +2263,9 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const {
// of the duplicated and not yet parented hierarchy then at least try to connect
// to the same target as the original
- if (p_copy->has_node(ptarget))
+ if (p_copy->has_node(ptarget)) {
copytarget = p_copy->get_node(ptarget);
+ }
if (copy && copytarget) {
const Callable copy_callable = Callable(copytarget, E->get().callable.get_method());
@@ -2364,7 +2282,6 @@ void Node::_duplicate_signals(const Node *p_original, Node *p_copy) const {
}
Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const {
-
ERR_FAIL_COND_V(get_filename() != "", nullptr);
Object *obj = ClassDB::instance(get_class());
@@ -2382,9 +2299,9 @@ Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const {
get_property_list(&plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
String name = E->get().name;
node->set(name, get(name));
}
@@ -2392,11 +2309,11 @@ Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const {
List<GroupInfo> groups;
get_groups(&groups);
- for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next())
+ for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) {
node->add_to_group(E->get().name, E->get().persistent);
+ }
for (int i = 0; i < get_child_count(); i++) {
-
get_child(i)->_duplicate_and_reown(node, p_reown_map);
}
@@ -2408,24 +2325,21 @@ Node *Node::duplicate_and_reown(const Map<Node *, Node *> &p_reown_map) const {
}
static void find_owned_by(Node *p_by, Node *p_node, List<Node *> *p_owned) {
-
- if (p_node->get_owner() == p_by)
+ if (p_node->get_owner() == p_by) {
p_owned->push_back(p_node);
+ }
for (int i = 0; i < p_node->get_child_count(); i++) {
-
find_owned_by(p_by, p_node->get_child(i), p_owned);
}
}
struct _NodeReplaceByPair {
-
String name;
Variant value;
};
void Node::replace_by(Node *p_node, bool p_keep_data) {
-
ERR_FAIL_NULL(p_node);
ERR_FAIL_COND(p_node->data.parent);
@@ -2436,15 +2350,14 @@ void Node::replace_by(Node *p_node, bool p_keep_data) {
List<_NodeReplaceByPair> replace_data;
if (p_keep_data) {
-
List<PropertyInfo> plist;
get_property_list(&plist);
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
_NodeReplaceByPair rd;
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
rd.name = E->get().name;
rd.value = get(rd.name);
}
@@ -2452,29 +2365,29 @@ void Node::replace_by(Node *p_node, bool p_keep_data) {
List<GroupInfo> groups;
get_groups(&groups);
- for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next())
+ for (List<GroupInfo>::Element *E = groups.front(); E; E = E->next()) {
p_node->add_to_group(E->get().name, E->get().persistent);
+ }
}
_replace_connections_target(p_node);
if (data.owner) {
- for (int i = 0; i < get_child_count(); i++)
+ for (int i = 0; i < get_child_count(); i++) {
find_owned_by(data.owner, get_child(i), &owned_by_owner);
+ }
}
Node *parent = data.parent;
int pos_in_parent = data.pos;
if (data.parent) {
-
parent->remove_child(this);
parent->add_child(p_node);
parent->move_child(p_node, pos_in_parent);
}
while (get_child_count()) {
-
Node *child = get_child(0);
remove_child(child);
if (!child->is_owned_by_parent()) {
@@ -2484,27 +2397,26 @@ void Node::replace_by(Node *p_node, bool p_keep_data) {
}
p_node->set_owner(owner);
- for (int i = 0; i < owned.size(); i++)
+ for (int i = 0; i < owned.size(); i++) {
owned[i]->set_owner(p_node);
+ }
- for (int i = 0; i < owned_by_owner.size(); i++)
+ for (int i = 0; i < owned_by_owner.size(); i++) {
owned_by_owner[i]->set_owner(owner);
+ }
p_node->set_filename(get_filename());
for (List<_NodeReplaceByPair>::Element *E = replace_data.front(); E; E = E->next()) {
-
p_node->set(E->get().name, E->get().value);
}
}
void Node::_replace_connections_target(Node *p_new_target) {
-
List<Connection> cl;
get_signals_connected_to_this(&cl);
for (List<Connection>::Element *E = cl.front(); E; E = E->next()) {
-
Connection &c = E->get();
if (c.flags & CONNECT_PERSIST) {
@@ -2517,41 +2429,45 @@ void Node::_replace_connections_target(Node *p_new_target) {
}
Vector<Variant> Node::make_binds(VARIANT_ARG_DECLARE) {
-
Vector<Variant> ret;
- if (p_arg1.get_type() == Variant::NIL)
+ if (p_arg1.get_type() == Variant::NIL) {
return ret;
- else
+ } else {
ret.push_back(p_arg1);
+ }
- if (p_arg2.get_type() == Variant::NIL)
+ if (p_arg2.get_type() == Variant::NIL) {
return ret;
- else
+ } else {
ret.push_back(p_arg2);
+ }
- if (p_arg3.get_type() == Variant::NIL)
+ if (p_arg3.get_type() == Variant::NIL) {
return ret;
- else
+ } else {
ret.push_back(p_arg3);
+ }
- if (p_arg4.get_type() == Variant::NIL)
+ if (p_arg4.get_type() == Variant::NIL) {
return ret;
- else
+ } else {
ret.push_back(p_arg4);
+ }
- if (p_arg5.get_type() == Variant::NIL)
+ if (p_arg5.get_type() == Variant::NIL) {
return ret;
- else
+ } else {
ret.push_back(p_arg5);
+ }
return ret;
}
bool Node::has_node_and_resource(const NodePath &p_path) const {
-
- if (!has_node(p_path))
+ if (!has_node(p_path)) {
return false;
+ }
RES res;
Vector<StringName> leftover_path;
Node *node = get_node_and_resource(p_path, res, leftover_path, false);
@@ -2560,21 +2476,22 @@ bool Node::has_node_and_resource(const NodePath &p_path) const {
}
Array Node::_get_node_and_resource(const NodePath &p_path) {
-
RES res;
Vector<StringName> leftover_path;
Node *node = get_node_and_resource(p_path, res, leftover_path, false);
Array result;
- if (node)
+ if (node) {
result.push_back(node);
- else
+ } else {
result.push_back(Variant());
+ }
- if (res.is_valid())
+ if (res.is_valid()) {
result.push_back(res);
- else
+ } else {
result.push_back(Variant());
+ }
result.push_back(NodePath(Vector<StringName>(), leftover_path, false));
@@ -2582,15 +2499,14 @@ Array Node::_get_node_and_resource(const NodePath &p_path) {
}
Node *Node::get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<StringName> &r_leftover_subpath, bool p_last_is_property) const {
-
Node *node = get_node(p_path);
r_res = RES();
r_leftover_subpath = Vector<StringName>();
- if (!node)
+ if (!node) {
return nullptr;
+ }
if (p_path.get_subname_count()) {
-
int j = 0;
// If not p_last_is_property, we shouldn't consider the last one as part of the resource
for (; j < p_path.get_subname_count() - (int)p_last_is_property; j++) {
@@ -2618,7 +2534,6 @@ Node *Node::get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<Str
}
void Node::_set_tree(SceneTree *p_tree) {
-
SceneTree *tree_changed_a = nullptr;
SceneTree *tree_changed_b = nullptr;
@@ -2633,7 +2548,6 @@ void Node::_set_tree(SceneTree *p_tree) {
data.tree = p_tree;
if (data.tree) {
-
_propagate_enter_tree();
if (!data.parent || data.parent->data.ready_notified) { // No parent (root) or parent ready
_propagate_ready(); //reverse_notification(NOTIFICATION_READY);
@@ -2642,21 +2556,24 @@ void Node::_set_tree(SceneTree *p_tree) {
tree_changed_b = data.tree;
}
- if (tree_changed_a)
+ if (tree_changed_a) {
tree_changed_a->tree_changed();
- if (tree_changed_b)
+ }
+ if (tree_changed_b) {
tree_changed_b->tree_changed();
+ }
}
#ifdef DEBUG_ENABLED
static void _Node_debug_sn(Object *p_obj) {
-
Node *n = Object::cast_to<Node>(p_obj);
- if (!n)
+ if (!n) {
return;
+ }
- if (n->is_inside_tree())
+ if (n->is_inside_tree()) {
return;
+ }
Node *p = n;
while (p->get_parent()) {
@@ -2664,28 +2581,26 @@ static void _Node_debug_sn(Object *p_obj) {
}
String path;
- if (p == n)
+ if (p == n) {
path = n->get_name();
- else
+ } else {
path = String(p->get_name()) + "/" + p->get_path_to(n);
+ }
print_line(itos(p_obj->get_instance_id()) + " - Stray Node: " + path + " (Type: " + n->get_class() + ")");
}
#endif // DEBUG_ENABLED
void Node::_print_stray_nodes() {
-
print_stray_nodes();
}
void Node::print_stray_nodes() {
-
#ifdef DEBUG_ENABLED
ObjectDB::debug_objects(_Node_debug_sn);
#endif
}
void Node::queue_delete() {
-
if (is_inside_tree()) {
get_tree()->queue_delete(this);
} else {
@@ -2693,26 +2608,24 @@ void Node::queue_delete() {
}
}
-Array Node::_get_children() const {
-
- Array arr;
+TypedArray<Node> Node::_get_children() const {
+ TypedArray<Node> arr;
int cc = get_child_count();
arr.resize(cc);
- for (int i = 0; i < cc; i++)
+ for (int i = 0; i < cc; i++) {
arr[i] = get_child(i);
+ }
return arr;
}
void Node::set_import_path(const NodePath &p_import_path) {
-
#ifdef TOOLS_ENABLED
data.import_path = p_import_path;
#endif
}
NodePath Node::get_import_path() const {
-
#ifdef TOOLS_ENABLED
return data.import_path;
#else
@@ -2721,15 +2634,15 @@ NodePath Node::get_import_path() const {
}
static void _add_nodes_to_options(const Node *p_base, const Node *p_node, List<String> *r_options) {
-
#ifdef TOOLS_ENABLED
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\"";
#else
const String quote_style = "\"";
#endif
- if (p_node != p_base && !p_node->get_owner())
+ if (p_node != p_base && !p_node->get_owner()) {
return;
+ }
String n = p_base->get_path_to(p_node);
r_options->push_back(quote_style + n + quote_style);
for (int i = 0; i < p_node->get_child_count(); i++) {
@@ -2738,17 +2651,14 @@ static void _add_nodes_to_options(const Node *p_base, const Node *p_node, List<S
}
void Node::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-
String pf = p_function;
if ((pf == "has_node" || pf == "get_node") && p_idx == 0) {
-
_add_nodes_to_options(this, this, r_options);
}
Object::get_argument_options(p_function, p_idx, r_options);
}
void Node::clear_internal_tree_resource_paths() {
-
clear_internal_resource_paths();
for (int i = 0; i < data.children.size(); i++) {
data.children[i]->clear_internal_tree_resource_paths();
@@ -2756,7 +2666,6 @@ void Node::clear_internal_tree_resource_paths() {
}
String Node::get_configuration_warning() const {
-
if (get_script_instance() && get_script_instance()->get_script().is_valid() &&
get_script_instance()->get_script()->is_tool() && get_script_instance()->has_method("_get_configuration_warning")) {
return get_script_instance()->call("_get_configuration_warning");
@@ -2765,10 +2674,10 @@ String Node::get_configuration_warning() const {
}
void Node::update_configuration_warning() {
-
#ifdef TOOLS_ENABLED
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
if (get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root() == this || get_tree()->get_edited_scene_root()->is_a_parent_of(this))) {
get_tree()->emit_signal(SceneStringNames::get_singleton()->node_configuration_warning_changed, this);
}
@@ -2784,7 +2693,6 @@ void Node::set_display_folded(bool p_folded) {
}
bool Node::is_displayed_folded() const {
-
return data.display_folded;
}
@@ -2793,13 +2701,12 @@ void Node::request_ready() {
}
void Node::_bind_methods() {
-
GLOBAL_DEF("node/name_num_separator", 0);
ProjectSettings::get_singleton()->set_custom_property_info("node/name_num_separator", PropertyInfo(Variant::INT, "node/name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash"));
GLOBAL_DEF("node/name_casing", NAME_CASING_PASCAL_CASE);
ProjectSettings::get_singleton()->set_custom_property_info("node/name_casing", PropertyInfo(Variant::INT, "node/name_casing", PROPERTY_HINT_ENUM, "PascalCase,camelCase,snake_case"));
- ClassDB::bind_method(D_METHOD("add_child_below_node", "preceding_node", "node", "legible_unique_name"), &Node::add_child_below_node, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("add_sibling", "sibling", "legible_unique_name"), &Node::add_sibling, DEFVAL(false));
ClassDB::bind_method(D_METHOD("set_name", "name"), &Node::set_name);
ClassDB::bind_method(D_METHOD("get_name"), &Node::get_name);
@@ -2994,16 +2901,19 @@ void Node::_bind_methods() {
String Node::_get_name_num_separator() {
switch (ProjectSettings::get_singleton()->get("node/name_num_separator").operator int()) {
- case 0: return "";
- case 1: return " ";
- case 2: return "_";
- case 3: return "-";
+ case 0:
+ return "";
+ case 1:
+ return " ";
+ case 2:
+ return "_";
+ case 3:
+ return "-";
}
return " ";
}
Node::Node() {
-
data.pos = -1;
data.depth = -1;
data.blocked = 0;
@@ -3037,7 +2947,6 @@ Node::Node() {
}
Node::~Node() {
-
data.grouped.clear();
data.owned.clear();
data.children.clear();
diff --git a/scene/main/node.h b/scene/main/node.h
index 5de07d506e..7595aabd9a 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -37,12 +37,12 @@
#include "core/object.h"
#include "core/project_settings.h"
#include "core/script_language.h"
+#include "core/typed_array.h"
#include "scene/main/scene_tree.h"
class Viewport;
class SceneState;
class Node : public Object {
-
GDCLASS(Node, Object);
OBJ_CATEGORY("Nodes");
@@ -66,12 +66,10 @@ public:
};
struct Comparator {
-
bool operator()(const Node *p_a, const Node *p_b) const { return p_b->is_greater_than(p_a); }
};
struct ComparatorWithPriority {
-
bool operator()(const Node *p_a, const Node *p_b) const { return p_b->data.process_priority == p_a->data.process_priority ? p_b->is_greater_than(p_a) : p_b->data.process_priority > p_a->data.process_priority; }
};
@@ -79,7 +77,6 @@ public:
private:
struct GroupData {
-
bool persistent;
SceneTree::Group *group;
GroupData() { persistent = false; }
@@ -91,7 +88,6 @@ private:
};
struct Data {
-
String filename;
Ref<SceneState> instance_state;
Ref<SceneState> inherited_state;
@@ -182,7 +178,7 @@ private:
void _duplicate_and_reown(Node *p_new_parent, const Map<Node *, Node *> &p_reown_map) const;
Node *_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap = nullptr) const;
- Array _get_children() const;
+ TypedArray<Node> _get_children() const;
Array _get_groups() const;
Variant _rpc_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
@@ -270,7 +266,7 @@ public:
void set_name(const String &p_name);
void add_child(Node *p_child, bool p_legible_unique_name = false);
- void add_child_below_node(Node *p_node, Node *p_child, bool p_legible_unique_name = false);
+ void add_sibling(Node *p_sibling, bool p_legible_unique_name = false);
void remove_child(Node *p_child);
int get_child_count() const;
@@ -304,7 +300,6 @@ public:
bool is_in_group(const StringName &p_identifier) const;
struct GroupInfo {
-
StringName name;
bool persistent;
};
diff --git a/scene/main/resource_preloader.cpp b/scene/main/resource_preloader.cpp
index 43a61834eb..c1d4435687 100644
--- a/scene/main/resource_preloader.cpp
+++ b/scene/main/resource_preloader.cpp
@@ -31,7 +31,6 @@
#include "resource_preloader.h"
void ResourcePreloader::_set_resources(const Array &p_data) {
-
resources.clear();
ERR_FAIL_COND(p_data.size() != 2);
@@ -41,7 +40,6 @@ void ResourcePreloader::_set_resources(const Array &p_data) {
ERR_FAIL_COND(names.size() != resdata.size());
for (int i = 0; i < resdata.size(); i++) {
-
String name = names[i];
RES resource = resdata[i];
ERR_CONTINUE(!resource.is_valid());
@@ -52,7 +50,6 @@ void ResourcePreloader::_set_resources(const Array &p_data) {
}
Array ResourcePreloader::_get_resources() const {
-
Vector<String> names;
Array arr;
arr.resize(resources.size());
@@ -66,7 +63,6 @@ Array ResourcePreloader::_get_resources() const {
int i = 0;
for (Set<String>::Element *E = sorted_names.front(); E; E = E->next()) {
-
names.set(i, E->get());
arr[i] = resources[E->get()];
i++;
@@ -79,15 +75,12 @@ Array ResourcePreloader::_get_resources() const {
}
void ResourcePreloader::add_resource(const StringName &p_name, const RES &p_resource) {
-
ERR_FAIL_COND(p_resource.is_null());
if (resources.has(p_name)) {
-
StringName new_name;
int idx = 2;
while (true) {
-
new_name = p_name.operator String() + " " + itos(idx);
if (resources.has(new_name)) {
idx++;
@@ -99,18 +92,16 @@ void ResourcePreloader::add_resource(const StringName &p_name, const RES &p_reso
add_resource(new_name, p_resource);
} else {
-
resources[p_name] = p_resource;
}
}
void ResourcePreloader::remove_resource(const StringName &p_name) {
-
ERR_FAIL_COND(!resources.has(p_name));
resources.erase(p_name);
}
-void ResourcePreloader::rename_resource(const StringName &p_from_name, const StringName &p_to_name) {
+void ResourcePreloader::rename_resource(const StringName &p_from_name, const StringName &p_to_name) {
ERR_FAIL_COND(!resources.has(p_from_name));
RES res = resources[p_from_name];
@@ -120,17 +111,15 @@ void ResourcePreloader::rename_resource(const StringName &p_from_name, const Str
}
bool ResourcePreloader::has_resource(const StringName &p_name) const {
-
return resources.has(p_name);
}
-RES ResourcePreloader::get_resource(const StringName &p_name) const {
+RES ResourcePreloader::get_resource(const StringName &p_name) const {
ERR_FAIL_COND_V(!resources.has(p_name), RES());
return resources[p_name];
}
Vector<String> ResourcePreloader::_get_resource_list() const {
-
Vector<String> res;
res.resize(resources.size());
int i = 0;
@@ -142,15 +131,12 @@ Vector<String> ResourcePreloader::_get_resource_list() const {
}
void ResourcePreloader::get_resource_list(List<StringName> *p_list) {
-
for (Map<StringName, RES>::Element *E = resources.front(); E; E = E->next()) {
-
p_list->push_back(E->key());
}
}
void ResourcePreloader::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_set_resources"), &ResourcePreloader::_set_resources);
ClassDB::bind_method(D_METHOD("_get_resources"), &ResourcePreloader::_get_resources);
diff --git a/scene/main/resource_preloader.h b/scene/main/resource_preloader.h
index 9ad219dd92..580dc35a57 100644
--- a/scene/main/resource_preloader.h
+++ b/scene/main/resource_preloader.h
@@ -34,7 +34,6 @@
#include "scene/main/node.h"
class ResourcePreloader : public Node {
-
GDCLASS(ResourcePreloader, Node);
Map<StringName, RES> resources;
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 0418b20e9c..a0e10f30c0 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -31,7 +31,7 @@
#include "scene_tree.h"
#include "core/debugger/engine_debugger.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/io/marshalls.h"
#include "core/io/resource_loader.h"
#include "core/message_queue.h"
@@ -56,7 +56,6 @@
#include <stdio.h>
void SceneTreeTimer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_time_left", "time"), &SceneTreeTimer::set_time_left);
ClassDB::bind_method(D_METHOD("get_time_left"), &SceneTreeTimer::get_time_left);
@@ -74,7 +73,6 @@ float SceneTreeTimer::get_time_left() const {
}
void SceneTreeTimer::set_pause_mode_process(bool p_pause_mode_process) {
-
process_pause = p_pause_mode_process;
}
@@ -83,7 +81,6 @@ bool SceneTreeTimer::is_pause_mode_process() {
}
void SceneTreeTimer::release_connections() {
-
List<Connection> connections;
get_all_signal_connections(&connections);
@@ -99,33 +96,29 @@ SceneTreeTimer::SceneTreeTimer() {
}
void SceneTree::tree_changed() {
-
tree_version++;
emit_signal(tree_changed_name);
}
void SceneTree::node_added(Node *p_node) {
-
emit_signal(node_added_name, p_node);
}
void SceneTree::node_removed(Node *p_node) {
-
if (current_scene == p_node) {
current_scene = nullptr;
}
emit_signal(node_removed_name, p_node);
- if (call_lock > 0)
+ if (call_lock > 0) {
call_skip.insert(p_node);
+ }
}
void SceneTree::node_renamed(Node *p_node) {
-
emit_signal(node_renamed_name, p_node);
}
SceneTree::Group *SceneTree::add_to_group(const StringName &p_group, Node *p_node) {
-
Map<StringName, Group>::Element *E = group_map.find(p_group);
if (!E) {
E = group_map.insert(p_group, Group());
@@ -139,26 +132,25 @@ SceneTree::Group *SceneTree::add_to_group(const StringName &p_group, Node *p_nod
}
void SceneTree::remove_from_group(const StringName &p_group, Node *p_node) {
-
Map<StringName, Group>::Element *E = group_map.find(p_group);
ERR_FAIL_COND(!E);
E->get().nodes.erase(p_node);
- if (E->get().nodes.empty())
+ if (E->get().nodes.empty()) {
group_map.erase(E);
+ }
}
void SceneTree::make_group_changed(const StringName &p_group) {
Map<StringName, Group>::Element *E = group_map.find(p_group);
- if (E)
+ if (E) {
E->get().changed = true;
+ }
}
void SceneTree::flush_transform_notifications() {
-
SelfList<Node> *n = xform_change_list.first();
while (n) {
-
Node *node = n->self();
SelfList<Node> *nx = n->next();
xform_change_list.remove(n);
@@ -168,16 +160,15 @@ void SceneTree::flush_transform_notifications() {
}
void SceneTree::_flush_ugc() {
-
ugc_locked = true;
while (unique_group_calls.size()) {
-
Map<UGCall, Vector<Variant>>::Element *E = unique_group_calls.front();
Variant v[VARIANT_ARG_MAX];
- for (int i = 0; i < E->get().size(); i++)
+ for (int i = 0; i < E->get().size(); i++) {
v[i] = E->get()[i];
+ }
call_group_flags(GROUP_CALL_REALTIME, E->key().group, E->key().call, v[0], v[1], v[2], v[3], v[4]);
@@ -188,11 +179,12 @@ void SceneTree::_flush_ugc() {
}
void SceneTree::_update_group_order(Group &g, bool p_use_priority) {
-
- if (!g.changed)
+ if (!g.changed) {
return;
- if (g.nodes.empty())
+ }
+ if (g.nodes.empty()) {
return;
+ }
Node **nodes = g.nodes.ptrw();
int node_count = g.nodes.size();
@@ -208,31 +200,33 @@ void SceneTree::_update_group_order(Group &g, bool p_use_priority) {
}
void SceneTree::call_group_flags(uint32_t p_call_flags, const StringName &p_group, const StringName &p_function, VARIANT_ARG_DECLARE) {
-
Map<StringName, Group>::Element *E = group_map.find(p_group);
- if (!E)
+ if (!E) {
return;
+ }
Group &g = E->get();
- if (g.nodes.empty())
+ if (g.nodes.empty()) {
return;
+ }
if (p_call_flags & GROUP_CALL_UNIQUE && !(p_call_flags & GROUP_CALL_REALTIME)) {
-
ERR_FAIL_COND(ugc_locked);
UGCall ug;
ug.call = p_function;
ug.group = p_group;
- if (unique_group_calls.has(ug))
+ if (unique_group_calls.has(ug)) {
return;
+ }
VARIANT_ARGPTRS;
Vector<Variant> args;
for (int i = 0; i < VARIANT_ARG_MAX; i++) {
- if (argptr[i]->get_type() == Variant::NIL)
+ if (argptr[i]->get_type() == Variant::NIL) {
break;
+ }
args.push_back(*argptr[i]);
}
@@ -249,51 +243,55 @@ void SceneTree::call_group_flags(uint32_t p_call_flags, const StringName &p_grou
call_lock++;
if (p_call_flags & GROUP_CALL_REVERSE) {
-
for (int i = node_count - 1; i >= 0; i--) {
-
- if (call_lock && call_skip.has(nodes[i]))
+ if (call_lock && call_skip.has(nodes[i])) {
continue;
+ }
if (p_call_flags & GROUP_CALL_REALTIME) {
- if (p_call_flags & GROUP_CALL_MULTILEVEL)
+ if (p_call_flags & GROUP_CALL_MULTILEVEL) {
nodes[i]->call_multilevel(p_function, VARIANT_ARG_PASS);
- else
+ } else {
nodes[i]->call(p_function, VARIANT_ARG_PASS);
- } else
+ }
+ } else {
MessageQueue::get_singleton()->push_call(nodes[i], p_function, VARIANT_ARG_PASS);
+ }
}
} else {
-
for (int i = 0; i < node_count; i++) {
-
- if (call_lock && call_skip.has(nodes[i]))
+ if (call_lock && call_skip.has(nodes[i])) {
continue;
+ }
if (p_call_flags & GROUP_CALL_REALTIME) {
- if (p_call_flags & GROUP_CALL_MULTILEVEL)
+ if (p_call_flags & GROUP_CALL_MULTILEVEL) {
nodes[i]->call_multilevel(p_function, VARIANT_ARG_PASS);
- else
+ } else {
nodes[i]->call(p_function, VARIANT_ARG_PASS);
- } else
+ }
+ } else {
MessageQueue::get_singleton()->push_call(nodes[i], p_function, VARIANT_ARG_PASS);
+ }
}
}
call_lock--;
- if (call_lock == 0)
+ if (call_lock == 0) {
call_skip.clear();
+ }
}
void SceneTree::notify_group_flags(uint32_t p_call_flags, const StringName &p_group, int p_notification) {
-
Map<StringName, Group>::Element *E = group_map.find(p_group);
- if (!E)
+ if (!E) {
return;
+ }
Group &g = E->get();
- if (g.nodes.empty())
+ if (g.nodes.empty()) {
return;
+ }
_update_group_order(g);
@@ -304,45 +302,47 @@ void SceneTree::notify_group_flags(uint32_t p_call_flags, const StringName &p_gr
call_lock++;
if (p_call_flags & GROUP_CALL_REVERSE) {
-
for (int i = node_count - 1; i >= 0; i--) {
-
- if (call_lock && call_skip.has(nodes[i]))
+ if (call_lock && call_skip.has(nodes[i])) {
continue;
+ }
- if (p_call_flags & GROUP_CALL_REALTIME)
+ if (p_call_flags & GROUP_CALL_REALTIME) {
nodes[i]->notification(p_notification);
- else
+ } else {
MessageQueue::get_singleton()->push_notification(nodes[i], p_notification);
+ }
}
} else {
-
for (int i = 0; i < node_count; i++) {
-
- if (call_lock && call_skip.has(nodes[i]))
+ if (call_lock && call_skip.has(nodes[i])) {
continue;
+ }
- if (p_call_flags & GROUP_CALL_REALTIME)
+ if (p_call_flags & GROUP_CALL_REALTIME) {
nodes[i]->notification(p_notification);
- else
+ } else {
MessageQueue::get_singleton()->push_notification(nodes[i], p_notification);
+ }
}
}
call_lock--;
- if (call_lock == 0)
+ if (call_lock == 0) {
call_skip.clear();
+ }
}
void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group, const String &p_name, const Variant &p_value) {
-
Map<StringName, Group>::Element *E = group_map.find(p_group);
- if (!E)
+ if (!E) {
return;
+ }
Group &g = E->get();
- if (g.nodes.empty())
+ if (g.nodes.empty()) {
return;
+ }
_update_group_order(g);
@@ -353,35 +353,36 @@ void SceneTree::set_group_flags(uint32_t p_call_flags, const StringName &p_group
call_lock++;
if (p_call_flags & GROUP_CALL_REVERSE) {
-
for (int i = node_count - 1; i >= 0; i--) {
-
- if (call_lock && call_skip.has(nodes[i]))
+ if (call_lock && call_skip.has(nodes[i])) {
continue;
+ }
- if (p_call_flags & GROUP_CALL_REALTIME)
+ if (p_call_flags & GROUP_CALL_REALTIME) {
nodes[i]->set(p_name, p_value);
- else
+ } else {
MessageQueue::get_singleton()->push_set(nodes[i], p_name, p_value);
+ }
}
} else {
-
for (int i = 0; i < node_count; i++) {
-
- if (call_lock && call_skip.has(nodes[i]))
+ if (call_lock && call_skip.has(nodes[i])) {
continue;
+ }
- if (p_call_flags & GROUP_CALL_REALTIME)
+ if (p_call_flags & GROUP_CALL_REALTIME) {
nodes[i]->set(p_name, p_value);
- else
+ } else {
MessageQueue::get_singleton()->push_set(nodes[i], p_name, p_value);
+ }
}
}
call_lock--;
- if (call_lock == 0)
+ if (call_lock == 0) {
call_skip.clear();
+ }
}
void SceneTree::call_group(const StringName &p_group, const StringName &p_function, VARIANT_ARG_DECLARE) {
@@ -389,12 +390,10 @@ void SceneTree::call_group(const StringName &p_group, const StringName &p_functi
}
void SceneTree::notify_group(const StringName &p_group, int p_notification) {
-
notify_group_flags(0, p_group, p_notification);
}
void SceneTree::set_group(const StringName &p_group, const String &p_name, const Variant &p_value) {
-
set_group_flags(0, p_group, p_name, p_value);
}
@@ -405,7 +404,6 @@ void SceneTree::init() {
}
bool SceneTree::iteration(float p_time) {
-
root_lock++;
current_frame++;
@@ -432,7 +430,6 @@ bool SceneTree::iteration(float p_time) {
}
bool SceneTree::idle(float p_time) {
-
//print_line("ram: "+itos(OS::get_singleton()->get_static_memory_usage())+" sram: "+itos(OS::get_singleton()->get_dynamic_memory_usage()));
//print_line("node count: "+itos(get_node_count()));
//print_line("TEXTURE RAM: "+itos(RS::get_singleton()->get_render_info(RS::INFO_TEXTURE_MEM_USED)));
@@ -470,7 +467,6 @@ bool SceneTree::idle(float p_time) {
List<Ref<SceneTreeTimer>>::Element *L = timers.back(); //last element
for (List<Ref<SceneTreeTimer>>::Element *E = timers.front(); E;) {
-
List<Ref<SceneTreeTimer>>::Element *N = E->next();
if (pause && !E->get()->is_pause_mode_process()) {
if (E == L) {
@@ -504,12 +500,11 @@ bool SceneTree::idle(float p_time) {
String env_path = ProjectSettings::get_singleton()->get("rendering/environment/default_environment");
env_path = env_path.strip_edges(); //user may have added a space or two
String cpath;
- Ref<Environment> fallback = get_root()->get_world()->get_fallback_environment();
+ Ref<Environment> fallback = get_root()->get_world_3d()->get_fallback_environment();
if (fallback.is_valid()) {
cpath = fallback->get_path();
}
if (cpath != env_path) {
-
if (env_path != String()) {
fallback = ResourceLoader::load(env_path);
if (fallback.is_null()) {
@@ -519,7 +514,7 @@ bool SceneTree::idle(float p_time) {
} else {
fallback.unref();
}
- get_root()->get_world()->set_fallback_environment(fallback);
+ get_root()->get_world_3d()->set_fallback_environment(fallback);
}
}
@@ -529,7 +524,6 @@ bool SceneTree::idle(float p_time) {
}
void SceneTree::finish() {
-
_flush_delete_queue();
_flush_ugc();
@@ -553,7 +547,6 @@ void SceneTree::finish() {
}
void SceneTree::quit(int p_exit_code) {
-
if (p_exit_code >= 0) {
// Override the exit code if a positive argument is given (the default is `-1`).
// This is a shorthand for calling `set_exit_code()` on the OS singleton then quitting.
@@ -564,11 +557,11 @@ void SceneTree::quit(int p_exit_code) {
}
void SceneTree::_main_window_close() {
-
if (accept_quit) {
_quit = true;
}
}
+
void SceneTree::_main_window_go_back() {
if (quit_on_go_back) {
_quit = true;
@@ -576,16 +569,14 @@ void SceneTree::_main_window_go_back() {
}
void SceneTree::_main_window_focus_in() {
- InputFilter *id = InputFilter::get_singleton();
+ Input *id = Input::get_singleton();
if (id) {
id->ensure_touch_mouse_raised();
}
}
void SceneTree::_notification(int p_notification) {
-
switch (p_notification) {
-
case NOTIFICATION_TRANSLATION_CHANGED: {
if (!Engine::get_singleton()->is_editor_hint()) {
get_root()->propagate_notification(p_notification);
@@ -597,7 +588,6 @@ void SceneTree::_notification(int p_notification) {
case NOTIFICATION_CRASH:
case NOTIFICATION_APP_RESUMED:
case NOTIFICATION_APP_PAUSED: {
-
get_root()->propagate_notification(p_notification);
} break;
@@ -607,89 +597,74 @@ void SceneTree::_notification(int p_notification) {
};
void SceneTree::set_auto_accept_quit(bool p_enable) {
-
accept_quit = p_enable;
}
void SceneTree::set_quit_on_go_back(bool p_enable) {
-
quit_on_go_back = p_enable;
}
#ifdef TOOLS_ENABLED
bool SceneTree::is_node_being_edited(const Node *p_node) const {
-
return Engine::get_singleton()->is_editor_hint() && edited_scene_root && (edited_scene_root->is_a_parent_of(p_node) || edited_scene_root == p_node);
}
#endif
#ifdef DEBUG_ENABLED
void SceneTree::set_debug_collisions_hint(bool p_enabled) {
-
debug_collisions_hint = p_enabled;
}
bool SceneTree::is_debugging_collisions_hint() const {
-
return debug_collisions_hint;
}
void SceneTree::set_debug_navigation_hint(bool p_enabled) {
-
debug_navigation_hint = p_enabled;
}
bool SceneTree::is_debugging_navigation_hint() const {
-
return debug_navigation_hint;
}
#endif
void SceneTree::set_debug_collisions_color(const Color &p_color) {
-
debug_collisions_color = p_color;
}
Color SceneTree::get_debug_collisions_color() const {
-
return debug_collisions_color;
}
void SceneTree::set_debug_collision_contact_color(const Color &p_color) {
-
debug_collision_contact_color = p_color;
}
Color SceneTree::get_debug_collision_contact_color() const {
-
return debug_collision_contact_color;
}
void SceneTree::set_debug_navigation_color(const Color &p_color) {
-
debug_navigation_color = p_color;
}
Color SceneTree::get_debug_navigation_color() const {
-
return debug_navigation_color;
}
void SceneTree::set_debug_navigation_disabled_color(const Color &p_color) {
-
debug_navigation_disabled_color = p_color;
}
Color SceneTree::get_debug_navigation_disabled_color() const {
-
return debug_navigation_disabled_color;
}
Ref<Material> SceneTree::get_debug_navigation_material() {
-
- if (navigation_material.is_valid())
+ if (navigation_material.is_valid()) {
return navigation_material;
+ }
Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
@@ -704,9 +679,9 @@ Ref<Material> SceneTree::get_debug_navigation_material() {
}
Ref<Material> SceneTree::get_debug_navigation_disabled_material() {
-
- if (navigation_disabled_material.is_valid())
+ if (navigation_disabled_material.is_valid()) {
return navigation_disabled_material;
+ }
Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
@@ -719,10 +694,11 @@ Ref<Material> SceneTree::get_debug_navigation_disabled_material() {
return navigation_disabled_material;
}
-Ref<Material> SceneTree::get_debug_collision_material() {
- if (collision_material.is_valid())
+Ref<Material> SceneTree::get_debug_collision_material() {
+ if (collision_material.is_valid()) {
return collision_material;
+ }
Ref<StandardMaterial3D> line_material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
line_material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
@@ -737,9 +713,9 @@ Ref<Material> SceneTree::get_debug_collision_material() {
}
Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() {
-
- if (debug_contact_mesh.is_valid())
+ if (debug_contact_mesh.is_valid()) {
return debug_contact_mesh;
+ }
debug_contact_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
@@ -773,12 +749,14 @@ Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() {
/* clang-format on */
Vector<int> indices;
- for (int i = 0; i < 8 * 3; i++)
+ for (int i = 0; i < 8 * 3; i++) {
indices.push_back(diamond_faces[i]);
+ }
Vector<Vector3> vertices;
- for (int i = 0; i < 6; i++)
+ for (int i = 0; i < 6; i++) {
vertices.push_back(diamond[i] * 0.1);
+ }
Array arr;
arr.resize(Mesh::ARRAY_MAX);
@@ -792,30 +770,31 @@ Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() {
}
void SceneTree::set_pause(bool p_enabled) {
-
- if (p_enabled == pause)
+ if (p_enabled == pause) {
return;
+ }
pause = p_enabled;
NavigationServer3D::get_singleton()->set_active(!p_enabled);
PhysicsServer3D::get_singleton()->set_active(!p_enabled);
PhysicsServer2D::get_singleton()->set_active(!p_enabled);
- if (get_root())
+ if (get_root()) {
get_root()->propagate_notification(p_enabled ? Node::NOTIFICATION_PAUSED : Node::NOTIFICATION_UNPAUSED);
+ }
}
bool SceneTree::is_paused() const {
-
return pause;
}
void SceneTree::_notify_group_pause(const StringName &p_group, int p_notification) {
-
Map<StringName, Group>::Element *E = group_map.find(p_group);
- if (!E)
+ if (!E) {
return;
+ }
Group &g = E->get();
- if (g.nodes.empty())
+ if (g.nodes.empty()) {
return;
+ }
_update_group_order(g, p_notification == Node::NOTIFICATION_PROCESS || p_notification == Node::NOTIFICATION_INTERNAL_PROCESS || p_notification == Node::NOTIFICATION_PHYSICS_PROCESS || p_notification == Node::NOTIFICATION_INTERNAL_PHYSICS_PROCESS);
@@ -829,23 +808,26 @@ void SceneTree::_notify_group_pause(const StringName &p_group, int p_notificatio
call_lock++;
for (int i = 0; i < node_count; i++) {
-
Node *n = nodes[i];
- if (call_lock && call_skip.has(n))
+ if (call_lock && call_skip.has(n)) {
continue;
+ }
- if (!n->can_process())
+ if (!n->can_process()) {
continue;
- if (!n->can_process_notification(p_notification))
+ }
+ if (!n->can_process_notification(p_notification)) {
continue;
+ }
n->notification(p_notification);
//ERR_FAIL_COND(node_count != g.nodes.size());
}
call_lock--;
- if (call_lock == 0)
+ if (call_lock == 0) {
call_skip.clear();
+ }
}
/*
@@ -857,16 +839,18 @@ void SceneMainLoop::_update_listener_2d() {
}
}
+
*/
void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input, Viewport *p_viewport) {
-
Map<StringName, Group>::Element *E = group_map.find(p_group);
- if (!E)
+ if (!E) {
return;
+ }
Group &g = E->get();
- if (g.nodes.empty())
+ if (g.nodes.empty()) {
return;
+ }
_update_group_order(g);
@@ -883,27 +867,30 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p
call_lock++;
for (int i = node_count - 1; i >= 0; i--) {
-
- if (p_viewport->is_input_handled())
+ if (p_viewport->is_input_handled()) {
break;
+ }
Node *n = nodes[i];
- if (call_lock && call_skip.has(n))
+ if (call_lock && call_skip.has(n)) {
continue;
+ }
- if (!n->can_process())
+ if (!n->can_process()) {
continue;
+ }
n->call_multilevel(p_method, (const Variant **)v, 1);
//ERR_FAIL_COND(node_count != g.nodes.size());
}
call_lock--;
- if (call_lock == 0)
+ if (call_lock == 0) {
call_skip.clear();
+ }
}
-Variant SceneTree::_call_group_flags(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
+Variant SceneTree::_call_group_flags(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
r_error.error = Callable::CallError::CALL_OK;
ERR_FAIL_COND_V(p_argcount < 3, Variant());
@@ -917,7 +904,6 @@ Variant SceneTree::_call_group_flags(const Variant **p_args, int p_argcount, Cal
Variant v[VARIANT_ARG_MAX];
for (int i = 0; i < MIN(p_argcount - 3, 5); i++) {
-
v[i] = *p_args[i + 3];
}
@@ -926,7 +912,6 @@ Variant SceneTree::_call_group_flags(const Variant **p_args, int p_argcount, Cal
}
Variant SceneTree::_call_group(const Variant **p_args, int p_argcount, Callable::CallError &r_error) {
-
r_error.error = Callable::CallError::CALL_OK;
ERR_FAIL_COND_V(p_argcount < 2, Variant());
@@ -938,7 +923,6 @@ Variant SceneTree::_call_group(const Variant **p_args, int p_argcount, Callable:
Variant v[VARIANT_ARG_MAX];
for (int i = 0; i < MIN(p_argcount - 2, 5); i++) {
-
v[i] = *p_args[i + 2];
}
@@ -947,31 +931,30 @@ Variant SceneTree::_call_group(const Variant **p_args, int p_argcount, Callable:
}
int64_t SceneTree::get_frame() const {
-
return current_frame;
}
-int64_t SceneTree::get_event_count() const {
+int64_t SceneTree::get_event_count() const {
return current_event;
}
Array SceneTree::_get_nodes_in_group(const StringName &p_group) {
-
Array ret;
Map<StringName, Group>::Element *E = group_map.find(p_group);
- if (!E)
+ if (!E) {
return ret;
+ }
_update_group_order(E->get()); //update order just in case
int nc = E->get().nodes.size();
- if (nc == 0)
+ if (nc == 0) {
return ret;
+ }
ret.resize(nc);
Node **ptr = E->get().nodes.ptrw();
for (int i = 0; i < nc; i++) {
-
ret[i] = ptr[i];
}
@@ -979,32 +962,30 @@ Array SceneTree::_get_nodes_in_group(const StringName &p_group) {
}
bool SceneTree::has_group(const StringName &p_identifier) const {
-
return group_map.has(p_identifier);
}
-void SceneTree::get_nodes_in_group(const StringName &p_group, List<Node *> *p_list) {
+void SceneTree::get_nodes_in_group(const StringName &p_group, List<Node *> *p_list) {
Map<StringName, Group>::Element *E = group_map.find(p_group);
- if (!E)
+ if (!E) {
return;
+ }
_update_group_order(E->get()); //update order just in case
int nc = E->get().nodes.size();
- if (nc == 0)
+ if (nc == 0) {
return;
+ }
Node **ptr = E->get().nodes.ptrw();
for (int i = 0; i < nc; i++) {
-
p_list->push_back(ptr[i]);
}
}
void SceneTree::_flush_delete_queue() {
-
_THREAD_SAFE_METHOD_
while (delete_queue.size()) {
-
Object *obj = ObjectDB::get_instance(delete_queue.front()->get());
if (obj) {
memdelete(obj);
@@ -1014,7 +995,6 @@ void SceneTree::_flush_delete_queue() {
}
void SceneTree::queue_delete(Object *p_object) {
-
_THREAD_SAFE_METHOD_
ERR_FAIL_NULL(p_object);
p_object->_is_queued_for_deletion = true;
@@ -1022,7 +1002,6 @@ void SceneTree::queue_delete(Object *p_object) {
}
int SceneTree::get_node_count() const {
-
return node_count;
}
@@ -1033,7 +1012,6 @@ void SceneTree::set_edited_scene_root(Node *p_node) {
}
Node *SceneTree::get_edited_scene_root() const {
-
#ifdef TOOLS_ENABLED
return edited_scene_root;
#else
@@ -1042,18 +1020,15 @@ Node *SceneTree::get_edited_scene_root() const {
}
void SceneTree::set_current_scene(Node *p_scene) {
-
ERR_FAIL_COND(p_scene && p_scene->get_parent() != root);
current_scene = p_scene;
}
Node *SceneTree::get_current_scene() const {
-
return current_scene;
}
void SceneTree::_change_scene(Node *p_to) {
-
if (current_scene) {
memdelete(current_scene);
current_scene = nullptr;
@@ -1075,8 +1050,9 @@ void SceneTree::_change_scene(Node *p_to) {
Error SceneTree::change_scene(const String &p_path) {
Ref<PackedScene> new_scene = ResourceLoader::load(p_path);
- if (new_scene.is_null())
+ if (new_scene.is_null()) {
return ERR_CANT_OPEN;
+ }
return change_scene_to(new_scene);
}
@@ -1099,13 +1075,11 @@ Error SceneTree::reload_current_scene() {
}
void SceneTree::add_current_scene(Node *p_current) {
-
current_scene = p_current;
root->add_child(p_current);
}
Ref<SceneTreeTimer> SceneTree::create_timer(float p_delay_sec, bool p_process_pause) {
-
Ref<SceneTreeTimer> stt;
stt.instance();
stt->set_pause_mode_process(p_process_pause);
@@ -1115,27 +1089,22 @@ Ref<SceneTreeTimer> SceneTree::create_timer(float p_delay_sec, bool p_process_pa
}
void SceneTree::_network_peer_connected(int p_id) {
-
emit_signal("network_peer_connected", p_id);
}
void SceneTree::_network_peer_disconnected(int p_id) {
-
emit_signal("network_peer_disconnected", p_id);
}
void SceneTree::_connected_to_server() {
-
emit_signal("connected_to_server");
}
void SceneTree::_connection_failed() {
-
emit_signal("connection_failed");
}
void SceneTree::_server_disconnected() {
-
emit_signal("server_disconnected");
}
@@ -1173,17 +1142,14 @@ void SceneTree::set_multiplayer(Ref<MultiplayerAPI> p_multiplayer) {
}
void SceneTree::set_network_peer(const Ref<NetworkedMultiplayerPeer> &p_network_peer) {
-
multiplayer->set_network_peer(p_network_peer);
}
Ref<NetworkedMultiplayerPeer> SceneTree::get_network_peer() const {
-
return multiplayer->get_network_peer();
}
bool SceneTree::is_network_server() const {
-
return multiplayer->is_network_server();
}
@@ -1192,12 +1158,10 @@ bool SceneTree::has_network_peer() const {
}
int SceneTree::get_network_unique_id() const {
-
return multiplayer->get_network_unique_id();
}
Vector<int> SceneTree::get_network_connected_peers() const {
-
return multiplayer->get_network_connected_peers();
}
@@ -1214,7 +1178,6 @@ bool SceneTree::is_refusing_new_network_connections() const {
}
void SceneTree::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_root"), &SceneTree::get_root);
ClassDB::bind_method(D_METHOD("has_group", "name"), &SceneTree::has_group);
@@ -1327,7 +1290,6 @@ SceneTree::IdleCallback SceneTree::idle_callbacks[SceneTree::MAX_IDLE_CALLBACKS]
int SceneTree::idle_callback_count = 0;
void SceneTree::_call_idle_callbacks() {
-
for (int i = 0; i < idle_callback_count; i++) {
idle_callbacks[i]();
}
@@ -1339,7 +1301,6 @@ void SceneTree::add_idle_callback(IdleCallback p_callback) {
}
void SceneTree::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-
if (p_function == "change_scene") {
DirAccessRef dir_access = DirAccess::create(DirAccess::ACCESS_RESOURCES);
List<String> directories;
@@ -1371,8 +1332,9 @@ void SceneTree::get_argument_options(const StringName &p_function, int p_idx, Li
}
SceneTree::SceneTree() {
-
- if (singleton == nullptr) singleton = this;
+ if (singleton == nullptr) {
+ singleton = this;
+ }
_quit = false;
accept_quit = true;
quit_on_go_back = true;
@@ -1409,8 +1371,9 @@ SceneTree::SceneTree() {
root = memnew(Window);
root->set_name("root");
- if (!root->get_world().is_valid())
- root->set_world(Ref<World3D>(memnew(World3D)));
+ if (!root->get_world_3d().is_valid()) {
+ root->set_world_3d(Ref<World3D>(memnew(World3D)));
+ }
// Initialize network state
multiplayer_poll = true;
@@ -1422,11 +1385,11 @@ SceneTree::SceneTree() {
current_scene = nullptr;
int msaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/msaa", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/msaa", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Fast),4x (Average),8x (Slow),16x (Slower)"));
root->set_msaa(Viewport::MSAA(msaa_mode));
int ssaa_mode = GLOBAL_DEF("rendering/quality/screen_filters/screen_space_aa", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_aa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled,FXAA"));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/screen_filters/screen_space_aa", PropertyInfo(Variant::INT, "rendering/quality/screen_filters/screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"));
root->set_screen_space_aa(Viewport::ScreenSpaceAA(ssaa_mode));
{ //load default fallback environment
@@ -1435,8 +1398,9 @@ SceneTree::SceneTree() {
ResourceLoader::get_recognized_extensions_for_type("Environment", &exts);
String ext_hint;
for (List<String>::Element *E = exts.front(); E; E = E->next()) {
- if (ext_hint != String())
+ if (ext_hint != String()) {
ext_hint += ",";
+ }
ext_hint += "*." + E->get();
}
//get path
@@ -1447,7 +1411,7 @@ SceneTree::SceneTree() {
if (env_path != String()) {
Ref<Environment> env = ResourceLoader::load(env_path);
if (env.is_valid()) {
- root->get_world()->set_fallback_environment(env);
+ root->get_world_3d()->set_fallback_environment(env);
} else {
if (Engine::get_singleton()->is_editor_hint()) {
//file was erased, clear the field.
@@ -1478,5 +1442,7 @@ SceneTree::~SceneTree() {
memdelete(root);
}
- if (singleton == this) singleton = nullptr;
+ if (singleton == this) {
+ singleton = nullptr;
+ }
}
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index 319b5a7e74..57b6b4dcfa 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -70,7 +70,6 @@ public:
};
class SceneTree : public MainLoop {
-
_THREAD_SAFE_CLASS_
GDCLASS(SceneTree, MainLoop);
@@ -80,7 +79,6 @@ public:
private:
struct Group {
-
Vector<Node *> nodes;
//uint64_t last_tree_version;
bool changed;
@@ -119,7 +117,6 @@ private:
Node *edited_scene_root;
#endif
struct UGCall {
-
StringName group;
StringName call;
diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp
index 13582cf655..726dcb58de 100644
--- a/scene/main/shader_globals_override.cpp
+++ b/scene/main/shader_globals_override.cpp
@@ -1,3 +1,33 @@
+/*************************************************************************/
+/* shader_globals_override.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#include "shader_globals_override.h"
#include "core/core_string_names.h"
@@ -5,7 +35,6 @@
#include "scene/scene_string_names.h"
StringName *ShaderGlobalsOverride::_remap(const StringName &p_name) const {
-
StringName *r = param_remaps.getptr(p_name);
if (!r) {
//not cached, do caching
@@ -19,8 +48,8 @@ StringName *ShaderGlobalsOverride::_remap(const StringName &p_name) const {
return r;
}
-bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_value) {
+bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_value) {
StringName *r = _remap(p_name);
if (r) {
@@ -45,7 +74,6 @@ bool ShaderGlobalsOverride::_set(const StringName &p_name, const Variant &p_valu
}
bool ShaderGlobalsOverride::_get(const StringName &p_name, Variant &r_ret) const {
-
StringName *r = _remap(p_name);
if (r) {
@@ -60,7 +88,6 @@ bool ShaderGlobalsOverride::_get(const StringName &p_name, Variant &r_ret) const
}
void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const {
-
Vector<StringName> variables;
variables = RS::get_singleton()->global_variable_get_list();
for (int i = 0; i < variables.size(); i++) {
@@ -168,7 +195,6 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const
pinfo.hint_string = "Cubemap";
} break;
default: {
-
} break;
}
@@ -176,7 +202,7 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const
Override o;
o.in_use = false;
Callable::CallError ce;
- o.override = Variant::construct(pinfo.type, NULL, 0, ce);
+ o.override = Variant::construct(pinfo.type, nullptr, 0, ce);
overrides[variables[i]] = o;
}
@@ -191,7 +217,6 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const
}
void ShaderGlobalsOverride::_activate() {
-
List<Node *> nodes;
get_tree()->get_nodes_in_group(SceneStringNames::get_singleton()->shader_overrides_group_active, &nodes);
if (nodes.size() == 0) {
@@ -212,14 +237,11 @@ void ShaderGlobalsOverride::_activate() {
}
void ShaderGlobalsOverride::_notification(int p_what) {
-
if (p_what == Node3D::NOTIFICATION_ENTER_TREE) {
-
add_to_group(SceneStringNames::get_singleton()->shader_overrides_group);
_activate();
} else if (p_what == Node3D::NOTIFICATION_EXIT_TREE) {
-
if (active) {
//remove overrides
const StringName *K = nullptr;
@@ -239,7 +261,6 @@ void ShaderGlobalsOverride::_notification(int p_what) {
}
String ShaderGlobalsOverride::get_configuration_warning() const {
-
if (!active) {
return TTR("ShaderGlobalsOverride is not active because another node of the same type is in the scene.");
}
@@ -248,7 +269,6 @@ String ShaderGlobalsOverride::get_configuration_warning() const {
}
void ShaderGlobalsOverride::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("_activate"), &ShaderGlobalsOverride::_activate);
}
diff --git a/scene/main/shader_globals_override.h b/scene/main/shader_globals_override.h
index 33d0dc948f..51420e00cf 100644
--- a/scene/main/shader_globals_override.h
+++ b/scene/main/shader_globals_override.h
@@ -1,10 +1,39 @@
+/*************************************************************************/
+/* shader_globals_override.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
#ifndef SHADER_GLOBALS_OVERRIDE_H
#define SHADER_GLOBALS_OVERRIDE_H
#include "scene/3d/node_3d.h"
class ShaderGlobalsOverride : public Node {
-
GDCLASS(ShaderGlobalsOverride, Node);
struct Override {
diff --git a/scene/main/timer.cpp b/scene/main/timer.cpp
index 7c847095e1..fb55892b54 100644
--- a/scene/main/timer.cpp
+++ b/scene/main/timer.cpp
@@ -33,45 +33,47 @@
#include "core/engine.h"
void Timer::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_READY: {
-
if (autostart) {
#ifdef TOOLS_ENABLED
- if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root() == this || get_tree()->get_edited_scene_root()->is_a_parent_of(this)))
+ if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && (get_tree()->get_edited_scene_root() == this || get_tree()->get_edited_scene_root()->is_a_parent_of(this))) {
break;
+ }
#endif
start();
autostart = false;
}
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
- if (timer_process_mode == TIMER_PROCESS_PHYSICS || !is_processing_internal())
+ if (timer_process_mode == TIMER_PROCESS_PHYSICS || !is_processing_internal()) {
return;
+ }
time_left -= get_process_delta_time();
if (time_left < 0) {
- if (!one_shot)
+ if (!one_shot) {
time_left += wait_time;
- else
+ } else {
stop();
+ }
emit_signal("timeout");
}
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
- if (timer_process_mode == TIMER_PROCESS_IDLE || !is_physics_processing_internal())
+ if (timer_process_mode == TIMER_PROCESS_IDLE || !is_physics_processing_internal()) {
return;
+ }
time_left -= get_physics_process_delta_time();
if (time_left < 0) {
- if (!one_shot)
+ if (!one_shot) {
time_left += wait_time;
- else
+ } else {
stop();
+ }
emit_signal("timeout");
}
@@ -83,31 +85,28 @@ void Timer::set_wait_time(float p_time) {
ERR_FAIL_COND_MSG(p_time <= 0, "Time should be greater than zero.");
wait_time = p_time;
}
-float Timer::get_wait_time() const {
+float Timer::get_wait_time() const {
return wait_time;
}
void Timer::set_one_shot(bool p_one_shot) {
-
one_shot = p_one_shot;
}
-bool Timer::is_one_shot() const {
+bool Timer::is_one_shot() const {
return one_shot;
}
void Timer::set_autostart(bool p_start) {
-
autostart = p_start;
}
-bool Timer::has_autostart() const {
+bool Timer::has_autostart() const {
return autostart;
}
void Timer::start(float p_time) {
-
ERR_FAIL_COND_MSG(!is_inside_tree(), "Timer was not added to the SceneTree. Either add it or set autostart to true.");
if (p_time > 0) {
@@ -124,8 +123,9 @@ void Timer::stop() {
}
void Timer::set_paused(bool p_paused) {
- if (paused == p_paused)
+ if (paused == p_paused) {
return;
+ }
paused = p_paused;
_set_process(processing);
@@ -140,14 +140,13 @@ bool Timer::is_stopped() const {
}
float Timer::get_time_left() const {
-
return time_left > 0 ? time_left : 0;
}
void Timer::set_timer_process_mode(TimerProcessMode p_mode) {
-
- if (timer_process_mode == p_mode)
+ if (timer_process_mode == p_mode) {
return;
+ }
switch (timer_process_mode) {
case TIMER_PROCESS_PHYSICS:
@@ -167,20 +166,22 @@ void Timer::set_timer_process_mode(TimerProcessMode p_mode) {
}
Timer::TimerProcessMode Timer::get_timer_process_mode() const {
-
return timer_process_mode;
}
void Timer::_set_process(bool p_process, bool p_force) {
switch (timer_process_mode) {
- case TIMER_PROCESS_PHYSICS: set_physics_process_internal(p_process && !paused); break;
- case TIMER_PROCESS_IDLE: set_process_internal(p_process && !paused); break;
+ case TIMER_PROCESS_PHYSICS:
+ set_physics_process_internal(p_process && !paused);
+ break;
+ case TIMER_PROCESS_IDLE:
+ set_process_internal(p_process && !paused);
+ break;
}
processing = p_process;
}
void Timer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_wait_time", "time_sec"), &Timer::set_wait_time);
ClassDB::bind_method(D_METHOD("get_wait_time"), &Timer::get_wait_time);
diff --git a/scene/main/timer.h b/scene/main/timer.h
index 044566738e..61abf04f59 100644
--- a/scene/main/timer.h
+++ b/scene/main/timer.h
@@ -34,7 +34,6 @@
#include "scene/main/node.h"
class Timer : public Node {
-
GDCLASS(Timer, Node);
float wait_time;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 72b1a877c1..8544d67ecc 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -32,7 +32,7 @@
#include "core/core_string_names.h"
#include "core/debugger/engine_debugger.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/os.h"
#include "core/project_settings.h"
#include "scene/2d/collision_object_2d.h"
@@ -56,7 +56,6 @@
#include "servers/physics_server_2d.h"
void ViewportTexture::setup_local_to_scene() {
-
if (vp) {
vp->viewport_textures.erase(this);
}
@@ -87,9 +86,9 @@ void ViewportTexture::setup_local_to_scene() {
}
void ViewportTexture::set_viewport_path_in_scene(const NodePath &p_path) {
-
- if (path == p_path)
+ if (path == p_path) {
return;
+ }
path = p_path;
@@ -99,27 +98,25 @@ void ViewportTexture::set_viewport_path_in_scene(const NodePath &p_path) {
}
NodePath ViewportTexture::get_viewport_path_in_scene() const {
-
return path;
}
int ViewportTexture::get_width() const {
-
ERR_FAIL_COND_V_MSG(!vp, 0, "Viewport Texture must be set to use it.");
return vp->size.width;
}
-int ViewportTexture::get_height() const {
+int ViewportTexture::get_height() const {
ERR_FAIL_COND_V_MSG(!vp, 0, "Viewport Texture must be set to use it.");
return vp->size.height;
}
-Size2 ViewportTexture::get_size() const {
+Size2 ViewportTexture::get_size() const {
ERR_FAIL_COND_V_MSG(!vp, Size2(), "Viewport Texture must be set to use it.");
return vp->size;
}
-RID ViewportTexture::get_rid() const {
+RID ViewportTexture::get_rid() const {
//ERR_FAIL_COND_V_MSG(!vp, RID(), "Viewport Texture must be set to use it.");
if (proxy.is_null()) {
proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
@@ -129,17 +126,15 @@ RID ViewportTexture::get_rid() const {
}
bool ViewportTexture::has_alpha() const {
-
return false;
}
-Ref<Image> ViewportTexture::get_data() const {
+Ref<Image> ViewportTexture::get_data() const {
ERR_FAIL_COND_V_MSG(!vp, Ref<Image>(), "Viewport Texture must be set to use it.");
return RS::get_singleton()->texture_2d_get(vp->texture_rid);
}
void ViewportTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_viewport_path_in_scene", "path"), &ViewportTexture::set_viewport_path_in_scene);
ClassDB::bind_method(D_METHOD("get_viewport_path_in_scene"), &ViewportTexture::get_viewport_path_in_scene);
@@ -147,13 +142,11 @@ void ViewportTexture::_bind_methods() {
}
ViewportTexture::ViewportTexture() {
-
vp = nullptr;
set_local_to_scene(true);
}
ViewportTexture::~ViewportTexture() {
-
if (vp) {
vp->viewport_textures.erase(this);
}
@@ -169,23 +162,20 @@ ViewportTexture::~ViewportTexture() {
/////////////////////////////////////
class TooltipPanel : public PopupPanel {
-
GDCLASS(TooltipPanel, PopupPanel);
public:
- TooltipPanel(){};
+ TooltipPanel() {}
};
class TooltipLabel : public Label {
-
GDCLASS(TooltipLabel, Label);
public:
- TooltipLabel(){};
+ TooltipLabel() {}
};
Viewport::GUI::GUI() {
-
embed_subwindows_hint = false;
embedding_subwindows = false;
@@ -206,20 +196,19 @@ Viewport::GUI::GUI() {
/////////////////////////////////////
void Viewport::update_worlds() {
-
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
Rect2 abstracted_rect = Rect2(Vector2(), get_visible_rect().size);
Rect2 xformed_rect = (global_canvas_transform * canvas_transform).affine_inverse().xform(abstracted_rect);
find_world_2d()->_update_viewport(this, xformed_rect);
find_world_2d()->_update();
- find_world()->_update(get_tree()->get_frame());
+ find_world_3d()->_update(get_tree()->get_frame());
}
void Viewport::_collision_object_input_event(CollisionObject3D *p_object, Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
-
Transform object_transform = p_object->get_global_transform();
Transform camera_transform = p_camera->get_global_transform();
ObjectID id = p_object->get_instance_id();
@@ -238,14 +227,12 @@ void Viewport::_collision_object_input_event(CollisionObject3D *p_object, Camera
}
void Viewport::_sub_window_update_order() {
-
for (int i = 0; i < gui.sub_windows.size(); i++) {
RS::get_singleton()->canvas_item_set_draw_index(gui.sub_windows[i].canvas_item, i);
}
}
void Viewport::_sub_window_register(Window *p_window) {
-
ERR_FAIL_COND(!is_inside_tree());
for (int i = 0; i < gui.sub_windows.size(); i++) {
ERR_FAIL_COND(gui.sub_windows[i].window == p_window);
@@ -268,7 +255,6 @@ void Viewport::_sub_window_register(Window *p_window) {
}
void Viewport::_sub_window_update(Window *p_window) {
-
int index = -1;
for (int i = 0; i < gui.sub_windows.size(); i++) {
if (gui.sub_windows[i].window == p_window) {
@@ -313,7 +299,6 @@ void Viewport::_sub_window_update(Window *p_window) {
}
void Viewport::_sub_window_grab_focus(Window *p_window) {
-
if (p_window == nullptr) {
//release current focus
if (gui.subwindow_focused) {
@@ -385,7 +370,6 @@ void Viewport::_sub_window_grab_focus(Window *p_window) {
}
void Viewport::_sub_window_remove(Window *p_window) {
-
for (int i = 0; i < gui.sub_windows.size(); i++) {
if (gui.sub_windows[i].window == p_window) {
RS::get_singleton()->free(gui.sub_windows[i].canvas_item);
@@ -407,7 +391,6 @@ void Viewport::_sub_window_remove(Window *p_window) {
gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
if (parent_visible && parent_visible != this) {
-
gui.subwindow_focused = parent_visible;
gui.subwindow_focused->_event_callback(DisplayServer::WINDOW_EVENT_FOCUS_IN);
} else {
@@ -422,33 +405,30 @@ void Viewport::_sub_window_remove(Window *p_window) {
RenderingServer::get_singleton()->viewport_set_parent_viewport(p_window->viewport, p_window->parent ? p_window->parent->viewport : RID());
}
-void Viewport::_own_world_changed() {
- ERR_FAIL_COND(world.is_null());
- ERR_FAIL_COND(own_world.is_null());
+void Viewport::_own_world_3d_changed() {
+ ERR_FAIL_COND(world_3d.is_null());
+ ERR_FAIL_COND(own_world_3d.is_null());
if (is_inside_tree()) {
_propagate_exit_world(this);
}
- own_world = world->duplicate();
+ own_world_3d = world_3d->duplicate();
if (is_inside_tree()) {
_propagate_enter_world(this);
}
if (is_inside_tree()) {
- RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world()->get_scenario());
+ RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
}
_update_listener();
}
void Viewport::_notification(int p_what) {
-
switch (p_what) {
-
case NOTIFICATION_ENTER_TREE: {
-
gui.embedding_subwindows = gui.embed_subwindows_hint;
if (get_parent()) {
@@ -459,7 +439,7 @@ void Viewport::_notification(int p_what) {
}
current_canvas = find_world_2d()->get_canvas();
- RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world()->get_scenario());
+ RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
RenderingServer::get_singleton()->viewport_attach_canvas(viewport, current_canvas);
_update_listener();
@@ -474,14 +454,14 @@ void Viewport::_notification(int p_what) {
contact_2d_debug = RenderingServer::get_singleton()->canvas_item_create();
RenderingServer::get_singleton()->canvas_item_set_parent(contact_2d_debug, find_world_2d()->get_canvas());
//3D
- PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world()->get_space(), get_tree()->get_collision_debug_contact_count());
+ PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count());
contact_3d_debug_multimesh = RenderingServer::get_singleton()->multimesh_create();
RenderingServer::get_singleton()->multimesh_allocate(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true);
RenderingServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0);
RenderingServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid());
contact_3d_debug_instance = RenderingServer::get_singleton()->instance_create();
RenderingServer::get_singleton()->instance_set_base(contact_3d_debug_instance, contact_3d_debug_multimesh);
- RenderingServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world()->get_scenario());
+ RenderingServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world_3d()->get_scenario());
//RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS, true);
}
@@ -491,28 +471,28 @@ void Viewport::_notification(int p_what) {
if (listeners.size() && !listener) {
Listener3D *first = nullptr;
for (Set<Listener3D *>::Element *E = listeners.front(); E; E = E->next()) {
-
if (first == nullptr || first->is_greater_than(E->get())) {
first = E->get();
}
}
- if (first)
+ if (first) {
first->make_current();
+ }
}
if (cameras.size() && !camera) {
//there are cameras but no current camera, pick first in tree and make it current
Camera3D *first = nullptr;
for (Set<Camera3D *>::Element *E = cameras.front(); E; E = E->next()) {
-
if (first == nullptr || first->is_greater_than(E->get())) {
first = E->get();
}
}
- if (first)
+ if (first) {
first->make_current();
+ }
}
#endif
@@ -522,10 +502,10 @@ void Viewport::_notification(int p_what) {
} break;
case NOTIFICATION_EXIT_TREE: {
-
_gui_cancel_tooltip();
- if (world_2d.is_valid())
+ if (world_2d.is_valid()) {
world_2d->_remove_viewport(this);
+ }
RenderingServer::get_singleton()->viewport_set_scenario(viewport, RID());
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
@@ -548,7 +528,6 @@ void Viewport::_notification(int p_what) {
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
-
if (gui.tooltip_timer >= 0) {
gui.tooltip_timer -= get_process_delta_time();
if (gui.tooltip_timer < 0) {
@@ -558,9 +537,7 @@ void Viewport::_notification(int p_what) {
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
-
if (get_tree()->is_debugging_collisions_hint() && contact_2d_debug.is_valid()) {
-
RenderingServer::get_singleton()->canvas_item_clear(contact_2d_debug);
RenderingServer::get_singleton()->canvas_item_set_draw_index(contact_2d_debug, 0xFFFFF); //very high index
@@ -569,21 +546,18 @@ void Viewport::_notification(int p_what) {
Color ccol = get_tree()->get_debug_collision_contact_color();
for (int i = 0; i < point_count; i++) {
-
RenderingServer::get_singleton()->canvas_item_add_rect(contact_2d_debug, Rect2(points[i] - Vector2(2, 2), Vector2(5, 5)), ccol);
}
}
if (get_tree()->is_debugging_collisions_hint() && contact_3d_debug_multimesh.is_valid()) {
-
- Vector<Vector3> points = PhysicsServer3D::get_singleton()->space_get_contacts(find_world()->get_space());
- int point_count = PhysicsServer3D::get_singleton()->space_get_contact_count(find_world()->get_space());
+ Vector<Vector3> points = PhysicsServer3D::get_singleton()->space_get_contacts(find_world_3d()->get_space());
+ int point_count = PhysicsServer3D::get_singleton()->space_get_contact_count(find_world_3d()->get_space());
RS::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, point_count);
}
- if (physics_object_picking && (to_screen_rect == Rect2i() || InputFilter::get_singleton()->get_mouse_mode() != InputFilter::MOUSE_MODE_CAPTURED)) {
-
+ if (physics_object_picking && (to_screen_rect == Rect2i() || Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED)) {
#ifndef _3D_DISABLED
Vector2 last_pos(1e20, 1e20);
CollisionObject3D *last_object = nullptr;
@@ -621,7 +595,6 @@ void Viewport::_notification(int p_what) {
}
while (physics_picking_events.size()) {
-
Ref<InputEvent> ev = physics_picking_events.front()->get();
physics_picking_events.pop_front();
@@ -631,7 +604,6 @@ void Viewport::_notification(int p_what) {
Ref<InputEventMouseMotion> mm = ev;
if (mm.is_valid()) {
-
pos = mm->get_position();
is_mouse = true;
@@ -647,7 +619,6 @@ void Viewport::_notification(int p_what) {
Ref<InputEventMouseButton> mb = ev;
if (mb.is_valid()) {
-
pos = mb->get_position();
is_mouse = true;
@@ -715,7 +686,6 @@ void Viewport::_notification(int p_what) {
int rc = ss2d->intersect_point_on_canvas(point, canvas_layer_id, res, 64, Set<RID>(), 0xFFFFFFFF, true, true, true);
for (int i = 0; i < rc; i++) {
-
if (res[i].collider_id.is_valid() && res[i].collider) {
CollisionObject2D *co = Object::cast_to<CollisionObject2D>(res[i].collider);
if (co) {
@@ -750,7 +720,6 @@ void Viewport::_notification(int p_what) {
if (E->get() != frame) {
Object *o = ObjectDB::get_instance(E->key());
if (o) {
-
CollisionObject2D *co = Object::cast_to<CollisionObject2D>(o);
if (co) {
co->_mouse_exit();
@@ -771,7 +740,6 @@ void Viewport::_notification(int p_what) {
bool captured = false;
if (physics_object_capture.is_valid()) {
-
CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_capture));
if (co && camera) {
_collision_object_input_event(co, camera, ev, Vector3(), Vector3(), 0);
@@ -788,7 +756,6 @@ void Viewport::_notification(int p_what) {
if (captured) {
//none
} else if (pos == last_pos) {
-
if (last_id.is_valid()) {
if (ObjectDB::get_instance(last_id) && last_object) {
//good, exists
@@ -799,22 +766,17 @@ void Viewport::_notification(int p_what) {
}
}
} else {
-
if (camera) {
-
Vector3 from = camera->project_ray_origin(pos);
Vector3 dir = camera->project_ray_normal(pos);
- PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world()->get_space());
+ PhysicsDirectSpaceState3D *space = PhysicsServer3D::get_singleton()->space_get_direct_state(find_world_3d()->get_space());
if (space) {
-
bool col = space->intersect_ray(from, from + dir * 10000, result, Set<RID>(), 0xFFFFFFFF, true, true, true);
ObjectID new_collider;
if (col) {
-
CollisionObject3D *co = Object::cast_to<CollisionObject3D>(result.collider);
if (co) {
-
_collision_object_input_event(co, camera, ev, result.position, result.normal, result.shape);
last_object = co;
last_id = result.collider_id;
@@ -826,9 +788,7 @@ void Viewport::_notification(int p_what) {
}
if (is_mouse && new_collider != physics_object_over) {
-
if (physics_object_over.is_valid()) {
-
CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(physics_object_over));
if (co) {
co->_mouse_exit();
@@ -836,7 +796,6 @@ void Viewport::_notification(int p_what) {
}
if (new_collider.is_valid()) {
-
CollisionObject3D *co = Object::cast_to<CollisionObject3D>(ObjectDB::get_instance(new_collider));
if (co) {
co->_mouse_enter();
@@ -857,7 +816,6 @@ void Viewport::_notification(int p_what) {
} break;
case NOTIFICATION_WM_MOUSE_EXIT:
case NOTIFICATION_WM_FOCUS_OUT: {
-
_drop_physics_mouseover();
if (gui.mouse_focus && !gui.forced_mouse_focus) {
@@ -868,21 +826,21 @@ void Viewport::_notification(int p_what) {
}
RID Viewport::get_viewport_rid() const {
-
return viewport;
}
void Viewport::update_canvas_items() {
- if (!is_inside_tree())
+ if (!is_inside_tree()) {
return;
+ }
_update_canvas_items(this);
}
void Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override, const Rect2i &p_to_screen_rect, const Transform2D &p_stretch_transform, bool p_allocated) {
-
- if (size == p_size && size_allocated == p_allocated && stretch_transform == p_stretch_transform && p_size_2d_override == size_2d_override && to_screen_rect != p_to_screen_rect)
+ if (size == p_size && size_allocated == p_allocated && stretch_transform == p_stretch_transform && p_size_2d_override == size_2d_override && to_screen_rect != p_to_screen_rect) {
return;
+ }
size = p_size;
size_allocated = p_allocated;
@@ -905,15 +863,16 @@ void Viewport::_set_size(const Size2i &p_size, const Size2i &p_size_2d_override,
Size2i Viewport::_get_size() const {
return size;
}
+
Size2i Viewport::_get_size_2d_override() const {
return size_2d_override;
}
+
bool Viewport::_is_size_allocated() const {
return size_allocated;
}
Rect2 Viewport::get_visible_rect() const {
-
Rect2 r;
if (size == Size2()) {
@@ -933,7 +892,6 @@ void Viewport::_update_listener() {
}
void Viewport::_update_listener_2d() {
-
/*
if (is_inside_tree() && audio_listener && (!get_parent() || (Object::cast_to<Control>(get_parent()) && Object::cast_to<Control>(get_parent())->is_visible_in_tree())))
SpatialSound2DServer::get_singleton()->listener_set_space(internal_listener_2d, find_world_2d()->get_sound_space());
@@ -943,23 +901,22 @@ void Viewport::_update_listener_2d() {
}
void Viewport::set_as_audio_listener(bool p_enable) {
-
- if (p_enable == audio_listener)
+ if (p_enable == audio_listener) {
return;
+ }
audio_listener = p_enable;
_update_listener();
}
bool Viewport::is_audio_listener() const {
-
return audio_listener;
}
void Viewport::set_as_audio_listener_2d(bool p_enable) {
-
- if (p_enable == audio_listener_2d)
+ if (p_enable == audio_listener_2d) {
return;
+ }
audio_listener_2d = p_enable;
@@ -967,7 +924,6 @@ void Viewport::set_as_audio_listener_2d(bool p_enable) {
}
bool Viewport::is_audio_listener_2d() const {
-
return audio_listener_2d;
}
@@ -1004,7 +960,6 @@ Transform2D Viewport::get_canvas_transform_override() const {
}
void Viewport::set_canvas_transform(const Transform2D &p_transform) {
-
canvas_transform = p_transform;
if (!override_canvas_transform) {
@@ -1013,26 +968,22 @@ void Viewport::set_canvas_transform(const Transform2D &p_transform) {
}
Transform2D Viewport::get_canvas_transform() const {
-
return canvas_transform;
}
void Viewport::_update_global_transform() {
-
Transform2D sxform = stretch_transform * global_canvas_transform;
RenderingServer::get_singleton()->viewport_set_global_canvas_transform(viewport, sxform);
}
void Viewport::set_global_canvas_transform(const Transform2D &p_transform) {
-
global_canvas_transform = p_transform;
_update_global_transform();
}
Transform2D Viewport::get_global_canvas_transform() const {
-
return global_canvas_transform;
}
@@ -1040,11 +991,11 @@ void Viewport::_listener_transform_changed_notify() {
}
void Viewport::_listener_set(Listener3D *p_listener) {
-
#ifndef _3D_DISABLED
- if (listener == p_listener)
+ if (listener == p_listener) {
return;
+ }
listener = p_listener;
@@ -1054,13 +1005,11 @@ void Viewport::_listener_set(Listener3D *p_listener) {
}
bool Viewport::_listener_add(Listener3D *p_listener) {
-
listeners.insert(p_listener);
return listeners.size() == 1;
}
void Viewport::_listener_remove(Listener3D *p_listener) {
-
listeners.erase(p_listener);
if (listener == p_listener) {
listener = nullptr;
@@ -1069,16 +1018,17 @@ void Viewport::_listener_remove(Listener3D *p_listener) {
#ifndef _3D_DISABLED
void Viewport::_listener_make_next_current(Listener3D *p_exclude) {
-
if (listeners.size() > 0) {
for (Set<Listener3D *>::Element *E = listeners.front(); E; E = E->next()) {
-
- if (p_exclude == E->get())
+ if (p_exclude == E->get()) {
continue;
- if (!E->get()->is_inside_tree())
+ }
+ if (!E->get()->is_inside_tree()) {
continue;
- if (listener != nullptr)
+ }
+ if (listener != nullptr) {
return;
+ }
E->get()->make_current();
}
@@ -1093,17 +1043,16 @@ void Viewport::_listener_make_next_current(Listener3D *p_exclude) {
#endif
void Viewport::_camera_transform_changed_notify() {
-
#ifndef _3D_DISABLED
#endif
}
void Viewport::_camera_set(Camera3D *p_camera) {
-
#ifndef _3D_DISABLED
- if (camera == p_camera)
+ if (camera == p_camera) {
return;
+ }
if (camera) {
camera->notification(Camera3D::NOTIFICATION_LOST_CURRENT);
@@ -1112,10 +1061,11 @@ void Viewport::_camera_set(Camera3D *p_camera) {
camera = p_camera;
if (!camera_override) {
- if (camera)
+ if (camera) {
RenderingServer::get_singleton()->viewport_attach_camera(viewport, camera->get_camera());
- else
+ } else {
RenderingServer::get_singleton()->viewport_attach_camera(viewport, RID());
+ }
}
if (camera) {
@@ -1128,13 +1078,11 @@ void Viewport::_camera_set(Camera3D *p_camera) {
}
bool Viewport::_camera_add(Camera3D *p_camera) {
-
cameras.insert(p_camera);
return cameras.size() == 1;
}
void Viewport::_camera_remove(Camera3D *p_camera) {
-
cameras.erase(p_camera);
if (camera == p_camera) {
camera->notification(Camera3D::NOTIFICATION_LOST_CURRENT);
@@ -1144,15 +1092,16 @@ void Viewport::_camera_remove(Camera3D *p_camera) {
#ifndef _3D_DISABLED
void Viewport::_camera_make_next_current(Camera3D *p_exclude) {
-
for (Set<Camera3D *>::Element *E = cameras.front(); E; E = E->next()) {
-
- if (p_exclude == E->get())
+ if (p_exclude == E->get()) {
continue;
- if (!E->get()->is_inside_tree())
+ }
+ if (!E->get()->is_inside_tree()) {
continue;
- if (camera != nullptr)
+ }
+ if (camera != nullptr) {
return;
+ }
E->get()->make_current();
}
@@ -1160,32 +1109,29 @@ void Viewport::_camera_make_next_current(Camera3D *p_exclude) {
#endif
void Viewport::_canvas_layer_add(CanvasLayer *p_canvas_layer) {
-
canvas_layers.insert(p_canvas_layer);
}
void Viewport::_canvas_layer_remove(CanvasLayer *p_canvas_layer) {
-
canvas_layers.erase(p_canvas_layer);
}
void Viewport::set_transparent_background(bool p_enable) {
-
transparent_bg = p_enable;
RS::get_singleton()->viewport_set_transparent_background(viewport, p_enable);
}
bool Viewport::has_transparent_background() const {
-
return transparent_bg;
}
void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
- if (world_2d == p_world_2d)
+ if (world_2d == p_world_2d) {
return;
+ }
if (parent && parent->find_world_2d() == p_world_2d) {
- WARN_PRINT("Unable to use parent world as world_2d");
+ WARN_PRINT("Unable to use parent world_3d as world_2d");
return;
}
@@ -1194,10 +1140,10 @@ void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
RenderingServer::get_singleton()->viewport_remove_canvas(viewport, current_canvas);
}
- if (p_world_2d.is_valid())
+ if (p_world_2d.is_valid()) {
world_2d = p_world_2d;
- else {
- WARN_PRINT("Invalid world");
+ } else {
+ WARN_PRINT("Invalid world_3d");
world_2d = Ref<World2D>(memnew(World2D));
}
@@ -1211,21 +1157,20 @@ void Viewport::set_world_2d(const Ref<World2D> &p_world_2d) {
}
Ref<World2D> Viewport::find_world_2d() const {
-
- if (world_2d.is_valid())
+ if (world_2d.is_valid()) {
return world_2d;
- else if (parent)
+ } else if (parent) {
return parent->find_world_2d();
- else
+ } else {
return Ref<World2D>();
+ }
}
void Viewport::_propagate_enter_world(Node *p_node) {
-
if (p_node != this) {
-
- if (!p_node->is_inside_tree()) //may not have entered scene yet
+ if (!p_node->is_inside_tree()) { //may not have entered scene yet
return;
+ }
#ifndef _3D_DISABLED
if (Object::cast_to<Node3D>(p_node) || Object::cast_to<WorldEnvironment>(p_node)) {
@@ -1234,9 +1179,9 @@ void Viewport::_propagate_enter_world(Node *p_node) {
#endif
Viewport *v = Object::cast_to<Viewport>(p_node);
if (v) {
-
- if (v->world.is_valid() || v->own_world.is_valid())
+ if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) {
return;
+ }
}
#ifndef _3D_DISABLED
}
@@ -1244,28 +1189,26 @@ void Viewport::_propagate_enter_world(Node *p_node) {
}
for (int i = 0; i < p_node->get_child_count(); i++) {
-
_propagate_enter_world(p_node->get_child(i));
}
}
void Viewport::_propagate_viewport_notification(Node *p_node, int p_what) {
-
p_node->notification(p_what);
for (int i = 0; i < p_node->get_child_count(); i++) {
Node *c = p_node->get_child(i);
- if (Object::cast_to<Viewport>(c))
+ if (Object::cast_to<Viewport>(c)) {
continue;
+ }
_propagate_viewport_notification(c, p_what);
}
}
void Viewport::_propagate_exit_world(Node *p_node) {
-
if (p_node != this) {
-
- if (!p_node->is_inside_tree()) //may have exited scene already
+ if (!p_node->is_inside_tree()) { //may have exited scene already
return;
+ }
#ifndef _3D_DISABLED
if (Object::cast_to<Node3D>(p_node) || Object::cast_to<WorldEnvironment>(p_node)) {
@@ -1274,9 +1217,9 @@ void Viewport::_propagate_exit_world(Node *p_node) {
#endif
Viewport *v = Object::cast_to<Viewport>(p_node);
if (v) {
-
- if (v->world.is_valid() || v->own_world.is_valid())
+ if (v->world_3d.is_valid() || v->own_world_3d.is_valid()) {
return;
+ }
}
#ifndef _3D_DISABLED
}
@@ -1284,68 +1227,66 @@ void Viewport::_propagate_exit_world(Node *p_node) {
}
for (int i = 0; i < p_node->get_child_count(); i++) {
-
_propagate_exit_world(p_node->get_child(i));
}
}
-void Viewport::set_world(const Ref<World3D> &p_world) {
-
- if (world == p_world)
+void Viewport::set_world_3d(const Ref<World3D> &p_world_3d) {
+ if (world_3d == p_world_3d) {
return;
+ }
- if (is_inside_tree())
+ if (is_inside_tree()) {
_propagate_exit_world(this);
+ }
- if (own_world.is_valid() && world.is_valid()) {
- world->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_changed));
+ if (own_world_3d.is_valid() && world_3d.is_valid()) {
+ world_3d->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed));
}
- world = p_world;
+ world_3d = p_world_3d;
- if (own_world.is_valid()) {
- if (world.is_valid()) {
- own_world = world->duplicate();
- world->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_changed));
+ if (own_world_3d.is_valid()) {
+ if (world_3d.is_valid()) {
+ own_world_3d = world_3d->duplicate();
+ world_3d->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed));
} else {
- own_world = Ref<World3D>(memnew(World3D));
+ own_world_3d = Ref<World3D>(memnew(World3D));
}
}
- if (is_inside_tree())
+ if (is_inside_tree()) {
_propagate_enter_world(this);
+ }
if (is_inside_tree()) {
- RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world()->get_scenario());
+ RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
}
_update_listener();
}
-Ref<World3D> Viewport::get_world() const {
-
- return world;
+Ref<World3D> Viewport::get_world_3d() const {
+ return world_3d;
}
Ref<World2D> Viewport::get_world_2d() const {
-
return world_2d;
}
-Ref<World3D> Viewport::find_world() const {
-
- if (own_world.is_valid())
- return own_world;
- else if (world.is_valid())
- return world;
- else if (parent)
- return parent->find_world();
- else
+Ref<World3D> Viewport::find_world_3d() const {
+ if (own_world_3d.is_valid()) {
+ return own_world_3d;
+ } else if (world_3d.is_valid()) {
+ return world_3d;
+ } else if (parent) {
+ return parent->find_world_3d();
+ } else {
return Ref<World3D>();
+ }
}
Listener3D *Viewport::get_listener() const {
-
return listener;
}
@@ -1354,7 +1295,6 @@ Camera3D *Viewport::get_camera() const {
}
void Viewport::enable_camera_override(bool p_enable) {
-
#ifndef _3D_DISABLED
if (p_enable == camera_override) {
return;
@@ -1399,8 +1339,9 @@ Transform Viewport::get_camera_override_transform() const {
void Viewport::set_camera_override_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) {
if (camera_override) {
if (camera_override.fov == p_fovy_degrees && camera_override.z_near == p_z_near &&
- camera_override.z_far == p_z_far && camera_override.projection == CameraOverrideData::PROJECTION_PERSPECTIVE)
+ camera_override.z_far == p_z_far && camera_override.projection == CameraOverrideData::PROJECTION_PERSPECTIVE) {
return;
+ }
camera_override.fov = p_fovy_degrees;
camera_override.z_near = p_z_near;
@@ -1414,8 +1355,9 @@ void Viewport::set_camera_override_perspective(float p_fovy_degrees, float p_z_n
void Viewport::set_camera_override_orthogonal(float p_size, float p_z_near, float p_z_far) {
if (camera_override) {
if (camera_override.size == p_size && camera_override.z_near == p_z_near &&
- camera_override.z_far == p_z_far && camera_override.projection == CameraOverrideData::PROJECTION_ORTHOGONAL)
+ camera_override.z_far == p_z_far && camera_override.projection == CameraOverrideData::PROJECTION_ORTHOGONAL) {
return;
+ }
camera_override.size = p_size;
camera_override.z_near = p_z_near;
@@ -1427,16 +1369,15 @@ void Viewport::set_camera_override_orthogonal(float p_size, float p_z_near, floa
}
Transform2D Viewport::get_final_transform() const {
-
return stretch_transform * global_canvas_transform;
}
void Viewport::_update_canvas_items(Node *p_node) {
if (p_node != this) {
-
Viewport *vp = Object::cast_to<Viewport>(p_node);
- if (vp)
+ if (vp) {
return;
+ }
CanvasItem *ci = Object::cast_to<CanvasItem>(p_node);
if (ci) {
@@ -1452,49 +1393,45 @@ void Viewport::_update_canvas_items(Node *p_node) {
}
Ref<ViewportTexture> Viewport::get_texture() const {
-
return default_texture;
}
void Viewport::set_shadow_atlas_size(int p_size) {
-
- if (shadow_atlas_size == p_size)
+ if (shadow_atlas_size == p_size) {
return;
+ }
shadow_atlas_size = p_size;
RS::get_singleton()->viewport_set_shadow_atlas_size(viewport, p_size);
}
int Viewport::get_shadow_atlas_size() const {
-
return shadow_atlas_size;
}
void Viewport::set_shadow_atlas_quadrant_subdiv(int p_quadrant, ShadowAtlasQuadrantSubdiv p_subdiv) {
-
ERR_FAIL_INDEX(p_quadrant, 4);
ERR_FAIL_INDEX(p_subdiv, SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
- if (shadow_atlas_quadrant_subdiv[p_quadrant] == p_subdiv)
+ if (shadow_atlas_quadrant_subdiv[p_quadrant] == p_subdiv) {
return;
+ }
shadow_atlas_quadrant_subdiv[p_quadrant] = p_subdiv;
static const int subdiv[SHADOW_ATLAS_QUADRANT_SUBDIV_MAX] = { 0, 1, 4, 16, 64, 256, 1024 };
RS::get_singleton()->viewport_set_shadow_atlas_quadrant_subdivision(viewport, p_quadrant, subdiv[p_subdiv]);
}
-Viewport::ShadowAtlasQuadrantSubdiv Viewport::get_shadow_atlas_quadrant_subdiv(int p_quadrant) const {
+Viewport::ShadowAtlasQuadrantSubdiv Viewport::get_shadow_atlas_quadrant_subdiv(int p_quadrant) const {
ERR_FAIL_INDEX_V(p_quadrant, 4, SHADOW_ATLAS_QUADRANT_SUBDIV_DISABLED);
return shadow_atlas_quadrant_subdiv[p_quadrant];
}
Transform2D Viewport::_get_input_pre_xform() const {
-
Transform2D pre_xf;
if (to_screen_rect.size.x != 0 && to_screen_rect.size.y != 0) {
-
pre_xf.elements[2] = -to_screen_rect.position;
pre_xf.scale(size / to_screen_rect.size);
}
@@ -1503,27 +1440,24 @@ Transform2D Viewport::_get_input_pre_xform() const {
}
Ref<InputEvent> Viewport::_make_input_local(const Ref<InputEvent> &ev) {
-
Transform2D ai = get_final_transform().affine_inverse() * _get_input_pre_xform();
return ev->xformed_by(ai);
}
Vector2 Viewport::get_mouse_position() const {
-
return gui.last_mouse_pos;
}
void Viewport::warp_mouse(const Vector2 &p_pos) {
-
Vector2 gpos = (get_final_transform().affine_inverse() * _get_input_pre_xform()).affine_inverse().xform(p_pos);
- InputFilter::get_singleton()->warp_mouse_position(gpos);
+ Input::get_singleton()->warp_mouse_position(gpos);
}
void Viewport::_gui_sort_roots() {
-
- if (!gui.roots_order_dirty)
+ if (!gui.roots_order_dirty) {
return;
+ }
gui.roots.sort_custom<Control::CComparator>();
@@ -1531,7 +1465,6 @@ void Viewport::_gui_sort_roots() {
}
void Viewport::_gui_cancel_tooltip() {
-
gui.tooltip = nullptr;
gui.tooltip_timer = -1;
if (gui.tooltip_popup) {
@@ -1542,26 +1475,27 @@ void Viewport::_gui_cancel_tooltip() {
}
String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Control **r_which) {
-
Vector2 pos = p_pos;
String tooltip;
while (p_control) {
-
tooltip = p_control->get_tooltip(pos);
if (r_which) {
*r_which = p_control;
}
- if (tooltip != String())
+ if (tooltip != String()) {
break;
+ }
pos = p_control->get_transform().xform(pos);
- if (p_control->data.mouse_filter == Control::MOUSE_FILTER_STOP)
+ if (p_control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
break;
- if (p_control->is_set_as_toplevel())
+ }
+ if (p_control->is_set_as_toplevel()) {
break;
+ }
p_control = p_control->get_parent_control();
}
@@ -1570,7 +1504,6 @@ String Viewport::_gui_get_tooltip(Control *p_control, const Vector2 &p_pos, Cont
}
void Viewport::_gui_show_tooltip() {
-
if (!gui.tooltip) {
return;
}
@@ -1578,8 +1511,9 @@ void Viewport::_gui_show_tooltip() {
Control *which = nullptr;
String tooltip = _gui_get_tooltip(gui.tooltip, gui.tooltip->get_global_transform().xform_inv(gui.tooltip_pos), &which);
tooltip = tooltip.strip_edges();
- if (tooltip.length() == 0)
+ if (tooltip.length() == 0) {
return; // bye
+ }
if (gui.tooltip_popup) {
memdelete(gui.tooltip_popup);
@@ -1621,15 +1555,17 @@ void Viewport::_gui_show_tooltip() {
Rect2i vr = gui.tooltip_popup->get_parent_visible_window()->get_usable_parent_rect();
- if (r.size.x + r.position.x > vr.size.x + vr.position.x)
+ if (r.size.x + r.position.x > vr.size.x + vr.position.x) {
r.position.x = vr.position.x + vr.size.x - r.size.x;
- else if (r.position.x < vr.position.x)
+ } else if (r.position.x < vr.position.x) {
r.position.x = vr.position.x;
+ }
- if (r.size.y + r.position.y > vr.size.y + vr.position.y)
+ if (r.size.y + r.position.y > vr.size.y + vr.position.y) {
r.position.y = vr.position.y + vr.size.y - r.size.y;
- else if (r.position.y < vr.position.y)
+ } else if (r.position.y < vr.position.y) {
r.position.y = vr.position.y;
+ }
gui.tooltip_popup->set_position(r.position);
gui.tooltip_popup->set_size(r.size);
@@ -1639,7 +1575,6 @@ void Viewport::_gui_show_tooltip() {
}
void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_input) {
-
//_block();
Ref<InputEvent> ev = p_input;
@@ -1659,32 +1594,36 @@ void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu
CanvasItem *ci = p_control;
while (ci) {
-
Control *control = Object::cast_to<Control>(ci);
if (control) {
-
if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) {
control->emit_signal(SceneStringNames::get_singleton()->gui_input, ev); //signal should be first, so it's possible to override an event (and then accept it)
}
- if (gui.key_event_accepted)
+ if (gui.key_event_accepted) {
break;
- if (!control->is_inside_tree())
+ }
+ if (!control->is_inside_tree()) {
break;
+ }
if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) {
control->call_multilevel(SceneStringNames::get_singleton()->_gui_input, ev);
}
- if (!control->is_inside_tree() || control->is_set_as_toplevel())
+ if (!control->is_inside_tree() || control->is_set_as_toplevel()) {
break;
- if (gui.key_event_accepted)
+ }
+ if (gui.key_event_accepted) {
break;
- if (!cant_stop_me_now && control->data.mouse_filter == Control::MOUSE_FILTER_STOP && ismouse)
+ }
+ if (!cant_stop_me_now && control->data.mouse_filter == Control::MOUSE_FILTER_STOP && ismouse) {
break;
+ }
}
- if (ci->is_set_as_toplevel())
+ if (ci->is_set_as_toplevel()) {
break;
+ }
ev = ev->xformed_by(ci->get_transform()); //transform event upwards
ci = ci->get_parent_item();
@@ -1694,64 +1633,67 @@ void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu
}
void Viewport::_gui_call_notification(Control *p_control, int p_what) {
-
CanvasItem *ci = p_control;
while (ci) {
-
Control *control = Object::cast_to<Control>(ci);
if (control) {
-
if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) {
control->notification(p_what);
}
- if (!control->is_inside_tree())
+ if (!control->is_inside_tree()) {
break;
+ }
- if (!control->is_inside_tree() || control->is_set_as_toplevel())
+ if (!control->is_inside_tree() || control->is_set_as_toplevel()) {
break;
- if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP)
+ }
+ if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
break;
+ }
}
- if (ci->is_set_as_toplevel())
+ if (ci->is_set_as_toplevel()) {
break;
+ }
ci = ci->get_parent_item();
}
//_unblock();
}
-Control *Viewport::_gui_find_control(const Point2 &p_global) {
+Control *Viewport::_gui_find_control(const Point2 &p_global) {
//aca va subwindows
_gui_sort_roots();
for (List<Control *>::Element *E = gui.roots.back(); E; E = E->prev()) {
-
Control *sw = E->get();
- if (!sw->is_visible_in_tree())
+ if (!sw->is_visible_in_tree()) {
continue;
+ }
Transform2D xform;
CanvasItem *pci = sw->get_parent_item();
- if (pci)
+ if (pci) {
xform = pci->get_global_transform_with_canvas();
- else
+ } else {
xform = sw->get_canvas_transform();
+ }
Control *ret = _gui_find_control_at_pos(sw, p_global, xform, gui.focus_inv_xform);
- if (ret)
+ if (ret) {
return ret;
+ }
}
return nullptr;
}
Control *Viewport::_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_global, const Transform2D &p_xform, Transform2D &r_inv_xform) {
-
- if (Object::cast_to<Viewport>(p_node))
+ if (Object::cast_to<Viewport>(p_node)) {
return nullptr;
+ }
if (!p_node->is_visible()) {
//return _find_next_visible_control_at_pos(p_node,p_global,r_inv_xform);
@@ -1760,27 +1702,29 @@ Control *Viewport::_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_
Transform2D matrix = p_xform * p_node->get_transform();
// matrix.basis_determinant() == 0.0f implies that node does not exist on scene
- if (matrix.basis_determinant() == 0.0f)
+ if (matrix.basis_determinant() == 0.0f) {
return nullptr;
+ }
Control *c = Object::cast_to<Control>(p_node);
if (!c || !c->clips_input() || c->has_point(matrix.affine_inverse().xform(p_global))) {
-
for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
-
CanvasItem *ci = Object::cast_to<CanvasItem>(p_node->get_child(i));
- if (!ci || ci->is_set_as_toplevel())
+ if (!ci || ci->is_set_as_toplevel()) {
continue;
+ }
Control *ret = _gui_find_control_at_pos(ci, p_global, matrix, r_inv_xform);
- if (ret)
+ if (ret) {
return ret;
+ }
}
}
- if (!c)
+ if (!c) {
return nullptr;
+ }
matrix.affine_invert();
@@ -1788,19 +1732,17 @@ Control *Viewport::_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_
if (c->data.mouse_filter != Control::MOUSE_FILTER_IGNORE && c->has_point(matrix.xform(p_global)) && (!gui.drag_preview || (c != gui.drag_preview && !gui.drag_preview->is_a_parent_of(c)))) {
r_inv_xform = matrix;
return c;
- } else
+ } else {
return nullptr;
+ }
}
bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_check) {
-
{ //attempt grab, try parent controls too
CanvasItem *ci = p_at_control;
while (ci) {
-
Control *control = Object::cast_to<Control>(ci);
if (control) {
-
if (control->can_drop_data(p_at_pos, gui.drag_data)) {
if (!p_just_check) {
control->drop_data(p_at_pos, gui.drag_data);
@@ -1809,14 +1751,16 @@ bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_che
return true;
}
- if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP)
+ if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
break;
+ }
}
p_at_pos = ci->get_transform().xform(p_at_pos);
- if (ci->is_set_as_toplevel())
+ if (ci->is_set_as_toplevel()) {
break;
+ }
ci = ci->get_parent_item();
}
@@ -1826,7 +1770,6 @@ bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_che
}
void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
-
ERR_FAIL_COND(p_event.is_null());
//?
@@ -1839,19 +1782,15 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
-
gui.key_event_accepted = false;
Point2 mpos = mb->get_position();
if (mb->is_pressed()) {
-
Size2 pos = mpos;
if (gui.mouse_focus_mask) {
-
//do not steal mouse focus and stuff while a focus mask exists
gui.mouse_focus_mask |= 1 << (mb->get_button_index() - 1); //add the button to the mask
} else {
-
bool is_handled = false;
if (is_handled) {
@@ -1892,7 +1831,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
#ifdef DEBUG_ENABLED
if (EngineDebugger::get_singleton() && gui.mouse_focus) {
-
Array arr;
arr.push_back(gui.mouse_focus->get_path());
arr.push_back(gui.mouse_focus->get_class());
@@ -1903,7 +1841,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (mb->get_button_index() == BUTTON_LEFT) { //assign focus
CanvasItem *ci = gui.mouse_focus;
while (ci) {
-
Control *control = Object::cast_to<Control>(ci);
if (control) {
if (control->get_focus_mode() != Control::FOCUS_NONE) {
@@ -1913,12 +1850,14 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
break;
}
- if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP)
+ if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
break;
+ }
}
- if (ci->is_set_as_toplevel())
+ if (ci->is_set_as_toplevel()) {
break;
+ }
ci = ci->get_parent_item();
}
@@ -1931,7 +1870,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
set_input_as_handled();
if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) {
-
//alternate drop use (when using force_drag(), as proposed by #5342
if (gui.mouse_focus) {
_gui_drop(gui.mouse_focus, pos, false);
@@ -1952,9 +1890,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
//gui.tooltip_popup->hide();
} else {
-
if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) {
-
if (gui.drag_mouse_over) {
_gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, false);
}
@@ -2009,7 +1945,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
gui.key_event_accepted = false;
Point2 mpos = mm->get_position();
@@ -2019,22 +1954,17 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
// D&D
if (!gui.drag_attempted && gui.mouse_focus && mm->get_button_mask() & BUTTON_MASK_LEFT) {
-
gui.drag_accum += mm->get_relative();
float len = gui.drag_accum.length();
if (len > 10) {
-
{ //attempt grab, try parent controls too
CanvasItem *ci = gui.mouse_focus;
while (ci) {
-
Control *control = Object::cast_to<Control>(ci);
if (control) {
-
gui.dragging = true;
gui.drag_data = control->get_drag_data(control->get_global_transform_with_canvas().affine_inverse().xform(mpos) - gui.drag_accum);
if (gui.drag_data.get_type() != Variant::NIL) {
-
gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false;
gui.mouse_focus_mask = 0;
@@ -2048,12 +1978,14 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.dragging = false;
}
- if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP)
+ if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
break;
+ }
}
- if (ci->is_set_as_toplevel())
+ if (ci->is_set_as_toplevel()) {
break;
+ }
ci = ci->get_parent_item();
}
@@ -2061,7 +1993,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.drag_attempted = true;
if (gui.drag_data.get_type() != Variant::NIL) {
-
_propagate_viewport_notification(this, NOTIFICATION_DRAG_BEGIN);
}
}
@@ -2072,12 +2003,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
//recompute focus_inv_xform again here
} else {
-
over = _gui_find_control(mpos);
}
if (over != gui.mouse_over) {
-
if (gui.mouse_over) {
_gui_call_notification(gui.mouse_over, Control::NOTIFICATION_MOUSE_EXIT);
}
@@ -2091,10 +2020,9 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.mouse_over = over;
- DisplayServer::CursorShape ds_cursor_shape = (DisplayServer::CursorShape)InputFilter::get_singleton()->get_default_cursor_shape();
+ DisplayServer::CursorShape ds_cursor_shape = (DisplayServer::CursorShape)Input::get_singleton()->get_default_cursor_shape();
if (over) {
-
Transform2D localizer = over->get_global_transform_with_canvas().affine_inverse();
Size2 pos = localizer.xform(mpos);
Vector2 speed = localizer.basis_xform(mm->get_speed());
@@ -2117,14 +2045,13 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (can_tooltip && gui.tooltip) {
String tooltip = _gui_get_tooltip(over, gui.tooltip->get_global_transform().xform_inv(mpos));
- if (tooltip.length() == 0)
+ if (tooltip.length() == 0) {
_gui_cancel_tooltip();
- else if (gui.tooltip_label) {
+ } else if (gui.tooltip_label) {
if (tooltip == gui.tooltip_label->get_text()) {
is_tooltip_shown = true;
}
} else {
-
Variant t = gui.tooltip_popup->call("get_tooltip_text");
if (t.get_type() == Variant::STRING) {
@@ -2135,12 +2062,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
is_tooltip_shown = true; //well, nothing to compare against, likely using custom control, so if it changes there is nothing we can do
}
}
- } else
+ } else {
_gui_cancel_tooltip();
+ }
}
if (can_tooltip && !is_tooltip_shown) {
-
gui.tooltip = over;
gui.tooltip_pos = over->get_screen_transform().xform(pos); //(parent_xform * get_transform()).affine_inverse().xform(pos);
gui.tooltip_timer = gui.tooltip_delay;
@@ -2158,12 +2085,15 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
while (c) {
cursor_shape = c->get_cursor_shape(cpos);
cpos = c->get_transform().xform(cpos);
- if (cursor_shape != Control::CURSOR_ARROW)
+ if (cursor_shape != Control::CURSOR_ARROW) {
break;
- if (c->data.mouse_filter == Control::MOUSE_FILTER_STOP)
+ }
+ if (c->data.mouse_filter == Control::MOUSE_FILTER_STOP) {
break;
- if (c->is_set_as_toplevel())
+ }
+ if (c->is_set_as_toplevel()) {
break;
+ }
c = c->get_parent_control();
}
}
@@ -2263,7 +2193,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
gui.drag_mouse_over_pos = localizer.xform(viewport_pos);
if (mm->get_button_mask() & BUTTON_MASK_LEFT) {
-
bool can_drop = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, true);
if (!can_drop) {
@@ -2284,15 +2213,11 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Ref<InputEventScreenTouch> touch_event = p_event;
if (touch_event.is_valid()) {
-
Size2 pos = touch_event->get_position();
if (touch_event->is_pressed()) {
-
Control *over = _gui_find_control(pos);
if (over) {
-
if (over->can_process()) {
-
touch_event = touch_event->xformed_by(Transform2D()); //make a copy
if (over == gui.mouse_focus) {
pos = gui.focus_inv_xform.xform(pos);
@@ -2306,9 +2231,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
return;
}
} else if (touch_event->get_index() == 0 && gui.last_mouse_focus) {
-
if (gui.last_mouse_focus->can_process()) {
-
touch_event = touch_event->xformed_by(Transform2D()); //make a copy
touch_event->set_position(gui.focus_inv_xform.xform(pos));
@@ -2321,7 +2244,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Ref<InputEventGesture> gesture_event = p_event;
if (gesture_event.is_valid()) {
-
gui.key_event_accepted = false;
_gui_cancel_tooltip();
@@ -2330,9 +2252,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Control *over = _gui_find_control(pos);
if (over) {
-
if (over->can_process()) {
-
gesture_event = gesture_event->xformed_by(Transform2D()); //make a copy
if (over == gui.mouse_focus) {
pos = gui.focus_inv_xform.xform(pos);
@@ -2349,15 +2269,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Ref<InputEventScreenDrag> drag_event = p_event;
if (drag_event.is_valid()) {
-
Control *over = gui.mouse_focus;
if (!over) {
over = _gui_find_control(drag_event->get_position());
}
if (over) {
-
if (over->can_process()) {
-
Transform2D localizer = over->get_global_transform_with_canvas().affine_inverse();
Size2 pos = localizer.xform(drag_event->get_position());
Vector2 speed = localizer.basis_xform(drag_event->get_speed());
@@ -2378,22 +2295,20 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
if (mm.is_null() && mb.is_null() && p_event->is_action_type()) {
-
if (gui.key_focus && !gui.key_focus->is_visible_in_tree()) {
gui.key_focus->release_focus();
}
if (gui.key_focus) {
-
gui.key_event_accepted = false;
if (gui.key_focus->can_process()) {
gui.key_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, p_event);
- if (gui.key_focus) //maybe lost it
+ if (gui.key_focus) { //maybe lost it
gui.key_focus->emit_signal(SceneStringNames::get_singleton()->gui_input, p_event);
+ }
}
if (gui.key_event_accepted) {
-
set_input_as_handled();
return;
}
@@ -2411,35 +2326,29 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (from && p_event->is_pressed()) {
Control *next = nullptr;
- InputFilter *input = InputFilter::get_singleton();
+ Input *input = Input::get_singleton();
if (p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) {
-
next = from->find_next_valid_focus();
}
if (p_event->is_action_pressed("ui_focus_prev") && input->is_action_just_pressed("ui_focus_prev")) {
-
next = from->find_prev_valid_focus();
}
if (!mods && p_event->is_action_pressed("ui_up") && input->is_action_just_pressed("ui_up")) {
-
next = from->_get_focus_neighbour(MARGIN_TOP);
}
if (!mods && p_event->is_action_pressed("ui_left") && input->is_action_just_pressed("ui_left")) {
-
next = from->_get_focus_neighbour(MARGIN_LEFT);
}
if (!mods && p_event->is_action_pressed("ui_right") && input->is_action_just_pressed("ui_right")) {
-
next = from->_get_focus_neighbour(MARGIN_RIGHT);
}
if (!mods && p_event->is_action_pressed("ui_down") && input->is_action_just_pressed("ui_down")) {
-
next = from->_get_focus_neighbour(MARGIN_BOTTOM);
}
@@ -2452,7 +2361,6 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
}
List<Control *>::Element *Viewport::_gui_add_root_control(Control *p_control) {
-
gui.roots_order_dirty = true;
return gui.roots.push_back(p_control);
}
@@ -2462,7 +2370,6 @@ void Viewport::_gui_set_root_order_dirty() {
}
void Viewport::_gui_force_drag(Control *p_base, const Variant &p_data, Control *p_control) {
-
ERR_FAIL_COND_MSG(p_data.get_type() == Variant::NIL, "Drag data must be a value.");
gui.dragging = true;
@@ -2475,7 +2382,6 @@ void Viewport::_gui_force_drag(Control *p_base, const Variant &p_data, Control *
}
void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) {
-
ERR_FAIL_NULL(p_control);
ERR_FAIL_COND(!Object::cast_to<Control>((Object *)p_control));
ERR_FAIL_COND(p_control->is_inside_tree());
@@ -2493,35 +2399,35 @@ void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) {
}
void Viewport::_gui_remove_root_control(List<Control *>::Element *RI) {
-
gui.roots.erase(RI);
}
void Viewport::_gui_unfocus_control(Control *p_control) {
-
if (gui.key_focus == p_control) {
gui.key_focus->release_focus();
}
}
void Viewport::_gui_hid_control(Control *p_control) {
-
if (gui.mouse_focus == p_control) {
_drop_mouse_focus();
}
- if (gui.key_focus == p_control)
+ if (gui.key_focus == p_control) {
_gui_remove_focus();
- if (gui.mouse_over == p_control)
+ }
+ if (gui.mouse_over == p_control) {
gui.mouse_over = nullptr;
- if (gui.drag_mouse_over == p_control)
+ }
+ if (gui.drag_mouse_over == p_control) {
gui.drag_mouse_over = nullptr;
- if (gui.tooltip == p_control)
+ }
+ if (gui.tooltip == p_control) {
_gui_cancel_tooltip();
+ }
}
void Viewport::_gui_remove_control(Control *p_control) {
-
if (gui.mouse_focus == p_control) {
gui.mouse_focus = nullptr;
gui.forced_mouse_focus = false;
@@ -2530,18 +2436,21 @@ void Viewport::_gui_remove_control(Control *p_control) {
if (gui.last_mouse_focus == p_control) {
gui.last_mouse_focus = nullptr;
}
- if (gui.key_focus == p_control)
+ if (gui.key_focus == p_control) {
gui.key_focus = nullptr;
- if (gui.mouse_over == p_control)
+ }
+ if (gui.mouse_over == p_control) {
gui.mouse_over = nullptr;
- if (gui.drag_mouse_over == p_control)
+ }
+ if (gui.drag_mouse_over == p_control) {
gui.drag_mouse_over = nullptr;
- if (gui.tooltip == p_control)
+ }
+ if (gui.tooltip == p_control) {
gui.tooltip = nullptr;
+ }
}
void Viewport::_gui_remove_focus() {
-
if (gui.key_focus) {
Node *f = gui.key_focus;
gui.key_focus = nullptr;
@@ -2550,15 +2459,14 @@ void Viewport::_gui_remove_focus() {
}
bool Viewport::_gui_control_has_focus(const Control *p_control) {
-
return gui.key_focus == p_control;
}
void Viewport::_gui_control_grab_focus(Control *p_control) {
-
//no need for change
- if (gui.key_focus && gui.key_focus == p_control)
+ if (gui.key_focus && gui.key_focus == p_control) {
return;
+ }
get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "_viewports", "_gui_remove_focus");
gui.key_focus = p_control;
emit_signal("gui_focus_changed", p_control);
@@ -2567,14 +2475,13 @@ void Viewport::_gui_control_grab_focus(Control *p_control) {
}
void Viewport::_gui_accept_event() {
-
gui.key_event_accepted = true;
- if (is_inside_tree())
+ if (is_inside_tree()) {
set_input_as_handled();
+ }
}
void Viewport::_drop_mouse_focus() {
-
Control *c = gui.mouse_focus;
int mask = gui.mouse_focus_mask;
gui.mouse_focus = nullptr;
@@ -2582,7 +2489,6 @@ void Viewport::_drop_mouse_focus() {
gui.mouse_focus_mask = 0;
for (int i = 0; i < 3; i++) {
-
if (mask & (1 << i)) {
Ref<InputEventMouseButton> mb;
mb.instance();
@@ -2596,7 +2502,6 @@ void Viewport::_drop_mouse_focus() {
}
void Viewport::_drop_physics_mouseover() {
-
physics_has_last_mousepos = false;
while (physics_2d_mouseover.size()) {
@@ -2622,18 +2527,15 @@ void Viewport::_drop_physics_mouseover() {
}
Control *Viewport::_gui_get_focus_owner() {
-
return gui.key_focus;
}
void Viewport::_gui_grab_click_focus(Control *p_control) {
-
gui.mouse_click_grabber = p_control;
call_deferred("_post_gui_grab_click_focus");
}
void Viewport::_post_gui_grab_click_focus() {
-
Control *focus_grabber = gui.mouse_click_grabber;
if (!focus_grabber) {
// Redundant grab requests were made
@@ -2642,17 +2544,15 @@ void Viewport::_post_gui_grab_click_focus() {
gui.mouse_click_grabber = nullptr;
if (gui.mouse_focus) {
-
- if (gui.mouse_focus == focus_grabber)
+ if (gui.mouse_focus == focus_grabber) {
return;
+ }
int mask = gui.mouse_focus_mask;
Point2 click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos);
for (int i = 0; i < 3; i++) {
-
if (mask & (1 << i)) {
-
Ref<InputEventMouseButton> mb;
mb.instance();
@@ -2670,9 +2570,7 @@ void Viewport::_post_gui_grab_click_focus() {
click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos);
for (int i = 0; i < 3; i++) {
-
if (mask & (1 << i)) {
-
Ref<InputEventMouseButton> mb;
mb.instance();
@@ -2690,7 +2588,6 @@ void Viewport::_post_gui_grab_click_focus() {
///////////////////////////////
void Viewport::input_text(const String &p_text) {
-
if (gui.subwindow_focused) {
gui.subwindow_focused->input_text(p_text);
return;
@@ -2700,8 +2597,8 @@ void Viewport::input_text(const String &p_text) {
gui.key_focus->call("set_text", p_text);
}
}
-Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subwindow, const Point2 &p_point) {
+Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subwindow, const Point2 &p_point) {
if (p_subwindow->get_flag(Window::FLAG_BORDERLESS)) {
return SUB_WINDOW_RESIZE_DISABLED;
}
@@ -2764,15 +2661,13 @@ Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subw
return SUB_WINDOW_RESIZE_DISABLED;
}
-bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
+bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
if (gui.subwindow_drag != SUB_WINDOW_DRAG_DISABLED) {
-
ERR_FAIL_COND_V(gui.subwindow_focused == nullptr, false);
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
if (gui.subwindow_drag == SUB_WINDOW_DRAG_CLOSE) {
if (gui.subwindow_drag_close_rect.has_point(mb->get_position())) {
//close window
@@ -2787,7 +2682,6 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
if (gui.subwindow_drag == SUB_WINDOW_DRAG_MOVE) {
Vector2 diff = mm->get_position() - gui.subwindow_drag_from;
Rect2i new_rect(gui.subwindow_drag_pos + diff, gui.subwindow_focused->get_size());
@@ -2813,7 +2707,6 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
switch (gui.subwindow_resize_mode) {
case SUB_WINDOW_RESIZE_TOP_LEFT: {
-
diff.x = MIN(diff.x, limit.x);
diff.y = MIN(diff.y, limit.y);
r.position += diff;
@@ -2879,7 +2772,6 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
//if the event is a mouse button, we need to check whether another window was clicked
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
-
bool click_on_window = false;
for (int i = gui.sub_windows.size() - 1; i >= 0; i--) {
SubWindow &sw = gui.sub_windows.write[i];
@@ -2896,7 +2788,6 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
title_bar.size.y = title_height;
if (title_bar.has_point(mb->get_position())) {
-
click_on_window = true;
int close_h_ofs = sw.window->get_theme_constant("close_h_ofs");
@@ -2913,12 +2804,10 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
}
if (close_rect.has_point(mb->get_position())) {
-
gui.subwindow_drag = SUB_WINDOW_DRAG_CLOSE;
gui.subwindow_drag_close_inside = true; //starts inside
gui.subwindow_drag_close_rect = close_rect;
} else {
-
gui.subwindow_drag = SUB_WINDOW_DRAG_MOVE;
}
@@ -2958,13 +2847,10 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
}
if (gui.subwindow_focused) {
-
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
-
SubWindowResize resize = _sub_window_get_resize_margin(gui.subwindow_focused, mm->get_position());
if (resize != SUB_WINDOW_RESIZE_DISABLED) {
-
DisplayServer::CursorShape shapes[SUB_WINDOW_RESIZE_MAX] = {
DisplayServer::CURSOR_ARROW,
DisplayServer::CURSOR_FDIAGSIZE,
@@ -3003,11 +2889,11 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
}
void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) {
-
ERR_FAIL_COND(!is_inside_tree());
- if (disable_input)
+ if (disable_input) {
return;
+ }
if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) {
return;
@@ -3038,11 +2924,11 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) {
}
void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) {
-
ERR_FAIL_COND(!is_inside_tree());
- if (disable_input)
+ if (disable_input) {
return;
+ }
if (Engine::get_singleton()->is_editor_hint() && get_tree()->get_edited_scene_root() && get_tree()->get_edited_scene_root()->is_a_parent_of(this)) {
return;
@@ -3063,8 +2949,7 @@ void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coor
}
if (physics_object_picking && !is_input_handled()) {
-
- if (InputFilter::get_singleton()->get_mouse_mode() != InputFilter::MOUSE_MODE_CAPTURED &&
+ if (Input::get_singleton()->get_mouse_mode() != Input::MOUSE_MODE_CAPTURED &&
(Object::cast_to<InputEventMouseButton>(*ev) ||
Object::cast_to<InputEventMouseMotion>(*ev) ||
Object::cast_to<InputEventScreenDrag>(*ev) ||
@@ -3077,45 +2962,45 @@ void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coor
}
}
-void Viewport::set_use_own_world(bool p_world) {
-
- if (p_world == own_world.is_valid())
+void Viewport::set_use_own_world_3d(bool p_world_3d) {
+ if (p_world_3d == own_world_3d.is_valid()) {
return;
+ }
- if (is_inside_tree())
+ if (is_inside_tree()) {
_propagate_exit_world(this);
+ }
- if (!p_world) {
- own_world = Ref<World3D>();
- if (world.is_valid()) {
- world->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_changed));
+ if (!p_world_3d) {
+ own_world_3d = Ref<World3D>();
+ if (world_3d.is_valid()) {
+ world_3d->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed));
}
} else {
- if (world.is_valid()) {
- own_world = world->duplicate();
- world->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_changed));
+ if (world_3d.is_valid()) {
+ own_world_3d = world_3d->duplicate();
+ world_3d->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Viewport::_own_world_3d_changed));
} else {
- own_world = Ref<World3D>(memnew(World3D));
+ own_world_3d = Ref<World3D>(memnew(World3D));
}
}
- if (is_inside_tree())
+ if (is_inside_tree()) {
_propagate_enter_world(this);
+ }
if (is_inside_tree()) {
- RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world()->get_scenario());
+ RenderingServer::get_singleton()->viewport_set_scenario(viewport, find_world_3d()->get_scenario());
}
_update_listener();
}
-bool Viewport::is_using_own_world() const {
-
- return own_world.is_valid();
+bool Viewport::is_using_own_world_3d() const {
+ return own_world_3d.is_valid();
}
void Viewport::set_physics_object_picking(bool p_enable) {
-
physics_object_picking = p_enable;
if (!physics_object_picking) {
physics_picking_events.clear();
@@ -3123,18 +3008,15 @@ void Viewport::set_physics_object_picking(bool p_enable) {
}
bool Viewport::get_physics_object_picking() {
-
return physics_object_picking;
}
Vector2 Viewport::get_camera_coords(const Vector2 &p_viewport_coords) const {
-
Transform2D xf = get_final_transform();
return xf.xform(p_viewport_coords);
}
Vector2 Viewport::get_camera_rect_size() const {
-
return size;
}
@@ -3143,7 +3025,6 @@ void Viewport::set_disable_input(bool p_disable) {
}
bool Viewport::is_input_disabled() const {
-
return disable_input;
}
@@ -3166,61 +3047,55 @@ String Viewport::get_configuration_warning() const {
void Viewport::gui_reset_canvas_sort_index() {
gui.canvas_sort_index = 0;
}
-int Viewport::gui_get_canvas_sort_index() {
+int Viewport::gui_get_canvas_sort_index() {
return gui.canvas_sort_index++;
}
void Viewport::set_msaa(MSAA p_msaa) {
-
ERR_FAIL_INDEX(p_msaa, MSAA_MAX);
- if (msaa == p_msaa)
+ if (msaa == p_msaa) {
return;
+ }
msaa = p_msaa;
RS::get_singleton()->viewport_set_msaa(viewport, RS::ViewportMSAA(p_msaa));
}
Viewport::MSAA Viewport::get_msaa() const {
-
return msaa;
}
void Viewport::set_screen_space_aa(ScreenSpaceAA p_screen_space_aa) {
-
ERR_FAIL_INDEX(p_screen_space_aa, SCREEN_SPACE_AA_MAX);
- if (screen_space_aa == p_screen_space_aa)
+ if (screen_space_aa == p_screen_space_aa) {
return;
+ }
screen_space_aa = p_screen_space_aa;
RS::get_singleton()->viewport_set_screen_space_aa(viewport, RS::ViewportScreenSpaceAA(p_screen_space_aa));
}
Viewport::ScreenSpaceAA Viewport::get_screen_space_aa() const {
-
return screen_space_aa;
}
-void Viewport::set_debug_draw(DebugDraw p_debug_draw) {
+void Viewport::set_debug_draw(DebugDraw p_debug_draw) {
debug_draw = p_debug_draw;
RS::get_singleton()->viewport_set_debug_draw(viewport, RS::ViewportDebugDraw(p_debug_draw));
}
Viewport::DebugDraw Viewport::get_debug_draw() const {
-
return debug_draw;
}
int Viewport::get_render_info(RenderInfo p_info) {
-
return RS::get_singleton()->viewport_get_render_info(viewport, RS::ViewportRenderInfo(p_info));
}
void Viewport::set_snap_controls_to_pixels(bool p_enable) {
-
snap_controls_to_pixels = p_enable;
}
bool Viewport::is_snap_controls_to_pixels_enabled() const {
-
return snap_controls_to_pixels;
}
@@ -3296,6 +3171,7 @@ void Viewport::set_default_canvas_item_texture_repeat(DefaultCanvasItemTextureRe
default_canvas_item_texture_repeat = p_repeat;
_propagate_update_default_repeat(this);
}
+
Viewport::DefaultCanvasItemTextureRepeat Viewport::get_default_canvas_item_texture_repeat() const {
return default_canvas_item_texture_repeat;
}
@@ -3338,9 +3214,11 @@ Viewport *Viewport::get_parent_viewport() const {
void Viewport::set_embed_subwindows_hint(bool p_embed) {
gui.embed_subwindows_hint = p_embed;
}
+
bool Viewport::get_embed_subwindows_hint() const {
return gui.embed_subwindows_hint;
}
+
bool Viewport::is_embedding_subwindows() const {
return gui.embed_subwindows_hint;
}
@@ -3362,13 +3240,12 @@ void Viewport::pass_mouse_focus_to(Viewport *p_viewport, Control *p_control) {
}
void Viewport::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_world_2d", "world_2d"), &Viewport::set_world_2d);
ClassDB::bind_method(D_METHOD("get_world_2d"), &Viewport::get_world_2d);
ClassDB::bind_method(D_METHOD("find_world_2d"), &Viewport::find_world_2d);
- ClassDB::bind_method(D_METHOD("set_world", "world"), &Viewport::set_world);
- ClassDB::bind_method(D_METHOD("get_world"), &Viewport::get_world);
- ClassDB::bind_method(D_METHOD("find_world"), &Viewport::find_world);
+ ClassDB::bind_method(D_METHOD("set_world_3d", "world_3d"), &Viewport::set_world_3d);
+ ClassDB::bind_method(D_METHOD("get_world_3d"), &Viewport::get_world_3d);
+ ClassDB::bind_method(D_METHOD("find_world_3d"), &Viewport::find_world_3d);
ClassDB::bind_method(D_METHOD("set_canvas_transform", "xform"), &Viewport::set_canvas_transform);
ClassDB::bind_method(D_METHOD("get_canvas_transform"), &Viewport::get_canvas_transform);
@@ -3404,8 +3281,8 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("update_worlds"), &Viewport::update_worlds);
- ClassDB::bind_method(D_METHOD("set_use_own_world", "enable"), &Viewport::set_use_own_world);
- ClassDB::bind_method(D_METHOD("is_using_own_world"), &Viewport::is_using_own_world);
+ ClassDB::bind_method(D_METHOD("set_use_own_world_3d", "enable"), &Viewport::set_use_own_world_3d);
+ ClassDB::bind_method(D_METHOD("is_using_own_world_3d"), &Viewport::is_using_own_world_3d);
ClassDB::bind_method(D_METHOD("get_camera"), &Viewport::get_camera);
@@ -3453,8 +3330,8 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_repeat", "mode"), &Viewport::set_default_canvas_item_texture_repeat);
ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_repeat"), &Viewport::get_default_canvas_item_texture_repeat);
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world"), "set_use_own_world", "is_using_own_world");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world", PROPERTY_HINT_RESOURCE_TYPE, "World"), "set_world", "get_world");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_3d", PROPERTY_HINT_RESOURCE_TYPE, "World3D"), "set_world_3d", "get_world_3d");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transparent_bg"), "set_transparent_background", "has_transparent_background");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally");
@@ -3495,6 +3372,17 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1024);
BIND_ENUM_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
+ BIND_ENUM_CONSTANT(MSAA_DISABLED);
+ BIND_ENUM_CONSTANT(MSAA_2X);
+ BIND_ENUM_CONSTANT(MSAA_4X);
+ BIND_ENUM_CONSTANT(MSAA_8X);
+ BIND_ENUM_CONSTANT(MSAA_16X);
+ BIND_ENUM_CONSTANT(MSAA_MAX);
+
+ BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_DISABLED);
+ BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_FXAA);
+ BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_MAX);
+
BIND_ENUM_CONSTANT(RENDER_INFO_OBJECTS_IN_FRAME);
BIND_ENUM_CONSTANT(RENDER_INFO_VERTICES_IN_FRAME);
BIND_ENUM_CONSTANT(RENDER_INFO_MATERIAL_CHANGES_IN_FRAME);
@@ -3505,9 +3393,10 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(DEBUG_DRAW_DISABLED);
BIND_ENUM_CONSTANT(DEBUG_DRAW_UNSHADED);
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_LIGHTING);
BIND_ENUM_CONSTANT(DEBUG_DRAW_OVERDRAW);
BIND_ENUM_CONSTANT(DEBUG_DRAW_WIREFRAME);
-
+ BIND_ENUM_CONSTANT(DEBUG_DRAW_NORMAL_BUFFER);
BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_ALBEDO);
BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_LIGHTING);
BIND_ENUM_CONSTANT(DEBUG_DRAW_GI_PROBE_EMISSION);
@@ -3519,18 +3408,12 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(DEBUG_DRAW_PSSM_SPLITS);
BIND_ENUM_CONSTANT(DEBUG_DRAW_DECAL_ATLAS);
- BIND_ENUM_CONSTANT(MSAA_DISABLED);
- BIND_ENUM_CONSTANT(MSAA_2X);
- BIND_ENUM_CONSTANT(MSAA_4X);
- BIND_ENUM_CONSTANT(MSAA_8X);
- BIND_ENUM_CONSTANT(MSAA_16X);
-
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);
-
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_FILTER_MAX);
+
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_ENABLED);
BIND_ENUM_CONSTANT(DEFAULT_CANVAS_ITEM_TEXTURE_REPEAT_MIRROR);
@@ -3538,7 +3421,6 @@ void Viewport::_bind_methods() {
}
Viewport::Viewport() {
-
world_2d = Ref<World2D>(memnew(World2D));
viewport = RenderingServer::get_singleton()->viewport_create();
@@ -3623,7 +3505,6 @@ Viewport::Viewport() {
}
Viewport::~Viewport() {
-
//erase itself from viewport textures
for (Set<ViewportTexture *>::Element *E = viewport_textures.front(); E; E = E->next()) {
E->get()->vp = nullptr;
@@ -3646,21 +3527,20 @@ bool SubViewport::is_using_xr() {
void SubViewport::set_size(const Size2i &p_size) {
_set_size(p_size, _get_size_2d_override(), Rect2i(), _stretch_transform(), true);
}
+
Size2i SubViewport::get_size() const {
return _get_size();
}
void SubViewport::set_size_2d_override(const Size2i &p_size) {
-
_set_size(_get_size(), p_size, Rect2i(), _stretch_transform(), true);
}
-Size2i SubViewport::get_size_2d_override() const {
+Size2i SubViewport::get_size_2d_override() const {
return _get_size_2d_override();
}
void SubViewport::set_size_2d_override_stretch(bool p_enable) {
-
if (p_enable == size_2d_override_stretch) {
return;
}
@@ -3668,28 +3548,26 @@ void SubViewport::set_size_2d_override_stretch(bool p_enable) {
size_2d_override_stretch = p_enable;
_set_size(_get_size(), _get_size_2d_override(), Rect2i(), _stretch_transform(), true);
}
-bool SubViewport::is_size_2d_override_stretch_enabled() const {
+bool SubViewport::is_size_2d_override_stretch_enabled() const {
return size_2d_override_stretch;
}
void SubViewport::set_update_mode(UpdateMode p_mode) {
-
update_mode = p_mode;
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::ViewportUpdateMode(p_mode));
}
-SubViewport::UpdateMode SubViewport::get_update_mode() const {
+SubViewport::UpdateMode SubViewport::get_update_mode() const {
return update_mode;
}
void SubViewport::set_clear_mode(ClearMode p_mode) {
-
clear_mode = p_mode;
RS::get_singleton()->viewport_set_clear_mode(get_viewport_rid(), RS::ViewportClearMode(p_mode));
}
-SubViewport::ClearMode SubViewport::get_clear_mode() const {
+SubViewport::ClearMode SubViewport::get_clear_mode() const {
return clear_mode;
}
@@ -3698,7 +3576,6 @@ DisplayServer::WindowID SubViewport::get_window_id() const {
}
Transform2D SubViewport::_stretch_transform() {
-
Transform2D transform = Transform2D();
Size2i view_size_2d_override = _get_size_2d_override();
if (size_2d_override_stretch && view_size_2d_override.width > 0 && view_size_2d_override.height > 0) {
@@ -3710,7 +3587,6 @@ Transform2D SubViewport::_stretch_transform() {
}
void SubViewport::_notification(int p_what) {
-
if (p_what == NOTIFICATION_ENTER_TREE) {
RS::get_singleton()->viewport_set_active(get_viewport_rid(), true);
}
@@ -3746,15 +3622,15 @@ void SubViewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode");
+ BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS);
+ BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER);
+ BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME);
+
BIND_ENUM_CONSTANT(UPDATE_DISABLED);
BIND_ENUM_CONSTANT(UPDATE_ONCE);
BIND_ENUM_CONSTANT(UPDATE_WHEN_VISIBLE);
BIND_ENUM_CONSTANT(UPDATE_WHEN_PARENT_VISIBLE);
BIND_ENUM_CONSTANT(UPDATE_ALWAYS);
-
- BIND_ENUM_CONSTANT(CLEAR_MODE_ALWAYS);
- BIND_ENUM_CONSTANT(CLEAR_MODE_NEVER);
- BIND_ENUM_CONSTANT(CLEAR_MODE_ONLY_NEXT_FRAME);
}
SubViewport::SubViewport() {
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 0cbc957307..4536b558f9 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -51,7 +51,6 @@ class Viewport;
class CollisionObject3D;
class ViewportTexture : public Texture2D {
-
GDCLASS(ViewportTexture, Texture2D);
NodePath path;
@@ -85,7 +84,6 @@ public:
};
class Viewport : public Node {
-
GDCLASS(Viewport, Node);
public:
@@ -116,7 +114,6 @@ public:
};
enum RenderInfo {
-
RENDER_INFO_OBJECTS_IN_FRAME,
RENDER_INFO_VERTICES_IN_FRAME,
RENDER_INFO_MATERIAL_CHANGES_IN_FRAME,
@@ -237,7 +234,6 @@ private:
bool physics_has_last_mousepos;
Vector2 physics_last_mousepos;
struct {
-
bool alt;
bool control;
bool shift;
@@ -254,8 +250,8 @@ private:
Map<ObjectID, uint64_t> physics_2d_mouseover;
Ref<World2D> world_2d;
- Ref<World3D> world;
- Ref<World3D> own_world;
+ Ref<World3D> world_3d;
+ Ref<World3D> own_world_3d;
Rect2i to_screen_rect;
StringName input_group;
@@ -431,7 +427,7 @@ private:
void _gui_set_root_order_dirty();
- void _own_world_changed();
+ void _own_world_3d_changed();
friend class Window;
@@ -478,10 +474,10 @@ public:
Rect2 get_visible_rect() const;
RID get_viewport_rid() const;
- void set_world(const Ref<World3D> &p_world);
+ void set_world_3d(const Ref<World3D> &p_world_3d);
void set_world_2d(const Ref<World2D> &p_world_2d);
- Ref<World3D> get_world() const;
- Ref<World3D> find_world() const;
+ Ref<World3D> get_world_3d() const;
+ Ref<World3D> find_world_3d() const;
Ref<World2D> get_world_2d() const;
Ref<World2D> find_world_2d() const;
@@ -520,8 +516,8 @@ public:
Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const;
Vector2 get_camera_rect_size() const;
- void set_use_own_world(bool p_world);
- bool is_using_own_world() const;
+ void set_use_own_world_3d(bool p_world_3d);
+ bool is_using_own_world_3d() const;
void input_text(const String &p_text);
void input(const Ref<InputEvent> &p_event, bool p_local_coords = false);
@@ -580,7 +576,6 @@ public:
};
class SubViewport : public Viewport {
-
GDCLASS(SubViewport, Viewport);
public:
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 19954299de..a9be8a1eff 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -43,20 +43,22 @@ void Window::set_title(const String &p_title) {
embedder->_sub_window_update(this);
} else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
-
DisplayServer::get_singleton()->window_set_title(p_title, window_id);
}
}
+
String Window::get_title() const {
return title;
}
void Window::set_current_screen(int p_screen) {
current_screen = p_screen;
- if (window_id == DisplayServer::INVALID_WINDOW_ID)
+ if (window_id == DisplayServer::INVALID_WINDOW_ID) {
return;
+ }
DisplayServer::get_singleton()->window_set_current_screen(p_screen, window_id);
}
+
int Window::get_current_screen() const {
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
current_screen = DisplayServer::get_singleton()->window_get_current_screen(window_id);
@@ -65,17 +67,16 @@ int Window::get_current_screen() const {
}
void Window::set_position(const Point2i &p_position) {
-
position = p_position;
if (embedder) {
embedder->_sub_window_update(this);
} else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
-
DisplayServer::get_singleton()->window_set_position(p_position, window_id);
}
}
+
Point2i Window::get_position() const {
return position;
}
@@ -84,13 +85,12 @@ void Window::set_size(const Size2i &p_size) {
size = p_size;
_update_window_size();
}
-Size2i Window::get_size() const {
+Size2i Window::get_size() const {
return size;
}
Size2i Window::get_real_size() const {
-
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
return DisplayServer::get_singleton()->window_get_real_size(window_id);
}
@@ -128,20 +128,17 @@ Size2i Window::get_min_size() const {
}
void Window::set_mode(Mode p_mode) {
-
mode = p_mode;
if (embedder) {
embedder->_sub_window_update(this);
} else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
-
DisplayServer::get_singleton()->window_set_mode(DisplayServer::WindowMode(p_mode), window_id);
}
}
Window::Mode Window::get_mode() const {
-
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
mode = (Mode)DisplayServer::get_singleton()->window_get_mode(window_id);
}
@@ -156,7 +153,6 @@ void Window::set_flag(Flags p_flag, bool p_enabled) {
embedder->_sub_window_update(this);
} else if (window_id != DisplayServer::INVALID_WINDOW_ID) {
-
DisplayServer::get_singleton()->window_set_flag(DisplayServer::WindowFlags(p_flag), p_enabled, window_id);
}
}
@@ -181,8 +177,8 @@ void Window::request_attention() {
DisplayServer::get_singleton()->window_request_attention(window_id);
}
}
-void Window::move_to_foreground() {
+void Window::move_to_foreground() {
if (embedder) {
embedder->_sub_window_grab_focus(this);
@@ -207,6 +203,7 @@ void Window::set_ime_active(bool p_active) {
DisplayServer::get_singleton()->window_set_ime_active(p_active, window_id);
}
}
+
void Window::set_ime_position(const Point2i &p_pos) {
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
DisplayServer::get_singleton()->window_set_ime_position(p_pos, window_id);
@@ -251,8 +248,8 @@ void Window::_make_window() {
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
}
-void Window::_update_from_window() {
+void Window::_update_from_window() {
ERR_FAIL_COND(window_id == DisplayServer::INVALID_WINDOW_ID);
mode = (Mode)DisplayServer::get_singleton()->window_get_mode(window_id);
for (int i = 0; i < FLAG_MAX; i++) {
@@ -283,7 +280,6 @@ void Window::_clear_window() {
}
void Window::_rect_changed_callback(const Rect2i &p_callback) {
-
//we must always accept this as the truth
if (size == p_callback.size && position == p_callback.position) {
return;
@@ -309,7 +305,6 @@ void Window::_propagate_window_notification(Node *p_node, int p_notification) {
}
void Window::_event_callback(DisplayServer::WindowEvent p_event) {
-
switch (p_event) {
case DisplayServer::WINDOW_EVENT_MOUSE_ENTER: {
_propagate_window_notification(this, NOTIFICATION_WM_MOUSE_ENTER);
@@ -351,12 +346,12 @@ void Window::_event_callback(DisplayServer::WindowEvent p_event) {
void Window::show() {
set_visible(true);
}
+
void Window::hide() {
set_visible(false);
}
void Window::set_visible(bool p_visible) {
-
if (visible == p_visible) {
return;
}
@@ -473,12 +468,12 @@ void Window::set_transient(bool p_transient) {
_clear_transient();
}
}
+
bool Window::is_transient() const {
return transient;
}
void Window::set_exclusive(bool p_exclusive) {
-
if (exclusive == p_exclusive) {
return;
}
@@ -506,7 +501,6 @@ bool Window::is_visible() const {
}
void Window::_update_window_size() {
-
Size2i size_limit;
if (wrap_controls) {
size_limit = get_contents_minimum_size();
@@ -535,6 +529,7 @@ void Window::_update_window_size() {
//update the viewport
_update_viewport_size();
}
+
void Window::_update_viewport_size() {
//update the viewport part
@@ -545,12 +540,10 @@ void Window::_update_viewport_size() {
float font_oversampling = 1.0;
if (content_scale_mode == CONTENT_SCALE_MODE_DISABLED || content_scale_size.x == 0 || content_scale_size.y == 0) {
-
stretch_transform = Transform2D();
final_size = size;
} else {
-
//actual screen video mode
Size2 video_mode = size;
Size2 desired_res = content_scale_size;
@@ -569,7 +562,6 @@ void Window::_update_viewport_size() {
// screen ratio is smaller vertically
if (content_scale_aspect == CONTENT_SCALE_ASPECT_KEEP_HEIGHT || content_scale_aspect == CONTENT_SCALE_ASPECT_EXPAND) {
-
//will stretch horizontally
viewport_size.x = desired_res.y * video_mode_aspect;
viewport_size.y = desired_res.y;
@@ -584,7 +576,6 @@ void Window::_update_viewport_size() {
} else {
//screen ratio is smaller horizontally
if (content_scale_aspect == CONTENT_SCALE_ASPECT_KEEP_WIDTH || content_scale_aspect == CONTENT_SCALE_ASPECT_EXPAND) {
-
//will stretch horizontally
viewport_size.x = desired_res.x;
viewport_size.y = desired_res.x / video_mode_aspect;
@@ -622,14 +613,12 @@ void Window::_update_viewport_size() {
//_update_font_oversampling(1.0);
} break;
case CONTENT_SCALE_MODE_OBJECTS: {
-
final_size = screen_size;
final_size_override = viewport_size;
attach_to_screen_rect = Rect2(margin, screen_size);
font_oversampling = screen_size.x / viewport_size.x;
} break;
case CONTENT_SCALE_MODE_PIXELS: {
-
final_size = viewport_size;
attach_to_screen_rect = Rect2(margin, screen_size);
@@ -652,12 +641,10 @@ void Window::_update_viewport_size() {
}
if (window_id == DisplayServer::MAIN_WINDOW_ID) {
-
if (!use_font_oversampling) {
font_oversampling = 1.0;
}
if (DynamicFontAtSize::font_oversampling != font_oversampling) {
-
DynamicFontAtSize::font_oversampling = font_oversampling;
DynamicFont::update_oversampling();
}
@@ -679,11 +666,9 @@ void Window::_update_window_callbacks() {
}
Viewport *Window::_get_embedder() const {
-
Viewport *vp = get_parent_viewport();
while (vp) {
-
if (vp->is_embedding_subwindows()) {
return vp;
}
@@ -699,10 +684,8 @@ Viewport *Window::_get_embedder() const {
void Window::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
-
bool embedded = false;
{
-
embedder = _get_embedder();
if (embedder) {
@@ -757,29 +740,24 @@ void Window::_notification(int p_what) {
}
if (p_what == NOTIFICATION_READY) {
-
if (wrap_controls) {
_update_child_controls();
}
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
if (transient) {
_clear_transient();
}
if (!is_embedded() && window_id != DisplayServer::INVALID_WINDOW_ID) {
-
if (window_id == DisplayServer::MAIN_WINDOW_ID) {
-
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
_update_window_callbacks();
} else {
_clear_window();
}
} else {
-
if (embedder) {
embedder->_sub_window_remove(this);
embedder = nullptr;
@@ -807,6 +785,7 @@ void Window::set_content_scale_mode(ContentScaleMode p_mode) {
content_scale_mode = p_mode;
_update_viewport_size();
}
+
Window::ContentScaleMode Window::get_content_scale_mode() const {
return content_scale_mode;
}
@@ -815,6 +794,7 @@ void Window::set_content_scale_aspect(ContentScaleAspect p_aspect) {
content_scale_aspect = p_aspect;
_update_viewport_size();
}
+
Window::ContentScaleAspect Window::get_content_scale_aspect() const {
return content_scale_aspect;
}
@@ -826,6 +806,7 @@ void Window::set_use_font_oversampling(bool p_oversampling) {
use_font_oversampling = p_oversampling;
_update_viewport_size();
}
+
bool Window::is_using_font_oversampling() const {
return use_font_oversampling;
}
@@ -861,8 +842,8 @@ Size2 Window::_get_contents_minimum_size() const {
return max;
}
-void Window::_update_child_controls() {
+void Window::_update_child_controls() {
if (!updating_child_controls) {
return;
}
@@ -871,8 +852,8 @@ void Window::_update_child_controls() {
updating_child_controls = false;
}
-void Window::child_controls_changed() {
+void Window::child_controls_changed() {
if (!is_inside_tree() || !visible || updating_child_controls) {
return;
}
@@ -882,8 +863,9 @@ void Window::child_controls_changed() {
}
void Window::_window_input(const Ref<InputEvent> &p_ev) {
- if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_ev.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_ev)))
+ if (Engine::get_singleton()->is_editor_hint() && (Object::cast_to<InputEventJoypadButton>(p_ev.ptr()) || Object::cast_to<InputEventJoypadMotion>(*p_ev))) {
return; //avoid joy input on editor
+ }
if (EngineDebugger::is_active()) {
//quit from game window using F8
@@ -905,15 +887,16 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) {
unhandled_input(p_ev);
}
}
+
void Window::_window_input_text(const String &p_text) {
input_text(p_text);
}
+
void Window::_window_drop_files(const Vector<String> &p_files) {
emit_signal("files_dropped", p_files, current_screen);
}
Viewport *Window::get_parent_viewport() const {
-
if (get_parent()) {
return get_parent()->get_viewport();
} else {
@@ -922,7 +905,6 @@ Viewport *Window::get_parent_viewport() const {
}
Window *Window::get_parent_visible_window() const {
-
Viewport *vp = get_parent_viewport();
Window *window = nullptr;
while (vp) {
@@ -940,7 +922,6 @@ Window *Window::get_parent_visible_window() const {
}
void Window::popup_on_parent(const Rect2i &p_parent_rect) {
-
ERR_FAIL_COND(!is_inside_tree());
ERR_FAIL_COND_MSG(window_id == DisplayServer::MAIN_WINDOW_ID, "Can't popup the main window.");
@@ -958,7 +939,6 @@ void Window::popup_on_parent(const Rect2i &p_parent_rect) {
}
void Window::popup_centered_clamped(const Size2i &p_size, float p_fallback_ratio) {
-
ERR_FAIL_COND(!is_inside_tree());
ERR_FAIL_COND_MSG(window_id == DisplayServer::MAIN_WINDOW_ID, "Can't popup the main window.");
@@ -1009,11 +989,10 @@ void Window::popup_centered(const Size2i &p_minsize) {
}
void Window::popup_centered_ratio(float p_ratio) {
-
ERR_FAIL_COND(!is_inside_tree());
ERR_FAIL_COND_MSG(window_id == DisplayServer::MAIN_WINDOW_ID, "Can't popup the main window.");
- Rect2i parent_rect;
+ Rect2 parent_rect;
if (is_embedded()) {
parent_rect = get_parent_viewport()->get_visible_rect();
@@ -1032,7 +1011,6 @@ void Window::popup_centered_ratio(float p_ratio) {
}
void Window::popup(const Rect2i &p_screen_rect) {
-
emit_signal("about_to_popup");
if (p_screen_rect != Rect2i()) {
@@ -1046,6 +1024,15 @@ void Window::popup(const Rect2i &p_screen_rect) {
set_size(adjust.size);
}
+ int scr = DisplayServer::get_singleton()->get_screen_count();
+ for (int i = 0; i < scr; i++) {
+ Rect2i r = DisplayServer::get_singleton()->screen_get_usable_rect(i);
+ if (r.has_point(position)) {
+ current_screen = i;
+ break;
+ }
+ }
+
set_transient(true);
set_visible(true);
_post_popup();
@@ -1074,7 +1061,6 @@ Rect2i Window::get_usable_parent_rect() const {
if (is_embedded()) {
parent = _get_embedder()->get_visible_rect();
} else {
-
const Window *w = is_visible() ? this : get_parent_visible_window();
//find a parent that can contain us
ERR_FAIL_COND_V(!w, Rect2());
@@ -1085,7 +1071,6 @@ Rect2i Window::get_usable_parent_rect() const {
}
void Window::add_child_notify(Node *p_child) {
-
Control *child_c = Object::cast_to<Control>(p_child);
if (child_c && child_c->data.theme.is_null() && (theme_owner || theme_owner_window)) {
@@ -1104,7 +1089,6 @@ void Window::add_child_notify(Node *p_child) {
}
void Window::remove_child_notify(Node *p_child) {
-
Control *child_c = Object::cast_to<Control>(p_child);
if (child_c && (child_c->data.theme_owner || child_c->data.theme_owner_window) && child_c->data.theme.is_null()) {
@@ -1123,19 +1107,17 @@ void Window::remove_child_notify(Node *p_child) {
}
void Window::set_theme(const Ref<Theme> &p_theme) {
-
- if (theme == p_theme)
+ if (theme == p_theme) {
return;
+ }
theme = p_theme;
if (!p_theme.is_null()) {
-
theme_owner = nullptr;
theme_owner_window = this;
Control::_propagate_theme_changed(this, nullptr, this);
} else {
-
Control *parent_c = cast_to<Control>(get_parent());
if (parent_c && (parent_c->data.theme_owner || parent_c->data.theme_owner_window)) {
Control::_propagate_theme_changed(this, parent_c->data.theme_owner, parent_c->data.theme_owner_window);
@@ -1149,6 +1131,7 @@ void Window::set_theme(const Ref<Theme> &p_theme) {
}
}
}
+
Ref<Theme> Window::get_theme() const {
return theme;
}
@@ -1157,22 +1140,27 @@ Ref<Texture2D> Window::get_theme_icon(const StringName &p_name, const StringName
StringName type = p_type ? p_type : get_class_name();
return Control::get_icons(theme_owner, theme_owner_window, p_name, type);
}
+
Ref<Shader> Window::get_theme_shader(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::get_shaders(theme_owner, theme_owner_window, p_name, type);
}
+
Ref<StyleBox> Window::get_theme_stylebox(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::get_styleboxs(theme_owner, theme_owner_window, p_name, type);
}
+
Ref<Font> Window::get_theme_font(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::get_fonts(theme_owner, theme_owner_window, p_name, type);
}
+
Color Window::get_theme_color(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::get_colors(theme_owner, theme_owner_window, p_name, type);
}
+
int Window::get_theme_constant(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::get_constants(theme_owner, theme_owner_window, p_name, type);
@@ -1182,22 +1170,27 @@ bool Window::has_theme_icon(const StringName &p_name, const StringName &p_type)
StringName type = p_type ? p_type : get_class_name();
return Control::has_icons(theme_owner, theme_owner_window, p_name, type);
}
+
bool Window::has_theme_shader(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::has_shaders(theme_owner, theme_owner_window, p_name, type);
}
+
bool Window::has_theme_stylebox(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::has_styleboxs(theme_owner, theme_owner_window, p_name, type);
}
+
bool Window::has_theme_font(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::has_fonts(theme_owner, theme_owner_window, p_name, type);
}
+
bool Window::has_theme_color(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::has_colors(theme_owner, theme_owner_window, p_name, type);
}
+
bool Window::has_theme_constant(const StringName &p_name, const StringName &p_type) const {
StringName type = p_type ? p_type : get_class_name();
return Control::has_constants(theme_owner, theme_owner_window, p_name, type);
@@ -1240,7 +1233,6 @@ Rect2i Window::get_parent_rect() const {
}
void Window::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_title", "title"), &Window::set_title);
ClassDB::bind_method(D_METHOD("get_title"), &Window::get_title);
@@ -1402,5 +1394,6 @@ Window::Window() {
content_scale_aspect = CONTENT_SCALE_ASPECT_IGNORE;
RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_DISABLED);
}
+
Window::~Window() {
}
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 264295325f..5588d1bd97 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -193,6 +193,7 @@
#include "scene/3d/gpu_particles_3d.h"
#include "scene/3d/immediate_geometry_3d.h"
#include "scene/3d/light_3d.h"
+#include "scene/3d/lightmap_probe.h"
#include "scene/3d/listener_3d.h"
#include "scene/3d/mesh_instance_3d.h"
#include "scene/3d/multimesh_instance_3d.h"
@@ -225,8 +226,8 @@ static Ref<ResourceFormatLoaderText> resource_loader_text;
static Ref<ResourceFormatLoaderDynamicFont> resource_loader_dynamic_font;
-static Ref<ResourceFormatLoaderStreamTexture> resource_loader_stream_texture;
-static Ref<ResourceFormatLoaderTextureLayered> resource_loader_texture_layered;
+static Ref<ResourceFormatLoaderStreamTexture2D> resource_loader_stream_texture;
+static Ref<ResourceFormatLoaderStreamTextureLayered> resource_loader_texture_layered;
static Ref<ResourceFormatLoaderBMFont> resource_loader_bmfont;
@@ -234,7 +235,6 @@ static Ref<ResourceFormatSaverShader> resource_saver_shader;
static Ref<ResourceFormatLoaderShader> resource_loader_shader;
void register_scene_types() {
-
SceneStringNames::create();
OS::get_singleton()->yield(); //may take time to init
@@ -432,8 +432,10 @@ void register_scene_types() {
ClassDB::register_class<Decal>();
ClassDB::register_class<GIProbe>();
ClassDB::register_class<GIProbeData>();
- //ClassDB::register_class<BakedLightmap>();
- //ClassDB::register_class<BakedLightmapData>();
+ ClassDB::register_class<BakedLightmap>();
+ ClassDB::register_class<BakedLightmapData>();
+ ClassDB::register_class<LightmapProbe>();
+ ClassDB::register_virtual_class<Lightmapper>();
ClassDB::register_class<GPUParticles3D>();
ClassDB::register_class<CPUParticles3D>();
ClassDB::register_class<Position3D>();
@@ -675,7 +677,7 @@ void register_scene_types() {
ClassDB::register_virtual_class<Texture>();
ClassDB::register_virtual_class<Texture2D>();
ClassDB::register_class<Sky>();
- ClassDB::register_class<StreamTexture>();
+ ClassDB::register_class<StreamTexture2D>();
ClassDB::register_class<ImageTexture>();
ClassDB::register_class<AtlasTexture>();
ClassDB::register_class<MeshTexture>();
@@ -686,9 +688,15 @@ void register_scene_types() {
ClassDB::register_class<AnimatedTexture>();
ClassDB::register_class<CameraTexture>();
ClassDB::register_virtual_class<TextureLayered>();
+ ClassDB::register_virtual_class<ImageTextureLayered>();
ClassDB::register_class<Cubemap>();
ClassDB::register_class<CubemapArray>();
ClassDB::register_class<Texture2DArray>();
+ ClassDB::register_virtual_class<StreamTextureLayered>();
+ ClassDB::register_class<StreamCubemap>();
+ ClassDB::register_class<StreamCubemapArray>();
+ ClassDB::register_class<StreamTexture2DArray>();
+
ClassDB::register_class<Animation>();
ClassDB::register_virtual_class<Font>();
ClassDB::register_class<BitmapFont>();
@@ -757,8 +765,16 @@ void register_scene_types() {
ClassDB::add_compatibility_class("AnimationTreePlayer", "AnimationTree");
// Renamed in 4.0.
+ // Keep alphabetical ordering to easily locate classes and avoid duplicates.
ClassDB::add_compatibility_class("AnimatedSprite", "AnimatedSprite2D");
ClassDB::add_compatibility_class("Area", "Area3D");
+ ClassDB::add_compatibility_class("ARVRCamera", "XRCamera3D");
+ ClassDB::add_compatibility_class("ARVRController", "XRController3D");
+ ClassDB::add_compatibility_class("ARVRAnchor", "XRAnchor3D");
+ ClassDB::add_compatibility_class("ARVRInterface", "XRInterface");
+ ClassDB::add_compatibility_class("ARVROrigin", "XROrigin3D");
+ ClassDB::add_compatibility_class("ARVRPositionalTracker", "XRPositionalTracker");
+ ClassDB::add_compatibility_class("ARVRServer", "XRServer");
ClassDB::add_compatibility_class("BoneAttachment", "BoneAttachment3D");
ClassDB::add_compatibility_class("BoxShape", "BoxShape3D");
ClassDB::add_compatibility_class("BulletPhysicsDirectBodyState", "BulletPhysicsDirectBodyState3D");
@@ -806,6 +822,7 @@ void register_scene_types() {
ClassDB::add_compatibility_class("Navigation2DServer", "NavigationServer2D");
ClassDB::add_compatibility_class("NavigationServer", "NavigationServer3D");
ClassDB::add_compatibility_class("OmniLight", "OmniLight3D");
+ ClassDB::add_compatibility_class("PanoramaSky", "Sky");
ClassDB::add_compatibility_class("Particles", "GPUParticles3D");
ClassDB::add_compatibility_class("Particles2D", "GPUParticles2D");
ClassDB::add_compatibility_class("Path", "Path3D");
@@ -827,6 +844,7 @@ void register_scene_types() {
ClassDB::add_compatibility_class("PhysicsShapeQueryResult", "PhysicsShapeQueryResult3D");
ClassDB::add_compatibility_class("PinJoint", "PinJoint3D");
ClassDB::add_compatibility_class("PlaneShape", "WorldMarginShape3D");
+ ClassDB::add_compatibility_class("ProceduralSky", "Sky");
ClassDB::add_compatibility_class("ProximityGroup", "ProximityGroup3D");
ClassDB::add_compatibility_class("RayCast", "RayCast3D");
ClassDB::add_compatibility_class("RayShape", "RayShape3D");
@@ -857,12 +875,7 @@ void register_scene_types() {
ClassDB::add_compatibility_class("VisualShaderNodeScalarOp", "VisualShaderNodeFloatOp");
ClassDB::add_compatibility_class("VisualShaderNodeScalarUniform", "VisualShaderNodeFloatUniform");
ClassDB::add_compatibility_class("World", "World3D");
- ClassDB::add_compatibility_class("ProceduralSky", "Sky");
- ClassDB::add_compatibility_class("PanoramaSky", "Sky");
- ClassDB::add_compatibility_class("ARVRCamera", "XRCamera3D");
- ClassDB::add_compatibility_class("ARVROrigin", "XROrigin3D");
- ClassDB::add_compatibility_class("ARVRController", "XRController3D");
- ClassDB::add_compatibility_class("ARVRAnchor", "XRAnchor3D");
+ ClassDB::add_compatibility_class("StreamTexture", "StreamTexture2D");
#endif
@@ -908,7 +921,6 @@ void register_scene_types() {
}
void unregister_scene_types() {
-
SceneDebugger::deinitialize();
clear_default_theme();
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index aa4c9bf225..c9fc68233d 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -36,38 +36,28 @@
#define ANIM_MIN_LENGTH 0.001
bool Animation::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name.begins_with("tracks/")) {
-
int track = name.get_slicec('/', 1).to_int();
String what = name.get_slicec('/', 2);
if (tracks.size() == track && what == "type") {
-
String type = p_value;
if (type == "transform") {
-
add_track(TYPE_TRANSFORM);
} else if (type == "value") {
-
add_track(TYPE_VALUE);
} else if (type == "method") {
-
add_track(TYPE_METHOD);
} else if (type == "bezier") {
-
add_track(TYPE_BEZIER);
} else if (type == "audio") {
-
add_track(TYPE_AUDIO);
} else if (type == "animation") {
-
add_track(TYPE_ANIMATION);
} else {
-
return false;
}
@@ -76,20 +66,18 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_INDEX_V(track, tracks.size(), false);
- if (what == "path")
+ if (what == "path") {
track_set_path(track, p_value);
- else if (what == "interp")
+ } else if (what == "interp") {
track_set_interpolation_type(track, InterpolationType(p_value.operator int()));
- else if (what == "loop_wrap")
+ } else if (what == "loop_wrap") {
track_set_interpolation_loop_wrap(track, p_value);
- else if (what == "imported")
+ } else if (what == "imported") {
track_set_imported(track, p_value);
- else if (what == "enabled")
+ } else if (what == "enabled") {
track_set_enabled(track, p_value);
- else if (what == "keys" || what == "key_values") {
-
+ } else if (what == "keys" || what == "key_values") {
if (track_get_type(track) == TYPE_TRANSFORM) {
-
TransformTrack *tt = static_cast<TransformTrack *>(tracks[track]);
Vector<float> values = p_value;
int vcount = values.size();
@@ -100,7 +88,6 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
tt->transforms.resize(vcount / 12);
for (int i = 0; i < (vcount / 12); i++) {
-
TKey<TransformKey> &tk = tt->transforms.write[i];
const float *ofs = &r[i * 12];
tk.time = ofs[0];
@@ -121,7 +108,6 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
}
} else if (track_get_type(track) == TYPE_VALUE) {
-
ValueTrack *vt = static_cast<ValueTrack *>(tracks[track]);
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("times"), false);
@@ -133,10 +119,11 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
if (d.has("update")) {
int um = d["update"];
- if (um < 0)
+ if (um < 0) {
um = 0;
- else if (um > 3)
+ } else if (um > 3) {
um = 3;
+ }
vt->update_mode = UpdateMode(um);
}
@@ -146,7 +133,6 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(times.size() != values.size(), false);
if (times.size()) {
-
int valcount = times.size();
const float *rt = times.ptr();
@@ -154,20 +140,17 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
vt->values.resize(valcount);
for (int i = 0; i < valcount; i++) {
-
vt->values.write[i].time = rt[i];
vt->values.write[i].value = values[i];
}
if (d.has("transitions")) {
-
Vector<float> transitions = d["transitions"];
ERR_FAIL_COND_V(transitions.size() != valcount, false);
const float *rtr = transitions.ptr();
for (int i = 0; i < valcount; i++) {
-
vt->values.write[i].transition = rtr[i];
}
}
@@ -176,9 +159,9 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
return true;
} else if (track_get_type(track) == TYPE_METHOD) {
-
- while (track_get_key_count(track))
+ while (track_get_key_count(track)) {
track_remove_key(track, 0); //well shouldn't be set anyway
+ }
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("times"), false);
@@ -190,31 +173,26 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(times.size() != values.size(), false);
if (times.size()) {
-
int valcount = times.size();
const float *rt = times.ptr();
for (int i = 0; i < valcount; i++) {
-
track_insert_key(track, rt[i], values[i]);
}
if (d.has("transitions")) {
-
Vector<float> transitions = d["transitions"];
ERR_FAIL_COND_V(transitions.size() != valcount, false);
const float *rtr = transitions.ptr();
for (int i = 0; i < valcount; i++) {
-
track_set_key_transition(track, i, rtr[i]);
}
}
}
} else if (track_get_type(track) == TYPE_BEZIER) {
-
BezierTrack *bt = static_cast<BezierTrack *>(tracks[track]);
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("times"), false);
@@ -226,7 +204,6 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(times.size() * 5 != values.size(), false);
if (times.size()) {
-
int valcount = times.size();
const float *rt = times.ptr();
@@ -235,7 +212,6 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
bt->values.resize(valcount);
for (int i = 0; i < valcount; i++) {
-
bt->values.write[i].time = rt[i];
bt->values.write[i].transition = 0; //unused in bezier
bt->values.write[i].value.value = rv[i * 5 + 0];
@@ -248,7 +224,6 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
return true;
} else if (track_get_type(track) == TYPE_AUDIO) {
-
AudioTrack *ad = static_cast<AudioTrack *>(tracks[track]);
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("times"), false);
@@ -260,7 +235,6 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(clips.size() != times.size(), false);
if (times.size()) {
-
int valcount = times.size();
const float *rt = times.ptr();
@@ -268,14 +242,16 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
ad->values.clear();
for (int i = 0; i < valcount; i++) {
-
Dictionary d2 = clips[i];
- if (!d2.has("start_offset"))
+ if (!d2.has("start_offset")) {
continue;
- if (!d2.has("end_offset"))
+ }
+ if (!d2.has("end_offset")) {
continue;
- if (!d2.has("stream"))
+ }
+ if (!d2.has("stream")) {
continue;
+ }
TKey<AudioKey> ak;
ak.time = rt[i];
@@ -289,7 +265,6 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
return true;
} else if (track_get_type(track) == TYPE_ANIMATION) {
-
AnimationTrack *an = static_cast<AnimationTrack *>(tracks[track]);
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("times"), false);
@@ -301,7 +276,6 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
ERR_FAIL_COND_V(clips.size() != times.size(), false);
if (times.size()) {
-
int valcount = times.size();
const float *rt = times.ptr();
@@ -310,7 +284,6 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
an->values.resize(valcount);
for (int i = 0; i < valcount; i++) {
-
TKey<StringName> ak;
ak.time = rt[i];
ak.value = rc[i];
@@ -322,57 +295,65 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
} else {
return false;
}
- } else
+ } else {
return false;
- } else
+ }
+ } else {
return false;
+ }
return true;
}
bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
- if (name == "length")
+ if (name == "length") {
r_ret = length;
- else if (name == "loop")
+ } else if (name == "loop") {
r_ret = loop;
- else if (name == "step")
+ } else if (name == "step") {
r_ret = step;
- else if (name.begins_with("tracks/")) {
-
+ } else if (name.begins_with("tracks/")) {
int track = name.get_slicec('/', 1).to_int();
String what = name.get_slicec('/', 2);
ERR_FAIL_INDEX_V(track, tracks.size(), false);
if (what == "type") {
-
switch (track_get_type(track)) {
-
- case TYPE_TRANSFORM: r_ret = "transform"; break;
- case TYPE_VALUE: r_ret = "value"; break;
- case TYPE_METHOD: r_ret = "method"; break;
- case TYPE_BEZIER: r_ret = "bezier"; break;
- case TYPE_AUDIO: r_ret = "audio"; break;
- case TYPE_ANIMATION: r_ret = "animation"; break;
+ case TYPE_TRANSFORM:
+ r_ret = "transform";
+ break;
+ case TYPE_VALUE:
+ r_ret = "value";
+ break;
+ case TYPE_METHOD:
+ r_ret = "method";
+ break;
+ case TYPE_BEZIER:
+ r_ret = "bezier";
+ break;
+ case TYPE_AUDIO:
+ r_ret = "audio";
+ break;
+ case TYPE_ANIMATION:
+ r_ret = "animation";
+ break;
}
return true;
- } else if (what == "path")
+ } else if (what == "path") {
r_ret = track_get_path(track);
- else if (what == "interp")
+ } else if (what == "interp") {
r_ret = track_get_interpolation_type(track);
- else if (what == "loop_wrap")
+ } else if (what == "loop_wrap") {
r_ret = track_get_interpolation_loop_wrap(track);
- else if (what == "imported")
+ } else if (what == "imported") {
r_ret = track_is_imported(track);
- else if (what == "enabled")
+ } else if (what == "enabled") {
r_ret = track_is_enabled(track);
- else if (what == "keys") {
-
+ } else if (what == "keys") {
if (track_get_type(track) == TYPE_TRANSFORM) {
-
Vector<float> keys;
int kk = track_get_key_count(track);
keys.resize(kk * 12);
@@ -381,7 +362,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
int idx = 0;
for (int i = 0; i < track_get_key_count(track); i++) {
-
Vector3 loc;
Quat rot;
Vector3 scale;
@@ -407,7 +387,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
return true;
} else if (track_get_type(track) == TYPE_VALUE) {
-
const ValueTrack *vt = static_cast<const ValueTrack *>(tracks[track]);
Dictionary d;
@@ -430,7 +409,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
const TKey<Variant> *vls = vt->values.ptr();
for (int i = 0; i < kk; i++) {
-
wti[idx] = vls[i].time;
wtr[idx] = vls[i].transition;
key_values[idx] = vls[i].value;
@@ -449,7 +427,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
return true;
} else if (track_get_type(track) == TYPE_METHOD) {
-
Dictionary d;
Vector<float> key_times;
@@ -467,7 +444,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
int idx = 0;
for (int i = 0; i < track_get_key_count(track); i++) {
-
wti[idx] = track_get_key_time(track, i);
wtr[idx] = track_get_key_transition(track, i);
key_values[idx] = track_get_key_value(track, i);
@@ -485,7 +461,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
return true;
} else if (track_get_type(track) == TYPE_BEZIER) {
-
const BezierTrack *bt = static_cast<const BezierTrack *>(tracks[track]);
Dictionary d;
@@ -506,7 +481,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
const TKey<BezierKey> *vls = bt->values.ptr();
for (int i = 0; i < kk; i++) {
-
wti[idx] = vls[i].time;
wpo[idx * 5 + 0] = vls[i].value.value;
wpo[idx * 5 + 1] = vls[i].value.in_handle.x;
@@ -523,7 +497,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
return true;
} else if (track_get_type(track) == TYPE_AUDIO) {
-
const AudioTrack *ad = static_cast<const AudioTrack *>(tracks[track]);
Dictionary d;
@@ -542,7 +515,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
const TKey<AudioKey> *vls = ad->values.ptr();
for (int i = 0; i < kk; i++) {
-
wti[idx] = vls[i].time;
Dictionary clip;
clip["start_offset"] = vls[i].value.start_offset;
@@ -559,7 +531,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
return true;
} else if (track_get_type(track) == TYPE_ANIMATION) {
-
const AnimationTrack *an = static_cast<const AnimationTrack *>(tracks[track]);
Dictionary d;
@@ -578,7 +549,6 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
const TKey<StringName> *vls = an->values.ptr();
for (int i = 0; i < kk; i++) {
-
wti[i] = vls[i].time;
wcl[i] = vls[i].value;
}
@@ -590,17 +560,18 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
return true;
}
- } else
+ } else {
return false;
- } else
+ }
+ } else {
return false;
+ }
return true;
}
void Animation::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < tracks.size(); i++) {
-
p_list->push_back(PropertyInfo(Variant::STRING, "tracks/" + itos(i) + "/type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::NODE_PATH, "tracks/" + itos(i) + "/path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::INT, "tracks/" + itos(i) + "/interp", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
@@ -612,44 +583,36 @@ void Animation::_get_property_list(List<PropertyInfo> *p_list) const {
}
int Animation::add_track(TrackType p_type, int p_at_pos) {
-
- if (p_at_pos < 0 || p_at_pos >= tracks.size())
+ if (p_at_pos < 0 || p_at_pos >= tracks.size()) {
p_at_pos = tracks.size();
+ }
switch (p_type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = memnew(TransformTrack);
tracks.insert(p_at_pos, tt);
} break;
case TYPE_VALUE: {
-
tracks.insert(p_at_pos, memnew(ValueTrack));
} break;
case TYPE_METHOD: {
-
tracks.insert(p_at_pos, memnew(MethodTrack));
} break;
case TYPE_BEZIER: {
-
tracks.insert(p_at_pos, memnew(BezierTrack));
} break;
case TYPE_AUDIO: {
-
tracks.insert(p_at_pos, memnew(AudioTrack));
} break;
case TYPE_ANIMATION: {
-
tracks.insert(p_at_pos, memnew(AnimationTrack));
} break;
default: {
-
ERR_PRINT("Unknown track type");
}
}
@@ -659,44 +622,36 @@ int Animation::add_track(TrackType p_type, int p_at_pos) {
}
void Animation::remove_track(int p_track) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
_clear(tt->transforms);
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
_clear(vt->values);
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
_clear(mt->methods);
} break;
case TYPE_BEZIER: {
-
BezierTrack *bz = static_cast<BezierTrack *>(t);
_clear(bz->values);
} break;
case TYPE_AUDIO: {
-
AudioTrack *ad = static_cast<AudioTrack *>(t);
_clear(ad->values);
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *an = static_cast<AnimationTrack *>(t);
_clear(an->values);
@@ -710,18 +665,15 @@ void Animation::remove_track(int p_track) {
}
int Animation::get_track_count() const {
-
return tracks.size();
}
Animation::TrackType Animation::track_get_type(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), TYPE_TRANSFORM);
return tracks[p_track]->type;
}
void Animation::track_set_path(int p_track, const NodePath &p_path) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
tracks[p_track]->path = p_path;
emit_changed();
@@ -729,23 +681,20 @@ void Animation::track_set_path(int p_track, const NodePath &p_path) {
}
NodePath Animation::track_get_path(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), NodePath());
return tracks[p_track]->path;
}
int Animation::find_track(const NodePath &p_path) const {
-
for (int i = 0; i < tracks.size(); i++) {
-
- if (tracks[i]->path == p_path)
+ if (tracks[i]->path == p_path) {
return i;
+ }
};
return -1;
};
void Animation::track_set_interpolation_type(int p_track, InterpolationType p_interp) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
ERR_FAIL_INDEX(p_interp, 3);
tracks[p_track]->interpolation = p_interp;
@@ -753,7 +702,6 @@ void Animation::track_set_interpolation_type(int p_track, InterpolationType p_in
}
Animation::InterpolationType Animation::track_get_interpolation_type(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), INTERPOLATION_NEAREST);
return tracks[p_track]->interpolation;
}
@@ -765,7 +713,6 @@ void Animation::track_set_interpolation_loop_wrap(int p_track, bool p_enable) {
}
bool Animation::track_get_interpolation_loop_wrap(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), INTERPOLATION_NEAREST);
return tracks[p_track]->loop_wrap;
}
@@ -796,23 +743,20 @@ int Animation::_insert_pos(float p_time, T& p_keys) {
}
}
+
*/
template <class T, class V>
int Animation::_insert(float p_time, T &p_keys, const V &p_value) {
-
int idx = p_keys.size();
while (true) {
-
// Condition for replacement.
if (idx > 0 && Math::is_equal_approx(p_keys[idx - 1].time, p_time)) {
-
p_keys.write[idx - 1] = p_value;
return idx - 1;
// Condition for insert.
} else if (idx == 0 || p_keys[idx - 1].time < p_time) {
-
p_keys.insert(idx, p_value);
return idx;
}
@@ -825,12 +769,10 @@ int Animation::_insert(float p_time, T &p_keys, const V &p_value) {
template <class T>
void Animation::_clear(T &p_keys) {
-
p_keys.clear();
}
Error Animation::transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
Track *t = tracks[p_track];
@@ -838,18 +780,20 @@ Error Animation::transform_track_get_key(int p_track, int p_key, Vector3 *r_loc,
ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, ERR_INVALID_PARAMETER);
ERR_FAIL_INDEX_V(p_key, tt->transforms.size(), ERR_INVALID_PARAMETER);
- if (r_loc)
+ if (r_loc) {
*r_loc = tt->transforms[p_key].value.loc;
- if (r_rot)
+ }
+ if (r_rot) {
*r_rot = tt->transforms[p_key].value.rot;
- if (r_scale)
+ }
+ if (r_scale) {
*r_scale = tt->transforms[p_key].value.scale;
+ }
return OK;
}
int Animation::transform_track_insert_key(int p_track, float p_time, const Vector3 &p_loc, const Quat &p_rot, const Vector3 &p_scale) {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, -1);
@@ -868,55 +812,47 @@ int Animation::transform_track_insert_key(int p_track, float p_time, const Vecto
}
void Animation::track_remove_key_at_position(int p_track, float p_pos) {
-
int idx = track_find_key(p_track, p_pos, true);
ERR_FAIL_COND(idx < 0);
track_remove_key(p_track, idx);
}
void Animation::track_remove_key(int p_track, int p_idx) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX(p_idx, tt->transforms.size());
tt->transforms.remove(p_idx);
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX(p_idx, vt->values.size());
vt->values.remove(p_idx);
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX(p_idx, mt->methods.size());
mt->methods.remove(p_idx);
} break;
case TYPE_BEZIER: {
-
BezierTrack *bz = static_cast<BezierTrack *>(t);
ERR_FAIL_INDEX(p_idx, bz->values.size());
bz->values.remove(p_idx);
} break;
case TYPE_AUDIO: {
-
AudioTrack *ad = static_cast<AudioTrack *>(t);
ERR_FAIL_INDEX(p_idx, ad->values.size());
ad->values.remove(p_idx);
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *an = static_cast<AnimationTrack *>(t);
ERR_FAIL_INDEX(p_idx, an->values.size());
an->values.remove(p_idx);
@@ -928,74 +864,79 @@ void Animation::track_remove_key(int p_track, int p_idx) {
}
int Animation::track_find_key(int p_track, float p_time, bool p_exact) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
switch (t->type) {
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
int k = _find(tt->transforms, p_time);
- if (k < 0 || k >= tt->transforms.size())
+ if (k < 0 || k >= tt->transforms.size()) {
return -1;
- if (tt->transforms[k].time != p_time && p_exact)
+ }
+ if (tt->transforms[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
int k = _find(vt->values, p_time);
- if (k < 0 || k >= vt->values.size())
+ if (k < 0 || k >= vt->values.size()) {
return -1;
- if (vt->values[k].time != p_time && p_exact)
+ }
+ if (vt->values[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
int k = _find(mt->methods, p_time);
- if (k < 0 || k >= mt->methods.size())
+ if (k < 0 || k >= mt->methods.size()) {
return -1;
- if (mt->methods[k].time != p_time && p_exact)
+ }
+ if (mt->methods[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
int k = _find(bt->values, p_time);
- if (k < 0 || k >= bt->values.size())
+ if (k < 0 || k >= bt->values.size()) {
return -1;
- if (bt->values[k].time != p_time && p_exact)
+ }
+ if (bt->values[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
int k = _find(at->values, p_time);
- if (k < 0 || k >= at->values.size())
+ if (k < 0 || k >= at->values.size()) {
return -1;
- if (at->values[k].time != p_time && p_exact)
+ }
+ if (at->values[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
int k = _find(at->values, p_time);
- if (k < 0 || k >= at->values.size())
+ if (k < 0 || k >= at->values.size()) {
return -1;
- if (at->values[k].time != p_time && p_exact)
+ }
+ if (at->values[k].time != p_time && p_exact) {
return -1;
+ }
return k;
} break;
@@ -1005,33 +946,32 @@ int Animation::track_find_key(int p_track, float p_time, bool p_exact) const {
}
void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key, float p_transition) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
Dictionary d = p_key;
Vector3 loc;
- if (d.has("location"))
+ if (d.has("location")) {
loc = d["location"];
+ }
Quat rot;
- if (d.has("rotation"))
+ if (d.has("rotation")) {
rot = d["rotation"];
+ }
Vector3 scale;
- if (d.has("scale"))
+ if (d.has("scale")) {
scale = d["scale"];
+ }
int idx = transform_track_insert_key(p_track, p_time, loc, rot, scale);
track_set_key_transition(p_track, idx, p_transition);
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
TKey<Variant> k;
@@ -1042,7 +982,6 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_COND(p_key.get_type() != Variant::DICTIONARY);
@@ -1062,7 +1001,6 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
Array arr = p_key;
@@ -1079,7 +1017,6 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
Dictionary k = p_key;
@@ -1096,7 +1033,6 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
TKey<StringName> ak;
@@ -1112,40 +1048,32 @@ void Animation::track_insert_key(int p_track, float p_time, const Variant &p_key
}
int Animation::track_get_key_count(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
return tt->transforms.size();
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
return vt->values.size();
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
return mt->methods.size();
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
return bt->values.size();
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
return at->values.size();
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
return at->values.size();
} break;
@@ -1155,14 +1083,11 @@ int Animation::track_get_key_count(int p_track) const {
}
Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), Variant());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), Variant());
@@ -1174,14 +1099,12 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
return d;
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), Variant());
return vt->values[p_key_idx].value;
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), Variant());
Dictionary d;
@@ -1191,7 +1114,6 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, bt->values.size(), Variant());
@@ -1206,7 +1128,6 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), Variant());
@@ -1218,7 +1139,6 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), Variant());
@@ -1231,48 +1151,40 @@ Variant Animation::track_get_key_value(int p_track, int p_key_idx) const {
}
float Animation::track_get_key_time(int p_track, int p_key_idx) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), -1);
return tt->transforms[p_key_idx].time;
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), -1);
return vt->values[p_key_idx].time;
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), -1);
return mt->methods[p_key_idx].time;
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, bt->values.size(), -1);
return bt->values[p_key_idx].time;
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), -1);
return at->values[p_key_idx].time;
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, at->values.size(), -1);
return at->values[p_key_idx].time;
@@ -1284,14 +1196,11 @@ float Animation::track_get_key_time(int p_track, int p_key_idx) const {
}
void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, tt->transforms.size());
TKey<TransformKey> key = tt->transforms[p_key_idx];
@@ -1301,7 +1210,6 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
return;
}
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, vt->values.size());
TKey<Variant> key = vt->values[p_key_idx];
@@ -1311,7 +1219,6 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
return;
}
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
MethodKey key = mt->methods[p_key_idx];
@@ -1321,7 +1228,6 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
return;
}
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, bt->values.size());
TKey<BezierKey> key = bt->values[p_key_idx];
@@ -1331,7 +1237,6 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
return;
}
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, at->values.size());
TKey<AudioKey> key = at->values[p_key_idx];
@@ -1341,7 +1246,6 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
return;
}
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, at->values.size());
TKey<StringName> key = at->values[p_key_idx];
@@ -1356,42 +1260,34 @@ void Animation::track_set_key_time(int p_track, int p_key_idx, float p_time) {
}
float Animation::track_get_key_transition(int p_track, int p_key_idx) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, tt->transforms.size(), -1);
return tt->transforms[p_key_idx].transition;
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, vt->values.size(), -1);
return vt->values[p_key_idx].transition;
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX_V(p_key_idx, mt->methods.size(), -1);
return mt->methods[p_key_idx].transition;
} break;
case TYPE_BEZIER: {
-
return 1; //bezier does not really use transitions
} break;
case TYPE_AUDIO: {
-
return 1; //audio does not really use transitions
} break;
case TYPE_ANIMATION: {
-
return 1; //animation does not really use transitions
} break;
}
@@ -1400,29 +1296,28 @@ float Animation::track_get_key_transition(int p_track, int p_key_idx) const {
}
void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p_value) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, tt->transforms.size());
Dictionary d = p_value;
- if (d.has("location"))
+ if (d.has("location")) {
tt->transforms.write[p_key_idx].value.loc = d["location"];
- if (d.has("rotation"))
+ }
+ if (d.has("rotation")) {
tt->transforms.write[p_key_idx].value.rot = d["rotation"];
- if (d.has("scale"))
+ }
+ if (d.has("scale")) {
tt->transforms.write[p_key_idx].value.scale = d["scale"];
+ }
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, vt->values.size());
@@ -1430,20 +1325,20 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
Dictionary d = p_value;
- if (d.has("method"))
+ if (d.has("method")) {
mt->methods.write[p_key_idx].method = d["method"];
- if (d.has("args"))
+ }
+ if (d.has("args")) {
mt->methods.write[p_key_idx].params = d["args"];
+ }
} break;
case TYPE_BEZIER: {
-
BezierTrack *bt = static_cast<BezierTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, bt->values.size());
@@ -1458,7 +1353,6 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
} break;
case TYPE_AUDIO: {
-
AudioTrack *at = static_cast<AudioTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, at->values.size());
@@ -1473,7 +1367,6 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
} break;
case TYPE_ANIMATION: {
-
AnimationTrack *at = static_cast<AnimationTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, at->values.size());
@@ -1486,27 +1379,22 @@ void Animation::track_set_key_value(int p_track, int p_key_idx, const Variant &p
}
void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_transition) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
TransformTrack *tt = static_cast<TransformTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, tt->transforms.size());
tt->transforms.write[p_key_idx].transition = p_transition;
} break;
case TYPE_VALUE: {
-
ValueTrack *vt = static_cast<ValueTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, vt->values.size());
vt->values.write[p_key_idx].transition = p_transition;
} break;
case TYPE_METHOD: {
-
MethodTrack *mt = static_cast<MethodTrack *>(t);
ERR_FAIL_INDEX(p_key_idx, mt->methods.size());
mt->methods.write[p_key_idx].transition = p_transition;
@@ -1524,42 +1412,43 @@ void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_tra
template <class K>
int Animation::_find(const Vector<K> &p_keys, float p_time) const {
-
int len = p_keys.size();
- if (len == 0)
+ if (len == 0) {
return -2;
+ }
int low = 0;
int high = len - 1;
int middle = 0;
#ifdef DEBUG_ENABLED
- if (low > high)
+ if (low > high) {
ERR_PRINT("low > high, this may be a bug");
+ }
#endif
const K *keys = &p_keys[0];
while (low <= high) {
-
middle = (low + high) / 2;
if (Math::is_equal_approx(p_time, keys[middle].time)) { //match
return middle;
- } else if (p_time < keys[middle].time)
+ } else if (p_time < keys[middle].time) {
high = middle - 1; //search low end of array
- else
+ } else {
low = middle + 1; //search high end of array
+ }
}
- if (keys[middle].time > p_time)
+ if (keys[middle].time > p_time) {
middle--;
+ }
return middle;
}
Animation::TransformKey Animation::_interpolate(const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, float p_c) const {
-
TransformKey ret;
ret.loc = _interpolate(p_a.loc, p_b.loc, p_c);
ret.rot = _interpolate(p_a.rot, p_b.rot, p_c);
@@ -1569,27 +1458,24 @@ Animation::TransformKey Animation::_interpolate(const Animation::TransformKey &p
}
Vector3 Animation::_interpolate(const Vector3 &p_a, const Vector3 &p_b, float p_c) const {
-
- return p_a.linear_interpolate(p_b, p_c);
+ return p_a.lerp(p_b, p_c);
}
-Quat Animation::_interpolate(const Quat &p_a, const Quat &p_b, float p_c) const {
+Quat Animation::_interpolate(const Quat &p_a, const Quat &p_b, float p_c) const {
return p_a.slerp(p_b, p_c);
}
-Variant Animation::_interpolate(const Variant &p_a, const Variant &p_b, float p_c) const {
+Variant Animation::_interpolate(const Variant &p_a, const Variant &p_b, float p_c) const {
Variant dst;
Variant::interpolate(p_a, p_b, p_c, dst);
return dst;
}
float Animation::_interpolate(const float &p_a, const float &p_b, float p_c) const {
-
return p_a * (1.0 - p_c) + p_b * p_c;
}
Animation::TransformKey Animation::_cubic_interpolate(const Animation::TransformKey &p_pre_a, const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, const Animation::TransformKey &p_post_b, float p_c) const {
-
Animation::TransformKey tk;
tk.loc = p_a.loc.cubic_interpolate(p_b.loc, p_pre_a.loc, p_post_b.loc, p_c);
@@ -1598,16 +1484,16 @@ Animation::TransformKey Animation::_cubic_interpolate(const Animation::Transform
return tk;
}
-Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, float p_c) const {
+Vector3 Animation::_cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, float p_c) const {
return p_a.cubic_interpolate(p_b, p_pre_a, p_post_b, p_c);
}
-Quat Animation::_cubic_interpolate(const Quat &p_pre_a, const Quat &p_a, const Quat &p_b, const Quat &p_post_b, float p_c) const {
+Quat Animation::_cubic_interpolate(const Quat &p_pre_a, const Quat &p_a, const Quat &p_b, const Quat &p_post_b, float p_c) const {
return p_a.cubic_slerp(p_b, p_pre_a, p_post_b, p_c);
}
-Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, float p_c) const {
+Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, float p_c) const {
Variant::Type type_a = p_a.get_type();
Variant::Type type_b = p_b.get_type();
Variant::Type type_pa = p_pre_a.get_type();
@@ -1638,14 +1524,11 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
(-p0 + 3.0f * p1 - 3.0f * p2 + p3) * t3);
} else if ((vformat & (vformat - 1))) {
-
return p_a; //can't interpolate, mix of types
}
switch (type_a) {
-
case Variant::VECTOR2: {
-
Vector2 a = p_a;
Vector2 b = p_b;
Vector2 pa = p_pre_a;
@@ -1654,7 +1537,6 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
return a.cubic_interpolate(b, pa, pb, p_c);
}
case Variant::RECT2: {
-
Rect2 a = p_a;
Rect2 b = p_b;
Rect2 pa = p_pre_a;
@@ -1665,7 +1547,6 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c));
}
case Variant::VECTOR3: {
-
Vector3 a = p_a;
Vector3 b = p_b;
Vector3 pa = p_pre_a;
@@ -1674,7 +1555,6 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
return a.cubic_interpolate(b, pa, pb, p_c);
}
case Variant::QUAT: {
-
Quat a = p_a;
Quat b = p_b;
Quat pa = p_pre_a;
@@ -1683,7 +1563,6 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
return a.cubic_slerp(b, pa, pb, p_c);
}
case Variant::AABB: {
-
AABB a = p_a;
AABB b = p_b;
AABB pa = p_pre_a;
@@ -1694,31 +1573,31 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c));
}
default: {
-
return _interpolate(p_a, p_b, p_c);
}
}
}
-float Animation::_cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const {
+float Animation::_cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const {
return _interpolate(p_a, p_b, p_c);
}
template <class T>
T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, InterpolationType p_interp, bool p_loop_wrap, bool *p_ok) const {
-
int len = _find(p_keys, length) + 1; // try to find last key (there may be more past the end)
if (len <= 0) {
// (-1 or -2 returned originally) (plus one above)
// meaning no keys, or only key time is larger than length
- if (p_ok)
+ if (p_ok) {
*p_ok = false;
+ }
return T();
} else if (len == 1) { // one key found (0+1), return it
- if (p_ok)
+ if (p_ok) {
*p_ok = true;
+ }
return p_keys[0].value;
}
@@ -1734,28 +1613,27 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola
if (loop && p_loop_wrap) {
// loop
if (idx >= 0) {
-
if ((idx + 1) < len) {
-
next = idx + 1;
float delta = p_keys[next].time - p_keys[idx].time;
float from = p_time - p_keys[idx].time;
- if (Math::is_zero_approx(delta))
+ if (Math::is_zero_approx(delta)) {
c = 0;
- else
+ } else {
c = from / delta;
+ }
} else {
-
next = 0;
float delta = (length - p_keys[idx].time) + p_keys[next].time;
float from = p_time - p_keys[idx].time;
- if (Math::is_zero_approx(delta))
+ if (Math::is_zero_approx(delta)) {
c = 0;
- else
+ } else {
c = from / delta;
+ }
}
} else {
@@ -1763,51 +1641,53 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola
idx = len - 1;
next = 0;
float endtime = (length - p_keys[idx].time);
- if (endtime < 0) // may be keys past the end
+ if (endtime < 0) { // may be keys past the end
endtime = 0;
+ }
float delta = endtime + p_keys[next].time;
float from = endtime + p_time;
- if (Math::is_zero_approx(delta))
+ if (Math::is_zero_approx(delta)) {
c = 0;
- else
+ } else {
c = from / delta;
+ }
}
} else { // no loop
if (idx >= 0) {
-
if ((idx + 1) < len) {
-
next = idx + 1;
float delta = p_keys[next].time - p_keys[idx].time;
float from = p_time - p_keys[idx].time;
- if (Math::is_zero_approx(delta))
+ if (Math::is_zero_approx(delta)) {
c = 0;
- else
+ } else {
c = from / delta;
+ }
} else {
-
next = idx;
}
} else {
-
// only allow extending first key to anim start if looping
- if (loop)
+ if (loop) {
idx = next = 0;
- else
+ } else {
result = false;
+ }
}
}
- if (p_ok)
+ if (p_ok) {
*p_ok = result;
- if (!result)
+ }
+ if (!result) {
return T();
+ }
float tr = p_keys[idx].transition;
@@ -1817,39 +1697,37 @@ T Animation::_interpolate(const Vector<TKey<T>> &p_keys, float p_time, Interpola
}
if (tr != 1.0) {
-
c = Math::ease(c, tr);
}
switch (p_interp) {
-
case INTERPOLATION_NEAREST: {
-
return p_keys[idx].value;
} break;
case INTERPOLATION_LINEAR: {
-
return _interpolate(p_keys[idx].value, p_keys[next].value, c);
} break;
case INTERPOLATION_CUBIC: {
int pre = idx - 1;
- if (pre < 0)
+ if (pre < 0) {
pre = 0;
+ }
int post = next + 1;
- if (post >= len)
+ if (post >= len) {
post = next;
+ }
return _cubic_interpolate(p_keys[pre].value, p_keys[idx].value, p_keys[next].value, p_keys[post].value, c);
} break;
- default: return p_keys[idx].value;
+ default:
+ return p_keys[idx].value;
}
// do a barrel roll
}
Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), ERR_INVALID_PARAMETER);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_TRANSFORM, ERR_INVALID_PARAMETER);
@@ -1860,23 +1738,26 @@ Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3
TransformKey tk = _interpolate(tt->transforms, p_time, tt->interpolation, tt->loop_wrap, &ok);
- if (!ok)
+ if (!ok) {
return ERR_UNAVAILABLE;
+ }
- if (r_loc)
+ if (r_loc) {
*r_loc = tk.loc;
+ }
- if (r_rot)
+ if (r_rot) {
*r_rot = tk.rot;
+ }
- if (r_scale)
+ if (r_scale) {
*r_scale = tk.scale;
+ }
return OK;
}
Variant Animation::value_track_interpolate(int p_track, float p_time) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_VALUE, Variant());
@@ -1887,7 +1768,6 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const {
Variant res = _interpolate(vt->values, p_time, (vt->update_mode == UPDATE_CONTINUOUS || vt->update_mode == UPDATE_CAPTURE) ? vt->interpolation : INTERPOLATION_NEAREST, vt->loop_wrap, &ok);
if (ok) {
-
return res;
}
@@ -1895,9 +1775,9 @@ Variant Animation::value_track_interpolate(int p_track, float p_time) const {
}
void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const {
-
- if (from_time != length && to_time == length)
+ if (from_time != length && to_time == length) {
to_time = length * 1.001; //include a little more if at the end
+ }
int to = _find(vt->values, to_time);
if (to >= 0 && from_time == to_time && vt->values[to].time == from_time) {
@@ -1908,29 +1788,30 @@ void Animation::_value_track_get_key_indices_in_range(const ValueTrack *vt, floa
// can't really send the events == time, will be sent in the next frame.
// if event>=len then it will probably never be requested by the anim player.
- if (to >= 0 && vt->values[to].time >= to_time)
+ if (to >= 0 && vt->values[to].time >= to_time) {
to--;
+ }
- if (to < 0)
+ if (to < 0) {
return; // not bother
+ }
int from = _find(vt->values, from_time);
// position in the right first event.+
- if (from < 0 || vt->values[from].time < from_time)
+ if (from < 0 || vt->values[from].time < from_time) {
from++;
+ }
int max = vt->values.size();
for (int i = from; i <= to; i++) {
-
ERR_CONTINUE(i < 0 || i >= max); // shouldn't happen
p_indices->push_back(i);
}
}
void Animation::value_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_VALUE);
@@ -1940,11 +1821,11 @@ void Animation::value_track_get_key_indices(int p_track, float p_time, float p_d
float from_time = p_time - p_delta;
float to_time = p_time;
- if (from_time > to_time)
+ if (from_time > to_time) {
SWAP(from_time, to_time);
+ }
if (loop) {
-
from_time = Math::fposmod(from_time, length);
to_time = Math::fposmod(to_time, length);
@@ -1955,23 +1836,25 @@ void Animation::value_track_get_key_indices(int p_track, float p_time, float p_d
return;
}
} else {
-
- if (from_time < 0)
+ if (from_time < 0) {
from_time = 0;
- if (from_time > length)
+ }
+ if (from_time > length) {
from_time = length;
+ }
- if (to_time < 0)
+ if (to_time < 0) {
to_time = 0;
- if (to_time > length)
+ }
+ if (to_time > length) {
to_time = length;
+ }
}
_value_track_get_key_indices_in_range(vt, from_time, to_time, p_indices);
}
void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_VALUE);
@@ -1982,7 +1865,6 @@ void Animation::value_track_set_update_mode(int p_track, UpdateMode p_mode) {
}
Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), UPDATE_CONTINUOUS);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_VALUE, UPDATE_CONTINUOUS);
@@ -1993,97 +1875,93 @@ Animation::UpdateMode Animation::value_track_get_update_mode(int p_track) const
template <class T>
void Animation::_track_get_key_indices_in_range(const Vector<T> &p_array, float from_time, float to_time, List<int> *p_indices) const {
-
- if (from_time != length && to_time == length)
+ if (from_time != length && to_time == length) {
to_time = length * 1.01; //include a little more if at the end
+ }
int to = _find(p_array, to_time);
// can't really send the events == time, will be sent in the next frame.
// if event>=len then it will probably never be requested by the anim player.
- if (to >= 0 && p_array[to].time >= to_time)
+ if (to >= 0 && p_array[to].time >= to_time) {
to--;
+ }
- if (to < 0)
+ if (to < 0) {
return; // not bother
+ }
int from = _find(p_array, from_time);
// position in the right first event.+
- if (from < 0 || p_array[from].time < from_time)
+ if (from < 0 || p_array[from].time < from_time) {
from++;
+ }
int max = p_array.size();
for (int i = from; i <= to; i++) {
-
ERR_CONTINUE(i < 0 || i >= max); // shouldn't happen
p_indices->push_back(i);
}
}
void Animation::track_get_key_indices_in_range(int p_track, float p_time, float p_delta, List<int> *p_indices) const {
-
ERR_FAIL_INDEX(p_track, tracks.size());
const Track *t = tracks[p_track];
float from_time = p_time - p_delta;
float to_time = p_time;
- if (from_time > to_time)
+ if (from_time > to_time) {
SWAP(from_time, to_time);
+ }
if (loop) {
-
- if (from_time > length || from_time < 0)
+ if (from_time > length || from_time < 0) {
from_time = Math::fposmod(from_time, length);
+ }
- if (to_time > length || to_time < 0)
+ if (to_time > length || to_time < 0) {
to_time = Math::fposmod(to_time, length);
+ }
if (from_time > to_time) {
// handle loop by splitting
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
const TransformTrack *tt = static_cast<const TransformTrack *>(t);
_track_get_key_indices_in_range(tt->transforms, from_time, length, p_indices);
_track_get_key_indices_in_range(tt->transforms, 0, to_time, p_indices);
} break;
case TYPE_VALUE: {
-
const ValueTrack *vt = static_cast<const ValueTrack *>(t);
_track_get_key_indices_in_range(vt->values, from_time, length, p_indices);
_track_get_key_indices_in_range(vt->values, 0, to_time, p_indices);
} break;
case TYPE_METHOD: {
-
const MethodTrack *mt = static_cast<const MethodTrack *>(t);
_track_get_key_indices_in_range(mt->methods, from_time, length, p_indices);
_track_get_key_indices_in_range(mt->methods, 0, to_time, p_indices);
} break;
case TYPE_BEZIER: {
-
const BezierTrack *bz = static_cast<const BezierTrack *>(t);
_track_get_key_indices_in_range(bz->values, from_time, length, p_indices);
_track_get_key_indices_in_range(bz->values, 0, to_time, p_indices);
} break;
case TYPE_AUDIO: {
-
const AudioTrack *ad = static_cast<const AudioTrack *>(t);
_track_get_key_indices_in_range(ad->values, from_time, length, p_indices);
_track_get_key_indices_in_range(ad->values, 0, to_time, p_indices);
} break;
case TYPE_ANIMATION: {
-
const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
_track_get_key_indices_in_range(an->values, from_time, length, p_indices);
_track_get_key_indices_in_range(an->values, 0, to_time, p_indices);
@@ -2093,52 +1971,48 @@ void Animation::track_get_key_indices_in_range(int p_track, float p_time, float
return;
}
} else {
-
- if (from_time < 0)
+ if (from_time < 0) {
from_time = 0;
- if (from_time > length)
+ }
+ if (from_time > length) {
from_time = length;
+ }
- if (to_time < 0)
+ if (to_time < 0) {
to_time = 0;
- if (to_time > length)
+ }
+ if (to_time > length) {
to_time = length;
+ }
}
switch (t->type) {
-
case TYPE_TRANSFORM: {
-
const TransformTrack *tt = static_cast<const TransformTrack *>(t);
_track_get_key_indices_in_range(tt->transforms, from_time, to_time, p_indices);
} break;
case TYPE_VALUE: {
-
const ValueTrack *vt = static_cast<const ValueTrack *>(t);
_track_get_key_indices_in_range(vt->values, from_time, to_time, p_indices);
} break;
case TYPE_METHOD: {
-
const MethodTrack *mt = static_cast<const MethodTrack *>(t);
_track_get_key_indices_in_range(mt->methods, from_time, to_time, p_indices);
} break;
case TYPE_BEZIER: {
-
const BezierTrack *bz = static_cast<const BezierTrack *>(t);
_track_get_key_indices_in_range(bz->values, from_time, to_time, p_indices);
} break;
case TYPE_AUDIO: {
-
const AudioTrack *ad = static_cast<const AudioTrack *>(t);
_track_get_key_indices_in_range(ad->values, from_time, to_time, p_indices);
} break;
case TYPE_ANIMATION: {
-
const AnimationTrack *an = static_cast<const AnimationTrack *>(t);
_track_get_key_indices_in_range(an->values, from_time, to_time, p_indices);
@@ -2147,38 +2021,39 @@ void Animation::track_get_key_indices_in_range(int p_track, float p_time, float
}
void Animation::_method_track_get_key_indices_in_range(const MethodTrack *mt, float from_time, float to_time, List<int> *p_indices) const {
-
- if (from_time != length && to_time == length)
+ if (from_time != length && to_time == length) {
to_time = length * 1.01; //include a little more if at the end
+ }
int to = _find(mt->methods, to_time);
// can't really send the events == time, will be sent in the next frame.
// if event>=len then it will probably never be requested by the anim player.
- if (to >= 0 && mt->methods[to].time >= to_time)
+ if (to >= 0 && mt->methods[to].time >= to_time) {
to--;
+ }
- if (to < 0)
+ if (to < 0) {
return; // not bother
+ }
int from = _find(mt->methods, from_time);
// position in the right first event.+
- if (from < 0 || mt->methods[from].time < from_time)
+ if (from < 0 || mt->methods[from].time < from_time) {
from++;
+ }
int max = mt->methods.size();
for (int i = from; i <= to; i++) {
-
ERR_CONTINUE(i < 0 || i >= max); // shouldn't happen
p_indices->push_back(i);
}
}
void Animation::method_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_METHOD);
@@ -2188,16 +2063,18 @@ void Animation::method_track_get_key_indices(int p_track, float p_time, float p_
float from_time = p_time - p_delta;
float to_time = p_time;
- if (from_time > to_time)
+ if (from_time > to_time) {
SWAP(from_time, to_time);
+ }
if (loop) {
-
- if (from_time > length || from_time < 0)
+ if (from_time > length || from_time < 0) {
from_time = Math::fposmod(from_time, length);
+ }
- if (to_time > length || to_time < 0)
+ if (to_time > length || to_time < 0) {
to_time = Math::fposmod(to_time, length);
+ }
if (from_time > to_time) {
// handle loop by splitting
@@ -2206,22 +2083,25 @@ void Animation::method_track_get_key_indices(int p_track, float p_time, float p_
return;
}
} else {
-
- if (from_time < 0)
+ if (from_time < 0) {
from_time = 0;
- if (from_time > length)
+ }
+ if (from_time > length) {
from_time = length;
+ }
- if (to_time < 0)
+ if (to_time < 0) {
to_time = 0;
- if (to_time > length)
+ }
+ if (to_time > length) {
to_time = length;
+ }
}
_method_track_get_key_indices_in_range(mt, from_time, to_time, p_indices);
}
-Vector<Variant> Animation::method_track_get_params(int p_track, int p_key_idx) const {
+Vector<Variant> Animation::method_track_get_params(int p_track, int p_key_idx) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector<Variant>());
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_METHOD, Vector<Variant>());
@@ -2234,8 +2114,8 @@ Vector<Variant> Animation::method_track_get_params(int p_track, int p_key_idx) c
return mk.params;
}
-StringName Animation::method_track_get_name(int p_track, int p_key_idx) const {
+StringName Animation::method_track_get_name(int p_track, int p_key_idx) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), StringName());
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_METHOD, StringName());
@@ -2248,7 +2128,6 @@ StringName Animation::method_track_get_name(int p_track, int p_key_idx) const {
}
int Animation::bezier_track_insert_key(int p_track, float p_time, float p_value, const Vector2 &p_in_handle, const Vector2 &p_out_handle) {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_BEZIER, -1);
@@ -2275,7 +2154,6 @@ int Animation::bezier_track_insert_key(int p_track, float p_time, float p_value,
}
void Animation::bezier_track_set_key_value(int p_track, int p_index, float p_value) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_BEZIER);
@@ -2289,7 +2167,6 @@ void Animation::bezier_track_set_key_value(int p_track, int p_index, float p_val
}
void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const Vector2 &p_handle) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_BEZIER);
@@ -2304,8 +2181,8 @@ void Animation::bezier_track_set_key_in_handle(int p_track, int p_index, const V
}
emit_changed();
}
-void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle) {
+void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const Vector2 &p_handle) {
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_BEZIER);
@@ -2320,8 +2197,8 @@ void Animation::bezier_track_set_key_out_handle(int p_track, int p_index, const
}
emit_changed();
}
-float Animation::bezier_track_get_key_value(int p_track, int p_index) const {
+float Animation::bezier_track_get_key_value(int p_track, int p_index) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_BEZIER, 0);
@@ -2332,8 +2209,8 @@ float Animation::bezier_track_get_key_value(int p_track, int p_index) const {
return bt->values[p_index].value.value;
}
-Vector2 Animation::bezier_track_get_key_in_handle(int p_track, int p_index) const {
+Vector2 Animation::bezier_track_get_key_in_handle(int p_track, int p_index) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector2());
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_BEZIER, Vector2());
@@ -2344,8 +2221,8 @@ Vector2 Animation::bezier_track_get_key_in_handle(int p_track, int p_index) cons
return bt->values[p_index].value.in_handle;
}
-Vector2 Animation::bezier_track_get_key_out_handle(int p_track, int p_index) const {
+Vector2 Animation::bezier_track_get_key_out_handle(int p_track, int p_index) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), Vector2());
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_BEZIER, Vector2());
@@ -2415,7 +2292,6 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const {
//narrow high and low as much as possible
for (int i = 0; i < iterations; i++) {
-
middle = (low + high) / 2;
Vector2 interp = _bezier_interp(middle, start, start_out, end_in, end);
@@ -2432,11 +2308,10 @@ float Animation::bezier_track_interpolate(int p_track, float p_time) const {
Vector2 high_pos = _bezier_interp(high, start, start_out, end_in, end);
float c = (t - low_pos.x) / (high_pos.x - low_pos.x);
- return low_pos.linear_interpolate(high_pos, c).y;
+ return low_pos.lerp(high_pos, c).y;
}
int Animation::audio_track_insert_key(int p_track, float p_time, const RES &p_stream, float p_start_offset, float p_end_offset) {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_AUDIO, -1);
@@ -2447,11 +2322,13 @@ int Animation::audio_track_insert_key(int p_track, float p_time, const RES &p_st
k.time = p_time;
k.value.stream = p_stream;
k.value.start_offset = p_start_offset;
- if (k.value.start_offset < 0)
+ if (k.value.start_offset < 0) {
k.value.start_offset = 0;
+ }
k.value.end_offset = p_end_offset;
- if (k.value.end_offset < 0)
+ if (k.value.end_offset < 0) {
k.value.end_offset = 0;
+ }
int key = _insert(p_time, at->values, k);
@@ -2461,7 +2338,6 @@ int Animation::audio_track_insert_key(int p_track, float p_time, const RES &p_st
}
void Animation::audio_track_set_key_stream(int p_track, int p_key, const RES &p_stream) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_AUDIO);
@@ -2476,7 +2352,6 @@ void Animation::audio_track_set_key_stream(int p_track, int p_key, const RES &p_
}
void Animation::audio_track_set_key_start_offset(int p_track, int p_key, float p_offset) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_AUDIO);
@@ -2485,8 +2360,9 @@ void Animation::audio_track_set_key_start_offset(int p_track, int p_key, float p
ERR_FAIL_INDEX(p_key, at->values.size());
- if (p_offset < 0)
+ if (p_offset < 0) {
p_offset = 0;
+ }
at->values.write[p_key].value.start_offset = p_offset;
@@ -2494,7 +2370,6 @@ void Animation::audio_track_set_key_start_offset(int p_track, int p_key, float p
}
void Animation::audio_track_set_key_end_offset(int p_track, int p_key, float p_offset) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_AUDIO);
@@ -2503,8 +2378,9 @@ void Animation::audio_track_set_key_end_offset(int p_track, int p_key, float p_o
ERR_FAIL_INDEX(p_key, at->values.size());
- if (p_offset < 0)
+ if (p_offset < 0) {
p_offset = 0;
+ }
at->values.write[p_key].value.end_offset = p_offset;
@@ -2512,7 +2388,6 @@ void Animation::audio_track_set_key_end_offset(int p_track, int p_key, float p_o
}
RES Animation::audio_track_get_key_stream(int p_track, int p_key) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), RES());
const Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_AUDIO, RES());
@@ -2523,8 +2398,8 @@ RES Animation::audio_track_get_key_stream(int p_track, int p_key) const {
return at->values[p_key].value.stream;
}
-float Animation::audio_track_get_key_start_offset(int p_track, int p_key) const {
+float Animation::audio_track_get_key_start_offset(int p_track, int p_key) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
const Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_AUDIO, 0);
@@ -2535,8 +2410,8 @@ float Animation::audio_track_get_key_start_offset(int p_track, int p_key) const
return at->values[p_key].value.start_offset;
}
-float Animation::audio_track_get_key_end_offset(int p_track, int p_key) const {
+float Animation::audio_track_get_key_end_offset(int p_track, int p_key) const {
ERR_FAIL_INDEX_V(p_track, tracks.size(), 0);
const Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_AUDIO, 0);
@@ -2551,7 +2426,6 @@ float Animation::audio_track_get_key_end_offset(int p_track, int p_key) const {
//
int Animation::animation_track_insert_key(int p_track, float p_time, const StringName &p_animation) {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), -1);
Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_ANIMATION, -1);
@@ -2570,7 +2444,6 @@ int Animation::animation_track_insert_key(int p_track, float p_time, const Strin
}
void Animation::animation_track_set_key_animation(int p_track, int p_key, const StringName &p_animation) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
Track *t = tracks[p_track];
ERR_FAIL_COND(t->type != TYPE_ANIMATION);
@@ -2585,7 +2458,6 @@ void Animation::animation_track_set_key_animation(int p_track, int p_key, const
}
StringName Animation::animation_track_get_key_animation(int p_track, int p_key) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), StringName());
const Track *t = tracks[p_track];
ERR_FAIL_COND_V(t->type != TYPE_ANIMATION, StringName());
@@ -2598,57 +2470,49 @@ StringName Animation::animation_track_get_key_animation(int p_track, int p_key)
}
void Animation::set_length(float p_length) {
-
if (p_length < ANIM_MIN_LENGTH) {
p_length = ANIM_MIN_LENGTH;
}
length = p_length;
emit_changed();
}
-float Animation::get_length() const {
+float Animation::get_length() const {
return length;
}
void Animation::set_loop(bool p_enabled) {
-
loop = p_enabled;
emit_changed();
}
-bool Animation::has_loop() const {
+bool Animation::has_loop() const {
return loop;
}
void Animation::track_set_imported(int p_track, bool p_imported) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
tracks[p_track]->imported = p_imported;
}
bool Animation::track_is_imported(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
return tracks[p_track]->imported;
}
void Animation::track_set_enabled(int p_track, bool p_enabled) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
tracks[p_track]->enabled = p_enabled;
emit_changed();
}
bool Animation::track_is_enabled(int p_track) const {
-
ERR_FAIL_INDEX_V(p_track, tracks.size(), false);
return tracks[p_track]->enabled;
}
void Animation::track_move_up(int p_track) {
-
if (p_track >= 0 && p_track < (tracks.size() - 1)) {
-
SWAP(tracks.write[p_track], tracks.write[p_track + 1]);
}
@@ -2657,9 +2521,7 @@ void Animation::track_move_up(int p_track) {
}
void Animation::track_move_down(int p_track) {
-
if (p_track > 0 && p_track < tracks.size()) {
-
SWAP(tracks.write[p_track], tracks.write[p_track - 1]);
}
@@ -2668,11 +2530,11 @@ void Animation::track_move_down(int p_track) {
}
void Animation::track_move_to(int p_track, int p_to_index) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
ERR_FAIL_INDEX(p_to_index, tracks.size() + 1);
- if (p_track == p_to_index || p_track == p_to_index - 1)
+ if (p_track == p_to_index || p_track == p_to_index - 1) {
return;
+ }
Track *track = tracks.get(p_track);
tracks.remove(p_track);
@@ -2684,11 +2546,11 @@ void Animation::track_move_to(int p_track, int p_to_index) {
}
void Animation::track_swap(int p_track, int p_with_track) {
-
ERR_FAIL_INDEX(p_track, tracks.size());
ERR_FAIL_INDEX(p_with_track, tracks.size());
- if (p_track == p_with_track)
+ if (p_track == p_with_track) {
return;
+ }
SWAP(tracks.write[p_track], tracks.write[p_with_track]);
emit_changed();
@@ -2696,13 +2558,11 @@ void Animation::track_swap(int p_track, int p_with_track) {
}
void Animation::set_step(float p_step) {
-
step = p_step;
emit_changed();
}
float Animation::get_step() const {
-
return step;
}
@@ -2724,7 +2584,6 @@ void Animation::copy_track(int p_track, Ref<Animation> p_to_animation) {
}
void Animation::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_track", "type", "at_position"), &Animation::add_track, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("remove_track", "track_idx"), &Animation::remove_track);
ClassDB::bind_method(D_METHOD("get_track_count"), &Animation::get_track_count);
@@ -2834,9 +2693,9 @@ void Animation::_bind_methods() {
}
void Animation::clear() {
-
- for (int i = 0; i < tracks.size(); i++)
+ for (int i = 0; i < tracks.size(); i++) {
memdelete(tracks[i]);
+ }
tracks.clear();
loop = false;
length = 1;
@@ -2845,7 +2704,6 @@ void Animation::clear() {
}
bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, const TKey<TransformKey> &t1, const TKey<TransformKey> &t2, float p_alowed_linear_err, float p_alowed_angular_err, float p_max_optimizable_angle, const Vector3 &p_norm) {
-
real_t c = (t1.time - t0.time) / (t2.time - t0.time);
real_t t[3] = { -1, -1, -1 };
@@ -2863,7 +2721,6 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
}
} else {
-
Vector3 pd = (v2 - v0);
float d0 = pd.dot(v0);
float d1 = pd.dot(v1);
@@ -2879,8 +2736,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
return false; //beyond allowed error for colinearity
}
- if (p_norm != Vector3() && Math::acos(pd.normalized().dot(p_norm)) > p_alowed_angular_err)
+ if (p_norm != Vector3() && Math::acos(pd.normalized().dot(p_norm)) > p_alowed_angular_err) {
return false;
+ }
t[0] = (d1 - d0) / (d2 - d0);
}
@@ -2895,12 +2753,11 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
//localize both to rotation from q0
if (q0.is_equal_approx(q2)) {
-
- if (!q0.is_equal_approx(q1))
+ if (!q0.is_equal_approx(q1)) {
return false;
+ }
} else {
-
Quat r02 = (q0.inverse() * q2).normalized();
Quat r01 = (q0.inverse() * q1).normalized();
@@ -2910,8 +2767,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
r02.get_axis_angle(v02, a02);
r01.get_axis_angle(v01, a01);
- if (Math::abs(a02) > p_max_optimizable_angle)
+ if (Math::abs(a02) > p_max_optimizable_angle) {
return false;
+ }
if (v01.dot(v02) < 0) {
//make sure both rotations go the same way to compare
@@ -2931,8 +2789,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
}
real_t tr = a01 / a02;
- if (tr < 0 || tr > 1)
+ if (tr < 0 || tr > 1) {
return false; //rotating too much or too less
+ }
t[1] = tr;
}
@@ -2952,7 +2811,6 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
}
} else {
-
Vector3 pd = (v2 - v0);
float d0 = pd.dot(v0);
float d1 = pd.dot(v1);
@@ -2974,10 +2832,8 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
bool erase = false;
if (t[0] == -1 && t[1] == -1 && t[2] == -1) {
-
erase = true;
} else {
-
erase = true;
real_t lt = -1;
for (int j = 0; j < 3; j++) {
@@ -2986,8 +2842,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
lt = t[j]; //official t
//validate rest
for (int k = j + 1; k < 3; k++) {
- if (t[k] == -1)
+ if (t[k] == -1) {
continue;
+ }
if (Math::abs(lt - t[k]) > p_alowed_linear_err) {
erase = false;
@@ -3001,7 +2858,6 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
ERR_FAIL_COND_V(lt == -1, false);
if (erase) {
-
if (Math::abs(lt - c) > p_alowed_linear_err) {
//todo, evaluate changing the transition if this fails?
//this could be done as a second pass and would be
@@ -3015,7 +2871,6 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons
}
void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err, float p_allowed_angular_err, float p_max_optimizable_angle) {
-
ERR_FAIL_INDEX(p_idx, tracks.size());
ERR_FAIL_COND(tracks[p_idx]->type != TYPE_TRANSFORM);
TransformTrack *tt = static_cast<TransformTrack *>(tracks[p_idx]);
@@ -3025,7 +2880,6 @@ void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err,
Vector3 norm;
for (int i = 1; i < tt->transforms.size() - 1; i++) {
-
TKey<TransformKey> &t0 = tt->transforms.write[i - 1];
TKey<TransformKey> &t1 = tt->transforms.write[i];
TKey<TransformKey> &t2 = tt->transforms.write[i + 1];
@@ -3041,7 +2895,6 @@ void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err,
}
if (erase) {
-
if (!prev_erased) {
first_erased = t1;
prev_erased = true;
@@ -3058,23 +2911,21 @@ void Animation::_transform_track_optimize(int p_idx, float p_allowed_linear_err,
}
void Animation::optimize(float p_allowed_linear_err, float p_allowed_angular_err, float p_max_optimizable_angle) {
-
for (int i = 0; i < tracks.size(); i++) {
-
- if (tracks[i]->type == TYPE_TRANSFORM)
+ if (tracks[i]->type == TYPE_TRANSFORM) {
_transform_track_optimize(i, p_allowed_linear_err, p_allowed_angular_err, p_max_optimizable_angle);
+ }
}
}
Animation::Animation() {
-
step = 0.1;
loop = false;
length = 1;
}
Animation::~Animation() {
-
- for (int i = 0; i < tracks.size(); i++)
+ for (int i = 0; i < tracks.size(); i++) {
memdelete(tracks[i]);
+ }
}
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index e4e5177a8c..722a400fd6 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -34,7 +34,6 @@
#include "core/resource.h"
class Animation : public Resource {
-
GDCLASS(Animation, Resource);
RES_BASE_EXTENSION("anim");
@@ -64,7 +63,6 @@ public:
private:
struct Track {
-
TrackType type;
InterpolationType interpolation;
bool loop_wrap;
@@ -81,7 +79,6 @@ private:
};
struct Key {
-
float transition;
float time; // time in secs
Key() {
@@ -93,12 +90,10 @@ private:
// transform key holds either Vector3 or Quaternion
template <class T>
struct TKey : public Key {
-
T value;
};
struct TransformKey {
-
Vector3 loc;
Quat rot;
Vector3 scale;
@@ -107,7 +102,6 @@ private:
/* TRANSFORM TRACK */
struct TransformTrack : public Track {
-
Vector<TKey<TransformKey>> transforms;
TransformTrack() { type = TYPE_TRANSFORM; }
@@ -116,7 +110,6 @@ private:
/* PROPERTY VALUE TRACK */
struct ValueTrack : public Track {
-
UpdateMode update_mode;
bool update_on_seek;
Vector<TKey<Variant>> values;
@@ -130,13 +123,11 @@ private:
/* METHOD TRACK */
struct MethodKey : public Key {
-
StringName method;
Vector<Variant> params;
};
struct MethodTrack : public Track {
-
Vector<MethodKey> methods;
MethodTrack() { type = TYPE_METHOD; }
};
@@ -150,7 +141,6 @@ private:
};
struct BezierTrack : public Track {
-
Vector<TKey<BezierKey>> values;
BezierTrack() {
@@ -171,7 +161,6 @@ private:
};
struct AudioTrack : public Track {
-
Vector<TKey<AudioKey>> values;
AudioTrack() {
@@ -182,7 +171,6 @@ private:
/* AUDIO TRACK */
struct AnimationTrack : public Track {
-
Vector<TKey<StringName>> values;
AnimationTrack() {
@@ -246,25 +234,21 @@ private:
}
Vector<int> _value_track_get_key_indices(int p_track, float p_time, float p_delta) const {
-
List<int> idxs;
value_track_get_key_indices(p_track, p_time, p_delta, &idxs);
Vector<int> idxr;
for (List<int>::Element *E = idxs.front(); E; E = E->next()) {
-
idxr.push_back(E->get());
}
return idxr;
}
Vector<int> _method_track_get_key_indices(int p_track, float p_time, float p_delta) const {
-
List<int> idxs;
method_track_get_key_indices(p_track, p_time, p_delta, &idxs);
Vector<int> idxr;
for (List<int>::Element *E = idxs.front(); E; E = E->next()) {
-
idxr.push_back(E->get());
}
return idxr;
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp
index d630a1f3ee..f02e7987a9 100644
--- a/scene/resources/audio_stream_sample.cpp
+++ b/scene/resources/audio_stream_sample.cpp
@@ -34,7 +34,6 @@
#include "core/os/file_access.h"
void AudioStreamPlaybackSample::start(float p_from_pos) {
-
if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) {
//no seeking in IMA_ADPCM
for (int i = 0; i < 2; i++) {
@@ -57,28 +56,25 @@ void AudioStreamPlaybackSample::start(float p_from_pos) {
}
void AudioStreamPlaybackSample::stop() {
-
active = false;
}
bool AudioStreamPlaybackSample::is_playing() const {
-
return active;
}
int AudioStreamPlaybackSample::get_loop_count() const {
-
return 0;
}
float AudioStreamPlaybackSample::get_playback_position() const {
-
return float(offset >> MIX_FRAC_BITS) / base->mix_rate;
}
-void AudioStreamPlaybackSample::seek(float p_time) {
- if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM)
+void AudioStreamPlaybackSample::seek(float p_time) {
+ if (base->format == AudioStreamSample::FORMAT_IMA_ADPCM) {
return; //no seeking in ima-adpcm
+ }
float max = base->get_length();
if (p_time < 0) {
@@ -92,22 +88,20 @@ void AudioStreamPlaybackSample::seek(float p_time) {
template <class Depth, bool is_stereo, bool is_ima_adpcm>
void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_dst, int64_t &offset, int32_t &increment, uint32_t amount, IMA_ADPCM_State *ima_adpcm) {
-
// this function will be compiled branchless by any decent compiler
int32_t final, final_r, next, next_r;
while (amount) {
amount--;
int64_t pos = offset >> MIX_FRAC_BITS;
- if (is_stereo && !is_ima_adpcm)
+ if (is_stereo && !is_ima_adpcm) {
pos <<= 1;
+ }
if (is_ima_adpcm) {
-
int64_t sample_pos = pos + ima_adpcm[0].window_ofs;
while (sample_pos > ima_adpcm[0].last_nibble) {
-
static const int16_t _ima_adpcm_step_table[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
@@ -126,7 +120,6 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds
};
for (int i = 0; i < (is_stereo ? 2 : 1); i++) {
-
int16_t nibble, diff, step;
ima_adpcm[i].last_nibble++;
@@ -138,30 +131,36 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds
step = _ima_adpcm_step_table[ima_adpcm[i].step_index];
ima_adpcm[i].step_index += _ima_adpcm_index_table[nibble];
- if (ima_adpcm[i].step_index < 0)
+ if (ima_adpcm[i].step_index < 0) {
ima_adpcm[i].step_index = 0;
- if (ima_adpcm[i].step_index > 88)
+ }
+ if (ima_adpcm[i].step_index > 88) {
ima_adpcm[i].step_index = 88;
+ }
diff = step >> 3;
- if (nibble & 1)
+ if (nibble & 1) {
diff += step >> 2;
- if (nibble & 2)
+ }
+ if (nibble & 2) {
diff += step >> 1;
- if (nibble & 4)
+ }
+ if (nibble & 4) {
diff += step;
- if (nibble & 8)
+ }
+ if (nibble & 8) {
diff = -diff;
+ }
ima_adpcm[i].predictor += diff;
- if (ima_adpcm[i].predictor < -0x8000)
+ if (ima_adpcm[i].predictor < -0x8000) {
ima_adpcm[i].predictor = -0x8000;
- else if (ima_adpcm[i].predictor > 0x7FFF)
+ } else if (ima_adpcm[i].predictor > 0x7FFF) {
ima_adpcm[i].predictor = 0x7FFF;
+ }
/* store loop if there */
if (ima_adpcm[i].last_nibble == ima_adpcm[i].loop_pos) {
-
ima_adpcm[i].loop_step_index = ima_adpcm[i].step_index;
ima_adpcm[i].loop_predictor = ima_adpcm[i].predictor;
}
@@ -177,17 +176,18 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds
} else {
final = p_src[pos];
- if (is_stereo)
+ if (is_stereo) {
final_r = p_src[pos + 1];
+ }
if (sizeof(Depth) == 1) { /* conditions will not exist anymore when compiled! */
final <<= 8;
- if (is_stereo)
+ if (is_stereo) {
final_r <<= 8;
+ }
}
if (is_stereo) {
-
next = p_src[pos + 2];
next_r = p_src[pos + 3];
} else {
@@ -196,15 +196,17 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds
if (sizeof(Depth) == 1) {
next <<= 8;
- if (is_stereo)
+ if (is_stereo) {
next_r <<= 8;
+ }
}
int32_t frac = int64_t(offset & MIX_FRAC_MASK);
final = final + ((next - final) * frac >> MIX_FRAC_BITS);
- if (is_stereo)
+ if (is_stereo) {
final_r = final_r + ((next_r - final_r) * frac >> MIX_FRAC_BITS);
+ }
}
if (!is_stereo) {
@@ -220,7 +222,6 @@ void AudioStreamPlaybackSample::do_resample(const Depth *p_src, AudioFrame *p_ds
}
void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
-
if (!base->data || !active) {
for (int i = 0; i < p_frames; i++) {
p_buffer[i] = AudioFrame(0, 0);
@@ -230,9 +231,15 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
int len = base->data_bytes;
switch (base->format) {
- case AudioStreamSample::FORMAT_8_BITS: len /= 1; break;
- case AudioStreamSample::FORMAT_16_BITS: len /= 2; break;
- case AudioStreamSample::FORMAT_IMA_ADPCM: len *= 2; break;
+ case AudioStreamSample::FORMAT_8_BITS:
+ len /= 1;
+ break;
+ case AudioStreamSample::FORMAT_16_BITS:
+ len /= 2;
+ break;
+ case AudioStreamSample::FORMAT_IMA_ADPCM:
+ len *= 2;
+ break;
}
if (base->stereo) {
@@ -273,7 +280,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
AudioFrame *dst_buff = p_buffer;
if (format == AudioStreamSample::FORMAT_IMA_ADPCM) {
-
if (loop_format != AudioStreamSample::LOOP_DISABLED) {
ima_adpcm[0].loop_pos = loop_begin_fp >> MIX_FRAC_BITS;
ima_adpcm[1].loop_pos = loop_begin_fp >> MIX_FRAC_BITS;
@@ -282,7 +288,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
}
while (todo > 0) {
-
int64_t limit = 0;
int32_t target = 0, aux = 0;
@@ -305,7 +310,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
} else {
/* check for sample not reaching beginning */
if (offset < 0) {
-
active = false;
break;
}
@@ -337,7 +341,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
} else {
/* no loop, check for end of sample */
if (offset >= length_fp) {
-
active = false;
break;
}
@@ -363,24 +366,26 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
switch (base->format) {
case AudioStreamSample::FORMAT_8_BITS: {
-
- if (is_stereo)
+ if (is_stereo) {
do_resample<int8_t, true, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm);
- else
+ } else {
do_resample<int8_t, false, false>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm);
+ }
} break;
case AudioStreamSample::FORMAT_16_BITS: {
- if (is_stereo)
+ if (is_stereo) {
do_resample<int16_t, true, false>((int16_t *)data, dst_buff, offset, increment, target, ima_adpcm);
- else
+ } else {
do_resample<int16_t, false, false>((int16_t *)data, dst_buff, offset, increment, target, ima_adpcm);
+ }
} break;
case AudioStreamSample::FORMAT_IMA_ADPCM: {
- if (is_stereo)
+ if (is_stereo) {
do_resample<int8_t, true, true>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm);
- else
+ } else {
do_resample<int8_t, false, true>((int8_t *)data, dst_buff, offset, increment, target, ima_adpcm);
+ }
} break;
}
@@ -398,7 +403,6 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
}
AudioStreamPlaybackSample::AudioStreamPlaybackSample() {
-
active = false;
offset = 0;
sign = 1;
@@ -407,67 +411,66 @@ AudioStreamPlaybackSample::AudioStreamPlaybackSample() {
/////////////////////
void AudioStreamSample::set_format(Format p_format) {
-
format = p_format;
}
AudioStreamSample::Format AudioStreamSample::get_format() const {
-
return format;
}
void AudioStreamSample::set_loop_mode(LoopMode p_loop_mode) {
-
loop_mode = p_loop_mode;
}
-AudioStreamSample::LoopMode AudioStreamSample::get_loop_mode() const {
+AudioStreamSample::LoopMode AudioStreamSample::get_loop_mode() const {
return loop_mode;
}
void AudioStreamSample::set_loop_begin(int p_frame) {
-
loop_begin = p_frame;
}
-int AudioStreamSample::get_loop_begin() const {
+int AudioStreamSample::get_loop_begin() const {
return loop_begin;
}
void AudioStreamSample::set_loop_end(int p_frame) {
-
loop_end = p_frame;
}
-int AudioStreamSample::get_loop_end() const {
+int AudioStreamSample::get_loop_end() const {
return loop_end;
}
void AudioStreamSample::set_mix_rate(int p_hz) {
-
ERR_FAIL_COND(p_hz == 0);
mix_rate = p_hz;
}
-int AudioStreamSample::get_mix_rate() const {
+int AudioStreamSample::get_mix_rate() const {
return mix_rate;
}
-void AudioStreamSample::set_stereo(bool p_enable) {
+void AudioStreamSample::set_stereo(bool p_enable) {
stereo = p_enable;
}
-bool AudioStreamSample::is_stereo() const {
+bool AudioStreamSample::is_stereo() const {
return stereo;
}
float AudioStreamSample::get_length() const {
-
int len = data_bytes;
switch (format) {
- case AudioStreamSample::FORMAT_8_BITS: len /= 1; break;
- case AudioStreamSample::FORMAT_16_BITS: len /= 2; break;
- case AudioStreamSample::FORMAT_IMA_ADPCM: len *= 2; break;
+ case AudioStreamSample::FORMAT_8_BITS:
+ len /= 1;
+ break;
+ case AudioStreamSample::FORMAT_16_BITS:
+ len /= 2;
+ break;
+ case AudioStreamSample::FORMAT_IMA_ADPCM:
+ len *= 2;
+ break;
}
if (stereo) {
@@ -478,7 +481,6 @@ float AudioStreamSample::get_length() const {
}
void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) {
-
AudioServer::get_singleton()->lock();
if (data) {
memfree(data);
@@ -488,7 +490,6 @@ void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) {
int datalen = p_data.size();
if (datalen) {
-
const uint8_t *r = p_data.ptr();
int alloc_len = datalen + DATA_PAD * 2;
data = memalloc(alloc_len); //alloc with some padding for interpolation
@@ -500,14 +501,13 @@ void AudioStreamSample::set_data(const Vector<uint8_t> &p_data) {
AudioServer::get_singleton()->unlock();
}
-Vector<uint8_t> AudioStreamSample::get_data() const {
+Vector<uint8_t> AudioStreamSample::get_data() const {
Vector<uint8_t> pv;
if (data) {
pv.resize(data_bytes);
{
-
uint8_t *w = pv.ptrw();
uint8_t *dataptr = (uint8_t *)data;
copymem(w, dataptr + DATA_PAD, data_bytes);
@@ -536,9 +536,15 @@ Error AudioStreamSample::save_to_wav(const String &p_path) {
int byte_pr_sample = 0;
switch (format) {
- case AudioStreamSample::FORMAT_8_BITS: byte_pr_sample = 1; break;
- case AudioStreamSample::FORMAT_16_BITS: byte_pr_sample = 2; break;
- case AudioStreamSample::FORMAT_IMA_ADPCM: byte_pr_sample = 4; break;
+ case AudioStreamSample::FORMAT_8_BITS:
+ byte_pr_sample = 1;
+ break;
+ case AudioStreamSample::FORMAT_16_BITS:
+ byte_pr_sample = 2;
+ break;
+ case AudioStreamSample::FORMAT_IMA_ADPCM:
+ byte_pr_sample = 4;
+ break;
}
String file_path = p_path;
@@ -592,7 +598,6 @@ Error AudioStreamSample::save_to_wav(const String &p_path) {
}
Ref<AudioStreamPlayback> AudioStreamSample::instance_playback() {
-
Ref<AudioStreamPlaybackSample> sample;
sample.instance();
sample->base = Ref<AudioStreamSample>(this);
@@ -600,12 +605,10 @@ Ref<AudioStreamPlayback> AudioStreamSample::instance_playback() {
}
String AudioStreamSample::get_stream_name() const {
-
return "";
}
void AudioStreamSample::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_data", "data"), &AudioStreamSample::set_data);
ClassDB::bind_method(D_METHOD("get_data"), &AudioStreamSample::get_data);
diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h
index 0b46bc1c75..2bd358117c 100644
--- a/scene/resources/audio_stream_sample.h
+++ b/scene/resources/audio_stream_sample.h
@@ -36,7 +36,6 @@
class AudioStreamSample;
class AudioStreamPlaybackSample : public AudioStreamPlayback {
-
GDCLASS(AudioStreamPlaybackSample, AudioStreamPlayback);
enum {
MIX_FRAC_BITS = 13,
@@ -45,7 +44,6 @@ class AudioStreamPlaybackSample : public AudioStreamPlayback {
};
struct IMA_ADPCM_State {
-
int16_t step_index;
int32_t predictor;
/* values at loop point */
diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp
index d45f36dfd1..10f0de8ff8 100644
--- a/scene/resources/bit_map.cpp
+++ b/scene/resources/bit_map.cpp
@@ -33,7 +33,6 @@
#include "core/io/image_loader.h"
void BitMap::create(const Size2 &p_size) {
-
ERR_FAIL_COND(p_size.width < 1);
ERR_FAIL_COND(p_size.height < 1);
@@ -44,7 +43,6 @@ void BitMap::create(const Size2 &p_size) {
}
void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshold) {
-
ERR_FAIL_COND(p_image.is_null() || p_image->empty());
Ref<Image> img = p_image->duplicate();
img->convert(Image::FORMAT_LA8);
@@ -56,7 +54,6 @@ void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshol
uint8_t *w = bitmask.ptrw();
for (int i = 0; i < width * height; i++) {
-
int bbyte = i / 8;
int bbit = i % 8;
if (r[i * 2 + 1] / 255.0 > p_threshold) {
@@ -66,24 +63,22 @@ void BitMap::create_from_image_alpha(const Ref<Image> &p_image, float p_threshol
}
void BitMap::set_bit_rect(const Rect2 &p_rect, bool p_value) {
-
Rect2i current = Rect2i(0, 0, width, height).clip(p_rect);
uint8_t *data = bitmask.ptrw();
for (int i = current.position.x; i < current.position.x + current.size.x; i++) {
-
for (int j = current.position.y; j < current.position.y + current.size.y; j++) {
-
int ofs = width * j + i;
int bbyte = ofs / 8;
int bbit = ofs % 8;
uint8_t b = data[bbyte];
- if (p_value)
+ if (p_value) {
b |= (1 << bbit);
- else
+ } else {
b &= ~(1 << bbit);
+ }
data[bbyte] = b;
}
@@ -91,7 +86,6 @@ void BitMap::set_bit_rect(const Rect2 &p_rect, bool p_value) {
}
int BitMap::get_true_bit_count() const {
-
int ds = bitmask.size();
const uint8_t *d = bitmask.ptr();
int c = 0;
@@ -99,7 +93,6 @@ int BitMap::get_true_bit_count() const {
//fast, almost branchless version
for (int i = 0; i < ds; i++) {
-
c += (d[i] & (1 << 7)) >> 7;
c += (d[i] & (1 << 6)) >> 6;
c += (d[i] & (1 << 5)) >> 5;
@@ -114,7 +107,6 @@ int BitMap::get_true_bit_count() const {
}
void BitMap::set_bit(const Point2 &p_pos, bool p_value) {
-
int x = p_pos.x;
int y = p_pos.y;
@@ -127,16 +119,16 @@ void BitMap::set_bit(const Point2 &p_pos, bool p_value) {
uint8_t b = bitmask[bbyte];
- if (p_value)
+ if (p_value) {
b |= (1 << bbit);
- else
+ } else {
b &= ~(1 << bbit);
+ }
bitmask.write[bbyte] = b;
}
bool BitMap::get_bit(const Point2 &p_pos) const {
-
int x = Math::fast_ftoi(p_pos.x);
int y = Math::fast_ftoi(p_pos.y);
ERR_FAIL_INDEX_V(x, width, false);
@@ -150,12 +142,10 @@ bool BitMap::get_bit(const Point2 &p_pos) const {
}
Size2 BitMap::get_size() const {
-
return Size2(width, height);
}
void BitMap::_set_data(const Dictionary &p_d) {
-
ERR_FAIL_COND(!p_d.has("size"));
ERR_FAIL_COND(!p_d.has("data"));
@@ -164,7 +154,6 @@ void BitMap::_set_data(const Dictionary &p_d) {
}
Dictionary BitMap::_get_data() const {
-
Dictionary d;
d["size"] = get_size();
d["data"] = bitmask;
@@ -172,7 +161,6 @@ Dictionary BitMap::_get_data() const {
}
Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) const {
-
int stepx = 0;
int stepy = 0;
int prevx = 0;
@@ -209,7 +197,6 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start)
}
switch (sv) {
-
case 1:
case 5:
case 13:
@@ -354,8 +341,9 @@ static float perpendicular_distance(const Vector2 &i, const Vector2 &start, cons
}
static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) {
- if (v.size() < 3)
+ if (v.size() < 3) {
return v;
+ }
int index = -1;
float dist = 0;
@@ -368,7 +356,6 @@ static Vector<Vector2> rdp(const Vector<Vector2> &v, float optimization) {
}
}
if (dist > optimization) {
-
Vector<Vector2> left, right;
left.resize(index);
for (int i = 0; i < index; i++) {
@@ -424,7 +411,6 @@ struct FillBitsStackEntry {
};
static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_pos, const Rect2i &rect) {
-
// Using a custom stack to work iteratively to avoid stack overflow on big bitmaps
Vector<FillBitsStackEntry> stack;
// Tracking size since we won't be shrinking the stack vector
@@ -453,15 +439,17 @@ static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_
continue;
}
- if (i < rect.position.x || i >= rect.position.x + rect.size.x)
+ if (i < rect.position.x || i >= rect.position.x + rect.size.x) {
continue;
- if (j < rect.position.y || j >= rect.position.y + rect.size.y)
+ }
+ if (j < rect.position.y || j >= rect.position.y + rect.size.y) {
continue;
+ }
- if (p_map->get_bit(Vector2(i, j)))
+ if (p_map->get_bit(Vector2(i, j))) {
continue;
- else if (p_src->get_bit(Vector2(i, j))) {
+ } else if (p_src->get_bit(Vector2(i, j))) {
p_map->set_bit(Vector2(i, j), true);
FillBitsStackEntry se = { pos, i, j };
@@ -494,7 +482,6 @@ static void fill_bits(const BitMap *p_src, Ref<BitMap> &p_map, const Point2i &p_
}
Vector<Vector<Vector2>> BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, float p_epsilon) const {
-
Rect2i r = Rect2i(0, 0, width, height).clip(p_rect);
print_verbose("BitMap: Rect: " + r);
@@ -507,7 +494,6 @@ Vector<Vector<Vector2>> BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, flo
for (int i = r.position.y; i < r.position.y + r.size.height; i++) {
for (int j = r.position.x; j < r.position.x + r.size.width; j++) {
if (!fill->get_bit(Point2(j, i)) && get_bit(Point2(j, i))) {
-
fill_bits(this, fill, Point2i(j, i), r);
Vector<Vector2> polygon = _march_square(r, Point2i(j, i));
@@ -529,7 +515,6 @@ Vector<Vector<Vector2>> BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, flo
}
void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) {
-
if (p_pixels == 0) {
return;
}
@@ -546,35 +531,38 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) {
for (int i = r.position.y; i < r.position.y + r.size.height; i++) {
for (int j = r.position.x; j < r.position.x + r.size.width; j++) {
- if (bit_value == get_bit(Point2(j, i)))
+ if (bit_value == get_bit(Point2(j, i))) {
continue;
+ }
bool found = false;
for (int y = i - p_pixels; y <= i + p_pixels; y++) {
for (int x = j - p_pixels; x <= j + p_pixels; x++) {
-
bool outside = false;
if ((x < p_rect.position.x) || (x >= p_rect.position.x + p_rect.size.x) || (y < p_rect.position.y) || (y >= p_rect.position.y + p_rect.size.y)) {
// outside of rectangle counts as bit not set
- if (!bit_value)
+ if (!bit_value) {
outside = true;
- else
+ } else {
continue;
+ }
}
float d = Point2(j, i).distance_to(Point2(x, y)) - CMP_EPSILON;
- if (d > p_pixels)
+ if (d > p_pixels) {
continue;
+ }
if (outside || (bit_value == copy->get_bit(Point2(x, y)))) {
found = true;
break;
}
}
- if (found)
+ if (found) {
break;
+ }
}
if (found) {
@@ -585,12 +573,10 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) {
}
void BitMap::shrink_mask(int p_pixels, const Rect2 &p_rect) {
-
grow_mask(-p_pixels, p_rect);
}
Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const {
-
Vector<Vector<Vector2>> result = clip_opaque_to_polygons(p_rect, p_epsilon);
// Convert result to bindable types
@@ -598,7 +584,6 @@ Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) con
Array result_array;
result_array.resize(result.size());
for (int i = 0; i < result.size(); i++) {
-
const Vector<Vector2> &polygon = result[i];
PackedVector2Array polygon_array;
@@ -618,7 +603,6 @@ Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) con
}
void BitMap::resize(const Size2 &p_new_size) {
-
Ref<BitMap> new_bitmap;
new_bitmap.instance();
new_bitmap->create(p_new_size);
@@ -636,7 +620,6 @@ void BitMap::resize(const Size2 &p_new_size) {
}
Ref<Image> BitMap::convert_to_image() const {
-
Ref<Image> image;
image.instance();
image->create(width, height, false, Image::FORMAT_L8);
@@ -649,8 +632,8 @@ Ref<Image> BitMap::convert_to_image() const {
return image;
}
-void BitMap::blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap) {
+void BitMap::blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap) {
int x = p_pos.x;
int y = p_pos.y;
int w = p_bitmap->get_size().width;
@@ -660,10 +643,12 @@ void BitMap::blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap) {
for (int j = 0; j < h; j++) {
int px = x + i;
int py = y + j;
- if (px < 0 || px >= width)
+ if (px < 0 || px >= width) {
continue;
- if (py < 0 || py >= height)
+ }
+ if (py < 0 || py >= height) {
continue;
+ }
if (p_bitmap->get_bit(Vector2(i, j))) {
set_bit(Vector2(x, y), true);
}
@@ -672,7 +657,6 @@ void BitMap::blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap) {
}
void BitMap::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("create", "size"), &BitMap::create);
ClassDB::bind_method(D_METHOD("create_from_image_alpha", "image", "threshold"), &BitMap::create_from_image_alpha, DEFVAL(0.1));
@@ -694,7 +678,6 @@ void BitMap::_bind_methods() {
}
BitMap::BitMap() {
-
width = 0;
height = 0;
}
diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h
index 05313a0cff..59f3b4dc3c 100644
--- a/scene/resources/bit_map.h
+++ b/scene/resources/bit_map.h
@@ -36,7 +36,6 @@
#include "core/resource.h"
class BitMap : public Resource {
-
GDCLASS(BitMap, Resource);
OBJ_SAVE_TYPE(BitMap);
diff --git a/scene/resources/box_shape_3d.cpp b/scene/resources/box_shape_3d.cpp
index 64c821a011..69339faf76 100644
--- a/scene/resources/box_shape_3d.cpp
+++ b/scene/resources/box_shape_3d.cpp
@@ -32,7 +32,6 @@
#include "servers/physics_server_3d.h"
Vector<Vector3> BoxShape3D::get_debug_mesh_lines() {
-
Vector<Vector3> lines;
AABB aabb;
aabb.position = -get_extents();
@@ -53,13 +52,11 @@ real_t BoxShape3D::get_enclosing_radius() const {
}
void BoxShape3D::_update_shape() {
-
PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), extents);
Shape3D::_update_shape();
}
void BoxShape3D::set_extents(const Vector3 &p_extents) {
-
extents = p_extents;
_update_shape();
notify_change_to_owners();
@@ -67,12 +64,10 @@ void BoxShape3D::set_extents(const Vector3 &p_extents) {
}
Vector3 BoxShape3D::get_extents() const {
-
return extents;
}
void BoxShape3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_extents", "extents"), &BoxShape3D::set_extents);
ClassDB::bind_method(D_METHOD("get_extents"), &BoxShape3D::get_extents);
@@ -81,6 +76,5 @@ void BoxShape3D::_bind_methods() {
BoxShape3D::BoxShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_BOX)) {
-
set_extents(Vector3(1, 1, 1));
}
diff --git a/scene/resources/box_shape_3d.h b/scene/resources/box_shape_3d.h
index a93fd8d33a..e00b523815 100644
--- a/scene/resources/box_shape_3d.h
+++ b/scene/resources/box_shape_3d.h
@@ -34,7 +34,6 @@
#include "scene/resources/shape_3d.h"
class BoxShape3D : public Shape3D {
-
GDCLASS(BoxShape3D, Shape3D);
Vector3 extents;
diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp
index ab2657c892..0e784e04ff 100644
--- a/scene/resources/capsule_shape_2d.cpp
+++ b/scene/resources/capsule_shape_2d.cpp
@@ -34,54 +34,51 @@
#include "servers/rendering_server.h"
Vector<Vector2> CapsuleShape2D::_get_points() const {
-
Vector<Vector2> points;
for (int i = 0; i < 24; i++) {
Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -get_height() * 0.5 : get_height() * 0.5);
points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() + ofs);
- if (i == 6 || i == 18)
+ if (i == 6 || i == 18) {
points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() - ofs);
+ }
}
return points;
}
bool CapsuleShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
return Geometry::is_point_in_polygon(p_point, _get_points());
}
void CapsuleShape2D::_update_shape() {
-
PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), Vector2(radius, height));
emit_changed();
}
void CapsuleShape2D::set_radius(real_t p_radius) {
-
radius = p_radius;
_update_shape();
}
real_t CapsuleShape2D::get_radius() const {
-
return radius;
}
void CapsuleShape2D::set_height(real_t p_height) {
-
height = p_height;
+ if (height < 0) {
+ height = 0;
+ }
+
_update_shape();
}
real_t CapsuleShape2D::get_height() const {
-
return height;
}
void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
Vector<Vector2> points = _get_points();
Vector<Color> col;
col.push_back(p_color);
@@ -89,7 +86,6 @@ void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
}
Rect2 CapsuleShape2D::get_rect() const {
-
Vector2 he = Point2(get_radius(), get_radius() + get_height() * 0.5);
Rect2 rect;
rect.position = -he;
@@ -102,7 +98,6 @@ real_t CapsuleShape2D::get_enclosing_radius() const {
}
void CapsuleShape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape2D::set_radius);
ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleShape2D::get_radius);
@@ -115,7 +110,6 @@ void CapsuleShape2D::_bind_methods() {
CapsuleShape2D::CapsuleShape2D() :
Shape2D(PhysicsServer2D::get_singleton()->capsule_shape_create()) {
-
radius = 10;
height = 20;
_update_shape();
diff --git a/scene/resources/capsule_shape_3d.cpp b/scene/resources/capsule_shape_3d.cpp
index da3ffcb306..28fc0d470c 100644
--- a/scene/resources/capsule_shape_3d.cpp
+++ b/scene/resources/capsule_shape_3d.cpp
@@ -32,7 +32,6 @@
#include "servers/physics_server_3d.h"
Vector<Vector3> CapsuleShape3D::get_debug_mesh_lines() {
-
float radius = get_radius();
float height = get_height();
@@ -40,7 +39,6 @@ Vector<Vector3> CapsuleShape3D::get_debug_mesh_lines() {
Vector3 d(0, height * 0.5, 0);
for (int i = 0; i < 360; i++) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + 1);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
@@ -53,7 +51,6 @@ Vector<Vector3> CapsuleShape3D::get_debug_mesh_lines() {
points.push_back(Vector3(b.x, 0, b.y) - d);
if (i % 90 == 0) {
-
points.push_back(Vector3(a.x, 0, a.y) + d);
points.push_back(Vector3(a.x, 0, a.y) - d);
}
@@ -74,7 +71,6 @@ real_t CapsuleShape3D::get_enclosing_radius() const {
}
void CapsuleShape3D::_update_shape() {
-
Dictionary d;
d["radius"] = radius;
d["height"] = height;
@@ -83,7 +79,6 @@ void CapsuleShape3D::_update_shape() {
}
void CapsuleShape3D::set_radius(float p_radius) {
-
radius = p_radius;
_update_shape();
notify_change_to_owners();
@@ -91,12 +86,10 @@ void CapsuleShape3D::set_radius(float p_radius) {
}
float CapsuleShape3D::get_radius() const {
-
return radius;
}
void CapsuleShape3D::set_height(float p_height) {
-
height = p_height;
_update_shape();
notify_change_to_owners();
@@ -104,12 +97,10 @@ void CapsuleShape3D::set_height(float p_height) {
}
float CapsuleShape3D::get_height() const {
-
return height;
}
void CapsuleShape3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape3D::set_radius);
ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleShape3D::get_radius);
ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape3D::set_height);
@@ -121,7 +112,6 @@ void CapsuleShape3D::_bind_methods() {
CapsuleShape3D::CapsuleShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CAPSULE)) {
-
radius = 1.0;
height = 1.0;
_update_shape();
diff --git a/scene/resources/capsule_shape_3d.h b/scene/resources/capsule_shape_3d.h
index dca7a6c983..5892f97709 100644
--- a/scene/resources/capsule_shape_3d.h
+++ b/scene/resources/capsule_shape_3d.h
@@ -34,7 +34,6 @@
#include "scene/resources/shape_3d.h"
class CapsuleShape3D : public Shape3D {
-
GDCLASS(CapsuleShape3D, Shape3D);
float radius;
float height;
diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp
index afb7597280..dc1bf3b185 100644
--- a/scene/resources/circle_shape_2d.cpp
+++ b/scene/resources/circle_shape_2d.cpp
@@ -34,29 +34,24 @@
#include "servers/rendering_server.h"
bool CircleShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
return p_point.length() < get_radius() + p_tolerance;
}
void CircleShape2D::_update_shape() {
-
PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), radius);
emit_changed();
}
void CircleShape2D::set_radius(real_t p_radius) {
-
radius = p_radius;
_update_shape();
}
real_t CircleShape2D::get_radius() const {
-
return radius;
}
void CircleShape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CircleShape2D::set_radius);
ClassDB::bind_method(D_METHOD("get_radius"), &CircleShape2D::get_radius);
@@ -75,10 +70,8 @@ real_t CircleShape2D::get_enclosing_radius() const {
}
void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
Vector<Vector2> points;
for (int i = 0; i < 24; i++) {
-
points.push_back(Vector2(Math::cos(i * Math_PI * 2 / 24.0), Math::sin(i * Math_PI * 2 / 24.0)) * get_radius());
}
@@ -89,7 +82,6 @@ void CircleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
CircleShape2D::CircleShape2D() :
Shape2D(PhysicsServer2D::get_singleton()->circle_shape_create()) {
-
radius = 10;
_update_shape();
}
diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp
index c8fec3b72d..2154633111 100644
--- a/scene/resources/concave_polygon_shape_2d.cpp
+++ b/scene/resources/concave_polygon_shape_2d.cpp
@@ -34,39 +34,38 @@
#include "servers/rendering_server.h"
bool ConcavePolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
Vector<Vector2> s = get_segments();
int len = s.size();
- if (len == 0 || (len % 2) == 1)
+ if (len == 0 || (len % 2) == 1) {
return false;
+ }
const Vector2 *r = s.ptr();
for (int i = 0; i < len; i += 2) {
Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, &r[i]);
- if (p_point.distance_to(closest) < p_tolerance)
+ if (p_point.distance_to(closest) < p_tolerance) {
return true;
+ }
}
return false;
}
void ConcavePolygonShape2D::set_segments(const Vector<Vector2> &p_segments) {
-
PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), p_segments);
emit_changed();
}
Vector<Vector2> ConcavePolygonShape2D::get_segments() const {
-
return PhysicsServer2D::get_singleton()->shape_get_data(get_rid());
}
void ConcavePolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
Vector<Vector2> s = get_segments();
int len = s.size();
- if (len == 0 || (len % 2) == 1)
+ if (len == 0 || (len % 2) == 1) {
return;
+ }
const Vector2 *r = s.ptr();
for (int i = 0; i < len; i += 2) {
@@ -75,20 +74,21 @@ void ConcavePolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) {
}
Rect2 ConcavePolygonShape2D::get_rect() const {
-
Vector<Vector2> s = get_segments();
int len = s.size();
- if (len == 0)
+ if (len == 0) {
return Rect2();
+ }
Rect2 rect;
const Vector2 *r = s.ptr();
for (int i = 0; i < len; i++) {
- if (i == 0)
+ if (i == 0) {
rect.position = r[i];
- else
+ } else {
rect.expand_to(r[i]);
+ }
}
return rect;
@@ -105,7 +105,6 @@ real_t ConcavePolygonShape2D::get_enclosing_radius() const {
}
void ConcavePolygonShape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_segments", "segments"), &ConcavePolygonShape2D::set_segments);
ClassDB::bind_method(D_METHOD("get_segments"), &ConcavePolygonShape2D::get_segments);
diff --git a/scene/resources/concave_polygon_shape_3d.cpp b/scene/resources/concave_polygon_shape_3d.cpp
index 42e06a49b6..7315945c03 100644
--- a/scene/resources/concave_polygon_shape_3d.cpp
+++ b/scene/resources/concave_polygon_shape_3d.cpp
@@ -33,7 +33,6 @@
#include "servers/physics_server_3d.h"
Vector<Vector3> ConcavePolygonShape3D::get_debug_mesh_lines() {
-
Set<DrawEdge> edges;
Vector<Vector3> data = get_faces();
@@ -43,9 +42,7 @@ Vector<Vector3> ConcavePolygonShape3D::get_debug_mesh_lines() {
const Vector3 *r = data.ptr();
for (int i = 0; i < datalen; i += 3) {
-
for (int j = 0; j < 3; j++) {
-
DrawEdge de(r[i + j], r[i + ((j + 1) % 3)]);
edges.insert(de);
}
@@ -55,7 +52,6 @@ Vector<Vector3> ConcavePolygonShape3D::get_debug_mesh_lines() {
points.resize(edges.size() * 2);
int idx = 0;
for (Set<DrawEdge>::Element *E = edges.front(); E; E = E->next()) {
-
points.write[idx + 0] = E->get().a;
points.write[idx + 1] = E->get().b;
idx += 2;
@@ -79,18 +75,15 @@ void ConcavePolygonShape3D::_update_shape() {
}
void ConcavePolygonShape3D::set_faces(const Vector<Vector3> &p_faces) {
-
PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), p_faces);
notify_change_to_owners();
}
Vector<Vector3> ConcavePolygonShape3D::get_faces() const {
-
return PhysicsServer3D::get_singleton()->shape_get_data(get_shape());
}
void ConcavePolygonShape3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_faces", "faces"), &ConcavePolygonShape3D::set_faces);
ClassDB::bind_method(D_METHOD("get_faces"), &ConcavePolygonShape3D::get_faces);
ADD_PROPERTY(PropertyInfo(Variant::PACKED_VECTOR3_ARRAY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_faces", "get_faces");
@@ -98,6 +91,5 @@ void ConcavePolygonShape3D::_bind_methods() {
ConcavePolygonShape3D::ConcavePolygonShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CONCAVE_POLYGON)) {
-
//set_planes(Vector3(1,1,1));
}
diff --git a/scene/resources/concave_polygon_shape_3d.h b/scene/resources/concave_polygon_shape_3d.h
index b4e96c662f..c268ed9f37 100644
--- a/scene/resources/concave_polygon_shape_3d.h
+++ b/scene/resources/concave_polygon_shape_3d.h
@@ -34,18 +34,17 @@
#include "scene/resources/shape_3d.h"
class ConcavePolygonShape3D : public Shape3D {
-
GDCLASS(ConcavePolygonShape3D, Shape3D);
struct DrawEdge {
-
Vector3 a;
Vector3 b;
bool operator<(const DrawEdge &p_edge) const {
- if (a == p_edge.a)
+ if (a == p_edge.a) {
return b < p_edge.b;
- else
+ } else {
return a < p_edge.a;
+ }
}
DrawEdge(const Vector3 &p_a = Vector3(), const Vector3 &p_b = Vector3()) {
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index 6b1ddec507..7df7c3ac72 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -35,12 +35,10 @@
#include "servers/rendering_server.h"
bool ConvexPolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
return Geometry::is_point_in_polygon(p_point, points);
}
void ConvexPolygonShape2D::_update_shape() {
-
Vector<Vector2> final_points = points;
if (Geometry::is_polygon_clockwise(final_points)) { //needs to be counter clockwise
final_points.invert();
@@ -50,26 +48,22 @@ void ConvexPolygonShape2D::_update_shape() {
}
void ConvexPolygonShape2D::set_point_cloud(const Vector<Vector2> &p_points) {
-
Vector<Point2> hull = Geometry::convex_hull_2d(p_points);
ERR_FAIL_COND(hull.size() < 3);
set_points(hull);
}
void ConvexPolygonShape2D::set_points(const Vector<Vector2> &p_points) {
-
points = p_points;
_update_shape();
}
Vector<Vector2> ConvexPolygonShape2D::get_points() const {
-
return points;
}
void ConvexPolygonShape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_point_cloud", "point_cloud"), &ConvexPolygonShape2D::set_point_cloud);
ClassDB::bind_method(D_METHOD("set_points", "points"), &ConvexPolygonShape2D::set_points);
ClassDB::bind_method(D_METHOD("get_points"), &ConvexPolygonShape2D::get_points);
@@ -78,20 +72,19 @@ void ConvexPolygonShape2D::_bind_methods() {
}
void ConvexPolygonShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
Vector<Color> col;
col.push_back(p_color);
RenderingServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
}
Rect2 ConvexPolygonShape2D::get_rect() const {
-
Rect2 rect;
for (int i = 0; i < points.size(); i++) {
- if (i == 0)
+ if (i == 0) {
rect.position = points[i];
- else
+ } else {
rect.expand_to(points[i]);
+ }
}
return rect;
diff --git a/scene/resources/convex_polygon_shape_3d.cpp b/scene/resources/convex_polygon_shape_3d.cpp
index ec9ab68015..e52df73663 100644
--- a/scene/resources/convex_polygon_shape_3d.cpp
+++ b/scene/resources/convex_polygon_shape_3d.cpp
@@ -33,11 +33,9 @@
#include "servers/physics_server_3d.h"
Vector<Vector3> ConvexPolygonShape3D::get_debug_mesh_lines() {
-
Vector<Vector3> points = get_points();
if (points.size() > 3) {
-
Vector<Vector3> varr = Variant(points);
Geometry::MeshData md;
Error err = QuickHull::build(varr, md);
@@ -66,25 +64,21 @@ real_t ConvexPolygonShape3D::get_enclosing_radius() const {
}
void ConvexPolygonShape3D::_update_shape() {
-
PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), points);
Shape3D::_update_shape();
}
void ConvexPolygonShape3D::set_points(const Vector<Vector3> &p_points) {
-
points = p_points;
_update_shape();
notify_change_to_owners();
}
Vector<Vector3> ConvexPolygonShape3D::get_points() const {
-
return points;
}
void ConvexPolygonShape3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_points", "points"), &ConvexPolygonShape3D::set_points);
ClassDB::bind_method(D_METHOD("get_points"), &ConvexPolygonShape3D::get_points);
diff --git a/scene/resources/convex_polygon_shape_3d.h b/scene/resources/convex_polygon_shape_3d.h
index 51e4c8eb0b..0e3dde47a5 100644
--- a/scene/resources/convex_polygon_shape_3d.h
+++ b/scene/resources/convex_polygon_shape_3d.h
@@ -34,7 +34,6 @@
#include "scene/resources/shape_3d.h"
class ConvexPolygonShape3D : public Shape3D {
-
GDCLASS(ConvexPolygonShape3D, Shape3D);
Vector<Vector3> points;
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index d19eae0d4f..de076670cf 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -58,10 +58,11 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, T
// Add a point and preserve order
// Curve bounds is in 0..1
- if (p_pos.x > MAX_X)
+ if (p_pos.x > MAX_X) {
p_pos.x = MAX_X;
- else if (p_pos.x < MIN_X)
+ } else if (p_pos.x < MIN_X) {
p_pos.x = MIN_X;
+ }
int ret = -1;
@@ -83,7 +84,6 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, T
}
} else {
-
int i = get_index(p_pos.x);
if (i == 0 && p_pos.x < _points[0].pos.x) {
@@ -106,7 +106,6 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, T
}
int Curve::get_index(real_t offset) const {
-
// Lower-bound float binary search
int imin = 0;
@@ -130,13 +129,13 @@ int Curve::get_index(real_t offset) const {
}
// Will happen if the offset is out of bounds
- if (offset > _points[imax].pos.x)
+ if (offset > _points[imax].pos.x) {
return imax;
+ }
return imin;
}
void Curve::clean_dupes() {
-
bool dirty = false;
for (int i = 1; i < _points.size(); ++i) {
@@ -148,8 +147,9 @@ void Curve::clean_dupes() {
}
}
- if (dirty)
+ if (dirty) {
mark_dirty();
+ }
}
void Curve::set_point_left_tangent(int i, real_t tangent) {
@@ -237,8 +237,9 @@ int Curve::set_point_offset(int p_index, float offset) {
_points.write[i].right_tangent = p.right_tangent;
_points.write[i].left_mode = p.left_mode;
_points.write[i].right_mode = p.right_mode;
- if (p_index != i)
+ if (p_index != i) {
update_auto_tangents(p_index);
+ }
update_auto_tangents(i);
return i;
}
@@ -254,7 +255,6 @@ Curve::Point Curve::get_point(int p_index) const {
}
void Curve::update_auto_tangents(int i) {
-
Point &p = _points.write[i];
if (i > 0) {
@@ -305,26 +305,29 @@ void Curve::set_max_value(float p_max) {
}
real_t Curve::interpolate(real_t offset) const {
- if (_points.size() == 0)
+ if (_points.size() == 0) {
return 0;
- if (_points.size() == 1)
+ }
+ if (_points.size() == 1) {
return _points[0].pos.y;
+ }
int i = get_index(offset);
- if (i == _points.size() - 1)
+ if (i == _points.size() - 1) {
return _points[i].pos.y;
+ }
real_t local = offset - _points[i].pos.x;
- if (i == 0 && local <= 0)
+ if (i == 0 && local <= 0) {
return _points[0].pos.y;
+ }
return interpolate_local_nocheck(i, local);
}
real_t Curve::interpolate_local_nocheck(int index, real_t local_offset) const {
-
const Point a = _points[index];
const Point b = _points[index + 1];
@@ -344,8 +347,9 @@ real_t Curve::interpolate_local_nocheck(int index, real_t local_offset) const {
// Control points are chosen at equal distances
real_t d = b.pos.x - a.pos.x;
- if (Math::abs(d) <= CMP_EPSILON)
+ if (Math::abs(d) <= CMP_EPSILON) {
return b.pos.y;
+ }
local_offset /= d;
d /= 3.0;
real_t yac = a.pos.y + d * a.right_tangent;
@@ -362,13 +366,11 @@ void Curve::mark_dirty() {
}
Array Curve::get_data() const {
-
Array output;
const unsigned int ELEMS = 5;
output.resize(_points.size() * ELEMS);
for (int j = 0; j < _points.size(); ++j) {
-
const Point p = _points[j];
int i = j * ELEMS;
@@ -406,7 +408,6 @@ void Curve::set_data(Array input) {
_points.resize(input.size() / ELEMS);
for (int j = 0; j < _points.size(); ++j) {
-
Point &p = _points.write[j];
int i = j * ELEMS;
@@ -457,8 +458,9 @@ real_t Curve::interpolate_baked(real_t offset) {
// Special cases if the cache is too small
if (_baked_cache.size() == 0) {
- if (_points.size() == 0)
+ if (_points.size() == 0) {
return 0;
+ }
return _points[0].pos.y;
} else if (_baked_cache.size() == 1) {
return _baked_cache[0];
@@ -486,7 +488,6 @@ real_t Curve::interpolate_baked(real_t offset) {
void Curve::ensure_default_setup(float p_min, float p_max) {
if (_points.size() == 0 && _min_value == 0 && _max_value == 1) {
-
add_point(Vector2(0, 1));
add_point(Vector2(1, 1));
set_min_value(p_min);
@@ -495,7 +496,6 @@ void Curve::ensure_default_setup(float p_min, float p_max) {
}
void Curve::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_point_count"), &Curve::get_point_count);
ClassDB::bind_method(D_METHOD("add_point", "position", "left_tangent", "right_tangent", "left_mode", "right_mode"), &Curve::add_point, DEFVAL(0), DEFVAL(0), DEFVAL(TANGENT_FREE), DEFVAL(TANGENT_FREE));
ClassDB::bind_method(D_METHOD("remove_point", "index"), &Curve::remove_point);
@@ -537,54 +537,51 @@ void Curve::_bind_methods() {
}
int Curve2D::get_point_count() const {
-
return points.size();
}
-void Curve2D::add_point(const Vector2 &p_pos, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) {
+void Curve2D::add_point(const Vector2 &p_pos, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) {
Point n;
n.pos = p_pos;
n.in = p_in;
n.out = p_out;
- if (p_atpos >= 0 && p_atpos < points.size())
+ if (p_atpos >= 0 && p_atpos < points.size()) {
points.insert(p_atpos, n);
- else
+ } else {
points.push_back(n);
+ }
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
void Curve2D::set_point_position(int p_index, const Vector2 &p_pos) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].pos = p_pos;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-Vector2 Curve2D::get_point_position(int p_index) const {
+Vector2 Curve2D::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector2());
return points[p_index].pos;
}
void Curve2D::set_point_in(int p_index, const Vector2 &p_in) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].in = p_in;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-Vector2 Curve2D::get_point_in(int p_index) const {
+Vector2 Curve2D::get_point_in(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector2());
return points[p_index].in;
}
void Curve2D::set_point_out(int p_index, const Vector2 &p_out) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].out = p_out;
@@ -593,13 +590,11 @@ void Curve2D::set_point_out(int p_index, const Vector2 &p_out) {
}
Vector2 Curve2D::get_point_out(int p_index) const {
-
ERR_FAIL_INDEX_V(p_index, points.size(), Vector2());
return points[p_index].out;
}
void Curve2D::remove_point(int p_index) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.remove(p_index);
baked_cache_dirty = true;
@@ -615,14 +610,14 @@ void Curve2D::clear_points() {
}
Vector2 Curve2D::interpolate(int p_index, float p_offset) const {
-
int pc = points.size();
ERR_FAIL_COND_V(pc == 0, Vector2());
- if (p_index >= pc - 1)
+ if (p_index >= pc - 1) {
return points[pc - 1].pos;
- else if (p_index < 0)
+ } else if (p_index < 0) {
return points[0].pos;
+ }
Vector2 p0 = points[p_index].pos;
Vector2 p1 = p0 + points[p_index].out;
@@ -633,17 +628,16 @@ Vector2 Curve2D::interpolate(int p_index, float p_offset) const {
}
Vector2 Curve2D::interpolatef(real_t p_findex) const {
-
- if (p_findex < 0)
+ if (p_findex < 0) {
p_findex = 0;
- else if (p_findex >= points.size())
+ } else if (p_findex >= points.size()) {
p_findex = points.size();
+ }
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
}
void Curve2D::_bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, float p_tol) const {
-
float mp = p_begin + (p_end - p_begin) * 0.5;
Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
Vector2 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
@@ -654,7 +648,6 @@ void Curve2D::_bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float
float dp = na.dot(nb);
if (dp < Math::cos(Math::deg2rad(p_tol))) {
-
r_bake[mp] = mid;
}
@@ -665,9 +658,9 @@ void Curve2D::_bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float
}
void Curve2D::_bake() const {
-
- if (!baked_cache_dirty)
+ if (!baked_cache_dirty) {
return;
+ }
baked_max_ofs = 0;
baked_cache_dirty = false;
@@ -678,7 +671,6 @@ void Curve2D::_bake() const {
}
if (points.size() == 1) {
-
baked_point_cache.resize(1);
baked_point_cache.set(0, points[0].pos);
return;
@@ -690,15 +682,14 @@ void Curve2D::_bake() const {
pointlist.push_back(pos); //start always from origin
for (int i = 0; i < points.size() - 1; i++) {
-
float step = 0.1; // at least 10 substeps ought to be enough?
float p = 0;
while (p < 1.0) {
-
float np = p + step;
- if (np > 1.0)
+ if (np > 1.0) {
np = 1.0;
+ }
Vector2 npp = _bezier_interp(np, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
float d = pos.distance_to(npp);
@@ -713,14 +704,14 @@ void Curve2D::_bake() const {
float mid = low + (hi - low) * 0.5;
for (int j = 0; j < iterations; j++) {
-
npp = _bezier_interp(mid, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
d = pos.distance_to(npp);
- if (bake_interval < d)
+ if (bake_interval < d) {
hi = mid;
- else
+ } else {
low = mid;
+ }
mid = low + (hi - low) * 0.5;
}
@@ -728,7 +719,6 @@ void Curve2D::_bake() const {
p = mid;
pointlist.push_back(pos);
} else {
-
p = np;
}
}
@@ -745,38 +735,41 @@ void Curve2D::_bake() const {
int idx = 0;
for (List<Vector2>::Element *E = pointlist.front(); E; E = E->next()) {
-
w[idx] = E->get();
idx++;
}
}
float Curve2D::get_baked_length() const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_max_ofs;
}
-Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
- if (baked_cache_dirty)
+Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, Vector2(), "No points in Curve2D.");
- if (pc == 1)
+ if (pc == 1) {
return baked_point_cache.get(0);
+ }
int bpc = baked_point_cache.size();
const Vector2 *r = baked_point_cache.ptr();
- if (p_offset < 0)
+ if (p_offset < 0) {
return r[0];
- if (p_offset >= baked_max_ofs)
+ }
+ if (p_offset >= baked_max_ofs) {
return r[bpc - 1];
+ }
int idx = Math::floor((double)p_offset / (double)bake_interval);
float frac = Math::fmod(p_offset, (float)bake_interval);
@@ -784,54 +777,54 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
if (idx >= bpc - 1) {
return r[bpc - 1];
} else if (idx == bpc - 2) {
- if (frac > 0)
+ if (frac > 0) {
frac /= Math::fmod(baked_max_ofs, bake_interval);
+ }
} else {
frac /= bake_interval;
}
if (p_cubic) {
-
Vector2 pre = idx > 0 ? r[idx - 1] : r[idx];
Vector2 post = (idx < (bpc - 2)) ? r[idx + 2] : r[idx + 1];
return r[idx].cubic_interpolate(r[idx + 1], pre, post, frac);
} else {
- return r[idx].linear_interpolate(r[idx + 1], frac);
+ return r[idx].lerp(r[idx + 1], frac);
}
}
PackedVector2Array Curve2D::get_baked_points() const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_point_cache;
}
void Curve2D::set_bake_interval(float p_tolerance) {
-
bake_interval = p_tolerance;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
float Curve2D::get_bake_interval() const {
-
return bake_interval;
}
Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const {
// Brute force method
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, Vector2(), "No points in Curve2D.");
- if (pc == 1)
+ if (pc == 1) {
return baked_point_cache.get(0);
+ }
const Vector2 *r = baked_point_cache.ptr();
@@ -859,15 +852,17 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const {
float Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
// Brute force method
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, 0.0f, "No points in Curve2D.");
- if (pc == 1)
+ if (pc == 1) {
return 0.0f;
+ }
const Vector2 *r = baked_point_cache.ptr();
@@ -896,7 +891,6 @@ float Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
}
Dictionary Curve2D::_get_data() const {
-
Dictionary dc;
PackedVector2Array d;
@@ -904,7 +898,6 @@ Dictionary Curve2D::_get_data() const {
Vector2 *w = d.ptrw();
for (int i = 0; i < points.size(); i++) {
-
w[i * 3 + 0] = points[i].in;
w[i * 3 + 1] = points[i].out;
w[i * 3 + 2] = points[i].pos;
@@ -914,8 +907,8 @@ Dictionary Curve2D::_get_data() const {
return dc;
}
-void Curve2D::_set_data(const Dictionary &p_data) {
+void Curve2D::_set_data(const Dictionary &p_data) {
ERR_FAIL_COND(!p_data.has("points"));
PackedVector2Array rp = p_data["points"];
@@ -925,7 +918,6 @@ void Curve2D::_set_data(const Dictionary &p_data) {
const Vector2 *r = rp.ptr();
for (int i = 0; i < points.size(); i++) {
-
points.write[i].in = r[i * 3 + 0];
points.write[i].out = r[i * 3 + 1];
points.write[i].pos = r[i * 3 + 2];
@@ -935,7 +927,6 @@ void Curve2D::_set_data(const Dictionary &p_data) {
}
PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const {
-
PackedVector2Array tess;
if (points.size() == 0) {
@@ -947,7 +938,6 @@ PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) cons
int pc = 1;
for (int i = 0; i < points.size() - 1; i++) {
-
_bake_segment2d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
pc++;
pc += midpoints[i].size();
@@ -959,9 +949,7 @@ PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) cons
int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) {
-
for (Map<float, Vector2>::Element *E = midpoints[i].front(); E; E = E->next()) {
-
pidx++;
bpw[pidx] = E->get();
}
@@ -974,7 +962,6 @@ PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) cons
}
void Curve2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_point_count"), &Curve2D::get_point_count);
ClassDB::bind_method(D_METHOD("add_point", "position", "in", "out", "at_position"), &Curve2D::add_point, DEFVAL(Vector2()), DEFVAL(Vector2()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("set_point_position", "idx", "position"), &Curve2D::set_point_position);
@@ -1022,67 +1009,64 @@ Curve2D::Curve2D() {
/***********************************************************************************/
int Curve3D::get_point_count() const {
-
return points.size();
}
-void Curve3D::add_point(const Vector3 &p_pos, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) {
+void Curve3D::add_point(const Vector3 &p_pos, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) {
Point n;
n.pos = p_pos;
n.in = p_in;
n.out = p_out;
- if (p_atpos >= 0 && p_atpos < points.size())
+ if (p_atpos >= 0 && p_atpos < points.size()) {
points.insert(p_atpos, n);
- else
+ } else {
points.push_back(n);
+ }
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-void Curve3D::set_point_position(int p_index, const Vector3 &p_pos) {
+void Curve3D::set_point_position(int p_index, const Vector3 &p_pos) {
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].pos = p_pos;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-Vector3 Curve3D::get_point_position(int p_index) const {
+Vector3 Curve3D::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector3());
return points[p_index].pos;
}
void Curve3D::set_point_tilt(int p_index, float p_tilt) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].tilt = p_tilt;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-float Curve3D::get_point_tilt(int p_index) const {
+float Curve3D::get_point_tilt(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), 0);
return points[p_index].tilt;
}
void Curve3D::set_point_in(int p_index, const Vector3 &p_in) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].in = p_in;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-Vector3 Curve3D::get_point_in(int p_index) const {
+Vector3 Curve3D::get_point_in(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector3());
return points[p_index].in;
}
void Curve3D::set_point_out(int p_index, const Vector3 &p_out) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].out = p_out;
@@ -1091,13 +1075,11 @@ void Curve3D::set_point_out(int p_index, const Vector3 &p_out) {
}
Vector3 Curve3D::get_point_out(int p_index) const {
-
ERR_FAIL_INDEX_V(p_index, points.size(), Vector3());
return points[p_index].out;
}
void Curve3D::remove_point(int p_index) {
-
ERR_FAIL_INDEX(p_index, points.size());
points.remove(p_index);
baked_cache_dirty = true;
@@ -1105,7 +1087,6 @@ void Curve3D::remove_point(int p_index) {
}
void Curve3D::clear_points() {
-
if (!points.empty()) {
points.clear();
baked_cache_dirty = true;
@@ -1114,14 +1095,14 @@ void Curve3D::clear_points() {
}
Vector3 Curve3D::interpolate(int p_index, float p_offset) const {
-
int pc = points.size();
ERR_FAIL_COND_V(pc == 0, Vector3());
- if (p_index >= pc - 1)
+ if (p_index >= pc - 1) {
return points[pc - 1].pos;
- else if (p_index < 0)
+ } else if (p_index < 0) {
return points[0].pos;
+ }
Vector3 p0 = points[p_index].pos;
Vector3 p1 = p0 + points[p_index].out;
@@ -1132,17 +1113,16 @@ Vector3 Curve3D::interpolate(int p_index, float p_offset) const {
}
Vector3 Curve3D::interpolatef(real_t p_findex) const {
-
- if (p_findex < 0)
+ if (p_findex < 0) {
p_findex = 0;
- else if (p_findex >= points.size())
+ } else if (p_findex >= points.size()) {
p_findex = points.size();
+ }
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
}
void Curve3D::_bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, float p_tol) const {
-
float mp = p_begin + (p_end - p_begin) * 0.5;
Vector3 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
Vector3 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
@@ -1153,7 +1133,6 @@ void Curve3D::_bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float
float dp = na.dot(nb);
if (dp < Math::cos(Math::deg2rad(p_tol))) {
-
r_bake[mp] = mid;
}
if (p_depth < p_max_depth) {
@@ -1163,9 +1142,9 @@ void Curve3D::_bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float
}
void Curve3D::_bake() const {
-
- if (!baked_cache_dirty)
+ if (!baked_cache_dirty) {
return;
+ }
baked_max_ofs = 0;
baked_cache_dirty = false;
@@ -1178,18 +1157,17 @@ void Curve3D::_bake() const {
}
if (points.size() == 1) {
-
baked_point_cache.resize(1);
baked_point_cache.set(0, points[0].pos);
baked_tilt_cache.resize(1);
baked_tilt_cache.set(0, points[0].tilt);
if (up_vector_enabled) {
-
baked_up_vector_cache.resize(1);
baked_up_vector_cache.set(0, Vector3(0, 1, 0));
- } else
+ } else {
baked_up_vector_cache.resize(0);
+ }
return;
}
@@ -1199,15 +1177,14 @@ void Curve3D::_bake() const {
pointlist.push_back(Plane(pos, points[0].tilt));
for (int i = 0; i < points.size() - 1; i++) {
-
float step = 0.1; // at least 10 substeps ought to be enough?
float p = 0;
while (p < 1.0) {
-
float np = p + step;
- if (np > 1.0)
+ if (np > 1.0) {
np = 1.0;
+ }
Vector3 npp = _bezier_interp(np, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
float d = pos.distance_to(npp);
@@ -1222,14 +1199,14 @@ void Curve3D::_bake() const {
float mid = low + (hi - low) * 0.5;
for (int j = 0; j < iterations; j++) {
-
npp = _bezier_interp(mid, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
d = pos.distance_to(npp);
- if (bake_interval < d)
+ if (bake_interval < d) {
hi = mid;
- else
+ } else {
low = mid;
+ }
mid = low + (hi - low) * 0.5;
}
@@ -1240,7 +1217,6 @@ void Curve3D::_bake() const {
post.d = Math::lerp(points[i].tilt, points[i + 1].tilt, mid);
pointlist.push_back(post);
} else {
-
p = np;
}
}
@@ -1272,7 +1248,6 @@ void Curve3D::_bake() const {
Vector3 prev_forward = Vector3(0, 0, 1);
for (List<Plane>::Element *E = pointlist.front(); E; E = E->next()) {
-
w[idx] = E->get().normal;
wt[idx] = E->get().d;
@@ -1296,8 +1271,9 @@ void Curve3D::_bake() const {
up = forward.cross(sideways).normalized();
}
- if (idx == 1)
+ if (idx == 1) {
up_write[0] = up;
+ }
up_write[idx] = up;
@@ -1310,31 +1286,35 @@ void Curve3D::_bake() const {
}
float Curve3D::get_baked_length() const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_max_ofs;
}
-Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
- if (baked_cache_dirty)
+Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, Vector3(), "No points in Curve3D.");
- if (pc == 1)
+ if (pc == 1) {
return baked_point_cache.get(0);
+ }
int bpc = baked_point_cache.size();
const Vector3 *r = baked_point_cache.ptr();
- if (p_offset < 0)
+ if (p_offset < 0) {
return r[0];
- if (p_offset >= baked_max_ofs)
+ }
+ if (p_offset >= baked_max_ofs) {
return r[bpc - 1];
+ }
int idx = Math::floor((double)p_offset / (double)bake_interval);
float frac = Math::fmod(p_offset, bake_interval);
@@ -1342,41 +1322,44 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
if (idx >= bpc - 1) {
return r[bpc - 1];
} else if (idx == bpc - 2) {
- if (frac > 0)
+ if (frac > 0) {
frac /= Math::fmod(baked_max_ofs, bake_interval);
+ }
} else {
frac /= bake_interval;
}
if (p_cubic) {
-
Vector3 pre = idx > 0 ? r[idx - 1] : r[idx];
Vector3 post = (idx < (bpc - 2)) ? r[idx + 2] : r[idx + 1];
return r[idx].cubic_interpolate(r[idx + 1], pre, post, frac);
} else {
- return r[idx].linear_interpolate(r[idx + 1], frac);
+ return r[idx].lerp(r[idx + 1], frac);
}
}
float Curve3D::interpolate_baked_tilt(float p_offset) const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_tilt_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, 0, "No tilts in Curve3D.");
- if (pc == 1)
+ if (pc == 1) {
return baked_tilt_cache.get(0);
+ }
int bpc = baked_tilt_cache.size();
const real_t *r = baked_tilt_cache.ptr();
- if (p_offset < 0)
+ if (p_offset < 0) {
return r[0];
- if (p_offset >= baked_max_ofs)
+ }
+ if (p_offset >= baked_max_ofs) {
return r[bpc - 1];
+ }
int idx = Math::floor((double)p_offset / (double)bake_interval);
float frac = Math::fmod(p_offset, bake_interval);
@@ -1384,8 +1367,9 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const {
if (idx >= bpc - 1) {
return r[bpc - 1];
} else if (idx == bpc - 2) {
- if (frac > 0)
+ if (frac > 0) {
frac /= Math::fmod(baked_max_ofs, bake_interval);
+ }
} else {
frac /= bake_interval;
}
@@ -1394,17 +1378,18 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const {
}
Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
// curve may not have baked up vectors
int count = baked_up_vector_cache.size();
ERR_FAIL_COND_V_MSG(count == 0, Vector3(0, 1, 0), "No up vectors in Curve3D.");
- if (count == 1)
+ if (count == 1) {
return baked_up_vector_cache.get(0);
+ }
const Vector3 *r = baked_up_vector_cache.ptr();
const Vector3 *rp = baked_point_cache.ptr();
@@ -1415,8 +1400,9 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt)
int idx = Math::floor((double)offset / (double)bake_interval);
float frac = Math::fmod(offset, bake_interval) / bake_interval;
- if (idx == count - 1)
+ if (idx == count - 1) {
return p_apply_tilt ? r[idx].rotated((rp[idx] - rp[idx - 1]).normalized(), rt[idx]) : r[idx];
+ }
Vector3 forward = (rp[idx + 1] - rp[idx]).normalized();
Vector3 up = r[idx];
@@ -1429,34 +1415,35 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt)
Vector3 axis = up.cross(up1);
- if (axis.length_squared() < CMP_EPSILON2)
+ if (axis.length_squared() < CMP_EPSILON2) {
axis = forward;
- else
+ } else {
axis.normalize();
+ }
return up.rotated(axis, up.angle_to(up1) * frac);
}
PackedVector3Array Curve3D::get_baked_points() const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_point_cache;
}
PackedFloat32Array Curve3D::get_baked_tilts() const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_tilt_cache;
}
PackedVector3Array Curve3D::get_baked_up_vectors() const {
-
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
return baked_up_vector_cache;
}
@@ -1464,15 +1451,17 @@ PackedVector3Array Curve3D::get_baked_up_vectors() const {
Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const {
// Brute force method
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, Vector3(), "No points in Curve3D.");
- if (pc == 1)
+ if (pc == 1) {
return baked_point_cache.get(0);
+ }
const Vector3 *r = baked_point_cache.ptr();
@@ -1500,15 +1489,17 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const {
float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
// Brute force method
- if (baked_cache_dirty)
+ if (baked_cache_dirty) {
_bake();
+ }
//validate//
int pc = baked_point_cache.size();
ERR_FAIL_COND_V_MSG(pc == 0, 0.0f, "No points in Curve3D.");
- if (pc == 1)
+ if (pc == 1) {
return 0.0f;
+ }
const Vector3 *r = baked_point_cache.ptr();
@@ -1537,31 +1528,26 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
}
void Curve3D::set_bake_interval(float p_tolerance) {
-
bake_interval = p_tolerance;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
float Curve3D::get_bake_interval() const {
-
return bake_interval;
}
void Curve3D::set_up_vector_enabled(bool p_enable) {
-
up_vector_enabled = p_enable;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
bool Curve3D::is_up_vector_enabled() const {
-
return up_vector_enabled;
}
Dictionary Curve3D::_get_data() const {
-
Dictionary dc;
PackedVector3Array d;
@@ -1572,7 +1558,6 @@ Dictionary Curve3D::_get_data() const {
real_t *wt = t.ptrw();
for (int i = 0; i < points.size(); i++) {
-
w[i * 3 + 0] = points[i].in;
w[i * 3 + 1] = points[i].out;
w[i * 3 + 2] = points[i].pos;
@@ -1584,8 +1569,8 @@ Dictionary Curve3D::_get_data() const {
return dc;
}
-void Curve3D::_set_data(const Dictionary &p_data) {
+void Curve3D::_set_data(const Dictionary &p_data) {
ERR_FAIL_COND(!p_data.has("points"));
ERR_FAIL_COND(!p_data.has("tilts"));
@@ -1598,7 +1583,6 @@ void Curve3D::_set_data(const Dictionary &p_data) {
const real_t *rt = rtl.ptr();
for (int i = 0; i < points.size(); i++) {
-
points.write[i].in = r[i * 3 + 0];
points.write[i].out = r[i * 3 + 1];
points.write[i].pos = r[i * 3 + 2];
@@ -1609,7 +1593,6 @@ void Curve3D::_set_data(const Dictionary &p_data) {
}
PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const {
-
PackedVector3Array tess;
if (points.size() == 0) {
@@ -1621,7 +1604,6 @@ PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) cons
int pc = 1;
for (int i = 0; i < points.size() - 1; i++) {
-
_bake_segment3d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
pc++;
pc += midpoints[i].size();
@@ -1633,9 +1615,7 @@ PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) cons
int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) {
-
for (Map<float, Vector3>::Element *E = midpoints[i].front(); E; E = E->next()) {
-
pidx++;
bpw[pidx] = E->get();
}
@@ -1648,7 +1628,6 @@ PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) cons
}
void Curve3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_point_count"), &Curve3D::get_point_count);
ClassDB::bind_method(D_METHOD("add_point", "position", "in", "out", "at_position"), &Curve3D::add_point, DEFVAL(Vector3()), DEFVAL(Vector3()), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("set_point_position", "idx", "position"), &Curve3D::set_point_position);
diff --git a/scene/resources/curve.h b/scene/resources/curve.h
index 7dcbf1ceff..57ddaf897d 100644
--- a/scene/resources/curve.h
+++ b/scene/resources/curve.h
@@ -68,7 +68,6 @@ public:
real_t p_right = 0,
TangentMode p_left_mode = TANGENT_FREE,
TangentMode p_right_mode = TANGENT_FREE) {
-
pos = p_pos;
left_tangent = p_left;
right_tangent = p_right;
@@ -149,11 +148,9 @@ private:
VARIANT_ENUM_CAST(Curve::TangentMode)
class Curve2D : public Resource {
-
GDCLASS(Curve2D, Resource);
struct Point {
-
Vector2 in;
Vector2 out;
Vector2 pos;
@@ -162,7 +159,6 @@ class Curve2D : public Resource {
Vector<Point> points;
struct BakedPoint {
-
float ofs;
Vector2 point;
};
@@ -212,11 +208,9 @@ public:
};
class Curve3D : public Resource {
-
GDCLASS(Curve3D, Resource);
struct Point {
-
Vector3 in;
Vector3 out;
Vector3 pos;
@@ -228,7 +222,6 @@ class Curve3D : public Resource {
Vector<Point> points;
struct BakedPoint {
-
float ofs;
Vector3 point;
};
diff --git a/scene/resources/cylinder_shape_3d.cpp b/scene/resources/cylinder_shape_3d.cpp
index 19f0542818..44786d6025 100644
--- a/scene/resources/cylinder_shape_3d.cpp
+++ b/scene/resources/cylinder_shape_3d.cpp
@@ -32,7 +32,6 @@
#include "servers/physics_server_3d.h"
Vector<Vector3> CylinderShape3D::get_debug_mesh_lines() {
-
float radius = get_radius();
float height = get_height();
@@ -40,7 +39,6 @@ Vector<Vector3> CylinderShape3D::get_debug_mesh_lines() {
Vector3 d(0, height * 0.5, 0);
for (int i = 0; i < 360; i++) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + 1);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * radius;
@@ -53,7 +51,6 @@ Vector<Vector3> CylinderShape3D::get_debug_mesh_lines() {
points.push_back(Vector3(b.x, 0, b.y) - d);
if (i % 90 == 0) {
-
points.push_back(Vector3(a.x, 0, a.y) + d);
points.push_back(Vector3(a.x, 0, a.y) - d);
}
@@ -67,7 +64,6 @@ real_t CylinderShape3D::get_enclosing_radius() const {
}
void CylinderShape3D::_update_shape() {
-
Dictionary d;
d["radius"] = radius;
d["height"] = height;
@@ -76,7 +72,6 @@ void CylinderShape3D::_update_shape() {
}
void CylinderShape3D::set_radius(float p_radius) {
-
radius = p_radius;
_update_shape();
notify_change_to_owners();
@@ -84,12 +79,10 @@ void CylinderShape3D::set_radius(float p_radius) {
}
float CylinderShape3D::get_radius() const {
-
return radius;
}
void CylinderShape3D::set_height(float p_height) {
-
height = p_height;
_update_shape();
notify_change_to_owners();
@@ -97,12 +90,10 @@ void CylinderShape3D::set_height(float p_height) {
}
float CylinderShape3D::get_height() const {
-
return height;
}
void CylinderShape3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CylinderShape3D::set_radius);
ClassDB::bind_method(D_METHOD("get_radius"), &CylinderShape3D::get_radius);
ClassDB::bind_method(D_METHOD("set_height", "height"), &CylinderShape3D::set_height);
@@ -114,7 +105,6 @@ void CylinderShape3D::_bind_methods() {
CylinderShape3D::CylinderShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_CYLINDER)) {
-
radius = 1.0;
height = 2.0;
_update_shape();
diff --git a/scene/resources/cylinder_shape_3d.h b/scene/resources/cylinder_shape_3d.h
index 7b37f733e0..23d206cbab 100644
--- a/scene/resources/cylinder_shape_3d.h
+++ b/scene/resources/cylinder_shape_3d.h
@@ -34,7 +34,6 @@
#include "scene/resources/shape_3d.h"
class CylinderShape3D : public Shape3D {
-
GDCLASS(CylinderShape3D, Shape3D);
float radius;
float height;
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index a1e8bf51bd..de39fac627 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -45,29 +45,16 @@ static float scale = 1;
template <class T>
static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, float p_right, float p_botton, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1, bool p_draw_center = true) {
-
Ref<ImageTexture> texture;
if (tex_cache->has(p_src)) {
texture = (*tex_cache)[p_src];
} else {
-
texture = Ref<ImageTexture>(memnew(ImageTexture));
Ref<Image> img = memnew(Image(p_src));
-
- if (scale > 1) {
- Size2 orig_size = Size2(img->get_width(), img->get_height());
-
- img->convert(Image::FORMAT_RGBA8);
- img->expand_x2_hq2x();
- if (scale != 2.0) {
- img->resize(orig_size.x * scale, orig_size.y * scale);
- }
- } else if (scale < 1) {
- Size2 orig_size = Size2(img->get_width(), img->get_height());
- img->convert(Image::FORMAT_RGBA8);
- img->resize(orig_size.x * scale, orig_size.y * scale);
- }
+ const Size2 orig_size = Size2(img->get_width(), img->get_height());
+ img->convert(Image::FORMAT_RGBA8);
+ img->resize(orig_size.x * scale, orig_size.y * scale);
texture->create_from_image(img);
(*tex_cache)[p_src] = texture;
@@ -89,7 +76,6 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, fl
}
static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left, float p_top, float p_right, float p_botton) {
-
p_sbox->set_expand_margin_size(MARGIN_LEFT, p_left * scale);
p_sbox->set_expand_margin_size(MARGIN_TOP, p_top * scale);
p_sbox->set_expand_margin_size(MARGIN_RIGHT, p_right * scale);
@@ -99,29 +85,17 @@ static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left,
template <class T>
static Ref<Texture2D> make_icon(T p_src) {
-
Ref<ImageTexture> texture(memnew(ImageTexture));
Ref<Image> img = memnew(Image(p_src));
- if (scale > 1) {
- Size2 orig_size = Size2(img->get_width(), img->get_height());
-
- img->convert(Image::FORMAT_RGBA8);
- img->expand_x2_hq2x();
- if (scale != 2.0) {
- img->resize(orig_size.x * scale, orig_size.y * scale);
- }
- } else if (scale < 1) {
- Size2 orig_size = Size2(img->get_width(), img->get_height());
- img->convert(Image::FORMAT_RGBA8);
- img->resize(orig_size.x * scale, orig_size.y * scale);
- }
+ const Size2 orig_size = Size2(img->get_width(), img->get_height());
+ img->convert(Image::FORMAT_RGBA8);
+ img->resize(orig_size.x * scale, orig_size.y * scale);
texture->create_from_image(img);
return texture;
}
static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_charcount, const int *p_char_rects, int p_kerning_count, const int *p_kernings, int p_w, int p_h, const unsigned char *p_img) {
-
Ref<BitmapFont> font(memnew(BitmapFont));
Ref<Image> image = memnew(Image(p_img));
@@ -131,7 +105,6 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_charcount, co
font->add_texture(tex);
for (int i = 0; i < p_charcount; i++) {
-
const int *c = &p_char_rects[i * 8];
int chr = c[0];
@@ -147,7 +120,6 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_charcount, co
}
for (int i = 0; i < p_kerning_count; i++) {
-
font->add_kerning_pair(p_kernings[i * 3 + 0], p_kernings[i * 3 + 1], p_kernings[i * 3 + 2]);
}
@@ -158,7 +130,6 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_charcount, co
}
static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1) {
-
Ref<StyleBox> style(memnew(StyleBoxEmpty));
style->set_default_margin(MARGIN_LEFT, p_margin_left * scale);
@@ -170,7 +141,6 @@ static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margi
}
void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture2D> &default_icon, Ref<StyleBox> &default_style, float p_scale) {
-
scale = p_scale;
tex_cache = memnew(TexCacheMap);
@@ -711,7 +681,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_color("font_color_disabled", "TabContainer", control_font_color_disabled);
theme->set_constant("side_margin", "TabContainer", 8 * scale);
- theme->set_constant("hseparation", "TabContainer", 4 * scale);
+ theme->set_constant("icon_separation", "TabContainer", 4 * scale);
// Tabs
@@ -779,8 +749,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// TooltipPanel
Ref<StyleBoxTexture> style_tt = make_stylebox(tooltip_bg_png, 4, 4, 4, 4);
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < 4; i++) {
style_tt->set_expand_margin_size((Margin)i, 4 * scale);
+ }
theme->set_stylebox("panel", "TooltipPanel", style_tt);
@@ -867,7 +838,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
}
void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
-
Ref<Theme> t;
t.instance();
@@ -891,7 +861,6 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) {
}
void clear_default_theme() {
-
Theme::set_project_default(nullptr);
Theme::set_default(nullptr);
Theme::set_default_icon(nullptr);
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index a613b01376..3b4e4b73f8 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -46,7 +46,6 @@ bool DynamicFontData::CacheID::operator<(CacheID right) const {
}
Ref<DynamicFontAtSize> DynamicFontData::_get_dynamic_font_at_size(CacheID p_cache_id) {
-
if (size_cache.has(p_cache_id)) {
return Ref<DynamicFontAtSize>(size_cache[p_cache_id]);
}
@@ -65,13 +64,11 @@ Ref<DynamicFontAtSize> DynamicFontData::_get_dynamic_font_at_size(CacheID p_cach
}
void DynamicFontData::set_font_ptr(const uint8_t *p_font_mem, int p_font_mem_size) {
-
font_mem = p_font_mem;
font_mem_size = p_font_mem_size;
}
void DynamicFontData::set_font_path(const String &p_path) {
-
font_path = p_path;
}
@@ -80,7 +77,6 @@ String DynamicFontData::get_font_path() const {
}
void DynamicFontData::set_force_autohinter(bool p_force) {
-
force_autohinter = p_force;
}
@@ -103,7 +99,6 @@ void DynamicFontData::_bind_methods() {
}
DynamicFontData::DynamicFontData() {
-
antialiased = true;
force_autohinter = false;
hinting = DynamicFontData::HINTING_NORMAL;
@@ -118,7 +113,6 @@ DynamicFontData::~DynamicFontData() {
HashMap<String, Vector<uint8_t>> DynamicFontAtSize::_fontdata;
Error DynamicFontAtSize::_load() {
-
int error = FT_Init_FreeType(&library);
ERR_FAIL_COND_V_MSG(error != 0, ERR_CANT_CREATE, "Error initializing FreeType.");
@@ -127,11 +121,9 @@ Error DynamicFontAtSize::_load() {
if (OS::get_singleton()->get_name() == "Android" && font->font_mem == nullptr && font->font_path != String()) {
// cache font only once for each font->font_path
if (_fontdata.has(font->font_path)) {
-
font->set_font_ptr(_fontdata[font->font_path].ptr(), _fontdata[font->font_path].size());
} else {
-
FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ);
if (!f) {
FT_Done_FreeType(library);
@@ -149,7 +141,6 @@ Error DynamicFontAtSize::_load() {
}
if (font->font_mem == nullptr && font->font_path != String()) {
-
FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ);
if (!f) {
FT_Done_FreeType(library);
@@ -170,7 +161,6 @@ Error DynamicFontAtSize::_load() {
fargs.stream = &stream;
error = FT_Open_Face(library, &fargs, 0, &face);
} else if (font->font_mem) {
-
memset(&stream, 0, sizeof(FT_StreamRec));
stream.base = (unsigned char *)font->font_mem;
stream.size = font->font_mem_size;
@@ -192,12 +182,10 @@ Error DynamicFontAtSize::_load() {
//error = FT_New_Face( library, src_path.utf8().get_data(),0,&face );
if (error == FT_Err_Unknown_File_Format) {
-
FT_Done_FreeType(library);
ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, "Unknown font format.");
} else if (error) {
-
FT_Done_FreeType(library);
ERR_FAIL_V_MSG(ERR_FILE_CANT_OPEN, "Error loading font.");
}
@@ -221,6 +209,8 @@ Error DynamicFontAtSize::_load() {
ascent = (face->size->metrics.ascender / 64.0) / oversampling * scale_color_font;
descent = (-face->size->metrics.descender / 64.0) / oversampling * scale_color_font;
+ underline_position = -face->underline_position / 64.0 / oversampling * scale_color_font;
+ underline_thickness = face->underline_thickness / 64.0 / oversampling * scale_color_font;
linegap = 0;
valid = true;
@@ -230,38 +220,44 @@ Error DynamicFontAtSize::_load() {
float DynamicFontAtSize::font_oversampling = 1.0;
float DynamicFontAtSize::get_height() const {
-
return ascent + descent;
}
float DynamicFontAtSize::get_ascent() const {
-
return ascent;
}
-float DynamicFontAtSize::get_descent() const {
+float DynamicFontAtSize::get_descent() const {
return descent;
}
+float DynamicFontAtSize::get_underline_position() const {
+ return underline_position;
+}
+
+float DynamicFontAtSize::get_underline_thickness() const {
+ return underline_thickness;
+}
+
const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const {
const Character *chr = char_map.getptr(p_char);
ERR_FAIL_COND_V(!chr, (Pair<const Character *, DynamicFontAtSize *>(nullptr, nullptr)));
if (!chr->found) {
-
//not found, try in fallbacks
for (int i = 0; i < p_fallbacks.size(); i++) {
-
DynamicFontAtSize *fb = const_cast<DynamicFontAtSize *>(p_fallbacks[i].ptr());
- if (!fb->valid)
+ if (!fb->valid) {
continue;
+ }
fb->_update_char(p_char);
const Character *fallback_chr = fb->char_map.getptr(p_char);
ERR_CONTINUE(!fallback_chr);
- if (!fallback_chr->found)
+ if (!fallback_chr->found) {
continue;
+ }
return Pair<const Character *, DynamicFontAtSize *>(fallback_chr, fb);
}
@@ -276,9 +272,9 @@ const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFon
}
Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const {
-
- if (!valid)
+ if (!valid) {
return Size2(1, 1);
+ }
const_cast<DynamicFontAtSize *>(this)->_update_char(p_char);
Pair<const Character *, DynamicFontAtSize *> char_pair_with_font = _find_char_with_font(p_char, p_fallbacks);
@@ -295,9 +291,9 @@ Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const V
}
float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only, bool p_outline) const {
-
- if (!valid)
+ if (!valid) {
return 0;
+ }
const_cast<DynamicFontAtSize *>(this)->_update_char(p_char);
@@ -346,20 +342,20 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT
}
unsigned long DynamicFontAtSize::_ft_stream_io(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) {
-
FileAccess *f = (FileAccess *)stream->descriptor.pointer;
if (f->get_position() != offset) {
f->seek(offset);
}
- if (count == 0)
+ if (count == 0) {
return 0;
+ }
return f->get_buffer(buffer, count);
}
-void DynamicFontAtSize::_ft_stream_close(FT_Stream stream) {
+void DynamicFontAtSize::_ft_stream_close(FT_Stream stream) {
FileAccess *f = (FileAccess *)stream->descriptor.pointer;
f->close();
memdelete(f);
@@ -385,27 +381,27 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp
int mh = p_height;
for (int i = 0; i < textures.size(); i++) {
-
const CharTexture &ct = textures[i];
- if (ct.texture->get_format() != p_image_format)
+ if (ct.texture->get_format() != p_image_format) {
continue;
+ }
- if (mw > ct.texture_size || mh > ct.texture_size) //too big for this texture
+ if (mw > ct.texture_size || mh > ct.texture_size) { //too big for this texture
continue;
+ }
ret.y = 0x7FFFFFFF;
ret.x = 0;
for (int j = 0; j < ct.texture_size - mw; j++) {
-
int max_y = 0;
for (int k = j; k < j + mw; k++) {
-
int y = ct.offsets[k];
- if (y > max_y)
+ if (y > max_y) {
max_y = y;
+ }
}
if (max_y < ret.y) {
@@ -414,8 +410,9 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp
}
}
- if (ret.y == 0x7FFFFFFF || ret.y + mh > ct.texture_size)
+ if (ret.y == 0x7FFFFFFF || ret.y + mh > ct.texture_size) {
continue; //fail, could not fit it here
+ }
ret.index = i;
break;
@@ -427,10 +424,12 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp
ret.y = 0;
int texsize = MAX(id.size * oversampling * 8, 256);
- if (mw > texsize)
+ if (mw > texsize) {
texsize = mw; //special case, adapt to it?
- if (mh > texsize)
+ }
+ if (mh > texsize) {
texsize = mh; //special case, adapt to it?
+ }
texsize = next_power_of_2(texsize);
@@ -449,8 +448,9 @@ DynamicFontAtSize::TexturePosition DynamicFontAtSize::_find_texture_pos_for_glyp
}
}
tex.offsets.resize(texsize);
- for (int i = 0; i < texsize; i++) //zero offsets
+ for (int i = 0; i < texsize; i++) { //zero offsets
tex.offsets.write[i] = 0;
+ }
textures.push_back(tex);
ret.index = textures.size() - 1;
@@ -484,7 +484,6 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
-
int ofs = ((i + tex_pos.y + rect_margin) * tex.texture_size + j + tex_pos.x + rect_margin) * color_size;
ERR_FAIL_COND_V(ofs >= tex.imgdata.size(), Character::not_found());
switch (bitmap.pixel_mode) {
@@ -516,7 +515,6 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
//blit to image and texture
{
-
Ref<Image> img = memnew(Image(tex.texture_size, tex.texture_size, 0, require_format, tex.imgdata));
if (tex.texture.is_null()) {
@@ -550,23 +548,28 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b
DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(CharType p_char) {
Character ret = Character::not_found();
- if (FT_Load_Char(face, p_char, FT_LOAD_NO_BITMAP | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)) != 0)
+ if (FT_Load_Char(face, p_char, FT_LOAD_NO_BITMAP | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)) != 0) {
return ret;
+ }
FT_Stroker stroker;
- if (FT_Stroker_New(library, &stroker) != 0)
+ if (FT_Stroker_New(library, &stroker) != 0) {
return ret;
+ }
FT_Stroker_Set(stroker, (int)(id.outline_size * oversampling * 64.0), FT_STROKER_LINECAP_BUTT, FT_STROKER_LINEJOIN_ROUND, 0);
FT_Glyph glyph;
FT_BitmapGlyph glyph_bitmap;
- if (FT_Get_Glyph(face->glyph, &glyph) != 0)
+ if (FT_Get_Glyph(face->glyph, &glyph) != 0) {
goto cleanup_stroker;
- if (FT_Glyph_Stroke(&glyph, stroker, 1) != 0)
+ }
+ if (FT_Glyph_Stroke(&glyph, stroker, 1) != 0) {
goto cleanup_glyph;
- if (FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, nullptr, 1) != 0)
+ }
+ if (FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, nullptr, 1) != 0) {
goto cleanup_glyph;
+ }
glyph_bitmap = (FT_BitmapGlyph)glyph;
ret = _bitmap_to_character(glyph_bitmap->bitmap, glyph_bitmap->top, glyph_bitmap->left, glyph->advance.x / 65536.0);
@@ -579,9 +582,9 @@ cleanup_stroker:
}
void DynamicFontAtSize::_update_char(CharType p_char) {
-
- if (char_map.has(p_char))
+ if (char_map.has(p_char)) {
return;
+ }
_THREAD_SAFE_METHOD_
@@ -618,16 +621,18 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
character = _make_outline_char(p_char);
} else {
error = FT_Render_Glyph(face->glyph, font->antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO);
- if (!error)
+ if (!error) {
character = _bitmap_to_character(slot->bitmap, slot->bitmap_top, slot->bitmap_left, slot->advance.x / 64.0);
+ }
}
char_map[p_char] = character;
}
void DynamicFontAtSize::update_oversampling() {
- if (oversampling == font_oversampling || !valid)
+ if (oversampling == font_oversampling || !valid) {
return;
+ }
FT_Done_FreeType(library);
textures.clear();
@@ -638,7 +643,6 @@ void DynamicFontAtSize::update_oversampling() {
}
DynamicFontAtSize::DynamicFontAtSize() {
-
valid = false;
rect_margin = 1;
ascent = 1;
@@ -649,7 +653,6 @@ DynamicFontAtSize::DynamicFontAtSize() {
}
DynamicFontAtSize::~DynamicFontAtSize() {
-
if (valid) {
FT_Done_FreeType(library);
}
@@ -660,7 +663,6 @@ DynamicFontAtSize::~DynamicFontAtSize() {
/////////////////////////
void DynamicFont::_reload_cache() {
-
ERR_FAIL_COND(cache_id.size < 1);
if (!data.is_valid()) {
data_at_size.unref();
@@ -682,8 +684,9 @@ void DynamicFont::_reload_cache() {
for (int i = 0; i < fallbacks.size(); i++) {
fallback_data_at_size.write[i] = fallbacks.write[i]->_get_dynamic_font_at_size(cache_id);
- if (outline_cache_id.outline_size > 0)
+ if (outline_cache_id.outline_size > 0) {
fallback_outline_data_at_size.write[i] = fallbacks.write[i]->_get_dynamic_font_at_size(outline_cache_id);
+ }
}
emit_changed();
@@ -691,7 +694,6 @@ void DynamicFont::_reload_cache() {
}
void DynamicFont::set_font_data(const Ref<DynamicFontData> &p_data) {
-
data = p_data;
_reload_cache();
@@ -700,27 +702,26 @@ void DynamicFont::set_font_data(const Ref<DynamicFontData> &p_data) {
}
Ref<DynamicFontData> DynamicFont::get_font_data() const {
-
return data;
}
void DynamicFont::set_size(int p_size) {
-
- if (cache_id.size == p_size)
+ if (cache_id.size == p_size) {
return;
+ }
cache_id.size = p_size;
outline_cache_id.size = p_size;
_reload_cache();
}
int DynamicFont::get_size() const {
-
return cache_id.size;
}
void DynamicFont::set_outline_size(int p_size) {
- if (outline_cache_id.outline_size == p_size)
+ if (outline_cache_id.outline_size == p_size) {
return;
+ }
ERR_FAIL_COND(p_size < 0 || p_size > UINT8_MAX);
outline_cache_id.outline_size = p_size;
_reload_cache();
@@ -743,31 +744,28 @@ Color DynamicFont::get_outline_color() const {
}
bool DynamicFontData::is_antialiased() const {
-
return antialiased;
}
void DynamicFontData::set_antialiased(bool p_antialiased) {
-
- if (antialiased == p_antialiased)
+ if (antialiased == p_antialiased) {
return;
+ }
antialiased = p_antialiased;
}
DynamicFontData::Hinting DynamicFontData::get_hinting() const {
-
return hinting;
}
void DynamicFontData::set_hinting(Hinting p_hinting) {
-
- if (hinting == p_hinting)
+ if (hinting == p_hinting) {
return;
+ }
hinting = p_hinting;
}
int DynamicFont::get_spacing(int p_type) const {
-
if (p_type == SPACING_TOP) {
return spacing_top;
} else if (p_type == SPACING_BOTTOM) {
@@ -782,7 +780,6 @@ int DynamicFont::get_spacing(int p_type) const {
}
void DynamicFont::set_spacing(int p_type, int p_value) {
-
if (p_type == SPACING_TOP) {
spacing_top = p_value;
} else if (p_type == SPACING_BOTTOM) {
@@ -798,45 +795,61 @@ void DynamicFont::set_spacing(int p_type, int p_value) {
}
float DynamicFont::get_height() const {
-
- if (!data_at_size.is_valid())
+ if (!data_at_size.is_valid()) {
return 1;
+ }
return data_at_size->get_height() + spacing_top + spacing_bottom;
}
float DynamicFont::get_ascent() const {
-
- if (!data_at_size.is_valid())
+ if (!data_at_size.is_valid()) {
return 1;
+ }
return data_at_size->get_ascent() + spacing_top;
}
float DynamicFont::get_descent() const {
-
- if (!data_at_size.is_valid())
+ if (!data_at_size.is_valid()) {
return 1;
+ }
return data_at_size->get_descent() + spacing_bottom;
}
-Size2 DynamicFont::get_char_size(CharType p_char, CharType p_next) const {
+float DynamicFont::get_underline_position() const {
+ if (!data_at_size.is_valid()) {
+ return 2;
+ }
+
+ return data_at_size->get_underline_position();
+}
+
+float DynamicFont::get_underline_thickness() const {
+ if (!data_at_size.is_valid()) {
+ return 1;
+ }
+
+ return data_at_size->get_underline_thickness();
+}
- if (!data_at_size.is_valid())
+Size2 DynamicFont::get_char_size(CharType p_char, CharType p_next) const {
+ if (!data_at_size.is_valid()) {
return Size2(1, 1);
+ }
Size2 ret = data_at_size->get_char_size(p_char, p_next, fallback_data_at_size);
- if (p_char == ' ')
+ if (p_char == ' ') {
ret.width += spacing_space + spacing_char;
- else if (p_next)
+ } else if (p_next) {
ret.width += spacing_char;
+ }
return ret;
}
bool DynamicFont::is_distance_field_hint() const {
-
return false;
}
@@ -847,8 +860,9 @@ bool DynamicFont::has_outline() const {
float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const {
const Ref<DynamicFontAtSize> &font_at_size = p_outline && outline_cache_id.outline_size > 0 ? outline_data_at_size : data_at_size;
- if (!font_at_size.is_valid())
+ if (!font_at_size.is_valid()) {
return 0;
+ }
const Vector<Ref<DynamicFontAtSize>> &fallbacks = p_outline && outline_cache_id.outline_size > 0 ? fallback_outline_data_at_size : fallback_data_at_size;
Color color = p_outline && outline_cache_id.outline_size > 0 ? p_modulate * outline_color : p_modulate;
@@ -859,7 +873,6 @@ float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_
}
void DynamicFont::set_fallback(int p_idx, const Ref<DynamicFontData> &p_data) {
-
ERR_FAIL_COND(p_data.is_null());
ERR_FAIL_INDEX(p_idx, fallbacks.size());
fallbacks.write[p_idx] = p_data;
@@ -867,12 +880,12 @@ void DynamicFont::set_fallback(int p_idx, const Ref<DynamicFontData> &p_data) {
}
void DynamicFont::add_fallback(const Ref<DynamicFontData> &p_data) {
-
ERR_FAIL_COND(p_data.is_null());
fallbacks.push_back(p_data);
fallback_data_at_size.push_back(fallbacks.write[fallbacks.size() - 1]->_get_dynamic_font_at_size(cache_id)); //const..
- if (outline_cache_id.outline_size > 0)
+ if (outline_cache_id.outline_size > 0) {
fallback_outline_data_at_size.push_back(fallbacks.write[fallbacks.size() - 1]->_get_dynamic_font_at_size(outline_cache_id));
+ }
_change_notify();
emit_changed();
@@ -882,14 +895,14 @@ void DynamicFont::add_fallback(const Ref<DynamicFontData> &p_data) {
int DynamicFont::get_fallback_count() const {
return fallbacks.size();
}
-Ref<DynamicFontData> DynamicFont::get_fallback(int p_idx) const {
+Ref<DynamicFontData> DynamicFont::get_fallback(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, fallbacks.size(), Ref<DynamicFontData>());
return fallbacks[p_idx];
}
-void DynamicFont::remove_fallback(int p_idx) {
+void DynamicFont::remove_fallback(int p_idx) {
ERR_FAIL_INDEX(p_idx, fallbacks.size());
fallbacks.remove(p_idx);
fallback_data_at_size.remove(p_idx);
@@ -898,7 +911,6 @@ void DynamicFont::remove_fallback(int p_idx) {
}
bool DynamicFont::_set(const StringName &p_name, const Variant &p_value) {
-
String str = p_name;
if (str.begins_with("fallback/")) {
int idx = str.get_slicec('/', 1).to_int();
@@ -924,7 +936,6 @@ bool DynamicFont::_set(const StringName &p_name, const Variant &p_value) {
}
bool DynamicFont::_get(const StringName &p_name, Variant &r_ret) const {
-
String str = p_name;
if (str.begins_with("fallback/")) {
int idx = str.get_slicec('/', 1).to_int();
@@ -940,8 +951,8 @@ bool DynamicFont::_get(const StringName &p_name, Variant &r_ret) const {
return false;
}
-void DynamicFont::_get_property_list(List<PropertyInfo> *p_list) const {
+void DynamicFont::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < fallbacks.size(); i++) {
p_list->push_back(PropertyInfo(Variant::OBJECT, "fallback/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "DynamicFontData"));
}
@@ -950,7 +961,6 @@ void DynamicFont::_get_property_list(List<PropertyInfo> *p_list) const {
}
void DynamicFont::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_font_data", "data"), &DynamicFont::set_font_data);
ClassDB::bind_method(D_METHOD("get_font_data"), &DynamicFont::get_font_data);
@@ -996,7 +1006,6 @@ SelfList<DynamicFont>::List *DynamicFont::dynamic_fonts = nullptr;
DynamicFont::DynamicFont() :
font_list(this) {
-
valid = false;
cache_id.size = 16;
outline_cache_id.size = 16;
@@ -1025,14 +1034,12 @@ void DynamicFont::finish_dynamic_fonts() {
}
void DynamicFont::update_oversampling() {
-
Vector<Ref<DynamicFont>> changed;
{
MutexLock lock(dynamic_font_mutex);
SelfList<DynamicFont> *E = dynamic_fonts->first();
while (E) {
-
if (E->self()->data_at_size.is_valid()) {
E->self()->data_at_size->update_oversampling();
@@ -1064,37 +1071,36 @@ void DynamicFont::update_oversampling() {
/////////////////////////
-RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
- if (r_error)
+RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
+ }
Ref<DynamicFontData> dfont;
dfont.instance();
dfont->set_font_path(p_path);
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return dfont;
}
void ResourceFormatLoaderDynamicFont::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("ttf");
p_extensions->push_back("otf");
}
bool ResourceFormatLoaderDynamicFont::handles_type(const String &p_type) const {
-
return (p_type == "DynamicFontData");
}
String ResourceFormatLoaderDynamicFont::get_resource_type(const String &p_path) const {
-
String el = p_path.get_extension().to_lower();
- if (el == "ttf" || el == "otf")
+ if (el == "ttf" || el == "otf") {
return "DynamicFontData";
+ }
return "";
}
diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h
index 9e628fc35a..08ad20a92d 100644
--- a/scene/resources/dynamic_font.h
+++ b/scene/resources/dynamic_font.h
@@ -47,7 +47,6 @@ class DynamicFontAtSize;
class DynamicFont;
class DynamicFontData : public Resource {
-
GDCLASS(DynamicFontData, Resource);
public:
@@ -109,7 +108,6 @@ public:
VARIANT_ENUM_CAST(DynamicFontData::Hinting);
class DynamicFontAtSize : public Reference {
-
GDCLASS(DynamicFontAtSize, Reference);
_THREAD_SAFE_CLASS_
@@ -124,11 +122,12 @@ class DynamicFontAtSize : public Reference {
float rect_margin;
float oversampling;
float scale_color_font;
+ float underline_position;
+ float underline_thickness;
bool valid;
struct CharTexture {
-
Vector<uint8_t> imgdata;
int texture_size;
Vector<int> offsets;
@@ -138,7 +137,6 @@ class DynamicFontAtSize : public Reference {
Vector<CharTexture> textures;
struct Character {
-
bool found;
int texture_idx;
Rect2 rect;
@@ -187,6 +185,8 @@ public:
float get_ascent() const;
float get_descent() const;
+ float get_underline_position() const;
+ float get_underline_thickness() const;
Size2 get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const;
@@ -202,7 +202,6 @@ public:
///////////////
class DynamicFont : public Font {
-
GDCLASS(DynamicFont, Font);
public:
@@ -274,6 +273,8 @@ public:
virtual float get_ascent() const;
virtual float get_descent() const;
+ virtual float get_underline_position() const;
+ virtual float get_underline_thickness() const;
virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const;
@@ -302,7 +303,7 @@ VARIANT_ENUM_CAST(DynamicFont::SpacingType);
class ResourceFormatLoaderDynamicFont : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 835fef81e1..80ee0c148d 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -34,60 +34,57 @@
#include "texture.h"
RID Environment::get_rid() const {
-
return environment;
}
void Environment::set_background(BGMode p_bg) {
-
bg_mode = p_bg;
RS::get_singleton()->environment_set_background(environment, RS::EnvironmentBG(p_bg));
_change_notify();
}
void Environment::set_sky(const Ref<Sky> &p_sky) {
-
bg_sky = p_sky;
RID sb_rid;
- if (bg_sky.is_valid())
+ if (bg_sky.is_valid()) {
sb_rid = bg_sky->get_rid();
+ }
RS::get_singleton()->environment_set_sky(environment, sb_rid);
}
void Environment::set_sky_custom_fov(float p_scale) {
-
bg_sky_custom_fov = p_scale;
RS::get_singleton()->environment_set_sky_custom_fov(environment, p_scale);
}
-void Environment::set_bg_color(const Color &p_color) {
+void Environment::set_bg_color(const Color &p_color) {
bg_color = p_color;
RS::get_singleton()->environment_set_bg_color(environment, p_color);
}
-void Environment::set_bg_energy(float p_energy) {
+void Environment::set_bg_energy(float p_energy) {
bg_energy = p_energy;
RS::get_singleton()->environment_set_bg_energy(environment, p_energy);
}
-void Environment::set_canvas_max_layer(int p_max_layer) {
+void Environment::set_canvas_max_layer(int p_max_layer) {
bg_canvas_max_layer = p_max_layer;
RS::get_singleton()->environment_set_canvas_max_layer(environment, p_max_layer);
}
-void Environment::set_ambient_light_color(const Color &p_color) {
+void Environment::set_ambient_light_color(const Color &p_color) {
ambient_color = p_color;
RS::get_singleton()->environment_set_ambient_light(environment, ambient_color, RS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), ao_color);
}
-void Environment::set_ambient_light_energy(float p_energy) {
+void Environment::set_ambient_light_energy(float p_energy) {
ambient_energy = p_energy;
RS::get_singleton()->environment_set_ambient_light(environment, ambient_color, RS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), ao_color);
}
-void Environment::set_ambient_light_sky_contribution(float p_energy) {
+void Environment::set_ambient_light_sky_contribution(float p_energy) {
ambient_sky_contribution = p_energy;
RS::get_singleton()->environment_set_ambient_light(environment, ambient_color, RS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), ao_color);
}
@@ -108,25 +105,25 @@ void Environment::set_ambient_source(AmbientSource p_source) {
Environment::AmbientSource Environment::get_ambient_source() const {
return ambient_source;
}
+
void Environment::set_reflection_source(ReflectionSource p_source) {
reflection_source = p_source;
RS::get_singleton()->environment_set_ambient_light(environment, ambient_color, RS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), ao_color);
}
+
Environment::ReflectionSource Environment::get_reflection_source() const {
return reflection_source;
}
Environment::BGMode Environment::get_background() const {
-
return bg_mode;
}
-Ref<Sky> Environment::get_sky() const {
+Ref<Sky> Environment::get_sky() const {
return bg_sky;
}
float Environment::get_sky_custom_fov() const {
-
return bg_sky_custom_fov;
}
@@ -136,176 +133,157 @@ void Environment::set_sky_rotation(const Vector3 &p_rotation) {
}
Vector3 Environment::get_sky_rotation() const {
-
return sky_rotation;
}
Color Environment::get_bg_color() const {
-
return bg_color;
}
-float Environment::get_bg_energy() const {
+float Environment::get_bg_energy() const {
return bg_energy;
}
-int Environment::get_canvas_max_layer() const {
+int Environment::get_canvas_max_layer() const {
return bg_canvas_max_layer;
}
-Color Environment::get_ambient_light_color() const {
+Color Environment::get_ambient_light_color() const {
return ambient_color;
}
-float Environment::get_ambient_light_energy() const {
+float Environment::get_ambient_light_energy() const {
return ambient_energy;
}
-float Environment::get_ambient_light_sky_contribution() const {
+float Environment::get_ambient_light_sky_contribution() const {
return ambient_sky_contribution;
}
-int Environment::get_camera_feed_id(void) const {
+int Environment::get_camera_feed_id() const {
return camera_feed_id;
}
void Environment::set_tonemapper(ToneMapper p_tone_mapper) {
-
tone_mapper = p_tone_mapper;
RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
}
Environment::ToneMapper Environment::get_tonemapper() const {
-
return tone_mapper;
}
void Environment::set_tonemap_exposure(float p_exposure) {
-
tonemap_exposure = p_exposure;
RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
}
float Environment::get_tonemap_exposure() const {
-
return tonemap_exposure;
}
void Environment::set_tonemap_white(float p_white) {
-
tonemap_white = p_white;
RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
}
-float Environment::get_tonemap_white() const {
+float Environment::get_tonemap_white() const {
return tonemap_white;
}
void Environment::set_tonemap_auto_exposure(bool p_enabled) {
-
tonemap_auto_exposure = p_enabled;
RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
_change_notify();
}
-bool Environment::get_tonemap_auto_exposure() const {
+bool Environment::get_tonemap_auto_exposure() const {
return tonemap_auto_exposure;
}
void Environment::set_tonemap_auto_exposure_max(float p_auto_exposure_max) {
-
tonemap_auto_exposure_max = p_auto_exposure_max;
RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
}
-float Environment::get_tonemap_auto_exposure_max() const {
+float Environment::get_tonemap_auto_exposure_max() const {
return tonemap_auto_exposure_max;
}
void Environment::set_tonemap_auto_exposure_min(float p_auto_exposure_min) {
-
tonemap_auto_exposure_min = p_auto_exposure_min;
RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
}
-float Environment::get_tonemap_auto_exposure_min() const {
+float Environment::get_tonemap_auto_exposure_min() const {
return tonemap_auto_exposure_min;
}
void Environment::set_tonemap_auto_exposure_speed(float p_auto_exposure_speed) {
-
tonemap_auto_exposure_speed = p_auto_exposure_speed;
RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
}
-float Environment::get_tonemap_auto_exposure_speed() const {
+float Environment::get_tonemap_auto_exposure_speed() const {
return tonemap_auto_exposure_speed;
}
void Environment::set_tonemap_auto_exposure_grey(float p_auto_exposure_grey) {
-
tonemap_auto_exposure_grey = p_auto_exposure_grey;
RS::get_singleton()->environment_set_tonemap(environment, RS::EnvironmentToneMapper(tone_mapper), tonemap_exposure, tonemap_white, tonemap_auto_exposure, tonemap_auto_exposure_min, tonemap_auto_exposure_max, tonemap_auto_exposure_speed, tonemap_auto_exposure_grey);
}
-float Environment::get_tonemap_auto_exposure_grey() const {
+float Environment::get_tonemap_auto_exposure_grey() const {
return tonemap_auto_exposure_grey;
}
void Environment::set_adjustment_enable(bool p_enable) {
-
adjustment_enabled = p_enable;
RS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
_change_notify();
}
bool Environment::is_adjustment_enabled() const {
-
return adjustment_enabled;
}
void Environment::set_adjustment_brightness(float p_brightness) {
-
adjustment_brightness = p_brightness;
RS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
}
-float Environment::get_adjustment_brightness() const {
+float Environment::get_adjustment_brightness() const {
return adjustment_brightness;
}
void Environment::set_adjustment_contrast(float p_contrast) {
-
adjustment_contrast = p_contrast;
RS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
}
-float Environment::get_adjustment_contrast() const {
+float Environment::get_adjustment_contrast() const {
return adjustment_contrast;
}
void Environment::set_adjustment_saturation(float p_saturation) {
-
adjustment_saturation = p_saturation;
RS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
}
-float Environment::get_adjustment_saturation() const {
+float Environment::get_adjustment_saturation() const {
return adjustment_saturation;
}
void Environment::set_adjustment_color_correction(const Ref<Texture2D> &p_ramp) {
-
adjustment_color_correction = p_ramp;
RS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
}
-Ref<Texture2D> Environment::get_adjustment_color_correction() const {
+Ref<Texture2D> Environment::get_adjustment_color_correction() const {
return adjustment_color_correction;
}
void Environment::_validate_property(PropertyInfo &property) const {
-
if (property.name == "sky" || property.name == "sky_custom_fov" || property.name == "sky_rotation" || property.name == "ambient_light/sky_contribution") {
if (bg_mode != BG_SKY && ambient_source != AMBIENT_SOURCE_SKY && reflection_source != REFLECTION_SOURCE_SKY) {
property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
@@ -387,409 +365,364 @@ void Environment::_validate_property(PropertyInfo &property) const {
}
void Environment::set_ssr_enabled(bool p_enable) {
-
ssr_enabled = p_enable;
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance);
_change_notify();
}
bool Environment::is_ssr_enabled() const {
-
return ssr_enabled;
}
void Environment::set_ssr_max_steps(int p_steps) {
-
ssr_max_steps = p_steps;
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance);
}
-int Environment::get_ssr_max_steps() const {
+int Environment::get_ssr_max_steps() const {
return ssr_max_steps;
}
void Environment::set_ssr_fade_in(float p_fade_in) {
-
ssr_fade_in = p_fade_in;
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance);
}
-float Environment::get_ssr_fade_in() const {
+float Environment::get_ssr_fade_in() const {
return ssr_fade_in;
}
void Environment::set_ssr_fade_out(float p_fade_out) {
-
ssr_fade_out = p_fade_out;
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance);
}
-float Environment::get_ssr_fade_out() const {
+float Environment::get_ssr_fade_out() const {
return ssr_fade_out;
}
void Environment::set_ssr_depth_tolerance(float p_depth_tolerance) {
-
ssr_depth_tolerance = p_depth_tolerance;
RS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance);
}
-float Environment::get_ssr_depth_tolerance() const {
+float Environment::get_ssr_depth_tolerance() const {
return ssr_depth_tolerance;
}
void Environment::set_ssao_enabled(bool p_enable) {
-
ssao_enabled = p_enable;
RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
_change_notify();
}
bool Environment::is_ssao_enabled() const {
-
return ssao_enabled;
}
void Environment::set_ssao_radius(float p_radius) {
-
ssao_radius = p_radius;
RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
-float Environment::get_ssao_radius() const {
+float Environment::get_ssao_radius() const {
return ssao_radius;
}
void Environment::set_ssao_intensity(float p_intensity) {
-
ssao_intensity = p_intensity;
RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
float Environment::get_ssao_intensity() const {
-
return ssao_intensity;
}
void Environment::set_ssao_bias(float p_bias) {
-
ssao_bias = p_bias;
RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
-float Environment::get_ssao_bias() const {
+float Environment::get_ssao_bias() const {
return ssao_bias;
}
void Environment::set_ssao_direct_light_affect(float p_direct_light_affect) {
-
ssao_direct_light_affect = p_direct_light_affect;
RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
-float Environment::get_ssao_direct_light_affect() const {
+float Environment::get_ssao_direct_light_affect() const {
return ssao_direct_light_affect;
}
void Environment::set_ssao_ao_channel_affect(float p_ao_channel_affect) {
-
ssao_ao_channel_affect = p_ao_channel_affect;
RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
-float Environment::get_ssao_ao_channel_affect() const {
+float Environment::get_ssao_ao_channel_affect() const {
return ssao_ao_channel_affect;
}
void Environment::set_ao_color(const Color &p_color) {
-
ao_color = p_color;
RS::get_singleton()->environment_set_ambient_light(environment, ambient_color, RS::EnvironmentAmbientSource(ambient_source), ambient_energy, ambient_sky_contribution, RS::EnvironmentReflectionSource(reflection_source), ao_color);
}
Color Environment::get_ao_color() const {
-
return ao_color;
}
void Environment::set_ssao_blur(SSAOBlur p_blur) {
-
ssao_blur = p_blur;
RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
-Environment::SSAOBlur Environment::get_ssao_blur() const {
+Environment::SSAOBlur Environment::get_ssao_blur() const {
return ssao_blur;
}
void Environment::set_ssao_edge_sharpness(float p_edge_sharpness) {
-
ssao_edge_sharpness = p_edge_sharpness;
RS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_bias, ssao_direct_light_affect, ssao_ao_channel_affect, RS::EnvironmentSSAOBlur(ssao_blur), ssao_edge_sharpness);
}
float Environment::get_ssao_edge_sharpness() const {
-
return ssao_edge_sharpness;
}
void Environment::set_glow_enabled(bool p_enabled) {
-
glow_enabled = p_enabled;
RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap);
_change_notify();
}
bool Environment::is_glow_enabled() const {
-
return glow_enabled;
}
void Environment::set_glow_level(int p_level, bool p_enabled) {
-
ERR_FAIL_INDEX(p_level, RS::MAX_GLOW_LEVELS);
- if (p_enabled)
+ if (p_enabled) {
glow_levels |= (1 << p_level);
- else
+ } else {
glow_levels &= ~(1 << p_level);
+ }
RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap);
}
-bool Environment::is_glow_level_enabled(int p_level) const {
+bool Environment::is_glow_level_enabled(int p_level) const {
ERR_FAIL_INDEX_V(p_level, RS::MAX_GLOW_LEVELS, false);
return glow_levels & (1 << p_level);
}
void Environment::set_glow_intensity(float p_intensity) {
-
glow_intensity = p_intensity;
RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap);
}
-float Environment::get_glow_intensity() const {
+float Environment::get_glow_intensity() const {
return glow_intensity;
}
void Environment::set_glow_strength(float p_strength) {
-
glow_strength = p_strength;
RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap);
}
-float Environment::get_glow_strength() const {
+float Environment::get_glow_strength() const {
return glow_strength;
}
void Environment::set_glow_mix(float p_mix) {
-
glow_mix = p_mix;
RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap);
}
-float Environment::get_glow_mix() const {
+float Environment::get_glow_mix() const {
return glow_mix;
}
void Environment::set_glow_bloom(float p_threshold) {
-
glow_bloom = p_threshold;
RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap);
}
-float Environment::get_glow_bloom() const {
+float Environment::get_glow_bloom() const {
return glow_bloom;
}
void Environment::set_glow_blend_mode(GlowBlendMode p_mode) {
-
glow_blend_mode = p_mode;
RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap);
_change_notify();
}
-Environment::GlowBlendMode Environment::get_glow_blend_mode() const {
+Environment::GlowBlendMode Environment::get_glow_blend_mode() const {
return glow_blend_mode;
}
void Environment::set_glow_hdr_bleed_threshold(float p_threshold) {
-
glow_hdr_bleed_threshold = p_threshold;
RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap);
}
-float Environment::get_glow_hdr_bleed_threshold() const {
+float Environment::get_glow_hdr_bleed_threshold() const {
return glow_hdr_bleed_threshold;
}
void Environment::set_glow_hdr_luminance_cap(float p_amount) {
-
glow_hdr_luminance_cap = p_amount;
RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap);
}
-float Environment::get_glow_hdr_luminance_cap() const {
+float Environment::get_glow_hdr_luminance_cap() const {
return glow_hdr_luminance_cap;
}
void Environment::set_glow_hdr_bleed_scale(float p_scale) {
-
glow_hdr_bleed_scale = p_scale;
RS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_mix, glow_bloom, RS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_threshold, glow_hdr_bleed_threshold, glow_hdr_luminance_cap);
}
-float Environment::get_glow_hdr_bleed_scale() const {
+float Environment::get_glow_hdr_bleed_scale() const {
return glow_hdr_bleed_scale;
}
void Environment::set_fog_enabled(bool p_enabled) {
-
fog_enabled = p_enabled;
RS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
_change_notify();
}
bool Environment::is_fog_enabled() const {
-
return fog_enabled;
}
void Environment::set_fog_color(const Color &p_color) {
-
fog_color = p_color;
RS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
}
-Color Environment::get_fog_color() const {
+Color Environment::get_fog_color() const {
return fog_color;
}
void Environment::set_fog_sun_color(const Color &p_color) {
-
fog_sun_color = p_color;
RS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
}
-Color Environment::get_fog_sun_color() const {
+Color Environment::get_fog_sun_color() const {
return fog_sun_color;
}
void Environment::set_fog_sun_amount(float p_amount) {
-
fog_sun_amount = p_amount;
RS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
}
-float Environment::get_fog_sun_amount() const {
+float Environment::get_fog_sun_amount() const {
return fog_sun_amount;
}
void Environment::set_fog_depth_enabled(bool p_enabled) {
-
fog_depth_enabled = p_enabled;
RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
}
-bool Environment::is_fog_depth_enabled() const {
+bool Environment::is_fog_depth_enabled() const {
return fog_depth_enabled;
}
void Environment::set_fog_depth_begin(float p_distance) {
-
fog_depth_begin = p_distance;
RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
}
-float Environment::get_fog_depth_begin() const {
+float Environment::get_fog_depth_begin() const {
return fog_depth_begin;
}
void Environment::set_fog_depth_end(float p_distance) {
-
fog_depth_end = p_distance;
RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
}
float Environment::get_fog_depth_end() const {
-
return fog_depth_end;
}
void Environment::set_fog_depth_curve(float p_curve) {
-
fog_depth_curve = p_curve;
RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
}
-float Environment::get_fog_depth_curve() const {
+float Environment::get_fog_depth_curve() const {
return fog_depth_curve;
}
void Environment::set_fog_transmit_enabled(bool p_enabled) {
-
fog_transmit_enabled = p_enabled;
RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
}
-bool Environment::is_fog_transmit_enabled() const {
+bool Environment::is_fog_transmit_enabled() const {
return fog_transmit_enabled;
}
void Environment::set_fog_transmit_curve(float p_curve) {
-
fog_transmit_curve = p_curve;
RS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_end, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
}
-float Environment::get_fog_transmit_curve() const {
+float Environment::get_fog_transmit_curve() const {
return fog_transmit_curve;
}
void Environment::set_fog_height_enabled(bool p_enabled) {
-
fog_height_enabled = p_enabled;
RS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
}
-bool Environment::is_fog_height_enabled() const {
+bool Environment::is_fog_height_enabled() const {
return fog_height_enabled;
}
void Environment::set_fog_height_min(float p_distance) {
-
fog_height_min = p_distance;
RS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
}
-float Environment::get_fog_height_min() const {
+float Environment::get_fog_height_min() const {
return fog_height_min;
}
void Environment::set_fog_height_max(float p_distance) {
-
fog_height_max = p_distance;
RS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
}
-float Environment::get_fog_height_max() const {
+float Environment::get_fog_height_max() const {
return fog_height_max;
}
void Environment::set_fog_height_curve(float p_distance) {
-
fog_height_curve = p_distance;
RS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
}
-float Environment::get_fog_height_curve() const {
+float Environment::get_fog_height_curve() const {
return fog_height_curve;
}
@@ -813,7 +746,6 @@ bool Environment::_set(const StringName &p_name, const Variant &p_value) {
#endif
void Environment::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_background", "mode"), &Environment::set_background);
ClassDB::bind_method(D_METHOD("set_sky", "sky"), &Environment::set_sky);
ClassDB::bind_method(D_METHOD("set_sky_custom_fov", "scale"), &Environment::set_sky_custom_fov);
@@ -1004,8 +936,8 @@ void Environment::_bind_methods() {
ADD_GROUP("SSAO", "ssao_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ssao_enabled"), "set_ssao_enabled", "is_ssao_enabled");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssao_radius", "get_ssao_radius");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.1"), "set_ssao_intensity", "get_ssao_intensity");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_radius", PROPERTY_HINT_RANGE, "0.1,128,0.01"), "set_ssao_radius", "get_ssao_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_intensity", PROPERTY_HINT_RANGE, "0.0,128,0.01"), "set_ssao_intensity", "get_ssao_intensity");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_bias", PROPERTY_HINT_RANGE, "0.001,8,0.001"), "set_ssao_bias", "get_ssao_bias");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_light_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_direct_light_affect", "get_ssao_direct_light_affect");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "ssao_ao_channel_affect", PROPERTY_HINT_RANGE, "0.00,1,0.01"), "set_ssao_ao_channel_affect", "get_ssao_ao_channel_affect");
@@ -1117,12 +1049,7 @@ void Environment::_bind_methods() {
BIND_ENUM_CONSTANT(SSAO_BLUR_3x3);
}
-Environment::Environment() :
- bg_mode(BG_CLEAR_COLOR),
- tone_mapper(TONE_MAPPER_LINEAR),
- ssao_blur(SSAO_BLUR_3x3),
- glow_blend_mode(GLOW_BLEND_MODE_ADDITIVE) {
-
+Environment::Environment() {
environment = RS::get_singleton()->environment_create();
bg_mode = BG_CLEAR_COLOR;
@@ -1204,84 +1131,72 @@ Environment::Environment() :
}
Environment::~Environment() {
-
RS::get_singleton()->free(environment);
}
//////////////////////
void CameraEffects::set_dof_blur_far_enabled(bool p_enable) {
-
dof_blur_far_enabled = p_enable;
RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
}
bool CameraEffects::is_dof_blur_far_enabled() const {
-
return dof_blur_far_enabled;
}
void CameraEffects::set_dof_blur_far_distance(float p_distance) {
-
dof_blur_far_distance = p_distance;
RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
}
-float CameraEffects::get_dof_blur_far_distance() const {
+float CameraEffects::get_dof_blur_far_distance() const {
return dof_blur_far_distance;
}
void CameraEffects::set_dof_blur_far_transition(float p_distance) {
-
dof_blur_far_transition = p_distance;
RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
}
-float CameraEffects::get_dof_blur_far_transition() const {
+float CameraEffects::get_dof_blur_far_transition() const {
return dof_blur_far_transition;
}
void CameraEffects::set_dof_blur_near_enabled(bool p_enable) {
-
dof_blur_near_enabled = p_enable;
RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
_change_notify();
}
bool CameraEffects::is_dof_blur_near_enabled() const {
-
return dof_blur_near_enabled;
}
void CameraEffects::set_dof_blur_near_distance(float p_distance) {
-
dof_blur_near_distance = p_distance;
RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
}
float CameraEffects::get_dof_blur_near_distance() const {
-
return dof_blur_near_distance;
}
void CameraEffects::set_dof_blur_near_transition(float p_distance) {
-
dof_blur_near_transition = p_distance;
RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
}
float CameraEffects::get_dof_blur_near_transition() const {
-
return dof_blur_near_transition;
}
void CameraEffects::set_dof_blur_amount(float p_amount) {
-
dof_blur_amount = p_amount;
RS::get_singleton()->camera_effects_set_dof_blur(camera_effects, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_amount);
}
-float CameraEffects::get_dof_blur_amount() const {
+float CameraEffects::get_dof_blur_amount() const {
return dof_blur_amount;
}
@@ -1308,7 +1223,6 @@ RID CameraEffects::get_rid() const {
}
void CameraEffects::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_dof_blur_far_enabled", "enabled"), &CameraEffects::set_dof_blur_far_enabled);
ClassDB::bind_method(D_METHOD("is_dof_blur_far_enabled"), &CameraEffects::is_dof_blur_far_enabled);
@@ -1350,7 +1264,6 @@ void CameraEffects::_bind_methods() {
}
CameraEffects::CameraEffects() {
-
camera_effects = RS::get_singleton()->camera_effects_create();
dof_blur_far_enabled = false;
@@ -1368,6 +1281,5 @@ CameraEffects::CameraEffects() {
}
CameraEffects::~CameraEffects() {
-
RS::get_singleton()->free(camera_effects);
}
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 02434bc592..b8caa59aab 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -37,7 +37,6 @@
#include "servers/rendering_server.h"
class Environment : public Resource {
-
GDCLASS(Environment, Resource);
public:
@@ -90,7 +89,7 @@ public:
private:
RID environment;
- BGMode bg_mode;
+ BGMode bg_mode = BG_CLEAR_COLOR;
Ref<Sky> bg_sky;
float bg_sky_custom_fov;
Vector3 sky_rotation;
@@ -105,7 +104,7 @@ private:
AmbientSource ambient_source;
ReflectionSource reflection_source;
- ToneMapper tone_mapper;
+ ToneMapper tone_mapper = TONE_MAPPER_LINEAR;
float tonemap_exposure;
float tonemap_white;
bool tonemap_auto_exposure;
@@ -132,7 +131,7 @@ private:
float ssao_bias;
float ssao_direct_light_affect;
float ssao_ao_channel_affect;
- SSAOBlur ssao_blur;
+ SSAOBlur ssao_blur = SSAO_BLUR_3x3;
float ssao_edge_sharpness;
bool glow_enabled;
@@ -141,7 +140,7 @@ private:
float glow_strength;
float glow_mix;
float glow_bloom;
- GlowBlendMode glow_blend_mode;
+ GlowBlendMode glow_blend_mode = GLOW_BLEND_MODE_ADDITIVE;
float glow_hdr_bleed_threshold;
float glow_hdr_bleed_scale;
float glow_hdr_luminance_cap;
@@ -200,7 +199,7 @@ public:
Color get_ambient_light_color() const;
float get_ambient_light_energy() const;
float get_ambient_light_sky_contribution() const;
- int get_camera_feed_id(void) const;
+ int get_camera_feed_id() const;
void set_tonemapper(ToneMapper p_tone_mapper);
ToneMapper get_tonemapper() const;
@@ -369,7 +368,6 @@ VARIANT_ENUM_CAST(Environment::GlowBlendMode)
VARIANT_ENUM_CAST(Environment::SSAOBlur)
class CameraEffects : public Resource {
-
GDCLASS(CameraEffects, Resource);
private:
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 192eefbf6a..1878b174e8 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -65,11 +65,11 @@ void Font::draw(RID p_canvas_item, const Point2 &p_pos, const String &p_text, co
int chars_drawn = 0;
bool with_outline = has_outline();
for (int i = 0; i < p_text.length(); i++) {
-
int width = get_char_size(p_text[i]).width;
- if (p_clip_w >= 0 && (ofs.x + width) > p_clip_w)
+ if (p_clip_w >= 0 && (ofs.x + width) > p_clip_w) {
break; //clip
+ }
ofs.x += draw_char(p_canvas_item, p_pos + ofs, p_text[i], p_text[i + 1], with_outline ? p_outline_modulate : p_modulate, with_outline);
++chars_drawn;
@@ -84,12 +84,10 @@ void Font::draw(RID p_canvas_item, const Point2 &p_pos, const String &p_text, co
}
void Font::update_changes() {
-
emit_changed();
}
void Font::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "string", "modulate", "clip_w", "outline_modulate"), &Font::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(-1), DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("get_ascent"), &Font::get_ascent);
ClassDB::bind_method(D_METHOD("get_descent"), &Font::get_descent);
@@ -108,30 +106,27 @@ Font::Font() {
/////////////////////////////////////////////////////////////////
void BitmapFont::_set_chars(const Vector<int> &p_chars) {
-
int len = p_chars.size();
//char 1 charsize 1 texture, 4 rect, 2 align, advance 1
ERR_FAIL_COND(len % 9);
- if (!len)
+ if (!len) {
return; //none to do
+ }
int chars = len / 9;
const int *r = p_chars.ptr();
for (int i = 0; i < chars; i++) {
-
const int *data = &r[i * 9];
add_char(data[0], data[1], Rect2(data[2], data[3], data[4], data[5]), Size2(data[6], data[7]), data[8]);
}
}
Vector<int> BitmapFont::_get_chars() const {
-
Vector<int> chars;
const CharType *key = nullptr;
while ((key = char_map.next(key))) {
-
const Character *c = char_map.getptr(*key);
ERR_FAIL_COND_V(!c, Vector<int>());
chars.push_back(*key);
@@ -150,26 +145,23 @@ Vector<int> BitmapFont::_get_chars() const {
}
void BitmapFont::_set_kernings(const Vector<int> &p_kernings) {
-
int len = p_kernings.size();
ERR_FAIL_COND(len % 3);
- if (!len)
+ if (!len) {
return;
+ }
const int *r = p_kernings.ptr();
for (int i = 0; i < len / 3; i++) {
-
const int *data = &r[i * 3];
add_kerning_pair(data[0], data[1], data[2]);
}
}
Vector<int> BitmapFont::_get_kernings() const {
-
Vector<int> kernings;
for (Map<KerningPairKey, int>::Element *E = kerning_map.front(); E; E = E->next()) {
-
kernings.push_back(E->key().A);
kernings.push_back(E->key().B);
kernings.push_back(E->get());
@@ -179,7 +171,6 @@ Vector<int> BitmapFont::_get_kernings() const {
}
void BitmapFont::_set_textures(const Vector<Variant> &p_textures) {
-
textures.clear();
for (int i = 0; i < p_textures.size(); i++) {
Ref<Texture2D> tex = p_textures[i];
@@ -189,10 +180,10 @@ void BitmapFont::_set_textures(const Vector<Variant> &p_textures) {
}
Vector<Variant> BitmapFont::_get_textures() const {
-
Vector<Variant> rtextures;
- for (int i = 0; i < textures.size(); i++)
+ for (int i = 0; i < textures.size(); i++) {
rtextures.push_back(textures[i]);
+ }
return rtextures;
}
@@ -207,7 +198,6 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
clear();
while (true) {
-
String line = f->get_line();
int delimiter = line.find(" ");
@@ -215,59 +205,62 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
int pos = delimiter + 1;
Map<String, String> keys;
- while (pos < line.size() && line[pos] == ' ')
+ while (pos < line.size() && line[pos] == ' ') {
pos++;
+ }
while (pos < line.size()) {
-
int eq = line.find("=", pos);
- if (eq == -1)
+ if (eq == -1) {
break;
+ }
String key = line.substr(pos, eq - pos);
int end = -1;
String value;
if (line[eq + 1] == '"') {
end = line.find("\"", eq + 2);
- if (end == -1)
+ if (end == -1) {
break;
+ }
value = line.substr(eq + 2, end - 1 - eq - 1);
pos = end + 1;
} else {
end = line.find(" ", eq + 1);
- if (end == -1)
+ if (end == -1) {
end = line.size();
+ }
value = line.substr(eq + 1, end - eq);
pos = end;
}
- while (pos < line.size() && line[pos] == ' ')
+ while (pos < line.size() && line[pos] == ' ') {
pos++;
+ }
keys[key] = value;
}
if (type == "info") {
-
- if (keys.has("face"))
+ if (keys.has("face")) {
set_name(keys["face"]);
+ }
/*
if (keys.has("size"))
font->set_height(keys["size"].to_int());
*/
} else if (type == "common") {
-
- if (keys.has("lineHeight"))
+ if (keys.has("lineHeight")) {
set_height(keys["lineHeight"].to_int());
- if (keys.has("base"))
+ }
+ if (keys.has("base")) {
set_ascent(keys["base"].to_int());
+ }
} else if (type == "page") {
-
if (keys.has("file")) {
-
String base_dir = p_file.get_base_dir();
String file = base_dir.plus_file(keys["file"]);
Ref<Texture2D> tex = ResourceLoader::load(file);
@@ -278,55 +271,66 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
}
}
} else if (type == "char") {
-
CharType idx = 0;
- if (keys.has("id"))
+ if (keys.has("id")) {
idx = keys["id"].to_int();
+ }
Rect2 rect;
- if (keys.has("x"))
+ if (keys.has("x")) {
rect.position.x = keys["x"].to_int();
- if (keys.has("y"))
+ }
+ if (keys.has("y")) {
rect.position.y = keys["y"].to_int();
- if (keys.has("width"))
+ }
+ if (keys.has("width")) {
rect.size.width = keys["width"].to_int();
- if (keys.has("height"))
+ }
+ if (keys.has("height")) {
rect.size.height = keys["height"].to_int();
+ }
Point2 ofs;
- if (keys.has("xoffset"))
+ if (keys.has("xoffset")) {
ofs.x = keys["xoffset"].to_int();
- if (keys.has("yoffset"))
+ }
+ if (keys.has("yoffset")) {
ofs.y = keys["yoffset"].to_int();
+ }
int texture = 0;
- if (keys.has("page"))
+ if (keys.has("page")) {
texture = keys["page"].to_int();
+ }
int advance = -1;
- if (keys.has("xadvance"))
+ if (keys.has("xadvance")) {
advance = keys["xadvance"].to_int();
+ }
add_char(idx, texture, rect, ofs, advance);
} else if (type == "kerning") {
-
CharType first = 0, second = 0;
int k = 0;
- if (keys.has("first"))
+ if (keys.has("first")) {
first = keys["first"].to_int();
- if (keys.has("second"))
+ }
+ if (keys.has("second")) {
second = keys["second"].to_int();
- if (keys.has("amount"))
+ }
+ if (keys.has("amount")) {
k = keys["amount"].to_int();
+ }
add_kerning_pair(first, second, -k);
}
- if (f->eof_reached())
+ if (f->eof_reached()) {
break;
+ }
}
memdelete(f);
@@ -335,57 +339,57 @@ Error BitmapFont::create_from_fnt(const String &p_file) {
}
void BitmapFont::set_height(float p_height) {
-
height = p_height;
}
-float BitmapFont::get_height() const {
+float BitmapFont::get_height() const {
return height;
}
void BitmapFont::set_ascent(float p_ascent) {
-
ascent = p_ascent;
}
-float BitmapFont::get_ascent() const {
+float BitmapFont::get_ascent() const {
return ascent;
}
-float BitmapFont::get_descent() const {
+float BitmapFont::get_descent() const {
return height - ascent;
}
-void BitmapFont::add_texture(const Ref<Texture2D> &p_texture) {
+float BitmapFont::get_underline_position() const {
+ return 2;
+}
+float BitmapFont::get_underline_thickness() const {
+ return 1;
+}
+
+void BitmapFont::add_texture(const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND_MSG(p_texture.is_null(), "It's not a reference to a valid Texture object.");
textures.push_back(p_texture);
}
int BitmapFont::get_texture_count() const {
-
return textures.size();
};
Ref<Texture2D> BitmapFont::get_texture(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, textures.size(), Ref<Texture2D>());
return textures[p_idx];
};
int BitmapFont::get_character_count() const {
-
return char_map.size();
};
Vector<CharType> BitmapFont::get_char_keys() const {
-
Vector<CharType> chars;
chars.resize(char_map.size());
const CharType *ct = nullptr;
int count = 0;
while ((ct = char_map.next(ct))) {
-
chars.write[count++] = *ct;
};
@@ -393,7 +397,6 @@ Vector<CharType> BitmapFont::get_char_keys() const {
};
BitmapFont::Character BitmapFont::get_character(CharType p_char) const {
-
if (!char_map.has(p_char)) {
ERR_FAIL_V(Character());
};
@@ -402,9 +405,9 @@ BitmapFont::Character BitmapFont::get_character(CharType p_char) const {
};
void BitmapFont::add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) {
-
- if (p_advance < 0)
+ if (p_advance < 0) {
p_advance = p_rect.size.width;
+ }
Character c;
c.rect = p_rect;
@@ -417,22 +420,18 @@ void BitmapFont::add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rec
}
void BitmapFont::add_kerning_pair(CharType p_A, CharType p_B, int p_kerning) {
-
KerningPairKey kpk;
kpk.A = p_A;
kpk.B = p_B;
if (p_kerning == 0 && kerning_map.has(kpk)) {
-
kerning_map.erase(kpk);
} else {
-
kerning_map[kpk] = p_kerning;
}
}
Vector<BitmapFont::KerningPairKey> BitmapFont::get_kerning_pair_keys() const {
-
Vector<BitmapFont::KerningPairKey> ret;
ret.resize(kerning_map.size());
int i = 0;
@@ -445,31 +444,28 @@ Vector<BitmapFont::KerningPairKey> BitmapFont::get_kerning_pair_keys() const {
}
int BitmapFont::get_kerning_pair(CharType p_A, CharType p_B) const {
-
KerningPairKey kpk;
kpk.A = p_A;
kpk.B = p_B;
const Map<KerningPairKey, int>::Element *E = kerning_map.find(kpk);
- if (E)
+ if (E) {
return E->get();
+ }
return 0;
}
void BitmapFont::set_distance_field_hint(bool p_distance_field) {
-
distance_field_hint = p_distance_field;
emit_changed();
}
bool BitmapFont::is_distance_field_hint() const {
-
return distance_field_hint;
}
void BitmapFont::clear() {
-
height = 1;
ascent = 0;
char_map.clear();
@@ -479,16 +475,15 @@ void BitmapFont::clear() {
}
Size2 Font::get_string_size(const String &p_string) const {
-
float w = 0;
int l = p_string.length();
- if (l == 0)
+ if (l == 0) {
return Size2(0, get_height());
+ }
const CharType *sptr = &p_string[0];
for (int i = 0; i < l; i++) {
-
w += get_char_size(sptr[i], sptr[i + 1]).width;
}
@@ -496,12 +491,12 @@ Size2 Font::get_string_size(const String &p_string) const {
}
Size2 Font::get_wordwrap_string_size(const String &p_string, float p_width) const {
-
ERR_FAIL_COND_V(p_width <= 0, Vector2(0, get_height()));
int l = p_string.length();
- if (l == 0)
+ if (l == 0) {
return Size2(p_width, get_height());
+ }
float line_w = 0;
float h = 0;
@@ -527,7 +522,6 @@ Size2 Font::get_wordwrap_string_size(const String &p_string, float p_width) cons
}
void BitmapFont::set_fallback(const Ref<BitmapFont> &p_fallback) {
-
for (Ref<BitmapFont> fallback_child = p_fallback; fallback_child != nullptr; fallback_child = fallback_child->get_fallback()) {
ERR_FAIL_COND_MSG(fallback_child == this, "Can't set as fallback one of its parents to prevent crashes due to recursive loop.");
}
@@ -536,17 +530,16 @@ void BitmapFont::set_fallback(const Ref<BitmapFont> &p_fallback) {
}
Ref<BitmapFont> BitmapFont::get_fallback() const {
-
return fallback;
}
float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const {
-
const Character *c = char_map.getptr(p_char);
if (!c) {
- if (fallback.is_valid())
+ if (fallback.is_valid()) {
return fallback->draw_char(p_canvas_item, p_pos, p_char, p_next, p_modulate, p_outline);
+ }
return 0;
}
@@ -563,26 +556,24 @@ float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_c
}
Size2 BitmapFont::get_char_size(CharType p_char, CharType p_next) const {
-
const Character *c = char_map.getptr(p_char);
if (!c) {
- if (fallback.is_valid())
+ if (fallback.is_valid()) {
return fallback->get_char_size(p_char, p_next);
+ }
return Size2();
}
Size2 ret(c->advance, c->rect.size.y);
if (p_next) {
-
KerningPairKey kpk;
kpk.A = p_char;
kpk.B = p_next;
const Map<KerningPairKey, int>::Element *E = kerning_map.find(kpk);
if (E) {
-
ret.width -= E->get();
}
}
@@ -591,7 +582,6 @@ Size2 BitmapFont::get_char_size(CharType p_char, CharType p_next) const {
}
void BitmapFont::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("create_from_fnt", "path"), &BitmapFont::create_from_fnt);
ClassDB::bind_method(D_METHOD("set_height", "px"), &BitmapFont::set_height);
@@ -635,21 +625,19 @@ void BitmapFont::_bind_methods() {
}
BitmapFont::BitmapFont() {
-
clear();
}
BitmapFont::~BitmapFont() {
-
clear();
}
////////////
-RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
- if (r_error)
+RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
+ }
Ref<BitmapFont> font;
font.instance();
@@ -657,8 +645,9 @@ RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_origi
Error err = font->create_from_fnt(p_path);
if (err) {
- if (r_error)
+ if (r_error) {
*r_error = err;
+ }
return RES();
}
@@ -666,19 +655,17 @@ RES ResourceFormatLoaderBMFont::load(const String &p_path, const String &p_origi
}
void ResourceFormatLoaderBMFont::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("fnt");
}
bool ResourceFormatLoaderBMFont::handles_type(const String &p_type) const {
-
return (p_type == "BitmapFont");
}
String ResourceFormatLoaderBMFont::get_resource_type(const String &p_path) const {
-
String el = p_path.get_extension().to_lower();
- if (el == "fnt")
+ if (el == "fnt") {
return "BitmapFont";
+ }
return "";
}
diff --git a/scene/resources/font.h b/scene/resources/font.h
index ce75f27e2a..14312308bb 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -36,7 +36,6 @@
#include "scene/resources/texture.h"
class Font : public Resource {
-
GDCLASS(Font, Resource);
protected:
@@ -47,6 +46,8 @@ public:
virtual float get_ascent() const = 0;
virtual float get_descent() const = 0;
+ virtual float get_underline_position() const = 0;
+ virtual float get_underline_thickness() const = 0;
virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const = 0;
Size2 get_string_size(const String &p_string) const;
@@ -104,7 +105,6 @@ public:
};
class BitmapFont : public Font {
-
GDCLASS(BitmapFont, Font);
RES_BASE_EXTENSION("font");
@@ -112,7 +112,6 @@ class BitmapFont : public Font {
public:
struct Character {
-
int texture_idx;
Rect2 rect;
float v_align;
@@ -126,7 +125,6 @@ public:
};
struct KerningPairKey {
-
union {
struct {
uint32_t A, B;
@@ -167,6 +165,8 @@ public:
void set_ascent(float p_ascent);
float get_ascent() const;
float get_descent() const;
+ float get_underline_position() const;
+ float get_underline_thickness() const;
void add_texture(const Ref<Texture2D> &p_texture);
void add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance = -1);
@@ -200,7 +200,7 @@ public:
class ResourceFormatLoaderBMFont : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp
index 7bce04beaf..d271c906ff 100644
--- a/scene/resources/gradient.cpp
+++ b/scene/resources/gradient.cpp
@@ -52,7 +52,6 @@ Gradient::~Gradient() {
}
void Gradient::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &Gradient::add_point);
ClassDB::bind_method(D_METHOD("remove_point", "offset"), &Gradient::remove_point);
@@ -104,8 +103,9 @@ void Gradient::set_offsets(const Vector<float> &p_offsets) {
}
void Gradient::set_colors(const Vector<Color> &p_colors) {
- if (points.size() < p_colors.size())
+ if (points.size() < p_colors.size()) {
is_sorted = false;
+ }
points.resize(p_colors.size());
for (int i = 0; i < points.size(); i++) {
points.write[i].color = p_colors[i];
@@ -118,7 +118,6 @@ Vector<Gradient::Point> &Gradient::get_points() {
}
void Gradient::add_point(float p_offset, const Color &p_color) {
-
Point p;
p.offset = p_offset;
p.color = p_color;
@@ -129,7 +128,6 @@ void Gradient::add_point(float p_offset, const Color &p_color) {
}
void Gradient::remove_point(int p_index) {
-
ERR_FAIL_INDEX(p_index, points.size());
ERR_FAIL_COND(points.size() <= 2);
points.remove(p_index);
@@ -143,10 +141,10 @@ void Gradient::set_points(Vector<Gradient::Point> &p_points) {
}
void Gradient::set_offset(int pos, const float offset) {
-
ERR_FAIL_COND(pos < 0);
- if (points.size() <= pos)
+ if (points.size() <= pos) {
points.resize(pos + 1);
+ }
points.write[pos].offset = offset;
is_sorted = false;
emit_signal(CoreStringNames::get_singleton()->changed);
diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h
index 2d98f799e2..d40dcc8d44 100644
--- a/scene/resources/gradient.h
+++ b/scene/resources/gradient.h
@@ -39,7 +39,6 @@ class Gradient : public Resource {
public:
struct Point {
-
float offset;
Color color;
bool operator<(const Point &p_ponit) const {
@@ -77,9 +76,9 @@ public:
Vector<Color> get_colors() const;
_FORCE_INLINE_ Color get_color_at_offset(float p_offset) {
-
- if (points.empty())
+ if (points.empty()) {
return Color(0, 0, 0, 1);
+ }
if (!is_sorted) {
points.sort();
@@ -92,8 +91,9 @@ public:
int middle = 0;
#ifdef DEBUG_ENABLED
- if (low > high)
+ if (low > high) {
ERR_PRINT("low > high, this may be a bug");
+ }
#endif
while (low <= high) {
@@ -114,13 +114,15 @@ public:
}
int first = middle;
int second = middle + 1;
- if (second >= points.size())
+ if (second >= points.size()) {
return points[points.size() - 1].color;
- if (first < 0)
+ }
+ if (first < 0) {
return points[0].color;
+ }
const Point &pointFirst = points[first];
const Point &pointSecond = points[second];
- return pointFirst.color.linear_interpolate(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset));
+ return pointFirst.color.lerp(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset));
}
int get_points_count() const;
diff --git a/scene/resources/height_map_shape_3d.cpp b/scene/resources/height_map_shape_3d.cpp
index 33b6063299..e112c6b436 100644
--- a/scene/resources/height_map_shape_3d.cpp
+++ b/scene/resources/height_map_shape_3d.cpp
@@ -35,7 +35,6 @@ Vector<Vector3> HeightMapShape3D::get_debug_mesh_lines() {
Vector<Vector3> points;
if ((map_width != 0) && (map_depth != 0)) {
-
// This will be slow for large maps...
// also we'll have to figure out how well bullet centers this shape...
@@ -81,7 +80,6 @@ real_t HeightMapShape3D::get_enclosing_radius() const {
}
void HeightMapShape3D::_update_shape() {
-
Dictionary d;
d["width"] = map_width;
d["depth"] = map_depth;
@@ -161,11 +159,13 @@ void HeightMapShape3D::set_map_data(PackedFloat32Array p_new) {
min_height = val;
max_height = val;
} else {
- if (min_height > val)
+ if (min_height > val) {
min_height = val;
+ }
- if (max_height < val)
+ if (max_height < val) {
max_height = val;
+ }
}
}
@@ -193,7 +193,6 @@ void HeightMapShape3D::_bind_methods() {
HeightMapShape3D::HeightMapShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_HEIGHTMAP)) {
-
map_width = 2;
map_depth = 2;
map_data.resize(map_width * map_depth);
diff --git a/scene/resources/line_shape_2d.cpp b/scene/resources/line_shape_2d.cpp
index a1c1b2f9f4..802ccaaee6 100644
--- a/scene/resources/line_shape_2d.cpp
+++ b/scene/resources/line_shape_2d.cpp
@@ -34,61 +34,56 @@
#include "servers/rendering_server.h"
bool LineShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
- Vector2 point = get_d() * get_normal();
+ Vector2 point = get_distance() * get_normal();
Vector2 l[2][2] = { { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 }, { point, point + get_normal() * 30 } };
for (int i = 0; i < 2; i++) {
Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, l[i]);
- if (p_point.distance_to(closest) < p_tolerance)
+ if (p_point.distance_to(closest) < p_tolerance) {
return true;
+ }
}
return false;
}
void LineShape2D::_update_shape() {
-
Array arr;
arr.push_back(normal);
- arr.push_back(d);
+ arr.push_back(distance);
PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), arr);
emit_changed();
}
void LineShape2D::set_normal(const Vector2 &p_normal) {
-
normal = p_normal;
_update_shape();
}
-void LineShape2D::set_d(real_t p_d) {
-
- d = p_d;
+void LineShape2D::set_distance(real_t p_distance) {
+ distance = p_distance;
_update_shape();
}
Vector2 LineShape2D::get_normal() const {
-
return normal;
}
-real_t LineShape2D::get_d() const {
- return d;
+real_t LineShape2D::get_distance() const {
+ return distance;
}
void LineShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
- Vector2 point = get_d() * get_normal();
+ Vector2 point = get_distance() * get_normal();
Vector2 l1[2] = { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 };
RS::get_singleton()->canvas_item_add_line(p_to_rid, l1[0], l1[1], p_color, 3);
Vector2 l2[2] = { point, point + get_normal() * 30 };
RS::get_singleton()->canvas_item_add_line(p_to_rid, l2[0], l2[1], p_color, 3);
}
-Rect2 LineShape2D::get_rect() const {
- Vector2 point = get_d() * get_normal();
+Rect2 LineShape2D::get_rect() const {
+ Vector2 point = get_distance() * get_normal();
Vector2 l1[2] = { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 };
Vector2 l2[2] = { point, point + get_normal() * 30 };
@@ -101,25 +96,23 @@ Rect2 LineShape2D::get_rect() const {
}
real_t LineShape2D::get_enclosing_radius() const {
- return d;
+ return distance;
}
void LineShape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_normal", "normal"), &LineShape2D::set_normal);
ClassDB::bind_method(D_METHOD("get_normal"), &LineShape2D::get_normal);
- ClassDB::bind_method(D_METHOD("set_d", "d"), &LineShape2D::set_d);
- ClassDB::bind_method(D_METHOD("get_d"), &LineShape2D::get_d);
+ ClassDB::bind_method(D_METHOD("set_distance", "distance"), &LineShape2D::set_distance);
+ ClassDB::bind_method(D_METHOD("get_distance"), &LineShape2D::get_distance);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "normal"), "set_normal", "get_normal");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "d"), "set_d", "get_d");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "distance"), "set_distance", "get_distance");
}
LineShape2D::LineShape2D() :
Shape2D(PhysicsServer2D::get_singleton()->line_shape_create()) {
-
normal = Vector2(0, 1);
- d = 0;
+ distance = 0;
_update_shape();
}
diff --git a/scene/resources/line_shape_2d.h b/scene/resources/line_shape_2d.h
index 5bf9e85bb9..74e8d57d03 100644
--- a/scene/resources/line_shape_2d.h
+++ b/scene/resources/line_shape_2d.h
@@ -37,7 +37,7 @@ class LineShape2D : public Shape2D {
GDCLASS(LineShape2D, Shape2D);
Vector2 normal;
- real_t d;
+ real_t distance;
void _update_shape();
@@ -48,10 +48,10 @@ public:
virtual bool _edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const;
void set_normal(const Vector2 &p_normal);
- void set_d(real_t p_d);
+ void set_distance(real_t p_distance);
Vector2 get_normal() const;
- real_t get_d() const;
+ real_t get_distance() const;
virtual void draw(const RID &p_to_rid, const Color &p_color);
virtual Rect2 get_rect() const;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index fd8cff7cd0..1e95a35726 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -39,28 +39,27 @@
#include "scene/scene_string_names.h"
void Material::set_next_pass(const Ref<Material> &p_pass) {
-
for (Ref<Material> pass_child = p_pass; pass_child != nullptr; pass_child = pass_child->get_next_pass()) {
ERR_FAIL_COND_MSG(pass_child == this, "Can't set as next_pass one of its parents to prevent crashes due to recursive loop.");
}
- if (next_pass == p_pass)
+ if (next_pass == p_pass) {
return;
+ }
next_pass = p_pass;
RID next_pass_rid;
- if (next_pass.is_valid())
+ if (next_pass.is_valid()) {
next_pass_rid = next_pass->get_rid();
+ }
RS::get_singleton()->material_set_next_pass(material, next_pass_rid);
}
Ref<Material> Material::get_next_pass() const {
-
return next_pass;
}
void Material::set_render_priority(int p_priority) {
-
ERR_FAIL_COND(p_priority < RENDER_PRIORITY_MIN);
ERR_FAIL_COND(p_priority > RENDER_PRIORITY_MAX);
render_priority = p_priority;
@@ -68,23 +67,20 @@ void Material::set_render_priority(int p_priority) {
}
int Material::get_render_priority() const {
-
return render_priority;
}
RID Material::get_rid() const {
-
return material;
}
-void Material::_validate_property(PropertyInfo &property) const {
+void Material::_validate_property(PropertyInfo &property) const {
if (!_can_do_next_pass() && property.name == "next_pass") {
property.usage = 0;
}
}
void Material::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_next_pass", "next_pass"), &Material::set_next_pass);
ClassDB::bind_method(D_METHOD("get_next_pass"), &Material::get_next_pass);
@@ -99,22 +95,18 @@ void Material::_bind_methods() {
}
Material::Material() {
-
material = RenderingServer::get_singleton()->material_create();
render_priority = 0;
}
Material::~Material() {
-
RenderingServer::get_singleton()->free(material);
}
///////////////////////////////////
bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
-
if (shader.is_valid()) {
-
StringName pr = shader->remap_param(p_name);
if (!pr) {
String n = p_name;
@@ -135,9 +127,7 @@ bool ShaderMaterial::_set(const StringName &p_name, const Variant &p_value) {
}
bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
-
if (shader.is_valid()) {
-
StringName pr = shader->remap_param(p_name);
if (!pr) {
String n = p_name;
@@ -159,16 +149,13 @@ bool ShaderMaterial::_get(const StringName &p_name, Variant &r_ret) const {
}
void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
-
if (!shader.is_null()) {
-
shader->get_param_list(p_list);
}
}
bool ShaderMaterial::property_can_revert(const String &p_name) {
if (shader.is_valid()) {
-
StringName pr = shader->remap_param(p_name);
if (pr) {
Variant default_value = RenderingServer::get_singleton()->shader_get_param_default(shader->get_rid(), pr);
@@ -192,7 +179,6 @@ Variant ShaderMaterial::property_get_revert(const String &p_name) {
}
void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) {
-
// Only connect/disconnect the signal when running in the editor.
// This can be a slow operation, and `_change_notify()` (which is called by `_shader_changed()`)
// does nothing in non-editor builds anyway. See GH-34741 for details.
@@ -217,17 +203,14 @@ void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) {
}
Ref<Shader> ShaderMaterial::get_shader() const {
-
return shader;
}
void ShaderMaterial::set_shader_param(const StringName &p_param, const Variant &p_value) {
-
RS::get_singleton()->material_set_param(_get_material(), p_param, p_value);
}
Variant ShaderMaterial::get_shader_param(const StringName &p_param) const {
-
return RS::get_singleton()->material_get_param(_get_material(), p_param);
}
@@ -236,7 +219,6 @@ void ShaderMaterial::_shader_changed() {
}
void ShaderMaterial::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_shader", "shader"), &ShaderMaterial::set_shader);
ClassDB::bind_method(D_METHOD("get_shader"), &ShaderMaterial::get_shader);
ClassDB::bind_method(D_METHOD("set_shader_param", "param", "value"), &ShaderMaterial::set_shader_param);
@@ -248,7 +230,6 @@ void ShaderMaterial::_bind_methods() {
}
void ShaderMaterial::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const {
-
#ifdef TOOLS_ENABLED
const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", 0) ? "'" : "\"";
#else
@@ -257,7 +238,6 @@ void ShaderMaterial::get_argument_options(const StringName &p_function, int p_id
String f = p_function.operator String();
if ((f == "get_shader_param" || f == "set_shader_param") && p_idx == 0) {
-
if (shader.is_valid()) {
List<PropertyInfo> pl;
shader->get_param_list(&pl);
@@ -270,15 +250,15 @@ void ShaderMaterial::get_argument_options(const StringName &p_function, int p_id
}
bool ShaderMaterial::_can_do_next_pass() const {
-
return shader.is_valid() && shader->get_mode() == Shader::MODE_SPATIAL;
}
Shader::Mode ShaderMaterial::get_shader_mode() const {
- if (shader.is_valid())
+ if (shader.is_valid()) {
return shader->get_mode();
- else
+ } else {
return Shader::MODE_SPATIAL;
+ }
}
ShaderMaterial::ShaderMaterial() {
@@ -295,7 +275,6 @@ Map<BaseMaterial3D::MaterialKey, BaseMaterial3D::ShaderData> BaseMaterial3D::sha
BaseMaterial3D::ShaderNames *BaseMaterial3D::shader_names = nullptr;
void BaseMaterial3D::init_shaders() {
-
dirty_materials = memnew(SelfList<BaseMaterial3D>::List);
shader_names = memnew(ShaderNames);
@@ -375,7 +354,6 @@ void BaseMaterial3D::init_shaders() {
Ref<StandardMaterial3D> BaseMaterial3D::materials_for_2d[BaseMaterial3D::MAX_MATERIALS_FOR_2D];
void BaseMaterial3D::finish_shaders() {
-
for (int i = 0; i < MAX_MATERIALS_FOR_2D; i++) {
materials_for_2d[i].unref();
}
@@ -387,12 +365,12 @@ void BaseMaterial3D::finish_shaders() {
}
void BaseMaterial3D::_update_shader() {
-
dirty_materials->remove(&element);
MaterialKey mk = _compute_key();
- if (mk == current_key)
+ if (mk == current_key) {
return; //no update required in the end
+ }
if (shader_map.has(current_key)) {
shader_map[current_key].users--;
@@ -406,7 +384,6 @@ void BaseMaterial3D::_update_shader() {
current_key = mk;
if (shader_map.has(mk)) {
-
RS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader);
shader_map[mk].users++;
return;
@@ -414,13 +391,26 @@ void BaseMaterial3D::_update_shader() {
String texfilter_str;
switch (texture_filter) {
- case TEXTURE_FILTER_NEAREST: texfilter_str = "filter_nearest"; break;
- case TEXTURE_FILTER_LINEAR: texfilter_str = "filter_linear"; break;
- case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS: texfilter_str = "filter_nearest_mipmap"; break;
- case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS: texfilter_str = "filter_linear_mipmap"; break;
- case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC: texfilter_str = "filter_nearest_mipmap_aniso"; break;
- case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: texfilter_str = "filter_linear_mipmap_aniso"; break;
- case TEXTURE_FILTER_MAX: break; // Internal value, skip.
+ case TEXTURE_FILTER_NEAREST:
+ texfilter_str = "filter_nearest";
+ break;
+ case TEXTURE_FILTER_LINEAR:
+ texfilter_str = "filter_linear";
+ break;
+ case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS:
+ texfilter_str = "filter_nearest_mipmap";
+ break;
+ case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS:
+ texfilter_str = "filter_linear_mipmap";
+ break;
+ case TEXTURE_FILTER_NEAREST_WITH_MIPMAPS_ANISOTROPIC:
+ texfilter_str = "filter_nearest_mipmap_aniso";
+ break;
+ case TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC:
+ texfilter_str = "filter_linear_mipmap_aniso";
+ break;
+ case TEXTURE_FILTER_MAX:
+ break; // Internal value, skip.
}
if (flags[FLAG_USE_TEXTURE_REPEAT]) {
@@ -433,10 +423,18 @@ void BaseMaterial3D::_update_shader() {
String code = "shader_type spatial;\nrender_mode ";
switch (blend_mode) {
- case BLEND_MODE_MIX: code += "blend_mix"; break;
- case BLEND_MODE_ADD: code += "blend_add"; break;
- case BLEND_MODE_SUB: code += "blend_sub"; break;
- case BLEND_MODE_MUL: code += "blend_mul"; break;
+ case BLEND_MODE_MIX:
+ code += "blend_mix";
+ break;
+ case BLEND_MODE_ADD:
+ code += "blend_add";
+ break;
+ case BLEND_MODE_SUB:
+ code += "blend_sub";
+ break;
+ case BLEND_MODE_MUL:
+ code += "blend_mul";
+ break;
}
DepthDrawMode ddm = depth_draw_mode;
@@ -445,9 +443,15 @@ void BaseMaterial3D::_update_shader() {
}
switch (ddm) {
- case DEPTH_DRAW_OPAQUE_ONLY: code += ",depth_draw_opaque"; break;
- case DEPTH_DRAW_ALWAYS: code += ",depth_draw_always"; break;
- case DEPTH_DRAW_DISABLED: code += ",depth_draw_never"; break;
+ case DEPTH_DRAW_OPAQUE_ONLY:
+ code += ",depth_draw_opaque";
+ break;
+ case DEPTH_DRAW_ALWAYS:
+ code += ",depth_draw_always";
+ break;
+ case DEPTH_DRAW_DISABLED:
+ code += ",depth_draw_never";
+ break;
}
if (transparency == TRANSPARENCY_ALPHA_DEPTH_PRE_PASS) {
@@ -455,23 +459,49 @@ void BaseMaterial3D::_update_shader() {
}
switch (cull_mode) {
- case CULL_BACK: code += ",cull_back"; break;
- case CULL_FRONT: code += ",cull_front"; break;
- case CULL_DISABLED: code += ",cull_disabled"; break;
+ case CULL_BACK:
+ code += ",cull_back";
+ break;
+ case CULL_FRONT:
+ code += ",cull_front";
+ break;
+ case CULL_DISABLED:
+ code += ",cull_disabled";
+ break;
}
switch (diffuse_mode) {
- case DIFFUSE_BURLEY: code += ",diffuse_burley"; break;
- case DIFFUSE_LAMBERT: code += ",diffuse_lambert"; break;
- case DIFFUSE_LAMBERT_WRAP: code += ",diffuse_lambert_wrap"; break;
- case DIFFUSE_OREN_NAYAR: code += ",diffuse_oren_nayar"; break;
- case DIFFUSE_TOON: code += ",diffuse_toon"; break;
+ case DIFFUSE_BURLEY:
+ code += ",diffuse_burley";
+ break;
+ case DIFFUSE_LAMBERT:
+ code += ",diffuse_lambert";
+ break;
+ case DIFFUSE_LAMBERT_WRAP:
+ code += ",diffuse_lambert_wrap";
+ break;
+ case DIFFUSE_OREN_NAYAR:
+ code += ",diffuse_oren_nayar";
+ break;
+ case DIFFUSE_TOON:
+ code += ",diffuse_toon";
+ break;
}
switch (specular_mode) {
- case SPECULAR_SCHLICK_GGX: code += ",specular_schlick_ggx"; break;
- case SPECULAR_BLINN: code += ",specular_blinn"; break;
- case SPECULAR_PHONG: code += ",specular_phong"; break;
- case SPECULAR_TOON: code += ",specular_toon"; break;
- case SPECULAR_DISABLED: code += ",specular_disabled"; break;
+ case SPECULAR_SCHLICK_GGX:
+ code += ",specular_schlick_ggx";
+ break;
+ case SPECULAR_BLINN:
+ code += ",specular_blinn";
+ break;
+ case SPECULAR_PHONG:
+ code += ",specular_phong";
+ break;
+ case SPECULAR_TOON:
+ code += ",specular_toon";
+ break;
+ case SPECULAR_DISABLED:
+ code += ",specular_disabled";
+ break;
}
if (features[FEATURE_SUBSURFACE_SCATTERING] && flags[FLAG_SUBSURFACE_MODE_SKIN]) {
code += ",sss_mode_skin";
@@ -553,7 +583,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_EMISSION]) {
-
code += "uniform sampler2D texture_emission : hint_black_albedo," + texfilter_str + ";\n";
code += "uniform vec4 emission : hint_color;\n";
code += "uniform float emission_energy;\n";
@@ -596,13 +625,11 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_SUBSURFACE_SCATTERING]) {
-
code += "uniform float subsurface_scattering_strength : hint_range(0,1);\n";
code += "uniform sampler2D texture_subsurface_scattering : hint_white," + texfilter_str + ";\n";
}
if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) {
-
code += "uniform vec4 transmittance_color : hint_color;\n";
code += "uniform float transmittance_depth;\n";
code += "uniform sampler2D texture_subsurface_transmittance : hint_white," + texfilter_str + ";\n";
@@ -611,7 +638,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_BACKLIGHT]) {
-
code += "uniform vec4 backlight : hint_color;\n";
code += "uniform sampler2D texture_backlight : hint_black," + texfilter_str + ";\n";
}
@@ -649,18 +675,15 @@ void BaseMaterial3D::_update_shader() {
code += "void vertex() {\n";
if (flags[FLAG_SRGB_VERTEX_COLOR]) {
-
code += "\tif (!OUTPUT_IS_SRGB) {\n";
code += "\t\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n";
code += "\t}\n";
}
if (flags[FLAG_USE_POINT_SIZE]) {
-
code += "\tPOINT_SIZE=point_size;\n";
}
if (shading_mode == SHADING_MODE_PER_VERTEX) {
-
code += "\tROUGHNESS=roughness;\n";
}
@@ -670,10 +693,8 @@ void BaseMaterial3D::_update_shader() {
switch (billboard_mode) {
case BILLBOARD_DISABLED: {
-
} break;
case BILLBOARD_ENABLED: {
-
code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],CAMERA_MATRIX[1],CAMERA_MATRIX[2],WORLD_MATRIX[3]);\n";
if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
@@ -681,7 +702,6 @@ void BaseMaterial3D::_update_shader() {
}
} break;
case BILLBOARD_FIXED_Y: {
-
code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat4(CAMERA_MATRIX[0],WORLD_MATRIX[1],vec4(normalize(cross(CAMERA_MATRIX[0].xyz,WORLD_MATRIX[1].xyz)), 0.0),WORLD_MATRIX[3]);\n";
if (flags[FLAG_BILLBOARD_KEEP_SCALE]) {
@@ -691,7 +711,6 @@ void BaseMaterial3D::_update_shader() {
}
} break;
case BILLBOARD_PARTICLES: {
-
//make billboard
code += "\tmat4 mat_world = mat4(normalize(CAMERA_MATRIX[0])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[1])*length(WORLD_MATRIX[0]),normalize(CAMERA_MATRIX[2])*length(WORLD_MATRIX[2]),WORLD_MATRIX[3]);\n";
//rotate by rotation
@@ -715,7 +734,6 @@ void BaseMaterial3D::_update_shader() {
}
if (flags[FLAG_FIXED_SIZE]) {
-
code += "\tif (PROJECTION_MATRIX[3][3] != 0.0) {\n";
//orthogonal matrix, try to do about the same
//with viewport size
@@ -750,7 +768,6 @@ void BaseMaterial3D::_update_shader() {
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
-
code += "\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n";
code += "\tuv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n";
code += "\tuv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n";
@@ -758,7 +775,6 @@ void BaseMaterial3D::_update_shader() {
}
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
-
code += "\tuv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n";
code += "\tuv2_power_normal/=dot(uv2_power_normal,vec3(1.0));\n";
code += "\tuv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n";
@@ -939,7 +955,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_REFRACTION]) {
-
if (features[FEATURE_NORMAL_MAPPING]) {
code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMALMAP.x + BINORMAL * NORMALMAP.y + NORMAL * NORMALMAP.z,NORMALMAP_DEPTH) );\n";
} else {
@@ -970,7 +985,6 @@ void BaseMaterial3D::_update_shader() {
if (distance_fade != DISTANCE_FADE_DISABLED) {
if ((distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER)) {
-
if (!RenderingServer::get_singleton()->is_low_end()) {
code += "\t{\n";
if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) {
@@ -1044,7 +1058,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_AMBIENT_OCCLUSION]) {
-
if (!orm) {
if (flags[FLAG_AO_ON_UV2]) {
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
@@ -1067,7 +1080,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_SUBSURFACE_SCATTERING]) {
-
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tfloat sss_tex = triplanar_texture(texture_subsurface_scattering,uv1_power_normal,uv1_triplanar_pos).r;\n";
} else {
@@ -1077,7 +1089,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_SUBSURFACE_TRANSMITTANCE]) {
-
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
code += "\tvec4 trans_color_tex = triplanar_texture(texture_subsurface_transmittance,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
@@ -1100,7 +1111,6 @@ void BaseMaterial3D::_update_shader() {
}
if (features[FEATURE_DETAIL]) {
-
bool triplanar = (flags[FLAG_UV1_USE_TRIPLANAR] && detail_uv == DETAIL_UV_1) || (flags[FLAG_UV2_USE_TRIPLANAR] && detail_uv == DETAIL_UV_2);
if (triplanar) {
@@ -1115,7 +1125,6 @@ void BaseMaterial3D::_update_shader() {
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
-
code += "\tvec4 detail_mask_tex = triplanar_texture(texture_detail_mask,uv1_power_normal,uv1_triplanar_pos);\n";
} else {
code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n";
@@ -1155,17 +1164,14 @@ void BaseMaterial3D::_update_shader() {
}
void BaseMaterial3D::flush_changes() {
-
MutexLock lock(material_mutex);
while (dirty_materials->first()) {
-
dirty_materials->first()->self()->_update_shader();
}
}
void BaseMaterial3D::_queue_shader_change() {
-
MutexLock lock(material_mutex);
if (!element.in_list()) {
@@ -1174,167 +1180,144 @@ void BaseMaterial3D::_queue_shader_change() {
}
bool BaseMaterial3D::_is_shader_dirty() const {
-
MutexLock lock(material_mutex);
return element.in_list();
}
-void BaseMaterial3D::set_albedo(const Color &p_albedo) {
+void BaseMaterial3D::set_albedo(const Color &p_albedo) {
albedo = p_albedo;
RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo, p_albedo);
}
Color BaseMaterial3D::get_albedo() const {
-
return albedo;
}
void BaseMaterial3D::set_specular(float p_specular) {
-
specular = p_specular;
RS::get_singleton()->material_set_param(_get_material(), shader_names->specular, p_specular);
}
float BaseMaterial3D::get_specular() const {
-
return specular;
}
void BaseMaterial3D::set_roughness(float p_roughness) {
-
roughness = p_roughness;
RS::get_singleton()->material_set_param(_get_material(), shader_names->roughness, p_roughness);
}
float BaseMaterial3D::get_roughness() const {
-
return roughness;
}
void BaseMaterial3D::set_metallic(float p_metallic) {
-
metallic = p_metallic;
RS::get_singleton()->material_set_param(_get_material(), shader_names->metallic, p_metallic);
}
float BaseMaterial3D::get_metallic() const {
-
return metallic;
}
void BaseMaterial3D::set_emission(const Color &p_emission) {
-
emission = p_emission;
RS::get_singleton()->material_set_param(_get_material(), shader_names->emission, p_emission);
}
-Color BaseMaterial3D::get_emission() const {
+Color BaseMaterial3D::get_emission() const {
return emission;
}
void BaseMaterial3D::set_emission_energy(float p_emission_energy) {
-
emission_energy = p_emission_energy;
RS::get_singleton()->material_set_param(_get_material(), shader_names->emission_energy, p_emission_energy);
}
-float BaseMaterial3D::get_emission_energy() const {
+float BaseMaterial3D::get_emission_energy() const {
return emission_energy;
}
void BaseMaterial3D::set_normal_scale(float p_normal_scale) {
-
normal_scale = p_normal_scale;
RS::get_singleton()->material_set_param(_get_material(), shader_names->normal_scale, p_normal_scale);
}
-float BaseMaterial3D::get_normal_scale() const {
+float BaseMaterial3D::get_normal_scale() const {
return normal_scale;
}
void BaseMaterial3D::set_rim(float p_rim) {
-
rim = p_rim;
RS::get_singleton()->material_set_param(_get_material(), shader_names->rim, p_rim);
}
-float BaseMaterial3D::get_rim() const {
+float BaseMaterial3D::get_rim() const {
return rim;
}
void BaseMaterial3D::set_rim_tint(float p_rim_tint) {
-
rim_tint = p_rim_tint;
RS::get_singleton()->material_set_param(_get_material(), shader_names->rim_tint, p_rim_tint);
}
-float BaseMaterial3D::get_rim_tint() const {
+float BaseMaterial3D::get_rim_tint() const {
return rim_tint;
}
void BaseMaterial3D::set_ao_light_affect(float p_ao_light_affect) {
-
ao_light_affect = p_ao_light_affect;
RS::get_singleton()->material_set_param(_get_material(), shader_names->ao_light_affect, p_ao_light_affect);
}
-float BaseMaterial3D::get_ao_light_affect() const {
+float BaseMaterial3D::get_ao_light_affect() const {
return ao_light_affect;
}
void BaseMaterial3D::set_clearcoat(float p_clearcoat) {
-
clearcoat = p_clearcoat;
RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat, p_clearcoat);
}
float BaseMaterial3D::get_clearcoat() const {
-
return clearcoat;
}
void BaseMaterial3D::set_clearcoat_gloss(float p_clearcoat_gloss) {
-
clearcoat_gloss = p_clearcoat_gloss;
RS::get_singleton()->material_set_param(_get_material(), shader_names->clearcoat_gloss, p_clearcoat_gloss);
}
float BaseMaterial3D::get_clearcoat_gloss() const {
-
return clearcoat_gloss;
}
void BaseMaterial3D::set_anisotropy(float p_anisotropy) {
-
anisotropy = p_anisotropy;
RS::get_singleton()->material_set_param(_get_material(), shader_names->anisotropy, p_anisotropy);
}
-float BaseMaterial3D::get_anisotropy() const {
+float BaseMaterial3D::get_anisotropy() const {
return anisotropy;
}
void BaseMaterial3D::set_heightmap_scale(float p_heightmap_scale) {
-
heightmap_scale = p_heightmap_scale;
RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_scale, p_heightmap_scale);
}
float BaseMaterial3D::get_heightmap_scale() const {
-
return heightmap_scale;
}
void BaseMaterial3D::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) {
-
subsurface_scattering_strength = p_subsurface_scattering_strength;
RS::get_singleton()->material_set_param(_get_material(), shader_names->subsurface_scattering_strength, subsurface_scattering_strength);
}
float BaseMaterial3D::get_subsurface_scattering_strength() const {
-
return subsurface_scattering_strength;
}
@@ -1351,6 +1334,7 @@ void BaseMaterial3D::set_transmittance_depth(float p_depth) {
transmittance_depth = p_depth;
RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_depth, p_depth);
}
+
float BaseMaterial3D::get_transmittance_depth() const {
return transmittance_depth;
}
@@ -1359,6 +1343,7 @@ void BaseMaterial3D::set_transmittance_curve(float p_curve) {
transmittance_curve = p_curve;
RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_curve, p_curve);
}
+
float BaseMaterial3D::get_transmittance_curve() const {
return transmittance_curve;
}
@@ -1367,70 +1352,65 @@ void BaseMaterial3D::set_transmittance_boost(float p_boost) {
transmittance_boost = p_boost;
RS::get_singleton()->material_set_param(_get_material(), shader_names->transmittance_boost, p_boost);
}
+
float BaseMaterial3D::get_transmittance_boost() const {
return transmittance_boost;
}
void BaseMaterial3D::set_backlight(const Color &p_backlight) {
-
backlight = p_backlight;
RS::get_singleton()->material_set_param(_get_material(), shader_names->backlight, backlight);
}
Color BaseMaterial3D::get_backlight() const {
-
return backlight;
}
void BaseMaterial3D::set_refraction(float p_refraction) {
-
refraction = p_refraction;
RS::get_singleton()->material_set_param(_get_material(), shader_names->refraction, refraction);
}
float BaseMaterial3D::get_refraction() const {
-
return refraction;
}
void BaseMaterial3D::set_detail_uv(DetailUV p_detail_uv) {
-
- if (detail_uv == p_detail_uv)
+ if (detail_uv == p_detail_uv) {
return;
+ }
detail_uv = p_detail_uv;
_queue_shader_change();
}
-BaseMaterial3D::DetailUV BaseMaterial3D::get_detail_uv() const {
+BaseMaterial3D::DetailUV BaseMaterial3D::get_detail_uv() const {
return detail_uv;
}
void BaseMaterial3D::set_blend_mode(BlendMode p_mode) {
-
- if (blend_mode == p_mode)
+ if (blend_mode == p_mode) {
return;
+ }
blend_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const {
+BaseMaterial3D::BlendMode BaseMaterial3D::get_blend_mode() const {
return blend_mode;
}
void BaseMaterial3D::set_detail_blend_mode(BlendMode p_mode) {
-
detail_blend_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::BlendMode BaseMaterial3D::get_detail_blend_mode() const {
+BaseMaterial3D::BlendMode BaseMaterial3D::get_detail_blend_mode() const {
return detail_blend_mode;
}
void BaseMaterial3D::set_transparency(Transparency p_transparency) {
-
if (transparency == p_transparency) {
return;
}
@@ -1445,7 +1425,6 @@ BaseMaterial3D::Transparency BaseMaterial3D::get_transparency() const {
}
void BaseMaterial3D::set_shading_mode(ShadingMode p_shading_mode) {
-
if (shading_mode == p_shading_mode) {
return;
}
@@ -1460,63 +1439,63 @@ BaseMaterial3D::ShadingMode BaseMaterial3D::get_shading_mode() const {
}
void BaseMaterial3D::set_depth_draw_mode(DepthDrawMode p_mode) {
-
- if (depth_draw_mode == p_mode)
+ if (depth_draw_mode == p_mode) {
return;
+ }
depth_draw_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::DepthDrawMode BaseMaterial3D::get_depth_draw_mode() const {
+BaseMaterial3D::DepthDrawMode BaseMaterial3D::get_depth_draw_mode() const {
return depth_draw_mode;
}
void BaseMaterial3D::set_cull_mode(CullMode p_mode) {
-
- if (cull_mode == p_mode)
+ if (cull_mode == p_mode) {
return;
+ }
cull_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::CullMode BaseMaterial3D::get_cull_mode() const {
+BaseMaterial3D::CullMode BaseMaterial3D::get_cull_mode() const {
return cull_mode;
}
void BaseMaterial3D::set_diffuse_mode(DiffuseMode p_mode) {
-
- if (diffuse_mode == p_mode)
+ if (diffuse_mode == p_mode) {
return;
+ }
diffuse_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::DiffuseMode BaseMaterial3D::get_diffuse_mode() const {
+BaseMaterial3D::DiffuseMode BaseMaterial3D::get_diffuse_mode() const {
return diffuse_mode;
}
void BaseMaterial3D::set_specular_mode(SpecularMode p_mode) {
-
- if (specular_mode == p_mode)
+ if (specular_mode == p_mode) {
return;
+ }
specular_mode = p_mode;
_queue_shader_change();
}
-BaseMaterial3D::SpecularMode BaseMaterial3D::get_specular_mode() const {
+BaseMaterial3D::SpecularMode BaseMaterial3D::get_specular_mode() const {
return specular_mode;
}
void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
-
ERR_FAIL_INDEX(p_flag, FLAG_MAX);
- if (flags[p_flag] == p_enabled)
+ if (flags[p_flag] == p_enabled) {
return;
+ }
flags[p_flag] = p_enabled;
if (p_flag == FLAG_USE_SHADOW_TO_OPACITY || p_flag == FLAG_USE_TEXTURE_REPEAT || p_flag == FLAG_SUBSURFACE_MODE_SKIN) {
@@ -1526,16 +1505,15 @@ void BaseMaterial3D::set_flag(Flags p_flag, bool p_enabled) {
}
bool BaseMaterial3D::get_flag(Flags p_flag) const {
-
ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false);
return flags[p_flag];
}
void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) {
-
ERR_FAIL_INDEX(p_feature, FEATURE_MAX);
- if (features[p_feature] == p_enabled)
+ if (features[p_feature] == p_enabled) {
return;
+ }
features[p_feature] = p_enabled;
_change_notify();
@@ -1543,13 +1521,11 @@ void BaseMaterial3D::set_feature(Feature p_feature, bool p_enabled) {
}
bool BaseMaterial3D::get_feature(Feature p_feature) const {
-
ERR_FAIL_INDEX_V(p_feature, FEATURE_MAX, false);
return features[p_feature];
}
void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) {
-
ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
textures[p_param] = p_texture;
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
@@ -1559,7 +1535,6 @@ void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_t
}
Ref<Texture2D> BaseMaterial3D::get_texture(TextureParam p_param) const {
-
ERR_FAIL_INDEX_V(p_param, TEXTURE_MAX, Ref<Texture2D>());
return textures[p_param];
}
@@ -1567,8 +1542,9 @@ Ref<Texture2D> BaseMaterial3D::get_texture(TextureParam p_param) const {
Ref<Texture2D> BaseMaterial3D::get_texture_by_name(StringName p_name) const {
for (int i = 0; i < (int)BaseMaterial3D::TEXTURE_MAX; i++) {
TextureParam param = TextureParam(i);
- if (p_name == shader_names->texture_names[param])
+ if (p_name == shader_names->texture_names[param]) {
return textures[param];
+ }
}
return Ref<Texture2D>();
}
@@ -1642,7 +1618,6 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
}
if (orm) {
-
if (property.name == "shading_mode") {
property.hint_string = "Unshaded,PerPixel"; //vertex not supported in ORM mode, since no individual roughness.
}
@@ -1657,9 +1632,7 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
}
if (shading_mode != SHADING_MODE_PER_PIXEL) {
-
if (shading_mode != SHADING_MODE_PER_VERTEX) {
-
//these may still work per vertex
if (property.name.begins_with("ao")) {
property.usage = 0;
@@ -1708,176 +1681,148 @@ void BaseMaterial3D::_validate_property(PropertyInfo &property) const {
}
void BaseMaterial3D::set_point_size(float p_point_size) {
-
point_size = p_point_size;
RS::get_singleton()->material_set_param(_get_material(), shader_names->point_size, p_point_size);
}
float BaseMaterial3D::get_point_size() const {
-
return point_size;
}
void BaseMaterial3D::set_uv1_scale(const Vector3 &p_scale) {
-
uv1_scale = p_scale;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_scale, p_scale);
}
Vector3 BaseMaterial3D::get_uv1_scale() const {
-
return uv1_scale;
}
void BaseMaterial3D::set_uv1_offset(const Vector3 &p_offset) {
-
uv1_offset = p_offset;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_offset, p_offset);
}
-Vector3 BaseMaterial3D::get_uv1_offset() const {
+Vector3 BaseMaterial3D::get_uv1_offset() const {
return uv1_offset;
}
void BaseMaterial3D::set_uv1_triplanar_blend_sharpness(float p_sharpness) {
-
uv1_triplanar_sharpness = p_sharpness;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv1_blend_sharpness, p_sharpness);
}
float BaseMaterial3D::get_uv1_triplanar_blend_sharpness() const {
-
return uv1_triplanar_sharpness;
}
void BaseMaterial3D::set_uv2_scale(const Vector3 &p_scale) {
-
uv2_scale = p_scale;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_scale, p_scale);
}
Vector3 BaseMaterial3D::get_uv2_scale() const {
-
return uv2_scale;
}
void BaseMaterial3D::set_uv2_offset(const Vector3 &p_offset) {
-
uv2_offset = p_offset;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_offset, p_offset);
}
Vector3 BaseMaterial3D::get_uv2_offset() const {
-
return uv2_offset;
}
void BaseMaterial3D::set_uv2_triplanar_blend_sharpness(float p_sharpness) {
-
uv2_triplanar_sharpness = p_sharpness;
RS::get_singleton()->material_set_param(_get_material(), shader_names->uv2_blend_sharpness, p_sharpness);
}
float BaseMaterial3D::get_uv2_triplanar_blend_sharpness() const {
-
return uv2_triplanar_sharpness;
}
void BaseMaterial3D::set_billboard_mode(BillboardMode p_mode) {
-
billboard_mode = p_mode;
_queue_shader_change();
_change_notify();
}
BaseMaterial3D::BillboardMode BaseMaterial3D::get_billboard_mode() const {
-
return billboard_mode;
}
void BaseMaterial3D::set_particles_anim_h_frames(int p_frames) {
-
particles_anim_h_frames = p_frames;
RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_h_frames, p_frames);
}
int BaseMaterial3D::get_particles_anim_h_frames() const {
-
return particles_anim_h_frames;
}
-void BaseMaterial3D::set_particles_anim_v_frames(int p_frames) {
+void BaseMaterial3D::set_particles_anim_v_frames(int p_frames) {
particles_anim_v_frames = p_frames;
RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_v_frames, p_frames);
}
int BaseMaterial3D::get_particles_anim_v_frames() const {
-
return particles_anim_v_frames;
}
void BaseMaterial3D::set_particles_anim_loop(bool p_loop) {
-
particles_anim_loop = p_loop;
RS::get_singleton()->material_set_param(_get_material(), shader_names->particles_anim_loop, particles_anim_loop);
}
bool BaseMaterial3D::get_particles_anim_loop() const {
-
return particles_anim_loop;
}
void BaseMaterial3D::set_heightmap_deep_parallax(bool p_enable) {
-
deep_parallax = p_enable;
_queue_shader_change();
_change_notify();
}
bool BaseMaterial3D::is_heightmap_deep_parallax_enabled() const {
-
return deep_parallax;
}
void BaseMaterial3D::set_heightmap_deep_parallax_min_layers(int p_layer) {
-
deep_parallax_min_layers = p_layer;
RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_min_layers, p_layer);
}
-int BaseMaterial3D::get_heightmap_deep_parallax_min_layers() const {
+int BaseMaterial3D::get_heightmap_deep_parallax_min_layers() const {
return deep_parallax_min_layers;
}
void BaseMaterial3D::set_heightmap_deep_parallax_max_layers(int p_layer) {
-
deep_parallax_max_layers = p_layer;
RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_max_layers, p_layer);
}
-int BaseMaterial3D::get_heightmap_deep_parallax_max_layers() const {
+int BaseMaterial3D::get_heightmap_deep_parallax_max_layers() const {
return deep_parallax_max_layers;
}
void BaseMaterial3D::set_heightmap_deep_parallax_flip_tangent(bool p_flip) {
-
heightmap_parallax_flip_tangent = p_flip;
RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
}
bool BaseMaterial3D::get_heightmap_deep_parallax_flip_tangent() const {
-
return heightmap_parallax_flip_tangent;
}
void BaseMaterial3D::set_heightmap_deep_parallax_flip_binormal(bool p_flip) {
-
heightmap_parallax_flip_binormal = p_flip;
RS::get_singleton()->material_set_param(_get_material(), shader_names->heightmap_flip, Vector2(heightmap_parallax_flip_tangent ? -1 : 1, heightmap_parallax_flip_binormal ? -1 : 1));
}
bool BaseMaterial3D::get_heightmap_deep_parallax_flip_binormal() const {
-
return heightmap_parallax_flip_binormal;
}
@@ -1897,7 +1842,6 @@ void BaseMaterial3D::set_alpha_scissor_threshold(float p_threshold) {
}
float BaseMaterial3D::get_alpha_scissor_threshold() const {
-
return alpha_scissor_threshold;
}
@@ -1907,7 +1851,6 @@ void BaseMaterial3D::set_grow(float p_grow) {
}
float BaseMaterial3D::get_grow() const {
-
return grow;
}
@@ -1934,7 +1877,6 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_metallic_texture_channel() co
}
void BaseMaterial3D::set_roughness_texture_channel(TextureChannel p_channel) {
-
ERR_FAIL_INDEX(p_channel, 5);
roughness_texture_channel = p_channel;
_queue_shader_change();
@@ -1945,7 +1887,6 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_roughness_texture_channel() c
}
void BaseMaterial3D::set_ao_texture_channel(TextureChannel p_channel) {
-
ERR_FAIL_INDEX(p_channel, 5);
ao_texture_channel = p_channel;
RS::get_singleton()->material_set_param(_get_material(), shader_names->ao_texture_channel, _get_texture_mask(p_channel));
@@ -1956,7 +1897,6 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_ao_texture_channel() const {
}
void BaseMaterial3D::set_refraction_texture_channel(TextureChannel p_channel) {
-
ERR_FAIL_INDEX(p_channel, 5);
refraction_texture_channel = p_channel;
RS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_texture_channel, _get_texture_mask(p_channel));
@@ -1967,22 +1907,28 @@ BaseMaterial3D::TextureChannel BaseMaterial3D::get_refraction_texture_channel()
}
RID BaseMaterial3D::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y) {
-
int version = 0;
- if (p_shaded)
+ if (p_shaded) {
version = 1;
- if (p_transparent)
+ }
+ if (p_transparent) {
version |= 2;
- if (p_cut_alpha)
+ }
+ if (p_cut_alpha) {
version |= 4;
- if (p_opaque_prepass)
+ }
+ if (p_opaque_prepass) {
version |= 8;
- if (p_double_sided)
+ }
+ if (p_double_sided) {
version |= 16;
- if (p_billboard)
+ }
+ if (p_billboard) {
version |= 32;
- if (p_billboard_y)
+ }
+ if (p_billboard_y) {
version |= 64;
+ }
if (materials_for_2d[version].is_valid()) {
return materials_for_2d[version]->get_rid();
@@ -2013,85 +1959,74 @@ void BaseMaterial3D::set_on_top_of_alpha() {
}
void BaseMaterial3D::set_proximity_fade(bool p_enable) {
-
proximity_fade_enabled = p_enable;
_queue_shader_change();
_change_notify();
}
bool BaseMaterial3D::is_proximity_fade_enabled() const {
-
return proximity_fade_enabled;
}
void BaseMaterial3D::set_proximity_fade_distance(float p_distance) {
-
proximity_fade_distance = p_distance;
RS::get_singleton()->material_set_param(_get_material(), shader_names->proximity_fade_distance, p_distance);
}
-float BaseMaterial3D::get_proximity_fade_distance() const {
+float BaseMaterial3D::get_proximity_fade_distance() const {
return proximity_fade_distance;
}
void BaseMaterial3D::set_distance_fade(DistanceFadeMode p_mode) {
-
distance_fade = p_mode;
_queue_shader_change();
_change_notify();
}
-BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const {
+BaseMaterial3D::DistanceFadeMode BaseMaterial3D::get_distance_fade() const {
return distance_fade;
}
void BaseMaterial3D::set_distance_fade_max_distance(float p_distance) {
-
distance_fade_max_distance = p_distance;
RS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_max, distance_fade_max_distance);
}
-float BaseMaterial3D::get_distance_fade_max_distance() const {
+float BaseMaterial3D::get_distance_fade_max_distance() const {
return distance_fade_max_distance;
}
void BaseMaterial3D::set_distance_fade_min_distance(float p_distance) {
-
distance_fade_min_distance = p_distance;
RS::get_singleton()->material_set_param(_get_material(), shader_names->distance_fade_min, distance_fade_min_distance);
}
float BaseMaterial3D::get_distance_fade_min_distance() const {
-
return distance_fade_min_distance;
}
void BaseMaterial3D::set_emission_operator(EmissionOperator p_op) {
-
- if (emission_op == p_op)
+ if (emission_op == p_op) {
return;
+ }
emission_op = p_op;
_queue_shader_change();
}
BaseMaterial3D::EmissionOperator BaseMaterial3D::get_emission_operator() const {
-
return emission_op;
}
RID BaseMaterial3D::get_shader_rid() const {
-
ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
return shader_map[current_key].shader;
}
Shader::Mode BaseMaterial3D::get_shader_mode() const {
-
return Shader::MODE_SPATIAL;
}
void BaseMaterial3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &BaseMaterial3D::set_albedo);
ClassDB::bind_method(D_METHOD("get_albedo"), &BaseMaterial3D::get_albedo);
@@ -2569,7 +2504,6 @@ void BaseMaterial3D::_bind_methods() {
BaseMaterial3D::BaseMaterial3D(bool p_orm) :
element(this) {
-
orm = p_orm;
// Initialize to the same values as the shader
transparency = TRANSPARENCY_DISABLED;
@@ -2637,7 +2571,7 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
depth_draw_mode = DEPTH_DRAW_OPAQUE_ONLY;
cull_mode = CULL_BACK;
for (int i = 0; i < FLAG_MAX; i++) {
- flags[i] = 0;
+ flags[i] = false;
}
flags[FLAG_USE_TEXTURE_REPEAT] = true;
@@ -2656,7 +2590,6 @@ BaseMaterial3D::BaseMaterial3D(bool p_orm) :
}
BaseMaterial3D::~BaseMaterial3D() {
-
MutexLock lock(material_mutex);
if (shader_map.has(current_key)) {
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 241357ba9b..433e3d304e 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -39,7 +39,6 @@
#include "servers/rendering_server.h"
class Material : public Resource {
-
GDCLASS(Material, Resource);
RES_BASE_EXTENSION("material")
OBJ_SAVE_TYPE(Material);
@@ -74,7 +73,6 @@ public:
};
class ShaderMaterial : public Material {
-
GDCLASS(ShaderMaterial, Material);
Ref<Shader> shader;
@@ -109,7 +107,6 @@ public:
class StandardMaterial3D;
class BaseMaterial3D : public Material {
-
GDCLASS(BaseMaterial3D, Material);
public:
@@ -269,7 +266,6 @@ public:
private:
union MaterialKey {
-
struct {
uint64_t feature_mask : FEATURE_MAX;
uint64_t detail_uv : 1;
@@ -316,7 +312,6 @@ private:
MaterialKey current_key;
_FORCE_INLINE_ MaterialKey _compute_key() const {
-
MaterialKey mk;
mk.key0 = 0;
mk.key1 = 0;
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 6bb5be15f3..10f0a040d0 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -40,28 +40,27 @@
Mesh::ConvexDecompositionFunc Mesh::convex_composition_function = nullptr;
Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
-
- if (triangle_mesh.is_valid())
+ if (triangle_mesh.is_valid()) {
return triangle_mesh;
+ }
int facecount = 0;
for (int i = 0; i < get_surface_count(); i++) {
-
- if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
+ if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) {
continue;
+ }
if (surface_get_format(i) & ARRAY_FORMAT_INDEX) {
-
facecount += surface_get_array_index_len(i);
} else {
-
facecount += surface_get_array_len(i);
}
}
- if (facecount == 0 || (facecount % 3) != 0)
+ if (facecount == 0 || (facecount % 3) != 0) {
return triangle_mesh;
+ }
Vector<Vector3> faces;
faces.resize(facecount);
@@ -70,9 +69,9 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
int widx = 0;
for (int i = 0; i < get_surface_count(); i++) {
-
- if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
+ if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) {
continue;
+ }
Array a = surface_get_arrays(i);
ERR_FAIL_COND_V(a.empty(), Ref<TriangleMesh>());
@@ -82,7 +81,6 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
const Vector3 *vr = vertices.ptr();
if (surface_get_format(i) & ARRAY_FORMAT_INDEX) {
-
int ic = surface_get_array_index_len(i);
Vector<int> indices = a[ARRAY_INDEX];
const int *ir = indices.ptr();
@@ -93,9 +91,9 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
}
} else {
-
- for (int j = 0; j < vc; j++)
+ for (int j = 0; j < vc; j++) {
facesw[widx++] = vr[j];
+ }
}
}
@@ -106,15 +104,15 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
}
void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) {
-
if (debug_lines.size() > 0) {
r_lines = debug_lines;
return;
}
Ref<TriangleMesh> tm = generate_triangle_mesh();
- if (tm.is_null())
+ if (tm.is_null()) {
return;
+ }
Vector<int> triangle_indices;
tm->get_indices(&triangle_indices);
@@ -141,10 +139,12 @@ void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) {
r_lines = debug_lines;
}
+
void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) {
Ref<TriangleMesh> tm = generate_triangle_mesh();
- if (tm.is_null())
+ if (tm.is_null()) {
return;
+ }
Vector<Vector3> vertices = tm->get_vertices();
@@ -161,10 +161,10 @@ bool Mesh::surface_is_softbody_friendly(int p_idx) const {
}
Vector<Face3> Mesh::get_faces() const {
-
Ref<TriangleMesh> tm = generate_triangle_mesh();
- if (tm.is_valid())
+ if (tm.is_valid()) {
return tm->get_faces();
+ }
return Vector<Face3>();
/*
for (int i=0;i<surfaces.size();i++) {
@@ -227,11 +227,9 @@ Vector<Face3> Mesh::get_faces() const {
}
Ref<Shape3D> Mesh::create_convex_shape() const {
-
Vector<Vector3> vertices;
for (int i = 0; i < get_surface_count(); i++) {
-
Array a = surface_get_arrays(i);
ERR_FAIL_COND_V(a.empty(), Ref<ConvexPolygonShape3D>());
Vector<Vector3> v = a[ARRAY_VERTEX];
@@ -244,16 +242,15 @@ Ref<Shape3D> Mesh::create_convex_shape() const {
}
Ref<Shape3D> Mesh::create_trimesh_shape() const {
-
Vector<Face3> faces = get_faces();
- if (faces.size() == 0)
+ if (faces.size() == 0) {
return Ref<Shape3D>();
+ }
Vector<Vector3> face_points;
face_points.resize(faces.size() * 3);
for (int i = 0; i < face_points.size(); i += 3) {
-
Face3 f = faces.get(i / 3);
face_points.set(i, f.vertex[0]);
face_points.set(i + 1, f.vertex[1]);
@@ -266,13 +263,12 @@ Ref<Shape3D> Mesh::create_trimesh_shape() const {
}
Ref<Mesh> Mesh::create_outline(float p_margin) const {
-
Array arrays;
int index_accum = 0;
for (int i = 0; i < get_surface_count(); i++) {
-
- if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
+ if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES) {
continue;
+ }
Array a = surface_get_arrays(i);
ERR_FAIL_COND_V(a.empty(), Ref<ArrayMesh>());
@@ -282,10 +278,8 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
Vector<Vector3> v = a[ARRAY_VERTEX];
index_accum += v.size();
} else {
-
int vcount = 0;
for (int j = 0; j < arrays.size(); j++) {
-
if (arrays[j].get_type() == Variant::NIL || a[j].get_type() == Variant::NIL) {
//mismatch, do not use
arrays[j] = Variant();
@@ -293,14 +287,13 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
}
switch (j) {
-
case ARRAY_VERTEX:
case ARRAY_NORMAL: {
-
Vector<Vector3> dst = arrays[j];
Vector<Vector3> src = a[j];
- if (j == ARRAY_VERTEX)
+ if (j == ARRAY_VERTEX) {
vcount = src.size();
+ }
if (dst.size() == 0 || src.size() == 0) {
arrays[j] = Variant();
continue;
@@ -311,7 +304,6 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
case ARRAY_TANGENT:
case ARRAY_BONES:
case ARRAY_WEIGHTS: {
-
Vector<real_t> dst = arrays[j];
Vector<real_t> src = a[j];
if (dst.size() == 0 || src.size() == 0) {
@@ -391,7 +383,6 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
//fill normals with triangle normals
for (int i = 0; i < vc; i += 3) {
-
Vector3 t[3];
if (has_indices) {
@@ -407,14 +398,14 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
Vector3 n = Plane(t[0], t[1], t[2]).normal;
for (int j = 0; j < 3; j++) {
-
Map<Vector3, Vector3>::Element *E = normal_accum.find(t[j]);
if (!E) {
normal_accum[t[j]] = n;
} else {
float d = n.dot(E->get());
- if (d < 1.0)
+ if (d < 1.0) {
E->get() += n * (1.0 - d);
+ }
//E->get()+=n;
}
}
@@ -430,7 +421,6 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
int vc2 = vertices.size();
for (int i = 0; i < vc2; i++) {
-
Vector3 t = r[i];
Map<Vector3, Vector3>::Element *E = normal_accum.find(t);
@@ -443,13 +433,11 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
arrays[ARRAY_VERTEX] = vertices;
if (!has_indices) {
-
Vector<int> new_indices;
new_indices.resize(vertices.size());
int *iw = new_indices.ptrw();
for (int j = 0; j < vc2; j += 3) {
-
iw[j] = j;
iw[j + 1] = j + 2;
iw[j + 2] = j + 1;
@@ -458,9 +446,7 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
arrays[ARRAY_INDEX] = new_indices;
} else {
-
for (int j = 0; j < vc; j += 3) {
-
SWAP(ir[j + 1], ir[j + 2]);
}
arrays[ARRAY_INDEX] = indices;
@@ -472,21 +458,20 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
return newmesh;
}
-void Mesh::set_lightmap_size_hint(const Vector2 &p_size) {
+void Mesh::set_lightmap_size_hint(const Size2i &p_size) {
lightmap_size_hint = p_size;
}
-Size2 Mesh::get_lightmap_size_hint() const {
+Size2i Mesh::get_lightmap_size_hint() const {
return lightmap_size_hint;
}
void Mesh::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_lightmap_size_hint", "size"), &Mesh::set_lightmap_size_hint);
ClassDB::bind_method(D_METHOD("get_lightmap_size_hint"), &Mesh::get_lightmap_size_hint);
ClassDB::bind_method(D_METHOD("get_aabb"), &Mesh::get_aabb);
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint");
ClassDB::bind_method(D_METHOD("get_surface_count"), &Mesh::get_surface_count);
ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &Mesh::surface_get_arrays);
@@ -542,7 +527,6 @@ void Mesh::clear_cache() const {
}
Vector<Ref<Shape3D>> Mesh::convex_decompose() const {
-
ERR_FAIL_COND_V(!convex_composition_function, Vector<Ref<Shape3D>>());
const Vector<Face3> faces = get_faces();
@@ -582,7 +566,6 @@ Mesh::Mesh() {
}
static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_format, uint32_t p_elements) {
-
bool vertex_16bit = p_format & ((1 << (Mesh::ARRAY_VERTEX + Mesh::ARRAY_COMPRESS_BASE)));
bool has_bones = (p_format & Mesh::ARRAY_FORMAT_BONES);
bool bone_8 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_INDEX << 2));
@@ -607,7 +590,6 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui
const uint8_t *r = p_src.ptr();
for (uint32_t i = 0; i < p_elements; i++) {
-
uint32_t remaining = src_stride;
const uint8_t *src = (const uint8_t *)(r + src_stride * i);
uint8_t *dst = (uint8_t *)(w + dst_stride * i);
@@ -642,7 +624,6 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui
}
if (has_bones) {
-
remaining -= bone_8 ? 4 : 8;
remaining -= weight_32 ? 16 : 8;
}
@@ -652,12 +633,10 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui
}
if (has_bones) {
-
dst += remaining;
src += remaining;
if (bone_8) {
-
const uint8_t *src_bones = (const uint8_t *)src;
uint16_t *dst_bones = (uint16_t *)dst;
@@ -678,7 +657,6 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui
dst += 8;
if (weight_32) {
-
const float *src_weights = (const float *)src;
uint16_t *dst_weights = (uint16_t *)dst;
@@ -700,43 +678,43 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui
}
bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
-
String sname = p_name;
if (p_name == "blend_shape/names") {
-
Vector<String> sk = p_value;
int sz = sk.size();
const String *r = sk.ptr();
- for (int i = 0; i < sz; i++)
+ for (int i = 0; i < sz; i++) {
add_blend_shape(r[i]);
+ }
return true;
}
if (p_name == "blend_shape/mode") {
-
set_blend_shape_mode(BlendShapeMode(int(p_value)));
return true;
}
if (sname.begins_with("surface_")) {
-
int sl = sname.find("/");
- if (sl == -1)
+ if (sl == -1) {
return false;
+ }
int idx = sname.substr(8, sl - 8).to_int() - 1;
String what = sname.get_slicec('/', 1);
- if (what == "material")
+ if (what == "material") {
surface_set_material(idx, p_value);
- else if (what == "name")
+ } else if (what == "name") {
surface_set_name(idx, p_value);
+ }
return true;
}
#ifndef DISABLE_DEPRECATED
// Kept for compatibility from 3.x to 4.0.
- if (!sname.begins_with("surfaces"))
+ if (!sname.begins_with("surfaces")) {
return false;
+ }
WARN_DEPRECATED_MSG("Mesh uses old surface format, which is deprecated (and loads slower). Consider re-importing or re-saving the scene.");
@@ -744,7 +722,6 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
String what = sname.get_slicec('/', 2);
if (idx == surfaces.size()) {
-
//create
Dictionary d = p_value;
ERR_FAIL_COND_V(!d.has("primitive"), false);
@@ -759,8 +736,9 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
//older format (3.x)
Vector<uint8_t> array_data = d["array_data"];
Vector<uint8_t> array_index_data;
- if (d.has("array_index_data"))
+ if (d.has("array_index_data")) {
array_index_data = d["array_index_data"];
+ }
ERR_FAIL_COND_V(!d.has("format"), false);
uint32_t format = d["format"];
@@ -785,8 +763,9 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
array_data = _fix_array_compatibility(array_data, format, vertex_count);
int index_count = 0;
- if (d.has("index_count"))
+ if (d.has("index_count")) {
index_count = d["index_count"];
+ }
Vector<Vector<uint8_t>> blend_shapes;
@@ -824,7 +803,6 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
}
if (d.has("material")) {
-
surface_set_material(idx, d["material"]);
}
if (d.has("name")) {
@@ -839,7 +817,6 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
}
Array ArrayMesh::_get_surfaces() const {
-
if (mesh.is_null()) {
return Array();
}
@@ -908,7 +885,6 @@ void ArrayMesh::_create_if_empty() const {
}
void ArrayMesh::_set_surfaces(const Array &p_surfaces) {
-
Vector<RS::SurfaceData> surface_data;
Vector<Ref<Material>> surface_materials;
Vector<String> surface_names;
@@ -1031,34 +1007,34 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) {
}
bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (_is_generated())
+ if (_is_generated()) {
return false;
+ }
String sname = p_name;
if (p_name == "blend_shape/names") {
-
Vector<String> sk;
- for (int i = 0; i < blend_shapes.size(); i++)
+ for (int i = 0; i < blend_shapes.size(); i++) {
sk.push_back(blend_shapes[i]);
+ }
r_ret = sk;
return true;
} else if (p_name == "blend_shape/mode") {
-
r_ret = get_blend_shape_mode();
return true;
} else if (sname.begins_with("surface_")) {
-
int sl = sname.find("/");
- if (sl == -1)
+ if (sl == -1) {
return false;
+ }
int idx = sname.substr(8, sl - 8).to_int() - 1;
String what = sname.get_slicec('/', 1);
- if (what == "material")
+ if (what == "material") {
r_ret = surface_get_material(idx);
- else if (what == "name")
+ } else if (what == "name") {
r_ret = surface_get_name(idx);
+ }
return true;
}
@@ -1066,9 +1042,9 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {
}
void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
-
- if (_is_generated())
+ if (_is_generated()) {
return;
+ }
if (blend_shapes.size()) {
p_list->push_back(PropertyInfo(Variant::PACKED_STRING_ARRAY, "blend_shape/names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
@@ -1076,7 +1052,6 @@ void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
}
for (int i = 0; i < surfaces.size(); i++) {
-
p_list->push_back(PropertyInfo(Variant::STRING, "surface_" + itos(i + 1) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR));
if (surfaces[i].is_2d) {
p_list->push_back(PropertyInfo(Variant::OBJECT, "surface_" + itos(i + 1) + "/material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,CanvasItemMaterial", PROPERTY_USAGE_EDITOR));
@@ -1087,23 +1062,21 @@ void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
}
void ArrayMesh::_recompute_aabb() {
-
// regenerate AABB
aabb = AABB();
for (int i = 0; i < surfaces.size(); i++) {
-
- if (i == 0)
+ if (i == 0) {
aabb = surfaces[i].aabb;
- else
+ } else {
aabb.merge_with(surfaces[i].aabb);
+ }
}
}
#ifndef _MSC_VER
#warning need to add binding to add_surface using future MeshSurfaceData object
#endif
void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes, const Vector<AABB> &p_bone_aabb, const Vector<RS::SurfaceData::LOD> &p_lods) {
-
_create_if_empty();
Surface s;
@@ -1137,7 +1110,6 @@ void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const
}
void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, uint32_t p_flags) {
-
ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX);
RS::SurfaceData surface;
@@ -1157,36 +1129,32 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &
}
Array ArrayMesh::surface_get_arrays(int p_surface) const {
-
ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array());
return RenderingServer::get_singleton()->mesh_surface_get_arrays(mesh, p_surface);
}
-Array ArrayMesh::surface_get_blend_shape_arrays(int p_surface) const {
+Array ArrayMesh::surface_get_blend_shape_arrays(int p_surface) const {
ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array());
return RenderingServer::get_singleton()->mesh_surface_get_blend_shape_arrays(mesh, p_surface);
}
+
Dictionary ArrayMesh::surface_get_lods(int p_surface) const {
ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Dictionary());
return RenderingServer::get_singleton()->mesh_surface_get_lods(mesh, p_surface);
}
int ArrayMesh::get_surface_count() const {
-
return surfaces.size();
}
void ArrayMesh::add_blend_shape(const StringName &p_name) {
-
ERR_FAIL_COND_MSG(surfaces.size(), "Can't add a shape key count if surfaces are already created.");
StringName name = p_name;
if (blend_shapes.find(name) != -1) {
-
int count = 2;
do {
-
name = String(p_name) + " " + itos(count);
count++;
} while (blend_shapes.find(name) != -1);
@@ -1197,22 +1165,21 @@ void ArrayMesh::add_blend_shape(const StringName &p_name) {
}
int ArrayMesh::get_blend_shape_count() const {
-
return blend_shapes.size();
}
+
StringName ArrayMesh::get_blend_shape_name(int p_index) const {
ERR_FAIL_INDEX_V(p_index, blend_shapes.size(), StringName());
return blend_shapes[p_index];
}
-void ArrayMesh::clear_blend_shapes() {
+void ArrayMesh::clear_blend_shapes() {
ERR_FAIL_COND_MSG(surfaces.size(), "Can't set shape key count if surfaces are already created.");
blend_shapes.clear();
}
void ArrayMesh::set_blend_shape_mode(BlendShapeMode p_mode) {
-
blend_shape_mode = p_mode;
if (mesh.is_valid()) {
RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)p_mode);
@@ -1220,39 +1187,34 @@ void ArrayMesh::set_blend_shape_mode(BlendShapeMode p_mode) {
}
ArrayMesh::BlendShapeMode ArrayMesh::get_blend_shape_mode() const {
-
return blend_shape_mode;
}
int ArrayMesh::surface_get_array_len(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1);
return surfaces[p_idx].array_length;
}
int ArrayMesh::surface_get_array_index_len(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1);
return surfaces[p_idx].index_array_length;
}
uint32_t ArrayMesh::surface_get_format(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), 0);
return surfaces[p_idx].format;
}
ArrayMesh::PrimitiveType ArrayMesh::surface_get_primitive_type(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), PRIMITIVE_LINES);
return surfaces[p_idx].primitive;
}
void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
-
ERR_FAIL_INDEX(p_idx, surfaces.size());
- if (surfaces[p_idx].material == p_material)
+ if (surfaces[p_idx].material == p_material) {
return;
+ }
surfaces.write[p_idx].material = p_material;
RenderingServer::get_singleton()->mesh_surface_set_material(mesh, p_idx, p_material.is_null() ? RID() : p_material->get_rid());
@@ -1270,7 +1232,6 @@ int ArrayMesh::surface_find_by_name(const String &p_name) const {
}
void ArrayMesh::surface_set_name(int p_idx, const String &p_name) {
-
ERR_FAIL_INDEX(p_idx, surfaces.size());
surfaces.write[p_idx].name = p_name;
@@ -1278,20 +1239,17 @@ void ArrayMesh::surface_set_name(int p_idx, const String &p_name) {
}
String ArrayMesh::surface_get_name(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), String());
return surfaces[p_idx].name;
}
void ArrayMesh::surface_update_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data) {
-
ERR_FAIL_INDEX(p_surface, surfaces.size());
RS::get_singleton()->mesh_surface_update_region(mesh, p_surface, p_offset, p_data);
emit_changed();
}
void ArrayMesh::surface_set_custom_aabb(int p_idx, const AABB &p_aabb) {
-
ERR_FAIL_INDEX(p_idx, surfaces.size());
surfaces.write[p_idx].aabb = p_aabb;
// set custom aabb too?
@@ -1299,18 +1257,16 @@ void ArrayMesh::surface_set_custom_aabb(int p_idx, const AABB &p_aabb) {
}
Ref<Material> ArrayMesh::surface_get_material(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), Ref<Material>());
return surfaces[p_idx].material;
}
RID ArrayMesh::get_rid() const {
-
_create_if_empty();
return mesh;
}
-AABB ArrayMesh::get_aabb() const {
+AABB ArrayMesh::get_aabb() const {
return aabb;
}
@@ -1324,7 +1280,6 @@ void ArrayMesh::clear_surfaces() {
}
void ArrayMesh::set_custom_aabb(const AABB &p_custom) {
-
_create_if_empty();
custom_aabb = p_custom;
RS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
@@ -1332,18 +1287,15 @@ void ArrayMesh::set_custom_aabb(const AABB &p_custom) {
}
AABB ArrayMesh::get_custom_aabb() const {
-
return custom_aabb;
}
void ArrayMesh::regen_normalmaps() {
-
if (surfaces.size() == 0) {
return;
}
Vector<Ref<SurfaceTool>> surfs;
for (int i = 0; i < get_surface_count(); i++) {
-
Ref<SurfaceTool> st = memnew(SurfaceTool);
st->create_from(Ref<ArrayMesh>(this), i);
surfs.push_back(st);
@@ -1352,17 +1304,15 @@ void ArrayMesh::regen_normalmaps() {
clear_surfaces();
for (int i = 0; i < surfs.size(); i++) {
-
surfs.write[i]->generate_tangents();
surfs.write[i]->commit(Ref<ArrayMesh>(this));
}
}
//dirty hack
-bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) = nullptr;
+bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y, int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache);
struct ArrayMeshLightmapSurface {
-
Ref<Material> material;
Vector<SurfaceTool::Vertex> vertices;
Mesh::PrimitiveType primitive;
@@ -1370,18 +1320,31 @@ struct ArrayMeshLightmapSurface {
};
Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) {
+ int *cache_data = nullptr;
+ unsigned int cache_size = 0;
+ bool use_cache = false; // Don't use cache
+ return lightmap_unwrap_cached(cache_data, cache_size, use_cache, p_base_transform, p_texel_size);
+}
+Error ArrayMesh::lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache, const Transform &p_base_transform, float p_texel_size) {
ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED);
ERR_FAIL_COND_V_MSG(blend_shapes.size() != 0, ERR_UNAVAILABLE, "Can't unwrap mesh with blend shapes.");
Vector<float> vertices;
Vector<float> normals;
Vector<int> indices;
- Vector<int> face_materials;
Vector<float> uv;
- Vector<Pair<int, int>> uv_index;
+ Vector<Pair<int, int>> uv_indices;
+
+ Vector<ArrayMeshLightmapSurface> lightmap_surfaces;
+
+ // Keep only the scale
+ Transform transform = p_base_transform;
+ transform.origin = Vector3();
+ transform.looking_at(Vector3(1, 0, 0), Vector3(0, 1, 0));
+
+ Basis normal_basis = transform.basis.inverse().transposed();
- Vector<ArrayMeshLightmapSurface> surfaces;
for (int i = 0; i < get_surface_count(); i++) {
ArrayMeshLightmapSurface s;
s.primitive = surface_get_primitive_type(i);
@@ -1405,12 +1368,11 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
vertices.resize((vertex_ofs + vc) * 3);
normals.resize((vertex_ofs + vc) * 3);
- uv_index.resize(vertex_ofs + vc);
+ uv_indices.resize(vertex_ofs + vc);
for (int j = 0; j < vc; j++) {
-
- Vector3 v = p_base_transform.xform(r[j]);
- Vector3 n = p_base_transform.basis.xform(rn[j]).normalized();
+ Vector3 v = transform.xform(r[j]);
+ Vector3 n = normal_basis.xform(rn[j]).normalized();
vertices.write[(j + vertex_ofs) * 3 + 0] = v.x;
vertices.write[(j + vertex_ofs) * 3 + 1] = v.y;
@@ -1418,38 +1380,37 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
normals.write[(j + vertex_ofs) * 3 + 0] = n.x;
normals.write[(j + vertex_ofs) * 3 + 1] = n.y;
normals.write[(j + vertex_ofs) * 3 + 2] = n.z;
- uv_index.write[j + vertex_ofs] = Pair<int, int>(i, j);
+ uv_indices.write[j + vertex_ofs] = Pair<int, int>(i, j);
}
Vector<int> rindices = arrays[Mesh::ARRAY_INDEX];
int ic = rindices.size();
if (ic == 0) {
-
for (int j = 0; j < vc / 3; j++) {
- if (Face3(r[j * 3 + 0], r[j * 3 + 1], r[j * 3 + 2]).is_degenerate())
+ if (Face3(r[j * 3 + 0], r[j * 3 + 1], r[j * 3 + 2]).is_degenerate()) {
continue;
+ }
indices.push_back(vertex_ofs + j * 3 + 0);
indices.push_back(vertex_ofs + j * 3 + 1);
indices.push_back(vertex_ofs + j * 3 + 2);
- face_materials.push_back(i);
}
} else {
const int *ri = rindices.ptr();
for (int j = 0; j < ic / 3; j++) {
- if (Face3(r[ri[j * 3 + 0]], r[ri[j * 3 + 1]], r[ri[j * 3 + 2]]).is_degenerate())
+ if (Face3(r[ri[j * 3 + 0]], r[ri[j * 3 + 1]], r[ri[j * 3 + 2]]).is_degenerate()) {
continue;
+ }
indices.push_back(vertex_ofs + ri[j * 3 + 0]);
indices.push_back(vertex_ofs + ri[j * 3 + 1]);
indices.push_back(vertex_ofs + ri[j * 3 + 2]);
- face_materials.push_back(i);
}
}
- surfaces.push_back(s);
+ lightmap_surfaces.push_back(s);
}
//unwrap
@@ -1462,7 +1423,7 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
int size_x;
int size_y;
- bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), face_materials.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y);
+ bool ok = array_mesh_lightmap_unwrap_callback(p_texel_size, vertices.ptr(), normals.ptr(), vertices.size() / 3, indices.ptr(), indices.size(), &gen_uvs, &gen_vertices, &gen_vertex_count, &gen_indices, &gen_index_count, &size_x, &size_y, r_cache_data, r_cache_size, r_used_cache);
if (!ok) {
return ERR_CANT_CREATE;
@@ -1474,49 +1435,47 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
//create surfacetools for each surface..
Vector<Ref<SurfaceTool>> surfaces_tools;
- for (int i = 0; i < surfaces.size(); i++) {
+ for (int i = 0; i < lightmap_surfaces.size(); i++) {
Ref<SurfaceTool> st;
st.instance();
st->begin(Mesh::PRIMITIVE_TRIANGLES);
- st->set_material(surfaces[i].material);
+ st->set_material(lightmap_surfaces[i].material);
surfaces_tools.push_back(st); //stay there
}
print_verbose("Mesh: Gen indices: " + itos(gen_index_count));
//go through all indices
for (int i = 0; i < gen_index_count; i += 3) {
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_indices.size(), ERR_BUG);
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_indices.size(), ERR_BUG);
+ ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_indices.size(), ERR_BUG);
- ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 0]], uv_index.size(), ERR_BUG);
- ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 1]], uv_index.size(), ERR_BUG);
- ERR_FAIL_INDEX_V(gen_vertices[gen_indices[i + 2]], uv_index.size(), ERR_BUG);
+ ERR_FAIL_COND_V(uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 1]]].first || uv_indices[gen_vertices[gen_indices[i + 0]]].first != uv_indices[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG);
- ERR_FAIL_COND_V(uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 1]]].first || uv_index[gen_vertices[gen_indices[i + 0]]].first != uv_index[gen_vertices[gen_indices[i + 2]]].first, ERR_BUG);
-
- int surface = uv_index[gen_vertices[gen_indices[i + 0]]].first;
+ int surface = uv_indices[gen_vertices[gen_indices[i + 0]]].first;
for (int j = 0; j < 3; j++) {
+ SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second];
- SurfaceTool::Vertex v = surfaces[surface].vertices[uv_index[gen_vertices[gen_indices[i + j]]].second];
-
- if (surfaces[surface].format & ARRAY_FORMAT_COLOR) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_COLOR) {
surfaces_tools.write[surface]->add_color(v.color);
}
- if (surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TEX_UV) {
surfaces_tools.write[surface]->add_uv(v.uv);
}
- if (surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_NORMAL) {
surfaces_tools.write[surface]->add_normal(v.normal);
}
- if (surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TANGENT) {
Plane t;
t.normal = v.tangent;
t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1;
surfaces_tools.write[surface]->add_tangent(t);
}
- if (surfaces[surface].format & ARRAY_FORMAT_BONES) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_BONES) {
surfaces_tools.write[surface]->add_bones(v.bones);
}
- if (surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
+ if (lightmap_surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) {
surfaces_tools.write[surface]->add_weights(v.weights);
}
@@ -1527,25 +1486,26 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe
}
}
- //free stuff
- ::free(gen_vertices);
- ::free(gen_indices);
- ::free(gen_uvs);
-
//generate surfaces
for (int i = 0; i < surfaces_tools.size(); i++) {
surfaces_tools.write[i]->index();
- surfaces_tools.write[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), surfaces[i].format);
+ surfaces_tools.write[i]->commit(Ref<ArrayMesh>((ArrayMesh *)this), lightmap_surfaces[i].format);
}
set_lightmap_size_hint(Size2(size_x, size_y));
+ if (!r_used_cache) {
+ //free stuff
+ ::free(gen_vertices);
+ ::free(gen_indices);
+ ::free(gen_uvs);
+ }
+
return OK;
}
void ArrayMesh::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape);
ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &ArrayMesh::get_blend_shape_count);
ClassDB::bind_method(D_METHOD("get_blend_shape_name", "index"), &ArrayMesh::get_blend_shape_name);
@@ -1620,14 +1580,12 @@ void ArrayMesh::reload_from_file() {
}
ArrayMesh::ArrayMesh() {
-
//mesh is now created on demand
//mesh = RenderingServer::get_singleton()->mesh_create();
blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE;
}
ArrayMesh::~ArrayMesh() {
-
if (mesh.is_valid()) {
RenderingServer::get_singleton()->free(mesh);
}
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 25a9722046..44e4e78322 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -43,7 +43,7 @@ class Mesh : public Resource {
mutable Ref<TriangleMesh> triangle_mesh; //cached
mutable Vector<Vector3> debug_lines;
- Size2 lightmap_size_hint;
+ Size2i lightmap_size_hint;
protected:
static void _bind_methods();
@@ -138,8 +138,8 @@ public:
virtual AABB get_aabb() const = 0;
- void set_lightmap_size_hint(const Vector2 &p_size);
- Size2 get_lightmap_size_hint() const;
+ void set_lightmap_size_hint(const Size2i &p_size);
+ Size2i get_lightmap_size_hint() const;
void clear_cache() const;
typedef Vector<Vector<Face3>> (*ConvexDecompositionFunc)(const Vector<Face3> &);
@@ -152,7 +152,6 @@ public:
};
class ArrayMesh : public Mesh {
-
GDCLASS(ArrayMesh, Mesh);
RES_BASE_EXTENSION("mesh");
@@ -238,6 +237,7 @@ public:
void regen_normalmaps();
Error lightmap_unwrap(const Transform &p_base_transform = Transform(), float p_texel_size = 0.05);
+ Error lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cache_size, bool &r_used_cache, const Transform &p_base_transform = Transform(), float p_texel_size = 0.05);
virtual void reload_from_file();
diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp
index 76d96786bc..a5c360f123 100644
--- a/scene/resources/mesh_data_tool.cpp
+++ b/scene/resources/mesh_data_tool.cpp
@@ -31,7 +31,6 @@
#include "mesh_data_tool.h"
void MeshDataTool::clear() {
-
vertices.clear();
edges.clear();
faces.clear();
@@ -40,7 +39,6 @@ void MeshDataTool::clear() {
}
Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surface) {
-
ERR_FAIL_COND_V(p_mesh.is_null(), ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_mesh->surface_get_primitive_type(p_surface) != Mesh::PRIMITIVE_TRIANGLES, ERR_INVALID_PARAMETER);
@@ -59,51 +57,61 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
const Vector3 *vr = varray.ptr();
const Vector3 *nr = nullptr;
- if (arrays[Mesh::ARRAY_NORMAL].get_type() != Variant::NIL)
+ if (arrays[Mesh::ARRAY_NORMAL].get_type() != Variant::NIL) {
nr = arrays[Mesh::ARRAY_NORMAL].operator Vector<Vector3>().ptr();
+ }
const real_t *ta = nullptr;
- if (arrays[Mesh::ARRAY_TANGENT].get_type() != Variant::NIL)
+ if (arrays[Mesh::ARRAY_TANGENT].get_type() != Variant::NIL) {
ta = arrays[Mesh::ARRAY_TANGENT].operator Vector<real_t>().ptr();
+ }
const Vector2 *uv = nullptr;
- if (arrays[Mesh::ARRAY_TEX_UV].get_type() != Variant::NIL)
+ if (arrays[Mesh::ARRAY_TEX_UV].get_type() != Variant::NIL) {
uv = arrays[Mesh::ARRAY_TEX_UV].operator Vector<Vector2>().ptr();
+ }
const Vector2 *uv2 = nullptr;
- if (arrays[Mesh::ARRAY_TEX_UV2].get_type() != Variant::NIL)
+ if (arrays[Mesh::ARRAY_TEX_UV2].get_type() != Variant::NIL) {
uv2 = arrays[Mesh::ARRAY_TEX_UV2].operator Vector<Vector2>().ptr();
+ }
const Color *col = nullptr;
- if (arrays[Mesh::ARRAY_COLOR].get_type() != Variant::NIL)
+ if (arrays[Mesh::ARRAY_COLOR].get_type() != Variant::NIL) {
col = arrays[Mesh::ARRAY_COLOR].operator Vector<Color>().ptr();
+ }
const int *bo = nullptr;
- if (arrays[Mesh::ARRAY_BONES].get_type() != Variant::NIL)
+ if (arrays[Mesh::ARRAY_BONES].get_type() != Variant::NIL) {
bo = arrays[Mesh::ARRAY_BONES].operator Vector<int>().ptr();
+ }
const real_t *we = nullptr;
- if (arrays[Mesh::ARRAY_WEIGHTS].get_type() != Variant::NIL)
+ if (arrays[Mesh::ARRAY_WEIGHTS].get_type() != Variant::NIL) {
we = arrays[Mesh::ARRAY_WEIGHTS].operator Vector<real_t>().ptr();
+ }
vertices.resize(vcount);
for (int i = 0; i < vcount; i++) {
-
Vertex v;
v.vertex = vr[i];
- if (nr)
+ if (nr) {
v.normal = nr[i];
- if (ta)
+ }
+ if (ta) {
v.tangent = Plane(ta[i * 4 + 0], ta[i * 4 + 1], ta[i * 4 + 2], ta[i * 4 + 3]);
- if (uv)
+ }
+ if (uv) {
v.uv = uv[i];
- if (uv2)
+ }
+ if (uv2) {
v.uv2 = uv2[i];
- if (col)
+ }
+ if (col) {
v.color = col[i];
+ }
if (we) {
-
v.weights.push_back(we[i * 4 + 0]);
v.weights.push_back(we[i * 4 + 1]);
v.weights.push_back(we[i * 4 + 2]);
@@ -111,7 +119,6 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
}
if (bo) {
-
v.bones.push_back(bo[i * 4 + 0]);
v.bones.push_back(bo[i * 4 + 1]);
v.bones.push_back(bo[i * 4 + 2]);
@@ -124,14 +131,14 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
Vector<int> indices;
if (arrays[Mesh::ARRAY_INDEX].get_type() != Variant::NIL) {
-
indices = arrays[Mesh::ARRAY_INDEX];
} else {
//make code simpler
indices.resize(vcount);
int *iw = indices.ptrw();
- for (int i = 0; i < vcount; i++)
+ for (int i = 0; i < vcount; i++) {
iw[i] = i;
+ }
}
int icount = indices.size();
@@ -140,14 +147,12 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
Map<Point2i, int> edge_indices;
for (int i = 0; i < icount; i += 3) {
-
Vertex *v[3] = { &vertices.write[r[i + 0]], &vertices.write[r[i + 1]], &vertices.write[r[i + 2]] };
int fidx = faces.size();
Face face;
for (int j = 0; j < 3; j++) {
-
face.v[j] = r[i + j];
Point2i edge(r[i + j], r[i + (j + 1) % 3]);
@@ -180,7 +185,6 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf
}
Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
-
ERR_FAIL_COND_V(p_mesh.is_null(), ERR_INVALID_PARAMETER);
Array arr;
arr.resize(Mesh::ARRAY_MAX);
@@ -198,7 +202,6 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
Vector<int> in;
{
-
v.resize(vcount);
Vector3 *vr = v.ptrw();
@@ -245,27 +248,29 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
}
for (int i = 0; i < vcount; i++) {
-
const Vertex &vtx = vertices[i];
vr[i] = vtx.vertex;
- if (nr)
+ if (nr) {
nr[i] = vtx.normal;
+ }
if (ta) {
ta[i * 4 + 0] = vtx.tangent.normal.x;
ta[i * 4 + 1] = vtx.tangent.normal.y;
ta[i * 4 + 2] = vtx.tangent.normal.z;
ta[i * 4 + 3] = vtx.tangent.d;
}
- if (uv)
+ if (uv) {
uv[i] = vtx.uv;
- if (uv2)
+ }
+ if (uv2) {
uv2[i] = vtx.uv2;
- if (col)
+ }
+ if (col) {
col[i] = vtx.color;
+ }
if (we) {
-
we[i * 4 + 0] = vtx.weights[0];
we[i * 4 + 1] = vtx.weights[1];
we[i * 4 + 2] = vtx.weights[2];
@@ -273,7 +278,6 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
}
if (bo) {
-
bo[i * 4 + 0] = vtx.bones[0];
bo[i * 4 + 1] = vtx.bones[1];
bo[i * 4 + 2] = vtx.bones[2];
@@ -285,7 +289,6 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
in.resize(fc * 3);
int *iw = in.ptrw();
for (int i = 0; i < fc; i++) {
-
iw[i * 3 + 0] = faces[i].v[0];
iw[i * 3 + 1] = faces[i].v[1];
iw[i * 3 + 2] = faces[i].v[2];
@@ -294,20 +297,27 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
arr[Mesh::ARRAY_VERTEX] = v;
arr[Mesh::ARRAY_INDEX] = in;
- if (n.size())
+ if (n.size()) {
arr[Mesh::ARRAY_NORMAL] = n;
- if (c.size())
+ }
+ if (c.size()) {
arr[Mesh::ARRAY_COLOR] = c;
- if (u.size())
+ }
+ if (u.size()) {
arr[Mesh::ARRAY_TEX_UV] = u;
- if (u2.size())
+ }
+ if (u2.size()) {
arr[Mesh::ARRAY_TEX_UV2] = u2;
- if (t.size())
+ }
+ if (t.size()) {
arr[Mesh::ARRAY_TANGENT] = t;
- if (b.size())
+ }
+ if (b.size()) {
arr[Mesh::ARRAY_BONES] = b;
- if (w.size())
+ }
+ if (w.size()) {
arr[Mesh::ARRAY_WEIGHTS] = w;
+ }
Ref<ArrayMesh> ncmesh = p_mesh;
int sc = ncmesh->get_surface_count();
@@ -318,111 +328,102 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
}
int MeshDataTool::get_format() const {
-
return format;
}
int MeshDataTool::get_vertex_count() const {
-
return vertices.size();
}
-int MeshDataTool::get_edge_count() const {
+int MeshDataTool::get_edge_count() const {
return edges.size();
}
-int MeshDataTool::get_face_count() const {
+int MeshDataTool::get_face_count() const {
return faces.size();
}
Vector3 MeshDataTool::get_vertex(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector3());
return vertices[p_idx].vertex;
}
-void MeshDataTool::set_vertex(int p_idx, const Vector3 &p_vertex) {
+void MeshDataTool::set_vertex(int p_idx, const Vector3 &p_vertex) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].vertex = p_vertex;
}
Vector3 MeshDataTool::get_vertex_normal(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector3());
return vertices[p_idx].normal;
}
-void MeshDataTool::set_vertex_normal(int p_idx, const Vector3 &p_normal) {
+void MeshDataTool::set_vertex_normal(int p_idx, const Vector3 &p_normal) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].normal = p_normal;
format |= Mesh::ARRAY_FORMAT_NORMAL;
}
Plane MeshDataTool::get_vertex_tangent(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Plane());
return vertices[p_idx].tangent;
}
-void MeshDataTool::set_vertex_tangent(int p_idx, const Plane &p_tangent) {
+void MeshDataTool::set_vertex_tangent(int p_idx, const Plane &p_tangent) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].tangent = p_tangent;
format |= Mesh::ARRAY_FORMAT_TANGENT;
}
Vector2 MeshDataTool::get_vertex_uv(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector2());
return vertices[p_idx].uv;
}
-void MeshDataTool::set_vertex_uv(int p_idx, const Vector2 &p_uv) {
+void MeshDataTool::set_vertex_uv(int p_idx, const Vector2 &p_uv) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].uv = p_uv;
format |= Mesh::ARRAY_FORMAT_TEX_UV;
}
Vector2 MeshDataTool::get_vertex_uv2(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector2());
return vertices[p_idx].uv2;
}
-void MeshDataTool::set_vertex_uv2(int p_idx, const Vector2 &p_uv2) {
+void MeshDataTool::set_vertex_uv2(int p_idx, const Vector2 &p_uv2) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].uv2 = p_uv2;
format |= Mesh::ARRAY_FORMAT_TEX_UV2;
}
Color MeshDataTool::get_vertex_color(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Color());
return vertices[p_idx].color;
}
-void MeshDataTool::set_vertex_color(int p_idx, const Color &p_color) {
+void MeshDataTool::set_vertex_color(int p_idx, const Color &p_color) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].color = p_color;
format |= Mesh::ARRAY_FORMAT_COLOR;
}
Vector<int> MeshDataTool::get_vertex_bones(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector<int>());
return vertices[p_idx].bones;
}
-void MeshDataTool::set_vertex_bones(int p_idx, const Vector<int> &p_bones) {
+void MeshDataTool::set_vertex_bones(int p_idx, const Vector<int> &p_bones) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].bones = p_bones;
format |= Mesh::ARRAY_FORMAT_BONES;
}
Vector<float> MeshDataTool::get_vertex_weights(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector<float>());
return vertices[p_idx].weights;
}
+
void MeshDataTool::set_vertex_weights(int p_idx, const Vector<float> &p_weights) {
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].weights = p_weights;
@@ -430,75 +431,69 @@ void MeshDataTool::set_vertex_weights(int p_idx, const Vector<float> &p_weights)
}
Variant MeshDataTool::get_vertex_meta(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Variant());
return vertices[p_idx].meta;
}
void MeshDataTool::set_vertex_meta(int p_idx, const Variant &p_meta) {
-
ERR_FAIL_INDEX(p_idx, vertices.size());
vertices.write[p_idx].meta = p_meta;
}
Vector<int> MeshDataTool::get_vertex_edges(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector<int>());
return vertices[p_idx].edges;
}
-Vector<int> MeshDataTool::get_vertex_faces(int p_idx) const {
+Vector<int> MeshDataTool::get_vertex_faces(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, vertices.size(), Vector<int>());
return vertices[p_idx].faces;
}
int MeshDataTool::get_edge_vertex(int p_edge, int p_vertex) const {
-
ERR_FAIL_INDEX_V(p_edge, edges.size(), -1);
ERR_FAIL_INDEX_V(p_vertex, 2, -1);
return edges[p_edge].vertex[p_vertex];
}
-Vector<int> MeshDataTool::get_edge_faces(int p_edge) const {
+Vector<int> MeshDataTool::get_edge_faces(int p_edge) const {
ERR_FAIL_INDEX_V(p_edge, edges.size(), Vector<int>());
return edges[p_edge].faces;
}
-Variant MeshDataTool::get_edge_meta(int p_idx) const {
+Variant MeshDataTool::get_edge_meta(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, edges.size(), Variant());
return edges[p_idx].meta;
}
-void MeshDataTool::set_edge_meta(int p_idx, const Variant &p_meta) {
+void MeshDataTool::set_edge_meta(int p_idx, const Variant &p_meta) {
ERR_FAIL_INDEX(p_idx, edges.size());
edges.write[p_idx].meta = p_meta;
}
int MeshDataTool::get_face_vertex(int p_face, int p_vertex) const {
-
ERR_FAIL_INDEX_V(p_face, faces.size(), -1);
ERR_FAIL_INDEX_V(p_vertex, 3, -1);
return faces[p_face].v[p_vertex];
}
-int MeshDataTool::get_face_edge(int p_face, int p_vertex) const {
+int MeshDataTool::get_face_edge(int p_face, int p_vertex) const {
ERR_FAIL_INDEX_V(p_face, faces.size(), -1);
ERR_FAIL_INDEX_V(p_vertex, 3, -1);
return faces[p_face].edges[p_vertex];
}
-Variant MeshDataTool::get_face_meta(int p_face) const {
+Variant MeshDataTool::get_face_meta(int p_face) const {
ERR_FAIL_INDEX_V(p_face, faces.size(), Variant());
return faces[p_face].meta;
}
-void MeshDataTool::set_face_meta(int p_face, const Variant &p_meta) {
+void MeshDataTool::set_face_meta(int p_face, const Variant &p_meta) {
ERR_FAIL_INDEX(p_face, faces.size());
faces.write[p_face].meta = p_meta;
}
Vector3 MeshDataTool::get_face_normal(int p_face) const {
-
ERR_FAIL_INDEX_V(p_face, faces.size(), Vector3());
Vector3 v0 = vertices[faces[p_face].v[0]].vertex;
Vector3 v1 = vertices[faces[p_face].v[1]].vertex;
@@ -508,17 +503,14 @@ Vector3 MeshDataTool::get_face_normal(int p_face) const {
}
Ref<Material> MeshDataTool::get_material() const {
-
return material;
}
void MeshDataTool::set_material(const Ref<Material> &p_material) {
-
material = p_material;
}
void MeshDataTool::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("clear"), &MeshDataTool::clear);
ClassDB::bind_method(D_METHOD("create_from_surface", "mesh", "surface"), &MeshDataTool::create_from_surface);
ClassDB::bind_method(D_METHOD("commit_to_surface", "mesh"), &MeshDataTool::commit_to_surface);
@@ -578,6 +570,5 @@ void MeshDataTool::_bind_methods() {
}
MeshDataTool::MeshDataTool() {
-
clear();
}
diff --git a/scene/resources/mesh_data_tool.h b/scene/resources/mesh_data_tool.h
index 5ac2c7e702..bf9f0dd25f 100644
--- a/scene/resources/mesh_data_tool.h
+++ b/scene/resources/mesh_data_tool.h
@@ -34,7 +34,6 @@
#include "scene/resources/mesh.h"
class MeshDataTool : public Reference {
-
GDCLASS(MeshDataTool, Reference);
int format;
@@ -55,7 +54,6 @@ class MeshDataTool : public Reference {
Vector<Vertex> vertices;
struct Edge {
-
int vertex[2];
Vector<int> faces;
Variant meta;
@@ -64,7 +62,6 @@ class MeshDataTool : public Reference {
Vector<Edge> edges;
struct Face {
-
int v[3];
int edges[3];
Variant meta;
diff --git a/scene/resources/mesh_library.cpp b/scene/resources/mesh_library.cpp
index fffd192348..09b0d4b038 100644
--- a/scene/resources/mesh_library.cpp
+++ b/scene/resources/mesh_library.cpp
@@ -31,20 +31,19 @@
#include "mesh_library.h"
bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name.begins_with("item/")) {
-
int idx = name.get_slicec('/', 1).to_int();
String what = name.get_slicec('/', 2);
- if (!item_map.has(idx))
+ if (!item_map.has(idx)) {
create_item(idx);
+ }
- if (what == "name")
+ if (what == "name") {
set_item_name(idx, p_value);
- else if (what == "mesh")
+ } else if (what == "mesh") {
set_item_mesh(idx, p_value);
- else if (what == "shape") {
+ } else if (what == "shape") {
Vector<ShapeData> shapes;
ShapeData sd;
sd.shape = p_value;
@@ -52,14 +51,15 @@ bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) {
set_item_shapes(idx, shapes);
} else if (what == "shapes") {
_set_item_shapes(idx, p_value);
- } else if (what == "preview")
+ } else if (what == "preview") {
set_item_preview(idx, p_value);
- else if (what == "navmesh")
+ } else if (what == "navmesh") {
set_item_navmesh(idx, p_value);
- else if (what == "navmesh_transform")
+ } else if (what == "navmesh_transform") {
set_item_navmesh_transform(idx, p_value);
- else
+ } else {
return false;
+ }
return true;
}
@@ -68,34 +68,32 @@ bool MeshLibrary::_set(const StringName &p_name, const Variant &p_value) {
}
bool MeshLibrary::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
int idx = name.get_slicec('/', 1).to_int();
ERR_FAIL_COND_V(!item_map.has(idx), false);
String what = name.get_slicec('/', 2);
- if (what == "name")
+ if (what == "name") {
r_ret = get_item_name(idx);
- else if (what == "mesh")
+ } else if (what == "mesh") {
r_ret = get_item_mesh(idx);
- else if (what == "shapes")
+ } else if (what == "shapes") {
r_ret = _get_item_shapes(idx);
- else if (what == "navmesh")
+ } else if (what == "navmesh") {
r_ret = get_item_navmesh(idx);
- else if (what == "navmesh_transform")
+ } else if (what == "navmesh_transform") {
r_ret = get_item_navmesh_transform(idx);
- else if (what == "preview")
+ } else if (what == "preview") {
r_ret = get_item_preview(idx);
- else
+ } else {
return false;
+ }
return true;
}
void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
-
for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) {
-
String name = "item/" + itos(E->key()) + "/";
p_list->push_back(PropertyInfo(Variant::STRING, name + "name"));
p_list->push_back(PropertyInfo(Variant::OBJECT, name + "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"));
@@ -108,7 +106,6 @@ void MeshLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
}
void MeshLibrary::create_item(int p_item) {
-
ERR_FAIL_COND(p_item < 0);
ERR_FAIL_COND(item_map.has(p_item));
item_map[p_item] = Item();
@@ -116,7 +113,6 @@ void MeshLibrary::create_item(int p_item) {
}
void MeshLibrary::set_item_name(int p_item, const String &p_name) {
-
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].name = p_name;
emit_changed();
@@ -124,7 +120,6 @@ void MeshLibrary::set_item_name(int p_item, const String &p_name) {
}
void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) {
-
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].mesh = p_mesh;
notify_change_to_owners();
@@ -133,7 +128,6 @@ void MeshLibrary::set_item_mesh(int p_item, const Ref<Mesh> &p_mesh) {
}
void MeshLibrary::set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes) {
-
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].shapes = p_shapes;
_change_notify();
@@ -143,7 +137,6 @@ void MeshLibrary::set_item_shapes(int p_item, const Vector<ShapeData> &p_shapes)
}
void MeshLibrary::set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navmesh) {
-
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].navmesh = p_navmesh;
_change_notify();
@@ -153,7 +146,6 @@ void MeshLibrary::set_item_navmesh(int p_item, const Ref<NavigationMesh> &p_navm
}
void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_transform) {
-
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].navmesh_transform = p_transform;
notify_change_to_owners();
@@ -162,7 +154,6 @@ void MeshLibrary::set_item_navmesh_transform(int p_item, const Transform &p_tran
}
void MeshLibrary::set_item_preview(int p_item, const Ref<Texture2D> &p_preview) {
-
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map[p_item].preview = p_preview;
emit_changed();
@@ -170,47 +161,40 @@ void MeshLibrary::set_item_preview(int p_item, const Ref<Texture2D> &p_preview)
}
String MeshLibrary::get_item_name(int p_item) const {
-
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), "", "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].name;
}
Ref<Mesh> MeshLibrary::get_item_mesh(int p_item) const {
-
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<Mesh>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].mesh;
}
Vector<MeshLibrary::ShapeData> MeshLibrary::get_item_shapes(int p_item) const {
-
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Vector<ShapeData>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].shapes;
}
Ref<NavigationMesh> MeshLibrary::get_item_navmesh(int p_item) const {
-
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<NavigationMesh>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].navmesh;
}
Transform MeshLibrary::get_item_navmesh_transform(int p_item) const {
-
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Transform(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].navmesh_transform;
}
Ref<Texture2D> MeshLibrary::get_item_preview(int p_item) const {
-
ERR_FAIL_COND_V_MSG(!item_map.has(p_item), Ref<Texture2D>(), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
return item_map[p_item].preview;
}
bool MeshLibrary::has_item(int p_item) const {
-
return item_map.has(p_item);
}
-void MeshLibrary::remove_item(int p_item) {
+void MeshLibrary::remove_item(int p_item) {
ERR_FAIL_COND_MSG(!item_map.has(p_item), "Requested for nonexistent MeshLibrary item '" + itos(p_item) + "'.");
item_map.erase(p_item);
notify_change_to_owners();
@@ -219,7 +203,6 @@ void MeshLibrary::remove_item(int p_item) {
}
void MeshLibrary::clear() {
-
item_map.clear();
notify_change_to_owners();
_change_notify();
@@ -227,12 +210,10 @@ void MeshLibrary::clear() {
}
Vector<int> MeshLibrary::get_item_list() const {
-
Vector<int> ret;
ret.resize(item_map.size());
int idx = 0;
for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) {
-
ret.write[idx++] = E->key();
}
@@ -240,25 +221,23 @@ Vector<int> MeshLibrary::get_item_list() const {
}
int MeshLibrary::find_item_by_name(const String &p_name) const {
-
for (Map<int, Item>::Element *E = item_map.front(); E; E = E->next()) {
-
- if (E->get().name == p_name)
+ if (E->get().name == p_name) {
return E->key();
+ }
}
return -1;
}
int MeshLibrary::get_last_unused_item_id() const {
-
- if (!item_map.size())
+ if (!item_map.size()) {
return 0;
- else
+ } else {
return item_map.back()->key() + 1;
+ }
}
void MeshLibrary::_set_item_shapes(int p_item, const Array &p_shapes) {
-
ERR_FAIL_COND(p_shapes.size() & 1);
Vector<ShapeData> shapes;
for (int i = 0; i < p_shapes.size(); i += 2) {
@@ -275,7 +254,6 @@ void MeshLibrary::_set_item_shapes(int p_item, const Array &p_shapes) {
}
Array MeshLibrary::_get_item_shapes(int p_item) const {
-
Vector<ShapeData> shapes = get_item_shapes(p_item);
Array ret;
for (int i = 0; i < shapes.size(); i++) {
@@ -287,7 +265,6 @@ Array MeshLibrary::_get_item_shapes(int p_item) const {
}
void MeshLibrary::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("create_item", "id"), &MeshLibrary::create_item);
ClassDB::bind_method(D_METHOD("set_item_name", "id", "name"), &MeshLibrary::set_item_name);
ClassDB::bind_method(D_METHOD("set_item_mesh", "id", "mesh"), &MeshLibrary::set_item_mesh);
@@ -311,5 +288,6 @@ void MeshLibrary::_bind_methods() {
MeshLibrary::MeshLibrary() {
}
+
MeshLibrary::~MeshLibrary() {
}
diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h
index 55001f2545..7b78398669 100644
--- a/scene/resources/mesh_library.h
+++ b/scene/resources/mesh_library.h
@@ -38,7 +38,6 @@
#include "shape_3d.h"
class MeshLibrary : public Resource {
-
GDCLASS(MeshLibrary, Resource);
RES_BASE_EXTENSION("meshlib");
diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp
index ce561bfaaf..f71cf383e5 100644
--- a/scene/resources/multimesh.cpp
+++ b/scene/resources/multimesh.cpp
@@ -36,19 +36,20 @@
// Kept for compatibility from 3.x to 4.0.
void MultiMesh::_set_transform_array(const Vector<Vector3> &p_array) {
- if (transform_format != TRANSFORM_3D)
+ if (transform_format != TRANSFORM_3D) {
return;
+ }
const Vector<Vector3> &xforms = p_array;
int len = xforms.size();
ERR_FAIL_COND((len / 4) != instance_count);
- if (len == 0)
+ if (len == 0) {
return;
+ }
const Vector3 *r = xforms.ptr();
for (int i = 0; i < len / 4; i++) {
-
Transform t;
t.basis[0] = r[i * 4 + 0];
t.basis[1] = r[i * 4 + 1];
@@ -60,12 +61,13 @@ void MultiMesh::_set_transform_array(const Vector<Vector3> &p_array) {
}
Vector<Vector3> MultiMesh::_get_transform_array() const {
-
- if (transform_format != TRANSFORM_3D)
+ if (transform_format != TRANSFORM_3D) {
return Vector<Vector3>();
+ }
- if (instance_count == 0)
+ if (instance_count == 0) {
return Vector<Vector3>();
+ }
Vector<Vector3> xforms;
xforms.resize(instance_count * 4);
@@ -73,7 +75,6 @@ Vector<Vector3> MultiMesh::_get_transform_array() const {
Vector3 *w = xforms.ptrw();
for (int i = 0; i < instance_count; i++) {
-
Transform t = get_instance_transform(i);
w[i * 4 + 0] = t.basis[0];
w[i * 4 + 1] = t.basis[1];
@@ -85,20 +86,20 @@ Vector<Vector3> MultiMesh::_get_transform_array() const {
}
void MultiMesh::_set_transform_2d_array(const Vector<Vector2> &p_array) {
-
- if (transform_format != TRANSFORM_2D)
+ if (transform_format != TRANSFORM_2D) {
return;
+ }
const Vector<Vector2> &xforms = p_array;
int len = xforms.size();
ERR_FAIL_COND((len / 3) != instance_count);
- if (len == 0)
+ if (len == 0) {
return;
+ }
const Vector2 *r = xforms.ptr();
for (int i = 0; i < len / 3; i++) {
-
Transform2D t;
t.elements[0] = r[i * 3 + 0];
t.elements[1] = r[i * 3 + 1];
@@ -109,12 +110,13 @@ void MultiMesh::_set_transform_2d_array(const Vector<Vector2> &p_array) {
}
Vector<Vector2> MultiMesh::_get_transform_2d_array() const {
-
- if (transform_format != TRANSFORM_2D)
+ if (transform_format != TRANSFORM_2D) {
return Vector<Vector2>();
+ }
- if (instance_count == 0)
+ if (instance_count == 0) {
return Vector<Vector2>();
+ }
Vector<Vector2> xforms;
xforms.resize(instance_count * 3);
@@ -122,7 +124,6 @@ Vector<Vector2> MultiMesh::_get_transform_2d_array() const {
Vector2 *w = xforms.ptrw();
for (int i = 0; i < instance_count; i++) {
-
Transform2D t = get_instance_transform_2d(i);
w[i * 3 + 0] = t.elements[0];
w[i * 3 + 1] = t.elements[1];
@@ -133,31 +134,29 @@ Vector<Vector2> MultiMesh::_get_transform_2d_array() const {
}
void MultiMesh::_set_color_array(const Vector<Color> &p_array) {
-
const Vector<Color> &colors = p_array;
int len = colors.size();
- if (len == 0)
+ if (len == 0) {
return;
+ }
ERR_FAIL_COND(len != instance_count);
const Color *r = colors.ptr();
for (int i = 0; i < len; i++) {
-
set_instance_color(i, r[i]);
}
}
Vector<Color> MultiMesh::_get_color_array() const {
-
- if (instance_count == 0 || !use_colors)
+ if (instance_count == 0 || !use_colors) {
return Vector<Color>();
+ }
Vector<Color> colors;
colors.resize(instance_count);
for (int i = 0; i < instance_count; i++) {
-
colors.set(i, get_instance_color(i));
}
@@ -165,31 +164,29 @@ Vector<Color> MultiMesh::_get_color_array() const {
}
void MultiMesh::_set_custom_data_array(const Vector<Color> &p_array) {
-
const Vector<Color> &custom_datas = p_array;
int len = custom_datas.size();
- if (len == 0)
+ if (len == 0) {
return;
+ }
ERR_FAIL_COND(len != instance_count);
const Color *r = custom_datas.ptr();
for (int i = 0; i < len; i++) {
-
set_instance_custom_data(i, r[i]);
}
}
Vector<Color> MultiMesh::_get_custom_data_array() const {
-
- if (instance_count == 0 || !use_custom_data)
+ if (instance_count == 0 || !use_custom_data) {
return Vector<Color>();
+ }
Vector<Color> custom_datas;
custom_datas.resize(instance_count);
for (int i = 0; i < instance_count; i++) {
-
custom_datas.set(i, get_instance_custom_data(i));
}
@@ -206,16 +203,15 @@ Vector<float> MultiMesh::get_buffer() const {
}
void MultiMesh::set_mesh(const Ref<Mesh> &p_mesh) {
-
mesh = p_mesh;
- if (!mesh.is_null())
+ if (!mesh.is_null()) {
RenderingServer::get_singleton()->multimesh_set_mesh(multimesh, mesh->get_rid());
- else
+ } else {
RenderingServer::get_singleton()->multimesh_set_mesh(multimesh, RID());
+ }
}
Ref<Mesh> MultiMesh::get_mesh() const {
-
return mesh;
}
@@ -224,8 +220,8 @@ void MultiMesh::set_instance_count(int p_count) {
RenderingServer::get_singleton()->multimesh_allocate(multimesh, p_count, RS::MultimeshTransformFormat(transform_format), use_colors, use_custom_data);
instance_count = p_count;
}
-int MultiMesh::get_instance_count() const {
+int MultiMesh::get_instance_count() const {
return instance_count;
}
@@ -235,56 +231,48 @@ void MultiMesh::set_visible_instance_count(int p_count) {
RenderingServer::get_singleton()->multimesh_set_visible_instances(multimesh, p_count);
visible_instance_count = p_count;
}
-int MultiMesh::get_visible_instance_count() const {
+int MultiMesh::get_visible_instance_count() const {
return visible_instance_count;
}
void MultiMesh::set_instance_transform(int p_instance, const Transform &p_transform) {
-
RenderingServer::get_singleton()->multimesh_instance_set_transform(multimesh, p_instance, p_transform);
}
void MultiMesh::set_instance_transform_2d(int p_instance, const Transform2D &p_transform) {
-
RenderingServer::get_singleton()->multimesh_instance_set_transform_2d(multimesh, p_instance, p_transform);
}
Transform MultiMesh::get_instance_transform(int p_instance) const {
-
return RenderingServer::get_singleton()->multimesh_instance_get_transform(multimesh, p_instance);
}
Transform2D MultiMesh::get_instance_transform_2d(int p_instance) const {
-
return RenderingServer::get_singleton()->multimesh_instance_get_transform_2d(multimesh, p_instance);
}
void MultiMesh::set_instance_color(int p_instance, const Color &p_color) {
-
RenderingServer::get_singleton()->multimesh_instance_set_color(multimesh, p_instance, p_color);
}
-Color MultiMesh::get_instance_color(int p_instance) const {
+Color MultiMesh::get_instance_color(int p_instance) const {
return RenderingServer::get_singleton()->multimesh_instance_get_color(multimesh, p_instance);
}
void MultiMesh::set_instance_custom_data(int p_instance, const Color &p_custom_data) {
-
RenderingServer::get_singleton()->multimesh_instance_set_custom_data(multimesh, p_instance, p_custom_data);
}
-Color MultiMesh::get_instance_custom_data(int p_instance) const {
+Color MultiMesh::get_instance_custom_data(int p_instance) const {
return RenderingServer::get_singleton()->multimesh_instance_get_custom_data(multimesh, p_instance);
}
AABB MultiMesh::get_aabb() const {
-
return RenderingServer::get_singleton()->multimesh_get_aabb(multimesh);
}
RID MultiMesh::get_rid() const {
-
return multimesh;
}
@@ -307,17 +295,15 @@ bool MultiMesh::is_using_custom_data() const {
}
void MultiMesh::set_transform_format(TransformFormat p_transform_format) {
-
ERR_FAIL_COND(instance_count > 0);
transform_format = p_transform_format;
}
-MultiMesh::TransformFormat MultiMesh::get_transform_format() const {
+MultiMesh::TransformFormat MultiMesh::get_transform_format() const {
return transform_format;
}
void MultiMesh::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_mesh", "mesh"), &MultiMesh::set_mesh);
ClassDB::bind_method(D_METHOD("get_mesh"), &MultiMesh::get_mesh);
ClassDB::bind_method(D_METHOD("set_use_colors", "enable"), &MultiMesh::set_use_colors);
@@ -374,7 +360,6 @@ void MultiMesh::_bind_methods() {
}
MultiMesh::MultiMesh() {
-
multimesh = RenderingServer::get_singleton()->multimesh_create();
use_colors = false;
use_custom_data = false;
@@ -384,6 +369,5 @@ MultiMesh::MultiMesh() {
}
MultiMesh::~MultiMesh() {
-
RenderingServer::get_singleton()->free(multimesh);
}
diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h
index c1e52bc981..8478789d41 100644
--- a/scene/resources/multimesh.h
+++ b/scene/resources/multimesh.h
@@ -35,7 +35,6 @@
#include "servers/rendering_server.h"
class MultiMesh : public Resource {
-
GDCLASS(MultiMesh, Resource);
RES_BASE_EXTENSION("multimesh");
diff --git a/scene/resources/navigation_mesh.cpp b/scene/resources/navigation_mesh.cpp
index e0aff2182e..e815da5d45 100644
--- a/scene/resources/navigation_mesh.cpp
+++ b/scene/resources/navigation_mesh.cpp
@@ -31,19 +31,19 @@
#include "navigation_mesh.h"
void NavigationMesh::create_from_mesh(const Ref<Mesh> &p_mesh) {
-
vertices = Vector<Vector3>();
clear_polygons();
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
-
- if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
+ if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
continue;
+ }
Array arr = p_mesh->surface_get_arrays(i);
Vector<Vector3> varr = arr[Mesh::ARRAY_VERTEX];
Vector<int> iarr = arr[Mesh::ARRAY_INDEX];
- if (varr.size() == 0 || iarr.size() == 0)
+ if (varr.size() == 0 || iarr.size() == 0) {
continue;
+ }
int from = vertices.size();
vertices.append_array(varr);
@@ -82,27 +82,24 @@ int NavigationMesh::get_parsed_geometry_type() const {
}
void NavigationMesh::set_collision_mask(uint32_t p_mask) {
-
collision_mask = p_mask;
}
uint32_t NavigationMesh::get_collision_mask() const {
-
return collision_mask;
}
void NavigationMesh::set_collision_mask_bit(int p_bit, bool p_value) {
-
uint32_t mask = get_collision_mask();
- if (p_value)
+ if (p_value) {
mask |= 1 << p_bit;
- else
+ } else {
mask &= ~(1 << p_bit);
+ }
set_collision_mask(mask);
}
bool NavigationMesh::get_collision_mask_bit(int p_bit) const {
-
return get_collision_mask() & (1 << p_bit);
}
@@ -253,18 +250,15 @@ bool NavigationMesh::get_filter_walkable_low_height_spans() const {
}
void NavigationMesh::set_vertices(const Vector<Vector3> &p_vertices) {
-
vertices = p_vertices;
_change_notify();
}
Vector<Vector3> NavigationMesh::get_vertices() const {
-
return vertices;
}
void NavigationMesh::_set_polygons(const Array &p_array) {
-
polygons.resize(p_array.size());
for (int i = 0; i < p_array.size(); i++) {
polygons.write[i].indices = p_array[i];
@@ -273,7 +267,6 @@ void NavigationMesh::_set_polygons(const Array &p_array) {
}
Array NavigationMesh::_get_polygons() const {
-
Array ret;
ret.resize(polygons.size());
for (int i = 0; i < ret.size(); i++) {
@@ -284,30 +277,29 @@ Array NavigationMesh::_get_polygons() const {
}
void NavigationMesh::add_polygon(const Vector<int> &p_polygon) {
-
Polygon polygon;
polygon.indices = p_polygon;
polygons.push_back(polygon);
_change_notify();
}
-int NavigationMesh::get_polygon_count() const {
+int NavigationMesh::get_polygon_count() const {
return polygons.size();
}
-Vector<int> NavigationMesh::get_polygon(int p_idx) {
+Vector<int> NavigationMesh::get_polygon(int p_idx) {
ERR_FAIL_INDEX_V(p_idx, polygons.size(), Vector<int>());
return polygons[p_idx].indices;
}
-void NavigationMesh::clear_polygons() {
+void NavigationMesh::clear_polygons() {
polygons.clear();
}
Ref<Mesh> NavigationMesh::get_debug_mesh() {
-
- if (debug_mesh.is_valid())
+ if (debug_mesh.is_valid()) {
return debug_mesh;
+ }
Vector<Vector3> vertices = get_vertices();
const Vector3 *vr = vertices.ptr();
@@ -334,26 +326,23 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() {
int tidx = 0;
for (List<Face3>::Element *E = faces.front(); E; E = E->next()) {
-
const Face3 &f = E->get();
for (int j = 0; j < 3; j++) {
-
tw[tidx++] = f.vertex[j];
_EdgeKey ek;
ek.from = f.vertex[j].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
ek.to = f.vertex[(j + 1) % 3].snapped(Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON));
- if (ek.from < ek.to)
+ if (ek.from < ek.to) {
SWAP(ek.from, ek.to);
+ }
Map<_EdgeKey, bool>::Element *F = edge_map.find(ek);
if (F) {
-
F->get() = false;
} else {
-
edge_map[ek] = true;
}
}
@@ -362,7 +351,6 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() {
List<Vector3> lines;
for (Map<_EdgeKey, bool>::Element *E = edge_map.front(); E; E = E->next()) {
-
if (E->get()) {
lines.push_back(E->key().from);
lines.push_back(E->key().to);
diff --git a/scene/resources/navigation_mesh.h b/scene/resources/navigation_mesh.h
index cc3ac6e3fd..6b9d1964f5 100644
--- a/scene/resources/navigation_mesh.h
+++ b/scene/resources/navigation_mesh.h
@@ -36,7 +36,6 @@
class Mesh;
class NavigationMesh : public Resource {
-
GDCLASS(NavigationMesh, Resource);
Vector<Vector3> vertices;
@@ -47,7 +46,6 @@ class NavigationMesh : public Resource {
Ref<ArrayMesh> debug_mesh;
struct _EdgeKey {
-
Vector3 from;
Vector3 to;
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 633771506e..058e89cf2e 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -42,12 +42,10 @@
#define PACKED_SCENE_VERSION 2
bool SceneState::can_instance() const {
-
return nodes.size() > 0;
}
Node *SceneState::instance(GenEditState p_edit_state) const {
-
// nodes where instancing failed (because something is missing)
List<Node *> stray_instances;
@@ -66,13 +64,15 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
const StringName *snames = nullptr;
int sname_count = names.size();
- if (sname_count)
+ if (sname_count) {
snames = &names[0];
+ }
const Variant *props = nullptr;
int prop_count = variants.size();
- if (prop_count)
+ if (prop_count) {
props = &variants[0];
+ }
//Vector<Variant> properties;
@@ -85,18 +85,15 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
Map<Ref<Resource>, Ref<Resource>> resources_local_to_scene;
for (int i = 0; i < nc; i++) {
-
const NodeData &n = nd[i];
Node *parent = nullptr;
if (i > 0) {
-
ERR_FAIL_COND_V_MSG(n.parent == -1, nullptr, vformat("Invalid scene: node %s does not specify its parent node.", snames[n.name]));
NODE_FROM_ID(nparent, n.parent);
#ifdef DEBUG_ENABLED
if (!nparent && (n.parent & FLAG_ID_IS_PATH)) {
-
WARN_PRINT(String("Parent path '" + String(node_paths[n.parent & FLAG_MASK]) + "' for node '" + String(snames[n.name]) + "' has vanished when instancing: '" + get_path() + "'.").ascii().get_data());
}
#endif
@@ -118,10 +115,8 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
} else if (n.instance >= 0) {
//instance a scene into this node
if (n.instance & FLAG_INSTANCE_IS_PLACEHOLDER) {
-
String path = props[n.instance & FLAG_MASK];
if (disable_placeholders) {
-
Ref<PackedScene> sdata = ResourceLoader::load(path, "PackedScene");
ERR_FAIL_COND_V(!sdata.is_valid(), nullptr);
node = sdata->instance(p_edit_state == GEN_EDIT_STATE_DISABLED ? PackedScene::GEN_EDIT_STATE_DISABLED : PackedScene::GEN_EDIT_STATE_INSTANCE);
@@ -187,11 +182,9 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
//properties
int nprop_count = n.properties.size();
if (nprop_count) {
-
const NodeData::Property *nprops = &n.properties[0];
for (int j = 0; j < nprop_count; j++) {
-
bool valid;
ERR_FAIL_INDEX_V(nprops[j].name, sname_count, nullptr);
ERR_FAIL_INDEX_V(nprops[j].value, prop_count, nullptr);
@@ -213,7 +206,6 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
node->set(E->get().first, E->get().second);
}
} else {
-
Variant value = props[nprops[j].value];
if (value.get_type() == Variant::OBJECT) {
@@ -221,13 +213,11 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
Ref<Resource> res = value;
if (res.is_valid()) {
if (res->is_local_to_scene()) {
-
Map<Ref<Resource>, Ref<Resource>>::Element *E = resources_local_to_scene.find(res);
if (E) {
value = E->get();
} else {
-
Node *base = i == 0 ? node : ret_nodes[0];
if (p_edit_state == GEN_EDIT_STATE_MAIN) {
@@ -259,7 +249,6 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
//groups
for (int j = 0; j < n.groups.size(); j++) {
-
ERR_FAIL_INDEX_V(n.groups[j], sname_count, nullptr);
node->add_to_group(snames[n.groups[j]], true);
}
@@ -269,8 +258,9 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
if (i > 0) {
if (parent) {
parent->_add_child_nocheck(node, snames[n.name]);
- if (n.index >= 0 && n.index < parent->get_child_count() - 1)
+ if (n.index >= 0 && n.index < parent->get_child_count() - 1) {
parent->move_child(node, n.index);
+ }
} else {
//it may be possible that an instanced scene has changed
//and the node has nowhere to go anymore
@@ -287,10 +277,10 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
}
if (n.owner >= 0) {
-
NODE_FROM_ID(owner, n.owner);
- if (owner)
+ if (owner) {
node->_set_owner_nocheck(owner);
+ }
}
}
@@ -303,7 +293,6 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
}
for (Map<Ref<Resource>, Ref<Resource>>::Element *E = resources_local_to_scene.front(); E; E = E->next()) {
-
E->get()->setup_local_to_scene();
}
@@ -313,7 +302,6 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
const ConnectionData *cdata = connections.ptr();
for (int i = 0; i < cc; i++) {
-
const ConnectionData &c = cdata[i];
//ERR_FAIL_INDEX_V( c.from, nc, nullptr );
//ERR_FAIL_INDEX_V( c.to, nc, nullptr );
@@ -321,14 +309,16 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
NODE_FROM_ID(cfrom, c.from);
NODE_FROM_ID(cto, c.to);
- if (!cfrom || !cto)
+ if (!cfrom || !cto) {
continue;
+ }
Vector<Variant> binds;
if (c.binds.size()) {
binds.resize(c.binds.size());
- for (int j = 0; j < c.binds.size(); j++)
+ for (int j = 0; j < c.binds.size(); j++) {
binds.write[j] = props[c.binds[j]];
+ }
}
cfrom->connect(snames[c.signal], Callable(cto, snames[c.method]), binds, CONNECT_PERSIST | c.flags);
@@ -353,9 +343,9 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
}
static int _nm_get_string(const String &p_string, Map<StringName, int> &name_map) {
-
- if (name_map.has(p_string))
+ if (name_map.has(p_string)) {
return name_map[p_string];
+ }
int idx = name_map.size();
name_map[p_string] = idx;
@@ -363,9 +353,9 @@ static int _nm_get_string(const String &p_string, Map<StringName, int> &name_map
}
static int _vm_get_variant(const Variant &p_variant, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map) {
-
- if (variant_map.has(p_variant))
+ if (variant_map.has(p_variant)) {
return variant_map[p_variant];
+ }
int idx = variant_map.size();
variant_map[p_variant] = idx;
@@ -373,20 +363,21 @@ static int _vm_get_variant(const Variant &p_variant, HashMap<Variant, int, Varia
}
Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map<StringName, int> &name_map, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map, Map<Node *, int> &node_map, Map<Node *, int> &nodepath_map) {
-
// this function handles all the work related to properly packing scenes, be it
// instanced or inherited.
// given the complexity of this process, an attempt will be made to properly
// document it. if you fail to understand something, please ask!
//discard nodes that do not belong to be processed
- if (p_node != p_owner && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner()))
+ if (p_node != p_owner && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner())) {
return OK;
+ }
// save the child instanced scenes that are chosen as editable, so they can be restored
// upon load back
- if (p_node != p_owner && p_node->get_filename() != String() && p_owner->is_editable_instance(p_node))
+ if (p_node != p_owner && p_node->get_filename() != String() && p_owner->is_editable_instance(p_node)) {
editable_instances.push_back(p_owner->get_path_to(p_node));
+ }
NodeData nd;
@@ -418,9 +409,7 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
Node *n = p_node;
while (n) {
-
if (n == p_owner) {
-
Ref<SceneState> state = n->get_scene_inherited_state();
if (state.is_valid()) {
int node = state->find_node_by_path(n->get_path_to(p_node));
@@ -435,7 +424,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
if (p_node->get_filename() != String() && p_node->get_owner() == p_owner && instanced_by_owner) {
-
if (p_node->get_scene_instance_load_placeholder()) {
//it's a placeholder, use the placeholder path
nd.instance = _vm_get_variant(p_node->get_filename(), variant_map);
@@ -479,7 +467,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
StringName type = p_node->get_class();
for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
-
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
}
@@ -530,17 +517,16 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
if (exists) {
-
//check if already exists and did not change
if (value.get_type() == Variant::FLOAT && original.get_type() == Variant::FLOAT) {
//this must be done because, as some scenes save as text, there might be a tiny difference in floats due to numerical error
float a = value;
float b = original;
- if (Math::is_equal_approx(a, b))
+ if (Math::is_equal_approx(a, b)) {
continue;
+ }
} else if (bool(Variant::evaluate(Variant::OP_EQUAL, value, original))) {
-
continue;
}
}
@@ -552,7 +538,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
} else {
-
if (isdefault) {
//it's the default value, no point in saving it
continue;
@@ -573,8 +558,9 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
for (List<Node::GroupInfo>::Element *E = groups.front(); E; E = E->next()) {
Node::GroupInfo &gi = E->get();
- if (!gi.persistent)
+ if (!gi.persistent) {
continue;
+ }
/*
if (instance_state_node>=0 && instance_state->is_node_in_group(instance_state_node,gi.name))
continue; //group was instanced, don't add here
@@ -590,8 +576,9 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
}
- if (skip)
+ if (skip) {
continue;
+ }
nd.groups.push_back(_nm_get_string(gi.name, name_map));
}
@@ -608,7 +595,6 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
//part of saved scene
nd.owner = 0;
} else {
-
nd.owner = -1;
}
@@ -637,14 +623,12 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
int parent_node = NO_PARENT_SAVED;
if (save_node) {
-
//don't save the node if nothing and subscene
node_map[p_node] = idx;
//ok validate parent node
if (p_parent_idx == NO_PARENT_SAVED) {
-
int sidx;
if (nodepath_map.has(p_node->get_parent())) {
sidx = nodepath_map[p_node->get_parent()];
@@ -663,20 +647,20 @@ Error SceneState::_parse_node(Node *p_owner, Node *p_node, int p_parent_idx, Map
}
for (int i = 0; i < p_node->get_child_count(); i++) {
-
Node *c = p_node->get_child(i);
Error err = _parse_node(p_owner, c, parent_node, name_map, variant_map, node_map, nodepath_map);
- if (err)
+ if (err) {
return err;
+ }
}
return OK;
}
Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName, int> &name_map, HashMap<Variant, int, VariantHasher, VariantComparator> &variant_map, Map<Node *, int> &node_map, Map<Node *, int> &nodepath_map) {
-
- if (p_node != p_owner && p_node->get_owner() && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner()))
+ if (p_node != p_owner && p_node->get_owner() && p_node->get_owner() != p_owner && !p_owner->is_editable_instance(p_node->get_owner())) {
return OK;
+ }
List<MethodInfo> _signals;
p_node->get_signal_list(&_signals);
@@ -686,18 +670,17 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
//NodeData &nd = nodes[node_map[p_node]];
for (List<MethodInfo>::Element *E = _signals.front(); E; E = E->next()) {
-
List<Node::Connection> conns;
p_node->get_signal_connection_list(E->get().name, &conns);
conns.sort();
for (List<Node::Connection>::Element *F = conns.front(); F; F = F->next()) {
-
const Node::Connection &c = F->get();
- if (!(c.flags & CONNECT_PERSIST)) //only persistent connections get saved
+ if (!(c.flags & CONNECT_PERSIST)) { //only persistent connections get saved
continue;
+ }
// only connections that originate or end into main saved scene are saved
// everything else is discarded
@@ -721,16 +704,15 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
//go through ownership chain to see if this exists
while (common_parent) {
-
Ref<SceneState> ps;
- if (common_parent == p_owner)
+ if (common_parent == p_owner) {
ps = common_parent->get_scene_inherited_state();
- else
+ } else {
ps = common_parent->get_scene_instance_state();
+ }
if (ps.is_valid()) {
-
NodePath signal_from = common_parent->get_path_to(p_node);
NodePath signal_to = common_parent->get_path_to(target);
@@ -740,10 +722,11 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
}
}
- if (common_parent == p_owner)
+ if (common_parent == p_owner) {
break;
- else
+ } else {
common_parent = common_parent->get_owner();
+ }
}
if (exists) { //already exists (comes from instance or inheritance), so don't save
@@ -756,9 +739,7 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
bool exists2 = false;
while (nl) {
-
if (nl == p_owner) {
-
Ref<SceneState> state = nl->get_scene_inherited_state();
if (state.is_valid()) {
int from_node = state->find_node_by_path(nl->get_path_to(p_node));
@@ -835,7 +816,6 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
cd.signal = _nm_get_string(c.signal.get_name(), name_map);
cd.flags = c.flags;
for (int i = 0; i < c.binds.size(); i++) {
-
cd.binds.push_back(_vm_get_variant(c.binds[i], variant_map));
}
connections.push_back(cd);
@@ -843,11 +823,11 @@ Error SceneState::_parse_connections(Node *p_owner, Node *p_node, Map<StringName
}
for (int i = 0; i < p_node->get_child_count(); i++) {
-
Node *c = p_node->get_child(i);
Error err = _parse_connections(p_owner, c, name_map, variant_map, node_map, nodepath_map);
- if (err)
+ if (err) {
return err;
+ }
}
return OK;
@@ -870,7 +850,6 @@ Error SceneState::pack(Node *p_scene) {
String path = scene->get_scene_inherited_state()->get_path();
Ref<PackedScene> instance = ResourceLoader::load(path);
if (instance.is_valid()) {
-
base_scene_idx = _vm_get_variant(instance, variant_map);
}
}
@@ -891,21 +870,18 @@ Error SceneState::pack(Node *p_scene) {
names.resize(name_map.size());
for (Map<StringName, int>::Element *E = name_map.front(); E; E = E->next()) {
-
names.write[E->get()] = E->key();
}
variants.resize(variant_map.size());
const Variant *K = nullptr;
while ((K = variant_map.next(K))) {
-
int idx = variant_map[*K];
variants.write[idx] = *K;
}
node_paths.resize(nodepath_map.size());
for (Map<Node *, int>::Element *E = nodepath_map.front(); E; E = E->next()) {
-
node_paths.write[E->get()] = scene->get_path_to(E->key());
}
@@ -913,17 +889,14 @@ Error SceneState::pack(Node *p_scene) {
}
void SceneState::set_path(const String &p_path) {
-
path = p_path;
}
String SceneState::get_path() const {
-
return path;
}
void SceneState::clear() {
-
names.clear();
variants.clear();
nodes.clear();
@@ -935,9 +908,7 @@ void SceneState::clear() {
}
Ref<SceneState> SceneState::_get_base_scene_state() const {
-
if (base_scene_idx >= 0) {
-
Ref<PackedScene> ps = variants[base_scene_idx];
if (ps.is_valid()) {
return ps->get_state();
@@ -948,7 +919,6 @@ Ref<SceneState> SceneState::_get_base_scene_state() const {
}
int SceneState::find_node_by_path(const NodePath &p_node) const {
-
if (!node_path_cache.has(p_node)) {
if (_get_base_scene_state().is_valid()) {
int idx = _get_base_scene_state()->find_node_by_path(p_node);
@@ -980,7 +950,6 @@ int SceneState::find_node_by_path(const NodePath &p_node) const {
}
int SceneState::_find_base_scene_node_remap_key(int p_idx) const {
-
for (Map<int, int>::Element *E = base_scene_node_remap.front(); E; E = E->next()) {
if (E->value() == p_idx) {
return E->key();
@@ -990,7 +959,6 @@ int SceneState::_find_base_scene_node_remap_key(int p_idx) const {
}
Variant SceneState::get_property_value(int p_node, const StringName &p_property, bool &found) const {
-
found = false;
ERR_FAIL_COND_V(p_node < 0, Variant());
@@ -1019,14 +987,14 @@ Variant SceneState::get_property_value(int p_node, const StringName &p_property,
}
bool SceneState::is_node_in_group(int p_node, const StringName &p_group) const {
-
ERR_FAIL_COND_V(p_node < 0, false);
if (p_node < nodes.size()) {
const StringName *namep = names.ptr();
for (int i = 0; i < nodes[p_node].groups.size(); i++) {
- if (namep[nodes[p_node].groups[i]] == p_group)
+ if (namep[nodes[p_node].groups[i]] == p_group) {
return true;
+ }
}
}
@@ -1040,17 +1008,14 @@ bool SceneState::is_node_in_group(int p_node, const StringName &p_group) const {
bool SceneState::disable_placeholders = false;
void SceneState::set_disable_placeholders(bool p_disable) {
-
disable_placeholders = p_disable;
}
bool SceneState::is_connection(int p_node, const StringName &p_signal, int p_to_node, const StringName &p_to_method) const {
-
ERR_FAIL_COND_V(p_node < 0, false);
ERR_FAIL_COND_V(p_to_node < 0, false);
if (p_node < nodes.size() && p_to_node < nodes.size()) {
-
int signal_idx = -1;
int method_idx = -1;
for (int i = 0; i < names.size(); i++) {
@@ -1065,9 +1030,7 @@ bool SceneState::is_connection(int p_node, const StringName &p_signal, int p_to_
//signal and method strings are stored..
for (int i = 0; i < connections.size(); i++) {
-
if (connections[i].from == p_node && connections[i].to == p_to_node && connections[i].signal == signal_idx && connections[i].method == method_idx) {
-
return true;
}
}
@@ -1082,7 +1045,6 @@ bool SceneState::is_connection(int p_node, const StringName &p_signal, int p_to_
}
void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
-
ERR_FAIL_COND(!p_dictionary.has("names"));
ERR_FAIL_COND(!p_dictionary.has("variants"));
ERR_FAIL_COND(!p_dictionary.has("node_count"));
@@ -1092,8 +1054,9 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
//ERR_FAIL_COND( !p_dictionary.has("path"));
int version = 1;
- if (p_dictionary.has("version"))
+ if (p_dictionary.has("version")) {
version = p_dictionary["version"];
+ }
ERR_FAIL_COND_MSG(version > PACKED_SCENE_VERSION, "Save format version too new.");
@@ -1107,12 +1070,12 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
Vector<String> snames = p_dictionary["names"];
if (snames.size()) {
-
int namecount = snames.size();
names.resize(namecount);
const String *r = snames.ptr();
- for (int i = 0; i < names.size(); i++)
+ for (int i = 0; i < names.size(); i++) {
names.write[i] = r[i];
+ }
}
Array svariants = p_dictionary["variants"];
@@ -1121,7 +1084,6 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
int varcount = svariants.size();
variants.resize(varcount);
for (int i = 0; i < varcount; i++) {
-
variants.write[i] = svariants[i];
}
@@ -1145,13 +1107,11 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
nd.instance = r[idx++];
nd.properties.resize(r[idx++]);
for (int j = 0; j < nd.properties.size(); j++) {
-
nd.properties.write[j].name = r[idx++];
nd.properties.write[j].value = r[idx++];
}
nd.groups.resize(r[idx++]);
for (int j = 0; j < nd.groups.size(); j++) {
-
nd.groups.write[j] = r[idx++];
}
}
@@ -1171,7 +1131,6 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
cd.binds.resize(r[idx++]);
for (int j = 0; j < cd.binds.size(); j++) {
-
cd.binds.write[j] = r[idx++];
}
}
@@ -1204,16 +1163,15 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) {
}
Dictionary SceneState::get_bundled_scene() const {
-
Vector<String> rnames;
rnames.resize(names.size());
if (names.size()) {
-
String *r = rnames.ptrw();
- for (int i = 0; i < names.size(); i++)
+ for (int i = 0; i < names.size(); i++) {
r[i] = names[i];
+ }
}
Dictionary d;
@@ -1224,7 +1182,6 @@ Dictionary SceneState::get_bundled_scene() const {
d["node_count"] = nodes.size();
for (int i = 0; i < nodes.size(); i++) {
-
const NodeData &nd = nodes[i];
rnodes.push_back(nd.parent);
rnodes.push_back(nd.owner);
@@ -1237,13 +1194,11 @@ Dictionary SceneState::get_bundled_scene() const {
rnodes.push_back(nd.instance);
rnodes.push_back(nd.properties.size());
for (int j = 0; j < nd.properties.size(); j++) {
-
rnodes.push_back(nd.properties[j].name);
rnodes.push_back(nd.properties[j].value);
}
rnodes.push_back(nd.groups.size());
for (int j = 0; j < nd.groups.size(); j++) {
-
rnodes.push_back(nd.groups[j]);
}
}
@@ -1254,7 +1209,6 @@ Dictionary SceneState::get_bundled_scene() const {
d["conn_count"] = connections.size();
for (int i = 0; i < connections.size(); i++) {
-
const ConnectionData &cd = connections[i];
rconns.push_back(cd.from);
rconns.push_back(cd.to);
@@ -1262,8 +1216,9 @@ Dictionary SceneState::get_bundled_scene() const {
rconns.push_back(cd.method);
rconns.push_back(cd.flags);
rconns.push_back(cd.binds.size());
- for (int j = 0; j < cd.binds.size(); j++)
+ for (int j = 0; j < cd.binds.size(); j++) {
rconns.push_back(cd.binds[j]);
+ }
}
d["conns"] = rconns;
@@ -1291,20 +1246,18 @@ Dictionary SceneState::get_bundled_scene() const {
}
int SceneState::get_node_count() const {
-
return nodes.size();
}
StringName SceneState::get_node_type(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), StringName());
- if (nodes[p_idx].type == TYPE_INSTANCED)
+ if (nodes[p_idx].type == TYPE_INSTANCED) {
return StringName();
+ }
return names[nodes[p_idx].type];
}
StringName SceneState::get_node_name(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), StringName());
return names[nodes[p_idx].name];
}
@@ -1315,7 +1268,6 @@ int SceneState::get_node_index(int p_idx) const {
}
bool SceneState::is_node_instance_placeholder(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), false);
return nodes[p_idx].instance >= 0 && (nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER);
@@ -1325,12 +1277,12 @@ Ref<PackedScene> SceneState::get_node_instance(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, nodes.size(), Ref<PackedScene>());
if (nodes[p_idx].instance >= 0) {
- if (nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER)
+ if (nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER) {
return Ref<PackedScene>();
- else
+ } else {
return variants[nodes[p_idx].instance & FLAG_MASK];
+ }
} else if (nodes[p_idx].parent < 0 || nodes[p_idx].parent == NO_PARENT_SAVED) {
-
if (base_scene_idx >= 0) {
return variants[base_scene_idx];
}
@@ -1340,7 +1292,6 @@ Ref<PackedScene> SceneState::get_node_instance(int p_idx) const {
}
String SceneState::get_node_instance_placeholder(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), String());
if (nodes[p_idx].instance >= 0 && (nodes[p_idx].instance & FLAG_INSTANCE_IS_PLACEHOLDER)) {
@@ -1360,7 +1311,6 @@ Vector<StringName> SceneState::get_node_groups(int p_idx) const {
}
NodePath SceneState::get_node_path(int p_idx, bool p_for_parent) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), NodePath());
if (nodes[p_idx].parent < 0 || nodes[p_idx].parent == NO_PARENT_SAVED) {
@@ -1376,7 +1326,6 @@ NodePath SceneState::get_node_path(int p_idx, bool p_for_parent) const {
int nidx = p_idx;
while (true) {
if (nodes[nidx].parent == NO_PARENT_SAVED || nodes[nidx].parent < 0) {
-
sub_path.insert(0, ".");
break;
}
@@ -1405,15 +1354,16 @@ NodePath SceneState::get_node_path(int p_idx, bool p_for_parent) const {
}
int SceneState::get_node_property_count(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), -1);
return nodes[p_idx].properties.size();
}
+
StringName SceneState::get_node_property_name(int p_idx, int p_prop) const {
ERR_FAIL_INDEX_V(p_idx, nodes.size(), StringName());
ERR_FAIL_INDEX_V(p_prop, nodes[p_idx].properties.size(), StringName());
return names[nodes[p_idx].properties[p_prop].name];
}
+
Variant SceneState::get_node_property_value(int p_idx, int p_prop) const {
ERR_FAIL_INDEX_V(p_idx, nodes.size(), Variant());
ERR_FAIL_INDEX_V(p_prop, nodes[p_idx].properties.size(), Variant());
@@ -1422,10 +1372,10 @@ Variant SceneState::get_node_property_value(int p_idx, int p_prop) const {
}
NodePath SceneState::get_node_owner_path(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, nodes.size(), NodePath());
- if (nodes[p_idx].owner < 0 || nodes[p_idx].owner == NO_PARENT_SAVED)
+ if (nodes[p_idx].owner < 0 || nodes[p_idx].owner == NO_PARENT_SAVED) {
return NodePath(); //root likely
+ }
if (nodes[p_idx].owner & FLAG_ID_IS_PATH) {
return node_paths[nodes[p_idx].owner & FLAG_MASK];
} else {
@@ -1434,11 +1384,10 @@ NodePath SceneState::get_node_owner_path(int p_idx) const {
}
int SceneState::get_connection_count() const {
-
return connections.size();
}
-NodePath SceneState::get_connection_source(int p_idx) const {
+NodePath SceneState::get_connection_source(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, connections.size(), NodePath());
if (connections[p_idx].from & FLAG_ID_IS_PATH) {
return node_paths[connections[p_idx].from & FLAG_MASK];
@@ -1448,12 +1397,11 @@ NodePath SceneState::get_connection_source(int p_idx) const {
}
StringName SceneState::get_connection_signal(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, connections.size(), StringName());
return names[connections[p_idx].signal];
}
-NodePath SceneState::get_connection_target(int p_idx) const {
+NodePath SceneState::get_connection_target(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, connections.size(), NodePath());
if (connections[p_idx].to & FLAG_ID_IS_PATH) {
return node_paths[connections[p_idx].to & FLAG_MASK];
@@ -1461,20 +1409,18 @@ NodePath SceneState::get_connection_target(int p_idx) const {
return get_node_path(connections[p_idx].to & FLAG_MASK);
}
}
-StringName SceneState::get_connection_method(int p_idx) const {
+StringName SceneState::get_connection_method(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, connections.size(), StringName());
return names[connections[p_idx].method];
}
int SceneState::get_connection_flags(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, connections.size(), -1);
return connections[p_idx].flags;
}
Array SceneState::get_connection_binds(int p_idx) const {
-
ERR_FAIL_INDEX_V(p_idx, connections.size(), Array());
Array binds;
for (int i = 0; i < connections[p_idx].binds.size(); i++) {
@@ -1484,7 +1430,6 @@ Array SceneState::get_connection_binds(int p_idx) const {
}
bool SceneState::has_connection(const NodePath &p_node_from, const StringName &p_signal, const NodePath &p_node_to, const StringName &p_method) {
-
// this method cannot be const because of this
Ref<SceneState> ss = this;
@@ -1525,37 +1470,35 @@ bool SceneState::has_connection(const NodePath &p_node_from, const StringName &p
Vector<NodePath> SceneState::get_editable_instances() const {
return editable_instances;
}
+
//add
int SceneState::add_name(const StringName &p_name) {
-
names.push_back(p_name);
return names.size() - 1;
}
int SceneState::find_name(const StringName &p_name) const {
-
for (int i = 0; i < names.size(); i++) {
- if (names[i] == p_name)
+ if (names[i] == p_name) {
return i;
+ }
}
return -1;
}
int SceneState::add_value(const Variant &p_value) {
-
variants.push_back(p_value);
return variants.size() - 1;
}
int SceneState::add_node_path(const NodePath &p_path) {
-
node_paths.push_back(p_path);
return (node_paths.size() - 1) | FLAG_ID_IS_PATH;
}
-int SceneState::add_node(int p_parent, int p_owner, int p_type, int p_name, int p_instance, int p_index) {
+int SceneState::add_node(int p_parent, int p_owner, int p_type, int p_name, int p_instance, int p_index) {
NodeData nd;
nd.parent = p_parent;
nd.owner = p_owner;
@@ -1568,8 +1511,8 @@ int SceneState::add_node(int p_parent, int p_owner, int p_type, int p_name, int
return nodes.size() - 1;
}
-void SceneState::add_node_property(int p_node, int p_name, int p_value) {
+void SceneState::add_node_property(int p_node, int p_name, int p_value) {
ERR_FAIL_INDEX(p_node, nodes.size());
ERR_FAIL_INDEX(p_name, names.size());
ERR_FAIL_INDEX(p_value, variants.size());
@@ -1579,19 +1522,19 @@ void SceneState::add_node_property(int p_node, int p_name, int p_value) {
prop.value = p_value;
nodes.write[p_node].properties.push_back(prop);
}
-void SceneState::add_node_group(int p_node, int p_group) {
+void SceneState::add_node_group(int p_node, int p_group) {
ERR_FAIL_INDEX(p_node, nodes.size());
ERR_FAIL_INDEX(p_group, names.size());
nodes.write[p_node].groups.push_back(p_group);
}
-void SceneState::set_base_scene(int p_idx) {
+void SceneState::set_base_scene(int p_idx) {
ERR_FAIL_INDEX(p_idx, variants.size());
base_scene_idx = p_idx;
}
-void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, const Vector<int> &p_binds) {
+void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method, int p_flags, const Vector<int> &p_binds) {
ERR_FAIL_INDEX(p_signal, names.size());
ERR_FAIL_INDEX(p_method, names.size());
@@ -1607,24 +1550,23 @@ void SceneState::add_connection(int p_from, int p_to, int p_signal, int p_method
c.binds = p_binds;
connections.push_back(c);
}
-void SceneState::add_editable_instance(const NodePath &p_path) {
+void SceneState::add_editable_instance(const NodePath &p_path) {
editable_instances.push_back(p_path);
}
Vector<String> SceneState::_get_node_groups(int p_idx) const {
-
Vector<StringName> groups = get_node_groups(p_idx);
Vector<String> ret;
- for (int i = 0; i < groups.size(); i++)
+ for (int i = 0; i < groups.size(); i++) {
ret.push_back(groups[i]);
+ }
return ret;
}
void SceneState::_bind_methods() {
-
//unbuild API
ClassDB::bind_method(D_METHOD("get_node_count"), &SceneState::get_node_count);
@@ -1654,7 +1596,6 @@ void SceneState::_bind_methods() {
}
SceneState::SceneState() {
-
base_scene_idx = -1;
last_modified_time = 0;
}
@@ -1662,46 +1603,42 @@ SceneState::SceneState() {
////////////////
void PackedScene::_set_bundled_scene(const Dictionary &p_scene) {
-
state->set_bundled_scene(p_scene);
}
Dictionary PackedScene::_get_bundled_scene() const {
-
return state->get_bundled_scene();
}
Error PackedScene::pack(Node *p_scene) {
-
return state->pack(p_scene);
}
void PackedScene::clear() {
-
state->clear();
}
bool PackedScene::can_instance() const {
-
return state->can_instance();
}
Node *PackedScene::instance(GenEditState p_edit_state) const {
-
#ifndef TOOLS_ENABLED
ERR_FAIL_COND_V_MSG(p_edit_state != GEN_EDIT_STATE_DISABLED, nullptr, "Edit state is only for editors, does not work without tools compiled.");
#endif
Node *s = state->instance((SceneState::GenEditState)p_edit_state);
- if (!s)
+ if (!s) {
return nullptr;
+ }
if (p_edit_state != GEN_EDIT_STATE_DISABLED) {
s->set_scene_instance_state(state);
}
- if (get_path() != "" && get_path().find("::") == -1)
+ if (get_path() != "" && get_path().find("::") == -1) {
s->set_filename(get_path());
+ }
s->notification(Node::NOTIFICATION_INSTANCED);
@@ -1709,7 +1646,6 @@ Node *PackedScene::instance(GenEditState p_edit_state) const {
}
void PackedScene::replace_state(Ref<SceneState> p_by) {
-
state = p_by;
state->set_path(get_path());
#ifdef TOOLS_ENABLED
@@ -1718,7 +1654,6 @@ void PackedScene::replace_state(Ref<SceneState> p_by) {
}
void PackedScene::recreate_state() {
-
state = Ref<SceneState>(memnew(SceneState));
state->set_path(get_path());
#ifdef TOOLS_ENABLED
@@ -1727,18 +1662,15 @@ void PackedScene::recreate_state() {
}
Ref<SceneState> PackedScene::get_state() {
-
return state;
}
void PackedScene::set_path(const String &p_path, bool p_take_over) {
-
state->set_path(p_path);
Resource::set_path(p_path, p_take_over);
}
void PackedScene::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("pack", "path"), &PackedScene::pack);
ClassDB::bind_method(D_METHOD("instance", "edit_state"), &PackedScene::instance, DEFVAL(GEN_EDIT_STATE_DISABLED));
ClassDB::bind_method(D_METHOD("can_instance"), &PackedScene::can_instance);
@@ -1754,6 +1686,5 @@ void PackedScene::_bind_methods() {
}
PackedScene::PackedScene() {
-
state = Ref<SceneState>(memnew(SceneState));
}
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index c5873a0792..898d5ff11f 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -35,7 +35,6 @@
#include "scene/main/node.h"
class SceneState : public Reference {
-
GDCLASS(SceneState, Reference);
Vector<StringName> names;
@@ -54,7 +53,6 @@ class SceneState : public Reference {
};
struct NodeData {
-
int parent;
int owner;
int type;
@@ -63,7 +61,6 @@ class SceneState : public Reference {
int index;
struct Property {
-
int name;
int value;
};
@@ -81,7 +78,6 @@ class SceneState : public Reference {
Vector<NodeData> nodes;
struct ConnectionData {
-
int from;
int to;
int signal;
@@ -195,7 +191,6 @@ public:
VARIANT_ENUM_CAST(SceneState::GenEditState)
class PackedScene : public Resource {
-
GDCLASS(PackedScene, Resource);
RES_BASE_EXTENSION("scn");
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index 83430aef9e..fc92a721db 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -36,7 +36,6 @@ Map<ParticlesMaterial::MaterialKey, ParticlesMaterial::ShaderData> ParticlesMate
ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = nullptr;
void ParticlesMaterial::init_shaders() {
-
dirty_materials = memnew(SelfList<ParticlesMaterial>::List);
shader_names = memnew(ShaderNames);
@@ -102,7 +101,6 @@ void ParticlesMaterial::init_shaders() {
}
void ParticlesMaterial::finish_shaders() {
-
memdelete(dirty_materials);
dirty_materials = nullptr;
@@ -110,12 +108,12 @@ void ParticlesMaterial::finish_shaders() {
}
void ParticlesMaterial::_update_shader() {
-
dirty_materials->remove(&element);
MaterialKey mk = _compute_key();
- if (mk.key == current_key.key)
+ if (mk.key == current_key.key) {
return; //no update required in the end
+ }
if (shader_map.has(current_key)) {
shader_map[current_key].users--;
@@ -129,7 +127,6 @@ void ParticlesMaterial::_update_shader() {
current_key = mk;
if (shader_map.has(mk)) {
-
RS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader);
shader_map[mk].users++;
return;
@@ -201,33 +198,46 @@ void ParticlesMaterial::_update_shader() {
code += "uniform vec3 gravity;\n";
- if (color_ramp.is_valid())
+ if (color_ramp.is_valid()) {
code += "uniform sampler2D color_ramp;\n";
+ }
- if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
+ if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
code += "uniform sampler2D linear_velocity_texture;\n";
- if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid())
+ }
+ if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
code += "uniform sampler2D orbit_velocity_texture;\n";
- if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid())
+ }
+ if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
code += "uniform sampler2D angular_velocity_texture;\n";
- if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid())
+ }
+ if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
code += "uniform sampler2D linear_accel_texture;\n";
- if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid())
+ }
+ if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
code += "uniform sampler2D radial_accel_texture;\n";
- if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid())
+ }
+ if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
code += "uniform sampler2D tangent_accel_texture;\n";
- if (tex_parameters[PARAM_DAMPING].is_valid())
+ }
+ if (tex_parameters[PARAM_DAMPING].is_valid()) {
code += "uniform sampler2D damping_texture;\n";
- if (tex_parameters[PARAM_ANGLE].is_valid())
+ }
+ if (tex_parameters[PARAM_ANGLE].is_valid()) {
code += "uniform sampler2D angle_texture;\n";
- if (tex_parameters[PARAM_SCALE].is_valid())
+ }
+ if (tex_parameters[PARAM_SCALE].is_valid()) {
code += "uniform sampler2D scale_texture;\n";
- if (tex_parameters[PARAM_HUE_VARIATION].is_valid())
+ }
+ if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) {
code += "uniform sampler2D hue_variation_texture;\n";
- if (tex_parameters[PARAM_ANIM_SPEED].is_valid())
+ }
+ if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) {
code += "uniform sampler2D anim_speed_texture;\n";
- if (tex_parameters[PARAM_ANIM_OFFSET].is_valid())
+ }
+ if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) {
code += "uniform sampler2D anim_offset_texture;\n";
+ }
if (trail_size_modifier.is_valid()) {
code += "uniform sampler2D trail_size_modifier;\n";
@@ -289,25 +299,27 @@ void ParticlesMaterial::_update_shader() {
code += " }\n\n";
code += " if (RESTART || restart) {\n";
- if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
+ if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(0.0, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_linear_velocity = 0.0;\n";
+ }
- if (tex_parameters[PARAM_ANGLE].is_valid())
+ if (tex_parameters[PARAM_ANGLE].is_valid()) {
code += " float tex_angle = textureLod(angle_texture, vec2(0.0, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_angle = 0.0;\n";
+ }
- if (tex_parameters[PARAM_ANIM_OFFSET].is_valid())
+ if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) {
code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(0.0, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_anim_offset = 0.0;\n";
+ }
code += " float spread_rad = spread * degree_to_rad;\n";
if (flags[FLAG_DISABLE_Z]) {
-
code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
code += " angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);\n";
code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n";
@@ -352,7 +364,6 @@ void ParticlesMaterial::_update_shader() {
if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) {
if (flags[FLAG_DISABLE_Z]) {
-
code += " mat2 rotm;";
code += " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xy;\n";
code += " rotm[1] = rotm[0].yx * vec2(1.0, -1.0);\n";
@@ -380,58 +391,67 @@ void ParticlesMaterial::_update_shader() {
code += " } else {\n";
code += " CUSTOM.y += DELTA / LIFETIME;\n";
- if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
+ if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_linear_velocity = 0.0;\n";
+ }
if (flags[FLAG_DISABLE_Z]) {
-
- if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid())
+ if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_orbit_velocity = 0.0;\n";
+ }
}
- if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid())
+ if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_angular_velocity = 0.0;\n";
+ }
- if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid())
+ if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_linear_accel = 0.0;\n";
+ }
- if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid())
+ if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_radial_accel = 0.0;\n";
+ }
- if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid())
+ if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_tangent_accel = 0.0;\n";
+ }
- if (tex_parameters[PARAM_DAMPING].is_valid())
+ if (tex_parameters[PARAM_DAMPING].is_valid()) {
code += " float tex_damping = textureLod(damping_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_damping = 0.0;\n";
+ }
- if (tex_parameters[PARAM_ANGLE].is_valid())
+ if (tex_parameters[PARAM_ANGLE].is_valid()) {
code += " float tex_angle = textureLod(angle_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_angle = 0.0;\n";
+ }
- if (tex_parameters[PARAM_ANIM_SPEED].is_valid())
+ if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) {
code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_anim_speed = 0.0;\n";
+ }
- if (tex_parameters[PARAM_ANIM_OFFSET].is_valid())
+ if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) {
code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_anim_offset = 0.0;\n";
+ }
code += " vec3 force = gravity;\n";
code += " vec3 pos = TRANSFORM[3].xyz;\n";
@@ -456,7 +476,6 @@ void ParticlesMaterial::_update_shader() {
code += " VELOCITY += force * DELTA;\n";
code += " // orbit velocity\n";
if (flags[FLAG_DISABLE_Z]) {
-
code += " float orbit_amount = (orbit_velocity + tex_orbit_velocity) * mix(1.0, rand_from_seed(alt_seed), orbit_velocity_random);\n";
code += " if (orbit_amount != 0.0) {\n";
code += " float ang = orbit_amount * DELTA * pi * 2.0;\n";
@@ -486,15 +505,17 @@ void ParticlesMaterial::_update_shader() {
code += " }\n";
// apply color
// apply hue rotation
- if (tex_parameters[PARAM_SCALE].is_valid())
+ if (tex_parameters[PARAM_SCALE].is_valid()) {
code += " float tex_scale = textureLod(scale_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_scale = 1.0;\n";
+ }
- if (tex_parameters[PARAM_HUE_VARIATION].is_valid())
+ if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) {
code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n";
- else
+ } else {
code += " float tex_hue_variation = 0.0;\n";
+ }
code += " float hue_rot_angle = (hue_variation + tex_hue_variation) * pi * 2.0 * mix(1.0, hue_rot_rand * 2.0 - 1.0, hue_variation_random);\n";
code += " float hue_rot_c = cos(hue_rot_angle);\n";
@@ -527,7 +548,6 @@ void ParticlesMaterial::_update_shader() {
code += "\n";
if (flags[FLAG_DISABLE_Z]) {
-
if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) {
code += " if (length(VELOCITY) > 0.0) {\n";
code += " TRANSFORM[1].xyz = normalize(VELOCITY);\n";
@@ -603,17 +623,14 @@ void ParticlesMaterial::_update_shader() {
}
void ParticlesMaterial::flush_changes() {
-
MutexLock lock(material_mutex);
while (dirty_materials->first()) {
-
dirty_materials->first()->self()->_update_shader();
}
}
void ParticlesMaterial::_queue_shader_change() {
-
MutexLock lock(material_mutex);
if (!element.in_list()) {
@@ -622,46 +639,39 @@ void ParticlesMaterial::_queue_shader_change() {
}
bool ParticlesMaterial::_is_shader_dirty() const {
-
MutexLock lock(material_mutex);
return element.in_list();
}
void ParticlesMaterial::set_direction(Vector3 p_direction) {
-
direction = p_direction;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->direction, direction);
}
Vector3 ParticlesMaterial::get_direction() const {
-
return direction;
}
void ParticlesMaterial::set_spread(float p_spread) {
-
spread = p_spread;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->spread, p_spread);
}
float ParticlesMaterial::get_spread() const {
-
return spread;
}
void ParticlesMaterial::set_flatness(float p_flatness) {
-
flatness = p_flatness;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->flatness, p_flatness);
}
-float ParticlesMaterial::get_flatness() const {
+float ParticlesMaterial::get_flatness() const {
return flatness;
}
void ParticlesMaterial::set_param(Parameter p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
parameters[p_param] = p_value;
@@ -703,18 +713,18 @@ void ParticlesMaterial::set_param(Parameter p_param, float p_value) {
case PARAM_ANIM_OFFSET: {
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset, p_value);
} break;
- case PARAM_MAX: break; // Can't happen, but silences warning
+ case PARAM_MAX:
+ break; // Can't happen, but silences warning
}
}
-float ParticlesMaterial::get_param(Parameter p_param) const {
+float ParticlesMaterial::get_param(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return parameters[p_param];
}
void ParticlesMaterial::set_param_randomness(Parameter p_param, float p_value) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
randomness[p_param] = p_value;
@@ -756,27 +766,27 @@ void ParticlesMaterial::set_param_randomness(Parameter p_param, float p_value) {
case PARAM_ANIM_OFFSET: {
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_random, p_value);
} break;
- case PARAM_MAX: break; // Can't happen, but silences warning
+ case PARAM_MAX:
+ break; // Can't happen, but silences warning
}
}
-float ParticlesMaterial::get_param_randomness(Parameter p_param) const {
+float ParticlesMaterial::get_param_randomness(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
return randomness[p_param];
}
static void _adjust_curve_range(const Ref<Texture2D> &p_texture, float p_min, float p_max) {
-
Ref<CurveTexture> curve_tex = p_texture;
- if (!curve_tex.is_valid())
+ if (!curve_tex.is_valid()) {
return;
+ }
curve_tex->ensure_default_setup(p_min, p_max);
}
void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D> &p_texture) {
-
ERR_FAIL_INDEX(p_param, PARAM_MAX);
tex_parameters[p_param] = p_texture;
@@ -828,31 +838,29 @@ void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture2D
case PARAM_ANIM_OFFSET: {
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_texture, p_texture);
} break;
- case PARAM_MAX: break; // Can't happen, but silences warning
+ case PARAM_MAX:
+ break; // Can't happen, but silences warning
}
_queue_shader_change();
}
-Ref<Texture2D> ParticlesMaterial::get_param_texture(Parameter p_param) const {
+Ref<Texture2D> ParticlesMaterial::get_param_texture(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Texture2D>());
return tex_parameters[p_param];
}
void ParticlesMaterial::set_color(const Color &p_color) {
-
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color, p_color);
color = p_color;
}
Color ParticlesMaterial::get_color() const {
-
return color;
}
void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) {
-
color_ramp = p_texture;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture);
_queue_shader_change();
@@ -860,7 +868,6 @@ void ParticlesMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) {
}
Ref<Texture2D> ParticlesMaterial::get_color_ramp() const {
-
return color_ramp;
}
@@ -886,87 +893,74 @@ void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) {
}
void ParticlesMaterial::set_emission_sphere_radius(float p_radius) {
-
emission_sphere_radius = p_radius;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_sphere_radius, p_radius);
}
void ParticlesMaterial::set_emission_box_extents(Vector3 p_extents) {
-
emission_box_extents = p_extents;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_box_extents, p_extents);
}
void ParticlesMaterial::set_emission_point_texture(const Ref<Texture2D> &p_points) {
-
emission_point_texture = p_points;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, p_points);
}
void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture2D> &p_normals) {
-
emission_normal_texture = p_normals;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, p_normals);
}
void ParticlesMaterial::set_emission_color_texture(const Ref<Texture2D> &p_colors) {
-
emission_color_texture = p_colors;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, p_colors);
_queue_shader_change();
}
void ParticlesMaterial::set_emission_point_count(int p_count) {
-
emission_point_count = p_count;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_point_count, p_count);
}
ParticlesMaterial::EmissionShape ParticlesMaterial::get_emission_shape() const {
-
return emission_shape;
}
float ParticlesMaterial::get_emission_sphere_radius() const {
-
return emission_sphere_radius;
}
-Vector3 ParticlesMaterial::get_emission_box_extents() const {
+Vector3 ParticlesMaterial::get_emission_box_extents() const {
return emission_box_extents;
}
-Ref<Texture2D> ParticlesMaterial::get_emission_point_texture() const {
+Ref<Texture2D> ParticlesMaterial::get_emission_point_texture() const {
return emission_point_texture;
}
-Ref<Texture2D> ParticlesMaterial::get_emission_normal_texture() const {
+Ref<Texture2D> ParticlesMaterial::get_emission_normal_texture() const {
return emission_normal_texture;
}
Ref<Texture2D> ParticlesMaterial::get_emission_color_texture() const {
-
return emission_color_texture;
}
int ParticlesMaterial::get_emission_point_count() const {
-
return emission_point_count;
}
void ParticlesMaterial::set_trail_divisor(int p_divisor) {
-
trail_divisor = p_divisor;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_divisor, p_divisor);
}
int ParticlesMaterial::get_trail_divisor() const {
-
return trail_divisor;
}
void ParticlesMaterial::set_trail_size_modifier(const Ref<CurveTexture> &p_trail_size_modifier) {
-
trail_size_modifier = p_trail_size_modifier;
Ref<CurveTexture> curve = trail_size_modifier;
@@ -979,24 +973,20 @@ void ParticlesMaterial::set_trail_size_modifier(const Ref<CurveTexture> &p_trail
}
Ref<CurveTexture> ParticlesMaterial::get_trail_size_modifier() const {
-
return trail_size_modifier;
}
void ParticlesMaterial::set_trail_color_modifier(const Ref<GradientTexture> &p_trail_color_modifier) {
-
trail_color_modifier = p_trail_color_modifier;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_color_modifier, p_trail_color_modifier);
_queue_shader_change();
}
Ref<GradientTexture> ParticlesMaterial::get_trail_color_modifier() const {
-
return trail_color_modifier;
}
void ParticlesMaterial::set_gravity(const Vector3 &p_gravity) {
-
gravity = p_gravity;
Vector3 gset = gravity;
if (gset == Vector3()) {
@@ -1006,29 +996,24 @@ void ParticlesMaterial::set_gravity(const Vector3 &p_gravity) {
}
Vector3 ParticlesMaterial::get_gravity() const {
-
return gravity;
}
void ParticlesMaterial::set_lifetime_randomness(float p_lifetime) {
-
lifetime_randomness = p_lifetime;
RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->lifetime_randomness, lifetime_randomness);
}
float ParticlesMaterial::get_lifetime_randomness() const {
-
return lifetime_randomness;
}
RID ParticlesMaterial::get_shader_rid() const {
-
ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
return shader_map[current_key].shader;
}
void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
-
if (property.name == "color" && color_ramp.is_valid()) {
property.usage = 0;
}
@@ -1059,12 +1044,10 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
}
Shader::Mode ParticlesMaterial::get_shader_mode() const {
-
return Shader::MODE_PARTICLES;
}
void ParticlesMaterial::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_direction", "degrees"), &ParticlesMaterial::set_direction);
ClassDB::bind_method(D_METHOD("get_direction"), &ParticlesMaterial::get_direction);
@@ -1232,7 +1215,6 @@ void ParticlesMaterial::_bind_methods() {
ParticlesMaterial::ParticlesMaterial() :
element(this) {
-
set_direction(Vector3(1, 0, 0));
set_spread(45);
set_flatness(0);
@@ -1273,7 +1255,6 @@ ParticlesMaterial::ParticlesMaterial() :
}
ParticlesMaterial::~ParticlesMaterial() {
-
MutexLock lock(material_mutex);
if (shader_map.has(current_key)) {
diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h
index c6c8316995..a1a4c38842 100644
--- a/scene/resources/particles_material.h
+++ b/scene/resources/particles_material.h
@@ -35,7 +35,6 @@
#define PARTICLES_MATERIAL_H
class ParticlesMaterial : public Material {
-
GDCLASS(ParticlesMaterial, Material);
public:
@@ -74,7 +73,6 @@ public:
private:
union MaterialKey {
-
struct {
uint32_t texture_mask : 16;
uint32_t texture_color : 1;
@@ -103,7 +101,6 @@ private:
MaterialKey current_key;
_FORCE_INLINE_ MaterialKey _compute_key() const {
-
MaterialKey mk;
mk.key = 0;
for (int i = 0; i < PARAM_MAX; i++) {
diff --git a/scene/resources/physics_material.cpp b/scene/resources/physics_material.cpp
index 8ac0191452..2a5cd1101a 100644
--- a/scene/resources/physics_material.cpp
+++ b/scene/resources/physics_material.cpp
@@ -31,7 +31,6 @@
#include "physics_material.h"
void PhysicsMaterial::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_friction", "friction"), &PhysicsMaterial::set_friction);
ClassDB::bind_method(D_METHOD("get_friction"), &PhysicsMaterial::get_friction);
@@ -69,9 +68,3 @@ void PhysicsMaterial::set_absorbent(bool p_val) {
absorbent = p_val;
emit_changed();
}
-
-PhysicsMaterial::PhysicsMaterial() :
- friction(1),
- rough(false),
- bounce(0),
- absorbent(false) {}
diff --git a/scene/resources/physics_material.h b/scene/resources/physics_material.h
index f4a77d9854..34aa7066df 100644
--- a/scene/resources/physics_material.h
+++ b/scene/resources/physics_material.h
@@ -28,22 +28,21 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef physics_material_override_H
-#define physics_material_override_H
+#ifndef PHYSICS_MATERIAL_H
+#define PHYSICS_MATERIAL_H
#include "core/resource.h"
#include "servers/physics_server_3d.h"
class PhysicsMaterial : public Resource {
-
GDCLASS(PhysicsMaterial, Resource);
OBJ_SAVE_TYPE(PhysicsMaterial);
RES_BASE_EXTENSION("phymat");
- real_t friction;
- bool rough;
- real_t bounce;
- bool absorbent;
+ real_t friction = 1;
+ bool rough = false;
+ real_t bounce = 0;
+ bool absorbent = false;
protected:
static void _bind_methods();
@@ -69,7 +68,7 @@ public:
return absorbent ? -bounce : bounce;
}
- PhysicsMaterial();
+ PhysicsMaterial() {}
};
-#endif // physics_material_override_H
+#endif // PHYSICS_MATERIAL_H
diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp
index c3daedf918..0546c92948 100644
--- a/scene/resources/polygon_path_finder.cpp
+++ b/scene/resources/polygon_path_finder.cpp
@@ -32,11 +32,9 @@
#include "core/math/geometry.h"
bool PolygonPathFinder::_is_point_inside(const Vector2 &p_point) const {
-
int crosses = 0;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
Vector2 a = points[e.points[0]].pos;
@@ -51,7 +49,6 @@ bool PolygonPathFinder::_is_point_inside(const Vector2 &p_point) const {
}
void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int> &p_connections) {
-
ERR_FAIL_COND(p_connections.size() & 1);
points.clear();
@@ -64,7 +61,6 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
bounds = Rect2();
for (int i = 0; i < p_points.size(); i++) {
-
points.write[i].pos = p_points[i];
points.write[i].penalty = 0;
@@ -84,7 +80,6 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
//insert edges (which are also connetions)
for (int i = 0; i < p_connections.size(); i += 2) {
-
Edge e(p_connections[i], p_connections[i + 1]);
ERR_FAIL_INDEX(e.points[0], point_count);
ERR_FAIL_INDEX(e.points[1], point_count);
@@ -96,25 +91,25 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
//fill the remaining connections based on visibility
for (int i = 0; i < point_count; i++) {
-
for (int j = i + 1; j < point_count; j++) {
-
- if (edges.has(Edge(i, j)))
+ if (edges.has(Edge(i, j))) {
continue; //if in edge ignore
+ }
Vector2 from = points[i].pos;
Vector2 to = points[j].pos;
- if (!_is_point_inside(from * 0.5 + to * 0.5)) //connection between points in inside space
+ if (!_is_point_inside(from * 0.5 + to * 0.5)) { //connection between points in inside space
continue;
+ }
bool valid = true;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
- if (e.points[0] == i || e.points[1] == i || e.points[0] == j || e.points[1] == j)
+ if (e.points[0] == i || e.points[1] == i || e.points[0] == j || e.points[1] == j) {
continue;
+ }
Vector2 a = points[e.points[0]].pos;
Vector2 b = points[e.points[1]].pos;
@@ -134,7 +129,6 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
}
Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector2 &p_to) {
-
Vector<Vector2> path;
Vector2 from = p_from;
@@ -143,12 +137,10 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
Edge ignore_to_edge(-1, -1);
if (!_is_point_inside(from)) {
-
float closest_dist = 1e20;
Vector2 closest_point;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
Vector2 seg[2] = {
points[e.points[0]].pos,
@@ -173,7 +165,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
Vector2 closest_point;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
Vector2 seg[2] = {
points[e.points[0]].pos,
@@ -195,16 +186,16 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
//test direct connection
{
-
bool can_see_eachother = true;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
- if (e.points[0] == ignore_from_edge.points[0] && e.points[1] == ignore_from_edge.points[1])
+ if (e.points[0] == ignore_from_edge.points[0] && e.points[1] == ignore_from_edge.points[1]) {
continue;
- if (e.points[0] == ignore_to_edge.points[0] && e.points[1] == ignore_to_edge.points[1])
+ }
+ if (e.points[0] == ignore_to_edge.points[0] && e.points[1] == ignore_to_edge.points[1]) {
continue;
+ }
Vector2 a = points[e.points[0]].pos;
Vector2 b = points[e.points[1]].pos;
@@ -216,7 +207,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
if (can_see_eachother) {
-
path.push_back(from);
path.push_back(to);
return path;
@@ -237,7 +227,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
points.write[bidx].penalty = 0;
for (int i = 0; i < points.size() - 2; i++) {
-
bool valid_a = true;
bool valid_b = true;
points.write[i].prev = -1;
@@ -252,22 +241,20 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
- if (e.points[0] == i || e.points[1] == i)
+ if (e.points[0] == i || e.points[1] == i) {
continue;
+ }
Vector2 a = points[e.points[0]].pos;
Vector2 b = points[e.points[1]].pos;
if (valid_a) {
-
if (e.points[0] != ignore_from_edge.points[1] &&
e.points[1] != ignore_from_edge.points[1] &&
e.points[0] != ignore_from_edge.points[0] &&
e.points[1] != ignore_from_edge.points[0]) {
-
if (Geometry::segment_intersects_segment_2d(a, b, from, points[i].pos, nullptr)) {
valid_a = false;
}
@@ -275,20 +262,19 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
if (valid_b) {
-
if (e.points[0] != ignore_to_edge.points[1] &&
e.points[1] != ignore_to_edge.points[1] &&
e.points[0] != ignore_to_edge.points[0] &&
e.points[1] != ignore_to_edge.points[0]) {
-
if (Geometry::segment_intersects_segment_2d(a, b, to, points[i].pos, nullptr)) {
valid_b = false;
}
}
}
- if (!valid_a && !valid_b)
+ if (!valid_a && !valid_b) {
break;
+ }
}
if (valid_a) {
@@ -308,7 +294,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
points.write[aidx].distance = 0;
points.write[aidx].prev = aidx;
for (Set<int>::Element *E = points[aidx].connections.front(); E; E = E->next()) {
-
open_list.insert(E->get());
points.write[E->get()].distance = from.distance_to(points[E->get()].pos);
points.write[E->get()].prev = aidx;
@@ -317,7 +302,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
bool found_route = false;
while (true) {
-
if (open_list.size() == 0) {
printf("open list empty\n");
break;
@@ -329,14 +313,12 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
//this could be faster (cache previous results)
for (Set<int>::Element *E = open_list.front(); E; E = E->next()) {
-
const Point &p = points[E->get()];
float cost = p.distance;
cost += p.pos.distance_to(to);
cost += p.penalty;
if (cost < least_cost) {
-
least_cost_point = E->get();
least_cost = cost;
}
@@ -346,7 +328,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
//open the neighbours for search
for (Set<int>::Element *E = np.connections.front(); E; E = E->next()) {
-
Point &p = points.write[E->get()];
float distance = np.pos.distance_to(p.pos) + np.distance;
@@ -354,7 +335,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
//oh this was visited already, can we win the cost?
if (p.distance > distance) {
-
p.prev = least_cost_point; //reasign previous
p.distance = distance;
}
@@ -373,8 +353,9 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
}
- if (found_route)
+ if (found_route) {
break;
+ }
open_list.erase(least_cost_point);
}
@@ -391,7 +372,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
for (int i = 0; i < points.size() - 2; i++) {
-
points.write[i].connections.erase(aidx);
points.write[i].connections.erase(bidx);
points.write[i].prev = -1;
@@ -409,7 +389,6 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
}
void PolygonPathFinder::_set_data(const Dictionary &p_data) {
-
ERR_FAIL_COND(!p_data.has("points"));
ERR_FAIL_COND(!p_data.has("connections"));
ERR_FAIL_COND(!p_data.has("segments"));
@@ -419,8 +398,9 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) {
Array c = p_data["connections"];
ERR_FAIL_COND(c.size() != p.size());
- if (c.size())
+ if (c.size()) {
return;
+ }
int pc = p.size();
points.resize(pc + 2);
@@ -432,13 +412,11 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) {
const int *cr = con.ptr();
int cc = con.size();
for (int j = 0; j < cc; j++) {
-
points.write[i].connections.insert(cr[j]);
}
}
if (p_data.has("penalties")) {
-
Vector<float> penalties = p_data["penalties"];
if (penalties.size() == pc) {
const float *pr2 = penalties.ptr();
@@ -453,7 +431,6 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) {
ERR_FAIL_COND(sc & 1);
const int *sr = segs.ptr();
for (int i = 0; i < sc; i += 2) {
-
Edge e(sr[i], sr[i + 1]);
edges.insert(e);
}
@@ -461,7 +438,6 @@ void PolygonPathFinder::_set_data(const Dictionary &p_data) {
}
Dictionary PolygonPathFinder::_get_data() const {
-
Dictionary d;
Vector<Vector2> p;
Vector<int> ind;
@@ -491,7 +467,6 @@ Dictionary PolygonPathFinder::_get_data() const {
}
}
{
-
int *iw = ind.ptrw();
int idx = 0;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
@@ -510,17 +485,14 @@ Dictionary PolygonPathFinder::_get_data() const {
}
bool PolygonPathFinder::is_point_inside(const Vector2 &p_point) const {
-
return _is_point_inside(p_point);
}
Vector2 PolygonPathFinder::get_closest_point(const Vector2 &p_point) const {
-
float closest_dist = 1e20;
Vector2 closest_point;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
-
const Edge &e = E->get();
Vector2 seg[2] = {
points[e.points[0]].pos,
@@ -542,7 +514,6 @@ Vector2 PolygonPathFinder::get_closest_point(const Vector2 &p_point) const {
}
Vector<Vector2> PolygonPathFinder::get_intersections(const Vector2 &p_from, const Vector2 &p_to) const {
-
Vector<Vector2> inters;
for (Set<Edge>::Element *E = edges.front(); E; E = E->next()) {
@@ -559,24 +530,20 @@ Vector<Vector2> PolygonPathFinder::get_intersections(const Vector2 &p_from, cons
}
Rect2 PolygonPathFinder::get_bounds() const {
-
return bounds;
}
void PolygonPathFinder::set_point_penalty(int p_point, float p_penalty) {
-
ERR_FAIL_INDEX(p_point, points.size() - 2);
points.write[p_point].penalty = p_penalty;
}
float PolygonPathFinder::get_point_penalty(int p_point) const {
-
ERR_FAIL_INDEX_V(p_point, points.size() - 2, 0);
return points[p_point].penalty;
}
void PolygonPathFinder::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("setup", "points", "connections"), &PolygonPathFinder::setup);
ClassDB::bind_method(D_METHOD("find_path", "from", "to"), &PolygonPathFinder::find_path);
ClassDB::bind_method(D_METHOD("get_intersections", "from", "to"), &PolygonPathFinder::get_intersections);
diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h
index 2ef5c89e2a..baee4dc20d 100644
--- a/scene/resources/polygon_path_finder.h
+++ b/scene/resources/polygon_path_finder.h
@@ -34,7 +34,6 @@
#include "core/resource.h"
class PolygonPathFinder : public Resource {
-
GDCLASS(PolygonPathFinder, Resource);
struct Point {
@@ -46,19 +45,17 @@ class PolygonPathFinder : public Resource {
};
struct Edge {
-
int points[2];
_FORCE_INLINE_ bool operator<(const Edge &p_edge) const {
-
- if (points[0] == p_edge.points[0])
+ if (points[0] == p_edge.points[0]) {
return points[1] < p_edge.points[1];
- else
+ } else {
return points[0] < p_edge.points[0];
+ }
}
Edge(int a = 0, int b = 0) {
-
if (a > b) {
SWAP(a, b);
}
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 46e8575018..99edf26dc1 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -35,7 +35,6 @@
PrimitiveMesh
*/
void PrimitiveMesh::_update() const {
-
Array arr;
arr.resize(RS::ARRAY_MAX);
_create_mesh_array(arr);
@@ -47,13 +46,13 @@ void PrimitiveMesh::_update() const {
int pc = points.size();
ERR_FAIL_COND(pc == 0);
{
-
const Vector3 *r = points.ptr();
for (int i = 0; i < pc; i++) {
- if (i == 0)
+ if (i == 0) {
aabb.position = r[i];
- else
+ } else {
aabb.expand_to(r[i]);
+ }
}
}
@@ -63,7 +62,6 @@ void PrimitiveMesh::_update() const {
Vector<Vector3> normals = arr[RS::ARRAY_NORMAL];
if (normals.size() && indices.size()) {
-
{
int nc = normals.size();
Vector3 *w = normals.ptrw();
@@ -99,9 +97,9 @@ void PrimitiveMesh::_update() const {
}
void PrimitiveMesh::_request_update() {
-
- if (pending_request)
+ if (pending_request) {
return;
+ }
_update();
}
@@ -142,8 +140,8 @@ Array PrimitiveMesh::surface_get_arrays(int p_surface) const {
Dictionary PrimitiveMesh::surface_get_lods(int p_surface) const {
return Dictionary(); //not really supported
}
-Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const {
+Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const {
return Array(); //not really supported
}
@@ -230,14 +228,12 @@ Array PrimitiveMesh::get_mesh_arrays() const {
}
void PrimitiveMesh::set_custom_aabb(const AABB &p_custom) {
-
custom_aabb = p_custom;
RS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
emit_changed();
}
AABB PrimitiveMesh::get_custom_aabb() const {
-
return custom_aabb;
}
@@ -251,7 +247,6 @@ bool PrimitiveMesh::get_flip_faces() const {
}
PrimitiveMesh::PrimitiveMesh() {
-
flip_faces = false;
// defaults
mesh = RenderingServer::get_singleton()->mesh_create();
@@ -1382,7 +1377,6 @@ void QuadMesh::_create_mesh_array(Array &p_arr) const {
};
for (int i = 0; i < 6; i++) {
-
int j = indices[i];
faces.set(i, quad_faces[j]);
normals.set(i, Vector3(0, 0, 1));
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index 5f17680c9e..3cffa44e3a 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -42,7 +42,6 @@
This class is set apart that it assumes a single surface is always generated for our mesh.
*/
class PrimitiveMesh : public Mesh {
-
GDCLASS(PrimitiveMesh, Mesh);
private:
@@ -134,7 +133,6 @@ public:
Similar to test cube but with subdivision support and different texture coordinates
*/
class CubeMesh : public PrimitiveMesh {
-
GDCLASS(CubeMesh, PrimitiveMesh);
private:
@@ -168,7 +166,6 @@ public:
*/
class CylinderMesh : public PrimitiveMesh {
-
GDCLASS(CylinderMesh, PrimitiveMesh);
private:
@@ -205,7 +202,6 @@ public:
Similar to quadmesh but with tessellation support
*/
class PlaneMesh : public PrimitiveMesh {
-
GDCLASS(PlaneMesh, PrimitiveMesh);
private:
@@ -234,7 +230,6 @@ public:
A prism shapen, handy for ramps, triangles, etc.
*/
class PrismMesh : public PrimitiveMesh {
-
GDCLASS(PrismMesh, PrimitiveMesh);
private:
@@ -272,7 +267,6 @@ public:
*/
class QuadMesh : public PrimitiveMesh {
-
GDCLASS(QuadMesh, PrimitiveMesh);
private:
@@ -293,7 +287,6 @@ public:
A sphere..
*/
class SphereMesh : public PrimitiveMesh {
-
GDCLASS(SphereMesh, PrimitiveMesh);
private:
@@ -331,7 +324,6 @@ public:
*/
class PointMesh : public PrimitiveMesh {
-
GDCLASS(PointMesh, PrimitiveMesh)
protected:
diff --git a/scene/resources/ray_shape_3d.cpp b/scene/resources/ray_shape_3d.cpp
index 0211c55f46..17205a500a 100644
--- a/scene/resources/ray_shape_3d.cpp
+++ b/scene/resources/ray_shape_3d.cpp
@@ -33,7 +33,6 @@
#include "servers/physics_server_3d.h"
Vector<Vector3> RayShape3D::get_debug_mesh_lines() {
-
Vector<Vector3> points;
points.push_back(Vector3());
points.push_back(Vector3(0, 0, get_length()));
@@ -46,7 +45,6 @@ real_t RayShape3D::get_enclosing_radius() const {
}
void RayShape3D::_update_shape() {
-
Dictionary d;
d["length"] = length;
d["slips_on_slope"] = slips_on_slope;
@@ -55,7 +53,6 @@ void RayShape3D::_update_shape() {
}
void RayShape3D::set_length(float p_length) {
-
length = p_length;
_update_shape();
notify_change_to_owners();
@@ -63,12 +60,10 @@ void RayShape3D::set_length(float p_length) {
}
float RayShape3D::get_length() const {
-
return length;
}
void RayShape3D::set_slips_on_slope(bool p_active) {
-
slips_on_slope = p_active;
_update_shape();
notify_change_to_owners();
@@ -80,7 +75,6 @@ bool RayShape3D::get_slips_on_slope() const {
}
void RayShape3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape3D::set_length);
ClassDB::bind_method(D_METHOD("get_length"), &RayShape3D::get_length);
@@ -93,7 +87,6 @@ void RayShape3D::_bind_methods() {
RayShape3D::RayShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_RAY)) {
-
length = 1.0;
slips_on_slope = false;
diff --git a/scene/resources/ray_shape_3d.h b/scene/resources/ray_shape_3d.h
index 83bb71cca3..ef849d2dee 100644
--- a/scene/resources/ray_shape_3d.h
+++ b/scene/resources/ray_shape_3d.h
@@ -33,7 +33,6 @@
#include "scene/resources/shape_3d.h"
class RayShape3D : public Shape3D {
-
GDCLASS(RayShape3D, Shape3D);
float length;
bool slips_on_slope;
diff --git a/scene/resources/rectangle_shape_2d.cpp b/scene/resources/rectangle_shape_2d.cpp
index 19e72a65b0..949fddf2e7 100644
--- a/scene/resources/rectangle_shape_2d.cpp
+++ b/scene/resources/rectangle_shape_2d.cpp
@@ -33,29 +33,24 @@
#include "servers/physics_server_2d.h"
#include "servers/rendering_server.h"
void RectangleShape2D::_update_shape() {
-
PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), extents);
emit_changed();
}
void RectangleShape2D::set_extents(const Vector2 &p_extents) {
-
extents = p_extents;
_update_shape();
}
Vector2 RectangleShape2D::get_extents() const {
-
return extents;
}
void RectangleShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
RenderingServer::get_singleton()->canvas_item_add_rect(p_to_rid, Rect2(-extents, extents * 2.0), p_color);
}
Rect2 RectangleShape2D::get_rect() const {
-
return Rect2(-extents, extents * 2.0);
}
@@ -64,7 +59,6 @@ real_t RectangleShape2D::get_enclosing_radius() const {
}
void RectangleShape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_extents", "extents"), &RectangleShape2D::set_extents);
ClassDB::bind_method(D_METHOD("get_extents"), &RectangleShape2D::get_extents);
@@ -73,7 +67,6 @@ void RectangleShape2D::_bind_methods() {
RectangleShape2D::RectangleShape2D() :
Shape2D(PhysicsServer2D::get_singleton()->rectangle_shape_create()) {
-
extents = Vector2(10, 10);
_update_shape();
}
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 5068bb548f..93db8b725f 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -46,17 +46,14 @@
///
void ResourceLoaderText::set_local_path(const String &p_local_path) {
-
res_path = p_local_path;
}
Ref<Resource> ResourceLoaderText::get_resource() {
-
return resource;
}
Error ResourceLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
-
VariantParser::Token token;
VariantParser::get_token(p_stream, token, line, r_err_str);
if (token.type != VariantParser::TK_NUMBER) {
@@ -86,7 +83,6 @@ Error ResourceLoaderText::_parse_sub_resource_dummy(DummyReadData *p_data, Varia
}
Error ResourceLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
-
VariantParser::Token token;
VariantParser::get_token(p_stream, token, line, r_err_str);
if (token.type != VariantParser::TK_NUMBER) {
@@ -110,7 +106,6 @@ Error ResourceLoaderText::_parse_ext_resource_dummy(DummyReadData *p_data, Varia
}
Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
-
VariantParser::Token token;
VariantParser::get_token(p_stream, token, line, r_err_str);
if (token.type != VariantParser::TK_NUMBER) {
@@ -120,18 +115,21 @@ Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, R
int index = token.value;
- String path = local_path + "::" + itos(index);
+ if (use_nocache) {
+ r_res = int_resources[index];
+ } else {
+ String path = local_path + "::" + itos(index);
- if (!ignore_resource_parsing) {
+ if (!ignore_resource_parsing) {
+ if (!ResourceCache::has(path)) {
+ r_err_str = "Can't load cached sub-resource: " + path;
+ return ERR_PARSE_ERROR;
+ }
- if (!ResourceCache::has(path)) {
- r_err_str = "Can't load cached sub-resource: " + path;
- return ERR_PARSE_ERROR;
+ r_res = RES(ResourceCache::get(path));
+ } else {
+ r_res = RES();
}
-
- r_res = RES(ResourceCache::get(path));
- } else {
- r_res = RES();
}
VariantParser::get_token(p_stream, token, line, r_err_str);
@@ -144,7 +142,6 @@ Error ResourceLoaderText::_parse_sub_resource(VariantParser::Stream *p_stream, R
}
Error ResourceLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, Ref<Resource> &r_res, int &line, String &r_err_str) {
-
VariantParser::Token token;
VariantParser::get_token(p_stream, token, line, r_err_str);
if (token.type != VariantParser::TK_NUMBER) {
@@ -155,7 +152,6 @@ Error ResourceLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, R
int id = token.value;
if (!ignore_resource_parsing) {
-
if (!ext_resources.has(id)) {
r_err_str = "Can't load cached ext-resource #" + itos(id);
return ERR_PARSE_ERROR;
@@ -167,10 +163,8 @@ Error ResourceLoaderText::_parse_ext_resource(VariantParser::Stream *p_stream, R
if (ext_resources[id].cache.is_valid()) {
r_res = ext_resources[id].cache;
} else if (use_sub_threads) {
-
RES res = ResourceLoader::load_threaded_get(path);
if (res.is_null()) {
-
if (ResourceLoader::get_abort_on_missing_resources()) {
error = ERR_FILE_CORRUPT;
error_text = "[ext_resource] referenced nonexistent resource at: " + path;
@@ -207,9 +201,7 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
packed_scene.instance();
while (true) {
-
if (next_tag.name == "node") {
-
int parent = -1;
int owner = -1;
int type = -1;
@@ -235,7 +227,6 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
}
if (next_tag.fields.has("instance")) {
-
instance = packed_scene->get_state()->add_value(next_tag.fields["instance"]);
if (packed_scene->get_state()->get_node_count() == 0 && parent == -1) {
@@ -245,7 +236,6 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
}
if (next_tag.fields.has("instance_placeholder")) {
-
String path = next_tag.fields["instance_placeholder"];
int path_v = packed_scene->get_state()->add_value(path);
@@ -263,8 +253,9 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
if (next_tag.fields.has("owner")) {
owner = packed_scene->get_state()->add_node_path(next_tag.fields["owner"]);
} else {
- if (parent != -1 && !(type == SceneState::TYPE_INSTANCED && instance == -1))
+ if (parent != -1 && !(type == SceneState::TYPE_INSTANCED && instance == -1)) {
owner = 0; //if no owner, owner is root
+ }
}
if (next_tag.fields.has("index")) {
@@ -274,7 +265,6 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
int node_id = packed_scene->get_state()->add_node(parent, owner, type, name, instance, index);
if (next_tag.fields.has("groups")) {
-
Array groups = next_tag.fields["groups"];
for (int i = 0; i < groups.size(); i++) {
packed_scene->get_state()->add_node_group(node_id, packed_scene->get_state()->add_name(groups[i]));
@@ -282,7 +272,6 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
}
while (true) {
-
String assign;
Variant value;
@@ -308,7 +297,6 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
}
}
} else if (next_tag.name == "connection") {
-
if (!next_tag.fields.has("from")) {
error = ERR_FILE_CORRUPT;
error_text = "missing 'from' field from connection tag";
@@ -373,7 +361,6 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
}
}
} else if (next_tag.name == "editable") {
-
if (!next_tag.fields.has("path")) {
error = ERR_FILE_CORRUPT;
error_text = "missing 'path' field from connection tag";
@@ -397,7 +384,6 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
}
}
} else {
-
error = ERR_FILE_CORRUPT;
_printerr();
return Ref<PackedScene>();
@@ -406,9 +392,9 @@ Ref<PackedScene> ResourceLoaderText::_parse_node_tag(VariantParser::ResourcePars
}
Error ResourceLoaderText::load() {
-
- if (error != OK)
+ if (error != OK) {
return error;
+ }
while (true) {
if (next_tag.name != "ext_resource") {
@@ -454,7 +440,6 @@ Error ResourceLoaderText::load() {
er.type = type;
if (use_sub_threads) {
-
Error err = ResourceLoader::load_threaded_request(path, type, use_sub_threads, local_path);
if (err != OK) {
@@ -472,7 +457,6 @@ Error ResourceLoaderText::load() {
RES res = ResourceLoader::load(path, type);
if (res.is_null()) {
-
if (ResourceLoader::get_abort_on_missing_resources()) {
error = ERR_FILE_CORRUPT;
error_text = "[ext_resource] referenced nonexistent resource at: " + path;
@@ -482,7 +466,6 @@ Error ResourceLoaderText::load() {
ResourceLoader::notify_dependency_error(local_path, path, type);
}
} else {
-
#ifdef TOOLS_ENABLED
//remember ID for saving
res->set_id_for_path(local_path, index);
@@ -535,11 +518,10 @@ Error ResourceLoaderText::load() {
Ref<Resource> res;
- if (!ResourceCache::has(path)) { //only if it doesn't exist
+ if (use_nocache || !ResourceCache::has(path)) { //only if it doesn't exist
Object *obj = ClassDB::instance(type);
if (!obj) {
-
error_text += "Can't create sub resource of type: " + type;
_printerr();
error = ERR_FILE_CORRUPT;
@@ -548,7 +530,6 @@ Error ResourceLoaderText::load() {
Resource *r = Object::cast_to<Resource>(obj);
if (!r) {
-
error_text += "Can't create sub resource of type, because not a resource: " + type;
_printerr();
error = ERR_FILE_CORRUPT;
@@ -556,14 +537,15 @@ Error ResourceLoaderText::load() {
}
res = Ref<Resource>(r);
- resource_cache.push_back(res);
- res->set_path(path);
+ int_resources[id] = res;
+ if (!use_nocache) {
+ res->set_path(path);
+ }
}
resource_current++;
while (true) {
-
String assign;
Variant value;
@@ -580,7 +562,6 @@ Error ResourceLoaderText::load() {
}
//it's assignment
} else if (next_tag.name != String()) {
-
error = OK;
break;
} else {
@@ -602,7 +583,6 @@ Error ResourceLoaderText::load() {
}
if (is_scene) {
-
error_text += "found the 'resource' tag on a scene file!";
_printerr();
error = ERR_FILE_CORRUPT;
@@ -611,7 +591,6 @@ Error ResourceLoaderText::load() {
Object *obj = ClassDB::instance(res_type);
if (!obj) {
-
error_text += "Can't create sub resource of type: " + res_type;
_printerr();
error = ERR_FILE_CORRUPT;
@@ -620,7 +599,6 @@ Error ResourceLoaderText::load() {
Resource *r = Object::cast_to<Resource>(obj);
if (!r) {
-
error_text += "Can't create sub resource of type, because not a resource: " + res_type;
_printerr();
error = ERR_FILE_CORRUPT;
@@ -632,7 +610,6 @@ Error ResourceLoaderText::load() {
resource_current++;
while (true) {
-
String assign;
Variant value;
@@ -643,10 +620,12 @@ Error ResourceLoaderText::load() {
_printerr();
} else {
error = OK;
- if (!ResourceCache::has(res_path)) {
- resource->set_path(res_path);
+ if (!use_nocache) {
+ if (!ResourceCache::has(res_path)) {
+ resource->set_path(res_path);
+ }
+ resource->set_as_translation_remapped(translation_remapped);
}
- resource->set_as_translation_remapped(translation_remapped);
}
return error;
}
@@ -655,7 +634,6 @@ Error ResourceLoaderText::load() {
resource->set(assign, value);
//it's assignment
} else if (next_tag.name != String()) {
-
error = ERR_FILE_CORRUPT;
error_text = "Extra tag found when parsing main resource file";
_printerr();
@@ -674,9 +652,7 @@ Error ResourceLoaderText::load() {
//for scene files
if (next_tag.name == "node") {
-
if (!is_scene) {
-
error_text += "found the 'node' tag on a resource file!";
_printerr();
error = ERR_FILE_CORRUPT;
@@ -685,13 +661,14 @@ Error ResourceLoaderText::load() {
Ref<PackedScene> packed_scene = _parse_node_tag(rp);
- if (!packed_scene.is_valid())
+ if (!packed_scene.is_valid()) {
return error;
+ }
error = OK;
//get it here
resource = packed_scene;
- if (!ResourceCache::has(res_path)) {
+ if (!use_nocache && !ResourceCache::has(res_path)) {
packed_scene->set_path(res_path);
}
@@ -711,20 +688,20 @@ Error ResourceLoaderText::load() {
}
int ResourceLoaderText::get_stage() const {
-
return resource_current;
}
-int ResourceLoaderText::get_stage_count() const {
+int ResourceLoaderText::get_stage_count() const {
return resources_total; //+ext_resources;
}
void ResourceLoaderText::set_translation_remapped(bool p_remapped) {
-
translation_remapped = p_remapped;
}
ResourceLoaderText::ResourceLoaderText() {
+ use_nocache = false;
+
resources_total = 0;
resource_current = 0;
use_sub_threads = false;
@@ -737,18 +714,15 @@ ResourceLoaderText::ResourceLoaderText() {
}
ResourceLoaderText::~ResourceLoaderText() {
-
memdelete(f);
}
void ResourceLoaderText::get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types) {
-
open(p_f);
ignore_resource_parsing = true;
ERR_FAIL_COND(error != OK);
while (next_tag.name == "ext_resource") {
-
if (!next_tag.fields.has("type")) {
error = ERR_FILE_CORRUPT;
error_text = "Missing 'type' in external resource tag";
@@ -789,7 +763,6 @@ void ResourceLoaderText::get_dependencies(FileAccess *p_f, List<String> *p_depen
}
Error ResourceLoaderText::rename_dependencies(FileAccess *p_f, const String &p_path, const Map<String, String> &p_map) {
-
open(p_f, true);
ERR_FAIL_COND_V(error != OK, error);
ignore_resource_parsing = true;
@@ -802,7 +775,6 @@ Error ResourceLoaderText::rename_dependencies(FileAccess *p_f, const String &p_p
uint64_t tag_end = f->get_position();
while (true) {
-
Error err = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp);
if (err != OK) {
@@ -814,17 +786,15 @@ Error ResourceLoaderText::rename_dependencies(FileAccess *p_f, const String &p_p
}
if (next_tag.name != "ext_resource") {
-
//nothing was done
- if (!fw)
+ if (!fw) {
return OK;
+ }
break;
} else {
-
if (!fw) {
-
fw = FileAccess::open(p_path + ".depren", FileAccess::WRITE);
if (is_scene) {
fw->store_line("[gd_scene load_steps=" + itos(resources_total) + " format=" + itos(FORMAT_VERSION) + "]\n");
@@ -891,7 +861,6 @@ Error ResourceLoaderText::rename_dependencies(FileAccess *p_f, const String &p_p
}
void ResourceLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) {
-
error = OK;
lines = 1;
@@ -906,7 +875,6 @@ void ResourceLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) {
Error err = VariantParser::parse_tag(&stream, lines, error_text, tag);
if (err) {
-
error = err;
_printerr();
return;
@@ -949,7 +917,6 @@ void ResourceLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) {
}
if (!p_skip_first_tag) {
-
err = VariantParser::parse_tag(&stream, lines, error_text, next_tag, &rp);
if (err) {
@@ -966,7 +933,6 @@ void ResourceLoaderText::open(FileAccess *p_f, bool p_skip_first_tag) {
}
static void bs_save_unicode_string(FileAccess *f, const String &p_string, bool p_bit_on_len = false) {
-
CharString utf8 = p_string.utf8();
if (p_bit_on_len) {
f->store_32((utf8.length() + 1) | 0x80000000);
@@ -977,9 +943,9 @@ static void bs_save_unicode_string(FileAccess *f, const String &p_string, bool p
}
Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path) {
-
- if (error)
+ if (error) {
return error;
+ }
FileAccessRef wf = FileAccess::open(p_path, FileAccess::WRITE);
if (!wf) {
@@ -999,8 +965,9 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path)
bs_save_unicode_string(wf.f, is_scene ? "PackedScene" : resource_type);
wf->store_64(0); //offset to import metadata, this is no longer used
- for (int i = 0; i < 14; i++)
+ for (int i = 0; i < 14; i++) {
wf->store_32(0); // reserved
+ }
wf->store_32(0); //string table size, will not be in use
size_t ext_res_count_pos = wf->get_position();
@@ -1016,7 +983,6 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path)
rp.userdata = &dummy_read;
while (next_tag.name == "ext_resource") {
-
if (!next_tag.fields.has("path")) {
error = ERR_FILE_CORRUPT;
error_text = "Missing 'path' in external resource tag";
@@ -1080,7 +1046,6 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path)
Vector<size_t> local_pointers_pos;
while (next_tag.name == "sub_resource" || next_tag.name == "resource") {
-
String type;
int id = -1;
bool main_res;
@@ -1122,7 +1087,6 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path)
int prop_count = 0;
while (true) {
-
String assign;
Variant value;
@@ -1139,14 +1103,12 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path)
}
if (assign != String()) {
-
Map<StringName, int> empty_string_map; //unused
bs_save_unicode_string(wf2, assign, true);
ResourceFormatSaverBinaryInstance::write_variant(wf2, value, dummy_read.resource_set, dummy_read.external_resources, empty_string_map);
prop_count++;
} else if (next_tag.name != String()) {
-
error = OK;
break;
} else {
@@ -1166,7 +1128,6 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path)
//this is a node, must save one more!
if (!is_scene) {
-
error_text += "found the 'node' tag on a resource file!";
_printerr();
error = ERR_FILE_CORRUPT;
@@ -1175,8 +1136,9 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path)
Ref<PackedScene> packed_scene = _parse_node_tag(rp);
- if (!packed_scene.is_valid())
+ if (!packed_scene.is_valid()) {
return error;
+ }
error = OK;
//get it here
@@ -1195,9 +1157,9 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path)
int prop_count = 0;
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
-
- if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
continue;
+ }
String name = E->get().name;
Variant value = packed_scene->get(name);
@@ -1241,7 +1203,6 @@ Error ResourceLoaderText::save_as_binary(FileAccess *p_f, const String &p_path)
}
String ResourceLoaderText::recognize(FileAccess *p_f) {
-
error = OK;
lines = 1;
@@ -1268,11 +1229,13 @@ String ResourceLoaderText::recognize(FileAccess *p_f) {
}
}
- if (tag.name == "gd_scene")
+ if (tag.name == "gd_scene") {
return "PackedScene";
+ }
- if (tag.name != "gd_resource")
+ if (tag.name != "gd_resource") {
return "";
+ }
if (!tag.fields.has("type")) {
error_text = "Missing 'type' field in 'gd_resource' tag";
@@ -1285,10 +1248,10 @@ String ResourceLoaderText::recognize(FileAccess *p_f) {
/////////////////////
-RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
- if (r_error)
+RES ResourceFormatLoaderText::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_CANT_OPEN;
+ }
Error err;
@@ -1298,6 +1261,7 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina
ResourceLoaderText loader;
String path = p_original_path != "" ? p_original_path : p_path;
+ loader.use_nocache = p_no_cache;
loader.use_sub_threads = p_use_sub_threads;
loader.local_path = ProjectSettings::get_singleton()->localize_path(path);
loader.progress = r_progress;
@@ -1316,41 +1280,39 @@ RES ResourceFormatLoaderText::load(const String &p_path, const String &p_origina
}
void ResourceFormatLoaderText::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const {
-
if (p_type == "") {
get_recognized_extensions(p_extensions);
return;
}
- if (p_type == "PackedScene")
+ if (p_type == "PackedScene") {
p_extensions->push_back("tscn");
- else
+ } else {
p_extensions->push_back("tres");
+ }
}
void ResourceFormatLoaderText::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("tscn");
p_extensions->push_back("tres");
}
bool ResourceFormatLoaderText::handles_type(const String &p_type) const {
-
return true;
}
-String ResourceFormatLoaderText::get_resource_type(const String &p_path) const {
+String ResourceFormatLoaderText::get_resource_type(const String &p_path) const {
String ext = p_path.get_extension().to_lower();
- if (ext == "tscn")
+ if (ext == "tscn") {
return "PackedScene";
- else if (ext != "tres")
+ } else if (ext != "tres") {
return String();
+ }
//for anyhting else must test..
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
-
return ""; //could not rwead
}
@@ -1363,10 +1325,8 @@ String ResourceFormatLoaderText::get_resource_type(const String &p_path) const {
}
void ResourceFormatLoaderText::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
-
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
-
ERR_FAIL();
}
@@ -1378,10 +1338,8 @@ void ResourceFormatLoaderText::get_dependencies(const String &p_path, List<Strin
}
Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
-
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
if (!f) {
-
ERR_FAIL_V(ERR_CANT_OPEN);
}
@@ -1395,7 +1353,6 @@ Error ResourceFormatLoaderText::rename_dependencies(const String &p_path, const
ResourceFormatLoaderText *ResourceFormatLoaderText::singleton = nullptr;
Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path, const String &p_dst_path) {
-
Error err;
FileAccess *f = FileAccess::open(p_src_path, FileAccess::READ, &err);
@@ -1422,18 +1379,14 @@ Error ResourceFormatLoaderText::convert_file_to_binary(const String &p_src_path,
/*****************************************************************************************************/
String ResourceFormatSaverTextInstance::_write_resources(void *ud, const RES &p_resource) {
-
ResourceFormatSaverTextInstance *rsi = (ResourceFormatSaverTextInstance *)ud;
return rsi->_write_resource(p_resource);
}
String ResourceFormatSaverTextInstance::_write_resource(const RES &res) {
-
if (external_resources.has(res)) {
-
return "ExtResource( " + itos(external_resources[res]) + " )";
} else {
-
if (internal_resources.has(res)) {
return "SubResource( " + itos(internal_resources[res]) + " )";
} else if (res->get_path().length() && res->get_path().find("::") == -1) {
@@ -1451,14 +1404,13 @@ String ResourceFormatSaverTextInstance::_write_resource(const RES &res) {
}
void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, bool p_main) {
-
switch (p_variant.get_type()) {
case Variant::OBJECT: {
-
RES res = p_variant;
- if (res.is_null() || external_resources.has(res))
+ if (res.is_null() || external_resources.has(res)) {
return;
+ }
if (!p_main && (!bundle_resources) && res->get_path().length() && res->get_path().find("::") == -1) {
if (res->get_path() == local_path) {
@@ -1470,8 +1422,9 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
return;
}
- if (resource_set.has(res))
+ if (resource_set.has(res)) {
return;
+ }
List<PropertyInfo> property_list;
@@ -1481,11 +1434,9 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
List<PropertyInfo>::Element *I = property_list.front();
while (I) {
-
PropertyInfo pi = I->get();
if (pi.usage & PROPERTY_USAGE_STORAGE) {
-
Variant v = res->get(I->get().name);
if (pi.usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
@@ -1511,23 +1462,19 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
} break;
case Variant::ARRAY: {
-
Array varray = p_variant;
int len = varray.size();
for (int i = 0; i < len; i++) {
-
const Variant &v = varray.get(i);
_find_resources(v);
}
} break;
case Variant::DICTIONARY: {
-
Dictionary d = p_variant;
List<Variant> keys;
d.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
-
Variant v = d[E->get()];
_find_resources(v);
}
@@ -1538,7 +1485,6 @@ void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant,
}
Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
if (p_path.ends_with(".tscn")) {
packed_scene = p_resource;
}
@@ -1564,8 +1510,9 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
if (packed_scene.is_valid()) {
//add instances to external resources if saving a packed scene
for (int i = 0; i < packed_scene->get_state()->get_node_count(); i++) {
- if (packed_scene->get_state()->is_node_instance_placeholder(i))
+ if (packed_scene->get_state()->is_node_instance_placeholder(i)) {
continue;
+ }
Ref<PackedScene> instance = packed_scene->get_state()->get_node_instance(i);
if (instance.is_valid() && !external_resources.has(instance)) {
@@ -1577,8 +1524,9 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
{
String title = packed_scene.is_valid() ? "[gd_scene " : "[gd_resource ";
- if (packed_scene.is_null())
+ if (packed_scene.is_null()) {
title += "type=\"" + p_resource->get_class() + "\" ";
+ }
int load_steps = saved_resources.size() + external_resources.size();
/*
if (packed_scene.is_valid()) {
@@ -1635,7 +1583,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
Vector<ResourceSort> sorted_er;
for (Map<RES, int>::Element *E = external_resources.front(); E; E = E->next()) {
-
ResourceSort rs;
rs.resource = E->key();
rs.index = E->get();
@@ -1650,16 +1597,15 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_string("[ext_resource path=\"" + p + "\" type=\"" + sorted_er[i].resource->get_save_class() + "\" id=" + itos(sorted_er[i].index) + "]\n"); //bundled
}
- if (external_resources.size())
+ if (external_resources.size()) {
f->store_line(String()); //separate
+ }
Set<int> used_indices;
for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) {
-
RES res = E->get();
if (E->next() && (res->get_path() == "" || res->get_path().find("::") != -1)) {
-
if (res->get_subindex() != 0) {
if (used_indices.has(res->get_subindex())) {
res->set_subindex(0); //repeated
@@ -1671,13 +1617,13 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
for (List<RES>::Element *E = saved_resources.front(); E; E = E->next()) {
-
RES res = E->get();
ERR_CONTINUE(!resource_set.has(res));
bool main = (E->next() == nullptr);
- if (main && packed_scene.is_valid())
+ if (main && packed_scene.is_valid()) {
break; //save as a scene
+ }
if (main) {
f->store_line("[resource]");
@@ -1710,12 +1656,11 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
res->get_property_list(&property_list);
//property_list.sort();
for (List<PropertyInfo>::Element *PE = property_list.front(); PE; PE = PE->next()) {
-
- if (skip_editor && PE->get().name.begins_with("__editor"))
+ if (skip_editor && PE->get().name.begins_with("__editor")) {
continue;
+ }
if (PE->get().usage & PROPERTY_USAGE_STORAGE) {
-
String name = PE->get().name;
Variant value;
if (PE->get().usage & PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT) {
@@ -1734,8 +1679,9 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
continue;
}
- if (PE->get().type == Variant::OBJECT && value.is_zero() && !(PE->get().usage & PROPERTY_USAGE_STORE_IF_NULL))
+ if (PE->get().type == Variant::OBJECT && value.is_zero() && !(PE->get().usage & PROPERTY_USAGE_STORE_IF_NULL)) {
continue;
+ }
String vars;
VariantWriter::write_to_string(value, vars, _write_resources, this);
@@ -1743,15 +1689,15 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
}
- if (E->next())
+ if (E->next()) {
f->store_line(String());
+ }
}
if (packed_scene.is_valid()) {
//if this is a scene, save nodes and connections!
Ref<SceneState> state = packed_scene->get_state();
for (int i = 0; i < state->get_node_count(); i++) {
-
StringName type = state->get_node_type(i);
StringName name = state->get_node_name(i);
int index = state->get_node_index(i);
@@ -1789,7 +1735,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_string(header);
if (instance_placeholder != String()) {
-
String vars;
f->store_string(" instance_placeholder=");
VariantWriter::write_to_string(instance_placeholder, vars, _write_resources, this);
@@ -1797,7 +1742,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
if (instance.is_valid()) {
-
String vars;
f->store_string(" instance=");
VariantWriter::write_to_string(instance, vars, _write_resources, this);
@@ -1807,19 +1751,18 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
f->store_line("]");
for (int j = 0; j < state->get_node_property_count(i); j++) {
-
String vars;
VariantWriter::write_to_string(state->get_node_property_value(i, j), vars, _write_resources, this);
f->store_string(String(state->get_node_property_name(i, j)).property_name_encode() + " = " + vars + "\n");
}
- if (i < state->get_node_count() - 1)
+ if (i < state->get_node_count() - 1) {
f->store_line(String());
+ }
}
for (int i = 0; i < state->get_connection_count(); i++) {
-
String connstr = "[connection";
connstr += " signal=\"" + String(state->get_connection_signal(i)) + "\"";
connstr += " from=\"" + String(state->get_connection_source(i).simplified()) + "\"";
@@ -1859,7 +1802,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r
}
Error ResourceFormatSaverText::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
if (p_path.ends_with(".sct") && p_resource->get_class() != "PackedScene") {
return ERR_FILE_UNRECOGNIZED;
}
@@ -1869,15 +1811,15 @@ Error ResourceFormatSaverText::save(const String &p_path, const RES &p_resource,
}
bool ResourceFormatSaverText::recognize(const RES &p_resource) const {
-
return true; // all recognized!
}
-void ResourceFormatSaverText::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
- if (p_resource->get_class() == "PackedScene")
+void ResourceFormatSaverText::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
+ if (p_resource->get_class() == "PackedScene") {
p_extensions->push_back("tscn"); //text scene
- else
+ } else {
p_extensions->push_back("tres"); //text resource
+ }
}
ResourceFormatSaverText *ResourceFormatSaverText::singleton = nullptr;
diff --git a/scene/resources/resource_format_text.h b/scene/resources/resource_format_text.h
index fbbd2e3346..cf522c9364 100644
--- a/scene/resources/resource_format_text.h
+++ b/scene/resources/resource_format_text.h
@@ -38,7 +38,6 @@
#include "scene/resources/packed_scene.h"
class ResourceLoaderText {
-
bool translation_remapped;
String local_path;
String res_path;
@@ -62,6 +61,7 @@ class ResourceLoaderText {
//Map<String,String> remaps;
Map<int, ExtResource> ext_resources;
+ Map<int, RES> int_resources;
int resources_total;
int resource_current;
@@ -69,6 +69,8 @@ class ResourceLoaderText {
VariantParser::Tag next_tag;
+ bool use_nocache;
+
bool use_sub_threads;
float *progress;
@@ -89,7 +91,6 @@ class ResourceLoaderText {
};
struct DummyReadData {
-
Map<RES, int> external_resources;
Map<int, RES> rev_external_resources;
Set<RES> resource_set;
@@ -106,7 +107,6 @@ class ResourceLoaderText {
friend class ResourceFormatLoaderText;
- List<RES> resource_cache;
Error error;
RES resource;
@@ -134,7 +134,7 @@ public:
class ResourceFormatLoaderText : public ResourceFormatLoader {
public:
static ResourceFormatLoaderText *singleton;
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
@@ -148,7 +148,6 @@ public:
};
class ResourceFormatSaverTextInstance {
-
String local_path;
Ref<PackedScene> packed_scene;
diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp
index 814c349784..7b409eebbb 100644
--- a/scene/resources/segment_shape_2d.cpp
+++ b/scene/resources/segment_shape_2d.cpp
@@ -34,14 +34,12 @@
#include "servers/rendering_server.h"
bool SegmentShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {
-
Vector2 l[2] = { a, b };
Vector2 closest = Geometry::get_closest_point_to_segment_2d(p_point, l);
return p_point.distance_to(closest) < p_tolerance;
}
void SegmentShape2D::_update_shape() {
-
Rect2 r;
r.position = a;
r.size = b;
@@ -50,32 +48,28 @@ void SegmentShape2D::_update_shape() {
}
void SegmentShape2D::set_a(const Vector2 &p_a) {
-
a = p_a;
_update_shape();
}
-Vector2 SegmentShape2D::get_a() const {
+Vector2 SegmentShape2D::get_a() const {
return a;
}
void SegmentShape2D::set_b(const Vector2 &p_b) {
-
b = p_b;
_update_shape();
}
-Vector2 SegmentShape2D::get_b() const {
+Vector2 SegmentShape2D::get_b() const {
return b;
}
void SegmentShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
RenderingServer::get_singleton()->canvas_item_add_line(p_to_rid, a, b, p_color, 3);
}
Rect2 SegmentShape2D::get_rect() const {
-
Rect2 rect;
rect.position = a;
rect.expand_to(b);
@@ -87,7 +81,6 @@ real_t SegmentShape2D::get_enclosing_radius() const {
}
void SegmentShape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_a", "a"), &SegmentShape2D::set_a);
ClassDB::bind_method(D_METHOD("get_a"), &SegmentShape2D::get_a);
@@ -100,7 +93,6 @@ void SegmentShape2D::_bind_methods() {
SegmentShape2D::SegmentShape2D() :
Shape2D(PhysicsServer2D::get_singleton()->segment_shape_create()) {
-
a = Vector2();
b = Vector2(0, 10);
_update_shape();
@@ -109,7 +101,6 @@ SegmentShape2D::SegmentShape2D() :
////////////////////////////////////////////////////////////
void RayShape2D::_update_shape() {
-
Dictionary d;
d["length"] = length;
d["slips_on_slope"] = slips_on_slope;
@@ -118,7 +109,6 @@ void RayShape2D::_update_shape() {
}
void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
-
Vector2 tip = Vector2(0, get_length());
RS::get_singleton()->canvas_item_add_line(p_to_rid, Vector2(), tip, p_color, 3);
Vector<Vector2> pts;
@@ -127,14 +117,14 @@ void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
pts.push_back(tip + Vector2(Math_SQRT12 * tsize, 0));
pts.push_back(tip + Vector2(-Math_SQRT12 * tsize, 0));
Vector<Color> cols;
- for (int i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++) {
cols.push_back(p_color);
+ }
RS::get_singleton()->canvas_item_add_primitive(p_to_rid, pts, cols, Vector<Point2>(), RID());
}
Rect2 RayShape2D::get_rect() const {
-
Rect2 rect;
rect.position = Vector2();
rect.expand_to(Vector2(0, length));
@@ -147,7 +137,6 @@ real_t RayShape2D::get_enclosing_radius() const {
}
void RayShape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_length", "length"), &RayShape2D::set_length);
ClassDB::bind_method(D_METHOD("get_length"), &RayShape2D::get_length);
@@ -159,17 +148,15 @@ void RayShape2D::_bind_methods() {
}
void RayShape2D::set_length(real_t p_length) {
-
length = p_length;
_update_shape();
}
-real_t RayShape2D::get_length() const {
+real_t RayShape2D::get_length() const {
return length;
}
void RayShape2D::set_slips_on_slope(bool p_active) {
-
slips_on_slope = p_active;
_update_shape();
}
@@ -180,7 +167,6 @@ bool RayShape2D::get_slips_on_slope() const {
RayShape2D::RayShape2D() :
Shape2D(PhysicsServer2D::get_singleton()->ray_shape_create()) {
-
length = 20;
slips_on_slope = false;
_update_shape();
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index a62e7ded16..4ca8032d65 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -36,12 +36,10 @@
#include "texture.h"
Shader::Mode Shader::get_mode() const {
-
return mode;
}
void Shader::set_code(const String &p_code) {
-
String type = ShaderLanguage::get_shader_type(p_code);
if (type == "canvas_item") {
@@ -61,13 +59,11 @@ void Shader::set_code(const String &p_code) {
}
String Shader::get_code() const {
-
_update_shader();
return RenderingServer::get_singleton()->shader_get_code(shader);
}
void Shader::get_param_list(List<PropertyInfo> *p_params) const {
-
_update_shader();
List<PropertyInfo> local;
@@ -76,7 +72,6 @@ void Shader::get_param_list(List<PropertyInfo> *p_params) const {
params_cache_dirty = false;
for (List<PropertyInfo>::Element *E = local.front(); E; E = E->next()) {
-
PropertyInfo pi = E->get();
if (default_textures.has(pi.name)) { //do not show default textures
continue;
@@ -84,24 +79,22 @@ void Shader::get_param_list(List<PropertyInfo> *p_params) const {
pi.name = "shader_param/" + pi.name;
params_cache[pi.name] = E->get().name;
if (p_params) {
-
//small little hack
- if (pi.type == Variant::_RID)
+ if (pi.type == Variant::_RID) {
pi.type = Variant::OBJECT;
+ }
p_params->push_back(pi);
}
}
}
RID Shader::get_rid() const {
-
_update_shader();
return shader;
}
void Shader::set_default_texture_param(const StringName &p_param, const Ref<Texture2D> &p_texture) {
-
if (p_texture.is_valid()) {
default_textures[p_param] = p_texture;
RS::get_singleton()->shader_set_default_texture_param(shader, p_param, p_texture->get_rid());
@@ -114,17 +107,15 @@ void Shader::set_default_texture_param(const StringName &p_param, const Ref<Text
}
Ref<Texture2D> Shader::get_default_texture_param(const StringName &p_param) const {
-
- if (default_textures.has(p_param))
+ if (default_textures.has(p_param)) {
return default_textures[p_param];
- else
+ } else {
return Ref<Texture2D>();
+ }
}
void Shader::get_default_texture_param_list(List<StringName> *r_textures) const {
-
for (const Map<StringName, Ref<Texture2D>>::Element *E = default_textures.front(); E; E = E->next()) {
-
r_textures->push_back(E->key());
}
}
@@ -134,7 +125,6 @@ bool Shader::is_text_shader() const {
}
bool Shader::has_param(const StringName &p_param) const {
-
return params_cache.has(p_param);
}
@@ -142,7 +132,6 @@ void Shader::_update_shader() const {
}
void Shader::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_mode"), &Shader::get_mode);
ClassDB::bind_method(D_METHOD("set_code", "code"), &Shader::set_code);
@@ -164,22 +153,21 @@ void Shader::_bind_methods() {
}
Shader::Shader() {
-
mode = MODE_SPATIAL;
shader = RenderingServer::get_singleton()->shader_create();
params_cache_dirty = true;
}
Shader::~Shader() {
-
RenderingServer::get_singleton()->free(shader);
}
-////////////
-RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+////////////
- if (r_error)
+RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ if (r_error) {
*r_error = ERR_FILE_CANT_OPEN;
+ }
Ref<Shader> shader;
shader.instance();
@@ -191,32 +179,30 @@ RES ResourceFormatLoaderShader::load(const String &p_path, const String &p_origi
shader->set_code(str);
- if (r_error)
+ if (r_error) {
*r_error = OK;
+ }
return shader;
}
void ResourceFormatLoaderShader::get_recognized_extensions(List<String> *p_extensions) const {
-
p_extensions->push_back("shader");
}
bool ResourceFormatLoaderShader::handles_type(const String &p_type) const {
-
return (p_type == "Shader");
}
String ResourceFormatLoaderShader::get_resource_type(const String &p_path) const {
-
String el = p_path.get_extension().to_lower();
- if (el == "shader")
+ if (el == "shader") {
return "Shader";
+ }
return "";
}
Error ResourceFormatSaverShader::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
-
Ref<Shader> shader = p_resource;
ERR_FAIL_COND_V(shader.is_null(), ERR_INVALID_PARAMETER);
@@ -239,14 +225,13 @@ Error ResourceFormatSaverShader::save(const String &p_path, const RES &p_resourc
}
void ResourceFormatSaverShader::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
-
if (const Shader *shader = Object::cast_to<Shader>(*p_resource)) {
if (shader->is_text_shader()) {
p_extensions->push_back("shader");
}
}
}
-bool ResourceFormatSaverShader::recognize(const RES &p_resource) const {
+bool ResourceFormatSaverShader::recognize(const RES &p_resource) const {
return p_resource->get_class_name() == "Shader"; //only shader, not inherited
}
diff --git a/scene/resources/shader.h b/scene/resources/shader.h
index cf0cec362c..2cdc2ec93f 100644
--- a/scene/resources/shader.h
+++ b/scene/resources/shader.h
@@ -37,7 +37,6 @@
#include "scene/resources/texture.h"
class Shader : public Resource {
-
GDCLASS(Shader, Resource);
OBJ_SAVE_TYPE(Shader);
@@ -83,12 +82,14 @@ public:
virtual bool is_text_shader() const;
_FORCE_INLINE_ StringName remap_param(const StringName &p_param) const {
- if (params_cache_dirty)
+ if (params_cache_dirty) {
get_param_list(nullptr);
+ }
const Map<StringName, StringName>::Element *E = params_cache.find(p_param);
- if (E)
+ if (E) {
return E->get();
+ }
return StringName();
}
@@ -102,7 +103,7 @@ VARIANT_ENUM_CAST(Shader::Mode);
class ResourceFormatLoaderShader : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp
index 4fe585053a..99e8020e34 100644
--- a/scene/resources/shape_2d.cpp
+++ b/scene/resources/shape_2d.cpp
@@ -31,23 +31,19 @@
#include "shape_2d.h"
#include "servers/physics_server_2d.h"
RID Shape2D::get_rid() const {
-
return shape;
}
void Shape2D::set_custom_solver_bias(real_t p_bias) {
-
custom_bias = p_bias;
PhysicsServer2D::get_singleton()->shape_set_custom_solver_bias(shape, custom_bias);
}
real_t Shape2D::get_custom_solver_bias() const {
-
return custom_bias;
}
bool Shape2D::collide_with_motion(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion) {
-
ERR_FAIL_COND_V(p_shape.is_null(), false);
int r;
return PhysicsServer2D::get_singleton()->shape_collide(get_rid(), p_local_xform, p_local_motion, p_shape->get_rid(), p_shape_xform, p_shape_motion, nullptr, 0, r);
@@ -60,14 +56,14 @@ bool Shape2D::collide(const Transform2D &p_local_xform, const Ref<Shape2D> &p_sh
}
Array Shape2D::collide_with_motion_and_get_contacts(const Transform2D &p_local_xform, const Vector2 &p_local_motion, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform, const Vector2 &p_shape_motion) {
-
ERR_FAIL_COND_V(p_shape.is_null(), Array());
const int max_contacts = 16;
Vector2 result[max_contacts * 2];
int contacts = 0;
- if (!PhysicsServer2D::get_singleton()->shape_collide(get_rid(), p_local_xform, p_local_motion, p_shape->get_rid(), p_shape_xform, p_shape_motion, result, max_contacts, contacts))
+ if (!PhysicsServer2D::get_singleton()->shape_collide(get_rid(), p_local_xform, p_local_motion, p_shape->get_rid(), p_shape_xform, p_shape_motion, result, max_contacts, contacts)) {
return Array();
+ }
Array results;
results.resize(contacts * 2);
@@ -77,15 +73,16 @@ Array Shape2D::collide_with_motion_and_get_contacts(const Transform2D &p_local_x
return results;
}
-Array Shape2D::collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform) {
+Array Shape2D::collide_and_get_contacts(const Transform2D &p_local_xform, const Ref<Shape2D> &p_shape, const Transform2D &p_shape_xform) {
ERR_FAIL_COND_V(p_shape.is_null(), Array());
const int max_contacts = 16;
Vector2 result[max_contacts * 2];
int contacts = 0;
- if (!PhysicsServer2D::get_singleton()->shape_collide(get_rid(), p_local_xform, Vector2(), p_shape->get_rid(), p_shape_xform, Vector2(), result, max_contacts, contacts))
+ if (!PhysicsServer2D::get_singleton()->shape_collide(get_rid(), p_local_xform, Vector2(), p_shape->get_rid(), p_shape_xform, Vector2(), result, max_contacts, contacts)) {
return Array();
+ }
Array results;
results.resize(contacts * 2);
@@ -97,7 +94,6 @@ Array Shape2D::collide_and_get_contacts(const Transform2D &p_local_xform, const
}
void Shape2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_custom_solver_bias", "bias"), &Shape2D::set_custom_solver_bias);
ClassDB::bind_method(D_METHOD("get_custom_solver_bias"), &Shape2D::get_custom_solver_bias);
ClassDB::bind_method(D_METHOD("collide", "local_xform", "with_shape", "shape_xform"), &Shape2D::collide);
@@ -114,6 +110,5 @@ Shape2D::Shape2D(const RID &p_rid) {
}
Shape2D::~Shape2D() {
-
PhysicsServer2D::get_singleton()->free(shape);
}
diff --git a/scene/resources/shape_3d.cpp b/scene/resources/shape_3d.cpp
index f4a5d91e52..59766f4f1f 100644
--- a/scene/resources/shape_3d.cpp
+++ b/scene/resources/shape_3d.cpp
@@ -36,11 +36,9 @@
#include "servers/physics_server_3d.h"
void Shape3D::add_vertices_to_array(Vector<Vector3> &array, const Transform &p_xform) {
-
Vector<Vector3> toadd = get_debug_mesh_lines();
if (toadd.size()) {
-
int base = array.size();
array.resize(base + toadd.size());
Vector3 *w = array.ptrw();
@@ -60,9 +58,9 @@ void Shape3D::set_margin(real_t p_margin) {
}
Ref<ArrayMesh> Shape3D::get_debug_mesh() {
-
- if (debug_mesh_cache.is_valid())
+ if (debug_mesh_cache.is_valid()) {
return debug_mesh_cache;
+ }
Vector<Vector3> lines = get_debug_mesh_lines();
@@ -73,7 +71,6 @@ Ref<ArrayMesh> Shape3D::get_debug_mesh() {
Vector<Vector3> array;
array.resize(lines.size());
{
-
Vector3 *w = array.ptrw();
for (int i = 0; i < lines.size(); i++) {
w[i] = lines[i];
@@ -102,26 +99,19 @@ void Shape3D::_update_shape() {
}
void Shape3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Shape3D::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &Shape3D::get_margin);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin", PROPERTY_HINT_RANGE, "0.001,10,0.001"), "set_margin", "get_margin");
}
-Shape3D::Shape3D() :
- margin(0.04) {
-
- ERR_PRINT("Constructor must not be called!");
+Shape3D::Shape3D() {
+ ERR_PRINT("Default constructor must not be called!");
}
Shape3D::Shape3D(RID p_shape) :
- margin(0.04) {
-
- shape = p_shape;
-}
+ shape(p_shape) {}
Shape3D::~Shape3D() {
-
PhysicsServer3D::get_singleton()->free(shape);
}
diff --git a/scene/resources/shape_3d.h b/scene/resources/shape_3d.h
index e7a516412d..a83b2ed009 100644
--- a/scene/resources/shape_3d.h
+++ b/scene/resources/shape_3d.h
@@ -36,12 +36,11 @@
class ArrayMesh;
class Shape3D : public Resource {
-
GDCLASS(Shape3D, Resource);
OBJ_SAVE_TYPE(Shape3D);
RES_BASE_EXTENSION("shape");
RID shape;
- real_t margin;
+ real_t margin = 0.04;
Ref<ArrayMesh> debug_mesh_cache;
diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp
index df0620b6c4..e88841a531 100644
--- a/scene/resources/skin.cpp
+++ b/scene/resources/skin.cpp
@@ -46,7 +46,6 @@ void Skin::add_bind(int p_bone, const Transform &p_pose) {
}
void Skin::add_named_bind(const String &p_name, const Transform &p_pose) {
-
uint32_t index = bind_count;
set_bind_count(bind_count + 1);
set_bind_name(index, p_name);
@@ -105,7 +104,6 @@ bool Skin::_set(const StringName &p_name, const Variant &p_value) {
}
bool Skin::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name == "bind_count") {
r_ret = get_bind_count();
@@ -126,6 +124,7 @@ bool Skin::_get(const StringName &p_name, Variant &r_ret) const {
}
return false;
}
+
void Skin::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::INT, "bind_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"));
for (int i = 0; i < get_bind_count(); i++) {
@@ -136,7 +135,6 @@ void Skin::_get_property_list(List<PropertyInfo> *p_list) const {
}
void Skin::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_bind_count", "bind_count"), &Skin::set_bind_count);
ClassDB::bind_method(D_METHOD("get_bind_count"), &Skin::get_bind_count);
diff --git a/scene/resources/sky.cpp b/scene/resources/sky.cpp
index cbe86b16b2..54b6cde8bd 100644
--- a/scene/resources/sky.cpp
+++ b/scene/resources/sky.cpp
@@ -43,7 +43,6 @@ void Sky::set_radiance_size(RadianceSize p_size) {
}
Sky::RadianceSize Sky::get_radiance_size() const {
-
return radiance_size;
}
@@ -59,8 +58,9 @@ Sky::ProcessMode Sky::get_process_mode() const {
void Sky::set_material(const Ref<Material> &p_material) {
sky_material = p_material;
RID material_rid;
- if (sky_material.is_valid())
+ if (sky_material.is_valid()) {
material_rid = sky_material->get_rid();
+ }
RS::get_singleton()->sky_set_material(sky, material_rid);
}
@@ -69,12 +69,10 @@ Ref<Material> Sky::get_material() const {
}
RID Sky::get_rid() const {
-
return sky;
}
void Sky::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_radiance_size", "size"), &Sky::set_radiance_size);
ClassDB::bind_method(D_METHOD("get_radiance_size"), &Sky::get_radiance_size);
@@ -108,6 +106,5 @@ Sky::Sky() {
}
Sky::~Sky() {
-
RS::get_singleton()->free(sky);
} \ No newline at end of file
diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp
index a0b6ab1e30..69e8e0b5bd 100644
--- a/scene/resources/sky_material.cpp
+++ b/scene/resources/sky_material.cpp
@@ -31,103 +31,92 @@
#include "sky_material.h"
void ProceduralSkyMaterial::set_sky_top_color(const Color &p_sky_top) {
-
sky_top_color = p_sky_top;
RS::get_singleton()->material_set_param(_get_material(), "sky_top_color", sky_top_color.to_linear());
}
Color ProceduralSkyMaterial::get_sky_top_color() const {
-
return sky_top_color;
}
void ProceduralSkyMaterial::set_sky_horizon_color(const Color &p_sky_horizon) {
-
sky_horizon_color = p_sky_horizon;
RS::get_singleton()->material_set_param(_get_material(), "sky_horizon_color", sky_horizon_color.to_linear());
}
-Color ProceduralSkyMaterial::get_sky_horizon_color() const {
+Color ProceduralSkyMaterial::get_sky_horizon_color() const {
return sky_horizon_color;
}
void ProceduralSkyMaterial::set_sky_curve(float p_curve) {
-
sky_curve = p_curve;
RS::get_singleton()->material_set_param(_get_material(), "sky_curve", sky_curve);
}
-float ProceduralSkyMaterial::get_sky_curve() const {
+float ProceduralSkyMaterial::get_sky_curve() const {
return sky_curve;
}
void ProceduralSkyMaterial::set_sky_energy(float p_energy) {
-
sky_energy = p_energy;
RS::get_singleton()->material_set_param(_get_material(), "sky_energy", sky_energy);
}
-float ProceduralSkyMaterial::get_sky_energy() const {
+float ProceduralSkyMaterial::get_sky_energy() const {
return sky_energy;
}
void ProceduralSkyMaterial::set_ground_bottom_color(const Color &p_ground_bottom) {
-
ground_bottom_color = p_ground_bottom;
RS::get_singleton()->material_set_param(_get_material(), "ground_bottom_color", ground_bottom_color.to_linear());
}
-Color ProceduralSkyMaterial::get_ground_bottom_color() const {
+Color ProceduralSkyMaterial::get_ground_bottom_color() const {
return ground_bottom_color;
}
void ProceduralSkyMaterial::set_ground_horizon_color(const Color &p_ground_horizon) {
-
ground_horizon_color = p_ground_horizon;
RS::get_singleton()->material_set_param(_get_material(), "ground_horizon_color", ground_horizon_color.to_linear());
}
-Color ProceduralSkyMaterial::get_ground_horizon_color() const {
+Color ProceduralSkyMaterial::get_ground_horizon_color() const {
return ground_horizon_color;
}
void ProceduralSkyMaterial::set_ground_curve(float p_curve) {
-
ground_curve = p_curve;
RS::get_singleton()->material_set_param(_get_material(), "ground_curve", ground_curve);
}
-float ProceduralSkyMaterial::get_ground_curve() const {
+float ProceduralSkyMaterial::get_ground_curve() const {
return ground_curve;
}
void ProceduralSkyMaterial::set_ground_energy(float p_energy) {
-
ground_energy = p_energy;
RS::get_singleton()->material_set_param(_get_material(), "ground_energy", ground_energy);
}
-float ProceduralSkyMaterial::get_ground_energy() const {
+float ProceduralSkyMaterial::get_ground_energy() const {
return ground_energy;
}
void ProceduralSkyMaterial::set_sun_angle_max(float p_angle) {
-
sun_angle_max = p_angle;
RS::get_singleton()->material_set_param(_get_material(), "sun_angle_max", Math::deg2rad(sun_angle_max));
}
-float ProceduralSkyMaterial::get_sun_angle_max() const {
+float ProceduralSkyMaterial::get_sun_angle_max() const {
return sun_angle_max;
}
void ProceduralSkyMaterial::set_sun_curve(float p_curve) {
-
sun_curve = p_curve;
RS::get_singleton()->material_set_param(_get_material(), "sun_curve", sun_curve);
}
-float ProceduralSkyMaterial::get_sun_curve() const {
+float ProceduralSkyMaterial::get_sun_curve() const {
return sun_curve;
}
@@ -136,17 +125,14 @@ bool ProceduralSkyMaterial::_can_do_next_pass() const {
}
Shader::Mode ProceduralSkyMaterial::get_shader_mode() const {
-
return Shader::MODE_SKY;
}
RID ProceduralSkyMaterial::get_shader_rid() const {
-
return shader;
}
void ProceduralSkyMaterial::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_sky_top_color", "color"), &ProceduralSkyMaterial::set_sky_top_color);
ClassDB::bind_method(D_METHOD("get_sky_top_color"), &ProceduralSkyMaterial::get_sky_top_color);
@@ -195,7 +181,6 @@ void ProceduralSkyMaterial::_bind_methods() {
}
ProceduralSkyMaterial::ProceduralSkyMaterial() {
-
String code = "shader_type sky;\n\n";
code += "uniform vec4 sky_top_color : hint_color = vec4(0.35, 0.46, 0.71, 1.0);\n";
@@ -285,13 +270,11 @@ ProceduralSkyMaterial::~ProceduralSkyMaterial() {
/* PanoramaSkyMaterial */
void PanoramaSkyMaterial::set_panorama(const Ref<Texture2D> &p_panorama) {
-
panorama = p_panorama;
RS::get_singleton()->material_set_param(_get_material(), "source_panorama", panorama);
}
Ref<Texture2D> PanoramaSkyMaterial::get_panorama() const {
-
return panorama;
}
@@ -300,17 +283,14 @@ bool PanoramaSkyMaterial::_can_do_next_pass() const {
}
Shader::Mode PanoramaSkyMaterial::get_shader_mode() const {
-
return Shader::MODE_SKY;
}
RID PanoramaSkyMaterial::get_shader_rid() const {
-
return shader;
}
void PanoramaSkyMaterial::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_panorama", "texture"), &PanoramaSkyMaterial::set_panorama);
ClassDB::bind_method(D_METHOD("get_panorama"), &PanoramaSkyMaterial::get_panorama);
@@ -336,124 +316,122 @@ PanoramaSkyMaterial::~PanoramaSkyMaterial() {
RS::get_singleton()->free(shader);
RS::get_singleton()->material_set_shader(_get_material(), RID());
}
+
//////////////////////////////////
/* PhysicalSkyMaterial */
void PhysicalSkyMaterial::set_rayleigh_coefficient(float p_rayleigh) {
-
rayleigh = p_rayleigh;
RS::get_singleton()->material_set_param(_get_material(), "rayleigh", rayleigh);
}
-float PhysicalSkyMaterial::get_rayleigh_coefficient() const {
+float PhysicalSkyMaterial::get_rayleigh_coefficient() const {
return rayleigh;
}
void PhysicalSkyMaterial::set_rayleigh_color(Color p_rayleigh_color) {
-
rayleigh_color = p_rayleigh_color;
RS::get_singleton()->material_set_param(_get_material(), "rayleigh_color", rayleigh_color);
}
-Color PhysicalSkyMaterial::get_rayleigh_color() const {
+Color PhysicalSkyMaterial::get_rayleigh_color() const {
return rayleigh_color;
}
void PhysicalSkyMaterial::set_mie_coefficient(float p_mie) {
-
mie = p_mie;
RS::get_singleton()->material_set_param(_get_material(), "mie", mie);
}
-float PhysicalSkyMaterial::get_mie_coefficient() const {
+float PhysicalSkyMaterial::get_mie_coefficient() const {
return mie;
}
void PhysicalSkyMaterial::set_mie_eccentricity(float p_eccentricity) {
-
mie_eccentricity = p_eccentricity;
RS::get_singleton()->material_set_param(_get_material(), "mie_eccentricity", mie_eccentricity);
}
-float PhysicalSkyMaterial::get_mie_eccentricity() const {
+float PhysicalSkyMaterial::get_mie_eccentricity() const {
return mie_eccentricity;
}
void PhysicalSkyMaterial::set_mie_color(Color p_mie_color) {
-
mie_color = p_mie_color;
RS::get_singleton()->material_set_param(_get_material(), "mie_color", mie_color);
}
+
Color PhysicalSkyMaterial::get_mie_color() const {
return mie_color;
}
void PhysicalSkyMaterial::set_turbidity(float p_turbidity) {
-
turbidity = p_turbidity;
RS::get_singleton()->material_set_param(_get_material(), "turbidity", turbidity);
}
-float PhysicalSkyMaterial::get_turbidity() const {
+float PhysicalSkyMaterial::get_turbidity() const {
return turbidity;
}
void PhysicalSkyMaterial::set_sun_disk_scale(float p_sun_disk_scale) {
-
sun_disk_scale = p_sun_disk_scale;
RS::get_singleton()->material_set_param(_get_material(), "sun_disk_scale", sun_disk_scale);
}
-float PhysicalSkyMaterial::get_sun_disk_scale() const {
+float PhysicalSkyMaterial::get_sun_disk_scale() const {
return sun_disk_scale;
}
void PhysicalSkyMaterial::set_ground_color(Color p_ground_color) {
-
ground_color = p_ground_color;
RS::get_singleton()->material_set_param(_get_material(), "ground_color", ground_color);
}
-Color PhysicalSkyMaterial::get_ground_color() const {
+Color PhysicalSkyMaterial::get_ground_color() const {
return ground_color;
}
void PhysicalSkyMaterial::set_exposure(float p_exposure) {
-
exposure = p_exposure;
RS::get_singleton()->material_set_param(_get_material(), "exposure", exposure);
}
-float PhysicalSkyMaterial::get_exposure() const {
+float PhysicalSkyMaterial::get_exposure() const {
return exposure;
}
void PhysicalSkyMaterial::set_dither_strength(float p_dither_strength) {
-
dither_strength = p_dither_strength;
RS::get_singleton()->material_set_param(_get_material(), "dither_strength", dither_strength);
}
-float PhysicalSkyMaterial::get_dither_strength() const {
+float PhysicalSkyMaterial::get_dither_strength() const {
return dither_strength;
}
+void PhysicalSkyMaterial::set_night_sky(const Ref<Texture2D> &p_night_sky) {
+ night_sky = p_night_sky;
+ RS::get_singleton()->material_set_param(_get_material(), "night_sky", night_sky);
+}
+
+Ref<Texture2D> PhysicalSkyMaterial::get_night_sky() const {
+ return night_sky;
+}
+
bool PhysicalSkyMaterial::_can_do_next_pass() const {
return false;
}
Shader::Mode PhysicalSkyMaterial::get_shader_mode() const {
-
return Shader::MODE_SKY;
}
RID PhysicalSkyMaterial::get_shader_rid() const {
-
return shader;
}
void PhysicalSkyMaterial::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_rayleigh_coefficient", "rayleigh"), &PhysicalSkyMaterial::set_rayleigh_coefficient);
ClassDB::bind_method(D_METHOD("get_rayleigh_coefficient"), &PhysicalSkyMaterial::get_rayleigh_coefficient);
@@ -484,6 +462,9 @@ void PhysicalSkyMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_dither_strength", "strength"), &PhysicalSkyMaterial::set_dither_strength);
ClassDB::bind_method(D_METHOD("get_dither_strength"), &PhysicalSkyMaterial::get_dither_strength);
+ ClassDB::bind_method(D_METHOD("set_night_sky", "night_sky"), &PhysicalSkyMaterial::set_night_sky);
+ ClassDB::bind_method(D_METHOD("get_night_sky"), &PhysicalSkyMaterial::get_night_sky);
+
ADD_GROUP("Rayleigh", "rayleigh_");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "rayleigh_coefficient", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_rayleigh_coefficient", "get_rayleigh_coefficient");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "rayleigh_color"), "set_rayleigh_color", "get_rayleigh_color");
@@ -498,6 +479,7 @@ void PhysicalSkyMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_color"), "set_ground_color", "get_ground_color");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "exposure", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_exposure", "get_exposure");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "dither_strength", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_dither_strength", "get_dither_strength");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "night_sky", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_night_sky", "get_night_sky");
}
PhysicalSkyMaterial::PhysicalSkyMaterial() {
@@ -515,6 +497,8 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() {
code += "uniform float exposure : hint_range(0, 128) = 0.1;\n";
code += "uniform float dither_strength : hint_range(0, 10) = 1.0;\n\n";
+ code += "uniform sampler2D night_sky : hint_black;";
+
code += "const float PI = 3.141592653589793238462643383279502884197169;\n";
code += "const vec3 UP = vec3( 0.0, 1.0, 0.0 );\n\n";
@@ -578,7 +562,7 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() {
code += "\tfloat sunAngularDiameterCos2 = cos(LIGHT0_SIZE * sun_disk_scale*0.5);\n";
code += "\tfloat sundisk = smoothstep(sunAngularDiameterCos, sunAngularDiameterCos2, cos_theta);\n";
code += "\tvec3 L0 = (sun_energy * 1900.0 * extinction) * sundisk * LIGHT0_COLOR;\n";
- code += "\t// Note: Add nightime here: L0 += night_sky * extinction\n\n";
+ code += "\tL0 += texture(night_sky, SKY_COORDS).xyz * extinction;\n\n";
code += "\tvec3 color = (Lin + L0) * 0.04;\n";
code += "\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n";
diff --git a/scene/resources/sky_material.h b/scene/resources/sky_material.h
index 9bd9d7ec8b..e470137d9e 100644
--- a/scene/resources/sky_material.h
+++ b/scene/resources/sky_material.h
@@ -35,7 +35,6 @@
#define SKY_MATERIAL_H
class ProceduralSkyMaterial : public Material {
-
GDCLASS(ProceduralSkyMaterial, Material);
private:
@@ -140,6 +139,7 @@ private:
Color ground_color;
float exposure;
float dither_strength;
+ Ref<Texture2D> night_sky;
protected:
static void _bind_methods();
@@ -176,6 +176,9 @@ public:
void set_dither_strength(float p_dither_strength);
float get_dither_strength() const;
+ void set_night_sky(const Ref<Texture2D> &p_night_sky);
+ Ref<Texture2D> get_night_sky() const;
+
virtual Shader::Mode get_shader_mode() const;
RID get_shader_rid() const;
diff --git a/scene/resources/sphere_shape_3d.cpp b/scene/resources/sphere_shape_3d.cpp
index 153db4c291..d24998ff18 100644
--- a/scene/resources/sphere_shape_3d.cpp
+++ b/scene/resources/sphere_shape_3d.cpp
@@ -32,13 +32,11 @@
#include "servers/physics_server_3d.h"
Vector<Vector3> SphereShape3D::get_debug_mesh_lines() {
-
float r = get_radius();
Vector<Vector3> points;
for (int i = 0; i <= 360; i++) {
-
float ra = Math::deg2rad((float)i);
float rb = Math::deg2rad((float)i + 1);
Point2 a = Vector2(Math::sin(ra), Math::cos(ra)) * r;
@@ -60,13 +58,11 @@ real_t SphereShape3D::get_enclosing_radius() const {
}
void SphereShape3D::_update_shape() {
-
PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), radius);
Shape3D::_update_shape();
}
void SphereShape3D::set_radius(float p_radius) {
-
radius = p_radius;
_update_shape();
notify_change_to_owners();
@@ -74,12 +70,10 @@ void SphereShape3D::set_radius(float p_radius) {
}
float SphereShape3D::get_radius() const {
-
return radius;
}
void SphereShape3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_radius", "radius"), &SphereShape3D::set_radius);
ClassDB::bind_method(D_METHOD("get_radius"), &SphereShape3D::get_radius);
@@ -88,6 +82,5 @@ void SphereShape3D::_bind_methods() {
SphereShape3D::SphereShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_SPHERE)) {
-
set_radius(1.0);
}
diff --git a/scene/resources/sphere_shape_3d.h b/scene/resources/sphere_shape_3d.h
index 3ed50cfe83..ee31bb615c 100644
--- a/scene/resources/sphere_shape_3d.h
+++ b/scene/resources/sphere_shape_3d.h
@@ -34,7 +34,6 @@
#include "scene/resources/shape_3d.h"
class SphereShape3D : public Shape3D {
-
GDCLASS(SphereShape3D, Shape3D);
float radius;
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 56fb5d441f..eb65f10ec9 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -35,32 +35,30 @@
#include <limits.h>
bool StyleBox::test_mask(const Point2 &p_point, const Rect2 &p_rect) const {
-
return true;
}
void StyleBox::set_default_margin(Margin p_margin, float p_value) {
-
ERR_FAIL_INDEX((int)p_margin, 4);
margin[p_margin] = p_value;
emit_changed();
}
-float StyleBox::get_default_margin(Margin p_margin) const {
+float StyleBox::get_default_margin(Margin p_margin) const {
ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0);
return margin[p_margin];
}
float StyleBox::get_margin(Margin p_margin) const {
-
ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0);
- if (margin[p_margin] < 0)
+ if (margin[p_margin] < 0) {
return get_style_margin(p_margin);
- else
+ } else {
return margin[p_margin];
+ }
}
CanvasItem *StyleBox::get_current_item_drawn() const {
@@ -68,17 +66,14 @@ CanvasItem *StyleBox::get_current_item_drawn() const {
}
Size2 StyleBox::get_minimum_size() const {
-
return Size2(get_margin(MARGIN_LEFT) + get_margin(MARGIN_RIGHT), get_margin(MARGIN_TOP) + get_margin(MARGIN_BOTTOM));
}
Point2 StyleBox::get_offset() const {
-
return Point2(get_margin(MARGIN_LEFT), get_margin(MARGIN_TOP));
}
Size2 StyleBox::get_center_size() const {
-
return Size2();
}
@@ -87,7 +82,6 @@ Rect2 StyleBox::get_draw_rect(const Rect2 &p_rect) const {
}
void StyleBox::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("test_mask", "point", "rect"), &StyleBox::test_mask);
ClassDB::bind_method(D_METHOD("set_default_margin", "margin", "offset"), &StyleBox::set_default_margin);
@@ -112,17 +106,15 @@ void StyleBox::_bind_methods() {
}
StyleBox::StyleBox() {
-
for (int i = 0; i < 4; i++) {
-
margin[i] = -1;
}
}
void StyleBoxTexture::set_texture(Ref<Texture2D> p_texture) {
-
- if (texture == p_texture)
+ if (texture == p_texture) {
return;
+ }
texture = p_texture;
if (p_texture.is_null()) {
region_rect = Rect2(0, 0, 0, 0);
@@ -135,25 +127,22 @@ void StyleBoxTexture::set_texture(Ref<Texture2D> p_texture) {
}
Ref<Texture2D> StyleBoxTexture::get_texture() const {
-
return texture;
}
void StyleBoxTexture::set_normal_map(Ref<Texture2D> p_normal_map) {
-
- if (normal_map == p_normal_map)
+ if (normal_map == p_normal_map) {
return;
+ }
normal_map = p_normal_map;
emit_changed();
}
Ref<Texture2D> StyleBoxTexture::get_normal_map() const {
-
return normal_map;
}
void StyleBoxTexture::set_margin_size(Margin p_margin, float p_size) {
-
ERR_FAIL_INDEX((int)p_margin, 4);
margin[p_margin] = p_size;
@@ -166,15 +155,14 @@ void StyleBoxTexture::set_margin_size(Margin p_margin, float p_size) {
};
_change_notify(margin_prop[p_margin]);
}
-float StyleBoxTexture::get_margin_size(Margin p_margin) const {
+float StyleBoxTexture::get_margin_size(Margin p_margin) const {
ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0);
return margin[p_margin];
}
float StyleBoxTexture::get_style_margin(Margin p_margin) const {
-
ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0);
return margin[p_margin];
@@ -185,8 +173,9 @@ Rect2 StyleBoxTexture::get_draw_rect(const Rect2 &p_rect) const {
}
void StyleBoxTexture::draw(RID p_canvas_item, const Rect2 &p_rect) const {
- if (texture.is_null())
+ if (texture.is_null()) {
return;
+ }
Rect2 rect = p_rect;
Rect2 src_rect = region_rect;
@@ -199,33 +188,31 @@ void StyleBoxTexture::draw(RID p_canvas_item, const Rect2 &p_rect) const {
rect.size.y += expand_margin[MARGIN_TOP] + expand_margin[MARGIN_BOTTOM];
RID normal_rid;
- if (normal_map.is_valid())
+ if (normal_map.is_valid()) {
normal_rid = normal_map->get_rid();
+ }
RenderingServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), RS::NinePatchAxisMode(axis_h), RS::NinePatchAxisMode(axis_v), draw_center, modulate, normal_rid);
}
void StyleBoxTexture::set_draw_center(bool p_enabled) {
-
draw_center = p_enabled;
emit_changed();
}
bool StyleBoxTexture::is_draw_center_enabled() const {
-
return draw_center;
}
Size2 StyleBoxTexture::get_center_size() const {
-
- if (texture.is_null())
+ if (texture.is_null()) {
return Size2();
+ }
return region_rect.size - get_minimum_size();
}
void StyleBoxTexture::set_expand_margin_size(Margin p_expand_margin, float p_size) {
-
ERR_FAIL_INDEX((int)p_expand_margin, 4);
expand_margin[p_expand_margin] = p_size;
emit_changed();
@@ -241,70 +228,62 @@ void StyleBoxTexture::set_expand_margin_size_individual(float p_left, float p_to
void StyleBoxTexture::set_expand_margin_size_all(float p_expand_margin_size) {
for (int i = 0; i < 4; i++) {
-
expand_margin[i] = p_expand_margin_size;
}
emit_changed();
}
float StyleBoxTexture::get_expand_margin_size(Margin p_expand_margin) const {
-
ERR_FAIL_INDEX_V((int)p_expand_margin, 4, 0);
return expand_margin[p_expand_margin];
}
void StyleBoxTexture::set_region_rect(const Rect2 &p_region_rect) {
-
- if (region_rect == p_region_rect)
+ if (region_rect == p_region_rect) {
return;
+ }
region_rect = p_region_rect;
emit_changed();
}
Rect2 StyleBoxTexture::get_region_rect() const {
-
return region_rect;
}
void StyleBoxTexture::set_h_axis_stretch_mode(AxisStretchMode p_mode) {
-
ERR_FAIL_INDEX((int)p_mode, 3);
axis_h = p_mode;
emit_changed();
}
StyleBoxTexture::AxisStretchMode StyleBoxTexture::get_h_axis_stretch_mode() const {
-
return axis_h;
}
void StyleBoxTexture::set_v_axis_stretch_mode(AxisStretchMode p_mode) {
-
ERR_FAIL_INDEX((int)p_mode, 3);
axis_v = p_mode;
emit_changed();
}
StyleBoxTexture::AxisStretchMode StyleBoxTexture::get_v_axis_stretch_mode() const {
-
return axis_v;
}
void StyleBoxTexture::set_modulate(const Color &p_modulate) {
- if (modulate == p_modulate)
+ if (modulate == p_modulate) {
return;
+ }
modulate = p_modulate;
emit_changed();
}
Color StyleBoxTexture::get_modulate() const {
-
return modulate;
}
void StyleBoxTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_texture", "texture"), &StyleBoxTexture::set_texture);
ClassDB::bind_method(D_METHOD("get_texture"), &StyleBoxTexture::get_texture);
@@ -362,7 +341,6 @@ void StyleBoxTexture::_bind_methods() {
}
StyleBoxTexture::StyleBoxTexture() {
-
for (int i = 0; i < 4; i++) {
margin[i] = 0;
expand_margin[i] = 0;
@@ -373,29 +351,27 @@ StyleBoxTexture::StyleBoxTexture() {
axis_h = AXIS_STRETCH_MODE_STRETCH;
axis_v = AXIS_STRETCH_MODE_STRETCH;
}
+
StyleBoxTexture::~StyleBoxTexture() {
}
////////////////
void StyleBoxFlat::set_bg_color(const Color &p_color) {
-
bg_color = p_color;
emit_changed();
}
Color StyleBoxFlat::get_bg_color() const {
-
return bg_color;
}
void StyleBoxFlat::set_border_color(const Color &p_color) {
-
border_color = p_color;
emit_changed();
}
-Color StyleBoxFlat::get_border_color() const {
+Color StyleBoxFlat::get_border_color() const {
return border_color;
}
@@ -406,8 +382,8 @@ void StyleBoxFlat::set_border_width_all(int p_size) {
border_width[3] = p_size;
emit_changed();
}
-int StyleBoxFlat::get_border_width_min() const {
+int StyleBoxFlat::get_border_width_min() const {
return MIN(MIN(border_width[0], border_width[1]), MIN(border_width[2], border_width[3]));
}
@@ -423,23 +399,22 @@ int StyleBoxFlat::get_border_width(Margin p_margin) const {
}
void StyleBoxFlat::set_border_blend(bool p_blend) {
-
blend_border = p_blend;
emit_changed();
}
-bool StyleBoxFlat::get_border_blend() const {
+bool StyleBoxFlat::get_border_blend() const {
return blend_border;
}
void StyleBoxFlat::set_corner_radius_all(int radius) {
-
for (int i = 0; i < 4; i++) {
corner_radius[i] = radius;
}
emit_changed();
}
+
void StyleBoxFlat::set_corner_radius_individual(const int radius_top_left, const int radius_top_right, const int radius_botton_right, const int radius_bottom_left) {
corner_radius[0] = radius_top_left;
corner_radius[1] = radius_top_right;
@@ -448,6 +423,7 @@ void StyleBoxFlat::set_corner_radius_individual(const int radius_top_left, const
emit_changed();
}
+
int StyleBoxFlat::get_corner_radius_min() const {
int smallest = corner_radius[0];
for (int i = 1; i < 4; i++) {
@@ -459,19 +435,17 @@ int StyleBoxFlat::get_corner_radius_min() const {
}
void StyleBoxFlat::set_corner_radius(const Corner p_corner, const int radius) {
-
ERR_FAIL_INDEX((int)p_corner, 4);
corner_radius[p_corner] = radius;
emit_changed();
}
-int StyleBoxFlat::get_corner_radius(const Corner p_corner) const {
+int StyleBoxFlat::get_corner_radius(const Corner p_corner) const {
ERR_FAIL_INDEX_V((int)p_corner, 4, 0);
return corner_radius[p_corner];
}
void StyleBoxFlat::set_expand_margin_size(Margin p_expand_margin, float p_size) {
-
ERR_FAIL_INDEX((int)p_expand_margin, 4);
expand_margin[p_expand_margin] = p_size;
emit_changed();
@@ -487,54 +461,49 @@ void StyleBoxFlat::set_expand_margin_size_individual(float p_left, float p_top,
void StyleBoxFlat::set_expand_margin_size_all(float p_expand_margin_size) {
for (int i = 0; i < 4; i++) {
-
expand_margin[i] = p_expand_margin_size;
}
emit_changed();
}
float StyleBoxFlat::get_expand_margin_size(Margin p_expand_margin) const {
-
ERR_FAIL_INDEX_V((int)p_expand_margin, 4, 0.0);
return expand_margin[p_expand_margin];
}
-void StyleBoxFlat::set_draw_center(bool p_enabled) {
+void StyleBoxFlat::set_draw_center(bool p_enabled) {
draw_center = p_enabled;
emit_changed();
}
-bool StyleBoxFlat::is_draw_center_enabled() const {
+bool StyleBoxFlat::is_draw_center_enabled() const {
return draw_center;
}
void StyleBoxFlat::set_shadow_color(const Color &p_color) {
-
shadow_color = p_color;
emit_changed();
}
-Color StyleBoxFlat::get_shadow_color() const {
+Color StyleBoxFlat::get_shadow_color() const {
return shadow_color;
}
void StyleBoxFlat::set_shadow_size(const int &p_size) {
-
shadow_size = p_size;
emit_changed();
}
-int StyleBoxFlat::get_shadow_size() const {
+int StyleBoxFlat::get_shadow_size() const {
return shadow_size;
}
void StyleBoxFlat::set_shadow_offset(const Point2 &p_offset) {
-
shadow_offset = p_offset;
emit_changed();
}
-Point2 StyleBoxFlat::get_shadow_offset() const {
+Point2 StyleBoxFlat::get_shadow_offset() const {
return shadow_offset;
}
@@ -542,6 +511,7 @@ void StyleBoxFlat::set_anti_aliased(const bool &p_anti_aliased) {
anti_aliased = p_anti_aliased;
emit_changed();
}
+
bool StyleBoxFlat::is_anti_aliased() const {
return anti_aliased;
}
@@ -550,6 +520,7 @@ void StyleBoxFlat::set_aa_size(const int &p_aa_size) {
aa_size = CLAMP(p_aa_size, 1, 5);
emit_changed();
}
+
int StyleBoxFlat::get_aa_size() const {
return aa_size;
}
@@ -558,12 +529,12 @@ void StyleBoxFlat::set_corner_detail(const int &p_corner_detail) {
corner_detail = CLAMP(p_corner_detail, 1, 20);
emit_changed();
}
+
int StyleBoxFlat::get_corner_detail() const {
return corner_detail;
}
Size2 StyleBoxFlat::get_center_size() const {
-
return Size2();
}
@@ -593,7 +564,6 @@ inline void set_inner_corner_radius(const Rect2 style_rect, const Rect2 inner_re
inline void draw_ring(Vector<Vector2> &verts, Vector<int> &indices, Vector<Color> &colors, const Rect2 &style_rect, const int corner_radius[4],
const Rect2 &ring_rect, const Rect2 &inner_rect, const Color &inner_color, const Color &outer_color, const int corner_detail, const bool fill_center = false) {
-
int vert_offset = verts.size();
if (!vert_offset) {
vert_offset = 0;
@@ -705,7 +675,6 @@ Rect2 StyleBoxFlat::get_draw_rect(const Rect2 &p_rect) const {
}
void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
-
//PREPARATIONS
bool draw_border = (border_width[0] > 0) || (border_width[1] > 0) || (border_width[2] > 0) || (border_width[3] > 0);
bool draw_shadow = (shadow_size > 0);
@@ -861,8 +830,8 @@ float StyleBoxFlat::get_style_margin(Margin p_margin) const {
ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0);
return border_width[p_margin];
}
-void StyleBoxFlat::_bind_methods() {
+void StyleBoxFlat::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &StyleBoxFlat::set_bg_color);
ClassDB::bind_method(D_METHOD("get_bg_color"), &StyleBoxFlat::get_bg_color);
@@ -950,7 +919,6 @@ void StyleBoxFlat::_bind_methods() {
}
StyleBoxFlat::StyleBoxFlat() {
-
bg_color = Color(0.6, 0.6, 0.6);
shadow_color = Color(0, 0, 0, 0.6);
border_color = Color(0.8, 0.8, 0.8);
@@ -979,6 +947,7 @@ StyleBoxFlat::StyleBoxFlat() {
corner_radius[2] = 0;
corner_radius[3] = 0;
}
+
StyleBoxFlat::~StyleBoxFlat() {
}
@@ -986,6 +955,7 @@ void StyleBoxLine::set_color(const Color &p_color) {
color = p_color;
emit_changed();
}
+
Color StyleBoxLine::get_color() const {
return color;
}
@@ -994,6 +964,7 @@ void StyleBoxLine::set_thickness(int p_thickness) {
thickness = p_thickness;
emit_changed();
}
+
int StyleBoxLine::get_thickness() const {
return thickness;
}
@@ -1002,6 +973,7 @@ void StyleBoxLine::set_vertical(bool p_vertical) {
vertical = p_vertical;
emit_changed();
}
+
bool StyleBoxLine::is_vertical() const {
return vertical;
}
@@ -1010,6 +982,7 @@ void StyleBoxLine::set_grow_end(float p_grow_end) {
grow_end = p_grow_end;
emit_changed();
}
+
float StyleBoxLine::get_grow_end() const {
return grow_end;
}
@@ -1018,12 +991,12 @@ void StyleBoxLine::set_grow_begin(float p_grow_begin) {
grow_begin = p_grow_begin;
emit_changed();
}
+
float StyleBoxLine::get_grow_begin() const {
return grow_begin;
}
void StyleBoxLine::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_color", "color"), &StyleBoxLine::set_color);
ClassDB::bind_method(D_METHOD("get_color"), &StyleBoxLine::get_color);
ClassDB::bind_method(D_METHOD("set_thickness", "thickness"), &StyleBoxLine::set_thickness);
@@ -1041,10 +1014,12 @@ void StyleBoxLine::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "thickness", PROPERTY_HINT_RANGE, "0,10"), "set_thickness", "get_thickness");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical");
}
+
float StyleBoxLine::get_style_margin(Margin p_margin) const {
ERR_FAIL_INDEX_V((int)p_margin, 4, thickness);
return thickness;
}
+
Size2 StyleBoxLine::get_center_size() const {
return Size2();
}
@@ -1073,4 +1048,5 @@ StyleBoxLine::StyleBoxLine() {
color = Color(0.0, 0.0, 0.0);
vertical = false;
}
+
StyleBoxLine::~StyleBoxLine() {}
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index f19b93d00d..99adbe589a 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -38,7 +38,6 @@
class CanvasItem;
class StyleBox : public Resource {
-
GDCLASS(StyleBox, Resource);
RES_BASE_EXTENSION("stylebox");
OBJ_SAVE_TYPE(StyleBox);
@@ -68,7 +67,6 @@ public:
};
class StyleBoxEmpty : public StyleBox {
-
GDCLASS(StyleBoxEmpty, StyleBox);
virtual float get_style_margin(Margin p_margin) const { return 0; }
@@ -78,7 +76,6 @@ public:
};
class StyleBoxTexture : public StyleBox {
-
GDCLASS(StyleBoxTexture, StyleBox);
public:
@@ -144,7 +141,6 @@ public:
VARIANT_ENUM_CAST(StyleBoxTexture::AxisStretchMode)
class StyleBoxFlat : public StyleBox {
-
GDCLASS(StyleBoxFlat, StyleBox);
Color bg_color;
@@ -238,7 +234,6 @@ public:
// just used to draw lines.
class StyleBoxLine : public StyleBox {
-
GDCLASS(StyleBoxLine, StyleBox);
Color color;
int thickness;
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 4b392e23b7..1a2dcc84bb 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -36,43 +36,50 @@
#define EQ_VERTEX_DIST 0.00001
bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const {
-
- if (vertex != p_vertex.vertex)
+ if (vertex != p_vertex.vertex) {
return false;
+ }
- if (uv != p_vertex.uv)
+ if (uv != p_vertex.uv) {
return false;
+ }
- if (uv2 != p_vertex.uv2)
+ if (uv2 != p_vertex.uv2) {
return false;
+ }
- if (normal != p_vertex.normal)
+ if (normal != p_vertex.normal) {
return false;
+ }
- if (binormal != p_vertex.binormal)
+ if (binormal != p_vertex.binormal) {
return false;
+ }
- if (color != p_vertex.color)
+ if (color != p_vertex.color) {
return false;
+ }
- if (bones.size() != p_vertex.bones.size())
+ if (bones.size() != p_vertex.bones.size()) {
return false;
+ }
for (int i = 0; i < bones.size(); i++) {
- if (bones[i] != p_vertex.bones[i])
+ if (bones[i] != p_vertex.bones[i]) {
return false;
+ }
}
for (int i = 0; i < weights.size(); i++) {
- if (weights[i] != p_vertex.weights[i])
+ if (weights[i] != p_vertex.weights[i]) {
return false;
+ }
}
return true;
}
uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) {
-
uint32_t h = hash_djb2_buffer((const uint8_t *)&p_vtx.vertex, sizeof(real_t) * 3);
h = hash_djb2_buffer((const uint8_t *)&p_vtx.normal, sizeof(real_t) * 3, h);
h = hash_djb2_buffer((const uint8_t *)&p_vtx.binormal, sizeof(real_t) * 3, h);
@@ -86,7 +93,6 @@ uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) {
}
void SurfaceTool::begin(Mesh::PrimitiveType p_primitive) {
-
clear();
primitive = p_primitive;
@@ -95,7 +101,6 @@ void SurfaceTool::begin(Mesh::PrimitiveType p_primitive) {
}
void SurfaceTool::add_vertex(const Vector3 &p_vertex) {
-
ERR_FAIL_COND(!begun);
Vertex vtx;
@@ -159,8 +164,8 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) {
format |= Mesh::ARRAY_FORMAT_VERTEX;
}
-void SurfaceTool::add_color(Color p_color) {
+void SurfaceTool::add_color(Color p_color) {
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_COLOR));
@@ -168,8 +173,8 @@ void SurfaceTool::add_color(Color p_color) {
format |= Mesh::ARRAY_FORMAT_COLOR;
last_color = p_color;
}
-void SurfaceTool::add_normal(const Vector3 &p_normal) {
+void SurfaceTool::add_normal(const Vector3 &p_normal) {
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_NORMAL));
@@ -179,7 +184,6 @@ void SurfaceTool::add_normal(const Vector3 &p_normal) {
}
void SurfaceTool::add_tangent(const Plane &p_tangent) {
-
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TANGENT));
@@ -188,7 +192,6 @@ void SurfaceTool::add_tangent(const Plane &p_tangent) {
}
void SurfaceTool::add_uv(const Vector2 &p_uv) {
-
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV));
@@ -197,7 +200,6 @@ void SurfaceTool::add_uv(const Vector2 &p_uv) {
}
void SurfaceTool::add_uv2(const Vector2 &p_uv2) {
-
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV2));
@@ -206,7 +208,6 @@ void SurfaceTool::add_uv2(const Vector2 &p_uv2) {
}
void SurfaceTool::add_bones(const Vector<int> &p_bones) {
-
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_BONES));
@@ -215,7 +216,6 @@ void SurfaceTool::add_bones(const Vector<int> &p_bones) {
}
void SurfaceTool::add_weights(const Vector<float> &p_weights) {
-
ERR_FAIL_COND(!begun);
ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_WEIGHTS));
@@ -224,12 +224,10 @@ void SurfaceTool::add_weights(const Vector<float> &p_weights) {
}
void SurfaceTool::add_smooth_group(bool p_smooth) {
-
ERR_FAIL_COND(!begun);
if (index_array.size()) {
smooth_groups[index_array.size()] = p_smooth;
} else {
-
smooth_groups[vertex_array.size()] = p_smooth;
}
}
@@ -264,7 +262,6 @@ void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertices, const Vect
}
void SurfaceTool::add_index(int p_index) {
-
ERR_FAIL_COND(!begun);
format |= Mesh::ARRAY_FORMAT_INDEX;
@@ -272,29 +269,25 @@ void SurfaceTool::add_index(int p_index) {
}
Array SurfaceTool::commit_to_arrays() {
-
int varr_len = vertex_array.size();
Array a;
a.resize(Mesh::ARRAY_MAX);
for (int i = 0; i < Mesh::ARRAY_MAX; i++) {
-
- if (!(format & (1 << i)))
+ if (!(format & (1 << i))) {
continue; //not in format
+ }
switch (i) {
-
case Mesh::ARRAY_VERTEX:
case Mesh::ARRAY_NORMAL: {
-
Vector<Vector3> array;
array.resize(varr_len);
Vector3 *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
-
const Vertex &v = E->get();
switch (i) {
@@ -313,18 +306,15 @@ Array SurfaceTool::commit_to_arrays() {
case Mesh::ARRAY_TEX_UV:
case Mesh::ARRAY_TEX_UV2: {
-
Vector<Vector2> array;
array.resize(varr_len);
Vector2 *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
-
const Vertex &v = E->get();
switch (i) {
-
case Mesh::ARRAY_TEX_UV: {
w[idx] = v.uv;
} break;
@@ -337,14 +327,12 @@ Array SurfaceTool::commit_to_arrays() {
a[i] = array;
} break;
case Mesh::ARRAY_TANGENT: {
-
Vector<float> array;
array.resize(varr_len * 4);
float *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) {
-
const Vertex &v = E->get();
w[idx + 0] = v.tangent.x;
@@ -360,14 +348,12 @@ Array SurfaceTool::commit_to_arrays() {
} break;
case Mesh::ARRAY_COLOR: {
-
Vector<Color> array;
array.resize(varr_len);
Color *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) {
-
const Vertex &v = E->get();
w[idx] = v.color;
}
@@ -375,14 +361,12 @@ Array SurfaceTool::commit_to_arrays() {
a[i] = array;
} break;
case Mesh::ARRAY_BONES: {
-
Vector<int> array;
array.resize(varr_len * 4);
int *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) {
-
const Vertex &v = E->get();
ERR_CONTINUE(v.bones.size() != 4);
@@ -396,19 +380,16 @@ Array SurfaceTool::commit_to_arrays() {
} break;
case Mesh::ARRAY_WEIGHTS: {
-
Vector<float> array;
array.resize(varr_len * 4);
float *w = array.ptrw();
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) {
-
const Vertex &v = E->get();
ERR_CONTINUE(v.weights.size() != 4);
for (int j = 0; j < 4; j++) {
-
w[idx + j] = v.weights[j];
}
}
@@ -417,7 +398,6 @@ Array SurfaceTool::commit_to_arrays() {
} break;
case Mesh::ARRAY_INDEX: {
-
ERR_CONTINUE(index_array.size() == 0);
Vector<int> array;
@@ -426,7 +406,6 @@ Array SurfaceTool::commit_to_arrays() {
int idx = 0;
for (List<int>::Element *E = index_array.front(); E; E = E->next(), idx++) {
-
w[idx] = E->get();
}
@@ -442,17 +421,18 @@ Array SurfaceTool::commit_to_arrays() {
}
Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing, uint32_t p_flags) {
-
Ref<ArrayMesh> mesh;
- if (p_existing.is_valid())
+ if (p_existing.is_valid()) {
mesh = p_existing;
- else
+ } else {
mesh.instance();
+ }
int varr_len = vertex_array.size();
- if (varr_len == 0)
+ if (varr_len == 0) {
return mesh;
+ }
int surface = mesh->get_surface_count();
@@ -460,22 +440,22 @@ Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing, uint32_t p_
mesh->add_surface_from_arrays(primitive, a, Array(), Dictionary(), p_flags);
- if (material.is_valid())
+ if (material.is_valid()) {
mesh->surface_set_material(surface, material);
+ }
return mesh;
}
void SurfaceTool::index() {
-
- if (index_array.size())
+ if (index_array.size()) {
return; //already indexed
+ }
HashMap<Vertex, int, VertexHasher> indices;
List<Vertex> new_vertices;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) {
-
int *idxptr = indices.getptr(E->get());
int idx;
if (!idxptr) {
@@ -496,19 +476,17 @@ void SurfaceTool::index() {
}
void SurfaceTool::deindex() {
-
- if (index_array.size() == 0)
+ if (index_array.size() == 0) {
return; //nothing to deindex
+ }
Vector<Vertex> varr;
varr.resize(vertex_array.size());
int idx = 0;
for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) {
-
varr.write[idx++] = E->get();
}
vertex_array.clear();
for (List<int>::Element *E = index_array.front(); E; E = E->next()) {
-
ERR_FAIL_INDEX(E->get(), varr.size());
vertex_array.push_back(varr[E->get()]);
}
@@ -517,14 +495,12 @@ void SurfaceTool::deindex() {
}
void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) {
-
Array arr = p_existing->surface_get_arrays(p_surface);
ERR_FAIL_COND(arr.size() != RS::ARRAY_MAX);
_create_list_from_arrays(arr, r_vertex, r_index, lformat);
}
Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays) {
-
Vector<SurfaceTool::Vertex> ret;
Vector<Vector3> varr = p_arrays[RS::ARRAY_VERTEX];
@@ -537,8 +513,9 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array
Vector<float> warr = p_arrays[RS::ARRAY_WEIGHTS];
int vc = varr.size();
- if (vc == 0)
+ if (vc == 0) {
return ret;
+ }
int lformat = 0;
if (varr.size()) {
@@ -568,21 +545,26 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array
for (int i = 0; i < vc; i++) {
Vertex v;
- if (lformat & RS::ARRAY_FORMAT_VERTEX)
+ if (lformat & RS::ARRAY_FORMAT_VERTEX) {
v.vertex = varr[i];
- if (lformat & RS::ARRAY_FORMAT_NORMAL)
+ }
+ if (lformat & RS::ARRAY_FORMAT_NORMAL) {
v.normal = narr[i];
+ }
if (lformat & RS::ARRAY_FORMAT_TANGENT) {
Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]);
v.tangent = p.normal;
v.binormal = p.normal.cross(v.tangent).normalized() * p.d;
}
- if (lformat & RS::ARRAY_FORMAT_COLOR)
+ if (lformat & RS::ARRAY_FORMAT_COLOR) {
v.color = carr[i];
- if (lformat & RS::ARRAY_FORMAT_TEX_UV)
+ }
+ if (lformat & RS::ARRAY_FORMAT_TEX_UV) {
v.uv = uvarr[i];
- if (lformat & RS::ARRAY_FORMAT_TEX_UV2)
+ }
+ if (lformat & RS::ARRAY_FORMAT_TEX_UV2) {
v.uv2 = uv2arr[i];
+ }
if (lformat & RS::ARRAY_FORMAT_BONES) {
Vector<int> b;
b.resize(4);
@@ -609,7 +591,6 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array
}
void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) {
-
Vector<Vector3> varr = arr[RS::ARRAY_VERTEX];
Vector<Vector3> narr = arr[RS::ARRAY_NORMAL];
Vector<float> tarr = arr[RS::ARRAY_TANGENT];
@@ -620,8 +601,9 @@ void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, Li
Vector<float> warr = arr[RS::ARRAY_WEIGHTS];
int vc = varr.size();
- if (vc == 0)
+ if (vc == 0) {
return;
+ }
lformat = 0;
if (varr.size()) {
@@ -651,21 +633,26 @@ void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, Li
for (int i = 0; i < vc; i++) {
Vertex v;
- if (lformat & RS::ARRAY_FORMAT_VERTEX)
+ if (lformat & RS::ARRAY_FORMAT_VERTEX) {
v.vertex = varr[i];
- if (lformat & RS::ARRAY_FORMAT_NORMAL)
+ }
+ if (lformat & RS::ARRAY_FORMAT_NORMAL) {
v.normal = narr[i];
+ }
if (lformat & RS::ARRAY_FORMAT_TANGENT) {
Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]);
v.tangent = p.normal;
v.binormal = p.normal.cross(v.tangent).normalized() * p.d;
}
- if (lformat & RS::ARRAY_FORMAT_COLOR)
+ if (lformat & RS::ARRAY_FORMAT_COLOR) {
v.color = carr[i];
- if (lformat & RS::ARRAY_FORMAT_TEX_UV)
+ }
+ if (lformat & RS::ARRAY_FORMAT_TEX_UV) {
v.uv = uvarr[i];
- if (lformat & RS::ARRAY_FORMAT_TEX_UV2)
+ }
+ if (lformat & RS::ARRAY_FORMAT_TEX_UV2) {
v.uv2 = uv2arr[i];
+ }
if (lformat & RS::ARRAY_FORMAT_BONES) {
Vector<int> b;
b.resize(4);
@@ -693,7 +680,6 @@ void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, Li
Vector<int> idx = arr[RS::ARRAY_INDEX];
int is = idx.size();
if (is) {
-
lformat |= RS::ARRAY_FORMAT_INDEX;
const int *iarr = idx.ptr();
for (int i = 0; i < is; i++) {
@@ -703,14 +689,12 @@ void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, Li
}
void SurfaceTool::create_from_triangle_arrays(const Array &p_arrays) {
-
clear();
primitive = Mesh::PRIMITIVE_TRIANGLES;
_create_list_from_arrays(p_arrays, &vertex_array, &index_array, format);
}
void SurfaceTool::create_from(const Ref<Mesh> &p_existing, int p_surface) {
-
clear();
primitive = p_existing->surface_get_primitive_type(p_surface);
_create_list(p_existing, p_surface, &vertex_array, &index_array, format);
@@ -738,7 +722,6 @@ void SurfaceTool::create_from_blend_shape(const Ref<Mesh> &p_existing, int p_sur
}
void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform) {
-
if (vertex_array.size() == 0) {
primitive = p_existing->surface_get_primitive_type(p_surface);
format = 0;
@@ -752,7 +735,6 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
int vfrom = vertex_array.size();
for (List<Vertex>::Element *E = nvertices.front(); E; E = E->next()) {
-
Vertex v = E->get();
v.vertex = p_xform.xform(v.vertex);
if (nformat & RS::ARRAY_FORMAT_NORMAL) {
@@ -767,7 +749,6 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const
}
for (List<int>::Element *E = nindices.front(); E; E = E->next()) {
-
int dst_index = E->get() + vfrom;
index_array.push_back(dst_index);
}
@@ -785,7 +766,6 @@ struct TangentGenerationContextUserData {
} // namespace
int SurfaceTool::mikktGetNumFaces(const SMikkTSpaceContext *pContext) {
-
TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
if (triangle_data.indices.size() > 0) {
@@ -794,12 +774,12 @@ int SurfaceTool::mikktGetNumFaces(const SMikkTSpaceContext *pContext) {
return triangle_data.vertices.size() / 3;
}
}
-int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, const int iFace) {
+int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, const int iFace) {
return 3; //always 3
}
-void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) {
+void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) {
TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
Vector3 v;
if (triangle_data.indices.size() > 0) {
@@ -817,7 +797,6 @@ void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvP
}
void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) {
-
TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
Vector3 v;
if (triangle_data.indices.size() > 0) {
@@ -833,8 +812,8 @@ void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNor
fvNormOut[1] = v.y;
fvNormOut[2] = v.z;
}
-void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) {
+void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) {
TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
Vector2 v;
if (triangle_data.indices.size() > 0) {
@@ -852,7 +831,6 @@ void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvT
void SurfaceTool::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, const float fvTangent[], const float fvBiTangent[], const float fMagS, const float fMagT,
const tbool bIsOrientationPreserving, const int iFace, const int iVert) {
-
TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData);
Vertex *vtx = nullptr;
if (triangle_data.indices.size() > 0) {
@@ -871,7 +849,6 @@ void SurfaceTool::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, cons
}
void SurfaceTool::generate_tangents() {
-
ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_TEX_UV));
ERR_FAIL_COND(!(format & Mesh::ARRAY_FORMAT_NORMAL));
@@ -909,7 +886,6 @@ void SurfaceTool::generate_tangents() {
}
void SurfaceTool::generate_normals(bool p_flip) {
-
ERR_FAIL_COND(primitive != Mesh::PRIMITIVE_TRIANGLES);
bool was_indexed = index_array.size();
@@ -920,12 +896,12 @@ void SurfaceTool::generate_normals(bool p_flip) {
int count = 0;
bool smooth = false;
- if (smooth_groups.has(0))
+ if (smooth_groups.has(0)) {
smooth = smooth_groups[0];
+ }
List<Vertex>::Element *B = vertex_array.front();
for (List<Vertex>::Element *E = B; E;) {
-
List<Vertex>::Element *v[3];
v[0] = E;
v[1] = v[0]->next();
@@ -935,15 +911,14 @@ void SurfaceTool::generate_normals(bool p_flip) {
E = v[2]->next();
Vector3 normal;
- if (!p_flip)
+ if (!p_flip) {
normal = Plane(v[0]->get().vertex, v[1]->get().vertex, v[2]->get().vertex).normal;
- else
+ } else {
normal = Plane(v[2]->get().vertex, v[1]->get().vertex, v[0]->get().vertex).normal;
+ }
if (smooth) {
-
for (int i = 0; i < 3; i++) {
-
Vector3 *lv = vertex_hash.getptr(v[i]->get());
if (!lv) {
vertex_hash.set(v[i]->get(), normal);
@@ -952,20 +927,15 @@ void SurfaceTool::generate_normals(bool p_flip) {
}
}
} else {
-
for (int i = 0; i < 3; i++) {
-
v[i]->get().normal = normal;
}
}
count += 3;
if (smooth_groups.has(count) || !E) {
-
if (vertex_hash.size()) {
-
while (B != E) {
-
Vector3 *lv = vertex_hash.getptr(B->get());
if (lv) {
B->get().normal = lv->normalized();
@@ -994,12 +964,10 @@ void SurfaceTool::generate_normals(bool p_flip) {
}
void SurfaceTool::set_material(const Ref<Material> &p_material) {
-
material = p_material;
}
void SurfaceTool::clear() {
-
begun = false;
primitive = Mesh::PRIMITIVE_LINES;
format = 0;
@@ -1012,7 +980,6 @@ void SurfaceTool::clear() {
}
void SurfaceTool::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("begin", "primitive"), &SurfaceTool::begin);
ClassDB::bind_method(D_METHOD("add_vertex", "vertex"), &SurfaceTool::add_vertex);
@@ -1046,7 +1013,6 @@ void SurfaceTool::_bind_methods() {
}
SurfaceTool::SurfaceTool() {
-
first = false;
begun = false;
primitive = Mesh::PRIMITIVE_LINES;
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index 89034f656d..d7b255e695 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -36,12 +36,10 @@
#include "thirdparty/misc/mikktspace.h"
class SurfaceTool : public Reference {
-
GDCLASS(SurfaceTool, Reference);
public:
struct Vertex {
-
Vector3 vertex;
Color color;
Vector3 normal; // normal, binormal, tangent
diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp
index e291dcb67e..e3bd5ce0ae 100644
--- a/scene/resources/text_file.cpp
+++ b/scene/resources/text_file.cpp
@@ -49,7 +49,6 @@ void TextFile::reload_from_file() {
}
Error TextFile::load_text(const String &p_path) {
-
Vector<uint8_t> sourcef;
Error err;
FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
diff --git a/scene/resources/text_file.h b/scene/resources/text_file.h
index 666c088d04..356b070ea0 100644
--- a/scene/resources/text_file.h
+++ b/scene/resources/text_file.h
@@ -35,7 +35,6 @@
#include "core/io/resource_saver.h"
class TextFile : public Resource {
-
GDCLASS(TextFile, Resource);
private:
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 749dff24f2..331cffed5d 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -39,7 +39,6 @@
#include "servers/camera/camera_feed.h"
Size2 Texture2D::get_size() const {
-
return Size2(get_width(), get_height());
}
@@ -48,28 +47,24 @@ bool Texture2D::is_pixel_opaque(int p_x, int p_y) const {
}
void Texture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
-
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
void Texture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
-
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
void Texture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
-
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
}
bool Texture2D::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
-
r_rect = p_rect;
r_src_rect = p_src_rect;
@@ -77,7 +72,6 @@ bool Texture2D::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Re
}
void Texture2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_width"), &Texture2D::get_width);
ClassDB::bind_method(D_METHOD("get_height"), &Texture2D::get_height);
ClassDB::bind_method(D_METHOD("get_size"), &Texture2D::get_size);
@@ -96,10 +90,10 @@ Texture2D::Texture2D() {
/////////////////////
void ImageTexture::reload_from_file() {
-
String path = ResourceLoader::path_remap(get_path());
- if (!path.is_resource_file())
+ if (!path.is_resource_file()) {
return;
+ }
Ref<Image> img;
img.instance();
@@ -114,43 +108,42 @@ void ImageTexture::reload_from_file() {
}
bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
-
- if (p_name == "image")
+ if (p_name == "image") {
create_from_image(p_value);
- else if (p_name == "size") {
+ } else if (p_name == "size") {
Size2 s = p_value;
w = s.width;
h = s.height;
RenderingServer::get_singleton()->texture_set_size_override(texture, w, h);
- } else
+ } else {
return false;
+ }
return true;
}
bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const {
-
- if (p_name == "image")
+ if (p_name == "image") {
r_ret = get_data();
- else if (p_name == "size")
+ } else if (p_name == "size") {
r_ret = Size2(w, h);
- else
+ } else {
return false;
+ }
return true;
}
void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
-
p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, ""));
}
void ImageTexture::_reload_hook(const RID &p_hook) {
-
String path = get_path();
- if (!path.is_resource_file())
+ if (!path.is_resource_file()) {
return;
+ }
Ref<Image> img;
img.instance();
@@ -166,7 +159,6 @@ void ImageTexture::_reload_hook(const RID &p_hook) {
}
void ImageTexture::create_from_image(const Ref<Image> &p_image) {
-
ERR_FAIL_COND(p_image.is_null());
w = p_image->get_width();
h = p_image->get_height();
@@ -186,12 +178,10 @@ void ImageTexture::create_from_image(const Ref<Image> &p_image) {
}
Image::Format ImageTexture::get_format() const {
-
return format;
}
void ImageTexture::update(const Ref<Image> &p_image, bool p_immediate) {
-
ERR_FAIL_COND(p_image.is_null());
ERR_FAIL_COND(texture.is_null());
ERR_FAIL_COND(p_image->get_width() != w || p_image->get_height() != h);
@@ -212,12 +202,10 @@ void ImageTexture::update(const Ref<Image> &p_image, bool p_immediate) {
}
void ImageTexture::_resource_path_changed() {
-
String path = get_path();
}
Ref<Image> ImageTexture::get_data() const {
-
if (image_stored) {
return RenderingServer::get_singleton()->texture_2d_get(texture);
} else {
@@ -226,17 +214,14 @@ Ref<Image> ImageTexture::get_data() const {
}
int ImageTexture::get_width() const {
-
return w;
}
int ImageTexture::get_height() const {
-
return h;
}
RID ImageTexture::get_rid() const {
-
if (texture.is_null()) {
//we are in trouble, create something temporary
texture = RenderingServer::get_singleton()->texture_2d_placeholder_create();
@@ -245,37 +230,37 @@ RID ImageTexture::get_rid() const {
}
bool ImageTexture::has_alpha() const {
-
return (format == Image::FORMAT_LA8 || format == Image::FORMAT_RGBA8);
}
void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
-
- if ((w | h) == 0)
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
- if ((w | h) == 0)
+void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
- if ((w | h) == 0)
+void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
}
bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
-
if (!alpha_cache.is_valid()) {
Ref<Image> img = get_data();
if (img.is_valid()) {
@@ -290,7 +275,6 @@ bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
}
if (alpha_cache.is_valid()) {
-
int aw = int(alpha_cache->get_size().width);
int ah = int(alpha_cache->get_size().height);
if (aw == 0 || ah == 0) {
@@ -310,17 +294,17 @@ bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
}
void ImageTexture::set_size_override(const Size2 &p_size) {
-
Size2 s = p_size;
- if (s.x != 0)
+ if (s.x != 0) {
w = s.x;
- if (s.y != 0)
+ }
+ if (s.y != 0) {
h = s.y;
+ }
RenderingServer::get_singleton()->texture_set_size_override(texture, w, h);
}
void ImageTexture::set_path(const String &p_path, bool p_take_over) {
-
if (texture.is_valid()) {
RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
@@ -329,7 +313,6 @@ void ImageTexture::set_path(const String &p_path, bool p_take_over) {
}
void ImageTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("create_from_image", "image"), &ImageTexture::create_from_image);
ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format);
@@ -339,7 +322,6 @@ void ImageTexture::_bind_methods() {
}
ImageTexture::ImageTexture() {
-
w = h = 0;
image_stored = false;
mipmaps = false;
@@ -347,7 +329,6 @@ ImageTexture::ImageTexture() {
}
ImageTexture::~ImageTexture() {
-
if (texture.is_valid()) {
RenderingServer::get_singleton()->free(texture);
}
@@ -355,8 +336,7 @@ ImageTexture::~ImageTexture() {
//////////////////////////////////////////
-Ref<Image> StreamTexture::load_image_from_file(FileAccess *f, int p_size_limit) {
-
+Ref<Image> StreamTexture2D::load_image_from_file(FileAccess *f, int p_size_limit) {
uint32_t data_format = f->get_32();
uint32_t w = f->get_16();
uint32_t h = f->get_16();
@@ -376,7 +356,6 @@ Ref<Image> StreamTexture::load_image_from_file(FileAccess *f, int p_size_limit)
bool first = true;
for (uint32_t i = 0; i < mipmaps + 1; i++) {
-
uint32_t size = f->get_32();
if (p_size_limit > 0 && i < (mipmaps - 1) && (sw > p_size_limit || sh > p_size_limit)) {
@@ -444,7 +423,6 @@ Ref<Image> StreamTexture::load_image_from_file(FileAccess *f, int p_size_limit)
int ofs = 0;
for (int i = 0; i < mipmap_images.size(); i++) {
-
Vector<uint8_t> id = mipmap_images[i]->get_data();
int len = id.size();
const uint8_t *r = id.ptr();
@@ -458,7 +436,6 @@ Ref<Image> StreamTexture::load_image_from_file(FileAccess *f, int p_size_limit)
}
} else if (data_format == DATA_FORMAT_IMAGE) {
-
int size = Image::get_image_data_size(w, h, format, mipmaps ? true : false);
for (uint32_t i = 0; i < mipmaps + 1; i++) {
@@ -492,8 +469,7 @@ Ref<Image> StreamTexture::load_image_from_file(FileAccess *f, int p_size_limit)
return Ref<Image>();
}
-void StreamTexture::set_path(const String &p_path, bool p_take_over) {
-
+void StreamTexture2D::set_path(const String &p_path, bool p_take_over) {
if (texture.is_valid()) {
RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
@@ -501,41 +477,36 @@ void StreamTexture::set_path(const String &p_path, bool p_take_over) {
Resource::set_path(p_path, p_take_over);
}
-void StreamTexture::_requested_3d(void *p_ud) {
-
- StreamTexture *st = (StreamTexture *)p_ud;
- Ref<StreamTexture> stex(st);
+void StreamTexture2D::_requested_3d(void *p_ud) {
+ StreamTexture2D *st = (StreamTexture2D *)p_ud;
+ Ref<StreamTexture2D> stex(st);
ERR_FAIL_COND(!request_3d_callback);
request_3d_callback(stex);
}
-void StreamTexture::_requested_roughness(void *p_ud, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel) {
-
- StreamTexture *st = (StreamTexture *)p_ud;
- Ref<StreamTexture> stex(st);
+void StreamTexture2D::_requested_roughness(void *p_ud, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel) {
+ StreamTexture2D *st = (StreamTexture2D *)p_ud;
+ Ref<StreamTexture2D> stex(st);
ERR_FAIL_COND(!request_roughness_callback);
request_roughness_callback(stex, p_normal_path, p_roughness_channel);
}
-void StreamTexture::_requested_normal(void *p_ud) {
-
- StreamTexture *st = (StreamTexture *)p_ud;
- Ref<StreamTexture> stex(st);
+void StreamTexture2D::_requested_normal(void *p_ud) {
+ StreamTexture2D *st = (StreamTexture2D *)p_ud;
+ Ref<StreamTexture2D> stex(st);
ERR_FAIL_COND(!request_normal_callback);
request_normal_callback(stex);
}
-StreamTexture::TextureFormatRequestCallback StreamTexture::request_3d_callback = nullptr;
-StreamTexture::TextureFormatRoughnessRequestCallback StreamTexture::request_roughness_callback = nullptr;
-StreamTexture::TextureFormatRequestCallback StreamTexture::request_normal_callback = nullptr;
-
-Image::Format StreamTexture::get_format() const {
+StreamTexture2D::TextureFormatRequestCallback StreamTexture2D::request_3d_callback = nullptr;
+StreamTexture2D::TextureFormatRoughnessRequestCallback StreamTexture2D::request_roughness_callback = nullptr;
+StreamTexture2D::TextureFormatRequestCallback StreamTexture2D::request_normal_callback = nullptr;
+Image::Format StreamTexture2D::get_format() const {
return format;
}
-Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) {
-
+Error StreamTexture2D::_load_data(const String &p_path, int &tw, int &th, int &tw_custom, int &th_custom, Ref<Image> &image, bool &r_request_3d, bool &r_request_normal, bool &r_request_roughness, int &mipmap_limit, int p_size_limit) {
alpha_cache.unref();
ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER);
@@ -595,8 +566,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &tw_
return OK;
}
-Error StreamTexture::load(const String &p_path) {
-
+Error StreamTexture2D::load(const String &p_path) {
int lw, lh, lwc, lhc;
Ref<Image> image;
image.instance();
@@ -607,8 +577,9 @@ Error StreamTexture::load(const String &p_path) {
int mipmap_limit;
Error err = _load_data(p_path, lw, lh, lwc, lhc, image, request_3d, request_normal, request_roughness, mipmap_limit);
- if (err)
+ if (err) {
return err;
+ }
if (texture.is_valid()) {
RID new_texture = RS::get_singleton()->texture_2d_create(image);
@@ -661,59 +632,58 @@ Error StreamTexture::load(const String &p_path) {
emit_changed();
return OK;
}
-String StreamTexture::get_load_path() const {
+String StreamTexture2D::get_load_path() const {
return path_to_file;
}
-int StreamTexture::get_width() const {
-
+int StreamTexture2D::get_width() const {
return w;
}
-int StreamTexture::get_height() const {
+int StreamTexture2D::get_height() const {
return h;
}
-RID StreamTexture::get_rid() const {
+RID StreamTexture2D::get_rid() const {
if (!texture.is_valid()) {
texture = RS::get_singleton()->texture_2d_placeholder_create();
}
return texture;
}
-void StreamTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
-
- if ((w | h) == 0)
+void StreamTexture2D::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
- if ((w | h) == 0)
+void StreamTexture2D::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
- if ((w | h) == 0)
+void StreamTexture2D::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
+ if ((w | h) == 0) {
return;
+ }
RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, p_clip_uv, p_texture_filter, p_texture_repeat);
}
-bool StreamTexture::has_alpha() const {
-
+bool StreamTexture2D::has_alpha() const {
return false;
}
-Ref<Image> StreamTexture::get_data() const {
-
+Ref<Image> StreamTexture2D::get_data() const {
if (texture.is_valid()) {
return RS::get_singleton()->texture_2d_get(texture);
} else {
@@ -721,8 +691,7 @@ Ref<Image> StreamTexture::get_data() const {
}
}
-bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const {
-
+bool StreamTexture2D::is_pixel_opaque(int p_x, int p_y) const {
if (!alpha_cache.is_valid()) {
Ref<Image> img = get_data();
if (img.is_valid()) {
@@ -738,7 +707,6 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const {
}
if (alpha_cache.is_valid()) {
-
int aw = int(alpha_cache->get_size().width);
int ah = int(alpha_cache->get_size().height);
if (aw == 0 || ah == 0) {
@@ -757,166 +725,163 @@ bool StreamTexture::is_pixel_opaque(int p_x, int p_y) const {
return true;
}
-void StreamTexture::reload_from_file() {
-
+void StreamTexture2D::reload_from_file() {
String path = get_path();
- if (!path.is_resource_file())
+ if (!path.is_resource_file()) {
return;
+ }
path = ResourceLoader::path_remap(path); //remap for translation
path = ResourceLoader::import_remap(path); //remap for import
- if (!path.is_resource_file())
+ if (!path.is_resource_file()) {
return;
+ }
load(path);
}
-void StreamTexture::_validate_property(PropertyInfo &property) const {
+void StreamTexture2D::_validate_property(PropertyInfo &property) const {
}
-void StreamTexture::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture::load);
- ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture::get_load_path);
+void StreamTexture2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture2D::load);
+ ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture2D::get_load_path);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
}
-StreamTexture::StreamTexture() {
-
+StreamTexture2D::StreamTexture2D() {
format = Image::FORMAT_MAX;
w = 0;
h = 0;
}
-StreamTexture::~StreamTexture() {
-
+StreamTexture2D::~StreamTexture2D() {
if (texture.is_valid()) {
RS::get_singleton()->free(texture);
}
}
-RES ResourceFormatLoaderStreamTexture::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
-
- Ref<StreamTexture> st;
+RES ResourceFormatLoaderStreamTexture2D::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ Ref<StreamTexture2D> st;
st.instance();
Error err = st->load(p_path);
- if (r_error)
+ if (r_error) {
*r_error = err;
- if (err != OK)
+ }
+ if (err != OK) {
return RES();
+ }
return st;
}
-void ResourceFormatLoaderStreamTexture::get_recognized_extensions(List<String> *p_extensions) const {
-
+void ResourceFormatLoaderStreamTexture2D::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("stex");
}
-bool ResourceFormatLoaderStreamTexture::handles_type(const String &p_type) const {
- return p_type == "StreamTexture";
+
+bool ResourceFormatLoaderStreamTexture2D::handles_type(const String &p_type) const {
+ return p_type == "StreamTexture2D";
}
-String ResourceFormatLoaderStreamTexture::get_resource_type(const String &p_path) const {
- if (p_path.get_extension().to_lower() == "stex")
- return "StreamTexture";
+String ResourceFormatLoaderStreamTexture2D::get_resource_type(const String &p_path) const {
+ if (p_path.get_extension().to_lower() == "stex") {
+ return "StreamTexture2D";
+ }
return "";
}
//////////////////////////////////////////
int AtlasTexture::get_width() const {
-
if (region.size.width == 0) {
- if (atlas.is_valid())
+ if (atlas.is_valid()) {
return atlas->get_width();
+ }
return 1;
} else {
return region.size.width + margin.size.width;
}
}
-int AtlasTexture::get_height() const {
+int AtlasTexture::get_height() const {
if (region.size.height == 0) {
- if (atlas.is_valid())
+ if (atlas.is_valid()) {
return atlas->get_height();
+ }
return 1;
} else {
return region.size.height + margin.size.height;
}
}
-RID AtlasTexture::get_rid() const {
- if (atlas.is_valid())
+RID AtlasTexture::get_rid() const {
+ if (atlas.is_valid()) {
return atlas->get_rid();
+ }
return RID();
}
bool AtlasTexture::has_alpha() const {
-
- if (atlas.is_valid())
+ if (atlas.is_valid()) {
return atlas->has_alpha();
+ }
return false;
}
void AtlasTexture::set_atlas(const Ref<Texture2D> &p_atlas) {
-
ERR_FAIL_COND(p_atlas == this);
- if (atlas == p_atlas)
+ if (atlas == p_atlas) {
return;
+ }
atlas = p_atlas;
emit_changed();
_change_notify("atlas");
}
-Ref<Texture2D> AtlasTexture::get_atlas() const {
+Ref<Texture2D> AtlasTexture::get_atlas() const {
return atlas;
}
void AtlasTexture::set_region(const Rect2 &p_region) {
-
- if (region == p_region)
+ if (region == p_region) {
return;
+ }
region = p_region;
emit_changed();
_change_notify("region");
}
Rect2 AtlasTexture::get_region() const {
-
return region;
}
void AtlasTexture::set_margin(const Rect2 &p_margin) {
-
- if (margin == p_margin)
+ if (margin == p_margin) {
return;
+ }
margin = p_margin;
emit_changed();
_change_notify("margin");
}
Rect2 AtlasTexture::get_margin() const {
-
return margin;
}
void AtlasTexture::set_filter_clip(const bool p_enable) {
-
filter_clip = p_enable;
emit_changed();
_change_notify("filter_clip");
}
bool AtlasTexture::has_filter_clip() const {
-
return filter_clip;
}
void AtlasTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_atlas", "atlas"), &AtlasTexture::set_atlas);
ClassDB::bind_method(D_METHOD("get_atlas"), &AtlasTexture::get_atlas);
@@ -936,9 +901,9 @@ void AtlasTexture::_bind_methods() {
}
void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
-
- if (!atlas.is_valid())
+ if (!atlas.is_valid()) {
return;
+ }
Rect2 rc = region;
@@ -956,9 +921,9 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m
}
void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
-
- if (!atlas.is_valid())
+ if (!atlas.is_valid()) {
return;
+ }
Rect2 rc = region;
@@ -977,11 +942,12 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid, specular_rid, p_specular_color_shininess, filter_clip, p_texture_filter, p_texture_repeat);
}
-void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
+void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
//this might not necessarily work well if using a rect, needs to be fixed properly
- if (!atlas.is_valid())
+ if (!atlas.is_valid()) {
return;
+ }
Rect2 dr;
Rect2 src_c;
@@ -993,9 +959,9 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
}
bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
-
- if (!atlas.is_valid())
+ if (!atlas.is_valid()) {
return false;
+ }
Rect2 rc = region;
@@ -1007,8 +973,9 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect,
src.position += (rc.position - margin.position);
Rect2 src_c = rc.clip(src);
- if (src_c.size == Size2())
+ if (src_c.size == Size2()) {
return false;
+ }
Vector2 ofs = (src_c.position - src.position);
if (scale.x < 0) {
@@ -1029,16 +996,20 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect,
}
bool AtlasTexture::is_pixel_opaque(int p_x, int p_y) const {
-
- if (!atlas.is_valid())
+ if (!atlas.is_valid()) {
return true;
+ }
int x = p_x + region.position.x - margin.position.x;
int y = p_y + region.position.y - margin.position.y;
// margin edge may outside of atlas
- if (x < 0 || x >= atlas->get_width()) return false;
- if (y < 0 || y >= atlas->get_height()) return false;
+ if (x < 0 || x >= atlas->get_width()) {
+ return false;
+ }
+ if (y < 0 || y >= atlas->get_height()) {
+ return false;
+ }
return atlas->is_pixel_opaque(x, y);
}
@@ -1052,9 +1023,11 @@ AtlasTexture::AtlasTexture() {
int MeshTexture::get_width() const {
return size.width;
}
+
int MeshTexture::get_height() const {
return size.height;
}
+
RID MeshTexture::get_rid() const {
return RID();
}
@@ -1066,6 +1039,7 @@ bool MeshTexture::has_alpha() const {
void MeshTexture::set_mesh(const Ref<Mesh> &p_mesh) {
mesh = p_mesh;
}
+
Ref<Mesh> MeshTexture::get_mesh() const {
return mesh;
}
@@ -1075,7 +1049,6 @@ void MeshTexture::set_image_size(const Size2 &p_size) {
}
Size2 MeshTexture::get_image_size() const {
-
return size;
}
@@ -1088,7 +1061,6 @@ Ref<Texture2D> MeshTexture::get_base_texture() const {
}
void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
-
if (mesh.is_null() || base_texture.is_null()) {
return;
}
@@ -1102,6 +1074,7 @@ void MeshTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_mo
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
+
void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
if (mesh.is_null() || base_texture.is_null()) {
return;
@@ -1125,8 +1098,8 @@ void MeshTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile,
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
-void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
+void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
if (mesh.is_null() || base_texture.is_null()) {
return;
}
@@ -1149,6 +1122,7 @@ void MeshTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const
RID specular_rid = p_specular_map.is_valid() ? p_specular_map->get_rid() : RID();
RenderingServer::get_singleton()->canvas_item_add_mesh(p_canvas_item, mesh->get_rid(), xform, p_modulate, base_texture->get_rid(), normal_rid, specular_rid, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
+
bool MeshTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
r_rect = p_rect;
r_src_rect = p_src_rect;
@@ -1178,30 +1152,28 @@ MeshTexture::MeshTexture() {
//////////////////////////////////////////
int LargeTexture::get_width() const {
-
return size.width;
}
-int LargeTexture::get_height() const {
+int LargeTexture::get_height() const {
return size.height;
}
-RID LargeTexture::get_rid() const {
+RID LargeTexture::get_rid() const {
return RID();
}
bool LargeTexture::has_alpha() const {
-
for (int i = 0; i < pieces.size(); i++) {
- if (pieces[i].texture->has_alpha())
+ if (pieces[i].texture->has_alpha()) {
return true;
+ }
}
return false;
}
int LargeTexture::add_piece(const Point2 &p_offset, const Ref<Texture2D> &p_texture) {
-
ERR_FAIL_COND_V(p_texture.is_null(), -1);
Piece p;
p.offset = p_offset;
@@ -1212,13 +1184,11 @@ int LargeTexture::add_piece(const Point2 &p_offset, const Ref<Texture2D> &p_text
}
void LargeTexture::set_piece_offset(int p_idx, const Point2 &p_offset) {
-
ERR_FAIL_INDEX(p_idx, pieces.size());
pieces.write[p_idx].offset = p_offset;
};
void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture2D> &p_texture) {
-
ERR_FAIL_COND(p_texture == this);
ERR_FAIL_COND(p_texture.is_null());
ERR_FAIL_INDEX(p_idx, pieces.size());
@@ -1226,17 +1196,15 @@ void LargeTexture::set_piece_texture(int p_idx, const Ref<Texture2D> &p_texture)
};
void LargeTexture::set_size(const Size2 &p_size) {
-
size = p_size;
}
-void LargeTexture::clear() {
+void LargeTexture::clear() {
pieces.clear();
size = Size2i();
}
Array LargeTexture::_get_data() const {
-
Array arr;
for (int i = 0; i < pieces.size(); i++) {
arr.push_back(pieces[i].offset);
@@ -1245,8 +1213,8 @@ Array LargeTexture::_get_data() const {
arr.push_back(Size2(size));
return arr;
}
-void LargeTexture::_set_data(const Array &p_array) {
+void LargeTexture::_set_data(const Array &p_array) {
ERR_FAIL_COND(p_array.size() < 1);
ERR_FAIL_COND(!(p_array.size() & 1));
clear();
@@ -1257,24 +1225,22 @@ void LargeTexture::_set_data(const Array &p_array) {
}
int LargeTexture::get_piece_count() const {
-
return pieces.size();
}
-Vector2 LargeTexture::get_piece_offset(int p_idx) const {
+Vector2 LargeTexture::get_piece_offset(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, pieces.size(), Vector2());
return pieces[p_idx].offset;
}
-Ref<Texture2D> LargeTexture::get_piece_texture(int p_idx) const {
+Ref<Texture2D> LargeTexture::get_piece_texture(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, pieces.size(), Ref<Texture2D>());
return pieces[p_idx].texture;
}
-Ref<Image> LargeTexture::to_image() const {
+Ref<Image> LargeTexture::to_image() const {
Ref<Image> img = memnew(Image(this->get_width(), this->get_height(), false, Image::FORMAT_RGBA8));
for (int i = 0; i < pieces.size(); i++) {
-
Ref<Image> src_img = pieces[i].texture->get_data();
img->blit_rect(src_img, Rect2(0, 0, src_img->get_width(), src_img->get_height()), pieces[i].offset);
}
@@ -1283,7 +1249,6 @@ Ref<Image> LargeTexture::to_image() const {
}
void LargeTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("add_piece", "ofs", "texture"), &LargeTexture::add_piece);
ClassDB::bind_method(D_METHOD("set_piece_offset", "idx", "ofs"), &LargeTexture::set_piece_offset);
ClassDB::bind_method(D_METHOD("set_piece_texture", "idx", "texture"), &LargeTexture::set_piece_texture);
@@ -1301,42 +1266,40 @@ void LargeTexture::_bind_methods() {
}
void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
-
for (int i = 0; i < pieces.size(); i++) {
-
// TODO
pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
}
void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat) const {
-
//tiling not supported for this
- if (size.x == 0 || size.y == 0)
+ if (size.x == 0 || size.y == 0) {
return;
+ }
Size2 scale = p_rect.size / size;
for (int i = 0; i < pieces.size(); i++) {
-
// TODO
pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose, p_normal_map, p_specular_map, p_specular_color_shininess, p_texture_filter, p_texture_repeat);
}
}
-void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
+void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture2D> &p_normal_map, const Ref<Texture2D> &p_specular_map, const Color &p_specular_color_shininess, RS::CanvasItemTextureFilter p_texture_filter, RS::CanvasItemTextureRepeat p_texture_repeat, bool p_clip_uv) const {
//tiling not supported for this
- if (p_src_rect.size.x == 0 || p_src_rect.size.y == 0)
+ if (p_src_rect.size.x == 0 || p_src_rect.size.y == 0) {
return;
+ }
Size2 scale = p_rect.size / p_src_rect.size;
for (int i = 0; i < pieces.size(); i++) {
-
// TODO
Rect2 rect(pieces[i].offset, pieces[i].texture->get_size());
- if (!p_src_rect.intersects(rect))
+ if (!p_src_rect.intersects(rect)) {
continue;
+ }
Rect2 local = p_src_rect.clip(rect);
Rect2 target = local;
target.size *= scale;
@@ -1347,12 +1310,11 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
}
bool LargeTexture::is_pixel_opaque(int p_x, int p_y) const {
-
for (int i = 0; i < pieces.size(); i++) {
-
// TODO
- if (!pieces[i].texture.is_valid())
+ if (!pieces[i].texture.is_valid()) {
continue;
+ }
Rect2 rect(pieces[i].offset, pieces[i].texture->get_size());
if (rect.has_point(Point2(p_x, p_y))) {
@@ -1369,7 +1331,6 @@ LargeTexture::LargeTexture() {
///////////////////
void CurveTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_width", "width"), &CurveTexture::set_width);
ClassDB::bind_method(D_METHOD("set_curve", "curve"), &CurveTexture::set_curve);
@@ -1382,14 +1343,12 @@ void CurveTexture::_bind_methods() {
}
void CurveTexture::set_width(int p_width) {
-
ERR_FAIL_COND(p_width < 32 || p_width > 4096);
_width = p_width;
_update();
}
int CurveTexture::get_width() const {
-
return _width;
}
@@ -1419,7 +1378,6 @@ void CurveTexture::set_curve(Ref<Curve> p_curve) {
}
void CurveTexture::_update() {
-
Vector<uint8_t> data;
data.resize(_width * sizeof(float));
@@ -1455,12 +1413,10 @@ void CurveTexture::_update() {
}
Ref<Curve> CurveTexture::get_curve() const {
-
return _curve;
}
RID CurveTexture::get_rid() const {
-
if (!_texture.is_valid()) {
_texture = RS::get_singleton()->texture_2d_placeholder_create();
}
@@ -1470,11 +1426,13 @@ RID CurveTexture::get_rid() const {
CurveTexture::CurveTexture() {
_width = 2048;
}
+
CurveTexture::~CurveTexture() {
if (_texture.is_valid()) {
RS::get_singleton()->free(_texture);
}
}
+
//////////////////
//setter and getter names for property serialization
@@ -1497,7 +1455,6 @@ GradientTexture::~GradientTexture() {
}
void GradientTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_gradient", "gradient"), &GradientTexture::set_gradient);
ClassDB::bind_method(D_METHOD("get_gradient"), &GradientTexture::get_gradient);
@@ -1510,8 +1467,9 @@ void GradientTexture::_bind_methods() {
}
void GradientTexture::set_gradient(Ref<Gradient> p_gradient) {
- if (p_gradient == gradient)
+ if (p_gradient == gradient) {
return;
+ }
if (gradient.is_valid()) {
gradient->disconnect(CoreStringNames::get_singleton()->changed, callable_mp(this, &GradientTexture::_update));
}
@@ -1528,20 +1486,20 @@ Ref<Gradient> GradientTexture::get_gradient() const {
}
void GradientTexture::_queue_update() {
-
- if (update_pending)
+ if (update_pending) {
return;
+ }
update_pending = true;
call_deferred("_update");
}
void GradientTexture::_update() {
-
update_pending = false;
- if (gradient.is_null())
+ if (gradient.is_null()) {
return;
+ }
Vector<uint8_t> data;
data.resize(width * 4);
@@ -1550,7 +1508,6 @@ void GradientTexture::_update() {
Gradient &g = **gradient;
for (int i = 0; i < width; i++) {
-
float ofs = float(i) / (width - 1);
Color color = g.get_color_at_offset(ofs);
@@ -1574,12 +1531,11 @@ void GradientTexture::_update() {
}
void GradientTexture::set_width(int p_width) {
-
width = p_width;
_queue_update();
}
-int GradientTexture::get_width() const {
+int GradientTexture::get_width() const {
return width;
}
@@ -1593,7 +1549,6 @@ Ref<Image> GradientTexture::get_data() const {
//////////////////////////////////////
void ProxyTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_base", "base"), &ProxyTexture::set_base);
ClassDB::bind_method(D_METHOD("get_base"), &ProxyTexture::get_base);
@@ -1601,7 +1556,6 @@ void ProxyTexture::_bind_methods() {
}
void ProxyTexture::set_base(const Ref<Texture2D> &p_texture) {
-
ERR_FAIL_COND(p_texture == this);
base = p_texture;
@@ -1619,24 +1573,24 @@ void ProxyTexture::set_base(const Ref<Texture2D> &p_texture) {
}
Ref<Texture2D> ProxyTexture::get_base() const {
-
return base;
}
int ProxyTexture::get_width() const {
-
- if (base.is_valid())
+ if (base.is_valid()) {
return base->get_width();
+ }
return 1;
}
-int ProxyTexture::get_height() const {
- if (base.is_valid())
+int ProxyTexture::get_height() const {
+ if (base.is_valid()) {
return base->get_height();
+ }
return 1;
}
-RID ProxyTexture::get_rid() const {
+RID ProxyTexture::get_rid() const {
if (proxy.is_null()) {
proxy_ph = RS::get_singleton()->texture_2d_placeholder_create();
proxy = RS::get_singleton()->texture_proxy_create(proxy_ph);
@@ -1645,19 +1599,17 @@ RID ProxyTexture::get_rid() const {
}
bool ProxyTexture::has_alpha() const {
-
- if (base.is_valid())
+ if (base.is_valid()) {
return base->has_alpha();
+ }
return false;
}
ProxyTexture::ProxyTexture() {
-
//proxy = RS::get_singleton()->texture_create();
}
ProxyTexture::~ProxyTexture() {
-
if (proxy_ph.is_valid()) {
RS::get_singleton()->free(proxy_ph);
}
@@ -1665,10 +1617,10 @@ ProxyTexture::~ProxyTexture() {
RS::get_singleton()->free(proxy);
}
}
+
//////////////////////////////////////////////
void AnimatedTexture::_update_proxy() {
-
RWLockRead r(rw_lock);
float delta;
@@ -1692,15 +1644,20 @@ void AnimatedTexture::_update_proxy() {
}
int iter_max = frame_count;
- while (iter_max) {
+ while (iter_max && !pause) {
float frame_limit = limit + frames[current_frame].delay_sec;
if (time > frame_limit) {
current_frame++;
if (current_frame >= frame_count) {
- current_frame = 0;
+ if (oneshot) {
+ current_frame = frame_count - 1;
+ } else {
+ current_frame = 0;
+ }
}
time -= frame_limit;
+ _change_notify("current_frame");
} else {
break;
}
@@ -1719,12 +1676,42 @@ void AnimatedTexture::set_frames(int p_frames) {
frame_count = p_frames;
}
+
int AnimatedTexture::get_frames() const {
return frame_count;
}
-void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture) {
+void AnimatedTexture::set_current_frame(int p_frame) {
+ ERR_FAIL_COND(p_frame < 0 || p_frame >= frame_count);
+
+ RWLockWrite r(rw_lock);
+
+ current_frame = p_frame;
+}
+
+int AnimatedTexture::get_current_frame() const {
+ return current_frame;
+}
+void AnimatedTexture::set_pause(bool p_pause) {
+ RWLockWrite r(rw_lock);
+ pause = p_pause;
+}
+
+bool AnimatedTexture::get_pause() const {
+ return pause;
+}
+
+void AnimatedTexture::set_oneshot(bool p_oneshot) {
+ RWLockWrite r(rw_lock);
+ oneshot = p_oneshot;
+}
+
+bool AnimatedTexture::get_oneshot() const {
+ return oneshot;
+}
+
+void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture) {
ERR_FAIL_COND(p_texture == this);
ERR_FAIL_INDEX(p_frame, MAX_FRAMES);
@@ -1732,6 +1719,7 @@ void AnimatedTexture::set_frame_texture(int p_frame, const Ref<Texture2D> &p_tex
frames[p_frame].texture = p_texture;
}
+
Ref<Texture2D> AnimatedTexture::get_frame_texture(int p_frame) const {
ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, Ref<Texture2D>());
@@ -1747,6 +1735,7 @@ void AnimatedTexture::set_frame_delay(int p_frame, float p_delay_sec) {
frames[p_frame].delay_sec = p_delay_sec;
}
+
float AnimatedTexture::get_frame_delay(int p_frame) const {
ERR_FAIL_INDEX_V(p_frame, MAX_FRAMES, 0);
@@ -1760,6 +1749,7 @@ void AnimatedTexture::set_fps(float p_fps) {
fps = p_fps;
}
+
float AnimatedTexture::get_fps() const {
return fps;
}
@@ -1773,6 +1763,7 @@ int AnimatedTexture::get_width() const {
return frames[current_frame].texture->get_width();
}
+
int AnimatedTexture::get_height() const {
RWLockRead r(rw_lock);
@@ -1782,12 +1773,12 @@ int AnimatedTexture::get_height() const {
return frames[current_frame].texture->get_height();
}
+
RID AnimatedTexture::get_rid() const {
return proxy;
}
bool AnimatedTexture::has_alpha() const {
-
RWLockRead r(rw_lock);
if (!frames[current_frame].texture.is_valid()) {
@@ -1798,7 +1789,6 @@ bool AnimatedTexture::has_alpha() const {
}
Ref<Image> AnimatedTexture::get_data() const {
-
RWLockRead r(rw_lock);
if (!frames[current_frame].texture.is_valid()) {
@@ -1809,7 +1799,6 @@ Ref<Image> AnimatedTexture::get_data() const {
}
bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const {
-
RWLockRead r(rw_lock);
if (frames[current_frame].texture.is_valid()) {
@@ -1819,7 +1808,6 @@ bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const {
}
void AnimatedTexture::_validate_property(PropertyInfo &property) const {
-
String prop = property.name;
if (prop.begins_with("frame_")) {
int frame = prop.get_slicec('/', 0).get_slicec('_', 1).to_int();
@@ -1833,6 +1821,15 @@ void AnimatedTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_frames", "frames"), &AnimatedTexture::set_frames);
ClassDB::bind_method(D_METHOD("get_frames"), &AnimatedTexture::get_frames);
+ ClassDB::bind_method(D_METHOD("set_current_frame", "frame"), &AnimatedTexture::set_current_frame);
+ ClassDB::bind_method(D_METHOD("get_current_frame"), &AnimatedTexture::get_current_frame);
+
+ ClassDB::bind_method(D_METHOD("set_pause", "pause"), &AnimatedTexture::set_pause);
+ ClassDB::bind_method(D_METHOD("get_pause"), &AnimatedTexture::get_pause);
+
+ ClassDB::bind_method(D_METHOD("set_oneshot", "oneshot"), &AnimatedTexture::set_oneshot);
+ ClassDB::bind_method(D_METHOD("get_oneshot"), &AnimatedTexture::get_oneshot);
+
ClassDB::bind_method(D_METHOD("set_fps", "fps"), &AnimatedTexture::set_fps);
ClassDB::bind_method(D_METHOD("get_fps"), &AnimatedTexture::get_fps);
@@ -1843,6 +1840,9 @@ void AnimatedTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_frame_delay", "frame"), &AnimatedTexture::get_frame_delay);
ADD_PROPERTY(PropertyInfo(Variant::INT, "frames", PROPERTY_HINT_RANGE, "1," + itos(MAX_FRAMES), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_frames", "get_frames");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "current_frame", PROPERTY_HINT_NONE, "", 0), "set_current_frame", "get_current_frame");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pause"), "set_pause", "get_pause");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "oneshot"), "set_oneshot", "get_oneshot");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps");
for (int i = 0; i < MAX_FRAMES; i++) {
@@ -1864,6 +1864,8 @@ AnimatedTexture::AnimatedTexture() {
fps = 4;
prev_ticks = 0;
current_frame = 0;
+ pause = false;
+ oneshot = false;
RenderingServer::get_singleton()->connect("frame_pre_draw", callable_mp(this, &AnimatedTexture::_update_proxy));
#ifndef NO_THREADS
@@ -1880,25 +1882,49 @@ AnimatedTexture::~AnimatedTexture() {
memdelete(rw_lock);
}
}
+
///////////////////////////////
-Image::Format TextureLayered::get_format() const {
+void TextureLayered::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format);
+ ClassDB::bind_method(D_METHOD("get_layered_type"), &TextureLayered::get_layered_type);
+ ClassDB::bind_method(D_METHOD("get_width"), &TextureLayered::get_width);
+ ClassDB::bind_method(D_METHOD("get_height"), &TextureLayered::get_height);
+ ClassDB::bind_method(D_METHOD("get_layers"), &TextureLayered::get_layers);
+ ClassDB::bind_method(D_METHOD("has_mipmaps"), &TextureLayered::has_mipmaps);
+ ClassDB::bind_method(D_METHOD("get_layer_data", "layer"), &TextureLayered::get_layer_data);
+
+ BIND_ENUM_CONSTANT(LAYERED_TYPE_2D_ARRAY);
+ BIND_ENUM_CONSTANT(LAYERED_TYPE_CUBEMAP);
+ BIND_ENUM_CONSTANT(LAYERED_TYPE_CUBEMAP_ARRAY);
+}
+
+///////////////////////////////
+Image::Format ImageTextureLayered::get_format() const {
return format;
}
-uint32_t TextureLayered::get_width() const {
+int ImageTextureLayered::get_width() const {
return width;
}
-uint32_t TextureLayered::get_height() const {
+int ImageTextureLayered::get_height() const {
return height;
}
-uint32_t TextureLayered::get_layers() const {
+int ImageTextureLayered::get_layers() const {
return layers;
}
-Error TextureLayered::_create_from_images(const Array &p_images) {
+bool ImageTextureLayered::has_mipmaps() const {
+ return mipmaps;
+}
+
+ImageTextureLayered::LayeredType ImageTextureLayered::get_layered_type() const {
+ return layered_type;
+}
+
+Error ImageTextureLayered::_create_from_images(const Array &p_images) {
Vector<Ref<Image>> images;
for (int i = 0; i < p_images.size(); i++) {
Ref<Image> img = p_images[i];
@@ -1909,7 +1935,7 @@ Error TextureLayered::_create_from_images(const Array &p_images) {
return create_from_images(images);
}
-Array TextureLayered::_get_images() const {
+Array ImageTextureLayered::_get_images() const {
Array images;
for (int i = 0; i < layers; i++) {
images.push_back(get_layer_data(i));
@@ -1917,14 +1943,13 @@ Array TextureLayered::_get_images() const {
return images;
}
-Error TextureLayered::create_from_images(Vector<Ref<Image>> p_images) {
-
+Error ImageTextureLayered::create_from_images(Vector<Ref<Image>> p_images) {
int new_layers = p_images.size();
ERR_FAIL_COND_V(new_layers == 0, ERR_INVALID_PARAMETER);
- if (layered_type == RS::TEXTURE_LAYERED_CUBEMAP) {
+ if (layered_type == LAYERED_TYPE_CUBEMAP) {
ERR_FAIL_COND_V_MSG(new_layers != 6, ERR_INVALID_PARAMETER,
"Cubemaps require exactly 6 layers");
- } else if (layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY) {
+ } else if (layered_type == LAYERED_TYPE_CUBEMAP_ARRAY) {
ERR_FAIL_COND_V_MSG((new_layers % 6) != 0, ERR_INVALID_PARAMETER,
"Cubemap array layers must be a multiple of 6");
}
@@ -1946,11 +1971,11 @@ Error TextureLayered::create_from_images(Vector<Ref<Image>> p_images) {
}
if (texture.is_valid()) {
- RID new_texture = RS::get_singleton()->texture_2d_layered_create(p_images, layered_type);
+ RID new_texture = RS::get_singleton()->texture_2d_layered_create(p_images, RS::TextureLayeredType(layered_type));
ERR_FAIL_COND_V(!new_texture.is_valid(), ERR_CANT_CREATE);
RS::get_singleton()->texture_replace(texture, new_texture);
} else {
- texture = RS::get_singleton()->texture_2d_layered_create(p_images, layered_type);
+ texture = RS::get_singleton()->texture_2d_layered_create(p_images, RS::TextureLayeredType(layered_type));
ERR_FAIL_COND_V(!texture.is_valid(), ERR_CANT_CREATE);
}
@@ -1962,7 +1987,7 @@ Error TextureLayered::create_from_images(Vector<Ref<Image>> p_images) {
return OK;
}
-void TextureLayered::update_layer(const Ref<Image> &p_image, int p_layer) {
+void ImageTextureLayered::update_layer(const Ref<Image> &p_image, int p_layer) {
ERR_FAIL_COND(texture.is_valid());
ERR_FAIL_COND(p_image.is_null());
ERR_FAIL_COND(p_image->get_format() != format);
@@ -1972,19 +1997,19 @@ void TextureLayered::update_layer(const Ref<Image> &p_image, int p_layer) {
RS::get_singleton()->texture_2d_update(texture, p_image, p_layer);
}
-Ref<Image> TextureLayered::get_layer_data(int p_layer) const {
+Ref<Image> ImageTextureLayered::get_layer_data(int p_layer) const {
ERR_FAIL_INDEX_V(p_layer, layers, Ref<Image>());
return RS::get_singleton()->texture_2d_layer_get(texture, p_layer);
}
-RID TextureLayered::get_rid() const {
+RID ImageTextureLayered::get_rid() const {
if (texture.is_null()) {
- texture = RS::get_singleton()->texture_2d_layered_placeholder_create();
+ texture = RS::get_singleton()->texture_2d_layered_placeholder_create(RS::TextureLayeredType(layered_type));
}
return texture;
}
-void TextureLayered::set_path(const String &p_path, bool p_take_over) {
+void ImageTextureLayered::set_path(const String &p_path, bool p_take_over) {
if (texture.is_valid()) {
RS::get_singleton()->texture_set_path(texture, p_path);
}
@@ -1992,24 +2017,16 @@ void TextureLayered::set_path(const String &p_path, bool p_take_over) {
Resource::set_path(p_path, p_take_over);
}
-void TextureLayered::_bind_methods() {
+void ImageTextureLayered::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("create_from_images", "images"), &ImageTextureLayered::_create_from_images);
+ ClassDB::bind_method(D_METHOD("update_layer", "image", "layer"), &ImageTextureLayered::update_layer);
- ClassDB::bind_method(D_METHOD("get_format"), &TextureLayered::get_format);
-
- ClassDB::bind_method(D_METHOD("get_width"), &TextureLayered::get_width);
- ClassDB::bind_method(D_METHOD("get_height"), &TextureLayered::get_height);
- ClassDB::bind_method(D_METHOD("get_layers"), &TextureLayered::get_layers);
-
- ClassDB::bind_method(D_METHOD("create_from_images", "images"), &TextureLayered::_create_from_images);
- ClassDB::bind_method(D_METHOD("update_layer", "image", "layer"), &TextureLayered::update_layer);
- ClassDB::bind_method(D_METHOD("get_layer_data", "layer"), &TextureLayered::get_layer_data);
-
- ClassDB::bind_method(D_METHOD("_get_images"), &TextureLayered::_get_images);
+ ClassDB::bind_method(D_METHOD("_get_images"), &ImageTextureLayered::_get_images);
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_images", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_INTERNAL), "create_from_images", "_get_images");
}
-TextureLayered::TextureLayered(RenderingServer::TextureLayeredType p_layered_type) {
+ImageTextureLayered::ImageTextureLayered(LayeredType p_layered_type) {
layered_type = p_layered_type;
format = Image::FORMAT_MAX;
@@ -2018,193 +2035,237 @@ TextureLayered::TextureLayered(RenderingServer::TextureLayeredType p_layered_typ
layers = 0;
}
-TextureLayered::~TextureLayered() {
+ImageTextureLayered::~ImageTextureLayered() {
if (texture.is_valid()) {
RS::get_singleton()->free(texture);
}
}
-RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) {
+///////////////////////////////////////////
- if (r_error) {
- *r_error = ERR_CANT_OPEN;
- }
-
- Ref<TextureLayered> lt;
-
- if (p_path.ends_with("cube")) {
- Ref<Cubemap> cube;
- cube.instance();
- lt = cube;
- } else if (p_path.ends_with("cubearr")) {
- Ref<CubemapArray> cubearr;
- cubearr.instance();
- lt = cubearr;
- } else if (p_path.ends_with("tex2darr")) {
- Ref<Texture2DArray> t2darr;
- t2darr.instance();
- lt = t2darr;
- } else {
- ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture extension.");
+void StreamTextureLayered::set_path(const String &p_path, bool p_take_over) {
+ if (texture.is_valid()) {
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
}
- FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
- ERR_FAIL_COND_V_MSG(!f, RES(), "Cannot open file '" + p_path + "'.");
+ Resource::set_path(p_path, p_take_over);
+}
- char header[5] = { 0, 0, 0, 0, 0 };
- f->get_buffer((uint8_t *)header, 4);
+Image::Format StreamTextureLayered::get_format() const {
+ return format;
+}
- if (String(header) != "GDLT") {
- f->close();
- memdelete(f);
- if (r_error) {
- *r_error = ERR_FILE_CORRUPT;
- }
- // FIXME: It's bogus that we fail in both branches. Seen while rebasing
- // vulkan branch on master branch.
- ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture.");
- } else {
+Error StreamTextureLayered::_load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit) {
+ ERR_FAIL_COND_V(images.size() != 0, ERR_INVALID_PARAMETER);
- f->close();
- memdelete(f);
- ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture file format '" + String((const char *)header) + "'.");
+ FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+
+ uint8_t header[4];
+ f->get_buffer(header, 4);
+ if (header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L') {
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture layered file is corrupt (Bad header).");
}
- int tw = f->get_32();
- int th = f->get_32();
- int td = f->get_32();
- bool use_mipmaps = f->get_32() != 0; //texture flags (deprecated)
- Image::Format format = Image::Format(f->get_32());
- uint32_t compression = f->get_32(); // 0 - lossless (PNG), 1 - vram, 2 - uncompressed
+ uint32_t version = f->get_32();
- Vector<Ref<Image>> images;
- for (int layer = 0; layer < td; layer++) {
+ if (version > FORMAT_VERSION) {
+ ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new.");
+ }
- Ref<Image> image;
- image.instance();
+ uint32_t layer_count = f->get_32(); //layer count
+ uint32_t type = f->get_32(); //layer count
+ ERR_FAIL_COND_V(type != layered_type, ERR_INVALID_DATA);
- if (compression == COMPRESSION_LOSSLESS) {
- //look for a PNG file inside
+ uint32_t df = f->get_32(); //data format
+ mipmap_limit = int(f->get_32());
+ //reserverd
+ f->get_32();
+ f->get_32();
+ f->get_32();
- int mipmaps = f->get_32();
- Vector<Ref<Image>> mipmap_images;
+ if (!(df & FORMAT_BIT_STREAM)) {
+ p_size_limit = 0;
+ }
- for (int i = 0; i < mipmaps; i++) {
- uint32_t size = f->get_32();
+ images.resize(layer_count);
- Vector<uint8_t> pv;
- pv.resize(size);
- {
- uint8_t *w = pv.ptrw();
- f->get_buffer(w, size);
- }
+ for (uint32_t i = 0; i < layer_count; i++) {
+ Ref<Image> image = StreamTexture2D::load_image_from_file(f, p_size_limit);
+ ERR_FAIL_COND_V(image.is_null() || image->empty(), ERR_CANT_OPEN);
+ images.write[i] = image;
+ }
- Ref<Image> img = Image::lossless_unpacker(pv);
+ return OK;
+}
- if (img.is_null() || img->empty() || format != img->get_format()) {
- if (r_error) {
- *r_error = ERR_FILE_CORRUPT;
- }
- f->close();
- memdelete(f);
- ERR_FAIL_V(RES());
- }
+Error StreamTextureLayered::load(const String &p_path) {
+ Vector<Ref<Image>> images;
- mipmap_images.push_back(img);
- }
+ int mipmap_limit;
- if (mipmap_images.size() == 1) {
+ Error err = _load_data(p_path, images, mipmap_limit);
+ if (err) {
+ return err;
+ }
- image = mipmap_images[0];
+ if (texture.is_valid()) {
+ RID new_texture = RS::get_singleton()->texture_2d_layered_create(images, RS::TextureLayeredType(layered_type));
+ RS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = RS::get_singleton()->texture_2d_layered_create(images, RS::TextureLayeredType(layered_type));
+ }
- } else {
- int total_size = Image::get_image_data_size(tw, th, format, true);
- Vector<uint8_t> img_data;
- img_data.resize(total_size);
-
- {
- uint8_t *w = img_data.ptrw();
-
- int ofs = 0;
- for (int i = 0; i < mipmap_images.size(); i++) {
-
- Vector<uint8_t> id = mipmap_images[i]->get_data();
- int len = id.size();
- const uint8_t *r = id.ptr();
- copymem(&w[ofs], r, len);
- ofs += len;
- }
- }
+ w = images[0]->get_width();
+ h = images[0]->get_height();
+ mipmaps = images[0]->has_mipmaps();
+ format = images[0]->get_format();
+ layers = images.size();
- image->create(tw, th, true, format, img_data);
- if (image->empty()) {
- if (r_error) {
- *r_error = ERR_FILE_CORRUPT;
- }
- f->close();
- memdelete(f);
- ERR_FAIL_V(RES());
- }
- }
+ path_to_file = p_path;
- } else {
+ if (get_path() == String()) {
+ //temporarily set path if no path set for resource, helps find errors
+ RenderingServer::get_singleton()->texture_set_path(texture, p_path);
+ }
- //look for regular format
+ _change_notify();
+ emit_changed();
+ return OK;
+}
- int total_size = Image::get_image_data_size(tw, th, format, use_mipmaps);
+String StreamTextureLayered::get_load_path() const {
+ return path_to_file;
+}
- Vector<uint8_t> img_data;
- img_data.resize(total_size);
+int StreamTextureLayered::get_width() const {
+ return w;
+}
- {
- uint8_t *w = img_data.ptrw();
- int bytes = f->get_buffer(w, total_size);
- if (bytes != total_size) {
- if (r_error) {
- *r_error = ERR_FILE_CORRUPT;
- }
- f->close();
- memdelete(f);
- ERR_FAIL_V(RES());
- }
- }
+int StreamTextureLayered::get_height() const {
+ return h;
+}
- image->create(tw, th, use_mipmaps, format, img_data);
- }
+int StreamTextureLayered::get_layers() const {
+ return layers;
+}
+
+bool StreamTextureLayered::has_mipmaps() const {
+ return mipmaps;
+}
- images.push_back(image);
+TextureLayered::LayeredType StreamTextureLayered::get_layered_type() const {
+ return layered_type;
+}
+
+RID StreamTextureLayered::get_rid() const {
+ if (!texture.is_valid()) {
+ texture = RS::get_singleton()->texture_2d_layered_placeholder_create(RS::TextureLayeredType(layered_type));
}
+ return texture;
+}
- Error err = lt->create_from_images(images);
- if (err != OK) {
- *r_error = err;
- return RES();
+Ref<Image> StreamTextureLayered::get_layer_data(int p_layer) const {
+ if (texture.is_valid()) {
+ return RS::get_singleton()->texture_2d_layer_get(texture, p_layer);
} else {
+ return Ref<Image>();
+ }
+}
- if (r_error)
- *r_error = OK;
+void StreamTextureLayered::reload_from_file() {
+ String path = get_path();
+ if (!path.is_resource_file()) {
+ return;
}
- return lt;
+ path = ResourceLoader::path_remap(path); //remap for translation
+ path = ResourceLoader::import_remap(path); //remap for import
+ if (!path.is_resource_file()) {
+ return;
+ }
+
+ load(path);
+}
+
+void StreamTextureLayered::_validate_property(PropertyInfo &property) const {
}
-void ResourceFormatLoaderTextureLayered::get_recognized_extensions(List<String> *p_extensions) const {
+void StreamTextureLayered::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("load", "path"), &StreamTextureLayered::load);
+ ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTextureLayered::get_load_path);
- p_extensions->push_back("cube");
- p_extensions->push_back("cubearr");
- p_extensions->push_back("tex2darr");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path");
+}
+
+StreamTextureLayered::StreamTextureLayered(LayeredType p_type) {
+ layered_type = p_type;
+ format = Image::FORMAT_MAX;
+ w = 0;
+ h = 0;
+ layers = 0;
+ mipmaps = false;
}
-bool ResourceFormatLoaderTextureLayered::handles_type(const String &p_type) const {
- return p_type == "Texture2DArray" || p_type == "Cubemap" || p_type == "CubemapArray";
+
+StreamTextureLayered::~StreamTextureLayered() {
+ if (texture.is_valid()) {
+ RS::get_singleton()->free(texture);
+ }
}
-String ResourceFormatLoaderTextureLayered::get_resource_type(const String &p_path) const {
- if (p_path.get_extension().to_lower() == "cube")
- return "Cubemap";
- if (p_path.get_extension().to_lower() == "cubearr")
- return "CubemapArray";
- if (p_path.get_extension().to_lower() == "tex2darr")
- return "Texture2DArray";
+/////////////////////////////////////////////////
+
+RES ResourceFormatLoaderStreamTextureLayered::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) {
+ Ref<StreamTextureLayered> st;
+ if (p_path.get_extension().to_lower() == "stexarray") {
+ Ref<StreamTexture2DArray> s;
+ s.instance();
+ st = s;
+ } else if (p_path.get_extension().to_lower() == "scube") {
+ Ref<StreamCubemap> s;
+ s.instance();
+ st = s;
+ } else if (p_path.get_extension().to_lower() == "scubearray") {
+ Ref<StreamCubemapArray> s;
+ s.instance();
+ st = s;
+ } else {
+ if (r_error) {
+ *r_error = ERR_FILE_UNRECOGNIZED;
+ }
+ return RES();
+ }
+ Error err = st->load(p_path);
+ if (r_error) {
+ *r_error = err;
+ }
+ if (err != OK) {
+ return RES();
+ }
+
+ return st;
+}
+
+void ResourceFormatLoaderStreamTextureLayered::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back("stexarray");
+ p_extensions->push_back("scube");
+ p_extensions->push_back("scubearray");
+}
+
+bool ResourceFormatLoaderStreamTextureLayered::handles_type(const String &p_type) const {
+ return p_type == "StreamTexture2DArray" || p_type == "StreamCubemap" || p_type == "StreamCubemapArray";
+}
+
+String ResourceFormatLoaderStreamTextureLayered::get_resource_type(const String &p_path) const {
+ if (p_path.get_extension().to_lower() == "stexarray") {
+ return "StreamTexture2DArray";
+ }
+ if (p_path.get_extension().to_lower() == "scube") {
+ return "StreamCubemap";
+ }
+ if (p_path.get_extension().to_lower() == "scubearray") {
+ return "StreamCubemapArray";
+ }
return "";
}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 18f70baa07..005f899512 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -51,7 +51,6 @@ public:
};
class Texture2D : public Texture {
-
GDCLASS(Texture2D, Texture);
OBJ_SAVE_TYPE(Texture2D); // Saves derived classes with common type so they can be interchanged.
@@ -81,7 +80,6 @@ public:
class BitMap;
class ImageTexture : public Texture2D {
-
GDCLASS(ImageTexture, Texture2D);
RES_BASE_EXTENSION("tex");
@@ -132,9 +130,8 @@ public:
~ImageTexture();
};
-class StreamTexture : public Texture2D {
-
- GDCLASS(StreamTexture, Texture2D);
+class StreamTexture2D : public Texture2D {
+ GDCLASS(StreamTexture2D, Texture2D);
public:
enum DataFormat {
@@ -181,8 +178,8 @@ protected:
public:
static Ref<Image> load_image_from_file(FileAccess *p_file, int p_size_limit);
- typedef void (*TextureFormatRequestCallback)(const Ref<StreamTexture> &);
- typedef void (*TextureFormatRoughnessRequestCallback)(const Ref<StreamTexture> &, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel);
+ typedef void (*TextureFormatRequestCallback)(const Ref<StreamTexture2D> &);
+ typedef void (*TextureFormatRoughnessRequestCallback)(const Ref<StreamTexture2D> &, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_roughness_channel);
static TextureFormatRequestCallback request_3d_callback;
static TextureFormatRoughnessRequestCallback request_roughness_callback;
@@ -207,20 +204,19 @@ public:
virtual Ref<Image> get_data() const;
- StreamTexture();
- ~StreamTexture();
+ StreamTexture2D();
+ ~StreamTexture2D();
};
-class ResourceFormatLoaderStreamTexture : public ResourceFormatLoader {
+class ResourceFormatLoaderStreamTexture2D : public ResourceFormatLoader {
public:
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
class AtlasTexture : public Texture2D {
-
GDCLASS(AtlasTexture, Texture2D);
RES_BASE_EXTENSION("atlastex");
@@ -264,7 +260,6 @@ public:
class Mesh;
class MeshTexture : public Texture2D {
-
GDCLASS(MeshTexture, Texture2D);
RES_BASE_EXTENSION("meshtex");
@@ -302,13 +297,11 @@ public:
};
class LargeTexture : public Texture2D {
-
GDCLASS(LargeTexture, Texture2D);
RES_BASE_EXTENSION("largetex");
protected:
struct Piece {
-
Point2 offset;
Ref<Texture2D> texture;
};
@@ -349,10 +342,33 @@ public:
};
class TextureLayered : public Texture {
-
GDCLASS(TextureLayered, Texture);
- RS::TextureLayeredType layered_type;
+protected:
+ static void _bind_methods();
+
+public:
+ enum LayeredType {
+ LAYERED_TYPE_2D_ARRAY,
+ LAYERED_TYPE_CUBEMAP,
+ LAYERED_TYPE_CUBEMAP_ARRAY
+ };
+
+ virtual Image::Format get_format() const = 0;
+ virtual LayeredType get_layered_type() const = 0;
+ virtual int get_width() const = 0;
+ virtual int get_height() const = 0;
+ virtual int get_layers() const = 0;
+ virtual bool has_mipmaps() const = 0;
+ virtual Ref<Image> get_layer_data(int p_layer) const = 0;
+};
+
+VARIANT_ENUM_CAST(TextureLayered::LayeredType)
+
+class ImageTextureLayered : public TextureLayered {
+ GDCLASS(ImageTextureLayered, TextureLayered);
+
+ LayeredType layered_type;
mutable RID texture;
Image::Format format;
@@ -370,65 +386,137 @@ protected:
static void _bind_methods();
public:
- Image::Format get_format() const;
- uint32_t get_width() const;
- uint32_t get_height() const;
- uint32_t get_layers() const;
- bool has_mipmaps() const;
+ virtual Image::Format get_format() const;
+ virtual int get_width() const;
+ virtual int get_height() const;
+ virtual int get_layers() const;
+ virtual bool has_mipmaps() const;
+ virtual LayeredType get_layered_type() const;
Error create_from_images(Vector<Ref<Image>> p_images);
void update_layer(const Ref<Image> &p_image, int p_layer);
- Ref<Image> get_layer_data(int p_layer) const;
+ virtual Ref<Image> get_layer_data(int p_layer) const;
virtual RID get_rid() const;
virtual void set_path(const String &p_path, bool p_take_over = false);
- TextureLayered(RS::TextureLayeredType p_layered_type);
- ~TextureLayered();
+ ImageTextureLayered(LayeredType p_layered_type);
+ ~ImageTextureLayered();
};
-class Texture2DArray : public TextureLayered {
-
- GDCLASS(Texture2DArray, TextureLayered)
+class Texture2DArray : public ImageTextureLayered {
+ GDCLASS(Texture2DArray, ImageTextureLayered)
public:
Texture2DArray() :
- TextureLayered(RS::TEXTURE_LAYERED_2D_ARRAY) {}
+ ImageTextureLayered(LAYERED_TYPE_2D_ARRAY) {}
};
-class Cubemap : public TextureLayered {
-
- GDCLASS(Cubemap, TextureLayered);
+class Cubemap : public ImageTextureLayered {
+ GDCLASS(Cubemap, ImageTextureLayered);
public:
Cubemap() :
- TextureLayered(RS::TEXTURE_LAYERED_CUBEMAP) {}
+ ImageTextureLayered(LAYERED_TYPE_CUBEMAP) {}
};
-class CubemapArray : public TextureLayered {
-
- GDCLASS(CubemapArray, TextureLayered);
+class CubemapArray : public ImageTextureLayered {
+ GDCLASS(CubemapArray, ImageTextureLayered);
public:
CubemapArray() :
- TextureLayered(RS::TEXTURE_LAYERED_CUBEMAP_ARRAY) {}
+ ImageTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {}
};
-class ResourceFormatLoaderTextureLayered : public ResourceFormatLoader {
+class StreamTextureLayered : public TextureLayered {
+ GDCLASS(StreamTextureLayered, TextureLayered);
+
public:
- enum Compression {
- COMPRESSION_LOSSLESS,
- COMPRESSION_VRAM,
- COMPRESSION_UNCOMPRESSED
+ enum DataFormat {
+ DATA_FORMAT_IMAGE,
+ DATA_FORMAT_LOSSLESS,
+ DATA_FORMAT_LOSSY,
+ DATA_FORMAT_BASIS_UNIVERSAL,
+ };
+
+ enum {
+ FORMAT_VERSION = 1
};
- virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr);
+ enum FormatBits {
+ FORMAT_MASK_IMAGE_FORMAT = (1 << 20) - 1,
+ FORMAT_BIT_LOSSLESS = 1 << 20,
+ FORMAT_BIT_LOSSY = 1 << 21,
+ FORMAT_BIT_STREAM = 1 << 22,
+ FORMAT_BIT_HAS_MIPMAPS = 1 << 23,
+ };
+
+private:
+ Error _load_data(const String &p_path, Vector<Ref<Image>> &images, int &mipmap_limit, int p_size_limit = 0);
+ String path_to_file;
+ mutable RID texture;
+ Image::Format format;
+ int w, h, layers;
+ bool mipmaps;
+ LayeredType layered_type;
+
+ virtual void reload_from_file();
+
+protected:
+ static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const;
+
+public:
+ Image::Format get_format() const;
+ Error load(const String &p_path);
+ String get_load_path() const;
+ virtual LayeredType get_layered_type() const;
+
+ int get_width() const;
+ int get_height() const;
+ int get_layers() const;
+ virtual bool has_mipmaps() const;
+ virtual RID get_rid() const;
+
+ virtual void set_path(const String &p_path, bool p_take_over);
+
+ virtual Ref<Image> get_layer_data(int p_layer) const;
+
+ StreamTextureLayered(LayeredType p_layered_type);
+ ~StreamTextureLayered();
+};
+
+class StreamTexture2DArray : public StreamTextureLayered {
+ GDCLASS(StreamTexture2DArray, StreamTextureLayered)
+public:
+ StreamTexture2DArray() :
+ StreamTextureLayered(LAYERED_TYPE_2D_ARRAY) {}
+};
+
+class StreamCubemap : public StreamTextureLayered {
+ GDCLASS(StreamCubemap, StreamTextureLayered);
+
+public:
+ StreamCubemap() :
+ StreamTextureLayered(LAYERED_TYPE_CUBEMAP) {}
+};
+
+class StreamCubemapArray : public StreamTextureLayered {
+ GDCLASS(StreamCubemapArray, StreamTextureLayered);
+
+public:
+ StreamCubemapArray() :
+ StreamTextureLayered(LAYERED_TYPE_CUBEMAP_ARRAY) {}
+};
+
+class ResourceFormatLoaderStreamTextureLayered : public ResourceFormatLoader {
+public:
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String &p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
class CurveTexture : public Texture2D {
-
GDCLASS(CurveTexture, Texture2D);
RES_BASE_EXTENSION("curvetex")
@@ -478,7 +566,6 @@ class GradientTexture : public Texture2D {
public:
struct Point {
-
float offset;
Color color;
bool operator<(const Point &p_ponit) const {
@@ -555,7 +642,6 @@ private:
RID proxy;
struct Frame {
-
Ref<Texture2D> texture;
float delay_sec;
@@ -567,7 +653,8 @@ private:
Frame frames[MAX_FRAMES];
int frame_count;
int current_frame;
-
+ bool pause;
+ bool oneshot;
float fps;
float time;
@@ -584,6 +671,15 @@ public:
void set_frames(int p_frames);
int get_frames() const;
+ void set_current_frame(int p_frame);
+ int get_current_frame() const;
+
+ void set_pause(bool p_pause);
+ bool get_pause() const;
+
+ void set_oneshot(bool p_oneshot);
+ bool get_oneshot() const;
+
void set_frame_texture(int p_frame, const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_frame_texture(int p_frame) const;
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 98ebf048dc..6a85d357ff 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -33,12 +33,10 @@
#include "core/print_string.h"
void Theme::_emit_theme_changed() {
-
emit_changed();
}
Vector<String> Theme::_get_icon_list(const String &p_type) const {
-
Vector<String> ilret;
List<StringName> il;
@@ -54,7 +52,6 @@ Vector<String> Theme::_get_icon_list(const String &p_type) const {
}
Vector<String> Theme::_get_stylebox_list(const String &p_type) const {
-
Vector<String> ilret;
List<StringName> il;
@@ -69,8 +66,7 @@ Vector<String> Theme::_get_stylebox_list(const String &p_type) const {
return ilret;
}
-Vector<String> Theme::_get_stylebox_types(void) const {
-
+Vector<String> Theme::_get_stylebox_types() const {
Vector<String> ilret;
List<StringName> il;
@@ -86,7 +82,6 @@ Vector<String> Theme::_get_stylebox_types(void) const {
}
Vector<String> Theme::_get_font_list(const String &p_type) const {
-
Vector<String> ilret;
List<StringName> il;
@@ -102,7 +97,6 @@ Vector<String> Theme::_get_font_list(const String &p_type) const {
}
Vector<String> Theme::_get_color_list(const String &p_type) const {
-
Vector<String> ilret;
List<StringName> il;
@@ -118,7 +112,6 @@ Vector<String> Theme::_get_color_list(const String &p_type) const {
}
Vector<String> Theme::_get_constant_list(const String &p_type) const {
-
Vector<String> ilret;
List<StringName> il;
@@ -134,7 +127,6 @@ Vector<String> Theme::_get_constant_list(const String &p_type) const {
}
Vector<String> Theme::_get_type_list(const String &p_type) const {
-
Vector<String> ilret;
List<StringName> il;
@@ -150,32 +142,26 @@ Vector<String> Theme::_get_type_list(const String &p_type) const {
}
bool Theme::_set(const StringName &p_name, const Variant &p_value) {
-
String sname = p_name;
if (sname.find("/") != -1) {
-
String type = sname.get_slicec('/', 1);
String node_type = sname.get_slicec('/', 0);
String name = sname.get_slicec('/', 2);
if (type == "icons") {
-
set_icon(name, node_type, p_value);
} else if (type == "styles") {
-
set_stylebox(name, node_type, p_value);
} else if (type == "fonts") {
-
set_font(name, node_type, p_value);
} else if (type == "colors") {
-
set_color(name, node_type, p_value);
} else if (type == "constants") {
-
set_constant(name, node_type, p_value);
- } else
+ } else {
return false;
+ }
return true;
}
@@ -184,41 +170,38 @@ bool Theme::_set(const StringName &p_name, const Variant &p_value) {
}
bool Theme::_get(const StringName &p_name, Variant &r_ret) const {
-
String sname = p_name;
if (sname.find("/") != -1) {
-
String type = sname.get_slicec('/', 1);
String node_type = sname.get_slicec('/', 0);
String name = sname.get_slicec('/', 2);
if (type == "icons") {
-
- if (!has_icon(name, node_type))
+ if (!has_icon(name, node_type)) {
r_ret = Ref<Texture2D>();
- else
+ } else {
r_ret = get_icon(name, node_type);
+ }
} else if (type == "styles") {
-
- if (!has_stylebox(name, node_type))
+ if (!has_stylebox(name, node_type)) {
r_ret = Ref<StyleBox>();
- else
+ } else {
r_ret = get_stylebox(name, node_type);
+ }
} else if (type == "fonts") {
-
- if (!has_font(name, node_type))
+ if (!has_font(name, node_type)) {
r_ret = Ref<Font>();
- else
+ } else {
r_ret = get_font(name, node_type);
+ }
} else if (type == "colors") {
-
r_ret = get_color(name, node_type);
} else if (type == "constants") {
-
r_ret = get_constant(name, node_type);
- } else
+ } else {
return false;
+ }
return true;
}
@@ -227,17 +210,14 @@ bool Theme::_get(const StringName &p_name, Variant &r_ret) const {
}
void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
-
List<PropertyInfo> list;
const StringName *key = nullptr;
while ((key = icon_map.next(key))) {
-
const StringName *key2 = nullptr;
while ((key2 = icon_map[*key].next(key2))) {
-
list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/icons/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
}
}
@@ -245,11 +225,9 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
while ((key = style_map.next(key))) {
-
const StringName *key2 = nullptr;
while ((key2 = style_map[*key].next(key2))) {
-
list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/styles/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
}
}
@@ -257,11 +235,9 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
while ((key = font_map.next(key))) {
-
const StringName *key2 = nullptr;
while ((key2 = font_map[*key].next(key2))) {
-
list.push_back(PropertyInfo(Variant::OBJECT, String() + *key + "/fonts/" + *key2, PROPERTY_HINT_RESOURCE_TYPE, "Font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_STORE_IF_NULL));
}
}
@@ -269,11 +245,9 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
while ((key = color_map.next(key))) {
-
const StringName *key2 = nullptr;
while ((key2 = color_map[*key].next(key2))) {
-
list.push_back(PropertyInfo(Variant::COLOR, String() + *key + "/colors/" + *key2));
}
}
@@ -281,11 +255,9 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
key = nullptr;
while ((key = constant_map.next(key))) {
-
const StringName *key2 = nullptr;
while ((key2 = constant_map[*key].next(key2))) {
-
list.push_back(PropertyInfo(Variant::INT, String() + *key + "/constants/" + *key2));
}
}
@@ -297,9 +269,9 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const {
}
void Theme::set_default_theme_font(const Ref<Font> &p_default_font) {
-
- if (default_theme_font == p_default_font)
+ if (default_theme_font == p_default_font) {
return;
+ }
if (default_theme_font.is_valid()) {
default_theme_font->disconnect("changed", callable_mp(this, &Theme::_emit_theme_changed));
@@ -316,7 +288,6 @@ void Theme::set_default_theme_font(const Ref<Font> &p_default_font) {
}
Ref<Font> Theme::get_default_theme_font() const {
-
return default_theme_font;
}
@@ -327,40 +298,34 @@ Ref<StyleBox> Theme::default_style;
Ref<Font> Theme::default_font;
Ref<Theme> Theme::get_default() {
-
return default_theme;
}
void Theme::set_default(const Ref<Theme> &p_default) {
-
default_theme = p_default;
}
Ref<Theme> Theme::get_project_default() {
-
return project_default_theme;
}
void Theme::set_project_default(const Ref<Theme> &p_project_default) {
-
project_default_theme = p_project_default;
}
void Theme::set_default_icon(const Ref<Texture2D> &p_icon) {
-
default_icon = p_icon;
}
-void Theme::set_default_style(const Ref<StyleBox> &p_style) {
+void Theme::set_default_style(const Ref<StyleBox> &p_style) {
default_style = p_style;
}
-void Theme::set_default_font(const Ref<Font> &p_font) {
+void Theme::set_default_font(const Ref<Font> &p_font) {
default_font = p_font;
}
void Theme::set_icon(const StringName &p_name, const StringName &p_type, const Ref<Texture2D> &p_icon) {
-
//ERR_FAIL_COND(p_icon.is_null());
bool new_value = !icon_map.has(p_type) || !icon_map[p_type].has(p_name);
@@ -380,10 +345,9 @@ void Theme::set_icon(const StringName &p_name, const StringName &p_type, const R
emit_changed();
}
}
-Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_type) const {
+Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_type) const {
if (icon_map.has(p_type) && icon_map[p_type].has(p_name) && icon_map[p_type][p_name].is_valid()) {
-
return icon_map[p_type][p_name];
} else {
return default_icon;
@@ -391,12 +355,10 @@ Ref<Texture2D> Theme::get_icon(const StringName &p_name, const StringName &p_typ
}
bool Theme::has_icon(const StringName &p_name, const StringName &p_type) const {
-
return (icon_map.has(p_type) && icon_map[p_type].has(p_name) && icon_map[p_type][p_name].is_valid());
}
void Theme::clear_icon(const StringName &p_name, const StringName &p_type) {
-
ERR_FAIL_COND(!icon_map.has(p_type));
ERR_FAIL_COND(!icon_map[p_type].has(p_name));
@@ -411,16 +373,15 @@ void Theme::clear_icon(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_icon_list(StringName p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!icon_map.has(p_type))
+ if (!icon_map.has(p_type)) {
return;
+ }
const StringName *key = nullptr;
while ((key = icon_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
@@ -458,22 +419,20 @@ void Theme::clear_shader(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_shader_list(const StringName &p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!shader_map.has(p_type))
+ if (!shader_map.has(p_type)) {
return;
+ }
const StringName *key = nullptr;
while ((key = shader_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
void Theme::set_stylebox(const StringName &p_name, const StringName &p_type, const Ref<StyleBox> &p_style) {
-
//ERR_FAIL_COND(p_style.is_null());
bool new_value = !style_map.has(p_type) || !style_map[p_type].has(p_name);
@@ -488,15 +447,14 @@ void Theme::set_stylebox(const StringName &p_name, const StringName &p_type, con
style_map[p_type][p_name]->connect("changed", callable_mp(this, &Theme::_emit_theme_changed), varray(), CONNECT_REFERENCE_COUNTED);
}
- if (new_value)
+ if (new_value) {
_change_notify();
+ }
emit_changed();
}
Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_type) const {
-
if (style_map.has(p_type) && style_map[p_type].has(p_name) && style_map[p_type][p_name].is_valid()) {
-
return style_map[p_type][p_name];
} else {
return default_style;
@@ -504,12 +462,10 @@ Ref<StyleBox> Theme::get_stylebox(const StringName &p_name, const StringName &p_
}
bool Theme::has_stylebox(const StringName &p_name, const StringName &p_type) const {
-
return (style_map.has(p_type) && style_map[p_type].has(p_name) && style_map[p_type][p_name].is_valid());
}
void Theme::clear_stylebox(const StringName &p_name, const StringName &p_type) {
-
ERR_FAIL_COND(!style_map.has(p_type));
ERR_FAIL_COND(!style_map[p_type].has(p_name));
@@ -524,16 +480,15 @@ void Theme::clear_stylebox(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_stylebox_list(StringName p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!style_map.has(p_type))
+ if (!style_map.has(p_type)) {
return;
+ }
const StringName *key = nullptr;
while ((key = style_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
@@ -548,7 +503,6 @@ void Theme::get_stylebox_types(List<StringName> *p_list) const {
}
void Theme::set_font(const StringName &p_name, const StringName &p_type, const Ref<Font> &p_font) {
-
//ERR_FAIL_COND(p_font.is_null());
bool new_value = !font_map.has(p_type) || !font_map[p_type].has(p_name);
@@ -568,23 +522,22 @@ void Theme::set_font(const StringName &p_name, const StringName &p_type, const R
emit_changed();
}
}
-Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_type) const {
- if (font_map.has(p_type) && font_map[p_type].has(p_name) && font_map[p_type][p_name].is_valid())
+Ref<Font> Theme::get_font(const StringName &p_name, const StringName &p_type) const {
+ if (font_map.has(p_type) && font_map[p_type].has(p_name) && font_map[p_type][p_name].is_valid()) {
return font_map[p_type][p_name];
- else if (default_theme_font.is_valid())
+ } else if (default_theme_font.is_valid()) {
return default_theme_font;
- else
+ } else {
return default_font;
+ }
}
bool Theme::has_font(const StringName &p_name, const StringName &p_type) const {
-
return (font_map.has(p_type) && font_map[p_type].has(p_name) && font_map[p_type][p_name].is_valid());
}
void Theme::clear_font(const StringName &p_name, const StringName &p_type) {
-
ERR_FAIL_COND(!font_map.has(p_type));
ERR_FAIL_COND(!font_map[p_type].has(p_name));
@@ -598,22 +551,20 @@ void Theme::clear_font(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_font_list(StringName p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!font_map.has(p_type))
+ if (!font_map.has(p_type)) {
return;
+ }
const StringName *key = nullptr;
while ((key = font_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
void Theme::set_color(const StringName &p_name, const StringName &p_type, const Color &p_color) {
-
bool new_value = !color_map.has(p_type) || !color_map[p_type].has(p_name);
color_map[p_type][p_name] = p_color;
@@ -625,20 +576,18 @@ void Theme::set_color(const StringName &p_name, const StringName &p_type, const
}
Color Theme::get_color(const StringName &p_name, const StringName &p_type) const {
-
- if (color_map.has(p_type) && color_map[p_type].has(p_name))
+ if (color_map.has(p_type) && color_map[p_type].has(p_name)) {
return color_map[p_type][p_name];
- else
+ } else {
return Color();
+ }
}
bool Theme::has_color(const StringName &p_name, const StringName &p_type) const {
-
return (color_map.has(p_type) && color_map[p_type].has(p_name));
}
void Theme::clear_color(const StringName &p_name, const StringName &p_type) {
-
ERR_FAIL_COND(!color_map.has(p_type));
ERR_FAIL_COND(!color_map[p_type].has(p_name));
@@ -648,22 +597,20 @@ void Theme::clear_color(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_color_list(StringName p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!color_map.has(p_type))
+ if (!color_map.has(p_type)) {
return;
+ }
const StringName *key = nullptr;
while ((key = color_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
void Theme::set_constant(const StringName &p_name, const StringName &p_type, int p_constant) {
-
bool new_value = !constant_map.has(p_type) || !constant_map[p_type].has(p_name);
constant_map[p_type][p_name] = p_constant;
@@ -674,21 +621,18 @@ void Theme::set_constant(const StringName &p_name, const StringName &p_type, int
}
int Theme::get_constant(const StringName &p_name, const StringName &p_type) const {
-
- if (constant_map.has(p_type) && constant_map[p_type].has(p_name))
+ if (constant_map.has(p_type) && constant_map[p_type].has(p_name)) {
return constant_map[p_type][p_name];
- else {
+ } else {
return 0;
}
}
bool Theme::has_constant(const StringName &p_name, const StringName &p_type) const {
-
return (constant_map.has(p_type) && constant_map[p_type].has(p_name));
}
void Theme::clear_constant(const StringName &p_name, const StringName &p_type) {
-
ERR_FAIL_COND(!constant_map.has(p_type));
ERR_FAIL_COND(!constant_map[p_type].has(p_name));
@@ -698,22 +642,20 @@ void Theme::clear_constant(const StringName &p_name, const StringName &p_type) {
}
void Theme::get_constant_list(StringName p_type, List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
- if (!constant_map.has(p_type))
+ if (!constant_map.has(p_type)) {
return;
+ }
const StringName *key = nullptr;
while ((key = constant_map[p_type].next(key))) {
-
p_list->push_back(*key);
}
}
void Theme::clear() {
-
//these need disconnecting
{
const StringName *K = nullptr;
@@ -766,13 +708,11 @@ void Theme::clear() {
}
void Theme::copy_default_theme() {
-
Ref<Theme> default_theme2 = get_default();
copy_theme(default_theme2);
}
void Theme::copy_theme(const Ref<Theme> &p_other) {
-
if (p_other.is_null()) {
clear();
@@ -821,53 +761,45 @@ void Theme::copy_theme(const Ref<Theme> &p_other) {
}
void Theme::get_type_list(List<StringName> *p_list) const {
-
ERR_FAIL_NULL(p_list);
Set<StringName> types;
const StringName *key = nullptr;
while ((key = icon_map.next(key))) {
-
types.insert(*key);
}
key = nullptr;
while ((key = style_map.next(key))) {
-
types.insert(*key);
}
key = nullptr;
while ((key = font_map.next(key))) {
-
types.insert(*key);
}
key = nullptr;
while ((key = color_map.next(key))) {
-
types.insert(*key);
}
key = nullptr;
while ((key = constant_map.next(key))) {
-
types.insert(*key);
}
for (Set<StringName>::Element *E = types.front(); E; E = E->next()) {
-
p_list->push_back(E->get());
}
}
void Theme::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_icon", "name", "type", "texture"), &Theme::set_icon);
ClassDB::bind_method(D_METHOD("get_icon", "name", "type"), &Theme::get_icon);
ClassDB::bind_method(D_METHOD("has_icon", "name", "type"), &Theme::has_icon);
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index d6d724e3f7..3c72ddd8a2 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -39,7 +39,6 @@
#include "scene/resources/texture.h"
class Theme : public Resource {
-
GDCLASS(Theme, Resource);
RES_BASE_EXTENSION("theme");
@@ -54,7 +53,7 @@ class Theme : public Resource {
Vector<String> _get_icon_list(const String &p_type) const;
Vector<String> _get_stylebox_list(const String &p_type) const;
- Vector<String> _get_stylebox_types(void) const;
+ Vector<String> _get_stylebox_types() const;
Vector<String> _get_font_list(const String &p_type) const;
Vector<String> _get_color_list(const String &p_type) const;
Vector<String> _get_constant_list(const String &p_type) const;
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 6f8a53be1a..c17b6f8817 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -33,50 +33,52 @@
#include "core/engine.h"
bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
-
String n = p_name;
int slash = n.find("/");
- if (slash == -1)
+ if (slash == -1) {
return false;
+ }
int id = String::to_int(n.c_str(), slash);
- if (!tile_map.has(id))
+ if (!tile_map.has(id)) {
create_tile(id);
+ }
String what = n.substr(slash + 1, n.length());
- if (what == "name")
+ if (what == "name") {
tile_set_name(id, p_value);
- else if (what == "texture")
+ } else if (what == "texture") {
tile_set_texture(id, p_value);
- else if (what == "normal_map")
+ } else if (what == "normal_map") {
tile_set_normal_map(id, p_value);
- else if (what == "tex_offset")
+ } else if (what == "tex_offset") {
tile_set_texture_offset(id, p_value);
- else if (what == "material")
+ } else if (what == "material") {
tile_set_material(id, p_value);
- else if (what == "modulate")
+ } else if (what == "modulate") {
tile_set_modulate(id, p_value);
- else if (what == "region")
+ } else if (what == "region") {
tile_set_region(id, p_value);
- else if (what == "tile_mode")
+ } else if (what == "tile_mode") {
tile_set_tile_mode(id, (TileMode)((int)p_value));
- else if (what == "is_autotile") {
+ } else if (what == "is_autotile") {
// backward compatibility for Godot 3.0.x
// autotile used to be a bool, it's now an enum
bool is_autotile = p_value;
- if (is_autotile)
+ if (is_autotile) {
tile_set_tile_mode(id, AUTO_TILE);
+ }
} else if (what.left(9) == "autotile/") {
what = what.right(9);
- if (what == "bitmask_mode")
+ if (what == "bitmask_mode") {
autotile_set_bitmask_mode(id, (BitmaskMode)((int)p_value));
- else if (what == "icon_coordinate")
+ } else if (what == "icon_coordinate") {
autotile_set_icon_coordinate(id, p_value);
- else if (what == "tile_size")
+ } else if (what == "tile_size") {
autotile_set_size(id, p_value);
- else if (what == "spacing")
+ } else if (what == "spacing") {
autotile_set_spacing(id, p_value);
- else if (what == "bitmask_flags") {
+ } else if (what == "bitmask_flags") {
tile_map[id].autotile_data.flags.clear();
if (p_value.is_array()) {
Array p = p_value;
@@ -147,7 +149,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
p.pop_front();
}
}
- } else if (what == "shape")
+ } else if (what == "shape") {
if (tile_get_shape_count(id) > 0) {
for (int i = 0; i < tile_get_shape_count(id); i++) {
tile_set_shape(id, i, p_value);
@@ -155,7 +157,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
} else {
tile_set_shape(id, 0, p_value);
}
- else if (what == "shape_offset")
+ } else if (what == "shape_offset") {
if (tile_get_shape_count(id) > 0) {
for (int i = 0; i < tile_get_shape_count(id); i++) {
tile_set_shape_offset(id, i, p_value);
@@ -163,7 +165,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
} else {
tile_set_shape_offset(id, 0, p_value);
}
- else if (what == "shape_transform")
+ } else if (what == "shape_transform") {
if (tile_get_shape_count(id) > 0) {
for (int i = 0; i < tile_get_shape_count(id); i++) {
tile_set_shape_transform(id, i, p_value);
@@ -171,7 +173,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
} else {
tile_set_shape_transform(id, 0, p_value);
}
- else if (what == "shape_one_way")
+ } else if (what == "shape_one_way") {
if (tile_get_shape_count(id) > 0) {
for (int i = 0; i < tile_get_shape_count(id); i++) {
tile_set_shape_one_way(id, i, p_value);
@@ -179,7 +181,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
} else {
tile_set_shape_one_way(id, 0, p_value);
}
- else if (what == "shape_one_way_margin")
+ } else if (what == "shape_one_way_margin") {
if (tile_get_shape_count(id) > 0) {
for (int i = 0; i < tile_get_shape_count(id); i++) {
tile_set_shape_one_way_margin(id, i, p_value);
@@ -187,63 +189,64 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
} else {
tile_set_shape_one_way_margin(id, 0, p_value);
}
- else if (what == "shapes")
+ } else if (what == "shapes") {
_tile_set_shapes(id, p_value);
- else if (what == "occluder")
+ } else if (what == "occluder") {
tile_set_light_occluder(id, p_value);
- else if (what == "occluder_offset")
+ } else if (what == "occluder_offset") {
tile_set_occluder_offset(id, p_value);
- else if (what == "navigation")
+ } else if (what == "navigation") {
tile_set_navigation_polygon(id, p_value);
- else if (what == "navigation_offset")
+ } else if (what == "navigation_offset") {
tile_set_navigation_polygon_offset(id, p_value);
- else if (what == "z_index")
+ } else if (what == "z_index") {
tile_set_z_index(id, p_value);
- else
+ } else {
return false;
+ }
return true;
}
bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
-
String n = p_name;
int slash = n.find("/");
- if (slash == -1)
+ if (slash == -1) {
return false;
+ }
int id = String::to_int(n.c_str(), slash);
ERR_FAIL_COND_V(!tile_map.has(id), false);
String what = n.substr(slash + 1, n.length());
- if (what == "name")
+ if (what == "name") {
r_ret = tile_get_name(id);
- else if (what == "texture")
+ } else if (what == "texture") {
r_ret = tile_get_texture(id);
- else if (what == "normal_map")
+ } else if (what == "normal_map") {
r_ret = tile_get_normal_map(id);
- else if (what == "tex_offset")
+ } else if (what == "tex_offset") {
r_ret = tile_get_texture_offset(id);
- else if (what == "material")
+ } else if (what == "material") {
r_ret = tile_get_material(id);
- else if (what == "modulate")
+ } else if (what == "modulate") {
r_ret = tile_get_modulate(id);
- else if (what == "region")
+ } else if (what == "region") {
r_ret = tile_get_region(id);
- else if (what == "tile_mode")
+ } else if (what == "tile_mode") {
r_ret = tile_get_tile_mode(id);
- else if (what.left(9) == "autotile/") {
+ } else if (what.left(9) == "autotile/") {
what = what.right(9);
- if (what == "bitmask_mode")
+ if (what == "bitmask_mode") {
r_ret = autotile_get_bitmask_mode(id);
- else if (what == "icon_coordinate")
+ } else if (what == "icon_coordinate") {
r_ret = autotile_get_icon_coordinate(id);
- else if (what == "tile_size")
+ } else if (what == "tile_size") {
r_ret = autotile_get_size(id);
- else if (what == "spacing")
+ } else if (what == "spacing") {
r_ret = autotile_get_spacing(id);
- else if (what == "bitmask_flags") {
+ } else if (what == "bitmask_flags") {
Array p;
for (Map<Vector2, uint32_t>::Element *E = tile_map[id].autotile_data.flags.front(); E; E = E->next()) {
p.push_back(E->key());
@@ -291,38 +294,37 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
}
r_ret = p;
}
- } else if (what == "shape")
+ } else if (what == "shape") {
r_ret = tile_get_shape(id, 0);
- else if (what == "shape_offset")
+ } else if (what == "shape_offset") {
r_ret = tile_get_shape_offset(id, 0);
- else if (what == "shape_transform")
+ } else if (what == "shape_transform") {
r_ret = tile_get_shape_transform(id, 0);
- else if (what == "shape_one_way")
+ } else if (what == "shape_one_way") {
r_ret = tile_get_shape_one_way(id, 0);
- else if (what == "shape_one_way_margin")
+ } else if (what == "shape_one_way_margin") {
r_ret = tile_get_shape_one_way_margin(id, 0);
- else if (what == "shapes")
+ } else if (what == "shapes") {
r_ret = _tile_get_shapes(id);
- else if (what == "occluder")
+ } else if (what == "occluder") {
r_ret = tile_get_light_occluder(id);
- else if (what == "occluder_offset")
+ } else if (what == "occluder_offset") {
r_ret = tile_get_occluder_offset(id);
- else if (what == "navigation")
+ } else if (what == "navigation") {
r_ret = tile_get_navigation_polygon(id);
- else if (what == "navigation_offset")
+ } else if (what == "navigation_offset") {
r_ret = tile_get_navigation_polygon_offset(id);
- else if (what == "z_index")
+ } else if (what == "z_index") {
r_ret = tile_get_z_index(id);
- else
+ } else {
return false;
+ }
return true;
}
void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
-
for (Map<int, TileData>::Element *E = tile_map.front(); E; E = E->next()) {
-
int id = E->key();
String pre = itos(id) + "/";
p_list->push_back(PropertyInfo(Variant::STRING, pre + "name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
@@ -382,13 +384,11 @@ void TileSet::autotile_set_bitmask_mode(int p_id, BitmaskMode p_mode) {
}
TileSet::BitmaskMode TileSet::autotile_get_bitmask_mode(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), BITMASK_2X2);
return tile_map[p_id].autotile_data.bitmask_mode;
}
void TileSet::tile_set_texture(int p_id, const Ref<Texture2D> &p_texture) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].texture = p_texture;
emit_changed();
@@ -396,39 +396,33 @@ void TileSet::tile_set_texture(int p_id, const Ref<Texture2D> &p_texture) {
}
Ref<Texture2D> TileSet::tile_get_texture(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture2D>());
return tile_map[p_id].texture;
}
void TileSet::tile_set_normal_map(int p_id, const Ref<Texture2D> &p_normal_map) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].normal_map = p_normal_map;
emit_changed();
}
Ref<Texture2D> TileSet::tile_get_normal_map(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Texture2D>());
return tile_map[p_id].normal_map;
}
void TileSet::tile_set_material(int p_id, const Ref<ShaderMaterial> &p_material) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].material = p_material;
emit_changed();
}
Ref<ShaderMaterial> TileSet::tile_get_material(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<ShaderMaterial>());
return tile_map[p_id].material;
}
void TileSet::tile_set_modulate(int p_id, const Color &p_modulate) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].modulate = p_modulate;
emit_changed();
@@ -436,26 +430,22 @@ void TileSet::tile_set_modulate(int p_id, const Color &p_modulate) {
}
Color TileSet::tile_get_modulate(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Color(1, 1, 1));
return tile_map[p_id].modulate;
}
void TileSet::tile_set_texture_offset(int p_id, const Vector2 &p_offset) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].offset = p_offset;
emit_changed();
}
Vector2 TileSet::tile_get_texture_offset(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
return tile_map[p_id].offset;
}
void TileSet::tile_set_region(int p_id, const Rect2 &p_region) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].region = p_region;
emit_changed();
@@ -463,7 +453,6 @@ void TileSet::tile_set_region(int p_id, const Rect2 &p_region) {
}
Rect2 TileSet::tile_get_region(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Rect2());
return tile_map[p_id].region;
}
@@ -476,26 +465,22 @@ void TileSet::tile_set_tile_mode(int p_id, TileMode p_tile_mode) {
}
TileSet::TileMode TileSet::tile_get_tile_mode(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), SINGLE_TILE);
return tile_map[p_id].tile_mode;
}
void TileSet::autotile_set_icon_coordinate(int p_id, Vector2 coord) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].autotile_data.icon_coord = coord;
emit_changed();
}
Vector2 TileSet::autotile_get_icon_coordinate(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
return tile_map[p_id].autotile_data.icon_coord;
}
void TileSet::autotile_set_spacing(int p_id, int p_spacing) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_spacing < 0);
tile_map[p_id].autotile_data.spacing = p_spacing;
@@ -503,39 +488,33 @@ void TileSet::autotile_set_spacing(int p_id, int p_spacing) {
}
int TileSet::autotile_get_spacing(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
return tile_map[p_id].autotile_data.spacing;
}
void TileSet::autotile_set_size(int p_id, Size2 p_size) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_size.x <= 0 || p_size.y <= 0);
tile_map[p_id].autotile_data.size = p_size;
}
Size2 TileSet::autotile_get_size(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Size2());
return tile_map[p_id].autotile_data.size;
}
void TileSet::autotile_clear_bitmask_map(int p_id) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].autotile_data.flags.clear();
}
void TileSet::autotile_set_subtile_priority(int p_id, const Vector2 &p_coord, int p_priority) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_priority <= 0);
tile_map[p_id].autotile_data.priority_map[p_coord] = p_priority;
}
int TileSet::autotile_get_subtile_priority(int p_id, const Vector2 &p_coord) {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 1);
if (tile_map[p_id].autotile_data.priority_map.has(p_coord)) {
return tile_map[p_id].autotile_data.priority_map[p_coord];
@@ -545,21 +524,18 @@ int TileSet::autotile_get_subtile_priority(int p_id, const Vector2 &p_coord) {
}
const Map<Vector2, int> &TileSet::autotile_get_priority_map(int p_id) const {
-
static Map<Vector2, int> dummy;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
return tile_map[p_id].autotile_data.priority_map;
}
void TileSet::autotile_set_z_index(int p_id, const Vector2 &p_coord, int p_z_index) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].autotile_data.z_index_map[p_coord] = p_z_index;
emit_changed();
}
int TileSet::autotile_get_z_index(int p_id, const Vector2 &p_coord) {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 1);
if (tile_map[p_id].autotile_data.z_index_map.has(p_coord)) {
return tile_map[p_id].autotile_data.z_index_map[p_coord];
@@ -569,25 +545,23 @@ int TileSet::autotile_get_z_index(int p_id, const Vector2 &p_coord) {
}
const Map<Vector2, int> &TileSet::autotile_get_z_index_map(int p_id) const {
-
static Map<Vector2, int> dummy;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
return tile_map[p_id].autotile_data.z_index_map;
}
void TileSet::autotile_set_bitmask(int p_id, Vector2 p_coord, uint32_t p_flag) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
if (p_flag == 0) {
- if (tile_map[p_id].autotile_data.flags.has(p_coord))
+ if (tile_map[p_id].autotile_data.flags.has(p_coord)) {
tile_map[p_id].autotile_data.flags.erase(p_coord);
+ }
} else {
tile_map[p_id].autotile_data.flags[p_coord] = p_flag;
}
}
uint32_t TileSet::autotile_get_bitmask(int p_id, Vector2 p_coord) {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
if (!tile_map[p_id].autotile_data.flags.has(p_coord)) {
return 0;
@@ -596,7 +570,6 @@ uint32_t TileSet::autotile_get_bitmask(int p_id, Vector2 p_coord) {
}
const Map<Vector2, uint32_t> &TileSet::autotile_get_bitmask_map(int p_id) {
-
static Map<Vector2, uint32_t> dummy;
static Map<Vector2, uint32_t> dummy_atlas;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
@@ -611,12 +584,12 @@ const Map<Vector2, uint32_t> &TileSet::autotile_get_bitmask_map(int p_id) {
}
}
return dummy_atlas;
- } else
+ } else {
return tile_map[p_id].autotile_data.flags;
+ }
}
Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node, const Vector2 &p_tile_location) {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
//First try to forward selection to script
if (p_tilemap_node->get_class_name() == "TileMap") {
@@ -678,7 +651,6 @@ Vector2 TileSet::autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask,
}
Vector2 TileSet::atlastile_get_subtile_by_priority(int p_id, const Node *p_tilemap_node, const Vector2 &p_tile_location) {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
//First try to forward selection to script
if (get_script_instance() != nullptr) {
@@ -708,7 +680,6 @@ Vector2 TileSet::atlastile_get_subtile_by_priority(int p_id, const Node *p_tilem
}
void TileSet::tile_set_name(int p_id, const String &p_name) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].name = p_name;
emit_changed();
@@ -716,19 +687,16 @@ void TileSet::tile_set_name(int p_id, const String &p_name) {
}
String TileSet::tile_get_name(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), String());
return tile_map[p_id].name;
}
void TileSet::tile_clear_shapes(int p_id) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].shapes_data.clear();
}
void TileSet::tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transform2D &p_transform, bool p_one_way, const Vector2 &p_autotile_coord) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ShapeData new_data = ShapeData();
@@ -741,52 +709,51 @@ void TileSet::tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transf
}
int TileSet::tile_get_shape_count(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
return tile_map[p_id].shapes_data.size();
}
void TileSet::tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_shape) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_shape_id < 0);
- if (p_shape_id >= tile_map[p_id].shapes_data.size())
+ if (p_shape_id >= tile_map[p_id].shapes_data.size()) {
tile_map[p_id].shapes_data.resize(p_shape_id + 1);
+ }
tile_map[p_id].shapes_data.write[p_shape_id].shape = p_shape;
_decompose_convex_shape(p_shape);
emit_changed();
}
Ref<Shape2D> TileSet::tile_get_shape(int p_id, int p_shape_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Shape2D>());
ERR_FAIL_COND_V(p_shape_id < 0, Ref<Shape2D>());
- if (p_shape_id < tile_map[p_id].shapes_data.size())
+ if (p_shape_id < tile_map[p_id].shapes_data.size()) {
return tile_map[p_id].shapes_data[p_shape_id].shape;
+ }
return Ref<Shape2D>();
}
void TileSet::tile_set_shape_transform(int p_id, int p_shape_id, const Transform2D &p_offset) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_shape_id < 0);
- if (p_shape_id >= tile_map[p_id].shapes_data.size())
+ if (p_shape_id >= tile_map[p_id].shapes_data.size()) {
tile_map[p_id].shapes_data.resize(p_shape_id + 1);
+ }
tile_map[p_id].shapes_data.write[p_shape_id].shape_transform = p_offset;
emit_changed();
}
Transform2D TileSet::tile_get_shape_transform(int p_id, int p_shape_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Transform2D());
ERR_FAIL_COND_V(p_shape_id < 0, Transform2D());
- if (p_shape_id < tile_map[p_id].shapes_data.size())
+ if (p_shape_id < tile_map[p_id].shapes_data.size()) {
return tile_map[p_id].shapes_data[p_shape_id].shape_transform;
+ }
return Transform2D();
}
@@ -802,57 +769,55 @@ Vector2 TileSet::tile_get_shape_offset(int p_id, int p_shape_id) const {
}
void TileSet::tile_set_shape_one_way(int p_id, int p_shape_id, const bool p_one_way) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_shape_id < 0);
- if (p_shape_id >= tile_map[p_id].shapes_data.size())
+ if (p_shape_id >= tile_map[p_id].shapes_data.size()) {
tile_map[p_id].shapes_data.resize(p_shape_id + 1);
+ }
tile_map[p_id].shapes_data.write[p_shape_id].one_way_collision = p_one_way;
emit_changed();
}
bool TileSet::tile_get_shape_one_way(int p_id, int p_shape_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), false);
ERR_FAIL_COND_V(p_shape_id < 0, false);
- if (p_shape_id < tile_map[p_id].shapes_data.size())
+ if (p_shape_id < tile_map[p_id].shapes_data.size()) {
return tile_map[p_id].shapes_data[p_shape_id].one_way_collision;
+ }
return false;
}
void TileSet::tile_set_shape_one_way_margin(int p_id, int p_shape_id, float p_margin) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
ERR_FAIL_COND(p_shape_id < 0);
- if (p_shape_id >= tile_map[p_id].shapes_data.size())
+ if (p_shape_id >= tile_map[p_id].shapes_data.size()) {
tile_map[p_id].shapes_data.resize(p_shape_id + 1);
+ }
tile_map[p_id].shapes_data.write[p_shape_id].one_way_collision_margin = p_margin;
emit_changed();
}
float TileSet::tile_get_shape_one_way_margin(int p_id, int p_shape_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
ERR_FAIL_COND_V(p_shape_id < 0, 0);
- if (p_shape_id < tile_map[p_id].shapes_data.size())
+ if (p_shape_id < tile_map[p_id].shapes_data.size()) {
return tile_map[p_id].shapes_data[p_shape_id].one_way_collision_margin;
+ }
return 0;
}
void TileSet::tile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].occluder = p_light_occluder;
}
Ref<OccluderPolygon2D> TileSet::tile_get_light_occluder(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<OccluderPolygon2D>());
return tile_map[p_id].occluder;
}
@@ -869,7 +834,6 @@ void TileSet::autotile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D>
}
Ref<OccluderPolygon2D> TileSet::autotile_get_light_occluder(int p_id, const Vector2 &p_coord) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<OccluderPolygon2D>());
if (!tile_map[p_id].autotile_data.occluder_map.has(p_coord)) {
@@ -880,38 +844,32 @@ Ref<OccluderPolygon2D> TileSet::autotile_get_light_occluder(int p_id, const Vect
}
void TileSet::tile_set_navigation_polygon_offset(int p_id, const Vector2 &p_offset) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].navigation_polygon_offset = p_offset;
}
Vector2 TileSet::tile_get_navigation_polygon_offset(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
return tile_map[p_id].navigation_polygon_offset;
}
void TileSet::tile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].navigation_polygon = p_navigation_polygon;
}
Ref<NavigationPolygon> TileSet::tile_get_navigation_polygon(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<NavigationPolygon>());
return tile_map[p_id].navigation_polygon;
}
const Map<Vector2, Ref<OccluderPolygon2D>> &TileSet::autotile_get_light_oclusion_map(int p_id) const {
-
static Map<Vector2, Ref<OccluderPolygon2D>> dummy;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
return tile_map[p_id].autotile_data.occluder_map;
}
void TileSet::autotile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon, const Vector2 &p_coord) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
if (p_navigation_polygon.is_null()) {
if (tile_map[p_id].autotile_data.navpoly_map.has(p_coord)) {
@@ -923,7 +881,6 @@ void TileSet::autotile_set_navigation_polygon(int p_id, const Ref<NavigationPoly
}
Ref<NavigationPolygon> TileSet::autotile_get_navigation_polygon(int p_id, const Vector2 &p_coord) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<NavigationPolygon>());
if (!tile_map[p_id].autotile_data.navpoly_map.has(p_coord)) {
return Ref<NavigationPolygon>();
@@ -933,26 +890,22 @@ Ref<NavigationPolygon> TileSet::autotile_get_navigation_polygon(int p_id, const
}
const Map<Vector2, Ref<NavigationPolygon>> &TileSet::autotile_get_navigation_map(int p_id) const {
-
static Map<Vector2, Ref<NavigationPolygon>> dummy;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
return tile_map[p_id].autotile_data.navpoly_map;
}
void TileSet::tile_set_occluder_offset(int p_id, const Vector2 &p_offset) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].occluder_offset = p_offset;
}
Vector2 TileSet::tile_get_occluder_offset(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector2());
return tile_map[p_id].occluder_offset;
}
void TileSet::tile_set_shapes(int p_id, const Vector<ShapeData> &p_shapes) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].shapes_data = p_shapes;
for (int i = 0; i < p_shapes.size(); i++) {
@@ -962,27 +915,23 @@ void TileSet::tile_set_shapes(int p_id, const Vector<ShapeData> &p_shapes) {
}
Vector<TileSet::ShapeData> TileSet::tile_get_shapes(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Vector<ShapeData>());
return tile_map[p_id].shapes_data;
}
int TileSet::tile_get_z_index(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), 0);
return tile_map[p_id].z_index;
}
void TileSet::tile_set_z_index(int p_id, int p_z_index) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map[p_id].z_index = p_z_index;
emit_changed();
}
void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
Vector<ShapeData> shapes_data;
Transform2D default_transform = tile_get_shape_transform(p_id, 0);
@@ -993,7 +942,9 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
if (p_shapes[i].get_type() == Variant::OBJECT) {
Ref<Shape2D> shape = p_shapes[i];
- if (shape.is_null()) continue;
+ if (shape.is_null()) {
+ continue;
+ }
s.shape = shape;
s.shape_transform = default_transform;
@@ -1005,30 +956,35 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
if (d.has("shape") && d["shape"].get_type() == Variant::OBJECT) {
s.shape = d["shape"];
_decompose_convex_shape(s.shape);
- } else
+ } else {
continue;
+ }
- if (d.has("shape_transform") && d["shape_transform"].get_type() == Variant::TRANSFORM2D)
+ if (d.has("shape_transform") && d["shape_transform"].get_type() == Variant::TRANSFORM2D) {
s.shape_transform = d["shape_transform"];
- else if (d.has("shape_offset") && d["shape_offset"].get_type() == Variant::VECTOR2)
+ } else if (d.has("shape_offset") && d["shape_offset"].get_type() == Variant::VECTOR2) {
s.shape_transform = Transform2D(0, (Vector2)d["shape_offset"]);
- else
+ } else {
s.shape_transform = default_transform;
+ }
- if (d.has("one_way") && d["one_way"].get_type() == Variant::BOOL)
+ if (d.has("one_way") && d["one_way"].get_type() == Variant::BOOL) {
s.one_way_collision = d["one_way"];
- else
+ } else {
s.one_way_collision = default_one_way;
+ }
- if (d.has("one_way_margin") && d["one_way_margin"].is_num())
+ if (d.has("one_way_margin") && d["one_way_margin"].is_num()) {
s.one_way_collision_margin = d["one_way_margin"];
- else
+ } else {
s.one_way_collision_margin = 1.0;
+ }
- if (d.has("autotile_coord") && d["autotile_coord"].get_type() == Variant::VECTOR2)
+ if (d.has("autotile_coord") && d["autotile_coord"].get_type() == Variant::VECTOR2) {
s.autotile_coord = d["autotile_coord"];
- else
+ } else {
s.autotile_coord = default_autotile_coord;
+ }
} else {
ERR_CONTINUE_MSG(true, "Expected an array of objects or dictionaries for tile_set_shapes.");
@@ -1042,7 +998,6 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) {
}
Array TileSet::_tile_get_shapes(int p_id) const {
-
ERR_FAIL_COND_V(!tile_map.has(p_id), Array());
Array arr;
@@ -1061,7 +1016,6 @@ Array TileSet::_tile_get_shapes(int p_id) const {
}
Array TileSet::_get_tiles_ids() const {
-
Array arr;
for (Map<int, TileData>::Element *E = tile_map.front(); E; E = E->next()) {
@@ -1072,11 +1026,13 @@ Array TileSet::_get_tiles_ids() const {
}
void TileSet::_decompose_convex_shape(Ref<Shape2D> p_shape) {
- if (Engine::get_singleton()->is_editor_hint())
+ if (Engine::get_singleton()->is_editor_hint()) {
return;
+ }
Ref<ConvexPolygonShape2D> convex = p_shape;
- if (!convex.is_valid())
+ if (!convex.is_valid()) {
return;
+ }
Vector<Vector<Vector2>> decomp = Geometry::decompose_polygon_in_convex(convex->get_points());
if (decomp.size() > 1) {
Array sub_shapes;
@@ -1092,20 +1048,16 @@ void TileSet::_decompose_convex_shape(Ref<Shape2D> p_shape) {
}
void TileSet::get_tile_list(List<int> *p_tiles) const {
-
for (Map<int, TileData>::Element *E = tile_map.front(); E; E = E->next()) {
-
p_tiles->push_back(E->key());
}
}
bool TileSet::has_tile(int p_id) const {
-
return tile_map.has(p_id);
}
bool TileSet::is_tile_bound(int p_drawn_id, int p_neighbor_id) {
-
if (p_drawn_id == p_neighbor_id) {
return true;
} else if (get_script_instance() != nullptr) {
@@ -1120,7 +1072,6 @@ bool TileSet::is_tile_bound(int p_drawn_id, int p_neighbor_id) {
}
void TileSet::remove_tile(int p_id) {
-
ERR_FAIL_COND(!tile_map.has(p_id));
tile_map.erase(p_id);
_change_notify("");
@@ -1128,32 +1079,29 @@ void TileSet::remove_tile(int p_id) {
}
int TileSet::get_last_unused_tile_id() const {
-
- if (tile_map.size())
+ if (tile_map.size()) {
return tile_map.back()->key() + 1;
- else
+ } else {
return 0;
+ }
}
int TileSet::find_tile_by_name(const String &p_name) const {
-
for (Map<int, TileData>::Element *E = tile_map.front(); E; E = E->next()) {
-
- if (p_name == E->get().name)
+ if (p_name == E->get().name) {
return E->key();
+ }
}
return -1;
}
void TileSet::clear() {
-
tile_map.clear();
_change_notify("");
emit_changed();
}
void TileSet::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("create_tile", "id"), &TileSet::create_tile);
ClassDB::bind_method(D_METHOD("autotile_clear_bitmask_map", "id"), &TileSet::autotile_clear_bitmask_map);
ClassDB::bind_method(D_METHOD("autotile_set_icon_coordinate", "id", "coord"), &TileSet::autotile_set_icon_coordinate);
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 05b43dfb89..78f34e46ce 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -40,7 +40,6 @@
#include "scene/resources/texture.h"
class TileSet : public Resource {
-
GDCLASS(TileSet, Resource);
public:
@@ -48,13 +47,10 @@ public:
Ref<Shape2D> shape;
Transform2D shape_transform;
Vector2 autotile_coord;
- bool one_way_collision;
- float one_way_collision_margin;
+ bool one_way_collision = false;
+ float one_way_collision_margin = 1.0;
- ShapeData() {
- one_way_collision = false;
- one_way_collision_margin = 1.0;
- }
+ ShapeData() {}
};
enum BitmaskMode {
@@ -92,27 +88,22 @@ public:
};
struct AutotileData {
- BitmaskMode bitmask_mode;
- Size2 size;
- int spacing;
- Vector2 icon_coord;
+ BitmaskMode bitmask_mode = BITMASK_2X2;
+ // Default size to prevent invalid value
+ Size2 size = Size2(64, 64);
+ Vector2 icon_coord = Vector2(0, 0);
+ int spacing = 0;
Map<Vector2, uint32_t> flags;
Map<Vector2, Ref<OccluderPolygon2D>> occluder_map;
Map<Vector2, Ref<NavigationPolygon>> navpoly_map;
Map<Vector2, int> priority_map;
Map<Vector2, int> z_index_map;
- // Default size to prevent invalid value
- explicit AutotileData() :
- bitmask_mode(BITMASK_2X2),
- size(64, 64),
- spacing(0),
- icon_coord(0, 0) {}
+ explicit AutotileData() {}
};
private:
struct TileData {
-
String name;
Ref<Texture2D> texture;
Ref<Texture2D> normal_map;
@@ -124,16 +115,13 @@ private:
Vector2 navigation_polygon_offset;
Ref<NavigationPolygon> navigation_polygon;
Ref<ShaderMaterial> material;
- TileMode tile_mode;
- Color modulate;
+ TileMode tile_mode = SINGLE_TILE;
+ // Default modulate for back-compat
+ Color modulate = Color(1, 1, 1);
AutotileData autotile_data;
- int z_index;
+ int z_index = 0;
- // Default modulate for back-compat
- explicit TileData() :
- tile_mode(SINGLE_TILE),
- modulate(1, 1, 1),
- z_index(0) {}
+ explicit TileData() {}
};
Map<int, TileData> tile_map;
diff --git a/scene/resources/video_stream.h b/scene/resources/video_stream.h
index a9b96214c3..379ba53a34 100644
--- a/scene/resources/video_stream.h
+++ b/scene/resources/video_stream.h
@@ -34,7 +34,6 @@
#include "scene/resources/texture.h"
class VideoStreamPlayback : public Resource {
-
GDCLASS(VideoStreamPlayback, Resource);
public:
@@ -68,7 +67,6 @@ public:
};
class VideoStream : public Resource {
-
GDCLASS(VideoStream, Resource);
OBJ_SAVE_TYPE(VideoStream); // Saves derived classes with common type so they can be interchanged.
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 310a7ef4e4..77d4dee21e 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -39,12 +39,10 @@ bool VisualShaderNode::is_simple_decl() const {
}
void VisualShaderNode::set_output_port_for_preview(int p_index) {
-
port_preview = p_index;
}
int VisualShaderNode::get_output_port_for_preview() const {
-
return port_preview;
}
@@ -68,6 +66,7 @@ bool VisualShaderNode::is_port_separator(int p_index) const {
Vector<VisualShader::DefaultTextureParam> VisualShaderNode::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const {
return Vector<VisualShader::DefaultTextureParam>();
}
+
String VisualShaderNode::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
return String();
}
@@ -85,7 +84,6 @@ Vector<StringName> VisualShaderNode::get_editable_properties() const {
}
Array VisualShaderNode::get_default_input_values() const {
-
Array ret;
for (Map<int, Variant>::Element *E = default_input_values.front(); E; E = E->next()) {
ret.push_back(E->key());
@@ -93,8 +91,8 @@ Array VisualShaderNode::get_default_input_values() const {
}
return ret;
}
-void VisualShaderNode::set_default_input_values(const Array &p_values) {
+void VisualShaderNode::set_default_input_values(const Array &p_values) {
if (p_values.size() % 2 == 0) {
for (int i = 0; i < p_values.size(); i += 2) {
default_input_values[p_values[i + 0]] = p_values[i + 1];
@@ -113,7 +111,6 @@ String VisualShaderNode::get_input_port_default_hint(int p_port) const {
}
void VisualShaderNode::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_output_port_for_preview", "port"), &VisualShaderNode::set_output_port_for_preview);
ClassDB::bind_method(D_METHOD("get_output_port_for_preview"), &VisualShaderNode::get_output_port_for_preview);
@@ -225,7 +222,6 @@ String VisualShaderNodeCustom::get_output_port_name(int p_port) const {
}
String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
ERR_FAIL_COND_V(!get_script_instance(), "");
ERR_FAIL_COND_V(!get_script_instance()->has_method("_get_code"), "");
Array input_vars;
@@ -264,7 +260,6 @@ String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, Vis
}
void VisualShaderNodeCustom::_bind_methods() {
-
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name"));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_description"));
BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
@@ -396,6 +391,7 @@ Vector<int> VisualShader::get_node_list(Type p_type) const {
return ret;
}
+
int VisualShader::get_valid_node_id(Type p_type) const {
ERR_FAIL_INDEX_V(p_type, TYPE_MAX, NODE_ID_INVALID);
const Graph *g = &graph[p_type];
@@ -404,8 +400,9 @@ int VisualShader::get_valid_node_id(Type p_type) const {
int VisualShader::find_node_id(Type p_type, const Ref<VisualShaderNode> &p_node) const {
for (const Map<int, Node>::Element *E = graph[p_type].nodes.front(); E; E = E->next()) {
- if (E->get().node == p_node)
+ if (E->get().node == p_node) {
return E->key();
+ }
}
return NODE_ID_INVALID;
@@ -445,7 +442,6 @@ bool VisualShader::is_node_connection(Type p_type, int p_from_node, int p_from_p
const Graph *g = &graph[p_type];
for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
-
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
return true;
}
@@ -460,7 +456,6 @@ bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_nod
const VisualShader::Node &node = p_graph->nodes[p_node];
for (const List<int>::Element *E = node.prev_connected_nodes.front(); E; E = E->next()) {
-
if (E->get() == p_target) {
return true;
}
@@ -474,24 +469,28 @@ bool VisualShader::is_nodes_connected_relatively(const Graph *p_graph, int p_nod
}
bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_port, int p_to_node, int p_to_port) const {
-
ERR_FAIL_INDEX_V(p_type, TYPE_MAX, false);
const Graph *g = &graph[p_type];
- if (!g->nodes.has(p_from_node))
+ if (!g->nodes.has(p_from_node)) {
return false;
+ }
- if (p_from_node == p_to_node)
+ if (p_from_node == p_to_node) {
return false;
+ }
- if (p_from_port < 0 || p_from_port >= g->nodes[p_from_node].node->get_output_port_count())
+ if (p_from_port < 0 || p_from_port >= g->nodes[p_from_node].node->get_output_port_count()) {
return false;
+ }
- if (!g->nodes.has(p_to_node))
+ if (!g->nodes.has(p_to_node)) {
return false;
+ }
- if (p_to_port < 0 || p_to_port >= g->nodes[p_to_node].node->get_input_port_count())
+ if (p_to_port < 0 || p_to_port >= g->nodes[p_to_node].node->get_input_port_count()) {
return false;
+ }
VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port);
VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port);
@@ -501,14 +500,14 @@ bool VisualShader::can_connect_nodes(Type p_type, int p_from_node, int p_from_po
}
for (const List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
-
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
return false;
}
}
- if (is_nodes_connected_relatively(g, p_from_node, p_to_node))
+ if (is_nodes_connected_relatively(g, p_from_node, p_to_node)) {
return false;
+ }
return true;
}
@@ -546,7 +545,6 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port,
ERR_FAIL_COND_V_MSG(!is_port_types_compatible(from_port_type, to_port_type), ERR_INVALID_PARAMETER, "Incompatible port types (scalar/vec/bool) with transform.");
for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
-
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
ERR_FAIL_V(ERR_ALREADY_EXISTS);
}
@@ -569,7 +567,6 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por
Graph *g = &graph[p_type];
for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) {
-
if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) {
g->connections.erase(E);
g->nodes[p_to_node].prev_connected_nodes.erase(p_from_node);
@@ -615,9 +612,7 @@ void VisualShader::set_mode(Mode p_mode) {
flags.clear();
shader_mode = p_mode;
for (int i = 0; i < TYPE_MAX; i++) {
-
for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
-
Ref<VisualShaderNodeInput> input = E->get().node;
if (input.is_valid()) {
input->shader_mode = shader_mode;
@@ -630,7 +625,6 @@ void VisualShader::set_mode(Mode p_mode) {
// clear connections since they are no longer valid
for (List<Connection>::Element *E = graph[i].connections.front(); E;) {
-
bool keep = true;
List<Connection>::Element *N = E->next();
@@ -684,7 +678,6 @@ bool VisualShader::is_text_shader() const {
}
String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port, Vector<DefaultTextureParam> &default_tex_params) const {
-
Ref<VisualShaderNode> node = get_node(p_type, p_node);
ERR_FAIL_COND_V(!node.is_valid(), String());
ERR_FAIL_COND_V(p_port < 0 || p_port >= node->get_output_port_count(), String());
@@ -703,7 +696,6 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port
for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
Ref<VisualShaderNodeGlobalExpression> global_expression = Object::cast_to<VisualShaderNodeGlobalExpression>(E->get().node.ptr());
if (global_expression.is_valid()) {
-
String expr = "";
expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n";
expr += global_expression->generate_global(get_mode(), Type(i), -1);
@@ -772,7 +764,6 @@ String VisualShader::validate_port_name(const String &p_name, const List<String>
}
if (name != String()) {
-
String valid_name;
for (int i = 0; i < name.length(); i++) {
@@ -813,13 +804,11 @@ String VisualShader::validate_port_name(const String &p_name, const List<String>
}
String VisualShader::validate_uniform_name(const String &p_name, const Ref<VisualShaderNodeUniform> &p_uniform) const {
-
String name = p_name; //validate name first
while (name.length() && !IS_INITIAL_CHAR(name[0])) {
name = name.substr(1, name.length() - 1);
}
if (name != String()) {
-
String valid_name;
for (int i = 0; i < name.length(); i++) {
@@ -840,7 +829,6 @@ String VisualShader::validate_uniform_name(const String &p_name, const Ref<Visua
int attempt = 1;
while (true) {
-
bool exists = false;
for (int i = 0; i < TYPE_MAX; i++) {
for (const Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
@@ -890,7 +878,6 @@ static const char *type_string[VisualShader::TYPE_MAX] = {
"light"
};
bool VisualShader::_set(const StringName &p_name, const Variant &p_value) {
-
String name = p_name;
if (name == "mode") {
set_mode(Shader::Mode(int(p_value)));
@@ -927,7 +914,6 @@ bool VisualShader::_set(const StringName &p_name, const Variant &p_value) {
String index = name.get_slicec('/', 2);
if (index == "connections") {
-
Vector<int> conns = p_value;
if (conns.size() % 4 == 0) {
for (int i = 0; i < conns.size(); i += 4) {
@@ -964,7 +950,6 @@ bool VisualShader::_set(const StringName &p_name, const Variant &p_value) {
}
bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const {
-
String name = p_name;
if (name == "mode") {
r_ret = get_mode();
@@ -993,7 +978,6 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const {
String index = name.get_slicec('/', 2);
if (index == "connections") {
-
Vector<int> conns;
for (const List<Connection>::Element *E = graph[type].connections.front(); E; E = E->next()) {
conns.push_back(E->get().from_node);
@@ -1074,13 +1058,11 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < TYPE_MAX; i++) {
for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
-
String prop_name = "nodes/";
prop_name += type_string[i];
prop_name += "/" + itos(E->key());
if (E->key() != NODE_ID_OUTPUT) {
-
p_list->push_back(PropertyInfo(Variant::OBJECT, prop_name + "/node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
}
p_list->push_back(PropertyInfo(Variant::VECTOR2, prop_name + "/position", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR));
@@ -1099,7 +1081,6 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const {
}
Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<VisualShader::DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const {
-
const Ref<VisualShaderNode> vsnode = graph[type].nodes[node].node;
//check inputs recursively first
@@ -1116,8 +1097,9 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
}
Error err = _write_node(type, global_code, global_code_per_node, global_code_per_func, code, def_tex_params, input_connections, output_connections, from_node, processed, for_preview, r_classes);
- if (err)
+ if (err) {
return err;
+ }
}
}
@@ -1181,7 +1163,6 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
inputs[i] = "int(" + src_var + ")";
}
} else {
-
Variant defval = vsnode->get_input_port_default_value(i);
if (defval.get_type() == Variant::FLOAT) {
float val = defval;
@@ -1229,11 +1210,21 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
for (int i = 0; i < output_count; i++) {
String var_name = "n_out" + itos(node) + "p" + itos(i);
switch (vsnode->get_output_port_type(i)) {
- case VisualShaderNode::PORT_TYPE_SCALAR: outputs[i] = "float " + var_name; break;
- case VisualShaderNode::PORT_TYPE_SCALAR_INT: outputs[i] = "int " + var_name; break;
- case VisualShaderNode::PORT_TYPE_VECTOR: outputs[i] = "vec3 " + var_name; break;
- case VisualShaderNode::PORT_TYPE_BOOLEAN: outputs[i] = "bool " + var_name; break;
- case VisualShaderNode::PORT_TYPE_TRANSFORM: outputs[i] = "mat4 " + var_name; break;
+ case VisualShaderNode::PORT_TYPE_SCALAR:
+ outputs[i] = "float " + var_name;
+ break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT:
+ outputs[i] = "int " + var_name;
+ break;
+ case VisualShaderNode::PORT_TYPE_VECTOR:
+ outputs[i] = "vec3 " + var_name;
+ break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN:
+ outputs[i] = "bool " + var_name;
+ break;
+ case VisualShaderNode::PORT_TYPE_TRANSFORM:
+ outputs[i] = "mat4 " + var_name;
+ break;
default: {
}
}
@@ -1243,11 +1234,21 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
for (int i = 0; i < output_count; i++) {
outputs[i] = "n_out" + itos(node) + "p" + itos(i);
switch (vsnode->get_output_port_type(i)) {
- case VisualShaderNode::PORT_TYPE_SCALAR: code += String() + "\tfloat " + outputs[i] + ";\n"; break;
- case VisualShaderNode::PORT_TYPE_SCALAR_INT: code += String() + "\tint " + outputs[i] + ";\n"; break;
- case VisualShaderNode::PORT_TYPE_VECTOR: code += String() + "\tvec3 " + outputs[i] + ";\n"; break;
- case VisualShaderNode::PORT_TYPE_BOOLEAN: code += String() + "\tbool " + outputs[i] + ";\n"; break;
- case VisualShaderNode::PORT_TYPE_TRANSFORM: code += String() + "\tmat4 " + outputs[i] + ";\n"; break;
+ case VisualShaderNode::PORT_TYPE_SCALAR:
+ code += String() + "\tfloat " + outputs[i] + ";\n";
+ break;
+ case VisualShaderNode::PORT_TYPE_SCALAR_INT:
+ code += String() + "\tint " + outputs[i] + ";\n";
+ break;
+ case VisualShaderNode::PORT_TYPE_VECTOR:
+ code += String() + "\tvec3 " + outputs[i] + ";\n";
+ break;
+ case VisualShaderNode::PORT_TYPE_BOOLEAN:
+ code += String() + "\tbool " + outputs[i] + ";\n";
+ break;
+ case VisualShaderNode::PORT_TYPE_TRANSFORM:
+ code += String() + "\tmat4 " + outputs[i] + ";\n";
+ break;
default: {
}
}
@@ -1263,7 +1264,6 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
bool skip_global = input.is_valid() && for_preview;
if (!skip_global) {
-
global_code += vsnode->generate_global(get_mode(), type, node);
String class_name = vsnode->get_class_name();
@@ -1288,8 +1288,9 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui
}
void VisualShader::_update_shader() const {
- if (!dirty)
+ if (!dirty) {
return;
+ }
dirty = false;
@@ -1310,11 +1311,8 @@ void VisualShader::_update_shader() const {
//fill render mode enums
int idx = 0;
while (render_mode_enums[idx].string) {
-
if (shader_mode == render_mode_enums[idx].mode) {
-
if (modes.has(render_mode_enums[idx].string)) {
-
int which = modes[render_mode_enums[idx].string];
int count = 0;
for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)).size(); i++) {
@@ -1337,7 +1335,6 @@ void VisualShader::_update_shader() const {
//fill render mode flags
for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)).size(); i++) {
-
String mode = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode))[i];
if (flags.has(mode)) {
if (render_mode != String()) {
@@ -1349,7 +1346,6 @@ void VisualShader::_update_shader() const {
}
if (render_mode != String()) {
-
global_code += "render_mode " + render_mode + ";\n\n";
}
@@ -1357,7 +1353,6 @@ void VisualShader::_update_shader() const {
String global_expressions;
for (int i = 0, index = 0; i < TYPE_MAX; i++) {
-
if (!ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader_mode)).has(func_name[i])) {
continue;
}
@@ -1365,7 +1360,6 @@ void VisualShader::_update_shader() const {
for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) {
Ref<VisualShaderNodeGlobalExpression> global_expression = Object::cast_to<VisualShaderNodeGlobalExpression>(E->get().node.ptr());
if (global_expression.is_valid()) {
-
String expr = "";
expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n";
expr += global_expression->generate_global(get_mode(), Type(i), -1);
@@ -1377,7 +1371,6 @@ void VisualShader::_update_shader() const {
}
for (int i = 0; i < TYPE_MAX; i++) {
-
if (!ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader_mode)).has(func_name[i])) {
continue;
}
@@ -1463,7 +1456,6 @@ void VisualShader::rebuild() {
}
void VisualShader::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_mode", "mode"), &VisualShader::set_mode);
ClassDB::bind_method(D_METHOD("add_node", "type", "node", "position", "id"), &VisualShader::add_node);
@@ -1630,9 +1622,11 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = {
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_vec", "vec3(LIGHT_VEC, 0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_height", "LIGHT_HEIGHT" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_color", "LIGHT_COLOR.rgb" },
- { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_alpha", "LIGHT_COLOR.a" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT_COLOR.a" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_uv", "vec3(LIGHT_UV, 0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_color", "SHADOW_COLOR.rgb" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "shadow_alpha", "SHADOW_COLOR.a" },
+ { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_vec", "vec3(SHADOW_VEC, 0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" },
{ Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD, 0.0)" },
@@ -1740,26 +1734,25 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = {
};
int VisualShaderNodeInput::get_input_port_count() const {
-
return 0;
}
-VisualShaderNodeInput::PortType VisualShaderNodeInput::get_input_port_type(int p_port) const {
+VisualShaderNodeInput::PortType VisualShaderNodeInput::get_input_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
-String VisualShaderNodeInput::get_input_port_name(int p_port) const {
+String VisualShaderNodeInput::get_input_port_name(int p_port) const {
return "";
}
int VisualShaderNodeInput::get_output_port_count() const {
-
return 1;
}
-VisualShaderNodeInput::PortType VisualShaderNodeInput::get_output_port_type(int p_port) const {
+VisualShaderNodeInput::PortType VisualShaderNodeInput::get_output_port_type(int p_port) const {
return get_input_type_by_name(input_name);
}
+
String VisualShaderNodeInput::get_output_port_name(int p_port) const {
return "";
}
@@ -1769,7 +1762,6 @@ String VisualShaderNodeInput::get_caption() const {
}
String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
if (get_output_port_type(0) == PORT_TYPE_SAMPLER) {
return "";
}
@@ -1846,7 +1838,6 @@ String VisualShaderNodeInput::get_input_name() const {
}
String VisualShaderNodeInput::get_input_real_name() const {
-
int idx = 0;
while (ports[idx].mode != Shader::MODE_MAX) {
@@ -1860,7 +1851,6 @@ String VisualShaderNodeInput::get_input_real_name() const {
}
VisualShaderNodeInput::PortType VisualShaderNodeInput::get_input_type_by_name(String p_name) const {
-
int idx = 0;
while (ports[idx].mode != Shader::MODE_MAX) {
@@ -1922,7 +1912,6 @@ String VisualShaderNodeInput::get_input_index_name(int p_index) const {
}
void VisualShaderNodeInput::_validate_property(PropertyInfo &property) const {
-
if (property.name == "input_name") {
String port_list;
@@ -1952,7 +1941,6 @@ Vector<StringName> VisualShaderNodeInput::get_editable_properties() const {
}
void VisualShaderNodeInput::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_input_name", "name"), &VisualShaderNodeInput::set_input_name);
ClassDB::bind_method(D_METHOD("get_input_name"), &VisualShaderNodeInput::get_input_name);
ClassDB::bind_method(D_METHOD("get_input_real_name"), &VisualShaderNodeInput::get_input_real_name);
@@ -1960,6 +1948,7 @@ void VisualShaderNodeInput::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "input_name", PROPERTY_HINT_ENUM, ""), "set_input_name", "get_input_name");
ADD_SIGNAL(MethodInfo("input_type_changed"));
}
+
VisualShaderNodeInput::VisualShaderNodeInput() {
input_name = "[None]";
// changed when set
@@ -2038,7 +2027,6 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = {
};
int VisualShaderNodeOutput::get_input_port_count() const {
-
int idx = 0;
int count = 0;
@@ -2053,7 +2041,6 @@ int VisualShaderNodeOutput::get_input_port_count() const {
}
VisualShaderNodeOutput::PortType VisualShaderNodeOutput::get_input_port_type(int p_port) const {
-
int idx = 0;
int count = 0;
@@ -2071,7 +2058,6 @@ VisualShaderNodeOutput::PortType VisualShaderNodeOutput::get_input_port_type(int
}
String VisualShaderNodeOutput::get_input_port_name(int p_port) const {
-
int idx = 0;
int count = 0;
@@ -2093,18 +2079,18 @@ Variant VisualShaderNodeOutput::get_input_port_default_value(int p_port) const {
}
int VisualShaderNodeOutput::get_output_port_count() const {
-
return 0;
}
+
VisualShaderNodeOutput::PortType VisualShaderNodeOutput::get_output_port_type(int p_port) const {
return PORT_TYPE_SCALAR;
}
+
String VisualShaderNodeOutput::get_output_port_name(int p_port) const {
return String();
}
bool VisualShaderNodeOutput::is_port_separator(int p_index) const {
-
if (shader_mode == Shader::MODE_SPATIAL && shader_type == VisualShader::TYPE_FRAGMENT) {
String name = get_input_port_name(p_index);
return (name == "Normal" || name == "Rim" || name == "Alpha Scissor");
@@ -2117,14 +2103,12 @@ String VisualShaderNodeOutput::get_caption() const {
}
String VisualShaderNodeOutput::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
int idx = 0;
int count = 0;
String code;
while (ports[idx].mode != Shader::MODE_MAX) {
if (ports[idx].mode == shader_mode && ports[idx].shader_type == shader_type) {
-
if (p_input_vars[count] != String()) {
String s = ports[idx].string;
if (s.find(":") != -1) {
@@ -2156,26 +2140,65 @@ String VisualShaderNodeUniform::get_uniform_name() const {
return uniform_name;
}
-void VisualShaderNodeUniform::_bind_methods() {
+void VisualShaderNodeUniform::set_qualifier(VisualShaderNodeUniform::Qualifier p_qual) {
+ qualifier = p_qual;
+ emit_changed();
+}
+
+VisualShaderNodeUniform::Qualifier VisualShaderNodeUniform::get_qualifier() const {
+ return qualifier;
+}
+void VisualShaderNodeUniform::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniform::set_uniform_name);
ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniform::get_uniform_name);
+ ClassDB::bind_method(D_METHOD("set_qualifier", "qualifier"), &VisualShaderNodeUniform::set_qualifier);
+ ClassDB::bind_method(D_METHOD("get_qualifier"), &VisualShaderNodeUniform::get_qualifier);
+
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name"), "set_uniform_name", "get_uniform_name");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "qualifier", PROPERTY_HINT_ENUM, "None,Global,Instance"), "set_qualifier", "get_qualifier");
+
+ BIND_ENUM_CONSTANT(QUAL_NONE);
+ BIND_ENUM_CONSTANT(QUAL_GLOBAL);
+ BIND_ENUM_CONSTANT(QUAL_INSTANCE);
}
-String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
+String VisualShaderNodeUniform::_get_qual_str() const {
+ if (is_qualifier_supported(qualifier)) {
+ switch (qualifier) {
+ case QUAL_NONE:
+ break;
+ case QUAL_GLOBAL:
+ return "global ";
+ case QUAL_INSTANCE:
+ return "instance ";
+ }
+ }
+ return String();
+}
+String VisualShaderNodeUniform::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
List<String> keyword_list;
ShaderLanguage::get_keyword_list(&keyword_list);
if (keyword_list.find(uniform_name)) {
return TTR("Uniform name cannot be equal to a shader keyword. Choose another name.");
}
+ if (!is_qualifier_supported(qualifier)) {
+ return "This uniform type does not support that qualifier.";
+ }
return String();
}
+Vector<StringName> VisualShaderNodeUniform::get_editable_properties() const {
+ Vector<StringName> props;
+ props.push_back("qualifier");
+ return props;
+}
+
VisualShaderNodeUniform::VisualShaderNodeUniform() {
+ qualifier = QUAL_NONE;
}
////////////// GroupBase
@@ -2193,9 +2216,9 @@ Vector2 VisualShaderNodeGroupBase::get_size() const {
}
void VisualShaderNodeGroupBase::set_inputs(const String &p_inputs) {
-
- if (inputs == p_inputs)
+ if (inputs == p_inputs) {
return;
+ }
clear_input_ports();
@@ -2206,7 +2229,6 @@ void VisualShaderNodeGroupBase::set_inputs(const String &p_inputs) {
int input_port_count = input_strings.size();
for (int i = 0; i < input_port_count; i++) {
-
Vector<String> arr = input_strings[i].split(",");
ERR_FAIL_COND(arr.size() != 3);
@@ -2226,9 +2248,9 @@ String VisualShaderNodeGroupBase::get_inputs() const {
}
void VisualShaderNodeGroupBase::set_outputs(const String &p_outputs) {
-
- if (outputs == p_outputs)
+ if (outputs == p_outputs) {
return;
+ }
clear_output_ports();
@@ -2239,7 +2261,6 @@ void VisualShaderNodeGroupBase::set_outputs(const String &p_outputs) {
int output_port_count = output_strings.size();
for (int i = 0; i < output_port_count; i++) {
-
Vector<String> arr = output_strings[i].split(",");
ERR_FAIL_COND(arr.size() != 3);
@@ -2276,7 +2297,6 @@ bool VisualShaderNodeGroupBase::is_valid_port_name(const String &p_name) const {
}
void VisualShaderNodeGroupBase::add_input_port(int p_id, int p_type, const String &p_name) {
-
String str = itos(p_id) + "," + itos(p_type) + "," + p_name + ";";
Vector<String> inputs_strings = inputs.split(";", false);
int index = 0;
@@ -2313,7 +2333,6 @@ void VisualShaderNodeGroupBase::add_input_port(int p_id, int p_type, const Strin
}
void VisualShaderNodeGroupBase::remove_input_port(int p_id) {
-
ERR_FAIL_COND(!has_input_port(p_id));
Vector<String> inputs_strings = inputs.split(";", false);
@@ -2346,7 +2365,6 @@ bool VisualShaderNodeGroupBase::has_input_port(int p_id) const {
}
void VisualShaderNodeGroupBase::add_output_port(int p_id, int p_type, const String &p_name) {
-
String str = itos(p_id) + "," + itos(p_type) + "," + p_name + ";";
Vector<String> outputs_strings = outputs.split(";", false);
int index = 0;
@@ -2383,7 +2401,6 @@ void VisualShaderNodeGroupBase::add_output_port(int p_id, int p_type, const Stri
}
void VisualShaderNodeGroupBase::remove_output_port(int p_id) {
-
ERR_FAIL_COND(!has_output_port(p_id));
Vector<String> outputs_strings = outputs.split(";", false);
@@ -2424,12 +2441,12 @@ void VisualShaderNodeGroupBase::clear_output_ports() {
}
void VisualShaderNodeGroupBase::set_input_port_type(int p_id, int p_type) {
-
ERR_FAIL_COND(!has_input_port(p_id));
ERR_FAIL_COND(p_type < 0 || p_type >= PORT_TYPE_MAX);
- if (input_ports[p_id].type == p_type)
+ if (input_ports[p_id].type == p_type) {
return;
+ }
Vector<String> inputs_strings = inputs.split(";", false);
int count = 0;
@@ -2459,12 +2476,12 @@ VisualShaderNodeGroupBase::PortType VisualShaderNodeGroupBase::get_input_port_ty
}
void VisualShaderNodeGroupBase::set_input_port_name(int p_id, const String &p_name) {
-
ERR_FAIL_COND(!has_input_port(p_id));
ERR_FAIL_COND(!is_valid_port_name(p_name));
- if (input_ports[p_id].name == p_name)
+ if (input_ports[p_id].name == p_name) {
return;
+ }
Vector<String> inputs_strings = inputs.split(";", false);
int count = 0;
@@ -2494,12 +2511,12 @@ String VisualShaderNodeGroupBase::get_input_port_name(int p_id) const {
}
void VisualShaderNodeGroupBase::set_output_port_type(int p_id, int p_type) {
-
ERR_FAIL_COND(!has_output_port(p_id));
ERR_FAIL_COND(p_type < 0 || p_type >= PORT_TYPE_MAX);
- if (output_ports[p_id].type == p_type)
+ if (output_ports[p_id].type == p_type) {
return;
+ }
Vector<String> output_strings = outputs.split(";", false);
int count = 0;
@@ -2529,12 +2546,12 @@ VisualShaderNodeGroupBase::PortType VisualShaderNodeGroupBase::get_output_port_t
}
void VisualShaderNodeGroupBase::set_output_port_name(int p_id, const String &p_name) {
-
ERR_FAIL_COND(!has_output_port(p_id));
ERR_FAIL_COND(!is_valid_port_name(p_name));
- if (output_ports[p_id].name == p_name)
+ if (output_ports[p_id].name == p_name) {
return;
+ }
Vector<String> output_strings = outputs.split(";", false);
int count = 0;
@@ -2581,7 +2598,6 @@ Control *VisualShaderNodeGroupBase::get_control(int p_index) {
}
void VisualShaderNodeGroupBase::_apply_port_changes() {
-
Vector<String> inputs_strings = inputs.split(";", false);
Vector<String> outputs_strings = outputs.split(";", false);
@@ -2617,7 +2633,6 @@ bool VisualShaderNodeGroupBase::is_editable() const {
}
void VisualShaderNodeGroupBase::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_size", "size"), &VisualShaderNodeGroupBase::set_size);
ClassDB::bind_method(D_METHOD("get_size"), &VisualShaderNodeGroupBase::get_size);
@@ -2679,7 +2694,6 @@ String VisualShaderNodeExpression::get_expression() const {
}
String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String _expression = expression;
_expression = _expression.insert(0, "\n");
@@ -2779,7 +2793,6 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad
}
void VisualShaderNodeExpression::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_expression", "expression"), &VisualShaderNodeExpression::set_expression);
ClassDB::bind_method(D_METHOD("get_expression"), &VisualShaderNodeExpression::get_expression);
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index ecf3f93fbb..8bd09df512 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -98,7 +98,6 @@ private:
void _queue_update();
union ConnectionKey {
-
struct {
uint64_t node : 32;
uint64_t port : 32;
@@ -369,21 +368,38 @@ public:
class VisualShaderNodeUniform : public VisualShaderNode {
GDCLASS(VisualShaderNodeUniform, VisualShaderNode);
+public:
+ enum Qualifier {
+ QUAL_NONE,
+ QUAL_GLOBAL,
+ QUAL_INSTANCE,
+ };
+
private:
String uniform_name;
+ Qualifier qualifier;
protected:
static void _bind_methods();
+ String _get_qual_str() const;
public:
void set_uniform_name(const String &p_name);
String get_uniform_name() const;
+ void set_qualifier(Qualifier p_qual);
+ Qualifier get_qualifier() const;
+
+ virtual bool is_qualifier_supported(Qualifier p_qual) const = 0;
+
+ virtual Vector<StringName> get_editable_properties() const;
virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const;
VisualShaderNodeUniform();
};
+VARIANT_ENUM_CAST(VisualShaderNodeUniform::Qualifier)
+
class VisualShaderNodeGroupBase : public VisualShaderNode {
GDCLASS(VisualShaderNodeGroupBase, VisualShaderNode);
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 2064ca10f3..87720cf110 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -65,13 +65,11 @@ String VisualShaderNodeFloatConstant::generate_code(Shader::Mode p_mode, VisualS
}
void VisualShaderNodeFloatConstant::set_constant(float p_value) {
-
constant = p_value;
emit_changed();
}
float VisualShaderNodeFloatConstant::get_constant() const {
-
return constant;
}
@@ -82,7 +80,6 @@ Vector<StringName> VisualShaderNodeFloatConstant::get_editable_properties() cons
}
void VisualShaderNodeFloatConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeFloatConstant::set_constant);
ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeFloatConstant::get_constant);
@@ -143,7 +140,6 @@ Vector<StringName> VisualShaderNodeIntConstant::get_editable_properties() const
}
void VisualShaderNodeIntConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeIntConstant::set_constant);
ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeIntConstant::get_constant);
@@ -204,7 +200,6 @@ Vector<StringName> VisualShaderNodeBooleanConstant::get_editable_properties() co
}
void VisualShaderNodeBooleanConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeBooleanConstant::set_constant);
ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeBooleanConstant::get_constant);
@@ -246,7 +241,6 @@ String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const {
}
String VisualShaderNodeColorConstant::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code;
code += "\t" + p_output_vars[0] + " = " + vformat("vec3(%.6f, %.6f, %.6f)", constant.r, constant.g, constant.b) + ";\n";
code += "\t" + p_output_vars[1] + " = " + vformat("%.6f", constant.a) + ";\n";
@@ -255,13 +249,11 @@ String VisualShaderNodeColorConstant::generate_code(Shader::Mode p_mode, VisualS
}
void VisualShaderNodeColorConstant::set_constant(Color p_value) {
-
constant = p_value;
emit_changed();
}
Color VisualShaderNodeColorConstant::get_constant() const {
-
return constant;
}
@@ -272,7 +264,6 @@ Vector<StringName> VisualShaderNodeColorConstant::get_editable_properties() cons
}
void VisualShaderNodeColorConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeColorConstant::set_constant);
ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeColorConstant::get_constant);
@@ -318,13 +309,11 @@ String VisualShaderNodeVec3Constant::generate_code(Shader::Mode p_mode, VisualSh
}
void VisualShaderNodeVec3Constant::set_constant(Vector3 p_value) {
-
constant = p_value;
emit_changed();
}
Vector3 VisualShaderNodeVec3Constant::get_constant() const {
-
return constant;
}
@@ -335,7 +324,6 @@ Vector<StringName> VisualShaderNodeVec3Constant::get_editable_properties() const
}
void VisualShaderNodeVec3Constant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeVec3Constant::set_constant);
ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeVec3Constant::get_constant);
@@ -388,13 +376,11 @@ String VisualShaderNodeTransformConstant::generate_code(Shader::Mode p_mode, Vis
}
void VisualShaderNodeTransformConstant::set_constant(Transform p_value) {
-
constant = p_value;
emit_changed();
}
Transform VisualShaderNodeTransformConstant::get_constant() const {
-
return constant;
}
@@ -405,7 +391,6 @@ Vector<StringName> VisualShaderNodeTransformConstant::get_editable_properties()
}
void VisualShaderNodeTransformConstant::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_constant", "value"), &VisualShaderNodeTransformConstant::set_constant);
ClassDB::bind_method(D_METHOD("get_constant"), &VisualShaderNodeTransformConstant::get_constant);
@@ -426,7 +411,6 @@ int VisualShaderNodeTexture::get_input_port_count() const {
}
VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(int p_port) const {
-
switch (p_port) {
case 0:
return PORT_TYPE_VECTOR;
@@ -440,7 +424,6 @@ VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(i
}
String VisualShaderNodeTexture::get_input_port_name(int p_port) const {
-
switch (p_port) {
case 0:
return "uv";
@@ -458,14 +441,16 @@ int VisualShaderNodeTexture::get_output_port_count() const {
}
VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_output_port_type(int p_port) const {
- if (p_port == 0 && source == SOURCE_DEPTH)
+ if (p_port == 0 && source == SOURCE_DEPTH) {
return PORT_TYPE_SCALAR;
+ }
return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR;
}
String VisualShaderNodeTexture::get_output_port_name(int p_port) const {
- if (p_port == 0 && source == SOURCE_DEPTH)
+ if (p_port == 0 && source == SOURCE_DEPTH) {
return "depth";
+ }
return p_port == 0 ? "rgb" : "alpha";
}
@@ -477,7 +462,6 @@ String VisualShaderNodeTexture::get_input_port_default_hint(int p_port) const {
}
static String make_unique_id(VisualShader::Type p_type, int p_id, const String &p_name) {
-
static const char *typepf[VisualShader::TYPE_MAX] = { "vtx", "frg", "lgt" };
return p_name + "_" + String(typepf[p_type]) + "_" + itos(p_id);
}
@@ -492,14 +476,17 @@ Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture::get_default_t
}
String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-
if (source == SOURCE_TEXTURE) {
-
String u = "uniform sampler2D " + make_unique_id(p_type, p_id, "tex");
switch (texture_type) {
- case TYPE_DATA: break;
- case TYPE_COLOR: u += " : hint_albedo"; break;
- case TYPE_NORMALMAP: u += " : hint_normal"; break;
+ case TYPE_DATA:
+ break;
+ case TYPE_COLOR:
+ u += " : hint_albedo";
+ break;
+ case TYPE_NORMALMAP:
+ u += " : hint_normal";
+ break;
}
return u + ";\n";
}
@@ -508,7 +495,6 @@ String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShade
}
String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
if (source == SOURCE_TEXTURE) {
String id = make_unique_id(p_type, p_id, "tex");
String code;
@@ -563,7 +549,6 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
}
if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
-
String code = "\t{\n";
if (p_input_vars[0] == String() || p_for_preview) { // Use UV by default.
@@ -587,7 +572,6 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
}
if (source == SOURCE_2D_TEXTURE && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
-
String code = "\t{\n";
if (p_input_vars[0] == String()) { // Use UV by default.
@@ -611,7 +595,6 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
}
if (source == SOURCE_2D_NORMAL && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
-
String code = "\t{\n";
if (p_input_vars[0] == String()) { // Use UV by default.
@@ -645,7 +628,6 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader:
}
if (source == SOURCE_DEPTH && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
-
String code = "\t{\n";
if (p_input_vars[0] == String()) { // Use UV by default.
@@ -711,13 +693,11 @@ VisualShaderNodeTexture::Source VisualShaderNodeTexture::get_source() const {
}
void VisualShaderNodeTexture::set_texture(Ref<Texture2D> p_value) {
-
texture = p_value;
emit_changed();
}
Ref<Texture2D> VisualShaderNodeTexture::get_texture() const {
-
return texture;
}
@@ -741,7 +721,6 @@ Vector<StringName> VisualShaderNodeTexture::get_editable_properties() const {
}
String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
-
if (source == SOURCE_TEXTURE) {
return String(); // all good
}
@@ -751,22 +730,18 @@ String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::T
}
if (source == SOURCE_SCREEN && (p_mode == Shader::MODE_SPATIAL || p_mode == Shader::MODE_CANVAS_ITEM) && p_type == VisualShader::TYPE_FRAGMENT) {
-
return String(); // all good
}
if (source == SOURCE_2D_TEXTURE && p_mode == Shader::MODE_CANVAS_ITEM && p_type == VisualShader::TYPE_FRAGMENT) {
-
return String(); // all good
}
if (source == SOURCE_2D_NORMAL && p_mode == Shader::MODE_CANVAS_ITEM) {
-
return String(); // all good
}
if (source == SOURCE_DEPTH && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) {
-
if (get_output_port_for_preview() == 0) { // DEPTH_TEXTURE is not supported in preview(canvas_item) shader
return TTR("Invalid source for preview.");
}
@@ -777,7 +752,6 @@ String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::T
}
void VisualShaderNodeTexture::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeTexture::set_source);
ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeTexture::get_source);
@@ -865,13 +839,17 @@ Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubemap::get_default_t
}
String VisualShaderNodeCubemap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-
if (source == SOURCE_TEXTURE) {
String u = "uniform samplerCube " + make_unique_id(p_type, p_id, "cube");
switch (texture_type) {
- case TYPE_DATA: break;
- case TYPE_COLOR: u += " : hint_albedo"; break;
- case TYPE_NORMALMAP: u += " : hint_normal"; break;
+ case TYPE_DATA:
+ break;
+ case TYPE_COLOR:
+ u += " : hint_albedo";
+ break;
+ case TYPE_NORMALMAP:
+ u += " : hint_normal";
+ break;
}
return u + ";\n";
}
@@ -879,7 +857,6 @@ String VisualShaderNodeCubemap::generate_global(Shader::Mode p_mode, VisualShade
}
String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code;
String id;
if (source == SOURCE_TEXTURE) {
@@ -939,13 +916,11 @@ VisualShaderNodeCubemap::Source VisualShaderNodeCubemap::get_source() const {
}
void VisualShaderNodeCubemap::set_cube_map(Ref<Cubemap> p_value) {
-
cube_map = p_value;
emit_changed();
}
Ref<Cubemap> VisualShaderNodeCubemap::get_cube_map() const {
-
return cube_map;
}
@@ -969,7 +944,6 @@ Vector<StringName> VisualShaderNodeCubemap::get_editable_properties() const {
}
void VisualShaderNodeCubemap::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeCubemap::set_source);
ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeCubemap::get_source);
@@ -1028,33 +1002,49 @@ String VisualShaderNodeFloatOp::get_output_port_name(int p_port) const {
}
String VisualShaderNodeFloatOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code = "\t" + p_output_vars[0] + " = ";
switch (op) {
-
- case OP_ADD: code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n"; break;
- case OP_SUB: code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; break;
- case OP_MUL: code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; break;
- case OP_DIV: code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; break;
- case OP_MOD: code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_POW: code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_MAX: code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_MIN: code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_ATAN2: code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_STEP: code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
+ case OP_ADD:
+ code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n";
+ break;
+ case OP_SUB:
+ code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MUL:
+ code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
+ break;
+ case OP_DIV:
+ code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MOD:
+ code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_POW:
+ code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_MAX:
+ code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_MIN:
+ code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_ATAN2:
+ code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_STEP:
+ code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
}
return code;
}
void VisualShaderNodeFloatOp::set_operator(Operator p_op) {
-
op = p_op;
emit_changed();
}
VisualShaderNodeFloatOp::Operator VisualShaderNodeFloatOp::get_operator() const {
-
return op;
}
@@ -1065,7 +1055,6 @@ Vector<StringName> VisualShaderNodeFloatOp::get_editable_properties() const {
}
void VisualShaderNodeFloatOp::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeFloatOp::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeFloatOp::get_operator);
@@ -1120,24 +1109,35 @@ String VisualShaderNodeIntOp::get_output_port_name(int p_port) const {
}
String VisualShaderNodeIntOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code = "\t" + p_output_vars[0] + " = ";
switch (op) {
-
- case OP_ADD: code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n"; break;
- case OP_SUB: code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; break;
- case OP_MUL: code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; break;
- case OP_DIV: code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; break;
- case OP_MOD: code += p_input_vars[0] + " % " + p_input_vars[1] + ";\n"; break;
- case OP_MAX: code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_MIN: code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
+ case OP_ADD:
+ code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n";
+ break;
+ case OP_SUB:
+ code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MUL:
+ code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
+ break;
+ case OP_DIV:
+ code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MOD:
+ code += p_input_vars[0] + " % " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MAX:
+ code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_MIN:
+ code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
}
return code;
}
void VisualShaderNodeIntOp::set_operator(Operator p_op) {
-
op = p_op;
emit_changed();
}
@@ -1153,7 +1153,6 @@ Vector<StringName> VisualShaderNodeIntOp::get_editable_properties() const {
}
void VisualShaderNodeIntOp::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeIntOp::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeIntOp::get_operator);
@@ -1205,35 +1204,55 @@ String VisualShaderNodeVectorOp::get_output_port_name(int p_port) const {
}
String VisualShaderNodeVectorOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code = "\t" + p_output_vars[0] + " = ";
switch (op) {
-
- case OP_ADD: code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n"; break;
- case OP_SUB: code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n"; break;
- case OP_MUL: code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n"; break;
- case OP_DIV: code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n"; break;
- case OP_MOD: code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_POW: code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_MAX: code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_MIN: code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_CROSS: code += "cross(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_ATAN2: code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_REFLECT: code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
- case OP_STEP: code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; break;
+ case OP_ADD:
+ code += p_input_vars[0] + " + " + p_input_vars[1] + ";\n";
+ break;
+ case OP_SUB:
+ code += p_input_vars[0] + " - " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MUL:
+ code += p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
+ break;
+ case OP_DIV:
+ code += p_input_vars[0] + " / " + p_input_vars[1] + ";\n";
+ break;
+ case OP_MOD:
+ code += "mod(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_POW:
+ code += "pow(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_MAX:
+ code += "max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_MIN:
+ code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_CROSS:
+ code += "cross(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_ATAN2:
+ code += "atan(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_REFLECT:
+ code += "reflect(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
+ case OP_STEP:
+ code += "step(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
+ break;
}
return code;
}
void VisualShaderNodeVectorOp::set_operator(Operator p_op) {
-
op = p_op;
emit_changed();
}
VisualShaderNodeVectorOp::Operator VisualShaderNodeVectorOp::get_operator() const {
-
return op;
}
@@ -1244,7 +1263,6 @@ Vector<StringName> VisualShaderNodeVectorOp::get_editable_properties() const {
}
void VisualShaderNodeVectorOp::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeVectorOp::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeVectorOp::get_operator);
@@ -1301,29 +1319,23 @@ String VisualShaderNodeColorOp::get_output_port_name(int p_port) const {
}
String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code;
static const char *axisn[3] = { "x", "y", "z" };
switch (op) {
case OP_SCREEN: {
-
code += "\t" + p_output_vars[0] + " = vec3(1.0) - (vec3(1.0) - " + p_input_vars[0] + ") * (vec3(1.0) - " + p_input_vars[1] + ");\n";
} break;
case OP_DIFFERENCE: {
-
code += "\t" + p_output_vars[0] + " = abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ");\n";
} break;
case OP_DARKEN: {
-
code += "\t" + p_output_vars[0] + " = min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
} break;
case OP_LIGHTEN: {
-
code += "\t" + p_output_vars[0] + " = max(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
} break;
case OP_OVERLAY: {
-
for (int i = 0; i < 3; i++) {
code += "\t{\n";
code += "\t\tfloat base = " + p_input_vars[0] + "." + axisn[i] + ";\n";
@@ -1338,16 +1350,13 @@ String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader:
} break;
case OP_DODGE: {
-
code += "\t" + p_output_vars[0] + " = (" + p_input_vars[0] + ") / (vec3(1.0) - " + p_input_vars[1] + ");\n";
} break;
case OP_BURN: {
-
code += "\t" + p_output_vars[0] + " = vec3(1.0) - (vec3(1.0) - " + p_input_vars[0] + ") / (" + p_input_vars[1] + ");\n";
} break;
case OP_SOFT_LIGHT: {
-
for (int i = 0; i < 3; i++) {
code += "\t{\n";
code += "\t\tfloat base = " + p_input_vars[0] + "." + axisn[i] + ";\n";
@@ -1362,7 +1371,6 @@ String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader:
} break;
case OP_HARD_LIGHT: {
-
for (int i = 0; i < 3; i++) {
code += "\t{\n";
code += "\t\tfloat base = " + p_input_vars[0] + "." + axisn[i] + ";\n";
@@ -1382,7 +1390,6 @@ String VisualShaderNodeColorOp::generate_code(Shader::Mode p_mode, VisualShader:
}
void VisualShaderNodeColorOp::set_operator(Operator p_op) {
-
op = p_op;
switch (op) {
case OP_SCREEN:
@@ -1417,7 +1424,6 @@ void VisualShaderNodeColorOp::set_operator(Operator p_op) {
}
VisualShaderNodeColorOp::Operator VisualShaderNodeColorOp::get_operator() const {
-
return op;
}
@@ -1428,7 +1434,6 @@ Vector<StringName> VisualShaderNodeColorOp::get_editable_properties() const {
}
void VisualShaderNodeColorOp::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeColorOp::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeColorOp::get_operator);
@@ -1482,7 +1487,6 @@ String VisualShaderNodeTransformMult::get_output_port_name(int p_port) const {
}
String VisualShaderNodeTransformMult::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
if (op == OP_AxB) {
return "\t" + p_output_vars[0] + " = " + p_input_vars[0] + " * " + p_input_vars[1] + ";\n";
} else if (op == OP_BxA) {
@@ -1495,13 +1499,11 @@ String VisualShaderNodeTransformMult::generate_code(Shader::Mode p_mode, VisualS
}
void VisualShaderNodeTransformMult::set_operator(Operator p_op) {
-
op = p_op;
emit_changed();
}
VisualShaderNodeTransformMult::Operator VisualShaderNodeTransformMult::get_operator() const {
-
return op;
}
@@ -1512,7 +1514,6 @@ Vector<StringName> VisualShaderNodeTransformMult::get_editable_properties() cons
}
void VisualShaderNodeTransformMult::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeTransformMult::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeTransformMult::get_operator);
@@ -1573,13 +1574,11 @@ String VisualShaderNodeTransformVecMult::generate_code(Shader::Mode p_mode, Visu
}
void VisualShaderNodeTransformVecMult::set_operator(Operator p_op) {
-
op = p_op;
emit_changed();
}
VisualShaderNodeTransformVecMult::Operator VisualShaderNodeTransformVecMult::get_operator() const {
-
return op;
}
@@ -1590,7 +1589,6 @@ Vector<StringName> VisualShaderNodeTransformVecMult::get_editable_properties() c
}
void VisualShaderNodeTransformVecMult::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeTransformVecMult::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeTransformVecMult::get_operator);
@@ -1639,7 +1637,6 @@ String VisualShaderNodeFloatFunc::get_output_port_name(int p_port) const {
}
String VisualShaderNodeFloatFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *scalar_func_id[FUNC_ONEMINUS + 1] = {
"sin($)",
"cos($)",
@@ -1679,13 +1676,11 @@ String VisualShaderNodeFloatFunc::generate_code(Shader::Mode p_mode, VisualShade
}
void VisualShaderNodeFloatFunc::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeFloatFunc::Function VisualShaderNodeFloatFunc::get_function() const {
-
return func;
}
@@ -1696,7 +1691,6 @@ Vector<StringName> VisualShaderNodeFloatFunc::get_editable_properties() const {
}
void VisualShaderNodeFloatFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeFloatFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeFloatFunc::get_function);
@@ -1810,7 +1804,6 @@ void VisualShaderNodeIntFunc::set_function(Function p_func) {
}
VisualShaderNodeIntFunc::Function VisualShaderNodeIntFunc::get_function() const {
-
return func;
}
@@ -1821,7 +1814,6 @@ Vector<StringName> VisualShaderNodeIntFunc::get_editable_properties() const {
}
void VisualShaderNodeIntFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function);
@@ -1869,7 +1861,6 @@ String VisualShaderNodeVectorFunc::get_output_port_name(int p_port) const {
}
String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *vec_func_id[FUNC_ONEMINUS + 1] = {
"normalize($)",
"max(min($, vec3(1.0)), vec3(0.0))",
@@ -1936,7 +1927,6 @@ String VisualShaderNodeVectorFunc::generate_code(Shader::Mode p_mode, VisualShad
}
void VisualShaderNodeVectorFunc::set_function(Function p_func) {
-
func = p_func;
if (func == FUNC_RGB2HSV) {
simple_decl = false;
@@ -1949,7 +1939,6 @@ void VisualShaderNodeVectorFunc::set_function(Function p_func) {
}
VisualShaderNodeVectorFunc::Function VisualShaderNodeVectorFunc::get_function() const {
-
return func;
}
@@ -1960,7 +1949,6 @@ Vector<StringName> VisualShaderNodeVectorFunc::get_editable_properties() const {
}
void VisualShaderNodeVectorFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeVectorFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeVectorFunc::get_function);
@@ -2039,7 +2027,6 @@ String VisualShaderNodeColorFunc::get_output_port_name(int p_port) const {
}
String VisualShaderNodeColorFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code;
switch (func) {
@@ -2067,13 +2054,11 @@ String VisualShaderNodeColorFunc::generate_code(Shader::Mode p_mode, VisualShade
}
void VisualShaderNodeColorFunc::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeColorFunc::Function VisualShaderNodeColorFunc::get_function() const {
-
return func;
}
@@ -2084,7 +2069,6 @@ Vector<StringName> VisualShaderNodeColorFunc::get_editable_properties() const {
}
void VisualShaderNodeColorFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeColorFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeColorFunc::get_function);
@@ -2131,7 +2115,6 @@ String VisualShaderNodeTransformFunc::get_output_port_name(int p_port) const {
}
String VisualShaderNodeTransformFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *funcs[FUNC_TRANSPOSE + 1] = {
"inverse($)",
"transpose($)"
@@ -2143,13 +2126,11 @@ String VisualShaderNodeTransformFunc::generate_code(Shader::Mode p_mode, VisualS
}
void VisualShaderNodeTransformFunc::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeTransformFunc::Function VisualShaderNodeTransformFunc::get_function() const {
-
return func;
}
@@ -2160,7 +2141,6 @@ Vector<StringName> VisualShaderNodeTransformFunc::get_editable_properties() cons
}
void VisualShaderNodeTransformFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeTransformFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeTransformFunc::get_function);
@@ -2321,7 +2301,6 @@ String VisualShaderNodeScalarDerivativeFunc::get_output_port_name(int p_port) co
}
String VisualShaderNodeScalarDerivativeFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *funcs[FUNC_Y + 1] = {
"fwidth($)",
"dFdx($)",
@@ -2334,13 +2313,11 @@ String VisualShaderNodeScalarDerivativeFunc::generate_code(Shader::Mode p_mode,
}
void VisualShaderNodeScalarDerivativeFunc::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeScalarDerivativeFunc::Function VisualShaderNodeScalarDerivativeFunc::get_function() const {
-
return func;
}
@@ -2351,7 +2328,6 @@ Vector<StringName> VisualShaderNodeScalarDerivativeFunc::get_editable_properties
}
void VisualShaderNodeScalarDerivativeFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeScalarDerivativeFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeScalarDerivativeFunc::get_function);
@@ -2398,7 +2374,6 @@ String VisualShaderNodeVectorDerivativeFunc::get_output_port_name(int p_port) co
}
String VisualShaderNodeVectorDerivativeFunc::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *funcs[FUNC_Y + 1] = {
"fwidth($)",
"dFdx($)",
@@ -2411,13 +2386,11 @@ String VisualShaderNodeVectorDerivativeFunc::generate_code(Shader::Mode p_mode,
}
void VisualShaderNodeVectorDerivativeFunc::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeVectorDerivativeFunc::Function VisualShaderNodeVectorDerivativeFunc::get_function() const {
-
return func;
}
@@ -2428,7 +2401,6 @@ Vector<StringName> VisualShaderNodeVectorDerivativeFunc::get_editable_properties
}
void VisualShaderNodeVectorDerivativeFunc::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeVectorDerivativeFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeVectorDerivativeFunc::get_function);
@@ -2459,12 +2431,13 @@ VisualShaderNodeScalarClamp::PortType VisualShaderNodeScalarClamp::get_input_por
}
String VisualShaderNodeScalarClamp::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "min";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "max";
+ }
return "";
}
@@ -2505,12 +2478,13 @@ VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorClamp::get_input_por
}
String VisualShaderNodeVectorClamp::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "min";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "max";
+ }
return "";
}
@@ -2649,10 +2623,11 @@ VisualShaderNodeVectorScalarStep::PortType VisualShaderNodeVectorScalarStep::get
}
String VisualShaderNodeVectorScalarStep::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "edge";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "x";
+ }
return "";
}
@@ -2692,12 +2667,13 @@ VisualShaderNodeScalarSmoothStep::PortType VisualShaderNodeScalarSmoothStep::get
}
String VisualShaderNodeScalarSmoothStep::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "edge0";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "edge1";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "x";
+ }
return "";
}
@@ -2738,12 +2714,13 @@ VisualShaderNodeVectorSmoothStep::PortType VisualShaderNodeVectorSmoothStep::get
}
String VisualShaderNodeVectorSmoothStep::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "edge0";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "edge1";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "x";
+ }
return "";
}
@@ -2789,12 +2766,13 @@ VisualShaderNodeVectorScalarSmoothStep::PortType VisualShaderNodeVectorScalarSmo
}
String VisualShaderNodeVectorScalarSmoothStep::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "edge0";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "edge1";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "x";
+ }
return "";
}
@@ -2875,7 +2853,6 @@ int VisualShaderNodeVectorRefract::get_input_port_count() const {
}
VisualShaderNodeVectorRefract::PortType VisualShaderNodeVectorRefract::get_input_port_type(int p_port) const {
-
if (p_port == 2) {
return PORT_TYPE_SCALAR;
}
@@ -3019,8 +2996,9 @@ int VisualShaderNodeVectorScalarMix::get_input_port_count() const {
}
VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_input_port_type(int p_port) const {
- if (p_port == 2)
+ if (p_port == 2) {
return PORT_TYPE_SCALAR;
+ }
return PORT_TYPE_VECTOR;
}
@@ -3097,7 +3075,6 @@ String VisualShaderNodeVectorCompose::generate_code(Shader::Mode p_mode, VisualS
}
VisualShaderNodeVectorCompose::VisualShaderNodeVectorCompose() {
-
set_input_port_default_value(0, 0.0);
set_input_port_default_value(1, 0.0);
set_input_port_default_value(2, 0.0);
@@ -3146,7 +3123,6 @@ String VisualShaderNodeTransformCompose::generate_code(Shader::Mode p_mode, Visu
}
VisualShaderNodeTransformCompose::VisualShaderNodeTransformCompose() {
-
set_input_port_default_value(0, Vector3());
set_input_port_default_value(1, Vector3());
set_input_port_default_value(2, Vector3());
@@ -3283,11 +3259,11 @@ String VisualShaderNodeFloatUniform::get_output_port_name(int p_port) const {
String VisualShaderNodeFloatUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
if (hint == HINT_RANGE) {
- return "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n";
+ return _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n";
} else if (hint == HINT_RANGE_STEP) {
- return "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n";
+ return _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n";
}
- return "uniform float " + get_uniform_name() + ";\n";
+ return _get_qual_str() + "uniform float " + get_uniform_name() + ";\n";
}
String VisualShaderNodeFloatUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
@@ -3353,8 +3329,12 @@ void VisualShaderNodeFloatUniform::_bind_methods() {
BIND_ENUM_CONSTANT(HINT_RANGE_STEP);
}
+bool VisualShaderNodeFloatUniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const {
- Vector<StringName> props;
+ Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
props.push_back("hint");
if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) {
props.push_back("min");
@@ -3405,11 +3385,11 @@ String VisualShaderNodeIntUniform::get_output_port_name(int p_port) const {
String VisualShaderNodeIntUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
if (hint == HINT_RANGE) {
- return "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n";
+ return _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n";
} else if (hint == HINT_RANGE_STEP) {
- return "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n";
+ return _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n";
}
- return "uniform int " + get_uniform_name() + ";\n";
+ return _get_qual_str() + "uniform int " + get_uniform_name() + ";\n";
}
String VisualShaderNodeIntUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
@@ -3475,8 +3455,12 @@ void VisualShaderNodeIntUniform::_bind_methods() {
BIND_ENUM_CONSTANT(HINT_RANGE_STEP);
}
+bool VisualShaderNodeIntUniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const {
- Vector<StringName> props;
+ Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
props.push_back("hint");
if (hint == HINT_RANGE || hint == HINT_RANGE_STEP) {
props.push_back("min");
@@ -3526,13 +3510,17 @@ String VisualShaderNodeBooleanUniform::get_output_port_name(int p_port) const {
}
String VisualShaderNodeBooleanUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- return "uniform bool " + get_uniform_name() + ";\n";
+ return _get_qual_str() + "uniform bool " + get_uniform_name() + ";\n";
}
String VisualShaderNodeBooleanUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
+bool VisualShaderNodeBooleanUniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
VisualShaderNodeBooleanUniform::VisualShaderNodeBooleanUniform() {
}
@@ -3567,8 +3555,7 @@ String VisualShaderNodeColorUniform::get_output_port_name(int p_port) const {
}
String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-
- return "uniform vec4 " + get_uniform_name() + " : hint_color;\n";
+ return _get_qual_str() + "uniform vec4 " + get_uniform_name() + " : hint_color;\n";
}
String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
@@ -3577,6 +3564,10 @@ String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualSh
return code;
}
+bool VisualShaderNodeColorUniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() {
}
@@ -3611,13 +3602,17 @@ String VisualShaderNodeVec3Uniform::get_output_port_name(int p_port) const {
}
String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- return "uniform vec3 " + get_uniform_name() + ";\n";
+ return _get_qual_str() + "uniform vec3 " + get_uniform_name() + ";\n";
}
String VisualShaderNodeVec3Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
+bool VisualShaderNodeVec3Uniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
VisualShaderNodeVec3Uniform::VisualShaderNodeVec3Uniform() {
}
@@ -3652,13 +3647,17 @@ String VisualShaderNodeTransformUniform::get_output_port_name(int p_port) const
}
String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- return "uniform mat4 " + get_uniform_name() + ";\n";
+ return _get_qual_str() + "uniform mat4 " + get_uniform_name() + ";\n";
}
String VisualShaderNodeTransformUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n";
}
+bool VisualShaderNodeTransformUniform::is_qualifier_supported(Qualifier p_qual) const {
+ return true; // all qualifiers are supported
+}
+
VisualShaderNodeTransformUniform::VisualShaderNodeTransformUniform() {
}
@@ -3685,7 +3684,6 @@ int VisualShaderNodeTextureUniform::get_output_port_count() const {
}
VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_output_port_type(int p_port) const {
-
switch (p_port) {
case 0:
return PORT_TYPE_VECTOR;
@@ -3699,7 +3697,6 @@ VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_out
}
String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const {
-
switch (p_port) {
case 0:
return "rgb";
@@ -3713,30 +3710,35 @@ String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const {
}
String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- String code = "uniform sampler2D " + get_uniform_name();
+ String code = _get_qual_str() + "uniform sampler2D " + get_uniform_name();
switch (texture_type) {
case TYPE_DATA:
- if (color_default == COLOR_DEFAULT_BLACK)
+ if (color_default == COLOR_DEFAULT_BLACK) {
code += " : hint_black;\n";
- else
+ } else {
code += ";\n";
+ }
break;
case TYPE_COLOR:
- if (color_default == COLOR_DEFAULT_BLACK)
+ if (color_default == COLOR_DEFAULT_BLACK) {
code += " : hint_black_albedo;\n";
- else
+ } else {
code += " : hint_albedo;\n";
+ }
+ break;
+ case TYPE_NORMALMAP:
+ code += " : hint_normal;\n";
+ break;
+ case TYPE_ANISO:
+ code += " : hint_aniso;\n";
break;
- case TYPE_NORMALMAP: code += " : hint_normal;\n"; break;
- case TYPE_ANISO: code += " : hint_aniso;\n"; break;
}
return code;
}
String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String id = get_uniform_name();
String code = "\t{\n";
if (p_input_vars[0] == String()) { // Use UV by default.
@@ -3759,7 +3761,6 @@ String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, Visual
}
void VisualShaderNodeTextureUniform::set_texture_type(TextureType p_type) {
-
texture_type = p_type;
emit_changed();
}
@@ -3778,7 +3779,7 @@ VisualShaderNodeTextureUniform::ColorDefault VisualShaderNodeTextureUniform::get
}
Vector<StringName> VisualShaderNodeTextureUniform::get_editable_properties() const {
- Vector<StringName> props;
+ Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
props.push_back("texture_type");
props.push_back("color_default");
return props;
@@ -3810,6 +3811,18 @@ String VisualShaderNodeTextureUniform::get_input_port_default_hint(int p_port) c
return "";
}
+bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) const {
+ switch (p_qual) {
+ case Qualifier::QUAL_NONE:
+ return true;
+ case Qualifier::QUAL_GLOBAL:
+ return true;
+ case Qualifier::QUAL_INSTANCE:
+ return false;
+ }
+ return false;
+}
+
VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() {
texture_type = TYPE_DATA;
color_default = COLOR_DEFAULT_WHITE;
@@ -3845,7 +3858,6 @@ String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port)
}
String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-
String code;
code += "// TRIPLANAR FUNCTION GLOBAL CODE\n";
@@ -3868,11 +3880,9 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader:
}
String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
-
String code;
if (p_type == VisualShader::TYPE_VERTEX) {
-
code += "\t// TRIPLANAR FUNCTION VERTEX CODE\n";
code += "\t\ttriplanar_power_normal = pow(abs(NORMAL), vec3(triplanar_sharpness));\n";
code += "\t\ttriplanar_power_normal /= dot(triplanar_power_normal, vec3(1.0));\n";
@@ -3884,7 +3894,6 @@ String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader:
}
String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String id = get_uniform_name();
String code = "\t{\n";
@@ -3952,23 +3961,29 @@ String VisualShaderNodeCubemapUniform::get_input_port_default_hint(int p_port) c
}
String VisualShaderNodeCubemapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- String code = "uniform samplerCube " + get_uniform_name();
+ String code = _get_qual_str() + "uniform samplerCube " + get_uniform_name();
switch (texture_type) {
case TYPE_DATA:
- if (color_default == COLOR_DEFAULT_BLACK)
+ if (color_default == COLOR_DEFAULT_BLACK) {
code += " : hint_black;\n";
- else
+ } else {
code += ";\n";
+ }
break;
case TYPE_COLOR:
- if (color_default == COLOR_DEFAULT_BLACK)
+ if (color_default == COLOR_DEFAULT_BLACK) {
code += " : hint_black_albedo;\n";
- else
+ } else {
code += " : hint_albedo;\n";
+ }
+ break;
+ case TYPE_NORMALMAP:
+ code += " : hint_normal;\n";
+ break;
+ case TYPE_ANISO:
+ code += " : hint_aniso;\n";
break;
- case TYPE_NORMALMAP: code += " : hint_normal;\n"; break;
- case TYPE_ANISO: code += " : hint_aniso;\n"; break;
}
return code;
@@ -4030,7 +4045,6 @@ String VisualShaderNodeIf::get_output_port_name(int p_port) const {
}
String VisualShaderNodeIf::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code;
code += "\tif(abs(" + p_input_vars[0] + " - " + p_input_vars[1] + ") < " + p_input_vars[2] + ")\n"; // abs(a - b) < tolerance eg. a == b
code += "\t{\n";
@@ -4100,7 +4114,6 @@ String VisualShaderNodeSwitch::get_output_port_name(int p_port) const {
}
String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String code;
code += "\tif(" + p_input_vars[0] + ")\n";
code += "\t{\n";
@@ -4196,7 +4209,6 @@ String VisualShaderNodeFresnel::get_output_port_name(int p_port) const {
}
String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
String normal;
String view;
if (p_input_vars[0] == String()) {
@@ -4230,42 +4242,34 @@ VisualShaderNodeFresnel::VisualShaderNodeFresnel() {
////////////// Is
String VisualShaderNodeIs::get_caption() const {
-
return "Is";
}
int VisualShaderNodeIs::get_input_port_count() const {
-
return 1;
}
VisualShaderNodeIs::PortType VisualShaderNodeIs::get_input_port_type(int p_port) const {
-
return PORT_TYPE_SCALAR;
}
String VisualShaderNodeIs::get_input_port_name(int p_port) const {
-
return "";
}
int VisualShaderNodeIs::get_output_port_count() const {
-
return 1;
}
VisualShaderNodeIs::PortType VisualShaderNodeIs::get_output_port_type(int p_port) const {
-
return PORT_TYPE_BOOLEAN;
}
String VisualShaderNodeIs::get_output_port_name(int p_port) const {
-
return "";
}
String VisualShaderNodeIs::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *funcs[FUNC_IS_NAN + 1] = {
"isinf($)",
"isnan($)"
@@ -4277,25 +4281,21 @@ String VisualShaderNodeIs::generate_code(Shader::Mode p_mode, VisualShader::Type
}
void VisualShaderNodeIs::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeIs::Function VisualShaderNodeIs::get_function() const {
-
return func;
}
Vector<StringName> VisualShaderNodeIs::get_editable_properties() const {
-
Vector<StringName> props;
props.push_back("function");
return props;
}
void VisualShaderNodeIs::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIs::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIs::get_function);
@@ -4306,7 +4306,6 @@ void VisualShaderNodeIs::_bind_methods() {
}
VisualShaderNodeIs::VisualShaderNodeIs() {
-
func = FUNC_IS_INF;
set_input_port_default_value(0, 0.0);
}
@@ -4314,12 +4313,10 @@ VisualShaderNodeIs::VisualShaderNodeIs() {
////////////// Compare
String VisualShaderNodeCompare::get_caption() const {
-
return "Compare";
}
int VisualShaderNodeCompare::get_input_port_count() const {
-
if (ctype == CTYPE_SCALAR && (func == FUNC_EQUAL || func == FUNC_NOT_EQUAL)) {
return 3;
}
@@ -4327,9 +4324,9 @@ int VisualShaderNodeCompare::get_input_port_count() const {
}
VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(int p_port) const {
-
- if (p_port == 2)
+ if (p_port == 2) {
return PORT_TYPE_SCALAR;
+ }
switch (ctype) {
case CTYPE_SCALAR:
return PORT_TYPE_SCALAR;
@@ -4346,12 +4343,13 @@ VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(i
}
String VisualShaderNodeCompare::get_input_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "a";
- else if (p_port == 1)
+ } else if (p_port == 1) {
return "b";
- else if (p_port == 2)
+ } else if (p_port == 2) {
return "tolerance";
+ }
return "";
}
@@ -4364,13 +4362,13 @@ VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_output_port_type(
}
String VisualShaderNodeCompare::get_output_port_name(int p_port) const {
- if (p_port == 0)
+ if (p_port == 0) {
return "result";
+ }
return "";
}
String VisualShaderNodeCompare::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const {
-
if (ctype == CTYPE_BOOLEAN || ctype == CTYPE_TRANSFORM) {
if (func > FUNC_NOT_EQUAL) {
return TTR("Invalid comparison function for that type.");
@@ -4381,7 +4379,6 @@ String VisualShaderNodeCompare::get_warning(Shader::Mode p_mode, VisualShader::T
}
String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
-
static const char *ops[FUNC_LESS_THAN_EQUAL + 1] = {
"==",
"!=",
@@ -4429,14 +4426,16 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader:
break;
case CTYPE_BOOLEAN:
- if (func > FUNC_NOT_EQUAL)
+ if (func > FUNC_NOT_EQUAL) {
return "\t" + p_output_vars[0] + " = false;\n";
+ }
code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n";
break;
case CTYPE_TRANSFORM:
- if (func > FUNC_NOT_EQUAL)
+ if (func > FUNC_NOT_EQUAL) {
return "\t" + p_output_vars[0] + " = false;\n";
+ }
code += "\t" + p_output_vars[0] + " = " + (p_input_vars[0] + " $ " + p_input_vars[1]).replace("$", ops[func]) + ";\n";
break;
@@ -4447,7 +4446,6 @@ String VisualShaderNodeCompare::generate_code(Shader::Mode p_mode, VisualShader:
}
void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_type) {
-
ctype = p_type;
switch (ctype) {
@@ -4481,29 +4479,24 @@ void VisualShaderNodeCompare::set_comparison_type(ComparisonType p_type) {
}
VisualShaderNodeCompare::ComparisonType VisualShaderNodeCompare::get_comparison_type() const {
-
return ctype;
}
void VisualShaderNodeCompare::set_function(Function p_func) {
-
func = p_func;
emit_changed();
}
VisualShaderNodeCompare::Function VisualShaderNodeCompare::get_function() const {
-
return func;
}
void VisualShaderNodeCompare::set_condition(Condition p_cond) {
-
condition = p_cond;
emit_changed();
}
VisualShaderNodeCompare::Condition VisualShaderNodeCompare::get_condition() const {
-
return condition;
}
@@ -4511,13 +4504,13 @@ Vector<StringName> VisualShaderNodeCompare::get_editable_properties() const {
Vector<StringName> props;
props.push_back("type");
props.push_back("function");
- if (ctype == CTYPE_VECTOR)
+ if (ctype == CTYPE_VECTOR) {
props.push_back("condition");
+ }
return props;
}
void VisualShaderNodeCompare::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_comparison_type", "type"), &VisualShaderNodeCompare::set_comparison_type);
ClassDB::bind_method(D_METHOD("get_comparison_type"), &VisualShaderNodeCompare::get_comparison_type);
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 035e39230c..69f42f621a 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -1457,6 +1457,8 @@ public:
void set_step(float p_value);
float get_step() const;
+ bool is_qualifier_supported(Qualifier p_qual) const;
+
virtual Vector<StringName> get_editable_properties() const;
VisualShaderNodeFloatUniform();
@@ -1509,6 +1511,8 @@ public:
void set_step(int p_value);
int get_step() const;
+ bool is_qualifier_supported(Qualifier p_qual) const;
+
virtual Vector<StringName> get_editable_properties() const;
VisualShaderNodeIntUniform();
@@ -1535,6 +1539,8 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ bool is_qualifier_supported(Qualifier p_qual) const;
+
VisualShaderNodeBooleanUniform();
};
@@ -1557,6 +1563,8 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ bool is_qualifier_supported(Qualifier p_qual) const;
+
VisualShaderNodeColorUniform();
};
@@ -1579,6 +1587,8 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ bool is_qualifier_supported(Qualifier p_qual) const;
+
VisualShaderNodeVec3Uniform();
};
@@ -1601,6 +1611,8 @@ public:
virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const;
virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty
+ bool is_qualifier_supported(Qualifier p_qual) const;
+
VisualShaderNodeTransformUniform();
};
@@ -1652,6 +1664,8 @@ public:
void set_color_default(ColorDefault p_default);
ColorDefault get_color_default() const;
+ bool is_qualifier_supported(Qualifier p_qual) const;
+
VisualShaderNodeTextureUniform();
};
diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp
index 742ef106d9..1c753fdb91 100644
--- a/scene/resources/world_2d.cpp
+++ b/scene/resources/world_2d.cpp
@@ -38,9 +38,7 @@
#include "servers/rendering_server.h"
struct SpatialIndexer2D {
-
struct CellRef {
-
int ref;
_FORCE_INLINE_ int inc() {
@@ -58,7 +56,6 @@ struct SpatialIndexer2D {
};
struct CellKey {
-
union {
struct {
int32_t x;
@@ -74,7 +71,6 @@ struct SpatialIndexer2D {
};
struct CellData {
-
Map<VisibilityNotifier2D *, CellRef> notifiers;
};
@@ -84,7 +80,6 @@ struct SpatialIndexer2D {
Map<VisibilityNotifier2D *, Rect2> notifiers;
struct ViewportData {
-
Map<VisibilityNotifier2D *, uint64_t> notifiers;
Rect2 rect;
};
@@ -96,30 +91,25 @@ struct SpatialIndexer2D {
uint64_t pass;
void _notifier_update_cells(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect, bool p_add) {
-
Point2i begin = p_rect.position;
begin /= cell_size;
Point2i end = p_rect.position + p_rect.size;
end /= cell_size;
for (int i = begin.x; i <= end.x; i++) {
-
for (int j = begin.y; j <= end.y; j++) {
-
CellKey ck;
ck.x = i;
ck.y = j;
Map<CellKey, CellData>::Element *E = cells.find(ck);
if (p_add) {
-
- if (!E)
+ if (!E) {
E = cells.insert(ck, CellData());
+ }
E->get().notifiers[p_notifier].inc();
} else {
-
ERR_CONTINUE(!E);
if (E->get().notifiers[p_notifier].dec() == 0) {
-
E->get().notifiers.erase(p_notifier);
if (E->get().notifiers.empty()) {
cells.erase(E);
@@ -131,7 +121,6 @@ struct SpatialIndexer2D {
}
void _notifier_add(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect) {
-
ERR_FAIL_COND(notifiers.has(p_notifier));
notifiers[p_notifier] = p_rect;
_notifier_update_cells(p_notifier, p_rect, true);
@@ -139,11 +128,11 @@ struct SpatialIndexer2D {
}
void _notifier_update(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect) {
-
Map<VisibilityNotifier2D *, Rect2>::Element *E = notifiers.find(p_notifier);
ERR_FAIL_COND(!E);
- if (E->get() == p_rect)
+ if (E->get() == p_rect) {
return;
+ }
_notifier_update_cells(p_notifier, p_rect, true);
_notifier_update_cells(p_notifier, E->get(), false);
@@ -152,7 +141,6 @@ struct SpatialIndexer2D {
}
void _notifier_remove(VisibilityNotifier2D *p_notifier) {
-
Map<VisibilityNotifier2D *, Rect2>::Element *E = notifiers.find(p_notifier);
ERR_FAIL_COND(!E);
_notifier_update_cells(p_notifier, E->get(), false);
@@ -160,7 +148,6 @@ struct SpatialIndexer2D {
List<Viewport *> removed;
for (Map<Viewport *, ViewportData>::Element *F = viewports.front(); F; F = F->next()) {
-
Map<VisibilityNotifier2D *, uint64_t>::Element *G = F->get().notifiers.find(p_notifier);
if (G) {
@@ -170,7 +157,6 @@ struct SpatialIndexer2D {
}
while (!removed.empty()) {
-
p_notifier->_exit_viewport(removed.front()->get());
removed.pop_front();
}
@@ -179,7 +165,6 @@ struct SpatialIndexer2D {
}
void _add_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
-
ERR_FAIL_COND(viewports.has(p_viewport));
ViewportData vd;
vd.rect = p_rect;
@@ -188,11 +173,11 @@ struct SpatialIndexer2D {
}
void _update_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
-
Map<Viewport *, ViewportData>::Element *E = viewports.find(p_viewport);
ERR_FAIL_COND(!E);
- if (E->get().rect == p_rect)
+ if (E->get().rect == p_rect) {
return;
+ }
E->get().rect = p_rect;
changed = true;
}
@@ -201,7 +186,6 @@ struct SpatialIndexer2D {
ERR_FAIL_COND(!viewports.has(p_viewport));
List<VisibilityNotifier2D *> removed;
for (Map<VisibilityNotifier2D *, uint64_t>::Element *E = viewports[p_viewport].notifiers.front(); E; E = E->next()) {
-
removed.push_back(E->key());
}
@@ -214,12 +198,11 @@ struct SpatialIndexer2D {
}
void _update() {
-
- if (!changed)
+ if (!changed) {
return;
+ }
for (Map<Viewport *, ViewportData>::Element *E = viewports.front(); E; E = E->next()) {
-
Point2i begin = E->get().rect.position;
begin /= cell_size;
Point2i end = E->get().rect.position + E->get().rect.size;
@@ -231,24 +214,22 @@ struct SpatialIndexer2D {
int visible_cells = (end.x - begin.x) * (end.y - begin.y);
if (visible_cells > 10000) {
-
//well you zoomed out a lot, it's your problem. To avoid freezing in the for loops below, we'll manually check cell by cell
for (Map<CellKey, CellData>::Element *F = cells.front(); F; F = F->next()) {
-
const CellKey &ck = F->key();
- if (ck.x < begin.x || ck.x > end.x)
+ if (ck.x < begin.x || ck.x > end.x) {
continue;
- if (ck.y < begin.y || ck.y > end.y)
+ }
+ if (ck.y < begin.y || ck.y > end.y) {
continue;
+ }
//notifiers in cell
for (Map<VisibilityNotifier2D *, CellRef>::Element *G = F->get().notifiers.front(); G; G = G->next()) {
-
Map<VisibilityNotifier2D *, uint64_t>::Element *H = E->get().notifiers.find(G->key());
if (!H) {
-
H = E->get().notifiers.insert(G->key(), pass);
added.push_back(G->key());
} else {
@@ -258,12 +239,9 @@ struct SpatialIndexer2D {
}
} else {
-
//check cells in grid fashion
for (int i = begin.x; i <= end.x; i++) {
-
for (int j = begin.y; j <= end.y; j++) {
-
CellKey ck;
ck.x = i;
ck.y = j;
@@ -275,10 +253,8 @@ struct SpatialIndexer2D {
//notifiers in cell
for (Map<VisibilityNotifier2D *, CellRef>::Element *G = F->get().notifiers.front(); G; G = G->next()) {
-
Map<VisibilityNotifier2D *, uint64_t>::Element *H = E->get().notifiers.find(G->key());
if (!H) {
-
H = E->get().notifiers.insert(G->key(), pass);
added.push_back(G->key());
} else {
@@ -290,9 +266,9 @@ struct SpatialIndexer2D {
}
for (Map<VisibilityNotifier2D *, uint64_t>::Element *F = E->get().notifiers.front(); F; F = F->next()) {
-
- if (F->get() != pass)
+ if (F->get() != pass) {
removed.push_back(F->key());
+ }
}
while (!added.empty()) {
@@ -311,64 +287,55 @@ struct SpatialIndexer2D {
}
SpatialIndexer2D() {
-
pass = 0;
changed = false;
- cell_size = 100; //should be configurable with GLOBAL_DEF("") i guess
+ cell_size = GLOBAL_DEF("world/2d/cell_size", 100);
}
};
void World2D::_register_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
-
indexer->_add_viewport(p_viewport, p_rect);
}
void World2D::_update_viewport(Viewport *p_viewport, const Rect2 &p_rect) {
-
indexer->_update_viewport(p_viewport, p_rect);
}
-void World2D::_remove_viewport(Viewport *p_viewport) {
+void World2D::_remove_viewport(Viewport *p_viewport) {
indexer->_remove_viewport(p_viewport);
}
void World2D::_register_notifier(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect) {
-
indexer->_notifier_add(p_notifier, p_rect);
}
-void World2D::_update_notifier(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect) {
+void World2D::_update_notifier(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect) {
indexer->_notifier_update(p_notifier, p_rect);
}
-void World2D::_remove_notifier(VisibilityNotifier2D *p_notifier) {
+void World2D::_remove_notifier(VisibilityNotifier2D *p_notifier) {
indexer->_notifier_remove(p_notifier);
}
void World2D::_update() {
-
indexer->_update();
}
RID World2D::get_canvas() {
-
return canvas;
}
RID World2D::get_space() {
-
return space;
}
void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
-
for (Map<Viewport *, SpatialIndexer2D::ViewportData>::Element *E = indexer->viewports.front(); E; E = E->next()) {
r_viewports->push_back(E->key());
}
}
void World2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_canvas"), &World2D::get_canvas);
ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space);
@@ -380,12 +347,10 @@ void World2D::_bind_methods() {
}
PhysicsDirectSpaceState2D *World2D::get_direct_space_state() {
-
return PhysicsServer2D::get_singleton()->space_get_direct_state(space);
}
World2D::World2D() {
-
canvas = RenderingServer::get_singleton()->canvas_create();
space = PhysicsServer2D::get_singleton()->space_create();
@@ -401,7 +366,6 @@ World2D::World2D() {
}
World2D::~World2D() {
-
RenderingServer::get_singleton()->free(canvas);
PhysicsServer2D::get_singleton()->free(space);
memdelete(indexer);
diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h
index 88b4c2594c..c330719104 100644
--- a/scene/resources/world_2d.h
+++ b/scene/resources/world_2d.h
@@ -40,7 +40,6 @@ class Viewport;
struct SpatialIndexer2D;
class World2D : public Resource {
-
GDCLASS(World2D, Resource);
RID canvas;
diff --git a/scene/resources/world_3d.cpp b/scene/resources/world_3d.cpp
index dee00dd82a..8100f150ef 100644
--- a/scene/resources/world_3d.cpp
+++ b/scene/resources/world_3d.cpp
@@ -37,18 +37,15 @@
#include "scene/scene_string_names.h"
struct SpatialIndexer {
-
Octree<VisibilityNotifier3D> octree;
struct NotifierData {
-
AABB aabb;
OctreeElementID id;
};
Map<VisibilityNotifier3D *, NotifierData> notifiers;
struct CameraData {
-
Map<VisibilityNotifier3D *, uint64_t> notifiers;
};
@@ -65,7 +62,6 @@ struct SpatialIndexer {
uint64_t last_frame;
void _notifier_add(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
-
ERR_FAIL_COND(notifiers.has(p_notifier));
notifiers[p_notifier].aabb = p_rect;
notifiers[p_notifier].id = octree.create(p_notifier, p_rect);
@@ -73,11 +69,11 @@ struct SpatialIndexer {
}
void _notifier_update(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
-
Map<VisibilityNotifier3D *, NotifierData>::Element *E = notifiers.find(p_notifier);
ERR_FAIL_COND(!E);
- if (E->get().aabb == p_rect)
+ if (E->get().aabb == p_rect) {
return;
+ }
E->get().aabb = p_rect;
octree.move(E->get().id, E->get().aabb);
@@ -85,7 +81,6 @@ struct SpatialIndexer {
}
void _notifier_remove(VisibilityNotifier3D *p_notifier) {
-
Map<VisibilityNotifier3D *, NotifierData>::Element *E = notifiers.find(p_notifier);
ERR_FAIL_COND(!E);
@@ -94,7 +89,6 @@ struct SpatialIndexer {
List<Camera3D *> removed;
for (Map<Camera3D *, CameraData>::Element *F = cameras.front(); F; F = F->next()) {
-
Map<VisibilityNotifier3D *, uint64_t>::Element *G = F->get().notifiers.find(p_notifier);
if (G) {
@@ -104,7 +98,6 @@ struct SpatialIndexer {
}
while (!removed.empty()) {
-
p_notifier->_exit_camera(removed.front()->get());
removed.pop_front();
}
@@ -113,7 +106,6 @@ struct SpatialIndexer {
}
void _add_camera(Camera3D *p_camera) {
-
ERR_FAIL_COND(cameras.has(p_camera));
CameraData vd;
cameras[p_camera] = vd;
@@ -121,7 +113,6 @@ struct SpatialIndexer {
}
void _update_camera(Camera3D *p_camera) {
-
Map<Camera3D *, CameraData>::Element *E = cameras.find(p_camera);
ERR_FAIL_COND(!E);
changed = true;
@@ -131,7 +122,6 @@ struct SpatialIndexer {
ERR_FAIL_COND(!cameras.has(p_camera));
List<VisibilityNotifier3D *> removed;
for (Map<VisibilityNotifier3D *, uint64_t>::Element *E = cameras[p_camera].notifiers.front(); E; E = E->next()) {
-
removed.push_back(E->key());
}
@@ -144,16 +134,16 @@ struct SpatialIndexer {
}
void _update(uint64_t p_frame) {
-
- if (p_frame == last_frame)
+ if (p_frame == last_frame) {
return;
+ }
last_frame = p_frame;
- if (!changed)
+ if (!changed) {
return;
+ }
for (Map<Camera3D *, CameraData>::Element *E = cameras.front(); E; E = E->next()) {
-
pass++;
Camera3D *c = E->key();
@@ -168,12 +158,10 @@ struct SpatialIndexer {
List<VisibilityNotifier3D *> removed;
for (int i = 0; i < culled; i++) {
-
//notifiers in frustum
Map<VisibilityNotifier3D *, uint64_t>::Element *H = E->get().notifiers.find(ptr[i]);
if (!H) {
-
E->get().notifiers.insert(ptr[i], pass);
added.push_back(ptr[i]);
} else {
@@ -182,9 +170,9 @@ struct SpatialIndexer {
}
for (Map<VisibilityNotifier3D *, uint64_t>::Element *F = E->get().notifiers.front(); F; F = F->next()) {
-
- if (F->get() != pass)
+ if (F->get() != pass) {
removed.push_back(F->key());
+ }
}
while (!added.empty()) {
@@ -202,7 +190,6 @@ struct SpatialIndexer {
}
SpatialIndexer() {
-
pass = 0;
last_frame = 0;
changed = false;
@@ -211,60 +198,52 @@ struct SpatialIndexer {
};
void World3D::_register_camera(Camera3D *p_camera) {
-
#ifndef _3D_DISABLED
indexer->_add_camera(p_camera);
#endif
}
void World3D::_update_camera(Camera3D *p_camera) {
-
#ifndef _3D_DISABLED
indexer->_update_camera(p_camera);
#endif
}
-void World3D::_remove_camera(Camera3D *p_camera) {
+void World3D::_remove_camera(Camera3D *p_camera) {
#ifndef _3D_DISABLED
indexer->_remove_camera(p_camera);
#endif
}
void World3D::_register_notifier(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
-
#ifndef _3D_DISABLED
indexer->_notifier_add(p_notifier, p_rect);
#endif
}
void World3D::_update_notifier(VisibilityNotifier3D *p_notifier, const AABB &p_rect) {
-
#ifndef _3D_DISABLED
indexer->_notifier_update(p_notifier, p_rect);
#endif
}
void World3D::_remove_notifier(VisibilityNotifier3D *p_notifier) {
-
#ifndef _3D_DISABLED
indexer->_notifier_remove(p_notifier);
#endif
}
void World3D::_update(uint64_t p_frame) {
-
#ifndef _3D_DISABLED
indexer->_update(p_frame);
#endif
}
RID World3D::get_space() const {
-
return space;
}
RID World3D::get_scenario() const {
-
return scenario;
}
@@ -274,16 +253,16 @@ void World3D::set_environment(const Ref<Environment> &p_environment) {
}
environment = p_environment;
- if (environment.is_valid())
+ if (environment.is_valid()) {
RS::get_singleton()->scenario_set_environment(scenario, environment->get_rid());
- else
+ } else {
RS::get_singleton()->scenario_set_environment(scenario, RID());
+ }
emit_changed();
}
Ref<Environment> World3D::get_environment() const {
-
return environment;
}
@@ -293,47 +272,43 @@ void World3D::set_fallback_environment(const Ref<Environment> &p_environment) {
}
fallback_environment = p_environment;
- if (fallback_environment.is_valid())
+ if (fallback_environment.is_valid()) {
RS::get_singleton()->scenario_set_fallback_environment(scenario, p_environment->get_rid());
- else
+ } else {
RS::get_singleton()->scenario_set_fallback_environment(scenario, RID());
+ }
emit_changed();
}
Ref<Environment> World3D::get_fallback_environment() const {
-
return fallback_environment;
}
void World3D::set_camera_effects(const Ref<CameraEffects> &p_camera_effects) {
-
camera_effects = p_camera_effects;
- if (camera_effects.is_valid())
+ if (camera_effects.is_valid()) {
RS::get_singleton()->scenario_set_camera_effects(scenario, camera_effects->get_rid());
- else
+ } else {
RS::get_singleton()->scenario_set_camera_effects(scenario, RID());
+ }
}
Ref<CameraEffects> World3D::get_camera_effects() const {
-
return camera_effects;
}
PhysicsDirectSpaceState3D *World3D::get_direct_space_state() {
-
return PhysicsServer3D::get_singleton()->space_get_direct_state(space);
}
void World3D::get_camera_list(List<Camera3D *> *r_cameras) {
-
for (Map<Camera3D *, SpatialIndexer::CameraData>::Element *E = indexer->cameras.front(); E; E = E->next()) {
r_cameras->push_back(E->key());
}
}
void World3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_space"), &World3D::get_space);
ClassDB::bind_method(D_METHOD("get_scenario"), &World3D::get_scenario);
ClassDB::bind_method(D_METHOD("set_environment", "env"), &World3D::set_environment);
@@ -352,7 +327,6 @@ void World3D::_bind_methods() {
}
World3D::World3D() {
-
space = PhysicsServer3D::get_singleton()->space_create();
scenario = RenderingServer::get_singleton()->scenario_create();
@@ -372,7 +346,6 @@ World3D::World3D() {
}
World3D::~World3D() {
-
PhysicsServer3D::get_singleton()->free(space);
RenderingServer::get_singleton()->free(scenario);
diff --git a/scene/resources/world_margin_shape_3d.cpp b/scene/resources/world_margin_shape_3d.cpp
index aa96f8aa68..d613413b33 100644
--- a/scene/resources/world_margin_shape_3d.cpp
+++ b/scene/resources/world_margin_shape_3d.cpp
@@ -33,7 +33,6 @@
#include "servers/physics_server_3d.h"
Vector<Vector3> WorldMarginShape3D::get_debug_mesh_lines() {
-
Plane p = get_plane();
Vector<Vector3> points;
@@ -62,13 +61,11 @@ Vector<Vector3> WorldMarginShape3D::get_debug_mesh_lines() {
}
void WorldMarginShape3D::_update_shape() {
-
PhysicsServer3D::get_singleton()->shape_set_data(get_shape(), plane);
Shape3D::_update_shape();
}
void WorldMarginShape3D::set_plane(Plane p_plane) {
-
plane = p_plane;
_update_shape();
notify_change_to_owners();
@@ -76,12 +73,10 @@ void WorldMarginShape3D::set_plane(Plane p_plane) {
}
Plane WorldMarginShape3D::get_plane() const {
-
return plane;
}
void WorldMarginShape3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_plane", "plane"), &WorldMarginShape3D::set_plane);
ClassDB::bind_method(D_METHOD("get_plane"), &WorldMarginShape3D::get_plane);
@@ -90,6 +85,5 @@ void WorldMarginShape3D::_bind_methods() {
WorldMarginShape3D::WorldMarginShape3D() :
Shape3D(PhysicsServer3D::get_singleton()->shape_create(PhysicsServer3D::SHAPE_PLANE)) {
-
set_plane(Plane(0, 1, 0, 0));
}
diff --git a/scene/resources/world_margin_shape_3d.h b/scene/resources/world_margin_shape_3d.h
index 5e0f046628..acb479972b 100644
--- a/scene/resources/world_margin_shape_3d.h
+++ b/scene/resources/world_margin_shape_3d.h
@@ -34,7 +34,6 @@
#include "scene/resources/shape_3d.h"
class WorldMarginShape3D : public Shape3D {
-
GDCLASS(WorldMarginShape3D, Shape3D);
Plane plane;
diff --git a/scene/scene_string_names.cpp b/scene/scene_string_names.cpp
index 5e3f8b803b..7f87da3724 100644
--- a/scene/scene_string_names.cpp
+++ b/scene/scene_string_names.cpp
@@ -33,7 +33,6 @@
SceneStringNames *SceneStringNames::singleton = nullptr;
SceneStringNames::SceneStringNames() {
-
_estimate_cost = StaticCString::create("_estimate_cost");
_compute_cost = StaticCString::create("_compute_cost");
@@ -189,7 +188,6 @@ SceneStringNames::SceneStringNames() {
_default = StaticCString::create("default");
for (int i = 0; i < MAX_MATERIALS; i++) {
-
mesh_materials[i] = "material/" + itos(i);
}
@@ -205,4 +203,9 @@ SceneStringNames::SceneStringNames() {
shader_overrides_group = StaticCString::create("_shader_overrides_group_");
shader_overrides_group_active = StaticCString::create("_shader_overrides_group_active_");
+
+#ifndef DISABLE_DEPRECATED
+ use_in_baked_light = StaticCString::create("use_in_baked_light");
+ use_dynamic_gi = StaticCString::create("use_dynamic_gi");
+#endif
}
diff --git a/scene/scene_string_names.h b/scene/scene_string_names.h
index c5de10a6f6..1a6ffbd5dd 100644
--- a/scene/scene_string_names.h
+++ b/scene/scene_string_names.h
@@ -35,7 +35,6 @@
#include "core/string_name.h"
class SceneStringNames {
-
friend void register_scene_types();
friend void unregister_scene_types();
@@ -210,6 +209,10 @@ public:
StringName shader_overrides_group;
StringName shader_overrides_group_active;
+#ifndef DISABLE_DEPRECATED
+ StringName use_in_baked_light;
+ StringName use_dynamic_gi;
+#endif
enum {
MAX_MATERIALS = 32
};
diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp
index ed67e8902a..ff0d2cad65 100644
--- a/servers/audio/audio_driver_dummy.cpp
+++ b/servers/audio/audio_driver_dummy.cpp
@@ -34,17 +34,16 @@
#include "core/project_settings.h"
Error AudioDriverDummy::init() {
-
active = false;
thread_exited = false;
exit_thread = false;
samples_in = nullptr;
- mix_rate = DEFAULT_MIX_RATE;
+ mix_rate = GLOBAL_GET("audio/mix_rate");
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
- int latency = GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+ int latency = GLOBAL_GET("audio/output_latency");
buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
samples_in = memnew_arr(int32_t, buffer_frames * channels);
@@ -55,15 +54,12 @@ Error AudioDriverDummy::init() {
};
void AudioDriverDummy::thread_func(void *p_udata) {
-
AudioDriverDummy *ad = (AudioDriverDummy *)p_udata;
uint64_t usdelay = (ad->buffer_frames / float(ad->mix_rate)) * 1000000;
while (!ad->exit_thread) {
-
if (ad->active) {
-
ad->lock();
ad->audio_server_process(ad->buffer_frames, ad->samples_in);
@@ -78,38 +74,35 @@ void AudioDriverDummy::thread_func(void *p_udata) {
};
void AudioDriverDummy::start() {
-
active = true;
};
int AudioDriverDummy::get_mix_rate() const {
-
return mix_rate;
};
AudioDriver::SpeakerMode AudioDriverDummy::get_speaker_mode() const {
-
return speaker_mode;
};
void AudioDriverDummy::lock() {
-
- if (!thread)
+ if (!thread) {
return;
+ }
mutex.lock();
};
void AudioDriverDummy::unlock() {
-
- if (!thread)
+ if (!thread) {
return;
+ }
mutex.unlock();
};
void AudioDriverDummy::finish() {
-
- if (!thread)
+ if (!thread) {
return;
+ }
exit_thread = true;
Thread::wait_to_finish(thread);
@@ -121,12 +114,3 @@ void AudioDriverDummy::finish() {
memdelete(thread);
thread = nullptr;
};
-
-AudioDriverDummy::AudioDriverDummy() {
-
- thread = nullptr;
-};
-
-AudioDriverDummy::~AudioDriverDummy(){
-
-};
diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h
index a2cd9b2dc6..84a566e420 100644
--- a/servers/audio/audio_driver_dummy.h
+++ b/servers/audio/audio_driver_dummy.h
@@ -37,8 +37,7 @@
#include "core/os/thread.h"
class AudioDriverDummy : public AudioDriver {
-
- Thread *thread;
+ Thread *thread = nullptr;
Mutex mutex;
int32_t *samples_in;
@@ -68,8 +67,8 @@ public:
virtual void unlock();
virtual void finish();
- AudioDriverDummy();
- ~AudioDriverDummy();
+ AudioDriverDummy() {}
+ ~AudioDriverDummy() {}
};
#endif
diff --git a/servers/audio/audio_filter_sw.cpp b/servers/audio/audio_filter_sw.cpp
index 2771fc177b..f5eafb7e60 100644
--- a/servers/audio/audio_filter_sw.cpp
+++ b/servers/audio/audio_filter_sw.cpp
@@ -31,34 +31,32 @@
#include "audio_filter_sw.h"
void AudioFilterSW::set_mode(Mode p_mode) {
-
mode = p_mode;
}
-void AudioFilterSW::set_cutoff(float p_cutoff) {
+void AudioFilterSW::set_cutoff(float p_cutoff) {
cutoff = p_cutoff;
}
-void AudioFilterSW::set_resonance(float p_resonance) {
+void AudioFilterSW::set_resonance(float p_resonance) {
resonance = p_resonance;
}
void AudioFilterSW::set_gain(float p_gain) {
-
gain = p_gain;
}
void AudioFilterSW::set_sampling_rate(float p_srate) {
-
sampling_rate = p_srate;
}
void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) {
-
int sr_limit = (sampling_rate / 2) + 512;
double final_cutoff = (cutoff > sr_limit) ? sr_limit : cutoff;
- if (final_cutoff < 1) final_cutoff = 1; //don't allow less than this
+ if (final_cutoff < 1) {
+ final_cutoff = 1; //don't allow less than this
+ }
double omega = 2.0 * Math_PI * final_cutoff / sampling_rate;
@@ -70,18 +68,19 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) {
Q = 0.0001;
}
- if (mode == BANDPASS)
+ if (mode == BANDPASS) {
Q *= 2.0;
- else if (mode == PEAK)
+ } else if (mode == PEAK) {
Q *= 3.0;
+ }
double tmpgain = gain;
- if (tmpgain < 0.001)
+ if (tmpgain < 0.001) {
tmpgain = 0.001;
+ }
if (stages > 1) {
-
Q = (Q > 1.0 ? Math::pow(Q, 1.0 / stages) : Q);
tmpgain = Math::pow(tmpgain, 1.0 / (stages + 1));
}
@@ -90,9 +89,7 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) {
double a0 = 1.0 + alpha;
switch (mode) {
-
case LOWPASS: {
-
p_coeffs->b0 = (1.0 - cos_v) / 2.0;
p_coeffs->b1 = 1.0 - cos_v;
p_coeffs->b2 = (1.0 - cos_v) / 2.0;
@@ -101,7 +98,6 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) {
} break;
case HIGHPASS: {
-
p_coeffs->b0 = (1.0 + cos_v) / 2.0;
p_coeffs->b1 = -(1.0 + cos_v);
p_coeffs->b2 = (1.0 + cos_v) / 2.0;
@@ -110,7 +106,6 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) {
} break;
case BANDPASS: {
-
p_coeffs->b0 = alpha * sqrt(Q + 1);
p_coeffs->b1 = 0.0;
p_coeffs->b2 = -alpha * sqrt(Q + 1);
@@ -119,7 +114,6 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) {
} break;
case NOTCH: {
-
p_coeffs->b0 = 1.0;
p_coeffs->b1 = -2.0 * cos_v;
p_coeffs->b2 = 1.0;
@@ -150,10 +144,10 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) {
} break;
case LOWSHELF: {
-
double tmpq = Math::sqrt(Q);
- if (tmpq <= 0)
+ if (tmpq <= 0) {
tmpq = 0.001;
+ }
double beta = Math::sqrt(tmpgain) / tmpq;
a0 = (tmpgain + 1.0) + (tmpgain - 1.0) * cos_v + beta * sin_v;
@@ -166,8 +160,9 @@ void AudioFilterSW::prepare_coefficients(Coeffs *p_coeffs) {
} break;
case HIGHSHELF: {
double tmpq = Math::sqrt(Q);
- if (tmpq <= 0)
+ if (tmpq <= 0) {
tmpq = 0.001;
+ }
double beta = Math::sqrt(tmpgain) / tmpq;
a0 = (tmpgain + 1.0) - (tmpgain - 1.0) * cos_v + beta * sin_v;
@@ -202,7 +197,6 @@ void AudioFilterSW::set_stages(int p_stages) { //adjust for multiple stages
/* Fouriertransform kernel to obtain response */
float AudioFilterSW::get_response(float p_freq, Coeffs *p_coeffs) {
-
float freq = p_freq / sampling_rate * Math_PI * 2.0f;
float cx = p_coeffs->b0, cy = 0.0;
@@ -226,7 +220,6 @@ float AudioFilterSW::get_response(float p_freq, Coeffs *p_coeffs) {
}
AudioFilterSW::AudioFilterSW() {
-
sampling_rate = 44100;
resonance = 0.5;
cutoff = 5000;
@@ -236,12 +229,10 @@ AudioFilterSW::AudioFilterSW() {
}
AudioFilterSW::Processor::Processor() {
-
set_filter(nullptr);
}
void AudioFilterSW::Processor::set_filter(AudioFilterSW *p_filter, bool p_clear_history) {
-
if (p_clear_history) {
ha1 = ha2 = hb1 = hb2 = 0;
}
@@ -249,9 +240,9 @@ void AudioFilterSW::Processor::set_filter(AudioFilterSW *p_filter, bool p_clear_
}
void AudioFilterSW::Processor::update_coeffs(int p_interp_buffer_len) {
-
- if (!filter)
+ if (!filter) {
return;
+ }
if (p_interp_buffer_len) { //interpolate
Coeffs old_coeffs = coeffs;
@@ -268,19 +259,17 @@ void AudioFilterSW::Processor::update_coeffs(int p_interp_buffer_len) {
}
void AudioFilterSW::Processor::process(float *p_samples, int p_amount, int p_stride, bool p_interpolate) {
-
- if (!filter)
+ if (!filter) {
return;
+ }
if (p_interpolate) {
for (int i = 0; i < p_amount; i++) {
-
process_one_interp(*p_samples);
p_samples += p_stride;
}
} else {
for (int i = 0; i < p_amount; i++) {
-
process_one(*p_samples);
p_samples += p_stride;
}
diff --git a/servers/audio/audio_filter_sw.h b/servers/audio/audio_filter_sw.h
index 61088eec55..a7f570fbb4 100644
--- a/servers/audio/audio_filter_sw.h
+++ b/servers/audio/audio_filter_sw.h
@@ -36,7 +36,6 @@
class AudioFilterSW {
public:
struct Coeffs {
-
float a1, a2;
float b0, b1, b2;
@@ -99,7 +98,6 @@ public:
/* inline methods */
void AudioFilterSW::Processor::process_one(float &p_sample) {
-
float pre = p_sample;
p_sample = (p_sample * coeffs.b0 + hb1 * coeffs.b1 + hb2 * coeffs.b2 + ha1 * coeffs.a1 + ha2 * coeffs.a2);
ha2 = ha1;
@@ -109,7 +107,6 @@ void AudioFilterSW::Processor::process_one(float &p_sample) {
}
void AudioFilterSW::Processor::process_one_interp(float &p_sample) {
-
float pre = p_sample;
p_sample = (p_sample * coeffs.b0 + hb1 * coeffs.b1 + hb2 * coeffs.b2 + ha1 * coeffs.a1 + ha2 * coeffs.a2);
ha2 = ha1;
diff --git a/servers/audio/audio_rb_resampler.cpp b/servers/audio/audio_rb_resampler.cpp
index 0ac7ddc7a9..7613e70e64 100644
--- a/servers/audio/audio_rb_resampler.cpp
+++ b/servers/audio/audio_rb_resampler.cpp
@@ -34,9 +34,9 @@
#include "servers/audio_server.h"
int AudioRBResampler::get_channel_count() const {
-
- if (!rb)
+ if (!rb) {
return 0;
+ }
return channels;
}
@@ -46,11 +46,9 @@ int AudioRBResampler::get_channel_count() const {
// but it wasn't obvious to integrate that with VideoPlayer
template <int C>
uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_increment) {
-
uint32_t read = offset & MIX_FRAC_MASK;
for (int i = 0; i < p_todo; i++) {
-
offset = (offset + p_increment) & (((1 << (rb_bits + MIX_FRAC_BITS)) - 1));
read += p_increment;
uint32_t pos = offset >> MIX_FRAC_BITS;
@@ -60,7 +58,6 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i
// since this is a template with a known compile time value (C), conditionals go away when compiling.
if (C == 1) {
-
float v0 = rb[pos];
float v0n = rb[pos_next];
v0 += (v0n - v0) * frac;
@@ -68,7 +65,6 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i
}
if (C == 2) {
-
float v0 = rb[(pos << 1) + 0];
float v1 = rb[(pos << 1) + 1];
float v0n = rb[(pos_next << 1) + 0];
@@ -81,7 +77,6 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i
// This will probably never be used, but added anyway
if (C == 4) {
-
float v0 = rb[(pos << 2) + 0];
float v1 = rb[(pos << 2) + 1];
float v0n = rb[(pos_next << 2) + 0];
@@ -92,7 +87,6 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i
}
if (C == 6) {
-
float v0 = rb[(pos * 6) + 0];
float v1 = rb[(pos * 6) + 1];
float v0n = rb[(pos_next * 6) + 0];
@@ -108,9 +102,9 @@ uint32_t AudioRBResampler::_resample(AudioFrame *p_dest, int p_todo, int32_t p_i
}
bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) {
-
- if (!rb)
+ if (!rb) {
return false;
+ }
int32_t increment = (src_mix_rate * MIX_FRAC_LEN) / target_mix_rate;
int read_space = get_reader_space();
@@ -119,14 +113,23 @@ bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) {
{
int src_read = 0;
switch (channels) {
- case 1: src_read = _resample<1>(p_dest, target_todo, increment); break;
- case 2: src_read = _resample<2>(p_dest, target_todo, increment); break;
- case 4: src_read = _resample<4>(p_dest, target_todo, increment); break;
- case 6: src_read = _resample<6>(p_dest, target_todo, increment); break;
+ case 1:
+ src_read = _resample<1>(p_dest, target_todo, increment);
+ break;
+ case 2:
+ src_read = _resample<2>(p_dest, target_todo, increment);
+ break;
+ case 4:
+ src_read = _resample<4>(p_dest, target_todo, increment);
+ break;
+ case 6:
+ src_read = _resample<6>(p_dest, target_todo, increment);
+ break;
}
- if (src_read > read_space)
+ if (src_read > read_space) {
src_read = read_space;
+ }
rb_read_pos = (rb_read_pos + src_read) & rb_mask;
@@ -147,15 +150,15 @@ bool AudioRBResampler::mix(AudioFrame *p_dest, int p_frames) {
}
int AudioRBResampler::get_num_of_ready_frames() {
- if (!is_ready())
+ if (!is_ready()) {
return 0;
+ }
int32_t increment = (src_mix_rate * MIX_FRAC_LEN) / target_mix_rate;
int read_space = get_reader_space();
return (int64_t(read_space) << MIX_FRAC_BITS) / increment;
}
Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_mix_rate, int p_buffer_msec, int p_minbuff_needed) {
-
ERR_FAIL_COND_V(p_channels != 1 && p_channels != 2 && p_channels != 4 && p_channels != 6, ERR_INVALID_PARAMETER);
int desired_rb_bits = nearest_shift(MAX((p_buffer_msec / 1000.0) * p_src_mix_rate, p_minbuff_needed));
@@ -163,14 +166,12 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m
bool recreate = !rb;
if (rb && (uint32_t(desired_rb_bits) != rb_bits || channels != uint32_t(p_channels))) {
-
memdelete_arr(rb);
memdelete_arr(read_buf);
recreate = true;
}
if (recreate) {
-
channels = p_channels;
rb_bits = desired_rb_bits;
rb_len = (1 << rb_bits);
@@ -187,7 +188,6 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m
//avoid maybe strange noises upon load
for (unsigned int i = 0; i < (rb_len * channels); i++) {
-
rb[i] = 0;
read_buf[i] = 0;
}
@@ -196,9 +196,9 @@ Error AudioRBResampler::setup(int p_channels, int p_src_mix_rate, int p_target_m
}
void AudioRBResampler::clear() {
-
- if (!rb)
+ if (!rb) {
return;
+ }
//should be stopped at this point but just in case
memdelete_arr(rb);
@@ -211,7 +211,6 @@ void AudioRBResampler::clear() {
}
AudioRBResampler::AudioRBResampler() {
-
rb = nullptr;
offset = 0;
read_buf = nullptr;
@@ -228,7 +227,6 @@ AudioRBResampler::AudioRBResampler() {
}
AudioRBResampler::~AudioRBResampler() {
-
if (rb) {
memdelete_arr(rb);
memdelete_arr(read_buf);
diff --git a/servers/audio/audio_rb_resampler.h b/servers/audio/audio_rb_resampler.h
index 40cf3e4cd7..12ec526adb 100644
--- a/servers/audio/audio_rb_resampler.h
+++ b/servers/audio/audio_rb_resampler.h
@@ -36,7 +36,6 @@
#include "servers/audio_server.h"
struct AudioRBResampler {
-
uint32_t rb_bits;
uint32_t rb_len;
uint32_t rb_mask;
@@ -116,31 +115,24 @@ public:
_FORCE_INLINE_ float *get_write_buffer() { return read_buf; }
_FORCE_INLINE_ void write(uint32_t p_frames) {
-
ERR_FAIL_COND(p_frames >= rb_len);
switch (channels) {
case 1: {
-
for (uint32_t i = 0; i < p_frames; i++) {
-
rb[rb_write_pos] = read_buf[i];
rb_write_pos = (rb_write_pos + 1) & rb_mask;
}
} break;
case 2: {
-
for (uint32_t i = 0; i < p_frames; i++) {
-
rb[(rb_write_pos << 1) + 0] = read_buf[(i << 1) + 0];
rb[(rb_write_pos << 1) + 1] = read_buf[(i << 1) + 1];
rb_write_pos = (rb_write_pos + 1) & rb_mask;
}
} break;
case 4: {
-
for (uint32_t i = 0; i < p_frames; i++) {
-
rb[(rb_write_pos << 2) + 0] = read_buf[(i << 2) + 0];
rb[(rb_write_pos << 2) + 1] = read_buf[(i << 2) + 1];
rb[(rb_write_pos << 2) + 2] = read_buf[(i << 2) + 2];
@@ -149,9 +141,7 @@ public:
}
} break;
case 6: {
-
for (uint32_t i = 0; i < p_frames; i++) {
-
rb[(rb_write_pos * 6) + 0] = read_buf[(i * 6) + 0];
rb[(rb_write_pos * 6) + 1] = read_buf[(i * 6) + 1];
rb[(rb_write_pos * 6) + 2] = read_buf[(i * 6) + 2];
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 46e674fd9b..2cc2f5c291 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -36,7 +36,6 @@
//////////////////////////////
void AudioStreamPlaybackResampled::_begin_resample() {
-
//clear cubic interpolation history
internal_buffer[0] = AudioFrame(0.0, 0.0);
internal_buffer[1] = AudioFrame(0.0, 0.0);
@@ -48,14 +47,12 @@ void AudioStreamPlaybackResampled::_begin_resample() {
}
void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
-
float target_rate = AudioServer::get_singleton()->get_mix_rate();
float global_rate_scale = AudioServer::get_singleton()->get_global_rate_scale();
uint64_t mix_increment = uint64_t(((get_stream_sampling_rate() * p_rate_scale) / double(target_rate * global_rate_scale)) * double(FP_LEN));
for (int i = 0; i < p_frames; i++) {
-
uint32_t idx = CUBIC_INTERP_HISTORY + uint32_t(mix_offset >> FP_BITS);
//standard cubic interpolation (great quality/performance ratio)
//this used to be moved to a LUT for greater performance, but nowadays CPU speed is generally faster than memory.
@@ -76,7 +73,6 @@ void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
mix_offset += mix_increment;
while ((mix_offset >> FP_BITS) >= INTERNAL_BUFFER_LEN) {
-
internal_buffer[0] = internal_buffer[INTERNAL_BUFFER_LEN + 0];
internal_buffer[1] = internal_buffer[INTERNAL_BUFFER_LEN + 1];
internal_buffer[2] = internal_buffer[INTERNAL_BUFFER_LEN + 2];
@@ -97,7 +93,6 @@ void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
////////////////////////////////
void AudioStream::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_length"), &AudioStream::get_length);
}
@@ -116,7 +111,6 @@ Ref<AudioStreamPlayback> AudioStreamMicrophone::instance_playback() {
}
String AudioStreamMicrophone::get_stream_name() const {
-
//if (audio_stream.is_valid()) {
//return "Random: " + audio_stream->get_name();
//}
@@ -134,7 +128,6 @@ AudioStreamMicrophone::AudioStreamMicrophone() {
}
void AudioStreamPlaybackMicrophone::_mix_internal(AudioFrame *p_buffer, int p_frames) {
-
AudioDriver::get_singleton()->lock();
Vector<int32_t> buf = AudioDriver::get_singleton()->get_input_buffer();
@@ -187,7 +180,6 @@ float AudioStreamPlaybackMicrophone::get_stream_sampling_rate() {
}
void AudioStreamPlaybackMicrophone::start(float p_from_pos) {
-
if (active) {
return;
}
@@ -239,7 +231,6 @@ AudioStreamPlaybackMicrophone::AudioStreamPlaybackMicrophone() {
////////////////////////////////
void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_stream) {
-
audio_stream = p_audio_stream;
if (audio_stream.is_valid()) {
for (Set<AudioStreamPlaybackRandomPitch *>::Element *E = playbacks.front(); E; E = E->next()) {
@@ -249,14 +240,13 @@ void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_st
}
Ref<AudioStream> AudioStreamRandomPitch::get_audio_stream() const {
-
return audio_stream;
}
void AudioStreamRandomPitch::set_random_pitch(float p_pitch) {
-
- if (p_pitch < 1)
+ if (p_pitch < 1) {
p_pitch = 1;
+ }
random_pitch = p_pitch;
}
@@ -267,8 +257,9 @@ float AudioStreamRandomPitch::get_random_pitch() const {
Ref<AudioStreamPlayback> AudioStreamRandomPitch::instance_playback() {
Ref<AudioStreamPlaybackRandomPitch> playback;
playback.instance();
- if (audio_stream.is_valid())
+ if (audio_stream.is_valid()) {
playback->playback = audio_stream->instance_playback();
+ }
playbacks.insert(playback.ptr());
playback->random_pitch = Ref<AudioStreamRandomPitch>((AudioStreamRandomPitch *)this);
@@ -276,7 +267,6 @@ Ref<AudioStreamPlayback> AudioStreamRandomPitch::instance_playback() {
}
String AudioStreamRandomPitch::get_stream_name() const {
-
if (audio_stream.is_valid()) {
return "Random: " + audio_stream->get_name();
}
@@ -292,7 +282,6 @@ float AudioStreamRandomPitch::get_length() const {
}
void AudioStreamRandomPitch::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_audio_stream", "stream"), &AudioStreamRandomPitch::set_audio_stream);
ClassDB::bind_method(D_METHOD("get_audio_stream"), &AudioStreamRandomPitch::get_audio_stream);
@@ -325,6 +314,7 @@ void AudioStreamPlaybackRandomPitch::stop() {
;
}
}
+
bool AudioStreamPlaybackRandomPitch::is_playing() const {
if (playing.is_valid()) {
return playing->is_playing();
@@ -348,6 +338,7 @@ float AudioStreamPlaybackRandomPitch::get_playback_position() const {
return 0;
}
+
void AudioStreamPlaybackRandomPitch::seek(float p_time) {
if (playing.is_valid()) {
playing->seek(p_time);
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 155b683d7d..fc66fd1ff7 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -37,7 +37,6 @@
#include "servers/audio_server.h"
class AudioStreamPlayback : public Reference {
-
GDCLASS(AudioStreamPlayback, Reference);
public:
@@ -54,7 +53,6 @@ public:
};
class AudioStreamPlaybackResampled : public AudioStreamPlayback {
-
GDCLASS(AudioStreamPlaybackResampled, AudioStreamPlayback);
enum {
@@ -80,7 +78,6 @@ public:
};
class AudioStream : public Resource {
-
GDCLASS(AudioStream, Resource);
OBJ_SAVE_TYPE(AudioStream); // Saves derived classes with common type so they can be interchanged.
@@ -99,7 +96,6 @@ public:
class AudioStreamPlaybackMicrophone;
class AudioStreamMicrophone : public AudioStream {
-
GDCLASS(AudioStreamMicrophone, AudioStream);
friend class AudioStreamPlaybackMicrophone;
@@ -118,7 +114,6 @@ public:
};
class AudioStreamPlaybackMicrophone : public AudioStreamPlaybackResampled {
-
GDCLASS(AudioStreamPlaybackMicrophone, AudioStreamPlaybackResampled);
friend class AudioStreamMicrophone;
@@ -152,7 +147,6 @@ public:
class AudioStreamPlaybackRandomPitch;
class AudioStreamRandomPitch : public AudioStream {
-
GDCLASS(AudioStreamRandomPitch, AudioStream);
friend class AudioStreamPlaybackRandomPitch;
@@ -179,7 +173,6 @@ public:
};
class AudioStreamPlaybackRandomPitch : public AudioStreamPlayback {
-
GDCLASS(AudioStreamPlaybackRandomPitch, AudioStreamPlayback);
friend class AudioStreamRandomPitch;
diff --git a/servers/audio/effects/audio_effect_amplify.cpp b/servers/audio/effects/audio_effect_amplify.cpp
index 8ad2ecc5ce..74fdcbc67a 100644
--- a/servers/audio/effects/audio_effect_amplify.cpp
+++ b/servers/audio/effects/audio_effect_amplify.cpp
@@ -31,7 +31,6 @@
#include "audio_effect_amplify.h"
void AudioEffectAmplifyInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
//multiply volume interpolating to avoid clicks if this changes
float volume_db = base->volume_db;
float vol = Math::db2linear(mix_volume_db);
@@ -58,12 +57,10 @@ void AudioEffectAmplify::set_volume_db(float p_volume) {
}
float AudioEffectAmplify::get_volume_db() const {
-
return volume_db;
}
void AudioEffectAmplify::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_volume_db", "volume"), &AudioEffectAmplify::set_volume_db);
ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioEffectAmplify::get_volume_db);
diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp
index 34c03dca8d..2b530475f0 100644
--- a/servers/audio/effects/audio_effect_chorus.cpp
+++ b/servers/audio/effects/audio_effect_chorus.cpp
@@ -33,11 +33,9 @@
#include "servers/audio_server.h"
void AudioEffectChorusInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
int todo = p_frame_count;
while (todo) {
-
int to_mix = MIN(todo, 256); //can't mix too much
_process_chunk(p_src_frames, p_dst_frames, to_mix);
@@ -50,7 +48,6 @@ void AudioEffectChorusInstance::process(const AudioFrame *p_src_frames, AudioFra
}
void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
//fill ringbuffer
for (int i = 0; i < p_frame_count; i++) {
audio_buffer.write[(buffer_pos + i) & buffer_mask] = p_src_frames[i];
@@ -61,7 +58,6 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A
/* process voices */
for (int vc = 0; vc < base->voice_count; vc++) {
-
AudioEffectChorus::Voice &v = base->voice[vc];
double time_to_mix = (float)p_frame_count / mix_rate;
@@ -85,8 +81,9 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A
}
//low pass filter
- if (v.cutoff == 0)
+ if (v.cutoff == 0) {
continue;
+ }
float auxlp = expf(-2.0 * Math_PI * v.cutoff / mix_rate);
float c1 = 1.0 - auxlp;
float c2 = auxlp;
@@ -103,7 +100,6 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A
vol_modifier.r *= CLAMP(1.0 + v.pan, 0, 1);
for (int i = 0; i < p_frame_count; i++) {
-
/** COMPUTE WAVEFORM **/
float phase = (float)(local_cycles & AudioEffectChorus::CYCLES_MASK) / (float)(1 << AudioEffectChorus::CYCLES_FRAC);
@@ -146,7 +142,6 @@ void AudioEffectChorusInstance::_process_chunk(const AudioFrame *p_src_frames, A
}
Ref<AudioEffectInstance> AudioEffectChorus::instance() {
-
Ref<AudioEffectChorusInstance> ins;
ins.instance();
ins->base = Ref<AudioEffectChorus>(this);
@@ -182,24 +177,21 @@ Ref<AudioEffectInstance> AudioEffectChorus::instance() {
}
void AudioEffectChorus::set_voice_count(int p_voices) {
-
ERR_FAIL_COND(p_voices < 1 || p_voices > MAX_VOICES);
voice_count = p_voices;
}
int AudioEffectChorus::get_voice_count() const {
-
return voice_count;
}
void AudioEffectChorus::set_voice_delay_ms(int p_voice, float p_delay_ms) {
-
ERR_FAIL_INDEX(p_voice, MAX_VOICES);
voice[p_voice].delay = p_delay_ms;
}
-float AudioEffectChorus::get_voice_delay_ms(int p_voice) const {
+float AudioEffectChorus::get_voice_delay_ms(int p_voice) const {
ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0);
return voice[p_voice].delay;
}
@@ -209,85 +201,78 @@ void AudioEffectChorus::set_voice_rate_hz(int p_voice, float p_rate_hz) {
voice[p_voice].rate = p_rate_hz;
}
-float AudioEffectChorus::get_voice_rate_hz(int p_voice) const {
+float AudioEffectChorus::get_voice_rate_hz(int p_voice) const {
ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0);
return voice[p_voice].rate;
}
void AudioEffectChorus::set_voice_depth_ms(int p_voice, float p_depth_ms) {
-
ERR_FAIL_INDEX(p_voice, MAX_VOICES);
voice[p_voice].depth = p_depth_ms;
}
-float AudioEffectChorus::get_voice_depth_ms(int p_voice) const {
+float AudioEffectChorus::get_voice_depth_ms(int p_voice) const {
ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0);
return voice[p_voice].depth;
}
void AudioEffectChorus::set_voice_level_db(int p_voice, float p_level_db) {
-
ERR_FAIL_INDEX(p_voice, MAX_VOICES);
voice[p_voice].level = p_level_db;
}
-float AudioEffectChorus::get_voice_level_db(int p_voice) const {
+float AudioEffectChorus::get_voice_level_db(int p_voice) const {
ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0);
return voice[p_voice].level;
}
void AudioEffectChorus::set_voice_cutoff_hz(int p_voice, float p_cutoff_hz) {
-
ERR_FAIL_INDEX(p_voice, MAX_VOICES);
voice[p_voice].cutoff = p_cutoff_hz;
}
-float AudioEffectChorus::get_voice_cutoff_hz(int p_voice) const {
+float AudioEffectChorus::get_voice_cutoff_hz(int p_voice) const {
ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0);
return voice[p_voice].cutoff;
}
void AudioEffectChorus::set_voice_pan(int p_voice, float p_pan) {
-
ERR_FAIL_INDEX(p_voice, MAX_VOICES);
voice[p_voice].pan = p_pan;
}
-float AudioEffectChorus::get_voice_pan(int p_voice) const {
+float AudioEffectChorus::get_voice_pan(int p_voice) const {
ERR_FAIL_INDEX_V(p_voice, MAX_VOICES, 0);
return voice[p_voice].pan;
}
void AudioEffectChorus::set_wet(float amount) {
-
wet = amount;
}
-float AudioEffectChorus::get_wet() const {
+float AudioEffectChorus::get_wet() const {
return wet;
}
void AudioEffectChorus::set_dry(float amount) {
-
dry = amount;
}
-float AudioEffectChorus::get_dry() const {
+float AudioEffectChorus::get_dry() const {
return dry;
}
void AudioEffectChorus::_validate_property(PropertyInfo &property) const {
-
if (property.name.begins_with("voice/")) {
int voice_idx = property.name.get_slice("/", 1).to_int();
if (voice_idx > voice_count) {
@@ -297,7 +282,6 @@ void AudioEffectChorus::_validate_property(PropertyInfo &property) const {
}
void AudioEffectChorus::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_voice_count", "voices"), &AudioEffectChorus::set_voice_count);
ClassDB::bind_method(D_METHOD("get_voice_count"), &AudioEffectChorus::get_voice_count);
diff --git a/servers/audio/effects/audio_effect_chorus.h b/servers/audio/effects/audio_effect_chorus.h
index ab5053b919..4d15c518d6 100644
--- a/servers/audio/effects/audio_effect_chorus.h
+++ b/servers/audio/effects/audio_effect_chorus.h
@@ -73,7 +73,6 @@ public:
private:
struct Voice {
-
float delay;
float rate;
float depth;
@@ -82,7 +81,6 @@ private:
float pan;
Voice() {
-
delay = 12.0;
rate = 1;
depth = 0;
diff --git a/servers/audio/effects/audio_effect_compressor.cpp b/servers/audio/effects/audio_effect_compressor.cpp
index 8d54bd8e36..4b0b4dabea 100644
--- a/servers/audio/effects/audio_effect_compressor.cpp
+++ b/servers/audio/effects/audio_effect_compressor.cpp
@@ -32,7 +32,6 @@
#include "servers/audio_server.h"
void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
float threshold = Math::db2linear(base->threshold);
float sample_rate = AudioServer::get_singleton()->get_mix_rate();
@@ -51,7 +50,6 @@ void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, Audi
const AudioFrame *src = p_src_frames;
if (base->sidechain != StringName() && current_channel != -1) {
-
int bus = AudioServer::get_singleton()->thread_find_bus_index(base->sidechain);
if (bus >= 0) {
src = AudioServer::get_singleton()->thread_get_channel_mix_buffer(bus, current_channel);
@@ -59,7 +57,6 @@ void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, Audi
}
for (int i = 0; i < p_frame_count; i++) {
-
AudioFrame s = src[i];
//convert to positive
s.l = Math::abs(s.l);
@@ -69,11 +66,13 @@ void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, Audi
float overdb = 2.08136898f * Math::linear2db(peak / threshold);
- if (overdb < 0.0) //we only care about what goes over to compress
+ if (overdb < 0.0) { //we only care about what goes over to compress
overdb = 0.0;
+ }
- if (overdb - rundb > 5) // diffeence is too large
+ if (overdb - rundb > 5) { // diffeence is too large
averatio = 4;
+ }
if (overdb > rundb) {
rundb = overdb + atcoef * (rundb - overdb);
@@ -104,8 +103,9 @@ void AudioEffectCompressorInstance::process(const AudioFrame *p_src_frames, Audi
gr_meter = grv;
} else {
gr_meter *= gr_meter_decay;
- if (gr_meter > 1)
+ if (gr_meter > 1) {
gr_meter = 1;
+ }
}
p_dst_frames[i] = p_src_frames[i] * grv * makeup * mix + p_src_frames[i] * (1.0 - mix);
@@ -127,76 +127,65 @@ Ref<AudioEffectInstance> AudioEffectCompressor::instance() {
}
void AudioEffectCompressor::set_threshold(float p_threshold) {
-
threshold = p_threshold;
}
float AudioEffectCompressor::get_threshold() const {
-
return threshold;
}
void AudioEffectCompressor::set_ratio(float p_ratio) {
-
ratio = p_ratio;
}
-float AudioEffectCompressor::get_ratio() const {
+float AudioEffectCompressor::get_ratio() const {
return ratio;
}
void AudioEffectCompressor::set_gain(float p_gain) {
-
gain = p_gain;
}
-float AudioEffectCompressor::get_gain() const {
+float AudioEffectCompressor::get_gain() const {
return gain;
}
void AudioEffectCompressor::set_attack_us(float p_attack_us) {
-
attack_us = p_attack_us;
}
-float AudioEffectCompressor::get_attack_us() const {
+float AudioEffectCompressor::get_attack_us() const {
return attack_us;
}
void AudioEffectCompressor::set_release_ms(float p_release_ms) {
-
release_ms = p_release_ms;
}
-float AudioEffectCompressor::get_release_ms() const {
+float AudioEffectCompressor::get_release_ms() const {
return release_ms;
}
void AudioEffectCompressor::set_mix(float p_mix) {
-
mix = p_mix;
}
-float AudioEffectCompressor::get_mix() const {
+float AudioEffectCompressor::get_mix() const {
return mix;
}
void AudioEffectCompressor::set_sidechain(const StringName &p_sidechain) {
-
AudioServer::get_singleton()->lock();
sidechain = p_sidechain;
AudioServer::get_singleton()->unlock();
}
StringName AudioEffectCompressor::get_sidechain() const {
-
return sidechain;
}
void AudioEffectCompressor::_validate_property(PropertyInfo &property) const {
-
if (property.name == "sidechain") {
-
String buses = "";
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
buses += ",";
@@ -208,7 +197,6 @@ void AudioEffectCompressor::_validate_property(PropertyInfo &property) const {
}
void AudioEffectCompressor::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_threshold", "threshold"), &AudioEffectCompressor::set_threshold);
ClassDB::bind_method(D_METHOD("get_threshold"), &AudioEffectCompressor::get_threshold);
diff --git a/servers/audio/effects/audio_effect_delay.cpp b/servers/audio/effects/audio_effect_delay.cpp
index fa57a94977..d6ab14be89 100644
--- a/servers/audio/effects/audio_effect_delay.cpp
+++ b/servers/audio/effects/audio_effect_delay.cpp
@@ -33,11 +33,9 @@
#include "servers/audio_server.h"
void AudioEffectDelayInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
int todo = p_frame_count;
while (todo) {
-
int to_mix = MIN(todo, 256); //can't mix too much
_process_chunk(p_src_frames, p_dst_frames, to_mix);
@@ -50,7 +48,6 @@ void AudioEffectDelayInstance::process(const AudioFrame *p_src_frames, AudioFram
}
void AudioEffectDelayInstance::_process_chunk(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
float main_level_f = base->dry;
float mix_rate = AudioServer::get_singleton()->get_mix_rate();
@@ -87,7 +84,6 @@ void AudioEffectDelayInstance::_process_chunk(const AudioFrame *p_src_frames, Au
AudioFrame *fb_buf = feedback_buffer.ptrw();
for (int i = 0; i < p_frame_count; i++) {
-
rb_buf[ring_buffer_pos & ring_buffer_mask] = src[i];
AudioFrame main_val = src[i] * main_level_f;
@@ -109,8 +105,9 @@ void AudioEffectDelayInstance::_process_chunk(const AudioFrame *p_src_frames, Au
ring_buffer_pos++;
- if ((++feedback_buffer_pos) >= feedback_delay_frames)
+ if ((++feedback_buffer_pos) >= feedback_delay_frames) {
feedback_buffer_pos = 0;
+ }
}
}
@@ -147,125 +144,110 @@ Ref<AudioEffectInstance> AudioEffectDelay::instance() {
}
void AudioEffectDelay::set_dry(float p_dry) {
-
dry = p_dry;
}
float AudioEffectDelay::get_dry() {
-
return dry;
}
void AudioEffectDelay::set_tap1_active(bool p_active) {
-
tap_1_active = p_active;
}
-bool AudioEffectDelay::is_tap1_active() const {
+bool AudioEffectDelay::is_tap1_active() const {
return tap_1_active;
}
void AudioEffectDelay::set_tap1_delay_ms(float p_delay_ms) {
-
tap_1_delay_ms = p_delay_ms;
}
-float AudioEffectDelay::get_tap1_delay_ms() const {
+float AudioEffectDelay::get_tap1_delay_ms() const {
return tap_1_delay_ms;
}
void AudioEffectDelay::set_tap1_level_db(float p_level_db) {
-
tap_1_level = p_level_db;
}
-float AudioEffectDelay::get_tap1_level_db() const {
+float AudioEffectDelay::get_tap1_level_db() const {
return tap_1_level;
}
void AudioEffectDelay::set_tap1_pan(float p_pan) {
-
tap_1_pan = p_pan;
}
-float AudioEffectDelay::get_tap1_pan() const {
+float AudioEffectDelay::get_tap1_pan() const {
return tap_1_pan;
}
void AudioEffectDelay::set_tap2_active(bool p_active) {
-
tap_2_active = p_active;
}
-bool AudioEffectDelay::is_tap2_active() const {
+bool AudioEffectDelay::is_tap2_active() const {
return tap_2_active;
}
void AudioEffectDelay::set_tap2_delay_ms(float p_delay_ms) {
-
tap_2_delay_ms = p_delay_ms;
}
-float AudioEffectDelay::get_tap2_delay_ms() const {
+float AudioEffectDelay::get_tap2_delay_ms() const {
return tap_2_delay_ms;
}
void AudioEffectDelay::set_tap2_level_db(float p_level_db) {
-
tap_2_level = p_level_db;
}
-float AudioEffectDelay::get_tap2_level_db() const {
+float AudioEffectDelay::get_tap2_level_db() const {
return tap_2_level;
}
void AudioEffectDelay::set_tap2_pan(float p_pan) {
-
tap_2_pan = p_pan;
}
-float AudioEffectDelay::get_tap2_pan() const {
+float AudioEffectDelay::get_tap2_pan() const {
return tap_2_pan;
}
void AudioEffectDelay::set_feedback_active(bool p_active) {
-
feedback_active = p_active;
}
-bool AudioEffectDelay::is_feedback_active() const {
+bool AudioEffectDelay::is_feedback_active() const {
return feedback_active;
}
void AudioEffectDelay::set_feedback_delay_ms(float p_delay_ms) {
-
feedback_delay_ms = p_delay_ms;
}
-float AudioEffectDelay::get_feedback_delay_ms() const {
+float AudioEffectDelay::get_feedback_delay_ms() const {
return feedback_delay_ms;
}
void AudioEffectDelay::set_feedback_level_db(float p_level_db) {
-
feedback_level = p_level_db;
}
-float AudioEffectDelay::get_feedback_level_db() const {
+float AudioEffectDelay::get_feedback_level_db() const {
return feedback_level;
}
void AudioEffectDelay::set_feedback_lowpass(float p_lowpass) {
-
feedback_lowpass = p_lowpass;
}
-float AudioEffectDelay::get_feedback_lowpass() const {
+float AudioEffectDelay::get_feedback_lowpass() const {
return feedback_lowpass;
}
void AudioEffectDelay::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_dry", "amount"), &AudioEffectDelay::set_dry);
ClassDB::bind_method(D_METHOD("get_dry"), &AudioEffectDelay::get_dry);
diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp
index bc4fc7ecd6..dc5c2cc16f 100644
--- a/servers/audio/effects/audio_effect_distortion.cpp
+++ b/servers/audio/effects/audio_effect_distortion.cpp
@@ -33,7 +33,6 @@
#include "servers/audio_server.h"
void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
const float *src = (const float *)p_src_frames;
float *dst = (float *)p_dst_frames;
@@ -51,7 +50,6 @@ void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, Audi
float lofi_mult = powf(2.0, 2.0 + (1.0 - drive_f) * 14); //goes from 16 to 2 bits
for (int i = 0; i < p_frame_count * 2; i++) {
-
float out = undenormalise(src[i] * lpf_ic + lpf_c * h[i & 1]);
h[i & 1] = out;
float a = out;
@@ -59,28 +57,24 @@ void AudioEffectDistortionInstance::process(const AudioFrame *p_src_frames, Audi
a *= pregain_f;
switch (base->mode) {
-
case AudioEffectDistortion::MODE_CLIP: {
-
a = powf(a, 1.0001 - drive_f);
- if (a > 1.0)
+ if (a > 1.0) {
a = 1.0;
- else if (a < (-1.0))
+ } else if (a < (-1.0)) {
a = -1.0;
+ }
} break;
case AudioEffectDistortion::MODE_ATAN: {
-
a = atanf(a * atan_mult) * atan_div;
} break;
case AudioEffectDistortion::MODE_LOFI: {
-
a = floorf(a * lofi_mult + 0.5) / lofi_mult;
} break;
case AudioEffectDistortion::MODE_OVERDRIVE: {
-
const double x = a * 0.686306;
const double z = 1 + exp(sqrt(fabs(x)) * -0.75);
a = (expf(x) - expf(-x * z)) / (expf(x) + expf(-x));
@@ -109,53 +103,46 @@ Ref<AudioEffectInstance> AudioEffectDistortion::instance() {
}
void AudioEffectDistortion::set_mode(Mode p_mode) {
-
mode = p_mode;
}
AudioEffectDistortion::Mode AudioEffectDistortion::get_mode() const {
-
return mode;
}
void AudioEffectDistortion::set_pre_gain(float p_pre_gain) {
-
pre_gain = p_pre_gain;
}
-float AudioEffectDistortion::get_pre_gain() const {
+float AudioEffectDistortion::get_pre_gain() const {
return pre_gain;
}
void AudioEffectDistortion::set_keep_hf_hz(float p_keep_hf_hz) {
-
keep_hf_hz = p_keep_hf_hz;
}
-float AudioEffectDistortion::get_keep_hf_hz() const {
+float AudioEffectDistortion::get_keep_hf_hz() const {
return keep_hf_hz;
}
void AudioEffectDistortion::set_drive(float p_drive) {
-
drive = p_drive;
}
-float AudioEffectDistortion::get_drive() const {
+float AudioEffectDistortion::get_drive() const {
return drive;
}
void AudioEffectDistortion::set_post_gain(float p_post_gain) {
-
post_gain = p_post_gain;
}
-float AudioEffectDistortion::get_post_gain() const {
+float AudioEffectDistortion::get_post_gain() const {
return post_gain;
}
void AudioEffectDistortion::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_mode", "mode"), &AudioEffectDistortion::set_mode);
ClassDB::bind_method(D_METHOD("get_mode"), &AudioEffectDistortion::get_mode);
diff --git a/servers/audio/effects/audio_effect_eq.cpp b/servers/audio/effects/audio_effect_eq.cpp
index b315fdc3bb..ed4e7122b5 100644
--- a/servers/audio/effects/audio_effect_eq.cpp
+++ b/servers/audio/effects/audio_effect_eq.cpp
@@ -32,7 +32,6 @@
#include "servers/audio_server.h"
void AudioEffectEQInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
int band_count = bands[0].size();
EQ::BandProcess *proc_l = bands[0].ptrw();
EQ::BandProcess *proc_r = bands[1].ptrw();
@@ -42,12 +41,10 @@ void AudioEffectEQInstance::process(const AudioFrame *p_src_frames, AudioFrame *
}
for (int i = 0; i < p_frame_count; i++) {
-
AudioFrame src = p_src_frames[i];
AudioFrame dst = AudioFrame(0, 0);
for (int j = 0; j < band_count; j++) {
-
float l = src.l;
float r = src.r;
@@ -87,12 +84,12 @@ float AudioEffectEQ::get_band_gain_db(int p_band) const {
return gain[p_band];
}
+
int AudioEffectEQ::get_band_count() const {
return gain.size();
}
bool AudioEffectEQ::_set(const StringName &p_name, const Variant &p_value) {
-
const Map<StringName, int>::Element *E = prop_band_map.find(p_name);
if (E) {
set_band_gain_db(E->get(), p_value);
@@ -103,7 +100,6 @@ bool AudioEffectEQ::_set(const StringName &p_name, const Variant &p_value) {
}
bool AudioEffectEQ::_get(const StringName &p_name, Variant &r_ret) const {
-
const Map<StringName, int>::Element *E = prop_band_map.find(p_name);
if (E) {
r_ret = get_band_gain_db(E->get());
@@ -114,22 +110,18 @@ bool AudioEffectEQ::_get(const StringName &p_name, Variant &r_ret) const {
}
void AudioEffectEQ::_get_property_list(List<PropertyInfo> *p_list) const {
-
for (int i = 0; i < band_names.size(); i++) {
-
p_list->push_back(PropertyInfo(Variant::FLOAT, band_names[i], PROPERTY_HINT_RANGE, "-60,24,0.1"));
}
}
void AudioEffectEQ::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_band_gain_db", "band_idx", "volume_db"), &AudioEffectEQ::set_band_gain_db);
ClassDB::bind_method(D_METHOD("get_band_gain_db", "band_idx"), &AudioEffectEQ::get_band_gain_db);
ClassDB::bind_method(D_METHOD("get_band_count"), &AudioEffectEQ::get_band_count);
}
AudioEffectEQ::AudioEffectEQ(EQ::Preset p_preset) {
-
eq.set_mix_rate(AudioServer::get_singleton()->get_mix_rate());
eq.set_preset_band_mode(p_preset);
gain.resize(eq.get_band_count());
diff --git a/servers/audio/effects/audio_effect_filter.cpp b/servers/audio/effects/audio_effect_filter.cpp
index 18047bc99e..a5135ee1a6 100644
--- a/servers/audio/effects/audio_effect_filter.cpp
+++ b/servers/audio/effects/audio_effect_filter.cpp
@@ -33,16 +33,18 @@
template <int S>
void AudioEffectFilterInstance::_process_filter(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
for (int i = 0; i < p_frame_count; i++) {
float f = p_src_frames[i].l;
filter_process[0][0].process_one(f);
- if (S > 1)
+ if (S > 1) {
filter_process[0][1].process_one(f);
- if (S > 2)
+ }
+ if (S > 2) {
filter_process[0][2].process_one(f);
- if (S > 3)
+ }
+ if (S > 3) {
filter_process[0][3].process_one(f);
+ }
p_dst_frames[i].l = f;
}
@@ -50,19 +52,21 @@ void AudioEffectFilterInstance::_process_filter(const AudioFrame *p_src_frames,
for (int i = 0; i < p_frame_count; i++) {
float f = p_src_frames[i].r;
filter_process[1][0].process_one(f);
- if (S > 1)
+ if (S > 1) {
filter_process[1][1].process_one(f);
- if (S > 2)
+ }
+ if (S > 2) {
filter_process[1][2].process_one(f);
- if (S > 3)
+ }
+ if (S > 3) {
filter_process[1][3].process_one(f);
+ }
p_dst_frames[i].r = f;
}
}
void AudioEffectFilterInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
filter.set_cutoff(base->cutoff);
filter.set_gain(base->gain);
filter.set_resonance(base->resonance);
@@ -89,7 +93,6 @@ void AudioEffectFilterInstance::process(const AudioFrame *p_src_frames, AudioFra
}
AudioEffectFilterInstance::AudioEffectFilterInstance() {
-
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 4; j++) {
filter_process[i][j].set_filter(&filter);
@@ -106,30 +109,26 @@ Ref<AudioEffectInstance> AudioEffectFilter::instance() {
}
void AudioEffectFilter::set_cutoff(float p_freq) {
-
cutoff = p_freq;
}
float AudioEffectFilter::get_cutoff() const {
-
return cutoff;
}
void AudioEffectFilter::set_resonance(float p_amount) {
-
resonance = p_amount;
}
-float AudioEffectFilter::get_resonance() const {
+float AudioEffectFilter::get_resonance() const {
return resonance;
}
void AudioEffectFilter::set_gain(float p_amount) {
-
gain = p_amount;
}
-float AudioEffectFilter::get_gain() const {
+float AudioEffectFilter::get_gain() const {
return gain;
}
@@ -138,12 +137,10 @@ void AudioEffectFilter::set_db(FilterDB p_db) {
}
AudioEffectFilter::FilterDB AudioEffectFilter::get_db() const {
-
return db;
}
void AudioEffectFilter::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_cutoff", "freq"), &AudioEffectFilter::set_cutoff);
ClassDB::bind_method(D_METHOD("get_cutoff"), &AudioEffectFilter::get_cutoff);
@@ -168,7 +165,6 @@ void AudioEffectFilter::_bind_methods() {
}
AudioEffectFilter::AudioEffectFilter(AudioFilterSW::Mode p_mode) {
-
mode = p_mode;
cutoff = 2000;
resonance = 0.5;
diff --git a/servers/audio/effects/audio_effect_filter.h b/servers/audio/effects/audio_effect_filter.h
index 0088118d8c..b11a4e3623 100644
--- a/servers/audio/effects/audio_effect_filter.h
+++ b/servers/audio/effects/audio_effect_filter.h
@@ -99,7 +99,9 @@ class AudioEffectLowPassFilter : public AudioEffectFilter {
GDCLASS(AudioEffectLowPassFilter, AudioEffectFilter);
void _validate_property(PropertyInfo &property) const {
- if (property.name == "gain") property.usage = 0;
+ if (property.name == "gain") {
+ property.usage = 0;
+ }
}
public:
@@ -110,7 +112,9 @@ public:
class AudioEffectHighPassFilter : public AudioEffectFilter {
GDCLASS(AudioEffectHighPassFilter, AudioEffectFilter);
void _validate_property(PropertyInfo &property) const {
- if (property.name == "gain") property.usage = 0;
+ if (property.name == "gain") {
+ property.usage = 0;
+ }
}
public:
@@ -121,7 +125,9 @@ public:
class AudioEffectBandPassFilter : public AudioEffectFilter {
GDCLASS(AudioEffectBandPassFilter, AudioEffectFilter);
void _validate_property(PropertyInfo &property) const {
- if (property.name == "gain") property.usage = 0;
+ if (property.name == "gain") {
+ property.usage = 0;
+ }
}
public:
diff --git a/servers/audio/effects/audio_effect_limiter.cpp b/servers/audio/effects/audio_effect_limiter.cpp
index 40a4243168..27f1aaf71f 100644
--- a/servers/audio/effects/audio_effect_limiter.cpp
+++ b/servers/audio/effects/audio_effect_limiter.cpp
@@ -31,7 +31,6 @@
#include "audio_effect_limiter.h"
void AudioEffectLimiterInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
float threshdb = base->threshold;
float ceiling = Math::db2linear(base->ceiling);
float ceildb = base->ceiling;
@@ -42,7 +41,6 @@ void AudioEffectLimiterInstance::process(const AudioFrame *p_src_frames, AudioFr
float scmult = Math::abs((ceildb - sc) / (peakdb - sc));
for (int i = 0; i < p_frame_count; i++) {
-
float spl0 = p_src_frames[i].l;
float spl1 = p_src_frames[i].r;
spl0 = spl0 * makeup;
@@ -78,44 +76,38 @@ Ref<AudioEffectInstance> AudioEffectLimiter::instance() {
}
void AudioEffectLimiter::set_threshold_db(float p_threshold) {
-
threshold = p_threshold;
}
float AudioEffectLimiter::get_threshold_db() const {
-
return threshold;
}
void AudioEffectLimiter::set_ceiling_db(float p_ceiling) {
-
ceiling = p_ceiling;
}
-float AudioEffectLimiter::get_ceiling_db() const {
+float AudioEffectLimiter::get_ceiling_db() const {
return ceiling;
}
void AudioEffectLimiter::set_soft_clip_db(float p_soft_clip) {
-
soft_clip = p_soft_clip;
}
-float AudioEffectLimiter::get_soft_clip_db() const {
+float AudioEffectLimiter::get_soft_clip_db() const {
return soft_clip;
}
void AudioEffectLimiter::set_soft_clip_ratio(float p_soft_clip) {
-
soft_clip_ratio = p_soft_clip;
}
-float AudioEffectLimiter::get_soft_clip_ratio() const {
+float AudioEffectLimiter::get_soft_clip_ratio() const {
return soft_clip_ratio;
}
void AudioEffectLimiter::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_ceiling_db", "ceiling"), &AudioEffectLimiter::set_ceiling_db);
ClassDB::bind_method(D_METHOD("get_ceiling_db"), &AudioEffectLimiter::get_ceiling_db);
diff --git a/servers/audio/effects/audio_effect_panner.cpp b/servers/audio/effects/audio_effect_panner.cpp
index 10724175e5..32b7921d1f 100644
--- a/servers/audio/effects/audio_effect_panner.cpp
+++ b/servers/audio/effects/audio_effect_panner.cpp
@@ -31,12 +31,10 @@
#include "audio_effect_panner.h"
void AudioEffectPannerInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
float lvol = CLAMP(1.0 - base->pan, 0, 1);
float rvol = CLAMP(1.0 + base->pan, 0, 1);
for (int i = 0; i < p_frame_count; i++) {
-
p_dst_frames[i].l = p_src_frames[i].l * lvol + p_src_frames[i].r * (1.0 - rvol);
p_dst_frames[i].r = p_src_frames[i].r * rvol + p_src_frames[i].l * (1.0 - lvol);
}
@@ -54,12 +52,10 @@ void AudioEffectPanner::set_pan(float p_cpanume) {
}
float AudioEffectPanner::get_pan() const {
-
return pan;
}
void AudioEffectPanner::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_pan", "cpanume"), &AudioEffectPanner::set_pan);
ClassDB::bind_method(D_METHOD("get_pan"), &AudioEffectPanner::get_pan);
diff --git a/servers/audio/effects/audio_effect_phaser.cpp b/servers/audio/effects/audio_effect_phaser.cpp
index 3709b69d45..ffeaa7d25e 100644
--- a/servers/audio/effects/audio_effect_phaser.cpp
+++ b/servers/audio/effects/audio_effect_phaser.cpp
@@ -33,7 +33,6 @@
#include "servers/audio_server.h"
void AudioEffectPhaserInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
float sampling_rate = AudioServer::get_singleton()->get_mix_rate();
float dmin = base->range_min / (sampling_rate / 2.0);
@@ -42,7 +41,6 @@ void AudioEffectPhaserInstance::process(const AudioFrame *p_src_frames, AudioFra
float increment = 2.f * Math_PI * (base->rate / sampling_rate);
for (int i = 0; i < p_frame_count; i++) {
-
phase += increment;
while (phase >= Math_PI * 2.f) {
@@ -91,54 +89,46 @@ Ref<AudioEffectInstance> AudioEffectPhaser::instance() {
}
void AudioEffectPhaser::set_range_min_hz(float p_hz) {
-
range_min = p_hz;
}
float AudioEffectPhaser::get_range_min_hz() const {
-
return range_min;
}
void AudioEffectPhaser::set_range_max_hz(float p_hz) {
-
range_max = p_hz;
}
-float AudioEffectPhaser::get_range_max_hz() const {
+float AudioEffectPhaser::get_range_max_hz() const {
return range_max;
}
void AudioEffectPhaser::set_rate_hz(float p_hz) {
-
rate = p_hz;
}
-float AudioEffectPhaser::get_rate_hz() const {
+float AudioEffectPhaser::get_rate_hz() const {
return rate;
}
void AudioEffectPhaser::set_feedback(float p_fbk) {
-
feedback = p_fbk;
}
-float AudioEffectPhaser::get_feedback() const {
+float AudioEffectPhaser::get_feedback() const {
return feedback;
}
void AudioEffectPhaser::set_depth(float p_depth) {
-
depth = p_depth;
}
float AudioEffectPhaser::get_depth() const {
-
return depth;
}
void AudioEffectPhaser::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_range_min_hz", "hz"), &AudioEffectPhaser::set_range_min_hz);
ClassDB::bind_method(D_METHOD("get_range_min_hz"), &AudioEffectPhaser::get_range_min_hz);
diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp
index a74ac3c007..fb6b56d984 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.cpp
+++ b/servers/audio/effects/audio_effect_pitch_shift.cpp
@@ -94,7 +94,9 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
freqPerBin = sampleRate/(double)fftFrameSize;
expct = 2.*Math_PI*(double)stepSize/(double)fftFrameSize;
inFifoLatency = fftFrameSize-stepSize;
- if (gRover == 0) gRover = inFifoLatency;
+ if (gRover == 0) { gRover = inFifoLatency;
+
+}
/* initialize our static arrays */
@@ -142,8 +144,10 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
/* map delta phase into +/- Pi interval */
qpd = tmp/Math_PI;
- if (qpd >= 0) qpd += qpd&1;
- else qpd -= qpd&1;
+ if (qpd >= 0) { qpd += qpd&1;
+ } else { qpd -= qpd&1;
+
+}
tmp -= Math_PI*(double)qpd;
/* get deviation from bin frequency from the +/- Pi interval */
@@ -200,7 +204,9 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
}
/* zero negative frequencies */
- for (k = fftFrameSize+2; k < 2*fftFrameSize; k++) gFFTworksp[k] = 0.;
+ for (k = fftFrameSize+2; k < 2*fftFrameSize; k++) { gFFTworksp[k] = 0.;
+
+}
/* do inverse transform */
smbFft(gFFTworksp, fftFrameSize, 1);
@@ -210,13 +216,17 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
window = -.5*cos(2.*Math_PI*(double)k/(double)fftFrameSize)+.5;
gOutputAccum[k] += 2.*window*gFFTworksp[2*k]/(fftFrameSize2*osamp);
}
- for (k = 0; k < stepSize; k++) gOutFIFO[k] = gOutputAccum[k];
+ for (k = 0; k < stepSize; k++) { gOutFIFO[k] = gOutputAccum[k];
+
+}
/* shift accumulator */
memmove(gOutputAccum, gOutputAccum+stepSize, fftFrameSize*sizeof(float));
/* move input FIFO */
- for (k = 0; k < inFifoLatency; k++) gInFIFO[k] = gInFIFO[k+stepSize];
+ for (k = 0; k < inFifoLatency; k++) { gInFIFO[k] = gInFIFO[k+stepSize];
+
+}
}
}
@@ -225,6 +235,7 @@ void SMBPitchShift::PitchShift(float pitchShift, long numSampsToProcess, long ff
}
+
void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
/*
FFT routine, (C)1996 S.M.Bernsee. Sign = -1 is FFT, 1 is iFFT (inverse)
@@ -244,7 +255,9 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
for (i = 2; i < 2*fftFrameSize-2; i += 2) {
for (bitm = 2, j = 0; bitm < 2*fftFrameSize; bitm <<= 1) {
- if (i & bitm) j++;
+ if (i & bitm) { j++;
+
+}
j <<= 1;
}
if (i < j) {
@@ -280,11 +293,11 @@ void SMBPitchShift::smbFft(float *fftBuffer, long fftFrameSize, long sign)
}
}
+
/* Godot code again */
/* clang-format on */
void AudioEffectPitchShiftInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
float sample_rate = AudioServer::get_singleton()->get_mix_rate();
float *in_l = (float *)p_src_frames;
@@ -313,7 +326,6 @@ void AudioEffectPitchShift::set_pitch_scale(float p_pitch_scale) {
}
float AudioEffectPitchShift::get_pitch_scale() const {
-
return pitch_scale;
}
@@ -323,7 +335,6 @@ void AudioEffectPitchShift::set_oversampling(int p_oversampling) {
}
int AudioEffectPitchShift::get_oversampling() const {
-
return oversampling;
}
@@ -337,7 +348,6 @@ AudioEffectPitchShift::FFT_Size AudioEffectPitchShift::get_fft_size() const {
}
void AudioEffectPitchShift::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_pitch_scale", "rate"), &AudioEffectPitchShift::set_pitch_scale);
ClassDB::bind_method(D_METHOD("get_pitch_scale"), &AudioEffectPitchShift::get_pitch_scale);
diff --git a/servers/audio/effects/audio_effect_pitch_shift.h b/servers/audio/effects/audio_effect_pitch_shift.h
index c6528bafa9..48f8e5dc39 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.h
+++ b/servers/audio/effects/audio_effect_pitch_shift.h
@@ -34,7 +34,6 @@
#include "servers/audio/audio_effect.h"
class SMBPitchShift {
-
enum {
MAX_FRAME_LENGTH = 8192
};
diff --git a/servers/audio/effects/audio_effect_record.cpp b/servers/audio/effects/audio_effect_record.cpp
index f2784679b5..79388b2dc7 100644
--- a/servers/audio/effects/audio_effect_record.cpp
+++ b/servers/audio/effects/audio_effect_record.cpp
@@ -101,7 +101,6 @@ void AudioEffectRecordInstance::_io_store_buffer() {
}
void AudioEffectRecordInstance::_thread_callback(void *_instance) {
-
AudioEffectRecordInstance *aeri = reinterpret_cast<AudioEffectRecordInstance *>(_instance);
aeri->_io_thread_process();
@@ -124,7 +123,6 @@ void AudioEffectRecordInstance::init() {
}
void AudioEffectRecordInstance::finish() {
-
#ifdef NO_THREADS
AudioServer::get_singleton()->remove_update_callback(&AudioEffectRecordInstance::_update, this);
#else
@@ -135,7 +133,6 @@ void AudioEffectRecordInstance::finish() {
}
AudioEffectRecordInstance::~AudioEffectRecordInstance() {
-
finish();
}
diff --git a/servers/audio/effects/audio_effect_record.h b/servers/audio/effects/audio_effect_record.h
index 09101033be..68d968c04b 100644
--- a/servers/audio/effects/audio_effect_record.h
+++ b/servers/audio/effects/audio_effect_record.h
@@ -49,7 +49,7 @@ class AudioEffectRecordInstance : public AudioEffectInstance {
bool is_recording;
Thread *io_thread;
- bool thread_active;
+ bool thread_active = false;
Vector<AudioFrame> ring_buffer;
Vector<float> recording_data;
@@ -71,8 +71,7 @@ public:
virtual void process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count);
virtual bool process_silence() const;
- AudioEffectRecordInstance() :
- thread_active(false) {}
+ AudioEffectRecordInstance() {}
~AudioEffectRecordInstance();
};
diff --git a/servers/audio/effects/audio_effect_reverb.cpp b/servers/audio/effects/audio_effect_reverb.cpp
index 6dccb2945b..f6465abfaf 100644
--- a/servers/audio/effects/audio_effect_reverb.cpp
+++ b/servers/audio/effects/audio_effect_reverb.cpp
@@ -31,7 +31,6 @@
#include "audio_effect_reverb.h"
#include "servers/audio_server.h"
void AudioEffectReverbInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
for (int i = 0; i < 2; i++) {
Reverb &r = reverb[i];
@@ -49,7 +48,6 @@ void AudioEffectReverbInstance::process(const AudioFrame *p_src_frames, AudioFra
int offset = 0;
while (todo) {
-
int to_mix = MIN(todo, Reverb::INPUT_BUFFER_MAX_SIZE);
for (int j = 0; j < to_mix; j++) {
@@ -75,7 +73,6 @@ void AudioEffectReverbInstance::process(const AudioFrame *p_src_frames, AudioFra
}
AudioEffectReverbInstance::AudioEffectReverbInstance() {
-
reverb[0].set_mix_rate(AudioServer::get_singleton()->get_mix_rate());
reverb[0].set_extra_spread_base(0);
reverb[1].set_mix_rate(AudioServer::get_singleton()->get_mix_rate());
@@ -90,75 +87,70 @@ Ref<AudioEffectInstance> AudioEffectReverb::instance() {
}
void AudioEffectReverb::set_predelay_msec(float p_msec) {
-
predelay = p_msec;
}
void AudioEffectReverb::set_predelay_feedback(float p_feedback) {
-
predelay_fb = CLAMP(p_feedback, 0, 0.98);
}
-void AudioEffectReverb::set_room_size(float p_size) {
+void AudioEffectReverb::set_room_size(float p_size) {
room_size = p_size;
}
-void AudioEffectReverb::set_damping(float p_damping) {
+void AudioEffectReverb::set_damping(float p_damping) {
damping = p_damping;
}
-void AudioEffectReverb::set_spread(float p_spread) {
+void AudioEffectReverb::set_spread(float p_spread) {
spread = p_spread;
}
void AudioEffectReverb::set_dry(float p_dry) {
-
dry = p_dry;
}
-void AudioEffectReverb::set_wet(float p_wet) {
+void AudioEffectReverb::set_wet(float p_wet) {
wet = p_wet;
}
-void AudioEffectReverb::set_hpf(float p_hpf) {
+void AudioEffectReverb::set_hpf(float p_hpf) {
hpf = p_hpf;
}
float AudioEffectReverb::get_predelay_msec() const {
-
return predelay;
}
-float AudioEffectReverb::get_predelay_feedback() const {
+float AudioEffectReverb::get_predelay_feedback() const {
return predelay_fb;
}
-float AudioEffectReverb::get_room_size() const {
+float AudioEffectReverb::get_room_size() const {
return room_size;
}
-float AudioEffectReverb::get_damping() const {
+float AudioEffectReverb::get_damping() const {
return damping;
}
-float AudioEffectReverb::get_spread() const {
+float AudioEffectReverb::get_spread() const {
return spread;
}
-float AudioEffectReverb::get_dry() const {
+float AudioEffectReverb::get_dry() const {
return dry;
}
-float AudioEffectReverb::get_wet() const {
+float AudioEffectReverb::get_wet() const {
return wet;
}
-float AudioEffectReverb::get_hpf() const {
+float AudioEffectReverb::get_hpf() const {
return hpf;
}
void AudioEffectReverb::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_predelay_msec", "msec"), &AudioEffectReverb::set_predelay_msec);
ClassDB::bind_method(D_METHOD("get_predelay_msec"), &AudioEffectReverb::get_predelay_msec);
diff --git a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
index 47aee02de2..e744dbf9b0 100644
--- a/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
+++ b/servers/audio/effects/audio_effect_spectrum_analyzer.cpp
@@ -50,7 +50,9 @@ static void smbFft(float *fftBuffer, long fftFrameSize, long sign)
for (i = 2; i < 2 * fftFrameSize - 2; i += 2) {
for (bitm = 2, j = 0; bitm < 2 * fftFrameSize; bitm <<= 1) {
- if (i & bitm) j++;
+ if (i & bitm) {
+ j++;
+ }
j <<= 1;
}
if (i < j) {
@@ -95,8 +97,8 @@ static void smbFft(float *fftBuffer, long fftFrameSize, long sign)
}
}
}
-void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
+void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
uint64_t time = OS::get_singleton()->get_ticks_usec();
//copy everything over first, since this only really does capture
@@ -148,14 +150,12 @@ void AudioEffectSpectrumAnalyzerInstance::process(const AudioFrame *p_src_frames
}
void AudioEffectSpectrumAnalyzerInstance::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_magnitude_for_frequency_range", "from_hz", "to_hz", "mode"), &AudioEffectSpectrumAnalyzerInstance::get_magnitude_for_frequency_range, DEFVAL(MAGNITUDE_MAX));
BIND_ENUM_CONSTANT(MAGNITUDE_AVERAGE);
BIND_ENUM_CONSTANT(MAGNITUDE_MAX);
}
Vector2 AudioEffectSpectrumAnalyzerInstance::get_magnitude_for_frequency_range(float p_begin, float p_end, MagnitudeMode p_mode) const {
-
if (last_fft_time == 0) {
return Vector2();
}
@@ -196,7 +196,6 @@ Vector2 AudioEffectSpectrumAnalyzerInstance::get_magnitude_for_frequency_range(f
return avg;
} else {
-
Vector2 max;
for (int i = begin_pos; i <= end_pos; i++) {
@@ -209,7 +208,6 @@ Vector2 AudioEffectSpectrumAnalyzerInstance::get_magnitude_for_frequency_range(f
}
Ref<AudioEffectInstance> AudioEffectSpectrumAnalyzer::instance() {
-
Ref<AudioEffectSpectrumAnalyzerInstance> ins;
ins.instance();
ins->base = Ref<AudioEffectSpectrumAnalyzer>(this);
@@ -236,7 +234,6 @@ void AudioEffectSpectrumAnalyzer::set_buffer_length(float p_seconds) {
}
float AudioEffectSpectrumAnalyzer::get_buffer_length() const {
-
return buffer_length;
}
@@ -258,7 +255,6 @@ AudioEffectSpectrumAnalyzer::FFT_Size AudioEffectSpectrumAnalyzer::get_fft_size(
}
void AudioEffectSpectrumAnalyzer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_buffer_length", "seconds"), &AudioEffectSpectrumAnalyzer::set_buffer_length);
ClassDB::bind_method(D_METHOD("get_buffer_length"), &AudioEffectSpectrumAnalyzer::get_buffer_length);
diff --git a/servers/audio/effects/audio_effect_stereo_enhance.cpp b/servers/audio/effects/audio_effect_stereo_enhance.cpp
index a10aca02b2..4f9bee83e4 100644
--- a/servers/audio/effects/audio_effect_stereo_enhance.cpp
+++ b/servers/audio/effects/audio_effect_stereo_enhance.cpp
@@ -31,14 +31,12 @@
#include "audio_effect_stereo_enhance.h"
#include "servers/audio_server.h"
void AudioEffectStereoEnhanceInstance::process(const AudioFrame *p_src_frames, AudioFrame *p_dst_frames, int p_frame_count) {
-
float intensity = base->pan_pullout;
bool surround_mode = base->surround > 0;
float surround_amount = base->surround;
unsigned int delay_frames = (base->time_pullout / 1000.0) * AudioServer::get_singleton()->get_mix_rate();
for (int i = 0; i < p_frame_count; i++) {
-
float l = p_src_frames[i].l;
float r = p_src_frames[i].r;
@@ -48,7 +46,6 @@ void AudioEffectStereoEnhanceInstance::process(const AudioFrame *p_src_frames, A
r = (center + (r - center) * intensity);
if (surround_mode) {
-
float val = (l + r) / 2.0;
delay_ringbuff[ringbuff_pos & ringbuff_mask] = val;
@@ -58,7 +55,6 @@ void AudioEffectStereoEnhanceInstance::process(const AudioFrame *p_src_frames, A
l += out;
r += -out;
} else {
-
float val = r;
delay_ringbuff[ringbuff_pos & ringbuff_mask] = val;
@@ -75,7 +71,6 @@ void AudioEffectStereoEnhanceInstance::process(const AudioFrame *p_src_frames, A
}
AudioEffectStereoEnhanceInstance::~AudioEffectStereoEnhanceInstance() {
-
memdelete_arr(delay_ringbuff);
}
@@ -108,35 +103,30 @@ Ref<AudioEffectInstance> AudioEffectStereoEnhance::instance() {
}
void AudioEffectStereoEnhance::set_pan_pullout(float p_amount) {
-
pan_pullout = p_amount;
}
float AudioEffectStereoEnhance::get_pan_pullout() const {
-
return pan_pullout;
}
void AudioEffectStereoEnhance::set_time_pullout(float p_amount) {
-
time_pullout = p_amount;
}
-float AudioEffectStereoEnhance::get_time_pullout() const {
+float AudioEffectStereoEnhance::get_time_pullout() const {
return time_pullout;
}
void AudioEffectStereoEnhance::set_surround(float p_amount) {
-
surround = p_amount;
}
-float AudioEffectStereoEnhance::get_surround() const {
+float AudioEffectStereoEnhance::get_surround() const {
return surround;
}
void AudioEffectStereoEnhance::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_pan_pullout", "amount"), &AudioEffectStereoEnhance::set_pan_pullout);
ClassDB::bind_method(D_METHOD("get_pan_pullout"), &AudioEffectStereoEnhance::get_pan_pullout);
diff --git a/servers/audio/effects/audio_stream_generator.cpp b/servers/audio/effects/audio_stream_generator.cpp
index d272a2cdf7..aba04550db 100644
--- a/servers/audio/effects/audio_stream_generator.cpp
+++ b/servers/audio/effects/audio_stream_generator.cpp
@@ -35,21 +35,18 @@ void AudioStreamGenerator::set_mix_rate(float p_mix_rate) {
}
float AudioStreamGenerator::get_mix_rate() const {
-
return mix_rate;
}
void AudioStreamGenerator::set_buffer_length(float p_seconds) {
-
buffer_len = p_seconds;
}
-float AudioStreamGenerator::get_buffer_length() const {
+float AudioStreamGenerator::get_buffer_length() const {
return buffer_len;
}
Ref<AudioStreamPlayback> AudioStreamGenerator::instance_playback() {
-
Ref<AudioStreamGeneratorPlayback> playback;
playback.instance();
playback->generator = this;
@@ -58,8 +55,8 @@ Ref<AudioStreamPlayback> AudioStreamGenerator::instance_playback() {
playback->buffer.clear();
return playback;
}
-String AudioStreamGenerator::get_stream_name() const {
+String AudioStreamGenerator::get_stream_name() const {
return "UserFeed";
}
@@ -99,8 +96,8 @@ bool AudioStreamGeneratorPlayback::push_frame(const Vector2 &p_frame) {
bool AudioStreamGeneratorPlayback::can_push_buffer(int p_frames) const {
return buffer.space_left() >= p_frames;
}
-bool AudioStreamGeneratorPlayback::push_buffer(const PackedVector2Array &p_frames) {
+bool AudioStreamGeneratorPlayback::push_buffer(const PackedVector2Array &p_frames) {
int to_write = p_frames.size();
if (buffer.space_left() < to_write) {
return false;
@@ -115,7 +112,6 @@ bool AudioStreamGeneratorPlayback::push_buffer(const PackedVector2Array &p_frame
AudioFrame buf[2048];
int ofs = 0;
while (to_write) {
-
int w = MIN(to_write, 2048);
for (int i = 0; i < w; i++) {
buf[i] = r[i + ofs];
@@ -143,7 +139,6 @@ void AudioStreamGeneratorPlayback::clear_buffer() {
}
void AudioStreamGeneratorPlayback::_mix_internal(AudioFrame *p_buffer, int p_frames) {
-
int read_amount = buffer.data_left();
if (p_frames < read_amount) {
read_amount = p_frames;
@@ -162,12 +157,12 @@ void AudioStreamGeneratorPlayback::_mix_internal(AudioFrame *p_buffer, int p_fra
mixed += p_frames / generator->get_mix_rate();
}
+
float AudioStreamGeneratorPlayback::get_stream_sampling_rate() {
return generator->get_mix_rate();
}
void AudioStreamGeneratorPlayback::start(float p_from_pos) {
-
if (mixed == 0.0) {
_begin_resample();
}
@@ -179,8 +174,8 @@ void AudioStreamGeneratorPlayback::start(float p_from_pos) {
void AudioStreamGeneratorPlayback::stop() {
active = false;
}
-bool AudioStreamGeneratorPlayback::is_playing() const {
+bool AudioStreamGeneratorPlayback::is_playing() const {
return active; //always playing, can't be stopped
}
@@ -191,6 +186,7 @@ int AudioStreamGeneratorPlayback::get_loop_count() const {
float AudioStreamGeneratorPlayback::get_playback_position() const {
return mixed;
}
+
void AudioStreamGeneratorPlayback::seek(float p_time) {
//no seek possible
}
diff --git a/servers/audio/effects/audio_stream_generator.h b/servers/audio/effects/audio_stream_generator.h
index aee3459e17..763d913684 100644
--- a/servers/audio/effects/audio_stream_generator.h
+++ b/servers/audio/effects/audio_stream_generator.h
@@ -58,7 +58,6 @@ public:
};
class AudioStreamGeneratorPlayback : public AudioStreamPlaybackResampled {
-
GDCLASS(AudioStreamGeneratorPlayback, AudioStreamPlaybackResampled);
friend class AudioStreamGenerator;
RingBuffer<AudioFrame> buffer;
diff --git a/servers/audio/effects/eq.cpp b/servers/audio/effects/eq.cpp
index 426f178dcb..08a6cf55fa 100644
--- a/servers/audio/effects/eq.cpp
+++ b/servers/audio/effects/eq.cpp
@@ -42,48 +42,45 @@ static int solve_quadratic(double a, double b, double c, double *r1, double *r2)
//solves quadractic and returns number of roots
double base = 2 * a;
- if (base == 0.0f)
+ if (base == 0.0f) {
return 0;
+ }
double squared = b * b - 4 * a * c;
- if (squared < 0.0)
+ if (squared < 0.0) {
return 0;
+ }
squared = sqrt(squared);
*r1 = (-b + squared) / base;
*r2 = (-b - squared) / base;
- if (*r1 == *r2)
+ if (*r1 == *r2) {
return 1;
- else
+ } else {
return 2;
+ }
}
EQ::BandProcess::BandProcess() {
-
c1 = c2 = c3 = history.a1 = history.a2 = history.a3 = 0;
history.b1 = history.b2 = history.b3 = 0;
}
void EQ::recalculate_band_coefficients() {
-
#define BAND_LOG(m_f) (log((m_f)) / log(2.))
for (int i = 0; i < band.size(); i++) {
-
double octave_size;
double frq = band[i].freq;
if (i == 0) {
-
octave_size = BAND_LOG(band[1].freq) - BAND_LOG(frq);
} else if (i == (band.size() - 1)) {
-
octave_size = BAND_LOG(frq) - BAND_LOG(band[i - 1].freq);
} else {
-
double next = BAND_LOG(band[i + 1].freq) - BAND_LOG(frq);
double prev = BAND_LOG(frq) - BAND_LOG(band[i - 1].freq);
octave_size = (next + prev) / 2.0;
@@ -118,27 +115,24 @@ void EQ::recalculate_band_coefficients() {
}
void EQ::set_preset_band_mode(Preset p_preset) {
-
band.clear();
#define PUSH_BANDS(m_bands) \
for (int i = 0; i < m_bands; i++) { \
Band b; \
b.freq = bands[i]; \
+ b.c1 = b.c2 = b.c3 = 0; \
band.push_back(b); \
}
switch (p_preset) {
-
case PRESET_6_BANDS: {
-
static const double bands[] = { 32, 100, 320, 1e3, 3200, 10e3 };
PUSH_BANDS(6);
} break;
case PRESET_8_BANDS: {
-
static const double bands[] = { 32, 72, 192, 512, 1200, 3000, 7500, 16e3 };
PUSH_BANDS(8);
@@ -152,14 +146,12 @@ void EQ::set_preset_band_mode(Preset p_preset) {
} break;
case PRESET_21_BANDS: {
-
static const double bands[] = { 22, 32, 44, 63, 90, 125, 175, 250, 350, 500, 700, 1e3, 1400, 2e3, 2800, 4e3, 5600, 8e3, 11e3, 16e3, 22e3 };
PUSH_BANDS(21);
} break;
case PRESET_31_BANDS: {
-
static const double bands[] = { 20, 25, 31.5, 40, 50, 63, 80, 100, 125, 160, 200, 250, 315, 400, 500, 630, 800, 1e3, 1250, 1600, 2e3, 2500, 3150, 4e3, 5e3, 6300, 8e3, 10e3, 12500, 16e3, 20e3 };
PUSH_BANDS(31);
} break;
@@ -169,19 +161,17 @@ void EQ::set_preset_band_mode(Preset p_preset) {
}
int EQ::get_band_count() const {
-
return band.size();
}
-float EQ::get_band_frequency(int p_band) {
+float EQ::get_band_frequency(int p_band) {
ERR_FAIL_INDEX_V(p_band, band.size(), 0);
return band[p_band].freq;
}
-void EQ::set_bands(const Vector<float> &p_bands) {
+void EQ::set_bands(const Vector<float> &p_bands) {
band.resize(p_bands.size());
for (int i = 0; i < p_bands.size(); i++) {
-
band.write[i].freq = p_bands[i];
}
@@ -189,13 +179,11 @@ void EQ::set_bands(const Vector<float> &p_bands) {
}
void EQ::set_mix_rate(float p_mix_rate) {
-
mix_rate = p_mix_rate;
recalculate_band_coefficients();
}
EQ::BandProcess EQ::get_band_processor(int p_band) const {
-
EQ::BandProcess band_proc;
ERR_FAIL_INDEX_V(p_band, band.size(), band_proc);
diff --git a/servers/audio/effects/eq.h b/servers/audio/effects/eq.h
index 6c002effbf..391a7aa24b 100644
--- a/servers/audio/effects/eq.h
+++ b/servers/audio/effects/eq.h
@@ -52,7 +52,6 @@ public:
};
class BandProcess {
-
friend class EQ;
float c1, c2, c3;
struct History {
@@ -69,7 +68,6 @@ public:
private:
struct Band {
-
float freq;
float c1, c2, c3;
};
@@ -96,7 +94,6 @@ public:
/* Inline Function */
inline void EQ::BandProcess::process_one(float &p_data) {
-
history.a1 = p_data;
history.b1 = c1 * (history.a1 - history.a3) + c3 * history.b2 - c2 * history.b3;
diff --git a/servers/audio/effects/reverb.cpp b/servers/audio/effects/reverb.cpp
index ea2174f1d4..7c35d88ced 100644
--- a/servers/audio/effects/reverb.cpp
+++ b/servers/audio/effects/reverb.cpp
@@ -31,7 +31,9 @@
// Author: Juan Linietsky <reduzio@gmail.com>, (C) 2006
#include "reverb.h"
+
#include "core/math/math_funcs.h"
+
#include <math.h>
const float Reverb::comb_tunings[MAX_COMBS] = {
@@ -55,24 +57,27 @@ const float Reverb::allpass_tunings[MAX_ALLPASS] = {
};
void Reverb::process(float *p_src, float *p_dst, int p_frames) {
-
- if (p_frames > INPUT_BUFFER_MAX_SIZE)
+ if (p_frames > INPUT_BUFFER_MAX_SIZE) {
p_frames = INPUT_BUFFER_MAX_SIZE;
+ }
int predelay_frames = lrint((params.predelay / 1000.0) * params.mix_rate);
- if (predelay_frames < 10)
+ if (predelay_frames < 10) {
predelay_frames = 10;
- if (predelay_frames >= echo_buffer_size)
+ }
+ if (predelay_frames >= echo_buffer_size) {
predelay_frames = echo_buffer_size - 1;
+ }
for (int i = 0; i < p_frames; i++) {
-
- if (echo_buffer_pos >= echo_buffer_size)
+ if (echo_buffer_pos >= echo_buffer_size) {
echo_buffer_pos = 0;
+ }
int read_pos = echo_buffer_pos - predelay_frames;
- while (read_pos < 0)
+ while (read_pos < 0) {
read_pos += echo_buffer_size;
+ }
float in = undenormalise(echo_buffer[read_pos] * params.predelay_fb + p_src[i]);
@@ -92,7 +97,6 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) {
float hp_b1 = hpaux;
for (int i = 0; i < p_frames; i++) {
-
float in = input_buffer[i];
input_buffer[i] = in * hp_a1 + hpf_h1 * hp_a2 + hpf_h2 * hp_b1;
hpf_h2 = input_buffer[i];
@@ -101,14 +105,13 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) {
}
for (int i = 0; i < MAX_COMBS; i++) {
-
Comb &c = comb[i];
int size_limit = c.size - lrintf((float)c.extra_spread_frames * (1.0 - params.extra_spread));
for (int j = 0; j < p_frames; j++) {
-
- if (c.pos >= size_limit) //reset this now just in case
+ if (c.pos >= size_limit) { //reset this now just in case
c.pos = 0;
+ }
float out = undenormalise(c.buffer[c.pos] * c.feedback);
out = out * (1.0 - c.damp) + c.damp_h * c.damp; //lowpass
@@ -155,14 +158,13 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) {
*/
for (int i = 0; i < MAX_ALLPASS; i++) {
-
AllPass &a = allpass[i];
int size_limit = a.size - lrintf((float)a.extra_spread_frames * (1.0 - params.extra_spread));
for (int j = 0; j < p_frames; j++) {
-
- if (a.pos >= size_limit)
+ if (a.pos >= size_limit) {
a.pos = 0;
+ }
float aux = a.buffer[a.pos];
a.buffer[a.pos] = undenormalise(allpass_feedback * aux + p_dst[j]);
@@ -174,108 +176,102 @@ void Reverb::process(float *p_src, float *p_dst, int p_frames) {
static const float wet_scale = 0.6;
for (int i = 0; i < p_frames; i++) {
-
p_dst[i] = p_dst[i] * params.wet * wet_scale + p_src[i] * params.dry;
}
}
void Reverb::set_room_size(float p_size) {
-
params.room_size = p_size;
update_parameters();
}
-void Reverb::set_damp(float p_damp) {
+void Reverb::set_damp(float p_damp) {
params.damp = p_damp;
update_parameters();
}
-void Reverb::set_wet(float p_wet) {
+void Reverb::set_wet(float p_wet) {
params.wet = p_wet;
}
void Reverb::set_dry(float p_dry) {
-
params.dry = p_dry;
}
void Reverb::set_predelay(float p_predelay) {
-
params.predelay = p_predelay;
}
-void Reverb::set_predelay_feedback(float p_predelay_fb) {
+void Reverb::set_predelay_feedback(float p_predelay_fb) {
params.predelay_fb = p_predelay_fb;
}
void Reverb::set_highpass(float p_frq) {
-
- if (p_frq > 1)
+ if (p_frq > 1) {
p_frq = 1;
- if (p_frq < 0)
+ }
+ if (p_frq < 0) {
p_frq = 0;
+ }
params.hpf = p_frq;
}
void Reverb::set_extra_spread(float p_spread) {
-
params.extra_spread = p_spread;
}
void Reverb::set_mix_rate(float p_mix_rate) {
-
params.mix_rate = p_mix_rate;
configure_buffers();
}
void Reverb::set_extra_spread_base(float p_sec) {
-
params.extra_spread_base = p_sec;
configure_buffers();
}
void Reverb::configure_buffers() {
-
clear_buffers(); //clear if necessary
for (int i = 0; i < MAX_COMBS; i++) {
-
Comb &c = comb[i];
c.extra_spread_frames = lrint(params.extra_spread_base * params.mix_rate);
int len = lrint(comb_tunings[i] * params.mix_rate) + c.extra_spread_frames;
- if (len < 5)
+ if (len < 5) {
len = 5; //may this happen?
+ }
c.buffer = memnew_arr(float, len);
c.pos = 0;
- for (int j = 0; j < len; j++)
+ for (int j = 0; j < len; j++) {
c.buffer[j] = 0;
+ }
c.size = len;
}
for (int i = 0; i < MAX_ALLPASS; i++) {
-
AllPass &a = allpass[i];
a.extra_spread_frames = lrint(params.extra_spread_base * params.mix_rate);
int len = lrint(allpass_tunings[i] * params.mix_rate) + a.extra_spread_frames;
- if (len < 5)
+ if (len < 5) {
len = 5; //may this happen?
+ }
a.buffer = memnew_arr(float, len);
a.pos = 0;
- for (int j = 0; j < len; j++)
+ for (int j = 0; j < len; j++) {
a.buffer[j] = 0;
+ }
a.size = len;
}
echo_buffer_size = (int)(((float)MAX_ECHO_MS / 1000.0) * params.mix_rate + 1.0);
echo_buffer = memnew_arr(float, echo_buffer_size);
for (int i = 0; i < echo_buffer_size; i++) {
-
echo_buffer[i] = 0;
}
@@ -283,19 +279,18 @@ void Reverb::configure_buffers() {
}
void Reverb::update_parameters() {
-
//more freeverb derived constants
static const float room_scale = 0.28f;
static const float room_offset = 0.7f;
for (int i = 0; i < MAX_COMBS; i++) {
-
Comb &c = comb[i];
c.feedback = room_offset + params.room_size * room_scale;
- if (c.feedback < room_offset)
+ if (c.feedback < room_offset) {
c.feedback = room_offset;
- else if (c.feedback > (room_offset + room_scale))
+ } else if (c.feedback > (room_offset + room_scale)) {
c.feedback = (room_offset + room_scale);
+ }
float auxdmp = params.damp / 2.0 + 0.5; //only half the range (0.5 .. 1.0 is enough)
auxdmp *= auxdmp;
@@ -305,29 +300,28 @@ void Reverb::update_parameters() {
}
void Reverb::clear_buffers() {
-
- if (echo_buffer)
+ if (echo_buffer) {
memdelete_arr(echo_buffer);
+ }
for (int i = 0; i < MAX_COMBS; i++) {
-
- if (comb[i].buffer)
+ if (comb[i].buffer) {
memdelete_arr(comb[i].buffer);
+ }
comb[i].buffer = nullptr;
}
for (int i = 0; i < MAX_ALLPASS; i++) {
-
- if (allpass[i].buffer)
+ if (allpass[i].buffer) {
memdelete_arr(allpass[i].buffer);
+ }
allpass[i].buffer = nullptr;
}
}
Reverb::Reverb() {
-
params.room_size = 0.8;
params.damp = 0.5;
params.dry = 1.0;
@@ -338,18 +332,14 @@ Reverb::Reverb() {
params.predelay = 150;
params.predelay_fb = 0.4;
params.hpf = 0;
- hpf_h1 = 0;
- hpf_h2 = 0;
input_buffer = memnew_arr(float, INPUT_BUFFER_MAX_SIZE);
- echo_buffer = nullptr;
configure_buffers();
update_parameters();
}
Reverb::~Reverb() {
-
memdelete_arr(input_buffer);
clear_buffers();
}
diff --git a/servers/audio/effects/reverb.h b/servers/audio/effects/reverb.h
index 92e4aed435..614de0c534 100644
--- a/servers/audio/effects/reverb.h
+++ b/servers/audio/effects/reverb.h
@@ -57,48 +57,35 @@ private:
static const float allpass_tunings[MAX_ALLPASS];
struct Comb {
-
- int size;
- float *buffer;
- float feedback;
- float damp; //lowpass
- float damp_h; //history
- int pos;
- int extra_spread_frames;
-
- Comb() {
- size = 0;
- buffer = 0;
- feedback = 0;
- damp_h = 0;
- pos = 0;
- }
+ int size = 0;
+ float *buffer = nullptr;
+ float feedback = 0;
+ float damp = 0; //lowpass
+ float damp_h = 0; //history
+ int pos = 0;
+ int extra_spread_frames = 0;
+
+ Comb() {}
};
struct AllPass {
-
- int size;
- float *buffer;
- int pos;
- int extra_spread_frames;
- AllPass() {
- size = 0;
- buffer = 0;
- pos = 0;
- }
+ int size = 0;
+ float *buffer = nullptr;
+ int pos = 0;
+ int extra_spread_frames = 0;
+ AllPass() {}
};
Comb comb[MAX_COMBS];
AllPass allpass[MAX_ALLPASS];
float *input_buffer;
- float *echo_buffer;
+ float *echo_buffer = nullptr;
int echo_buffer_size;
int echo_buffer_pos;
- float hpf_h1, hpf_h2;
+ float hpf_h1, hpf_h2 = 0;
struct Parameters {
-
float room_size;
float damp;
float wet;
diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp
index 90033d4a87..09d2914e05 100644
--- a/servers/audio_server.cpp
+++ b/servers/audio_server.cpp
@@ -47,45 +47,41 @@
AudioDriver *AudioDriver::singleton = nullptr;
AudioDriver *AudioDriver::get_singleton() {
-
return singleton;
}
void AudioDriver::set_singleton() {
-
singleton = this;
}
void AudioDriver::audio_server_process(int p_frames, int32_t *p_buffer, bool p_update_mix_time) {
-
- if (p_update_mix_time)
+ if (p_update_mix_time) {
update_mix_time(p_frames);
+ }
- if (AudioServer::get_singleton())
+ if (AudioServer::get_singleton()) {
AudioServer::get_singleton()->_driver_process(p_frames, p_buffer);
+ }
}
void AudioDriver::update_mix_time(int p_frames) {
-
_last_mix_frames = p_frames;
- if (OS::get_singleton())
+ if (OS::get_singleton()) {
_last_mix_time = OS::get_singleton()->get_ticks_usec();
+ }
}
double AudioDriver::get_time_since_last_mix() const {
-
return (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0;
}
double AudioDriver::get_time_to_next_mix() const {
-
double total = (OS::get_singleton()->get_ticks_usec() - _last_mix_time) / 1000000.0;
double mix_buffer = _last_mix_frames / (double)get_mix_rate();
return mix_buffer - total;
}
void AudioDriver::input_buffer_init(int driver_buffer_frames) {
-
const int input_buffer_channels = 2;
input_buffer.resize(driver_buffer_frames * input_buffer_channels * 4);
input_position = 0;
@@ -93,7 +89,6 @@ void AudioDriver::input_buffer_init(int driver_buffer_frames) {
}
void AudioDriver::input_buffer_write(int32_t sample) {
-
if ((int)input_position < input_buffer.size()) {
input_buffer.write[input_position++] = sample;
if ((int)input_position >= input_buffer.size()) {
@@ -109,9 +104,12 @@ void AudioDriver::input_buffer_write(int32_t sample) {
AudioDriver::SpeakerMode AudioDriver::get_speaker_mode_by_total_channels(int p_channels) const {
switch (p_channels) {
- case 4: return SPEAKER_SURROUND_31;
- case 6: return SPEAKER_SURROUND_51;
- case 8: return SPEAKER_SURROUND_71;
+ case 4:
+ return SPEAKER_SURROUND_31;
+ case 6:
+ return SPEAKER_SURROUND_51;
+ case 8:
+ return SPEAKER_SURROUND_71;
}
// Default to STEREO
@@ -120,10 +118,14 @@ AudioDriver::SpeakerMode AudioDriver::get_speaker_mode_by_total_channels(int p_c
int AudioDriver::get_total_channels_by_speaker_mode(AudioDriver::SpeakerMode p_mode) const {
switch (p_mode) {
- case SPEAKER_MODE_STEREO: return 2;
- case SPEAKER_SURROUND_31: return 4;
- case SPEAKER_SURROUND_51: return 6;
- case SPEAKER_SURROUND_71: return 8;
+ case SPEAKER_MODE_STEREO:
+ return 2;
+ case SPEAKER_SURROUND_31:
+ return 4;
+ case SPEAKER_SURROUND_51:
+ return 6;
+ case SPEAKER_SURROUND_71:
+ return 8;
}
ERR_FAIL_V(2);
@@ -150,7 +152,6 @@ Array AudioDriver::capture_get_device_list() {
}
AudioDriver::AudioDriver() {
-
_last_mix_time = 0;
_last_mix_frames = 0;
input_position = 0;
@@ -168,7 +169,6 @@ AudioDriver *AudioDriverManager::drivers[MAX_DRIVERS] = {
int AudioDriverManager::driver_count = 1;
void AudioDriverManager::add_driver(AudioDriver *p_driver) {
-
ERR_FAIL_COND(driver_count >= MAX_DRIVERS);
drivers[driver_count - 1] = p_driver;
@@ -177,12 +177,14 @@ void AudioDriverManager::add_driver(AudioDriver *p_driver) {
}
int AudioDriverManager::get_driver_count() {
-
return driver_count;
}
void AudioDriverManager::initialize(int p_driver) {
GLOBAL_DEF_RST("audio/enable_audio_input", false);
+ GLOBAL_DEF_RST("audio/mix_rate", DEFAULT_MIX_RATE);
+ GLOBAL_DEF_RST("audio/output_latency", DEFAULT_OUTPUT_LATENCY);
+
int failed_driver = -1;
// Check if there is a selected driver
@@ -214,7 +216,6 @@ void AudioDriverManager::initialize(int p_driver) {
}
AudioDriver *AudioDriverManager::get_driver(int p_driver) {
-
ERR_FAIL_INDEX_V(p_driver, driver_count, nullptr);
return drivers[p_driver];
}
@@ -225,7 +226,6 @@ AudioDriver *AudioDriverManager::get_driver(int p_driver) {
//////////////////////////////////////////////
void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
-
int todo = p_frames;
#ifdef DEBUG_ENABLED
@@ -239,7 +239,6 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
}
while (todo) {
-
if (to_mix == 0) {
_mix_step();
}
@@ -254,13 +253,10 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
//master master, send to output
int cs = master->channels.size();
for (int k = 0; k < cs; k++) {
-
if (master->channels[k].active) {
-
const AudioFrame *buf = master->channels[k].buffer.ptr();
for (int j = 0; j < to_copy; j++) {
-
float l = CLAMP(buf[from + j].l, -1.0, 1.0);
int32_t vl = l * ((1 << 20) - 1);
int32_t vl2 = (vl < 0 ? -1 : 1) * (ABS(vl) << 11);
@@ -274,7 +270,6 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
} else {
for (int j = 0; j < to_copy; j++) {
-
p_buffer[(from_buf + j) * (cs * 2) + k * 2 + 0] = 0;
p_buffer[(from_buf + j) * (cs * 2) + k * 2 + 1] = 0;
}
@@ -291,14 +286,12 @@ void AudioServer::_driver_process(int p_frames, int32_t *p_buffer) {
}
void AudioServer::_mix_step() {
-
bool solo_mode = false;
for (int i = 0; i < buses.size(); i++) {
Bus *bus = buses[i];
bus->index_cache = i; //might be moved around by editor, so..
for (int k = 0; k < bus->channels.size(); k++) {
-
bus->channels.write[k].used = false;
}
@@ -307,7 +300,6 @@ void AudioServer::_mix_step() {
solo_mode = true;
bus->soloed = true;
do {
-
if (bus != buses[0]) {
//everything has a send save for master bus
if (!bus_map.has(bus->send)) {
@@ -333,7 +325,6 @@ void AudioServer::_mix_step() {
//make callbacks for mixing the audio
for (Set<CallbackItem>::Element *E = callbacks.front(); E; E = E->next()) {
-
E->get().callback(E->get().userdata);
}
@@ -342,13 +333,11 @@ void AudioServer::_mix_step() {
Bus *bus = buses[i];
for (int k = 0; k < bus->channels.size(); k++) {
-
if (bus->channels[k].active && !bus->channels[k].used) {
//buffer was not used, but it's still active, so it must be cleaned
AudioFrame *buf = bus->channels.write[k].buffer.ptrw();
for (uint32_t j = 0; j < buffer_size; j++) {
-
buf[j] = AudioFrame(0, 0);
}
}
@@ -357,26 +346,26 @@ void AudioServer::_mix_step() {
//process effects
if (!bus->bypass) {
for (int j = 0; j < bus->effects.size(); j++) {
-
- if (!bus->effects[j].enabled)
+ if (!bus->effects[j].enabled) {
continue;
+ }
#ifdef DEBUG_ENABLED
uint64_t ticks = OS::get_singleton()->get_ticks_usec();
#endif
for (int k = 0; k < bus->channels.size(); k++) {
-
- if (!(bus->channels[k].active || bus->channels[k].effect_instances[j]->process_silence()))
+ if (!(bus->channels[k].active || bus->channels[k].effect_instances[j]->process_silence())) {
continue;
+ }
bus->channels.write[k].effect_instances.write[j]->process(bus->channels[k].buffer.ptr(), temp_buffer.write[k].ptrw(), buffer_size);
}
//swap buffers, so internal buffer always has the right data
for (int k = 0; k < bus->channels.size(); k++) {
-
- if (!(buses[i]->channels[k].active || bus->channels[k].effect_instances[j]->process_silence()))
+ if (!(buses[i]->channels[k].active || bus->channels[k].effect_instances[j]->process_silence())) {
continue;
+ }
SWAP(bus->channels.write[k].buffer, temp_buffer.write[k]);
}
@@ -403,9 +392,9 @@ void AudioServer::_mix_step() {
}
for (int k = 0; k < bus->channels.size(); k++) {
-
- if (!bus->channels[k].active)
+ if (!bus->channels[k].active) {
continue;
+ }
AudioFrame *buf = bus->channels.write[k].buffer.ptrw();
@@ -425,7 +414,6 @@ void AudioServer::_mix_step() {
//apply volume and compute peak
for (uint32_t j = 0; j < buffer_size; j++) {
-
buf[j] *= volume;
float l = ABS(buf[j].l);
@@ -467,15 +455,16 @@ void AudioServer::_mix_step() {
}
bool AudioServer::thread_has_channel_mix_buffer(int p_bus, int p_buffer) const {
- if (p_bus < 0 || p_bus >= buses.size())
+ if (p_bus < 0 || p_bus >= buses.size()) {
return false;
- if (p_buffer < 0 || p_buffer >= buses[p_bus]->channels.size())
+ }
+ if (p_buffer < 0 || p_buffer >= buses[p_bus]->channels.size()) {
return false;
+ }
return true;
}
AudioFrame *AudioServer::thread_get_channel_mix_buffer(int p_bus, int p_buffer) {
-
ERR_FAIL_INDEX_V(p_bus, buses.size(), nullptr);
ERR_FAIL_INDEX_V(p_buffer, buses[p_bus]->channels.size(), nullptr);
@@ -494,12 +483,10 @@ AudioFrame *AudioServer::thread_get_channel_mix_buffer(int p_bus, int p_buffer)
}
int AudioServer::thread_get_mix_buffer_size() const {
-
return buffer_size;
}
int AudioServer::thread_find_bus_index(const StringName &p_name) {
-
if (bus_map.has(p_name)) {
return bus_map[p_name]->index_cache;
} else {
@@ -508,7 +495,6 @@ int AudioServer::thread_find_bus_index(const StringName &p_name) {
}
void AudioServer::set_bus_count(int p_count) {
-
ERR_FAIL_COND(p_count < 1);
ERR_FAIL_INDEX(p_count, 256);
@@ -527,14 +513,11 @@ void AudioServer::set_bus_count(int p_count) {
buses.resize(p_count);
for (int i = cb; i < buses.size(); i++) {
-
String attempt = "New Bus";
int attempts = 1;
while (true) {
-
bool name_free = true;
for (int j = 0; j < i; j++) {
-
if (buses[j]->name == attempt) {
name_free = false;
break;
@@ -572,7 +555,6 @@ void AudioServer::set_bus_count(int p_count) {
}
void AudioServer::remove_bus(int p_index) {
-
ERR_FAIL_INDEX(p_index, buses.size());
ERR_FAIL_COND(p_index == 0);
@@ -588,25 +570,23 @@ void AudioServer::remove_bus(int p_index) {
}
void AudioServer::add_bus(int p_at_pos) {
-
MARK_EDITED
if (p_at_pos >= buses.size()) {
p_at_pos = -1;
} else if (p_at_pos == 0) {
- if (buses.size() > 1)
+ if (buses.size() > 1) {
p_at_pos = 1;
- else
+ } else {
p_at_pos = -1;
+ }
}
String attempt = "New Bus";
int attempts = 1;
while (true) {
-
bool name_free = true;
for (int j = 0; j < buses.size(); j++) {
-
if (buses[j]->name == attempt) {
name_free = false;
break;
@@ -634,23 +614,24 @@ void AudioServer::add_bus(int p_at_pos) {
bus_map[attempt] = bus;
- if (p_at_pos == -1)
+ if (p_at_pos == -1) {
buses.push_back(bus);
- else
+ } else {
buses.insert(p_at_pos, bus);
+ }
emit_signal("bus_layout_changed");
}
void AudioServer::move_bus(int p_bus, int p_to_pos) {
-
ERR_FAIL_COND(p_bus < 1 || p_bus >= buses.size());
ERR_FAIL_COND(p_to_pos != -1 && (p_to_pos < 1 || p_to_pos > buses.size()));
MARK_EDITED
- if (p_bus == p_to_pos)
+ if (p_bus == p_to_pos) {
return;
+ }
Bus *bus = buses[p_bus];
buses.remove(p_bus);
@@ -667,15 +648,14 @@ void AudioServer::move_bus(int p_bus, int p_to_pos) {
}
int AudioServer::get_bus_count() const {
-
return buses.size();
}
void AudioServer::set_bus_name(int p_bus, const String &p_name) {
-
ERR_FAIL_INDEX(p_bus, buses.size());
- if (p_bus == 0 && p_name != "Master")
+ if (p_bus == 0 && p_name != "Master") {
return; //bus 0 is always master
+ }
MARK_EDITED
@@ -690,10 +670,8 @@ void AudioServer::set_bus_name(int p_bus, const String &p_name) {
int attempts = 1;
while (true) {
-
bool name_free = true;
for (int i = 0; i < buses.size(); i++) {
-
if (buses[i]->name == attempt) {
name_free = false;
break;
@@ -714,8 +692,8 @@ void AudioServer::set_bus_name(int p_bus, const String &p_name) {
emit_signal("bus_layout_changed");
}
-String AudioServer::get_bus_name(int p_bus) const {
+String AudioServer::get_bus_name(int p_bus) const {
ERR_FAIL_INDEX_V(p_bus, buses.size(), String());
return buses[p_bus]->name;
}
@@ -730,27 +708,24 @@ int AudioServer::get_bus_index(const StringName &p_bus_name) const {
}
void AudioServer::set_bus_volume_db(int p_bus, float p_volume_db) {
-
ERR_FAIL_INDEX(p_bus, buses.size());
MARK_EDITED
buses[p_bus]->volume_db = p_volume_db;
}
-float AudioServer::get_bus_volume_db(int p_bus) const {
+float AudioServer::get_bus_volume_db(int p_bus) const {
ERR_FAIL_INDEX_V(p_bus, buses.size(), 0);
return buses[p_bus]->volume_db;
}
int AudioServer::get_bus_channels(int p_bus) const {
-
ERR_FAIL_INDEX_V(p_bus, buses.size(), 0);
return buses[p_bus]->channels.size();
}
void AudioServer::set_bus_send(int p_bus, const StringName &p_send) {
-
ERR_FAIL_INDEX(p_bus, buses.size());
MARK_EDITED
@@ -759,13 +734,11 @@ void AudioServer::set_bus_send(int p_bus, const StringName &p_send) {
}
StringName AudioServer::get_bus_send(int p_bus) const {
-
ERR_FAIL_INDEX_V(p_bus, buses.size(), StringName());
return buses[p_bus]->send;
}
void AudioServer::set_bus_solo(int p_bus, bool p_enable) {
-
ERR_FAIL_INDEX(p_bus, buses.size());
MARK_EDITED
@@ -774,44 +747,40 @@ void AudioServer::set_bus_solo(int p_bus, bool p_enable) {
}
bool AudioServer::is_bus_solo(int p_bus) const {
-
ERR_FAIL_INDEX_V(p_bus, buses.size(), false);
return buses[p_bus]->solo;
}
void AudioServer::set_bus_mute(int p_bus, bool p_enable) {
-
ERR_FAIL_INDEX(p_bus, buses.size());
MARK_EDITED
buses[p_bus]->mute = p_enable;
}
-bool AudioServer::is_bus_mute(int p_bus) const {
+bool AudioServer::is_bus_mute(int p_bus) const {
ERR_FAIL_INDEX_V(p_bus, buses.size(), false);
return buses[p_bus]->mute;
}
void AudioServer::set_bus_bypass_effects(int p_bus, bool p_enable) {
-
ERR_FAIL_INDEX(p_bus, buses.size());
MARK_EDITED
buses[p_bus]->bypass = p_enable;
}
-bool AudioServer::is_bus_bypassing_effects(int p_bus) const {
+bool AudioServer::is_bus_bypassing_effects(int p_bus) const {
ERR_FAIL_INDEX_V(p_bus, buses.size(), false);
return buses[p_bus]->bypass;
}
void AudioServer::_update_bus_effects(int p_bus) {
-
for (int i = 0; i < buses[p_bus]->channels.size(); i++) {
buses.write[p_bus]->channels.write[i].effect_instances.resize(buses[p_bus]->effects.size());
for (int j = 0; j < buses[p_bus]->effects.size(); j++) {
@@ -825,7 +794,6 @@ void AudioServer::_update_bus_effects(int p_bus) {
}
void AudioServer::add_bus_effect(int p_bus, const Ref<AudioEffect> &p_effect, int p_at_pos) {
-
ERR_FAIL_COND(p_effect.is_null());
ERR_FAIL_INDEX(p_bus, buses.size());
@@ -853,7 +821,6 @@ void AudioServer::add_bus_effect(int p_bus, const Ref<AudioEffect> &p_effect, in
}
void AudioServer::remove_bus_effect(int p_bus, int p_effect) {
-
ERR_FAIL_INDEX(p_bus, buses.size());
MARK_EDITED
@@ -867,14 +834,12 @@ void AudioServer::remove_bus_effect(int p_bus, int p_effect) {
}
int AudioServer::get_bus_effect_count(int p_bus) {
-
ERR_FAIL_INDEX_V(p_bus, buses.size(), 0);
return buses[p_bus]->effects.size();
}
Ref<AudioEffectInstance> AudioServer::get_bus_effect_instance(int p_bus, int p_effect, int p_channel) {
-
ERR_FAIL_INDEX_V(p_bus, buses.size(), Ref<AudioEffectInstance>());
ERR_FAIL_INDEX_V(p_effect, buses[p_bus]->effects.size(), Ref<AudioEffectInstance>());
ERR_FAIL_INDEX_V(p_channel, buses[p_bus]->channels.size(), Ref<AudioEffectInstance>());
@@ -883,7 +848,6 @@ Ref<AudioEffectInstance> AudioServer::get_bus_effect_instance(int p_bus, int p_e
}
Ref<AudioEffect> AudioServer::get_bus_effect(int p_bus, int p_effect) {
-
ERR_FAIL_INDEX_V(p_bus, buses.size(), Ref<AudioEffect>());
ERR_FAIL_INDEX_V(p_effect, buses[p_bus]->effects.size(), Ref<AudioEffect>());
@@ -891,7 +855,6 @@ Ref<AudioEffect> AudioServer::get_bus_effect(int p_bus, int p_effect) {
}
void AudioServer::swap_bus_effects(int p_bus, int p_effect, int p_by_effect) {
-
ERR_FAIL_INDEX(p_bus, buses.size());
ERR_FAIL_INDEX(p_effect, buses[p_bus]->effects.size());
ERR_FAIL_INDEX(p_by_effect, buses[p_bus]->effects.size());
@@ -905,7 +868,6 @@ void AudioServer::swap_bus_effects(int p_bus, int p_effect, int p_by_effect) {
}
void AudioServer::set_bus_effect_enabled(int p_bus, int p_effect, bool p_enabled) {
-
ERR_FAIL_INDEX(p_bus, buses.size());
ERR_FAIL_INDEX(p_effect, buses[p_bus]->effects.size());
@@ -913,22 +875,21 @@ void AudioServer::set_bus_effect_enabled(int p_bus, int p_effect, bool p_enabled
buses.write[p_bus]->effects.write[p_effect].enabled = p_enabled;
}
-bool AudioServer::is_bus_effect_enabled(int p_bus, int p_effect) const {
+bool AudioServer::is_bus_effect_enabled(int p_bus, int p_effect) const {
ERR_FAIL_INDEX_V(p_bus, buses.size(), false);
ERR_FAIL_INDEX_V(p_effect, buses[p_bus]->effects.size(), false);
return buses[p_bus]->effects[p_effect].enabled;
}
float AudioServer::get_bus_peak_volume_left_db(int p_bus, int p_channel) const {
-
ERR_FAIL_INDEX_V(p_bus, buses.size(), 0);
ERR_FAIL_INDEX_V(p_channel, buses[p_bus]->channels.size(), 0);
return buses[p_bus]->channels[p_channel].peak_volume.l;
}
-float AudioServer::get_bus_peak_volume_right_db(int p_bus, int p_channel) const {
+float AudioServer::get_bus_peak_volume_right_db(int p_bus, int p_channel) const {
ERR_FAIL_INDEX_V(p_bus, buses.size(), 0);
ERR_FAIL_INDEX_V(p_channel, buses[p_bus]->channels.size(), 0);
@@ -936,7 +897,6 @@ float AudioServer::get_bus_peak_volume_right_db(int p_bus, int p_channel) const
}
bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const {
-
ERR_FAIL_INDEX_V(p_bus, buses.size(), false);
ERR_FAIL_INDEX_V(p_channel, buses[p_bus]->channels.size(), false);
@@ -944,11 +904,10 @@ bool AudioServer::is_bus_channel_active(int p_bus, int p_channel) const {
}
void AudioServer::set_global_rate_scale(float p_scale) {
-
global_rate_scale = p_scale;
}
-float AudioServer::get_global_rate_scale() const {
+float AudioServer::get_global_rate_scale() const {
return global_rate_scale;
}
@@ -969,7 +928,6 @@ void AudioServer::init_channels_and_buffers() {
}
void AudioServer::init() {
-
channel_disable_threshold_db = GLOBAL_DEF_RST("audio/channel_disable_threshold_db", -60.0);
channel_disable_frames = float(GLOBAL_DEF_RST("audio/channel_disable_time", 2.0)) * get_mix_rate();
ProjectSettings::get_singleton()->set_custom_property_info("audio/channel_disable_time", PropertyInfo(Variant::FLOAT, "audio/channel_disable_time", PROPERTY_HINT_RANGE, "0,5,0.01,or_greater"));
@@ -981,8 +939,9 @@ void AudioServer::init() {
set_bus_count(1);
set_bus_name(0, "Master");
- if (AudioDriver::get_singleton())
+ if (AudioDriver::get_singleton()) {
AudioDriver::get_singleton()->start();
+ }
#ifdef TOOLS_ENABLED
set_edited(false); //avoid editors from thinking this was edited
@@ -994,35 +953,39 @@ void AudioServer::init() {
void AudioServer::update() {
#ifdef DEBUG_ENABLED
if (EngineDebugger::is_profiling("servers")) {
-
// Driver time includes server time + effects times
// Server time includes effects times
uint64_t driver_time = AudioDriver::get_singleton()->get_profiling_time();
uint64_t server_time = prof_time;
// Subtract the server time from the driver time
- if (driver_time > server_time)
+ if (driver_time > server_time) {
driver_time -= server_time;
+ }
Array values;
for (int i = buses.size() - 1; i >= 0; i--) {
Bus *bus = buses[i];
- if (bus->bypass)
+ if (bus->bypass) {
continue;
+ }
for (int j = 0; j < bus->effects.size(); j++) {
- if (!bus->effects[j].enabled)
+ if (!bus->effects[j].enabled) {
continue;
+ }
values.push_back(String(bus->name) + bus->effects[j].effect->get_name());
values.push_back(USEC_TO_SEC(bus->effects[j].prof_time));
// Subtract the effect time from the driver and server times
- if (driver_time > bus->effects[j].prof_time)
+ if (driver_time > bus->effects[j].prof_time) {
driver_time -= bus->effects[j].prof_time;
- if (server_time > bus->effects[j].prof_time)
+ }
+ if (server_time > bus->effects[j].prof_time) {
server_time -= bus->effects[j].prof_time;
+ }
}
}
@@ -1038,12 +1001,14 @@ void AudioServer::update() {
// Reset profiling times
for (int i = buses.size() - 1; i >= 0; i--) {
Bus *bus = buses[i];
- if (bus->bypass)
+ if (bus->bypass) {
continue;
+ }
for (int j = 0; j < bus->effects.size(); j++) {
- if (!bus->effects[j].enabled)
+ if (!bus->effects[j].enabled) {
continue;
+ }
bus->effects.write[j].prof_time = 0;
}
@@ -1054,13 +1019,11 @@ void AudioServer::update() {
#endif
for (Set<CallbackItem>::Element *E = update_callbacks.front(); E; E = E->next()) {
-
E->get().callback(E->get().userdata);
}
}
void AudioServer::load_default_bus_layout() {
-
String layout_path = ProjectSettings::get_singleton()->get("audio/default_bus_layout");
if (ResourceLoader::exists(layout_path)) {
@@ -1072,7 +1035,6 @@ void AudioServer::load_default_bus_layout() {
}
void AudioServer::finish() {
-
for (int i = 0; i < AudioDriverManager::get_driver_count(); i++) {
AudioDriverManager::get_driver(i)->finish();
}
@@ -1087,45 +1049,38 @@ void AudioServer::finish() {
/* MISC config */
void AudioServer::lock() {
-
AudioDriver::get_singleton()->lock();
}
-void AudioServer::unlock() {
+void AudioServer::unlock() {
AudioDriver::get_singleton()->unlock();
}
AudioServer::SpeakerMode AudioServer::get_speaker_mode() const {
-
return (AudioServer::SpeakerMode)AudioDriver::get_singleton()->get_speaker_mode();
}
-float AudioServer::get_mix_rate() const {
+float AudioServer::get_mix_rate() const {
return AudioDriver::get_singleton()->get_mix_rate();
}
float AudioServer::read_output_peak_db() const {
-
return 0;
}
AudioServer *AudioServer::get_singleton() {
-
return singleton;
}
double AudioServer::get_output_latency() const {
-
return AudioDriver::get_singleton()->get_latency();
}
double AudioServer::get_time_to_next_mix() const {
-
return AudioDriver::get_singleton()->get_time_to_next_mix();
}
double AudioServer::get_time_since_last_mix() const {
-
return AudioDriver::get_singleton()->get_time_since_last_mix();
}
@@ -1141,7 +1096,6 @@ void AudioServer::add_callback(AudioCallback p_callback, void *p_userdata) {
}
void AudioServer::remove_callback(AudioCallback p_callback, void *p_userdata) {
-
lock();
CallbackItem ci;
ci.callback = p_callback;
@@ -1160,7 +1114,6 @@ void AudioServer::add_update_callback(AudioCallback p_callback, void *p_userdata
}
void AudioServer::remove_update_callback(AudioCallback p_callback, void *p_userdata) {
-
lock();
CallbackItem ci;
ci.callback = p_callback;
@@ -1170,7 +1123,6 @@ void AudioServer::remove_update_callback(AudioCallback p_callback, void *p_userd
}
void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
-
ERR_FAIL_COND(p_bus_layout.is_null() || p_bus_layout->buses.size() == 0);
lock();
@@ -1194,11 +1146,9 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
bus->volume_db = p_bus_layout->buses[i].volume_db;
for (int j = 0; j < p_bus_layout->buses[i].effects.size(); j++) {
-
Ref<AudioEffect> fx = p_bus_layout->buses[i].effects[j].effect;
if (fx.is_valid()) {
-
Bus::Effect bfx;
bfx.effect = fx;
bfx.enabled = p_bus_layout->buses[i].effects[j].enabled;
@@ -1222,14 +1172,12 @@ void AudioServer::set_bus_layout(const Ref<AudioBusLayout> &p_bus_layout) {
}
Ref<AudioBusLayout> AudioServer::generate_bus_layout() const {
-
Ref<AudioBusLayout> state;
state.instance();
state->buses.resize(buses.size());
for (int i = 0; i < buses.size(); i++) {
-
state->buses.write[i].name = buses[i]->name;
state->buses.write[i].send = buses[i]->send;
state->buses.write[i].mute = buses[i]->mute;
@@ -1248,37 +1196,30 @@ Ref<AudioBusLayout> AudioServer::generate_bus_layout() const {
}
Array AudioServer::get_device_list() {
-
return AudioDriver::get_singleton()->get_device_list();
}
String AudioServer::get_device() {
-
return AudioDriver::get_singleton()->get_device();
}
void AudioServer::set_device(String device) {
-
AudioDriver::get_singleton()->set_device(device);
}
Array AudioServer::capture_get_device_list() {
-
return AudioDriver::get_singleton()->capture_get_device_list();
}
String AudioServer::capture_get_device() {
-
return AudioDriver::get_singleton()->capture_get_device();
}
void AudioServer::capture_set_device(const String &p_name) {
-
AudioDriver::get_singleton()->capture_set_device(p_name);
}
void AudioServer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_bus_count", "amount"), &AudioServer::set_bus_count);
ClassDB::bind_method(D_METHOD("get_bus_count"), &AudioServer::get_bus_count);
@@ -1357,7 +1298,6 @@ void AudioServer::_bind_methods() {
}
AudioServer::AudioServer() {
-
singleton = this;
mix_frames = 0;
channel_count = 0;
@@ -1371,14 +1311,12 @@ AudioServer::AudioServer() {
}
AudioServer::~AudioServer() {
-
singleton = nullptr;
}
/////////////////////////////////
bool AudioBusLayout::_set(const StringName &p_name, const Variant &p_value) {
-
String s = p_name;
if (s.begins_with("bus/")) {
int index = s.get_slice("/", 1).to_int();
@@ -1431,13 +1369,12 @@ bool AudioBusLayout::_set(const StringName &p_name, const Variant &p_value) {
}
bool AudioBusLayout::_get(const StringName &p_name, Variant &r_ret) const {
-
String s = p_name;
if (s.begins_with("bus/")) {
-
int index = s.get_slice("/", 1).to_int();
- if (index < 0 || index >= buses.size())
+ if (index < 0 || index >= buses.size()) {
return false;
+ }
const Bus &bus = buses[index];
@@ -1482,8 +1419,8 @@ bool AudioBusLayout::_get(const StringName &p_name, Variant &r_ret) const {
return false;
}
-void AudioBusLayout::_get_property_list(List<PropertyInfo> *p_list) const {
+void AudioBusLayout::_get_property_list(List<PropertyInfo> *p_list) const {
for (int i = 0; i < buses.size(); i++) {
p_list->push_back(PropertyInfo(Variant::STRING, "bus/" + itos(i) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
p_list->push_back(PropertyInfo(Variant::BOOL, "bus/" + itos(i) + "/solo", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
@@ -1500,7 +1437,6 @@ void AudioBusLayout::_get_property_list(List<PropertyInfo> *p_list) const {
}
AudioBusLayout::AudioBusLayout() {
-
buses.resize(1);
buses.write[0].name = "Master";
}
diff --git a/servers/audio_server.h b/servers/audio_server.h
index a1a3dde719..80e244aacd 100644
--- a/servers/audio_server.h
+++ b/servers/audio_server.h
@@ -42,7 +42,6 @@ class AudioStream;
class AudioStreamSample;
class AudioDriver {
-
static AudioDriver *singleton;
uint64_t _last_mix_time;
uint64_t _last_mix_frames;
@@ -81,9 +80,6 @@ public:
SPEAKER_SURROUND_71,
};
- static const int DEFAULT_MIX_RATE = 44100;
- static const int DEFAULT_OUTPUT_LATENCY = 15;
-
static AudioDriver *get_singleton();
void set_singleton();
@@ -125,12 +121,14 @@ public:
};
class AudioDriverManager {
-
enum {
MAX_DRIVERS = 10
};
+ static const int DEFAULT_MIX_RATE = 44100;
+ static const int DEFAULT_OUTPUT_LATENCY = 15;
+
static AudioDriver *drivers[MAX_DRIVERS];
static int driver_count;
@@ -146,7 +144,6 @@ public:
class AudioBusLayout;
class AudioServer : public Object {
-
GDCLASS(AudioServer, Object);
public:
@@ -184,7 +181,6 @@ private:
float global_rate_scale;
struct Bus {
-
StringName name;
bool solo;
bool mute;
@@ -237,7 +233,6 @@ private:
void _mix_step();
struct CallbackItem {
-
AudioCallback callback;
void *userdata;
@@ -258,10 +253,14 @@ protected:
public:
_FORCE_INLINE_ int get_channel_count() const {
switch (get_speaker_mode()) {
- case SPEAKER_MODE_STEREO: return 1;
- case SPEAKER_SURROUND_31: return 2;
- case SPEAKER_SURROUND_51: return 3;
- case SPEAKER_SURROUND_71: return 4;
+ case SPEAKER_MODE_STEREO:
+ return 1;
+ case SPEAKER_SURROUND_31:
+ return 2;
+ case SPEAKER_SURROUND_51:
+ return 3;
+ case SPEAKER_SURROUND_71:
+ return 4;
}
ERR_FAIL_V(1);
}
@@ -366,13 +365,11 @@ public:
VARIANT_ENUM_CAST(AudioServer::SpeakerMode)
class AudioBusLayout : public Resource {
-
GDCLASS(AudioBusLayout, Resource);
friend class AudioServer;
struct Bus {
-
StringName name;
bool solo;
bool mute;
diff --git a/servers/display_server.cpp b/servers/display_server.cpp
index da1a68a179..cc818cbe04 100644
--- a/servers/display_server.cpp
+++ b/servers/display_server.cpp
@@ -30,7 +30,7 @@
#include "display_server.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "scene/resources/texture.h"
DisplayServer *DisplayServer::singleton = nullptr;
@@ -127,6 +127,7 @@ void DisplayServer::global_menu_clear(const String &p_menu_root) {
void DisplayServer::mouse_set_mode(MouseMode p_mode) {
WARN_PRINT("Mouse is not supported by this display server.");
}
+
DisplayServer::MouseMode DisplayServer::mouse_get_mode() const {
return MOUSE_MODE_VISIBLE;
}
@@ -134,12 +135,15 @@ DisplayServer::MouseMode DisplayServer::mouse_get_mode() const {
void DisplayServer::mouse_warp_to_position(const Point2i &p_to) {
WARN_PRINT("Mouse warping is not supported by this display server.");
}
+
Point2i DisplayServer::mouse_get_absolute_position() const {
ERR_FAIL_V_MSG(Point2i(), "Mouse is not supported by this display server.");
}
+
Point2i DisplayServer::mouse_get_position() const {
ERR_FAIL_V_MSG(Point2i(), "Mouse is not supported by this display server.");
}
+
int DisplayServer::mouse_get_button_state() const {
ERR_FAIL_V_MSG(0, "Mouse is not supported by this display server.");
}
@@ -147,6 +151,7 @@ int DisplayServer::mouse_get_button_state() const {
void DisplayServer::clipboard_set(const String &p_text) {
WARN_PRINT("Clipboard is not supported by this display server.");
}
+
String DisplayServer::clipboard_get() const {
ERR_FAIL_V_MSG(String(), "Clipboard is not supported by this display server.");
}
@@ -154,6 +159,7 @@ String DisplayServer::clipboard_get() const {
void DisplayServer::screen_set_orientation(ScreenOrientation p_orientation, int p_screen) {
WARN_PRINT("Orientation not supported by this display server.");
}
+
DisplayServer::ScreenOrientation DisplayServer::screen_get_orientation(int p_screen) const {
return SCREEN_LANDSCAPE;
}
@@ -164,12 +170,13 @@ float DisplayServer::screen_get_scale(int p_screen) const {
bool DisplayServer::screen_is_touchscreen(int p_screen) const {
//return false;
- return InputFilter::get_singleton() && InputFilter::get_singleton()->is_emulating_touch_from_mouse();
+ return Input::get_singleton() && Input::get_singleton()->is_emulating_touch_from_mouse();
}
void DisplayServer::screen_set_keep_on(bool p_enable) {
WARN_PRINT("Keeping screen on not supported by this display server.");
}
+
bool DisplayServer::screen_is_kept_on() const {
return false;
}
@@ -177,6 +184,7 @@ bool DisplayServer::screen_is_kept_on() const {
DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &) {
ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server.");
}
+
void DisplayServer::delete_sub_window(WindowID p_id) {
ERR_FAIL_MSG("Sub-windows not supported by this display server.");
}
@@ -184,6 +192,7 @@ void DisplayServer::delete_sub_window(WindowID p_id) {
void DisplayServer::window_set_ime_active(const bool p_active, WindowID p_window) {
WARN_PRINT("IME not supported by this display server.");
}
+
void DisplayServer::window_set_ime_position(const Point2i &p_pos, WindowID p_window) {
WARN_PRINT("IME not supported by this display server.");
}
@@ -191,6 +200,7 @@ void DisplayServer::window_set_ime_position(const Point2i &p_pos, WindowID p_win
Point2i DisplayServer::ime_get_selection() const {
ERR_FAIL_V_MSG(Point2i(), "IME or NOTIFICATION_WM_IME_UPDATE not supported by this display server.");
}
+
String DisplayServer::ime_get_text() const {
ERR_FAIL_V_MSG(String(), "IME or NOTIFICATION_WM_IME_UPDATEnot supported by this display server.");
}
@@ -198,13 +208,15 @@ String DisplayServer::ime_get_text() const {
void DisplayServer::console_set_visible(bool p_enabled) {
WARN_PRINT("Console window not supported by this display server.");
}
+
bool DisplayServer::is_console_visible() const {
return false;
}
-void DisplayServer::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_legth) {
+void DisplayServer::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_length, int p_cursor_start, int p_cursor_end) {
WARN_PRINT("Virtual keyboard not supported by this display server.");
}
+
void DisplayServer::virtual_keyboard_hide() {
WARN_PRINT("Virtual keyboard not supported by this display server.");
}
@@ -217,9 +229,11 @@ int DisplayServer::virtual_keyboard_get_height() const {
void DisplayServer::cursor_set_shape(CursorShape p_shape) {
WARN_PRINT("Cursor shape not supported by this display server.");
}
+
DisplayServer::CursorShape DisplayServer::cursor_get_shape() const {
return CURSOR_ARROW;
}
+
void DisplayServer::cursor_set_custom_image(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
WARN_PRINT("Custom cursor shape not supported by this display server.");
}
@@ -235,15 +249,19 @@ void DisplayServer::enable_for_stealing_focus(OS::ProcessID pid) {
Error DisplayServer::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track, int p_screen) {
ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Native video not supported by this display server.");
}
+
bool DisplayServer::native_video_is_playing() const {
return false;
}
+
void DisplayServer::native_video_pause() {
WARN_PRINT("Native video not supported by this display server.");
}
+
void DisplayServer::native_video_unpause() {
WARN_PRINT("Native video not supported by this display server.");
}
+
void DisplayServer::native_video_stop() {
WARN_PRINT("Native video not supported by this display server.");
}
@@ -252,6 +270,7 @@ Error DisplayServer::dialog_show(String p_title, String p_description, Vector<St
WARN_PRINT("Native dialogs not supported by this display server.");
return OK;
}
+
Error DisplayServer::dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) {
WARN_PRINT("Native dialogs not supported by this display server.");
return OK;
@@ -267,9 +286,11 @@ void DisplayServer::force_process_and_drop_events() {
void DisplayServer::release_rendering_thread() {
WARN_PRINT("Rendering thread not supported by this display server.");
}
+
void DisplayServer::make_rendering_thread() {
WARN_PRINT("Rendering thread not supported by this display server.");
}
+
void DisplayServer::swap_buffers() {
WARN_PRINT("Swap buffers not supported by this display server.");
}
@@ -277,6 +298,7 @@ void DisplayServer::swap_buffers() {
void DisplayServer::set_native_icon(const String &p_filename) {
WARN_PRINT("Native icon not supported by this display server.");
}
+
void DisplayServer::set_icon(const Ref<Image> &p_icon) {
WARN_PRINT("Icon not supported by this display server.");
}
@@ -284,6 +306,7 @@ void DisplayServer::set_icon(const Ref<Image> &p_icon) {
void DisplayServer::_set_use_vsync(bool p_enable) {
WARN_PRINT("VSync not supported by this display server.");
}
+
void DisplayServer::vsync_set_enabled(bool p_enable) {
vsync_enabled = p_enable;
if (switch_vsync_function) { //if a function was set, use function
@@ -292,6 +315,7 @@ void DisplayServer::vsync_set_enabled(bool p_enable) {
_set_use_vsync(p_enable);
}
}
+
bool DisplayServer::vsync_is_enabled() const {
return vsync_enabled;
}
@@ -299,6 +323,7 @@ bool DisplayServer::vsync_is_enabled() const {
void DisplayServer::vsync_set_use_via_compositor(bool p_enable) {
WARN_PRINT("VSync via compositor not supported by this display server.");
}
+
bool DisplayServer::vsync_is_using_via_compositor() const {
return false;
}
@@ -307,7 +332,6 @@ void DisplayServer::set_context(Context p_context) {
}
void DisplayServer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("has_feature", "feature"), &DisplayServer::has_feature);
ClassDB::bind_method(D_METHOD("get_name"), &DisplayServer::get_name);
@@ -415,7 +439,7 @@ void DisplayServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("console_set_visible", "console_visible"), &DisplayServer::console_set_visible);
ClassDB::bind_method(D_METHOD("is_console_visible"), &DisplayServer::is_console_visible);
- ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position", "max_length"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2i()), DEFVAL(-1));
+ ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position", "max_length", "cursor_start", "cursor_end"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2i()), DEFVAL(-1), DEFVAL(-1), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("virtual_keyboard_hide"), &DisplayServer::virtual_keyboard_hide);
ClassDB::bind_method(D_METHOD("virtual_keyboard_get_height"), &DisplayServer::virtual_keyboard_get_height);
@@ -563,31 +587,34 @@ DisplayServer *DisplayServer::create(int p_index, const String &p_rendering_driv
return server_create_functions[p_index].create_function(p_rendering_driver, p_mode, p_flags, p_resolution, r_error);
}
-void DisplayServer::_input_set_mouse_mode(InputFilter::MouseMode p_mode) {
+void DisplayServer::_input_set_mouse_mode(Input::MouseMode p_mode) {
singleton->mouse_set_mode(MouseMode(p_mode));
}
-InputFilter::MouseMode DisplayServer::_input_get_mouse_mode() {
- return InputFilter::MouseMode(singleton->mouse_get_mode());
+
+Input::MouseMode DisplayServer::_input_get_mouse_mode() {
+ return Input::MouseMode(singleton->mouse_get_mode());
}
void DisplayServer::_input_warp(const Vector2 &p_to_pos) {
singleton->mouse_warp_to_position(p_to_pos);
}
-InputFilter::CursorShape DisplayServer::_input_get_current_cursor_shape() {
- return (InputFilter::CursorShape)singleton->cursor_get_shape();
+Input::CursorShape DisplayServer::_input_get_current_cursor_shape() {
+ return (Input::CursorShape)singleton->cursor_get_shape();
}
-void DisplayServer::_input_set_custom_mouse_cursor_func(const RES &p_image, InputFilter::CursorShape p_shape, const Vector2 &p_hostspot) {
+
+void DisplayServer::_input_set_custom_mouse_cursor_func(const RES &p_image, Input::CursorShape p_shape, const Vector2 &p_hostspot) {
singleton->cursor_set_custom_image(p_image, (CursorShape)p_shape, p_hostspot);
}
DisplayServer::DisplayServer() {
singleton = this;
- InputFilter::set_mouse_mode_func = _input_set_mouse_mode;
- InputFilter::get_mouse_mode_func = _input_get_mouse_mode;
- InputFilter::warp_mouse_func = _input_warp;
- InputFilter::get_current_cursor_shape_func = _input_get_current_cursor_shape;
- InputFilter::set_custom_mouse_cursor_func = _input_set_custom_mouse_cursor_func;
+ Input::set_mouse_mode_func = _input_set_mouse_mode;
+ Input::get_mouse_mode_func = _input_get_mouse_mode;
+ Input::warp_mouse_func = _input_warp;
+ Input::get_current_cursor_shape_func = _input_get_current_cursor_shape;
+ Input::set_custom_mouse_cursor_func = _input_set_custom_mouse_cursor_func;
}
+
DisplayServer::~DisplayServer() {
}
diff --git a/servers/display_server.h b/servers/display_server.h
index 93db7ef844..b25b1931c8 100644
--- a/servers/display_server.h
+++ b/servers/display_server.h
@@ -32,7 +32,7 @@
#define DISPLAY_SERVER_H
#include "core/callable.h"
-#include "core/input/input_filter.h"
+#include "core/input/input.h"
#include "core/os/os.h"
#include "core/resource.h"
@@ -61,11 +61,11 @@ public:
typedef Vector<String> (*GetRenderingDriversFunction)();
private:
- static void _input_set_mouse_mode(InputFilter::MouseMode p_mode);
- static InputFilter::MouseMode _input_get_mouse_mode();
+ static void _input_set_mouse_mode(Input::MouseMode p_mode);
+ static Input::MouseMode _input_get_mouse_mode();
static void _input_warp(const Vector2 &p_to_pos);
- static InputFilter::CursorShape _input_get_current_cursor_shape();
- static void _input_set_custom_mouse_cursor_func(const RES &, InputFilter::CursorShape, const Vector2 &p_hostspot);
+ static Input::CursorShape _input_get_current_cursor_shape();
+ static void _input_set_custom_mouse_cursor_func(const RES &, Input::CursorShape, const Vector2 &p_hostspot);
protected:
static void _bind_methods();
@@ -280,7 +280,7 @@ public:
virtual void console_set_visible(bool p_enabled);
virtual bool is_console_visible() const;
- virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_legth = -1);
+ virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
virtual void virtual_keyboard_hide();
// returns height of the currently shown virtual keyboard (0 if keyboard is hidden)
diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp
index 17f2232c72..b20f6865cd 100644
--- a/servers/navigation_server_2d.cpp
+++ b/servers/navigation_server_2d.cpp
@@ -83,21 +83,27 @@ NavigationServer2D *NavigationServer2D::singleton = nullptr;
static RID rid_to_rid(const RID d) {
return d;
}
+
static bool bool_to_bool(const bool d) {
return d;
}
+
static int int_to_int(const int d) {
return d;
}
+
static real_t real_to_real(const real_t d) {
return d;
}
+
static Vector3 v2_to_v3(const Vector2 d) {
return Vector3(d.x, 0.0, d.y);
}
+
static Vector2 v3_to_v2(const Vector3 &d) {
return Vector2(d.x, d.z);
}
+
static Vector<Vector2> vector_v3_to_v2(const Vector<Vector3> &d) {
Vector<Vector2> nd;
nd.resize(d.size());
@@ -106,21 +112,26 @@ static Vector<Vector2> vector_v3_to_v2(const Vector<Vector3> &d) {
}
return nd;
}
+
static Transform trf2_to_trf3(const Transform2D &d) {
Vector3 o(v2_to_v3(d.get_origin()));
Basis b;
b.rotate(Vector3(0, 1, 0), d.get_rotation());
return Transform(b, o);
}
+
static Object *obj_to_obj(Object *d) {
return d;
}
+
static StringName sn_to_sn(StringName &d) {
return d;
}
+
static Variant var_to_var(Variant &d) {
return d;
}
+
static Ref<NavigationMesh> poly_to_mesh(Ref<NavigationPolygon> d) {
if (d.is_valid()) {
return d->get_mesh();
diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp
index 67a4d0e413..8f9b5df589 100644
--- a/servers/navigation_server_3d.cpp
+++ b/servers/navigation_server_3d.cpp
@@ -37,7 +37,6 @@
NavigationServer3D *NavigationServer3D::singleton = nullptr;
void NavigationServer3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("map_create"), &NavigationServer3D::map_create);
ClassDB::bind_method(D_METHOD("map_set_active", "map", "active"), &NavigationServer3D::map_set_active);
ClassDB::bind_method(D_METHOD("map_is_active", "nap"), &NavigationServer3D::map_is_active);
diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp
index 85ec2aae47..acbbb7e1e8 100644
--- a/servers/physics_2d/area_2d_sw.cpp
+++ b/servers/physics_2d/area_2d_sw.cpp
@@ -38,6 +38,7 @@ Area2DSW::BodyKey::BodyKey(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_a
body_shape = p_body_shape;
area_shape = p_area_shape;
}
+
Area2DSW::BodyKey::BodyKey(Area2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {
rid = p_body->get_self();
instance_id = p_body->get_instance_id();
@@ -46,27 +47,28 @@ Area2DSW::BodyKey::BodyKey(Area2DSW *p_body, uint32_t p_body_shape, uint32_t p_a
}
void Area2DSW::_shapes_changed() {
-
- if (!moved_list.in_list() && get_space())
+ if (!moved_list.in_list() && get_space()) {
get_space()->area_add_to_moved_list(&moved_list);
+ }
}
void Area2DSW::set_transform(const Transform2D &p_transform) {
-
- if (!moved_list.in_list() && get_space())
+ if (!moved_list.in_list() && get_space()) {
get_space()->area_add_to_moved_list(&moved_list);
+ }
_set_transform(p_transform);
_set_inv_transform(p_transform.affine_inverse());
}
void Area2DSW::set_space(Space2DSW *p_space) {
-
if (get_space()) {
- if (monitor_query_list.in_list())
+ if (monitor_query_list.in_list()) {
get_space()->area_remove_from_monitor_query_list(&monitor_query_list);
- if (moved_list.in_list())
+ }
+ if (moved_list.in_list()) {
get_space()->area_remove_from_moved_list(&moved_list);
+ }
}
monitored_bodies.clear();
@@ -76,7 +78,6 @@ void Area2DSW::set_space(Space2DSW *p_space) {
}
void Area2DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) {
-
if (p_id == monitor_callback_id) {
monitor_callback_method = p_method;
return;
@@ -92,12 +93,12 @@ void Area2DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) {
_shape_changed();
- if (!moved_list.in_list() && get_space())
+ if (!moved_list.in_list() && get_space()) {
get_space()->area_add_to_moved_list(&moved_list);
+ }
}
void Area2DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) {
-
if (p_id == area_monitor_callback_id) {
area_monitor_callback_method = p_method;
return;
@@ -113,74 +114,97 @@ void Area2DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_meth
_shape_changed();
- if (!moved_list.in_list() && get_space())
+ if (!moved_list.in_list() && get_space()) {
get_space()->area_add_to_moved_list(&moved_list);
+ }
}
void Area2DSW::set_space_override_mode(PhysicsServer2D::AreaSpaceOverrideMode p_mode) {
bool do_override = p_mode != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED;
- if (do_override == (space_override_mode != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED))
+ if (do_override == (space_override_mode != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED)) {
return;
+ }
_unregister_shapes();
space_override_mode = p_mode;
_shape_changed();
}
void Area2DSW::set_param(PhysicsServer2D::AreaParameter p_param, const Variant &p_value) {
-
switch (p_param) {
- case PhysicsServer2D::AREA_PARAM_GRAVITY: gravity = p_value; break;
- case PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR: gravity_vector = p_value; break;
- case PhysicsServer2D::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point = p_value; break;
- case PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale = p_value; break;
- case PhysicsServer2D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation = p_value; break;
- case PhysicsServer2D::AREA_PARAM_LINEAR_DAMP: linear_damp = p_value; break;
- case PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP: angular_damp = p_value; break;
- case PhysicsServer2D::AREA_PARAM_PRIORITY: priority = p_value; break;
+ case PhysicsServer2D::AREA_PARAM_GRAVITY:
+ gravity = p_value;
+ break;
+ case PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR:
+ gravity_vector = p_value;
+ break;
+ case PhysicsServer2D::AREA_PARAM_GRAVITY_IS_POINT:
+ gravity_is_point = p_value;
+ break;
+ case PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ gravity_distance_scale = p_value;
+ break;
+ case PhysicsServer2D::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ point_attenuation = p_value;
+ break;
+ case PhysicsServer2D::AREA_PARAM_LINEAR_DAMP:
+ linear_damp = p_value;
+ break;
+ case PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP:
+ angular_damp = p_value;
+ break;
+ case PhysicsServer2D::AREA_PARAM_PRIORITY:
+ priority = p_value;
+ break;
}
}
Variant Area2DSW::get_param(PhysicsServer2D::AreaParameter p_param) const {
-
switch (p_param) {
- case PhysicsServer2D::AREA_PARAM_GRAVITY: return gravity;
- case PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR: return gravity_vector;
- case PhysicsServer2D::AREA_PARAM_GRAVITY_IS_POINT: return gravity_is_point;
- case PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: return gravity_distance_scale;
- case PhysicsServer2D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: return point_attenuation;
- case PhysicsServer2D::AREA_PARAM_LINEAR_DAMP: return linear_damp;
- case PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP: return angular_damp;
- case PhysicsServer2D::AREA_PARAM_PRIORITY: return priority;
+ case PhysicsServer2D::AREA_PARAM_GRAVITY:
+ return gravity;
+ case PhysicsServer2D::AREA_PARAM_GRAVITY_VECTOR:
+ return gravity_vector;
+ case PhysicsServer2D::AREA_PARAM_GRAVITY_IS_POINT:
+ return gravity_is_point;
+ case PhysicsServer2D::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ return gravity_distance_scale;
+ case PhysicsServer2D::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ return point_attenuation;
+ case PhysicsServer2D::AREA_PARAM_LINEAR_DAMP:
+ return linear_damp;
+ case PhysicsServer2D::AREA_PARAM_ANGULAR_DAMP:
+ return angular_damp;
+ case PhysicsServer2D::AREA_PARAM_PRIORITY:
+ return priority;
}
return Variant();
}
void Area2DSW::_queue_monitor_update() {
-
ERR_FAIL_COND(!get_space());
- if (!monitor_query_list.in_list())
+ if (!monitor_query_list.in_list()) {
get_space()->area_add_to_monitor_query_list(&monitor_query_list);
+ }
}
void Area2DSW::set_monitorable(bool p_monitorable) {
-
- if (monitorable == p_monitorable)
+ if (monitorable == p_monitorable) {
return;
+ }
monitorable = p_monitorable;
_set_static(!monitorable);
}
void Area2DSW::call_queries() {
-
if (monitor_callback_id.is_valid() && !monitored_bodies.empty()) {
-
Variant res[5];
Variant *resptr[5];
- for (int i = 0; i < 5; i++)
+ for (int i = 0; i < 5; i++) {
resptr[i] = &res[i];
+ }
Object *obj = ObjectDB::get_instance(monitor_callback_id);
if (!obj) {
@@ -190,9 +214,9 @@ void Area2DSW::call_queries() {
}
for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E; E = E->next()) {
-
- if (E->get().state == 0)
+ if (E->get().state == 0) {
continue; //nothing happened
+ }
res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED;
res[1] = E->key().rid;
@@ -208,11 +232,11 @@ void Area2DSW::call_queries() {
monitored_bodies.clear();
if (area_monitor_callback_id.is_valid() && !monitored_areas.empty()) {
-
Variant res[5];
Variant *resptr[5];
- for (int i = 0; i < 5; i++)
+ for (int i = 0; i < 5; i++) {
resptr[i] = &res[i];
+ }
Object *obj = ObjectDB::get_instance(area_monitor_callback_id);
if (!obj) {
@@ -222,9 +246,9 @@ void Area2DSW::call_queries() {
}
for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E; E = E->next()) {
-
- if (E->get().state == 0)
+ if (E->get().state == 0) {
continue; //nothing happened
+ }
res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED;
res[1] = E->key().rid;
@@ -246,7 +270,6 @@ Area2DSW::Area2DSW() :
CollisionObject2DSW(TYPE_AREA),
monitor_query_list(this),
moved_list(this) {
-
_set_static(true); //areas are not active by default
space_override_mode = PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED;
gravity = 9.80665;
diff --git a/servers/physics_2d/area_2d_sw.h b/servers/physics_2d/area_2d_sw.h
index ae2a8ff995..f14466f582 100644
--- a/servers/physics_2d/area_2d_sw.h
+++ b/servers/physics_2d/area_2d_sw.h
@@ -41,7 +41,6 @@ class Body2DSW;
class Constraint2DSW;
class Area2DSW : public CollisionObject2DSW {
-
PhysicsServer2D::AreaSpaceOverrideMode space_override_mode;
real_t gravity;
Vector2 gravity_vector;
@@ -63,23 +62,21 @@ class Area2DSW : public CollisionObject2DSW {
SelfList<Area2DSW> moved_list;
struct BodyKey {
-
RID rid;
ObjectID instance_id;
uint32_t body_shape;
uint32_t area_shape;
_FORCE_INLINE_ bool operator<(const BodyKey &p_key) const {
-
if (rid == p_key.rid) {
-
if (body_shape == p_key.body_shape) {
-
return area_shape < p_key.area_shape;
- } else
+ } else {
return body_shape < p_key.body_shape;
- } else
+ }
+ } else {
return rid < p_key.rid;
+ }
}
_FORCE_INLINE_ BodyKey() {}
@@ -88,7 +85,6 @@ class Area2DSW : public CollisionObject2DSW {
};
struct BodyState {
-
int state;
_FORCE_INLINE_ void inc() { state++; }
_FORCE_INLINE_ void dec() { state--; }
@@ -170,33 +166,35 @@ public:
};
void Area2DSW::add_body_to_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {
-
BodyKey bk(p_body, p_body_shape, p_area_shape);
monitored_bodies[bk].inc();
- if (!monitor_query_list.in_list())
+ if (!monitor_query_list.in_list()) {
_queue_monitor_update();
+ }
}
-void Area2DSW::remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {
+void Area2DSW::remove_body_from_query(Body2DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {
BodyKey bk(p_body, p_body_shape, p_area_shape);
monitored_bodies[bk].dec();
- if (!monitor_query_list.in_list())
+ if (!monitor_query_list.in_list()) {
_queue_monitor_update();
+ }
}
void Area2DSW::add_area_to_query(Area2DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) {
-
BodyKey bk(p_area, p_area_shape, p_self_shape);
monitored_areas[bk].inc();
- if (!monitor_query_list.in_list())
+ if (!monitor_query_list.in_list()) {
_queue_monitor_update();
+ }
}
-void Area2DSW::remove_area_from_query(Area2DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) {
+void Area2DSW::remove_area_from_query(Area2DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) {
BodyKey bk(p_area, p_area_shape, p_self_shape);
monitored_areas[bk].dec();
- if (!monitor_query_list.in_list())
+ if (!monitor_query_list.in_list()) {
_queue_monitor_update();
+ }
}
#endif // AREA_2D_SW_H
diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp
index 0e70a626c2..d7bceb9f02 100644
--- a/servers/physics_2d/area_pair_2d_sw.cpp
+++ b/servers/physics_2d/area_pair_2d_sw.cpp
@@ -32,7 +32,6 @@
#include "collision_solver_2d_sw.h"
bool AreaPair2DSW::setup(real_t p_step) {
-
bool result = false;
if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) {
@@ -42,20 +41,21 @@ bool AreaPair2DSW::setup(real_t p_step) {
}
if (result != colliding) {
-
if (result) {
-
- if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED)
+ if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED) {
body->add_area(area);
- if (area->has_monitor_callback())
+ }
+ if (area->has_monitor_callback()) {
area->add_body_to_query(body, body_shape, area_shape);
+ }
} else {
-
- if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED)
+ if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED) {
body->remove_area(area);
- if (area->has_monitor_callback())
+ }
+ if (area->has_monitor_callback()) {
area->remove_body_from_query(body, body_shape, area_shape);
+ }
}
colliding = result;
@@ -68,7 +68,6 @@ void AreaPair2DSW::solve(real_t p_step) {
}
AreaPair2DSW::AreaPair2DSW(Body2DSW *p_body, int p_body_shape, Area2DSW *p_area, int p_area_shape) {
-
body = p_body;
area = p_area;
body_shape = p_body_shape;
@@ -76,18 +75,19 @@ AreaPair2DSW::AreaPair2DSW(Body2DSW *p_body, int p_body_shape, Area2DSW *p_area,
colliding = false;
body->add_constraint(this, 0);
area->add_constraint(this);
- if (p_body->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC) //need to be active to process pair
+ if (p_body->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC) { //need to be active to process pair
p_body->set_active(true);
+ }
}
AreaPair2DSW::~AreaPair2DSW() {
-
if (colliding) {
-
- if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED)
+ if (area->get_space_override_mode() != PhysicsServer2D::AREA_SPACE_OVERRIDE_DISABLED) {
body->remove_area(area);
- if (area->has_monitor_callback())
+ }
+ if (area->has_monitor_callback()) {
area->remove_body_from_query(body, body_shape, area_shape);
+ }
}
body->remove_constraint(this);
area->remove_constraint(this);
@@ -96,7 +96,6 @@ AreaPair2DSW::~AreaPair2DSW() {
//////////////////////////////////
bool Area2Pair2DSW::setup(real_t p_step) {
-
bool result = false;
if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) {
result = false;
@@ -105,22 +104,23 @@ bool Area2Pair2DSW::setup(real_t p_step) {
}
if (result != colliding) {
-
if (result) {
-
- if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
+ if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
area_b->add_area_to_query(area_a, shape_a, shape_b);
+ }
- if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
+ if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
area_a->add_area_to_query(area_b, shape_b, shape_a);
+ }
} else {
-
- if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
+ if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
area_b->remove_area_from_query(area_a, shape_a, shape_b);
+ }
- if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
+ if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
area_a->remove_area_from_query(area_b, shape_b, shape_a);
+ }
}
colliding = result;
@@ -133,7 +133,6 @@ void Area2Pair2DSW::solve(real_t p_step) {
}
Area2Pair2DSW::Area2Pair2DSW(Area2DSW *p_area_a, int p_shape_a, Area2DSW *p_area_b, int p_shape_b) {
-
area_a = p_area_a;
area_b = p_area_b;
shape_a = p_shape_a;
@@ -144,14 +143,14 @@ Area2Pair2DSW::Area2Pair2DSW(Area2DSW *p_area_a, int p_shape_a, Area2DSW *p_area
}
Area2Pair2DSW::~Area2Pair2DSW() {
-
if (colliding) {
-
- if (area_b->has_area_monitor_callback())
+ if (area_b->has_area_monitor_callback()) {
area_b->remove_area_from_query(area_a, shape_a, shape_b);
+ }
- if (area_a->has_area_monitor_callback())
+ if (area_a->has_area_monitor_callback()) {
area_a->remove_area_from_query(area_b, shape_b, shape_a);
+ }
}
area_a->remove_constraint(this);
diff --git a/servers/physics_2d/area_pair_2d_sw.h b/servers/physics_2d/area_pair_2d_sw.h
index 78173d98b2..5e8670b464 100644
--- a/servers/physics_2d/area_pair_2d_sw.h
+++ b/servers/physics_2d/area_pair_2d_sw.h
@@ -36,7 +36,6 @@
#include "constraint_2d_sw.h"
class AreaPair2DSW : public Constraint2DSW {
-
Body2DSW *body;
Area2DSW *area;
int body_shape;
@@ -52,7 +51,6 @@ public:
};
class Area2Pair2DSW : public Constraint2DSW {
-
Area2DSW *area_a;
Area2DSW *area_b;
int shape_a;
diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp
index 39e28fd002..856bba78f7 100644
--- a/servers/physics_2d/body_2d_sw.cpp
+++ b/servers/physics_2d/body_2d_sw.cpp
@@ -34,19 +34,16 @@
#include "space_2d_sw.h"
void Body2DSW::_update_inertia() {
-
- if (!user_inertia && get_space() && !inertia_update_list.in_list())
+ if (!user_inertia && get_space() && !inertia_update_list.in_list()) {
get_space()->body_add_to_inertia_update_list(&inertia_update_list);
+ }
}
void Body2DSW::update_inertias() {
-
//update shapes and motions
switch (mode) {
-
case PhysicsServer2D::BODY_MODE_RIGID: {
-
if (user_inertia) {
_inv_inertia = inertia > 0 ? (1.0 / inertia) : 0;
break;
@@ -55,14 +52,12 @@ void Body2DSW::update_inertias() {
real_t total_area = 0;
for (int i = 0; i < get_shape_count(); i++) {
-
total_area += get_shape_aabb(i).get_area();
}
inertia = 0;
for (int i = 0; i < get_shape_count(); i++) {
-
if (is_shape_disabled(i)) {
continue;
}
@@ -80,20 +75,19 @@ void Body2DSW::update_inertias() {
_inv_inertia = inertia > 0 ? (1.0 / inertia) : 0;
- if (mass)
+ if (mass) {
_inv_mass = 1.0 / mass;
- else
+ } else {
_inv_mass = 0;
+ }
} break;
case PhysicsServer2D::BODY_MODE_KINEMATIC:
case PhysicsServer2D::BODY_MODE_STATIC: {
-
_inv_inertia = 0;
_inv_mass = 0;
} break;
case PhysicsServer2D::BODY_MODE_CHARACTER: {
-
_inv_inertia = 0;
_inv_mass = 1.0 / mass;
@@ -105,19 +99,22 @@ void Body2DSW::update_inertias() {
}
void Body2DSW::set_active(bool p_active) {
-
- if (active == p_active)
+ if (active == p_active) {
return;
+ }
active = p_active;
if (!p_active) {
- if (get_space())
+ if (get_space()) {
get_space()->body_remove_from_active_list(&active_list);
+ }
} else {
- if (mode == PhysicsServer2D::BODY_MODE_STATIC)
+ if (mode == PhysicsServer2D::BODY_MODE_STATIC) {
return; //static bodies can't become active
- if (get_space())
+ }
+ if (get_space()) {
get_space()->body_add_to_active_list(&active_list);
+ }
//still_time=0;
}
@@ -135,14 +132,11 @@ void Body2DSW::set_active(bool p_active) {
}
void Body2DSW::set_param(PhysicsServer2D::BodyParameter p_param, real_t p_value) {
-
switch (p_param) {
case PhysicsServer2D::BODY_PARAM_BOUNCE: {
-
bounce = p_value;
} break;
case PhysicsServer2D::BODY_PARAM_FRICTION: {
-
friction = p_value;
} break;
case PhysicsServer2D::BODY_PARAM_MASS: {
@@ -165,11 +159,9 @@ void Body2DSW::set_param(PhysicsServer2D::BodyParameter p_param, real_t p_value)
gravity_scale = p_value;
} break;
case PhysicsServer2D::BODY_PARAM_LINEAR_DAMP: {
-
linear_damp = p_value;
} break;
case PhysicsServer2D::BODY_PARAM_ANGULAR_DAMP: {
-
angular_damp = p_value;
} break;
default: {
@@ -178,14 +170,11 @@ void Body2DSW::set_param(PhysicsServer2D::BodyParameter p_param, real_t p_value)
}
real_t Body2DSW::get_param(PhysicsServer2D::BodyParameter p_param) const {
-
switch (p_param) {
case PhysicsServer2D::BODY_PARAM_BOUNCE: {
-
return bounce;
}
case PhysicsServer2D::BODY_PARAM_FRICTION: {
-
return friction;
}
case PhysicsServer2D::BODY_PARAM_MASS: {
@@ -198,11 +187,9 @@ real_t Body2DSW::get_param(PhysicsServer2D::BodyParameter p_param) const {
return gravity_scale;
}
case PhysicsServer2D::BODY_PARAM_LINEAR_DAMP: {
-
return linear_damp;
}
case PhysicsServer2D::BODY_PARAM_ANGULAR_DAMP: {
-
return angular_damp;
}
default: {
@@ -213,7 +200,6 @@ real_t Body2DSW::get_param(PhysicsServer2D::BodyParameter p_param) const {
}
void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) {
-
PhysicsServer2D::BodyMode prev = mode;
mode = p_mode;
@@ -221,7 +207,6 @@ void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) {
//CLEAR UP EVERYTHING IN CASE IT NOT WORKS!
case PhysicsServer2D::BODY_MODE_STATIC:
case PhysicsServer2D::BODY_MODE_KINEMATIC: {
-
_set_inv_transform(get_transform().affine_inverse());
_inv_mass = 0;
_inv_inertia = 0;
@@ -234,7 +219,6 @@ void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) {
}
} break;
case PhysicsServer2D::BODY_MODE_RIGID: {
-
_inv_mass = mass > 0 ? (1.0 / mass) : 0;
_inv_inertia = inertia > 0 ? (1.0 / inertia) : 0;
_set_static(false);
@@ -242,7 +226,6 @@ void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) {
} break;
case PhysicsServer2D::BODY_MODE_CHARACTER: {
-
_inv_mass = mass > 0 ? (1.0 / mass) : 0;
_inv_inertia = 0;
_set_static(false);
@@ -258,24 +241,20 @@ void Body2DSW::set_mode(PhysicsServer2D::BodyMode p_mode) {
_update_queries();
*/
}
-PhysicsServer2D::BodyMode Body2DSW::get_mode() const {
+PhysicsServer2D::BodyMode Body2DSW::get_mode() const {
return mode;
}
void Body2DSW::_shapes_changed() {
-
_update_inertia();
wakeup_neighbours();
}
void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_variant) {
-
switch (p_state) {
case PhysicsServer2D::BODY_STATE_TRANSFORM: {
-
if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC) {
-
new_transform = p_variant;
//wakeup_neighbours();
set_active(true);
@@ -292,8 +271,9 @@ void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_va
Transform2D t = p_variant;
t.orthonormalize();
new_transform = get_transform(); //used as old to compute motion
- if (t == new_transform)
+ if (t == new_transform) {
break;
+ }
_set_transform(t);
_set_inv_transform(get_transform().inverse());
}
@@ -301,7 +281,6 @@ void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_va
} break;
case PhysicsServer2D::BODY_STATE_LINEAR_VELOCITY: {
-
/*
if (mode==PhysicsServer2D::BODY_MODE_STATIC)
break;
@@ -321,8 +300,9 @@ void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_va
} break;
case PhysicsServer2D::BODY_STATE_SLEEPING: {
//?
- if (mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC)
+ if (mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) {
break;
+ }
bool do_sleep = p_variant;
if (do_sleep) {
linear_velocity = Vector2();
@@ -331,20 +311,22 @@ void Body2DSW::set_state(PhysicsServer2D::BodyState p_state, const Variant &p_va
//biased_angular_velocity=Vector3();
set_active(false);
} else {
- if (mode != PhysicsServer2D::BODY_MODE_STATIC)
+ if (mode != PhysicsServer2D::BODY_MODE_STATIC) {
set_active(true);
+ }
}
} break;
case PhysicsServer2D::BODY_STATE_CAN_SLEEP: {
can_sleep = p_variant;
- if (mode == PhysicsServer2D::BODY_MODE_RIGID && !active && !can_sleep)
+ if (mode == PhysicsServer2D::BODY_MODE_RIGID && !active && !can_sleep) {
set_active(true);
+ }
} break;
}
}
-Variant Body2DSW::get_state(PhysicsServer2D::BodyState p_state) const {
+Variant Body2DSW::get_state(PhysicsServer2D::BodyState p_state) const {
switch (p_state) {
case PhysicsServer2D::BODY_STATE_TRANSFORM: {
return get_transform();
@@ -367,26 +349,27 @@ Variant Body2DSW::get_state(PhysicsServer2D::BodyState p_state) const {
}
void Body2DSW::set_space(Space2DSW *p_space) {
-
if (get_space()) {
-
wakeup_neighbours();
- if (inertia_update_list.in_list())
+ if (inertia_update_list.in_list()) {
get_space()->body_remove_from_inertia_update_list(&inertia_update_list);
- if (active_list.in_list())
+ }
+ if (active_list.in_list()) {
get_space()->body_remove_from_active_list(&active_list);
- if (direct_state_query_list.in_list())
+ }
+ if (direct_state_query_list.in_list()) {
get_space()->body_remove_from_state_query_list(&direct_state_query_list);
+ }
}
_set_space(p_space);
if (get_space()) {
-
_update_inertia();
- if (active)
+ if (active) {
get_space()->body_add_to_active_list(&active_list);
+ }
/*
_update_queries();
if (is_active()) {
@@ -400,7 +383,6 @@ void Body2DSW::set_space(Space2DSW *p_space) {
}
void Body2DSW::_compute_area_gravity_and_dampenings(const Area2DSW *p_area) {
-
if (p_area->is_gravity_point()) {
if (p_area->get_gravity_distance_scale() > 0) {
Vector2 v = p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin();
@@ -417,9 +399,9 @@ void Body2DSW::_compute_area_gravity_and_dampenings(const Area2DSW *p_area) {
}
void Body2DSW::integrate_forces(real_t p_step) {
-
- if (mode == PhysicsServer2D::BODY_MODE_STATIC)
+ if (mode == PhysicsServer2D::BODY_MODE_STATIC) {
return;
+ }
Area2DSW *def_area = get_space()->get_default_area();
// Area2DSW *damp_area = def_area;
@@ -461,15 +443,17 @@ void Body2DSW::integrate_forces(real_t p_step) {
gravity *= gravity_scale;
// If less than 0, override dampenings with that of the Body2D
- if (angular_damp >= 0)
+ if (angular_damp >= 0) {
area_angular_damp = angular_damp;
+ }
/*
else
area_angular_damp=damp_area->get_angular_damp();
*/
- if (linear_damp >= 0)
+ if (linear_damp >= 0) {
area_linear_damp = linear_damp;
+ }
/*
else
area_linear_damp=damp_area->get_linear_damp();
@@ -479,7 +463,6 @@ void Body2DSW::integrate_forces(real_t p_step) {
bool do_motion = false;
if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC) {
-
//compute motion, angular and etc. velocities from prev transform
motion = new_transform.get_origin() - get_transform().get_origin();
linear_velocity = motion / p_step;
@@ -506,13 +489,15 @@ void Body2DSW::integrate_forces(real_t p_step) {
real_t damp = 1.0 - p_step * area_linear_damp;
- if (damp < 0) // reached zero in the given time
+ if (damp < 0) { // reached zero in the given time
damp = 0;
+ }
real_t angular_damp = 1.0 - p_step * area_angular_damp;
- if (angular_damp < 0) // reached zero in the given time
+ if (angular_damp < 0) { // reached zero in the given time
angular_damp = 0;
+ }
linear_velocity *= damp;
angular_velocity *= angular_damp;
@@ -522,7 +507,6 @@ void Body2DSW::integrate_forces(real_t p_step) {
}
if (continuous_cd_mode != PhysicsServer2D::CCD_MODE_DISABLED) {
-
motion = linear_velocity * p_step;
do_motion = true;
}
@@ -544,19 +528,20 @@ void Body2DSW::integrate_forces(real_t p_step) {
}
void Body2DSW::integrate_velocities(real_t p_step) {
-
- if (mode == PhysicsServer2D::BODY_MODE_STATIC)
+ if (mode == PhysicsServer2D::BODY_MODE_STATIC) {
return;
+ }
- if (fi_callback)
+ if (fi_callback) {
get_space()->body_add_to_state_query_list(&direct_state_query_list);
+ }
if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC) {
-
_set_transform(new_transform, false);
_set_inv_transform(new_transform.affine_inverse());
- if (contacts.size() == 0 && linear_velocity == Vector2() && angular_velocity == 0)
+ if (contacts.size() == 0 && linear_velocity == Vector2() && angular_velocity == 0) {
set_active(false); //stopped moving, deactivate
+ }
return;
}
@@ -569,38 +554,37 @@ void Body2DSW::integrate_velocities(real_t p_step) {
_set_transform(Transform2D(angle, pos), continuous_cd_mode == PhysicsServer2D::CCD_MODE_DISABLED);
_set_inv_transform(get_transform().inverse());
- if (continuous_cd_mode != PhysicsServer2D::CCD_MODE_DISABLED)
+ if (continuous_cd_mode != PhysicsServer2D::CCD_MODE_DISABLED) {
new_transform = get_transform();
+ }
//_update_inertia_tensor();
}
void Body2DSW::wakeup_neighbours() {
-
for (Map<Constraint2DSW *, int>::Element *E = constraint_map.front(); E; E = E->next()) {
-
const Constraint2DSW *c = E->key();
Body2DSW **n = c->get_body_ptr();
int bc = c->get_body_count();
for (int i = 0; i < bc; i++) {
-
- if (i == E->get())
+ if (i == E->get()) {
continue;
+ }
Body2DSW *b = n[i];
- if (b->mode != PhysicsServer2D::BODY_MODE_RIGID)
+ if (b->mode != PhysicsServer2D::BODY_MODE_RIGID) {
continue;
+ }
- if (!b->is_active())
+ if (!b->is_active()) {
b->set_active(true);
+ }
}
}
}
void Body2DSW::call_queries() {
-
if (fi_callback) {
-
PhysicsDirectBodyState2DSW *dbs = PhysicsDirectBodyState2DSW::singleton;
dbs->body = this;
@@ -609,12 +593,10 @@ void Body2DSW::call_queries() {
Object *obj = ObjectDB::get_instance(fi_callback->id);
if (!obj) {
-
set_force_integration_callback(ObjectID(), StringName());
} else {
Callable::CallError ce;
if (fi_callback->callback_udata.get_type() != Variant::NIL) {
-
obj->call(fi_callback->method, vp, 2, ce);
} else {
@@ -625,36 +607,31 @@ void Body2DSW::call_queries() {
}
bool Body2DSW::sleep_test(real_t p_step) {
-
- if (mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC)
+ if (mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) {
return true; //
- else if (mode == PhysicsServer2D::BODY_MODE_CHARACTER)
+ } else if (mode == PhysicsServer2D::BODY_MODE_CHARACTER) {
return !active; // characters and kinematic bodies don't sleep unless asked to sleep
- else if (!can_sleep)
+ } else if (!can_sleep) {
return false;
+ }
if (Math::abs(angular_velocity) < get_space()->get_body_angular_velocity_sleep_threshold() && Math::abs(linear_velocity.length_squared()) < get_space()->get_body_linear_velocity_sleep_threshold() * get_space()->get_body_linear_velocity_sleep_threshold()) {
-
still_time += p_step;
return still_time > get_space()->get_body_time_to_sleep();
} else {
-
still_time = 0; //maybe this should be set to 0 on set_active?
return false;
}
}
void Body2DSW::set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata) {
-
if (fi_callback) {
-
memdelete(fi_callback);
fi_callback = nullptr;
}
if (p_id.is_valid()) {
-
fi_callback = memnew(ForceIntegrationCallback);
fi_callback->id = p_id;
fi_callback->method = p_method;
@@ -667,7 +644,6 @@ Body2DSW::Body2DSW() :
active_list(this),
inertia_update_list(this),
direct_state_query_list(this) {
-
mode = PhysicsServer2D::BODY_MODE_RIGID;
active = true;
angular_velocity = 0;
@@ -701,31 +677,27 @@ Body2DSW::Body2DSW() :
}
Body2DSW::~Body2DSW() {
-
- if (fi_callback)
+ if (fi_callback) {
memdelete(fi_callback);
+ }
}
PhysicsDirectBodyState2DSW *PhysicsDirectBodyState2DSW::singleton = nullptr;
PhysicsDirectSpaceState2D *PhysicsDirectBodyState2DSW::get_space_state() {
-
return body->get_space()->get_direct_state();
}
Variant PhysicsDirectBodyState2DSW::get_contact_collider_shape_metadata(int p_contact_idx) const {
-
ERR_FAIL_INDEX_V(p_contact_idx, body->contact_count, Variant());
if (!PhysicsServer2DSW::singletonsw->body_owner.owns(body->contacts[p_contact_idx].collider)) {
-
return Variant();
}
Body2DSW *other = PhysicsServer2DSW::singletonsw->body_owner.getornull(body->contacts[p_contact_idx].collider);
int sidx = body->contacts[p_contact_idx].collider_shape;
if (sidx < 0 || sidx >= other->get_shape_count()) {
-
return Variant();
}
diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h
index 0514b263b4..2300c9cdee 100644
--- a/servers/physics_2d/body_2d_sw.h
+++ b/servers/physics_2d/body_2d_sw.h
@@ -38,7 +38,6 @@
class Constraint2DSW;
class Body2DSW : public CollisionObject2DSW {
-
PhysicsServer2D::BodyMode mode;
Vector2 biased_linear_velocity;
@@ -87,7 +86,6 @@ class Body2DSW : public CollisionObject2DSW {
Map<Constraint2DSW *, int> constraint_map;
struct AreaCMP {
-
Area2DSW *area;
int refCount;
_FORCE_INLINE_ bool operator==(const AreaCMP &p_cmp) const { return area->get_self() == p_cmp.area->get_self(); }
@@ -102,7 +100,6 @@ class Body2DSW : public CollisionObject2DSW {
Vector<AreaCMP> areas;
struct Contact {
-
Vector2 local_pos;
Vector2 local_normal;
real_t depth;
@@ -118,7 +115,6 @@ class Body2DSW : public CollisionObject2DSW {
int contact_count;
struct ForceIntegrationCallback {
-
ObjectID id;
StringName method;
Variant callback_udata;
@@ -150,15 +146,18 @@ public:
int index = areas.find(AreaCMP(p_area));
if (index > -1) {
areas.write[index].refCount -= 1;
- if (areas[index].refCount < 1)
+ if (areas[index].refCount < 1) {
areas.remove(index);
+ }
}
}
_FORCE_INLINE_ void set_max_contacts_reported(int p_size) {
contacts.resize(p_size);
contact_count = 0;
- if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC && p_size) set_active(true);
+ if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC && p_size) {
+ set_active(true);
+ }
}
_FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); }
@@ -205,7 +204,6 @@ public:
}
_FORCE_INLINE_ void apply_impulse(const Vector2 &p_offset, const Vector2 &p_impulse) {
-
linear_velocity += p_impulse * _inv_mass;
angular_velocity += _inv_inertia * p_offset.cross(p_impulse);
}
@@ -215,7 +213,6 @@ public:
}
_FORCE_INLINE_ void apply_bias_impulse(const Vector2 &p_pos, const Vector2 &p_j) {
-
biased_linear_velocity += p_j * _inv_mass;
biased_angular_velocity += _inv_inertia * p_pos.cross(p_j);
}
@@ -224,8 +221,9 @@ public:
_FORCE_INLINE_ bool is_active() const { return active; }
_FORCE_INLINE_ void wakeup() {
- if ((!get_space()) || mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC)
+ if ((!get_space()) || mode == PhysicsServer2D::BODY_MODE_STATIC || mode == PhysicsServer2D::BODY_MODE_KINEMATIC) {
return;
+ }
set_active(true);
}
@@ -249,7 +247,6 @@ public:
}
_FORCE_INLINE_ void add_force(const Vector2 &p_offset, const Vector2 &p_force) {
-
applied_force += p_force;
applied_torque += p_offset.cross(p_force);
}
@@ -277,7 +274,6 @@ public:
void integrate_velocities(real_t p_step);
_FORCE_INLINE_ Vector2 get_motion() const {
-
if (mode > PhysicsServer2D::BODY_MODE_KINEMATIC) {
return new_transform.get_origin() - get_transform().get_origin();
} else if (mode == PhysicsServer2D::BODY_MODE_KINEMATIC) {
@@ -298,11 +294,11 @@ public:
//add contact inline
void Body2DSW::add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_normal, real_t p_depth, int p_local_shape, const Vector2 &p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID &p_collider, const Vector2 &p_collider_velocity_at_pos) {
-
int c_max = contacts.size();
- if (c_max == 0)
+ if (c_max == 0) {
return;
+ }
Contact *c = contacts.ptrw();
@@ -311,11 +307,9 @@ void Body2DSW::add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_no
if (contact_count < c_max) {
idx = contact_count++;
} else {
-
real_t least_depth = 1e20;
int least_deep = -1;
for (int i = 0; i < c_max; i++) {
-
if (i == 0 || c[i].depth < least_depth) {
least_deep = i;
least_depth = c[i].depth;
@@ -323,11 +317,11 @@ void Body2DSW::add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_no
}
if (least_deep >= 0 && least_depth < p_depth) {
-
idx = least_deep;
}
- if (idx == -1)
+ if (idx == -1) {
return; //none least deepe than this
+ }
}
c[idx].local_pos = p_local_pos;
@@ -342,7 +336,6 @@ void Body2DSW::add_contact(const Vector2 &p_local_pos, const Vector2 &p_local_no
}
class PhysicsDirectBodyState2DSW : public PhysicsDirectBodyState2D {
-
GDCLASS(PhysicsDirectBodyState2DSW, PhysicsDirectBodyState2D);
public:
diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp
index f38a76cff6..e483ddf1cc 100644
--- a/servers/physics_2d/body_pair_2d_sw.cpp
+++ b/servers/physics_2d/body_pair_2d_sw.cpp
@@ -36,14 +36,12 @@
#define ACCUMULATE_IMPULSES
void BodyPair2DSW::_add_contact(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_self) {
-
BodyPair2DSW *self = (BodyPair2DSW *)p_self;
self->_contact_added_callback(p_point_A, p_point_B);
}
void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vector2 &p_point_B) {
-
// check if we already have the contact
Vector2 local_A = A->get_inv_transform().basis_xform(p_point_A);
@@ -69,12 +67,10 @@ void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vecto
real_t recycle_radius_2 = space->get_contact_recycle_radius() * space->get_contact_recycle_radius();
for (int i = 0; i < contact_count; i++) {
-
Contact &c = contacts[i];
if (
c.local_A.distance_squared_to(local_A) < (recycle_radius_2) &&
c.local_B.distance_squared_to(local_B) < (recycle_radius_2)) {
-
contact.acc_normal_impulse = c.acc_normal_impulse;
contact.acc_tangent_impulse = c.acc_tangent_impulse;
contact.acc_bias_impulse = c.acc_bias_impulse;
@@ -86,14 +82,12 @@ void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vecto
// figure out if the contact amount must be reduced to fit the new contact
if (new_index == MAX_CONTACTS) {
-
// remove the contact with the minimum depth
int least_deep = -1;
real_t min_depth = 1e10;
for (int i = 0; i <= contact_count; i++) {
-
Contact &c = (i == contact_count) ? contact : contacts[i];
Vector2 global_A = A->get_transform().basis_xform(c.local_A);
Vector2 global_B = B->get_transform().basis_xform(c.local_B) + offset_B;
@@ -102,7 +96,6 @@ void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vecto
real_t depth = axis.dot(c.normal);
if (depth < min_depth) {
-
min_depth = depth;
least_deep = i;
}
@@ -121,20 +114,17 @@ void BodyPair2DSW::_contact_added_callback(const Vector2 &p_point_A, const Vecto
contacts[new_index] = contact;
if (new_index == contact_count) {
-
contact_count++;
}
}
void BodyPair2DSW::_validate_contacts() {
-
//make sure to erase contacts that are no longer valid
real_t max_separation = space->get_contact_max_separation();
real_t max_separation2 = max_separation * max_separation;
for (int i = 0; i < contact_count; i++) {
-
Contact &c = contacts[i];
bool erase = false;
@@ -169,11 +159,11 @@ void BodyPair2DSW::_validate_contacts() {
}
bool BodyPair2DSW::_test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const Transform2D &p_xform_A, Body2DSW *p_B, int p_shape_B, const Transform2D &p_xform_B, bool p_swap_result) {
-
Vector2 motion = p_A->get_linear_velocity() * p_step;
real_t mlen = motion.length();
- if (mlen < CMP_EPSILON)
+ if (mlen < CMP_EPSILON) {
return false;
+ }
Vector2 mnormal = motion / mlen;
@@ -199,8 +189,9 @@ bool BodyPair2DSW::_test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const
Vector2 local_to = from_inv.xform(to);
Vector2 rpos, rnorm;
- if (!p_B->get_shape(p_shape_B)->intersect_segment(local_from, local_to, rpos, rnorm))
+ if (!p_B->get_shape(p_shape_B)->intersect_segment(local_from, local_to, rpos, rnorm)) {
return false;
+ }
//ray hit something
@@ -211,10 +202,11 @@ bool BodyPair2DSW::_test_ccd(real_t p_step, Body2DSW *p_A, int p_shape_A, const
//create a contact
- if (p_swap_result)
+ if (p_swap_result) {
_contact_added_callback(contact_B, contact_A);
- else
+ } else {
_contact_added_callback(contact_A, contact_B);
+ }
return true;
}
@@ -228,7 +220,6 @@ real_t combine_friction(Body2DSW *A, Body2DSW *B) {
}
bool BodyPair2DSW::setup(real_t p_step) {
-
//cannot collide
if (!A->test_collision_mask(B) || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode() <= PhysicsServer2D::BODY_MODE_KINEMATIC && B->get_mode() <= PhysicsServer2D::BODY_MODE_KINEMATIC && A->get_max_contacts_reported() == 0 && B->get_max_contacts_reported() == 0)) {
collided = false;
@@ -270,17 +261,18 @@ bool BodyPair2DSW::setup(real_t p_step) {
collided = CollisionSolver2DSW::solve(shape_A_ptr, xform_A, motion_A, shape_B_ptr, xform_B, motion_B, _add_contact, this, &sep_axis);
if (!collided) {
-
//test ccd (currently just a raycast)
if (A->get_continuous_collision_detection_mode() == PhysicsServer2D::CCD_MODE_CAST_RAY && A->get_mode() > PhysicsServer2D::BODY_MODE_KINEMATIC) {
- if (_test_ccd(p_step, A, shape_A, xform_A, B, shape_B, xform_B))
+ if (_test_ccd(p_step, A, shape_A, xform_A, B, shape_B, xform_B)) {
collided = true;
+ }
}
if (B->get_continuous_collision_detection_mode() == PhysicsServer2D::CCD_MODE_CAST_RAY && B->get_mode() > PhysicsServer2D::BODY_MODE_KINEMATIC) {
- if (_test_ccd(p_step, B, shape_B, xform_B, A, shape_A, xform_A, true))
+ if (_test_ccd(p_step, B, shape_B, xform_B, A, shape_A, xform_A, true)) {
collided = true;
+ }
}
if (!collided) {
@@ -289,22 +281,24 @@ bool BodyPair2DSW::setup(real_t p_step) {
}
}
- if (oneway_disabled)
+ if (oneway_disabled) {
return false;
+ }
//if (!prev_collided) {
{
-
if (A->is_shape_set_as_one_way_collision(shape_A)) {
Vector2 direction = xform_A.get_axis(1).normalized();
bool valid = false;
if (B->get_linear_velocity().dot(direction) >= 0) {
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (!c.reused)
+ if (!c.reused) {
continue;
- if (c.normal.dot(direction) > 0) //greater (normal inverted)
+ }
+ if (c.normal.dot(direction) > 0) { //greater (normal inverted)
continue;
+ }
valid = true;
break;
@@ -324,10 +318,12 @@ bool BodyPair2DSW::setup(real_t p_step) {
if (A->get_linear_velocity().dot(direction) >= 0) {
for (int i = 0; i < contact_count; i++) {
Contact &c = contacts[i];
- if (!c.reused)
+ if (!c.reused) {
continue;
- if (c.normal.dot(direction) < 0) //less (normal ok)
+ }
+ if (c.normal.dot(direction) < 0) { //less (normal ok)
continue;
+ }
valid = true;
break;
@@ -345,13 +341,13 @@ bool BodyPair2DSW::setup(real_t p_step) {
real_t bias = 0.3;
if (shape_A_ptr->get_custom_bias() || shape_B_ptr->get_custom_bias()) {
-
- if (shape_A_ptr->get_custom_bias() == 0)
+ if (shape_A_ptr->get_custom_bias() == 0) {
bias = shape_B_ptr->get_custom_bias();
- else if (shape_B_ptr->get_custom_bias() == 0)
+ } else if (shape_B_ptr->get_custom_bias() == 0) {
bias = shape_A_ptr->get_custom_bias();
- else
+ } else {
bias = (shape_B_ptr->get_custom_bias() + shape_A_ptr->get_custom_bias()) * 0.5;
+ }
}
cc = 0;
@@ -361,7 +357,6 @@ bool BodyPair2DSW::setup(real_t p_step) {
bool do_process = false;
for (int i = 0; i < contact_count; i++) {
-
Contact &c = contacts[i];
Vector2 global_A = xform_Au.xform(c.local_A);
@@ -388,7 +383,6 @@ bool BodyPair2DSW::setup(real_t p_step) {
c.rB = global_B - offset_B;
if (gather_A | gather_B) {
-
//Vector2 crB( -B->get_angular_velocity() * c.rB.y, B->get_angular_velocity() * c.rB.x );
global_A += offset_A;
@@ -399,7 +393,6 @@ bool BodyPair2DSW::setup(real_t p_step) {
A->add_contact(global_A, -c.normal, depth, shape_A, global_B, shape_B, B->get_instance_id(), B->get_self(), crB + B->get_linear_velocity());
}
if (gather_B) {
-
Vector2 crA(-A->get_angular_velocity() * c.rA.y, A->get_angular_velocity() * c.rA.x);
B->add_contact(global_B, c.normal, depth, shape_B, global_A, shape_A, A->get_instance_id(), A->get_self(), crA + A->get_linear_velocity());
}
@@ -442,7 +435,6 @@ bool BodyPair2DSW::setup(real_t p_step) {
c.bounce = combine_bounce(A, B);
if (c.bounce) {
-
Vector2 crA(-A->get_angular_velocity() * c.rA.y, A->get_angular_velocity() * c.rA.x);
Vector2 crB(-B->get_angular_velocity() * c.rB.y, B->get_angular_velocity() * c.rB.x);
Vector2 dv = B->get_linear_velocity() + crB - A->get_linear_velocity() - crA;
@@ -456,17 +448,17 @@ bool BodyPair2DSW::setup(real_t p_step) {
}
void BodyPair2DSW::solve(real_t p_step) {
-
- if (!collided)
+ if (!collided) {
return;
+ }
for (int i = 0; i < contact_count; ++i) {
-
Contact &c = contacts[i];
cc++;
- if (!c.active)
+ if (!c.active) {
continue;
+ }
// Relative velocity at contact
@@ -512,7 +504,6 @@ void BodyPair2DSW::solve(real_t p_step) {
BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A, Body2DSW *p_B, int p_shape_B) :
Constraint2DSW(_arr, 2) {
-
A = p_A;
B = p_B;
shape_A = p_shape_A;
@@ -526,7 +517,6 @@ BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A, Body2DSW *p_B, int p_sh
}
BodyPair2DSW::~BodyPair2DSW() {
-
A->remove_constraint(this);
B->remove_constraint(this);
}
diff --git a/servers/physics_2d/body_pair_2d_sw.h b/servers/physics_2d/body_pair_2d_sw.h
index e46ecbc8eb..ea4d55841a 100644
--- a/servers/physics_2d/body_pair_2d_sw.h
+++ b/servers/physics_2d/body_pair_2d_sw.h
@@ -35,7 +35,6 @@
#include "constraint_2d_sw.h"
class BodyPair2DSW : public Constraint2DSW {
-
enum {
MAX_CONTACTS = 2
};
@@ -54,7 +53,6 @@ class BodyPair2DSW : public Constraint2DSW {
Space2DSW *space;
struct Contact {
-
Vector2 position;
Vector2 normal;
Vector2 local_A, local_B;
diff --git a/servers/physics_2d/broad_phase_2d_basic.cpp b/servers/physics_2d/broad_phase_2d_basic.cpp
index 5e3a13f4dd..8c7e715a09 100644
--- a/servers/physics_2d/broad_phase_2d_basic.cpp
+++ b/servers/physics_2d/broad_phase_2d_basic.cpp
@@ -31,7 +31,6 @@
#include "broad_phase_2d_basic.h"
BroadPhase2DBasic::ID BroadPhase2DBasic::create(CollisionObject2DSW *p_object_, int p_subindex) {
-
current++;
Element e;
@@ -44,76 +43,71 @@ BroadPhase2DBasic::ID BroadPhase2DBasic::create(CollisionObject2DSW *p_object_,
}
void BroadPhase2DBasic::move(ID p_id, const Rect2 &p_aabb) {
-
Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
E->get().aabb = p_aabb;
}
-void BroadPhase2DBasic::set_static(ID p_id, bool p_static) {
+void BroadPhase2DBasic::set_static(ID p_id, bool p_static) {
Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
E->get()._static = p_static;
}
-void BroadPhase2DBasic::remove(ID p_id) {
+void BroadPhase2DBasic::remove(ID p_id) {
Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
element_map.erase(E);
}
CollisionObject2DSW *BroadPhase2DBasic::get_object(ID p_id) const {
-
const Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND_V(!E, nullptr);
return E->get().owner;
}
-bool BroadPhase2DBasic::is_static(ID p_id) const {
+bool BroadPhase2DBasic::is_static(ID p_id) const {
const Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND_V(!E, false);
return E->get()._static;
}
-int BroadPhase2DBasic::get_subindex(ID p_id) const {
+int BroadPhase2DBasic::get_subindex(ID p_id) const {
const Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND_V(!E, -1);
return E->get().subindex;
}
int BroadPhase2DBasic::cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) {
-
int rc = 0;
for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) {
-
const Rect2 aabb = E->get().aabb;
if (aabb.intersects_segment(p_from, p_to)) {
-
p_results[rc] = E->get().owner;
p_result_indices[rc] = E->get().subindex;
rc++;
- if (rc >= p_max_results)
+ if (rc >= p_max_results) {
break;
+ }
}
}
return rc;
}
-int BroadPhase2DBasic::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) {
+int BroadPhase2DBasic::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) {
int rc = 0;
for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) {
-
const Rect2 aabb = E->get().aabb;
if (aabb.intersects(p_aabb)) {
-
p_results[rc] = E->get().owner;
p_result_indices[rc] = E->get().subindex;
rc++;
- if (rc >= p_max_results)
+ if (rc >= p_max_results) {
break;
+ }
}
}
@@ -121,28 +115,25 @@ int BroadPhase2DBasic::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_re
}
void BroadPhase2DBasic::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) {
-
pair_userdata = p_userdata;
pair_callback = p_pair_callback;
}
-void BroadPhase2DBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) {
+void BroadPhase2DBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) {
unpair_userdata = p_userdata;
unpair_callback = p_unpair_callback;
}
void BroadPhase2DBasic::update() {
-
// recompute pairs
for (Map<ID, Element>::Element *I = element_map.front(); I; I = I->next()) {
-
for (Map<ID, Element>::Element *J = I->next(); J; J = J->next()) {
-
Element *elem_A = &I->get();
Element *elem_B = &J->get();
- if (elem_A->owner == elem_B->owner)
+ if (elem_A->owner == elem_B->owner) {
continue;
+ }
bool pair_ok = elem_A->aabb.intersects(elem_B->aabb) && (!elem_A->_static || !elem_B->_static);
@@ -151,16 +142,17 @@ void BroadPhase2DBasic::update() {
Map<PairKey, void *>::Element *E = pair_map.find(key);
if (!pair_ok && E) {
- if (unpair_callback)
+ if (unpair_callback) {
unpair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, E->get(), unpair_userdata);
+ }
pair_map.erase(key);
}
if (pair_ok && !E) {
-
void *data = nullptr;
- if (pair_callback)
+ if (pair_callback) {
data = pair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, unpair_userdata);
+ }
pair_map.insert(key, data);
}
}
@@ -168,12 +160,10 @@ void BroadPhase2DBasic::update() {
}
BroadPhase2DSW *BroadPhase2DBasic::_create() {
-
return memnew(BroadPhase2DBasic);
}
BroadPhase2DBasic::BroadPhase2DBasic() {
-
current = 1;
unpair_callback = nullptr;
unpair_userdata = nullptr;
diff --git a/servers/physics_2d/broad_phase_2d_basic.h b/servers/physics_2d/broad_phase_2d_basic.h
index 7d02590af9..ec5cfdbf1d 100644
--- a/servers/physics_2d/broad_phase_2d_basic.h
+++ b/servers/physics_2d/broad_phase_2d_basic.h
@@ -34,9 +34,7 @@
#include "core/map.h"
#include "space_2d_sw.h"
class BroadPhase2DBasic : public BroadPhase2DSW {
-
struct Element {
-
CollisionObject2DSW *owner;
bool _static;
Rect2 aabb;
@@ -48,7 +46,6 @@ class BroadPhase2DBasic : public BroadPhase2DSW {
ID current;
struct PairKey {
-
union {
struct {
ID a;
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
index 2cb021258a..ae549ed2e4 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
@@ -34,13 +34,11 @@
#define LARGE_ELEMENT_FI 1.01239812
void BroadPhase2DHashGrid::_pair_attempt(Element *p_elem, Element *p_with) {
-
Map<Element *, PairData *>::Element *E = p_elem->paired.find(p_with);
ERR_FAIL_COND(p_elem->_static && p_with->_static);
if (!E) {
-
PairData *pd = memnew(PairData);
p_elem->paired[p_with] = pd;
p_with->paired[p_elem] = pd;
@@ -50,7 +48,6 @@ void BroadPhase2DHashGrid::_pair_attempt(Element *p_elem, Element *p_with) {
}
void BroadPhase2DHashGrid::_unpair_attempt(Element *p_elem, Element *p_with) {
-
Map<Element *, PairData *>::Element *E = p_elem->paired.find(p_with);
ERR_FAIL_COND(!E); //this should really be paired..
@@ -58,7 +55,6 @@ void BroadPhase2DHashGrid::_unpair_attempt(Element *p_elem, Element *p_with) {
E->get()->rc--;
if (E->get()->rc == 0) {
-
if (E->get()->colliding) {
//uncollide
if (unpair_callback) {
@@ -73,20 +69,15 @@ void BroadPhase2DHashGrid::_unpair_attempt(Element *p_elem, Element *p_with) {
}
void BroadPhase2DHashGrid::_check_motion(Element *p_elem) {
-
for (Map<Element *, PairData *>::Element *E = p_elem->paired.front(); E; E = E->next()) {
-
bool pairing = p_elem->aabb.intersects(E->key()->aabb);
if (pairing != E->get()->colliding) {
-
if (pairing) {
-
if (pair_callback) {
E->get()->ud = pair_callback(p_elem->owner, p_elem->subindex, E->key()->owner, E->key()->subindex, pair_userdata);
}
} else {
-
if (unpair_callback) {
unpair_callback(p_elem->owner, p_elem->subindex, E->key()->owner, E->key()->subindex, E->get()->ud, unpair_userdata);
}
@@ -98,17 +89,19 @@ void BroadPhase2DHashGrid::_check_motion(Element *p_elem) {
}
void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, bool p_static) {
-
Vector2 sz = (p_rect.size / cell_size * LARGE_ELEMENT_FI); //use magic number to avoid floating point issues
if (sz.width * sz.height > large_object_min_surface) {
//large object, do not use grid, must check against all elements
for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) {
- if (E->key() == p_elem->self)
+ if (E->key() == p_elem->self) {
continue; // do not pair against itself
- if (E->get().owner == p_elem->owner)
+ }
+ if (E->get().owner == p_elem->owner) {
continue;
- if (E->get()._static && p_static)
+ }
+ if (E->get()._static && p_static) {
continue;
+ }
_pair_attempt(p_elem, &E->get());
}
@@ -121,9 +114,7 @@ void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, boo
Point2i to = ((p_rect.position + p_rect.size) / cell_size).floor();
for (int i = from.x; i <= to.x; i++) {
-
for (int j = from.y; j <= to.y; j++) {
-
PosKey pk;
pk.x = i;
pk.y = j;
@@ -132,7 +123,6 @@ void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, boo
PosBin *pb = hash_table[idx];
while (pb) {
-
if (pb->key == pk) {
break;
}
@@ -156,26 +146,23 @@ void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, boo
}
} else {
if (pb->object_set[p_elem].inc() == 1) {
-
entered = true;
}
}
if (entered) {
-
for (Map<Element *, RC>::Element *E = pb->object_set.front(); E; E = E->next()) {
-
- if (E->key()->owner == p_elem->owner)
+ if (E->key()->owner == p_elem->owner) {
continue;
+ }
_pair_attempt(p_elem, E->key());
}
if (!p_static) {
-
for (Map<Element *, RC>::Element *E = pb->static_object_set.front(); E; E = E->next()) {
-
- if (E->key()->owner == p_elem->owner)
+ if (E->key()->owner == p_elem->owner) {
continue;
+ }
_pair_attempt(p_elem, E->key());
}
}
@@ -186,23 +173,23 @@ void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, boo
//pair separatedly with large elements
for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) {
-
- if (E->key() == p_elem)
+ if (E->key() == p_elem) {
continue; // do not pair against itself
- if (E->key()->owner == p_elem->owner)
+ }
+ if (E->key()->owner == p_elem->owner) {
continue;
- if (E->key()->_static && p_static)
+ }
+ if (E->key()->_static && p_static) {
continue;
+ }
_pair_attempt(E->key(), p_elem);
}
}
void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool p_static) {
-
Vector2 sz = (p_rect.size / cell_size * LARGE_ELEMENT_FI);
if (sz.width * sz.height > large_object_min_surface) {
-
//unpair all elements, instead of checking all, just check what is already paired, so we at least save from checking static vs static
Map<Element *, PairData *>::Element *E = p_elem->paired.front();
while (E) {
@@ -221,9 +208,7 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool
Point2i to = ((p_rect.position + p_rect.size) / cell_size).floor();
for (int i = from.x; i <= to.x; i++) {
-
for (int j = from.y; j <= to.y; j++) {
-
PosKey pk;
pk.x = i;
pk.y = j;
@@ -232,7 +217,6 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool
PosBin *pb = hash_table[idx];
while (pb) {
-
if (pb->key == pk) {
break;
}
@@ -246,48 +230,41 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool
if (p_static) {
if (pb->static_object_set[p_elem].dec() == 0) {
-
pb->static_object_set.erase(p_elem);
exited = true;
}
} else {
if (pb->object_set[p_elem].dec() == 0) {
-
pb->object_set.erase(p_elem);
exited = true;
}
}
if (exited) {
-
for (Map<Element *, RC>::Element *E = pb->object_set.front(); E; E = E->next()) {
-
- if (E->key()->owner == p_elem->owner)
+ if (E->key()->owner == p_elem->owner) {
continue;
+ }
_unpair_attempt(p_elem, E->key());
}
if (!p_static) {
-
for (Map<Element *, RC>::Element *E = pb->static_object_set.front(); E; E = E->next()) {
-
- if (E->key()->owner == p_elem->owner)
+ if (E->key()->owner == p_elem->owner) {
continue;
+ }
_unpair_attempt(p_elem, E->key());
}
}
}
if (pb->object_set.empty() && pb->static_object_set.empty()) {
-
if (hash_table[idx] == pb) {
hash_table[idx] = pb->next;
} else {
-
PosBin *px = hash_table[idx];
while (px) {
-
if (px->next == pb) {
px->next = pb->next;
break;
@@ -305,12 +282,15 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool
}
for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) {
- if (E->key() == p_elem)
+ if (E->key() == p_elem) {
continue; // do not pair against itself
- if (E->key()->owner == p_elem->owner)
+ }
+ if (E->key()->owner == p_elem->owner) {
continue;
- if (E->key()->_static && p_static)
+ }
+ if (E->key()->_static && p_static) {
continue;
+ }
//unpair from large elements
_unpair_attempt(p_elem, E->key());
@@ -318,7 +298,6 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool
}
BroadPhase2DHashGrid::ID BroadPhase2DHashGrid::create(CollisionObject2DSW *p_object, int p_subindex) {
-
current++;
Element e;
@@ -333,22 +312,20 @@ BroadPhase2DHashGrid::ID BroadPhase2DHashGrid::create(CollisionObject2DSW *p_obj
}
void BroadPhase2DHashGrid::move(ID p_id, const Rect2 &p_aabb) {
-
Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
Element &e = E->get();
- if (p_aabb == e.aabb)
+ if (p_aabb == e.aabb) {
return;
+ }
if (p_aabb != Rect2()) {
-
_enter_grid(&e, p_aabb, e._static);
}
if (e.aabb != Rect2()) {
-
_exit_grid(&e, e.aabb, e._static);
}
@@ -358,18 +335,20 @@ void BroadPhase2DHashGrid::move(ID p_id, const Rect2 &p_aabb) {
e.aabb = p_aabb;
}
-void BroadPhase2DHashGrid::set_static(ID p_id, bool p_static) {
+void BroadPhase2DHashGrid::set_static(ID p_id, bool p_static) {
Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
Element &e = E->get();
- if (e._static == p_static)
+ if (e._static == p_static) {
return;
+ }
- if (e.aabb != Rect2())
+ if (e.aabb != Rect2()) {
_exit_grid(&e, e.aabb, e._static);
+ }
e._static = p_static;
@@ -378,33 +357,33 @@ void BroadPhase2DHashGrid::set_static(ID p_id, bool p_static) {
_check_motion(&e);
}
}
-void BroadPhase2DHashGrid::remove(ID p_id) {
+void BroadPhase2DHashGrid::remove(ID p_id) {
Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
Element &e = E->get();
- if (e.aabb != Rect2())
+ if (e.aabb != Rect2()) {
_exit_grid(&e, e.aabb, e._static);
+ }
element_map.erase(p_id);
}
CollisionObject2DSW *BroadPhase2DHashGrid::get_object(ID p_id) const {
-
const Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND_V(!E, nullptr);
return E->get().owner;
}
-bool BroadPhase2DHashGrid::is_static(ID p_id) const {
+bool BroadPhase2DHashGrid::is_static(ID p_id) const {
const Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND_V(!E, false);
return E->get()._static;
}
-int BroadPhase2DHashGrid::get_subindex(ID p_id) const {
+int BroadPhase2DHashGrid::get_subindex(ID p_id) const {
const Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND_V(!E, -1);
return E->get().subindex;
@@ -412,7 +391,6 @@ int BroadPhase2DHashGrid::get_subindex(ID p_id) const {
template <bool use_aabb, bool use_segment>
void BroadPhase2DHashGrid::_cull(const Point2i p_cell, const Rect2 &p_aabb, const Point2 &p_from, const Point2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices, int &index) {
-
PosKey pk;
pk.x = p_cell.x;
pk.y = p_cell.y;
@@ -421,7 +399,6 @@ void BroadPhase2DHashGrid::_cull(const Point2i p_cell, const Rect2 &p_aabb, cons
PosBin *pb = hash_table[idx];
while (pb) {
-
if (pb->key == pk) {
break;
}
@@ -429,23 +406,27 @@ void BroadPhase2DHashGrid::_cull(const Point2i p_cell, const Rect2 &p_aabb, cons
pb = pb->next;
}
- if (!pb)
+ if (!pb) {
return;
+ }
for (Map<Element *, RC>::Element *E = pb->object_set.front(); E; E = E->next()) {
-
- if (index >= p_max_results)
+ if (index >= p_max_results) {
break;
- if (E->key()->pass == pass)
+ }
+ if (E->key()->pass == pass) {
continue;
+ }
E->key()->pass = pass;
- if (use_aabb && !p_aabb.intersects(E->key()->aabb))
+ if (use_aabb && !p_aabb.intersects(E->key()->aabb)) {
continue;
+ }
- if (use_segment && !E->key()->aabb.intersects_segment(p_from, p_to))
+ if (use_segment && !E->key()->aabb.intersects_segment(p_from, p_to)) {
continue;
+ }
p_results[index] = E->key()->owner;
p_result_indices[index] = E->key()->subindex;
@@ -453,18 +434,20 @@ void BroadPhase2DHashGrid::_cull(const Point2i p_cell, const Rect2 &p_aabb, cons
}
for (Map<Element *, RC>::Element *E = pb->static_object_set.front(); E; E = E->next()) {
-
- if (index >= p_max_results)
+ if (index >= p_max_results) {
break;
- if (E->key()->pass == pass)
+ }
+ if (E->key()->pass == pass) {
continue;
+ }
if (use_aabb && !p_aabb.intersects(E->key()->aabb)) {
continue;
}
- if (use_segment && !E->key()->aabb.intersects_segment(p_from, p_to))
+ if (use_segment && !E->key()->aabb.intersects_segment(p_from, p_to)) {
continue;
+ }
E->key()->pass = pass;
p_results[index] = E->key()->owner;
@@ -474,18 +457,20 @@ void BroadPhase2DHashGrid::_cull(const Point2i p_cell, const Rect2 &p_aabb, cons
}
int BroadPhase2DHashGrid::cull_segment(const Vector2 &p_from, const Vector2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) {
-
pass++;
Vector2 dir = (p_to - p_from);
- if (dir == Vector2())
+ if (dir == Vector2()) {
return 0;
+ }
//avoid divisions by zero
dir.normalize();
- if (dir.x == 0.0)
+ if (dir.x == 0.0) {
dir.x = 0.000001;
- if (dir.y == 0.0)
+ }
+ if (dir.y == 0.0) {
dir.y = 0.000001;
+ }
Vector2 delta = dir.abs();
delta.x = cell_size / delta.x;
@@ -498,15 +483,17 @@ int BroadPhase2DHashGrid::cull_segment(const Vector2 &p_from, const Vector2 &p_t
Vector2 max;
- if (dir.x < 0)
+ if (dir.x < 0) {
max.x = (Math::floor((double)pos.x) * cell_size - p_from.x) / dir.x;
- else
+ } else {
max.x = (Math::floor((double)pos.x + 1) * cell_size - p_from.x) / dir.x;
+ }
- if (dir.y < 0)
+ if (dir.y < 0) {
max.y = (Math::floor((double)pos.y) * cell_size - p_from.y) / dir.y;
- else
+ } else {
max.y = (Math::floor((double)pos.y + 1) * cell_size - p_from.y) / dir.y;
+ }
int cullcount = 0;
_cull<false, true>(pos, Rect2(), p_from, p_to, p_results, p_max_results, p_result_indices, cullcount);
@@ -515,45 +502,44 @@ int BroadPhase2DHashGrid::cull_segment(const Vector2 &p_from, const Vector2 &p_t
bool reached_y = false;
while (true) {
-
if (max.x < max.y) {
-
max.x += delta.x;
pos.x += step.x;
} else {
-
max.y += delta.y;
pos.y += step.y;
}
if (step.x > 0) {
- if (pos.x >= end.x)
+ if (pos.x >= end.x) {
reached_x = true;
+ }
} else if (pos.x <= end.x) {
-
reached_x = true;
}
if (step.y > 0) {
- if (pos.y >= end.y)
+ if (pos.y >= end.y) {
reached_y = true;
+ }
} else if (pos.y <= end.y) {
-
reached_y = true;
}
_cull<false, true>(pos, Rect2(), p_from, p_to, p_results, p_max_results, p_result_indices, cullcount);
- if (reached_x && reached_y)
+ if (reached_x && reached_y) {
break;
+ }
}
for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) {
-
- if (cullcount >= p_max_results)
+ if (cullcount >= p_max_results) {
break;
- if (E->key()->pass == pass)
+ }
+ if (E->key()->pass == pass) {
continue;
+ }
E->key()->pass = pass;
@@ -562,8 +548,9 @@ int BroadPhase2DHashGrid::cull_segment(const Vector2 &p_from, const Vector2 &p_t
continue;
*/
- if (!E->key()->aabb.intersects_segment(p_from, p_to))
+ if (!E->key()->aabb.intersects_segment(p_from, p_to)) {
continue;
+ }
p_results[cullcount] = E->key()->owner;
p_result_indices[cullcount] = E->key()->subindex;
@@ -574,7 +561,6 @@ int BroadPhase2DHashGrid::cull_segment(const Vector2 &p_from, const Vector2 &p_t
}
int BroadPhase2DHashGrid::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices) {
-
pass++;
Point2i from = (p_aabb.position / cell_size).floor();
@@ -582,24 +568,24 @@ int BroadPhase2DHashGrid::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p
int cullcount = 0;
for (int i = from.x; i <= to.x; i++) {
-
for (int j = from.y; j <= to.y; j++) {
-
_cull<true, false>(Point2i(i, j), p_aabb, Point2(), Point2(), p_results, p_max_results, p_result_indices, cullcount);
}
}
for (Map<Element *, RC>::Element *E = large_elements.front(); E; E = E->next()) {
-
- if (cullcount >= p_max_results)
+ if (cullcount >= p_max_results) {
break;
- if (E->key()->pass == pass)
+ }
+ if (E->key()->pass == pass) {
continue;
+ }
E->key()->pass = pass;
- if (!p_aabb.intersects(E->key()->aabb))
+ if (!p_aabb.intersects(E->key()->aabb)) {
continue;
+ }
/*
if (!E->key()->aabb.intersects_segment(p_from,p_to))
@@ -614,12 +600,11 @@ int BroadPhase2DHashGrid::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p
}
void BroadPhase2DHashGrid::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) {
-
pair_callback = p_pair_callback;
pair_userdata = p_userdata;
}
-void BroadPhase2DHashGrid::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) {
+void BroadPhase2DHashGrid::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) {
unpair_callback = p_unpair_callback;
unpair_userdata = p_userdata;
}
@@ -628,12 +613,10 @@ void BroadPhase2DHashGrid::update() {
}
BroadPhase2DSW *BroadPhase2DHashGrid::_create() {
-
return memnew(BroadPhase2DHashGrid);
}
BroadPhase2DHashGrid::BroadPhase2DHashGrid() {
-
hash_table_size = GLOBAL_DEF("physics/2d/bp_hash_table_size", 4096);
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/bp_hash_table_size", PropertyInfo(Variant::INT, "physics/2d/bp_hash_table_size", PROPERTY_HINT_RANGE, "0,8192,1,or_greater"));
hash_table_size = Math::larger_prime(hash_table_size);
@@ -645,15 +628,15 @@ BroadPhase2DHashGrid::BroadPhase2DHashGrid() {
large_object_min_surface = GLOBAL_DEF("physics/2d/large_object_surface_threshold_in_cells", 512);
ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/large_object_surface_threshold_in_cells", PropertyInfo(Variant::INT, "physics/2d/large_object_surface_threshold_in_cells", PROPERTY_HINT_RANGE, "0,1024,1,or_greater"));
- for (uint32_t i = 0; i < hash_table_size; i++)
+ for (uint32_t i = 0; i < hash_table_size; i++) {
hash_table[i] = nullptr;
+ }
pass = 1;
current = 0;
}
BroadPhase2DHashGrid::~BroadPhase2DHashGrid() {
-
for (uint32_t i = 0; i < hash_table_size; i++) {
while (hash_table[i]) {
PosBin *pb = hash_table[i];
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.h b/servers/physics_2d/broad_phase_2d_hash_grid.h
index dc29d0c619..de1ada0932 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.h
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.h
@@ -35,9 +35,7 @@
#include "core/map.h"
class BroadPhase2DHashGrid : public BroadPhase2DSW {
-
struct PairData {
-
bool colliding;
int rc;
void *ud;
@@ -49,7 +47,6 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW {
};
struct Element {
-
ID self;
CollisionObject2DSW *owner;
bool _static;
@@ -60,7 +57,6 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW {
};
struct RC {
-
int ref;
_FORCE_INLINE_ int inc() {
@@ -85,7 +81,6 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW {
uint64_t pass;
struct PairKey {
-
union {
struct {
ID a;
@@ -126,7 +121,6 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW {
_FORCE_INLINE_ void _cull(const Point2i p_cell, const Rect2 &p_aabb, const Point2 &p_from, const Point2 &p_to, CollisionObject2DSW **p_results, int p_max_results, int *p_result_indices, int &index);
struct PosKey {
-
union {
struct {
int32_t x;
@@ -153,7 +147,6 @@ class BroadPhase2DHashGrid : public BroadPhase2DSW {
};
struct PosBin {
-
PosKey key;
Map<Element *, RC> object_set;
Map<Element *, RC> static_object_set;
diff --git a/servers/physics_2d/broad_phase_2d_sw.h b/servers/physics_2d/broad_phase_2d_sw.h
index 5e42c72d83..e4444cd180 100644
--- a/servers/physics_2d/broad_phase_2d_sw.h
+++ b/servers/physics_2d/broad_phase_2d_sw.h
@@ -37,7 +37,6 @@
class CollisionObject2DSW;
class BroadPhase2DSW {
-
public:
typedef BroadPhase2DSW *(*CreateFunction)();
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index 0ec293c042..6931d96fe4 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -33,7 +33,6 @@
#include "space_2d_sw.h"
void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_transform, bool p_disabled) {
-
Shape s;
s.shape = p_shape;
s.xform = p_transform;
@@ -53,7 +52,6 @@ void CollisionObject2DSW::add_shape(Shape2DSW *p_shape, const Transform2D &p_tra
}
void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) {
-
ERR_FAIL_INDEX(p_index, shapes.size());
shapes[p_index].shape->remove_owner(this);
shapes.write[p_index].shape = p_shape;
@@ -68,13 +66,11 @@ void CollisionObject2DSW::set_shape(int p_index, Shape2DSW *p_shape) {
}
void CollisionObject2DSW::set_shape_metadata(int p_index, const Variant &p_metadata) {
-
ERR_FAIL_INDEX(p_index, shapes.size());
shapes.write[p_index].metadata = p_metadata;
}
void CollisionObject2DSW::set_shape_transform(int p_index, const Transform2D &p_transform) {
-
ERR_FAIL_INDEX(p_index, shapes.size());
shapes.write[p_index].xform = p_transform;
@@ -91,13 +87,15 @@ void CollisionObject2DSW::set_shape_as_disabled(int p_idx, bool p_disabled) {
ERR_FAIL_INDEX(p_idx, shapes.size());
CollisionObject2DSW::Shape &shape = shapes.write[p_idx];
- if (shape.disabled == p_disabled)
+ if (shape.disabled == p_disabled) {
return;
+ }
shape.disabled = p_disabled;
- if (!space)
+ if (!space) {
return;
+ }
if (p_disabled && shape.bpid != 0) {
space->get_broadphase()->remove(shape.bpid);
@@ -115,10 +113,8 @@ void CollisionObject2DSW::set_shape_as_disabled(int p_idx, bool p_disabled) {
}
void CollisionObject2DSW::remove_shape(Shape2DSW *p_shape) {
-
//remove a shape, all the times it appears
for (int i = 0; i < shapes.size(); i++) {
-
if (shapes[i].shape == p_shape) {
remove_shape(i);
i--;
@@ -127,13 +123,12 @@ void CollisionObject2DSW::remove_shape(Shape2DSW *p_shape) {
}
void CollisionObject2DSW::remove_shape(int p_index) {
-
//remove anything from shape to be erased to end, so subindices don't change
ERR_FAIL_INDEX(p_index, shapes.size());
for (int i = p_index; i < shapes.size(); i++) {
-
- if (shapes[i].bpid == 0)
+ if (shapes[i].bpid == 0) {
continue;
+ }
//should never get here with a null owner
space->get_broadphase()->remove(shapes[i].bpid);
shapes.write[i].bpid = 0;
@@ -149,12 +144,14 @@ void CollisionObject2DSW::remove_shape(int p_index) {
}
void CollisionObject2DSW::_set_static(bool p_static) {
- if (_static == p_static)
+ if (_static == p_static) {
return;
+ }
_static = p_static;
- if (!space)
+ if (!space) {
return;
+ }
for (int i = 0; i < get_shape_count(); i++) {
const Shape &s = shapes[i];
if (s.bpid > 0) {
@@ -164,9 +161,7 @@ void CollisionObject2DSW::_set_static(bool p_static) {
}
void CollisionObject2DSW::_unregister_shapes() {
-
for (int i = 0; i < shapes.size(); i++) {
-
Shape &s = shapes.write[i];
if (s.bpid > 0) {
space->get_broadphase()->remove(s.bpid);
@@ -176,16 +171,16 @@ void CollisionObject2DSW::_unregister_shapes() {
}
void CollisionObject2DSW::_update_shapes() {
-
- if (!space)
+ if (!space) {
return;
+ }
for (int i = 0; i < shapes.size(); i++) {
-
Shape &s = shapes.write[i];
- if (s.disabled)
+ if (s.disabled) {
continue;
+ }
if (s.bpid == 0) {
s.bpid = space->get_broadphase()->create(this, i);
@@ -204,15 +199,15 @@ void CollisionObject2DSW::_update_shapes() {
}
void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) {
-
- if (!space)
+ if (!space) {
return;
+ }
for (int i = 0; i < shapes.size(); i++) {
-
Shape &s = shapes.write[i];
- if (s.disabled)
+ if (s.disabled) {
continue;
+ }
if (s.bpid == 0) {
s.bpid = space->get_broadphase()->create(this, i);
@@ -231,13 +226,10 @@ void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) {
}
void CollisionObject2DSW::_set_space(Space2DSW *p_space) {
-
if (space) {
-
space->remove_object(this);
for (int i = 0; i < shapes.size(); i++) {
-
Shape &s = shapes.write[i];
if (s.bpid) {
space->get_broadphase()->remove(s.bpid);
@@ -249,21 +241,18 @@ void CollisionObject2DSW::_set_space(Space2DSW *p_space) {
space = p_space;
if (space) {
-
space->add_object(this);
_update_shapes();
}
}
void CollisionObject2DSW::_shape_changed() {
-
_update_shapes();
_shapes_changed();
}
CollisionObject2DSW::CollisionObject2DSW(Type p_type) :
pending_shape_update_list(this) {
-
_static = true;
type = p_type;
space = nullptr;
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index 98105a7c0e..84a2baaa74 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -53,7 +53,6 @@ private:
bool pickable;
struct Shape {
-
Transform2D xform;
Transform2D xform_inv;
BroadPhase2DSW::ID bpid;
@@ -186,7 +185,6 @@ public:
_FORCE_INLINE_ bool is_pickable() const { return pickable; }
_FORCE_INLINE_ bool test_collision_mask(CollisionObject2DSW *p_other) const {
-
return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask;
}
diff --git a/servers/physics_2d/collision_solver_2d_sat.cpp b/servers/physics_2d/collision_solver_2d_sat.cpp
index a954cb3de3..2cada2bf50 100644
--- a/servers/physics_2d/collision_solver_2d_sat.cpp
+++ b/servers/physics_2d/collision_solver_2d_sat.cpp
@@ -33,7 +33,6 @@
#include "core/math/geometry.h"
struct _CollectorCallback2D {
-
CollisionSolver2DSW::CallbackResult callback;
void *userdata;
bool swap;
@@ -42,22 +41,21 @@ struct _CollectorCallback2D {
Vector2 *sep_axis;
_FORCE_INLINE_ void call(const Vector2 &p_point_A, const Vector2 &p_point_B) {
-
/*
if (normal.dot(p_point_A) >= normal.dot(p_point_B))
return;
*/
- if (swap)
+ if (swap) {
callback(p_point_B, p_point_A, userdata);
- else
+ } else {
callback(p_point_A, p_point_B, userdata);
+ }
}
};
typedef void (*GenerateContactsFunc)(const Vector2 *, int, const Vector2 *, int, _CollectorCallback2D *);
_FORCE_INLINE_ static void _generate_contacts_point_point(const Vector2 *p_points_A, int p_point_count_A, const Vector2 *p_points_B, int p_point_count_B, _CollectorCallback2D *p_collector) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A != 1);
ERR_FAIL_COND(p_point_count_B != 1);
@@ -67,7 +65,6 @@ _FORCE_INLINE_ static void _generate_contacts_point_point(const Vector2 *p_point
}
_FORCE_INLINE_ static void _generate_contacts_point_edge(const Vector2 *p_points_A, int p_point_count_A, const Vector2 *p_points_B, int p_point_count_B, _CollectorCallback2D *p_collector) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A != 1);
ERR_FAIL_COND(p_point_count_B != 2);
@@ -85,7 +82,6 @@ struct _generate_contacts_Pair {
};
_FORCE_INLINE_ static void _generate_contacts_edge_edge(const Vector2 *p_points_A, int p_point_count_A, const Vector2 *p_points_B, int p_point_count_B, _CollectorCallback2D *p_collector) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A != 2);
ERR_FAIL_COND(p_point_count_B != 2); // circle is actually a 4x3 matrix
@@ -115,25 +111,25 @@ _FORCE_INLINE_ static void _generate_contacts_edge_edge(const Vector2 *p_points_
sa.sort(dvec, 4);
for (int i = 1; i <= 2; i++) {
-
if (dvec[i].a) {
Vector2 a = p_points_A[dvec[i].idx];
Vector2 b = n.plane_project(dB, a);
- if (n.dot(a) > n.dot(b) - CMP_EPSILON)
+ if (n.dot(a) > n.dot(b) - CMP_EPSILON) {
continue;
+ }
p_collector->call(a, b);
} else {
Vector2 b = p_points_B[dvec[i].idx];
Vector2 a = n.plane_project(dA, b);
- if (n.dot(a) > n.dot(b) - CMP_EPSILON)
+ if (n.dot(a) > n.dot(b) - CMP_EPSILON) {
continue;
+ }
p_collector->call(a, b);
}
}
}
static void _generate_contacts_from_supports(const Vector2 *p_points_A, int p_point_count_A, const Vector2 *p_points_B, int p_point_count_B, _CollectorCallback2D *p_collector) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A < 1);
ERR_FAIL_COND(p_point_count_B < 1);
@@ -165,7 +161,6 @@ static void _generate_contacts_from_supports(const Vector2 *p_points_A, int p_po
points_A = p_points_B;
points_B = p_points_A;
} else {
-
pointcount_B = p_point_count_B;
pointcount_A = p_point_count_A;
points_A = p_points_A;
@@ -182,7 +177,6 @@ static void _generate_contacts_from_supports(const Vector2 *p_points_A, int p_po
template <class ShapeA, class ShapeB, bool castA = false, bool castB = false, bool withMargin = false>
class SeparatorAxisTest2D {
-
const ShapeA *shape_A;
const ShapeB *shape_B;
const Transform2D *transform_A;
@@ -199,7 +193,6 @@ class SeparatorAxisTest2D {
public:
_FORCE_INLINE_ bool test_previous_axis() {
-
if (callback && callback->sep_axis && *callback->sep_axis != Vector2()) {
return test_axis(*callback->sep_axis);
} else {
@@ -211,30 +204,30 @@ public:
}
_FORCE_INLINE_ bool test_cast() {
-
if (castA) {
-
Vector2 na = motion_A.normalized();
- if (!test_axis(na))
+ if (!test_axis(na)) {
return false;
- if (!test_axis(na.tangent()))
+ }
+ if (!test_axis(na.tangent())) {
return false;
+ }
}
if (castB) {
-
Vector2 nb = motion_B.normalized();
- if (!test_axis(nb))
+ if (!test_axis(nb)) {
return false;
- if (!test_axis(nb.tangent()))
+ }
+ if (!test_axis(nb.tangent())) {
return false;
+ }
}
return true;
}
_FORCE_INLINE_ bool test_axis(const Vector2 &p_axis) {
-
Vector2 axis = p_axis;
if (Math::is_zero_approx(axis.x) &&
@@ -245,15 +238,17 @@ public:
real_t min_A, max_A, min_B, max_B;
- if (castA)
+ if (castA) {
shape_A->project_range_cast(motion_A, axis, *transform_A, min_A, max_A);
- else
+ } else {
shape_A->project_range(axis, *transform_A, min_A, max_A);
+ }
- if (castB)
+ if (castB) {
shape_B->project_range_cast(motion_B, axis, *transform_B, min_B, max_B);
- else
+ } else {
shape_B->project_range(axis, *transform_B, min_B, max_B);
+ }
if (withMargin) {
min_A -= margin_A;
@@ -269,8 +264,9 @@ public:
real_t dmax = max_B - (min_A + max_A) * 0.5;
if (dmin > 0.0 || dmax < 0.0) {
- if (callback && callback->sep_axis)
+ if (callback && callback->sep_axis) {
*callback->sep_axis = axis;
+ }
#ifdef DEBUG_ENABLED
best_axis_count++;
#endif
@@ -308,16 +304,17 @@ public:
}
_FORCE_INLINE_ void generate_contacts() {
-
// nothing to do, don't generate
- if (best_axis == Vector2(0.0, 0.0))
+ if (best_axis == Vector2(0.0, 0.0)) {
return;
+ }
if (callback) {
callback->collided = true;
- if (!callback->callback)
+ if (!callback->callback) {
return; //only collide, no callback
+ }
}
static const int max_supports = 2;
@@ -333,7 +330,6 @@ public:
}
if (withMargin) {
-
for (int i = 0; i < support_count_A; i++) {
supports_A[i] += -best_axis * margin_A;
}
@@ -351,7 +347,6 @@ public:
}
if (withMargin) {
-
for (int i = 0; i < support_count_B; i++) {
supports_B[i] += best_axis * margin_B;
}
@@ -360,13 +355,13 @@ public:
callback->normal = best_axis;
_generate_contacts_from_supports(supports_A, support_count_A, supports_B, support_count_B, callback);
- if (callback->sep_axis && *callback->sep_axis != Vector2())
+ if (callback->sep_axis && *callback->sep_axis != Vector2()) {
*callback->sep_axis = Vector2(); //invalidate previous axis (no test)
+ }
}
}
_FORCE_INLINE_ SeparatorAxisTest2D(const ShapeA *p_shape_A, const Transform2D &p_transform_a, const ShapeB *p_shape_B, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_A = Vector2(), const Vector2 &p_motion_B = Vector2(), real_t p_margin_A = 0, real_t p_margin_B = 0) {
-
margin_A = p_margin_A;
margin_B = p_margin_B;
best_depth = 1e15;
@@ -397,35 +392,42 @@ typedef void (*CollisionFunc)(const Shape2DSW *, const Transform2D &, const Shap
template <bool castA, bool castB, bool withMargin>
static void _collision_segment_segment(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a);
const SegmentShape2DSW *segment_B = static_cast<const SegmentShape2DSW *>(p_b);
SeparatorAxisTest2D<SegmentShape2DSW, SegmentShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, segment_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
//this collision is kind of pointless
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
- if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a)))
+ if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) {
return;
- if (!separator.test_axis(segment_B->get_xformed_normal(p_transform_b)))
+ }
+ if (!separator.test_axis(segment_B->get_xformed_normal(p_transform_b))) {
return;
+ }
if (withMargin) {
//points grow to circles
- if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(segment_B->get_a())))
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(segment_B->get_a()))) {
return;
- if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(segment_B->get_b())))
+ }
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(segment_B->get_b()))) {
return;
- if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(segment_B->get_a())))
+ }
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(segment_B->get_a()))) {
return;
- if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(segment_B->get_b())))
+ }
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(segment_B->get_b()))) {
return;
+ }
}
separator.generate_contacts();
@@ -433,90 +435,102 @@ static void _collision_segment_segment(const Shape2DSW *p_a, const Transform2D &
template <bool castA, bool castB, bool withMargin>
static void _collision_segment_circle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a);
const CircleShape2DSW *circle_B = static_cast<const CircleShape2DSW *>(p_b);
SeparatorAxisTest2D<SegmentShape2DSW, CircleShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, circle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
//segment normal
if (!separator.test_axis(
- (p_transform_a.xform(segment_A->get_b()) - p_transform_a.xform(segment_A->get_a())).normalized().tangent()))
+ (p_transform_a.xform(segment_A->get_b()) - p_transform_a.xform(segment_A->get_a())).normalized().tangent())) {
return;
+ }
//endpoint a vs circle
- if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.get_origin()))
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.get_origin())) {
return;
+ }
//endpoint b vs circle
- if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.get_origin()))
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.get_origin())) {
return;
+ }
separator.generate_contacts();
}
template <bool castA, bool castB, bool withMargin>
static void _collision_segment_rectangle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a);
const RectangleShape2DSW *rectangle_B = static_cast<const RectangleShape2DSW *>(p_b);
SeparatorAxisTest2D<SegmentShape2DSW, RectangleShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
- if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a)))
+ if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) {
return;
+ }
- if (!separator.test_axis(p_transform_b.elements[0].normalized()))
+ if (!separator.test_axis(p_transform_b.elements[0].normalized())) {
return;
+ }
- if (!separator.test_axis(p_transform_b.elements[1].normalized()))
+ if (!separator.test_axis(p_transform_b.elements[1].normalized())) {
return;
+ }
if (withMargin) {
-
Transform2D inv = p_transform_b.affine_inverse();
Vector2 a = p_transform_a.xform(segment_A->get_a());
Vector2 b = p_transform_a.xform(segment_A->get_b());
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a)))
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a))) {
return;
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b)))
+ }
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b))) {
return;
+ }
if (castA) {
-
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a + p_motion_a)))
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a + p_motion_a))) {
return;
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b + p_motion_a)))
+ }
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b + p_motion_a))) {
return;
+ }
}
if (castB) {
-
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a - p_motion_b)))
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a - p_motion_b))) {
return;
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b - p_motion_b)))
+ }
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b - p_motion_b))) {
return;
+ }
}
if (castA && castB) {
-
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a - p_motion_b + p_motion_a)))
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, a - p_motion_b + p_motion_a))) {
return;
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b - p_motion_b + p_motion_a)))
+ }
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, inv, b - p_motion_b + p_motion_a))) {
return;
+ }
}
}
@@ -525,64 +539,74 @@ static void _collision_segment_rectangle(const Shape2DSW *p_a, const Transform2D
template <bool castA, bool castB, bool withMargin>
static void _collision_segment_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a);
const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b);
SeparatorAxisTest2D<SegmentShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
- if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a)))
+ if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) {
return;
+ }
- if (!separator.test_axis(p_transform_b.elements[0].normalized()))
+ if (!separator.test_axis(p_transform_b.elements[0].normalized())) {
return;
+ }
- if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5)))
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5))) {
return;
- if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5)))
+ }
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5))) {
return;
- if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5)))
+ }
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5))) {
return;
- if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5)))
+ }
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5))) {
return;
+ }
separator.generate_contacts();
}
template <bool castA, bool castB, bool withMargin>
static void _collision_segment_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const SegmentShape2DSW *segment_A = static_cast<const SegmentShape2DSW *>(p_a);
const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b);
SeparatorAxisTest2D<SegmentShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(segment_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
- if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a)))
+ if (!separator.test_axis(segment_A->get_xformed_normal(p_transform_a))) {
return;
+ }
for (int i = 0; i < convex_B->get_point_count(); i++) {
-
- if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i)))
+ if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) {
return;
+ }
if (withMargin) {
-
- if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(convex_B->get_point(i))))
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_a()), p_transform_b.xform(convex_B->get_point(i)))) {
return;
- if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(convex_B->get_point(i))))
+ }
+ if (TEST_POINT(p_transform_a.xform(segment_A->get_b()), p_transform_b.xform(convex_B->get_point(i)))) {
return;
+ }
}
}
@@ -593,74 +617,79 @@ static void _collision_segment_convex_polygon(const Shape2DSW *p_a, const Transf
template <bool castA, bool castB, bool withMargin>
static void _collision_circle_circle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a);
const CircleShape2DSW *circle_B = static_cast<const CircleShape2DSW *>(p_b);
SeparatorAxisTest2D<CircleShape2DSW, CircleShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, circle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
- if (TEST_POINT(p_transform_a.get_origin(), p_transform_b.get_origin()))
+ if (TEST_POINT(p_transform_a.get_origin(), p_transform_b.get_origin())) {
return;
+ }
separator.generate_contacts();
}
template <bool castA, bool castB, bool withMargin>
static void _collision_circle_rectangle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a);
const RectangleShape2DSW *rectangle_B = static_cast<const RectangleShape2DSW *>(p_b);
SeparatorAxisTest2D<CircleShape2DSW, RectangleShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
const Vector2 &sphere = p_transform_a.elements[2];
const Vector2 *axis = &p_transform_b.elements[0];
//const Vector2& half_extents = rectangle_B->get_half_extents();
- if (!separator.test_axis(axis[0].normalized()))
+ if (!separator.test_axis(axis[0].normalized())) {
return;
+ }
- if (!separator.test_axis(axis[1].normalized()))
+ if (!separator.test_axis(axis[1].normalized())) {
return;
+ }
Transform2D binv = p_transform_b.affine_inverse();
{
-
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphere)))
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphere))) {
return;
+ }
}
if (castA) {
-
Vector2 sphereofs = sphere + p_motion_a;
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs)))
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs))) {
return;
+ }
}
if (castB) {
-
Vector2 sphereofs = sphere - p_motion_b;
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs)))
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs))) {
return;
+ }
}
if (castA && castB) {
-
Vector2 sphereofs = sphere - p_motion_b + p_motion_a;
- if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs)))
+ if (!separator.test_axis(rectangle_B->get_circle_axis(p_transform_b, binv, sphereofs))) {
return;
+ }
}
separator.generate_contacts();
@@ -668,53 +697,59 @@ static void _collision_circle_rectangle(const Shape2DSW *p_a, const Transform2D
template <bool castA, bool castB, bool withMargin>
static void _collision_circle_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a);
const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b);
SeparatorAxisTest2D<CircleShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
//capsule axis
- if (!separator.test_axis(p_transform_b.elements[0].normalized()))
+ if (!separator.test_axis(p_transform_b.elements[0].normalized())) {
return;
+ }
//capsule endpoints
- if (TEST_POINT(p_transform_a.get_origin(), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5)))
+ if (TEST_POINT(p_transform_a.get_origin(), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * 0.5))) {
return;
- if (TEST_POINT(p_transform_a.get_origin(), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5)))
+ }
+ if (TEST_POINT(p_transform_a.get_origin(), (p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * -0.5))) {
return;
+ }
separator.generate_contacts();
}
template <bool castA, bool castB, bool withMargin>
static void _collision_circle_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const CircleShape2DSW *circle_A = static_cast<const CircleShape2DSW *>(p_a);
const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b);
SeparatorAxisTest2D<CircleShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(circle_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
//poly faces and poly points vs circle
for (int i = 0; i < convex_B->get_point_count(); i++) {
-
- if (TEST_POINT(p_transform_a.get_origin(), p_transform_b.xform(convex_B->get_point(i))))
+ if (TEST_POINT(p_transform_a.get_origin(), p_transform_b.xform(convex_B->get_point(i)))) {
return;
+ }
- if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i)))
+ if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) {
return;
+ }
}
separator.generate_contacts();
@@ -724,42 +759,46 @@ static void _collision_circle_convex_polygon(const Shape2DSW *p_a, const Transfo
template <bool castA, bool castB, bool withMargin>
static void _collision_rectangle_rectangle(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const RectangleShape2DSW *rectangle_A = static_cast<const RectangleShape2DSW *>(p_a);
const RectangleShape2DSW *rectangle_B = static_cast<const RectangleShape2DSW *>(p_b);
SeparatorAxisTest2D<RectangleShape2DSW, RectangleShape2DSW, castA, castB, withMargin> separator(rectangle_A, p_transform_a, rectangle_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
//box faces A
- if (!separator.test_axis(p_transform_a.elements[0].normalized()))
+ if (!separator.test_axis(p_transform_a.elements[0].normalized())) {
return;
+ }
- if (!separator.test_axis(p_transform_a.elements[1].normalized()))
+ if (!separator.test_axis(p_transform_a.elements[1].normalized())) {
return;
+ }
//box faces B
- if (!separator.test_axis(p_transform_b.elements[0].normalized()))
+ if (!separator.test_axis(p_transform_b.elements[0].normalized())) {
return;
+ }
- if (!separator.test_axis(p_transform_b.elements[1].normalized()))
+ if (!separator.test_axis(p_transform_b.elements[1].normalized())) {
return;
+ }
if (withMargin) {
-
Transform2D invA = p_transform_a.affine_inverse();
Transform2D invB = p_transform_b.affine_inverse();
- if (!separator.test_axis(rectangle_A->get_box_axis(p_transform_a, invA, rectangle_B, p_transform_b, invB)))
+ if (!separator.test_axis(rectangle_A->get_box_axis(p_transform_a, invA, rectangle_B, p_transform_b, invB))) {
return;
+ }
if (castA || castB) {
-
Transform2D aofs = p_transform_a;
aofs.elements[2] += p_motion_a;
@@ -770,21 +809,21 @@ static void _collision_rectangle_rectangle(const Shape2DSW *p_a, const Transform
Transform2D bofsinv = bofs.affine_inverse();
if (castA) {
-
- if (!separator.test_axis(rectangle_A->get_box_axis(aofs, aofsinv, rectangle_B, p_transform_b, invB)))
+ if (!separator.test_axis(rectangle_A->get_box_axis(aofs, aofsinv, rectangle_B, p_transform_b, invB))) {
return;
+ }
}
if (castB) {
-
- if (!separator.test_axis(rectangle_A->get_box_axis(p_transform_a, invA, rectangle_B, bofs, bofsinv)))
+ if (!separator.test_axis(rectangle_A->get_box_axis(p_transform_a, invA, rectangle_B, bofs, bofsinv))) {
return;
+ }
}
if (castA && castB) {
-
- if (!separator.test_axis(rectangle_A->get_box_axis(aofs, aofsinv, rectangle_B, bofs, bofsinv)))
+ if (!separator.test_axis(rectangle_A->get_box_axis(aofs, aofsinv, rectangle_B, bofs, bofsinv))) {
return;
+ }
}
}
}
@@ -794,56 +833,62 @@ static void _collision_rectangle_rectangle(const Shape2DSW *p_a, const Transform
template <bool castA, bool castB, bool withMargin>
static void _collision_rectangle_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const RectangleShape2DSW *rectangle_A = static_cast<const RectangleShape2DSW *>(p_a);
const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b);
SeparatorAxisTest2D<RectangleShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(rectangle_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
//box faces
- if (!separator.test_axis(p_transform_a.elements[0].normalized()))
+ if (!separator.test_axis(p_transform_a.elements[0].normalized())) {
return;
+ }
- if (!separator.test_axis(p_transform_a.elements[1].normalized()))
+ if (!separator.test_axis(p_transform_a.elements[1].normalized())) {
return;
+ }
//capsule axis
- if (!separator.test_axis(p_transform_b.elements[0].normalized()))
+ if (!separator.test_axis(p_transform_b.elements[0].normalized())) {
return;
+ }
//box endpoints to capsule circles
Transform2D boxinv = p_transform_a.affine_inverse();
for (int i = 0; i < 2; i++) {
-
{
Vector2 capsule_endpoint = p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * (i == 0 ? 0.5 : -0.5);
- if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint)))
+ if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) {
return;
+ }
}
if (castA) {
Vector2 capsule_endpoint = p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * (i == 0 ? 0.5 : -0.5);
capsule_endpoint -= p_motion_a;
- if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint)))
+ if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) {
return;
+ }
}
if (castB) {
Vector2 capsule_endpoint = p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * (i == 0 ? 0.5 : -0.5);
capsule_endpoint += p_motion_b;
- if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint)))
+ if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) {
return;
+ }
}
if (castA && castB) {
@@ -851,8 +896,9 @@ static void _collision_rectangle_capsule(const Shape2DSW *p_a, const Transform2D
capsule_endpoint -= p_motion_a;
capsule_endpoint += p_motion_b;
- if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint)))
+ if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, capsule_endpoint))) {
return;
+ }
}
}
@@ -861,24 +907,27 @@ static void _collision_rectangle_capsule(const Shape2DSW *p_a, const Transform2D
template <bool castA, bool castB, bool withMargin>
static void _collision_rectangle_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const RectangleShape2DSW *rectangle_A = static_cast<const RectangleShape2DSW *>(p_a);
const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b);
SeparatorAxisTest2D<RectangleShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(rectangle_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
//box faces
- if (!separator.test_axis(p_transform_a.elements[0].normalized()))
+ if (!separator.test_axis(p_transform_a.elements[0].normalized())) {
return;
+ }
- if (!separator.test_axis(p_transform_a.elements[1].normalized()))
+ if (!separator.test_axis(p_transform_a.elements[1].normalized())) {
return;
+ }
//convex faces
Transform2D boxinv;
@@ -886,28 +935,29 @@ static void _collision_rectangle_convex_polygon(const Shape2DSW *p_a, const Tran
boxinv = p_transform_a.affine_inverse();
}
for (int i = 0; i < convex_B->get_point_count(); i++) {
-
- if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i)))
+ if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) {
return;
+ }
if (withMargin) {
//all points vs all points need to be tested if margin exist
- if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)))))
+ if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i))))) {
return;
+ }
if (castA) {
-
- if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) - p_motion_a)))
+ if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) - p_motion_a))) {
return;
+ }
}
if (castB) {
-
- if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) + p_motion_b)))
+ if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) + p_motion_b))) {
return;
+ }
}
if (castA && castB) {
-
- if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) + p_motion_b - p_motion_a)))
+ if (!separator.test_axis(rectangle_A->get_circle_axis(p_transform_a, boxinv, p_transform_b.xform(convex_B->get_point(i)) + p_motion_b - p_motion_a))) {
return;
+ }
}
}
}
@@ -919,38 +969,40 @@ static void _collision_rectangle_convex_polygon(const Shape2DSW *p_a, const Tran
template <bool castA, bool castB, bool withMargin>
static void _collision_capsule_capsule(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const CapsuleShape2DSW *capsule_A = static_cast<const CapsuleShape2DSW *>(p_a);
const CapsuleShape2DSW *capsule_B = static_cast<const CapsuleShape2DSW *>(p_b);
SeparatorAxisTest2D<CapsuleShape2DSW, CapsuleShape2DSW, castA, castB, withMargin> separator(capsule_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
//capsule axis
- if (!separator.test_axis(p_transform_b.elements[0].normalized()))
+ if (!separator.test_axis(p_transform_b.elements[0].normalized())) {
return;
+ }
- if (!separator.test_axis(p_transform_a.elements[0].normalized()))
+ if (!separator.test_axis(p_transform_a.elements[0].normalized())) {
return;
+ }
//capsule endpoints
for (int i = 0; i < 2; i++) {
-
Vector2 capsule_endpoint_A = p_transform_a.get_origin() + p_transform_a.elements[1] * capsule_A->get_height() * (i == 0 ? 0.5 : -0.5);
for (int j = 0; j < 2; j++) {
-
Vector2 capsule_endpoint_B = p_transform_b.get_origin() + p_transform_b.elements[1] * capsule_B->get_height() * (j == 0 ? 0.5 : -0.5);
- if (TEST_POINT(capsule_endpoint_A, capsule_endpoint_B))
+ if (TEST_POINT(capsule_endpoint_A, capsule_endpoint_B)) {
return;
+ }
}
}
@@ -959,38 +1011,40 @@ static void _collision_capsule_capsule(const Shape2DSW *p_a, const Transform2D &
template <bool castA, bool castB, bool withMargin>
static void _collision_capsule_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const CapsuleShape2DSW *capsule_A = static_cast<const CapsuleShape2DSW *>(p_a);
const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b);
SeparatorAxisTest2D<CapsuleShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(capsule_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
//capsule axis
- if (!separator.test_axis(p_transform_a.elements[0].normalized()))
+ if (!separator.test_axis(p_transform_a.elements[0].normalized())) {
return;
+ }
//poly vs capsule
for (int i = 0; i < convex_B->get_point_count(); i++) {
-
Vector2 cpoint = p_transform_b.xform(convex_B->get_point(i));
for (int j = 0; j < 2; j++) {
-
Vector2 capsule_endpoint_A = p_transform_a.get_origin() + p_transform_a.elements[1] * capsule_A->get_height() * (j == 0 ? 0.5 : -0.5);
- if (TEST_POINT(capsule_endpoint_A, cpoint))
+ if (TEST_POINT(capsule_endpoint_A, cpoint)) {
return;
+ }
}
- if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i)))
+ if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) {
return;
+ }
}
separator.generate_contacts();
@@ -1000,37 +1054,37 @@ static void _collision_capsule_convex_polygon(const Shape2DSW *p_a, const Transf
template <bool castA, bool castB, bool withMargin>
static void _collision_convex_polygon_convex_polygon(const Shape2DSW *p_a, const Transform2D &p_transform_a, const Shape2DSW *p_b, const Transform2D &p_transform_b, _CollectorCallback2D *p_collector, const Vector2 &p_motion_a, const Vector2 &p_motion_b, real_t p_margin_A, real_t p_margin_B) {
-
const ConvexPolygonShape2DSW *convex_A = static_cast<const ConvexPolygonShape2DSW *>(p_a);
const ConvexPolygonShape2DSW *convex_B = static_cast<const ConvexPolygonShape2DSW *>(p_b);
SeparatorAxisTest2D<ConvexPolygonShape2DSW, ConvexPolygonShape2DSW, castA, castB, withMargin> separator(convex_A, p_transform_a, convex_B, p_transform_b, p_collector, p_motion_a, p_motion_b, p_margin_A, p_margin_B);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_cast())
+ if (!separator.test_cast()) {
return;
+ }
for (int i = 0; i < convex_A->get_point_count(); i++) {
-
- if (!separator.test_axis(convex_A->get_xformed_segment_normal(p_transform_a, i)))
+ if (!separator.test_axis(convex_A->get_xformed_segment_normal(p_transform_a, i))) {
return;
+ }
}
for (int i = 0; i < convex_B->get_point_count(); i++) {
-
- if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i)))
+ if (!separator.test_axis(convex_B->get_xformed_segment_normal(p_transform_b, i))) {
return;
+ }
}
if (withMargin) {
-
for (int i = 0; i < convex_A->get_point_count(); i++) {
for (int j = 0; j < convex_B->get_point_count(); j++) {
-
- if (TEST_POINT(p_transform_a.xform(convex_A->get_point(i)), p_transform_b.xform(convex_B->get_point(j))))
+ if (TEST_POINT(p_transform_a.xform(convex_A->get_point(i)), p_transform_b.xform(convex_B->get_point(j)))) {
return;
+ }
}
}
}
@@ -1041,7 +1095,6 @@ static void _collision_convex_polygon_convex_polygon(const Shape2DSW *p_a, const
////////
bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CollisionSolver2DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap, Vector2 *sep_axis, real_t p_margin_A, real_t p_margin_B) {
-
PhysicsServer2D::ShapeType type_A = p_shape_A->get_type();
ERR_FAIL_COND_V(type_A == PhysicsServer2D::SHAPE_LINE, false);
@@ -1323,7 +1376,6 @@ bool sat_2d_calculate_penetration(const Shape2DSW *p_shape_A, const Transform2D
collision_func = collision_table_castA_castB_margin[type_A - 2][type_B - 2];
}
} else {
-
if (*motion_A == Vector2() && *motion_B == Vector2()) {
collision_func = collision_table[type_A - 2][type_B - 2];
} else if (*motion_A != Vector2() && *motion_B == Vector2()) {
diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp
index f117dcbfe5..beba709807 100644
--- a/servers/physics_2d/collision_solver_2d_sw.cpp
+++ b/servers/physics_2d/collision_solver_2d_sw.cpp
@@ -35,10 +35,10 @@
//#define collision_solver gjk_epa_calculate_penetration
bool CollisionSolver2DSW::solve_static_line(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) {
-
const LineShape2DSW *line = static_cast<const LineShape2DSW *>(p_shape_A);
- if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_LINE)
+ if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_LINE) {
return false;
+ }
Vector2 n = p_transform_A.basis_xform(line->get_normal()).normalized();
Vector2 p = p_transform_A.xform(line->get_normal() * line->get_d());
@@ -52,20 +52,21 @@ bool CollisionSolver2DSW::solve_static_line(const Shape2DSW *p_shape_A, const Tr
bool found = false;
for (int i = 0; i < support_count; i++) {
-
supports[i] = p_transform_B.xform(supports[i]);
real_t pd = n.dot(supports[i]);
- if (pd >= d)
+ if (pd >= d) {
continue;
+ }
found = true;
Vector2 support_A = supports[i] - n * (pd - d);
if (p_result_callback) {
- if (p_swap_result)
+ if (p_swap_result) {
p_result_callback(supports[i], support_A, p_userdata);
- else
+ } else {
p_result_callback(support_A, supports[i], p_userdata);
+ }
}
}
@@ -73,10 +74,10 @@ bool CollisionSolver2DSW::solve_static_line(const Shape2DSW *p_shape_A, const Tr
}
bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Vector2 &p_motion_A, const Transform2D &p_transform_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis) {
-
const RayShape2DSW *ray = static_cast<const RayShape2DSW *>(p_shape_A);
- if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_RAY)
+ if (p_shape_B->get_type() == PhysicsServer2D::SHAPE_RAY) {
return false;
+ }
Vector2 from = p_transform_A.get_origin();
Vector2 to = from + p_transform_A[1] * ray->get_length();
@@ -93,9 +94,9 @@ bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Vector
Vector2 p, n;
if (!p_shape_B->intersect_segment(from, to, p, n)) {
-
- if (sep_axis)
+ if (sep_axis) {
*sep_axis = p_transform_A[1].normalized();
+ }
return false;
}
@@ -106,16 +107,16 @@ bool CollisionSolver2DSW::solve_raycast(const Shape2DSW *p_shape_A, const Vector
}
if (p_result_callback) {
- if (p_swap_result)
+ if (p_swap_result) {
p_result_callback(support_B, support_A, p_userdata);
- else
+ } else {
p_result_callback(support_A, support_B, p_userdata);
+ }
}
return true;
}
struct _ConcaveCollisionInfo2D {
-
const Transform2D *transform_A;
const Shape2DSW *shape_A;
const Transform2D *transform_B;
@@ -133,22 +134,22 @@ struct _ConcaveCollisionInfo2D {
};
void CollisionSolver2DSW::concave_callback(void *p_userdata, Shape2DSW *p_convex) {
-
_ConcaveCollisionInfo2D &cinfo = *(_ConcaveCollisionInfo2D *)(p_userdata);
cinfo.aabb_tests++;
- if (!cinfo.result_callback && cinfo.collided)
+ if (!cinfo.result_callback && cinfo.collided) {
return; //already collided and no contacts requested, don't test anymore
+ }
bool collided = collision_solver(cinfo.shape_A, *cinfo.transform_A, cinfo.motion_A, p_convex, *cinfo.transform_B, cinfo.motion_B, cinfo.result_callback, cinfo.userdata, cinfo.swap_result, cinfo.sep_axis, cinfo.margin_A, cinfo.margin_B);
- if (!collided)
+ if (!collided) {
return;
+ }
cinfo.collided = true;
cinfo.collisions++;
}
bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, Vector2 *sep_axis, real_t p_margin_A, real_t p_margin_B) {
-
const ConcaveShape2DSW *concave_B = static_cast<const ConcaveShape2DSW *>(p_shape_B);
_ConcaveCollisionInfo2D cinfo;
@@ -174,7 +175,6 @@ bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A, const Transf
Rect2 local_aabb;
for (int i = 0; i < 2; i++) {
-
Vector2 axis(p_transform_B.elements[i]);
real_t axis_scale = 1.0 / axis.length();
axis *= axis_scale;
@@ -194,7 +194,6 @@ bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A, const Transf
}
bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, Vector2 *sep_axis, real_t p_margin_A, real_t p_margin_B) {
-
PhysicsServer2D::ShapeType type_A = p_shape_A->get_type();
PhysicsServer2D::ShapeType type_B = p_shape_B->get_type();
bool concave_A = p_shape_A->is_concave();
@@ -211,7 +210,6 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p
}
if (type_A == PhysicsServer2D::SHAPE_LINE) {
-
if (type_B == PhysicsServer2D::SHAPE_LINE || type_B == PhysicsServer2D::SHAPE_RAY) {
return false;
}
@@ -223,9 +221,7 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p
}
} else if (type_A == PhysicsServer2D::SHAPE_RAY) {
-
if (type_B == PhysicsServer2D::SHAPE_RAY) {
-
return false; //no ray-ray
}
@@ -236,17 +232,17 @@ bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p
}
} else if (concave_B) {
-
- if (concave_A)
+ if (concave_A) {
return false;
+ }
- if (!swap)
+ if (!swap) {
return solve_concave(p_shape_A, p_transform_A, p_motion_A, p_shape_B, p_transform_B, p_motion_B, p_result_callback, p_userdata, false, sep_axis, margin_A, margin_B);
- else
+ } else {
return solve_concave(p_shape_B, p_transform_B, p_motion_B, p_shape_A, p_transform_A, p_motion_A, p_result_callback, p_userdata, true, sep_axis, margin_A, margin_B);
+ }
} else {
-
return collision_solver(p_shape_A, p_transform_A, p_motion_A, p_shape_B, p_transform_B, p_motion_B, p_result_callback, p_userdata, false, sep_axis, margin_A, margin_B);
}
}
diff --git a/servers/physics_2d/constraint_2d_sw.h b/servers/physics_2d/constraint_2d_sw.h
index f8eb16214f..d8751f588e 100644
--- a/servers/physics_2d/constraint_2d_sw.h
+++ b/servers/physics_2d/constraint_2d_sw.h
@@ -34,7 +34,6 @@
#include "body_2d_sw.h"
class Constraint2DSW {
-
Body2DSW **_body_ptr;
int _body_count;
uint64_t island_step;
diff --git a/servers/physics_2d/joints_2d_sw.cpp b/servers/physics_2d/joints_2d_sw.cpp
index 4524629d50..eda0b923a2 100644
--- a/servers/physics_2d/joints_2d_sw.cpp
+++ b/servers/physics_2d/joints_2d_sw.cpp
@@ -56,7 +56,6 @@
*/
static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const Vector2 &rB, const Vector2 &n) {
-
real_t value = 0;
{
@@ -66,7 +65,6 @@ static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const
}
if (b) {
-
value += b->get_inv_mass();
real_t rcn = rB.cross(n);
value += b->get_inv_inertia() * rcn * rcn;
@@ -78,10 +76,11 @@ static inline real_t k_scalar(Body2DSW *a, Body2DSW *b, const Vector2 &rA, const
static inline Vector2
relative_velocity(Body2DSW *a, Body2DSW *b, Vector2 rA, Vector2 rB) {
Vector2 sum = a->get_linear_velocity() - rA.tangent() * a->get_angular_velocity();
- if (b)
+ if (b) {
return (b->get_linear_velocity() - rB.tangent() * b->get_angular_velocity()) - sum;
- else
+ } else {
return -sum;
+ }
}
static inline real_t
@@ -90,7 +89,6 @@ normal_relative_velocity(Body2DSW *a, Body2DSW *b, Vector2 rA, Vector2 rB, Vecto
}
bool PinJoint2DSW::setup(real_t p_step) {
-
Space2DSW *space = A->get_space();
ERR_FAIL_COND_V(!space, false);
rA = A->get_transform().basis_xform(anchor_A);
@@ -115,7 +113,6 @@ bool PinJoint2DSW::setup(real_t p_step) {
K[1] = K1[1] + K2[1];
if (B) {
-
Transform2D K3;
K3[0].x = B->get_inv_inertia() * rB.y * rB.y;
K3[1].x = -B->get_inv_inertia() * rB.x * rB.y;
@@ -140,53 +137,53 @@ bool PinJoint2DSW::setup(real_t p_step) {
// apply accumulated impulse
A->apply_impulse(rA, -P);
- if (B)
+ if (B) {
B->apply_impulse(rB, P);
+ }
return true;
}
inline Vector2 custom_cross(const Vector2 &p_vec, real_t p_other) {
-
return Vector2(p_other * p_vec.y, -p_other * p_vec.x);
}
void PinJoint2DSW::solve(real_t p_step) {
-
// compute relative velocity
Vector2 vA = A->get_linear_velocity() - custom_cross(rA, A->get_angular_velocity());
Vector2 rel_vel;
- if (B)
+ if (B) {
rel_vel = B->get_linear_velocity() - custom_cross(rB, B->get_angular_velocity()) - vA;
- else
+ } else {
rel_vel = -vA;
+ }
Vector2 impulse = M.basis_xform(bias - rel_vel - Vector2(softness, softness) * P);
A->apply_impulse(rA, -impulse);
- if (B)
+ if (B) {
B->apply_impulse(rB, impulse);
+ }
P += impulse;
}
void PinJoint2DSW::set_param(PhysicsServer2D::PinJointParam p_param, real_t p_value) {
-
- if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS)
+ if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS) {
softness = p_value;
+ }
}
real_t PinJoint2DSW::get_param(PhysicsServer2D::PinJointParam p_param) const {
-
- if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS)
+ if (p_param == PhysicsServer2D::PIN_JOINT_SOFTNESS) {
return softness;
+ }
ERR_FAIL_V(0);
}
PinJoint2DSW::PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p_body_b) :
Joint2DSW(_arr, p_body_b ? 2 : 1) {
-
A = p_body_a;
B = p_body_b;
anchor_A = p_body_a->get_inv_transform().xform(p_pos);
@@ -195,16 +192,18 @@ PinJoint2DSW::PinJoint2DSW(const Vector2 &p_pos, Body2DSW *p_body_a, Body2DSW *p
softness = 0;
p_body_a->add_constraint(this, 0);
- if (p_body_b)
+ if (p_body_b) {
p_body_b->add_constraint(this, 1);
+ }
}
PinJoint2DSW::~PinJoint2DSW() {
-
- if (A)
+ if (A) {
A->remove_constraint(this);
- if (B)
+ }
+ if (B) {
B->remove_constraint(this);
+ }
}
//////////////////////////////////////////////
@@ -259,7 +258,6 @@ mult_k(const Vector2 &vr, const Vector2 &k1, const Vector2 &k2) {
}
bool GrooveJoint2DSW::setup(real_t p_step) {
-
// calculate endpoints in worldspace
Vector2 ta = A->get_transform().xform(A_groove_1);
Vector2 tb = A->get_transform().xform(A_groove_2);
@@ -311,7 +309,6 @@ bool GrooveJoint2DSW::setup(real_t p_step) {
}
void GrooveJoint2DSW::solve(real_t p_step) {
-
// compute impulse
Vector2 vr = relative_velocity(A, B, rA, rB);
@@ -329,7 +326,6 @@ void GrooveJoint2DSW::solve(real_t p_step) {
GrooveJoint2DSW::GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, Body2DSW *p_body_a, Body2DSW *p_body_b) :
Joint2DSW(_arr, 2) {
-
A = p_body_a;
B = p_body_b;
@@ -343,7 +339,6 @@ GrooveJoint2DSW::GrooveJoint2DSW(const Vector2 &p_a_groove1, const Vector2 &p_a_
}
GrooveJoint2DSW::~GrooveJoint2DSW() {
-
A->remove_constraint(this);
B->remove_constraint(this);
}
@@ -353,17 +348,17 @@ GrooveJoint2DSW::~GrooveJoint2DSW() {
//////////////////////////////////////////////
bool DampedSpringJoint2DSW::setup(real_t p_step) {
-
rA = A->get_transform().basis_xform(anchor_A);
rB = B->get_transform().basis_xform(anchor_B);
Vector2 delta = (B->get_transform().get_origin() + rB) - (A->get_transform().get_origin() + rA);
real_t dist = delta.length();
- if (dist)
+ if (dist) {
n = delta / dist;
- else
+ } else {
n = Vector2();
+ }
real_t k = k_scalar(A, B, rA, rB, n);
n_mass = 1.0f / k;
@@ -382,7 +377,6 @@ bool DampedSpringJoint2DSW::setup(real_t p_step) {
}
void DampedSpringJoint2DSW::solve(real_t p_step) {
-
// compute relative velocity
real_t vrn = normal_relative_velocity(A, B, rA, rB, n) - target_vrn;
@@ -397,38 +391,28 @@ void DampedSpringJoint2DSW::solve(real_t p_step) {
}
void DampedSpringJoint2DSW::set_param(PhysicsServer2D::DampedStringParam p_param, real_t p_value) {
-
switch (p_param) {
-
case PhysicsServer2D::DAMPED_STRING_REST_LENGTH: {
-
rest_length = p_value;
} break;
case PhysicsServer2D::DAMPED_STRING_DAMPING: {
-
damping = p_value;
} break;
case PhysicsServer2D::DAMPED_STRING_STIFFNESS: {
-
stiffness = p_value;
} break;
}
}
real_t DampedSpringJoint2DSW::get_param(PhysicsServer2D::DampedStringParam p_param) const {
-
switch (p_param) {
-
case PhysicsServer2D::DAMPED_STRING_REST_LENGTH: {
-
return rest_length;
} break;
case PhysicsServer2D::DAMPED_STRING_DAMPING: {
-
return damping;
} break;
case PhysicsServer2D::DAMPED_STRING_STIFFNESS: {
-
return stiffness;
} break;
}
@@ -438,7 +422,6 @@ real_t DampedSpringJoint2DSW::get_param(PhysicsServer2D::DampedStringParam p_par
DampedSpringJoint2DSW::DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, Body2DSW *p_body_a, Body2DSW *p_body_b) :
Joint2DSW(_arr, 2) {
-
A = p_body_a;
B = p_body_b;
anchor_A = A->get_inv_transform().xform(p_anchor_a);
@@ -453,7 +436,6 @@ DampedSpringJoint2DSW::DampedSpringJoint2DSW(const Vector2 &p_anchor_a, const Ve
}
DampedSpringJoint2DSW::~DampedSpringJoint2DSW() {
-
A->remove_constraint(this);
B->remove_constraint(this);
}
diff --git a/servers/physics_2d/joints_2d_sw.h b/servers/physics_2d/joints_2d_sw.h
index a0d25dc70d..87556ccea1 100644
--- a/servers/physics_2d/joints_2d_sw.h
+++ b/servers/physics_2d/joints_2d_sw.h
@@ -35,7 +35,6 @@
#include "constraint_2d_sw.h"
class Joint2DSW : public Constraint2DSW {
-
real_t max_force;
real_t bias;
real_t max_bias;
@@ -59,7 +58,6 @@ public:
};
class PinJoint2DSW : public Joint2DSW {
-
union {
struct {
Body2DSW *A;
@@ -91,7 +89,6 @@ public:
};
class GrooveJoint2DSW : public Joint2DSW {
-
union {
struct {
Body2DSW *A;
@@ -126,7 +123,6 @@ public:
};
class DampedSpringJoint2DSW : public Joint2DSW {
-
union {
struct {
Body2DSW *A;
diff --git a/servers/physics_2d/physics_server_2d_sw.cpp b/servers/physics_2d/physics_server_2d_sw.cpp
index 871e2aba1d..a686903763 100644
--- a/servers/physics_2d/physics_server_2d_sw.cpp
+++ b/servers/physics_2d/physics_server_2d_sw.cpp
@@ -41,44 +41,33 @@
ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead.");
RID PhysicsServer2DSW::_shape_create(ShapeType p_shape) {
-
Shape2DSW *shape = nullptr;
switch (p_shape) {
-
case SHAPE_LINE: {
-
shape = memnew(LineShape2DSW);
} break;
case SHAPE_RAY: {
-
shape = memnew(RayShape2DSW);
} break;
case SHAPE_SEGMENT: {
-
shape = memnew(SegmentShape2DSW);
} break;
case SHAPE_CIRCLE: {
-
shape = memnew(CircleShape2DSW);
} break;
case SHAPE_RECTANGLE: {
-
shape = memnew(RectangleShape2DSW);
} break;
case SHAPE_CAPSULE: {
-
shape = memnew(CapsuleShape2DSW);
} break;
case SHAPE_CONVEX_POLYGON: {
-
shape = memnew(ConvexPolygonShape2DSW);
} break;
case SHAPE_CONCAVE_POLYGON: {
-
shape = memnew(ConcavePolygonShape2DSW);
} break;
case SHAPE_CUSTOM: {
-
ERR_FAIL_V(RID());
} break;
@@ -91,63 +80,56 @@ RID PhysicsServer2DSW::_shape_create(ShapeType p_shape) {
}
RID PhysicsServer2DSW::line_shape_create() {
-
return _shape_create(SHAPE_LINE);
}
RID PhysicsServer2DSW::ray_shape_create() {
-
return _shape_create(SHAPE_RAY);
}
-RID PhysicsServer2DSW::segment_shape_create() {
+RID PhysicsServer2DSW::segment_shape_create() {
return _shape_create(SHAPE_SEGMENT);
}
-RID PhysicsServer2DSW::circle_shape_create() {
+RID PhysicsServer2DSW::circle_shape_create() {
return _shape_create(SHAPE_CIRCLE);
}
-RID PhysicsServer2DSW::rectangle_shape_create() {
+RID PhysicsServer2DSW::rectangle_shape_create() {
return _shape_create(SHAPE_RECTANGLE);
}
-RID PhysicsServer2DSW::capsule_shape_create() {
+RID PhysicsServer2DSW::capsule_shape_create() {
return _shape_create(SHAPE_CAPSULE);
}
RID PhysicsServer2DSW::convex_polygon_shape_create() {
-
return _shape_create(SHAPE_CONVEX_POLYGON);
}
-RID PhysicsServer2DSW::concave_polygon_shape_create() {
+RID PhysicsServer2DSW::concave_polygon_shape_create() {
return _shape_create(SHAPE_CONCAVE_POLYGON);
}
void PhysicsServer2DSW::shape_set_data(RID p_shape, const Variant &p_data) {
-
Shape2DSW *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND(!shape);
shape->set_data(p_data);
};
void PhysicsServer2DSW::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) {
-
Shape2DSW *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND(!shape);
shape->set_custom_bias(p_bias);
}
PhysicsServer2D::ShapeType PhysicsServer2DSW::shape_get_type(RID p_shape) const {
-
const Shape2DSW *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, SHAPE_CUSTOM);
return shape->get_type();
};
Variant PhysicsServer2DSW::shape_get_data(RID p_shape) const {
-
const Shape2DSW *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, Variant());
ERR_FAIL_COND_V(!shape->is_configured(), Variant());
@@ -155,18 +137,17 @@ Variant PhysicsServer2DSW::shape_get_data(RID p_shape) const {
};
real_t PhysicsServer2DSW::shape_get_custom_solver_bias(RID p_shape) const {
-
const Shape2DSW *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0);
return shape->get_custom_bias();
}
void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata) {
-
CollCbkData *cbk = (CollCbkData *)p_userdata;
- if (cbk->max == 0)
+ if (cbk->max == 0) {
return;
+ }
if (cbk->valid_dir != Vector2()) {
if (p_point_A.distance_squared_to(p_point_B) > cbk->valid_depth * cbk->valid_depth) {
@@ -194,7 +175,6 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &
real_t min_depth = 1e20;
int min_depth_idx = 0;
for (int i = 0; i < cbk->amount; i++) {
-
real_t d = cbk->ptr[i * 2 + 0].distance_squared_to(cbk->ptr[i * 2 + 1]);
if (d < min_depth) {
min_depth = d;
@@ -203,14 +183,14 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &
}
real_t d = p_point_A.distance_squared_to(p_point_B);
- if (d < min_depth)
+ if (d < min_depth) {
return;
+ }
cbk->ptr[min_depth_idx * 2 + 0] = p_point_A;
cbk->ptr[min_depth_idx * 2 + 1] = p_point_B;
cbk->passed++;
} else {
-
cbk->ptr[cbk->amount * 2 + 0] = p_point_A;
cbk->ptr[cbk->amount * 2 + 1] = p_point_B;
cbk->amount++;
@@ -219,14 +199,12 @@ void PhysicsServer2DSW::_shape_col_cbk(const Vector2 &p_point_A, const Vector2 &
}
bool PhysicsServer2DSW::shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) {
-
Shape2DSW *shape_A = shape_owner.getornull(p_shape_A);
ERR_FAIL_COND_V(!shape_A, false);
Shape2DSW *shape_B = shape_owner.getornull(p_shape_B);
ERR_FAIL_COND_V(!shape_B, false);
if (p_result_max == 0) {
-
return CollisionSolver2DSW::solve(shape_A, p_xform_A, p_motion_A, shape_B, p_xform_B, p_motion_B, nullptr, nullptr);
}
@@ -242,7 +220,6 @@ bool PhysicsServer2DSW::shape_collide(RID p_shape_A, const Transform2D &p_xform_
}
RID PhysicsServer2DSW::space_create() {
-
Space2DSW *space = memnew(Space2DSW);
RID id = space_owner.make_rid(space);
space->set_self(id);
@@ -257,17 +234,16 @@ RID PhysicsServer2DSW::space_create() {
};
void PhysicsServer2DSW::space_set_active(RID p_space, bool p_active) {
-
Space2DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
- if (p_active)
+ if (p_active) {
active_spaces.insert(space);
- else
+ } else {
active_spaces.erase(space);
+ }
}
bool PhysicsServer2DSW::space_is_active(RID p_space) const {
-
const Space2DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, false);
@@ -275,7 +251,6 @@ bool PhysicsServer2DSW::space_is_active(RID p_space) const {
}
void PhysicsServer2DSW::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) {
-
Space2DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
@@ -283,35 +258,30 @@ void PhysicsServer2DSW::space_set_param(RID p_space, SpaceParameter p_param, rea
}
real_t PhysicsServer2DSW::space_get_param(RID p_space, SpaceParameter p_param) const {
-
const Space2DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, 0);
return space->get_param(p_param);
}
void PhysicsServer2DSW::space_set_debug_contacts(RID p_space, int p_max_contacts) {
-
Space2DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
space->set_debug_contacts(p_max_contacts);
}
Vector<Vector2> PhysicsServer2DSW::space_get_contacts(RID p_space) const {
-
Space2DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, Vector<Vector2>());
return space->get_debug_contacts();
}
int PhysicsServer2DSW::space_get_contact_count(RID p_space) const {
-
Space2DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, 0);
return space->get_debug_contact_count();
}
PhysicsDirectSpaceState2D *PhysicsServer2DSW::space_get_direct_state(RID p_space) {
-
Space2DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, nullptr);
ERR_FAIL_COND_V_MSG((using_threads && !doing_sync) || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification.");
@@ -320,7 +290,6 @@ PhysicsDirectSpaceState2D *PhysicsServer2DSW::space_get_direct_state(RID p_space
}
RID PhysicsServer2DSW::area_create() {
-
Area2DSW *area = memnew(Area2DSW);
RID rid = area_owner.make_rid(area);
area->set_self(rid);
@@ -328,7 +297,6 @@ RID PhysicsServer2DSW::area_create() {
};
void PhysicsServer2DSW::area_set_space(RID p_area, RID p_space) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -338,26 +306,26 @@ void PhysicsServer2DSW::area_set_space(RID p_area, RID p_space) {
ERR_FAIL_COND(!space);
}
- if (area->get_space() == space)
+ if (area->get_space() == space) {
return; //pointless
+ }
area->clear_constraints();
area->set_space(space);
};
RID PhysicsServer2DSW::area_get_space(RID p_area) const {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, RID());
Space2DSW *space = area->get_space();
- if (!space)
+ if (!space) {
return RID();
+ }
return space->get_self();
};
void PhysicsServer2DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -365,7 +333,6 @@ void PhysicsServer2DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverri
}
PhysicsServer2D::AreaSpaceOverrideMode PhysicsServer2DSW::area_get_space_override_mode(RID p_area) const {
-
const Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, AREA_SPACE_OVERRIDE_DISABLED);
@@ -373,7 +340,6 @@ PhysicsServer2D::AreaSpaceOverrideMode PhysicsServer2DSW::area_get_space_overrid
}
void PhysicsServer2DSW::area_add_shape(RID p_area, RID p_shape, const Transform2D &p_transform, bool p_disabled) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -384,7 +350,6 @@ void PhysicsServer2DSW::area_add_shape(RID p_area, RID p_shape, const Transform2
}
void PhysicsServer2DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -394,8 +359,8 @@ void PhysicsServer2DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape)
area->set_shape(p_shape_idx, shape);
}
-void PhysicsServer2DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform2D &p_transform) {
+void PhysicsServer2DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform2D &p_transform) {
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -403,7 +368,6 @@ void PhysicsServer2DSW::area_set_shape_transform(RID p_area, int p_shape_idx, co
}
void PhysicsServer2DSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_disabled) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
ERR_FAIL_INDEX(p_shape, area->get_shape_count());
@@ -413,14 +377,13 @@ void PhysicsServer2DSW::area_set_shape_disabled(RID p_area, int p_shape, bool p_
}
int PhysicsServer2DSW::area_get_shape_count(RID p_area) const {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, -1);
return area->get_shape_count();
}
-RID PhysicsServer2DSW::area_get_shape(RID p_area, int p_shape_idx) const {
+RID PhysicsServer2DSW::area_get_shape(RID p_area, int p_shape_idx) const {
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, RID());
@@ -429,8 +392,8 @@ RID PhysicsServer2DSW::area_get_shape(RID p_area, int p_shape_idx) const {
return shape->get_self();
}
-Transform2D PhysicsServer2DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const {
+Transform2D PhysicsServer2DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const {
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, Transform2D());
@@ -438,7 +401,6 @@ Transform2D PhysicsServer2DSW::area_get_shape_transform(RID p_area, int p_shape_
}
void PhysicsServer2DSW::area_remove_shape(RID p_area, int p_shape_idx) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -446,16 +408,15 @@ void PhysicsServer2DSW::area_remove_shape(RID p_area, int p_shape_idx) {
}
void PhysicsServer2DSW::area_clear_shapes(RID p_area) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- while (area->get_shape_count())
+ while (area->get_shape_count()) {
area->remove_shape(0);
+ }
}
void PhysicsServer2DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id) {
-
if (space_owner.owns(p_area)) {
Space2DSW *space = space_owner.getornull(p_area);
p_area = space->get_default_area()->get_self();
@@ -464,8 +425,8 @@ void PhysicsServer2DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id
ERR_FAIL_COND(!area);
area->set_instance_id(p_id);
}
-ObjectID PhysicsServer2DSW::area_get_object_instance_id(RID p_area) const {
+ObjectID PhysicsServer2DSW::area_get_object_instance_id(RID p_area) const {
if (space_owner.owns(p_area)) {
Space2DSW *space = space_owner.getornull(p_area);
p_area = space->get_default_area()->get_self();
@@ -476,7 +437,6 @@ ObjectID PhysicsServer2DSW::area_get_object_instance_id(RID p_area) const {
}
void PhysicsServer2DSW::area_attach_canvas_instance_id(RID p_area, ObjectID p_id) {
-
if (space_owner.owns(p_area)) {
Space2DSW *space = space_owner.getornull(p_area);
p_area = space->get_default_area()->get_self();
@@ -485,8 +445,8 @@ void PhysicsServer2DSW::area_attach_canvas_instance_id(RID p_area, ObjectID p_id
ERR_FAIL_COND(!area);
area->set_canvas_instance_id(p_id);
}
-ObjectID PhysicsServer2DSW::area_get_canvas_instance_id(RID p_area) const {
+ObjectID PhysicsServer2DSW::area_get_canvas_instance_id(RID p_area) const {
if (space_owner.owns(p_area)) {
Space2DSW *space = space_owner.getornull(p_area);
p_area = space->get_default_area()->get_self();
@@ -497,7 +457,6 @@ ObjectID PhysicsServer2DSW::area_get_canvas_instance_id(RID p_area) const {
}
void PhysicsServer2DSW::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) {
-
if (space_owner.owns(p_area)) {
Space2DSW *space = space_owner.getornull(p_area);
p_area = space->get_default_area()->get_self();
@@ -508,14 +467,12 @@ void PhysicsServer2DSW::area_set_param(RID p_area, AreaParameter p_param, const
};
void PhysicsServer2DSW::area_set_transform(RID p_area, const Transform2D &p_transform) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_transform(p_transform);
};
Variant PhysicsServer2DSW::area_get_param(RID p_area, AreaParameter p_param) const {
-
if (space_owner.owns(p_area)) {
Space2DSW *space = space_owner.getornull(p_area);
p_area = space->get_default_area()->get_self();
@@ -527,7 +484,6 @@ Variant PhysicsServer2DSW::area_get_param(RID p_area, AreaParameter p_param) con
};
Transform2D PhysicsServer2DSW::area_get_transform(RID p_area) const {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, Transform2D());
@@ -535,14 +491,12 @@ Transform2D PhysicsServer2DSW::area_get_transform(RID p_area) const {
};
void PhysicsServer2DSW::area_set_pickable(RID p_area, bool p_pickable) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_pickable(p_pickable);
}
void PhysicsServer2DSW::area_set_monitorable(RID p_area, bool p_monitorable) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
FLUSH_QUERY_CHECK(area);
@@ -551,7 +505,6 @@ void PhysicsServer2DSW::area_set_monitorable(RID p_area, bool p_monitorable) {
}
void PhysicsServer2DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -559,7 +512,6 @@ void PhysicsServer2DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) {
}
void PhysicsServer2DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -567,7 +519,6 @@ void PhysicsServer2DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) {
}
void PhysicsServer2DSW::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -575,7 +526,6 @@ void PhysicsServer2DSW::area_set_monitor_callback(RID p_area, Object *p_receiver
}
void PhysicsServer2DSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
-
Area2DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -585,7 +535,6 @@ void PhysicsServer2DSW::area_set_area_monitor_callback(RID p_area, Object *p_rec
/* BODY API */
RID PhysicsServer2DSW::body_create() {
-
Body2DSW *body = memnew(Body2DSW);
RID rid = body_owner.make_rid(body);
body->set_self(rid);
@@ -593,7 +542,6 @@ RID PhysicsServer2DSW::body_create() {
}
void PhysicsServer2DSW::body_set_space(RID p_body, RID p_space) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
Space2DSW *space = nullptr;
@@ -602,26 +550,26 @@ void PhysicsServer2DSW::body_set_space(RID p_body, RID p_space) {
ERR_FAIL_COND(!space);
}
- if (body->get_space() == space)
+ if (body->get_space() == space) {
return; //pointless
+ }
body->clear_constraint_map();
body->set_space(space);
};
RID PhysicsServer2DSW::body_get_space(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, RID());
Space2DSW *space = body->get_space();
- if (!space)
+ if (!space) {
return RID();
+ }
return space->get_self();
};
void PhysicsServer2DSW::body_set_mode(RID p_body, BodyMode p_mode) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
FLUSH_QUERY_CHECK(body);
@@ -630,7 +578,6 @@ void PhysicsServer2DSW::body_set_mode(RID p_body, BodyMode p_mode) {
};
PhysicsServer2D::BodyMode PhysicsServer2DSW::body_get_mode(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, BODY_MODE_STATIC);
@@ -638,7 +585,6 @@ PhysicsServer2D::BodyMode PhysicsServer2DSW::body_get_mode(RID p_body) const {
};
void PhysicsServer2DSW::body_add_shape(RID p_body, RID p_shape, const Transform2D &p_transform, bool p_disabled) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -649,7 +595,6 @@ void PhysicsServer2DSW::body_add_shape(RID p_body, RID p_shape, const Transform2
}
void PhysicsServer2DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -659,8 +604,8 @@ void PhysicsServer2DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape)
body->set_shape(p_shape_idx, shape);
}
-void PhysicsServer2DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform) {
+void PhysicsServer2DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform2D &p_transform) {
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -668,28 +613,25 @@ void PhysicsServer2DSW::body_set_shape_transform(RID p_body, int p_shape_idx, co
}
void PhysicsServer2DSW::body_set_shape_metadata(RID p_body, int p_shape_idx, const Variant &p_metadata) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_shape_metadata(p_shape_idx, p_metadata);
}
Variant PhysicsServer2DSW::body_get_shape_metadata(RID p_body, int p_shape_idx) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Variant());
return body->get_shape_metadata(p_shape_idx);
}
int PhysicsServer2DSW::body_get_shape_count(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, -1);
return body->get_shape_count();
}
-RID PhysicsServer2DSW::body_get_shape(RID p_body, int p_shape_idx) const {
+RID PhysicsServer2DSW::body_get_shape(RID p_body, int p_shape_idx) const {
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, RID());
@@ -698,8 +640,8 @@ RID PhysicsServer2DSW::body_get_shape(RID p_body, int p_shape_idx) const {
return shape->get_self();
}
-Transform2D PhysicsServer2DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const {
+Transform2D PhysicsServer2DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const {
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Transform2D());
@@ -707,7 +649,6 @@ Transform2D PhysicsServer2DSW::body_get_shape_transform(RID p_body, int p_shape_
}
void PhysicsServer2DSW::body_remove_shape(RID p_body, int p_shape_idx) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -715,16 +656,15 @@ void PhysicsServer2DSW::body_remove_shape(RID p_body, int p_shape_idx) {
}
void PhysicsServer2DSW::body_clear_shapes(RID p_body) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- while (body->get_shape_count())
+ while (body->get_shape_count()) {
body->remove_shape(0);
+ }
}
void PhysicsServer2DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
@@ -732,8 +672,8 @@ void PhysicsServer2DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, boo
body->set_shape_as_disabled(p_shape_idx, p_disabled);
}
-void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, float p_margin) {
+void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_shape_idx, bool p_enable, float p_margin) {
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
@@ -743,14 +683,12 @@ void PhysicsServer2DSW::body_set_shape_as_one_way_collision(RID p_body, int p_sh
}
void PhysicsServer2DSW::body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_continuous_collision_detection_mode(p_mode);
}
PhysicsServer2DSW::CCDMode PhysicsServer2DSW::body_get_continuous_collision_detection_mode(RID p_body) const {
-
const Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, CCD_MODE_DISABLED);
@@ -758,7 +696,6 @@ PhysicsServer2DSW::CCDMode PhysicsServer2DSW::body_get_continuous_collision_dete
}
void PhysicsServer2DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -766,7 +703,6 @@ void PhysicsServer2DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id
};
ObjectID PhysicsServer2DSW::body_get_object_instance_id(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, ObjectID());
@@ -774,7 +710,6 @@ ObjectID PhysicsServer2DSW::body_get_object_instance_id(RID p_body) const {
};
void PhysicsServer2DSW::body_attach_canvas_instance_id(RID p_body, ObjectID p_id) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -782,7 +717,6 @@ void PhysicsServer2DSW::body_attach_canvas_instance_id(RID p_body, ObjectID p_id
};
ObjectID PhysicsServer2DSW::body_get_canvas_instance_id(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, ObjectID());
@@ -790,14 +724,12 @@ ObjectID PhysicsServer2DSW::body_get_canvas_instance_id(RID p_body) const {
};
void PhysicsServer2DSW::body_set_collision_layer(RID p_body, uint32_t p_layer) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_collision_layer(p_layer);
};
uint32_t PhysicsServer2DSW::body_get_collision_layer(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -805,14 +737,12 @@ uint32_t PhysicsServer2DSW::body_get_collision_layer(RID p_body) const {
};
void PhysicsServer2DSW::body_set_collision_mask(RID p_body, uint32_t p_mask) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_collision_mask(p_mask);
};
uint32_t PhysicsServer2DSW::body_get_collision_mask(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -820,7 +750,6 @@ uint32_t PhysicsServer2DSW::body_get_collision_mask(RID p_body) const {
};
void PhysicsServer2DSW::body_set_param(RID p_body, BodyParameter p_param, real_t p_value) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -828,7 +757,6 @@ void PhysicsServer2DSW::body_set_param(RID p_body, BodyParameter p_param, real_t
};
real_t PhysicsServer2DSW::body_get_param(RID p_body, BodyParameter p_param) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -836,7 +764,6 @@ real_t PhysicsServer2DSW::body_get_param(RID p_body, BodyParameter p_param) cons
};
void PhysicsServer2DSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -844,7 +771,6 @@ void PhysicsServer2DSW::body_set_state(RID p_body, BodyState p_state, const Vari
};
Variant PhysicsServer2DSW::body_get_state(RID p_body, BodyState p_state) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Variant());
@@ -852,7 +778,6 @@ Variant PhysicsServer2DSW::body_get_state(RID p_body, BodyState p_state) const {
};
void PhysicsServer2DSW::body_set_applied_force(RID p_body, const Vector2 &p_force) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -861,14 +786,12 @@ void PhysicsServer2DSW::body_set_applied_force(RID p_body, const Vector2 &p_forc
};
Vector2 PhysicsServer2DSW::body_get_applied_force(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Vector2());
return body->get_applied_force();
};
void PhysicsServer2DSW::body_set_applied_torque(RID p_body, real_t p_torque) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -877,7 +800,6 @@ void PhysicsServer2DSW::body_set_applied_torque(RID p_body, real_t p_torque) {
};
real_t PhysicsServer2DSW::body_get_applied_torque(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -902,7 +824,6 @@ void PhysicsServer2DSW::body_apply_torque_impulse(RID p_body, real_t p_torque) {
}
void PhysicsServer2DSW::body_apply_impulse(RID p_body, const Vector2 &p_pos, const Vector2 &p_impulse) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -921,7 +842,6 @@ void PhysicsServer2DSW::body_add_central_force(RID p_body, const Vector2 &p_forc
};
void PhysicsServer2DSW::body_add_force(RID p_body, const Vector2 &p_offset, const Vector2 &p_force) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -938,7 +858,6 @@ void PhysicsServer2DSW::body_add_torque(RID p_body, real_t p_torque) {
};
void PhysicsServer2DSW::body_set_axis_velocity(RID p_body, const Vector2 &p_axis_velocity) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -953,7 +872,6 @@ void PhysicsServer2DSW::body_set_axis_velocity(RID p_body, const Vector2 &p_axis
};
void PhysicsServer2DSW::body_add_collision_exception(RID p_body, RID p_body_b) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -962,7 +880,6 @@ void PhysicsServer2DSW::body_add_collision_exception(RID p_body, RID p_body_b) {
};
void PhysicsServer2DSW::body_remove_collision_exception(RID p_body, RID p_body_b) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -971,7 +888,6 @@ void PhysicsServer2DSW::body_remove_collision_exception(RID p_body, RID p_body_b
};
void PhysicsServer2DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -981,20 +897,17 @@ void PhysicsServer2DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_e
};
void PhysicsServer2DSW::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
};
real_t PhysicsServer2DSW::body_get_contacts_reported_depth_threshold(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
return 0;
};
void PhysicsServer2DSW::body_set_omit_force_integration(RID p_body, bool p_omit) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -1002,35 +915,30 @@ void PhysicsServer2DSW::body_set_omit_force_integration(RID p_body, bool p_omit)
};
bool PhysicsServer2DSW::body_is_omitting_force_integration(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
return body->get_omit_force_integration();
};
void PhysicsServer2DSW::body_set_max_contacts_reported(RID p_body, int p_contacts) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_max_contacts_reported(p_contacts);
}
int PhysicsServer2DSW::body_get_max_contacts_reported(RID p_body) const {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, -1);
return body->get_max_contacts_reported();
}
void PhysicsServer2DSW::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method, p_udata);
}
bool PhysicsServer2DSW::body_collide_shape(RID p_body, int p_body_shape, RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, Vector2 *r_results, int p_result_max, int &r_result_count) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
ERR_FAIL_INDEX_V(p_body_shape, body->get_shape_count(), false);
@@ -1039,14 +947,12 @@ bool PhysicsServer2DSW::body_collide_shape(RID p_body, int p_body_shape, RID p_s
}
void PhysicsServer2DSW::body_set_pickable(RID p_body, bool p_pickable) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_pickable(p_pickable);
}
bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, MotionResult *r_result, bool p_exclude_raycast_shapes) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
ERR_FAIL_COND_V(!body->get_space(), false);
@@ -1058,7 +964,6 @@ bool PhysicsServer2DSW::body_test_motion(RID p_body, const Transform2D &p_from,
}
int PhysicsServer2DSW::body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) {
-
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
ERR_FAIL_COND_V(!body->get_space(), false);
@@ -1068,11 +973,11 @@ int PhysicsServer2DSW::body_test_ray_separation(RID p_body, const Transform2D &p
}
PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) {
-
ERR_FAIL_COND_V_MSG((using_threads && !doing_sync), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");
- if (!body_owner.owns(p_body))
+ if (!body_owner.owns(p_body)) {
return nullptr;
+ }
Body2DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, nullptr);
@@ -1086,26 +991,36 @@ PhysicsDirectBodyState2D *PhysicsServer2DSW::body_get_direct_state(RID p_body) {
/* JOINT API */
void PhysicsServer2DSW::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) {
-
Joint2DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
switch (p_param) {
- case JOINT_PARAM_BIAS: joint->set_bias(p_value); break;
- case JOINT_PARAM_MAX_BIAS: joint->set_max_bias(p_value); break;
- case JOINT_PARAM_MAX_FORCE: joint->set_max_force(p_value); break;
+ case JOINT_PARAM_BIAS:
+ joint->set_bias(p_value);
+ break;
+ case JOINT_PARAM_MAX_BIAS:
+ joint->set_max_bias(p_value);
+ break;
+ case JOINT_PARAM_MAX_FORCE:
+ joint->set_max_force(p_value);
+ break;
}
}
real_t PhysicsServer2DSW::joint_get_param(RID p_joint, JointParam p_param) const {
-
const Joint2DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, -1);
switch (p_param) {
- case JOINT_PARAM_BIAS: return joint->get_bias(); break;
- case JOINT_PARAM_MAX_BIAS: return joint->get_max_bias(); break;
- case JOINT_PARAM_MAX_FORCE: return joint->get_max_force(); break;
+ case JOINT_PARAM_BIAS:
+ return joint->get_bias();
+ break;
+ case JOINT_PARAM_MAX_BIAS:
+ return joint->get_max_bias();
+ break;
+ case JOINT_PARAM_MAX_FORCE:
+ return joint->get_max_force();
+ break;
}
return 0;
@@ -1139,7 +1054,6 @@ bool PhysicsServer2DSW::joint_is_disabled_collisions_between_bodies(RID p_joint)
}
RID PhysicsServer2DSW::pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID p_body_b) {
-
Body2DSW *A = body_owner.getornull(p_body_a);
ERR_FAIL_COND_V(!A, RID());
Body2DSW *B = nullptr;
@@ -1156,7 +1070,6 @@ RID PhysicsServer2DSW::pin_joint_create(const Vector2 &p_pos, RID p_body_a, RID
}
RID PhysicsServer2DSW::groove_joint_create(const Vector2 &p_a_groove1, const Vector2 &p_a_groove2, const Vector2 &p_b_anchor, RID p_body_a, RID p_body_b) {
-
Body2DSW *A = body_owner.getornull(p_body_a);
ERR_FAIL_COND_V(!A, RID());
@@ -1170,7 +1083,6 @@ RID PhysicsServer2DSW::groove_joint_create(const Vector2 &p_a_groove1, const Vec
}
RID PhysicsServer2DSW::damped_spring_joint_create(const Vector2 &p_anchor_a, const Vector2 &p_anchor_b, RID p_body_a, RID p_body_b) {
-
Body2DSW *A = body_owner.getornull(p_body_a);
ERR_FAIL_COND_V(!A, RID());
@@ -1184,7 +1096,6 @@ RID PhysicsServer2DSW::damped_spring_joint_create(const Vector2 &p_anchor_a, con
}
void PhysicsServer2DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) {
-
Joint2DSW *j = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!j);
ERR_FAIL_COND(j->get_type() != JOINT_PIN);
@@ -1203,7 +1114,6 @@ real_t PhysicsServer2DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param
}
void PhysicsServer2DSW::damped_string_joint_set_param(RID p_joint, DampedStringParam p_param, real_t p_value) {
-
Joint2DSW *j = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!j);
ERR_FAIL_COND(j->get_type() != JOINT_DAMPED_SPRING);
@@ -1213,7 +1123,6 @@ void PhysicsServer2DSW::damped_string_joint_set_param(RID p_joint, DampedStringP
}
real_t PhysicsServer2DSW::damped_string_joint_get_param(RID p_joint, DampedStringParam p_param) const {
-
Joint2DSW *j = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!j, 0);
ERR_FAIL_COND_V(j->get_type() != JOINT_DAMPED_SPRING, 0);
@@ -1223,7 +1132,6 @@ real_t PhysicsServer2DSW::damped_string_joint_get_param(RID p_joint, DampedStrin
}
PhysicsServer2D::JointType PhysicsServer2DSW::joint_get_type(RID p_joint) const {
-
Joint2DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, JOINT_PIN);
@@ -1231,11 +1139,9 @@ PhysicsServer2D::JointType PhysicsServer2DSW::joint_get_type(RID p_joint) const
}
void PhysicsServer2DSW::free(RID p_rid) {
-
_update_shapes(); // just in case
if (shape_owner.owns(p_rid)) {
-
Shape2DSW *shape = shape_owner.getornull(p_rid);
while (shape->get_owners().size()) {
@@ -1246,7 +1152,6 @@ void PhysicsServer2DSW::free(RID p_rid) {
shape_owner.free(p_rid);
memdelete(shape);
} else if (body_owner.owns(p_rid)) {
-
Body2DSW *body = body_owner.getornull(p_rid);
/*
@@ -1260,7 +1165,6 @@ void PhysicsServer2DSW::free(RID p_rid) {
body_set_space(p_rid, RID());
while (body->get_shape_count()) {
-
body->remove_shape(0);
}
@@ -1268,7 +1172,6 @@ void PhysicsServer2DSW::free(RID p_rid) {
memdelete(body);
} else if (area_owner.owns(p_rid)) {
-
Area2DSW *area = area_owner.getornull(p_rid);
/*
@@ -1279,14 +1182,12 @@ void PhysicsServer2DSW::free(RID p_rid) {
area->set_space(nullptr);
while (area->get_shape_count()) {
-
area->remove_shape(0);
}
area_owner.free(p_rid);
memdelete(area);
} else if (space_owner.owns(p_rid)) {
-
Space2DSW *space = space_owner.getornull(p_rid);
while (space->get_objects().size()) {
@@ -1299,25 +1200,21 @@ void PhysicsServer2DSW::free(RID p_rid) {
space_owner.free(p_rid);
memdelete(space);
} else if (joint_owner.owns(p_rid)) {
-
Joint2DSW *joint = joint_owner.getornull(p_rid);
joint_owner.free(p_rid);
memdelete(joint);
} else {
-
ERR_FAIL_MSG("Invalid ID.");
}
};
void PhysicsServer2DSW::set_active(bool p_active) {
-
active = p_active;
};
void PhysicsServer2DSW::init() {
-
doing_sync = false;
last_step = 0.001;
iterations = 8; // 8?
@@ -1326,9 +1223,9 @@ void PhysicsServer2DSW::init() {
};
void PhysicsServer2DSW::step(real_t p_step) {
-
- if (!active)
+ if (!active) {
return;
+ }
_update_shapes();
@@ -1340,7 +1237,6 @@ void PhysicsServer2DSW::step(real_t p_step) {
active_objects = 0;
collision_pairs = 0;
for (Set<const Space2DSW *>::Element *E = active_spaces.front(); E; E = E->next()) {
-
stepper->step((Space2DSW *)E->get(), p_step, iterations);
island_count += E->get()->get_island_count();
active_objects += E->get()->get_active_objects();
@@ -1349,21 +1245,19 @@ void PhysicsServer2DSW::step(real_t p_step) {
};
void PhysicsServer2DSW::sync() {
-
doing_sync = true;
};
void PhysicsServer2DSW::flush_queries() {
-
- if (!active)
+ if (!active) {
return;
+ }
flushing_queries = true;
uint64_t time_beg = OS::get_singleton()->get_ticks_usec();
for (Set<const Space2DSW *>::Element *E = active_spaces.front(); E; E = E->next()) {
-
Space2DSW *space = (Space2DSW *)E->get();
space->call_queries();
}
@@ -1371,7 +1265,6 @@ void PhysicsServer2DSW::flush_queries() {
flushing_queries = false;
if (EngineDebugger::is_profiling("servers")) {
-
uint64_t total_time[Space2DSW::ELAPSED_TIME_MAX];
static const char *time_name[Space2DSW::ELAPSED_TIME_MAX] = {
"integrate_forces",
@@ -1386,7 +1279,6 @@ void PhysicsServer2DSW::flush_queries() {
}
for (Set<const Space2DSW *>::Element *E = active_spaces.front(); E; E = E->next()) {
-
for (int i = 0; i < Space2DSW::ELAPSED_TIME_MAX; i++) {
total_time[i] += E->get()->get_elapsed_time(Space2DSW::ElapsedTime(i));
}
@@ -1411,13 +1303,11 @@ void PhysicsServer2DSW::end_sync() {
}
void PhysicsServer2DSW::finish() {
-
memdelete(stepper);
memdelete(direct_state);
};
void PhysicsServer2DSW::_update_shapes() {
-
while (pending_shape_update_list.first()) {
pending_shape_update_list.first()->self()->_shape_changed();
pending_shape_update_list.remove(pending_shape_update_list.first());
@@ -1425,18 +1315,14 @@ void PhysicsServer2DSW::_update_shapes() {
}
int PhysicsServer2DSW::get_process_info(ProcessInfo p_info) {
-
switch (p_info) {
-
case INFO_ACTIVE_OBJECTS: {
-
return active_objects;
} break;
case INFO_COLLISION_PAIRS: {
return collision_pairs;
} break;
case INFO_ISLAND_COUNT: {
-
return island_count;
} break;
}
@@ -1447,7 +1333,6 @@ int PhysicsServer2DSW::get_process_info(ProcessInfo p_info) {
PhysicsServer2DSW *PhysicsServer2DSW::singletonsw = nullptr;
PhysicsServer2DSW::PhysicsServer2DSW() {
-
singletonsw = this;
BroadPhase2DSW::create_func = BroadPhase2DHashGrid::_create;
//BroadPhase2DSW::create_func=BroadPhase2DBasic::_create;
@@ -1459,7 +1344,3 @@ PhysicsServer2DSW::PhysicsServer2DSW() {
using_threads = int(ProjectSettings::get_singleton()->get("physics/2d/thread_model")) == 2;
flushing_queries = false;
};
-
-PhysicsServer2DSW::~PhysicsServer2DSW(){
-
-};
diff --git a/servers/physics_2d/physics_server_2d_sw.h b/servers/physics_2d/physics_server_2d_sw.h
index 918958ffe2..f9b0bc716c 100644
--- a/servers/physics_2d/physics_server_2d_sw.h
+++ b/servers/physics_2d/physics_server_2d_sw.h
@@ -39,7 +39,6 @@
#include "step_2d_sw.h"
class PhysicsServer2DSW : public PhysicsServer2D {
-
GDCLASS(PhysicsServer2DSW, PhysicsServer2D);
friend class PhysicsDirectSpaceState2DSW;
@@ -79,7 +78,6 @@ class PhysicsServer2DSW : public PhysicsServer2D {
public:
struct CollCbkData {
-
Vector2 valid_dir;
real_t valid_depth;
int max;
@@ -290,7 +288,7 @@ public:
int get_process_info(ProcessInfo p_info);
PhysicsServer2DSW();
- ~PhysicsServer2DSW();
+ ~PhysicsServer2DSW() {}
};
#endif
diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.cpp b/servers/physics_2d/physics_server_2d_wrap_mt.cpp
index 0a89a76615..49c38c6ce0 100644
--- a/servers/physics_2d/physics_server_2d_wrap_mt.cpp
+++ b/servers/physics_2d/physics_server_2d_wrap_mt.cpp
@@ -33,25 +33,21 @@
#include "core/os/os.h"
void PhysicsServer2DWrapMT::thread_exit() {
-
exit = true;
}
void PhysicsServer2DWrapMT::thread_step(real_t p_delta) {
-
physics_2d_server->step(p_delta);
step_sem.post();
}
void PhysicsServer2DWrapMT::_thread_callback(void *_instance) {
-
PhysicsServer2DWrapMT *vsmt = reinterpret_cast<PhysicsServer2DWrapMT *>(_instance);
vsmt->thread_loop();
}
void PhysicsServer2DWrapMT::thread_loop() {
-
server_thread = Thread::get_caller_id();
physics_2d_server->init();
@@ -71,57 +67,47 @@ void PhysicsServer2DWrapMT::thread_loop() {
/* EVENT QUEUING */
void PhysicsServer2DWrapMT::step(real_t p_step) {
-
if (create_thread) {
-
command_queue.push(this, &PhysicsServer2DWrapMT::thread_step, p_step);
} else {
-
command_queue.flush_all(); //flush all pending from other threads
physics_2d_server->step(p_step);
}
}
void PhysicsServer2DWrapMT::sync() {
-
if (thread) {
- if (first_frame)
+ if (first_frame) {
first_frame = false;
- else
+ } else {
step_sem.wait(); //must not wait if a step was not issued
+ }
}
physics_2d_server->sync();
}
void PhysicsServer2DWrapMT::flush_queries() {
-
physics_2d_server->flush_queries();
}
void PhysicsServer2DWrapMT::end_sync() {
-
physics_2d_server->end_sync();
}
void PhysicsServer2DWrapMT::init() {
-
if (create_thread) {
-
//OS::get_singleton()->release_rendering_thread();
thread = Thread::create(_thread_callback, this);
while (!step_thread_up) {
OS::get_singleton()->delay_usec(1000);
}
} else {
-
physics_2d_server->init();
}
}
void PhysicsServer2DWrapMT::finish() {
-
if (thread) {
-
command_queue.push(this, &PhysicsServer2DWrapMT::thread_exit);
Thread::wait_to_finish(thread);
memdelete(thread);
@@ -147,7 +133,6 @@ void PhysicsServer2DWrapMT::finish() {
PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool p_create_thread) :
command_queue(p_create_thread) {
-
physics_2d_server = p_contained;
create_thread = p_create_thread;
thread = nullptr;
@@ -167,7 +152,6 @@ PhysicsServer2DWrapMT::PhysicsServer2DWrapMT(PhysicsServer2D *p_contained, bool
}
PhysicsServer2DWrapMT::~PhysicsServer2DWrapMT() {
-
memdelete(physics_2d_server);
//finish();
}
diff --git a/servers/physics_2d/physics_server_2d_wrap_mt.h b/servers/physics_2d/physics_server_2d_wrap_mt.h
index 7e61927378..c2ae288f95 100644
--- a/servers/physics_2d/physics_server_2d_wrap_mt.h
+++ b/servers/physics_2d/physics_server_2d_wrap_mt.h
@@ -43,7 +43,6 @@
#endif
class PhysicsServer2DWrapMT : public PhysicsServer2D {
-
mutable PhysicsServer2D *physics_2d_server;
mutable CommandQueueMT command_queue;
@@ -95,7 +94,6 @@ public:
//these work well, but should be used from the main thread only
bool shape_collide(RID p_shape_A, const Transform2D &p_xform_A, const Vector2 &p_motion_A, RID p_shape_B, const Transform2D &p_xform_B, const Vector2 &p_motion_B, Vector2 *r_results, int p_result_max, int &r_result_count) {
-
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
return physics_2d_server->shape_collide(p_shape_A, p_xform_A, p_motion_A, p_shape_B, p_xform_B, p_motion_B, r_results, p_result_max, r_result_count);
}
@@ -111,20 +109,17 @@ public:
// this function only works on physics process, errors and returns null otherwise
PhysicsDirectSpaceState2D *space_get_direct_state(RID p_space) {
-
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
return physics_2d_server->space_get_direct_state(p_space);
}
FUNC2(space_set_debug_contacts, RID, int);
virtual Vector<Vector2> space_get_contacts(RID p_space) const {
-
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), Vector<Vector2>());
return physics_2d_server->space_get_contacts(p_space);
}
virtual int space_get_contact_count(RID p_space) const {
-
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), 0);
return physics_2d_server->space_get_contact_count(p_space);
}
@@ -256,20 +251,17 @@ public:
FUNC2(body_set_pickable, RID, bool);
bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) {
-
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
return physics_2d_server->body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r_result, p_exclude_raycast_shapes);
}
int body_test_ray_separation(RID p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin = 0.001) {
-
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), false);
return physics_2d_server->body_test_ray_separation(p_body, p_transform, p_infinite_inertia, r_recover_motion, r_results, p_result_max, p_margin);
}
// this function only works on physics process, errors and returns null otherwise
PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) {
-
ERR_FAIL_COND_V(main_thread != Thread::get_caller_id(), nullptr);
return physics_2d_server->body_get_direct_state(p_body);
}
@@ -325,14 +317,14 @@ public:
template <class T>
static PhysicsServer2D *init_server() {
-
int tm = GLOBAL_DEF("physics/2d/thread_model", 1);
- if (tm == 0) // single unsafe
+ if (tm == 0) { // single unsafe
return memnew(T);
- else if (tm == 1) // single safe
+ } else if (tm == 1) { // single safe
return memnew(PhysicsServer2DWrapMT(memnew(T), false));
- else // multi threaded
+ } else { // multi threaded
return memnew(PhysicsServer2DWrapMT(memnew(T), true));
+ }
}
#undef ServerNameWrapMT
diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp
index 06096d674a..c0589b9804 100644
--- a/servers/physics_2d/shape_2d_sw.cpp
+++ b/servers/physics_2d/shape_2d_sw.cpp
@@ -43,7 +43,6 @@ void Shape2DSW::configure(const Rect2 &p_aabb) {
}
Vector2 Shape2DSW::get_support(const Vector2 &p_normal) const {
-
Vector2 res[2];
int amnt;
get_supports(p_normal, res, amnt);
@@ -51,7 +50,6 @@ Vector2 Shape2DSW::get_support(const Vector2 &p_normal) const {
}
void Shape2DSW::add_owner(ShapeOwner2DSW *p_owner) {
-
Map<ShapeOwner2DSW *, int>::Element *E = owners.find(p_owner);
if (E) {
E->get()++;
@@ -61,7 +59,6 @@ void Shape2DSW::add_owner(ShapeOwner2DSW *p_owner) {
}
void Shape2DSW::remove_owner(ShapeOwner2DSW *p_owner) {
-
Map<ShapeOwner2DSW *, int>::Element *E = owners.find(p_owner);
ERR_FAIL_COND(!E);
E->get()--;
@@ -71,7 +68,6 @@ void Shape2DSW::remove_owner(ShapeOwner2DSW *p_owner) {
}
bool Shape2DSW::is_owner(ShapeOwner2DSW *p_owner) const {
-
return owners.has(p_owner);
}
@@ -80,13 +76,11 @@ const Map<ShapeOwner2DSW *, int> &Shape2DSW::get_owners() const {
}
Shape2DSW::Shape2DSW() {
-
custom_bias = 0;
configured = false;
}
Shape2DSW::~Shape2DSW() {
-
ERR_FAIL_COND(owners.size());
}
@@ -95,23 +89,19 @@ Shape2DSW::~Shape2DSW() {
/*********************************************************/
void LineShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
-
r_amount = 0;
}
bool LineShape2DSW::contains_point(const Vector2 &p_point) const {
-
return normal.dot(p_point) < d;
}
bool LineShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
-
Vector2 segment = p_begin - p_end;
real_t den = normal.dot(segment);
//printf("den is %i\n",den);
if (Math::abs(den) <= CMP_EPSILON) {
-
return false;
}
@@ -119,7 +109,6 @@ bool LineShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_e
//printf("dist is %i\n",dist);
if (dist < -CMP_EPSILON || dist > (1.0 + CMP_EPSILON)) {
-
return false;
}
@@ -130,12 +119,10 @@ bool LineShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_e
}
real_t LineShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
-
return 0;
}
void LineShape2DSW::set_data(const Variant &p_data) {
-
ERR_FAIL_COND(p_data.get_type() != Variant::ARRAY);
Array arr = p_data;
ERR_FAIL_COND(arr.size() != 2);
@@ -145,7 +132,6 @@ void LineShape2DSW::set_data(const Variant &p_data) {
}
Variant LineShape2DSW::get_data() const {
-
Array arr;
arr.resize(2);
arr[0] = normal;
@@ -158,32 +144,28 @@ Variant LineShape2DSW::get_data() const {
/*********************************************************/
void RayShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
-
r_amount = 1;
- if (p_normal.y > 0)
+ if (p_normal.y > 0) {
*r_supports = Vector2(0, length);
- else
+ } else {
*r_supports = Vector2();
+ }
}
bool RayShape2DSW::contains_point(const Vector2 &p_point) const {
-
return false;
}
bool RayShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
-
return false; //rays can't be intersected
}
real_t RayShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
-
return 0; //rays are mass-less
}
void RayShape2DSW::set_data(const Variant &p_data) {
-
Dictionary d = p_data;
length = d["length"];
slips_on_slope = d["slips_on_slope"];
@@ -191,7 +173,6 @@ void RayShape2DSW::set_data(const Variant &p_data) {
}
Variant RayShape2DSW::get_data() const {
-
Dictionary d;
d["length"] = length;
d["slips_on_slope"] = slips_on_slope;
@@ -203,7 +184,6 @@ Variant RayShape2DSW::get_data() const {
/*********************************************************/
void SegmentShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
-
if (Math::abs(p_normal.dot(n)) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
r_supports[0] = a;
r_supports[1] = b;
@@ -212,22 +192,22 @@ void SegmentShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports
}
real_t dp = p_normal.dot(b - a);
- if (dp > 0)
+ if (dp > 0) {
*r_supports = b;
- else
+ } else {
*r_supports = a;
+ }
r_amount = 1;
}
bool SegmentShape2DSW::contains_point(const Vector2 &p_point) const {
-
return false;
}
bool SegmentShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
-
- if (!Geometry::segment_intersects_segment_2d(p_begin, p_end, a, b, &r_point))
+ if (!Geometry::segment_intersects_segment_2d(p_begin, p_end, a, b, &r_point)) {
return false;
+ }
if (n.dot(p_begin) > n.dot(a)) {
r_normal = n;
@@ -239,12 +219,10 @@ bool SegmentShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &
}
real_t SegmentShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
-
return p_mass * ((a * p_scale).distance_squared_to(b * p_scale)) / 12;
}
void SegmentShape2DSW::set_data(const Variant &p_data) {
-
ERR_FAIL_COND(p_data.get_type() != Variant::RECT2);
Rect2 r = p_data;
@@ -255,15 +233,16 @@ void SegmentShape2DSW::set_data(const Variant &p_data) {
Rect2 aabb;
aabb.position = a;
aabb.expand_to(b);
- if (aabb.size.x == 0)
+ if (aabb.size.x == 0) {
aabb.size.x = 0.001;
- if (aabb.size.y == 0)
+ }
+ if (aabb.size.y == 0) {
aabb.size.y = 0.001;
+ }
configure(aabb);
}
Variant SegmentShape2DSW::get_data() const {
-
Rect2 r;
r.position = a;
r.size = b;
@@ -275,18 +254,15 @@ Variant SegmentShape2DSW::get_data() const {
/*********************************************************/
void CircleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
-
r_amount = 1;
*r_supports = p_normal * radius;
}
bool CircleShape2DSW::contains_point(const Vector2 &p_point) const {
-
return p_point.length_squared() < radius * radius;
}
bool CircleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
-
Vector2 line_vec = p_end - p_begin;
real_t a, b, c;
@@ -297,8 +273,9 @@ bool CircleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p
real_t sqrtterm = b * b - 4 * a * c;
- if (sqrtterm < 0)
+ if (sqrtterm < 0) {
return false;
+ }
sqrtterm = Math::sqrt(sqrtterm);
real_t res = (-b - sqrtterm) / (2 * a);
@@ -312,21 +289,18 @@ bool CircleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p
}
real_t CircleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
-
real_t a = radius * p_scale.x;
real_t b = radius * p_scale.y;
return p_mass * (a * a + b * b) / 4;
}
void CircleShape2DSW::set_data(const Variant &p_data) {
-
ERR_FAIL_COND(!p_data.is_num());
radius = p_data;
configure(Rect2(-radius, -radius, radius * 2, radius * 2));
}
Variant CircleShape2DSW::get_data() const {
-
return radius;
}
@@ -335,14 +309,13 @@ Variant CircleShape2DSW::get_data() const {
/*********************************************************/
void RectangleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
-
for (int i = 0; i < 2; i++) {
-
Vector2 ag;
ag[i] = 1.0;
real_t dp = ag.dot(p_normal);
- if (Math::abs(dp) < _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)
+ if (Math::abs(dp) < _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
continue;
+ }
real_t sgn = dp > 0 ? 1.0 : -1.0;
@@ -374,18 +347,15 @@ bool RectangleShape2DSW::contains_point(const Vector2 &p_point) const {
}
bool RectangleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
-
return get_aabb().intersects_segment(p_begin, p_end, &r_point, &r_normal);
}
real_t RectangleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
-
Vector2 he2 = half_extents * 2 * p_scale;
return p_mass * he2.dot(he2) / 12.0;
}
void RectangleShape2DSW::set_data(const Variant &p_data) {
-
ERR_FAIL_COND(p_data.get_type() != Variant::VECTOR2);
half_extents = p_data;
@@ -393,7 +363,6 @@ void RectangleShape2DSW::set_data(const Variant &p_data) {
}
Variant RectangleShape2DSW::get_data() const {
-
return half_extents;
}
@@ -402,13 +371,11 @@ Variant RectangleShape2DSW::get_data() const {
/*********************************************************/
void CapsuleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
-
Vector2 n = p_normal;
real_t d = n.y;
if (Math::abs(d) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) {
-
// make it flat
n.y = 0.0;
n.normalize();
@@ -421,7 +388,6 @@ void CapsuleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports
r_supports[1].y -= height * 0.5;
} else {
-
real_t h = (d > 0) ? height : -height;
n *= radius;
@@ -432,25 +398,23 @@ void CapsuleShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports
}
bool CapsuleShape2DSW::contains_point(const Vector2 &p_point) const {
-
Vector2 p = p_point;
p.y = Math::abs(p.y);
p.y -= height * 0.5;
- if (p.y < 0)
+ if (p.y < 0) {
p.y = 0;
+ }
return p.length_squared() < radius * radius;
}
bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
-
real_t d = 1e10;
Vector2 n = (p_end - p_begin).normalized();
bool collided = false;
//try spheres
for (int i = 0; i < 2; i++) {
-
Vector2 begin = p_begin;
Vector2 end = p_end;
real_t ofs = (i == 0) ? -height * 0.5 : height * 0.5;
@@ -467,8 +431,9 @@ bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &
real_t sqrtterm = b * b - 4 * a * c;
- if (sqrtterm < 0)
+ if (sqrtterm < 0) {
continue;
+ }
sqrtterm = Math::sqrt(sqrtterm);
real_t res = (-b - sqrtterm) / (2 * a);
@@ -490,7 +455,6 @@ bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &
Vector2 rpos, rnorm;
if (Rect2(Point2(-radius, -height * 0.5), Size2(radius * 2.0, height)).intersects_segment(p_begin, p_end, &rpos, &rnorm)) {
-
real_t pd = n.dot(rpos);
if (pd < d) {
r_point = rpos;
@@ -505,13 +469,11 @@ bool CapsuleShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &
}
real_t CapsuleShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
-
Vector2 he2 = Vector2(radius * 2, height + radius * 2) * p_scale;
return p_mass * he2.dot(he2) / 12.0;
}
void CapsuleShape2DSW::set_data(const Variant &p_data) {
-
ERR_FAIL_COND(p_data.get_type() != Variant::ARRAY && p_data.get_type() != Variant::VECTOR2);
if (p_data.get_type() == Variant::ARRAY) {
@@ -520,7 +482,6 @@ void CapsuleShape2DSW::set_data(const Variant &p_data) {
height = arr[0];
radius = arr[1];
} else {
-
Point2 p = p_data;
radius = p.x;
height = p.y;
@@ -531,7 +492,6 @@ void CapsuleShape2DSW::set_data(const Variant &p_data) {
}
Variant CapsuleShape2DSW::get_data() const {
-
return Point2(height, radius);
}
@@ -540,12 +500,10 @@ Variant CapsuleShape2DSW::get_data() const {
/*********************************************************/
void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
-
int support_idx = -1;
real_t d = -1e10;
for (int i = 0; i < point_count; i++) {
-
//test point
real_t ld = p_normal.dot(points[i].pos);
if (ld > d) {
@@ -555,7 +513,6 @@ void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_su
//test segment
if (points[i].normal.dot(p_normal) > _SEGMENT_IS_VALID_SUPPORT_THRESHOLD) {
-
r_amount = 2;
r_supports[0] = points[i].pos;
r_supports[1] = points[(i + 1) % point_count].pos;
@@ -570,30 +527,27 @@ void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_su
}
bool ConvexPolygonShape2DSW::contains_point(const Vector2 &p_point) const {
-
bool out = false;
bool in = false;
for (int i = 0; i < point_count; i++) {
-
real_t d = points[i].normal.dot(p_point) - points[i].normal.dot(points[i].pos);
- if (d > 0)
+ if (d > 0) {
out = true;
- else
+ } else {
in = true;
+ }
}
return in != out;
}
bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
-
Vector2 n = (p_end - p_begin).normalized();
real_t d = 1e10;
bool inters = false;
for (int i = 0; i < point_count; i++) {
-
//hmm.. no can do..
/*
if (d.dot(points[i].normal)>=0)
@@ -602,12 +556,12 @@ bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vec
Vector2 res;
- if (!Geometry::segment_intersects_segment_2d(p_begin, p_end, points[i].pos, points[(i + 1) % point_count].pos, &res))
+ if (!Geometry::segment_intersects_segment_2d(p_begin, p_end, points[i].pos, points[(i + 1) % point_count].pos, &res)) {
continue;
+ }
real_t nd = n.dot(res);
if (nd < d) {
-
d = nd;
r_point = res;
r_normal = points[i].normal;
@@ -616,9 +570,9 @@ bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vec
}
if (inters) {
-
- if (n.dot(r_normal) > 0)
+ if (n.dot(r_normal) > 0) {
r_normal = -r_normal;
+ }
}
//return get_aabb().intersects_segment(p_begin,p_end,&r_point,&r_normal);
@@ -626,11 +580,9 @@ bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vec
}
real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
-
Rect2 aabb;
aabb.position = points[0].pos * p_scale;
for (int i = 0; i < point_count; i++) {
-
aabb.expand_to(points[i].pos * p_scale);
}
@@ -638,11 +590,11 @@ real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2
}
void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
-
ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT32_ARRAY);
- if (points)
+ if (points) {
memdelete_arr(points);
+ }
points = nullptr;
point_count = 0;
@@ -658,13 +610,11 @@ void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
}
for (int i = 0; i < point_count; i++) {
-
Vector2 p = points[i].pos;
Vector2 pn = points[(i + 1) % point_count].pos;
points[i].normal = (pn - p).tangent().normalized();
}
} else {
-
Vector<real_t> dvr = p_data;
point_count = dvr.size() / 4;
ERR_FAIL_COND(point_count == 0);
@@ -673,7 +623,6 @@ void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
const real_t *r = dvr.ptr();
for (int i = 0; i < point_count; i++) {
-
int idx = i << 2;
points[i].pos.x = r[idx + 0];
points[i].pos.y = r[idx + 1];
@@ -685,14 +634,14 @@ void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
ERR_FAIL_COND(point_count == 0);
Rect2 aabb;
aabb.position = points[0].pos;
- for (int i = 1; i < point_count; i++)
+ for (int i = 1; i < point_count; i++) {
aabb.expand_to(points[i].pos);
+ }
configure(aabb);
}
Variant ConvexPolygonShape2DSW::get_data() const {
-
Vector<Vector2> dvr;
dvr.resize(point_count);
@@ -705,25 +654,22 @@ Variant ConvexPolygonShape2DSW::get_data() const {
}
ConvexPolygonShape2DSW::ConvexPolygonShape2DSW() {
-
points = nullptr;
point_count = 0;
}
ConvexPolygonShape2DSW::~ConvexPolygonShape2DSW() {
-
- if (points)
+ if (points) {
memdelete_arr(points);
+ }
}
//////////////////////////////////////////////////
void ConcavePolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
-
real_t d = -1e10;
int idx = -1;
for (int i = 0; i < points.size(); i++) {
-
real_t ld = p_normal.dot(points[i]);
if (ld > d) {
d = ld;
@@ -737,12 +683,10 @@ void ConcavePolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_s
}
bool ConcavePolygonShape2DSW::contains_point(const Vector2 &p_point) const {
-
return false; //sorry
}
bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
-
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * bvh_depth);
enum {
@@ -773,23 +717,18 @@ bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Ve
stack[0] = 0;
while (true) {
-
uint32_t node = stack[level] & NODE_IDX_MASK;
const BVH &bvh = bvhptr[node];
bool done = false;
switch (stack[level] >> VISITED_BIT_SHIFT) {
case TEST_AABB_BIT: {
-
bool valid = bvh.aabb.intersects_segment(p_begin, p_end);
if (!valid) {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
if (bvh.left < 0) {
-
const Segment &s = segmentptr[bvh.right];
Vector2 a = pointptr[s.points[0]];
Vector2 b = pointptr[s.points[1]];
@@ -797,10 +736,8 @@ bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Ve
Vector2 res;
if (Geometry::segment_intersects_segment_2d(p_begin, p_end, a, b, &res)) {
-
real_t nd = n.dot(res);
if (nd < d) {
-
d = nd;
r_point = res;
r_normal = (b - a).tangent().normalized();
@@ -811,54 +748,50 @@ bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Ve
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
}
}
}
continue;
case VISIT_LEFT_BIT: {
-
stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = bvh.left | TEST_AABB_BIT;
level++;
}
continue;
case VISIT_RIGHT_BIT: {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = bvh.right | TEST_AABB_BIT;
level++;
}
continue;
case VISIT_DONE_BIT: {
-
if (level == 0) {
done = true;
break;
- } else
+ } else {
level--;
+ }
}
continue;
}
- if (done)
+ if (done) {
break;
+ }
}
if (inters) {
-
- if (n.dot(r_normal) > 0)
+ if (n.dot(r_normal) > 0) {
r_normal = -r_normal;
+ }
}
return inters;
}
int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) {
-
if (p_len == 1) {
-
bvh_depth = MAX(p_depth, bvh_depth);
bvh.push_back(*p_bvh);
return bvh.size() - 1;
@@ -872,12 +805,10 @@ int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) {
}
if (global_aabb.size.x > global_aabb.size.y) {
-
SortArray<BVH, BVH_CompareX> sort;
sort.sort(p_bvh, p_len);
} else {
-
SortArray<BVH, BVH_CompareY> sort;
sort.sort(p_bvh, p_len);
}
@@ -898,13 +829,11 @@ int ConcavePolygonShape2DSW::_generate_bvh(BVH *p_bvh, int p_len, int p_depth) {
}
void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
-
ERR_FAIL_COND(p_data.get_type() != Variant::PACKED_VECTOR2_ARRAY && p_data.get_type() != Variant::PACKED_FLOAT32_ARRAY);
Rect2 aabb;
if (p_data.get_type() == Variant::PACKED_VECTOR2_ARRAY) {
-
Vector<Vector2> p2arr = p_data;
int len = p2arr.size();
ERR_FAIL_COND(len % 2);
@@ -923,7 +852,6 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
Map<Point2, int> pointmap;
for (int i = 0; i < len; i += 2) {
-
Point2 p1 = arr[i];
Point2 p2 = arr[i + 1];
int idx_p1, idx_p2;
@@ -951,7 +879,6 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
points.resize(pointmap.size());
aabb.position = pointmap.front()->key();
for (Map<Point2, int>::Element *E = pointmap.front(); E; E = E->next()) {
-
aabb.expand_to(E->key());
points.write[E->get()] = E->key();
}
@@ -959,7 +886,6 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
Vector<BVH> main_vbh;
main_vbh.resize(segments.size());
for (int i = 0; i < main_vbh.size(); i++) {
-
main_vbh.write[i].aabb.position = points[segments[i].points[0]];
main_vbh.write[i].aabb.expand_to(points[segments[i].points[1]]);
main_vbh.write[i].left = -1;
@@ -974,14 +900,13 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
configure(aabb);
}
-Variant ConcavePolygonShape2DSW::get_data() const {
+Variant ConcavePolygonShape2DSW::get_data() const {
Vector<Vector2> rsegments;
int len = segments.size();
rsegments.resize(len * 2);
Vector2 *w = rsegments.ptrw();
for (int i = 0; i < len; i++) {
-
w[(i << 1) + 0] = points[segments[i].points[0]];
w[(i << 1) + 1] = points[segments[i].points[1]];
}
@@ -990,7 +915,6 @@ Variant ConcavePolygonShape2DSW::get_data() const {
}
void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, Callback p_callback, void *p_userdata) const {
-
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * bvh_depth);
enum {
@@ -1021,22 +945,17 @@ void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, Callback p_callbac
stack[0] = 0;
while (true) {
-
uint32_t node = stack[level] & NODE_IDX_MASK;
const BVH &bvh = bvhptr[node];
switch (stack[level] >> VISITED_BIT_SHIFT) {
case TEST_AABB_BIT: {
-
bool valid = p_local_aabb.intersects(bvh.aabb);
if (!valid) {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
if (bvh.left < 0) {
-
const Segment &s = segmentptr[bvh.right];
Vector2 a = pointptr[s.points[0]];
Vector2 b = pointptr[s.points[1]];
@@ -1047,32 +966,29 @@ void ConcavePolygonShape2DSW::cull(const Rect2 &p_local_aabb, Callback p_callbac
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
} else {
-
stack[level] = (VISIT_LEFT_BIT << VISITED_BIT_SHIFT) | node;
}
}
}
continue;
case VISIT_LEFT_BIT: {
-
stack[level] = (VISIT_RIGHT_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = bvh.left | TEST_AABB_BIT;
level++;
}
continue;
case VISIT_RIGHT_BIT: {
-
stack[level] = (VISIT_DONE_BIT << VISITED_BIT_SHIFT) | node;
stack[level + 1] = bvh.right | TEST_AABB_BIT;
level++;
}
continue;
case VISIT_DONE_BIT: {
-
- if (level == 0)
+ if (level == 0) {
return;
- else
+ } else {
level--;
+ }
}
continue;
}
diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h
index ca001e6dd9..eca284f7a4 100644
--- a/servers/physics_2d/shape_2d_sw.h
+++ b/servers/physics_2d/shape_2d_sw.h
@@ -57,7 +57,6 @@ public:
};
class Shape2DSW {
-
RID self;
Rect2 aabb;
bool configured;
@@ -100,13 +99,12 @@ public:
const Map<ShapeOwner2DSW *, int> &get_owners() const;
_FORCE_INLINE_ void get_supports_transformed_cast(const Vector2 &p_cast, const Vector2 &p_normal, const Transform2D &p_xform, Vector2 *r_supports, int &r_amount) const {
-
get_supports(p_xform.basis_xform_inv(p_normal).normalized(), r_supports, r_amount);
- for (int i = 0; i < r_amount; i++)
+ for (int i = 0; i < r_amount; i++) {
r_supports[i] = p_xform.xform(r_supports[i]);
+ }
if (r_amount == 1) {
-
if (Math::abs(p_normal.dot(p_cast.normalized())) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) {
//make line because they are parallel
r_amount = 2;
@@ -117,7 +115,6 @@ public:
}
} else {
-
if (Math::abs(p_normal.dot(p_cast.normalized())) < (1.0 - _SEGMENT_IS_VALID_SUPPORT_THRESHOLD)) {
//optimize line and make it larger because they are parallel
if ((r_supports[1] - r_supports[0]).dot(p_cast) > 0) {
@@ -145,7 +142,6 @@ public:
project_range_cast(p_cast, p_normal, p_transform, r_min, r_max); \
} \
_FORCE_INLINE_ void project_range_cast(const Vector2 &p_cast, const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const { \
- \
real_t mina, maxa; \
real_t minb, maxb; \
Transform2D ofsb = p_transform; \
@@ -157,7 +153,6 @@ public:
}
class LineShape2DSW : public Shape2DSW {
-
Vector2 normal;
real_t d;
@@ -195,7 +190,6 @@ public:
};
class RayShape2DSW : public Shape2DSW {
-
real_t length;
bool slips_on_slope;
@@ -220,7 +214,6 @@ public:
r_max = p_normal.dot(p_transform.get_origin());
r_min = p_normal.dot(p_transform.xform(Vector2(0, length)));
if (r_max < r_min) {
-
SWAP(r_max, r_min);
}
}
@@ -232,7 +225,6 @@ public:
};
class SegmentShape2DSW : public Shape2DSW {
-
Vector2 a;
Vector2 b;
Vector2 n;
@@ -245,7 +237,6 @@ public:
virtual PhysicsServer2D::ShapeType get_type() const { return PhysicsServer2D::SHAPE_SEGMENT; }
_FORCE_INLINE_ Vector2 get_xformed_normal(const Transform2D &p_xform) const {
-
return (p_xform.xform(b) - p_xform.xform(a)).normalized().tangent();
}
virtual void project_rangev(const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const { project_range(p_normal, p_transform, r_min, r_max); }
@@ -263,7 +254,6 @@ public:
r_max = p_normal.dot(p_transform.xform(a));
r_min = p_normal.dot(p_transform.xform(b));
if (r_max < r_min) {
-
SWAP(r_max, r_min);
}
}
@@ -279,7 +269,6 @@ public:
};
class CircleShape2DSW : public Shape2DSW {
-
real_t radius;
public:
@@ -313,7 +302,6 @@ public:
};
class RectangleShape2DSW : public Shape2DSW {
-
Vector2 half_extents;
public:
@@ -336,18 +324,18 @@ public:
r_max = -1e20;
r_min = 1e20;
for (int i = 0; i < 4; i++) {
-
real_t d = p_normal.dot(p_transform.xform(Vector2(((i & 1) * 2 - 1) * half_extents.x, ((i >> 1) * 2 - 1) * half_extents.y)));
- if (d > r_max)
+ if (d > r_max) {
r_max = d;
- if (d < r_min)
+ }
+ if (d < r_min) {
r_min = d;
+ }
}
}
_FORCE_INLINE_ Vector2 get_circle_axis(const Transform2D &p_xform, const Transform2D &p_xform_inv, const Vector2 &p_circle) const {
-
Vector2 local_v = p_xform_inv.xform(p_circle);
Vector2 he(
@@ -358,7 +346,6 @@ public:
}
_FORCE_INLINE_ Vector2 get_box_axis(const Transform2D &p_xform, const Transform2D &p_xform_inv, const RectangleShape2DSW *p_B, const Transform2D &p_B_xform, const Transform2D &p_B_xform_inv) const {
-
Vector2 a, b;
{
@@ -387,7 +374,6 @@ public:
};
class CapsuleShape2DSW : public Shape2DSW {
-
real_t radius;
real_t height;
@@ -419,7 +405,6 @@ public:
r_min = p_normal.dot(p_transform.xform(-n));
if (r_max < r_min) {
-
SWAP(r_max, r_min);
}
@@ -430,9 +415,7 @@ public:
};
class ConvexPolygonShape2DSW : public Shape2DSW {
-
struct Point {
-
Vector2 pos;
Vector2 normal; //normal to next segment
};
@@ -445,7 +428,6 @@ public:
_FORCE_INLINE_ const Vector2 &get_point(int p_idx) const { return points[p_idx].pos; }
_FORCE_INLINE_ const Vector2 &get_segment_normal(int p_idx) const { return points[p_idx].normal; }
_FORCE_INLINE_ Vector2 get_xformed_segment_normal(const Transform2D &p_xform, int p_idx) const {
-
Vector2 a = points[p_idx].pos;
p_idx++;
Vector2 b = points[p_idx == point_count ? 0 : p_idx].pos;
@@ -465,7 +447,6 @@ public:
virtual Variant get_data() const;
_FORCE_INLINE_ void project_range(const Vector2 &p_normal, const Transform2D &p_transform, real_t &r_min, real_t &r_max) const {
-
if (!points || point_count <= 0) {
r_min = r_max = 0;
return;
@@ -473,12 +454,13 @@ public:
r_min = r_max = p_normal.dot(p_transform.xform(points[0].pos));
for (int i = 1; i < point_count; i++) {
-
real_t d = p_normal.dot(p_transform.xform(points[i].pos));
- if (d > r_max)
+ if (d > r_max) {
r_max = d;
- if (d < r_min)
+ }
+ if (d < r_min) {
r_min = d;
+ }
}
}
@@ -489,7 +471,6 @@ public:
};
class ConcaveShape2DSW : public Shape2DSW {
-
public:
virtual bool is_concave() const { return true; }
typedef void (*Callback)(void *p_userdata, Shape2DSW *p_convex);
@@ -498,9 +479,7 @@ public:
};
class ConcavePolygonShape2DSW : public ConcaveShape2DSW {
-
struct Segment {
-
int points[2];
};
@@ -508,7 +487,6 @@ class ConcavePolygonShape2DSW : public ConcaveShape2DSW {
Vector<Point2> points;
struct BVH {
-
Rect2 aabb;
int left, right;
};
@@ -517,17 +495,13 @@ class ConcavePolygonShape2DSW : public ConcaveShape2DSW {
int bvh_depth;
struct BVH_CompareX {
-
_FORCE_INLINE_ bool operator()(const BVH &a, const BVH &b) const {
-
return (a.aabb.position.x + a.aabb.size.x * 0.5) < (b.aabb.position.x + b.aabb.size.x * 0.5);
}
};
struct BVH_CompareY {
-
_FORCE_INLINE_ bool operator()(const BVH &a, const BVH &b) const {
-
return (a.aabb.position.y + a.aabb.size.y * 0.5) < (b.aabb.position.y + b.aabb.size.y * 0.5);
}
};
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index 7ae2e9769f..f4a21da254 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -35,24 +35,25 @@
#include "core/pair.h"
#include "physics_server_2d_sw.h"
_FORCE_INLINE_ static bool _can_collide_with(CollisionObject2DSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
if (!(p_object->get_collision_layer() & p_collision_mask)) {
return false;
}
- if (p_object->get_type() == CollisionObject2DSW::TYPE_AREA && !p_collide_with_areas)
+ if (p_object->get_type() == CollisionObject2DSW::TYPE_AREA && !p_collide_with_areas) {
return false;
+ }
- if (p_object->get_type() == CollisionObject2DSW::TYPE_BODY && !p_collide_with_bodies)
+ if (p_object->get_type() == CollisionObject2DSW::TYPE_BODY && !p_collide_with_bodies) {
return false;
+ }
return true;
}
int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point, bool p_filter_by_canvas, ObjectID p_canvas_instance_id) {
-
- if (p_result_max <= 0)
+ if (p_result_max <= 0) {
return 0;
+ }
Rect2 aabb;
aabb.position = p_point - Vector2(0.00001, 0.00001);
@@ -63,20 +64,23 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S
int cc = 0;
for (int i = 0; i < amount; i++) {
-
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
- if (p_exclude.has(space->intersection_query_results[i]->get_self()))
+ if (p_exclude.has(space->intersection_query_results[i]->get_self())) {
continue;
+ }
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
- if (p_pick_point && !col_obj->is_pickable())
+ if (p_pick_point && !col_obj->is_pickable()) {
continue;
+ }
- if (p_filter_by_canvas && col_obj->get_canvas_instance_id() != p_canvas_instance_id)
+ if (p_filter_by_canvas && col_obj->get_canvas_instance_id() != p_canvas_instance_id) {
continue;
+ }
int shape_idx = space->intersection_query_subindex_results[i];
@@ -84,15 +88,18 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S
Vector2 local_point = (col_obj->get_transform() * col_obj->get_shape_transform(shape_idx)).affine_inverse().xform(p_point);
- if (!shape->contains_point(local_point))
+ if (!shape->contains_point(local_point)) {
continue;
+ }
- if (cc >= p_result_max)
+ if (cc >= p_result_max) {
continue;
+ }
r_results[cc].collider_id = col_obj->get_instance_id();
- if (r_results[cc].collider_id.is_valid())
+ if (r_results[cc].collider_id.is_valid()) {
r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id);
+ }
r_results[cc].rid = col_obj->get_self();
r_results[cc].shape = shape_idx;
r_results[cc].metadata = col_obj->get_shape_metadata(shape_idx);
@@ -104,17 +111,14 @@ int PhysicsDirectSpaceState2DSW::_intersect_point_impl(const Vector2 &p_point, S
}
int PhysicsDirectSpaceState2DSW::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) {
-
return _intersect_point_impl(p_point, r_results, p_result_max, p_exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas, p_pick_point);
}
int PhysicsDirectSpaceState2DSW::intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_instance_id, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point) {
-
return _intersect_point_impl(p_point, r_results, p_result_max, p_exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas, p_pick_point, true, p_canvas_instance_id);
}
bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
ERR_FAIL_COND_V(space->locked, false);
Vector2 begin, end;
@@ -134,12 +138,13 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec
real_t min_d = 1e10;
for (int i = 0; i < amount; i++) {
-
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
- if (p_exclude.has(space->intersection_query_results[i]->get_self()))
+ if (p_exclude.has(space->intersection_query_results[i]->get_self())) {
continue;
+ }
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
@@ -160,14 +165,12 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec
Vector2 shape_point, shape_normal;
if (shape->intersect_segment(local_from, local_to, shape_point, shape_normal)) {
-
Transform2D xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
shape_point = xform.xform(shape_point);
real_t ld = normal.dot(shape_point);
if (ld < min_d) {
-
min_d = ld;
res_point = shape_point;
res_normal = inv_xform.basis_xform_inv(shape_normal).normalized();
@@ -178,12 +181,14 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec
}
}
- if (!collided)
+ if (!collided) {
return false;
+ }
r_result.collider_id = res_obj->get_instance_id();
- if (r_result.collider_id.is_valid())
+ if (r_result.collider_id.is_valid()) {
r_result.collider = ObjectDB::get_instance(r_result.collider_id);
+ }
r_result.normal = res_normal;
r_result.metadata = res_obj->get_shape_metadata(res_shape);
r_result.position = res_point;
@@ -194,9 +199,9 @@ bool PhysicsDirectSpaceState2DSW::intersect_ray(const Vector2 &p_from, const Vec
}
int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
- if (p_result_max <= 0)
+ if (p_result_max <= 0) {
return 0;
+ }
Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0);
@@ -209,25 +214,29 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans
int cc = 0;
for (int i = 0; i < amount; i++) {
-
- if (cc >= p_result_max)
+ if (cc >= p_result_max) {
break;
+ }
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
- if (p_exclude.has(space->intersection_query_results[i]->get_self()))
+ if (p_exclude.has(space->intersection_query_results[i]->get_self())) {
continue;
+ }
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
- if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_margin))
+ if (!CollisionSolver2DSW::solve(shape, p_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), nullptr, nullptr, nullptr, p_margin)) {
continue;
+ }
r_results[cc].collider_id = col_obj->get_instance_id();
- if (r_results[cc].collider_id.is_valid())
+ if (r_results[cc].collider_id.is_valid()) {
r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id);
+ }
r_results[cc].rid = col_obj->get_self();
r_results[cc].shape = shape_idx;
r_results[cc].metadata = col_obj->get_shape_metadata(shape_idx);
@@ -239,7 +248,6 @@ int PhysicsDirectSpaceState2DSW::intersect_shape(const RID &p_shape, const Trans
}
bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, false);
@@ -253,12 +261,13 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor
real_t best_unsafe = 1;
for (int i = 0; i < amount; i++) {
-
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
- if (p_exclude.has(space->intersection_query_results[i]->get_self()))
+ if (p_exclude.has(space->intersection_query_results[i]->get_self())) {
continue; //ignore excluded
+ }
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
@@ -271,7 +280,6 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor
//test initial overlap
if (CollisionSolver2DSW::solve(shape, p_xform, Vector2(), col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, nullptr, p_margin)) {
-
return false;
}
@@ -288,10 +296,8 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor
bool collided = CollisionSolver2DSW::solve(shape, p_xform, p_motion * ofs, col_obj->get_shape(shape_idx), col_obj_xform, Vector2(), nullptr, nullptr, &sep, p_margin);
if (collided) {
-
hi = ofs;
} else {
-
low = ofs;
}
}
@@ -309,9 +315,9 @@ bool PhysicsDirectSpaceState2DSW::cast_motion(const RID &p_shape, const Transfor
}
bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
- if (p_result_max <= 0)
- return 0;
+ if (p_result_max <= 0) {
+ return false;
+ }
Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0);
@@ -335,15 +341,16 @@ bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D &
PhysicsServer2DSW::CollCbkData *cbkptr = &cbk;
for (int i = 0; i < amount; i++) {
-
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
- if (p_exclude.has(col_obj->get_self()))
+ if (p_exclude.has(col_obj->get_self())) {
continue;
+ }
cbk.valid_dir = Vector2();
cbk.valid_depth = 0;
@@ -359,7 +366,6 @@ bool PhysicsDirectSpaceState2DSW::collide_shape(RID p_shape, const Transform2D &
}
struct _RestCallbackData2D {
-
const CollisionObject2DSW *object;
const CollisionObject2DSW *best_object;
int local_shape;
@@ -375,24 +381,27 @@ struct _RestCallbackData2D {
};
static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B, void *p_userdata) {
-
_RestCallbackData2D *rd = (_RestCallbackData2D *)p_userdata;
if (rd->valid_dir != Vector2()) {
- if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth)
+ if (p_point_A.distance_squared_to(p_point_B) > rd->valid_depth * rd->valid_depth) {
return;
- if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25)
+ }
+ if (rd->valid_dir.dot((p_point_A - p_point_B).normalized()) < Math_PI * 0.25) {
return;
+ }
}
Vector2 contact_rel = p_point_B - p_point_A;
real_t len = contact_rel.length();
- if (len < rd->min_allowed_depth)
+ if (len < rd->min_allowed_depth) {
return;
+ }
- if (len <= rd->best_len)
+ if (len <= rd->best_len) {
return;
+ }
rd->best_len = len;
rd->best_contact = p_point_B;
@@ -403,7 +412,6 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B,
}
bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
Shape2DSW *shape = PhysicsServer2DSW::singletonsw->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0);
@@ -420,15 +428,16 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh
rcd.min_allowed_depth = space->test_motion_min_contact_depth;
for (int i = 0; i < amount; i++) {
-
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
- if (p_exclude.has(col_obj->get_self()))
+ if (p_exclude.has(col_obj->get_self())) {
continue;
+ }
rcd.valid_dir = Vector2();
rcd.valid_depth = 0;
@@ -436,12 +445,14 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh
rcd.shape = shape_idx;
rcd.local_shape = 0;
bool sc = CollisionSolver2DSW::solve(shape, p_shape_xform, p_motion, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), Vector2(), _rest_cbk_result, &rcd, nullptr, p_margin);
- if (!sc)
+ if (!sc) {
continue;
+ }
}
- if (rcd.best_len == 0 || !rcd.best_object)
+ if (rcd.best_len == 0 || !rcd.best_object) {
return false;
+ }
r_info->collider_id = rcd.best_object->get_instance_id();
r_info->shape = rcd.best_shape;
@@ -450,7 +461,6 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh
r_info->rid = rcd.best_object->get_self();
r_info->metadata = rcd.best_object->get_shape_metadata(rcd.best_shape);
if (rcd.best_object->get_type() == CollisionObject2DSW::TYPE_BODY) {
-
const Body2DSW *body = static_cast<const Body2DSW *>(rcd.best_object);
Vector2 rel_vec = r_info->point - body->get_transform().get_origin();
r_info->linear_velocity = Vector2(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity();
@@ -463,33 +473,30 @@ bool PhysicsDirectSpaceState2DSW::rest_info(RID p_shape, const Transform2D &p_sh
}
PhysicsDirectSpaceState2DSW::PhysicsDirectSpaceState2DSW() {
-
space = nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) {
-
int amount = broadphase->cull_aabb(p_aabb, intersection_query_results, INTERSECTION_QUERY_MAX, intersection_query_subindex_results);
for (int i = 0; i < amount; i++) {
-
bool keep = true;
- if (intersection_query_results[i] == p_body)
+ if (intersection_query_results[i] == p_body) {
keep = false;
- else if (intersection_query_results[i]->get_type() == CollisionObject2DSW::TYPE_AREA)
+ } else if (intersection_query_results[i]->get_type() == CollisionObject2DSW::TYPE_AREA) {
keep = false;
- else if ((static_cast<Body2DSW *>(intersection_query_results[i])->test_collision_mask(p_body)) == 0)
+ } else if ((static_cast<Body2DSW *>(intersection_query_results[i])->test_collision_mask(p_body)) == 0) {
keep = false;
- else if (static_cast<Body2DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self()))
+ } else if (static_cast<Body2DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) {
keep = false;
- else if (static_cast<Body2DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i]))
+ } else if (static_cast<Body2DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i])) {
keep = false;
+ }
if (!keep) {
-
if (i < amount - 1) {
SWAP(intersection_query_results[i], intersection_query_results[amount - 1]);
SWAP(intersection_query_subindex_results[i], intersection_query_subindex_results[amount - 1]);
@@ -504,18 +511,18 @@ int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body, const Rect2 &p_aabb) {
}
int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_transform, bool p_infinite_inertia, Vector2 &r_recover_motion, PhysicsServer2D::SeparationResult *r_results, int p_result_max, real_t p_margin) {
-
Rect2 body_aabb;
bool shapes_found = false;
for (int i = 0; i < p_body->get_shape_count(); i++) {
-
- if (p_body->is_shape_set_as_disabled(i))
+ if (p_body->is_shape_set_as_disabled(i)) {
continue;
+ }
- if (p_body->get_shape(i)->get_type() != PhysicsServer2D::SHAPE_RAY)
+ if (p_body->get_shape(i)->get_type() != PhysicsServer2D::SHAPE_RAY) {
continue;
+ }
if (!shapes_found) {
body_aabb = p_body->get_shape_aabb(i);
@@ -554,7 +561,6 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
CollisionSolver2DSW::CallbackResult cbkres = PhysicsServer2DSW::_shape_col_cbk;
do {
-
Vector2 recover_motion;
bool collided = false;
@@ -562,18 +568,19 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_disabled(j))
+ if (p_body->is_shape_set_as_disabled(j)) {
continue;
+ }
Shape2DSW *body_shape = p_body->get_shape(j);
- if (body_shape->get_type() != PhysicsServer2D::SHAPE_RAY)
+ if (body_shape->get_type() != PhysicsServer2D::SHAPE_RAY) {
continue;
+ }
Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
for (int i = 0; i < amount; i++) {
-
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
@@ -631,7 +638,6 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
}
if (ray_index != -1) {
-
PhysicsServer2D::SeparationResult &result = r_results[ray_index];
for (int k = 0; k < cbk.amount; k++) {
@@ -642,7 +648,6 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
float depth = a.distance_to(b);
if (depth > result.collision_depth) {
-
result.collision_depth = depth;
result.collision_point = b;
result.collision_normal = (b - a).normalized();
@@ -688,7 +693,6 @@ int Space2DSW::test_body_ray_separation(Body2DSW *p_body, const Transform2D &p_t
}
bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer2D::MotionResult *r_result, bool p_exclude_raycast_shapes) {
-
//give me back regular physics engine logic
//this is madness
//and most people using this function will think
@@ -705,12 +709,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
bool shapes_found = false;
for (int i = 0; i < p_body->get_shape_count(); i++) {
-
- if (p_body->is_shape_set_as_disabled(i))
+ if (p_body->is_shape_set_as_disabled(i)) {
continue;
+ }
- if (p_exclude_raycast_shapes && p_body->get_shape(i)->get_type() == PhysicsServer2D::SHAPE_RAY)
+ if (p_exclude_raycast_shapes && p_body->get_shape(i)->get_type() == PhysicsServer2D::SHAPE_RAY) {
continue;
+ }
if (!shapes_found) {
body_aabb = p_body->get_shape_aabb(i);
@@ -748,7 +753,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
Vector2 sr[max_results * 2];
do {
-
PhysicsServer2DSW::CollCbkData cbk;
cbk.max = max_results;
cbk.amount = 0;
@@ -765,8 +769,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_disabled(j))
+ if (p_body->is_shape_set_as_disabled(j)) {
continue;
+ }
Shape2DSW *body_shape = p_body->get_shape(j);
if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer2D::SHAPE_RAY) {
@@ -775,7 +780,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
Transform2D body_shape_xform = body_transform * p_body->get_shape_transform(j);
for (int i = 0; i < amount; i++) {
-
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
@@ -789,7 +793,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
-
cbk.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
float owc_margin = col_obj->get_shape_one_way_collision_margin(shape_idx);
@@ -846,7 +849,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
Vector2 recover_motion;
for (int i = 0; i < cbk.amount; i++) {
-
Vector2 a = sr[i * 2 + 0];
Vector2 b = sr[i * 2 + 1];
recover_motion += (b - a) * 0.4;
@@ -879,9 +881,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
int amount = _cull_aabb_for_body(p_body, motion_aabb);
for (int body_shape_idx = 0; body_shape_idx < p_body->get_shape_count(); body_shape_idx++) {
-
- if (p_body->is_shape_set_as_disabled(body_shape_idx))
+ if (p_body->is_shape_set_as_disabled(body_shape_idx)) {
continue;
+ }
Shape2DSW *body_shape = p_body->get_shape(body_shape_idx);
if (p_exclude_raycast_shapes && body_shape->get_type() == PhysicsServer2D::SHAPE_RAY) {
@@ -896,7 +898,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
real_t best_unsafe = 1;
for (int i = 0; i < amount; i++) {
-
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int col_shape_idx = intersection_query_subindex_results[i];
Shape2DSW *against_shape = col_obj->get_shape(col_shape_idx);
@@ -911,7 +912,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
bool excluded = false;
for (int k = 0; k < excluded_shape_pair_count; k++) {
-
if (excluded_shape_pairs[k].local_shape == body_shape && excluded_shape_pairs[k].against_object == col_obj && excluded_shape_pairs[k].against_shape_index == col_shape_idx) {
excluded = true;
break;
@@ -919,7 +919,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
if (excluded) {
-
continue;
}
@@ -931,7 +930,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
//test initial overlap
if (CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, nullptr, 0)) {
-
if (col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) {
continue;
}
@@ -953,16 +951,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
bool collided = CollisionSolver2DSW::solve(body_shape, body_shape_xform, p_motion * ofs, against_shape, col_obj_shape_xform, Vector2(), nullptr, nullptr, &sep, 0);
if (collided) {
-
hi = ofs;
} else {
-
low = ofs;
}
}
if (col_obj->is_shape_set_as_one_way_collision(col_shape_idx)) {
-
Vector2 cd[2];
PhysicsServer2DSW::CollCbkData cbk;
cbk.max = 1;
@@ -987,7 +982,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
if (stuck) {
-
safe = 0;
unsafe = 0;
best_shape = body_shape_idx; //sadly it's the best
@@ -997,7 +991,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
continue;
}
if (best_safe < safe) {
-
safe = best_safe;
unsafe = best_unsafe;
best_shape = body_shape_idx;
@@ -1011,7 +1004,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
{
-
//it collided, let's get the rest info in unsafe advance
Transform2D ugt = body_transform;
ugt.elements[2] += p_motion * unsafe;
@@ -1027,9 +1019,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
int to_shape = best_shape != -1 ? best_shape + 1 : p_body->get_shape_count();
for (int j = from_shape; j < to_shape; j++) {
-
- if (p_body->is_shape_set_as_disabled(j))
+ if (p_body->is_shape_set_as_disabled(j)) {
continue;
+ }
Transform2D body_shape_xform = ugt * p_body->get_shape_transform(j);
Shape2DSW *body_shape = p_body->get_shape(j);
@@ -1043,7 +1035,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int i = 0; i < amount; i++) {
-
const CollisionObject2DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
@@ -1058,19 +1049,18 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
bool excluded = false;
for (int k = 0; k < excluded_shape_pair_count; k++) {
-
if (excluded_shape_pairs[k].local_shape == body_shape && excluded_shape_pairs[k].against_object == col_obj && excluded_shape_pairs[k].against_shape_index == shape_idx) {
excluded = true;
break;
}
}
- if (excluded)
+ if (excluded) {
continue;
+ }
Transform2D col_obj_shape_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
if (col_obj->is_shape_set_as_one_way_collision(shape_idx)) {
-
rcd.valid_dir = col_obj_shape_xform.get_axis(1).normalized();
rcd.valid_depth = 10e20;
} else {
@@ -1082,13 +1072,13 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
rcd.shape = shape_idx;
rcd.local_shape = j;
bool sc = CollisionSolver2DSW::solve(body_shape, body_shape_xform, Vector2(), against_shape, col_obj_shape_xform, Vector2(), _rest_cbk_result, &rcd, nullptr, p_margin);
- if (!sc)
+ if (!sc) {
continue;
+ }
}
}
if (rcd.best_len != 0) {
-
if (r_result) {
r_result->collider = rcd.best_object->get_self();
r_result->collider_id = rcd.best_object->get_instance_id();
@@ -1112,7 +1102,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
if (!collided && r_result) {
-
r_result->motion = p_motion;
r_result->remainder = Vector2();
r_result->motion += (body_transform.get_origin() - p_from.get_origin());
@@ -1122,11 +1111,9 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
void *Space2DSW::_broadphase_pair(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_self) {
-
CollisionObject2DSW::Type type_A = A->get_type();
CollisionObject2DSW::Type type_B = B->get_type();
if (type_A > type_B) {
-
SWAP(A, B);
SWAP(p_subindex_A, p_subindex_B);
SWAP(type_A, type_B);
@@ -1136,22 +1123,18 @@ void *Space2DSW::_broadphase_pair(CollisionObject2DSW *A, int p_subindex_A, Coll
self->collision_pairs++;
if (type_A == CollisionObject2DSW::TYPE_AREA) {
-
Area2DSW *area = static_cast<Area2DSW *>(A);
if (type_B == CollisionObject2DSW::TYPE_AREA) {
-
Area2DSW *area_b = static_cast<Area2DSW *>(B);
Area2Pair2DSW *area2_pair = memnew(Area2Pair2DSW(area_b, p_subindex_B, area, p_subindex_A));
return area2_pair;
} else {
-
Body2DSW *body = static_cast<Body2DSW *>(B);
AreaPair2DSW *area_pair = memnew(AreaPair2DSW(body, p_subindex_B, area, p_subindex_A));
return area_pair;
}
} else {
-
BodyPair2DSW *b = memnew(BodyPair2DSW((Body2DSW *)A, p_subindex_A, (Body2DSW *)B, p_subindex_B));
return b;
}
@@ -1160,7 +1143,6 @@ void *Space2DSW::_broadphase_pair(CollisionObject2DSW *A, int p_subindex_A, Coll
}
void Space2DSW::_broadphase_unpair(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_data, void *p_self) {
-
Space2DSW *self = (Space2DSW *)p_self;
self->collision_pairs--;
Constraint2DSW *c = (Constraint2DSW *)p_data;
@@ -1168,94 +1150,79 @@ void Space2DSW::_broadphase_unpair(CollisionObject2DSW *A, int p_subindex_A, Col
}
const SelfList<Body2DSW>::List &Space2DSW::get_active_body_list() const {
-
return active_list;
}
-void Space2DSW::body_add_to_active_list(SelfList<Body2DSW> *p_body) {
+void Space2DSW::body_add_to_active_list(SelfList<Body2DSW> *p_body) {
active_list.add(p_body);
}
-void Space2DSW::body_remove_from_active_list(SelfList<Body2DSW> *p_body) {
+void Space2DSW::body_remove_from_active_list(SelfList<Body2DSW> *p_body) {
active_list.remove(p_body);
}
void Space2DSW::body_add_to_inertia_update_list(SelfList<Body2DSW> *p_body) {
-
inertia_update_list.add(p_body);
}
void Space2DSW::body_remove_from_inertia_update_list(SelfList<Body2DSW> *p_body) {
-
inertia_update_list.remove(p_body);
}
BroadPhase2DSW *Space2DSW::get_broadphase() {
-
return broadphase;
}
void Space2DSW::add_object(CollisionObject2DSW *p_object) {
-
ERR_FAIL_COND(objects.has(p_object));
objects.insert(p_object);
}
void Space2DSW::remove_object(CollisionObject2DSW *p_object) {
-
ERR_FAIL_COND(!objects.has(p_object));
objects.erase(p_object);
}
const Set<CollisionObject2DSW *> &Space2DSW::get_objects() const {
-
return objects;
}
void Space2DSW::body_add_to_state_query_list(SelfList<Body2DSW> *p_body) {
-
state_query_list.add(p_body);
}
-void Space2DSW::body_remove_from_state_query_list(SelfList<Body2DSW> *p_body) {
+void Space2DSW::body_remove_from_state_query_list(SelfList<Body2DSW> *p_body) {
state_query_list.remove(p_body);
}
void Space2DSW::area_add_to_monitor_query_list(SelfList<Area2DSW> *p_area) {
-
monitor_query_list.add(p_area);
}
-void Space2DSW::area_remove_from_monitor_query_list(SelfList<Area2DSW> *p_area) {
+void Space2DSW::area_remove_from_monitor_query_list(SelfList<Area2DSW> *p_area) {
monitor_query_list.remove(p_area);
}
void Space2DSW::area_add_to_moved_list(SelfList<Area2DSW> *p_area) {
-
area_moved_list.add(p_area);
}
void Space2DSW::area_remove_from_moved_list(SelfList<Area2DSW> *p_area) {
-
area_moved_list.remove(p_area);
}
const SelfList<Area2DSW>::List &Space2DSW::get_moved_area_list() const {
-
return area_moved_list;
}
void Space2DSW::call_queries() {
-
while (state_query_list.first()) {
-
Body2DSW *b = state_query_list.first()->self();
state_query_list.remove(state_query_list.first());
b->call_queries();
}
while (monitor_query_list.first()) {
-
Area2DSW *a = monitor_query_list.first()->self();
monitor_query_list.remove(monitor_query_list.first());
a->call_queries();
@@ -1263,7 +1230,6 @@ void Space2DSW::call_queries() {
}
void Space2DSW::setup() {
-
contact_debug_count = 0;
while (inertia_update_list.first()) {
@@ -1273,63 +1239,77 @@ void Space2DSW::setup() {
}
void Space2DSW::update() {
-
broadphase->update();
}
void Space2DSW::set_param(PhysicsServer2D::SpaceParameter p_param, real_t p_value) {
-
switch (p_param) {
-
- case PhysicsServer2D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: contact_recycle_radius = p_value; break;
- case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION: contact_max_separation = p_value; break;
- case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: contact_max_allowed_penetration = p_value; break;
- case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: body_linear_velocity_sleep_threshold = p_value; break;
- case PhysicsServer2D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: body_angular_velocity_sleep_threshold = p_value; break;
- case PhysicsServer2D::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep = p_value; break;
- case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias = p_value; break;
- case PhysicsServer2D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: test_motion_min_contact_depth = p_value; break;
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS:
+ contact_recycle_radius = p_value;
+ break;
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
+ contact_max_separation = p_value;
+ break;
+ case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ contact_max_allowed_penetration = p_value;
+ break;
+ case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
+ body_linear_velocity_sleep_threshold = p_value;
+ break;
+ case PhysicsServer2D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
+ body_angular_velocity_sleep_threshold = p_value;
+ break;
+ case PhysicsServer2D::SPACE_PARAM_BODY_TIME_TO_SLEEP:
+ body_time_to_sleep = p_value;
+ break;
+ case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
+ constraint_bias = p_value;
+ break;
+ case PhysicsServer2D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH:
+ test_motion_min_contact_depth = p_value;
+ break;
}
}
real_t Space2DSW::get_param(PhysicsServer2D::SpaceParameter p_param) const {
-
switch (p_param) {
-
- case PhysicsServer2D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: return contact_recycle_radius;
- case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION: return contact_max_separation;
- case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: return contact_max_allowed_penetration;
- case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: return body_linear_velocity_sleep_threshold;
- case PhysicsServer2D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: return body_angular_velocity_sleep_threshold;
- case PhysicsServer2D::SPACE_PARAM_BODY_TIME_TO_SLEEP: return body_time_to_sleep;
- case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: return constraint_bias;
- case PhysicsServer2D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: return test_motion_min_contact_depth;
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS:
+ return contact_recycle_radius;
+ case PhysicsServer2D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
+ return contact_max_separation;
+ case PhysicsServer2D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ return contact_max_allowed_penetration;
+ case PhysicsServer2D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
+ return body_linear_velocity_sleep_threshold;
+ case PhysicsServer2D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
+ return body_angular_velocity_sleep_threshold;
+ case PhysicsServer2D::SPACE_PARAM_BODY_TIME_TO_SLEEP:
+ return body_time_to_sleep;
+ case PhysicsServer2D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
+ return constraint_bias;
+ case PhysicsServer2D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH:
+ return test_motion_min_contact_depth;
}
return 0;
}
void Space2DSW::lock() {
-
locked = true;
}
void Space2DSW::unlock() {
-
locked = false;
}
bool Space2DSW::is_locked() const {
-
return locked;
}
PhysicsDirectSpaceState2DSW *Space2DSW::get_direct_state() {
-
return direct_access;
}
Space2DSW::Space2DSW() {
-
collision_pairs = 0;
active_objects = 0;
island_count = 0;
@@ -1356,12 +1336,12 @@ Space2DSW::Space2DSW() {
direct_access = memnew(PhysicsDirectSpaceState2DSW);
direct_access->space = this;
- for (int i = 0; i < ELAPSED_TIME_MAX; i++)
+ for (int i = 0; i < ELAPSED_TIME_MAX; i++) {
elapsed_time[i] = 0;
+ }
}
Space2DSW::~Space2DSW() {
-
memdelete(broadphase);
memdelete(direct_access);
}
diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h
index c6b324c928..0a96f2f495 100644
--- a/servers/physics_2d/space_2d_sw.h
+++ b/servers/physics_2d/space_2d_sw.h
@@ -42,7 +42,6 @@
#include "core/typedefs.h"
class PhysicsDirectSpaceState2DSW : public PhysicsDirectSpaceState2D {
-
GDCLASS(PhysicsDirectSpaceState2DSW, PhysicsDirectSpaceState2D);
int _intersect_point_impl(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_point, bool p_filter_by_canvas = false, ObjectID p_canvas_instance_id = ObjectID());
@@ -62,7 +61,6 @@ public:
};
class Space2DSW {
-
public:
enum ElapsedTime {
ELAPSED_TIME_INTEGRATE_FORCES,
@@ -192,7 +190,9 @@ public:
void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); }
_FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); }
_FORCE_INLINE_ void add_debug_contact(const Vector2 &p_contact) {
- if (contact_debug_count < contact_debug.size()) contact_debug.write[contact_debug_count++] = p_contact;
+ if (contact_debug_count < contact_debug.size()) {
+ contact_debug.write[contact_debug_count++] = p_contact;
+ }
}
_FORCE_INLINE_ Vector<Vector2> get_debug_contacts() { return contact_debug; }
_FORCE_INLINE_ int get_debug_contact_count() { return contact_debug_count; }
diff --git a/servers/physics_2d/step_2d_sw.cpp b/servers/physics_2d/step_2d_sw.cpp
index 6f3bcfec13..c7711bcd1d 100644
--- a/servers/physics_2d/step_2d_sw.cpp
+++ b/servers/physics_2d/step_2d_sw.cpp
@@ -32,33 +32,33 @@
#include "core/os/os.h"
void Step2DSW::_populate_island(Body2DSW *p_body, Body2DSW **p_island, Constraint2DSW **p_constraint_island) {
-
p_body->set_island_step(_step);
p_body->set_island_next(*p_island);
*p_island = p_body;
for (Map<Constraint2DSW *, int>::Element *E = p_body->get_constraint_map().front(); E; E = E->next()) {
-
Constraint2DSW *c = (Constraint2DSW *)E->key();
- if (c->get_island_step() == _step)
+ if (c->get_island_step() == _step) {
continue; //already processed
+ }
c->set_island_step(_step);
c->set_island_next(*p_constraint_island);
*p_constraint_island = c;
for (int i = 0; i < c->get_body_count(); i++) {
- if (i == E->get())
+ if (i == E->get()) {
continue;
+ }
Body2DSW *b = c->get_body_ptr()[i];
- if (b->get_island_step() == _step || b->get_mode() == PhysicsServer2D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC)
+ if (b->get_island_step() == _step || b->get_mode() == PhysicsServer2D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC) {
continue; //no go
+ }
_populate_island(c->get_body_ptr()[i], p_island, p_constraint_island);
}
}
}
bool Step2DSW::_setup_island(Constraint2DSW *p_island, real_t p_delta) {
-
Constraint2DSW *ci = p_island;
Constraint2DSW *prev_ci = nullptr;
bool removed_root = false;
@@ -83,9 +83,7 @@ bool Step2DSW::_setup_island(Constraint2DSW *p_island, real_t p_delta) {
}
void Step2DSW::_solve_island(Constraint2DSW *p_island, int p_iterations, real_t p_delta) {
-
for (int i = 0; i < p_iterations; i++) {
-
Constraint2DSW *ci = p_island;
while (ci) {
ci->solve(p_delta);
@@ -95,19 +93,18 @@ void Step2DSW::_solve_island(Constraint2DSW *p_island, int p_iterations, real_t
}
void Step2DSW::_check_suspend(Body2DSW *p_island, real_t p_delta) {
-
bool can_sleep = true;
Body2DSW *b = p_island;
while (b) {
-
if (b->get_mode() == PhysicsServer2D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC) {
b = b->get_island_next();
continue; //ignore for static
}
- if (!b->sleep_test(p_delta))
+ if (!b->sleep_test(p_delta)) {
can_sleep = false;
+ }
b = b->get_island_next();
}
@@ -116,7 +113,6 @@ void Step2DSW::_check_suspend(Body2DSW *p_island, real_t p_delta) {
b = p_island;
while (b) {
-
if (b->get_mode() == PhysicsServer2D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer2D::BODY_MODE_KINEMATIC) {
b = b->get_island_next();
continue; //ignore for static
@@ -124,15 +120,15 @@ void Step2DSW::_check_suspend(Body2DSW *p_island, real_t p_delta) {
bool active = b->is_active();
- if (active == can_sleep)
+ if (active == can_sleep) {
b->set_active(!can_sleep);
+ }
b = b->get_island_next();
}
}
void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
-
p_space->lock(); // can't access space during this
p_space->setup(); //update inertias, etc
@@ -148,7 +144,6 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
const SelfList<Body2DSW> *b = body_list->first();
while (b) {
-
b->self()->integrate_forces(p_delta);
b = b->next();
active_count++;
@@ -174,7 +169,6 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
Body2DSW *body = b->self();
if (body->get_island_step() != _step) {
-
Body2DSW *island = nullptr;
Constraint2DSW *constraint_island = nullptr;
_populate_island(body, &island, &constraint_island);
@@ -197,10 +191,10 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
while (aml.first()) {
for (const Set<Constraint2DSW *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) {
-
Constraint2DSW *c = E->get();
- if (c->get_island_step() == _step)
+ if (c->get_island_step() == _step) {
continue;
+ }
c->set_island_step(_step);
c->set_island_next(nullptr);
c->set_island_list_next(constraint_island_list);
@@ -221,9 +215,7 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
Constraint2DSW *ci = constraint_island_list;
Constraint2DSW *prev_ci = nullptr;
while (ci) {
-
if (_setup_island(ci, p_delta)) {
-
//removed the root from the island graph because it is not to be processed
Constraint2DSW *next = ci->get_island_next();
@@ -238,7 +230,6 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
}
prev_ci = next;
} else {
-
//list is empty, just skip
if (prev_ci) {
prev_ci->set_island_list_next(ci->get_island_list_next());
@@ -282,7 +273,6 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
b = body_list->first();
while (b) {
-
const SelfList<Body2DSW> *n = b->next();
b->self()->integrate_velocities(p_delta);
b = n; // in case it shuts itself down
@@ -293,7 +283,6 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
{
Body2DSW *bi = island_list;
while (bi) {
-
_check_suspend(bi, p_delta);
bi = bi->get_island_list_next();
}
@@ -311,6 +300,5 @@ void Step2DSW::step(Space2DSW *p_space, real_t p_delta, int p_iterations) {
}
Step2DSW::Step2DSW() {
-
_step = 1;
}
diff --git a/servers/physics_2d/step_2d_sw.h b/servers/physics_2d/step_2d_sw.h
index 22d59b729b..c1b2d01fb4 100644
--- a/servers/physics_2d/step_2d_sw.h
+++ b/servers/physics_2d/step_2d_sw.h
@@ -34,7 +34,6 @@
#include "space_2d_sw.h"
class Step2DSW {
-
uint64_t _step;
void _populate_island(Body2DSW *p_body, Body2DSW **p_island, Constraint2DSW **p_constraint_island);
diff --git a/servers/physics_3d/area_3d_sw.cpp b/servers/physics_3d/area_3d_sw.cpp
index 911a664a10..98237dd91c 100644
--- a/servers/physics_3d/area_3d_sw.cpp
+++ b/servers/physics_3d/area_3d_sw.cpp
@@ -38,6 +38,7 @@ Area3DSW::BodyKey::BodyKey(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_a
body_shape = p_body_shape;
area_shape = p_area_shape;
}
+
Area3DSW::BodyKey::BodyKey(Area3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {
rid = p_body->get_self();
instance_id = p_body->get_instance_id();
@@ -46,27 +47,28 @@ Area3DSW::BodyKey::BodyKey(Area3DSW *p_body, uint32_t p_body_shape, uint32_t p_a
}
void Area3DSW::_shapes_changed() {
-
- if (!moved_list.in_list() && get_space())
+ if (!moved_list.in_list() && get_space()) {
get_space()->area_add_to_moved_list(&moved_list);
+ }
}
void Area3DSW::set_transform(const Transform &p_transform) {
-
- if (!moved_list.in_list() && get_space())
+ if (!moved_list.in_list() && get_space()) {
get_space()->area_add_to_moved_list(&moved_list);
+ }
_set_transform(p_transform);
_set_inv_transform(p_transform.affine_inverse());
}
void Area3DSW::set_space(Space3DSW *p_space) {
-
if (get_space()) {
- if (monitor_query_list.in_list())
+ if (monitor_query_list.in_list()) {
get_space()->area_remove_from_monitor_query_list(&monitor_query_list);
- if (moved_list.in_list())
+ }
+ if (moved_list.in_list()) {
get_space()->area_remove_from_moved_list(&moved_list);
+ }
}
monitored_bodies.clear();
@@ -76,7 +78,6 @@ void Area3DSW::set_space(Space3DSW *p_space) {
}
void Area3DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) {
-
if (p_id == monitor_callback_id) {
monitor_callback_method = p_method;
return;
@@ -92,12 +93,12 @@ void Area3DSW::set_monitor_callback(ObjectID p_id, const StringName &p_method) {
_shape_changed();
- if (!moved_list.in_list() && get_space())
+ if (!moved_list.in_list() && get_space()) {
get_space()->area_add_to_moved_list(&moved_list);
+ }
}
void Area3DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_method) {
-
if (p_id == area_monitor_callback_id) {
area_monitor_callback_method = p_method;
return;
@@ -113,74 +114,97 @@ void Area3DSW::set_area_monitor_callback(ObjectID p_id, const StringName &p_meth
_shape_changed();
- if (!moved_list.in_list() && get_space())
+ if (!moved_list.in_list() && get_space()) {
get_space()->area_add_to_moved_list(&moved_list);
+ }
}
void Area3DSW::set_space_override_mode(PhysicsServer3D::AreaSpaceOverrideMode p_mode) {
bool do_override = p_mode != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED;
- if (do_override == (space_override_mode != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED))
+ if (do_override == (space_override_mode != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED)) {
return;
+ }
_unregister_shapes();
space_override_mode = p_mode;
_shape_changed();
}
void Area3DSW::set_param(PhysicsServer3D::AreaParameter p_param, const Variant &p_value) {
-
switch (p_param) {
- case PhysicsServer3D::AREA_PARAM_GRAVITY: gravity = p_value; break;
- case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR: gravity_vector = p_value; break;
- case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT: gravity_is_point = p_value; break;
- case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: gravity_distance_scale = p_value; break;
- case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: point_attenuation = p_value; break;
- case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: linear_damp = p_value; break;
- case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: angular_damp = p_value; break;
- case PhysicsServer3D::AREA_PARAM_PRIORITY: priority = p_value; break;
+ case PhysicsServer3D::AREA_PARAM_GRAVITY:
+ gravity = p_value;
+ break;
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR:
+ gravity_vector = p_value;
+ break;
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT:
+ gravity_is_point = p_value;
+ break;
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ gravity_distance_scale = p_value;
+ break;
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ point_attenuation = p_value;
+ break;
+ case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP:
+ linear_damp = p_value;
+ break;
+ case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP:
+ angular_damp = p_value;
+ break;
+ case PhysicsServer3D::AREA_PARAM_PRIORITY:
+ priority = p_value;
+ break;
}
}
Variant Area3DSW::get_param(PhysicsServer3D::AreaParameter p_param) const {
-
switch (p_param) {
- case PhysicsServer3D::AREA_PARAM_GRAVITY: return gravity;
- case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR: return gravity_vector;
- case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT: return gravity_is_point;
- case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE: return gravity_distance_scale;
- case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION: return point_attenuation;
- case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP: return linear_damp;
- case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP: return angular_damp;
- case PhysicsServer3D::AREA_PARAM_PRIORITY: return priority;
+ case PhysicsServer3D::AREA_PARAM_GRAVITY:
+ return gravity;
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_VECTOR:
+ return gravity_vector;
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_IS_POINT:
+ return gravity_is_point;
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_DISTANCE_SCALE:
+ return gravity_distance_scale;
+ case PhysicsServer3D::AREA_PARAM_GRAVITY_POINT_ATTENUATION:
+ return point_attenuation;
+ case PhysicsServer3D::AREA_PARAM_LINEAR_DAMP:
+ return linear_damp;
+ case PhysicsServer3D::AREA_PARAM_ANGULAR_DAMP:
+ return angular_damp;
+ case PhysicsServer3D::AREA_PARAM_PRIORITY:
+ return priority;
}
return Variant();
}
void Area3DSW::_queue_monitor_update() {
-
ERR_FAIL_COND(!get_space());
- if (!monitor_query_list.in_list())
+ if (!monitor_query_list.in_list()) {
get_space()->area_add_to_monitor_query_list(&monitor_query_list);
+ }
}
void Area3DSW::set_monitorable(bool p_monitorable) {
-
- if (monitorable == p_monitorable)
+ if (monitorable == p_monitorable) {
return;
+ }
monitorable = p_monitorable;
_set_static(!monitorable);
}
void Area3DSW::call_queries() {
-
if (monitor_callback_id.is_valid() && !monitored_bodies.empty()) {
-
Variant res[5];
Variant *resptr[5];
- for (int i = 0; i < 5; i++)
+ for (int i = 0; i < 5; i++) {
resptr[i] = &res[i];
+ }
Object *obj = ObjectDB::get_instance(monitor_callback_id);
if (!obj) {
@@ -190,9 +214,9 @@ void Area3DSW::call_queries() {
}
for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E; E = E->next()) {
-
- if (E->get().state == 0)
+ if (E->get().state == 0) {
continue; //nothing happened
+ }
res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED;
res[1] = E->key().rid;
@@ -208,11 +232,11 @@ void Area3DSW::call_queries() {
monitored_bodies.clear();
if (area_monitor_callback_id.is_valid() && !monitored_areas.empty()) {
-
Variant res[5];
Variant *resptr[5];
- for (int i = 0; i < 5; i++)
+ for (int i = 0; i < 5; i++) {
resptr[i] = &res[i];
+ }
Object *obj = ObjectDB::get_instance(area_monitor_callback_id);
if (!obj) {
@@ -222,9 +246,9 @@ void Area3DSW::call_queries() {
}
for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E; E = E->next()) {
-
- if (E->get().state == 0)
+ if (E->get().state == 0) {
continue; //nothing happened
+ }
res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED;
res[1] = E->key().rid;
@@ -245,7 +269,6 @@ Area3DSW::Area3DSW() :
CollisionObject3DSW(TYPE_AREA),
monitor_query_list(this),
moved_list(this) {
-
_set_static(true); //areas are never active
space_override_mode = PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED;
gravity = 9.80665;
diff --git a/servers/physics_3d/area_3d_sw.h b/servers/physics_3d/area_3d_sw.h
index 05e74e63dc..6af3976167 100644
--- a/servers/physics_3d/area_3d_sw.h
+++ b/servers/physics_3d/area_3d_sw.h
@@ -41,7 +41,6 @@ class Body3DSW;
class Constraint3DSW;
class Area3DSW : public CollisionObject3DSW {
-
PhysicsServer3D::AreaSpaceOverrideMode space_override_mode;
real_t gravity;
Vector3 gravity_vector;
@@ -63,23 +62,21 @@ class Area3DSW : public CollisionObject3DSW {
SelfList<Area3DSW> moved_list;
struct BodyKey {
-
RID rid;
ObjectID instance_id;
uint32_t body_shape;
uint32_t area_shape;
_FORCE_INLINE_ bool operator<(const BodyKey &p_key) const {
-
if (rid == p_key.rid) {
-
if (body_shape == p_key.body_shape) {
-
return area_shape < p_key.area_shape;
- } else
+ } else {
return body_shape < p_key.body_shape;
- } else
+ }
+ } else {
return rid < p_key.rid;
+ }
}
_FORCE_INLINE_ BodyKey() {}
@@ -88,7 +85,6 @@ class Area3DSW : public CollisionObject3DSW {
};
struct BodyState {
-
int state;
_FORCE_INLINE_ void inc() { state++; }
_FORCE_INLINE_ void dec() { state--; }
@@ -171,33 +167,35 @@ public:
};
void Area3DSW::add_body_to_query(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {
-
BodyKey bk(p_body, p_body_shape, p_area_shape);
monitored_bodies[bk].inc();
- if (!monitor_query_list.in_list())
+ if (!monitor_query_list.in_list()) {
_queue_monitor_update();
+ }
}
-void Area3DSW::remove_body_from_query(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {
+void Area3DSW::remove_body_from_query(Body3DSW *p_body, uint32_t p_body_shape, uint32_t p_area_shape) {
BodyKey bk(p_body, p_body_shape, p_area_shape);
monitored_bodies[bk].dec();
- if (!monitor_query_list.in_list())
+ if (!monitor_query_list.in_list()) {
_queue_monitor_update();
+ }
}
void Area3DSW::add_area_to_query(Area3DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) {
-
BodyKey bk(p_area, p_area_shape, p_self_shape);
monitored_areas[bk].inc();
- if (!monitor_query_list.in_list())
+ if (!monitor_query_list.in_list()) {
_queue_monitor_update();
+ }
}
-void Area3DSW::remove_area_from_query(Area3DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) {
+void Area3DSW::remove_area_from_query(Area3DSW *p_area, uint32_t p_area_shape, uint32_t p_self_shape) {
BodyKey bk(p_area, p_area_shape, p_self_shape);
monitored_areas[bk].dec();
- if (!monitor_query_list.in_list())
+ if (!monitor_query_list.in_list()) {
_queue_monitor_update();
+ }
}
#endif // AREA__SW_H
diff --git a/servers/physics_3d/area_pair_3d_sw.cpp b/servers/physics_3d/area_pair_3d_sw.cpp
index fa2fb2dabb..a5fb20fe2b 100644
--- a/servers/physics_3d/area_pair_3d_sw.cpp
+++ b/servers/physics_3d/area_pair_3d_sw.cpp
@@ -32,7 +32,6 @@
#include "collision_solver_3d_sw.h"
bool AreaPair3DSW::setup(real_t p_step) {
-
bool result = false;
if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) {
@@ -42,20 +41,21 @@ bool AreaPair3DSW::setup(real_t p_step) {
}
if (result != colliding) {
-
if (result) {
-
- if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED)
+ if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) {
body->add_area(area);
- if (area->has_monitor_callback())
+ }
+ if (area->has_monitor_callback()) {
area->add_body_to_query(body, body_shape, area_shape);
+ }
} else {
-
- if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED)
+ if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) {
body->remove_area(area);
- if (area->has_monitor_callback())
+ }
+ if (area->has_monitor_callback()) {
area->remove_body_from_query(body, body_shape, area_shape);
+ }
}
colliding = result;
@@ -68,7 +68,6 @@ void AreaPair3DSW::solve(real_t p_step) {
}
AreaPair3DSW::AreaPair3DSW(Body3DSW *p_body, int p_body_shape, Area3DSW *p_area, int p_area_shape) {
-
body = p_body;
area = p_area;
body_shape = p_body_shape;
@@ -76,18 +75,19 @@ AreaPair3DSW::AreaPair3DSW(Body3DSW *p_body, int p_body_shape, Area3DSW *p_area,
colliding = false;
body->add_constraint(this, 0);
area->add_constraint(this);
- if (p_body->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC)
+ if (p_body->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC) {
p_body->set_active(true);
+ }
}
AreaPair3DSW::~AreaPair3DSW() {
-
if (colliding) {
-
- if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED)
+ if (area->get_space_override_mode() != PhysicsServer3D::AREA_SPACE_OVERRIDE_DISABLED) {
body->remove_area(area);
- if (area->has_monitor_callback())
+ }
+ if (area->has_monitor_callback()) {
area->remove_body_from_query(body, body_shape, area_shape);
+ }
}
body->remove_constraint(this);
area->remove_constraint(this);
@@ -96,7 +96,6 @@ AreaPair3DSW::~AreaPair3DSW() {
////////////////////////////////////////////////////
bool Area2Pair3DSW::setup(real_t p_step) {
-
bool result = false;
if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) {
result = false;
@@ -105,22 +104,23 @@ bool Area2Pair3DSW::setup(real_t p_step) {
}
if (result != colliding) {
-
if (result) {
-
- if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
+ if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
area_b->add_area_to_query(area_a, shape_a, shape_b);
+ }
- if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
+ if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
area_a->add_area_to_query(area_b, shape_b, shape_a);
+ }
} else {
-
- if (area_b->has_area_monitor_callback() && area_a->is_monitorable())
+ if (area_b->has_area_monitor_callback() && area_a->is_monitorable()) {
area_b->remove_area_from_query(area_a, shape_a, shape_b);
+ }
- if (area_a->has_area_monitor_callback() && area_b->is_monitorable())
+ if (area_a->has_area_monitor_callback() && area_b->is_monitorable()) {
area_a->remove_area_from_query(area_b, shape_b, shape_a);
+ }
}
colliding = result;
@@ -133,7 +133,6 @@ void Area2Pair3DSW::solve(real_t p_step) {
}
Area2Pair3DSW::Area2Pair3DSW(Area3DSW *p_area_a, int p_shape_a, Area3DSW *p_area_b, int p_shape_b) {
-
area_a = p_area_a;
area_b = p_area_b;
shape_a = p_shape_a;
@@ -144,14 +143,14 @@ Area2Pair3DSW::Area2Pair3DSW(Area3DSW *p_area_a, int p_shape_a, Area3DSW *p_area
}
Area2Pair3DSW::~Area2Pair3DSW() {
-
if (colliding) {
-
- if (area_b->has_area_monitor_callback())
+ if (area_b->has_area_monitor_callback()) {
area_b->remove_area_from_query(area_a, shape_a, shape_b);
+ }
- if (area_a->has_area_monitor_callback())
+ if (area_a->has_area_monitor_callback()) {
area_a->remove_area_from_query(area_b, shape_b, shape_a);
+ }
}
area_a->remove_constraint(this);
diff --git a/servers/physics_3d/area_pair_3d_sw.h b/servers/physics_3d/area_pair_3d_sw.h
index 3490f41c26..992d4747b9 100644
--- a/servers/physics_3d/area_pair_3d_sw.h
+++ b/servers/physics_3d/area_pair_3d_sw.h
@@ -36,7 +36,6 @@
#include "constraint_3d_sw.h"
class AreaPair3DSW : public Constraint3DSW {
-
Body3DSW *body;
Area3DSW *area;
int body_shape;
@@ -52,7 +51,6 @@ public:
};
class Area2Pair3DSW : public Constraint3DSW {
-
Area3DSW *area_a;
Area3DSW *area_b;
int shape_a;
diff --git a/servers/physics_3d/body_3d_sw.cpp b/servers/physics_3d/body_3d_sw.cpp
index fea5aed6ad..a3bdc96c9f 100644
--- a/servers/physics_3d/body_3d_sw.cpp
+++ b/servers/physics_3d/body_3d_sw.cpp
@@ -33,13 +33,12 @@
#include "space_3d_sw.h"
void Body3DSW::_update_inertia() {
-
- if (get_space() && !inertia_update_list.in_list())
+ if (get_space() && !inertia_update_list.in_list()) {
get_space()->body_add_to_inertia_update_list(&inertia_update_list);
+ }
}
void Body3DSW::_update_transform_dependant() {
-
center_of_mass = get_transform().basis.xform(center_of_mass_local);
principal_inertia_axes = get_transform().basis * principal_inertia_axes_local;
@@ -52,18 +51,14 @@ void Body3DSW::_update_transform_dependant() {
}
void Body3DSW::update_inertias() {
-
//update shapes and motions
switch (mode) {
-
case PhysicsServer3D::BODY_MODE_RIGID: {
-
//update tensor for all shapes, not the best way but should be somehow OK. (inspired from bullet)
real_t total_area = 0;
for (int i = 0; i < get_shape_count(); i++) {
-
total_area += get_shape_area(i);
}
@@ -86,7 +81,6 @@ void Body3DSW::update_inertias() {
inertia_tensor.set_zero();
for (int i = 0; i < get_shape_count(); i++) {
-
if (is_shape_disabled(i)) {
continue;
}
@@ -112,21 +106,20 @@ void Body3DSW::update_inertias() {
principal_inertia_axes_local = inertia_tensor.diagonalize().transposed();
_inv_inertia = inertia_tensor.get_main_diagonal().inverse();
- if (mass)
+ if (mass) {
_inv_mass = 1.0 / mass;
- else
+ } else {
_inv_mass = 0;
+ }
} break;
case PhysicsServer3D::BODY_MODE_KINEMATIC:
case PhysicsServer3D::BODY_MODE_STATIC: {
-
_inv_inertia_tensor.set_zero();
_inv_mass = 0;
} break;
case PhysicsServer3D::BODY_MODE_CHARACTER: {
-
_inv_inertia_tensor.set_zero();
_inv_mass = 1.0 / mass;
@@ -139,19 +132,22 @@ void Body3DSW::update_inertias() {
}
void Body3DSW::set_active(bool p_active) {
-
- if (active == p_active)
+ if (active == p_active) {
return;
+ }
active = p_active;
if (!p_active) {
- if (get_space())
+ if (get_space()) {
get_space()->body_remove_from_active_list(&active_list);
+ }
} else {
- if (mode == PhysicsServer3D::BODY_MODE_STATIC)
+ if (mode == PhysicsServer3D::BODY_MODE_STATIC) {
return; //static bodies can't become active
- if (get_space())
+ }
+ if (get_space()) {
get_space()->body_add_to_active_list(&active_list);
+ }
//still_time=0;
}
@@ -169,14 +165,11 @@ void Body3DSW::set_active(bool p_active) {
}
void Body3DSW::set_param(PhysicsServer3D::BodyParameter p_param, real_t p_value) {
-
switch (p_param) {
case PhysicsServer3D::BODY_PARAM_BOUNCE: {
-
bounce = p_value;
} break;
case PhysicsServer3D::BODY_PARAM_FRICTION: {
-
friction = p_value;
} break;
case PhysicsServer3D::BODY_PARAM_MASS: {
@@ -189,11 +182,9 @@ void Body3DSW::set_param(PhysicsServer3D::BodyParameter p_param, real_t p_value)
gravity_scale = p_value;
} break;
case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP: {
-
linear_damp = p_value;
} break;
case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP: {
-
angular_damp = p_value;
} break;
default: {
@@ -202,14 +193,11 @@ void Body3DSW::set_param(PhysicsServer3D::BodyParameter p_param, real_t p_value)
}
real_t Body3DSW::get_param(PhysicsServer3D::BodyParameter p_param) const {
-
switch (p_param) {
case PhysicsServer3D::BODY_PARAM_BOUNCE: {
-
return bounce;
} break;
case PhysicsServer3D::BODY_PARAM_FRICTION: {
-
return friction;
} break;
case PhysicsServer3D::BODY_PARAM_MASS: {
@@ -219,11 +207,9 @@ real_t Body3DSW::get_param(PhysicsServer3D::BodyParameter p_param) const {
return gravity_scale;
} break;
case PhysicsServer3D::BODY_PARAM_LINEAR_DAMP: {
-
return linear_damp;
} break;
case PhysicsServer3D::BODY_PARAM_ANGULAR_DAMP: {
-
return angular_damp;
} break;
@@ -235,7 +221,6 @@ real_t Body3DSW::get_param(PhysicsServer3D::BodyParameter p_param) const {
}
void Body3DSW::set_mode(PhysicsServer3D::BodyMode p_mode) {
-
PhysicsServer3D::BodyMode prev = mode;
mode = p_mode;
@@ -243,7 +228,6 @@ void Body3DSW::set_mode(PhysicsServer3D::BodyMode p_mode) {
//CLEAR UP EVERYTHING IN CASE IT NOT WORKS!
case PhysicsServer3D::BODY_MODE_STATIC:
case PhysicsServer3D::BODY_MODE_KINEMATIC: {
-
_set_inv_transform(get_transform().affine_inverse());
_inv_mass = 0;
_set_static(p_mode == PhysicsServer3D::BODY_MODE_STATIC);
@@ -257,14 +241,12 @@ void Body3DSW::set_mode(PhysicsServer3D::BodyMode p_mode) {
} break;
case PhysicsServer3D::BODY_MODE_RIGID: {
-
_inv_mass = mass > 0 ? (1.0 / mass) : 0;
_set_static(false);
set_active(true);
} break;
case PhysicsServer3D::BODY_MODE_CHARACTER: {
-
_inv_mass = mass > 0 ? (1.0 / mass) : 0;
_set_static(false);
set_active(true);
@@ -278,21 +260,18 @@ void Body3DSW::set_mode(PhysicsServer3D::BodyMode p_mode) {
_update_queries();
*/
}
-PhysicsServer3D::BodyMode Body3DSW::get_mode() const {
+PhysicsServer3D::BodyMode Body3DSW::get_mode() const {
return mode;
}
void Body3DSW::_shapes_changed() {
-
_update_inertia();
}
void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_variant) {
-
switch (p_state) {
case PhysicsServer3D::BODY_STATE_TRANSFORM: {
-
if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) {
new_transform = p_variant;
//wakeup_neighbours();
@@ -311,8 +290,9 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va
Transform t = p_variant;
t.orthonormalize();
new_transform = get_transform(); //used as old to compute motion
- if (new_transform == t)
+ if (new_transform == t) {
break;
+ }
_set_transform(t);
_set_inv_transform(get_transform().inverse());
}
@@ -320,7 +300,6 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va
} break;
case PhysicsServer3D::BODY_STATE_LINEAR_VELOCITY: {
-
/*
if (mode==PhysicsServer3D::BODY_MODE_STATIC)
break;
@@ -339,8 +318,9 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va
} break;
case PhysicsServer3D::BODY_STATE_SLEEPING: {
//?
- if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC)
+ if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) {
break;
+ }
bool do_sleep = p_variant;
if (do_sleep) {
linear_velocity = Vector3();
@@ -354,14 +334,15 @@ void Body3DSW::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_va
} break;
case PhysicsServer3D::BODY_STATE_CAN_SLEEP: {
can_sleep = p_variant;
- if (mode == PhysicsServer3D::BODY_MODE_RIGID && !active && !can_sleep)
+ if (mode == PhysicsServer3D::BODY_MODE_RIGID && !active && !can_sleep) {
set_active(true);
+ }
} break;
}
}
-Variant Body3DSW::get_state(PhysicsServer3D::BodyState p_state) const {
+Variant Body3DSW::get_state(PhysicsServer3D::BodyState p_state) const {
switch (p_state) {
case PhysicsServer3D::BODY_STATE_TRANSFORM: {
return get_transform();
@@ -384,24 +365,25 @@ Variant Body3DSW::get_state(PhysicsServer3D::BodyState p_state) const {
}
void Body3DSW::set_space(Space3DSW *p_space) {
-
if (get_space()) {
-
- if (inertia_update_list.in_list())
+ if (inertia_update_list.in_list()) {
get_space()->body_remove_from_inertia_update_list(&inertia_update_list);
- if (active_list.in_list())
+ }
+ if (active_list.in_list()) {
get_space()->body_remove_from_active_list(&active_list);
- if (direct_state_query_list.in_list())
+ }
+ if (direct_state_query_list.in_list()) {
get_space()->body_remove_from_state_query_list(&direct_state_query_list);
+ }
}
_set_space(p_space);
if (get_space()) {
-
_update_inertia();
- if (active)
+ if (active) {
get_space()->body_add_to_active_list(&active_list);
+ }
/*
_update_queries();
if (is_active()) {
@@ -415,7 +397,6 @@ void Body3DSW::set_space(Space3DSW *p_space) {
}
void Body3DSW::_compute_area_gravity_and_dampenings(const Area3DSW *p_area) {
-
if (p_area->is_gravity_point()) {
if (p_area->get_gravity_distance_scale() > 0) {
Vector3 v = p_area->get_transform().xform(p_area->get_gravity_vector()) - get_transform().get_origin();
@@ -444,9 +425,9 @@ bool Body3DSW::is_axis_locked(PhysicsServer3D::BodyAxis p_axis) const {
}
void Body3DSW::integrate_forces(real_t p_step) {
-
- if (mode == PhysicsServer3D::BODY_MODE_STATIC)
+ if (mode == PhysicsServer3D::BODY_MODE_STATIC) {
return;
+ }
Area3DSW *def_area = get_space()->get_default_area();
// AreaSW *damp_area = def_area;
@@ -491,15 +472,17 @@ void Body3DSW::integrate_forces(real_t p_step) {
gravity *= gravity_scale;
// If less than 0, override dampenings with that of the Body
- if (angular_damp >= 0)
+ if (angular_damp >= 0) {
area_angular_damp = angular_damp;
+ }
/*
else
area_angular_damp=damp_area->get_angular_damp();
*/
- if (linear_damp >= 0)
+ if (linear_damp >= 0) {
area_linear_damp = linear_damp;
+ }
/*
else
area_linear_damp=damp_area->get_linear_damp();
@@ -509,7 +492,6 @@ void Body3DSW::integrate_forces(real_t p_step) {
bool do_motion = false;
if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) {
-
//compute motion, angular and etc. velocities from prev transform
linear_velocity = (new_transform.origin - get_transform().origin) / p_step;
@@ -535,13 +517,15 @@ void Body3DSW::integrate_forces(real_t p_step) {
real_t damp = 1.0 - p_step * area_linear_damp;
- if (damp < 0) // reached zero in the given time
+ if (damp < 0) { // reached zero in the given time
damp = 0;
+ }
real_t angular_damp = 1.0 - p_step * area_angular_damp;
- if (angular_damp < 0) // reached zero in the given time
+ if (angular_damp < 0) { // reached zero in the given time
angular_damp = 0;
+ }
linear_velocity *= damp;
angular_velocity *= angular_damp;
@@ -574,12 +558,13 @@ void Body3DSW::integrate_forces(real_t p_step) {
}
void Body3DSW::integrate_velocities(real_t p_step) {
-
- if (mode == PhysicsServer3D::BODY_MODE_STATIC)
+ if (mode == PhysicsServer3D::BODY_MODE_STATIC) {
return;
+ }
- if (fi_callback)
+ if (fi_callback) {
get_space()->body_add_to_state_query_list(&direct_state_query_list);
+ }
//apply axis lock linear
for (int i = 0; i < 3; i++) {
@@ -598,11 +583,11 @@ void Body3DSW::integrate_velocities(real_t p_step) {
}
if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC) {
-
_set_transform(new_transform, false);
_set_inv_transform(new_transform.affine_inverse());
- if (contacts.size() == 0 && linear_velocity == Vector3() && angular_velocity == Vector3())
+ if (contacts.size() == 0 && linear_velocity == Vector3() && angular_velocity == Vector3()) {
set_active(false); //stopped moving, deactivate
+ }
return;
}
@@ -673,34 +658,33 @@ void BodySW::simulate_motion(const Transform& p_xform,real_t p_step) {
}
+
*/
void Body3DSW::wakeup_neighbours() {
-
for (Map<Constraint3DSW *, int>::Element *E = constraint_map.front(); E; E = E->next()) {
-
const Constraint3DSW *c = E->key();
Body3DSW **n = c->get_body_ptr();
int bc = c->get_body_count();
for (int i = 0; i < bc; i++) {
-
- if (i == E->get())
+ if (i == E->get()) {
continue;
+ }
Body3DSW *b = n[i];
- if (b->mode != PhysicsServer3D::BODY_MODE_RIGID)
+ if (b->mode != PhysicsServer3D::BODY_MODE_RIGID) {
continue;
+ }
- if (!b->is_active())
+ if (!b->is_active()) {
b->set_active(true);
+ }
}
}
}
void Body3DSW::call_queries() {
-
if (fi_callback) {
-
PhysicsDirectBodyState3DSW *dbs = PhysicsDirectBodyState3DSW::singleton;
dbs->body = this;
@@ -708,7 +692,6 @@ void Body3DSW::call_queries() {
Object *obj = ObjectDB::get_instance(fi_callback->id);
if (!obj) {
-
set_force_integration_callback(ObjectID(), StringName());
} else {
const Variant *vp[2] = { &v, &fi_callback->udata };
@@ -721,36 +704,31 @@ void Body3DSW::call_queries() {
}
bool Body3DSW::sleep_test(real_t p_step) {
-
- if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC)
+ if (mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) {
return true; //
- else if (mode == PhysicsServer3D::BODY_MODE_CHARACTER)
+ } else if (mode == PhysicsServer3D::BODY_MODE_CHARACTER) {
return !active; // characters don't sleep unless asked to sleep
- else if (!can_sleep)
+ } else if (!can_sleep) {
return false;
+ }
if (Math::abs(angular_velocity.length()) < get_space()->get_body_angular_velocity_sleep_threshold() && Math::abs(linear_velocity.length_squared()) < get_space()->get_body_linear_velocity_sleep_threshold() * get_space()->get_body_linear_velocity_sleep_threshold()) {
-
still_time += p_step;
return still_time > get_space()->get_body_time_to_sleep();
} else {
-
still_time = 0; //maybe this should be set to 0 on set_active?
return false;
}
}
void Body3DSW::set_force_integration_callback(ObjectID p_id, const StringName &p_method, const Variant &p_udata) {
-
if (fi_callback) {
-
memdelete(fi_callback);
fi_callback = nullptr;
}
if (p_id.is_valid()) {
-
fi_callback = memnew(ForceIntegrationCallback);
fi_callback->id = p_id;
fi_callback->method = p_method;
@@ -764,11 +742,10 @@ void Body3DSW::set_kinematic_margin(real_t p_margin) {
Body3DSW::Body3DSW() :
CollisionObject3DSW(TYPE_BODY),
- locked_axis(0),
+
active_list(this),
inertia_update_list(this),
direct_state_query_list(this) {
-
mode = PhysicsServer3D::BODY_MODE_RIGID;
active = true;
@@ -801,14 +778,13 @@ Body3DSW::Body3DSW() :
}
Body3DSW::~Body3DSW() {
-
- if (fi_callback)
+ if (fi_callback) {
memdelete(fi_callback);
+ }
}
PhysicsDirectBodyState3DSW *PhysicsDirectBodyState3DSW::singleton = nullptr;
PhysicsDirectSpaceState3D *PhysicsDirectBodyState3DSW::get_space_state() {
-
return body->get_space()->get_direct_state();
}
diff --git a/servers/physics_3d/body_3d_sw.h b/servers/physics_3d/body_3d_sw.h
index 2bd335e6c0..483ea58620 100644
--- a/servers/physics_3d/body_3d_sw.h
+++ b/servers/physics_3d/body_3d_sw.h
@@ -38,7 +38,6 @@
class Constraint3DSW;
class Body3DSW : public CollisionObject3DSW {
-
PhysicsServer3D::BodyMode mode;
Vector3 linear_velocity;
@@ -54,7 +53,7 @@ class Body3DSW : public CollisionObject3DSW {
real_t angular_damp;
real_t gravity_scale;
- uint16_t locked_axis;
+ uint16_t locked_axis = 0;
real_t kinematic_safe_margin;
real_t _inv_mass;
@@ -99,7 +98,6 @@ class Body3DSW : public CollisionObject3DSW {
Map<Constraint3DSW *, int> constraint_map;
struct AreaCMP {
-
Area3DSW *area;
int refCount;
_FORCE_INLINE_ bool operator==(const AreaCMP &p_cmp) const { return area->get_self() == p_cmp.area->get_self(); }
@@ -114,7 +112,6 @@ class Body3DSW : public CollisionObject3DSW {
Vector<AreaCMP> areas;
struct Contact {
-
Vector3 local_pos;
Vector3 local_normal;
real_t depth;
@@ -130,7 +127,6 @@ class Body3DSW : public CollisionObject3DSW {
int contact_count;
struct ForceIntegrationCallback {
-
ObjectID id;
StringName method;
Variant udata;
@@ -167,15 +163,18 @@ public:
int index = areas.find(AreaCMP(p_area));
if (index > -1) {
areas.write[index].refCount -= 1;
- if (areas[index].refCount < 1)
+ if (areas[index].refCount < 1) {
areas.remove(index);
+ }
}
}
_FORCE_INLINE_ void set_max_contacts_reported(int p_size) {
contacts.resize(p_size);
contact_count = 0;
- if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC && p_size) set_active(true);
+ if (mode == PhysicsServer3D::BODY_MODE_KINEMATIC && p_size) {
+ set_active(true);
+ }
}
_FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); }
@@ -222,18 +221,15 @@ public:
}
_FORCE_INLINE_ void apply_impulse(const Vector3 &p_pos, const Vector3 &p_j) {
-
linear_velocity += p_j * _inv_mass;
angular_velocity += _inv_inertia_tensor.xform((p_pos - center_of_mass).cross(p_j));
}
_FORCE_INLINE_ void apply_torque_impulse(const Vector3 &p_j) {
-
angular_velocity += _inv_inertia_tensor.xform(p_j);
}
_FORCE_INLINE_ void apply_bias_impulse(const Vector3 &p_pos, const Vector3 &p_j, real_t p_max_delta_av = -1.0) {
-
biased_linear_velocity += p_j * _inv_mass;
if (p_max_delta_av != 0.0) {
Vector3 delta_av = _inv_inertia_tensor.xform((p_pos - center_of_mass).cross(p_j));
@@ -245,17 +241,14 @@ public:
}
_FORCE_INLINE_ void apply_bias_torque_impulse(const Vector3 &p_j) {
-
biased_angular_velocity += _inv_inertia_tensor.xform(p_j);
}
_FORCE_INLINE_ void add_central_force(const Vector3 &p_force) {
-
applied_force += p_force;
}
_FORCE_INLINE_ void add_force(const Vector3 &p_force, const Vector3 &p_pos) {
-
applied_force += p_force;
applied_torque += (p_pos - center_of_mass).cross(p_force);
}
@@ -268,8 +261,9 @@ public:
_FORCE_INLINE_ bool is_active() const { return active; }
_FORCE_INLINE_ void wakeup() {
- if ((!get_space()) || mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC)
+ if ((!get_space()) || mode == PhysicsServer3D::BODY_MODE_STATIC || mode == PhysicsServer3D::BODY_MODE_KINEMATIC) {
return;
+ }
set_active(true);
}
@@ -309,12 +303,10 @@ public:
void integrate_velocities(real_t p_step);
_FORCE_INLINE_ Vector3 get_velocity_in_local_point(const Vector3 &rel_pos) const {
-
return linear_velocity + angular_velocity.cross(rel_pos - center_of_mass);
}
_FORCE_INLINE_ real_t compute_impulse_denominator(const Vector3 &p_pos, const Vector3 &p_normal) const {
-
Vector3 r0 = p_pos - get_transform().origin - center_of_mass;
Vector3 c0 = (r0).cross(p_normal);
@@ -325,7 +317,6 @@ public:
}
_FORCE_INLINE_ real_t compute_angular_impulse_denominator(const Vector3 &p_axis) const {
-
return p_axis.dot(_inv_inertia_tensor.xform_inv(p_axis));
}
@@ -342,11 +333,11 @@ public:
//add contact inline
void Body3DSW::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_normal, real_t p_depth, int p_local_shape, const Vector3 &p_collider_pos, int p_collider_shape, ObjectID p_collider_instance_id, const RID &p_collider, const Vector3 &p_collider_velocity_at_pos) {
-
int c_max = contacts.size();
- if (c_max == 0)
+ if (c_max == 0) {
return;
+ }
Contact *c = contacts.ptrw();
@@ -355,11 +346,9 @@ void Body3DSW::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_no
if (contact_count < c_max) {
idx = contact_count++;
} else {
-
real_t least_depth = 1e20;
int least_deep = -1;
for (int i = 0; i < c_max; i++) {
-
if (i == 0 || c[i].depth < least_depth) {
least_deep = i;
least_depth = c[i].depth;
@@ -367,11 +356,11 @@ void Body3DSW::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_no
}
if (least_deep >= 0 && least_depth < p_depth) {
-
idx = least_deep;
}
- if (idx == -1)
+ if (idx == -1) {
return; //none least deepe than this
+ }
}
c[idx].local_pos = p_local_pos;
@@ -386,7 +375,6 @@ void Body3DSW::add_contact(const Vector3 &p_local_pos, const Vector3 &p_local_no
}
class PhysicsDirectBodyState3DSW : public PhysicsDirectBodyState3D {
-
GDCLASS(PhysicsDirectBodyState3DSW, PhysicsDirectBodyState3D);
public:
diff --git a/servers/physics_3d/body_pair_3d_sw.cpp b/servers/physics_3d/body_pair_3d_sw.cpp
index 245fb3449c..a4f86badbe 100644
--- a/servers/physics_3d/body_pair_3d_sw.cpp
+++ b/servers/physics_3d/body_pair_3d_sw.cpp
@@ -50,13 +50,11 @@
#define MAX_BIAS_ROTATION (Math_PI / 8)
void BodyPair3DSW::_contact_added_callback(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) {
-
BodyPair3DSW *pair = (BodyPair3DSW *)p_userdata;
pair->contact_added_callback(p_point_A, p_point_B);
}
void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, const Vector3 &p_point_B) {
-
// check if we already have the contact
//Vector3 local_A = A->get_inv_transform().xform(p_point_A);
@@ -84,11 +82,9 @@ void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, const Vector
real_t contact_recycle_radius = space->get_contact_recycle_radius();
for (int i = 0; i < contact_count; i++) {
-
Contact &c = contacts[i];
if (c.local_A.distance_squared_to(local_A) < (contact_recycle_radius * contact_recycle_radius) &&
c.local_B.distance_squared_to(local_B) < (contact_recycle_radius * contact_recycle_radius)) {
-
contact.acc_normal_impulse = c.acc_normal_impulse;
contact.acc_bias_impulse = c.acc_bias_impulse;
contact.acc_bias_impulse_center_of_mass = c.acc_bias_impulse_center_of_mass;
@@ -101,14 +97,12 @@ void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, const Vector
// figure out if the contact amount must be reduced to fit the new contact
if (new_index == MAX_CONTACTS) {
-
// remove the contact with the minimum depth
int least_deep = -1;
real_t min_depth = 1e10;
for (int i = 0; i <= contact_count; i++) {
-
Contact &c = (i == contact_count) ? contact : contacts[i];
Vector3 global_A = A->get_transform().basis.xform(c.local_A);
Vector3 global_B = B->get_transform().basis.xform(c.local_B) + offset_B;
@@ -117,7 +111,6 @@ void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, const Vector
real_t depth = axis.dot(c.normal);
if (depth < min_depth) {
-
min_depth = depth;
least_deep = i;
}
@@ -136,18 +129,15 @@ void BodyPair3DSW::contact_added_callback(const Vector3 &p_point_A, const Vector
contacts[new_index] = contact;
if (new_index == contact_count) {
-
contact_count++;
}
}
void BodyPair3DSW::validate_contacts() {
-
//make sure to erase contacts that are no longer valid
real_t contact_max_separation = space->get_contact_max_separation();
for (int i = 0; i < contact_count; i++) {
-
Contact &c = contacts[i];
Vector3 global_A = A->get_transform().basis.xform(c.local_A);
@@ -170,11 +160,11 @@ void BodyPair3DSW::validate_contacts() {
}
bool BodyPair3DSW::_test_ccd(real_t p_step, Body3DSW *p_A, int p_shape_A, const Transform &p_xform_A, Body3DSW *p_B, int p_shape_B, const Transform &p_xform_B) {
-
Vector3 motion = p_A->get_linear_velocity() * p_step;
real_t mlen = motion.length();
- if (mlen < CMP_EPSILON)
+ if (mlen < CMP_EPSILON) {
return false;
+ }
Vector3 mnormal = motion / mlen;
@@ -220,7 +210,6 @@ real_t combine_friction(Body3DSW *A, Body3DSW *B) {
}
bool BodyPair3DSW::setup(real_t p_step) {
-
//cannot collide
if (!A->test_collision_mask(B) || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode() <= PhysicsServer3D::BODY_MODE_KINEMATIC && B->get_mode() <= PhysicsServer3D::BODY_MODE_KINEMATIC && A->get_max_contacts_reported() == 0 && B->get_max_contacts_reported() == 0)) {
collided = false;
@@ -251,7 +240,6 @@ bool BodyPair3DSW::setup(real_t p_step) {
this->collided = collided;
if (!collided) {
-
//test ccd (currently just a raycast)
if (A->is_continuous_collision_detection_enabled() && A->get_mode() > PhysicsServer3D::BODY_MODE_KINEMATIC && B->get_mode() <= PhysicsServer3D::BODY_MODE_KINEMATIC) {
@@ -270,19 +258,18 @@ bool BodyPair3DSW::setup(real_t p_step) {
real_t bias = (real_t)0.3;
if (shape_A_ptr->get_custom_bias() || shape_B_ptr->get_custom_bias()) {
-
- if (shape_A_ptr->get_custom_bias() == 0)
+ if (shape_A_ptr->get_custom_bias() == 0) {
bias = shape_B_ptr->get_custom_bias();
- else if (shape_B_ptr->get_custom_bias() == 0)
+ } else if (shape_B_ptr->get_custom_bias() == 0) {
bias = shape_A_ptr->get_custom_bias();
- else
+ } else {
bias = (shape_B_ptr->get_custom_bias() + shape_A_ptr->get_custom_bias()) * 0.5;
+ }
}
real_t inv_dt = 1.0 / p_step;
for (int i = 0; i < contact_count; i++) {
-
Contact &c = contacts[i];
c.active = false;
@@ -341,7 +328,6 @@ bool BodyPair3DSW::setup(real_t p_step) {
c.bounce = combine_bounce(A, B);
if (c.bounce) {
-
Vector3 crA = A->get_angular_velocity().cross(c.rA);
Vector3 crB = B->get_angular_velocity().cross(c.rB);
Vector3 dv = B->get_linear_velocity() + crB - A->get_linear_velocity() - crA;
@@ -354,15 +340,15 @@ bool BodyPair3DSW::setup(real_t p_step) {
}
void BodyPair3DSW::solve(real_t p_step) {
-
- if (!collided)
+ if (!collided) {
return;
+ }
for (int i = 0; i < contact_count; i++) {
-
Contact &c = contacts[i];
- if (!c.active)
+ if (!c.active) {
continue;
+ }
c.active = false; //try to deactivate, will activate itself if still needed
@@ -375,7 +361,6 @@ void BodyPair3DSW::solve(real_t p_step) {
real_t vbn = dbv.dot(c.normal);
if (Math::abs(-vbn + c.bias) > MIN_VELOCITY) {
-
real_t jbn = (-vbn + c.bias) * c.mass_normal;
real_t jbnOld = c.acc_bias_impulse;
c.acc_bias_impulse = MAX(jbnOld + jbn, 0.0f);
@@ -392,7 +377,6 @@ void BodyPair3DSW::solve(real_t p_step) {
vbn = dbv.dot(c.normal);
if (Math::abs(-vbn + c.bias) > MIN_VELOCITY) {
-
real_t jbn_com = (-vbn + c.bias) / (A->get_inv_mass() + B->get_inv_mass());
real_t jbnOld_com = c.acc_bias_impulse_center_of_mass;
c.acc_bias_impulse_center_of_mass = MAX(jbnOld_com + jbn_com, 0.0f);
@@ -414,7 +398,6 @@ void BodyPair3DSW::solve(real_t p_step) {
real_t vn = dv.dot(c.normal);
if (Math::abs(vn) > MIN_VELOCITY) {
-
real_t jn = -(c.bounce + vn) * c.mass_normal;
real_t jnOld = c.acc_normal_impulse;
c.acc_normal_impulse = MAX(jnOld + jn, 0.0f);
@@ -442,7 +425,6 @@ void BodyPair3DSW::solve(real_t p_step) {
real_t tvl = tv.length();
if (tvl > MIN_VELOCITY) {
-
tv /= tvl;
Vector3 temp1 = A->get_inv_inertia_tensor().xform(c.rA.cross(tv));
@@ -460,7 +442,6 @@ void BodyPair3DSW::solve(real_t p_step) {
real_t jtMax = c.acc_normal_impulse * friction;
if (fi_len > CMP_EPSILON && fi_len > jtMax) {
-
c.acc_tangent_impulse *= jtMax / fi_len;
}
@@ -476,7 +457,6 @@ void BodyPair3DSW::solve(real_t p_step) {
BodyPair3DSW::BodyPair3DSW(Body3DSW *p_A, int p_shape_A, Body3DSW *p_B, int p_shape_B) :
Constraint3DSW(_arr, 2) {
-
A = p_A;
B = p_B;
shape_A = p_shape_A;
@@ -489,7 +469,6 @@ BodyPair3DSW::BodyPair3DSW(Body3DSW *p_A, int p_shape_A, Body3DSW *p_B, int p_sh
}
BodyPair3DSW::~BodyPair3DSW() {
-
A->remove_constraint(this);
B->remove_constraint(this);
}
diff --git a/servers/physics_3d/body_pair_3d_sw.h b/servers/physics_3d/body_pair_3d_sw.h
index 7f4afb9dca..59e36e7ea5 100644
--- a/servers/physics_3d/body_pair_3d_sw.h
+++ b/servers/physics_3d/body_pair_3d_sw.h
@@ -53,7 +53,6 @@ class BodyPair3DSW : public Constraint3DSW {
int shape_B;
struct Contact {
-
Vector3 position;
Vector3 normal;
Vector3 local_A, local_B;
diff --git a/servers/physics_3d/broad_phase_3d_basic.cpp b/servers/physics_3d/broad_phase_3d_basic.cpp
index 08ea219869..0f271b33af 100644
--- a/servers/physics_3d/broad_phase_3d_basic.cpp
+++ b/servers/physics_3d/broad_phase_3d_basic.cpp
@@ -33,7 +33,6 @@
#include "core/print_string.h"
BroadPhase3DSW::ID BroadPhase3DBasic::create(CollisionObject3DSW *p_object, int p_subindex) {
-
ERR_FAIL_COND_V(p_object == nullptr, 0);
current++;
@@ -48,27 +47,24 @@ BroadPhase3DSW::ID BroadPhase3DBasic::create(CollisionObject3DSW *p_object, int
}
void BroadPhase3DBasic::move(ID p_id, const AABB &p_aabb) {
-
Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
E->get().aabb = p_aabb;
}
-void BroadPhase3DBasic::set_static(ID p_id, bool p_static) {
+void BroadPhase3DBasic::set_static(ID p_id, bool p_static) {
Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
E->get()._static = p_static;
}
-void BroadPhase3DBasic::remove(ID p_id) {
+void BroadPhase3DBasic::remove(ID p_id) {
Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND(!E);
List<PairKey> to_erase;
//unpair must be done immediately on removal to avoid potential invalid pointers
for (Map<PairKey, void *>::Element *F = pair_map.front(); F; F = F->next()) {
-
if (F->key().a == p_id || F->key().b == p_id) {
-
if (unpair_callback) {
Element *elem_A = &element_map[F->key().a];
Element *elem_B = &element_map[F->key().b];
@@ -78,7 +74,6 @@ void BroadPhase3DBasic::remove(ID p_id) {
}
}
while (to_erase.size()) {
-
pair_map.erase(to_erase.front()->get());
to_erase.pop_front();
}
@@ -86,38 +81,35 @@ void BroadPhase3DBasic::remove(ID p_id) {
}
CollisionObject3DSW *BroadPhase3DBasic::get_object(ID p_id) const {
-
const Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND_V(!E, nullptr);
return E->get().owner;
}
-bool BroadPhase3DBasic::is_static(ID p_id) const {
+bool BroadPhase3DBasic::is_static(ID p_id) const {
const Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND_V(!E, false);
return E->get()._static;
}
-int BroadPhase3DBasic::get_subindex(ID p_id) const {
+int BroadPhase3DBasic::get_subindex(ID p_id) const {
const Map<ID, Element>::Element *E = element_map.find(p_id);
ERR_FAIL_COND_V(!E, -1);
return E->get().subindex;
}
int BroadPhase3DBasic::cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) {
-
int rc = 0;
for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) {
-
const AABB aabb = E->get().aabb;
if (aabb.has_point(p_point)) {
-
p_results[rc] = E->get().owner;
p_result_indices[rc] = E->get().subindex;
rc++;
- if (rc >= p_max_results)
+ if (rc >= p_max_results) {
break;
+ }
}
}
@@ -125,38 +117,35 @@ int BroadPhase3DBasic::cull_point(const Vector3 &p_point, CollisionObject3DSW **
}
int BroadPhase3DBasic::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) {
-
int rc = 0;
for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) {
-
const AABB aabb = E->get().aabb;
if (aabb.intersects_segment(p_from, p_to)) {
-
p_results[rc] = E->get().owner;
p_result_indices[rc] = E->get().subindex;
rc++;
- if (rc >= p_max_results)
+ if (rc >= p_max_results) {
break;
+ }
}
}
return rc;
}
-int BroadPhase3DBasic::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) {
+int BroadPhase3DBasic::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) {
int rc = 0;
for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) {
-
const AABB aabb = E->get().aabb;
if (aabb.intersects(p_aabb)) {
-
p_results[rc] = E->get().owner;
p_result_indices[rc] = E->get().subindex;
rc++;
- if (rc >= p_max_results)
+ if (rc >= p_max_results) {
break;
+ }
}
}
@@ -164,28 +153,25 @@ int BroadPhase3DBasic::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_res
}
void BroadPhase3DBasic::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) {
-
pair_userdata = p_userdata;
pair_callback = p_pair_callback;
}
-void BroadPhase3DBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) {
+void BroadPhase3DBasic::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) {
unpair_userdata = p_userdata;
unpair_callback = p_unpair_callback;
}
void BroadPhase3DBasic::update() {
-
// recompute pairs
for (Map<ID, Element>::Element *I = element_map.front(); I; I = I->next()) {
-
for (Map<ID, Element>::Element *J = I->next(); J; J = J->next()) {
-
Element *elem_A = &I->get();
Element *elem_B = &J->get();
- if (elem_A->owner == elem_B->owner)
+ if (elem_A->owner == elem_B->owner) {
continue;
+ }
bool pair_ok = elem_A->aabb.intersects(elem_B->aabb) && (!elem_A->_static || !elem_B->_static);
@@ -194,16 +180,17 @@ void BroadPhase3DBasic::update() {
Map<PairKey, void *>::Element *E = pair_map.find(key);
if (!pair_ok && E) {
- if (unpair_callback)
+ if (unpair_callback) {
unpair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, E->get(), unpair_userdata);
+ }
pair_map.erase(key);
}
if (pair_ok && !E) {
-
void *data = nullptr;
- if (pair_callback)
+ if (pair_callback) {
data = pair_callback(elem_A->owner, elem_A->subindex, elem_B->owner, elem_B->subindex, unpair_userdata);
+ }
pair_map.insert(key, data);
}
}
@@ -211,12 +198,10 @@ void BroadPhase3DBasic::update() {
}
BroadPhase3DSW *BroadPhase3DBasic::_create() {
-
return memnew(BroadPhase3DBasic);
}
BroadPhase3DBasic::BroadPhase3DBasic() {
-
current = 1;
unpair_callback = nullptr;
unpair_userdata = nullptr;
diff --git a/servers/physics_3d/broad_phase_3d_basic.h b/servers/physics_3d/broad_phase_3d_basic.h
index 563dda6931..4b644bf818 100644
--- a/servers/physics_3d/broad_phase_3d_basic.h
+++ b/servers/physics_3d/broad_phase_3d_basic.h
@@ -35,9 +35,7 @@
#include "core/map.h"
class BroadPhase3DBasic : public BroadPhase3DSW {
-
struct Element {
-
CollisionObject3DSW *owner;
bool _static;
AABB aabb;
@@ -49,7 +47,6 @@ class BroadPhase3DBasic : public BroadPhase3DSW {
ID current;
struct PairKey {
-
union {
struct {
ID a;
diff --git a/servers/physics_3d/broad_phase_3d_sw.h b/servers/physics_3d/broad_phase_3d_sw.h
index 5950489619..081e75810f 100644
--- a/servers/physics_3d/broad_phase_3d_sw.h
+++ b/servers/physics_3d/broad_phase_3d_sw.h
@@ -37,7 +37,6 @@
class CollisionObject3DSW;
class BroadPhase3DSW {
-
public:
typedef BroadPhase3DSW *(*CreateFunction)();
diff --git a/servers/physics_3d/broad_phase_octree.cpp b/servers/physics_3d/broad_phase_octree.cpp
index 264ab21e1e..1ace1a4fcf 100644
--- a/servers/physics_3d/broad_phase_octree.cpp
+++ b/servers/physics_3d/broad_phase_octree.cpp
@@ -32,81 +32,73 @@
#include "collision_object_3d_sw.h"
BroadPhase3DSW::ID BroadPhaseOctree::create(CollisionObject3DSW *p_object, int p_subindex) {
-
ID oid = octree.create(p_object, AABB(), p_subindex, false, 1 << p_object->get_type(), 0);
return oid;
}
void BroadPhaseOctree::move(ID p_id, const AABB &p_aabb) {
-
octree.move(p_id, p_aabb);
}
void BroadPhaseOctree::set_static(ID p_id, bool p_static) {
-
CollisionObject3DSW *it = octree.get(p_id);
octree.set_pairable(p_id, !p_static, 1 << it->get_type(), p_static ? 0 : 0xFFFFF); //pair everything, don't care 1?
}
-void BroadPhaseOctree::remove(ID p_id) {
+void BroadPhaseOctree::remove(ID p_id) {
octree.erase(p_id);
}
CollisionObject3DSW *BroadPhaseOctree::get_object(ID p_id) const {
-
CollisionObject3DSW *it = octree.get(p_id);
ERR_FAIL_COND_V(!it, nullptr);
return it;
}
-bool BroadPhaseOctree::is_static(ID p_id) const {
+bool BroadPhaseOctree::is_static(ID p_id) const {
return !octree.is_pairable(p_id);
}
-int BroadPhaseOctree::get_subindex(ID p_id) const {
+int BroadPhaseOctree::get_subindex(ID p_id) const {
return octree.get_subindex(p_id);
}
int BroadPhaseOctree::cull_point(const Vector3 &p_point, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) {
-
return octree.cull_point(p_point, p_results, p_max_results, p_result_indices);
}
int BroadPhaseOctree::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) {
-
return octree.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices);
}
int BroadPhaseOctree::cull_aabb(const AABB &p_aabb, CollisionObject3DSW **p_results, int p_max_results, int *p_result_indices) {
-
return octree.cull_aabb(p_aabb, p_results, p_max_results, p_result_indices);
}
void *BroadPhaseOctree::_pair_callback(void *self, OctreeElementID p_A, CollisionObject3DSW *p_object_A, int subindex_A, OctreeElementID p_B, CollisionObject3DSW *p_object_B, int subindex_B) {
-
BroadPhaseOctree *bpo = (BroadPhaseOctree *)(self);
- if (!bpo->pair_callback)
+ if (!bpo->pair_callback) {
return nullptr;
+ }
return bpo->pair_callback(p_object_A, subindex_A, p_object_B, subindex_B, bpo->pair_userdata);
}
void BroadPhaseOctree::_unpair_callback(void *self, OctreeElementID p_A, CollisionObject3DSW *p_object_A, int subindex_A, OctreeElementID p_B, CollisionObject3DSW *p_object_B, int subindex_B, void *pairdata) {
-
BroadPhaseOctree *bpo = (BroadPhaseOctree *)(self);
- if (!bpo->unpair_callback)
+ if (!bpo->unpair_callback) {
return;
+ }
bpo->unpair_callback(p_object_A, subindex_A, p_object_B, subindex_B, pairdata, bpo->unpair_userdata);
}
void BroadPhaseOctree::set_pair_callback(PairCallback p_pair_callback, void *p_userdata) {
-
pair_callback = p_pair_callback;
pair_userdata = p_userdata;
}
-void BroadPhaseOctree::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) {
+void BroadPhaseOctree::set_unpair_callback(UnpairCallback p_unpair_callback, void *p_userdata) {
unpair_callback = p_unpair_callback;
unpair_userdata = p_userdata;
}
@@ -116,7 +108,6 @@ void BroadPhaseOctree::update() {
}
BroadPhase3DSW *BroadPhaseOctree::_create() {
-
return memnew(BroadPhaseOctree);
}
diff --git a/servers/physics_3d/broad_phase_octree.h b/servers/physics_3d/broad_phase_octree.h
index 0ad59d8b0c..761a90a051 100644
--- a/servers/physics_3d/broad_phase_octree.h
+++ b/servers/physics_3d/broad_phase_octree.h
@@ -35,7 +35,6 @@
#include "core/math/octree.h"
class BroadPhaseOctree : public BroadPhase3DSW {
-
Octree<CollisionObject3DSW, true> octree;
static void *_pair_callback(void *, OctreeElementID, CollisionObject3DSW *, int, OctreeElementID, CollisionObject3DSW *, int);
diff --git a/servers/physics_3d/collision_object_3d_sw.cpp b/servers/physics_3d/collision_object_3d_sw.cpp
index 24715d211d..e12f0659e2 100644
--- a/servers/physics_3d/collision_object_3d_sw.cpp
+++ b/servers/physics_3d/collision_object_3d_sw.cpp
@@ -33,7 +33,6 @@
#include "space_3d_sw.h"
void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform &p_transform, bool p_disabled) {
-
Shape s;
s.shape = p_shape;
s.xform = p_transform;
@@ -51,7 +50,6 @@ void CollisionObject3DSW::add_shape(Shape3DSW *p_shape, const Transform &p_trans
}
void CollisionObject3DSW::set_shape(int p_index, Shape3DSW *p_shape) {
-
ERR_FAIL_INDEX(p_index, shapes.size());
shapes[p_index].shape->remove_owner(this);
shapes.write[p_index].shape = p_shape;
@@ -63,8 +61,8 @@ void CollisionObject3DSW::set_shape(int p_index, Shape3DSW *p_shape) {
//_update_shapes();
//_shapes_changed();
}
-void CollisionObject3DSW::set_shape_transform(int p_index, const Transform &p_transform) {
+void CollisionObject3DSW::set_shape_transform(int p_index, const Transform &p_transform) {
ERR_FAIL_INDEX(p_index, shapes.size());
shapes.write[p_index].xform = p_transform;
@@ -84,10 +82,8 @@ void CollisionObject3DSW::set_shape_as_disabled(int p_idx, bool p_enable) {
}
void CollisionObject3DSW::remove_shape(Shape3DSW *p_shape) {
-
//remove a shape, all the times it appears
for (int i = 0; i < shapes.size(); i++) {
-
if (shapes[i].shape == p_shape) {
remove_shape(i);
i--;
@@ -96,13 +92,12 @@ void CollisionObject3DSW::remove_shape(Shape3DSW *p_shape) {
}
void CollisionObject3DSW::remove_shape(int p_index) {
-
//remove anything from shape to be erased to end, so subindices don't change
ERR_FAIL_INDEX(p_index, shapes.size());
for (int i = p_index; i < shapes.size(); i++) {
-
- if (shapes[i].bpid == 0)
+ if (shapes[i].bpid == 0) {
continue;
+ }
//should never get here with a null owner
space->get_broadphase()->remove(shapes[i].bpid);
shapes.write[i].bpid = 0;
@@ -118,12 +113,14 @@ void CollisionObject3DSW::remove_shape(int p_index) {
}
void CollisionObject3DSW::_set_static(bool p_static) {
- if (_static == p_static)
+ if (_static == p_static) {
return;
+ }
_static = p_static;
- if (!space)
+ if (!space) {
return;
+ }
for (int i = 0; i < get_shape_count(); i++) {
const Shape &s = shapes[i];
if (s.bpid > 0) {
@@ -133,9 +130,7 @@ void CollisionObject3DSW::_set_static(bool p_static) {
}
void CollisionObject3DSW::_unregister_shapes() {
-
for (int i = 0; i < shapes.size(); i++) {
-
Shape &s = shapes.write[i];
if (s.bpid > 0) {
space->get_broadphase()->remove(s.bpid);
@@ -145,12 +140,11 @@ void CollisionObject3DSW::_unregister_shapes() {
}
void CollisionObject3DSW::_update_shapes() {
-
- if (!space)
+ if (!space) {
return;
+ }
for (int i = 0; i < shapes.size(); i++) {
-
Shape &s = shapes.write[i];
if (s.bpid == 0) {
s.bpid = space->get_broadphase()->create(this, i);
@@ -172,12 +166,11 @@ void CollisionObject3DSW::_update_shapes() {
}
void CollisionObject3DSW::_update_shapes_with_motion(const Vector3 &p_motion) {
-
- if (!space)
+ if (!space) {
return;
+ }
for (int i = 0; i < shapes.size(); i++) {
-
Shape &s = shapes.write[i];
if (s.bpid == 0) {
s.bpid = space->get_broadphase()->create(this, i);
@@ -196,13 +189,10 @@ void CollisionObject3DSW::_update_shapes_with_motion(const Vector3 &p_motion) {
}
void CollisionObject3DSW::_set_space(Space3DSW *p_space) {
-
if (space) {
-
space->remove_object(this);
for (int i = 0; i < shapes.size(); i++) {
-
Shape &s = shapes.write[i];
if (s.bpid) {
space->get_broadphase()->remove(s.bpid);
@@ -214,21 +204,18 @@ void CollisionObject3DSW::_set_space(Space3DSW *p_space) {
space = p_space;
if (space) {
-
space->add_object(this);
_update_shapes();
}
}
void CollisionObject3DSW::_shape_changed() {
-
_update_shapes();
_shapes_changed();
}
CollisionObject3DSW::CollisionObject3DSW(Type p_type) :
pending_shape_update_list(this) {
-
_static = true;
type = p_type;
space = nullptr;
diff --git a/servers/physics_3d/collision_object_3d_sw.h b/servers/physics_3d/collision_object_3d_sw.h
index c5773d0c61..9506f14402 100644
--- a/servers/physics_3d/collision_object_3d_sw.h
+++ b/servers/physics_3d/collision_object_3d_sw.h
@@ -59,7 +59,6 @@ private:
uint32_t collision_mask;
struct Shape {
-
Transform xform;
Transform xform_inv;
BroadPhase3DSW::ID bpid;
@@ -92,7 +91,9 @@ protected:
#endif
transform = p_transform;
- if (p_update_shapes) _update_shapes();
+ if (p_update_shapes) {
+ _update_shapes();
+ }
}
_FORCE_INLINE_ void _set_inv_transform(const Transform &p_transform) { inv_transform = p_transform; }
void _set_static(bool p_static);
diff --git a/servers/physics_3d/collision_solver_3d_sat.cpp b/servers/physics_3d/collision_solver_3d_sat.cpp
index 5096b080ab..736222c7d9 100644
--- a/servers/physics_3d/collision_solver_3d_sat.cpp
+++ b/servers/physics_3d/collision_solver_3d_sat.cpp
@@ -34,7 +34,6 @@
#define _EDGE_IS_VALID_SUPPORT_THRESHOLD 0.02
struct _CollectorCallback {
-
CollisionSolver3DSW::CallbackResult callback;
void *userdata;
bool swap;
@@ -43,18 +42,17 @@ struct _CollectorCallback {
Vector3 *prev_axis;
_FORCE_INLINE_ void call(const Vector3 &p_point_A, const Vector3 &p_point_B) {
-
- if (swap)
+ if (swap) {
callback(p_point_B, p_point_A, userdata);
- else
+ } else {
callback(p_point_A, p_point_B, userdata);
+ }
}
};
typedef void (*GenerateContactsFunc)(const Vector3 *, int, const Vector3 *, int, _CollectorCallback *);
static void _generate_contacts_point_point(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A != 1);
ERR_FAIL_COND(p_point_count_B != 1);
@@ -64,7 +62,6 @@ static void _generate_contacts_point_point(const Vector3 *p_points_A, int p_poin
}
static void _generate_contacts_point_edge(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A != 1);
ERR_FAIL_COND(p_point_count_B != 2);
@@ -75,7 +72,6 @@ static void _generate_contacts_point_edge(const Vector3 *p_points_A, int p_point
}
static void _generate_contacts_point_face(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A != 1);
ERR_FAIL_COND(p_point_count_B < 3);
@@ -87,7 +83,6 @@ static void _generate_contacts_point_face(const Vector3 *p_points_A, int p_point
}
static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A != 2);
ERR_FAIL_COND(p_point_count_B != 2); // circle is actually a 4x3 matrix
@@ -99,7 +94,6 @@ static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_
Vector3 c = rel_A.cross(rel_B).cross(rel_B);
if (Math::is_zero_approx(rel_A.dot(c))) {
-
// should handle somehow..
//ERR_PRINT("TODO FIX");
//return;
@@ -123,10 +117,11 @@ static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_
real_t d = (c.dot(p_points_B[0]) - p_points_A[0].dot(c)) / rel_A.dot(c);
- if (d < 0.0)
+ if (d < 0.0) {
d = 0.0;
- else if (d > 1.0)
+ } else if (d > 1.0) {
d = 1.0;
+ }
Vector3 closest_A = p_points_A[0] + rel_A * d;
Vector3 closest_B = Geometry::get_closest_point_to_segment_uncapped(closest_A, p_points_B);
@@ -134,7 +129,6 @@ static void _generate_contacts_edge_edge(const Vector3 *p_points_A, int p_point_
}
static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A < 2);
ERR_FAIL_COND(p_point_count_B < 3);
@@ -150,7 +144,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_
// copy A points to clipbuf_src
for (int i = 0; i < p_point_count_A; i++) {
-
clipbuf_src[i] = p_points_A[i];
}
@@ -158,7 +151,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_
// go through all of B points
for (int i = 0; i < p_point_count_B; i++) {
-
int i_n = (i + 1) % p_point_count_B;
Vector3 edge0_B = p_points_B[i];
@@ -172,7 +164,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_
int dst_idx = 0;
bool edge = clipbuf_len == 2;
for (int j = 0; j < clipbuf_len; j++) {
-
int j_n = (j + 1) % clipbuf_len;
Vector3 edge0_A = clipbuf_src[j];
@@ -190,7 +181,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_
// check for different sides and non coplanar
//if ( (dist0*dist1) < -CMP_EPSILON && !(edge && j)) {
if ((dist0 * dist1) < 0 && !(edge && j)) {
-
// calculate intersection
Vector3 rel = edge1_A - edge0_A;
real_t den = clip.normal.dot(rel);
@@ -211,7 +201,6 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_
//Plane plane_A(p_points_A[0],p_points_A[1],p_points_A[2]);
for (int i = 0; i < clipbuf_len; i++) {
-
real_t d = plane_B.distance_to(clipbuf_src[i]);
/*
if (d>CMP_EPSILON)
@@ -220,15 +209,15 @@ static void _generate_contacts_face_face(const Vector3 *p_points_A, int p_point_
Vector3 closest_B = clipbuf_src[i] - plane_B.normal * d;
- if (p_callback->normal.dot(clipbuf_src[i]) >= p_callback->normal.dot(closest_B))
+ if (p_callback->normal.dot(clipbuf_src[i]) >= p_callback->normal.dot(closest_B)) {
continue;
+ }
p_callback->call(clipbuf_src[i], closest_B);
}
}
static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_point_count_A, const Vector3 *p_points_B, int p_point_count_B, _CollectorCallback *p_callback) {
-
#ifdef DEBUG_ENABLED
ERR_FAIL_COND(p_point_count_A < 1);
ERR_FAIL_COND(p_point_count_B < 1);
@@ -267,7 +256,6 @@ static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_po
points_A = p_points_B;
points_B = p_points_A;
} else {
-
pointcount_B = p_point_count_B;
pointcount_A = p_point_count_A;
points_A = p_points_A;
@@ -284,7 +272,6 @@ static void _generate_contacts_from_supports(const Vector3 *p_points_A, int p_po
template <class ShapeA, class ShapeB, bool withMargin = false>
class SeparatorAxisTest {
-
const ShapeA *shape_A;
const ShapeB *shape_B;
const Transform *transform_A;
@@ -298,15 +285,14 @@ class SeparatorAxisTest {
public:
_FORCE_INLINE_ bool test_previous_axis() {
-
- if (callback && callback->prev_axis && *callback->prev_axis != Vector3())
+ if (callback && callback->prev_axis && *callback->prev_axis != Vector3()) {
return test_axis(*callback->prev_axis);
- else
+ } else {
return true;
+ }
}
_FORCE_INLINE_ bool test_axis(const Vector3 &p_axis) {
-
Vector3 axis = p_axis;
if (Math::abs(axis.x) < CMP_EPSILON &&
@@ -361,16 +347,17 @@ public:
}
_FORCE_INLINE_ void generate_contacts() {
-
// nothing to do, don't generate
- if (best_axis == Vector3(0.0, 0.0, 0.0))
+ if (best_axis == Vector3(0.0, 0.0, 0.0)) {
return;
+ }
if (!callback->callback) {
//just was checking intersection?
callback->collided = true;
- if (callback->prev_axis)
+ if (callback->prev_axis) {
*callback->prev_axis = best_axis;
+ }
return;
}
@@ -384,7 +371,6 @@ public:
}
if (withMargin) {
-
for (int i = 0; i < support_count_A; i++) {
supports_A[i] += -best_axis * margin_A;
}
@@ -398,15 +384,15 @@ public:
}
if (withMargin) {
-
for (int i = 0; i < support_count_B; i++) {
supports_B[i] += best_axis * margin_B;
}
}
callback->normal = best_axis;
- if (callback->prev_axis)
+ if (callback->prev_axis) {
*callback->prev_axis = best_axis;
+ }
_generate_contacts_from_supports(supports_A, support_count_A, supports_B, support_count_B, callback);
callback->collided = true;
@@ -430,7 +416,6 @@ typedef void (*CollisionFunc)(const Shape3DSW *, const Transform &, const Shape3
template <bool withMargin>
static void _collision_sphere_sphere(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a);
const SphereShape3DSW *sphere_B = static_cast<const SphereShape3DSW *>(p_b);
@@ -438,34 +423,36 @@ static void _collision_sphere_sphere(const Shape3DSW *p_a, const Transform &p_tr
// previous axis
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
- if (!separator.test_axis((p_transform_a.origin - p_transform_b.origin).normalized()))
+ if (!separator.test_axis((p_transform_a.origin - p_transform_b.origin).normalized())) {
return;
+ }
separator.generate_contacts();
}
template <bool withMargin>
static void _collision_sphere_box(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a);
const BoxShape3DSW *box_B = static_cast<const BoxShape3DSW *>(p_b);
SeparatorAxisTest<SphereShape3DSW, BoxShape3DSW, withMargin> separator(sphere_A, p_transform_a, box_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
// test faces
for (int i = 0; i < 3; i++) {
-
Vector3 axis = p_transform_b.basis.get_axis(i).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// calculate closest point to sphere
@@ -481,17 +468,18 @@ static void _collision_sphere_box(const Shape3DSW *p_a, const Transform &p_trans
// use point to test axis
Vector3 point_axis = (p_transform_a.origin - cpoint).normalized();
- if (!separator.test_axis(point_axis))
+ if (!separator.test_axis(point_axis)) {
return;
+ }
// test edges
for (int i = 0; i < 3; i++) {
-
Vector3 axis = point_axis.cross(p_transform_b.basis.get_axis(i)).cross(p_transform_b.basis.get_axis(i)).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
separator.generate_contacts();
@@ -499,14 +487,14 @@ static void _collision_sphere_box(const Shape3DSW *p_a, const Transform &p_trans
template <bool withMargin>
static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a);
const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b);
SeparatorAxisTest<SphereShape3DSW, CapsuleShape3DSW, withMargin> separator(sphere_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
//capsule sphere 1, sphere
@@ -514,15 +502,17 @@ static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_t
Vector3 capsule_ball_1 = p_transform_b.origin + capsule_axis;
- if (!separator.test_axis((capsule_ball_1 - p_transform_a.origin).normalized()))
+ if (!separator.test_axis((capsule_ball_1 - p_transform_a.origin).normalized())) {
return;
+ }
//capsule sphere 2, sphere
Vector3 capsule_ball_2 = p_transform_b.origin - capsule_axis;
- if (!separator.test_axis((capsule_ball_2 - p_transform_a.origin).normalized()))
+ if (!separator.test_axis((capsule_ball_2 - p_transform_a.origin).normalized())) {
return;
+ }
//capsule edge, sphere
@@ -530,8 +520,9 @@ static void _collision_sphere_capsule(const Shape3DSW *p_a, const Transform &p_t
Vector3 axis = b2a.cross(capsule_axis).cross(capsule_axis).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
separator.generate_contacts();
}
@@ -542,14 +533,14 @@ static void _collision_sphere_cylinder(const Shape3DSW *p_a, const Transform &p_
template <bool withMargin>
static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a);
const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b);
SeparatorAxisTest<SphereShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(sphere_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
const Geometry::MeshData &mesh = convex_polygon_B->get_mesh();
@@ -562,16 +553,15 @@ static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transfo
// faces of B
for (int i = 0; i < face_count; i++) {
-
Vector3 axis = p_transform_b.xform(faces[i].plane).normal;
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// edges of B
for (int i = 0; i < edge_count; i++) {
-
Vector3 v1 = p_transform_b.xform(vertices[edges[i].a]);
Vector3 v2 = p_transform_b.xform(vertices[edges[i].b]);
Vector3 v3 = p_transform_a.origin;
@@ -581,20 +571,21 @@ static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transfo
Vector3 axis = n1.cross(n2).cross(n1).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// vertices of B
for (int i = 0; i < vertex_count; i++) {
-
Vector3 v1 = p_transform_b.xform(vertices[i]);
Vector3 v2 = p_transform_a.origin;
Vector3 axis = (v2 - v1).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
separator.generate_contacts();
@@ -602,7 +593,6 @@ static void _collision_sphere_convex_polygon(const Shape3DSW *p_a, const Transfo
template <bool withMargin>
static void _collision_sphere_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const SphereShape3DSW *sphere_A = static_cast<const SphereShape3DSW *>(p_a);
const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b);
@@ -614,12 +604,12 @@ static void _collision_sphere_face(const Shape3DSW *p_a, const Transform &p_tran
p_transform_b.xform(face_B->vertex[2]),
};
- if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized()))
+ if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) {
return;
+ }
// edges and points of B
for (int i = 0; i < 3; i++) {
-
Vector3 n1 = vertex[i] - p_transform_a.origin;
if (!separator.test_axis(n1.normalized())) {
@@ -640,44 +630,43 @@ static void _collision_sphere_face(const Shape3DSW *p_a, const Transform &p_tran
template <bool withMargin>
static void _collision_box_box(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a);
const BoxShape3DSW *box_B = static_cast<const BoxShape3DSW *>(p_b);
SeparatorAxisTest<BoxShape3DSW, BoxShape3DSW, withMargin> separator(box_A, p_transform_a, box_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
// test faces of A
for (int i = 0; i < 3; i++) {
-
Vector3 axis = p_transform_a.basis.get_axis(i).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// test faces of B
for (int i = 0; i < 3; i++) {
-
Vector3 axis = p_transform_b.basis.get_axis(i).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// test combined edges
for (int i = 0; i < 3; i++) {
-
for (int j = 0; j < 3; j++) {
-
Vector3 axis = p_transform_a.basis.get_axis(i).cross(p_transform_b.basis.get_axis(j));
- if (Math::is_zero_approx(axis.length_squared()))
+ if (Math::is_zero_approx(axis.length_squared())) {
continue;
+ }
axis.normalize();
if (!separator.test_axis(axis)) {
@@ -718,18 +707,19 @@ static void _collision_box_box(const Shape3DSW *p_a, const Transform &p_transfor
//now try edges, which become cylinders!
for (int i = 0; i < 3; i++) {
-
//a ->b
Vector3 axis_a = p_transform_a.basis.get_axis(i);
- if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized()))
+ if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized())) {
return;
+ }
//b ->a
Vector3 axis_b = p_transform_b.basis.get_axis(i);
- if (!separator.test_axis(axis_ab.cross(axis_b).cross(axis_b).normalized()))
+ if (!separator.test_axis(axis_ab.cross(axis_b).cross(axis_b).normalized())) {
return;
+ }
}
}
@@ -738,22 +728,22 @@ static void _collision_box_box(const Shape3DSW *p_a, const Transform &p_transfor
template <bool withMargin>
static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a);
const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b);
SeparatorAxisTest<BoxShape3DSW, CapsuleShape3DSW, withMargin> separator(box_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
// faces of A
for (int i = 0; i < 3; i++) {
-
Vector3 axis = p_transform_a.basis.get_axis(i);
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
Vector3 cyl_axis = p_transform_b.basis.get_axis(2).normalized();
@@ -761,15 +751,16 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran
// edges of A, capsule cylinder
for (int i = 0; i < 3; i++) {
-
// cylinder
Vector3 box_axis = p_transform_a.basis.get_axis(i);
Vector3 axis = box_axis.cross(cyl_axis);
- if (Math::is_zero_approx(axis.length_squared()))
+ if (Math::is_zero_approx(axis.length_squared())) {
continue;
+ }
- if (!separator.test_axis(axis.normalized()))
+ if (!separator.test_axis(axis.normalized())) {
return;
+ }
}
// points of A, capsule cylinder
@@ -783,14 +774,16 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran
he.y *= (j * 2 - 1);
he.z *= (k * 2 - 1);
Vector3 point = p_transform_a.origin;
- for (int l = 0; l < 3; l++)
+ for (int l = 0; l < 3; l++) {
point += p_transform_a.basis.get_axis(l) * he[l];
+ }
//Vector3 axis = (point - cyl_axis * cyl_axis.dot(point)).normalized();
Vector3 axis = Plane(cyl_axis, 0).project(point).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
}
}
@@ -798,7 +791,6 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran
// capsule balls, edges of A
for (int i = 0; i < 2; i++) {
-
Vector3 capsule_axis = p_transform_b.basis.get_axis(2) * (capsule_B->get_height() * 0.5);
Vector3 sphere_pos = p_transform_b.origin + ((i == 0) ? capsule_axis : -capsule_axis);
@@ -814,17 +806,18 @@ static void _collision_box_capsule(const Shape3DSW *p_a, const Transform &p_tran
// use point to test axis
Vector3 point_axis = (sphere_pos - cpoint).normalized();
- if (!separator.test_axis(point_axis))
+ if (!separator.test_axis(point_axis)) {
return;
+ }
// test edges of A
for (int j = 0; j < 3; j++) {
-
Vector3 axis = point_axis.cross(p_transform_a.basis.get_axis(j)).cross(p_transform_a.basis.get_axis(j)).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
}
@@ -837,14 +830,14 @@ static void _collision_box_cylinder(const Shape3DSW *p_a, const Transform &p_tra
template <bool withMargin>
static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a);
const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b);
SeparatorAxisTest<BoxShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(box_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
const Geometry::MeshData &mesh = convex_polygon_B->get_mesh();
@@ -857,43 +850,40 @@ static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform
// faces of A
for (int i = 0; i < 3; i++) {
-
Vector3 axis = p_transform_a.basis.get_axis(i).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// faces of B
for (int i = 0; i < face_count; i++) {
-
Vector3 axis = p_transform_b.xform(faces[i].plane).normal;
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// A<->B edges
for (int i = 0; i < 3; i++) {
-
Vector3 e1 = p_transform_a.basis.get_axis(i);
for (int j = 0; j < edge_count; j++) {
-
Vector3 e2 = p_transform_b.basis.xform(vertices[edges[j].a]) - p_transform_b.basis.xform(vertices[edges[j].b]);
Vector3 axis = e1.cross(e2).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
}
if (withMargin) {
-
// calculate closest points between vertices and box edges
for (int v = 0; v < vertex_count; v++) {
-
Vector3 vtxb = p_transform_b.xform(vertices[v]);
Vector3 ab_vec = vtxb - p_transform_a.origin;
@@ -914,12 +904,12 @@ static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform
//now try edges, which become cylinders!
for (int i = 0; i < 3; i++) {
-
//a ->b
Vector3 axis_a = p_transform_a.basis.get_axis(i);
- if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized()))
+ if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized())) {
return;
+ }
}
}
@@ -932,17 +922,18 @@ static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform
he.y *= (j * 2 - 1);
he.z *= (k * 2 - 1);
Vector3 point = p_transform_a.origin;
- for (int l = 0; l < 3; l++)
+ for (int l = 0; l < 3; l++) {
point += p_transform_a.basis.get_axis(l) * he[l];
+ }
for (int e = 0; e < edge_count; e++) {
-
Vector3 p1 = p_transform_b.xform(vertices[edges[e].a]);
Vector3 p2 = p_transform_b.xform(vertices[edges[e].b]);
Vector3 n = (p2 - p1);
- if (!separator.test_axis((point - p2).cross(n).cross(n).normalized()))
+ if (!separator.test_axis((point - p2).cross(n).cross(n).normalized())) {
return;
+ }
}
}
}
@@ -954,7 +945,6 @@ static void _collision_box_convex_polygon(const Shape3DSW *p_a, const Transform
template <bool withMargin>
static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const BoxShape3DSW *box_A = static_cast<const BoxShape3DSW *>(p_a);
const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b);
@@ -966,38 +956,36 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transfo
p_transform_b.xform(face_B->vertex[2]),
};
- if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized()))
+ if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) {
return;
+ }
// faces of A
for (int i = 0; i < 3; i++) {
-
Vector3 axis = p_transform_a.basis.get_axis(i).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// combined edges
for (int i = 0; i < 3; i++) {
-
Vector3 e = vertex[i] - vertex[(i + 1) % 3];
for (int j = 0; j < 3; j++) {
-
Vector3 axis = p_transform_a.basis.get_axis(j);
- if (!separator.test_axis(e.cross(axis).normalized()))
+ if (!separator.test_axis(e.cross(axis).normalized())) {
return;
+ }
}
}
if (withMargin) {
-
// calculate closest points between vertices and box edges
for (int v = 0; v < 3; v++) {
-
Vector3 ab_vec = vertex[v] - p_transform_a.origin;
Vector3 cnormal_a = p_transform_a.basis.xform_inv(ab_vec);
@@ -1017,12 +1005,12 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transfo
//now try edges, which become cylinders!
for (int i = 0; i < 3; i++) {
-
//a ->b
Vector3 axis_a = p_transform_a.basis.get_axis(i);
- if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized()))
+ if (!separator.test_axis(axis_ab.cross(axis_a).cross(axis_a).normalized())) {
return;
+ }
}
}
@@ -1035,18 +1023,19 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transfo
he.y *= (j * 2 - 1);
he.z *= (k * 2 - 1);
Vector3 point = p_transform_a.origin;
- for (int l = 0; l < 3; l++)
+ for (int l = 0; l < 3; l++) {
point += p_transform_a.basis.get_axis(l) * he[l];
+ }
for (int e = 0; e < 3; e++) {
-
Vector3 p1 = vertex[e];
Vector3 p2 = vertex[(e + 1) % 3];
Vector3 n = (p2 - p1);
- if (!separator.test_axis((point - p2).cross(n).cross(n).normalized()))
+ if (!separator.test_axis((point - p2).cross(n).cross(n).normalized())) {
return;
+ }
}
}
}
@@ -1058,14 +1047,14 @@ static void _collision_box_face(const Shape3DSW *p_a, const Transform &p_transfo
template <bool withMargin>
static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a);
const CapsuleShape3DSW *capsule_B = static_cast<const CapsuleShape3DSW *>(p_b);
SeparatorAxisTest<CapsuleShape3DSW, CapsuleShape3DSW, withMargin> separator(capsule_A, p_transform_a, capsule_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
// some values
@@ -1079,34 +1068,43 @@ static void _collision_capsule_capsule(const Shape3DSW *p_a, const Transform &p_
//balls-balls
- if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_1).normalized()))
+ if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_1).normalized())) {
return;
- if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_2).normalized()))
+ }
+ if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_2).normalized())) {
return;
+ }
- if (!separator.test_axis((capsule_A_ball_2 - capsule_B_ball_1).normalized()))
+ if (!separator.test_axis((capsule_A_ball_2 - capsule_B_ball_1).normalized())) {
return;
- if (!separator.test_axis((capsule_A_ball_2 - capsule_B_ball_2).normalized()))
+ }
+ if (!separator.test_axis((capsule_A_ball_2 - capsule_B_ball_2).normalized())) {
return;
+ }
// edges-balls
- if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_1).cross(capsule_A_axis).cross(capsule_A_axis).normalized()))
+ if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_1).cross(capsule_A_axis).cross(capsule_A_axis).normalized())) {
return;
+ }
- if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_2).cross(capsule_A_axis).cross(capsule_A_axis).normalized()))
+ if (!separator.test_axis((capsule_A_ball_1 - capsule_B_ball_2).cross(capsule_A_axis).cross(capsule_A_axis).normalized())) {
return;
+ }
- if (!separator.test_axis((capsule_B_ball_1 - capsule_A_ball_1).cross(capsule_B_axis).cross(capsule_B_axis).normalized()))
+ if (!separator.test_axis((capsule_B_ball_1 - capsule_A_ball_1).cross(capsule_B_axis).cross(capsule_B_axis).normalized())) {
return;
+ }
- if (!separator.test_axis((capsule_B_ball_1 - capsule_A_ball_2).cross(capsule_B_axis).cross(capsule_B_axis).normalized()))
+ if (!separator.test_axis((capsule_B_ball_1 - capsule_A_ball_2).cross(capsule_B_axis).cross(capsule_B_axis).normalized())) {
return;
+ }
// edges
- if (!separator.test_axis(capsule_A_axis.cross(capsule_B_axis).normalized()))
+ if (!separator.test_axis(capsule_A_axis.cross(capsule_B_axis).normalized())) {
return;
+ }
separator.generate_contacts();
}
@@ -1117,14 +1115,14 @@ static void _collision_capsule_cylinder(const Shape3DSW *p_a, const Transform &p
template <bool withMargin>
static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a);
const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b);
SeparatorAxisTest<CapsuleShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(capsule_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
const Geometry::MeshData &mesh = convex_polygon_B->get_mesh();
@@ -1136,29 +1134,28 @@ static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transf
// faces of B
for (int i = 0; i < face_count; i++) {
-
Vector3 axis = p_transform_b.xform(faces[i].plane).normal;
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// edges of B, capsule cylinder
for (int i = 0; i < edge_count; i++) {
-
// cylinder
Vector3 edge_axis = p_transform_b.basis.xform(vertices[edges[i].a]) - p_transform_b.basis.xform(vertices[edges[i].b]);
Vector3 axis = edge_axis.cross(p_transform_a.basis.get_axis(2)).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// capsule balls, edges of B
for (int i = 0; i < 2; i++) {
-
// edges of B, capsule cylinder
Vector3 capsule_axis = p_transform_a.basis.get_axis(2) * (capsule_A->get_height() * 0.5);
@@ -1166,14 +1163,14 @@ static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transf
Vector3 sphere_pos = p_transform_a.origin + ((i == 0) ? capsule_axis : -capsule_axis);
for (int j = 0; j < edge_count; j++) {
-
Vector3 n1 = sphere_pos - p_transform_b.xform(vertices[edges[j].a]);
Vector3 n2 = p_transform_b.basis.xform(vertices[edges[j].a]) - p_transform_b.basis.xform(vertices[edges[j].b]);
Vector3 axis = n1.cross(n2).cross(n2).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
}
@@ -1182,7 +1179,6 @@ static void _collision_capsule_convex_polygon(const Shape3DSW *p_a, const Transf
template <bool withMargin>
static void _collision_capsule_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const CapsuleShape3DSW *capsule_A = static_cast<const CapsuleShape3DSW *>(p_a);
const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b);
@@ -1194,41 +1190,44 @@ static void _collision_capsule_face(const Shape3DSW *p_a, const Transform &p_tra
p_transform_b.xform(face_B->vertex[2]),
};
- if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized()))
+ if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) {
return;
+ }
// edges of B, capsule cylinder
Vector3 capsule_axis = p_transform_a.basis.get_axis(2) * (capsule_A->get_height() * 0.5);
for (int i = 0; i < 3; i++) {
-
// edge-cylinder
Vector3 edge_axis = vertex[i] - vertex[(i + 1) % 3];
Vector3 axis = edge_axis.cross(capsule_axis).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
- if (!separator.test_axis((p_transform_a.origin - vertex[i]).cross(capsule_axis).cross(capsule_axis).normalized()))
+ if (!separator.test_axis((p_transform_a.origin - vertex[i]).cross(capsule_axis).cross(capsule_axis).normalized())) {
return;
+ }
for (int j = 0; j < 2; j++) {
-
// point-spheres
Vector3 sphere_pos = p_transform_a.origin + ((j == 0) ? capsule_axis : -capsule_axis);
Vector3 n1 = sphere_pos - vertex[i];
- if (!separator.test_axis(n1.normalized()))
+ if (!separator.test_axis(n1.normalized())) {
return;
+ }
Vector3 n2 = edge_axis;
axis = n1.cross(n2).cross(n2);
- if (!separator.test_axis(axis.normalized()))
+ if (!separator.test_axis(axis.normalized())) {
return;
+ }
}
}
@@ -1249,14 +1248,14 @@ static void _collision_cylinder_face(const Shape3DSW *p_a, const Transform &p_tr
template <bool withMargin>
static void _collision_convex_polygon_convex_polygon(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const ConvexPolygonShape3DSW *convex_polygon_A = static_cast<const ConvexPolygonShape3DSW *>(p_a);
const ConvexPolygonShape3DSW *convex_polygon_B = static_cast<const ConvexPolygonShape3DSW *>(p_b);
SeparatorAxisTest<ConvexPolygonShape3DSW, ConvexPolygonShape3DSW, withMargin> separator(convex_polygon_A, p_transform_a, convex_polygon_B, p_transform_b, p_collector, p_margin_a, p_margin_b);
- if (!separator.test_previous_axis())
+ if (!separator.test_previous_axis()) {
return;
+ }
const Geometry::MeshData &mesh_A = convex_polygon_A->get_mesh();
@@ -1278,82 +1277,77 @@ static void _collision_convex_polygon_convex_polygon(const Shape3DSW *p_a, const
// faces of A
for (int i = 0; i < face_count_A; i++) {
-
Vector3 axis = p_transform_a.xform(faces_A[i].plane).normal;
//Vector3 axis = p_transform_a.basis.xform( faces_A[i].plane.normal ).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// faces of B
for (int i = 0; i < face_count_B; i++) {
-
Vector3 axis = p_transform_b.xform(faces_B[i].plane).normal;
//Vector3 axis = p_transform_b.basis.xform( faces_B[i].plane.normal ).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// A<->B edges
for (int i = 0; i < edge_count_A; i++) {
-
Vector3 e1 = p_transform_a.basis.xform(vertices_A[edges_A[i].a]) - p_transform_a.basis.xform(vertices_A[edges_A[i].b]);
for (int j = 0; j < edge_count_B; j++) {
-
Vector3 e2 = p_transform_b.basis.xform(vertices_B[edges_B[j].a]) - p_transform_b.basis.xform(vertices_B[edges_B[j].b]);
Vector3 axis = e1.cross(e2).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
}
if (withMargin) {
-
//vertex-vertex
for (int i = 0; i < vertex_count_A; i++) {
-
Vector3 va = p_transform_a.xform(vertices_A[i]);
for (int j = 0; j < vertex_count_B; j++) {
-
- if (!separator.test_axis((va - p_transform_b.xform(vertices_B[j])).normalized()))
+ if (!separator.test_axis((va - p_transform_b.xform(vertices_B[j])).normalized())) {
return;
+ }
}
}
//edge-vertex (shell)
for (int i = 0; i < edge_count_A; i++) {
-
Vector3 e1 = p_transform_a.basis.xform(vertices_A[edges_A[i].a]);
Vector3 e2 = p_transform_a.basis.xform(vertices_A[edges_A[i].b]);
Vector3 n = (e2 - e1);
for (int j = 0; j < vertex_count_B; j++) {
-
Vector3 e3 = p_transform_b.xform(vertices_B[j]);
- if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized()))
+ if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) {
return;
+ }
}
}
for (int i = 0; i < edge_count_B; i++) {
-
Vector3 e1 = p_transform_b.basis.xform(vertices_B[edges_B[i].a]);
Vector3 e2 = p_transform_b.basis.xform(vertices_B[edges_B[i].b]);
Vector3 n = (e2 - e1);
for (int j = 0; j < vertex_count_A; j++) {
-
Vector3 e3 = p_transform_a.xform(vertices_A[j]);
- if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized()))
+ if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) {
return;
+ }
}
}
}
@@ -1363,7 +1357,6 @@ static void _collision_convex_polygon_convex_polygon(const Shape3DSW *p_a, const
template <bool withMargin>
static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform &p_transform_a, const Shape3DSW *p_b, const Transform &p_transform_b, _CollectorCallback *p_collector, real_t p_margin_a, real_t p_margin_b) {
-
const ConvexPolygonShape3DSW *convex_polygon_A = static_cast<const ConvexPolygonShape3DSW *>(p_a);
const FaceShape3DSW *face_B = static_cast<const FaceShape3DSW *>(p_b);
@@ -1384,77 +1377,73 @@ static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform
p_transform_b.xform(face_B->vertex[2]),
};
- if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized()))
+ if (!separator.test_axis((vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]).normalized())) {
return;
+ }
// faces of A
for (int i = 0; i < face_count; i++) {
-
//Vector3 axis = p_transform_a.xform( faces[i].plane ).normal;
Vector3 axis = p_transform_a.basis.xform(faces[i].plane.normal).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
// A<->B edges
for (int i = 0; i < edge_count; i++) {
-
Vector3 e1 = p_transform_a.xform(vertices[edges[i].a]) - p_transform_a.xform(vertices[edges[i].b]);
for (int j = 0; j < 3; j++) {
-
Vector3 e2 = vertex[j] - vertex[(j + 1) % 3];
Vector3 axis = e1.cross(e2).normalized();
- if (!separator.test_axis(axis))
+ if (!separator.test_axis(axis)) {
return;
+ }
}
}
if (withMargin) {
-
//vertex-vertex
for (int i = 0; i < vertex_count; i++) {
-
Vector3 va = p_transform_a.xform(vertices[i]);
for (int j = 0; j < 3; j++) {
-
- if (!separator.test_axis((va - vertex[j]).normalized()))
+ if (!separator.test_axis((va - vertex[j]).normalized())) {
return;
+ }
}
}
//edge-vertex (shell)
for (int i = 0; i < edge_count; i++) {
-
Vector3 e1 = p_transform_a.basis.xform(vertices[edges[i].a]);
Vector3 e2 = p_transform_a.basis.xform(vertices[edges[i].b]);
Vector3 n = (e2 - e1);
for (int j = 0; j < 3; j++) {
-
Vector3 e3 = vertex[j];
- if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized()))
+ if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) {
return;
+ }
}
}
for (int i = 0; i < 3; i++) {
-
Vector3 e1 = vertex[i];
Vector3 e2 = vertex[(i + 1) % 3];
Vector3 n = (e2 - e1);
for (int j = 0; j < vertex_count; j++) {
-
Vector3 e3 = p_transform_a.xform(vertices[j]);
- if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized()))
+ if (!separator.test_axis((e1 - e3).cross(n).cross(n).normalized())) {
return;
+ }
}
}
}
@@ -1463,7 +1452,6 @@ static void _collision_convex_polygon_face(const Shape3DSW *p_a, const Transform
}
bool sat_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap, Vector3 *r_prev_axis, real_t p_margin_a, real_t p_margin_b) {
-
PhysicsServer3D::ShapeType type_A = p_shape_A->get_type();
ERR_FAIL_COND_V(type_A == PhysicsServer3D::SHAPE_PLANE, false);
diff --git a/servers/physics_3d/collision_solver_3d_sw.cpp b/servers/physics_3d/collision_solver_3d_sw.cpp
index 5d31e1f546..e2bfaf990d 100644
--- a/servers/physics_3d/collision_solver_3d_sw.cpp
+++ b/servers/physics_3d/collision_solver_3d_sw.cpp
@@ -37,10 +37,10 @@
//#define collision_solver gjk_epa_calculate_penetration
bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) {
-
const PlaneShape3DSW *plane = static_cast<const PlaneShape3DSW *>(p_shape_A);
- if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE)
+ if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE) {
return false;
+ }
Plane p = p_transform_A.xform(plane->get_plane());
static const int max_supports = 16;
@@ -52,19 +52,20 @@ bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const T
bool found = false;
for (int i = 0; i < support_count; i++) {
-
supports[i] = p_transform_B.xform(supports[i]);
- if (p.distance_to(supports[i]) >= 0)
+ if (p.distance_to(supports[i]) >= 0) {
continue;
+ }
found = true;
Vector3 support_A = p.project(supports[i]);
if (p_result_callback) {
- if (p_swap_result)
+ if (p_swap_result) {
p_result_callback(supports[i], support_A, p_userdata);
- else
+ } else {
p_result_callback(support_A, supports[i], p_userdata);
+ }
}
}
@@ -72,7 +73,6 @@ bool CollisionSolver3DSW::solve_static_plane(const Shape3DSW *p_shape_A, const T
}
bool CollisionSolver3DSW::solve_ray(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result) {
-
const RayShape3DSW *ray = static_cast<const RayShape3DSW *>(p_shape_A);
Vector3 from = p_transform_A.origin;
@@ -85,8 +85,9 @@ bool CollisionSolver3DSW::solve_ray(const Shape3DSW *p_shape_A, const Transform
to = ai.xform(to);
Vector3 p, n;
- if (!p_shape_B->intersect_segment(from, to, p, n))
+ if (!p_shape_B->intersect_segment(from, to, p, n)) {
return false;
+ }
Vector3 support_B = p_transform_B.xform(p);
if (ray->get_slips_on_slope()) {
@@ -95,16 +96,16 @@ bool CollisionSolver3DSW::solve_ray(const Shape3DSW *p_shape_A, const Transform
}
if (p_result_callback) {
- if (p_swap_result)
+ if (p_swap_result) {
p_result_callback(support_B, support_A, p_userdata);
- else
+ } else {
p_result_callback(support_A, support_B, p_userdata);
+ }
}
return true;
}
struct _ConcaveCollisionInfo {
-
const Transform *transform_A;
const Shape3DSW *shape_A;
const Transform *transform_B;
@@ -121,20 +122,19 @@ struct _ConcaveCollisionInfo {
};
void CollisionSolver3DSW::concave_callback(void *p_userdata, Shape3DSW *p_convex) {
-
_ConcaveCollisionInfo &cinfo = *(_ConcaveCollisionInfo *)(p_userdata);
cinfo.aabb_tests++;
bool collided = collision_solver(cinfo.shape_A, *cinfo.transform_A, p_convex, *cinfo.transform_B, cinfo.result_callback, cinfo.userdata, cinfo.swap_result, nullptr, cinfo.margin_A, cinfo.margin_B);
- if (!collided)
+ if (!collided) {
return;
+ }
cinfo.collided = true;
cinfo.collisions++;
}
bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, bool p_swap_result, real_t p_margin_A, real_t p_margin_B) {
-
const ConcaveShape3DSW *concave_B = static_cast<const ConcaveShape3DSW *>(p_shape_B);
_ConcaveCollisionInfo cinfo;
@@ -158,7 +158,6 @@ bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transf
AABB local_aabb;
for (int i = 0; i < 3; i++) {
-
Vector3 axis(p_transform_B.basis.get_axis(i));
real_t axis_scale = 1.0 / axis.length();
axis *= axis_scale;
@@ -180,7 +179,6 @@ bool CollisionSolver3DSW::solve_concave(const Shape3DSW *p_shape_A, const Transf
}
bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis, real_t p_margin_A, real_t p_margin_B) {
-
PhysicsServer3D::ShapeType type_A = p_shape_A->get_type();
PhysicsServer3D::ShapeType type_B = p_shape_B->get_type();
bool concave_A = p_shape_A->is_concave();
@@ -195,9 +193,9 @@ bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transfo
}
if (type_A == PhysicsServer3D::SHAPE_PLANE) {
-
- if (type_B == PhysicsServer3D::SHAPE_PLANE)
+ if (type_B == PhysicsServer3D::SHAPE_PLANE) {
return false;
+ }
if (type_B == PhysicsServer3D::SHAPE_RAY) {
return false;
}
@@ -209,9 +207,9 @@ bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transfo
}
} else if (type_A == PhysicsServer3D::SHAPE_RAY) {
-
- if (type_B == PhysicsServer3D::SHAPE_RAY)
+ if (type_B == PhysicsServer3D::SHAPE_RAY) {
return false;
+ }
if (swap) {
return solve_ray(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true);
@@ -220,35 +218,35 @@ bool CollisionSolver3DSW::solve_static(const Shape3DSW *p_shape_A, const Transfo
}
} else if (concave_B) {
-
- if (concave_A)
+ if (concave_A) {
return false;
+ }
- if (!swap)
+ if (!swap) {
return solve_concave(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, p_margin_A, p_margin_B);
- else
+ } else {
return solve_concave(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true, p_margin_A, p_margin_B);
+ }
} else {
-
return collision_solver(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, r_sep_axis, p_margin_A, p_margin_B);
}
}
void CollisionSolver3DSW::concave_distance_callback(void *p_userdata, Shape3DSW *p_convex) {
-
_ConcaveCollisionInfo &cinfo = *(_ConcaveCollisionInfo *)(p_userdata);
cinfo.aabb_tests++;
- if (cinfo.collided)
+ if (cinfo.collided) {
return;
+ }
Vector3 close_A, close_B;
cinfo.collided = !gjk_epa_calculate_distance(cinfo.shape_A, *cinfo.transform_A, p_convex, *cinfo.transform_B, close_A, close_B);
- if (cinfo.collided)
+ if (cinfo.collided) {
return;
+ }
if (!cinfo.tested || close_A.distance_squared_to(close_B) < cinfo.close_A.distance_squared_to(cinfo.close_B)) {
-
cinfo.close_A = close_A;
cinfo.close_B = close_B;
cinfo.tested = true;
@@ -258,10 +256,10 @@ void CollisionSolver3DSW::concave_distance_callback(void *p_userdata, Shape3DSW
}
bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B) {
-
const PlaneShape3DSW *plane = static_cast<const PlaneShape3DSW *>(p_shape_A);
- if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE)
+ if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE) {
return false;
+ }
Plane p = p_transform_A.xform(plane->get_plane());
static const int max_supports = 16;
@@ -275,14 +273,14 @@ bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const
real_t closest_d = 0;
for (int i = 0; i < support_count; i++) {
-
supports[i] = p_transform_B.xform(supports[i]);
real_t d = p.distance_to(supports[i]);
if (i == 0 || d < closest_d) {
closest = supports[i];
closest_d = d;
- if (d <= 0)
+ if (d <= 0) {
collided = true;
+ }
}
}
@@ -293,12 +291,11 @@ bool CollisionSolver3DSW::solve_distance_plane(const Shape3DSW *p_shape_A, const
}
bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_point_A, Vector3 &r_point_B, const AABB &p_concave_hint, Vector3 *r_sep_axis) {
-
- if (p_shape_A->is_concave())
+ if (p_shape_A->is_concave()) {
return false;
+ }
if (p_shape_B->get_type() == PhysicsServer3D::SHAPE_PLANE) {
-
Vector3 a, b;
bool col = solve_distance_plane(p_shape_B, p_transform_B, p_shape_A, p_transform_A, a, b);
r_point_A = b;
@@ -306,9 +303,9 @@ bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Trans
return !col;
} else if (p_shape_B->is_concave()) {
-
- if (p_shape_A->is_concave())
+ if (p_shape_A->is_concave()) {
return false;
+ }
const ConcaveShape3DSW *concave_B = static_cast<const ConcaveShape3DSW *>(p_shape_B);
@@ -338,7 +335,6 @@ bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Trans
AABB local_aabb;
for (int i = 0; i < 3; i++) {
-
Vector3 axis(p_transform_B.basis.get_axis(i));
real_t axis_scale = ((real_t)1.0) / axis.length();
axis *= axis_scale;
@@ -366,7 +362,6 @@ bool CollisionSolver3DSW::solve_distance(const Shape3DSW *p_shape_A, const Trans
return !cinfo.collided;
} else {
-
return gjk_epa_calculate_distance(p_shape_A, p_transform_A, p_shape_B, p_transform_B, r_point_A, r_point_B); //should pass sepaxis..
}
}
diff --git a/servers/physics_3d/constraint_3d_sw.h b/servers/physics_3d/constraint_3d_sw.h
index 5e2b00404b..081ddb0382 100644
--- a/servers/physics_3d/constraint_3d_sw.h
+++ b/servers/physics_3d/constraint_3d_sw.h
@@ -34,7 +34,6 @@
#include "body_3d_sw.h"
class Constraint3DSW {
-
Body3DSW **_body_ptr;
int _body_count;
uint64_t island_step;
diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp
index db37f261ce..d99a2532f8 100644
--- a/servers/physics_3d/gjk_epa.cpp
+++ b/servers/physics_3d/gjk_epa.cpp
@@ -123,10 +123,12 @@ struct MinkowskiDiff {
_FORCE_INLINE_ Vector3 Support ( const Vector3& d,U index ) const
{
- if ( index )
+ if ( index ) {
return ( Support1 ( d ) );
- else
+ } else {
return ( Support0 ( d ) );
+
+}
}
};
@@ -278,7 +280,9 @@ struct GJK
m_free[m_nfree++] = cs.c[i];
}
}
- if(mask==15) m_status=eStatus::Inside;
+ if(mask==15) { m_status=eStatus::Inside;
+
+}
}
else
{/* Return old simplex */
@@ -307,10 +311,14 @@ struct GJK
Vector3 axis=Vector3(0,0,0);
axis[i]=1;
appendvertice(*m_simplex, axis);
- if(EncloseOrigin()) return(true);
+ if(EncloseOrigin()) { return(true);
+
+}
removevertice(*m_simplex);
appendvertice(*m_simplex,-axis);
- if(EncloseOrigin()) return(true);
+ if(EncloseOrigin()) { return(true);
+
+}
removevertice(*m_simplex);
}
}
@@ -326,10 +334,14 @@ struct GJK
if(p.length_squared()>0)
{
appendvertice(*m_simplex, p);
- if(EncloseOrigin()) return(true);
+ if(EncloseOrigin()) { return(true);
+
+}
removevertice(*m_simplex);
appendvertice(*m_simplex,-p);
- if(EncloseOrigin()) return(true);
+ if(EncloseOrigin()) { return(true);
+
+}
removevertice(*m_simplex);
}
}
@@ -342,10 +354,14 @@ struct GJK
if(n.length_squared()>0)
{
appendvertice(*m_simplex,n);
- if(EncloseOrigin()) return(true);
+ if(EncloseOrigin()) { return(true);
+
+}
removevertice(*m_simplex);
appendvertice(*m_simplex,-n);
- if(EncloseOrigin()) return(true);
+ if(EncloseOrigin()) { return(true);
+
+}
removevertice(*m_simplex);
}
}
@@ -354,8 +370,10 @@ struct GJK
{
if(Math::abs(det( m_simplex->c[0]->w-m_simplex->c[3]->w,
m_simplex->c[1]->w-m_simplex->c[3]->w,
- m_simplex->c[2]->w-m_simplex->c[3]->w))>0)
+ m_simplex->c[2]->w-m_simplex->c[3]->w))>0) {
return(true);
+
+}
}
break;
}
@@ -513,16 +531,16 @@ struct GJK
};
struct sList
{
- sFace* root;
- U count;
- sList() : root(nullptr),count(0) {}
+ sFace* root = nullptr;
+ U count = 0;
+ sList() {}
};
struct sHorizon
{
- sFace* cf;
- sFace* ff;
- U nf;
- sHorizon() : cf(nullptr),ff(nullptr),nf(0) {}
+ sFace* cf = nullptr;
+ sFace* ff = nullptr;
+ U nf = 0;
+ sHorizon() {}
};
struct eStatus { enum _ {
Valid,
@@ -561,15 +579,23 @@ struct GJK
{
face->l[0] = nullptr;
face->l[1] = list.root;
- if(list.root) list.root->l[0]=face;
+ if(list.root) { list.root->l[0]=face;
+
+}
list.root = face;
++list.count;
}
static inline void remove(sList& list,sFace* face)
{
- if(face->l[1]) face->l[1]->l[0]=face->l[0];
- if(face->l[0]) face->l[0]->l[1]=face->l[1];
- if(face==list.root) list.root=face->l[1];
+ if(face->l[1]) { face->l[1]->l[0]=face->l[0];
+
+}
+ if(face->l[0]) { face->l[0]->l[1]=face->l[1];
+
+}
+ if(face==list.root) { list.root=face->l[1];
+
+}
--list.count;
}
@@ -650,7 +676,9 @@ struct GJK
remove(m_hull,best);
append(m_stock,best);
best=findbest();
- if(best->p>=outer.p) outer=*best;
+ if(best->p>=outer.p) { outer=*best;
+
+}
} else { m_status=eStatus::InvalidHull;break; }
} else { m_status=eStatus::AccuraryReached;break; }
} else { m_status=eStatus::OutOfVertices;break; }
@@ -679,10 +707,12 @@ struct GJK
m_status = eStatus::FallBack;
m_normal = -guess;
const real_t nl=m_normal.length();
- if(nl>0)
+ if(nl>0) {
m_normal = m_normal/nl;
- else
+ } else {
m_normal = Vector3(1,0,0);
+
+}
m_depth = 0;
m_result.rank=1;
m_result.c[0]=simplex.c[0];
@@ -716,8 +746,12 @@ struct GJK
if(forced||(face->d>=-EPA_PLANE_EPS))
{
return(face);
- } else m_status=eStatus::NonConvex;
- } else m_status=eStatus::Degenerated;
+ } else { m_status=eStatus::NonConvex;
+
+}
+ } else { m_status=eStatus::Degenerated;
+
+}
remove(m_hull,face);
append(m_stock,face);
return(nullptr);
@@ -758,7 +792,9 @@ struct GJK
if(nf)
{
bind(nf,0,f,e);
- if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf;
+ if(horizon.cf) { bind(horizon.cf,1,nf,2); } else { horizon.ff=nf;
+
+}
horizon.cf=nf;
++horizon.nf;
return(true);
@@ -847,6 +883,7 @@ bool Distance( const Shape3DSW* shape0,
}
}
+
//
bool Penetration( const Shape3DSW* shape0,
const Transform& wtrs0,
@@ -879,7 +916,9 @@ bool Penetration( const Shape3DSW* shape0,
results.normal = -epa.m_normal;
results.distance = -epa.m_depth;
return(true);
- } else results.status=sResults::EPA_Failed;
+ } else { results.status=sResults::EPA_Failed;
+
+}
}
break;
case GJK::eStatus::Failed:
@@ -891,6 +930,7 @@ bool Penetration( const Shape3DSW* shape0,
}
+
/* Symbols cleanup */
#undef GJK_MAX_ITERATIONS
@@ -915,11 +955,9 @@ bool Penetration( const Shape3DSW* shape0,
/* clang-format on */
bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, Vector3 &r_result_A, Vector3 &r_result_B) {
-
GjkEpa2::sResults res;
if (GjkEpa2::Distance(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_transform_B.origin - p_transform_A.origin, res)) {
-
r_result_A = res.witnesses[0];
r_result_B = res.witnesses[1];
return true;
@@ -929,15 +967,15 @@ bool gjk_epa_calculate_distance(const Shape3DSW *p_shape_A, const Transform &p_t
}
bool gjk_epa_calculate_penetration(const Shape3DSW *p_shape_A, const Transform &p_transform_A, const Shape3DSW *p_shape_B, const Transform &p_transform_B, CollisionSolver3DSW::CallbackResult p_result_callback, void *p_userdata, bool p_swap) {
-
GjkEpa2::sResults res;
if (GjkEpa2::Penetration(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_transform_B.origin - p_transform_A.origin, res)) {
if (p_result_callback) {
- if (p_swap)
+ if (p_swap) {
p_result_callback(res.witnesses[1], res.witnesses[0], p_userdata);
- else
+ } else {
p_result_callback(res.witnesses[0], res.witnesses[1], p_userdata);
+ }
}
return true;
}
diff --git a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp
index a072c1f3a0..9d10ede608 100644
--- a/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/cone_twist_joint_3d_sw.cpp
@@ -52,7 +52,6 @@ Written by: Marcus Hennix
#include "cone_twist_joint_3d_sw.h"
static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
-
if (Math::abs(n.z) > Math_SQRT12) {
// choose p in y-z plane
real_t a = n[1] * n[1] + n[2] * n[2];
@@ -87,7 +86,6 @@ static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
ConeTwistJoint3DSW::ConeTwistJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &rbAFrame, const Transform &rbBFrame) :
Joint3DSW(_arr, 2) {
-
A = rbA;
B = rbB;
@@ -238,7 +236,6 @@ bool ConeTwistJoint3DSW::setup(real_t p_timestep) {
}
void ConeTwistJoint3DSW::solve(real_t p_timestep) {
-
Vector3 pivotAInW = A->get_transform().xform(m_rbAFrame.origin);
Vector3 pivotBInW = B->get_transform().xform(m_rbBFrame.origin);
@@ -309,57 +306,47 @@ void ConeTwistJoint3DSW::solve(real_t p_timestep) {
}
void ConeTwistJoint3DSW::set_param(PhysicsServer3D::ConeTwistJointParam p_param, real_t p_value) {
-
switch (p_param) {
case PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN: {
-
m_swingSpan1 = p_value;
m_swingSpan2 = p_value;
} break;
case PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN: {
-
m_twistSpan = p_value;
} break;
case PhysicsServer3D::CONE_TWIST_JOINT_BIAS: {
-
m_biasFactor = p_value;
} break;
case PhysicsServer3D::CONE_TWIST_JOINT_SOFTNESS: {
-
m_limitSoftness = p_value;
} break;
case PhysicsServer3D::CONE_TWIST_JOINT_RELAXATION: {
-
m_relaxationFactor = p_value;
} break;
- case PhysicsServer3D::CONE_TWIST_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::CONE_TWIST_MAX:
+ break; // Can't happen, but silences warning
}
}
real_t ConeTwistJoint3DSW::get_param(PhysicsServer3D::ConeTwistJointParam p_param) const {
-
switch (p_param) {
case PhysicsServer3D::CONE_TWIST_JOINT_SWING_SPAN: {
-
return m_swingSpan1;
} break;
case PhysicsServer3D::CONE_TWIST_JOINT_TWIST_SPAN: {
-
return m_twistSpan;
} break;
case PhysicsServer3D::CONE_TWIST_JOINT_BIAS: {
-
return m_biasFactor;
} break;
case PhysicsServer3D::CONE_TWIST_JOINT_SOFTNESS: {
-
return m_limitSoftness;
} break;
case PhysicsServer3D::CONE_TWIST_JOINT_RELAXATION: {
-
return m_relaxationFactor;
} break;
- case PhysicsServer3D::CONE_TWIST_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::CONE_TWIST_MAX:
+ break; // Can't happen, but silences warning
}
return 0;
diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
index e15aeca842..423bbc0dfd 100644
--- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
@@ -83,7 +83,9 @@ int G6DOFRotationalLimitMotor3DSW::testLimitValue(real_t test_value) {
real_t G6DOFRotationalLimitMotor3DSW::solveAngularLimits(
real_t timeStep, Vector3 &axis, real_t jacDiagABInv,
Body3DSW *body0, Body3DSW *body1) {
- if (!needApplyTorques()) return 0.0f;
+ if (!needApplyTorques()) {
+ return 0.0f;
+ }
real_t target_velocity = m_targetVelocity;
real_t maxMotorForce = m_maxMotorForce;
@@ -137,7 +139,9 @@ real_t G6DOFRotationalLimitMotor3DSW::solveAngularLimits(
Vector3 motorImp = clippedMotorImpulse * axis;
body0->apply_torque_impulse(motorImp);
- if (body1) body1->apply_torque_impulse(-motorImp);
+ if (body1) {
+ body1->apply_torque_impulse(-motorImp);
+ }
return clippedMotorImpulse;
}
@@ -153,7 +157,6 @@ real_t G6DOFTranslationalLimitMotor3DSW::solveLinearAxis(
int limit_index,
const Vector3 &axis_normal_on_a,
const Vector3 &anchorPos) {
-
///find relative velocity
// Vector3 rel_pos1 = pointInA - body1->get_transform().origin;
// Vector3 rel_pos2 = pointInB - body2->get_transform().origin;
@@ -301,7 +304,6 @@ bool Generic6DOFJoint3DSW::testAngularLimitMotor(int axis_index) {
}
bool Generic6DOFJoint3DSW::setup(real_t p_timestep) {
-
// Clear accumulated impulses for the next simulation step
m_linearLimits.m_accumulatedImpulse = Vector3(real_t(0.), real_t(0.), real_t(0.));
int i;
@@ -325,10 +327,11 @@ bool Generic6DOFJoint3DSW::setup(real_t p_timestep) {
//linear part
for (i = 0; i < 3; i++) {
if (m_linearLimits.enable_limit[i] && m_linearLimits.isLimited(i)) {
- if (m_useLinearReferenceFrameA)
+ if (m_useLinearReferenceFrameA) {
normalWorld = m_calculatedTransformA.basis.get_axis(i);
- else
+ } else {
normalWorld = m_calculatedTransformB.basis.get_axis(i);
+ }
buildLinearJacobian(
m_jacLinear[i], normalWorld,
@@ -367,10 +370,11 @@ void Generic6DOFJoint3DSW::solve(real_t p_timestep) {
if (m_linearLimits.enable_limit[i] && m_linearLimits.isLimited(i)) {
jacDiagABInv = real_t(1.) / m_jacLinear[i].getDiagonal();
- if (m_useLinearReferenceFrameA)
+ if (m_useLinearReferenceFrameA) {
linear_axis = m_calculatedTransformA.basis.get_axis(i);
- else
+ } else {
linear_axis = m_calculatedTransformB.basis.get_axis(i);
+ }
m_linearLimits.solveLinearAxis(
m_timeStep,
@@ -386,7 +390,6 @@ void Generic6DOFJoint3DSW::solve(real_t p_timestep) {
real_t angularJacDiagABInv;
for (i = 0; i < 3; i++) {
if (m_angularLimits[i].m_enableLimit && m_angularLimits[i].needApplyTorques()) {
-
// get axis
angular_axis = getAxis(i);
@@ -409,7 +412,7 @@ real_t Generic6DOFJoint3DSW::getAngle(int axis_index) const {
return m_calculatedAxisAngleDiff[axis_index];
}
-void Generic6DOFJoint3DSW::calcAnchorPos(void) {
+void Generic6DOFJoint3DSW::calcAnchorPos() {
real_t imA = A->get_inv_mass();
real_t imB = B->get_inv_mass();
real_t weight;
@@ -424,75 +427,60 @@ void Generic6DOFJoint3DSW::calcAnchorPos(void) {
} // Generic6DOFJointSW::calcAnchorPos()
void Generic6DOFJoint3DSW::set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param, real_t p_value) {
-
ERR_FAIL_INDEX(p_axis, 3);
switch (p_param) {
case PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT: {
-
m_linearLimits.m_lowerLimit[p_axis] = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_UPPER_LIMIT: {
-
m_linearLimits.m_upperLimit[p_axis] = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS: {
-
m_linearLimits.m_limitSoftness[p_axis] = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_RESTITUTION: {
-
m_linearLimits.m_restitution[p_axis] = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_DAMPING: {
-
m_linearLimits.m_damping[p_axis] = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LOWER_LIMIT: {
-
m_angularLimits[p_axis].m_loLimit = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_UPPER_LIMIT: {
-
m_angularLimits[p_axis].m_hiLimit = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS: {
-
m_angularLimits[p_axis].m_limitSoftness = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_DAMPING: {
-
m_angularLimits[p_axis].m_damping = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_RESTITUTION: {
-
m_angularLimits[p_axis].m_bounce = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_FORCE_LIMIT: {
-
m_angularLimits[p_axis].m_maxLimitForce = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_ERP: {
-
m_angularLimits[p_axis].m_ERP = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY: {
-
m_angularLimits[p_axis].m_targetVelocity = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT: {
-
m_angularLimits[p_axis].m_maxLimitForce = p_value;
} break;
@@ -520,7 +508,8 @@ void Generic6DOFJoint3DSW::set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DO
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: {
// Not implemented in GodotPhysics3D backend
} break;
- case PhysicsServer3D::G6DOF_JOINT_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::G6DOF_JOINT_MAX:
+ break; // Can't happen, but silences warning
}
}
@@ -528,71 +517,57 @@ real_t Generic6DOFJoint3DSW::get_param(Vector3::Axis p_axis, PhysicsServer3D::G6
ERR_FAIL_INDEX_V(p_axis, 3, 0);
switch (p_param) {
case PhysicsServer3D::G6DOF_JOINT_LINEAR_LOWER_LIMIT: {
-
return m_linearLimits.m_lowerLimit[p_axis];
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_UPPER_LIMIT: {
-
return m_linearLimits.m_upperLimit[p_axis];
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS: {
-
return m_linearLimits.m_limitSoftness[p_axis];
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_RESTITUTION: {
-
return m_linearLimits.m_restitution[p_axis];
} break;
case PhysicsServer3D::G6DOF_JOINT_LINEAR_DAMPING: {
-
return m_linearLimits.m_damping[p_axis];
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LOWER_LIMIT: {
-
return m_angularLimits[p_axis].m_loLimit;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_UPPER_LIMIT: {
-
return m_angularLimits[p_axis].m_hiLimit;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS: {
-
return m_angularLimits[p_axis].m_limitSoftness;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_DAMPING: {
-
return m_angularLimits[p_axis].m_damping;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_RESTITUTION: {
-
return m_angularLimits[p_axis].m_bounce;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_FORCE_LIMIT: {
-
return m_angularLimits[p_axis].m_maxLimitForce;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_ERP: {
-
return m_angularLimits[p_axis].m_ERP;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY: {
-
return m_angularLimits[p_axis].m_targetVelocity;
} break;
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT: {
-
return m_angularLimits[p_axis].m_maxMotorForce;
} break;
@@ -620,26 +595,23 @@ real_t Generic6DOFJoint3DSW::get_param(Vector3::Axis p_axis, PhysicsServer3D::G6
case PhysicsServer3D::G6DOF_JOINT_ANGULAR_SPRING_EQUILIBRIUM_POINT: {
// Not implemented in GodotPhysics3D backend
} break;
- case PhysicsServer3D::G6DOF_JOINT_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::G6DOF_JOINT_MAX:
+ break; // Can't happen, but silences warning
}
return 0;
}
void Generic6DOFJoint3DSW::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag, bool p_value) {
-
ERR_FAIL_INDEX(p_axis, 3);
switch (p_flag) {
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT: {
-
m_linearLimits.enable_limit[p_axis] = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT: {
-
m_angularLimits[p_axis].m_enableLimit = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_MOTOR: {
-
m_angularLimits[p_axis].m_enableMotor = p_value;
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: {
@@ -651,23 +623,21 @@ void Generic6DOFJoint3DSW::set_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOF
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: {
// Not implemented in GodotPhysics3D backend
} break;
- case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX:
+ break; // Can't happen, but silences warning
}
}
-bool Generic6DOFJoint3DSW::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const {
+bool Generic6DOFJoint3DSW::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisFlag p_flag) const {
ERR_FAIL_INDEX_V(p_axis, 3, 0);
switch (p_flag) {
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT: {
-
return m_linearLimits.enable_limit[p_axis];
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT: {
-
return m_angularLimits[p_axis].m_enableLimit;
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_MOTOR: {
-
return m_angularLimits[p_axis].m_enableMotor;
} break;
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR: {
@@ -679,8 +649,9 @@ bool Generic6DOFJoint3DSW::get_flag(Vector3::Axis p_axis, PhysicsServer3D::G6DOF
case PhysicsServer3D::G6DOF_JOINT_FLAG_ENABLE_ANGULAR_SPRING: {
// Not implemented in GodotPhysics3D backend
} break;
- case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::G6DOF_JOINT_FLAG_MAX:
+ break; // Can't happen, but silences warning
}
- return 0;
+ return false;
}
diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h
index f7aa607901..cc1423a1cb 100644
--- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h
+++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h
@@ -389,7 +389,7 @@ public:
return B;
}
- virtual void calcAnchorPos(void); // overridable
+ virtual void calcAnchorPos(); // overridable
void set_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param, real_t p_value);
real_t get_param(Vector3::Axis p_axis, PhysicsServer3D::G6DOFJointAxisParam p_param) const;
diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp b/servers/physics_3d/joints/hinge_joint_3d_sw.cpp
index e76d366422..a879b4ca7f 100644
--- a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/hinge_joint_3d_sw.cpp
@@ -50,7 +50,6 @@ subject to the following restrictions:
#include "hinge_joint_3d_sw.h"
static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
-
if (Math::abs(n.z) > Math_SQRT12) {
// choose p in y-z plane
real_t a = n[1] * n[1] + n[2] * n[2];
@@ -70,7 +69,6 @@ static void plane_space(const Vector3 &n, Vector3 &p, Vector3 &q) {
HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &frameA, const Transform &frameB) :
Joint3DSW(_arr, 2) {
-
A = rbA;
B = rbB;
@@ -103,7 +101,6 @@ HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &fr
HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Vector3 &pivotInA, const Vector3 &pivotInB,
const Vector3 &axisInA, const Vector3 &axisInB) :
Joint3DSW(_arr, 2) {
-
A = rbA;
B = rbB;
@@ -158,7 +155,6 @@ HingeJoint3DSW::HingeJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Vector3 &pivo
}
bool HingeJoint3DSW::setup(real_t p_step) {
-
m_appliedImpulse = real_t(0.);
if (!m_angularOnly) {
@@ -254,7 +250,6 @@ bool HingeJoint3DSW::setup(real_t p_step) {
}
void HingeJoint3DSW::solve(real_t p_step) {
-
Vector3 pivotAInW = A->get_transform().xform(m_rbAFrame.origin);
Vector3 pivotBInW = B->get_transform().xform(m_rbBFrame.origin);
@@ -365,12 +360,14 @@ void HingeJoint3DSW::solve(real_t p_step) {
}
}
}
+
/*
void HingeJointSW::updateRHS(real_t timeStep)
{
(void)timeStep;
}
+
*/
static _FORCE_INLINE_ real_t atan2fast(real_t y, real_t x) {
@@ -397,53 +394,82 @@ real_t HingeJoint3DSW::get_hinge_angle() {
}
void HingeJoint3DSW::set_param(PhysicsServer3D::HingeJointParam p_param, real_t p_value) {
-
switch (p_param) {
-
- case PhysicsServer3D::HINGE_JOINT_BIAS: tau = p_value; break;
- case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER: m_upperLimit = p_value; break;
- case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER: m_lowerLimit = p_value; break;
- case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS: m_biasFactor = p_value; break;
- case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS: m_limitSoftness = p_value; break;
- case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION: m_relaxationFactor = p_value; break;
- case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY: m_motorTargetVelocity = p_value; break;
- case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE: m_maxMotorImpulse = p_value; break;
- case PhysicsServer3D::HINGE_JOINT_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::HINGE_JOINT_BIAS:
+ tau = p_value;
+ break;
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER:
+ m_upperLimit = p_value;
+ break;
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER:
+ m_lowerLimit = p_value;
+ break;
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS:
+ m_biasFactor = p_value;
+ break;
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS:
+ m_limitSoftness = p_value;
+ break;
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION:
+ m_relaxationFactor = p_value;
+ break;
+ case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY:
+ m_motorTargetVelocity = p_value;
+ break;
+ case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE:
+ m_maxMotorImpulse = p_value;
+ break;
+ case PhysicsServer3D::HINGE_JOINT_MAX:
+ break; // Can't happen, but silences warning
}
}
real_t HingeJoint3DSW::get_param(PhysicsServer3D::HingeJointParam p_param) const {
-
switch (p_param) {
-
- case PhysicsServer3D::HINGE_JOINT_BIAS: return tau;
- case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER: return m_upperLimit;
- case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER: return m_lowerLimit;
- case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS: return m_biasFactor;
- case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS: return m_limitSoftness;
- case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION: return m_relaxationFactor;
- case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY: return m_motorTargetVelocity;
- case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE: return m_maxMotorImpulse;
- case PhysicsServer3D::HINGE_JOINT_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::HINGE_JOINT_BIAS:
+ return tau;
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_UPPER:
+ return m_upperLimit;
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_LOWER:
+ return m_lowerLimit;
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_BIAS:
+ return m_biasFactor;
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_SOFTNESS:
+ return m_limitSoftness;
+ case PhysicsServer3D::HINGE_JOINT_LIMIT_RELAXATION:
+ return m_relaxationFactor;
+ case PhysicsServer3D::HINGE_JOINT_MOTOR_TARGET_VELOCITY:
+ return m_motorTargetVelocity;
+ case PhysicsServer3D::HINGE_JOINT_MOTOR_MAX_IMPULSE:
+ return m_maxMotorImpulse;
+ case PhysicsServer3D::HINGE_JOINT_MAX:
+ break; // Can't happen, but silences warning
}
return 0;
}
void HingeJoint3DSW::set_flag(PhysicsServer3D::HingeJointFlag p_flag, bool p_value) {
-
switch (p_flag) {
- case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT: m_useLimit = p_value; break;
- case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR: m_enableAngularMotor = p_value; break;
- case PhysicsServer3D::HINGE_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT:
+ m_useLimit = p_value;
+ break;
+ case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR:
+ m_enableAngularMotor = p_value;
+ break;
+ case PhysicsServer3D::HINGE_JOINT_FLAG_MAX:
+ break; // Can't happen, but silences warning
}
}
-bool HingeJoint3DSW::get_flag(PhysicsServer3D::HingeJointFlag p_flag) const {
+bool HingeJoint3DSW::get_flag(PhysicsServer3D::HingeJointFlag p_flag) const {
switch (p_flag) {
- case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT: return m_useLimit;
- case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR: return m_enableAngularMotor;
- case PhysicsServer3D::HINGE_JOINT_FLAG_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::HINGE_JOINT_FLAG_USE_LIMIT:
+ return m_useLimit;
+ case PhysicsServer3D::HINGE_JOINT_FLAG_ENABLE_MOTOR:
+ return m_enableAngularMotor;
+ case PhysicsServer3D::HINGE_JOINT_FLAG_MAX:
+ break; // Can't happen, but silences warning
}
return false;
diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.h b/servers/physics_3d/joints/hinge_joint_3d_sw.h
index eebead20b8..c5af888eca 100644
--- a/servers/physics_3d/joints/hinge_joint_3d_sw.h
+++ b/servers/physics_3d/joints/hinge_joint_3d_sw.h
@@ -54,7 +54,6 @@ subject to the following restrictions:
*/
class HingeJoint3DSW : public Joint3DSW {
-
union {
struct {
Body3DSW *A;
diff --git a/servers/physics_3d/joints/jacobian_entry_3d_sw.h b/servers/physics_3d/joints/jacobian_entry_3d_sw.h
index 7e605ab173..1737c21b3d 100644
--- a/servers/physics_3d/joints/jacobian_entry_3d_sw.h
+++ b/servers/physics_3d/joints/jacobian_entry_3d_sw.h
@@ -54,7 +54,7 @@ subject to the following restrictions:
class JacobianEntry3DSW {
public:
- JacobianEntry3DSW(){};
+ JacobianEntry3DSW() {}
//constraint between two different rigidbodies
JacobianEntry3DSW(
const Basis &world2A,
diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.cpp b/servers/physics_3d/joints/pin_joint_3d_sw.cpp
index 95c01bc463..230904408b 100644
--- a/servers/physics_3d/joints/pin_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/pin_joint_3d_sw.cpp
@@ -50,7 +50,6 @@ subject to the following restrictions:
#include "pin_joint_3d_sw.h"
bool PinJoint3DSW::setup(real_t p_step) {
-
m_appliedImpulse = real_t(0.);
Vector3 normal(0, 0, 0);
@@ -74,7 +73,6 @@ bool PinJoint3DSW::setup(real_t p_step) {
}
void PinJoint3DSW::solve(real_t p_step) {
-
Vector3 pivotAInW = A->get_transform().xform(m_pivotInA);
Vector3 pivotBInW = B->get_transform().xform(m_pivotInB);
@@ -111,10 +109,12 @@ void PinJoint3DSW::solve(real_t p_step) {
real_t impulseClamp = m_impulseClamp;
if (impulseClamp > 0) {
- if (impulse < -impulseClamp)
+ if (impulse < -impulseClamp) {
impulse = -impulseClamp;
- if (impulse > impulseClamp)
+ }
+ if (impulse > impulseClamp) {
impulse = impulseClamp;
+ }
}
m_appliedImpulse += impulse;
@@ -127,20 +127,27 @@ void PinJoint3DSW::solve(real_t p_step) {
}
void PinJoint3DSW::set_param(PhysicsServer3D::PinJointParam p_param, real_t p_value) {
-
switch (p_param) {
- case PhysicsServer3D::PIN_JOINT_BIAS: m_tau = p_value; break;
- case PhysicsServer3D::PIN_JOINT_DAMPING: m_damping = p_value; break;
- case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP: m_impulseClamp = p_value; break;
+ case PhysicsServer3D::PIN_JOINT_BIAS:
+ m_tau = p_value;
+ break;
+ case PhysicsServer3D::PIN_JOINT_DAMPING:
+ m_damping = p_value;
+ break;
+ case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP:
+ m_impulseClamp = p_value;
+ break;
}
}
real_t PinJoint3DSW::get_param(PhysicsServer3D::PinJointParam p_param) const {
-
switch (p_param) {
- case PhysicsServer3D::PIN_JOINT_BIAS: return m_tau;
- case PhysicsServer3D::PIN_JOINT_DAMPING: return m_damping;
- case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP: return m_impulseClamp;
+ case PhysicsServer3D::PIN_JOINT_BIAS:
+ return m_tau;
+ case PhysicsServer3D::PIN_JOINT_DAMPING:
+ return m_damping;
+ case PhysicsServer3D::PIN_JOINT_IMPULSE_CLAMP:
+ return m_impulseClamp;
}
return 0;
@@ -148,7 +155,6 @@ real_t PinJoint3DSW::get_param(PhysicsServer3D::PinJointParam p_param) const {
PinJoint3DSW::PinJoint3DSW(Body3DSW *p_body_a, const Vector3 &p_pos_a, Body3DSW *p_body_b, const Vector3 &p_pos_b) :
Joint3DSW(_arr, 2) {
-
A = p_body_a;
B = p_body_b;
m_pivotInA = p_pos_a;
diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.h b/servers/physics_3d/joints/pin_joint_3d_sw.h
index 8e81ccf5e0..0181a4455b 100644
--- a/servers/physics_3d/joints/pin_joint_3d_sw.h
+++ b/servers/physics_3d/joints/pin_joint_3d_sw.h
@@ -54,7 +54,6 @@ subject to the following restrictions:
*/
class PinJoint3DSW : public Joint3DSW {
-
union {
struct {
Body3DSW *A;
diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.cpp b/servers/physics_3d/joints/slider_joint_3d_sw.cpp
index 066c30e0f3..5b4609f24e 100644
--- a/servers/physics_3d/joints/slider_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/slider_joint_3d_sw.cpp
@@ -116,7 +116,6 @@ SliderJoint3DSW::SliderJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &
Joint3DSW(_arr, 2),
m_frameInA(frameInA),
m_frameInB(frameInB) {
-
A = rbA;
B = rbB;
@@ -129,7 +128,6 @@ SliderJoint3DSW::SliderJoint3DSW(Body3DSW *rbA, Body3DSW *rbB, const Transform &
//-----------------------------------------------------------------------------
bool SliderJoint3DSW::setup(real_t p_step) {
-
//calculate transforms
m_calculatedTransformA = A->get_transform() * m_frameInA;
m_calculatedTransformB = B->get_transform() * m_frameInB;
@@ -182,7 +180,6 @@ bool SliderJoint3DSW::setup(real_t p_step) {
//-----------------------------------------------------------------------------
void SliderJoint3DSW::solve(real_t p_step) {
-
int i;
// linear
Vector3 velA = A->get_velocity_in_local_point(m_relPosA);
@@ -304,7 +301,7 @@ void SliderJoint3DSW::solve(real_t p_step) {
//-----------------------------------------------------------------------------
-void SliderJoint3DSW::calculateTransforms(void) {
+void SliderJoint3DSW::calculateTransforms() {
m_calculatedTransformA = A->get_transform() * m_frameInA;
m_calculatedTransformB = B->get_transform() * m_frameInB;
m_realPivotAInW = m_calculatedTransformA.origin;
@@ -323,7 +320,7 @@ void SliderJoint3DSW::calculateTransforms(void) {
//-----------------------------------------------------------------------------
-void SliderJoint3DSW::testLinLimits(void) {
+void SliderJoint3DSW::testLinLimits() {
m_solveLinLim = false;
m_linPos = m_depth[0];
if (m_lowerLinLimit <= m_upperLinLimit) {
@@ -343,7 +340,7 @@ void SliderJoint3DSW::testLinLimits(void) {
//-----------------------------------------------------------------------------
-void SliderJoint3DSW::testAngLimits(void) {
+void SliderJoint3DSW::testAngLimits() {
m_angDepth = real_t(0.);
m_solveAngLim = false;
if (m_lowerAngLimit <= m_upperAngLimit) {
@@ -363,7 +360,7 @@ void SliderJoint3DSW::testAngLimits(void) {
//-----------------------------------------------------------------------------
-Vector3 SliderJoint3DSW::getAncorInA(void) {
+Vector3 SliderJoint3DSW::getAncorInA() {
Vector3 ancorInA;
ancorInA = m_realPivotAInW + (m_lowerLinLimit + m_upperLinLimit) * real_t(0.5) * m_sliderAxis;
ancorInA = A->get_transform().inverse().xform(ancorInA);
@@ -372,71 +369,137 @@ Vector3 SliderJoint3DSW::getAncorInA(void) {
//-----------------------------------------------------------------------------
-Vector3 SliderJoint3DSW::getAncorInB(void) {
+Vector3 SliderJoint3DSW::getAncorInB() {
Vector3 ancorInB;
ancorInB = m_frameInB.origin;
return ancorInB;
} // SliderJointSW::getAncorInB();
void SliderJoint3DSW::set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value) {
-
switch (p_param) {
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: m_upperLinLimit = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: m_lowerLinLimit = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: m_softnessLimLin = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: m_restitutionLimLin = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: m_dampingLimLin = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: m_softnessDirLin = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: m_restitutionDirLin = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: m_dampingDirLin = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: m_softnessOrthoLin = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: m_restitutionOrthoLin = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: m_dampingOrthoLin = p_value; break;
-
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: m_upperAngLimit = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: m_lowerAngLimit = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: m_softnessLimAng = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: m_restitutionLimAng = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: m_dampingLimAng = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: m_softnessDirAng = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: m_restitutionDirAng = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: m_dampingDirAng = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: m_softnessOrthoAng = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: m_restitutionOrthoAng = p_value; break;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: m_dampingOrthoAng = p_value; break;
-
- case PhysicsServer3D::SLIDER_JOINT_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER:
+ m_upperLinLimit = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER:
+ m_lowerLinLimit = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS:
+ m_softnessLimLin = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION:
+ m_restitutionLimLin = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING:
+ m_dampingLimLin = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS:
+ m_softnessDirLin = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION:
+ m_restitutionDirLin = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING:
+ m_dampingDirLin = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS:
+ m_softnessOrthoLin = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION:
+ m_restitutionOrthoLin = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING:
+ m_dampingOrthoLin = p_value;
+ break;
+
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER:
+ m_upperAngLimit = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER:
+ m_lowerAngLimit = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS:
+ m_softnessLimAng = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION:
+ m_restitutionLimAng = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING:
+ m_dampingLimAng = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS:
+ m_softnessDirAng = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION:
+ m_restitutionDirAng = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING:
+ m_dampingDirAng = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS:
+ m_softnessOrthoAng = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION:
+ m_restitutionOrthoAng = p_value;
+ break;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING:
+ m_dampingOrthoAng = p_value;
+ break;
+
+ case PhysicsServer3D::SLIDER_JOINT_MAX:
+ break; // Can't happen, but silences warning
}
}
real_t SliderJoint3DSW::get_param(PhysicsServer3D::SliderJointParam p_param) const {
-
switch (p_param) {
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER: return m_upperLinLimit;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER: return m_lowerLinLimit;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS: return m_softnessLimLin;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION: return m_restitutionLimLin;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING: return m_dampingLimLin;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS: return m_softnessDirLin;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION: return m_restitutionDirLin;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING: return m_dampingDirLin;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS: return m_softnessOrthoLin;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION: return m_restitutionOrthoLin;
- case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING: return m_dampingOrthoLin;
-
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER: return m_upperAngLimit;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER: return m_lowerAngLimit;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS: return m_softnessLimAng;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION: return m_restitutionLimAng;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING: return m_dampingLimAng;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS: return m_softnessDirAng;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION: return m_restitutionDirAng;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING: return m_dampingDirAng;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS: return m_softnessOrthoAng;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION: return m_restitutionOrthoAng;
- case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING: return m_dampingOrthoAng;
-
- case PhysicsServer3D::SLIDER_JOINT_MAX: break; // Can't happen, but silences warning
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_UPPER:
+ return m_upperLinLimit;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_LOWER:
+ return m_lowerLinLimit;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS:
+ return m_softnessLimLin;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION:
+ return m_restitutionLimLin;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_LIMIT_DAMPING:
+ return m_dampingLimLin;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_SOFTNESS:
+ return m_softnessDirLin;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_RESTITUTION:
+ return m_restitutionDirLin;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_MOTION_DAMPING:
+ return m_dampingDirLin;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS:
+ return m_softnessOrthoLin;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION:
+ return m_restitutionOrthoLin;
+ case PhysicsServer3D::SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING:
+ return m_dampingOrthoLin;
+
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_UPPER:
+ return m_upperAngLimit;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_LOWER:
+ return m_lowerAngLimit;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS:
+ return m_softnessLimAng;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION:
+ return m_restitutionLimAng;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_LIMIT_DAMPING:
+ return m_dampingLimAng;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS:
+ return m_softnessDirAng;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION:
+ return m_restitutionDirAng;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_MOTION_DAMPING:
+ return m_dampingDirAng;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS:
+ return m_softnessOrthoAng;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION:
+ return m_restitutionOrthoAng;
+ case PhysicsServer3D::SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING:
+ return m_dampingOrthoAng;
+
+ case PhysicsServer3D::SLIDER_JOINT_MAX:
+ break; // Can't happen, but silences warning
}
return 0;
diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.h b/servers/physics_3d/joints/slider_joint_3d_sw.h
index 18287db9c2..37394a1580 100644
--- a/servers/physics_3d/joints/slider_joint_3d_sw.h
+++ b/servers/physics_3d/joints/slider_joint_3d_sw.h
@@ -230,12 +230,12 @@ public:
bool getSolveAngLimit() { return m_solveAngLim; }
real_t getAngDepth() { return m_angDepth; }
// shared code used by ODE solver
- void calculateTransforms(void);
- void testLinLimits(void);
- void testAngLimits(void);
+ void calculateTransforms();
+ void testLinLimits();
+ void testAngLimits();
// access for PE Solver
- Vector3 getAncorInA(void);
- Vector3 getAncorInB(void);
+ Vector3 getAncorInA();
+ Vector3 getAncorInB();
void set_param(PhysicsServer3D::SliderJointParam p_param, real_t p_value);
real_t get_param(PhysicsServer3D::SliderJointParam p_param) const;
diff --git a/servers/physics_3d/joints_3d_sw.h b/servers/physics_3d/joints_3d_sw.h
index 0f2d4892a8..6a010ee771 100644
--- a/servers/physics_3d/joints_3d_sw.h
+++ b/servers/physics_3d/joints_3d_sw.h
@@ -35,7 +35,6 @@
#include "constraint_3d_sw.h"
class Joint3DSW : public Constraint3DSW {
-
public:
virtual PhysicsServer3D::JointType get_type() const = 0;
_FORCE_INLINE_ Joint3DSW(Body3DSW **p_body_ptr = nullptr, int p_body_count = 0) :
diff --git a/servers/physics_3d/physics_server_3d_sw.cpp b/servers/physics_3d/physics_server_3d_sw.cpp
index d8da6e715b..1c2329f2dc 100644
--- a/servers/physics_3d/physics_server_3d_sw.cpp
+++ b/servers/physics_3d/physics_server_3d_sw.cpp
@@ -44,48 +44,36 @@
ERR_FAIL_COND_MSG(m_object->get_space() && flushing_queries, "Can't change this state while flushing queries. Use call_deferred() or set_deferred() to change monitoring state instead.");
RID PhysicsServer3DSW::shape_create(ShapeType p_shape) {
-
Shape3DSW *shape = nullptr;
switch (p_shape) {
-
case SHAPE_PLANE: {
-
shape = memnew(PlaneShape3DSW);
} break;
case SHAPE_RAY: {
-
shape = memnew(RayShape3DSW);
} break;
case SHAPE_SPHERE: {
-
shape = memnew(SphereShape3DSW);
} break;
case SHAPE_BOX: {
-
shape = memnew(BoxShape3DSW);
} break;
case SHAPE_CAPSULE: {
-
shape = memnew(CapsuleShape3DSW);
} break;
case SHAPE_CYLINDER: {
-
ERR_FAIL_V_MSG(RID(), "CylinderShape3D is not supported in GodotPhysics3D. Please switch to Bullet in the Project Settings.");
} break;
case SHAPE_CONVEX_POLYGON: {
-
shape = memnew(ConvexPolygonShape3DSW);
} break;
case SHAPE_CONCAVE_POLYGON: {
-
shape = memnew(ConcavePolygonShape3DSW);
} break;
case SHAPE_HEIGHTMAP: {
-
shape = memnew(HeightMapShape3DSW);
} break;
case SHAPE_CUSTOM: {
-
ERR_FAIL_V(RID());
} break;
@@ -98,28 +86,24 @@ RID PhysicsServer3DSW::shape_create(ShapeType p_shape) {
};
void PhysicsServer3DSW::shape_set_data(RID p_shape, const Variant &p_data) {
-
Shape3DSW *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND(!shape);
shape->set_data(p_data);
};
void PhysicsServer3DSW::shape_set_custom_solver_bias(RID p_shape, real_t p_bias) {
-
Shape3DSW *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND(!shape);
shape->set_custom_bias(p_bias);
}
PhysicsServer3D::ShapeType PhysicsServer3DSW::shape_get_type(RID p_shape) const {
-
const Shape3DSW *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, SHAPE_CUSTOM);
return shape->get_type();
};
Variant PhysicsServer3DSW::shape_get_data(RID p_shape) const {
-
const Shape3DSW *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, Variant());
ERR_FAIL_COND_V(!shape->is_configured(), Variant());
@@ -134,14 +118,12 @@ real_t PhysicsServer3DSW::shape_get_margin(RID p_shape) const {
}
real_t PhysicsServer3DSW::shape_get_custom_solver_bias(RID p_shape) const {
-
const Shape3DSW *shape = shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0);
return shape->get_custom_bias();
}
RID PhysicsServer3DSW::space_create() {
-
Space3DSW *space = memnew(Space3DSW);
RID id = space_owner.make_rid(space);
space->set_self(id);
@@ -160,17 +142,16 @@ RID PhysicsServer3DSW::space_create() {
};
void PhysicsServer3DSW::space_set_active(RID p_space, bool p_active) {
-
Space3DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
- if (p_active)
+ if (p_active) {
active_spaces.insert(space);
- else
+ } else {
active_spaces.erase(space);
+ }
}
bool PhysicsServer3DSW::space_is_active(RID p_space) const {
-
const Space3DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, false);
@@ -178,7 +159,6 @@ bool PhysicsServer3DSW::space_is_active(RID p_space) const {
}
void PhysicsServer3DSW::space_set_param(RID p_space, SpaceParameter p_param, real_t p_value) {
-
Space3DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
@@ -186,14 +166,12 @@ void PhysicsServer3DSW::space_set_param(RID p_space, SpaceParameter p_param, rea
}
real_t PhysicsServer3DSW::space_get_param(RID p_space, SpaceParameter p_param) const {
-
const Space3DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, 0);
return space->get_param(p_param);
}
PhysicsDirectSpaceState3D *PhysicsServer3DSW::space_get_direct_state(RID p_space) {
-
Space3DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, nullptr);
ERR_FAIL_COND_V_MSG(!doing_sync || space->is_locked(), nullptr, "Space state is inaccessible right now, wait for iteration or physics process notification.");
@@ -202,28 +180,24 @@ PhysicsDirectSpaceState3D *PhysicsServer3DSW::space_get_direct_state(RID p_space
}
void PhysicsServer3DSW::space_set_debug_contacts(RID p_space, int p_max_contacts) {
-
Space3DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND(!space);
space->set_debug_contacts(p_max_contacts);
}
Vector<Vector3> PhysicsServer3DSW::space_get_contacts(RID p_space) const {
-
Space3DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, Vector<Vector3>());
return space->get_debug_contacts();
}
int PhysicsServer3DSW::space_get_contact_count(RID p_space) const {
-
Space3DSW *space = space_owner.getornull(p_space);
ERR_FAIL_COND_V(!space, 0);
return space->get_debug_contact_count();
}
RID PhysicsServer3DSW::area_create() {
-
Area3DSW *area = memnew(Area3DSW);
RID rid = area_owner.make_rid(area);
area->set_self(rid);
@@ -231,7 +205,6 @@ RID PhysicsServer3DSW::area_create() {
};
void PhysicsServer3DSW::area_set_space(RID p_area, RID p_space) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -241,26 +214,26 @@ void PhysicsServer3DSW::area_set_space(RID p_area, RID p_space) {
ERR_FAIL_COND(!space);
}
- if (area->get_space() == space)
+ if (area->get_space() == space) {
return; //pointless
+ }
area->clear_constraints();
area->set_space(space);
};
RID PhysicsServer3DSW::area_get_space(RID p_area) const {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, RID());
Space3DSW *space = area->get_space();
- if (!space)
+ if (!space) {
return RID();
+ }
return space->get_self();
};
void PhysicsServer3DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -268,7 +241,6 @@ void PhysicsServer3DSW::area_set_space_override_mode(RID p_area, AreaSpaceOverri
}
PhysicsServer3D::AreaSpaceOverrideMode PhysicsServer3DSW::area_get_space_override_mode(RID p_area) const {
-
const Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, AREA_SPACE_OVERRIDE_DISABLED);
@@ -276,7 +248,6 @@ PhysicsServer3D::AreaSpaceOverrideMode PhysicsServer3DSW::area_get_space_overrid
}
void PhysicsServer3DSW::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform, bool p_disabled) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -287,7 +258,6 @@ void PhysicsServer3DSW::area_add_shape(RID p_area, RID p_shape, const Transform
}
void PhysicsServer3DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -299,7 +269,6 @@ void PhysicsServer3DSW::area_set_shape(RID p_area, int p_shape_idx, RID p_shape)
}
void PhysicsServer3DSW::area_set_shape_transform(RID p_area, int p_shape_idx, const Transform &p_transform) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -307,14 +276,13 @@ void PhysicsServer3DSW::area_set_shape_transform(RID p_area, int p_shape_idx, co
}
int PhysicsServer3DSW::area_get_shape_count(RID p_area) const {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, -1);
return area->get_shape_count();
}
-RID PhysicsServer3DSW::area_get_shape(RID p_area, int p_shape_idx) const {
+RID PhysicsServer3DSW::area_get_shape(RID p_area, int p_shape_idx) const {
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, RID());
@@ -323,8 +291,8 @@ RID PhysicsServer3DSW::area_get_shape(RID p_area, int p_shape_idx) const {
return shape->get_self();
}
-Transform PhysicsServer3DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const {
+Transform PhysicsServer3DSW::area_get_shape_transform(RID p_area, int p_shape_idx) const {
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, Transform());
@@ -332,7 +300,6 @@ Transform PhysicsServer3DSW::area_get_shape_transform(RID p_area, int p_shape_id
}
void PhysicsServer3DSW::area_remove_shape(RID p_area, int p_shape_idx) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -340,16 +307,15 @@ void PhysicsServer3DSW::area_remove_shape(RID p_area, int p_shape_idx) {
}
void PhysicsServer3DSW::area_clear_shapes(RID p_area) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
- while (area->get_shape_count())
+ while (area->get_shape_count()) {
area->remove_shape(0);
+ }
}
void PhysicsServer3DSW::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
ERR_FAIL_INDEX(p_shape_idx, area->get_shape_count());
@@ -358,7 +324,6 @@ void PhysicsServer3DSW::area_set_shape_disabled(RID p_area, int p_shape_idx, boo
}
void PhysicsServer3DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id) {
-
if (space_owner.owns(p_area)) {
Space3DSW *space = space_owner.getornull(p_area);
p_area = space->get_default_area()->get_self();
@@ -367,8 +332,8 @@ void PhysicsServer3DSW::area_attach_object_instance_id(RID p_area, ObjectID p_id
ERR_FAIL_COND(!area);
area->set_instance_id(p_id);
}
-ObjectID PhysicsServer3DSW::area_get_object_instance_id(RID p_area) const {
+ObjectID PhysicsServer3DSW::area_get_object_instance_id(RID p_area) const {
if (space_owner.owns(p_area)) {
Space3DSW *space = space_owner.getornull(p_area);
p_area = space->get_default_area()->get_self();
@@ -379,7 +344,6 @@ ObjectID PhysicsServer3DSW::area_get_object_instance_id(RID p_area) const {
}
void PhysicsServer3DSW::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) {
-
if (space_owner.owns(p_area)) {
Space3DSW *space = space_owner.getornull(p_area);
p_area = space->get_default_area()->get_self();
@@ -390,14 +354,12 @@ void PhysicsServer3DSW::area_set_param(RID p_area, AreaParameter p_param, const
};
void PhysicsServer3DSW::area_set_transform(RID p_area, const Transform &p_transform) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
area->set_transform(p_transform);
};
Variant PhysicsServer3DSW::area_get_param(RID p_area, AreaParameter p_param) const {
-
if (space_owner.owns(p_area)) {
Space3DSW *space = space_owner.getornull(p_area);
p_area = space->get_default_area()->get_self();
@@ -409,7 +371,6 @@ Variant PhysicsServer3DSW::area_get_param(RID p_area, AreaParameter p_param) con
};
Transform PhysicsServer3DSW::area_get_transform(RID p_area) const {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, Transform());
@@ -417,7 +378,6 @@ Transform PhysicsServer3DSW::area_get_transform(RID p_area) const {
};
void PhysicsServer3DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -425,7 +385,6 @@ void PhysicsServer3DSW::area_set_collision_layer(RID p_area, uint32_t p_layer) {
}
void PhysicsServer3DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -433,7 +392,6 @@ void PhysicsServer3DSW::area_set_collision_mask(RID p_area, uint32_t p_mask) {
}
void PhysicsServer3DSW::area_set_monitorable(RID p_area, bool p_monitorable) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
FLUSH_QUERY_CHECK(area);
@@ -442,7 +400,6 @@ void PhysicsServer3DSW::area_set_monitorable(RID p_area, bool p_monitorable) {
}
void PhysicsServer3DSW::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -450,7 +407,6 @@ void PhysicsServer3DSW::area_set_monitor_callback(RID p_area, Object *p_receiver
}
void PhysicsServer3DSW::area_set_ray_pickable(RID p_area, bool p_enable) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -458,7 +414,6 @@ void PhysicsServer3DSW::area_set_ray_pickable(RID p_area, bool p_enable) {
}
bool PhysicsServer3DSW::area_is_ray_pickable(RID p_area) const {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND_V(!area, false);
@@ -466,7 +421,6 @@ bool PhysicsServer3DSW::area_is_ray_pickable(RID p_area) const {
}
void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
-
Area3DSW *area = area_owner.getornull(p_area);
ERR_FAIL_COND(!area);
@@ -476,19 +430,19 @@ void PhysicsServer3DSW::area_set_area_monitor_callback(RID p_area, Object *p_rec
/* BODY API */
RID PhysicsServer3DSW::body_create(BodyMode p_mode, bool p_init_sleeping) {
-
Body3DSW *body = memnew(Body3DSW);
- if (p_mode != BODY_MODE_RIGID)
+ if (p_mode != BODY_MODE_RIGID) {
body->set_mode(p_mode);
- if (p_init_sleeping)
+ }
+ if (p_init_sleeping) {
body->set_state(BODY_STATE_SLEEPING, p_init_sleeping);
+ }
RID rid = body_owner.make_rid(body);
body->set_self(rid);
return rid;
};
void PhysicsServer3DSW::body_set_space(RID p_body, RID p_space) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -498,26 +452,26 @@ void PhysicsServer3DSW::body_set_space(RID p_body, RID p_space) {
ERR_FAIL_COND(!space);
}
- if (body->get_space() == space)
+ if (body->get_space() == space) {
return; //pointless
+ }
body->clear_constraint_map();
body->set_space(space);
};
RID PhysicsServer3DSW::body_get_space(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, RID());
Space3DSW *space = body->get_space();
- if (!space)
+ if (!space) {
return RID();
+ }
return space->get_self();
};
void PhysicsServer3DSW::body_set_mode(RID p_body, BodyMode p_mode) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -525,7 +479,6 @@ void PhysicsServer3DSW::body_set_mode(RID p_body, BodyMode p_mode) {
};
PhysicsServer3D::BodyMode PhysicsServer3DSW::body_get_mode(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, BODY_MODE_STATIC);
@@ -533,7 +486,6 @@ PhysicsServer3D::BodyMode PhysicsServer3DSW::body_get_mode(RID p_body) const {
};
void PhysicsServer3DSW::body_add_shape(RID p_body, RID p_shape, const Transform &p_transform, bool p_disabled) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -544,7 +496,6 @@ void PhysicsServer3DSW::body_add_shape(RID p_body, RID p_shape, const Transform
}
void PhysicsServer3DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -554,8 +505,8 @@ void PhysicsServer3DSW::body_set_shape(RID p_body, int p_shape_idx, RID p_shape)
body->set_shape(p_shape_idx, shape);
}
-void PhysicsServer3DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) {
+void PhysicsServer3DSW::body_set_shape_transform(RID p_body, int p_shape_idx, const Transform &p_transform) {
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -563,14 +514,13 @@ void PhysicsServer3DSW::body_set_shape_transform(RID p_body, int p_shape_idx, co
}
int PhysicsServer3DSW::body_get_shape_count(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, -1);
return body->get_shape_count();
}
-RID PhysicsServer3DSW::body_get_shape(RID p_body, int p_shape_idx) const {
+RID PhysicsServer3DSW::body_get_shape(RID p_body, int p_shape_idx) const {
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, RID());
@@ -581,7 +531,6 @@ RID PhysicsServer3DSW::body_get_shape(RID p_body, int p_shape_idx) const {
}
void PhysicsServer3DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
@@ -591,7 +540,6 @@ void PhysicsServer3DSW::body_set_shape_disabled(RID p_body, int p_shape_idx, boo
}
Transform PhysicsServer3DSW::body_get_shape_transform(RID p_body, int p_shape_idx) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Transform());
@@ -599,7 +547,6 @@ Transform PhysicsServer3DSW::body_get_shape_transform(RID p_body, int p_shape_id
}
void PhysicsServer3DSW::body_remove_shape(RID p_body, int p_shape_idx) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -607,16 +554,15 @@ void PhysicsServer3DSW::body_remove_shape(RID p_body, int p_shape_idx) {
}
void PhysicsServer3DSW::body_clear_shapes(RID p_body) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
- while (body->get_shape_count())
+ while (body->get_shape_count()) {
body->remove_shape(0);
+ }
}
void PhysicsServer3DSW::body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -624,7 +570,6 @@ void PhysicsServer3DSW::body_set_enable_continuous_collision_detection(RID p_bod
}
bool PhysicsServer3DSW::body_is_continuous_collision_detection_enabled(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
@@ -632,7 +577,6 @@ bool PhysicsServer3DSW::body_is_continuous_collision_detection_enabled(RID p_bod
}
void PhysicsServer3DSW::body_set_collision_layer(RID p_body, uint32_t p_layer) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -641,7 +585,6 @@ void PhysicsServer3DSW::body_set_collision_layer(RID p_body, uint32_t p_layer) {
}
uint32_t PhysicsServer3DSW::body_get_collision_layer(RID p_body) const {
-
const Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -649,7 +592,6 @@ uint32_t PhysicsServer3DSW::body_get_collision_layer(RID p_body) const {
}
void PhysicsServer3DSW::body_set_collision_mask(RID p_body, uint32_t p_mask) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -658,7 +600,6 @@ void PhysicsServer3DSW::body_set_collision_mask(RID p_body, uint32_t p_mask) {
}
uint32_t PhysicsServer3DSW::body_get_collision_mask(RID p_body) const {
-
const Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -666,7 +607,6 @@ uint32_t PhysicsServer3DSW::body_get_collision_mask(RID p_body) const {
}
void PhysicsServer3DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -674,7 +614,6 @@ void PhysicsServer3DSW::body_attach_object_instance_id(RID p_body, ObjectID p_id
};
ObjectID PhysicsServer3DSW::body_get_object_instance_id(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, ObjectID());
@@ -682,13 +621,11 @@ ObjectID PhysicsServer3DSW::body_get_object_instance_id(RID p_body) const {
};
void PhysicsServer3DSW::body_set_user_flags(RID p_body, uint32_t p_flags) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
};
uint32_t PhysicsServer3DSW::body_get_user_flags(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -696,7 +633,6 @@ uint32_t PhysicsServer3DSW::body_get_user_flags(RID p_body) const {
};
void PhysicsServer3DSW::body_set_param(RID p_body, BodyParameter p_param, real_t p_value) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -704,7 +640,6 @@ void PhysicsServer3DSW::body_set_param(RID p_body, BodyParameter p_param, real_t
};
real_t PhysicsServer3DSW::body_get_param(RID p_body, BodyParameter p_param) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -725,7 +660,6 @@ real_t PhysicsServer3DSW::body_get_kinematic_safe_margin(RID p_body) const {
}
void PhysicsServer3DSW::body_set_state(RID p_body, BodyState p_state, const Variant &p_variant) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -733,7 +667,6 @@ void PhysicsServer3DSW::body_set_state(RID p_body, BodyState p_state, const Vari
};
Variant PhysicsServer3DSW::body_get_state(RID p_body, BodyState p_state) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Variant());
@@ -741,7 +674,6 @@ Variant PhysicsServer3DSW::body_get_state(RID p_body, BodyState p_state) const {
};
void PhysicsServer3DSW::body_set_applied_force(RID p_body, const Vector3 &p_force) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -750,14 +682,12 @@ void PhysicsServer3DSW::body_set_applied_force(RID p_body, const Vector3 &p_forc
};
Vector3 PhysicsServer3DSW::body_get_applied_force(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Vector3());
return body->get_applied_force();
};
void PhysicsServer3DSW::body_set_applied_torque(RID p_body, const Vector3 &p_torque) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -766,7 +696,6 @@ void PhysicsServer3DSW::body_set_applied_torque(RID p_body, const Vector3 &p_tor
};
Vector3 PhysicsServer3DSW::body_get_applied_torque(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, Vector3());
@@ -808,7 +737,6 @@ void PhysicsServer3DSW::body_apply_central_impulse(RID p_body, const Vector3 &p_
}
void PhysicsServer3DSW::body_apply_impulse(RID p_body, const Vector3 &p_pos, const Vector3 &p_impulse) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -819,7 +747,6 @@ void PhysicsServer3DSW::body_apply_impulse(RID p_body, const Vector3 &p_pos, con
};
void PhysicsServer3DSW::body_apply_torque_impulse(RID p_body, const Vector3 &p_impulse) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -830,7 +757,6 @@ void PhysicsServer3DSW::body_apply_torque_impulse(RID p_body, const Vector3 &p_i
};
void PhysicsServer3DSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis_velocity) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -845,7 +771,6 @@ void PhysicsServer3DSW::body_set_axis_velocity(RID p_body, const Vector3 &p_axis
};
void PhysicsServer3DSW::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_lock) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -854,14 +779,12 @@ void PhysicsServer3DSW::body_set_axis_lock(RID p_body, BodyAxis p_axis, bool p_l
}
bool PhysicsServer3DSW::body_is_axis_locked(RID p_body, BodyAxis p_axis) const {
-
const Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
return body->is_axis_locked(p_axis);
}
void PhysicsServer3DSW::body_add_collision_exception(RID p_body, RID p_body_b) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -870,7 +793,6 @@ void PhysicsServer3DSW::body_add_collision_exception(RID p_body, RID p_body_b) {
};
void PhysicsServer3DSW::body_remove_collision_exception(RID p_body, RID p_body_b) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -879,7 +801,6 @@ void PhysicsServer3DSW::body_remove_collision_exception(RID p_body, RID p_body_b
};
void PhysicsServer3DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_exceptions) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -889,20 +810,17 @@ void PhysicsServer3DSW::body_get_collision_exceptions(RID p_body, List<RID> *p_e
};
void PhysicsServer3DSW::body_set_contacts_reported_depth_threshold(RID p_body, real_t p_threshold) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
};
real_t PhysicsServer3DSW::body_get_contacts_reported_depth_threshold(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, 0);
return 0;
};
void PhysicsServer3DSW::body_set_omit_force_integration(RID p_body, bool p_omit) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
@@ -910,49 +828,42 @@ void PhysicsServer3DSW::body_set_omit_force_integration(RID p_body, bool p_omit)
};
bool PhysicsServer3DSW::body_is_omitting_force_integration(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
return body->get_omit_force_integration();
};
void PhysicsServer3DSW::body_set_max_contacts_reported(RID p_body, int p_contacts) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_max_contacts_reported(p_contacts);
}
int PhysicsServer3DSW::body_get_max_contacts_reported(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, -1);
return body->get_max_contacts_reported();
}
void PhysicsServer3DSW::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(), p_method, p_udata);
}
void PhysicsServer3DSW::body_set_ray_pickable(RID p_body, bool p_enable) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND(!body);
body->set_ray_pickable(p_enable);
}
bool PhysicsServer3DSW::body_is_ray_pickable(RID p_body) const {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
return body->is_ray_pickable();
}
bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result, bool p_exclude_raycast_shapes) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
ERR_FAIL_COND_V(!body->get_space(), false);
@@ -964,7 +875,6 @@ bool PhysicsServer3DSW::body_test_motion(RID p_body, const Transform &p_from, co
}
int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, SeparationResult *r_results, int p_result_max, float p_margin) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, false);
ERR_FAIL_COND_V(!body->get_space(), false);
@@ -976,7 +886,6 @@ int PhysicsServer3DSW::body_test_ray_separation(RID p_body, const Transform &p_t
}
PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) {
-
Body3DSW *body = body_owner.getornull(p_body);
ERR_FAIL_COND_V(!body, nullptr);
ERR_FAIL_COND_V_MSG(!doing_sync || body->get_space()->is_locked(), nullptr, "Body state is inaccessible right now, wait for iteration or physics process notification.");
@@ -988,7 +897,6 @@ PhysicsDirectBodyState3D *PhysicsServer3DSW::body_get_direct_state(RID p_body) {
/* JOINT API */
RID PhysicsServer3DSW::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) {
-
Body3DSW *body_A = body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
@@ -1009,15 +917,14 @@ RID PhysicsServer3DSW::joint_create_pin(RID p_body_A, const Vector3 &p_local_A,
}
void PhysicsServer3DSW::pin_joint_set_param(RID p_joint, PinJointParam p_param, real_t p_value) {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint);
pin_joint->set_param(p_param, p_value);
}
-real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {
+real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, 0);
@@ -1026,15 +933,14 @@ real_t PhysicsServer3DSW::pin_joint_get_param(RID p_joint, PinJointParam p_param
}
void PhysicsServer3DSW::pin_joint_set_local_a(RID p_joint, const Vector3 &p_A) {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint);
pin_joint->set_pos_a(p_A);
}
-Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const {
+Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, Vector3());
ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3());
@@ -1043,15 +949,14 @@ Vector3 PhysicsServer3DSW::pin_joint_get_local_a(RID p_joint) const {
}
void PhysicsServer3DSW::pin_joint_set_local_b(RID p_joint, const Vector3 &p_B) {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_PIN);
PinJoint3DSW *pin_joint = static_cast<PinJoint3DSW *>(joint);
pin_joint->set_pos_b(p_B);
}
-Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const {
+Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, Vector3());
ERR_FAIL_COND_V(joint->get_type() != JOINT_PIN, Vector3());
@@ -1060,7 +965,6 @@ Vector3 PhysicsServer3DSW::pin_joint_get_local_b(RID p_joint) const {
}
RID PhysicsServer3DSW::joint_create_hinge(RID p_body_A, const Transform &p_frame_A, RID p_body_B, const Transform &p_frame_B) {
-
Body3DSW *body_A = body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
@@ -1081,7 +985,6 @@ RID PhysicsServer3DSW::joint_create_hinge(RID p_body_A, const Transform &p_frame
}
RID PhysicsServer3DSW::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_pivot_A, const Vector3 &p_axis_A, RID p_body_B, const Vector3 &p_pivot_B, const Vector3 &p_axis_B) {
-
Body3DSW *body_A = body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
@@ -1102,15 +1005,14 @@ RID PhysicsServer3DSW::joint_create_hinge_simple(RID p_body_A, const Vector3 &p_
}
void PhysicsServer3DSW::hinge_joint_set_param(RID p_joint, HingeJointParam p_param, real_t p_value) {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_HINGE);
HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint);
hinge_joint->set_param(p_param, p_value);
}
-real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const {
+real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_param) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, 0);
@@ -1119,15 +1021,14 @@ real_t PhysicsServer3DSW::hinge_joint_get_param(RID p_joint, HingeJointParam p_p
}
void PhysicsServer3DSW::hinge_joint_set_flag(RID p_joint, HingeJointFlag p_flag, bool p_value) {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_HINGE);
HingeJoint3DSW *hinge_joint = static_cast<HingeJoint3DSW *>(joint);
hinge_joint->set_flag(p_flag, p_value);
}
-bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const {
+bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, false);
ERR_FAIL_COND_V(joint->get_type() != JOINT_HINGE, false);
@@ -1136,14 +1037,12 @@ bool PhysicsServer3DSW::hinge_joint_get_flag(RID p_joint, HingeJointFlag p_flag)
}
void PhysicsServer3DSW::joint_set_solver_priority(RID p_joint, int p_priority) {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
joint->set_priority(p_priority);
}
int PhysicsServer3DSW::joint_get_solver_priority(RID p_joint) const {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
return joint->get_priority();
@@ -1177,14 +1076,12 @@ bool PhysicsServer3DSW::joint_is_disabled_collisions_between_bodies(RID p_joint)
}
PhysicsServer3DSW::JointType PhysicsServer3DSW::joint_get_type(RID p_joint) const {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, JOINT_PIN);
return joint->get_type();
}
RID PhysicsServer3DSW::joint_create_slider(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
-
Body3DSW *body_A = body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
@@ -1205,15 +1102,14 @@ RID PhysicsServer3DSW::joint_create_slider(RID p_body_A, const Transform &p_loca
}
void PhysicsServer3DSW::slider_joint_set_param(RID p_joint, SliderJointParam p_param, real_t p_value) {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_SLIDER);
SliderJoint3DSW *slider_joint = static_cast<SliderJoint3DSW *>(joint);
slider_joint->set_param(p_param, p_value);
}
-real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const {
+real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p_param) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0);
@@ -1222,7 +1118,6 @@ real_t PhysicsServer3DSW::slider_joint_get_param(RID p_joint, SliderJointParam p
}
RID PhysicsServer3DSW::joint_create_cone_twist(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
-
Body3DSW *body_A = body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
@@ -1243,15 +1138,14 @@ RID PhysicsServer3DSW::joint_create_cone_twist(RID p_body_A, const Transform &p_
}
void PhysicsServer3DSW::cone_twist_joint_set_param(RID p_joint, ConeTwistJointParam p_param, real_t p_value) {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_CONE_TWIST);
ConeTwistJoint3DSW *cone_twist_joint = static_cast<ConeTwistJoint3DSW *>(joint);
cone_twist_joint->set_param(p_param, p_value);
}
-real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const {
+real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJointParam p_param) const {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_CONE_TWIST, 0);
@@ -1260,7 +1154,6 @@ real_t PhysicsServer3DSW::cone_twist_joint_get_param(RID p_joint, ConeTwistJoint
}
RID PhysicsServer3DSW::joint_create_generic_6dof(RID p_body_A, const Transform &p_local_frame_A, RID p_body_B, const Transform &p_local_frame_B) {
-
Body3DSW *body_A = body_owner.getornull(p_body_A);
ERR_FAIL_COND_V(!body_A, RID());
@@ -1281,15 +1174,14 @@ RID PhysicsServer3DSW::joint_create_generic_6dof(RID p_body_A, const Transform &
}
void PhysicsServer3DSW::generic_6dof_joint_set_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param, real_t p_value) {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_6DOF);
Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint);
generic_6dof_joint->set_param(p_axis, p_param, p_value);
}
-real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) {
+real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisParam p_param) {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, 0);
ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, 0);
@@ -1298,15 +1190,14 @@ real_t PhysicsServer3DSW::generic_6dof_joint_get_param(RID p_joint, Vector3::Axi
}
void PhysicsServer3DSW::generic_6dof_joint_set_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag, bool p_enable) {
-
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND(!joint);
ERR_FAIL_COND(joint->get_type() != JOINT_6DOF);
Generic6DOFJoint3DSW *generic_6dof_joint = static_cast<Generic6DOFJoint3DSW *>(joint);
generic_6dof_joint->set_flag(p_axis, p_flag, p_enable);
}
-bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) {
+bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p_axis, G6DOFJointAxisFlag p_flag) {
Joint3DSW *joint = joint_owner.getornull(p_joint);
ERR_FAIL_COND_V(!joint, false);
ERR_FAIL_COND_V(joint->get_type() != JOINT_6DOF, false);
@@ -1315,11 +1206,9 @@ bool PhysicsServer3DSW::generic_6dof_joint_get_flag(RID p_joint, Vector3::Axis p
}
void PhysicsServer3DSW::free(RID p_rid) {
-
_update_shapes(); //just in case
if (shape_owner.owns(p_rid)) {
-
Shape3DSW *shape = shape_owner.getornull(p_rid);
while (shape->get_owners().size()) {
@@ -1330,7 +1219,6 @@ void PhysicsServer3DSW::free(RID p_rid) {
shape_owner.free(p_rid);
memdelete(shape);
} else if (body_owner.owns(p_rid)) {
-
Body3DSW *body = body_owner.getornull(p_rid);
/*
@@ -1344,7 +1232,6 @@ void PhysicsServer3DSW::free(RID p_rid) {
body->set_space(nullptr);
while (body->get_shape_count()) {
-
body->remove_shape(0);
}
@@ -1352,7 +1239,6 @@ void PhysicsServer3DSW::free(RID p_rid) {
memdelete(body);
} else if (area_owner.owns(p_rid)) {
-
Area3DSW *area = area_owner.getornull(p_rid);
/*
@@ -1363,14 +1249,12 @@ void PhysicsServer3DSW::free(RID p_rid) {
area->set_space(nullptr);
while (area->get_shape_count()) {
-
area->remove_shape(0);
}
area_owner.free(p_rid);
memdelete(area);
} else if (space_owner.owns(p_rid)) {
-
Space3DSW *space = space_owner.getornull(p_rid);
while (space->get_objects().size()) {
@@ -1385,29 +1269,24 @@ void PhysicsServer3DSW::free(RID p_rid) {
space_owner.free(p_rid);
memdelete(space);
} else if (joint_owner.owns(p_rid)) {
-
Joint3DSW *joint = joint_owner.getornull(p_rid);
for (int i = 0; i < joint->get_body_count(); i++) {
-
joint->get_body_ptr()[i]->remove_constraint(joint);
}
joint_owner.free(p_rid);
memdelete(joint);
} else {
-
ERR_FAIL_MSG("Invalid ID.");
}
};
void PhysicsServer3DSW::set_active(bool p_active) {
-
active = p_active;
};
void PhysicsServer3DSW::init() {
-
doing_sync = true;
last_step = 0.001;
iterations = 8; // 8?
@@ -1416,11 +1295,11 @@ void PhysicsServer3DSW::init() {
};
void PhysicsServer3DSW::step(real_t p_step) {
-
#ifndef _3D_DISABLED
- if (!active)
+ if (!active) {
return;
+ }
_update_shapes();
@@ -1433,7 +1312,6 @@ void PhysicsServer3DSW::step(real_t p_step) {
active_objects = 0;
collision_pairs = 0;
for (Set<const Space3DSW *>::Element *E = active_spaces.front(); E; E = E->next()) {
-
stepper->step((Space3DSW *)E->get(), p_step, iterations);
island_count += E->get()->get_island_count();
active_objects += E->get()->get_active_objects();
@@ -1442,16 +1320,12 @@ void PhysicsServer3DSW::step(real_t p_step) {
#endif
}
-void PhysicsServer3DSW::sync(){
-
-};
-
void PhysicsServer3DSW::flush_queries() {
-
#ifndef _3D_DISABLED
- if (!active)
+ if (!active) {
return;
+ }
doing_sync = true;
@@ -1460,7 +1334,6 @@ void PhysicsServer3DSW::flush_queries() {
uint64_t time_beg = OS::get_singleton()->get_ticks_usec();
for (Set<const Space3DSW *>::Element *E = active_spaces.front(); E; E = E->next()) {
-
Space3DSW *space = (Space3DSW *)E->get();
space->call_queries();
}
@@ -1468,7 +1341,6 @@ void PhysicsServer3DSW::flush_queries() {
flushing_queries = false;
if (EngineDebugger::is_profiling("servers")) {
-
uint64_t total_time[Space3DSW::ELAPSED_TIME_MAX];
static const char *time_name[Space3DSW::ELAPSED_TIME_MAX] = {
"integrate_forces",
@@ -1483,7 +1355,6 @@ void PhysicsServer3DSW::flush_queries() {
}
for (Set<const Space3DSW *>::Element *E = active_spaces.front(); E; E = E->next()) {
-
for (int i = 0; i < Space3DSW::ELAPSED_TIME_MAX; i++) {
total_time[i] += E->get()->get_elapsed_time(Space3DSW::ElapsedTime(i));
}
@@ -1499,30 +1370,25 @@ void PhysicsServer3DSW::flush_queries() {
values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec() - time_beg));
values.push_front("physics");
- EngineDebugger::profiler_add_frame_data("server", values);
+ EngineDebugger::profiler_add_frame_data("servers", values);
}
#endif
};
void PhysicsServer3DSW::finish() {
-
memdelete(stepper);
memdelete(direct_state);
};
int PhysicsServer3DSW::get_process_info(ProcessInfo p_info) {
-
switch (p_info) {
-
case INFO_ACTIVE_OBJECTS: {
-
return active_objects;
} break;
case INFO_COLLISION_PAIRS: {
return collision_pairs;
} break;
case INFO_ISLAND_COUNT: {
-
return island_count;
} break;
}
@@ -1531,7 +1397,6 @@ int PhysicsServer3DSW::get_process_info(ProcessInfo p_info) {
}
void PhysicsServer3DSW::_update_shapes() {
-
while (pending_shape_update_list.first()) {
pending_shape_update_list.first()->self()->_shape_changed();
pending_shape_update_list.remove(pending_shape_update_list.first());
@@ -1539,18 +1404,17 @@ void PhysicsServer3DSW::_update_shapes() {
}
void PhysicsServer3DSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) {
-
CollCbkData *cbk = (CollCbkData *)p_userdata;
- if (cbk->max == 0)
+ if (cbk->max == 0) {
return;
+ }
if (cbk->amount == cbk->max) {
//find least deep
real_t min_depth = 1e20;
int min_depth_idx = 0;
for (int i = 0; i < cbk->amount; i++) {
-
real_t d = cbk->ptr[i * 2 + 0].distance_squared_to(cbk->ptr[i * 2 + 1]);
if (d < min_depth) {
min_depth = d;
@@ -1559,13 +1423,13 @@ void PhysicsServer3DSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 &
}
real_t d = p_point_A.distance_squared_to(p_point_B);
- if (d < min_depth)
+ if (d < min_depth) {
return;
+ }
cbk->ptr[min_depth_idx * 2 + 0] = p_point_A;
cbk->ptr[min_depth_idx * 2 + 1] = p_point_B;
} else {
-
cbk->ptr[cbk->amount * 2 + 0] = p_point_A;
cbk->ptr[cbk->amount * 2 + 1] = p_point_B;
cbk->amount++;
@@ -1583,7 +1447,3 @@ PhysicsServer3DSW::PhysicsServer3DSW() {
active = true;
flushing_queries = false;
};
-
-PhysicsServer3DSW::~PhysicsServer3DSW(){
-
-};
diff --git a/servers/physics_3d/physics_server_3d_sw.h b/servers/physics_3d/physics_server_3d_sw.h
index 6e79d9eceb..26230ef674 100644
--- a/servers/physics_3d/physics_server_3d_sw.h
+++ b/servers/physics_3d/physics_server_3d_sw.h
@@ -39,7 +39,6 @@
#include "step_3d_sw.h"
class PhysicsServer3DSW : public PhysicsServer3D {
-
GDCLASS(PhysicsServer3DSW, PhysicsServer3D);
friend class PhysicsDirectSpaceState3DSW;
@@ -74,7 +73,6 @@ public:
static PhysicsServer3DSW *singleton;
struct CollCbkData {
-
int max;
int amount;
Vector3 *ptr;
@@ -307,7 +305,7 @@ public:
virtual void soft_body_remove_all_pinned_points(RID p_body) {}
virtual void soft_body_pin_point(RID p_body, int p_point_index, bool p_pin) {}
- virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) { return 0; }
+ virtual bool soft_body_is_point_pinned(RID p_body, int p_point_index) { return false; }
/* JOINT API */
@@ -367,7 +365,7 @@ public:
virtual void set_active(bool p_active);
virtual void init();
virtual void step(real_t p_step);
- virtual void sync();
+ virtual void sync() {}
virtual void flush_queries();
virtual void finish();
@@ -376,7 +374,7 @@ public:
int get_process_info(ProcessInfo p_info);
PhysicsServer3DSW();
- ~PhysicsServer3DSW();
+ ~PhysicsServer3DSW() {}
};
#endif
diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp
index 61c32b779a..eb0e87cec0 100644
--- a/servers/physics_3d/shape_3d_sw.cpp
+++ b/servers/physics_3d/shape_3d_sw.cpp
@@ -48,7 +48,6 @@ void Shape3DSW::configure(const AABB &p_aabb) {
}
Vector3 Shape3DSW::get_support(const Vector3 &p_normal) const {
-
Vector3 res;
int amnt;
get_supports(p_normal, 1, &res, amnt);
@@ -56,7 +55,6 @@ Vector3 Shape3DSW::get_support(const Vector3 &p_normal) const {
}
void Shape3DSW::add_owner(ShapeOwner3DSW *p_owner) {
-
Map<ShapeOwner3DSW *, int>::Element *E = owners.find(p_owner);
if (E) {
E->get()++;
@@ -66,7 +64,6 @@ void Shape3DSW::add_owner(ShapeOwner3DSW *p_owner) {
}
void Shape3DSW::remove_owner(ShapeOwner3DSW *p_owner) {
-
Map<ShapeOwner3DSW *, int>::Element *E = owners.find(p_owner);
ERR_FAIL_COND(!E);
E->get()--;
@@ -76,7 +73,6 @@ void Shape3DSW::remove_owner(ShapeOwner3DSW *p_owner) {
}
bool Shape3DSW::is_owner(ShapeOwner3DSW *p_owner) const {
-
return owners.has(p_owner);
}
@@ -85,48 +81,41 @@ const Map<ShapeOwner3DSW *, int> &Shape3DSW::get_owners() const {
}
Shape3DSW::Shape3DSW() {
-
custom_bias = 0;
configured = false;
}
Shape3DSW::~Shape3DSW() {
-
ERR_FAIL_COND(owners.size());
}
Plane PlaneShape3DSW::get_plane() const {
-
return plane;
}
void PlaneShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
-
// gibberish, a plane is infinity
r_min = -1e7;
r_max = 1e7;
}
Vector3 PlaneShape3DSW::get_support(const Vector3 &p_normal) const {
-
return p_normal * 1e15;
}
bool PlaneShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
-
bool inters = plane.intersects_segment(p_begin, p_end, &r_result);
- if (inters)
+ if (inters) {
r_normal = plane.normal;
+ }
return inters;
}
bool PlaneShape3DSW::intersect_point(const Vector3 &p_point) const {
-
return plane.distance_to(p_point) < 0;
}
Vector3 PlaneShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
-
if (plane.is_point_over(p_point)) {
return plane.project(p_point);
} else {
@@ -135,23 +124,19 @@ Vector3 PlaneShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
}
Vector3 PlaneShape3DSW::get_moment_of_inertia(real_t p_mass) const {
-
return Vector3(); //wtf
}
void PlaneShape3DSW::_setup(const Plane &p_plane) {
-
plane = p_plane;
configure(AABB(Vector3(-1e4, -1e4, -1e4), Vector3(1e4 * 2, 1e4 * 2, 1e4 * 2)));
}
void PlaneShape3DSW::set_data(const Variant &p_data) {
-
_setup(p_data);
}
Variant PlaneShape3DSW::get_data() const {
-
return plane;
}
@@ -161,7 +146,6 @@ PlaneShape3DSW::PlaneShape3DSW() {
//
real_t RayShape3DSW::get_length() const {
-
return length;
}
@@ -170,24 +154,21 @@ bool RayShape3DSW::get_slips_on_slope() const {
}
void RayShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
-
// don't think this will be even used
r_min = 0;
r_max = 1;
}
Vector3 RayShape3DSW::get_support(const Vector3 &p_normal) const {
-
- if (p_normal.z > 0)
+ if (p_normal.z > 0) {
return Vector3(0, 0, length);
- else
+ } else {
return Vector3(0, 0, 0);
+ }
}
void RayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
-
if (Math::abs(p_normal.z) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
-
r_amount = 2;
r_supports[0] = Vector3(0, 0, 0);
r_supports[1] = Vector3(0, 0, length);
@@ -201,17 +182,14 @@ void RayShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s
}
bool RayShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
-
return false; //simply not possible
}
bool RayShape3DSW::intersect_point(const Vector3 &p_point) const {
-
return false; //simply not possible
}
Vector3 RayShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
-
Vector3 s[2] = {
Vector3(0, 0, 0),
Vector3(0, 0, length)
@@ -221,25 +199,21 @@ Vector3 RayShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
}
Vector3 RayShape3DSW::get_moment_of_inertia(real_t p_mass) const {
-
return Vector3();
}
void RayShape3DSW::_setup(real_t p_length, bool p_slips_on_slope) {
-
length = p_length;
slips_on_slope = p_slips_on_slope;
configure(AABB(Vector3(0, 0, 0), Vector3(0.1, 0.1, length)));
}
void RayShape3DSW::set_data(const Variant &p_data) {
-
Dictionary d = p_data;
_setup(d["length"], d["slips_on_slope"]);
}
Variant RayShape3DSW::get_data() const {
-
Dictionary d;
d["length"] = length;
d["slips_on_slope"] = slips_on_slope;
@@ -247,7 +221,6 @@ Variant RayShape3DSW::get_data() const {
}
RayShape3DSW::RayShape3DSW() {
-
length = 1;
slips_on_slope = false;
}
@@ -255,12 +228,10 @@ RayShape3DSW::RayShape3DSW() {
/********** SPHERE *************/
real_t SphereShape3DSW::get_radius() const {
-
return radius;
}
void SphereShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
-
real_t d = p_normal.dot(p_transform.origin);
// figure out scale at point
@@ -272,66 +243,56 @@ void SphereShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_
}
Vector3 SphereShape3DSW::get_support(const Vector3 &p_normal) const {
-
return p_normal * radius;
}
void SphereShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
-
*r_supports = p_normal * radius;
r_amount = 1;
}
bool SphereShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
-
return Geometry::segment_intersects_sphere(p_begin, p_end, Vector3(), radius, &r_result, &r_normal);
}
bool SphereShape3DSW::intersect_point(const Vector3 &p_point) const {
-
return p_point.length() < radius;
}
Vector3 SphereShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
-
Vector3 p = p_point;
float l = p.length();
- if (l < radius)
+ if (l < radius) {
return p_point;
+ }
return (p / l) * radius;
}
Vector3 SphereShape3DSW::get_moment_of_inertia(real_t p_mass) const {
-
real_t s = 0.4 * p_mass * radius * radius;
return Vector3(s, s, s);
}
void SphereShape3DSW::_setup(real_t p_radius) {
-
radius = p_radius;
configure(AABB(Vector3(-radius, -radius, -radius), Vector3(radius * 2.0, radius * 2.0, radius * 2.0)));
}
void SphereShape3DSW::set_data(const Variant &p_data) {
-
_setup(p_data);
}
Variant SphereShape3DSW::get_data() const {
-
return radius;
}
SphereShape3DSW::SphereShape3DSW() {
-
radius = 0;
}
/********** BOX *************/
void BoxShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
-
// no matter the angle, the box is mirrored anyway
Vector3 local_normal = p_transform.basis.xform_inv(p_normal);
@@ -343,7 +304,6 @@ void BoxShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_tra
}
Vector3 BoxShape3DSW::get_support(const Vector3 &p_normal) const {
-
Vector3 point(
(p_normal.x < 0) ? -half_extents.x : half_extents.x,
(p_normal.y < 0) ? -half_extents.y : half_extents.y,
@@ -353,17 +313,14 @@ Vector3 BoxShape3DSW::get_support(const Vector3 &p_normal) const {
}
void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
-
static const int next[3] = { 1, 2, 0 };
static const int next2[3] = { 2, 0, 1 };
for (int i = 0; i < 3; i++) {
-
Vector3 axis;
axis[i] = 1.0;
real_t dot = p_normal.dot(axis);
if (Math::abs(dot) > _FACE_IS_VALID_SUPPORT_THRESHOLD) {
-
//Vector3 axis_b;
bool neg = dot < 0;
@@ -384,7 +341,6 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s
};
for (int j = 0; j < 4; j++) {
-
point[i_n] = sign[j][0] * half_extents[i_n];
point[i_n2] = sign[j][1] * half_extents[i_n2];
r_supports[j] = neg ? -point : point;
@@ -402,12 +358,10 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s
}
for (int i = 0; i < 3; i++) {
-
Vector3 axis;
axis[i] = 1.0;
if (Math::abs(p_normal.dot(axis)) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
-
r_amount = 2;
int i_n = next[i];
@@ -440,24 +394,20 @@ void BoxShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_s
}
bool BoxShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
-
AABB aabb(-half_extents, half_extents * 2.0);
return aabb.intersects_segment(p_begin, p_end, &r_result, &r_normal);
}
bool BoxShape3DSW::intersect_point(const Vector3 &p_point) const {
-
return (Math::abs(p_point.x) < half_extents.x && Math::abs(p_point.y) < half_extents.y && Math::abs(p_point.z) < half_extents.z);
}
Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
-
int outside = 0;
Vector3 min_point;
for (int i = 0; i < 3; i++) {
-
if (Math::abs(p_point[i]) > half_extents[i]) {
outside++;
if (outside == 1) {
@@ -471,11 +421,13 @@ Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
}
}
- if (!outside)
+ if (!outside) {
return p_point; //it's inside, don't do anything else
+ }
- if (outside == 1) //if only above one plane, this plane clearly wins
+ if (outside == 1) { //if only above one plane, this plane clearly wins
return min_point;
+ }
//check segments
float min_distance = 1e20;
@@ -486,7 +438,6 @@ Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
};
for (int i = 0; i < 3; i++) {
-
s[1] = closest_vertex;
s[1][i] = -s[1][i]; //edge
@@ -503,7 +454,6 @@ Vector3 BoxShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
}
Vector3 BoxShape3DSW::get_moment_of_inertia(real_t p_mass) const {
-
real_t lx = half_extents.x;
real_t ly = half_extents.y;
real_t lz = half_extents.z;
@@ -512,19 +462,16 @@ Vector3 BoxShape3DSW::get_moment_of_inertia(real_t p_mass) const {
}
void BoxShape3DSW::_setup(const Vector3 &p_half_extents) {
-
half_extents = p_half_extents.abs();
configure(AABB(-half_extents, half_extents * 2));
}
void BoxShape3DSW::set_data(const Variant &p_data) {
-
_setup(p_data);
}
Variant BoxShape3DSW::get_data() const {
-
return half_extents;
}
@@ -534,7 +481,6 @@ BoxShape3DSW::BoxShape3DSW() {
/********** CAPSULE *************/
void CapsuleShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
-
Vector3 n = p_transform.basis.xform_inv(p_normal).normalized();
real_t h = (n.z > 0) ? height : -height;
@@ -546,7 +492,6 @@ void CapsuleShape3DSW::project_range(const Vector3 &p_normal, const Transform &p
}
Vector3 CapsuleShape3DSW::get_support(const Vector3 &p_normal) const {
-
Vector3 n = p_normal;
real_t h = (n.z > 0) ? height : -height;
@@ -557,13 +502,11 @@ Vector3 CapsuleShape3DSW::get_support(const Vector3 &p_normal) const {
}
void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
-
Vector3 n = p_normal;
real_t d = n.z;
if (Math::abs(d) < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
-
// make it flat
n.z = 0.0;
n.normalize();
@@ -576,7 +519,6 @@ void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3
r_supports[1].z -= height * 0.5;
} else {
-
real_t h = (d > 0) ? height : -height;
n *= radius;
@@ -587,7 +529,6 @@ void CapsuleShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3
}
bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
-
Vector3 norm = (p_end - p_begin).normalized();
real_t min_d = 1e20;
@@ -637,7 +578,6 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &
}
if (collision) {
-
r_result = res;
r_normal = n;
}
@@ -645,7 +585,6 @@ bool CapsuleShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &
}
bool CapsuleShape3DSW::intersect_point(const Vector3 &p_point) const {
-
if (Math::abs(p_point.z) < height * 0.5) {
return Vector3(p_point.x, p_point.y, 0).length() < radius;
} else {
@@ -656,7 +595,6 @@ bool CapsuleShape3DSW::intersect_point(const Vector3 &p_point) const {
}
Vector3 CapsuleShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
-
Vector3 s[2] = {
Vector3(0, 0, -height * 0.5),
Vector3(0, 0, height * 0.5),
@@ -664,14 +602,14 @@ Vector3 CapsuleShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
Vector3 p = Geometry::get_closest_point_to_segment(p_point, s);
- if (p.distance_to(p_point) < radius)
+ if (p.distance_to(p_point) < radius) {
return p_point;
+ }
return p + (p_point - p).normalized() * radius;
}
Vector3 CapsuleShape3DSW::get_moment_of_inertia(real_t p_mass) const {
-
// use bad AABB approximation
Vector3 extents = get_aabb().size * 0.5;
@@ -682,14 +620,12 @@ Vector3 CapsuleShape3DSW::get_moment_of_inertia(real_t p_mass) const {
}
void CapsuleShape3DSW::_setup(real_t p_height, real_t p_radius) {
-
height = p_height;
radius = p_radius;
configure(AABB(Vector3(-radius, -radius, -height * 0.5 - radius), Vector3(radius * 2, radius * 2, height + radius * 2.0)));
}
void CapsuleShape3DSW::set_data(const Variant &p_data) {
-
Dictionary d = p_data;
ERR_FAIL_COND(!d.has("radius"));
ERR_FAIL_COND(!d.has("height"));
@@ -697,7 +633,6 @@ void CapsuleShape3DSW::set_data(const Variant &p_data) {
}
Variant CapsuleShape3DSW::get_data() const {
-
Dictionary d;
d["radius"] = radius;
d["height"] = height;
@@ -705,46 +640,45 @@ Variant CapsuleShape3DSW::get_data() const {
}
CapsuleShape3DSW::CapsuleShape3DSW() {
-
height = radius = 0;
}
/********** CONVEX POLYGON *************/
void ConvexPolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
-
int vertex_count = mesh.vertices.size();
- if (vertex_count == 0)
+ if (vertex_count == 0) {
return;
+ }
const Vector3 *vrts = &mesh.vertices[0];
for (int i = 0; i < vertex_count; i++) {
-
real_t d = p_normal.dot(p_transform.xform(vrts[i]));
- if (i == 0 || d > r_max)
+ if (i == 0 || d > r_max) {
r_max = d;
- if (i == 0 || d < r_min)
+ }
+ if (i == 0 || d < r_min) {
r_min = d;
+ }
}
}
Vector3 ConvexPolygonShape3DSW::get_support(const Vector3 &p_normal) const {
-
Vector3 n = p_normal;
int vert_support_idx = -1;
real_t support_max = 0;
int vertex_count = mesh.vertices.size();
- if (vertex_count == 0)
+ if (vertex_count == 0) {
return Vector3();
+ }
const Vector3 *vrts = &mesh.vertices[0];
for (int i = 0; i < vertex_count; i++) {
-
real_t d = n.dot(vrts[i]);
if (i == 0 || d > support_max) {
@@ -757,7 +691,6 @@ Vector3 ConvexPolygonShape3DSW::get_support(const Vector3 &p_normal) const {
}
void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
-
const Geometry::MeshData::Face *faces = mesh.faces.ptr();
int fc = mesh.faces.size();
@@ -772,7 +705,6 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve
int vtx = 0;
for (int i = 0; i < vc; i++) {
-
real_t d = p_normal.dot(vertices[i]);
if (i == 0 || d > max) {
@@ -782,9 +714,7 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve
}
for (int i = 0; i < fc; i++) {
-
if (faces[i].plane.normal.dot(p_normal) > _FACE_IS_VALID_SUPPORT_THRESHOLD) {
-
int ic = faces[i].indices.size();
const int *ind = faces[i].indices.ptr();
@@ -796,12 +726,12 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve
}
}
- if (!valid)
+ if (!valid) {
continue;
+ }
int m = MIN(p_max, ic);
for (int j = 0; j < m; j++) {
-
r_supports[j] = vertices[ind[j]];
}
r_amount = m;
@@ -810,11 +740,9 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve
}
for (int i = 0; i < ec; i++) {
-
real_t dot = (vertices[edges[i].a] - vertices[edges[i].b]).normalized().dot(p_normal);
dot = ABS(dot);
if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD && (edges[i].a == vtx || edges[i].b == vtx)) {
-
r_amount = 2;
r_supports[0] = vertices[edges[i].a];
r_supports[1] = vertices[edges[i].b];
@@ -827,7 +755,6 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve
}
bool ConvexPolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
-
const Geometry::MeshData::Face *faces = mesh.faces.ptr();
int fc = mesh.faces.size();
@@ -838,15 +765,14 @@ bool ConvexPolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vec
bool col = false;
for (int i = 0; i < fc; i++) {
-
- if (faces[i].plane.normal.dot(n) > 0)
+ if (faces[i].plane.normal.dot(n) > 0) {
continue; //opposing face
+ }
int ic = faces[i].indices.size();
const int *ind = faces[i].indices.ptr();
for (int j = 1; j < ic - 1; j++) {
-
Face3 f(vertices[ind[0]], vertices[ind[j]], vertices[ind[j + 1]]);
Vector3 result;
if (f.intersects_segment(p_begin, p_end, &result)) {
@@ -867,30 +793,28 @@ bool ConvexPolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vec
}
bool ConvexPolygonShape3DSW::intersect_point(const Vector3 &p_point) const {
-
const Geometry::MeshData::Face *faces = mesh.faces.ptr();
int fc = mesh.faces.size();
for (int i = 0; i < fc; i++) {
-
- if (faces[i].plane.distance_to(p_point) >= 0)
+ if (faces[i].plane.distance_to(p_point) >= 0) {
return false;
+ }
}
return true;
}
Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
-
const Geometry::MeshData::Face *faces = mesh.faces.ptr();
int fc = mesh.faces.size();
const Vector3 *vertices = mesh.vertices.ptr();
bool all_inside = true;
for (int i = 0; i < fc; i++) {
-
- if (!faces[i].plane.is_point_over(p_point))
+ if (!faces[i].plane.is_point_over(p_point)) {
continue;
+ }
all_inside = false;
bool is_inside = true;
@@ -898,7 +822,6 @@ Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) con
const int *indices = faces[i].indices.ptr();
for (int j = 0; j < ic; j++) {
-
Vector3 a = vertices[indices[j]];
Vector3 b = vertices[indices[(j + 1) % ic]];
Vector3 n = (a - b).cross(faces[i].plane.normal).normalized();
@@ -924,7 +847,6 @@ Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) con
const Geometry::MeshData::Edge *edges = mesh.edges.ptr();
int ec = mesh.edges.size();
for (int i = 0; i < ec; i++) {
-
Vector3 s[2] = {
vertices[edges[i].a],
vertices[edges[i].b]
@@ -942,7 +864,6 @@ Vector3 ConvexPolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) con
}
Vector3 ConvexPolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const {
-
// use bad AABB approximation
Vector3 extents = get_aabb().size * 0.5;
@@ -953,31 +874,29 @@ Vector3 ConvexPolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const {
}
void ConvexPolygonShape3DSW::_setup(const Vector<Vector3> &p_vertices) {
-
Error err = QuickHull::build(p_vertices, mesh);
- if (err != OK)
+ if (err != OK) {
ERR_PRINT("Failed to build QuickHull");
+ }
AABB _aabb;
for (int i = 0; i < mesh.vertices.size(); i++) {
-
- if (i == 0)
+ if (i == 0) {
_aabb.position = mesh.vertices[i];
- else
+ } else {
_aabb.expand_to(mesh.vertices[i]);
+ }
}
configure(_aabb);
}
void ConvexPolygonShape3DSW::set_data(const Variant &p_data) {
-
_setup(p_data);
}
Variant ConvexPolygonShape3DSW::get_data() const {
-
return mesh.vertices;
}
@@ -987,27 +906,25 @@ ConvexPolygonShape3DSW::ConvexPolygonShape3DSW() {
/********** FACE POLYGON *************/
void FaceShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
-
for (int i = 0; i < 3; i++) {
-
Vector3 v = p_transform.xform(vertex[i]);
real_t d = p_normal.dot(v);
- if (i == 0 || d > r_max)
+ if (i == 0 || d > r_max) {
r_max = d;
+ }
- if (i == 0 || d < r_min)
+ if (i == 0 || d < r_min) {
r_min = d;
+ }
}
}
Vector3 FaceShape3DSW::get_support(const Vector3 &p_normal) const {
-
int vert_support_idx = -1;
real_t support_max = 0;
for (int i = 0; i < 3; i++) {
-
real_t d = p_normal.dot(vertex[i]);
if (i == 0 || d > support_max) {
@@ -1020,15 +937,12 @@ Vector3 FaceShape3DSW::get_support(const Vector3 &p_normal) const {
}
void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const {
-
Vector3 n = p_normal;
/** TEST FACE AS SUPPORT **/
if (normal.dot(n) > _FACE_IS_VALID_SUPPORT_THRESHOLD) {
-
r_amount = 3;
for (int i = 0; i < 3; i++) {
-
r_supports[i] = vertex[i];
}
return;
@@ -1040,7 +954,6 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_
real_t support_max = 0;
for (int i = 0; i < 3; i++) {
-
real_t d = n.dot(vertex[i]);
if (i == 0 || d > support_max) {
@@ -1052,16 +965,15 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_
/** TEST EDGES AS SUPPORT **/
for (int i = 0; i < 3; i++) {
-
int nx = (i + 1) % 3;
- if (i != vert_support_idx && nx != vert_support_idx)
+ if (i != vert_support_idx && nx != vert_support_idx) {
continue;
+ }
// check if edge is valid as a support
real_t dot = (vertex[i] - vertex[nx]).normalized().dot(n);
dot = ABS(dot);
if (dot < _EDGE_IS_VALID_SUPPORT_THRESHOLD) {
-
r_amount = 2;
r_supports[0] = vertex[i];
r_supports[1] = vertex[nx];
@@ -1074,7 +986,6 @@ void FaceShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_
}
bool FaceShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
-
bool c = Geometry::segment_intersects_triangle(p_begin, p_end, vertex[0], vertex[1], vertex[2], &r_result);
if (c) {
r_normal = Plane(vertex[0], vertex[1], vertex[2]).normal;
@@ -1087,36 +998,29 @@ bool FaceShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_e
}
bool FaceShape3DSW::intersect_point(const Vector3 &p_point) const {
-
return false; //face is flat
}
Vector3 FaceShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
-
return Face3(vertex[0], vertex[1], vertex[2]).get_closest_point_to(p_point);
}
Vector3 FaceShape3DSW::get_moment_of_inertia(real_t p_mass) const {
-
return Vector3(); // Sorry, but i don't think anyone cares, FaceShape!
}
FaceShape3DSW::FaceShape3DSW() {
-
configure(AABB());
}
Vector<Vector3> ConcavePolygonShape3DSW::get_faces() const {
-
Vector<Vector3> rfaces;
rfaces.resize(faces.size() * 3);
for (int i = 0; i < faces.size(); i++) {
-
Face f = faces.get(i);
for (int j = 0; j < 3; j++) {
-
rfaces.set(i * 3 + j, vertices.get(f.indices[j]));
}
}
@@ -1125,7 +1029,6 @@ Vector<Vector3> ConcavePolygonShape3DSW::get_faces() const {
}
void ConcavePolygonShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
-
int count = vertices.size();
if (count == 0) {
r_min = 0;
@@ -1135,21 +1038,22 @@ void ConcavePolygonShape3DSW::project_range(const Vector3 &p_normal, const Trans
const Vector3 *vptr = vertices.ptr();
for (int i = 0; i < count; i++) {
-
real_t d = p_normal.dot(p_transform.xform(vptr[i]));
- if (i == 0 || d > r_max)
+ if (i == 0 || d > r_max) {
r_max = d;
- if (i == 0 || d < r_min)
+ }
+ if (i == 0 || d < r_min) {
r_min = d;
+ }
}
}
Vector3 ConcavePolygonShape3DSW::get_support(const Vector3 &p_normal) const {
-
int count = vertices.size();
- if (count == 0)
+ if (count == 0) {
return Vector3();
+ }
const Vector3 *vptr = vertices.ptr();
@@ -1159,7 +1063,6 @@ Vector3 ConcavePolygonShape3DSW::get_support(const Vector3 &p_normal) const {
real_t support_max = 0;
for (int i = 0; i < count; i++) {
-
real_t d = n.dot(vptr[i]);
if (i == 0 || d > support_max) {
@@ -1172,7 +1075,6 @@ Vector3 ConcavePolygonShape3DSW::get_support(const Vector3 &p_normal) const {
}
void ConcavePolygonShape3DSW::_cull_segment(int p_idx, _SegmentCullParams *p_params) const {
-
const BVH *bvh = &p_params->bvh[p_idx];
/*
@@ -1182,12 +1084,10 @@ void ConcavePolygonShape3DSW::_cull_segment(int p_idx, _SegmentCullParams *p_par
//printf("addr: %p\n",bvh);
if (!bvh->aabb.intersects_segment(p_params->from, p_params->to)) {
-
return;
}
if (bvh->face_index >= 0) {
-
Vector3 res;
Vector3 vertices[3] = {
p_params->vertices[p_params->faces[bvh->face_index].indices[0]],
@@ -1202,11 +1102,9 @@ void ConcavePolygonShape3DSW::_cull_segment(int p_idx, _SegmentCullParams *p_par
vertices[1],
vertices[2],
&res)) {
-
real_t d = p_params->dir.dot(res) - p_params->dir.dot(p_params->from);
//TODO, seems segmen/triangle intersection is broken :(
if (d > 0 && d < p_params->min_d) {
-
p_params->min_d = d;
p_params->result = res;
p_params->normal = Plane(vertices[0], vertices[1], vertices[2]).normal;
@@ -1215,18 +1113,19 @@ void ConcavePolygonShape3DSW::_cull_segment(int p_idx, _SegmentCullParams *p_par
}
} else {
-
- if (bvh->left >= 0)
+ if (bvh->left >= 0) {
_cull_segment(bvh->left, p_params);
- if (bvh->right >= 0)
+ }
+ if (bvh->right >= 0) {
_cull_segment(bvh->right, p_params);
+ }
}
}
bool ConcavePolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const {
-
- if (faces.size() == 0)
+ if (faces.size() == 0) {
return false;
+ }
// unlock data
const Face *fr = faces.ptr();
@@ -1248,35 +1147,30 @@ bool ConcavePolygonShape3DSW::intersect_segment(const Vector3 &p_begin, const Ve
_cull_segment(0, &params);
if (params.collisions > 0) {
-
r_result = params.result;
r_normal = params.normal;
return true;
} else {
-
return false;
}
}
bool ConcavePolygonShape3DSW::intersect_point(const Vector3 &p_point) const {
-
return false; //face is flat
}
Vector3 ConcavePolygonShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
-
return Vector3();
}
void ConcavePolygonShape3DSW::_cull(int p_idx, _CullParams *p_params) const {
-
const BVH *bvh = &p_params->bvh[p_idx];
- if (!p_params->aabb.intersects(bvh->aabb))
+ if (!p_params->aabb.intersects(bvh->aabb)) {
return;
+ }
if (bvh->face_index >= 0) {
-
const Face *f = &p_params->faces[bvh->face_index];
FaceShape3DSW *face = p_params->face;
face->normal = f->normal;
@@ -1286,24 +1180,21 @@ void ConcavePolygonShape3DSW::_cull(int p_idx, _CullParams *p_params) const {
p_params->callback(p_params->userdata, face);
} else {
-
if (bvh->left >= 0) {
-
_cull(bvh->left, p_params);
}
if (bvh->right >= 0) {
-
_cull(bvh->right, p_params);
}
}
}
void ConcavePolygonShape3DSW::cull(const AABB &p_local_aabb, Callback p_callback, void *p_userdata) const {
-
// make matrix local to concave
- if (faces.size() == 0)
+ if (faces.size() == 0) {
return;
+ }
AABB local_aabb = p_local_aabb;
@@ -1328,7 +1219,6 @@ void ConcavePolygonShape3DSW::cull(const AABB &p_local_aabb, Callback p_callback
}
Vector3 ConcavePolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const {
-
// use bad AABB approximation
Vector3 extents = get_aabb().size * 0.5;
@@ -1339,38 +1229,30 @@ Vector3 ConcavePolygonShape3DSW::get_moment_of_inertia(real_t p_mass) const {
}
struct _VolumeSW_BVH_Element {
-
AABB aabb;
Vector3 center;
int face_index;
};
struct _VolumeSW_BVH_CompareX {
-
_FORCE_INLINE_ bool operator()(const _VolumeSW_BVH_Element &a, const _VolumeSW_BVH_Element &b) const {
-
return a.center.x < b.center.x;
}
};
struct _VolumeSW_BVH_CompareY {
-
_FORCE_INLINE_ bool operator()(const _VolumeSW_BVH_Element &a, const _VolumeSW_BVH_Element &b) const {
-
return a.center.y < b.center.y;
}
};
struct _VolumeSW_BVH_CompareZ {
-
_FORCE_INLINE_ bool operator()(const _VolumeSW_BVH_Element &a, const _VolumeSW_BVH_Element &b) const {
-
return a.center.z < b.center.z;
}
};
struct _VolumeSW_BVH {
-
AABB aabb;
_VolumeSW_BVH *left;
_VolumeSW_BVH *right;
@@ -1379,7 +1261,6 @@ struct _VolumeSW_BVH {
};
_VolumeSW_BVH *_volume_sw_build_bvh(_VolumeSW_BVH_Element *p_elements, int p_size, int &count) {
-
_VolumeSW_BVH *bvh = memnew(_VolumeSW_BVH);
if (p_size == 1) {
@@ -1391,34 +1272,29 @@ _VolumeSW_BVH *_volume_sw_build_bvh(_VolumeSW_BVH_Element *p_elements, int p_siz
count++;
return bvh;
} else {
-
bvh->face_index = -1;
}
AABB aabb;
for (int i = 0; i < p_size; i++) {
-
- if (i == 0)
+ if (i == 0) {
aabb = p_elements[i].aabb;
- else
+ } else {
aabb.merge_with(p_elements[i].aabb);
+ }
}
bvh->aabb = aabb;
switch (aabb.get_longest_axis_index()) {
-
case 0: {
-
SortArray<_VolumeSW_BVH_Element, _VolumeSW_BVH_CompareX> sort_x;
sort_x.sort(p_elements, p_size);
} break;
case 1: {
-
SortArray<_VolumeSW_BVH_Element, _VolumeSW_BVH_CompareY> sort_y;
sort_y.sort(p_elements, p_size);
} break;
case 2: {
-
SortArray<_VolumeSW_BVH_Element, _VolumeSW_BVH_CompareZ> sort_z;
sort_z.sort(p_elements, p_size);
} break;
@@ -1434,7 +1310,6 @@ _VolumeSW_BVH *_volume_sw_build_bvh(_VolumeSW_BVH_Element *p_elements, int p_siz
}
void ConcavePolygonShape3DSW::_fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_array, int &p_idx) {
-
int idx = p_idx;
p_bvh_array[idx].aabb = p_bvh_tree->aabb;
@@ -1446,7 +1321,6 @@ void ConcavePolygonShape3DSW::_fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_ar
_fill_bvh(p_bvh_tree->left, p_bvh_array, p_idx);
} else {
-
p_bvh_array[p_idx].left = -1;
}
@@ -1455,7 +1329,6 @@ void ConcavePolygonShape3DSW::_fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_ar
_fill_bvh(p_bvh_tree->right, p_bvh_array, p_idx);
} else {
-
p_bvh_array[p_idx].right = -1;
}
@@ -1463,7 +1336,6 @@ void ConcavePolygonShape3DSW::_fill_bvh(_VolumeSW_BVH *p_bvh_tree, BVH *p_bvh_ar
}
void ConcavePolygonShape3DSW::_setup(Vector<Vector3> p_faces) {
-
int src_face_count = p_faces.size();
if (src_face_count == 0) {
configure(AABB());
@@ -1489,7 +1361,6 @@ void ConcavePolygonShape3DSW::_setup(Vector<Vector3> p_faces) {
AABB _aabb;
for (int i = 0; i < src_face_count; i++) {
-
Face3 face(facesr[i * 3 + 0], facesr[i * 3 + 1], facesr[i * 3 + 2]);
bvh_arrayw[i].aabb = face.get_aabb();
@@ -1502,10 +1373,11 @@ void ConcavePolygonShape3DSW::_setup(Vector<Vector3> p_faces) {
verticesw[i * 3 + 0] = face.vertex[0];
verticesw[i * 3 + 1] = face.vertex[1];
verticesw[i * 3 + 2] = face.vertex[2];
- if (i == 0)
+ if (i == 0) {
_aabb = bvh_arrayw[i].aabb;
- else
+ } else {
_aabb.merge_with(bvh_arrayw[i].aabb);
+ }
}
int count = 0;
@@ -1522,12 +1394,10 @@ void ConcavePolygonShape3DSW::_setup(Vector<Vector3> p_faces) {
}
void ConcavePolygonShape3DSW::set_data(const Variant &p_data) {
-
_setup(p_data);
}
Variant ConcavePolygonShape3DSW::get_data() const {
-
return get_faces();
}
@@ -1537,36 +1407,32 @@ ConcavePolygonShape3DSW::ConcavePolygonShape3DSW() {
/* HEIGHT MAP SHAPE */
Vector<real_t> HeightMapShape3DSW::get_heights() const {
-
return heights;
}
-int HeightMapShape3DSW::get_width() const {
+int HeightMapShape3DSW::get_width() const {
return width;
}
-int HeightMapShape3DSW::get_depth() const {
+int HeightMapShape3DSW::get_depth() const {
return depth;
}
-real_t HeightMapShape3DSW::get_cell_size() const {
+real_t HeightMapShape3DSW::get_cell_size() const {
return cell_size;
}
void HeightMapShape3DSW::project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
-
//not very useful, but not very used either
p_transform.xform(get_aabb()).project_range_in_plane(Plane(p_normal, 0), r_min, r_max);
}
Vector3 HeightMapShape3DSW::get_support(const Vector3 &p_normal) const {
-
//not very useful, but not very used either
return get_aabb().get_support(p_normal);
}
bool HeightMapShape3DSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const {
-
return false;
}
@@ -1575,7 +1441,6 @@ bool HeightMapShape3DSW::intersect_point(const Vector3 &p_point) const {
}
Vector3 HeightMapShape3DSW::get_closest_point_to(const Vector3 &p_point) const {
-
return Vector3();
}
@@ -1583,7 +1448,6 @@ void HeightMapShape3DSW::cull(const AABB &p_local_aabb, Callback p_callback, voi
}
Vector3 HeightMapShape3DSW::get_moment_of_inertia(real_t p_mass) const {
-
// use bad AABB approximation
Vector3 extents = get_aabb().size * 0.5;
@@ -1594,7 +1458,6 @@ Vector3 HeightMapShape3DSW::get_moment_of_inertia(real_t p_mass) const {
}
void HeightMapShape3DSW::_setup(Vector<real_t> p_heights, int p_width, int p_depth, real_t p_cell_size) {
-
heights = p_heights;
width = p_width;
depth = p_depth;
@@ -1605,16 +1468,15 @@ void HeightMapShape3DSW::_setup(Vector<real_t> p_heights, int p_width, int p_dep
AABB aabb;
for (int i = 0; i < depth; i++) {
-
for (int j = 0; j < width; j++) {
-
real_t h = r[i * width + j];
Vector3 pos(j * cell_size, h, i * cell_size);
- if (i == 0 || j == 0)
+ if (i == 0 || j == 0) {
aabb.position = pos;
- else
+ } else {
aabb.expand_to(pos);
+ }
}
}
@@ -1622,7 +1484,6 @@ void HeightMapShape3DSW::_setup(Vector<real_t> p_heights, int p_width, int p_dep
}
void HeightMapShape3DSW::set_data(const Variant &p_data) {
-
ERR_FAIL_COND(p_data.get_type() != Variant::DICTIONARY);
Dictionary d = p_data;
ERR_FAIL_COND(!d.has("width"));
@@ -1643,12 +1504,10 @@ void HeightMapShape3DSW::set_data(const Variant &p_data) {
}
Variant HeightMapShape3DSW::get_data() const {
-
ERR_FAIL_V(Variant());
}
HeightMapShape3DSW::HeightMapShape3DSW() {
-
width = 0;
depth = 0;
cell_size = 0;
diff --git a/servers/physics_3d/shape_3d_sw.h b/servers/physics_3d/shape_3d_sw.h
index dd29ec849b..848a1135ad 100644
--- a/servers/physics_3d/shape_3d_sw.h
+++ b/servers/physics_3d/shape_3d_sw.h
@@ -56,7 +56,6 @@ public:
};
class Shape3DSW {
-
RID self;
AABB aabb;
bool configured;
@@ -108,7 +107,6 @@ public:
};
class ConcaveShape3DSW : public Shape3DSW {
-
public:
virtual bool is_concave() const { return true; }
typedef void (*Callback)(void *p_userdata, Shape3DSW *p_convex);
@@ -120,7 +118,6 @@ public:
};
class PlaneShape3DSW : public Shape3DSW {
-
Plane plane;
void _setup(const Plane &p_plane);
@@ -146,7 +143,6 @@ public:
};
class RayShape3DSW : public Shape3DSW {
-
real_t length;
bool slips_on_slope;
@@ -175,7 +171,6 @@ public:
};
class SphereShape3DSW : public Shape3DSW {
-
real_t radius;
void _setup(real_t p_radius);
@@ -203,7 +198,6 @@ public:
};
class BoxShape3DSW : public Shape3DSW {
-
Vector3 half_extents;
void _setup(const Vector3 &p_half_extents);
@@ -229,7 +223,6 @@ public:
};
class CapsuleShape3DSW : public Shape3DSW {
-
real_t height;
real_t radius;
@@ -259,7 +252,6 @@ public:
};
struct ConvexPolygonShape3DSW : public Shape3DSW {
-
Geometry::MeshData mesh;
void _setup(const Vector<Vector3> &p_vertices);
@@ -291,7 +283,6 @@ struct ConcavePolygonShape3DSW : public ConcaveShape3DSW {
// always a trimesh
struct Face {
-
Vector3 normal;
int indices[3];
};
@@ -300,7 +291,6 @@ struct ConcavePolygonShape3DSW : public ConcaveShape3DSW {
Vector<Vector3> vertices;
struct BVH {
-
AABB aabb;
int left;
int right;
@@ -311,7 +301,6 @@ struct ConcavePolygonShape3DSW : public ConcaveShape3DSW {
Vector<BVH> bvh;
struct _CullParams {
-
AABB aabb;
Callback callback;
void *userdata;
@@ -322,7 +311,6 @@ struct ConcavePolygonShape3DSW : public ConcaveShape3DSW {
};
struct _SegmentCullParams {
-
Vector3 from;
Vector3 to;
const Face *faces;
@@ -366,7 +354,6 @@ public:
};
struct HeightMapShape3DSW : public ConcaveShape3DSW {
-
Vector<real_t> heights;
int width;
int depth;
@@ -403,7 +390,6 @@ public:
//used internally
struct FaceShape3DSW : public Shape3DSW {
-
Vector3 normal; //cache
Vector3 vertex[3];
@@ -427,14 +413,12 @@ struct FaceShape3DSW : public Shape3DSW {
};
struct MotionShape3DSW : public Shape3DSW {
-
Shape3DSW *shape;
Vector3 motion;
virtual PhysicsServer3D::ShapeType get_type() const { return PhysicsServer3D::SHAPE_CONVEX_POLYGON; }
void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const {
-
Vector3 cast = p_transform.basis.xform(motion);
real_t mina, maxa;
real_t minb, maxb;
@@ -447,7 +431,6 @@ struct MotionShape3DSW : public Shape3DSW {
}
Vector3 get_support(const Vector3 &p_normal) const {
-
Vector3 support = shape->get_support(p_normal);
if (p_normal.dot(motion) > 0) {
support += motion;
diff --git a/servers/physics_3d/space_3d_sw.cpp b/servers/physics_3d/space_3d_sw.cpp
index bd8e89a8f5..4d272bdabd 100644
--- a/servers/physics_3d/space_3d_sw.cpp
+++ b/servers/physics_3d/space_3d_sw.cpp
@@ -35,22 +35,22 @@
#include "physics_server_3d_sw.h"
_FORCE_INLINE_ static bool _can_collide_with(CollisionObject3DSW *p_object, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
if (!(p_object->get_collision_layer() & p_collision_mask)) {
return false;
}
- if (p_object->get_type() == CollisionObject3DSW::TYPE_AREA && !p_collide_with_areas)
+ if (p_object->get_type() == CollisionObject3DSW::TYPE_AREA && !p_collide_with_areas) {
return false;
+ }
- if (p_object->get_type() == CollisionObject3DSW::TYPE_BODY && !p_collide_with_bodies)
+ if (p_object->get_type() == CollisionObject3DSW::TYPE_BODY && !p_collide_with_bodies) {
return false;
+ }
return true;
}
int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
ERR_FAIL_COND_V(space->locked, false);
int amount = space->broadphase->cull_point(p_point, space->intersection_query_results, Space3DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
int cc = 0;
@@ -58,17 +58,19 @@ int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeRe
//Transform ai = p_xform.affine_inverse();
for (int i = 0; i < amount; i++) {
-
- if (cc >= p_result_max)
+ if (cc >= p_result_max) {
break;
+ }
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
//area can't be picked by ray (default)
- if (p_exclude.has(space->intersection_query_results[i]->get_self()))
+ if (p_exclude.has(space->intersection_query_results[i]->get_self())) {
continue;
+ }
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
@@ -76,14 +78,16 @@ int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeRe
Transform inv_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
inv_xform.affine_invert();
- if (!col_obj->get_shape(shape_idx)->intersect_point(inv_xform.xform(p_point)))
+ if (!col_obj->get_shape(shape_idx)->intersect_point(inv_xform.xform(p_point))) {
continue;
+ }
r_results[cc].collider_id = col_obj->get_instance_id();
- if (r_results[cc].collider_id.is_valid())
+ if (r_results[cc].collider_id.is_valid()) {
r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id);
- else
+ } else {
r_results[cc].collider = nullptr;
+ }
r_results[cc].rid = col_obj->get_self();
r_results[cc].shape = shape_idx;
@@ -94,7 +98,6 @@ int PhysicsDirectSpaceState3DSW::intersect_point(const Vector3 &p_point, ShapeRe
}
bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_pick_ray) {
-
ERR_FAIL_COND_V(space->locked, false);
Vector3 begin, end;
@@ -114,15 +117,17 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec
real_t min_d = 1e10;
for (int i = 0; i < amount; i++) {
-
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
- if (p_pick_ray && !(space->intersection_query_results[i]->is_ray_pickable()))
+ if (p_pick_ray && !(space->intersection_query_results[i]->is_ray_pickable())) {
continue;
+ }
- if (p_exclude.has(space->intersection_query_results[i]->get_self()))
+ if (p_exclude.has(space->intersection_query_results[i]->get_self())) {
continue;
+ }
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
@@ -137,14 +142,12 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec
Vector3 shape_point, shape_normal;
if (shape->intersect_segment(local_from, local_to, shape_point, shape_normal)) {
-
Transform xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
shape_point = xform.xform(shape_point);
real_t ld = normal.dot(shape_point);
if (ld < min_d) {
-
min_d = ld;
res_point = shape_point;
res_normal = inv_xform.basis.xform_inv(shape_normal).normalized();
@@ -155,14 +158,16 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec
}
}
- if (!collided)
+ if (!collided) {
return false;
+ }
r_result.collider_id = res_obj->get_instance_id();
- if (r_result.collider_id.is_valid())
+ if (r_result.collider_id.is_valid()) {
r_result.collider = ObjectDB::get_instance(r_result.collider_id);
- else
+ } else {
r_result.collider = nullptr;
+ }
r_result.normal = res_normal;
r_result.position = res_point;
r_result.rid = res_obj->get_self();
@@ -172,9 +177,9 @@ bool PhysicsDirectSpaceState3DSW::intersect_ray(const Vector3 &p_from, const Vec
}
int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
- if (p_result_max <= 0)
+ if (p_result_max <= 0) {
return 0;
+ }
Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0);
@@ -188,30 +193,34 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans
//Transform ai = p_xform.affine_inverse();
for (int i = 0; i < amount; i++) {
-
- if (cc >= p_result_max)
+ if (cc >= p_result_max) {
break;
+ }
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
//area can't be picked by ray (default)
- if (p_exclude.has(space->intersection_query_results[i]->get_self()))
+ if (p_exclude.has(space->intersection_query_results[i]->get_self())) {
continue;
+ }
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
- if (!CollisionSolver3DSW::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_margin, 0))
+ if (!CollisionSolver3DSW::solve_static(shape, p_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), nullptr, nullptr, nullptr, p_margin, 0)) {
continue;
+ }
if (r_results) {
r_results[cc].collider_id = col_obj->get_instance_id();
- if (r_results[cc].collider_id.is_valid())
+ if (r_results[cc].collider_id.is_valid()) {
r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id);
- else
+ } else {
r_results[cc].collider = nullptr;
+ }
r_results[cc].rid = col_obj->get_self();
r_results[cc].shape = shape_idx;
}
@@ -223,7 +232,6 @@ int PhysicsDirectSpaceState3DSW::intersect_shape(const RID &p_shape, const Trans
}
bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas, ShapeRestInfo *r_info) {
-
Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, false);
@@ -246,12 +254,13 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor
Vector3 closest_A, closest_B;
for (int i = 0; i < amount; i++) {
-
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
- if (p_exclude.has(space->intersection_query_results[i]->get_self()))
+ if (p_exclude.has(space->intersection_query_results[i]->get_self())) {
continue; //ignore excluded
+ }
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
@@ -290,10 +299,8 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor
bool collided = !CollisionSolver3DSW::solve_distance(&mshape, p_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, aabb, &sep);
if (collided) {
-
hi = ofs;
} else {
-
point_A = lA;
point_B = lB;
low = ofs;
@@ -329,9 +336,9 @@ bool PhysicsDirectSpaceState3DSW::cast_motion(const RID &p_shape, const Transfor
}
bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
- if (p_result_max <= 0)
- return 0;
+ if (p_result_max <= 0) {
+ return false;
+ }
Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0);
@@ -353,9 +360,9 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_
PhysicsServer3DSW::CollCbkData *cbkptr = &cbk;
for (int i = 0; i < amount; i++) {
-
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
@@ -375,7 +382,6 @@ bool PhysicsDirectSpaceState3DSW::collide_shape(RID p_shape, const Transform &p_
}
struct _RestCallbackData {
-
const CollisionObject3DSW *object;
const CollisionObject3DSW *best_object;
int shape;
@@ -387,15 +393,16 @@ struct _RestCallbackData {
};
static void _rest_cbk_result(const Vector3 &p_point_A, const Vector3 &p_point_B, void *p_userdata) {
-
_RestCallbackData *rd = (_RestCallbackData *)p_userdata;
Vector3 contact_rel = p_point_B - p_point_A;
real_t len = contact_rel.length();
- if (len < rd->min_allowed_depth)
+ if (len < rd->min_allowed_depth) {
return;
- if (len <= rd->best_len)
+ }
+ if (len <= rd->best_len) {
return;
+ }
rd->best_len = len;
rd->best_contact = p_point_B;
@@ -403,8 +410,8 @@ static void _rest_cbk_result(const Vector3 &p_point_A, const Vector3 &p_point_B,
rd->best_object = rd->object;
rd->best_shape = rd->shape;
}
-bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
+bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
Shape3DSW *shape = static_cast<PhysicsServer3DSW *>(PhysicsServer3D::get_singleton())->shape_owner.getornull(p_shape);
ERR_FAIL_COND_V(!shape, 0);
@@ -420,25 +427,28 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap
rcd.min_allowed_depth = space->test_motion_min_contact_depth;
for (int i = 0; i < amount; i++) {
-
- if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas))
+ if (!_can_collide_with(space->intersection_query_results[i], p_collision_mask, p_collide_with_bodies, p_collide_with_areas)) {
continue;
+ }
const CollisionObject3DSW *col_obj = space->intersection_query_results[i];
int shape_idx = space->intersection_query_subindex_results[i];
- if (p_exclude.has(col_obj->get_self()))
+ if (p_exclude.has(col_obj->get_self())) {
continue;
+ }
rcd.object = col_obj;
rcd.shape = shape_idx;
bool sc = CollisionSolver3DSW::solve_static(shape, p_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin);
- if (!sc)
+ if (!sc) {
continue;
+ }
}
- if (rcd.best_len == 0 || !rcd.best_object)
+ if (rcd.best_len == 0 || !rcd.best_object) {
return false;
+ }
r_info->collider_id = rcd.best_object->get_instance_id();
r_info->shape = rcd.best_shape;
@@ -446,7 +456,6 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap
r_info->point = rcd.best_contact;
r_info->rid = rcd.best_object->get_self();
if (rcd.best_object->get_type() == CollisionObject3DSW::TYPE_BODY) {
-
const Body3DSW *body = static_cast<const Body3DSW *>(rcd.best_object);
r_info->linear_velocity = body->get_linear_velocity() +
(body->get_angular_velocity()).cross(body->get_transform().origin - rcd.best_contact); // * mPos);
@@ -459,7 +468,6 @@ bool PhysicsDirectSpaceState3DSW::rest_info(RID p_shape, const Transform &p_shap
}
Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const {
-
CollisionObject3DSW *obj = PhysicsServer3DSW::singleton->area_owner.getornull(p_object);
if (!obj) {
obj = PhysicsServer3DSW::singleton->body_owner.getornull(p_object);
@@ -474,9 +482,9 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob
bool shapes_found = false;
for (int i = 0; i < obj->get_shape_count(); i++) {
-
- if (obj->is_shape_set_as_disabled(i))
+ if (obj->is_shape_set_as_disabled(i)) {
continue;
+ }
Transform shape_xform = obj->get_transform() * obj->get_shape_transform(i);
Shape3DSW *shape = obj->get_shape(i);
@@ -500,33 +508,30 @@ Vector3 PhysicsDirectSpaceState3DSW::get_closest_point_to_object_volume(RID p_ob
}
PhysicsDirectSpaceState3DSW::PhysicsDirectSpaceState3DSW() {
-
space = nullptr;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
int Space3DSW::_cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb) {
-
int amount = broadphase->cull_aabb(p_aabb, intersection_query_results, INTERSECTION_QUERY_MAX, intersection_query_subindex_results);
for (int i = 0; i < amount; i++) {
-
bool keep = true;
- if (intersection_query_results[i] == p_body)
+ if (intersection_query_results[i] == p_body) {
keep = false;
- else if (intersection_query_results[i]->get_type() == CollisionObject3DSW::TYPE_AREA)
+ } else if (intersection_query_results[i]->get_type() == CollisionObject3DSW::TYPE_AREA) {
keep = false;
- else if ((static_cast<Body3DSW *>(intersection_query_results[i])->test_collision_mask(p_body)) == 0)
+ } else if ((static_cast<Body3DSW *>(intersection_query_results[i])->test_collision_mask(p_body)) == 0) {
keep = false;
- else if (static_cast<Body3DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self()))
+ } else if (static_cast<Body3DSW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self())) {
keep = false;
- else if (static_cast<Body3DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i]))
+ } else if (static_cast<Body3DSW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i])) {
keep = false;
+ }
if (!keep) {
-
if (i < amount - 1) {
SWAP(intersection_query_results[i], intersection_query_results[amount - 1]);
SWAP(intersection_query_subindex_results[i], intersection_query_subindex_results[amount - 1]);
@@ -541,15 +546,14 @@ int Space3DSW::_cull_aabb_for_body(Body3DSW *p_body, const AABB &p_aabb) {
}
int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_transform, bool p_infinite_inertia, Vector3 &r_recover_motion, PhysicsServer3D::SeparationResult *r_results, int p_result_max, real_t p_margin) {
-
AABB body_aabb;
bool shapes_found = false;
for (int i = 0; i < p_body->get_shape_count(); i++) {
-
- if (p_body->is_shape_set_as_disabled(i))
+ if (p_body->is_shape_set_as_disabled(i)) {
continue;
+ }
if (!shapes_found) {
body_aabb = p_body->get_shape_aabb(i);
@@ -587,7 +591,6 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra
CollisionSolver3DSW::CallbackResult cbkres = PhysicsServer3DSW::_shape_col_cbk;
do {
-
Vector3 recover_motion;
bool collided = false;
@@ -595,18 +598,19 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_disabled(j))
+ if (p_body->is_shape_set_as_disabled(j)) {
continue;
+ }
Shape3DSW *body_shape = p_body->get_shape(j);
- if (body_shape->get_type() != PhysicsServer3D::SHAPE_RAY)
+ if (body_shape->get_type() != PhysicsServer3D::SHAPE_RAY) {
continue;
+ }
Transform body_shape_xform = body_transform * p_body->get_shape_transform(j);
for (int i = 0; i < amount; i++) {
-
const CollisionObject3DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
@@ -649,7 +653,6 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra
float depth = a.distance_to(b);
if (depth > result.collision_depth) {
-
result.collision_depth = depth;
result.collision_point = b;
result.collision_normal = (b - a).normalized();
@@ -696,7 +699,6 @@ int Space3DSW::test_body_ray_separation(Body3DSW *p_body, const Transform &p_tra
}
bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, real_t p_margin, PhysicsServer3D::MotionResult *r_result, bool p_exclude_raycast_shapes) {
-
//give me back regular physics engine logic
//this is madness
//and most people using this function will think
@@ -712,9 +714,9 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
bool shapes_found = false;
for (int i = 0; i < p_body->get_shape_count(); i++) {
-
- if (p_body->is_shape_set_as_disabled(i))
+ if (p_body->is_shape_set_as_disabled(i)) {
continue;
+ }
if (!shapes_found) {
body_aabb = p_body->get_shape_aabb(i);
@@ -747,7 +749,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
Vector3 sr[max_results * 2];
do {
-
PhysicsServer3DSW::CollCbkData cbk;
cbk.max = max_results;
cbk.amount = 0;
@@ -761,8 +762,9 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
- if (p_body->is_shape_set_as_disabled(j))
+ if (p_body->is_shape_set_as_disabled(j)) {
continue;
+ }
Transform body_shape_xform = body_transform * p_body->get_shape_transform(j);
Shape3DSW *body_shape = p_body->get_shape(j);
@@ -771,7 +773,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
}
for (int i = 0; i < amount; i++) {
-
const CollisionObject3DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
@@ -788,7 +789,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
Vector3 recover_motion;
for (int i = 0; i < cbk.amount; i++) {
-
Vector3 a = sr[i * 2 + 0];
Vector3 b = sr[i * 2 + 1];
recover_motion += (b - a) * 0.4;
@@ -821,9 +821,9 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
int amount = _cull_aabb_for_body(p_body, motion_aabb);
for (int j = 0; j < p_body->get_shape_count(); j++) {
-
- if (p_body->is_shape_set_as_disabled(j))
+ if (p_body->is_shape_set_as_disabled(j)) {
continue;
+ }
Transform body_shape_xform = body_transform * p_body->get_shape_transform(j);
Shape3DSW *body_shape = p_body->get_shape(j);
@@ -843,7 +843,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
real_t best_unsafe = 1;
for (int i = 0; i < amount; i++) {
-
const CollisionObject3DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
@@ -881,10 +880,8 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
bool collided = !CollisionSolver3DSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, motion_aabb, &sep);
if (collided) {
-
hi = ofs;
} else {
-
point_A = lA;
point_B = lB;
low = ofs;
@@ -898,7 +895,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
}
if (stuck) {
-
safe = 0;
unsafe = 0;
best_shape = j; //sadly it's the best
@@ -908,7 +904,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
continue;
}
if (best_safe < safe) {
-
safe = best_safe;
unsafe = best_unsafe;
best_shape = j;
@@ -921,14 +916,12 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
//not collided
collided = false;
if (r_result) {
-
r_result->motion = p_motion;
r_result->remainder = Vector3();
r_result->motion += (body_transform.get_origin() - p_from.get_origin());
}
} else {
-
//it collided, let's get the rest info in unsafe advance
Transform ugt = body_transform;
ugt.origin += p_motion * unsafe;
@@ -947,19 +940,18 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
int amount = _cull_aabb_for_body(p_body, body_aabb);
for (int i = 0; i < amount; i++) {
-
const CollisionObject3DSW *col_obj = intersection_query_results[i];
int shape_idx = intersection_query_subindex_results[i];
rcd.object = col_obj;
rcd.shape = shape_idx;
bool sc = CollisionSolver3DSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, nullptr, p_margin);
- if (!sc)
+ if (!sc) {
continue;
+ }
}
if (rcd.best_len != 0) {
-
if (r_result) {
r_result->collider = rcd.best_object->get_self();
r_result->collider_id = rcd.best_object->get_instance_id();
@@ -982,7 +974,6 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
collided = true;
} else {
if (r_result) {
-
r_result->motion = p_motion;
r_result->remainder = Vector3();
r_result->motion += (body_transform.get_origin() - p_from.get_origin());
@@ -996,11 +987,9 @@ bool Space3DSW::test_body_motion(Body3DSW *p_body, const Transform &p_from, cons
}
void *Space3DSW::_broadphase_pair(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_self) {
-
CollisionObject3DSW::Type type_A = A->get_type();
CollisionObject3DSW::Type type_B = B->get_type();
if (type_A > type_B) {
-
SWAP(A, B);
SWAP(p_subindex_A, p_subindex_B);
SWAP(type_A, type_B);
@@ -1011,21 +1000,17 @@ void *Space3DSW::_broadphase_pair(CollisionObject3DSW *A, int p_subindex_A, Coll
self->collision_pairs++;
if (type_A == CollisionObject3DSW::TYPE_AREA) {
-
Area3DSW *area = static_cast<Area3DSW *>(A);
if (type_B == CollisionObject3DSW::TYPE_AREA) {
-
Area3DSW *area_b = static_cast<Area3DSW *>(B);
Area2Pair3DSW *area2_pair = memnew(Area2Pair3DSW(area_b, p_subindex_B, area, p_subindex_A));
return area2_pair;
} else {
-
Body3DSW *body = static_cast<Body3DSW *>(B);
AreaPair3DSW *area_pair = memnew(AreaPair3DSW(body, p_subindex_B, area, p_subindex_A));
return area_pair;
}
} else {
-
BodyPair3DSW *b = memnew(BodyPair3DSW((Body3DSW *)A, p_subindex_A, (Body3DSW *)B, p_subindex_B));
return b;
}
@@ -1034,7 +1019,6 @@ void *Space3DSW::_broadphase_pair(CollisionObject3DSW *A, int p_subindex_A, Coll
}
void Space3DSW::_broadphase_unpair(CollisionObject3DSW *A, int p_subindex_A, CollisionObject3DSW *B, int p_subindex_B, void *p_data, void *p_self) {
-
Space3DSW *self = (Space3DSW *)p_self;
self->collision_pairs--;
Constraint3DSW *c = (Constraint3DSW *)p_data;
@@ -1042,94 +1026,79 @@ void Space3DSW::_broadphase_unpair(CollisionObject3DSW *A, int p_subindex_A, Col
}
const SelfList<Body3DSW>::List &Space3DSW::get_active_body_list() const {
-
return active_list;
}
-void Space3DSW::body_add_to_active_list(SelfList<Body3DSW> *p_body) {
+void Space3DSW::body_add_to_active_list(SelfList<Body3DSW> *p_body) {
active_list.add(p_body);
}
-void Space3DSW::body_remove_from_active_list(SelfList<Body3DSW> *p_body) {
+void Space3DSW::body_remove_from_active_list(SelfList<Body3DSW> *p_body) {
active_list.remove(p_body);
}
void Space3DSW::body_add_to_inertia_update_list(SelfList<Body3DSW> *p_body) {
-
inertia_update_list.add(p_body);
}
void Space3DSW::body_remove_from_inertia_update_list(SelfList<Body3DSW> *p_body) {
-
inertia_update_list.remove(p_body);
}
BroadPhase3DSW *Space3DSW::get_broadphase() {
-
return broadphase;
}
void Space3DSW::add_object(CollisionObject3DSW *p_object) {
-
ERR_FAIL_COND(objects.has(p_object));
objects.insert(p_object);
}
void Space3DSW::remove_object(CollisionObject3DSW *p_object) {
-
ERR_FAIL_COND(!objects.has(p_object));
objects.erase(p_object);
}
const Set<CollisionObject3DSW *> &Space3DSW::get_objects() const {
-
return objects;
}
void Space3DSW::body_add_to_state_query_list(SelfList<Body3DSW> *p_body) {
-
state_query_list.add(p_body);
}
-void Space3DSW::body_remove_from_state_query_list(SelfList<Body3DSW> *p_body) {
+void Space3DSW::body_remove_from_state_query_list(SelfList<Body3DSW> *p_body) {
state_query_list.remove(p_body);
}
void Space3DSW::area_add_to_monitor_query_list(SelfList<Area3DSW> *p_area) {
-
monitor_query_list.add(p_area);
}
-void Space3DSW::area_remove_from_monitor_query_list(SelfList<Area3DSW> *p_area) {
+void Space3DSW::area_remove_from_monitor_query_list(SelfList<Area3DSW> *p_area) {
monitor_query_list.remove(p_area);
}
void Space3DSW::area_add_to_moved_list(SelfList<Area3DSW> *p_area) {
-
area_moved_list.add(p_area);
}
void Space3DSW::area_remove_from_moved_list(SelfList<Area3DSW> *p_area) {
-
area_moved_list.remove(p_area);
}
const SelfList<Area3DSW>::List &Space3DSW::get_moved_area_list() const {
-
return area_moved_list;
}
void Space3DSW::call_queries() {
-
while (state_query_list.first()) {
-
Body3DSW *b = state_query_list.first()->self();
state_query_list.remove(state_query_list.first());
b->call_queries();
}
while (monitor_query_list.first()) {
-
Area3DSW *a = monitor_query_list.first()->self();
monitor_query_list.remove(monitor_query_list.first());
a->call_queries();
@@ -1137,7 +1106,6 @@ void Space3DSW::call_queries() {
}
void Space3DSW::setup() {
-
contact_debug_count = 0;
while (inertia_update_list.first()) {
inertia_update_list.first()->self()->update_inertias();
@@ -1146,65 +1114,82 @@ void Space3DSW::setup() {
}
void Space3DSW::update() {
-
broadphase->update();
}
void Space3DSW::set_param(PhysicsServer3D::SpaceParameter p_param, real_t p_value) {
-
switch (p_param) {
-
- case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: contact_recycle_radius = p_value; break;
- case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION: contact_max_separation = p_value; break;
- case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: contact_max_allowed_penetration = p_value; break;
- case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: body_linear_velocity_sleep_threshold = p_value; break;
- case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: body_angular_velocity_sleep_threshold = p_value; break;
- case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP: body_time_to_sleep = p_value; break;
- case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: body_angular_velocity_damp_ratio = p_value; break;
- case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: constraint_bias = p_value; break;
- case PhysicsServer3D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: test_motion_min_contact_depth = p_value; break;
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS:
+ contact_recycle_radius = p_value;
+ break;
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
+ contact_max_separation = p_value;
+ break;
+ case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ contact_max_allowed_penetration = p_value;
+ break;
+ case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
+ body_linear_velocity_sleep_threshold = p_value;
+ break;
+ case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
+ body_angular_velocity_sleep_threshold = p_value;
+ break;
+ case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP:
+ body_time_to_sleep = p_value;
+ break;
+ case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO:
+ body_angular_velocity_damp_ratio = p_value;
+ break;
+ case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
+ constraint_bias = p_value;
+ break;
+ case PhysicsServer3D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH:
+ test_motion_min_contact_depth = p_value;
+ break;
}
}
real_t Space3DSW::get_param(PhysicsServer3D::SpaceParameter p_param) const {
-
switch (p_param) {
-
- case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS: return contact_recycle_radius;
- case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION: return contact_max_separation;
- case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION: return contact_max_allowed_penetration;
- case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD: return body_linear_velocity_sleep_threshold;
- case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD: return body_angular_velocity_sleep_threshold;
- case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP: return body_time_to_sleep;
- case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO: return body_angular_velocity_damp_ratio;
- case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS: return constraint_bias;
- case PhysicsServer3D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH: return test_motion_min_contact_depth;
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_RECYCLE_RADIUS:
+ return contact_recycle_radius;
+ case PhysicsServer3D::SPACE_PARAM_CONTACT_MAX_SEPARATION:
+ return contact_max_separation;
+ case PhysicsServer3D::SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION:
+ return contact_max_allowed_penetration;
+ case PhysicsServer3D::SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD:
+ return body_linear_velocity_sleep_threshold;
+ case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD:
+ return body_angular_velocity_sleep_threshold;
+ case PhysicsServer3D::SPACE_PARAM_BODY_TIME_TO_SLEEP:
+ return body_time_to_sleep;
+ case PhysicsServer3D::SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO:
+ return body_angular_velocity_damp_ratio;
+ case PhysicsServer3D::SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS:
+ return constraint_bias;
+ case PhysicsServer3D::SPACE_PARAM_TEST_MOTION_MIN_CONTACT_DEPTH:
+ return test_motion_min_contact_depth;
}
return 0;
}
void Space3DSW::lock() {
-
locked = true;
}
void Space3DSW::unlock() {
-
locked = false;
}
bool Space3DSW::is_locked() const {
-
return locked;
}
PhysicsDirectSpaceState3DSW *Space3DSW::get_direct_state() {
-
return direct_access;
}
Space3DSW::Space3DSW() {
-
collision_pairs = 0;
active_objects = 0;
island_count = 0;
@@ -1231,12 +1216,12 @@ Space3DSW::Space3DSW() {
direct_access = memnew(PhysicsDirectSpaceState3DSW);
direct_access->space = this;
- for (int i = 0; i < ELAPSED_TIME_MAX; i++)
+ for (int i = 0; i < ELAPSED_TIME_MAX; i++) {
elapsed_time[i] = 0;
+ }
}
Space3DSW::~Space3DSW() {
-
memdelete(broadphase);
memdelete(direct_access);
}
diff --git a/servers/physics_3d/space_3d_sw.h b/servers/physics_3d/space_3d_sw.h
index 3634834952..f9198e3d40 100644
--- a/servers/physics_3d/space_3d_sw.h
+++ b/servers/physics_3d/space_3d_sw.h
@@ -42,7 +42,6 @@
#include "core/typedefs.h"
class PhysicsDirectSpaceState3DSW : public PhysicsDirectSpaceState3D {
-
GDCLASS(PhysicsDirectSpaceState3DSW, PhysicsDirectSpaceState3D);
public:
@@ -60,7 +59,6 @@ public:
};
class Space3DSW {
-
public:
enum ElapsedTime {
ELAPSED_TIME_INTEGRATE_FORCES,
@@ -187,7 +185,9 @@ public:
void set_debug_contacts(int p_amount) { contact_debug.resize(p_amount); }
_FORCE_INLINE_ bool is_debugging_contacts() const { return !contact_debug.empty(); }
_FORCE_INLINE_ void add_debug_contact(const Vector3 &p_contact) {
- if (contact_debug_count < contact_debug.size()) contact_debug.write[contact_debug_count++] = p_contact;
+ if (contact_debug_count < contact_debug.size()) {
+ contact_debug.write[contact_debug_count++] = p_contact;
+ }
}
_FORCE_INLINE_ Vector<Vector3> get_debug_contacts() { return contact_debug; }
_FORCE_INLINE_ int get_debug_contact_count() { return contact_debug_count; }
diff --git a/servers/physics_3d/step_3d_sw.cpp b/servers/physics_3d/step_3d_sw.cpp
index 1a7d5f8cec..9a2a0073a1 100644
--- a/servers/physics_3d/step_3d_sw.cpp
+++ b/servers/physics_3d/step_3d_sw.cpp
@@ -34,33 +34,33 @@
#include "core/os/os.h"
void Step3DSW::_populate_island(Body3DSW *p_body, Body3DSW **p_island, Constraint3DSW **p_constraint_island) {
-
p_body->set_island_step(_step);
p_body->set_island_next(*p_island);
*p_island = p_body;
for (Map<Constraint3DSW *, int>::Element *E = p_body->get_constraint_map().front(); E; E = E->next()) {
-
Constraint3DSW *c = (Constraint3DSW *)E->key();
- if (c->get_island_step() == _step)
+ if (c->get_island_step() == _step) {
continue; //already processed
+ }
c->set_island_step(_step);
c->set_island_next(*p_constraint_island);
*p_constraint_island = c;
for (int i = 0; i < c->get_body_count(); i++) {
- if (i == E->get())
+ if (i == E->get()) {
continue;
+ }
Body3DSW *b = c->get_body_ptr()[i];
- if (b->get_island_step() == _step || b->get_mode() == PhysicsServer3D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC)
+ if (b->get_island_step() == _step || b->get_mode() == PhysicsServer3D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC) {
continue; //no go
+ }
_populate_island(c->get_body_ptr()[i], p_island, p_constraint_island);
}
}
}
void Step3DSW::_setup_island(Constraint3DSW *p_island, real_t p_delta) {
-
Constraint3DSW *ci = p_island;
while (ci) {
ci->setup(p_delta);
@@ -70,13 +70,10 @@ void Step3DSW::_setup_island(Constraint3DSW *p_island, real_t p_delta) {
}
void Step3DSW::_solve_island(Constraint3DSW *p_island, int p_iterations, real_t p_delta) {
-
int at_priority = 1;
while (p_island) {
-
for (int i = 0; i < p_iterations; i++) {
-
Constraint3DSW *ci = p_island;
while (ci) {
ci->solve(p_delta);
@@ -97,7 +94,6 @@ void Step3DSW::_solve_island(Constraint3DSW *p_island, int p_iterations, real_t
p_island = ci->get_island_next();
}
} else {
-
prev = ci;
}
@@ -108,19 +104,18 @@ void Step3DSW::_solve_island(Constraint3DSW *p_island, int p_iterations, real_t
}
void Step3DSW::_check_suspend(Body3DSW *p_island, real_t p_delta) {
-
bool can_sleep = true;
Body3DSW *b = p_island;
while (b) {
-
if (b->get_mode() == PhysicsServer3D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC) {
b = b->get_island_next();
continue; //ignore for static
}
- if (!b->sleep_test(p_delta))
+ if (!b->sleep_test(p_delta)) {
can_sleep = false;
+ }
b = b->get_island_next();
}
@@ -129,7 +124,6 @@ void Step3DSW::_check_suspend(Body3DSW *p_island, real_t p_delta) {
b = p_island;
while (b) {
-
if (b->get_mode() == PhysicsServer3D::BODY_MODE_STATIC || b->get_mode() == PhysicsServer3D::BODY_MODE_KINEMATIC) {
b = b->get_island_next();
continue; //ignore for static
@@ -137,15 +131,15 @@ void Step3DSW::_check_suspend(Body3DSW *p_island, real_t p_delta) {
bool active = b->is_active();
- if (active == can_sleep)
+ if (active == can_sleep) {
b->set_active(!can_sleep);
+ }
b = b->get_island_next();
}
}
void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) {
-
p_space->lock(); // can't access space during this
p_space->setup(); //update inertias, etc
@@ -161,7 +155,6 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) {
const SelfList<Body3DSW> *b = body_list->first();
while (b) {
-
b->self()->integrate_forces(p_delta);
b = b->next();
active_count++;
@@ -187,7 +180,6 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) {
Body3DSW *body = b->self();
if (body->get_island_step() != _step) {
-
Body3DSW *island = nullptr;
Constraint3DSW *constraint_island = nullptr;
_populate_island(body, &island, &constraint_island);
@@ -210,10 +202,10 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) {
while (aml.first()) {
for (const Set<Constraint3DSW *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) {
-
Constraint3DSW *c = E->get();
- if (c->get_island_step() == _step)
+ if (c->get_island_step() == _step) {
continue;
+ }
c->set_island_step(_step);
c->set_island_next(nullptr);
c->set_island_list_next(constraint_island_list);
@@ -233,7 +225,6 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) {
{
Constraint3DSW *ci = constraint_island_list;
while (ci) {
-
_setup_island(ci, p_delta);
ci = ci->get_island_list_next();
}
@@ -276,7 +267,6 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) {
{
Body3DSW *bi = island_list;
while (bi) {
-
_check_suspend(bi, p_delta);
bi = bi->get_island_list_next();
}
@@ -294,6 +284,5 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) {
}
Step3DSW::Step3DSW() {
-
_step = 1;
}
diff --git a/servers/physics_3d/step_3d_sw.h b/servers/physics_3d/step_3d_sw.h
index c735688a9e..9dbb61308f 100644
--- a/servers/physics_3d/step_3d_sw.h
+++ b/servers/physics_3d/step_3d_sw.h
@@ -34,7 +34,6 @@
#include "space_3d_sw.h"
class Step3DSW {
-
uint64_t _step;
void _populate_island(Body3DSW *p_body, Body3DSW **p_island, Constraint3DSW **p_constraint_island);
diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp
index 48c51b5350..c2de7fbd00 100644
--- a/servers/physics_server_2d.cpp
+++ b/servers/physics_server_2d.cpp
@@ -37,7 +37,6 @@
PhysicsServer2D *PhysicsServer2D::singleton = nullptr;
void PhysicsDirectBodyState2D::integrate_forces() {
-
real_t step = get_step();
Vector2 lv = get_linear_velocity();
lv += get_total_gravity() * step;
@@ -46,15 +45,17 @@ void PhysicsDirectBodyState2D::integrate_forces() {
float damp = 1.0 - step * get_total_linear_damp();
- if (damp < 0) // reached zero in the given time
+ if (damp < 0) { // reached zero in the given time
damp = 0;
+ }
lv *= damp;
damp = 1.0 - step * get_total_angular_damp();
- if (damp < 0) // reached zero in the given time
+ if (damp < 0) { // reached zero in the given time
damp = 0;
+ }
av *= damp;
@@ -63,19 +64,16 @@ void PhysicsDirectBodyState2D::integrate_forces() {
}
Object *PhysicsDirectBodyState2D::get_contact_collider_object(int p_contact_idx) const {
-
ObjectID objid = get_contact_collider_id(p_contact_idx);
Object *obj = ObjectDB::get_instance(objid);
return obj;
}
PhysicsServer2D *PhysicsServer2D::get_singleton() {
-
return singleton;
}
void PhysicsDirectBodyState2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_total_gravity"), &PhysicsDirectBodyState2D::get_total_gravity);
ClassDB::bind_method(D_METHOD("get_total_linear_damp"), &PhysicsDirectBodyState2D::get_total_linear_damp);
ClassDB::bind_method(D_METHOD("get_total_angular_damp"), &PhysicsDirectBodyState2D::get_total_angular_damp);
@@ -135,66 +133,58 @@ PhysicsDirectBodyState2D::PhysicsDirectBodyState2D() {}
///////////////////////////////////////////////////////
void PhysicsShapeQueryParameters2D::set_shape(const RES &p_shape) {
-
ERR_FAIL_COND(p_shape.is_null());
shape = p_shape->get_rid();
}
void PhysicsShapeQueryParameters2D::set_shape_rid(const RID &p_shape) {
-
shape = p_shape;
}
RID PhysicsShapeQueryParameters2D::get_shape_rid() const {
-
return shape;
}
void PhysicsShapeQueryParameters2D::set_transform(const Transform2D &p_transform) {
-
transform = p_transform;
}
-Transform2D PhysicsShapeQueryParameters2D::get_transform() const {
+Transform2D PhysicsShapeQueryParameters2D::get_transform() const {
return transform;
}
void PhysicsShapeQueryParameters2D::set_motion(const Vector2 &p_motion) {
-
motion = p_motion;
}
-Vector2 PhysicsShapeQueryParameters2D::get_motion() const {
+Vector2 PhysicsShapeQueryParameters2D::get_motion() const {
return motion;
}
void PhysicsShapeQueryParameters2D::set_margin(float p_margin) {
-
margin = p_margin;
}
-float PhysicsShapeQueryParameters2D::get_margin() const {
+float PhysicsShapeQueryParameters2D::get_margin() const {
return margin;
}
void PhysicsShapeQueryParameters2D::set_collision_mask(int p_collision_mask) {
-
collision_mask = p_collision_mask;
}
-int PhysicsShapeQueryParameters2D::get_collision_mask() const {
+int PhysicsShapeQueryParameters2D::get_collision_mask() const {
return collision_mask;
}
void PhysicsShapeQueryParameters2D::set_exclude(const Vector<RID> &p_exclude) {
-
exclude.clear();
- for (int i = 0; i < p_exclude.size(); i++)
+ for (int i = 0; i < p_exclude.size(); i++) {
exclude.insert(p_exclude[i]);
+ }
}
Vector<RID> PhysicsShapeQueryParameters2D::get_exclude() const {
-
Vector<RID> ret;
ret.resize(exclude.size());
int idx = 0;
@@ -221,7 +211,6 @@ bool PhysicsShapeQueryParameters2D::is_collide_with_areas_enabled() const {
}
void PhysicsShapeQueryParameters2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters2D::set_shape);
ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters2D::set_shape_rid);
ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters2D::get_shape_rid);
@@ -259,7 +248,6 @@ void PhysicsShapeQueryParameters2D::_bind_methods() {
}
PhysicsShapeQueryParameters2D::PhysicsShapeQueryParameters2D() {
-
margin = 0;
collision_mask = 0x7FFFFFFF;
collide_with_bodies = true;
@@ -267,16 +255,17 @@ PhysicsShapeQueryParameters2D::PhysicsShapeQueryParameters2D() {
}
Dictionary PhysicsDirectSpaceState2D::_intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
RayResult inters;
Set<RID> exclude;
- for (int i = 0; i < p_exclude.size(); i++)
+ for (int i = 0; i < p_exclude.size(); i++) {
exclude.insert(p_exclude[i]);
+ }
bool res = intersect_ray(p_from, p_to, inters, exclude, p_layers, p_collide_with_bodies, p_collide_with_areas);
- if (!res)
+ if (!res) {
return Dictionary();
+ }
Dictionary d;
d["position"] = inters.position;
@@ -291,7 +280,6 @@ Dictionary PhysicsDirectSpaceState2D::_intersect_ray(const Vector2 &p_from, cons
}
Array PhysicsDirectSpaceState2D::_intersect_shape(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query, int p_max_results) {
-
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
Vector<ShapeResult> sr;
@@ -300,7 +288,6 @@ Array PhysicsDirectSpaceState2D::_intersect_shape(const Ref<PhysicsShapeQueryPar
Array ret;
ret.resize(rc);
for (int i = 0; i < rc; i++) {
-
Dictionary d;
d["rid"] = sr[i].rid;
d["collider_id"] = sr[i].collider_id;
@@ -314,13 +301,13 @@ Array PhysicsDirectSpaceState2D::_intersect_shape(const Ref<PhysicsShapeQueryPar
}
Array PhysicsDirectSpaceState2D::_cast_motion(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query) {
-
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
float closest_safe, closest_unsafe;
bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
- if (!res)
+ if (!res) {
return Array();
+ }
Array ret;
ret.resize(2);
ret[0] = closest_safe;
@@ -329,27 +316,28 @@ Array PhysicsDirectSpaceState2D::_cast_motion(const Ref<PhysicsShapeQueryParamet
}
Array PhysicsDirectSpaceState2D::_intersect_point_impl(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas, bool p_filter_by_canvas, ObjectID p_canvas_instance_id) {
-
Set<RID> exclude;
- for (int i = 0; i < p_exclude.size(); i++)
+ for (int i = 0; i < p_exclude.size(); i++) {
exclude.insert(p_exclude[i]);
+ }
Vector<ShapeResult> ret;
ret.resize(p_max_results);
int rc;
- if (p_filter_by_canvas)
+ if (p_filter_by_canvas) {
rc = intersect_point(p_point, ret.ptrw(), ret.size(), exclude, p_layers, p_collide_with_bodies, p_collide_with_areas);
- else
+ } else {
rc = intersect_point_on_canvas(p_point, p_canvas_instance_id, ret.ptrw(), ret.size(), exclude, p_layers, p_collide_with_bodies, p_collide_with_areas);
+ }
- if (rc == 0)
+ if (rc == 0) {
return Array();
+ }
Array r;
r.resize(rc);
for (int i = 0; i < rc; i++) {
-
Dictionary d;
d["rid"] = ret[i].rid;
d["collider_id"] = ret[i].collider_id;
@@ -362,41 +350,41 @@ Array PhysicsDirectSpaceState2D::_intersect_point_impl(const Vector2 &p_point, i
}
Array PhysicsDirectSpaceState2D::_intersect_point(const Vector2 &p_point, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
return _intersect_point_impl(p_point, p_max_results, p_exclude, p_layers, p_collide_with_bodies, p_collide_with_areas);
}
Array PhysicsDirectSpaceState2D::_intersect_point_on_canvas(const Vector2 &p_point, ObjectID p_canvas_intance_id, int p_max_results, const Vector<RID> &p_exclude, uint32_t p_layers, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
return _intersect_point_impl(p_point, p_max_results, p_exclude, p_layers, p_collide_with_bodies, p_collide_with_areas, true, p_canvas_intance_id);
}
Array PhysicsDirectSpaceState2D::_collide_shape(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query, int p_max_results) {
-
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
Vector<Vector2> ret;
ret.resize(p_max_results * 2);
int rc = 0;
bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
- if (!res)
+ if (!res) {
return Array();
+ }
Array r;
r.resize(rc * 2);
- for (int i = 0; i < rc * 2; i++)
+ for (int i = 0; i < rc * 2; i++) {
r[i] = ret[i];
+ }
return r;
}
-Dictionary PhysicsDirectSpaceState2D::_get_rest_info(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query) {
+Dictionary PhysicsDirectSpaceState2D::_get_rest_info(const Ref<PhysicsShapeQueryParameters2D> &p_shape_query) {
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Dictionary());
ShapeRestInfo sri;
bool res = rest_info(p_shape_query->shape, p_shape_query->transform, p_shape_query->motion, p_shape_query->margin, &sri, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
Dictionary r;
- if (!res)
+ if (!res) {
return r;
+ }
r["point"] = sri.point;
r["normal"] = sri.normal;
@@ -413,7 +401,6 @@ PhysicsDirectSpaceState2D::PhysicsDirectSpaceState2D() {
}
void PhysicsDirectSpaceState2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState2D::_intersect_point, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("intersect_point_on_canvas", "point", "canvas_instance_id", "max_results", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState2D::_intersect_point_on_canvas, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_layer", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState2D::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false));
@@ -424,23 +411,22 @@ void PhysicsDirectSpaceState2D::_bind_methods() {
}
int PhysicsShapeQueryResult2D::get_result_count() const {
-
return result.size();
}
-RID PhysicsShapeQueryResult2D::get_result_rid(int p_idx) const {
+RID PhysicsShapeQueryResult2D::get_result_rid(int p_idx) const {
return result[p_idx].rid;
}
-ObjectID PhysicsShapeQueryResult2D::get_result_object_id(int p_idx) const {
+ObjectID PhysicsShapeQueryResult2D::get_result_object_id(int p_idx) const {
return result[p_idx].collider_id;
}
-Object *PhysicsShapeQueryResult2D::get_result_object(int p_idx) const {
+Object *PhysicsShapeQueryResult2D::get_result_object(int p_idx) const {
return result[p_idx].collider;
}
-int PhysicsShapeQueryResult2D::get_result_object_shape(int p_idx) const {
+int PhysicsShapeQueryResult2D::get_result_object_shape(int p_idx) const {
return result[p_idx].shape;
}
@@ -448,7 +434,6 @@ PhysicsShapeQueryResult2D::PhysicsShapeQueryResult2D() {
}
void PhysicsShapeQueryResult2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_result_count"), &PhysicsShapeQueryResult2D::get_result_count);
ClassDB::bind_method(D_METHOD("get_result_rid", "idx"), &PhysicsShapeQueryResult2D::get_result_rid);
ClassDB::bind_method(D_METHOD("get_result_object_id", "idx"), &PhysicsShapeQueryResult2D::get_result_object_id);
@@ -459,32 +444,30 @@ void PhysicsShapeQueryResult2D::_bind_methods() {
///////////////////////////////
Vector2 PhysicsTestMotionResult2D::get_motion() const {
-
return result.motion;
}
-Vector2 PhysicsTestMotionResult2D::get_motion_remainder() const {
+Vector2 PhysicsTestMotionResult2D::get_motion_remainder() const {
return result.remainder;
}
Vector2 PhysicsTestMotionResult2D::get_collision_point() const {
-
return result.collision_point;
}
-Vector2 PhysicsTestMotionResult2D::get_collision_normal() const {
+Vector2 PhysicsTestMotionResult2D::get_collision_normal() const {
return result.collision_normal;
}
-Vector2 PhysicsTestMotionResult2D::get_collider_velocity() const {
+Vector2 PhysicsTestMotionResult2D::get_collider_velocity() const {
return result.collider_velocity;
}
-ObjectID PhysicsTestMotionResult2D::get_collider_id() const {
+ObjectID PhysicsTestMotionResult2D::get_collider_id() const {
return result.collider_id;
}
-RID PhysicsTestMotionResult2D::get_collider_rid() const {
+RID PhysicsTestMotionResult2D::get_collider_rid() const {
return result.collider;
}
@@ -493,12 +476,10 @@ Object *PhysicsTestMotionResult2D::get_collider() const {
}
int PhysicsTestMotionResult2D::get_collider_shape() const {
-
return result.collider_shape;
}
void PhysicsTestMotionResult2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_motion"), &PhysicsTestMotionResult2D::get_motion);
ClassDB::bind_method(D_METHOD("get_motion_remainder"), &PhysicsTestMotionResult2D::get_motion_remainder);
ClassDB::bind_method(D_METHOD("get_collision_point"), &PhysicsTestMotionResult2D::get_collision_point);
@@ -521,7 +502,6 @@ void PhysicsTestMotionResult2D::_bind_methods() {
}
PhysicsTestMotionResult2D::PhysicsTestMotionResult2D() {
-
colliding = false;
result.collider_shape = 0;
@@ -530,15 +510,14 @@ PhysicsTestMotionResult2D::PhysicsTestMotionResult2D() {
///////////////////////////////////////
bool PhysicsServer2D::_body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin, const Ref<PhysicsTestMotionResult2D> &p_result) {
-
MotionResult *r = nullptr;
- if (p_result.is_valid())
+ if (p_result.is_valid()) {
r = p_result->get_result_ptr();
+ }
return body_test_motion(p_body, p_from, p_motion, p_infinite_inertia, p_margin, r);
}
void PhysicsServer2D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("line_shape_create"), &PhysicsServer2D::line_shape_create);
ClassDB::bind_method(D_METHOD("ray_shape_create"), &PhysicsServer2D::ray_shape_create);
ClassDB::bind_method(D_METHOD("segment_shape_create"), &PhysicsServer2D::segment_shape_create);
@@ -765,12 +744,10 @@ void PhysicsServer2D::_bind_methods() {
}
PhysicsServer2D::PhysicsServer2D() {
-
singleton = this;
}
PhysicsServer2D::~PhysicsServer2D() {
-
singleton = nullptr;
}
@@ -780,7 +757,6 @@ int PhysicsServer2DManager::default_server_priority = -1;
const String PhysicsServer2DManager::setting_property_name("physics/2d/physics_engine");
void PhysicsServer2DManager::on_servers_changed() {
-
String physics_servers("DEFAULT");
for (int i = get_servers_count() - 1; 0 <= i; --i) {
physics_servers += "," + get_server_name(i);
@@ -789,7 +765,6 @@ void PhysicsServer2DManager::on_servers_changed() {
}
void PhysicsServer2DManager::register_server(const String &p_name, CreatePhysicsServer2DCallback p_creat_callback) {
-
ERR_FAIL_COND(!p_creat_callback);
ERR_FAIL_COND(find_server_id(p_name) != -1);
physics_2d_servers.push_back(ClassInfo(p_name, p_creat_callback));
@@ -797,7 +772,6 @@ void PhysicsServer2DManager::register_server(const String &p_name, CreatePhysics
}
void PhysicsServer2DManager::set_default_server(const String &p_name, int p_priority) {
-
const int id = find_server_id(p_name);
ERR_FAIL_COND(id == -1); // Not found
if (default_server_priority < p_priority) {
@@ -807,7 +781,6 @@ void PhysicsServer2DManager::set_default_server(const String &p_name, int p_prio
}
int PhysicsServer2DManager::find_server_id(const String &p_name) {
-
for (int i = physics_2d_servers.size() - 1; 0 <= i; --i) {
if (p_name == physics_2d_servers[i].name) {
return i;
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index 8c833b390f..3553ec11a1 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -38,7 +38,6 @@
class PhysicsDirectSpaceState2D;
class PhysicsDirectBodyState2D : public Object {
-
GDCLASS(PhysicsDirectBodyState2D, Object);
protected:
@@ -97,7 +96,6 @@ class PhysicsShapeQueryResult2D;
//used for script
class PhysicsShapeQueryParameters2D : public Reference {
-
GDCLASS(PhysicsShapeQueryParameters2D, Reference);
friend class PhysicsDirectSpaceState2D;
RID shape;
@@ -143,7 +141,6 @@ public:
};
class PhysicsDirectSpaceState2D : public Object {
-
GDCLASS(PhysicsDirectSpaceState2D, Object);
Dictionary _intersect_ray(const Vector2 &p_from, const Vector2 &p_to, const Vector<RID> &p_exclude = Vector<RID>(), uint32_t p_layers = 0, bool p_collide_with_bodies = true, bool p_collide_with_areas = false);
@@ -160,7 +157,6 @@ protected:
public:
struct RayResult {
-
Vector2 position;
Vector2 normal;
RID rid;
@@ -173,7 +169,6 @@ public:
virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
struct ShapeResult {
-
RID rid;
ObjectID collider_id;
Object *collider;
@@ -191,7 +186,6 @@ public:
virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
struct ShapeRestInfo {
-
Vector2 point;
Vector2 normal;
RID rid;
@@ -207,7 +201,6 @@ public:
};
class PhysicsShapeQueryResult2D : public Reference {
-
GDCLASS(PhysicsShapeQueryResult2D, Reference);
Vector<PhysicsDirectSpaceState2D::ShapeResult> result;
@@ -230,7 +223,6 @@ public:
class PhysicsTestMotionResult2D;
class PhysicsServer2D : public Object {
-
GDCLASS(PhysicsServer2D, Object);
static PhysicsServer2D *singleton;
@@ -493,7 +485,6 @@ public:
virtual PhysicsDirectBodyState2D *body_get_direct_state(RID p_body) = 0;
struct MotionResult {
-
Vector2 motion;
Vector2 remainder;
@@ -516,7 +507,6 @@ public:
virtual bool body_test_motion(RID p_body, const Transform2D &p_from, const Vector2 &p_motion, bool p_infinite_inertia, float p_margin = 0.001, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0;
struct SeparationResult {
-
float collision_depth;
Vector2 collision_point;
Vector2 collision_normal;
@@ -607,7 +597,6 @@ public:
};
class PhysicsTestMotionResult2D : public Reference {
-
GDCLASS(PhysicsTestMotionResult2D, Reference);
PhysicsServer2D::MotionResult result;
@@ -640,11 +629,9 @@ typedef PhysicsServer2D *(*CreatePhysicsServer2DCallback)();
class PhysicsServer2DManager {
struct ClassInfo {
String name;
- CreatePhysicsServer2DCallback create_callback;
+ CreatePhysicsServer2DCallback create_callback = nullptr;
- ClassInfo() :
- name(""),
- create_callback(nullptr) {}
+ ClassInfo() {}
ClassInfo(String p_name, CreatePhysicsServer2DCallback p_create_callback) :
name(p_name),
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index a5a02fd1bd..2dd8ea3edb 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -37,7 +37,6 @@
PhysicsServer3D *PhysicsServer3D::singleton = nullptr;
void PhysicsDirectBodyState3D::integrate_forces() {
-
real_t step = get_step();
Vector3 lv = get_linear_velocity();
lv += get_total_gravity() * step;
@@ -46,13 +45,15 @@ void PhysicsDirectBodyState3D::integrate_forces() {
float linear_damp = 1.0 - step * get_total_linear_damp();
- if (linear_damp < 0) // reached zero in the given time
+ if (linear_damp < 0) { // reached zero in the given time
linear_damp = 0;
+ }
float angular_damp = 1.0 - step * get_total_angular_damp();
- if (angular_damp < 0) // reached zero in the given time
+ if (angular_damp < 0) { // reached zero in the given time
angular_damp = 0;
+ }
lv *= linear_damp;
av *= angular_damp;
@@ -62,19 +63,16 @@ void PhysicsDirectBodyState3D::integrate_forces() {
}
Object *PhysicsDirectBodyState3D::get_contact_collider_object(int p_contact_idx) const {
-
ObjectID objid = get_contact_collider_id(p_contact_idx);
Object *obj = ObjectDB::get_instance(objid);
return obj;
}
PhysicsServer3D *PhysicsServer3D::get_singleton() {
-
return singleton;
}
void PhysicsDirectBodyState3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_total_gravity"), &PhysicsDirectBodyState3D::get_total_gravity);
ClassDB::bind_method(D_METHOD("get_total_linear_damp"), &PhysicsDirectBodyState3D::get_total_linear_damp);
ClassDB::bind_method(D_METHOD("get_total_angular_damp"), &PhysicsDirectBodyState3D::get_total_angular_damp);
@@ -139,58 +137,50 @@ PhysicsDirectBodyState3D::PhysicsDirectBodyState3D() {}
///////////////////////////////////////////////////////
void PhysicsShapeQueryParameters3D::set_shape(const RES &p_shape) {
-
ERR_FAIL_COND(p_shape.is_null());
shape = p_shape->get_rid();
}
void PhysicsShapeQueryParameters3D::set_shape_rid(const RID &p_shape) {
-
shape = p_shape;
}
RID PhysicsShapeQueryParameters3D::get_shape_rid() const {
-
return shape;
}
void PhysicsShapeQueryParameters3D::set_transform(const Transform &p_transform) {
-
transform = p_transform;
}
-Transform PhysicsShapeQueryParameters3D::get_transform() const {
+Transform PhysicsShapeQueryParameters3D::get_transform() const {
return transform;
}
void PhysicsShapeQueryParameters3D::set_margin(float p_margin) {
-
margin = p_margin;
}
float PhysicsShapeQueryParameters3D::get_margin() const {
-
return margin;
}
void PhysicsShapeQueryParameters3D::set_collision_mask(int p_collision_mask) {
-
collision_mask = p_collision_mask;
}
-int PhysicsShapeQueryParameters3D::get_collision_mask() const {
+int PhysicsShapeQueryParameters3D::get_collision_mask() const {
return collision_mask;
}
void PhysicsShapeQueryParameters3D::set_exclude(const Vector<RID> &p_exclude) {
-
exclude.clear();
- for (int i = 0; i < p_exclude.size(); i++)
+ for (int i = 0; i < p_exclude.size(); i++) {
exclude.insert(p_exclude[i]);
+ }
}
Vector<RID> PhysicsShapeQueryParameters3D::get_exclude() const {
-
Vector<RID> ret;
ret.resize(exclude.size());
int idx = 0;
@@ -217,7 +207,6 @@ bool PhysicsShapeQueryParameters3D::is_collide_with_areas_enabled() const {
}
void PhysicsShapeQueryParameters3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("set_shape", "shape"), &PhysicsShapeQueryParameters3D::set_shape);
ClassDB::bind_method(D_METHOD("set_shape_rid", "shape"), &PhysicsShapeQueryParameters3D::set_shape_rid);
ClassDB::bind_method(D_METHOD("get_shape_rid"), &PhysicsShapeQueryParameters3D::get_shape_rid);
@@ -251,7 +240,6 @@ void PhysicsShapeQueryParameters3D::_bind_methods() {
}
PhysicsShapeQueryParameters3D::PhysicsShapeQueryParameters3D() {
-
margin = 0;
collision_mask = 0x7FFFFFFF;
collide_with_bodies = true;
@@ -261,16 +249,17 @@ PhysicsShapeQueryParameters3D::PhysicsShapeQueryParameters3D() {
/////////////////////////////////////
Dictionary PhysicsDirectSpaceState3D::_intersect_ray(const Vector3 &p_from, const Vector3 &p_to, const Vector<RID> &p_exclude, uint32_t p_collision_mask, bool p_collide_with_bodies, bool p_collide_with_areas) {
-
RayResult inters;
Set<RID> exclude;
- for (int i = 0; i < p_exclude.size(); i++)
+ for (int i = 0; i < p_exclude.size(); i++) {
exclude.insert(p_exclude[i]);
+ }
bool res = intersect_ray(p_from, p_to, inters, exclude, p_collision_mask, p_collide_with_bodies, p_collide_with_areas);
- if (!res)
+ if (!res) {
return Dictionary();
+ }
Dictionary d;
d["position"] = inters.position;
@@ -284,7 +273,6 @@ Dictionary PhysicsDirectSpaceState3D::_intersect_ray(const Vector3 &p_from, cons
}
Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, int p_max_results) {
-
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
Vector<ShapeResult> sr;
@@ -293,7 +281,6 @@ Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryPar
Array ret;
ret.resize(rc);
for (int i = 0; i < rc; i++) {
-
Dictionary d;
d["rid"] = sr[i].rid;
d["collider_id"] = sr[i].collider_id;
@@ -306,45 +293,48 @@ Array PhysicsDirectSpaceState3D::_intersect_shape(const Ref<PhysicsShapeQueryPar
}
Array PhysicsDirectSpaceState3D::_cast_motion(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, const Vector3 &p_motion) {
-
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
float closest_safe, closest_unsafe;
bool res = cast_motion(p_shape_query->shape, p_shape_query->transform, p_motion, p_shape_query->margin, closest_safe, closest_unsafe, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
- if (!res)
+ if (!res) {
return Array();
+ }
Array ret;
ret.resize(2);
ret[0] = closest_safe;
ret[1] = closest_unsafe;
return ret;
}
-Array PhysicsDirectSpaceState3D::_collide_shape(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, int p_max_results) {
+Array PhysicsDirectSpaceState3D::_collide_shape(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query, int p_max_results) {
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Array());
Vector<Vector3> ret;
ret.resize(p_max_results * 2);
int rc = 0;
bool res = collide_shape(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, ret.ptrw(), p_max_results, rc, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
- if (!res)
+ if (!res) {
return Array();
+ }
Array r;
r.resize(rc * 2);
- for (int i = 0; i < rc * 2; i++)
+ for (int i = 0; i < rc * 2; i++) {
r[i] = ret[i];
+ }
return r;
}
-Dictionary PhysicsDirectSpaceState3D::_get_rest_info(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query) {
+Dictionary PhysicsDirectSpaceState3D::_get_rest_info(const Ref<PhysicsShapeQueryParameters3D> &p_shape_query) {
ERR_FAIL_COND_V(!p_shape_query.is_valid(), Dictionary());
ShapeRestInfo sri;
bool res = rest_info(p_shape_query->shape, p_shape_query->transform, p_shape_query->margin, &sri, p_shape_query->exclude, p_shape_query->collision_mask, p_shape_query->collide_with_bodies, p_shape_query->collide_with_areas);
Dictionary r;
- if (!res)
+ if (!res) {
return r;
+ }
r["point"] = sri.point;
r["normal"] = sri.normal;
@@ -360,7 +350,6 @@ PhysicsDirectSpaceState3D::PhysicsDirectSpaceState3D() {
}
void PhysicsDirectSpaceState3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("intersect_ray", "from", "to", "exclude", "collision_mask", "collide_with_bodies", "collide_with_areas"), &PhysicsDirectSpaceState3D::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(true), DEFVAL(false));
ClassDB::bind_method(D_METHOD("intersect_shape", "shape", "max_results"), &PhysicsDirectSpaceState3D::_intersect_shape, DEFVAL(32));
ClassDB::bind_method(D_METHOD("cast_motion", "shape", "motion"), &PhysicsDirectSpaceState3D::_cast_motion);
@@ -369,23 +358,22 @@ void PhysicsDirectSpaceState3D::_bind_methods() {
}
int PhysicsShapeQueryResult3D::get_result_count() const {
-
return result.size();
}
-RID PhysicsShapeQueryResult3D::get_result_rid(int p_idx) const {
+RID PhysicsShapeQueryResult3D::get_result_rid(int p_idx) const {
return result[p_idx].rid;
}
-ObjectID PhysicsShapeQueryResult3D::get_result_object_id(int p_idx) const {
+ObjectID PhysicsShapeQueryResult3D::get_result_object_id(int p_idx) const {
return result[p_idx].collider_id;
}
-Object *PhysicsShapeQueryResult3D::get_result_object(int p_idx) const {
+Object *PhysicsShapeQueryResult3D::get_result_object(int p_idx) const {
return result[p_idx].collider;
}
-int PhysicsShapeQueryResult3D::get_result_object_shape(int p_idx) const {
+int PhysicsShapeQueryResult3D::get_result_object_shape(int p_idx) const {
return result[p_idx].shape;
}
@@ -393,7 +381,6 @@ PhysicsShapeQueryResult3D::PhysicsShapeQueryResult3D() {
}
void PhysicsShapeQueryResult3D::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("get_result_count"), &PhysicsShapeQueryResult3D::get_result_count);
ClassDB::bind_method(D_METHOD("get_result_rid", "idx"), &PhysicsShapeQueryResult3D::get_result_rid);
ClassDB::bind_method(D_METHOD("get_result_object_id", "idx"), &PhysicsShapeQueryResult3D::get_result_object_id);
@@ -404,7 +391,6 @@ void PhysicsShapeQueryResult3D::_bind_methods() {
///////////////////////////////////////
void PhysicsServer3D::_bind_methods() {
-
#ifndef _3D_DISABLED
ClassDB::bind_method(D_METHOD("shape_create", "type"), &PhysicsServer3D::shape_create);
@@ -724,13 +710,11 @@ void PhysicsServer3D::_bind_methods() {
}
PhysicsServer3D::PhysicsServer3D() {
-
ERR_FAIL_COND(singleton != nullptr);
singleton = this;
}
PhysicsServer3D::~PhysicsServer3D() {
-
singleton = nullptr;
}
@@ -740,7 +724,6 @@ int PhysicsServer3DManager::default_server_priority = -1;
const String PhysicsServer3DManager::setting_property_name("physics/3d/physics_engine");
void PhysicsServer3DManager::on_servers_changed() {
-
String physics_servers2("DEFAULT");
for (int i = get_servers_count() - 1; 0 <= i; --i) {
physics_servers2 += "," + get_server_name(i);
@@ -749,7 +732,6 @@ void PhysicsServer3DManager::on_servers_changed() {
}
void PhysicsServer3DManager::register_server(const String &p_name, CreatePhysicsServer3DCallback p_creat_callback) {
-
ERR_FAIL_COND(!p_creat_callback);
ERR_FAIL_COND(find_server_id(p_name) != -1);
physics_servers.push_back(ClassInfo(p_name, p_creat_callback));
@@ -757,7 +739,6 @@ void PhysicsServer3DManager::register_server(const String &p_name, CreatePhysics
}
void PhysicsServer3DManager::set_default_server(const String &p_name, int p_priority) {
-
const int id = find_server_id(p_name);
ERR_FAIL_COND(id == -1); // Not found
if (default_server_priority < p_priority) {
@@ -767,7 +748,6 @@ void PhysicsServer3DManager::set_default_server(const String &p_name, int p_prio
}
int PhysicsServer3DManager::find_server_id(const String &p_name) {
-
for (int i = physics_servers.size() - 1; 0 <= i; --i) {
if (p_name == physics_servers[i].name) {
return i;
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index 8ea8b22455..2465b40d3e 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -37,7 +37,6 @@
class PhysicsDirectSpaceState3D;
class PhysicsDirectBodyState3D : public Object {
-
GDCLASS(PhysicsDirectBodyState3D, Object);
protected:
@@ -98,7 +97,6 @@ public:
class PhysicsShapeQueryResult3D;
class PhysicsShapeQueryParameters3D : public Reference {
-
GDCLASS(PhysicsShapeQueryParameters3D, Reference);
friend class PhysicsDirectSpaceState3D;
@@ -141,7 +139,6 @@ public:
};
class PhysicsDirectSpaceState3D : public Object {
-
GDCLASS(PhysicsDirectSpaceState3D, Object);
private:
@@ -156,7 +153,6 @@ protected:
public:
struct ShapeResult {
-
RID rid;
ObjectID collider_id;
Object *collider;
@@ -166,7 +162,6 @@ public:
virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
struct RayResult {
-
Vector3 position;
Vector3 normal;
RID rid;
@@ -180,7 +175,6 @@ public:
virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_mask = 0xFFFFFFFF, bool p_collide_with_bodies = true, bool p_collide_with_areas = false) = 0;
struct ShapeRestInfo {
-
Vector3 point;
Vector3 normal;
RID rid;
@@ -201,7 +195,6 @@ public:
};
class PhysicsShapeQueryResult3D : public Reference {
-
GDCLASS(PhysicsShapeQueryResult3D, Reference);
Vector<PhysicsDirectSpaceState3D::ShapeResult> result;
@@ -222,7 +215,6 @@ public:
};
class PhysicsServer3D : public Object {
-
GDCLASS(PhysicsServer3D, Object);
static PhysicsServer3D *singleton;
@@ -481,7 +473,6 @@ public:
virtual PhysicsDirectBodyState3D *body_get_direct_state(RID p_body) = 0;
struct MotionResult {
-
Vector3 motion;
Vector3 remainder;
@@ -503,7 +494,6 @@ public:
virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, bool p_infinite_inertia, MotionResult *r_result = nullptr, bool p_exclude_raycast_shapes = true) = 0;
struct SeparationResult {
-
float collision_depth;
Vector3 collision_point;
Vector3 collision_normal;
@@ -781,11 +771,9 @@ typedef PhysicsServer3D *(*CreatePhysicsServer3DCallback)();
class PhysicsServer3DManager {
struct ClassInfo {
String name;
- CreatePhysicsServer3DCallback create_callback;
+ CreatePhysicsServer3DCallback create_callback = nullptr;
- ClassInfo() :
- name(""),
- create_callback(nullptr) {}
+ ClassInfo() {}
ClassInfo(String p_name, CreatePhysicsServer3DCallback p_create_callback) :
name(p_name),
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 556f9cd8e3..adca7b8055 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -62,6 +62,10 @@
#include "physics_3d/physics_server_3d_sw.h"
#include "physics_server_2d.h"
#include "physics_server_3d.h"
+#include "rendering/rasterizer.h"
+#include "rendering/rendering_device.h"
+#include "rendering/rendering_device_binds.h"
+
#include "rendering_server.h"
#include "servers/rendering/shader_types.h"
#include "xr/xr_interface.h"
@@ -79,7 +83,6 @@ PhysicsServer2D *_createGodotPhysics2DCallback() {
}
static bool has_server_feature_callback(const String &p_feature) {
-
if (RenderingServer::get_singleton()) {
if (RenderingServer::get_singleton()->has_os_feature(p_feature)) {
return true;
@@ -94,24 +97,23 @@ void preregister_server_types() {
}
void register_server_types() {
-
OS::get_singleton()->set_has_server_feature_callback(has_server_feature_callback);
ClassDB::register_virtual_class<DisplayServer>();
ClassDB::register_virtual_class<RenderingServer>();
ClassDB::register_class<AudioServer>();
- ClassDB::register_virtual_class<PhysicsServer3D>();
ClassDB::register_virtual_class<PhysicsServer2D>();
+ ClassDB::register_virtual_class<PhysicsServer3D>();
+ ClassDB::register_virtual_class<NavigationServer2D>();
+ ClassDB::register_virtual_class<NavigationServer3D>();
ClassDB::register_class<XRServer>();
ClassDB::register_class<CameraServer>();
+ ClassDB::register_virtual_class<RenderingDevice>();
+
ClassDB::register_virtual_class<XRInterface>();
ClassDB::register_class<XRPositionalTracker>();
- ClassDB::add_compatibility_class("ARVRServer", "XRServer");
- ClassDB::add_compatibility_class("ARVRInterface", "XRInterface");
- ClassDB::add_compatibility_class("ARVRPositionalTracker", "XRPositionalTracker");
-
ClassDB::register_virtual_class<AudioStream>();
ClassDB::register_virtual_class<AudioStreamPlayback>();
ClassDB::register_virtual_class<AudioStreamPlaybackResampled>();
@@ -161,6 +163,22 @@ void register_server_types() {
ClassDB::register_virtual_class<AudioEffectSpectrumAnalyzerInstance>();
}
+ ClassDB::register_virtual_class<RenderingDevice>();
+ ClassDB::register_class<RDTextureFormat>();
+ ClassDB::register_class<RDTextureView>();
+ ClassDB::register_class<RDAttachmentFormat>();
+ ClassDB::register_class<RDSamplerState>();
+ ClassDB::register_class<RDVertexAttribute>();
+ ClassDB::register_class<RDUniform>();
+ ClassDB::register_class<RDPipelineRasterizationState>();
+ ClassDB::register_class<RDPipelineMultisampleState>();
+ ClassDB::register_class<RDPipelineDepthStencilState>();
+ ClassDB::register_class<RDPipelineColorBlendStateAttachment>();
+ ClassDB::register_class<RDPipelineColorBlendState>();
+ ClassDB::register_class<RDShaderSource>();
+ ClassDB::register_class<RDShaderBytecode>();
+ ClassDB::register_class<RDShaderFile>();
+
ClassDB::register_class<CameraFeed>();
ClassDB::register_virtual_class<PhysicsDirectBodyState2D>();
@@ -190,12 +208,11 @@ void register_server_types() {
}
void unregister_server_types() {
-
memdelete(shader_types);
}
void register_server_singletons() {
-
+ Engine::get_singleton()->add_singleton(Engine::Singleton("DisplayServer", DisplayServer::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("RenderingServer", RenderingServer::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("AudioServer", AudioServer::get_singleton()));
Engine::get_singleton()->add_singleton(Engine::Singleton("PhysicsServer2D", PhysicsServer2D::get_singleton()));
diff --git a/servers/rendering/rasterizer.cpp b/servers/rendering/rasterizer.cpp
index f62e0a43a6..566a14b655 100644
--- a/servers/rendering/rasterizer.cpp
+++ b/servers/rendering/rasterizer.cpp
@@ -40,6 +40,7 @@ void RasterizerScene::InstanceDependency::instance_notify_changed(bool p_aabb, b
E->key()->dependency_changed(p_aabb, p_dependencies);
}
}
+
void RasterizerScene::InstanceDependency::instance_notify_deleted(RID p_deleted) {
for (Map<InstanceBase *, uint32_t>::Element *E = instances.front(); E; E = E->next()) {
E->key()->dependency_deleted(p_deleted);
@@ -63,7 +64,6 @@ RasterizerScene::InstanceDependency::~InstanceDependency() {
}
Rasterizer *Rasterizer::create() {
-
return _create_func();
}
@@ -72,6 +72,5 @@ RasterizerCanvas *RasterizerCanvas::singleton = nullptr;
RasterizerStorage *RasterizerStorage::base_singleton = nullptr;
RasterizerStorage::RasterizerStorage() {
-
base_singleton = this;
}
diff --git a/servers/rendering/rasterizer.h b/servers/rendering/rasterizer.h
index 955241e79c..e0d4432fd5 100644
--- a/servers/rendering/rasterizer.h
+++ b/servers/rendering/rasterizer.h
@@ -38,7 +38,6 @@
#include "core/self_list.h"
class RasterizerScene {
-
public:
/* SHADOW ATLAS API */
@@ -57,6 +56,7 @@ public:
virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0;
virtual void sky_set_mode(RID p_sky, RS::SkyMode p_samples) = 0;
virtual void sky_set_material(RID p_sky, RID p_material) = 0;
+ virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0;
/* ENVIRONMENT API */
@@ -94,6 +94,8 @@ public:
virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
+ virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0;
+
virtual bool is_environment(RID p_env) const = 0;
virtual RS::EnvironmentBG environment_get_background(RID p_env) const = 0;
virtual int environment_get_canvas_max_layer(RID p_env) const = 0;
@@ -160,9 +162,11 @@ public:
SelfList<InstanceBase> dependency_item;
- InstanceBase *lightmap_capture;
- RID lightmap;
- Vector<Color> lightmap_capture_data; //in a array (12 values) to avoid wasting space if unused. Alpha is unused, but needed to send to shader
+ InstanceBase *lightmap;
+ Rect2 lightmap_uv_scale;
+ int lightmap_slice_index;
+ uint32_t lightmap_cull_index;
+ Vector<Color> lightmap_sh; //spherical harmonic
AABB aabb;
AABB transformed_aabb;
@@ -178,8 +182,8 @@ public:
bool instance_allocated_shader_parameters = false;
int32_t instance_allocated_shader_parameters_offset = -1;
- virtual void dependency_deleted(RID p_dependency) = 0;
- virtual void dependency_changed(bool p_aabb, bool p_dependencies) = 0;
+ virtual void dependency_deleted(RID p_dependency) {}
+ virtual void dependency_changed(bool p_aabb, bool p_dependencies) {}
Set<InstanceDependency *> dependencies;
@@ -222,7 +226,6 @@ public:
InstanceBase() :
dependency_item(this) {
-
base_type = RS::INSTANCE_NONE;
cast_shadows = RS::SHADOW_CASTING_SETTING_ON;
receive_shadows = true;
@@ -233,7 +236,9 @@ public:
baked_light = false;
dynamic_gi = false;
redraw_if_visible = false;
- lightmap_capture = nullptr;
+ lightmap_slice_index = 0;
+ lightmap = nullptr;
+ lightmap_cull_index = 0;
}
virtual ~InstanceBase() {
@@ -268,7 +273,7 @@ public:
virtual bool gi_probe_needs_update(RID p_probe) const = 0;
virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) = 0;
- virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0;
+ virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) = 0;
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0;
virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0;
@@ -286,6 +291,8 @@ public:
virtual void sub_surface_scattering_set_quality(RS::SubSurfaceScatteringQuality p_quality) = 0;
virtual void sub_surface_scattering_set_scale(float p_scale, float p_depth_scale) = 0;
+ virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0;
+
virtual bool free(RID p_rid) = 0;
virtual void update() = 0;
@@ -293,7 +300,6 @@ public:
};
class RasterizerStorage {
-
Color default_clear_color;
public:
@@ -311,7 +317,7 @@ public:
//these two APIs can be used together or in combination with the others.
virtual RID texture_2d_placeholder_create() = 0;
- virtual RID texture_2d_layered_placeholder_create() = 0;
+ virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type) = 0;
virtual RID texture_3d_placeholder_create() = 0;
virtual Ref<Image> texture_2d_get(RID p_texture) const = 0;
@@ -593,29 +599,21 @@ public:
/* LIGHTMAP CAPTURE */
- struct LightmapCaptureOctree {
-
- enum {
- CHILD_EMPTY = 0xFFFFFFFF
- };
-
- uint16_t light[6][3]; //anisotropic light
- float alpha;
- uint32_t children[8];
- };
-
- virtual RID lightmap_capture_create() = 0;
- virtual void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) = 0;
- virtual AABB lightmap_capture_get_bounds(RID p_capture) const = 0;
- virtual void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) = 0;
- virtual Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const = 0;
- virtual void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) = 0;
- virtual Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const = 0;
- virtual void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) = 0;
- virtual int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const = 0;
- virtual void lightmap_capture_set_energy(RID p_capture, float p_energy) = 0;
- virtual float lightmap_capture_get_energy(RID p_capture) const = 0;
- virtual const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const = 0;
+ virtual RID lightmap_create() = 0;
+
+ virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0;
+ virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0;
+ virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) = 0;
+ virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) = 0;
+ virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const = 0;
+ virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const = 0;
+ virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const = 0;
+ virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const = 0;
+ virtual AABB lightmap_get_aabb(RID p_lightmap) const = 0;
+ virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) = 0;
+ virtual bool lightmap_is_interior(RID p_lightmap) const = 0;
+ virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0;
+ virtual float lightmap_get_probe_capture_update_speed() const = 0;
/* PARTICLES */
@@ -721,14 +719,16 @@ public:
Color get_default_clear_color() const {
return default_clear_color;
}
-#define TIMESTAMP_BEGIN() \
- { \
- if (RSG::storage->capturing_timestamps) RSG::storage->capture_timestamps_begin(); \
+#define TIMESTAMP_BEGIN() \
+ { \
+ if (RSG::storage->capturing_timestamps) \
+ RSG::storage->capture_timestamps_begin(); \
}
-#define RENDER_TIMESTAMP(m_text) \
- { \
- if (RSG::storage->capturing_timestamps) RSG::storage->capture_timestamp(m_text); \
+#define RENDER_TIMESTAMP(m_text) \
+ { \
+ if (RSG::storage->capturing_timestamps) \
+ RSG::storage->capture_timestamp(m_text); \
}
bool capturing_timestamps = false;
@@ -760,7 +760,6 @@ public:
};
struct Light {
-
bool enabled;
Color color;
Transform2D xform;
@@ -839,7 +838,6 @@ public:
struct Item;
struct TextureBinding {
-
TextureBindingID binding_id;
_FORCE_INLINE_ void create(RS::CanvasItemTextureFilter p_item_filter, RS::CanvasItemTextureRepeat p_item_repeat, RID p_texture, RID p_normalmap, RID p_specular, RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat, RID p_multimesh) {
@@ -857,7 +855,9 @@ public:
_FORCE_INLINE_ TextureBinding() { binding_id = 0; }
_FORCE_INLINE_ ~TextureBinding() {
- if (binding_id) singleton->free_texture_binding(binding_id);
+ if (binding_id) {
+ singleton->free_texture_binding(binding_id);
+ }
}
};
@@ -867,7 +867,6 @@ public:
//also easier to wrap to avoid mistakes
struct Polygon {
-
PolygonID polygon_id;
Rect2 rect_cache;
@@ -886,14 +885,15 @@ public:
_FORCE_INLINE_ Polygon() { polygon_id = 0; }
_FORCE_INLINE_ ~Polygon() {
- if (polygon_id) singleton->free_polygon(polygon_id);
+ if (polygon_id) {
+ singleton->free_polygon(polygon_id);
+ }
}
};
//item
struct Item {
-
//commands are allocated in blocks of 4k to improve performance
//and cache coherence.
//blocks always grow but never shrink.
@@ -907,7 +907,6 @@ public:
};
struct Command {
-
enum Type {
TYPE_RECT,
@@ -927,7 +926,6 @@ public:
};
struct CommandRect : public Command {
-
Rect2 rect;
Color modulate;
Rect2 source;
@@ -943,7 +941,6 @@ public:
};
struct CommandNinePatch : public Command {
-
Rect2 rect;
Rect2 source;
float margin[4];
@@ -960,7 +957,6 @@ public:
};
struct CommandPolygon : public Command {
-
RS::PrimitiveType primitive;
Polygon polygon;
Color specular_shininess;
@@ -971,7 +967,6 @@ public:
};
struct CommandPrimitive : public Command {
-
uint32_t point_count;
Vector2 points[4];
Vector2 uvs[4];
@@ -984,7 +979,6 @@ public:
};
struct CommandMesh : public Command {
-
RID mesh;
Transform2D transform;
Color modulate;
@@ -994,7 +988,6 @@ public:
};
struct CommandMultiMesh : public Command {
-
RID multimesh;
Color specular_shininess;
TextureBinding texture_binding;
@@ -1002,7 +995,6 @@ public:
};
struct CommandParticles : public Command {
-
RID particles;
Color specular_shininess;
TextureBinding texture_binding;
@@ -1010,13 +1002,11 @@ public:
};
struct CommandTransform : public Command {
-
Transform2D xform;
CommandTransform() { type = TYPE_TRANSFORM; }
};
struct CommandClipIgnore : public Command {
-
bool ignore;
CommandClipIgnore() {
type = TYPE_CLIP_IGNORE;
@@ -1066,13 +1056,13 @@ public:
Rect2 global_rect_cache;
const Rect2 &get_rect() const {
- if (custom_rect || (!rect_dirty && !update_when_visible))
+ if (custom_rect || (!rect_dirty && !update_when_visible)) {
return rect;
+ }
//must update rect
if (commands == nullptr) {
-
rect = Rect2();
rect_dirty = false;
return rect;
@@ -1085,29 +1075,24 @@ public:
const Item::Command *c = commands;
while (c) {
-
Rect2 r;
switch (c->type) {
case Item::Command::TYPE_RECT: {
-
const Item::CommandRect *crect = static_cast<const Item::CommandRect *>(c);
r = crect->rect;
} break;
case Item::Command::TYPE_NINEPATCH: {
-
const Item::CommandNinePatch *style = static_cast<const Item::CommandNinePatch *>(c);
r = style->rect;
} break;
case Item::Command::TYPE_POLYGON: {
-
const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
r = polygon->polygon.rect_cache;
} break;
case Item::Command::TYPE_PRIMITIVE: {
-
const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
for (uint32_t j = 0; j < primitive->point_count; j++) {
if (j == 0) {
@@ -1118,7 +1103,6 @@ public:
}
} break;
case Item::Command::TYPE_MESH: {
-
const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c);
AABB aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, RID());
@@ -1126,7 +1110,6 @@ public:
} break;
case Item::Command::TYPE_MULTIMESH: {
-
const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c);
AABB aabb = RasterizerStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh);
@@ -1134,7 +1117,6 @@ public:
} break;
case Item::Command::TYPE_PARTICLES: {
-
const Item::CommandParticles *particles_cmd = static_cast<const Item::CommandParticles *>(c);
if (particles_cmd->particles.is_valid()) {
AABB aabb = RasterizerStorage::base_singleton->particles_get_aabb(particles_cmd->particles);
@@ -1143,7 +1125,6 @@ public:
} break;
case Item::Command::TYPE_TRANSFORM: {
-
const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c);
xf = transform->xform;
found_xform = true;
@@ -1226,7 +1207,6 @@ public:
}
struct CustomData {
-
virtual ~CustomData() {}
};
@@ -1288,7 +1268,9 @@ public:
for (int i = 0; i < blocks.size(); i++) {
memfree(blocks[i].memory);
}
- if (copy_back_buffer) memdelete(copy_back_buffer);
+ if (copy_back_buffer) {
+ memdelete(copy_back_buffer);
+ }
if (custom_data) {
memdelete(custom_data);
}
@@ -1299,7 +1281,6 @@ public:
virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0;
struct LightOccluderInstance {
-
bool enabled;
RID canvas;
RID polygon;
@@ -1365,6 +1346,8 @@ public:
virtual void end_frame(bool p_swap_buffers) = 0;
virtual void finalize() = 0;
+ virtual uint64_t get_frame_number() const = 0;
+ virtual float get_frame_delta_time() const = 0;
virtual bool is_low_end() const = 0;
diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp b/servers/rendering/rasterizer_rd/light_cluster_builder.cpp
index f75308a975..efb48e6df7 100644
--- a/servers/rendering/rasterizer_rd/light_cluster_builder.cpp
+++ b/servers/rendering/rasterizer_rd/light_cluster_builder.cpp
@@ -45,7 +45,6 @@ void LightClusterBuilder::begin(const Transform &p_view_transform, const CameraM
}
void LightClusterBuilder::bake_cluster() {
-
float slice_depth = (z_near - z_far) / depth;
uint8_t *cluster_dataw = cluster_data.ptrw();
@@ -56,7 +55,6 @@ void LightClusterBuilder::bake_cluster() {
/* Step 1, create cell positions and count them */
for (uint32_t i = 0; i < item_count; i++) {
-
const Item &item = items[i];
int from_slice = Math::floor((z_near - (item.aabb.position.z + item.aabb.size.z)) / slice_depth);
@@ -70,7 +68,6 @@ void LightClusterBuilder::bake_cluster() {
to_slice = MIN((int)depth - 1, to_slice);
for (int j = from_slice; j <= to_slice; j++) {
-
Vector3 min = item.aabb.position;
Vector3 max = item.aabb.position + item.aabb.size;
@@ -126,7 +123,6 @@ void LightClusterBuilder::bake_cluster() {
sort_id_max = nearest_power_of_2_templated(sort_id_max + 1);
sort_ids = (SortID *)memrealloc(sort_ids, sizeof(SortID) * sort_id_max);
if (ids.size()) {
-
ids.resize(sort_id_max);
RD::get_singleton()->free(items_buffer);
items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * sort_id_max);
@@ -178,7 +174,6 @@ void LightClusterBuilder::bake_cluster() {
}
void LightClusterBuilder::setup(uint32_t p_width, uint32_t p_height, uint32_t p_depth) {
-
if (width == p_width && height == p_height && depth == p_depth) {
return;
}
@@ -208,6 +203,7 @@ void LightClusterBuilder::setup(uint32_t p_width, uint32_t p_height, uint32_t p_
RID LightClusterBuilder::get_cluster_texture() const {
return cluster_texture;
}
+
RID LightClusterBuilder::get_cluster_indices_buffer() const {
return items_buffer;
}
@@ -231,8 +227,8 @@ LightClusterBuilder::LightClusterBuilder() {
items_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 1024);
item_max = 1024;
}
-LightClusterBuilder::~LightClusterBuilder() {
+LightClusterBuilder::~LightClusterBuilder() {
if (cluster_data.size()) {
RD::get_singleton()->free(cluster_texture);
}
diff --git a/servers/rendering/rasterizer_rd/light_cluster_builder.h b/servers/rendering/rasterizer_rd/light_cluster_builder.h
index 78288dc620..b1da083dad 100644
--- a/servers/rendering/rasterizer_rd/light_cluster_builder.h
+++ b/servers/rendering/rasterizer_rd/light_cluster_builder.h
@@ -170,7 +170,6 @@ public:
_add_item(aabb, ITEM_TYPE_OMNI_LIGHT, light_count);
} break;
case LIGHT_TYPE_SPOT: {
-
float r = ld.radius;
real_t len = Math::tan(Math::deg2rad(ld.spot_aperture)) * r;
@@ -187,7 +186,6 @@ public:
}
_FORCE_INLINE_ void add_reflection_probe(const Transform &p_transform, const Vector3 &p_half_extents) {
-
if (unlikely(refprobe_count == refprobe_max)) {
refprobe_max = nearest_power_of_2_templated(refprobe_max + 1);
refprobes = (OrientedBoxData *)memrealloc(refprobes, sizeof(OrientedBoxData) * refprobe_max);
@@ -233,7 +231,6 @@ public:
}
_FORCE_INLINE_ void add_decal(const Transform &p_transform, const Vector3 &p_half_extents) {
-
if (unlikely(decal_count == decal_max)) {
decal_max = nearest_power_of_2_templated(decal_max + 1);
decals = (OrientedBoxData *)memrealloc(decals, sizeof(OrientedBoxData) * decal_max);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
index 1a21fdb4d7..4c477ca5f4 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.cpp
@@ -34,7 +34,6 @@
#include "rasterizer_rd.h"
void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_transform, float *p_mat4) {
-
p_mat4[0] = p_transform.elements[0][0];
p_mat4[1] = p_transform.elements[0][1];
p_mat4[2] = 0;
@@ -54,7 +53,6 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat4(const Transform2D &p_trans
}
void RasterizerCanvasRD::_update_transform_2d_to_mat2x4(const Transform2D &p_transform, float *p_mat2x4) {
-
p_mat2x4[0] = p_transform.elements[0][0];
p_mat2x4[1] = p_transform.elements[1][0];
p_mat2x4[2] = 0;
@@ -67,7 +65,6 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat2x4(const Transform2D &p_tra
}
void RasterizerCanvasRD::_update_transform_2d_to_mat2x3(const Transform2D &p_transform, float *p_mat2x3) {
-
p_mat2x3[0] = p_transform.elements[0][0];
p_mat2x3[1] = p_transform.elements[0][1];
p_mat2x3[2] = p_transform.elements[1][0];
@@ -77,7 +74,6 @@ void RasterizerCanvasRD::_update_transform_2d_to_mat2x3(const Transform2D &p_tra
}
void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform, float *p_mat4) {
-
p_mat4[0] = p_transform.basis.elements[0][0];
p_mat4[1] = p_transform.basis.elements[1][0];
p_mat4[2] = p_transform.basis.elements[2][0];
@@ -97,7 +93,6 @@ void RasterizerCanvasRD::_update_transform_to_mat4(const Transform &p_transform,
}
void RasterizerCanvasRD::_update_specular_shininess(const Color &p_transform, uint32_t *r_ss) {
-
*r_ss = uint32_t(CLAMP(p_transform.a * 255.0, 0, 255)) << 24;
*r_ss |= uint32_t(CLAMP(p_transform.b * 255.0, 0, 255)) << 16;
*r_ss |= uint32_t(CLAMP(p_transform.g * 255.0, 0, 255)) << 8;
@@ -105,7 +100,6 @@ void RasterizerCanvasRD::_update_specular_shininess(const Color &p_transform, ui
}
RID RasterizerCanvasRD::_create_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat, RID p_multimesh) {
-
Vector<RD::Uniform> uniform_set;
{ // COLOR TEXTURE
@@ -169,7 +163,6 @@ RID RasterizerCanvasRD::_create_texture_binding(RID p_texture, RID p_normalmap,
}
RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(RID p_texture, RID p_normalmap, RID p_specular, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat, RID p_multimesh) {
-
if (p_filter == RS::CANVAS_ITEM_TEXTURE_FILTER_DEFAULT) {
p_filter = default_samplers.default_filter;
}
@@ -221,7 +214,6 @@ RasterizerCanvas::TextureBindingID RasterizerCanvasRD::request_texture_binding(R
}
void RasterizerCanvasRD::free_texture_binding(TextureBindingID p_binding) {
-
TextureBinding **binding_ptr = bindings.texture_bindings.getptr(p_binding);
ERR_FAIL_COND(!binding_ptr);
TextureBinding *binding = *binding_ptr;
@@ -233,7 +225,6 @@ void RasterizerCanvasRD::free_texture_binding(TextureBindingID p_binding) {
}
void RasterizerCanvasRD::_dispose_bindings() {
-
while (bindings.to_dispose_list.first()) {
TextureBinding *binding = bindings.to_dispose_list.first()->self();
if (binding->uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(binding->uniform_set)) {
@@ -248,7 +239,6 @@ void RasterizerCanvasRD::_dispose_bindings() {
}
RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights) {
-
// Care must be taken to generate array formats
// in ways where they could be reused, so we will
// put single-occuring elements first, and repeated
@@ -273,7 +263,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
Vector<uint8_t> polygon_buffer;
polygon_buffer.resize(buffer_size * sizeof(float));
- Vector<RD::VertexDescription> descriptions;
+ Vector<RD::VertexAttribute> descriptions;
descriptions.resize(4);
Vector<RID> buffers;
buffers.resize(4);
@@ -284,7 +274,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
uint32_t *uptr = (uint32_t *)r;
uint32_t base_offset = 0;
{ //vertices
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
vd.offset = base_offset * sizeof(float);
vd.location = RS::ARRAY_VERTEX;
@@ -304,7 +294,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
//colors
if ((uint32_t)p_colors.size() == vertex_count || p_colors.size() == 1) {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
vd.offset = base_offset * sizeof(float);
vd.location = RS::ARRAY_COLOR;
@@ -332,7 +322,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
}
base_offset += 4;
} else {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
vd.offset = 0;
vd.location = RS::ARRAY_COLOR;
@@ -344,7 +334,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
//uvs
if ((uint32_t)p_uvs.size() == vertex_count) {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
vd.offset = base_offset * sizeof(float);
vd.location = RS::ARRAY_TEX_UV;
@@ -360,7 +350,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
}
base_offset += 2;
} else {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
vd.offset = 0;
vd.location = RS::ARRAY_TEX_UV;
@@ -372,7 +362,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
//bones
if ((uint32_t)p_indices.size() == vertex_count * 4 && (uint32_t)p_weights.size() == vertex_count * 4) {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
vd.offset = base_offset * sizeof(float);
vd.location = RS::ARRAY_BONES;
@@ -384,7 +374,6 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
const float *weight_ptr = p_weights.ptr();
for (uint32_t i = 0; i < vertex_count; i++) {
-
uint16_t *bone16w = (uint16_t *)&uptr[base_offset + i * stride];
uint16_t *weight16w = (uint16_t *)&uptr[base_offset + i * stride + 2];
@@ -401,7 +390,7 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
base_offset += 4;
} else {
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
vd.offset = 0;
vd.location = RS::ARRAY_BONES;
@@ -450,7 +439,6 @@ RasterizerCanvas::PolygonID RasterizerCanvasRD::request_polygon(const Vector<int
}
void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) {
-
PolygonBuffers *pb_ptr = polygon_buffers.polygons.getptr(p_polygon);
ERR_FAIL_COND(!pb_ptr);
@@ -470,7 +458,6 @@ void RasterizerCanvasRD::free_polygon(PolygonID p_polygon) {
}
Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD::DrawListID p_draw_list, uint32_t &flags) {
-
TextureBinding **texture_binding_ptr = bindings.texture_bindings.getptr(p_binding);
ERR_FAIL_COND_V(!texture_binding_ptr, Size2i());
TextureBinding *texture_binding = *texture_binding_ptr;
@@ -498,7 +485,6 @@ Size2i RasterizerCanvasRD::_bind_texture_binding(TextureBindingID p_binding, RD:
////////////////////
void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_item, RD::FramebufferFormatID p_framebuffer_format, const Transform2D &p_canvas_transform_inverse, Item *&current_clip, Light *p_lights, PipelineVariants *p_pipeline_variants) {
-
//create an empty push constant
PushConstant push_constant;
@@ -541,13 +527,10 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
PipelineLightMode light_mode;
{
-
Light *light = p_lights;
while (light) {
-
if (light->render_index_cache >= 0 && p_item->light_mask & light->item_mask && p_item->z_final >= light->z_min && p_item->z_final <= light->z_max && p_item->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) {
-
uint32_t light_index = light->render_index_cache;
push_constant.lights[light_count >> 2] |= light_index << ((light_count & 3) * 8);
@@ -575,7 +558,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
}
{
-
RID &canvas_item_state = light_count ? state_data->state_uniform_set_with_light : state_data->state_uniform_set;
bool invalid_uniform = canvas_item_state.is_valid() && !RD::get_singleton()->uniform_set_is_valid(canvas_item_state);
@@ -640,7 +622,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
}
{
-
RD::Uniform u_lights;
u_lights.type = RD::UNIFORM_TYPE_TEXTURE;
u_lights.binding = 4;
@@ -652,7 +633,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
//lights
for (uint32_t i = 0; i < state.max_lights_per_item; i++) {
if (i < light_count) {
-
CanvasLight *cl = canvas_light_owner.getornull(light_cache[i]->light_internal);
ERR_CONTINUE(!cl);
@@ -711,7 +691,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
switch (c->type) {
case Item::Command::TYPE_RECT: {
-
const Item::CommandRect *rect = static_cast<const Item::CommandRect *>(c);
//bind pipeline
@@ -811,7 +790,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
} break;
case Item::Command::TYPE_NINEPATCH: {
-
const Item::CommandNinePatch *np = static_cast<const Item::CommandNinePatch *>(c);
//bind pipeline
@@ -839,12 +817,10 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
Rect2 dst_rect(np->rect.position.x, np->rect.position.y, np->rect.size.x, np->rect.size.y);
if (texpixel_size == Size2()) {
-
texpixel_size = Size2(1, 1);
src_rect = Rect2(0, 0, 1, 1);
} else {
-
if (np->source != Rect2()) {
src_rect = Rect2(np->source.position.x * texpixel_size.width, np->source.position.y * texpixel_size.height, np->source.size.x * texpixel_size.width, np->source.size.y * texpixel_size.height);
texpixel_size = Size2(1.0 / np->source.size.width, 1.0 / np->source.size.height);
@@ -889,7 +865,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
} break;
case Item::Command::TYPE_POLYGON: {
-
const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
PolygonBuffers *pb = polygon_buffers.polygons.getptr(polygon->polygon.polygon_id);
@@ -945,7 +920,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
} break;
case Item::Command::TYPE_PRIMITIVE: {
-
const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
//bind pipeline
@@ -1291,23 +1265,18 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
} break;
#endif
case Item::Command::TYPE_TRANSFORM: {
-
const Item::CommandTransform *transform = static_cast<const Item::CommandTransform *>(c);
_update_transform_2d_to_mat2x3(base_transform * transform->xform, push_constant.world);
} break;
case Item::Command::TYPE_CLIP_IGNORE: {
-
const Item::CommandClipIgnore *ci = static_cast<const Item::CommandClipIgnore *>(c);
if (current_clip) {
-
if (ci->ignore != reclip) {
-
if (ci->ignore) {
RD::get_singleton()->draw_list_disable_scissor(p_draw_list);
reclip = true;
} else {
-
RD::get_singleton()->draw_list_enable_scissor(p_draw_list, current_clip->final_clip_rect);
reclip = false;
}
@@ -1327,7 +1296,6 @@ void RasterizerCanvasRD::_render_item(RD::DrawListID p_draw_list, const Item *p_
}
void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count, const Transform2D &p_canvas_transform_inverse, Light *p_lights, RID p_screen_uniform_set) {
-
Item *current_clip = nullptr;
Transform2D canvas_transform_inverse = p_canvas_transform_inverse;
@@ -1357,33 +1325,27 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
PipelineVariants *pipeline_variants = &shader.pipeline_variants;
for (int i = 0; i < p_item_count; i++) {
-
Item *ci = items[i];
if (current_clip != ci->final_clip_owner) {
-
current_clip = ci->final_clip_owner;
//setup clip
if (current_clip) {
-
RD::get_singleton()->draw_list_enable_scissor(draw_list, current_clip->final_clip_rect);
} else {
-
RD::get_singleton()->draw_list_disable_scissor(draw_list);
}
}
if (ci->material != prev_material) {
-
MaterialData *material_data = nullptr;
if (ci->material.is_valid()) {
material_data = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D);
}
if (material_data) {
-
if (material_data->shader_data->version.is_valid() && material_data->shader_data->valid) {
pipeline_variants = &material_data->shader_data->pipeline_variants;
if (material_data->uniform_set.is_valid()) {
@@ -1406,7 +1368,6 @@ void RasterizerCanvasRD::_render_items(RID p_to_render_target, int p_item_count,
}
void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform) {
-
int item_count = 0;
//setup canvas state uniforms if needed
@@ -1447,12 +1408,10 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
//setup lights if exist
{
-
Light *l = p_light_list;
uint32_t index = 0;
while (l) {
-
if (index == state.max_lights_per_render) {
l->render_index_cache = -1;
l = l->next_ptr;
@@ -1513,7 +1472,6 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
RID screen_uniform_set;
while (ci) {
-
if (ci->copy_back_buffer) {
backbuffer_copy = true;
@@ -1527,7 +1485,6 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
if (ci->material.is_valid()) {
MaterialData *md = (MaterialData *)storage->material_get_data(ci->material, RasterizerStorageRD::SHADER_TYPE_2D);
if (md && md->shader_data->valid) {
-
if (md->shader_data->uses_screen_texture) {
if (!material_screen_texture_found) {
backbuffer_copy = true;
@@ -1539,8 +1496,8 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
}
}
- if (md->last_frame != RasterizerRD::get_frame_number()) {
- md->last_frame = RasterizerRD::get_frame_number();
+ if (md->last_frame != RasterizerRD::singleton->get_frame_number()) {
+ md->last_frame = RasterizerRD::singleton->get_frame_number();
if (!RD::get_singleton()->uniform_set_is_valid(md->uniform_set)) {
// uniform set may be gone because a dependency was erased. In this case, it will happen
// if a texture is deleted, so just re-create it.
@@ -1574,7 +1531,6 @@ void RasterizerCanvasRD::canvas_render_items(RID p_to_render_target, Item *p_ite
}
RID RasterizerCanvasRD::light_create() {
-
CanvasLight canvas_light;
canvas_light.shadow.size = 0;
return canvas_light_owner.make_rid(canvas_light);
@@ -1589,6 +1545,7 @@ void RasterizerCanvasRD::light_set_texture(RID p_rid, RID p_texture) {
cl->texture = p_texture;
}
+
void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_resolution) {
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND(!cl);
@@ -1598,7 +1555,6 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re
}
if (cl->shadow.texture.is_valid()) {
-
RD::get_singleton()->free(cl->shadow.fb);
RD::get_singleton()->free(cl->shadow.depth);
RD::get_singleton()->free(cl->shadow.texture);
@@ -1608,7 +1564,6 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re
}
if (p_enable) {
-
Vector<RID> fb_textures;
{ //texture
@@ -1641,12 +1596,10 @@ void RasterizerCanvasRD::light_set_use_shadow(RID p_rid, bool p_enable, int p_re
}
void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders) {
-
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND(cl->shadow.texture.is_null());
for (int i = 0; i < 4; i++) {
-
//make sure it remains orthogonal, makes easy to read angle later
//light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1));
@@ -1691,11 +1644,9 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_lig
LightOccluderInstance *instance = p_occluders;
while (instance) {
-
OccluderPolygon *co = occluder_polygon_owner.getornull(instance->occluder);
if (!co || co->index_array.is_null() || !(p_light_mask & instance->light_mask)) {
-
instance = instance->next;
continue;
}
@@ -1717,7 +1668,6 @@ void RasterizerCanvasRD::light_update_shadow(RID p_rid, const Transform2D &p_lig
}
RID RasterizerCanvasRD::occluder_polygon_create() {
-
OccluderPolygon occluder;
occluder.point_count = 0;
occluder.cull_mode = RS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
@@ -1725,12 +1675,10 @@ RID RasterizerCanvasRD::occluder_polygon_create() {
}
void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, const Vector<Vector2> &p_lines) {
-
OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder);
ERR_FAIL_COND(!oc);
if (oc->point_count != p_lines.size() && oc->vertex_array.is_valid()) {
-
RD::get_singleton()->free(oc->vertex_array);
RD::get_singleton()->free(oc->vertex_buffer);
RD::get_singleton()->free(oc->index_array);
@@ -1743,7 +1691,6 @@ void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, con
}
if (p_lines.size()) {
-
Vector<uint8_t> geometry;
Vector<uint8_t> indices;
int lc = p_lines.size();
@@ -1762,7 +1709,6 @@ void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, con
const int POLY_HEIGHT = 16384;
for (int i = 0; i < lc / 2; i++) {
-
vwptr[i * 12 + 0] = lr[i * 2 + 0].x;
vwptr[i * 12 + 1] = lr[i * 2 + 0].y;
vwptr[i * 12 + 2] = POLY_HEIGHT;
@@ -1813,6 +1759,7 @@ void RasterizerCanvasRD::occluder_polygon_set_shape_as_lines(RID p_occluder, con
}
}
}
+
void RasterizerCanvasRD::occluder_polygon_set_cull_mode(RID p_occluder, RS::CanvasOccluderPolygonCullMode p_mode) {
OccluderPolygon *oc = occluder_polygon_owner.getornull(p_occluder);
ERR_FAIL_COND(!oc);
@@ -1895,12 +1842,10 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
switch (blend_mode) {
case BLEND_MODE_DISABLED: {
-
// nothing to do here, disabled by default
} break;
case BLEND_MODE_MIX: {
-
attachment.enable_blend = true;
attachment.alpha_blend_op = RD::BLEND_OP_ADD;
attachment.color_blend_op = RD::BLEND_OP_ADD;
@@ -1911,7 +1856,6 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
} break;
case BLEND_MODE_ADD: {
-
attachment.enable_blend = true;
attachment.alpha_blend_op = RD::BLEND_OP_ADD;
attachment.color_blend_op = RD::BLEND_OP_ADD;
@@ -1922,7 +1866,6 @@ void RasterizerCanvasRD::ShaderData::set_code(const String &p_code) {
} break;
case BLEND_MODE_SUB: {
-
attachment.enable_blend = true;
attachment.alpha_blend_op = RD::BLEND_OP_SUBTRACT;
attachment.color_blend_op = RD::BLEND_OP_SUBTRACT;
@@ -2014,12 +1957,11 @@ void RasterizerCanvasRD::ShaderData::set_default_texture_param(const StringName
default_texture_params[p_name] = p_texture;
}
}
-void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
Map<int, StringName> order;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
-
if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) {
continue;
}
@@ -2031,7 +1973,6 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_
}
for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
-
PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]);
pi.name = E->get();
p_param_list->push_back(pi);
@@ -2039,9 +1980,7 @@ void RasterizerCanvasRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_
}
void RasterizerCanvasRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const {
-
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
-
if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
@@ -2066,9 +2005,11 @@ bool RasterizerCanvasRD::ShaderData::is_param_texture(const StringName &p_param)
bool RasterizerCanvasRD::ShaderData::is_animated() const {
return false;
}
+
bool RasterizerCanvasRD::ShaderData::casts_shadows() const {
return false;
}
+
Variant RasterizerCanvasRD::ShaderData::get_default_parameter(const StringName &p_parameter) const {
if (uniforms.has(p_parameter)) {
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
@@ -2097,8 +2038,8 @@ RasterizerStorageRD::ShaderData *RasterizerCanvasRD::_create_shader_func() {
ShaderData *shader_data = memnew(ShaderData);
return shader_data;
}
-void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
RasterizerCanvasRD *canvas_singleton = (RasterizerCanvasRD *)RasterizerCanvas::singleton;
if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
@@ -2123,7 +2064,6 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V
//check whether buffer changed
if (p_uniform_dirty && ubo_data.size()) {
-
update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
}
@@ -2142,7 +2082,6 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V
}
if (p_textures_dirty && tex_uniform_count) {
-
update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), false);
}
@@ -2201,6 +2140,7 @@ void RasterizerCanvasRD::MaterialData::update_parameters(const Map<StringName, V
uniform_set = RD::get_singleton()->uniform_set_create(uniforms, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), 1);
}
+
RasterizerCanvasRD::MaterialData::~MaterialData() {
if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
RD::get_singleton()->free(uniform_set);
@@ -2423,8 +2363,8 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
}
//pipelines
- Vector<RD::VertexDescription> vf;
- RD::VertexDescription vd;
+ Vector<RD::VertexAttribute> vf;
+ RD::VertexAttribute vd;
vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
vd.location = 0;
vd.offset = 0;
@@ -2514,7 +2454,6 @@ RasterizerCanvasRD::RasterizerCanvasRD(RasterizerStorageRD *p_storage) {
}
bool RasterizerCanvasRD::free(RID p_rid) {
-
if (canvas_light_owner.owns(p_rid)) {
CanvasLight *cl = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND_V(!cl, false);
@@ -2531,7 +2470,6 @@ bool RasterizerCanvasRD::free(RID p_rid) {
}
RasterizerCanvasRD::~RasterizerCanvasRD() {
-
//canvas state
{
@@ -2547,14 +2485,12 @@ RasterizerCanvasRD::~RasterizerCanvasRD() {
//shadow rendering
{
-
shadow_render.shader.version_free(shadow_render.shader_version);
//this will also automatically clear all pipelines
RD::get_singleton()->free(state.shadow_sampler);
}
//bindings
{
-
free_texture_binding(bindings.default_empty);
//dispose pending
diff --git a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
index 4d47b3e13b..bfe4e61f47 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_canvas_rd.h
@@ -40,7 +40,6 @@
#include "servers/rendering/rendering_device.h"
class RasterizerCanvasRD : public RasterizerCanvas {
-
RasterizerStorageRD *storage;
enum ShaderVariant {
@@ -149,7 +148,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
} shader;
struct ShaderData : public RasterizerStorageRD::ShaderData {
-
enum BlendMode { //used internally
BLEND_MODE_MIX,
BLEND_MODE_ADD,
@@ -313,7 +311,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
/******************/
struct CanvasLight {
-
RID texture;
struct {
int size;
@@ -333,7 +330,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
};
struct OccluderPolygon {
-
RS::CanvasOccluderPolygonCullMode cull_mode;
int point_count;
RID vertex_buffer;
@@ -371,7 +367,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
//state that does not vary across rendering all items
struct ItemStateData : public Item::CustomData {
-
struct LightCache {
uint64_t light_version;
Light *light;
@@ -382,7 +377,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
RID state_uniform_set_with_light;
RID state_uniform_set;
ItemStateData() {
-
for (int i = 0; i < DEFAULT_MAX_LIGHTS_PER_ITEM; i++) {
light_cache[i].light_version = 0;
light_cache[i].light = nullptr;
@@ -401,7 +395,6 @@ class RasterizerCanvasRD : public RasterizerCanvas {
};
struct State {
-
//state buffer
struct Buffer {
float canvas_transform[16];
@@ -489,7 +482,7 @@ public:
void canvas_render_items(RID p_to_render_target, Item *p_item_list, const Color &p_modulate, Light *p_light_list, const Transform2D &p_canvas_transform);
- void canvas_debug_viewport_shadows(Light *p_lights_with_shadow){};
+ void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {}
void draw_window_margins(int *p_margins, RID *p_margin_textures) {}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
index d469dd97ca..303cb7ad42 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.cpp
@@ -51,17 +51,14 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar
}
static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
-
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
-
p_array[i * 4 + j] = p_mtx.matrix[i][j];
}
}
}
RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) {
-
if (image_to_uniform_set_cache.has(p_image)) {
RID uniform_set = image_to_uniform_set_cache[p_image];
if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
@@ -83,7 +80,6 @@ RID RasterizerEffectsRD::_get_uniform_set_from_image(RID p_image) {
}
RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) {
-
if (texture_to_uniform_set_cache.has(p_texture)) {
RID uniform_set = texture_to_uniform_set_cache[p_texture];
if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
@@ -107,7 +103,6 @@ RID RasterizerEffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use
}
RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) {
-
if (texture_to_compute_uniform_set_cache.has(p_texture)) {
RID uniform_set = texture_to_compute_uniform_set_cache[p_texture];
if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
@@ -131,7 +126,6 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bo
}
RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_texture1, RID p_texture2, bool p_use_mipmaps) {
-
TexturePair tp;
tp.texture1 = p_texture1;
tp.texture2 = p_texture2;
@@ -169,7 +163,6 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_texture_pair(RID p_textur
}
RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1, RID p_texture2) {
-
TexturePair tp;
tp.texture1 = p_texture1;
tp.texture2 = p_texture2;
@@ -205,7 +198,6 @@ RID RasterizerEffectsRD::_get_compute_uniform_set_from_image_pair(RID p_texture1
}
void RasterizerEffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) {
-
zeromem(&copy_to_fb.push_constant, sizeof(CopyToFbPushConstant));
copy_to_fb.push_constant.use_section = true;
@@ -249,7 +241,6 @@ void RasterizerEffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_fr
}
void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst) {
-
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
if (p_flip_y) {
copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
@@ -282,8 +273,30 @@ void RasterizerEffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_textu
RD::get_singleton()->compute_list_end();
}
-void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) {
+void RasterizerEffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array) {
+ zeromem(&copy.push_constant, sizeof(CopyPushConstant));
+
+ copy.push_constant.section[0] = 0;
+ copy.push_constant.section[1] = 0;
+ copy.push_constant.section[2] = p_panorama_size.width;
+ copy.push_constant.section[3] = p_panorama_size.height;
+ copy.push_constant.target[0] = 0;
+ copy.push_constant.target[1] = 0;
+ copy.push_constant.camera_z_far = p_lod;
+
+ int32_t x_groups = (p_panorama_size.width - 1) / 8 + 1;
+ int32_t y_groups = (p_panorama_size.height - 1) / 8 + 1;
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_is_array ? COPY_MODE_CUBE_ARRAY_TO_PANORAMA : COPY_MODE_CUBE_TO_PANORAMA]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cube), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_panorama), 3);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &copy.push_constant, sizeof(CopyPushConstant));
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 1);
+ RD::get_singleton()->compute_list_end();
+}
+
+void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) {
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
if (p_flip_y) {
copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
@@ -311,7 +324,6 @@ void RasterizerEffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_textu
}
void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) {
-
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
if (p_flip_y) {
copy.push_constant.flags |= COPY_FLAG_FLIP_Y;
@@ -337,7 +349,6 @@ void RasterizerEffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest
}
void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Rect2i &p_region, bool p_8bit_dst) {
-
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
uint32_t base_flags = 0;
@@ -373,7 +384,6 @@ void RasterizerEffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture,
}
void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) {
-
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW;
@@ -425,7 +435,6 @@ void RasterizerEffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_texture,
}
void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_roughness, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) {
-
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
int32_t x_groups = (p_screen_size.width - 1) / 8 + 1;
@@ -454,7 +463,6 @@ void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, R
}
{
-
ssr.push_constant.camera_z_far = p_camera.get_z_far();
ssr.push_constant.camera_z_near = p_camera.get_z_near();
ssr.push_constant.orthogonal = p_camera.is_orthogonal();
@@ -494,7 +502,6 @@ void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, R
}
if (p_roughness_quality != RS::ENV_SSR_ROUGNESS_QUALITY_DISABLED) {
-
//blurr
RD::get_singleton()->compute_list_add_barrier(compute_list);
@@ -551,7 +558,6 @@ void RasterizerEffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal, R
}
void RasterizerEffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) {
-
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
int32_t x_groups = (p_screen_size.width - 1) / 8 + 1;
@@ -598,11 +604,9 @@ void RasterizerEffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2,
}
void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection) {
-
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>());
if (p_reflection.is_valid()) {
-
if (p_base.is_valid()) {
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_SSR].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2);
@@ -614,7 +618,6 @@ void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular,
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_reflection), 1);
} else {
-
if (p_base.is_valid()) {
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, specular_merge.pipelines[SPECULAR_MERGE_ADD].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer)));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_base), 2);
@@ -631,7 +634,6 @@ void RasterizerEffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular,
}
void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) {
-
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
copy.push_constant.section[0] = 0;
@@ -652,7 +654,6 @@ void RasterizerEffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_textur
}
void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, float p_z_near, float p_z_far, float p_bias, bool p_dp_flip) {
-
CopyToDPPushConstant push_constant;
push_constant.screen_size[0] = p_rect.size.x;
push_constant.screen_size[1] = p_rect.size.y;
@@ -676,7 +677,6 @@ void RasterizerEffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dest
}
void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer, const TonemapSettings &p_settings) {
-
zeromem(&tonemap.push_constant, sizeof(TonemapPushConstant));
tonemap.push_constant.use_bcs = p_settings.use_bcs;
@@ -719,7 +719,6 @@ void RasterizerEffectsRD::tonemapper(RID p_source_color, RID p_dst_framebuffer,
}
void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) {
-
luminance_reduce.push_constant.source_size[0] = p_source_size.x;
luminance_reduce.push_constant.source_size[1] = p_source_size.y;
luminance_reduce.push_constant.max_luminance = p_max_luminance;
@@ -729,12 +728,10 @@ void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
for (int i = 0; i < p_reduce.size(); i++) {
-
if (i == 0) {
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, luminance_reduce.pipelines[LUMINANCE_REDUCE_READ]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_texture), 0);
} else {
-
RD::get_singleton()->compute_list_add_barrier(compute_list); //needs barrier, wait until previous is done
if (i == p_reduce.size() - 1 && !p_set) {
@@ -764,7 +761,6 @@ void RasterizerEffectsRD::luminance_reduction(RID p_source_texture, const Size2i
}
void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_halfsize_texture1, RID p_halfsize_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) {
-
bokeh.push_constant.blur_far_active = p_dof_far;
bokeh.push_constant.blur_far_begin = p_dof_far_begin;
bokeh.push_constant.blur_far_end = p_dof_far_begin + p_dof_far_size;
@@ -807,7 +803,6 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con
RD::get_singleton()->compute_list_add_barrier(compute_list);
if (p_bokeh_shape == RS::DOF_BOKEH_BOX || p_bokeh_shape == RS::DOF_BOKEH_HEXAGON) {
-
//second pass
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.pipelines[p_bokeh_shape == RS::DOF_BOKEH_BOX ? BOKEH_GEN_BOKEH_BOX : BOKEH_GEN_BOKEH_HEXAGONAL]);
@@ -843,7 +838,6 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con
bokeh.push_constant.second_pass = true;
if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) {
-
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_halfsize_texture2), 0);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_halfsize_texture1), 1);
} else {
@@ -927,7 +921,6 @@ void RasterizerEffectsRD::bokeh_dof(RID p_base_texture, RID p_depth_texture, con
}
void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer, const Size2i &p_depth_buffer_size, RID p_depth_mipmaps_texture, const Vector<RID> &depth_mipmaps, RID p_ao1, bool p_half_size, RID p_ao2, RID p_upscale_buffer, float p_intensity, float p_radius, float p_bias, const CameraMatrix &p_projection, RS::EnvironmentSSAOQuality p_quality, RS::EnvironmentSSAOBlur p_blur, float p_edge_sharpness) {
-
//minify first
ssao.minify_push_constant.orthogonal = p_projection.is_orthogonal();
ssao.minify_push_constant.z_near = p_projection.get_z_near();
@@ -943,7 +936,6 @@ void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer,
// Minify the depth buffer.
for (int i = 0; i < depth_mipmaps.size(); i++) {
-
if (i == 0) {
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[SSAO_MINIFY_FIRST]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_depth_buffer), 0);
@@ -1027,7 +1019,6 @@ void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer,
ssao.blur_push_constant.axis[1] = 0;
if (p_blur != RS::ENV_SSAO_BLUR_DISABLED) {
-
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, ssao.pipelines[p_half_size ? SSAO_BLUR_PASS_HALF : SSAO_BLUR_PASS]);
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_ao1), 0);
if (p_half_size) {
@@ -1083,7 +1074,6 @@ void RasterizerEffectsRD::generate_ssao(RID p_depth_buffer, RID p_normal_buffer,
}
void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) {
-
roughness_limiter.push_constant.screen_size[0] = p_size.x;
roughness_limiter.push_constant.screen_size[1] = p_size.y;
roughness_limiter.push_constant.curve = p_curve;
@@ -1104,7 +1094,6 @@ void RasterizerEffectsRD::roughness_limit(RID p_source_normal, RID p_roughness,
}
void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) {
-
zeromem(&roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id;
@@ -1130,7 +1119,6 @@ void RasterizerEffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_
}
void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) {
-
cubemap_downsampler.push_constant.face_size = p_size.x;
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
@@ -1149,7 +1137,6 @@ void RasterizerEffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cu
}
void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) {
-
Vector<RD::Uniform> uniforms;
for (int i = 0; i < p_dest_cubemap.size(); i++) {
RD::Uniform u;
@@ -1179,7 +1166,6 @@ void RasterizerEffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_des
}
void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_fb, RID p_samplers, RID p_lights, RenderPipelineVertexFormatCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const CameraMatrix &p_camera, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position) {
-
SkyPushConstant sky_push_constant;
zeromem(&sky_push_constant, sizeof(SkyPushConstant));
@@ -1202,7 +1188,9 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_
RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, p_pipeline->get_render_pipeline(RD::INVALID_ID, fb_format));
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_samplers, 0);
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_uniform_set, 1);
+ if (p_uniform_set.is_valid()) { //material may not have uniform set
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_uniform_set, 1);
+ }
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_texture_set, 2);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_lights, 3);
@@ -1214,7 +1202,6 @@ void RasterizerEffectsRD::render_sky(RD::DrawListID p_list, float p_time, RID p_
}
RasterizerEffectsRD::RasterizerEffectsRD() {
-
{ // Initialize copy
Vector<String> copy_modes;
copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n");
@@ -1226,6 +1213,8 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n");
copy_modes.push_back("\n#define MODE_MIPMAP\n");
copy_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n");
+ copy_modes.push_back("\n#define MODE_CUBEMAP_TO_PANORAMA\n");
+ copy_modes.push_back("\n#define MODE_CUBEMAP_ARRAY_TO_PANORAMA\n");
copy.shader.initialize(copy_modes);
zeromem(&copy.push_constant, sizeof(CopyPushConstant));
@@ -1464,7 +1453,6 @@ RasterizerEffectsRD::RasterizerEffectsRD() {
blend_additive.attachments.push_back(ba);
for (int i = 0; i < SPECULAR_MERGE_MAX; i++) {
-
RD::PipelineColorBlendState blend_state;
if (i == SPECULAR_MERGE_ADDITIVE_ADD || i == SPECULAR_MERGE_ADDITIVE_SSR) {
blend_state = blend_additive;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
index 531591442b..8a55d2d13c 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_effects_rd.h
@@ -55,7 +55,6 @@
#include "servers/rendering_server.h"
class RasterizerEffectsRD {
-
enum CopyMode {
COPY_MODE_GAUSSIAN_COPY,
COPY_MODE_GAUSSIAN_COPY_8BIT,
@@ -66,6 +65,8 @@ class RasterizerEffectsRD {
COPY_MODE_SIMPLY_COPY_DEPTH,
COPY_MODE_MIPMAP,
COPY_MODE_LINEARIZE_DEPTH,
+ COPY_MODE_CUBE_TO_PANORAMA,
+ COPY_MODE_CUBE_ARRAY_TO_PANORAMA,
COPY_MODE_MAX,
};
@@ -82,7 +83,6 @@ class RasterizerEffectsRD {
};
struct CopyPushConstant {
-
int32_t section[4];
int32_t target[2];
uint32_t flags;
@@ -119,7 +119,6 @@ class RasterizerEffectsRD {
};
struct CopyToFbPushConstant {
-
float section[4];
float pixel_size[2];
uint32_t flip_y;
@@ -148,7 +147,6 @@ class RasterizerEffectsRD {
};
struct CubemapRoughness {
-
CubemapRoughnessPushConstant push_constant;
CubemapRoughnessShaderRD shader;
RID shader_version;
@@ -212,7 +210,6 @@ class RasterizerEffectsRD {
};
struct LuminanceReduce {
-
LuminanceReducePushConstant push_constant;
LuminanceReduceShaderRD shader;
RID shader_version;
@@ -229,7 +226,6 @@ class RasterizerEffectsRD {
};
struct CoptToDP {
-
CubeToDpShaderRD shader;
RID shader_version;
RID pipeline;
@@ -270,7 +266,6 @@ class RasterizerEffectsRD {
};
struct Bokeh {
-
BokehPushConstant push_constant;
BokehDofShaderRD shader;
RID shader_version;
@@ -331,7 +326,6 @@ class RasterizerEffectsRD {
};
struct SSAO {
-
SSAOMinifyPushConstant minify_push_constant;
SsaoMinifyShaderRD minify_shader;
RID minify_shader_version;
@@ -354,7 +348,6 @@ class RasterizerEffectsRD {
};
struct RoughnessLimiter {
-
RoughnessLimiterPushConstant push_constant;
RoughnessLimiterShaderRD shader;
RID shader_version;
@@ -368,7 +361,6 @@ class RasterizerEffectsRD {
};
struct CubemapDownsampler {
-
CubemapDownsamplerPushConstant push_constant;
CubemapDownsamplerShaderRD shader;
RID shader_version;
@@ -385,7 +377,6 @@ class RasterizerEffectsRD {
};
struct CubemapFilter {
-
CubemapFilterShaderRD shader;
RID shader_version;
RID pipelines[FILTER_MODE_MAX];
@@ -418,7 +409,6 @@ class RasterizerEffectsRD {
*/
struct SpecularMerge {
-
SpecularMergeShaderRD shader;
RID shader_version;
RenderPipelineVertexFormatCacheRD pipelines[SPECULAR_MERGE_MAX];
@@ -432,7 +422,6 @@ class RasterizerEffectsRD {
};
struct ScreenSpaceReflectionPushConstant {
-
float proj_info[4];
int32_t screen_size[2];
@@ -453,7 +442,6 @@ class RasterizerEffectsRD {
};
struct ScreenSpaceReflection {
-
ScreenSpaceReflectionPushConstant push_constant;
ScreenSpaceReflectionShaderRD shader;
RID shader_version;
@@ -462,7 +450,6 @@ class RasterizerEffectsRD {
} ssr;
struct ScreenSpaceReflectionFilterPushConstant {
-
float proj_info[4];
uint32_t orthogonal;
@@ -481,7 +468,6 @@ class RasterizerEffectsRD {
};
struct ScreenSpaceReflectionFilter {
-
ScreenSpaceReflectionFilterPushConstant push_constant;
ScreenSpaceReflectionFilterShaderRD shader;
RID shader_version;
@@ -489,7 +475,6 @@ class RasterizerEffectsRD {
} ssr_filter;
struct ScreenSpaceReflectionScalePushConstant {
-
int32_t screen_size[2];
float camera_z_near;
float camera_z_far;
@@ -500,7 +485,6 @@ class RasterizerEffectsRD {
};
struct ScreenSpaceReflectionScale {
-
ScreenSpaceReflectionScalePushConstant push_constant;
ScreenSpaceReflectionScaleShaderRD shader;
RID shader_version;
@@ -508,7 +492,6 @@ class RasterizerEffectsRD {
} ssr_scale;
struct SubSurfaceScatteringPushConstant {
-
int32_t screen_size[2];
float camera_z_far;
float camera_z_near;
@@ -523,7 +506,6 @@ class RasterizerEffectsRD {
};
struct SubSurfaceScattering {
-
SubSurfaceScatteringPushConstant push_constant;
SubsurfaceScatteringShaderRD shader;
RID shader_version;
@@ -564,6 +546,7 @@ class RasterizerEffectsRD {
public:
void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false);
void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false);
+ void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array);
void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false);
void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far);
void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false);
@@ -577,7 +560,6 @@ public:
void bokeh_dof(RID p_base_texture, RID p_depth_texture, const Size2i &p_base_texture_size, RID p_secondary_texture, RID p_bokeh_texture1, RID p_bokeh_texture2, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal);
struct TonemapSettings {
-
bool use_glow = false;
enum GlowMode {
GLOW_MODE_ADD,
diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_rd.cpp
index 9c54f0caae..18cf4fa340 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_rd.cpp
@@ -30,12 +30,13 @@
#include "rasterizer_rd.h"
+#include "core/project_settings.h"
+
void RasterizerRD::prepare_for_blitting_render_targets() {
RD::get_singleton()->prepare_screen_for_drawing();
}
void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_screen, const BlitToScreen *p_render_targets, int p_amount) {
-
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin_for_screen(p_screen);
for (int i = 0; i < p_amount; i++) {
@@ -77,13 +78,17 @@ void RasterizerRD::blit_render_targets_to_screen(DisplayServer::WindowID p_scree
void RasterizerRD::begin_frame(double frame_step) {
frame++;
+ delta = frame_step;
time += frame_step;
+
+ double time_roll_over = GLOBAL_GET("rendering/limits/time/time_rollover_secs");
+ time = Math::fmod(time, time_roll_over);
+
canvas->set_time(time);
scene->set_time(time, frame_step);
}
void RasterizerRD::end_frame(bool p_swap_buffers) {
-
#ifndef _MSC_VER
#warning TODO: likely passa bool to swap buffers to avoid display?
#endif
@@ -91,7 +96,6 @@ void RasterizerRD::end_frame(bool p_swap_buffers) {
}
void RasterizerRD::initialize() {
-
{ //create framebuffer copy shader
RenderingDevice::ShaderStageData vert;
vert.shader_stage = RenderingDevice::SHADER_STAGE_VERTEX;
@@ -151,10 +155,9 @@ void RasterizerRD::initialize() {
}
ThreadWorkPool RasterizerRD::thread_work_pool;
-uint32_t RasterizerRD::frame = 1;
+uint64_t RasterizerRD::frame = 1;
void RasterizerRD::finalize() {
-
thread_work_pool.finish();
memdelete(scene);
@@ -167,7 +170,10 @@ void RasterizerRD::finalize() {
RD::get_singleton()->free(copy_viewports_sampler);
}
+RasterizerRD *RasterizerRD::singleton = nullptr;
+
RasterizerRD::RasterizerRD() {
+ singleton = this;
thread_work_pool.init();
time = 0;
diff --git a/servers/rendering/rasterizer_rd/rasterizer_rd.h b/servers/rendering/rasterizer_rd/rasterizer_rd.h
index 756b9499ca..cb53a531ac 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_rd.h
@@ -53,8 +53,9 @@ protected:
Map<RID, RID> render_target_descriptors;
double time;
+ float delta;
- static uint32_t frame;
+ static uint64_t frame;
public:
RasterizerStorage *get_storage() { return storage; }
@@ -71,7 +72,8 @@ public:
void end_frame(bool p_swap_buffers);
void finalize();
- static _ALWAYS_INLINE_ uint64_t get_frame_number() { return frame; }
+ _ALWAYS_INLINE_ uint64_t get_frame_number() const { return frame; }
+ _ALWAYS_INLINE_ float get_frame_delta_time() const { return delta; }
static Error is_viable() {
return OK;
@@ -89,6 +91,7 @@ public:
static ThreadWorkPool thread_work_pool;
+ static RasterizerRD *singleton;
RasterizerRD();
~RasterizerRD() {}
};
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
index b3cf40f166..7d351f249a 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.cpp
@@ -67,33 +67,30 @@ static _FORCE_INLINE_ void store_basis_3x4(const Basis &p_mtx, float *p_array) {
p_array[11] = 0;
}
-static _FORCE_INLINE_ void store_transform_3x3(const Transform &p_mtx, float *p_array) {
- p_array[0] = p_mtx.basis.elements[0][0];
- p_array[1] = p_mtx.basis.elements[1][0];
- p_array[2] = p_mtx.basis.elements[2][0];
+static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.elements[0][0];
+ p_array[1] = p_mtx.elements[1][0];
+ p_array[2] = p_mtx.elements[2][0];
p_array[3] = 0;
- p_array[4] = p_mtx.basis.elements[0][1];
- p_array[5] = p_mtx.basis.elements[1][1];
- p_array[6] = p_mtx.basis.elements[2][1];
+ p_array[4] = p_mtx.elements[0][1];
+ p_array[5] = p_mtx.elements[1][1];
+ p_array[6] = p_mtx.elements[2][1];
p_array[7] = 0;
- p_array[8] = p_mtx.basis.elements[0][2];
- p_array[9] = p_mtx.basis.elements[1][2];
- p_array[10] = p_mtx.basis.elements[2][2];
+ p_array[8] = p_mtx.elements[0][2];
+ p_array[9] = p_mtx.elements[1][2];
+ p_array[10] = p_mtx.elements[2][2];
p_array[11] = 0;
}
static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
-
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
-
p_array[i * 4 + j] = p_mtx.matrix[i][j];
}
}
}
static _FORCE_INLINE_ void store_soft_shadow_kernel(const float *p_kernel, float *p_array) {
-
for (int i = 0; i < 128; i++) {
p_array[i] = p_kernel[i];
}
@@ -224,7 +221,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
switch (blend_mode) {
case BLEND_MODE_MIX: {
-
blend_attachment.enable_blend = true;
blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
@@ -235,7 +231,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
} break;
case BLEND_MODE_ADD: {
-
blend_attachment.enable_blend = true;
blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
@@ -247,7 +242,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
} break;
case BLEND_MODE_SUB: {
-
blend_attachment.enable_blend = true;
blend_attachment.alpha_blend_op = RD::BLEND_OP_SUBTRACT;
blend_attachment.color_blend_op = RD::BLEND_OP_SUBTRACT;
@@ -288,7 +282,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
}
for (int i = 0; i < CULL_VARIANT_MAX; i++) {
-
RD::PolygonCullMode cull_mode_rd_table[CULL_VARIANT_MAX][3] = {
{ RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_FRONT, RD::POLYGON_CULL_BACK },
{ RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_BACK, RD::POLYGON_CULL_FRONT },
@@ -298,7 +291,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
RD::PolygonCullMode cull_mode_rd = cull_mode_rd_table[i][cull];
for (int j = 0; j < RS::PRIMITIVE_MAX; j++) {
-
RD::RenderPrimitive primitive_rd_table[RS::PRIMITIVE_MAX] = {
RD::RENDER_PRIMITIVE_POINTS,
RD::RENDER_PRIMITIVE_LINES,
@@ -310,7 +302,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
RD::RenderPrimitive primitive_rd = uses_point_size ? RD::RENDER_PRIMITIVE_POINTS : primitive_rd_table[j];
for (int k = 0; k < SHADER_VERSION_MAX; k++) {
-
RD::PipelineRasterizationState raster_state;
raster_state.cull_mode = cull_mode_rd;
raster_state.wireframe = wireframe;
@@ -337,7 +328,6 @@ void RasterizerSceneHighEndRD::ShaderData::set_code(const String &p_code) {
continue; // do not use this version (will error if using it is attempted)
}
} else {
-
if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_VCT_COLOR_PASS || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
blend_state = blend_state_opaque;
} else if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
@@ -373,11 +363,9 @@ void RasterizerSceneHighEndRD::ShaderData::set_default_texture_param(const Strin
}
void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
-
Map<int, StringName> order;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
-
if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) {
continue;
}
@@ -390,7 +378,6 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_
}
for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
-
PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]);
pi.name = E->get();
p_param_list->push_back(pi);
@@ -398,9 +385,7 @@ void RasterizerSceneHighEndRD::ShaderData::get_param_list(List<PropertyInfo> *p_
}
void RasterizerSceneHighEndRD::ShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const {
-
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
-
if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
@@ -429,6 +414,7 @@ bool RasterizerSceneHighEndRD::ShaderData::is_animated() const {
bool RasterizerSceneHighEndRD::ShaderData::casts_shadows() const {
return false;
}
+
Variant RasterizerSceneHighEndRD::ShaderData::get_default_parameter(const StringName &p_parameter) const {
if (uniforms.has(p_parameter)) {
ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
@@ -466,7 +452,6 @@ void RasterizerSceneHighEndRD::MaterialData::set_next_pass(RID p_pass) {
}
void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
-
RasterizerSceneHighEndRD *scene_singleton = (RasterizerSceneHighEndRD *)RasterizerSceneHighEndRD::singleton;
if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
@@ -491,7 +476,6 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN
//check whether buffer changed
if (p_uniform_dirty && ubo_data.size()) {
-
update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
}
@@ -510,7 +494,6 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN
}
if (p_textures_dirty && tex_uniform_count) {
-
update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
}
@@ -527,7 +510,6 @@ void RasterizerSceneHighEndRD::MaterialData::update_parameters(const Map<StringN
Vector<RD::Uniform> uniforms;
{
-
if (shader_data->ubo_size) {
RD::Uniform u;
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
@@ -572,7 +554,6 @@ RasterizerSceneHighEndRD::RenderBufferDataHighEnd::~RenderBufferDataHighEnd() {
}
void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() {
-
if (!specular.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
@@ -588,7 +569,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() {
specular = RD::get_singleton()->texture_create(tf, RD::TextureView());
if (msaa == RS::VIEWPORT_MSAA_DISABLED) {
-
{
Vector<RID> fb;
fb.push_back(color);
@@ -605,7 +585,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() {
}
} else {
-
tf.samples = texture_samples;
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
specular_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
@@ -629,7 +608,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::ensure_specular() {
}
void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::clear() {
-
if (color_msaa.is_valid()) {
RD::get_singleton()->free(color_msaa);
color_msaa = RID();
@@ -689,7 +667,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_bu
depth = p_depth_buffer;
if (p_msaa == RS::VIEWPORT_MSAA_DISABLED) {
-
{
Vector<RID> fb;
fb.push_back(p_color_buffer);
@@ -704,7 +681,6 @@ void RasterizerSceneHighEndRD::RenderBufferDataHighEnd::configure(RID p_color_bu
depth_fb = RD::get_singleton()->framebuffer_create(fb);
}
} else {
-
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.width = p_width;
@@ -785,7 +761,6 @@ void RasterizerSceneHighEndRD::_allocate_normal_texture(RenderBufferDataHighEnd
}
void RasterizerSceneHighEndRD::_allocate_roughness_texture(RenderBufferDataHighEnd *rb) {
-
if (rb->roughness_buffer.is_valid()) {
return;
}
@@ -807,7 +782,6 @@ void RasterizerSceneHighEndRD::_allocate_roughness_texture(RenderBufferDataHighE
rb->roughness_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) {
-
Vector<RID> fb;
fb.push_back(rb->depth);
fb.push_back(rb->normal_buffer);
@@ -840,9 +814,9 @@ bool RasterizerSceneHighEndRD::free(RID p_rid) {
}
void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth) {
+ uint32_t lightmap_captures_used = 0;
for (int i = 0; i < p_element_count; i++) {
-
const RenderList::Element *e = p_elements[i];
InstanceData &id = scene_state.instances[i];
store_transform(e->instance->transform, id.transform);
@@ -898,6 +872,7 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements,
if (written == 0) {
id.gi_offset = index;
+ id.flags |= INSTANCE_DATA_FLAG_USE_GIPROBE;
written = 1;
} else {
id.gi_offset = index << 16;
@@ -910,18 +885,51 @@ void RasterizerSceneHighEndRD::_fill_instances(RenderList::Element **p_elements,
} else if (written == 1) {
id.gi_offset |= 0xFFFF0000;
}
+ } else if (e->instance->lightmap) {
+ int32_t lightmap_index = storage->lightmap_get_array_index(e->instance->lightmap->base);
+ if (lightmap_index >= 0) {
+ id.gi_offset = lightmap_index;
+ id.gi_offset |= e->instance->lightmap_slice_index << 12;
+ id.gi_offset |= e->instance->lightmap_cull_index << 20;
+ id.lightmap_uv_scale[0] = e->instance->lightmap_uv_scale.position.x;
+ id.lightmap_uv_scale[1] = e->instance->lightmap_uv_scale.position.y;
+ id.lightmap_uv_scale[2] = e->instance->lightmap_uv_scale.size.width;
+ id.lightmap_uv_scale[3] = e->instance->lightmap_uv_scale.size.height;
+ id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP;
+ if (storage->lightmap_uses_spherical_harmonics(e->instance->lightmap->base)) {
+ id.flags |= INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP;
+ }
+ } else {
+ id.gi_offset = 0xFFFFFFFF;
+ }
+ } else if (!e->instance->lightmap_sh.empty()) {
+ if (lightmap_captures_used < scene_state.max_lightmap_captures) {
+ const Color *src_capture = e->instance->lightmap_sh.ptr();
+ LightmapCaptureData &lcd = scene_state.lightmap_captures[lightmap_captures_used];
+ for (int j = 0; j < 9; j++) {
+ lcd.sh[j * 4 + 0] = src_capture[j].r;
+ lcd.sh[j * 4 + 1] = src_capture[j].g;
+ lcd.sh[j * 4 + 2] = src_capture[j].b;
+ lcd.sh[j * 4 + 3] = src_capture[j].a;
+ }
+ id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE;
+ id.gi_offset = lightmap_captures_used;
+ lightmap_captures_used++;
+ }
} else {
id.gi_offset = 0xFFFFFFFF;
}
}
RD::get_singleton()->buffer_update(scene_state.instance_buffer, 0, sizeof(InstanceData) * p_element_count, scene_state.instances, true);
+ if (lightmap_captures_used) {
+ RD::get_singleton()->buffer_update(scene_state.lightmap_capture_buffer, 0, sizeof(LightmapCaptureData) * lightmap_captures_used, scene_state.lightmap_captures, true);
+ }
}
/// RENDERING ///
-void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set) {
-
+void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set, bool p_force_wireframe, const Vector2 &p_uv_offset) {
RD::DrawListID draw_list = p_draw_list;
RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format;
@@ -949,9 +957,10 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
PushConstant push_constant;
zeromem(&push_constant, sizeof(PushConstant));
+ push_constant.bake_uv2_offset[0] = p_uv_offset.x;
+ push_constant.bake_uv2_offset[1] = p_uv_offset.y;
for (int i = 0; i < p_element_count; i++) {
-
const RenderList::Element *e = p_elements[i];
MaterialData *material = e->material;
@@ -961,7 +970,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
//find cull variant
ShaderData::CullVariant cull_variant;
- if ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) {
+ if (p_pass_mode == PASS_MODE_DEPTH_MATERIAL || ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)) {
cull_variant = ShaderData::CULL_VARIANT_DOUBLE_SIDED;
} else {
bool mirror = e->instance->mirror;
@@ -1080,7 +1089,7 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
prev_index_array_rd = index_array_rd;
}
- RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format);
+ RID pipeline_rd = pipeline->get_render_pipeline(vertex_format, framebuffer_format, p_force_wireframe);
if (pipeline_rd != prev_pipeline_rd) {
// checking with prev shader does not make so much sense, as
@@ -1115,10 +1124,8 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
RD::get_singleton()->draw_list_draw(draw_list, index_array_rd.is_valid(), instances);
} break;
case RS::INSTANCE_IMMEDIATE: {
-
} break;
case RS::INSTANCE_PARTICLES: {
-
} break;
default: {
ERR_CONTINUE(true); //should be a bug
@@ -1128,7 +1135,6 @@ void RasterizerSceneHighEndRD::_render_list(RenderingDevice::DrawListID p_draw_l
}
void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows) {
-
//CameraMatrix projection = p_cam_projection;
//projection.flip_y(); // Vulkan and modern APIs use Y-Down
CameraMatrix correction;
@@ -1173,7 +1179,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer
scene_state.ubo.time = time;
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
-
scene_state.ubo.use_ambient_light = true;
scene_state.ubo.ambient_light_color_energy[0] = 1;
scene_state.ubo.ambient_light_color_energy[1] = 1;
@@ -1184,7 +1189,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer
scene_state.ubo.ssao_enabled = false;
} else if (is_environment(p_environment)) {
-
RS::EnvironmentBG env_bg = environment_get_background(p_environment);
RS::EnvironmentAmbientSource ambient_src = environment_get_ambient_source(p_environment);
@@ -1195,7 +1199,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer
//ambient
if (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && (env_bg == RS::ENV_BG_CLEAR_COLOR || env_bg == RS::ENV_BG_COLOR)) {
-
Color color = env_bg == RS::ENV_BG_CLEAR_COLOR ? p_default_bg_color : environment_get_bg_color(p_environment);
color = color.to_linear();
@@ -1205,7 +1208,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer
scene_state.ubo.use_ambient_light = true;
scene_state.ubo.use_ambient_cubemap = false;
} else {
-
float energy = environment_get_ambient_light_energy(p_environment);
Color color = environment_get_ambient_light_color(p_environment);
color = color.to_linear();
@@ -1240,7 +1242,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer
scene_state.ubo.ao_color[3] = ao_color.a;
} else {
-
if (p_reflection_probe.is_valid() && storage->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_reflection_probe))) {
scene_state.ubo.use_ambient_light = false;
} else {
@@ -1255,6 +1256,7 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer
scene_state.ubo.use_ambient_cubemap = false;
scene_state.ubo.use_reflection_cubemap = false;
+ scene_state.ubo.ssao_enabled = false;
}
scene_state.ubo.roughness_limiter_enabled = p_opaque_render_buffers && screen_space_roughness_limiter_is_active();
@@ -1263,7 +1265,6 @@ void RasterizerSceneHighEndRD::_setup_environment(RID p_environment, const Camer
}
void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index) {
-
RID m_src;
m_src = p_instance->material_override.is_valid() ? p_instance->material_override : p_material;
@@ -1271,8 +1272,6 @@ void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t
if (unlikely(get_debug_draw_mode() != RS::VIEWPORT_DEBUG_DRAW_DISABLED)) {
if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
m_src = overdraw_material;
- } else if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME) {
- m_src = wireframe_material;
} else if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING) {
m_src = default_material;
}
@@ -1297,16 +1296,15 @@ void RasterizerSceneHighEndRD::_add_geometry(InstanceBase *p_instance, uint32_t
_add_geometry_with_material(p_instance, p_surface, material, m_src, p_pass_mode, p_geometry_index);
while (material->next_pass.is_valid()) {
-
material = (MaterialData *)storage->material_get_data(material->next_pass, RasterizerStorageRD::SHADER_TYPE_3D);
- if (!material || !material->shader_data->valid)
+ if (!material || !material->shader_data->valid) {
break;
+ }
_add_geometry_with_material(p_instance, p_surface, material, material->next_pass, p_pass_mode, p_geometry_index);
}
}
void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index) {
-
bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture;
bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha);
bool has_blend_alpha = p_material->shader_data->uses_blend_alpha;
@@ -1329,7 +1327,6 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta
}
if (p_pass_mode != PASS_MODE_COLOR && p_pass_mode != PASS_MODE_COLOR_SPECULAR) {
-
if (has_blend_alpha || has_read_screen_alpha || (has_base_alpha && !p_material->shader_data->uses_depth_pre_pass) || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED || p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
//conditions in which no depth pass should be processed
return;
@@ -1351,8 +1348,9 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta
RenderList::Element *e = (has_alpha || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED) ? render_list.add_alpha_element() : render_list.add_element();
- if (!e)
+ if (!e) {
return;
+ }
e->instance = p_instance;
e->material = p_material;
@@ -1374,7 +1372,7 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta
e->geometry_index = p_geometry_index;
e->material_index = e->material->index;
e->uses_instancing = e->instance->base_type == RS::INSTANCE_MULTIMESH;
- e->uses_lightmap = e->instance->lightmap.is_valid();
+ e->uses_lightmap = e->instance->lightmap != nullptr || !e->instance->lightmap_sh.empty();
e->uses_vct = e->instance->gi_probe_instances.size();
e->shader_index = e->shader_index;
e->depth_layer = e->instance->depth_layer;
@@ -1386,7 +1384,6 @@ void RasterizerSceneHighEndRD::_add_geometry_with_material(InstanceBase *p_insta
}
void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_no_gi) {
-
scene_state.current_shader_index = 0;
scene_state.current_material_index = 0;
scene_state.used_sss = false;
@@ -1399,14 +1396,11 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i
//fill list
for (int i = 0; i < p_cull_count; i++) {
-
InstanceBase *inst = p_cull_result[i];
//add geometry for drawing
switch (inst->base_type) {
-
case RS::INSTANCE_MESH: {
-
const RID *materials = nullptr;
uint32_t surface_count;
@@ -1418,7 +1412,6 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i
const RID *inst_materials = inst->materials.ptr();
for (uint32_t j = 0; j < surface_count; j++) {
-
RID material = inst_materials[j].is_valid() ? inst_materials[j] : materials[j];
uint32_t surface_index = storage->mesh_surface_get_render_pass_index(inst->base, j, render_pass, &geometry_index);
@@ -1430,7 +1423,6 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i
} break;
case RS::INSTANCE_MULTIMESH: {
-
if (storage->multimesh_get_instances_to_draw(inst->base) == 0) {
//not visible, 0 instances
continue;
@@ -1450,7 +1442,6 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i
}
for (uint32_t j = 0; j < surface_count; j++) {
-
uint32_t surface_index = storage->mesh_surface_get_multimesh_render_pass_index(mesh, j, render_pass, &geometry_index);
_add_geometry(inst, j, materials[j], p_pass_mode, surface_index);
}
@@ -1497,9 +1488,7 @@ void RasterizerSceneHighEndRD::_fill_render_list(InstanceBase **p_cull_result, i
}
void RasterizerSceneHighEndRD::_setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment) {
-
for (int i = 0; i < p_reflection_probe_cull_count; i++) {
-
RID rpi = p_reflection_probe_cull_result[i];
if (i >= (int)scene_state.max_reflections) {
@@ -1575,12 +1564,29 @@ void RasterizerSceneHighEndRD::_setup_reflections(RID *p_reflection_probe_cull_r
}
}
-void RasterizerSceneHighEndRD::_setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform) {
+void RasterizerSceneHighEndRD::_setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform) {
+ uint32_t lightmaps_used = 0;
+ for (int i = 0; i < p_lightmap_cull_count; i++) {
+ if (i >= (int)scene_state.max_lightmaps) {
+ break;
+ }
+ InstanceBase *lm = p_lightmap_cull_result[i];
+ Basis to_lm = lm->transform.basis.inverse() * p_cam_transform.basis;
+ to_lm = to_lm.inverse().transposed(); //will transform normals
+ store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
+ lm->lightmap_cull_index = i;
+ lightmaps_used++;
+ }
+ if (lightmaps_used > 0) {
+ RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * lightmaps_used, scene_state.lightmaps, true);
+ }
+}
+
+void RasterizerSceneHighEndRD::_setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform) {
int index = 0;
for (int i = 0; i < p_gi_probe_probe_cull_count; i++) {
-
RID rpi = p_gi_probe_probe_cull_result[i];
if (index >= (int)scene_state.max_gi_probes) {
@@ -1631,13 +1637,11 @@ void RasterizerSceneHighEndRD::_setup_gi_probes(RID *p_gi_probe_probe_cull_resul
}
void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_light_cull_count, const Transform &p_camera_inverse_transform, RID p_shadow_atlas, bool p_using_shadows) {
-
uint32_t light_count = 0;
scene_state.ubo.directional_light_count = 0;
sky_scene_state.directional_light_count = 0;
for (int i = 0; i < p_light_cull_count; i++) {
-
RID li = p_light_cull_result[i];
RID base = light_instance_get_base_light(li);
@@ -1645,9 +1649,7 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
RS::LightType type = storage->light_get_type(base);
switch (type) {
-
case RS::LIGHT_DIRECTIONAL: {
-
if (scene_state.ubo.directional_light_count >= scene_state.max_directional_lights) {
continue;
}
@@ -1699,7 +1701,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
light_data.shadow_color4[3] = 1.0;
} else {
-
light_data.shadow_color1[0] = shadow_col.r;
light_data.shadow_color1[1] = shadow_col.g;
light_data.shadow_color1[2] = shadow_col.b;
@@ -1720,8 +1721,17 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
light_data.shadow_enabled = p_using_shadows && storage->light_has_shadow(base);
- if (light_data.shadow_enabled) {
+ float angular_diameter = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
+ if (angular_diameter > 0.0) {
+ // I know tan(0) is 0, but let's not risk it with numerical precision.
+ // technically this will keep expanding until reaching the sun, but all we care
+ // is expand until we reach the radius of the near plane (there can't be more occluders than that)
+ angular_diameter = Math::tan(Math::deg2rad(angular_diameter));
+ } else {
+ angular_diameter = 0.0;
+ }
+ if (light_data.shadow_enabled) {
RS::LightDirectionalShadowMode smode = storage->light_directional_get_shadow_mode(base);
int limit = smode == RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL ? 0 : (smode == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS ? 1 : 3);
@@ -1775,22 +1785,15 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
light_data.fade_to = -light_data.shadow_split_offsets[3];
light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR);
+ light_data.softshadow_angle = angular_diameter;
- float softshadow_angle = storage->light_get_param(base, RS::LIGHT_PARAM_SIZE);
- if (softshadow_angle > 0.0) {
- // I know tan(0) is 0, but let's not risk it with numerical precision.
- // technically this will keep expanding until reaching the sun, but all we care
- // is expand until we reach the radius of the near plane (there can't be more occluders than that)
- light_data.softshadow_angle = Math::tan(Math::deg2rad(softshadow_angle));
- } else {
- light_data.softshadow_angle = 0;
+ if (angular_diameter <= 0.0) {
light_data.soft_shadow_scale *= directional_shadow_quality_radius_get(); // Only use quality radius for PCF
}
}
// Copy to SkyDirectionalLightData
if (sky_scene_state.directional_light_count < sky_scene_state.max_directional_lights) {
-
SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.directional_light_count];
Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
@@ -1806,7 +1809,7 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
sky_light_data.color[2] = light_data.color[2];
sky_light_data.enabled = true;
- sky_light_data.size = light_data.softshadow_angle;
+ sky_light_data.size = angular_diameter;
sky_scene_state.directional_light_count++;
}
@@ -1814,7 +1817,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
} break;
case RS::LIGHT_SPOT:
case RS::LIGHT_OMNI: {
-
if (light_count >= scene_state.max_lights) {
continue;
}
@@ -1870,7 +1872,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
Rect2 rect = storage->decal_atlas_get_texture_rect(projector);
if (type == RS::LIGHT_SPOT) {
-
light_data.projector_rect[0] = rect.position.x;
light_data.projector_rect[1] = rect.position.y + rect.size.height; //flip because shadow is flipped
light_data.projector_rect[2] = rect.size.width;
@@ -1923,14 +1924,12 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
light_data.soft_shadow_scale = storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BLUR);
if (type == RS::LIGHT_OMNI) {
-
light_data.atlas_rect[3] *= 0.5; //one paraboloid on top of another
Transform proj = (p_camera_inverse_transform * light_transform).inverse();
store_transform(proj, light_data.shadow_matrix);
if (size > 0.0) {
-
light_data.soft_shadow_size = size;
} else {
light_data.soft_shadow_size = 0.0;
@@ -1938,7 +1937,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
}
} else if (type == RS::LIGHT_SPOT) {
-
Transform modelview = (p_camera_inverse_transform * light_transform).inverse();
CameraMatrix bias;
bias.set_light_bias();
@@ -1982,7 +1980,6 @@ void RasterizerSceneHighEndRD::_setup_lights(RID *p_light_cull_result, int p_lig
}
void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform) {
-
Transform uv_xform;
uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
uv_xform.origin = Vector3(-1.0, 0.0, -1.0);
@@ -1990,7 +1987,6 @@ void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p
p_decal_count = MIN((uint32_t)p_decal_count, scene_state.max_decals);
int idx = 0;
for (int i = 0; i < p_decal_count; i++) {
-
RID di = p_decal_instances[i];
RID decal = decal_instance_get_base(di);
@@ -2038,7 +2034,6 @@ void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p
dd.albedo_rect[2] = rect.size.x;
dd.albedo_rect[3] = rect.size.y;
} else {
-
if (!emission_tex.is_valid()) {
continue; //no albedo, no emission, no decal.
}
@@ -2114,8 +2109,7 @@ void RasterizerSceneHighEndRD::_setup_decals(const RID *p_decal_instances, int p
}
}
-void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) {
-
+void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color) {
RenderBufferDataHighEnd *render_buffer = nullptr;
if (p_render_buffer.is_valid()) {
render_buffer = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffer);
@@ -2164,7 +2158,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
bool using_ssr = false;
if (render_buffer) {
-
screen_pixel_size.width = 1.0 / render_buffer->width;
screen_pixel_size.height = 1.0 / render_buffer->height;
screen_size.x = render_buffer->width;
@@ -2234,6 +2227,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
_setup_decals(p_decal_cull_result, p_decal_cull_count, p_cam_transform.affine_inverse());
_setup_reflections(p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_cam_transform.affine_inverse(), p_environment);
_setup_gi_probes(p_gi_probe_cull_result, p_gi_probe_cull_count, p_cam_transform);
+ _setup_lightmaps(p_lightmap_cull_result, p_lightmap_cull_count, p_cam_transform);
_setup_environment(p_environment, p_cam_projection, p_cam_transform, p_reflection_probe, p_reflection_probe.is_valid(), screen_pixel_size, p_shadow_atlas, !p_reflection_probe.is_valid(), p_default_bg_color, p_cam_projection.get_z_near(), p_cam_projection.get_z_far(), false);
cluster_builder.bake_cluster(); //bake to cluster
@@ -2285,7 +2279,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
keep_color = true;
} break;
case RS::ENV_BG_CAMERA_FEED: {
-
} break;
default: {
}
@@ -2294,7 +2287,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
if (draw_sky || environment_get_reflection_source(p_environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
RID sky = environment_get_sky(p_environment);
if (sky.is_valid()) {
-
RENDER_TIMESTAMP("Setup Sky");
CameraMatrix projection = p_cam_projection;
if (p_reflection_probe.is_valid()) {
@@ -2312,7 +2304,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
}
}
} else {
-
clear_color = p_default_bg_color;
}
@@ -2334,7 +2325,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
bool finish_depth = using_ssao;
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, radiance_uniform_set, RID());
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(depth_framebuffer), render_list.elements, render_list.element_count, false, depth_pass_mode, render_buffer == nullptr, radiance_uniform_set, RID(), get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
RD::get_singleton()->draw_list_end();
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
@@ -2373,7 +2364,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss;
{
-
bool will_continue_color = (can_continue_color || draw_sky || debug_giprobes);
bool will_continue_depth = (can_continue_depth || draw_sky || debug_giprobes);
@@ -2390,7 +2380,7 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer;
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (using_ssao ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CONTINUE) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(framebuffer), render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set);
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(framebuffer), render_list.elements, render_list.element_count, false, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
RD::get_singleton()->draw_list_end();
if (will_continue_color && using_separate_specular) {
@@ -2429,7 +2419,6 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
}
if (render_buffer && !can_continue_color && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
-
RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true);
if (using_separate_specular) {
RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular, true);
@@ -2437,12 +2426,10 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
}
if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
-
RD::get_singleton()->texture_resolve_multisample(render_buffer->depth_msaa, render_buffer->depth, true);
}
if (using_separate_specular) {
-
if (using_sss) {
RENDER_TIMESTAMP("Sub Surface Scattering");
_process_sss(p_render_buffer, p_cam_projection);
@@ -2468,18 +2455,16 @@ void RasterizerSceneHighEndRD::_render_scene(RID p_render_buffer, const Transfor
{
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
- _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(alpha_framebuffer), &render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set);
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(alpha_framebuffer), &render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, false, PASS_MODE_COLOR, render_buffer == nullptr, radiance_uniform_set, render_buffers_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME);
RD::get_singleton()->draw_list_end();
}
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
-
RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color, true);
}
}
void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake) {
-
RENDER_TIMESTAMP("Setup Rendering Shadow");
_update_render_base_uniform_set();
@@ -2513,13 +2498,14 @@ void RasterizerSceneHighEndRD::_render_shadow(RID p_framebuffer, InstanceBase **
}
void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {
- RENDER_TIMESTAMP("Setup Rendering Shadow");
+ RENDER_TIMESTAMP("Setup Rendering Material");
_update_render_base_uniform_set();
render_pass++;
scene_state.ubo.dual_paraboloid_side = 0;
+ scene_state.ubo.material_uv2_mode = true;
_setup_environment(RID(), p_cam_projection, p_cam_transform, RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0);
@@ -2550,8 +2536,68 @@ void RasterizerSceneHighEndRD::_render_material(const Transform &p_cam_transform
}
}
-void RasterizerSceneHighEndRD::_base_uniforms_changed() {
+void RasterizerSceneHighEndRD::_render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {
+ RENDER_TIMESTAMP("Setup Rendering UV2");
+
+ _update_render_base_uniform_set();
+
+ render_pass++;
+
+ scene_state.ubo.dual_paraboloid_side = 0;
+ scene_state.ubo.material_uv2_mode = true;
+
+ _setup_environment(RID(), CameraMatrix(), Transform(), RID(), true, Vector2(1, 1), RID(), false, Color(), 0, 0);
+
+ render_list.clear();
+
+ PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
+ _fill_render_list(p_cull_result, p_cull_count, pass_mode, true);
+
+ _setup_view_dependant_uniform_set(RID(), RID());
+
+ RENDER_TIMESTAMP("Render Material");
+
+ render_list.sort_by_key(false);
+
+ _fill_instances(render_list.elements, render_list.element_count, true);
+
+ {
+ //regular forward for now
+ Vector<Color> clear;
+ clear.push_back(Color(0, 0, 0, 0));
+ clear.push_back(Color(0, 0, 0, 0));
+ clear.push_back(Color(0, 0, 0, 0));
+ clear.push_back(Color(0, 0, 0, 0));
+ clear.push_back(Color(0, 0, 0, 0));
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, clear, 1.0, 0, p_region);
+
+ const int uv_offset_count = 9;
+ static const Vector2 uv_offsets[uv_offset_count] = {
+ Vector2(-1, 1),
+ Vector2(1, 1),
+ Vector2(1, -1),
+ Vector2(-1, -1),
+ Vector2(-1, 0),
+ Vector2(1, 0),
+ Vector2(0, -1),
+ Vector2(0, 1),
+ Vector2(0, 0),
+
+ };
+
+ for (int i = 0; i < uv_offset_count; i++) {
+ Vector2 ofs = uv_offsets[i];
+ ofs.x /= p_region.size.width;
+ ofs.y /= p_region.size.height;
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), RID(), true, ofs); //first wireframe, for pseudo conservative
+ }
+ _render_list(draw_list, RD::get_singleton()->framebuffer_get_format(p_framebuffer), render_list.elements, render_list.element_count, true, pass_mode, true, RID(), RID(), false); //second regular triangles
+ RD::get_singleton()->draw_list_end();
+ }
+}
+
+void RasterizerSceneHighEndRD::_base_uniforms_changed() {
if (!render_base_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
RD::get_singleton()->free(render_base_uniform_set);
}
@@ -2559,13 +2605,13 @@ void RasterizerSceneHighEndRD::_base_uniforms_changed() {
}
void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
-
- if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
-
+ if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != storage->lightmap_array_get_version())) {
if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
RD::get_singleton()->free(render_base_uniform_set);
}
+ lightmap_texture_array_version = storage->lightmap_array_get_version();
+
Vector<RD::Uniform> uniforms;
{
@@ -2653,7 +2699,6 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
}
for (int i = 0; i < slot_count; i++) {
-
RID probe = gi_probe_get_slots()[i];
if (gi_probe_is_anisotropic()) {
@@ -2681,6 +2726,27 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
{
RD::Uniform u;
u.binding = 10;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(scene_state.lightmap_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 11;
+ u.type = RD::UNIFORM_TYPE_TEXTURE;
+ u.ids = storage->lightmap_array_get_textures();
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 12;
+ u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(scene_state.lightmap_capture_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 13;
u.type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture();
u.ids.push_back(decal_atlas);
@@ -2688,7 +2754,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
}
{
RD::Uniform u;
- u.binding = 11;
+ u.binding = 14;
u.type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture_srgb();
u.ids.push_back(decal_atlas);
@@ -2696,7 +2762,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
}
{
RD::Uniform u;
- u.binding = 12;
+ u.binding = 15;
u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(scene_state.decal_buffer);
uniforms.push_back(u);
@@ -2704,14 +2770,14 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
{
RD::Uniform u;
- u.binding = 13;
+ u.binding = 16;
u.type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(cluster_builder.get_cluster_texture());
uniforms.push_back(u);
}
{
RD::Uniform u;
- u.binding = 14;
+ u.binding = 17;
u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(cluster_builder.get_cluster_indices_buffer());
uniforms.push_back(u);
@@ -2719,7 +2785,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
{
RD::Uniform u;
- u.binding = 15;
+ u.binding = 18;
u.type = RD::UNIFORM_TYPE_TEXTURE;
if (directional_shadow_get_texture().is_valid()) {
u.ids.push_back(directional_shadow_get_texture());
@@ -2732,7 +2798,7 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
{
RD::Uniform u;
u.type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 16;
+ u.binding = 19;
u.ids.push_back(storage->global_variables_get_storage_buffer());
uniforms.push_back(u);
}
@@ -2742,7 +2808,6 @@ void RasterizerSceneHighEndRD::_update_render_base_uniform_set() {
}
void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_atlas, RID p_reflection_atlas) {
-
if (view_dependant_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(view_dependant_uniform_set)) {
RD::get_singleton()->free(view_dependant_uniform_set);
}
@@ -2752,7 +2817,6 @@ void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_at
Vector<RD::Uniform> uniforms;
{
-
RID ref_texture = p_reflection_atlas.is_valid() ? reflection_atlas_get_texture(p_reflection_atlas) : RID();
RD::Uniform u;
u.binding = 0;
@@ -2784,7 +2848,6 @@ void RasterizerSceneHighEndRD::_setup_view_dependant_uniform_set(RID p_shadow_at
}
void RasterizerSceneHighEndRD::_render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb) {
-
if (!rb->uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(rb->uniform_set)) {
RD::get_singleton()->free(rb->uniform_set);
}
@@ -2792,7 +2855,6 @@ void RasterizerSceneHighEndRD::_render_buffers_clear_uniform_set(RenderBufferDat
}
void RasterizerSceneHighEndRD::_render_buffers_uniform_set_changed(RID p_render_buffers) {
-
RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
_render_buffers_clear_uniform_set(rb);
@@ -2811,11 +2873,9 @@ RID RasterizerSceneHighEndRD::_render_buffers_get_normal_texture(RID p_render_bu
}
void RasterizerSceneHighEndRD::_update_render_buffers_uniform_set(RID p_render_buffers) {
-
RenderBufferDataHighEnd *rb = (RenderBufferDataHighEnd *)render_buffers_get_data(p_render_buffers);
if (rb->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->uniform_set)) {
-
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
@@ -2947,7 +3007,21 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
scene_state.gi_probe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GIProbeData) * scene_state.max_gi_probes);
defines += "\n#define MAX_GI_PROBES " + itos(scene_state.max_gi_probes) + "\n";
}
+ {
+ //lightmaps
+ scene_state.max_lightmaps = storage->lightmap_array_get_size();
+ defines += "\n#define MAX_LIGHTMAP_TEXTURES " + itos(scene_state.max_lightmaps) + "\n";
+ defines += "\n#define MAX_LIGHTMAPS " + itos(scene_state.max_lightmaps) + "\n";
+ scene_state.lightmaps = memnew_arr(LightmapData, scene_state.max_lightmaps);
+ scene_state.lightmap_buffer = RD::get_singleton()->storage_buffer_create(sizeof(LightmapData) * scene_state.max_lightmaps);
+ }
+ {
+ //captures
+ scene_state.max_lightmap_captures = 2048;
+ scene_state.lightmap_captures = memnew_arr(LightmapCaptureData, scene_state.max_lightmap_captures);
+ scene_state.lightmap_capture_buffer = RD::get_singleton()->storage_buffer_create(sizeof(LightmapCaptureData) * scene_state.max_lightmap_captures);
+ }
{ //decals
scene_state.max_decals = MIN(1024 * 1024, uniform_max_size) / sizeof(DecalData); //1mb of decals
uint32_t decal_buffer_size = scene_state.max_decals * sizeof(DecalData);
@@ -2955,6 +3029,10 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
scene_state.decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size);
}
+ {
+ defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n";
+ }
+
Vector<String> shader_versions;
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n");
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n");
@@ -3125,7 +3203,6 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
render_pass = 0;
{
-
scene_state.max_instances = render_list.max_elements;
scene_state.instances = memnew_arr(InstanceData, scene_state.max_instances);
scene_state.instance_buffer = RD::get_singleton()->storage_buffer_create(sizeof(InstanceData) * scene_state.max_instances);
@@ -3145,7 +3222,6 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
}
{
-
overdraw_material_shader = storage->shader_create();
storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }");
overdraw_material = storage->material_create();
@@ -3169,7 +3245,6 @@ RasterizerSceneHighEndRD::RasterizerSceneHighEndRD(RasterizerStorageRD *p_storag
default_vec4_xform_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, TRANSFORMS_UNIFORM_SET);
}
{
-
RD::SamplerState sampler;
sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
@@ -3235,12 +3310,16 @@ RasterizerSceneHighEndRD::~RasterizerSceneHighEndRD() {
RD::get_singleton()->free(scene_state.gi_probe_buffer);
RD::get_singleton()->free(scene_state.directional_light_buffer);
RD::get_singleton()->free(scene_state.light_buffer);
+ RD::get_singleton()->free(scene_state.lightmap_buffer);
+ RD::get_singleton()->free(scene_state.lightmap_capture_buffer);
RD::get_singleton()->free(scene_state.reflection_buffer);
RD::get_singleton()->free(scene_state.decal_buffer);
memdelete_arr(scene_state.instances);
memdelete_arr(scene_state.gi_probes);
memdelete_arr(scene_state.directional_lights);
memdelete_arr(scene_state.lights);
+ memdelete_arr(scene_state.lightmaps);
+ memdelete_arr(scene_state.lightmap_captures);
memdelete_arr(scene_state.reflections);
memdelete_arr(scene_state.decals);
}
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h
index a48e2e2259..8438a4f730 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_high_end_rd.h
@@ -38,7 +38,6 @@
#include "servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl.gen.h"
class RasterizerSceneHighEndRD : public RasterizerSceneRD {
-
enum {
SCENE_UNIFORM_SET = 0,
RADIANCE_UNIFORM_SET = 1,
@@ -75,7 +74,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
/* Material */
struct ShaderData : public RasterizerStorageRD::ShaderData {
-
enum BlendMode { //used internally
BLEND_MODE_MIX,
BLEND_MODE_ADD,
@@ -193,7 +191,8 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
struct PushConstant {
uint32_t index;
- uint32_t pad[3];
+ uint32_t pad;
+ float bake_uv2_offset[2];
};
/* Framebuffer */
@@ -241,6 +240,8 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
RID render_base_uniform_set;
RID view_dependant_uniform_set;
+ uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
+
virtual void _base_uniforms_changed();
void _render_buffers_clear_uniform_set(RenderBufferDataHighEnd *rb);
virtual void _render_buffers_uniform_set_changed(RID p_render_buffers);
@@ -285,7 +286,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
};
struct DirectionalLightData {
-
float direction[3];
float energy;
float color[3];
@@ -331,6 +331,10 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
uint32_t pad[1];
};
+ struct LightmapData {
+ float normal_xform[12];
+ };
+
struct DecalData {
float xform[16];
float inv_extents[3];
@@ -349,7 +353,15 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
float normal_fade;
};
+ struct LightmapCaptureData {
+ float sh[9 * 4];
+ };
+
enum {
+ INSTANCE_DATA_FLAG_USE_LIGHTMAP_CAPTURE = 1 << 8,
+ INSTANCE_DATA_FLAG_USE_LIGHTMAP = 1 << 9,
+ INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP = 1 << 10,
+ INSTANCE_DATA_FLAG_USE_GIPROBE = 1 << 11,
INSTANCE_DATA_FLAG_MULTIMESH = 1 << 12,
INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D = 1 << 13,
INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR = 1 << 14,
@@ -366,6 +378,7 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
uint32_t instance_uniforms_ofs; //instance_offset in instancing/skeleton buffer
uint32_t gi_offset; //GI information when using lightmapping (VCT or lightmap)
uint32_t mask;
+ float lightmap_uv_scale[4];
};
struct SceneState {
@@ -418,6 +431,9 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
uint32_t roughness_limiter_enabled;
float ao_color[4];
+
+ uint32_t material_uv2_mode;
+ uint32_t pad_material[3];
};
UBO ubo;
@@ -434,6 +450,10 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
RID gi_probe_buffer;
uint32_t max_gi_probe_probes_per_instance;
+ LightmapData *lightmaps;
+ uint32_t max_lightmaps;
+ RID lightmap_buffer;
+
DecalData *decals;
uint32_t max_decals;
RID decal_buffer;
@@ -446,6 +466,10 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
uint32_t max_directional_lights;
RID directional_light_buffer;
+ LightmapCaptureData *lightmap_captures;
+ uint32_t max_lightmap_captures;
+ RID lightmap_capture_buffer;
+
RID instance_buffer;
InstanceData *instances;
uint32_t max_instances;
@@ -456,12 +480,12 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
bool used_sss = false;
uint32_t current_shader_index = 0;
uint32_t current_material_index = 0;
+
} scene_state;
/* Render List */
struct RenderList {
-
int max_elements;
struct Element {
@@ -492,7 +516,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
int alpha_element_count;
void clear() {
-
element_count = 0;
alpha_element_count = 0;
}
@@ -500,14 +523,12 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
//should eventually be replaced by radix
struct SortByKey {
-
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
return A->sort_key < B->sort_key;
}
};
void sort_by_key(bool p_alpha) {
-
SortArray<Element *, SortByKey> sorter;
if (p_alpha) {
sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
@@ -517,7 +538,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
}
struct SortByDepth {
-
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
return A->instance->depth < B->instance->depth;
}
@@ -534,7 +554,6 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
}
struct SortByReverseDepthAndPriority {
-
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
uint32_t layer_A = uint32_t(A->priority);
uint32_t layer_B = uint32_t(B->priority);
@@ -557,17 +576,17 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
}
_FORCE_INLINE_ Element *add_element() {
-
- if (element_count + alpha_element_count >= max_elements)
+ if (element_count + alpha_element_count >= max_elements) {
return nullptr;
+ }
elements[element_count] = &base_elements[element_count];
return elements[element_count++];
}
_FORCE_INLINE_ Element *add_alpha_element() {
-
- if (element_count + alpha_element_count >= max_elements)
+ if (element_count + alpha_element_count >= max_elements) {
return nullptr;
+ }
int idx = max_elements - alpha_element_count - 1;
elements[idx] = &base_elements[idx];
alpha_element_count++;
@@ -575,17 +594,16 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
}
void init() {
-
element_count = 0;
alpha_element_count = 0;
elements = memnew_arr(Element *, max_elements);
base_elements = memnew_arr(Element, max_elements);
- for (int i = 0; i < max_elements; i++)
+ for (int i = 0; i < max_elements; i++) {
elements[i] = &base_elements[i]; // assign elements
+ }
}
RenderList() {
-
max_elements = 0;
}
@@ -632,18 +650,20 @@ class RasterizerSceneHighEndRD : public RasterizerSceneRD {
void _setup_decals(const RID *p_decal_instances, int p_decal_count, const Transform &p_camera_inverse_xform);
void _setup_reflections(RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, const Transform &p_camera_inverse_transform, RID p_environment);
void _setup_gi_probes(RID *p_gi_probe_probe_cull_result, int p_gi_probe_probe_cull_count, const Transform &p_camera_transform);
+ void _setup_lightmaps(InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, const Transform &p_cam_transform);
void _fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth);
- void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set);
+ void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_radiance_uniform_set, RID p_render_buffers_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2());
_FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index);
_FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index);
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, PassMode p_pass_mode, bool p_no_gi);
protected:
- virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color);
+ virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color);
virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake);
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region);
+ virtual void _render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region);
public:
virtual void set_time(double p_time, double p_step);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
index 8877de87ac..689552be2f 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.cpp
@@ -49,7 +49,6 @@ void get_vogel_disk(float *r_kernel, int p_sample_count) {
}
void RasterizerSceneRD::_clear_reflection_data(ReflectionData &rd) {
-
rd.layers.clear();
rd.radiance_base_cubemap = RID();
if (rd.downsampled_radiance_cubemap.is_valid()) {
@@ -152,7 +151,6 @@ void RasterizerSceneRD::_update_reflection_data(ReflectionData &rd, int p_size,
}
void RasterizerSceneRD::_create_reflection_fast_filter(ReflectionData &rd, bool p_use_arrays) {
-
storage->get_effects()->cubemap_downsample(rd.radiance_base_cubemap, rd.downsampled_layer.mipmaps[0].view, rd.downsampled_layer.mipmaps[0].size);
for (int i = 1; i < rd.downsampled_layer.mipmaps.size(); i++) {
@@ -174,21 +172,16 @@ void RasterizerSceneRD::_create_reflection_fast_filter(ReflectionData &rd, bool
}
void RasterizerSceneRD::_create_reflection_importance_sample(ReflectionData &rd, bool p_use_arrays, int p_cube_side, int p_base_layer) {
-
if (p_use_arrays) {
-
//render directly to the layers
storage->get_effects()->cubemap_roughness(rd.radiance_base_cubemap, rd.layers[p_base_layer].views[0], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers.size() - 1.0), rd.layers[p_base_layer].mipmaps[0].size.x);
} else {
-
storage->get_effects()->cubemap_roughness(rd.layers[0].views[p_base_layer - 1], rd.layers[0].views[p_base_layer], p_cube_side, sky_ggx_samples_quality, float(p_base_layer) / (rd.layers[0].mipmaps.size() - 1.0), rd.layers[0].mipmaps[p_base_layer].size.x);
}
}
void RasterizerSceneRD::_update_reflection_mipmaps(ReflectionData &rd) {
-
if (sky_use_cubemap_array) {
-
for (int i = 0; i < rd.layers.size(); i++) {
for (int j = 0; j < rd.layers[i].mipmaps.size() - 1; j++) {
for (int k = 0; k < 6; k++) {
@@ -263,13 +256,49 @@ void RasterizerSceneRD::sky_set_material(RID p_sky, RID p_material) {
Sky *sky = sky_owner.getornull(p_sky);
ERR_FAIL_COND(!sky);
sky->material = p_material;
+ _sky_invalidate(sky);
}
-void RasterizerSceneRD::_update_dirty_skys() {
+Ref<Image> RasterizerSceneRD::sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) {
+ Sky *sky = sky_owner.getornull(p_sky);
+ ERR_FAIL_COND_V(!sky, Ref<Image>());
+
+ _update_dirty_skys();
+
+ if (sky->radiance.is_valid()) {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
+ tf.width = p_size.width;
+ tf.height = p_size.height;
+ tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+
+ RID rad_tex = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ storage->get_effects()->copy_cubemap_to_panorama(sky->radiance, rad_tex, p_size, p_bake_irradiance ? roughness_layers : 0, sky->reflection.layers.size() > 1);
+ Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rad_tex, 0);
+ RD::get_singleton()->free(rad_tex);
+
+ Ref<Image> img;
+ img.instance();
+ img->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF, data);
+ for (int i = 0; i < p_size.width; i++) {
+ for (int j = 0; j < p_size.height; j++) {
+ Color c = img->get_pixel(i, j);
+ c.r *= p_energy;
+ c.g *= p_energy;
+ c.b *= p_energy;
+ img->set_pixel(i, j, c);
+ }
+ }
+ return img;
+ }
+
+ return Ref<Image>();
+}
+
+void RasterizerSceneRD::_update_dirty_skys() {
Sky *sky = dirty_sky_list;
while (sky) {
-
bool texture_set_dirty = false;
//update sky configuration if texture is missing
@@ -381,7 +410,6 @@ RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader,
ERR_FAIL_COND_V(!sky, RID());
if (sky->uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(sky->uniform_set)) {
-
sky->uniform_set = RID();
if (sky->radiance.is_valid()) {
Vector<RD::Uniform> uniforms;
@@ -401,7 +429,6 @@ RID RasterizerSceneRD::sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader,
}
RID RasterizerSceneRD::_get_sky_textures(Sky *p_sky, SkyTextureSetVersion p_version) {
-
if (p_sky->texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(p_sky->texture_uniform_sets[p_version])) {
return p_sky->texture_uniform_sets[p_version];
}
@@ -468,7 +495,6 @@ RID RasterizerSceneRD::sky_get_material(RID p_sky) const {
}
void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) {
-
ERR_FAIL_COND(!is_environment(p_environment));
Sky *sky = sky_owner.getornull(environment_get_sky(p_environment));
@@ -505,7 +531,6 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue
CameraMatrix camera;
if (custom_fov) {
-
float near_plane = p_projection.get_z_near();
float far_plane = p_projection.get_z_far();
float aspect = p_projection.get_aspect();
@@ -554,7 +579,6 @@ void RasterizerSceneRD::_draw_sky(bool p_can_continue_color, bool p_can_continue
}
void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position, const Size2i p_screen_size) {
-
ERR_FAIL_COND(!is_environment(p_environment));
Sky *sky = sky_owner.getornull(environment_get_sky(p_environment));
@@ -612,26 +636,22 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position,
}
if (shader_data->uses_time && time - sky->prev_time > 0.00001) {
-
sky->prev_time = time;
sky->reflection.dirty = true;
RenderingServerRaster::redraw_request();
}
if (material != sky->prev_material) {
-
sky->prev_material = material;
sky->reflection.dirty = true;
}
if (material->uniform_set_updated) {
-
material->uniform_set_updated = false;
sky->reflection.dirty = true;
}
if (!p_position.is_equal_approx(sky->prev_position) && shader_data->uses_position) {
-
sky->prev_position = p_position;
sky->reflection.dirty = true;
}
@@ -664,7 +684,6 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position,
}
if (light_data_dirty || sky_scene_state.light_uniform_set.is_null()) {
-
RD::get_singleton()->buffer_update(sky_scene_state.directional_light_buffer, 0, sizeof(SkyDirectionalLightData) * sky_scene_state.max_directional_lights, sky_scene_state.directional_lights, true);
if (sky_scene_state.light_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky_scene_state.light_uniform_set)) {
@@ -692,7 +711,6 @@ void RasterizerSceneRD::_setup_sky(RID p_environment, const Vector3 &p_position,
}
void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform) {
-
ERR_FAIL_COND(!is_environment(p_environment));
Sky *sky = sky_owner.getornull(environment_get_sky(p_environment));
@@ -724,7 +742,6 @@ void RasterizerSceneRD::_update_sky(RID p_environment, const CameraMatrix &p_pro
// Update radiance cubemap
if (sky->reflection.dirty) {
-
static const Vector3 view_normals[6] = {
Vector3(+1, 0, 0),
Vector3(-1, 0, 0),
@@ -905,7 +922,6 @@ void RasterizerSceneRD::SkyShaderData::set_code(const String &p_code) {
//update pipelines
for (int i = 0; i < SKY_VERSION_MAX; i++) {
-
RD::PipelineDepthStencilState depth_stencil_state;
depth_stencil_state.enable_depth_test = true;
depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
@@ -926,11 +942,9 @@ void RasterizerSceneRD::SkyShaderData::set_default_texture_param(const StringNam
}
void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
-
Map<int, StringName> order;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
-
if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
@@ -943,7 +957,6 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para
}
for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
-
PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]);
pi.name = E->get();
p_param_list->push_back(pi);
@@ -951,9 +964,7 @@ void RasterizerSceneRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_para
}
void RasterizerSceneRD::SkyShaderData::get_instance_param_list(List<RasterizerStorage::InstanceShaderParam> *p_param_list) const {
-
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
-
if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue;
}
@@ -1011,7 +1022,6 @@ RasterizerStorageRD::ShaderData *RasterizerSceneRD::_create_sky_shader_func() {
}
void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
-
RasterizerSceneRD *scene_singleton = (RasterizerSceneRD *)RasterizerSceneRD::singleton;
uniform_set_updated = true;
@@ -1038,7 +1048,6 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName,
//check whether buffer changed
if (p_uniform_dirty && ubo_data.size()) {
-
update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw());
}
@@ -1057,7 +1066,6 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName,
}
if (p_textures_dirty && tex_uniform_count) {
-
update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
}
@@ -1074,7 +1082,6 @@ void RasterizerSceneRD::SkyMaterialData::update_parameters(const Map<StringName,
Vector<RD::Uniform> uniforms;
{
-
if (shader_data->ubo_size) {
RD::Uniform u;
u.type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
@@ -1115,7 +1122,6 @@ RasterizerStorageRD::MaterialData *RasterizerSceneRD::_create_sky_material_func(
}
RID RasterizerSceneRD::environment_create() {
-
return environment_owner.make_rid(Environent());
}
@@ -1124,36 +1130,43 @@ void RasterizerSceneRD::environment_set_background(RID p_env, RS::EnvironmentBG
ERR_FAIL_COND(!env);
env->background = p_bg;
}
+
void RasterizerSceneRD::environment_set_sky(RID p_env, RID p_sky) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky = p_sky;
}
+
void RasterizerSceneRD::environment_set_sky_custom_fov(RID p_env, float p_scale) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky_custom_fov = p_scale;
}
+
void RasterizerSceneRD::environment_set_sky_orientation(RID p_env, const Basis &p_orientation) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->sky_orientation = p_orientation;
}
+
void RasterizerSceneRD::environment_set_bg_color(RID p_env, const Color &p_color) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->bg_color = p_color;
}
+
void RasterizerSceneRD::environment_set_bg_energy(RID p_env, float p_energy) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->bg_energy = p_energy;
}
+
void RasterizerSceneRD::environment_set_canvas_max_layer(RID p_env, int p_max_layer) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->canvas_max_layer = p_max_layer;
}
+
void RasterizerSceneRD::environment_set_ambient_light(RID p_env, const Color &p_color, RS::EnvironmentAmbientSource p_ambient, float p_energy, float p_sky_contribution, RS::EnvironmentReflectionSource p_reflection_source, const Color &p_ao_color) {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -1170,56 +1183,67 @@ RS::EnvironmentBG RasterizerSceneRD::environment_get_background(RID p_env) const
ERR_FAIL_COND_V(!env, RS::ENV_BG_MAX);
return env->background;
}
+
RID RasterizerSceneRD::environment_get_sky(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RID());
return env->sky;
}
+
float RasterizerSceneRD::environment_get_sky_custom_fov(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->sky_custom_fov;
}
+
Basis RasterizerSceneRD::environment_get_sky_orientation(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Basis());
return env->sky_orientation;
}
+
Color RasterizerSceneRD::environment_get_bg_color(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->bg_color;
}
+
float RasterizerSceneRD::environment_get_bg_energy(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->bg_energy;
}
+
int RasterizerSceneRD::environment_get_canvas_max_layer(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->canvas_max_layer;
}
+
Color RasterizerSceneRD::environment_get_ambient_light_color(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, Color());
return env->ambient_light;
}
+
RS::EnvironmentAmbientSource RasterizerSceneRD::environment_get_ambient_source(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RS::ENV_AMBIENT_SOURCE_BG);
return env->ambient_source;
}
+
float RasterizerSceneRD::environment_get_ambient_light_energy(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->ambient_light_energy;
}
+
float RasterizerSceneRD::environment_get_ambient_sky_contribution(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, 0);
return env->ambient_sky_contribution;
}
+
RS::EnvironmentReflectionSource RasterizerSceneRD::environment_get_reflection_source(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, RS::ENV_REFLECTION_SOURCE_DISABLED);
@@ -1249,7 +1273,6 @@ void RasterizerSceneRD::environment_set_tonemap(RID p_env, RS::EnvironmentToneMa
}
void RasterizerSceneRD::environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, RS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) {
-
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->glow_enabled = p_enable;
@@ -1269,7 +1292,6 @@ void RasterizerSceneRD::environment_glow_set_use_bicubic_upscale(bool p_enable)
}
void RasterizerSceneRD::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance) {
-
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -1289,7 +1311,6 @@ RS::EnvironmentSSRRoughnessQuality RasterizerSceneRD::environment_get_ssr_roughn
}
void RasterizerSceneRD::environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_bias, float p_light_affect, float p_ao_channel_affect, RS::EnvironmentSSAOBlur p_blur, float p_bilateral_sharpness) {
-
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
@@ -1308,7 +1329,6 @@ void RasterizerSceneRD::environment_set_ssao_quality(RS::EnvironmentSSAOQuality
}
bool RasterizerSceneRD::environment_is_ssao_enabled(RID p_env) const {
-
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, false);
return env->ssao_enabled;
@@ -1319,6 +1339,7 @@ float RasterizerSceneRD::environment_get_ssao_ao_affect(RID p_env) const {
ERR_FAIL_COND_V(!env, false);
return env->ssao_ao_channel_affect;
}
+
float RasterizerSceneRD::environment_get_ssao_light_affect(RID p_env) const {
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, false);
@@ -1326,7 +1347,6 @@ float RasterizerSceneRD::environment_get_ssao_light_affect(RID p_env) const {
}
bool RasterizerSceneRD::environment_is_ssr_enabled(RID p_env) const {
-
Environent *env = environment_owner.getornull(p_env);
ERR_FAIL_COND_V(!env, false);
return env->ssr_enabled;
@@ -1336,10 +1356,46 @@ bool RasterizerSceneRD::is_environment(RID p_env) const {
return environment_owner.owns(p_env);
}
+Ref<Image> RasterizerSceneRD::environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) {
+ Environent *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND_V(!env, Ref<Image>());
+
+ if (env->background == RS::ENV_BG_CAMERA_FEED || env->background == RS::ENV_BG_CANVAS || env->background == RS::ENV_BG_KEEP) {
+ return Ref<Image>(); //nothing to bake
+ }
+
+ if (env->background == RS::ENV_BG_CLEAR_COLOR || env->background == RS::ENV_BG_COLOR) {
+ Color color;
+ if (env->background == RS::ENV_BG_CLEAR_COLOR) {
+ color = storage->get_default_clear_color();
+ } else {
+ color = env->bg_color;
+ }
+ color.r *= env->bg_energy;
+ color.g *= env->bg_energy;
+ color.b *= env->bg_energy;
+
+ Ref<Image> ret;
+ ret.instance();
+ ret->create(p_size.width, p_size.height, false, Image::FORMAT_RGBAF);
+ for (int i = 0; i < p_size.width; i++) {
+ for (int j = 0; j < p_size.height; j++) {
+ ret->set_pixel(i, j, color);
+ }
+ }
+ return ret;
+ }
+
+ if (env->background == RS::ENV_BG_SKY && env->sky.is_valid()) {
+ return sky_bake_panorama(env->sky, env->bg_energy, p_bake_irradiance, p_size);
+ }
+
+ return Ref<Image>();
+}
+
////////////////////////////////////////////////////////////
RID RasterizerSceneRD::reflection_atlas_create() {
-
ReflectionAtlas ra;
ra.count = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_count");
ra.size = GLOBAL_GET("rendering/quality/reflection_atlas/reflection_size");
@@ -1348,7 +1404,6 @@ RID RasterizerSceneRD::reflection_atlas_create() {
}
void RasterizerSceneRD::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) {
-
ReflectionAtlas *ra = reflection_atlas_owner.getornull(p_ref_atlas);
ERR_FAIL_COND(!ra);
@@ -1395,7 +1450,6 @@ void RasterizerSceneRD::reflection_probe_instance_set_transform(RID p_instance,
}
void RasterizerSceneRD::reflection_probe_release_atlas_index(RID p_instance) {
-
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND(!rpi);
@@ -1411,7 +1465,6 @@ void RasterizerSceneRD::reflection_probe_release_atlas_index(RID p_instance) {
}
bool RasterizerSceneRD::reflection_probe_instance_needs_redraw(RID p_instance) {
-
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, false);
@@ -1431,7 +1484,6 @@ bool RasterizerSceneRD::reflection_probe_instance_needs_redraw(RID p_instance) {
}
bool RasterizerSceneRD::reflection_probe_instance_has_reflection(RID p_instance) {
-
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, false);
@@ -1439,7 +1491,6 @@ bool RasterizerSceneRD::reflection_probe_instance_has_reflection(RID p_instance)
}
bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) {
-
ReflectionAtlas *atlas = reflection_atlas_owner.getornull(p_reflection_atlas);
ERR_FAIL_COND_V(!atlas, false);
@@ -1484,7 +1535,6 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R
atlas->reflection = RD::get_singleton()->texture_create(tf, RD::TextureView());
}
{
-
RD::TextureFormat tf;
tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
tf.width = atlas->size;
@@ -1540,7 +1590,6 @@ bool RasterizerSceneRD::reflection_probe_instance_begin_render(RID p_instance, R
}
bool RasterizerSceneRD::reflection_probe_instance_postprocess_step(RID p_instance) {
-
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!rpi, false);
ERR_FAIL_COND_V(!rpi->rendering, false);
@@ -1618,19 +1667,18 @@ RID RasterizerSceneRD::reflection_probe_instance_get_depth_framebuffer(RID p_ins
///////////////////////////////////////////////////////////
RID RasterizerSceneRD::shadow_atlas_create() {
-
return shadow_atlas_owner.make_rid(ShadowAtlas());
}
void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
-
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
ERR_FAIL_COND(!shadow_atlas);
ERR_FAIL_COND(p_size < 0);
p_size = next_power_of_2(p_size);
- if (p_size == shadow_atlas->size)
+ if (p_size == shadow_atlas->size) {
return;
+ }
// erasing atlas
if (shadow_atlas->depth.is_valid()) {
@@ -1656,7 +1704,6 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
shadow_atlas->size = p_size;
if (shadow_atlas->size) {
-
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
tf.width = shadow_atlas->size;
@@ -1668,7 +1715,6 @@ void RasterizerSceneRD::shadow_atlas_set_size(RID p_atlas, int p_size) {
}
void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {
-
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
ERR_FAIL_COND(!shadow_atlas);
ERR_FAIL_INDEX(p_quadrant, 4);
@@ -1683,12 +1729,12 @@ void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p
//obtain the number that will be x*x
- if (shadow_atlas->quadrants[p_quadrant].subdivision == subdiv)
+ if (shadow_atlas->quadrants[p_quadrant].subdivision == subdiv) {
return;
+ }
//erase all data from quadrant
for (int i = 0; i < shadow_atlas->quadrants[p_quadrant].shadows.size(); i++) {
-
if (shadow_atlas->quadrants[p_quadrant].shadows[i].owner.is_valid()) {
shadow_atlas->shadow_owners.erase(shadow_atlas->quadrants[p_quadrant].shadows[i].owner);
LightInstance *li = light_instance_owner.getornull(shadow_atlas->quadrants[p_quadrant].shadows[i].owner);
@@ -1731,9 +1777,7 @@ void RasterizerSceneRD::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p
}
bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow) {
-
for (int i = p_quadrant_count - 1; i >= 0; i--) {
-
int qidx = p_in_quadrants[i];
if (shadow_atlas->quadrants[qidx].subdivision == (uint32_t)p_current_subdiv) {
@@ -1758,10 +1802,10 @@ bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int
ERR_CONTINUE(!sli);
if (sli->last_scene_pass != scene_pass) {
-
//was just allocated, don't kill it so soon, wait a bit..
- if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec)
+ if (p_tick - sarr[j].alloc_tick < shadow_atlas_realloc_tolerance_msec) {
continue;
+ }
if (found_used_idx == -1 || sli->last_scene_pass < min_pass) {
found_used_idx = j;
@@ -1770,8 +1814,9 @@ bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int
}
}
- if (found_free_idx == -1 && found_used_idx == -1)
+ if (found_free_idx == -1 && found_used_idx == -1) {
continue; //nothing found
+ }
if (found_free_idx == -1 && found_used_idx != -1) {
found_free_idx = found_used_idx;
@@ -1787,7 +1832,6 @@ bool RasterizerSceneRD::_shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int
}
bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) {
-
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_atlas);
ERR_FAIL_COND_V(!shadow_atlas, false);
@@ -1810,13 +1854,15 @@ bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intan
for (int i = 0; i < 4; i++) {
int q = shadow_atlas->size_order[i];
int sd = shadow_atlas->quadrants[q].subdivision;
- if (sd == 0)
+ if (sd == 0) {
continue; //unused
+ }
int max_fit = quad_size / sd;
- if (best_size != -1 && max_fit > best_size)
+ if (best_size != -1 && max_fit > best_size) {
break; //too large
+ }
valid_quadrants[valid_quadrant_count++] = q;
best_subdiv = sd;
@@ -1921,7 +1967,6 @@ bool RasterizerSceneRD::shadow_atlas_update_light(RID p_atlas, RID p_light_intan
}
void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) {
-
p_size = nearest_power_of_2_templated(p_size);
if (directional_shadow.size == p_size) {
@@ -1936,7 +1981,6 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) {
}
if (p_size > 0) {
-
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
tf.width = p_size;
@@ -1950,13 +1994,11 @@ void RasterizerSceneRD::directional_shadow_atlas_set_size(int p_size) {
}
void RasterizerSceneRD::set_directional_shadow_count(int p_count) {
-
directional_shadow.light_count = p_count;
directional_shadow.current_light = 0;
}
static Rect2i _get_directional_shadow_rect(int p_size, int p_shadow_count, int p_shadow_index) {
-
int split_h = 1;
int split_v = 1;
@@ -1979,7 +2021,6 @@ static Rect2i _get_directional_shadow_rect(int p_size, int p_shadow_count, int p
}
int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) {
-
ERR_FAIL_COND_V(directional_shadow.light_count == 0, 0);
Rect2i r = _get_directional_shadow_rect(directional_shadow.size, directional_shadow.light_count, 0);
@@ -1990,8 +2031,12 @@ int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) {
switch (storage->light_directional_get_shadow_mode(light_instance->light)) {
case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL:
break; //none
- case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: r.size.height /= 2; break;
- case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: r.size /= 2; break;
+ case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
+ r.size.height /= 2;
+ break;
+ case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:
+ r.size /= 2;
+ break;
}
return MAX(r.size.width, r.size.height);
@@ -2000,18 +2045,15 @@ int RasterizerSceneRD::get_directional_light_shadow_size(RID p_light_intance) {
//////////////////////////////////////////////////
RID RasterizerSceneRD::camera_effects_create() {
-
return camera_effects_owner.make_rid(CameraEffects());
}
void RasterizerSceneRD::camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter) {
-
dof_blur_quality = p_quality;
dof_blur_use_jitter = p_use_jitter;
}
void RasterizerSceneRD::camera_effects_set_dof_blur_bokeh_shape(RS::DOFBokehShape p_shape) {
-
dof_blur_bokeh_shape = p_shape;
}
@@ -2031,7 +2073,6 @@ void RasterizerSceneRD::camera_effects_set_dof_blur(RID p_camera_effects, bool p
}
void RasterizerSceneRD::camera_effects_set_custom_exposure(RID p_camera_effects, bool p_enable, float p_exposure) {
-
CameraEffects *camfx = camera_effects_owner.getornull(p_camera_effects);
ERR_FAIL_COND(!camfx);
@@ -2040,7 +2081,6 @@ void RasterizerSceneRD::camera_effects_set_custom_exposure(RID p_camera_effects,
}
RID RasterizerSceneRD::light_instance_create(RID p_light) {
-
RID li = light_instance_owner.make_rid(LightInstance());
LightInstance *light_instance = light_instance_owner.getornull(li);
@@ -2053,7 +2093,6 @@ RID RasterizerSceneRD::light_instance_create(RID p_light) {
}
void RasterizerSceneRD::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {
-
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
@@ -2061,7 +2100,6 @@ void RasterizerSceneRD::light_instance_set_transform(RID p_light_instance, const
}
void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
-
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
@@ -2082,7 +2120,6 @@ void RasterizerSceneRD::light_instance_set_shadow_transform(RID p_light_instance
}
void RasterizerSceneRD::light_instance_mark_visible(RID p_light_instance) {
-
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
@@ -2090,9 +2127,7 @@ void RasterizerSceneRD::light_instance_mark_visible(RID p_light_instance) {
}
RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_size) {
-
if (!shadow_cubemaps.has(p_size)) {
-
ShadowCubemap sc;
{
RD::TextureFormat tf;
@@ -2119,9 +2154,7 @@ RasterizerSceneRD::ShadowCubemap *RasterizerSceneRD::_get_shadow_cubemap(int p_s
}
RasterizerSceneRD::ShadowMap *RasterizerSceneRD::_get_shadow_map(const Size2i &p_size) {
-
if (!shadow_maps.has(p_size)) {
-
ShadowMap sm;
{
RD::TextureFormat tf;
@@ -2181,7 +2214,6 @@ RID RasterizerSceneRD::gi_probe_instance_create(RID p_base) {
}
void RasterizerSceneRD::gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) {
-
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
ERR_FAIL_COND(!gi_probe);
@@ -2197,7 +2229,6 @@ bool RasterizerSceneRD::gi_probe_needs_update(RID p_probe) const {
}
void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, int p_dynamic_object_count, InstanceBase **p_dynamic_objects) {
-
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
ERR_FAIL_COND(!gi_probe);
@@ -2449,7 +2480,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
dmap.depth = RD::get_singleton()->texture_create(dtf, RD::TextureView());
if (gi_probe->dynamic_maps.size() == 0) {
-
dtf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
dtf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
dmap.albedo = RD::get_singleton()->texture_create(dtf, RD::TextureView());
@@ -2557,7 +2587,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
}
if (write) {
-
{
RD::Uniform u;
u.type = RD::UNIFORM_TYPE_IMAGE;
@@ -2590,7 +2619,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
}
if (plot) {
-
{
RD::Uniform u;
u.type = RD::UNIFORM_TYPE_IMAGE;
@@ -2644,7 +2672,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
uint32_t light_count = 0;
if (p_update_light_instances || p_dynamic_object_count > 0) {
-
light_count = MIN(gi_probe_max_lights, (uint32_t)p_light_instances.size());
{
@@ -2724,9 +2751,7 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
int wg_limit_x = RD::get_singleton()->limit_get(RD::LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X);
for (int pass = 0; pass < passes; pass++) {
-
if (p_update_light_instances) {
-
for (int i = 0; i < gi_probe->mipmaps.size(); i++) {
if (i == 0) {
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[pass == 0 ? GI_PROBE_SHADER_VERSION_COMPUTE_LIGHT : GI_PROBE_SHADER_VERSION_COMPUTE_SECOND_BOUNCE]);
@@ -2762,7 +2787,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, giprobe_lighting_shader_version_pipelines[GI_PROBE_SHADER_VERSION_WRITE_TEXTURE]);
for (int i = 0; i < gi_probe->mipmaps.size(); i++) {
-
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, gi_probe->mipmaps[i].write_uniform_set, 0);
push_constant.cell_offset = gi_probe->mipmaps[i].cell_offset;
@@ -2786,7 +2810,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
gi_probe->has_dynamic_object_data = false; //clear until dynamic object data is used again
if (p_dynamic_object_count && gi_probe->dynamic_maps.size()) {
-
Vector3i octree_size = storage->gi_probe_get_octree_size(gi_probe->probe);
int multiplier = gi_probe->dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z);
@@ -2801,7 +2824,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
//this could probably be better parallelized in compute..
for (int i = 0; i < p_dynamic_object_count; i++) {
-
InstanceBase *instance = p_dynamic_objects[i];
//not used, so clear
instance->depth_layer = 0;
@@ -2830,7 +2852,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
//print_line("aabb: " + aabb);
for (int j = 0; j < 6; j++) {
-
//if (j != 0 && j != 3) {
// continue;
//}
@@ -2919,7 +2940,6 @@ void RasterizerSceneRD::gi_probe_update(RID p_probe, bool p_update_light_instanc
//print_line("rect: " + itos(i) + ": " + rect);
for (int k = 1; k < gi_probe->dynamic_maps.size(); k++) {
-
// enlarge the rect if needed so all pixels fit when downscaled,
// this ensures downsampling is smooth and optimal because no pixels are left behind
@@ -3017,7 +3037,6 @@ void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_lis
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
-
push_constant.projection[i * 4 + j] = transform.matrix[i][j];
}
}
@@ -3080,7 +3099,6 @@ void RasterizerSceneRD::_debug_giprobe(RID p_gi_probe, RD::DrawListID p_draw_lis
}
const Vector<RID> &RasterizerSceneRD::gi_probe_get_slots() const {
-
return gi_probe_slots;
}
@@ -3119,7 +3137,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) {
int base_height = rb->height;
for (uint32_t i = 0; i < mipmaps_required; i++) {
-
RenderBuffers::Blur::Mipmap mm;
mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[0].texture, 0, i);
@@ -3129,7 +3146,6 @@ void RasterizerSceneRD::_allocate_blur_textures(RenderBuffers *rb) {
rb->blur[0].mipmaps.push_back(mm);
if (i > 0) {
-
mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[1].texture, 0, i - 1);
rb->blur[1].mipmaps.push_back(mm);
@@ -3174,7 +3190,6 @@ void RasterizerSceneRD::_allocate_luminance_textures(RenderBuffers *rb) {
}
void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) {
-
if (rb->texture.is_valid()) {
RD::get_singleton()->free(rb->texture);
rb->texture = RID();
@@ -3240,7 +3255,6 @@ void RasterizerSceneRD::_free_render_buffer_data(RenderBuffers *rb) {
}
void RasterizerSceneRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) {
-
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -3260,7 +3274,6 @@ void RasterizerSceneRD::_process_sss(RID p_render_buffers, const CameraMatrix &p
}
void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_roughness_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) {
-
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -3314,7 +3327,6 @@ void RasterizerSceneRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffe
}
void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) {
-
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -3382,7 +3394,6 @@ void RasterizerSceneRD::_process_ssao(RID p_render_buffers, RID p_environment, R
}
void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_buffers, RID p_environment, RID p_camera_effects, const CameraMatrix &p_projection) {
-
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -3393,7 +3404,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
bool can_use_effects = rb->width >= 8 && rb->height >= 8;
if (can_use_effects && camfx && (camfx->dof_blur_near_enabled || camfx->dof_blur_far_enabled) && camfx->dof_blur_amount > 0.0) {
-
if (rb->blur[0].texture.is_null()) {
_allocate_blur_textures(rb);
_render_buffers_uniform_set_changed(p_render_buffers);
@@ -3404,7 +3414,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
}
if (can_use_effects && env && env->auto_exposure) {
-
if (rb->luminance.current.is_null()) {
_allocate_luminance_textures(rb);
_render_buffers_uniform_set_changed(p_render_buffers);
@@ -3425,7 +3434,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
int glow_mask = 0;
if (can_use_effects && env && env->glow_enabled) {
-
/* see that blur textures are allocated */
if (rb->blur[0].texture.is_null()) {
@@ -3435,7 +3443,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) {
if (env->glow_levels & (1 << i)) {
-
if (i >= rb->blur[1].mipmaps.size()) {
max_glow_level = rb->blur[1].mipmaps.size() - 1;
glow_mask |= 1 << max_glow_level;
@@ -3448,7 +3455,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
}
for (int i = 0; i < (max_glow_level + 1); i++) {
-
int vp_w = rb->blur[1].mipmaps[i].width;
int vp_h = rb->blur[1].mipmaps[i].height;
@@ -3475,7 +3481,6 @@ void RasterizerSceneRD::_render_buffers_post_process_and_tonemap(RID p_render_bu
tonemap.exposure_texture = rb->luminance.current;
tonemap.auto_exposure_grey = env->auto_exp_scale;
} else {
-
tonemap.exposure_texture = storage->texture_rd_get_default(RasterizerStorageRD::DEFAULT_RD_TEXTURE_WHITE);
}
@@ -3570,7 +3575,6 @@ void RasterizerSceneRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_s
}
RID RasterizerSceneRD::render_buffers_get_back_buffer_texture(RID p_render_buffers) {
-
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
if (!rb->blur[0].texture.is_valid()) {
@@ -3587,7 +3591,6 @@ RID RasterizerSceneRD::render_buffers_get_ao_texture(RID p_render_buffers) {
}
void RasterizerSceneRD::render_buffers_configure(RID p_render_buffers, RID p_render_target, int p_width, int p_height, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa) {
-
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
rb->width = p_width;
rb->height = p_height;
@@ -3642,7 +3645,6 @@ void RasterizerSceneRD::sub_surface_scattering_set_scale(float p_scale, float p_
}
void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) {
-
ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum");
if (shadows_quality != p_quality) {
@@ -3683,7 +3685,6 @@ void RasterizerSceneRD::shadows_quality_set(RS::ShadowQuality p_quality) {
}
void RasterizerSceneRD::directional_shadow_quality_set(RS::ShadowQuality p_quality) {
-
ERR_FAIL_INDEX_MSG(p_quality, RS::SHADOW_QUALITY_MAX, "Shadow quality too high, please see RenderingServer's ShadowQuality enum");
if (directional_shadow_quality != p_quality) {
@@ -3737,8 +3738,7 @@ RasterizerSceneRD::RenderBufferData *RasterizerSceneRD::render_buffers_get_data(
return rb->data;
}
-void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
-
+void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
Color clear_color;
if (p_render_buffers.is_valid()) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
@@ -3748,7 +3748,7 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca
clear_color = storage->get_default_clear_color();
}
- _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_decal_cull_result, p_decal_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color);
+ _render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_light_cull_result, p_light_cull_count, p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_gi_probe_cull_result, p_gi_probe_cull_count, p_decal_cull_result, p_decal_cull_count, p_lightmap_cull_result, p_lightmap_cull_count, p_environment, p_camera_effects, p_shadow_atlas, p_reflection_atlas, p_reflection_probe, p_reflection_probe_pass, clear_color);
if (p_render_buffers.is_valid()) {
RENDER_TIMESTAMP("Tonemap");
@@ -3759,7 +3759,6 @@ void RasterizerSceneRD::render_scene(RID p_render_buffers, const Transform &p_ca
}
void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {
-
LightInstance *light_instance = light_instance_owner.getornull(p_light);
ERR_FAIL_COND(!light_instance);
@@ -3801,7 +3800,6 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
atlas_rect.size.height = light_instance->directional_rect.size.y;
if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
-
atlas_rect.size.width /= 2;
atlas_rect.size.height /= 2;
@@ -3815,11 +3813,9 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
}
} else if (storage->light_directional_get_shadow_mode(light_instance->light) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
-
atlas_rect.size.height /= 2;
if (p_pass == 0) {
-
} else {
atlas_rect.position.y += atlas_rect.size.height;
}
@@ -3872,9 +3868,7 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
normal_bias = storage->light_get_param(light_instance->light, RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS);
if (storage->light_get_type(light_instance->light) == RS::LIGHT_OMNI) {
-
if (storage->light_omni_get_shadow_mode(light_instance->light) == RS::LIGHT_OMNI_SHADOW_CUBE) {
-
ShadowCubemap *cubemap = _get_shadow_cubemap(shadow_size / 2);
render_fb = cubemap->side_fb[p_pass];
@@ -3886,7 +3880,6 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
finalize_cubemap = p_pass == 5;
} else {
-
light_projection = light_instance->shadow_transform[0].camera;
light_transform = light_instance->shadow_transform[0].transform;
@@ -3902,7 +3895,6 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
}
} else if (storage->light_get_type(light_instance->light) == RS::LIGHT_SPOT) {
-
light_projection = light_instance->shadow_transform[0].camera;
light_transform = light_instance->shadow_transform[0].transform;
@@ -3943,12 +3935,10 @@ void RasterizerSceneRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pas
}
void RasterizerSceneRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) {
-
_render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_cull_result, p_cull_count, p_framebuffer, p_region);
}
bool RasterizerSceneRD::free(RID p_rid) {
-
if (render_buffers_owner.owns(p_rid)) {
RenderBuffers *rb = render_buffers_owner.getornull(p_rid);
_free_render_buffer_data(rb);
@@ -4020,7 +4010,6 @@ bool RasterizerSceneRD::free(RID p_rid) {
sky_owner.free(p_rid);
} else if (light_instance_owner.owns(p_rid)) {
-
LightInstance *light_instance = light_instance_owner.getornull(p_rid);
//remove from shadow atlases..
@@ -4038,7 +4027,6 @@ bool RasterizerSceneRD::free(RID p_rid) {
light_instance_owner.free(p_rid);
} else if (shadow_atlas_owner.owns(p_rid)) {
-
shadow_atlas_set_size(p_rid, 0);
shadow_atlas_owner.free(p_rid);
@@ -4075,6 +4063,97 @@ float RasterizerSceneRD::screen_space_roughness_limiter_get_curve() const {
return screen_space_roughness_limiter_curve;
}
+TypedArray<Image> RasterizerSceneRD::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ tf.width = p_image_size.width; // Always 64x64
+ tf.height = p_image_size.height;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+
+ RID albedo_alpha_tex = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RID normal_tex = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ RID orm_tex = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ RID emission_tex = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ tf.format = RD::DATA_FORMAT_R32_SFLOAT;
+ RID depth_write_tex = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+ tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D32_SFLOAT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D32_SFLOAT : RD::DATA_FORMAT_X8_D24_UNORM_PACK32;
+ RID depth_tex = RD::get_singleton()->texture_create(tf, RD::TextureView());
+
+ Vector<RID> fb_tex;
+ fb_tex.push_back(albedo_alpha_tex);
+ fb_tex.push_back(normal_tex);
+ fb_tex.push_back(orm_tex);
+ fb_tex.push_back(emission_tex);
+ fb_tex.push_back(depth_write_tex);
+ fb_tex.push_back(depth_tex);
+
+ RID fb = RD::get_singleton()->framebuffer_create(fb_tex);
+
+ //RID sampled_light;
+
+ InstanceBase ins;
+
+ ins.base_type = RSG::storage->get_base_type(p_base);
+ ins.base = p_base;
+ ins.materials.resize(RSG::storage->mesh_get_surface_count(p_base));
+ for (int i = 0; i < ins.materials.size(); i++) {
+ if (i < p_material_overrides.size()) {
+ ins.materials.write[i] = p_material_overrides[i];
+ }
+ }
+
+ InstanceBase *cull = &ins;
+ _render_uv2(&cull, 1, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height));
+
+ TypedArray<Image> ret;
+
+ {
+ PackedByteArray data = RD::get_singleton()->texture_get_data(albedo_alpha_tex, 0);
+ Ref<Image> img;
+ img.instance();
+ img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data);
+ RD::get_singleton()->free(albedo_alpha_tex);
+ ret.push_back(img);
+ }
+
+ {
+ PackedByteArray data = RD::get_singleton()->texture_get_data(normal_tex, 0);
+ Ref<Image> img;
+ img.instance();
+ img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data);
+ RD::get_singleton()->free(normal_tex);
+ ret.push_back(img);
+ }
+
+ {
+ PackedByteArray data = RD::get_singleton()->texture_get_data(orm_tex, 0);
+ Ref<Image> img;
+ img.instance();
+ img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBA8, data);
+ RD::get_singleton()->free(orm_tex);
+ ret.push_back(img);
+ }
+
+ {
+ PackedByteArray data = RD::get_singleton()->texture_get_data(emission_tex, 0);
+ Ref<Image> img;
+ img.instance();
+ img->create(p_image_size.width, p_image_size.height, false, Image::FORMAT_RGBAH, data);
+ RD::get_singleton()->free(emission_tex);
+ ret.push_back(img);
+ }
+
+ RD::get_singleton()->free(depth_write_tex);
+ RD::get_singleton()->free(depth_tex);
+
+ return ret;
+}
+
RasterizerSceneRD *RasterizerSceneRD::singleton = nullptr;
RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
@@ -4089,7 +4168,6 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
{
-
//kinda complicated to compute the amount of slots, we try to use as many as we can
gi_probe_max_lights = 32;
@@ -4144,7 +4222,6 @@ RasterizerSceneRD::RasterizerSceneRD(RasterizerStorageRD *p_storage) {
}
{
-
String defines;
if (gi_probe_use_anisotropy) {
defines += "\n#define USE_ANISOTROPY\n";
diff --git a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
index a511838e16..781dbd50cc 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_scene_rd.h
@@ -52,7 +52,6 @@ protected:
// Skys need less info from Directional Lights than the normal shaders
struct SkyDirectionalLightData {
-
float direction[3];
float energy;
float color[3];
@@ -62,7 +61,6 @@ protected:
};
struct SkySceneState {
-
SkyDirectionalLightData *directional_lights;
SkyDirectionalLightData *last_frame_directional_lights;
uint32_t max_directional_lights;
@@ -74,15 +72,15 @@ protected:
} sky_scene_state;
struct RenderBufferData {
-
virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) = 0;
virtual ~RenderBufferData() {}
};
virtual RenderBufferData *_create_render_buffer_data() = 0;
- virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color) = 0;
+ virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color) = 0;
virtual void _render_shadow(RID p_framebuffer, InstanceBase **p_cull_result, int p_cull_count, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake) = 0;
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0;
+ virtual void _render_uv2(InstanceBase **p_cull_result, int p_cull_count, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
@@ -111,7 +109,6 @@ private:
RasterizerStorageRD *storage;
struct ReflectionData {
-
struct Layer {
struct Mipmap {
RID framebuffers[6];
@@ -286,7 +283,6 @@ private:
/* REFLECTION ATLAS */
struct ReflectionAtlas {
-
int count = 0;
int size = 0;
@@ -308,7 +304,6 @@ private:
/* REFLECTION PROBE INSTANCE */
struct ReflectionProbeInstance {
-
RID probe;
int atlas_index = -1;
RID atlas;
@@ -330,7 +325,6 @@ private:
/* REFLECTION PROBE INSTANCE */
struct DecalInstance {
-
RID decal;
Transform transform;
};
@@ -340,7 +334,6 @@ private:
/* GIPROBE INSTANCE */
struct GIProbeLight {
-
uint32_t type;
float energy;
float radius;
@@ -357,7 +350,6 @@ private:
};
struct GIProbePushConstant {
-
int32_t limits[3];
uint32_t stack_size;
@@ -373,7 +365,6 @@ private:
};
struct GIProbeDynamicPushConstant {
-
int32_t limits[3];
uint32_t light_count;
int32_t x_dir[3];
@@ -395,7 +386,6 @@ private:
};
struct GIProbeInstance {
-
RID probe;
RID texture;
RID anisotropy[2]; //only if anisotropy is used
@@ -495,7 +485,6 @@ private:
/* SHADOW ATLAS */
struct ShadowAtlas {
-
enum {
QUADRANT_SHIFT = 27,
SHADOW_INDEX_MASK = (1 << QUADRANT_SHIFT) - 1,
@@ -503,7 +492,6 @@ private:
};
struct Quadrant {
-
uint32_t subdivision;
struct Shadow {
@@ -567,7 +555,6 @@ private:
/* SHADOW CUBEMAPS */
struct ShadowCubemap {
-
RID cubemap;
RID side_fb[6];
};
@@ -588,9 +575,7 @@ private:
/* LIGHT INSTANCE */
struct LightInstance {
-
struct ShadowTransform {
-
CameraMatrix camera;
Transform transform;
float farplane;
@@ -637,7 +622,6 @@ private:
/* ENVIRONMENT */
struct Environent {
-
// BG
RS::EnvironmentBG background = RS::ENV_BG_CLEAR_COLOR;
RID sky;
@@ -710,7 +694,6 @@ private:
/* CAMERA EFFECTS */
struct CameraEffects {
-
bool dof_blur_far_enabled = false;
float dof_blur_far_distance = 10;
float dof_blur_far_transition = 5;
@@ -737,7 +720,6 @@ private:
/* RENDER BUFFERS */
struct RenderBuffers {
-
RenderBufferData *data = nullptr;
int width = 0, height = 0;
RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED;
@@ -766,7 +748,6 @@ private:
Blur blur[2]; //the second one starts from the first mipmap
struct Luminance {
-
Vector<RID> reduce;
RID current;
} luminance;
@@ -843,6 +824,7 @@ public:
void sky_set_radiance_size(RID p_sky, int p_radiance_size);
void sky_set_mode(RID p_sky, RS::SkyMode p_mode);
void sky_set_material(RID p_sky, RID p_material);
+ Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size);
RID sky_get_radiance_texture_rd(RID p_sky) const;
RID sky_get_radiance_uniform_set_rd(RID p_sky, RID p_shader, int p_set) const;
@@ -900,6 +882,8 @@ public:
void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) {}
void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {}
+ virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size);
+
virtual RID camera_effects_create();
virtual void camera_effects_set_dof_blur_quality(RS::DOFBlurQuality p_quality, bool p_use_jitter);
@@ -924,7 +908,6 @@ public:
}
_FORCE_INLINE_ Rect2 light_instance_get_shadow_atlas_rect(RID p_light_instance, RID p_shadow_atlas) {
-
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
LightInstance *li = light_instance_owner.getornull(p_light_instance);
uint32_t key = shadow_atlas->shadow_owners[li->self];
@@ -951,13 +934,11 @@ public:
}
_FORCE_INLINE_ CameraMatrix light_instance_get_shadow_camera(RID p_light_instance, int p_index) {
-
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->shadow_transform[p_index].camera;
}
_FORCE_INLINE_ float light_instance_get_shadow_texel_size(RID p_light_instance, RID p_shadow_atlas) {
-
#ifdef DEBUG_ENABLED
LightInstance *li = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND_V(!li->shadow_atlases.has(p_shadow_atlas), 0);
@@ -980,46 +961,38 @@ public:
_FORCE_INLINE_ Transform
light_instance_get_shadow_transform(RID p_light_instance, int p_index) {
-
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->shadow_transform[p_index].transform;
}
_FORCE_INLINE_ float light_instance_get_shadow_bias_scale(RID p_light_instance, int p_index) {
-
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->shadow_transform[p_index].bias_scale;
}
_FORCE_INLINE_ float light_instance_get_shadow_range(RID p_light_instance, int p_index) {
-
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->shadow_transform[p_index].farplane;
}
_FORCE_INLINE_ float light_instance_get_shadow_range_begin(RID p_light_instance, int p_index) {
-
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->shadow_transform[p_index].range_begin;
}
_FORCE_INLINE_ Vector2 light_instance_get_shadow_uv_scale(RID p_light_instance, int p_index) {
-
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->shadow_transform[p_index].uv_scale;
}
_FORCE_INLINE_ Rect2 light_instance_get_directional_shadow_atlas_rect(RID p_light_instance, int p_index) {
-
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->shadow_transform[p_index].atlas_rect;
}
_FORCE_INLINE_ float light_instance_get_directional_shadow_split(RID p_light_instance, int p_index) {
-
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->shadow_transform[p_index].split;
}
_FORCE_INLINE_ float light_instance_get_directional_shadow_texel_size(RID p_light_instance, int p_index) {
-
LightInstance *li = light_instance_owner.getornull(p_light_instance);
return li->shadow_transform[p_index].shadow_texel_size;
}
@@ -1194,7 +1167,7 @@ public:
RID render_buffers_get_ao_texture(RID p_render_buffers);
RID render_buffers_get_back_buffer_texture(RID p_render_buffers);
- void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
+ void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID *p_gi_probe_cull_result, int p_gi_probe_cull_count, RID *p_decal_cull_result, int p_decal_cull_count, InstanceBase **p_lightmap_cull_result, int p_lightmap_cull_count, RID p_environment, RID p_shadow_atlas, RID p_camera_effects, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass);
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
@@ -1235,6 +1208,8 @@ public:
int get_roughness_layers() const;
bool is_using_radiance_cubemap_array() const;
+ virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size);
+
virtual bool free(RID p_rid);
virtual void update();
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
index 97ef604dd2..4f216d7cb5 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.cpp
@@ -36,7 +36,6 @@
#include "servers/rendering/shader_language.h"
Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_image, TextureToRDFormat &r_format) {
-
Ref<Image> image = p_image->duplicate();
switch (p_image->get_format()) {
@@ -131,7 +130,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
image->convert(Image::FORMAT_RGBAF);
}
- r_format.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
@@ -171,7 +169,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
image->convert(Image::FORMAT_RGBAH);
}
- r_format.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
r_format.swizzle_r = RD::TEXTURE_SWIZZLE_R;
r_format.swizzle_g = RD::TEXTURE_SWIZZLE_G;
r_format.swizzle_b = RD::TEXTURE_SWIZZLE_B;
@@ -405,7 +402,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
} break; //etc2
case Image::FORMAT_ETC2_R11S: {
-
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_EAC_R11_SNORM_BLOCK;
} else {
@@ -483,7 +479,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
} break;
case Image::FORMAT_ETC2_RGB8A1: {
-
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK;
r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK;
@@ -500,7 +495,6 @@ Ref<Image> RasterizerStorageRD::_validate_texture_format(const Ref<Image> &p_ima
r_format.swizzle_a = RD::TEXTURE_SWIZZLE_A;
} break;
case Image::FORMAT_ETC2_RA_AS_RG: {
-
if (RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT)) {
r_format.format = RD::DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK;
r_format.format_srgb = RD::DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK;
@@ -611,11 +605,116 @@ RID RasterizerStorageRD::texture_2d_create(const Ref<Image> &p_image) {
}
RID RasterizerStorageRD::texture_2d_layered_create(const Vector<Ref<Image>> &p_layers, RS::TextureLayeredType p_layered_type) {
+ ERR_FAIL_COND_V(p_layers.size() == 0, RID());
- return RID();
+ ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP && p_layers.size() != 6, RID());
+ ERR_FAIL_COND_V(p_layered_type == RS::TEXTURE_LAYERED_CUBEMAP_ARRAY && (p_layers.size() < 6 || (p_layers.size() % 6) != 0), RID());
+
+ TextureToRDFormat ret_format;
+ Vector<Ref<Image>> images;
+ {
+ int valid_width = 0;
+ int valid_height = 0;
+ bool valid_mipmaps = false;
+ Image::Format valid_format = Image::FORMAT_MAX;
+
+ for (int i = 0; i < p_layers.size(); i++) {
+ ERR_FAIL_COND_V(p_layers[i]->empty(), RID());
+
+ if (i == 0) {
+ valid_width = p_layers[i]->get_width();
+ valid_height = p_layers[i]->get_height();
+ valid_format = p_layers[i]->get_format();
+ valid_mipmaps = p_layers[i]->has_mipmaps();
+ } else {
+ ERR_FAIL_COND_V(p_layers[i]->get_width() != valid_width, RID());
+ ERR_FAIL_COND_V(p_layers[i]->get_height() != valid_height, RID());
+ ERR_FAIL_COND_V(p_layers[i]->get_format() != valid_format, RID());
+ ERR_FAIL_COND_V(p_layers[i]->has_mipmaps() != valid_mipmaps, RID());
+ }
+
+ images.push_back(_validate_texture_format(p_layers[i], ret_format));
+ }
+ }
+
+ Texture texture;
+
+ texture.type = Texture::TYPE_LAYERED;
+ texture.layered_type = p_layered_type;
+
+ texture.width = p_layers[0]->get_width();
+ texture.height = p_layers[0]->get_height();
+ texture.layers = p_layers.size();
+ texture.mipmaps = p_layers[0]->get_mipmap_count() + 1;
+ texture.depth = 1;
+ texture.format = p_layers[0]->get_format();
+ texture.validated_format = images[0]->get_format();
+
+ switch (p_layered_type) {
+ case RS::TEXTURE_LAYERED_2D_ARRAY: {
+ texture.rd_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ } break;
+ case RS::TEXTURE_LAYERED_CUBEMAP: {
+ texture.rd_type = RD::TEXTURE_TYPE_CUBE;
+ } break;
+ case RS::TEXTURE_LAYERED_CUBEMAP_ARRAY: {
+ texture.rd_type = RD::TEXTURE_TYPE_CUBE_ARRAY;
+ } break;
+ }
+
+ texture.rd_format = ret_format.format;
+ texture.rd_format_srgb = ret_format.format_srgb;
+
+ RD::TextureFormat rd_format;
+ RD::TextureView rd_view;
+ { //attempt register
+ rd_format.format = texture.rd_format;
+ rd_format.width = texture.width;
+ rd_format.height = texture.height;
+ rd_format.depth = 1;
+ rd_format.array_layers = texture.layers;
+ rd_format.mipmaps = texture.mipmaps;
+ rd_format.type = texture.rd_type;
+ rd_format.samples = RD::TEXTURE_SAMPLES_1;
+ rd_format.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+ if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
+ rd_format.shareable_formats.push_back(texture.rd_format);
+ rd_format.shareable_formats.push_back(texture.rd_format_srgb);
+ }
+ }
+ {
+ rd_view.swizzle_r = ret_format.swizzle_r;
+ rd_view.swizzle_g = ret_format.swizzle_g;
+ rd_view.swizzle_b = ret_format.swizzle_b;
+ rd_view.swizzle_a = ret_format.swizzle_a;
+ }
+ Vector<Vector<uint8_t>> data_slices;
+ for (int i = 0; i < images.size(); i++) {
+ Vector<uint8_t> data = images[i]->get_data(); //use image data
+ data_slices.push_back(data);
+ }
+ texture.rd_texture = RD::get_singleton()->texture_create(rd_format, rd_view, data_slices);
+ ERR_FAIL_COND_V(texture.rd_texture.is_null(), RID());
+ if (texture.rd_format_srgb != RD::DATA_FORMAT_MAX) {
+ rd_view.format_override = texture.rd_format_srgb;
+ texture.rd_texture_srgb = RD::get_singleton()->texture_create_shared(rd_view, texture.rd_texture);
+ if (texture.rd_texture_srgb.is_null()) {
+ RD::get_singleton()->free(texture.rd_texture);
+ ERR_FAIL_COND_V(texture.rd_texture_srgb.is_null(), RID());
+ }
+ }
+
+ //used for 2D, overridable
+ texture.width_2d = texture.width;
+ texture.height_2d = texture.height;
+ texture.is_render_target = false;
+ texture.rd_view = rd_view;
+ texture.is_proxy = false;
+
+ return texture_owner.make_rid(texture);
}
-RID RasterizerStorageRD::texture_3d_create(const Vector<Ref<Image>> &p_slices) {
+RID RasterizerStorageRD::texture_3d_create(const Vector<Ref<Image>> &p_slices) {
return RID();
}
@@ -643,7 +742,6 @@ RID RasterizerStorageRD::texture_proxy_create(RID p_base) {
}
void RasterizerStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer, bool p_immediate) {
-
ERR_FAIL_COND(p_image.is_null() || p_image->empty());
Texture *tex = texture_owner.getornull(p_texture);
@@ -668,14 +766,15 @@ void RasterizerStorageRD::_texture_2d_update(RID p_texture, const Ref<Image> &p_
void RasterizerStorageRD::texture_2d_update_immediate(RID p_texture, const Ref<Image> &p_image, int p_layer) {
_texture_2d_update(p_texture, p_image, p_layer, true);
}
+
void RasterizerStorageRD::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {
_texture_2d_update(p_texture, p_image, p_layer, false);
}
+
void RasterizerStorageRD::texture_3d_update(RID p_texture, const Ref<Image> &p_image, int p_depth, int p_mipmap) {
}
void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) {
-
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
ERR_FAIL_COND(!tex->is_proxy);
@@ -716,7 +815,6 @@ void RasterizerStorageRD::texture_proxy_update(RID p_texture, RID p_proxy_to) {
//these two APIs can be used together or in combination with the others.
RID RasterizerStorageRD::texture_2d_placeholder_create() {
-
//this could be better optimized to reuse an existing image , done this way
//for now to get it working
Ref<Image> image;
@@ -731,17 +829,38 @@ RID RasterizerStorageRD::texture_2d_placeholder_create() {
return texture_2d_create(image);
}
-RID RasterizerStorageRD::texture_2d_layered_placeholder_create() {
- return RID();
+RID RasterizerStorageRD::texture_2d_layered_placeholder_create(RS::TextureLayeredType p_layered_type) {
+ //this could be better optimized to reuse an existing image , done this way
+ //for now to get it working
+ Ref<Image> image;
+ image.instance();
+ image->create(4, 4, false, Image::FORMAT_RGBA8);
+
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ image->set_pixel(i, j, Color(1, 0, 1, 1));
+ }
+ }
+
+ Vector<Ref<Image>> images;
+ if (p_layered_type == RS::TEXTURE_LAYERED_2D_ARRAY) {
+ images.push_back(image);
+ } else {
+ //cube
+ for (int i = 0; i < 6; i++) {
+ images.push_back(image);
+ }
+ }
+
+ return texture_2d_layered_create(images, p_layered_type);
}
-RID RasterizerStorageRD::texture_3d_placeholder_create() {
+RID RasterizerStorageRD::texture_3d_placeholder_create() {
return RID();
}
Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const {
-
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND_V(!tex, Ref<Image>());
@@ -768,17 +887,16 @@ Ref<Image> RasterizerStorageRD::texture_2d_get(RID p_texture) const {
return image;
}
-Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const {
+Ref<Image> RasterizerStorageRD::texture_2d_layer_get(RID p_texture, int p_layer) const {
return Ref<Image>();
}
-Ref<Image> RasterizerStorageRD::texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const {
+Ref<Image> RasterizerStorageRD::texture_3d_slice_get(RID p_texture, int p_depth, int p_mipmap) const {
return Ref<Image>();
}
void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) {
-
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
ERR_FAIL_COND(tex->proxy_to.is_valid()); //cant replace proxy
@@ -817,6 +935,7 @@ void RasterizerStorageRD::texture_replace(RID p_texture, RID p_by_texture) {
decal_atlas.dirty = true; //mark it dirty since it was most likely modified
}
}
+
void RasterizerStorageRD::texture_set_size_override(RID p_texture, int p_width, int p_height) {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
@@ -830,6 +949,7 @@ void RasterizerStorageRD::texture_set_path(RID p_texture, const String &p_path)
ERR_FAIL_COND(!tex);
tex->path = p_path;
}
+
String RasterizerStorageRD::texture_get_path(RID p_texture) const {
return String();
}
@@ -840,23 +960,27 @@ void RasterizerStorageRD::texture_set_detect_3d_callback(RID p_texture, RS::Text
tex->detect_3d_callback_ud = p_userdata;
tex->detect_3d_callback = p_callback;
}
+
void RasterizerStorageRD::texture_set_detect_normal_callback(RID p_texture, RS::TextureDetectCallback p_callback, void *p_userdata) {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
tex->detect_normal_callback_ud = p_userdata;
tex->detect_normal_callback = p_callback;
}
+
void RasterizerStorageRD::texture_set_detect_roughness_callback(RID p_texture, RS::TextureDetectRoughnessCallback p_callback, void *p_userdata) {
Texture *tex = texture_owner.getornull(p_texture);
ERR_FAIL_COND(!tex);
tex->detect_roughness_callback_ud = p_userdata;
tex->detect_roughness_callback = p_callback;
}
+
void RasterizerStorageRD::texture_debug_usage(List<RS::TextureInfo> *r_info) {
}
void RasterizerStorageRD::texture_set_proxy(RID p_proxy, RID p_base) {
}
+
void RasterizerStorageRD::texture_set_force_redraw_if_visible(RID p_texture, bool p_enable) {
}
@@ -867,7 +991,6 @@ Size2 RasterizerStorageRD::texture_size_with_proxy(RID p_proxy) {
/* SHADER API */
RID RasterizerStorageRD::shader_create() {
-
Shader shader;
shader.data = nullptr;
shader.type = SHADER_TYPE_MAX;
@@ -883,16 +1006,17 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) {
String mode_string = ShaderLanguage::get_shader_type(p_code);
ShaderType new_type;
- if (mode_string == "canvas_item")
+ if (mode_string == "canvas_item") {
new_type = SHADER_TYPE_2D;
- else if (mode_string == "particles")
+ } else if (mode_string == "particles") {
new_type = SHADER_TYPE_PARTICLES;
- else if (mode_string == "spatial")
+ } else if (mode_string == "spatial") {
new_type = SHADER_TYPE_3D;
- else if (mode_string == "sky")
+ } else if (mode_string == "sky") {
new_type = SHADER_TYPE_SKY;
- else
+ } else {
new_type = SHADER_TYPE_MAX;
+ }
if (new_type != shader->type) {
if (shader->data) {
@@ -901,7 +1025,6 @@ void RasterizerStorageRD::shader_set_code(RID p_shader, const String &p_code) {
}
for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) {
-
Material *material = E->get();
material->shader_type = new_type;
if (material->data) {
@@ -946,8 +1069,8 @@ String RasterizerStorageRD::shader_get_code(RID p_shader) const {
ERR_FAIL_COND_V(!shader, String());
return shader->code;
}
-void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
+void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const {
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND(!shader);
if (shader->data) {
@@ -956,7 +1079,6 @@ void RasterizerStorageRD::shader_get_param_list(RID p_shader, List<PropertyInfo>
}
void RasterizerStorageRD::shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) {
-
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND(!shader);
@@ -981,6 +1103,7 @@ RID RasterizerStorageRD::shader_get_default_texture_param(RID p_shader, const St
return RID();
}
+
Variant RasterizerStorageRD::shader_get_param_default(RID p_shader, const StringName &p_param) const {
Shader *shader = shader_owner.getornull(p_shader);
ERR_FAIL_COND_V(!shader, Variant());
@@ -989,6 +1112,7 @@ Variant RasterizerStorageRD::shader_get_param_default(RID p_shader, const String
}
return Variant();
}
+
void RasterizerStorageRD::shader_set_data_request_function(ShaderType p_shader_type, ShaderDataRequestFunction p_function) {
ERR_FAIL_INDEX(p_shader_type, SHADER_TYPE_MAX);
shader_data_request_func[p_shader_type] = p_function;
@@ -997,7 +1121,6 @@ void RasterizerStorageRD::shader_set_data_request_function(ShaderType p_shader_t
/* COMMON MATERIAL API */
RID RasterizerStorageRD::material_create() {
-
Material material;
material.data = nullptr;
material.shader = nullptr;
@@ -1028,7 +1151,6 @@ void RasterizerStorageRD::_material_queue_update(Material *material, bool p_unif
}
void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) {
-
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -1070,7 +1192,6 @@ void RasterizerStorageRD::material_set_shader(RID p_material, RID p_shader) {
}
void RasterizerStorageRD::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
-
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -1113,6 +1234,7 @@ void RasterizerStorageRD::material_set_next_pass(RID p_material, RID p_next_mate
material->instance_dependency.instance_notify_changed(false, true);
}
+
void RasterizerStorageRD::material_set_render_priority(RID p_material, int priority) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
@@ -1134,6 +1256,7 @@ bool RasterizerStorageRD::material_is_animated(RID p_material) {
}
return false; //by default nothing is animated
}
+
bool RasterizerStorageRD::material_casts_shadows(RID p_material) {
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND_V(!material, true);
@@ -1148,7 +1271,6 @@ bool RasterizerStorageRD::material_casts_shadows(RID p_material) {
}
void RasterizerStorageRD::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) {
-
Material *material = material_owner.getornull(p_material);
ERR_FAIL_COND(!material);
if (material->shader && material->shader->data) {
@@ -1177,14 +1299,12 @@ void RasterizerStorageRD::material_set_data_request_function(ShaderType p_shader
_FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataType type, const Variant &value, uint8_t *data, bool p_linear_color) {
switch (type) {
case ShaderLanguage::TYPE_BOOL: {
-
bool v = value;
uint32_t *gui = (uint32_t *)data;
*gui = v ? 1 : 0;
} break;
case ShaderLanguage::TYPE_BVEC2: {
-
int v = value;
uint32_t *gui = (uint32_t *)data;
gui[0] = v & 1 ? 1 : 0;
@@ -1192,7 +1312,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
} break;
case ShaderLanguage::TYPE_BVEC3: {
-
int v = value;
uint32_t *gui = (uint32_t *)data;
gui[0] = (v & 1) ? 1 : 0;
@@ -1201,7 +1320,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
} break;
case ShaderLanguage::TYPE_BVEC4: {
-
int v = value;
uint32_t *gui = (uint32_t *)data;
gui[0] = (v & 1) ? 1 : 0;
@@ -1211,14 +1329,12 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
} break;
case ShaderLanguage::TYPE_INT: {
-
int v = value;
int32_t *gui = (int32_t *)data;
gui[0] = v;
} break;
case ShaderLanguage::TYPE_IVEC2: {
-
Vector<int> iv = value;
int s = iv.size();
int32_t *gui = (int32_t *)data;
@@ -1226,15 +1342,15 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
const int *r = iv.ptr();
for (int i = 0; i < 2; i++) {
- if (i < s)
+ if (i < s) {
gui[i] = r[i];
- else
+ } else {
gui[i] = 0;
+ }
}
} break;
case ShaderLanguage::TYPE_IVEC3: {
-
Vector<int> iv = value;
int s = iv.size();
int32_t *gui = (int32_t *)data;
@@ -1242,14 +1358,14 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
const int *r = iv.ptr();
for (int i = 0; i < 3; i++) {
- if (i < s)
+ if (i < s) {
gui[i] = r[i];
- else
+ } else {
gui[i] = 0;
+ }
}
} break;
case ShaderLanguage::TYPE_IVEC4: {
-
Vector<int> iv = value;
int s = iv.size();
int32_t *gui = (int32_t *)data;
@@ -1257,21 +1373,20 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
const int *r = iv.ptr();
for (int i = 0; i < 4; i++) {
- if (i < s)
+ if (i < s) {
gui[i] = r[i];
- else
+ } else {
gui[i] = 0;
+ }
}
} break;
case ShaderLanguage::TYPE_UINT: {
-
int v = value;
uint32_t *gui = (uint32_t *)data;
gui[0] = v;
} break;
case ShaderLanguage::TYPE_UVEC2: {
-
Vector<int> iv = value;
int s = iv.size();
uint32_t *gui = (uint32_t *)data;
@@ -1279,10 +1394,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
const int *r = iv.ptr();
for (int i = 0; i < 2; i++) {
- if (i < s)
+ if (i < s) {
gui[i] = r[i];
- else
+ } else {
gui[i] = 0;
+ }
}
} break;
case ShaderLanguage::TYPE_UVEC3: {
@@ -1293,10 +1409,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
const int *r = iv.ptr();
for (int i = 0; i < 3; i++) {
- if (i < s)
+ if (i < s) {
gui[i] = r[i];
- else
+ } else {
gui[i] = 0;
+ }
}
} break;
@@ -1308,10 +1425,11 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
const int *r = iv.ptr();
for (int i = 0; i < 4; i++) {
- if (i < s)
+ if (i < s) {
gui[i] = r[i];
- else
+ } else {
gui[i] = 0;
+ }
}
} break;
case ShaderLanguage::TYPE_FLOAT: {
@@ -1336,7 +1454,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
} break;
case ShaderLanguage::TYPE_VEC4: {
-
float *gui = (float *)data;
if (value.get_type() == Variant::COLOR) {
@@ -1388,7 +1505,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[7] = 0;
} break;
case ShaderLanguage::TYPE_MAT3: {
-
Basis v = value;
float *gui = (float *)data;
@@ -1406,7 +1522,6 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
gui[11] = 0;
} break;
case ShaderLanguage::TYPE_MAT4: {
-
Transform v = value;
float *gui = (float *)data;
@@ -1433,22 +1548,18 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
}
_FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type, const Vector<ShaderLanguage::ConstantNode::Value> &value, uint8_t *data) {
-
switch (type) {
case ShaderLanguage::TYPE_BOOL: {
-
uint32_t *gui = (uint32_t *)data;
*gui = value[0].boolean ? 1 : 0;
} break;
case ShaderLanguage::TYPE_BVEC2: {
-
uint32_t *gui = (uint32_t *)data;
gui[0] = value[0].boolean ? 1 : 0;
gui[1] = value[1].boolean ? 1 : 0;
} break;
case ShaderLanguage::TYPE_BVEC3: {
-
uint32_t *gui = (uint32_t *)data;
gui[0] = value[0].boolean ? 1 : 0;
gui[1] = value[1].boolean ? 1 : 0;
@@ -1456,7 +1567,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
} break;
case ShaderLanguage::TYPE_BVEC4: {
-
uint32_t *gui = (uint32_t *)data;
gui[0] = value[0].boolean ? 1 : 0;
gui[1] = value[1].boolean ? 1 : 0;
@@ -1465,13 +1575,11 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
} break;
case ShaderLanguage::TYPE_INT: {
-
int32_t *gui = (int32_t *)data;
gui[0] = value[0].sint;
} break;
case ShaderLanguage::TYPE_IVEC2: {
-
int32_t *gui = (int32_t *)data;
for (int i = 0; i < 2; i++) {
@@ -1480,7 +1588,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
} break;
case ShaderLanguage::TYPE_IVEC3: {
-
int32_t *gui = (int32_t *)data;
for (int i = 0; i < 3; i++) {
@@ -1489,7 +1596,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
} break;
case ShaderLanguage::TYPE_IVEC4: {
-
int32_t *gui = (int32_t *)data;
for (int i = 0; i < 4; i++) {
@@ -1498,13 +1604,11 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
} break;
case ShaderLanguage::TYPE_UINT: {
-
uint32_t *gui = (uint32_t *)data;
gui[0] = value[0].uint;
} break;
case ShaderLanguage::TYPE_UVEC2: {
-
int32_t *gui = (int32_t *)data;
for (int i = 0; i < 2; i++) {
@@ -1527,13 +1631,11 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
}
} break;
case ShaderLanguage::TYPE_FLOAT: {
-
float *gui = (float *)data;
gui[0] = value[0].real;
} break;
case ShaderLanguage::TYPE_VEC2: {
-
float *gui = (float *)data;
for (int i = 0; i < 2; i++) {
@@ -1542,7 +1644,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
} break;
case ShaderLanguage::TYPE_VEC3: {
-
float *gui = (float *)data;
for (int i = 0; i < 3; i++) {
@@ -1551,7 +1652,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
} break;
case ShaderLanguage::TYPE_VEC4: {
-
float *gui = (float *)data;
for (int i = 0; i < 4; i++) {
@@ -1572,7 +1672,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
gui[7] = 0;
} break;
case ShaderLanguage::TYPE_MAT3: {
-
float *gui = (float *)data;
gui[0] = value[0].real;
@@ -1589,7 +1688,6 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
gui[11] = 0;
} break;
case ShaderLanguage::TYPE_MAT4: {
-
float *gui = (float *)data;
for (int i = 0; i < 16; i++) {
@@ -1602,9 +1700,7 @@ _FORCE_INLINE_ static void _fill_std140_ubo_value(ShaderLanguage::DataType type,
}
_FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, uint8_t *data) {
-
switch (type) {
-
case ShaderLanguage::TYPE_BOOL:
case ShaderLanguage::TYPE_INT:
case ShaderLanguage::TYPE_UINT:
@@ -1625,15 +1721,12 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type,
case ShaderLanguage::TYPE_IVEC4:
case ShaderLanguage::TYPE_UVEC4:
case ShaderLanguage::TYPE_VEC4: {
-
zeromem(data, 16);
} break;
case ShaderLanguage::TYPE_MAT2: {
-
zeromem(data, 32);
} break;
case ShaderLanguage::TYPE_MAT3: {
-
zeromem(data, 48);
} break;
case ShaderLanguage::TYPE_MAT4: {
@@ -1646,13 +1739,12 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type,
}
void RasterizerStorageRD::MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) {
-
bool uses_global_buffer = false;
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = p_uniforms.front(); E; E = E->next()) {
-
- if (E->get().order < 0)
+ if (E->get().order < 0) {
continue; // texture, does not go here
+ }
if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue; //instance uniforms don't appear in the bufferr
@@ -1740,7 +1832,6 @@ RasterizerStorageRD::MaterialData::~MaterialData() {
}
void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) {
-
RasterizerStorageRD *singleton = (RasterizerStorageRD *)RasterizerStorage::base_singleton;
#ifdef TOOLS_ENABLED
Texture *roughness_detect_texture = nullptr;
@@ -1752,13 +1843,11 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
global_textures_pass++;
for (int i = 0; i < p_texture_uniforms.size(); i++) {
-
const StringName &uniform_name = p_texture_uniforms[i].name;
RID texture;
if (p_texture_uniforms[i].global) {
-
RasterizerStorageRD *rs = base_singleton;
uses_global_textures = true;
@@ -1769,7 +1858,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!.");
} else {
-
Map<StringName, uint64_t>::Element *E = used_global_textures.find(uniform_name);
if (!E) {
E = used_global_textures.insert(uniform_name, global_textures_pass);
@@ -1786,7 +1874,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
}
} else {
if (!texture.is_valid()) {
-
const Map<StringName, Variant>::Element *V = p_parameters.find(uniform_name);
if (V) {
texture = V->get();
@@ -1796,7 +1883,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
if (!texture.is_valid()) {
const Map<StringName, RID>::Element *W = p_default_textures.find(uniform_name);
if (W) {
-
texture = W->get();
}
}
@@ -1827,7 +1913,6 @@ void RasterizerStorageRD::MaterialData::update_textures(const Map<StringName, Va
Texture *tex = singleton->texture_owner.getornull(texture);
if (tex) {
-
rd_texture = (srgb && tex->rd_texture_srgb.is_valid()) ? tex->rd_texture_srgb : tex->rd_texture;
#ifdef TOOLS_ENABLED
if (tex->detect_3d_callback && p_use_linear_color) {
@@ -1919,16 +2004,15 @@ void RasterizerStorageRD::_update_queued_materials() {
}
material_update_list = nullptr;
}
+
/* MESH API */
RID RasterizerStorageRD::mesh_create() {
-
return mesh_owner.make_rid(Mesh());
}
/// Returns stride
void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) {
-
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
@@ -1939,17 +2023,12 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
#ifdef DEBUG_ENABLED
//do a validation, to catch errors first
{
-
uint32_t stride = 0;
for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {
-
if ((p_surface.format & (1 << i))) {
-
switch (i) {
-
case RS::ARRAY_VERTEX: {
-
if (p_surface.format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
stride += sizeof(float) * 2;
} else {
@@ -1958,7 +2037,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
} break;
case RS::ARRAY_NORMAL: {
-
if (p_surface.format & RS::ARRAY_COMPRESS_NORMAL) {
stride += sizeof(int8_t) * 4;
} else {
@@ -1967,7 +2045,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
} break;
case RS::ARRAY_TANGENT: {
-
if (p_surface.format & RS::ARRAY_COMPRESS_TANGENT) {
stride += sizeof(int8_t) * 4;
} else {
@@ -1976,7 +2053,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
} break;
case RS::ARRAY_COLOR: {
-
if (p_surface.format & RS::ARRAY_COMPRESS_COLOR) {
stride += sizeof(int8_t) * 4;
} else {
@@ -1985,7 +2061,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
} break;
case RS::ARRAY_TEX_UV: {
-
if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV) {
stride += sizeof(int16_t) * 2;
} else {
@@ -1994,7 +2069,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
} break;
case RS::ARRAY_TEX_UV2: {
-
if (p_surface.format & RS::ARRAY_COMPRESS_TEX_UV2) {
stride += sizeof(int16_t) * 2;
} else {
@@ -2039,7 +2113,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
s->lod_count = p_surface.lods.size();
for (int i = 0; i < p_surface.lods.size(); i++) {
-
uint32_t indices = p_surface.lods[i].index_data.size() / (is_index_16 ? 2 : 4);
s->lods[i].index_buffer = RD::get_singleton()->index_buffer_create(indices, is_index_16 ? RD::INDEX_BUFFER_FORMAT_UINT16 : RD::INDEX_BUFFER_FORMAT_UINT32, p_surface.lods[i].index_data);
s->lods[i].index_array = RD::get_singleton()->index_array_create(s->lods[i].index_buffer, 0, indices);
@@ -2052,7 +2125,6 @@ void RasterizerStorageRD::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_
s->bone_aabbs = p_surface.bone_aabbs; //only really useful for returning them.
for (int i = 0; i < p_surface.blend_shapes.size(); i++) {
-
if (p_surface.blend_shapes[i].size() != p_surface.vertex_data.size()) {
memdelete(s);
ERR_FAIL_COND(p_surface.blend_shapes[i].size() != p_surface.vertex_data.size());
@@ -2097,6 +2169,7 @@ void RasterizerStorageRD::mesh_set_blend_shape_mode(RID p_mesh, RS::BlendShapeMo
mesh->blend_shape_mode = p_mode;
}
+
RS::BlendShapeMode RasterizerStorageRD::mesh_get_blend_shape_mode(RID p_mesh) const {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, RS::BLEND_SHAPE_MODE_NORMALIZED);
@@ -2123,6 +2196,7 @@ void RasterizerStorageRD::mesh_surface_set_material(RID p_mesh, int p_surface, R
mesh->instance_dependency.instance_notify_changed(false, true);
mesh->material_cache.clear();
}
+
RID RasterizerStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) const {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, RID());
@@ -2132,7 +2206,6 @@ RID RasterizerStorageRD::mesh_surface_get_material(RID p_mesh, int p_surface) co
}
RS::SurfaceData RasterizerStorageRD::mesh_get_surface(RID p_mesh, int p_surface) const {
-
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, RS::SurfaceData());
ERR_FAIL_UNSIGNED_INDEX_V((uint32_t)p_surface, mesh->surface_count, RS::SurfaceData());
@@ -2178,6 +2251,7 @@ void RasterizerStorageRD::mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) {
ERR_FAIL_COND(!mesh);
mesh->custom_aabb = p_aabb;
}
+
AABB RasterizerStorageRD::mesh_get_custom_aabb(RID p_mesh) const {
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND_V(!mesh, AABB());
@@ -2201,10 +2275,8 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
AABB aabb;
for (uint32_t i = 0; i < mesh->surface_count; i++) {
-
AABB laabb;
if ((mesh->surfaces[i]->format & RS::ARRAY_FORMAT_BONES) && mesh->surfaces[i]->bone_aabbs.size()) {
-
int bs = mesh->surfaces[i]->bone_aabbs.size();
const AABB *skbones = mesh->surfaces[i]->bone_aabbs.ptr();
@@ -2216,9 +2288,9 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
if (skeleton->use_2d) {
for (int j = 0; j < bs; j++) {
-
- if (skbones[0].size == Vector3())
+ if (skbones[0].size == Vector3()) {
continue; //bone is unused
+ }
const float *dataptr = baseptr + j * 8;
@@ -2243,9 +2315,9 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
}
} else {
for (int j = 0; j < bs; j++) {
-
- if (skbones[0].size == Vector3())
+ if (skbones[0].size == Vector3()) {
continue; //bone is unused
+ }
const float *dataptr = baseptr + j * 12;
@@ -2278,7 +2350,6 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
laabb = mesh->surfaces[i]->aabb;
}
} else {
-
laabb = mesh->surfaces[i]->aabb;
}
@@ -2293,7 +2364,6 @@ AABB RasterizerStorageRD::mesh_get_aabb(RID p_mesh, RID p_skeleton) {
}
void RasterizerStorageRD::mesh_clear(RID p_mesh) {
-
Mesh *mesh = mesh_owner.getornull(p_mesh);
ERR_FAIL_COND(!mesh);
for (uint32_t i = 0; i < mesh->surface_count; i++) {
@@ -2341,14 +2411,13 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
Mesh::Surface::Version &v = s->versions[version];
- Vector<RD::VertexDescription> attributes;
+ Vector<RD::VertexAttribute> attributes;
Vector<RID> buffers;
uint32_t stride = 0;
for (int i = 0; i < RS::ARRAY_WEIGHTS; i++) {
-
- RD::VertexDescription vd;
+ RD::VertexAttribute vd;
RID buffer;
vd.location = i;
@@ -2356,9 +2425,7 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
// Not supplied by surface, use default value
buffer = mesh_default_rd_buffers[i];
switch (i) {
-
case RS::ARRAY_VERTEX: {
-
vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
} break;
@@ -2366,25 +2433,20 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
vd.format = RD::DATA_FORMAT_R32G32B32_SFLOAT;
} break;
case RS::ARRAY_TANGENT: {
-
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
} break;
case RS::ARRAY_COLOR: {
-
vd.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT;
} break;
case RS::ARRAY_TEX_UV: {
-
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
} break;
case RS::ARRAY_TEX_UV2: {
-
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
} break;
case RS::ARRAY_BONES: {
-
//assumed weights too
vd.format = RD::DATA_FORMAT_R32G32B32A32_UINT;
} break;
@@ -2397,9 +2459,7 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
buffer = s->vertex_buffer;
switch (i) {
-
case RS::ARRAY_VERTEX: {
-
if (s->format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
vd.format = RD::DATA_FORMAT_R32G32_SFLOAT;
stride += sizeof(float) * 2;
@@ -2410,7 +2470,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
} break;
case RS::ARRAY_NORMAL: {
-
if (s->format & RS::ARRAY_COMPRESS_NORMAL) {
vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM;
stride += sizeof(int8_t) * 4;
@@ -2421,7 +2480,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
} break;
case RS::ARRAY_TANGENT: {
-
if (s->format & RS::ARRAY_COMPRESS_TANGENT) {
vd.format = RD::DATA_FORMAT_R8G8B8A8_SNORM;
stride += sizeof(int8_t) * 4;
@@ -2432,7 +2490,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
} break;
case RS::ARRAY_COLOR: {
-
if (s->format & RS::ARRAY_COMPRESS_COLOR) {
vd.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
stride += sizeof(int8_t) * 4;
@@ -2443,7 +2500,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
} break;
case RS::ARRAY_TEX_UV: {
-
if (s->format & RS::ARRAY_COMPRESS_TEX_UV) {
vd.format = RD::DATA_FORMAT_R16G16_SFLOAT;
stride += sizeof(int16_t) * 2;
@@ -2454,7 +2510,6 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
} break;
case RS::ARRAY_TEX_UV2: {
-
if (s->format & RS::ARRAY_COMPRESS_TEX_UV2) {
vd.format = RD::DATA_FORMAT_R16G16_SFLOAT;
stride += sizeof(int16_t) * 2;
@@ -2499,12 +2554,10 @@ void RasterizerStorageRD::_mesh_surface_generate_version_for_input_mask(Mesh::Su
////////////////// MULTIMESH
RID RasterizerStorageRD::multimesh_create() {
-
return multimesh_owner.make_rid(MultiMesh());
}
void RasterizerStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, RS::MultimeshTransformFormat p_transform_format, bool p_use_colors, bool p_use_custom_data) {
-
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
@@ -2540,7 +2593,6 @@ void RasterizerStorageRD::multimesh_allocate(RID p_multimesh, int p_instances, R
multimesh->visible_instances = MIN(multimesh->visible_instances, multimesh->instances);
if (multimesh->instances) {
-
multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache * 4);
}
}
@@ -2595,7 +2647,6 @@ void RasterizerStorageRD::_multimesh_make_local(MultiMesh *multimesh) const {
if (multimesh->buffer_set) {
Vector<uint8_t> buffer = RD::get_singleton()->buffer_get_data(multimesh->buffer);
{
-
const uint8_t *r = buffer.ptr();
copymem(w, r, buffer.size());
}
@@ -2606,13 +2657,12 @@ void RasterizerStorageRD::_multimesh_make_local(MultiMesh *multimesh) const {
uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
multimesh->data_cache_dirty_regions = memnew_arr(bool, data_cache_dirty_region_count);
for (uint32_t i = 0; i < data_cache_dirty_region_count; i++) {
- multimesh->data_cache_dirty_regions[i] = 0;
+ multimesh->data_cache_dirty_regions[i] = false;
}
multimesh->data_cache_used_dirty_regions = 0;
}
void RasterizerStorageRD::_multimesh_mark_dirty(MultiMesh *multimesh, int p_index, bool p_aabb) {
-
uint32_t region_index = p_index / MULTIMESH_DIRTY_REGION_SIZE;
#ifdef DEBUG_ENABLED
uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
@@ -2658,7 +2708,6 @@ void RasterizerStorageRD::_multimesh_mark_all_dirty(MultiMesh *multimesh, bool p
}
void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const float *p_data, int p_instances) {
-
ERR_FAIL_COND(multimesh->mesh.is_null());
AABB aabb;
AABB mesh_aabb = mesh_get_aabb(multimesh->mesh);
@@ -2667,7 +2716,6 @@ void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const
Transform t;
if (multimesh->xform_format == RS::MULTIMESH_TRANSFORM_3D) {
-
t.basis.elements[0][0] = data[0];
t.basis.elements[0][1] = data[1];
t.basis.elements[0][2] = data[2];
@@ -2682,7 +2730,6 @@ void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const
t.origin.z = data[11];
} else {
-
t.basis.elements[0].x = data[0];
t.basis.elements[1].x = data[1];
t.origin.x = data[3];
@@ -2703,7 +2750,6 @@ void RasterizerStorageRD::_multimesh_re_create_aabb(MultiMesh *multimesh, const
}
void RasterizerStorageRD::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {
-
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
ERR_FAIL_INDEX(p_index, multimesh->instances);
@@ -2734,7 +2780,6 @@ void RasterizerStorageRD::multimesh_instance_set_transform(RID p_multimesh, int
}
void RasterizerStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) {
-
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
ERR_FAIL_INDEX(p_index, multimesh->instances);
@@ -2759,8 +2804,8 @@ void RasterizerStorageRD::multimesh_instance_set_transform_2d(RID p_multimesh, i
_multimesh_mark_dirty(multimesh, p_index, true);
}
-void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
+void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
ERR_FAIL_INDEX(p_index, multimesh->instances);
@@ -2781,6 +2826,7 @@ void RasterizerStorageRD::multimesh_instance_set_color(RID p_multimesh, int p_in
_multimesh_mark_dirty(multimesh, p_index, false);
}
+
void RasterizerStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, int p_index, const Color &p_color) {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
@@ -2804,7 +2850,6 @@ void RasterizerStorageRD::multimesh_instance_set_custom_data(RID p_multimesh, in
}
RID RasterizerStorageRD::multimesh_get_mesh(RID p_multimesh) const {
-
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, RID());
@@ -2812,7 +2857,6 @@ RID RasterizerStorageRD::multimesh_get_mesh(RID p_multimesh) const {
}
Transform RasterizerStorageRD::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
-
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, Transform());
ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform());
@@ -2842,8 +2886,8 @@ Transform RasterizerStorageRD::multimesh_instance_get_transform(RID p_multimesh,
return t;
}
-Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const {
+Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multimesh, int p_index) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, Transform2D());
ERR_FAIL_INDEX_V(p_index, multimesh->instances, Transform2D());
@@ -2867,8 +2911,8 @@ Transform2D RasterizerStorageRD::multimesh_instance_get_transform_2d(RID p_multi
return t;
}
-Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
+Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, Color());
ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());
@@ -2890,8 +2934,8 @@ Color RasterizerStorageRD::multimesh_instance_get_color(RID p_multimesh, int p_i
return c;
}
-Color RasterizerStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const {
+Color RasterizerStorageRD::multimesh_instance_get_custom_data(RID p_multimesh, int p_index) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, Color());
ERR_FAIL_INDEX_V(p_index, multimesh->instances, Color());
@@ -2971,7 +3015,6 @@ Vector<float> RasterizerStorageRD::multimesh_get_buffer(RID p_multimesh) const {
}
void RasterizerStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p_visible) {
-
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND(!multimesh);
ERR_FAIL_COND(p_visible < -1 || p_visible > multimesh->instances);
@@ -2986,6 +3029,7 @@ void RasterizerStorageRD::multimesh_set_visible_instances(RID p_multimesh, int p
multimesh->visible_instances = p_visible;
}
+
int RasterizerStorageRD::multimesh_get_visible_instances(RID p_multimesh) const {
MultiMesh *multimesh = multimesh_owner.getornull(p_multimesh);
ERR_FAIL_COND_V(!multimesh, 0);
@@ -3002,9 +3046,7 @@ AABB RasterizerStorageRD::multimesh_get_aabb(RID p_multimesh) const {
}
void RasterizerStorageRD::_update_dirty_multimeshes() {
-
while (multimesh_dirty_list) {
-
MultiMesh *multimesh = multimesh_dirty_list;
if (multimesh->data_cache.size()) { //may have been cleared, so only process if it exists
@@ -3013,7 +3055,6 @@ void RasterizerStorageRD::_update_dirty_multimeshes() {
uint32_t visible_instances = multimesh->visible_instances >= 0 ? multimesh->visible_instances : multimesh->instances;
if (multimesh->data_cache_used_dirty_regions) {
-
uint32_t data_cache_dirty_region_count = (multimesh->instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
uint32_t visible_region_count = (visible_instances - 1) / MULTIMESH_DIRTY_REGION_SIZE + 1;
@@ -3062,12 +3103,10 @@ void RasterizerStorageRD::_update_dirty_multimeshes() {
/* SKELETON API */
RID RasterizerStorageRD::skeleton_create() {
-
return skeleton_owner.make_rid(Skeleton());
}
void RasterizerStorageRD::_skeleton_make_dirty(Skeleton *skeleton) {
-
if (!skeleton->dirty) {
skeleton->dirty = true;
skeleton->dirty_list = skeleton_dirty_list;
@@ -3076,13 +3115,13 @@ void RasterizerStorageRD::_skeleton_make_dirty(Skeleton *skeleton) {
}
void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_2d_skeleton) {
-
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
ERR_FAIL_COND(p_bones < 0);
- if (skeleton->size == p_bones && skeleton->use_2d == p_2d_skeleton)
+ if (skeleton->size == p_bones && skeleton->use_2d == p_2d_skeleton) {
return;
+ }
skeleton->size = p_bones;
skeleton->use_2d = p_2d_skeleton;
@@ -3095,7 +3134,6 @@ void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_
}
if (skeleton->size) {
-
skeleton->data.resize(skeleton->size * (skeleton->use_2d ? 8 : 12));
skeleton->buffer = RD::get_singleton()->storage_buffer_create(skeleton->data.size() * sizeof(float));
zeromem(skeleton->data.ptrw(), skeleton->data.size() * sizeof(float));
@@ -3103,8 +3141,8 @@ void RasterizerStorageRD::skeleton_allocate(RID p_skeleton, int p_bones, bool p_
_skeleton_make_dirty(skeleton);
}
}
-int RasterizerStorageRD::skeleton_get_bone_count(RID p_skeleton) const {
+int RasterizerStorageRD::skeleton_get_bone_count(RID p_skeleton) const {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND_V(!skeleton, 0);
@@ -3112,7 +3150,6 @@ int RasterizerStorageRD::skeleton_get_bone_count(RID p_skeleton) const {
}
void RasterizerStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) {
-
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
@@ -3138,7 +3175,6 @@ void RasterizerStorageRD::skeleton_bone_set_transform(RID p_skeleton, int p_bone
}
Transform RasterizerStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p_bone) const {
-
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND_V(!skeleton, Transform());
@@ -3164,8 +3200,8 @@ Transform RasterizerStorageRD::skeleton_bone_get_transform(RID p_skeleton, int p
return t;
}
-void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {
+void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
@@ -3185,8 +3221,8 @@ void RasterizerStorageRD::skeleton_bone_set_transform_2d(RID p_skeleton, int p_b
_skeleton_make_dirty(skeleton);
}
-Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {
+Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const {
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND_V(!skeleton, Transform2D());
@@ -3207,7 +3243,6 @@ Transform2D RasterizerStorageRD::skeleton_bone_get_transform_2d(RID p_skeleton,
}
void RasterizerStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {
-
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton->use_2d);
@@ -3216,13 +3251,10 @@ void RasterizerStorageRD::skeleton_set_base_transform_2d(RID p_skeleton, const T
}
void RasterizerStorageRD::_update_dirty_skeletons() {
-
while (skeleton_dirty_list) {
-
Skeleton *skeleton = skeleton_dirty_list;
if (skeleton->size) {
-
RD::get_singleton()->buffer_update(skeleton->buffer, 0, skeleton->data.size() * sizeof(float), skeleton->data.ptr(), false);
}
@@ -3240,7 +3272,6 @@ void RasterizerStorageRD::_update_dirty_skeletons() {
/* LIGHT */
RID RasterizerStorageRD::light_create(RS::LightType p_type) {
-
Light light;
light.type = p_type;
@@ -3264,14 +3295,13 @@ RID RasterizerStorageRD::light_create(RS::LightType p_type) {
}
void RasterizerStorageRD::light_set_color(RID p_light, const Color &p_color) {
-
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->color = p_color;
}
-void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) {
+void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, float p_value) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
ERR_FAIL_INDEX(p_param, RS::LIGHT_PARAM_MAX);
@@ -3286,7 +3316,6 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f
case RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS:
case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:
case RS::LIGHT_PARAM_SHADOW_BIAS: {
-
light->version++;
light->instance_dependency.instance_notify_changed(true, false);
} break;
@@ -3296,8 +3325,8 @@ void RasterizerStorageRD::light_set_param(RID p_light, RS::LightParam p_param, f
light->param[p_param] = p_value;
}
-void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
+void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->shadow = p_enabled;
@@ -3307,14 +3336,12 @@ void RasterizerStorageRD::light_set_shadow(RID p_light, bool p_enabled) {
}
void RasterizerStorageRD::light_set_shadow_color(RID p_light, const Color &p_color) {
-
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->shadow_color = p_color;
}
void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) {
-
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
@@ -3334,14 +3361,13 @@ void RasterizerStorageRD::light_set_projector(RID p_light, RID p_texture) {
}
void RasterizerStorageRD::light_set_negative(RID p_light, bool p_enable) {
-
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
light->negative = p_enable;
}
-void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) {
+void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
@@ -3352,7 +3378,6 @@ void RasterizerStorageRD::light_set_cull_mask(RID p_light, uint32_t p_mask) {
}
void RasterizerStorageRD::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled) {
-
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
@@ -3371,8 +3396,8 @@ void RasterizerStorageRD::light_set_use_gi(RID p_light, bool p_enabled) {
light->version++;
light->instance_dependency.instance_notify_changed(true, false);
}
-void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
+void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
@@ -3383,7 +3408,6 @@ void RasterizerStorageRD::light_omni_set_shadow_mode(RID p_light, RS::LightOmniS
}
RS::LightOmniShadowMode RasterizerStorageRD::light_omni_get_shadow_mode(RID p_light) {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, RS::LIGHT_OMNI_SHADOW_CUBE);
@@ -3391,7 +3415,6 @@ RS::LightOmniShadowMode RasterizerStorageRD::light_omni_get_shadow_mode(RID p_li
}
void RasterizerStorageRD::light_directional_set_shadow_mode(RID p_light, RS::LightDirectionalShadowMode p_mode) {
-
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
@@ -3401,7 +3424,6 @@ void RasterizerStorageRD::light_directional_set_shadow_mode(RID p_light, RS::Lig
}
void RasterizerStorageRD::light_directional_set_blend_splits(RID p_light, bool p_enable) {
-
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
@@ -3411,7 +3433,6 @@ void RasterizerStorageRD::light_directional_set_blend_splits(RID p_light, bool p
}
bool RasterizerStorageRD::light_directional_get_blend_splits(RID p_light) const {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, false);
@@ -3419,7 +3440,6 @@ bool RasterizerStorageRD::light_directional_get_blend_splits(RID p_light) const
}
RS::LightDirectionalShadowMode RasterizerStorageRD::light_directional_get_shadow_mode(RID p_light) {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL);
@@ -3427,7 +3447,6 @@ RS::LightDirectionalShadowMode RasterizerStorageRD::light_directional_get_shadow
}
void RasterizerStorageRD::light_directional_set_shadow_depth_range_mode(RID p_light, RS::LightDirectionalShadowDepthRangeMode p_range_mode) {
-
Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND(!light);
@@ -3435,7 +3454,6 @@ void RasterizerStorageRD::light_directional_set_shadow_depth_range_mode(RID p_li
}
RS::LightDirectionalShadowDepthRangeMode RasterizerStorageRD::light_directional_get_shadow_depth_range_mode(RID p_light) const {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE);
@@ -3450,7 +3468,6 @@ bool RasterizerStorageRD::light_get_use_gi(RID p_light) {
}
uint64_t RasterizerStorageRD::light_get_version(RID p_light) const {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, 0);
@@ -3458,25 +3475,20 @@ uint64_t RasterizerStorageRD::light_get_version(RID p_light) const {
}
AABB RasterizerStorageRD::light_get_aabb(RID p_light) const {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, AABB());
switch (light->type) {
-
case RS::LIGHT_SPOT: {
-
float len = light->param[RS::LIGHT_PARAM_RANGE];
float size = Math::tan(Math::deg2rad(light->param[RS::LIGHT_PARAM_SPOT_ANGLE])) * len;
return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
};
case RS::LIGHT_OMNI: {
-
float r = light->param[RS::LIGHT_PARAM_RANGE];
return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
};
case RS::LIGHT_DIRECTIONAL: {
-
return AABB();
};
}
@@ -3487,12 +3499,10 @@ AABB RasterizerStorageRD::light_get_aabb(RID p_light) const {
/* REFLECTION PROBE */
RID RasterizerStorageRD::reflection_probe_create() {
-
return reflection_probe_owner.make_rid(ReflectionProbe());
}
void RasterizerStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionProbeUpdateMode p_mode) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -3501,7 +3511,6 @@ void RasterizerStorageRD::reflection_probe_set_update_mode(RID p_probe, RS::Refl
}
void RasterizerStorageRD::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -3509,7 +3518,6 @@ void RasterizerStorageRD::reflection_probe_set_intensity(RID p_probe, float p_in
}
void RasterizerStorageRD::reflection_probe_set_interior_ambient(RID p_probe, const Color &p_ambient) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -3517,7 +3525,6 @@ void RasterizerStorageRD::reflection_probe_set_interior_ambient(RID p_probe, con
}
void RasterizerStorageRD::reflection_probe_set_interior_ambient_energy(RID p_probe, float p_energy) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -3525,7 +3532,6 @@ void RasterizerStorageRD::reflection_probe_set_interior_ambient_energy(RID p_pro
}
void RasterizerStorageRD::reflection_probe_set_interior_ambient_probe_contribution(RID p_probe, float p_contrib) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -3533,7 +3539,6 @@ void RasterizerStorageRD::reflection_probe_set_interior_ambient_probe_contributi
}
void RasterizerStorageRD::reflection_probe_set_max_distance(RID p_probe, float p_distance) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -3541,16 +3546,16 @@ void RasterizerStorageRD::reflection_probe_set_max_distance(RID p_probe, float p
reflection_probe->instance_dependency.instance_notify_changed(true, false);
}
-void RasterizerStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
+void RasterizerStorageRD::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->extents = p_extents;
reflection_probe->instance_dependency.instance_notify_changed(true, false);
}
-void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
+void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -3559,15 +3564,14 @@ void RasterizerStorageRD::reflection_probe_set_origin_offset(RID p_probe, const
}
void RasterizerStorageRD::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->interior = p_enable;
reflection_probe->instance_dependency.instance_notify_changed(true, false);
}
-void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
+void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -3575,15 +3579,14 @@ void RasterizerStorageRD::reflection_probe_set_enable_box_projection(RID p_probe
}
void RasterizerStorageRD::reflection_probe_set_enable_shadows(RID p_probe, bool p_enable) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
reflection_probe->enable_shadows = p_enable;
reflection_probe->instance_dependency.instance_notify_changed(true, false);
}
-void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
+void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
@@ -3592,7 +3595,6 @@ void RasterizerStorageRD::reflection_probe_set_cull_mask(RID p_probe, uint32_t p
}
void RasterizerStorageRD::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
-
ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND(!reflection_probe);
ERR_FAIL_COND(p_resolution < 32);
@@ -3610,8 +3612,8 @@ AABB RasterizerStorageRD::reflection_probe_get_aabb(RID p_probe) const {
return aabb;
}
-RS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_mode(RID p_probe) const {
+RS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_mode(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, RS::REFLECTION_PROBE_UPDATE_ALWAYS);
@@ -3619,7 +3621,6 @@ RS::ReflectionProbeUpdateMode RasterizerStorageRD::reflection_probe_get_update_m
}
uint32_t RasterizerStorageRD::reflection_probe_get_cull_mask(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
@@ -3627,14 +3628,13 @@ uint32_t RasterizerStorageRD::reflection_probe_get_cull_mask(RID p_probe) const
}
Vector3 RasterizerStorageRD::reflection_probe_get_extents(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, Vector3());
return reflection_probe->extents;
}
-Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) const {
+Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, Vector3());
@@ -3642,7 +3642,6 @@ Vector3 RasterizerStorageRD::reflection_probe_get_origin_offset(RID p_probe) con
}
bool RasterizerStorageRD::reflection_probe_renders_shadows(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, false);
@@ -3650,7 +3649,6 @@ bool RasterizerStorageRD::reflection_probe_renders_shadows(RID p_probe) const {
}
float RasterizerStorageRD::reflection_probe_get_origin_max_distance(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
@@ -3658,7 +3656,6 @@ float RasterizerStorageRD::reflection_probe_get_origin_max_distance(RID p_probe)
}
int RasterizerStorageRD::reflection_probe_get_resolution(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
@@ -3666,21 +3663,20 @@ int RasterizerStorageRD::reflection_probe_get_resolution(RID p_probe) const {
}
float RasterizerStorageRD::reflection_probe_get_intensity(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
return reflection_probe->intensity;
}
-bool RasterizerStorageRD::reflection_probe_is_interior(RID p_probe) const {
+bool RasterizerStorageRD::reflection_probe_is_interior(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, false);
return reflection_probe->interior;
}
-bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const {
+bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, false);
@@ -3688,21 +3684,20 @@ bool RasterizerStorageRD::reflection_probe_is_box_projection(RID p_probe) const
}
Color RasterizerStorageRD::reflection_probe_get_interior_ambient(RID p_probe) const {
-
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, Color());
return reflection_probe->interior_ambient;
}
-float RasterizerStorageRD::reflection_probe_get_interior_ambient_energy(RID p_probe) const {
+float RasterizerStorageRD::reflection_probe_get_interior_ambient_energy(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
return reflection_probe->interior_ambient_energy;
}
-float RasterizerStorageRD::reflection_probe_get_interior_ambient_probe_contribution(RID p_probe) const {
+float RasterizerStorageRD::reflection_probe_get_interior_ambient_probe_contribution(RID p_probe) const {
const ReflectionProbe *reflection_probe = reflection_probe_owner.getornull(p_probe);
ERR_FAIL_COND_V(!reflection_probe, 0);
@@ -3719,6 +3714,7 @@ void RasterizerStorageRD::decal_set_extents(RID p_decal, const Vector3 &p_extent
decal->extents = p_extents;
decal->instance_dependency.instance_notify_changed(true, false);
}
+
void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
@@ -3742,6 +3738,7 @@ void RasterizerStorageRD::decal_set_texture(RID p_decal, RS::DecalTexture p_type
decal->instance_dependency.instance_notify_changed(false, true);
}
+
void RasterizerStorageRD::decal_set_emission_energy(RID p_decal, float p_energy) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
@@ -3759,6 +3756,7 @@ void RasterizerStorageRD::decal_set_modulate(RID p_decal, const Color &p_modulat
ERR_FAIL_COND(!decal);
decal->modulate = p_modulate;
}
+
void RasterizerStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
@@ -3767,7 +3765,6 @@ void RasterizerStorageRD::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
}
void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
-
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->distance_fade = p_enabled;
@@ -3776,7 +3773,6 @@ void RasterizerStorageRD::decal_set_distance_fade(RID p_decal, bool p_enabled, f
}
void RasterizerStorageRD::decal_set_fade(RID p_decal, float p_above, float p_below) {
-
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->upper_fade = p_above;
@@ -3784,7 +3780,6 @@ void RasterizerStorageRD::decal_set_fade(RID p_decal, float p_above, float p_bel
}
void RasterizerStorageRD::decal_set_normal_fade(RID p_decal, float p_fade) {
-
Decal *decal = decal_owner.getornull(p_decal);
ERR_FAIL_COND(!decal);
decal->normal_fade = p_fade;
@@ -3798,7 +3793,6 @@ AABB RasterizerStorageRD::decal_get_aabb(RID p_decal) const {
}
RID RasterizerStorageRD::gi_probe_create() {
-
return gi_probe_owner.make_rid(GIProbe());
}
@@ -3940,6 +3934,7 @@ Vector3i RasterizerStorageRD::gi_probe_get_octree_size(RID p_gi_probe) const {
ERR_FAIL_COND_V(!gi_probe, Vector3i());
return gi_probe->octree_size;
}
+
Vector<uint8_t> RasterizerStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>());
@@ -3949,6 +3944,7 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_octree_cells(RID p_gi_probe) c
}
return Vector<uint8_t>();
}
+
Vector<uint8_t> RasterizerStorageRD::gi_probe_get_data_cells(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>());
@@ -3958,6 +3954,7 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_data_cells(RID p_gi_probe) con
}
return Vector<uint8_t>();
}
+
Vector<uint8_t> RasterizerStorageRD::gi_probe_get_distance_field(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, Vector<uint8_t>());
@@ -3967,12 +3964,14 @@ Vector<uint8_t> RasterizerStorageRD::gi_probe_get_distance_field(RID p_gi_probe)
}
return Vector<uint8_t>();
}
+
Vector<int> RasterizerStorageRD::gi_probe_get_level_counts(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, Vector<int>());
return gi_probe->level_counts;
}
+
Transform RasterizerStorageRD::gi_probe_get_to_cell_xform(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, Transform());
@@ -3987,6 +3986,7 @@ void RasterizerStorageRD::gi_probe_set_dynamic_range(RID p_gi_probe, float p_ran
gi_probe->dynamic_range = p_range;
gi_probe->version++;
}
+
float RasterizerStorageRD::gi_probe_get_dynamic_range(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
@@ -4001,6 +4001,7 @@ void RasterizerStorageRD::gi_probe_set_propagation(RID p_gi_probe, float p_range
gi_probe->propagation = p_range;
gi_probe->version++;
}
+
float RasterizerStorageRD::gi_probe_get_propagation(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
@@ -4013,6 +4014,7 @@ void RasterizerStorageRD::gi_probe_set_energy(RID p_gi_probe, float p_energy) {
gi_probe->energy = p_energy;
}
+
float RasterizerStorageRD::gi_probe_get_energy(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
@@ -4025,6 +4027,7 @@ void RasterizerStorageRD::gi_probe_set_ao(RID p_gi_probe, float p_ao) {
gi_probe->ao = p_ao;
}
+
float RasterizerStorageRD::gi_probe_get_ao(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
@@ -4032,7 +4035,6 @@ float RasterizerStorageRD::gi_probe_get_ao(RID p_gi_probe) const {
}
void RasterizerStorageRD::gi_probe_set_ao_size(RID p_gi_probe, float p_strength) {
-
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
@@ -4051,6 +4053,7 @@ void RasterizerStorageRD::gi_probe_set_bias(RID p_gi_probe, float p_bias) {
gi_probe->bias = p_bias;
}
+
float RasterizerStorageRD::gi_probe_get_bias(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
@@ -4063,6 +4066,7 @@ void RasterizerStorageRD::gi_probe_set_normal_bias(RID p_gi_probe, float p_norma
gi_probe->normal_bias = p_normal_bias;
}
+
float RasterizerStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, 0);
@@ -4070,7 +4074,6 @@ float RasterizerStorageRD::gi_probe_get_normal_bias(RID p_gi_probe) const {
}
void RasterizerStorageRD::gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) {
-
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND(!gi_probe);
@@ -4123,13 +4126,12 @@ uint32_t RasterizerStorageRD::gi_probe_get_data_version(RID p_gi_probe) {
}
RID RasterizerStorageRD::gi_probe_get_octree_buffer(RID p_gi_probe) const {
-
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, RID());
return gi_probe->octree_buffer;
}
-RID RasterizerStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const {
+RID RasterizerStorageRD::gi_probe_get_data_buffer(RID p_gi_probe) const {
GIProbe *gi_probe = gi_probe_owner.getornull(p_gi_probe);
ERR_FAIL_COND_V(!gi_probe, RID());
return gi_probe->data_buffer;
@@ -4142,10 +4144,182 @@ RID RasterizerStorageRD::gi_probe_get_sdf_texture(RID p_gi_probe) {
return gi_probe->sdf_texture;
}
+/* LIGHTMAP API */
+
+RID RasterizerStorageRD::lightmap_create() {
+ return lightmap_owner.make_rid(Lightmap());
+}
+
+void RasterizerStorageRD::lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) {
+ Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND(!lm);
+
+ lightmap_array_version++;
+
+ //erase lightmap users
+ if (lm->light_texture.is_valid()) {
+ Texture *t = texture_owner.getornull(lm->light_texture);
+ if (t) {
+ t->lightmap_users.erase(p_lightmap);
+ }
+ }
+
+ Texture *t = texture_owner.getornull(p_light);
+ lm->light_texture = p_light;
+ lm->uses_spherical_harmonics = p_uses_spherical_haromics;
+
+ RID default_2d_array = default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE];
+ if (!t) {
+ if (using_lightmap_array) {
+ if (lm->array_index >= 0) {
+ lightmap_textures.write[lm->array_index] = default_2d_array;
+ lm->array_index = -1;
+ }
+ }
+
+ return;
+ }
+
+ t->lightmap_users.insert(p_lightmap);
+
+ if (using_lightmap_array) {
+ if (lm->array_index < 0) {
+ //not in array, try to put in array
+ for (int i = 0; i < lightmap_textures.size(); i++) {
+ if (lightmap_textures[i] == default_2d_array) {
+ lm->array_index = i;
+ break;
+ }
+ }
+ }
+ ERR_FAIL_COND_MSG(lm->array_index < 0, "Maximum amount of lightmaps in use (" + itos(lightmap_textures.size()) + ") has been exceeded, lightmap will nod display properly.");
+
+ lightmap_textures.write[lm->array_index] = t->rd_texture;
+ }
+}
+
+void RasterizerStorageRD::lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) {
+ Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND(!lm);
+ lm->bounds = p_bounds;
+}
+
+void RasterizerStorageRD::lightmap_set_probe_interior(RID p_lightmap, bool p_interior) {
+ Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND(!lm);
+ lm->interior = p_interior;
+}
+
+void RasterizerStorageRD::lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) {
+ Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND(!lm);
+
+ if (p_points.size()) {
+ ERR_FAIL_COND(p_points.size() * 9 != p_point_sh.size());
+ ERR_FAIL_COND((p_tetrahedra.size() % 4) != 0);
+ ERR_FAIL_COND((p_bsp_tree.size() % 6) != 0);
+ }
+
+ lm->points = p_points;
+ lm->bsp_tree = p_bsp_tree;
+ lm->point_sh = p_point_sh;
+ lm->tetrahedra = p_tetrahedra;
+}
+
+PackedVector3Array RasterizerStorageRD::lightmap_get_probe_capture_points(RID p_lightmap) const {
+ Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND_V(!lm, PackedVector3Array());
+
+ return lm->points;
+}
+
+PackedColorArray RasterizerStorageRD::lightmap_get_probe_capture_sh(RID p_lightmap) const {
+ Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND_V(!lm, PackedColorArray());
+ return lm->point_sh;
+}
+
+PackedInt32Array RasterizerStorageRD::lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const {
+ Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND_V(!lm, PackedInt32Array());
+ return lm->tetrahedra;
+}
+
+PackedInt32Array RasterizerStorageRD::lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const {
+ Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND_V(!lm, PackedInt32Array());
+ return lm->bsp_tree;
+}
+
+void RasterizerStorageRD::lightmap_set_probe_capture_update_speed(float p_speed) {
+ lightmap_probe_capture_update_speed = p_speed;
+}
+
+void RasterizerStorageRD::lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh) {
+ Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND(!lm);
+
+ for (int i = 0; i < 9; i++) {
+ r_sh[i] = Color(0, 0, 0, 0);
+ }
+
+ if (!lm->points.size() || !lm->bsp_tree.size() || !lm->tetrahedra.size()) {
+ return;
+ }
+
+ static_assert(sizeof(Lightmap::BSP) == 24);
+
+ const Lightmap::BSP *bsp = (const Lightmap::BSP *)lm->bsp_tree.ptr();
+ int32_t node = 0;
+ while (node >= 0) {
+ if (Plane(bsp[node].plane[0], bsp[node].plane[1], bsp[node].plane[2], bsp[node].plane[3]).is_point_over(p_point)) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(bsp[node].over >= 0 && bsp[node].over < node);
+#endif
+
+ node = bsp[node].over;
+ } else {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_COND(bsp[node].under >= 0 && bsp[node].under < node);
+#endif
+ node = bsp[node].under;
+ }
+ }
+
+ if (node == Lightmap::BSP::EMPTY_LEAF) {
+ return; //nothing could be done
+ }
+
+ node = ABS(node) - 1;
+
+ uint32_t *tetrahedron = (uint32_t *)&lm->tetrahedra[node * 4];
+ Vector3 points[4] = { lm->points[tetrahedron[0]], lm->points[tetrahedron[1]], lm->points[tetrahedron[2]], lm->points[tetrahedron[3]] };
+ const Color *sh_colors[4]{ &lm->point_sh[tetrahedron[0] * 9], &lm->point_sh[tetrahedron[1] * 9], &lm->point_sh[tetrahedron[2] * 9], &lm->point_sh[tetrahedron[3] * 9] };
+ Color barycentric = Geometry::tetrahedron_get_barycentric_coords(points[0], points[1], points[2], points[3], p_point);
+
+ for (int i = 0; i < 4; i++) {
+ float c = CLAMP(barycentric[i], 0.0, 1.0);
+ for (int j = 0; j < 9; j++) {
+ r_sh[j] += sh_colors[i][j] * c;
+ }
+ }
+}
+
+bool RasterizerStorageRD::lightmap_is_interior(RID p_lightmap) const {
+ const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND_V(!lm, false);
+ return lm->interior;
+}
+
+AABB RasterizerStorageRD::lightmap_get_aabb(RID p_lightmap) const {
+ const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ ERR_FAIL_COND_V(!lm, AABB());
+ return lm->bounds;
+}
+
/* RENDER TARGET API */
void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) {
-
//free in reverse dependency order
if (rt->framebuffer.is_valid()) {
RD::get_singleton()->free(rt->framebuffer);
@@ -4174,7 +4348,6 @@ void RasterizerStorageRD::_clear_render_target(RenderTarget *rt) {
}
void RasterizerStorageRD::_update_render_target(RenderTarget *rt) {
-
if (rt->texture.is_null()) {
//create a placeholder until updated
rt->texture = texture_2d_placeholder_create();
@@ -4279,7 +4452,6 @@ void RasterizerStorageRD::_create_render_target_backbuffer(RenderTarget *rt) {
//create mipmaps
for (uint32_t i = 1; i < mipmaps_required; i++) {
-
RenderTarget::BackbufferMipmap mm;
{
mm.mipmap = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rt->backbuffer, 0, i);
@@ -4343,14 +4515,12 @@ void RasterizerStorageRD::render_target_set_flag(RID p_render_target, RenderTarg
}
bool RasterizerStorageRD::render_target_was_used(RID p_render_target) {
-
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, false);
return rt->was_used;
}
void RasterizerStorageRD::render_target_set_as_unused(RID p_render_target) {
-
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
rt->was_used = false;
@@ -4369,12 +4539,14 @@ RID RasterizerStorageRD::render_target_get_rd_framebuffer(RID p_render_target) {
return rt->framebuffer;
}
+
RID RasterizerStorageRD::render_target_get_rd_texture(RID p_render_target) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, RID());
return rt->color;
}
+
void RasterizerStorageRD::render_target_request_clear(RID p_render_target, const Color &p_clear_color) {
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
@@ -4389,21 +4561,18 @@ bool RasterizerStorageRD::render_target_is_clear_requested(RID p_render_target)
}
Color RasterizerStorageRD::render_target_get_clear_request_color(RID p_render_target) {
-
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND_V(!rt, Color());
return rt->clear_color;
}
void RasterizerStorageRD::render_target_disable_clear_request(RID p_render_target) {
-
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
rt->clear_requested = false;
}
void RasterizerStorageRD::render_target_do_clear_request(RID p_render_target) {
-
RenderTarget *rt = render_target_owner.getornull(p_render_target);
ERR_FAIL_COND(!rt);
if (!rt->clear_requested) {
@@ -4478,7 +4647,6 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In
Mesh *mesh = mesh_owner.getornull(p_base);
p_instance->update_dependency(&mesh->instance_dependency);
} else if (multimesh_owner.owns(p_base)) {
-
MultiMesh *multimesh = multimesh_owner.getornull(p_base);
p_instance->update_dependency(&multimesh->instance_dependency);
if (multimesh->mesh.is_valid()) {
@@ -4493,6 +4661,9 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In
} else if (gi_probe_owner.owns(p_base)) {
GIProbe *gip = gi_probe_owner.getornull(p_base);
p_instance->update_dependency(&gip->instance_dependency);
+ } else if (lightmap_owner.owns(p_base)) {
+ Lightmap *lm = lightmap_owner.getornull(p_base);
+ p_instance->update_dependency(&lm->instance_dependency);
} else if (light_owner.owns(p_base)) {
Light *l = light_owner.getornull(p_base);
p_instance->update_dependency(&l->instance_dependency);
@@ -4500,7 +4671,6 @@ void RasterizerStorageRD::base_update_dependency(RID p_base, RasterizerScene::In
}
void RasterizerStorageRD::skeleton_update_dependency(RID p_skeleton, RasterizerScene::InstanceBase *p_instance) {
-
Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
ERR_FAIL_COND(!skeleton);
@@ -4508,7 +4678,6 @@ void RasterizerStorageRD::skeleton_update_dependency(RID p_skeleton, RasterizerS
}
RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const {
-
if (mesh_owner.owns(p_rid)) {
return RS::INSTANCE_MESH;
}
@@ -4527,6 +4696,9 @@ RS::InstanceType RasterizerStorageRD::get_base_type(RID p_rid) const {
if (light_owner.owns(p_rid)) {
return RS::INSTANCE_LIGHT;
}
+ if (lightmap_owner.owns(p_rid)) {
+ return RS::INSTANCE_LIGHTMAP;
+ }
return RS::INSTANCE_NONE;
}
@@ -4590,7 +4762,7 @@ void RasterizerStorageRD::_update_decal_atlas() {
Vector<DecalAtlas::SortItem> itemsv;
itemsv.resize(decal_atlas.textures.size());
int base_size = 8;
- const RID *K = NULL;
+ const RID *K = nullptr;
int idx = 0;
while ((K = decal_atlas.textures.next(K))) {
@@ -4620,7 +4792,6 @@ void RasterizerStorageRD::_update_decal_atlas() {
int atlas_height = 0;
while (true) {
-
Vector<int> v_offsetsv;
v_offsetsv.resize(base_size);
@@ -4680,12 +4851,11 @@ void RasterizerStorageRD::_update_decal_atlas() {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(items[i].texture);
t->uv_rect.position = items[i].pos * border + Vector2i(border / 2, border / 2);
t->uv_rect.size = items[i].pixel_size;
- //print_line("blitrect: " + t->uv_rect);
+
t->uv_rect.position /= Size2(decal_atlas.size);
t->uv_rect.size /= Size2(decal_atlas.size);
}
} else {
-
//use border as size, so it at least has enough mipmaps
decal_atlas.size.width = border;
decal_atlas.size.height = border;
@@ -4737,14 +4907,13 @@ void RasterizerStorageRD::_update_decal_atlas() {
Color clear_color(0, 0, 0, 0);
if (decal_atlas.textures.size()) {
-
if (i == 0) {
Vector<Color> cc;
cc.push_back(clear_color);
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc);
- const RID *K = NULL;
+ const RID *K = nullptr;
while ((K = decal_atlas.textures.next(K))) {
DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K);
Texture *src_tex = texture_owner.getornull(*K);
@@ -4755,7 +4924,6 @@ void RasterizerStorageRD::_update_decal_atlas() {
prev_texture = mm.texture;
} else {
-
effects.copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size));
prev_texture = mm.texture;
}
@@ -4766,7 +4934,6 @@ void RasterizerStorageRD::_update_decal_atlas() {
}
int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) {
-
int32_t idx = 0;
while (idx + p_elements <= global_variables.buffer_size) {
if (global_variables.buffer_usage[idx].elements == 0) {
@@ -4793,10 +4960,8 @@ int32_t RasterizerStorageRD::_global_variable_allocate(uint32_t p_elements) {
}
void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::GlobalVariableType p_type, const Variant &p_value) {
-
switch (p_type) {
case RS::GLOBAL_VAR_TYPE_BOOL: {
-
GlobalVariables::Value &bv = global_variables.buffer_values[p_index];
bool b = p_value;
bv.x = b ? 1.0 : 0.0;
@@ -4975,7 +5140,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::
} break;
case RS::GLOBAL_VAR_TYPE_MAT3: {
-
GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
Basis v = p_value;
bv[0].x = v.elements[0][0];
@@ -4995,7 +5159,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::
} break;
case RS::GLOBAL_VAR_TYPE_MAT4: {
-
GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
Vector<float> m2 = p_value;
@@ -5025,7 +5188,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::
} break;
case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: {
-
GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
Transform2D v = p_value;
bv[0].x = v.elements[0][0];
@@ -5045,7 +5207,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::
} break;
case RS::GLOBAL_VAR_TYPE_TRANSFORM: {
-
GlobalVariables::Value *bv = &global_variables.buffer_values[p_index];
Transform v = p_value;
bv[0].x = v.basis.elements[0][0];
@@ -5063,10 +5224,10 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::
bv[2].z = v.basis.elements[2][2];
bv[2].w = 0;
- bv[2].x = v.origin.x;
- bv[2].y = v.origin.y;
- bv[2].z = v.origin.z;
- bv[2].w = 1;
+ bv[3].x = v.origin.x;
+ bv[3].y = v.origin.y;
+ bv[3].z = v.origin.z;
+ bv[3].w = 1;
} break;
default: {
@@ -5076,7 +5237,6 @@ void RasterizerStorageRD::_global_variable_store_in_buffer(int32_t p_index, RS::
}
void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, int32_t p_elements) {
-
int32_t prev_chunk = -1;
for (int32_t i = 0; i < p_elements; i++) {
@@ -5093,7 +5253,6 @@ void RasterizerStorageRD::_global_variable_mark_buffer_dirty(int32_t p_index, in
}
void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) {
-
ERR_FAIL_COND(global_variables.variables.has(p_name));
GlobalVariables::Variable gv;
gv.type = p_type;
@@ -5104,7 +5263,6 @@ void RasterizerStorageRD::global_variable_add(const StringName &p_name, RS::Glob
//is texture
global_variables.must_update_texture_materials = true; //normally ther are no
} else {
-
gv.buffer_elements = 1;
if (p_type == RS::GLOBAL_VAR_TYPE_COLOR || p_type == RS::GLOBAL_VAR_TYPE_MAT2) {
//color needs to elements to store srgb and linear
@@ -5147,13 +5305,13 @@ void RasterizerStorageRD::global_variable_remove(const StringName &p_name) {
global_variables.variables.erase(p_name);
}
-Vector<StringName> RasterizerStorageRD::global_variable_get_list() const {
+Vector<StringName> RasterizerStorageRD::global_variable_get_list() const {
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance.");
}
- const StringName *K = NULL;
+ const StringName *K = nullptr;
Vector<StringName> names;
while ((K = global_variables.variables.next(K))) {
names.push_back(*K);
@@ -5181,6 +5339,7 @@ void RasterizerStorageRD::global_variable_set(const StringName &p_name, const Va
}
}
}
+
void RasterizerStorageRD::global_variable_set_override(const StringName &p_name, const Variant &p_value) {
if (!global_variables.variables.has(p_name)) {
return; //variable may not exist
@@ -5210,7 +5369,6 @@ void RasterizerStorageRD::global_variable_set_override(const StringName &p_name,
}
Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const {
-
if (!Engine::get_singleton()->is_editor_hint()) {
ERR_FAIL_V_MSG(Variant(), "This function should never be used outside the editor, it can severely damage performance.");
}
@@ -5223,7 +5381,6 @@ Variant RasterizerStorageRD::global_variable_get(const StringName &p_name) const
}
RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type_internal(const StringName &p_name) const {
-
if (!global_variables.variables.has(p_name)) {
return RS::GLOBAL_VAR_TYPE_MAX;
}
@@ -5240,7 +5397,6 @@ RS::GlobalVariableType RasterizerStorageRD::global_variable_get_type(const Strin
}
void RasterizerStorageRD::global_variables_load_settings(bool p_load_textures) {
-
List<PropertyInfo> settings;
ProjectSettings::get_singleton()->get_property_list(&settings);
@@ -5346,8 +5502,8 @@ void RasterizerStorageRD::global_variables_instance_free(RID p_instance) {
}
global_variables.instance_buffer_pos.erase(p_instance);
}
-void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {
+void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p_index, const Variant &p_value) {
if (!global_variables.instance_buffer_pos.has(p_instance)) {
return; //just not allocated, ignore
}
@@ -5391,7 +5547,6 @@ void RasterizerStorageRD::global_variables_instance_update(RID p_instance, int p
}
void RasterizerStorageRD::_update_global_variables() {
-
if (global_variables.buffer_dirty_region_count > 0) {
uint32_t total_regions = global_variables.buffer_size / GlobalVariables::BUFFER_DIRTY_REGION_SIZE;
if (total_regions / global_variables.buffer_dirty_region_count <= 4) {
@@ -5403,7 +5558,6 @@ void RasterizerStorageRD::_update_global_variables() {
for (uint32_t i = 0; i < total_regions; i++) {
if (global_variables.buffer_dirty_regions[i]) {
-
RD::get_singleton()->buffer_update(global_variables.buffer, i * region_byte_size, region_byte_size, global_variables.buffer_values);
global_variables.buffer_dirty_regions[i] = false;
@@ -5451,7 +5605,6 @@ void RasterizerStorageRD::update_dirty_resources() {
}
bool RasterizerStorageRD::has_os_feature(const String &p_feature) const {
-
if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
return true;
}
@@ -5474,8 +5627,8 @@ bool RasterizerStorageRD::has_os_feature(const String &p_feature) const {
return false;
}
-bool RasterizerStorageRD::free(RID p_rid) {
+bool RasterizerStorageRD::free(RID p_rid) {
if (texture_owner.owns(p_rid)) {
Texture *t = texture_owner.getornull(p_rid);
@@ -5565,9 +5718,13 @@ bool RasterizerStorageRD::free(RID p_rid) {
GIProbe *gi_probe = gi_probe_owner.getornull(p_rid);
gi_probe->instance_dependency.instance_notify_deleted(p_rid);
gi_probe_owner.free(p_rid);
+ } else if (lightmap_owner.owns(p_rid)) {
+ lightmap_set_textures(p_rid, RID(), false);
+ Lightmap *lightmap = lightmap_owner.getornull(p_rid);
+ lightmap->instance_dependency.instance_notify_deleted(p_rid);
+ lightmap_owner.free(p_rid);
} else if (light_owner.owns(p_rid)) {
-
light_set_projector(p_rid, RID()); //clear projector
// delete the texture
Light *light = light_owner.getornull(p_rid);
@@ -5608,6 +5765,7 @@ void RasterizerStorageRD::capture_timestamp(const String &p_name) {
uint32_t RasterizerStorageRD::get_captured_timestamps_count() const {
return RD::get_singleton()->get_captured_timestamps_count();
}
+
uint64_t RasterizerStorageRD::get_captured_timestamps_frame() const {
return RD::get_singleton()->get_captured_timestamps_frame();
}
@@ -5615,9 +5773,11 @@ uint64_t RasterizerStorageRD::get_captured_timestamps_frame() const {
uint64_t RasterizerStorageRD::get_captured_timestamp_gpu_time(uint32_t p_index) const {
return RD::get_singleton()->get_captured_timestamp_gpu_time(p_index);
}
+
uint64_t RasterizerStorageRD::get_captured_timestamp_cpu_time(uint32_t p_index) const {
return RD::get_singleton()->get_captured_timestamp_cpu_time(p_index);
}
+
String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const {
return RD::get_singleton()->get_captured_timestamp_name(p_index);
}
@@ -5625,7 +5785,6 @@ String RasterizerStorageRD::get_captured_timestamp_name(uint32_t p_index) const
RasterizerStorageRD *RasterizerStorageRD::base_singleton = nullptr;
RasterizerStorageRD::RasterizerStorageRD() {
-
base_singleton = this;
for (int i = 0; i < SHADER_TYPE_MAX; i++) {
@@ -5803,6 +5962,32 @@ RasterizerStorageRD::RasterizerStorageRD() {
}
}
+ { //create default array
+
+ RD::TextureFormat tformat;
+ tformat.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
+ tformat.width = 4;
+ tformat.height = 4;
+ tformat.array_layers = 1;
+ tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT;
+ tformat.type = RD::TEXTURE_TYPE_2D_ARRAY;
+
+ Vector<uint8_t> pv;
+ pv.resize(16 * 4);
+ for (int i = 0; i < 16; i++) {
+ pv.set(i * 4 + 0, 255);
+ pv.set(i * 4 + 1, 255);
+ pv.set(i * 4 + 2, 255);
+ pv.set(i * 4 + 3, 255);
+ }
+
+ {
+ Vector<Vector<uint8_t>> vpv;
+ vpv.push_back(pv);
+ default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE] = RD::get_singleton()->texture_create(tformat, RD::TextureView(), vpv);
+ }
+ }
+
//default samplers
for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) {
for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) {
@@ -5814,7 +5999,6 @@ RasterizerStorageRD::RasterizerStorageRD() {
sampler_state.max_lod = 0;
} break;
case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR: {
-
sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.max_lod = 0;
@@ -5835,14 +6019,14 @@ RasterizerStorageRD::RasterizerStorageRD() {
sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.use_anisotropy = true;
- sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/texture_filters/max_anisotropy");
+ sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/quality/texture_filters/anisotropic_filtering_level"));
} break;
case RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS_ANISOTROPIC: {
sampler_state.mag_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.min_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.mip_filter = RD::SAMPLER_FILTER_LINEAR;
sampler_state.use_anisotropy = true;
- sampler_state.anisotropy_max = GLOBAL_GET("rendering/quality/texture_filters/max_anisotropy");
+ sampler_state.anisotropy_max = 1 << int(GLOBAL_GET("rendering/quality/texture_filters/anisotropic_filtering_level"));
} break;
default: {
@@ -5850,7 +6034,6 @@ RasterizerStorageRD::RasterizerStorageRD() {
}
switch (j) {
case RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED: {
-
sampler_state.repeat_u = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
sampler_state.repeat_v = RD::SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE;
@@ -5873,129 +6056,134 @@ RasterizerStorageRD::RasterizerStorageRD() {
//default rd buffers
{
-
- //vertex
+ Vector<uint8_t> buffer;
{
+ buffer.resize(sizeof(float) * 3);
+ {
+ uint8_t *w = buffer.ptrw();
+ float *fptr = (float *)w;
+ fptr[0] = 0.0;
+ fptr[1] = 0.0;
+ fptr[2] = 0.0;
+ }
+ mesh_default_rd_buffers[DEFAULT_RD_BUFFER_VERTEX] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
+ }
- Vector<uint8_t> buffer;
+ { //normal
+ buffer.resize(sizeof(float) * 3);
+ {
+ uint8_t *w = buffer.ptrw();
+ float *fptr = (float *)w;
+ fptr[0] = 1.0;
+ fptr[1] = 0.0;
+ fptr[2] = 0.0;
+ }
+ mesh_default_rd_buffers[DEFAULT_RD_BUFFER_NORMAL] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
+ }
- buffer.resize(sizeof(float) * 3);
- {
- uint8_t *w = buffer.ptrw();
- float *fptr = (float *)w;
- fptr[0] = 0.0;
- fptr[1] = 0.0;
- fptr[2] = 0.0;
- }
- mesh_default_rd_buffers[DEFAULT_RD_BUFFER_VERTEX] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
-}
+ { //tangent
+ buffer.resize(sizeof(float) * 4);
+ {
+ uint8_t *w = buffer.ptrw();
+ float *fptr = (float *)w;
+ fptr[0] = 1.0;
+ fptr[1] = 0.0;
+ fptr[2] = 0.0;
+ fptr[3] = 0.0;
+ }
+ mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TANGENT] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
+ }
-{ //normal
- Vector<uint8_t> buffer;
- buffer.resize(sizeof(float) * 3);
- {
- uint8_t *w = buffer.ptrw();
- float *fptr = (float *)w;
- fptr[0] = 1.0;
- fptr[1] = 0.0;
- fptr[2] = 0.0;
- }
- mesh_default_rd_buffers[DEFAULT_RD_BUFFER_NORMAL] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
-}
+ { //color
+ buffer.resize(sizeof(float) * 4);
+ {
+ uint8_t *w = buffer.ptrw();
+ float *fptr = (float *)w;
+ fptr[0] = 1.0;
+ fptr[1] = 1.0;
+ fptr[2] = 1.0;
+ fptr[3] = 1.0;
+ }
+ mesh_default_rd_buffers[DEFAULT_RD_BUFFER_COLOR] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
+ }
-{ //tangent
- Vector<uint8_t> buffer;
- buffer.resize(sizeof(float) * 4);
- {
- uint8_t *w = buffer.ptrw();
- float *fptr = (float *)w;
- fptr[0] = 1.0;
- fptr[1] = 0.0;
- fptr[2] = 0.0;
- fptr[3] = 0.0;
- }
- mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TANGENT] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
-}
+ { //tex uv 1
+ buffer.resize(sizeof(float) * 2);
+ {
+ uint8_t *w = buffer.ptrw();
+ float *fptr = (float *)w;
+ fptr[0] = 0.0;
+ fptr[1] = 0.0;
+ }
+ mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
+ }
+ { //tex uv 2
+ buffer.resize(sizeof(float) * 2);
+ {
+ uint8_t *w = buffer.ptrw();
+ float *fptr = (float *)w;
+ fptr[0] = 0.0;
+ fptr[1] = 0.0;
+ }
+ mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV2] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
+ }
-{ //color
- Vector<uint8_t> buffer;
- buffer.resize(sizeof(float) * 4);
- {
- uint8_t *w = buffer.ptrw();
- float *fptr = (float *)w;
- fptr[0] = 1.0;
- fptr[1] = 1.0;
- fptr[2] = 1.0;
- fptr[3] = 1.0;
- }
- mesh_default_rd_buffers[DEFAULT_RD_BUFFER_COLOR] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
-}
+ { //bones
+ buffer.resize(sizeof(uint32_t) * 4);
+ {
+ uint8_t *w = buffer.ptrw();
+ uint32_t *fptr = (uint32_t *)w;
+ fptr[0] = 0;
+ fptr[1] = 0;
+ fptr[2] = 0;
+ fptr[3] = 0;
+ }
+ mesh_default_rd_buffers[DEFAULT_RD_BUFFER_BONES] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
+ }
-{ //tex uv 1
- Vector<uint8_t> buffer;
- buffer.resize(sizeof(float) * 2);
- {
- uint8_t *w = buffer.ptrw();
- float *fptr = (float *)w;
- fptr[0] = 0.0;
- fptr[1] = 0.0;
- }
- mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
-}
-{ //tex uv 2
- Vector<uint8_t> buffer;
- buffer.resize(sizeof(float) * 2);
- {
- uint8_t *w = buffer.ptrw();
- float *fptr = (float *)w;
- fptr[0] = 0.0;
- fptr[1] = 0.0;
+ { //weights
+ buffer.resize(sizeof(float) * 4);
+ {
+ uint8_t *w = buffer.ptrw();
+ float *fptr = (float *)w;
+ fptr[0] = 0.0;
+ fptr[1] = 0.0;
+ fptr[2] = 0.0;
+ fptr[3] = 0.0;
+ }
+ mesh_default_rd_buffers[DEFAULT_RD_BUFFER_WEIGHTS] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
+ }
}
- mesh_default_rd_buffers[DEFAULT_RD_BUFFER_TEX_UV2] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
-}
-{ //bones
- Vector<uint8_t> buffer;
- buffer.resize(sizeof(uint32_t) * 4);
{
- uint8_t *w = buffer.ptrw();
- uint32_t *fptr = (uint32_t *)w;
- fptr[0] = 0;
- fptr[1] = 0;
- fptr[2] = 0;
- fptr[3] = 0;
+ Vector<String> sdf_versions;
+ sdf_versions.push_back(""); //one only
+ giprobe_sdf_shader.initialize(sdf_versions);
+ giprobe_sdf_shader_version = giprobe_sdf_shader.version_create();
+ giprobe_sdf_shader.version_set_compute_code(giprobe_sdf_shader_version, "", "", "", Vector<String>());
+ giprobe_sdf_shader_version_shader = giprobe_sdf_shader.version_get_shader(giprobe_sdf_shader_version, 0);
+ giprobe_sdf_shader_pipeline = RD::get_singleton()->compute_pipeline_create(giprobe_sdf_shader_version_shader);
}
- mesh_default_rd_buffers[DEFAULT_RD_BUFFER_BONES] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
-}
-{ //weights
- Vector<uint8_t> buffer;
- buffer.resize(sizeof(float) * 4);
- {
- uint8_t *w = buffer.ptrw();
- float *fptr = (float *)w;
- fptr[0] = 0.0;
- fptr[1] = 0.0;
- fptr[2] = 0.0;
- fptr[3] = 0.0;
+ using_lightmap_array = true; // high end
+ if (using_lightmap_array) {
+ uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
+
+ if (textures_per_stage <= 256) {
+ lightmap_textures.resize(32);
+ } else {
+ lightmap_textures.resize(1024);
+ }
+
+ for (int i = 0; i < lightmap_textures.size(); i++) {
+ lightmap_textures.write[i] = default_rd_textures[DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE];
+ }
}
- mesh_default_rd_buffers[DEFAULT_RD_BUFFER_WEIGHTS] = RD::get_singleton()->vertex_buffer_create(buffer.size(), buffer);
-}
-}
-{
- Vector<String> sdf_versions;
- sdf_versions.push_back(""); //one only
- giprobe_sdf_shader.initialize(sdf_versions);
- giprobe_sdf_shader_version = giprobe_sdf_shader.version_create();
- giprobe_sdf_shader.version_set_compute_code(giprobe_sdf_shader_version, "", "", "", Vector<String>());
- giprobe_sdf_shader_version_shader = giprobe_sdf_shader.version_get_shader(giprobe_sdf_shader_version, 0);
- giprobe_sdf_shader_pipeline = RD::get_singleton()->compute_pipeline_create(giprobe_sdf_shader_version_shader);
-}
+ lightmap_probe_capture_update_speed = GLOBAL_GET("rendering/lightmapper/probe_capture_update_speed");
}
RasterizerStorageRD::~RasterizerStorageRD() {
-
memdelete_arr(global_variables.buffer_values);
memdelete_arr(global_variables.buffer_usage);
memdelete_arr(global_variables.buffer_dirty_regions);
diff --git a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
index f874c3baf8..fe9377192e 100644
--- a/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
+++ b/servers/rendering/rasterizer_rd/rasterizer_storage_rd.h
@@ -64,7 +64,6 @@ public:
typedef ShaderData *(*ShaderDataRequestFunction)();
struct MaterialData {
-
void update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color);
void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, RID> &p_default_textures, const Vector<ShaderCompilerRD::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color);
@@ -92,6 +91,7 @@ public:
DEFAULT_RD_TEXTURE_CUBEMAP_BLACK,
DEFAULT_RD_TEXTURE_CUBEMAP_ARRAY_BLACK,
DEFAULT_RD_TEXTURE_3D_WHITE,
+ DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE,
DEFAULT_RD_TEXTURE_MAX
};
@@ -110,7 +110,6 @@ public:
private:
/* TEXTURE API */
struct Texture {
-
enum Type {
TYPE_2D,
TYPE_LAYERED,
@@ -118,6 +117,7 @@ private:
};
Type type;
+ RS::TextureLayeredType layered_type = RS::TEXTURE_LAYERED_2D_ARRAY;
RenderingDevice::TextureType rd_type;
RID rd_texture;
@@ -147,6 +147,7 @@ private:
RID proxy_to;
Vector<RID> proxies;
+ Set<RID> lightmap_users;
RS::TextureDetectCallback detect_3d_callback = nullptr;
void *detect_3d_callback_ud = nullptr;
@@ -187,7 +188,6 @@ private:
struct DecalAtlas {
struct Texture {
-
int panorama_to_dp_users;
int users;
Rect2 uv_rect;
@@ -271,7 +271,6 @@ private:
/* Mesh */
struct Mesh {
-
struct Surface {
RS::PrimitiveType primitive = RS::PRIMITIVE_POINTS;
uint32_t format = 0;
@@ -413,7 +412,6 @@ private:
/* LIGHT */
struct Light {
-
RS::LightType type;
float param[RS::LIGHT_PARAM_MAX];
Color color = Color(1, 1, 1, 1);
@@ -438,7 +436,6 @@ private:
/* REFLECTION PROBE */
struct ReflectionProbe {
-
RS::ReflectionProbeUpdateMode update_mode = RS::REFLECTION_PROBE_UPDATE_ONCE;
int resolution = 256;
float intensity = 1.0;
@@ -461,7 +458,6 @@ private:
/* DECAL */
struct Decal {
-
Vector3 extents = Vector3(1, 1, 1);
RID textures[RS::DECAL_TEXTURE_MAX];
float emission_energy = 1.0;
@@ -483,7 +479,6 @@ private:
/* GI PROBE */
struct GIProbe {
-
RID octree_buffer;
RID data_buffer;
RID sdf_texture;
@@ -524,10 +519,42 @@ private:
mutable RID_Owner<GIProbe> gi_probe_owner;
+ /* REFLECTION PROBE */
+
+ struct Lightmap {
+ RID light_texture;
+ bool uses_spherical_harmonics = false;
+ bool interior = false;
+ AABB bounds = AABB(Vector3(), Vector3(1, 1, 1));
+ int32_t array_index = -1; //unassigned
+ PackedVector3Array points;
+ PackedColorArray point_sh;
+ PackedInt32Array tetrahedra;
+ PackedInt32Array bsp_tree;
+
+ struct BSP {
+ static const int32_t EMPTY_LEAF = INT32_MIN;
+ float plane[4];
+ int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
+ };
+
+ RasterizerScene::InstanceDependency instance_dependency;
+ };
+
+ bool using_lightmap_array; //high end uses this
+ /* for high end */
+
+ Vector<RID> lightmap_textures;
+
+ uint64_t lightmap_array_version = 0;
+
+ mutable RID_Owner<Lightmap> lightmap_owner;
+
+ float lightmap_probe_capture_update_speed = 4;
+
/* RENDER TARGET */
struct RenderTarget {
-
Size2i size;
RID framebuffer;
RID color;
@@ -568,7 +595,6 @@ private:
/* GLOBAL SHADER VARIABLES */
struct GlobalVariables {
-
enum {
BUFFER_DIRTY_REGION_SIZE = 1024
};
@@ -653,7 +679,7 @@ public:
//these two APIs can be used together or in combination with the others.
virtual RID texture_2d_placeholder_create();
- virtual RID texture_2d_layered_placeholder_create();
+ virtual RID texture_2d_layered_placeholder_create(RenderingServer::TextureLayeredType p_layered_type);
virtual RID texture_3d_placeholder_create();
virtual Ref<Image> texture_2d_get(RID p_texture) const;
@@ -1037,7 +1063,6 @@ public:
AABB light_get_aabb(RID p_light) const;
_FORCE_INLINE_ float light_get_param(RID p_light, RS::LightParam p_param) {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, 0);
@@ -1045,7 +1070,6 @@ public:
}
_FORCE_INLINE_ RID light_get_projector(RID p_light) {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, RID());
@@ -1053,7 +1077,6 @@ public:
}
_FORCE_INLINE_ Color light_get_color(RID p_light) {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, Color());
@@ -1061,7 +1084,6 @@ public:
}
_FORCE_INLINE_ Color light_get_shadow_color(RID p_light) {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, Color());
@@ -1069,7 +1091,6 @@ public:
}
_FORCE_INLINE_ uint32_t light_get_cull_mask(RID p_light) {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, 0);
@@ -1077,7 +1098,6 @@ public:
}
_FORCE_INLINE_ bool light_has_shadow(RID p_light) const {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL);
@@ -1085,7 +1105,6 @@ public:
}
_FORCE_INLINE_ bool light_is_negative(RID p_light) const {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, RS::LIGHT_DIRECTIONAL);
@@ -1093,7 +1112,6 @@ public:
}
_FORCE_INLINE_ float light_get_transmittance_bias(RID p_light) const {
-
const Light *light = light_owner.getornull(p_light);
ERR_FAIL_COND_V(!light, 0.0);
@@ -1270,23 +1288,47 @@ public:
/* LIGHTMAP CAPTURE */
- void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) {}
- AABB lightmap_capture_get_bounds(RID p_capture) const { return AABB(); }
- void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) {}
- RID lightmap_capture_create() {
- return RID();
+ virtual RID lightmap_create();
+
+ virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics);
+ virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds);
+ virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior);
+ virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree);
+ virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const;
+ virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const;
+ virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const;
+ virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const;
+ virtual AABB lightmap_get_aabb(RID p_lightmap) const;
+ virtual bool lightmap_is_interior(RID p_lightmap) const;
+ virtual void lightmap_tap_sh_light(RID p_lightmap, const Vector3 &p_point, Color *r_sh);
+ virtual void lightmap_set_probe_capture_update_speed(float p_speed);
+ _FORCE_INLINE_ float lightmap_get_probe_capture_update_speed() const {
+ return lightmap_probe_capture_update_speed;
+ }
+
+ _FORCE_INLINE_ int32_t lightmap_get_array_index(RID p_lightmap) const {
+ ERR_FAIL_COND_V(!using_lightmap_array, -1); //only for arrays
+ const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ return lm->array_index;
}
- Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const {
- return Vector<uint8_t>();
+ _FORCE_INLINE_ bool lightmap_uses_spherical_harmonics(RID p_lightmap) const {
+ ERR_FAIL_COND_V(!using_lightmap_array, false); //only for arrays
+ const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
+ return lm->uses_spherical_harmonics;
}
- void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) {}
- Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const { return Transform(); }
- void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) {}
- int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const { return 0; }
- void lightmap_capture_set_energy(RID p_capture, float p_energy) {}
- float lightmap_capture_get_energy(RID p_capture) const { return 0.0; }
- const Vector<LightmapCaptureOctree> *lightmap_capture_get_octree_ptr(RID p_capture) const {
- return nullptr;
+ _FORCE_INLINE_ uint64_t lightmap_array_get_version() const {
+ ERR_FAIL_COND_V(!using_lightmap_array, 0); //only for arrays
+ return lightmap_array_version;
+ }
+
+ _FORCE_INLINE_ int lightmap_array_get_size() const {
+ ERR_FAIL_COND_V(!using_lightmap_array, 0); //only for arrays
+ return lightmap_textures.size();
+ }
+
+ _FORCE_INLINE_ const Vector<RID> &lightmap_array_get_textures() const {
+ ERR_FAIL_COND_V(!using_lightmap_array, lightmap_textures); //only for arrays
+ return lightmap_textures;
}
/* PARTICLES */
diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp
index 2bfdb7fffe..5cc3da8d4e 100644
--- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp
+++ b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.cpp
@@ -31,23 +31,25 @@
#include "render_pipeline_vertex_format_cache_rd.h"
#include "core/os/memory.h"
-RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) {
-
+RID RenderPipelineVertexFormatCacheRD::_generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe) {
RD::PipelineMultisampleState multisample_state_version = multisample_state;
multisample_state_version.sample_count = RD::get_singleton()->framebuffer_format_get_texture_samples(p_framebuffer_format_id);
- RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, rasterization_state, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags);
+ RD::PipelineRasterizationState raster_state_version = rasterization_state;
+ raster_state_version.wireframe = p_wireframe;
+
+ RID pipeline = RD::get_singleton()->render_pipeline_create(shader, p_framebuffer_format_id, p_vertex_format_id, render_primitive, raster_state_version, multisample_state_version, depth_stencil_state, blend_state, dynamic_state_flags);
ERR_FAIL_COND_V(pipeline.is_null(), RID());
versions = (Version *)memrealloc(versions, sizeof(Version) * (version_count + 1));
versions[version_count].framebuffer_id = p_framebuffer_format_id;
versions[version_count].vertex_id = p_vertex_format_id;
+ versions[version_count].wireframe = p_wireframe;
versions[version_count].pipeline = pipeline;
version_count++;
return pipeline;
}
void RenderPipelineVertexFormatCacheRD::_clear() {
-
if (versions) {
for (uint32_t i = 0; i < version_count; i++) {
//shader may be gone, so this may not be valid
diff --git a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h
index ecb1b42b06..cf15e79586 100644
--- a/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h
+++ b/servers/rendering/rasterizer_rd/render_pipeline_vertex_format_cache_rd.h
@@ -35,7 +35,6 @@
#include "servers/rendering/rendering_device.h"
class RenderPipelineVertexFormatCacheRD {
-
SpinLock spin_lock;
RID shader;
@@ -51,13 +50,14 @@ class RenderPipelineVertexFormatCacheRD {
struct Version {
RD::VertexFormatID vertex_id;
RD::FramebufferFormatID framebuffer_id;
+ bool wireframe;
RID pipeline;
};
Version *versions;
uint32_t version_count;
- RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id);
+ RID _generate_version(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe);
void _clear();
@@ -65,7 +65,7 @@ public:
void setup(RID p_shader, RD::RenderPrimitive p_primitive, const RD::PipelineRasterizationState &p_rasterization_state, RD::PipelineMultisampleState p_multisample, const RD::PipelineDepthStencilState &p_depth_stencil_state, const RD::PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0);
void update_shader(RID p_shader);
- _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id) {
+ _FORCE_INLINE_ RID get_render_pipeline(RD::VertexFormatID p_vertex_format_id, RD::FramebufferFormatID p_framebuffer_format_id, bool p_wireframe = false) {
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_V_MSG(shader.is_null(), RID(),
"Attempted to use an unused shader variant (shader is null),");
@@ -74,13 +74,13 @@ public:
spin_lock.lock();
RID result;
for (uint32_t i = 0; i < version_count; i++) {
- if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id) {
+ if (versions[i].vertex_id == p_vertex_format_id && versions[i].framebuffer_id == p_framebuffer_format_id && versions[i].wireframe == p_wireframe) {
result = versions[i].pipeline;
spin_lock.unlock();
return result;
}
}
- result = _generate_version(p_vertex_format_id, p_framebuffer_format_id);
+ result = _generate_version(p_vertex_format_id, p_framebuffer_format_id, p_wireframe);
spin_lock.unlock();
return result;
}
diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
index 9cbff2571a..d0b91df470 100644
--- a/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.cpp
@@ -38,7 +38,6 @@
#define SL ShaderLanguage
static String _mktab(int p_level) {
-
String tb;
for (int i = 0; i < p_level; i++) {
tb += "\t";
@@ -48,7 +47,6 @@ static String _mktab(int p_level) {
}
static String _typestr(SL::DataType p_type) {
-
String type = ShaderLanguage::get_datatype_name(p_type);
if (ShaderLanguage::is_sampler_type(p_type)) {
type = type.replace("sampler", "texture"); //we use textures instead of samplers
@@ -57,42 +55,72 @@ static String _typestr(SL::DataType p_type) {
}
static int _get_datatype_size(SL::DataType p_type) {
-
switch (p_type) {
-
- case SL::TYPE_VOID: return 0;
- case SL::TYPE_BOOL: return 4;
- case SL::TYPE_BVEC2: return 8;
- case SL::TYPE_BVEC3: return 12;
- case SL::TYPE_BVEC4: return 16;
- case SL::TYPE_INT: return 4;
- case SL::TYPE_IVEC2: return 8;
- case SL::TYPE_IVEC3: return 12;
- case SL::TYPE_IVEC4: return 16;
- case SL::TYPE_UINT: return 4;
- case SL::TYPE_UVEC2: return 8;
- case SL::TYPE_UVEC3: return 12;
- case SL::TYPE_UVEC4: return 16;
- case SL::TYPE_FLOAT: return 4;
- case SL::TYPE_VEC2: return 8;
- case SL::TYPE_VEC3: return 12;
- case SL::TYPE_VEC4: return 16;
+ case SL::TYPE_VOID:
+ return 0;
+ case SL::TYPE_BOOL:
+ return 4;
+ case SL::TYPE_BVEC2:
+ return 8;
+ case SL::TYPE_BVEC3:
+ return 12;
+ case SL::TYPE_BVEC4:
+ return 16;
+ case SL::TYPE_INT:
+ return 4;
+ case SL::TYPE_IVEC2:
+ return 8;
+ case SL::TYPE_IVEC3:
+ return 12;
+ case SL::TYPE_IVEC4:
+ return 16;
+ case SL::TYPE_UINT:
+ return 4;
+ case SL::TYPE_UVEC2:
+ return 8;
+ case SL::TYPE_UVEC3:
+ return 12;
+ case SL::TYPE_UVEC4:
+ return 16;
+ case SL::TYPE_FLOAT:
+ return 4;
+ case SL::TYPE_VEC2:
+ return 8;
+ case SL::TYPE_VEC3:
+ return 12;
+ case SL::TYPE_VEC4:
+ return 16;
case SL::TYPE_MAT2:
return 32; //4 * 4 + 4 * 4
case SL::TYPE_MAT3:
return 48; // 4 * 4 + 4 * 4 + 4 * 4
- case SL::TYPE_MAT4: return 64;
- case SL::TYPE_SAMPLER2D: return 16;
- case SL::TYPE_ISAMPLER2D: return 16;
- case SL::TYPE_USAMPLER2D: return 16;
- case SL::TYPE_SAMPLER2DARRAY: return 16;
- case SL::TYPE_ISAMPLER2DARRAY: return 16;
- case SL::TYPE_USAMPLER2DARRAY: return 16;
- case SL::TYPE_SAMPLER3D: return 16;
- case SL::TYPE_ISAMPLER3D: return 16;
- case SL::TYPE_USAMPLER3D: return 16;
- case SL::TYPE_SAMPLERCUBE: return 16;
- case SL::TYPE_STRUCT: return 0;
+ case SL::TYPE_MAT4:
+ return 64;
+ case SL::TYPE_SAMPLER2D:
+ return 16;
+ case SL::TYPE_ISAMPLER2D:
+ return 16;
+ case SL::TYPE_USAMPLER2D:
+ return 16;
+ case SL::TYPE_SAMPLER2DARRAY:
+ return 16;
+ case SL::TYPE_ISAMPLER2DARRAY:
+ return 16;
+ case SL::TYPE_USAMPLER2DARRAY:
+ return 16;
+ case SL::TYPE_SAMPLER3D:
+ return 16;
+ case SL::TYPE_ISAMPLER3D:
+ return 16;
+ case SL::TYPE_USAMPLER3D:
+ return 16;
+ case SL::TYPE_SAMPLERCUBE:
+ return 16;
+ case SL::TYPE_SAMPLERCUBEARRAY:
+ return 16;
+ case SL::TYPE_STRUCT:
+ return 0;
+
case SL::TYPE_MAX: {
ERR_FAIL_V(0);
};
@@ -102,40 +130,71 @@ static int _get_datatype_size(SL::DataType p_type) {
}
static int _get_datatype_alignment(SL::DataType p_type) {
-
switch (p_type) {
-
- case SL::TYPE_VOID: return 0;
- case SL::TYPE_BOOL: return 4;
- case SL::TYPE_BVEC2: return 8;
- case SL::TYPE_BVEC3: return 16;
- case SL::TYPE_BVEC4: return 16;
- case SL::TYPE_INT: return 4;
- case SL::TYPE_IVEC2: return 8;
- case SL::TYPE_IVEC3: return 16;
- case SL::TYPE_IVEC4: return 16;
- case SL::TYPE_UINT: return 4;
- case SL::TYPE_UVEC2: return 8;
- case SL::TYPE_UVEC3: return 16;
- case SL::TYPE_UVEC4: return 16;
- case SL::TYPE_FLOAT: return 4;
- case SL::TYPE_VEC2: return 8;
- case SL::TYPE_VEC3: return 16;
- case SL::TYPE_VEC4: return 16;
- case SL::TYPE_MAT2: return 16;
- case SL::TYPE_MAT3: return 16;
- case SL::TYPE_MAT4: return 16;
- case SL::TYPE_SAMPLER2D: return 16;
- case SL::TYPE_ISAMPLER2D: return 16;
- case SL::TYPE_USAMPLER2D: return 16;
- case SL::TYPE_SAMPLER2DARRAY: return 16;
- case SL::TYPE_ISAMPLER2DARRAY: return 16;
- case SL::TYPE_USAMPLER2DARRAY: return 16;
- case SL::TYPE_SAMPLER3D: return 16;
- case SL::TYPE_ISAMPLER3D: return 16;
- case SL::TYPE_USAMPLER3D: return 16;
- case SL::TYPE_SAMPLERCUBE: return 16;
- case SL::TYPE_STRUCT: return 0;
+ case SL::TYPE_VOID:
+ return 0;
+ case SL::TYPE_BOOL:
+ return 4;
+ case SL::TYPE_BVEC2:
+ return 8;
+ case SL::TYPE_BVEC3:
+ return 16;
+ case SL::TYPE_BVEC4:
+ return 16;
+ case SL::TYPE_INT:
+ return 4;
+ case SL::TYPE_IVEC2:
+ return 8;
+ case SL::TYPE_IVEC3:
+ return 16;
+ case SL::TYPE_IVEC4:
+ return 16;
+ case SL::TYPE_UINT:
+ return 4;
+ case SL::TYPE_UVEC2:
+ return 8;
+ case SL::TYPE_UVEC3:
+ return 16;
+ case SL::TYPE_UVEC4:
+ return 16;
+ case SL::TYPE_FLOAT:
+ return 4;
+ case SL::TYPE_VEC2:
+ return 8;
+ case SL::TYPE_VEC3:
+ return 16;
+ case SL::TYPE_VEC4:
+ return 16;
+ case SL::TYPE_MAT2:
+ return 16;
+ case SL::TYPE_MAT3:
+ return 16;
+ case SL::TYPE_MAT4:
+ return 16;
+ case SL::TYPE_SAMPLER2D:
+ return 16;
+ case SL::TYPE_ISAMPLER2D:
+ return 16;
+ case SL::TYPE_USAMPLER2D:
+ return 16;
+ case SL::TYPE_SAMPLER2DARRAY:
+ return 16;
+ case SL::TYPE_ISAMPLER2DARRAY:
+ return 16;
+ case SL::TYPE_USAMPLER2DARRAY:
+ return 16;
+ case SL::TYPE_SAMPLER3D:
+ return 16;
+ case SL::TYPE_ISAMPLER3D:
+ return 16;
+ case SL::TYPE_USAMPLER3D:
+ return 16;
+ case SL::TYPE_SAMPLERCUBE:
+ return 16;
+ case SL::TYPE_SAMPLERCUBEARRAY:
+ return 16;
+ case SL::TYPE_STRUCT:
+ return 0;
case SL::TYPE_MAX: {
ERR_FAIL_V(0);
}
@@ -143,49 +202,53 @@ static int _get_datatype_alignment(SL::DataType p_type) {
ERR_FAIL_V(0);
}
-static String _interpstr(SL::DataInterpolation p_interp) {
+static String _interpstr(SL::DataInterpolation p_interp) {
switch (p_interp) {
- case SL::INTERPOLATION_FLAT: return "flat ";
- case SL::INTERPOLATION_SMOOTH: return "";
+ case SL::INTERPOLATION_FLAT:
+ return "flat ";
+ case SL::INTERPOLATION_SMOOTH:
+ return "";
}
return "";
}
static String _prestr(SL::DataPrecision p_pres) {
-
switch (p_pres) {
- case SL::PRECISION_LOWP: return "lowp ";
- case SL::PRECISION_MEDIUMP: return "mediump ";
- case SL::PRECISION_HIGHP: return "highp ";
- case SL::PRECISION_DEFAULT: return "";
+ case SL::PRECISION_LOWP:
+ return "lowp ";
+ case SL::PRECISION_MEDIUMP:
+ return "mediump ";
+ case SL::PRECISION_HIGHP:
+ return "highp ";
+ case SL::PRECISION_DEFAULT:
+ return "";
}
return "";
}
static String _qualstr(SL::ArgumentQualifier p_qual) {
-
switch (p_qual) {
- case SL::ARGUMENT_QUALIFIER_IN: return "";
- case SL::ARGUMENT_QUALIFIER_OUT: return "out ";
- case SL::ARGUMENT_QUALIFIER_INOUT: return "inout ";
+ case SL::ARGUMENT_QUALIFIER_IN:
+ return "";
+ case SL::ARGUMENT_QUALIFIER_OUT:
+ return "out ";
+ case SL::ARGUMENT_QUALIFIER_INOUT:
+ return "inout ";
}
return "";
}
static String _opstr(SL::Operator p_op) {
-
return SL::get_operator_text(p_op);
}
static String _mkid(const String &p_id) {
-
String id = "m_" + p_id.replace("__", "_dus_");
return id.replace("__", "_dus_"); //doubleunderscore is reserved in glsl
}
static String f2sp0(float p_float) {
-
String num = rtoss(p_float);
if (num.find(".") == -1 && num.find("e") == -1) {
num += ".0";
@@ -194,17 +257,17 @@ static String f2sp0(float p_float) {
}
static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNode::Value> &p_values) {
-
switch (p_type) {
- case SL::TYPE_BOOL: return p_values[0].boolean ? "true" : "false";
+ case SL::TYPE_BOOL:
+ return p_values[0].boolean ? "true" : "false";
case SL::TYPE_BVEC2:
case SL::TYPE_BVEC3:
case SL::TYPE_BVEC4: {
-
String text = "bvec" + itos(p_type - SL::TYPE_BOOL + 1) + "(";
for (int i = 0; i < p_values.size(); i++) {
- if (i > 0)
+ if (i > 0) {
text += ",";
+ }
text += p_values[i].boolean ? "true" : "false";
}
@@ -212,15 +275,16 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
return text;
}
- case SL::TYPE_INT: return itos(p_values[0].sint);
+ case SL::TYPE_INT:
+ return itos(p_values[0].sint);
case SL::TYPE_IVEC2:
case SL::TYPE_IVEC3:
case SL::TYPE_IVEC4: {
-
String text = "ivec" + itos(p_type - SL::TYPE_INT + 1) + "(";
for (int i = 0; i < p_values.size(); i++) {
- if (i > 0)
+ if (i > 0) {
text += ",";
+ }
text += itos(p_values[i].sint);
}
@@ -228,30 +292,32 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
return text;
} break;
- case SL::TYPE_UINT: return itos(p_values[0].uint) + "u";
+ case SL::TYPE_UINT:
+ return itos(p_values[0].uint) + "u";
case SL::TYPE_UVEC2:
case SL::TYPE_UVEC3:
case SL::TYPE_UVEC4: {
-
String text = "uvec" + itos(p_type - SL::TYPE_UINT + 1) + "(";
for (int i = 0; i < p_values.size(); i++) {
- if (i > 0)
+ if (i > 0) {
text += ",";
+ }
text += itos(p_values[i].uint) + "u";
}
text += ")";
return text;
} break;
- case SL::TYPE_FLOAT: return f2sp0(p_values[0].real);
+ case SL::TYPE_FLOAT:
+ return f2sp0(p_values[0].real);
case SL::TYPE_VEC2:
case SL::TYPE_VEC3:
case SL::TYPE_VEC4: {
-
String text = "vec" + itos(p_type - SL::TYPE_FLOAT + 1) + "(";
for (int i = 0; i < p_values.size(); i++) {
- if (i > 0)
+ if (i > 0) {
text += ",";
+ }
text += f2sp0(p_values[i].real);
}
@@ -262,11 +328,11 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
case SL::TYPE_MAT2:
case SL::TYPE_MAT3:
case SL::TYPE_MAT4: {
-
String text = "mat" + itos(p_type - SL::TYPE_MAT2 + 2) + "(";
for (int i = 0; i < p_values.size(); i++) {
- if (i > 0)
+ if (i > 0) {
text += ",";
+ }
text += f2sp0(p_values[i].real);
}
@@ -274,7 +340,8 @@ static String get_constant_text(SL::DataType p_type, const Vector<SL::ConstantNo
return text;
} break;
- default: ERR_FAIL_V(String());
+ default:
+ ERR_FAIL_V(String());
}
}
@@ -291,7 +358,6 @@ String ShaderCompilerRD::_get_sampler_name(ShaderLanguage::TextureFilter p_filte
}
void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) {
-
int fidx = -1;
for (int i = 0; i < p_node->functions.size(); i++) {
@@ -304,7 +370,6 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S
ERR_FAIL_COND(fidx == -1);
for (Set<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) {
-
if (added.has(E->get())) {
continue; //was added already
}
@@ -331,9 +396,9 @@ void ShaderCompilerRD::_dump_function_deps(const SL::ShaderNode *p_node, const S
header = _typestr(fnode->return_type) + " " + _mkid(fnode->name) + "(";
}
for (int i = 0; i < fnode->arguments.size(); i++) {
-
- if (i > 0)
+ if (i > 0) {
header += ", ";
+ }
if (fnode->arguments[i].type == SL::TYPE_STRUCT) {
header += _qualstr(fnode->arguments[i].qualifier) + _mkid(fnode->arguments[i].type_str) + " " + _mkid(fnode->arguments[i].name);
} else {
@@ -415,19 +480,14 @@ static String _get_global_variable_from_type_and_index(const String &p_buffer, c
}
String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning) {
-
String code;
switch (p_node->type) {
-
case SL::Node::TYPE_SHADER: {
-
SL::ShaderNode *pnode = (SL::ShaderNode *)p_node;
for (int i = 0; i < pnode->render_modes.size(); i++) {
-
if (p_default_actions.render_mode_defines.has(pnode->render_modes[i]) && !used_rmode_defines.has(pnode->render_modes[i])) {
-
r_gen_code.defines.push_back(p_default_actions.render_mode_defines[pnode->render_modes[i]]);
used_rmode_defines.insert(pnode->render_modes[i]);
}
@@ -445,7 +505,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
// structs
for (int i = 0; i < pnode->vstructs.size(); i++) {
-
SL::StructNode *st = pnode->vstructs[i].shader_struct;
String struct_code;
@@ -481,11 +540,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
int max_uniforms = 0;
for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) {
-
if (SL::is_sampler_type(E->get().type)) {
max_texture_uniforms++;
} else {
-
if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) {
continue; //instances are indexed directly, dont need index uniforms
}
@@ -505,7 +562,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
bool uses_uniforms = false;
for (Map<StringName, SL::ShaderNode::Uniform>::Element *E = pnode->uniforms.front(); E; E = E->next()) {
-
String ucode;
if (E->get().scope == SL::ShaderNode::Uniform::SCOPE_INSTANCE) {
@@ -547,7 +603,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
r_gen_code.texture_uniforms.write[E->get().texture_order] = texture;
} else {
if (!uses_uniforms) {
-
r_gen_code.defines.push_back(String("#define USE_MATERIAL_UNIFORMS\n"));
uses_uniforms = true;
}
@@ -573,7 +628,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
// add up
int offset = 0;
for (int i = 0; i < uniform_sizes.size(); i++) {
-
int align = offset % uniform_alignments[i];
if (align != 0) {
@@ -593,9 +647,7 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
#else
// add up
for (int i = 0; i < uniform_sizes.size(); i++) {
-
if (i > 0) {
-
int align = uniform_sizes[i - 1] % uniform_alignments[i];
if (align != 0) {
uniform_sizes[i - 1] += uniform_alignments[i] - align;
@@ -607,7 +659,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
//offset
r_gen_code.uniform_offsets.resize(uniform_sizes.size());
for (int i = 0; i < uniform_sizes.size(); i++) {
-
if (i > 0)
r_gen_code.uniform_offsets[i] = uniform_sizes[i - 1];
else
@@ -633,7 +684,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
uint32_t index = p_default_actions.base_varying_index;
for (Map<StringName, SL::ShaderNode::Varying>::Element *E = pnode->varyings.front(); E; E = E->next()) {
-
String vcode;
String interp_mode = _interpstr(E->get().interpolation);
vcode += _prestr(E->get().precision);
@@ -650,18 +700,19 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
index++;
}
- for (Map<StringName, SL::ShaderNode::Constant>::Element *E = pnode->constants.front(); E; E = E->next()) {
+ for (int i = 0; i < pnode->vconstants.size(); i++) {
+ const SL::ShaderNode::Constant &cnode = pnode->vconstants[i];
String gcode;
gcode += "const ";
- gcode += _prestr(E->get().precision);
- if (E->get().type == SL::TYPE_STRUCT) {
- gcode += _mkid(E->get().type_str);
+ gcode += _prestr(cnode.precision);
+ if (cnode.type == SL::TYPE_STRUCT) {
+ gcode += _mkid(cnode.type_str);
} else {
- gcode += _typestr(E->get().type);
+ gcode += _typestr(cnode.type);
}
- gcode += " " + _mkid(E->key());
+ gcode += " " + _mkid(String(cnode.name));
gcode += "=";
- gcode += _dump_node_code(E->get().initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
+ gcode += _dump_node_code(cnode.initializer, p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
gcode += ";\n";
r_gen_code.vertex_global += gcode;
r_gen_code.fragment_global += gcode;
@@ -684,7 +735,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
Set<StringName> added_fragment; //share for light
for (int i = 0; i < pnode->functions.size(); i++) {
-
SL::FunctionNode *fnode = pnode->functions[i].function;
function = fnode;
@@ -692,19 +742,16 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
current_func_name = fnode->name;
if (fnode->name == vertex_name) {
-
_dump_function_deps(pnode, fnode->name, function_code, r_gen_code.vertex_global, added_vtx);
r_gen_code.vertex = function_code[vertex_name];
}
if (fnode->name == fragment_name) {
-
_dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment);
r_gen_code.fragment = function_code[fragment_name];
}
if (fnode->name == light_name) {
-
_dump_function_deps(pnode, fnode->name, function_code, r_gen_code.fragment_global, added_fragment);
r_gen_code.light = function_code[light_name];
}
@@ -714,10 +761,8 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
//code+=dump_node_code(pnode->body,p_level);
} break;
case SL::Node::TYPE_STRUCT: {
-
} break;
case SL::Node::TYPE_FUNCTION: {
-
} break;
case SL::Node::TYPE_BLOCK: {
SL::BlockNode *bnode = (SL::BlockNode *)p_node;
@@ -728,7 +773,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
}
for (int i = 0; i < bnode->statements.size(); i++) {
-
String scode = _dump_node_code(bnode->statements[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
if (bnode->statements[i]->type == SL::Node::TYPE_CONTROL_FLOW || bnode->single_statement) {
@@ -790,9 +834,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
used_flag_pointers.insert(vnode->name);
}
- if (p_default_actions.renames.has(vnode->name))
+ if (p_default_actions.renames.has(vnode->name)) {
code = p_default_actions.renames[vnode->name];
- else {
+ } else {
if (shader->uniforms.has(vnode->name)) {
//its a uniform!
const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[vnode->name];
@@ -850,7 +894,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
code += ")";
} break;
case SL::Node::TYPE_ARRAY_DECLARATION: {
-
SL::ArrayDeclarationNode *adnode = (SL::ArrayDeclarationNode *)p_node;
String declaration;
if (adnode->is_const) {
@@ -916,10 +959,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
used_flag_pointers.insert(anode->name);
}
- if (p_default_actions.renames.has(anode->name))
+ if (p_default_actions.renames.has(anode->name)) {
code = p_default_actions.renames[anode->name];
- else
+ } else {
code = _mkid(anode->name);
+ }
if (anode->call_expression != nullptr) {
code += ".";
@@ -951,7 +995,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
SL::OperatorNode *onode = (SL::OperatorNode *)p_node;
switch (onode->op) {
-
case SL::OP_ASSIGN:
case SL::OP_ASSIGN_ADD:
case SL::OP_ASSIGN_SUB:
@@ -979,7 +1022,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
case SL::OP_CALL:
case SL::OP_STRUCT:
case SL::OP_CONSTRUCT: {
-
ERR_FAIL_COND_V(onode->arguments[0]->type != SL::Node::TYPE_VARIABLE, String());
SL::VariableNode *vnode = (SL::VariableNode *)onode->arguments[0];
@@ -990,7 +1032,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
} else if (onode->op == SL::OP_CONSTRUCT) {
code += String(vnode->name);
} else {
-
if (internal_functions.has(vnode->name)) {
code += vnode->name;
is_texture_func = texture_functions.has(vnode->name);
@@ -1004,11 +1045,11 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
code += "(";
for (int i = 1; i < onode->arguments.size(); i++) {
- if (i > 1)
+ if (i > 1) {
code += ", ";
+ }
String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
if (is_texture_func && i == 1 && onode->arguments[i]->type == SL::Node::TYPE_VARIABLE) {
-
//need to map from texture to sampler in order to sample
const SL::VariableNode *varnode = static_cast<const SL::VariableNode *>(onode->arguments[i]);
@@ -1054,7 +1095,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
code += ")";
} break;
case SL::OP_INDEX: {
-
code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += "[";
code += _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
@@ -1062,7 +1102,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
} break;
case SL::OP_SELECT_IF: {
-
code += "(";
code += _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
code += "?";
@@ -1074,7 +1113,6 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
} break;
default: {
-
code = "(" + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")";
break;
}
@@ -1084,37 +1122,29 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
case SL::Node::TYPE_CONTROL_FLOW: {
SL::ControlFlowNode *cfnode = (SL::ControlFlowNode *)p_node;
if (cfnode->flow_op == SL::FLOW_OP_IF) {
-
code += _mktab(p_level) + "if (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
if (cfnode->blocks.size() == 2) {
-
code += _mktab(p_level) + "else\n";
code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
}
} else if (cfnode->flow_op == SL::FLOW_OP_SWITCH) {
-
code += _mktab(p_level) + "switch (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
} else if (cfnode->flow_op == SL::FLOW_OP_CASE) {
-
code += _mktab(p_level) + "case " + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ":\n";
code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
} else if (cfnode->flow_op == SL::FLOW_OP_DEFAULT) {
-
code += _mktab(p_level) + "default:\n";
code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
} else if (cfnode->flow_op == SL::FLOW_OP_DO) {
-
code += _mktab(p_level) + "do";
code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ");";
} else if (cfnode->flow_op == SL::FLOW_OP_WHILE) {
-
code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ")\n";
code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
} else if (cfnode->flow_op == SL::FLOW_OP_FOR) {
-
String left = _dump_node_code(cfnode->blocks[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
String middle = _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
String right = _dump_node_code(cfnode->expressions[1], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
@@ -1122,14 +1152,12 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
code += _dump_node_code(cfnode->blocks[1], p_level + 1, r_gen_code, p_actions, p_default_actions, p_assigning);
} else if (cfnode->flow_op == SL::FLOW_OP_RETURN) {
-
if (cfnode->expressions.size()) {
code = "return " + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions, p_assigning) + ";";
} else {
code = "return;";
}
} else if (cfnode->flow_op == SL::FLOW_OP_DISCARD) {
-
if (p_actions.usage_flag_pointers.has("DISCARD") && !used_flag_pointers.has("DISCARD")) {
*p_actions.usage_flag_pointers["DISCARD"] = true;
used_flag_pointers.insert("DISCARD");
@@ -1137,10 +1165,8 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
code = "discard;";
} else if (cfnode->flow_op == SL::FLOW_OP_CONTINUE) {
-
code = "continue;";
} else if (cfnode->flow_op == SL::FLOW_OP_BREAK) {
-
code = "break;";
}
@@ -1166,11 +1192,9 @@ ShaderLanguage::DataType ShaderCompilerRD::_get_variable_type(const StringName &
}
Error ShaderCompilerRD::compile(RS::ShaderMode p_mode, const String &p_code, IdentifierActions *p_actions, const String &p_path, GeneratedCode &r_gen_code) {
-
Error err = parser.compile(p_code, ShaderTypes::get_singleton()->get_functions(p_mode), ShaderTypes::get_singleton()->get_modes(p_mode), ShaderTypes::get_singleton()->get_types(), _get_variable_type);
if (err != OK) {
-
Vector<String> shader = p_code.split("\n");
for (int i = 0; i < shader.size(); i++) {
print_line(itos(i + 1) + " " + shader[i]);
diff --git a/servers/rendering/rasterizer_rd/shader_compiler_rd.h b/servers/rendering/rasterizer_rd/shader_compiler_rd.h
index 16d53197a7..eaad34b8cd 100644
--- a/servers/rendering/rasterizer_rd/shader_compiler_rd.h
+++ b/servers/rendering/rasterizer_rd/shader_compiler_rd.h
@@ -39,7 +39,6 @@
class ShaderCompilerRD {
public:
struct IdentifierActions {
-
Map<StringName, Pair<int *, int>> render_mode_values;
Map<StringName, bool *> render_mode_flags;
Map<StringName, bool *> usage_flag_pointers;
@@ -49,7 +48,6 @@ public:
};
struct GeneratedCode {
-
Vector<String> defines;
struct Texture {
StringName name;
@@ -77,7 +75,6 @@ public:
};
struct DefaultIdentifierActions {
-
Map<StringName, String> renames;
Map<StringName, String> render_mode_defines;
Map<StringName, String> usage_defines;
diff --git a/servers/rendering/rasterizer_rd/shader_rd.cpp b/servers/rendering/rasterizer_rd/shader_rd.cpp
index d60a58813e..8c57651263 100644
--- a/servers/rendering/rasterizer_rd/shader_rd.cpp
+++ b/servers/rendering/rasterizer_rd/shader_rd.cpp
@@ -35,7 +35,6 @@
#include "servers/rendering/rendering_device.h"
void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, const char *p_compute_code, const char *p_name) {
-
name = p_name;
//split vertex and shader code (thank you, shader compiler programmers from you know what company).
if (p_vertex_code) {
@@ -64,7 +63,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con
if (cpos == -1) {
vertex_code1 = code.ascii();
} else {
-
vertex_code1 = code.substr(0, cpos).ascii();
String code2 = code.substr(cpos + globals_tag.length(), code.length());
@@ -72,7 +70,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con
if (cpos == -1) {
vertex_code2 = code2.ascii();
} else {
-
vertex_code2 = code2.substr(0, cpos).ascii();
vertex_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii();
}
@@ -106,7 +103,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con
if (cpos == -1) {
fragment_code1 = code.ascii();
} else {
-
fragment_code1 = code.substr(0, cpos).ascii();
//print_line("CODE1:\n"+String(fragment_code1.get_data()));
@@ -116,7 +112,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con
if (cpos == -1) {
fragment_code2 = code2.ascii();
} else {
-
fragment_code2 = code2.substr(0, cpos).ascii();
//print_line("CODE2:\n"+String(fragment_code2.get_data()));
@@ -126,7 +121,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con
if (cpos == -1) {
fragment_code3 = code3.ascii();
} else {
-
fragment_code3 = code3.substr(0, cpos).ascii();
//print_line("CODE3:\n"+String(fragment_code3.get_data()));
fragment_code4 = code3.substr(cpos + code_tag.length(), code3.length()).ascii();
@@ -165,7 +159,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con
if (cpos == -1) {
compute_code1 = code.ascii();
} else {
-
compute_code1 = code.substr(0, cpos).ascii();
String code2 = code.substr(cpos + globals_tag.length(), code.length());
@@ -173,7 +166,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con
if (cpos == -1) {
compute_code2 = code2.ascii();
} else {
-
compute_code2 = code2.substr(0, cpos).ascii();
compute_code3 = code2.substr(cpos + code_tag.length(), code2.length()).ascii();
}
@@ -183,7 +175,6 @@ void ShaderRD::setup(const char *p_vertex_code, const char *p_fragment_code, con
}
RID ShaderRD::version_create() {
-
//initialize() was never called
ERR_FAIL_COND_V(variant_defines.size() == 0, RID());
@@ -208,7 +199,6 @@ void ShaderRD::_clear_version(Version *p_version) {
}
void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
-
Vector<RD::ShaderStageData> stages;
String error;
@@ -250,7 +240,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
if (stage.spir_v.size() == 0) {
build_ok = false;
} else {
-
stage.shader_stage = RD::SHADER_STAGE_VERTEX;
stages.push_back(stage);
}
@@ -295,7 +284,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
if (stage.spir_v.size() == 0) {
build_ok = false;
} else {
-
stage.shader_stage = RD::SHADER_STAGE_FRAGMENT;
stages.push_back(stage);
}
@@ -336,7 +324,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
if (stage.spir_v.size() == 0) {
build_ok = false;
} else {
-
stage.shader_stage = RD::SHADER_STAGE_COMPUTE;
stages.push_back(stage);
}
@@ -361,7 +348,6 @@ void ShaderRD::_compile_variant(uint32_t p_variant, Version *p_version) {
}
void ShaderRD::_compile_version(Version *p_version) {
-
_clear_version(p_version);
p_version->valid = false;
@@ -373,7 +359,6 @@ void ShaderRD::_compile_version(Version *p_version) {
RasterizerRD::thread_work_pool.do_work(variant_defines.size(), this, &ShaderRD::_compile_variant, p_version);
#else
for (int i = 0; i < variant_defines.size(); i++) {
-
_compile_variant(i, p_version);
}
#endif
@@ -402,7 +387,6 @@ void ShaderRD::_compile_version(Version *p_version) {
}
void ShaderRD::version_set_code(RID p_version, const String &p_uniforms, const String &p_vertex_globals, const String &p_vertex_code, const String &p_fragment_globals, const String &p_fragment_light, const String &p_fragment_code, const Vector<String> &p_custom_defines) {
-
ERR_FAIL_COND(is_compute);
Version *version = version_owner.getornull(p_version);
@@ -427,7 +411,6 @@ void ShaderRD::version_set_code(RID p_version, const String &p_uniforms, const S
}
void ShaderRD::version_set_compute_code(RID p_version, const String &p_uniforms, const String &p_compute_globals, const String &p_compute_code, const Vector<String> &p_custom_defines) {
-
ERR_FAIL_COND(!is_compute);
Version *version = version_owner.getornull(p_version);
@@ -460,7 +443,6 @@ bool ShaderRD::version_is_valid(RID p_version) {
}
bool ShaderRD::version_free(RID p_version) {
-
if (version_owner.owns(p_version)) {
Version *version = version_owner.getornull(p_version);
_clear_version(version);
@@ -477,7 +459,6 @@ void ShaderRD::initialize(const Vector<String> &p_variant_defines, const String
ERR_FAIL_COND(p_variant_defines.size() == 0);
general_defines = p_general_defines.utf8();
for (int i = 0; i < p_variant_defines.size(); i++) {
-
variant_defines.push_back(p_variant_defines[i].utf8());
}
}
diff --git a/servers/rendering/rasterizer_rd/shader_rd.h b/servers/rendering/rasterizer_rd/shader_rd.h
index 6635b08cc8..d9bb068ba6 100644
--- a/servers/rendering/rasterizer_rd/shader_rd.h
+++ b/servers/rendering/rasterizer_rd/shader_rd.h
@@ -43,7 +43,6 @@
*/
class ShaderRD {
-
//versions
CharString general_defines;
Vector<CharString> variant_defines;
diff --git a/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl b/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl
index 7153fe6b17..63f086a83d 100644
--- a/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/bokeh_dof.glsl
@@ -1,5 +1,4 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
@@ -8,7 +7,6 @@ VERSION_DEFINES
#define BLOCK_SIZE 8
layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in;
-/* clang-format on */
#ifdef MODE_GEN_BLUR_SIZE
layout(rgba16f, set = 0, binding = 0) uniform restrict image2D color_image;
@@ -69,7 +67,6 @@ float get_depth_at_pos(vec2 uv) {
}
float get_blur_size(float depth) {
-
if (params.blur_near_active && depth < params.blur_near_begin) {
return -(1.0 - smoothstep(params.blur_near_end, params.blur_near_begin, depth)) * params.blur_size - DEPTH_GAP; //near blur is negative
}
@@ -95,7 +92,6 @@ float hash12n(vec2 p) {
#if defined(MODE_BOKEH_BOX) || defined(MODE_BOKEH_HEXAGONAL)
vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) {
-
dir *= pixel_size;
vec4 color = texture(color_texture, uv);
@@ -109,7 +105,6 @@ vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) {
}
for (int i = -params.blur_steps; i <= params.blur_steps; i++) {
-
if (i == 0) {
continue;
}
@@ -141,7 +136,6 @@ vec4 weighted_filter_dir(vec2 dir, vec2 uv, vec2 pixel_size) {
#endif
void main() {
-
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
if (any(greaterThan(pos, params.size))) { //too large, do nothing
@@ -218,7 +212,6 @@ void main() {
float radius = params.blur_scale;
for (float ang = 0.0; radius < params.blur_size; ang += GOLDEN_ANGLE) {
-
vec2 suv = uv + vec2(cos(ang), sin(ang)) * pixel_size * radius;
vec4 sample_color = texture(color_texture, suv);
float sample_size = abs(sample_color.a);
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas.glsl b/servers/rendering/rasterizer_rd/shaders/canvas.glsl
index 28135fce31..e33b3face9 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/canvas.glsl
@@ -1,5 +1,4 @@
-/* clang-format off */
-[vertex]
+#[vertex]
#version 450
@@ -7,7 +6,6 @@ VERSION_DEFINES
#ifdef USE_ATTRIBUTES
layout(location = 0) in vec2 vertex_attrib;
-/* clang-format on */
layout(location = 3) in vec4 color_attrib;
layout(location = 4) in vec2 uv_attrib;
@@ -40,7 +38,6 @@ VERTEX_SHADER_GLOBALS
/* clang-format on */
void main() {
-
vec4 instance_custom = vec4(0.0);
#ifdef USE_PRIMITIVE
@@ -88,7 +85,6 @@ void main() {
#if 0
if (draw_data.flags & FLAGS_INSTANCING_ENABLED) {
-
uint offset = draw_data.flags & FLAGS_INSTANCING_STRIDE_MASK;
offset *= gl_InstanceIndex;
mat4 instance_xform = mat4(
@@ -149,7 +145,6 @@ VERTEX_SHADER_CODE
color_interp = color;
if (bool(draw_data.flags & FLAGS_USE_PIXEL_SNAP)) {
-
vertex = floor(vertex + 0.5);
// precision issue on some hardware creates artifacts within texture
// offset uv by a small amount to avoid
@@ -160,7 +155,6 @@ VERTEX_SHADER_CODE
#if 0
if (bool(draw_data.flags & FLAGS_USE_SKELETON) && bone_weights != vec4(0.0)) { //must be a valid bone
//skeleton transform
-
ivec4 bone_indicesi = ivec4(bone_indices);
uvec2 tex_ofs = bone_indicesi.x * 2;
@@ -211,8 +205,7 @@ VERTEX_SHADER_CODE
#endif
}
-/* clang-format off */
-[fragment]
+#[fragment]
#version 450
@@ -221,7 +214,6 @@ VERSION_DEFINES
#include "canvas_uniforms_inc.glsl"
layout(location = 0) in vec2 uv_interp;
-/* clang-format on */
layout(location = 1) in vec4 color_interp;
layout(location = 2) in vec2 vertex_interp;
@@ -258,7 +250,6 @@ vec4 light_compute(
vec2 screen_uv,
vec2 uv,
vec4 color) {
-
vec4 light = vec4(0.0);
/* clang-format off */
LIGHT_SHADER_CODE
@@ -271,7 +262,6 @@ LIGHT_SHADER_CODE
#ifdef USE_NINEPATCH
float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, int np_repeat, inout int draw_center) {
-
float tex_size = 1.0 / tex_pixel_size;
if (pixel < margin_begin) {
@@ -313,7 +303,6 @@ float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, flo
#endif
void main() {
-
vec4 color = color_interp;
vec2 uv = uv_interp;
vec2 vertex = vertex_interp;
@@ -335,7 +324,6 @@ void main() {
#endif
if (bool(draw_data.flags & FLAGS_CLIP_RECT_UV)) {
-
uv = clamp(uv, draw_data.src_rect.xy, draw_data.src_rect.xy + abs(draw_data.src_rect.zw));
}
@@ -348,7 +336,6 @@ void main() {
vec3 normal;
#if defined(NORMAL_USED)
-
bool normal_used = true;
#else
bool normal_used = false;
@@ -458,7 +445,6 @@ FRAGMENT_SHADER_CODE
light_color.rgb *= light_base_color.rgb * light_base_color.a;
if (normal_used) {
-
vec3 light_pos = vec3(light_array.data[light_base].position, light_array.data[light_base].height);
vec3 pos = light_vertex;
vec3 light_vec = normalize(light_pos - pos);
@@ -490,7 +476,6 @@ FRAGMENT_SHADER_CODE
}
if (bool(light_array.data[light_base].flags & LIGHT_FLAGS_HAS_SHADOW)) {
-
vec2 shadow_pos = (vec4(shadow_vertex, 0.0, 1.0) * mat4(light_array.data[light_base].shadow_matrix[0], light_array.data[light_base].shadow_matrix[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))).xy; //multiply inverse given its transposed. Optimizer removes useless operations.
vec2 pos_norm = normalize(shadow_pos);
diff --git a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl b/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl
index 7b30cc8fe9..99e70a1976 100644
--- a/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/canvas_occlusion.glsl
@@ -1,13 +1,10 @@
-/* clang-format off */
-[vertex]
+#[vertex]
#version 450
layout(location = 0) in highp vec3 vertex;
-/* clang-format on */
layout(push_constant, binding = 0, std430) uniform Constants {
-
mat4 projection;
mat2x4 modelview;
vec2 direction;
@@ -18,23 +15,19 @@ constants;
layout(location = 0) out highp float depth;
void main() {
-
highp vec4 vtx = vec4(vertex, 1.0) * mat4(constants.modelview[0], constants.modelview[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
depth = dot(constants.direction, vtx.xy);
gl_Position = constants.projection * vtx;
}
-/* clang-format off */
-[fragment]
+#[fragment]
#version 450
layout(location = 0) in highp float depth;
-/* clang-format on */
layout(location = 0) out highp float distance_buf;
void main() {
-
distance_buf = depth;
}
diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl
index 2d7661f65f..eb39c28fa9 100644
--- a/servers/rendering/rasterizer_rd/shaders/copy.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl
@@ -1,12 +1,10 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-/* clang-format on */
#define FLAG_HORIZONTAL (1 << 0)
#define FLAG_USE_BLUR_SECTION (1 << 1)
@@ -39,7 +37,13 @@ layout(push_constant, binding = 1, std430) uniform Params {
}
params;
+#ifdef MODE_CUBEMAP_ARRAY_TO_PANORAMA
+layout(set = 0, binding = 0) uniform samplerCubeArray source_color;
+#elif defined(MODE_CUBEMAP_TO_PANORAMA)
+layout(set = 0, binding = 0) uniform samplerCube source_color;
+#else
layout(set = 0, binding = 0) uniform sampler2D source_color;
+#endif
#ifdef GLOW_USE_AUTO_EXPOSURE
layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
@@ -54,10 +58,9 @@ layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_bu
#endif
void main() {
-
// Pixel being shaded
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThan(pos, params.section.zw))) { //too large, do nothing
+ if (any(greaterThanEqual(pos, params.section.zw))) { //too large, do nothing
return;
}
@@ -78,7 +81,6 @@ void main() {
//Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect
if (bool(params.flags & FLAG_HORIZONTAL)) {
-
ivec2 base_pos = (pos + params.section.xy) << 1;
vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.214607;
color += texelFetch(source_color, base_pos + ivec2(1, 0), 0) * 0.189879;
@@ -89,7 +91,6 @@ void main() {
color += texelFetch(source_color, base_pos + ivec2(-3, 0), 0) * 0.071303;
imageStore(dest_buffer, pos + params.target, color);
} else {
-
ivec2 base_pos = (pos + params.section.xy);
vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.38774;
color += texelFetch(source_color, base_pos + ivec2(0, 1), 0) * 0.24477;
@@ -115,7 +116,6 @@ void main() {
vec4 color = vec4(0.0);
if (bool(params.flags & FLAG_HORIZONTAL)) {
-
ivec2 base_pos = (pos + params.section.xy) << 1;
ivec2 section_begin = params.section.xy << 1;
ivec2 section_end = section_begin + (params.section.zw << 1);
@@ -129,7 +129,6 @@ void main() {
GLOW_ADD(ivec2(-3, 0), 0.106595);
color *= params.glow_strength;
} else {
-
ivec2 base_pos = pos + params.section.xy;
ivec2 section_begin = params.section.xy;
ivec2 section_end = section_begin + params.section.zw;
@@ -217,4 +216,25 @@ void main() {
imageStore(dest_buffer, pos + params.target, color);
#endif
+
+#if defined(MODE_CUBEMAP_TO_PANORAMA) || defined(MODE_CUBEMAP_ARRAY_TO_PANORAMA)
+
+ const float PI = 3.14159265359;
+ vec2 uv = vec2(pos) / vec2(params.section.zw);
+ uv.y = 1.0 - uv.y;
+ float phi = uv.x * 2.0 * PI;
+ float theta = uv.y * PI;
+
+ vec3 normal;
+ normal.x = sin(phi) * sin(theta) * -1.0;
+ normal.y = cos(theta);
+ normal.z = cos(phi) * sin(theta) * -1.0;
+
+#ifdef MODE_CUBEMAP_TO_PANORAMA
+ vec4 color = textureLod(source_color, normal, params.camera_z_far); //the biggest the lod the least the acne
+#else
+ vec4 color = textureLod(source_color, vec4(normal, params.camera_z_far), 0.0); //the biggest the lod the least the acne
+#endif
+ imageStore(dest_buffer, pos + params.target, color);
+#endif
}
diff --git a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
index 07f8d09743..b1cfe1e91e 100644
--- a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
@@ -1,12 +1,10 @@
-/* clang-format off */
-[vertex]
+#[vertex]
#version 450
VERSION_DEFINES
layout(location = 0) out vec2 uv_interp;
-/* clang-format on */
layout(push_constant, binding = 1, std430) uniform Params {
vec4 section;
@@ -20,7 +18,6 @@ layout(push_constant, binding = 1, std430) uniform Params {
params;
void main() {
-
vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
uv_interp = base_arr[gl_VertexIndex];
@@ -36,8 +33,7 @@ void main() {
}
}
-/* clang-format off */
-[fragment]
+#[fragment]
#version 450
@@ -52,18 +48,16 @@ layout(push_constant, binding = 1, std430) uniform Params {
bool force_luminance;
bool alpha_to_zero;
uint pad[2];
-} params;
-
+}
+params;
layout(location = 0) in vec2 uv_interp;
-/* clang-format on */
layout(set = 0, binding = 0) uniform sampler2D source_color;
layout(location = 0) out vec4 frag_color;
void main() {
-
vec2 uv = uv_interp;
#ifdef MODE_PANORAMA_TO_DP
@@ -83,8 +77,9 @@ void main() {
vec2 st = vec2(atan(normal.x, normal.z), acos(normal.y));
- if (st.x < 0.0)
+ if (st.x < 0.0) {
st.x += M_PI * 2.0;
+ }
uv = st / vec2(M_PI * 2.0, M_PI);
diff --git a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl
index 02ebe1a53b..54d67db6c6 100644
--- a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl
@@ -1,12 +1,10 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-/* clang-format on */
layout(set = 0, binding = 0) uniform samplerCube source_cube;
@@ -23,7 +21,6 @@ params;
layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer;
void main() {
-
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing
return;
diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl b/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl
index 9f3ecf6053..7f269b7af3 100644
--- a/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/cubemap_downsampler.glsl
@@ -18,8 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
-/* clang-format off */
-[compute]
+#[compute]
#version 450
@@ -28,7 +27,6 @@ VERSION_DEFINES
#define BLOCK_SIZE 8
layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in;
-/* clang-format on */
layout(set = 0, binding = 0) uniform samplerCube source_cubemap;
@@ -46,26 +44,31 @@ void get_dir_0(out vec3 dir, in float u, in float v) {
dir[1] = v;
dir[2] = -u;
}
+
void get_dir_1(out vec3 dir, in float u, in float v) {
dir[0] = -1.0;
dir[1] = v;
dir[2] = u;
}
+
void get_dir_2(out vec3 dir, in float u, in float v) {
dir[0] = u;
dir[1] = 1.0;
dir[2] = -v;
}
+
void get_dir_3(out vec3 dir, in float u, in float v) {
dir[0] = u;
dir[1] = -1.0;
dir[2] = v;
}
+
void get_dir_4(out vec3 dir, in float u, in float v) {
dir[0] = u;
dir[1] = v;
dir[2] = 1.0;
}
+
void get_dir_5(out vec3 dir, in float u, in float v) {
dir[0] = -u;
dir[1] = v;
diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl b/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl
index 193d0a8a3c..987545fb76 100644
--- a/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/cubemap_filter.glsl
@@ -18,8 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
-/* clang-format off */
-[compute]
+#[compute]
#version 450
@@ -28,7 +27,6 @@ VERSION_DEFINES
#define GROUP_SIZE 64
layout(local_size_x = GROUP_SIZE, local_size_y = 1, local_size_z = 1) in;
-/* clang-format on */
layout(set = 0, binding = 0) uniform samplerCube source_cubemap;
layout(rgba16f, set = 2, binding = 0) uniform restrict writeonly imageCube dest_cubemap0;
diff --git a/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl b/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl
index e85996fa1a..5cbb00baa4 100644
--- a/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/cubemap_roughness.glsl
@@ -1,5 +1,4 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
@@ -8,7 +7,6 @@ VERSION_DEFINES
#define GROUP_SIZE 8
layout(local_size_x = GROUP_SIZE, local_size_y = GROUP_SIZE, local_size_z = 1) in;
-/* clang-format on */
layout(set = 0, binding = 0) uniform samplerCube source_cube;
@@ -119,10 +117,8 @@ void main() {
//vec4 color = color_interp;
if (params.use_direct_write) {
-
imageStore(dest_cubemap, ivec3(id), vec4(texture(source_cube, N).rgb, 1.0));
} else {
-
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
for (uint sampleNum = 0u; sampleNum < params.sample_count; sampleNum++) {
@@ -135,7 +131,6 @@ void main() {
float ndotl = clamp(dot(N, L), 0.0, 1.0);
if (ndotl > 0.0) {
-
sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl;
sum.a += ndotl;
}
diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe.glsl
index fd09f96a57..ea4237a45e 100644
--- a/servers/rendering/rasterizer_rd/shaders/giprobe.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/giprobe.glsl
@@ -1,5 +1,4 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
@@ -10,7 +9,6 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#else
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
#endif
-/* clang-format on */
#ifndef MODE_DYNAMIC
@@ -47,7 +45,6 @@ cell_data;
#if defined(MODE_COMPUTE_LIGHT) || defined(MODE_DYNAMIC_LIGHTING)
struct Light {
-
uint type;
float energy;
float radius;
@@ -191,7 +188,6 @@ layout(r16ui, set = 0, binding = 13) uniform restrict writeonly uimage3D aniso_n
#if defined(MODE_COMPUTE_LIGHT) || defined(MODE_DYNAMIC_LIGHTING)
float raymarch(float distance, float distance_adv, vec3 from, vec3 direction) {
-
vec3 cell_size = 1.0 / vec3(params.limits);
float occlusion = 1.0;
while (distance > 0.5) { //use this to avoid precision errors
@@ -213,14 +209,11 @@ float raymarch(float distance, float distance_adv, vec3 from, vec3 direction) {
}
bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3 light_pos) {
-
if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) {
-
light_pos = pos - lights.data[light].direction * length(vec3(params.limits));
attenuation = 1.0;
} else {
-
light_pos = lights.data[light].position;
float distance = length(pos - light_pos);
if (distance >= lights.data[light].radius) {
@@ -230,7 +223,6 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3
attenuation = pow(clamp(1.0 - distance / lights.data[light].radius, 0.0001, 1.0), lights.data[light].attenuation);
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
-
vec3 rel = normalize(pos - light_pos);
float angle = acos(dot(rel, lights.data[light].direction));
if (angle > lights.data[light].spot_angle_radians) {
@@ -246,7 +238,6 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3
}
float get_normal_advance(vec3 p_normal) {
-
vec3 normal = p_normal;
vec3 unorm = abs(normal);
@@ -269,7 +260,6 @@ float get_normal_advance(vec3 p_normal) {
}
void clip_segment(vec4 plane, vec3 begin, inout vec3 end) {
-
vec3 segment = begin - end;
float den = dot(plane.xyz, segment);
@@ -302,7 +292,6 @@ bool compute_light_at_pos(uint index, vec3 pos, vec3 normal, inout vec3 light, i
}
if (lights.data[index].has_shadow) {
-
float distance_adv = get_normal_advance(light_dir);
vec3 to = pos;
@@ -352,7 +341,6 @@ bool compute_light_at_pos(uint index, vec3 pos, vec3 normal, inout vec3 light, i
#endif // MODE COMPUTE LIGHT
void main() {
-
#ifndef MODE_DYNAMIC
uint cell_index = gl_GlobalInvocationID.x;
@@ -383,7 +371,6 @@ void main() {
#endif
for (uint i = 0; i < params.light_count; i++) {
-
vec3 light;
vec3 light_dir;
if (!compute_light_at_pos(i, pos, normal.xyz, light, light_dir)) {
@@ -394,7 +381,6 @@ void main() {
#ifdef MODE_ANISOTROPIC
for (uint j = 0; j < 6; j++) {
-
accum[j] += max(0.0, dot(accum_dirs[j], -light_dir)) * light;
}
#else
@@ -461,7 +447,6 @@ void main() {
#endif
if (length(normal.xyz) > 0.2) {
-
vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
vec3 tangent = normalize(cross(v0, normal.xyz));
vec3 bitangent = normalize(cross(tangent, normal.xyz));
@@ -481,11 +466,9 @@ void main() {
float tan_half_angle = 0.577;
for (int i = 0; i < MAX_CONE_DIRS; i++) {
-
vec3 direction = normal_mat * cone_dirs[i];
vec4 color = vec4(0.0);
{
-
float dist = 1.5;
float max_distance = length(vec3(params.limits));
vec3 cell_size = 1.0 / vec3(params.limits);
@@ -519,7 +502,6 @@ void main() {
color *= cone_weights[i] * vec4(albedo.rgb, 1.0) * params.dynamic_range; //restore range
#ifdef MODE_ANISOTROPIC
for (uint j = 0; j < 6; j++) {
-
accum[j] += max(0.0, dot(accum_dirs[j], direction)) * color.rgb;
}
#else
@@ -594,7 +576,6 @@ void main() {
#ifdef MODE_WRITE_TEXTURE
{
-
#ifdef MODE_ANISOTROPIC
vec3 accum_total = vec3(0.0);
accum_total += outputs.data[cell_index * 6 + 0].rgb;
@@ -665,7 +646,6 @@ void main() {
vec3 accum = vec3(0.0);
for (uint i = 0; i < params.light_count; i++) {
-
vec3 light;
vec3 light_dir;
if (!compute_light_at_pos(i, vec3(pos) * params.pos_multiplier, normal, light, light_dir)) {
diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl
index b1784e7eee..515cc35507 100644
--- a/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/giprobe_debug.glsl
@@ -1,5 +1,4 @@
-/* clang-format off */
-[vertex]
+#[vertex]
#version 450
@@ -11,7 +10,6 @@ struct CellData {
uint emission; //rgb normalized with e as multiplier
uint normal; //RGB normal encoded
};
-/* clang-format on */
layout(set = 0, binding = 1, std140) buffer CellDataBuffer {
CellData data[];
@@ -28,7 +26,6 @@ layout(set = 0, binding = 5) uniform texture3D aniso_neg_tex;
#endif
layout(push_constant, binding = 0, std430) uniform Params {
-
mat4 projection;
uint cell_offset;
float dynamic_range;
@@ -42,7 +39,6 @@ params;
layout(location = 0) out vec4 color_interp;
void main() {
-
const vec3 cube_triangles[36] = vec3[](
vec3(-1.0f, -1.0f, -1.0f),
vec3(-1.0f, -1.0f, 1.0f),
@@ -130,12 +126,24 @@ void main() {
float strength = 0.0;
switch (side) {
- case POS_X: strength = aniso_pos.x; break;
- case POS_Y: strength = aniso_pos.y; break;
- case POS_Z: strength = aniso_pos.z; break;
- case NEG_X: strength = aniso_neg.x; break;
- case NEG_Y: strength = aniso_neg.y; break;
- case NEG_Z: strength = aniso_neg.z; break;
+ case POS_X:
+ strength = aniso_pos.x;
+ break;
+ case POS_Y:
+ strength = aniso_pos.y;
+ break;
+ case POS_Z:
+ strength = aniso_pos.z;
+ break;
+ case NEG_X:
+ strength = aniso_neg.x;
+ break;
+ case NEG_Y:
+ strength = aniso_neg.y;
+ break;
+ case NEG_Z:
+ strength = aniso_neg.z;
+ break;
}
color_interp.xyz *= strength;
@@ -160,19 +168,16 @@ void main() {
#endif
}
-/* clang-format off */
-[fragment]
+#[fragment]
#version 450
VERSION_DEFINES
layout(location = 0) in vec4 color_interp;
-/* clang-format on */
layout(location = 0) out vec4 frag_color;
void main() {
-
frag_color = color_interp;
#ifdef MODE_DEBUG_LIGHT_FULL
@@ -184,22 +189,38 @@ void main() {
int index = x + y * 4;
float limit = 0.0;
if (x < 8) {
- if (index == 0) limit = 0.0625;
- if (index == 1) limit = 0.5625;
- if (index == 2) limit = 0.1875;
- if (index == 3) limit = 0.6875;
- if (index == 4) limit = 0.8125;
- if (index == 5) limit = 0.3125;
- if (index == 6) limit = 0.9375;
- if (index == 7) limit = 0.4375;
- if (index == 8) limit = 0.25;
- if (index == 9) limit = 0.75;
- if (index == 10) limit = 0.125;
- if (index == 11) limit = 0.625;
- if (index == 12) limit = 1.0;
- if (index == 13) limit = 0.5;
- if (index == 14) limit = 0.875;
- if (index == 15) limit = 0.375;
+ if (index == 0)
+ limit = 0.0625;
+ if (index == 1)
+ limit = 0.5625;
+ if (index == 2)
+ limit = 0.1875;
+ if (index == 3)
+ limit = 0.6875;
+ if (index == 4)
+ limit = 0.8125;
+ if (index == 5)
+ limit = 0.3125;
+ if (index == 6)
+ limit = 0.9375;
+ if (index == 7)
+ limit = 0.4375;
+ if (index == 8)
+ limit = 0.25;
+ if (index == 9)
+ limit = 0.75;
+ if (index == 10)
+ limit = 0.125;
+ if (index == 11)
+ limit = 0.625;
+ if (index == 12)
+ limit = 1.0;
+ if (index == 13)
+ limit = 0.5;
+ if (index == 14)
+ limit = 0.875;
+ if (index == 15)
+ limit = 0.375;
}
if (frag_color.a < limit) {
discard;
diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl
index d089236723..5b3dec0ee7 100644
--- a/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/giprobe_sdf.glsl
@@ -1,12 +1,10 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
layout(local_size_x = 4, local_size_y = 4, local_size_z = 4) in;
-/* clang-format on */
#define MAX_DISTANCE 100000
@@ -45,7 +43,6 @@ layout(push_constant, binding = 0, std430) uniform Params {
params;
void main() {
-
vec3 pos = vec3(gl_GlobalInvocationID);
float closest_dist = 100000.0;
@@ -71,19 +68,17 @@ void main() {
#if 0
layout(push_constant, binding = 0, std430) uniform Params {
-
ivec3 limits;
uint stack_size;
-} params;
+}
+params;
float distance_to_aabb(ivec3 pos, ivec3 aabb_pos, ivec3 aabb_size) {
-
vec3 delta = vec3(max(ivec3(0), max(aabb_pos - pos, pos - (aabb_pos + aabb_size - ivec3(1)))));
return length(delta);
}
void main() {
-
ivec3 pos = ivec3(gl_GlobalInvocationID);
uint stack[10] = uint[](0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
@@ -107,7 +102,6 @@ void main() {
int stack_pos = 0;
while (true) {
-
uint index = stack_indices[stack_pos] >> 24;
if (index == 8) {
diff --git a/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl b/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl
index c832223b1e..9c794f1bcc 100644
--- a/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/giprobe_write.glsl
@@ -1,12 +1,10 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
layout(local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
-/* clang-format on */
#define NO_CHILDREN 0xFFFFFFFF
#define GREY_VEC vec3(0.33333, 0.33333, 0.33333)
@@ -84,24 +82,20 @@ output;
#ifdef MODE_COMPUTE_LIGHT
uint raymarch(float distance, float distance_adv, vec3 from, vec3 direction) {
-
uint result = NO_CHILDREN;
ivec3 size = ivec3(max(max(params.limits.x, params.limits.y), params.limits.z));
while (distance > -distance_adv) { //use this to avoid precision errors
-
uint cell = 0;
ivec3 pos = ivec3(from);
if (all(greaterThanEqual(pos, ivec3(0))) && all(lessThan(pos, size))) {
-
ivec3 ofs = ivec3(0);
ivec3 half_size = size / 2;
for (int i = 0; i < params.stack_size - 1; i++) {
-
bvec3 greater = greaterThanEqual(pos, ofs + half_size);
ofs += mix(ivec3(0), half_size, greater);
@@ -118,8 +112,9 @@ uint raymarch(float distance, float distance_adv, vec3 from, vec3 direction) {
}
cell = cell_children.data[cell].children[child];
- if (cell == NO_CHILDREN)
+ if (cell == NO_CHILDREN) {
break;
+ }
half_size >>= ivec3(1);
}
@@ -137,14 +132,10 @@ uint raymarch(float distance, float distance_adv, vec3 from, vec3 direction) {
}
bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation, out vec3 light_pos) {
-
if (lights.data[light].type == LIGHT_TYPE_DIRECTIONAL) {
-
light_pos = pos - lights.data[light].direction * length(vec3(params.limits));
attenuation = 1.0;
-
} else {
-
light_pos = lights.data[light].position;
float distance = length(pos - light_pos);
if (distance >= lights.data[light].radius) {
@@ -154,7 +145,6 @@ bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation
attenuation = pow(clamp(1.0 - distance / lights.data[light].radius, 0.0001, 1.0), lights.data[light].attenuation);
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
-
vec3 rel = normalize(pos - light_pos);
float angle = acos(dot(rel, lights.data[light].direction));
if (angle > lights.data[light].spot_angle_radians) {
@@ -170,7 +160,6 @@ bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation
}
float get_normal_advance(vec3 p_normal) {
-
vec3 normal = p_normal;
vec3 unorm = abs(normal);
@@ -195,7 +184,6 @@ float get_normal_advance(vec3 p_normal) {
#endif
void main() {
-
uint cell_index = gl_GlobalInvocationID.x;
if (cell_index >= params.cell_count) {
return;
@@ -220,7 +208,6 @@ void main() {
#endif
for (uint i = 0; i < params.light_count; i++) {
-
float attenuation;
vec3 light_pos;
@@ -237,7 +224,6 @@ void main() {
}
if (lights.data[i].has_shadow) {
-
float distance_adv = get_normal_advance(light_dir);
distance += distance_adv - mod(distance, distance_adv); //make it reach the center of the box always
diff --git a/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl b/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl
index 4bf5b7e7f1..8a11c35b78 100644
--- a/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/luminance_reduce.glsl
@@ -1,5 +1,4 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
@@ -8,7 +7,6 @@ VERSION_DEFINES
#define BLOCK_SIZE 8
layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in;
-/* clang-format on */
shared float tmp_data[BLOCK_SIZE * BLOCK_SIZE];
@@ -40,12 +38,10 @@ layout(push_constant, binding = 1, std430) uniform Params {
params;
void main() {
-
uint t = gl_LocalInvocationID.y * BLOCK_SIZE + gl_LocalInvocationID.x;
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
if (any(lessThan(pos, params.source_size))) {
-
#ifdef READ_TEXTURE
vec3 v = texelFetch(source_texture, pos, 0).rgb;
tmp_data[t] = max(v.r, max(v.g, v.b));
@@ -69,7 +65,6 @@ void main() {
barrier();
size >>= 1;
-
} while (size >= 1);
if (t == 0) {
diff --git a/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl b/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl
index 3637b1abb2..464895928a 100644
--- a/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/roughness_limiter.glsl
@@ -1,12 +1,10 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-/* clang-format on */
layout(set = 0, binding = 0) uniform sampler2D source_normal;
layout(r8, set = 1, binding = 0) uniform restrict writeonly image2D dest_roughness;
@@ -21,7 +19,6 @@ params;
#define HALF_PI 1.5707963267948966
void main() {
-
// Pixel being shaded
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing
@@ -53,14 +50,14 @@ void main() {
float kappa = (3.0f * r - r * r2) / (1.0f - r2);
float variance = 0.25f / kappa;
limit = sqrt(min(2.0f * variance, threshold * threshold));
-//*/
+ */
/*
//Formula based on probability distribution graph
float width = acos(max(0.0,r)); // convert to angle (width)
float roughness = pow(width,1.7)*0.854492; //approximate (crappy) formula to convert to roughness
limit = min(sqrt(roughness), threshold); //convert to perceptual roughness and apply threshold
-//*/
+ */
limit = min(sqrt(pow(acos(max(0.0, r)) / HALF_PI, params.curve)), threshold); //convert to perceptual roughness and apply threshold
diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
index ec47887036..9f42b0f814 100644
--- a/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end.glsl
@@ -1,5 +1,4 @@
-/* clang-format off */
-[vertex]
+#[vertex]
#version 450
@@ -10,7 +9,6 @@ VERSION_DEFINES
/* INPUT ATTRIBS */
layout(location = 0) in vec3 vertex_attrib;
-/* clang-format on */
layout(location = 1) in vec3 normal_attrib;
#if defined(TANGENT_USED) || defined(NORMALMAP_USED) || defined(LIGHT_ANISOTROPY_USED)
layout(location = 2) in vec4 tangent_attrib;
@@ -22,7 +20,7 @@ layout(location = 3) in vec4 color_attrib;
layout(location = 4) in vec2 uv_attrib;
-#if defined(UV2_USED) || defined(USE_LIGHTMAP)
+#if defined(UV2_USED) || defined(USE_LIGHTMAP) || defined(MODE_RENDER_MATERIAL)
layout(location = 5) in vec2 uv2_attrib;
#endif
@@ -49,7 +47,7 @@ layout(location = 6) out vec3 binormal_interp;
#endif
#ifdef USE_MATERIAL_UNIFORMS
-layout(set = 5, binding = 0, std140) uniform MaterialUniforms{
+layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{
/* clang-format off */
MATERIAL_UNIFORMS
/* clang-format on */
@@ -62,8 +60,6 @@ VERTEX_SHADER_GLOBALS
/* clang-format on */
-// FIXME: This triggers a Mesa bug that breaks rendering, so disabled for now.
-// See GH-13450 and https://bugs.freedesktop.org/show_bug.cgi?id=100316
invariant gl_Position;
layout(location = 7) flat out uint instance_index;
@@ -75,7 +71,6 @@ layout(location = 8) out float dp_clip;
#endif
void main() {
-
instance_index = draw_call.instance_index;
vec4 instance_custom = vec4(0.0);
#if defined(COLOR_USED)
@@ -263,10 +258,17 @@ VERTEX_SHADER_CODE
}
}
#endif
+
+#ifdef MODE_RENDER_MATERIAL
+ if (scene_data.material_uv2_mode) {
+ gl_Position.xy = (uv2_attrib.xy + draw_call.bake_uv2_offset) * 2.0 - 1.0;
+ gl_Position.z = 0.00001;
+ gl_Position.w = 1.0;
+ }
+#endif
}
-/* clang-format off */
-[fragment]
+#[fragment]
#version 450
@@ -277,7 +279,6 @@ VERSION_DEFINES
/* Varyings */
layout(location = 0) in vec3 vertex_interp;
-/* clang-format on */
layout(location = 1) in vec3 normal_interp;
#if defined(COLOR_USED)
@@ -315,7 +316,7 @@ layout(location = 8) in float dp_clip;
#endif
#ifdef USE_MATERIAL_UNIFORMS
-layout(set = 5, binding = 0, std140) uniform MaterialUniforms{
+layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{
/* clang-format off */
MATERIAL_UNIFORMS
/* clang-format on */
@@ -420,7 +421,8 @@ float SchlickFresnel(float u) {
}
float GTR1(float NdotH, float a) {
- if (a >= 1.0) return 1.0 / M_PI;
+ if (a >= 1.0)
+ return 1.0 / M_PI;
float a2 = a * a;
float t = 1.0 + (a2 - 1.0) * NdotH * NdotH;
return (a2 - 1.0) / (M_PI * log(a2) * t);
@@ -684,7 +686,6 @@ float quick_hash(vec2 pos) {
}
float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) {
-
vec2 pos = coord.xy;
float depth = coord.z;
@@ -711,7 +712,6 @@ float sample_directional_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, ve
}
float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) {
-
vec2 pos = coord.xy;
float depth = coord.z;
@@ -738,7 +738,6 @@ float sample_pcf_shadow(texture2D shadow, vec2 shadow_pixel_size, vec4 coord) {
}
float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex_scale) {
-
//find blocker
float blocker_count = 0.0;
float blocker_average = 0.0;
@@ -752,7 +751,6 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex
}
for (uint i = 0; i < scene_data.directional_penumbra_shadow_samples; i++) {
-
vec2 suv = pssm_coord.xy + (disk_rotation * scene_data.directional_penumbra_shadow_kernel[i].xy) * tex_scale;
float d = textureLod(sampler2D(shadow, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r;
if (d < pssm_coord.z) {
@@ -762,7 +760,6 @@ float sample_directional_soft_shadow(texture2D shadow, vec3 pssm_coord, vec2 tex
}
if (blocker_count > 0.0) {
-
//blockers found, do soft shadow
blocker_average /= blocker_count;
float penumbra = (pssm_coord.z - blocker_average) / blocker_average;
@@ -820,7 +817,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
float size_A = 0.0;
if (lights.data[idx].size > 0.0) {
-
float t = lights.data[idx].size / max(0.001, light_length);
size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t));
}
@@ -874,7 +870,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
bitangent *= lights.data[idx].soft_shadow_size * lights.data[idx].soft_shadow_scale;
for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) {
-
vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy;
vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y;
@@ -883,11 +878,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
vec4 uv_rect = lights.data[idx].atlas_rect;
if (pos.z >= 0.0) {
-
pos.z += 1.0;
uv_rect.y += uv_rect.w;
} else {
-
pos.z = 1.0 - pos.z;
}
@@ -904,7 +897,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
}
if (blocker_count > 0.0) {
-
//blockers found, do soft shadow
blocker_average /= blocker_count;
float penumbra = (z_norm - blocker_average) / blocker_average;
@@ -915,7 +907,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
shadow = 0.0;
for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) {
-
vec2 disk = disk_rotation * scene_data.penumbra_shadow_kernel[i].xy;
vec3 pos = splane.xyz + tangent * disk.x + bitangent * disk.y;
@@ -923,11 +914,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
vec4 uv_rect = lights.data[idx].atlas_rect;
if (pos.z >= 0.0) {
-
pos.z += 1.0;
uv_rect.y += uv_rect.w;
} else {
-
pos.z = 1.0 - pos.z;
}
@@ -945,12 +934,10 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
shadow = 1.0;
}
} else {
-
splane.xyz = normalize(splane.xyz);
vec4 clamp_rect = lights.data[idx].atlas_rect;
if (splane.z >= 0.0) {
-
splane.z += 1.0;
clamp_rect.y += clamp_rect.w;
@@ -970,7 +957,6 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_TRANSMITTANCE_USED
{
-
vec4 clamp_rect = lights.data[idx].atlas_rect;
//redo shadowmapping, but shrink the model a bit to avoid arctifacts
@@ -980,11 +966,9 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
splane = normalize(splane.xyz);
if (splane.z >= 0.0) {
-
splane.z += 1.0;
} else {
-
splane.z = 1.0 - splane.z;
}
@@ -1002,19 +986,16 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
vec3 no_shadow = vec3(1.0);
if (lights.data[idx].projector_rect != vec4(0.0)) {
-
vec3 local_v = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0)).xyz;
local_v = normalize(local_v);
vec4 atlas_rect = lights.data[idx].projector_rect;
if (local_v.z >= 0.0) {
-
local_v.z += 1.0;
atlas_rect.y += atlas_rect.w;
} else {
-
local_v.z = 1.0 - local_v.z;
}
@@ -1029,10 +1010,8 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
local_v_ddx = normalize(local_v_ddx);
if (local_v_ddx.z >= 0.0) {
-
local_v_ddx.z += 1.0;
} else {
-
local_v_ddx.z = 1.0 - local_v_ddx.z;
}
@@ -1045,10 +1024,8 @@ void light_process_omni(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
local_v_ddy = normalize(local_v_ddy);
if (local_v_ddy.z >= 0.0) {
-
local_v_ddy.z += 1.0;
} else {
-
local_v_ddy.z = 1.0 - local_v_ddy.z;
}
@@ -1136,7 +1113,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
float size_A = 0.0;
if (lights.data[idx].size > 0.0) {
-
float t = lights.data[idx].size / max(0.001, light_length);
size_A = max(0.0, 1.0 - 1 / sqrt(1 + t * t));
}
@@ -1193,7 +1169,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
float uv_size = lights.data[idx].soft_shadow_size * z_norm * lights.data[idx].soft_shadow_scale;
vec2 clamp_max = lights.data[idx].atlas_rect.xy + lights.data[idx].atlas_rect.zw;
for (uint i = 0; i < scene_data.penumbra_shadow_samples; i++) {
-
vec2 suv = shadow_uv + (disk_rotation * scene_data.penumbra_shadow_kernel[i].xy) * uv_size;
suv = clamp(suv, lights.data[idx].atlas_rect.xy, clamp_max);
float d = textureLod(sampler2D(shadow_atlas, material_samplers[SAMPLER_LINEAR_CLAMP]), suv, 0.0).r;
@@ -1204,7 +1179,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
}
if (blocker_count > 0.0) {
-
//blockers found, do soft shadow
blocker_average /= blocker_count;
float penumbra = (z_norm - blocker_average) / blocker_average;
@@ -1234,7 +1208,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
vec3 no_shadow = vec3(1.0);
if (lights.data[idx].projector_rect != vec4(0.0)) {
-
splane = (lights.data[idx].shadow_matrix * vec4(vertex, 1.0));
splane /= splane.w;
@@ -1257,7 +1230,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
#ifdef LIGHT_TRANSMITTANCE_USED
{
-
splane = (lights.data[idx].shadow_matrix * vec4(vertex - normalize(normal_interp) * lights.data[idx].transmittance_bias, 1.0));
splane /= splane.w;
splane.xy = splane.xy * lights.data[idx].atlas_rect.zw + lights.data[idx].atlas_rect.xy;
@@ -1301,7 +1273,6 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
}
void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughness, vec3 ambient_light, vec3 specular_light, inout vec4 ambient_accum, inout vec4 reflection_accum) {
-
vec3 box_extents = reflections.data[ref_index].box_extents;
vec3 local_pos = (reflections.data[ref_index].local_matrix * vec4(vertex, 1.0)).xyz;
@@ -1368,7 +1339,6 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes
ambient_out.rgb *= ambient_out.a;
ambient_accum += ambient_out;
} else {
-
vec4 ambient_out;
ambient_out.a = blend;
ambient_out.rgb = reflections.data[ref_index].ambient.rgb;
@@ -1385,7 +1355,6 @@ void reflection_process(uint ref_index, vec3 vertex, vec3 normal, float roughnes
//standard voxel cone trace
vec4 voxel_cone_trace(texture3D probe, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) {
-
float dist = p_bias;
vec4 color = vec4(0.0);
@@ -1412,7 +1381,6 @@ vec4 voxel_cone_trace(texture3D probe, vec3 cell_size, vec3 pos, vec3 direction,
#ifdef GI_PROBE_USE_ANISOTROPY
vec4 voxel_cone_trace_anisotropic_45_degrees(texture3D probe, texture3D aniso_pos, texture3D aniso_neg, vec3 normal, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) {
-
float dist = p_bias;
vec4 color = vec4(0.0);
float radius = max(0.5, tan_half_angle * dist);
@@ -1444,7 +1412,6 @@ vec4 voxel_cone_trace_anisotropic_45_degrees(texture3D probe, texture3D aniso_po
#else
vec4 voxel_cone_trace_45_degrees(texture3D probe, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) {
-
float dist = p_bias;
vec4 color = vec4(0.0);
float radius = max(0.5, tan_half_angle * dist);
@@ -1476,7 +1443,6 @@ vec4 voxel_cone_trace_45_degrees(texture3D probe, vec3 cell_size, vec3 pos, vec3
//standard voxel cone trace
vec4 voxel_cone_trace_anisotropic(texture3D probe, texture3D aniso_pos, texture3D aniso_neg, vec3 normal, vec3 cell_size, vec3 pos, vec3 direction, float tan_half_angle, float max_distance, float p_bias) {
-
float dist = p_bias;
vec4 color = vec4(0.0);
@@ -1507,7 +1473,6 @@ vec4 voxel_cone_trace_anisotropic(texture3D probe, texture3D aniso_pos, texture3
#endif
void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3 normal_xform, float roughness, vec3 ambient, vec3 environment, inout vec4 out_spec, inout vec4 out_diff) {
-
position = (gi_probes.data[index].xform * vec4(position, 1.0)).xyz;
ref_vec = normalize((gi_probes.data[index].xform * vec4(ref_vec, 0.0)).xyz);
normal = normalize((gi_probes.data[index].xform * vec4(normal, 0.0)).xyz);
@@ -1568,7 +1533,6 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3
vec3 light = vec3(0.0);
for (int i = 0; i < MAX_CONE_DIRS; i++) {
-
vec3 dir = normalize((gi_probes.data[index].xform * vec4(normal_xform * cone_dirs[i], 0.0)).xyz);
#if defined(GI_PROBE_HIGH_QUALITY) || defined(GI_PROBE_LOW_QUALITY)
@@ -1600,7 +1564,6 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3
light *= gi_probes.data[index].dynamic_range;
if (gi_probes.data[index].ambient_occlusion > 0.001) {
-
float size = 1.0 + gi_probes.data[index].ambient_occlusion_size * 7.0;
float taps, blend;
@@ -1641,7 +1604,6 @@ void gi_probe_compute(uint index, vec3 position, vec3 normal, vec3 ref_vec, mat3
#endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
void main() {
-
#ifdef MODE_DUAL_PARABOLOID
if (dp_clip > 0.0)
@@ -1793,7 +1755,6 @@ FRAGMENT_SHADER_CODE
//do outside for performance and avoiding arctifacts
for (uint i = 0; i < decal_count; i++) {
-
uint decal_index = cluster_data.indices[decal_pointer + i];
if (!bool(decals.data[decal_index].mask & instances.data[instance_index].layer_mask)) {
continue; //not masked
@@ -1822,7 +1783,6 @@ FRAGMENT_SHADER_CODE
albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix);
if (decals.data[decal_index].normal_rect != vec4(0.0)) {
-
vec3 decal_normal = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz;
decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software
decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy)));
@@ -1833,7 +1793,6 @@ FRAGMENT_SHADER_CODE
}
if (decals.data[decal_index].orm_rect != vec4(0.0)) {
-
vec3 decal_orm = textureGrad(sampler2D(decal_atlas, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz;
#if defined(AO_USED)
ao = mix(ao, decal_orm.r, decal_albedo.a);
@@ -1867,7 +1826,6 @@ FRAGMENT_SHADER_CODE
}
if (scene_data.use_reflection_cubemap) {
-
vec3 ref_vec = reflect(-view, normal);
ref_vec = scene_data.radiance_inverse_xform * ref_vec;
#ifdef USE_RADIANCE_CUBEMAP_ARRAY
@@ -1887,7 +1845,6 @@ FRAGMENT_SHADER_CODE
#ifndef USE_LIGHTMAP
//lightmap overrides everything
if (scene_data.use_ambient_light) {
-
ambient_light = scene_data.ambient_light_color_energy.rgb;
if (scene_data.use_ambient_cubemap) {
@@ -1916,42 +1873,95 @@ FRAGMENT_SHADER_CODE
#if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
//gi probes
+#ifdef USE_LIGHTMAP
+
//lightmap
+ if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE)) { //has lightmap capture
+ uint index = instances.data[instance_index].gi_offset;
+
+ vec3 wnormal = mat3(scene_data.camera_matrix) * normal;
+ const float c1 = 0.429043;
+ const float c2 = 0.511664;
+ const float c3 = 0.743125;
+ const float c4 = 0.886227;
+ const float c5 = 0.247708;
+ ambient_light += (c1 * lightmap_captures.data[index].sh[8].rgb * (wnormal.x * wnormal.x - wnormal.y * wnormal.y) +
+ c3 * lightmap_captures.data[index].sh[6].rgb * wnormal.z * wnormal.z +
+ c4 * lightmap_captures.data[index].sh[0].rgb -
+ c5 * lightmap_captures.data[index].sh[6].rgb +
+ 2.0 * c1 * lightmap_captures.data[index].sh[4].rgb * wnormal.x * wnormal.y +
+ 2.0 * c1 * lightmap_captures.data[index].sh[7].rgb * wnormal.x * wnormal.z +
+ 2.0 * c1 * lightmap_captures.data[index].sh[5].rgb * wnormal.y * wnormal.z +
+ 2.0 * c2 * lightmap_captures.data[index].sh[3].rgb * wnormal.x +
+ 2.0 * c2 * lightmap_captures.data[index].sh[1].rgb * wnormal.y +
+ 2.0 * c2 * lightmap_captures.data[index].sh[2].rgb * wnormal.z);
+
+ } else if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_LIGHTMAP)) { // has actual lightmap
+ bool uses_sh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_SH_LIGHTMAP);
+ uint ofs = instances.data[instance_index].gi_offset & 0xFFF;
+ vec3 uvw;
+ uvw.xy = uv2 * instances.data[instance_index].lightmap_uv_scale.zw + instances.data[instance_index].lightmap_uv_scale.xy;
+ uvw.z = float((instances.data[instance_index].gi_offset >> 12) & 0xFF);
+
+ if (uses_sh) {
+ uvw.z *= 4.0; //SH textures use 4 times more data
+ vec3 lm_light_l0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb;
+ vec3 lm_light_l1n1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb;
+ vec3 lm_light_l1_0 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb;
+ vec3 lm_light_l1p1 = textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb;
+
+ uint idx = instances.data[instance_index].gi_offset >> 20;
+ vec3 n = normalize(lightmaps.data[idx].normal_xform * normal);
+
+ ambient_light += lm_light_l0 * 0.282095f;
+ ambient_light += lm_light_l1n1 * 0.32573 * n.y;
+ ambient_light += lm_light_l1_0 * 0.32573 * n.z;
+ ambient_light += lm_light_l1p1 * 0.32573 * n.x;
+ if (metallic > 0.01) { // since the more direct bounced light is lost, we can kind of fake it with this trick
+ vec3 r = reflect(normalize(-vertex), normal);
+ specular_light += lm_light_l1n1 * 0.32573 * r.y;
+ specular_light += lm_light_l1_0 * 0.32573 * r.z;
+ specular_light += lm_light_l1p1 * 0.32573 * r.x;
+ }
+ } else {
+ ambient_light += textureLod(sampler2DArray(lightmap_textures[ofs], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw, 0.0).rgb;
+ }
+ }
+#endif
//lightmap capture
#ifdef USE_VOXEL_CONE_TRACING
- { // process giprobes
- uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
- if (index1 != 0xFFFF) {
- vec3 ref_vec = normalize(reflect(normalize(vertex), normal));
- //find arbitrary tangent and bitangent, then build a matrix
- vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
- vec3 tangent = normalize(cross(v0, normal));
- vec3 bitangent = normalize(cross(tangent, normal));
- mat3 normal_mat = mat3(tangent, bitangent, normal);
+ if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GIPROBE)) { // process giprobes
- vec4 amb_accum = vec4(0.0);
- vec4 spec_accum = vec4(0.0);
- gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
+ uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
+ vec3 ref_vec = normalize(reflect(normalize(vertex), normal));
+ //find arbitrary tangent and bitangent, then build a matrix
+ vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);
+ vec3 tangent = normalize(cross(v0, normal));
+ vec3 bitangent = normalize(cross(tangent, normal));
+ mat3 normal_mat = mat3(tangent, bitangent, normal);
- uint index2 = instances.data[instance_index].gi_offset >> 16;
+ vec4 amb_accum = vec4(0.0);
+ vec4 spec_accum = vec4(0.0);
+ gi_probe_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
- if (index2 != 0xFFFF) {
- gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
- }
+ uint index2 = instances.data[instance_index].gi_offset >> 16;
- if (amb_accum.a > 0.0) {
- amb_accum.rgb /= amb_accum.a;
- }
+ if (index2 != 0xFFFF) {
+ gi_probe_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum);
+ }
- if (spec_accum.a > 0.0) {
- spec_accum.rgb /= spec_accum.a;
- }
+ if (amb_accum.a > 0.0) {
+ amb_accum.rgb /= amb_accum.a;
+ }
- specular_light = spec_accum.rgb;
- ambient_light = amb_accum.rgb;
+ if (spec_accum.a > 0.0) {
+ spec_accum.rgb /= spec_accum.a;
}
+
+ specular_light = spec_accum.rgb;
+ ambient_light = amb_accum.rgb;
}
#endif
@@ -1964,7 +1974,6 @@ FRAGMENT_SHADER_CODE
uint reflection_probe_pointer = cluster_cell.z & CLUSTER_POINTER_MASK;
for (uint i = 0; i < reflection_probe_count; i++) {
-
uint ref_index = cluster_data.indices[reflection_probe_pointer + i];
reflection_process(ref_index, vertex, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
}
@@ -1981,7 +1990,6 @@ FRAGMENT_SHADER_CODE
}
{
-
#if defined(DIFFUSE_TOON)
//simplify for toon, as
specular_light *= specular * metallic * albedo * 2.0;
@@ -2006,7 +2014,6 @@ FRAGMENT_SHADER_CODE
{ //directional light
for (uint i = 0; i < scene_data.directional_light_count; i++) {
-
if (!bool(directional_lights.data[i].mask & instances.data[instance_index].layer_mask)) {
continue; //not masked
}
@@ -2066,7 +2073,6 @@ FRAGMENT_SHADER_CODE
}
#endif
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
-
vec4 v = vec4(vertex, 1.0);
BIAS_FUNC(v, 1)
@@ -2099,7 +2105,6 @@ FRAGMENT_SHADER_CODE
}
#endif
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
-
vec4 v = vec4(vertex, 1.0);
BIAS_FUNC(v, 2)
@@ -2133,7 +2138,6 @@ FRAGMENT_SHADER_CODE
#endif
} else {
-
vec4 v = vec4(vertex, 1.0);
BIAS_FUNC(v, 3)
@@ -2169,7 +2173,6 @@ FRAGMENT_SHADER_CODE
}
if (directional_lights.data[i].blend_splits) {
-
vec3 shadow_color_blend = vec3(0.0);
float pssm_blend;
float shadow2;
@@ -2279,7 +2282,6 @@ FRAGMENT_SHADER_CODE
uint omni_light_pointer = cluster_cell.x & CLUSTER_POINTER_MASK;
for (uint i = 0; i < omni_light_count; i++) {
-
uint light_index = cluster_data.indices[omni_light_pointer + i];
if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
@@ -2318,7 +2320,6 @@ FRAGMENT_SHADER_CODE
uint spot_light_pointer = cluster_cell.y & CLUSTER_POINTER_MASK;
for (uint i = 0; i < spot_light_count; i++) {
-
uint light_index = cluster_data.indices[spot_light_pointer + i];
if (!bool(lights.data[light_index].mask & instances.data[instance_index].layer_mask)) {
@@ -2423,7 +2424,6 @@ FRAGMENT_SHADER_CODE
ao_light_affect = mix(1.0, ao, ao_light_affect);
specular_light = mix(scene_data.ao_color.rgb, specular_light, ao_light_affect);
diffuse_light = mix(scene_data.ao_color.rgb, diffuse_light, ao_light_affect);
-
#else
if (scene_data.ssao_enabled) {
diff --git a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
index ce4fabf9f2..1cac12406a 100644
--- a/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/scene_high_end_inc.glsl
@@ -3,7 +3,8 @@
layout(push_constant, binding = 0, std430) uniform DrawCall {
uint instance_index;
- uint pad[3]; //16 bits minimum size
+ uint pad; //16 bits minimum size
+ vec2 bake_uv2_offset; //used for bake to uv2, ignored otherwise
}
draw_call;
@@ -27,7 +28,6 @@ layout(set = 0, binding = 1) uniform sampler material_samplers[12];
layout(set = 0, binding = 2) uniform sampler shadow_sampler;
layout(set = 0, binding = 3, std140) uniform SceneData {
-
mat4 projection_matrix;
mat4 inv_projection_matrix;
@@ -77,6 +77,10 @@ layout(set = 0, binding = 3, std140) uniform SceneData {
bool roughness_limiter_enabled;
vec4 ao_color;
+ bool material_uv2_mode;
+ uint pad_material0;
+ uint pad_material1;
+ uint pad_material2;
#if 0
vec4 ambient_light_color;
@@ -113,13 +117,13 @@ layout(set = 0, binding = 3, std140) uniform SceneData {
float fog_height_curve;
#endif
}
-scene_data;
-#define INSTANCE_FLAGS_FORWARD_MASK 0x7
-#define INSTANCE_FLAGS_FORWARD_OMNI_LIGHT_SHIFT 3
-#define INSTANCE_FLAGS_FORWARD_SPOT_LIGHT_SHIFT 6
-#define INSTANCE_FLAGS_FORWARD_DECAL_SHIFT 9
+scene_data;
+#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8)
+#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 9)
+#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 10)
+#define INSTANCE_FLAGS_USE_GIPROBE (1 << 11)
#define INSTANCE_FLAGS_MULTIMESH (1 << 12)
#define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13)
#define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14)
@@ -135,8 +139,9 @@ struct InstanceData {
mat4 normal_transform;
uint flags;
uint instance_uniforms_ofs; //base offset in global buffer for instance variables
- uint gi_offset; //GI information when using lightmapping (VCT or lightmap)
+ uint gi_offset; //GI information when using lightmapping (VCT or lightmap index)
uint layer_mask;
+ vec4 lightmap_uv_scale;
};
layout(set = 0, binding = 4, std430) restrict readonly buffer Instances {
@@ -171,7 +176,6 @@ layout(set = 0, binding = 5, std430) restrict readonly buffer Lights {
lights;
struct ReflectionData {
-
vec3 box_extents;
float index;
vec3 box_offset;
@@ -248,12 +252,35 @@ gi_probes;
layout(set = 0, binding = 9) uniform texture3D gi_probe_textures[MAX_GI_PROBE_TEXTURES];
+#define LIGHTMAP_FLAG_USE_DIRECTION 1
+#define LIGHTMAP_FLAG_USE_SPECULAR_DIRECTION 2
+
+struct Lightmap {
+ mat3 normal_xform;
+};
+
+layout(set = 0, binding = 10, std140) restrict readonly buffer Lightmaps {
+ Lightmap data[];
+}
+lightmaps;
+
+layout(set = 0, binding = 11) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
+
+struct LightmapCapture {
+ vec4 sh[9];
+};
+
+layout(set = 0, binding = 12, std140) restrict readonly buffer LightmapCaptures {
+ LightmapCapture data[];
+}
+lightmap_captures;
+
#define CLUSTER_COUNTER_SHIFT 20
#define CLUSTER_POINTER_MASK ((1 << CLUSTER_COUNTER_SHIFT) - 1)
#define CLUSTER_COUNTER_MASK 0xfff
-layout(set = 0, binding = 10) uniform texture2D decal_atlas;
-layout(set = 0, binding = 11) uniform texture2D decal_atlas_srgb;
+layout(set = 0, binding = 13) uniform texture2D decal_atlas;
+layout(set = 0, binding = 14) uniform texture2D decal_atlas_srgb;
struct DecalData {
mat4 xform; //to decal transform
@@ -273,21 +300,21 @@ struct DecalData {
float normal_fade;
};
-layout(set = 0, binding = 12, std430) restrict readonly buffer Decals {
+layout(set = 0, binding = 15, std430) restrict readonly buffer Decals {
DecalData data[];
}
decals;
-layout(set = 0, binding = 13) uniform utexture3D cluster_texture;
+layout(set = 0, binding = 16) uniform utexture3D cluster_texture;
-layout(set = 0, binding = 14, std430) restrict readonly buffer ClusterData {
+layout(set = 0, binding = 17, std430) restrict readonly buffer ClusterData {
uint indices[];
}
cluster_data;
-layout(set = 0, binding = 15) uniform texture2D directional_shadow_atlas;
+layout(set = 0, binding = 18) uniform texture2D directional_shadow_atlas;
-layout(set = 0, binding = 16, std430) restrict readonly buffer GlobalVariableData {
+layout(set = 0, binding = 19, std430) restrict readonly buffer GlobalVariableData {
vec4 data[];
}
global_variables;
@@ -312,7 +339,7 @@ layout(set = 2, binding = 0) uniform textureCubeArray reflection_atlas;
layout(set = 2, binding = 1) uniform texture2D shadow_atlas;
-/* Set 1, Render Buffers */
+/* Set 3, Render Buffers */
layout(set = 3, binding = 0) uniform texture2D depth_buffer;
layout(set = 3, binding = 1) uniform texture2D color_buffer;
diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl
index e3c26c9b72..084f28d932 100644
--- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection.glsl
@@ -1,16 +1,11 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
-
-
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-/* clang-format on */
-
layout(rgba16f, set = 0, binding = 0) uniform restrict readonly image2D source_diffuse;
layout(r32f, set = 0, binding = 1) uniform restrict readonly image2D source_depth;
layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2D ssr_image;
@@ -24,7 +19,6 @@ layout(set = 3, binding = 1) uniform sampler2D source_roughness;
#endif
layout(push_constant, binding = 2, std430) uniform Params {
-
vec4 proj_info;
ivec2 screen_size;
@@ -64,11 +58,10 @@ vec3 reconstructCSPosition(vec2 S, float z) {
}
void main() {
-
// Pixel being shaded
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing
+ if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
return;
}
@@ -156,7 +149,6 @@ void main() {
float steps_taken = 0.0;
for (int i = 0; i < params.num_steps; i++) {
-
pos += line_advance;
z += z_advance;
w += w_advance;
@@ -187,7 +179,6 @@ void main() {
}
if (found) {
-
float margin_blend = 1.0;
vec2 margin = vec2((params.screen_size.x + params.screen_size.y) * 0.5 * 0.05); // make a uniform margin
@@ -220,7 +211,6 @@ void main() {
float roughness = texelFetch(source_roughness, ssC << 1, 0).r;
if (roughness > 0.001) {
-
float cone_angle = min(roughness, 0.999) * M_PI * 0.5;
float cone_len = length(final_pos - line_begin);
float op_len = 2.0 * tan(cone_angle) * cone_len; // opposite side of iso triangle
diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl
index 1a5dd5ab55..a5afe74cb2 100644
--- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_filter.glsl
@@ -1,16 +1,11 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
-
-
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-/* clang-format on */
-
layout(rgba16f, set = 0, binding = 0) uniform restrict readonly image2D source_ssr;
layout(r8, set = 0, binding = 1) uniform restrict readonly image2D source_radius;
layout(rgba8, set = 1, binding = 0) uniform restrict readonly image2D source_normal;
@@ -22,7 +17,6 @@ layout(r8, set = 2, binding = 1) uniform restrict writeonly image2D dest_radius;
layout(r32f, set = 3, binding = 0) uniform restrict readonly image2D source_depth;
layout(push_constant, binding = 2, std430) uniform Params {
-
vec4 proj_info;
bool orthogonal;
@@ -58,7 +52,6 @@ const float gauss_table[GAUSS_TABLE_SIZE + 1] = float[](
);
float gauss_weight(float p_val) {
-
float idxf;
float c = modf(max(0.0, p_val * float(GAUSS_TABLE_SIZE)), idxf);
int idx = int(idxf);
@@ -80,7 +73,6 @@ vec3 reconstructCSPosition(vec2 S, float z) {
}
void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor, ivec2 texcoord, ivec2 increment, vec3 p_pos, vec3 normal, float p_limit_radius) {
-
for (int i = 1; i < params.steps; i++) {
float d = float(i * params.increment);
ivec2 tc = texcoord + increment * i;
@@ -104,7 +96,6 @@ void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor,
}
if (d < radius) {
-
float w = gauss_weight(d / radius);
accum += imageLoad(source_ssr, tc) * w;
#ifndef VERTICAL_PASS
@@ -116,11 +107,10 @@ void do_filter(inout vec4 accum, inout float accum_radius, inout float divisor,
}
void main() {
-
// Pixel being shaded
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing
+ if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
return;
}
diff --git a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl
index cec6c14c76..218605a962 100644
--- a/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/screen_space_reflection_scale.glsl
@@ -1,15 +1,11 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
-
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-/* clang-format on */
-
layout(set = 0, binding = 0) uniform sampler2D source_ssr;
layout(set = 1, binding = 0) uniform sampler2D source_depth;
layout(set = 1, binding = 1) uniform sampler2D source_normal;
@@ -18,7 +14,6 @@ layout(r32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_depth
layout(rgba8, set = 3, binding = 1) uniform restrict writeonly image2D dest_normal;
layout(push_constant, binding = 1, std430) uniform Params {
-
ivec2 screen_size;
float camera_z_near;
float camera_z_far;
@@ -30,11 +25,10 @@ layout(push_constant, binding = 1, std430) uniform Params {
params;
void main() {
-
// Pixel being shaded
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing
+ if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
return;
}
//do not filter, SSR will generate arctifacts if this is done
@@ -45,13 +39,11 @@ void main() {
vec3 normal;
if (params.filtered) {
-
color = vec4(0.0);
depth = 0.0;
normal = vec3(0.0);
for (int i = 0; i < 4; i++) {
-
ivec2 ofs = ssC << 1;
if (bool(i & 1)) {
ofs.x += 1;
@@ -75,7 +67,6 @@ void main() {
color /= 4.0;
depth /= 4.0;
normal = normalize(normal / 4.0) * 0.5 + 0.5;
-
} else {
color = texelFetch(source_ssr, ssC << 1, 0);
depth = texelFetch(source_depth, ssC << 1, 0).r;
diff --git a/servers/rendering/rasterizer_rd/shaders/sky.glsl b/servers/rendering/rasterizer_rd/shaders/sky.glsl
index 536077980d..9c59be6841 100644
--- a/servers/rendering/rasterizer_rd/shaders/sky.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/sky.glsl
@@ -1,12 +1,10 @@
-/* clang-format off */
-[vertex]
+#[vertex]
#version 450
VERSION_DEFINES
layout(location = 0) out vec2 uv_interp;
-/* clang-format on */
layout(push_constant, binding = 1, std430) uniform Params {
mat3 orientation;
@@ -17,14 +15,12 @@ layout(push_constant, binding = 1, std430) uniform Params {
params;
void main() {
-
vec2 base_arr[4] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 1.0), vec2(1.0, 1.0), vec2(1.0, -1.0));
uv_interp = base_arr[gl_VertexIndex];
gl_Position = vec4(uv_interp, 1.0, 1.0);
}
-/* clang-format off */
-[fragment]
+#[fragment]
#version 450
@@ -33,7 +29,6 @@ VERSION_DEFINES
#define M_PI 3.14159265359
layout(location = 0) in vec2 uv_interp;
-/* clang-format on */
layout(push_constant, binding = 1, std430) uniform Params {
mat3 orientation;
@@ -109,6 +104,7 @@ struct DirectionalLightData {
layout(set = 3, binding = 0, std140) uniform DirectionalLights {
DirectionalLightData data[MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS];
}
+
directional_lights;
/* clang-format off */
@@ -120,7 +116,6 @@ FRAGMENT_SHADER_GLOBALS
layout(location = 0) out vec4 frag_color;
void main() {
-
vec3 cube_normal;
cube_normal.z = -1.0;
cube_normal.x = (cube_normal.z * (-uv_interp.x - params.proj.x)) / params.proj.y;
diff --git a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl b/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl
index b28250318e..0b8f406213 100644
--- a/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/specular_merge.glsl
@@ -1,30 +1,25 @@
-/* clang-format off */
-[vertex]
+#[vertex]
#version 450
VERSION_DEFINES
layout(location = 0) out vec2 uv_interp;
-/* clang-format on */
void main() {
-
vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
uv_interp = base_arr[gl_VertexIndex];
gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
}
-/* clang-format off */
-[fragment]
+#[fragment]
#version 450
VERSION_DEFINES
layout(location = 0) in vec2 uv_interp;
-/* clang-format on */
layout(set = 0, binding = 0) uniform sampler2D specular;
@@ -43,13 +38,12 @@ layout(set = 2, binding = 0) uniform sampler2D diffuse;
layout(location = 0) out vec4 frag_color;
void main() {
-
frag_color.rgb = texture(specular, uv_interp).rgb;
frag_color.a = 0.0;
#ifdef MODE_SSR
- vec4 ssr = texture(ssr, uv_interp);
- frag_color.rgb = mix(frag_color.rgb, ssr.rgb, ssr.a);
+ vec4 ssr_color = texture(ssr, uv_interp);
+ frag_color.rgb = mix(frag_color.rgb, ssr_color.rgb, ssr_color.a);
#endif
#ifdef MODE_MERGE
diff --git a/servers/rendering/rasterizer_rd/shaders/ssao.glsl b/servers/rendering/rasterizer_rd/shaders/ssao.glsl
index c9d7134610..346338181a 100644
--- a/servers/rendering/rasterizer_rd/shaders/ssao.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/ssao.glsl
@@ -1,12 +1,10 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-/* clang-format on */
#define TWO_PI 6.283185307179586476925286766559
@@ -49,7 +47,6 @@ const int ROTATIONS[] = int[](
29, 21, 19, 27, 31, 29, 21, 18, 17, 29,
31, 31, 23, 18, 25, 26, 25, 23, 19, 34,
19, 27, 21, 25, 39, 29, 17, 21, 27);
-/* clang-format on */
//#define NUM_SPIRAL_TURNS (7)
const int NUM_SPIRAL_TURNS = ROTATIONS[NUM_SAMPLES - 1];
@@ -212,7 +209,7 @@ float sampleAO(in ivec2 ssC, in vec3 C, in vec3 n_C, in float ssDiskRadius, in f
void main() {
// Pixel being shaded
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing
+ if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
return;
}
diff --git a/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl b/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl
index e90c788e08..3e63e3cb59 100644
--- a/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/ssao_blur.glsl
@@ -1,12 +1,10 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-/* clang-format on */
layout(set = 0, binding = 0) uniform sampler2D source_ssao;
layout(set = 1, binding = 0) uniform sampler2D source_depth;
@@ -46,10 +44,9 @@ const float gaussian[R + 1] =
//float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0
void main() {
-
// Pixel being shaded
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing
+ if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
return;
}
@@ -122,7 +119,6 @@ void main() {
// We already handled the zero case above. This loop should be unrolled and the static branch optimized out,
// so the IF statement has no runtime cost
if (r != 0) {
-
ivec2 ppos = ssC + params.axis * (r * params.filter_scale);
float value = texelFetch(source_ssao, clamp(ppos, ivec2(0), clamp_limit), 0).r;
ivec2 rpos = clamp(ppos, ivec2(0), clamp_limit);
diff --git a/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl b/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl
index 8728154347..263fca386f 100644
--- a/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/ssao_minify.glsl
@@ -1,12 +1,10 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-/* clang-format on */
layout(push_constant, binding = 1, std430) uniform Params {
vec2 pixel_size;
@@ -26,7 +24,6 @@ layout(r32f, set = 0, binding = 0) uniform restrict readonly image2D source_imag
layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D dest_image;
void main() {
-
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
if (any(greaterThan(pos, params.source_size >> 1))) { //too large, do nothing
diff --git a/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl b/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl
index 41f8fde3ca..88a953562f 100644
--- a/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/subsurface_scattering.glsl
@@ -1,16 +1,11 @@
-/* clang-format off */
-[compute]
+#[compute]
#version 450
VERSION_DEFINES
-
-
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-/* clang-format on */
-
#ifdef USE_25_SAMPLES
const int kernel_size = 13;
@@ -93,7 +88,6 @@ const vec4 skin_kernel[kernel_size] = vec4[](
#endif //USE_11_SAMPLES
layout(push_constant, binding = 1, std430) uniform Params {
-
ivec2 screen_size;
float camera_z_far;
float camera_z_near;
@@ -113,7 +107,6 @@ layout(rgba16f, set = 1, binding = 0) uniform restrict writeonly image2D dest_im
layout(set = 2, binding = 0) uniform sampler2D source_depth;
void do_filter(inout vec3 color_accum, inout vec3 divisor, vec2 uv, vec2 step, bool p_skin) {
-
// Accumulate the other samples:
for (int i = 1; i < kernel_size; i++) {
// Fetch color and depth for current sample:
@@ -138,11 +131,10 @@ void do_filter(inout vec3 color_accum, inout vec3 divisor, vec2 uv, vec2 step, b
}
void main() {
-
// Pixel being shaded
ivec2 ssC = ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThan(ssC, params.screen_size))) { //too large, do nothing
+ if (any(greaterThanEqual(ssC, params.screen_size))) { //too large, do nothing
return;
}
@@ -153,7 +145,6 @@ void main() {
float strength = abs(base_color.a);
if (strength > 0.0) {
-
vec2 dir = params.vertical ? vec2(0.0, 1.0) : vec2(1.0, 0.0);
// Fetch linear depth of current pixel:
diff --git a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl
index a142d263e2..b7c46a7d0e 100644
--- a/servers/rendering/rasterizer_rd/shaders/tonemap.glsl
+++ b/servers/rendering/rasterizer_rd/shaders/tonemap.glsl
@@ -1,29 +1,24 @@
-/* clang-format off */
-[vertex]
+#[vertex]
#version 450
VERSION_DEFINES
layout(location = 0) out vec2 uv_interp;
-/* clang-format on */
void main() {
-
vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0));
uv_interp = base_arr[gl_VertexIndex];
gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
}
-/* clang-format off */
-[fragment]
+#[fragment]
#version 450
VERSION_DEFINES
layout(location = 0) in vec2 uv_interp;
-/* clang-format on */
layout(set = 0, binding = 0) uniform sampler2D source_color;
layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
@@ -260,7 +255,6 @@ vec3 apply_color_correction(vec3 color, sampler3D correction_tex) {
}
vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
-
const float FXAA_REDUCE_MIN = (1.0 / 128.0);
const float FXAA_REDUCE_MUL = (1.0 / 8.0);
const float FXAA_SPAN_MAX = 8.0;
@@ -298,10 +292,11 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
textureLod(source_color, uv_interp + dir * 0.5, 0.0).xyz * exposure);
float lumaB = dot(rgbB, luma);
- if ((lumaB < lumaMin) || (lumaB > lumaMax))
+ if ((lumaB < lumaMin) || (lumaB > lumaMax)) {
return rgbA;
- else
+ } else {
return rgbB;
+ }
}
void main() {
@@ -320,7 +315,6 @@ void main() {
// Early Tonemap & SRGB Conversion
if (params.use_glow && params.glow_mode == GLOW_MODE_MIX) {
-
vec3 glow = gather_glow(source_glow, uv_interp);
color.rgb = mix(color.rgb, glow, params.glow_intensity);
}
@@ -335,7 +329,6 @@ void main() {
// Glow
if (params.use_glow && params.glow_mode != GLOW_MODE_MIX) {
-
vec3 glow = gather_glow(source_glow, uv_interp) * params.glow_intensity;
// high dynamic range -> SRGB
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index 75ef38354a..55b65d2747 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -29,6 +29,8 @@
/*************************************************************************/
#include "rendering_device.h"
+#include "core/method_bind_ext.gen.inc"
+#include "rendering_device_binds.h"
RenderingDevice *RenderingDevice::singleton = nullptr;
@@ -42,6 +44,7 @@ RenderingDevice::ShaderCacheFunction RenderingDevice::cache_function = nullptr;
void RenderingDevice::shader_set_compile_function(ShaderCompileFunction p_function) {
compile_function = p_function;
}
+
void RenderingDevice::shader_set_cache_function(ShaderCacheFunction p_function) {
cache_function = p_function;
}
@@ -59,6 +62,741 @@ Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage,
return compile_function(p_stage, p_source_code, p_language, r_error);
}
+RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data) {
+ ERR_FAIL_COND_V(p_format.is_null(), RID());
+ ERR_FAIL_COND_V(p_view.is_null(), RID());
+ Vector<Vector<uint8_t>> data;
+ for (int i = 0; i < p_data.size(); i++) {
+ Vector<uint8_t> byte_slice = p_data[i];
+ ERR_FAIL_COND_V(byte_slice.empty(), RID());
+ data.push_back(byte_slice);
+ }
+ return texture_create(p_format->base, p_view->base, data);
+}
+
+RID RenderingDevice::_texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture) {
+ ERR_FAIL_COND_V(p_view.is_null(), RID());
+
+ return texture_create_shared(p_view->base, p_with_texture);
+}
+
+RID RenderingDevice::_texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type) {
+ ERR_FAIL_COND_V(p_view.is_null(), RID());
+
+ return texture_create_shared_from_slice(p_view->base, p_with_texture, p_layer, p_mipmap, p_slice_type);
+}
+
+RenderingDevice::FramebufferFormatID RenderingDevice::_framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments) {
+ Vector<AttachmentFormat> attachments;
+ attachments.resize(p_attachments.size());
+
+ for (int i = 0; i < p_attachments.size(); i++) {
+ Ref<RDAttachmentFormat> af = p_attachments[i];
+ ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID);
+ attachments.write[i] = af->base;
+ }
+ return framebuffer_format_create(attachments);
+}
+
+RID RenderingDevice::_framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check) {
+ Vector<RID> textures = Variant(p_textures);
+ return framebuffer_create(textures, p_format_check);
+}
+
+RID RenderingDevice::_sampler_create(const Ref<RDSamplerState> &p_state) {
+ ERR_FAIL_COND_V(p_state.is_null(), RID());
+
+ return sampler_create(p_state->base);
+}
+
+RenderingDevice::VertexFormatID RenderingDevice::_vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats) {
+ Vector<VertexAttribute> descriptions;
+ descriptions.resize(p_vertex_formats.size());
+
+ for (int i = 0; i < p_vertex_formats.size(); i++) {
+ Ref<RDVertexAttribute> af = p_vertex_formats[i];
+ ERR_FAIL_COND_V(af.is_null(), INVALID_FORMAT_ID);
+ descriptions.write[i] = af->base;
+ }
+ return vertex_format_create(descriptions);
+}
+
+RID RenderingDevice::_vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers) {
+ Vector<RID> buffers = Variant(p_src_buffers);
+
+ return vertex_array_create(p_vertex_count, p_vertex_format, buffers);
+}
+
+Ref<RDShaderBytecode> RenderingDevice::_shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache) {
+ ERR_FAIL_COND_V(p_source.is_null(), Ref<RDShaderBytecode>());
+
+ Ref<RDShaderBytecode> bytecode;
+ bytecode.instance();
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ String error;
+
+ ShaderStage stage = ShaderStage(i);
+ Vector<uint8_t> spirv = shader_compile_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache);
+ bytecode->set_stage_bytecode(stage, spirv);
+ bytecode->set_stage_compile_error(stage, error);
+ }
+ return bytecode;
+}
+
+RID RenderingDevice::shader_create_from_bytecode(const Ref<RDShaderBytecode> &p_bytecode) {
+ ERR_FAIL_COND_V(p_bytecode.is_null(), RID());
+
+ Vector<ShaderStageData> stage_data;
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ ShaderStage stage = ShaderStage(i);
+ ShaderStageData sd;
+ sd.shader_stage = stage;
+ String error = p_bytecode->get_stage_compile_error(stage);
+ ERR_FAIL_COND_V_MSG(error != String(), RID(), "Can't create a shader from an errored bytecode. Check errors in source bytecode.");
+ sd.spir_v = p_bytecode->get_stage_bytecode(stage);
+ if (sd.spir_v.empty()) {
+ continue;
+ }
+ stage_data.push_back(sd);
+ }
+
+ return shader_create(stage_data);
+}
+
+RID RenderingDevice::_uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set) {
+ Vector<Uniform> uniforms;
+ uniforms.resize(p_uniforms.size());
+ for (int i = 0; i < p_uniforms.size(); i++) {
+ Ref<RDUniform> uniform = p_uniforms[i];
+ ERR_FAIL_COND_V(!uniform.is_valid(), RID());
+ uniforms.write[i] = uniform->base;
+ }
+ return uniform_set_create(uniforms, p_shader, p_shader_set);
+}
+
+Error RenderingDevice::_buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw) {
+ return buffer_update(p_buffer, p_offset, p_size, p_data.ptr(), p_sync_with_draw);
+}
+
+RID RenderingDevice::_render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags) {
+ PipelineRasterizationState rasterization_state;
+ if (p_rasterization_state.is_valid()) {
+ rasterization_state = p_rasterization_state->base;
+ }
+
+ PipelineMultisampleState multisample_state;
+ if (p_multisample_state.is_valid()) {
+ multisample_state = p_multisample_state->base;
+ for (int i = 0; i < p_multisample_state->sample_masks.size(); i++) {
+ int64_t mask = p_multisample_state->sample_masks[i];
+ multisample_state.sample_mask.push_back(mask);
+ }
+ }
+
+ PipelineDepthStencilState depth_stencil_state;
+ if (p_depth_stencil_state.is_valid()) {
+ depth_stencil_state = p_depth_stencil_state->base;
+ }
+
+ PipelineColorBlendState color_blend_state;
+ if (p_blend_state.is_valid()) {
+ color_blend_state = p_blend_state->base;
+ for (int i = 0; i < p_blend_state->attachments.size(); i++) {
+ Ref<RDPipelineColorBlendStateAttachment> attachment = p_blend_state->attachments[i];
+ if (attachment.is_valid()) {
+ color_blend_state.attachments.push_back(attachment->base);
+ }
+ }
+ }
+
+ return render_pipeline_create(p_shader, p_framebuffer_format, p_vertex_format, p_render_primitive, rasterization_state, multisample_state, depth_stencil_state, color_blend_state, p_dynamic_state_flags);
+}
+
+Vector<int64_t> RenderingDevice::_draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region) {
+ Vector<DrawListID> splits;
+ splits.resize(p_splits);
+ draw_list_begin_split(p_framebuffer, p_splits, splits.ptrw(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region);
+
+ Vector<int64_t> split_ids;
+ split_ids.resize(splits.size());
+ for (int i = 0; i < splits.size(); i++) {
+ split_ids.write[i] = splits[i];
+ }
+
+ return split_ids;
+}
+
+void RenderingDevice::_draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) {
+ ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size);
+ draw_list_set_push_constant(p_list, p_data.ptr(), p_data_size);
+}
+
+void RenderingDevice::_compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size) {
+ ERR_FAIL_COND((uint32_t)p_data.size() > p_data_size);
+ compute_list_set_push_constant(p_list, p_data.ptr(), p_data_size);
+}
+
+void RenderingDevice::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("texture_create", "format", "view", "data"), &RenderingDevice::_texture_create, DEFVAL(Array()));
+ ClassDB::bind_method(D_METHOD("texture_create_shared", "view", "with_texture"), &RenderingDevice::_texture_create_shared);
+ ClassDB::bind_method(D_METHOD("texture_create_shared_from_slice", "view", "with_texture", "layer", "mipmap", "slice_type"), &RenderingDevice::_texture_create_shared_from_slice, DEFVAL(TEXTURE_SLICE_2D));
+
+ ClassDB::bind_method(D_METHOD("texture_update", "texture", "layer", "data", "sync_with_draw"), &RenderingDevice::texture_update, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "layer"), &RenderingDevice::texture_get_data);
+
+ ClassDB::bind_method(D_METHOD("texture_is_format_supported_for_usage", "format", "usage_flags"), &RenderingDevice::texture_is_format_supported_for_usage);
+
+ ClassDB::bind_method(D_METHOD("texture_is_shared", "texture"), &RenderingDevice::texture_is_shared);
+ ClassDB::bind_method(D_METHOD("texture_is_valid", "texture"), &RenderingDevice::texture_is_valid);
+
+ ClassDB::bind_method(D_METHOD("texture_copy", "from_texture", "to_texture", "from_pos", "to_pos", "size", "src_mipmap", "dst_mipmap", "src_layer", "dst_layer", "sync_with_draw"), &RenderingDevice::texture_copy, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("texture_clear", "texture", "color", "base_mipmap", "mipmap_count", "base_layer", "layer_count", "sync_with_draw"), &RenderingDevice::texture_clear, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("texture_resolve_multisample", "from_texture", "to_texture", "sync_with_draw"), &RenderingDevice::texture_resolve_multisample, DEFVAL(false));
+
+ ClassDB::bind_method(D_METHOD("framebuffer_format_create", "attachments"), &RenderingDevice::_framebuffer_format_create);
+ ClassDB::bind_method(D_METHOD("framebuffer_format_get_texture_samples", "format"), &RenderingDevice::framebuffer_format_get_texture_samples);
+ ClassDB::bind_method(D_METHOD("framebuffer_create", "textures", "validate_with_format"), &RenderingDevice::_framebuffer_create, DEFVAL(INVALID_FORMAT_ID));
+ ClassDB::bind_method(D_METHOD("framebuffer_get_format", "framebuffer"), &RenderingDevice::framebuffer_get_format);
+
+ ClassDB::bind_method(D_METHOD("sampler_create", "state"), &RenderingDevice::_sampler_create);
+
+ ClassDB::bind_method(D_METHOD("vertex_buffer_create", "size_bytes", "data"), &RenderingDevice::vertex_buffer_create, DEFVAL(Vector<uint8_t>()));
+ ClassDB::bind_method(D_METHOD("vertex_format_create", "vertex_descriptions"), &RenderingDevice::_vertex_format_create);
+
+ ClassDB::bind_method(D_METHOD("index_buffer_create", "size_indices", "format", "data"), &RenderingDevice::index_buffer_create, DEFVAL(Vector<uint8_t>()), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("index_array_create", "index_buffer", "index_offset", "index_count"), &RenderingDevice::index_array_create);
+
+ ClassDB::bind_method(D_METHOD("shader_compile_from_source", "shader_source", "allow_cache"), &RenderingDevice::_shader_compile_from_source, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("shader_create", "shader_data"), &RenderingDevice::shader_create_from_bytecode);
+ ClassDB::bind_method(D_METHOD("shader_get_vertex_input_attribute_mask", "shader"), &RenderingDevice::shader_get_vertex_input_attribute_mask);
+
+ ClassDB::bind_method(D_METHOD("uniform_buffer_create", "size_bytes", "data"), &RenderingDevice::uniform_buffer_create, DEFVAL(Vector<uint8_t>()));
+ ClassDB::bind_method(D_METHOD("storage_buffer_create", "size_bytes", "data"), &RenderingDevice::storage_buffer_create, DEFVAL(Vector<uint8_t>()));
+ ClassDB::bind_method(D_METHOD("texture_buffer_create", "size_bytes", "format", "data"), &RenderingDevice::texture_buffer_create, DEFVAL(Vector<uint8_t>()));
+
+ ClassDB::bind_method(D_METHOD("uniform_set_create", "uniforms", "shader", "shader_set"), &RenderingDevice::_uniform_set_create);
+ ClassDB::bind_method(D_METHOD("uniform_set_is_valid", "uniform_set"), &RenderingDevice::uniform_set_is_valid);
+
+ ClassDB::bind_method(D_METHOD("buffer_update", "buffer", "offset", "size_bytes", "data", "sync_with_draw"), &RenderingDevice::_buffer_update, DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("buffer_get_data", "buffer"), &RenderingDevice::buffer_get_data);
+
+ ClassDB::bind_method(D_METHOD("render_pipeline_create", "shader", "framebuffer_format", "vertex_format", "primitive", "rasterization_state", "multisample_state", "stencil_state", "color_blend_state", "dynamic_state_flags"), &RenderingDevice::_render_pipeline_create, DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("render_pipeline_is_valid", "render_pipeline"), &RenderingDevice::render_pipeline_is_valid);
+
+ ClassDB::bind_method(D_METHOD("compute_pipeline_create", "shader"), &RenderingDevice::compute_pipeline_create);
+ ClassDB::bind_method(D_METHOD("compute_pipeline_is_valid", "compute_pieline"), &RenderingDevice::compute_pipeline_is_valid);
+
+ ClassDB::bind_method(D_METHOD("screen_get_width", "screen"), &RenderingDevice::screen_get_width, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("screen_get_height", "screen"), &RenderingDevice::screen_get_height, DEFVAL(DisplayServer::MAIN_WINDOW_ID));
+ ClassDB::bind_method(D_METHOD("screen_get_framebuffer_format"), &RenderingDevice::screen_get_framebuffer_format);
+
+ ClassDB::bind_method(D_METHOD("draw_list_begin_for_screen", "screen", "clear_color"), &RenderingDevice::draw_list_begin_for_screen, DEFVAL(DisplayServer::MAIN_WINDOW_ID), DEFVAL(Color()));
+
+ ClassDB::bind_method(D_METHOD("draw_list_begin", "framebuffer", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::draw_list_begin, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i()));
+ ClassDB::bind_method(D_METHOD("draw_list_begin_split", "framebuffer", "splits", "initial_color_action", "final_color_action", "initial_depth_action", "final_depth_action", "clear_color_values", "clear_depth", "clear_stencil", "region"), &RenderingDevice::_draw_list_begin_split, DEFVAL(Vector<Color>()), DEFVAL(1.0), DEFVAL(0), DEFVAL(Rect2i()));
+
+ ClassDB::bind_method(D_METHOD("draw_list_bind_render_pipeline", "draw_list", "render_pipeline"), &RenderingDevice::draw_list_bind_render_pipeline);
+ ClassDB::bind_method(D_METHOD("draw_list_bind_uniform_set", "draw_list", "uniform_set", "set_index"), &RenderingDevice::draw_list_bind_uniform_set);
+ ClassDB::bind_method(D_METHOD("draw_list_bind_vertex_array", "draw_list", "vertex_array"), &RenderingDevice::draw_list_bind_vertex_array);
+ ClassDB::bind_method(D_METHOD("draw_list_bind_index_array", "draw_list", "index_array"), &RenderingDevice::draw_list_bind_index_array);
+ ClassDB::bind_method(D_METHOD("draw_list_set_push_constant", "draw_list", "buffer", "size_bytes"), &RenderingDevice::_draw_list_set_push_constant);
+
+ ClassDB::bind_method(D_METHOD("draw_list_draw", "draw_list", "use_indices", "instances", "procedural_vertex_count"), &RenderingDevice::draw_list_draw, DEFVAL(0));
+
+ ClassDB::bind_method(D_METHOD("draw_list_enable_scissor", "draw_list", "rect"), &RenderingDevice::draw_list_enable_scissor, DEFVAL(Rect2i()));
+ ClassDB::bind_method(D_METHOD("draw_list_disable_scissor", "draw_list"), &RenderingDevice::draw_list_disable_scissor);
+
+ ClassDB::bind_method(D_METHOD("draw_list_end"), &RenderingDevice::draw_list_end);
+
+ ClassDB::bind_method(D_METHOD("compute_list_begin"), &RenderingDevice::compute_list_begin);
+ ClassDB::bind_method(D_METHOD("compute_list_bind_compute_pipeline", "compute_list", "compute_pipeline"), &RenderingDevice::compute_list_bind_compute_pipeline);
+ ClassDB::bind_method(D_METHOD("compute_list_set_push_constant", "compute_list", "buffer", "size_bytes"), &RenderingDevice::_compute_list_set_push_constant);
+ ClassDB::bind_method(D_METHOD("compute_list_bind_uniform_set", "compute_list", "uniform_set", "set_index"), &RenderingDevice::compute_list_bind_uniform_set);
+ ClassDB::bind_method(D_METHOD("compute_list_dispatch", "compute_list", "x_groups", "y_groups", "z_groups"), &RenderingDevice::compute_list_dispatch);
+ ClassDB::bind_method(D_METHOD("compute_list_add_barrier", "compute_list"), &RenderingDevice::compute_list_add_barrier);
+ ClassDB::bind_method(D_METHOD("compute_list_end"), &RenderingDevice::compute_list_end);
+
+ ClassDB::bind_method(D_METHOD("free", "rid"), &RenderingDevice::free);
+
+ ClassDB::bind_method(D_METHOD("capture_timestamp", "name", "sync_to_draw"), &RenderingDevice::capture_timestamp);
+ ClassDB::bind_method(D_METHOD("get_captured_timestamps_count"), &RenderingDevice::get_captured_timestamps_count);
+ ClassDB::bind_method(D_METHOD("get_captured_timestamps_frame"), &RenderingDevice::get_captured_timestamps_frame);
+ ClassDB::bind_method(D_METHOD("get_captured_timestamp_gpu_time", "index"), &RenderingDevice::get_captured_timestamp_gpu_time);
+ ClassDB::bind_method(D_METHOD("get_captured_timestamp_cpu_time", "index"), &RenderingDevice::get_captured_timestamp_cpu_time);
+ ClassDB::bind_method(D_METHOD("get_captured_timestamp_name", "index"), &RenderingDevice::get_captured_timestamp_name);
+
+ ClassDB::bind_method(D_METHOD("limit_get", "limit"), &RenderingDevice::limit_get);
+ ClassDB::bind_method(D_METHOD("get_frame_delay"), &RenderingDevice::get_frame_delay);
+ ClassDB::bind_method(D_METHOD("submit"), &RenderingDevice::submit);
+ ClassDB::bind_method(D_METHOD("sync"), &RenderingDevice::sync);
+
+ ClassDB::bind_method(D_METHOD("create_local_device"), &RenderingDevice::create_local_device);
+
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4_UNORM_PACK8);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R4G4B4A4_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B4G4R4A4_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R5G6B5_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B5G6R5_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R5G5B5A1_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B5G5R5A1_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A1R5G5B5_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R8G8B8A8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8A8_SRGB);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_USCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SSCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_UINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A8B8G8R8_SRGB_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_USCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SSCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_UINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2R10G10B10_SINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_USCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SSCALED_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_UINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_A2B10G10R10_SINT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_USCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SSCALED);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R16G16B16A16_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R32G32B32A32_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R64G64B64A64_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B10G11R11_UFLOAT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_E5B9G9R9_UFLOAT_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_X8_D24_UNORM_PACK32);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_S8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_D16_UNORM_S8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_D24_UNORM_S8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_D32_SFLOAT_S8_UINT);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGB_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC1_RGBA_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC2_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC3_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC4_SNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC5_SNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_UFLOAT_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC6H_SFLOAT_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_BC7_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11_SNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_EAC_R11G11_SNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_4x4_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x4_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_5x5_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x5_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_6x6_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x5_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x6_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_8x8_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x5_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x6_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x8_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_10x10_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x10_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_UNORM_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_ASTC_12x12_SRGB_BLOCK);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8B8G8R8_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B8G8R8G8_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_420_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_420_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8R8_2PLANE_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G8_B8_R8_3PLANE_444_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6_UNORM_2PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4_UNORM_PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4_UNORM_2PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16B16G16R16_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_B16G16R16G16_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_420_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_420_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16R16_2PLANE_422_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_G16_B16_R16_3PLANE_444_UNORM);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG);
+ BIND_ENUM_CONSTANT(DATA_FORMAT_MAX);
+
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_3D);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_1D_ARRAY);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_2D_ARRAY);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_CUBE_ARRAY);
+ BIND_ENUM_CONSTANT(TEXTURE_TYPE_MAX);
+
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_1);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_2);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_4);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_8);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_16);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_32);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_64);
+ BIND_ENUM_CONSTANT(TEXTURE_SAMPLES_MAX);
+
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_SAMPLING_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_COLOR_ATTACHMENT_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_STORAGE_ATOMIC_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_CPU_READ_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_UPDATE_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_FROM_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_CAN_COPY_TO_BIT);
+ BIND_ENUM_CONSTANT(TEXTURE_USAGE_RESOLVE_ATTACHMENT_BIT);
+
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_IDENTITY);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ZERO);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_ONE);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_R);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_G);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_B);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_A);
+ BIND_ENUM_CONSTANT(TEXTURE_SWIZZLE_MAX);
+
+ BIND_ENUM_CONSTANT(TEXTURE_SLICE_2D);
+ BIND_ENUM_CONSTANT(TEXTURE_SLICE_CUBEMAP);
+ BIND_ENUM_CONSTANT(TEXTURE_SLICE_3D);
+
+ BIND_ENUM_CONSTANT(SAMPLER_FILTER_NEAREST);
+ BIND_ENUM_CONSTANT(SAMPLER_FILTER_LINEAR);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_REPEAT);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRRORED_REPEAT);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_EDGE);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_CLAMP_TO_BORDER);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MIRROR_CLAMP_TO_EDGE);
+ BIND_ENUM_CONSTANT(SAMPLER_REPEAT_MODE_MAX);
+
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_TRANSPARENT_BLACK);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_BLACK);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_BLACK);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_FLOAT_OPAQUE_WHITE);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_INT_OPAQUE_WHITE);
+ BIND_ENUM_CONSTANT(SAMPLER_BORDER_COLOR_MAX);
+
+ BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_VERTEX);
+ BIND_ENUM_CONSTANT(VERTEX_FREQUENCY_INSTANCE);
+
+ BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT16);
+ BIND_ENUM_CONSTANT(INDEX_BUFFER_FORMAT_UINT32);
+
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER); //for sampling only (sampler GLSL type)
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE); // for sampling only); but includes a texture); (samplerXX GLSL type)); first a sampler then a texture
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE); //only texture); (textureXX GLSL type)
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE); // storage image (imageXX GLSL type)); for compute mostly
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_TEXTURE_BUFFER); // buffer texture (or TBO); textureBuffer type)
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_SAMPLER_WITH_TEXTURE_BUFFER); // buffer texture with a sampler(or TBO); samplerBuffer type)
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_IMAGE_BUFFER); //texel buffer); (imageBuffer type)); for compute mostly
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_UNIFORM_BUFFER); //regular uniform buffer (or UBO).
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_STORAGE_BUFFER); //storage buffer ("buffer" qualifier) like UBO); but supports storage); for compute mostly
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_INPUT_ATTACHMENT); //used for sub-pass read/write); for mobile mostly
+ BIND_ENUM_CONSTANT(UNIFORM_TYPE_MAX);
+
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_POINTS);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINES_WITH_ADJACENCY);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_LINESTRIPS_WITH_ADJACENCY);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLES_WITH_ADJACENCY);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_AJACENCY);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TRIANGLE_STRIPS_WITH_RESTART_INDEX);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_TESSELATION_PATCH);
+ BIND_ENUM_CONSTANT(RENDER_PRIMITIVE_MAX);
+
+ BIND_ENUM_CONSTANT(POLYGON_CULL_DISABLED);
+ BIND_ENUM_CONSTANT(POLYGON_CULL_FRONT);
+ BIND_ENUM_CONSTANT(POLYGON_CULL_BACK);
+
+ BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_CLOCKWISE);
+ BIND_ENUM_CONSTANT(POLYGON_FRONT_FACE_COUNTER_CLOCKWISE);
+
+ BIND_ENUM_CONSTANT(STENCIL_OP_KEEP);
+ BIND_ENUM_CONSTANT(STENCIL_OP_ZERO);
+ BIND_ENUM_CONSTANT(STENCIL_OP_REPLACE);
+ BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_CLAMP);
+ BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_CLAMP);
+ BIND_ENUM_CONSTANT(STENCIL_OP_INVERT);
+ BIND_ENUM_CONSTANT(STENCIL_OP_INCREMENT_AND_WRAP);
+ BIND_ENUM_CONSTANT(STENCIL_OP_DECREMENT_AND_WRAP);
+ BIND_ENUM_CONSTANT(STENCIL_OP_MAX); //not an actual operator); just the amount of operators :D
+
+ BIND_ENUM_CONSTANT(COMPARE_OP_NEVER);
+ BIND_ENUM_CONSTANT(COMPARE_OP_LESS);
+ BIND_ENUM_CONSTANT(COMPARE_OP_EQUAL);
+ BIND_ENUM_CONSTANT(COMPARE_OP_LESS_OR_EQUAL);
+ BIND_ENUM_CONSTANT(COMPARE_OP_GREATER);
+ BIND_ENUM_CONSTANT(COMPARE_OP_NOT_EQUAL);
+ BIND_ENUM_CONSTANT(COMPARE_OP_GREATER_OR_EQUAL);
+ BIND_ENUM_CONSTANT(COMPARE_OP_ALWAYS);
+ BIND_ENUM_CONSTANT(COMPARE_OP_MAX);
+
+ BIND_ENUM_CONSTANT(LOGIC_OP_CLEAR);
+ BIND_ENUM_CONSTANT(LOGIC_OP_AND);
+ BIND_ENUM_CONSTANT(LOGIC_OP_AND_REVERSE);
+ BIND_ENUM_CONSTANT(LOGIC_OP_COPY);
+ BIND_ENUM_CONSTANT(LOGIC_OP_AND_INVERTED);
+ BIND_ENUM_CONSTANT(LOGIC_OP_NO_OP);
+ BIND_ENUM_CONSTANT(LOGIC_OP_XOR);
+ BIND_ENUM_CONSTANT(LOGIC_OP_OR);
+ BIND_ENUM_CONSTANT(LOGIC_OP_NOR);
+ BIND_ENUM_CONSTANT(LOGIC_OP_EQUIVALENT);
+ BIND_ENUM_CONSTANT(LOGIC_OP_INVERT);
+ BIND_ENUM_CONSTANT(LOGIC_OP_OR_REVERSE);
+ BIND_ENUM_CONSTANT(LOGIC_OP_COPY_INVERTED);
+ BIND_ENUM_CONSTANT(LOGIC_OP_OR_INVERTED);
+ BIND_ENUM_CONSTANT(LOGIC_OP_NAND);
+ BIND_ENUM_CONSTANT(LOGIC_OP_SET);
+ BIND_ENUM_CONSTANT(LOGIC_OP_MAX); //not an actual operator); just the amount of operators :D
+
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ZERO);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_DST_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_DST_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_CONSTANT_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC_ALPHA_SATURATE);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_COLOR);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_SRC1_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA);
+ BIND_ENUM_CONSTANT(BLEND_FACTOR_MAX);
+
+ BIND_ENUM_CONSTANT(BLEND_OP_ADD);
+ BIND_ENUM_CONSTANT(BLEND_OP_SUBTRACT);
+ BIND_ENUM_CONSTANT(BLEND_OP_REVERSE_SUBTRACT);
+ BIND_ENUM_CONSTANT(BLEND_OP_MINIMUM);
+ BIND_ENUM_CONSTANT(BLEND_OP_MAXIMUM);
+ BIND_ENUM_CONSTANT(BLEND_OP_MAX);
+
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_LINE_WIDTH);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BIAS);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_BLEND_CONSTANTS);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_DEPTH_BOUNDS);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_COMPARE_MASK);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_WRITE_MASK);
+ BIND_ENUM_CONSTANT(DYNAMIC_STATE_STENCIL_REFERENCE);
+
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_CLEAR); //start rendering and clear the framebuffer (supply params)
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_KEEP); //start rendering); but keep attached color texture contents (depth will be cleared)
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_DROP); //start rendering); ignore what is there); just write above it
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_CONTINUE); //continue rendering (framebuffer must have been left in "continue" state as final action previously)
+ BIND_ENUM_CONSTANT(INITIAL_ACTION_MAX);
+
+ BIND_ENUM_CONSTANT(FINAL_ACTION_READ); //will no longer render to it); allows attached textures to be read again); but depth buffer contents will be dropped (Can't be read from)
+ BIND_ENUM_CONSTANT(FINAL_ACTION_DISCARD); // discard contents after rendering
+ BIND_ENUM_CONSTANT(FINAL_ACTION_CONTINUE); //will continue rendering later); attached textures can't be read until re-bound with "finish"
+ BIND_ENUM_CONSTANT(FINAL_ACTION_MAX);
+
+ BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_MAX);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_VERTEX_BIT);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_FRAGMENT_BIT);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_CONTROL_BIT);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_TESSELATION_EVALUATION_BIT);
+ BIND_ENUM_CONSTANT(SHADER_STAGE_COMPUTE_BIT);
+
+ BIND_ENUM_CONSTANT(SHADER_LANGUAGE_GLSL);
+ BIND_ENUM_CONSTANT(SHADER_LANGUAGE_HLSL);
+
+ BIND_ENUM_CONSTANT(LIMIT_MAX_BOUND_UNIFORM_SETS);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_COLOR_ATTACHMENTS);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_UNIFORM_SET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_UNIFORM_SET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_UNIFORM_SET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_UNIFORM_SET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_UNIFORM_SET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_DRAW_INDEXED_INDEX);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_HEIGHT);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_FRAMEBUFFER_WIDTH);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_ARRAY_LAYERS);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_1D);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_2D);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_3D);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURE_SIZE_CUBE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_SAMPLERS_PER_SHADER_STAGE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_BUFFERS_PER_SHADER_STAGE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_STORAGE_IMAGES_PER_SHADER_STAGE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFERS_PER_SHADER_STAGE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_PUSH_CONSTANT_SIZE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_UNIFORM_BUFFER_SIZE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_ATTRIBUTES);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDINGS);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_VERTEX_INPUT_BINDING_STRIDE);
+ BIND_ENUM_CONSTANT(LIMIT_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_SHARED_MEMORY_SIZE);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_X);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Y);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_COUNT_Z);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_INVOCATIONS);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_X);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Y);
+ BIND_ENUM_CONSTANT(LIMIT_MAX_COMPUTE_WORKGROUP_SIZE_Z);
+
+ BIND_CONSTANT(INVALID_ID);
+ BIND_CONSTANT(INVALID_FORMAT_ID);
+}
+
RenderingDevice::RenderingDevice() {
if (singleton == nullptr) { // there may be more rendering devices later
singleton = this;
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index 6c58b8fd57..ee39ee11ed 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -32,8 +32,22 @@
#define RENDERING_DEVICE_H
#include "core/object.h"
+#include "core/typed_array.h"
#include "servers/display_server.h"
+class RDTextureFormat;
+class RDTextureView;
+class RDAttachmentFormat;
+class RDSamplerState;
+class RDVertexAttribute;
+class RDShaderSource;
+class RDShaderBytecode;
+class RDUniforms;
+class RDPipelineRasterizationState;
+class RDPipelineMultisampleState;
+class RDPipelineDepthStencilState;
+class RDPipelineColorBlendState;
+
class RenderingDevice : public Object {
GDCLASS(RenderingDevice, Object)
public:
@@ -65,10 +79,14 @@ private:
static RenderingDevice *singleton;
+protected:
+ static void _bind_methods();
+
public:
//base numeric ID for all types
enum {
- INVALID_ID = -1
+ INVALID_ID = -1,
+ INVALID_FORMAT_ID = -1
};
/*****************/
@@ -530,13 +548,13 @@ public:
VERTEX_FREQUENCY_INSTANCE,
};
- struct VertexDescription {
+ struct VertexAttribute {
uint32_t location; //shader location
uint32_t offset;
DataFormat format;
uint32_t stride;
VertexFrequency frequency;
- VertexDescription() {
+ VertexAttribute() {
location = 0;
offset = 0;
stride = 0;
@@ -549,7 +567,7 @@ public:
typedef int64_t VertexFormatID;
// This ID is warranted to be unique for the same formats, does not need to be freed
- virtual VertexFormatID vertex_format_create(const Vector<VertexDescription> &p_vertex_formats) = 0;
+ virtual VertexFormatID vertex_format_create(const Vector<VertexAttribute> &p_vertex_formats) = 0;
virtual RID vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const Vector<RID> &p_src_buffers) = 0;
enum IndexBufferFormat {
@@ -578,6 +596,7 @@ public:
}
};
+ RID shader_create_from_bytecode(const Ref<RDShaderBytecode> &p_bytecode);
virtual RID shader_create(const Vector<ShaderStageData> &p_stages) = 0;
virtual uint32_t shader_get_vertex_input_attribute_mask(RID p_shader) = 0;
@@ -595,7 +614,7 @@ public:
UNIFORM_TYPE_IMAGE_BUFFER, //texel buffer, (imageBuffer type), for compute mostly
UNIFORM_TYPE_UNIFORM_BUFFER, //regular uniform buffer (or UBO).
UNIFORM_TYPE_STORAGE_BUFFER, //storage buffer ("buffer" qualifier) like UBO, but supports storage, for compute mostly
- UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for compute mostly
+ UNIFORM_TYPE_INPUT_ATTACHMENT, //used for sub-pass read/write, for mobile mostly
UNIFORM_TYPE_MAX
};
@@ -767,7 +786,6 @@ public:
};
struct PipelineDepthStencilState {
-
bool enable_depth_test;
bool enable_depth_write;
CompareOperator depth_compare_operator;
@@ -796,8 +814,8 @@ public:
}
};
- StencilOperationState stencil_operation_front;
- StencilOperationState stencil_operation_back;
+ StencilOperationState front_op;
+ StencilOperationState back_op;
PipelineDepthStencilState() {
enable_depth_test = false;
@@ -811,7 +829,6 @@ public:
};
struct PipelineColorBlendState {
-
bool enable_logic_op;
LogicOperation logic_op;
struct Attachment {
@@ -852,7 +869,6 @@ public:
static PipelineColorBlendState create_blend(int p_attachments = 1) {
PipelineColorBlendState bs;
for (int i = 0; i < p_attachments; i++) {
-
Attachment ba;
ba.enable_blend = true;
ba.src_color_blend_factor = BLEND_FACTOR_SRC_ALPHA;
@@ -884,8 +900,8 @@ public:
DYNAMIC_STATE_STENCIL_REFERENCE = (1 << 6),
};
- virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0;
virtual bool render_pipeline_is_valid(RID p_pipeline) = 0;
+ virtual RID render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const PipelineRasterizationState &p_rasterization_state, const PipelineMultisampleState &p_multisample_state, const PipelineDepthStencilState &p_depth_stencil_state, const PipelineColorBlendState &p_blend_state, int p_dynamic_state_flags = 0) = 0;
/**************************/
/**** COMPUTE PIPELINE ****/
@@ -932,7 +948,7 @@ public:
virtual void draw_list_bind_vertex_array(DrawListID p_list, RID p_vertex_array) = 0;
virtual void draw_list_bind_index_array(DrawListID p_list, RID p_index_array) = 0;
virtual void draw_list_set_line_width(DrawListID p_list, float p_width) = 0;
- virtual void draw_list_set_push_constant(DrawListID p_list, void *p_data, uint32_t p_data_size) = 0;
+ virtual void draw_list_set_push_constant(DrawListID p_list, const void *p_data, uint32_t p_data_size) = 0;
virtual void draw_list_draw(DrawListID p_list, bool p_use_indices, uint32_t p_instances = 1, uint32_t p_procedural_vertices = 0) = 0;
@@ -950,7 +966,7 @@ public:
virtual ComputeListID compute_list_begin() = 0;
virtual void compute_list_bind_compute_pipeline(ComputeListID p_list, RID p_compute_pipeline) = 0;
virtual void compute_list_bind_uniform_set(ComputeListID p_list, RID p_uniform_set, uint32_t p_index) = 0;
- virtual void compute_list_set_push_constant(ComputeListID p_list, void *p_data, uint32_t p_data_size) = 0;
+ virtual void compute_list_set_push_constant(ComputeListID p_list, const void *p_data, uint32_t p_data_size) = 0;
virtual void compute_list_dispatch(ComputeListID p_list, uint32_t p_x_groups, uint32_t p_y_groups, uint32_t p_z_groups) = 0;
virtual void compute_list_add_barrier(ComputeListID p_list) = 0;
@@ -1027,12 +1043,65 @@ public:
virtual void submit() = 0;
virtual void sync() = 0;
+ virtual uint64_t get_memory_usage() const = 0;
+
virtual RenderingDevice *create_local_device() = 0;
static RenderingDevice *get_singleton();
RenderingDevice();
+
+protected:
+ //binders to script API
+ RID _texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data = Array());
+ RID _texture_create_shared(const Ref<RDTextureView> &p_view, RID p_with_texture);
+ RID _texture_create_shared_from_slice(const Ref<RDTextureView> &p_view, RID p_with_texture, uint32_t p_layer, uint32_t p_mipmap, TextureSliceType p_slice_type = TEXTURE_SLICE_2D);
+
+ FramebufferFormatID _framebuffer_format_create(const TypedArray<RDAttachmentFormat> &p_attachments);
+ RID _framebuffer_create(const Array &p_textures, FramebufferFormatID p_format_check = INVALID_ID);
+ RID _sampler_create(const Ref<RDSamplerState> &p_state);
+ VertexFormatID _vertex_format_create(const TypedArray<RDVertexAttribute> &p_vertex_formats);
+ RID _vertex_array_create(uint32_t p_vertex_count, VertexFormatID p_vertex_format, const TypedArray<RID> &p_src_buffers);
+
+ Ref<RDShaderBytecode> _shader_compile_from_source(const Ref<RDShaderSource> &p_source, bool p_allow_cache = true);
+
+ RID _uniform_set_create(const Array &p_uniforms, RID p_shader, uint32_t p_shader_set);
+
+ Error _buffer_update(RID p_buffer, uint32_t p_offset, uint32_t p_size, const Vector<uint8_t> &p_data, bool p_sync_with_draw = false);
+
+ RID _render_pipeline_create(RID p_shader, FramebufferFormatID p_framebuffer_format, VertexFormatID p_vertex_format, RenderPrimitive p_render_primitive, const Ref<RDPipelineRasterizationState> &p_rasterization_state, const Ref<RDPipelineMultisampleState> &p_multisample_state, const Ref<RDPipelineDepthStencilState> &p_depth_stencil_state, const Ref<RDPipelineColorBlendState> &p_blend_state, int p_dynamic_state_flags = 0);
+
+ Vector<int64_t> _draw_list_begin_split(RID p_framebuffer, uint32_t p_splits, InitialAction p_initial_color_action, FinalAction p_final_color_action, InitialAction p_initial_depth_action, FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values = Vector<Color>(), float p_clear_depth = 1.0, uint32_t p_clear_stencil = 0, const Rect2 &p_region = Rect2());
+ void _draw_list_set_push_constant(DrawListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
+ void _compute_list_set_push_constant(ComputeListID p_list, const Vector<uint8_t> &p_data, uint32_t p_data_size);
};
+VARIANT_ENUM_CAST(RenderingDevice::ShaderStage)
+VARIANT_ENUM_CAST(RenderingDevice::ShaderLanguage)
+VARIANT_ENUM_CAST(RenderingDevice::CompareOperator)
+VARIANT_ENUM_CAST(RenderingDevice::DataFormat)
+VARIANT_ENUM_CAST(RenderingDevice::TextureType)
+VARIANT_ENUM_CAST(RenderingDevice::TextureSamples)
+VARIANT_ENUM_CAST(RenderingDevice::TextureUsageBits)
+VARIANT_ENUM_CAST(RenderingDevice::TextureSwizzle)
+VARIANT_ENUM_CAST(RenderingDevice::TextureSliceType)
+VARIANT_ENUM_CAST(RenderingDevice::SamplerFilter)
+VARIANT_ENUM_CAST(RenderingDevice::SamplerRepeatMode)
+VARIANT_ENUM_CAST(RenderingDevice::SamplerBorderColor)
+VARIANT_ENUM_CAST(RenderingDevice::VertexFrequency)
+VARIANT_ENUM_CAST(RenderingDevice::IndexBufferFormat)
+VARIANT_ENUM_CAST(RenderingDevice::UniformType)
+VARIANT_ENUM_CAST(RenderingDevice::RenderPrimitive)
+VARIANT_ENUM_CAST(RenderingDevice::PolygonCullMode)
+VARIANT_ENUM_CAST(RenderingDevice::PolygonFrontFace)
+VARIANT_ENUM_CAST(RenderingDevice::StencilOperation)
+VARIANT_ENUM_CAST(RenderingDevice::LogicOperation)
+VARIANT_ENUM_CAST(RenderingDevice::BlendFactor)
+VARIANT_ENUM_CAST(RenderingDevice::BlendOperation)
+VARIANT_ENUM_CAST(RenderingDevice::PipelineDynamicStateFlags)
+VARIANT_ENUM_CAST(RenderingDevice::InitialAction)
+VARIANT_ENUM_CAST(RenderingDevice::FinalAction)
+VARIANT_ENUM_CAST(RenderingDevice::Limit)
+
typedef RenderingDevice RD;
#endif // RENDERING_DEVICE_H
diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp
new file mode 100644
index 0000000000..291f2ff705
--- /dev/null
+++ b/servers/rendering/rendering_device_binds.cpp
@@ -0,0 +1,205 @@
+/*************************************************************************/
+/* rendering_device_binds.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "rendering_device_binds.h"
+
+Error RDShaderFile::parse_versions_from_text(const String &p_text, const String p_defines, OpenIncludeFunction p_include_func, void *p_include_func_userdata) {
+ Vector<String> lines = p_text.split("\n");
+
+ bool reading_versions = false;
+ bool stage_found[RD::SHADER_STAGE_MAX] = { false, false, false, false, false };
+ RD::ShaderStage stage = RD::SHADER_STAGE_MAX;
+ static const char *stage_str[RD::SHADER_STAGE_MAX] = {
+ "vertex",
+ "fragment",
+ "tesselation_control",
+ "tesselation_evaluation",
+ "compute",
+ };
+ String stage_code[RD::SHADER_STAGE_MAX];
+ int stages_found = 0;
+ Map<StringName, String> version_texts;
+
+ versions.clear();
+ base_error = "";
+
+ for (int lidx = 0; lidx < lines.size(); lidx++) {
+ String line = lines[lidx];
+
+ {
+ String ls = line.strip_edges();
+ if (ls.begins_with("#[") && ls.ends_with("]")) {
+ String section = ls.substr(2, ls.length() - 3).strip_edges();
+ if (section == "versions") {
+ if (stages_found) {
+ base_error = "Invalid shader file, #[versions] must be the first section found.";
+ break;
+ }
+ reading_versions = true;
+ } else {
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ if (section == stage_str[i]) {
+ if (stage_found[i]) {
+ base_error = "Invalid shader file, stage appears twice: " + section;
+ break;
+ }
+
+ stage_found[i] = true;
+ stages_found++;
+
+ stage = RD::ShaderStage(i);
+ reading_versions = false;
+ break;
+ }
+ }
+
+ if (base_error != String()) {
+ break;
+ }
+ }
+
+ continue;
+ }
+ }
+
+ if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") {
+ line = line.strip_edges();
+ if (line.begins_with("//") || line.begins_with("/*")) {
+ continue; //assuming comment (single line)
+ }
+ }
+
+ if (reading_versions) {
+ String l = line.strip_edges();
+ if (l != "") {
+ if (l.find("=") == -1) {
+ base_error = "Missing `=` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`.";
+ break;
+ }
+ if (l.find(";") != -1) {
+ // We don't require a semicolon per se, but it's needed for clang-format to handle things properly.
+ base_error = "Missing `;` in '" + l + "'. Version syntax is `version = \"<defines with C escaping>\";`.";
+ break;
+ }
+ Vector<String> slices = l.get_slice(";", 0).split("=");
+ String version = slices[0].strip_edges();
+ if (!version.is_valid_identifier()) {
+ base_error = "Version names must be valid identifiers, found '" + version + "' instead.";
+ break;
+ }
+ String define = slices[1].strip_edges();
+ if (!define.begins_with("\"") || !define.ends_with("\"")) {
+ base_error = "Version text must be quoted using \"\", instead found '" + define + "'.";
+ break;
+ }
+ define = "\n" + define.substr(1, define.length() - 2).c_unescape() + "\n"; // Add newline before and after just in case.
+
+ version_texts[version] = define + "\n" + p_defines;
+ }
+ } else {
+ if (stage == RD::SHADER_STAGE_MAX && line.strip_edges() != "") {
+ base_error = "Text was found that does not belong to a valid section: " + line;
+ break;
+ }
+
+ if (stage != RD::SHADER_STAGE_MAX) {
+ if (line.strip_edges().begins_with("#include")) {
+ if (p_include_func) {
+ //process include
+ String include = line.replace("#include", "").strip_edges();
+ if (!include.begins_with("\"") || !include.ends_with("\"")) {
+ base_error = "Malformed #include syntax, expected #include \"<path>\", found instad: " + include;
+ break;
+ }
+ include = include.substr(1, include.length() - 2).strip_edges();
+ String include_text = p_include_func(include, p_include_func_userdata);
+ if (include_text != String()) {
+ stage_code[stage] += "\n" + include_text + "\n";
+ } else {
+ base_error = "#include failed for file '" + include + "'";
+ }
+ } else {
+ base_error = "#include used, but no include function provided.";
+ }
+ } else {
+ stage_code[stage] += line + "\n";
+ }
+ }
+ }
+ }
+
+ Ref<RDShaderFile> shader_file;
+ shader_file.instance();
+
+ if (base_error == "") {
+ if (stage_found[RD::SHADER_STAGE_COMPUTE] && stages_found > 1) {
+ ERR_FAIL_V_MSG(ERR_PARSE_ERROR, "When writing compute shaders, [compute] mustbe the only stage present.");
+ }
+
+ if (version_texts.empty()) {
+ version_texts[""] = ""; //make sure a default version exists
+ }
+
+ bool errors_found = false;
+
+ /* STEP 2, Compile the versions, add to shader file */
+
+ for (Map<StringName, String>::Element *E = version_texts.front(); E; E = E->next()) {
+ Ref<RDShaderBytecode> bytecode;
+ bytecode.instance();
+
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ String code = stage_code[i];
+ if (code == String()) {
+ continue;
+ }
+ code = code.replace("VERSION_DEFINES", E->get());
+ String error;
+ Vector<uint8_t> spirv = RenderingDevice::get_singleton()->shader_compile_from_source(RD::ShaderStage(i), code, RD::SHADER_LANGUAGE_GLSL, &error, false);
+ bytecode->set_stage_bytecode(RD::ShaderStage(i), spirv);
+ if (error != "") {
+ error += String() + "\n\nStage '" + stage_str[i] + "' source code: \n\n";
+ Vector<String> sclines = code.split("\n");
+ for (int j = 0; j < sclines.size(); j++) {
+ error += itos(j + 1) + "\t\t" + sclines[j] + "\n";
+ }
+ errors_found = true;
+ }
+ bytecode->set_stage_compile_error(RD::ShaderStage(i), error);
+ }
+
+ set_bytecode(bytecode, E->key());
+ }
+
+ return errors_found ? ERR_PARSE_ERROR : OK;
+ } else {
+ return ERR_PARSE_ERROR;
+ }
+}
diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h
new file mode 100644
index 0000000000..319c6d9fde
--- /dev/null
+++ b/servers/rendering/rendering_device_binds.h
@@ -0,0 +1,629 @@
+/*************************************************************************/
+/* rendering_device_binds.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RENDERING_DEVICE_BINDS_H
+#define RENDERING_DEVICE_BINDS_H
+
+#include "servers/rendering/rendering_device.h"
+
+#define RD_SETGET(m_type, m_member) \
+ void set_##m_member(m_type p_##m_member) { base.m_member = p_##m_member; } \
+ m_type get_##m_member() const { return base.m_member; }
+
+#define RD_BIND(m_variant_type, m_class, m_member) \
+ ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_member); \
+ ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_member)), &m_class::get_##m_member); \
+ ADD_PROPERTY(PropertyInfo(m_variant_type, #m_member), "set_" _MKSTR(m_member), "get_" _MKSTR(m_member))
+
+#define RD_SETGET_SUB(m_type, m_sub, m_member) \
+ void set_##m_sub##_##m_member(m_type p_##m_member) { base.m_sub.m_member = p_##m_member; } \
+ m_type get_##m_sub##_##m_member() const { return base.m_sub.m_member; }
+
+#define RD_BIND_SUB(m_variant_type, m_class, m_sub, m_member) \
+ ClassDB::bind_method(D_METHOD("set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "p_" _MKSTR(member)), &m_class::set_##m_sub##_##m_member); \
+ ClassDB::bind_method(D_METHOD("get_" _MKSTR(m_sub) "_" _MKSTR(m_member)), &m_class::get_##m_sub##_##m_member); \
+ ADD_PROPERTY(PropertyInfo(m_variant_type, _MKSTR(m_sub) "_" _MKSTR(m_member)), "set_" _MKSTR(m_sub) "_" _MKSTR(m_member), "get_" _MKSTR(m_sub) "_" _MKSTR(m_member))
+
+class RDTextureFormat : public Reference {
+ GDCLASS(RDTextureFormat, Reference)
+ friend class RenderingDevice;
+
+ RD::TextureFormat base;
+
+public:
+ RD_SETGET(RD::DataFormat, format)
+ RD_SETGET(uint32_t, width)
+ RD_SETGET(uint32_t, height)
+ RD_SETGET(uint32_t, depth)
+ RD_SETGET(uint32_t, array_layers)
+ RD_SETGET(uint32_t, mipmaps)
+ RD_SETGET(RD::TextureType, type)
+ RD_SETGET(RD::TextureSamples, samples)
+ RD_SETGET(uint32_t, usage_bits)
+
+ void add_shareable_format(RD::DataFormat p_format) { base.shareable_formats.push_back(p_format); }
+ void remove_shareable_format(RD::DataFormat p_format) { base.shareable_formats.erase(p_format); }
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDTextureFormat, format);
+ RD_BIND(Variant::INT, RDTextureFormat, width);
+ RD_BIND(Variant::INT, RDTextureFormat, height);
+ RD_BIND(Variant::INT, RDTextureFormat, depth);
+ RD_BIND(Variant::INT, RDTextureFormat, array_layers);
+ RD_BIND(Variant::INT, RDTextureFormat, mipmaps);
+ RD_BIND(Variant::INT, RDTextureFormat, type);
+ RD_BIND(Variant::INT, RDTextureFormat, samples);
+ RD_BIND(Variant::INT, RDTextureFormat, usage_bits);
+ ClassDB::bind_method(D_METHOD("add_shareable_format", "format"), &RDTextureFormat::add_shareable_format);
+ ClassDB::bind_method(D_METHOD("remove_shareable_format", "format"), &RDTextureFormat::remove_shareable_format);
+ }
+};
+
+class RDTextureView : public Reference {
+ GDCLASS(RDTextureView, Reference)
+
+ friend class RenderingDevice;
+
+ RD::TextureView base;
+
+public:
+ RD_SETGET(RD::DataFormat, format_override)
+ RD_SETGET(RD::TextureSwizzle, swizzle_r)
+ RD_SETGET(RD::TextureSwizzle, swizzle_g)
+ RD_SETGET(RD::TextureSwizzle, swizzle_b)
+ RD_SETGET(RD::TextureSwizzle, swizzle_a)
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDTextureView, format_override);
+ RD_BIND(Variant::INT, RDTextureView, swizzle_r);
+ RD_BIND(Variant::INT, RDTextureView, swizzle_g);
+ RD_BIND(Variant::INT, RDTextureView, swizzle_b);
+ RD_BIND(Variant::INT, RDTextureView, swizzle_a);
+ }
+};
+
+class RDAttachmentFormat : public Reference {
+ GDCLASS(RDAttachmentFormat, Reference)
+ friend class RenderingDevice;
+
+ RD::AttachmentFormat base;
+
+public:
+ RD_SETGET(RD::DataFormat, format)
+ RD_SETGET(RD::TextureSamples, samples)
+ RD_SETGET(uint32_t, usage_flags)
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDAttachmentFormat, format);
+ RD_BIND(Variant::INT, RDAttachmentFormat, samples);
+ RD_BIND(Variant::INT, RDAttachmentFormat, usage_flags);
+ }
+};
+
+class RDSamplerState : public Reference {
+ GDCLASS(RDSamplerState, Reference)
+ friend class RenderingDevice;
+
+ RD::SamplerState base;
+
+public:
+ RD_SETGET(RD::SamplerFilter, mag_filter)
+ RD_SETGET(RD::SamplerFilter, min_filter)
+ RD_SETGET(RD::SamplerFilter, mip_filter)
+ RD_SETGET(RD::SamplerRepeatMode, repeat_u)
+ RD_SETGET(RD::SamplerRepeatMode, repeat_v)
+ RD_SETGET(RD::SamplerRepeatMode, repeat_w)
+ RD_SETGET(float, lod_bias)
+ RD_SETGET(bool, use_anisotropy)
+ RD_SETGET(float, anisotropy_max)
+ RD_SETGET(bool, enable_compare)
+ RD_SETGET(RD::CompareOperator, compare_op)
+ RD_SETGET(float, min_lod)
+ RD_SETGET(float, max_lod)
+ RD_SETGET(RD::SamplerBorderColor, border_color)
+ RD_SETGET(bool, unnormalized_uvw)
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDSamplerState, mag_filter);
+ RD_BIND(Variant::INT, RDSamplerState, min_filter);
+ RD_BIND(Variant::INT, RDSamplerState, mip_filter);
+ RD_BIND(Variant::INT, RDSamplerState, repeat_u);
+ RD_BIND(Variant::INT, RDSamplerState, repeat_v);
+ RD_BIND(Variant::INT, RDSamplerState, repeat_w);
+ RD_BIND(Variant::FLOAT, RDSamplerState, lod_bias);
+ RD_BIND(Variant::BOOL, RDSamplerState, use_anisotropy);
+ RD_BIND(Variant::FLOAT, RDSamplerState, anisotropy_max);
+ RD_BIND(Variant::BOOL, RDSamplerState, enable_compare);
+ RD_BIND(Variant::INT, RDSamplerState, compare_op);
+ RD_BIND(Variant::FLOAT, RDSamplerState, min_lod);
+ RD_BIND(Variant::FLOAT, RDSamplerState, max_lod);
+ RD_BIND(Variant::INT, RDSamplerState, border_color);
+ RD_BIND(Variant::BOOL, RDSamplerState, unnormalized_uvw);
+ }
+};
+
+class RDVertexAttribute : public Reference {
+ GDCLASS(RDVertexAttribute, Reference)
+ friend class RenderingDevice;
+ RD::VertexAttribute base;
+
+public:
+ RD_SETGET(uint32_t, location)
+ RD_SETGET(uint32_t, offset)
+ RD_SETGET(RD::DataFormat, format)
+ RD_SETGET(uint32_t, stride)
+ RD_SETGET(RD::VertexFrequency, frequency)
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDVertexAttribute, location);
+ RD_BIND(Variant::INT, RDVertexAttribute, offset);
+ RD_BIND(Variant::INT, RDVertexAttribute, format);
+ RD_BIND(Variant::INT, RDVertexAttribute, stride);
+ RD_BIND(Variant::INT, RDVertexAttribute, frequency);
+ }
+};
+class RDShaderSource : public Reference {
+ GDCLASS(RDShaderSource, Reference)
+ String source[RD::SHADER_STAGE_MAX];
+ RD::ShaderLanguage language = RD::SHADER_LANGUAGE_GLSL;
+
+public:
+ void set_stage_source(RD::ShaderStage p_stage, const String &p_source) {
+ ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX);
+ source[p_stage] = p_source;
+ }
+
+ String get_stage_source(RD::ShaderStage p_stage) const {
+ ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String());
+ return source[p_stage];
+ }
+
+ void set_language(RD::ShaderLanguage p_language) {
+ language = p_language;
+ }
+
+ RD::ShaderLanguage get_language() const {
+ return language;
+ }
+
+protected:
+ static void _bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_stage_source", "stage", "source"), &RDShaderSource::set_stage_source);
+ ClassDB::bind_method(D_METHOD("get_stage_source", "stage"), &RDShaderSource::get_stage_source);
+
+ ClassDB::bind_method(D_METHOD("set_language", "language"), &RDShaderSource::set_language);
+ ClassDB::bind_method(D_METHOD("get_language"), &RDShaderSource::get_language);
+
+ ADD_GROUP("Source", "source_");
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_vertex"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_VERTEX);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_fragment"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_FRAGMENT);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_control"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_CONTROL);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_tesselation_evaluation"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_TESSELATION_EVALUATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "source_compute"), "set_stage_source", "get_stage_source", RD::SHADER_STAGE_COMPUTE);
+ ADD_GROUP("Syntax", "source_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "language", PROPERTY_HINT_RANGE, "GLSL,HLSL"), "set_language", "get_language");
+ }
+};
+
+class RDShaderBytecode : public Resource {
+ GDCLASS(RDShaderBytecode, Resource)
+
+ Vector<uint8_t> bytecode[RD::SHADER_STAGE_MAX];
+ String compile_error[RD::SHADER_STAGE_MAX];
+
+public:
+ void set_stage_bytecode(RD::ShaderStage p_stage, const Vector<uint8_t> &p_bytecode) {
+ ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX);
+ bytecode[p_stage] = p_bytecode;
+ }
+
+ Vector<uint8_t> get_stage_bytecode(RD::ShaderStage p_stage) const {
+ ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, Vector<uint8_t>());
+ return bytecode[p_stage];
+ }
+
+ void set_stage_compile_error(RD::ShaderStage p_stage, const String &p_compile_error) {
+ ERR_FAIL_INDEX(p_stage, RD::SHADER_STAGE_MAX);
+ compile_error[p_stage] = p_compile_error;
+ }
+
+ String get_stage_compile_error(RD::ShaderStage p_stage) const {
+ ERR_FAIL_INDEX_V(p_stage, RD::SHADER_STAGE_MAX, String());
+ return compile_error[p_stage];
+ }
+
+protected:
+ static void _bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_stage_bytecode", "stage", "bytecode"), &RDShaderBytecode::set_stage_bytecode);
+ ClassDB::bind_method(D_METHOD("get_stage_bytecode", "stage"), &RDShaderBytecode::get_stage_bytecode);
+
+ ClassDB::bind_method(D_METHOD("set_stage_compile_error", "stage", "compile_error"), &RDShaderBytecode::set_stage_compile_error);
+ ClassDB::bind_method(D_METHOD("get_stage_compile_error", "stage"), &RDShaderBytecode::get_stage_compile_error);
+
+ ADD_GROUP("Bytecode", "bytecode_");
+ ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_vertex"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_VERTEX);
+ ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_fragment"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_FRAGMENT);
+ ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_control"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_CONTROL);
+ ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_tesselation_evaluation"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_TESSELATION_EVALUATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytecode_compute"), "set_stage_bytecode", "get_stage_bytecode", RD::SHADER_STAGE_COMPUTE);
+ ADD_GROUP("Compile Error", "compile_error_");
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_vertex"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_VERTEX);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_fragment"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_FRAGMENT);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_control"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_CONTROL);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_tesselation_evaluation"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_TESSELATION_EVALUATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::STRING, "compile_error_compute"), "set_stage_compile_error", "get_stage_compile_error", RD::SHADER_STAGE_COMPUTE);
+ }
+};
+
+class RDShaderFile : public Resource {
+ GDCLASS(RDShaderFile, Resource)
+
+ Map<StringName, Ref<RDShaderBytecode>> versions;
+ String base_error;
+
+public:
+ void set_bytecode(const Ref<RDShaderBytecode> &p_bytecode, const StringName &p_version = StringName()) {
+ ERR_FAIL_COND(p_bytecode.is_null());
+ versions[p_version] = p_bytecode;
+ emit_changed();
+ }
+
+ Ref<RDShaderBytecode> get_bytecode(const StringName &p_version = StringName()) const {
+ ERR_FAIL_COND_V(!versions.has(p_version), Ref<RDShaderBytecode>());
+ return versions[p_version];
+ }
+
+ Vector<StringName> get_version_list() const {
+ Vector<StringName> vnames;
+ for (Map<StringName, Ref<RDShaderBytecode>>::Element *E = versions.front(); E; E = E->next()) {
+ vnames.push_back(E->key());
+ }
+ vnames.sort_custom<StringName::AlphCompare>();
+ return vnames;
+ }
+
+ void set_base_error(const String &p_error) {
+ base_error = p_error;
+ emit_changed();
+ }
+
+ String get_base_error() const {
+ return base_error;
+ }
+
+ void print_errors(const String &p_file) {
+ if (base_error != "") {
+ ERR_PRINT("Error parsing shader '" + p_file + "':\n\n" + base_error);
+ } else {
+ for (Map<StringName, Ref<RDShaderBytecode>>::Element *E = versions.front(); E; E = E->next()) {
+ for (int i = 0; i < RD::SHADER_STAGE_MAX; i++) {
+ String error = E->get()->get_stage_compile_error(RD::ShaderStage(i));
+ if (error != String()) {
+ static const char *stage_str[RD::SHADER_STAGE_MAX] = {
+ "vertex",
+ "fragment",
+ "tesselation_control",
+ "tesselation_evaluation",
+ "compute"
+ };
+
+ ERR_PRINT("Error parsing shader '" + p_file + "', version '" + String(E->key()) + "', stage '" + stage_str[i] + "':\n\n" + error);
+ }
+ }
+ }
+ }
+ }
+
+ typedef String (*OpenIncludeFunction)(const String &, void *userdata);
+ Error parse_versions_from_text(const String &p_text, const String p_defines = String(), OpenIncludeFunction p_include_func = nullptr, void *p_include_func_userdata = nullptr);
+
+protected:
+ Dictionary _get_versions() const {
+ Vector<StringName> vnames = get_version_list();
+ Dictionary ret;
+ for (int i = 0; i < vnames.size(); i++) {
+ ret[vnames[i]] = versions[vnames[i]];
+ }
+ return ret;
+ }
+ void _set_versions(const Dictionary &p_versions) {
+ versions.clear();
+ List<Variant> keys;
+ p_versions.get_key_list(&keys);
+ for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
+ StringName name = E->get();
+ Ref<RDShaderBytecode> bc = p_versions[E->get()];
+ ERR_CONTINUE(bc.is_null());
+ versions[name] = bc;
+ }
+
+ emit_changed();
+ }
+
+ static void _bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_bytecode", "bytecode", "version"), &RDShaderFile::set_bytecode, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("get_bytecode", "version"), &RDShaderFile::get_bytecode, DEFVAL(StringName()));
+ ClassDB::bind_method(D_METHOD("get_version_list"), &RDShaderFile::get_version_list);
+
+ ClassDB::bind_method(D_METHOD("set_base_error", "error"), &RDShaderFile::set_base_error);
+ ClassDB::bind_method(D_METHOD("get_base_error"), &RDShaderFile::get_base_error);
+
+ ClassDB::bind_method(D_METHOD("_set_versions", "versions"), &RDShaderFile::_set_versions);
+ ClassDB::bind_method(D_METHOD("_get_versions"), &RDShaderFile::_get_versions);
+
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_versions", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_versions", "_get_versions");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "base_error"), "set_base_error", "get_base_error");
+ }
+};
+
+class RDUniform : public Reference {
+ GDCLASS(RDUniform, Reference)
+ friend class RenderingDevice;
+ RD::Uniform base;
+
+public:
+ RD_SETGET(RD::UniformType, type)
+ RD_SETGET(int32_t, binding)
+
+ void add_id(const RID &p_id) { base.ids.push_back(p_id); }
+ void clear_ids() { base.ids.clear(); }
+ Array get_ids() const {
+ Array ids;
+ for (int i = 0; i < base.ids.size(); i++) {
+ ids.push_back(base.ids[i]);
+ }
+ return ids;
+ }
+
+protected:
+ void _set_ids(const Array &p_ids) {
+ base.ids.clear();
+ for (int i = 0; i < p_ids.size(); i++) {
+ RID id = p_ids[i];
+ ERR_FAIL_COND(id.is_null());
+ base.ids.push_back(id);
+ }
+ }
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDUniform, type);
+ RD_BIND(Variant::INT, RDUniform, binding);
+ ClassDB::bind_method(D_METHOD("add_id", "id"), &RDUniform::add_id);
+ ClassDB::bind_method(D_METHOD("clear_ids"), &RDUniform::clear_ids);
+ ClassDB::bind_method(D_METHOD("_set_ids", "ids"), &RDUniform::_set_ids);
+ ClassDB::bind_method(D_METHOD("get_ids"), &RDUniform::get_ids);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_ids", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_ids", "get_ids");
+ }
+};
+class RDPipelineRasterizationState : public Reference {
+ GDCLASS(RDPipelineRasterizationState, Reference)
+ friend class RenderingDevice;
+
+ RD::PipelineRasterizationState base;
+
+public:
+ RD_SETGET(bool, enable_depth_clamp)
+ RD_SETGET(bool, discard_primitives)
+ RD_SETGET(bool, wireframe)
+ RD_SETGET(RD::PolygonCullMode, cull_mode)
+ RD_SETGET(RD::PolygonFrontFace, front_face)
+ RD_SETGET(bool, depth_bias_enable)
+ RD_SETGET(float, depth_bias_constant_factor)
+ RD_SETGET(float, depth_bias_clamp)
+ RD_SETGET(float, depth_bias_slope_factor)
+ RD_SETGET(float, line_width)
+ RD_SETGET(uint32_t, patch_control_points)
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::BOOL, RDPipelineRasterizationState, enable_depth_clamp);
+ RD_BIND(Variant::BOOL, RDPipelineRasterizationState, discard_primitives);
+ RD_BIND(Variant::BOOL, RDPipelineRasterizationState, wireframe);
+ RD_BIND(Variant::INT, RDPipelineRasterizationState, cull_mode);
+ RD_BIND(Variant::INT, RDPipelineRasterizationState, front_face);
+ RD_BIND(Variant::BOOL, RDPipelineRasterizationState, depth_bias_enable);
+ RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_constant_factor);
+ RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_clamp);
+ RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, depth_bias_slope_factor);
+ RD_BIND(Variant::FLOAT, RDPipelineRasterizationState, line_width);
+ RD_BIND(Variant::INT, RDPipelineRasterizationState, patch_control_points);
+ }
+};
+
+class RDPipelineMultisampleState : public Reference {
+ GDCLASS(RDPipelineMultisampleState, Reference)
+ friend class RenderingDevice;
+
+ RD::PipelineMultisampleState base;
+ TypedArray<int64_t> sample_masks;
+
+public:
+ RD_SETGET(RD::TextureSamples, sample_count)
+ RD_SETGET(bool, enable_sample_shading)
+ RD_SETGET(float, min_sample_shading)
+ RD_SETGET(bool, enable_alpha_to_coverage)
+ RD_SETGET(bool, enable_alpha_to_one)
+
+ void set_sample_masks(const TypedArray<int64_t> &p_masks) { sample_masks = p_masks; }
+ TypedArray<int64_t> get_sample_masks() const { return sample_masks; }
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::INT, RDPipelineMultisampleState, sample_count);
+ RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_sample_shading);
+ RD_BIND(Variant::FLOAT, RDPipelineMultisampleState, min_sample_shading);
+ RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_coverage);
+ RD_BIND(Variant::BOOL, RDPipelineMultisampleState, enable_alpha_to_one);
+
+ ClassDB::bind_method(D_METHOD("set_sample_masks", "masks"), &RDPipelineMultisampleState::set_sample_masks);
+ ClassDB::bind_method(D_METHOD("get_sample_masks"), &RDPipelineMultisampleState::get_sample_masks);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "sample_masks", PROPERTY_HINT_ARRAY_TYPE, "int"), "set_sample_masks", "get_sample_masks");
+ }
+};
+
+class RDPipelineDepthStencilState : public Reference {
+ GDCLASS(RDPipelineDepthStencilState, Reference)
+ friend class RenderingDevice;
+
+ RD::PipelineDepthStencilState base;
+
+public:
+ RD_SETGET(bool, enable_depth_test)
+ RD_SETGET(bool, enable_depth_write)
+ RD_SETGET(RD::CompareOperator, depth_compare_operator)
+ RD_SETGET(bool, enable_depth_range)
+ RD_SETGET(float, depth_range_min)
+ RD_SETGET(float, depth_range_max)
+ RD_SETGET(bool, enable_stencil)
+
+ RD_SETGET_SUB(RD::StencilOperation, front_op, fail)
+ RD_SETGET_SUB(RD::StencilOperation, front_op, pass)
+ RD_SETGET_SUB(RD::StencilOperation, front_op, depth_fail)
+ RD_SETGET_SUB(RD::CompareOperator, front_op, compare)
+ RD_SETGET_SUB(uint32_t, front_op, compare_mask)
+ RD_SETGET_SUB(uint32_t, front_op, write_mask)
+ RD_SETGET_SUB(uint32_t, front_op, reference)
+
+ RD_SETGET_SUB(RD::StencilOperation, back_op, fail)
+ RD_SETGET_SUB(RD::StencilOperation, back_op, pass)
+ RD_SETGET_SUB(RD::StencilOperation, back_op, depth_fail)
+ RD_SETGET_SUB(RD::CompareOperator, back_op, compare)
+ RD_SETGET_SUB(uint32_t, back_op, compare_mask)
+ RD_SETGET_SUB(uint32_t, back_op, write_mask)
+ RD_SETGET_SUB(uint32_t, back_op, reference)
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_test);
+ RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_write);
+ RD_BIND(Variant::INT, RDPipelineDepthStencilState, depth_compare_operator);
+ RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_depth_range);
+ RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_min);
+ RD_BIND(Variant::FLOAT, RDPipelineDepthStencilState, depth_range_max);
+ RD_BIND(Variant::BOOL, RDPipelineDepthStencilState, enable_stencil);
+
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, fail);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, pass);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, depth_fail);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, compare_mask);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, write_mask);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, front_op, reference);
+
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, fail);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, pass);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, depth_fail);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, compare_mask);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, write_mask);
+ RD_BIND_SUB(Variant::INT, RDPipelineDepthStencilState, back_op, reference);
+ }
+};
+
+class RDPipelineColorBlendStateAttachment : public Reference {
+ GDCLASS(RDPipelineColorBlendStateAttachment, Reference)
+ friend class RenderingDevice;
+ RD::PipelineColorBlendState::Attachment base;
+
+public:
+ RD_SETGET(bool, enable_blend)
+ RD_SETGET(RD::BlendFactor, src_color_blend_factor)
+ RD_SETGET(RD::BlendFactor, dst_color_blend_factor)
+ RD_SETGET(RD::BlendOperation, color_blend_op)
+ RD_SETGET(RD::BlendFactor, src_alpha_blend_factor)
+ RD_SETGET(RD::BlendFactor, dst_alpha_blend_factor)
+ RD_SETGET(RD::BlendOperation, alpha_blend_op)
+ RD_SETGET(bool, write_r)
+ RD_SETGET(bool, write_g)
+ RD_SETGET(bool, write_b)
+ RD_SETGET(bool, write_a)
+
+ void set_as_mix() {
+ base = RD::PipelineColorBlendState::Attachment();
+ base.enable_blend = true;
+ base.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
+ base.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+ base.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
+ base.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+ }
+
+protected:
+ static void _bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_as_mix"), &RDPipelineColorBlendStateAttachment::set_as_mix);
+
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, enable_blend);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_color_blend_factor);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_color_blend_factor);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, color_blend_op);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, src_alpha_blend_factor);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, dst_alpha_blend_factor);
+ RD_BIND(Variant::INT, RDPipelineColorBlendStateAttachment, alpha_blend_op);
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_r);
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_g);
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_b);
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendStateAttachment, write_a);
+ }
+};
+
+class RDPipelineColorBlendState : public Reference {
+ GDCLASS(RDPipelineColorBlendState, Reference)
+ friend class RenderingDevice;
+ RD::PipelineColorBlendState base;
+
+ TypedArray<RDPipelineColorBlendStateAttachment> attachments;
+
+public:
+ RD_SETGET(bool, enable_logic_op)
+ RD_SETGET(RD::LogicOperation, logic_op)
+ RD_SETGET(Color, blend_constant)
+
+ void set_attachments(const TypedArray<RDPipelineColorBlendStateAttachment> &p_attachments) {
+ attachments.push_back(p_attachments);
+ }
+
+ TypedArray<RDPipelineColorBlendStateAttachment> get_attachments() const {
+ return attachments;
+ }
+
+protected:
+ static void _bind_methods() {
+ RD_BIND(Variant::BOOL, RDPipelineColorBlendState, enable_logic_op);
+ RD_BIND(Variant::INT, RDPipelineColorBlendState, logic_op);
+ RD_BIND(Variant::COLOR, RDPipelineColorBlendState, blend_constant);
+
+ ClassDB::bind_method(D_METHOD("set_attachments", "atachments"), &RDPipelineColorBlendState::set_attachments);
+ ClassDB::bind_method(D_METHOD("get_attachments"), &RDPipelineColorBlendState::get_attachments);
+ ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "attachments", PROPERTY_HINT_ARRAY_TYPE, "RDPipelineColorBlendStateAttachment"), "set_attachments", "get_attachments");
+ }
+};
+
+#endif // RENDERING_DEVICE_BINDS_H
diff --git a/servers/rendering/rendering_server_canvas.cpp b/servers/rendering/rendering_server_canvas.cpp
index 5d6dcfd2c1..0c9290a765 100644
--- a/servers/rendering/rendering_server_canvas.cpp
+++ b/servers/rendering/rendering_server_canvas.cpp
@@ -36,7 +36,6 @@
static const int z_range = RS::CANVAS_ITEM_Z_MAX - RS::CANVAS_ITEM_Z_MIN + 1;
void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Canvas::ChildItem *p_child_items, int p_child_item_count, Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, RasterizerCanvas::Light *p_lights) {
-
RENDER_TIMESTAMP("Cull CanvasItem Tree");
memset(z_list, 0, z_range * sizeof(RasterizerCanvas::Item *));
@@ -53,8 +52,9 @@ void RenderingServerCanvas::_render_canvas_item_tree(RID p_to_render_target, Can
RasterizerCanvas::Item *list_end = nullptr;
for (int i = 0; i < z_range; i++) {
- if (!z_list[i])
+ if (!z_list[i]) {
continue;
+ }
if (!list) {
list = z_list[i];
list_end = z_last_list[i];
@@ -83,8 +83,9 @@ void _collect_ysort_children(RenderingServerCanvas::Item *p_canvas_item, Transfo
r_index++;
- if (child_items[i]->sort_y)
+ if (child_items[i]->sort_y) {
_collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index);
+ }
}
}
}
@@ -97,14 +98,13 @@ void _mark_ysort_dirty(RenderingServerCanvas::Item *ysort_owner, RID_PtrOwner<Re
}
void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transform2D &p_transform, const Rect2 &p_clip_rect, const Color &p_modulate, int p_z, RasterizerCanvas::Item **z_list, RasterizerCanvas::Item **z_last_list, Item *p_canvas_clip, Item *p_material_owner) {
-
Item *ci = p_canvas_item;
- if (!ci->visible)
+ if (!ci->visible) {
return;
+ }
if (ci->children_order_dirty) {
-
ci->child_items.sort_custom<ItemIndexSort>();
ci->children_order_dirty = false;
}
@@ -114,17 +114,18 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
Rect2 global_rect = xform.xform(rect);
global_rect.position += p_clip_rect.position;
- if (ci->use_parent_material && p_material_owner)
+ if (ci->use_parent_material && p_material_owner) {
ci->material_owner = p_material_owner;
- else {
+ } else {
p_material_owner = ci;
ci->material_owner = nullptr;
}
Color modulate(ci->modulate.r * p_modulate.r, ci->modulate.g * p_modulate.g, ci->modulate.b * p_modulate.b, ci->modulate.a * p_modulate.a);
- if (modulate.a < 0.007)
+ if (modulate.a < 0.007) {
return;
+ }
int child_item_count = ci->child_items.size();
Item **child_items = ci->child_items.ptrw();
@@ -142,7 +143,6 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
}
if (ci->sort_y) {
-
if (ci->ysort_children_count == -1) {
ci->ysort_children_count = 0;
_collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count);
@@ -158,15 +158,16 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
sorter.sort(child_items, child_item_count);
}
- if (ci->z_relative)
+ if (ci->z_relative) {
p_z = CLAMP(p_z + ci->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
- else
+ } else {
p_z = ci->z_index;
+ }
for (int i = 0; i < child_item_count; i++) {
-
- if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y))
+ if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) {
continue;
+ }
if (ci->sort_y) {
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
} else {
@@ -175,7 +176,6 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
}
if (ci->copy_back_buffer) {
-
ci->copy_back_buffer->screen_rect = xform.xform(ci->copy_back_buffer->rect).clip(p_clip_rect);
}
@@ -208,9 +208,9 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
}
for (int i = 0; i < child_item_count; i++) {
-
- if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y))
+ if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) {
continue;
+ }
if (ci->sort_y) {
_cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner);
} else {
@@ -220,17 +220,15 @@ void RenderingServerCanvas::_cull_canvas_item(Item *p_canvas_item, const Transfo
}
void RenderingServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas::Item *p_canvas_item, RasterizerCanvas::Light *p_masked_lights) {
-
- if (!p_masked_lights)
+ if (!p_masked_lights) {
return;
+ }
RasterizerCanvas::Item *ci = p_canvas_item;
while (ci) {
-
RasterizerCanvas::Light *light = p_masked_lights;
while (light) {
-
if (ci->light_mask & light->item_mask && p_z >= light->z_min && p_z <= light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) {
ci->light_masked = true;
}
@@ -243,11 +241,9 @@ void RenderingServerCanvas::_light_mask_canvas_items(int p_z, RasterizerCanvas::
}
void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas, const Transform2D &p_transform, RasterizerCanvas::Light *p_lights, RasterizerCanvas::Light *p_masked_lights, const Rect2 &p_clip_rect) {
-
RENDER_TIMESTAMP(">Render Canvas");
if (p_canvas->children_order_dirty) {
-
p_canvas->child_items.sort();
p_canvas->children_order_dirty = false;
}
@@ -264,29 +260,24 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas,
}
if (!has_mirror) {
-
_render_canvas_item_tree(p_render_target, ci, l, nullptr, p_transform, p_clip_rect, p_canvas->modulate, p_lights);
} else {
//used for parallaxlayer mirroring
for (int i = 0; i < l; i++) {
-
const Canvas::ChildItem &ci2 = p_canvas->child_items[i];
_render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, p_transform, p_clip_rect, p_canvas->modulate, p_lights);
//mirroring (useful for scrolling backgrounds)
if (ci2.mirror.x != 0) {
-
Transform2D xform2 = p_transform * Transform2D(0, Vector2(ci2.mirror.x, 0));
_render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights);
}
if (ci2.mirror.y != 0) {
-
Transform2D xform2 = p_transform * Transform2D(0, Vector2(0, ci2.mirror.y));
_render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights);
}
if (ci2.mirror.y != 0 && ci2.mirror.x != 0) {
-
Transform2D xform2 = p_transform * Transform2D(0, ci2.mirror);
_render_canvas_item_tree(p_render_target, nullptr, 0, ci2.item, xform2, p_clip_rect, p_canvas->modulate, p_lights);
}
@@ -297,7 +288,6 @@ void RenderingServerCanvas::render_canvas(RID p_render_target, Canvas *p_canvas,
}
RID RenderingServerCanvas::canvas_create() {
-
Canvas *canvas = memnew(Canvas);
ERR_FAIL_COND_V(!canvas, RID());
RID rid = canvas_owner.make_rid(canvas);
@@ -306,7 +296,6 @@ RID RenderingServerCanvas::canvas_create() {
}
void RenderingServerCanvas::canvas_set_item_mirroring(RID p_canvas, RID p_item, const Point2 &p_mirroring) {
-
Canvas *canvas = canvas_owner.getornull(p_canvas);
ERR_FAIL_COND(!canvas);
Item *canvas_item = canvas_item_owner.getornull(p_item);
@@ -316,8 +305,8 @@ void RenderingServerCanvas::canvas_set_item_mirroring(RID p_canvas, RID p_item,
ERR_FAIL_COND(idx == -1);
canvas->child_items.write[idx].mirror = p_mirroring;
}
-void RenderingServerCanvas::canvas_set_modulate(RID p_canvas, const Color &p_color) {
+void RenderingServerCanvas::canvas_set_modulate(RID p_canvas, const Color &p_color) {
Canvas *canvas = canvas_owner.getornull(p_canvas);
ERR_FAIL_COND(!canvas);
canvas->modulate = p_color;
@@ -328,7 +317,6 @@ void RenderingServerCanvas::canvas_set_disable_scale(bool p_disable) {
}
void RenderingServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float p_scale) {
-
Canvas *canvas = canvas_owner.getornull(p_canvas);
ERR_FAIL_COND(!canvas);
@@ -337,7 +325,6 @@ void RenderingServerCanvas::canvas_set_parent(RID p_canvas, RID p_parent, float
}
RID RenderingServerCanvas::canvas_item_create() {
-
Item *canvas_item = memnew(Item);
ERR_FAIL_COND_V(!canvas_item, RID());
@@ -345,18 +332,14 @@ RID RenderingServerCanvas::canvas_item_create() {
}
void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
if (canvas_item->parent.is_valid()) {
-
if (canvas_owner.owns(canvas_item->parent)) {
-
Canvas *canvas = canvas_owner.getornull(canvas_item->parent);
canvas->erase_item(canvas_item);
} else if (canvas_item_owner.owns(canvas_item->parent)) {
-
Item *item_owner = canvas_item_owner.getornull(canvas_item->parent);
item_owner->child_items.erase(canvas_item);
@@ -370,14 +353,12 @@ void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) {
if (p_parent.is_valid()) {
if (canvas_owner.owns(p_parent)) {
-
Canvas *canvas = canvas_owner.getornull(p_parent);
Canvas::ChildItem ci;
ci.item = canvas_item;
canvas->child_items.push_back(ci);
canvas->children_order_dirty = true;
} else if (canvas_item_owner.owns(p_parent)) {
-
Item *item_owner = canvas_item_owner.getornull(p_parent);
item_owner->child_items.push_back(canvas_item);
item_owner->children_order_dirty = true;
@@ -387,15 +368,14 @@ void RenderingServerCanvas::canvas_item_set_parent(RID p_item, RID p_parent) {
}
} else {
-
ERR_FAIL_MSG("Invalid parent.");
}
}
canvas_item->parent = p_parent;
}
-void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) {
+void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -403,8 +383,8 @@ void RenderingServerCanvas::canvas_item_set_visible(RID p_item, bool p_visible)
_mark_ysort_dirty(canvas_item, canvas_item_owner);
}
-void RenderingServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) {
+void RenderingServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -412,43 +392,42 @@ void RenderingServerCanvas::canvas_item_set_light_mask(RID p_item, int p_mask) {
}
void RenderingServerCanvas::canvas_item_set_transform(RID p_item, const Transform2D &p_transform) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->xform = p_transform;
}
-void RenderingServerCanvas::canvas_item_set_clip(RID p_item, bool p_clip) {
+void RenderingServerCanvas::canvas_item_set_clip(RID p_item, bool p_clip) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->clip = p_clip;
}
-void RenderingServerCanvas::canvas_item_set_distance_field_mode(RID p_item, bool p_enable) {
+void RenderingServerCanvas::canvas_item_set_distance_field_mode(RID p_item, bool p_enable) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->distance_field = p_enable;
}
-void RenderingServerCanvas::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect) {
+void RenderingServerCanvas::canvas_item_set_custom_rect(RID p_item, bool p_custom_rect, const Rect2 &p_rect) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->custom_rect = p_custom_rect;
canvas_item->rect = p_rect;
}
-void RenderingServerCanvas::canvas_item_set_modulate(RID p_item, const Color &p_color) {
+void RenderingServerCanvas::canvas_item_set_modulate(RID p_item, const Color &p_color) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->modulate = p_color;
}
-void RenderingServerCanvas::canvas_item_set_self_modulate(RID p_item, const Color &p_color) {
+void RenderingServerCanvas::canvas_item_set_self_modulate(RID p_item, const Color &p_color) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -456,7 +435,6 @@ void RenderingServerCanvas::canvas_item_set_self_modulate(RID p_item, const Colo
}
void RenderingServerCanvas::canvas_item_set_draw_behind_parent(RID p_item, bool p_enable) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -464,7 +442,6 @@ void RenderingServerCanvas::canvas_item_set_draw_behind_parent(RID p_item, bool
}
void RenderingServerCanvas::canvas_item_set_update_when_visible(RID p_item, bool p_update) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -472,28 +449,24 @@ void RenderingServerCanvas::canvas_item_set_update_when_visible(RID p_item, bool
}
void RenderingServerCanvas::canvas_item_set_default_texture_filter(RID p_item, RS::CanvasItemTextureFilter p_filter) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->texture_filter = p_filter;
}
void RenderingServerCanvas::canvas_item_set_default_texture_repeat(RID p_item, RS::CanvasItemTextureRepeat p_repeat) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->texture_repeat = p_repeat;
}
void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
Item::CommandPrimitive *line = canvas_item->alloc_command<Item::CommandPrimitive>();
ERR_FAIL_COND(!line);
if (p_width > 1.001) {
-
Vector2 t = (p_from - p_to).tangent().normalized();
line->points[0] = p_from + t * p_width;
line->points[1] = p_from - t * p_width;
@@ -512,7 +485,6 @@ void RenderingServerCanvas::canvas_item_add_line(RID p_item, const Point2 &p_fro
}
void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
-
ERR_FAIL_COND(p_points.size() < 2);
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -604,7 +576,6 @@ void RenderingServerCanvas::canvas_item_add_polyline(RID p_item, const Vector<Po
}
void RenderingServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width) {
-
ERR_FAIL_COND(p_points.size() < 2);
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -625,7 +596,6 @@ void RenderingServerCanvas::canvas_item_add_multiline(RID p_item, const Vector<P
}
void RenderingServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -636,7 +606,6 @@ void RenderingServerCanvas::canvas_item_add_rect(RID p_item, const Rect2 &p_rect
}
void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -674,7 +643,6 @@ void RenderingServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_p
}
void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -690,12 +658,10 @@ void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2
}
if (p_rect.size.x < 0) {
-
rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_H;
rect->rect.size.x = -rect->rect.size.x;
}
if (p_rect.size.y < 0) {
-
rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_V;
rect->rect.size.y = -rect->rect.size.y;
}
@@ -708,7 +674,6 @@ void RenderingServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2
}
void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, bool p_clip_uv, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -722,22 +687,18 @@ void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, cons
rect->flags = RasterizerCanvas::CANVAS_RECT_REGION;
if (p_rect.size.x < 0) {
-
rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_H;
rect->rect.size.x = -rect->rect.size.x;
}
if (p_src_rect.size.x < 0) {
-
rect->flags ^= RasterizerCanvas::CANVAS_RECT_FLIP_H;
rect->source.size.x = -rect->source.size.x;
}
if (p_rect.size.y < 0) {
-
rect->flags |= RasterizerCanvas::CANVAS_RECT_FLIP_V;
rect->rect.size.y = -rect->rect.size.y;
}
if (p_src_rect.size.y < 0) {
-
rect->flags ^= RasterizerCanvas::CANVAS_RECT_FLIP_V;
rect->source.size.y = -rect->source.size.y;
}
@@ -753,7 +714,6 @@ void RenderingServerCanvas::canvas_item_add_texture_rect_region(RID p_item, cons
}
void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, RS::NinePatchAxisMode p_x_axis_mode, RS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -772,8 +732,8 @@ void RenderingServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &
style->axis_x = p_x_axis_mode;
style->axis_y = p_y_axis_mode;
}
-void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
+void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
uint32_t pc = p_points.size();
ERR_FAIL_COND(pc == 0 || pc > 4);
@@ -804,7 +764,6 @@ void RenderingServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<P
}
void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
#ifdef DEBUG_ENABLED
@@ -827,7 +786,6 @@ void RenderingServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Poi
}
void RenderingServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, const Vector<int> &p_bones, const Vector<float> &p_weights, RID p_texture, int p_count, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -850,7 +808,6 @@ void RenderingServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vec
}
void RenderingServerCanvas::canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -860,7 +817,6 @@ void RenderingServerCanvas::canvas_item_add_set_transform(RID p_item, const Tran
}
void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, const Transform2D &p_transform, const Color &p_modulate, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -872,8 +828,8 @@ void RenderingServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh,
m->transform = p_transform;
m->modulate = p_modulate;
}
-void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
+void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -888,7 +844,6 @@ void RenderingServerCanvas::canvas_item_add_particles(RID p_item, RID p_particle
}
void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture, RID p_normal_map, RID p_specular_map, const Color &p_specular_color_shininess, RenderingServer::CanvasItemTextureFilter p_filter, RenderingServer::CanvasItemTextureRepeat p_repeat) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -900,7 +855,6 @@ void RenderingServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RI
}
void RenderingServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -908,8 +862,8 @@ void RenderingServerCanvas::canvas_item_add_clip_ignore(RID p_item, bool p_ignor
ERR_FAIL_COND(!ci);
ci->ignore = p_ignore;
}
-void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) {
+void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -917,8 +871,8 @@ void RenderingServerCanvas::canvas_item_set_sort_children_by_y(RID p_item, bool
_mark_ysort_dirty(canvas_item, canvas_item_owner);
}
-void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) {
+void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) {
ERR_FAIL_COND(p_z < RS::CANVAS_ITEM_Z_MIN || p_z > RS::CANVAS_ITEM_Z_MAX);
Item *canvas_item = canvas_item_owner.getornull(p_item);
@@ -926,8 +880,8 @@ void RenderingServerCanvas::canvas_item_set_z_index(RID p_item, int p_z) {
canvas_item->z_index = p_z;
}
-void RenderingServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) {
+void RenderingServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -935,7 +889,6 @@ void RenderingServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item,
}
void RenderingServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -943,7 +896,6 @@ void RenderingServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skelet
}
void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
if (bool(canvas_item->copy_back_buffer != nullptr) != p_enable) {
@@ -962,14 +914,13 @@ void RenderingServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool
}
void RenderingServerCanvas::canvas_item_clear(RID p_item) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
canvas_item->clear();
}
-void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index) {
+void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -989,7 +940,6 @@ void RenderingServerCanvas::canvas_item_set_draw_index(RID p_item, int p_index)
}
void RenderingServerCanvas::canvas_item_set_material(RID p_item, RID p_material) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -997,7 +947,6 @@ void RenderingServerCanvas::canvas_item_set_material(RID p_item, RID p_material)
}
void RenderingServerCanvas::canvas_item_set_use_parent_material(RID p_item, bool p_enable) {
-
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -1005,57 +954,54 @@ void RenderingServerCanvas::canvas_item_set_use_parent_material(RID p_item, bool
}
RID RenderingServerCanvas::canvas_light_create() {
-
RasterizerCanvas::Light *clight = memnew(RasterizerCanvas::Light);
clight->light_internal = RSG::canvas_render->light_create();
return canvas_light_owner.make_rid(clight);
}
-void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) {
+void RenderingServerCanvas::canvas_light_attach_to_canvas(RID p_light, RID p_canvas) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
if (clight->canvas.is_valid()) {
-
Canvas *canvas = canvas_owner.getornull(clight->canvas);
canvas->lights.erase(clight);
}
- if (!canvas_owner.owns(p_canvas))
+ if (!canvas_owner.owns(p_canvas)) {
p_canvas = RID();
+ }
clight->canvas = p_canvas;
if (clight->canvas.is_valid()) {
-
Canvas *canvas = canvas_owner.getornull(clight->canvas);
canvas->lights.insert(clight);
}
}
void RenderingServerCanvas::canvas_light_set_enabled(RID p_light, bool p_enabled) {
-
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->enabled = p_enabled;
}
-void RenderingServerCanvas::canvas_light_set_scale(RID p_light, float p_scale) {
+void RenderingServerCanvas::canvas_light_set_scale(RID p_light, float p_scale) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->scale = p_scale;
}
-void RenderingServerCanvas::canvas_light_set_transform(RID p_light, const Transform2D &p_transform) {
+void RenderingServerCanvas::canvas_light_set_transform(RID p_light, const Transform2D &p_transform) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->xform = p_transform;
}
-void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) {
+void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
@@ -1063,66 +1009,66 @@ void RenderingServerCanvas::canvas_light_set_texture(RID p_light, RID p_texture)
clight->version++;
RSG::canvas_render->light_set_texture(clight->light_internal, p_texture);
}
-void RenderingServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) {
+void RenderingServerCanvas::canvas_light_set_texture_offset(RID p_light, const Vector2 &p_offset) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->texture_offset = p_offset;
}
-void RenderingServerCanvas::canvas_light_set_color(RID p_light, const Color &p_color) {
+void RenderingServerCanvas::canvas_light_set_color(RID p_light, const Color &p_color) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->color = p_color;
}
-void RenderingServerCanvas::canvas_light_set_height(RID p_light, float p_height) {
+void RenderingServerCanvas::canvas_light_set_height(RID p_light, float p_height) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->height = p_height;
}
-void RenderingServerCanvas::canvas_light_set_energy(RID p_light, float p_energy) {
+void RenderingServerCanvas::canvas_light_set_energy(RID p_light, float p_energy) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->energy = p_energy;
}
-void RenderingServerCanvas::canvas_light_set_z_range(RID p_light, int p_min_z, int p_max_z) {
+void RenderingServerCanvas::canvas_light_set_z_range(RID p_light, int p_min_z, int p_max_z) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->z_min = p_min_z;
clight->z_max = p_max_z;
}
-void RenderingServerCanvas::canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer) {
+void RenderingServerCanvas::canvas_light_set_layer_range(RID p_light, int p_min_layer, int p_max_layer) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->layer_max = p_max_layer;
clight->layer_min = p_min_layer;
}
-void RenderingServerCanvas::canvas_light_set_item_cull_mask(RID p_light, int p_mask) {
+void RenderingServerCanvas::canvas_light_set_item_cull_mask(RID p_light, int p_mask) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->item_mask = p_mask;
}
-void RenderingServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) {
+void RenderingServerCanvas::canvas_light_set_item_shadow_cull_mask(RID p_light, int p_mask) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->item_shadow_mask = p_mask;
}
-void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) {
+void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMode p_mode) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
@@ -1130,7 +1076,6 @@ void RenderingServerCanvas::canvas_light_set_mode(RID p_light, RS::CanvasLightMo
}
void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled) {
-
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
@@ -1143,15 +1088,15 @@ void RenderingServerCanvas::canvas_light_set_shadow_enabled(RID p_light, bool p_
}
void RenderingServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int p_size) {
-
ERR_FAIL_COND(p_size < 32 || p_size > 16384);
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
int new_size = next_power_of_2(p_size);
- if (new_size == clight->shadow_buffer_size)
+ if (new_size == clight->shadow_buffer_size) {
return;
+ }
clight->shadow_buffer_size = next_power_of_2(p_size);
clight->version++;
@@ -1160,14 +1105,13 @@ void RenderingServerCanvas::canvas_light_set_shadow_buffer_size(RID p_light, int
}
void RenderingServerCanvas::canvas_light_set_shadow_filter(RID p_light, RS::CanvasLightShadowFilter p_filter) {
-
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->shadow_filter = p_filter;
}
-void RenderingServerCanvas::canvas_light_set_shadow_color(RID p_light, const Color &p_color) {
+void RenderingServerCanvas::canvas_light_set_shadow_color(RID p_light, const Color &p_color) {
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
@@ -1175,49 +1119,46 @@ void RenderingServerCanvas::canvas_light_set_shadow_color(RID p_light, const Col
}
void RenderingServerCanvas::canvas_light_set_shadow_smooth(RID p_light, float p_smooth) {
-
RasterizerCanvas::Light *clight = canvas_light_owner.getornull(p_light);
ERR_FAIL_COND(!clight);
clight->shadow_smooth = p_smooth;
}
RID RenderingServerCanvas::canvas_light_occluder_create() {
-
RasterizerCanvas::LightOccluderInstance *occluder = memnew(RasterizerCanvas::LightOccluderInstance);
return canvas_light_occluder_owner.make_rid(occluder);
}
-void RenderingServerCanvas::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) {
+void RenderingServerCanvas::canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) {
RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
if (occluder->canvas.is_valid()) {
-
Canvas *canvas = canvas_owner.getornull(occluder->canvas);
canvas->occluders.erase(occluder);
}
- if (!canvas_owner.owns(p_canvas))
+ if (!canvas_owner.owns(p_canvas)) {
p_canvas = RID();
+ }
occluder->canvas = p_canvas;
if (occluder->canvas.is_valid()) {
-
Canvas *canvas = canvas_owner.getornull(occluder->canvas);
canvas->occluders.insert(occluder);
}
}
-void RenderingServerCanvas::canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled) {
+void RenderingServerCanvas::canvas_light_occluder_set_enabled(RID p_occluder, bool p_enabled) {
RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
occluder->enabled = p_enabled;
}
-void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon) {
+void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RID p_polygon) {
RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
@@ -1244,15 +1185,15 @@ void RenderingServerCanvas::canvas_light_occluder_set_polygon(RID p_occluder, RI
}
}
}
-void RenderingServerCanvas::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) {
+void RenderingServerCanvas::canvas_light_occluder_set_transform(RID p_occluder, const Transform2D &p_xform) {
RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
occluder->xform = p_xform;
}
-void RenderingServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask) {
+void RenderingServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder, int p_mask) {
RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_occluder);
ERR_FAIL_COND(!occluder);
@@ -1260,13 +1201,12 @@ void RenderingServerCanvas::canvas_light_occluder_set_light_mask(RID p_occluder,
}
RID RenderingServerCanvas::canvas_occluder_polygon_create() {
-
LightOccluderPolygon *occluder_poly = memnew(LightOccluderPolygon);
occluder_poly->occluder = RSG::canvas_render->occluder_polygon_create();
return canvas_light_occluder_polygon_owner.make_rid(occluder_poly);
}
-void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) {
+void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const Vector<Vector2> &p_shape, bool p_closed) {
if (p_shape.size() < 3) {
canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon, p_shape);
return;
@@ -1285,7 +1225,6 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_pol
max--;
}
for (int i = 0; i < max; i++) {
-
Vector2 a = r[i];
Vector2 b = r[(i + 1) % (lc / 2)];
w[i * 2 + 0] = a;
@@ -1295,8 +1234,8 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape(RID p_occluder_pol
canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon, lines);
}
-void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon, const Vector<Vector2> &p_shape) {
+void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon, const Vector<Vector2> &p_shape) {
LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon);
ERR_FAIL_COND(!occluder_poly);
ERR_FAIL_COND(p_shape.size() & 1);
@@ -1306,10 +1245,11 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occ
{
const Vector2 *r = p_shape.ptr();
for (int i = 0; i < lc; i++) {
- if (i == 0)
+ if (i == 0) {
occluder_poly->aabb.position = r[i];
- else
+ } else {
occluder_poly->aabb.expand_to(r[i]);
+ }
}
}
@@ -1320,7 +1260,6 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occ
}
void RenderingServerCanvas::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, RS::CanvasOccluderPolygonCullMode p_mode) {
-
LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_occluder_polygon);
ERR_FAIL_COND(!occluder_poly);
occluder_poly->cull_mode = p_mode;
@@ -1331,14 +1270,11 @@ void RenderingServerCanvas::canvas_occluder_polygon_set_cull_mode(RID p_occluder
}
bool RenderingServerCanvas::free(RID p_rid) {
-
if (canvas_owner.owns(p_rid)) {
-
Canvas *canvas = canvas_owner.getornull(p_rid);
ERR_FAIL_COND_V(!canvas, false);
while (canvas->viewports.size()) {
-
RenderingServerViewport::Viewport *vp = RSG::viewport->viewport_owner.getornull(canvas->viewports.front()->get());
ERR_FAIL_COND_V(!vp, true);
@@ -1350,17 +1286,14 @@ bool RenderingServerCanvas::free(RID p_rid) {
}
for (int i = 0; i < canvas->child_items.size(); i++) {
-
canvas->child_items[i].item->parent = RID();
}
for (Set<RasterizerCanvas::Light *>::Element *E = canvas->lights.front(); E; E = E->next()) {
-
E->get()->canvas = RID();
}
for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *E = canvas->occluders.front(); E; E = E->next()) {
-
E->get()->canvas = RID();
}
@@ -1369,18 +1302,14 @@ bool RenderingServerCanvas::free(RID p_rid) {
memdelete(canvas);
} else if (canvas_item_owner.owns(p_rid)) {
-
Item *canvas_item = canvas_item_owner.getornull(p_rid);
ERR_FAIL_COND_V(!canvas_item, true);
if (canvas_item->parent.is_valid()) {
-
if (canvas_owner.owns(canvas_item->parent)) {
-
Canvas *canvas = canvas_owner.getornull(canvas_item->parent);
canvas->erase_item(canvas_item);
} else if (canvas_item_owner.owns(canvas_item->parent)) {
-
Item *item_owner = canvas_item_owner.getornull(canvas_item->parent);
item_owner->child_items.erase(canvas_item);
@@ -1391,7 +1320,6 @@ bool RenderingServerCanvas::free(RID p_rid) {
}
for (int i = 0; i < canvas_item->child_items.size(); i++) {
-
canvas_item->child_items[i]->parent = RID();
}
@@ -1406,14 +1334,14 @@ bool RenderingServerCanvas::free(RID p_rid) {
memdelete(canvas_item);
} else if (canvas_light_owner.owns(p_rid)) {
-
RasterizerCanvas::Light *canvas_light = canvas_light_owner.getornull(p_rid);
ERR_FAIL_COND_V(!canvas_light, true);
if (canvas_light->canvas.is_valid()) {
Canvas *canvas = canvas_owner.getornull(canvas_light->canvas);
- if (canvas)
+ if (canvas) {
canvas->lights.erase(canvas_light);
+ }
}
RSG::canvas_render->free(canvas_light->light_internal);
@@ -1422,12 +1350,10 @@ bool RenderingServerCanvas::free(RID p_rid) {
memdelete(canvas_light);
} else if (canvas_light_occluder_owner.owns(p_rid)) {
-
RasterizerCanvas::LightOccluderInstance *occluder = canvas_light_occluder_owner.getornull(p_rid);
ERR_FAIL_COND_V(!occluder, true);
if (occluder->polygon.is_valid()) {
-
LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(occluder->polygon);
if (occluder_poly) {
occluder_poly->owners.erase(occluder);
@@ -1435,7 +1361,6 @@ bool RenderingServerCanvas::free(RID p_rid) {
}
if (occluder->canvas.is_valid() && canvas_owner.owns(occluder->canvas)) {
-
Canvas *canvas = canvas_owner.getornull(occluder->canvas);
canvas->occluders.erase(occluder);
}
@@ -1444,13 +1369,11 @@ bool RenderingServerCanvas::free(RID p_rid) {
memdelete(occluder);
} else if (canvas_light_occluder_polygon_owner.owns(p_rid)) {
-
LightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.getornull(p_rid);
ERR_FAIL_COND_V(!occluder_poly, true);
RSG::canvas_render->free(occluder_poly->occluder);
while (occluder_poly->owners.size()) {
-
occluder_poly->owners.front()->get()->polygon = RID();
occluder_poly->owners.erase(occluder_poly->owners.front());
}
@@ -1465,7 +1388,6 @@ bool RenderingServerCanvas::free(RID p_rid) {
}
RenderingServerCanvas::RenderingServerCanvas() {
-
z_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *));
z_last_list = (RasterizerCanvas::Item **)memalloc(z_range * sizeof(RasterizerCanvas::Item *));
@@ -1473,7 +1395,6 @@ RenderingServerCanvas::RenderingServerCanvas() {
}
RenderingServerCanvas::~RenderingServerCanvas() {
-
memfree(z_list);
memfree(z_last_list);
}
diff --git a/servers/rendering/rendering_server_canvas.h b/servers/rendering/rendering_server_canvas.h
index 9da11462db..59c0d1fa52 100644
--- a/servers/rendering/rendering_server_canvas.h
+++ b/servers/rendering/rendering_server_canvas.h
@@ -37,7 +37,6 @@
class RenderingServerCanvas {
public:
struct Item : public RasterizerCanvas::Item {
-
RID parent; // canvas it belongs to
List<Item *>::Element *E;
int z_index;
@@ -76,26 +75,22 @@ public:
};
struct ItemIndexSort {
-
_FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const {
-
return p_left->index < p_right->index;
}
};
struct ItemPtrSort {
-
_FORCE_INLINE_ bool operator()(const Item *p_left, const Item *p_right) const {
-
- if (Math::is_equal_approx(p_left->ysort_pos.y, p_right->ysort_pos.y))
+ if (Math::is_equal_approx(p_left->ysort_pos.y, p_right->ysort_pos.y)) {
return p_left->ysort_pos.x < p_right->ysort_pos.x;
+ }
return p_left->ysort_pos.y < p_right->ysort_pos.y;
}
};
struct LightOccluderPolygon {
-
bool active;
Rect2 aabb;
RS::CanvasOccluderPolygonCullMode cull_mode;
@@ -113,10 +108,8 @@ public:
RID_PtrOwner<RasterizerCanvas::LightOccluderInstance> canvas_light_occluder_owner;
struct Canvas : public RenderingServerViewport::CanvasBase {
-
Set<RID> viewports;
struct ChildItem {
-
Point2 mirror;
Item *item;
bool operator<(const ChildItem &p_item) const {
@@ -136,15 +129,17 @@ public:
int find_item(Item *p_item) {
for (int i = 0; i < child_items.size(); i++) {
- if (child_items[i].item == p_item)
+ if (child_items[i].item == p_item) {
return i;
+ }
}
return -1;
}
void erase_item(Item *p_item) {
int idx = find_item(p_item);
- if (idx >= 0)
+ if (idx >= 0) {
child_items.remove(idx);
+ }
}
Canvas() {
diff --git a/servers/rendering/rendering_server_raster.cpp b/servers/rendering/rendering_server_raster.cpp
index c6f3273339..d30160702b 100644
--- a/servers/rendering/rendering_server_raster.cpp
+++ b/servers/rendering/rendering_server_raster.cpp
@@ -45,7 +45,6 @@ int RenderingServerRaster::changes = 0;
/* BLACK BARS */
void RenderingServerRaster::black_bars_set_margins(int p_left, int p_top, int p_right, int p_bottom) {
-
black_margin[MARGIN_LEFT] = p_left;
black_margin[MARGIN_TOP] = p_top;
black_margin[MARGIN_RIGHT] = p_right;
@@ -53,7 +52,6 @@ void RenderingServerRaster::black_bars_set_margins(int p_left, int p_top, int p_
}
void RenderingServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_right, RID p_bottom) {
-
black_image[MARGIN_LEFT] = p_left;
black_image[MARGIN_TOP] = p_top;
black_image[MARGIN_RIGHT] = p_right;
@@ -61,30 +59,32 @@ void RenderingServerRaster::black_bars_set_images(RID p_left, RID p_top, RID p_r
}
void RenderingServerRaster::_draw_margins() {
-
RSG::canvas_render->draw_window_margins(black_margin, black_image);
};
/* FREE */
void RenderingServerRaster::free(RID p_rid) {
-
- if (RSG::storage->free(p_rid))
+ if (RSG::storage->free(p_rid)) {
return;
- if (RSG::canvas->free(p_rid))
+ }
+ if (RSG::canvas->free(p_rid)) {
return;
- if (RSG::viewport->free(p_rid))
+ }
+ if (RSG::viewport->free(p_rid)) {
return;
- if (RSG::scene->free(p_rid))
+ }
+ if (RSG::scene->free(p_rid)) {
return;
- if (RSG::scene_render->free(p_rid))
+ }
+ if (RSG::scene_render->free(p_rid)) {
return;
+ }
}
/* EVENT QUEUING */
void RenderingServerRaster::request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) {
-
ERR_FAIL_NULL(p_where);
FrameDrawnCallbacks fdc;
fdc.object = p_where->get_instance_id();
@@ -95,7 +95,6 @@ void RenderingServerRaster::request_frame_drawn_callback(Object *p_where, const
}
void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) {
-
//needs to be done before changes is reset to 0, to not force the editor to redraw
RS::get_singleton()->emit_signal("frame_pre_draw");
@@ -117,7 +116,6 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) {
RSG::rasterizer->end_frame(p_swap_buffers);
while (frame_drawn_callbacks.front()) {
-
Object *obj = ObjectDB::get_instance(frame_drawn_callbacks.front()->get().object);
if (obj) {
Callable::CallError ce;
@@ -163,18 +161,19 @@ void RenderingServerRaster::draw(bool p_swap_buffers, double frame_step) {
frame_profile_frame = RSG::storage->get_captured_timestamps_frame();
}
+
void RenderingServerRaster::sync() {
}
-bool RenderingServerRaster::has_changed() const {
+bool RenderingServerRaster::has_changed() const {
return changes > 0;
}
-void RenderingServerRaster::init() {
+void RenderingServerRaster::init() {
RSG::rasterizer->initialize();
}
-void RenderingServerRaster::finish() {
+void RenderingServerRaster::finish() {
if (test_cube.is_valid()) {
free(test_cube);
}
@@ -185,17 +184,14 @@ void RenderingServerRaster::finish() {
/* STATUS INFORMATION */
int RenderingServerRaster::get_render_info(RenderInfo p_info) {
-
return RSG::storage->get_render_info(p_info);
}
String RenderingServerRaster::get_video_adapter_name() const {
-
return RSG::storage->get_video_adapter_name();
}
String RenderingServerRaster::get_video_adapter_vendor() const {
-
return RSG::storage->get_video_adapter_vendor();
}
@@ -214,16 +210,15 @@ Vector<RenderingServer::FrameProfileArea> RenderingServerRaster::get_frame_profi
/* TESTING */
void RenderingServerRaster::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale, bool p_use_filter) {
-
redraw_request();
RSG::rasterizer->set_boot_image(p_image, p_color, p_scale, p_use_filter);
}
+
void RenderingServerRaster::set_default_clear_color(const Color &p_color) {
RSG::viewport->set_default_clear_color(p_color);
}
bool RenderingServerRaster::has_feature(Features p_feature) const {
-
return false;
}
@@ -235,12 +230,10 @@ RID RenderingServerRaster::get_test_cube() {
}
bool RenderingServerRaster::has_os_feature(const String &p_feature) const {
-
return RSG::storage->has_os_feature(p_feature);
}
void RenderingServerRaster::set_debug_generate_wireframes(bool p_generate) {
-
RSG::storage->set_debug_generate_wireframes(p_generate);
}
@@ -255,8 +248,8 @@ bool RenderingServerRaster::is_low_end() const {
//return RSG::rasterizer->is_low_end();
return false;
}
-RenderingServerRaster::RenderingServerRaster() {
+RenderingServerRaster::RenderingServerRaster() {
RSG::canvas = memnew(RenderingServerCanvas);
RSG::viewport = memnew(RenderingServerViewport);
RSG::scene = memnew(RenderingServerScene);
@@ -274,7 +267,6 @@ RenderingServerRaster::RenderingServerRaster() {
}
RenderingServerRaster::~RenderingServerRaster() {
-
memdelete(RSG::canvas);
memdelete(RSG::viewport);
memdelete(RSG::rasterizer);
diff --git a/servers/rendering/rendering_server_raster.h b/servers/rendering/rendering_server_raster.h
index f7b963a015..8a3c55118d 100644
--- a/servers/rendering/rendering_server_raster.h
+++ b/servers/rendering/rendering_server_raster.h
@@ -40,7 +40,6 @@
#include "servers/rendering_server.h"
class RenderingServerRaster : public RenderingServer {
-
enum {
MAX_INSTANCE_CULL = 8192,
@@ -61,7 +60,6 @@ class RenderingServerRaster : public RenderingServer {
RID black_image[4];
struct FrameDrawnCallbacks {
-
ObjectID object;
StringName method;
Variant param;
@@ -108,8 +106,12 @@ public:
m_r m_name(m_type1 arg1, m_type2 arg2) { return BINDBASE->m_name(arg1, arg2); }
#define BIND2RC(m_r, m_name, m_type1, m_type2) \
m_r m_name(m_type1 arg1, m_type2 arg2) const { return BINDBASE->m_name(arg1, arg2); }
+#define BIND3R(m_r, m_name, m_type1, m_type2, m_type3) \
+ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) { return BINDBASE->m_name(arg1, arg2, arg3); }
#define BIND3RC(m_r, m_name, m_type1, m_type2, m_type3) \
m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3) const { return BINDBASE->m_name(arg1, arg2, arg3); }
+#define BIND4R(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \
+ m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) { return BINDBASE->m_name(arg1, arg2, arg3, arg4); }
#define BIND4RC(m_r, m_name, m_type1, m_type2, m_type3, m_type4) \
m_r m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4) const { return BINDBASE->m_name(arg1, arg2, arg3, arg4); }
@@ -170,7 +172,7 @@ public:
//these also go pass-through
BIND0R(RID, texture_2d_placeholder_create)
- BIND0R(RID, texture_2d_layered_placeholder_create)
+ BIND1R(RID, texture_2d_layered_placeholder_create, TextureLayeredType)
BIND0R(RID, texture_3d_placeholder_create)
BIND1RC(Ref<Image>, texture_2d_get, RID)
@@ -404,23 +406,19 @@ public:
BIND2(gi_probe_set_anisotropy_strength, RID, float)
BIND1RC(float, gi_probe_get_anisotropy_strength, RID)
- /* LIGHTMAP CAPTURE */
-
- BIND0R(RID, lightmap_capture_create)
-
- BIND2(lightmap_capture_set_bounds, RID, const AABB &)
- BIND1RC(AABB, lightmap_capture_get_bounds, RID)
+ /* LIGHTMAP */
- BIND2(lightmap_capture_set_octree, RID, const Vector<uint8_t> &)
- BIND1RC(Vector<uint8_t>, lightmap_capture_get_octree, RID)
+ BIND0R(RID, lightmap_create)
- BIND2(lightmap_capture_set_octree_cell_transform, RID, const Transform &)
- BIND1RC(Transform, lightmap_capture_get_octree_cell_transform, RID)
- BIND2(lightmap_capture_set_octree_cell_subdiv, RID, int)
- BIND1RC(int, lightmap_capture_get_octree_cell_subdiv, RID)
-
- BIND2(lightmap_capture_set_energy, RID, float)
- BIND1RC(float, lightmap_capture_get_energy, RID)
+ BIND3(lightmap_set_textures, RID, RID, bool)
+ BIND2(lightmap_set_probe_bounds, RID, const AABB &)
+ BIND2(lightmap_set_probe_interior, RID, bool)
+ BIND5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &)
+ BIND1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID)
+ BIND1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID)
+ BIND1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID)
+ BIND1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID)
+ BIND1(lightmap_set_probe_capture_update_speed, float)
/* PARTICLES */
@@ -532,6 +530,7 @@ public:
BIND2(sky_set_radiance_size, RID, int)
BIND2(sky_set_mode, RID, SkyMode)
BIND2(sky_set_material, RID, RID)
+ BIND4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &)
BIND0R(RID, environment_create)
@@ -565,6 +564,8 @@ public:
BIND7(environment_set_fog_depth, RID, bool, float, float, float, bool, float)
BIND5(environment_set_fog_height, RID, bool, float, float, float)
+ BIND3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &)
+
BIND2(screen_space_roughness_limiter_set_active, bool, float)
BIND1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality)
BIND2(sub_surface_scattering_set_scale, float, float)
@@ -605,7 +606,6 @@ public:
BIND3(instance_set_blend_shape_weight, RID, int, float)
BIND3(instance_set_surface_material, RID, int, RID)
BIND2(instance_set_visible, RID, bool)
- BIND3(instance_set_use_lightmap, RID, RID, RID)
BIND2(instance_set_custom_aabb, RID, AABB)
@@ -625,12 +625,15 @@ public:
BIND5(instance_geometry_set_draw_range, RID, float, float, float, float)
BIND2(instance_geometry_set_as_instance_lod, RID, RID)
+ BIND4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int)
BIND3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &)
BIND2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &)
BIND2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &)
BIND2C(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *)
+ BIND3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &)
+
#undef BINDBASE
//from now on, calls forwarded to this singleton
#define BINDBASE RSG::canvas
diff --git a/servers/rendering/rendering_server_scene.cpp b/servers/rendering/rendering_server_scene.cpp
index 9d141ea570..7b8504036e 100644
--- a/servers/rendering/rendering_server_scene.cpp
+++ b/servers/rendering/rendering_server_scene.cpp
@@ -39,13 +39,11 @@
/* CAMERA API */
RID RenderingServerScene::camera_create() {
-
Camera *camera = memnew(Camera);
return camera_owner.make_rid(camera);
}
void RenderingServerScene::camera_set_perspective(RID p_camera, float p_fovy_degrees, float p_z_near, float p_z_far) {
-
Camera *camera = camera_owner.getornull(p_camera);
ERR_FAIL_COND(!camera);
camera->type = Camera::PERSPECTIVE;
@@ -55,7 +53,6 @@ void RenderingServerScene::camera_set_perspective(RID p_camera, float p_fovy_deg
}
void RenderingServerScene::camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) {
-
Camera *camera = camera_owner.getornull(p_camera);
ERR_FAIL_COND(!camera);
camera->type = Camera::ORTHOGONAL;
@@ -75,14 +72,12 @@ void RenderingServerScene::camera_set_frustum(RID p_camera, float p_size, Vector
}
void RenderingServerScene::camera_set_transform(RID p_camera, const Transform &p_transform) {
-
Camera *camera = camera_owner.getornull(p_camera);
ERR_FAIL_COND(!camera);
camera->transform = p_transform.orthonormalized();
}
void RenderingServerScene::camera_set_cull_mask(RID p_camera, uint32_t p_layers) {
-
Camera *camera = camera_owner.getornull(p_camera);
ERR_FAIL_COND(!camera);
@@ -90,21 +85,18 @@ void RenderingServerScene::camera_set_cull_mask(RID p_camera, uint32_t p_layers)
}
void RenderingServerScene::camera_set_environment(RID p_camera, RID p_env) {
-
Camera *camera = camera_owner.getornull(p_camera);
ERR_FAIL_COND(!camera);
camera->env = p_env;
}
void RenderingServerScene::camera_set_camera_effects(RID p_camera, RID p_fx) {
-
Camera *camera = camera_owner.getornull(p_camera);
ERR_FAIL_COND(!camera);
camera->effects = p_fx;
}
void RenderingServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_enable) {
-
Camera *camera = camera_owner.getornull(p_camera);
ERR_FAIL_COND(!camera);
camera->vaspect = p_enable;
@@ -113,7 +105,6 @@ void RenderingServerScene::camera_set_use_vertical_aspect(RID p_camera, bool p_e
/* SCENARIO API */
void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int) {
-
//RenderingServerScene *self = (RenderingServerScene*)p_self;
Instance *A = p_A;
Instance *B = p_B;
@@ -124,7 +115,6 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan
}
if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
-
InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@@ -135,14 +125,12 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan
List<InstanceLightData::PairInfo>::Element *E = light->geometries.push_back(pinfo);
if (geom->can_cast_shadows) {
-
light->shadow_dirty = true;
}
geom->lighting_dirty = true;
return E; //this element should make freeing faster
} else if (B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
-
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@@ -156,7 +144,6 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan
return E; //this element should make freeing faster
} else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
-
InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@@ -169,21 +156,22 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan
geom->decal_dirty = true;
return E; //this element should make freeing faster
- } else if (B->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
-
- InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(B->base_data);
+ } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
- InstanceLightmapCaptureData::PairInfo pinfo;
- pinfo.geometry = A;
- pinfo.L = geom->lightmap_captures.push_back(B);
-
- List<InstanceLightmapCaptureData::PairInfo>::Element *E = lightmap_capture->geometries.push_back(pinfo);
- ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture
+ if (A->dynamic_gi) {
+ InstanceLightmapData::PairInfo pinfo;
+ pinfo.geometry = A;
+ pinfo.L = geom->lightmap_captures.push_back(B);
+ List<InstanceLightmapData::PairInfo>::Element *E = lightmap_data->geometries.push_back(pinfo);
+ ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture
+ return E; //this element should make freeing faster
+ } else {
+ return nullptr;
+ }
- return E; //this element should make freeing faster
} else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
-
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@@ -203,15 +191,14 @@ void *RenderingServerScene::_instance_pair(void *p_self, OctreeElementID, Instan
return E; //this element should make freeing faster
} else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) {
-
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
return gi_probe->lights.insert(A);
}
return nullptr;
}
-void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *udata) {
+void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Instance *p_A, int, OctreeElementID, Instance *p_B, int, void *udata) {
//RenderingServerScene *self = (RenderingServerScene*)p_self;
Instance *A = p_A;
Instance *B = p_B;
@@ -222,7 +209,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta
}
if (B->base_type == RS::INSTANCE_LIGHT && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
-
InstanceLightData *light = static_cast<InstanceLightData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@@ -237,7 +223,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta
geom->lighting_dirty = true;
} else if (B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
-
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@@ -248,7 +233,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta
geom->reflection_dirty = true;
} else if (B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
-
InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@@ -258,19 +242,19 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta
decal->geometries.erase(E);
geom->decal_dirty = true;
- } else if (B->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ } else if (B->base_type == RS::INSTANCE_LIGHTMAP && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
+ if (udata) { //only for dynamic geometries
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(B->base_data);
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
- InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(B->base_data);
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
+ List<InstanceLightmapData::PairInfo>::Element *E = reinterpret_cast<List<InstanceLightmapData::PairInfo>::Element *>(udata);
- List<InstanceLightmapCaptureData::PairInfo>::Element *E = reinterpret_cast<List<InstanceLightmapCaptureData::PairInfo>::Element *>(udata);
-
- geom->lightmap_captures.erase(E->get().L);
- lightmap_capture->geometries.erase(E);
- ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture
+ geom->lightmap_captures.erase(E->get().L);
+ lightmap_data->geometries.erase(E);
+ ((RenderingServerScene *)p_self)->_instance_queue_update(A, false, false); //need to update capture
+ }
} else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
-
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@@ -286,7 +270,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta
geom->gi_probes_dirty = true;
} else if (B->base_type == RS::INSTANCE_GI_PROBE && A->base_type == RS::INSTANCE_LIGHT) {
-
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
Set<Instance *>::Element *E = reinterpret_cast<Set<Instance *>::Element *>(udata);
@@ -295,7 +278,6 @@ void RenderingServerScene::_instance_unpair(void *p_self, OctreeElementID, Insta
}
RID RenderingServerScene::scenario_create() {
-
Scenario *scenario = memnew(Scenario);
ERR_FAIL_COND_V(!scenario, RID());
RID scenario_rid = scenario_owner.make_rid(scenario);
@@ -314,35 +296,30 @@ RID RenderingServerScene::scenario_create() {
}
void RenderingServerScene::scenario_set_debug(RID p_scenario, RS::ScenarioDebugMode p_debug_mode) {
-
Scenario *scenario = scenario_owner.getornull(p_scenario);
ERR_FAIL_COND(!scenario);
scenario->debug = p_debug_mode;
}
void RenderingServerScene::scenario_set_environment(RID p_scenario, RID p_environment) {
-
Scenario *scenario = scenario_owner.getornull(p_scenario);
ERR_FAIL_COND(!scenario);
scenario->environment = p_environment;
}
void RenderingServerScene::scenario_set_camera_effects(RID p_scenario, RID p_camera_effects) {
-
Scenario *scenario = scenario_owner.getornull(p_scenario);
ERR_FAIL_COND(!scenario);
scenario->camera_effects = p_camera_effects;
}
void RenderingServerScene::scenario_set_fallback_environment(RID p_scenario, RID p_environment) {
-
Scenario *scenario = scenario_owner.getornull(p_scenario);
ERR_FAIL_COND(!scenario);
scenario->fallback_environment = p_environment;
}
void RenderingServerScene::scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) {
-
Scenario *scenario = scenario_owner.getornull(p_scenario);
ERR_FAIL_COND(!scenario);
RSG::scene_render->reflection_atlas_set_size(scenario->reflection_atlas, p_reflection_size, p_reflection_count);
@@ -351,20 +328,21 @@ void RenderingServerScene::scenario_set_reflection_atlas_size(RID p_scenario, in
/* INSTANCING API */
void RenderingServerScene::_instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies) {
-
- if (p_update_aabb)
+ if (p_update_aabb) {
p_instance->update_aabb = true;
- if (p_update_dependencies)
+ }
+ if (p_update_dependencies) {
p_instance->update_dependencies = true;
+ }
- if (p_instance->update_item.in_list())
+ if (p_instance->update_item.in_list()) {
return;
+ }
_instance_update_list.add(&p_instance->update_item);
}
RID RenderingServerScene::instance_create() {
-
Instance *instance = memnew(Instance);
ERR_FAIL_COND_V(!instance, RID());
@@ -375,7 +353,6 @@ RID RenderingServerScene::instance_create() {
}
void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
-
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
@@ -391,7 +368,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
switch (instance->base_type) {
case RS::INSTANCE_LIGHT: {
-
InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
#ifdef DEBUG_ENABLED
if (light->geometries.size()) {
@@ -405,7 +381,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
RSG::scene_render->free(light->instance);
} break;
case RS::INSTANCE_REFLECTION_PROBE: {
-
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
RSG::scene_render->free(reflection_probe->instance);
if (reflection_probe->update_list.in_list()) {
@@ -413,21 +388,18 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
}
} break;
case RS::INSTANCE_DECAL: {
-
InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data);
RSG::scene_render->free(decal->instance);
} break;
- case RS::INSTANCE_LIGHTMAP_CAPTURE: {
-
- InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(instance->base_data);
+ case RS::INSTANCE_LIGHTMAP: {
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(instance->base_data);
//erase dependencies, since no longer a lightmap
- while (lightmap_capture->users.front()) {
- instance_set_use_lightmap(lightmap_capture->users.front()->get()->self, RID(), RID());
+ while (lightmap_data->users.front()) {
+ instance_geometry_set_lightmap(lightmap_data->users.front()->get()->self, RID(), Rect2(), 0);
}
} break;
case RS::INSTANCE_GI_PROBE: {
-
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
#ifdef DEBUG_ENABLED
if (gi_probe->geometries.size()) {
@@ -443,14 +415,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
gi_probe_update_list.remove(&gi_probe->update_element);
}
- if (instance->lightmap_capture) {
- Instance *capture = (Instance *)instance->lightmap_capture;
- InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(capture->base_data);
- lightmap_capture->users.erase(instance);
- instance->lightmap_capture = nullptr;
- instance->lightmap = RID();
- }
-
RSG::scene_render->free(gi_probe->probe_instance);
} break;
@@ -471,13 +435,11 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
instance->base = RID();
if (p_base.is_valid()) {
-
instance->base_type = RSG::storage->get_base_type(p_base);
ERR_FAIL_COND(instance->base_type == RS::INSTANCE_NONE);
switch (instance->base_type) {
case RS::INSTANCE_LIGHT: {
-
InstanceLightData *light = memnew(InstanceLightData);
if (scenario && RSG::storage->light_get_type(p_base) == RS::LIGHT_DIRECTIONAL) {
@@ -492,7 +454,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
case RS::INSTANCE_MULTIMESH:
case RS::INSTANCE_IMMEDIATE:
case RS::INSTANCE_PARTICLES: {
-
InstanceGeometryData *geom = memnew(InstanceGeometryData);
instance->base_data = geom;
if (instance->base_type == RS::INSTANCE_MESH) {
@@ -500,7 +461,6 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
}
} break;
case RS::INSTANCE_REFLECTION_PROBE: {
-
InstanceReflectionProbeData *reflection_probe = memnew(InstanceReflectionProbeData);
reflection_probe->owner = instance;
instance->base_data = reflection_probe;
@@ -508,21 +468,18 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
reflection_probe->instance = RSG::scene_render->reflection_probe_instance_create(p_base);
} break;
case RS::INSTANCE_DECAL: {
-
InstanceDecalData *decal = memnew(InstanceDecalData);
decal->owner = instance;
instance->base_data = decal;
decal->instance = RSG::scene_render->decal_instance_create(p_base);
} break;
- case RS::INSTANCE_LIGHTMAP_CAPTURE: {
-
- InstanceLightmapCaptureData *lightmap_capture = memnew(InstanceLightmapCaptureData);
- instance->base_data = lightmap_capture;
- //lightmap_capture->instance = RSG::scene_render->lightmap_capture_instance_create(p_base);
+ case RS::INSTANCE_LIGHTMAP: {
+ InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData);
+ instance->base_data = lightmap_data;
+ //lightmap_data->instance = RSG::scene_render->lightmap_data_instance_create(p_base);
} break;
case RS::INSTANCE_GI_PROBE: {
-
InstanceGIProbeData *gi_probe = memnew(InstanceGIProbeData);
instance->base_data = gi_probe;
gi_probe->owner = instance;
@@ -546,13 +503,12 @@ void RenderingServerScene::instance_set_base(RID p_instance, RID p_base) {
_instance_queue_update(instance, true, true);
}
-void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) {
+void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
if (instance->scenario) {
-
instance->scenario->instances.remove(&instance->scenario_item);
if (instance->octree_id) {
@@ -561,9 +517,7 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario)
}
switch (instance->base_type) {
-
case RS::INSTANCE_LIGHT: {
-
InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
#ifdef DEBUG_ENABLED
if (light->geometries.size()) {
@@ -581,7 +535,6 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario)
} break;
case RS::INSTANCE_GI_PROBE: {
-
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
#ifdef DEBUG_ENABLED
@@ -607,7 +560,6 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario)
}
if (p_scenario.is_valid()) {
-
Scenario *scenario = scenario_owner.getornull(p_scenario);
ERR_FAIL_COND(!scenario);
@@ -616,9 +568,7 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario)
scenario->instances.add(&instance->scenario_item);
switch (instance->base_type) {
-
case RS::INSTANCE_LIGHT: {
-
InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
if (RSG::storage->light_get_type(instance->base) == RS::LIGHT_DIRECTIONAL) {
@@ -626,7 +576,6 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario)
}
} break;
case RS::INSTANCE_GI_PROBE: {
-
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
if (!gi_probe->update_element.in_list()) {
gi_probe_update_list.add(&gi_probe->update_element);
@@ -639,20 +588,21 @@ void RenderingServerScene::instance_set_scenario(RID p_instance, RID p_scenario)
_instance_queue_update(instance, true, true);
}
}
-void RenderingServerScene::instance_set_layer_mask(RID p_instance, uint32_t p_mask) {
+void RenderingServerScene::instance_set_layer_mask(RID p_instance, uint32_t p_mask) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
instance->layer_mask = p_mask;
}
-void RenderingServerScene::instance_set_transform(RID p_instance, const Transform &p_transform) {
+void RenderingServerScene::instance_set_transform(RID p_instance, const Transform &p_transform) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
- if (instance->transform == p_transform)
+ if (instance->transform == p_transform) {
return; //must be checked to avoid worst evil
+ }
#ifdef DEBUG_ENABLED
@@ -670,15 +620,15 @@ void RenderingServerScene::instance_set_transform(RID p_instance, const Transfor
instance->transform = p_transform;
_instance_queue_update(instance, true);
}
-void RenderingServerScene::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) {
+void RenderingServerScene::instance_attach_object_instance_id(RID p_instance, ObjectID p_id) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
instance->object_id = p_id;
}
-void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) {
+void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
@@ -691,7 +641,6 @@ void RenderingServerScene::instance_set_blend_shape_weight(RID p_instance, int p
}
void RenderingServerScene::instance_set_surface_material(RID p_instance, int p_surface, RID p_material) {
-
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
@@ -708,12 +657,12 @@ void RenderingServerScene::instance_set_surface_material(RID p_instance, int p_s
}
void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible) {
-
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
- if (instance->visible == p_visible)
+ if (instance->visible == p_visible) {
return;
+ }
instance->visible = p_visible;
@@ -736,9 +685,9 @@ void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible)
}
} break;
- case RS::INSTANCE_LIGHTMAP_CAPTURE: {
+ case RS::INSTANCE_LIGHTMAP: {
if (instance->octree_id && instance->scenario) {
- instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_LIGHTMAP_CAPTURE, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0);
+ instance->scenario->octree.set_pairable(instance->octree_id, p_visible, 1 << RS::INSTANCE_LIGHTMAP, p_visible ? RS::INSTANCE_GEOMETRY_MASK : 0);
}
} break;
@@ -752,49 +701,24 @@ void RenderingServerScene::instance_set_visible(RID p_instance, bool p_visible)
}
}
}
+
inline bool is_geometry_instance(RenderingServer::InstanceType p_type) {
return p_type == RS::INSTANCE_MESH || p_type == RS::INSTANCE_MULTIMESH || p_type == RS::INSTANCE_PARTICLES || p_type == RS::INSTANCE_IMMEDIATE;
}
-void RenderingServerScene::instance_set_use_lightmap(RID p_instance, RID p_lightmap_instance, RID p_lightmap) {
-
- Instance *instance = instance_owner.getornull(p_instance);
- ERR_FAIL_COND(!instance);
-
- if (instance->lightmap_capture) {
- InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(((Instance *)instance->lightmap_capture)->base_data);
- lightmap_capture->users.erase(instance);
- instance->lightmap = RID();
- instance->lightmap_capture = nullptr;
- }
-
- if (p_lightmap_instance.is_valid()) {
- Instance *lightmap_instance = instance_owner.getornull(p_lightmap_instance);
- ERR_FAIL_COND(!lightmap_instance);
- ERR_FAIL_COND(lightmap_instance->base_type != RS::INSTANCE_LIGHTMAP_CAPTURE);
- instance->lightmap_capture = lightmap_instance;
-
- InstanceLightmapCaptureData *lightmap_capture = static_cast<InstanceLightmapCaptureData *>(((Instance *)instance->lightmap_capture)->base_data);
- lightmap_capture->users.insert(instance);
- instance->lightmap = p_lightmap;
- }
-}
-
void RenderingServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb) {
-
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
ERR_FAIL_COND(!is_geometry_instance(instance->base_type));
if (p_aabb != AABB()) {
-
// Set custom AABB
- if (instance->custom_aabb == nullptr)
+ if (instance->custom_aabb == nullptr) {
instance->custom_aabb = memnew(AABB);
+ }
*instance->custom_aabb = p_aabb;
} else {
-
// Clear custom AABB
if (instance->custom_aabb != nullptr) {
memdelete(instance->custom_aabb);
@@ -802,17 +726,18 @@ void RenderingServerScene::instance_set_custom_aabb(RID p_instance, AABB p_aabb)
}
}
- if (instance->scenario)
+ if (instance->scenario) {
_instance_queue_update(instance, true, false);
+ }
}
void RenderingServerScene::instance_attach_skeleton(RID p_instance, RID p_skeleton) {
-
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
- if (instance->skeleton == p_skeleton)
+ if (instance->skeleton == p_skeleton) {
return;
+ }
instance->skeleton = p_skeleton;
@@ -835,7 +760,6 @@ void RenderingServerScene::instance_set_extra_visibility_margin(RID p_instance,
}
Vector<ObjectID> RenderingServerScene::instances_cull_aabb(const AABB &p_aabb, RID p_scenario) const {
-
Vector<ObjectID> instances;
Scenario *scenario = scenario_owner.getornull(p_scenario);
ERR_FAIL_COND_V(!scenario, instances);
@@ -847,19 +771,19 @@ Vector<ObjectID> RenderingServerScene::instances_cull_aabb(const AABB &p_aabb, R
culled = scenario->octree.cull_aabb(p_aabb, cull, 1024);
for (int i = 0; i < culled; i++) {
-
Instance *instance = cull[i];
ERR_CONTINUE(!instance);
- if (instance->object_id.is_null())
+ if (instance->object_id.is_null()) {
continue;
+ }
instances.push_back(instance->object_id);
}
return instances;
}
-Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const {
+Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const {
Vector<ObjectID> instances;
Scenario *scenario = scenario_owner.getornull(p_scenario);
ERR_FAIL_COND_V(!scenario, instances);
@@ -872,16 +796,17 @@ Vector<ObjectID> RenderingServerScene::instances_cull_ray(const Vector3 &p_from,
for (int i = 0; i < culled; i++) {
Instance *instance = cull[i];
ERR_CONTINUE(!instance);
- if (instance->object_id.is_null())
+ if (instance->object_id.is_null()) {
continue;
+ }
instances.push_back(instance->object_id);
}
return instances;
}
-Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const {
+Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario) const {
Vector<ObjectID> instances;
Scenario *scenario = scenario_owner.getornull(p_scenario);
ERR_FAIL_COND_V(!scenario, instances);
@@ -893,11 +818,11 @@ Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane>
culled = scenario->octree.cull_convex(p_convex, cull, 1024);
for (int i = 0; i < culled; i++) {
-
Instance *instance = cull[i];
ERR_CONTINUE(!instance);
- if (instance->object_id.is_null())
+ if (instance->object_id.is_null()) {
continue;
+ }
instances.push_back(instance->object_id);
}
@@ -906,21 +831,17 @@ Vector<ObjectID> RenderingServerScene::instances_cull_convex(const Vector<Plane>
}
void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::InstanceFlags p_flags, bool p_enabled) {
-
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
//ERR_FAIL_COND(((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK));
switch (p_flags) {
-
case RS::INSTANCE_FLAG_USE_BAKED_LIGHT: {
-
instance->baked_light = p_enabled;
} break;
case RS::INSTANCE_FLAG_USE_DYNAMIC_GI: {
-
if (p_enabled == instance->dynamic_gi) {
//bye, redundant
return;
@@ -938,7 +859,6 @@ void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::Instan
} break;
case RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE: {
-
instance->redraw_if_visible = p_enabled;
} break;
@@ -946,16 +866,16 @@ void RenderingServerScene::instance_geometry_set_flag(RID p_instance, RS::Instan
}
}
}
-void RenderingServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) {
+void RenderingServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, RS::ShadowCastingSetting p_shadow_casting_setting) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
instance->cast_shadows = p_shadow_casting_setting;
_instance_queue_update(instance, false, true);
}
-void RenderingServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) {
+void RenderingServerScene::instance_geometry_set_material_override(RID p_instance, RID p_material) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
@@ -965,11 +885,33 @@ void RenderingServerScene::instance_geometry_set_material_override(RID p_instanc
void RenderingServerScene::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) {
}
+
void RenderingServerScene::instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) {
}
-void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) {
+void RenderingServerScene::instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index) {
+ Instance *instance = instance_owner.getornull(p_instance);
+ ERR_FAIL_COND(!instance);
+
+ if (instance->lightmap) {
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(((Instance *)instance->lightmap)->base_data);
+ lightmap_data->users.erase(instance);
+ instance->lightmap = nullptr;
+ }
+
+ Instance *lightmap_instance = instance_owner.getornull(p_lightmap);
+ instance->lightmap = lightmap_instance;
+ instance->lightmap_uv_scale = p_lightmap_uv_scale;
+ instance->lightmap_slice_index = p_slice_index;
+
+ if (lightmap_instance) {
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(lightmap_instance->base_data);
+ lightmap_data->users.insert(instance);
+ }
+}
+
+void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
@@ -991,7 +933,6 @@ void RenderingServerScene::instance_geometry_set_shader_parameter(RID p_instance
}
Variant RenderingServerScene::instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const {
-
const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!instance, Variant());
@@ -1002,7 +943,6 @@ Variant RenderingServerScene::instance_geometry_get_shader_parameter(RID p_insta
}
Variant RenderingServerScene::instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const {
-
const Instance *instance = const_cast<RenderingServerScene *>(this)->instance_owner.getornull(p_instance);
ERR_FAIL_COND_V(!instance, Variant());
@@ -1030,11 +970,9 @@ void RenderingServerScene::instance_geometry_get_shader_parameter_list(RID p_ins
}
void RenderingServerScene::_update_instance(Instance *p_instance) {
-
p_instance->version++;
if (p_instance->base_type == RS::INSTANCE_LIGHT) {
-
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
RSG::scene_render->light_instance_set_transform(light->instance, p_instance->transform);
@@ -1042,7 +980,6 @@ void RenderingServerScene::_update_instance(Instance *p_instance) {
}
if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
-
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
RSG::scene_render->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform);
@@ -1050,21 +987,18 @@ void RenderingServerScene::_update_instance(Instance *p_instance) {
}
if (p_instance->base_type == RS::INSTANCE_DECAL) {
-
InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data);
RSG::scene_render->decal_instance_set_transform(decal->instance, p_instance->transform);
}
if (p_instance->base_type == RS::INSTANCE_GI_PROBE) {
-
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data);
RSG::scene_render->gi_probe_instance_set_transform_to_data(gi_probe->probe_instance, p_instance->transform);
}
if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
-
RSG::storage->particles_set_emission_transform(p_instance->base, p_instance->transform);
}
@@ -1073,7 +1007,6 @@ void RenderingServerScene::_update_instance(Instance *p_instance) {
}
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
-
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
//make sure lights are updated if it casts shadow
@@ -1084,16 +1017,28 @@ void RenderingServerScene::_update_instance(Instance *p_instance) {
}
}
- if (!p_instance->lightmap_capture && geom->lightmap_captures.size()) {
+ if (!p_instance->lightmap && geom->lightmap_captures.size()) {
//affected by lightmap captures, must update capture info!
_update_instance_lightmap_captures(p_instance);
} else {
- if (!p_instance->lightmap_capture_data.empty()) {
- p_instance->lightmap_capture_data.resize(0); //not in use, clear capture data
+ if (!p_instance->lightmap_sh.empty()) {
+ p_instance->lightmap_sh.clear(); //don't need SH
+ p_instance->lightmap_target_sh.clear(); //don't need SH
}
}
}
+ if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
+ //if this moved, update the captured objects
+ InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data);
+ //erase dependencies, since no longer a lightmap
+
+ for (List<InstanceLightmapData::PairInfo>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) {
+ Instance *geom = E->get().geometry;
+ _instance_queue_update(geom, true, false);
+ }
+ }
+
p_instance->mirror = p_instance->transform.basis.determinant() < 0.0;
AABB new_aabb;
@@ -1103,18 +1048,15 @@ void RenderingServerScene::_update_instance(Instance *p_instance) {
p_instance->transformed_aabb = new_aabb;
if (!p_instance->scenario) {
-
return;
}
if (p_instance->octree_id == 0) {
-
uint32_t base_type = 1 << p_instance->base_type;
uint32_t pairable_mask = 0;
bool pairable = false;
- if (p_instance->base_type == RS::INSTANCE_LIGHT || p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL || p_instance->base_type == RS::INSTANCE_LIGHTMAP_CAPTURE) {
-
+ if (p_instance->base_type == RS::INSTANCE_LIGHT || p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL || p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
pairable_mask = p_instance->visible ? RS::INSTANCE_GEOMETRY_MASK : 0;
pairable = true;
}
@@ -1129,7 +1071,6 @@ void RenderingServerScene::_update_instance(Instance *p_instance) {
p_instance->octree_id = p_instance->scenario->octree.create(p_instance, new_aabb, 0, pairable, base_type, pairable_mask);
} else {
-
/*
if (new_aabb==p_instance->data.transformed_aabb)
return;
@@ -1140,72 +1081,65 @@ void RenderingServerScene::_update_instance(Instance *p_instance) {
}
void RenderingServerScene::_update_instance_aabb(Instance *p_instance) {
-
AABB new_aabb;
ERR_FAIL_COND(p_instance->base_type != RS::INSTANCE_NONE && !p_instance->base.is_valid());
switch (p_instance->base_type) {
case RenderingServer::INSTANCE_NONE: {
-
// do nothing
} break;
case RenderingServer::INSTANCE_MESH: {
-
- if (p_instance->custom_aabb)
+ if (p_instance->custom_aabb) {
new_aabb = *p_instance->custom_aabb;
- else
+ } else {
new_aabb = RSG::storage->mesh_get_aabb(p_instance->base, p_instance->skeleton);
+ }
} break;
case RenderingServer::INSTANCE_MULTIMESH: {
-
- if (p_instance->custom_aabb)
+ if (p_instance->custom_aabb) {
new_aabb = *p_instance->custom_aabb;
- else
+ } else {
new_aabb = RSG::storage->multimesh_get_aabb(p_instance->base);
+ }
} break;
case RenderingServer::INSTANCE_IMMEDIATE: {
-
- if (p_instance->custom_aabb)
+ if (p_instance->custom_aabb) {
new_aabb = *p_instance->custom_aabb;
- else
+ } else {
new_aabb = RSG::storage->immediate_get_aabb(p_instance->base);
+ }
} break;
case RenderingServer::INSTANCE_PARTICLES: {
-
- if (p_instance->custom_aabb)
+ if (p_instance->custom_aabb) {
new_aabb = *p_instance->custom_aabb;
- else
+ } else {
new_aabb = RSG::storage->particles_get_aabb(p_instance->base);
+ }
} break;
case RenderingServer::INSTANCE_LIGHT: {
-
new_aabb = RSG::storage->light_get_aabb(p_instance->base);
} break;
case RenderingServer::INSTANCE_REFLECTION_PROBE: {
-
new_aabb = RSG::storage->reflection_probe_get_aabb(p_instance->base);
} break;
case RenderingServer::INSTANCE_DECAL: {
-
new_aabb = RSG::storage->decal_get_aabb(p_instance->base);
} break;
case RenderingServer::INSTANCE_GI_PROBE: {
-
new_aabb = RSG::storage->gi_probe_get_bounds(p_instance->base);
} break;
- case RenderingServer::INSTANCE_LIGHTMAP_CAPTURE: {
-
- new_aabb = RSG::storage->lightmap_capture_get_bounds(p_instance->base);
+ case RenderingServer::INSTANCE_LIGHTMAP: {
+ new_aabb = RSG::storage->lightmap_get_aabb(p_instance->base);
} break;
default: {
@@ -1213,247 +1147,92 @@ void RenderingServerScene::_update_instance_aabb(Instance *p_instance) {
}
// <Zylann> This is why I didn't re-use Instance::aabb to implement custom AABBs
- if (p_instance->extra_margin)
+ if (p_instance->extra_margin) {
new_aabb.grow_by(p_instance->extra_margin);
+ }
p_instance->aabb = new_aabb;
}
-_FORCE_INLINE_ static void _light_capture_sample_octree(const RasterizerStorage::LightmapCaptureOctree *p_octree, int p_cell_subdiv, const Vector3 &p_pos, const Vector3 &p_dir, float p_level, Vector3 &r_color, float &r_alpha) {
-
- static const Vector3 aniso_normal[6] = {
- Vector3(-1, 0, 0),
- Vector3(1, 0, 0),
- Vector3(0, -1, 0),
- Vector3(0, 1, 0),
- Vector3(0, 0, -1),
- Vector3(0, 0, 1)
- };
-
- int size = 1 << (p_cell_subdiv - 1);
-
- int clamp_v = size - 1;
- //first of all, clamp
- Vector3 pos;
- pos.x = CLAMP(p_pos.x, 0, clamp_v);
- pos.y = CLAMP(p_pos.y, 0, clamp_v);
- pos.z = CLAMP(p_pos.z, 0, clamp_v);
-
- float level = (p_cell_subdiv - 1) - p_level;
-
- int target_level;
- float level_filter;
- if (level <= 0.0) {
- level_filter = 0;
- target_level = 0;
- } else {
- target_level = Math::ceil(level);
- level_filter = target_level - level;
- }
-
- Vector3 color[2][8];
- float alpha[2][8];
- zeromem(alpha, sizeof(float) * 2 * 8);
-
- //find cell at given level first
-
- for (int c = 0; c < 2; c++) {
-
- int current_level = MAX(0, target_level - c);
- int level_cell_size = (1 << (p_cell_subdiv - 1)) >> current_level;
-
- for (int n = 0; n < 8; n++) {
-
- int x = int(pos.x);
- int y = int(pos.y);
- int z = int(pos.z);
+void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instance) {
+ bool first_set = p_instance->lightmap_sh.size() == 0;
+ p_instance->lightmap_sh.resize(9); //using SH
+ p_instance->lightmap_target_sh.resize(9); //using SH
+ Color *instance_sh = p_instance->lightmap_target_sh.ptrw();
+ bool inside = false;
+ Color accum_sh[9];
+ float accum_blend = 0.0;
- if (n & 1)
- x += level_cell_size;
- if (n & 2)
- y += level_cell_size;
- if (n & 4)
- z += level_cell_size;
+ InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+ for (List<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) {
+ Instance *lightmap = E->get();
- int ofs_x = 0;
- int ofs_y = 0;
- int ofs_z = 0;
+ bool interior = RSG::storage->lightmap_is_interior(lightmap->base);
- x = CLAMP(x, 0, clamp_v);
- y = CLAMP(y, 0, clamp_v);
- z = CLAMP(z, 0, clamp_v);
+ if (inside && !interior) {
+ continue; //we are inside, ignore exteriors
+ }
- int half = size / 2;
- uint32_t cell = 0;
- for (int i = 0; i < current_level; i++) {
+ Transform to_bounds = lightmap->transform.affine_inverse();
+ Vector3 center = p_instance->transform.xform(p_instance->aabb.position + p_instance->aabb.size * 0.5); //use aabb center
- const RasterizerStorage::LightmapCaptureOctree *bc = &p_octree[cell];
+ Vector3 lm_pos = to_bounds.xform(center);
- int child = 0;
- if (x >= ofs_x + half) {
- child |= 1;
- ofs_x += half;
- }
- if (y >= ofs_y + half) {
- child |= 2;
- ofs_y += half;
- }
- if (z >= ofs_z + half) {
- child |= 4;
- ofs_z += half;
- }
+ AABB bounds = RSG::storage->lightmap_get_aabb(lightmap->base);
+ if (!bounds.has_point(lm_pos)) {
+ continue; //not in this lightmap
+ }
- cell = bc->children[child];
- if (cell == RasterizerStorage::LightmapCaptureOctree::CHILD_EMPTY)
- break;
+ Color sh[9];
+ RSG::storage->lightmap_tap_sh_light(lightmap->base, lm_pos, sh);
- half >>= 1;
+ //rotate it
+ Basis rot = lightmap->transform.basis.orthonormalized();
+ for (int i = 0; i < 3; i++) {
+ float csh[9];
+ for (int j = 0; j < 9; j++) {
+ csh[j] = sh[j][i];
}
-
- if (cell == RasterizerStorage::LightmapCaptureOctree::CHILD_EMPTY) {
- alpha[c][n] = 0;
- } else {
- alpha[c][n] = p_octree[cell].alpha;
-
- for (int i = 0; i < 6; i++) {
- //anisotropic read light
- float amount = p_dir.dot(aniso_normal[i]);
- if (amount < 0)
- amount = 0;
- color[c][n].x += p_octree[cell].light[i][0] / 1024.0 * amount;
- color[c][n].y += p_octree[cell].light[i][1] / 1024.0 * amount;
- color[c][n].z += p_octree[cell].light[i][2] / 1024.0 * amount;
- }
+ rot.rotate_sh(csh);
+ for (int j = 0; j < 9; j++) {
+ sh[j][i] = csh[j];
}
-
- //print_line("\tlev " + itos(c) + " - " + itos(n) + " alpha: " + rtos(cells[test_cell].alpha) + " col: " + color[c][n]);
}
- }
-
- float target_level_size = size >> target_level;
- Vector3 pos_fract[2];
-
- pos_fract[0].x = Math::fmod(pos.x, target_level_size) / target_level_size;
- pos_fract[0].y = Math::fmod(pos.y, target_level_size) / target_level_size;
- pos_fract[0].z = Math::fmod(pos.z, target_level_size) / target_level_size;
-
- target_level_size = size >> MAX(0, target_level - 1);
-
- pos_fract[1].x = Math::fmod(pos.x, target_level_size) / target_level_size;
- pos_fract[1].y = Math::fmod(pos.y, target_level_size) / target_level_size;
- pos_fract[1].z = Math::fmod(pos.z, target_level_size) / target_level_size;
- float alpha_interp[2];
- Vector3 color_interp[2];
+ Vector3 inner_pos = ((lm_pos - bounds.position) / bounds.size) * 2.0 - Vector3(1.0, 1.0, 1.0);
- for (int i = 0; i < 2; i++) {
-
- Vector3 color_x00 = color[i][0].linear_interpolate(color[i][1], pos_fract[i].x);
- Vector3 color_xy0 = color[i][2].linear_interpolate(color[i][3], pos_fract[i].x);
- Vector3 blend_z0 = color_x00.linear_interpolate(color_xy0, pos_fract[i].y);
-
- Vector3 color_x0z = color[i][4].linear_interpolate(color[i][5], pos_fract[i].x);
- Vector3 color_xyz = color[i][6].linear_interpolate(color[i][7], pos_fract[i].x);
- Vector3 blend_z1 = color_x0z.linear_interpolate(color_xyz, pos_fract[i].y);
-
- color_interp[i] = blend_z0.linear_interpolate(blend_z1, pos_fract[i].z);
-
- float alpha_x00 = Math::lerp(alpha[i][0], alpha[i][1], pos_fract[i].x);
- float alpha_xy0 = Math::lerp(alpha[i][2], alpha[i][3], pos_fract[i].x);
- float alpha_z0 = Math::lerp(alpha_x00, alpha_xy0, pos_fract[i].y);
-
- float alpha_x0z = Math::lerp(alpha[i][4], alpha[i][5], pos_fract[i].x);
- float alpha_xyz = Math::lerp(alpha[i][6], alpha[i][7], pos_fract[i].x);
- float alpha_z1 = Math::lerp(alpha_x0z, alpha_xyz, pos_fract[i].y);
-
- alpha_interp[i] = Math::lerp(alpha_z0, alpha_z1, pos_fract[i].z);
- }
-
- r_color = color_interp[0].linear_interpolate(color_interp[1], level_filter);
- r_alpha = Math::lerp(alpha_interp[0], alpha_interp[1], level_filter);
-
- //print_line("pos: " + p_posf + " level " + rtos(p_level) + " down to " + itos(target_level) + "." + rtos(level_filter) + " color " + r_color + " alpha " + rtos(r_alpha));
-}
-
-_FORCE_INLINE_ static Color _light_capture_voxel_cone_trace(const RasterizerStorage::LightmapCaptureOctree *p_octree, const Vector3 &p_pos, const Vector3 &p_dir, float p_aperture, int p_cell_subdiv) {
-
- float bias = 0.0; //no need for bias here
- float max_distance = (Vector3(1, 1, 1) * (1 << (p_cell_subdiv - 1))).length();
-
- float dist = bias;
- float alpha = 0.0;
- Vector3 color;
-
- Vector3 scolor;
- float salpha;
-
- while (dist < max_distance && alpha < 0.95) {
- float diameter = MAX(1.0, 2.0 * p_aperture * dist);
- _light_capture_sample_octree(p_octree, p_cell_subdiv, p_pos + dist * p_dir, p_dir, log2(diameter), scolor, salpha);
- float a = (1.0 - alpha);
- color += scolor * a;
- alpha += a * salpha;
- dist += diameter * 0.5;
- }
-
- return Color(color.x, color.y, color.z, alpha);
-}
-
-void RenderingServerScene::_update_instance_lightmap_captures(Instance *p_instance) {
-
- InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+ float blend = MAX(inner_pos.x, MAX(inner_pos.y, inner_pos.z));
+ //make blend more rounded
+ blend = Math::lerp(inner_pos.length(), blend, blend);
+ blend *= blend;
+ blend = MAX(0.0, 1.0 - blend);
- static const Vector3 cone_traces[12] = {
- Vector3(0, 0, 1),
- Vector3(0.866025, 0, 0.5),
- Vector3(0.267617, 0.823639, 0.5),
- Vector3(-0.700629, 0.509037, 0.5),
- Vector3(-0.700629, -0.509037, 0.5),
- Vector3(0.267617, -0.823639, 0.5),
- Vector3(0, 0, -1),
- Vector3(0.866025, 0, -0.5),
- Vector3(0.267617, 0.823639, -0.5),
- Vector3(-0.700629, 0.509037, -0.5),
- Vector3(-0.700629, -0.509037, -0.5),
- Vector3(0.267617, -0.823639, -0.5)
- };
-
- float cone_aperture = 0.577; // tan(angle) 60 degrees
-
- if (p_instance->lightmap_capture_data.empty()) {
- p_instance->lightmap_capture_data.resize(12);
+ if (interior && !inside) {
+ //do not blend, just replace
+ for (int j = 0; j < 9; j++) {
+ accum_sh[j] = sh[j] * blend;
+ }
+ accum_blend = blend;
+ inside = true;
+ } else {
+ for (int j = 0; j < 9; j++) {
+ accum_sh[j] += sh[j] * blend;
+ }
+ accum_blend += blend;
+ }
}
- //print_line("update captures for pos: " + p_instance->transform.origin);
-
- for (int i = 0; i < 12; i++)
- new (&p_instance->lightmap_capture_data.ptrw()[i]) Color;
-
- //this could use some sort of blending..
- for (List<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) {
- const Vector<RasterizerStorage::LightmapCaptureOctree> *octree = RSG::storage->lightmap_capture_get_octree_ptr(E->get()->base);
- //print_line("octree size: " + itos(octree->size()));
- if (octree->size() == 0)
- continue;
- Transform to_cell_xform = RSG::storage->lightmap_capture_get_octree_cell_transform(E->get()->base);
- int cell_subdiv = RSG::storage->lightmap_capture_get_octree_cell_subdiv(E->get()->base);
- to_cell_xform = to_cell_xform * E->get()->transform.affine_inverse();
-
- const RasterizerStorage::LightmapCaptureOctree *octree_r = octree->ptr();
-
- Vector3 pos = to_cell_xform.xform(p_instance->transform.origin);
-
- for (int i = 0; i < 12; i++) {
-
- Vector3 dir = to_cell_xform.basis.xform(cone_traces[i]).normalized();
- Color capture = _light_capture_voxel_cone_trace(octree_r, pos, dir, cone_aperture, cell_subdiv);
- p_instance->lightmap_capture_data.write[i] += capture;
+ if (accum_blend > 0.0) {
+ for (int j = 0; j < 9; j++) {
+ instance_sh[j] = accum_sh[j] / accum_blend;
+ if (first_set) {
+ p_instance->lightmap_sh.write[j] = instance_sh[j];
+ }
}
}
}
bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario) {
-
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
Transform light_transform = p_instance->transform;
@@ -1462,9 +1241,7 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
bool animated_material_found = false;
switch (RSG::storage->light_get_type(p_instance->base)) {
-
case RS::LIGHT_DIRECTIONAL: {
-
real_t max_distance = p_cam_projection.get_z_far();
real_t shadow_max = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE);
if (shadow_max > 0 && !p_cam_orthogonal) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera
@@ -1489,7 +1266,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
real_t z_min = 1e20;
for (int i = 0; i < cull_count; i++) {
-
Instance *instance = instance_shadow_cull_result[i];
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
continue;
@@ -1523,9 +1299,15 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
int splits = 0;
switch (RSG::storage->light_directional_get_shadow_mode(p_instance->base)) {
- case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: splits = 1; break;
- case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: splits = 2; break;
- case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: splits = 4; break;
+ case RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL:
+ splits = 1;
+ break;
+ case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
+ splits = 2;
+ break;
+ case RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:
+ splits = 4;
+ break;
}
real_t distances[5];
@@ -1546,7 +1328,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
real_t min_distance_bias_scale = pancake_size > 0 ? distances[1] / 10.0 : 0;
for (int i = 0; i < splits; i++) {
-
RENDER_TIMESTAMP("Culling Directional Light split" + itos(i));
// setup a camera matrix for that range!
@@ -1555,12 +1336,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
real_t aspect = p_cam_projection.get_aspect();
if (p_cam_orthogonal) {
-
Vector2 vp_he = p_cam_projection.get_viewport_half_extents();
camera_matrix.set_orthogonal(vp_he.y * 2.0, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
} else {
-
real_t fov = p_cam_projection.get_fov(); //this is actually yfov, because set aspect tries to keep it
camera_matrix.set_perspective(fov, aspect, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
}
@@ -1597,25 +1376,30 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
//used for culling
for (int j = 0; j < 8; j++) {
-
real_t d_x = x_vec.dot(endpoints[j]);
real_t d_y = y_vec.dot(endpoints[j]);
real_t d_z = z_vec.dot(endpoints[j]);
- if (j == 0 || d_x < x_min)
+ if (j == 0 || d_x < x_min) {
x_min = d_x;
- if (j == 0 || d_x > x_max)
+ }
+ if (j == 0 || d_x > x_max) {
x_max = d_x;
+ }
- if (j == 0 || d_y < y_min)
+ if (j == 0 || d_y < y_min) {
y_min = d_y;
- if (j == 0 || d_y > y_max)
+ }
+ if (j == 0 || d_y > y_max) {
y_max = d_y;
+ }
- if (j == 0 || d_z < z_min)
+ if (j == 0 || d_z < z_min) {
z_min = d_z;
- if (j == 0 || d_z > z_max)
+ }
+ if (j == 0 || d_z > z_max) {
z_max = d_z;
+ }
}
real_t radius = 0;
@@ -1626,7 +1410,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
//camera viewport stuff
for (int j = 0; j < 8; j++) {
-
center += endpoints[j];
}
center /= 8.0;
@@ -1634,10 +1417,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
//center=x_vec*(x_max-x_min)*0.5 + y_vec*(y_max-y_min)*0.5 + z_vec*(z_max-z_min)*0.5;
for (int j = 0; j < 8; j++) {
-
real_t d = center.distance_to(endpoints[j]);
- if (d > radius)
+ if (d > radius) {
radius = d;
+ }
}
radius *= texture_size / (texture_size - 2.0); //add a texel by each side
@@ -1651,11 +1434,9 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
z_min_cam = z_vec.dot(center) - radius;
{
-
float soft_shadow_angle = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SIZE);
if (soft_shadow_angle > 0.0 && pancake_size > 0.0) {
-
float z_range = (z_vec.dot(center) + radius + pancake_size) - z_min_cam;
soft_shadow_expand = Math::tan(Math::deg2rad(soft_shadow_angle)) * z_range;
@@ -1708,7 +1489,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
real_t cull_max = 0;
for (int j = 0; j < cull_count; j++) {
-
real_t min, max;
Instance *instance = instance_shadow_cull_result[j];
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
@@ -1735,14 +1515,12 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
}
if (aspect != 1.0) {
-
// if the aspect is different, then the radius will become larger.
// if this happens, then bias needs to be adjusted too, as depth will increase
// to do this, compare the depth of one that would have resulted from a square frustum
CameraMatrix camera_matrix_square;
if (p_cam_orthogonal) {
-
Vector2 vp_he = camera_matrix.get_viewport_half_extents();
if (p_cam_vaspect) {
camera_matrix_square.set_orthogonal(vp_he.x * 2.0, 1.0, distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], true);
@@ -1756,10 +1534,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
} else {
camera_matrix_square.set_frustum(vp_he.y * 2.0, 1.0, Vector2(), distances[(i == 0 || !overlap) ? i : i - 1], distances[i + 1], false);
}
-
- if (i == 0) {
- //print_line("prev he: " + vp_he + " new he: " + camera_matrix_square.get_viewport_half_extents());
- }
}
Vector3 endpoints_square[8]; // frustum plane endpoints
@@ -1769,13 +1543,13 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
real_t z_max_square = 0;
for (int j = 0; j < 8; j++) {
-
center_square += endpoints_square[j];
real_t d_z = z_vec.dot(endpoints_square[j]);
- if (j == 0 || d_z > z_max_square)
+ if (j == 0 || d_z > z_max_square) {
z_max_square = d_z;
+ }
}
if (cull_max > z_max_square) {
@@ -1787,10 +1561,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
real_t radius_square = 0;
for (int j = 0; j < 8; j++) {
-
real_t d = center_square.distance_to(endpoints_square[j]);
- if (d > radius_square)
+ if (d > radius_square) {
radius_square = d;
+ }
}
radius_square *= texture_size / (texture_size - 2.0); //add a texel by each side
@@ -1809,7 +1583,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
}
{
-
CameraMatrix ortho_camera;
real_t half_x = (x_max_cam - x_min_cam) * 0.5;
real_t half_y = (y_max_cam - y_min_cam) * 0.5;
@@ -1836,13 +1609,10 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
} break;
case RS::LIGHT_OMNI: {
-
RS::LightOmniShadowMode shadow_mode = RSG::storage->light_omni_get_shadow_mode(p_instance->base);
if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !RSG::scene_render->light_instances_can_render_shadow_cube()) {
-
for (int i = 0; i < 2; i++) {
-
//using this one ensures that raster deferred will have it
RENDER_TIMESTAMP("Culling Shadow Paraboloid" + itos(i));
@@ -1850,18 +1620,18 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
real_t z = i == 0 ? -1 : 1;
Vector<Plane> planes;
- planes.resize(5);
+ planes.resize(6);
planes.write[0] = light_transform.xform(Plane(Vector3(0, 0, z), radius));
planes.write[1] = light_transform.xform(Plane(Vector3(1, 0, z).normalized(), radius));
planes.write[2] = light_transform.xform(Plane(Vector3(-1, 0, z).normalized(), radius));
planes.write[3] = light_transform.xform(Plane(Vector3(0, 1, z).normalized(), radius));
planes.write[4] = light_transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
+ planes.write[5] = light_transform.xform(Plane(Vector3(0, 0, -z), 0));
int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, RS::INSTANCE_GEOMETRY_MASK);
Plane near_plane(light_transform.origin, light_transform.basis.get_axis(2) * z);
for (int j = 0; j < cull_count; j++) {
-
Instance *instance = instance_shadow_cull_result[j];
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
cull_count--;
@@ -1887,7 +1657,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
cm.set_perspective(90, 1, 0.01, radius);
for (int i = 0; i < 6; i++) {
-
RENDER_TIMESTAMP("Culling Shadow Cube side" + itos(i));
//using this one ensures that raster deferred will have it
@@ -1916,7 +1685,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
Plane near_plane(xform.origin, -xform.basis.get_axis(2));
for (int j = 0; j < cull_count; j++) {
-
Instance *instance = instance_shadow_cull_result[j];
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
cull_count--;
@@ -1941,7 +1709,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
} break;
case RS::LIGHT_SPOT: {
-
RENDER_TIMESTAMP("Culling Spot Light");
real_t radius = RSG::storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE);
@@ -1955,7 +1722,6 @@ bool RenderingServerScene::_light_instance_update_shadow(Instance *p_instance, c
Plane near_plane(light_transform.origin, -light_transform.basis.get_axis(2));
for (int j = 0; j < cull_count; j++) {
-
Instance *instance = instance_shadow_cull_result[j];
if (!instance->visible || !((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) || !static_cast<InstanceGeometryData *>(instance->base_data)->can_cast_shadows) {
cull_count--;
@@ -1992,7 +1758,6 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID
switch (camera->type) {
case Camera::ORTHOGONAL: {
-
camera_matrix.set_orthogonal(
camera->size,
p_viewport_size.width / (float)p_viewport_size.height,
@@ -2002,7 +1767,6 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID
ortho = true;
} break;
case Camera::PERSPECTIVE: {
-
camera_matrix.set_perspective(
camera->fov,
p_viewport_size.width / (float)p_viewport_size.height,
@@ -2013,7 +1777,6 @@ void RenderingServerScene::render_camera(RID p_render_buffers, RID p_camera, RID
} break;
case Camera::FRUSTUM: {
-
camera_matrix.set_frustum(
camera->size,
p_viewport_size.width / (float)p_viewport_size.height,
@@ -2140,6 +1903,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
reflection_probe_cull_count = 0;
decal_cull_count = 0;
gi_probe_cull_count = 0;
+ lightmap_cull_count = 0;
//light_samplers_culled=0;
@@ -2154,9 +1918,10 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
//removed, will replace with culling
/* STEP 4 - REMOVE FURTHER CULLED OBJECTS, ADD LIGHTS */
+ uint64_t frame_number = RSG::rasterizer->get_frame_number();
+ float lightmap_probe_update_speed = RSG::storage->lightmap_get_probe_capture_update_speed() * RSG::rasterizer->get_frame_delta_time();
for (int i = 0; i < instance_cull_count; i++) {
-
Instance *ins = instance_cull_result[i];
bool keep = false;
@@ -2164,9 +1929,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
if ((camera_layer_mask & ins->layer_mask) == 0) {
//failure
} else if (ins->base_type == RS::INSTANCE_LIGHT && ins->visible) {
-
if (light_cull_count < MAX_LIGHTS_CULLED) {
-
InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data);
if (!light->geometries.empty()) {
@@ -2181,9 +1944,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
}
}
} else if (ins->base_type == RS::INSTANCE_REFLECTION_PROBE && ins->visible) {
-
if (reflection_probe_cull_count < MAX_REFLECTION_PROBES_CULLED) {
-
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(ins->base_data);
if (p_reflection_probe != reflection_probe->instance) {
@@ -2209,9 +1970,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
}
}
} else if (ins->base_type == RS::INSTANCE_DECAL && ins->visible) {
-
if (decal_cull_count < MAX_DECALS_CULLED) {
-
InstanceDecalData *decal = static_cast<InstanceDecalData *>(ins->base_data);
if (!decal->geometries.empty()) {
@@ -2222,7 +1981,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
}
} else if (ins->base_type == RS::INSTANCE_GI_PROBE && ins->visible) {
-
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(ins->base_data);
if (!gi_probe->update_element.in_list()) {
gi_probe_update_list.add(&gi_probe->update_element);
@@ -2232,9 +1990,13 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
gi_probe_instance_cull_result[gi_probe_cull_count] = gi_probe->probe_instance;
gi_probe_cull_count++;
}
+ } else if (ins->base_type == RS::INSTANCE_LIGHTMAP && ins->visible) {
+ if (lightmap_cull_count < MAX_LIGHTMAPS_CULLED) {
+ lightmap_cull_result[lightmap_cull_count] = ins;
+ lightmap_cull_count++;
+ }
} else if (((1 << ins->base_type) & RS::INSTANCE_GEOMETRY_MASK) && ins->visible && ins->cast_shadows != RS::SHADOW_CASTING_SETTING_SHADOWS_ONLY) {
-
keep = true;
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(ins->base_data);
@@ -2261,7 +2023,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
ins->light_instances.resize(geom->lighting.size());
for (List<Instance *>::Element *E = geom->lighting.front(); E; E = E->next()) {
-
InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
ins->light_instances.write[l++] = light->instance;
@@ -2276,7 +2037,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
ins->reflection_probe_instances.resize(geom->reflection_probes.size());
for (List<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) {
-
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data);
ins->reflection_probe_instances.write[l++] = reflection_probe->instance;
@@ -2291,7 +2051,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
ins->gi_probe_instances.resize(geom->gi_probes.size());
for (List<Instance *>::Element *E = geom->gi_probes.front(); E; E = E->next()) {
-
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data);
ins->gi_probe_instances.write[l++] = gi_probe->probe_instance;
@@ -2300,6 +2059,14 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
geom->gi_probes_dirty = false;
}
+ if (ins->last_frame_pass != frame_number && !ins->lightmap_target_sh.empty() && !ins->lightmap_sh.empty()) {
+ Color *sh = ins->lightmap_sh.ptrw();
+ const Color *target_sh = ins->lightmap_target_sh.ptr();
+ for (uint32_t j = 0; j < 9; j++) {
+ sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed));
+ }
+ }
+
ins->depth = near_plane.distance_to(ins->transform.origin);
ins->depth_layer = CLAMP(int(ins->depth * 16 / z_far), 0, 15);
}
@@ -2311,9 +2078,9 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
i--;
ins->last_render_pass = 0; // make invalid
} else {
-
ins->last_render_pass = render_pass;
}
+ ins->last_frame_pass = frame_number;
}
/* STEP 5 - PROCESS LIGHTS */
@@ -2323,18 +2090,17 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
// directional lights
{
-
Instance **lights_with_shadow = (Instance **)alloca(sizeof(Instance *) * scenario->directional_lights.size());
int directional_shadow_count = 0;
for (List<Instance *>::Element *E = scenario->directional_lights.front(); E; E = E->next()) {
-
if (light_cull_count + directional_light_count >= MAX_LIGHTS_CULLED) {
break;
}
- if (!E->get()->visible)
+ if (!E->get()->visible) {
continue;
+ }
InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
@@ -2352,7 +2118,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
RSG::scene_render->set_directional_shadow_count(directional_shadow_count);
for (int i = 0; i < directional_shadow_count; i++) {
-
RENDER_TIMESTAMP(">Rendering Directional Light " + itos(i));
_light_instance_update_shadow(lights_with_shadow[i], p_cam_transform, p_cam_projection, p_cam_orthogonal, p_cam_vaspect, p_shadow_atlas, scenario);
@@ -2366,11 +2131,11 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
//SortArray<Instance*,_InstanceLightsort> sorter;
//sorter.sort(light_cull_result,light_cull_count);
for (int i = 0; i < light_cull_count; i++) {
-
Instance *ins = light_cull_result[i];
- if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base))
+ if (!p_shadow_atlas.is_valid() || !RSG::storage->light_has_shadow(ins->base)) {
continue;
+ }
InstanceLightData *light = static_cast<InstanceLightData *>(ins->base_data);
@@ -2386,9 +2151,7 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
Vector2 vp_half_extents = p_cam_projection.get_viewport_half_extents();
switch (RSG::storage->light_get_type(ins->base)) {
-
case RS::LIGHT_OMNI: {
-
float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
//get two points parallel to near plane
@@ -2412,7 +2175,6 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
coverage = screen_diameter / (vp_half_extents.x + vp_half_extents.y);
} break;
case RS::LIGHT_SPOT: {
-
float radius = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_RANGE);
float angle = RSG::storage->light_get_param(ins->base, RS::LIGHT_PARAM_SPOT_ANGLE);
@@ -2465,18 +2227,18 @@ void RenderingServerScene::_prepare_scene(const Transform p_cam_transform, const
}
void RenderingServerScene::_render_scene(RID p_render_buffers, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, RID p_force_environment, RID p_force_camera_effects, RID p_scenario, RID p_shadow_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
-
Scenario *scenario = scenario_owner.getornull(p_scenario);
/* ENVIRONMENT */
RID environment;
- if (p_force_environment.is_valid()) //camera has more environment priority
+ if (p_force_environment.is_valid()) { //camera has more environment priority
environment = p_force_environment;
- else if (scenario->environment.is_valid())
+ } else if (scenario->environment.is_valid()) {
environment = scenario->environment;
- else
+ } else {
environment = scenario->fallback_environment;
+ }
RID camera_effects;
if (p_force_camera_effects.is_valid()) {
@@ -2487,27 +2249,26 @@ void RenderingServerScene::_render_scene(RID p_render_buffers, const Transform p
/* PROCESS GEOMETRY AND DRAW SCENE */
RENDER_TIMESTAMP("Render Scene ");
- RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, decal_instance_cull_result, decal_cull_count, environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass);
+ RSG::scene_render->render_scene(p_render_buffers, p_cam_transform, p_cam_projection, p_cam_orthogonal, (RasterizerScene::InstanceBase **)instance_cull_result, instance_cull_count, light_instance_cull_result, light_cull_count + directional_light_count, reflection_probe_instance_cull_result, reflection_probe_cull_count, gi_probe_instance_cull_result, gi_probe_cull_count, decal_instance_cull_result, decal_cull_count, (RasterizerScene::InstanceBase **)lightmap_cull_result, lightmap_cull_count, environment, camera_effects, p_shadow_atlas, p_reflection_probe.is_valid() ? RID() : scenario->reflection_atlas, p_reflection_probe, p_reflection_probe_pass);
}
void RenderingServerScene::render_empty_scene(RID p_render_buffers, RID p_scenario, RID p_shadow_atlas) {
-
#ifndef _3D_DISABLED
Scenario *scenario = scenario_owner.getornull(p_scenario);
RID environment;
- if (scenario->environment.is_valid())
+ if (scenario->environment.is_valid()) {
environment = scenario->environment;
- else
+ } else {
environment = scenario->fallback_environment;
+ }
RENDER_TIMESTAMP("Render Empty Scene ");
- RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0);
+ RSG::scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, nullptr, 0, environment, RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0);
#endif
}
bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, int p_step) {
-
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
Scenario *scenario = p_instance->scenario;
ERR_FAIL_COND_V(!scenario, true);
@@ -2515,14 +2276,12 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i
RenderingServerRaster::redraw_request(); //update, so it updates in editor
if (p_step == 0) {
-
if (!RSG::scene_render->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) {
return true; //all full
}
}
if (p_step >= 0 && p_step < 6) {
-
static const Vector3 view_normals[6] = {
Vector3(+1, 0, 0),
Vector3(-1, 0, 0),
@@ -2562,7 +2321,6 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i
bool use_shadows = RSG::storage->reflection_probe_renders_shadows(p_instance->base);
if (use_shadows) {
-
shadow_atlas = scenario->reflection_probe_shadow_atlas;
}
@@ -2580,7 +2338,6 @@ bool RenderingServerScene::_render_reflection_probe_step(Instance *p_instance, i
}
void RenderingServerScene::render_probes() {
-
/* REFLECTION PROBES */
SelfList<InstanceReflectionProbeData> *ref_probe = reflection_probe_render_list.first();
@@ -2588,15 +2345,14 @@ void RenderingServerScene::render_probes() {
bool busy = false;
while (ref_probe) {
-
SelfList<InstanceReflectionProbeData> *next = ref_probe->next();
RID base = ref_probe->self()->owner->base;
switch (RSG::storage->reflection_probe_get_update_mode(base)) {
-
case RS::REFLECTION_PROBE_UPDATE_ONCE: {
- if (busy) //already rendering something
+ if (busy) { //already rendering something
break;
+ }
bool done = _render_reflection_probe_step(ref_probe->self()->owner, ref_probe->self()->render_step);
if (done) {
@@ -2608,7 +2364,6 @@ void RenderingServerScene::render_probes() {
busy = true; //do not render another one of this kind
} break;
case RS::REFLECTION_PROBE_UPDATE_ALWAYS: {
-
int step = 0;
bool done = false;
while (!done) {
@@ -2632,7 +2387,6 @@ void RenderingServerScene::render_probes() {
}
while (gi_probe) {
-
SelfList<InstanceGIProbeData> *next = gi_probe->next();
InstanceGIProbeData *probe = gi_probe->self();
@@ -2643,7 +2397,6 @@ void RenderingServerScene::render_probes() {
bool cache_dirty = false;
int cache_count = 0;
{
-
int light_cache_size = probe->light_cache.size();
const InstanceGIProbeData::LightCache *caches = probe->light_cache.ptr();
const RID *instance_caches = probe->light_instances.ptr();
@@ -2660,7 +2413,6 @@ void RenderingServerScene::render_probes() {
} else if (idx >= light_cache_size) {
cache_dirty = true;
} else {
-
const InstanceGIProbeData::LightCache *cache = &caches[idx];
if (
@@ -2683,7 +2435,6 @@ void RenderingServerScene::render_probes() {
}
for (List<Instance *>::Element *E = probe->owner->scenario->directional_lights.front(); E; E = E->next()) {
-
Instance *instance = E->get();
InstanceLightData *instance_light = (InstanceLightData *)instance->base_data;
if (!instance->visible) {
@@ -2694,7 +2445,6 @@ void RenderingServerScene::render_probes() {
} else if (idx >= light_cache_size) {
cache_dirty = true;
} else {
-
const InstanceGIProbeData::LightCache *cache = &caches[idx];
if (
@@ -2801,7 +2551,6 @@ void RenderingServerScene::render_probes() {
ins->gi_probe_instances.resize(geom->gi_probes.size());
for (List<Instance *>::Element *F = geom->gi_probes.front(); F; F = F->next()) {
-
InstanceGIProbeData *gi_probe2 = static_cast<InstanceGIProbeData *>(F->get()->base_data);
ins->gi_probe_instances.write[l++] = gi_probe2->probe_instance;
@@ -2823,7 +2572,6 @@ void RenderingServerScene::render_probes() {
}
void RenderingServerScene::_update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material) {
-
List<RasterizerStorage::InstanceShaderParam> plist;
RSG::storage->material_get_instance_shader_parameters(p_material, &plist);
for (List<RasterizerStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) {
@@ -2852,13 +2600,11 @@ void RenderingServerScene::_update_instance_shader_parameters_from_material(Map<
}
void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
-
if (p_instance->update_aabb) {
_update_instance_aabb(p_instance);
}
if (p_instance->update_dependencies) {
-
p_instance->instance_increase_version();
if (p_instance->base.is_valid()) {
@@ -2885,7 +2631,6 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
}
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
-
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
bool can_cast_shadows = true;
@@ -2903,7 +2648,6 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
is_animated = RSG::storage->material_is_animated(p_instance->material_override);
_update_instance_shader_parameters_from_material(isparams, p_instance->instance_shader_parameters, p_instance->material_override);
} else {
-
if (p_instance->base_type == RS::INSTANCE_MESH) {
RID mesh = p_instance->base;
@@ -2911,13 +2655,11 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
bool cast_shadows = false;
for (int i = 0; i < p_instance->materials.size(); i++) {
-
RID mat = p_instance->materials[i].is_valid() ? p_instance->materials[i] : RSG::storage->mesh_surface_get_material(mesh, i);
if (!mat.is_valid()) {
cast_shadows = true;
} else {
-
if (RSG::storage->material_casts_shadows(mat)) {
cast_shadows = true;
}
@@ -2940,19 +2682,16 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
} else if (p_instance->base_type == RS::INSTANCE_MULTIMESH) {
RID mesh = RSG::storage->multimesh_get_mesh(p_instance->base);
if (mesh.is_valid()) {
-
bool cast_shadows = false;
int sc = RSG::storage->mesh_get_surface_count(mesh);
for (int i = 0; i < sc; i++) {
-
RID mat = RSG::storage->mesh_surface_get_material(mesh, i);
if (!mat.is_valid()) {
cast_shadows = true;
} else {
-
if (RSG::storage->material_casts_shadows(mat)) {
cast_shadows = true;
}
@@ -2973,7 +2712,6 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
RSG::storage->base_update_dependency(mesh, p_instance);
}
} else if (p_instance->base_type == RS::INSTANCE_IMMEDIATE) {
-
RID mat = RSG::storage->immediate_get_material(p_instance->base);
if (!(!mat.is_valid() || RSG::storage->material_casts_shadows(mat))) {
@@ -2993,26 +2731,23 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
}
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
-
bool cast_shadows = false;
int dp = RSG::storage->particles_get_draw_passes(p_instance->base);
for (int i = 0; i < dp; i++) {
-
RID mesh = RSG::storage->particles_get_draw_pass_mesh(p_instance->base, i);
- if (!mesh.is_valid())
+ if (!mesh.is_valid()) {
continue;
+ }
int sc = RSG::storage->mesh_get_surface_count(mesh);
for (int j = 0; j < sc; j++) {
-
RID mat = RSG::storage->mesh_surface_get_material(mesh, j);
if (!mat.is_valid()) {
cast_shadows = true;
} else {
-
if (RSG::storage->material_casts_shadows(mat)) {
cast_shadows = true;
}
@@ -3079,26 +2814,21 @@ void RenderingServerScene::_update_dirty_instance(Instance *p_instance) {
}
void RenderingServerScene::update_dirty_instances() {
-
RSG::storage->update_dirty_resources();
while (_instance_update_list.first()) {
-
_update_dirty_instance(_instance_update_list.first()->self());
}
}
bool RenderingServerScene::free(RID p_rid) {
-
if (camera_owner.owns(p_rid)) {
-
Camera *camera = camera_owner.getornull(p_rid);
camera_owner.free(p_rid);
memdelete(camera);
} else if (scenario_owner.owns(p_rid)) {
-
Scenario *scenario = scenario_owner.getornull(p_rid);
while (scenario->instances.first()) {
@@ -3116,7 +2846,7 @@ bool RenderingServerScene::free(RID p_rid) {
Instance *instance = instance_owner.getornull(p_rid);
- instance_set_use_lightmap(p_rid, RID(), RID());
+ instance_geometry_set_lightmap(p_rid, RID(), Rect2(), 0);
instance_set_scenario(p_rid, RID());
instance_set_base(p_rid, RID());
instance_geometry_set_material_override(p_rid, RID());
@@ -3137,10 +2867,13 @@ bool RenderingServerScene::free(RID p_rid) {
return true;
}
+TypedArray<Image> RenderingServerScene::bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) {
+ return RSG::scene_render->bake_render_uv2(p_base, p_material_overrides, p_image_size);
+}
+
RenderingServerScene *RenderingServerScene::singleton = nullptr;
RenderingServerScene::RenderingServerScene() {
-
render_pass = 1;
singleton = this;
}
diff --git a/servers/rendering/rendering_server_scene.h b/servers/rendering/rendering_server_scene.h
index db2fbd6707..f59028603f 100644
--- a/servers/rendering/rendering_server_scene.h
+++ b/servers/rendering/rendering_server_scene.h
@@ -51,6 +51,7 @@ public:
MAX_DECALS_CULLED = 4096,
MAX_GI_PROBES_CULLED = 4096,
MAX_ROOM_CULL = 32,
+ MAX_LIGHTMAPS_CULLED = 4096,
MAX_EXTERIOR_PORTALS = 128,
};
@@ -61,7 +62,6 @@ public:
/* CAMERA API */
struct Camera {
-
enum Type {
PERSPECTIVE,
ORTHOGONAL,
@@ -80,9 +80,8 @@ public:
Transform transform;
Camera() {
-
visible_layers = 0xFFFFFFFF;
- fov = 70;
+ fov = 75;
type = PERSPECTIVE;
znear = 0.05;
zfar = 100;
@@ -109,7 +108,6 @@ public:
struct Instance;
struct Scenario {
-
RS::ScenarioDebugMode debug;
RID self;
@@ -143,12 +141,10 @@ public:
/* INSTANCING API */
struct InstanceBaseData {
-
virtual ~InstanceBaseData() {}
};
struct Instance : RasterizerScene::InstanceBase {
-
RID self;
//scenario stuff
OctreeElementID octree_id;
@@ -171,6 +167,8 @@ public:
float lod_end_hysteresis;
RID lod_instance;
+ Vector<Color> lightmap_target_sh; //target is used for incrementally changing the SH over time, this avoids pops in some corner cases and when going interior <-> exterior
+
uint64_t last_render_pass;
uint64_t last_frame_pass;
@@ -195,7 +193,6 @@ public:
Instance() :
scenario_item(this),
update_item(this) {
-
octree_id = 0;
scenario = nullptr;
@@ -220,11 +217,12 @@ public:
}
~Instance() {
-
- if (base_data)
+ if (base_data) {
memdelete(base_data);
- if (custom_aabb)
+ }
+ if (custom_aabb) {
memdelete(custom_aabb);
+ }
}
};
@@ -232,7 +230,6 @@ public:
void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false);
struct InstanceGeometryData : public InstanceBaseData {
-
List<Instance *> lighting;
bool lighting_dirty;
bool can_cast_shadows;
@@ -250,7 +247,6 @@ public:
List<Instance *> lightmap_captures;
InstanceGeometryData() {
-
lighting_dirty = false;
reflection_dirty = true;
can_cast_shadows = true;
@@ -261,7 +257,6 @@ public:
};
struct InstanceReflectionProbeData : public InstanceBaseData {
-
Instance *owner;
struct PairInfo {
@@ -278,14 +273,12 @@ public:
InstanceReflectionProbeData() :
update_list(this) {
-
reflection_dirty = true;
render_step = -1;
}
};
struct InstanceDecalData : public InstanceBaseData {
-
Instance *owner;
RID instance;
@@ -302,7 +295,6 @@ public:
SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list;
struct InstanceLightData : public InstanceBaseData {
-
struct PairInfo {
List<Instance *>::Element *L; //light iterator in geometry
Instance *geometry;
@@ -319,7 +311,6 @@ public:
Instance *baked_light;
InstanceLightData() {
-
shadow_dirty = true;
D = nullptr;
last_version = 0;
@@ -328,7 +319,6 @@ public:
};
struct InstanceGIProbeData : public InstanceBaseData {
-
Instance *owner;
struct PairInfo {
@@ -342,7 +332,6 @@ public:
Set<Instance *> lights;
struct LightCache {
-
RS::LightType type;
Transform transform;
Color color;
@@ -374,8 +363,7 @@ public:
SelfList<InstanceGIProbeData>::List gi_probe_update_list;
- struct InstanceLightmapCaptureData : public InstanceBaseData {
-
+ struct InstanceLightmapData : public InstanceBaseData {
struct PairInfo {
List<Instance *>::Element *L; //iterator in geometry
Instance *geometry;
@@ -384,7 +372,7 @@ public:
Set<Instance *> users;
- InstanceLightmapCaptureData() {
+ InstanceLightmapData() {
}
};
@@ -401,6 +389,8 @@ public:
int decal_cull_count;
RID gi_probe_instance_cull_result[MAX_GI_PROBES_CULLED];
int gi_probe_cull_count;
+ Instance *lightmap_cull_result[MAX_LIGHTS_CULLED];
+ int lightmap_cull_count;
RID_PtrOwner<Instance> instance_owner;
@@ -414,7 +404,6 @@ public:
virtual void instance_set_blend_shape_weight(RID p_instance, int p_shape, float p_weight);
virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material);
virtual void instance_set_visible(RID p_instance, bool p_visible);
- virtual void instance_set_use_lightmap(RID p_instance, RID p_lightmap_instance, RID p_lightmap);
virtual void instance_set_custom_aabb(RID p_instance, AABB p_aabb);
@@ -434,6 +423,7 @@ public:
virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin);
virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance);
+ virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index);
void _update_instance_shader_parameters_from_material(Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RasterizerScene::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material);
@@ -460,6 +450,8 @@ public:
void render_probes();
+ TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size);
+
bool free(RID p_rid);
RenderingServerScene();
diff --git a/servers/rendering/rendering_server_viewport.cpp b/servers/rendering/rendering_server_viewport.cpp
index 6fb8f6ca63..48be6ca13b 100644
--- a/servers/rendering/rendering_server_viewport.cpp
+++ b/servers/rendering/rendering_server_viewport.cpp
@@ -36,7 +36,6 @@
#include "rendering_server_scene.h"
static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_viewport, RenderingServerCanvas::Canvas *p_canvas, RenderingServerViewport::Viewport::CanvasData *p_canvas_data, const Vector2 &p_vp_size) {
-
Transform2D xf = p_viewport->global_transform;
float scale = 1.0;
@@ -63,7 +62,6 @@ static Transform2D _canvas_get_transform(RenderingServerViewport::Viewport *p_vi
}
void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p_eye) {
-
RENDER_TIMESTAMP(">Begin Rendering 3D Scene");
Ref<XRInterface> xr_interface;
@@ -80,7 +78,6 @@ void RenderingServerViewport::_draw_3d(Viewport *p_viewport, XRInterface::Eyes p
}
void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::Eyes p_eye) {
-
if (p_viewport->measure_render_time) {
String rt_id = "vp_begin_" + itos(p_viewport->self.get_id());
RSG::storage->capture_timestamp(rt_id);
@@ -95,7 +92,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
Color bgcolor = RSG::storage->get_default_clear_color();
if (!p_viewport->hide_canvas && !p_viewport->disable_environment && RSG::scene->scenario_owner.owns(p_viewport->scenario)) {
-
RenderingServerScene::Scenario *scenario = RSG::scene->scenario_owner.getornull(p_viewport->scenario);
ERR_FAIL_COND(!scenario);
if (RSG::scene_render->is_environment(scenario->environment)) {
@@ -143,7 +139,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
RENDER_TIMESTAMP("Cull Canvas Lights");
for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
-
RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas);
Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size);
@@ -151,7 +146,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
//find lights in canvas
for (Set<RasterizerCanvas::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) {
-
RasterizerCanvas::Light *cl = F->get();
if (cl->enabled && cl->texture.is_valid()) {
//not super efficient..
@@ -163,7 +157,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
cl->xform_cache = xf * cl->xform;
if (clip_rect.intersects_transformed(cl->xform_cache, cl->rect_cache)) {
-
cl->filter_next_ptr = lights;
lights = cl;
// cl->texture_cache = nullptr;
@@ -173,7 +166,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
cl->light_shader_xform = cl->xform * scale;
//cl->light_shader_pos = cl->xform_cache[2];
if (cl->use_shadow) {
-
cl->shadows_next_ptr = lights_with_shadow;
if (lights_with_shadow == nullptr) {
shadow_rect = cl->xform_cache.xform(cl->rect_cache);
@@ -209,17 +201,15 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
//make list of occluders
for (Map<RID, Viewport::CanvasData>::Element *E = p_viewport->canvas_map.front(); E; E = E->next()) {
-
RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get().canvas);
Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E->get(), clip_rect.size);
for (Set<RasterizerCanvas::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) {
-
- if (!F->get()->enabled)
+ if (!F->get()->enabled) {
continue;
+ }
F->get()->xform_cache = xf * F->get()->xform;
if (shadow_rect.intersects_transformed(F->get()->xform_cache, F->get()->aabb_cache)) {
-
F->get()->next = occluders;
occluders = F->get();
}
@@ -229,7 +219,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
RasterizerCanvas::Light *light = lights_with_shadow;
while (light) {
-
RENDER_TIMESTAMP("Render Shadow");
RSG::canvas_render->light_update_shadow(light->light_internal, light->xform_cache.affine_inverse(), light->item_shadow_mask, light->radius_cache / 1000.0, light->radius_cache * 1.1, occluders);
@@ -250,7 +239,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
}
for (Map<Viewport::CanvasKey, Viewport::CanvasData *>::Element *E = canvas_map.front(); E; E = E->next()) {
-
RenderingServerCanvas::Canvas *canvas = static_cast<RenderingServerCanvas::Canvas *>(E->get()->canvas);
Transform2D xform = _canvas_get_transform(p_viewport, canvas, E->get(), clip_rect.size);
@@ -304,7 +292,6 @@ void RenderingServerViewport::_draw_viewport(Viewport *p_viewport, XRInterface::
}
void RenderingServerViewport::draw_viewports() {
-
timestamp_vp_map.clear();
// get our xr interface in case we need it
@@ -335,8 +322,9 @@ void RenderingServerViewport::draw_viewports() {
Viewport *vp = active_viewports[i];
- if (vp->update_mode == RS::VIEWPORT_UPDATE_DISABLED)
+ if (vp->update_mode == RS::VIEWPORT_UPDATE_DISABLED) {
continue;
+ }
if (!vp->render_target.is_valid()) {
continue;
@@ -368,7 +356,6 @@ void RenderingServerViewport::draw_viewports() {
}
for (int i = 0; i < active_viewports.size(); i++) {
-
Viewport *vp = active_viewports[i];
if (vp->last_pass != draw_viewports_pass) {
@@ -470,7 +457,6 @@ void RenderingServerViewport::draw_viewports() {
}
RID RenderingServerViewport::viewport_create() {
-
Viewport *viewport = memnew(Viewport);
RID rid = viewport_owner.make_rid(viewport);
@@ -493,7 +479,6 @@ void RenderingServerViewport::viewport_set_use_xr(RID p_viewport, bool p_use_xr)
}
void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int p_height) {
-
ERR_FAIL_COND(p_width < 0 && p_height < 0);
Viewport *viewport = viewport_owner.getornull(p_viewport);
@@ -512,7 +497,6 @@ void RenderingServerViewport::viewport_set_size(RID p_viewport, int p_width, int
}
void RenderingServerViewport::viewport_set_active(RID p_viewport, bool p_active) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -525,7 +509,6 @@ void RenderingServerViewport::viewport_set_active(RID p_viewport, bool p_active)
}
void RenderingServerViewport::viewport_set_parent_viewport(RID p_viewport, RID p_parent_viewport) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -533,7 +516,6 @@ void RenderingServerViewport::viewport_set_parent_viewport(RID p_viewport, RID p
}
void RenderingServerViewport::viewport_set_clear_mode(RID p_viewport, RS::ViewportClearMode p_clear_mode) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -541,7 +523,6 @@ void RenderingServerViewport::viewport_set_clear_mode(RID p_viewport, RS::Viewpo
}
void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Rect2 &p_rect, DisplayServer::WindowID p_screen) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -549,7 +530,6 @@ void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Re
// If using GLES2 we can optimize this operation by rendering directly to system_fbo
// instead of rendering to fbo and copying to system_fbo after
if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
-
RSG::storage->render_target_set_size(viewport->render_target, p_rect.size.x, p_rect.size.y);
RSG::storage->render_target_set_position(viewport->render_target, p_rect.position.x, p_rect.position.y);
}
@@ -557,10 +537,8 @@ void RenderingServerViewport::viewport_attach_to_screen(RID p_viewport, const Re
viewport->viewport_to_screen_rect = p_rect;
viewport->viewport_to_screen = p_screen;
} else {
-
// if render_direct_to_screen was used, reset size and position
if (RSG::rasterizer->is_low_end() && viewport->viewport_render_direct_to_screen) {
-
RSG::storage->render_target_set_position(viewport->render_target, 0, 0);
RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y);
}
@@ -574,12 +552,12 @@ void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewpor
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
- if (p_enable == viewport->viewport_render_direct_to_screen)
+ if (p_enable == viewport->viewport_render_direct_to_screen) {
return;
+ }
// if disabled, reset render_target size and position
if (!p_enable) {
-
RSG::storage->render_target_set_position(viewport->render_target, 0, 0);
RSG::storage->render_target_set_size(viewport->render_target, viewport->size.x, viewport->size.y);
}
@@ -589,14 +567,12 @@ void RenderingServerViewport::viewport_set_render_direct_to_screen(RID p_viewpor
// if attached to screen already, setup screen size and position, this needs to happen after setting flag to avoid an unnecessary buffer allocation
if (RSG::rasterizer->is_low_end() && viewport->viewport_to_screen_rect != Rect2() && p_enable) {
-
RSG::storage->render_target_set_size(viewport->render_target, viewport->viewport_to_screen_rect.size.x, viewport->viewport_to_screen_rect.size.y);
RSG::storage->render_target_set_position(viewport->render_target, viewport->viewport_to_screen_rect.position.x, viewport->viewport_to_screen_rect.position.y);
}
}
void RenderingServerViewport::viewport_set_update_mode(RID p_viewport, RS::ViewportUpdateMode p_mode) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -604,7 +580,6 @@ void RenderingServerViewport::viewport_set_update_mode(RID p_viewport, RS::Viewp
}
RID RenderingServerViewport::viewport_get_texture(RID p_viewport) const {
-
const Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND_V(!viewport, RID());
@@ -612,21 +587,20 @@ RID RenderingServerViewport::viewport_get_texture(RID p_viewport) const {
}
void RenderingServerViewport::viewport_set_hide_scenario(RID p_viewport, bool p_hide) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->hide_scenario = p_hide;
}
-void RenderingServerViewport::viewport_set_hide_canvas(RID p_viewport, bool p_hide) {
+void RenderingServerViewport::viewport_set_hide_canvas(RID p_viewport, bool p_hide) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->hide_canvas = p_hide;
}
-void RenderingServerViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) {
+void RenderingServerViewport::viewport_set_disable_environment(RID p_viewport, bool p_disable) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -634,21 +608,20 @@ void RenderingServerViewport::viewport_set_disable_environment(RID p_viewport, b
}
void RenderingServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->camera = p_camera;
}
-void RenderingServerViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) {
+void RenderingServerViewport::viewport_set_scenario(RID p_viewport, RID p_scenario) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->scenario = p_scenario;
}
-void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) {
+void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canvas) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -664,7 +637,6 @@ void RenderingServerViewport::viewport_attach_canvas(RID p_viewport, RID p_canva
}
void RenderingServerViewport::viewport_remove_canvas(RID p_viewport, RID p_canvas) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -674,16 +646,16 @@ void RenderingServerViewport::viewport_remove_canvas(RID p_viewport, RID p_canva
viewport->canvas_map.erase(p_canvas);
canvas->viewports.erase(p_viewport);
}
-void RenderingServerViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) {
+void RenderingServerViewport::viewport_set_canvas_transform(RID p_viewport, RID p_canvas, const Transform2D &p_offset) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
ERR_FAIL_COND(!viewport->canvas_map.has(p_canvas));
viewport->canvas_map[p_canvas].transform = p_offset;
}
-void RenderingServerViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) {
+void RenderingServerViewport::viewport_set_transparent_background(RID p_viewport, bool p_enabled) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -692,14 +664,13 @@ void RenderingServerViewport::viewport_set_transparent_background(RID p_viewport
}
void RenderingServerViewport::viewport_set_global_canvas_transform(RID p_viewport, const Transform2D &p_transform) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
viewport->global_transform = p_transform;
}
-void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) {
+void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p_canvas, int p_layer, int p_sublayer) {
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -709,7 +680,6 @@ void RenderingServerViewport::viewport_set_canvas_stacking(RID p_viewport, RID p
}
void RenderingServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int p_size) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -719,7 +689,6 @@ void RenderingServerViewport::viewport_set_shadow_atlas_size(RID p_viewport, int
}
void RenderingServerViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -727,7 +696,6 @@ void RenderingServerViewport::viewport_set_shadow_atlas_quadrant_subdivision(RID
}
void RenderingServerViewport::viewport_set_msaa(RID p_viewport, RS::ViewportMSAA p_msaa) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -754,18 +722,17 @@ void RenderingServerViewport::viewport_set_screen_space_aa(RID p_viewport, RS::V
}
int RenderingServerViewport::viewport_get_render_info(RID p_viewport, RS::ViewportRenderInfo p_info) {
-
ERR_FAIL_INDEX_V(p_info, RS::VIEWPORT_RENDER_INFO_MAX, -1);
Viewport *viewport = viewport_owner.getornull(p_viewport);
- if (!viewport)
+ if (!viewport) {
return 0; //there should be a lock here..
+ }
return viewport->render_info[p_info];
}
void RenderingServerViewport::viewport_set_debug_draw(RID p_viewport, RS::ViewportDebugDraw p_draw) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -773,7 +740,6 @@ void RenderingServerViewport::viewport_set_debug_draw(RID p_viewport, RS::Viewpo
}
void RenderingServerViewport::viewport_set_measure_render_time(RID p_viewport, bool p_enable) {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND(!viewport);
@@ -781,7 +747,6 @@ void RenderingServerViewport::viewport_set_measure_render_time(RID p_viewport, b
}
float RenderingServerViewport::viewport_get_measured_render_time_cpu(RID p_viewport) const {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND_V(!viewport, 0);
@@ -789,7 +754,6 @@ float RenderingServerViewport::viewport_get_measured_render_time_cpu(RID p_viewp
}
float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewport) const {
-
Viewport *viewport = viewport_owner.getornull(p_viewport);
ERR_FAIL_COND_V(!viewport, 0);
@@ -797,9 +761,7 @@ float RenderingServerViewport::viewport_get_measured_render_time_gpu(RID p_viewp
}
bool RenderingServerViewport::free(RID p_rid) {
-
if (viewport_owner.owns(p_rid)) {
-
Viewport *viewport = viewport_owner.getornull(p_rid);
RSG::storage->free(viewport->render_target);
@@ -825,7 +787,6 @@ bool RenderingServerViewport::free(RID p_rid) {
}
void RenderingServerViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time) {
-
RID *vp = timestamp_vp_map.getptr(p_timestamp);
if (!vp) {
return;
diff --git a/servers/rendering/rendering_server_viewport.h b/servers/rendering/rendering_server_viewport.h
index fcba7886c5..0b90646e4f 100644
--- a/servers/rendering/rendering_server_viewport.h
+++ b/servers/rendering/rendering_server_viewport.h
@@ -43,7 +43,6 @@ public:
};
struct Viewport {
-
RID self;
RID parent;
@@ -89,12 +88,12 @@ public:
bool transparent_bg;
struct CanvasKey {
-
int64_t stacking;
RID canvas;
bool operator<(const CanvasKey &p_canvas) const {
- if (stacking == p_canvas.stacking)
+ if (stacking == p_canvas.stacking) {
return canvas < p_canvas.canvas;
+ }
return stacking < p_canvas.stacking;
}
CanvasKey() {
@@ -109,7 +108,6 @@ public:
};
struct CanvasData {
-
CanvasBase *canvas;
Transform2D transform;
int layer;
@@ -154,12 +152,10 @@ public:
struct ViewportSort {
_FORCE_INLINE_ bool operator()(const Viewport *p_left, const Viewport *p_right) const {
-
bool left_to_screen = p_left->viewport_to_screen_rect.size != Size2();
bool right_to_screen = p_right->viewport_to_screen_rect.size != Size2();
if (left_to_screen == right_to_screen) {
-
return p_right->parent == p_left->self;
}
return (right_to_screen ? 0 : 1) < (left_to_screen ? 0 : 1);
diff --git a/servers/rendering/rendering_server_wrap_mt.cpp b/servers/rendering/rendering_server_wrap_mt.cpp
index 4ca13dbef9..9aa6593cbe 100644
--- a/servers/rendering/rendering_server_wrap_mt.cpp
+++ b/servers/rendering/rendering_server_wrap_mt.cpp
@@ -34,32 +34,26 @@
#include "servers/display_server.h"
void RenderingServerWrapMT::thread_exit() {
-
exit = true;
}
void RenderingServerWrapMT::thread_draw(bool p_swap_buffers, double frame_step) {
-
if (!atomic_decrement(&draw_pending)) {
-
rendering_server->draw(p_swap_buffers, frame_step);
}
}
void RenderingServerWrapMT::thread_flush() {
-
atomic_decrement(&draw_pending);
}
void RenderingServerWrapMT::_thread_callback(void *_instance) {
-
RenderingServerWrapMT *vsmt = reinterpret_cast<RenderingServerWrapMT *>(_instance);
vsmt->thread_loop();
}
void RenderingServerWrapMT::thread_loop() {
-
server_thread = Thread::get_caller_id();
DisplayServer::get_singleton()->make_rendering_thread();
@@ -81,33 +75,25 @@ void RenderingServerWrapMT::thread_loop() {
/* EVENT QUEUING */
void RenderingServerWrapMT::sync() {
-
if (create_thread) {
-
atomic_increment(&draw_pending);
command_queue.push_and_sync(this, &RenderingServerWrapMT::thread_flush);
} else {
-
command_queue.flush_all(); //flush all pending from other threads
}
}
void RenderingServerWrapMT::draw(bool p_swap_buffers, double frame_step) {
-
if (create_thread) {
-
atomic_increment(&draw_pending);
command_queue.push(this, &RenderingServerWrapMT::thread_draw, p_swap_buffers, frame_step);
} else {
-
rendering_server->draw(p_swap_buffers, frame_step);
}
}
void RenderingServerWrapMT::init() {
-
if (create_thread) {
-
print_verbose("RenderingServerWrapMT: Creating render thread");
DisplayServer::get_singleton()->release_rendering_thread();
if (create_thread) {
@@ -119,13 +105,11 @@ void RenderingServerWrapMT::init() {
}
print_verbose("RenderingServerWrapMT: Finished render thread");
} else {
-
rendering_server->init();
}
}
void RenderingServerWrapMT::finish() {
-
sky_free_cached_ids();
shader_free_cached_ids();
material_free_cached_ids();
@@ -138,7 +122,7 @@ void RenderingServerWrapMT::finish() {
spot_light_free_cached_ids();
reflection_probe_free_cached_ids();
gi_probe_free_cached_ids();
- lightmap_capture_free_cached_ids();
+ lightmap_free_cached_ids();
particles_free_cached_ids();
camera_free_cached_ids();
viewport_free_cached_ids();
@@ -152,7 +136,6 @@ void RenderingServerWrapMT::finish() {
canvas_occluder_polygon_free_cached_ids();
if (thread) {
-
command_queue.push(this, &RenderingServerWrapMT::thread_exit);
Thread::wait_to_finish(thread);
memdelete(thread);
@@ -164,7 +147,6 @@ void RenderingServerWrapMT::finish() {
}
void RenderingServerWrapMT::set_use_vsync_callback(bool p_enable) {
-
singleton_mt->call_set_use_vsync(p_enable);
}
@@ -172,7 +154,6 @@ RenderingServerWrapMT *RenderingServerWrapMT::singleton_mt = nullptr;
RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool p_create_thread) :
command_queue(p_create_thread) {
-
singleton_mt = this;
DisplayServer::switch_vsync_function = set_use_vsync_callback; //as this goes to another thread, make sure it goes properly
@@ -191,7 +172,6 @@ RenderingServerWrapMT::RenderingServerWrapMT(RenderingServer *p_contained, bool
}
RenderingServerWrapMT::~RenderingServerWrapMT() {
-
memdelete(rendering_server);
//finish();
}
diff --git a/servers/rendering/rendering_server_wrap_mt.h b/servers/rendering/rendering_server_wrap_mt.h
index d4e58485b8..a746aa52b2 100644
--- a/servers/rendering/rendering_server_wrap_mt.h
+++ b/servers/rendering/rendering_server_wrap_mt.h
@@ -36,7 +36,6 @@
#include "servers/rendering_server.h"
class RenderingServerWrapMT : public RenderingServer {
-
// the real visual server
mutable RenderingServer *rendering_server;
@@ -92,7 +91,7 @@ public:
//these also go pass-through
virtual RID texture_2d_placeholder_create() { return rendering_server->texture_2d_placeholder_create(); }
- virtual RID texture_2d_layered_placeholder_create() { return rendering_server->texture_2d_layered_placeholder_create(); }
+ virtual RID texture_2d_layered_placeholder_create(TextureLayeredType p_type) { return rendering_server->texture_2d_layered_placeholder_create(p_type); }
virtual RID texture_3d_placeholder_create() { return rendering_server->texture_3d_placeholder_create(); }
FUNC1RC(Ref<Image>, texture_2d_get, RID)
@@ -324,19 +323,17 @@ public:
/* LIGHTMAP CAPTURE */
- FUNCRID(lightmap_capture)
-
- FUNC2(lightmap_capture_set_bounds, RID, const AABB &)
- FUNC1RC(AABB, lightmap_capture_get_bounds, RID)
+ FUNCRID(lightmap)
+ FUNC3(lightmap_set_textures, RID, RID, bool)
+ FUNC2(lightmap_set_probe_bounds, RID, const AABB &)
+ FUNC2(lightmap_set_probe_interior, RID, bool)
+ FUNC5(lightmap_set_probe_capture_data, RID, const PackedVector3Array &, const PackedColorArray &, const PackedInt32Array &, const PackedInt32Array &)
+ FUNC1RC(PackedVector3Array, lightmap_get_probe_capture_points, RID)
+ FUNC1RC(PackedColorArray, lightmap_get_probe_capture_sh, RID)
+ FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_tetrahedra, RID)
+ FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID)
- FUNC2(lightmap_capture_set_octree, RID, const Vector<uint8_t> &)
- FUNC1RC(Vector<uint8_t>, lightmap_capture_get_octree, RID)
- FUNC2(lightmap_capture_set_octree_cell_transform, RID, const Transform &)
- FUNC1RC(Transform, lightmap_capture_get_octree_cell_transform, RID)
- FUNC2(lightmap_capture_set_octree_cell_subdiv, RID, int)
- FUNC1RC(int, lightmap_capture_get_octree_cell_subdiv, RID)
- FUNC2(lightmap_capture_set_energy, RID, float)
- FUNC1RC(float, lightmap_capture_get_energy, RID)
+ FUNC1(lightmap_set_probe_capture_update_speed, float)
/* PARTICLES */
@@ -442,6 +439,7 @@ public:
FUNC2(sky_set_radiance_size, RID, int)
FUNC2(sky_set_mode, RID, SkyMode)
FUNC2(sky_set_material, RID, RID)
+ FUNC4R(Ref<Image>, sky_bake_panorama, RID, float, bool, const Size2i &)
/* ENVIRONMENT API */
@@ -478,6 +476,8 @@ public:
FUNC7(environment_set_fog_depth, RID, bool, float, float, float, bool, float)
FUNC5(environment_set_fog_height, RID, bool, float, float, float)
+ FUNC3R(Ref<Image>, environment_bake_panorama, RID, bool, const Size2i &)
+
FUNC2(screen_space_roughness_limiter_set_active, bool, float)
FUNC1(sub_surface_scattering_set_quality, SubSurfaceScatteringQuality)
FUNC2(sub_surface_scattering_set_scale, float, float)
@@ -511,7 +511,6 @@ public:
FUNC3(instance_set_blend_shape_weight, RID, int, float)
FUNC3(instance_set_surface_material, RID, int, RID)
FUNC2(instance_set_visible, RID, bool)
- FUNC3(instance_set_use_lightmap, RID, RID, RID)
FUNC2(instance_set_custom_aabb, RID, AABB)
@@ -531,12 +530,17 @@ public:
FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float)
FUNC2(instance_geometry_set_as_instance_lod, RID, RID)
+ FUNC4(instance_geometry_set_lightmap, RID, RID, const Rect2 &, int)
FUNC3(instance_geometry_set_shader_parameter, RID, const StringName &, const Variant &)
FUNC2RC(Variant, instance_geometry_get_shader_parameter, RID, const StringName &)
FUNC2RC(Variant, instance_geometry_get_shader_parameter_default_value, RID, const StringName &)
FUNC2SC(instance_geometry_get_shader_parameter_list, RID, List<PropertyInfo> *)
+ /* BAKE */
+
+ FUNC3R(TypedArray<Image>, bake_render_uv2, RID, const Vector<RID> &, const Size2i &)
+
/* CANVAS (2D) */
FUNCRID(canvas)
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index bec0958f71..2ec65b7ea8 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -34,22 +34,18 @@
#include "servers/rendering_server.h"
static bool _is_text_char(CharType c) {
-
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
static bool _is_number(CharType c) {
-
return (c >= '0' && c <= '9');
}
static bool _is_hex(CharType c) {
-
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');
}
String ShaderLanguage::get_operator_text(Operator p_op) {
-
static const char *op_names[OP_MAX] = { "==",
"!=",
"<",
@@ -132,6 +128,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
"TYPE_ISAMPLER3D",
"TYPE_USAMPLER3D",
"TYPE_SAMPLERCUBE",
+ "TYPE_SAMPLERCUBEARRAY",
"INTERPOLATION_FLAT",
"INTERPOLATION_SMOOTH",
"CONST",
@@ -225,7 +222,6 @@ const char *ShaderLanguage::token_names[TK_MAX] = {
};
String ShaderLanguage::get_token_text(Token p_token) {
-
String name = token_names[p_token.type];
if (p_token.type == TK_INT_CONSTANT || p_token.type == TK_REAL_CONSTANT) {
name += "(" + rtos(p_token.constant) + ")";
@@ -239,7 +235,6 @@ String ShaderLanguage::get_token_text(Token p_token) {
}
ShaderLanguage::Token ShaderLanguage::_make_token(TokenType p_type, const StringName &p_text) {
-
Token tk;
tk.type = p_type;
tk.text = p_text;
@@ -283,6 +278,7 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
{ TK_TYPE_ISAMPLER3D, "isampler3D" },
{ TK_TYPE_USAMPLER3D, "usampler3D" },
{ TK_TYPE_SAMPLERCUBE, "samplerCube" },
+ { TK_TYPE_SAMPLERCUBEARRAY, "samplerCubeArray" },
{ TK_INTERPOLATION_FLAT, "flat" },
{ TK_INTERPOLATION_SMOOTH, "smooth" },
{ TK_CONST, "const" },
@@ -338,13 +334,11 @@ const ShaderLanguage::KeyWord ShaderLanguage::keyword_list[] = {
};
ShaderLanguage::Token ShaderLanguage::_get_token() {
-
#define GETCHAR(m_idx) (((char_idx + m_idx) < code.length()) ? code[char_idx + m_idx] : CharType(0))
while (true) {
char_idx++;
switch (GETCHAR(-1)) {
-
case 0:
return _make_token(TK_EOF);
case 0xFFFF:
@@ -357,7 +351,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
tk_line++;
continue;
case '/': {
-
switch (GETCHAR(0)) {
case '*': { // block comment
@@ -405,7 +398,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
continue; //a comment, continue to next token
} break;
case '=': {
-
if (GETCHAR(0) == '=') {
char_idx++;
return _make_token(TK_OP_EQUAL);
@@ -494,7 +486,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
return _make_token(TK_OP_BIT_AND);
} break;
case '|': {
-
if (GETCHAR(0) == '=') {
char_idx++;
return _make_token(TK_OP_ASSIGN_BIT_OR);
@@ -506,7 +497,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
} break;
case '*': {
-
if (GETCHAR(0) == '=') {
char_idx++;
return _make_token(TK_OP_ASSIGN_MUL);
@@ -514,12 +504,10 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
return _make_token(TK_OP_MUL);
} break;
case '+': {
-
if (GETCHAR(0) == '=') {
char_idx++;
return _make_token(TK_OP_ASSIGN_ADD);
} else if (GETCHAR(0) == '+') {
-
char_idx++;
return _make_token(TK_OP_INCREMENT);
}
@@ -527,12 +515,10 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
return _make_token(TK_OP_ADD);
} break;
case '-': {
-
if (GETCHAR(0) == '=') {
char_idx++;
return _make_token(TK_OP_ASSIGN_SUB);
} else if (GETCHAR(0) == '-') {
-
char_idx++;
return _make_token(TK_OP_DECREMENT);
}
@@ -540,7 +526,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
return _make_token(TK_OP_SUB);
} break;
case '%': {
-
if (GETCHAR(0) == '=') {
char_idx++;
return _make_token(TK_OP_ASSIGN_MOD);
@@ -549,7 +534,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
return _make_token(TK_OP_MOD);
} break;
default: {
-
char_idx--; //go back one, since we have no idea what this is
if (_is_number(GETCHAR(0)) || (GETCHAR(0) == '.' && _is_number(GETCHAR(1)))) {
@@ -565,32 +549,38 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
while (true) {
if (GETCHAR(i) == '.') {
- if (period_found || exponent_found || hexa_found || float_suffix_found)
+ if (period_found || exponent_found || hexa_found || float_suffix_found) {
return _make_token(TK_ERROR, "Invalid numeric constant");
+ }
period_found = true;
} else if (GETCHAR(i) == 'x') {
- if (hexa_found || str.length() != 1 || str[0] != '0')
+ if (hexa_found || str.length() != 1 || str[0] != '0') {
return _make_token(TK_ERROR, "Invalid numeric constant");
+ }
hexa_found = true;
} else if (GETCHAR(i) == 'e') {
- if (hexa_found || exponent_found || float_suffix_found)
+ if (hexa_found || exponent_found || float_suffix_found) {
return _make_token(TK_ERROR, "Invalid numeric constant");
+ }
exponent_found = true;
} else if (GETCHAR(i) == 'f') {
- if (hexa_found || exponent_found)
+ if (hexa_found || exponent_found) {
return _make_token(TK_ERROR, "Invalid numeric constant");
+ }
float_suffix_found = true;
} else if (_is_number(GETCHAR(i))) {
- if (float_suffix_found)
+ if (float_suffix_found) {
return _make_token(TK_ERROR, "Invalid numeric constant");
+ }
} else if (hexa_found && _is_hex(GETCHAR(i))) {
-
} else if ((GETCHAR(i) == '-' || GETCHAR(i) == '+') && exponent_found) {
- if (sign_found)
+ if (sign_found) {
return _make_token(TK_ERROR, "Invalid numeric constant");
+ }
sign_found = true;
- } else
+ } else {
break;
+ }
str += CharType(GETCHAR(i));
i++;
@@ -646,10 +636,11 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
char_idx += str.length();
Token tk;
- if (period_found || exponent_found || float_suffix_found)
+ if (period_found || exponent_found || float_suffix_found) {
tk.type = TK_REAL_CONSTANT;
- else
+ } else {
tk.type = TK_INT_CONSTANT;
+ }
if (hexa_found) {
tk.constant = (double)str.hex_to_int64(true);
@@ -672,7 +663,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
String str;
while (_is_text_char(GETCHAR(0))) {
-
str += CharType(GETCHAR(0));
char_idx++;
}
@@ -682,9 +672,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
int idx = 0;
while (keyword_list[idx].text) {
-
if (str == keyword_list[idx].text) {
-
return _make_token(keyword_list[idx].token);
}
idx++;
@@ -695,10 +683,11 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
return _make_token(TK_IDENTIFIER, str);
}
- if (GETCHAR(0) > 32)
+ if (GETCHAR(0) > 32) {
return _make_token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0)) + ": '" + String::chr(GETCHAR(0)) + "'");
- else
+ } else {
return _make_token(TK_ERROR, "Tokenizer: Unknown character #" + itos(GETCHAR(0)));
+ }
} break;
}
@@ -710,7 +699,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
}
String ShaderLanguage::token_debug(const String &p_code) {
-
clear();
code = p_code;
@@ -719,7 +707,6 @@ String ShaderLanguage::token_debug(const String &p_code) {
Token tk = _get_token();
while (tk.type != TK_EOF && tk.type != TK_ERROR) {
-
output += itos(tk_line) + ": " + get_token_text(tk) + "\n";
tk = _get_token();
}
@@ -752,7 +739,6 @@ bool ShaderLanguage::is_token_variable_datatype(TokenType p_type) {
}
bool ShaderLanguage::is_token_datatype(TokenType p_type) {
-
return (
p_type == TK_TYPE_VOID ||
p_type == TK_TYPE_BOOL ||
@@ -783,31 +769,29 @@ bool ShaderLanguage::is_token_datatype(TokenType p_type) {
p_type == TK_TYPE_SAMPLER3D ||
p_type == TK_TYPE_ISAMPLER3D ||
p_type == TK_TYPE_USAMPLER3D ||
- p_type == TK_TYPE_SAMPLERCUBE);
+ p_type == TK_TYPE_SAMPLERCUBE ||
+ p_type == TK_TYPE_SAMPLERCUBEARRAY);
}
ShaderLanguage::DataType ShaderLanguage::get_token_datatype(TokenType p_type) {
-
return DataType(p_type - TK_TYPE_VOID);
}
bool ShaderLanguage::is_token_interpolation(TokenType p_type) {
-
return (
p_type == TK_INTERPOLATION_FLAT ||
p_type == TK_INTERPOLATION_SMOOTH);
}
ShaderLanguage::DataInterpolation ShaderLanguage::get_token_interpolation(TokenType p_type) {
-
- if (p_type == TK_INTERPOLATION_FLAT)
+ if (p_type == TK_INTERPOLATION_FLAT) {
return INTERPOLATION_FLAT;
- else
+ } else {
return INTERPOLATION_SMOOTH;
+ }
}
bool ShaderLanguage::is_token_precision(TokenType p_type) {
-
return (
p_type == TK_PRECISION_LOW ||
p_type == TK_PRECISION_MID ||
@@ -815,20 +799,23 @@ bool ShaderLanguage::is_token_precision(TokenType p_type) {
}
ShaderLanguage::DataPrecision ShaderLanguage::get_token_precision(TokenType p_type) {
-
- if (p_type == TK_PRECISION_LOW)
+ if (p_type == TK_PRECISION_LOW) {
return PRECISION_LOWP;
- else if (p_type == TK_PRECISION_HIGH)
+ } else if (p_type == TK_PRECISION_HIGH) {
return PRECISION_HIGHP;
- else
+ } else {
return PRECISION_MEDIUMP;
+ }
}
String ShaderLanguage::get_precision_name(DataPrecision p_type) {
switch (p_type) {
- case PRECISION_LOWP: return "lowp";
- case PRECISION_MEDIUMP: return "mediump";
- case PRECISION_HIGHP: return "highp";
+ case PRECISION_LOWP:
+ return "lowp";
+ case PRECISION_MEDIUMP:
+ return "mediump";
+ case PRECISION_HIGHP:
+ return "highp";
default:
break;
}
@@ -836,53 +823,83 @@ String ShaderLanguage::get_precision_name(DataPrecision p_type) {
}
String ShaderLanguage::get_datatype_name(DataType p_type) {
-
switch (p_type) {
-
- case TYPE_VOID: return "void";
- case TYPE_BOOL: return "bool";
- case TYPE_BVEC2: return "bvec2";
- case TYPE_BVEC3: return "bvec3";
- case TYPE_BVEC4: return "bvec4";
- case TYPE_INT: return "int";
- case TYPE_IVEC2: return "ivec2";
- case TYPE_IVEC3: return "ivec3";
- case TYPE_IVEC4: return "ivec4";
- case TYPE_UINT: return "uint";
- case TYPE_UVEC2: return "uvec2";
- case TYPE_UVEC3: return "uvec3";
- case TYPE_UVEC4: return "uvec4";
- case TYPE_FLOAT: return "float";
- case TYPE_VEC2: return "vec2";
- case TYPE_VEC3: return "vec3";
- case TYPE_VEC4: return "vec4";
- case TYPE_MAT2: return "mat2";
- case TYPE_MAT3: return "mat3";
- case TYPE_MAT4: return "mat4";
- case TYPE_SAMPLER2D: return "sampler2D";
- case TYPE_ISAMPLER2D: return "isampler2D";
- case TYPE_USAMPLER2D: return "usampler2D";
- case TYPE_SAMPLER2DARRAY: return "sampler2DArray";
- case TYPE_ISAMPLER2DARRAY: return "isampler2DArray";
- case TYPE_USAMPLER2DARRAY: return "usampler2DArray";
- case TYPE_SAMPLER3D: return "sampler3D";
- case TYPE_ISAMPLER3D: return "isampler3D";
- case TYPE_USAMPLER3D: return "usampler3D";
- case TYPE_SAMPLERCUBE: return "samplerCube";
- case TYPE_STRUCT: return "struct";
- case TYPE_MAX: return "invalid";
+ case TYPE_VOID:
+ return "void";
+ case TYPE_BOOL:
+ return "bool";
+ case TYPE_BVEC2:
+ return "bvec2";
+ case TYPE_BVEC3:
+ return "bvec3";
+ case TYPE_BVEC4:
+ return "bvec4";
+ case TYPE_INT:
+ return "int";
+ case TYPE_IVEC2:
+ return "ivec2";
+ case TYPE_IVEC3:
+ return "ivec3";
+ case TYPE_IVEC4:
+ return "ivec4";
+ case TYPE_UINT:
+ return "uint";
+ case TYPE_UVEC2:
+ return "uvec2";
+ case TYPE_UVEC3:
+ return "uvec3";
+ case TYPE_UVEC4:
+ return "uvec4";
+ case TYPE_FLOAT:
+ return "float";
+ case TYPE_VEC2:
+ return "vec2";
+ case TYPE_VEC3:
+ return "vec3";
+ case TYPE_VEC4:
+ return "vec4";
+ case TYPE_MAT2:
+ return "mat2";
+ case TYPE_MAT3:
+ return "mat3";
+ case TYPE_MAT4:
+ return "mat4";
+ case TYPE_SAMPLER2D:
+ return "sampler2D";
+ case TYPE_ISAMPLER2D:
+ return "isampler2D";
+ case TYPE_USAMPLER2D:
+ return "usampler2D";
+ case TYPE_SAMPLER2DARRAY:
+ return "sampler2DArray";
+ case TYPE_ISAMPLER2DARRAY:
+ return "isampler2DArray";
+ case TYPE_USAMPLER2DARRAY:
+ return "usampler2DArray";
+ case TYPE_SAMPLER3D:
+ return "sampler3D";
+ case TYPE_ISAMPLER3D:
+ return "isampler3D";
+ case TYPE_USAMPLER3D:
+ return "usampler3D";
+ case TYPE_SAMPLERCUBE:
+ return "samplerCube";
+ case TYPE_SAMPLERCUBEARRAY:
+ return "samplerCubeArray";
+ case TYPE_STRUCT:
+ return "struct";
+ case TYPE_MAX:
+ return "invalid";
}
return "";
}
bool ShaderLanguage::is_token_nonvoid_datatype(TokenType p_type) {
-
return is_token_datatype(p_type) && p_type != TK_TYPE_VOID;
}
void ShaderLanguage::clear() {
-
current_function = StringName();
completion_type = COMPLETION_NONE;
@@ -904,9 +921,7 @@ void ShaderLanguage::clear() {
}
bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_reassign, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, bool *r_is_const, int *r_array_size, StringName *r_struct_name) {
-
if (p_builtin_types.has(p_identifier)) {
-
if (r_data_type) {
*r_data_type = p_builtin_types[p_identifier].type;
}
@@ -923,7 +938,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
FunctionNode *function = nullptr;
while (p_block) {
-
if (p_block->variables.has(p_identifier)) {
if (r_data_type) {
*r_data_type = p_block->variables[p_identifier].type;
@@ -1010,9 +1024,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
}
for (int i = 0; i < shader->functions.size(); i++) {
-
- if (!shader->functions[i].callable)
+ if (!shader->functions[i].callable) {
continue;
+ }
if (shader->functions[i].name == p_identifier) {
if (r_data_type) {
@@ -1029,7 +1043,6 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, bool p_allow_rea
}
bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type) {
-
bool valid = false;
DataType ret_type = TYPE_VOID;
@@ -1062,7 +1075,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
} break;
case OP_NOT: {
-
DataType na = p_op->arguments[0]->get_datatype();
valid = na == TYPE_BOOL;
ret_type = TYPE_BOOL;
@@ -1201,7 +1213,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
case OP_ASSIGN_SHIFT_RIGHT:
case OP_SHIFT_LEFT:
case OP_SHIFT_RIGHT: {
-
DataType na = p_op->arguments[0]->get_datatype();
DataType nb = p_op->arguments[1]->get_datatype();
@@ -1263,7 +1274,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
case OP_ASSIGN_SUB:
case OP_ASSIGN_MUL:
case OP_ASSIGN_DIV: {
-
DataType na = p_op->arguments[0]->get_datatype();
DataType nb = p_op->arguments[1]->get_datatype();
@@ -1323,7 +1333,6 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
case OP_BIT_AND:
case OP_BIT_OR:
case OP_BIT_XOR: {
-
/*
* The bitwise operators and (&), exclusive-or (^), and inclusive-or (|). The operands must be of type
* signed or unsigned integers or integer vectors. The operands cannot be vectors of differing size. If
@@ -1403,8 +1412,9 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type
}
}
- if (r_ret_type)
+ if (r_ret_type) {
*r_ret_type = ret_type;
+ }
return valid;
}
@@ -2011,6 +2021,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
{ "textureSize", TYPE_IVEC3, { TYPE_USAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
{ "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBEARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
@@ -2032,6 +2043,8 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, false },
{ "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, false },
+ { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
{ "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
{ "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL, true },
@@ -2062,6 +2075,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
{ "textureLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
{ "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
+ { "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, false },
{ "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
{ "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL, true },
@@ -2093,6 +2107,7 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = {
{ "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
{ "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
{ "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
+ { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBEARRAY, TYPE_VEC4, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL, true },
{ "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL, true },
{ "dFdx", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL, true },
@@ -2125,7 +2140,6 @@ const ShaderLanguage::BuiltinFuncOutArgs ShaderLanguage::builtin_func_out_args[]
};
bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, DataType *r_ret_type, StringName *r_ret_type_str) {
-
ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, false);
Vector<DataType> args;
@@ -2151,18 +2165,15 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
int idx = 0;
while (builtin_func_defs[idx].name) {
-
if (completion_class != builtin_func_defs[idx].tag) {
idx++;
continue;
}
if (name == builtin_func_defs[idx].name) {
-
failed_builtin = true;
bool fail = false;
for (int i = 0; i < argcount; i++) {
-
if (get_scalar_type(args[i]) == args[i] && p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && convert_constant(static_cast<ConstantNode *>(p_func->arguments[i + 1]), builtin_func_defs[idx].args[i])) {
//all good, but needs implicit conversion later
} else if (args[i] != builtin_func_defs[idx].args[i]) {
@@ -2181,20 +2192,18 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
}
}
- if (!fail && argcount < 4 && builtin_func_defs[idx].args[argcount] != TYPE_VOID)
+ if (!fail && argcount < 4 && builtin_func_defs[idx].args[argcount] != TYPE_VOID) {
fail = true; //make sure the number of arguments matches
+ }
if (!fail) {
-
//make sure its not an out argument used in the wrong way
int outarg_idx = 0;
while (builtin_func_out_args[outarg_idx].name) {
-
if (String(name) == builtin_func_out_args[outarg_idx].name) {
int arg_idx = builtin_func_out_args[outarg_idx].argument;
if (arg_idx < argcount) {
-
if (p_func->arguments[arg_idx + 1]->type != Node::TYPE_VARIABLE && p_func->arguments[arg_idx + 1]->type != Node::TYPE_MEMBER && p_func->arguments[arg_idx + 1]->type != Node::TYPE_ARRAY) {
_set_error("Argument " + itos(arg_idx + 1) + " of function '" + String(name) + "' is not a variable, array or member.");
return false;
@@ -2282,7 +2291,6 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
}
//implicitly convert values if possible
for (int i = 0; i < argcount; i++) {
-
if (get_scalar_type(args[i]) != args[i] || args[i] == builtin_func_defs[idx].args[i] || p_func->arguments[i + 1]->type != Node::TYPE_CONSTANT) {
//can't do implicit conversion here
continue;
@@ -2299,8 +2307,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
p_func->arguments.write[i + 1] = conversion;
}
- if (r_ret_type)
+ if (r_ret_type) {
*r_ret_type = builtin_func_defs[idx].rettype;
+ }
return true;
}
@@ -2311,7 +2320,6 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
}
if (unsupported_builtin) {
-
String arglist = "";
for (int i = 0; i < argcount; i++) {
if (i > 0) {
@@ -2328,8 +2336,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
if (failed_builtin) {
String err = "Invalid arguments for built-in function: " + String(name) + "(";
for (int i = 0; i < argcount; i++) {
- if (i > 0)
+ if (i > 0) {
err += ",";
+ }
if (p_func->arguments[i + 1]->type == Node::TYPE_CONSTANT && p_func->arguments[i + 1]->get_datatype() == TYPE_INT && static_cast<ConstantNode *>(p_func->arguments[i + 1])->values[0].sint < 0) {
err += "-";
@@ -2347,7 +2356,6 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
BlockNode *block = p_block;
while (block) {
-
if (block->parent_function) {
exclude_function = block->parent_function->name;
}
@@ -2360,9 +2368,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
}
for (int i = 0; i < shader->functions.size(); i++) {
-
- if (name != shader->functions[i].name)
+ if (name != shader->functions[i].name) {
continue;
+ }
if (!shader->functions[i].callable) {
_set_error("Function '" + String(name) + " can't be called from source code.");
@@ -2371,8 +2379,9 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
FunctionNode *pfunc = shader->functions[i].function;
- if (pfunc->arguments.size() != args.size())
+ if (pfunc->arguments.size() != args.size()) {
continue;
+ }
bool fail = false;
@@ -2390,10 +2399,8 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const Map<Strin
}
if (!fail) {
-
//implicitly convert values if possible
for (int k = 0; k < args.size(); k++) {
-
if (get_scalar_type(args[k]) != args[k] || args[k] == pfunc->arguments[k].type || p_func->arguments[k + 1]->type != Node::TYPE_CONSTANT) {
//can't do implicit conversion here
continue;
@@ -2437,7 +2444,6 @@ bool ShaderLanguage::_compare_datatypes_in_nodes(Node *a, Node *b) const {
}
bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, OperatorNode *p_func, int *r_complete_arg) {
-
TkPos pos = _get_tkpos();
Token tk = _get_token();
@@ -2448,16 +2454,13 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str
_set_tkpos(pos);
while (true) {
-
if (r_complete_arg) {
pos = _get_tkpos();
tk = _get_token();
if (tk.type == TK_CURSOR) {
-
*r_complete_arg = p_func->arguments.size() - 1;
} else {
-
_set_tkpos(pos);
}
}
@@ -2465,7 +2468,6 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str
Node *arg = _parse_and_reduce_expression(p_block, p_builtin_types);
if (!arg) {
-
return false;
}
@@ -2474,7 +2476,6 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str
tk = _get_token();
if (tk.type == TK_PARENTHESIS_CLOSE) {
-
return true;
} else if (tk.type != TK_COMMA) {
// something is broken
@@ -2487,7 +2488,6 @@ bool ShaderLanguage::_parse_function_arguments(BlockNode *p_block, const Map<Str
}
bool ShaderLanguage::is_token_operator(TokenType p_type) {
-
return (p_type == TK_OP_EQUAL ||
p_type == TK_OP_NOT_EQUAL ||
p_type == TK_OP_LESS ||
@@ -2526,7 +2526,6 @@ bool ShaderLanguage::is_token_operator(TokenType p_type) {
}
bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_type, ConstantNode::Value *p_value) {
-
if (p_constant->datatype == p_to_type) {
if (p_value) {
for (int i = 0; i < p_constant->values.size(); i++) {
@@ -2535,13 +2534,11 @@ bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_ty
}
return true;
} else if (p_constant->datatype == TYPE_INT && p_to_type == TYPE_FLOAT) {
-
if (p_value) {
p_value->real = p_constant->values[0].sint;
}
return true;
} else if (p_constant->datatype == TYPE_UINT && p_to_type == TYPE_FLOAT) {
-
if (p_value) {
p_value->real = p_constant->values[0].uint;
}
@@ -2555,7 +2552,6 @@ bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_ty
}
return true;
} else if (p_constant->datatype == TYPE_UINT && p_to_type == TYPE_INT) {
-
if (p_constant->values[0].uint > 0x7FFFFFFF) {
return false;
}
@@ -2563,17 +2559,16 @@ bool ShaderLanguage::convert_constant(ConstantNode *p_constant, DataType p_to_ty
p_value->sint = p_constant->values[0].uint;
}
return true;
- } else
+ } else {
return false;
+ }
}
bool ShaderLanguage::is_scalar_type(DataType p_type) {
-
return p_type == TYPE_BOOL || p_type == TYPE_INT || p_type == TYPE_UINT || p_type == TYPE_FLOAT;
}
bool ShaderLanguage::is_sampler_type(DataType p_type) {
-
return p_type == TYPE_SAMPLER2D ||
p_type == TYPE_ISAMPLER2D ||
p_type == TYPE_USAMPLER2D ||
@@ -2583,7 +2578,8 @@ bool ShaderLanguage::is_sampler_type(DataType p_type) {
p_type == TYPE_SAMPLER3D ||
p_type == TYPE_ISAMPLER3D ||
p_type == TYPE_USAMPLER3D ||
- p_type == TYPE_SAMPLERCUBE;
+ p_type == TYPE_SAMPLERCUBE ||
+ p_type == TYPE_SAMPLERCUBEARRAY;
}
Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::ConstantNode::Value> &p_value, DataType p_type, ShaderLanguage::ShaderNode::Uniform::Hint p_hint) {
@@ -2677,7 +2673,8 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
case ShaderLanguage::TYPE_USAMPLER2DARRAY:
case ShaderLanguage::TYPE_USAMPLER2D:
case ShaderLanguage::TYPE_USAMPLER3D:
- case ShaderLanguage::TYPE_SAMPLERCUBE: {
+ case ShaderLanguage::TYPE_SAMPLERCUBE:
+ case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
// Texture types, likely not relevant here.
break;
}
@@ -2696,8 +2693,12 @@ Variant ShaderLanguage::constant_value_to_variant(const Vector<ShaderLanguage::C
PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform &p_uniform) {
PropertyInfo pi;
switch (p_uniform.type) {
- case ShaderLanguage::TYPE_VOID: pi.type = Variant::NIL; break;
- case ShaderLanguage::TYPE_BOOL: pi.type = Variant::BOOL; break;
+ case ShaderLanguage::TYPE_VOID:
+ pi.type = Variant::NIL;
+ break;
+ case ShaderLanguage::TYPE_BOOL:
+ pi.type = Variant::BOOL;
+ break;
case ShaderLanguage::TYPE_BVEC2:
pi.type = Variant::INT;
pi.hint = PROPERTY_HINT_FLAGS;
@@ -2728,7 +2729,6 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
case ShaderLanguage::TYPE_UVEC2:
case ShaderLanguage::TYPE_UVEC3:
case ShaderLanguage::TYPE_UVEC4: {
-
pi.type = Variant::PACKED_INT32_ARRAY;
} break;
case ShaderLanguage::TYPE_FLOAT: {
@@ -2739,8 +2739,12 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
}
} break;
- case ShaderLanguage::TYPE_VEC2: pi.type = Variant::VECTOR2; break;
- case ShaderLanguage::TYPE_VEC3: pi.type = Variant::VECTOR3; break;
+ case ShaderLanguage::TYPE_VEC2:
+ pi.type = Variant::VECTOR2;
+ break;
+ case ShaderLanguage::TYPE_VEC3:
+ pi.type = Variant::VECTOR3;
+ break;
case ShaderLanguage::TYPE_VEC4: {
if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_COLOR) {
pi.type = Variant::COLOR;
@@ -2748,13 +2752,18 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
pi.type = Variant::PLANE;
}
} break;
- case ShaderLanguage::TYPE_MAT2: pi.type = Variant::TRANSFORM2D; break;
- case ShaderLanguage::TYPE_MAT3: pi.type = Variant::BASIS; break;
- case ShaderLanguage::TYPE_MAT4: pi.type = Variant::TRANSFORM; break;
+ case ShaderLanguage::TYPE_MAT2:
+ pi.type = Variant::TRANSFORM2D;
+ break;
+ case ShaderLanguage::TYPE_MAT3:
+ pi.type = Variant::BASIS;
+ break;
+ case ShaderLanguage::TYPE_MAT4:
+ pi.type = Variant::TRANSFORM;
+ break;
case ShaderLanguage::TYPE_SAMPLER2D:
case ShaderLanguage::TYPE_ISAMPLER2D:
case ShaderLanguage::TYPE_USAMPLER2D: {
-
pi.type = Variant::OBJECT;
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
pi.hint_string = "Texture2D";
@@ -2762,10 +2771,9 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
case ShaderLanguage::TYPE_SAMPLER2DARRAY:
case ShaderLanguage::TYPE_ISAMPLER2DARRAY:
case ShaderLanguage::TYPE_USAMPLER2DARRAY: {
-
pi.type = Variant::OBJECT;
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
- pi.hint_string = "TextureArray";
+ pi.hint_string = "TextureLayered";
} break;
case ShaderLanguage::TYPE_SAMPLER3D:
case ShaderLanguage::TYPE_ISAMPLER3D:
@@ -2774,11 +2782,11 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
pi.hint_string = "Texture3D";
} break;
- case ShaderLanguage::TYPE_SAMPLERCUBE: {
-
+ case ShaderLanguage::TYPE_SAMPLERCUBE:
+ case ShaderLanguage::TYPE_SAMPLERCUBEARRAY: {
pi.type = Variant::OBJECT;
pi.hint = PROPERTY_HINT_RESOURCE_TYPE;
- pi.hint_string = "CubeMap";
+ pi.hint_string = "TextureLayered";
} break;
case ShaderLanguage::TYPE_STRUCT: {
// FIXME: Implement this.
@@ -2829,6 +2837,7 @@ uint32_t ShaderLanguage::get_type_size(DataType p_type) {
case TYPE_ISAMPLER3D:
case TYPE_USAMPLER3D:
case TYPE_SAMPLERCUBE:
+ case TYPE_SAMPLERCUBEARRAY:
return 4; //not really, but useful for indices
case TYPE_STRUCT:
// FIXME: Implement.
@@ -2840,13 +2849,11 @@ uint32_t ShaderLanguage::get_type_size(DataType p_type) {
}
void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
-
Set<String> kws;
int idx = 0;
while (keyword_list[idx].text) {
-
kws.insert(keyword_list[idx].text);
idx++;
}
@@ -2854,7 +2861,6 @@ void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
idx = 0;
while (builtin_func_defs[idx].name) {
-
kws.insert(builtin_func_defs[idx].name);
idx++;
@@ -2866,13 +2872,11 @@ void ShaderLanguage::get_keyword_list(List<String> *r_keywords) {
}
void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) {
-
Set<String> kws;
int idx = 0;
while (builtin_func_defs[idx].name) {
-
kws.insert(builtin_func_defs[idx].name);
idx++;
@@ -2884,7 +2888,6 @@ void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) {
}
ShaderLanguage::DataType ShaderLanguage::get_scalar_type(DataType p_type) {
-
static const DataType scalar_types[] = {
TYPE_VOID,
TYPE_BOOL,
@@ -2947,7 +2950,6 @@ int ShaderLanguage::get_cardinality(DataType p_type) {
}
bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier) {
-
identifier = StringName();
TkPos pos = { 0, 0 };
@@ -2961,7 +2963,6 @@ bool ShaderLanguage::_get_completable_identifier(BlockNode *p_block, CompletionT
}
if (tk.type == TK_CURSOR) {
-
completion_type = p_type;
completion_line = tk_line;
completion_block = p_block;
@@ -3004,9 +3005,7 @@ bool ShaderLanguage::_is_operator_assign(Operator p_op) const {
}
bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message) {
-
if (p_node->type == Node::TYPE_OPERATOR) {
-
OperatorNode *op = static_cast<OperatorNode *>(p_node);
if (op->op == OP_INDEX) {
@@ -3017,42 +3016,45 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
return _validate_assign(op->arguments[1], p_builtin_types, r_message);
} else if (op->op == OP_CALL) {
- if (r_message)
+ if (r_message) {
*r_message = RTR("Assignment to function.");
+ }
return false;
}
} else if (p_node->type == Node::TYPE_MEMBER) {
-
MemberNode *member = static_cast<MemberNode *>(p_node);
if (member->has_swizzling_duplicates) {
- if (r_message)
+ if (r_message) {
*r_message = RTR("Swizzling assignment contains duplicates.");
+ }
return false;
}
return _validate_assign(member->owner, p_builtin_types, r_message);
} else if (p_node->type == Node::TYPE_VARIABLE) {
-
VariableNode *var = static_cast<VariableNode *>(p_node);
if (shader->uniforms.has(var->name)) {
- if (r_message)
+ if (r_message) {
*r_message = RTR("Assignment to uniform.");
+ }
return false;
}
if (shader->varyings.has(var->name) && current_function != String("vertex")) {
- if (r_message)
+ if (r_message) {
*r_message = RTR("Varyings can only be assigned in vertex function.");
+ }
return false;
}
if (shader->constants.has(var->name) || var->is_const) {
- if (r_message)
+ if (r_message) {
*r_message = RTR("Constants cannot be modified.");
+ }
return false;
}
@@ -3060,33 +3062,34 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI
return true;
}
} else if (p_node->type == Node::TYPE_ARRAY) {
-
ArrayNode *arr = static_cast<ArrayNode *>(p_node);
if (arr->is_const) {
- if (r_message)
+ if (r_message) {
*r_message = RTR("Constants cannot be modified.");
+ }
return false;
}
if (shader->varyings.has(arr->name) && current_function != String("vertex")) {
- if (r_message)
+ if (r_message) {
*r_message = RTR("Varyings can only be assigned in vertex function.");
+ }
return false;
}
return true;
}
- if (r_message)
+ if (r_message) {
*r_message = "Assignment to constant expression.";
+ }
return false;
}
bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringName p_name, int p_argument, TextureFilter p_filter, TextureRepeat p_repeat) {
for (int i = 0; shader->functions.size(); i++) {
if (shader->functions[i].name == p_name) {
-
ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
if (arg->tex_builtin_check) {
@@ -3097,12 +3100,10 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam
if (arg->tex_argument_filter == p_filter && arg->tex_argument_repeat == p_repeat) {
return true;
} else {
-
_set_error("Sampler argument #" + itos(p_argument) + " of function '" + String(p_name) + "' called more than once using textures that differ in either filter or repeat setting.");
return false;
}
} else {
-
arg->tex_argument_check = true;
arg->tex_argument_filter = p_filter;
arg->tex_argument_repeat = p_repeat;
@@ -3119,10 +3120,10 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam
}
ERR_FAIL_V(false); //bug? function not found
}
+
bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringName p_name, int p_argument, const StringName &p_builtin) {
for (int i = 0; shader->functions.size(); i++) {
if (shader->functions[i].name == p_name) {
-
ERR_FAIL_INDEX_V(p_argument, shader->functions[i].function->arguments.size(), false);
FunctionNode::Argument *arg = &shader->functions[i].function->arguments.write[p_argument];
if (arg->tex_argument_check) {
@@ -3137,7 +3138,6 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa
return false;
}
} else {
-
arg->tex_builtin_check = true;
arg->tex_builtin = p_builtin;
@@ -3156,13 +3156,11 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa
}
ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) {
-
Vector<Expression> expression;
//Vector<TokenType> operators;
while (true) {
-
Node *expr = nullptr;
TkPos prepos = _get_tkpos();
Token tk = _get_token();
@@ -3174,19 +3172,18 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
//handle subexpression
expr = _parse_and_reduce_expression(p_block, p_builtin_types);
- if (!expr)
+ if (!expr) {
return nullptr;
+ }
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
-
_set_error("Expected ')' in expression");
return nullptr;
}
} else if (tk.type == TK_REAL_CONSTANT) {
-
ConstantNode *constant = alloc_node<ConstantNode>();
ConstantNode::Value v;
v.real = tk.constant;
@@ -3195,7 +3192,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr = constant;
} else if (tk.type == TK_INT_CONSTANT) {
-
ConstantNode *constant = alloc_node<ConstantNode>();
ConstantNode::Value v;
v.sint = tk.constant;
@@ -3204,7 +3200,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr = constant;
} else if (tk.type == TK_TRUE) {
-
//handle true constant
ConstantNode *constant = alloc_node<ConstantNode>();
ConstantNode::Value v;
@@ -3214,7 +3209,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr = constant;
} else if (tk.type == TK_FALSE) {
-
//handle false constant
ConstantNode *constant = alloc_node<ConstantNode>();
ConstantNode::Value v;
@@ -3224,7 +3218,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr = constant;
} else if (tk.type == TK_TYPE_VOID) {
-
//make sure void is not used in expression
_set_error("Void value not allowed in Expression");
return nullptr;
@@ -3235,7 +3228,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
func->op = OP_CONSTRUCT;
if (is_token_precision(tk.type)) {
-
func->return_precision_cache = get_token_precision(tk.type);
tk = _get_token();
}
@@ -3262,8 +3254,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
completion_argument = carg;
}
- if (!ok)
+ if (!ok) {
return nullptr;
+ }
if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) {
_set_error("No matching constructor found for: '" + String(funcname->name) + "'");
@@ -3273,7 +3266,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr = _reduce_expression(p_block, func);
} else if (tk.type == TK_IDENTIFIER) {
-
_set_tkpos(prepos);
StringName identifier;
@@ -3290,7 +3282,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
tk = _get_token();
if (tk.type == TK_PARENTHESIS_OPEN) {
-
if (struct_init) { //a struct constructor
const StringName &name = identifier;
@@ -3307,7 +3298,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
Node *nexpr;
if (pstruct->members[i]->array_size != 0) {
-
DataType type = pstruct->members[i]->get_datatype();
String struct_name = pstruct->members[i]->struct_name;
int array_size = pstruct->members[i]->array_size;
@@ -3323,7 +3313,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_CURLY_BRACKET_OPEN) {
auto_size = true;
} else {
-
if (shader->structs.has(tk.text)) {
type2 = TYPE_STRUCT;
struct_name2 = tk.text;
@@ -3406,7 +3395,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_PARENTHESIS_OPEN || auto_size) { // initialization
while (true) {
-
Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
if (!n) {
return nullptr;
@@ -3428,10 +3416,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
an->initializer.push_back(n);
break;
} else {
- if (auto_size)
+ if (auto_size) {
_set_error("Expected '}' or ','");
- else
+ } else {
_set_error("Expected ')' or ','");
+ }
return nullptr;
}
}
@@ -3526,8 +3515,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
completion_argument = carg;
}
- if (!ok)
+ if (!ok) {
return nullptr;
+ }
if (!_validate_function_call(p_block, p_builtin_types, func, &func->return_cache, &func->struct_name)) {
_set_error("No matching function found for: '" + String(funcname->name) + "'");
@@ -3540,14 +3530,12 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
FunctionNode *call_function = shader->functions[function_index].function;
if (call_function) {
-
//get current base function
FunctionNode *base_function = nullptr;
{
BlockNode *b = p_block;
while (b) {
-
if (b->parent_function) {
base_function = b->parent_function;
break;
@@ -3669,7 +3657,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
return nullptr;
}
} else {
-
if (!_find_identifier(p_block, false, p_builtin_types, identifier, &data_type, &ident_type, &is_const, &array_size, &struct_name)) {
_set_error("Unknown identifier in expression: " + String(identifier));
return nullptr;
@@ -3697,14 +3684,16 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
p_block->block_tag = SubClassTag::TAG_ARRAY;
call_expression = _parse_and_reduce_expression(p_block, p_builtin_types);
p_block->block_tag = SubClassTag::TAG_GLOBAL;
- if (!call_expression)
+ if (!call_expression) {
return nullptr;
+ }
data_type = call_expression->get_datatype();
} else { // indexing
index_expression = _parse_and_reduce_expression(p_block, p_builtin_types);
- if (!index_expression)
+ if (!index_expression) {
return nullptr;
+ }
if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) {
_set_error("Only integer expressions are allowed for indexing");
@@ -3741,7 +3730,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expr = arrname;
} else {
-
VariableNode *varname = alloc_node<VariableNode>();
varname->name = identifier;
varname->datatype_cache = data_type;
@@ -3753,17 +3741,27 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else if (tk.type == TK_OP_ADD) {
continue; //this one does nothing
} else if (tk.type == TK_OP_SUB || tk.type == TK_OP_NOT || tk.type == TK_OP_BIT_INVERT || tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) {
-
Expression e;
e.is_op = true;
switch (tk.type) {
- case TK_OP_SUB: e.op = OP_NEGATE; break;
- case TK_OP_NOT: e.op = OP_NOT; break;
- case TK_OP_BIT_INVERT: e.op = OP_BIT_INVERT; break;
- case TK_OP_INCREMENT: e.op = OP_INCREMENT; break;
- case TK_OP_DECREMENT: e.op = OP_DECREMENT; break;
- default: ERR_FAIL_V(nullptr);
+ case TK_OP_SUB:
+ e.op = OP_NEGATE;
+ break;
+ case TK_OP_NOT:
+ e.op = OP_NOT;
+ break;
+ case TK_OP_BIT_INVERT:
+ e.op = OP_BIT_INVERT;
+ break;
+ case TK_OP_INCREMENT:
+ e.op = OP_INCREMENT;
+ break;
+ case TK_OP_DECREMENT:
+ e.op = OP_DECREMENT;
+ break;
+ default:
+ ERR_FAIL_V(nullptr);
}
expression.push_back(e);
@@ -3787,9 +3785,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
if (tk.type == TK_CURSOR) {
//do nothing
} else if (tk.type == TK_IDENTIFIER) {
-
} else if (tk.type == TK_PERIOD) {
-
DataType dt = expr->get_datatype();
String st = expr->get_datatype_name();
@@ -3844,7 +3840,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
case TYPE_IVEC2:
case TYPE_UVEC2:
case TYPE_VEC2: {
-
int l = ident.length();
if (l == 1) {
member_type = DataType(dt - 1);
@@ -3861,7 +3856,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
const CharType *c = ident.ptr();
for (int i = 0; i < l; i++) {
-
switch (c[i]) {
case 'r':
case 'g':
@@ -3910,7 +3904,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
case TYPE_IVEC3:
case TYPE_UVEC3:
case TYPE_VEC3: {
-
int l = ident.length();
if (l == 1) {
member_type = DataType(dt - 2);
@@ -3927,7 +3920,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
const CharType *c = ident.ptr();
for (int i = 0; i < l; i++) {
-
switch (c[i]) {
case 'r':
case 'g':
@@ -3979,7 +3971,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
case TYPE_IVEC4:
case TYPE_UVEC4:
case TYPE_VEC4: {
-
int l = ident.length();
if (l == 1) {
member_type = DataType(dt - 3);
@@ -3996,7 +3987,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
const CharType *c = ident.ptr();
for (int i = 0; i < l; i++) {
-
switch (c[i]) {
case 'r':
case 'g':
@@ -4075,16 +4065,15 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
mn->has_swizzling_duplicates = repeated;
if (array_size > 0) {
-
tk = _get_token();
if (tk.type == TK_PERIOD) {
_set_error("Nested array length() is not yet implemented");
return nullptr;
} else if (tk.type == TK_BRACKET_OPEN) {
-
Node *index_expression = _parse_and_reduce_expression(p_block, p_builtin_types);
- if (!index_expression)
+ if (!index_expression) {
return nullptr;
+ }
if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) {
_set_error("Only integer expressions are allowed for indexing");
@@ -4130,10 +4119,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
*/
} else if (tk.type == TK_BRACKET_OPEN) {
-
Node *index = _parse_and_reduce_expression(p_block, p_builtin_types);
- if (!index)
+ if (!index) {
return nullptr;
+ }
if (index->get_datatype() != TYPE_INT && index->get_datatype() != TYPE_UINT) {
_set_error("Only integer datatypes are allowed for indexing");
@@ -4157,12 +4146,23 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
switch (expr->get_datatype()) {
- case TYPE_BVEC2: member_type = TYPE_BOOL; break;
- case TYPE_VEC2: member_type = TYPE_FLOAT; break;
- case TYPE_IVEC2: member_type = TYPE_INT; break;
- case TYPE_UVEC2: member_type = TYPE_UINT; break;
- case TYPE_MAT2: member_type = TYPE_VEC2; break;
- default: break;
+ case TYPE_BVEC2:
+ member_type = TYPE_BOOL;
+ break;
+ case TYPE_VEC2:
+ member_type = TYPE_FLOAT;
+ break;
+ case TYPE_IVEC2:
+ member_type = TYPE_INT;
+ break;
+ case TYPE_UVEC2:
+ member_type = TYPE_UINT;
+ break;
+ case TYPE_MAT2:
+ member_type = TYPE_VEC2;
+ break;
+ default:
+ break;
}
break;
@@ -4180,12 +4180,23 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
switch (expr->get_datatype()) {
- case TYPE_BVEC3: member_type = TYPE_BOOL; break;
- case TYPE_VEC3: member_type = TYPE_FLOAT; break;
- case TYPE_IVEC3: member_type = TYPE_INT; break;
- case TYPE_UVEC3: member_type = TYPE_UINT; break;
- case TYPE_MAT3: member_type = TYPE_VEC3; break;
- default: break;
+ case TYPE_BVEC3:
+ member_type = TYPE_BOOL;
+ break;
+ case TYPE_VEC3:
+ member_type = TYPE_FLOAT;
+ break;
+ case TYPE_IVEC3:
+ member_type = TYPE_INT;
+ break;
+ case TYPE_UVEC3:
+ member_type = TYPE_UINT;
+ break;
+ case TYPE_MAT3:
+ member_type = TYPE_VEC3;
+ break;
+ default:
+ break;
}
break;
case TYPE_BVEC4:
@@ -4202,12 +4213,23 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
switch (expr->get_datatype()) {
- case TYPE_BVEC4: member_type = TYPE_BOOL; break;
- case TYPE_VEC4: member_type = TYPE_FLOAT; break;
- case TYPE_IVEC4: member_type = TYPE_INT; break;
- case TYPE_UVEC4: member_type = TYPE_UINT; break;
- case TYPE_MAT4: member_type = TYPE_VEC4; break;
- default: break;
+ case TYPE_BVEC4:
+ member_type = TYPE_BOOL;
+ break;
+ case TYPE_VEC4:
+ member_type = TYPE_FLOAT;
+ break;
+ case TYPE_IVEC4:
+ member_type = TYPE_INT;
+ break;
+ case TYPE_UVEC4:
+ member_type = TYPE_UINT;
+ break;
+ case TYPE_MAT4:
+ member_type = TYPE_VEC4;
+ break;
+ default:
+ break;
}
break;
default: {
@@ -4230,7 +4252,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
} else if (tk.type == TK_OP_INCREMENT || tk.type == TK_OP_DECREMENT) {
-
OperatorNode *op = alloc_node<OperatorNode>();
op->op = tk.type == TK_OP_DECREMENT ? OP_POST_DECREMENT : OP_POST_INCREMENT;
op->arguments.push_back(expr);
@@ -4246,7 +4267,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
expr = op;
} else {
-
_set_tkpos(pos2);
break;
}
@@ -4261,43 +4281,103 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
tk = _get_token();
if (is_token_operator(tk.type)) {
-
Expression o;
o.is_op = true;
switch (tk.type) {
-
- case TK_OP_EQUAL: o.op = OP_EQUAL; break;
- case TK_OP_NOT_EQUAL: o.op = OP_NOT_EQUAL; break;
- case TK_OP_LESS: o.op = OP_LESS; break;
- case TK_OP_LESS_EQUAL: o.op = OP_LESS_EQUAL; break;
- case TK_OP_GREATER: o.op = OP_GREATER; break;
- case TK_OP_GREATER_EQUAL: o.op = OP_GREATER_EQUAL; break;
- case TK_OP_AND: o.op = OP_AND; break;
- case TK_OP_OR: o.op = OP_OR; break;
- case TK_OP_ADD: o.op = OP_ADD; break;
- case TK_OP_SUB: o.op = OP_SUB; break;
- case TK_OP_MUL: o.op = OP_MUL; break;
- case TK_OP_DIV: o.op = OP_DIV; break;
- case TK_OP_MOD: o.op = OP_MOD; break;
- case TK_OP_SHIFT_LEFT: o.op = OP_SHIFT_LEFT; break;
- case TK_OP_SHIFT_RIGHT: o.op = OP_SHIFT_RIGHT; break;
- case TK_OP_ASSIGN: o.op = OP_ASSIGN; break;
- case TK_OP_ASSIGN_ADD: o.op = OP_ASSIGN_ADD; break;
- case TK_OP_ASSIGN_SUB: o.op = OP_ASSIGN_SUB; break;
- case TK_OP_ASSIGN_MUL: o.op = OP_ASSIGN_MUL; break;
- case TK_OP_ASSIGN_DIV: o.op = OP_ASSIGN_DIV; break;
- case TK_OP_ASSIGN_MOD: o.op = OP_ASSIGN_MOD; break;
- case TK_OP_ASSIGN_SHIFT_LEFT: o.op = OP_ASSIGN_SHIFT_LEFT; break;
- case TK_OP_ASSIGN_SHIFT_RIGHT: o.op = OP_ASSIGN_SHIFT_RIGHT; break;
- case TK_OP_ASSIGN_BIT_AND: o.op = OP_ASSIGN_BIT_AND; break;
- case TK_OP_ASSIGN_BIT_OR: o.op = OP_ASSIGN_BIT_OR; break;
- case TK_OP_ASSIGN_BIT_XOR: o.op = OP_ASSIGN_BIT_XOR; break;
- case TK_OP_BIT_AND: o.op = OP_BIT_AND; break;
- case TK_OP_BIT_OR: o.op = OP_BIT_OR; break;
- case TK_OP_BIT_XOR: o.op = OP_BIT_XOR; break;
- case TK_QUESTION: o.op = OP_SELECT_IF; break;
- case TK_COLON: o.op = OP_SELECT_ELSE; break;
+ case TK_OP_EQUAL:
+ o.op = OP_EQUAL;
+ break;
+ case TK_OP_NOT_EQUAL:
+ o.op = OP_NOT_EQUAL;
+ break;
+ case TK_OP_LESS:
+ o.op = OP_LESS;
+ break;
+ case TK_OP_LESS_EQUAL:
+ o.op = OP_LESS_EQUAL;
+ break;
+ case TK_OP_GREATER:
+ o.op = OP_GREATER;
+ break;
+ case TK_OP_GREATER_EQUAL:
+ o.op = OP_GREATER_EQUAL;
+ break;
+ case TK_OP_AND:
+ o.op = OP_AND;
+ break;
+ case TK_OP_OR:
+ o.op = OP_OR;
+ break;
+ case TK_OP_ADD:
+ o.op = OP_ADD;
+ break;
+ case TK_OP_SUB:
+ o.op = OP_SUB;
+ break;
+ case TK_OP_MUL:
+ o.op = OP_MUL;
+ break;
+ case TK_OP_DIV:
+ o.op = OP_DIV;
+ break;
+ case TK_OP_MOD:
+ o.op = OP_MOD;
+ break;
+ case TK_OP_SHIFT_LEFT:
+ o.op = OP_SHIFT_LEFT;
+ break;
+ case TK_OP_SHIFT_RIGHT:
+ o.op = OP_SHIFT_RIGHT;
+ break;
+ case TK_OP_ASSIGN:
+ o.op = OP_ASSIGN;
+ break;
+ case TK_OP_ASSIGN_ADD:
+ o.op = OP_ASSIGN_ADD;
+ break;
+ case TK_OP_ASSIGN_SUB:
+ o.op = OP_ASSIGN_SUB;
+ break;
+ case TK_OP_ASSIGN_MUL:
+ o.op = OP_ASSIGN_MUL;
+ break;
+ case TK_OP_ASSIGN_DIV:
+ o.op = OP_ASSIGN_DIV;
+ break;
+ case TK_OP_ASSIGN_MOD:
+ o.op = OP_ASSIGN_MOD;
+ break;
+ case TK_OP_ASSIGN_SHIFT_LEFT:
+ o.op = OP_ASSIGN_SHIFT_LEFT;
+ break;
+ case TK_OP_ASSIGN_SHIFT_RIGHT:
+ o.op = OP_ASSIGN_SHIFT_RIGHT;
+ break;
+ case TK_OP_ASSIGN_BIT_AND:
+ o.op = OP_ASSIGN_BIT_AND;
+ break;
+ case TK_OP_ASSIGN_BIT_OR:
+ o.op = OP_ASSIGN_BIT_OR;
+ break;
+ case TK_OP_ASSIGN_BIT_XOR:
+ o.op = OP_ASSIGN_BIT_XOR;
+ break;
+ case TK_OP_BIT_AND:
+ o.op = OP_BIT_AND;
+ break;
+ case TK_OP_BIT_OR:
+ o.op = OP_BIT_OR;
+ break;
+ case TK_OP_BIT_XOR:
+ o.op = OP_BIT_XOR;
+ break;
+ case TK_QUESTION:
+ o.op = OP_SELECT_IF;
+ break;
+ case TK_COLON:
+ o.op = OP_SELECT_ELSE;
+ break;
default: {
_set_error("Invalid token for operator: " + get_token_text(tk));
return nullptr;
@@ -4315,16 +4395,13 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
/* Reduce the set set of expressions and place them in an operator tree, respecting precedence */
while (expression.size() > 1) {
-
int next_op = -1;
int min_priority = 0xFFFFF;
bool is_unary = false;
bool is_ternary = false;
for (int i = 0; i < expression.size(); i++) {
-
if (!expression[i].is_op) {
-
continue;
}
@@ -4333,14 +4410,30 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
int priority;
switch (expression[i].op) {
- case OP_EQUAL: priority = 8; break;
- case OP_NOT_EQUAL: priority = 8; break;
- case OP_LESS: priority = 7; break;
- case OP_LESS_EQUAL: priority = 7; break;
- case OP_GREATER: priority = 7; break;
- case OP_GREATER_EQUAL: priority = 7; break;
- case OP_AND: priority = 12; break;
- case OP_OR: priority = 14; break;
+ case OP_EQUAL:
+ priority = 8;
+ break;
+ case OP_NOT_EQUAL:
+ priority = 8;
+ break;
+ case OP_LESS:
+ priority = 7;
+ break;
+ case OP_LESS_EQUAL:
+ priority = 7;
+ break;
+ case OP_GREATER:
+ priority = 7;
+ break;
+ case OP_GREATER_EQUAL:
+ priority = 7;
+ break;
+ case OP_AND:
+ priority = 12;
+ break;
+ case OP_OR:
+ priority = 14;
+ break;
case OP_NOT:
priority = 3;
unary = true;
@@ -4349,27 +4442,69 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
priority = 3;
unary = true;
break;
- case OP_ADD: priority = 5; break;
- case OP_SUB: priority = 5; break;
- case OP_MUL: priority = 4; break;
- case OP_DIV: priority = 4; break;
- case OP_MOD: priority = 4; break;
- case OP_SHIFT_LEFT: priority = 6; break;
- case OP_SHIFT_RIGHT: priority = 6; break;
- case OP_ASSIGN: priority = 16; break;
- case OP_ASSIGN_ADD: priority = 16; break;
- case OP_ASSIGN_SUB: priority = 16; break;
- case OP_ASSIGN_MUL: priority = 16; break;
- case OP_ASSIGN_DIV: priority = 16; break;
- case OP_ASSIGN_MOD: priority = 16; break;
- case OP_ASSIGN_SHIFT_LEFT: priority = 16; break;
- case OP_ASSIGN_SHIFT_RIGHT: priority = 16; break;
- case OP_ASSIGN_BIT_AND: priority = 16; break;
- case OP_ASSIGN_BIT_OR: priority = 16; break;
- case OP_ASSIGN_BIT_XOR: priority = 16; break;
- case OP_BIT_AND: priority = 9; break;
- case OP_BIT_OR: priority = 11; break;
- case OP_BIT_XOR: priority = 10; break;
+ case OP_ADD:
+ priority = 5;
+ break;
+ case OP_SUB:
+ priority = 5;
+ break;
+ case OP_MUL:
+ priority = 4;
+ break;
+ case OP_DIV:
+ priority = 4;
+ break;
+ case OP_MOD:
+ priority = 4;
+ break;
+ case OP_SHIFT_LEFT:
+ priority = 6;
+ break;
+ case OP_SHIFT_RIGHT:
+ priority = 6;
+ break;
+ case OP_ASSIGN:
+ priority = 16;
+ break;
+ case OP_ASSIGN_ADD:
+ priority = 16;
+ break;
+ case OP_ASSIGN_SUB:
+ priority = 16;
+ break;
+ case OP_ASSIGN_MUL:
+ priority = 16;
+ break;
+ case OP_ASSIGN_DIV:
+ priority = 16;
+ break;
+ case OP_ASSIGN_MOD:
+ priority = 16;
+ break;
+ case OP_ASSIGN_SHIFT_LEFT:
+ priority = 16;
+ break;
+ case OP_ASSIGN_SHIFT_RIGHT:
+ priority = 16;
+ break;
+ case OP_ASSIGN_BIT_AND:
+ priority = 16;
+ break;
+ case OP_ASSIGN_BIT_OR:
+ priority = 16;
+ break;
+ case OP_ASSIGN_BIT_XOR:
+ priority = 16;
+ break;
+ case OP_BIT_AND:
+ priority = 9;
+ break;
+ case OP_BIT_OR:
+ priority = 11;
+ break;
+ case OP_BIT_XOR:
+ priority = 10;
+ break;
case OP_BIT_INVERT:
priority = 3;
unary = true;
@@ -4410,10 +4545,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
// OK! create operator..
// OK! create operator..
if (is_unary) {
-
int expr_pos = next_op;
while (expression[expr_pos].is_op) {
-
expr_pos++;
if (expr_pos == expression.size()) {
//can happen..
@@ -4424,11 +4557,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
//consecutively do unary operators
for (int i = expr_pos - 1; i >= next_op; i--) {
-
OperatorNode *op = alloc_node<OperatorNode>();
op->op = expression[i].op;
if ((op->op == OP_INCREMENT || op->op == OP_DECREMENT) && !_validate_assign(expression[i + 1].node, p_builtin_types)) {
-
_set_error("Can't use increment/decrement operator in constant expression.");
return nullptr;
}
@@ -4438,11 +4569,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expression.write[i].node = op;
if (!_validate_operator(op, &op->return_cache)) {
-
String at;
for (int j = 0; j < op->arguments.size(); j++) {
- if (j > 0)
+ if (j > 0) {
at += " and ";
+ }
at += get_datatype_name(op->arguments[j]->get_datatype());
}
_set_error("Invalid arguments to unary operator '" + get_operator_text(op->op) + "' :" + at);
@@ -4452,7 +4583,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
} else if (is_ternary) {
-
if (next_op < 1 || next_op >= (expression.size() - 1)) {
_set_error("Parser bug...");
ERR_FAIL_V(nullptr);
@@ -4472,11 +4602,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expression.write[next_op - 1].is_op = false;
expression.write[next_op - 1].node = op;
if (!_validate_operator(op, &op->return_cache)) {
-
String at;
for (int i = 0; i < op->arguments.size(); i++) {
- if (i > 0)
+ if (i > 0) {
at += " and ";
+ }
at += get_datatype_name(op->arguments[i]->get_datatype());
}
_set_error("Invalid argument to ternary ?: operator: " + at);
@@ -4488,7 +4618,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
} else {
-
if (next_op < 1 || next_op >= (expression.size() - 1)) {
_set_error("Parser bug...");
ERR_FAIL_V(nullptr);
@@ -4498,16 +4627,13 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
op->op = expression[next_op].op;
if (expression[next_op - 1].is_op) {
-
_set_error("Parser bug...");
ERR_FAIL_V(nullptr);
}
if (_is_operator_assign(op->op)) {
-
String assign_message;
if (!_validate_assign(expression[next_op - 1].node, p_builtin_types, &assign_message)) {
-
_set_error(assign_message);
return nullptr;
}
@@ -4529,11 +4655,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
//replace all 3 nodes by this operator and make it an expression
if (!_validate_operator(op, &op->return_cache)) {
-
String at;
for (int i = 0; i < op->arguments.size(); i++) {
- if (i > 0)
+ if (i > 0) {
at += " and ";
+ }
if (op->arguments[i]->get_datatype() == TYPE_STRUCT) {
at += op->arguments[i]->get_datatype_name();
} else {
@@ -4553,15 +4679,14 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
}
ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, ShaderLanguage::Node *p_node) {
-
- if (p_node->type != Node::TYPE_OPERATOR)
+ if (p_node->type != Node::TYPE_OPERATOR) {
return p_node;
+ }
//for now only reduce simple constructors
OperatorNode *op = static_cast<OperatorNode *>(p_node);
if (op->op == OP_CONSTRUCT) {
-
ERR_FAIL_COND_V(op->arguments[0]->type != Node::TYPE_VARIABLE, p_node);
DataType type = op->get_datatype();
@@ -4571,7 +4696,6 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
Vector<ConstantNode::Value> values;
for (int i = 1; i < op->arguments.size(); i++) {
-
op->arguments.write[i] = _reduce_expression(p_block, op->arguments[i]);
if (op->arguments[i]->type == Node::TYPE_CONSTANT) {
ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[i]);
@@ -4581,7 +4705,6 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
values.push_back(cn->values[j]);
}
} else if (get_scalar_type(cn->datatype) == cn->datatype) {
-
ConstantNode::Value v;
if (!convert_constant(cn, base, &v)) {
return p_node;
@@ -4625,10 +4748,8 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
cn->values = values;
return cn;
} else if (op->op == OP_NEGATE) {
-
op->arguments.write[0] = _reduce_expression(p_block, op->arguments[0]);
if (op->arguments[0]->type == Node::TYPE_CONSTANT) {
-
ConstantNode *cn = static_cast<ConstantNode *>(op->arguments[0]);
DataType base = get_scalar_type(cn->datatype);
@@ -4636,7 +4757,6 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
Vector<ConstantNode::Value> values;
for (int i = 0; i < cn->values.size(); i++) {
-
ConstantNode::Value nv;
switch (base) {
case TYPE_BOOL: {
@@ -4668,10 +4788,10 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
}
ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) {
-
ShaderLanguage::Node *expr = _parse_expression(p_block, p_builtin_types);
- if (!expr) //errored
+ if (!expr) { //errored
return nullptr;
+ }
expr = _reduce_expression(p_block, expr);
@@ -4679,9 +4799,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_and_reduce_expression(BlockNode *p_
}
Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, bool p_just_one, bool p_can_break, bool p_can_continue) {
-
while (true) {
-
TkPos pos = _get_tkpos();
Token tk = _get_token();
@@ -4757,7 +4875,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
Node *vardecl = nullptr;
while (true) {
-
if (tk.type != TK_IDENTIFIER) {
_set_error("Expected identifier after type");
return ERR_PARSE_ERROR;
@@ -4810,7 +4927,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
if (tk.type == TK_BRACKET_CLOSE) {
unknown_size = true;
} else {
-
if (tk.type != TK_INT_CONSTANT || ((int)tk.constant) <= 0) {
_set_error("Expected integer constant > 0 or ']'");
return ERR_PARSE_ERROR;
@@ -4830,7 +4946,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
tk = _get_token();
if (tk.type == TK_OP_ASSIGN) {
-
if (RenderingServer::get_singleton()->is_low_end()) {
_set_error("Array initialization is supported only on high-end platform!");
return ERR_PARSE_ERROR;
@@ -4839,7 +4954,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
tk = _get_token();
if (tk.type != TK_CURLY_BRACKET_OPEN) {
-
if (unknown_size) {
_set_error("Expected '{'");
return ERR_PARSE_ERROR;
@@ -4968,7 +5082,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
while (true) {
-
Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
if (!n) {
return ERR_PARSE_ERROR;
@@ -4995,10 +5108,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
decl.initializer.push_back(n);
break;
} else {
- if (curly)
+ if (curly) {
_set_error("Expected '}' or ','");
- else
+ } else {
_set_error("Expected ')' or ','");
+ }
return ERR_PARSE_ERROR;
}
}
@@ -5024,7 +5138,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
node->declarations.push_back(decl);
} else if (tk.type == TK_OP_ASSIGN) {
-
VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>();
if (is_struct) {
node->struct_name = struct_name;
@@ -5042,8 +5155,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
//variable created with assignment! must parse an expression
Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
- if (!n)
+ if (!n) {
return ERR_PARSE_ERROR;
+ }
if (node->is_const && n->type == Node::TYPE_OPERATOR && ((OperatorNode *)n)->op == OP_CALL) {
_set_error("Expected constant expression after '='");
return ERR_PARSE_ERROR;
@@ -5115,8 +5229,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
cf->flow_op = FLOW_OP_IF;
Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
- if (!n)
+ if (!n) {
return ERR_PARSE_ERROR;
+ }
if (n->get_datatype() != TYPE_BOOL) {
_set_error("Expected boolean expression");
@@ -5136,13 +5251,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
p_block->statements.push_back(cf);
Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
- if (err)
+ if (err) {
return err;
+ }
pos = _get_tkpos();
tk = _get_token();
if (tk.type == TK_CF_ELSE) {
-
block = alloc_node<BlockNode>();
block->parent_block = p_block;
cf->blocks.push_back(block);
@@ -5152,7 +5267,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
_set_tkpos(pos); //rollback
}
} else if (tk.type == TK_CF_SWITCH) {
-
if (RenderingServer::get_singleton()->is_low_end()) {
_set_error("\"switch\" operator is supported only on high-end platform!");
return ERR_PARSE_ERROR;
@@ -5167,8 +5281,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
ControlFlowNode *cf = alloc_node<ControlFlowNode>();
cf->flow_op = FLOW_OP_SWITCH;
Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
- if (!n)
+ if (!n) {
return ERR_PARSE_ERROR;
+ }
if (n->get_datatype() != TYPE_INT) {
_set_error("Expected integer expression");
return ERR_PARSE_ERROR;
@@ -5295,13 +5410,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
p_block->statements.push_back(cf);
Error err = _parse_block(case_block, p_builtin_types, false, true, false);
- if (err)
+ if (err) {
return err;
+ }
return OK;
} else if (tk.type == TK_CF_DEFAULT) {
-
if (p_block && p_block->block_type == BlockNode::BLOCK_TYPE_CASE) {
_set_tkpos(pos);
return OK;
@@ -5329,8 +5444,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
p_block->statements.push_back(cf);
Error err = _parse_block(default_block, p_builtin_types, false, true, false);
- if (err)
+ if (err) {
return err;
+ }
return OK;
@@ -5341,13 +5457,13 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
BlockNode *do_block = nullptr;
if (is_do) {
-
do_block = alloc_node<BlockNode>();
do_block->parent_block = p_block;
Error err = _parse_block(do_block, p_builtin_types, true, true, true);
- if (err)
+ if (err) {
return err;
+ }
tk = _get_token();
if (tk.type != TK_CF_WHILE) {
@@ -5369,8 +5485,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->flow_op = FLOW_OP_WHILE;
}
Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
- if (!n)
+ if (!n) {
return ERR_PARSE_ERROR;
+ }
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
@@ -5385,10 +5502,10 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
p_block->statements.push_back(cf);
Error err = _parse_block(block, p_builtin_types, true, true, true);
- if (err)
+ if (err) {
return err;
+ }
} else {
-
cf->expressions.push_back(n);
cf->blocks.push_back(do_block);
p_block->statements.push_back(cf);
@@ -5420,8 +5537,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
Node *n = _parse_and_reduce_expression(init_block, p_builtin_types);
- if (!n)
+ if (!n) {
return ERR_PARSE_ERROR;
+ }
if (n->get_datatype() != TYPE_BOOL) {
_set_error("Middle expression is expected to be boolean.");
@@ -5437,8 +5555,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
cf->expressions.push_back(n);
n = _parse_and_reduce_expression(init_block, p_builtin_types);
- if (!n)
+ if (!n) {
return ERR_PARSE_ERROR;
+ }
cf->expressions.push_back(n);
@@ -5454,11 +5573,11 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
p_block->statements.push_back(cf);
Error err = _parse_block(block, p_builtin_types, true, true, true);
- if (err)
+ if (err) {
return err;
+ }
} else if (tk.type == TK_CF_RETURN) {
-
//check return type
BlockNode *b = p_block;
while (b && !b->parent_function) {
@@ -5484,8 +5603,9 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
} else {
_set_tkpos(pos); //rollback, wants expression
Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types);
- if (!expr)
+ if (!expr) {
return ERR_PARSE_ERROR;
+ }
if (b->parent_function->return_type != expr->get_datatype()) {
_set_error("Expected return expression of type '" + get_datatype_name(b->parent_function->return_type) + "'");
@@ -5511,7 +5631,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
block = block->parent_block;
}
} else if (tk.type == TK_CF_DISCARD) {
-
//check return type
BlockNode *b = p_block;
while (b && !b->parent_function) {
@@ -5539,7 +5658,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
p_block->statements.push_back(flow);
} else if (tk.type == TK_CF_BREAK) {
-
if (!p_can_break) {
//all is good
_set_error("Breaking is not allowed here");
@@ -5566,7 +5684,6 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
} else if (tk.type == TK_CF_CONTINUE) {
-
if (!p_can_continue) {
//all is good
_set_error("Continuing is not allowed here");
@@ -5585,12 +5702,12 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
p_block->statements.push_back(flow);
} else {
-
//nothing else, so expression
_set_tkpos(pos); //rollback
Node *expr = _parse_and_reduce_expression(p_block, p_builtin_types);
- if (!expr)
+ if (!expr) {
return ERR_PARSE_ERROR;
+ }
p_block->statements.push_back(expr);
tk = _get_token();
@@ -5600,15 +5717,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui
}
}
- if (p_just_one)
+ if (p_just_one) {
break;
+ }
}
return OK;
}
String ShaderLanguage::_get_shader_type_list(const Set<String> &p_shader_types) const {
-
// Return a list of shader types as an human-readable string
String valid_types;
for (const Set<String>::Element *E = p_shader_types.front(); E; E = E->next()) {
@@ -5664,7 +5781,6 @@ Error ShaderLanguage::_validate_datatype(DataType p_type) {
}
Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types) {
-
Token tk = _get_token();
if (tk.type != TK_SHADER_TYPE) {
@@ -5702,12 +5818,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
while (tk.type != TK_EOF) {
-
switch (tk.type) {
case TK_RENDER_MODE: {
-
while (true) {
-
StringName mode;
_get_completable_identifier(nullptr, COMPLETION_RENDER_MODE, mode);
@@ -5869,7 +5982,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} break;
case TK_GLOBAL: {
-
tk = _get_token();
if (tk.type != TK_UNIFORM) {
_set_error("Expected 'uniform' after 'global'");
@@ -5891,7 +6003,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
[[fallthrough]];
case TK_UNIFORM:
case TK_VARYING: {
-
bool uniform = tk.type == TK_UNIFORM;
DataPrecision precision = PRECISION_DEFAULT;
DataInterpolation interpolation = INTERPOLATION_SMOOTH;
@@ -5945,7 +6056,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (uniform) {
-
if (uniform_scope == ShaderNode::Uniform::SCOPE_GLOBAL) {
//validate global uniform
DataType gvtype = global_var_get_type_func(name);
@@ -5972,7 +6082,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
} else {
- if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) {
+ if (uniform_scope == ShaderNode::Uniform::SCOPE_INSTANCE && (type == TYPE_MAT2 || type == TYPE_MAT3 || type == TYPE_MAT4)) {
_set_error("Uniforms with 'instance' qualifiers can't be of matrix type.");
return ERR_PARSE_ERROR;
}
@@ -6025,7 +6135,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
uniform2.hint = ShaderNode::Uniform::HINT_COLOR;
} else if (tk.type == TK_HINT_RANGE) {
-
uniform2.hint = ShaderNode::Uniform::HINT_RANGE;
if (type != TYPE_FLOAT && type != TYPE_INT) {
_set_error("Range hint is for float and int only");
@@ -6104,7 +6213,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
} else if (tk.type == TK_HINT_INSTANCE_INDEX) {
-
if (custom_instance_index != -1) {
_set_error("Can only specify 'instance_index' once.");
return ERR_PARSE_ERROR;
@@ -6186,10 +6294,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
//reset scope for next uniform
if (tk.type == TK_OP_ASSIGN) {
-
Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>());
- if (!expr)
+ if (!expr) {
return ERR_PARSE_ERROR;
+ }
if (expr->type != Node::TYPE_CONSTANT) {
_set_error("Expected constant expression after '='");
return ERR_PARSE_ERROR;
@@ -6215,7 +6323,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
} else {
-
ShaderNode::Varying varying;
varying.type = type;
varying.precision = precision;
@@ -6281,7 +6388,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
is_struct = true;
struct_name = tk.text;
} else {
-
if (!is_token_datatype(tk.type)) {
_set_error("Expected constant, function, uniform or varying");
return ERR_PARSE_ERROR;
@@ -6334,13 +6440,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
while (true) {
ShaderNode::Constant constant;
+ constant.name = name;
constant.type = is_struct ? TYPE_STRUCT : type;
constant.type_str = struct_name;
constant.precision = precision;
constant.initializer = nullptr;
if (tk.type == TK_OP_ASSIGN) {
-
if (!is_constant) {
_set_error("Expected 'const' keyword before constant definition");
return ERR_PARSE_ERROR;
@@ -6348,8 +6454,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
//variable created with assignment! must parse an expression
Node *expr = _parse_and_reduce_expression(nullptr, Map<StringName, BuiltInInfo>());
- if (!expr)
+ if (!expr) {
return ERR_PARSE_ERROR;
+ }
if (expr->type == Node::TYPE_OPERATOR && ((OperatorNode *)expr)->op == OP_CALL) {
_set_error("Expected constant expression after '='");
return ERR_PARSE_ERROR;
@@ -6373,6 +6480,8 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
shader->constants[name] = constant;
+ shader->vconstants.push_back(constant);
+
if (tk.type == TK_COMMA) {
tk = _get_token();
if (tk.type != TK_IDENTIFIER) {
@@ -6582,11 +6691,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
current_function = name;
Error err = _parse_block(func_node->body, builtin_types);
- if (err)
+ if (err) {
return err;
+ }
if (func_node->return_type != DataType::TYPE_VOID) {
-
BlockNode *block = func_node->body;
if (_find_last_flow_op_in_block(block, FlowOperation::FLOW_OP_RETURN) != OK) {
_set_error("Expected at least one return statement in a non-void function.");
@@ -6604,7 +6713,6 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name) {
-
if (p_functions.has("vertex")) {
if (p_functions["vertex"].built_ins.has(p_name)) {
return true;
@@ -6624,7 +6732,6 @@ bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionI
}
Error ShaderLanguage::_find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op) {
-
bool found = false;
for (int i = p_flow->blocks.size() - 1; i >= 0; i--) {
@@ -6643,11 +6750,9 @@ Error ShaderLanguage::_find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOper
}
Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperation p_op) {
-
bool found = false;
for (int i = p_block->statements.size() - 1; i >= 0; i--) {
-
if (p_block->statements[i]->type == Node::TYPE_CONTROL_FLOW) {
ControlFlowNode *flow = (ControlFlowNode *)p_block->statements[i];
if (flow->flow_op == p_op) {
@@ -6676,7 +6781,6 @@ Error ShaderLanguage::_find_last_flow_op_in_block(BlockNode *p_block, FlowOperat
// skips over whitespace and /* */ and // comments
static int _get_first_ident_pos(const String &p_code) {
-
int idx = 0;
#define GETCHAR(m_idx) (((idx + m_idx) < p_code.length()) ? p_code[idx + m_idx] : CharType(0))
@@ -6685,7 +6789,9 @@ static int _get_first_ident_pos(const String &p_code) {
if (GETCHAR(0) == '/' && GETCHAR(1) == '/') {
idx += 2;
while (true) {
- if (GETCHAR(0) == 0) return 0;
+ if (GETCHAR(0) == 0) {
+ return 0;
+ }
if (GETCHAR(0) == '\n') {
idx++;
break; // loop
@@ -6695,7 +6801,9 @@ static int _get_first_ident_pos(const String &p_code) {
} else if (GETCHAR(0) == '/' && GETCHAR(1) == '*') {
idx += 2;
while (true) {
- if (GETCHAR(0) == 0) return 0;
+ if (GETCHAR(0) == 0) {
+ return 0;
+ }
if (GETCHAR(0) == '*' && GETCHAR(1) == '/') {
idx += 2;
break; // loop
@@ -6720,13 +6828,11 @@ static int _get_first_ident_pos(const String &p_code) {
}
String ShaderLanguage::get_shader_type(const String &p_code) {
-
bool reading_type = false;
String cur_identifier;
for (int i = _get_first_ident_pos(p_code); i < p_code.length(); i++) {
-
if (p_code[i] == ';') {
break;
@@ -6748,14 +6854,14 @@ String ShaderLanguage::get_shader_type(const String &p_code) {
}
}
- if (reading_type)
+ if (reading_type) {
return cur_identifier;
+ }
return String();
}
Error ShaderLanguage::compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func) {
-
clear();
code = p_code;
@@ -6773,7 +6879,6 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi
}
Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, GlobalVariableGetTypeFunc p_global_variable_type_func, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) {
-
clear();
code = p_code;
@@ -6785,7 +6890,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
_parse_shader(p_functions, p_render_modes, p_shader_types);
switch (completion_type) {
-
case COMPLETION_NONE: {
//do nothing
return OK;
@@ -6799,7 +6903,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
return OK;
} break;
case COMPLETION_STRUCT: {
-
if (shader->structs.has(completion_struct)) {
StructNode *node = shader->structs[completion_struct].shader_struct;
for (int i = 0; i < node->members.size(); i++) {
@@ -6811,7 +6914,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
return OK;
} break;
case COMPLETION_MAIN_FUNCTION: {
-
for (const Map<StringName, FunctionInfo>::Element *E = p_functions.front(); E; E = E->next()) {
ScriptCodeCompletionOption option(E->key(), ScriptCodeCompletionOption::KIND_FUNCTION);
r_options->push_back(option);
@@ -6821,7 +6923,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
} break;
case COMPLETION_IDENTIFIER:
case COMPLETION_FUNCTION_CALL: {
-
bool comp_ident = completion_type == COMPLETION_IDENTIFIER;
Map<String, ScriptCodeCompletionOption::Kind> matches;
StringName skip_function;
@@ -6831,7 +6932,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
while (block) {
if (comp_ident) {
for (const Map<StringName, BlockNode::Variable>::Element *E = block->variables.front(); E; E = E->next()) {
-
if (E->get().line < completion_line) {
matches.insert(E->key(), ScriptCodeCompletionOption::KIND_VARIABLE);
}
@@ -6879,8 +6979,9 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
for (int i = 0; i < shader->functions.size(); i++) {
- if (!shader->functions[i].callable || shader->functions[i].name == skip_function)
+ if (!shader->functions[i].callable || shader->functions[i].name == skip_function) {
continue;
+ }
matches.insert(String(shader->functions[i].name), ScriptCodeCompletionOption::KIND_FUNCTION);
}
@@ -6923,12 +7024,11 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
return OK;
} break;
case COMPLETION_CALL_ARGUMENTS: {
-
for (int i = 0; i < shader->functions.size(); i++) {
- if (!shader->functions[i].callable)
+ if (!shader->functions[i].callable) {
continue;
+ }
if (shader->functions[i].name == completion_function) {
-
String calltip;
calltip += get_datatype_name(shader->functions[i].function->return_type);
@@ -6937,11 +7037,11 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
calltip += "(";
for (int j = 0; j < shader->functions[i].function->arguments.size(); j++) {
-
- if (j > 0)
+ if (j > 0) {
calltip += ", ";
- else
+ } else {
calltip += " ";
+ }
if (j == completion_argument) {
calltip += CharType(0xFFFF);
@@ -6964,8 +7064,9 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
}
- if (shader->functions[i].function->arguments.size())
+ if (shader->functions[i].function->arguments.size()) {
calltip += " ";
+ }
calltip += ")";
r_call_hint = calltip;
@@ -6979,7 +7080,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
bool low_end = RenderingServer::get_singleton()->is_low_end();
while (builtin_func_defs[idx].name) {
-
if (low_end && builtin_func_defs[idx].high_end) {
idx++;
continue;
@@ -6996,14 +7096,14 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
if (completion_function == builtin_func_defs[idx].name) {
-
if (builtin_func_defs[idx].tag != completion_class) {
idx++;
continue;
}
- if (calltip.length())
+ if (calltip.length()) {
calltip += "\n";
+ }
calltip += get_datatype_name(builtin_func_defs[idx].rettype);
calltip += " ";
@@ -7012,14 +7112,15 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
bool found_arg = false;
for (int i = 0; i < 4; i++) {
-
- if (builtin_func_defs[idx].args[i] == TYPE_VOID)
+ if (builtin_func_defs[idx].args[i] == TYPE_VOID) {
break;
+ }
- if (i > 0)
+ if (i > 0) {
calltip += ", ";
- else
+ } else {
calltip += " ";
+ }
if (i == completion_argument) {
calltip += CharType(0xFFFF);
@@ -7038,8 +7139,9 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
found_arg = true;
}
- if (found_arg)
+ if (found_arg) {
calltip += " ";
+ }
calltip += ")";
}
idx++;
@@ -7051,7 +7153,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
} break;
case COMPLETION_INDEX: {
-
const char colv[4] = { 'r', 'g', 'b', 'a' };
const char coordv[4] = { 'x', 'y', 'z', 'w' };
const char coordt[4] = { 's', 't', 'p', 'q' };
@@ -7070,7 +7171,6 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
case TYPE_IVEC3:
case TYPE_UVEC3:
case TYPE_VEC3: {
-
limit = 3;
} break;
@@ -7078,13 +7178,18 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
case TYPE_IVEC4:
case TYPE_UVEC4:
case TYPE_VEC4: {
-
limit = 4;
} break;
- case TYPE_MAT2: limit = 2; break;
- case TYPE_MAT3: limit = 3; break;
- case TYPE_MAT4: limit = 4; break;
+ case TYPE_MAT2:
+ limit = 2;
+ break;
+ case TYPE_MAT3:
+ limit = 3;
+ break;
+ case TYPE_MAT4:
+ limit = 4;
+ break;
default: {
}
}
@@ -7102,27 +7207,22 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
String ShaderLanguage::get_error_text() {
-
return error_str;
}
int ShaderLanguage::get_error_line() {
-
return error_line;
}
ShaderLanguage::ShaderNode *ShaderLanguage::get_shader() {
-
return shader;
}
ShaderLanguage::ShaderLanguage() {
-
nodes = nullptr;
completion_class = TAG_GLOBAL;
}
ShaderLanguage::~ShaderLanguage() {
-
clear();
}
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index 48f1d1440f..020a5e3e6f 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -40,7 +40,6 @@
#include "core/variant.h"
class ShaderLanguage {
-
public:
enum TokenType {
TK_EMPTY,
@@ -79,6 +78,7 @@ public:
TK_TYPE_ISAMPLER3D,
TK_TYPE_USAMPLER3D,
TK_TYPE_SAMPLERCUBE,
+ TK_TYPE_SAMPLERCUBEARRAY,
TK_INTERPOLATION_FLAT,
TK_INTERPOLATION_SMOOTH,
TK_CONST,
@@ -218,6 +218,7 @@ public:
TYPE_ISAMPLER3D,
TYPE_USAMPLER3D,
TYPE_SAMPLERCUBE,
+ TYPE_SAMPLERCUBEARRAY,
TYPE_STRUCT,
TYPE_MAX
};
@@ -326,7 +327,7 @@ public:
};
struct Node {
- Node *next;
+ Node *next = nullptr;
enum Type {
TYPE_SHADER,
@@ -350,7 +351,6 @@ public:
virtual String get_datatype_name() const { return ""; }
Node(Type t) :
- next(nullptr),
type(t) {}
virtual ~Node() {}
};
@@ -366,41 +366,35 @@ public:
Node *nodes;
struct OperatorNode : public Node {
- DataType return_cache;
- DataPrecision return_precision_cache;
- Operator op;
+ DataType return_cache = TYPE_VOID;
+ DataPrecision return_precision_cache = PRECISION_DEFAULT;
+ Operator op = OP_EQUAL;
StringName struct_name;
Vector<Node *> arguments;
virtual DataType get_datatype() const { return return_cache; }
virtual String get_datatype_name() const { return String(struct_name); }
OperatorNode() :
- Node(TYPE_OPERATOR),
- return_cache(TYPE_VOID),
- return_precision_cache(PRECISION_DEFAULT),
- op(OP_EQUAL),
- struct_name("") {}
+ Node(TYPE_OPERATOR) {}
};
struct VariableNode : public Node {
- DataType datatype_cache;
+ DataType datatype_cache = TYPE_VOID;
StringName name;
StringName struct_name;
virtual DataType get_datatype() const { return datatype_cache; }
virtual String get_datatype_name() const { return String(struct_name); }
- bool is_const;
+ bool is_const = false;
VariableNode() :
- Node(TYPE_VARIABLE),
- datatype_cache(TYPE_VOID),
- is_const(false) {}
+ Node(TYPE_VARIABLE) {}
};
struct VariableDeclarationNode : public Node {
- DataPrecision precision;
- DataType datatype;
+ DataPrecision precision = PRECISION_DEFAULT;
+ DataType datatype = TYPE_VOID;
String struct_name;
- bool is_const;
+ bool is_const = false;
struct Declaration {
StringName name;
@@ -411,47 +405,38 @@ public:
virtual DataType get_datatype() const { return datatype; }
VariableDeclarationNode() :
- Node(TYPE_VARIABLE_DECLARATION),
- precision(PRECISION_DEFAULT),
- datatype(TYPE_VOID),
- is_const(false) {}
+ Node(TYPE_VARIABLE_DECLARATION) {}
};
struct ArrayNode : public Node {
- DataType datatype_cache;
+ DataType datatype_cache = TYPE_VOID;
StringName struct_name;
StringName name;
- Node *index_expression;
- Node *call_expression;
- bool is_const;
+ Node *index_expression = nullptr;
+ Node *call_expression = nullptr;
+ bool is_const = false;
virtual DataType get_datatype() const { return datatype_cache; }
virtual String get_datatype_name() const { return String(struct_name); }
ArrayNode() :
- Node(TYPE_ARRAY),
- datatype_cache(TYPE_VOID),
- index_expression(nullptr),
- call_expression(nullptr),
- is_const(false) {}
+ Node(TYPE_ARRAY) {}
};
struct ArrayConstructNode : public Node {
- DataType datatype;
+ DataType datatype = TYPE_VOID;
String struct_name;
Vector<Node *> initializer;
ArrayConstructNode() :
- Node(TYPE_ARRAY_CONSTRUCT),
- datatype(TYPE_VOID) {
- }
+ Node(TYPE_ARRAY_CONSTRUCT) {}
};
struct ArrayDeclarationNode : public Node {
- DataPrecision precision;
- DataType datatype;
+ DataPrecision precision = PRECISION_DEFAULT;
+ DataType datatype = TYPE_VOID;
String struct_name;
- bool is_const;
+ bool is_const = false;
struct Declaration {
StringName name;
@@ -463,14 +448,11 @@ public:
virtual DataType get_datatype() const { return datatype; }
ArrayDeclarationNode() :
- Node(TYPE_ARRAY_DECLARATION),
- precision(PRECISION_DEFAULT),
- datatype(TYPE_VOID),
- is_const(false) {}
+ Node(TYPE_ARRAY_DECLARATION) {}
};
struct ConstantNode : public Node {
- DataType datatype;
+ DataType datatype = TYPE_VOID;
union Value {
bool boolean;
@@ -483,15 +465,14 @@ public:
virtual DataType get_datatype() const { return datatype; }
ConstantNode() :
- Node(TYPE_CONSTANT),
- datatype(TYPE_VOID) {}
+ Node(TYPE_CONSTANT) {}
};
struct FunctionNode;
struct BlockNode : public Node {
- FunctionNode *parent_function;
- BlockNode *parent_block;
+ FunctionNode *parent_function = nullptr;
+ BlockNode *parent_block = nullptr;
enum BlockType {
BLOCK_TYPE_STANDART,
@@ -501,8 +482,8 @@ public:
BLOCK_TYPE_DEFAULT,
};
- int block_type;
- SubClassTag block_tag;
+ int block_type = BLOCK_TYPE_STANDART;
+ SubClassTag block_tag = SubClassTag::TAG_GLOBAL;
struct Variable {
DataType type;
@@ -515,63 +496,48 @@ public:
Map<StringName, Variable> variables;
List<Node *> statements;
- bool single_statement;
+ bool single_statement = false;
BlockNode() :
- Node(TYPE_BLOCK),
- parent_function(nullptr),
- parent_block(nullptr),
- block_type(BLOCK_TYPE_STANDART),
- block_tag(SubClassTag::TAG_GLOBAL),
- single_statement(false) {}
+ Node(TYPE_BLOCK) {}
};
struct ControlFlowNode : public Node {
- FlowOperation flow_op;
+ FlowOperation flow_op = FLOW_OP_IF;
Vector<Node *> expressions;
Vector<BlockNode *> blocks;
ControlFlowNode() :
- Node(TYPE_CONTROL_FLOW),
- flow_op(FLOW_OP_IF) {}
+ Node(TYPE_CONTROL_FLOW) {}
};
struct MemberNode : public Node {
- DataType basetype;
- bool basetype_const;
+ DataType basetype = TYPE_VOID;
+ bool basetype_const = false;
StringName base_struct_name;
DataPrecision precision;
- DataType datatype;
- int array_size;
+ DataType datatype = TYPE_VOID;
+ int array_size = 0;
StringName struct_name;
StringName name;
- Node *owner;
- Node *index_expression;
- bool has_swizzling_duplicates;
+ Node *owner = nullptr;
+ Node *index_expression = nullptr;
+ bool has_swizzling_duplicates = false;
virtual DataType get_datatype() const { return datatype; }
virtual String get_datatype_name() const { return String(struct_name); }
MemberNode() :
- Node(TYPE_MEMBER),
- basetype(TYPE_VOID),
- basetype_const(false),
- datatype(TYPE_VOID),
- array_size(0),
- owner(nullptr),
- index_expression(nullptr),
- has_swizzling_duplicates(false) {}
+ Node(TYPE_MEMBER) {}
};
struct StructNode : public Node {
-
List<MemberNode *> members;
StructNode() :
Node(TYPE_STRUCT) {}
};
struct FunctionNode : public Node {
-
struct Argument {
ArgumentQualifier qualifier;
StringName name;
@@ -589,24 +555,20 @@ public:
};
StringName name;
- DataType return_type;
+ DataType return_type = TYPE_VOID;
StringName return_struct_name;
- DataPrecision return_precision;
+ DataPrecision return_precision = PRECISION_DEFAULT;
Vector<Argument> arguments;
- BlockNode *body;
- bool can_discard;
+ BlockNode *body = nullptr;
+ bool can_discard = false;
FunctionNode() :
- Node(TYPE_FUNCTION),
- return_type(TYPE_VOID),
- return_precision(PRECISION_DEFAULT),
- body(nullptr),
- can_discard(false) {}
+ Node(TYPE_FUNCTION) {}
};
struct ShaderNode : public Node {
-
struct Constant {
+ StringName name;
DataType type;
StringName type_str;
DataPrecision precision;
@@ -626,16 +588,12 @@ public:
};
struct Varying {
- DataType type;
- DataInterpolation interpolation;
- DataPrecision precision;
- int array_size;
+ DataType type = TYPE_VOID;
+ DataInterpolation interpolation = INTERPOLATION_FLAT;
+ DataPrecision precision = PRECISION_DEFAULT;
+ int array_size = 0;
- Varying() :
- type(TYPE_VOID),
- interpolation(INTERPOLATION_FLAT),
- precision(PRECISION_DEFAULT),
- array_size(0) {}
+ Varying() {}
};
struct Uniform {
@@ -664,27 +622,19 @@ public:
SCOPE_GLOBAL,
};
- int order;
- int texture_order;
- DataType type;
- DataPrecision precision;
+ int order = 0;
+ int texture_order = 0;
+ DataType type = TYPE_VOID;
+ DataPrecision precision = PRECISION_DEFAULT;
Vector<ConstantNode::Value> default_value;
- Scope scope;
- Hint hint;
- TextureFilter filter;
- TextureRepeat repeat;
+ Scope scope = SCOPE_LOCAL;
+ Hint hint = HINT_NONE;
+ TextureFilter filter = FILTER_DEFAULT;
+ TextureRepeat repeat = REPEAT_DEFAULT;
float hint_range[3];
- int instance_index;
-
- Uniform() :
- order(0),
- texture_order(0),
- type(TYPE_VOID),
- precision(PRECISION_DEFAULT),
- hint(HINT_NONE),
- filter(FILTER_DEFAULT),
- repeat(REPEAT_DEFAULT),
- instance_index(0) {
+ int instance_index = 0;
+
+ Uniform() {
hint_range[0] = 0.0f;
hint_range[1] = 1.0f;
hint_range[2] = 0.001f;
@@ -698,6 +648,7 @@ public:
Vector<StringName> render_modes;
Vector<Function> functions;
+ Vector<Constant> vconstants;
Vector<Struct> vstructs;
ShaderNode() :
@@ -763,12 +714,10 @@ public:
static void get_builtin_funcs(List<String> *r_keywords);
struct BuiltInInfo {
- DataType type;
- bool constant;
+ DataType type = TYPE_VOID;
+ bool constant = false;
- BuiltInInfo() :
- type(TYPE_VOID),
- constant(false) {}
+ BuiltInInfo() {}
BuiltInInfo(DataType p_type, bool p_constant = false) :
type(p_type),
@@ -821,8 +770,9 @@ private:
}
void _set_error(const String &p_str) {
- if (error_set)
+ if (error_set) {
return;
+ }
error_line = tk_line;
error_set = true;
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index 78bbd73db4..2601efa9e2 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -31,12 +31,10 @@
#include "shader_types.h"
const Map<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(RS::ShaderMode p_mode) {
-
return shader_modes[p_mode].functions;
}
const Vector<StringName> &ShaderTypes::get_modes(RS::ShaderMode p_mode) {
-
return shader_modes[p_mode].modes;
}
@@ -47,7 +45,6 @@ const Set<String> &ShaderTypes::get_types() {
ShaderTypes *ShaderTypes::singleton = nullptr;
static ShaderLanguage::BuiltInInfo constt(ShaderLanguage::DataType p_type) {
-
return ShaderLanguage::BuiltInInfo(p_type, true);
}
diff --git a/servers/rendering/shader_types.h b/servers/rendering/shader_types.h
index 499a761265..7d8057a5c6 100644
--- a/servers/rendering/shader_types.h
+++ b/servers/rendering/shader_types.h
@@ -36,9 +36,7 @@
#include "shader_language.h"
class ShaderTypes {
-
struct Type {
-
Map<StringName, ShaderLanguage::FunctionInfo> functions;
Vector<StringName> modes;
};
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 0d3b44c0dc..906946f074 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -37,27 +37,24 @@ RenderingServer *RenderingServer::singleton = nullptr;
RenderingServer *(*RenderingServer::create_func)() = nullptr;
RenderingServer *RenderingServer::get_singleton() {
-
return singleton;
}
RenderingServer *RenderingServer::create() {
-
ERR_FAIL_COND_V(singleton, nullptr);
- if (create_func)
+ if (create_func) {
return create_func();
+ }
return nullptr;
}
Array RenderingServer::_texture_debug_usage_bind() {
-
List<TextureInfo> list;
texture_debug_usage(&list);
Array arr;
for (const List<TextureInfo>::Element *E = list.front(); E; E = E->next()) {
-
Dictionary dict;
dict["texture"] = E->get().texture;
dict["width"] = E->get().width;
@@ -72,7 +69,6 @@ Array RenderingServer::_texture_debug_usage_bind() {
}
Array RenderingServer::_shader_get_param_list_bind(RID p_shader) const {
-
List<PropertyInfo> l;
shader_get_param_list(p_shader, &l);
return convert_property_list(&l);
@@ -88,19 +84,16 @@ static Array to_array(const Vector<ObjectID> &ids) {
}
Array RenderingServer::_instances_cull_aabb_bind(const AABB &p_aabb, RID p_scenario) const {
-
Vector<ObjectID> ids = instances_cull_aabb(p_aabb, p_scenario);
return to_array(ids);
}
Array RenderingServer::_instances_cull_ray_bind(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario) const {
-
Vector<ObjectID> ids = instances_cull_ray(p_from, p_to, p_scenario);
return to_array(ids);
}
Array RenderingServer::_instances_cull_convex_bind(const Array &p_convex, RID p_scenario) const {
-
Vector<Plane> planes;
for (int i = 0; i < p_convex.size(); ++i) {
Variant v = p_convex[i];
@@ -113,7 +106,6 @@ Array RenderingServer::_instances_cull_convex_bind(const Array &p_convex, RID p_
}
RID RenderingServer::get_test_texture() {
-
if (test_texture.is_valid()) {
return test_texture;
};
@@ -127,20 +119,16 @@ RID RenderingServer::get_test_texture() {
uint8_t *w = test_data.ptrw();
for (int x = 0; x < TEST_TEXTURE_SIZE; x++) {
-
for (int y = 0; y < TEST_TEXTURE_SIZE; y++) {
-
Color c;
int r = 255 - (x + y) / 2;
if ((x % (TEST_TEXTURE_SIZE / 8)) < 2 || (y % (TEST_TEXTURE_SIZE / 8)) < 2) {
-
c.r = y;
c.g = r;
c.b = x;
} else {
-
c.r = r;
c.g = x;
c.b = y;
@@ -161,17 +149,18 @@ RID RenderingServer::get_test_texture() {
}
void RenderingServer::_free_internal_rids() {
-
- if (test_texture.is_valid())
+ if (test_texture.is_valid()) {
free(test_texture);
- if (white_texture.is_valid())
+ }
+ if (white_texture.is_valid()) {
free(white_texture);
- if (test_material.is_valid())
+ }
+ if (test_material.is_valid()) {
free(test_material);
+ }
}
RID RenderingServer::_make_test_cube() {
-
Vector<Vector3> vertices;
Vector<Vector3> normals;
Vector<float> tangents;
@@ -187,24 +176,22 @@ RID RenderingServer::_make_test_cube() {
uvs.push_back(Vector3(uv_points[m_idx * 2 + 0], uv_points[m_idx * 2 + 1], 0));
for (int i = 0; i < 6; i++) {
-
Vector3 face_points[4];
Vector3 normal_points[4];
float uv_points[8] = { 0, 0, 0, 1, 1, 1, 1, 0 };
for (int j = 0; j < 4; j++) {
-
float v[3];
v[0] = 1.0;
v[1] = 1 - 2 * ((j >> 1) & 1);
v[2] = v[1] * (1 - 2 * (j & 1));
for (int k = 0; k < 3; k++) {
-
- if (i < 3)
+ if (i < 3) {
face_points[j][(i + k) % 3] = v[k];
- else
+ } else {
face_points[3 - j][(i + k) % 3] = -v[k];
+ }
}
normal_points[j] = Vector3();
normal_points[j][i % 3] = (i >= 3 ? -1 : 1);
@@ -231,8 +218,9 @@ RID RenderingServer::_make_test_cube() {
Vector<int> indices;
indices.resize(vertices.size());
- for (int i = 0; i < vertices.size(); i++)
+ for (int i = 0; i < vertices.size(); i++) {
indices.set(i, i);
+ }
d[RenderingServer::ARRAY_INDEX] = indices;
mesh_add_surface_from_arrays(test_cube, PRIMITIVE_TRIANGLES, d);
@@ -253,7 +241,6 @@ RID RenderingServer::_make_test_cube() {
}
RID RenderingServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) {
-
Vector<Vector3> vertices;
Vector<Vector3> normals;
@@ -267,7 +254,6 @@ RID RenderingServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) {
double zr1 = Math::cos(lat1);
for (int j = p_lons; j >= 1; j--) {
-
double lng0 = 2 * Math_PI * (double)(j - 1) / p_lons;
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
@@ -310,16 +296,17 @@ RID RenderingServer::make_sphere_mesh(int p_lats, int p_lons, float p_radius) {
}
RID RenderingServer::get_white_texture() {
-
- if (white_texture.is_valid())
+ if (white_texture.is_valid()) {
return white_texture;
+ }
Vector<uint8_t> wt;
wt.resize(16 * 3);
{
uint8_t *w = wt.ptrw();
- for (int i = 0; i < 16 * 3; i++)
+ for (int i = 0; i < 16 * 3; i++) {
w[i] = 255;
+ }
}
Ref<Image> white = memnew(Image(4, 4, 0, Image::FORMAT_RGB8, wt));
white_texture = texture_2d_create(white);
@@ -330,7 +317,6 @@ RID RenderingServer::get_white_texture() {
#define SMALL_VEC3 Vector3(0.00001, 0.00001, 0.00001)
Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_stride, Vector<uint8_t> &r_vertex_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb) {
-
uint8_t *vw = r_vertex_array.ptrw();
uint8_t *iw = nullptr;
@@ -341,16 +327,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
int max_bone = 0;
for (int ai = 0; ai < RS::ARRAY_MAX; ai++) {
-
- if (!(p_format & (1 << ai))) // no array
+ if (!(p_format & (1 << ai))) { // no array
continue;
+ }
switch (ai) {
-
case RS::ARRAY_VERTEX: {
-
if (p_format & RS::ARRAY_FLAG_USE_2D_VERTICES) {
-
Vector<Vector2> array = p_arrays[ai];
ERR_FAIL_COND_V(array.size() != p_vertex_array_len, ERR_INVALID_PARAMETER);
@@ -361,16 +344,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
{
for (int i = 0; i < p_vertex_array_len; i++) {
-
float vector[2] = { src[i].x, src[i].y };
copymem(&vw[p_offsets[ai] + i * p_stride], vector, sizeof(float) * 2);
if (i == 0) {
-
aabb = Rect2(src[i], SMALL_VEC2); //must have a bit of size
} else {
-
aabb.expand_to(src[i]);
}
}
@@ -389,16 +369,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
{
for (int i = 0; i < p_vertex_array_len; i++) {
-
float vector[3] = { src[i].x, src[i].y, src[i].z };
copymem(&vw[p_offsets[ai] + i * p_stride], vector, sizeof(float) * 3);
if (i == 0) {
-
aabb = AABB(src[i], SMALL_VEC3);
} else {
-
aabb.expand_to(src[i]);
}
}
@@ -409,7 +386,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} break;
case RS::ARRAY_NORMAL: {
-
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_VECTOR3_ARRAY, ERR_INVALID_PARAMETER);
Vector<Vector3> array = p_arrays[ai];
@@ -420,9 +396,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
// setting vertices means regenerating the AABB
if (p_format & ARRAY_COMPRESS_NORMAL) {
-
for (int i = 0; i < p_vertex_array_len; i++) {
-
int8_t vector[4] = {
(int8_t)CLAMP(src[i].x * 127, -128, 127),
(int8_t)CLAMP(src[i].y * 127, -128, 127),
@@ -435,7 +409,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} else {
for (int i = 0; i < p_vertex_array_len; i++) {
-
float vector[3] = { src[i].x, src[i].y, src[i].z };
copymem(&vw[p_offsets[ai] + i * p_stride], vector, 3 * 4);
}
@@ -444,7 +417,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} break;
case RS::ARRAY_TANGENT: {
-
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER);
Vector<real_t> array = p_arrays[ai];
@@ -454,7 +426,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const real_t *src = array.ptr();
if (p_format & ARRAY_COMPRESS_TANGENT) {
-
for (int i = 0; i < p_vertex_array_len; i++) {
int8_t xyzw[4] = {
(int8_t)CLAMP(src[i * 4 + 0] * 127, -128, 127),
@@ -468,7 +439,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} else {
for (int i = 0; i < p_vertex_array_len; i++) {
-
float xyzw[4] = {
src[i * 4 + 0],
src[i * 4 + 1],
@@ -482,7 +452,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} break;
case RS::ARRAY_COLOR: {
-
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_COLOR_ARRAY, ERR_INVALID_PARAMETER);
Vector<Color> array = p_arrays[ai];
@@ -492,29 +461,23 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const Color *src = array.ptr();
if (p_format & ARRAY_COMPRESS_COLOR) {
-
for (int i = 0; i < p_vertex_array_len; i++) {
-
uint8_t colors[4];
for (int j = 0; j < 4; j++) {
-
colors[j] = CLAMP(int((src[i][j]) * 255.0), 0, 255);
}
copymem(&vw[p_offsets[ai] + i * p_stride], colors, 4);
}
} else {
-
for (int i = 0; i < p_vertex_array_len; i++) {
-
copymem(&vw[p_offsets[ai] + i * p_stride], &src[i], 4 * 4);
}
}
} break;
case RS::ARRAY_TEX_UV: {
-
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_VECTOR3_ARRAY && p_arrays[ai].get_type() != Variant::PACKED_VECTOR2_ARRAY, ERR_INVALID_PARAMETER);
Vector<Vector2> array = p_arrays[ai];
@@ -524,16 +487,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const Vector2 *src = array.ptr();
if (p_format & ARRAY_COMPRESS_TEX_UV) {
-
for (int i = 0; i < p_vertex_array_len; i++) {
-
uint16_t uv[2] = { Math::make_half_float(src[i].x), Math::make_half_float(src[i].y) };
copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 2);
}
} else {
for (int i = 0; i < p_vertex_array_len; i++) {
-
float uv[2] = { src[i].x, src[i].y };
copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 4);
@@ -543,7 +503,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} break;
case RS::ARRAY_TEX_UV2: {
-
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_VECTOR3_ARRAY && p_arrays[ai].get_type() != Variant::PACKED_VECTOR2_ARRAY, ERR_INVALID_PARAMETER);
Vector<Vector2> array = p_arrays[ai];
@@ -553,16 +512,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const Vector2 *src = array.ptr();
if (p_format & ARRAY_COMPRESS_TEX_UV2) {
-
for (int i = 0; i < p_vertex_array_len; i++) {
-
uint16_t uv[2] = { Math::make_half_float(src[i].x), Math::make_half_float(src[i].y) };
copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 2);
}
} else {
for (int i = 0; i < p_vertex_array_len; i++) {
-
float uv[2] = { src[i].x, src[i].y };
copymem(&vw[p_offsets[ai] + i * p_stride], uv, 2 * 4);
@@ -570,7 +526,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
}
} break;
case RS::ARRAY_WEIGHTS: {
-
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER);
Vector<real_t> array = p_arrays[ai];
@@ -580,9 +535,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const real_t *src = array.ptr();
{
-
for (int i = 0; i < p_vertex_array_len; i++) {
-
uint16_t data[RS::ARRAY_WEIGHTS_SIZE];
for (int j = 0; j < RS::ARRAY_WEIGHTS_SIZE; j++) {
data[j] = CLAMP(src[i * RS::ARRAY_WEIGHTS_SIZE + j] * 65535, 0, 65535);
@@ -594,7 +547,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} break;
case RS::ARRAY_BONES: {
-
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_INT32_ARRAY && p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER);
Vector<int> array = p_arrays[ai];
@@ -604,7 +556,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const int *src = array.ptr();
for (int i = 0; i < p_vertex_array_len; i++) {
-
uint16_t data[RS::ARRAY_WEIGHTS_SIZE];
for (int j = 0; j < RS::ARRAY_WEIGHTS_SIZE; j++) {
data[j] = src[i * RS::ARRAY_WEIGHTS_SIZE + j];
@@ -616,7 +567,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} break;
case RS::ARRAY_INDEX: {
-
ERR_FAIL_NULL_V(iw, ERR_INVALID_DATA);
ERR_FAIL_COND_V(p_index_array_len <= 0, ERR_INVALID_DATA);
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_INT32_ARRAY, ERR_INVALID_PARAMETER);
@@ -630,7 +580,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const int *src = indices.ptr();
for (int i = 0; i < p_index_array_len; i++) {
-
if (p_vertex_array_len < (1 << 16)) {
uint16_t v = src[i];
@@ -669,7 +618,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
bool any_valid = false;
if (vertices.size() && bones.size() == vertices.size() * 4 && weights.size() == bones.size()) {
-
int vs = vertices.size();
const Vector3 *rv = vertices.ptr();
const int *rb = bones.ptr();
@@ -678,14 +626,13 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
AABB *bptr = r_bone_aabb.ptrw();
for (int i = 0; i < vs; i++) {
-
Vector3 v = rv[i];
for (int j = 0; j < 4; j++) {
-
int idx = rb[i * 4 + j];
float w = rw[i * 4 + j];
- if (w == 0)
+ if (w == 0) {
continue; //break;
+ }
ERR_FAIL_INDEX_V(idx, total_bones, ERR_INVALID_DATA);
if (bptr[idx].size.x < 0) {
@@ -700,7 +647,6 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
}
if (!any_valid && first) {
-
r_bone_aabb.clear();
}
}
@@ -719,22 +665,19 @@ uint32_t RenderingServer::mesh_surface_get_format_stride(uint32_t p_format, int
}
uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets) const {
-
int total_elem_size = 0;
for (int i = 0; i < RS::ARRAY_MAX; i++) {
-
r_offsets[i] = 0; //reset
- if (!(p_format & (1 << i))) // no array
+ if (!(p_format & (1 << i))) { // no array
continue;
+ }
int elem_size = 0;
switch (i) {
-
case RS::ARRAY_VERTEX: {
-
if (p_format & ARRAY_FLAG_USE_2D_VERTICES) {
elem_size = 2;
} else {
@@ -751,7 +694,6 @@ uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_forma
} break;
case RS::ARRAY_NORMAL: {
-
if (p_format & ARRAY_COMPRESS_NORMAL) {
elem_size = sizeof(uint32_t);
} else {
@@ -769,7 +711,6 @@ uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_forma
} break;
case RS::ARRAY_COLOR: {
-
if (p_format & ARRAY_COMPRESS_COLOR) {
elem_size = sizeof(uint32_t);
} else {
@@ -794,24 +735,20 @@ uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_forma
} break;
case RS::ARRAY_WEIGHTS: {
-
elem_size = sizeof(uint16_t) * 4;
} break;
case RS::ARRAY_BONES: {
-
elem_size = sizeof(uint16_t) * 4;
} break;
case RS::ARRAY_INDEX: {
-
if (p_index_len <= 0) {
ERR_PRINT("index_array_len==NO_INDEX_ARRAY");
break;
}
/* determine whether using 16 or 32 bits indices */
if (p_vertex_len >= (1 << 16)) {
-
elem_size = 4;
} else {
@@ -832,7 +769,6 @@ uint32_t RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_forma
}
Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surface_data, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, uint32_t p_compress_format) {
-
ERR_FAIL_INDEX_V(p_primitive, RS::PRIMITIVE_MAX, ERR_INVALID_PARAMETER);
ERR_FAIL_COND_V(p_arrays.size() != RS::ARRAY_MAX, ERR_INVALID_PARAMETER);
@@ -843,14 +779,13 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
int array_len = 0;
for (int i = 0; i < p_arrays.size(); i++) {
-
- if (p_arrays[i].get_type() == Variant::NIL)
+ if (p_arrays[i].get_type() == Variant::NIL) {
continue;
+ }
format |= (1 << i);
if (i == RS::ARRAY_VERTEX) {
-
Variant var = p_arrays[i];
switch (var.get_type()) {
case Variant::PACKED_VECTOR2_ARRAY: {
@@ -867,7 +802,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
array_len = PackedVector3Array(p_arrays[i]).size();
ERR_FAIL_COND_V(array_len == 0, ERR_INVALID_DATA);
} else if (i == RS::ARRAY_INDEX) {
-
index_array_len = PackedInt32Array(p_arrays[i]).size();
}
}
@@ -877,13 +811,12 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
if (p_blend_shapes.size()) {
//validate format for morphs
for (int i = 0; i < p_blend_shapes.size(); i++) {
-
uint32_t bsformat = 0;
Array arr = p_blend_shapes[i];
for (int j = 0; j < arr.size(); j++) {
-
- if (arr[j].get_type() != Variant::NIL)
+ if (arr[j].get_type() != Variant::NIL) {
bsformat |= (1 << j);
+ }
}
ERR_FAIL_COND_V((bsformat) != (format & (RS::ARRAY_FORMAT_INDEX - 1)), ERR_INVALID_PARAMETER);
@@ -895,18 +828,16 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
int total_elem_size = 0;
for (int i = 0; i < RS::ARRAY_MAX; i++) {
-
offsets[i] = 0; //reset
- if (!(format & (1 << i))) // no array
+ if (!(format & (1 << i))) { // no array
continue;
+ }
int elem_size = 0;
switch (i) {
-
case RS::ARRAY_VERTEX: {
-
Variant arr = p_arrays[0];
if (arr.get_type() == Variant::PACKED_VECTOR2_ARRAY) {
elem_size = 2;
@@ -924,7 +855,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
} break;
case RS::ARRAY_NORMAL: {
-
if (p_compress_format & ARRAY_COMPRESS_NORMAL) {
elem_size = sizeof(uint32_t);
} else {
@@ -942,7 +872,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
} break;
case RS::ARRAY_COLOR: {
-
if (p_compress_format & ARRAY_COMPRESS_COLOR) {
elem_size = sizeof(uint32_t);
} else {
@@ -967,24 +896,20 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
} break;
case RS::ARRAY_WEIGHTS: {
-
elem_size = sizeof(uint16_t) * 4;
} break;
case RS::ARRAY_BONES: {
-
elem_size = sizeof(uint16_t) * 4;
} break;
case RS::ARRAY_INDEX: {
-
if (index_array_len <= 0) {
ERR_PRINT("index_array_len==NO_INDEX_ARRAY");
break;
}
/* determine whether using 16 or 32 bits indices */
if (array_len >= (1 << 16)) {
-
elem_size = 4;
} else {
@@ -1024,7 +949,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
Vector<Vector<uint8_t>> blend_shape_data;
for (int i = 0; i < p_blend_shapes.size(); i++) {
-
Vector<uint8_t> vertex_array_shape;
vertex_array_shape.resize(array_size);
Vector<uint8_t> noindex;
@@ -1038,7 +962,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
Vector<SurfaceData::LOD> lods;
if (index_array_len) {
-
List<Variant> keys;
p_lods.get_key_list(&keys);
for (List<Variant>::Element *E = keys.front(); E; E = E->next()) {
@@ -1093,7 +1016,6 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
void RenderingServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, const Dictionary &p_lods, uint32_t p_compress_format) {
-
SurfaceData sd;
Error err = mesh_create_surface_data_from_arrays(&sd, p_primitive, p_arrays, p_blend_shapes, p_lods, p_compress_format);
if (err != OK) {
@@ -1103,24 +1025,21 @@ void RenderingServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_p
}
Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t> p_vertex_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len) const {
-
uint32_t offsets[ARRAY_MAX];
int total_elem_size = 0;
for (int i = 0; i < RS::ARRAY_MAX; i++) {
-
offsets[i] = 0; //reset
- if (!(p_format & (1 << i))) // no array
+ if (!(p_format & (1 << i))) { // no array
continue;
+ }
int elem_size = 0;
switch (i) {
-
case RS::ARRAY_VERTEX: {
-
if (p_format & ARRAY_FLAG_USE_2D_VERTICES) {
elem_size = 2;
} else {
@@ -1133,7 +1052,6 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
} break;
case RS::ARRAY_NORMAL: {
-
if (p_format & ARRAY_COMPRESS_NORMAL) {
elem_size = sizeof(uint32_t);
} else {
@@ -1151,7 +1069,6 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
} break;
case RS::ARRAY_COLOR: {
-
if (p_format & ARRAY_COMPRESS_COLOR) {
elem_size = sizeof(uint32_t);
} else {
@@ -1176,24 +1093,20 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
} break;
case RS::ARRAY_WEIGHTS: {
-
elem_size = sizeof(uint16_t) * 4;
} break;
case RS::ARRAY_BONES: {
-
elem_size = sizeof(uint16_t) * 4;
} break;
case RS::ARRAY_INDEX: {
-
if (p_index_len <= 0) {
ERR_PRINT("index_array_len==NO_INDEX_ARRAY");
break;
}
/* determine whether using 16 or 32 bits indices */
if (p_vertex_len >= (1 << 16)) {
-
elem_size = 4;
} else {
@@ -1217,25 +1130,20 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
const uint8_t *r = p_vertex_data.ptr();
for (int i = 0; i < RS::ARRAY_MAX; i++) {
-
- if (!(p_format & (1 << i)))
+ if (!(p_format & (1 << i))) {
continue;
+ }
switch (i) {
-
case RS::ARRAY_VERTEX: {
-
if (p_format & ARRAY_FLAG_USE_2D_VERTICES) {
-
Vector<Vector2> arr_2d;
arr_2d.resize(p_vertex_len);
{
-
Vector2 *w = arr_2d.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
w[j] = Vector2(v[0], v[1]);
}
@@ -1243,16 +1151,13 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
ret[i] = arr_2d;
} else {
-
Vector<Vector3> arr_3d;
arr_3d.resize(p_vertex_len);
{
-
Vector3 *w = arr_3d.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
w[j] = Vector3(v[0], v[1], v[2]);
}
@@ -1267,12 +1172,10 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
arr.resize(p_vertex_len);
if (p_format & ARRAY_COMPRESS_NORMAL) {
-
Vector3 *w = arr.ptrw();
const float multiplier = 1.f / 127.f;
for (int j = 0; j < p_vertex_len; j++) {
-
const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]];
w[j] = Vector3(float(v[0]) * multiplier, float(v[1]) * multiplier, float(v[2]) * multiplier);
}
@@ -1280,7 +1183,6 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
Vector3 *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
w[j] = Vector3(v[0], v[1], v[2]);
}
@@ -1297,14 +1199,12 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
float *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]];
for (int k = 0; k < 4; k++) {
w[j * 4 + k] = float(v[k] / 127.0);
}
}
} else {
-
float *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
@@ -1319,16 +1219,13 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
} break;
case RS::ARRAY_COLOR: {
-
Vector<Color> arr;
arr.resize(p_vertex_len);
if (p_format & ARRAY_COMPRESS_COLOR) {
-
Color *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]];
w[j] = Color(float(v[0] / 255.0), float(v[1] / 255.0), float(v[2] / 255.0), float(v[3] / 255.0));
}
@@ -1336,7 +1233,6 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
Color *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
w[j] = Color(v[0], v[1], v[2], v[3]);
}
@@ -1345,25 +1241,20 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
ret[i] = arr;
} break;
case RS::ARRAY_TEX_UV: {
-
Vector<Vector2> arr;
arr.resize(p_vertex_len);
if (p_format & ARRAY_COMPRESS_TEX_UV) {
-
Vector2 *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]];
w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1]));
}
} else {
-
Vector2 *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
w[j] = Vector2(v[0], v[1]);
}
@@ -1377,20 +1268,16 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
arr.resize(p_vertex_len);
if (p_format & ARRAY_COMPRESS_TEX_UV2) {
-
Vector2 *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]];
w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1]));
}
} else {
-
Vector2 *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
w[j] = Vector2(v[0], v[1]);
}
@@ -1400,14 +1287,12 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
} break;
case RS::ARRAY_WEIGHTS: {
-
Vector<float> arr;
arr.resize(p_vertex_len * 4);
{
float *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]];
for (int k = 0; k < 4; k++) {
w[j * 4 + k] = float(v[k] / 65535.0);
@@ -1419,14 +1304,12 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
} break;
case RS::ARRAY_BONES: {
-
Vector<int> arr;
arr.resize(p_vertex_len * 4);
int *w = arr.ptrw();
for (int j = 0; j < p_vertex_len; j++) {
-
const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]];
for (int k = 0; k < 4; k++) {
w[j * 4 + k] = v[k];
@@ -1444,16 +1327,13 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
Vector<int> arr;
arr.resize(p_index_len);
if (p_vertex_len < (1 << 16)) {
-
int *w = arr.ptrw();
for (int j = 0; j < p_index_len; j++) {
-
const uint16_t *v = (const uint16_t *)&ir[j * 2];
w[j] = *v;
}
} else {
-
int *w = arr.ptrw();
for (int j = 0; j < p_index_len; j++) {
@@ -1473,13 +1353,11 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
}
Array RenderingServer::mesh_surface_get_arrays(RID p_mesh, int p_surface) const {
-
SurfaceData sd = mesh_get_surface(p_mesh, p_surface);
return mesh_create_arrays_from_surface_data(sd);
}
Dictionary RenderingServer::mesh_surface_get_lods(RID p_mesh, int p_surface) const {
-
SurfaceData sd = mesh_get_surface(p_mesh, p_surface);
ERR_FAIL_COND_V(sd.vertex_count == 0, Dictionary());
@@ -1514,7 +1392,6 @@ Dictionary RenderingServer::mesh_surface_get_lods(RID p_mesh, int p_surface) con
}
Array RenderingServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surface) const {
-
SurfaceData sd = mesh_get_surface(p_mesh, p_surface);
ERR_FAIL_COND_V(sd.vertex_count == 0, Array());
@@ -1541,7 +1418,6 @@ Array RenderingServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_sur
}
Array RenderingServer::mesh_create_arrays_from_surface_data(const SurfaceData &p_data) const {
-
Vector<uint8_t> vertex_data = p_data.vertex_data;
ERR_FAIL_COND_V(vertex_data.size() == 0, Array());
@@ -1567,42 +1443,69 @@ Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_su
#endif
ShaderLanguage::DataType RenderingServer::global_variable_type_get_shader_datatype(GlobalVariableType p_type) {
-
switch (p_type) {
- case RS::GLOBAL_VAR_TYPE_BOOL: return ShaderLanguage::TYPE_BOOL;
- case RS::GLOBAL_VAR_TYPE_BVEC2: return ShaderLanguage::TYPE_BVEC2;
- case RS::GLOBAL_VAR_TYPE_BVEC3: return ShaderLanguage::TYPE_BVEC3;
- case RS::GLOBAL_VAR_TYPE_BVEC4: return ShaderLanguage::TYPE_BVEC4;
- case RS::GLOBAL_VAR_TYPE_INT: return ShaderLanguage::TYPE_INT;
- case RS::GLOBAL_VAR_TYPE_IVEC2: return ShaderLanguage::TYPE_IVEC2;
- case RS::GLOBAL_VAR_TYPE_IVEC3: return ShaderLanguage::TYPE_IVEC3;
- case RS::GLOBAL_VAR_TYPE_IVEC4: return ShaderLanguage::TYPE_IVEC4;
- case RS::GLOBAL_VAR_TYPE_RECT2I: return ShaderLanguage::TYPE_IVEC4;
- case RS::GLOBAL_VAR_TYPE_UINT: return ShaderLanguage::TYPE_UINT;
- case RS::GLOBAL_VAR_TYPE_UVEC2: return ShaderLanguage::TYPE_UVEC2;
- case RS::GLOBAL_VAR_TYPE_UVEC3: return ShaderLanguage::TYPE_UVEC3;
- case RS::GLOBAL_VAR_TYPE_UVEC4: return ShaderLanguage::TYPE_UVEC4;
- case RS::GLOBAL_VAR_TYPE_FLOAT: return ShaderLanguage::TYPE_FLOAT;
- case RS::GLOBAL_VAR_TYPE_VEC2: return ShaderLanguage::TYPE_VEC2;
- case RS::GLOBAL_VAR_TYPE_VEC3: return ShaderLanguage::TYPE_VEC3;
- case RS::GLOBAL_VAR_TYPE_VEC4: return ShaderLanguage::TYPE_VEC4;
- case RS::GLOBAL_VAR_TYPE_COLOR: return ShaderLanguage::TYPE_VEC4;
- case RS::GLOBAL_VAR_TYPE_RECT2: return ShaderLanguage::TYPE_VEC4;
- case RS::GLOBAL_VAR_TYPE_MAT2: return ShaderLanguage::TYPE_MAT2;
- case RS::GLOBAL_VAR_TYPE_MAT3: return ShaderLanguage::TYPE_MAT3;
- case RS::GLOBAL_VAR_TYPE_MAT4: return ShaderLanguage::TYPE_MAT4;
- case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: return ShaderLanguage::TYPE_MAT3;
- case RS::GLOBAL_VAR_TYPE_TRANSFORM: return ShaderLanguage::TYPE_MAT4;
- case RS::GLOBAL_VAR_TYPE_SAMPLER2D: return ShaderLanguage::TYPE_SAMPLER2D;
- case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY: return ShaderLanguage::TYPE_SAMPLER2DARRAY;
- case RS::GLOBAL_VAR_TYPE_SAMPLER3D: return ShaderLanguage::TYPE_SAMPLER3D;
- case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE: return ShaderLanguage::TYPE_SAMPLERCUBE;
- default: return ShaderLanguage::TYPE_MAX; //invalid or not found
+ case RS::GLOBAL_VAR_TYPE_BOOL:
+ return ShaderLanguage::TYPE_BOOL;
+ case RS::GLOBAL_VAR_TYPE_BVEC2:
+ return ShaderLanguage::TYPE_BVEC2;
+ case RS::GLOBAL_VAR_TYPE_BVEC3:
+ return ShaderLanguage::TYPE_BVEC3;
+ case RS::GLOBAL_VAR_TYPE_BVEC4:
+ return ShaderLanguage::TYPE_BVEC4;
+ case RS::GLOBAL_VAR_TYPE_INT:
+ return ShaderLanguage::TYPE_INT;
+ case RS::GLOBAL_VAR_TYPE_IVEC2:
+ return ShaderLanguage::TYPE_IVEC2;
+ case RS::GLOBAL_VAR_TYPE_IVEC3:
+ return ShaderLanguage::TYPE_IVEC3;
+ case RS::GLOBAL_VAR_TYPE_IVEC4:
+ return ShaderLanguage::TYPE_IVEC4;
+ case RS::GLOBAL_VAR_TYPE_RECT2I:
+ return ShaderLanguage::TYPE_IVEC4;
+ case RS::GLOBAL_VAR_TYPE_UINT:
+ return ShaderLanguage::TYPE_UINT;
+ case RS::GLOBAL_VAR_TYPE_UVEC2:
+ return ShaderLanguage::TYPE_UVEC2;
+ case RS::GLOBAL_VAR_TYPE_UVEC3:
+ return ShaderLanguage::TYPE_UVEC3;
+ case RS::GLOBAL_VAR_TYPE_UVEC4:
+ return ShaderLanguage::TYPE_UVEC4;
+ case RS::GLOBAL_VAR_TYPE_FLOAT:
+ return ShaderLanguage::TYPE_FLOAT;
+ case RS::GLOBAL_VAR_TYPE_VEC2:
+ return ShaderLanguage::TYPE_VEC2;
+ case RS::GLOBAL_VAR_TYPE_VEC3:
+ return ShaderLanguage::TYPE_VEC3;
+ case RS::GLOBAL_VAR_TYPE_VEC4:
+ return ShaderLanguage::TYPE_VEC4;
+ case RS::GLOBAL_VAR_TYPE_COLOR:
+ return ShaderLanguage::TYPE_VEC4;
+ case RS::GLOBAL_VAR_TYPE_RECT2:
+ return ShaderLanguage::TYPE_VEC4;
+ case RS::GLOBAL_VAR_TYPE_MAT2:
+ return ShaderLanguage::TYPE_MAT2;
+ case RS::GLOBAL_VAR_TYPE_MAT3:
+ return ShaderLanguage::TYPE_MAT3;
+ case RS::GLOBAL_VAR_TYPE_MAT4:
+ return ShaderLanguage::TYPE_MAT4;
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D:
+ return ShaderLanguage::TYPE_MAT3;
+ case RS::GLOBAL_VAR_TYPE_TRANSFORM:
+ return ShaderLanguage::TYPE_MAT4;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2D:
+ return ShaderLanguage::TYPE_SAMPLER2D;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER2DARRAY:
+ return ShaderLanguage::TYPE_SAMPLER2DARRAY;
+ case RS::GLOBAL_VAR_TYPE_SAMPLER3D:
+ return ShaderLanguage::TYPE_SAMPLER3D;
+ case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE:
+ return ShaderLanguage::TYPE_SAMPLERCUBE;
+ default:
+ return ShaderLanguage::TYPE_MAX; //invalid or not found
}
}
void RenderingServer::_bind_methods() {
-
ClassDB::bind_method(D_METHOD("force_sync"), &RenderingServer::sync);
ClassDB::bind_method(D_METHOD("force_draw", "swap_buffers", "frame_step"), &RenderingServer::draw, DEFVAL(true), DEFVAL(0.0));
@@ -1755,8 +1658,8 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("gi_probe_set_compress", "probe", "enable"), &RenderingServer::gi_probe_set_compress);
ClassDB::bind_method(D_METHOD("gi_probe_is_compressed", "probe"), &RenderingServer::gi_probe_is_compressed);
#endif
-
- ClassDB::bind_method(D_METHOD("lightmap_capture_create"), &RenderingServer::lightmap_capture_create);
+/*
+ ClassDB::bind_method(D_METHOD("lightmap_create()"), &RenderingServer::lightmap_capture_create);
ClassDB::bind_method(D_METHOD("lightmap_capture_set_bounds", "capture", "bounds"), &RenderingServer::lightmap_capture_set_bounds);
ClassDB::bind_method(D_METHOD("lightmap_capture_get_bounds", "capture"), &RenderingServer::lightmap_capture_get_bounds);
ClassDB::bind_method(D_METHOD("lightmap_capture_set_octree", "capture", "octree"), &RenderingServer::lightmap_capture_set_octree);
@@ -1767,6 +1670,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("lightmap_capture_get_octree", "capture"), &RenderingServer::lightmap_capture_get_octree);
ClassDB::bind_method(D_METHOD("lightmap_capture_set_energy", "capture", "energy"), &RenderingServer::lightmap_capture_set_energy);
ClassDB::bind_method(D_METHOD("lightmap_capture_get_energy", "capture"), &RenderingServer::lightmap_capture_get_energy);
+*/
#endif
ClassDB::bind_method(D_METHOD("particles_create"), &RenderingServer::particles_create);
ClassDB::bind_method(D_METHOD("particles_set_emitting", "particles", "emitting"), &RenderingServer::particles_set_emitting);
@@ -1866,7 +1770,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("instance_set_blend_shape_weight", "instance", "shape", "weight"), &RenderingServer::instance_set_blend_shape_weight);
ClassDB::bind_method(D_METHOD("instance_set_surface_material", "instance", "surface", "material"), &RenderingServer::instance_set_surface_material);
ClassDB::bind_method(D_METHOD("instance_set_visible", "instance", "visible"), &RenderingServer::instance_set_visible);
- ClassDB::bind_method(D_METHOD("instance_set_use_lightmap", "instance", "lightmap_instance", "lightmap"), &RenderingServer::instance_set_use_lightmap);
+ // ClassDB::bind_method(D_METHOD("instance_set_use_lightmap", "instance", "lightmap_instance", "lightmap"), &RenderingServer::instance_set_use_lightmap);
ClassDB::bind_method(D_METHOD("instance_set_custom_aabb", "instance", "aabb"), &RenderingServer::instance_set_custom_aabb);
ClassDB::bind_method(D_METHOD("instance_attach_skeleton", "instance", "skeleton"), &RenderingServer::instance_attach_skeleton);
ClassDB::bind_method(D_METHOD("instance_set_exterior", "instance", "enabled"), &RenderingServer::instance_set_exterior);
@@ -1998,9 +1902,6 @@ void RenderingServer::_bind_methods() {
BIND_CONSTANT(MAX_GLOW_LEVELS);
BIND_CONSTANT(MAX_CURSORS);
- BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MIN);
- BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MAX);
-
BIND_ENUM_CONSTANT(TEXTURE_LAYERED_2D_ARRAY);
BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP);
BIND_ENUM_CONSTANT(TEXTURE_LAYERED_CUBEMAP_ARRAY);
@@ -2018,6 +1919,9 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(SHADER_SKY);
BIND_ENUM_CONSTANT(SHADER_MAX);
+ BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MIN);
+ BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MAX);
+
BIND_ENUM_CONSTANT(ARRAY_VERTEX);
BIND_ENUM_CONSTANT(ARRAY_NORMAL);
BIND_ENUM_CONSTANT(ARRAY_TANGENT);
@@ -2045,9 +1949,10 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2);
BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT);
+
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES);
BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE);
- BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT);
BIND_ENUM_CONSTANT(PRIMITIVE_POINTS);
BIND_ENUM_CONSTANT(PRIMITIVE_LINES);
@@ -2070,6 +1975,7 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(LIGHT_PARAM_INDIRECT_ENERGY);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SPECULAR);
BIND_ENUM_CONSTANT(LIGHT_PARAM_RANGE);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SIZE);
BIND_ENUM_CONSTANT(LIGHT_PARAM_ATTENUATION);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ANGLE);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ATTENUATION);
@@ -2080,6 +1986,9 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_FADE_START);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_NORMAL_BIAS);
BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_PANCAKE_SIZE);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BLUR);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_TRANSMITTANCE_BIAS);
BIND_ENUM_CONSTANT(LIGHT_PARAM_MAX);
BIND_ENUM_CONSTANT(LIGHT_OMNI_SHADOW_DUAL_PARABOLOID);
@@ -2095,6 +2004,12 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ONCE);
BIND_ENUM_CONSTANT(REFLECTION_PROBE_UPDATE_ALWAYS);
+ BIND_ENUM_CONSTANT(DECAL_TEXTURE_ALBEDO);
+ BIND_ENUM_CONSTANT(DECAL_TEXTURE_NORMAL);
+ BIND_ENUM_CONSTANT(DECAL_TEXTURE_ORM);
+ BIND_ENUM_CONSTANT(DECAL_TEXTURE_EMISSION);
+ BIND_ENUM_CONSTANT(DECAL_TEXTURE_MAX);
+
BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_INDEX);
BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_LIFETIME);
BIND_ENUM_CONSTANT(PARTICLES_DRAW_ORDER_VIEW_DEPTH);
@@ -2114,6 +2029,11 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(VIEWPORT_MSAA_4X);
BIND_ENUM_CONSTANT(VIEWPORT_MSAA_8X);
BIND_ENUM_CONSTANT(VIEWPORT_MSAA_16X);
+ BIND_ENUM_CONSTANT(VIEWPORT_MSAA_MAX);
+
+ BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_DISABLED);
+ BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_FXAA);
+ BIND_ENUM_CONSTANT(VIEWPORT_SCREEN_SPACE_AA_MAX);
BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME);
BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME);
@@ -2138,6 +2058,7 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_SSAO);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER);
BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_PSSM_SPLITS);
+ BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_DECAL_ATLAS);
BIND_ENUM_CONSTANT(SKY_MODE_QUALITY);
BIND_ENUM_CONSTANT(SKY_MODE_REALTIME);
@@ -2170,6 +2091,11 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_FILMIC);
BIND_ENUM_CONSTANT(ENV_TONE_MAPPER_ACES);
+ BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_DISABLED);
+ BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_LOW);
+ BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_MEDIUM);
+ BIND_ENUM_CONSTANT(ENV_SSR_ROUGNESS_QUALITY_HIGH);
+
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_DISABLED);
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_1x1);
BIND_ENUM_CONSTANT(ENV_SSAO_BLUR_2x2);
@@ -2180,6 +2106,11 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_HIGH);
BIND_ENUM_CONSTANT(ENV_SSAO_QUALITY_ULTRA);
+ BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_DISABLED);
+ BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_LOW);
+ BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_MEDIUM);
+ BIND_ENUM_CONSTANT(SUB_SURFACE_SCATTERING_QUALITY_HIGH);
+
BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_VERY_LOW);
BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_LOW);
BIND_ENUM_CONSTANT(DOF_BLUR_QUALITY_MEDIUM);
@@ -2189,6 +2120,13 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(DOF_BOKEH_HEXAGON);
BIND_ENUM_CONSTANT(DOF_BOKEH_CIRCLE);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_HARD);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_LOW);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_MEDIUM);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_HIGH);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_SOFT_ULTRA);
+ BIND_ENUM_CONSTANT(SHADOW_QUALITY_MAX);
+
BIND_ENUM_CONSTANT(SCENARIO_DEBUG_DISABLED);
BIND_ENUM_CONSTANT(SCENARIO_DEBUG_WIREFRAME);
BIND_ENUM_CONSTANT(SCENARIO_DEBUG_OVERDRAW);
@@ -2201,8 +2139,9 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(INSTANCE_PARTICLES);
BIND_ENUM_CONSTANT(INSTANCE_LIGHT);
BIND_ENUM_CONSTANT(INSTANCE_REFLECTION_PROBE);
+ BIND_ENUM_CONSTANT(INSTANCE_DECAL);
BIND_ENUM_CONSTANT(INSTANCE_GI_PROBE);
- BIND_ENUM_CONSTANT(INSTANCE_LIGHTMAP_CAPTURE);
+ BIND_ENUM_CONSTANT(INSTANCE_LIGHTMAP);
BIND_ENUM_CONSTANT(INSTANCE_MAX);
BIND_ENUM_CONSTANT(INSTANCE_GEOMETRY_MASK);
@@ -2298,27 +2237,22 @@ void RenderingServer::_bind_methods() {
}
void RenderingServer::_canvas_item_add_style_box(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector<float> &p_margins, const Color &p_modulate) {
-
ERR_FAIL_COND(p_margins.size() != 4);
//canvas_item_add_style_box(p_item,p_rect,p_source,p_texture,Vector2(p_margins[0],p_margins[1]),Vector2(p_margins[2],p_margins[3]),true,p_modulate);
}
void RenderingServer::_camera_set_orthogonal(RID p_camera, float p_size, float p_z_near, float p_z_far) {
-
camera_set_orthogonal(p_camera, p_size, p_z_near, p_z_far);
}
void RenderingServer::mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry::MeshData &p_mesh_data) {
-
Vector<Vector3> vertices;
Vector<Vector3> normals;
for (int i = 0; i < p_mesh_data.faces.size(); i++) {
-
const Geometry::MeshData::Face &f = p_mesh_data.faces[i];
for (int j = 2; j < f.indices.size(); j++) {
-
#define _ADD_VERTEX(m_idx) \
vertices.push_back(p_mesh_data.vertices[f.indices[m_idx]]); \
normals.push_back(f.plane.normal);
@@ -2337,7 +2271,6 @@ void RenderingServer::mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry
}
void RenderingServer::mesh_add_surface_from_planes(RID p_mesh, const Vector<Plane> &p_planes) {
-
Geometry::MeshData mdata = Geometry::build_convex_mesh(p_planes);
mesh_add_surface_from_mesh_data(p_mesh, mdata);
}
@@ -2347,7 +2280,6 @@ void RenderingServer::immediate_vertex_2d(RID p_immediate, const Vector2 &p_vert
}
RID RenderingServer::instance_create2(RID p_base, RID p_scenario) {
-
RID instance = instance_create();
instance_set_base(instance, p_base);
instance_set_scenario(instance, p_scenario);
@@ -2355,7 +2287,6 @@ RID RenderingServer::instance_create2(RID p_base, RID p_scenario) {
}
RenderingServer::RenderingServer() {
-
//ERR_FAIL_COND(singleton);
singleton = this;
@@ -2365,6 +2296,9 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF_RST("rendering/vram_compression/import_etc2", true);
GLOBAL_DEF_RST("rendering/vram_compression/import_pvrtc", false);
+ GLOBAL_DEF("rendering/limits/time/time_rollover_secs", 3600);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/time/time_rollover_secs", PropertyInfo(Variant::FLOAT, "rendering/limits/time/time_rollover_secs", PROPERTY_HINT_RANGE, "0,10000,1,or_greater"));
+
GLOBAL_DEF("rendering/quality/directional_shadow/size", 4096);
GLOBAL_DEF("rendering/quality/directional_shadow/size.mobile", 2048);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/directional_shadow/size", PropertyInfo(Variant::INT, "rendering/quality/directional_shadow/size", PROPERTY_HINT_RANGE, "256,16384"));
@@ -2413,7 +2347,8 @@ RenderingServer::RenderingServer() {
GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple");
GLOBAL_DEF("rendering/quality/texture_filters/use_nearest_mipmap_filter", false);
- GLOBAL_DEF("rendering/quality/texture_filters/max_anisotropy", 4);
+ GLOBAL_DEF("rendering/quality/texture_filters/anisotropic_filtering_level", 2);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/texture_filters/anisotropic_filtering_level", PropertyInfo(Variant::INT, "rendering/quality/texture_filters/anisotropic_filtering_level", PROPERTY_HINT_ENUM, "Disabled (Fastest),2x (Faster),4x (Fast),8x (Average),16x (Slow)"));
GLOBAL_DEF("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", 1);
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PropertyInfo(Variant::INT, "rendering/quality/depth_of_field/depth_of_field_bokeh_shape", PROPERTY_HINT_ENUM, "Box (Fast),Hexagon (Average),Circle (Slow)"));
@@ -2445,9 +2380,11 @@ RenderingServer::RenderingServer() {
ProjectSettings::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PropertyInfo(Variant::FLOAT, "rendering/quality/subsurface_scattering/subsurface_scattering_depth_scale", PROPERTY_HINT_RANGE, "0.001,1,0.001"));
GLOBAL_DEF("rendering/high_end/global_shader_variables_buffer_size", 65536);
+
+ GLOBAL_DEF("rendering/lightmapper/probe_capture_update_speed", 15);
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/lightmapper/probe_capture_update_speed", PropertyInfo(Variant::FLOAT, "rendering/lightmapper/probe_capture_update_speed", PROPERTY_HINT_RANGE, "0.001,256,0.001"));
}
RenderingServer::~RenderingServer() {
-
singleton = nullptr;
}
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 3bc182a16b..92a27b7fe6 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -36,12 +36,12 @@
#include "core/math/transform_2d.h"
#include "core/object.h"
#include "core/rid.h"
+#include "core/typed_array.h"
#include "core/variant.h"
#include "servers/display_server.h"
#include "servers/rendering/shader_language.h"
class RenderingServer : public Object {
-
GDCLASS(RenderingServer, Object);
static RenderingServer *singleton;
@@ -86,7 +86,6 @@ public:
};
enum CubeMapLayer {
-
CUBEMAP_LAYER_LEFT,
CUBEMAP_LAYER_RIGHT,
CUBEMAP_LAYER_BOTTOM,
@@ -107,7 +106,7 @@ public:
//these two APIs can be used together or in combination with the others.
virtual RID texture_2d_placeholder_create() = 0;
- virtual RID texture_2d_layered_placeholder_create() = 0;
+ virtual RID texture_2d_layered_placeholder_create(TextureLayeredType p_layered_type) = 0;
virtual RID texture_3d_placeholder_create() = 0;
virtual Ref<Image> texture_2d_get(RID p_texture) const = 0;
@@ -158,7 +157,6 @@ public:
/* SHADER API */
enum ShaderMode {
-
SHADER_SPATIAL,
SHADER_CANVAS_ITEM,
SHADER_PARTICLES,
@@ -182,8 +180,8 @@ public:
enum {
MATERIAL_RENDER_PRIORITY_MIN = -128,
MATERIAL_RENDER_PRIORITY_MAX = 127,
-
};
+
virtual RID material_create() = 0;
virtual void material_set_shader(RID p_shader_material, RID p_shader) = 0;
@@ -198,7 +196,6 @@ public:
/* MESH API */
enum ArrayType {
-
ARRAY_VERTEX = 0,
ARRAY_NORMAL = 1,
ARRAY_TANGENT = 2,
@@ -230,12 +227,10 @@ public:
ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE),
ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE),
+ ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2,
ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1,
ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3,
-
- ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2
-
};
enum PrimitiveType {
@@ -248,7 +243,6 @@ public:
};
struct SurfaceData {
-
PrimitiveType primitive = PRIMITIVE_MAX;
uint32_t format = 0;
@@ -378,7 +372,6 @@ public:
};
enum LightParam {
-
LIGHT_PARAM_ENERGY,
LIGHT_PARAM_INDIRECT_ENERGY,
LIGHT_PARAM_SPECULAR,
@@ -528,19 +521,20 @@ public:
virtual void gi_probe_set_anisotropy_strength(RID p_gi_probe, float p_strength) = 0;
virtual float gi_probe_get_anisotropy_strength(RID p_gi_probe) const = 0;
- /* LIGHTMAP CAPTURE */
+ /* LIGHTMAP */
+
+ virtual RID lightmap_create() = 0;
- virtual RID lightmap_capture_create() = 0;
- virtual void lightmap_capture_set_bounds(RID p_capture, const AABB &p_bounds) = 0;
- virtual AABB lightmap_capture_get_bounds(RID p_capture) const = 0;
- virtual void lightmap_capture_set_octree(RID p_capture, const Vector<uint8_t> &p_octree) = 0;
- virtual void lightmap_capture_set_octree_cell_transform(RID p_capture, const Transform &p_xform) = 0;
- virtual Transform lightmap_capture_get_octree_cell_transform(RID p_capture) const = 0;
- virtual void lightmap_capture_set_octree_cell_subdiv(RID p_capture, int p_subdiv) = 0;
- virtual int lightmap_capture_get_octree_cell_subdiv(RID p_capture) const = 0;
- virtual Vector<uint8_t> lightmap_capture_get_octree(RID p_capture) const = 0;
- virtual void lightmap_capture_set_energy(RID p_capture, float p_energy) = 0;
- virtual float lightmap_capture_get_energy(RID p_capture) const = 0;
+ virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) = 0;
+ virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) = 0;
+ virtual void lightmap_set_probe_interior(RID p_lightmap, bool p_interior) = 0;
+ virtual void lightmap_set_probe_capture_data(RID p_lightmap, const PackedVector3Array &p_points, const PackedColorArray &p_point_sh, const PackedInt32Array &p_tetrahedra, const PackedInt32Array &p_bsp_tree) = 0;
+ virtual PackedVector3Array lightmap_get_probe_capture_points(RID p_lightmap) const = 0;
+ virtual PackedColorArray lightmap_get_probe_capture_sh(RID p_lightmap) const = 0;
+ virtual PackedInt32Array lightmap_get_probe_capture_tetrahedra(RID p_lightmap) const = 0;
+ virtual PackedInt32Array lightmap_get_probe_capture_bsp_tree(RID p_lightmap) const = 0;
+
+ virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0;
/* PARTICLES API */
@@ -599,7 +593,8 @@ public:
};
virtual void particles_set_collision(RID p_particles,ParticlesCollisionMode p_mode,const Transform&, p_xform,const RID p_depth_tex,const RID p_normal_tex)=0;
-*/
+ */
+
/* VIEWPORT TARGET API */
virtual RID viewport_create() = 0;
@@ -623,7 +618,6 @@ public:
virtual void viewport_set_update_mode(RID p_viewport, ViewportUpdateMode p_mode) = 0;
enum ViewportClearMode {
-
VIEWPORT_CLEAR_ALWAYS,
VIEWPORT_CLEAR_NEVER,
VIEWPORT_CLEAR_ONLY_NEXT_FRAME
@@ -664,18 +658,19 @@ public:
enum ViewportScreenSpaceAA {
VIEWPORT_SCREEN_SPACE_AA_DISABLED,
VIEWPORT_SCREEN_SPACE_AA_FXAA,
+ VIEWPORT_SCREEN_SPACE_AA_MAX,
};
+
virtual void viewport_set_screen_space_aa(RID p_viewport, ViewportScreenSpaceAA p_mode) = 0;
enum ViewportRenderInfo {
-
VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME,
VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME,
VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME,
VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME,
VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME,
VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME,
- VIEWPORT_RENDER_INFO_MAX
+ VIEWPORT_RENDER_INFO_MAX,
};
virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) = 0;
@@ -697,7 +692,6 @@ public:
VIEWPORT_DEBUG_DRAW_ROUGHNESS_LIMITER,
VIEWPORT_DEBUG_DRAW_PSSM_SPLITS,
VIEWPORT_DEBUG_DRAW_DECAL_ATLAS,
-
};
virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0;
@@ -719,13 +713,13 @@ public:
virtual void sky_set_radiance_size(RID p_sky, int p_radiance_size) = 0;
virtual void sky_set_mode(RID p_sky, SkyMode p_mode) = 0;
virtual void sky_set_material(RID p_sky, RID p_material) = 0;
+ virtual Ref<Image> sky_bake_panorama(RID p_sky, float p_energy, bool p_bake_irradiance, const Size2i &p_size) = 0;
/* ENVIRONMENT API */
virtual RID environment_create() = 0;
enum EnvironmentBG {
-
ENV_BG_CLEAR_COLOR,
ENV_BG_COLOR,
ENV_BG_SKY,
@@ -768,6 +762,7 @@ public:
ENV_GLOW_BLEND_MODE_REPLACE,
ENV_GLOW_BLEND_MODE_MIX,
};
+
virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_mix, float p_bloom_threshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, float p_hdr_luminance_cap) = 0;
virtual void environment_glow_set_use_bicubic_upscale(bool p_enable) = 0;
@@ -815,6 +810,8 @@ public:
virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_end, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
+ virtual Ref<Image> environment_bake_panorama(RID p_env, bool p_bake_irradiance, const Size2i &p_size) = 0;
+
virtual void screen_space_roughness_limiter_set_active(bool p_enable, float p_curve) = 0;
enum SubSurfaceScatteringQuality {
@@ -872,7 +869,6 @@ public:
SCENARIO_DEBUG_WIREFRAME,
SCENARIO_DEBUG_OVERDRAW,
SCENARIO_DEBUG_SHADELESS,
-
};
virtual void scenario_set_debug(RID p_scenario, ScenarioDebugMode p_debug_mode) = 0;
@@ -883,7 +879,6 @@ public:
/* INSTANCING API */
enum InstanceType {
-
INSTANCE_NONE,
INSTANCE_MESH,
INSTANCE_MULTIMESH,
@@ -893,7 +888,7 @@ public:
INSTANCE_REFLECTION_PROBE,
INSTANCE_DECAL,
INSTANCE_GI_PROBE,
- INSTANCE_LIGHTMAP_CAPTURE,
+ INSTANCE_LIGHTMAP,
INSTANCE_MAX,
INSTANCE_GEOMETRY_MASK = (1 << INSTANCE_MESH) | (1 << INSTANCE_MULTIMESH) | (1 << INSTANCE_IMMEDIATE) | (1 << INSTANCE_PARTICLES)
@@ -912,8 +907,6 @@ public:
virtual void instance_set_surface_material(RID p_instance, int p_surface, RID p_material) = 0;
virtual void instance_set_visible(RID p_instance, bool p_visible) = 0;
- virtual void instance_set_use_lightmap(RID p_instance, RID p_lightmap_instance, RID p_lightmap) = 0;
-
virtual void instance_set_custom_aabb(RID p_instance, AABB aabb) = 0;
virtual void instance_attach_skeleton(RID p_instance, RID p_skeleton) = 0;
@@ -950,12 +943,24 @@ public:
virtual void instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) = 0;
virtual void instance_geometry_set_as_instance_lod(RID p_instance, RID p_as_lod_of_instance) = 0;
+ virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice) = 0;
virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &, const Variant &p_value) = 0;
virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &) const = 0;
virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &) const = 0;
virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const = 0;
+ /* Bake 3D objects */
+
+ enum BakeChannels {
+ BAKE_CHANNEL_ALBEDO_ALPHA,
+ BAKE_CHANNEL_NORMAL,
+ BAKE_CHANNEL_ORM,
+ BAKE_CHANNEL_EMISSION
+ };
+
+ virtual TypedArray<Image> bake_render_uv2(RID p_base, const Vector<RID> &p_material_overrides, const Size2i &p_image_size) = 0;
+
/* CANVAS (2D) */
virtual RID canvas_create() = 0;
@@ -1094,6 +1099,7 @@ public:
CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE,
CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE,
};
+
virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon, CanvasOccluderPolygonCullMode p_mode) = 0;
/* GLOBAL VARIABLES */
@@ -1167,7 +1173,6 @@ public:
/* STATUS INFORMATION */
enum RenderInfo {
-
INFO_OBJECTS_IN_FRAME,
INFO_VERTICES_IN_FRAME,
INFO_MATERIAL_CHANGES_IN_FRAME,
@@ -1194,8 +1199,6 @@ public:
virtual Vector<FrameProfileArea> get_frame_profile() = 0;
virtual uint64_t get_frame_profile_frame() = 0;
- /* Materials for 2D on 3D */
-
/* TESTING */
virtual RID get_test_cube() = 0;
@@ -1250,6 +1253,7 @@ VARIANT_ENUM_CAST(RenderingServer::ParticlesDrawOrder);
VARIANT_ENUM_CAST(RenderingServer::ViewportUpdateMode);
VARIANT_ENUM_CAST(RenderingServer::ViewportClearMode);
VARIANT_ENUM_CAST(RenderingServer::ViewportMSAA);
+VARIANT_ENUM_CAST(RenderingServer::ViewportScreenSpaceAA);
VARIANT_ENUM_CAST(RenderingServer::ViewportRenderInfo);
VARIANT_ENUM_CAST(RenderingServer::ViewportDebugDraw);
VARIANT_ENUM_CAST(RenderingServer::SkyMode);
@@ -1258,10 +1262,13 @@ VARIANT_ENUM_CAST(RenderingServer::EnvironmentAmbientSource);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentReflectionSource);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentGlowBlendMode);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentToneMapper);
-VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOQuality);
+VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSRRoughnessQuality);
VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOBlur);
+VARIANT_ENUM_CAST(RenderingServer::EnvironmentSSAOQuality);
+VARIANT_ENUM_CAST(RenderingServer::SubSurfaceScatteringQuality);
VARIANT_ENUM_CAST(RenderingServer::DOFBlurQuality);
VARIANT_ENUM_CAST(RenderingServer::DOFBokehShape);
+VARIANT_ENUM_CAST(RenderingServer::ShadowQuality);
VARIANT_ENUM_CAST(RenderingServer::ScenarioDebugMode);
VARIANT_ENUM_CAST(RenderingServer::InstanceType);
VARIANT_ENUM_CAST(RenderingServer::InstanceFlags);
@@ -1276,7 +1283,7 @@ VARIANT_ENUM_CAST(RenderingServer::GlobalVariableType);
VARIANT_ENUM_CAST(RenderingServer::RenderInfo);
VARIANT_ENUM_CAST(RenderingServer::Features);
-//typedef RenderingServer VS; // makes it easier to use
+// Alias to make it easier to use.
#define RS RenderingServer
-#endif
+#endif // RENDERING_SERVER_H
diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp
index c1233ae810..e9858416ec 100644
--- a/servers/xr/xr_interface.cpp
+++ b/servers/xr/xr_interface.cpp
@@ -122,7 +122,7 @@ XRInterface::XRInterface() {
tracking_state = XR_UNKNOWN_TRACKING;
};
-XRInterface::~XRInterface(){};
+XRInterface::~XRInterface() {}
// optional render to external texture which enhances performance on those platforms that require us to submit our end result into special textures.
unsigned int XRInterface::get_external_texture_for_eye(XRInterface::Eyes p_eye) {
@@ -134,9 +134,9 @@ bool XRInterface::get_anchor_detection_is_enabled() const {
return false;
};
-void XRInterface::set_anchor_detection_is_enabled(bool p_enable){
+void XRInterface::set_anchor_detection_is_enabled(bool p_enable) {
// don't do anything here, this needs to be implemented on AR interface to enable/disable things like plane detection etc.
-};
+}
int XRInterface::get_camera_feed_id() {
// don't do anything here, this needs to be implemented on AR interface to enable/disable things like plane detection etc.
diff --git a/servers/xr/xr_positional_tracker.cpp b/servers/xr/xr_positional_tracker.cpp
index 808b0a608f..ad5cee92ea 100644
--- a/servers/xr/xr_positional_tracker.cpp
+++ b/servers/xr/xr_positional_tracker.cpp
@@ -29,7 +29,8 @@
/*************************************************************************/
#include "xr_positional_tracker.h"
-#include "core/input/input_filter.h"
+
+#include "core/input/input.h"
void XRPositionalTracker::_bind_methods() {
BIND_ENUM_CONSTANT(TRACKER_HAND_UNKNOWN);
@@ -231,7 +232,3 @@ XRPositionalTracker::XRPositionalTracker() {
hand = TRACKER_HAND_UNKNOWN;
rumble = 0.0;
};
-
-XRPositionalTracker::~XRPositionalTracker(){
-
-};
diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h
index d9d1f909e9..515359e9b1 100644
--- a/servers/xr/xr_positional_tracker.h
+++ b/servers/xr/xr_positional_tracker.h
@@ -96,7 +96,7 @@ public:
Transform get_transform(bool p_adjust_by_reference_frame) const;
XRPositionalTracker();
- ~XRPositionalTracker();
+ ~XRPositionalTracker() {}
};
VARIANT_ENUM_CAST(XRPositionalTracker::TrackerHand);
diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp
index a93b99025f..09800443b7 100644
--- a/servers/xr_server.cpp
+++ b/servers/xr_server.cpp
@@ -152,7 +152,6 @@ void XRServer::add_interface(const Ref<XRInterface> &p_interface) {
ERR_FAIL_COND(p_interface.is_null());
for (int i = 0; i < interfaces.size(); i++) {
-
if (interfaces[i] == p_interface) {
ERR_PRINT("Interface was already added");
return;
@@ -168,9 +167,7 @@ void XRServer::remove_interface(const Ref<XRInterface> &p_interface) {
int idx = -1;
for (int i = 0; i < interfaces.size(); i++) {
-
if (interfaces[i] == p_interface) {
-
idx = i;
break;
};
@@ -197,9 +194,7 @@ Ref<XRInterface> XRServer::get_interface(int p_index) const {
Ref<XRInterface> XRServer::find_interface(const String &p_name) const {
int idx = -1;
for (int i = 0; i < interfaces.size(); i++) {
-
if (interfaces[i]->get_name() == p_name) {
-
idx = i;
break;
};
@@ -277,9 +272,7 @@ void XRServer::remove_tracker(XRPositionalTracker *p_tracker) {
int idx = -1;
for (int i = 0; i < trackers.size(); i++) {
-
if (trackers[i] == p_tracker) {
-
idx = i;
break;
};
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 95a6902089..64c2ce336d 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -27,7 +27,7 @@ Files extracted from upstream source:
## basis_universal
- Upstream: https://github.com/BinomialLLC/basis_universal
-- Version: git (895ee8e, 2020)
+- Version: git (895ee8ee7e04f22267f8d16d46de04d5a01d63ac, 2020)
- License: Apache 2.0
Files extracted from upstream source:
@@ -40,9 +40,11 @@ Files extracted from upstream source:
## bullet
- Upstream: https://github.com/bulletphysics/bullet3
-- Version: 2.89
+- Version: git pre-2.90 (cd8cf7521cbb8b7808126a6adebd47bb83ea166a, 2020)
- License: zlib
+Important: Synced with a pre-release version of bullet 2.90 from the master branch.
+
Files extracted from upstream source:
- src/* apart from CMakeLists.txt and premake4.lua files
@@ -52,7 +54,7 @@ Files extracted from upstream source:
## certs
- Upstream: Mozilla, via https://apps.fedoraproject.org/packages/ca-certificates
-- Version: 2018.2.26
+- Version: 2018.2.26 (2018)
- License: MPL 2.0
File extracted from a recent Fedora install:
@@ -64,7 +66,7 @@ as it's generated on the user's system.)
## cvtt
- Upstream: https://github.com/elasota/cvtt
-- Version: 1.0.0-beta4
+- Version: 1.0.0-beta4 (2018)
- License: MIT
Files extracted from upstream source:
@@ -75,7 +77,7 @@ Files extracted from upstream source:
## enet
- Upstream: http://enet.bespin.org
-- Version: 1.3.14 (0eaf48e, 2019)
+- Version: 1.3.15 (224f31101fc60939c02f6bbe8e8fc810a7db306b, 2020)
- License: MIT
Files extracted from upstream source:
@@ -85,21 +87,21 @@ Files extracted from upstream source:
- LICENSE file
Important: enet.h, host.c, protocol.c have been slightly modified
-to be usable by godot socket implementation and allow IPv6.
-Apply the patch in the `patches/` folder when syncing on newer upstream
+to be usable by godot socket implementation and allow IPv6 and DTLS.
+Apply the patches in the `patches/` folder when syncing on newer upstream
commits.
Two files (godot.cpp and enet/godot.h) have been added to provide
enet socket implementation using Godot classes.
It is still possible to build against a system wide ENet but doing so
-will limit it's functionality to IPv4 only.
+will limit its functionality to IPv4 only.
## etc2comp
- Upstream: https://github.com/google/etc2comp
-- Version: git (9cd0f9c, 2017)
+- Version: git (9cd0f9cae0f32338943699bb418107db61bb66f2, 2017)
- License: Apache 2.0
Files extracted from upstream source:
@@ -117,7 +119,7 @@ comments.
### Noto Sans
- Upstream: https://github.com/googlei18n/noto-fonts
-- Version: 1.06
+- Version: 1.06 (2017)
- License: OFL-1.1
Use UI font variant if available, because it has tight vertical metrics and good for UI.
@@ -125,7 +127,7 @@ Use UI font variant if available, because it has tight vertical metrics and good
### Hack Regular
- Upstream: https://github.com/source-foundry/Hack
-- Version: 3.003
+- Version: 3.003 (2018)
- License: MIT + Bitstream Vera License
### DroidSans*.ttf
@@ -138,7 +140,7 @@ Use UI font variant if available, because it has tight vertical metrics and good
## freetype
- Upstream: https://www.freetype.org
-- Version: 2.10.1
+- Version: 2.10.2 (2020)
- License: FreeType License (BSD-like)
Files extracted from upstream source:
@@ -151,7 +153,7 @@ Files extracted from upstream source:
## glad
- Upstream: https://github.com/Dav1dde/glad
-- Version: 0.1.33
+- Version: 0.1.33 (2019)
- License: MIT
The files we package are automatically generated.
@@ -182,18 +184,18 @@ Patches in the `patches` directory should be re-applied after updates.
## jpeg-compressor
- Upstream: https://github.com/richgel999/jpeg-compressor
-- Version: 1.04
+- Version: 2.00 (aeb7d3b463aa8228b87a28013c15ee50a7e6fcf3, 2020)
- License: Public domain
Files extracted from upstream source:
-- `jpgd.{c,h}`
+- `jpgd*.{c,h}`
## libogg
- Upstream: https://www.xiph.org/ogg
-- Version: git (c8fca6b, 2019)
+- Version: git (c8fca6b4a02d695b1ceea39b330d4406001c03ed, 2019)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -206,7 +208,7 @@ Files extracted from upstream source:
## libpng
- Upstream: http://libpng.org/pub/png/libpng.html
-- Version: 1.6.37
+- Version: 1.6.37 (2019)
- License: libpng/zlib
Files extracted from upstream source:
@@ -221,7 +223,7 @@ Files extracted from upstream source:
## libsimplewebm
- Upstream: https://github.com/zaps166/libsimplewebm
-- Version: git (fe57fd3, 2019)
+- Version: git (fe57fd3cfe6c0af4c6af110b1f84a90cf191d943, 2019)
- License: MIT (main), BSD-3-Clause (libwebm)
This contains libwebm, but the version in use is updated from the one used by libsimplewebm,
@@ -240,7 +242,7 @@ comments.
## libtheora
- Upstream: https://www.theora.org
-- Version: 1.1.1
+- Version: 1.1.1 (2010)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -256,7 +258,7 @@ on top of the 1.1.1 source (not included in any stable release yet).
## libvorbis
- Upstream: https://www.xiph.org/vorbis
-- Version: 1.3.6
+- Version: 1.3.6 (2018)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -269,7 +271,7 @@ Files extracted from upstream source:
## libvpx
- Upstream: https://chromium.googlesource.com/webm/libvpx/
-- Version: 1.6.0
+- Version: 1.6.0 (2016)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -286,7 +288,7 @@ from the Android NDK r18.
## libwebp
- Upstream: https://chromium.googlesource.com/webm/libwebp/
-- Version: 1.1.0
+- Version: 1.1.0 (2020)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -302,7 +304,7 @@ changes are marked with `// -- GODOT --` comments.
## mbedtls
- Upstream: https://tls.mbed.org/
-- Version: 2.16.5
+- Version: 2.16.6 (2020)
- License: Apache 2.0
File extracted from upstream release tarball (`-apache.tgz` variant):
@@ -322,7 +324,7 @@ File extracted from upstream release tarball (`-apache.tgz` variant):
## miniupnpc
- Upstream: https://github.com/miniupnp/miniupnp/tree/master/miniupnpc
-- Version: git (4436632, 2020)
+- Version: git (44366328661826603982d1e0d7ebb4062c5f2bfc, 2020)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -338,7 +340,7 @@ The only modified file is miniupnpcstrings.h, which was created for Godot
## minizip
- Upstream: http://www.zlib.net
-- Version: 1.2.11 (zlib contrib)
+- Version: 1.2.11 (zlib contrib, 2017)
- License: zlib
Files extracted from the upstream source:
@@ -358,15 +360,15 @@ Collection of single-file libraries used in Godot components.
- `clipper.{cpp,hpp}`
* Upstream: https://sourceforge.net/projects/polyclipping
- * Version: 6.4.2 + Godot changes (added optional exceptions handling)
+ * Version: 6.4.2 (2017) + Godot changes (added optional exceptions handling)
* License: BSL-1.0
- `cubemap_coeffs.h`
* Upstream: https://research.activision.com/publications/archives/fast-filtering-of-reflection-probes
- File coeffs_const_8.txt
+ File coeffs_const_8.txt (retrieved April 2020)
* License: MIT
- `fastlz.{c,h}`
* Upstream: https://github.com/ariya/FastLZ
- * Version: git (f121734, 2007)
+ * Version: 0.5.0 (4f20f54d46f5a6dd4fae4def134933369b7602d2, 2020)
* License: MIT
- `hq2x.{cpp,h}`
* Upstream: https://github.com/brunexgeek/hqx
@@ -374,17 +376,25 @@ Collection of single-file libraries used in Godot components.
* License: Apache 2.0
- `open-simplex-noise.{c,h}`
* Upstream: https://github.com/smcameron/open-simplex-noise-in-c
- * Version: git (0d555e7, 2015)
+ * Version: git (0d555e7f40527d0870906fe9469a3b1bb4020b7f, 2015) + custom changes
* License: Unlicense
- `pcg.{cpp,h}`
* Upstream: http://www.pcg-random.org
* Version: minimal C implementation, http://www.pcg-random.org/download.html
* License: Apache 2.0
+- `r128.h`
+ * Upstream: https://github.com/fahickman/r128
+ * Version: git (423f693617faafd01de21e92818add4208eb8bd1, 2020)
+ * License: Public Domain
- `smaz.{c,h}`
* Upstream: https://github.com/antirez/smaz
- * Version: git (150e125, 2009)
+ * Version: git (150e125cbae2e8fd20dd332432776ce13395d4d4, 2009)
* License: BSD-3-Clause
* Modifications: use `const char*` instead of `char*` for input string
+- `stb_rect_pack.h`
+ * Upstream: https://github.com/nothings/stb
+ * Version: 1.00 (2019)
+ * License: Public Domain (Unlicense) or MIT
- `triangulator.{cpp,h}`
* Upstream: https://github.com/ivanfratric/polypartition (`src/polypartition.cpp`)
* Version: TBD, class was renamed
@@ -392,10 +402,6 @@ Collection of single-file libraries used in Godot components.
### modules
-- `curl_hostcheck.{c,h}`
- * Upstream: https://curl.haxx.se/
- * Version: ? (2013)
- * License: MIT
- `yuv2rgb.h`
* Upstream: http://wss.co.uk/pinknoise/yuv2rgb/ (to check)
* Version: ?
@@ -405,29 +411,30 @@ Collection of single-file libraries used in Godot components.
- `ifaddrs-android.{cc,h}`
* Upstream: https://chromium.googlesource.com/external/webrtc/stable/talk/+/master/base/ifaddrs-android.h
- * Version: git (5976650, 2013)
+ * Version: git (5976650443d68ccfadf1dea24999ee459dd2819d, 2013)
* License: BSD-3-Clause
### scene
- `easing_equations.cpp`
* Upstream: http://robertpenner.com/easing/ via https://github.com/jesusgollonet/ofpennereasing (modified to fit Godot types)
- * Version: git (af72c14, 2008) + Godot types and style changes
+ * Version: git (af72c147c3a74e7e872aa28c7e2abfcced04fdce, 2008) + Godot types and style changes
* License: BSD-3-Clause
- `mikktspace.{c,h}`
- * Upstream: https://wiki.blender.org/index.php/Dev:Shading/Tangent_Space_Normal_Maps
- * Version: 1.0
+ * Upstream: https://archive.blender.org/wiki/index.php/Dev:Shading/Tangent_Space_Normal_Maps/
+ * Version: 1.0 (2011)
* License: zlib
- `stb_vorbis.c`
* Upstream: https://github.com/nothings/stb
- * Version: 1.17
+ * Version: 1.19
* License: Public Domain (Unlicense) or MIT
+ * Modifications: `f->temp_offset += (sz+3)&~3;` changed to `f->temp_offset += (sz+7)&~7;` (needed until fixed upstream)
## nanosvg
- Upstream: https://github.com/memononen/nanosvg
-- Version: git (25241c5, 2019)
+- Version: git (25241c5a8f8451d41ab1b02ab2d865b01600d949, 2019)
- License: zlib
Files extracted from the upstream source:
@@ -436,10 +443,21 @@ Files extracted from the upstream source:
- LICENSE.txt
+## oidn
+
+- Upstream: https://github.com/OpenImageDenoise/oidn
+- Version: TBD
+- License: Apache 2.0
+
+Files extracted from upstream source:
+
+- TBD
+
+
## opus
- Upstream: https://opus-codec.org
-- Version: 1.1.5 (opus) and 0.8 (opusfile)
+- Version: 1.1.5 (opus) and 0.8 (opusfile) (2017)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -456,14 +474,13 @@ Files extracted from upstream source:
## pcre2
- Upstream: http://www.pcre.org
-- Version: 10.33
+- Version: 10.34 (2019)
- License: BSD-3-Clause
Files extracted from upstream source:
- Files listed in the file NON-AUTOTOOLS-BUILD steps 1-4
- All .h files in src/ apart from pcre2posix.h
-- src/pcre2_jit_compile.c
- src/pcre2_jit_match.c
- src/pcre2_jit_misc.c
- src/sljit/*
@@ -473,7 +490,7 @@ Files extracted from upstream source:
## pvrtccompressor
- Upstream: https://bitbucket.org/jthlim/pvrtccompressor
-- Version: hg (cf71777, 2015)
+- Version: hg (cf7177748ee0dcdccfe89716dc11a47d2dc81af5, 2015)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -485,19 +502,19 @@ Files extracted from upstream source:
## recastnavigation
- Upstream: https://github.com/recastnavigation/recastnavigation
-- Version: git (ef3ea40f, 2017)
+- Version: git (57610fa6ef31b39020231906f8c5d40eaa8294ae, 2019)
- License: zlib
Files extracted from upstream source:
-- `Recast/` folder
+- `Recast/` folder without `CMakeLists.txt`
- License.txt
-## Rvo2
+## rvo2
- Upstream: http://gamma.cs.unc.edu/RVO2/
-- Version: 3D - 1.0.1
+- Version: 3D - 1.0.1 (2016)
- License: Apache 2.0
Files extracted from upstream source:
@@ -513,7 +530,7 @@ Godot. Please check the file to know what's new.
## squish
- Upstream: https://sourceforge.net/projects/libsquish
-- Version: 1.15
+- Version: 1.15 (2017)
- License: MIT
Files extracted from upstream source:
@@ -528,7 +545,7 @@ comments and a patch is provided in the squish/ folder.
## tinyexr
- Upstream: https://github.com/syoyo/tinyexr
-- Version: git (656bb61, 2019)
+- Version: git (4dbd05a22f51a2d7462311569b8b0cba0bbe2ac5, 2020)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -539,7 +556,7 @@ Files extracted from upstream source:
## vhacd
- Upstream: https://github.com/kmammou/v-hacd
-- Version: git (b07958e, 2019)
+- Version: git (b07958e18e01d504e3af80eeaeb9f033226533d7, 2019)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -556,7 +573,7 @@ folder.
## vulkan
- Upstream: https://github.com/KhronosGroup/Vulkan-Loader
-- Version: sdk-1.2.131.2
+- Version: sdk-1.2.131.2 (2020)
- License: Apache 2.0
Unless there is a specific reason to package a more recent version, please stick
@@ -578,7 +595,7 @@ Includes custom change to disable MSVC pragma, might be upstreamed via:
https://github.com/KhronosGroup/Vulkan-ValidationLayers/pull/1666
`vk_mem_alloc.h` is taken from https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
-Version: 2.3.0
+Version: 2.3.0 (2019)
Patches in the `patches` directory should be re-applied after updates.
@@ -586,7 +603,7 @@ Patches in the `patches` directory should be re-applied after updates.
## wslay
- Upstream: https://github.com/tatsuhiro-t/wslay
-- Version: 1.1.0
+- Version: 1.1.0 (2018)
- License: MIT
File extracted from upstream release tarball:
@@ -599,7 +616,7 @@ File extracted from upstream release tarball:
## xatlas
- Upstream: https://github.com/jpcy/xatlas
-- Version: git (e12ea82, 2019)
+- Version: git (470576d3516f7e6d8b4554e7c941194a935969fd, 2020)
- License: MIT
Files extracted from upstream source:
@@ -611,7 +628,7 @@ Files extracted from upstream source:
## zlib
- Upstream: http://www.zlib.net
-- Version: 1.2.11
+- Version: 1.2.11 (2017)
- License: zlib
Files extracted from upstream source:
@@ -622,7 +639,7 @@ Files extracted from upstream source:
## zstd
- Upstream: https://github.com/facebook/zstd
-- Version: 1.4.4
+- Version: 1.4.4 (2019)
- License: BSD-3-Clause
Files extracted from upstream source:
diff --git a/thirdparty/basis_universal/basisu_enc.h b/thirdparty/basis_universal/basisu_enc.h
index c2b9133045..0a0c3c6fc0 100644
--- a/thirdparty/basis_universal/basisu_enc.h
+++ b/thirdparty/basis_universal/basisu_enc.h
@@ -22,6 +22,7 @@
#include <functional>
#include <thread>
#include <unordered_map>
+#include <ostream>
#if !defined(_WIN32) || defined(__MINGW32__)
#include <libgen.h>
diff --git a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.h b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.h
index 980d19a754..55daa7fb57 100644
--- a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.h
+++ b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.h
@@ -203,8 +203,8 @@ struct btDbvntNode
btDbvntNode(const btDbvtNode* n)
: volume(n->volume)
- , angle(0)
, normal(0,0,0)
+ , angle(0)
, data(n->data)
{
childs[0] = 0;
diff --git a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
index f4a2d5e368..56011899cb 100644
--- a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
+++ b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
@@ -61,7 +61,8 @@ public:
virtual void cleanOverlappingPair(btBroadphasePair& pair, btDispatcher* dispatcher) = 0;
virtual int getNumOverlappingPairs() const = 0;
-
+ virtual bool needsBroadphaseCollision(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1) const = 0;
+ virtual btOverlapFilterCallback* getOverlapFilterCallback() = 0;
virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy, btDispatcher* dispatcher) = 0;
virtual void setOverlapFilterCallback(btOverlapFilterCallback* callback) = 0;
@@ -380,6 +381,14 @@ public:
{
}
+ bool needsBroadphaseCollision(btBroadphaseProxy*, btBroadphaseProxy*) const
+ {
+ return true;
+ }
+ btOverlapFilterCallback* getOverlapFilterCallback()
+ {
+ return 0;
+ }
virtual void setOverlapFilterCallback(btOverlapFilterCallback* /*callback*/)
{
}
diff --git a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
index b814fd84d8..4954e773e2 100644
--- a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
+++ b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
@@ -468,7 +468,7 @@ void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCall
#ifdef RAYAABB2
btVector3 rayDir = (rayTarget - raySource);
- rayDir.normalize();
+ rayDir.safeNormalize();// stephengold changed normalize to safeNormalize 2020-02-17
lambda_max = rayDir.dot(rayTarget - raySource);
///what about division by zero? --> just set rayDirection[i] to 1.0
btVector3 rayDirectionInverse;
@@ -554,7 +554,7 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback*
#ifdef RAYAABB2
btVector3 rayDirection = (rayTarget - raySource);
- rayDirection.normalize();
+ rayDirection.safeNormalize();// stephengold changed normalize to safeNormalize 2020-02-17
lambda_max = rayDirection.dot(rayTarget - raySource);
///what about division by zero? --> just set rayDirection[i] to 1.0
rayDirection[0] = rayDirection[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[0];
diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
index 6b9f5e23a5..04309670cf 100644
--- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
+++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
@@ -46,8 +46,6 @@ protected:
btAlignedObjectArray<btPersistentManifold*> m_manifoldsPtr;
- btManifoldResult m_defaultManifoldResult;
-
btNearCallback m_nearCallback;
btPoolAllocator* m_collisionAlgorithmPoolAllocator;
@@ -95,11 +93,15 @@ public:
btPersistentManifold* getManifoldByIndexInternal(int index)
{
+ btAssert(index>=0);
+ btAssert(index<m_manifoldsPtr.size());
return m_manifoldsPtr[index];
}
const btPersistentManifold* getManifoldByIndexInternal(int index) const
{
+ btAssert(index>=0);
+ btAssert(index<m_manifoldsPtr.size());
return m_manifoldsPtr[index];
}
diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp
index 6fe56538d2..89bc8d920e 100644
--- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp
+++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp
@@ -28,6 +28,7 @@ subject to the following restrictions:
btCollisionDispatcherMt::btCollisionDispatcherMt(btCollisionConfiguration* config, int grainSize)
: btCollisionDispatcher(config)
{
+ m_batchManifoldsPtr.resize(btGetTaskScheduler()->getNumThreads());
m_batchUpdating = false;
m_grainSize = grainSize; // iterations per task
}
@@ -65,6 +66,10 @@ btPersistentManifold* btCollisionDispatcherMt::getNewManifold(const btCollisionO
manifold->m_index1a = m_manifoldsPtr.size();
m_manifoldsPtr.push_back(manifold);
}
+ else
+ {
+ m_batchManifoldsPtr[btGetCurrentThreadIndex()].push_back(manifold);
+ }
return manifold;
}
@@ -121,7 +126,7 @@ struct CollisionDispatcherUpdater : public btIParallelForBody
void btCollisionDispatcherMt::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache, const btDispatcherInfo& info, btDispatcher* dispatcher)
{
- int pairCount = pairCache->getNumOverlappingPairs();
+ const int pairCount = pairCache->getNumOverlappingPairs();
if (pairCount == 0)
{
return;
@@ -136,16 +141,17 @@ void btCollisionDispatcherMt::dispatchAllCollisionPairs(btOverlappingPairCache*
btParallelFor(0, pairCount, m_grainSize, updater);
m_batchUpdating = false;
- // reconstruct the manifolds array to ensure determinism
- m_manifoldsPtr.resizeNoInitialize(0);
-
- btBroadphasePair* pairs = pairCache->getOverlappingPairArrayPtr();
- for (int i = 0; i < pairCount; ++i)
+ // merge new manifolds, if any
+ for (int i = 0; i < m_batchManifoldsPtr.size(); ++i)
{
- if (btCollisionAlgorithm* algo = pairs[i].m_algorithm)
+ btAlignedObjectArray<btPersistentManifold*>& batchManifoldsPtr = m_batchManifoldsPtr[i];
+
+ for (int j = 0; j < batchManifoldsPtr.size(); ++j)
{
- algo->getAllContactManifolds(m_manifoldsPtr);
+ m_manifoldsPtr.push_back(batchManifoldsPtr[j]);
}
+
+ batchManifoldsPtr.resizeNoInitialize(0);
}
// update the indices (used when releasing manifolds)
diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h
index 28eba7f32a..1155de2cfe 100644
--- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h
+++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h
@@ -30,6 +30,7 @@ public:
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache, const btDispatcherInfo& info, btDispatcher* dispatcher) BT_OVERRIDE;
protected:
+ btAlignedObjectArray<btAlignedObjectArray<btPersistentManifold*> > m_batchManifoldsPtr;
bool m_batchUpdating;
int m_grainSize;
};
diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
index 1bb21104cb..b5f4a3c869 100644
--- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
+++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
@@ -139,7 +139,12 @@ public:
if (TestAabbAgainstAabb2(aabbMin0, aabbMax0, aabbMin1, aabbMax1))
{
- btCollisionObjectWrapper compoundWrap(this->m_compoundColObjWrap, childShape, m_compoundColObjWrap->getCollisionObject(), newChildWorldTrans, childTrans, -1, index);
+ btTransform preTransform = childTrans;
+ if (this->m_compoundColObjWrap->m_preTransform)
+ {
+ preTransform = preTransform *(*(this->m_compoundColObjWrap->m_preTransform));
+ }
+ btCollisionObjectWrapper compoundWrap(this->m_compoundColObjWrap, childShape, m_compoundColObjWrap->getCollisionObject(), newChildWorldTrans, preTransform, -1, index);
btCollisionAlgorithm* algo = 0;
bool allocatedAlgorithm = false;
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
index e82d1b139e..4356c12abf 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
@@ -46,7 +46,7 @@ struct btContactSolverInfoData
btScalar m_sor; //successive over-relaxation term
btScalar m_erp; //error reduction for non-contact constraints
btScalar m_erp2; //error reduction for contact constraints
- btScalar m_deformable_erp; //error reduction for deformable constraints
+ btScalar m_deformable_erp; //error reduction for deformable constraints
btScalar m_globalCfm; //constraint force mixing for contacts and non-contacts
btScalar m_frictionERP; //error reduction for friction constraints
btScalar m_frictionCFM; //constraint force mixing for friction constraints
@@ -67,6 +67,7 @@ struct btContactSolverInfoData
bool m_jointFeedbackInWorldSpace;
bool m_jointFeedbackInJointFrame;
int m_reportSolverAnalytics;
+ int m_numNonContactInnerIterations;
};
struct btContactSolverInfo : public btContactSolverInfoData
@@ -82,7 +83,7 @@ struct btContactSolverInfo : public btContactSolverInfoData
m_numIterations = 10;
m_erp = btScalar(0.2);
m_erp2 = btScalar(0.2);
- m_deformable_erp = btScalar(0.);
+ m_deformable_erp = btScalar(0.1);
m_globalCfm = btScalar(0.);
m_frictionERP = btScalar(0.2); //positional friction 'anchors' are disabled by default
m_frictionCFM = btScalar(0.);
@@ -104,6 +105,7 @@ struct btContactSolverInfo : public btContactSolverInfoData
m_jointFeedbackInWorldSpace = false;
m_jointFeedbackInJointFrame = false;
m_reportSolverAnalytics = 0;
+ m_numNonContactInnerIterations = 1; // the number of inner iterations for solving motor constraint in a single iteration of the constraint solve
}
};
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp
index 93626f18ff..74a13c6249 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp
@@ -876,7 +876,10 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2(
// will we not request a velocity with the wrong direction ?
// and the answer is not, because in practice during the solving the current velocity is subtracted from the m_constraintError
// so the sign of the force that is really matters
- info->m_constraintError[srow] = (rotational ? -1 : 1) * (f < 0 ? -SIMD_INFINITY : SIMD_INFINITY);
+ if (m_flags & BT_6DOF_FLAGS_USE_INFINITE_ERROR)
+ info->m_constraintError[srow] = (rotational ? -1 : 1) * (f < 0 ? -SIMD_INFINITY : SIMD_INFINITY);
+ else
+ info->m_constraintError[srow] = vel + f / m * (rotational ? -1 : 1);
btScalar minf = f < fd ? f : fd;
btScalar maxf = f < fd ? fd : f;
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h
index 00e24364e0..c86dc373da 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h
@@ -265,6 +265,7 @@ enum bt6DofFlags2
BT_6DOF_FLAGS_ERP_STOP2 = 2,
BT_6DOF_FLAGS_CFM_MOTO2 = 4,
BT_6DOF_FLAGS_ERP_MOTO2 = 8,
+ BT_6DOF_FLAGS_USE_INFINITE_ERROR = (1<<16)
};
#define BT_6DOF_FLAGS_AXIS_SHIFT2 4 // bits per axis
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
index e4da468299..d2641c582f 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
@@ -14,7 +14,9 @@ subject to the following restrictions:
*/
//#define COMPUTE_IMPULSE_DENOM 1
-//#define BT_ADDITIONAL_DEBUG
+#ifdef BT_DEBUG
+# define BT_ADDITIONAL_DEBUG
+#endif
//It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms.
@@ -690,8 +692,10 @@ int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject&
{
#if BT_THREADSAFE
int solverBodyId = -1;
- bool isRigidBodyType = btRigidBody::upcast(&body) != NULL;
- if (isRigidBodyType && !body.isStaticOrKinematicObject())
+ const bool isRigidBodyType = btRigidBody::upcast(&body) != NULL;
+ const bool isStaticOrKinematic = body.isStaticOrKinematicObject();
+ const bool isKinematic = body.isKinematicObject();
+ if (isRigidBodyType && !isStaticOrKinematic)
{
// dynamic body
// Dynamic bodies can only be in one island, so it's safe to write to the companionId
@@ -704,7 +708,7 @@ int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject&
body.setCompanionId(solverBodyId);
}
}
- else if (isRigidBodyType && body.isKinematicObject())
+ else if (isRigidBodyType && isKinematic)
{
//
// NOTE: must test for kinematic before static because some kinematic objects also
diff --git a/thirdparty/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/thirdparty/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
index a3c9f42eb9..fb15ae31eb 100644
--- a/thirdparty/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
+++ b/thirdparty/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
@@ -800,6 +800,14 @@ public:
///don't do CCD when the collision filters are not matching
if (!ClosestConvexResultCallback::needsCollision(proxy0))
return false;
+ if (m_pairCache->getOverlapFilterCallback()) {
+ btBroadphaseProxy* proxy1 = m_me->getBroadphaseHandle();
+ bool collides = m_pairCache->needsBroadphaseCollision(proxy0, proxy1);
+ if (!collides)
+ {
+ return false;
+ }
+ }
btCollisionObject* otherObj = (btCollisionObject*)proxy0->m_clientObject;
diff --git a/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp b/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp
index 9e8705b001..27fdead761 100644
--- a/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp
+++ b/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.cpp
@@ -136,8 +136,13 @@ void btRigidBody::setGravity(const btVector3& acceleration)
void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping)
{
- m_linearDamping = btClamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
- m_angularDamping = btClamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
+#ifdef BT_USE_OLD_DAMPING_METHOD
+ m_linearDamping = btMax(lin_damping, btScalar(0.0));
+ m_angularDamping = btMax(ang_damping, btScalar(0.0));
+#else
+ m_linearDamping = btClamped(lin_damping, btScalar(0.0), btScalar(1.0));
+ m_angularDamping = btClamped(ang_damping, btScalar(0.0), btScalar(1.0));
+#endif
}
///applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping
@@ -146,10 +151,9 @@ void btRigidBody::applyDamping(btScalar timeStep)
//On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74
//todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway
-//#define USE_OLD_DAMPING_METHOD 1
-#ifdef USE_OLD_DAMPING_METHOD
- m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
- m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
+#ifdef BT_USE_OLD_DAMPING_METHOD
+ m_linearVelocity *= btMax((btScalar(1.0) - timeStep * m_linearDamping), btScalar(0.0));
+ m_angularVelocity *= btMax((btScalar(1.0) - timeStep * m_angularDamping), btScalar(0.0));
#else
m_linearVelocity *= btPow(btScalar(1) - m_linearDamping, timeStep);
m_angularVelocity *= btPow(btScalar(1) - m_angularDamping, timeStep);
@@ -380,6 +384,9 @@ void btRigidBody::integrateVelocities(btScalar step)
{
m_angularVelocity *= (MAX_ANGVEL / step) / angvel;
}
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ clampVelocity(m_angularVelocity);
+ #endif
}
btQuaternion btRigidBody::getOrientation() const
diff --git a/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.h b/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.h
index 39d47cbbda..943d724cce 100644
--- a/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.h
+++ b/thirdparty/bullet/BulletDynamics/Dynamics/btRigidBody.h
@@ -305,6 +305,9 @@ public:
void applyTorque(const btVector3& torque)
{
m_totalTorque += torque * m_angularFactor;
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ clampVelocity(m_totalTorque);
+ #endif
}
void applyForce(const btVector3& force, const btVector3& rel_pos)
@@ -316,11 +319,17 @@ public:
void applyCentralImpulse(const btVector3& impulse)
{
m_linearVelocity += impulse * m_linearFactor * m_inverseMass;
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ clampVelocity(m_linearVelocity);
+ #endif
}
void applyTorqueImpulse(const btVector3& torque)
{
m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ clampVelocity(m_angularVelocity);
+ #endif
}
void applyImpulse(const btVector3& impulse, const btVector3& rel_pos)
@@ -361,20 +370,46 @@ public:
{
m_pushVelocity = v;
}
-
+
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ void clampVelocity(btVector3& v) const {
+ v.setX(
+ fmax(-BT_CLAMP_VELOCITY_TO,
+ fmin(BT_CLAMP_VELOCITY_TO, v.getX()))
+ );
+ v.setY(
+ fmax(-BT_CLAMP_VELOCITY_TO,
+ fmin(BT_CLAMP_VELOCITY_TO, v.getY()))
+ );
+ v.setZ(
+ fmax(-BT_CLAMP_VELOCITY_TO,
+ fmin(BT_CLAMP_VELOCITY_TO, v.getZ()))
+ );
+ }
+ #endif
+
void setTurnVelocity(const btVector3& v)
{
m_turnVelocity = v;
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ clampVelocity(m_turnVelocity);
+ #endif
}
void applyCentralPushImpulse(const btVector3& impulse)
{
m_pushVelocity += impulse * m_linearFactor * m_inverseMass;
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ clampVelocity(m_pushVelocity);
+ #endif
}
void applyTorqueTurnImpulse(const btVector3& torque)
{
m_turnVelocity += m_invInertiaTensorWorld * torque * m_angularFactor;
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ clampVelocity(m_turnVelocity);
+ #endif
}
void clearForces()
@@ -408,12 +443,18 @@ public:
{
m_updateRevision++;
m_linearVelocity = lin_vel;
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ clampVelocity(m_linearVelocity);
+ #endif
}
inline void setAngularVelocity(const btVector3& ang_vel)
{
m_updateRevision++;
m_angularVelocity = ang_vel;
+ #if defined(BT_CLAMP_VELOCITY_TO) && BT_CLAMP_VELOCITY_TO > 0
+ clampVelocity(m_angularVelocity);
+ #endif
}
btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
diff --git a/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp b/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp
index 5353fe009e..772b774202 100644
--- a/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp
+++ b/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp
@@ -171,6 +171,8 @@ void btSimulationIslandManagerMt::initIslandPools()
btSimulationIslandManagerMt::Island* btSimulationIslandManagerMt::getIsland(int id)
{
+ btAssert(id >= 0);
+ btAssert(id < m_lookupIslandFromId.size());
Island* island = m_lookupIslandFromId[id];
if (island == NULL)
{
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp
index bdaa473476..a1d5bb9ca8 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp
@@ -583,52 +583,6 @@ void btMultiBody::compTreeLinkVelocities(btVector3 *omega, btVector3 *vel) const
}
}
-btScalar btMultiBody::getKineticEnergy() const
-{
- int num_links = getNumLinks();
- // TODO: would be better not to allocate memory here
- btAlignedObjectArray<btVector3> omega;
- omega.resize(num_links + 1);
- btAlignedObjectArray<btVector3> vel;
- vel.resize(num_links + 1);
- compTreeLinkVelocities(&omega[0], &vel[0]);
-
- // we will do the factor of 0.5 at the end
- btScalar result = m_baseMass * vel[0].dot(vel[0]);
- result += omega[0].dot(m_baseInertia * omega[0]);
-
- for (int i = 0; i < num_links; ++i)
- {
- result += m_links[i].m_mass * vel[i + 1].dot(vel[i + 1]);
- result += omega[i + 1].dot(m_links[i].m_inertiaLocal * omega[i + 1]);
- }
-
- return 0.5f * result;
-}
-
-btVector3 btMultiBody::getAngularMomentum() const
-{
- int num_links = getNumLinks();
- // TODO: would be better not to allocate memory here
- btAlignedObjectArray<btVector3> omega;
- omega.resize(num_links + 1);
- btAlignedObjectArray<btVector3> vel;
- vel.resize(num_links + 1);
- btAlignedObjectArray<btQuaternion> rot_from_world;
- rot_from_world.resize(num_links + 1);
- compTreeLinkVelocities(&omega[0], &vel[0]);
-
- rot_from_world[0] = m_baseQuat;
- btVector3 result = quatRotate(rot_from_world[0].inverse(), (m_baseInertia * omega[0]));
-
- for (int i = 0; i < num_links; ++i)
- {
- rot_from_world[i + 1] = m_links[i].m_cachedRotParentToThis * rot_from_world[m_links[i].m_parent + 1];
- result += (quatRotate(rot_from_world[i + 1].inverse(), (m_links[i].m_inertiaLocal * omega[i + 1])));
- }
-
- return result;
-}
void btMultiBody::clearConstraintForces()
{
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h
index afed669a7b..be795633fd 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h
@@ -307,13 +307,6 @@ public:
//
btMatrix3x3 localFrameToWorld(int i, const btMatrix3x3 &local_frame) const;
- //
- // calculate kinetic energy and angular momentum
- // useful for debugging.
- //
-
- btScalar getKineticEnergy() const;
- btVector3 getAngularMomentum() const;
//
// set external forces and torques. Note all external forces/torques are given in the WORLD frame.
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
index ffae5300f0..2788367431 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
@@ -30,23 +30,28 @@ btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btColl
btScalar leastSquaredResidual = btSequentialImpulseConstraintSolver::solveSingleIteration(iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer);
//solve featherstone non-contact constraints
-
+ btScalar nonContactResidual = 0;
//printf("m_multiBodyNonContactConstraints = %d\n",m_multiBodyNonContactConstraints.size());
-
- for (int j = 0; j < m_multiBodyNonContactConstraints.size(); j++)
+ for (int i = 0; i < infoGlobal.m_numNonContactInnerIterations; ++i)
{
- int index = iteration & 1 ? j : m_multiBodyNonContactConstraints.size() - 1 - j;
+ // reset the nonContactResdual to 0 at start of each inner iteration
+ nonContactResidual = 0;
+ for (int j = 0; j < m_multiBodyNonContactConstraints.size(); j++)
+ {
+ int index = iteration & 1 ? j : m_multiBodyNonContactConstraints.size() - 1 - j;
- btMultiBodySolverConstraint& constraint = m_multiBodyNonContactConstraints[index];
+ btMultiBodySolverConstraint& constraint = m_multiBodyNonContactConstraints[index];
- btScalar residual = resolveSingleConstraintRowGeneric(constraint);
- leastSquaredResidual = btMax(leastSquaredResidual, residual * residual);
+ btScalar residual = resolveSingleConstraintRowGeneric(constraint);
+ nonContactResidual = btMax(nonContactResidual, residual * residual);
- if (constraint.m_multiBodyA)
- constraint.m_multiBodyA->setPosUpdated(false);
- if (constraint.m_multiBodyB)
- constraint.m_multiBodyB->setPosUpdated(false);
+ if (constraint.m_multiBodyA)
+ constraint.m_multiBodyA->setPosUpdated(false);
+ if (constraint.m_multiBodyB)
+ constraint.m_multiBodyB->setPosUpdated(false);
+ }
}
+ leastSquaredResidual = btMax(leastSquaredResidual, nonContactResidual);
//solve featherstone normal contact
for (int j0 = 0; j0 < m_multiBodyNormalContactConstraints.size(); j0++)
@@ -1250,7 +1255,7 @@ void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold*
{
const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1());
-
+
btMultiBody* mbA = fcA ? fcA->m_multiBody : 0;
btMultiBody* mbB = fcB ? fcB->m_multiBody : 0;
@@ -1270,7 +1275,7 @@ void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold*
// return;
//only a single rollingFriction per manifold
- int rollingFriction = 1;
+ int rollingFriction = 4;
for (int j = 0; j < manifold->getNumContacts(); j++)
{
diff --git a/thirdparty/bullet/BulletSoftBody/btConjugateResidual.h b/thirdparty/bullet/BulletSoftBody/btConjugateResidual.h
new file mode 100644
index 0000000000..7b211c4172
--- /dev/null
+++ b/thirdparty/bullet/BulletSoftBody/btConjugateResidual.h
@@ -0,0 +1,188 @@
+/*
+ Written by Xuchen Han <xuchenhan2015@u.northwestern.edu>
+
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef BT_CONJUGATE_RESIDUAL_H
+#define BT_CONJUGATE_RESIDUAL_H
+#include <iostream>
+#include <cmath>
+#include <limits>
+#include <LinearMath/btAlignedObjectArray.h>
+#include <LinearMath/btVector3.h>
+#include <LinearMath/btScalar.h>
+#include "LinearMath/btQuickprof.h"
+template <class MatrixX>
+class btConjugateResidual
+{
+ typedef btAlignedObjectArray<btVector3> TVStack;
+ TVStack r,p,z,temp_p, temp_r, best_x;
+ // temp_r = A*r
+ // temp_p = A*p
+ // z = M^(-1) * temp_p = M^(-1) * A * p
+ int max_iterations;
+ btScalar tolerance_squared, best_r;
+public:
+ btConjugateResidual(const int max_it_in)
+ : max_iterations(max_it_in)
+ {
+ tolerance_squared = 1e-2;
+ }
+
+ virtual ~btConjugateResidual(){}
+
+ // return the number of iterations taken
+ int solve(MatrixX& A, TVStack& x, const TVStack& b, bool verbose = false)
+ {
+ BT_PROFILE("CRSolve");
+ btAssert(x.size() == b.size());
+ reinitialize(b);
+ // r = b - A * x --with assigned dof zeroed out
+ A.multiply(x, temp_r); // borrow temp_r here to store A*x
+ r = sub(b, temp_r);
+ // z = M^(-1) * r
+ A.precondition(r, z); // borrow z to store preconditioned r
+ r = z;
+ btScalar residual_norm = norm(r);
+ if (residual_norm <= tolerance_squared) {
+ if (verbose)
+ {
+ std::cout << "Iteration = 0" << std::endl;
+ std::cout << "Two norm of the residual = " << residual_norm << std::endl;
+ }
+ return 0;
+ }
+ p = r;
+ btScalar r_dot_Ar, r_dot_Ar_new;
+ // temp_p = A*p
+ A.multiply(p, temp_p);
+ // temp_r = A*r
+ temp_r = temp_p;
+ r_dot_Ar = dot(r, temp_r);
+ for (int k = 1; k <= max_iterations; k++) {
+ // z = M^(-1) * Ap
+ A.precondition(temp_p, z);
+ // alpha = r^T * A * r / (Ap)^T * M^-1 * Ap)
+ btScalar alpha = r_dot_Ar / dot(temp_p, z);
+ // x += alpha * p;
+ multAndAddTo(alpha, p, x);
+ // r -= alpha * z;
+ multAndAddTo(-alpha, z, r);
+ btScalar norm_r = norm(r);
+ if (norm_r < best_r)
+ {
+ best_x = x;
+ best_r = norm_r;
+ if (norm_r < tolerance_squared) {
+ if (verbose)
+ {
+ std::cout << "ConjugateResidual iterations " << k << std::endl;
+ }
+ return k;
+ }
+ else
+ {
+ if (verbose)
+ {
+ std::cout << "ConjugateResidual iterations " << k << " has residual "<< norm_r << std::endl;
+ }
+ }
+ }
+ // temp_r = A * r;
+ A.multiply(r, temp_r);
+ r_dot_Ar_new = dot(r, temp_r);
+ btScalar beta = r_dot_Ar_new/r_dot_Ar;
+ r_dot_Ar = r_dot_Ar_new;
+ // p = beta*p + r;
+ p = multAndAdd(beta, p, r);
+ // temp_p = beta*temp_p + temp_r;
+ temp_p = multAndAdd(beta, temp_p, temp_r);
+ }
+ if (verbose)
+ {
+ std::cout << "ConjugateResidual max iterations reached " << max_iterations << std::endl;
+ }
+ x = best_x;
+ return max_iterations;
+ }
+
+ void reinitialize(const TVStack& b)
+ {
+ r.resize(b.size());
+ p.resize(b.size());
+ z.resize(b.size());
+ temp_p.resize(b.size());
+ temp_r.resize(b.size());
+ best_x.resize(b.size());
+ best_r = SIMD_INFINITY;
+ }
+
+ TVStack sub(const TVStack& a, const TVStack& b)
+ {
+ // c = a-b
+ btAssert(a.size() == b.size());
+ TVStack c;
+ c.resize(a.size());
+ for (int i = 0; i < a.size(); ++i)
+ {
+ c[i] = a[i] - b[i];
+ }
+ return c;
+ }
+
+ btScalar squaredNorm(const TVStack& a)
+ {
+ return dot(a,a);
+ }
+
+ btScalar norm(const TVStack& a)
+ {
+ btScalar ret = 0;
+ for (int i = 0; i < a.size(); ++i)
+ {
+ for (int d = 0; d < 3; ++d)
+ {
+ ret = btMax(ret, btFabs(a[i][d]));
+ }
+ }
+ return ret;
+ }
+
+ btScalar dot(const TVStack& a, const TVStack& b)
+ {
+ btScalar ans(0);
+ for (int i = 0; i < a.size(); ++i)
+ ans += a[i].dot(b[i]);
+ return ans;
+ }
+
+ void multAndAddTo(btScalar s, const TVStack& a, TVStack& result)
+ {
+ // result += s*a
+ btAssert(a.size() == result.size());
+ for (int i = 0; i < a.size(); ++i)
+ result[i] += s * a[i];
+ }
+
+ TVStack multAndAdd(btScalar s, const TVStack& a, const TVStack& b)
+ {
+ // result = a*s + b
+ TVStack result;
+ result.resize(a.size());
+ for (int i = 0; i < a.size(); ++i)
+ result[i] = s * a[i] + b[i];
+ return result;
+ }
+};
+#endif /* btConjugateResidual_h */
+
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.cpp
index 1b247641aa..5381ee6265 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.cpp
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.cpp
@@ -23,12 +23,15 @@ btDeformableBackwardEulerObjective::btDeformableBackwardEulerObjective(btAligned
, m_backupVelocity(backup_v)
, m_implicit(false)
{
- m_preconditioner = new MassPreconditioner(m_softBodies);
+ m_massPreconditioner = new MassPreconditioner(m_softBodies);
+ m_KKTPreconditioner = new KKTPreconditioner(m_softBodies, m_projection, m_lf, m_dt, m_implicit);
+ m_preconditioner = m_KKTPreconditioner;
}
btDeformableBackwardEulerObjective::~btDeformableBackwardEulerObjective()
{
- delete m_preconditioner;
+ delete m_KKTPreconditioner;
+ delete m_massPreconditioner;
}
void btDeformableBackwardEulerObjective::reinitialize(bool nodeUpdated, btScalar dt)
@@ -47,7 +50,7 @@ void btDeformableBackwardEulerObjective::reinitialize(bool nodeUpdated, btScalar
m_lf[i]->reinitialize(nodeUpdated);
}
m_projection.reinitialize(nodeUpdated);
- m_preconditioner->reinitialize(nodeUpdated);
+// m_preconditioner->reinitialize(nodeUpdated);
}
void btDeformableBackwardEulerObjective::setDt(btScalar dt)
@@ -80,6 +83,33 @@ void btDeformableBackwardEulerObjective::multiply(const TVStack& x, TVStack& b)
m_lf[i]->addScaledElasticForceDifferential(-m_dt*m_dt, x, b);
}
}
+ int offset = m_nodes.size();
+ for (int i = offset; i < b.size(); ++i)
+ {
+ b[i].setZero();
+ }
+ // add in the lagrange multiplier terms
+
+ for (int c = 0; c < m_projection.m_lagrangeMultipliers.size(); ++c)
+ {
+ // C^T * lambda
+ const LagrangeMultiplier& lm = m_projection.m_lagrangeMultipliers[c];
+ for (int i = 0; i < lm.m_num_nodes; ++i)
+ {
+ for (int j = 0; j < lm.m_num_constraints; ++j)
+ {
+ b[lm.m_indices[i]] += x[offset+c][j] * lm.m_weights[i] * lm.m_dirs[j];
+ }
+ }
+ // C * x
+ for (int d = 0; d < lm.m_num_constraints; ++d)
+ {
+ for (int i = 0; i < lm.m_num_nodes; ++i)
+ {
+ b[offset+c][d] += lm.m_weights[i] * x[lm.m_indices[i]].dot(lm.m_dirs[d]);
+ }
+ }
+ }
}
void btDeformableBackwardEulerObjective::updateVelocity(const TVStack& dv)
@@ -134,7 +164,7 @@ void btDeformableBackwardEulerObjective::computeResidual(btScalar dt, TVStack &r
m_lf[i]->addScaledDampingForce(dt, residual);
}
}
- m_projection.project(residual);
+// m_projection.project(residual);
}
btScalar btDeformableBackwardEulerObjective::computeNorm(const TVStack& residual) const
@@ -186,9 +216,9 @@ void btDeformableBackwardEulerObjective::initialGuess(TVStack& dv, const TVStack
}
//set constraints as projections
-void btDeformableBackwardEulerObjective::setConstraints()
+void btDeformableBackwardEulerObjective::setConstraints(const btContactSolverInfo& infoGlobal)
{
- m_projection.setConstraints();
+ m_projection.setConstraints(infoGlobal);
}
void btDeformableBackwardEulerObjective::applyDynamicFriction(TVStack& r)
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.h b/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.h
index 05ab42ff0a..86579e71ac 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.h
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableBackwardEulerObjective.h
@@ -15,11 +15,12 @@
#ifndef BT_BACKWARD_EULER_OBJECTIVE_H
#define BT_BACKWARD_EULER_OBJECTIVE_H
-#include "btConjugateGradient.h"
+//#include "btConjugateGradient.h"
#include "btDeformableLagrangianForce.h"
#include "btDeformableMassSpringForce.h"
#include "btDeformableGravityForce.h"
#include "btDeformableCorotatedForce.h"
+#include "btDeformableMousePickingForce.h"
#include "btDeformableLinearElasticityForce.h"
#include "btDeformableNeoHookeanForce.h"
#include "btDeformableContactProjection.h"
@@ -39,6 +40,8 @@ public:
const TVStack& m_backupVelocity;
btAlignedObjectArray<btSoftBody::Node* > m_nodes;
bool m_implicit;
+ MassPreconditioner* m_massPreconditioner;
+ KKTPreconditioner* m_KKTPreconditioner;
btDeformableBackwardEulerObjective(btAlignedObjectArray<btSoftBody *>& softBodies, const TVStack& backup_v);
@@ -79,7 +82,7 @@ public:
void updateVelocity(const TVStack& dv);
//set constraints as projections
- void setConstraints();
+ void setConstraints(const btContactSolverInfo& infoGlobal);
// update the projections and project the residual
void project(TVStack& r)
@@ -129,6 +132,42 @@ public:
// Calculate the total potential energy in the system
btScalar totalEnergy(btScalar dt);
+
+ void addLagrangeMultiplier(const TVStack& vec, TVStack& extended_vec)
+ {
+ extended_vec.resize(vec.size() + m_projection.m_lagrangeMultipliers.size());
+ for (int i = 0; i < vec.size(); ++i)
+ {
+ extended_vec[i] = vec[i];
+ }
+ int offset = vec.size();
+ for (int i = 0; i < m_projection.m_lagrangeMultipliers.size(); ++i)
+ {
+ extended_vec[offset + i].setZero();
+ }
+ }
+
+ void addLagrangeMultiplierRHS(const TVStack& residual, const TVStack& m_dv, TVStack& extended_residual)
+ {
+ extended_residual.resize(residual.size() + m_projection.m_lagrangeMultipliers.size());
+ for (int i = 0; i < residual.size(); ++i)
+ {
+ extended_residual[i] = residual[i];
+ }
+ int offset = residual.size();
+ for (int i = 0; i < m_projection.m_lagrangeMultipliers.size(); ++i)
+ {
+ const LagrangeMultiplier& lm = m_projection.m_lagrangeMultipliers[i];
+ extended_residual[offset + i].setZero();
+ for (int d = 0; d < lm.m_num_constraints; ++d)
+ {
+ for (int n = 0; n < lm.m_num_nodes; ++n)
+ {
+ extended_residual[offset + i][d] += lm.m_weights[n] * m_dv[lm.m_indices[n]].dot(lm.m_dirs[d]);
+ }
+ }
+ }
+ }
};
#endif /* btBackwardEulerObjective_h */
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp
index 7724a8ec69..132699c54f 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.cpp
@@ -18,13 +18,15 @@
#include "btDeformableBodySolver.h"
#include "btSoftBodyInternals.h"
#include "LinearMath/btQuickprof.h"
-static const int kMaxConjugateGradientIterations = 50;
+static const int kMaxConjugateGradientIterations = 50;
btDeformableBodySolver::btDeformableBodySolver()
: m_numNodes(0)
, m_cg(kMaxConjugateGradientIterations)
+, m_cr(kMaxConjugateGradientIterations)
, m_maxNewtonIterations(5)
, m_newtonTolerance(1e-4)
, m_lineSearch(false)
+, m_useProjection(false)
{
m_objective = new btDeformableBackwardEulerObjective(m_softBodies, m_backupVelocity);
}
@@ -41,7 +43,22 @@ void btDeformableBodySolver::solveDeformableConstraints(btScalar solverdt)
{
m_objective->computeResidual(solverdt, m_residual);
m_objective->applyDynamicFriction(m_residual);
- computeStep(m_dv, m_residual);
+ if (m_useProjection)
+ {
+ computeStep(m_dv, m_residual);
+ }
+ else
+ {
+ TVStack rhs, x;
+ m_objective->addLagrangeMultiplierRHS(m_residual, m_dv, rhs);
+ m_objective->addLagrangeMultiplier(m_dv, x);
+ m_objective->m_preconditioner->reinitialize(true);
+ computeStep(x, rhs);
+ for (int i = 0; i<m_dv.size(); ++i)
+ {
+ m_dv[i] = x[i];
+ }
+ }
updateVelocity();
}
else
@@ -63,7 +80,7 @@ void btDeformableBodySolver::solveDeformableConstraints(btScalar solverdt)
++counter;
}
}
-
+
m_objective->computeResidual(solverdt, m_residual);
if (m_objective->computeNorm(m_residual) < m_newtonTolerance && i > 0)
{
@@ -200,7 +217,10 @@ void btDeformableBodySolver::updateDv(btScalar scale)
void btDeformableBodySolver::computeStep(TVStack& ddv, const TVStack& residual)
{
- m_cg.solve(*m_objective, ddv, residual);
+ if (m_useProjection)
+ m_cg.solve(*m_objective, ddv, residual, false);
+ else
+ m_cr.solve(*m_objective, ddv, residual, false);
}
void btDeformableBodySolver::reinitialize(const btAlignedObjectArray<btSoftBody *>& softBodies, btScalar dt)
@@ -226,27 +246,22 @@ void btDeformableBodySolver::reinitialize(const btAlignedObjectArray<btSoftBody
m_dt = dt;
m_objective->reinitialize(nodeUpdated, dt);
+ updateSoftBodies();
}
-void btDeformableBodySolver::setConstraints()
+void btDeformableBodySolver::setConstraints(const btContactSolverInfo& infoGlobal)
{
BT_PROFILE("setConstraint");
- m_objective->setConstraints();
+ m_objective->setConstraints(infoGlobal);
}
-btScalar btDeformableBodySolver::solveContactConstraints(btCollisionObject** deformableBodies,int numDeformableBodies)
+btScalar btDeformableBodySolver::solveContactConstraints(btCollisionObject** deformableBodies,int numDeformableBodies, const btContactSolverInfo& infoGlobal)
{
BT_PROFILE("solveContactConstraints");
- btScalar maxSquaredResidual = m_objective->m_projection.update(deformableBodies,numDeformableBodies);
+ btScalar maxSquaredResidual = m_objective->m_projection.update(deformableBodies,numDeformableBodies, infoGlobal);
return maxSquaredResidual;
}
-btScalar btDeformableBodySolver::solveSplitImpulse(const btContactSolverInfo& infoGlobal)
-{
- BT_PROFILE("solveSplitImpulse");
- return m_objective->m_projection.solveSplitImpulse(infoGlobal);
-}
-
void btDeformableBodySolver::splitImpulseSetup(const btContactSolverInfo& infoGlobal)
{
m_objective->m_projection.splitImpulseSetup(infoGlobal);
@@ -333,8 +348,10 @@ void btDeformableBodySolver::setupDeformableSolve(bool implicit)
m_backupVelocity[counter] = psb->m_nodes[j].m_vn;
}
else
+ {
m_dv[counter] = psb->m_nodes[j].m_v - m_backupVelocity[counter];
- psb->m_nodes[j].m_v = m_backupVelocity[counter] + psb->m_nodes[j].m_vsplit;
+ }
+ psb->m_nodes[j].m_v = m_backupVelocity[counter];
++counter;
}
}
@@ -385,6 +402,7 @@ void btDeformableBodySolver::predictMotion(btScalar solverdt)
void btDeformableBodySolver::predictDeformableMotion(btSoftBody* psb, btScalar dt)
{
+ BT_PROFILE("btDeformableBodySolver::predictDeformableMotion");
int i, ni;
/* Update */
@@ -423,40 +441,22 @@ void btDeformableBodySolver::predictDeformableMotion(btSoftBody* psb, btScalar d
n.m_v *= max_v;
}
n.m_q = n.m_x + n.m_v * dt;
+ n.m_penetration = 0;
}
/* Nodes */
- ATTRIBUTE_ALIGNED16(btDbvtVolume)
- vol;
- for (i = 0, ni = psb->m_nodes.size(); i < ni; ++i)
- {
- btSoftBody::Node& n = psb->m_nodes[i];
- btVector3 points[2] = {n.m_x, n.m_q};
- vol = btDbvtVolume::FromPoints(points, 2);
- vol.Expand(btVector3(psb->m_sst.radmrg, psb->m_sst.radmrg, psb->m_sst.radmrg));
- psb->m_ndbvt.update(n.m_leaf, vol);
- }
-
+ psb->updateNodeTree(true, true);
if (!psb->m_fdbvt.empty())
{
- for (int i = 0; i < psb->m_faces.size(); ++i)
- {
- btSoftBody::Face& f = psb->m_faces[i];
- btVector3 points[6] = {f.m_n[0]->m_x, f.m_n[0]->m_q,
- f.m_n[1]->m_x, f.m_n[1]->m_q,
- f.m_n[2]->m_x, f.m_n[2]->m_q};
- vol = btDbvtVolume::FromPoints(points, 6);
- vol.Expand(btVector3(psb->m_sst.radmrg, psb->m_sst.radmrg, psb->m_sst.radmrg));
- psb->m_fdbvt.update(f.m_leaf, vol);
- }
+ psb->updateFaceTree(true, true);
}
- /* Clear contacts */
+ /* Clear contacts */
psb->m_nodeRigidContacts.resize(0);
psb->m_faceRigidContacts.resize(0);
psb->m_faceNodeContacts.resize(0);
/* Optimize dbvt's */
- psb->m_ndbvt.optimizeIncremental(1);
- psb->m_fdbvt.optimizeIncremental(1);
+// psb->m_ndbvt.optimizeIncremental(1);
+// psb->m_fdbvt.optimizeIncremental(1);
}
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.h b/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.h
index f78a8f696b..d4e5f4c603 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.h
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableBodySolver.h
@@ -22,7 +22,8 @@
#include "btDeformableMultiBodyDynamicsWorld.h"
#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraint.h"
-
+#include "btConjugateResidual.h"
+#include "btConjugateGradient.h"
struct btCollisionObjectWrapper;
class btDeformableBackwardEulerObjective;
class btDeformableMultiBodyDynamicsWorld;
@@ -40,14 +41,15 @@ protected:
TVStack m_backupVelocity; // backed up v, equals v_n for implicit, equals v_{n+1}^* for explicit
btScalar m_dt; // dt
btConjugateGradient<btDeformableBackwardEulerObjective> m_cg; // CG solver
+ btConjugateResidual<btDeformableBackwardEulerObjective> m_cr; // CR solver
bool m_implicit; // use implicit scheme if true, explicit scheme if false
int m_maxNewtonIterations; // max number of newton iterations
btScalar m_newtonTolerance; // stop newton iterations if f(x) < m_newtonTolerance
bool m_lineSearch; // If true, use newton's method with line search under implicit scheme
-
public:
// handles data related to objective function
btDeformableBackwardEulerObjective* m_objective;
+ bool m_useProjection;
btDeformableBodySolver();
@@ -61,15 +63,11 @@ public:
// update soft body normals
virtual void updateSoftBodies();
+ virtual btScalar solveContactConstraints(btCollisionObject** deformableBodies,int numDeformableBodies, const btContactSolverInfo& infoGlobal);
+
// solve the momentum equation
virtual void solveDeformableConstraints(btScalar solverdt);
- // solve the contact between deformable and rigid as well as among deformables
- btScalar solveContactConstraints(btCollisionObject** deformableBodies,int numDeformableBodies);
-
- // solve the position error between deformable and rigid as well as among deformables;
- btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal);
-
// set up the position error in split impulse
void splitImpulseSetup(const btContactSolverInfo& infoGlobal);
@@ -77,7 +75,7 @@ public:
void reinitialize(const btAlignedObjectArray<btSoftBody *>& softBodies, btScalar dt);
// set up contact constraints
- void setConstraints();
+ void setConstraints(const btContactSolverInfo& infoGlobal);
// add in elastic forces and gravity to obtain v_{n+1}^* and calls predictDeformableMotion
virtual void predictMotion(btScalar solverdt);
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.cpp
index e8219dc50e..2864446de6 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.cpp
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.cpp
@@ -15,9 +15,9 @@
#include "btDeformableContactConstraint.h"
/* ================ Deformable Node Anchor =================== */
-btDeformableNodeAnchorConstraint::btDeformableNodeAnchorConstraint(const btSoftBody::DeformableNodeRigidAnchor& a)
+btDeformableNodeAnchorConstraint::btDeformableNodeAnchorConstraint(const btSoftBody::DeformableNodeRigidAnchor& a, const btContactSolverInfo& infoGlobal)
: m_anchor(&a)
-, btDeformableContactConstraint(a.m_cti.m_normal)
+, btDeformableContactConstraint(a.m_cti.m_normal, infoGlobal)
{
}
@@ -79,14 +79,14 @@ btVector3 btDeformableNodeAnchorConstraint::getVa() const
return va;
}
-btScalar btDeformableNodeAnchorConstraint::solveConstraint()
+btScalar btDeformableNodeAnchorConstraint::solveConstraint(const btContactSolverInfo& infoGlobal)
{
const btSoftBody::sCti& cti = m_anchor->m_cti;
btVector3 va = getVa();
btVector3 vb = getVb();
btVector3 vr = (vb - va);
// + (m_anchor->m_node->m_x - cti.m_colObj->getWorldTransform() * m_anchor->m_local) * 10.0
- const btScalar dn = btDot(vr, cti.m_normal);
+ const btScalar dn = btDot(vr, vr);
// dn is the normal component of velocity diffrerence. Approximates the residual. // todo xuchenhan@: this prob needs to be scaled by dt
btScalar residualSquare = dn*dn;
btVector3 impulse = m_anchor->m_c0 * vr;
@@ -134,14 +134,15 @@ void btDeformableNodeAnchorConstraint::applyImpulse(const btVector3& impulse)
}
/* ================ Deformable vs. Rigid =================== */
-btDeformableRigidContactConstraint::btDeformableRigidContactConstraint(const btSoftBody::DeformableRigidContact& c)
+btDeformableRigidContactConstraint::btDeformableRigidContactConstraint(const btSoftBody::DeformableRigidContact& c, const btContactSolverInfo& infoGlobal)
: m_contact(&c)
-, btDeformableContactConstraint(c.m_cti.m_normal)
+, btDeformableContactConstraint(c.m_cti.m_normal, infoGlobal)
{
m_total_normal_dv.setZero();
m_total_tangent_dv.setZero();
- // penetration is non-positive. The magnitude of penetration is the depth of penetration.
- m_penetration = btMin(btScalar(0), c.m_cti.m_offset);
+ // The magnitude of penetration is the depth of penetration.
+ m_penetration = c.m_cti.m_offset;
+// m_penetration = btMin(btScalar(0),c.m_cti.m_offset);
}
btDeformableRigidContactConstraint::btDeformableRigidContactConstraint(const btDeformableRigidContactConstraint& other)
@@ -206,16 +207,16 @@ btVector3 btDeformableRigidContactConstraint::getVa() const
return va;
}
-btScalar btDeformableRigidContactConstraint::solveConstraint()
+btScalar btDeformableRigidContactConstraint::solveConstraint(const btContactSolverInfo& infoGlobal)
{
const btSoftBody::sCti& cti = m_contact->m_cti;
btVector3 va = getVa();
btVector3 vb = getVb();
btVector3 vr = vb - va;
- const btScalar dn = btDot(vr, cti.m_normal);
+ btScalar dn = btDot(vr, cti.m_normal) + m_penetration * infoGlobal.m_deformable_erp / infoGlobal.m_timeStep;
// dn is the normal component of velocity diffrerence. Approximates the residual. // todo xuchenhan@: this prob needs to be scaled by dt
btScalar residualSquare = dn*dn;
- btVector3 impulse = m_contact->m_c0 * vr;
+ btVector3 impulse = m_contact->m_c0 * (vr + m_penetration * infoGlobal.m_deformable_erp / infoGlobal.m_timeStep * cti.m_normal) ;
const btVector3 impulse_normal = m_contact->m_c0 * (cti.m_normal * dn);
btVector3 impulse_tangent = impulse - impulse_normal;
btVector3 old_total_tangent_dv = m_total_tangent_dv;
@@ -256,6 +257,8 @@ btScalar btDeformableRigidContactConstraint::solveConstraint()
impulse = impulse_normal + impulse_tangent;
// apply impulse to deformable nodes involved and change their velocities
applyImpulse(impulse);
+ if (residualSquare < 1e-7)
+ return residualSquare;
// apply impulse to the rigid/multibodies involved and change their velocities
if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY)
{
@@ -285,43 +288,17 @@ btScalar btDeformableRigidContactConstraint::solveConstraint()
}
}
}
+// va = getVa();
+// vb = getVb();
+// vr = vb - va;
+// btScalar dn1 = btDot(vr, cti.m_normal) / 150;
+// m_penetration += dn1;
return residualSquare;
}
-
-btScalar btDeformableRigidContactConstraint::solveSplitImpulse(const btContactSolverInfo& infoGlobal)
-{
- const btSoftBody::sCti& cti = m_contact->m_cti;
- const btScalar dn = m_penetration;
- if (dn != 0)
- {
- const btVector3 impulse = (m_contact->m_c0 * (cti.m_normal * dn / infoGlobal.m_timeStep));
- // one iteration of the position impulse corrects all the position error at this timestep
- m_penetration -= dn;
- // apply impulse to deformable nodes involved and change their position
- applySplitImpulse(impulse);
- // apply impulse to the rigid/multibodies involved and change their position
- if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY)
- {
- btRigidBody* rigidCol = 0;
- rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj);
- if (rigidCol)
- {
- rigidCol->applyPushImpulse(impulse, m_contact->m_c1);
- }
- }
- else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK)
- {
- // todo xuchenhan@
- }
- return (m_penetration/infoGlobal.m_timeStep) * (m_penetration/infoGlobal.m_timeStep);
- }
- return 0;
-}
-
/* ================ Node vs. Rigid =================== */
-btDeformableNodeRigidContactConstraint::btDeformableNodeRigidContactConstraint(const btSoftBody::DeformableNodeRigidContact& contact)
+btDeformableNodeRigidContactConstraint::btDeformableNodeRigidContactConstraint(const btSoftBody::DeformableNodeRigidContact& contact, const btContactSolverInfo& infoGlobal)
: m_node(contact.m_node)
- , btDeformableRigidContactConstraint(contact)
+ , btDeformableRigidContactConstraint(contact, infoGlobal)
{
}
@@ -349,22 +326,17 @@ void btDeformableNodeRigidContactConstraint::applyImpulse(const btVector3& impul
contact->m_node->m_v -= dv;
}
-void btDeformableNodeRigidContactConstraint::applySplitImpulse(const btVector3& impulse)
-{
- const btSoftBody::DeformableNodeRigidContact* contact = getContact();
- btVector3 dv = impulse * contact->m_c2;
- contact->m_node->m_vsplit -= dv;
-};
-
/* ================ Face vs. Rigid =================== */
-btDeformableFaceRigidContactConstraint::btDeformableFaceRigidContactConstraint(const btSoftBody::DeformableFaceRigidContact& contact)
+btDeformableFaceRigidContactConstraint::btDeformableFaceRigidContactConstraint(const btSoftBody::DeformableFaceRigidContact& contact, const btContactSolverInfo& infoGlobal, bool useStrainLimiting)
: m_face(contact.m_face)
-, btDeformableRigidContactConstraint(contact)
+, m_useStrainLimiting(useStrainLimiting)
+, btDeformableRigidContactConstraint(contact, infoGlobal)
{
}
btDeformableFaceRigidContactConstraint::btDeformableFaceRigidContactConstraint(const btDeformableFaceRigidContactConstraint& other)
: m_face(other.m_face)
+, m_useStrainLimiting(other.m_useStrainLimiting)
, btDeformableRigidContactConstraint(other)
{
}
@@ -411,47 +383,70 @@ void btDeformableFaceRigidContactConstraint::applyImpulse(const btVector3& impul
v1 -= dv * contact->m_weights[1];
if (im2 > 0)
v2 -= dv * contact->m_weights[2];
-
- // apply strain limiting to prevent undamped modes
- btScalar m01 = (btScalar(1)/(im0 + im1));
- btScalar m02 = (btScalar(1)/(im0 + im2));
- btScalar m12 = (btScalar(1)/(im1 + im2));
-
- btVector3 dv0 = im0 * (m01 * (v1-v0) + m02 * (v2-v0));
- btVector3 dv1 = im1 * (m01 * (v0-v1) + m12 * (v2-v1));
- btVector3 dv2 = im2 * (m12 * (v1-v2) + m02 * (v0-v2));
-
- v0 += dv0;
- v1 += dv1;
- v2 += dv2;
-}
-
-void btDeformableFaceRigidContactConstraint::applySplitImpulse(const btVector3& impulse)
-{
- const btSoftBody::DeformableFaceRigidContact* contact = getContact();
- btVector3 dv = impulse * contact->m_c2;
- btSoftBody::Face* face = contact->m_face;
-
- btVector3& v0 = face->m_n[0]->m_vsplit;
- btVector3& v1 = face->m_n[1]->m_vsplit;
- btVector3& v2 = face->m_n[2]->m_vsplit;
- const btScalar& im0 = face->m_n[0]->m_im;
- const btScalar& im1 = face->m_n[1]->m_im;
- const btScalar& im2 = face->m_n[2]->m_im;
- if (im0 > 0)
- v0 -= dv * contact->m_weights[0];
- if (im1 > 0)
- v1 -= dv * contact->m_weights[1];
- if (im2 > 0)
- v2 -= dv * contact->m_weights[2];
+ if (m_useStrainLimiting)
+ {
+ btScalar relaxation = 1./btScalar(m_infoGlobal->m_numIterations);
+ btScalar m01 = (relaxation/(im0 + im1));
+ btScalar m02 = (relaxation/(im0 + im2));
+ btScalar m12 = (relaxation/(im1 + im2));
+ #ifdef USE_STRAIN_RATE_LIMITING
+ // apply strain limiting to prevent the new velocity to change the current length of the edge by more than 1%.
+ btScalar p = 0.01;
+ btVector3& x0 = face->m_n[0]->m_x;
+ btVector3& x1 = face->m_n[1]->m_x;
+ btVector3& x2 = face->m_n[2]->m_x;
+ const btVector3 x_diff[3] = {x1-x0, x2-x0, x2-x1};
+ const btVector3 v_diff[3] = {v1-v0, v2-v0, v2-v1};
+ btVector3 u[3];
+ btScalar x_diff_dot_u, dn[3];
+ btScalar dt = m_infoGlobal->m_timeStep;
+ for (int i = 0; i < 3; ++i)
+ {
+ btScalar x_diff_norm = x_diff[i].safeNorm();
+ btScalar x_diff_norm_new = (x_diff[i] + v_diff[i] * dt).safeNorm();
+ btScalar strainRate = x_diff_norm_new/x_diff_norm;
+ u[i] = v_diff[i];
+ u[i].safeNormalize();
+ if (x_diff_norm == 0 || (1-p <= strainRate && strainRate <= 1+p))
+ {
+ dn[i] = 0;
+ continue;
+ }
+ x_diff_dot_u = btDot(x_diff[i], u[i]);
+ btScalar s;
+ if (1-p > strainRate)
+ {
+ s = 1/dt * (-x_diff_dot_u - btSqrt(x_diff_dot_u*x_diff_dot_u + (p*p-2*p) * x_diff_norm * x_diff_norm));
+ }
+ else
+ {
+ s = 1/dt * (-x_diff_dot_u + btSqrt(x_diff_dot_u*x_diff_dot_u + (p*p+2*p) * x_diff_norm * x_diff_norm));
+ }
+ // x_diff_norm_new = (x_diff[i] + s * u[i] * dt).safeNorm();
+ // strainRate = x_diff_norm_new/x_diff_norm;
+ dn[i] = s - v_diff[i].safeNorm();
+ }
+ btVector3 dv0 = im0 * (m01 * u[0]*(-dn[0]) + m02 * u[1]*-(dn[1]));
+ btVector3 dv1 = im1 * (m01 * u[0]*(dn[0]) + m12 * u[2]*(-dn[2]));
+ btVector3 dv2 = im2 * (m12 * u[2]*(dn[2]) + m02 * u[1]*(dn[1]));
+ #else
+ // apply strain limiting to prevent undamped modes
+ btVector3 dv0 = im0 * (m01 * (v1-v0) + m02 * (v2-v0));
+ btVector3 dv1 = im1 * (m01 * (v0-v1) + m12 * (v2-v1));
+ btVector3 dv2 = im2 * (m12 * (v1-v2) + m02 * (v0-v2));
+ #endif
+ v0 += dv0;
+ v1 += dv1;
+ v2 += dv2;
+ }
}
/* ================ Face vs. Node =================== */
-btDeformableFaceNodeContactConstraint::btDeformableFaceNodeContactConstraint(const btSoftBody::DeformableFaceNodeContact& contact)
+btDeformableFaceNodeContactConstraint::btDeformableFaceNodeContactConstraint(const btSoftBody::DeformableFaceNodeContact& contact, const btContactSolverInfo& infoGlobal)
: m_node(contact.m_node)
, m_face(contact.m_face)
, m_contact(&contact)
-, btDeformableContactConstraint(contact.m_normal)
+, btDeformableContactConstraint(contact.m_normal, infoGlobal)
{
m_total_normal_dv.setZero();
m_total_tangent_dv.setZero();
@@ -487,7 +482,7 @@ btVector3 btDeformableFaceNodeContactConstraint::getDv(const btSoftBody::Node* n
return dv * contact->m_weights[2];
}
-btScalar btDeformableFaceNodeContactConstraint::solveConstraint()
+btScalar btDeformableFaceNodeContactConstraint::solveConstraint(const btContactSolverInfo& infoGlobal)
{
btVector3 va = getVa();
btVector3 vb = getVb();
@@ -577,15 +572,4 @@ void btDeformableFaceNodeContactConstraint::applyImpulse(const btVector3& impuls
{
v2 -= dvb * contact->m_weights[2];
}
- // todo: Face node constraints needs more work
-// btScalar m01 = (btScalar(1)/(im0 + im1));
-// btScalar m02 = (btScalar(1)/(im0 + im2));
-// btScalar m12 = (btScalar(1)/(im1 + im2));
-//
-// btVector3 dv0 = im0 * (m01 * (v1-v0) + m02 * (v2-v0));
-// btVector3 dv1 = im1 * (m01 * (v0-v1) + m12 * (v2-v1));
-// btVector3 dv2 = im2 * (m12 * (v1-v2) + m02 * (v0-v2));
-// v0 += dv0;
-// v1 += dv1;
-// v2 += dv2;
}
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.h b/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.h
index 912119e7c3..9f9d5bf0a3 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.h
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableContactConstraint.h
@@ -24,34 +24,33 @@ public:
// True if the friction is static
// False if the friction is dynamic
bool m_static;
-
- // normal of the contact
- btVector3 m_normal;
-
- btDeformableContactConstraint(const btVector3& normal): m_static(false), m_normal(normal)
- {
- }
-
- btDeformableContactConstraint(bool isStatic, const btVector3& normal): m_static(isStatic), m_normal(normal)
- {
- }
-
- btDeformableContactConstraint(const btDeformableContactConstraint& other)
- : m_static(other.m_static)
- , m_normal(other.m_normal)
- {
-
- }
- btDeformableContactConstraint(){}
-
+ const btContactSolverInfo* m_infoGlobal;
+
+ // normal of the contact
+ btVector3 m_normal;
+
+ btDeformableContactConstraint(const btVector3& normal, const btContactSolverInfo& infoGlobal): m_static(false), m_normal(normal), m_infoGlobal(&infoGlobal)
+ {
+ }
+
+ btDeformableContactConstraint(bool isStatic, const btVector3& normal, const btContactSolverInfo& infoGlobal): m_static(isStatic), m_normal(normal), m_infoGlobal(&infoGlobal)
+ {
+ }
+
+ btDeformableContactConstraint(){}
+
+ btDeformableContactConstraint(const btDeformableContactConstraint& other)
+ : m_static(other.m_static)
+ , m_normal(other.m_normal)
+ , m_infoGlobal(other.m_infoGlobal)
+ {
+ }
+
virtual ~btDeformableContactConstraint(){}
// solve the constraint with inelastic impulse and return the error, which is the square of normal component of velocity diffrerence
// the constraint is solved by calculating the impulse between object A and B in the contact and apply the impulse to both objects involved in the contact
- virtual btScalar solveConstraint() = 0;
-
- // solve the position error by applying an inelastic impulse that changes only the position (not velocity)
- virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal) = 0;
+ virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal) = 0;
// get the velocity of the object A in the contact
virtual btVector3 getVa() const = 0;
@@ -65,9 +64,6 @@ public:
// apply impulse to the soft body node and/or face involved
virtual void applyImpulse(const btVector3& impulse) = 0;
- // apply position based impulse to the soft body node and/or face involved
- virtual void applySplitImpulse(const btVector3& impulse) = 0;
-
// scale the penetration depth by erp
virtual void setPenetrationScale(btScalar scale) = 0;
};
@@ -77,29 +73,21 @@ public:
class btDeformableStaticConstraint : public btDeformableContactConstraint
{
public:
- const btSoftBody::Node* m_node;
-
- btDeformableStaticConstraint(){}
+ btSoftBody::Node* m_node;
- btDeformableStaticConstraint(const btSoftBody::Node* node): m_node(node), btDeformableContactConstraint(false, btVector3(0,0,0))
+ btDeformableStaticConstraint(btSoftBody::Node* node, const btContactSolverInfo& infoGlobal): m_node(node), btDeformableContactConstraint(false, btVector3(0,0,0), infoGlobal)
{
}
-
+ btDeformableStaticConstraint(){}
btDeformableStaticConstraint(const btDeformableStaticConstraint& other)
: m_node(other.m_node)
, btDeformableContactConstraint(other)
{
-
}
virtual ~btDeformableStaticConstraint(){}
- virtual btScalar solveConstraint()
- {
- return 0;
- }
-
- virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal)
+ virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal)
{
return 0;
}
@@ -120,7 +108,6 @@ public:
}
virtual void applyImpulse(const btVector3& impulse){}
- virtual void applySplitImpulse(const btVector3& impulse){}
virtual void setPenetrationScale(btScalar scale){}
};
@@ -130,19 +117,15 @@ class btDeformableNodeAnchorConstraint : public btDeformableContactConstraint
{
public:
const btSoftBody::DeformableNodeRigidAnchor* m_anchor;
-
- btDeformableNodeAnchorConstraint(){}
- btDeformableNodeAnchorConstraint(const btSoftBody::DeformableNodeRigidAnchor& c);
+
+ btDeformableNodeAnchorConstraint(const btSoftBody::DeformableNodeRigidAnchor& c, const btContactSolverInfo& infoGlobal);
btDeformableNodeAnchorConstraint(const btDeformableNodeAnchorConstraint& other);
+ btDeformableNodeAnchorConstraint(){}
virtual ~btDeformableNodeAnchorConstraint()
{
}
- virtual btScalar solveConstraint();
- virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal)
- {
- // todo xuchenhan@
- return 0;
- }
+ virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal);
+
// object A is the rigid/multi body, and object B is the deformable node/face
virtual btVector3 getVa() const;
// get the velocity of the deformable node in contact
@@ -152,10 +135,7 @@ public:
return btVector3(0,0,0);
}
virtual void applyImpulse(const btVector3& impulse);
- virtual void applySplitImpulse(const btVector3& impulse)
- {
- // todo xuchenhan@
- };
+
virtual void setPenetrationScale(btScalar scale){}
};
@@ -169,10 +149,10 @@ public:
btVector3 m_total_tangent_dv;
btScalar m_penetration;
const btSoftBody::DeformableRigidContact* m_contact;
-
- btDeformableRigidContactConstraint(){}
- btDeformableRigidContactConstraint(const btSoftBody::DeformableRigidContact& c);
+
+ btDeformableRigidContactConstraint(const btSoftBody::DeformableRigidContact& c, const btContactSolverInfo& infoGlobal);
btDeformableRigidContactConstraint(const btDeformableRigidContactConstraint& other);
+ btDeformableRigidContactConstraint(){}
virtual ~btDeformableRigidContactConstraint()
{
}
@@ -180,9 +160,7 @@ public:
// object A is the rigid/multi body, and object B is the deformable node/face
virtual btVector3 getVa() const;
- virtual btScalar solveConstraint();
-
- virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal);
+ virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal);
virtual void setPenetrationScale(btScalar scale)
{
@@ -196,12 +174,11 @@ class btDeformableNodeRigidContactConstraint : public btDeformableRigidContactCo
{
public:
// the deformable node in contact
- const btSoftBody::Node* m_node;
-
- btDeformableNodeRigidContactConstraint(){}
- btDeformableNodeRigidContactConstraint(const btSoftBody::DeformableNodeRigidContact& contact);
+ btSoftBody::Node* m_node;
+
+ btDeformableNodeRigidContactConstraint(const btSoftBody::DeformableNodeRigidContact& contact, const btContactSolverInfo& infoGlobal);
btDeformableNodeRigidContactConstraint(const btDeformableNodeRigidContactConstraint& other);
-
+ btDeformableNodeRigidContactConstraint(){}
virtual ~btDeformableNodeRigidContactConstraint()
{
}
@@ -219,7 +196,6 @@ public:
}
virtual void applyImpulse(const btVector3& impulse);
- virtual void applySplitImpulse(const btVector3& impulse);
};
//
@@ -228,10 +204,10 @@ class btDeformableFaceRigidContactConstraint : public btDeformableRigidContactCo
{
public:
const btSoftBody::Face* m_face;
- btDeformableFaceRigidContactConstraint(){}
- btDeformableFaceRigidContactConstraint(const btSoftBody::DeformableFaceRigidContact& contact);
+ bool m_useStrainLimiting;
+ btDeformableFaceRigidContactConstraint(const btSoftBody::DeformableFaceRigidContact& contact, const btContactSolverInfo& infoGlobal, bool useStrainLimiting);
btDeformableFaceRigidContactConstraint(const btDeformableFaceRigidContactConstraint& other);
-
+ btDeformableFaceRigidContactConstraint(): m_useStrainLimiting(false) {}
virtual ~btDeformableFaceRigidContactConstraint()
{
}
@@ -249,7 +225,6 @@ public:
}
virtual void applyImpulse(const btVector3& impulse);
- virtual void applySplitImpulse(const btVector3& impulse);
};
//
@@ -263,19 +238,11 @@ public:
btVector3 m_total_normal_dv;
btVector3 m_total_tangent_dv;
- btDeformableFaceNodeContactConstraint(){}
-
- btDeformableFaceNodeContactConstraint(const btSoftBody::DeformableFaceNodeContact& contact);
-
+ btDeformableFaceNodeContactConstraint(const btSoftBody::DeformableFaceNodeContact& contact, const btContactSolverInfo& infoGlobal);
+ btDeformableFaceNodeContactConstraint(){}
virtual ~btDeformableFaceNodeContactConstraint(){}
- virtual btScalar solveConstraint();
-
- virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal)
- {
- // todo: xuchenhan@
- return 0;
- }
+ virtual btScalar solveConstraint(const btContactSolverInfo& infoGlobal);
// get the velocity of the object A in the contact
virtual btVector3 getVa() const;
@@ -293,10 +260,7 @@ public:
}
virtual void applyImpulse(const btVector3& impulse);
- virtual void applySplitImpulse(const btVector3& impulse)
- {
- // todo xuchenhan@
- }
+
virtual void setPenetrationScale(btScalar scale){}
};
#endif /* BT_DEFORMABLE_CONTACT_CONSTRAINT_H */
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.cpp
index 5a4f3241b4..22ca8bf582 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.cpp
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.cpp
@@ -17,7 +17,7 @@
#include "btDeformableMultiBodyDynamicsWorld.h"
#include <algorithm>
#include <cmath>
-btScalar btDeformableContactProjection::update(btCollisionObject** deformableBodies,int numDeformableBodies)
+btScalar btDeformableContactProjection::update(btCollisionObject** deformableBodies,int numDeformableBodies, const btContactSolverInfo& infoGlobal)
{
btScalar residualSquare = 0;
for (int i = 0; i < numDeformableBodies; ++i)
@@ -32,25 +32,25 @@ btScalar btDeformableContactProjection::update(btCollisionObject** deformableBod
for (int k = 0; k < m_nodeRigidConstraints[j].size(); ++k)
{
btDeformableNodeRigidContactConstraint& constraint = m_nodeRigidConstraints[j][k];
- btScalar localResidualSquare = constraint.solveConstraint();
+ btScalar localResidualSquare = constraint.solveConstraint(infoGlobal);
residualSquare = btMax(residualSquare, localResidualSquare);
}
for (int k = 0; k < m_nodeAnchorConstraints[j].size(); ++k)
{
btDeformableNodeAnchorConstraint& constraint = m_nodeAnchorConstraints[j][k];
- btScalar localResidualSquare = constraint.solveConstraint();
+ btScalar localResidualSquare = constraint.solveConstraint(infoGlobal);
residualSquare = btMax(residualSquare, localResidualSquare);
}
for (int k = 0; k < m_faceRigidConstraints[j].size(); ++k)
{
btDeformableFaceRigidContactConstraint& constraint = m_faceRigidConstraints[j][k];
- btScalar localResidualSquare = constraint.solveConstraint();
+ btScalar localResidualSquare = constraint.solveConstraint(infoGlobal);
residualSquare = btMax(residualSquare, localResidualSquare);
}
for (int k = 0; k < m_deformableConstraints[j].size(); ++k)
{
btDeformableFaceNodeContactConstraint& constraint = m_deformableConstraints[j][k];
- btScalar localResidualSquare = constraint.solveConstraint();
+ btScalar localResidualSquare = constraint.solveConstraint(infoGlobal);
residualSquare = btMax(residualSquare, localResidualSquare);
}
}
@@ -77,39 +77,8 @@ void btDeformableContactProjection::splitImpulseSetup(const btContactSolverInfo&
}
}
-btScalar btDeformableContactProjection::solveSplitImpulse(const btContactSolverInfo& infoGlobal)
-{
- btScalar residualSquare = 0;
- for (int i = 0; i < m_softBodies.size(); ++i)
- {
- // node constraints
- for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j)
- {
- btDeformableNodeRigidContactConstraint& constraint = m_nodeRigidConstraints[i][j];
- btScalar localResidualSquare = constraint.solveSplitImpulse(infoGlobal);
- residualSquare = btMax(residualSquare, localResidualSquare);
- }
- // anchor constraints
- for (int j = 0; j < m_nodeAnchorConstraints[i].size(); ++j)
- {
- btDeformableNodeAnchorConstraint& constraint = m_nodeAnchorConstraints[i][j];
- btScalar localResidualSquare = constraint.solveSplitImpulse(infoGlobal);
- residualSquare = btMax(residualSquare, localResidualSquare);
- }
- // face constraints
- for (int j = 0; j < m_faceRigidConstraints[i].size(); ++j)
- {
- btDeformableFaceRigidContactConstraint& constraint = m_faceRigidConstraints[i][j];
- btScalar localResidualSquare = constraint.solveSplitImpulse(infoGlobal);
- residualSquare = btMax(residualSquare, localResidualSquare);
- }
-
- }
- return residualSquare;
-}
-
-void btDeformableContactProjection::setConstraints()
-{
+void btDeformableContactProjection::setConstraints(const btContactSolverInfo& infoGlobal)
+{
BT_PROFILE("setConstraints");
for (int i = 0; i < m_softBodies.size(); ++i)
{
@@ -124,7 +93,7 @@ void btDeformableContactProjection::setConstraints()
{
if (psb->m_nodes[j].m_im == 0)
{
- btDeformableStaticConstraint static_constraint(&psb->m_nodes[j]);
+ btDeformableStaticConstraint static_constraint(&psb->m_nodes[j], infoGlobal);
m_staticConstraints[i].push_back(static_constraint);
}
}
@@ -139,7 +108,7 @@ void btDeformableContactProjection::setConstraints()
continue;
}
anchor.m_c1 = anchor.m_cti.m_colObj->getWorldTransform().getBasis() * anchor.m_local;
- btDeformableNodeAnchorConstraint constraint(anchor);
+ btDeformableNodeAnchorConstraint constraint(anchor, infoGlobal);
m_nodeAnchorConstraints[i].push_back(constraint);
}
@@ -152,7 +121,7 @@ void btDeformableContactProjection::setConstraints()
{
continue;
}
- btDeformableNodeRigidContactConstraint constraint(contact);
+ btDeformableNodeRigidContactConstraint constraint(contact, infoGlobal);
btVector3 va = constraint.getVa();
btVector3 vb = constraint.getVb();
const btVector3 vr = vb - va;
@@ -173,7 +142,7 @@ void btDeformableContactProjection::setConstraints()
{
continue;
}
- btDeformableFaceRigidContactConstraint constraint(contact);
+ btDeformableFaceRigidContactConstraint constraint(contact, infoGlobal, m_useStrainLimiting);
btVector3 va = constraint.getVa();
btVector3 vb = constraint.getVb();
const btVector3 vr = vb - va;
@@ -184,253 +153,404 @@ void btDeformableContactProjection::setConstraints()
m_faceRigidConstraints[i].push_back(constraint);
}
}
-
- // set Deformable Face vs. Deformable Node constraint
- for (int j = 0; j < psb->m_faceNodeContacts.size(); ++j)
- {
- const btSoftBody::DeformableFaceNodeContact& contact = psb->m_faceNodeContacts[j];
-
- btDeformableFaceNodeContactConstraint constraint(contact);
- btVector3 va = constraint.getVa();
- btVector3 vb = constraint.getVb();
- const btVector3 vr = vb - va;
- const btScalar dn = btDot(vr, contact.m_normal);
- if (dn > -SIMD_EPSILON)
- {
- m_deformableConstraints[i].push_back(constraint);
- }
- }
}
}
void btDeformableContactProjection::project(TVStack& x)
{
- const int dim = 3;
- for (int index = 0; index < m_projectionsDict.size(); ++index)
- {
- btAlignedObjectArray<btVector3>& projectionDirs = *m_projectionsDict.getAtIndex(index);
- size_t i = m_projectionsDict.getKeyAtIndex(index).getUid1();
- if (projectionDirs.size() >= dim)
- {
- // static node
- x[i].setZero();
- continue;
- }
- else if (projectionDirs.size() == 2)
- {
- btVector3 dir0 = projectionDirs[0];
- btVector3 dir1 = projectionDirs[1];
- btVector3 free_dir = btCross(dir0, dir1);
- if (free_dir.safeNorm() < SIMD_EPSILON)
- {
- x[i] -= x[i].dot(dir0) * dir0;
- x[i] -= x[i].dot(dir1) * dir1;
- }
- else
- {
- free_dir.normalize();
- x[i] = x[i].dot(free_dir) * free_dir;
- }
- }
- else
- {
- btAssert(projectionDirs.size() == 1);
- btVector3 dir0 = projectionDirs[0];
- x[i] -= x[i].dot(dir0) * dir0;
- }
- }
+#ifndef USE_MGS
+ const int dim = 3;
+ for (int index = 0; index < m_projectionsDict.size(); ++index)
+ {
+ btAlignedObjectArray<btVector3>& projectionDirs = *m_projectionsDict.getAtIndex(index);
+ size_t i = m_projectionsDict.getKeyAtIndex(index).getUid1();
+ if (projectionDirs.size() >= dim)
+ {
+ // static node
+ x[i].setZero();
+ continue;
+ }
+ else if (projectionDirs.size() == 2)
+ {
+ btVector3 dir0 = projectionDirs[0];
+ btVector3 dir1 = projectionDirs[1];
+ btVector3 free_dir = btCross(dir0, dir1);
+ if (free_dir.safeNorm() < SIMD_EPSILON)
+ {
+ x[i] -= x[i].dot(dir0) * dir0;
+ x[i] -= x[i].dot(dir1) * dir1;
+ }
+ else
+ {
+ free_dir.normalize();
+ x[i] = x[i].dot(free_dir) * free_dir;
+ }
+ }
+ else
+ {
+ btAssert(projectionDirs.size() == 1);
+ btVector3 dir0 = projectionDirs[0];
+ x[i] -= x[i].dot(dir0) * dir0;
+ }
+ }
+#else
+ btReducedVector p(x.size());
+ for (int i = 0; i < m_projections.size(); ++i)
+ {
+ p += (m_projections[i].dot(x) * m_projections[i]);
+ }
+ for (int i = 0; i < p.m_indices.size(); ++i)
+ {
+ x[p.m_indices[i]] -= p.m_vecs[i];
+ }
+#endif
}
void btDeformableContactProjection::setProjection()
{
- btAlignedObjectArray<btVector3> units;
- units.push_back(btVector3(1,0,0));
- units.push_back(btVector3(0,1,0));
- units.push_back(btVector3(0,0,1));
- for (int i = 0; i < m_softBodies.size(); ++i)
- {
- btSoftBody* psb = m_softBodies[i];
- if (!psb->isActive())
- {
- continue;
- }
- for (int j = 0; j < m_staticConstraints[i].size(); ++j)
- {
- int index = m_staticConstraints[i][j].m_node->index;
- if (m_projectionsDict.find(index) == NULL)
+#ifndef USE_MGS
+ BT_PROFILE("btDeformableContactProjection::setProjection");
+ btAlignedObjectArray<btVector3> units;
+ units.push_back(btVector3(1,0,0));
+ units.push_back(btVector3(0,1,0));
+ units.push_back(btVector3(0,0,1));
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ if (!psb->isActive())
+ {
+ continue;
+ }
+ for (int j = 0; j < m_staticConstraints[i].size(); ++j)
+ {
+ int index = m_staticConstraints[i][j].m_node->index;
+ m_staticConstraints[i][j].m_node->m_penetration = SIMD_INFINITY;
+ if (m_projectionsDict.find(index) == NULL)
+ {
+ m_projectionsDict.insert(index, units);
+ }
+ else
+ {
+ btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
+ for (int k = 0; k < 3; ++k)
+ {
+ projections.push_back(units[k]);
+ }
+ }
+ }
+ for (int j = 0; j < m_nodeAnchorConstraints[i].size(); ++j)
+ {
+ int index = m_nodeAnchorConstraints[i][j].m_anchor->m_node->index;
+ m_nodeAnchorConstraints[i][j].m_anchor->m_node->m_penetration = SIMD_INFINITY;
+ if (m_projectionsDict.find(index) == NULL)
+ {
+ m_projectionsDict.insert(index, units);
+ }
+ else
+ {
+ btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
+ for (int k = 0; k < 3; ++k)
+ {
+ projections.push_back(units[k]);
+ }
+ }
+ }
+ for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j)
+ {
+ int index = m_nodeRigidConstraints[i][j].m_node->index;
+ m_nodeRigidConstraints[i][j].m_node->m_penetration = -m_nodeRigidConstraints[i][j].getContact()->m_cti.m_offset;
+ if (m_nodeRigidConstraints[i][j].m_static)
+ {
+ if (m_projectionsDict.find(index) == NULL)
+ {
+ m_projectionsDict.insert(index, units);
+ }
+ else
+ {
+ btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
+ for (int k = 0; k < 3; ++k)
+ {
+ projections.push_back(units[k]);
+ }
+ }
+ }
+ else
+ {
+ if (m_projectionsDict.find(index) == NULL)
+ {
+ btAlignedObjectArray<btVector3> projections;
+ projections.push_back(m_nodeRigidConstraints[i][j].m_normal);
+ m_projectionsDict.insert(index, projections);
+ }
+ else
+ {
+ btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
+ projections.push_back(m_nodeRigidConstraints[i][j].m_normal);
+ }
+ }
+ }
+ for (int j = 0; j < m_faceRigidConstraints[i].size(); ++j)
+ {
+ const btSoftBody::Face* face = m_faceRigidConstraints[i][j].m_face;
+ btScalar penetration = -m_faceRigidConstraints[i][j].getContact()->m_cti.m_offset;
+ for (int k = 0; k < 3; ++k)
+ {
+ face->m_n[k]->m_penetration = btMax(face->m_n[k]->m_penetration, penetration);
+ }
+ for (int k = 0; k < 3; ++k)
+ {
+ btSoftBody::Node* node = face->m_n[k];
+ node->m_penetration = true;
+ int index = node->index;
+ if (m_faceRigidConstraints[i][j].m_static)
+ {
+ if (m_projectionsDict.find(index) == NULL)
+ {
+ m_projectionsDict.insert(index, units);
+ }
+ else
+ {
+ btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
+ for (int k = 0; k < 3; ++k)
+ {
+ projections.push_back(units[k]);
+ }
+ }
+ }
+ else
+ {
+ if (m_projectionsDict.find(index) == NULL)
+ {
+ btAlignedObjectArray<btVector3> projections;
+ projections.push_back(m_faceRigidConstraints[i][j].m_normal);
+ m_projectionsDict.insert(index, projections);
+ }
+ else
+ {
+ btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
+ projections.push_back(m_faceRigidConstraints[i][j].m_normal);
+ }
+ }
+ }
+ }
+ }
+#else
+ int dof = 0;
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ dof += m_softBodies[i]->m_nodes.size();
+ }
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ if (!psb->isActive())
+ {
+ continue;
+ }
+ for (int j = 0; j < m_staticConstraints[i].size(); ++j)
+ {
+ int index = m_staticConstraints[i][j].m_node->index;
+ m_staticConstraints[i][j].m_node->m_penetration = SIMD_INFINITY;
+ btAlignedObjectArray<int> indices;
+ btAlignedObjectArray<btVector3> vecs1,vecs2,vecs3;
+ indices.push_back(index);
+ vecs1.push_back(btVector3(1,0,0));
+ vecs2.push_back(btVector3(0,1,0));
+ vecs3.push_back(btVector3(0,0,1));
+ m_projections.push_back(btReducedVector(dof, indices, vecs1));
+ m_projections.push_back(btReducedVector(dof, indices, vecs2));
+ m_projections.push_back(btReducedVector(dof, indices, vecs3));
+ }
+
+ for (int j = 0; j < m_nodeAnchorConstraints[i].size(); ++j)
+ {
+ int index = m_nodeAnchorConstraints[i][j].m_anchor->m_node->index;
+ m_nodeAnchorConstraints[i][j].m_anchor->m_node->m_penetration = SIMD_INFINITY;
+ btAlignedObjectArray<int> indices;
+ btAlignedObjectArray<btVector3> vecs1,vecs2,vecs3;
+ indices.push_back(index);
+ vecs1.push_back(btVector3(1,0,0));
+ vecs2.push_back(btVector3(0,1,0));
+ vecs3.push_back(btVector3(0,0,1));
+ m_projections.push_back(btReducedVector(dof, indices, vecs1));
+ m_projections.push_back(btReducedVector(dof, indices, vecs2));
+ m_projections.push_back(btReducedVector(dof, indices, vecs3));
+ }
+ for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j)
+ {
+ int index = m_nodeRigidConstraints[i][j].m_node->index;
+ m_nodeRigidConstraints[i][j].m_node->m_penetration = -m_nodeRigidConstraints[i][j].getContact()->m_cti.m_offset;
+ btAlignedObjectArray<int> indices;
+ indices.push_back(index);
+ btAlignedObjectArray<btVector3> vecs1,vecs2,vecs3;
+ if (m_nodeRigidConstraints[i][j].m_static)
+ {
+ vecs1.push_back(btVector3(1,0,0));
+ vecs2.push_back(btVector3(0,1,0));
+ vecs3.push_back(btVector3(0,0,1));
+ m_projections.push_back(btReducedVector(dof, indices, vecs1));
+ m_projections.push_back(btReducedVector(dof, indices, vecs2));
+ m_projections.push_back(btReducedVector(dof, indices, vecs3));
+ }
+ else
+ {
+ vecs1.push_back(m_nodeRigidConstraints[i][j].m_normal);
+ m_projections.push_back(btReducedVector(dof, indices, vecs1));
+ }
+ }
+ for (int j = 0; j < m_faceRigidConstraints[i].size(); ++j)
+ {
+ const btSoftBody::Face* face = m_faceRigidConstraints[i][j].m_face;
+ btVector3 bary = m_faceRigidConstraints[i][j].getContact()->m_bary;
+ btScalar penetration = -m_faceRigidConstraints[i][j].getContact()->m_cti.m_offset;
+ for (int k = 0; k < 3; ++k)
+ {
+ face->m_n[k]->m_penetration = btMax(face->m_n[k]->m_penetration, penetration);
+ }
+ if (m_faceRigidConstraints[i][j].m_static)
{
- m_projectionsDict.insert(index, units);
- }
- else
- {
- btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
- for (int k = 0; k < 3; ++k)
+ for (int l = 0; l < 3; ++l)
{
- projections.push_back(units[k]);
- }
- }
- }
- for (int j = 0; j < m_nodeAnchorConstraints[i].size(); ++j)
- {
- int index = m_nodeAnchorConstraints[i][j].m_anchor->m_node->index;
- if (m_projectionsDict.find(index) == NULL)
- {
- m_projectionsDict.insert(index, units);
- }
- else
- {
- btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
- for (int k = 0; k < 3; ++k)
- {
- projections.push_back(units[k]);
- }
- }
- }
- for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j)
- {
- int index = m_nodeRigidConstraints[i][j].m_node->index;
- if (m_nodeRigidConstraints[i][j].m_static)
- {
- if (m_projectionsDict.find(index) == NULL)
- {
- m_projectionsDict.insert(index, units);
- }
- else
- {
- btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
+
+ btReducedVector rv(dof);
for (int k = 0; k < 3; ++k)
{
- projections.push_back(units[k]);
+ rv.m_indices.push_back(face->m_n[k]->index);
+ btVector3 v(0,0,0);
+ v[l] = bary[k];
+ rv.m_vecs.push_back(v);
+ rv.sort();
}
+ m_projections.push_back(rv);
}
}
else
{
- if (m_projectionsDict.find(index) == NULL)
- {
- btAlignedObjectArray<btVector3> projections;
- projections.push_back(m_nodeRigidConstraints[i][j].m_normal);
- m_projectionsDict.insert(index, projections);
- }
- else
- {
- btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
- projections.push_back(m_nodeRigidConstraints[i][j].m_normal);
- }
- }
- }
- for (int j = 0; j < m_faceRigidConstraints[i].size(); ++j)
- {
- const btSoftBody::Face* face = m_faceRigidConstraints[i][j].m_face;
- for (int k = 0; k < 3; ++k)
- {
- const btSoftBody::Node* node = face->m_n[k];
- int index = node->index;
- if (m_faceRigidConstraints[i][j].m_static)
+ btReducedVector rv(dof);
+ for (int k = 0; k < 3; ++k)
{
- if (m_projectionsDict.find(index) == NULL)
- {
- m_projectionsDict.insert(index, units);
- }
- else
- {
- btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
- for (int k = 0; k < 3; ++k)
- {
- projections.push_back(units[k]);
- }
- }
- }
- else
- {
- if (m_projectionsDict.find(index) == NULL)
- {
- btAlignedObjectArray<btVector3> projections;
- projections.push_back(m_faceRigidConstraints[i][j].m_normal);
- m_projectionsDict.insert(index, projections);
- }
- else
- {
- btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
- projections.push_back(m_faceRigidConstraints[i][j].m_normal);
- }
+ rv.m_indices.push_back(face->m_n[k]->index);
+ rv.m_vecs.push_back(bary[k] * m_faceRigidConstraints[i][j].m_normal);
+ rv.sort();
}
+ m_projections.push_back(rv);
}
}
- for (int j = 0; j < m_deformableConstraints[i].size(); ++j)
- {
- const btSoftBody::Face* face = m_deformableConstraints[i][j].m_face;
- for (int k = 0; k < 3; ++k)
- {
- const btSoftBody::Node* node = face->m_n[k];
- int index = node->index;
- if (m_deformableConstraints[i][j].m_static)
- {
- if (m_projectionsDict.find(index) == NULL)
- {
- m_projectionsDict.insert(index, units);
- }
- else
- {
- btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
- for (int k = 0; k < 3; ++k)
- {
- projections.push_back(units[k]);
- }
- }
- }
- else
- {
- if (m_projectionsDict.find(index) == NULL)
- {
- btAlignedObjectArray<btVector3> projections;
- projections.push_back(m_deformableConstraints[i][j].m_normal);
- m_projectionsDict.insert(index, projections);
- }
- else
- {
- btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
- projections.push_back(m_deformableConstraints[i][j].m_normal);
- }
- }
- }
+ }
+ btModifiedGramSchmidt<btReducedVector> mgs(m_projections);
+ mgs.solve();
+ m_projections = mgs.m_out;
+#endif
+}
+
+void btDeformableContactProjection::checkConstraints(const TVStack& x)
+{
+ for (int i = 0; i < m_lagrangeMultipliers.size(); ++i)
+ {
+ btVector3 d(0,0,0);
+ const LagrangeMultiplier& lm = m_lagrangeMultipliers[i];
+ for (int j = 0; j < lm.m_num_constraints; ++j)
+ {
+ for (int k = 0; k < lm.m_num_nodes; ++k)
+ {
+ d[j] += lm.m_weights[k] * x[lm.m_indices[k]].dot(lm.m_dirs[j]);
+ }
+ }
+ printf("d = %f, %f, %f\n",d[0],d[1],d[2]);
+ }
+}
+
+void btDeformableContactProjection::setLagrangeMultiplier()
+{
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ if (!psb->isActive())
+ {
+ continue;
+ }
+ for (int j = 0; j < m_staticConstraints[i].size(); ++j)
+ {
+ int index = m_staticConstraints[i][j].m_node->index;
+ m_staticConstraints[i][j].m_node->m_penetration = SIMD_INFINITY;
+ LagrangeMultiplier lm;
+ lm.m_num_nodes = 1;
+ lm.m_indices[0] = index;
+ lm.m_weights[0] = 1.0;
+ lm.m_num_constraints = 3;
+ lm.m_dirs[0] = btVector3(1,0,0);
+ lm.m_dirs[1] = btVector3(0,1,0);
+ lm.m_dirs[2] = btVector3(0,0,1);
+ m_lagrangeMultipliers.push_back(lm);
+ }
+ for (int j = 0; j < m_nodeAnchorConstraints[i].size(); ++j)
+ {
+ int index = m_nodeAnchorConstraints[i][j].m_anchor->m_node->index;
+ m_nodeAnchorConstraints[i][j].m_anchor->m_node->m_penetration = SIMD_INFINITY;
+ LagrangeMultiplier lm;
+ lm.m_num_nodes = 1;
+ lm.m_indices[0] = index;
+ lm.m_weights[0] = 1.0;
+ lm.m_num_constraints = 3;
+ lm.m_dirs[0] = btVector3(1,0,0);
+ lm.m_dirs[1] = btVector3(0,1,0);
+ lm.m_dirs[2] = btVector3(0,0,1);
+ m_lagrangeMultipliers.push_back(lm);
+ }
+ for (int j = 0; j < m_nodeRigidConstraints[i].size(); ++j)
+ {
+ int index = m_nodeRigidConstraints[i][j].m_node->index;
+ m_nodeRigidConstraints[i][j].m_node->m_penetration = -m_nodeRigidConstraints[i][j].getContact()->m_cti.m_offset;
+ LagrangeMultiplier lm;
+ lm.m_num_nodes = 1;
+ lm.m_indices[0] = index;
+ lm.m_weights[0] = 1.0;
+ if (m_nodeRigidConstraints[i][j].m_static)
+ {
+ lm.m_num_constraints = 3;
+ lm.m_dirs[0] = btVector3(1,0,0);
+ lm.m_dirs[1] = btVector3(0,1,0);
+ lm.m_dirs[2] = btVector3(0,0,1);
+ }
+ else
+ {
+ lm.m_num_constraints = 1;
+ lm.m_dirs[0] = m_nodeRigidConstraints[i][j].m_normal;
+ }
+ m_lagrangeMultipliers.push_back(lm);
+ }
+ for (int j = 0; j < m_faceRigidConstraints[i].size(); ++j)
+ {
+ const btSoftBody::Face* face = m_faceRigidConstraints[i][j].m_face;
- const btSoftBody::Node* node = m_deformableConstraints[i][j].m_node;
- int index = node->index;
- if (m_deformableConstraints[i][j].m_static)
+ btVector3 bary = m_faceRigidConstraints[i][j].getContact()->m_bary;
+ btScalar penetration = -m_faceRigidConstraints[i][j].getContact()->m_cti.m_offset;
+ LagrangeMultiplier lm;
+ lm.m_num_nodes = 3;
+ for (int k = 0; k<3; ++k)
{
- if (m_projectionsDict.find(index) == NULL)
- {
- m_projectionsDict.insert(index, units);
- }
- else
- {
- btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
- for (int k = 0; k < 3; ++k)
- {
- projections.push_back(units[k]);
- }
- }
+ face->m_n[k]->m_penetration = btMax(face->m_n[k]->m_penetration, penetration);
+ lm.m_indices[k] = face->m_n[k]->index;
+ lm.m_weights[k] = bary[k];
+ }
+ if (m_faceRigidConstraints[i][j].m_static)
+ {
+ lm.m_num_constraints = 3;
+ lm.m_dirs[0] = btVector3(1,0,0);
+ lm.m_dirs[1] = btVector3(0,1,0);
+ lm.m_dirs[2] = btVector3(0,0,1);
}
else
{
- if (m_projectionsDict.find(index) == NULL)
- {
- btAlignedObjectArray<btVector3> projections;
- projections.push_back(m_deformableConstraints[i][j].m_normal);
- m_projectionsDict.insert(index, projections);
- }
- else
- {
- btAlignedObjectArray<btVector3>& projections = *m_projectionsDict[index];
- projections.push_back(m_deformableConstraints[i][j].m_normal);
- }
+ lm.m_num_constraints = 1;
+ lm.m_dirs[0] = m_faceRigidConstraints[i][j].m_normal;
}
+ m_lagrangeMultipliers.push_back(lm);
}
}
}
-
+//
void btDeformableContactProjection::applyDynamicFriction(TVStack& f)
{
for (int i = 0; i < m_softBodies.size(); ++i)
@@ -502,7 +622,12 @@ void btDeformableContactProjection::reinitialize(bool nodeUpdated)
m_faceRigidConstraints[i].clear();
m_deformableConstraints[i].clear();
}
- m_projectionsDict.clear();
+#ifndef USE_MGS
+ m_projectionsDict.clear();
+#else
+ m_projections.clear();
+#endif
+ m_lagrangeMultipliers.clear();
}
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.h b/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.h
index 3c4490765e..8d7e94d4fb 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.h
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableContactProjection.h
@@ -21,30 +21,37 @@
#include "BulletDynamics/Featherstone/btMultiBodyConstraint.h"
#include "btDeformableContactConstraint.h"
#include "LinearMath/btHashMap.h"
+#include "LinearMath/btReducedVector.h"
+#include "LinearMath/btModifiedGramSchmidt.h"
#include <vector>
+
+struct LagrangeMultiplier
+{
+ int m_num_constraints; // Number of constraints
+ int m_num_nodes; // Number of nodes in these constraints
+ btScalar m_weights[3]; // weights of the nodes involved, same size as m_num_nodes
+ btVector3 m_dirs[3]; // Constraint directions, same size of m_num_constraints;
+ int m_indices[3]; // indices of the nodes involved, same size as m_num_nodes;
+};
+
+
class btDeformableContactProjection
{
public:
typedef btAlignedObjectArray<btVector3> TVStack;
btAlignedObjectArray<btSoftBody *>& m_softBodies;
-
-// // map from node index to static constraint
-// btHashMap<btHashInt, btDeformableStaticConstraint> m_staticConstraints;
-// // map from node index to node rigid constraint
-// btHashMap<btHashInt, btAlignedObjectArray<btDeformableNodeRigidContactConstraint> > m_nodeRigidConstraints;
-// // map from node index to face rigid constraint
-// btHashMap<btHashInt, btAlignedObjectArray<btDeformableFaceRigidContactConstraint*> > m_faceRigidConstraints;
-// // map from node index to deformable constraint
-// btHashMap<btHashInt, btAlignedObjectArray<btDeformableFaceNodeContactConstraint*> > m_deformableConstraints;
-// // map from node index to node anchor constraint
-// btHashMap<btHashInt, btDeformableNodeAnchorConstraint> m_nodeAnchorConstraints;
// all constraints involving face
btAlignedObjectArray<btDeformableContactConstraint*> m_allFaceConstraints;
-
+#ifndef USE_MGS
// map from node index to projection directions
btHashMap<btHashInt, btAlignedObjectArray<btVector3> > m_projectionsDict;
-
+#else
+ btAlignedObjectArray<btReducedVector> m_projections;
+#endif
+
+ btAlignedObjectArray<LagrangeMultiplier> m_lagrangeMultipliers;
+
// map from node index to static constraint
btAlignedObjectArray<btAlignedObjectArray<btDeformableStaticConstraint> > m_staticConstraints;
// map from node index to node rigid constraint
@@ -56,6 +63,8 @@ public:
// map from node index to node anchor constraint
btAlignedObjectArray<btAlignedObjectArray<btDeformableNodeAnchorConstraint> > m_nodeAnchorConstraints;
+ bool m_useStrainLimiting;
+
btDeformableContactProjection(btAlignedObjectArray<btSoftBody *>& softBodies)
: m_softBodies(softBodies)
{
@@ -72,13 +81,10 @@ public:
virtual void applyDynamicFriction(TVStack& f);
// update and solve the constraints
- virtual btScalar update(btCollisionObject** deformableBodies,int numDeformableBodies);
-
- // solve the position error using split impulse
- virtual btScalar solveSplitImpulse(const btContactSolverInfo& infoGlobal);
+ virtual btScalar update(btCollisionObject** deformableBodies,int numDeformableBodies, const btContactSolverInfo& infoGlobal);
// Add constraints to m_constraints. In addition, the constraints that each vertex own are recorded in m_constraintsDict.
- virtual void setConstraints();
+ virtual void setConstraints(const btContactSolverInfo& infoGlobal);
// Set up projections for each vertex by adding the projection direction to
virtual void setProjection();
@@ -86,5 +92,9 @@ public:
virtual void reinitialize(bool nodeUpdated);
virtual void splitImpulseSetup(const btContactSolverInfo& infoGlobal);
+
+ virtual void setLagrangeMultiplier();
+
+ void checkConstraints(const TVStack& x);
};
#endif /* btDeformableContactProjection_h */
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableCorotatedForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableCorotatedForce.h
index c2a26338e7..2d042df729 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableCorotatedForce.h
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableCorotatedForce.h
@@ -114,6 +114,8 @@ public:
{
}
+ virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA){}
+
virtual btDeformableLagrangianForceType getForceType()
{
return BT_COROTATED_FORCE;
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableGravityForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableGravityForce.h
index 33e5a8564a..13ee3eacb6 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableGravityForce.h
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableGravityForce.h
@@ -50,6 +50,8 @@ public:
{
}
+ virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA){}
+
virtual void addScaledGravityForce(btScalar scale, TVStack& force)
{
int numNodes = getNumNodes();
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableLagrangianForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableLagrangianForce.h
index 64e80e23b3..0b6447442d 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableLagrangianForce.h
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableLagrangianForce.h
@@ -26,7 +26,8 @@ enum btDeformableLagrangianForceType
BT_MASSSPRING_FORCE = 2,
BT_COROTATED_FORCE = 3,
BT_NEOHOOKEAN_FORCE = 4,
- BT_LINEAR_ELASTICITY_FORCE = 5
+ BT_LINEAR_ELASTICITY_FORCE = 5,
+ BT_MOUSE_PICKING_FORCE = 6
};
static inline double randomDouble(double low, double high)
@@ -53,6 +54,9 @@ public:
// add damping df
virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df) = 0;
+ // build diagonal of A matrix
+ virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA) = 0;
+
// add elastic df
virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df) = 0;
@@ -85,6 +89,11 @@ public:
m_softBodies.push_back(psb);
}
+ virtual void removeSoftBody(btSoftBody* psb)
+ {
+ m_softBodies.remove(psb);
+ }
+
virtual void setIndices(const btAlignedObjectArray<btSoftBody::Node*>* nodes)
{
m_nodes = nodes;
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableMassSpringForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableMassSpringForce.h
index 54b4e4481d..b128df92cc 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableMassSpringForce.h
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableMassSpringForce.h
@@ -149,6 +149,52 @@ public:
}
}
+ virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA)
+ {
+ // implicit damping force differential
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ if (!psb->isActive())
+ {
+ continue;
+ }
+ btScalar scaled_k_damp = m_dampingStiffness * scale;
+ for (int j = 0; j < psb->m_links.size(); ++j)
+ {
+ const btSoftBody::Link& link = psb->m_links[j];
+ btSoftBody::Node* node1 = link.m_n[0];
+ btSoftBody::Node* node2 = link.m_n[1];
+ size_t id1 = node1->index;
+ size_t id2 = node2->index;
+ if (m_momentum_conserving)
+ {
+ if ((node2->m_x - node1->m_x).norm() > SIMD_EPSILON)
+ {
+ btVector3 dir = (node2->m_x - node1->m_x).normalized();
+ for (int d = 0; d < 3; ++d)
+ {
+ if (node1->m_im > 0)
+ diagA[id1][d] -= scaled_k_damp * dir[d] * dir[d];
+ if (node2->m_im > 0)
+ diagA[id2][d] -= scaled_k_damp * dir[d] * dir[d];
+ }
+ }
+ }
+ else
+ {
+ for (int d = 0; d < 3; ++d)
+ {
+ if (node1->m_im > 0)
+ diagA[id1][d] -= scaled_k_damp;
+ if (node2->m_im > 0)
+ diagA[id2][d] -= scaled_k_damp;
+ }
+ }
+ }
+ }
+ }
+
virtual double totalElasticEnergy(btScalar dt)
{
double energy = 0;
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableMousePickingForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableMousePickingForce.h
new file mode 100644
index 0000000000..07c10935f4
--- /dev/null
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableMousePickingForce.h
@@ -0,0 +1,145 @@
+/*
+ Written by Xuchen Han <xuchenhan2015@u.northwestern.edu>
+
+ Bullet Continuous Collision Detection and Physics Library
+ Copyright (c) 2019 Google Inc. http://bulletphysics.org
+ This software is provided 'as-is', without any express or implied warranty.
+ In no event will the authors be held liable for any damages arising from the use of this software.
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it freely,
+ subject to the following restrictions:
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef BT_MOUSE_PICKING_FORCE_H
+#define BT_MOUSE_PICKING_FORCE_H
+
+#include "btDeformableLagrangianForce.h"
+
+class btDeformableMousePickingForce : public btDeformableLagrangianForce
+{
+ // If true, the damping force will be in the direction of the spring
+ // If false, the damping force will be in the direction of the velocity
+ btScalar m_elasticStiffness, m_dampingStiffness;
+ const btSoftBody::Face& m_face;
+ btVector3 m_mouse_pos;
+ btScalar m_maxForce;
+public:
+ typedef btAlignedObjectArray<btVector3> TVStack;
+ btDeformableMousePickingForce(btScalar k, btScalar d, const btSoftBody::Face& face, btVector3 mouse_pos, btScalar maxForce = 0.3) : m_elasticStiffness(k), m_dampingStiffness(d), m_face(face), m_mouse_pos(mouse_pos), m_maxForce(maxForce)
+ {
+ }
+
+ virtual void addScaledForces(btScalar scale, TVStack& force)
+ {
+ addScaledDampingForce(scale, force);
+ addScaledElasticForce(scale, force);
+ }
+
+ virtual void addScaledExplicitForce(btScalar scale, TVStack& force)
+ {
+ addScaledElasticForce(scale, force);
+ }
+
+ virtual void addScaledDampingForce(btScalar scale, TVStack& force)
+ {
+ for (int i = 0; i < 3; ++i)
+ {
+ btVector3 v_diff = m_face.m_n[i]->m_v;
+ btVector3 scaled_force = scale * m_dampingStiffness * v_diff;
+ if ((m_face.m_n[i]->m_x - m_mouse_pos).norm() > SIMD_EPSILON)
+ {
+ btVector3 dir = (m_face.m_n[i]->m_x - m_mouse_pos).normalized();
+ scaled_force = scale * m_dampingStiffness * v_diff.dot(dir) * dir;
+ }
+ force[m_face.m_n[i]->index] -= scaled_force;
+ }
+ }
+
+ virtual void addScaledElasticForce(btScalar scale, TVStack& force)
+ {
+ btScalar scaled_stiffness = scale * m_elasticStiffness;
+ for (int i = 0; i < 3; ++i)
+ {
+ btVector3 dir = (m_face.m_n[i]->m_q - m_mouse_pos);
+ btVector3 scaled_force = scaled_stiffness * dir;
+ if (scaled_force.safeNorm() > m_maxForce)
+ {
+ scaled_force.safeNormalize();
+ scaled_force *= m_maxForce;
+ }
+ force[m_face.m_n[i]->index] -= scaled_force;
+ }
+ }
+
+ virtual void addScaledDampingForceDifferential(btScalar scale, const TVStack& dv, TVStack& df)
+ {
+ btScalar scaled_k_damp = m_dampingStiffness * scale;
+ for (int i = 0; i < 3; ++i)
+ {
+ btVector3 local_scaled_df = scaled_k_damp * dv[m_face.m_n[i]->index];
+ if ((m_face.m_n[i]->m_x - m_mouse_pos).norm() > SIMD_EPSILON)
+ {
+ btVector3 dir = (m_face.m_n[i]->m_x - m_mouse_pos).normalized();
+ local_scaled_df= scaled_k_damp * dv[m_face.m_n[i]->index].dot(dir) * dir;
+ }
+ df[m_face.m_n[i]->index] -= local_scaled_df;
+ }
+ }
+
+ virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA){}
+
+ virtual double totalElasticEnergy(btScalar dt)
+ {
+ double energy = 0;
+ for (int i = 0; i < 3; ++i)
+ {
+ btVector3 dir = (m_face.m_n[i]->m_q - m_mouse_pos);
+ btVector3 scaled_force = m_elasticStiffness * dir;
+ if (scaled_force.safeNorm() > m_maxForce)
+ {
+ scaled_force.safeNormalize();
+ scaled_force *= m_maxForce;
+ }
+ energy += 0.5 * scaled_force.dot(dir);
+ }
+ return energy;
+ }
+
+ virtual double totalDampingEnergy(btScalar dt)
+ {
+ double energy = 0;
+ for (int i = 0; i < 3; ++i)
+ {
+ btVector3 v_diff = m_face.m_n[i]->m_v;
+ btVector3 scaled_force = m_dampingStiffness * v_diff;
+ if ((m_face.m_n[i]->m_x - m_mouse_pos).norm() > SIMD_EPSILON)
+ {
+ btVector3 dir = (m_face.m_n[i]->m_x - m_mouse_pos).normalized();
+ scaled_force = m_dampingStiffness * v_diff.dot(dir) * dir;
+ }
+ energy -= scaled_force.dot(m_face.m_n[i]->m_v) / dt;
+ }
+ return energy;
+ }
+
+ virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df)
+ {
+ //TODO
+ }
+
+ void setMousePos(const btVector3& p)
+ {
+ m_mouse_pos = p;
+ }
+
+ virtual btDeformableLagrangianForceType getForceType()
+ {
+ return BT_MOUSE_PICKING_FORCE;
+ }
+
+};
+
+#endif /* btMassSpring_h */
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp
index 06f95d69f6..c8cc47923e 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyConstraintSolver.cpp
@@ -32,7 +32,7 @@ btScalar btDeformableMultiBodyConstraintSolver::solveDeformableGroupIterations(b
m_leastSquaresResidual = solveSingleIteration(iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer);
// solver body velocity -> rigid body velocity
solverBodyWriteBack(infoGlobal);
- btScalar deformableResidual = m_deformableSolver->solveContactConstraints(deformableBodies,numDeformableBodies);
+ btScalar deformableResidual = m_deformableSolver->solveContactConstraints(deformableBodies,numDeformableBodies, infoGlobal);
// update rigid body velocity in rigid/deformable contact
m_leastSquaresResidual = btMax(m_leastSquaresResidual, deformableResidual);
// solver body velocity <- rigid body velocity
@@ -112,7 +112,7 @@ void btDeformableMultiBodyConstraintSolver::solveGroupCacheFriendlySplitImpulseI
if (infoGlobal.m_splitImpulse)
{
{
- m_deformableSolver->splitImpulseSetup(infoGlobal);
+// m_deformableSolver->splitImpulseSetup(infoGlobal);
for (iteration = 0; iteration < infoGlobal.m_numIterations; iteration++)
{
btScalar leastSquaresResidual = 0.f;
@@ -127,8 +127,8 @@ void btDeformableMultiBodyConstraintSolver::solveGroupCacheFriendlySplitImpulseI
leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
}
// solve the position correction between deformable and rigid/multibody
- btScalar residual = m_deformableSolver->solveSplitImpulse(infoGlobal);
- leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
+// btScalar residual = m_deformableSolver->solveSplitImpulse(infoGlobal);
+// leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
}
if (leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || iteration >= (infoGlobal.m_numIterations - 1))
{
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp
index 618e5c0d7b..6b742978ef 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.cpp
@@ -22,7 +22,6 @@ Call internalStepSimulation multiple times, to achieve 240Hz (4 steps of 60Hz).
2. Detect discrete collisions between rigid and deformable bodies at position x_{n+1}^* = x_n + dt * v_{n+1}^*.
3a. Solve all constraints, including LCP. Contact, position correction due to numerical drift, friction, and anchors for deformable.
- TODO: add option for positional drift correction (using vel_target += erp * pos_error/dt
3b. 5 Newton steps (multiple step). Conjugent Gradient solves linear system. Deformable Damping: Then velocities of deformable bodies v_{n+1} are solved in
M(v_{n+1} - v_{n+1}^*) = damping_force * dt / mass,
@@ -58,14 +57,20 @@ m_deformableBodySolver(deformableBodySolver), m_solverCallback(0)
m_sbi.water_density = 0;
m_sbi.water_offset = 0;
m_sbi.water_normal = btVector3(0, 0, 0);
- m_sbi.m_gravity.setValue(0, -10, 0);
+ m_sbi.m_gravity.setValue(0, -9.8, 0);
m_internalTime = 0.0;
m_implicit = false;
m_lineSearch = false;
- m_selfCollision = true;
+ m_useProjection = true;
+ m_ccdIterations = 5;
m_solverDeformableBodyIslandCallback = new DeformableBodyInplaceSolverIslandCallback(constraintSolver, dispatcher);
}
+btDeformableMultiBodyDynamicsWorld::~btDeformableMultiBodyDynamicsWorld()
+{
+ delete m_solverDeformableBodyIslandCallback;
+}
+
void btDeformableMultiBodyDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
{
BT_PROFILE("internalSingleStepSimulation");
@@ -74,20 +79,16 @@ void btDeformableMultiBodyDynamicsWorld::internalSingleStepSimulation(btScalar t
(*m_internalPreTickCallback)(this, timeStep);
}
reinitialize(timeStep);
+
// add gravity to velocity of rigid and multi bodys
applyRigidBodyGravity(timeStep);
///apply gravity and explicit force to velocity, predict motion
predictUnconstraintMotion(timeStep);
- ///perform collision detection
+ ///perform collision detection that involves rigid/multi bodies
btMultiBodyDynamicsWorld::performDiscreteCollisionDetection();
- if (m_selfCollision)
- {
- softBodySelfCollision();
- }
-
btMultiBodyDynamicsWorld::calculateSimulationIslands();
beforeSolverCallbacks(timeStep);
@@ -96,7 +97,13 @@ void btDeformableMultiBodyDynamicsWorld::internalSingleStepSimulation(btScalar t
solveConstraints(timeStep);
afterSolverCallbacks(timeStep);
-
+
+ performDeformableCollisionDetection();
+
+ applyRepulsionForce(timeStep);
+
+ performGeometricCollisions(timeStep);
+
integrateTransforms(timeStep);
///update vehicle simulation
@@ -107,6 +114,27 @@ void btDeformableMultiBodyDynamicsWorld::internalSingleStepSimulation(btScalar t
// ///////////////////////////////
}
+void btDeformableMultiBodyDynamicsWorld::performDeformableCollisionDetection()
+{
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ m_softBodies[i]->m_softSoftCollision = true;
+ }
+
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ for (int j = i; j < m_softBodies.size(); ++j)
+ {
+ m_softBodies[i]->defaultCollisionHandler(m_softBodies[j]);
+ }
+ }
+
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ m_softBodies[i]->m_softSoftCollision = false;
+ }
+}
+
void btDeformableMultiBodyDynamicsWorld::updateActivationState(btScalar timeStep)
{
for (int i = 0; i < m_softBodies.size(); i++)
@@ -131,10 +159,106 @@ void btDeformableMultiBodyDynamicsWorld::updateActivationState(btScalar timeStep
btMultiBodyDynamicsWorld::updateActivationState(timeStep);
}
+void btDeformableMultiBodyDynamicsWorld::applyRepulsionForce(btScalar timeStep)
+{
+ BT_PROFILE("btDeformableMultiBodyDynamicsWorld::applyRepulsionForce");
+ for (int i = 0; i < m_softBodies.size(); i++)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ if (psb->isActive())
+ {
+ psb->applyRepulsionForce(timeStep, true);
+ }
+ }
+}
+
+void btDeformableMultiBodyDynamicsWorld::performGeometricCollisions(btScalar timeStep)
+{
+ BT_PROFILE("btDeformableMultiBodyDynamicsWorld::performGeometricCollisions");
+ // refit the BVH tree for CCD
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ if (psb->isActive())
+ {
+ m_softBodies[i]->updateFaceTree(true, false);
+ m_softBodies[i]->updateNodeTree(true, false);
+ for (int j = 0; j < m_softBodies[i]->m_faces.size(); ++j)
+ {
+ btSoftBody::Face& f = m_softBodies[i]->m_faces[j];
+ f.m_n0 = (f.m_n[1]->m_x - f.m_n[0]->m_x).cross(f.m_n[2]->m_x - f.m_n[0]->m_x);
+ }
+ }
+ }
+
+ // clear contact points & update DBVT
+ for (int r = 0; r < m_ccdIterations; ++r)
+ {
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ if (psb->isActive())
+ {
+ // clear contact points in the previous iteration
+ psb->m_faceNodeContacts.clear();
+
+ // update m_q and normals for CCD calculation
+ for (int j = 0; j < psb->m_nodes.size(); ++j)
+ {
+ psb->m_nodes[j].m_q = psb->m_nodes[j].m_x + timeStep * psb->m_nodes[j].m_v;
+ }
+ for (int j = 0; j < psb->m_faces.size(); ++j)
+ {
+ btSoftBody::Face& f = psb->m_faces[j];
+ f.m_n1 = (f.m_n[1]->m_q - f.m_n[0]->m_q).cross(f.m_n[2]->m_q - f.m_n[0]->m_q);
+ f.m_vn = (f.m_n[1]->m_v - f.m_n[0]->m_v).cross(f.m_n[2]->m_v - f.m_n[0]->m_v) * timeStep * timeStep;
+ }
+ }
+ }
+
+ // apply CCD to register new contact points
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ for (int j = i; j < m_softBodies.size(); ++j)
+ {
+ btSoftBody* psb1 = m_softBodies[i];
+ btSoftBody* psb2 = m_softBodies[j];
+ if (psb1->isActive() && psb2->isActive())
+ {
+ m_softBodies[i]->geometricCollisionHandler(m_softBodies[j]);
+ }
+ }
+ }
+
+ int penetration_count = 0;
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ if (psb->isActive())
+ {
+ penetration_count += psb->m_faceNodeContacts.size();
+ }
+ }
+ if (penetration_count == 0)
+ {
+ break;
+ }
+
+ // apply inelastic impulse
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ if (psb->isActive())
+ {
+ psb->applyRepulsionForce(timeStep, false);
+ }
+ }
+ }
+}
void btDeformableMultiBodyDynamicsWorld::softBodySelfCollision()
{
- m_deformableBodySolver->updateSoftBodies();
+ BT_PROFILE("btDeformableMultiBodyDynamicsWorld::softBodySelfCollision");
for (int i = 0; i < m_softBodies.size(); i++)
{
btSoftBody* psb = m_softBodies[i];
@@ -192,8 +316,6 @@ void btDeformableMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep)
}
}
node.m_x = node.m_x + timeStep * node.m_v;
- node.m_v -= node.m_vsplit;
- node.m_vsplit.setZero();
node.m_q = node.m_x;
node.m_vn = node.m_v;
}
@@ -255,6 +377,7 @@ void btDeformableMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep)
void btDeformableMultiBodyDynamicsWorld::solveConstraints(btScalar timeStep)
{
+ BT_PROFILE("btDeformableMultiBodyDynamicsWorld::solveConstraints");
// save v_{n+1}^* velocity after explicit forces
m_deformableBodySolver->backupVelocity();
@@ -265,8 +388,11 @@ void btDeformableMultiBodyDynamicsWorld::solveConstraints(btScalar timeStep)
solveContactConstraints();
// set up the directions in which the velocity does not change in the momentum solve
- m_deformableBodySolver->m_objective->m_projection.setProjection();
-
+ if (m_useProjection)
+ m_deformableBodySolver->m_objective->m_projection.setProjection();
+ else
+ m_deformableBodySolver->m_objective->m_projection.setLagrangeMultiplier();
+
// for explicit scheme, m_backupVelocity = v_{n+1}^*
// for implicit scheme, m_backupVelocity = v_n
// Here, set dv = v_{n+1} - v_n for nodes in contact
@@ -280,7 +406,7 @@ void btDeformableMultiBodyDynamicsWorld::solveConstraints(btScalar timeStep)
void btDeformableMultiBodyDynamicsWorld::setupConstraints()
{
// set up constraints between multibody and deformable bodies
- m_deformableBodySolver->setConstraints();
+ m_deformableBodySolver->setConstraints(m_solverInfo);
// set up constraints among multibodies
{
@@ -403,6 +529,17 @@ void btDeformableMultiBodyDynamicsWorld::reinitialize(btScalar timeStep)
dispatchInfo.m_stepCount = 0;
dispatchInfo.m_debugDraw = btMultiBodyDynamicsWorld::getDebugDrawer();
btMultiBodyDynamicsWorld::getSolverInfo().m_timeStep = timeStep;
+ if (m_useProjection)
+ {
+ m_deformableBodySolver->m_useProjection = true;
+// m_deformableBodySolver->m_objective->m_projection.m_useStrainLimiting = true;
+ m_deformableBodySolver->m_objective->m_preconditioner = m_deformableBodySolver->m_objective->m_massPreconditioner;
+ }
+ else
+ {
+ m_deformableBodySolver->m_objective->m_preconditioner = m_deformableBodySolver->m_objective->m_KKTPreconditioner;
+ }
+
}
@@ -566,6 +703,24 @@ void btDeformableMultiBodyDynamicsWorld::addForce(btSoftBody* psb, btDeformableL
}
}
+void btDeformableMultiBodyDynamicsWorld::removeForce(btSoftBody* psb, btDeformableLagrangianForce* force)
+{
+ btAlignedObjectArray<btDeformableLagrangianForce*>& forces = m_deformableBodySolver->m_objective->m_lf;
+ int removed_index = -1;
+ for (int i = 0; i < forces.size(); ++i)
+ {
+ if (forces[i]->getForceType() == force->getForceType())
+ {
+ forces[i]->removeSoftBody(psb);
+ if (forces[i]->m_softBodies.size() == 0)
+ removed_index = i;
+ break;
+ }
+ }
+ if (removed_index >= 0)
+ forces.removeAtIndex(removed_index);
+}
+
void btDeformableMultiBodyDynamicsWorld::removeSoftBody(btSoftBody* body)
{
m_softBodies.remove(body);
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h
index 7630385767..76b58a0378 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h
@@ -46,10 +46,10 @@ class btDeformableMultiBodyDynamicsWorld : public btMultiBodyDynamicsWorld
bool m_drawClusterTree;
btSoftBodyWorldInfo m_sbi;
btScalar m_internalTime;
- int m_contact_iterations;
+ int m_ccdIterations;
bool m_implicit;
bool m_lineSearch;
- bool m_selfCollision;
+ bool m_useProjection;
DeformableBodyInplaceSolverIslandCallback* m_solverDeformableBodyIslandCallback;
typedef void (*btSolverCallback)(btScalar time, btDeformableMultiBodyDynamicsWorld* world);
@@ -80,9 +80,7 @@ public:
m_solverCallback = cb;
}
- virtual ~btDeformableMultiBodyDynamicsWorld()
- {
- }
+ virtual ~btDeformableMultiBodyDynamicsWorld();
virtual btMultiBodyDynamicsWorld* getMultiBodyDynamicsWorld()
{
@@ -133,6 +131,8 @@ public:
void addForce(btSoftBody* psb, btDeformableLagrangianForce* force);
+ void removeForce(btSoftBody* psb, btDeformableLagrangianForce* force);
+
void removeSoftBody(btSoftBody* body);
void removeCollisionObject(btCollisionObject* collisionObject);
@@ -142,6 +142,8 @@ public:
void setupConstraints();
+ void performDeformableCollisionDetection();
+
void solveMultiBodyConstraints();
void solveContactConstraints();
@@ -159,7 +161,151 @@ public:
{
m_lineSearch = lineSearch;
}
+
+ void applyRepulsionForce(btScalar timeStep);
+
+ void performGeometricCollisions(btScalar timeStep);
+
+ struct btDeformableSingleRayCallback : public btBroadphaseRayCallback
+ {
+ btVector3 m_rayFromWorld;
+ btVector3 m_rayToWorld;
+ btTransform m_rayFromTrans;
+ btTransform m_rayToTrans;
+ btVector3 m_hitNormal;
+
+ const btDeformableMultiBodyDynamicsWorld* m_world;
+ btCollisionWorld::RayResultCallback& m_resultCallback;
+
+ btDeformableSingleRayCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld, const btDeformableMultiBodyDynamicsWorld* world, btCollisionWorld::RayResultCallback& resultCallback)
+ : m_rayFromWorld(rayFromWorld),
+ m_rayToWorld(rayToWorld),
+ m_world(world),
+ m_resultCallback(resultCallback)
+ {
+ m_rayFromTrans.setIdentity();
+ m_rayFromTrans.setOrigin(m_rayFromWorld);
+ m_rayToTrans.setIdentity();
+ m_rayToTrans.setOrigin(m_rayToWorld);
+
+ btVector3 rayDir = (rayToWorld - rayFromWorld);
+
+ rayDir.normalize();
+ ///what about division by zero? --> just set rayDirection[i] to INF/1e30
+ m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0];
+ m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1];
+ m_rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[2];
+ m_signs[0] = m_rayDirectionInverse[0] < 0.0;
+ m_signs[1] = m_rayDirectionInverse[1] < 0.0;
+ m_signs[2] = m_rayDirectionInverse[2] < 0.0;
+
+ m_lambda_max = rayDir.dot(m_rayToWorld - m_rayFromWorld);
+ }
+
+ virtual bool process(const btBroadphaseProxy* proxy)
+ {
+ ///terminate further ray tests, once the closestHitFraction reached zero
+ if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
+ return false;
+
+ btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject;
+
+ //only perform raycast if filterMask matches
+ if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
+ {
+ //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+ //btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+#if 0
+#ifdef RECALCULATE_AABB
+ btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+ collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
+#else
+ //getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
+ const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
+ const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
+#endif
+#endif
+ //btScalar hitLambda = m_resultCallback.m_closestHitFraction;
+ //culling already done by broadphase
+ //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
+ {
+ m_world->rayTestSingle(m_rayFromTrans, m_rayToTrans,
+ collisionObject,
+ collisionObject->getCollisionShape(),
+ collisionObject->getWorldTransform(),
+ m_resultCallback);
+ }
+ }
+ return true;
+ }
+ };
+
+
+ void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
+ {
+ BT_PROFILE("rayTest");
+ /// use the broadphase to accelerate the search for objects, based on their aabb
+ /// and for each object with ray-aabb overlap, perform an exact ray test
+ btDeformableSingleRayCallback rayCB(rayFromWorld, rayToWorld, this, resultCallback);
+
+#ifndef USE_BRUTEFORCE_RAYBROADPHASE
+ m_broadphasePairCache->rayTest(rayFromWorld, rayToWorld, rayCB);
+#else
+ for (int i = 0; i < this->getNumCollisionObjects(); i++)
+ {
+ rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
+ }
+#endif //USE_BRUTEFORCE_RAYBROADPHASE
+ }
+
+ void rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans,
+ btCollisionObject* collisionObject,
+ const btCollisionShape* collisionShape,
+ const btTransform& colObjWorldTransform,
+ RayResultCallback& resultCallback) const
+ {
+ if (collisionShape->isSoftBody())
+ {
+ btSoftBody* softBody = btSoftBody::upcast(collisionObject);
+ if (softBody)
+ {
+ btSoftBody::sRayCast softResult;
+ if (softBody->rayFaceTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult))
+ {
+ if (softResult.fraction <= resultCallback.m_closestHitFraction)
+ {
+ btCollisionWorld::LocalShapeInfo shapeInfo;
+ shapeInfo.m_shapePart = 0;
+ shapeInfo.m_triangleIndex = softResult.index;
+ // get the normal
+ btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin();
+ btVector3 normal = -rayDir;
+ normal.normalize();
+ {
+ normal = softBody->m_faces[softResult.index].m_normal;
+ if (normal.dot(rayDir) > 0)
+ {
+ // normal always point toward origin of the ray
+ normal = -normal;
+ }
+ }
+
+ btCollisionWorld::LocalRayResult rayResult(collisionObject,
+ &shapeInfo,
+ normal,
+ softResult.fraction);
+ bool normalInWorldSpace = true;
+ resultCallback.addSingleResult(rayResult, normalInWorldSpace);
+ }
+ }
+ }
+ }
+ else
+ {
+ btCollisionWorld::rayTestSingle(rayFromTrans, rayToTrans, collisionObject, collisionShape, colObjWorldTransform, resultCallback);
+ }
+ }
};
#endif //BT_DEFORMABLE_MULTIBODY_DYNAMICS_WORLD_H
diff --git a/thirdparty/bullet/BulletSoftBody/btDeformableNeoHookeanForce.h b/thirdparty/bullet/BulletSoftBody/btDeformableNeoHookeanForce.h
index 3d06e304d2..d89bc4aca4 100644
--- a/thirdparty/bullet/BulletSoftBody/btDeformableNeoHookeanForce.h
+++ b/thirdparty/bullet/BulletSoftBody/btDeformableNeoHookeanForce.h
@@ -24,21 +24,65 @@ class btDeformableNeoHookeanForce : public btDeformableLagrangianForce
{
public:
typedef btAlignedObjectArray<btVector3> TVStack;
- btScalar m_mu, m_lambda;
+ btScalar m_mu, m_lambda; // Lame Parameters
+ btScalar m_E, m_nu; // Young's modulus and Poisson ratio
btScalar m_mu_damp, m_lambda_damp;
btDeformableNeoHookeanForce(): m_mu(1), m_lambda(1)
{
btScalar damping = 0.05;
m_mu_damp = damping * m_mu;
m_lambda_damp = damping * m_lambda;
+ updateYoungsModulusAndPoissonRatio();
}
btDeformableNeoHookeanForce(btScalar mu, btScalar lambda, btScalar damping = 0.05): m_mu(mu), m_lambda(lambda)
{
m_mu_damp = damping * m_mu;
m_lambda_damp = damping * m_lambda;
+ updateYoungsModulusAndPoissonRatio();
}
-
+
+ void updateYoungsModulusAndPoissonRatio()
+ {
+ // conversion from Lame Parameters to Young's modulus and Poisson ratio
+ // https://en.wikipedia.org/wiki/Lam%C3%A9_parameters
+ m_E = m_mu * (3*m_lambda + 2*m_mu)/(m_lambda + m_mu);
+ m_nu = m_lambda * 0.5 / (m_mu + m_lambda);
+ }
+
+ void updateLameParameters()
+ {
+ // conversion from Young's modulus and Poisson ratio to Lame Parameters
+ // https://en.wikipedia.org/wiki/Lam%C3%A9_parameters
+ m_mu = m_E * 0.5 / (1 + m_nu);
+ m_lambda = m_E * m_nu / ((1 + m_nu) * (1- 2*m_nu));
+ }
+
+ void setYoungsModulus(btScalar E)
+ {
+ m_E = E;
+ updateLameParameters();
+ }
+
+ void setPoissonRatio(btScalar nu)
+ {
+ m_nu = nu;
+ updateLameParameters();
+ }
+
+ void setDamping(btScalar damping)
+ {
+ m_mu_damp = damping * m_mu;
+ m_lambda_damp = damping * m_lambda;
+ }
+
+ void setLameParameters(btScalar mu, btScalar lambda)
+ {
+ m_mu = mu;
+ m_lambda = lambda;
+ updateYoungsModulusAndPoissonRatio();
+ }
+
virtual void addScaledForces(btScalar scale, TVStack& force)
{
addScaledDampingForce(scale, force);
@@ -269,6 +313,8 @@ public:
}
}
+ virtual void buildDampingForceDifferentialDiagonal(btScalar scale, TVStack& diagA){}
+
virtual void addScaledElasticForceDifferential(btScalar scale, const TVStack& dx, TVStack& df)
{
int numNodes = getNumNodes();
diff --git a/thirdparty/bullet/BulletSoftBody/btPreconditioner.h b/thirdparty/bullet/BulletSoftBody/btPreconditioner.h
index d712420381..c2db448ef8 100644
--- a/thirdparty/bullet/BulletSoftBody/btPreconditioner.h
+++ b/thirdparty/bullet/BulletSoftBody/btPreconditioner.h
@@ -68,12 +68,221 @@ public:
virtual void operator()(const TVStack& x, TVStack& b)
{
btAssert(b.size() == x.size());
- btAssert(m_inv_mass.size() == x.size());
- for (int i = 0; i < b.size(); ++i)
+ btAssert(m_inv_mass.size() <= x.size());
+ for (int i = 0; i < m_inv_mass.size(); ++i)
{
b[i] = x[i] * m_inv_mass[i];
}
+ for (int i = m_inv_mass.size(); i < b.size(); ++i)
+ {
+ b[i] = x[i];
+ }
+ }
+};
+
+
+class KKTPreconditioner : public Preconditioner
+{
+ const btAlignedObjectArray<btSoftBody *>& m_softBodies;
+ const btDeformableContactProjection& m_projections;
+ const btAlignedObjectArray<btDeformableLagrangianForce*>& m_lf;
+ TVStack m_inv_A, m_inv_S;
+ const btScalar& m_dt;
+ const bool& m_implicit;
+public:
+ KKTPreconditioner(const btAlignedObjectArray<btSoftBody *>& softBodies, const btDeformableContactProjection& projections, const btAlignedObjectArray<btDeformableLagrangianForce*>& lf, const btScalar& dt, const bool& implicit)
+ : m_softBodies(softBodies)
+ , m_projections(projections)
+ , m_lf(lf)
+ , m_dt(dt)
+ , m_implicit(implicit)
+ {
+ }
+
+ virtual void reinitialize(bool nodeUpdated)
+ {
+ if (nodeUpdated)
+ {
+ int num_nodes = 0;
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ num_nodes += psb->m_nodes.size();
+ }
+ m_inv_A.resize(num_nodes);
+ }
+ buildDiagonalA(m_inv_A);
+ for (int i = 0; i < m_inv_A.size(); ++i)
+ {
+// printf("A[%d] = %f, %f, %f \n", i, m_inv_A[i][0], m_inv_A[i][1], m_inv_A[i][2]);
+ for (int d = 0; d < 3; ++d)
+ {
+ m_inv_A[i][d] = (m_inv_A[i][d] == 0) ? 0.0 : 1.0/ m_inv_A[i][d];
+ }
+ }
+ m_inv_S.resize(m_projections.m_lagrangeMultipliers.size());
+// printf("S.size() = %d \n", m_inv_S.size());
+ buildDiagonalS(m_inv_A, m_inv_S);
+ for (int i = 0; i < m_inv_S.size(); ++i)
+ {
+// printf("S[%d] = %f, %f, %f \n", i, m_inv_S[i][0], m_inv_S[i][1], m_inv_S[i][2]);
+ for (int d = 0; d < 3; ++d)
+ {
+ m_inv_S[i][d] = (m_inv_S[i][d] == 0) ? 0.0 : 1.0/ m_inv_S[i][d];
+ }
+ }
+ }
+
+ void buildDiagonalA(TVStack& diagA) const
+ {
+ size_t counter = 0;
+ for (int i = 0; i < m_softBodies.size(); ++i)
+ {
+ btSoftBody* psb = m_softBodies[i];
+ for (int j = 0; j < psb->m_nodes.size(); ++j)
+ {
+ const btSoftBody::Node& node = psb->m_nodes[j];
+ diagA[counter] = (node.m_im == 0) ? btVector3(0,0,0) : btVector3(1.0/node.m_im, 1.0 / node.m_im, 1.0 / node.m_im);
+ ++counter;
+ }
+ }
+ if (m_implicit)
+ {
+ printf("implicit not implemented\n");
+ btAssert(false);
+ }
+ for (int i = 0; i < m_lf.size(); ++i)
+ {
+ // add damping matrix
+ m_lf[i]->buildDampingForceDifferentialDiagonal(-m_dt, diagA);
+ }
+ }
+
+ void buildDiagonalS(const TVStack& inv_A, TVStack& diagS)
+ {
+ for (int c = 0; c < m_projections.m_lagrangeMultipliers.size(); ++c)
+ {
+ // S[k,k] = e_k^T * C A_d^-1 C^T * e_k
+ const LagrangeMultiplier& lm = m_projections.m_lagrangeMultipliers[c];
+ btVector3& t = diagS[c];
+ t.setZero();
+ for (int j = 0; j < lm.m_num_constraints; ++j)
+ {
+ for (int i = 0; i < lm.m_num_nodes; ++i)
+ {
+ for (int d = 0; d < 3; ++d)
+ {
+ t[j] += inv_A[lm.m_indices[i]][d] * lm.m_dirs[j][d] * lm.m_dirs[j][d] * lm.m_weights[i] * lm.m_weights[i];
+ }
+ }
+ }
+ }
+ }
+#define USE_FULL_PRECONDITIONER
+#ifndef USE_FULL_PRECONDITIONER
+ virtual void operator()(const TVStack& x, TVStack& b)
+ {
+ btAssert(b.size() == x.size());
+ for (int i = 0; i < m_inv_A.size(); ++i)
+ {
+ b[i] = x[i] * m_inv_A[i];
+ }
+ int offset = m_inv_A.size();
+ for (int i = 0; i < m_inv_S.size(); ++i)
+ {
+ b[i+offset] = x[i+offset] * m_inv_S[i];
+ }
+ }
+#else
+ virtual void operator()(const TVStack& x, TVStack& b)
+ {
+ btAssert(b.size() == x.size());
+ int offset = m_inv_A.size();
+
+ for (int i = 0; i < m_inv_A.size(); ++i)
+ {
+ b[i] = x[i] * m_inv_A[i];
+ }
+
+ for (int i = 0; i < m_inv_S.size(); ++i)
+ {
+ b[i+offset].setZero();
+ }
+
+ for (int c = 0; c < m_projections.m_lagrangeMultipliers.size(); ++c)
+ {
+ const LagrangeMultiplier& lm = m_projections.m_lagrangeMultipliers[c];
+ // C * x
+ for (int d = 0; d < lm.m_num_constraints; ++d)
+ {
+ for (int i = 0; i < lm.m_num_nodes; ++i)
+ {
+ b[offset+c][d] += lm.m_weights[i] * b[lm.m_indices[i]].dot(lm.m_dirs[d]);
+ }
+ }
+ }
+
+ for (int i = 0; i < m_inv_S.size(); ++i)
+ {
+ b[i+offset] = b[i+offset] * m_inv_S[i];
+ }
+
+ for (int i = 0; i < m_inv_A.size(); ++i)
+ {
+ b[i].setZero();
+ }
+
+ for (int c = 0; c < m_projections.m_lagrangeMultipliers.size(); ++c)
+ {
+ // C^T * lambda
+ const LagrangeMultiplier& lm = m_projections.m_lagrangeMultipliers[c];
+ for (int i = 0; i < lm.m_num_nodes; ++i)
+ {
+ for (int j = 0; j < lm.m_num_constraints; ++j)
+ {
+ b[lm.m_indices[i]] += b[offset+c][j] * lm.m_weights[i] * lm.m_dirs[j];
+ }
+ }
+ }
+
+ for (int i = 0; i < m_inv_A.size(); ++i)
+ {
+ b[i] = (x[i] - b[i]) * m_inv_A[i];
+ }
+
+ TVStack t;
+ t.resize(b.size());
+ for (int i = 0; i < m_inv_S.size(); ++i)
+ {
+ t[i+offset] = x[i+offset] * m_inv_S[i];
+ }
+ for (int i = 0; i < m_inv_A.size(); ++i)
+ {
+ t[i].setZero();
+ }
+ for (int c = 0; c < m_projections.m_lagrangeMultipliers.size(); ++c)
+ {
+ // C^T * lambda
+ const LagrangeMultiplier& lm = m_projections.m_lagrangeMultipliers[c];
+ for (int i = 0; i < lm.m_num_nodes; ++i)
+ {
+ for (int j = 0; j < lm.m_num_constraints; ++j)
+ {
+ t[lm.m_indices[i]] += t[offset+c][j] * lm.m_weights[i] * lm.m_dirs[j];
+ }
+ }
+ }
+ for (int i = 0; i < m_inv_A.size(); ++i)
+ {
+ b[i] += t[i] * m_inv_A[i];
+ }
+
+ for (int i = 0; i < m_inv_S.size(); ++i)
+ {
+ b[i+offset] -= x[i+offset] * m_inv_S[i];
+ }
}
+#endif
};
#endif /* BT_PRECONDITIONER_H */
diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp b/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp
index 2a458b1d80..81b846d7f8 100644
--- a/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp
+++ b/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp
@@ -18,6 +18,7 @@ subject to the following restrictions:
#include "BulletSoftBody/btSoftBodySolvers.h"
#include "btSoftBodyData.h"
#include "LinearMath/btSerializer.h"
+#include "LinearMath/btImplicitQRSVD.h"
#include "LinearMath/btAlignedAllocator.h"
#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraint.h"
@@ -25,6 +26,107 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btTriangleShape.h"
#include <iostream>
//
+static inline btDbvtNode* buildTreeBottomUp(btAlignedObjectArray<btDbvtNode*>& leafNodes, btAlignedObjectArray<btAlignedObjectArray<int> >& adj)
+{
+ int N = leafNodes.size();
+ if (N == 0)
+ {
+ return NULL;
+ }
+ while (N > 1)
+ {
+ btAlignedObjectArray<bool> marked;
+ btAlignedObjectArray<btDbvtNode*> newLeafNodes;
+ btAlignedObjectArray<std::pair<int,int> > childIds;
+ btAlignedObjectArray<btAlignedObjectArray<int> > newAdj;
+ marked.resize(N);
+ for (int i = 0; i < N; ++i)
+ marked[i] = false;
+
+ // pair adjacent nodes into new(parent) node
+ for (int i = 0; i < N; ++i)
+ {
+ if (marked[i])
+ continue;
+ bool merged = false;
+ for (int j = 0; j < adj[i].size(); ++j)
+ {
+ int n = adj[i][j];
+ if (!marked[adj[i][j]])
+ {
+ btDbvtNode* node = new (btAlignedAlloc(sizeof(btDbvtNode), 16)) btDbvtNode();
+ node->parent = NULL;
+ node->childs[0] = leafNodes[i];
+ node->childs[1] = leafNodes[n];
+ leafNodes[i]->parent = node;
+ leafNodes[n]->parent = node;
+ newLeafNodes.push_back(node);
+ childIds.push_back(std::make_pair(i,n));
+ merged = true;
+ marked[n] = true;
+ break;
+ }
+ }
+ if (!merged)
+ {
+ newLeafNodes.push_back(leafNodes[i]);
+ childIds.push_back(std::make_pair(i,-1));
+ }
+ marked[i] = true;
+ }
+ // update adjacency matrix
+ newAdj.resize(newLeafNodes.size());
+ for (int i = 0; i < newLeafNodes.size(); ++i)
+ {
+ for (int j = i+1; j < newLeafNodes.size(); ++j)
+ {
+ bool neighbor = false;
+ const btAlignedObjectArray<int>& leftChildNeighbors = adj[childIds[i].first];
+ for (int k = 0; k < leftChildNeighbors.size(); ++k)
+ {
+ if (leftChildNeighbors[k] == childIds[j].first || leftChildNeighbors[k] == childIds[j].second)
+ {
+ neighbor = true;
+ break;
+ }
+ }
+ if (!neighbor && childIds[i].second != -1)
+ {
+ const btAlignedObjectArray<int>& rightChildNeighbors = adj[childIds[i].second];
+ for (int k = 0; k < rightChildNeighbors.size(); ++k)
+ {
+ if (rightChildNeighbors[k] == childIds[j].first || rightChildNeighbors[k] == childIds[j].second)
+ {
+ neighbor = true;
+ break;
+ }
+ }
+ }
+ if (neighbor)
+ {
+ newAdj[i].push_back(j);
+ newAdj[j].push_back(i);
+ }
+ }
+ }
+ leafNodes = newLeafNodes;
+ //this assignment leaks memory, the assignment doesn't do a deep copy, for now a manual copy
+ //adj = newAdj;
+ adj.clear();
+ adj.resize(newAdj.size());
+ for (int i = 0; i < newAdj.size(); i++)
+ {
+ for (int j = 0; j < newAdj[i].size(); j++)
+ {
+ adj[i].push_back(newAdj[i][j]);
+ }
+ }
+ N = leafNodes.size();
+ }
+ return leafNodes[0];
+}
+
+//
btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btVector3* x, const btScalar* m)
: m_softBodySolver(0), m_worldInfo(worldInfo)
{
@@ -41,6 +143,7 @@ btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btV
/* Nodes */
const btScalar margin = getCollisionShape()->getMargin();
m_nodes.resize(node_count);
+ m_X.resize(node_count);
for (int i = 0, ni = node_count; i < ni; ++i)
{
Node& n = m_nodes[i];
@@ -51,8 +154,11 @@ btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btV
n.m_im = n.m_im > 0 ? 1 / n.m_im : 0;
n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x, margin), &n);
n.m_material = pm;
+ m_X[i] = n.m_x;
}
updateBounds();
+ setCollisionQuadrature(3);
+ m_fdbvnt = 0;
}
btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo)
@@ -111,15 +217,18 @@ void btSoftBody::initDefaults()
m_collisionShape = new btSoftBodyCollisionShape(this);
m_collisionShape->setMargin(0.25f);
- m_initialWorldTransform.setIdentity();
+ m_worldTransform.setIdentity();
m_windVelocity = btVector3(0, 0, 0);
m_restLengthScale = btScalar(1.0);
- m_dampingCoefficient = 1;
- m_sleepingThreshold = 0.1;
- m_useFaceContact = true;
+ m_dampingCoefficient = 1.0;
+ m_sleepingThreshold = .4;
m_useSelfCollision = false;
- m_collisionFlags = 0;
+ m_collisionFlags = 0;
+ m_softSoftCollision = false;
+ m_maxSpeedSquared = 0;
+ m_repulsionStiffness = 0.5;
+ m_fdbvnt = 0;
}
//
@@ -134,6 +243,8 @@ btSoftBody::~btSoftBody()
btAlignedFree(m_materials[i]);
for (i = 0; i < m_joints.size(); ++i)
btAlignedFree(m_joints[i]);
+ if (m_fdbvnt)
+ delete m_fdbvnt;
}
//
@@ -897,6 +1008,71 @@ void btSoftBody::setVolumeDensity(btScalar density)
}
//
+btVector3 btSoftBody::getLinearVelocity()
+{
+ btVector3 total_momentum = btVector3(0,0,0);
+ for (int i = 0; i < m_nodes.size(); ++i)
+ {
+ btScalar mass = m_nodes[i].m_im == 0 ? 0 : 1.0/m_nodes[i].m_im;
+ total_momentum += mass * m_nodes[i].m_v;
+ }
+ btScalar total_mass = getTotalMass();
+ return total_mass == 0 ? total_momentum : total_momentum / total_mass;
+}
+
+//
+void btSoftBody::setLinearVelocity(const btVector3& linVel)
+{
+ btVector3 old_vel = getLinearVelocity();
+ btVector3 diff = linVel - old_vel;
+ for (int i = 0; i < m_nodes.size(); ++i)
+ m_nodes[i].m_v += diff;
+}
+
+//
+void btSoftBody::setAngularVelocity(const btVector3& angVel)
+{
+ btVector3 old_vel = getLinearVelocity();
+ btVector3 com = getCenterOfMass();
+ for (int i = 0; i < m_nodes.size(); ++i)
+ {
+ m_nodes[i].m_v = angVel.cross(m_nodes[i].m_x - com) + old_vel;
+ }
+}
+
+//
+btTransform btSoftBody::getRigidTransform()
+{
+ btVector3 t = getCenterOfMass();
+ btMatrix3x3 S;
+ S.setZero();
+ // get rotation that minimizes L2 difference: \sum_i || RX_i + t - x_i ||
+ for (int i = 0; i < m_nodes.size(); ++i)
+ {
+ S += OuterProduct(m_X[i], t-m_nodes[i].m_x);
+ }
+ btVector3 sigma;
+ btMatrix3x3 U,V;
+ singularValueDecomposition(S,U,sigma,V);
+ btMatrix3x3 R = V * U.transpose();
+ btTransform trs;
+ trs.setIdentity();
+ trs.setOrigin(t);
+ trs.setBasis(R);
+ return trs;
+}
+
+//
+void btSoftBody::transformTo(const btTransform& trs)
+{
+ // get the current best rigid fit
+ btTransform current_transform = getRigidTransform();
+ // apply transform in material space
+ btTransform new_transform = trs * current_transform.inverse();
+ transform(new_transform);
+}
+
+//
void btSoftBody::transform(const btTransform& trs)
{
const btScalar margin = getCollisionShape()->getMargin();
@@ -916,7 +1092,6 @@ void btSoftBody::transform(const btTransform& trs)
updateNormals();
updateBounds();
updateConstants();
- m_initialWorldTransform = trs;
}
//
@@ -1834,6 +2009,25 @@ bool btSoftBody::rayTest(const btVector3& rayFrom,
return (rayTest(rayFrom, rayTo, results.fraction, results.feature, results.index, false) != 0);
}
+bool btSoftBody::rayFaceTest(const btVector3& rayFrom,
+ const btVector3& rayTo,
+ sRayCast& results)
+{
+ if (m_faces.size() == 0)
+ return false;
+ else
+ {
+ if (m_fdbvt.empty())
+ initializeFaceTree();
+ }
+
+ results.body = this;
+ results.fraction = 1.f;
+ results.index = -1;
+
+ return (rayFaceTest(rayFrom, rayTo, results.fraction, results.index) != 0);
+}
+
//
void btSoftBody::setSolver(eSolverPresets::_ preset)
{
@@ -2339,15 +2533,160 @@ int btSoftBody::rayTest(const btVector3& rayFrom, const btVector3& rayTo,
return (cnt);
}
+int btSoftBody::rayFaceTest(const btVector3& rayFrom, const btVector3& rayTo,
+ btScalar& mint, int& index) const
+{
+ int cnt = 0;
+ { /* Use dbvt */
+ RayFromToCaster collider(rayFrom, rayTo, mint);
+
+ btDbvt::rayTest(m_fdbvt.m_root, rayFrom, rayTo, collider);
+ if (collider.m_face)
+ {
+ mint = collider.m_mint;
+ index = (int)(collider.m_face - &m_faces[0]);
+ cnt = 1;
+ }
+ }
+ return (cnt);
+}
+
+
//
+static inline btDbvntNode* copyToDbvnt(const btDbvtNode* n)
+{
+ if (n == 0)
+ return 0;
+ btDbvntNode* root = new btDbvntNode(n);
+ if (n->isinternal())
+ {
+ btDbvntNode* c0 = copyToDbvnt(n->childs[0]);
+ root->childs[0] = c0;
+ btDbvntNode* c1 = copyToDbvnt(n->childs[1]);
+ root->childs[1] = c1;
+ }
+ return root;
+}
+
+static inline void calculateNormalCone(btDbvntNode* root)
+{
+ if (!root)
+ return;
+ if (root->isleaf())
+ {
+ const btSoftBody::Face* face = (btSoftBody::Face*)root->data;
+ root->normal = face->m_normal;
+ root->angle = 0;
+ }
+ else
+ {
+ btVector3 n0(0,0,0), n1(0,0,0);
+ btScalar a0 = 0, a1 = 0;
+ if (root->childs[0])
+ {
+ calculateNormalCone(root->childs[0]);
+ n0 = root->childs[0]->normal;
+ a0 = root->childs[0]->angle;
+ }
+ if (root->childs[1])
+ {
+ calculateNormalCone(root->childs[1]);
+ n1 = root->childs[1]->normal;
+ a1 = root->childs[1]->angle;
+ }
+ root->normal = (n0+n1).safeNormalize();
+ root->angle = btMax(a0,a1) + btAngle(n0, n1)*0.5;
+ }
+}
+
void btSoftBody::initializeFaceTree()
{
+ BT_PROFILE("btSoftBody::initializeFaceTree");
m_fdbvt.clear();
+ // create leaf nodes;
+ btAlignedObjectArray<btDbvtNode*> leafNodes;
+ leafNodes.resize(m_faces.size());
for (int i = 0; i < m_faces.size(); ++i)
{
Face& f = m_faces[i];
- f.m_leaf = m_fdbvt.insert(VolumeOf(f, 0), &f);
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol = VolumeOf(f, 0);
+ btDbvtNode* node = new (btAlignedAlloc(sizeof(btDbvtNode), 16)) btDbvtNode();
+ node->parent = NULL;
+ node->data = &f;
+ node->childs[1] = 0;
+ node->volume = vol;
+ leafNodes[i] = node;
+ f.m_leaf = node;
}
+ btAlignedObjectArray<btAlignedObjectArray<int> > adj;
+ adj.resize(m_faces.size());
+ // construct the adjacency list for triangles
+ for (int i = 0; i < adj.size(); ++i)
+ {
+ for (int j = i+1; j < adj.size(); ++j)
+ {
+ int dup = 0;
+ for (int k = 0; k < 3; ++k)
+ {
+ for (int l = 0; l < 3; ++l)
+ {
+ if (m_faces[i].m_n[k] == m_faces[j].m_n[l])
+ {
+ ++dup;
+ break;
+ }
+ }
+ if (dup == 2)
+ {
+ adj[i].push_back(j);
+ adj[j].push_back(i);
+ }
+ }
+ }
+ }
+ m_fdbvt.m_root = buildTreeBottomUp(leafNodes, adj);
+ if (m_fdbvnt)
+ delete m_fdbvnt;
+ m_fdbvnt = copyToDbvnt(m_fdbvt.m_root);
+ updateFaceTree(false, false);
+ rebuildNodeTree();
+}
+
+//
+void btSoftBody::rebuildNodeTree()
+{
+ m_ndbvt.clear();
+ btAlignedObjectArray<btDbvtNode*> leafNodes;
+ leafNodes.resize(m_nodes.size());
+ for (int i = 0; i < m_nodes.size(); ++i)
+ {
+ Node& n = m_nodes[i];
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol = btDbvtVolume::FromCR(n.m_x, 0);
+ btDbvtNode* node = new (btAlignedAlloc(sizeof(btDbvtNode), 16)) btDbvtNode();
+ node->parent = NULL;
+ node->data = &n;
+ node->childs[1] = 0;
+ node->volume = vol;
+ leafNodes[i] = node;
+ n.m_leaf = node;
+ }
+ btAlignedObjectArray<btAlignedObjectArray<int> > adj;
+ adj.resize(m_nodes.size());
+ btAlignedObjectArray<int> old_id;
+ old_id.resize(m_nodes.size());
+ for (int i = 0; i < m_nodes.size(); ++i)
+ old_id[i] = m_nodes[i].index;
+ for (int i = 0; i < m_nodes.size(); ++i)
+ m_nodes[i].index = i;
+ for (int i = 0; i < m_links.size(); ++i)
+ {
+ Link& l = m_links[i];
+ adj[l.m_n[0]->index].push_back(l.m_n[1]->index);
+ adj[l.m_n[1]->index].push_back(l.m_n[0]->index);
+ }
+ m_ndbvt.m_root = buildTreeBottomUp(leafNodes, adj);
+ for (int i = 0; i < m_nodes.size(); ++i)
+ m_nodes[i].index = old_id[i];
}
//
@@ -2403,10 +2742,9 @@ bool btSoftBody::checkDeformableContact(const btCollisionObjectWrapper* colObjWr
const btCollisionObject* tmpCollisionObj = colObjWrap->getCollisionObject();
// use the position x_{n+1}^* = x_n + dt * v_{n+1}^* where v_{n+1}^* = v_n + dtg for collision detect
// but resolve contact at x_n
-// btTransform wtr = (predict) ?
-// (colObjWrap->m_preTransform != NULL ? tmpCollisionObj->getInterpolationWorldTransform()*(*colObjWrap->m_preTransform) : tmpCollisionObj->getInterpolationWorldTransform())
-// : colObjWrap->getWorldTransform();
- const btTransform& wtr = colObjWrap->getWorldTransform();
+ btTransform wtr = (predict) ?
+ (colObjWrap->m_preTransform != NULL ? tmpCollisionObj->getInterpolationWorldTransform()*(*colObjWrap->m_preTransform) : tmpCollisionObj->getInterpolationWorldTransform())
+ : colObjWrap->getWorldTransform();
btScalar dst =
m_worldInfo->m_sparsesdf.Evaluate(
wtr.invXform(x),
@@ -2457,7 +2795,6 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO
btTransform wtr = (predict) ?
(colObjWrap->m_preTransform != NULL ? tmpCollisionObj->getInterpolationWorldTransform()*(*colObjWrap->m_preTransform) : tmpCollisionObj->getInterpolationWorldTransform())
: colObjWrap->getWorldTransform();
-// const btTransform& wtr = colObjWrap->getWorldTransform();
btScalar dst;
//#define USE_QUADRATURE 1
@@ -2476,6 +2813,7 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO
nrm,
margin);
nrm = wtr.getBasis() * nrm;
+ cti.m_colObj = colObjWrap->getCollisionObject();
// use cached contact point
}
else
@@ -2492,10 +2830,11 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO
contact_point = results.witnesses[0];
getBarycentric(contact_point, f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary);
nrm = results.normal;
+ cti.m_colObj = colObjWrap->getCollisionObject();
for (int i = 0; i < 3; ++i)
f.m_pcontact[i] = bary[i];
}
-
+ return (dst < 0);
#endif
// use collision quadrature point
@@ -2505,7 +2844,11 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO
btVector3 local_nrm;
for (int q = 0; q < m_quads.size(); ++q)
{
- btVector3 p = BaryEval(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, m_quads[q]);
+ btVector3 p;
+ if (predict)
+ p = BaryEval(f.m_n[0]->m_q, f.m_n[1]->m_q, f.m_n[2]->m_q, m_quads[q]);
+ else
+ p = BaryEval(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, m_quads[q]);
btScalar local_dst = m_worldInfo->m_sparsesdf.Evaluate(
wtr.invXform(p),
shp,
@@ -2513,43 +2856,83 @@ bool btSoftBody::checkDeformableFaceContact(const btCollisionObjectWrapper* colO
margin);
if (local_dst < dst)
{
+ if (local_dst < 0 && predict)
+ return true;
dst = local_dst;
contact_point = p;
bary = m_quads[q];
- nrm = wtr.getBasis() * local_nrm;
+ nrm = local_nrm;
+ }
+ if (!predict)
+ {
+ cti.m_colObj = colObjWrap->getCollisionObject();
+ cti.m_normal = wtr.getBasis() * nrm;
+ cti.m_offset = dst;
}
}
+ return (dst < 0);
}
#endif
+// // regular face contact
+// {
+// btGjkEpaSolver2::sResults results;
+// btTransform triangle_transform;
+// triangle_transform.setIdentity();
+// triangle_transform.setOrigin(f.m_n[0]->m_x);
+// btTriangleShape triangle(btVector3(0,0,0), f.m_n[1]->m_x-f.m_n[0]->m_x, f.m_n[2]->m_x-f.m_n[0]->m_x);
+// btVector3 guess(0,0,0);
+// if (predict)
+// {
+// triangle_transform.setOrigin(f.m_n[0]->m_q);
+// triangle = btTriangleShape(btVector3(0,0,0), f.m_n[1]->m_q-f.m_n[0]->m_q, f.m_n[2]->m_q-f.m_n[0]->m_q);
+// }
+// const btConvexShape* csh = static_cast<const btConvexShape*>(shp);
+//// btGjkEpaSolver2::SignedDistance(&triangle, triangle_transform, csh, wtr, guess, results);
+//// dst = results.distance - margin;
+//// contact_point = results.witnesses[0];
+// btGjkEpaSolver2::Penetration(&triangle, triangle_transform, csh, wtr, guess, results);
+// if (results.status == btGjkEpaSolver2::sResults::Separated)
+// return false;
+// dst = results.distance - margin;
+// contact_point = results.witnesses[1];
+// getBarycentric(contact_point, f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary);
+// nrm = results.normal;
+// for (int i = 0; i < 3; ++i)
+// f.m_pcontact[i] = bary[i];
+// }
+//
+// if (!predict)
+// {
+// cti.m_colObj = colObjWrap->getCollisionObject();
+// cti.m_normal = nrm;
+// cti.m_offset = dst;
+// }
+//
+
// regular face contact
{
btGjkEpaSolver2::sResults results;
btTransform triangle_transform;
triangle_transform.setIdentity();
- triangle_transform.setOrigin(f.m_n[0]->m_x);
- btTriangleShape triangle(btVector3(0,0,0), f.m_n[1]->m_x-f.m_n[0]->m_x, f.m_n[2]->m_x-f.m_n[0]->m_x);
+ triangle_transform.setOrigin(f.m_n[0]->m_q);
+ btTriangleShape triangle(btVector3(0,0,0), f.m_n[1]->m_q-f.m_n[0]->m_q, f.m_n[2]->m_q-f.m_n[0]->m_q);
btVector3 guess(0,0,0);
const btConvexShape* csh = static_cast<const btConvexShape*>(shp);
btGjkEpaSolver2::SignedDistance(&triangle, triangle_transform, csh, wtr, guess, results);
- dst = results.distance - margin;
+ dst = results.distance-csh->getMargin();
+ dst -= margin;
+ if (dst >= 0)
+ return false;
contact_point = results.witnesses[0];
- getBarycentric(contact_point, f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary);
+ getBarycentric(contact_point, f.m_n[0]->m_q, f.m_n[1]->m_q, f.m_n[2]->m_q, bary);
+ btVector3 curr = BaryEval(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, bary);
nrm = results.normal;
- for (int i = 0; i < 3; ++i)
- f.m_pcontact[i] = bary[i];
- }
-
- if (!predict)
- {
cti.m_colObj = colObjWrap->getCollisionObject();
cti.m_normal = nrm;
- cti.m_offset = dst;
+ cti.m_offset = dst + (curr - contact_point).dot(nrm);
}
-
- if (dst < 0)
- return true;
- return (false);
+ return (dst < 0);
}
//
@@ -3075,6 +3458,7 @@ void btSoftBody::setSpringStiffness(btScalar k)
{
m_links[i].Feature::m_material->m_kLST = k;
}
+ m_repulsionStiffness = k;
}
void btSoftBody::initializeDmInverse()
@@ -3372,18 +3756,39 @@ void btSoftBody::setMaxStress(btScalar maxStress)
//
void btSoftBody::interpolateRenderMesh()
{
- for (int i = 0; i < m_renderNodes.size(); ++i)
- {
- Node& n = m_renderNodes[i];
- n.m_x.setZero();
- for (int j = 0; j < 4; ++j)
- {
- if (m_renderNodesParents[i].size())
+ if (m_z.size() > 0)
+ {
+ for (int i = 0; i < m_renderNodes.size(); ++i)
+ {
+ const Node* p0 = m_renderNodesParents[i][0];
+ const Node* p1 = m_renderNodesParents[i][1];
+ const Node* p2 = m_renderNodesParents[i][2];
+ btVector3 normal = btCross(p1->m_x - p0->m_x, p2->m_x - p0->m_x);
+ btVector3 unit_normal = normal.normalized();
+ Node& n = m_renderNodes[i];
+ n.m_x.setZero();
+ for (int j = 0; j < 3; ++j)
{
n.m_x += m_renderNodesParents[i][j]->m_x * m_renderNodesInterpolationWeights[i][j];
}
- }
- }
+ n.m_x += m_z[i] * unit_normal;
+ }
+ }
+ else
+ {
+ for (int i = 0; i < m_renderNodes.size(); ++i)
+ {
+ Node& n = m_renderNodes[i];
+ n.m_x.setZero();
+ for (int j = 0; j < 4; ++j)
+ {
+ if (m_renderNodesParents[i].size())
+ {
+ n.m_x += m_renderNodesParents[i][j]->m_x * m_renderNodesInterpolationWeights[i][j];
+ }
+ }
+ }
+ }
}
void btSoftBody::setCollisionQuadrature(int N)
@@ -3649,13 +4054,10 @@ void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap
break;
case fCollision::SDF_RD:
{
-
btRigidBody* prb1 = (btRigidBody*)btRigidBody::upcast(pcoWrap->getCollisionObject());
if (pcoWrap->getCollisionObject()->isActive() || this->isActive())
{
const btTransform wtr = pcoWrap->getWorldTransform();
-// const btTransform ctr = pcoWrap->getWorldTransform();
-// const btScalar timemargin = (wtr.getOrigin() - ctr.getOrigin()).length();
const btScalar timemargin = 0;
const btScalar basemargin = getCollisionShape()->getMargin();
btVector3 mins;
@@ -3667,22 +4069,25 @@ void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap
maxs);
volume = btDbvtVolume::FromMM(mins, maxs);
volume.Expand(btVector3(basemargin, basemargin, basemargin));
- btSoftColliders::CollideSDF_RD docollideNode;
- docollideNode.psb = this;
- docollideNode.m_colObj1Wrap = pcoWrap;
- docollideNode.m_rigidBody = prb1;
- docollideNode.dynmargin = basemargin + timemargin;
- docollideNode.stamargin = basemargin;
- m_ndbvt.collideTV(m_ndbvt.m_root, volume, docollideNode);
-
- if (this->m_useFaceContact)
+ if (m_cfg.collisions & fCollision::SDF_RDN)
+ {
+ btSoftColliders::CollideSDF_RD docollideNode;
+ docollideNode.psb = this;
+ docollideNode.m_colObj1Wrap = pcoWrap;
+ docollideNode.m_rigidBody = prb1;
+ docollideNode.dynmargin = basemargin + timemargin;
+ docollideNode.stamargin = basemargin;
+ m_ndbvt.collideTV(m_ndbvt.m_root, volume, docollideNode);
+ }
+
+ if (((pcoWrap->getCollisionObject()->getInternalType() == CO_RIGID_BODY) && (m_cfg.collisions & fCollision::SDF_RDF)) || ((pcoWrap->getCollisionObject()->getInternalType() == CO_FEATHERSTONE_LINK) && (m_cfg.collisions & fCollision::SDF_MDF)))
{
btSoftColliders::CollideSDF_RDF docollideFace;
docollideFace.psb = this;
docollideFace.m_colObj1Wrap = pcoWrap;
docollideFace.m_rigidBody = prb1;
- docollideFace.dynmargin = basemargin + timemargin;
- docollideFace.stamargin = basemargin;
+ docollideFace.dynmargin = basemargin + timemargin;
+ docollideFace.stamargin = basemargin;
m_fdbvt.collideTV(m_fdbvt.m_root, volume, docollideFace);
}
}
@@ -3691,51 +4096,6 @@ void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap
}
}
-static inline btDbvntNode* copyToDbvnt(const btDbvtNode* n)
-{
- if (n == 0)
- return 0;
- btDbvntNode* root = new btDbvntNode(n);
- if (n->isinternal())
- {
- btDbvntNode* c0 = copyToDbvnt(n->childs[0]);
- root->childs[0] = c0;
- btDbvntNode* c1 = copyToDbvnt(n->childs[1]);
- root->childs[1] = c1;
- }
- return root;
-}
-
-static inline void calculateNormalCone(btDbvntNode* root)
-{
- if (!root)
- return;
- if (root->isleaf())
- {
- const btSoftBody::Face* face = (btSoftBody::Face*)root->data;
- root->normal = face->m_normal;
- root->angle = 0;
- }
- else
- {
- btVector3 n0(0,0,0), n1(0,0,0);
- btScalar a0 = 0, a1 = 0;
- if (root->childs[0])
- {
- calculateNormalCone(root->childs[0]);
- n0 = root->childs[0]->normal;
- a0 = root->childs[0]->angle;
- }
- if (root->childs[1])
- {
- calculateNormalCone(root->childs[1]);
- n1 = root->childs[1]->normal;
- a1 = root->childs[1]->angle;
- }
- root->normal = (n0+n1).safeNormalize();
- root->angle = btMax(a0,a1) + btAngle(n0, n1)*0.5;
- }
-}
//
void btSoftBody::defaultCollisionHandler(btSoftBody* psb)
{
@@ -3779,6 +4139,8 @@ void btSoftBody::defaultCollisionHandler(btSoftBody* psb)
break;
case fCollision::VF_DD:
{
+ if (!psb->m_softSoftCollision)
+ return;
if (psb->isActive() || this->isActive())
{
if (this != psb)
@@ -3797,6 +4159,7 @@ void btSoftBody::defaultCollisionHandler(btSoftBody* psb)
docollide.psb[0]->m_ndbvt.collideTT(docollide.psb[0]->m_ndbvt.m_root,
docollide.psb[1]->m_fdbvt.m_root,
docollide);
+
/* psb1 nodes vs psb0 faces */
if (this->m_tetras.size() > 0)
docollide.useFaceNormal = true;
@@ -3812,20 +4175,17 @@ void btSoftBody::defaultCollisionHandler(btSoftBody* psb)
{
if (psb->useSelfCollision())
{
- btSoftColliders::CollideFF_DD docollide;
- docollide.mrg = getCollisionShape()->getMargin() +
- psb->getCollisionShape()->getMargin();
- docollide.psb[0] = this;
- docollide.psb[1] = psb;
- if (this->m_tetras.size() > 0)
- docollide.useFaceNormal = true;
- else
- docollide.useFaceNormal = false;
- /* psb0 faces vs psb0 faces */
- btDbvntNode* root = copyToDbvnt(this->m_fdbvt.m_root);
- calculateNormalCone(root);
- this->m_fdbvt.selfCollideT(root,docollide);
- delete root;
+ btSoftColliders::CollideFF_DD docollide;
+ docollide.mrg = 2*getCollisionShape()->getMargin();
+ docollide.psb[0] = this;
+ docollide.psb[1] = psb;
+ if (this->m_tetras.size() > 0)
+ docollide.useFaceNormal = true;
+ else
+ docollide.useFaceNormal = false;
+ /* psb0 faces vs psb0 faces */
+ calculateNormalCone(this->m_fdbvnt);
+ this->m_fdbvt.selfCollideT(m_fdbvnt,docollide);
}
}
}
@@ -3837,6 +4197,58 @@ void btSoftBody::defaultCollisionHandler(btSoftBody* psb)
}
}
+void btSoftBody::geometricCollisionHandler(btSoftBody* psb)
+{
+ if (psb->isActive() || this->isActive())
+ {
+ if (this != psb)
+ {
+ btSoftColliders::CollideCCD docollide;
+ /* common */
+ docollide.mrg = SAFE_EPSILON; // for rounding error instead of actual margin
+ docollide.dt = psb->m_sst.sdt;
+ /* psb0 nodes vs psb1 faces */
+ if (psb->m_tetras.size() > 0)
+ docollide.useFaceNormal = true;
+ else
+ docollide.useFaceNormal = false;
+ docollide.psb[0] = this;
+ docollide.psb[1] = psb;
+ docollide.psb[0]->m_ndbvt.collideTT(docollide.psb[0]->m_ndbvt.m_root,
+ docollide.psb[1]->m_fdbvt.m_root,
+ docollide);
+ /* psb1 nodes vs psb0 faces */
+ if (this->m_tetras.size() > 0)
+ docollide.useFaceNormal = true;
+ else
+ docollide.useFaceNormal = false;
+ docollide.psb[0] = psb;
+ docollide.psb[1] = this;
+ docollide.psb[0]->m_ndbvt.collideTT(docollide.psb[0]->m_ndbvt.m_root,
+ docollide.psb[1]->m_fdbvt.m_root,
+ docollide);
+ }
+ else
+ {
+ if (psb->useSelfCollision())
+ {
+ btSoftColliders::CollideCCD docollide;
+ docollide.mrg = SAFE_EPSILON;
+ docollide.psb[0] = this;
+ docollide.psb[1] = psb;
+ docollide.dt = psb->m_sst.sdt;
+ if (this->m_tetras.size() > 0)
+ docollide.useFaceNormal = true;
+ else
+ docollide.useFaceNormal = false;
+ /* psb0 faces vs psb0 faces */
+ calculateNormalCone(this->m_fdbvnt); // should compute this outside of this scope
+ this->m_fdbvt.selfCollideT(m_fdbvnt,docollide);
+ }
+ }
+ }
+}
+
void btSoftBody::setWindVelocity(const btVector3& velocity)
{
m_windVelocity = velocity;
diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBody.h b/thirdparty/bullet/BulletSoftBody/btSoftBody.h
index 2b048c1118..6a55eccbd2 100644
--- a/thirdparty/bullet/BulletSoftBody/btSoftBody.h
+++ b/thirdparty/bullet/BulletSoftBody/btSoftBody.h
@@ -35,6 +35,8 @@ subject to the following restrictions:
//#else
#define btSoftBodyData btSoftBodyFloatData
#define btSoftBodyDataName "btSoftBodyFloatData"
+static const btScalar OVERLAP_REDUCTION_FACTOR = 0.1;
+static unsigned long seed = 243703;
//#endif //BT_USE_DOUBLE_PRECISION
class btBroadphaseInterface;
@@ -161,14 +163,18 @@ public:
RVSmask = 0x000f, ///Rigid versus soft mask
SDF_RS = 0x0001, ///SDF based rigid vs soft
CL_RS = 0x0002, ///Cluster vs convex rigid vs soft
- SDF_RD = 0x0003, ///DF based rigid vs deformable
- SDF_RDF = 0x0004, ///DF based rigid vs deformable faces
+ SDF_RD = 0x0004, ///rigid vs deformable
- SVSmask = 0x00F0, ///Rigid versus soft mask
+ SVSmask = 0x00f0, ///Rigid versus soft mask
VF_SS = 0x0010, ///Vertex vs face soft vs soft handling
CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling
CL_SELF = 0x0040, ///Cluster soft body self collision
- VF_DD = 0x0050, ///Vertex vs face soft vs soft handling
+ VF_DD = 0x0080, ///Vertex vs face soft vs soft handling
+
+ RVDFmask = 0x0f00, /// Rigid versus deformable face mask
+ SDF_RDF = 0x0100, /// GJK based Rigid vs. deformable face
+ SDF_MDF = 0x0200, /// GJK based Multibody vs. deformable face
+ SDF_RDN = 0x0400, /// SDF based Rigid vs. deformable node
/* presets */
Default = SDF_RS,
END
@@ -257,13 +263,13 @@ public:
btVector3 m_x; // Position
btVector3 m_q; // Previous step position/Test position
btVector3 m_v; // Velocity
- btVector3 m_vsplit; // Temporary Velocity in addintion to velocity used in split impulse
btVector3 m_vn; // Previous step velocity
btVector3 m_f; // Force accumulator
btVector3 m_n; // Normal
btScalar m_im; // 1/mass
btScalar m_area; // Area
btDbvtNode* m_leaf; // Leaf data
+ btScalar m_penetration; // depth of penetration
int m_battach : 1; // Attached
int index;
};
@@ -289,6 +295,7 @@ public:
btScalar m_ra; // Rest area
btDbvtNode* m_leaf; // Leaf data
btVector4 m_pcontact; // barycentric weights of the persistent contact
+ btVector3 m_n0, m_n1, m_vn;
int m_index;
};
/* Tetra */
@@ -717,6 +724,15 @@ public:
/* SolverState */
struct SolverState
{
+ //if you add new variables, always initialize them!
+ SolverState()
+ :sdt(0),
+ isdt(0),
+ velmrg(0),
+ radmrg(0),
+ updmrg(0)
+ {
+ }
btScalar sdt; // dt*timescale
btScalar isdt; // 1/sdt
btScalar velmrg; // velocity margin
@@ -796,22 +812,24 @@ public:
bool m_bUpdateRtCst; // Update runtime constants
btDbvt m_ndbvt; // Nodes tree
btDbvt m_fdbvt; // Faces tree
+ btDbvntNode* m_fdbvnt; // Faces tree with normals
btDbvt m_cdbvt; // Clusters tree
tClusterArray m_clusters; // Clusters
- btScalar m_dampingCoefficient; // Damping Coefficient
- btScalar m_sleepingThreshold;
- btScalar m_maxSpeedSquared;
- bool m_useFaceContact;
- btAlignedObjectArray<btVector3> m_quads; // quadrature points for collision detection
-
- btAlignedObjectArray<btVector4> m_renderNodesInterpolationWeights;
- btAlignedObjectArray<btAlignedObjectArray<const btSoftBody::Node*> > m_renderNodesParents;
- bool m_useSelfCollision;
+ btScalar m_dampingCoefficient; // Damping Coefficient
+ btScalar m_sleepingThreshold;
+ btScalar m_maxSpeedSquared;
+ btAlignedObjectArray<btVector3> m_quads; // quadrature points for collision detection
+ btScalar m_repulsionStiffness;
+ btAlignedObjectArray<btVector3> m_X; // initial positions
+
+ btAlignedObjectArray<btVector4> m_renderNodesInterpolationWeights;
+ btAlignedObjectArray<btAlignedObjectArray<const btSoftBody::Node*> > m_renderNodesParents;
+ btAlignedObjectArray<btScalar> m_z; // vertical distance used in extrapolation
+ bool m_useSelfCollision;
+ bool m_softSoftCollision;
btAlignedObjectArray<bool> m_clusterConnectivity; //cluster connectivity, for self-collision
- btTransform m_initialWorldTransform;
-
btVector3 m_windVelocity;
btScalar m_restLengthScale;
@@ -843,11 +861,6 @@ public:
{
m_dampingCoefficient = damping_coeff;
}
-
- void setUseFaceContact(bool useFaceContact)
- {
- m_useFaceContact = false;
- }
///@todo: avoid internal softbody shape hack and move collision code to collision library
virtual void setCollisionShape(btCollisionShape* collisionShape)
@@ -957,6 +970,16 @@ public:
void setVolumeMass(btScalar mass);
/* Set volume density (using tetrahedrons) */
void setVolumeDensity(btScalar density);
+ /* Get the linear velocity of the center of mass */
+ btVector3 getLinearVelocity();
+ /* Set the linear velocity of the center of mass */
+ void setLinearVelocity(const btVector3& linVel);
+ /* Set the angular velocity of the center of mass */
+ void setAngularVelocity(const btVector3& angVel);
+ /* Get best fit rigid transform */
+ btTransform getRigidTransform();
+ /* Transform to given pose */
+ void transformTo(const btTransform& trs);
/* Transform */
void transform(const btTransform& trs);
/* Translate */
@@ -1023,6 +1046,11 @@ public:
bool rayTest(const btVector3& rayFrom,
const btVector3& rayTo,
sRayCast& results);
+ bool rayFaceTest(const btVector3& rayFrom,
+ const btVector3& rayTo,
+ sRayCast& results);
+ int rayFaceTest(const btVector3& rayFrom, const btVector3& rayTo,
+ btScalar& mint, int& index) const;
/* Solver presets */
void setSolver(eSolverPresets::_ preset);
/* predictMotion */
@@ -1120,6 +1148,7 @@ public:
int rayTest(const btVector3& rayFrom, const btVector3& rayTo,
btScalar& mint, eFeature::_& feature, int& index, bool bcountonly) const;
void initializeFaceTree();
+ void rebuildNodeTree();
btVector3 evaluateCom() const;
bool checkDeformableContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const;
bool checkDeformableFaceContact(const btCollisionObjectWrapper* colObjWrap, Face& f, btVector3& contact_point, btVector3& bary, btScalar margin, btSoftBody::sCti& cti, bool predict = false) const;
@@ -1152,7 +1181,180 @@ public:
static void VSolve_Links(btSoftBody* psb, btScalar kst);
static psolver_t getSolver(ePSolver::_ solver);
static vsolver_t getSolver(eVSolver::_ solver);
+ void geometricCollisionHandler(btSoftBody* psb);
+#define SAFE_EPSILON SIMD_EPSILON*100.0
+ void updateNode(btDbvtNode* node, bool use_velocity, bool margin)
+ {
+ if (node->isleaf())
+ {
+ btSoftBody::Node* n = (btSoftBody::Node*)(node->data);
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol;
+ btScalar pad = margin ? m_sst.radmrg : SAFE_EPSILON; // use user defined margin or margin for floating point precision
+ if (use_velocity)
+ {
+ btVector3 points[2] = {n->m_x, n->m_x + m_sst.sdt * n->m_v};
+ vol = btDbvtVolume::FromPoints(points, 2);
+ vol.Expand(btVector3(pad, pad, pad));
+ }
+ else
+ {
+ vol = btDbvtVolume::FromCR(n->m_x, pad);
+ }
+ node->volume = vol;
+ return;
+ }
+ else
+ {
+ updateNode(node->childs[0], use_velocity, margin);
+ updateNode(node->childs[1], use_velocity, margin);
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol;
+ Merge(node->childs[0]->volume, node->childs[1]->volume, vol);
+ node->volume = vol;
+ }
+ }
+
+ void updateNodeTree(bool use_velocity, bool margin)
+ {
+ if (m_ndbvt.m_root)
+ updateNode(m_ndbvt.m_root, use_velocity, margin);
+ }
+
+ template <class DBVTNODE> // btDbvtNode or btDbvntNode
+ void updateFace(DBVTNODE* node, bool use_velocity, bool margin)
+ {
+ if (node->isleaf())
+ {
+ btSoftBody::Face* f = (btSoftBody::Face*)(node->data);
+ btScalar pad = margin ? m_sst.radmrg : SAFE_EPSILON; // use user defined margin or margin for floating point precision
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol;
+ if (use_velocity)
+ {
+ btVector3 points[6] = {f->m_n[0]->m_x, f->m_n[0]->m_x + m_sst.sdt * f->m_n[0]->m_v,
+ f->m_n[1]->m_x, f->m_n[1]->m_x + m_sst.sdt * f->m_n[1]->m_v,
+ f->m_n[2]->m_x, f->m_n[2]->m_x + m_sst.sdt * f->m_n[2]->m_v};
+ vol = btDbvtVolume::FromPoints(points, 6);
+ }
+ else
+ {
+ btVector3 points[3] = {f->m_n[0]->m_x,
+ f->m_n[1]->m_x,
+ f->m_n[2]->m_x};
+ vol = btDbvtVolume::FromPoints(points, 3);
+ }
+ vol.Expand(btVector3(pad, pad, pad));
+ node->volume = vol;
+ return;
+ }
+ else
+ {
+ updateFace(node->childs[0], use_velocity, margin);
+ updateFace(node->childs[1], use_velocity, margin);
+ ATTRIBUTE_ALIGNED16(btDbvtVolume) vol;
+ Merge(node->childs[0]->volume, node->childs[1]->volume, vol);
+ node->volume = vol;
+ }
+ }
+ void updateFaceTree(bool use_velocity, bool margin)
+ {
+ if (m_fdbvt.m_root)
+ updateFace(m_fdbvt.m_root, use_velocity, margin);
+ if (m_fdbvnt)
+ updateFace(m_fdbvnt, use_velocity, margin);
+ }
+
+ template <typename T>
+ static inline T BaryEval(const T& a,
+ const T& b,
+ const T& c,
+ const btVector3& coord)
+ {
+ return (a * coord.x() + b * coord.y() + c * coord.z());
+ }
+ void applyRepulsionForce(btScalar timeStep, bool applySpringForce)
+ {
+ btAlignedObjectArray<int> indices;
+ {
+ // randomize the order of repulsive force
+ indices.resize(m_faceNodeContacts.size());
+ for (int i = 0; i < m_faceNodeContacts.size(); ++i)
+ indices[i] = i;
+#define NEXTRAND (seed = (1664525L * seed + 1013904223L) & 0xffffffff)
+ int i, ni;
+
+ for (i = 0, ni = indices.size(); i < ni; ++i)
+ {
+ btSwap(indices[i], indices[NEXTRAND % ni]);
+ }
+ }
+ for (int k = 0; k < m_faceNodeContacts.size(); ++k)
+ {
+ int i = indices[k];
+ btSoftBody::DeformableFaceNodeContact& c = m_faceNodeContacts[i];
+ btSoftBody::Node* node = c.m_node;
+ btSoftBody::Face* face = c.m_face;
+ const btVector3& w = c.m_bary;
+ const btVector3& n = c.m_normal;
+ btVector3 l = node->m_x - BaryEval(face->m_n[0]->m_x, face->m_n[1]->m_x, face->m_n[2]->m_x, w);
+ btScalar d = c.m_margin - n.dot(l);
+ d = btMax(btScalar(0),d);
+
+ const btVector3& va = node->m_v;
+ btVector3 vb = BaryEval(face->m_n[0]->m_v, face->m_n[1]->m_v, face->m_n[2]->m_v, w);
+ btVector3 vr = va - vb;
+ const btScalar vn = btDot(vr, n); // dn < 0 <==> opposing
+ if (vn > OVERLAP_REDUCTION_FACTOR * d / timeStep)
+ continue;
+ btVector3 vt = vr - vn*n;
+ btScalar I = 0;
+ btScalar mass = node->m_im == 0 ? 0 : btScalar(1)/node->m_im;
+ if (applySpringForce)
+ I = -btMin(m_repulsionStiffness * timeStep * d, mass * (OVERLAP_REDUCTION_FACTOR * d / timeStep - vn));
+ if (vn < 0)
+ I += 0.5 * mass * vn;
+ btScalar face_penetration = 0, node_penetration = node->m_penetration;
+ for (int i = 0; i < 3; ++i)
+ face_penetration = btMax(face_penetration, face->m_n[i]->m_penetration);
+ btScalar I_tilde = .5 *I /(1.0+w.length2());
+
+// double the impulse if node or face is constrained.
+ if (face_penetration > 0 || node_penetration > 0)
+ I_tilde *= 2.0;
+ if (face_penetration <= node_penetration)
+ {
+ for (int j = 0; j < 3; ++j)
+ face->m_n[j]->m_v += w[j]*n*I_tilde*node->m_im;
+ }
+ if (face_penetration >= node_penetration)
+ {
+ node->m_v -= I_tilde*node->m_im*n;
+ }
+
+ // apply frictional impulse
+ btScalar vt_norm = vt.safeNorm();
+ if (vt_norm > SIMD_EPSILON)
+ {
+ btScalar delta_vn = -2 * I * node->m_im;
+ btScalar mu = c.m_friction;
+ btScalar vt_new = btMax(btScalar(1) - mu * delta_vn / (vt_norm + SIMD_EPSILON), btScalar(0))*vt_norm;
+ I = 0.5 * mass * (vt_norm-vt_new);
+ vt.safeNormalize();
+ I_tilde = .5 *I /(1.0+w.length2());
+// double the impulse if node or face is constrained.
+// if (face_penetration > 0 || node_penetration > 0)
+// I_tilde *= 2.0;
+ if (face_penetration <= node_penetration)
+ {
+ for (int j = 0; j < 3; ++j)
+ face->m_n[j]->m_v += w[j] * vt * I_tilde * (face->m_n[j])->m_im;
+ }
+ if (face_penetration >= node_penetration)
+ {
+ node->m_v -= I_tilde * node->m_im * vt;
+ }
+ }
+ }
+ }
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.cpp b/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.cpp
index 649d6f58cf..c1a87c7d57 100644
--- a/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.cpp
+++ b/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.cpp
@@ -1300,13 +1300,23 @@ btSoftBody* btSoftBodyHelpers::CreateFromVtkFile(btSoftBodyWorldInfo& worldInfo,
}
else if (reading_tets)
{
+ int d;
+ ss >> d;
+ if (d != 4)
+ {
+ printf("Load deformable failed: Only Tetrahedra are supported in VTK file.\n");
+ fs.close();
+ return 0;
+ }
ss.ignore(128, ' '); // ignore "4"
Index tet;
tet.resize(4);
for (size_t i = 0; i < 4; i++)
{
ss >> tet[i];
+ printf("%d ", tet[i]);
}
+ printf("\n");
indices[indices_count++] = tet;
}
}
@@ -1500,10 +1510,27 @@ void btSoftBodyHelpers::getBarycentricWeights(const btVector3& a, const btVector
bary = btVector4(va6*v6, vb6*v6, vc6*v6, vd6*v6);
}
+// Given a simplex with vertices a,b,c, find the barycentric weights of p in this simplex. bary[3] = 0.
+void btSoftBodyHelpers::getBarycentricWeights(const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& p, btVector4& bary)
+{
+ btVector3 v0 = b - a, v1 = c - a, v2 = p - a;
+ btScalar d00 = btDot(v0, v0);
+ btScalar d01 = btDot(v0, v1);
+ btScalar d11 = btDot(v1, v1);
+ btScalar d20 = btDot(v2, v0);
+ btScalar d21 = btDot(v2, v1);
+ btScalar invDenom = 1.0 / (d00 * d11 - d01 * d01);
+ bary[1] = (d11 * d20 - d01 * d21) * invDenom;
+ bary[2] = (d00 * d21 - d01 * d20) * invDenom;
+ bary[0] = 1.0 - bary[1] - bary[2];
+ bary[3] = 0;
+}
+
// Iterate through all render nodes to find the simulation tetrahedron that contains the render node and record the barycentric weights
// If the node is not inside any tetrahedron, assign it to the tetrahedron in which the node has the least negative barycentric weight
void btSoftBodyHelpers::interpolateBarycentricWeights(btSoftBody* psb)
{
+ psb->m_z.resize(0);
psb->m_renderNodesInterpolationWeights.resize(psb->m_renderNodes.size());
psb->m_renderNodesParents.resize(psb->m_renderNodes.size());
for (int i = 0; i < psb->m_renderNodes.size(); ++i)
@@ -1513,7 +1540,6 @@ void btSoftBodyHelpers::interpolateBarycentricWeights(btSoftBody* psb)
btVector4 optimal_bary;
btScalar min_bary_weight = -1e3;
btAlignedObjectArray<const btSoftBody::Node*> optimal_parents;
- bool found = false;
for (int j = 0; j < psb->m_tetras.size(); ++j)
{
const btSoftBody::Tetra& t = psb->m_tetras[j];
@@ -1544,3 +1570,55 @@ void btSoftBodyHelpers::interpolateBarycentricWeights(btSoftBody* psb)
psb->m_renderNodesParents[i] = optimal_parents;
}
}
+
+
+// Iterate through all render nodes to find the simulation triangle that's closest to the node in the barycentric sense.
+void btSoftBodyHelpers::extrapolateBarycentricWeights(btSoftBody* psb)
+{
+ psb->m_renderNodesInterpolationWeights.resize(psb->m_renderNodes.size());
+ psb->m_renderNodesParents.resize(psb->m_renderNodes.size());
+ psb->m_z.resize(psb->m_renderNodes.size());
+ for (int i = 0; i < psb->m_renderNodes.size(); ++i)
+ {
+ const btVector3& p = psb->m_renderNodes[i].m_x;
+ btVector4 bary;
+ btVector4 optimal_bary;
+ btScalar min_bary_weight = -SIMD_INFINITY;
+ btAlignedObjectArray<const btSoftBody::Node*> optimal_parents;
+ btScalar dist = 0, optimal_dist = 0;
+ for (int j = 0; j < psb->m_faces.size(); ++j)
+ {
+ const btSoftBody::Face& f = psb->m_faces[j];
+ btVector3 n = btCross(f.m_n[1]->m_x - f.m_n[0]->m_x, f.m_n[2]->m_x - f.m_n[0]->m_x);
+ btVector3 unit_n = n.normalized();
+ dist = (p-f.m_n[0]->m_x).dot(unit_n);
+ btVector3 proj_p = p - dist*unit_n;
+ getBarycentricWeights(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x, proj_p, bary);
+ btScalar new_min_bary_weight = bary[0];
+ for (int k = 1; k < 3; ++k)
+ {
+ new_min_bary_weight = btMin(new_min_bary_weight, bary[k]);
+ }
+
+ // p is out of the current best triangle, we found a traingle that's better
+ bool better_than_closest_outisde = (new_min_bary_weight > min_bary_weight && min_bary_weight<0.);
+ // p is inside of the current best triangle, we found a triangle that's better
+ bool better_than_best_inside = (new_min_bary_weight>=0 && min_bary_weight>=0 && btFabs(dist)<btFabs(optimal_dist));
+
+ if (better_than_closest_outisde || better_than_best_inside)
+ {
+ btAlignedObjectArray<const btSoftBody::Node*> parents;
+ parents.push_back(f.m_n[0]);
+ parents.push_back(f.m_n[1]);
+ parents.push_back(f.m_n[2]);
+ optimal_parents = parents;
+ optimal_bary = bary;
+ optimal_dist = dist;
+ min_bary_weight = new_min_bary_weight;
+ }
+ }
+ psb->m_renderNodesInterpolationWeights[i] = optimal_bary;
+ psb->m_renderNodesParents[i] = optimal_parents;
+ psb->m_z[i] = optimal_dist;
+ }
+}
diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.h b/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.h
index b20f2f6d62..abe1870890 100644
--- a/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.h
+++ b/thirdparty/bullet/BulletSoftBody/btSoftBodyHelpers.h
@@ -148,8 +148,12 @@ struct btSoftBodyHelpers
static void getBarycentricWeights(const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, const btVector3& p, btVector4& bary);
+ static void getBarycentricWeights(const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& p, btVector4& bary);
+
static void interpolateBarycentricWeights(btSoftBody* psb);
+ static void extrapolateBarycentricWeights(btSoftBody* psb);
+
static void generateBoundaryFaces(btSoftBody* psb);
static void duplicateFaces(const char* filename, const btSoftBody* psb);
diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBodyInternals.h b/thirdparty/bullet/BulletSoftBody/btSoftBodyInternals.h
index cde4746d58..b9ebc95b6b 100644
--- a/thirdparty/bullet/BulletSoftBody/btSoftBodyInternals.h
+++ b/thirdparty/bullet/BulletSoftBody/btSoftBodyInternals.h
@@ -18,7 +18,6 @@ subject to the following restrictions:
#define _BT_SOFT_BODY_INTERNALS_H
#include "btSoftBody.h"
-
#include "LinearMath/btQuickprof.h"
#include "LinearMath/btPolarDecomposition.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
@@ -29,9 +28,10 @@ subject to the following restrictions:
#include "BulletDynamics/Featherstone/btMultiBodyConstraint.h"
#include <string.h> //for memset
#include <cmath>
+#include "poly34.h"
// Given a multibody link, a contact point and a contact direction, fill in the jacobian data needed to calculate the velocity change given an impulse in the contact direction
-static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol,
+static SIMD_FORCE_INLINE void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol,
btMultiBodyJacobianData& jacobianData,
const btVector3& contact_point,
const btVector3& dir)
@@ -44,7 +44,7 @@ static void findJacobian(const btMultiBodyLinkCollider* multibodyLinkCol,
multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, contact_point, dir, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m);
multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], &jacobianData.m_deltaVelocitiesUnitImpulse[0], jacobianData.scratch_r, jacobianData.scratch_v);
}
-static btVector3 generateUnitOrthogonalVector(const btVector3& u)
+static SIMD_FORCE_INLINE btVector3 generateUnitOrthogonalVector(const btVector3& u)
{
btScalar ux = u.getX();
btScalar uy = u.getY();
@@ -62,6 +62,571 @@ static btVector3 generateUnitOrthogonalVector(const btVector3& u)
v.normalize();
return v;
}
+
+static SIMD_FORCE_INLINE bool proximityTest(const btVector3& x1, const btVector3& x2, const btVector3& x3, const btVector3& x4, const btVector3& normal, const btScalar& mrg, btVector3& bary)
+{
+ btVector3 x43 = x4-x3;
+ if (std::abs(x43.dot(normal)) > mrg)
+ return false;
+ btVector3 x13 = x1-x3;
+ btVector3 x23 = x2-x3;
+ btScalar a11 = x13.length2();
+ btScalar a22 = x23.length2();
+ btScalar a12 = x13.dot(x23);
+ btScalar b1 = x13.dot(x43);
+ btScalar b2 = x23.dot(x43);
+ btScalar det = a11*a22 - a12*a12;
+ if (det < SIMD_EPSILON)
+ return false;
+ btScalar w1 = (b1*a22-b2*a12)/det;
+ btScalar w2 = (b2*a11-b1*a12)/det;
+ btScalar w3 = 1-w1-w2;
+ btScalar delta = mrg / std::sqrt(0.5*std::abs(x13.cross(x23).safeNorm()));
+ bary = btVector3(w1,w2,w3);
+ for (int i = 0; i < 3; ++i)
+ {
+ if (bary[i] < -delta || bary[i] > 1+delta)
+ return false;
+ }
+ return true;
+}
+static const int KDOP_COUNT = 13;
+static btVector3 dop[KDOP_COUNT]={btVector3(1,0,0),
+ btVector3(0,1,0),
+ btVector3(0,0,1),
+ btVector3(1,1,0),
+ btVector3(1,0,1),
+ btVector3(0,1,1),
+ btVector3(1,-1,0),
+ btVector3(1,0,-1),
+ btVector3(0,1,-1),
+ btVector3(1,1,1),
+ btVector3(1,-1,1),
+ btVector3(1,1,-1),
+ btVector3(1,-1,-1)
+};
+
+static inline int getSign(const btVector3& n, const btVector3& x)
+{
+ btScalar d = n.dot(x);
+ if (d>SIMD_EPSILON)
+ return 1;
+ if (d<-SIMD_EPSILON)
+ return -1;
+ return 0;
+}
+
+static SIMD_FORCE_INLINE bool hasSeparatingPlane(const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt)
+{
+ btVector3 hex[6] = {face->m_n[0]->m_x - node->m_x,
+ face->m_n[1]->m_x - node->m_x,
+ face->m_n[2]->m_x - node->m_x,
+ face->m_n[0]->m_x + dt*face->m_n[0]->m_v - node->m_x,
+ face->m_n[1]->m_x + dt*face->m_n[1]->m_v - node->m_x,
+ face->m_n[2]->m_x + dt*face->m_n[2]->m_v - node->m_x
+ };
+ btVector3 segment = dt*node->m_v;
+ for (int i = 0; i < KDOP_COUNT; ++i)
+ {
+ int s = getSign(dop[i], segment);
+ int j = 0;
+ for (; j < 6; ++j)
+ {
+ if (getSign(dop[i], hex[j]) == s)
+ break;
+ }
+ if (j == 6)
+ return true;
+ }
+ return false;
+}
+
+static SIMD_FORCE_INLINE bool nearZero(const btScalar& a)
+{
+ return (a>-SAFE_EPSILON && a<SAFE_EPSILON);
+}
+static SIMD_FORCE_INLINE bool sameSign(const btScalar& a, const btScalar& b)
+{
+ return (nearZero(a) || nearZero(b) || (a>SAFE_EPSILON && b>SAFE_EPSILON) || (a<-SAFE_EPSILON && b<-SAFE_EPSILON));
+}
+static SIMD_FORCE_INLINE bool diffSign(const btScalar& a, const btScalar& b)
+{
+ return !sameSign(a, b);
+}
+inline btScalar evaluateBezier2(const btScalar &p0, const btScalar &p1, const btScalar &p2, const btScalar &t, const btScalar &s)
+{
+ btScalar s2 = s*s;
+ btScalar t2 = t*t;
+
+ return p0*s2+p1*btScalar(2.0)*s*t+p2*t2;
+}
+inline btScalar evaluateBezier(const btScalar &p0, const btScalar &p1, const btScalar &p2, const btScalar &p3, const btScalar &t, const btScalar &s)
+{
+ btScalar s2 = s*s;
+ btScalar s3 = s2*s;
+ btScalar t2 = t*t;
+ btScalar t3 = t2*t;
+
+ return p0*s3+p1*btScalar(3.0)*s2*t+p2*btScalar(3.0)*s*t2+p3*t3;
+}
+static SIMD_FORCE_INLINE bool getSigns(bool type_c, const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& t0, const btScalar& t1, btScalar &lt0, btScalar &lt1)
+{
+ if (sameSign(t0, t1)) {
+ lt0 = t0;
+ lt1 = t0;
+ return true;
+ }
+
+ if (type_c || diffSign(k0, k3)) {
+ btScalar ft = evaluateBezier(k0, k1, k2, k3, t0, -t1);
+ if (t0<-0)
+ ft = -ft;
+
+ if (sameSign(ft, k0)) {
+ lt0 = t1;
+ lt1 = t1;
+ }
+ else {
+ lt0 = t0;
+ lt1 = t0;
+ }
+ return true;
+ }
+
+ if (!type_c) {
+ btScalar ft = evaluateBezier(k0, k1, k2, k3, t0, -t1);
+ if (t0<-0)
+ ft = -ft;
+
+ if (diffSign(ft, k0)) {
+ lt0 = t0;
+ lt1 = t1;
+ return true;
+ }
+
+ btScalar fk = evaluateBezier2(k1-k0, k2-k1, k3-k2, t0, -t1);
+
+ if (sameSign(fk, k1-k0))
+ lt0 = lt1 = t1;
+ else
+ lt0 = lt1 = t0;
+
+ return true;
+ }
+ return false;
+}
+
+static SIMD_FORCE_INLINE void getBernsteinCoeff(const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt, btScalar& k0, btScalar& k1, btScalar& k2, btScalar& k3)
+{
+ const btVector3& n0 = face->m_n0;
+ const btVector3& n1 = face->m_n1;
+ btVector3 n_hat = n0 + n1 - face->m_vn;
+ btVector3 p0ma0 = node->m_x - face->m_n[0]->m_x;
+ btVector3 p1ma1 = node->m_q - face->m_n[0]->m_q;
+ k0 = (p0ma0).dot(n0) * 3.0;
+ k1 = (p0ma0).dot(n_hat) + (p1ma1).dot(n0);
+ k2 = (p1ma1).dot(n_hat) + (p0ma0).dot(n1);
+ k3 = (p1ma1).dot(n1) * 3.0;
+}
+
+static SIMD_FORCE_INLINE void polyDecomposition(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& j0, const btScalar& j1, const btScalar& j2, btScalar& u0, btScalar& u1, btScalar& v0, btScalar& v1)
+{
+ btScalar denom = 4.0 * (j1-j2) * (j1-j0) + (j2-j0) * (j2-j0);
+ u0 = (2.0*(j1-j2)*(3.0*k1-2.0*k0-k3) - (j0-j2)*(3.0*k2-2.0*k3-k0)) / denom;
+ u1 = (2.0*(j1-j0)*(3.0*k2-2.0*k3-k0) - (j2-j0)*(3.0*k1-2.0*k0-k3)) / denom;
+ v0 = k0-u0*j0;
+ v1 = k3-u1*j2;
+}
+
+static SIMD_FORCE_INLINE bool rootFindingLemma(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3)
+{
+ btScalar u0, u1, v0, v1;
+ btScalar j0 = 3.0*(k1-k0);
+ btScalar j1 = 3.0*(k2-k1);
+ btScalar j2 = 3.0*(k3-k2);
+ polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1);
+ if (sameSign(v0, v1))
+ {
+ btScalar Ypa = j0*(1.0-v0)*(1.0-v0) + 2.0*j1*v0*(1.0-v0) + j2*v0*v0; // Y'(v0)
+ if (sameSign(Ypa, j0))
+ {
+ return (diffSign(k0,v1));
+ }
+ }
+ return diffSign(k0,v0);
+}
+
+static SIMD_FORCE_INLINE void getJs(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btSoftBody::Node* a, const btSoftBody::Node* b, const btSoftBody::Node* c, const btSoftBody::Node* p, const btScalar& dt, btScalar& j0, btScalar& j1, btScalar& j2)
+{
+ const btVector3& a0 = a->m_x;
+ const btVector3& b0 = b->m_x;
+ const btVector3& c0 = c->m_x;
+ const btVector3& va = a->m_v;
+ const btVector3& vb = b->m_v;
+ const btVector3& vc = c->m_v;
+ const btVector3 a1 = a0 + dt*va;
+ const btVector3 b1 = b0 + dt*vb;
+ const btVector3 c1 = c0 + dt*vc;
+ btVector3 n0 = (b0-a0).cross(c0-a0);
+ btVector3 n1 = (b1-a1).cross(c1-a1);
+ btVector3 n_hat = n0+n1 - dt*dt*(vb-va).cross(vc-va);
+ const btVector3& p0 = p->m_x;
+ const btVector3& vp = p->m_v;
+ btVector3 p1 = p0 + dt*vp;
+ btVector3 m0 = (b0-p0).cross(c0-p0);
+ btVector3 m1 = (b1-p1).cross(c1-p1);
+ btVector3 m_hat = m0+m1 - dt*dt*(vb-vp).cross(vc-vp);
+ btScalar l0 = m0.dot(n0);
+ btScalar l1 = 0.25 * (m0.dot(n_hat) + m_hat.dot(n0));
+ btScalar l2 = btScalar(1)/btScalar(6)*(m0.dot(n1) + m_hat.dot(n_hat) + m1.dot(n0));
+ btScalar l3 = 0.25 * (m_hat.dot(n1) + m1.dot(n_hat));
+ btScalar l4 = m1.dot(n1);
+
+ btScalar k1p = 0.25 * k0 + 0.75 * k1;
+ btScalar k2p = 0.5 * k1 + 0.5 * k2;
+ btScalar k3p = 0.75 * k2 + 0.25 * k3;
+
+ btScalar s0 = (l1 * k0 - l0 * k1p)*4.0;
+ btScalar s1 = (l2 * k0 - l0 * k2p)*2.0;
+ btScalar s2 = (l3 * k0 - l0 * k3p)*btScalar(4)/btScalar(3);
+ btScalar s3 = l4 * k0 - l0 * k3;
+
+ j0 = (s1*k0 - s0*k1) * 3.0;
+ j1 = (s2*k0 - s0*k2) * 1.5;
+ j2 = (s3*k0 - s0*k3);
+}
+
+static SIMD_FORCE_INLINE bool signDetermination1Internal(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& u0, const btScalar& u1, const btScalar& v0, const btScalar& v1)
+{
+ btScalar Yu0 = k0*(1.0-u0)*(1.0-u0)*(1.0-u0) + 3.0*k1*u0*(1.0-u0)*(1.0-u0) + 3.0*k2*u0*u0*(1.0-u0) + k3*u0*u0*u0; // Y(u0)
+ btScalar Yv0 = k0*(1.0-v0)*(1.0-v0)*(1.0-v0) + 3.0*k1*v0*(1.0-v0)*(1.0-v0) + 3.0*k2*v0*v0*(1.0-v0) + k3*v0*v0*v0; // Y(v0)
+
+ btScalar sign_Ytp = (u0 > u1) ? Yu0 : -Yu0;
+ btScalar L = sameSign(sign_Ytp, k0) ? u1 : u0;
+ sign_Ytp = (v0 > v1) ? Yv0 : -Yv0;
+ btScalar K = (sameSign(sign_Ytp,k0)) ? v1 : v0;
+ return diffSign(L,K);
+}
+
+static SIMD_FORCE_INLINE bool signDetermination2Internal(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& j0, const btScalar& j1, const btScalar& j2, const btScalar& u0, const btScalar& u1, const btScalar& v0, const btScalar& v1)
+{
+ btScalar Yu0 = k0*(1.0-u0)*(1.0-u0)*(1.0-u0) + 3.0*k1*u0*(1.0-u0)*(1.0-u0) + 3.0*k2*u0*u0*(1.0-u0) + k3*u0*u0*u0; // Y(u0)
+ btScalar sign_Ytp = (u0 > u1) ? Yu0 : -Yu0, L1, L2;
+ if (diffSign(sign_Ytp,k0))
+ {
+ L1 = u0;
+ L2 = u1;
+ }
+ else
+ {
+ btScalar Yp_u0 = j0*(1.0-u0)*(1.0-u0) + 2.0*j1*(1.0-u0)*u0 + j2*u0*u0;
+ if (sameSign(Yp_u0,j0))
+ {
+ L1 = u1;
+ L2 = u1;
+ }
+ else
+ {
+ L1 = u0;
+ L2 = u0;
+ }
+ }
+ btScalar Yv0 = k0*(1.0-v0)*(1.0-v0)*(1.0-v0) + 3.0*k1*v0*(1.0-v0)*(1.0-v0) + 3.0*k2*v0*v0*(1.0-v0) + k3*v0*v0*v0; // Y(uv0)
+ sign_Ytp = (v0 > v1) ? Yv0 : -Yv0;
+ btScalar K1, K2;
+ if (diffSign(sign_Ytp,k0))
+ {
+ K1 = v0;
+ K2 = v1;
+ }
+ else
+ {
+ btScalar Yp_v0 = j0*(1.0-v0)*(1.0-v0) + 2.0*j1*(1.0-v0)*v0 + j2*v0*v0;
+ if (sameSign(Yp_v0,j0))
+ {
+ K1 = v1;
+ K2 = v1;
+ }
+ else
+ {
+ K1 = v0;
+ K2 = v0;
+ }
+ }
+ return (diffSign(K1, L1) || diffSign(L2, K2));
+}
+
+static SIMD_FORCE_INLINE bool signDetermination1(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt)
+{
+ btScalar j0, j1, j2, u0, u1, v0, v1;
+ // p1
+ getJs(k0,k1,k2,k3,face->m_n[0], face->m_n[1], face->m_n[2], node, dt, j0, j1, j2);
+ if (nearZero(j0+j2-j1*2.0))
+ {
+ btScalar lt0, lt1;
+ getSigns(true, k0, k1, k2, k3, j0, j2, lt0, lt1);
+ if (lt0 < -SAFE_EPSILON)
+ return false;
+ }
+ else
+ {
+ polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1);
+ if (!signDetermination1Internal(k0,k1,k2,k3,u0,u1,v0,v1))
+ return false;
+ }
+ // p2
+ getJs(k0,k1,k2,k3,face->m_n[1], face->m_n[2], face->m_n[0], node, dt, j0, j1, j2);
+ if (nearZero(j0+j2-j1*2.0))
+ {
+ btScalar lt0, lt1;
+ getSigns(true, k0, k1, k2, k3, j0, j2, lt0, lt1);
+ if (lt0 < -SAFE_EPSILON)
+ return false;
+ }
+ else
+ {
+ polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1);
+ if (!signDetermination1Internal(k0,k1,k2,k3,u0,u1,v0,v1))
+ return false;
+ }
+ // p3
+ getJs(k0,k1,k2,k3,face->m_n[2], face->m_n[0], face->m_n[1], node, dt, j0, j1, j2);
+ if (nearZero(j0+j2-j1*2.0))
+ {
+ btScalar lt0, lt1;
+ getSigns(true, k0, k1, k2, k3, j0, j2, lt0, lt1);
+ if (lt0 < -SAFE_EPSILON)
+ return false;
+ }
+ else
+ {
+ polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1);
+ if (!signDetermination1Internal(k0,k1,k2,k3,u0,u1,v0,v1))
+ return false;
+ }
+ return true;
+}
+
+static SIMD_FORCE_INLINE bool signDetermination2(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt)
+{
+ btScalar j0, j1, j2, u0, u1, v0, v1;
+ // p1
+ getJs(k0,k1,k2,k3,face->m_n[0], face->m_n[1], face->m_n[2], node, dt, j0, j1, j2);
+ if (nearZero(j0+j2-j1*2.0))
+ {
+ btScalar lt0, lt1;
+ bool bt0 = true, bt1=true;
+ getSigns(false, k0, k1, k2, k3, j0, j2, lt0, lt1);
+ if (lt0 < -SAFE_EPSILON)
+ bt0 = false;
+ if (lt1 < -SAFE_EPSILON)
+ bt1 = false;
+ if (!bt0 && !bt1)
+ return false;
+ }
+ else
+ {
+ polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1);
+ if (!signDetermination2Internal(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1))
+ return false;
+ }
+ // p2
+ getJs(k0,k1,k2,k3,face->m_n[1], face->m_n[2], face->m_n[0], node, dt, j0, j1, j2);
+ if (nearZero(j0+j2-j1*2.0))
+ {
+ btScalar lt0, lt1;
+ bool bt0=true, bt1=true;
+ getSigns(false, k0, k1, k2, k3, j0, j2, lt0, lt1);
+ if (lt0 < -SAFE_EPSILON)
+ bt0 = false;
+ if (lt1 < -SAFE_EPSILON)
+ bt1 = false;
+ if (!bt0 && !bt1)
+ return false;
+ }
+ else
+ {
+ polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1);
+ if (!signDetermination2Internal(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1))
+ return false;
+ }
+ // p3
+ getJs(k0,k1,k2,k3,face->m_n[2], face->m_n[0], face->m_n[1], node, dt, j0, j1, j2);
+ if (nearZero(j0+j2-j1*2.0))
+ {
+ btScalar lt0, lt1;
+ bool bt0=true, bt1=true;
+ getSigns(false, k0, k1, k2, k3, j0, j2, lt0, lt1);
+ if (lt0 < -SAFE_EPSILON)
+ bt0 = false;
+ if (lt1 < -SAFE_EPSILON)
+ bt1 = false;
+ if (!bt0 && !bt1)
+ return false;
+ }
+ else
+ {
+ polyDecomposition(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1);
+ if (!signDetermination2Internal(k0,k1,k2,k3,j0,j1,j2,u0,u1,v0,v1))
+ return false;
+ }
+ return true;
+}
+
+static SIMD_FORCE_INLINE bool coplanarAndInsideTest(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt)
+{
+ // Coplanar test
+ if (diffSign(k1-k0, k3-k2))
+ {
+ // Case b:
+ if (sameSign(k0, k3) && !rootFindingLemma(k0,k1,k2,k3))
+ return false;
+ // inside test
+ return signDetermination2(k0, k1, k2, k3, face, node, dt);
+ }
+ else
+ {
+ // Case c:
+ if (sameSign(k0, k3))
+ return false;
+ // inside test
+ return signDetermination1(k0, k1, k2, k3, face, node, dt);
+ }
+ return false;
+}
+static SIMD_FORCE_INLINE bool conservativeCulling(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& mrg)
+{
+ if (k0 > mrg && k1 > mrg && k2 > mrg && k3 > mrg)
+ return true;
+ if (k0 < -mrg && k1 < -mrg && k2 < -mrg && k3 < -mrg)
+ return true;
+ return false;
+}
+
+static SIMD_FORCE_INLINE bool bernsteinVFTest(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& mrg, const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt)
+{
+ if (conservativeCulling(k0, k1, k2, k3, mrg))
+ return false;
+ return coplanarAndInsideTest(k0, k1, k2, k3, face, node, dt);
+}
+
+static SIMD_FORCE_INLINE void deCasteljau(const btScalar& k0, const btScalar& k1, const btScalar& k2, const btScalar& k3, const btScalar& t0, btScalar& k10, btScalar& k20, btScalar& k30, btScalar& k21, btScalar& k12)
+{
+ k10 = k0*(1.0-t0) + k1*t0;
+ btScalar k11 = k1*(1.0-t0) + k2*t0;
+ k12 = k2*(1.0-t0) + k3*t0;
+ k20 = k10*(1.0-t0) + k11*t0;
+ k21 = k11*(1.0-t0) + k12*t0;
+ k30 = k20*(1.0-t0) + k21*t0;
+}
+static SIMD_FORCE_INLINE bool bernsteinVFTest(const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt, const btScalar& mrg)
+{
+ btScalar k0, k1, k2, k3;
+ getBernsteinCoeff(face, node, dt, k0, k1, k2, k3);
+ if (conservativeCulling(k0, k1, k2, k3, mrg))
+ return false;
+ return true;
+ if (diffSign(k2-2.0*k1+k0, k3-2.0*k2+k1))
+ {
+ btScalar k10, k20, k30, k21, k12;
+ btScalar t0 = (k2-2.0*k1+k0)/(k0-3.0*k1+3.0*k2-k3);
+ deCasteljau(k0, k1, k2, k3, t0, k10, k20, k30, k21, k12);
+ return bernsteinVFTest(k0, k10, k20, k30, mrg, face, node, dt) || bernsteinVFTest(k30, k21, k12, k3, mrg, face, node, dt);
+ }
+ return coplanarAndInsideTest(k0, k1, k2, k3, face, node, dt);
+}
+
+static SIMD_FORCE_INLINE bool continuousCollisionDetection(const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt, const btScalar& mrg, btVector3& bary)
+{
+ if (hasSeparatingPlane(face, node, dt))
+ return false;
+ btVector3 x21 = face->m_n[1]->m_x - face->m_n[0]->m_x;
+ btVector3 x31 = face->m_n[2]->m_x - face->m_n[0]->m_x;
+ btVector3 x41 = node->m_x - face->m_n[0]->m_x;
+ btVector3 v21 = face->m_n[1]->m_v - face->m_n[0]->m_v;
+ btVector3 v31 = face->m_n[2]->m_v - face->m_n[0]->m_v;
+ btVector3 v41 = node->m_v - face->m_n[0]->m_v;
+ btVector3 a = x21.cross(x31);
+ btVector3 b = x21.cross(v31) + v21.cross(x31);
+ btVector3 c = v21.cross(v31);
+ btVector3 d = x41;
+ btVector3 e = v41;
+ btScalar a0 = a.dot(d);
+ btScalar a1 = a.dot(e) + b.dot(d);
+ btScalar a2 = c.dot(d) + b.dot(e);
+ btScalar a3 = c.dot(e);
+ btScalar eps = SAFE_EPSILON;
+ int num_roots = 0;
+ btScalar roots[3];
+ if (std::abs(a3) < eps)
+ {
+ // cubic term is zero
+ if (std::abs(a2) < eps)
+ {
+ if (std::abs(a1) < eps)
+ {
+ if (std::abs(a0) < eps)
+ {
+ num_roots = 2;
+ roots[0] = 0;
+ roots[1] = dt;
+ }
+ }
+ else
+ {
+ num_roots = 1;
+ roots[0] = -a0/a1;
+ }
+ }
+ else
+ {
+ num_roots = SolveP2(roots, a1/a2, a0/a2);
+ }
+ }
+ else
+ {
+ num_roots = SolveP3(roots, a2/a3, a1/a3, a0/a3);
+ }
+// std::sort(roots, roots+num_roots);
+ if (num_roots > 1)
+ {
+ if (roots[0] > roots[1])
+ btSwap(roots[0], roots[1]);
+ }
+ if (num_roots > 2)
+ {
+ if (roots[0] > roots[2])
+ btSwap(roots[0], roots[2]);
+ if (roots[1] > roots[2])
+ btSwap(roots[1], roots[2]);
+ }
+ for (int r = 0; r < num_roots; ++r)
+ {
+ double root = roots[r];
+ if (root <= 0)
+ continue;
+ if (root > dt + SIMD_EPSILON)
+ return false;
+ btVector3 x1 = face->m_n[0]->m_x + root * face->m_n[0]->m_v;
+ btVector3 x2 = face->m_n[1]->m_x + root * face->m_n[1]->m_v;
+ btVector3 x3 = face->m_n[2]->m_x + root * face->m_n[2]->m_v;
+ btVector3 x4 = node->m_x + root * node->m_v;
+ btVector3 normal = (x2-x1).cross(x3-x1);
+ normal.safeNormalize();
+ if (proximityTest(x1, x2, x3, x4, normal, mrg, bary))
+ return true;
+ }
+ return false;
+}
+static SIMD_FORCE_INLINE bool bernsteinCCD(const btSoftBody::Face* face, const btSoftBody::Node* node, const btScalar& dt, const btScalar& mrg, btVector3& bary)
+{
+ if (!bernsteinVFTest(face, node, dt, mrg))
+ return false;
+ if (!continuousCollisionDetection(face, node, dt, 1e-6, bary))
+ return false;
+ return true;
+}
+
//
// btSymMatrix
//
@@ -373,6 +938,26 @@ static inline btMatrix3x3 OuterProduct(const btScalar* v1,const btScalar* v2,con
return (m);
}
+static inline btMatrix3x3 OuterProduct(const btVector3& v1,const btVector3& v2)
+{
+ btMatrix3x3 m;
+ btScalar a11 = v1[0] * v2[0];
+ btScalar a12 = v1[0] * v2[1];
+ btScalar a13 = v1[0] * v2[2];
+
+ btScalar a21 = v1[1] * v2[0];
+ btScalar a22 = v1[1] * v2[1];
+ btScalar a23 = v1[1] * v2[2];
+
+ btScalar a31 = v1[2] * v2[0];
+ btScalar a32 = v1[2] * v2[1];
+ btScalar a33 = v1[2] * v2[2];
+ m[0] = btVector3(a11, a12, a13);
+ m[1] = btVector3(a21, a22, a23);
+ m[2] = btVector3(a31, a32, a33);
+ return (m);
+}
+
//
static inline btMatrix3x3 Add(const btMatrix3x3& a,
@@ -1070,8 +1655,8 @@ struct btSoftColliders
if (!n.m_battach)
{
- // check for collision at x_{n+1}^* as well at x_n
- if (psb->checkDeformableContact(m_colObj1Wrap, n.m_x, m, c.m_cti, /*predict = */ true) || psb->checkDeformableContact(m_colObj1Wrap, n.m_q, m, c.m_cti, /*predict = */ true))
+ // check for collision at x_{n+1}^*
+ if (psb->checkDeformableContact(m_colObj1Wrap, n.m_q, m, c.m_cti, /*predict = */ true))
{
const btScalar ima = n.m_im;
// todo: collision between multibody and fixed deformable node will be missed.
@@ -1159,7 +1744,6 @@ struct btSoftColliders
btSoftBody::Node* n0 = f.m_n[0];
btSoftBody::Node* n1 = f.m_n[1];
btSoftBody::Node* n2 = f.m_n[2];
-
const btScalar m = (n0->m_im > 0 && n1->m_im > 0 && n2->m_im > 0 )? dynmargin : stamargin;
btSoftBody::DeformableFaceRigidContact c;
btVector3 contact_point;
@@ -1174,18 +1758,19 @@ struct btSoftColliders
if (ms > 0)
{
// resolve contact at x_n
- psb->checkDeformableFaceContact(m_colObj1Wrap, f, contact_point, bary, m, c.m_cti, /*predict = */ false);
+// psb->checkDeformableFaceContact(m_colObj1Wrap, f, contact_point, bary, m, c.m_cti, /*predict = */ false);
btSoftBody::sCti& cti = c.m_cti;
c.m_contactPoint = contact_point;
c.m_bary = bary;
// todo xuchenhan@: this is assuming mass of all vertices are the same. Need to modify if mass are different for distinct vertices
c.m_weights = btScalar(2)/(btScalar(1) + bary.length2()) * bary;
c.m_face = &f;
+ // friction is handled by the nodes to prevent sticking
+// const btScalar fc = 0;
const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction();
// the effective inverse mass of the face as in https://graphics.stanford.edu/papers/cloth-sig02/cloth.pdf
ima = bary.getX()*c.m_weights.getX() * n0->m_im + bary.getY()*c.m_weights.getY() * n1->m_im + bary.getZ()*c.m_weights.getZ() * n2->m_im;
-
c.m_c2 = ima;
c.m_c3 = fc;
c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject() ? psb->m_cfg.kKHR : psb->m_cfg.kCHR;
@@ -1316,19 +1901,11 @@ struct btSoftColliders
{
btSoftBody::Node* node = (btSoftBody::Node*)lnode->data;
btSoftBody::Face* face = (btSoftBody::Face*)lface->data;
-
- btVector3 o = node->m_x;
- btVector3 p;
- btScalar d = SIMD_INFINITY;
- ProjectOrigin(face->m_n[0]->m_x - o,
- face->m_n[1]->m_x - o,
- face->m_n[2]->m_x - o,
- p, d);
- const btScalar m = mrg + (o - node->m_q).safeNorm() * 2;
- if (d < (m * m))
+ btVector3 bary;
+ if (proximityTest(face->m_n[0]->m_x, face->m_n[1]->m_x, face->m_n[2]->m_x, node->m_x, face->m_normal, mrg, bary))
{
const btSoftBody::Node* n[] = {face->m_n[0], face->m_n[1], face->m_n[2]};
- const btVector3 w = BaryCoord(n[0]->m_x, n[1]->m_x, n[2]->m_x, p + o);
+ const btVector3 w = bary;
const btScalar ma = node->m_im;
btScalar mb = BaryEval(n[0]->m_im, n[1]->m_im, n[2]->m_im, w);
if ((n[0]->m_im <= 0) ||
@@ -1341,20 +1918,14 @@ struct btSoftColliders
if (ms > 0)
{
btSoftBody::DeformableFaceNodeContact c;
- if (useFaceNormal)
- c.m_normal = face->m_normal;
- else
- c.m_normal = p / -btSqrt(d);
+ c.m_normal = face->m_normal;
+ if (!useFaceNormal && c.m_normal.dot(node->m_x - face->m_n[2]->m_x) < 0)
+ c.m_normal = -face->m_normal;
c.m_margin = mrg;
c.m_node = node;
c.m_face = face;
c.m_bary = w;
- // todo xuchenhan@: this is assuming mass of all vertices are the same. Need to modify if mass are different for distinct vertices
- c.m_weights = btScalar(2)/(btScalar(1) + w.length2()) * w;
c.m_friction = psb[0]->m_cfg.kDF * psb[1]->m_cfg.kDF;
- // the effective inverse mass of the face as in https://graphics.stanford.edu/papers/cloth-sig02/cloth.pdf
- c.m_imf = c.m_bary[0]*c.m_weights[0] * n[0]->m_im + c.m_bary[1]*c.m_weights[1] * n[1]->m_im + c.m_bary[2]*c.m_weights[2] * n[2]->m_im;
- c.m_c0 = btScalar(1)/(ma + c.m_imf);
psb[0]->m_faceNodeContacts.push_back(c);
}
}
@@ -1372,69 +1943,152 @@ struct btSoftColliders
void Process(const btDbvntNode* lface1,
const btDbvntNode* lface2)
{
- btSoftBody::Face* f = (btSoftBody::Face*)lface1->data;
- btSoftBody::Face* face = (btSoftBody::Face*)lface2->data;
+ btSoftBody::Face* f1 = (btSoftBody::Face*)lface1->data;
+ btSoftBody::Face* f2 = (btSoftBody::Face*)lface2->data;
+ if (f1 != f2)
+ {
+ Repel(f1, f2);
+ Repel(f2, f1);
+ }
+ }
+ void Repel(btSoftBody::Face* f1, btSoftBody::Face* f2)
+ {
+ //#define REPEL_NEIGHBOR 1
+#ifndef REPEL_NEIGHBOR
for (int node_id = 0; node_id < 3; ++node_id)
{
- btSoftBody::Node* node = f->m_n[node_id];
- bool skip = false;
+ btSoftBody::Node* node = f1->m_n[node_id];
for (int i = 0; i < 3; ++i)
{
- if (face->m_n[i] == node)
+ if (f2->m_n[i] == node)
+ return;
+ }
+ }
+#endif
+ bool skip = false;
+ for (int node_id = 0; node_id < 3; ++node_id)
+ {
+ btSoftBody::Node* node = f1->m_n[node_id];
+#ifdef REPEL_NEIGHBOR
+ for (int i = 0; i < 3; ++i)
+ {
+ if (f2->m_n[i] == node)
{
skip = true;
break;
}
}
if (skip)
+ {
+ skip = false;
+ continue;
+ }
+#endif
+ btSoftBody::Face* face = f2;
+ btVector3 bary;
+ if (!proximityTest(face->m_n[0]->m_x, face->m_n[1]->m_x, face->m_n[2]->m_x, node->m_x, face->m_normal, mrg, bary))
continue;
- btVector3 o = node->m_x;
- btVector3 p;
- btScalar d = SIMD_INFINITY;
- ProjectOrigin(face->m_n[0]->m_x - o,
- face->m_n[1]->m_x - o,
- face->m_n[2]->m_x - o,
- p, d);
- const btScalar m = mrg + (o - node->m_q).safeNorm() * 2;
- if (d < (m * m))
+ btSoftBody::DeformableFaceNodeContact c;
+ c.m_normal = face->m_normal;
+ if (!useFaceNormal && c.m_normal.dot(node->m_x - face->m_n[2]->m_x) < 0)
+ c.m_normal = -face->m_normal;
+ c.m_margin = mrg;
+ c.m_node = node;
+ c.m_face = face;
+ c.m_bary = bary;
+ c.m_friction = psb[0]->m_cfg.kDF * psb[1]->m_cfg.kDF;
+ psb[0]->m_faceNodeContacts.push_back(c);
+ }
+ }
+ btSoftBody* psb[2];
+ btScalar mrg;
+ bool useFaceNormal;
+ };
+
+ struct CollideCCD : btDbvt::ICollide
+ {
+ void Process(const btDbvtNode* lnode,
+ const btDbvtNode* lface)
+ {
+ btSoftBody::Node* node = (btSoftBody::Node*)lnode->data;
+ btSoftBody::Face* face = (btSoftBody::Face*)lface->data;
+ btVector3 bary;
+ if (bernsteinCCD(face, node, dt, SAFE_EPSILON, bary))
+ {
+ btSoftBody::DeformableFaceNodeContact c;
+ c.m_normal = face->m_normal;
+ if (!useFaceNormal && c.m_normal.dot(node->m_x - face->m_n[2]->m_x) < 0)
+ c.m_normal = -face->m_normal;
+ c.m_node = node;
+ c.m_face = face;
+ c.m_bary = bary;
+ c.m_friction = psb[0]->m_cfg.kDF * psb[1]->m_cfg.kDF;
+ psb[0]->m_faceNodeContacts.push_back(c);
+ }
+ }
+ void Process(const btDbvntNode* lface1,
+ const btDbvntNode* lface2)
+ {
+ btSoftBody::Face* f1 = (btSoftBody::Face*)lface1->data;
+ btSoftBody::Face* f2 = (btSoftBody::Face*)lface2->data;
+ if (f1 != f2)
+ {
+ Repel(f1, f2);
+ Repel(f2, f1);
+ }
+ }
+ void Repel(btSoftBody::Face* f1, btSoftBody::Face* f2)
+ {
+ //#define REPEL_NEIGHBOR 1
+#ifndef REPEL_NEIGHBOR
+ for (int node_id = 0; node_id < 3; ++node_id)
+ {
+ btSoftBody::Node* node = f1->m_n[node_id];
+ for (int i = 0; i < 3; ++i)
{
- const btSoftBody::Node* n[] = {face->m_n[0], face->m_n[1], face->m_n[2]};
- const btVector3 w = BaryCoord(n[0]->m_x, n[1]->m_x, n[2]->m_x, p + o);
- const btScalar ma = node->m_im;
- btScalar mb = BaryEval(n[0]->m_im, n[1]->m_im, n[2]->m_im, w);
- if ((n[0]->m_im <= 0) ||
- (n[1]->m_im <= 0) ||
- (n[2]->m_im <= 0))
- {
- mb = 0;
- }
- const btScalar ms = ma + mb;
- if (ms > 0)
+ if (f2->m_n[i] == node)
+ return;
+ }
+ }
+#endif
+ bool skip = false;
+ for (int node_id = 0; node_id < 3; ++node_id)
+ {
+ btSoftBody::Node* node = f1->m_n[node_id];
+#ifdef REPEL_NEIGHBOR
+ for (int i = 0; i < 3; ++i)
+ {
+ if (f2->m_n[i] == node)
{
- btSoftBody::DeformableFaceNodeContact c;
- if (useFaceNormal)
- c.m_normal = face->m_normal;
- else
- c.m_normal = p / -btSqrt(d);
- c.m_margin = mrg;
- c.m_node = node;
- c.m_face = face;
- c.m_bary = w;
- // todo xuchenhan@: this is assuming mass of all vertices are the same. Need to modify if mass are different for distinct vertices
- c.m_weights = btScalar(2)/(btScalar(1) + w.length2()) * w;
- c.m_friction = psb[0]->m_cfg.kDF * psb[1]->m_cfg.kDF;
- // the effective inverse mass of the face as in https://graphics.stanford.edu/papers/cloth-sig02/cloth.pdf
- c.m_imf = c.m_bary[0]*c.m_weights[0] * n[0]->m_im + c.m_bary[1]*c.m_weights[1] * n[1]->m_im + c.m_bary[2]*c.m_weights[2] * n[2]->m_im;
- c.m_c0 = btScalar(1)/(ma + c.m_imf);
- psb[0]->m_faceNodeContacts.push_back(c);
+ skip = true;
+ break;
}
}
+ if (skip)
+ {
+ skip = false;
+ continue;
+ }
+#endif
+ btSoftBody::Face* face = f2;
+ btVector3 bary;
+ if (bernsteinCCD(face, node, dt, SAFE_EPSILON, bary))
+ {
+ btSoftBody::DeformableFaceNodeContact c;
+ c.m_normal = face->m_normal;
+ if (!useFaceNormal && c.m_normal.dot(node->m_x - face->m_n[2]->m_x) < 0)
+ c.m_normal = -face->m_normal;
+ c.m_node = node;
+ c.m_face = face;
+ c.m_bary = bary;
+ c.m_friction = psb[0]->m_cfg.kDF * psb[1]->m_cfg.kDF;
+ psb[0]->m_faceNodeContacts.push_back(c);
+ }
}
}
btSoftBody* psb[2];
- btScalar mrg;
+ btScalar dt, mrg;
bool useFaceNormal;
};
};
-
#endif //_BT_SOFT_BODY_INTERNALS_H
diff --git a/thirdparty/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp b/thirdparty/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
index 56d8083f22..5b65216e4b 100644
--- a/thirdparty/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
+++ b/thirdparty/bullet/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
@@ -48,9 +48,10 @@ btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm()
}
#include <stdio.h>
-
+#include "LinearMath/btQuickprof.h"
void btSoftRigidCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut)
{
+ BT_PROFILE("btSoftRigidCollisionAlgorithm::processCollision");
(void)dispatchInfo;
(void)resultOut;
//printf("btSoftRigidCollisionAlgorithm\n");
diff --git a/thirdparty/bullet/BulletSoftBody/poly34.cpp b/thirdparty/bullet/BulletSoftBody/poly34.cpp
new file mode 100644
index 0000000000..819d0c79f7
--- /dev/null
+++ b/thirdparty/bullet/BulletSoftBody/poly34.cpp
@@ -0,0 +1,419 @@
+// poly34.cpp : solution of cubic and quartic equation
+// (c) Khashin S.I. http://math.ivanovo.ac.ru/dalgebra/Khashin/index.html
+// khash2 (at) gmail.com
+// Thanks to Alexandr Rakhmanin <rakhmanin (at) gmail.com>
+// public domain
+//
+#include <math.h>
+
+#include "poly34.h" // solution of cubic and quartic equation
+#define TwoPi 6.28318530717958648
+const btScalar eps = SIMD_EPSILON;
+
+//=============================================================================
+// _root3, root3 from http://prografix.narod.ru
+//=============================================================================
+static SIMD_FORCE_INLINE btScalar _root3(btScalar x)
+{
+ btScalar s = 1.;
+ while (x < 1.) {
+ x *= 8.;
+ s *= 0.5;
+ }
+ while (x > 8.) {
+ x *= 0.125;
+ s *= 2.;
+ }
+ btScalar r = 1.5;
+ r -= 1. / 3. * (r - x / (r * r));
+ r -= 1. / 3. * (r - x / (r * r));
+ r -= 1. / 3. * (r - x / (r * r));
+ r -= 1. / 3. * (r - x / (r * r));
+ r -= 1. / 3. * (r - x / (r * r));
+ r -= 1. / 3. * (r - x / (r * r));
+ return r * s;
+}
+
+btScalar SIMD_FORCE_INLINE root3(btScalar x)
+{
+ if (x > 0)
+ return _root3(x);
+ else if (x < 0)
+ return -_root3(-x);
+ else
+ return 0.;
+}
+
+// x - array of size 2
+// return 2: 2 real roots x[0], x[1]
+// return 0: pair of complex roots: x[0]i*x[1]
+int SolveP2(btScalar* x, btScalar a, btScalar b)
+{ // solve equation x^2 + a*x + b = 0
+ btScalar D = 0.25 * a * a - b;
+ if (D >= 0) {
+ D = sqrt(D);
+ x[0] = -0.5 * a + D;
+ x[1] = -0.5 * a - D;
+ return 2;
+ }
+ x[0] = -0.5 * a;
+ x[1] = sqrt(-D);
+ return 0;
+}
+//---------------------------------------------------------------------------
+// x - array of size 3
+// In case 3 real roots: => x[0], x[1], x[2], return 3
+// 2 real roots: x[0], x[1], return 2
+// 1 real root : x[0], x[1] i*x[2], return 1
+int SolveP3(btScalar* x, btScalar a, btScalar b, btScalar c)
+{ // solve cubic equation x^3 + a*x^2 + b*x + c = 0
+ btScalar a2 = a * a;
+ btScalar q = (a2 - 3 * b) / 9;
+ if (q < 0)
+ q = eps;
+ btScalar r = (a * (2 * a2 - 9 * b) + 27 * c) / 54;
+ // equation x^3 + q*x + r = 0
+ btScalar r2 = r * r;
+ btScalar q3 = q * q * q;
+ btScalar A, B;
+ if (r2 <= (q3 + eps)) { //<<-- FIXED!
+ btScalar t = r / sqrt(q3);
+ if (t < -1)
+ t = -1;
+ if (t > 1)
+ t = 1;
+ t = acos(t);
+ a /= 3;
+ q = -2 * sqrt(q);
+ x[0] = q * cos(t / 3) - a;
+ x[1] = q * cos((t + TwoPi) / 3) - a;
+ x[2] = q * cos((t - TwoPi) / 3) - a;
+ return (3);
+ }
+ else {
+ //A =-pow(fabs(r)+sqrt(r2-q3),1./3);
+ A = -root3(fabs(r) + sqrt(r2 - q3));
+ if (r < 0)
+ A = -A;
+ B = (A == 0 ? 0 : q / A);
+
+ a /= 3;
+ x[0] = (A + B) - a;
+ x[1] = -0.5 * (A + B) - a;
+ x[2] = 0.5 * sqrt(3.) * (A - B);
+ if (fabs(x[2]) < eps) {
+ x[2] = x[1];
+ return (2);
+ }
+ return (1);
+ }
+} // SolveP3(btScalar *x,btScalar a,btScalar b,btScalar c) {
+//---------------------------------------------------------------------------
+// a>=0!
+void CSqrt(btScalar x, btScalar y, btScalar& a, btScalar& b) // returns: a+i*s = sqrt(x+i*y)
+{
+ btScalar r = sqrt(x * x + y * y);
+ if (y == 0) {
+ r = sqrt(r);
+ if (x >= 0) {
+ a = r;
+ b = 0;
+ }
+ else {
+ a = 0;
+ b = r;
+ }
+ }
+ else { // y != 0
+ a = sqrt(0.5 * (x + r));
+ b = 0.5 * y / a;
+ }
+}
+//---------------------------------------------------------------------------
+int SolveP4Bi(btScalar* x, btScalar b, btScalar d) // solve equation x^4 + b*x^2 + d = 0
+{
+ btScalar D = b * b - 4 * d;
+ if (D >= 0) {
+ btScalar sD = sqrt(D);
+ btScalar x1 = (-b + sD) / 2;
+ btScalar x2 = (-b - sD) / 2; // x2 <= x1
+ if (x2 >= 0) // 0 <= x2 <= x1, 4 real roots
+ {
+ btScalar sx1 = sqrt(x1);
+ btScalar sx2 = sqrt(x2);
+ x[0] = -sx1;
+ x[1] = sx1;
+ x[2] = -sx2;
+ x[3] = sx2;
+ return 4;
+ }
+ if (x1 < 0) // x2 <= x1 < 0, two pair of imaginary roots
+ {
+ btScalar sx1 = sqrt(-x1);
+ btScalar sx2 = sqrt(-x2);
+ x[0] = 0;
+ x[1] = sx1;
+ x[2] = 0;
+ x[3] = sx2;
+ return 0;
+ }
+ // now x2 < 0 <= x1 , two real roots and one pair of imginary root
+ btScalar sx1 = sqrt(x1);
+ btScalar sx2 = sqrt(-x2);
+ x[0] = -sx1;
+ x[1] = sx1;
+ x[2] = 0;
+ x[3] = sx2;
+ return 2;
+ }
+ else { // if( D < 0 ), two pair of compex roots
+ btScalar sD2 = 0.5 * sqrt(-D);
+ CSqrt(-0.5 * b, sD2, x[0], x[1]);
+ CSqrt(-0.5 * b, -sD2, x[2], x[3]);
+ return 0;
+ } // if( D>=0 )
+} // SolveP4Bi(btScalar *x, btScalar b, btScalar d) // solve equation x^4 + b*x^2 d
+//---------------------------------------------------------------------------
+#define SWAP(a, b) \
+{ \
+t = b; \
+b = a; \
+a = t; \
+}
+static void dblSort3(btScalar& a, btScalar& b, btScalar& c) // make: a <= b <= c
+{
+ btScalar t;
+ if (a > b)
+ SWAP(a, b); // now a<=b
+ if (c < b) {
+ SWAP(b, c); // now a<=b, b<=c
+ if (a > b)
+ SWAP(a, b); // now a<=b
+ }
+}
+//---------------------------------------------------------------------------
+int SolveP4De(btScalar* x, btScalar b, btScalar c, btScalar d) // solve equation x^4 + b*x^2 + c*x + d
+{
+ //if( c==0 ) return SolveP4Bi(x,b,d); // After that, c!=0
+ if (fabs(c) < 1e-14 * (fabs(b) + fabs(d)))
+ return SolveP4Bi(x, b, d); // After that, c!=0
+
+ int res3 = SolveP3(x, 2 * b, b * b - 4 * d, -c * c); // solve resolvent
+ // by Viet theorem: x1*x2*x3=-c*c not equals to 0, so x1!=0, x2!=0, x3!=0
+ if (res3 > 1) // 3 real roots,
+ {
+ dblSort3(x[0], x[1], x[2]); // sort roots to x[0] <= x[1] <= x[2]
+ // Note: x[0]*x[1]*x[2]= c*c > 0
+ if (x[0] > 0) // all roots are positive
+ {
+ btScalar sz1 = sqrt(x[0]);
+ btScalar sz2 = sqrt(x[1]);
+ btScalar sz3 = sqrt(x[2]);
+ // Note: sz1*sz2*sz3= -c (and not equal to 0)
+ if (c > 0) {
+ x[0] = (-sz1 - sz2 - sz3) / 2;
+ x[1] = (-sz1 + sz2 + sz3) / 2;
+ x[2] = (+sz1 - sz2 + sz3) / 2;
+ x[3] = (+sz1 + sz2 - sz3) / 2;
+ return 4;
+ }
+ // now: c<0
+ x[0] = (-sz1 - sz2 + sz3) / 2;
+ x[1] = (-sz1 + sz2 - sz3) / 2;
+ x[2] = (+sz1 - sz2 - sz3) / 2;
+ x[3] = (+sz1 + sz2 + sz3) / 2;
+ return 4;
+ } // if( x[0] > 0) // all roots are positive
+ // now x[0] <= x[1] < 0, x[2] > 0
+ // two pair of comlex roots
+ btScalar sz1 = sqrt(-x[0]);
+ btScalar sz2 = sqrt(-x[1]);
+ btScalar sz3 = sqrt(x[2]);
+
+ if (c > 0) // sign = -1
+ {
+ x[0] = -sz3 / 2;
+ x[1] = (sz1 - sz2) / 2; // x[0]i*x[1]
+ x[2] = sz3 / 2;
+ x[3] = (-sz1 - sz2) / 2; // x[2]i*x[3]
+ return 0;
+ }
+ // now: c<0 , sign = +1
+ x[0] = sz3 / 2;
+ x[1] = (-sz1 + sz2) / 2;
+ x[2] = -sz3 / 2;
+ x[3] = (sz1 + sz2) / 2;
+ return 0;
+ } // if( res3>1 ) // 3 real roots,
+ // now resoventa have 1 real and pair of compex roots
+ // x[0] - real root, and x[0]>0,
+ // x[1]i*x[2] - complex roots,
+ // x[0] must be >=0. But one times x[0]=~ 1e-17, so:
+ if (x[0] < 0)
+ x[0] = 0;
+ btScalar sz1 = sqrt(x[0]);
+ btScalar szr, szi;
+ CSqrt(x[1], x[2], szr, szi); // (szr+i*szi)^2 = x[1]+i*x[2]
+ if (c > 0) // sign = -1
+ {
+ x[0] = -sz1 / 2 - szr; // 1st real root
+ x[1] = -sz1 / 2 + szr; // 2nd real root
+ x[2] = sz1 / 2;
+ x[3] = szi;
+ return 2;
+ }
+ // now: c<0 , sign = +1
+ x[0] = sz1 / 2 - szr; // 1st real root
+ x[1] = sz1 / 2 + szr; // 2nd real root
+ x[2] = -sz1 / 2;
+ x[3] = szi;
+ return 2;
+} // SolveP4De(btScalar *x, btScalar b, btScalar c, btScalar d) // solve equation x^4 + b*x^2 + c*x + d
+//-----------------------------------------------------------------------------
+btScalar N4Step(btScalar x, btScalar a, btScalar b, btScalar c, btScalar d) // one Newton step for x^4 + a*x^3 + b*x^2 + c*x + d
+{
+ btScalar fxs = ((4 * x + 3 * a) * x + 2 * b) * x + c; // f'(x)
+ if (fxs == 0)
+ return x; //return 1e99; <<-- FIXED!
+ btScalar fx = (((x + a) * x + b) * x + c) * x + d; // f(x)
+ return x - fx / fxs;
+}
+//-----------------------------------------------------------------------------
+// x - array of size 4
+// return 4: 4 real roots x[0], x[1], x[2], x[3], possible multiple roots
+// return 2: 2 real roots x[0], x[1] and complex x[2]i*x[3],
+// return 0: two pair of complex roots: x[0]i*x[1], x[2]i*x[3],
+int SolveP4(btScalar* x, btScalar a, btScalar b, btScalar c, btScalar d)
+{ // solve equation x^4 + a*x^3 + b*x^2 + c*x + d by Dekart-Euler method
+ // move to a=0:
+ btScalar d1 = d + 0.25 * a * (0.25 * b * a - 3. / 64 * a * a * a - c);
+ btScalar c1 = c + 0.5 * a * (0.25 * a * a - b);
+ btScalar b1 = b - 0.375 * a * a;
+ int res = SolveP4De(x, b1, c1, d1);
+ if (res == 4) {
+ x[0] -= a / 4;
+ x[1] -= a / 4;
+ x[2] -= a / 4;
+ x[3] -= a / 4;
+ }
+ else if (res == 2) {
+ x[0] -= a / 4;
+ x[1] -= a / 4;
+ x[2] -= a / 4;
+ }
+ else {
+ x[0] -= a / 4;
+ x[2] -= a / 4;
+ }
+ // one Newton step for each real root:
+ if (res > 0) {
+ x[0] = N4Step(x[0], a, b, c, d);
+ x[1] = N4Step(x[1], a, b, c, d);
+ }
+ if (res > 2) {
+ x[2] = N4Step(x[2], a, b, c, d);
+ x[3] = N4Step(x[3], a, b, c, d);
+ }
+ return res;
+}
+//-----------------------------------------------------------------------------
+#define F5(t) (((((t + a) * t + b) * t + c) * t + d) * t + e)
+//-----------------------------------------------------------------------------
+btScalar SolveP5_1(btScalar a, btScalar b, btScalar c, btScalar d, btScalar e) // return real root of x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0
+{
+ int cnt;
+ if (fabs(e) < eps)
+ return 0;
+
+ btScalar brd = fabs(a); // brd - border of real roots
+ if (fabs(b) > brd)
+ brd = fabs(b);
+ if (fabs(c) > brd)
+ brd = fabs(c);
+ if (fabs(d) > brd)
+ brd = fabs(d);
+ if (fabs(e) > brd)
+ brd = fabs(e);
+ brd++; // brd - border of real roots
+
+ btScalar x0, f0; // less than root
+ btScalar x1, f1; // greater than root
+ btScalar x2, f2, f2s; // next values, f(x2), f'(x2)
+ btScalar dx = 0;
+
+ if (e < 0) {
+ x0 = 0;
+ x1 = brd;
+ f0 = e;
+ f1 = F5(x1);
+ x2 = 0.01 * brd;
+ } // positive root
+ else {
+ x0 = -brd;
+ x1 = 0;
+ f0 = F5(x0);
+ f1 = e;
+ x2 = -0.01 * brd;
+ } // negative root
+
+ if (fabs(f0) < eps)
+ return x0;
+ if (fabs(f1) < eps)
+ return x1;
+
+ // now x0<x1, f(x0)<0, f(x1)>0
+ // Firstly 10 bisections
+ for (cnt = 0; cnt < 10; cnt++) {
+ x2 = (x0 + x1) / 2; // next point
+ //x2 = x0 - f0*(x1 - x0) / (f1 - f0); // next point
+ f2 = F5(x2); // f(x2)
+ if (fabs(f2) < eps)
+ return x2;
+ if (f2 > 0) {
+ x1 = x2;
+ f1 = f2;
+ }
+ else {
+ x0 = x2;
+ f0 = f2;
+ }
+ }
+
+ // At each step:
+ // x0<x1, f(x0)<0, f(x1)>0.
+ // x2 - next value
+ // we hope that x0 < x2 < x1, but not necessarily
+ do {
+ if (cnt++ > 50)
+ break;
+ if (x2 <= x0 || x2 >= x1)
+ x2 = (x0 + x1) / 2; // now x0 < x2 < x1
+ f2 = F5(x2); // f(x2)
+ if (fabs(f2) < eps)
+ return x2;
+ if (f2 > 0) {
+ x1 = x2;
+ f1 = f2;
+ }
+ else {
+ x0 = x2;
+ f0 = f2;
+ }
+ f2s = (((5 * x2 + 4 * a) * x2 + 3 * b) * x2 + 2 * c) * x2 + d; // f'(x2)
+ if (fabs(f2s) < eps) {
+ x2 = 1e99;
+ continue;
+ }
+ dx = f2 / f2s;
+ x2 -= dx;
+ } while (fabs(dx) > eps);
+ return x2;
+} // SolveP5_1(btScalar a,btScalar b,btScalar c,btScalar d,btScalar e) // return real root of x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0
+//-----------------------------------------------------------------------------
+int SolveP5(btScalar* x, btScalar a, btScalar b, btScalar c, btScalar d, btScalar e) // solve equation x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0
+{
+ btScalar r = x[0] = SolveP5_1(a, b, c, d, e);
+ btScalar a1 = a + r, b1 = b + r * a1, c1 = c + r * b1, d1 = d + r * c1;
+ return 1 + SolveP4(x + 1, a1, b1, c1, d1);
+} // SolveP5(btScalar *x,btScalar a,btScalar b,btScalar c,btScalar d,btScalar e) // solve equation x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0
+//-----------------------------------------------------------------------------
diff --git a/thirdparty/bullet/BulletSoftBody/poly34.h b/thirdparty/bullet/BulletSoftBody/poly34.h
new file mode 100644
index 0000000000..32ad5d7da5
--- /dev/null
+++ b/thirdparty/bullet/BulletSoftBody/poly34.h
@@ -0,0 +1,38 @@
+// poly34.h : solution of cubic and quartic equation
+// (c) Khashin S.I. http://math.ivanovo.ac.ru/dalgebra/Khashin/index.html
+// khash2 (at) gmail.com
+
+#ifndef POLY_34
+#define POLY_34
+#include "LinearMath/btScalar.h"
+// x - array of size 2
+// return 2: 2 real roots x[0], x[1]
+// return 0: pair of complex roots: x[0]i*x[1]
+int SolveP2(btScalar* x, btScalar a, btScalar b); // solve equation x^2 + a*x + b = 0
+
+// x - array of size 3
+// return 3: 3 real roots x[0], x[1], x[2]
+// return 1: 1 real root x[0] and pair of complex roots: x[1]i*x[2]
+int SolveP3(btScalar* x, btScalar a, btScalar b, btScalar c); // solve cubic equation x^3 + a*x^2 + b*x + c = 0
+
+// x - array of size 4
+// return 4: 4 real roots x[0], x[1], x[2], x[3], possible multiple roots
+// return 2: 2 real roots x[0], x[1] and complex x[2]i*x[3],
+// return 0: two pair of complex roots: x[0]i*x[1], x[2]i*x[3],
+int SolveP4(btScalar* x, btScalar a, btScalar b, btScalar c, btScalar d); // solve equation x^4 + a*x^3 + b*x^2 + c*x + d = 0 by Dekart-Euler method
+
+// x - array of size 5
+// return 5: 5 real roots x[0], x[1], x[2], x[3], x[4], possible multiple roots
+// return 3: 3 real roots x[0], x[1], x[2] and complex x[3]i*x[4],
+// return 1: 1 real root x[0] and two pair of complex roots: x[1]i*x[2], x[3]i*x[4],
+int SolveP5(btScalar* x, btScalar a, btScalar b, btScalar c, btScalar d, btScalar e); // solve equation x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0
+
+//-----------------------------------------------------------------------------
+// And some additional functions for internal use.
+// Your may remove this definitions from here
+int SolveP4Bi(btScalar* x, btScalar b, btScalar d); // solve equation x^4 + b*x^2 + d = 0
+int SolveP4De(btScalar* x, btScalar b, btScalar c, btScalar d); // solve equation x^4 + b*x^2 + c*x + d = 0
+void CSqrt(btScalar x, btScalar y, btScalar& a, btScalar& b); // returns as a+i*s, sqrt(x+i*y)
+btScalar N4Step(btScalar x, btScalar a, btScalar b, btScalar c, btScalar d); // one Newton step for x^4 + a*x^3 + b*x^2 + c*x + d
+btScalar SolveP5_1(btScalar a, btScalar b, btScalar c, btScalar d, btScalar e); // return real root of x^5 + a*x^4 + b*x^3 + c*x^2 + d*x + e = 0
+#endif
diff --git a/thirdparty/bullet/LinearMath/btImplicitQRSVD.h b/thirdparty/bullet/LinearMath/btImplicitQRSVD.h
index 7b4cfaf21e..aaedc964f6 100644
--- a/thirdparty/bullet/LinearMath/btImplicitQRSVD.h
+++ b/thirdparty/bullet/LinearMath/btImplicitQRSVD.h
@@ -41,7 +41,7 @@
#ifndef btImplicitQRSVD_h
#define btImplicitQRSVD_h
-
+#include <limits>
#include "btMatrix3x3.h"
class btMatrix2x2
{
@@ -753,7 +753,7 @@ inline int singularValueDecomposition(const btMatrix3x3& A,
btMatrix3x3& V,
btScalar tol = 128*std::numeric_limits<btScalar>::epsilon())
{
- using std::fabs;
+// using std::fabs;
btMatrix3x3 B = A;
U.setIdentity();
V.setIdentity();
diff --git a/thirdparty/bullet/LinearMath/btMatrix3x3.h b/thirdparty/bullet/LinearMath/btMatrix3x3.h
index cc33a68664..9c90fee1d2 100644
--- a/thirdparty/bullet/LinearMath/btMatrix3x3.h
+++ b/thirdparty/bullet/LinearMath/btMatrix3x3.h
@@ -26,10 +26,12 @@ subject to the following restrictions:
#endif
#if defined(BT_USE_SSE)
+#define v0000 (_mm_set_ps(0.0f, 0.0f, 0.0f, 0.0f))
#define v1000 (_mm_set_ps(0.0f, 0.0f, 0.0f, 1.0f))
#define v0100 (_mm_set_ps(0.0f, 0.0f, 1.0f, 0.0f))
#define v0010 (_mm_set_ps(0.0f, 1.0f, 0.0f, 0.0f))
#elif defined(BT_USE_NEON)
+const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0000) = {0.0f, 0.0f, 0.0f, 0.0f};
const btSimdFloat4 ATTRIBUTE_ALIGNED16(v1000) = {1.0f, 0.0f, 0.0f, 0.0f};
const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0100) = {0.0f, 1.0f, 0.0f, 0.0f};
const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0010) = {0.0f, 0.0f, 1.0f, 0.0f};
@@ -330,6 +332,20 @@ public:
btScalar(0.0), btScalar(0.0), btScalar(1.0));
#endif
}
+
+ /**@brief Set the matrix to the identity */
+ void setZero()
+ {
+#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON)
+ m_el[0] = v0000;
+ m_el[1] = v0000;
+ m_el[2] = v0000;
+#else
+ setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0),
+ btScalar(0.0), btScalar(0.0), btScalar(0.0),
+ btScalar(0.0), btScalar(0.0), btScalar(0.0));
+#endif
+ }
static const btMatrix3x3& getIdentity()
{
diff --git a/thirdparty/bullet/LinearMath/btMatrixX.h b/thirdparty/bullet/LinearMath/btMatrixX.h
index 961c94dc63..bb0f0dd259 100644
--- a/thirdparty/bullet/LinearMath/btMatrixX.h
+++ b/thirdparty/bullet/LinearMath/btMatrixX.h
@@ -346,10 +346,9 @@ struct btMatrixX
T dotProd = 0;
{
{
- int r = rows();
int c = cols();
- for (int k = 0; k < cols(); k++)
+ for (int k = 0; k < c; k++)
{
T w = (*this)(i, k);
if (other(k, j) != 0.f)
diff --git a/thirdparty/bullet/LinearMath/btModifiedGramSchmidt.h b/thirdparty/bullet/LinearMath/btModifiedGramSchmidt.h
new file mode 100644
index 0000000000..33bab8d650
--- /dev/null
+++ b/thirdparty/bullet/LinearMath/btModifiedGramSchmidt.h
@@ -0,0 +1,83 @@
+//
+// btModifiedGramSchmidt.h
+// LinearMath
+//
+// Created by Xuchen Han on 4/4/20.
+//
+
+#ifndef btModifiedGramSchmidt_h
+#define btModifiedGramSchmidt_h
+
+#include "btReducedVector.h"
+#include "btAlignedObjectArray.h"
+#include <iostream>
+#include <cmath>
+template<class TV>
+class btModifiedGramSchmidt
+{
+public:
+ btAlignedObjectArray<TV> m_in;
+ btAlignedObjectArray<TV> m_out;
+
+ btModifiedGramSchmidt(const btAlignedObjectArray<TV>& vecs): m_in(vecs)
+ {
+ m_out.resize(0);
+ }
+
+ void solve()
+ {
+ m_out.resize(m_in.size());
+ for (int i = 0; i < m_in.size(); ++i)
+ {
+// printf("========= starting %d ==========\n", i);
+ TV v(m_in[i]);
+// v.print();
+ for (int j = 0; j < i; ++j)
+ {
+ v = v - v.proj(m_out[j]);
+// v.print();
+ }
+ v.normalize();
+ m_out[i] = v;
+// v.print();
+ }
+ }
+
+ void test()
+ {
+ std::cout << SIMD_EPSILON << std::endl;
+ printf("=======inputs=========\n");
+ for (int i = 0; i < m_out.size(); ++i)
+ {
+ m_in[i].print();
+ }
+ printf("=======output=========\n");
+ for (int i = 0; i < m_out.size(); ++i)
+ {
+ m_out[i].print();
+ }
+ btScalar eps = SIMD_EPSILON;
+ for (int i = 0; i < m_out.size(); ++i)
+ {
+ for (int j = 0; j < m_out.size(); ++j)
+ {
+ if (i == j)
+ {
+ if (std::abs(1.0-m_out[i].dot(m_out[j])) > eps)// && std::abs(m_out[i].dot(m_out[j])) > eps)
+ {
+ printf("vec[%d] is not unit, norm squared = %f\n", i,m_out[i].dot(m_out[j]));
+ }
+ }
+ else
+ {
+ if (std::abs(m_out[i].dot(m_out[j])) > eps)
+ {
+ printf("vec[%d] and vec[%d] is not orthogonal, dot product = %f\n", i, j, m_out[i].dot(m_out[j]));
+ }
+ }
+ }
+ }
+ }
+};
+template class btModifiedGramSchmidt<btReducedVector>;
+#endif /* btModifiedGramSchmidt_h */
diff --git a/thirdparty/bullet/LinearMath/btReducedVector.cpp b/thirdparty/bullet/LinearMath/btReducedVector.cpp
new file mode 100644
index 0000000000..1539584e7e
--- /dev/null
+++ b/thirdparty/bullet/LinearMath/btReducedVector.cpp
@@ -0,0 +1,170 @@
+//
+// btReducedVector.cpp
+// LinearMath
+//
+// Created by Xuchen Han on 4/4/20.
+//
+#include <stdio.h>
+#include "btReducedVector.h"
+#include <cmath>
+
+// returns the projection of this onto other
+btReducedVector btReducedVector::proj(const btReducedVector& other) const
+{
+ btReducedVector ret(m_sz);
+ btScalar other_length2 = other.length2();
+ if (other_length2 < SIMD_EPSILON)
+ {
+ return ret;
+ }
+ return other*(this->dot(other))/other_length2;
+}
+
+void btReducedVector::normalize()
+{
+ if (this->length2() < SIMD_EPSILON)
+ {
+ m_indices.clear();
+ m_vecs.clear();
+ return;
+ }
+ *this /= std::sqrt(this->length2());
+}
+
+bool btReducedVector::testAdd() const
+{
+ int sz = 5;
+ btAlignedObjectArray<int> id1;
+ id1.push_back(1);
+ id1.push_back(3);
+ btAlignedObjectArray<btVector3> v1;
+ v1.push_back(btVector3(1,0,1));
+ v1.push_back(btVector3(3,1,5));
+ btAlignedObjectArray<int> id2;
+ id2.push_back(2);
+ id2.push_back(3);
+ id2.push_back(5);
+ btAlignedObjectArray<btVector3> v2;
+ v2.push_back(btVector3(2,3,1));
+ v2.push_back(btVector3(3,4,9));
+ v2.push_back(btVector3(0,4,0));
+ btAlignedObjectArray<int> id3;
+ id3.push_back(1);
+ id3.push_back(2);
+ id3.push_back(3);
+ id3.push_back(5);
+ btAlignedObjectArray<btVector3> v3;
+ v3.push_back(btVector3(1,0,1));
+ v3.push_back(btVector3(2,3,1));
+ v3.push_back(btVector3(6,5,14));
+ v3.push_back(btVector3(0,4,0));
+ btReducedVector rv1(sz, id1, v1);
+ btReducedVector rv2(sz, id2, v2);
+ btReducedVector ans(sz, id3, v3);
+ bool ret = ((ans == rv1+rv2) && (ans == rv2+rv1));
+ if (!ret)
+ printf("btReducedVector testAdd failed\n");
+ return ret;
+}
+
+bool btReducedVector::testMinus() const
+{
+ int sz = 5;
+ btAlignedObjectArray<int> id1;
+ id1.push_back(1);
+ id1.push_back(3);
+ btAlignedObjectArray<btVector3> v1;
+ v1.push_back(btVector3(1,0,1));
+ v1.push_back(btVector3(3,1,5));
+ btAlignedObjectArray<int> id2;
+ id2.push_back(2);
+ id2.push_back(3);
+ id2.push_back(5);
+ btAlignedObjectArray<btVector3> v2;
+ v2.push_back(btVector3(2,3,1));
+ v2.push_back(btVector3(3,4,9));
+ v2.push_back(btVector3(0,4,0));
+ btAlignedObjectArray<int> id3;
+ id3.push_back(1);
+ id3.push_back(2);
+ id3.push_back(3);
+ id3.push_back(5);
+ btAlignedObjectArray<btVector3> v3;
+ v3.push_back(btVector3(-1,-0,-1));
+ v3.push_back(btVector3(2,3,1));
+ v3.push_back(btVector3(0,3,4));
+ v3.push_back(btVector3(0,4,0));
+ btReducedVector rv1(sz, id1, v1);
+ btReducedVector rv2(sz, id2, v2);
+ btReducedVector ans(sz, id3, v3);
+ bool ret = (ans == rv2-rv1);
+ if (!ret)
+ printf("btReducedVector testMinus failed\n");
+ return ret;
+}
+
+bool btReducedVector::testDot() const
+{
+ int sz = 5;
+ btAlignedObjectArray<int> id1;
+ id1.push_back(1);
+ id1.push_back(3);
+ btAlignedObjectArray<btVector3> v1;
+ v1.push_back(btVector3(1,0,1));
+ v1.push_back(btVector3(3,1,5));
+ btAlignedObjectArray<int> id2;
+ id2.push_back(2);
+ id2.push_back(3);
+ id2.push_back(5);
+ btAlignedObjectArray<btVector3> v2;
+ v2.push_back(btVector3(2,3,1));
+ v2.push_back(btVector3(3,4,9));
+ v2.push_back(btVector3(0,4,0));
+ btReducedVector rv1(sz, id1, v1);
+ btReducedVector rv2(sz, id2, v2);
+ btScalar ans = 58;
+ bool ret = (ans == rv2.dot(rv1) && ans == rv1.dot(rv2));
+ ans = 14+16+9+16+81;
+ ret &= (ans==rv2.dot(rv2));
+
+ if (!ret)
+ printf("btReducedVector testDot failed\n");
+ return ret;
+}
+
+bool btReducedVector::testMultiply() const
+{
+ int sz = 5;
+ btAlignedObjectArray<int> id1;
+ id1.push_back(1);
+ id1.push_back(3);
+ btAlignedObjectArray<btVector3> v1;
+ v1.push_back(btVector3(1,0,1));
+ v1.push_back(btVector3(3,1,5));
+ btScalar s = 2;
+ btReducedVector rv1(sz, id1, v1);
+ btAlignedObjectArray<int> id2;
+ id2.push_back(1);
+ id2.push_back(3);
+ btAlignedObjectArray<btVector3> v2;
+ v2.push_back(btVector3(2,0,2));
+ v2.push_back(btVector3(6,2,10));
+ btReducedVector ans(sz, id2, v2);
+ bool ret = (ans == rv1*s);
+ if (!ret)
+ printf("btReducedVector testMultiply failed\n");
+ return ret;
+}
+
+void btReducedVector::test() const
+{
+ bool ans = testAdd() && testMinus() && testDot() && testMultiply();
+ if (ans)
+ {
+ printf("All tests passed\n");
+ }
+ else
+ {
+ printf("Tests failed\n");
+ }
+}
diff --git a/thirdparty/bullet/LinearMath/btReducedVector.h b/thirdparty/bullet/LinearMath/btReducedVector.h
new file mode 100644
index 0000000000..83b5e581e5
--- /dev/null
+++ b/thirdparty/bullet/LinearMath/btReducedVector.h
@@ -0,0 +1,320 @@
+//
+// btReducedVectors.h
+// BulletLinearMath
+//
+// Created by Xuchen Han on 4/4/20.
+//
+#ifndef btReducedVectors_h
+#define btReducedVectors_h
+#include "btVector3.h"
+#include "btMatrix3x3.h"
+#include "btAlignedObjectArray.h"
+#include <stdio.h>
+#include <vector>
+#include <algorithm>
+struct TwoInts
+{
+ int a,b;
+};
+inline bool operator<(const TwoInts& A, const TwoInts& B)
+{
+ return A.b < B.b;
+}
+
+
+// A helper vector type used for CG projections
+class btReducedVector
+{
+public:
+ btAlignedObjectArray<int> m_indices;
+ btAlignedObjectArray<btVector3> m_vecs;
+ int m_sz; // all m_indices value < m_sz
+public:
+ btReducedVector():m_sz(0)
+ {
+ m_indices.resize(0);
+ m_vecs.resize(0);
+ m_indices.clear();
+ m_vecs.clear();
+ }
+
+ btReducedVector(int sz): m_sz(sz)
+ {
+ m_indices.resize(0);
+ m_vecs.resize(0);
+ m_indices.clear();
+ m_vecs.clear();
+ }
+
+ btReducedVector(int sz, const btAlignedObjectArray<int>& indices, const btAlignedObjectArray<btVector3>& vecs): m_sz(sz), m_indices(indices), m_vecs(vecs)
+ {
+ }
+
+ void simplify()
+ {
+ btAlignedObjectArray<int> old_indices(m_indices);
+ btAlignedObjectArray<btVector3> old_vecs(m_vecs);
+ m_indices.resize(0);
+ m_vecs.resize(0);
+ m_indices.clear();
+ m_vecs.clear();
+ for (int i = 0; i < old_indices.size(); ++i)
+ {
+ if (old_vecs[i].length2() > SIMD_EPSILON)
+ {
+ m_indices.push_back(old_indices[i]);
+ m_vecs.push_back(old_vecs[i]);
+ }
+ }
+ }
+
+ btReducedVector operator+(const btReducedVector& other)
+ {
+ btReducedVector ret(m_sz);
+ int i=0, j=0;
+ while (i < m_indices.size() && j < other.m_indices.size())
+ {
+ if (m_indices[i] < other.m_indices[j])
+ {
+ ret.m_indices.push_back(m_indices[i]);
+ ret.m_vecs.push_back(m_vecs[i]);
+ ++i;
+ }
+ else if (m_indices[i] > other.m_indices[j])
+ {
+ ret.m_indices.push_back(other.m_indices[j]);
+ ret.m_vecs.push_back(other.m_vecs[j]);
+ ++j;
+ }
+ else
+ {
+ ret.m_indices.push_back(other.m_indices[j]);
+ ret.m_vecs.push_back(m_vecs[i] + other.m_vecs[j]);
+ ++i; ++j;
+ }
+ }
+ while (i < m_indices.size())
+ {
+ ret.m_indices.push_back(m_indices[i]);
+ ret.m_vecs.push_back(m_vecs[i]);
+ ++i;
+ }
+ while (j < other.m_indices.size())
+ {
+ ret.m_indices.push_back(other.m_indices[j]);
+ ret.m_vecs.push_back(other.m_vecs[j]);
+ ++j;
+ }
+ ret.simplify();
+ return ret;
+ }
+
+ btReducedVector operator-()
+ {
+ btReducedVector ret(m_sz);
+ for (int i = 0; i < m_indices.size(); ++i)
+ {
+ ret.m_indices.push_back(m_indices[i]);
+ ret.m_vecs.push_back(-m_vecs[i]);
+ }
+ ret.simplify();
+ return ret;
+ }
+
+ btReducedVector operator-(const btReducedVector& other)
+ {
+ btReducedVector ret(m_sz);
+ int i=0, j=0;
+ while (i < m_indices.size() && j < other.m_indices.size())
+ {
+ if (m_indices[i] < other.m_indices[j])
+ {
+ ret.m_indices.push_back(m_indices[i]);
+ ret.m_vecs.push_back(m_vecs[i]);
+ ++i;
+ }
+ else if (m_indices[i] > other.m_indices[j])
+ {
+ ret.m_indices.push_back(other.m_indices[j]);
+ ret.m_vecs.push_back(-other.m_vecs[j]);
+ ++j;
+ }
+ else
+ {
+ ret.m_indices.push_back(other.m_indices[j]);
+ ret.m_vecs.push_back(m_vecs[i] - other.m_vecs[j]);
+ ++i; ++j;
+ }
+ }
+ while (i < m_indices.size())
+ {
+ ret.m_indices.push_back(m_indices[i]);
+ ret.m_vecs.push_back(m_vecs[i]);
+ ++i;
+ }
+ while (j < other.m_indices.size())
+ {
+ ret.m_indices.push_back(other.m_indices[j]);
+ ret.m_vecs.push_back(-other.m_vecs[j]);
+ ++j;
+ }
+ ret.simplify();
+ return ret;
+ }
+
+ bool operator==(const btReducedVector& other) const
+ {
+ if (m_sz != other.m_sz)
+ return false;
+ if (m_indices.size() != other.m_indices.size())
+ return false;
+ for (int i = 0; i < m_indices.size(); ++i)
+ {
+ if (m_indices[i] != other.m_indices[i] || m_vecs[i] != other.m_vecs[i])
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool operator!=(const btReducedVector& other) const
+ {
+ return !(*this == other);
+ }
+
+ btReducedVector& operator=(const btReducedVector& other)
+ {
+ if (this == &other)
+ {
+ return *this;
+ }
+ m_sz = other.m_sz;
+ m_indices.copyFromArray(other.m_indices);
+ m_vecs.copyFromArray(other.m_vecs);
+ return *this;
+ }
+
+ btScalar dot(const btReducedVector& other) const
+ {
+ btScalar ret = 0;
+ int j = 0;
+ for (int i = 0; i < m_indices.size(); ++i)
+ {
+ while (j < other.m_indices.size() && other.m_indices[j] < m_indices[i])
+ {
+ ++j;
+ }
+ if (j < other.m_indices.size() && other.m_indices[j] == m_indices[i])
+ {
+ ret += m_vecs[i].dot(other.m_vecs[j]);
+// ++j;
+ }
+ }
+ return ret;
+ }
+
+ btScalar dot(const btAlignedObjectArray<btVector3>& other) const
+ {
+ btScalar ret = 0;
+ for (int i = 0; i < m_indices.size(); ++i)
+ {
+ ret += m_vecs[i].dot(other[m_indices[i]]);
+ }
+ return ret;
+ }
+
+ btScalar length2() const
+ {
+ return this->dot(*this);
+ }
+
+ void normalize();
+
+ // returns the projection of this onto other
+ btReducedVector proj(const btReducedVector& other) const;
+
+ bool testAdd() const;
+
+ bool testMinus() const;
+
+ bool testDot() const;
+
+ bool testMultiply() const;
+
+ void test() const;
+
+ void print() const
+ {
+ for (int i = 0; i < m_indices.size(); ++i)
+ {
+ printf("%d: (%f, %f, %f)/", m_indices[i], m_vecs[i][0],m_vecs[i][1],m_vecs[i][2]);
+ }
+ printf("\n");
+ }
+
+
+ void sort()
+ {
+ std::vector<TwoInts> tuples;
+ for (int i = 0; i < m_indices.size(); ++i)
+ {
+ TwoInts ti;
+ ti.a = i;
+ ti.b = m_indices[i];
+ tuples.push_back(ti);
+ }
+ std::sort(tuples.begin(), tuples.end());
+ btAlignedObjectArray<int> new_indices;
+ btAlignedObjectArray<btVector3> new_vecs;
+ for (int i = 0; i < tuples.size(); ++i)
+ {
+ new_indices.push_back(tuples[i].b);
+ new_vecs.push_back(m_vecs[tuples[i].a]);
+ }
+ m_indices = new_indices;
+ m_vecs = new_vecs;
+ }
+};
+
+SIMD_FORCE_INLINE btReducedVector operator*(const btReducedVector& v, btScalar s)
+{
+ btReducedVector ret(v.m_sz);
+ for (int i = 0; i < v.m_indices.size(); ++i)
+ {
+ ret.m_indices.push_back(v.m_indices[i]);
+ ret.m_vecs.push_back(s*v.m_vecs[i]);
+ }
+ ret.simplify();
+ return ret;
+}
+
+SIMD_FORCE_INLINE btReducedVector operator*(btScalar s, const btReducedVector& v)
+{
+ return v*s;
+}
+
+SIMD_FORCE_INLINE btReducedVector operator/(const btReducedVector& v, btScalar s)
+{
+ return v * (1.0/s);
+}
+
+SIMD_FORCE_INLINE btReducedVector& operator/=(btReducedVector& v, btScalar s)
+{
+ v = v/s;
+ return v;
+}
+
+SIMD_FORCE_INLINE btReducedVector& operator+=(btReducedVector& v1, const btReducedVector& v2)
+{
+ v1 = v1+v2;
+ return v1;
+}
+
+SIMD_FORCE_INLINE btReducedVector& operator-=(btReducedVector& v1, const btReducedVector& v2)
+{
+ v1 = v1-v2;
+ return v1;
+}
+
+#endif /* btReducedVectors_h */
diff --git a/thirdparty/bullet/btBulletCollisionAll.cpp b/thirdparty/bullet/btBulletCollisionAll.cpp
index 2851fb3b73..4a3ec8dd6f 100644
--- a/thirdparty/bullet/btBulletCollisionAll.cpp
+++ b/thirdparty/bullet/btBulletCollisionAll.cpp
@@ -23,6 +23,7 @@
#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp"
#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp"
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp"
#include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp"
#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp"
#include "BulletCollision/CollisionDispatch/btCollisionObject.cpp"
diff --git a/thirdparty/bullet/btLinearMathAll.cpp b/thirdparty/bullet/btLinearMathAll.cpp
index 808f412803..d05a19e630 100644
--- a/thirdparty/bullet/btLinearMathAll.cpp
+++ b/thirdparty/bullet/btLinearMathAll.cpp
@@ -8,6 +8,7 @@
#include "LinearMath/btConvexHullComputer.cpp"
#include "LinearMath/btQuickprof.cpp"
#include "LinearMath/btThreads.cpp"
+#include "LinearMath/btReducedVector.cpp"
#include "LinearMath/TaskScheduler/btTaskScheduler.cpp"
#include "LinearMath/TaskScheduler/btThreadSupportPosix.cpp"
#include "LinearMath/TaskScheduler/btThreadSupportWin32.cpp"
diff --git a/thirdparty/enet/LICENSE b/thirdparty/enet/LICENSE
index 78d9dcf613..6906f8eb0b 100644
--- a/thirdparty/enet/LICENSE
+++ b/thirdparty/enet/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2002-2019 Lee Salzman
+Copyright (c) 2002-2020 Lee Salzman
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h
index ac7552adb2..3900353c34 100644
--- a/thirdparty/enet/enet/enet.h
+++ b/thirdparty/enet/enet/enet.h
@@ -22,7 +22,7 @@ extern "C"
#define ENET_VERSION_MAJOR 1
#define ENET_VERSION_MINOR 3
-#define ENET_VERSION_PATCH 14
+#define ENET_VERSION_PATCH 15
#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
#define ENET_VERSION_GET_MAJOR(version) (((version)>>16)&0xFF)
#define ENET_VERSION_GET_MINOR(version) (((version)>>8)&0xFF)
@@ -248,6 +248,11 @@ typedef struct _ENetChannel
ENetList incomingUnreliableCommands;
} ENetChannel;
+typedef enum _ENetPeerFlag
+{
+ ENET_PEER_FLAG_NEEDS_DISPATCH = (1 << 0)
+} ENetPeerFlag;
+
/**
* An ENet peer which data packets may be sent or received from.
*
@@ -309,7 +314,9 @@ typedef struct _ENetPeer
ENetList outgoingReliableCommands;
ENetList outgoingUnreliableCommands;
ENetList dispatchedCommands;
- int needsDispatch;
+ enet_uint16 flags;
+ enet_uint8 roundTripTimeRemainder;
+ enet_uint8 roundTripTimeVarianceRemainder;
enet_uint16 incomingUnsequencedGroup;
enet_uint16 outgoingUnsequencedGroup;
enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32];
diff --git a/thirdparty/enet/enet/utility.h b/thirdparty/enet/enet/utility.h
index e48a476be3..b04bb7a5b3 100644
--- a/thirdparty/enet/enet/utility.h
+++ b/thirdparty/enet/enet/utility.h
@@ -7,6 +7,7 @@
#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
+#define ENET_DIFFERENCE(x, y) ((x) < (y) ? (y) - (x) : (x) - (y))
#endif /* __ENET_UTILITY_H__ */
diff --git a/thirdparty/enet/patches/dtls_support.patch b/thirdparty/enet/patches/dtls_support.patch
new file mode 100644
index 0000000000..ce3480a858
--- /dev/null
+++ b/thirdparty/enet/patches/dtls_support.patch
@@ -0,0 +1,13 @@
+diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h
+index 966e3a465d..ac7552adb2 100644
+--- a/thirdparty/enet/enet/enet.h
++++ b/thirdparty/enet/enet/enet.h
+@@ -578,6 +578,8 @@ ENET_API void enet_host_channel_limit (ENetHost *, size_t);
+ ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
+ extern void enet_host_bandwidth_throttle (ENetHost *);
+ extern enet_uint32 enet_host_random_seed (void);
++ENET_API void enet_host_dtls_server_setup (ENetHost *, void *, void *);
++ENET_API void enet_host_dtls_client_setup (ENetHost *, void *, uint8_t, const char *);
+
+ ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
+ ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
diff --git a/thirdparty/enet/peer.c b/thirdparty/enet/peer.c
index e2d0872bd3..1278b85a80 100644
--- a/thirdparty/enet/peer.c
+++ b/thirdparty/enet/peer.c
@@ -66,7 +66,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
peer -> packetThrottle = peer -> packetThrottleLimit;
}
else
- if (rtt < peer -> lastRoundTripTime)
+ if (rtt <= peer -> lastRoundTripTime)
{
peer -> packetThrottle += peer -> packetThrottleAcceleration;
@@ -76,7 +76,7 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
return 1;
}
else
- if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
+ if (rtt >= peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
{
if (peer -> packetThrottle > peer -> packetThrottleDeceleration)
peer -> packetThrottle -= peer -> packetThrottleDeceleration;
@@ -306,11 +306,11 @@ enet_peer_reset_queues (ENetPeer * peer)
{
ENetChannel * channel;
- if (peer -> needsDispatch)
+ if (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH)
{
enet_list_remove (& peer -> dispatchList);
- peer -> needsDispatch = 0;
+ peer -> flags &= ~ ENET_PEER_FLAG_NEEDS_DISPATCH;
}
while (! enet_list_empty (& peer -> acknowledgements))
@@ -418,6 +418,9 @@ enet_peer_reset (ENetPeer * peer)
peer -> outgoingUnsequencedGroup = 0;
peer -> eventData = 0;
peer -> totalWaitingData = 0;
+ peer -> flags = 0;
+ peer -> roundTripTimeRemainder = 0;
+ peer -> roundTripTimeVarianceRemainder = 0;
memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
@@ -724,11 +727,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
{
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
- if (! peer -> needsDispatch)
+ if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
{
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
- peer -> needsDispatch = 1;
+ peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
}
droppedCommand = currentCommand;
@@ -752,11 +755,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
{
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
- if (! peer -> needsDispatch)
+ if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
{
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
- peer -> needsDispatch = 1;
+ peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
}
}
}
@@ -768,11 +771,11 @@ enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel *
{
enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand));
- if (! peer -> needsDispatch)
+ if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
{
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
- peer -> needsDispatch = 1;
+ peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
}
droppedCommand = currentCommand;
@@ -809,11 +812,11 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch
enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand));
- if (! peer -> needsDispatch)
+ if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
{
enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
- peer -> needsDispatch = 1;
+ peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
}
if (! enet_list_empty (& channel -> incomingUnreliableCommands))
diff --git a/thirdparty/enet/protocol.c b/thirdparty/enet/protocol.c
index 28ad5fc41c..fefc0e6f0a 100644
--- a/thirdparty/enet/protocol.c
+++ b/thirdparty/enet/protocol.c
@@ -48,11 +48,11 @@ enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState st
{
enet_protocol_change_state (host, peer, state);
- if (! peer -> needsDispatch)
+ if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH))
{
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
- peer -> needsDispatch = 1;
+ peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
}
}
@@ -63,7 +63,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
{
ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue));
- peer -> needsDispatch = 0;
+ peer -> flags &= ~ ENET_PEER_FLAG_NEEDS_DISPATCH;
switch (peer -> state)
{
@@ -101,7 +101,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event)
if (! enet_list_empty (& peer -> dispatchedCommands))
{
- peer -> needsDispatch = 1;
+ peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH;
enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList);
}
@@ -851,24 +851,29 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime))
return 0;
- peer -> lastReceiveTime = host -> serviceTime;
- peer -> earliestTimeout = 0;
-
roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime);
+ roundTripTime = ENET_MAX (roundTripTime, 1);
- enet_peer_throttle (peer, roundTripTime);
+ if (peer -> lastReceiveTime > 0)
+ {
+ enet_uint32 accumRoundTripTime = (peer -> roundTripTime << 8) + peer -> roundTripTimeRemainder;
+ enet_uint32 accumRoundTripTimeVariance = (peer -> roundTripTimeVariance << 8) + peer -> roundTripTimeVarianceRemainder;
- peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4;
+ enet_peer_throttle (peer, roundTripTime);
- if (roundTripTime >= peer -> roundTripTime)
- {
- peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8;
- peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4;
+ roundTripTime <<= 8;
+ accumRoundTripTimeVariance = (accumRoundTripTimeVariance * 3 + ENET_DIFFERENCE (roundTripTime, accumRoundTripTime)) / 4;
+ accumRoundTripTime = (accumRoundTripTime * 7 + roundTripTime) / 8;
+
+ peer -> roundTripTime = accumRoundTripTime >> 8;
+ peer -> roundTripTimeRemainder = accumRoundTripTime & 0xFF;
+ peer -> roundTripTimeVariance = accumRoundTripTimeVariance >> 8;
+ peer -> roundTripTimeVarianceRemainder = accumRoundTripTimeVariance & 0xFF;
}
else
{
- peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8;
- peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4;
+ peer -> roundTripTime = roundTripTime;
+ peer -> roundTripTimeVariance = (roundTripTime + 1) / 2;
}
if (peer -> roundTripTime < peer -> lowestRoundTripTime)
@@ -881,12 +886,15 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer *
ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval)
{
peer -> lastRoundTripTime = peer -> lowestRoundTripTime;
- peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance;
+ peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 2);
peer -> lowestRoundTripTime = peer -> roundTripTime;
peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance;
peer -> packetThrottleEpoch = host -> serviceTime;
}
+ peer -> lastReceiveTime = ENET_MAX (host -> serviceTime, 1);
+ peer -> earliestTimeout = 0;
+
receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber);
commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID);
@@ -1261,7 +1269,7 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event)
}
}
- return -1;
+ return 0;
}
static void
@@ -1663,19 +1671,9 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
#ifdef ENET_DEBUG
printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0);
#endif
-
- currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4;
- if (packetLoss >= currentPeer -> packetLoss)
- {
- currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8;
- currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4;
- }
- else
- {
- currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8;
- currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4;
- }
+ currentPeer -> packetLossVariance = (currentPeer -> packetLossVariance * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4;
+ currentPeer -> packetLoss = (currentPeer -> packetLoss * 7 + packetLoss) / 8;
currentPeer -> packetLossEpoch = host -> serviceTime;
currentPeer -> packetsSent = 0;
diff --git a/thirdparty/freetype/include/freetype/config/ftconfig.h b/thirdparty/freetype/include/freetype/config/ftconfig.h
index 9466603377..14eecefc2a 100644
--- a/thirdparty/freetype/include/freetype/config/ftconfig.h
+++ b/thirdparty/freetype/include/freetype/config/ftconfig.h
@@ -4,7 +4,7 @@
*
* ANSI-specific configuration file (specification only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/config/ftheader.h b/thirdparty/freetype/include/freetype/config/ftheader.h
index 696d6ba906..e91598e207 100644
--- a/thirdparty/freetype/include/freetype/config/ftheader.h
+++ b/thirdparty/freetype/include/freetype/config/ftheader.h
@@ -4,7 +4,7 @@
*
* Build macros of the FreeType 2 library.
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/config/ftoption.h b/thirdparty/freetype/include/freetype/config/ftoption.h
index 12f47a82e8..426806d2e4 100644
--- a/thirdparty/freetype/include/freetype/config/ftoption.h
+++ b/thirdparty/freetype/include/freetype/config/ftoption.h
@@ -4,7 +4,7 @@
*
* User-selectable configuration macros (specification only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -294,6 +294,22 @@ FT_BEGIN_HEADER
/**************************************************************************
*
+ * Brotli support.
+ *
+ * FreeType uses the Brotli library to provide support for decompressing
+ * WOFF2 streams.
+ *
+ * Define this macro if you want to enable this 'feature'.
+ *
+ * If you use a build system like cmake or the `configure` script,
+ * options set by those programs have precedence, overwriting the value
+ * here with the configured one.
+ */
+/* #define FT_CONFIG_OPTION_USE_BROTLI */
+
+
+ /**************************************************************************
+ *
* Glyph Postscript Names handling
*
* By default, FreeType 2 is compiled with the 'psnames' module. This
@@ -871,9 +887,11 @@ FT_BEGIN_HEADER
*
* Compile 'autofit' module with fallback Indic script support, covering
* some scripts that the 'latin' submodule of the 'autofit' module doesn't
- * (yet) handle.
+ * (yet) handle. Currently, this needs option `AF_CONFIG_OPTION_CJK`.
*/
+#ifdef AF_CONFIG_OPTION_CJK
#define AF_CONFIG_OPTION_INDIC
+#endif
/**************************************************************************
diff --git a/thirdparty/freetype/include/freetype/config/ftstdlib.h b/thirdparty/freetype/include/freetype/config/ftstdlib.h
index 438b6145d5..d6091f8b3d 100644
--- a/thirdparty/freetype/include/freetype/config/ftstdlib.h
+++ b/thirdparty/freetype/include/freetype/config/ftstdlib.h
@@ -5,7 +5,7 @@
* ANSI-specific library and header configuration file (specification
* only).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/freetype.h b/thirdparty/freetype/include/freetype/freetype.h
index a6bb667e3a..973264b125 100644
--- a/thirdparty/freetype/include/freetype/freetype.h
+++ b/thirdparty/freetype/include/freetype/freetype.h
@@ -4,7 +4,7 @@
*
* FreeType high-level API and common types (specification only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -1239,7 +1239,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_HAS_HORIZONTAL( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_HORIZONTAL ) )
/**************************************************************************
@@ -1253,7 +1253,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_HAS_VERTICAL( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_VERTICAL )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_VERTICAL ) )
/**************************************************************************
@@ -1267,7 +1267,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_HAS_KERNING( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_KERNING )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_KERNING ) )
/**************************************************************************
@@ -1282,7 +1282,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_IS_SCALABLE( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_SCALABLE )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_SCALABLE ) )
/**************************************************************************
@@ -1301,7 +1301,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_IS_SFNT( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_SFNT )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_SFNT ) )
/**************************************************************************
@@ -1316,7 +1316,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_IS_FIXED_WIDTH( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_FIXED_WIDTH ) )
/**************************************************************************
@@ -1331,7 +1331,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_HAS_FIXED_SIZES( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_FIXED_SIZES ) )
/**************************************************************************
@@ -1357,7 +1357,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_HAS_GLYPH_NAMES( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) )
/**************************************************************************
@@ -1372,7 +1372,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_HAS_MULTIPLE_MASTERS( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS ) )
/**************************************************************************
@@ -1394,7 +1394,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_IS_NAMED_INSTANCE( face ) \
- ( (face)->face_index & 0x7FFF0000L )
+ ( !!( (face)->face_index & 0x7FFF0000L ) )
/**************************************************************************
@@ -1412,7 +1412,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_IS_VARIATION( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_VARIATION )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_VARIATION ) )
/**************************************************************************
@@ -1429,7 +1429,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_IS_CID_KEYED( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_CID_KEYED )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_CID_KEYED ) )
/**************************************************************************
@@ -1443,7 +1443,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_IS_TRICKY( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_TRICKY )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_TRICKY ) )
/**************************************************************************
@@ -1460,7 +1460,7 @@ FT_BEGIN_HEADER
*
*/
#define FT_HAS_COLOR( face ) \
- ( (face)->face_flags & FT_FACE_FLAG_COLOR )
+ ( !!( (face)->face_flags & FT_FACE_FLAG_COLOR ) )
/**************************************************************************
@@ -2078,7 +2078,8 @@ FT_BEGIN_HEADER
* The size in bytes of the file in memory.
*
* pathname ::
- * A pointer to an 8-bit file pathname.
+ * A pointer to an 8-bit file pathname. The pointer is not owned by
+ * FreeType.
*
* stream ::
* A handle to a source stream object.
@@ -4781,7 +4782,7 @@ FT_BEGIN_HEADER
*/
#define FREETYPE_MAJOR 2
#define FREETYPE_MINOR 10
-#define FREETYPE_PATCH 1
+#define FREETYPE_PATCH 2
/**************************************************************************
diff --git a/thirdparty/freetype/include/freetype/ftadvanc.h b/thirdparty/freetype/include/freetype/ftadvanc.h
index 95c38f92bd..c30472bfdb 100644
--- a/thirdparty/freetype/include/freetype/ftadvanc.h
+++ b/thirdparty/freetype/include/freetype/ftadvanc.h
@@ -4,7 +4,7 @@
*
* Quick computation of advance widths (specification only).
*
- * Copyright (C) 2008-2019 by
+ * Copyright (C) 2008-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftbbox.h b/thirdparty/freetype/include/freetype/ftbbox.h
index 22da70c0dc..294f996976 100644
--- a/thirdparty/freetype/include/freetype/ftbbox.h
+++ b/thirdparty/freetype/include/freetype/ftbbox.h
@@ -4,7 +4,7 @@
*
* FreeType exact bbox computation (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftbdf.h b/thirdparty/freetype/include/freetype/ftbdf.h
index 1c46da5985..61db27c8f8 100644
--- a/thirdparty/freetype/include/freetype/ftbdf.h
+++ b/thirdparty/freetype/include/freetype/ftbdf.h
@@ -4,7 +4,7 @@
*
* FreeType API for accessing BDF-specific strings (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftbitmap.h b/thirdparty/freetype/include/freetype/ftbitmap.h
index a6acdb9690..6c55455767 100644
--- a/thirdparty/freetype/include/freetype/ftbitmap.h
+++ b/thirdparty/freetype/include/freetype/ftbitmap.h
@@ -4,7 +4,7 @@
*
* FreeType utility functions for bitmaps (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftbzip2.h b/thirdparty/freetype/include/freetype/ftbzip2.h
index ae88cfdbdb..cb8e8458ef 100644
--- a/thirdparty/freetype/include/freetype/ftbzip2.h
+++ b/thirdparty/freetype/include/freetype/ftbzip2.h
@@ -4,7 +4,7 @@
*
* Bzip2-compressed stream support.
*
- * Copyright (C) 2010-2019 by
+ * Copyright (C) 2010-2020 by
* Joel Klinghed.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftcache.h b/thirdparty/freetype/include/freetype/ftcache.h
index 0d589d0b34..d82c4815cf 100644
--- a/thirdparty/freetype/include/freetype/ftcache.h
+++ b/thirdparty/freetype/include/freetype/ftcache.h
@@ -4,7 +4,7 @@
*
* FreeType Cache subsystem (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftcid.h b/thirdparty/freetype/include/freetype/ftcid.h
index 8eafc1c78f..85b74e0047 100644
--- a/thirdparty/freetype/include/freetype/ftcid.h
+++ b/thirdparty/freetype/include/freetype/ftcid.h
@@ -4,7 +4,7 @@
*
* FreeType API for accessing CID font information (specification).
*
- * Copyright (C) 2007-2019 by
+ * Copyright (C) 2007-2020 by
* Dereg Clegg and Michael Toftdal.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftcolor.h b/thirdparty/freetype/include/freetype/ftcolor.h
index cf18021953..b744939dd8 100644
--- a/thirdparty/freetype/include/freetype/ftcolor.h
+++ b/thirdparty/freetype/include/freetype/ftcolor.h
@@ -4,7 +4,7 @@
*
* FreeType's glyph color management (specification).
*
- * Copyright (C) 2018-2019 by
+ * Copyright (C) 2018-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -125,9 +125,9 @@ FT_BEGIN_HEADER
* The number of palettes.
*
* palette_name_ids ::
- * A read-only array of palette name IDs with `num_palettes` elements,
- * corresponding to entries like 'dark' or 'light' in the font's 'name'
- * table.
+ * An optional read-only array of palette name IDs with `num_palettes`
+ * elements, corresponding to entries like 'dark' or 'light' in the
+ * font's 'name' table.
*
* An empty name ID in the 'CPAL' table gets represented as value
* 0xFFFF.
@@ -135,8 +135,8 @@ FT_BEGIN_HEADER
* `NULL` if the font's 'CPAL' table doesn't contain appropriate data.
*
* palette_flags ::
- * A read-only array of palette flags with `num_palettes` elements.
- * Possible values are an ORed combination of
+ * An optional read-only array of palette flags with `num_palettes`
+ * elements. Possible values are an ORed combination of
* @FT_PALETTE_FOR_LIGHT_BACKGROUND and
* @FT_PALETTE_FOR_DARK_BACKGROUND.
*
@@ -147,7 +147,7 @@ FT_BEGIN_HEADER
* same size.
*
* palette_entry_name_ids ::
- * A read-only array of palette entry name IDs with
+ * An optional read-only array of palette entry name IDs with
* `num_palette_entries`. In each palette, entries with the same index
* have the same function. For example, index~0 might correspond to
* string 'outline' in the font's 'name' table to indicate that this
@@ -163,6 +163,9 @@ FT_BEGIN_HEADER
* Use function @FT_Get_Sfnt_Name to map name IDs and entry name IDs to
* name strings.
*
+ * Use function @FT_Palette_Select to get the colors associated with a
+ * palette entry.
+ *
* @since:
* 2.10
*/
diff --git a/thirdparty/freetype/include/freetype/ftdriver.h b/thirdparty/freetype/include/freetype/ftdriver.h
index 497bde9f6e..19b666ecb0 100644
--- a/thirdparty/freetype/include/freetype/ftdriver.h
+++ b/thirdparty/freetype/include/freetype/ftdriver.h
@@ -4,7 +4,7 @@
*
* FreeType API for controlling driver modules (specification only).
*
- * Copyright (C) 2017-2019 by
+ * Copyright (C) 2017-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/fterrdef.h b/thirdparty/freetype/include/freetype/fterrdef.h
index 9bc7dc65e3..895d2d4dc8 100644
--- a/thirdparty/freetype/include/freetype/fterrdef.h
+++ b/thirdparty/freetype/include/freetype/fterrdef.h
@@ -4,7 +4,7 @@
*
* FreeType error codes (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/fterrors.h b/thirdparty/freetype/include/freetype/fterrors.h
index 2b47eb2096..771bc5db52 100644
--- a/thirdparty/freetype/include/freetype/fterrors.h
+++ b/thirdparty/freetype/include/freetype/fterrors.h
@@ -4,7 +4,7 @@
*
* FreeType error code handling (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftfntfmt.h b/thirdparty/freetype/include/freetype/ftfntfmt.h
index aae0b13264..ad5a1d4162 100644
--- a/thirdparty/freetype/include/freetype/ftfntfmt.h
+++ b/thirdparty/freetype/include/freetype/ftfntfmt.h
@@ -4,7 +4,7 @@
*
* Support functions for font formats.
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftgasp.h b/thirdparty/freetype/include/freetype/ftgasp.h
index 24673d8ce1..aca1a1329d 100644
--- a/thirdparty/freetype/include/freetype/ftgasp.h
+++ b/thirdparty/freetype/include/freetype/ftgasp.h
@@ -4,7 +4,7 @@
*
* Access of TrueType's 'gasp' table (specification).
*
- * Copyright (C) 2007-2019 by
+ * Copyright (C) 2007-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftglyph.h b/thirdparty/freetype/include/freetype/ftglyph.h
index fedab8491e..ec515a3694 100644
--- a/thirdparty/freetype/include/freetype/ftglyph.h
+++ b/thirdparty/freetype/include/freetype/ftglyph.h
@@ -4,7 +4,7 @@
*
* FreeType convenience functions to handle glyphs (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftgxval.h b/thirdparty/freetype/include/freetype/ftgxval.h
index b14f637c56..691a73b94a 100644
--- a/thirdparty/freetype/include/freetype/ftgxval.h
+++ b/thirdparty/freetype/include/freetype/ftgxval.h
@@ -4,7 +4,7 @@
*
* FreeType API for validating TrueTypeGX/AAT tables (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* Masatake YAMATO, Redhat K.K,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/include/freetype/ftgzip.h b/thirdparty/freetype/include/freetype/ftgzip.h
index 418c61228e..f588c8503b 100644
--- a/thirdparty/freetype/include/freetype/ftgzip.h
+++ b/thirdparty/freetype/include/freetype/ftgzip.h
@@ -4,7 +4,7 @@
*
* Gzip-compressed stream support.
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftimage.h b/thirdparty/freetype/include/freetype/ftimage.h
index face34fe49..185967c1b8 100644
--- a/thirdparty/freetype/include/freetype/ftimage.h
+++ b/thirdparty/freetype/include/freetype/ftimage.h
@@ -5,7 +5,7 @@
* FreeType glyph image formats and default raster interface
* (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftincrem.h b/thirdparty/freetype/include/freetype/ftincrem.h
index a4db02b585..8c00cfe41c 100644
--- a/thirdparty/freetype/include/freetype/ftincrem.h
+++ b/thirdparty/freetype/include/freetype/ftincrem.h
@@ -4,7 +4,7 @@
*
* FreeType incremental loading (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftlcdfil.h b/thirdparty/freetype/include/freetype/ftlcdfil.h
index 3a19d043bb..c5516d0e0d 100644
--- a/thirdparty/freetype/include/freetype/ftlcdfil.h
+++ b/thirdparty/freetype/include/freetype/ftlcdfil.h
@@ -5,7 +5,7 @@
* FreeType API for color filtering of subpixel bitmap glyphs
* (specification).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftlist.h b/thirdparty/freetype/include/freetype/ftlist.h
index 4782892d1a..3f6079f243 100644
--- a/thirdparty/freetype/include/freetype/ftlist.h
+++ b/thirdparty/freetype/include/freetype/ftlist.h
@@ -4,7 +4,7 @@
*
* Generic list support for FreeType (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftlzw.h b/thirdparty/freetype/include/freetype/ftlzw.h
index fd22968f5a..37a53c1b3e 100644
--- a/thirdparty/freetype/include/freetype/ftlzw.h
+++ b/thirdparty/freetype/include/freetype/ftlzw.h
@@ -4,7 +4,7 @@
*
* LZW-compressed stream support.
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftmac.h b/thirdparty/freetype/include/freetype/ftmac.h
index 92b9f3dc0f..c1a0aa373e 100644
--- a/thirdparty/freetype/include/freetype/ftmac.h
+++ b/thirdparty/freetype/include/freetype/ftmac.h
@@ -4,7 +4,7 @@
*
* Additional Mac-specific API.
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftmm.h b/thirdparty/freetype/include/freetype/ftmm.h
index f2e16b6408..0d839942b9 100644
--- a/thirdparty/freetype/include/freetype/ftmm.h
+++ b/thirdparty/freetype/include/freetype/ftmm.h
@@ -4,7 +4,7 @@
*
* FreeType Multiple Master font interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftmodapi.h b/thirdparty/freetype/include/freetype/ftmodapi.h
index 8d039c4f3a..01cb5fba88 100644
--- a/thirdparty/freetype/include/freetype/ftmodapi.h
+++ b/thirdparty/freetype/include/freetype/ftmodapi.h
@@ -4,7 +4,7 @@
*
* FreeType modules public interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftmoderr.h b/thirdparty/freetype/include/freetype/ftmoderr.h
index e16993572c..5e6aeeb43e 100644
--- a/thirdparty/freetype/include/freetype/ftmoderr.h
+++ b/thirdparty/freetype/include/freetype/ftmoderr.h
@@ -4,7 +4,7 @@
*
* FreeType module error offsets (specification).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftotval.h b/thirdparty/freetype/include/freetype/ftotval.h
index c034f48959..6f46c414bd 100644
--- a/thirdparty/freetype/include/freetype/ftotval.h
+++ b/thirdparty/freetype/include/freetype/ftotval.h
@@ -4,7 +4,7 @@
*
* FreeType API for validating OpenType tables (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftoutln.h b/thirdparty/freetype/include/freetype/ftoutln.h
index b72327b703..fa295b0ab6 100644
--- a/thirdparty/freetype/include/freetype/ftoutln.h
+++ b/thirdparty/freetype/include/freetype/ftoutln.h
@@ -5,7 +5,7 @@
* Support for the FT_Outline type used to store glyph shapes of
* most scalable font formats (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftparams.h b/thirdparty/freetype/include/freetype/ftparams.h
index c374ee2f2f..255c6bb160 100644
--- a/thirdparty/freetype/include/freetype/ftparams.h
+++ b/thirdparty/freetype/include/freetype/ftparams.h
@@ -4,7 +4,7 @@
*
* FreeType API for possible FT_Parameter tags (specification only).
*
- * Copyright (C) 2017-2019 by
+ * Copyright (C) 2017-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftpfr.h b/thirdparty/freetype/include/freetype/ftpfr.h
index b4eca76eb7..58fbbb78d3 100644
--- a/thirdparty/freetype/include/freetype/ftpfr.h
+++ b/thirdparty/freetype/include/freetype/ftpfr.h
@@ -4,7 +4,7 @@
*
* FreeType API for accessing PFR-specific data (specification only).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftrender.h b/thirdparty/freetype/include/freetype/ftrender.h
index a01c774272..6845111901 100644
--- a/thirdparty/freetype/include/freetype/ftrender.h
+++ b/thirdparty/freetype/include/freetype/ftrender.h
@@ -4,7 +4,7 @@
*
* FreeType renderer modules public interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftsizes.h b/thirdparty/freetype/include/freetype/ftsizes.h
index 6c63cef2bf..7dc9295211 100644
--- a/thirdparty/freetype/include/freetype/ftsizes.h
+++ b/thirdparty/freetype/include/freetype/ftsizes.h
@@ -4,7 +4,7 @@
*
* FreeType size objects management (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftsnames.h b/thirdparty/freetype/include/freetype/ftsnames.h
index 4d43602a42..2982760635 100644
--- a/thirdparty/freetype/include/freetype/ftsnames.h
+++ b/thirdparty/freetype/include/freetype/ftsnames.h
@@ -7,7 +7,7 @@
*
* This is _not_ used to retrieve glyph names!
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftstroke.h b/thirdparty/freetype/include/freetype/ftstroke.h
index 01a9c1811c..141af7d0ba 100644
--- a/thirdparty/freetype/include/freetype/ftstroke.h
+++ b/thirdparty/freetype/include/freetype/ftstroke.h
@@ -4,7 +4,7 @@
*
* FreeType path stroker (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -114,22 +114,19 @@ FT_BEGIN_HEADER
* FT_STROKER_LINEJOIN_MITER_FIXED ::
* Used to render mitered line joins, with fixed bevels if the miter
* limit is exceeded. The outer edges of the strokes for the two
- * segments are extended until they meet at an angle. If the segments
- * meet at too sharp an angle (such that the miter would extend from
- * the intersection of the segments a distance greater than the product
- * of the miter limit value and the border radius), then a bevel join
- * (see above) is used instead. This prevents long spikes being
- * created. `FT_STROKER_LINEJOIN_MITER_FIXED` generates a miter line
- * join as used in PostScript and PDF.
+ * segments are extended until they meet at an angle. A bevel join
+ * (see above) is used if the segments meet at too sharp an angle and
+ * the outer edges meet beyond a distance corresponding to the meter
+ * limit. This prevents long spikes being created.
+ * `FT_STROKER_LINEJOIN_MITER_FIXED` generates a miter line join as
+ * used in PostScript and PDF.
*
* FT_STROKER_LINEJOIN_MITER_VARIABLE ::
* FT_STROKER_LINEJOIN_MITER ::
* Used to render mitered line joins, with variable bevels if the miter
- * limit is exceeded. The intersection of the strokes is clipped at a
- * line perpendicular to the bisector of the angle between the strokes,
- * at the distance from the intersection of the segments equal to the
- * product of the miter limit value and the border radius. This
- * prevents long spikes being created.
+ * limit is exceeded. The intersection of the strokes is clipped
+ * perpendicularly to the bisector, at a distance corresponding to
+ * the miter limit. This prevents long spikes being created.
* `FT_STROKER_LINEJOIN_MITER_VARIABLE` generates a mitered line join
* as used in XPS. `FT_STROKER_LINEJOIN_MITER` is an alias for
* `FT_STROKER_LINEJOIN_MITER_VARIABLE`, retained for backward
@@ -296,12 +293,17 @@ FT_BEGIN_HEADER
* The line join style.
*
* miter_limit ::
- * The miter limit for the `FT_STROKER_LINEJOIN_MITER_FIXED` and
- * `FT_STROKER_LINEJOIN_MITER_VARIABLE` line join styles, expressed as
- * 16.16 fixed-point value.
+ * The maximum reciprocal sine of half-angle at the miter join,
+ * expressed as 16.16 fixed point value.
*
* @note:
- * The radius is expressed in the same units as the outline coordinates.
+ * The `radius` is expressed in the same units as the outline
+ * coordinates.
+ *
+ * The `miter_limit` multiplied by the `radius` gives the maximum size
+ * of a miter spike, at which it is clipped for
+ * @FT_STROKER_LINEJOIN_MITER_VARIABLE or replaced with a bevel join for
+ * @FT_STROKER_LINEJOIN_MITER_FIXED.
*
* This function calls @FT_Stroker_Rewind automatically.
*/
diff --git a/thirdparty/freetype/include/freetype/ftsynth.h b/thirdparty/freetype/include/freetype/ftsynth.h
index 8754f97cee..3882e69e61 100644
--- a/thirdparty/freetype/include/freetype/ftsynth.h
+++ b/thirdparty/freetype/include/freetype/ftsynth.h
@@ -5,7 +5,7 @@
* FreeType synthesizing code for emboldening and slanting
* (specification).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftsystem.h b/thirdparty/freetype/include/freetype/ftsystem.h
index 889a6ba172..f7fecb53f3 100644
--- a/thirdparty/freetype/include/freetype/ftsystem.h
+++ b/thirdparty/freetype/include/freetype/ftsystem.h
@@ -4,7 +4,7 @@
*
* FreeType low-level system interface definition (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/fttrigon.h b/thirdparty/freetype/include/freetype/fttrigon.h
index 37e1412fdf..968df1fbfd 100644
--- a/thirdparty/freetype/include/freetype/fttrigon.h
+++ b/thirdparty/freetype/include/freetype/fttrigon.h
@@ -4,7 +4,7 @@
*
* FreeType trigonometric functions (specification).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/fttypes.h b/thirdparty/freetype/include/freetype/fttypes.h
index 10571505a5..cb785d98b2 100644
--- a/thirdparty/freetype/include/freetype/fttypes.h
+++ b/thirdparty/freetype/include/freetype/fttypes.h
@@ -4,7 +4,7 @@
*
* FreeType simple types definitions (specification only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ftwinfnt.h b/thirdparty/freetype/include/freetype/ftwinfnt.h
index a2fba903d2..bacb8aa373 100644
--- a/thirdparty/freetype/include/freetype/ftwinfnt.h
+++ b/thirdparty/freetype/include/freetype/ftwinfnt.h
@@ -4,7 +4,7 @@
*
* FreeType API for accessing Windows fnt-specific data.
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/autohint.h b/thirdparty/freetype/include/freetype/internal/autohint.h
index f64c28bb2c..438f9c175e 100644
--- a/thirdparty/freetype/include/freetype/internal/autohint.h
+++ b/thirdparty/freetype/include/freetype/internal/autohint.h
@@ -4,7 +4,7 @@
*
* High-level 'autohint' module-specific interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/cffotypes.h b/thirdparty/freetype/include/freetype/internal/cffotypes.h
index b26893eab3..207eeda5ff 100644
--- a/thirdparty/freetype/include/freetype/internal/cffotypes.h
+++ b/thirdparty/freetype/include/freetype/internal/cffotypes.h
@@ -4,7 +4,7 @@
*
* Basic OpenType/CFF object type definitions (specification).
*
- * Copyright (C) 2017-2019 by
+ * Copyright (C) 2017-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/cfftypes.h b/thirdparty/freetype/include/freetype/internal/cfftypes.h
index 2fc905ec79..40b0fc73c9 100644
--- a/thirdparty/freetype/include/freetype/internal/cfftypes.h
+++ b/thirdparty/freetype/include/freetype/internal/cfftypes.h
@@ -5,7 +5,7 @@
* Basic OpenType/CFF type definitions and interface (specification
* only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/ftcalc.h b/thirdparty/freetype/include/freetype/internal/ftcalc.h
index 1811fcd1ea..3054a4c497 100644
--- a/thirdparty/freetype/include/freetype/internal/ftcalc.h
+++ b/thirdparty/freetype/include/freetype/internal/ftcalc.h
@@ -4,7 +4,7 @@
*
* Arithmetic computations (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/ftdebug.h b/thirdparty/freetype/include/freetype/internal/ftdebug.h
index 54a9673afa..00d258e642 100644
--- a/thirdparty/freetype/include/freetype/internal/ftdebug.h
+++ b/thirdparty/freetype/include/freetype/internal/ftdebug.h
@@ -4,7 +4,7 @@
*
* Debugging and logging component (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/ftdrv.h b/thirdparty/freetype/include/freetype/internal/ftdrv.h
index 09e846e1c7..1dd9206c87 100644
--- a/thirdparty/freetype/include/freetype/internal/ftdrv.h
+++ b/thirdparty/freetype/include/freetype/internal/ftdrv.h
@@ -4,7 +4,7 @@
*
* FreeType internal font driver interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/ftgloadr.h b/thirdparty/freetype/include/freetype/internal/ftgloadr.h
index 770871d81b..6f3793b1c0 100644
--- a/thirdparty/freetype/include/freetype/internal/ftgloadr.h
+++ b/thirdparty/freetype/include/freetype/internal/ftgloadr.h
@@ -4,7 +4,7 @@
*
* The FreeType glyph loader (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/ftmemory.h b/thirdparty/freetype/include/freetype/internal/ftmemory.h
index 78bd3bc229..e0758c127a 100644
--- a/thirdparty/freetype/include/freetype/internal/ftmemory.h
+++ b/thirdparty/freetype/include/freetype/internal/ftmemory.h
@@ -4,7 +4,7 @@
*
* The FreeType memory management macros (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg
*
* This file is part of the FreeType project, and may only be used,
@@ -57,6 +57,14 @@ FT_BEGIN_HEADER
/*************************************************************************/
+ /* The calculation `NULL + n' is undefined in C. Even if the resulting */
+ /* pointer doesn't get dereferenced, this causes warnings with */
+ /* sanitizers. */
+ /* */
+ /* We thus provide a macro that should be used if `base' can be NULL. */
+#define FT_OFFSET( base, count ) ( (base) ? (base) + (count) : NULL )
+
+
/*
* C++ refuses to handle statements like p = (void*)anything, with `p' a
* typed pointer. Since we don't have a `typeof' operator in standard C++,
@@ -153,10 +161,10 @@ extern "C++"
(FT_Long)(size), \
&error ) )
-#define FT_MEM_FREE( ptr ) \
- FT_BEGIN_STMNT \
- ft_mem_free( memory, (ptr) ); \
- (ptr) = NULL; \
+#define FT_MEM_FREE( ptr ) \
+ FT_BEGIN_STMNT \
+ FT_DEBUG_INNER( ft_mem_free( memory, (ptr) ) ); \
+ (ptr) = NULL; \
FT_END_STMNT
#define FT_MEM_NEW( ptr ) \
diff --git a/thirdparty/freetype/include/freetype/internal/ftobjs.h b/thirdparty/freetype/include/freetype/internal/ftobjs.h
index 0c1d3e5bf2..140eebc7c6 100644
--- a/thirdparty/freetype/include/freetype/internal/ftobjs.h
+++ b/thirdparty/freetype/include/freetype/internal/ftobjs.h
@@ -4,7 +4,7 @@
*
* The FreeType private base classes (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/ftpsprop.h b/thirdparty/freetype/include/freetype/internal/ftpsprop.h
index 574837f6d4..72907c4c3a 100644
--- a/thirdparty/freetype/include/freetype/internal/ftpsprop.h
+++ b/thirdparty/freetype/include/freetype/internal/ftpsprop.h
@@ -4,7 +4,7 @@
*
* Get and set properties of PostScript drivers (specification).
*
- * Copyright (C) 2017-2019 by
+ * Copyright (C) 2017-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/ftrfork.h b/thirdparty/freetype/include/freetype/internal/ftrfork.h
index 75b3e531bb..9a275a5155 100644
--- a/thirdparty/freetype/include/freetype/internal/ftrfork.h
+++ b/thirdparty/freetype/include/freetype/internal/ftrfork.h
@@ -4,7 +4,7 @@
*
* Embedded resource forks accessor (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* Masatake YAMATO and Redhat K.K.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/ftserv.h b/thirdparty/freetype/include/freetype/internal/ftserv.h
index 8836cf3f18..bcaf4720d5 100644
--- a/thirdparty/freetype/include/freetype/internal/ftserv.h
+++ b/thirdparty/freetype/include/freetype/internal/ftserv.h
@@ -4,7 +4,7 @@
*
* The FreeType services (specification only).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/ftstream.h b/thirdparty/freetype/include/freetype/internal/ftstream.h
index a579a039b9..f3b3ef0d02 100644
--- a/thirdparty/freetype/include/freetype/internal/ftstream.h
+++ b/thirdparty/freetype/include/freetype/internal/ftstream.h
@@ -4,7 +4,7 @@
*
* Stream handling (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/fttrace.h b/thirdparty/freetype/include/freetype/internal/fttrace.h
index f5f9598046..58bd77413c 100644
--- a/thirdparty/freetype/include/freetype/internal/fttrace.h
+++ b/thirdparty/freetype/include/freetype/internal/fttrace.h
@@ -4,7 +4,7 @@
*
* Tracing handling (specification only).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -49,6 +49,7 @@ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */
FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */
FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */
FT_TRACE_DEF( sfwoff ) /* WOFF format handler (sfwoff.c) */
+FT_TRACE_DEF( sfwoff2 ) /* WOFF2 format handler (sfwoff2.c) */
FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */
FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */
FT_TRACE_DEF( ttcolr ) /* glyph layer table (ttcolr.c) */
diff --git a/thirdparty/freetype/include/freetype/internal/ftvalid.h b/thirdparty/freetype/include/freetype/internal/ftvalid.h
index 38aa06cc4e..62aea4dc68 100644
--- a/thirdparty/freetype/include/freetype/internal/ftvalid.h
+++ b/thirdparty/freetype/include/freetype/internal/ftvalid.h
@@ -4,7 +4,7 @@
*
* FreeType validation support (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/internal.h b/thirdparty/freetype/include/freetype/internal/internal.h
index 3c8830f7e4..766bf64c23 100644
--- a/thirdparty/freetype/include/freetype/internal/internal.h
+++ b/thirdparty/freetype/include/freetype/internal/internal.h
@@ -4,7 +4,7 @@
*
* Internal header files (specification only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/psaux.h b/thirdparty/freetype/include/freetype/internal/psaux.h
index f962a973de..8248a0ecdb 100644
--- a/thirdparty/freetype/include/freetype/internal/psaux.h
+++ b/thirdparty/freetype/include/freetype/internal/psaux.h
@@ -5,7 +5,7 @@
* Auxiliary functions and data structures related to PostScript fonts
* (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/pshints.h b/thirdparty/freetype/include/freetype/internal/pshints.h
index 699acea6f5..cf0c65298c 100644
--- a/thirdparty/freetype/include/freetype/internal/pshints.h
+++ b/thirdparty/freetype/include/freetype/internal/pshints.h
@@ -6,7 +6,7 @@
* recorders (specification only). These are used to support native
* T1/T2 hints in the 'type1', 'cid', and 'cff' font drivers.
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svbdf.h b/thirdparty/freetype/include/freetype/internal/services/svbdf.h
index e4786ed038..0ec9c7ccb0 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svbdf.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svbdf.h
@@ -4,7 +4,7 @@
*
* The FreeType BDF services (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svcfftl.h b/thirdparty/freetype/include/freetype/internal/services/svcfftl.h
index 6c621732da..c2f42c1d17 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svcfftl.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svcfftl.h
@@ -4,7 +4,7 @@
*
* The FreeType CFF tables loader service (specification).
*
- * Copyright (C) 2017-2019 by
+ * Copyright (C) 2017-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svcid.h b/thirdparty/freetype/include/freetype/internal/services/svcid.h
index 555a5af5b9..b8efd8147b 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svcid.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svcid.h
@@ -4,7 +4,7 @@
*
* The FreeType CID font services (specification).
*
- * Copyright (C) 2007-2019 by
+ * Copyright (C) 2007-2020 by
* Derek Clegg and Michael Toftdal.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svfntfmt.h b/thirdparty/freetype/include/freetype/internal/services/svfntfmt.h
index 6f4285ea8c..5ec84c933c 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svfntfmt.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svfntfmt.h
@@ -4,7 +4,7 @@
*
* The FreeType font format service (specification only).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svgldict.h b/thirdparty/freetype/include/freetype/internal/services/svgldict.h
index 0949621835..5a63883c90 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svgldict.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svgldict.h
@@ -4,7 +4,7 @@
*
* The FreeType glyph dictionary services (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svgxval.h b/thirdparty/freetype/include/freetype/internal/services/svgxval.h
index 0bb76f3144..d0cb10a423 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svgxval.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svgxval.h
@@ -4,7 +4,7 @@
*
* FreeType API for validating TrueTypeGX/AAT tables (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/include/freetype/internal/services/svkern.h b/thirdparty/freetype/include/freetype/internal/services/svkern.h
index f992a327c1..891c61a755 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svkern.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svkern.h
@@ -4,7 +4,7 @@
*
* The FreeType Kerning service (specification).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svmetric.h b/thirdparty/freetype/include/freetype/internal/services/svmetric.h
index d688bc7c60..06faa4b4f8 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svmetric.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svmetric.h
@@ -4,7 +4,7 @@
*
* The FreeType services for metrics variations (specification).
*
- * Copyright (C) 2016-2019 by
+ * Copyright (C) 2016-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svmm.h b/thirdparty/freetype/include/freetype/internal/services/svmm.h
index 3652f2050a..fa044c92dd 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svmm.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svmm.h
@@ -4,7 +4,7 @@
*
* The FreeType Multiple Masters and GX var services (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svotval.h b/thirdparty/freetype/include/freetype/internal/services/svotval.h
index cab4c6efbb..34ad7ca9f1 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svotval.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svotval.h
@@ -4,7 +4,7 @@
*
* The FreeType OpenType validation service (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svpfr.h b/thirdparty/freetype/include/freetype/internal/services/svpfr.h
index fd01d614dd..2dd075c5da 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svpfr.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svpfr.h
@@ -4,7 +4,7 @@
*
* Internal PFR service functions (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svpostnm.h b/thirdparty/freetype/include/freetype/internal/services/svpostnm.h
index 18e3843cbe..86ab611382 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svpostnm.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svpostnm.h
@@ -4,7 +4,7 @@
*
* The FreeType PostScript name services (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svprop.h b/thirdparty/freetype/include/freetype/internal/services/svprop.h
index e48d0151ec..8f755436a1 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svprop.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svprop.h
@@ -4,7 +4,7 @@
*
* The FreeType property service (specification).
*
- * Copyright (C) 2012-2019 by
+ * Copyright (C) 2012-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svpscmap.h b/thirdparty/freetype/include/freetype/internal/services/svpscmap.h
index dfac3bafa9..6c2ffe2e2a 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svpscmap.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svpscmap.h
@@ -4,7 +4,7 @@
*
* The FreeType PostScript charmap service (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svpsinfo.h b/thirdparty/freetype/include/freetype/internal/services/svpsinfo.h
index fb4e0e3fa9..ade24dc2ba 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svpsinfo.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svpsinfo.h
@@ -4,7 +4,7 @@
*
* The FreeType PostScript info service (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svsfnt.h b/thirdparty/freetype/include/freetype/internal/services/svsfnt.h
index 464aa209f7..f3e81ca84e 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svsfnt.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svsfnt.h
@@ -4,7 +4,7 @@
*
* The FreeType SFNT table loading service (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svttcmap.h b/thirdparty/freetype/include/freetype/internal/services/svttcmap.h
index 0fcb81371d..fbb3115ed4 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svttcmap.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svttcmap.h
@@ -4,7 +4,7 @@
*
* The FreeType TrueType/sfnt cmap extra information service.
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* Masatake YAMATO, Redhat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/include/freetype/internal/services/svtteng.h b/thirdparty/freetype/include/freetype/internal/services/svtteng.h
index a852f5c6fb..6218d9efe0 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svtteng.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svtteng.h
@@ -4,7 +4,7 @@
*
* The FreeType TrueType engine query service (specification).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svttglyf.h b/thirdparty/freetype/include/freetype/internal/services/svttglyf.h
index c8798771fb..d9894e362d 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svttglyf.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svttglyf.h
@@ -4,7 +4,7 @@
*
* The FreeType TrueType glyph service.
*
- * Copyright (C) 2007-2019 by
+ * Copyright (C) 2007-2020 by
* David Turner.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/services/svwinfnt.h b/thirdparty/freetype/include/freetype/internal/services/svwinfnt.h
index 38ee020965..377f73d450 100644
--- a/thirdparty/freetype/include/freetype/internal/services/svwinfnt.h
+++ b/thirdparty/freetype/include/freetype/internal/services/svwinfnt.h
@@ -4,7 +4,7 @@
*
* The FreeType Windows FNT/FONT service (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/sfnt.h b/thirdparty/freetype/include/freetype/internal/sfnt.h
index b19241c306..b9c81a8f37 100644
--- a/thirdparty/freetype/include/freetype/internal/sfnt.h
+++ b/thirdparty/freetype/include/freetype/internal/sfnt.h
@@ -4,7 +4,7 @@
*
* High-level 'sfnt' driver interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/t1types.h b/thirdparty/freetype/include/freetype/internal/t1types.h
index d94c8c1284..799c2939fa 100644
--- a/thirdparty/freetype/include/freetype/internal/t1types.h
+++ b/thirdparty/freetype/include/freetype/internal/t1types.h
@@ -5,7 +5,7 @@
* Basic Type1/Type2 type definitions and interface (specification
* only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/tttypes.h b/thirdparty/freetype/include/freetype/internal/tttypes.h
index 23db240e7c..1bddf102be 100644
--- a/thirdparty/freetype/include/freetype/internal/tttypes.h
+++ b/thirdparty/freetype/include/freetype/internal/tttypes.h
@@ -5,7 +5,7 @@
* Basic SFNT/TrueType type definitions and interface (specification
* only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/internal/wofftypes.h b/thirdparty/freetype/include/freetype/internal/wofftypes.h
index ba55bf883e..26159b9d3e 100644
--- a/thirdparty/freetype/include/freetype/internal/wofftypes.h
+++ b/thirdparty/freetype/include/freetype/internal/wofftypes.h
@@ -5,7 +5,7 @@
* Basic WOFF/WOFF2 type definitions and interface (specification
* only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -104,6 +104,207 @@ FT_BEGIN_HEADER
} WOFF_TableRec, *WOFF_Table;
+ /**************************************************************************
+ *
+ * @struct:
+ * WOFF2_TtcFontRec
+ *
+ * @description:
+ * Metadata for a TTC font entry in WOFF2.
+ *
+ * @fields:
+ * flavor ::
+ * TTC font flavor.
+ *
+ * num_tables ::
+ * Number of tables in TTC, indicating number of elements in
+ * `table_indices`.
+ *
+ * table_indices ::
+ * Array of table indices for each TTC font.
+ */
+ typedef struct WOFF2_TtcFontRec_
+ {
+ FT_ULong flavor;
+ FT_UShort num_tables;
+ FT_UShort* table_indices;
+
+ } WOFF2_TtcFontRec, *WOFF2_TtcFont;
+
+
+ /**************************************************************************
+ *
+ * @struct:
+ * WOFF2_HeaderRec
+ *
+ * @description:
+ * WOFF2 file format header.
+ *
+ * @fields:
+ * See
+ *
+ * https://www.w3.org/TR/WOFF2/#woff20Header
+ *
+ * @note:
+ * We don't care about the fields `reserved`, `majorVersion` and
+ * `minorVersion`, so they are not included. The `totalSfntSize` field
+ * does not necessarily represent the actual size of the uncompressed
+ * SFNT font stream, so that is used as a reference value instead.
+ */
+ typedef struct WOFF2_HeaderRec_
+ {
+ FT_ULong signature;
+ FT_ULong flavor;
+ FT_ULong length;
+ FT_UShort num_tables;
+ FT_ULong totalSfntSize;
+ FT_ULong totalCompressedSize;
+ FT_ULong metaOffset;
+ FT_ULong metaLength;
+ FT_ULong metaOrigLength;
+ FT_ULong privOffset;
+ FT_ULong privLength;
+
+ FT_ULong uncompressed_size; /* uncompressed brotli stream size */
+ FT_ULong compressed_offset; /* compressed stream offset */
+ FT_ULong header_version; /* version of original TTC Header */
+ FT_UShort num_fonts; /* number of fonts in TTC */
+ FT_ULong actual_sfnt_size; /* actual size of sfnt stream */
+
+ WOFF2_TtcFont ttc_fonts; /* metadata for fonts in a TTC */
+
+ } WOFF2_HeaderRec, *WOFF2_Header;
+
+
+ /**************************************************************************
+ *
+ * @struct:
+ * WOFF2_TableRec
+ *
+ * @description:
+ * This structure describes a given table of a WOFF2 font.
+ *
+ * @fields:
+ * See
+ *
+ * https://www.w3.org/TR/WOFF2/#table_dir_format
+ */
+ typedef struct WOFF2_TableRec_
+ {
+ FT_Byte FlagByte; /* table type and flags */
+ FT_ULong Tag; /* table file offset */
+ FT_ULong dst_length; /* uncompressed table length */
+ FT_ULong TransformLength; /* transformed length */
+
+ FT_ULong flags; /* calculated flags */
+ FT_ULong src_offset; /* compressed table offset */
+ FT_ULong src_length; /* compressed table length */
+ FT_ULong dst_offset; /* uncompressed table offset */
+
+ } WOFF2_TableRec, *WOFF2_Table;
+
+
+ /**************************************************************************
+ *
+ * @struct:
+ * WOFF2_InfoRec
+ *
+ * @description:
+ * Metadata for WOFF2 font that may be required for reconstruction of
+ * sfnt tables.
+ *
+ * @fields:
+ * header_checksum ::
+ * Checksum of SFNT offset table.
+ *
+ * num_glyphs ::
+ * Number of glyphs in the font.
+ *
+ * num_hmetrics ::
+ * `numberOfHMetrics` field in the 'hhea' table.
+ *
+ * x_mins ::
+ * `xMin` values of glyph bounding box.
+ *
+ * glyf_table ::
+ * A pointer to the `glyf' table record.
+ *
+ * loca_table ::
+ * A pointer to the `loca' table record.
+ *
+ * head_table ::
+ * A pointer to the `head' table record.
+ */
+ typedef struct WOFF2_InfoRec_
+ {
+ FT_ULong header_checksum;
+ FT_UShort num_glyphs;
+ FT_UShort num_hmetrics;
+ FT_Short* x_mins;
+
+ WOFF2_Table glyf_table;
+ WOFF2_Table loca_table;
+ WOFF2_Table head_table;
+
+ } WOFF2_InfoRec, *WOFF2_Info;
+
+
+ /**************************************************************************
+ *
+ * @struct:
+ * WOFF2_SubstreamRec
+ *
+ * @description:
+ * This structure stores information about a substream in the transformed
+ * 'glyf' table in a WOFF2 stream.
+ *
+ * @fields:
+ * start ::
+ * Beginning of the substream relative to uncompressed table stream.
+ *
+ * offset ::
+ * Offset of the substream relative to uncompressed table stream.
+ *
+ * size ::
+ * Size of the substream.
+ */
+ typedef struct WOFF2_SubstreamRec_
+ {
+ FT_ULong start;
+ FT_ULong offset;
+ FT_ULong size;
+
+ } WOFF2_SubstreamRec, *WOFF2_Substream;
+
+
+ /**************************************************************************
+ *
+ * @struct:
+ * WOFF2_PointRec
+ *
+ * @description:
+ * This structure stores information about a point in the transformed
+ * 'glyf' table in a WOFF2 stream.
+ *
+ * @fields:
+ * x ::
+ * x-coordinate of point.
+ *
+ * y ::
+ * y-coordinate of point.
+ *
+ * on_curve ::
+ * Set if point is on-curve.
+ */
+ typedef struct WOFF2_PointRec_
+ {
+ FT_Int x;
+ FT_Int y;
+ FT_Bool on_curve;
+
+ } WOFF2_PointRec, *WOFF2_Point;
+
+
FT_END_HEADER
#endif /* WOFFTYPES_H_ */
diff --git a/thirdparty/freetype/include/freetype/t1tables.h b/thirdparty/freetype/include/freetype/t1tables.h
index 645e645720..522d6ae6aa 100644
--- a/thirdparty/freetype/include/freetype/t1tables.h
+++ b/thirdparty/freetype/include/freetype/t1tables.h
@@ -5,7 +5,7 @@
* Basic Type 1/Type 2 tables definitions and interface (specification
* only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/ttnameid.h b/thirdparty/freetype/include/freetype/ttnameid.h
index cc677de75a..9a00913ee7 100644
--- a/thirdparty/freetype/include/freetype/ttnameid.h
+++ b/thirdparty/freetype/include/freetype/ttnameid.h
@@ -4,7 +4,7 @@
*
* TrueType name ID definitions (specification only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/tttables.h b/thirdparty/freetype/include/freetype/tttables.h
index d04f810218..8108db7173 100644
--- a/thirdparty/freetype/include/freetype/tttables.h
+++ b/thirdparty/freetype/include/freetype/tttables.h
@@ -5,7 +5,7 @@
* Basic SFNT/TrueType tables definitions and interface
* (specification only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/include/freetype/tttags.h b/thirdparty/freetype/include/freetype/tttags.h
index bd0986eff0..f2b2a45266 100644
--- a/thirdparty/freetype/include/freetype/tttags.h
+++ b/thirdparty/freetype/include/freetype/tttags.h
@@ -4,7 +4,7 @@
*
* Tags for TrueType and OpenType tables (specification only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -107,6 +107,7 @@ FT_BEGIN_HEADER
#define TTAG_vmtx FT_MAKE_TAG( 'v', 'm', 't', 'x' )
#define TTAG_VVAR FT_MAKE_TAG( 'V', 'V', 'A', 'R' )
#define TTAG_wOFF FT_MAKE_TAG( 'w', 'O', 'F', 'F' )
+#define TTAG_wOF2 FT_MAKE_TAG( 'w', 'O', 'F', '2' )
/* used by "Keyboard.dfont" on legacy Mac OS X */
#define TTAG_0xA5kbd FT_MAKE_TAG( 0xA5, 'k', 'b', 'd' )
diff --git a/thirdparty/freetype/include/ft2build.h b/thirdparty/freetype/include/ft2build.h
index e3f4887943..195e918335 100644
--- a/thirdparty/freetype/include/ft2build.h
+++ b/thirdparty/freetype/include/ft2build.h
@@ -4,7 +4,7 @@
*
* FreeType 2 build and setup macros.
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afangles.c b/thirdparty/freetype/src/autofit/afangles.c
index 9e1f7a21ff..a2d45eb72c 100644
--- a/thirdparty/freetype/src/autofit/afangles.c
+++ b/thirdparty/freetype/src/autofit/afangles.c
@@ -5,7 +5,7 @@
* Routines used to compute vector angles with limited accuracy
* and very high speed. It also contains sorting routines (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afblue.c b/thirdparty/freetype/src/autofit/afblue.c
index b99dbeb19c..63f9ed4589 100644
--- a/thirdparty/freetype/src/autofit/afblue.c
+++ b/thirdparty/freetype/src/autofit/afblue.c
@@ -7,7 +7,7 @@
*
* Auto-fitter data for blue strings (body).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -340,6 +340,12 @@
'\0',
'\xF0', '\x90', '\x92', '\x80', ' ', '\xF0', '\x90', '\x92', '\x82', ' ', '\xF0', '\x90', '\x92', '\x86', ' ', '\xF0', '\x90', '\x92', '\x88', ' ', '\xF0', '\x90', '\x92', '\x8A', ' ', '\xF0', '\x90', '\x92', '\x92', ' ', '\xF0', '\x90', '\x92', '\xA0', ' ', '\xF0', '\x90', '\x92', '\xA9', /* ð’€ ð’‚ ð’† ð’ˆ ð’Š ð’’ ð’  ð’© */
'\0',
+ '\xF0', '\x90', '\xB4', '\x83', ' ', '\xF0', '\x90', '\xB4', '\x80', ' ', '\xF0', '\x90', '\xB4', '\x86', ' ', '\xF0', '\x90', '\xB4', '\x96', ' ', '\xF0', '\x90', '\xB4', '\x95', /* ð´ƒ ð´€ ð´† ð´– ð´• */
+ '\0',
+ '\xF0', '\x90', '\xB4', '\x94', ' ', '\xF0', '\x90', '\xB4', '\x96', ' ', '\xF0', '\x90', '\xB4', '\x95', ' ', '\xF0', '\x90', '\xB4', '\x91', ' ', '\xF0', '\x90', '\xB4', '\x90', /* ð´” ð´– ð´• ð´‘ ð´ */
+ '\0',
+ '\xD9', '\x80', /* Ù€ */
+ '\0',
'\xEA', '\xA2', '\x9C', ' ', '\xEA', '\xA2', '\x9E', ' ', '\xEA', '\xA2', '\xB3', ' ', '\xEA', '\xA2', '\x82', ' ', '\xEA', '\xA2', '\x96', ' ', '\xEA', '\xA2', '\x92', ' ', '\xEA', '\xA2', '\x9D', ' ', '\xEA', '\xA2', '\x9B', /* ꢜ ꢞ ꢳ ꢂ ꢖ ꢒ ê¢ ê¢› */
'\0',
'\xEA', '\xA2', '\x82', ' ', '\xEA', '\xA2', '\xA8', ' ', '\xEA', '\xA2', '\xBA', ' ', '\xEA', '\xA2', '\xA4', ' ', '\xEA', '\xA2', '\x8E', /* ꢂ ꢨ ꢺ ꢤ ꢎ */
@@ -687,6 +693,10 @@
{ AF_BLUE_STRING_OSMANYA_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_OSMANYA_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },
+ { AF_BLUE_STRING_ROHINGYA_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
+ { AF_BLUE_STRING_ROHINGYA_BOTTOM, 0 },
+ { AF_BLUE_STRING_ROHINGYA_JOIN, AF_BLUE_PROPERTY_LATIN_NEUTRAL },
+ { AF_BLUE_STRING_MAX, 0 },
{ AF_BLUE_STRING_SAURASHTRA_TOP, AF_BLUE_PROPERTY_LATIN_TOP },
{ AF_BLUE_STRING_SAURASHTRA_BOTTOM, 0 },
{ AF_BLUE_STRING_MAX, 0 },
diff --git a/thirdparty/freetype/src/autofit/afblue.cin b/thirdparty/freetype/src/autofit/afblue.cin
index 6545d1fd43..c6a697fee0 100644
--- a/thirdparty/freetype/src/autofit/afblue.cin
+++ b/thirdparty/freetype/src/autofit/afblue.cin
@@ -4,7 +4,7 @@
*
* Auto-fitter data for blue strings (body).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afblue.dat b/thirdparty/freetype/src/autofit/afblue.dat
index 46db43fe22..f8356ba3a1 100644
--- a/thirdparty/freetype/src/autofit/afblue.dat
+++ b/thirdparty/freetype/src/autofit/afblue.dat
@@ -2,7 +2,7 @@
//
// Auto-fitter data for blue strings.
//
-// Copyright (C) 2013-2019 by
+// Copyright (C) 2013-2020 by
// David Turner, Robert Wilhelm, and Werner Lemberg.
//
// This file is part of the FreeType project, and may only be used,
@@ -443,6 +443,13 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN:
AF_BLUE_STRING_OSMANYA_BOTTOM
"ð’€ ð’‚ ð’† ð’ˆ ð’Š ð’’ ð’  ð’©"
+ AF_BLUE_STRING_ROHINGYA_TOP
+ "ð´ƒ ð´€ ð´† ð´– ð´•"
+ AF_BLUE_STRING_ROHINGYA_BOTTOM
+ "ð´” ð´– ð´• ð´‘ ð´"
+ AF_BLUE_STRING_ROHINGYA_JOIN
+ "Ù€"
+
AF_BLUE_STRING_SAURASHTRA_TOP
"ꢜ ꢞ ꢳ ꢂ ꢖ ꢒ ê¢ ê¢›"
AF_BLUE_STRING_SAURASHTRA_BOTTOM
@@ -1002,6 +1009,12 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN:
{ AF_BLUE_STRING_OSMANYA_BOTTOM, 0 }
{ AF_BLUE_STRING_MAX, 0 }
+ AF_BLUE_STRINGSET_ROHG
+ { AF_BLUE_STRING_ROHINGYA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
+ { AF_BLUE_STRING_ROHINGYA_BOTTOM, 0 }
+ { AF_BLUE_STRING_ROHINGYA_JOIN, AF_BLUE_PROPERTY_LATIN_NEUTRAL }
+ { AF_BLUE_STRING_MAX, 0 }
+
AF_BLUE_STRINGSET_SAUR
{ AF_BLUE_STRING_SAURASHTRA_TOP, AF_BLUE_PROPERTY_LATIN_TOP }
{ AF_BLUE_STRING_SAURASHTRA_BOTTOM, 0 }
diff --git a/thirdparty/freetype/src/autofit/afblue.h b/thirdparty/freetype/src/autofit/afblue.h
index b69b1df521..2b6a5cdda4 100644
--- a/thirdparty/freetype/src/autofit/afblue.h
+++ b/thirdparty/freetype/src/autofit/afblue.h
@@ -7,7 +7,7 @@
*
* Auto-fitter data for blue strings (specification).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -234,36 +234,39 @@ FT_BEGIN_HEADER
AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4095,
AF_BLUE_STRING_OSMANYA_TOP = 4110,
AF_BLUE_STRING_OSMANYA_BOTTOM = 4150,
- AF_BLUE_STRING_SAURASHTRA_TOP = 4190,
- AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4222,
- AF_BLUE_STRING_SHAVIAN_TOP = 4242,
- AF_BLUE_STRING_SHAVIAN_BOTTOM = 4252,
- AF_BLUE_STRING_SHAVIAN_DESCENDER = 4277,
- AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4287,
- AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4322,
- AF_BLUE_STRING_SINHALA_TOP = 4337,
- AF_BLUE_STRING_SINHALA_BOTTOM = 4369,
- AF_BLUE_STRING_SINHALA_DESCENDER = 4401,
- AF_BLUE_STRING_SUNDANESE_TOP = 4445,
- AF_BLUE_STRING_SUNDANESE_BOTTOM = 4469,
- AF_BLUE_STRING_SUNDANESE_DESCENDER = 4501,
- AF_BLUE_STRING_TAI_VIET_TOP = 4509,
- AF_BLUE_STRING_TAI_VIET_BOTTOM = 4529,
- AF_BLUE_STRING_TAMIL_TOP = 4541,
- AF_BLUE_STRING_TAMIL_BOTTOM = 4573,
- AF_BLUE_STRING_TELUGU_TOP = 4605,
- AF_BLUE_STRING_TELUGU_BOTTOM = 4633,
- AF_BLUE_STRING_THAI_TOP = 4661,
- AF_BLUE_STRING_THAI_BOTTOM = 4685,
- AF_BLUE_STRING_THAI_ASCENDER = 4713,
- AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4725,
- AF_BLUE_STRING_THAI_DESCENDER = 4737,
- AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4753,
- AF_BLUE_STRING_THAI_DIGIT_TOP = 4761,
- AF_BLUE_STRING_TIFINAGH = 4773,
- AF_BLUE_STRING_VAI_TOP = 4805,
- AF_BLUE_STRING_VAI_BOTTOM = 4837,
- af_blue_1_1 = 4868,
+ AF_BLUE_STRING_ROHINGYA_TOP = 4190,
+ AF_BLUE_STRING_ROHINGYA_BOTTOM = 4215,
+ AF_BLUE_STRING_ROHINGYA_JOIN = 4240,
+ AF_BLUE_STRING_SAURASHTRA_TOP = 4243,
+ AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4275,
+ AF_BLUE_STRING_SHAVIAN_TOP = 4295,
+ AF_BLUE_STRING_SHAVIAN_BOTTOM = 4305,
+ AF_BLUE_STRING_SHAVIAN_DESCENDER = 4330,
+ AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4340,
+ AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4375,
+ AF_BLUE_STRING_SINHALA_TOP = 4390,
+ AF_BLUE_STRING_SINHALA_BOTTOM = 4422,
+ AF_BLUE_STRING_SINHALA_DESCENDER = 4454,
+ AF_BLUE_STRING_SUNDANESE_TOP = 4498,
+ AF_BLUE_STRING_SUNDANESE_BOTTOM = 4522,
+ AF_BLUE_STRING_SUNDANESE_DESCENDER = 4554,
+ AF_BLUE_STRING_TAI_VIET_TOP = 4562,
+ AF_BLUE_STRING_TAI_VIET_BOTTOM = 4582,
+ AF_BLUE_STRING_TAMIL_TOP = 4594,
+ AF_BLUE_STRING_TAMIL_BOTTOM = 4626,
+ AF_BLUE_STRING_TELUGU_TOP = 4658,
+ AF_BLUE_STRING_TELUGU_BOTTOM = 4686,
+ AF_BLUE_STRING_THAI_TOP = 4714,
+ AF_BLUE_STRING_THAI_BOTTOM = 4738,
+ AF_BLUE_STRING_THAI_ASCENDER = 4766,
+ AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4778,
+ AF_BLUE_STRING_THAI_DESCENDER = 4790,
+ AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4806,
+ AF_BLUE_STRING_THAI_DIGIT_TOP = 4814,
+ AF_BLUE_STRING_TIFINAGH = 4826,
+ AF_BLUE_STRING_VAI_TOP = 4858,
+ AF_BLUE_STRING_VAI_BOTTOM = 4890,
+ af_blue_1_1 = 4921,
#ifdef AF_CONFIG_OPTION_CJK
AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1,
AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203,
@@ -365,17 +368,18 @@ FT_BEGIN_HEADER
AF_BLUE_STRINGSET_ORKH = 196,
AF_BLUE_STRINGSET_OSGE = 199,
AF_BLUE_STRINGSET_OSMA = 207,
- AF_BLUE_STRINGSET_SAUR = 210,
- AF_BLUE_STRINGSET_SHAW = 213,
- AF_BLUE_STRINGSET_SINH = 219,
- AF_BLUE_STRINGSET_SUND = 223,
- AF_BLUE_STRINGSET_TAML = 227,
- AF_BLUE_STRINGSET_TAVT = 230,
- AF_BLUE_STRINGSET_TELU = 233,
- AF_BLUE_STRINGSET_TFNG = 236,
- AF_BLUE_STRINGSET_THAI = 239,
- AF_BLUE_STRINGSET_VAII = 247,
- af_blue_2_1 = 250,
+ AF_BLUE_STRINGSET_ROHG = 210,
+ AF_BLUE_STRINGSET_SAUR = 214,
+ AF_BLUE_STRINGSET_SHAW = 217,
+ AF_BLUE_STRINGSET_SINH = 223,
+ AF_BLUE_STRINGSET_SUND = 227,
+ AF_BLUE_STRINGSET_TAML = 231,
+ AF_BLUE_STRINGSET_TAVT = 234,
+ AF_BLUE_STRINGSET_TELU = 237,
+ AF_BLUE_STRINGSET_TFNG = 240,
+ AF_BLUE_STRINGSET_THAI = 243,
+ AF_BLUE_STRINGSET_VAII = 251,
+ af_blue_2_1 = 254,
#ifdef AF_CONFIG_OPTION_CJK
AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0,
af_blue_2_1_1 = af_blue_2_1 + 2,
diff --git a/thirdparty/freetype/src/autofit/afblue.hin b/thirdparty/freetype/src/autofit/afblue.hin
index 30a28dafa5..3957027091 100644
--- a/thirdparty/freetype/src/autofit/afblue.hin
+++ b/thirdparty/freetype/src/autofit/afblue.hin
@@ -4,7 +4,7 @@
*
* Auto-fitter data for blue strings (specification).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afcjk.c b/thirdparty/freetype/src/autofit/afcjk.c
index a61689bee3..ca6ce0c60c 100644
--- a/thirdparty/freetype/src/autofit/afcjk.c
+++ b/thirdparty/freetype/src/autofit/afcjk.c
@@ -4,7 +4,7 @@
*
* Auto-fitter hinting routines for CJK writing system (body).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -806,7 +806,7 @@
{
AF_AxisHints axis = &hints->axis[dim];
AF_Segment segments = axis->segments;
- AF_Segment segment_limit = segments + axis->num_segments;
+ AF_Segment segment_limit = FT_OFFSET( segments, axis->num_segments );
FT_Error error;
AF_Segment seg;
diff --git a/thirdparty/freetype/src/autofit/afcjk.h b/thirdparty/freetype/src/autofit/afcjk.h
index 59acae5342..fd0f451aa8 100644
--- a/thirdparty/freetype/src/autofit/afcjk.h
+++ b/thirdparty/freetype/src/autofit/afcjk.h
@@ -4,7 +4,7 @@
*
* Auto-fitter hinting routines for CJK writing system (specification).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afcover.h b/thirdparty/freetype/src/autofit/afcover.h
index ff207a97e0..03085ad07e 100644
--- a/thirdparty/freetype/src/autofit/afcover.h
+++ b/thirdparty/freetype/src/autofit/afcover.h
@@ -4,7 +4,7 @@
*
* Auto-fitter coverages (specification only).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afdummy.c b/thirdparty/freetype/src/autofit/afdummy.c
index 7e07a41e7d..77d31df974 100644
--- a/thirdparty/freetype/src/autofit/afdummy.c
+++ b/thirdparty/freetype/src/autofit/afdummy.c
@@ -5,7 +5,7 @@
* Auto-fitter dummy routines to be used if no hinting should be
* performed (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afdummy.h b/thirdparty/freetype/src/autofit/afdummy.h
index ab9227d35d..efd799e84b 100644
--- a/thirdparty/freetype/src/autofit/afdummy.h
+++ b/thirdparty/freetype/src/autofit/afdummy.h
@@ -5,7 +5,7 @@
* Auto-fitter dummy routines to be used if no hinting should be
* performed (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/aferrors.h b/thirdparty/freetype/src/autofit/aferrors.h
index 2ec336f72c..6c7d0e1d70 100644
--- a/thirdparty/freetype/src/autofit/aferrors.h
+++ b/thirdparty/freetype/src/autofit/aferrors.h
@@ -4,7 +4,7 @@
*
* Autofitter error codes (specification only).
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afglobal.c b/thirdparty/freetype/src/autofit/afglobal.c
index 6a9a1e5aaa..5ad4ea9211 100644
--- a/thirdparty/freetype/src/autofit/afglobal.c
+++ b/thirdparty/freetype/src/autofit/afglobal.c
@@ -4,7 +4,7 @@
*
* Auto-fitter routines to compute global hinting values (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afglobal.h b/thirdparty/freetype/src/autofit/afglobal.h
index 52f38350db..fecf7af977 100644
--- a/thirdparty/freetype/src/autofit/afglobal.h
+++ b/thirdparty/freetype/src/autofit/afglobal.h
@@ -5,7 +5,7 @@
* Auto-fitter routines to compute global hinting values
* (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afhints.c b/thirdparty/freetype/src/autofit/afhints.c
index ed111c4117..5a123b2ba3 100644
--- a/thirdparty/freetype/src/autofit/afhints.c
+++ b/thirdparty/freetype/src/autofit/afhints.c
@@ -4,7 +4,7 @@
*
* Auto-fitter hinting routines (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afhints.h b/thirdparty/freetype/src/autofit/afhints.h
index e0cf612f0c..6397f098f0 100644
--- a/thirdparty/freetype/src/autofit/afhints.h
+++ b/thirdparty/freetype/src/autofit/afhints.h
@@ -4,7 +4,7 @@
*
* Auto-fitter hinting routines (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afindic.c b/thirdparty/freetype/src/autofit/afindic.c
index a17117c712..bc2837a26d 100644
--- a/thirdparty/freetype/src/autofit/afindic.c
+++ b/thirdparty/freetype/src/autofit/afindic.c
@@ -4,7 +4,7 @@
*
* Auto-fitter hinting routines for Indic writing system (body).
*
- * Copyright (C) 2007-2019 by
+ * Copyright (C) 2007-2020 by
* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afindic.h b/thirdparty/freetype/src/autofit/afindic.h
index bc5bc59fa5..088b88b19d 100644
--- a/thirdparty/freetype/src/autofit/afindic.h
+++ b/thirdparty/freetype/src/autofit/afindic.h
@@ -5,7 +5,7 @@
* Auto-fitter hinting routines for Indic writing system
* (specification).
*
- * Copyright (C) 2007-2019 by
+ * Copyright (C) 2007-2020 by
* Rahul Bhalerao <rahul.bhalerao@redhat.com>, <b.rahul.pm@gmail.com>.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/aflatin.c b/thirdparty/freetype/src/autofit/aflatin.c
index 27d4024882..b453fcdf69 100644
--- a/thirdparty/freetype/src/autofit/aflatin.c
+++ b/thirdparty/freetype/src/autofit/aflatin.c
@@ -4,7 +4,7 @@
*
* Auto-fitter hinting routines for latin writing system (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -1910,7 +1910,7 @@
/* sense -- this is used to better detect and ignore serifs */
{
AF_Segment segments = axis->segments;
- AF_Segment segments_end = segments + axis->num_segments;
+ AF_Segment segments_end = FT_OFFSET( segments, axis->num_segments );
for ( segment = segments; segment < segments_end; segment++ )
@@ -2314,7 +2314,7 @@
*/
{
AF_Edge edges = axis->edges;
- AF_Edge edge_limit = edges + axis->num_edges;
+ AF_Edge edge_limit = FT_OFFSET( edges, axis->num_edges );
AF_Edge edge;
diff --git a/thirdparty/freetype/src/autofit/aflatin.h b/thirdparty/freetype/src/autofit/aflatin.h
index 40479538c2..62bc4c8d44 100644
--- a/thirdparty/freetype/src/autofit/aflatin.h
+++ b/thirdparty/freetype/src/autofit/aflatin.h
@@ -5,7 +5,7 @@
* Auto-fitter hinting routines for latin writing system
* (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/aflatin2.c b/thirdparty/freetype/src/autofit/aflatin2.c
index c601ab8d9a..7bd4156a0f 100644
--- a/thirdparty/freetype/src/autofit/aflatin2.c
+++ b/thirdparty/freetype/src/autofit/aflatin2.c
@@ -9,7 +9,7 @@
*
* Auto-fitter hinting routines for latin writing system (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -21,6 +21,7 @@
*/
+#include <ft2build.h>
#include FT_ADVANCES_H
diff --git a/thirdparty/freetype/src/autofit/aflatin2.h b/thirdparty/freetype/src/autofit/aflatin2.h
index 507cef3df2..c2aebc49ac 100644
--- a/thirdparty/freetype/src/autofit/aflatin2.h
+++ b/thirdparty/freetype/src/autofit/aflatin2.h
@@ -10,7 +10,7 @@
* Auto-fitter hinting routines for latin writing system
* (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afloader.c b/thirdparty/freetype/src/autofit/afloader.c
index 83743b7be1..a53fbf2d21 100644
--- a/thirdparty/freetype/src/autofit/afloader.c
+++ b/thirdparty/freetype/src/autofit/afloader.c
@@ -4,7 +4,7 @@
*
* Auto-fitter glyph loading routines (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afloader.h b/thirdparty/freetype/src/autofit/afloader.h
index d1e0f3c093..97282371cd 100644
--- a/thirdparty/freetype/src/autofit/afloader.h
+++ b/thirdparty/freetype/src/autofit/afloader.h
@@ -4,7 +4,7 @@
*
* Auto-fitter glyph loading routines (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afmodule.c b/thirdparty/freetype/src/autofit/afmodule.c
index 3e46a3655a..0bcae4cc25 100644
--- a/thirdparty/freetype/src/autofit/afmodule.c
+++ b/thirdparty/freetype/src/autofit/afmodule.c
@@ -4,7 +4,7 @@
*
* Auto-fitter module implementation (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afmodule.h b/thirdparty/freetype/src/autofit/afmodule.h
index b410809aa8..efa0240b4b 100644
--- a/thirdparty/freetype/src/autofit/afmodule.h
+++ b/thirdparty/freetype/src/autofit/afmodule.h
@@ -4,7 +4,7 @@
*
* Auto-fitter module implementation (specification).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afranges.c b/thirdparty/freetype/src/autofit/afranges.c
index 45c8bbfc95..d6ecf88910 100644
--- a/thirdparty/freetype/src/autofit/afranges.c
+++ b/thirdparty/freetype/src/autofit/afranges.c
@@ -4,7 +4,7 @@
*
* Auto-fitter Unicode script ranges (body).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -778,6 +778,18 @@
};
+ const AF_Script_UniRangeRec af_rohg_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0x10D00, 0x10D3F ), /* Hanifi Rohingya */
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+ const AF_Script_UniRangeRec af_rohg_nonbase_uniranges[] =
+ {
+ AF_UNIRANGE_REC( 0, 0 )
+ };
+
+
const AF_Script_UniRangeRec af_saur_uniranges[] =
{
AF_UNIRANGE_REC( 0xA880, 0xA8DF ), /* Saurashtra */
diff --git a/thirdparty/freetype/src/autofit/afranges.h b/thirdparty/freetype/src/autofit/afranges.h
index d5917aefed..c2ffda4b0f 100644
--- a/thirdparty/freetype/src/autofit/afranges.h
+++ b/thirdparty/freetype/src/autofit/afranges.h
@@ -4,7 +4,7 @@
*
* Auto-fitter Unicode script ranges (specification).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afscript.h b/thirdparty/freetype/src/autofit/afscript.h
index 2da8c70183..36caaddc56 100644
--- a/thirdparty/freetype/src/autofit/afscript.h
+++ b/thirdparty/freetype/src/autofit/afscript.h
@@ -4,7 +4,7 @@
*
* Auto-fitter scripts (specification only).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -291,6 +291,12 @@
HINTING_BOTTOM_TO_TOP,
"\xF0\x90\x92\x86 \xF0\x90\x92\xA0" ) /* ð’† ð’  */
+ SCRIPT( rohg, ROHG,
+ "Hanifi Rohingya",
+ HB_SCRIPT_HANIFI_ROHINGYA,
+ HINTING_BOTTOM_TO_TOP,
+ "\xF0\x90\xB4\xB0" ) /* ð´° */
+
SCRIPT( saur, SAUR,
"Saurashtra",
HB_SCRIPT_SAURASHTRA,
diff --git a/thirdparty/freetype/src/autofit/afshaper.c b/thirdparty/freetype/src/autofit/afshaper.c
index a5191c6915..d3902db2ed 100644
--- a/thirdparty/freetype/src/autofit/afshaper.c
+++ b/thirdparty/freetype/src/autofit/afshaper.c
@@ -4,7 +4,7 @@
*
* HarfBuzz interface for accessing OpenType features (body).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afshaper.h b/thirdparty/freetype/src/autofit/afshaper.h
index 06a1e06616..a7dbf34f1a 100644
--- a/thirdparty/freetype/src/autofit/afshaper.h
+++ b/thirdparty/freetype/src/autofit/afshaper.h
@@ -4,7 +4,7 @@
*
* HarfBuzz interface for accessing OpenType features (specification).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afstyles.h b/thirdparty/freetype/src/autofit/afstyles.h
index 8d1d70812f..8d411ab0d7 100644
--- a/thirdparty/freetype/src/autofit/afstyles.h
+++ b/thirdparty/freetype/src/autofit/afstyles.h
@@ -4,7 +4,7 @@
*
* Auto-fitter styles (specification only).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -378,6 +378,13 @@
AF_BLUE_STRINGSET_OSMA,
AF_COVERAGE_DEFAULT )
+ STYLE( rohg_dflt, ROHG_DFLT,
+ "Hanifi Rohingya default style",
+ AF_WRITING_SYSTEM_LATIN,
+ AF_SCRIPT_ROHG,
+ AF_BLUE_STRINGSET_ROHG,
+ AF_COVERAGE_DEFAULT )
+
STYLE( saur_dflt, SAUR_DFLT,
"Saurashtra default style",
AF_WRITING_SYSTEM_LATIN,
diff --git a/thirdparty/freetype/src/autofit/aftypes.h b/thirdparty/freetype/src/autofit/aftypes.h
index 579003d27d..7ca0b59e32 100644
--- a/thirdparty/freetype/src/autofit/aftypes.h
+++ b/thirdparty/freetype/src/autofit/aftypes.h
@@ -4,7 +4,7 @@
*
* Auto-fitter types (specification only).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afwarp.c b/thirdparty/freetype/src/autofit/afwarp.c
index 84e9753ad9..808280df5d 100644
--- a/thirdparty/freetype/src/autofit/afwarp.c
+++ b/thirdparty/freetype/src/autofit/afwarp.c
@@ -4,7 +4,7 @@
*
* Auto-fitter warping algorithm (body).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afwarp.h b/thirdparty/freetype/src/autofit/afwarp.h
index 9a2c9a42c1..cdea23e7de 100644
--- a/thirdparty/freetype/src/autofit/afwarp.h
+++ b/thirdparty/freetype/src/autofit/afwarp.h
@@ -4,7 +4,7 @@
*
* Auto-fitter warping algorithm (specification).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/afwrtsys.h b/thirdparty/freetype/src/autofit/afwrtsys.h
index 5611cf441a..3990633d2d 100644
--- a/thirdparty/freetype/src/autofit/afwrtsys.h
+++ b/thirdparty/freetype/src/autofit/afwrtsys.h
@@ -4,7 +4,7 @@
*
* Auto-fitter writing systems (specification only).
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/autofit.c b/thirdparty/freetype/src/autofit/autofit.c
index facfec1744..88be8bf2bc 100644
--- a/thirdparty/freetype/src/autofit/autofit.c
+++ b/thirdparty/freetype/src/autofit/autofit.c
@@ -4,7 +4,7 @@
*
* Auto-fitter module (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/autofit/module.mk b/thirdparty/freetype/src/autofit/module.mk
index cf77b169f7..c32781f478 100644
--- a/thirdparty/freetype/src/autofit/module.mk
+++ b/thirdparty/freetype/src/autofit/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2003-2019 by
+# Copyright (C) 2003-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/autofit/rules.mk b/thirdparty/freetype/src/autofit/rules.mk
index c59da33a55..553ddce6b7 100644
--- a/thirdparty/freetype/src/autofit/rules.mk
+++ b/thirdparty/freetype/src/autofit/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2003-2019 by
+# Copyright (C) 2003-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/base/ftadvanc.c b/thirdparty/freetype/src/base/ftadvanc.c
index 0dfba57036..310bbba41e 100644
--- a/thirdparty/freetype/src/base/ftadvanc.c
+++ b/thirdparty/freetype/src/base/ftadvanc.c
@@ -4,7 +4,7 @@
*
* Quick computation of advance widths (body).
*
- * Copyright (C) 2008-2019 by
+ * Copyright (C) 2008-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftbase.c b/thirdparty/freetype/src/base/ftbase.c
index fb8cbfcc27..b8242bb960 100644
--- a/thirdparty/freetype/src/base/ftbase.c
+++ b/thirdparty/freetype/src/base/ftbase.c
@@ -4,7 +4,7 @@
*
* Single object library component (body only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftbase.h b/thirdparty/freetype/src/base/ftbase.h
index 35b1c47fd9..472713addf 100644
--- a/thirdparty/freetype/src/base/ftbase.h
+++ b/thirdparty/freetype/src/base/ftbase.h
@@ -4,7 +4,7 @@
*
* Private functions used in the `base' module (specification).
*
- * Copyright (C) 2008-2019 by
+ * Copyright (C) 2008-2020 by
* David Turner, Robert Wilhelm, Werner Lemberg, and suzuki toshiya.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftbbox.c b/thirdparty/freetype/src/base/ftbbox.c
index a0b2c46f7b..9d9f9c4015 100644
--- a/thirdparty/freetype/src/base/ftbbox.c
+++ b/thirdparty/freetype/src/base/ftbbox.c
@@ -4,7 +4,7 @@
*
* FreeType bbox computation (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
@@ -294,10 +294,10 @@
if ( shift > 2 )
shift = 2;
- q1 <<= shift;
- q2 <<= shift;
- q3 <<= shift;
- q4 <<= shift;
+ q1 *= 1 << shift;
+ q2 *= 1 << shift;
+ q3 *= 1 << shift;
+ q4 *= 1 << shift;
}
else
{
diff --git a/thirdparty/freetype/src/base/ftbdf.c b/thirdparty/freetype/src/base/ftbdf.c
index c0fccd7b7c..a239e5f873 100644
--- a/thirdparty/freetype/src/base/ftbdf.c
+++ b/thirdparty/freetype/src/base/ftbdf.c
@@ -4,7 +4,7 @@
*
* FreeType API for accessing BDF-specific strings (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftbitmap.c b/thirdparty/freetype/src/base/ftbitmap.c
index 0e0a76fe40..18ac4c5f34 100644
--- a/thirdparty/freetype/src/base/ftbitmap.c
+++ b/thirdparty/freetype/src/base/ftbitmap.c
@@ -4,7 +4,7 @@
*
* FreeType utility functions for bitmaps (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftcalc.c b/thirdparty/freetype/src/base/ftcalc.c
index 315dc44185..53550057b1 100644
--- a/thirdparty/freetype/src/base/ftcalc.c
+++ b/thirdparty/freetype/src/base/ftcalc.c
@@ -4,7 +4,7 @@
*
* Arithmetic computations (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftcid.c b/thirdparty/freetype/src/base/ftcid.c
index 190b23f357..17c25730e7 100644
--- a/thirdparty/freetype/src/base/ftcid.c
+++ b/thirdparty/freetype/src/base/ftcid.c
@@ -4,7 +4,7 @@
*
* FreeType API for accessing CID font information.
*
- * Copyright (C) 2007-2019 by
+ * Copyright (C) 2007-2020 by
* Derek Clegg and Michael Toftdal.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftcolor.c b/thirdparty/freetype/src/base/ftcolor.c
index 8cb057a365..986e9924a6 100644
--- a/thirdparty/freetype/src/base/ftcolor.c
+++ b/thirdparty/freetype/src/base/ftcolor.c
@@ -4,7 +4,7 @@
*
* FreeType's glyph color management (body).
*
- * Copyright (C) 2018-2019 by
+ * Copyright (C) 2018-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftdbgmem.c b/thirdparty/freetype/src/base/ftdbgmem.c
index 55cd269e1f..7f06c86006 100644
--- a/thirdparty/freetype/src/base/ftdbgmem.c
+++ b/thirdparty/freetype/src/base/ftdbgmem.c
@@ -4,7 +4,7 @@
*
* Memory debugger (body).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -621,8 +621,10 @@
if ( node->size < 0 )
ft_mem_debug_panic(
- "freeing memory block at %p more than once at (%s:%ld)\n"
- "block allocated at (%s:%ld) and released at (%s:%ld)",
+ "freeing memory block at %p more than once\n"
+ " at (%s:%ld)!\n"
+ " Block was allocated at (%s:%ld)\n"
+ " and released at (%s:%ld).",
address,
FT_FILENAME( _ft_debug_file ), _ft_debug_lineno,
FT_FILENAME( node->source->file_name ), node->source->line_no,
diff --git a/thirdparty/freetype/src/base/ftdebug.c b/thirdparty/freetype/src/base/ftdebug.c
index ec72337873..da1c1265e3 100644
--- a/thirdparty/freetype/src/base/ftdebug.c
+++ b/thirdparty/freetype/src/base/ftdebug.c
@@ -4,7 +4,7 @@
*
* Debugging and logging component (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/fterrors.c b/thirdparty/freetype/src/base/fterrors.c
index 84fe590289..8aa688fbe2 100644
--- a/thirdparty/freetype/src/base/fterrors.c
+++ b/thirdparty/freetype/src/base/fterrors.c
@@ -4,7 +4,7 @@
*
* FreeType API for error code handling.
*
- * Copyright (C) 2018-2019 by
+ * Copyright (C) 2018-2020 by
* Armin Hasitzka, David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftfntfmt.c b/thirdparty/freetype/src/base/ftfntfmt.c
index 54ba537416..95e9b6e4c1 100644
--- a/thirdparty/freetype/src/base/ftfntfmt.c
+++ b/thirdparty/freetype/src/base/ftfntfmt.c
@@ -4,7 +4,7 @@
*
* FreeType utility file for font formats (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftfstype.c b/thirdparty/freetype/src/base/ftfstype.c
index 45e2d8089b..461d857077 100644
--- a/thirdparty/freetype/src/base/ftfstype.c
+++ b/thirdparty/freetype/src/base/ftfstype.c
@@ -4,7 +4,7 @@
*
* FreeType utility file to access FSType data (body).
*
- * Copyright (C) 2008-2019 by
+ * Copyright (C) 2008-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftgasp.c b/thirdparty/freetype/src/base/ftgasp.c
index 720fb113ca..0fd80b9cd6 100644
--- a/thirdparty/freetype/src/base/ftgasp.c
+++ b/thirdparty/freetype/src/base/ftgasp.c
@@ -4,7 +4,7 @@
*
* Access of TrueType's `gasp' table (body).
*
- * Copyright (C) 2007-2019 by
+ * Copyright (C) 2007-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftgloadr.c b/thirdparty/freetype/src/base/ftgloadr.c
index bfeed461a8..6032885c6b 100644
--- a/thirdparty/freetype/src/base/ftgloadr.c
+++ b/thirdparty/freetype/src/base/ftgloadr.c
@@ -4,7 +4,7 @@
*
* The FreeType glyph loader (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg
*
* This file is part of the FreeType project, and may only be used,
@@ -146,9 +146,9 @@
FT_Outline* current = &loader->current.outline;
- current->points = base->points + base->n_points;
- current->tags = base->tags + base->n_points;
- current->contours = base->contours + base->n_contours;
+ current->points = FT_OFFSET( base->points, base->n_points );
+ current->tags = FT_OFFSET( base->tags, base->n_points );
+ current->contours = FT_OFFSET( base->contours, base->n_contours );
/* handle extra points table - if any */
if ( loader->use_extra )
@@ -169,6 +169,10 @@
FT_Memory memory = loader->memory;
+ if ( loader->max_points == 0 ||
+ loader->base.extra_points != NULL )
+ return FT_Err_Ok;
+
if ( !FT_NEW_ARRAY( loader->base.extra_points, 2 * loader->max_points ) )
{
loader->use_extra = 1;
@@ -189,7 +193,7 @@
FT_GlyphLoad current = &loader->current;
- current->subglyphs = base->subglyphs + base->num_subglyphs;
+ current->subglyphs = FT_OFFSET( base->subglyphs, base->num_subglyphs );
}
@@ -211,6 +215,10 @@
FT_UInt new_max, old_max;
+ error = FT_GlyphLoader_CreateExtra( loader );
+ if ( error )
+ return error;
+
/* check points & tags */
new_max = (FT_UInt)base->n_points + (FT_UInt)current->n_points +
n_points;
@@ -244,6 +252,10 @@
loader->max_points = new_max;
}
+ error = FT_GlyphLoader_CreateExtra( loader );
+ if ( error )
+ return error;
+
/* check contours */
old_max = loader->max_contours;
new_max = (FT_UInt)base->n_contours + (FT_UInt)current->n_contours +
diff --git a/thirdparty/freetype/src/base/ftglyph.c b/thirdparty/freetype/src/base/ftglyph.c
index e6b1327901..44654be780 100644
--- a/thirdparty/freetype/src/base/ftglyph.c
+++ b/thirdparty/freetype/src/base/ftglyph.c
@@ -4,7 +4,7 @@
*
* FreeType convenience functions to handle glyphs (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftgxval.c b/thirdparty/freetype/src/base/ftgxval.c
index 0677d26faa..fa32c5f6ca 100644
--- a/thirdparty/freetype/src/base/ftgxval.c
+++ b/thirdparty/freetype/src/base/ftgxval.c
@@ -4,7 +4,7 @@
*
* FreeType API for validating TrueTypeGX/AAT tables (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* Masatake YAMATO, Redhat K.K,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/base/ftinit.c b/thirdparty/freetype/src/base/ftinit.c
index c73cd78b83..1aab09a771 100644
--- a/thirdparty/freetype/src/base/ftinit.c
+++ b/thirdparty/freetype/src/base/ftinit.c
@@ -4,7 +4,7 @@
*
* FreeType initialization layer (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftlcdfil.c b/thirdparty/freetype/src/base/ftlcdfil.c
index d9f4af4293..d4ef93a518 100644
--- a/thirdparty/freetype/src/base/ftlcdfil.c
+++ b/thirdparty/freetype/src/base/ftlcdfil.c
@@ -4,7 +4,7 @@
*
* FreeType API for color filtering of subpixel bitmap glyphs (body).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftmac.c b/thirdparty/freetype/src/base/ftmac.c
index 5f23ceea9f..2de43a0146 100644
--- a/thirdparty/freetype/src/base/ftmac.c
+++ b/thirdparty/freetype/src/base/ftmac.c
@@ -8,7 +8,7 @@
* This file is for Mac OS X only; see builds/mac/ftoldmac.c for
* classic platforms built by MPW.
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* Just van Rossum, David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftmm.c b/thirdparty/freetype/src/base/ftmm.c
index ba9e67f008..ef2e3d9588 100644
--- a/thirdparty/freetype/src/base/ftmm.c
+++ b/thirdparty/freetype/src/base/ftmm.c
@@ -4,7 +4,7 @@
*
* Multiple Master font support (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftobjs.c b/thirdparty/freetype/src/base/ftobjs.c
index e301f8f11a..1b042614d2 100644
--- a/thirdparty/freetype/src/base/ftobjs.c
+++ b/thirdparty/freetype/src/base/ftobjs.c
@@ -4,7 +4,7 @@
*
* The FreeType private base classes (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftotval.c b/thirdparty/freetype/src/base/ftotval.c
index 007576ce6e..9f69e0c1fd 100644
--- a/thirdparty/freetype/src/base/ftotval.c
+++ b/thirdparty/freetype/src/base/ftotval.c
@@ -4,7 +4,7 @@
*
* FreeType API for validating OpenType tables (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftoutln.c b/thirdparty/freetype/src/base/ftoutln.c
index 0e2ba3475d..faaae83294 100644
--- a/thirdparty/freetype/src/base/ftoutln.c
+++ b/thirdparty/freetype/src/base/ftoutln.c
@@ -4,7 +4,7 @@
*
* FreeType outline management (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -711,7 +711,7 @@
FT_Vector* limit;
- if ( !outline || !matrix )
+ if ( !outline || !matrix || !outline->points )
return;
vec = outline->points;
diff --git a/thirdparty/freetype/src/base/ftpatent.c b/thirdparty/freetype/src/base/ftpatent.c
index 020f4646eb..077a9b03fa 100644
--- a/thirdparty/freetype/src/base/ftpatent.c
+++ b/thirdparty/freetype/src/base/ftpatent.c
@@ -5,7 +5,7 @@
* FreeType API for checking patented TrueType bytecode instructions
* (body). Obsolete, retained for backward compatibility.
*
- * Copyright (C) 2007-2019 by
+ * Copyright (C) 2007-2020 by
* David Turner.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftpfr.c b/thirdparty/freetype/src/base/ftpfr.c
index aeff1db8bd..57e65665ff 100644
--- a/thirdparty/freetype/src/base/ftpfr.c
+++ b/thirdparty/freetype/src/base/ftpfr.c
@@ -4,7 +4,7 @@
*
* FreeType API for accessing PFR-specific data (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftpsprop.c b/thirdparty/freetype/src/base/ftpsprop.c
index 52b9d453ad..c63f864c1a 100644
--- a/thirdparty/freetype/src/base/ftpsprop.c
+++ b/thirdparty/freetype/src/base/ftpsprop.c
@@ -5,7 +5,7 @@
* Get and set properties of PostScript drivers (body).
* See `ftdriver.h' for available properties.
*
- * Copyright (C) 2017-2019 by
+ * Copyright (C) 2017-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -165,9 +165,9 @@
driver->hinting_engine = *hinting_engine;
else
error = FT_ERR( Unimplemented_Feature );
-
- return error;
}
+
+ return error;
}
else if ( !ft_strcmp( property_name, "no-stem-darkening" ) )
diff --git a/thirdparty/freetype/src/base/ftrfork.c b/thirdparty/freetype/src/base/ftrfork.c
index 73b7eb0ded..1bf7800f17 100644
--- a/thirdparty/freetype/src/base/ftrfork.c
+++ b/thirdparty/freetype/src/base/ftrfork.c
@@ -4,7 +4,7 @@
*
* Embedded resource forks accessor (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* Masatake YAMATO and Redhat K.K.
*
* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are
diff --git a/thirdparty/freetype/src/base/ftsnames.c b/thirdparty/freetype/src/base/ftsnames.c
index 7ab3fe3cfa..25f5d45be5 100644
--- a/thirdparty/freetype/src/base/ftsnames.c
+++ b/thirdparty/freetype/src/base/ftsnames.c
@@ -7,7 +7,7 @@
*
* This is _not_ used to retrieve glyph names!
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftstream.c b/thirdparty/freetype/src/base/ftstream.c
index 4b0890d7fd..7dbf9b55fc 100644
--- a/thirdparty/freetype/src/base/ftstream.c
+++ b/thirdparty/freetype/src/base/ftstream.c
@@ -4,7 +4,7 @@
*
* I/O stream support (body).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -286,7 +286,7 @@
}
stream->cursor = stream->base;
- stream->limit = stream->cursor + count;
+ stream->limit = FT_OFFSET( stream->cursor, count );
stream->pos += read_bytes;
}
else
diff --git a/thirdparty/freetype/src/base/ftstroke.c b/thirdparty/freetype/src/base/ftstroke.c
index 1b2c0f657c..3369dc24b1 100644
--- a/thirdparty/freetype/src/base/ftstroke.c
+++ b/thirdparty/freetype/src/base/ftstroke.c
@@ -4,7 +4,7 @@
*
* FreeType path stroker (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -540,63 +540,52 @@
FT_Angle angle_start,
FT_Angle angle_diff )
{
- FT_Angle total, angle, step, rotate, next, theta;
- FT_Vector a, b, a2, b2;
- FT_Fixed length;
+ FT_Fixed coef;
+ FT_Vector a0, a1, a2, a3;
+ FT_Int i, arcs = 1;
FT_Error error = FT_Err_Ok;
- /* compute start point */
- FT_Vector_From_Polar( &a, radius, angle_start );
- a.x += center->x;
- a.y += center->y;
+ /* number of cubic arcs to draw */
+ while ( angle_diff > FT_ARC_CUBIC_ANGLE * arcs ||
+ -angle_diff > FT_ARC_CUBIC_ANGLE * arcs )
+ arcs++;
- total = angle_diff;
- angle = angle_start;
- rotate = ( angle_diff >= 0 ) ? FT_ANGLE_PI2 : -FT_ANGLE_PI2;
+ /* control tangents */
+ coef = FT_Tan( angle_diff / ( 4 * arcs ) );
+ coef += coef / 3;
- while ( total != 0 )
- {
- step = total;
- if ( step > FT_ARC_CUBIC_ANGLE )
- step = FT_ARC_CUBIC_ANGLE;
-
- else if ( step < -FT_ARC_CUBIC_ANGLE )
- step = -FT_ARC_CUBIC_ANGLE;
-
- next = angle + step;
- theta = step;
- if ( theta < 0 )
- theta = -theta;
+ /* compute start and first control point */
+ FT_Vector_From_Polar( &a0, radius, angle_start );
+ a1.x = FT_MulFix( -a0.y, coef );
+ a1.y = FT_MulFix( a0.x, coef );
- theta >>= 1;
+ a0.x += center->x;
+ a0.y += center->y;
+ a1.x += a0.x;
+ a1.y += a0.y;
- /* compute end point */
- FT_Vector_From_Polar( &b, radius, next );
- b.x += center->x;
- b.y += center->y;
-
- /* compute first and second control points */
- length = FT_MulDiv( radius, FT_Sin( theta ) * 4,
- ( 0x10000L + FT_Cos( theta ) ) * 3 );
-
- FT_Vector_From_Polar( &a2, length, angle + rotate );
- a2.x += a.x;
- a2.y += a.y;
+ for ( i = 1; i <= arcs; i++ )
+ {
+ /* compute end and second control point */
+ FT_Vector_From_Polar( &a3, radius,
+ angle_start + i * angle_diff / arcs );
+ a2.x = FT_MulFix( a3.y, coef );
+ a2.y = FT_MulFix( -a3.x, coef );
- FT_Vector_From_Polar( &b2, length, next - rotate );
- b2.x += b.x;
- b2.y += b.y;
+ a3.x += center->x;
+ a3.y += center->y;
+ a2.x += a3.x;
+ a2.y += a3.y;
/* add cubic arc */
- error = ft_stroke_border_cubicto( border, &a2, &b2, &b );
+ error = ft_stroke_border_cubicto( border, &a1, &a2, &a3 );
if ( error )
break;
- /* process the rest of the arc ?? */
- a = b;
- total -= step;
- angle = next;
+ /* a0 = a3; */
+ a1.x = a3.x - a2.x + a3.x;
+ a1.y = a3.y - a2.y + a3.y;
}
return error;
@@ -934,55 +923,40 @@
error = ft_stroker_arcto( stroker, side );
}
- else if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE )
+ else
{
- /* add a square cap */
- FT_Vector delta, delta2;
- FT_Angle rotate = FT_SIDE_TO_ROTATE( side );
+ /* add a square or butt cap */
+ FT_Vector middle, delta;
FT_Fixed radius = stroker->radius;
FT_StrokeBorder border = stroker->borders + side;
- FT_Vector_From_Polar( &delta2, radius, angle + rotate );
- FT_Vector_From_Polar( &delta, radius, angle );
-
- delta.x += stroker->center.x + delta2.x;
- delta.y += stroker->center.y + delta2.y;
-
- error = ft_stroke_border_lineto( border, &delta, FALSE );
- if ( error )
- goto Exit;
-
- FT_Vector_From_Polar( &delta2, radius, angle - rotate );
- FT_Vector_From_Polar( &delta, radius, angle );
-
- delta.x += delta2.x + stroker->center.x;
- delta.y += delta2.y + stroker->center.y;
+ /* compute middle point and first angle point */
+ FT_Vector_From_Polar( &middle, radius, angle );
+ delta.x = side ? middle.y : -middle.y;
+ delta.y = side ? -middle.x : middle.x;
- error = ft_stroke_border_lineto( border, &delta, FALSE );
- }
- else if ( stroker->line_cap == FT_STROKER_LINECAP_BUTT )
- {
- /* add a butt ending */
- FT_Vector delta;
- FT_Angle rotate = FT_SIDE_TO_ROTATE( side );
- FT_Fixed radius = stroker->radius;
- FT_StrokeBorder border = stroker->borders + side;
-
-
- FT_Vector_From_Polar( &delta, radius, angle + rotate );
+ if ( stroker->line_cap == FT_STROKER_LINECAP_SQUARE )
+ {
+ middle.x += stroker->center.x;
+ middle.y += stroker->center.y;
+ }
+ else /* FT_STROKER_LINECAP_BUTT */
+ {
+ middle.x = stroker->center.x;
+ middle.y = stroker->center.y;
+ }
- delta.x += stroker->center.x;
- delta.y += stroker->center.y;
+ delta.x += middle.x;
+ delta.y += middle.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
if ( error )
goto Exit;
- FT_Vector_From_Polar( &delta, radius, angle - rotate );
-
- delta.x += stroker->center.x;
- delta.y += stroker->center.y;
+ /* compute second angle point */
+ delta.x = middle.x - delta.x + middle.x;
+ delta.y = middle.y - delta.y + middle.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
}
@@ -1000,8 +974,8 @@
{
FT_StrokeBorder border = stroker->borders + side;
FT_Angle phi, theta, rotate;
- FT_Fixed length, thcos;
- FT_Vector delta;
+ FT_Fixed length;
+ FT_Vector sigma, delta;
FT_Error error = FT_Err_Ok;
FT_Bool intersect; /* use intersection of lines? */
@@ -1019,10 +993,13 @@
else
{
/* compute minimum required length of lines */
- FT_Fixed min_length = ft_pos_abs( FT_MulFix( stroker->radius,
- FT_Tan( theta ) ) );
+ FT_Fixed min_length;
+ FT_Vector_Unit( &sigma, theta );
+ min_length =
+ ft_pos_abs( FT_MulDiv( stroker->radius, sigma.y, sigma.x ) );
+
intersect = FT_BOOL( min_length &&
stroker->line_length >= min_length &&
line_length >= min_length );
@@ -1040,13 +1017,11 @@
else
{
/* compute median angle */
- phi = stroker->angle_in + theta;
-
- thcos = FT_Cos( theta );
+ phi = stroker->angle_in + theta + rotate;
- length = FT_DivFix( stroker->radius, thcos );
+ length = FT_DivFix( stroker->radius, sigma.x );
- FT_Vector_From_Polar( &delta, length, phi + rotate );
+ FT_Vector_From_Polar( &delta, length, phi );
delta.x += stroker->center.x;
delta.y += stroker->center.y;
}
@@ -1073,10 +1048,10 @@
else
{
/* this is a mitered (pointed) or beveled (truncated) corner */
- FT_Fixed sigma = 0, radius = stroker->radius;
- FT_Angle theta = 0, phi = 0;
- FT_Fixed thcos = 0;
- FT_Bool bevel, fixed_bevel;
+ FT_Fixed radius = stroker->radius;
+ FT_Vector sigma;
+ FT_Angle theta = 0, phi = 0;
+ FT_Bool bevel, fixed_bevel;
rotate = FT_SIDE_TO_ROTATE( side );
@@ -1087,26 +1062,20 @@
fixed_bevel =
FT_BOOL( stroker->line_join != FT_STROKER_LINEJOIN_MITER_VARIABLE );
+ /* check miter limit first */
if ( !bevel )
{
- theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out );
+ theta = FT_Angle_Diff( stroker->angle_in, stroker->angle_out ) / 2;
- if ( theta == FT_ANGLE_PI )
- {
- theta = rotate;
- phi = stroker->angle_in;
- }
- else
- {
- theta /= 2;
- phi = stroker->angle_in + theta + rotate;
- }
+ if ( theta == FT_ANGLE_PI2 )
+ theta = -rotate;
- thcos = FT_Cos( theta );
- sigma = FT_MulFix( stroker->miter_limit, thcos );
+ phi = stroker->angle_in + theta + rotate;
+
+ FT_Vector_From_Polar( &sigma, stroker->miter_limit, theta );
/* is miter limit exceeded? */
- if ( sigma < 0x10000L )
+ if ( sigma.x < 0x10000L )
{
/* don't create variable bevels for very small deviations; */
/* FT_Sin(x) = 0 for x <= 57 */
@@ -1133,36 +1102,34 @@
border->movable = FALSE;
error = ft_stroke_border_lineto( border, &delta, FALSE );
}
- else /* variable bevel */
+ else /* variable bevel or clipped miter */
{
/* the miter is truncated */
FT_Vector middle, delta;
- FT_Fixed length;
+ FT_Fixed coef;
- /* compute middle point */
+ /* compute middle point and first angle point */
FT_Vector_From_Polar( &middle,
FT_MulFix( radius, stroker->miter_limit ),
phi );
- middle.x += stroker->center.x;
- middle.y += stroker->center.y;
- /* compute first angle point */
- length = FT_MulDiv( radius, 0x10000L - sigma,
- ft_pos_abs( FT_Sin( theta ) ) );
+ coef = FT_DivFix( 0x10000L - sigma.x, sigma.y );
+ delta.x = FT_MulFix( middle.y, coef );
+ delta.y = FT_MulFix( -middle.x, coef );
- FT_Vector_From_Polar( &delta, length, phi + rotate );
- delta.x += middle.x;
- delta.y += middle.y;
+ middle.x += stroker->center.x;
+ middle.y += stroker->center.y;
+ delta.x += middle.x;
+ delta.y += middle.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
if ( error )
goto Exit;
/* compute second angle point */
- FT_Vector_From_Polar( &delta, length, phi - rotate );
- delta.x += middle.x;
- delta.y += middle.y;
+ delta.x = middle.x - delta.x + middle.x;
+ delta.y = middle.y - delta.y + middle.y;
error = ft_stroke_border_lineto( border, &delta, FALSE );
if ( error )
@@ -1189,7 +1156,7 @@
FT_Vector delta;
- length = FT_DivFix( stroker->radius, thcos );
+ length = FT_MulDiv( stroker->radius, stroker->miter_limit, sigma.x );
FT_Vector_From_Polar( &delta, length, phi );
delta.x += stroker->center.x;
diff --git a/thirdparty/freetype/src/base/ftsynth.c b/thirdparty/freetype/src/base/ftsynth.c
index f87ed65e75..eee6b952b4 100644
--- a/thirdparty/freetype/src/base/ftsynth.c
+++ b/thirdparty/freetype/src/base/ftsynth.c
@@ -4,7 +4,7 @@
*
* FreeType synthesizing code for emboldening and slanting (body).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftsystem.c b/thirdparty/freetype/src/base/ftsystem.c
index f92b3a03d5..290100613f 100644
--- a/thirdparty/freetype/src/base/ftsystem.c
+++ b/thirdparty/freetype/src/base/ftsystem.c
@@ -4,7 +4,7 @@
*
* ANSI-specific FreeType low-level system interface (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/fttrigon.c b/thirdparty/freetype/src/base/fttrigon.c
index 38721977c7..dbe11107bd 100644
--- a/thirdparty/freetype/src/base/fttrigon.c
+++ b/thirdparty/freetype/src/base/fttrigon.c
@@ -4,7 +4,7 @@
*
* FreeType trigonometric functions (body).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/fttype1.c b/thirdparty/freetype/src/base/fttype1.c
index 26d4f1c3a8..61778faa70 100644
--- a/thirdparty/freetype/src/base/fttype1.c
+++ b/thirdparty/freetype/src/base/fttype1.c
@@ -4,7 +4,7 @@
*
* FreeType utility file for PS names support (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftutil.c b/thirdparty/freetype/src/base/ftutil.c
index 92bd857e92..629af174b1 100644
--- a/thirdparty/freetype/src/base/ftutil.c
+++ b/thirdparty/freetype/src/base/ftutil.c
@@ -4,7 +4,7 @@
*
* FreeType utility file for memory and list management (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/ftver.rc b/thirdparty/freetype/src/base/ftver.rc
index 1354497423..fcbd9eff5f 100644
--- a/thirdparty/freetype/src/base/ftver.rc
+++ b/thirdparty/freetype/src/base/ftver.rc
@@ -4,7 +4,7 @@
/* */
/* FreeType VERSIONINFO resource for Windows DLLs. */
/* */
-/* Copyright (C) 2018-2019 by */
+/* Copyright (C) 2018-2020 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -18,8 +18,8 @@
#include<windows.h>
-#define FT_VERSION 2,10,1,0
-#define FT_VERSION_STR "2.10.1"
+#define FT_VERSION 2,10,2,0
+#define FT_VERSION_STR "2.10.2"
VS_VERSION_INFO VERSIONINFO
FILEVERSION FT_VERSION
@@ -45,7 +45,7 @@ BEGIN
VALUE "FileVersion", FT_VERSION_STR
VALUE "ProductName", "FreeType"
VALUE "ProductVersion", FT_VERSION_STR
- VALUE "LegalCopyright", "\251 2018-2019 The FreeType Project www.freetype.org. All rights reserved."
+ VALUE "LegalCopyright", "\251 2000-2020 The FreeType Project www.freetype.org. All rights reserved."
VALUE "InternalName", "freetype"
VALUE "OriginalFilename", FT_FILENAME
END
diff --git a/thirdparty/freetype/src/base/ftwinfnt.c b/thirdparty/freetype/src/base/ftwinfnt.c
index 59daa77031..77527277c2 100644
--- a/thirdparty/freetype/src/base/ftwinfnt.c
+++ b/thirdparty/freetype/src/base/ftwinfnt.c
@@ -4,7 +4,7 @@
*
* FreeType API for accessing Windows FNT specific info (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/base/rules.mk b/thirdparty/freetype/src/base/rules.mk
index 4b24c6dce7..411c4c821f 100644
--- a/thirdparty/freetype/src/base/rules.mk
+++ b/thirdparty/freetype/src/base/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/bzip2/ftbzip2.c b/thirdparty/freetype/src/bzip2/ftbzip2.c
index 1fda59b60c..e4d7a4901a 100644
--- a/thirdparty/freetype/src/bzip2/ftbzip2.c
+++ b/thirdparty/freetype/src/bzip2/ftbzip2.c
@@ -8,7 +8,7 @@
* parse compressed PCF fonts, as found with many X11 server
* distributions.
*
- * Copyright (C) 2010-2019 by
+ * Copyright (C) 2010-2020 by
* Joel Klinghed.
*
* based on `src/gzip/ftgzip.c'
diff --git a/thirdparty/freetype/src/bzip2/rules.mk b/thirdparty/freetype/src/bzip2/rules.mk
index f365c1f76d..eed0f4baa4 100644
--- a/thirdparty/freetype/src/bzip2/rules.mk
+++ b/thirdparty/freetype/src/bzip2/rules.mk
@@ -2,7 +2,7 @@
# FreeType 2 BZIP2 support configuration rules
#
-# Copyright (C) 2010-2019 by
+# Copyright (C) 2010-2020 by
# Joel Klinghed.
#
# based on `src/lzw/rules.mk'
diff --git a/thirdparty/freetype/src/cache/ftcache.c b/thirdparty/freetype/src/cache/ftcache.c
index a6a3e63ef0..4137f68690 100644
--- a/thirdparty/freetype/src/cache/ftcache.c
+++ b/thirdparty/freetype/src/cache/ftcache.c
@@ -4,7 +4,7 @@
*
* The FreeType Caching sub-system (body only).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcbasic.c b/thirdparty/freetype/src/cache/ftcbasic.c
index a473585ebc..a65a90e867 100644
--- a/thirdparty/freetype/src/cache/ftcbasic.c
+++ b/thirdparty/freetype/src/cache/ftcbasic.c
@@ -4,7 +4,7 @@
*
* The FreeType basic cache interface (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftccache.c b/thirdparty/freetype/src/cache/ftccache.c
index f38ca44ddd..1d406c4200 100644
--- a/thirdparty/freetype/src/cache/ftccache.c
+++ b/thirdparty/freetype/src/cache/ftccache.c
@@ -4,7 +4,7 @@
*
* The FreeType internal cache interface (body).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftccache.h b/thirdparty/freetype/src/cache/ftccache.h
index 140ceadb11..2996ee8080 100644
--- a/thirdparty/freetype/src/cache/ftccache.h
+++ b/thirdparty/freetype/src/cache/ftccache.h
@@ -4,7 +4,7 @@
*
* FreeType internal cache interface (specification).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftccback.h b/thirdparty/freetype/src/cache/ftccback.h
index 9321bc3d4e..252be7c2b5 100644
--- a/thirdparty/freetype/src/cache/ftccback.h
+++ b/thirdparty/freetype/src/cache/ftccback.h
@@ -4,7 +4,7 @@
*
* Callback functions of the caching sub-system (specification only).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftccmap.c b/thirdparty/freetype/src/cache/ftccmap.c
index 76ba10e3e9..a5da694d56 100644
--- a/thirdparty/freetype/src/cache/ftccmap.c
+++ b/thirdparty/freetype/src/cache/ftccmap.c
@@ -4,7 +4,7 @@
*
* FreeType CharMap cache (body)
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcerror.h b/thirdparty/freetype/src/cache/ftcerror.h
index e2d6417180..15e416ed21 100644
--- a/thirdparty/freetype/src/cache/ftcerror.h
+++ b/thirdparty/freetype/src/cache/ftcerror.h
@@ -4,7 +4,7 @@
*
* Caching sub-system error codes (specification only).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcglyph.c b/thirdparty/freetype/src/cache/ftcglyph.c
index 2a0e97d4af..559a2fb4c8 100644
--- a/thirdparty/freetype/src/cache/ftcglyph.c
+++ b/thirdparty/freetype/src/cache/ftcglyph.c
@@ -4,7 +4,7 @@
*
* FreeType Glyph Image (FT_Glyph) cache (body).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcglyph.h b/thirdparty/freetype/src/cache/ftcglyph.h
index 5a1f0e2a74..ef689f9947 100644
--- a/thirdparty/freetype/src/cache/ftcglyph.h
+++ b/thirdparty/freetype/src/cache/ftcglyph.h
@@ -4,7 +4,7 @@
*
* FreeType abstract glyph cache (specification).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcimage.c b/thirdparty/freetype/src/cache/ftcimage.c
index 9e64d51a22..7696b2e52d 100644
--- a/thirdparty/freetype/src/cache/ftcimage.c
+++ b/thirdparty/freetype/src/cache/ftcimage.c
@@ -4,7 +4,7 @@
*
* FreeType Image cache (body).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcimage.h b/thirdparty/freetype/src/cache/ftcimage.h
index dcb101fabc..f99c5074cf 100644
--- a/thirdparty/freetype/src/cache/ftcimage.h
+++ b/thirdparty/freetype/src/cache/ftcimage.h
@@ -4,7 +4,7 @@
*
* FreeType Generic Image cache (specification)
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcmanag.c b/thirdparty/freetype/src/cache/ftcmanag.c
index bd585968e3..a6f1733f64 100644
--- a/thirdparty/freetype/src/cache/ftcmanag.c
+++ b/thirdparty/freetype/src/cache/ftcmanag.c
@@ -4,7 +4,7 @@
*
* FreeType Cache Manager (body).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcmanag.h b/thirdparty/freetype/src/cache/ftcmanag.h
index 60c66c8fc8..17ade7175f 100644
--- a/thirdparty/freetype/src/cache/ftcmanag.h
+++ b/thirdparty/freetype/src/cache/ftcmanag.h
@@ -4,7 +4,7 @@
*
* FreeType Cache Manager (specification).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcmru.c b/thirdparty/freetype/src/cache/ftcmru.c
index 18a7b80054..370ae3be04 100644
--- a/thirdparty/freetype/src/cache/ftcmru.c
+++ b/thirdparty/freetype/src/cache/ftcmru.c
@@ -4,7 +4,7 @@
*
* FreeType MRU support (body).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcmru.h b/thirdparty/freetype/src/cache/ftcmru.h
index 58721ed340..1591c20807 100644
--- a/thirdparty/freetype/src/cache/ftcmru.h
+++ b/thirdparty/freetype/src/cache/ftcmru.h
@@ -4,7 +4,7 @@
*
* Simple MRU list-cache (specification).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcsbits.c b/thirdparty/freetype/src/cache/ftcsbits.c
index 06b46c896e..24e4aa1316 100644
--- a/thirdparty/freetype/src/cache/ftcsbits.c
+++ b/thirdparty/freetype/src/cache/ftcsbits.c
@@ -4,7 +4,7 @@
*
* FreeType sbits manager (body).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/ftcsbits.h b/thirdparty/freetype/src/cache/ftcsbits.h
index f1b71c2835..2517d15552 100644
--- a/thirdparty/freetype/src/cache/ftcsbits.h
+++ b/thirdparty/freetype/src/cache/ftcsbits.h
@@ -4,7 +4,7 @@
*
* A small-bitmap cache (specification).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cache/rules.mk b/thirdparty/freetype/src/cache/rules.mk
index 1618d98303..4738b5153a 100644
--- a/thirdparty/freetype/src/cache/rules.mk
+++ b/thirdparty/freetype/src/cache/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2000-2019 by
+# Copyright (C) 2000-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/cff/cff.c b/thirdparty/freetype/src/cff/cff.c
index a34ba9b710..755228bb6c 100644
--- a/thirdparty/freetype/src/cff/cff.c
+++ b/thirdparty/freetype/src/cff/cff.c
@@ -4,7 +4,7 @@
*
* FreeType OpenType driver component (body only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cffcmap.c b/thirdparty/freetype/src/cff/cffcmap.c
index 15cc94cafb..1a045765de 100644
--- a/thirdparty/freetype/src/cff/cffcmap.c
+++ b/thirdparty/freetype/src/cff/cffcmap.c
@@ -4,7 +4,7 @@
*
* CFF character mapping table (cmap) support (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cffcmap.h b/thirdparty/freetype/src/cff/cffcmap.h
index 07366bc748..319be88241 100644
--- a/thirdparty/freetype/src/cff/cffcmap.h
+++ b/thirdparty/freetype/src/cff/cffcmap.h
@@ -4,7 +4,7 @@
*
* CFF character mapping table (cmap) support (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cffdrivr.c b/thirdparty/freetype/src/cff/cffdrivr.c
index 2324989811..6d0dcd09d2 100644
--- a/thirdparty/freetype/src/cff/cffdrivr.c
+++ b/thirdparty/freetype/src/cff/cffdrivr.c
@@ -4,7 +4,7 @@
*
* OpenType font driver implementation (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cffdrivr.h b/thirdparty/freetype/src/cff/cffdrivr.h
index f2bbcfe4f1..25471d511b 100644
--- a/thirdparty/freetype/src/cff/cffdrivr.h
+++ b/thirdparty/freetype/src/cff/cffdrivr.h
@@ -4,7 +4,7 @@
*
* High-level OpenType driver interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cfferrs.h b/thirdparty/freetype/src/cff/cfferrs.h
index 78d47a156d..32be8a7637 100644
--- a/thirdparty/freetype/src/cff/cfferrs.h
+++ b/thirdparty/freetype/src/cff/cfferrs.h
@@ -4,7 +4,7 @@
*
* CFF error codes (specification only).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cffgload.c b/thirdparty/freetype/src/cff/cffgload.c
index 36aa7d1b9c..1c4e1979c4 100644
--- a/thirdparty/freetype/src/cff/cffgload.c
+++ b/thirdparty/freetype/src/cff/cffgload.c
@@ -4,7 +4,7 @@
*
* OpenType Glyph Loader (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cffgload.h b/thirdparty/freetype/src/cff/cffgload.h
index 754c55acf9..b4ad61a564 100644
--- a/thirdparty/freetype/src/cff/cffgload.h
+++ b/thirdparty/freetype/src/cff/cffgload.h
@@ -4,7 +4,7 @@
*
* OpenType Glyph Loader (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cffload.c b/thirdparty/freetype/src/cff/cffload.c
index 12efd18dc4..9f1d0e2e64 100644
--- a/thirdparty/freetype/src/cff/cffload.c
+++ b/thirdparty/freetype/src/cff/cffload.c
@@ -4,7 +4,7 @@
*
* OpenType and CFF data/program tables loader (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -2057,7 +2057,7 @@
if ( !error )
{
FT_TRACE4(( " top dictionary:\n" ));
- error = cff_parser_run( &parser, dict, dict + dict_len );
+ error = cff_parser_run( &parser, dict, FT_OFFSET( dict, dict_len ) );
}
/* clean up regardless of error */
diff --git a/thirdparty/freetype/src/cff/cffload.h b/thirdparty/freetype/src/cff/cffload.h
index 42d2696f33..1b7971293b 100644
--- a/thirdparty/freetype/src/cff/cffload.h
+++ b/thirdparty/freetype/src/cff/cffload.h
@@ -4,7 +4,7 @@
*
* OpenType & CFF data/program tables loader (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cffobjs.c b/thirdparty/freetype/src/cff/cffobjs.c
index f76245f30b..78c3cb3c2d 100644
--- a/thirdparty/freetype/src/cff/cffobjs.c
+++ b/thirdparty/freetype/src/cff/cffobjs.c
@@ -4,7 +4,7 @@
*
* OpenType objects manager (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -1018,9 +1018,9 @@
}
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
- /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
- /* has unset this flag because of the 3.0 `post' table. */
- if ( dict->cid_registry == 0xFFFFU )
+ /* CID-keyed CFF or CFF2 fonts don't have glyph names -- the SFNT */
+ /* loader has unset this flag because of the 3.0 `post' table. */
+ if ( dict->cid_registry == 0xFFFFU && !cff2 )
cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
#endif
diff --git a/thirdparty/freetype/src/cff/cffobjs.h b/thirdparty/freetype/src/cff/cffobjs.h
index 03bc78a67f..6f12b95db6 100644
--- a/thirdparty/freetype/src/cff/cffobjs.h
+++ b/thirdparty/freetype/src/cff/cffobjs.h
@@ -4,7 +4,7 @@
*
* OpenType objects manager (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cffparse.c b/thirdparty/freetype/src/cff/cffparse.c
index 008752c3ae..0d3bf34592 100644
--- a/thirdparty/freetype/src/cff/cffparse.c
+++ b/thirdparty/freetype/src/cff/cffparse.c
@@ -4,7 +4,7 @@
*
* CFF token stream parser (body)
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cffparse.h b/thirdparty/freetype/src/cff/cffparse.h
index 4e74709a2d..887110a748 100644
--- a/thirdparty/freetype/src/cff/cffparse.h
+++ b/thirdparty/freetype/src/cff/cffparse.h
@@ -4,7 +4,7 @@
*
* CFF token stream parser (specification)
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/cfftoken.h b/thirdparty/freetype/src/cff/cfftoken.h
index 063a7b3be0..4c6a53eec1 100644
--- a/thirdparty/freetype/src/cff/cfftoken.h
+++ b/thirdparty/freetype/src/cff/cfftoken.h
@@ -4,7 +4,7 @@
*
* CFF token definitions (specification only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cff/module.mk b/thirdparty/freetype/src/cff/module.mk
index 8c610959d3..bd728c6a34 100644
--- a/thirdparty/freetype/src/cff/module.mk
+++ b/thirdparty/freetype/src/cff/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/cff/rules.mk b/thirdparty/freetype/src/cff/rules.mk
index 6e2dc476ef..70bb92d506 100644
--- a/thirdparty/freetype/src/cff/rules.mk
+++ b/thirdparty/freetype/src/cff/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/cid/ciderrs.h b/thirdparty/freetype/src/cid/ciderrs.h
index be80bed3be..52ab55d684 100644
--- a/thirdparty/freetype/src/cid/ciderrs.h
+++ b/thirdparty/freetype/src/cid/ciderrs.h
@@ -4,7 +4,7 @@
*
* CID error codes (specification only).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cid/cidgload.c b/thirdparty/freetype/src/cid/cidgload.c
index f59f2880f0..daa0bddc2a 100644
--- a/thirdparty/freetype/src/cid/cidgload.c
+++ b/thirdparty/freetype/src/cid/cidgload.c
@@ -4,7 +4,7 @@
*
* CID-keyed Type1 Glyph Loader (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cid/cidgload.h b/thirdparty/freetype/src/cid/cidgload.h
index 37eba7ca7b..251c93c9f2 100644
--- a/thirdparty/freetype/src/cid/cidgload.h
+++ b/thirdparty/freetype/src/cid/cidgload.h
@@ -4,7 +4,7 @@
*
* OpenType Glyph Loader (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cid/cidload.c b/thirdparty/freetype/src/cid/cidload.c
index fce3e37da7..4723966024 100644
--- a/thirdparty/freetype/src/cid/cidload.c
+++ b/thirdparty/freetype/src/cid/cidload.c
@@ -4,7 +4,7 @@
*
* CID-keyed Type1 font loader (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -715,7 +715,7 @@
if ( ft_isdigit( *p ) )
val = (FT_Byte)( *p - '0' );
else if ( *p >= 'a' && *p <= 'f' )
- val = (FT_Byte)( *p - 'a' );
+ val = (FT_Byte)( *p - 'a' + 10 );
else if ( *p >= 'A' && *p <= 'F' )
val = (FT_Byte)( *p - 'A' + 10 );
else if ( *p == ' ' ||
diff --git a/thirdparty/freetype/src/cid/cidload.h b/thirdparty/freetype/src/cid/cidload.h
index fb9d46216d..e639f6ffef 100644
--- a/thirdparty/freetype/src/cid/cidload.h
+++ b/thirdparty/freetype/src/cid/cidload.h
@@ -4,7 +4,7 @@
*
* CID-keyed Type1 font loader (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cid/cidobjs.c b/thirdparty/freetype/src/cid/cidobjs.c
index 4e9728719b..34f72b588d 100644
--- a/thirdparty/freetype/src/cid/cidobjs.c
+++ b/thirdparty/freetype/src/cid/cidobjs.c
@@ -4,7 +4,7 @@
*
* CID objects manager (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cid/cidobjs.h b/thirdparty/freetype/src/cid/cidobjs.h
index 89c9aa74ab..efe812fd11 100644
--- a/thirdparty/freetype/src/cid/cidobjs.h
+++ b/thirdparty/freetype/src/cid/cidobjs.h
@@ -4,7 +4,7 @@
*
* CID objects manager (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cid/cidparse.c b/thirdparty/freetype/src/cid/cidparse.c
index 1be46ec328..94a36e22f5 100644
--- a/thirdparty/freetype/src/cid/cidparse.c
+++ b/thirdparty/freetype/src/cid/cidparse.c
@@ -4,7 +4,7 @@
*
* CID-keyed Type1 parser (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cid/cidparse.h b/thirdparty/freetype/src/cid/cidparse.h
index ec1f6a346d..6b2944ff57 100644
--- a/thirdparty/freetype/src/cid/cidparse.h
+++ b/thirdparty/freetype/src/cid/cidparse.h
@@ -4,7 +4,7 @@
*
* CID-keyed Type1 parser (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cid/cidriver.c b/thirdparty/freetype/src/cid/cidriver.c
index 4d91e87529..ad2f7b5cf5 100644
--- a/thirdparty/freetype/src/cid/cidriver.c
+++ b/thirdparty/freetype/src/cid/cidriver.c
@@ -4,7 +4,7 @@
*
* CID driver interface (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cid/cidriver.h b/thirdparty/freetype/src/cid/cidriver.h
index 3402fd7e99..400c2ae295 100644
--- a/thirdparty/freetype/src/cid/cidriver.h
+++ b/thirdparty/freetype/src/cid/cidriver.h
@@ -4,7 +4,7 @@
*
* High-level CID driver interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cid/cidtoken.h b/thirdparty/freetype/src/cid/cidtoken.h
index f505c9e166..e9f068bb50 100644
--- a/thirdparty/freetype/src/cid/cidtoken.h
+++ b/thirdparty/freetype/src/cid/cidtoken.h
@@ -4,7 +4,7 @@
*
* CID token definitions (specification only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/cid/module.mk b/thirdparty/freetype/src/cid/module.mk
index 875c683c72..9fb02235e6 100644
--- a/thirdparty/freetype/src/cid/module.mk
+++ b/thirdparty/freetype/src/cid/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/cid/rules.mk b/thirdparty/freetype/src/cid/rules.mk
index 2b68dd48a0..94f663c80e 100644
--- a/thirdparty/freetype/src/cid/rules.mk
+++ b/thirdparty/freetype/src/cid/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/cid/type1cid.c b/thirdparty/freetype/src/cid/type1cid.c
index d21801cec1..ba9141075f 100644
--- a/thirdparty/freetype/src/cid/type1cid.c
+++ b/thirdparty/freetype/src/cid/type1cid.c
@@ -4,7 +4,7 @@
*
* FreeType OpenType driver component (body only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/gxvalid/README b/thirdparty/freetype/src/gxvalid/README
index d493587842..2a32bab204 100644
--- a/thirdparty/freetype/src/gxvalid/README
+++ b/thirdparty/freetype/src/gxvalid/README
@@ -518,7 +518,7 @@ gxvalid: TrueType GX validator
------------------------------------------------------------------------
-Copyright (C) 2004-2019 by
+Copyright (C) 2004-2020 by
suzuki toshiya, Masatake YAMATO, Red hat K.K.,
David Turner, Robert Wilhelm, and Werner Lemberg.
diff --git a/thirdparty/freetype/src/gxvalid/gxvalid.c b/thirdparty/freetype/src/gxvalid/gxvalid.c
index 462e461bf2..cb655aeb9d 100644
--- a/thirdparty/freetype/src/gxvalid/gxvalid.c
+++ b/thirdparty/freetype/src/gxvalid/gxvalid.c
@@ -4,7 +4,7 @@
*
* FreeType validator for TrueTypeGX/AAT tables (body only).
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvalid.h b/thirdparty/freetype/src/gxvalid/gxvalid.h
index 969cd0927a..cdf1986324 100644
--- a/thirdparty/freetype/src/gxvalid/gxvalid.h
+++ b/thirdparty/freetype/src/gxvalid/gxvalid.h
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT table validation (specification only).
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvbsln.c b/thirdparty/freetype/src/gxvalid/gxvbsln.c
index f22f2545fa..ac58d4615c 100644
--- a/thirdparty/freetype/src/gxvalid/gxvbsln.c
+++ b/thirdparty/freetype/src/gxvalid/gxvbsln.c
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT bsln table validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvcommn.c b/thirdparty/freetype/src/gxvalid/gxvcommn.c
index c5cb8ebe8b..ead0f24cd3 100644
--- a/thirdparty/freetype/src/gxvalid/gxvcommn.c
+++ b/thirdparty/freetype/src/gxvalid/gxvcommn.c
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT common tables validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvcommn.h b/thirdparty/freetype/src/gxvalid/gxvcommn.h
index 334dc9dfb3..2372fc86fa 100644
--- a/thirdparty/freetype/src/gxvalid/gxvcommn.h
+++ b/thirdparty/freetype/src/gxvalid/gxvcommn.h
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT common tables validation (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxverror.h b/thirdparty/freetype/src/gxvalid/gxverror.h
index da0edb35f9..475b9f7778 100644
--- a/thirdparty/freetype/src/gxvalid/gxverror.h
+++ b/thirdparty/freetype/src/gxvalid/gxverror.h
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT validation module error codes (specification only).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvfeat.c b/thirdparty/freetype/src/gxvalid/gxvfeat.c
index e1a12a18ed..400ec8a3fb 100644
--- a/thirdparty/freetype/src/gxvalid/gxvfeat.c
+++ b/thirdparty/freetype/src/gxvalid/gxvfeat.c
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT feat table validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvfeat.h b/thirdparty/freetype/src/gxvalid/gxvfeat.h
index 6c9892910c..435dcefb09 100644
--- a/thirdparty/freetype/src/gxvalid/gxvfeat.h
+++ b/thirdparty/freetype/src/gxvalid/gxvfeat.h
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT feat table validation (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvfgen.c b/thirdparty/freetype/src/gxvalid/gxvfgen.c
index 5ecb9443c3..fe05a6f3a1 100644
--- a/thirdparty/freetype/src/gxvalid/gxvfgen.c
+++ b/thirdparty/freetype/src/gxvalid/gxvfgen.c
@@ -5,7 +5,7 @@
* Generate feature registry data for gxv `feat' validator.
* This program is derived from gxfeatreg.c in gxlayout.
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* Masatake YAMATO and Redhat K.K.
*
* This file may only be used,
diff --git a/thirdparty/freetype/src/gxvalid/gxvjust.c b/thirdparty/freetype/src/gxvalid/gxvjust.c
index a582377859..d8875b4111 100644
--- a/thirdparty/freetype/src/gxvalid/gxvjust.c
+++ b/thirdparty/freetype/src/gxvalid/gxvjust.c
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT just table validation (body).
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvkern.c b/thirdparty/freetype/src/gxvalid/gxvkern.c
index a7532335a5..ab5643eb83 100644
--- a/thirdparty/freetype/src/gxvalid/gxvkern.c
+++ b/thirdparty/freetype/src/gxvalid/gxvkern.c
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT kern table validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvlcar.c b/thirdparty/freetype/src/gxvalid/gxvlcar.c
index 13b3de3eaa..82ac1907ab 100644
--- a/thirdparty/freetype/src/gxvalid/gxvlcar.c
+++ b/thirdparty/freetype/src/gxvalid/gxvlcar.c
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT lcar table validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmod.c b/thirdparty/freetype/src/gxvalid/gxvmod.c
index eeadeb3e1d..2b8f45d1c2 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmod.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmod.c
@@ -4,7 +4,7 @@
*
* FreeType's TrueTypeGX/AAT validation module implementation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmod.h b/thirdparty/freetype/src/gxvalid/gxvmod.h
index 6ecd7312c9..bdf465f4f0 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmod.h
+++ b/thirdparty/freetype/src/gxvalid/gxvmod.h
@@ -5,7 +5,7 @@
* FreeType's TrueTypeGX/AAT validation module implementation
* (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmort.c b/thirdparty/freetype/src/gxvalid/gxvmort.c
index 288ef6988b..aae7f01a89 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmort.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmort.c
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT mort table validation (body).
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmort.h b/thirdparty/freetype/src/gxvalid/gxvmort.h
index 0619e24fb9..35a18e76a6 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmort.h
+++ b/thirdparty/freetype/src/gxvalid/gxvmort.h
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT common definition for mort table (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmort0.c b/thirdparty/freetype/src/gxvalid/gxvmort0.c
index 2c01bf95ec..d452c1ccaa 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmort0.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmort0.c
@@ -5,7 +5,7 @@
* TrueTypeGX/AAT mort table validation
* body for type0 (Indic Script Rearrangement) subtable.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmort1.c b/thirdparty/freetype/src/gxvalid/gxvmort1.c
index c71ba13351..d743f89f6e 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmort1.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmort1.c
@@ -5,7 +5,7 @@
* TrueTypeGX/AAT mort table validation
* body for type1 (Contextual Substitution) subtable.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmort2.c b/thirdparty/freetype/src/gxvalid/gxvmort2.c
index 889d3bd582..9e69e1269d 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmort2.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmort2.c
@@ -5,7 +5,7 @@
* TrueTypeGX/AAT mort table validation
* body for type2 (Ligature Substitution) subtable.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmort4.c b/thirdparty/freetype/src/gxvalid/gxvmort4.c
index f8ce6cf789..4584d204cf 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmort4.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmort4.c
@@ -5,7 +5,7 @@
* TrueTypeGX/AAT mort table validation
* body for type4 (Non-Contextual Glyph Substitution) subtable.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmort5.c b/thirdparty/freetype/src/gxvalid/gxvmort5.c
index 1ba1e5ded0..a15a24fe65 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmort5.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmort5.c
@@ -5,7 +5,7 @@
* TrueTypeGX/AAT mort table validation
* body for type5 (Contextual Glyph Insertion) subtable.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx.c b/thirdparty/freetype/src/gxvalid/gxvmorx.c
index 8bd45c27e6..754d9f8bf1 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmorx.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmorx.c
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT morx table validation (body).
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx.h b/thirdparty/freetype/src/gxvalid/gxvmorx.h
index e257270342..99be181067 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmorx.h
+++ b/thirdparty/freetype/src/gxvalid/gxvmorx.h
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT common definition for morx table (specification).
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx0.c b/thirdparty/freetype/src/gxvalid/gxvmorx0.c
index d7764a0ae8..5a42e552e2 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmorx0.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmorx0.c
@@ -5,7 +5,7 @@
* TrueTypeGX/AAT morx table validation
* body for type0 (Indic Script Rearrangement) subtable.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx1.c b/thirdparty/freetype/src/gxvalid/gxvmorx1.c
index 5b41b3605f..9f8b69067e 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmorx1.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmorx1.c
@@ -5,7 +5,7 @@
* TrueTypeGX/AAT morx table validation
* body for type1 (Contextual Substitution) subtable.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx2.c b/thirdparty/freetype/src/gxvalid/gxvmorx2.c
index ec4c81299d..98b5c49c26 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmorx2.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmorx2.c
@@ -5,7 +5,7 @@
* TrueTypeGX/AAT morx table validation
* body for type2 (Ligature Substitution) subtable.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx4.c b/thirdparty/freetype/src/gxvalid/gxvmorx4.c
index 7b041534c0..857e4d4eb8 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmorx4.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmorx4.c
@@ -5,7 +5,7 @@
* TrueTypeGX/AAT morx table validation
* body for "morx" type4 (Non-Contextual Glyph Substitution) subtable.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvmorx5.c b/thirdparty/freetype/src/gxvalid/gxvmorx5.c
index 70a4623656..7ceba077af 100644
--- a/thirdparty/freetype/src/gxvalid/gxvmorx5.c
+++ b/thirdparty/freetype/src/gxvalid/gxvmorx5.c
@@ -5,7 +5,7 @@
* TrueTypeGX/AAT morx table validation
* body for type5 (Contextual Glyph Insertion) subtable.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvopbd.c b/thirdparty/freetype/src/gxvalid/gxvopbd.c
index f055a22054..a398fe0977 100644
--- a/thirdparty/freetype/src/gxvalid/gxvopbd.c
+++ b/thirdparty/freetype/src/gxvalid/gxvopbd.c
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT opbd table validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvprop.c b/thirdparty/freetype/src/gxvalid/gxvprop.c
index e1911edd48..bee8bab97b 100644
--- a/thirdparty/freetype/src/gxvalid/gxvprop.c
+++ b/thirdparty/freetype/src/gxvalid/gxvprop.c
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT prop table validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/gxvtrak.c b/thirdparty/freetype/src/gxvalid/gxvtrak.c
index b7794b7af4..58a631c9e5 100644
--- a/thirdparty/freetype/src/gxvalid/gxvtrak.c
+++ b/thirdparty/freetype/src/gxvalid/gxvtrak.c
@@ -4,7 +4,7 @@
*
* TrueTypeGX/AAT trak table validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
diff --git a/thirdparty/freetype/src/gxvalid/module.mk b/thirdparty/freetype/src/gxvalid/module.mk
index 04067ce617..e7d408df9d 100644
--- a/thirdparty/freetype/src/gxvalid/module.mk
+++ b/thirdparty/freetype/src/gxvalid/module.mk
@@ -2,7 +2,7 @@
# FreeType 2 gxvalid module definition
#
-# Copyright (C) 2004-2019 by
+# Copyright (C) 2004-2020 by
# suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
diff --git a/thirdparty/freetype/src/gxvalid/rules.mk b/thirdparty/freetype/src/gxvalid/rules.mk
index 4ef463bc21..d55a4935e2 100644
--- a/thirdparty/freetype/src/gxvalid/rules.mk
+++ b/thirdparty/freetype/src/gxvalid/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2004-2019 by
+# Copyright (C) 2004-2020 by
# suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
diff --git a/thirdparty/freetype/src/gzip/ftgzip.c b/thirdparty/freetype/src/gzip/ftgzip.c
index 5e78bc6f8d..6b1df3a4a7 100644
--- a/thirdparty/freetype/src/gzip/ftgzip.c
+++ b/thirdparty/freetype/src/gzip/ftgzip.c
@@ -8,7 +8,7 @@
* parse compressed PCF fonts, as found with many X11 server
* distributions.
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -746,7 +746,17 @@
stream.zfree = (free_func) ft_gzip_free;
stream.opaque = memory;
+ /* This is a temporary fix and will be removed once the internal
+ * copy of zlib is updated to the newest version. The `|32' flag
+ * is only supported in the new versions of zlib to enable gzip
+ * encoded header.
+ */
+#ifdef FT_CONFIG_OPTION_SYSTEM_ZLIB
err = inflateInit2( &stream, MAX_WBITS|32 );
+#else
+ err = inflateInit2( &stream, MAX_WBITS );
+#endif
+
if ( err != Z_OK )
return FT_THROW( Invalid_Argument );
diff --git a/thirdparty/freetype/src/gzip/infutil.h b/thirdparty/freetype/src/gzip/infutil.h
index 7174b6dd0f..cdf18b4f90 100644
--- a/thirdparty/freetype/src/gzip/infutil.h
+++ b/thirdparty/freetype/src/gzip/infutil.h
@@ -86,7 +86,7 @@ struct inflate_blocks_state {
/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
#ifndef NO_INFLATE_MASK
-local uInt inflate_mask[17];
+local const uInt inflate_mask[17];
#endif
/* copy as much as possible from the sliding window to the output area */
diff --git a/thirdparty/freetype/src/gzip/rules.mk b/thirdparty/freetype/src/gzip/rules.mk
index 44206a1dae..4ea823f8d3 100644
--- a/thirdparty/freetype/src/gzip/rules.mk
+++ b/thirdparty/freetype/src/gzip/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2002-2019 by
+# Copyright (C) 2002-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/lzw/ftlzw.c b/thirdparty/freetype/src/lzw/ftlzw.c
index 9805a1e3bd..7d3f3e3f55 100644
--- a/thirdparty/freetype/src/lzw/ftlzw.c
+++ b/thirdparty/freetype/src/lzw/ftlzw.c
@@ -8,7 +8,7 @@
* be used to parse compressed PCF fonts, as found with many X11 server
* distributions.
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* Albert Chin-A-Young.
*
* based on code in `src/gzip/ftgzip.c'
diff --git a/thirdparty/freetype/src/lzw/ftzopen.c b/thirdparty/freetype/src/lzw/ftzopen.c
index 67e6760f95..cdc7f4e683 100644
--- a/thirdparty/freetype/src/lzw/ftzopen.c
+++ b/thirdparty/freetype/src/lzw/ftzopen.c
@@ -8,7 +8,7 @@
* be used to parse compressed PCF fonts, as found with many X11 server
* distributions.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* David Turner.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/lzw/ftzopen.h b/thirdparty/freetype/src/lzw/ftzopen.h
index 44fe36d6c5..2866529bd4 100644
--- a/thirdparty/freetype/src/lzw/ftzopen.h
+++ b/thirdparty/freetype/src/lzw/ftzopen.h
@@ -8,7 +8,7 @@
* be used to parse compressed PCF fonts, as found with many X11 server
* distributions.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* David Turner.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/lzw/rules.mk b/thirdparty/freetype/src/lzw/rules.mk
index 930b32e6b1..3468ee024d 100644
--- a/thirdparty/freetype/src/lzw/rules.mk
+++ b/thirdparty/freetype/src/lzw/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2004-2019 by
+# Copyright (C) 2004-2020 by
# Albert Chin-A-Young.
#
# based on `src/lzw/rules.mk'
diff --git a/thirdparty/freetype/src/otvalid/module.mk b/thirdparty/freetype/src/otvalid/module.mk
index 5ea5b7b57b..67b9820d84 100644
--- a/thirdparty/freetype/src/otvalid/module.mk
+++ b/thirdparty/freetype/src/otvalid/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2004-2019 by
+# Copyright (C) 2004-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/otvalid/otvalid.c b/thirdparty/freetype/src/otvalid/otvalid.c
index e3964b99ae..487d336a3b 100644
--- a/thirdparty/freetype/src/otvalid/otvalid.c
+++ b/thirdparty/freetype/src/otvalid/otvalid.c
@@ -4,7 +4,7 @@
*
* FreeType validator for OpenType tables (body only).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/otvalid.h b/thirdparty/freetype/src/otvalid/otvalid.h
index 5ca819f261..3c70268964 100644
--- a/thirdparty/freetype/src/otvalid/otvalid.h
+++ b/thirdparty/freetype/src/otvalid/otvalid.h
@@ -4,7 +4,7 @@
*
* OpenType table validation (specification only).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/otvbase.c b/thirdparty/freetype/src/otvalid/otvbase.c
index be69d7ca31..250ae98ab5 100644
--- a/thirdparty/freetype/src/otvalid/otvbase.c
+++ b/thirdparty/freetype/src/otvalid/otvbase.c
@@ -4,7 +4,7 @@
*
* OpenType BASE table validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/otvcommn.c b/thirdparty/freetype/src/otvalid/otvcommn.c
index 5ed1723506..faaa846871 100644
--- a/thirdparty/freetype/src/otvalid/otvcommn.c
+++ b/thirdparty/freetype/src/otvalid/otvcommn.c
@@ -4,7 +4,7 @@
*
* OpenType common tables validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -151,6 +151,9 @@
FT_UInt result = 0;
+ if ( !count )
+ return result;
+
switch ( CoverageFormat )
{
case 1:
diff --git a/thirdparty/freetype/src/otvalid/otvcommn.h b/thirdparty/freetype/src/otvalid/otvcommn.h
index bfcc5b974a..1daf7dca79 100644
--- a/thirdparty/freetype/src/otvalid/otvcommn.h
+++ b/thirdparty/freetype/src/otvalid/otvcommn.h
@@ -4,7 +4,7 @@
*
* OpenType common tables validation (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/otverror.h b/thirdparty/freetype/src/otvalid/otverror.h
index a7d35acf1a..49c34d6cd8 100644
--- a/thirdparty/freetype/src/otvalid/otverror.h
+++ b/thirdparty/freetype/src/otvalid/otverror.h
@@ -4,7 +4,7 @@
*
* OpenType validation module error codes (specification only).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/otvgdef.c b/thirdparty/freetype/src/otvalid/otvgdef.c
index 2529b544d2..88874b8474 100644
--- a/thirdparty/freetype/src/otvalid/otvgdef.c
+++ b/thirdparty/freetype/src/otvalid/otvgdef.c
@@ -4,7 +4,7 @@
*
* OpenType GDEF table validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/otvgpos.c b/thirdparty/freetype/src/otvalid/otvgpos.c
index f3bddeac6c..29d56f91e8 100644
--- a/thirdparty/freetype/src/otvalid/otvgpos.c
+++ b/thirdparty/freetype/src/otvalid/otvgpos.c
@@ -4,7 +4,7 @@
*
* OpenType GPOS table validation (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/otvgpos.h b/thirdparty/freetype/src/otvalid/otvgpos.h
index b3154312eb..06a03a0e6c 100644
--- a/thirdparty/freetype/src/otvalid/otvgpos.h
+++ b/thirdparty/freetype/src/otvalid/otvgpos.h
@@ -4,7 +4,7 @@
*
* OpenType GPOS table validator (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/otvgsub.c b/thirdparty/freetype/src/otvalid/otvgsub.c
index 97da997d3d..f0d563ba92 100644
--- a/thirdparty/freetype/src/otvalid/otvgsub.c
+++ b/thirdparty/freetype/src/otvalid/otvgsub.c
@@ -4,7 +4,7 @@
*
* OpenType GSUB table validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/otvjstf.c b/thirdparty/freetype/src/otvalid/otvjstf.c
index d4e6d87178..79de7b809d 100644
--- a/thirdparty/freetype/src/otvalid/otvjstf.c
+++ b/thirdparty/freetype/src/otvalid/otvjstf.c
@@ -4,7 +4,7 @@
*
* OpenType JSTF table validation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/otvmath.c b/thirdparty/freetype/src/otvalid/otvmath.c
index 3aaf0ec0ec..dfdeaaba7e 100644
--- a/thirdparty/freetype/src/otvalid/otvmath.c
+++ b/thirdparty/freetype/src/otvalid/otvmath.c
@@ -4,7 +4,7 @@
*
* OpenType MATH table validation (body).
*
- * Copyright (C) 2007-2019 by
+ * Copyright (C) 2007-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* Written by George Williams.
diff --git a/thirdparty/freetype/src/otvalid/otvmod.c b/thirdparty/freetype/src/otvalid/otvmod.c
index f417bd220f..5f3e7e8d49 100644
--- a/thirdparty/freetype/src/otvalid/otvmod.c
+++ b/thirdparty/freetype/src/otvalid/otvmod.c
@@ -4,7 +4,7 @@
*
* FreeType's OpenType validation module implementation (body).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/otvmod.h b/thirdparty/freetype/src/otvalid/otvmod.h
index 5539de7ec6..f172c2c8fa 100644
--- a/thirdparty/freetype/src/otvalid/otvmod.h
+++ b/thirdparty/freetype/src/otvalid/otvmod.h
@@ -5,7 +5,7 @@
* FreeType's OpenType validation module implementation
* (specification).
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/otvalid/rules.mk b/thirdparty/freetype/src/otvalid/rules.mk
index 3c6ece1c19..7f0169fd89 100644
--- a/thirdparty/freetype/src/otvalid/rules.mk
+++ b/thirdparty/freetype/src/otvalid/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2004-2019 by
+# Copyright (C) 2004-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/pfr/module.mk b/thirdparty/freetype/src/pfr/module.mk
index 30d876d4c8..762353dda2 100644
--- a/thirdparty/freetype/src/pfr/module.mk
+++ b/thirdparty/freetype/src/pfr/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2002-2019 by
+# Copyright (C) 2002-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/pfr/pfr.c b/thirdparty/freetype/src/pfr/pfr.c
index 6d885ea47f..5dea6fa34a 100644
--- a/thirdparty/freetype/src/pfr/pfr.c
+++ b/thirdparty/freetype/src/pfr/pfr.c
@@ -4,7 +4,7 @@
*
* FreeType PFR driver component.
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrcmap.c b/thirdparty/freetype/src/pfr/pfrcmap.c
index bfa1b9ea05..3f64ba8b04 100644
--- a/thirdparty/freetype/src/pfr/pfrcmap.c
+++ b/thirdparty/freetype/src/pfr/pfrcmap.c
@@ -4,7 +4,7 @@
*
* FreeType PFR cmap handling (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrcmap.h b/thirdparty/freetype/src/pfr/pfrcmap.h
index 1e203a0514..b90e8a101f 100644
--- a/thirdparty/freetype/src/pfr/pfrcmap.h
+++ b/thirdparty/freetype/src/pfr/pfrcmap.h
@@ -4,7 +4,7 @@
*
* FreeType PFR cmap handling (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrdrivr.c b/thirdparty/freetype/src/pfr/pfrdrivr.c
index f67eebf118..2028c8e11b 100644
--- a/thirdparty/freetype/src/pfr/pfrdrivr.c
+++ b/thirdparty/freetype/src/pfr/pfrdrivr.c
@@ -4,7 +4,7 @@
*
* FreeType PFR driver interface (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrdrivr.h b/thirdparty/freetype/src/pfr/pfrdrivr.h
index 33b7b9413f..865ec8188a 100644
--- a/thirdparty/freetype/src/pfr/pfrdrivr.h
+++ b/thirdparty/freetype/src/pfr/pfrdrivr.h
@@ -4,7 +4,7 @@
*
* High-level Type PFR driver interface (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrerror.h b/thirdparty/freetype/src/pfr/pfrerror.h
index 4829cfc000..2dbeedfe15 100644
--- a/thirdparty/freetype/src/pfr/pfrerror.h
+++ b/thirdparty/freetype/src/pfr/pfrerror.h
@@ -4,7 +4,7 @@
*
* PFR error codes (specification only).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrgload.c b/thirdparty/freetype/src/pfr/pfrgload.c
index 6ef5856a8d..7d57ae1530 100644
--- a/thirdparty/freetype/src/pfr/pfrgload.c
+++ b/thirdparty/freetype/src/pfr/pfrgload.c
@@ -4,7 +4,7 @@
*
* FreeType PFR glyph loader (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrgload.h b/thirdparty/freetype/src/pfr/pfrgload.h
index d0e1420b67..f356b4c75b 100644
--- a/thirdparty/freetype/src/pfr/pfrgload.h
+++ b/thirdparty/freetype/src/pfr/pfrgload.h
@@ -4,7 +4,7 @@
*
* FreeType PFR glyph loader (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrload.c b/thirdparty/freetype/src/pfr/pfrload.c
index ccf0b7e1f8..6eeed28245 100644
--- a/thirdparty/freetype/src/pfr/pfrload.c
+++ b/thirdparty/freetype/src/pfr/pfrload.c
@@ -4,7 +4,7 @@
*
* FreeType PFR loader (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrload.h b/thirdparty/freetype/src/pfr/pfrload.h
index 2e7ffd0127..7d113df270 100644
--- a/thirdparty/freetype/src/pfr/pfrload.h
+++ b/thirdparty/freetype/src/pfr/pfrload.h
@@ -4,7 +4,7 @@
*
* FreeType PFR loader (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrobjs.c b/thirdparty/freetype/src/pfr/pfrobjs.c
index 9765f95c2f..9bc90a4b68 100644
--- a/thirdparty/freetype/src/pfr/pfrobjs.c
+++ b/thirdparty/freetype/src/pfr/pfrobjs.c
@@ -4,7 +4,7 @@
*
* FreeType PFR object methods (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrobjs.h b/thirdparty/freetype/src/pfr/pfrobjs.h
index 39cffd07c5..808822f1c4 100644
--- a/thirdparty/freetype/src/pfr/pfrobjs.h
+++ b/thirdparty/freetype/src/pfr/pfrobjs.h
@@ -4,7 +4,7 @@
*
* FreeType PFR object methods (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrsbit.c b/thirdparty/freetype/src/pfr/pfrsbit.c
index 00a9616455..00669e13ff 100644
--- a/thirdparty/freetype/src/pfr/pfrsbit.c
+++ b/thirdparty/freetype/src/pfr/pfrsbit.c
@@ -4,7 +4,7 @@
*
* FreeType PFR bitmap loader (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrsbit.h b/thirdparty/freetype/src/pfr/pfrsbit.h
index 6568b90943..8cb0de0d25 100644
--- a/thirdparty/freetype/src/pfr/pfrsbit.h
+++ b/thirdparty/freetype/src/pfr/pfrsbit.h
@@ -4,7 +4,7 @@
*
* FreeType PFR bitmap loader (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/pfrtypes.h b/thirdparty/freetype/src/pfr/pfrtypes.h
index 6a5f9d571b..dfc47beff3 100644
--- a/thirdparty/freetype/src/pfr/pfrtypes.h
+++ b/thirdparty/freetype/src/pfr/pfrtypes.h
@@ -4,7 +4,7 @@
*
* FreeType PFR data structures (specification only).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pfr/rules.mk b/thirdparty/freetype/src/pfr/rules.mk
index f14ca699e2..a1fe82baff 100644
--- a/thirdparty/freetype/src/pfr/rules.mk
+++ b/thirdparty/freetype/src/pfr/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2002-2019 by
+# Copyright (C) 2002-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/psaux/afmparse.c b/thirdparty/freetype/src/psaux/afmparse.c
index f78adbba3d..b957158aec 100644
--- a/thirdparty/freetype/src/psaux/afmparse.c
+++ b/thirdparty/freetype/src/psaux/afmparse.c
@@ -4,7 +4,7 @@
*
* AFM parser (body).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/afmparse.h b/thirdparty/freetype/src/psaux/afmparse.h
index 2ceb77553b..50f4834b3f 100644
--- a/thirdparty/freetype/src/psaux/afmparse.h
+++ b/thirdparty/freetype/src/psaux/afmparse.h
@@ -4,7 +4,7 @@
*
* AFM parser (specification).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/cffdecode.c b/thirdparty/freetype/src/psaux/cffdecode.c
index 17cccf818b..172e3b23a3 100644
--- a/thirdparty/freetype/src/psaux/cffdecode.c
+++ b/thirdparty/freetype/src/psaux/cffdecode.c
@@ -4,7 +4,7 @@
*
* PostScript CFF (Type 2) decoding routines (body).
*
- * Copyright (C) 2017-2019 by
+ * Copyright (C) 2017-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -330,7 +330,7 @@
builder->left_bearing.x = 0;
builder->left_bearing.y = 0;
- builder->pos_x = adx - asb;
+ builder->pos_x = SUB_LONG( adx, asb );
builder->pos_y = ady;
/* Now load `achar' on top of the base outline. */
@@ -530,6 +530,9 @@
builder->path_begun = 0;
+ if ( !charstring_base )
+ return FT_Err_Ok;
+
zone->base = charstring_base;
limit = zone->limit = charstring_base + charstring_len;
ip = zone->cursor = zone->base;
diff --git a/thirdparty/freetype/src/psaux/cffdecode.h b/thirdparty/freetype/src/psaux/cffdecode.h
index a6691979f0..5dc968b255 100644
--- a/thirdparty/freetype/src/psaux/cffdecode.h
+++ b/thirdparty/freetype/src/psaux/cffdecode.h
@@ -4,7 +4,7 @@
*
* PostScript CFF (Type 2) decoding routines (specification).
*
- * Copyright (C) 2017-2019 by
+ * Copyright (C) 2017-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/module.mk b/thirdparty/freetype/src/psaux/module.mk
index bb0886abdf..651db01426 100644
--- a/thirdparty/freetype/src/psaux/module.mk
+++ b/thirdparty/freetype/src/psaux/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/psaux/psaux.c b/thirdparty/freetype/src/psaux/psaux.c
index 1db0462551..96d2484e9d 100644
--- a/thirdparty/freetype/src/psaux/psaux.c
+++ b/thirdparty/freetype/src/psaux/psaux.c
@@ -4,7 +4,7 @@
*
* FreeType auxiliary PostScript driver component (body only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/psauxerr.h b/thirdparty/freetype/src/psaux/psauxerr.h
index 523e1886c2..df8b09ff78 100644
--- a/thirdparty/freetype/src/psaux/psauxerr.h
+++ b/thirdparty/freetype/src/psaux/psauxerr.h
@@ -4,7 +4,7 @@
*
* PS auxiliary module error codes (specification only).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/psauxmod.c b/thirdparty/freetype/src/psaux/psauxmod.c
index 5df8e69056..bb520792e0 100644
--- a/thirdparty/freetype/src/psaux/psauxmod.c
+++ b/thirdparty/freetype/src/psaux/psauxmod.c
@@ -4,7 +4,7 @@
*
* FreeType auxiliary PostScript module implementation (body).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/psauxmod.h b/thirdparty/freetype/src/psaux/psauxmod.h
index a0eda0bfc0..6e2eb67042 100644
--- a/thirdparty/freetype/src/psaux/psauxmod.h
+++ b/thirdparty/freetype/src/psaux/psauxmod.h
@@ -4,7 +4,7 @@
*
* FreeType auxiliary PostScript module implementation (specification).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/psconv.c b/thirdparty/freetype/src/psaux/psconv.c
index c88761681c..c813a0596c 100644
--- a/thirdparty/freetype/src/psaux/psconv.c
+++ b/thirdparty/freetype/src/psaux/psconv.c
@@ -4,7 +4,7 @@
*
* Some convenience conversions (body).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/psconv.h b/thirdparty/freetype/src/psaux/psconv.h
index 6b24bf6fc9..2cd5c60e4b 100644
--- a/thirdparty/freetype/src/psaux/psconv.h
+++ b/thirdparty/freetype/src/psaux/psconv.h
@@ -4,7 +4,7 @@
*
* Some convenience conversions (specification).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/psft.c b/thirdparty/freetype/src/psaux/psft.c
index 54be468343..50b40bf8fe 100644
--- a/thirdparty/freetype/src/psaux/psft.c
+++ b/thirdparty/freetype/src/psaux/psft.c
@@ -313,7 +313,7 @@
FT_Error error = FT_Err_Ok;
CF2_Font font;
- FT_Bool is_t1 = decoder->builder.is_t1;
+ FT_Bool is_t1 = decoder->builder.is_t1;
FT_ASSERT( decoder &&
@@ -385,7 +385,7 @@
FT_ZERO( &buf );
buf.start =
buf.ptr = charstring_base;
- buf.end = charstring_base + charstring_len;
+ buf.end = FT_OFFSET( charstring_base, charstring_len );
FT_ZERO( &transform );
@@ -697,7 +697,7 @@
FT_ASSERT( charstring + len >= charstring );
buf->start = charstring;
- buf->end = charstring + len;
+ buf->end = FT_OFFSET( charstring, len );
buf->ptr = buf->start;
return FT_Err_Ok;
@@ -820,7 +820,7 @@
/* The CID driver stores subroutines with seed bytes. This */
/* case is taken care of when decoder->subrs_len == 0. */
if ( decoder->locals_len )
- buf->end = buf->start + decoder->locals_len[idx];
+ buf->end = FT_OFFSET( buf->start, decoder->locals_len[idx] );
else
{
/* We are using subroutines from a CID font. We must adjust */
diff --git a/thirdparty/freetype/src/psaux/psintrp.c b/thirdparty/freetype/src/psaux/psintrp.c
index e2f3accdd5..0a84145535 100644
--- a/thirdparty/freetype/src/psaux/psintrp.c
+++ b/thirdparty/freetype/src/psaux/psintrp.c
@@ -1433,6 +1433,13 @@
lastError = error2; /* pass FreeType error through */
goto exit;
}
+
+ /* save the left bearing and width of the SEAC */
+ /* glyph as they will be erased by the next load */
+
+ left_bearing = *decoder->builder.left_bearing;
+ advance = *decoder->builder.advance;
+
cf2_interpT2CharString( font,
&component,
callbacks,
@@ -1443,11 +1450,14 @@
&dummyWidth );
cf2_freeT1SeacComponent( decoder, &component );
- /* save the left bearing and width of the base */
- /* character as they will be erased by the next load */
+ /* If the SEAC glyph doesn't have a (H)SBW of its */
+ /* own use the values from the base glyph. */
- left_bearing = *decoder->builder.left_bearing;
- advance = *decoder->builder.advance;
+ if ( !haveWidth )
+ {
+ left_bearing = *decoder->builder.left_bearing;
+ advance = *decoder->builder.advance;
+ }
decoder->builder.left_bearing->x = 0;
decoder->builder.left_bearing->y = 0;
@@ -1473,8 +1483,8 @@
&dummyWidth );
cf2_freeT1SeacComponent( decoder, &component );
- /* restore the left side bearing and */
- /* advance width of the base character */
+ /* restore the left side bearing and advance width */
+ /* of the SEAC glyph or base character (saved above) */
*decoder->builder.left_bearing = left_bearing;
*decoder->builder.advance = advance;
diff --git a/thirdparty/freetype/src/psaux/psobjs.c b/thirdparty/freetype/src/psaux/psobjs.c
index 8bfdb92332..b37a78832c 100644
--- a/thirdparty/freetype/src/psaux/psobjs.c
+++ b/thirdparty/freetype/src/psaux/psobjs.c
@@ -4,7 +4,7 @@
*
* Auxiliary functions for PostScript fonts (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -214,7 +214,7 @@
}
/* add the object to the base block and adjust offset */
- table->elements[idx] = table->block + table->cursor;
+ table->elements[idx] = FT_OFFSET( table->block, table->cursor );
table->lengths [idx] = length;
FT_MEM_COPY( table->block + table->cursor, object, length );
@@ -2577,7 +2577,7 @@
FT_UShort seed )
{
PS_Conv_EexecDecode( &buffer,
- buffer + length,
+ FT_OFFSET( buffer, length ),
buffer,
length,
&seed );
diff --git a/thirdparty/freetype/src/psaux/psobjs.h b/thirdparty/freetype/src/psaux/psobjs.h
index c44dc450ec..d37638d0ca 100644
--- a/thirdparty/freetype/src/psaux/psobjs.h
+++ b/thirdparty/freetype/src/psaux/psobjs.h
@@ -4,7 +4,7 @@
*
* Auxiliary functions for PostScript fonts (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/rules.mk b/thirdparty/freetype/src/psaux/rules.mk
index 2de734d547..f49aecbc79 100644
--- a/thirdparty/freetype/src/psaux/rules.mk
+++ b/thirdparty/freetype/src/psaux/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/psaux/t1cmap.c b/thirdparty/freetype/src/psaux/t1cmap.c
index d62d2d5c81..451b276537 100644
--- a/thirdparty/freetype/src/psaux/t1cmap.c
+++ b/thirdparty/freetype/src/psaux/t1cmap.c
@@ -4,7 +4,7 @@
*
* Type 1 character map support (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/t1cmap.h b/thirdparty/freetype/src/psaux/t1cmap.h
index d325e7b5a6..5411913831 100644
--- a/thirdparty/freetype/src/psaux/t1cmap.h
+++ b/thirdparty/freetype/src/psaux/t1cmap.h
@@ -4,7 +4,7 @@
*
* Type 1 character map support (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psaux/t1decode.c b/thirdparty/freetype/src/psaux/t1decode.c
index c2b3729b53..fa1745d9e0 100644
--- a/thirdparty/freetype/src/psaux/t1decode.c
+++ b/thirdparty/freetype/src/psaux/t1decode.c
@@ -4,7 +4,7 @@
*
* PostScript Type 1 decoding routines (body).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -367,6 +367,12 @@
FT_GlyphLoader_Prepare( decoder->builder.loader ); /* prepare loader */
+ /* save the left bearing and width of the SEAC */
+ /* glyph as they will be erased by the next load */
+
+ left_bearing = decoder->builder.left_bearing;
+ advance = decoder->builder.advance;
+
/* the seac operator must not be nested */
decoder->seac = TRUE;
error = t1_decoder_parse_glyph( decoder, (FT_UInt)bchar_index );
@@ -374,11 +380,14 @@
if ( error )
goto Exit;
- /* save the left bearing and width of the base character */
- /* as they will be erased by the next load. */
+ /* If the SEAC glyph doesn't have a (H)SBW of its */
+ /* own use the values from the base glyph. */
- left_bearing = decoder->builder.left_bearing;
- advance = decoder->builder.advance;
+ if ( decoder->builder.parse_state != T1_Parse_Have_Width )
+ {
+ left_bearing = decoder->builder.left_bearing;
+ advance = decoder->builder.advance;
+ }
decoder->builder.left_bearing.x = 0;
decoder->builder.left_bearing.y = 0;
@@ -396,8 +405,8 @@
if ( error )
goto Exit;
- /* restore the left side bearing and */
- /* advance width of the base character */
+ /* restore the left side bearing and advance width */
+ /* of the SEAC glyph or base character (saved above) */
decoder->builder.left_bearing = left_bearing;
decoder->builder.advance = advance;
@@ -650,10 +659,8 @@
if ( value > 32000 || value < -32000 )
{
if ( large_int )
- {
FT_ERROR(( "t1_decoder_parse_charstrings:"
" no `div' after large integer\n" ));
- }
else
large_int = TRUE;
}
@@ -1690,6 +1697,7 @@
FT_Byte* ip;
FT_Byte* limit;
T1_Builder builder = &decoder->builder;
+ FT_Bool large_int;
#ifdef FT_DEBUG_LEVEL_TRACE
FT_Bool bol = TRUE;
@@ -1707,6 +1715,8 @@
limit = zone->limit = charstring_base + charstring_len;
ip = zone->cursor = zone->base;
+ large_int = FALSE;
+
/* now, execute loop */
while ( ip < limit )
{
@@ -1767,6 +1777,9 @@
case 7:
op = op_sbw;
break;
+ case 12:
+ op = op_div;
+ break;
default:
goto No_Width;
@@ -1796,13 +1809,19 @@
/* anyway. */
if ( value > 32000 || value < -32000 )
{
- FT_ERROR(( "t1_decoder_parse_metrics:"
- " large integer found for width\n" ));
- goto Syntax_Error;
+ if ( large_int )
+ {
+ FT_ERROR(( "t1_decoder_parse_metrics:"
+ " no `div' after large integer\n" ));
+ goto Syntax_Error;
+ }
+ else
+ large_int = TRUE;
}
else
{
- value = (FT_Int32)( (FT_UInt32)value << 16 );
+ if ( !large_int )
+ value = (FT_Int32)( (FT_UInt32)value << 16 );
}
break;
@@ -1827,7 +1846,8 @@
value = -( ( ( ip[-2] - 251 ) * 256 ) + ip[-1] + 108 );
}
- value = (FT_Int32)( (FT_UInt32)value << 16 );
+ if ( !large_int )
+ value = (FT_Int32)( (FT_UInt32)value << 16 );
}
else
{
@@ -1837,6 +1857,13 @@
}
}
+ if ( large_int && !( op == op_none || op == op_div ) )
+ {
+ FT_ERROR(( "t1_decoder_parse_metrics:"
+ " no `div' after large integer\n" ));
+ goto Syntax_Error;
+ }
+
/**********************************************************************
*
* Push value on stack, or process operator
@@ -1851,6 +1878,9 @@
}
#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( large_int )
+ FT_TRACE4(( " %d", value ));
+ else
FT_TRACE4(( " %d", value / 65536 ));
#endif
@@ -1869,11 +1899,14 @@
#ifdef FT_DEBUG_LEVEL_TRACE
- if ( top - decoder->stack != num_args )
- FT_TRACE0(( "t1_decoder_parse_metrics:"
- " too much operands on the stack"
- " (seen %d, expected %d)\n",
- top - decoder->stack, num_args ));
+ if ( op != op_div )
+ {
+ if ( top - decoder->stack != num_args )
+ FT_TRACE0(( "t1_decoder_parse_metrics:"
+ " too much operands on the stack"
+ " (seen %d, expected %d)\n",
+ top - decoder->stack, num_args ));
+ }
#endif /* FT_DEBUG_LEVEL_TRACE */
@@ -1917,12 +1950,26 @@
FT_TRACE4(( "\n" ));
return FT_Err_Ok;
+ case op_div:
+ FT_TRACE4(( " div" ));
+
+ /* if `large_int' is set, we divide unscaled numbers; */
+ /* otherwise, we divide numbers in 16.16 format -- */
+ /* in both cases, it is the same operation */
+ *top = FT_DivFix( top[0], top[1] );
+ top++;
+
+ large_int = FALSE;
+ break;
+
default:
FT_ERROR(( "t1_decoder_parse_metrics:"
" unhandled opcode %d\n", op ));
goto Syntax_Error;
}
+ decoder->top = top;
+
} /* general operator processing */
} /* while ip < limit */
diff --git a/thirdparty/freetype/src/psaux/t1decode.h b/thirdparty/freetype/src/psaux/t1decode.h
index 1b5d6263d3..231947e852 100644
--- a/thirdparty/freetype/src/psaux/t1decode.h
+++ b/thirdparty/freetype/src/psaux/t1decode.h
@@ -4,7 +4,7 @@
*
* PostScript Type 1 decoding routines (specification).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pshinter/module.mk b/thirdparty/freetype/src/pshinter/module.mk
index 0a12a260e1..b440d2e76a 100644
--- a/thirdparty/freetype/src/pshinter/module.mk
+++ b/thirdparty/freetype/src/pshinter/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/pshinter/pshalgo.c b/thirdparty/freetype/src/pshinter/pshalgo.c
index 0c5ae62699..57dfa3da96 100644
--- a/thirdparty/freetype/src/pshinter/pshalgo.c
+++ b/thirdparty/freetype/src/pshinter/pshalgo.c
@@ -4,7 +4,7 @@
*
* PostScript hinting algorithm (body).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
diff --git a/thirdparty/freetype/src/pshinter/pshalgo.h b/thirdparty/freetype/src/pshinter/pshalgo.h
index 6859e95cd2..5367a5d164 100644
--- a/thirdparty/freetype/src/pshinter/pshalgo.h
+++ b/thirdparty/freetype/src/pshinter/pshalgo.h
@@ -4,7 +4,7 @@
*
* PostScript hinting algorithm (specification).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pshinter/pshglob.c b/thirdparty/freetype/src/pshinter/pshglob.c
index b021e6e42a..d9f835f99e 100644
--- a/thirdparty/freetype/src/pshinter/pshglob.c
+++ b/thirdparty/freetype/src/pshinter/pshglob.c
@@ -5,7 +5,7 @@
* PostScript hinter global hinting management (body).
* Inspired by the new auto-hinter module.
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
diff --git a/thirdparty/freetype/src/pshinter/pshglob.h b/thirdparty/freetype/src/pshinter/pshglob.h
index 0049d4c0bc..cd2f3122f7 100644
--- a/thirdparty/freetype/src/pshinter/pshglob.h
+++ b/thirdparty/freetype/src/pshinter/pshglob.h
@@ -4,7 +4,7 @@
*
* PostScript hinter global hinting management.
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pshinter/pshinter.c b/thirdparty/freetype/src/pshinter/pshinter.c
index 16c3a0a117..6009db5187 100644
--- a/thirdparty/freetype/src/pshinter/pshinter.c
+++ b/thirdparty/freetype/src/pshinter/pshinter.c
@@ -4,7 +4,7 @@
*
* FreeType PostScript Hinting module
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pshinter/pshmod.c b/thirdparty/freetype/src/pshinter/pshmod.c
index 2d36ea2a6a..686859b3ed 100644
--- a/thirdparty/freetype/src/pshinter/pshmod.c
+++ b/thirdparty/freetype/src/pshinter/pshmod.c
@@ -4,7 +4,7 @@
*
* FreeType PostScript hinter module implementation (body).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pshinter/pshmod.h b/thirdparty/freetype/src/pshinter/pshmod.h
index ea8771308a..c44112e9d4 100644
--- a/thirdparty/freetype/src/pshinter/pshmod.h
+++ b/thirdparty/freetype/src/pshinter/pshmod.h
@@ -4,7 +4,7 @@
*
* PostScript hinter module interface (specification).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pshinter/pshnterr.h b/thirdparty/freetype/src/pshinter/pshnterr.h
index fb9dbca2b1..c4e9f42d2c 100644
--- a/thirdparty/freetype/src/pshinter/pshnterr.h
+++ b/thirdparty/freetype/src/pshinter/pshnterr.h
@@ -4,7 +4,7 @@
*
* PS Hinter error codes (specification only).
*
- * Copyright (C) 2003-2019 by
+ * Copyright (C) 2003-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pshinter/pshrec.c b/thirdparty/freetype/src/pshinter/pshrec.c
index 9dd09efe4c..a81c6f7123 100644
--- a/thirdparty/freetype/src/pshinter/pshrec.c
+++ b/thirdparty/freetype/src/pshinter/pshrec.c
@@ -4,7 +4,7 @@
*
* FreeType PostScript hints recorder (body).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pshinter/pshrec.h b/thirdparty/freetype/src/pshinter/pshrec.h
index 02cc2102ec..a8bc5aeecb 100644
--- a/thirdparty/freetype/src/pshinter/pshrec.h
+++ b/thirdparty/freetype/src/pshinter/pshrec.h
@@ -4,7 +4,7 @@
*
* Postscript (Type1/Type2) hints recorder (specification).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/pshinter/rules.mk b/thirdparty/freetype/src/pshinter/rules.mk
index 58227d10f2..c845c255cd 100644
--- a/thirdparty/freetype/src/pshinter/rules.mk
+++ b/thirdparty/freetype/src/pshinter/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2001-2019 by
+# Copyright (C) 2001-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/psnames/module.mk b/thirdparty/freetype/src/psnames/module.mk
index 0806a318a7..675bb37131 100644
--- a/thirdparty/freetype/src/psnames/module.mk
+++ b/thirdparty/freetype/src/psnames/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/psnames/psmodule.c b/thirdparty/freetype/src/psnames/psmodule.c
index 0ec440e67b..bb3ff07022 100644
--- a/thirdparty/freetype/src/psnames/psmodule.c
+++ b/thirdparty/freetype/src/psnames/psmodule.c
@@ -4,7 +4,7 @@
*
* psnames module implementation (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psnames/psmodule.h b/thirdparty/freetype/src/psnames/psmodule.h
index 0df9a7d889..955f699f3a 100644
--- a/thirdparty/freetype/src/psnames/psmodule.h
+++ b/thirdparty/freetype/src/psnames/psmodule.h
@@ -4,7 +4,7 @@
*
* High-level psnames module interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psnames/psnamerr.h b/thirdparty/freetype/src/psnames/psnamerr.h
index 67ab1765d3..fb9058e61a 100644
--- a/thirdparty/freetype/src/psnames/psnamerr.h
+++ b/thirdparty/freetype/src/psnames/psnamerr.h
@@ -4,7 +4,7 @@
*
* PS names module error codes (specification only).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psnames/psnames.c b/thirdparty/freetype/src/psnames/psnames.c
index 4722f98831..5ac3897d25 100644
--- a/thirdparty/freetype/src/psnames/psnames.c
+++ b/thirdparty/freetype/src/psnames/psnames.c
@@ -4,7 +4,7 @@
*
* FreeType psnames module component (body only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psnames/pstables.h b/thirdparty/freetype/src/psnames/pstables.h
index c0139bbc60..c215f16ffc 100644
--- a/thirdparty/freetype/src/psnames/pstables.h
+++ b/thirdparty/freetype/src/psnames/pstables.h
@@ -4,7 +4,7 @@
*
* PostScript glyph names.
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/psnames/rules.mk b/thirdparty/freetype/src/psnames/rules.mk
index dcc203e391..14cdda3ad1 100644
--- a/thirdparty/freetype/src/psnames/rules.mk
+++ b/thirdparty/freetype/src/psnames/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/raster/ftmisc.h b/thirdparty/freetype/src/raster/ftmisc.h
index a246569e3b..6efe4a9a5a 100644
--- a/thirdparty/freetype/src/raster/ftmisc.h
+++ b/thirdparty/freetype/src/raster/ftmisc.h
@@ -5,7 +5,7 @@
* Miscellaneous macros for stand-alone rasterizer (specification
* only).
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
diff --git a/thirdparty/freetype/src/raster/ftraster.c b/thirdparty/freetype/src/raster/ftraster.c
index 023b6c1eff..35655a6346 100644
--- a/thirdparty/freetype/src/raster/ftraster.c
+++ b/thirdparty/freetype/src/raster/ftraster.c
@@ -4,7 +4,7 @@
*
* The FreeType glyph rasterizer (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/raster/ftraster.h b/thirdparty/freetype/src/raster/ftraster.h
index 50d34201a1..833d30f234 100644
--- a/thirdparty/freetype/src/raster/ftraster.h
+++ b/thirdparty/freetype/src/raster/ftraster.h
@@ -4,7 +4,7 @@
*
* The FreeType glyph rasterizer (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used
diff --git a/thirdparty/freetype/src/raster/ftrend1.c b/thirdparty/freetype/src/raster/ftrend1.c
index 62c727182a..944279a8d1 100644
--- a/thirdparty/freetype/src/raster/ftrend1.c
+++ b/thirdparty/freetype/src/raster/ftrend1.c
@@ -4,7 +4,7 @@
*
* The FreeType glyph rasterizer interface (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/raster/ftrend1.h b/thirdparty/freetype/src/raster/ftrend1.h
index 82ecac686c..dc972b1bc2 100644
--- a/thirdparty/freetype/src/raster/ftrend1.h
+++ b/thirdparty/freetype/src/raster/ftrend1.h
@@ -4,7 +4,7 @@
*
* The FreeType glyph rasterizer interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/raster/module.mk b/thirdparty/freetype/src/raster/module.mk
index 0a6d4b09d9..3600732b16 100644
--- a/thirdparty/freetype/src/raster/module.mk
+++ b/thirdparty/freetype/src/raster/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/raster/raster.c b/thirdparty/freetype/src/raster/raster.c
index e3ac9e566a..08431c8509 100644
--- a/thirdparty/freetype/src/raster/raster.c
+++ b/thirdparty/freetype/src/raster/raster.c
@@ -4,7 +4,7 @@
*
* FreeType monochrome rasterer module component (body only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/raster/rasterrs.h b/thirdparty/freetype/src/raster/rasterrs.h
index 7266407365..379e1d3e89 100644
--- a/thirdparty/freetype/src/raster/rasterrs.h
+++ b/thirdparty/freetype/src/raster/rasterrs.h
@@ -4,7 +4,7 @@
*
* monochrome renderer error codes (specification only).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/raster/rules.mk b/thirdparty/freetype/src/raster/rules.mk
index 7664671e80..3e949d7741 100644
--- a/thirdparty/freetype/src/raster/rules.mk
+++ b/thirdparty/freetype/src/raster/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/sfnt/module.mk b/thirdparty/freetype/src/sfnt/module.mk
index 8c3b44fec7..0f459d8421 100644
--- a/thirdparty/freetype/src/sfnt/module.mk
+++ b/thirdparty/freetype/src/sfnt/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/sfnt/pngshim.c b/thirdparty/freetype/src/sfnt/pngshim.c
index ca85d9751f..523b30a745 100644
--- a/thirdparty/freetype/src/sfnt/pngshim.c
+++ b/thirdparty/freetype/src/sfnt/pngshim.c
@@ -4,7 +4,7 @@
*
* PNG Bitmap glyph support.
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* Google, Inc.
* Written by Stuart Gill and Behdad Esfahbod.
*
@@ -68,6 +68,7 @@
( ( __clang_major__ >= 4 ) || \
( ( __clang_major__ == 3 ) && ( __clang_minor__ >= 2 ) ) ) ) ) && \
defined( __OPTIMIZE__ ) && \
+ defined( __SSE__ ) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#ifdef __clang__
diff --git a/thirdparty/freetype/src/sfnt/pngshim.h b/thirdparty/freetype/src/sfnt/pngshim.h
index 06c6f6b20e..d2c9e2b9b5 100644
--- a/thirdparty/freetype/src/sfnt/pngshim.h
+++ b/thirdparty/freetype/src/sfnt/pngshim.h
@@ -4,7 +4,7 @@
*
* PNG Bitmap glyph support.
*
- * Copyright (C) 2013-2019 by
+ * Copyright (C) 2013-2020 by
* Google, Inc.
* Written by Stuart Gill and Behdad Esfahbod.
*
diff --git a/thirdparty/freetype/src/sfnt/rules.mk b/thirdparty/freetype/src/sfnt/rules.mk
index ee3314eac3..f56ef060ed 100644
--- a/thirdparty/freetype/src/sfnt/rules.mk
+++ b/thirdparty/freetype/src/sfnt/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
@@ -28,19 +28,21 @@ SFNT_COMPILE := $(CC) $(ANSIFLAGS) \
# SFNT driver sources (i.e., C files)
#
-SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c \
- $(SFNT_DIR)/sfdriver.c \
- $(SFNT_DIR)/sfobjs.c \
- $(SFNT_DIR)/sfwoff.c \
- $(SFNT_DIR)/ttbdf.c \
- $(SFNT_DIR)/ttcmap.c \
- $(SFNT_DIR)/ttcolr.c \
- $(SFNT_DIR)/ttcpal.c \
- $(SFNT_DIR)/ttkern.c \
- $(SFNT_DIR)/ttload.c \
- $(SFNT_DIR)/ttmtx.c \
- $(SFNT_DIR)/ttpost.c \
- $(SFNT_DIR)/ttsbit.c
+SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c \
+ $(SFNT_DIR)/sfdriver.c \
+ $(SFNT_DIR)/sfobjs.c \
+ $(SFNT_DIR)/sfwoff.c \
+ $(SFNT_DIR)/sfwoff2.c \
+ $(SFNT_DIR)/ttbdf.c \
+ $(SFNT_DIR)/ttcmap.c \
+ $(SFNT_DIR)/ttcolr.c \
+ $(SFNT_DIR)/ttcpal.c \
+ $(SFNT_DIR)/ttkern.c \
+ $(SFNT_DIR)/ttload.c \
+ $(SFNT_DIR)/ttmtx.c \
+ $(SFNT_DIR)/ttpost.c \
+ $(SFNT_DIR)/ttsbit.c \
+ $(SFNT_DIR)/woff2tags.c
# SFNT driver headers
#
diff --git a/thirdparty/freetype/src/sfnt/sfdriver.c b/thirdparty/freetype/src/sfnt/sfdriver.c
index 2611685284..6ca4f3c268 100644
--- a/thirdparty/freetype/src/sfnt/sfdriver.c
+++ b/thirdparty/freetype/src/sfnt/sfdriver.c
@@ -4,7 +4,7 @@
*
* High-level SFNT driver interface (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/sfdriver.h b/thirdparty/freetype/src/sfnt/sfdriver.h
index 8c174634b3..d108ee2000 100644
--- a/thirdparty/freetype/src/sfnt/sfdriver.h
+++ b/thirdparty/freetype/src/sfnt/sfdriver.h
@@ -4,7 +4,7 @@
*
* High-level SFNT driver interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/sferrors.h b/thirdparty/freetype/src/sfnt/sferrors.h
index 43e148d295..fbfca0e525 100644
--- a/thirdparty/freetype/src/sfnt/sferrors.h
+++ b/thirdparty/freetype/src/sfnt/sferrors.h
@@ -4,7 +4,7 @@
*
* SFNT error codes (specification only).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/sfnt.c b/thirdparty/freetype/src/sfnt/sfnt.c
index b4faf34a3a..9db7935ae4 100644
--- a/thirdparty/freetype/src/sfnt/sfnt.c
+++ b/thirdparty/freetype/src/sfnt/sfnt.c
@@ -4,7 +4,7 @@
*
* Single object library component.
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -23,6 +23,7 @@
#include "sfdriver.c"
#include "sfobjs.c"
#include "sfwoff.c"
+#include "sfwoff2.c"
#include "ttbdf.c"
#include "ttcmap.c"
#include "ttcolr.c"
@@ -33,6 +34,7 @@
#include "ttmtx.c"
#include "ttpost.c"
#include "ttsbit.c"
+#include "woff2tags.c"
/* END */
diff --git a/thirdparty/freetype/src/sfnt/sfobjs.c b/thirdparty/freetype/src/sfnt/sfobjs.c
index 6edf3ae1de..2c66a9b648 100644
--- a/thirdparty/freetype/src/sfnt/sfobjs.c
+++ b/thirdparty/freetype/src/sfnt/sfobjs.c
@@ -4,7 +4,7 @@
*
* SFNT object management (base).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -22,6 +22,7 @@
#include "ttcmap.h"
#include "ttkern.h"
#include "sfwoff.h"
+#include "sfwoff2.h"
#include FT_INTERNAL_SFNT_H
#include FT_INTERNAL_DEBUG_H
#include FT_TRUETYPE_IDS_H
@@ -341,7 +342,9 @@
/* synthesized into a TTC with one offset table. */
static FT_Error
sfnt_open_font( FT_Stream stream,
- TT_Face face )
+ TT_Face face,
+ FT_Int* face_instance_index,
+ FT_Long* woff2_num_faces )
{
FT_Memory memory = stream->memory;
FT_Error error;
@@ -385,6 +388,25 @@
goto retry;
}
+ if ( tag == TTAG_wOF2 )
+ {
+ FT_TRACE2(( "sfnt_open_font: file is a WOFF2; synthesizing SFNT\n" ));
+
+ if ( FT_STREAM_SEEK( offset ) )
+ return error;
+
+ error = woff2_open_font( stream,
+ face,
+ face_instance_index,
+ woff2_num_faces );
+ if ( error )
+ return error;
+
+ /* Swap out stream and retry! */
+ stream = face->root.stream;
+ goto retry;
+ }
+
if ( tag != 0x00010000UL &&
tag != TTAG_ttcf &&
tag != TTAG_OTTO &&
@@ -461,9 +483,10 @@
FT_Parameter* params )
{
FT_Error error;
- FT_Library library = face->root.driver->root.library;
+ FT_Library library = face->root.driver->root.library;
SFNT_Service sfnt;
FT_Int face_index;
+ FT_Long woff2_num_faces = 0;
/* for now, parameters are unused */
@@ -514,7 +537,10 @@
FT_TRACE2(( "SFNT driver\n" ));
- error = sfnt_open_font( stream, face );
+ error = sfnt_open_font( stream,
+ face,
+ &face_instance_index,
+ &woff2_num_faces );
if ( error )
return error;
@@ -689,6 +715,10 @@
face->root.num_faces = face->ttc_header.count;
face->root.face_index = face_instance_index;
+ /* `num_faces' for a WOFF2 needs to be handled separately. */
+ if ( woff2_num_faces )
+ face->root.num_faces = woff2_num_faces;
+
return error;
}
diff --git a/thirdparty/freetype/src/sfnt/sfobjs.h b/thirdparty/freetype/src/sfnt/sfobjs.h
index 3fbf2dd6bd..d8438a4834 100644
--- a/thirdparty/freetype/src/sfnt/sfobjs.h
+++ b/thirdparty/freetype/src/sfnt/sfobjs.h
@@ -4,7 +4,7 @@
*
* SFNT object management (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/sfwoff.c b/thirdparty/freetype/src/sfnt/sfwoff.c
index ca4821a20a..d1e330f675 100644
--- a/thirdparty/freetype/src/sfnt/sfwoff.c
+++ b/thirdparty/freetype/src/sfnt/sfwoff.c
@@ -4,7 +4,7 @@
*
* WOFF format management (base).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -371,18 +371,18 @@
sfnt + table->OrigOffset, &output_len,
stream->cursor, table->CompLength );
if ( error )
- goto Exit;
+ goto Exit1;
if ( output_len != table->OrigLength )
{
FT_ERROR(( "woff_font_open: compressed table length mismatch\n" ));
error = FT_THROW( Invalid_Table );
- goto Exit;
+ goto Exit1;
}
#else /* !FT_CONFIG_OPTION_USE_ZLIB */
error = FT_THROW( Unimplemented_Feature );
- goto Exit;
+ goto Exit1;
#endif /* !FT_CONFIG_OPTION_USE_ZLIB */
}
@@ -424,6 +424,10 @@
}
return error;
+
+ Exit1:
+ FT_FRAME_EXIT();
+ goto Exit;
}
diff --git a/thirdparty/freetype/src/sfnt/sfwoff.h b/thirdparty/freetype/src/sfnt/sfwoff.h
index 15495c32a2..c1789d33d5 100644
--- a/thirdparty/freetype/src/sfnt/sfwoff.h
+++ b/thirdparty/freetype/src/sfnt/sfwoff.h
@@ -4,7 +4,7 @@
*
* WOFFF format management (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/sfwoff2.c b/thirdparty/freetype/src/sfnt/sfwoff2.c
new file mode 100644
index 0000000000..1b99e7d28c
--- /dev/null
+++ b/thirdparty/freetype/src/sfnt/sfwoff2.c
@@ -0,0 +1,2328 @@
+/****************************************************************************
+ *
+ * sfwoff2.c
+ *
+ * WOFF2 format management (base).
+ *
+ * Copyright (C) 2019-2020 by
+ * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+#include <ft2build.h>
+#include "sfwoff2.h"
+#include "woff2tags.h"
+#include FT_TRUETYPE_TAGS_H
+#include FT_INTERNAL_DEBUG_H
+#include FT_INTERNAL_STREAM_H
+
+
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
+
+#include <brotli/decode.h>
+
+#endif
+
+
+ /**************************************************************************
+ *
+ * The macro FT_COMPONENT is used in trace mode. It is an implicit
+ * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+ * messages during execution.
+ */
+#undef FT_COMPONENT
+#define FT_COMPONENT sfwoff2
+
+
+#define READ_255USHORT( var ) FT_SET_ERROR( Read255UShort( stream, &var ) )
+
+#define READ_BASE128( var ) FT_SET_ERROR( ReadBase128( stream, &var ) )
+
+#define ROUND4( var ) ( ( var + 3 ) & ~3 )
+
+#define WRITE_USHORT( p, v ) \
+ do \
+ { \
+ *(p)++ = (FT_Byte)( (v) >> 8 ); \
+ *(p)++ = (FT_Byte)( (v) >> 0 ); \
+ \
+ } while ( 0 )
+
+#define WRITE_ULONG( p, v ) \
+ do \
+ { \
+ *(p)++ = (FT_Byte)( (v) >> 24 ); \
+ *(p)++ = (FT_Byte)( (v) >> 16 ); \
+ *(p)++ = (FT_Byte)( (v) >> 8 ); \
+ *(p)++ = (FT_Byte)( (v) >> 0 ); \
+ \
+ } while ( 0 )
+
+#define WRITE_SHORT( p, v ) \
+ do \
+ { \
+ *(p)++ = ( (v) >> 8 ); \
+ *(p)++ = ( (v) >> 0 ); \
+ \
+ } while ( 0 )
+
+#define WRITE_SFNT_BUF( buf, s ) \
+ write_buf( &sfnt, sfnt_size, &dest_offset, buf, s, memory )
+
+#define WRITE_SFNT_BUF_AT( offset, buf, s ) \
+ write_buf( &sfnt, sfnt_size, &offset, buf, s, memory )
+
+#define N_CONTOUR_STREAM 0
+#define N_POINTS_STREAM 1
+#define FLAG_STREAM 2
+#define GLYPH_STREAM 3
+#define COMPOSITE_STREAM 4
+#define BBOX_STREAM 5
+#define INSTRUCTION_STREAM 6
+
+
+ static void
+ stream_close( FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+
+
+ FT_FREE( stream->base );
+
+ stream->size = 0;
+ stream->base = NULL;
+ stream->close = NULL;
+ }
+
+
+ FT_CALLBACK_DEF( int )
+ compare_tags( const void* a,
+ const void* b )
+ {
+ WOFF2_Table table1 = *(WOFF2_Table*)a;
+ WOFF2_Table table2 = *(WOFF2_Table*)b;
+
+ FT_ULong tag1 = table1->Tag;
+ FT_ULong tag2 = table2->Tag;
+
+
+ if ( tag1 > tag2 )
+ return 1;
+ else if ( tag1 < tag2 )
+ return -1;
+ else
+ return 0;
+ }
+
+
+ static FT_Error
+ Read255UShort( FT_Stream stream,
+ FT_UShort* value )
+ {
+ static const FT_Int oneMoreByteCode1 = 255;
+ static const FT_Int oneMoreByteCode2 = 254;
+ static const FT_Int wordCode = 253;
+ static const FT_Int lowestUCode = 253;
+
+ FT_Error error = FT_Err_Ok;
+ FT_Byte code;
+ FT_Byte result_byte = 0;
+ FT_UShort result_short = 0;
+
+
+ if ( FT_READ_BYTE( code ) )
+ return error;
+ if ( code == wordCode )
+ {
+ /* Read next two bytes and store `FT_UShort' value. */
+ if ( FT_READ_USHORT( result_short ) )
+ return error;
+ *value = result_short;
+ return FT_Err_Ok;
+ }
+ else if ( code == oneMoreByteCode1 )
+ {
+ if ( FT_READ_BYTE( result_byte ) )
+ return error;
+ *value = result_byte + lowestUCode;
+ return FT_Err_Ok;
+ }
+ else if ( code == oneMoreByteCode2 )
+ {
+ if ( FT_READ_BYTE( result_byte ) )
+ return error;
+ *value = result_byte + lowestUCode * 2;
+ return FT_Err_Ok;
+ }
+ else
+ {
+ *value = code;
+ return FT_Err_Ok;
+ }
+ }
+
+
+ static FT_Error
+ ReadBase128( FT_Stream stream,
+ FT_ULong* value )
+ {
+ FT_ULong result = 0;
+ FT_Int i;
+ FT_Byte code;
+ FT_Error error = FT_Err_Ok;
+
+
+ for ( i = 0; i < 5; ++i )
+ {
+ code = 0;
+ if ( FT_READ_BYTE( code ) )
+ return error;
+
+ /* Leading zeros are invalid. */
+ if ( i == 0 && code == 0x80 )
+ return FT_THROW( Invalid_Table );
+
+ /* If any of top seven bits are set then we're about to overflow. */
+ if ( result & 0xfe000000 )
+ return FT_THROW( Invalid_Table );
+
+ result = ( result << 7 ) | ( code & 0x7f );
+
+ /* Spin until most significant bit of data byte is false. */
+ if ( ( code & 0x80 ) == 0 )
+ {
+ *value = result;
+ return FT_Err_Ok;
+ }
+ }
+
+ /* Make sure not to exceed the size bound. */
+ return FT_THROW( Invalid_Table );
+ }
+
+
+ /* Extend memory of `dst_bytes' buffer and copy data from `src'. */
+ static FT_Error
+ write_buf( FT_Byte** dst_bytes,
+ FT_ULong* dst_size,
+ FT_ULong* offset,
+ FT_Byte* src,
+ FT_ULong size,
+ FT_Memory memory )
+ {
+ FT_Error error = FT_Err_Ok;
+ /* We are reallocating memory for `dst', so its pointer may change. */
+ FT_Byte* dst = *dst_bytes;
+
+
+ /* Check whether we are within limits. */
+ if ( ( *offset + size ) > WOFF2_DEFAULT_MAX_SIZE )
+ return FT_THROW( Array_Too_Large );
+
+ /* Reallocate `dst'. */
+ if ( ( *offset + size ) > *dst_size )
+ {
+ FT_TRACE6(( "Reallocating %lu to %lu.\n",
+ *dst_size, (*offset + size) ));
+ if ( FT_REALLOC( dst,
+ (FT_ULong)( *dst_size ),
+ (FT_ULong)( *offset + size ) ) )
+ goto Exit;
+
+ *dst_size = *offset + size;
+ }
+
+ /* Copy data. */
+ ft_memcpy( dst + *offset, src, size );
+
+ *offset += size;
+ /* Set pointer of `dst' to its correct value. */
+ *dst_bytes = dst;
+
+ Exit:
+ return error;
+ }
+
+
+ /* Pad buffer to closest multiple of 4. */
+ static FT_Error
+ pad4( FT_Byte** sfnt_bytes,
+ FT_ULong* sfnt_size,
+ FT_ULong* out_offset,
+ FT_Memory memory )
+ {
+ FT_Byte* sfnt = *sfnt_bytes;
+ FT_ULong dest_offset = *out_offset;
+
+ FT_Byte zeroes[] = { 0, 0, 0 };
+ FT_ULong pad_bytes;
+
+
+ if ( dest_offset + 3 < dest_offset )
+ return FT_THROW( Invalid_Table );
+
+ pad_bytes = ROUND4( dest_offset ) - dest_offset;
+ if ( pad_bytes > 0 )
+ {
+ if ( WRITE_SFNT_BUF( &zeroes[0], pad_bytes ) )
+ return FT_THROW( Invalid_Table );
+ }
+
+ *sfnt_bytes = sfnt;
+ *out_offset = dest_offset;
+ return FT_Err_Ok;
+ }
+
+
+ /* Calculate table checksum of `buf'. */
+ static FT_Long
+ compute_ULong_sum( FT_Byte* buf,
+ FT_ULong size )
+ {
+ FT_ULong checksum = 0;
+ FT_ULong aligned_size = size & ~3;
+ FT_ULong i;
+ FT_ULong v;
+
+
+ for ( i = 0; i < aligned_size; i += 4 )
+ checksum += ( (FT_ULong)buf[i ] << 24 ) |
+ ( (FT_ULong)buf[i + 1] << 16 ) |
+ ( (FT_ULong)buf[i + 2] << 8 ) |
+ ( (FT_ULong)buf[i + 3] << 0 );
+
+ /* If size is not aligned to 4, treat as if it is padded with 0s. */
+ if ( size != aligned_size )
+ {
+ v = 0;
+ for ( i = aligned_size ; i < size; ++i )
+ v |= (FT_ULong)buf[i] << ( 24 - 8 * ( i & 3 ) );
+ checksum += v;
+ }
+
+ return checksum;
+ }
+
+
+ static FT_Error
+ woff2_decompress( FT_Byte* dst,
+ FT_ULong dst_size,
+ const FT_Byte* src,
+ FT_ULong src_size )
+ {
+#ifdef FT_CONFIG_OPTION_USE_BROTLI
+
+ FT_ULong uncompressed_size = dst_size;
+ BrotliDecoderResult result;
+
+
+ result = BrotliDecoderDecompress( src_size,
+ src,
+ &uncompressed_size,
+ dst );
+
+ if ( result != BROTLI_DECODER_RESULT_SUCCESS ||
+ uncompressed_size != dst_size )
+ {
+ FT_ERROR(( "woff2_decompress: Stream length mismatch.\n" ));
+ return FT_THROW( Invalid_Table );
+ }
+
+ FT_TRACE2(( "woff2_decompress: Brotli stream decompressed.\n" ));
+ return FT_Err_Ok;
+
+#else /* !FT_CONFIG_OPTION_USE_BROTLI */
+
+ FT_ERROR(( "woff2_decompress: Brotli support not available.\n" ));
+ return FT_THROW( Unimplemented_Feature );
+
+#endif /* !FT_CONFIG_OPTION_USE_BROTLI */
+ }
+
+
+ static WOFF2_Table
+ find_table( WOFF2_Table* tables,
+ FT_UShort num_tables,
+ FT_ULong tag )
+ {
+ FT_Int i;
+
+
+ for ( i = 0; i < num_tables; i++ )
+ {
+ if ( tables[i]->Tag == tag )
+ return tables[i];
+ }
+ return NULL;
+ }
+
+
+ /* Read `numberOfHMetrics' field from `hhea' table. */
+ static FT_Error
+ read_num_hmetrics( FT_Stream stream,
+ FT_UShort* num_hmetrics )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_UShort num_metrics;
+
+
+ if ( FT_STREAM_SKIP( 34 ) )
+ return FT_THROW( Invalid_Table );
+
+ if ( FT_READ_USHORT( num_metrics ) )
+ return FT_THROW( Invalid_Table );
+
+ *num_hmetrics = num_metrics;
+
+ return error;
+ }
+
+
+ /* An auxiliary function for overflow-safe addition. */
+ static FT_Int
+ with_sign( FT_Byte flag,
+ FT_Int base_val )
+ {
+ /* Precondition: 0 <= base_val < 65536 (to avoid overflow). */
+ return ( flag & 1 ) ? base_val : -base_val;
+ }
+
+
+ /* An auxiliary function for overflow-safe addition. */
+ static FT_Int
+ safe_int_addition( FT_Int a,
+ FT_Int b,
+ FT_Int* result )
+ {
+ if ( ( ( a > 0 ) && ( b > FT_INT_MAX - a ) ) ||
+ ( ( a < 0 ) && ( b < FT_INT_MIN - a ) ) )
+ return FT_THROW( Invalid_Table );
+
+ *result = a + b;
+ return FT_Err_Ok;
+ }
+
+
+ /*
+ * Decode variable-length (flag, xCoordinate, yCoordinate) triplet for a
+ * simple glyph. See
+ *
+ * https://www.w3.org/TR/WOFF2/#triplet_decoding
+ */
+ static FT_Error
+ triplet_decode( const FT_Byte* flags_in,
+ const FT_Byte* in,
+ FT_ULong in_size,
+ FT_ULong n_points,
+ WOFF2_Point result,
+ FT_ULong* in_bytes_used )
+ {
+ FT_Int x = 0;
+ FT_Int y = 0;
+ FT_Int dx;
+ FT_Int dy;
+ FT_Int b0, b1, b2;
+
+ FT_ULong triplet_index = 0;
+ FT_ULong data_bytes;
+
+ FT_UInt i;
+
+
+ if ( n_points > in_size )
+ return FT_THROW( Invalid_Table );
+
+ for ( i = 0; i < n_points; ++i )
+ {
+ FT_Byte flag = flags_in[i];
+ FT_Bool on_curve = !( flag >> 7 );
+
+
+ flag &= 0x7f;
+ if ( flag < 84 )
+ data_bytes = 1;
+ else if ( flag < 120 )
+ data_bytes = 2;
+ else if ( flag < 124 )
+ data_bytes = 3;
+ else
+ data_bytes = 4;
+
+ /* Overflow checks */
+ if ( triplet_index + data_bytes > in_size ||
+ triplet_index + data_bytes < triplet_index )
+ return FT_THROW( Invalid_Table );
+
+ if ( flag < 10 )
+ {
+ dx = 0;
+ dy = with_sign( flag,
+ ( ( flag & 14 ) << 7 ) + in[triplet_index] );
+ }
+ else if ( flag < 20 )
+ {
+ dx = with_sign( flag,
+ ( ( ( flag - 10 ) & 14 ) << 7 ) +
+ in[triplet_index] );
+ dy = 0;
+ }
+ else if ( flag < 84 )
+ {
+ b0 = flag - 20;
+ b1 = in[triplet_index];
+ dx = with_sign( flag,
+ 1 + ( b0 & 0x30 ) + ( b1 >> 4 ) );
+ dy = with_sign( flag >> 1,
+ 1 + ( ( b0 & 0x0c ) << 2 ) + ( b1 & 0x0f ) );
+ }
+ else if ( flag < 120 )
+ {
+ b0 = flag - 84;
+ dx = with_sign( flag,
+ 1 + ( ( b0 / 12 ) << 8 ) + in[triplet_index] );
+ dy = with_sign( flag >> 1,
+ 1 + ( ( ( b0 % 12 ) >> 2 ) << 8 ) +
+ in[triplet_index + 1] );
+ }
+ else if ( flag < 124 )
+ {
+ b2 = in[triplet_index + 1];
+ dx = with_sign( flag,
+ ( in[triplet_index] << 4 ) + ( b2 >> 4 ) );
+ dy = with_sign( flag >> 1,
+ ( ( b2 & 0x0f ) << 8 ) + in[triplet_index + 2] );
+ }
+ else
+ {
+ dx = with_sign( flag,
+ ( in[triplet_index] << 8 ) +
+ in[triplet_index + 1] );
+ dy = with_sign( flag >> 1,
+ ( in[triplet_index + 2] << 8 ) +
+ in[triplet_index + 3] );
+ }
+
+ triplet_index += data_bytes;
+
+ if ( safe_int_addition( x, dx, &x ) )
+ return FT_THROW( Invalid_Table );
+
+ if ( safe_int_addition( y, dy, &y ) )
+ return FT_THROW( Invalid_Table );
+
+ result[i].x = x;
+ result[i].y = y;
+ result[i].on_curve = on_curve;
+ }
+
+ *in_bytes_used = triplet_index;
+ return FT_Err_Ok;
+ }
+
+
+ /* Store decoded points in glyph buffer. */
+ static FT_Error
+ store_points( FT_ULong n_points,
+ const WOFF2_Point points,
+ FT_UShort n_contours,
+ FT_UShort instruction_len,
+ FT_Byte* dst,
+ FT_ULong dst_size,
+ FT_ULong* glyph_size )
+ {
+ FT_UInt flag_offset = 10 + ( 2 * n_contours ) + 2 + instruction_len;
+ FT_Int last_flag = -1;
+ FT_Int repeat_count = 0;
+ FT_Int last_x = 0;
+ FT_Int last_y = 0;
+ FT_UInt x_bytes = 0;
+ FT_UInt y_bytes = 0;
+ FT_UInt xy_bytes;
+ FT_UInt i;
+ FT_UInt x_offset;
+ FT_UInt y_offset;
+ FT_Byte* pointer;
+
+
+ for ( i = 0; i < n_points; ++i )
+ {
+ const WOFF2_PointRec point = points[i];
+
+ FT_Int flag = point.on_curve ? GLYF_ON_CURVE : 0;
+ FT_Int dx = point.x - last_x;
+ FT_Int dy = point.y - last_y;
+
+
+ if ( dx == 0 )
+ flag |= GLYF_THIS_X_IS_SAME;
+ else if ( dx > -256 && dx < 256 )
+ {
+ flag |= GLYF_X_SHORT | ( dx > 0 ? GLYF_THIS_X_IS_SAME : 0 );
+ x_bytes += 1;
+ }
+ else
+ x_bytes += 2;
+
+ if ( dy == 0 )
+ flag |= GLYF_THIS_Y_IS_SAME;
+ else if ( dy > -256 && dy < 256 )
+ {
+ flag |= GLYF_Y_SHORT | ( dy > 0 ? GLYF_THIS_Y_IS_SAME : 0 );
+ y_bytes += 1;
+ }
+ else
+ y_bytes += 2;
+
+ if ( flag == last_flag && repeat_count != 255 )
+ {
+ dst[flag_offset - 1] |= GLYF_REPEAT;
+ repeat_count++;
+ }
+ else
+ {
+ if ( repeat_count != 0 )
+ {
+ if ( flag_offset >= dst_size )
+ return FT_THROW( Invalid_Table );
+
+ dst[flag_offset++] = repeat_count;
+ }
+ if ( flag_offset >= dst_size )
+ return FT_THROW( Invalid_Table );
+
+ dst[flag_offset++] = flag;
+ repeat_count = 0;
+ }
+
+ last_x = point.x;
+ last_y = point.y;
+ last_flag = flag;
+ }
+
+ if ( repeat_count != 0 )
+ {
+ if ( flag_offset >= dst_size )
+ return FT_THROW( Invalid_Table );
+
+ dst[flag_offset++] = repeat_count;
+ }
+
+ xy_bytes = x_bytes + y_bytes;
+ if ( xy_bytes < x_bytes ||
+ flag_offset + xy_bytes < flag_offset ||
+ flag_offset + xy_bytes > dst_size )
+ return FT_THROW( Invalid_Table );
+
+ x_offset = flag_offset;
+ y_offset = flag_offset + x_bytes;
+ last_x = 0;
+ last_y = 0;
+
+ for ( i = 0; i < n_points; ++i )
+ {
+ FT_Int dx = points[i].x - last_x;
+ FT_Int dy = points[i].y - last_y;
+
+
+ if ( dx == 0 )
+ ;
+ else if ( dx > -256 && dx < 256 )
+ dst[x_offset++] = FT_ABS( dx );
+ else
+ {
+ pointer = dst + x_offset;
+ WRITE_SHORT( pointer, dx );
+ x_offset += 2;
+ }
+
+ last_x += dx;
+
+ if ( dy == 0 )
+ ;
+ else if ( dy > -256 && dy < 256 )
+ dst[y_offset++] = FT_ABS( dy );
+ else
+ {
+ pointer = dst + y_offset;
+ WRITE_SHORT( pointer, dy );
+ y_offset += 2;
+ }
+
+ last_y += dy;
+ }
+
+ *glyph_size = y_offset;
+ return FT_Err_Ok;
+ }
+
+
+ static void
+ compute_bbox( FT_ULong n_points,
+ const WOFF2_Point points,
+ FT_Byte* dst,
+ FT_UShort* src_x_min )
+ {
+ FT_Int x_min = 0;
+ FT_Int y_min = 0;
+ FT_Int x_max = 0;
+ FT_Int y_max = 0;
+
+ FT_UInt i;
+
+ FT_ULong offset;
+ FT_Byte* pointer;
+
+
+ if ( n_points > 0 )
+ {
+ x_min = points[0].x;
+ y_min = points[0].y;
+ x_max = points[0].x;
+ y_max = points[0].y;
+ }
+
+ for ( i = 1; i < n_points; ++i )
+ {
+ FT_Int x = points[i].x;
+ FT_Int y = points[i].y;
+
+
+ x_min = FT_MIN( x, x_min );
+ y_min = FT_MIN( y, y_min );
+ x_max = FT_MAX( x, x_max );
+ y_max = FT_MAX( y, y_max );
+ }
+
+ /* Write values to `glyf' record. */
+ offset = 2;
+ pointer = dst + offset;
+
+ WRITE_SHORT( pointer, x_min );
+ WRITE_SHORT( pointer, y_min );
+ WRITE_SHORT( pointer, x_max );
+ WRITE_SHORT( pointer, y_max );
+
+ *src_x_min = (FT_UShort)x_min;
+ }
+
+
+ static FT_Error
+ compositeGlyph_size( FT_Stream stream,
+ FT_ULong offset,
+ FT_ULong* size,
+ FT_Bool* have_instructions )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_ULong start_offset = offset;
+ FT_Bool we_have_inst = FALSE;
+ FT_UShort flags = FLAG_MORE_COMPONENTS;
+
+
+ if ( FT_STREAM_SEEK( start_offset ) )
+ goto Exit;
+ while ( flags & FLAG_MORE_COMPONENTS )
+ {
+ FT_ULong arg_size;
+
+
+ if ( FT_READ_USHORT( flags ) )
+ goto Exit;
+ we_have_inst |= ( flags & FLAG_WE_HAVE_INSTRUCTIONS ) != 0;
+ /* glyph index */
+ arg_size = 2;
+ if ( flags & FLAG_ARG_1_AND_2_ARE_WORDS )
+ arg_size += 4;
+ else
+ arg_size += 2;
+
+ if ( flags & FLAG_WE_HAVE_A_SCALE )
+ arg_size += 2;
+ else if ( flags & FLAG_WE_HAVE_AN_X_AND_Y_SCALE )
+ arg_size += 4;
+ else if ( flags & FLAG_WE_HAVE_A_TWO_BY_TWO )
+ arg_size += 8;
+
+ if ( FT_STREAM_SKIP( arg_size ) )
+ goto Exit;
+ }
+
+ *size = FT_STREAM_POS() - start_offset;
+ *have_instructions = we_have_inst;
+
+ Exit:
+ return error;
+ }
+
+
+ /* Store loca values (provided by `reconstruct_glyf') to output stream. */
+ static FT_Error
+ store_loca( FT_ULong* loca_values,
+ FT_ULong loca_values_size,
+ FT_UShort index_format,
+ FT_ULong* checksum,
+ FT_Byte** sfnt_bytes,
+ FT_ULong* sfnt_size,
+ FT_ULong* out_offset,
+ FT_Memory memory )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_Byte* sfnt = *sfnt_bytes;
+ FT_ULong dest_offset = *out_offset;
+
+ FT_Byte* loca_buf = NULL;
+ FT_Byte* dst = NULL;
+
+ FT_UInt i = 0;
+ FT_ULong loca_buf_size;
+
+ const FT_ULong offset_size = index_format ? 4 : 2;
+
+
+ if ( ( loca_values_size << 2 ) >> 2 != loca_values_size )
+ goto Fail;
+
+ loca_buf_size = loca_values_size * offset_size;
+ if ( FT_NEW_ARRAY( loca_buf, loca_buf_size ) )
+ goto Fail;
+
+ dst = loca_buf;
+ for ( i = 0; i < loca_values_size; i++ )
+ {
+ FT_ULong value = loca_values[i];
+
+
+ if ( index_format )
+ WRITE_ULONG( dst, value );
+ else
+ WRITE_USHORT( dst, ( value >> 1 ) );
+ }
+
+ *checksum = compute_ULong_sum( loca_buf, loca_buf_size );
+ /* Write `loca' table to sfnt buffer. */
+ if ( WRITE_SFNT_BUF( loca_buf, loca_buf_size ) )
+ goto Fail;
+
+ /* Set pointer `sfnt_bytes' to its correct value. */
+ *sfnt_bytes = sfnt;
+ *out_offset = dest_offset;
+
+ FT_FREE( loca_buf );
+ return error;
+
+ Fail:
+ if ( !error )
+ error = FT_THROW( Invalid_Table );
+
+ FT_FREE( loca_buf );
+
+ return error;
+ }
+
+
+ static FT_Error
+ reconstruct_glyf( FT_Stream stream,
+ FT_ULong* glyf_checksum,
+ FT_ULong* loca_checksum,
+ FT_Byte** sfnt_bytes,
+ FT_ULong* sfnt_size,
+ FT_ULong* out_offset,
+ WOFF2_Info info,
+ FT_Memory memory )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_Byte* sfnt = *sfnt_bytes;
+
+ /* current position in stream */
+ const FT_ULong pos = FT_STREAM_POS();
+
+ FT_UInt num_substreams = 7;
+
+ FT_UShort num_glyphs;
+ FT_UShort index_format;
+ FT_ULong expected_loca_length;
+ FT_UInt offset;
+ FT_UInt i;
+ FT_ULong points_size;
+ FT_ULong bitmap_length;
+ FT_ULong glyph_buf_size;
+ FT_ULong bbox_bitmap_offset;
+
+ const FT_ULong glyf_start = *out_offset;
+ FT_ULong dest_offset = *out_offset;
+
+ WOFF2_Substream substreams = NULL;
+
+ FT_ULong* loca_values = NULL;
+ FT_UShort* n_points_arr = NULL;
+ FT_Byte* glyph_buf = NULL;
+ WOFF2_Point points = NULL;
+
+
+ if ( FT_NEW_ARRAY( substreams, num_substreams ) )
+ goto Fail;
+
+ if ( FT_STREAM_SKIP( 4 ) )
+ goto Fail;
+ if ( FT_READ_USHORT( num_glyphs ) )
+ goto Fail;
+ if ( FT_READ_USHORT( index_format ) )
+ goto Fail;
+
+ FT_TRACE4(( "num_glyphs = %u; index_format = %u\n",
+ num_glyphs, index_format ));
+
+ info->num_glyphs = num_glyphs;
+
+ /* Calculate expected length of loca and compare. */
+ /* See https://www.w3.org/TR/WOFF2/#conform-mustRejectLoca */
+ /* index_format = 0 => Short version `loca'. */
+ /* index_format = 1 => Long version `loca'. */
+ expected_loca_length = ( index_format ? 4 : 2 ) *
+ ( (FT_ULong)num_glyphs + 1 );
+ if ( info->loca_table->dst_length != expected_loca_length )
+ goto Fail;
+
+ offset = ( 2 + num_substreams ) * 4;
+ if ( offset > info->glyf_table->TransformLength )
+ goto Fail;
+
+ for ( i = 0; i < num_substreams; ++i )
+ {
+ FT_ULong substream_size;
+
+
+ if ( FT_READ_ULONG( substream_size ) )
+ goto Fail;
+ if ( substream_size > info->glyf_table->TransformLength - offset )
+ goto Fail;
+
+ substreams[i].start = pos + offset;
+ substreams[i].offset = pos + offset;
+ substreams[i].size = substream_size;
+
+ FT_TRACE5(( " Substream %d: offset = %lu; size = %lu;\n",
+ i, substreams[i].offset, substreams[i].size ));
+ offset += substream_size;
+ }
+
+ if ( FT_NEW_ARRAY( loca_values, num_glyphs + 1 ) )
+ goto Fail;
+
+ points_size = 0;
+ bbox_bitmap_offset = substreams[BBOX_STREAM].offset;
+
+ /* Size of bboxBitmap = 4 * floor((numGlyphs + 31) / 32) */
+ bitmap_length = ( ( num_glyphs + 31 ) >> 5 ) << 2;
+ substreams[BBOX_STREAM].offset += bitmap_length;
+
+ glyph_buf_size = WOFF2_DEFAULT_GLYPH_BUF;
+ if ( FT_NEW_ARRAY( glyph_buf, glyph_buf_size ) )
+ goto Fail;
+
+ if ( FT_NEW_ARRAY( info->x_mins, num_glyphs ) )
+ goto Fail;
+
+ for ( i = 0; i < num_glyphs; ++i )
+ {
+ FT_ULong glyph_size = 0;
+ FT_UShort n_contours = 0;
+ FT_Bool have_bbox = FALSE;
+ FT_Byte bbox_bitmap;
+ FT_ULong bbox_offset;
+ FT_UShort x_min = 0;
+
+
+ /* Set `have_bbox'. */
+ bbox_offset = bbox_bitmap_offset + ( i >> 3 );
+ if ( FT_STREAM_SEEK( bbox_offset ) ||
+ FT_READ_BYTE( bbox_bitmap ) )
+ goto Fail;
+ if ( bbox_bitmap & ( 0x80 >> ( i & 7 ) ) )
+ have_bbox = TRUE;
+
+ /* Read value from `nContourStream'. */
+ if ( FT_STREAM_SEEK( substreams[N_CONTOUR_STREAM].offset ) ||
+ FT_READ_USHORT( n_contours ) )
+ goto Fail;
+ substreams[N_CONTOUR_STREAM].offset += 2;
+
+ if ( n_contours == 0xffff )
+ {
+ /* composite glyph */
+ FT_Bool have_instructions = FALSE;
+ FT_UShort instruction_size = 0;
+ FT_ULong composite_size;
+ FT_ULong size_needed;
+ FT_Byte* pointer = NULL;
+
+
+ /* Composite glyphs must have explicit bbox. */
+ if ( !have_bbox )
+ goto Fail;
+
+ if ( compositeGlyph_size( stream,
+ substreams[COMPOSITE_STREAM].offset,
+ &composite_size,
+ &have_instructions) )
+ goto Fail;
+
+ if ( have_instructions )
+ {
+ if ( FT_STREAM_SEEK( substreams[GLYPH_STREAM].offset ) ||
+ READ_255USHORT( instruction_size ) )
+ goto Fail;
+ substreams[GLYPH_STREAM].offset = FT_STREAM_POS();
+ }
+
+ size_needed = 12 + composite_size + instruction_size;
+ if ( glyph_buf_size < size_needed )
+ {
+ if ( FT_RENEW_ARRAY( glyph_buf, glyph_buf_size, size_needed ) )
+ goto Fail;
+ glyph_buf_size = size_needed;
+ }
+
+ pointer = glyph_buf + glyph_size;
+ WRITE_USHORT( pointer, n_contours );
+ glyph_size += 2;
+
+ /* Read x_min for current glyph. */
+ if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
+ FT_READ_USHORT( x_min ) )
+ goto Fail;
+ /* No increment here because we read again. */
+
+ if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
+ FT_STREAM_READ( glyph_buf + glyph_size, 8 ) )
+ goto Fail;
+
+ substreams[BBOX_STREAM].offset += 8;
+ glyph_size += 8;
+
+ if ( FT_STREAM_SEEK( substreams[COMPOSITE_STREAM].offset ) ||
+ FT_STREAM_READ( glyph_buf + glyph_size, composite_size ) )
+ goto Fail;
+
+ substreams[COMPOSITE_STREAM].offset += composite_size;
+ glyph_size += composite_size;
+
+ if ( have_instructions )
+ {
+ pointer = glyph_buf + glyph_size;
+ WRITE_USHORT( pointer, instruction_size );
+ glyph_size += 2;
+
+ if ( FT_STREAM_SEEK( substreams[INSTRUCTION_STREAM].offset ) ||
+ FT_STREAM_READ( glyph_buf + glyph_size, instruction_size ) )
+ goto Fail;
+
+ substreams[INSTRUCTION_STREAM].offset += instruction_size;
+ glyph_size += instruction_size;
+ }
+ }
+ else if ( n_contours > 0 )
+ {
+ /* simple glyph */
+ FT_ULong total_n_points = 0;
+ FT_UShort n_points_contour;
+ FT_UInt j;
+ FT_ULong flag_size;
+ FT_ULong triplet_size;
+ FT_ULong triplet_bytes_used;
+ FT_Byte* flags_buf = NULL;
+ FT_Byte* triplet_buf = NULL;
+ FT_UShort instruction_size;
+ FT_ULong size_needed;
+ FT_Int end_point;
+ FT_UInt contour_ix;
+
+ FT_Byte* pointer = NULL;
+
+
+ if ( FT_NEW_ARRAY( n_points_arr, n_contours ) )
+ goto Fail;
+
+ if ( FT_STREAM_SEEK( substreams[N_POINTS_STREAM].offset ) )
+ goto Fail;
+
+ for ( j = 0; j < n_contours; ++j )
+ {
+ if ( READ_255USHORT( n_points_contour ) )
+ goto Fail;
+ n_points_arr[j] = n_points_contour;
+ /* Prevent negative/overflow. */
+ if ( total_n_points + n_points_contour < total_n_points )
+ goto Fail;
+ total_n_points += n_points_contour;
+ }
+ substreams[N_POINTS_STREAM].offset = FT_STREAM_POS();
+
+ flag_size = total_n_points;
+ if ( flag_size > substreams[FLAG_STREAM].size )
+ goto Fail;
+
+ flags_buf = stream->base + substreams[FLAG_STREAM].offset;
+ triplet_buf = stream->base + substreams[GLYPH_STREAM].offset;
+
+ if ( substreams[GLYPH_STREAM].size <
+ ( substreams[GLYPH_STREAM].offset -
+ substreams[GLYPH_STREAM].start ) )
+ goto Fail;
+
+ triplet_size = substreams[GLYPH_STREAM].size -
+ ( substreams[GLYPH_STREAM].offset -
+ substreams[GLYPH_STREAM].start );
+ triplet_bytes_used = 0;
+
+ /* Create array to store point information. */
+ points_size = total_n_points;
+ if ( FT_NEW_ARRAY( points, points_size ) )
+ goto Fail;
+
+ if ( triplet_decode( flags_buf,
+ triplet_buf,
+ triplet_size,
+ total_n_points,
+ points,
+ &triplet_bytes_used ) )
+ goto Fail;
+
+ substreams[FLAG_STREAM].offset += flag_size;
+ substreams[GLYPH_STREAM].offset += triplet_bytes_used;
+
+ if ( FT_STREAM_SEEK( substreams[GLYPH_STREAM].offset ) ||
+ READ_255USHORT( instruction_size ) )
+ goto Fail;
+
+ substreams[GLYPH_STREAM].offset = FT_STREAM_POS();
+
+ if ( total_n_points >= ( 1 << 27 ) )
+ goto Fail;
+
+ size_needed = 12 +
+ ( 2 * n_contours ) +
+ ( 5 * total_n_points ) +
+ instruction_size;
+ if ( glyph_buf_size < size_needed )
+ {
+ if ( FT_RENEW_ARRAY( glyph_buf, glyph_buf_size, size_needed ) )
+ goto Fail;
+ glyph_buf_size = size_needed;
+ }
+
+ pointer = glyph_buf + glyph_size;
+ WRITE_USHORT( pointer, n_contours );
+ glyph_size += 2;
+
+ if ( have_bbox )
+ {
+ /* Read x_min for current glyph. */
+ if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
+ FT_READ_USHORT( x_min ) )
+ goto Fail;
+ /* No increment here because we read again. */
+
+ if ( FT_STREAM_SEEK( substreams[BBOX_STREAM].offset ) ||
+ FT_STREAM_READ( glyph_buf + glyph_size, 8 ) )
+ goto Fail;
+ substreams[BBOX_STREAM].offset += 8;
+ }
+ else
+ compute_bbox( total_n_points, points, glyph_buf, &x_min );
+
+ glyph_size = CONTOUR_OFFSET_END_POINT;
+
+ pointer = glyph_buf + glyph_size;
+ end_point = -1;
+
+ for ( contour_ix = 0; contour_ix < n_contours; ++contour_ix )
+ {
+ end_point += n_points_arr[contour_ix];
+ if ( end_point >= 65536 )
+ goto Fail;
+
+ WRITE_SHORT( pointer, end_point );
+ glyph_size += 2;
+ }
+
+ WRITE_USHORT( pointer, instruction_size );
+ glyph_size += 2;
+
+ if ( FT_STREAM_SEEK( substreams[INSTRUCTION_STREAM].offset ) ||
+ FT_STREAM_READ( glyph_buf + glyph_size, instruction_size ) )
+ goto Fail;
+
+ substreams[INSTRUCTION_STREAM].offset += instruction_size;
+ glyph_size += instruction_size;
+
+ if ( store_points( total_n_points,
+ points,
+ n_contours,
+ instruction_size,
+ glyph_buf,
+ glyph_buf_size,
+ &glyph_size ) )
+ goto Fail;
+
+ FT_FREE( points );
+ FT_FREE( n_points_arr );
+ }
+ else
+ {
+ /* Empty glyph. */
+ /* Must not have a bbox. */
+ if ( have_bbox )
+ {
+ FT_ERROR(( "Empty glyph has a bbox.\n" ));
+ goto Fail;
+ }
+ }
+
+ loca_values[i] = dest_offset - glyf_start;
+
+ if ( WRITE_SFNT_BUF( glyph_buf, glyph_size ) )
+ goto Fail;
+
+ if ( pad4( &sfnt, sfnt_size, &dest_offset, memory ) )
+ goto Fail;
+
+ *glyf_checksum += compute_ULong_sum( glyph_buf, glyph_size );
+
+ /* Store x_mins, may be required to reconstruct `hmtx'. */
+ if ( n_contours > 0 )
+ info->x_mins[i] = x_min;
+ }
+
+ info->glyf_table->dst_length = dest_offset - info->glyf_table->dst_offset;
+ info->loca_table->dst_offset = dest_offset;
+
+ /* `loca[n]' will be equal to the length of the `glyf' table. */
+ loca_values[num_glyphs] = info->glyf_table->dst_length;
+
+ if ( store_loca( loca_values,
+ num_glyphs + 1,
+ index_format,
+ loca_checksum,
+ &sfnt,
+ sfnt_size,
+ &dest_offset,
+ memory ) )
+ goto Fail;
+
+ info->loca_table->dst_length = dest_offset - info->loca_table->dst_offset;
+
+ FT_TRACE4(( " loca table info:\n" ));
+ FT_TRACE4(( " dst_offset = %lu\n", info->loca_table->dst_offset ));
+ FT_TRACE4(( " dst_length = %lu\n", info->loca_table->dst_length ));
+ FT_TRACE4(( " checksum = %09x\n", *loca_checksum ));
+
+ /* Set pointer `sfnt_bytes' to its correct value. */
+ *sfnt_bytes = sfnt;
+ *out_offset = dest_offset;
+
+ FT_FREE( substreams );
+ FT_FREE( loca_values );
+ FT_FREE( n_points_arr );
+ FT_FREE( glyph_buf );
+ FT_FREE( points );
+
+ return error;
+
+ Fail:
+ if ( !error )
+ error = FT_THROW( Invalid_Table );
+
+ /* Set pointer `sfnt_bytes' to its correct value. */
+ *sfnt_bytes = sfnt;
+
+ FT_FREE( substreams );
+ FT_FREE( loca_values );
+ FT_FREE( n_points_arr );
+ FT_FREE( glyph_buf );
+ FT_FREE( points );
+
+ return error;
+ }
+
+
+ /* Get `x_mins' for untransformed `glyf' table. */
+ static FT_Error
+ get_x_mins( FT_Stream stream,
+ WOFF2_Table* tables,
+ FT_UShort num_tables,
+ WOFF2_Info info,
+ FT_Memory memory )
+ {
+ FT_UShort num_glyphs;
+ FT_UShort index_format;
+ FT_ULong glyf_offset;
+ FT_UShort glyf_offset_short;
+ FT_ULong loca_offset;
+ FT_Int i;
+ FT_Error error = FT_Err_Ok;
+ FT_ULong offset_size;
+
+ /* At this point of time those tables might not have been read yet. */
+ const WOFF2_Table maxp_table = find_table( tables, num_tables,
+ TTAG_maxp );
+ const WOFF2_Table head_table = find_table( tables, num_tables,
+ TTAG_head );
+
+
+ if ( !maxp_table )
+ {
+ FT_ERROR(( "`maxp' table is missing.\n" ));
+ return FT_THROW( Invalid_Table );
+ }
+
+ if ( !head_table )
+ {
+ FT_ERROR(( "`head' table is missing.\n" ));
+ return FT_THROW( Invalid_Table );
+ }
+
+ /* Read `numGlyphs' field from `maxp' table. */
+ if ( FT_STREAM_SEEK( maxp_table->src_offset ) || FT_STREAM_SKIP( 8 ) )
+ return error;
+
+ if ( FT_READ_USHORT( num_glyphs ) )
+ return error;
+
+ info->num_glyphs = num_glyphs;
+
+ /* Read `indexToLocFormat' field from `head' table. */
+ if ( FT_STREAM_SEEK( head_table->src_offset ) ||
+ FT_STREAM_SKIP( 50 ) )
+ return error;
+
+ if ( FT_READ_USHORT( index_format ) )
+ return error;
+
+ offset_size = index_format ? 4 : 2;
+
+ /* Create `x_mins' array. */
+ if ( FT_NEW_ARRAY( info->x_mins, num_glyphs ) )
+ return error;
+
+ loca_offset = info->loca_table->src_offset;
+
+ for ( i = 0; i < num_glyphs; ++i )
+ {
+ if ( FT_STREAM_SEEK( loca_offset ) )
+ return error;
+
+ loca_offset += offset_size;
+
+ if ( index_format )
+ {
+ if ( FT_READ_ULONG( glyf_offset ) )
+ return error;
+ }
+ else
+ {
+ if ( FT_READ_USHORT( glyf_offset_short ) )
+ return error;
+
+ glyf_offset = (FT_ULong)( glyf_offset_short );
+ glyf_offset = glyf_offset << 1;
+ }
+
+ glyf_offset += info->glyf_table->src_offset;
+
+ if ( FT_STREAM_SEEK( glyf_offset ) || FT_STREAM_SKIP( 2 ) )
+ return error;
+
+ if ( FT_READ_USHORT( info->x_mins[i] ) )
+ return error;
+ }
+
+ return error;
+ }
+
+
+ static FT_Error
+ reconstruct_hmtx( FT_Stream stream,
+ FT_UShort num_glyphs,
+ FT_UShort num_hmetrics,
+ FT_Short* x_mins,
+ FT_ULong* checksum,
+ FT_Byte** sfnt_bytes,
+ FT_ULong* sfnt_size,
+ FT_ULong* out_offset,
+ FT_Memory memory )
+ {
+ FT_Error error = FT_Err_Ok;
+ FT_Byte* sfnt = *sfnt_bytes;
+ FT_ULong dest_offset = *out_offset;
+
+ FT_Byte hmtx_flags;
+ FT_Bool has_proportional_lsbs, has_monospace_lsbs;
+ FT_ULong hmtx_table_size;
+ FT_Int i;
+
+ FT_UShort* advance_widths = NULL;
+ FT_Short* lsbs = NULL;
+ FT_Byte* hmtx_table = NULL;
+ FT_Byte* dst = NULL;
+
+
+ if ( FT_READ_BYTE( hmtx_flags ) )
+ goto Fail;
+
+ has_proportional_lsbs = ( hmtx_flags & 1 ) == 0;
+ has_monospace_lsbs = ( hmtx_flags & 2 ) == 0;
+
+ /* Bits 2-7 are reserved and MUST be zero. */
+ if ( ( hmtx_flags & 0xFC ) != 0 )
+ goto Fail;
+
+ /* Are you REALLY transformed? */
+ if ( has_proportional_lsbs && has_monospace_lsbs )
+ goto Fail;
+
+ /* Cannot have a transformed `hmtx' without `glyf'. */
+ if ( ( num_hmetrics > num_glyphs ) ||
+ ( num_hmetrics < 1 ) )
+ goto Fail;
+
+ /* Must have at least one entry. */
+ if ( num_hmetrics < 1 )
+ goto Fail;
+
+ if ( FT_NEW_ARRAY( advance_widths, num_hmetrics ) ||
+ FT_NEW_ARRAY( lsbs, num_glyphs ) )
+ goto Fail;
+
+ /* Read `advanceWidth' stream. Always present. */
+ for ( i = 0; i < num_hmetrics; i++ )
+ {
+ FT_UShort advance_width;
+
+
+ if ( FT_READ_USHORT( advance_width ) )
+ goto Fail;
+
+ advance_widths[i] = advance_width;
+ }
+
+ /* lsb values for proportional glyphs. */
+ for ( i = 0; i < num_hmetrics; i++ )
+ {
+ FT_Short lsb;
+
+
+ if ( has_proportional_lsbs )
+ {
+ if ( FT_READ_SHORT( lsb ) )
+ goto Fail;
+ }
+ else
+ lsb = x_mins[i];
+
+ lsbs[i] = lsb;
+ }
+
+ /* lsb values for monospaced glyphs. */
+ for ( i = num_hmetrics; i < num_glyphs; i++ )
+ {
+ FT_Short lsb;
+
+
+ if ( has_monospace_lsbs )
+ {
+ if ( FT_READ_SHORT( lsb ) )
+ goto Fail;
+ }
+ else
+ lsb = x_mins[i];
+
+ lsbs[i] = lsb;
+ }
+
+ /* Build the hmtx table. */
+ hmtx_table_size = 2 * num_hmetrics + 2 * num_glyphs;
+ if ( FT_NEW_ARRAY( hmtx_table, hmtx_table_size ) )
+ goto Fail;
+
+ dst = hmtx_table;
+ FT_TRACE6(( "hmtx values: \n" ));
+ for ( i = 0; i < num_glyphs; i++ )
+ {
+ if ( i < num_hmetrics )
+ {
+ WRITE_SHORT( dst, advance_widths[i] );
+ FT_TRACE6(( "%d ", advance_widths[i] ));
+ }
+
+ WRITE_SHORT( dst, lsbs[i] );
+ FT_TRACE6(( "%d ", lsbs[i] ));
+ }
+ FT_TRACE6(( "\n" ));
+
+ *checksum = compute_ULong_sum( hmtx_table, hmtx_table_size );
+ /* Write `hmtx' table to sfnt buffer. */
+ if ( WRITE_SFNT_BUF( hmtx_table, hmtx_table_size ) )
+ goto Fail;
+
+ /* Set pointer `sfnt_bytes' to its correct value. */
+ *sfnt_bytes = sfnt;
+ *out_offset = dest_offset;
+
+ FT_FREE( advance_widths );
+ FT_FREE( lsbs );
+ FT_FREE( hmtx_table );
+
+ return error;
+
+ Fail:
+ FT_FREE( advance_widths );
+ FT_FREE( lsbs );
+ FT_FREE( hmtx_table );
+
+ if ( !error )
+ error = FT_THROW( Invalid_Table );
+
+ return error;
+ }
+
+
+ static FT_Error
+ reconstruct_font( FT_Byte* transformed_buf,
+ FT_ULong transformed_buf_size,
+ WOFF2_Table* indices,
+ WOFF2_Header woff2,
+ WOFF2_Info info,
+ FT_Byte** sfnt_bytes,
+ FT_ULong* sfnt_size,
+ FT_Memory memory )
+ {
+ /* Memory management of `transformed_buf' is handled by the caller. */
+
+ FT_Error error = FT_Err_Ok;
+ FT_Stream stream = NULL;
+ FT_Byte* buf_cursor = NULL;
+ FT_Byte* table_entry = NULL;
+
+ /* We are reallocating memory for `sfnt', so its pointer may change. */
+ FT_Byte* sfnt = *sfnt_bytes;
+
+ FT_UShort num_tables = woff2->num_tables;
+ FT_ULong dest_offset = 12 + num_tables * 16UL;
+
+ FT_ULong checksum = 0;
+ FT_ULong loca_checksum = 0;
+ FT_Int nn = 0;
+ FT_UShort num_hmetrics = 0;
+ FT_ULong font_checksum = info->header_checksum;
+ FT_Bool is_glyf_xform = FALSE;
+
+ FT_ULong table_entry_offset = 12;
+
+
+ /* A few table checks before reconstruction. */
+ /* `glyf' must be present with `loca'. */
+ info->glyf_table = find_table( indices, num_tables, TTAG_glyf );
+ info->loca_table = find_table( indices, num_tables, TTAG_loca );
+
+ if ( ( info->glyf_table == NULL ) ^ ( info->loca_table == NULL ) )
+ {
+ FT_ERROR(( "One of `glyf'/`loca' tables missing.\n" ));
+ return FT_THROW( Invalid_Table );
+ }
+
+ /* Both `glyf' and `loca' must have same transformation. */
+ if ( info->glyf_table != NULL )
+ {
+ if ( ( info->glyf_table->flags & WOFF2_FLAGS_TRANSFORM ) !=
+ ( info->loca_table->flags & WOFF2_FLAGS_TRANSFORM ) )
+ {
+ FT_ERROR(( "Transformation mismatch"
+ " between `glyf' and `loca' table." ));
+ return FT_THROW( Invalid_Table );
+ }
+ }
+
+ /* Create buffer for table entries. */
+ if ( FT_NEW_ARRAY( table_entry, 16 ) )
+ goto Fail;
+
+ /* Create a stream for the uncompressed buffer. */
+ if ( FT_NEW( stream ) )
+ goto Fail;
+ FT_Stream_OpenMemory( stream, transformed_buf, transformed_buf_size );
+
+ FT_ASSERT( FT_STREAM_POS() == 0 );
+
+ /* Reconstruct/copy tables to output stream. */
+ for ( nn = 0; nn < num_tables; nn++ )
+ {
+ WOFF2_TableRec table = *( indices[nn] );
+
+
+ FT_TRACE3(( "Seeking to %d with table size %d.\n",
+ table.src_offset, table.src_length ));
+ FT_TRACE3(( "Table tag: %c%c%c%c.\n",
+ (FT_Char)( table.Tag >> 24 ),
+ (FT_Char)( table.Tag >> 16 ),
+ (FT_Char)( table.Tag >> 8 ),
+ (FT_Char)( table.Tag ) ));
+
+ if ( FT_STREAM_SEEK( table.src_offset ) )
+ goto Fail;
+
+ if ( table.src_offset + table.src_length > transformed_buf_size )
+ goto Fail;
+
+ /* Get stream size for fields of `hmtx' table. */
+ if ( table.Tag == TTAG_hhea )
+ {
+ if ( read_num_hmetrics( stream, &num_hmetrics ) )
+ goto Fail;
+ }
+
+ info->num_hmetrics = num_hmetrics;
+
+ checksum = 0;
+ if ( ( table.flags & WOFF2_FLAGS_TRANSFORM ) != WOFF2_FLAGS_TRANSFORM )
+ {
+ /* Check whether `head' is at least 12 bytes. */
+ if ( table.Tag == TTAG_head )
+ {
+ if ( table.src_length < 12 )
+ goto Fail;
+
+ buf_cursor = transformed_buf + table.src_offset + 8;
+ /* Set checkSumAdjustment = 0 */
+ WRITE_ULONG( buf_cursor, 0 );
+ }
+
+ table.dst_offset = dest_offset;
+
+ checksum = compute_ULong_sum( transformed_buf + table.src_offset,
+ table.src_length );
+ FT_TRACE4(( "Checksum = %09x.\n", checksum ));
+
+ if ( WRITE_SFNT_BUF( transformed_buf + table.src_offset,
+ table.src_length ) )
+ goto Fail;
+ }
+ else
+ {
+ FT_TRACE3(( "This table is transformed.\n" ));
+
+ if ( table.Tag == TTAG_glyf )
+ {
+ is_glyf_xform = TRUE;
+ table.dst_offset = dest_offset;
+
+ if ( reconstruct_glyf( stream,
+ &checksum,
+ &loca_checksum,
+ &sfnt,
+ sfnt_size,
+ &dest_offset,
+ info,
+ memory ) )
+ goto Fail;
+
+ FT_TRACE4(( "Checksum = %09x.\n", checksum ));
+ }
+
+ else if ( table.Tag == TTAG_loca )
+ checksum = loca_checksum;
+
+ else if ( table.Tag == TTAG_hmtx )
+ {
+ /* If glyf is not transformed and hmtx is, handle separately. */
+ if ( !is_glyf_xform )
+ {
+ if ( get_x_mins( stream, indices, num_tables, info, memory ) )
+ goto Fail;
+ }
+
+ table.dst_offset = dest_offset;
+
+ if ( reconstruct_hmtx( stream,
+ info->num_glyphs,
+ info->num_hmetrics,
+ info->x_mins,
+ &checksum,
+ &sfnt,
+ sfnt_size,
+ &dest_offset,
+ memory ) )
+ goto Fail;
+ }
+ else
+ {
+ /* Unknown transform. */
+ FT_ERROR(( "Unknown table transform.\n" ));
+ goto Fail;
+ }
+ }
+
+ font_checksum += checksum;
+
+ buf_cursor = &table_entry[0];
+ WRITE_ULONG( buf_cursor, table.Tag );
+ WRITE_ULONG( buf_cursor, checksum );
+ WRITE_ULONG( buf_cursor, table.dst_offset );
+ WRITE_ULONG( buf_cursor, table.dst_length );
+
+ WRITE_SFNT_BUF_AT( table_entry_offset, table_entry, 16 );
+
+ /* Update checksum. */
+ font_checksum += compute_ULong_sum( table_entry, 16 );
+
+ if ( pad4( &sfnt, sfnt_size, &dest_offset, memory ) )
+ goto Fail;
+
+ /* Sanity check. */
+ if ( (FT_ULong)( table.dst_offset + table.dst_length ) > dest_offset )
+ {
+ FT_ERROR(( "Table was partially written.\n" ));
+ goto Fail;
+ }
+ }
+
+ /* Update `head' checkSumAdjustment. */
+ info->head_table = find_table( indices, num_tables, TTAG_head );
+ if ( !info->head_table )
+ {
+ FT_ERROR(( "`head' table is missing.\n" ));
+ goto Fail;
+ }
+
+ if ( info->head_table->dst_length < 12 )
+ goto Fail;
+
+ buf_cursor = sfnt + info->head_table->dst_offset + 8;
+ font_checksum = 0xB1B0AFBA - font_checksum;
+
+ WRITE_ULONG( buf_cursor, font_checksum );
+
+ FT_TRACE2(( "Final checksum = %09x.\n", font_checksum ));
+
+ woff2->actual_sfnt_size = dest_offset;
+
+ /* Set pointer of sfnt stream to its correct value. */
+ *sfnt_bytes = sfnt;
+
+ FT_FREE( table_entry );
+ FT_Stream_Close( stream );
+ FT_FREE( stream );
+
+ return error;
+
+ Fail:
+ if ( !error )
+ error = FT_THROW( Invalid_Table );
+
+ /* Set pointer of sfnt stream to its correct value. */
+ *sfnt_bytes = sfnt;
+
+ FT_FREE( table_entry );
+ FT_Stream_Close( stream );
+ FT_FREE( stream );
+
+ return error;
+ }
+
+
+ /* Replace `face->root.stream' with a stream containing the extracted */
+ /* SFNT of a WOFF2 font. */
+
+ FT_LOCAL_DEF( FT_Error )
+ woff2_open_font( FT_Stream stream,
+ TT_Face face,
+ FT_Int* face_instance_index,
+ FT_Long* num_faces )
+ {
+ FT_Memory memory = stream->memory;
+ FT_Error error = FT_Err_Ok;
+ FT_Int face_index;
+
+ WOFF2_HeaderRec woff2;
+ WOFF2_InfoRec info = { 0, 0, 0, NULL, NULL, NULL, NULL };
+ WOFF2_Table tables = NULL;
+ WOFF2_Table* indices = NULL;
+ WOFF2_Table* temp_indices = NULL;
+ WOFF2_Table last_table;
+
+ FT_Int nn;
+ FT_ULong j;
+ FT_ULong flags;
+ FT_UShort xform_version;
+ FT_ULong src_offset = 0;
+
+ FT_UInt glyf_index;
+ FT_UInt loca_index;
+ FT_UInt32 file_offset;
+
+ FT_Byte* sfnt = NULL;
+ FT_Stream sfnt_stream = NULL;
+ FT_Byte* sfnt_header;
+ FT_ULong sfnt_size;
+
+ FT_Byte* uncompressed_buf = NULL;
+
+ static const FT_Frame_Field woff2_header_fields[] =
+ {
+#undef FT_STRUCTURE
+#define FT_STRUCTURE WOFF2_HeaderRec
+
+ FT_FRAME_START( 48 ),
+ FT_FRAME_ULONG ( signature ),
+ FT_FRAME_ULONG ( flavor ),
+ FT_FRAME_ULONG ( length ),
+ FT_FRAME_USHORT ( num_tables ),
+ FT_FRAME_SKIP_BYTES( 2 ),
+ FT_FRAME_ULONG ( totalSfntSize ),
+ FT_FRAME_ULONG ( totalCompressedSize ),
+ FT_FRAME_SKIP_BYTES( 2 * 2 ),
+ FT_FRAME_ULONG ( metaOffset ),
+ FT_FRAME_ULONG ( metaLength ),
+ FT_FRAME_ULONG ( metaOrigLength ),
+ FT_FRAME_ULONG ( privOffset ),
+ FT_FRAME_ULONG ( privLength ),
+ FT_FRAME_END
+ };
+
+
+ FT_ASSERT( stream == face->root.stream );
+ FT_ASSERT( FT_STREAM_POS() == 0 );
+
+ face_index = FT_ABS( *face_instance_index ) & 0xFFFF;
+
+ /* Read WOFF2 Header. */
+ if ( FT_STREAM_READ_FIELDS( woff2_header_fields, &woff2 ) )
+ return error;
+
+ FT_TRACE4(( "signature -> 0x%X\n", woff2.signature ));
+ FT_TRACE2(( "flavor -> 0x%08lx\n", woff2.flavor ));
+ FT_TRACE4(( "length -> %lu\n", woff2.length ));
+ FT_TRACE2(( "num_tables -> %hu\n", woff2.num_tables ));
+ FT_TRACE4(( "totalSfntSize -> %lu\n", woff2.totalSfntSize ));
+ FT_TRACE4(( "metaOffset -> %hu\n", woff2.metaOffset ));
+ FT_TRACE4(( "metaLength -> %hu\n", woff2.metaLength ));
+ FT_TRACE4(( "privOffset -> %hu\n", woff2.privOffset ));
+ FT_TRACE4(( "privLength -> %hu\n", woff2.privLength ));
+
+ /* Make sure we don't recurse back here. */
+ if ( woff2.flavor == TTAG_wOF2 )
+ return FT_THROW( Invalid_Table );
+
+ /* Miscellaneous checks. */
+ if ( woff2.length != stream->size ||
+ woff2.num_tables == 0 ||
+ 48 + woff2.num_tables * 20UL >= woff2.length ||
+ ( woff2.metaOffset == 0 && ( woff2.metaLength != 0 ||
+ woff2.metaOrigLength != 0 ) ) ||
+ ( woff2.metaLength != 0 && woff2.metaOrigLength == 0 ) ||
+ ( woff2.metaOffset >= woff2.length ) ||
+ ( woff2.length - woff2.metaOffset < woff2.metaLength ) ||
+ ( woff2.privOffset == 0 && woff2.privLength != 0 ) ||
+ ( woff2.privOffset >= woff2.length ) ||
+ ( woff2.length - woff2.privOffset < woff2.privLength ) )
+ {
+ FT_ERROR(( "woff2_open_font: invalid WOFF2 header\n" ));
+ return FT_THROW( Invalid_Table );
+ }
+
+ FT_TRACE2(( "woff2_open_font: WOFF2 Header is valid.\n" ));
+
+ woff2.ttc_fonts = NULL;
+
+ /* Read table directory. */
+ if ( FT_NEW_ARRAY( tables, woff2.num_tables ) ||
+ FT_NEW_ARRAY( indices, woff2.num_tables ) )
+ goto Exit;
+
+ FT_TRACE2(( "\n"
+ " tag flags transform origLen transformLen\n"
+ " --------------------------------------------------\n" ));
+
+ for ( nn = 0; nn < woff2.num_tables; nn++ )
+ {
+ WOFF2_Table table = tables + nn;
+
+
+ if ( FT_READ_BYTE( table->FlagByte ) )
+ goto Exit;
+
+ if ( ( table->FlagByte & 0x3f ) == 0x3f )
+ {
+ if ( FT_READ_ULONG( table->Tag ) )
+ goto Exit;
+ }
+ else
+ {
+ table->Tag = woff2_known_tags( table->FlagByte & 0x3f );
+ if ( !table->Tag )
+ {
+ FT_ERROR(( "woff2_open_font: Unknown table tag." ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+ }
+
+ flags = 0;
+ xform_version = ( table->FlagByte >> 6 ) & 0x03;
+
+ /* 0 means xform for glyph/loca, non-0 for others. */
+ if ( table->Tag == TTAG_glyf || table->Tag == TTAG_loca )
+ {
+ if ( xform_version == 0 )
+ flags |= WOFF2_FLAGS_TRANSFORM;
+ }
+ else if ( xform_version != 0 )
+ flags |= WOFF2_FLAGS_TRANSFORM;
+
+ flags |= xform_version;
+
+ if ( READ_BASE128( table->dst_length ) )
+ goto Exit;
+
+ table->TransformLength = table->dst_length;
+
+ if ( ( flags & WOFF2_FLAGS_TRANSFORM ) != 0 )
+ {
+ if ( READ_BASE128( table->TransformLength ) )
+ goto Exit;
+
+ if ( table->Tag == TTAG_loca && table->TransformLength )
+ {
+ FT_ERROR(( "woff2_open_font: Invalid loca `transformLength'.\n" ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+ }
+
+ if ( src_offset + table->TransformLength < src_offset )
+ {
+ FT_ERROR(( "woff2_open_font: invalid WOFF2 table directory.\n" ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ table->src_offset = src_offset;
+ table->src_length = table->TransformLength;
+ src_offset += table->TransformLength;
+ table->flags = flags;
+
+ FT_TRACE2(( " %c%c%c%c %08d %08d %08ld %08ld\n",
+ (FT_Char)( table->Tag >> 24 ),
+ (FT_Char)( table->Tag >> 16 ),
+ (FT_Char)( table->Tag >> 8 ),
+ (FT_Char)( table->Tag ),
+ table->FlagByte & 0x3f,
+ ( table->FlagByte >> 6 ) & 0x03,
+ table->dst_length,
+ table->TransformLength,
+ table->src_length,
+ table->src_offset ));
+
+ indices[nn] = table;
+ }
+
+ /* End of last table is uncompressed size. */
+ last_table = indices[woff2.num_tables - 1];
+
+ woff2.uncompressed_size = last_table->src_offset +
+ last_table->src_length;
+ if ( woff2.uncompressed_size < last_table->src_offset )
+ {
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ FT_TRACE2(( "Table directory parsed.\n" ));
+
+ /* Check for and read collection directory. */
+ woff2.num_fonts = 1;
+ woff2.header_version = 0;
+
+ if ( woff2.flavor == TTAG_ttcf )
+ {
+ FT_TRACE2(( "Font is a TTC, reading collection directory.\n" ));
+
+ if ( FT_READ_ULONG( woff2.header_version ) )
+ goto Exit;
+
+ if ( woff2.header_version != 0x00010000 &&
+ woff2.header_version != 0x00020000 )
+ {
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ if ( READ_255USHORT( woff2.num_fonts ) )
+ goto Exit;
+
+ if ( !woff2.num_fonts )
+ {
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ FT_TRACE4(( "Number of fonts in TTC: %ld\n", woff2.num_fonts ));
+
+ if ( FT_NEW_ARRAY( woff2.ttc_fonts, woff2.num_fonts ) )
+ goto Exit;
+
+ for ( nn = 0; nn < woff2.num_fonts; nn++ )
+ {
+ WOFF2_TtcFont ttc_font = woff2.ttc_fonts + nn;
+
+
+ if ( READ_255USHORT( ttc_font->num_tables ) )
+ goto Exit;
+ if ( FT_READ_ULONG( ttc_font->flavor ) )
+ goto Exit;
+
+ if ( FT_NEW_ARRAY( ttc_font->table_indices, ttc_font->num_tables ) )
+ goto Exit;
+
+ FT_TRACE5(( "Number of tables in font %d: %ld\n",
+ nn, ttc_font->num_tables ));
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( ttc_font->num_tables )
+ FT_TRACE6(( " Indices: " ));
+#endif
+
+ glyf_index = 0;
+ loca_index = 0;
+
+ for ( j = 0; j < ttc_font->num_tables; j++ )
+ {
+ FT_UShort table_index;
+ WOFF2_Table table;
+
+
+ if ( READ_255USHORT( table_index ) )
+ goto Exit;
+
+ FT_TRACE6(( "%hu ", table_index ));
+ if ( table_index >= woff2.num_tables )
+ {
+ FT_ERROR(( "woff2_open_font: invalid table index\n" ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ ttc_font->table_indices[j] = table_index;
+
+ table = indices[table_index];
+ if ( table->Tag == TTAG_loca )
+ loca_index = table_index;
+ if ( table->Tag == TTAG_glyf )
+ glyf_index = table_index;
+ }
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( ttc_font->num_tables )
+ FT_TRACE6(( "\n" ));
+#endif
+
+ /* glyf and loca must be consecutive */
+ if ( glyf_index > 0 || loca_index > 0 )
+ {
+ if ( glyf_index > loca_index ||
+ loca_index - glyf_index != 1 )
+ {
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+ }
+ }
+
+ /* Collection directory reading complete. */
+ FT_TRACE2(( "WOFF2 collection directory is valid.\n" ));
+ }
+ else
+ woff2.ttc_fonts = NULL;
+
+ woff2.compressed_offset = FT_STREAM_POS();
+ file_offset = ROUND4( woff2.compressed_offset +
+ woff2.totalCompressedSize );
+
+ /* Some more checks before we start reading the tables. */
+ if ( file_offset > woff2.length )
+ {
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ if ( woff2.metaOffset )
+ {
+ if ( file_offset != woff2.metaOffset )
+ {
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+ file_offset = ROUND4(woff2.metaOffset + woff2.metaLength);
+ }
+
+ if ( woff2.privOffset )
+ {
+ if ( file_offset != woff2.privOffset )
+ {
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+ file_offset = ROUND4(woff2.privOffset + woff2.privLength);
+ }
+
+ if ( file_offset != ( ROUND4( woff2.length ) ) )
+ {
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ /* Validate requested face index. */
+ *num_faces = woff2.num_fonts;
+ /* value -(N+1) requests information on index N */
+ if ( *face_instance_index < 0 )
+ face_index--;
+
+ if ( face_index >= woff2.num_fonts )
+ {
+ if ( *face_instance_index >= 0 )
+ {
+ error = FT_THROW( Invalid_Argument );
+ goto Exit;
+ }
+ else
+ face_index = 0;
+ }
+
+ /* Only retain tables of the requested face in a TTC. */
+ if ( woff2.header_version )
+ {
+ WOFF2_TtcFont ttc_font = woff2.ttc_fonts + face_index;
+
+
+ /* Create a temporary array. */
+ if ( FT_NEW_ARRAY( temp_indices,
+ ttc_font->num_tables ) )
+ goto Exit;
+
+ FT_TRACE4(( "Storing tables for TTC face index %d.\n", face_index ));
+ for ( nn = 0; nn < ttc_font->num_tables; nn++ )
+ temp_indices[nn] = indices[ttc_font->table_indices[nn]];
+
+ /* Resize array to required size. */
+ if ( FT_RENEW_ARRAY( indices,
+ woff2.num_tables,
+ ttc_font->num_tables ) )
+ goto Exit;
+
+ for ( nn = 0; nn < ttc_font->num_tables; nn++ )
+ indices[nn] = temp_indices[nn];
+
+ FT_FREE( temp_indices );
+
+ /* Change header values. */
+ woff2.flavor = ttc_font->flavor;
+ woff2.num_tables = ttc_font->num_tables;
+ }
+
+ /* We need to allocate this much at the minimum. */
+ sfnt_size = 12 + woff2.num_tables * 16UL;
+ /* This is what we normally expect. */
+ /* Initially trust `totalSfntSize' and change later as required. */
+ if ( woff2.totalSfntSize > sfnt_size )
+ {
+ /* However, adjust the value to something reasonable. */
+
+ /* Factor 64 is heuristic. */
+ if ( ( woff2.totalSfntSize >> 6 ) > woff2.length )
+ sfnt_size = woff2.length << 6;
+ else
+ sfnt_size = woff2.totalSfntSize;
+
+ /* Value 1<<26 = 67108864 is heuristic. */
+ if (sfnt_size >= (1 << 26))
+ sfnt_size = 1 << 26;
+
+#ifdef FT_DEBUG_LEVEL_TRACE
+ if ( sfnt_size != woff2.totalSfntSize )
+ FT_TRACE4(( "adjusting estimate of uncompressed font size"
+ " to %lu bytes\n",
+ sfnt_size ));
+#endif
+ }
+
+ /* Write sfnt header. */
+ if ( FT_ALLOC( sfnt, sfnt_size ) ||
+ FT_NEW( sfnt_stream ) )
+ goto Exit;
+
+ sfnt_header = sfnt;
+
+ WRITE_ULONG( sfnt_header, woff2.flavor );
+
+ if ( woff2.num_tables )
+ {
+ FT_UInt searchRange, entrySelector, rangeShift, x;
+
+
+ x = woff2.num_tables;
+ entrySelector = 0;
+ while ( x )
+ {
+ x >>= 1;
+ entrySelector += 1;
+ }
+ entrySelector--;
+
+ searchRange = ( 1 << entrySelector ) * 16;
+ rangeShift = ( woff2.num_tables * 16 ) - searchRange;
+
+ WRITE_USHORT( sfnt_header, woff2.num_tables );
+ WRITE_USHORT( sfnt_header, searchRange );
+ WRITE_USHORT( sfnt_header, entrySelector );
+ WRITE_USHORT( sfnt_header, rangeShift );
+ }
+
+ info.header_checksum = compute_ULong_sum( sfnt, 12 );
+
+ /* Sort tables by tag. */
+ ft_qsort( indices,
+ woff2.num_tables,
+ sizeof ( WOFF2_Table ),
+ compare_tags );
+
+ if ( woff2.uncompressed_size < 1 )
+ {
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ if ( woff2.uncompressed_size > sfnt_size )
+ {
+ FT_ERROR(( "woff2_open_font: SFNT table lengths are too large.\n" ));
+ error = FT_THROW( Invalid_Table );
+ goto Exit;
+ }
+
+ /* Allocate memory for uncompressed table data. */
+ if ( FT_ALLOC( uncompressed_buf, woff2.uncompressed_size ) ||
+ FT_FRAME_ENTER( woff2.totalCompressedSize ) )
+ goto Exit;
+
+ /* Uncompress the stream. */
+ error = woff2_decompress( uncompressed_buf,
+ woff2.uncompressed_size,
+ stream->cursor,
+ woff2.totalCompressedSize );
+
+ FT_FRAME_EXIT();
+
+ if ( error )
+ goto Exit;
+
+ error = reconstruct_font( uncompressed_buf,
+ woff2.uncompressed_size,
+ indices,
+ &woff2,
+ &info,
+ &sfnt,
+ &sfnt_size,
+ memory );
+
+ if ( error )
+ goto Exit;
+
+ /* Resize `sfnt' to actual size of sfnt stream. */
+ if ( woff2.actual_sfnt_size < sfnt_size )
+ {
+ FT_TRACE5(( "Trimming sfnt stream from %lu to %lu.\n",
+ sfnt_size, woff2.actual_sfnt_size ));
+ if ( FT_REALLOC( sfnt,
+ (FT_ULong)( sfnt_size ),
+ (FT_ULong)( woff2.actual_sfnt_size ) ) )
+ goto Exit;
+ }
+
+ /* `reconstruct_font' has done all the work. */
+ /* Swap out stream and return. */
+ FT_Stream_OpenMemory( sfnt_stream, sfnt, woff2.actual_sfnt_size );
+ sfnt_stream->memory = stream->memory;
+ sfnt_stream->close = stream_close;
+
+ FT_Stream_Free(
+ face->root.stream,
+ ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 );
+
+ face->root.stream = sfnt_stream;
+ face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM;
+
+ /* Set face_index to 0 or -1. */
+ if ( *face_instance_index >= 0 )
+ *face_instance_index = 0;
+ else
+ *face_instance_index = -1;
+
+ FT_TRACE2(( "woff2_open_font: SFNT synthesized.\n" ));
+
+ Exit:
+ FT_FREE( tables );
+ FT_FREE( indices );
+ FT_FREE( uncompressed_buf );
+ FT_FREE( info.x_mins );
+
+ if ( woff2.ttc_fonts )
+ {
+ WOFF2_TtcFont ttc_font = woff2.ttc_fonts;
+
+
+ for ( nn = 0; nn < woff2.num_fonts; nn++ )
+ {
+ FT_FREE( ttc_font->table_indices );
+ ttc_font++;
+ }
+
+ FT_FREE( woff2.ttc_fonts );
+ }
+
+ if ( error )
+ {
+ FT_FREE( sfnt );
+ if ( sfnt_stream )
+ {
+ FT_Stream_Close( sfnt_stream );
+ FT_FREE( sfnt_stream );
+ }
+ }
+
+ return error;
+ }
+
+
+#undef READ_255USHORT
+#undef READ_BASE128
+#undef ROUND4
+#undef WRITE_USHORT
+#undef WRITE_ULONG
+#undef WRITE_SHORT
+#undef WRITE_SFNT_BUF
+#undef WRITE_SFNT_BUF_AT
+
+#undef N_CONTOUR_STREAM
+#undef N_POINTS_STREAM
+#undef FLAG_STREAM
+#undef GLYPH_STREAM
+#undef COMPOSITE_STREAM
+#undef BBOX_STREAM
+#undef INSTRUCTION_STREAM
+
+
+/* END */
diff --git a/thirdparty/freetype/src/sfnt/sfwoff2.h b/thirdparty/freetype/src/sfnt/sfwoff2.h
new file mode 100644
index 0000000000..7ae6e2c06d
--- /dev/null
+++ b/thirdparty/freetype/src/sfnt/sfwoff2.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+ *
+ * sfwoff2.h
+ *
+ * WOFFF2 format management (specification).
+ *
+ * Copyright (C) 2019-2020 by
+ * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+#ifndef SFWOFF2_H_
+#define SFWOFF2_H_
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_SFNT_H
+#include FT_INTERNAL_OBJECTS_H
+
+
+FT_BEGIN_HEADER
+
+
+ /* Leave the first byte open to store `flag_byte'. */
+#define WOFF2_FLAGS_TRANSFORM 1 << 8
+
+#define WOFF2_SFNT_HEADER_SIZE 12
+#define WOFF2_SFNT_ENTRY_SIZE 16
+
+ /* Suggested maximum size for output. */
+#define WOFF2_DEFAULT_MAX_SIZE 30 * 1024 * 1024
+
+ /* 98% of Google Fonts have no glyph above 5k bytes. */
+#define WOFF2_DEFAULT_GLYPH_BUF 5120
+
+ /* Composite glyph flags. */
+ /* See `CompositeGlyph.java' in `sfntly' for full definitions. */
+#define FLAG_ARG_1_AND_2_ARE_WORDS 1 << 0
+#define FLAG_WE_HAVE_A_SCALE 1 << 3
+#define FLAG_MORE_COMPONENTS 1 << 5
+#define FLAG_WE_HAVE_AN_X_AND_Y_SCALE 1 << 6
+#define FLAG_WE_HAVE_A_TWO_BY_TWO 1 << 7
+#define FLAG_WE_HAVE_INSTRUCTIONS 1 << 8
+
+ /* Simple glyph flags */
+#define GLYF_ON_CURVE 1 << 0
+#define GLYF_X_SHORT 1 << 1
+#define GLYF_Y_SHORT 1 << 2
+#define GLYF_REPEAT 1 << 3
+#define GLYF_THIS_X_IS_SAME 1 << 4
+#define GLYF_THIS_Y_IS_SAME 1 << 5
+
+ /* Other constants */
+#define CONTOUR_OFFSET_END_POINT 10
+
+
+ FT_LOCAL( FT_Error )
+ woff2_open_font( FT_Stream stream,
+ TT_Face face,
+ FT_Int* face_index,
+ FT_Long* num_faces );
+
+
+FT_END_HEADER
+
+#endif /* SFWOFF2_H_ */
+
+
+/* END */
diff --git a/thirdparty/freetype/src/sfnt/ttbdf.c b/thirdparty/freetype/src/sfnt/ttbdf.c
index 853599fc43..bc35284cc8 100644
--- a/thirdparty/freetype/src/sfnt/ttbdf.c
+++ b/thirdparty/freetype/src/sfnt/ttbdf.c
@@ -4,7 +4,7 @@
*
* TrueType and OpenType embedded BDF properties (body).
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/ttbdf.h b/thirdparty/freetype/src/sfnt/ttbdf.h
index e4164e61fc..c340f6631d 100644
--- a/thirdparty/freetype/src/sfnt/ttbdf.h
+++ b/thirdparty/freetype/src/sfnt/ttbdf.h
@@ -4,7 +4,7 @@
*
* TrueType and OpenType embedded BDF properties (specification).
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/ttcmap.c b/thirdparty/freetype/src/sfnt/ttcmap.c
index 683f3b1818..2c34efb5ce 100644
--- a/thirdparty/freetype/src/sfnt/ttcmap.c
+++ b/thirdparty/freetype/src/sfnt/ttcmap.c
@@ -4,7 +4,7 @@
*
* TrueType character mapping table (cmap) support (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -3764,28 +3764,31 @@
FT_LOCAL_DEF( FT_Error )
tt_face_build_cmaps( TT_Face face )
{
- FT_Byte* table = face->cmap_table;
- FT_Byte* limit = table + face->cmap_size;
+ FT_Byte* const table = face->cmap_table;
+ FT_Byte* limit;
FT_UInt volatile num_cmaps;
- FT_Byte* volatile p = table;
+ FT_Byte* volatile p = table;
FT_Library library = FT_FACE_LIBRARY( face );
FT_UNUSED( library );
- if ( !p || p + 4 > limit )
+ if ( !p || face->cmap_size < 4 )
return FT_THROW( Invalid_Table );
- /* only recognize format 0 */
- if ( TT_NEXT_USHORT( p ) != 0 )
- {
- FT_ERROR(( "tt_face_build_cmaps:"
- " unsupported `cmap' table format = %d\n",
- TT_PEEK_USHORT( p - 2 ) ));
- return FT_THROW( Invalid_Table );
- }
+ /* Version 1.8.3 of the OpenType specification contains the following */
+ /* (https://docs.microsoft.com/en-us/typography/opentype/spec/cmap): */
+ /* */
+ /* The 'cmap' table version number remains at 0x0000 for fonts that */
+ /* make use of the newer subtable formats. */
+ /* */
+ /* This essentially means that a version format test is useless. */
+
+ /* ignore format */
+ p += 2;
num_cmaps = TT_NEXT_USHORT( p );
+ limit = table + face->cmap_size;
for ( ; num_cmaps > 0 && p + 8 <= limit; num_cmaps-- )
{
diff --git a/thirdparty/freetype/src/sfnt/ttcmap.h b/thirdparty/freetype/src/sfnt/ttcmap.h
index 36801c939e..4bf49e2d49 100644
--- a/thirdparty/freetype/src/sfnt/ttcmap.h
+++ b/thirdparty/freetype/src/sfnt/ttcmap.h
@@ -4,7 +4,7 @@
*
* TrueType character mapping table (cmap) support (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/ttcmapc.h b/thirdparty/freetype/src/sfnt/ttcmapc.h
index ace9e69ca8..2e4ce5075b 100644
--- a/thirdparty/freetype/src/sfnt/ttcmapc.h
+++ b/thirdparty/freetype/src/sfnt/ttcmapc.h
@@ -4,7 +4,7 @@
*
* TT CMAP classes definitions (specification only).
*
- * Copyright (C) 2009-2019 by
+ * Copyright (C) 2009-2020 by
* Oran Agra and Mickey Gabel.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/ttcolr.c b/thirdparty/freetype/src/sfnt/ttcolr.c
index 6b537d95b8..b37fa7b09a 100644
--- a/thirdparty/freetype/src/sfnt/ttcolr.c
+++ b/thirdparty/freetype/src/sfnt/ttcolr.c
@@ -4,7 +4,7 @@
*
* TrueType and OpenType colored glyph layer support (body).
*
- * Copyright (C) 2018-2019 by
+ * Copyright (C) 2018-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* Originally written by Shao Yu Zhang <shaozhang@fb.com>.
diff --git a/thirdparty/freetype/src/sfnt/ttcolr.h b/thirdparty/freetype/src/sfnt/ttcolr.h
index 817489a855..8da6b3aa14 100644
--- a/thirdparty/freetype/src/sfnt/ttcolr.h
+++ b/thirdparty/freetype/src/sfnt/ttcolr.h
@@ -4,7 +4,7 @@
*
* TrueType and OpenType colored glyph layer support (specification).
*
- * Copyright (C) 2018-2019 by
+ * Copyright (C) 2018-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* Originally written by Shao Yu Zhang <shaozhang@fb.com>.
diff --git a/thirdparty/freetype/src/sfnt/ttcpal.c b/thirdparty/freetype/src/sfnt/ttcpal.c
index 3482169a89..165423e305 100644
--- a/thirdparty/freetype/src/sfnt/ttcpal.c
+++ b/thirdparty/freetype/src/sfnt/ttcpal.c
@@ -4,7 +4,7 @@
*
* TrueType and OpenType color palette support (body).
*
- * Copyright (C) 2018-2019 by
+ * Copyright (C) 2018-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* Originally written by Shao Yu Zhang <shaozhang@fb.com>.
diff --git a/thirdparty/freetype/src/sfnt/ttcpal.h b/thirdparty/freetype/src/sfnt/ttcpal.h
index d1b244f3e3..f2e116ba2c 100644
--- a/thirdparty/freetype/src/sfnt/ttcpal.h
+++ b/thirdparty/freetype/src/sfnt/ttcpal.h
@@ -4,7 +4,7 @@
*
* TrueType and OpenType color palette support (specification).
*
- * Copyright (C) 2018-2019 by
+ * Copyright (C) 2018-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* Originally written by Shao Yu Zhang <shaozhang@fb.com>.
diff --git a/thirdparty/freetype/src/sfnt/ttkern.c b/thirdparty/freetype/src/sfnt/ttkern.c
index 8d1b781090..1d34acbd13 100644
--- a/thirdparty/freetype/src/sfnt/ttkern.c
+++ b/thirdparty/freetype/src/sfnt/ttkern.c
@@ -5,7 +5,7 @@
* Load the basic TrueType kerning table. This doesn't handle
* kerning data within the GPOS table at the moment.
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/ttkern.h b/thirdparty/freetype/src/sfnt/ttkern.h
index 5f283e5e62..6560a283a6 100644
--- a/thirdparty/freetype/src/sfnt/ttkern.h
+++ b/thirdparty/freetype/src/sfnt/ttkern.h
@@ -5,7 +5,7 @@
* Load the basic TrueType kerning table. This doesn't handle
* kerning data within the GPOS table at the moment.
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/ttload.c b/thirdparty/freetype/src/sfnt/ttload.c
index 5443bf4b69..d4e4ee4f10 100644
--- a/thirdparty/freetype/src/sfnt/ttload.c
+++ b/thirdparty/freetype/src/sfnt/ttload.c
@@ -5,7 +5,7 @@
* Load the basic TrueType tables, i.e., tables that can be either in
* TTF or OTF fonts (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -397,7 +397,15 @@
}
}
else
+ {
valid_entries = sfnt.num_tables;
+ if ( !valid_entries )
+ {
+ FT_TRACE2(( "tt_face_load_font_dir: no valid tables found\n" ));
+ error = FT_THROW( Unknown_File_Format );
+ goto Exit;
+ }
+ }
face->num_tables = valid_entries;
face->format_tag = sfnt.format_tag;
@@ -916,7 +924,7 @@
/* load language tags */
{
TT_LangTag entry = table->langTags;
- TT_LangTag limit = entry + table->numLangTagRecords;
+ TT_LangTag limit = FT_OFFSET( entry, table->numLangTagRecords );
for ( ; entry < limit; entry++ )
diff --git a/thirdparty/freetype/src/sfnt/ttload.h b/thirdparty/freetype/src/sfnt/ttload.h
index cc18c18694..49d40655f8 100644
--- a/thirdparty/freetype/src/sfnt/ttload.h
+++ b/thirdparty/freetype/src/sfnt/ttload.h
@@ -5,7 +5,7 @@
* Load the basic TrueType tables, i.e., tables that can be either in
* TTF or OTF fonts (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/ttmtx.c b/thirdparty/freetype/src/sfnt/ttmtx.c
index b6725c962f..e18ff877ef 100644
--- a/thirdparty/freetype/src/sfnt/ttmtx.c
+++ b/thirdparty/freetype/src/sfnt/ttmtx.c
@@ -4,7 +4,7 @@
*
* Load the metrics tables common to TTF and OTF fonts (body).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/ttmtx.h b/thirdparty/freetype/src/sfnt/ttmtx.h
index 5b0b60b641..c98c79ec51 100644
--- a/thirdparty/freetype/src/sfnt/ttmtx.h
+++ b/thirdparty/freetype/src/sfnt/ttmtx.h
@@ -4,7 +4,7 @@
*
* Load the metrics tables common to TTF and OTF fonts (specification).
*
- * Copyright (C) 2006-2019 by
+ * Copyright (C) 2006-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/ttpost.c b/thirdparty/freetype/src/sfnt/ttpost.c
index 636a0a004a..f7be716219 100644
--- a/thirdparty/freetype/src/sfnt/ttpost.c
+++ b/thirdparty/freetype/src/sfnt/ttpost.c
@@ -5,7 +5,7 @@
* PostScript name table processing for TrueType and OpenType fonts
* (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/ttpost.h b/thirdparty/freetype/src/sfnt/ttpost.h
index 812a0fc92d..547f2ff843 100644
--- a/thirdparty/freetype/src/sfnt/ttpost.h
+++ b/thirdparty/freetype/src/sfnt/ttpost.h
@@ -5,7 +5,7 @@
* PostScript name table processing for TrueType and OpenType fonts
* (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/ttsbit.c b/thirdparty/freetype/src/sfnt/ttsbit.c
index 23bd9d7eb0..3f8730f7fb 100644
--- a/thirdparty/freetype/src/sfnt/ttsbit.c
+++ b/thirdparty/freetype/src/sfnt/ttsbit.c
@@ -4,7 +4,7 @@
*
* TrueType and OpenType embedded bitmap support (body).
*
- * Copyright (C) 2005-2019 by
+ * Copyright (C) 2005-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* Copyright 2013 by Google, Inc.
diff --git a/thirdparty/freetype/src/sfnt/ttsbit.h b/thirdparty/freetype/src/sfnt/ttsbit.h
index 5ab8ff5568..dfeb886838 100644
--- a/thirdparty/freetype/src/sfnt/ttsbit.h
+++ b/thirdparty/freetype/src/sfnt/ttsbit.h
@@ -4,7 +4,7 @@
*
* TrueType and OpenType embedded bitmap support (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/sfnt/woff2tags.c b/thirdparty/freetype/src/sfnt/woff2tags.c
new file mode 100644
index 0000000000..246f7fa062
--- /dev/null
+++ b/thirdparty/freetype/src/sfnt/woff2tags.c
@@ -0,0 +1,110 @@
+/****************************************************************************
+ *
+ * woff2tags.c
+ *
+ * WOFF2 Font table tags (base).
+ *
+ * Copyright (C) 2019-2020 by
+ * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+#include <ft2build.h>
+#include FT_TRUETYPE_TAGS_H
+
+
+ /*
+ * Return tag from index in the order given in WOFF2 specification.
+ *
+ * See
+ *
+ * https://www.w3.org/TR/WOFF2/#table_dir_format
+ *
+ * for details.
+ */
+ FT_LOCAL_DEF( FT_ULong )
+ woff2_known_tags( FT_Byte index )
+ {
+ const FT_ULong known_tags[63] =
+ {
+ FT_MAKE_TAG('c', 'm', 'a', 'p'), /* 0 */
+ FT_MAKE_TAG('h', 'e', 'a', 'd'), /* 1 */
+ FT_MAKE_TAG('h', 'h', 'e', 'a'), /* 2 */
+ FT_MAKE_TAG('h', 'm', 't', 'x'), /* 3 */
+ FT_MAKE_TAG('m', 'a', 'x', 'p'), /* 4 */
+ FT_MAKE_TAG('n', 'a', 'm', 'e'), /* 5 */
+ FT_MAKE_TAG('O', 'S', '/', '2'), /* 6 */
+ FT_MAKE_TAG('p', 'o', 's', 't'), /* 7 */
+ FT_MAKE_TAG('c', 'v', 't', ' '), /* 8 */
+ FT_MAKE_TAG('f', 'p', 'g', 'm'), /* 9 */
+ FT_MAKE_TAG('g', 'l', 'y', 'f'), /* 10 */
+ FT_MAKE_TAG('l', 'o', 'c', 'a'), /* 11 */
+ FT_MAKE_TAG('p', 'r', 'e', 'p'), /* 12 */
+ FT_MAKE_TAG('C', 'F', 'F', ' '), /* 13 */
+ FT_MAKE_TAG('V', 'O', 'R', 'G'), /* 14 */
+ FT_MAKE_TAG('E', 'B', 'D', 'T'), /* 15 */
+ FT_MAKE_TAG('E', 'B', 'L', 'C'), /* 16 */
+ FT_MAKE_TAG('g', 'a', 's', 'p'), /* 17 */
+ FT_MAKE_TAG('h', 'd', 'm', 'x'), /* 18 */
+ FT_MAKE_TAG('k', 'e', 'r', 'n'), /* 19 */
+ FT_MAKE_TAG('L', 'T', 'S', 'H'), /* 20 */
+ FT_MAKE_TAG('P', 'C', 'L', 'T'), /* 21 */
+ FT_MAKE_TAG('V', 'D', 'M', 'X'), /* 22 */
+ FT_MAKE_TAG('v', 'h', 'e', 'a'), /* 23 */
+ FT_MAKE_TAG('v', 'm', 't', 'x'), /* 24 */
+ FT_MAKE_TAG('B', 'A', 'S', 'E'), /* 25 */
+ FT_MAKE_TAG('G', 'D', 'E', 'F'), /* 26 */
+ FT_MAKE_TAG('G', 'P', 'O', 'S'), /* 27 */
+ FT_MAKE_TAG('G', 'S', 'U', 'B'), /* 28 */
+ FT_MAKE_TAG('E', 'B', 'S', 'C'), /* 29 */
+ FT_MAKE_TAG('J', 'S', 'T', 'F'), /* 30 */
+ FT_MAKE_TAG('M', 'A', 'T', 'H'), /* 31 */
+ FT_MAKE_TAG('C', 'B', 'D', 'T'), /* 32 */
+ FT_MAKE_TAG('C', 'B', 'L', 'C'), /* 33 */
+ FT_MAKE_TAG('C', 'O', 'L', 'R'), /* 34 */
+ FT_MAKE_TAG('C', 'P', 'A', 'L'), /* 35 */
+ FT_MAKE_TAG('S', 'V', 'G', ' '), /* 36 */
+ FT_MAKE_TAG('s', 'b', 'i', 'x'), /* 37 */
+ FT_MAKE_TAG('a', 'c', 'n', 't'), /* 38 */
+ FT_MAKE_TAG('a', 'v', 'a', 'r'), /* 39 */
+ FT_MAKE_TAG('b', 'd', 'a', 't'), /* 40 */
+ FT_MAKE_TAG('b', 'l', 'o', 'c'), /* 41 */
+ FT_MAKE_TAG('b', 's', 'l', 'n'), /* 42 */
+ FT_MAKE_TAG('c', 'v', 'a', 'r'), /* 43 */
+ FT_MAKE_TAG('f', 'd', 's', 'c'), /* 44 */
+ FT_MAKE_TAG('f', 'e', 'a', 't'), /* 45 */
+ FT_MAKE_TAG('f', 'm', 't', 'x'), /* 46 */
+ FT_MAKE_TAG('f', 'v', 'a', 'r'), /* 47 */
+ FT_MAKE_TAG('g', 'v', 'a', 'r'), /* 48 */
+ FT_MAKE_TAG('h', 's', 't', 'y'), /* 49 */
+ FT_MAKE_TAG('j', 'u', 's', 't'), /* 50 */
+ FT_MAKE_TAG('l', 'c', 'a', 'r'), /* 51 */
+ FT_MAKE_TAG('m', 'o', 'r', 't'), /* 52 */
+ FT_MAKE_TAG('m', 'o', 'r', 'x'), /* 53 */
+ FT_MAKE_TAG('o', 'p', 'b', 'd'), /* 54 */
+ FT_MAKE_TAG('p', 'r', 'o', 'p'), /* 55 */
+ FT_MAKE_TAG('t', 'r', 'a', 'k'), /* 56 */
+ FT_MAKE_TAG('Z', 'a', 'p', 'f'), /* 57 */
+ FT_MAKE_TAG('S', 'i', 'l', 'f'), /* 58 */
+ FT_MAKE_TAG('G', 'l', 'a', 't'), /* 59 */
+ FT_MAKE_TAG('G', 'l', 'o', 'c'), /* 60 */
+ FT_MAKE_TAG('F', 'e', 'a', 't'), /* 61 */
+ FT_MAKE_TAG('S', 'i', 'l', 'l'), /* 62 */
+ };
+
+
+ if ( index > 62 )
+ return 0;
+
+ return known_tags[index];
+ }
+
+
+/* END */
diff --git a/thirdparty/freetype/src/sfnt/woff2tags.h b/thirdparty/freetype/src/sfnt/woff2tags.h
new file mode 100644
index 0000000000..13d242e11d
--- /dev/null
+++ b/thirdparty/freetype/src/sfnt/woff2tags.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ *
+ * woff2tags.h
+ *
+ * WOFFF2 Font table tags (specification).
+ *
+ * Copyright (C) 1996-2020 by
+ * Nikhil Ramakrishnan, David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
+
+
+#ifndef WOFF2TAGS_H
+#define WOFF2TAGS_H
+
+
+#include <ft2build.h>
+#include FT_INTERNAL_OBJECTS_H
+
+
+FT_BEGIN_HEADER
+
+
+ FT_LOCAL( FT_ULong )
+ woff2_known_tags( FT_Byte index );
+
+
+FT_END_HEADER
+
+#endif /* WOFF2TAGS_H */
+
+
+/* END */
diff --git a/thirdparty/freetype/src/smooth/ftgrays.c b/thirdparty/freetype/src/smooth/ftgrays.c
index fd357a50fc..93538331af 100644
--- a/thirdparty/freetype/src/smooth/ftgrays.c
+++ b/thirdparty/freetype/src/smooth/ftgrays.c
@@ -4,7 +4,7 @@
*
* A new `perfect' anti-aliasing renderer (body).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/smooth/ftgrays.h b/thirdparty/freetype/src/smooth/ftgrays.h
index e9f9c7a4ad..e10fd039ac 100644
--- a/thirdparty/freetype/src/smooth/ftgrays.h
+++ b/thirdparty/freetype/src/smooth/ftgrays.h
@@ -4,7 +4,7 @@
*
* FreeType smooth renderer declaration
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/smooth/ftsmerrs.h b/thirdparty/freetype/src/smooth/ftsmerrs.h
index d52c0dd9e2..3f8567b0fa 100644
--- a/thirdparty/freetype/src/smooth/ftsmerrs.h
+++ b/thirdparty/freetype/src/smooth/ftsmerrs.h
@@ -4,7 +4,7 @@
*
* smooth renderer error codes (specification only).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/smooth/ftsmooth.c b/thirdparty/freetype/src/smooth/ftsmooth.c
index cd034d2b40..072045cbc2 100644
--- a/thirdparty/freetype/src/smooth/ftsmooth.c
+++ b/thirdparty/freetype/src/smooth/ftsmooth.c
@@ -4,7 +4,7 @@
*
* Anti-aliasing renderer interface (body).
*
- * Copyright (C) 2000-2019 by
+ * Copyright (C) 2000-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -155,6 +155,9 @@
goto Exit;
}
+ if ( !bitmap->rows || !bitmap->pitch )
+ goto Exit;
+
/* allocate new one */
if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) )
goto Exit;
@@ -188,7 +191,7 @@
/* implode outline if needed */
{
FT_Vector* points = outline->points;
- FT_Vector* points_end = points + outline->n_points;
+ FT_Vector* points_end = FT_OFFSET( points, outline->n_points );
FT_Vector* vec;
@@ -207,7 +210,7 @@
/* deflate outline if needed */
{
FT_Vector* points = outline->points;
- FT_Vector* points_end = points + outline->n_points;
+ FT_Vector* points_end = FT_OFFSET( points, outline->n_points );
FT_Vector* vec;
diff --git a/thirdparty/freetype/src/smooth/ftsmooth.h b/thirdparty/freetype/src/smooth/ftsmooth.h
index fbb21a31d0..ee5d2ff61d 100644
--- a/thirdparty/freetype/src/smooth/ftsmooth.h
+++ b/thirdparty/freetype/src/smooth/ftsmooth.h
@@ -4,7 +4,7 @@
*
* Anti-aliasing renderer interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/smooth/module.mk b/thirdparty/freetype/src/smooth/module.mk
index 44b76dfec6..ad8b47dab6 100644
--- a/thirdparty/freetype/src/smooth/module.mk
+++ b/thirdparty/freetype/src/smooth/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/smooth/rules.mk b/thirdparty/freetype/src/smooth/rules.mk
index 0153ac24a4..b08056fac5 100644
--- a/thirdparty/freetype/src/smooth/rules.mk
+++ b/thirdparty/freetype/src/smooth/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/smooth/smooth.c b/thirdparty/freetype/src/smooth/smooth.c
index 9c543d3360..6ad9424f01 100644
--- a/thirdparty/freetype/src/smooth/smooth.c
+++ b/thirdparty/freetype/src/smooth/smooth.c
@@ -4,7 +4,7 @@
*
* FreeType anti-aliasing rasterer module component (body only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/module.mk b/thirdparty/freetype/src/truetype/module.mk
index 8a841cc956..2d8d39d1f7 100644
--- a/thirdparty/freetype/src/truetype/module.mk
+++ b/thirdparty/freetype/src/truetype/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/truetype/rules.mk b/thirdparty/freetype/src/truetype/rules.mk
index df8dcd4a4e..2f6fecfc44 100644
--- a/thirdparty/freetype/src/truetype/rules.mk
+++ b/thirdparty/freetype/src/truetype/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/truetype/truetype.c b/thirdparty/freetype/src/truetype/truetype.c
index 84928e7321..1f15b29bb2 100644
--- a/thirdparty/freetype/src/truetype/truetype.c
+++ b/thirdparty/freetype/src/truetype/truetype.c
@@ -4,7 +4,7 @@
*
* FreeType TrueType driver component (body only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/ttdriver.c b/thirdparty/freetype/src/truetype/ttdriver.c
index ff626d53ab..90fab46e28 100644
--- a/thirdparty/freetype/src/truetype/ttdriver.c
+++ b/thirdparty/freetype/src/truetype/ttdriver.c
@@ -4,7 +4,7 @@
*
* TrueType font driver implementation (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/ttdriver.h b/thirdparty/freetype/src/truetype/ttdriver.h
index 3936c6a4de..d1cfa47c8b 100644
--- a/thirdparty/freetype/src/truetype/ttdriver.h
+++ b/thirdparty/freetype/src/truetype/ttdriver.h
@@ -4,7 +4,7 @@
*
* High-level TrueType driver interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/tterrors.h b/thirdparty/freetype/src/truetype/tterrors.h
index 5609d28d68..71d66023cd 100644
--- a/thirdparty/freetype/src/truetype/tterrors.h
+++ b/thirdparty/freetype/src/truetype/tterrors.h
@@ -4,7 +4,7 @@
*
* TrueType error codes (specification only).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/ttgload.c b/thirdparty/freetype/src/truetype/ttgload.c
index a04684086b..2a1742839a 100644
--- a/thirdparty/freetype/src/truetype/ttgload.c
+++ b/thirdparty/freetype/src/truetype/ttgload.c
@@ -4,7 +4,7 @@
*
* TrueType Glyph Loader (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -1102,9 +1102,16 @@
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- /* if we have a HVAR table, `pp1' and/or `pp2' are already adjusted */
- if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ||
- !IS_HINTED( loader->load_flags ) )
+ /* if we have a HVAR table, `pp1' and/or `pp2' */
+ /* are already adjusted but unscaled */
+ if ( ( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) &&
+ IS_HINTED( loader->load_flags ) )
+ {
+ loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
+ loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
+ /* pp1.y and pp2.y are always zero */
+ }
+ else
#endif
{
loader->pp1 = outline->points[n_points - 4];
@@ -1112,9 +1119,17 @@
}
#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
- /* if we have a VVAR table, `pp3' and/or `pp4' are already adjusted */
- if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ||
- !IS_HINTED( loader->load_flags ) )
+ /* if we have a VVAR table, `pp3' and/or `pp4' */
+ /* are already adjusted but unscaled */
+ if ( ( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) &&
+ IS_HINTED( loader->load_flags ) )
+ {
+ loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
+ loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
+ loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
+ loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
+ }
+ else
#endif
{
loader->pp3 = outline->points[n_points - 2];
@@ -2287,13 +2302,14 @@
if ( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 )
{
- top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
+ top = (FT_Short)FT_DivFix( SUB_LONG( loader->pp3.y, bbox.yMax ),
y_scale );
if ( loader->pp3.y <= loader->pp4.y )
advance = 0;
else
- advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,
+ advance = (FT_UShort)FT_DivFix( SUB_LONG( loader->pp3.y,
+ loader->pp4.y ),
y_scale );
}
else
diff --git a/thirdparty/freetype/src/truetype/ttgload.h b/thirdparty/freetype/src/truetype/ttgload.h
index f1324bc862..9a8c3e71dd 100644
--- a/thirdparty/freetype/src/truetype/ttgload.h
+++ b/thirdparty/freetype/src/truetype/ttgload.h
@@ -4,7 +4,7 @@
*
* TrueType Glyph Loader (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/ttgxvar.c b/thirdparty/freetype/src/truetype/ttgxvar.c
index 78d87dc097..110f24a116 100644
--- a/thirdparty/freetype/src/truetype/ttgxvar.c
+++ b/thirdparty/freetype/src/truetype/ttgxvar.c
@@ -4,7 +4,7 @@
*
* TrueType GX Font Variation loader
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, Werner Lemberg, and George Williams.
*
* This file is part of the FreeType project, and may only be used,
@@ -1470,6 +1470,7 @@
FT_ULong table_len;
FT_ULong gvar_start;
FT_ULong offsetToData;
+ FT_ULong offsets_len;
GX_GVar_Head gvar_head;
static const FT_Frame_Field gvar_fields[] =
@@ -1530,9 +1531,13 @@
goto Exit;
}
- /* rough sanity check: offsets can be either 2 or 4 bytes */
- if ( (FT_ULong)gvar_head.glyphCount *
- ( ( gvar_head.flags & 1 ) ? 4 : 2 ) > table_len )
+ /* offsets can be either 2 or 4 bytes */
+ /* (one more offset than glyphs, to mark size of last) */
+ offsets_len = ( gvar_head.glyphCount + 1 ) *
+ ( ( gvar_head.flags & 1 ) ? 4L : 2L );
+
+ /* rough sanity check */
+ if (offsets_len > table_len )
{
FT_TRACE1(( "ft_var_load_gvar: invalid number of glyphs\n" ));
error = FT_THROW( Invalid_Table );
@@ -1541,81 +1546,102 @@
FT_TRACE2(( "loaded\n" ));
- blend->gvar_size = table_len;
- blend->tuplecount = gvar_head.globalCoordCount;
- blend->gv_glyphcnt = gvar_head.glyphCount;
- offsetToData = gvar_start + gvar_head.offsetToData;
+ blend->gvar_size = table_len;
+ offsetToData = gvar_start + gvar_head.offsetToData;
FT_TRACE5(( "gvar: there %s %d shared coordinate%s:\n",
- blend->tuplecount == 1 ? "is" : "are",
- blend->tuplecount,
- blend->tuplecount == 1 ? "" : "s" ));
+ gvar_head.globalCoordCount == 1 ? "is" : "are",
+ gvar_head.globalCoordCount,
+ gvar_head.globalCoordCount == 1 ? "" : "s" ));
- if ( FT_NEW_ARRAY( blend->glyphoffsets, blend->gv_glyphcnt + 1 ) )
+ if ( FT_FRAME_ENTER( offsets_len ) )
goto Exit;
+ /* offsets (one more offset than glyphs, to mark size of last) */
+ if ( FT_NEW_ARRAY( blend->glyphoffsets, gvar_head.glyphCount + 1 ) )
+ goto Fail2;
+
if ( gvar_head.flags & 1 )
{
- FT_ULong limit = gvar_start + table_len;
-
+ FT_ULong limit = gvar_start + table_len;
+ FT_ULong max_offset = 0;
- /* long offsets (one more offset than glyphs, to mark size of last) */
- if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) )
- goto Exit;
- for ( i = 0; i <= blend->gv_glyphcnt; i++ )
+ for ( i = 0; i <= gvar_head.glyphCount; i++ )
{
blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG();
- /* use `>', not `>=' */
- if ( blend->glyphoffsets[i] > limit )
+
+ if ( max_offset <= blend->glyphoffsets[i] )
+ max_offset = blend->glyphoffsets[i];
+ else
{
FT_TRACE2(( "ft_var_load_gvar:"
- " invalid glyph variation data offset for index %d\n",
+ " glyph variation data offset %d not monotonic\n",
i ));
- error = FT_THROW( Invalid_Table );
- break;
+ blend->glyphoffsets[i] = max_offset;
+ }
+
+ /* use `<', not `<=' */
+ if ( limit < blend->glyphoffsets[i] )
+ {
+ FT_TRACE2(( "ft_var_load_gvar:"
+ " glyph variation data offset %d out of range\n",
+ i ));
+ blend->glyphoffsets[i] = limit;
}
}
}
else
{
- FT_ULong limit = gvar_start + table_len;
-
+ FT_ULong limit = gvar_start + table_len;
+ FT_ULong max_offset = 0;
- /* short offsets (one more offset than glyphs, to mark size of last) */
- if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) )
- goto Exit;
- for ( i = 0; i <= blend->gv_glyphcnt; i++ )
+ for ( i = 0; i <= gvar_head.glyphCount; i++ )
{
blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2;
- /* use `>', not `>=' */
- if ( blend->glyphoffsets[i] > limit )
+
+ if ( max_offset <= blend->glyphoffsets[i] )
+ max_offset = blend->glyphoffsets[i];
+ else
{
FT_TRACE2(( "ft_var_load_gvar:"
- " invalid glyph variation data offset for index %d\n",
+ " glyph variation data offset %d not monotonic\n",
i ));
- error = FT_THROW( Invalid_Table );
- break;
+ blend->glyphoffsets[i] = max_offset;
+ }
+
+ /* use `<', not `<=' */
+ if ( limit < blend->glyphoffsets[i] )
+ {
+ FT_TRACE2(( "ft_var_load_gvar:"
+ " glyph variation data offset %d out of range\n",
+ i ));
+ blend->glyphoffsets[i] = limit;
}
}
}
+ blend->gv_glyphcnt = gvar_head.glyphCount;
+
FT_FRAME_EXIT();
- if ( error )
- goto Exit;
- if ( blend->tuplecount != 0 )
+ if ( gvar_head.globalCoordCount != 0 )
{
- if ( FT_NEW_ARRAY( blend->tuplecoords,
- gvar_head.axisCount * blend->tuplecount ) )
- goto Exit;
+ if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) ||
+ FT_FRAME_ENTER( gvar_head.globalCoordCount *
+ gvar_head.axisCount * 2L ) )
+ {
+ FT_TRACE2(( "ft_var_load_gvar:"
+ " glyph variation shared tuples missing\n" ));
+ goto Fail;
+ }
- if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) ||
- FT_FRAME_ENTER( blend->tuplecount * gvar_head.axisCount * 2L ) )
- goto Exit;
+ if ( FT_NEW_ARRAY( blend->tuplecoords,
+ gvar_head.axisCount * gvar_head.globalCoordCount ) )
+ goto Fail2;
- for ( i = 0; i < blend->tuplecount; i++ )
+ for ( i = 0; i < gvar_head.globalCoordCount; i++ )
{
FT_TRACE5(( " [ " ));
for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ )
@@ -1628,6 +1654,8 @@
FT_TRACE5(( "]\n" ));
}
+ blend->tuplecount = gvar_head.globalCoordCount;
+
FT_TRACE5(( "\n" ));
FT_FRAME_EXIT();
@@ -1635,6 +1663,14 @@
Exit:
return error;
+
+ Fail2:
+ FT_FRAME_EXIT();
+
+ Fail:
+ FT_FREE( blend->glyphoffsets );
+ blend->gv_glyphcnt = 0;
+ goto Exit;
}
@@ -2127,7 +2163,7 @@
/* `fvar' table validity check in `sfnt_init_face' */
/* the various `*_size' variables, which we also use as */
- /* offsets into the `mmlen' array, must be multiples of the */
+ /* offsets into the `mmvar' array, must be multiples of the */
/* pointer size (except the last one); without such an */
/* alignment there might be runtime errors due to */
/* misaligned addresses */
@@ -3037,7 +3073,7 @@
TT_Set_Named_Instance( TT_Face face,
FT_UInt instance_index )
{
- FT_Error error = FT_ERR( Invalid_Argument );
+ FT_Error error;
GX_Blend blend;
FT_MM_Var* mmvar;
@@ -3057,7 +3093,10 @@
/* `instance_index' starts with value 1, thus `>' */
if ( instance_index > num_instances )
+ {
+ error = FT_ERR( Invalid_Argument );
goto Exit;
+ }
if ( instance_index > 0 )
{
@@ -3766,7 +3805,7 @@
blend->glyphoffsets[glyph_index + 1] )
{
FT_TRACE2(( "TT_Vary_Apply_Glyph_Deltas:"
- " no variation data for this glyph\n" ));
+ " no variation data for glyph %d\n", glyph_index ));
return FT_Err_Ok;
}
diff --git a/thirdparty/freetype/src/truetype/ttgxvar.h b/thirdparty/freetype/src/truetype/ttgxvar.h
index 07c99b6403..11664e997a 100644
--- a/thirdparty/freetype/src/truetype/ttgxvar.h
+++ b/thirdparty/freetype/src/truetype/ttgxvar.h
@@ -4,7 +4,7 @@
*
* TrueType GX Font Variation loader (specification)
*
- * Copyright (C) 2004-2019 by
+ * Copyright (C) 2004-2020 by
* David Turner, Robert Wilhelm, Werner Lemberg and George Williams.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/ttinterp.c b/thirdparty/freetype/src/truetype/ttinterp.c
index 70434e1729..3215040970 100644
--- a/thirdparty/freetype/src/truetype/ttinterp.c
+++ b/thirdparty/freetype/src/truetype/ttinterp.c
@@ -4,7 +4,7 @@
*
* TrueType bytecode interpreter (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -3718,7 +3718,7 @@
/* We will then parse the current table. */
rec = exc->FDefs;
- limit = rec + exc->numFDefs;
+ limit = FT_OFFSET( rec, exc->numFDefs );
n = (FT_ULong)args[0];
for ( ; rec < limit; rec++ )
@@ -3965,6 +3965,9 @@
if ( BOUNDSL( F, exc->maxFunc + 1 ) )
goto Fail;
+ if ( !exc->FDefs )
+ goto Fail;
+
/* Except for some old Apple fonts, all functions in a TrueType */
/* font are defined in increasing order, starting from 0. This */
/* means that we normally have */
@@ -4062,7 +4065,7 @@
/* */
/* If this isn't true, we need to look up the function table. */
- def = exc->FDefs + F;
+ def = FT_OFFSET( exc->FDefs, F );
if ( exc->maxFunc + 1 != exc->numFDefs || def->opc != F )
{
/* look up the FDefs table */
@@ -4070,7 +4073,7 @@
def = exc->FDefs;
- limit = def + exc->numFDefs;
+ limit = FT_OFFSET( def, exc->numFDefs );
while ( def < limit && def->opc != F )
def++;
@@ -4150,7 +4153,7 @@
/* First of all, look for the same function in our table */
def = exc->IDefs;
- limit = def + exc->numIDefs;
+ limit = FT_OFFSET( def, exc->numIDefs );
for ( ; def < limit; def++ )
if ( def->opc == (FT_ULong)args[0] )
@@ -6346,12 +6349,14 @@
/* twilight points (confirmed by Greg Hitchcock) */
if ( exc->GS.gep1 == 0 )
{
- exc->zp1.org[point].x = exc->zp0.org[exc->GS.rp0].x +
- TT_MulFix14( cvt_dist,
- exc->GS.freeVector.x );
- exc->zp1.org[point].y = exc->zp0.org[exc->GS.rp0].y +
- TT_MulFix14( cvt_dist,
- exc->GS.freeVector.y );
+ exc->zp1.org[point].x = ADD_LONG(
+ exc->zp0.org[exc->GS.rp0].x,
+ TT_MulFix14( cvt_dist,
+ exc->GS.freeVector.x ) );
+ exc->zp1.org[point].y = ADD_LONG(
+ exc->zp0.org[exc->GS.rp0].y,
+ TT_MulFix14( cvt_dist,
+ exc->GS.freeVector.y ) );
exc->zp1.cur[point] = exc->zp1.org[point];
}
@@ -7715,7 +7720,7 @@
Ins_UNKNOWN( TT_ExecContext exc )
{
TT_DefRecord* def = exc->IDefs;
- TT_DefRecord* limit = def + exc->numIDefs;
+ TT_DefRecord* limit = FT_OFFSET( def, exc->numIDefs );
for ( ; def < limit; def++ )
@@ -7867,7 +7872,7 @@
FT_MAX( 50,
exc->cvtSize / 10 );
else
- exc->loopcall_counter_max = 300 + 8 * exc->cvtSize;
+ exc->loopcall_counter_max = 300 + 22 * exc->cvtSize;
/* as a protection against an unreasonable number of CVT entries */
/* we assume at most 100 control values per glyph for the counter */
@@ -8567,7 +8572,7 @@
case FT_ERR( Invalid_Opcode ):
{
TT_DefRecord* def = exc->IDefs;
- TT_DefRecord* limit = def + exc->numIDefs;
+ TT_DefRecord* limit = FT_OFFSET( def, exc->numIDefs );
for ( ; def < limit; def++ )
diff --git a/thirdparty/freetype/src/truetype/ttinterp.h b/thirdparty/freetype/src/truetype/ttinterp.h
index 0cb1e892fb..07e4ad6891 100644
--- a/thirdparty/freetype/src/truetype/ttinterp.h
+++ b/thirdparty/freetype/src/truetype/ttinterp.h
@@ -4,7 +4,7 @@
*
* TrueType bytecode interpreter (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/ttobjs.c b/thirdparty/freetype/src/truetype/ttobjs.c
index e4775a51ed..730a5b8cdf 100644
--- a/thirdparty/freetype/src/truetype/ttobjs.c
+++ b/thirdparty/freetype/src/truetype/ttobjs.c
@@ -4,7 +4,7 @@
*
* Objects manager (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/ttobjs.h b/thirdparty/freetype/src/truetype/ttobjs.h
index 9fc654d5d1..7c3fc7ef8a 100644
--- a/thirdparty/freetype/src/truetype/ttobjs.h
+++ b/thirdparty/freetype/src/truetype/ttobjs.h
@@ -4,7 +4,7 @@
*
* Objects manager (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/ttpload.c b/thirdparty/freetype/src/truetype/ttpload.c
index bc954c2dba..d35393a8b0 100644
--- a/thirdparty/freetype/src/truetype/ttpload.c
+++ b/thirdparty/freetype/src/truetype/ttpload.c
@@ -4,7 +4,7 @@
*
* TrueType-specific tables loader (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -633,7 +633,7 @@
FT_UInt nn;
FT_Byte* result = NULL;
FT_ULong record_size = face->hdmx_record_size;
- FT_Byte* record = face->hdmx_table + 8;
+ FT_Byte* record = FT_OFFSET( face->hdmx_table, 8 );
for ( nn = 0; nn < face->hdmx_record_count; nn++ )
diff --git a/thirdparty/freetype/src/truetype/ttpload.h b/thirdparty/freetype/src/truetype/ttpload.h
index 022750e324..3bbd4add19 100644
--- a/thirdparty/freetype/src/truetype/ttpload.h
+++ b/thirdparty/freetype/src/truetype/ttpload.h
@@ -4,7 +4,7 @@
*
* TrueType-specific tables loader (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/ttsubpix.c b/thirdparty/freetype/src/truetype/ttsubpix.c
index 23a2e5b440..8289818863 100644
--- a/thirdparty/freetype/src/truetype/ttsubpix.c
+++ b/thirdparty/freetype/src/truetype/ttsubpix.c
@@ -4,7 +4,7 @@
*
* TrueType Subpixel Hinting.
*
- * Copyright (C) 2010-2019 by
+ * Copyright (C) 2010-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/truetype/ttsubpix.h b/thirdparty/freetype/src/truetype/ttsubpix.h
index 4966800c2d..23adf7e8d8 100644
--- a/thirdparty/freetype/src/truetype/ttsubpix.h
+++ b/thirdparty/freetype/src/truetype/ttsubpix.h
@@ -4,7 +4,7 @@
*
* TrueType Subpixel Hinting.
*
- * Copyright (C) 2010-2019 by
+ * Copyright (C) 2010-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/module.mk b/thirdparty/freetype/src/type1/module.mk
index 2f48c65821..cffb774b45 100644
--- a/thirdparty/freetype/src/type1/module.mk
+++ b/thirdparty/freetype/src/type1/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/type1/rules.mk b/thirdparty/freetype/src/type1/rules.mk
index 901169c7a5..213e619247 100644
--- a/thirdparty/freetype/src/type1/rules.mk
+++ b/thirdparty/freetype/src/type1/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/type1/t1afm.c b/thirdparty/freetype/src/type1/t1afm.c
index 6841184539..0866e7bf97 100644
--- a/thirdparty/freetype/src/type1/t1afm.c
+++ b/thirdparty/freetype/src/type1/t1afm.c
@@ -4,7 +4,7 @@
*
* AFM support for Type 1 fonts (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1afm.h b/thirdparty/freetype/src/type1/t1afm.h
index a8e6a5495a..40ce8f9754 100644
--- a/thirdparty/freetype/src/type1/t1afm.h
+++ b/thirdparty/freetype/src/type1/t1afm.h
@@ -4,7 +4,7 @@
*
* AFM support for Type 1 fonts (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1driver.c b/thirdparty/freetype/src/type1/t1driver.c
index 557733da3b..75a5698e8d 100644
--- a/thirdparty/freetype/src/type1/t1driver.c
+++ b/thirdparty/freetype/src/type1/t1driver.c
@@ -4,7 +4,7 @@
*
* Type 1 driver interface (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1driver.h b/thirdparty/freetype/src/type1/t1driver.h
index 206f64a0bc..84b3e041c4 100644
--- a/thirdparty/freetype/src/type1/t1driver.h
+++ b/thirdparty/freetype/src/type1/t1driver.h
@@ -4,7 +4,7 @@
*
* High-level Type 1 driver interface (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1errors.h b/thirdparty/freetype/src/type1/t1errors.h
index b35f67a24c..1b119b843a 100644
--- a/thirdparty/freetype/src/type1/t1errors.h
+++ b/thirdparty/freetype/src/type1/t1errors.h
@@ -4,7 +4,7 @@
*
* Type 1 error codes (specification only).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1gload.c b/thirdparty/freetype/src/type1/t1gload.c
index f9b115b186..fcaf66c401 100644
--- a/thirdparty/freetype/src/type1/t1gload.c
+++ b/thirdparty/freetype/src/type1/t1gload.c
@@ -4,7 +4,7 @@
*
* Type 1 Glyph Loader (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1gload.h b/thirdparty/freetype/src/type1/t1gload.h
index 80440369dc..59fae82b6d 100644
--- a/thirdparty/freetype/src/type1/t1gload.h
+++ b/thirdparty/freetype/src/type1/t1gload.h
@@ -4,7 +4,7 @@
*
* Type 1 Glyph Loader (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1load.c b/thirdparty/freetype/src/type1/t1load.c
index 5cffdfaac4..d0ea36badb 100644
--- a/thirdparty/freetype/src/type1/t1load.c
+++ b/thirdparty/freetype/src/type1/t1load.c
@@ -4,7 +4,7 @@
*
* Type 1 font loader (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
@@ -309,31 +309,55 @@
FT_UInt i;
FT_Fixed axiscoords[T1_MAX_MM_AXIS];
PS_Blend blend = face->blend;
+ FT_UShort* axis_flags;
+
+ FT_Offset mmvar_size;
+ FT_Offset axis_flags_size;
+ FT_Offset axis_size;
error = T1_Get_Multi_Master( face, &mmaster );
if ( error )
goto Exit;
- if ( FT_ALLOC( mmvar,
- sizeof ( FT_MM_Var ) +
- mmaster.num_axis * sizeof ( FT_Var_Axis ) ) )
+
+ /* the various `*_size' variables, which we also use as */
+ /* offsets into the `mmvar' array, must be multiples of the */
+ /* pointer size (except the last one); without such an */
+ /* alignment there might be runtime errors due to */
+ /* misaligned addresses */
+#undef ALIGN_SIZE
+#define ALIGN_SIZE( n ) \
+ ( ( (n) + sizeof (void*) - 1 ) & ~( sizeof (void*) - 1 ) )
+
+ mmvar_size = ALIGN_SIZE( sizeof ( FT_MM_Var ) );
+ axis_flags_size = ALIGN_SIZE( mmaster.num_axis *
+ sizeof ( FT_UShort ) );
+ axis_size = mmaster.num_axis * sizeof ( FT_Var_Axis );
+
+ if ( FT_ALLOC( mmvar, mmvar_size +
+ axis_flags_size +
+ axis_size ) )
goto Exit;
mmvar->num_axis = mmaster.num_axis;
mmvar->num_designs = mmaster.num_designs;
mmvar->num_namedstyles = 0; /* Not supported */
- mmvar->axis = (FT_Var_Axis*)&mmvar[1];
- /* Point to axes after MM_Var struct */
- mmvar->namedstyle = NULL;
+
+ /* while axis flags are meaningless here, we have to provide the array */
+ /* to make `FT_Get_Var_Axis_Flags' work: the function expects that the */
+ /* values directly follow the data of `FT_MM_Var' */
+ axis_flags = (FT_UShort*)( (char*)mmvar + mmvar_size );
+ for ( i = 0; i < mmaster.num_axis; i++ )
+ axis_flags[i] = 0;
+
+ mmvar->axis = (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size );
+ mmvar->namedstyle = NULL;
for ( i = 0; i < mmaster.num_axis; i++ )
{
mmvar->axis[i].name = mmaster.axis[i].name;
mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum );
mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum );
- mmvar->axis[i].def = ( mmvar->axis[i].minimum +
- mmvar->axis[i].maximum ) / 2;
- /* Does not apply. But this value is in range */
mmvar->axis[i].strid = ~0U; /* Does not apply */
mmvar->axis[i].tag = ~0U; /* Does not apply */
diff --git a/thirdparty/freetype/src/type1/t1load.h b/thirdparty/freetype/src/type1/t1load.h
index 44f835bde2..9cac0f6fb6 100644
--- a/thirdparty/freetype/src/type1/t1load.h
+++ b/thirdparty/freetype/src/type1/t1load.h
@@ -4,7 +4,7 @@
*
* Type 1 font loader (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1objs.c b/thirdparty/freetype/src/type1/t1objs.c
index 741388a645..80ee0e265e 100644
--- a/thirdparty/freetype/src/type1/t1objs.c
+++ b/thirdparty/freetype/src/type1/t1objs.c
@@ -4,7 +4,7 @@
*
* Type 1 objects manager (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1objs.h b/thirdparty/freetype/src/type1/t1objs.h
index 2161091f77..6bc902cc89 100644
--- a/thirdparty/freetype/src/type1/t1objs.h
+++ b/thirdparty/freetype/src/type1/t1objs.h
@@ -4,7 +4,7 @@
*
* Type 1 objects manager (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1parse.c b/thirdparty/freetype/src/type1/t1parse.c
index 56caeb9e40..ec30355bf8 100644
--- a/thirdparty/freetype/src/type1/t1parse.c
+++ b/thirdparty/freetype/src/type1/t1parse.c
@@ -4,7 +4,7 @@
*
* Type 1 parser (body).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1parse.h b/thirdparty/freetype/src/type1/t1parse.h
index dab8fddc8b..edf79b0a8b 100644
--- a/thirdparty/freetype/src/type1/t1parse.h
+++ b/thirdparty/freetype/src/type1/t1parse.h
@@ -4,7 +4,7 @@
*
* Type 1 parser (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/t1tokens.h b/thirdparty/freetype/src/type1/t1tokens.h
index 97f2dbe0cf..c09420355d 100644
--- a/thirdparty/freetype/src/type1/t1tokens.h
+++ b/thirdparty/freetype/src/type1/t1tokens.h
@@ -4,7 +4,7 @@
*
* Type 1 tokenizer (specification).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type1/type1.c b/thirdparty/freetype/src/type1/type1.c
index ce8557a5fb..95dbaeb501 100644
--- a/thirdparty/freetype/src/type1/type1.c
+++ b/thirdparty/freetype/src/type1/type1.c
@@ -4,7 +4,7 @@
*
* FreeType Type 1 driver component (body only).
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type42/module.mk b/thirdparty/freetype/src/type42/module.mk
index 9e9d15455b..6ef3a95ead 100644
--- a/thirdparty/freetype/src/type42/module.mk
+++ b/thirdparty/freetype/src/type42/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2002-2019 by
+# Copyright (C) 2002-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/type42/rules.mk b/thirdparty/freetype/src/type42/rules.mk
index 9d71f5300e..f4ce91a3b7 100644
--- a/thirdparty/freetype/src/type42/rules.mk
+++ b/thirdparty/freetype/src/type42/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 2002-2019 by
+# Copyright (C) 2002-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/type42/t42drivr.c b/thirdparty/freetype/src/type42/t42drivr.c
index 09ad632e97..4b2cab3474 100644
--- a/thirdparty/freetype/src/type42/t42drivr.c
+++ b/thirdparty/freetype/src/type42/t42drivr.c
@@ -4,7 +4,7 @@
*
* High-level Type 42 driver interface (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* Roberto Alameda.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type42/t42drivr.h b/thirdparty/freetype/src/type42/t42drivr.h
index a35ca28f84..7e7ec70f9d 100644
--- a/thirdparty/freetype/src/type42/t42drivr.h
+++ b/thirdparty/freetype/src/type42/t42drivr.h
@@ -4,7 +4,7 @@
*
* High-level Type 42 driver interface (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* Roberto Alameda.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type42/t42error.h b/thirdparty/freetype/src/type42/t42error.h
index 5fb2143949..6d3617e927 100644
--- a/thirdparty/freetype/src/type42/t42error.h
+++ b/thirdparty/freetype/src/type42/t42error.h
@@ -4,7 +4,7 @@
*
* Type 42 error codes (specification only).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type42/t42objs.c b/thirdparty/freetype/src/type42/t42objs.c
index d31bace451..8d1e63ffc7 100644
--- a/thirdparty/freetype/src/type42/t42objs.c
+++ b/thirdparty/freetype/src/type42/t42objs.c
@@ -4,7 +4,7 @@
*
* Type 42 objects manager (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* Roberto Alameda.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type42/t42objs.h b/thirdparty/freetype/src/type42/t42objs.h
index 98300cf348..ecb495e8f0 100644
--- a/thirdparty/freetype/src/type42/t42objs.h
+++ b/thirdparty/freetype/src/type42/t42objs.h
@@ -4,7 +4,7 @@
*
* Type 42 objects manager (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* Roberto Alameda.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type42/t42parse.c b/thirdparty/freetype/src/type42/t42parse.c
index c47a77786d..7f26d04170 100644
--- a/thirdparty/freetype/src/type42/t42parse.c
+++ b/thirdparty/freetype/src/type42/t42parse.c
@@ -4,7 +4,7 @@
*
* Type 42 font parser (body).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* Roberto Alameda.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type42/t42parse.h b/thirdparty/freetype/src/type42/t42parse.h
index 0c7bb48496..de54a46cf1 100644
--- a/thirdparty/freetype/src/type42/t42parse.h
+++ b/thirdparty/freetype/src/type42/t42parse.h
@@ -4,7 +4,7 @@
*
* Type 42 font parser (specification).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* Roberto Alameda.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type42/t42types.h b/thirdparty/freetype/src/type42/t42types.h
index a258144ec3..f66f09db87 100644
--- a/thirdparty/freetype/src/type42/t42types.h
+++ b/thirdparty/freetype/src/type42/t42types.h
@@ -4,7 +4,7 @@
*
* Type 42 font data types (specification only).
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* Roberto Alameda.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/type42/type42.c b/thirdparty/freetype/src/type42/type42.c
index 0cb7b77eec..4739b3c333 100644
--- a/thirdparty/freetype/src/type42/type42.c
+++ b/thirdparty/freetype/src/type42/type42.c
@@ -4,7 +4,7 @@
*
* FreeType Type 42 driver component.
*
- * Copyright (C) 2002-2019 by
+ * Copyright (C) 2002-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/winfonts/fnterrs.h b/thirdparty/freetype/src/winfonts/fnterrs.h
index af29307c75..f98e68435b 100644
--- a/thirdparty/freetype/src/winfonts/fnterrs.h
+++ b/thirdparty/freetype/src/winfonts/fnterrs.h
@@ -4,7 +4,7 @@
*
* Win FNT/FON error codes (specification only).
*
- * Copyright (C) 2001-2019 by
+ * Copyright (C) 2001-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
*
* This file is part of the FreeType project, and may only be used,
diff --git a/thirdparty/freetype/src/winfonts/module.mk b/thirdparty/freetype/src/winfonts/module.mk
index 82fb0151f8..4614c55fd0 100644
--- a/thirdparty/freetype/src/winfonts/module.mk
+++ b/thirdparty/freetype/src/winfonts/module.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/winfonts/rules.mk b/thirdparty/freetype/src/winfonts/rules.mk
index 998d49bc9f..e73ef5ea99 100644
--- a/thirdparty/freetype/src/winfonts/rules.mk
+++ b/thirdparty/freetype/src/winfonts/rules.mk
@@ -3,7 +3,7 @@
#
-# Copyright (C) 1996-2019 by
+# Copyright (C) 1996-2020 by
# David Turner, Robert Wilhelm, and Werner Lemberg.
#
# This file is part of the FreeType project, and may only be used, modified,
diff --git a/thirdparty/freetype/src/winfonts/winfnt.c b/thirdparty/freetype/src/winfonts/winfnt.c
index 2d771be2cc..9b466e8f28 100644
--- a/thirdparty/freetype/src/winfonts/winfnt.c
+++ b/thirdparty/freetype/src/winfonts/winfnt.c
@@ -4,7 +4,7 @@
*
* FreeType font driver for Windows FNT/FON files
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
* Copyright 2003 Huw D M Davies for Codeweavers
* Copyright 2007 Dmitry Timoshkov for Codeweavers
@@ -331,7 +331,7 @@
{
FT_TRACE2(( "invalid alignment shift count for resource data\n" ));
error = FT_THROW( Invalid_File_Format );
- goto Exit;
+ goto Exit1;
}
@@ -597,6 +597,10 @@
Exit:
return error;
+
+ Exit1:
+ FT_FRAME_EXIT();
+ goto Exit;
}
diff --git a/thirdparty/freetype/src/winfonts/winfnt.h b/thirdparty/freetype/src/winfonts/winfnt.h
index b628ad4c42..391f4448a7 100644
--- a/thirdparty/freetype/src/winfonts/winfnt.h
+++ b/thirdparty/freetype/src/winfonts/winfnt.h
@@ -4,7 +4,7 @@
*
* FreeType font driver for Windows FNT/FON files
*
- * Copyright (C) 1996-2019 by
+ * Copyright (C) 1996-2020 by
* David Turner, Robert Wilhelm, and Werner Lemberg.
* Copyright 2007 Dmitry Timoshkov for Codeweavers
*
diff --git a/thirdparty/jpeg-compressor/jpgd.cpp b/thirdparty/jpeg-compressor/jpgd.cpp
index 62fbd1b72d..baf6ea0484 100644
--- a/thirdparty/jpeg-compressor/jpgd.cpp
+++ b/thirdparty/jpeg-compressor/jpgd.cpp
@@ -1,27 +1,53 @@
-// jpgd.cpp - C++ class for JPEG decompression.
-// Public domain, Rich Geldreich <richgel99@gmail.com>
+// jpgd.cpp - C++ class for JPEG decompression. Written by Richard Geldreich <richgel99@gmail.com> between 1994-2020.
+// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2.
+// Supports box and linear chroma upsampling.
+//
+// Released under two licenses. You are free to choose which license you want:
+// License 1:
+// Public Domain
+//
+// License 2:
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
// Alex Evans: Linear memory allocator (taken from jpge.h).
-// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings (all looked harmless)
+// v1.04, May. 19, 2012: Code tweaks to fix VS2008 static code analysis warnings
+// v2.00, March 20, 2020: Fuzzed with zzuf and afl. Fixed several issues, converted most assert()'s to run-time checks. Added chroma upsampling. Removed freq. domain upsampling. gcc/clang warnings.
//
-// Supports progressive and baseline sequential JPEG image files, and the most common chroma subsampling factors: Y, H1V1, H2V1, H1V2, and H2V2.
+// Important:
+// #define JPGD_USE_SSE2 to 0 to completely disable SSE2 usage.
//
-// Chroma upsampling quality: H2V2 is upsampled in the frequency domain, H2V1 and H1V2 are upsampled using point sampling.
-// Chroma upsampling reference: "Fast Scheme for Image Size Change in the Compressed Domain"
-// http://vision.ai.uiuc.edu/~dugad/research/dct/index.html
-
#include "jpgd.h"
#include <string.h>
-
+#include <algorithm>
#include <assert.h>
-#define JPGD_ASSERT(x) assert(x)
#ifdef _MSC_VER
#pragma warning (disable : 4611) // warning C4611: interaction between '_setjmp' and C++ object destruction is non-portable
#endif
-// Set to 1 to enable freq. domain chroma upsampling on images using H2V2 subsampling (0=faster nearest neighbor sampling).
-// This is slower, but results in higher quality on images with highly saturated colors.
-#define JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING 1
+#ifndef JPGD_USE_SSE2
+
+ #if defined(__GNUC__)
+ #if defined(__SSE2__)
+ #define JPGD_USE_SSE2 (1)
+ #endif
+ #elif defined(_MSC_VER)
+ #if defined(_M_X64)
+ #define JPGD_USE_SSE2 (1)
+ #endif
+ #endif
+
+#endif
#define JPGD_TRUE (1)
#define JPGD_FALSE (0)
@@ -29,28 +55,28 @@
#define JPGD_MAX(a,b) (((a)>(b)) ? (a) : (b))
#define JPGD_MIN(a,b) (((a)<(b)) ? (a) : (b))
-// TODO: Move to header and use these constants when declaring the arrays.
-#define JPGD_HUFF_TREE_MAX_LENGTH 512
-#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256
-
namespace jpgd {
-static inline void *jpgd_malloc(size_t nSize) { return malloc(nSize); }
-static inline void jpgd_free(void *p) { free(p); }
+ static inline void* jpgd_malloc(size_t nSize) { return malloc(nSize); }
+ static inline void jpgd_free(void* p) { free(p); }
+
+ // DCT coefficients are stored in this sequence.
+ static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 };
-// DCT coefficients are stored in this sequence.
-static int g_ZAG[64] = { 0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 };
+ enum JPEG_MARKER
+ {
+ M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8,
+ M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC,
+ M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7,
+ M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF,
+ M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0
+ };
-enum JPEG_MARKER
-{
- M_SOF0 = 0xC0, M_SOF1 = 0xC1, M_SOF2 = 0xC2, M_SOF3 = 0xC3, M_SOF5 = 0xC5, M_SOF6 = 0xC6, M_SOF7 = 0xC7, M_JPG = 0xC8,
- M_SOF9 = 0xC9, M_SOF10 = 0xCA, M_SOF11 = 0xCB, M_SOF13 = 0xCD, M_SOF14 = 0xCE, M_SOF15 = 0xCF, M_DHT = 0xC4, M_DAC = 0xCC,
- M_RST0 = 0xD0, M_RST1 = 0xD1, M_RST2 = 0xD2, M_RST3 = 0xD3, M_RST4 = 0xD4, M_RST5 = 0xD5, M_RST6 = 0xD6, M_RST7 = 0xD7,
- M_SOI = 0xD8, M_EOI = 0xD9, M_SOS = 0xDA, M_DQT = 0xDB, M_DNL = 0xDC, M_DRI = 0xDD, M_DHP = 0xDE, M_EXP = 0xDF,
- M_APP0 = 0xE0, M_APP15 = 0xEF, M_JPG0 = 0xF0, M_JPG13 = 0xFD, M_COM = 0xFE, M_TEM = 0x01, M_ERROR = 0x100, RST0 = 0xD0
-};
+ enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 };
-enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2, JPGD_YH2V2 };
+#if JPGD_USE_SSE2
+#include "jpgd_idct.h"
+#endif
#define CONST_BITS 13
#define PASS1_BITS 2
@@ -76,3130 +102,3182 @@ enum JPEG_SUBSAMPLING { JPGD_GRAYSCALE = 0, JPGD_YH1V1, JPGD_YH2V1, JPGD_YH1V2,
#define CLAMP(i) ((static_cast<uint>(i) > 255) ? (((~i) >> 31) & 0xFF) : (i))
-// Compiler creates a fast path 1D IDCT for X non-zero columns
-template <int NONZERO_COLS>
-struct Row
-{
- static void idct(int* pTemp, const jpgd_block_t* pSrc)
- {
- // ACCESS_COL() will be optimized at compile time to either an array access, or 0.
- #define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0)
-
- const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6);
-
- const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
- const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
- const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
-
- const int tmp0 = (ACCESS_COL(0) + ACCESS_COL(4)) << CONST_BITS;
- const int tmp1 = (ACCESS_COL(0) - ACCESS_COL(4)) << CONST_BITS;
-
- const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
-
- const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1);
-
- const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;
- const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);
-
- const int az1 = MULTIPLY(bz1, - FIX_0_899976223);
- const int az2 = MULTIPLY(bz2, - FIX_2_562915447);
- const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5;
- const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5;
-
- const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;
- const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;
- const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;
- const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;
-
- pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS-PASS1_BITS);
- pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS-PASS1_BITS);
- pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS-PASS1_BITS);
- pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS-PASS1_BITS);
- pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS-PASS1_BITS);
- pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS-PASS1_BITS);
- pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS-PASS1_BITS);
- pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS-PASS1_BITS);
- }
-};
-
-template <>
-struct Row<0>
-{
- static void idct(int* pTemp, const jpgd_block_t* pSrc)
- {
-#ifdef _MSC_VER
- pTemp; pSrc;
+ static inline int left_shifti(int val, uint32_t bits)
+ {
+ return static_cast<int>(static_cast<uint32_t>(val) << bits);
+ }
+
+ // Compiler creates a fast path 1D IDCT for X non-zero columns
+ template <int NONZERO_COLS>
+ struct Row
+ {
+ static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc)
+ {
+ // ACCESS_COL() will be optimized at compile time to either an array access, or 0. Good compilers will then optimize out muls against 0.
+#define ACCESS_COL(x) (((x) < NONZERO_COLS) ? (int)pSrc[x] : 0)
+
+ const int z2 = ACCESS_COL(2), z3 = ACCESS_COL(6);
+
+ const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
+ const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065);
+ const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
+
+ const int tmp0 = left_shifti(ACCESS_COL(0) + ACCESS_COL(4), CONST_BITS);
+ const int tmp1 = left_shifti(ACCESS_COL(0) - ACCESS_COL(4), CONST_BITS);
+
+ const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
+
+ const int atmp0 = ACCESS_COL(7), atmp1 = ACCESS_COL(5), atmp2 = ACCESS_COL(3), atmp3 = ACCESS_COL(1);
+
+ const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;
+ const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);
+
+ const int az1 = MULTIPLY(bz1, -FIX_0_899976223);
+ const int az2 = MULTIPLY(bz2, -FIX_2_562915447);
+ const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5;
+ const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5;
+
+ const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;
+ const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;
+ const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;
+ const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;
+
+ pTemp[0] = DESCALE(tmp10 + btmp3, CONST_BITS - PASS1_BITS);
+ pTemp[7] = DESCALE(tmp10 - btmp3, CONST_BITS - PASS1_BITS);
+ pTemp[1] = DESCALE(tmp11 + btmp2, CONST_BITS - PASS1_BITS);
+ pTemp[6] = DESCALE(tmp11 - btmp2, CONST_BITS - PASS1_BITS);
+ pTemp[2] = DESCALE(tmp12 + btmp1, CONST_BITS - PASS1_BITS);
+ pTemp[5] = DESCALE(tmp12 - btmp1, CONST_BITS - PASS1_BITS);
+ pTemp[3] = DESCALE(tmp13 + btmp0, CONST_BITS - PASS1_BITS);
+ pTemp[4] = DESCALE(tmp13 - btmp0, CONST_BITS - PASS1_BITS);
+ }
+ };
+
+ template <>
+ struct Row<0>
+ {
+ static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc)
+ {
+ (void)pTemp;
+ (void)pSrc;
+ }
+ };
+
+ template <>
+ struct Row<1>
+ {
+ static void idct(int* pTemp, const jpgd_block_coeff_t* pSrc)
+ {
+ const int dcval = left_shifti(pSrc[0], PASS1_BITS);
+
+ pTemp[0] = dcval;
+ pTemp[1] = dcval;
+ pTemp[2] = dcval;
+ pTemp[3] = dcval;
+ pTemp[4] = dcval;
+ pTemp[5] = dcval;
+ pTemp[6] = dcval;
+ pTemp[7] = dcval;
+ }
+ };
+
+ // Compiler creates a fast path 1D IDCT for X non-zero rows
+ template <int NONZERO_ROWS>
+ struct Col
+ {
+ static void idct(uint8* pDst_ptr, const int* pTemp)
+ {
+ // ACCESS_ROW() will be optimized at compile time to either an array access, or 0.
+#define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0)
+
+ const int z2 = ACCESS_ROW(2);
+ const int z3 = ACCESS_ROW(6);
+
+ const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
+ const int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065);
+ const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
+
+ const int tmp0 = left_shifti(ACCESS_ROW(0) + ACCESS_ROW(4), CONST_BITS);
+ const int tmp1 = left_shifti(ACCESS_ROW(0) - ACCESS_ROW(4), CONST_BITS);
+
+ const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
+
+ const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1);
+
+ const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;
+ const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);
+
+ const int az1 = MULTIPLY(bz1, -FIX_0_899976223);
+ const int az2 = MULTIPLY(bz2, -FIX_2_562915447);
+ const int az3 = MULTIPLY(bz3, -FIX_1_961570560) + bz5;
+ const int az4 = MULTIPLY(bz4, -FIX_0_390180644) + bz5;
+
+ const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;
+ const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;
+ const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;
+ const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;
+
+ int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 0] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 7] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 1] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 6] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 2] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 5] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 3] = (uint8)CLAMP(i);
+
+ i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS + PASS1_BITS + 3);
+ pDst_ptr[8 * 4] = (uint8)CLAMP(i);
+ }
+ };
+
+ template <>
+ struct Col<1>
+ {
+ static void idct(uint8* pDst_ptr, const int* pTemp)
+ {
+ int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS + 3);
+ const uint8 dcval_clamped = (uint8)CLAMP(dcval);
+ pDst_ptr[0 * 8] = dcval_clamped;
+ pDst_ptr[1 * 8] = dcval_clamped;
+ pDst_ptr[2 * 8] = dcval_clamped;
+ pDst_ptr[3 * 8] = dcval_clamped;
+ pDst_ptr[4 * 8] = dcval_clamped;
+ pDst_ptr[5 * 8] = dcval_clamped;
+ pDst_ptr[6 * 8] = dcval_clamped;
+ pDst_ptr[7 * 8] = dcval_clamped;
+ }
+ };
+
+ static const uint8 s_idct_row_table[] =
+ {
+ 1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0,
+ 4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0,
+ 6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0,
+ 6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0,
+ 8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2,
+ 8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2,
+ 8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4,
+ 8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8,
+ };
+
+ static const uint8 s_idct_col_table[] =
+ {
+ 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
+ };
+
+ // Scalar "fast pathing" IDCT.
+ static void idct(const jpgd_block_coeff_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag, bool use_simd)
+ {
+ (void)use_simd;
+
+ assert(block_max_zag >= 1);
+ assert(block_max_zag <= 64);
+
+ if (block_max_zag <= 1)
+ {
+ int k = ((pSrc_ptr[0] + 4) >> 3) + 128;
+ k = CLAMP(k);
+ k = k | (k << 8);
+ k = k | (k << 16);
+
+ for (int i = 8; i > 0; i--)
+ {
+ *(int*)&pDst_ptr[0] = k;
+ *(int*)&pDst_ptr[4] = k;
+ pDst_ptr += 8;
+ }
+ return;
+ }
+
+#if JPGD_USE_SSE2
+ if (use_simd)
+ {
+ assert((((uintptr_t)pSrc_ptr) & 15) == 0);
+ assert((((uintptr_t)pDst_ptr) & 15) == 0);
+ idctSSEShortU8(pSrc_ptr, pDst_ptr);
+ return;
+ }
#endif
- }
-};
-
-template <>
-struct Row<1>
-{
- static void idct(int* pTemp, const jpgd_block_t* pSrc)
- {
- const int dcval = (pSrc[0] << PASS1_BITS);
-
- pTemp[0] = dcval;
- pTemp[1] = dcval;
- pTemp[2] = dcval;
- pTemp[3] = dcval;
- pTemp[4] = dcval;
- pTemp[5] = dcval;
- pTemp[6] = dcval;
- pTemp[7] = dcval;
- }
-};
-
-// Compiler creates a fast path 1D IDCT for X non-zero rows
-template <int NONZERO_ROWS>
-struct Col
-{
- static void idct(uint8* pDst_ptr, const int* pTemp)
- {
- // ACCESS_ROW() will be optimized at compile time to either an array access, or 0.
- #define ACCESS_ROW(x) (((x) < NONZERO_ROWS) ? pTemp[x * 8] : 0)
-
- const int z2 = ACCESS_ROW(2);
- const int z3 = ACCESS_ROW(6);
-
- const int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
- const int tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
- const int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
-
- const int tmp0 = (ACCESS_ROW(0) + ACCESS_ROW(4)) << CONST_BITS;
- const int tmp1 = (ACCESS_ROW(0) - ACCESS_ROW(4)) << CONST_BITS;
-
- const int tmp10 = tmp0 + tmp3, tmp13 = tmp0 - tmp3, tmp11 = tmp1 + tmp2, tmp12 = tmp1 - tmp2;
-
- const int atmp0 = ACCESS_ROW(7), atmp1 = ACCESS_ROW(5), atmp2 = ACCESS_ROW(3), atmp3 = ACCESS_ROW(1);
-
- const int bz1 = atmp0 + atmp3, bz2 = atmp1 + atmp2, bz3 = atmp0 + atmp2, bz4 = atmp1 + atmp3;
- const int bz5 = MULTIPLY(bz3 + bz4, FIX_1_175875602);
-
- const int az1 = MULTIPLY(bz1, - FIX_0_899976223);
- const int az2 = MULTIPLY(bz2, - FIX_2_562915447);
- const int az3 = MULTIPLY(bz3, - FIX_1_961570560) + bz5;
- const int az4 = MULTIPLY(bz4, - FIX_0_390180644) + bz5;
-
- const int btmp0 = MULTIPLY(atmp0, FIX_0_298631336) + az1 + az3;
- const int btmp1 = MULTIPLY(atmp1, FIX_2_053119869) + az2 + az4;
- const int btmp2 = MULTIPLY(atmp2, FIX_3_072711026) + az2 + az3;
- const int btmp3 = MULTIPLY(atmp3, FIX_1_501321110) + az1 + az4;
-
- int i = DESCALE_ZEROSHIFT(tmp10 + btmp3, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*0] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp10 - btmp3, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*7] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp11 + btmp2, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*1] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp11 - btmp2, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*6] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp12 + btmp1, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*2] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp12 - btmp1, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*5] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp13 + btmp0, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*3] = (uint8)CLAMP(i);
-
- i = DESCALE_ZEROSHIFT(tmp13 - btmp0, CONST_BITS+PASS1_BITS+3);
- pDst_ptr[8*4] = (uint8)CLAMP(i);
- }
-};
-
-template <>
-struct Col<1>
-{
- static void idct(uint8* pDst_ptr, const int* pTemp)
- {
- int dcval = DESCALE_ZEROSHIFT(pTemp[0], PASS1_BITS+3);
- const uint8 dcval_clamped = (uint8)CLAMP(dcval);
- pDst_ptr[0*8] = dcval_clamped;
- pDst_ptr[1*8] = dcval_clamped;
- pDst_ptr[2*8] = dcval_clamped;
- pDst_ptr[3*8] = dcval_clamped;
- pDst_ptr[4*8] = dcval_clamped;
- pDst_ptr[5*8] = dcval_clamped;
- pDst_ptr[6*8] = dcval_clamped;
- pDst_ptr[7*8] = dcval_clamped;
- }
-};
-
-static const uint8 s_idct_row_table[] =
-{
- 1,0,0,0,0,0,0,0, 2,0,0,0,0,0,0,0, 2,1,0,0,0,0,0,0, 2,1,1,0,0,0,0,0, 2,2,1,0,0,0,0,0, 3,2,1,0,0,0,0,0, 4,2,1,0,0,0,0,0, 4,3,1,0,0,0,0,0,
- 4,3,2,0,0,0,0,0, 4,3,2,1,0,0,0,0, 4,3,2,1,1,0,0,0, 4,3,2,2,1,0,0,0, 4,3,3,2,1,0,0,0, 4,4,3,2,1,0,0,0, 5,4,3,2,1,0,0,0, 6,4,3,2,1,0,0,0,
- 6,5,3,2,1,0,0,0, 6,5,4,2,1,0,0,0, 6,5,4,3,1,0,0,0, 6,5,4,3,2,0,0,0, 6,5,4,3,2,1,0,0, 6,5,4,3,2,1,1,0, 6,5,4,3,2,2,1,0, 6,5,4,3,3,2,1,0,
- 6,5,4,4,3,2,1,0, 6,5,5,4,3,2,1,0, 6,6,5,4,3,2,1,0, 7,6,5,4,3,2,1,0, 8,6,5,4,3,2,1,0, 8,7,5,4,3,2,1,0, 8,7,6,4,3,2,1,0, 8,7,6,5,3,2,1,0,
- 8,7,6,5,4,2,1,0, 8,7,6,5,4,3,1,0, 8,7,6,5,4,3,2,0, 8,7,6,5,4,3,2,1, 8,7,6,5,4,3,2,2, 8,7,6,5,4,3,3,2, 8,7,6,5,4,4,3,2, 8,7,6,5,5,4,3,2,
- 8,7,6,6,5,4,3,2, 8,7,7,6,5,4,3,2, 8,8,7,6,5,4,3,2, 8,8,8,6,5,4,3,2, 8,8,8,7,5,4,3,2, 8,8,8,7,6,4,3,2, 8,8,8,7,6,5,3,2, 8,8,8,7,6,5,4,2,
- 8,8,8,7,6,5,4,3, 8,8,8,7,6,5,4,4, 8,8,8,7,6,5,5,4, 8,8,8,7,6,6,5,4, 8,8,8,7,7,6,5,4, 8,8,8,8,7,6,5,4, 8,8,8,8,8,6,5,4, 8,8,8,8,8,7,5,4,
- 8,8,8,8,8,7,6,4, 8,8,8,8,8,7,6,5, 8,8,8,8,8,7,6,6, 8,8,8,8,8,7,7,6, 8,8,8,8,8,8,7,6, 8,8,8,8,8,8,8,6, 8,8,8,8,8,8,8,7, 8,8,8,8,8,8,8,8,
-};
-
-static const uint8 s_idct_col_table[] = { 1, 1, 2, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 };
-
-void idct(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr, int block_max_zag)
-{
- JPGD_ASSERT(block_max_zag >= 1);
- JPGD_ASSERT(block_max_zag <= 64);
-
- if (block_max_zag <= 1)
- {
- int k = ((pSrc_ptr[0] + 4) >> 3) + 128;
- k = CLAMP(k);
- k = k | (k<<8);
- k = k | (k<<16);
-
- for (int i = 8; i > 0; i--)
- {
- *(int*)&pDst_ptr[0] = k;
- *(int*)&pDst_ptr[4] = k;
- pDst_ptr += 8;
- }
- return;
- }
-
- int temp[64];
-
- const jpgd_block_t* pSrc = pSrc_ptr;
- int* pTemp = temp;
-
- const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8];
- int i;
- for (i = 8; i > 0; i--, pRow_tab++)
- {
- switch (*pRow_tab)
- {
- case 0: Row<0>::idct(pTemp, pSrc); break;
- case 1: Row<1>::idct(pTemp, pSrc); break;
- case 2: Row<2>::idct(pTemp, pSrc); break;
- case 3: Row<3>::idct(pTemp, pSrc); break;
- case 4: Row<4>::idct(pTemp, pSrc); break;
- case 5: Row<5>::idct(pTemp, pSrc); break;
- case 6: Row<6>::idct(pTemp, pSrc); break;
- case 7: Row<7>::idct(pTemp, pSrc); break;
- case 8: Row<8>::idct(pTemp, pSrc); break;
- }
-
- pSrc += 8;
- pTemp += 8;
- }
-
- pTemp = temp;
-
- const int nonzero_rows = s_idct_col_table[block_max_zag - 1];
- for (i = 8; i > 0; i--)
- {
- switch (nonzero_rows)
- {
- case 1: Col<1>::idct(pDst_ptr, pTemp); break;
- case 2: Col<2>::idct(pDst_ptr, pTemp); break;
- case 3: Col<3>::idct(pDst_ptr, pTemp); break;
- case 4: Col<4>::idct(pDst_ptr, pTemp); break;
- case 5: Col<5>::idct(pDst_ptr, pTemp); break;
- case 6: Col<6>::idct(pDst_ptr, pTemp); break;
- case 7: Col<7>::idct(pDst_ptr, pTemp); break;
- case 8: Col<8>::idct(pDst_ptr, pTemp); break;
- }
-
- pTemp++;
- pDst_ptr++;
- }
-}
-
-void idct_4x4(const jpgd_block_t* pSrc_ptr, uint8* pDst_ptr)
-{
- int temp[64];
- int* pTemp = temp;
- const jpgd_block_t* pSrc = pSrc_ptr;
-
- for (int i = 4; i > 0; i--)
- {
- Row<4>::idct(pTemp, pSrc);
- pSrc += 8;
- pTemp += 8;
- }
-
- pTemp = temp;
- for (int i = 8; i > 0; i--)
- {
- Col<4>::idct(pDst_ptr, pTemp);
- pTemp++;
- pDst_ptr++;
- }
-}
-
-// Retrieve one character from the input stream.
-inline uint jpeg_decoder::get_char()
-{
- // Any bytes remaining in buffer?
- if (!m_in_buf_left)
- {
- // Try to get more bytes.
- prep_in_buffer();
- // Still nothing to get?
- if (!m_in_buf_left)
- {
- // Pad the end of the stream with 0xFF 0xD9 (EOI marker)
- int t = m_tem_flag;
- m_tem_flag ^= 1;
- if (t)
- return 0xD9;
- else
- return 0xFF;
- }
- }
-
- uint c = *m_pIn_buf_ofs++;
- m_in_buf_left--;
-
- return c;
-}
-
-// Same as previous method, except can indicate if the character is a pad character or not.
-inline uint jpeg_decoder::get_char(bool *pPadding_flag)
-{
- if (!m_in_buf_left)
- {
- prep_in_buffer();
- if (!m_in_buf_left)
- {
- *pPadding_flag = true;
- int t = m_tem_flag;
- m_tem_flag ^= 1;
- if (t)
- return 0xD9;
- else
- return 0xFF;
- }
- }
-
- *pPadding_flag = false;
-
- uint c = *m_pIn_buf_ofs++;
- m_in_buf_left--;
-
- return c;
-}
-
-// Inserts a previously retrieved character back into the input buffer.
-inline void jpeg_decoder::stuff_char(uint8 q)
-{
- *(--m_pIn_buf_ofs) = q;
- m_in_buf_left++;
-}
-
-// Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered.
-inline uint8 jpeg_decoder::get_octet()
-{
- bool padding_flag;
- int c = get_char(&padding_flag);
-
- if (c == 0xFF)
- {
- if (padding_flag)
- return 0xFF;
-
- c = get_char(&padding_flag);
- if (padding_flag)
- {
- stuff_char(0xFF);
- return 0xFF;
- }
-
- if (c == 0x00)
- return 0xFF;
- else
- {
- stuff_char(static_cast<uint8>(c));
- stuff_char(0xFF);
- return 0xFF;
- }
- }
-
- return static_cast<uint8>(c);
-}
-
-// Retrieves a variable number of bits from the input stream. Does not recognize markers.
-inline uint jpeg_decoder::get_bits(int num_bits)
-{
- if (!num_bits)
- return 0;
-
- uint i = m_bit_buf >> (32 - num_bits);
-
- if ((m_bits_left -= num_bits) <= 0)
- {
- m_bit_buf <<= (num_bits += m_bits_left);
-
- uint c1 = get_char();
- uint c2 = get_char();
- m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2;
-
- m_bit_buf <<= -m_bits_left;
-
- m_bits_left += 16;
-
- JPGD_ASSERT(m_bits_left >= 0);
- }
- else
- m_bit_buf <<= num_bits;
-
- return i;
-}
-
-// Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered.
-inline uint jpeg_decoder::get_bits_no_markers(int num_bits)
-{
- if (!num_bits)
- return 0;
-
- uint i = m_bit_buf >> (32 - num_bits);
-
- if ((m_bits_left -= num_bits) <= 0)
- {
- m_bit_buf <<= (num_bits += m_bits_left);
-
- if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF))
- {
- uint c1 = get_octet();
- uint c2 = get_octet();
- m_bit_buf |= (c1 << 8) | c2;
- }
- else
- {
- m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1];
- m_in_buf_left -= 2;
- m_pIn_buf_ofs += 2;
- }
-
- m_bit_buf <<= -m_bits_left;
-
- m_bits_left += 16;
-
- JPGD_ASSERT(m_bits_left >= 0);
- }
- else
- m_bit_buf <<= num_bits;
-
- return i;
-}
-
-// Decodes a Huffman encoded symbol.
-inline int jpeg_decoder::huff_decode(huff_tables *pH)
-{
- JPGD_ASSERT(pH);
-
- int symbol;
- // Check first 8-bits: do we have a complete symbol?
- if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0)
- {
- // Decode more bits, use a tree traversal to find symbol.
- int ofs = 23;
- do
- {
- unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
- JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
- symbol = pH->tree[idx];
- ofs--;
- } while (symbol < 0);
-
- get_bits_no_markers(8 + (23 - ofs));
- }
- else
- {
- JPGD_ASSERT(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
- get_bits_no_markers(pH->code_size[symbol]);
- }
-
- return symbol;
-}
-
-// Decodes a Huffman encoded symbol.
-inline int jpeg_decoder::huff_decode(huff_tables *pH, int& extra_bits)
-{
- int symbol;
-
- JPGD_ASSERT(pH);
-
- // Check first 8-bits: do we have a complete symbol?
- if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0)
- {
- // Use a tree traversal to find symbol.
- int ofs = 23;
- do
- {
- unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
- JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
- symbol = pH->tree[idx];
- ofs--;
- } while (symbol < 0);
-
- get_bits_no_markers(8 + (23 - ofs));
-
- extra_bits = get_bits_no_markers(symbol & 0xF);
- }
- else
- {
- JPGD_ASSERT(((symbol >> 8) & 31) == pH->code_size[symbol & 255] + ((symbol & 0x8000) ? (symbol & 15) : 0));
-
- if (symbol & 0x8000)
- {
- get_bits_no_markers((symbol >> 8) & 31);
- extra_bits = symbol >> 16;
- }
- else
- {
- int code_size = (symbol >> 8) & 31;
- int num_extra_bits = symbol & 0xF;
- int bits = code_size + num_extra_bits;
- if (bits <= (m_bits_left + 16))
- extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1);
- else
- {
- get_bits_no_markers(code_size);
- extra_bits = get_bits_no_markers(num_extra_bits);
- }
- }
-
- symbol &= 0xFF;
- }
-
- return symbol;
-}
-
-// Tables and macro used to fully decode the DPCM differences.
-static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
-static const int s_extend_offset[16] = { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1, ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1, ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1, ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
-static const int s_extend_mask[] = { 0, (1<<0), (1<<1), (1<<2), (1<<3), (1<<4), (1<<5), (1<<6), (1<<7), (1<<8), (1<<9), (1<<10), (1<<11), (1<<12), (1<<13), (1<<14), (1<<15), (1<<16) };
-// The logical AND's in this macro are to shut up static code analysis (aren't really necessary - couldn't find another way to do this)
+
+ int temp[64];
+
+ const jpgd_block_coeff_t* pSrc = pSrc_ptr;
+ int* pTemp = temp;
+
+ const uint8* pRow_tab = &s_idct_row_table[(block_max_zag - 1) * 8];
+ int i;
+ for (i = 8; i > 0; i--, pRow_tab++)
+ {
+ switch (*pRow_tab)
+ {
+ case 0: Row<0>::idct(pTemp, pSrc); break;
+ case 1: Row<1>::idct(pTemp, pSrc); break;
+ case 2: Row<2>::idct(pTemp, pSrc); break;
+ case 3: Row<3>::idct(pTemp, pSrc); break;
+ case 4: Row<4>::idct(pTemp, pSrc); break;
+ case 5: Row<5>::idct(pTemp, pSrc); break;
+ case 6: Row<6>::idct(pTemp, pSrc); break;
+ case 7: Row<7>::idct(pTemp, pSrc); break;
+ case 8: Row<8>::idct(pTemp, pSrc); break;
+ }
+
+ pSrc += 8;
+ pTemp += 8;
+ }
+
+ pTemp = temp;
+
+ const int nonzero_rows = s_idct_col_table[block_max_zag - 1];
+ for (i = 8; i > 0; i--)
+ {
+ switch (nonzero_rows)
+ {
+ case 1: Col<1>::idct(pDst_ptr, pTemp); break;
+ case 2: Col<2>::idct(pDst_ptr, pTemp); break;
+ case 3: Col<3>::idct(pDst_ptr, pTemp); break;
+ case 4: Col<4>::idct(pDst_ptr, pTemp); break;
+ case 5: Col<5>::idct(pDst_ptr, pTemp); break;
+ case 6: Col<6>::idct(pDst_ptr, pTemp); break;
+ case 7: Col<7>::idct(pDst_ptr, pTemp); break;
+ case 8: Col<8>::idct(pDst_ptr, pTemp); break;
+ }
+
+ pTemp++;
+ pDst_ptr++;
+ }
+ }
+
+ // Retrieve one character from the input stream.
+ inline uint jpeg_decoder::get_char()
+ {
+ // Any bytes remaining in buffer?
+ if (!m_in_buf_left)
+ {
+ // Try to get more bytes.
+ prep_in_buffer();
+ // Still nothing to get?
+ if (!m_in_buf_left)
+ {
+ // Pad the end of the stream with 0xFF 0xD9 (EOI marker)
+ int t = m_tem_flag;
+ m_tem_flag ^= 1;
+ if (t)
+ return 0xD9;
+ else
+ return 0xFF;
+ }
+ }
+
+ uint c = *m_pIn_buf_ofs++;
+ m_in_buf_left--;
+
+ return c;
+ }
+
+ // Same as previous method, except can indicate if the character is a pad character or not.
+ inline uint jpeg_decoder::get_char(bool* pPadding_flag)
+ {
+ if (!m_in_buf_left)
+ {
+ prep_in_buffer();
+ if (!m_in_buf_left)
+ {
+ *pPadding_flag = true;
+ int t = m_tem_flag;
+ m_tem_flag ^= 1;
+ if (t)
+ return 0xD9;
+ else
+ return 0xFF;
+ }
+ }
+
+ *pPadding_flag = false;
+
+ uint c = *m_pIn_buf_ofs++;
+ m_in_buf_left--;
+
+ return c;
+ }
+
+ // Inserts a previously retrieved character back into the input buffer.
+ inline void jpeg_decoder::stuff_char(uint8 q)
+ {
+ // This could write before the input buffer, but we've placed another array there.
+ *(--m_pIn_buf_ofs) = q;
+ m_in_buf_left++;
+ }
+
+ // Retrieves one character from the input stream, but does not read past markers. Will continue to return 0xFF when a marker is encountered.
+ inline uint8 jpeg_decoder::get_octet()
+ {
+ bool padding_flag;
+ int c = get_char(&padding_flag);
+
+ if (c == 0xFF)
+ {
+ if (padding_flag)
+ return 0xFF;
+
+ c = get_char(&padding_flag);
+ if (padding_flag)
+ {
+ stuff_char(0xFF);
+ return 0xFF;
+ }
+
+ if (c == 0x00)
+ return 0xFF;
+ else
+ {
+ stuff_char(static_cast<uint8>(c));
+ stuff_char(0xFF);
+ return 0xFF;
+ }
+ }
+
+ return static_cast<uint8>(c);
+ }
+
+ // Retrieves a variable number of bits from the input stream. Does not recognize markers.
+ inline uint jpeg_decoder::get_bits(int num_bits)
+ {
+ if (!num_bits)
+ return 0;
+
+ uint i = m_bit_buf >> (32 - num_bits);
+
+ if ((m_bits_left -= num_bits) <= 0)
+ {
+ m_bit_buf <<= (num_bits += m_bits_left);
+
+ uint c1 = get_char();
+ uint c2 = get_char();
+ m_bit_buf = (m_bit_buf & 0xFFFF0000) | (c1 << 8) | c2;
+
+ m_bit_buf <<= -m_bits_left;
+
+ m_bits_left += 16;
+
+ assert(m_bits_left >= 0);
+ }
+ else
+ m_bit_buf <<= num_bits;
+
+ return i;
+ }
+
+ // Retrieves a variable number of bits from the input stream. Markers will not be read into the input bit buffer. Instead, an infinite number of all 1's will be returned when a marker is encountered.
+ inline uint jpeg_decoder::get_bits_no_markers(int num_bits)
+ {
+ if (!num_bits)
+ return 0;
+
+ assert(num_bits <= 16);
+
+ uint i = m_bit_buf >> (32 - num_bits);
+
+ if ((m_bits_left -= num_bits) <= 0)
+ {
+ m_bit_buf <<= (num_bits += m_bits_left);
+
+ if ((m_in_buf_left < 2) || (m_pIn_buf_ofs[0] == 0xFF) || (m_pIn_buf_ofs[1] == 0xFF))
+ {
+ uint c1 = get_octet();
+ uint c2 = get_octet();
+ m_bit_buf |= (c1 << 8) | c2;
+ }
+ else
+ {
+ m_bit_buf |= ((uint)m_pIn_buf_ofs[0] << 8) | m_pIn_buf_ofs[1];
+ m_in_buf_left -= 2;
+ m_pIn_buf_ofs += 2;
+ }
+
+ m_bit_buf <<= -m_bits_left;
+
+ m_bits_left += 16;
+
+ assert(m_bits_left >= 0);
+ }
+ else
+ m_bit_buf <<= num_bits;
+
+ return i;
+ }
+
+ // Decodes a Huffman encoded symbol.
+ inline int jpeg_decoder::huff_decode(huff_tables* pH)
+ {
+ if (!pH)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ int symbol;
+ // Check first 8-bits: do we have a complete symbol?
+ if ((symbol = pH->look_up[m_bit_buf >> 24]) < 0)
+ {
+ // Decode more bits, use a tree traversal to find symbol.
+ int ofs = 23;
+ do
+ {
+ unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
+
+ // This should never happen, but to be safe I'm turning these asserts into a run-time check.
+ if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0))
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ symbol = pH->tree[idx];
+ ofs--;
+ } while (symbol < 0);
+
+ get_bits_no_markers(8 + (23 - ofs));
+ }
+ else
+ {
+ assert(symbol < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
+ get_bits_no_markers(pH->code_size[symbol]);
+ }
+
+ return symbol;
+ }
+
+ // Decodes a Huffman encoded symbol.
+ inline int jpeg_decoder::huff_decode(huff_tables* pH, int& extra_bits)
+ {
+ int symbol;
+
+ if (!pH)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ // Check first 8-bits: do we have a complete symbol?
+ if ((symbol = pH->look_up2[m_bit_buf >> 24]) < 0)
+ {
+ // Use a tree traversal to find symbol.
+ int ofs = 23;
+ do
+ {
+ unsigned int idx = -(int)(symbol + ((m_bit_buf >> ofs) & 1));
+
+ // This should never happen, but to be safe I'm turning these asserts into a run-time check.
+ if ((idx >= JPGD_HUFF_TREE_MAX_LENGTH) || (ofs < 0))
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ symbol = pH->tree[idx];
+ ofs--;
+ } while (symbol < 0);
+
+ get_bits_no_markers(8 + (23 - ofs));
+
+ extra_bits = get_bits_no_markers(symbol & 0xF);
+ }
+ else
+ {
+ if (symbol & 0x8000)
+ {
+ //get_bits_no_markers((symbol >> 8) & 31);
+ assert(((symbol >> 8) & 31) <= 15);
+ get_bits_no_markers((symbol >> 8) & 15);
+ extra_bits = symbol >> 16;
+ }
+ else
+ {
+ int code_size = (symbol >> 8) & 31;
+ int num_extra_bits = symbol & 0xF;
+ int bits = code_size + num_extra_bits;
+
+ if (bits <= 16)
+ extra_bits = get_bits_no_markers(bits) & ((1 << num_extra_bits) - 1);
+ else
+ {
+ get_bits_no_markers(code_size);
+ extra_bits = get_bits_no_markers(num_extra_bits);
+ }
+ }
+
+ symbol &= 0xFF;
+ }
+
+ return symbol;
+ }
+
+ // Tables and macro used to fully decode the DPCM differences.
+ static const int s_extend_test[16] = { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
+ static const int s_extend_offset[16] = { 0, -1, -3, -7, -15, -31, -63, -127, -255, -511, -1023, -2047, -4095, -8191, -16383, -32767 };
+ //static const int s_extend_mask[] = { 0, (1 << 0), (1 << 1), (1 << 2), (1 << 3), (1 << 4), (1 << 5), (1 << 6), (1 << 7), (1 << 8), (1 << 9), (1 << 10), (1 << 11), (1 << 12), (1 << 13), (1 << 14), (1 << 15), (1 << 16) };
+
#define JPGD_HUFF_EXTEND(x, s) (((x) < s_extend_test[s & 15]) ? ((x) + s_extend_offset[s & 15]) : (x))
-// Clamps a value between 0-255.
-inline uint8 jpeg_decoder::clamp(int i)
-{
- if (static_cast<uint>(i) > 255)
- i = (((~i) >> 31) & 0xFF);
-
- return static_cast<uint8>(i);
-}
-
-namespace DCT_Upsample
-{
- struct Matrix44
- {
- typedef int Element_Type;
- enum { NUM_ROWS = 4, NUM_COLS = 4 };
-
- Element_Type v[NUM_ROWS][NUM_COLS];
-
- inline int rows() const { return NUM_ROWS; }
- inline int cols() const { return NUM_COLS; }
-
- inline const Element_Type & at(int r, int c) const { return v[r][c]; }
- inline Element_Type & at(int r, int c) { return v[r][c]; }
-
- inline Matrix44() { }
-
- inline Matrix44& operator += (const Matrix44& a)
- {
- for (int r = 0; r < NUM_ROWS; r++)
- {
- at(r, 0) += a.at(r, 0);
- at(r, 1) += a.at(r, 1);
- at(r, 2) += a.at(r, 2);
- at(r, 3) += a.at(r, 3);
- }
- return *this;
- }
-
- inline Matrix44& operator -= (const Matrix44& a)
- {
- for (int r = 0; r < NUM_ROWS; r++)
- {
- at(r, 0) -= a.at(r, 0);
- at(r, 1) -= a.at(r, 1);
- at(r, 2) -= a.at(r, 2);
- at(r, 3) -= a.at(r, 3);
- }
- return *this;
- }
-
- friend inline Matrix44 operator + (const Matrix44& a, const Matrix44& b)
- {
- Matrix44 ret;
- for (int r = 0; r < NUM_ROWS; r++)
- {
- ret.at(r, 0) = a.at(r, 0) + b.at(r, 0);
- ret.at(r, 1) = a.at(r, 1) + b.at(r, 1);
- ret.at(r, 2) = a.at(r, 2) + b.at(r, 2);
- ret.at(r, 3) = a.at(r, 3) + b.at(r, 3);
- }
- return ret;
- }
-
- friend inline Matrix44 operator - (const Matrix44& a, const Matrix44& b)
- {
- Matrix44 ret;
- for (int r = 0; r < NUM_ROWS; r++)
- {
- ret.at(r, 0) = a.at(r, 0) - b.at(r, 0);
- ret.at(r, 1) = a.at(r, 1) - b.at(r, 1);
- ret.at(r, 2) = a.at(r, 2) - b.at(r, 2);
- ret.at(r, 3) = a.at(r, 3) - b.at(r, 3);
- }
- return ret;
- }
-
- static inline void add_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b)
- {
- for (int r = 0; r < 4; r++)
- {
- pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) + b.at(r, 0));
- pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) + b.at(r, 1));
- pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) + b.at(r, 2));
- pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) + b.at(r, 3));
- }
- }
-
- static inline void sub_and_store(jpgd_block_t* pDst, const Matrix44& a, const Matrix44& b)
- {
- for (int r = 0; r < 4; r++)
- {
- pDst[0*8 + r] = static_cast<jpgd_block_t>(a.at(r, 0) - b.at(r, 0));
- pDst[1*8 + r] = static_cast<jpgd_block_t>(a.at(r, 1) - b.at(r, 1));
- pDst[2*8 + r] = static_cast<jpgd_block_t>(a.at(r, 2) - b.at(r, 2));
- pDst[3*8 + r] = static_cast<jpgd_block_t>(a.at(r, 3) - b.at(r, 3));
- }
- }
- };
-
- const int FRACT_BITS = 10;
- const int SCALE = 1 << FRACT_BITS;
-
- typedef int Temp_Type;
- #define D(i) (((i) + (SCALE >> 1)) >> FRACT_BITS)
- #define F(i) ((int)((i) * SCALE + .5f))
-
- // Any decent C++ compiler will optimize this at compile time to a 0, or an array access.
- #define AT(c, r) ((((c)>=NUM_COLS)||((r)>=NUM_ROWS)) ? 0 : pSrc[(c)+(r)*8])
-
- // NUM_ROWS/NUM_COLS = # of non-zero rows/cols in input matrix
- template<int NUM_ROWS, int NUM_COLS>
- struct P_Q
- {
- static void calc(Matrix44& P, Matrix44& Q, const jpgd_block_t* pSrc)
- {
- // 4x8 = 4x8 times 8x8, matrix 0 is constant
- const Temp_Type X000 = AT(0, 0);
- const Temp_Type X001 = AT(0, 1);
- const Temp_Type X002 = AT(0, 2);
- const Temp_Type X003 = AT(0, 3);
- const Temp_Type X004 = AT(0, 4);
- const Temp_Type X005 = AT(0, 5);
- const Temp_Type X006 = AT(0, 6);
- const Temp_Type X007 = AT(0, 7);
- const Temp_Type X010 = D(F(0.415735f) * AT(1, 0) + F(0.791065f) * AT(3, 0) + F(-0.352443f) * AT(5, 0) + F(0.277785f) * AT(7, 0));
- const Temp_Type X011 = D(F(0.415735f) * AT(1, 1) + F(0.791065f) * AT(3, 1) + F(-0.352443f) * AT(5, 1) + F(0.277785f) * AT(7, 1));
- const Temp_Type X012 = D(F(0.415735f) * AT(1, 2) + F(0.791065f) * AT(3, 2) + F(-0.352443f) * AT(5, 2) + F(0.277785f) * AT(7, 2));
- const Temp_Type X013 = D(F(0.415735f) * AT(1, 3) + F(0.791065f) * AT(3, 3) + F(-0.352443f) * AT(5, 3) + F(0.277785f) * AT(7, 3));
- const Temp_Type X014 = D(F(0.415735f) * AT(1, 4) + F(0.791065f) * AT(3, 4) + F(-0.352443f) * AT(5, 4) + F(0.277785f) * AT(7, 4));
- const Temp_Type X015 = D(F(0.415735f) * AT(1, 5) + F(0.791065f) * AT(3, 5) + F(-0.352443f) * AT(5, 5) + F(0.277785f) * AT(7, 5));
- const Temp_Type X016 = D(F(0.415735f) * AT(1, 6) + F(0.791065f) * AT(3, 6) + F(-0.352443f) * AT(5, 6) + F(0.277785f) * AT(7, 6));
- const Temp_Type X017 = D(F(0.415735f) * AT(1, 7) + F(0.791065f) * AT(3, 7) + F(-0.352443f) * AT(5, 7) + F(0.277785f) * AT(7, 7));
- const Temp_Type X020 = AT(4, 0);
- const Temp_Type X021 = AT(4, 1);
- const Temp_Type X022 = AT(4, 2);
- const Temp_Type X023 = AT(4, 3);
- const Temp_Type X024 = AT(4, 4);
- const Temp_Type X025 = AT(4, 5);
- const Temp_Type X026 = AT(4, 6);
- const Temp_Type X027 = AT(4, 7);
- const Temp_Type X030 = D(F(0.022887f) * AT(1, 0) + F(-0.097545f) * AT(3, 0) + F(0.490393f) * AT(5, 0) + F(0.865723f) * AT(7, 0));
- const Temp_Type X031 = D(F(0.022887f) * AT(1, 1) + F(-0.097545f) * AT(3, 1) + F(0.490393f) * AT(5, 1) + F(0.865723f) * AT(7, 1));
- const Temp_Type X032 = D(F(0.022887f) * AT(1, 2) + F(-0.097545f) * AT(3, 2) + F(0.490393f) * AT(5, 2) + F(0.865723f) * AT(7, 2));
- const Temp_Type X033 = D(F(0.022887f) * AT(1, 3) + F(-0.097545f) * AT(3, 3) + F(0.490393f) * AT(5, 3) + F(0.865723f) * AT(7, 3));
- const Temp_Type X034 = D(F(0.022887f) * AT(1, 4) + F(-0.097545f) * AT(3, 4) + F(0.490393f) * AT(5, 4) + F(0.865723f) * AT(7, 4));
- const Temp_Type X035 = D(F(0.022887f) * AT(1, 5) + F(-0.097545f) * AT(3, 5) + F(0.490393f) * AT(5, 5) + F(0.865723f) * AT(7, 5));
- const Temp_Type X036 = D(F(0.022887f) * AT(1, 6) + F(-0.097545f) * AT(3, 6) + F(0.490393f) * AT(5, 6) + F(0.865723f) * AT(7, 6));
- const Temp_Type X037 = D(F(0.022887f) * AT(1, 7) + F(-0.097545f) * AT(3, 7) + F(0.490393f) * AT(5, 7) + F(0.865723f) * AT(7, 7));
-
- // 4x4 = 4x8 times 8x4, matrix 1 is constant
- P.at(0, 0) = X000;
- P.at(0, 1) = D(X001 * F(0.415735f) + X003 * F(0.791065f) + X005 * F(-0.352443f) + X007 * F(0.277785f));
- P.at(0, 2) = X004;
- P.at(0, 3) = D(X001 * F(0.022887f) + X003 * F(-0.097545f) + X005 * F(0.490393f) + X007 * F(0.865723f));
- P.at(1, 0) = X010;
- P.at(1, 1) = D(X011 * F(0.415735f) + X013 * F(0.791065f) + X015 * F(-0.352443f) + X017 * F(0.277785f));
- P.at(1, 2) = X014;
- P.at(1, 3) = D(X011 * F(0.022887f) + X013 * F(-0.097545f) + X015 * F(0.490393f) + X017 * F(0.865723f));
- P.at(2, 0) = X020;
- P.at(2, 1) = D(X021 * F(0.415735f) + X023 * F(0.791065f) + X025 * F(-0.352443f) + X027 * F(0.277785f));
- P.at(2, 2) = X024;
- P.at(2, 3) = D(X021 * F(0.022887f) + X023 * F(-0.097545f) + X025 * F(0.490393f) + X027 * F(0.865723f));
- P.at(3, 0) = X030;
- P.at(3, 1) = D(X031 * F(0.415735f) + X033 * F(0.791065f) + X035 * F(-0.352443f) + X037 * F(0.277785f));
- P.at(3, 2) = X034;
- P.at(3, 3) = D(X031 * F(0.022887f) + X033 * F(-0.097545f) + X035 * F(0.490393f) + X037 * F(0.865723f));
- // 40 muls 24 adds
-
- // 4x4 = 4x8 times 8x4, matrix 1 is constant
- Q.at(0, 0) = D(X001 * F(0.906127f) + X003 * F(-0.318190f) + X005 * F(0.212608f) + X007 * F(-0.180240f));
- Q.at(0, 1) = X002;
- Q.at(0, 2) = D(X001 * F(-0.074658f) + X003 * F(0.513280f) + X005 * F(0.768178f) + X007 * F(-0.375330f));
- Q.at(0, 3) = X006;
- Q.at(1, 0) = D(X011 * F(0.906127f) + X013 * F(-0.318190f) + X015 * F(0.212608f) + X017 * F(-0.180240f));
- Q.at(1, 1) = X012;
- Q.at(1, 2) = D(X011 * F(-0.074658f) + X013 * F(0.513280f) + X015 * F(0.768178f) + X017 * F(-0.375330f));
- Q.at(1, 3) = X016;
- Q.at(2, 0) = D(X021 * F(0.906127f) + X023 * F(-0.318190f) + X025 * F(0.212608f) + X027 * F(-0.180240f));
- Q.at(2, 1) = X022;
- Q.at(2, 2) = D(X021 * F(-0.074658f) + X023 * F(0.513280f) + X025 * F(0.768178f) + X027 * F(-0.375330f));
- Q.at(2, 3) = X026;
- Q.at(3, 0) = D(X031 * F(0.906127f) + X033 * F(-0.318190f) + X035 * F(0.212608f) + X037 * F(-0.180240f));
- Q.at(3, 1) = X032;
- Q.at(3, 2) = D(X031 * F(-0.074658f) + X033 * F(0.513280f) + X035 * F(0.768178f) + X037 * F(-0.375330f));
- Q.at(3, 3) = X036;
- // 40 muls 24 adds
- }
- };
-
- template<int NUM_ROWS, int NUM_COLS>
- struct R_S
- {
- static void calc(Matrix44& R, Matrix44& S, const jpgd_block_t* pSrc)
- {
- // 4x8 = 4x8 times 8x8, matrix 0 is constant
- const Temp_Type X100 = D(F(0.906127f) * AT(1, 0) + F(-0.318190f) * AT(3, 0) + F(0.212608f) * AT(5, 0) + F(-0.180240f) * AT(7, 0));
- const Temp_Type X101 = D(F(0.906127f) * AT(1, 1) + F(-0.318190f) * AT(3, 1) + F(0.212608f) * AT(5, 1) + F(-0.180240f) * AT(7, 1));
- const Temp_Type X102 = D(F(0.906127f) * AT(1, 2) + F(-0.318190f) * AT(3, 2) + F(0.212608f) * AT(5, 2) + F(-0.180240f) * AT(7, 2));
- const Temp_Type X103 = D(F(0.906127f) * AT(1, 3) + F(-0.318190f) * AT(3, 3) + F(0.212608f) * AT(5, 3) + F(-0.180240f) * AT(7, 3));
- const Temp_Type X104 = D(F(0.906127f) * AT(1, 4) + F(-0.318190f) * AT(3, 4) + F(0.212608f) * AT(5, 4) + F(-0.180240f) * AT(7, 4));
- const Temp_Type X105 = D(F(0.906127f) * AT(1, 5) + F(-0.318190f) * AT(3, 5) + F(0.212608f) * AT(5, 5) + F(-0.180240f) * AT(7, 5));
- const Temp_Type X106 = D(F(0.906127f) * AT(1, 6) + F(-0.318190f) * AT(3, 6) + F(0.212608f) * AT(5, 6) + F(-0.180240f) * AT(7, 6));
- const Temp_Type X107 = D(F(0.906127f) * AT(1, 7) + F(-0.318190f) * AT(3, 7) + F(0.212608f) * AT(5, 7) + F(-0.180240f) * AT(7, 7));
- const Temp_Type X110 = AT(2, 0);
- const Temp_Type X111 = AT(2, 1);
- const Temp_Type X112 = AT(2, 2);
- const Temp_Type X113 = AT(2, 3);
- const Temp_Type X114 = AT(2, 4);
- const Temp_Type X115 = AT(2, 5);
- const Temp_Type X116 = AT(2, 6);
- const Temp_Type X117 = AT(2, 7);
- const Temp_Type X120 = D(F(-0.074658f) * AT(1, 0) + F(0.513280f) * AT(3, 0) + F(0.768178f) * AT(5, 0) + F(-0.375330f) * AT(7, 0));
- const Temp_Type X121 = D(F(-0.074658f) * AT(1, 1) + F(0.513280f) * AT(3, 1) + F(0.768178f) * AT(5, 1) + F(-0.375330f) * AT(7, 1));
- const Temp_Type X122 = D(F(-0.074658f) * AT(1, 2) + F(0.513280f) * AT(3, 2) + F(0.768178f) * AT(5, 2) + F(-0.375330f) * AT(7, 2));
- const Temp_Type X123 = D(F(-0.074658f) * AT(1, 3) + F(0.513280f) * AT(3, 3) + F(0.768178f) * AT(5, 3) + F(-0.375330f) * AT(7, 3));
- const Temp_Type X124 = D(F(-0.074658f) * AT(1, 4) + F(0.513280f) * AT(3, 4) + F(0.768178f) * AT(5, 4) + F(-0.375330f) * AT(7, 4));
- const Temp_Type X125 = D(F(-0.074658f) * AT(1, 5) + F(0.513280f) * AT(3, 5) + F(0.768178f) * AT(5, 5) + F(-0.375330f) * AT(7, 5));
- const Temp_Type X126 = D(F(-0.074658f) * AT(1, 6) + F(0.513280f) * AT(3, 6) + F(0.768178f) * AT(5, 6) + F(-0.375330f) * AT(7, 6));
- const Temp_Type X127 = D(F(-0.074658f) * AT(1, 7) + F(0.513280f) * AT(3, 7) + F(0.768178f) * AT(5, 7) + F(-0.375330f) * AT(7, 7));
- const Temp_Type X130 = AT(6, 0);
- const Temp_Type X131 = AT(6, 1);
- const Temp_Type X132 = AT(6, 2);
- const Temp_Type X133 = AT(6, 3);
- const Temp_Type X134 = AT(6, 4);
- const Temp_Type X135 = AT(6, 5);
- const Temp_Type X136 = AT(6, 6);
- const Temp_Type X137 = AT(6, 7);
- // 80 muls 48 adds
-
- // 4x4 = 4x8 times 8x4, matrix 1 is constant
- R.at(0, 0) = X100;
- R.at(0, 1) = D(X101 * F(0.415735f) + X103 * F(0.791065f) + X105 * F(-0.352443f) + X107 * F(0.277785f));
- R.at(0, 2) = X104;
- R.at(0, 3) = D(X101 * F(0.022887f) + X103 * F(-0.097545f) + X105 * F(0.490393f) + X107 * F(0.865723f));
- R.at(1, 0) = X110;
- R.at(1, 1) = D(X111 * F(0.415735f) + X113 * F(0.791065f) + X115 * F(-0.352443f) + X117 * F(0.277785f));
- R.at(1, 2) = X114;
- R.at(1, 3) = D(X111 * F(0.022887f) + X113 * F(-0.097545f) + X115 * F(0.490393f) + X117 * F(0.865723f));
- R.at(2, 0) = X120;
- R.at(2, 1) = D(X121 * F(0.415735f) + X123 * F(0.791065f) + X125 * F(-0.352443f) + X127 * F(0.277785f));
- R.at(2, 2) = X124;
- R.at(2, 3) = D(X121 * F(0.022887f) + X123 * F(-0.097545f) + X125 * F(0.490393f) + X127 * F(0.865723f));
- R.at(3, 0) = X130;
- R.at(3, 1) = D(X131 * F(0.415735f) + X133 * F(0.791065f) + X135 * F(-0.352443f) + X137 * F(0.277785f));
- R.at(3, 2) = X134;
- R.at(3, 3) = D(X131 * F(0.022887f) + X133 * F(-0.097545f) + X135 * F(0.490393f) + X137 * F(0.865723f));
- // 40 muls 24 adds
- // 4x4 = 4x8 times 8x4, matrix 1 is constant
- S.at(0, 0) = D(X101 * F(0.906127f) + X103 * F(-0.318190f) + X105 * F(0.212608f) + X107 * F(-0.180240f));
- S.at(0, 1) = X102;
- S.at(0, 2) = D(X101 * F(-0.074658f) + X103 * F(0.513280f) + X105 * F(0.768178f) + X107 * F(-0.375330f));
- S.at(0, 3) = X106;
- S.at(1, 0) = D(X111 * F(0.906127f) + X113 * F(-0.318190f) + X115 * F(0.212608f) + X117 * F(-0.180240f));
- S.at(1, 1) = X112;
- S.at(1, 2) = D(X111 * F(-0.074658f) + X113 * F(0.513280f) + X115 * F(0.768178f) + X117 * F(-0.375330f));
- S.at(1, 3) = X116;
- S.at(2, 0) = D(X121 * F(0.906127f) + X123 * F(-0.318190f) + X125 * F(0.212608f) + X127 * F(-0.180240f));
- S.at(2, 1) = X122;
- S.at(2, 2) = D(X121 * F(-0.074658f) + X123 * F(0.513280f) + X125 * F(0.768178f) + X127 * F(-0.375330f));
- S.at(2, 3) = X126;
- S.at(3, 0) = D(X131 * F(0.906127f) + X133 * F(-0.318190f) + X135 * F(0.212608f) + X137 * F(-0.180240f));
- S.at(3, 1) = X132;
- S.at(3, 2) = D(X131 * F(-0.074658f) + X133 * F(0.513280f) + X135 * F(0.768178f) + X137 * F(-0.375330f));
- S.at(3, 3) = X136;
- // 40 muls 24 adds
- }
- };
-} // end namespace DCT_Upsample
-
-// Unconditionally frees all allocated m_blocks.
-void jpeg_decoder::free_all_blocks()
-{
- m_pStream = NULL;
- for (mem_block *b = m_pMem_blocks; b; )
- {
- mem_block *n = b->m_pNext;
- jpgd_free(b);
- b = n;
- }
- m_pMem_blocks = NULL;
-}
-
-// This method handles all errors. It will never return.
-// It could easily be changed to use C++ exceptions.
-JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status)
-{
- m_error_code = status;
- free_all_blocks();
- longjmp(m_jmp_state, status);
-}
-
-void *jpeg_decoder::alloc(size_t nSize, bool zero)
-{
- nSize = (JPGD_MAX(nSize, 1) + 3) & ~3;
- char *rv = NULL;
- for (mem_block *b = m_pMem_blocks; b; b = b->m_pNext)
- {
- if ((b->m_used_count + nSize) <= b->m_size)
- {
- rv = b->m_data + b->m_used_count;
- b->m_used_count += nSize;
- break;
- }
- }
- if (!rv)
- {
- int capacity = JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047);
- mem_block *b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity);
- if (!b) { stop_decoding(JPGD_NOTENOUGHMEM); }
- b->m_pNext = m_pMem_blocks; m_pMem_blocks = b;
- b->m_used_count = nSize;
- b->m_size = capacity;
- rv = b->m_data;
- }
- if (zero) memset(rv, 0, nSize);
- return rv;
-}
-
-void jpeg_decoder::word_clear(void *p, uint16 c, uint n)
-{
- uint8 *pD = (uint8*)p;
- const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF;
- while (n)
- {
- pD[0] = l; pD[1] = h; pD += 2;
- n--;
- }
-}
-
-// Refill the input buffer.
-// This method will sit in a loop until (A) the buffer is full or (B)
-// the stream's read() method reports and end of file condition.
-void jpeg_decoder::prep_in_buffer()
-{
- m_in_buf_left = 0;
- m_pIn_buf_ofs = m_in_buf;
-
- if (m_eof_flag)
- return;
-
- do
- {
- int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag);
- if (bytes_read == -1)
- stop_decoding(JPGD_STREAM_READ);
-
- m_in_buf_left += bytes_read;
- } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag));
-
- m_total_bytes_read += m_in_buf_left;
-
- // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid).
- // (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.)
- word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64);
-}
-
-// Read a Huffman code table.
-void jpeg_decoder::read_dht_marker()
-{
- int i, index, count;
- uint8 huff_num[17];
- uint8 huff_val[256];
-
- uint num_left = get_bits(16);
-
- if (num_left < 2)
- stop_decoding(JPGD_BAD_DHT_MARKER);
-
- num_left -= 2;
-
- while (num_left)
- {
- index = get_bits(8);
-
- huff_num[0] = 0;
-
- count = 0;
-
- for (i = 1; i <= 16; i++)
- {
- huff_num[i] = static_cast<uint8>(get_bits(8));
- count += huff_num[i];
- }
-
- if (count > 255)
- stop_decoding(JPGD_BAD_DHT_COUNTS);
-
- for (i = 0; i < count; i++)
- huff_val[i] = static_cast<uint8>(get_bits(8));
+ // Unconditionally frees all allocated m_blocks.
+ void jpeg_decoder::free_all_blocks()
+ {
+ m_pStream = nullptr;
+ for (mem_block* b = m_pMem_blocks; b; )
+ {
+ mem_block* n = b->m_pNext;
+ jpgd_free(b);
+ b = n;
+ }
+ m_pMem_blocks = nullptr;
+ }
+
+ // This method handles all errors. It will never return.
+ // It could easily be changed to use C++ exceptions.
+ JPGD_NORETURN void jpeg_decoder::stop_decoding(jpgd_status status)
+ {
+ m_error_code = status;
+ free_all_blocks();
+ longjmp(m_jmp_state, status);
+ }
+
+ void* jpeg_decoder::alloc(size_t nSize, bool zero)
+ {
+ nSize = (JPGD_MAX(nSize, 1) + 3) & ~3;
+ char* rv = nullptr;
+ for (mem_block* b = m_pMem_blocks; b; b = b->m_pNext)
+ {
+ if ((b->m_used_count + nSize) <= b->m_size)
+ {
+ rv = b->m_data + b->m_used_count;
+ b->m_used_count += nSize;
+ break;
+ }
+ }
+ if (!rv)
+ {
+ int capacity = JPGD_MAX(32768 - 256, (nSize + 2047) & ~2047);
+ mem_block* b = (mem_block*)jpgd_malloc(sizeof(mem_block) + capacity);
+ if (!b)
+ {
+ stop_decoding(JPGD_NOTENOUGHMEM);
+ }
+
+ b->m_pNext = m_pMem_blocks;
+ m_pMem_blocks = b;
+ b->m_used_count = nSize;
+ b->m_size = capacity;
+ rv = b->m_data;
+ }
+ if (zero) memset(rv, 0, nSize);
+ return rv;
+ }
+
+ void* jpeg_decoder::alloc_aligned(size_t nSize, uint32_t align, bool zero)
+ {
+ assert((align >= 1U) && ((align & (align - 1U)) == 0U));
+ void *p = alloc(nSize + align - 1U, zero);
+ p = (void *)( ((uintptr_t)p + (align - 1U)) & ~((uintptr_t)(align - 1U)) );
+ return p;
+ }
+
+ void jpeg_decoder::word_clear(void* p, uint16 c, uint n)
+ {
+ uint8* pD = (uint8*)p;
+ const uint8 l = c & 0xFF, h = (c >> 8) & 0xFF;
+ while (n)
+ {
+ pD[0] = l;
+ pD[1] = h;
+ pD += 2;
+ n--;
+ }
+ }
+
+ // Refill the input buffer.
+ // This method will sit in a loop until (A) the buffer is full or (B)
+ // the stream's read() method reports and end of file condition.
+ void jpeg_decoder::prep_in_buffer()
+ {
+ m_in_buf_left = 0;
+ m_pIn_buf_ofs = m_in_buf;
+
+ if (m_eof_flag)
+ return;
+
+ do
+ {
+ int bytes_read = m_pStream->read(m_in_buf + m_in_buf_left, JPGD_IN_BUF_SIZE - m_in_buf_left, &m_eof_flag);
+ if (bytes_read == -1)
+ stop_decoding(JPGD_STREAM_READ);
+
+ m_in_buf_left += bytes_read;
+ } while ((m_in_buf_left < JPGD_IN_BUF_SIZE) && (!m_eof_flag));
+
+ m_total_bytes_read += m_in_buf_left;
+
+ // Pad the end of the block with M_EOI (prevents the decompressor from going off the rails if the stream is invalid).
+ // (This dates way back to when this decompressor was written in C/asm, and the all-asm Huffman decoder did some fancy things to increase perf.)
+ word_clear(m_pIn_buf_ofs + m_in_buf_left, 0xD9FF, 64);
+ }
+
+ // Read a Huffman code table.
+ void jpeg_decoder::read_dht_marker()
+ {
+ int i, index, count;
+ uint8 huff_num[17];
+ uint8 huff_val[256];
- i = 1 + 16 + count;
+ uint num_left = get_bits(16);
- if (num_left < (uint)i)
- stop_decoding(JPGD_BAD_DHT_MARKER);
+ if (num_left < 2)
+ stop_decoding(JPGD_BAD_DHT_MARKER);
- num_left -= i;
+ num_left -= 2;
- if ((index & 0x10) > 0x10)
- stop_decoding(JPGD_BAD_DHT_INDEX);
+ while (num_left)
+ {
+ index = get_bits(8);
- index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1);
+ huff_num[0] = 0;
- if (index >= JPGD_MAX_HUFF_TABLES)
- stop_decoding(JPGD_BAD_DHT_INDEX);
+ count = 0;
- if (!m_huff_num[index])
- m_huff_num[index] = (uint8 *)alloc(17);
+ for (i = 1; i <= 16; i++)
+ {
+ huff_num[i] = static_cast<uint8>(get_bits(8));
+ count += huff_num[i];
+ }
- if (!m_huff_val[index])
- m_huff_val[index] = (uint8 *)alloc(256);
+ if (count > 255)
+ stop_decoding(JPGD_BAD_DHT_COUNTS);
- m_huff_ac[index] = (index & 0x10) != 0;
- memcpy(m_huff_num[index], huff_num, 17);
- memcpy(m_huff_val[index], huff_val, 256);
- }
-}
+ bool symbol_present[256];
+ memset(symbol_present, 0, sizeof(symbol_present));
-// Read a quantization table.
-void jpeg_decoder::read_dqt_marker()
-{
- int n, i, prec;
- uint num_left;
- uint temp;
+ for (i = 0; i < count; i++)
+ {
+ const int s = get_bits(8);
- num_left = get_bits(16);
+ // Check for obviously bogus tables.
+ if (symbol_present[s])
+ stop_decoding(JPGD_BAD_DHT_COUNTS);
- if (num_left < 2)
- stop_decoding(JPGD_BAD_DQT_MARKER);
+ huff_val[i] = static_cast<uint8_t>(s);
+ symbol_present[s] = true;
+ }
- num_left -= 2;
+ i = 1 + 16 + count;
- while (num_left)
- {
- n = get_bits(8);
- prec = n >> 4;
- n &= 0x0F;
+ if (num_left < (uint)i)
+ stop_decoding(JPGD_BAD_DHT_MARKER);
- if (n >= JPGD_MAX_QUANT_TABLES)
- stop_decoding(JPGD_BAD_DQT_TABLE);
+ num_left -= i;
- if (!m_quant[n])
- m_quant[n] = (jpgd_quant_t *)alloc(64 * sizeof(jpgd_quant_t));
+ if ((index & 0x10) > 0x10)
+ stop_decoding(JPGD_BAD_DHT_INDEX);
- // read quantization entries, in zag order
- for (i = 0; i < 64; i++)
- {
- temp = get_bits(8);
+ index = (index & 0x0F) + ((index & 0x10) >> 4) * (JPGD_MAX_HUFF_TABLES >> 1);
- if (prec)
- temp = (temp << 8) + get_bits(8);
+ if (index >= JPGD_MAX_HUFF_TABLES)
+ stop_decoding(JPGD_BAD_DHT_INDEX);
- m_quant[n][i] = static_cast<jpgd_quant_t>(temp);
- }
+ if (!m_huff_num[index])
+ m_huff_num[index] = (uint8*)alloc(17);
- i = 64 + 1;
+ if (!m_huff_val[index])
+ m_huff_val[index] = (uint8*)alloc(256);
- if (prec)
- i += 64;
+ m_huff_ac[index] = (index & 0x10) != 0;
+ memcpy(m_huff_num[index], huff_num, 17);
+ memcpy(m_huff_val[index], huff_val, 256);
+ }
+ }
- if (num_left < (uint)i)
- stop_decoding(JPGD_BAD_DQT_LENGTH);
+ // Read a quantization table.
+ void jpeg_decoder::read_dqt_marker()
+ {
+ int n, i, prec;
+ uint num_left;
+ uint temp;
- num_left -= i;
- }
-}
+ num_left = get_bits(16);
-// Read the start of frame (SOF) marker.
-void jpeg_decoder::read_sof_marker()
-{
- int i;
- uint num_left;
+ if (num_left < 2)
+ stop_decoding(JPGD_BAD_DQT_MARKER);
- num_left = get_bits(16);
+ num_left -= 2;
- if (get_bits(8) != 8) /* precision: sorry, only 8-bit precision is supported right now */
- stop_decoding(JPGD_BAD_PRECISION);
+ while (num_left)
+ {
+ n = get_bits(8);
+ prec = n >> 4;
+ n &= 0x0F;
- m_image_y_size = get_bits(16);
+ if (n >= JPGD_MAX_QUANT_TABLES)
+ stop_decoding(JPGD_BAD_DQT_TABLE);
- if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT))
- stop_decoding(JPGD_BAD_HEIGHT);
+ if (!m_quant[n])
+ m_quant[n] = (jpgd_quant_t*)alloc(64 * sizeof(jpgd_quant_t));
- m_image_x_size = get_bits(16);
+ // read quantization entries, in zag order
+ for (i = 0; i < 64; i++)
+ {
+ temp = get_bits(8);
- if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH))
- stop_decoding(JPGD_BAD_WIDTH);
+ if (prec)
+ temp = (temp << 8) + get_bits(8);
- m_comps_in_frame = get_bits(8);
+ m_quant[n][i] = static_cast<jpgd_quant_t>(temp);
+ }
- if (m_comps_in_frame > JPGD_MAX_COMPONENTS)
- stop_decoding(JPGD_TOO_MANY_COMPONENTS);
+ i = 64 + 1;
- if (num_left != (uint)(m_comps_in_frame * 3 + 8))
- stop_decoding(JPGD_BAD_SOF_LENGTH);
+ if (prec)
+ i += 64;
- for (i = 0; i < m_comps_in_frame; i++)
- {
- m_comp_ident[i] = get_bits(8);
- m_comp_h_samp[i] = get_bits(4);
- m_comp_v_samp[i] = get_bits(4);
- m_comp_quant[i] = get_bits(8);
- }
-}
+ if (num_left < (uint)i)
+ stop_decoding(JPGD_BAD_DQT_LENGTH);
-// Used to skip unrecognized markers.
-void jpeg_decoder::skip_variable_marker()
-{
- uint num_left;
+ num_left -= i;
+ }
+ }
- num_left = get_bits(16);
+ // Read the start of frame (SOF) marker.
+ void jpeg_decoder::read_sof_marker()
+ {
+ int i;
+ uint num_left;
- if (num_left < 2)
- stop_decoding(JPGD_BAD_VARIABLE_MARKER);
+ num_left = get_bits(16);
- num_left -= 2;
+ /* precision: sorry, only 8-bit precision is supported */
+ if (get_bits(8) != 8)
+ stop_decoding(JPGD_BAD_PRECISION);
- while (num_left)
- {
- get_bits(8);
- num_left--;
- }
-}
+ m_image_y_size = get_bits(16);
-// Read a define restart interval (DRI) marker.
-void jpeg_decoder::read_dri_marker()
-{
- if (get_bits(16) != 4)
- stop_decoding(JPGD_BAD_DRI_LENGTH);
+ if ((m_image_y_size < 1) || (m_image_y_size > JPGD_MAX_HEIGHT))
+ stop_decoding(JPGD_BAD_HEIGHT);
- m_restart_interval = get_bits(16);
-}
+ m_image_x_size = get_bits(16);
-// Read a start of scan (SOS) marker.
-void jpeg_decoder::read_sos_marker()
-{
- uint num_left;
- int i, ci, n, c, cc;
+ if ((m_image_x_size < 1) || (m_image_x_size > JPGD_MAX_WIDTH))
+ stop_decoding(JPGD_BAD_WIDTH);
- num_left = get_bits(16);
+ m_comps_in_frame = get_bits(8);
- n = get_bits(8);
-
- m_comps_in_scan = n;
-
- num_left -= 3;
-
- if ( (num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN) )
- stop_decoding(JPGD_BAD_SOS_LENGTH);
-
- for (i = 0; i < n; i++)
- {
- cc = get_bits(8);
- c = get_bits(8);
- num_left -= 2;
-
- for (ci = 0; ci < m_comps_in_frame; ci++)
- if (cc == m_comp_ident[ci])
- break;
-
- if (ci >= m_comps_in_frame)
- stop_decoding(JPGD_BAD_SOS_COMP_ID);
-
- m_comp_list[i] = ci;
- m_comp_dc_tab[ci] = (c >> 4) & 15;
- m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1);
- }
-
- m_spectral_start = get_bits(8);
- m_spectral_end = get_bits(8);
- m_successive_high = get_bits(4);
- m_successive_low = get_bits(4);
-
- if (!m_progressive_flag)
- {
- m_spectral_start = 0;
- m_spectral_end = 63;
- }
-
- num_left -= 3;
-
- while (num_left) /* read past whatever is num_left */
- {
- get_bits(8);
- num_left--;
- }
-}
-
-// Finds the next marker.
-int jpeg_decoder::next_marker()
-{
- uint c, bytes;
-
- bytes = 0;
-
- do
- {
- do
- {
- bytes++;
- c = get_bits(8);
- } while (c != 0xFF);
-
- do
- {
- c = get_bits(8);
- } while (c == 0xFF);
-
- } while (c == 0);
-
- // If bytes > 0 here, there where extra bytes before the marker (not good).
-
- return c;
-}
-
-// Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is
-// encountered.
-int jpeg_decoder::process_markers()
-{
- int c;
-
- for ( ; ; )
- {
- c = next_marker();
-
- switch (c)
- {
- case M_SOF0:
- case M_SOF1:
- case M_SOF2:
- case M_SOF3:
- case M_SOF5:
- case M_SOF6:
- case M_SOF7:
-// case M_JPG:
- case M_SOF9:
- case M_SOF10:
- case M_SOF11:
- case M_SOF13:
- case M_SOF14:
- case M_SOF15:
- case M_SOI:
- case M_EOI:
- case M_SOS:
- {
- return c;
- }
- case M_DHT:
- {
- read_dht_marker();
- break;
- }
- // No arithmitic support - dumb patents!
- case M_DAC:
- {
- stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);
- break;
- }
- case M_DQT:
- {
- read_dqt_marker();
- break;
- }
- case M_DRI:
- {
- read_dri_marker();
- break;
- }
- //case M_APP0: /* no need to read the JFIF marker */
-
- case M_JPG:
- case M_RST0: /* no parameters */
- case M_RST1:
- case M_RST2:
- case M_RST3:
- case M_RST4:
- case M_RST5:
- case M_RST6:
- case M_RST7:
- case M_TEM:
- {
- stop_decoding(JPGD_UNEXPECTED_MARKER);
- break;
- }
- default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */
- {
- skip_variable_marker();
- break;
- }
- }
- }
-}
-
-// Finds the start of image (SOI) marker.
-// This code is rather defensive: it only checks the first 512 bytes to avoid
-// false positives.
-void jpeg_decoder::locate_soi_marker()
-{
- uint lastchar, thischar;
- uint bytesleft;
-
- lastchar = get_bits(8);
-
- thischar = get_bits(8);
-
- /* ok if it's a normal JPEG file without a special header */
-
- if ((lastchar == 0xFF) && (thischar == M_SOI))
- return;
-
- bytesleft = 4096; //512;
-
- for ( ; ; )
- {
- if (--bytesleft == 0)
- stop_decoding(JPGD_NOT_JPEG);
-
- lastchar = thischar;
-
- thischar = get_bits(8);
-
- if (lastchar == 0xFF)
- {
- if (thischar == M_SOI)
- break;
- else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end
- stop_decoding(JPGD_NOT_JPEG);
- }
- }
-
- // Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad.
- thischar = (m_bit_buf >> 24) & 0xFF;
-
- if (thischar != 0xFF)
- stop_decoding(JPGD_NOT_JPEG);
-}
-
-// Find a start of frame (SOF) marker.
-void jpeg_decoder::locate_sof_marker()
-{
- locate_soi_marker();
-
- int c = process_markers();
-
- switch (c)
- {
- case M_SOF2:
- m_progressive_flag = JPGD_TRUE;
- case M_SOF0: /* baseline DCT */
- case M_SOF1: /* extended sequential DCT */
- {
- read_sof_marker();
- break;
- }
- case M_SOF9: /* Arithmitic coding */
- {
- stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);
- break;
- }
- default:
- {
- stop_decoding(JPGD_UNSUPPORTED_MARKER);
- break;
- }
- }
-}
-
-// Find a start of scan (SOS) marker.
-int jpeg_decoder::locate_sos_marker()
-{
- int c;
-
- c = process_markers();
-
- if (c == M_EOI)
- return JPGD_FALSE;
- else if (c != M_SOS)
- stop_decoding(JPGD_UNEXPECTED_MARKER);
-
- read_sos_marker();
-
- return JPGD_TRUE;
-}
-
-// Reset everything to default/uninitialized state.
-void jpeg_decoder::init(jpeg_decoder_stream *pStream)
-{
- m_pMem_blocks = NULL;
- m_error_code = JPGD_SUCCESS;
- m_ready_flag = false;
- m_image_x_size = m_image_y_size = 0;
- m_pStream = pStream;
- m_progressive_flag = JPGD_FALSE;
-
- memset(m_huff_ac, 0, sizeof(m_huff_ac));
- memset(m_huff_num, 0, sizeof(m_huff_num));
- memset(m_huff_val, 0, sizeof(m_huff_val));
- memset(m_quant, 0, sizeof(m_quant));
-
- m_scan_type = 0;
- m_comps_in_frame = 0;
-
- memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp));
- memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp));
- memset(m_comp_quant, 0, sizeof(m_comp_quant));
- memset(m_comp_ident, 0, sizeof(m_comp_ident));
- memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks));
- memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks));
-
- m_comps_in_scan = 0;
- memset(m_comp_list, 0, sizeof(m_comp_list));
- memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab));
- memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab));
-
- m_spectral_start = 0;
- m_spectral_end = 0;
- m_successive_low = 0;
- m_successive_high = 0;
- m_max_mcu_x_size = 0;
- m_max_mcu_y_size = 0;
- m_blocks_per_mcu = 0;
- m_max_blocks_per_row = 0;
- m_mcus_per_row = 0;
- m_mcus_per_col = 0;
- m_expanded_blocks_per_component = 0;
- m_expanded_blocks_per_mcu = 0;
- m_expanded_blocks_per_row = 0;
- m_freq_domain_chroma_upsample = false;
-
- memset(m_mcu_org, 0, sizeof(m_mcu_org));
-
- m_total_lines_left = 0;
- m_mcu_lines_left = 0;
- m_real_dest_bytes_per_scan_line = 0;
- m_dest_bytes_per_scan_line = 0;
- m_dest_bytes_per_pixel = 0;
-
- memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs));
-
- memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs));
- memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs));
- memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));
-
- m_eob_run = 0;
-
- memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));
-
- m_pIn_buf_ofs = m_in_buf;
- m_in_buf_left = 0;
- m_eof_flag = false;
- m_tem_flag = 0;
-
- memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start));
- memset(m_in_buf, 0, sizeof(m_in_buf));
- memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end));
-
- m_restart_interval = 0;
- m_restarts_left = 0;
- m_next_restart_num = 0;
-
- m_max_mcus_per_row = 0;
- m_max_blocks_per_mcu = 0;
- m_max_mcus_per_col = 0;
-
- memset(m_last_dc_val, 0, sizeof(m_last_dc_val));
- m_pMCU_coefficients = NULL;
- m_pSample_buf = NULL;
-
- m_total_bytes_read = 0;
-
- m_pScan_line_0 = NULL;
- m_pScan_line_1 = NULL;
-
- // Ready the input buffer.
- prep_in_buffer();
-
- // Prime the bit buffer.
- m_bits_left = 16;
- m_bit_buf = 0;
-
- get_bits(16);
- get_bits(16);
-
- for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++)
- m_mcu_block_max_zag[i] = 64;
-}
+ if (m_comps_in_frame > JPGD_MAX_COMPONENTS)
+ stop_decoding(JPGD_TOO_MANY_COMPONENTS);
+
+ if (num_left != (uint)(m_comps_in_frame * 3 + 8))
+ stop_decoding(JPGD_BAD_SOF_LENGTH);
+
+ for (i = 0; i < m_comps_in_frame; i++)
+ {
+ m_comp_ident[i] = get_bits(8);
+ m_comp_h_samp[i] = get_bits(4);
+ m_comp_v_samp[i] = get_bits(4);
+
+ if (!m_comp_h_samp[i] || !m_comp_v_samp[i] || (m_comp_h_samp[i] > 2) || (m_comp_v_samp[i] > 2))
+ stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
+
+ m_comp_quant[i] = get_bits(8);
+ if (m_comp_quant[i] >= JPGD_MAX_QUANT_TABLES)
+ stop_decoding(JPGD_DECODE_ERROR);
+ }
+ }
+
+ // Used to skip unrecognized markers.
+ void jpeg_decoder::skip_variable_marker()
+ {
+ uint num_left;
+
+ num_left = get_bits(16);
+
+ if (num_left < 2)
+ stop_decoding(JPGD_BAD_VARIABLE_MARKER);
+
+ num_left -= 2;
+
+ while (num_left)
+ {
+ get_bits(8);
+ num_left--;
+ }
+ }
+
+ // Read a define restart interval (DRI) marker.
+ void jpeg_decoder::read_dri_marker()
+ {
+ if (get_bits(16) != 4)
+ stop_decoding(JPGD_BAD_DRI_LENGTH);
+
+ m_restart_interval = get_bits(16);
+ }
+
+ // Read a start of scan (SOS) marker.
+ void jpeg_decoder::read_sos_marker()
+ {
+ uint num_left;
+ int i, ci, n, c, cc;
+
+ num_left = get_bits(16);
+
+ n = get_bits(8);
+
+ m_comps_in_scan = n;
+
+ num_left -= 3;
+
+ if ((num_left != (uint)(n * 2 + 3)) || (n < 1) || (n > JPGD_MAX_COMPS_IN_SCAN))
+ stop_decoding(JPGD_BAD_SOS_LENGTH);
+
+ for (i = 0; i < n; i++)
+ {
+ cc = get_bits(8);
+ c = get_bits(8);
+ num_left -= 2;
+
+ for (ci = 0; ci < m_comps_in_frame; ci++)
+ if (cc == m_comp_ident[ci])
+ break;
+
+ if (ci >= m_comps_in_frame)
+ stop_decoding(JPGD_BAD_SOS_COMP_ID);
+
+ if (ci >= JPGD_MAX_COMPONENTS)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ m_comp_list[i] = ci;
+
+ m_comp_dc_tab[ci] = (c >> 4) & 15;
+ m_comp_ac_tab[ci] = (c & 15) + (JPGD_MAX_HUFF_TABLES >> 1);
+
+ if (m_comp_dc_tab[ci] >= JPGD_MAX_HUFF_TABLES)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ if (m_comp_ac_tab[ci] >= JPGD_MAX_HUFF_TABLES)
+ stop_decoding(JPGD_DECODE_ERROR);
+ }
+
+ m_spectral_start = get_bits(8);
+ m_spectral_end = get_bits(8);
+ m_successive_high = get_bits(4);
+ m_successive_low = get_bits(4);
+
+ if (!m_progressive_flag)
+ {
+ m_spectral_start = 0;
+ m_spectral_end = 63;
+ }
+
+ num_left -= 3;
+
+ /* read past whatever is num_left */
+ while (num_left)
+ {
+ get_bits(8);
+ num_left--;
+ }
+ }
+
+ // Finds the next marker.
+ int jpeg_decoder::next_marker()
+ {
+ uint c, bytes;
+
+ bytes = 0;
+
+ do
+ {
+ do
+ {
+ bytes++;
+ c = get_bits(8);
+ } while (c != 0xFF);
+
+ do
+ {
+ c = get_bits(8);
+ } while (c == 0xFF);
+
+ } while (c == 0);
+
+ // If bytes > 0 here, there where extra bytes before the marker (not good).
+
+ return c;
+ }
+
+ // Process markers. Returns when an SOFx, SOI, EOI, or SOS marker is
+ // encountered.
+ int jpeg_decoder::process_markers()
+ {
+ int c;
+
+ for (; ; )
+ {
+ c = next_marker();
+
+ switch (c)
+ {
+ case M_SOF0:
+ case M_SOF1:
+ case M_SOF2:
+ case M_SOF3:
+ case M_SOF5:
+ case M_SOF6:
+ case M_SOF7:
+ // case M_JPG:
+ case M_SOF9:
+ case M_SOF10:
+ case M_SOF11:
+ case M_SOF13:
+ case M_SOF14:
+ case M_SOF15:
+ case M_SOI:
+ case M_EOI:
+ case M_SOS:
+ {
+ return c;
+ }
+ case M_DHT:
+ {
+ read_dht_marker();
+ break;
+ }
+ // No arithmitic support - dumb patents!
+ case M_DAC:
+ {
+ stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);
+ break;
+ }
+ case M_DQT:
+ {
+ read_dqt_marker();
+ break;
+ }
+ case M_DRI:
+ {
+ read_dri_marker();
+ break;
+ }
+ //case M_APP0: /* no need to read the JFIF marker */
+ case M_JPG:
+ case M_RST0: /* no parameters */
+ case M_RST1:
+ case M_RST2:
+ case M_RST3:
+ case M_RST4:
+ case M_RST5:
+ case M_RST6:
+ case M_RST7:
+ case M_TEM:
+ {
+ stop_decoding(JPGD_UNEXPECTED_MARKER);
+ break;
+ }
+ default: /* must be DNL, DHP, EXP, APPn, JPGn, COM, or RESn or APP0 */
+ {
+ skip_variable_marker();
+ break;
+ }
+ }
+ }
+ }
+
+ // Finds the start of image (SOI) marker.
+ void jpeg_decoder::locate_soi_marker()
+ {
+ uint lastchar, thischar;
+ uint bytesleft;
+
+ lastchar = get_bits(8);
+
+ thischar = get_bits(8);
+
+ /* ok if it's a normal JPEG file without a special header */
+
+ if ((lastchar == 0xFF) && (thischar == M_SOI))
+ return;
+
+ bytesleft = 4096;
+
+ for (; ; )
+ {
+ if (--bytesleft == 0)
+ stop_decoding(JPGD_NOT_JPEG);
+
+ lastchar = thischar;
+
+ thischar = get_bits(8);
+
+ if (lastchar == 0xFF)
+ {
+ if (thischar == M_SOI)
+ break;
+ else if (thischar == M_EOI) // get_bits will keep returning M_EOI if we read past the end
+ stop_decoding(JPGD_NOT_JPEG);
+ }
+ }
+
+ // Check the next character after marker: if it's not 0xFF, it can't be the start of the next marker, so the file is bad.
+ thischar = (m_bit_buf >> 24) & 0xFF;
+
+ if (thischar != 0xFF)
+ stop_decoding(JPGD_NOT_JPEG);
+ }
+
+ // Find a start of frame (SOF) marker.
+ void jpeg_decoder::locate_sof_marker()
+ {
+ locate_soi_marker();
+
+ int c = process_markers();
+
+ switch (c)
+ {
+ case M_SOF2:
+ {
+ m_progressive_flag = JPGD_TRUE;
+ read_sof_marker();
+ break;
+ }
+ case M_SOF0: /* baseline DCT */
+ case M_SOF1: /* extended sequential DCT */
+ {
+ read_sof_marker();
+ break;
+ }
+ case M_SOF9: /* Arithmitic coding */
+ {
+ stop_decoding(JPGD_NO_ARITHMITIC_SUPPORT);
+ break;
+ }
+ default:
+ {
+ stop_decoding(JPGD_UNSUPPORTED_MARKER);
+ break;
+ }
+ }
+ }
+
+ // Find a start of scan (SOS) marker.
+ int jpeg_decoder::locate_sos_marker()
+ {
+ int c;
+
+ c = process_markers();
+
+ if (c == M_EOI)
+ return JPGD_FALSE;
+ else if (c != M_SOS)
+ stop_decoding(JPGD_UNEXPECTED_MARKER);
+
+ read_sos_marker();
+
+ return JPGD_TRUE;
+ }
+
+ // Reset everything to default/uninitialized state.
+ void jpeg_decoder::init(jpeg_decoder_stream* pStream, uint32_t flags)
+ {
+ m_flags = flags;
+ m_pMem_blocks = nullptr;
+ m_error_code = JPGD_SUCCESS;
+ m_ready_flag = false;
+ m_image_x_size = m_image_y_size = 0;
+ m_pStream = pStream;
+ m_progressive_flag = JPGD_FALSE;
+
+ memset(m_huff_ac, 0, sizeof(m_huff_ac));
+ memset(m_huff_num, 0, sizeof(m_huff_num));
+ memset(m_huff_val, 0, sizeof(m_huff_val));
+ memset(m_quant, 0, sizeof(m_quant));
+
+ m_scan_type = 0;
+ m_comps_in_frame = 0;
+
+ memset(m_comp_h_samp, 0, sizeof(m_comp_h_samp));
+ memset(m_comp_v_samp, 0, sizeof(m_comp_v_samp));
+ memset(m_comp_quant, 0, sizeof(m_comp_quant));
+ memset(m_comp_ident, 0, sizeof(m_comp_ident));
+ memset(m_comp_h_blocks, 0, sizeof(m_comp_h_blocks));
+ memset(m_comp_v_blocks, 0, sizeof(m_comp_v_blocks));
+
+ m_comps_in_scan = 0;
+ memset(m_comp_list, 0, sizeof(m_comp_list));
+ memset(m_comp_dc_tab, 0, sizeof(m_comp_dc_tab));
+ memset(m_comp_ac_tab, 0, sizeof(m_comp_ac_tab));
+
+ m_spectral_start = 0;
+ m_spectral_end = 0;
+ m_successive_low = 0;
+ m_successive_high = 0;
+ m_max_mcu_x_size = 0;
+ m_max_mcu_y_size = 0;
+ m_blocks_per_mcu = 0;
+ m_max_blocks_per_row = 0;
+ m_mcus_per_row = 0;
+ m_mcus_per_col = 0;
+
+ memset(m_mcu_org, 0, sizeof(m_mcu_org));
+
+ m_total_lines_left = 0;
+ m_mcu_lines_left = 0;
+ m_num_buffered_scanlines = 0;
+ m_real_dest_bytes_per_scan_line = 0;
+ m_dest_bytes_per_scan_line = 0;
+ m_dest_bytes_per_pixel = 0;
+
+ memset(m_pHuff_tabs, 0, sizeof(m_pHuff_tabs));
+
+ memset(m_dc_coeffs, 0, sizeof(m_dc_coeffs));
+ memset(m_ac_coeffs, 0, sizeof(m_ac_coeffs));
+ memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));
+
+ m_eob_run = 0;
+
+ m_pIn_buf_ofs = m_in_buf;
+ m_in_buf_left = 0;
+ m_eof_flag = false;
+ m_tem_flag = 0;
+
+ memset(m_in_buf_pad_start, 0, sizeof(m_in_buf_pad_start));
+ memset(m_in_buf, 0, sizeof(m_in_buf));
+ memset(m_in_buf_pad_end, 0, sizeof(m_in_buf_pad_end));
+
+ m_restart_interval = 0;
+ m_restarts_left = 0;
+ m_next_restart_num = 0;
+
+ m_max_mcus_per_row = 0;
+ m_max_blocks_per_mcu = 0;
+ m_max_mcus_per_col = 0;
+
+ memset(m_last_dc_val, 0, sizeof(m_last_dc_val));
+ m_pMCU_coefficients = nullptr;
+ m_pSample_buf = nullptr;
+ m_pSample_buf_prev = nullptr;
+ m_sample_buf_prev_valid = false;
+
+ m_total_bytes_read = 0;
+
+ m_pScan_line_0 = nullptr;
+ m_pScan_line_1 = nullptr;
+
+ // Ready the input buffer.
+ prep_in_buffer();
+
+ // Prime the bit buffer.
+ m_bits_left = 16;
+ m_bit_buf = 0;
+
+ get_bits(16);
+ get_bits(16);
+
+ for (int i = 0; i < JPGD_MAX_BLOCKS_PER_MCU; i++)
+ m_mcu_block_max_zag[i] = 64;
+
+ m_has_sse2 = false;
+
+#if JPGD_USE_SSE2
+#ifdef _MSC_VER
+ int cpu_info[4];
+ __cpuid(cpu_info, 1);
+ const int cpu_info3 = cpu_info[3];
+ m_has_sse2 = ((cpu_info3 >> 26U) & 1U) != 0U;
+#else
+ m_has_sse2 = true;
+#endif
+#endif
+ }
#define SCALEBITS 16
#define ONE_HALF ((int) 1 << (SCALEBITS-1))
#define FIX(x) ((int) ((x) * (1L<<SCALEBITS) + 0.5f))
-// Create a few tables that allow us to quickly convert YCbCr to RGB.
-void jpeg_decoder::create_look_ups()
-{
- for (int i = 0; i <= 255; i++)
- {
- int k = i - 128;
- m_crr[i] = ( FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS;
- m_cbb[i] = ( FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS;
- m_crg[i] = (-FIX(0.71414f)) * k;
- m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF;
- }
-}
-
-// This method throws back into the stream any bytes that where read
-// into the bit buffer during initial marker scanning.
-void jpeg_decoder::fix_in_buffer()
-{
- // In case any 0xFF's where pulled into the buffer during marker scanning.
- JPGD_ASSERT((m_bits_left & 7) == 0);
-
- if (m_bits_left == 16)
- stuff_char( (uint8)(m_bit_buf & 0xFF));
-
- if (m_bits_left >= 8)
- stuff_char( (uint8)((m_bit_buf >> 8) & 0xFF));
-
- stuff_char((uint8)((m_bit_buf >> 16) & 0xFF));
- stuff_char((uint8)((m_bit_buf >> 24) & 0xFF));
-
- m_bits_left = 16;
- get_bits_no_markers(16);
- get_bits_no_markers(16);
-}
-
-void jpeg_decoder::transform_mcu(int mcu_row)
-{
- jpgd_block_t* pSrc_ptr = m_pMCU_coefficients;
- if (m_freq_domain_chroma_upsample) {
- JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_expanded_blocks_per_row);
- }
- else {
- JPGD_ASSERT(mcu_row * m_blocks_per_mcu < m_max_blocks_per_row);
- }
- uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64;
-
- for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
- {
- idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]);
- pSrc_ptr += 64;
- pDst_ptr += 64;
- }
-}
-
-static const uint8 s_max_rc[64] =
-{
- 17, 18, 34, 50, 50, 51, 52, 52, 52, 68, 84, 84, 84, 84, 85, 86, 86, 86, 86, 86,
- 102, 118, 118, 118, 118, 118, 118, 119, 120, 120, 120, 120, 120, 120, 120, 136,
- 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136,
- 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136, 136
-};
-
-void jpeg_decoder::transform_mcu_expand(int mcu_row)
-{
- jpgd_block_t* pSrc_ptr = m_pMCU_coefficients;
- uint8* pDst_ptr = m_pSample_buf + mcu_row * m_expanded_blocks_per_mcu * 64;
-
- // Y IDCT
- int mcu_block;
- for (mcu_block = 0; mcu_block < m_expanded_blocks_per_component; mcu_block++)
- {
- idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block]);
- pSrc_ptr += 64;
- pDst_ptr += 64;
- }
-
- // Chroma IDCT, with upsampling
- jpgd_block_t temp_block[64];
-
- for (int i = 0; i < 2; i++)
- {
- DCT_Upsample::Matrix44 P, Q, R, S;
-
- JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] >= 1);
- JPGD_ASSERT(m_mcu_block_max_zag[mcu_block] <= 64);
-
- int max_zag = m_mcu_block_max_zag[mcu_block++] - 1;
- if (max_zag <= 0) max_zag = 0; // should never happen, only here to shut up static analysis
- switch (s_max_rc[max_zag])
- {
- case 1*16+1:
- DCT_Upsample::P_Q<1, 1>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<1, 1>::calc(R, S, pSrc_ptr);
- break;
- case 1*16+2:
- DCT_Upsample::P_Q<1, 2>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<1, 2>::calc(R, S, pSrc_ptr);
- break;
- case 2*16+2:
- DCT_Upsample::P_Q<2, 2>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<2, 2>::calc(R, S, pSrc_ptr);
- break;
- case 3*16+2:
- DCT_Upsample::P_Q<3, 2>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<3, 2>::calc(R, S, pSrc_ptr);
- break;
- case 3*16+3:
- DCT_Upsample::P_Q<3, 3>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<3, 3>::calc(R, S, pSrc_ptr);
- break;
- case 3*16+4:
- DCT_Upsample::P_Q<3, 4>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<3, 4>::calc(R, S, pSrc_ptr);
- break;
- case 4*16+4:
- DCT_Upsample::P_Q<4, 4>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<4, 4>::calc(R, S, pSrc_ptr);
- break;
- case 5*16+4:
- DCT_Upsample::P_Q<5, 4>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<5, 4>::calc(R, S, pSrc_ptr);
- break;
- case 5*16+5:
- DCT_Upsample::P_Q<5, 5>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<5, 5>::calc(R, S, pSrc_ptr);
- break;
- case 5*16+6:
- DCT_Upsample::P_Q<5, 6>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<5, 6>::calc(R, S, pSrc_ptr);
- break;
- case 6*16+6:
- DCT_Upsample::P_Q<6, 6>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<6, 6>::calc(R, S, pSrc_ptr);
- break;
- case 7*16+6:
- DCT_Upsample::P_Q<7, 6>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<7, 6>::calc(R, S, pSrc_ptr);
- break;
- case 7*16+7:
- DCT_Upsample::P_Q<7, 7>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<7, 7>::calc(R, S, pSrc_ptr);
- break;
- case 7*16+8:
- DCT_Upsample::P_Q<7, 8>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<7, 8>::calc(R, S, pSrc_ptr);
- break;
- case 8*16+8:
- DCT_Upsample::P_Q<8, 8>::calc(P, Q, pSrc_ptr);
- DCT_Upsample::R_S<8, 8>::calc(R, S, pSrc_ptr);
- break;
- default:
- JPGD_ASSERT(false);
- }
-
- DCT_Upsample::Matrix44 a(P + Q); P -= Q;
- DCT_Upsample::Matrix44& b = P;
- DCT_Upsample::Matrix44 c(R + S); R -= S;
- DCT_Upsample::Matrix44& d = R;
-
- DCT_Upsample::Matrix44::add_and_store(temp_block, a, c);
- idct_4x4(temp_block, pDst_ptr);
- pDst_ptr += 64;
-
- DCT_Upsample::Matrix44::sub_and_store(temp_block, a, c);
- idct_4x4(temp_block, pDst_ptr);
- pDst_ptr += 64;
-
- DCT_Upsample::Matrix44::add_and_store(temp_block, b, d);
- idct_4x4(temp_block, pDst_ptr);
- pDst_ptr += 64;
-
- DCT_Upsample::Matrix44::sub_and_store(temp_block, b, d);
- idct_4x4(temp_block, pDst_ptr);
- pDst_ptr += 64;
-
- pSrc_ptr += 64;
- }
-}
-
-// Loads and dequantizes the next row of (already decoded) coefficients.
-// Progressive images only.
-void jpeg_decoder::load_next_row()
-{
- int i;
- jpgd_block_t *p;
- jpgd_quant_t *q;
- int mcu_row, mcu_block, row_block = 0;
- int component_num, component_id;
- int block_x_mcu[JPGD_MAX_COMPONENTS];
-
- memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int));
-
- for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
- {
- int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;
-
- for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
- {
- component_id = m_mcu_org[mcu_block];
- JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES);
- q = m_quant[m_comp_quant[component_id]];
-
- p = m_pMCU_coefficients + 64 * mcu_block;
-
- jpgd_block_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
- jpgd_block_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
- p[0] = pDC[0];
- memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_t));
-
- for (i = 63; i > 0; i--)
- if (p[g_ZAG[i]])
- break;
-
- m_mcu_block_max_zag[mcu_block] = i + 1;
-
- for ( ; i >= 0; i--)
- if (p[g_ZAG[i]])
- p[g_ZAG[i]] = static_cast<jpgd_block_t>(p[g_ZAG[i]] * q[i]);
-
- row_block++;
-
- if (m_comps_in_scan == 1)
- block_x_mcu[component_id]++;
- else
- {
- if (++block_x_mcu_ofs == m_comp_h_samp[component_id])
- {
- block_x_mcu_ofs = 0;
-
- if (++block_y_mcu_ofs == m_comp_v_samp[component_id])
- {
- block_y_mcu_ofs = 0;
-
- block_x_mcu[component_id] += m_comp_h_samp[component_id];
- }
- }
- }
- }
-
- if (m_freq_domain_chroma_upsample)
- transform_mcu_expand(mcu_row);
- else
- transform_mcu(mcu_row);
- }
-
- if (m_comps_in_scan == 1)
- m_block_y_mcu[m_comp_list[0]]++;
- else
- {
- for (component_num = 0; component_num < m_comps_in_scan; component_num++)
- {
- component_id = m_comp_list[component_num];
-
- m_block_y_mcu[component_id] += m_comp_v_samp[component_id];
- }
- }
-}
-
-// Restart interval processing.
-void jpeg_decoder::process_restart()
-{
- int i;
- int c = 0;
-
- // Align to a byte boundry
- // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers!
- //get_bits_no_markers(m_bits_left & 7);
-
- // Let's scan a little bit to find the marker, but not _too_ far.
- // 1536 is a "fudge factor" that determines how much to scan.
- for (i = 1536; i > 0; i--)
- if (get_char() == 0xFF)
- break;
-
- if (i == 0)
- stop_decoding(JPGD_BAD_RESTART_MARKER);
-
- for ( ; i > 0; i--)
- if ((c = get_char()) != 0xFF)
- break;
-
- if (i == 0)
- stop_decoding(JPGD_BAD_RESTART_MARKER);
-
- // Is it the expected marker? If not, something bad happened.
- if (c != (m_next_restart_num + M_RST0))
- stop_decoding(JPGD_BAD_RESTART_MARKER);
-
- // Reset each component's DC prediction values.
- memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));
-
- m_eob_run = 0;
-
- m_restarts_left = m_restart_interval;
-
- m_next_restart_num = (m_next_restart_num + 1) & 7;
-
- // Get the bit buffer going again...
-
- m_bits_left = 16;
- get_bits_no_markers(16);
- get_bits_no_markers(16);
-}
-
-static inline int dequantize_ac(int c, int q) { c *= q; return c; }
-
-// Decodes and dequantizes the next row of coefficients.
-void jpeg_decoder::decode_next_row()
-{
- int row_block = 0;
-
- for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
- {
- if ((m_restart_interval) && (m_restarts_left == 0))
- process_restart();
-
- jpgd_block_t* p = m_pMCU_coefficients;
- for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64)
- {
- int component_id = m_mcu_org[mcu_block];
- JPGD_ASSERT(m_comp_quant[component_id] < JPGD_MAX_QUANT_TABLES);
- jpgd_quant_t* q = m_quant[m_comp_quant[component_id]];
-
- int r, s;
- s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r);
- s = JPGD_HUFF_EXTEND(r, s);
-
- m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]);
-
- p[0] = static_cast<jpgd_block_t>(s * q[0]);
-
- int prev_num_set = m_mcu_block_max_zag[mcu_block];
-
- huff_tables *pH = m_pHuff_tabs[m_comp_ac_tab[component_id]];
-
- int k;
- for (k = 1; k < 64; k++)
- {
- int extra_bits;
- s = huff_decode(pH, extra_bits);
-
- r = s >> 4;
- s &= 15;
-
- if (s)
- {
- if (r)
- {
- if ((k + r) > 63)
- stop_decoding(JPGD_DECODE_ERROR);
-
- if (k < prev_num_set)
- {
- int n = JPGD_MIN(r, prev_num_set - k);
- int kt = k;
- while (n--)
- p[g_ZAG[kt++]] = 0;
- }
-
- k += r;
- }
-
- s = JPGD_HUFF_EXTEND(extra_bits, s);
-
- JPGD_ASSERT(k < 64);
-
- p[g_ZAG[k]] = static_cast<jpgd_block_t>(dequantize_ac(s, q[k])); //s * q[k];
- }
- else
- {
- if (r == 15)
- {
- if ((k + 16) > 64)
- stop_decoding(JPGD_DECODE_ERROR);
-
- if (k < prev_num_set)
- {
- int n = JPGD_MIN(16, prev_num_set - k);
- int kt = k;
- while (n--)
- {
- JPGD_ASSERT(kt <= 63);
- p[g_ZAG[kt++]] = 0;
- }
- }
-
- k += 16 - 1; // - 1 because the loop counter is k
- JPGD_ASSERT(p[g_ZAG[k]] == 0);
- }
- else
- break;
- }
- }
-
- if (k < prev_num_set)
- {
- int kt = k;
- while (kt < prev_num_set)
- p[g_ZAG[kt++]] = 0;
- }
-
- m_mcu_block_max_zag[mcu_block] = k;
-
- row_block++;
- }
-
- if (m_freq_domain_chroma_upsample)
- transform_mcu_expand(mcu_row);
- else
- transform_mcu(mcu_row);
-
- m_restarts_left--;
- }
-}
-
-// YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB
-void jpeg_decoder::H1V1Convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
- uint8 *d = m_pScan_line_0;
- uint8 *s = m_pSample_buf + row * 8;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- for (int j = 0; j < 8; j++)
- {
- int y = s[j];
- int cb = s[64+j];
- int cr = s[128+j];
-
- d[0] = clamp(y + m_crr[cr]);
- d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16));
- d[2] = clamp(y + m_cbb[cb]);
- d[3] = 255;
-
- d += 4;
- }
-
- s += 64*3;
- }
-}
-
-// YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB
-void jpeg_decoder::H2V1Convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
- uint8 *d0 = m_pScan_line_0;
- uint8 *y = m_pSample_buf + row * 8;
- uint8 *c = m_pSample_buf + 2*64 + row * 8;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- for (int l = 0; l < 2; l++)
- {
- for (int j = 0; j < 4; j++)
- {
- int cb = c[0];
- int cr = c[64];
-
- int rc = m_crr[cr];
- int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
- int bc = m_cbb[cb];
-
- int yy = y[j<<1];
- d0[0] = clamp(yy+rc);
- d0[1] = clamp(yy+gc);
- d0[2] = clamp(yy+bc);
- d0[3] = 255;
-
- yy = y[(j<<1)+1];
- d0[4] = clamp(yy+rc);
- d0[5] = clamp(yy+gc);
- d0[6] = clamp(yy+bc);
- d0[7] = 255;
-
- d0 += 8;
-
- c++;
- }
- y += 64;
- }
-
- y += 64*4 - 64*2;
- c += 64*4 - 8;
- }
-}
-
-// YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB
-void jpeg_decoder::H1V2Convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
- uint8 *d0 = m_pScan_line_0;
- uint8 *d1 = m_pScan_line_1;
- uint8 *y;
- uint8 *c;
-
- if (row < 8)
- y = m_pSample_buf + row * 8;
- else
- y = m_pSample_buf + 64*1 + (row & 7) * 8;
-
- c = m_pSample_buf + 64*2 + (row >> 1) * 8;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- for (int j = 0; j < 8; j++)
- {
- int cb = c[0+j];
- int cr = c[64+j];
-
- int rc = m_crr[cr];
- int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
- int bc = m_cbb[cb];
-
- int yy = y[j];
- d0[0] = clamp(yy+rc);
- d0[1] = clamp(yy+gc);
- d0[2] = clamp(yy+bc);
- d0[3] = 255;
-
- yy = y[8+j];
- d1[0] = clamp(yy+rc);
- d1[1] = clamp(yy+gc);
- d1[2] = clamp(yy+bc);
- d1[3] = 255;
-
- d0 += 4;
- d1 += 4;
- }
-
- y += 64*4;
- c += 64*4;
- }
-}
-
-// YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB
-void jpeg_decoder::H2V2Convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
- uint8 *d0 = m_pScan_line_0;
- uint8 *d1 = m_pScan_line_1;
- uint8 *y;
- uint8 *c;
-
- if (row < 8)
- y = m_pSample_buf + row * 8;
- else
- y = m_pSample_buf + 64*2 + (row & 7) * 8;
-
- c = m_pSample_buf + 64*4 + (row >> 1) * 8;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- for (int l = 0; l < 2; l++)
- {
- for (int j = 0; j < 8; j += 2)
- {
- int cb = c[0];
- int cr = c[64];
+ // Create a few tables that allow us to quickly convert YCbCr to RGB.
+ void jpeg_decoder::create_look_ups()
+ {
+ for (int i = 0; i <= 255; i++)
+ {
+ int k = i - 128;
+ m_crr[i] = (FIX(1.40200f) * k + ONE_HALF) >> SCALEBITS;
+ m_cbb[i] = (FIX(1.77200f) * k + ONE_HALF) >> SCALEBITS;
+ m_crg[i] = (-FIX(0.71414f)) * k;
+ m_cbg[i] = (-FIX(0.34414f)) * k + ONE_HALF;
+ }
+ }
+
+ // This method throws back into the stream any bytes that where read
+ // into the bit buffer during initial marker scanning.
+ void jpeg_decoder::fix_in_buffer()
+ {
+ // In case any 0xFF's where pulled into the buffer during marker scanning.
+ assert((m_bits_left & 7) == 0);
+
+ if (m_bits_left == 16)
+ stuff_char((uint8)(m_bit_buf & 0xFF));
+
+ if (m_bits_left >= 8)
+ stuff_char((uint8)((m_bit_buf >> 8) & 0xFF));
+
+ stuff_char((uint8)((m_bit_buf >> 16) & 0xFF));
+ stuff_char((uint8)((m_bit_buf >> 24) & 0xFF));
+
+ m_bits_left = 16;
+ get_bits_no_markers(16);
+ get_bits_no_markers(16);
+ }
+
+ void jpeg_decoder::transform_mcu(int mcu_row)
+ {
+ jpgd_block_coeff_t* pSrc_ptr = m_pMCU_coefficients;
+ if (mcu_row * m_blocks_per_mcu >= m_max_blocks_per_row)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ uint8* pDst_ptr = m_pSample_buf + mcu_row * m_blocks_per_mcu * 64;
+
+ for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
+ {
+ idct(pSrc_ptr, pDst_ptr, m_mcu_block_max_zag[mcu_block], ((m_flags & cFlagDisableSIMD) == 0) && m_has_sse2);
+ pSrc_ptr += 64;
+ pDst_ptr += 64;
+ }
+ }
+
+ // Loads and dequantizes the next row of (already decoded) coefficients.
+ // Progressive images only.
+ void jpeg_decoder::load_next_row()
+ {
+ int i;
+ jpgd_block_coeff_t* p;
+ jpgd_quant_t* q;
+ int mcu_row, mcu_block, row_block = 0;
+ int component_num, component_id;
+ int block_x_mcu[JPGD_MAX_COMPONENTS];
+
+ memset(block_x_mcu, 0, JPGD_MAX_COMPONENTS * sizeof(int));
+
+ for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
+ {
+ int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;
+
+ for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
+ {
+ component_id = m_mcu_org[mcu_block];
+ if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ q = m_quant[m_comp_quant[component_id]];
+
+ p = m_pMCU_coefficients + 64 * mcu_block;
+
+ jpgd_block_coeff_t* pAC = coeff_buf_getp(m_ac_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
+ jpgd_block_coeff_t* pDC = coeff_buf_getp(m_dc_coeffs[component_id], block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
+ p[0] = pDC[0];
+ memcpy(&p[1], &pAC[1], 63 * sizeof(jpgd_block_coeff_t));
+
+ for (i = 63; i > 0; i--)
+ if (p[g_ZAG[i]])
+ break;
+
+ m_mcu_block_max_zag[mcu_block] = i + 1;
+
+ for (; i >= 0; i--)
+ if (p[g_ZAG[i]])
+ p[g_ZAG[i]] = static_cast<jpgd_block_coeff_t>(p[g_ZAG[i]] * q[i]);
+
+ row_block++;
+
+ if (m_comps_in_scan == 1)
+ block_x_mcu[component_id]++;
+ else
+ {
+ if (++block_x_mcu_ofs == m_comp_h_samp[component_id])
+ {
+ block_x_mcu_ofs = 0;
+
+ if (++block_y_mcu_ofs == m_comp_v_samp[component_id])
+ {
+ block_y_mcu_ofs = 0;
+
+ block_x_mcu[component_id] += m_comp_h_samp[component_id];
+ }
+ }
+ }
+ }
+
+ transform_mcu(mcu_row);
+ }
+
+ if (m_comps_in_scan == 1)
+ m_block_y_mcu[m_comp_list[0]]++;
+ else
+ {
+ for (component_num = 0; component_num < m_comps_in_scan; component_num++)
+ {
+ component_id = m_comp_list[component_num];
+
+ m_block_y_mcu[component_id] += m_comp_v_samp[component_id];
+ }
+ }
+ }
+
+ // Restart interval processing.
+ void jpeg_decoder::process_restart()
+ {
+ int i;
+ int c = 0;
+
+ // Align to a byte boundry
+ // FIXME: Is this really necessary? get_bits_no_markers() never reads in markers!
+ //get_bits_no_markers(m_bits_left & 7);
+
+ // Let's scan a little bit to find the marker, but not _too_ far.
+ // 1536 is a "fudge factor" that determines how much to scan.
+ for (i = 1536; i > 0; i--)
+ if (get_char() == 0xFF)
+ break;
+
+ if (i == 0)
+ stop_decoding(JPGD_BAD_RESTART_MARKER);
+
+ for (; i > 0; i--)
+ if ((c = get_char()) != 0xFF)
+ break;
+
+ if (i == 0)
+ stop_decoding(JPGD_BAD_RESTART_MARKER);
+
+ // Is it the expected marker? If not, something bad happened.
+ if (c != (m_next_restart_num + M_RST0))
+ stop_decoding(JPGD_BAD_RESTART_MARKER);
+
+ // Reset each component's DC prediction values.
+ memset(&m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));
+
+ m_eob_run = 0;
+
+ m_restarts_left = m_restart_interval;
+
+ m_next_restart_num = (m_next_restart_num + 1) & 7;
+
+ // Get the bit buffer going again...
+
+ m_bits_left = 16;
+ get_bits_no_markers(16);
+ get_bits_no_markers(16);
+ }
+
+ static inline int dequantize_ac(int c, int q) { c *= q; return c; }
+
+ // Decodes and dequantizes the next row of coefficients.
+ void jpeg_decoder::decode_next_row()
+ {
+ int row_block = 0;
+
+ for (int mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
+ {
+ if ((m_restart_interval) && (m_restarts_left == 0))
+ process_restart();
+
+ jpgd_block_coeff_t* p = m_pMCU_coefficients;
+ for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++, p += 64)
+ {
+ int component_id = m_mcu_org[mcu_block];
+ if (m_comp_quant[component_id] >= JPGD_MAX_QUANT_TABLES)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ jpgd_quant_t* q = m_quant[m_comp_quant[component_id]];
+
+ int r, s;
+ s = huff_decode(m_pHuff_tabs[m_comp_dc_tab[component_id]], r);
+ if (s >= 16)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ s = JPGD_HUFF_EXTEND(r, s);
+
+ m_last_dc_val[component_id] = (s += m_last_dc_val[component_id]);
+
+ p[0] = static_cast<jpgd_block_coeff_t>(s * q[0]);
+
+ int prev_num_set = m_mcu_block_max_zag[mcu_block];
+
+ huff_tables* pH = m_pHuff_tabs[m_comp_ac_tab[component_id]];
+
+ int k;
+ for (k = 1; k < 64; k++)
+ {
+ int extra_bits;
+ s = huff_decode(pH, extra_bits);
+
+ r = s >> 4;
+ s &= 15;
+
+ if (s)
+ {
+ if (r)
+ {
+ if ((k + r) > 63)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ if (k < prev_num_set)
+ {
+ int n = JPGD_MIN(r, prev_num_set - k);
+ int kt = k;
+ while (n--)
+ p[g_ZAG[kt++]] = 0;
+ }
+
+ k += r;
+ }
+
+ s = JPGD_HUFF_EXTEND(extra_bits, s);
+
+ if (k >= 64)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(dequantize_ac(s, q[k])); //s * q[k];
+ }
+ else
+ {
+ if (r == 15)
+ {
+ if ((k + 16) > 64)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ if (k < prev_num_set)
+ {
+ int n = JPGD_MIN(16, prev_num_set - k);
+ int kt = k;
+ while (n--)
+ {
+ if (kt > 63)
+ stop_decoding(JPGD_DECODE_ERROR);
+ p[g_ZAG[kt++]] = 0;
+ }
+ }
+
+ k += 16 - 1; // - 1 because the loop counter is k
+
+ if (p[g_ZAG[k & 63]] != 0)
+ stop_decoding(JPGD_DECODE_ERROR);
+ }
+ else
+ break;
+ }
+ }
+
+ if (k < prev_num_set)
+ {
+ int kt = k;
+ while (kt < prev_num_set)
+ p[g_ZAG[kt++]] = 0;
+ }
+
+ m_mcu_block_max_zag[mcu_block] = k;
+
+ row_block++;
+ }
+
+ transform_mcu(mcu_row);
+
+ m_restarts_left--;
+ }
+ }
+
+ // YCbCr H1V1 (1x1:1:1, 3 m_blocks per MCU) to RGB
+ void jpeg_decoder::H1V1Convert()
+ {
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d = m_pScan_line_0;
+ uint8* s = m_pSample_buf + row * 8;
+
+ for (int i = m_max_mcus_per_row; i > 0; i--)
+ {
+ for (int j = 0; j < 8; j++)
+ {
+ int y = s[j];
+ int cb = s[64 + j];
+ int cr = s[128 + j];
+
+ d[0] = clamp(y + m_crr[cr]);
+ d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16));
+ d[2] = clamp(y + m_cbb[cb]);
+ d[3] = 255;
+
+ d += 4;
+ }
+
+ s += 64 * 3;
+ }
+ }
+
+ // YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB
+ void jpeg_decoder::H2V1Convert()
+ {
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d0 = m_pScan_line_0;
+ uint8* y = m_pSample_buf + row * 8;
+ uint8* c = m_pSample_buf + 2 * 64 + row * 8;
+
+ for (int i = m_max_mcus_per_row; i > 0; i--)
+ {
+ for (int l = 0; l < 2; l++)
+ {
+ for (int j = 0; j < 4; j++)
+ {
+ int cb = c[0];
+ int cr = c[64];
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ int yy = y[j << 1];
+ d0[0] = clamp(yy + rc);
+ d0[1] = clamp(yy + gc);
+ d0[2] = clamp(yy + bc);
+ d0[3] = 255;
+
+ yy = y[(j << 1) + 1];
+ d0[4] = clamp(yy + rc);
+ d0[5] = clamp(yy + gc);
+ d0[6] = clamp(yy + bc);
+ d0[7] = 255;
+
+ d0 += 8;
+
+ c++;
+ }
+ y += 64;
+ }
+
+ y += 64 * 4 - 64 * 2;
+ c += 64 * 4 - 8;
+ }
+ }
+
+ // YCbCr H2V1 (2x1:1:1, 4 m_blocks per MCU) to RGB
+ void jpeg_decoder::H2V1ConvertFiltered()
+ {
+ const uint BLOCKS_PER_MCU = 4;
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d0 = m_pScan_line_0;
+
+ const int half_image_x_size = (m_image_x_size >> 1) - 1;
+ const int row_x8 = row * 8;
+
+ for (int x = 0; x < m_image_x_size; x++)
+ {
+ int y = m_pSample_buf[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + row_x8)];
+
+ int c_x0 = (x - 1) >> 1;
+ int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);
+ c_x0 = JPGD_MAX(c_x0, 0);
+
+ int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7) + row_x8 + 128;
+ int cb0 = m_pSample_buf[check_sample_buf_ofs(a)];
+ int cr0 = m_pSample_buf[check_sample_buf_ofs(a + 64)];
+
+ int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7) + row_x8 + 128;
+ int cb1 = m_pSample_buf[check_sample_buf_ofs(b)];
+ int cr1 = m_pSample_buf[check_sample_buf_ofs(b + 64)];
+
+ int w0 = (x & 1) ? 3 : 1;
+ int w1 = (x & 1) ? 1 : 3;
+
+ int cb = (cb0 * w0 + cb1 * w1 + 2) >> 2;
+ int cr = (cr0 * w0 + cr1 * w1 + 2) >> 2;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d0[0] = clamp(y + rc);
+ d0[1] = clamp(y + gc);
+ d0[2] = clamp(y + bc);
+ d0[3] = 255;
+
+ d0 += 4;
+ }
+ }
+
+ // YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB
+ void jpeg_decoder::H1V2Convert()
+ {
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d0 = m_pScan_line_0;
+ uint8* d1 = m_pScan_line_1;
+ uint8* y;
+ uint8* c;
+
+ if (row < 8)
+ y = m_pSample_buf + row * 8;
+ else
+ y = m_pSample_buf + 64 * 1 + (row & 7) * 8;
+
+ c = m_pSample_buf + 64 * 2 + (row >> 1) * 8;
+
+ for (int i = m_max_mcus_per_row; i > 0; i--)
+ {
+ for (int j = 0; j < 8; j++)
+ {
+ int cb = c[0 + j];
+ int cr = c[64 + j];
int rc = m_crr[cr];
int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
int bc = m_cbb[cb];
int yy = y[j];
- d0[0] = clamp(yy+rc);
- d0[1] = clamp(yy+gc);
- d0[2] = clamp(yy+bc);
+ d0[0] = clamp(yy + rc);
+ d0[1] = clamp(yy + gc);
+ d0[2] = clamp(yy + bc);
d0[3] = 255;
- yy = y[j+1];
- d0[4] = clamp(yy+rc);
- d0[5] = clamp(yy+gc);
- d0[6] = clamp(yy+bc);
- d0[7] = 255;
-
- yy = y[j+8];
- d1[0] = clamp(yy+rc);
- d1[1] = clamp(yy+gc);
- d1[2] = clamp(yy+bc);
+ yy = y[8 + j];
+ d1[0] = clamp(yy + rc);
+ d1[1] = clamp(yy + gc);
+ d1[2] = clamp(yy + bc);
d1[3] = 255;
- yy = y[j+8+1];
- d1[4] = clamp(yy+rc);
- d1[5] = clamp(yy+gc);
- d1[6] = clamp(yy+bc);
- d1[7] = 255;
+ d0 += 4;
+ d1 += 4;
+ }
+
+ y += 64 * 4;
+ c += 64 * 4;
+ }
+ }
+
+ // YCbCr H2V1 (1x2:1:1, 4 m_blocks per MCU) to RGB
+ void jpeg_decoder::H1V2ConvertFiltered()
+ {
+ const uint BLOCKS_PER_MCU = 4;
+ int y = m_image_y_size - m_total_lines_left;
+ int row = y & 15;
+
+ const int half_image_y_size = (m_image_y_size >> 1) - 1;
+
+ uint8* d0 = m_pScan_line_0;
+
+ const int w0 = (row & 1) ? 3 : 1;
+ const int w1 = (row & 1) ? 1 : 3;
+
+ int c_y0 = (y - 1) >> 1;
+ int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size);
+
+ const uint8_t* p_YSamples = m_pSample_buf;
+ const uint8_t* p_C0Samples = m_pSample_buf;
+ if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1))
+ {
+ assert(y > 0);
+ assert(m_sample_buf_prev_valid);
+
+ if ((row & 15) == 15)
+ p_YSamples = m_pSample_buf_prev;
+
+ p_C0Samples = m_pSample_buf_prev;
+ }
+
+ const int y_sample_base_ofs = ((row & 8) ? 64 : 0) + (row & 7) * 8;
+ const int y0_base = (c_y0 & 7) * 8 + 128;
+ const int y1_base = (c_y1 & 7) * 8 + 128;
+
+ for (int x = 0; x < m_image_x_size; x++)
+ {
+ const int base_ofs = (x >> 3) * BLOCKS_PER_MCU * 64 + (x & 7);
+
+ int y_sample = p_YSamples[check_sample_buf_ofs(base_ofs + y_sample_base_ofs)];
+
+ int a = base_ofs + y0_base;
+ int cb0_sample = p_C0Samples[check_sample_buf_ofs(a)];
+ int cr0_sample = p_C0Samples[check_sample_buf_ofs(a + 64)];
+
+ int b = base_ofs + y1_base;
+ int cb1_sample = m_pSample_buf[check_sample_buf_ofs(b)];
+ int cr1_sample = m_pSample_buf[check_sample_buf_ofs(b + 64)];
+
+ int cb = (cb0_sample * w0 + cb1_sample * w1 + 2) >> 2;
+ int cr = (cr0_sample * w0 + cr1_sample * w1 + 2) >> 2;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d0[0] = clamp(y_sample + rc);
+ d0[1] = clamp(y_sample + gc);
+ d0[2] = clamp(y_sample + bc);
+ d0[3] = 255;
+
+ d0 += 4;
+ }
+ }
+
+ // YCbCr H2V2 (2x2:1:1, 6 m_blocks per MCU) to RGB
+ void jpeg_decoder::H2V2Convert()
+ {
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d0 = m_pScan_line_0;
+ uint8* d1 = m_pScan_line_1;
+ uint8* y;
+ uint8* c;
- d0 += 8;
- d1 += 8;
+ if (row < 8)
+ y = m_pSample_buf + row * 8;
+ else
+ y = m_pSample_buf + 64 * 2 + (row & 7) * 8;
- c++;
+ c = m_pSample_buf + 64 * 4 + (row >> 1) * 8;
+
+ for (int i = m_max_mcus_per_row; i > 0; i--)
+ {
+ for (int l = 0; l < 2; l++)
+ {
+ for (int j = 0; j < 8; j += 2)
+ {
+ int cb = c[0];
+ int cr = c[64];
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ int yy = y[j];
+ d0[0] = clamp(yy + rc);
+ d0[1] = clamp(yy + gc);
+ d0[2] = clamp(yy + bc);
+ d0[3] = 255;
+
+ yy = y[j + 1];
+ d0[4] = clamp(yy + rc);
+ d0[5] = clamp(yy + gc);
+ d0[6] = clamp(yy + bc);
+ d0[7] = 255;
+
+ yy = y[j + 8];
+ d1[0] = clamp(yy + rc);
+ d1[1] = clamp(yy + gc);
+ d1[2] = clamp(yy + bc);
+ d1[3] = 255;
+
+ yy = y[j + 8 + 1];
+ d1[4] = clamp(yy + rc);
+ d1[5] = clamp(yy + gc);
+ d1[6] = clamp(yy + bc);
+ d1[7] = 255;
+
+ d0 += 8;
+ d1 += 8;
+
+ c++;
+ }
+ y += 64;
}
- y += 64;
- }
-
- y += 64*6 - 64*2;
- c += 64*6 - 8;
- }
-}
-
-// Y (1 block per MCU) to 8-bit grayscale
-void jpeg_decoder::gray_convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
- uint8 *d = m_pScan_line_0;
- uint8 *s = m_pSample_buf + row * 8;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- *(uint *)d = *(uint *)s;
- *(uint *)(&d[4]) = *(uint *)(&s[4]);
-
- s += 64;
- d += 8;
- }
-}
-
-void jpeg_decoder::expanded_convert()
-{
- int row = m_max_mcu_y_size - m_mcu_lines_left;
-
- uint8* Py = m_pSample_buf + (row / 8) * 64 * m_comp_h_samp[0] + (row & 7) * 8;
-
- uint8* d = m_pScan_line_0;
-
- for (int i = m_max_mcus_per_row; i > 0; i--)
- {
- for (int k = 0; k < m_max_mcu_x_size; k += 8)
- {
- const int Y_ofs = k * 8;
- const int Cb_ofs = Y_ofs + 64 * m_expanded_blocks_per_component;
- const int Cr_ofs = Y_ofs + 64 * m_expanded_blocks_per_component * 2;
- for (int j = 0; j < 8; j++)
- {
- int y = Py[Y_ofs + j];
- int cb = Py[Cb_ofs + j];
- int cr = Py[Cr_ofs + j];
-
- d[0] = clamp(y + m_crr[cr]);
- d[1] = clamp(y + ((m_crg[cr] + m_cbg[cb]) >> 16));
- d[2] = clamp(y + m_cbb[cb]);
- d[3] = 255;
-
- d += 4;
- }
- }
-
- Py += 64 * m_expanded_blocks_per_mcu;
- }
-}
-
-// Find end of image (EOI) marker, so we can return to the user the exact size of the input stream.
-void jpeg_decoder::find_eoi()
-{
- if (!m_progressive_flag)
- {
- // Attempt to read the EOI marker.
- //get_bits_no_markers(m_bits_left & 7);
-
- // Prime the bit buffer
- m_bits_left = 16;
- get_bits(16);
- get_bits(16);
-
- // The next marker _should_ be EOI
- process_markers();
- }
-
- m_total_bytes_read -= m_in_buf_left;
-}
-
-int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len)
-{
- if ((m_error_code) || (!m_ready_flag))
- return JPGD_FAILED;
-
- if (m_total_lines_left == 0)
- return JPGD_DONE;
-
- if (m_mcu_lines_left == 0)
- {
- if (setjmp(m_jmp_state))
- return JPGD_FAILED;
-
- if (m_progressive_flag)
- load_next_row();
- else
- decode_next_row();
-
- // Find the EOI marker if that was the last row.
- if (m_total_lines_left <= m_max_mcu_y_size)
- find_eoi();
-
- m_mcu_lines_left = m_max_mcu_y_size;
- }
-
- if (m_freq_domain_chroma_upsample)
- {
- expanded_convert();
- *pScan_line = m_pScan_line_0;
- }
- else
- {
- switch (m_scan_type)
- {
- case JPGD_YH2V2:
- {
- if ((m_mcu_lines_left & 1) == 0)
- {
- H2V2Convert();
- *pScan_line = m_pScan_line_0;
- }
- else
- *pScan_line = m_pScan_line_1;
-
- break;
- }
- case JPGD_YH2V1:
- {
- H2V1Convert();
- *pScan_line = m_pScan_line_0;
- break;
- }
- case JPGD_YH1V2:
- {
- if ((m_mcu_lines_left & 1) == 0)
- {
- H1V2Convert();
- *pScan_line = m_pScan_line_0;
- }
- else
- *pScan_line = m_pScan_line_1;
-
- break;
- }
- case JPGD_YH1V1:
- {
- H1V1Convert();
- *pScan_line = m_pScan_line_0;
- break;
- }
- case JPGD_GRAYSCALE:
- {
- gray_convert();
- *pScan_line = m_pScan_line_0;
-
- break;
- }
- }
- }
-
- *pScan_line_len = m_real_dest_bytes_per_scan_line;
-
- m_mcu_lines_left--;
- m_total_lines_left--;
-
- return JPGD_SUCCESS;
-}
-
-// Creates the tables needed for efficient Huffman decoding.
-void jpeg_decoder::make_huff_table(int index, huff_tables *pH)
-{
- int p, i, l, si;
- uint8 huffsize[257];
- uint huffcode[257];
- uint code;
- uint subtree;
- int code_size;
- int lastp;
- int nextfreeentry;
- int currententry;
-
- pH->ac_table = m_huff_ac[index] != 0;
-
- p = 0;
-
- for (l = 1; l <= 16; l++)
- {
- for (i = 1; i <= m_huff_num[index][l]; i++)
- {
- JPGD_ASSERT(p < 257);
- huffsize[p++] = static_cast<uint8>(l);
- }
- }
-
- huffsize[p] = 0;
-
- lastp = p;
-
- code = 0;
- si = huffsize[0];
- p = 0;
-
- while (huffsize[p])
- {
- while (huffsize[p] == si)
- {
- JPGD_ASSERT(p < 257);
- huffcode[p++] = code;
- code++;
- }
-
- code <<= 1;
- si++;
- }
-
- memset(pH->look_up, 0, sizeof(pH->look_up));
- memset(pH->look_up2, 0, sizeof(pH->look_up2));
- memset(pH->tree, 0, sizeof(pH->tree));
- memset(pH->code_size, 0, sizeof(pH->code_size));
-
- nextfreeentry = -1;
-
- p = 0;
-
- while (p < lastp)
- {
- i = m_huff_val[index][p];
- code = huffcode[p];
- code_size = huffsize[p];
-
- pH->code_size[i] = static_cast<uint8>(code_size);
-
- if (code_size <= 8)
- {
- code <<= (8 - code_size);
-
- for (l = 1 << (8 - code_size); l > 0; l--)
- {
- JPGD_ASSERT(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
- JPGD_ASSERT(code < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
-
- pH->look_up[code] = i;
-
- bool has_extrabits = false;
- int extra_bits = 0;
- int num_extra_bits = i & 15;
-
- int bits_to_fetch = code_size;
- if (num_extra_bits)
- {
- int total_codesize = code_size + num_extra_bits;
- if (total_codesize <= 8)
- {
- has_extrabits = true;
- extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize));
- JPGD_ASSERT(extra_bits <= 0x7FFF);
- bits_to_fetch += num_extra_bits;
- }
- }
-
- if (!has_extrabits)
- pH->look_up2[code] = i | (bits_to_fetch << 8);
- else
- pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8);
-
- code++;
- }
- }
- else
- {
- subtree = (code >> (code_size - 8)) & 0xFF;
-
- currententry = pH->look_up[subtree];
-
- if (currententry == 0)
- {
- pH->look_up[subtree] = currententry = nextfreeentry;
- pH->look_up2[subtree] = currententry = nextfreeentry;
-
- nextfreeentry -= 2;
- }
-
- code <<= (16 - (code_size - 8));
-
- for (l = code_size; l > 9; l--)
- {
- if ((code & 0x8000) == 0)
- currententry--;
-
- unsigned int idx = -currententry - 1;
- JPGD_ASSERT(idx < JPGD_HUFF_TREE_MAX_LENGTH);
- if (pH->tree[idx] == 0)
- {
- pH->tree[idx] = nextfreeentry;
-
- currententry = nextfreeentry;
-
- nextfreeentry -= 2;
- }
- else {
- currententry = pH->tree[idx];
- }
-
- code <<= 1;
- }
-
- if ((code & 0x8000) == 0)
- currententry--;
-
- pH->tree[-currententry - 1] = i;
- }
-
- p++;
- }
-}
-
-// Verifies the quantization tables needed for this scan are available.
-void jpeg_decoder::check_quant_tables()
-{
- for (int i = 0; i < m_comps_in_scan; i++)
- if (m_quant[m_comp_quant[m_comp_list[i]]] == NULL)
- stop_decoding(JPGD_UNDEFINED_QUANT_TABLE);
-}
-
-// Verifies that all the Huffman tables needed for this scan are available.
-void jpeg_decoder::check_huff_tables()
-{
- for (int i = 0; i < m_comps_in_scan; i++)
- {
- if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == NULL))
- stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);
-
- if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == NULL))
- stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);
- }
-
- for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++)
- if (m_huff_num[i])
- {
- if (!m_pHuff_tabs[i])
- m_pHuff_tabs[i] = (huff_tables *)alloc(sizeof(huff_tables));
-
- make_huff_table(i, m_pHuff_tabs[i]);
- }
-}
-
-// Determines the component order inside each MCU.
-// Also calcs how many MCU's are on each row, etc.
-void jpeg_decoder::calc_mcu_block_order()
-{
- int component_num, component_id;
- int max_h_samp = 0, max_v_samp = 0;
-
- for (component_id = 0; component_id < m_comps_in_frame; component_id++)
- {
- if (m_comp_h_samp[component_id] > max_h_samp)
- max_h_samp = m_comp_h_samp[component_id];
-
- if (m_comp_v_samp[component_id] > max_v_samp)
- max_v_samp = m_comp_v_samp[component_id];
- }
-
- for (component_id = 0; component_id < m_comps_in_frame; component_id++)
- {
- m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8;
- m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8;
- }
-
- if (m_comps_in_scan == 1)
- {
- m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]];
- m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]];
- }
- else
- {
- m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp;
- m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp;
- }
-
- if (m_comps_in_scan == 1)
- {
- m_mcu_org[0] = m_comp_list[0];
-
- m_blocks_per_mcu = 1;
- }
- else
- {
- m_blocks_per_mcu = 0;
-
- for (component_num = 0; component_num < m_comps_in_scan; component_num++)
- {
- int num_blocks;
-
- component_id = m_comp_list[component_num];
-
- num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id];
-
- while (num_blocks--)
- m_mcu_org[m_blocks_per_mcu++] = component_id;
- }
- }
-}
-
-// Starts a new scan.
-int jpeg_decoder::init_scan()
-{
- if (!locate_sos_marker())
- return JPGD_FALSE;
-
- calc_mcu_block_order();
-
- check_huff_tables();
-
- check_quant_tables();
-
- memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));
-
- m_eob_run = 0;
-
- if (m_restart_interval)
- {
- m_restarts_left = m_restart_interval;
- m_next_restart_num = 0;
- }
-
- fix_in_buffer();
-
- return JPGD_TRUE;
-}
-
-// Starts a frame. Determines if the number of components or sampling factors
-// are supported.
-void jpeg_decoder::init_frame()
-{
- int i;
-
- if (m_comps_in_frame == 1)
- {
- if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1))
- stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
-
- m_scan_type = JPGD_GRAYSCALE;
- m_max_blocks_per_mcu = 1;
- m_max_mcu_x_size = 8;
- m_max_mcu_y_size = 8;
- }
- else if (m_comps_in_frame == 3)
- {
- if ( ((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) ||
- ((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1)) )
- stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
-
- if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1))
- {
- m_scan_type = JPGD_YH1V1;
-
- m_max_blocks_per_mcu = 3;
- m_max_mcu_x_size = 8;
- m_max_mcu_y_size = 8;
- }
- else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1))
- {
- m_scan_type = JPGD_YH2V1;
- m_max_blocks_per_mcu = 4;
- m_max_mcu_x_size = 16;
- m_max_mcu_y_size = 8;
- }
- else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2))
- {
- m_scan_type = JPGD_YH1V2;
- m_max_blocks_per_mcu = 4;
- m_max_mcu_x_size = 8;
- m_max_mcu_y_size = 16;
- }
- else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2))
- {
- m_scan_type = JPGD_YH2V2;
- m_max_blocks_per_mcu = 6;
- m_max_mcu_x_size = 16;
- m_max_mcu_y_size = 16;
- }
- else
- stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
- }
- else
- stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);
-
- m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size;
- m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size;
-
- // These values are for the *destination* pixels: after conversion.
- if (m_scan_type == JPGD_GRAYSCALE)
- m_dest_bytes_per_pixel = 1;
- else
- m_dest_bytes_per_pixel = 4;
-
- m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel;
-
- m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel);
-
- // Initialize two scan line buffers.
- m_pScan_line_0 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true);
- if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2))
- m_pScan_line_1 = (uint8 *)alloc(m_dest_bytes_per_scan_line, true);
-
- m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu;
-
- // Should never happen
- if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW)
- stop_decoding(JPGD_ASSERTION_ERROR);
-
- // Allocate the coefficient buffer, enough for one MCU
- m_pMCU_coefficients = (jpgd_block_t*)alloc(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_t));
-
- for (i = 0; i < m_max_blocks_per_mcu; i++)
- m_mcu_block_max_zag[i] = 64;
-
- m_expanded_blocks_per_component = m_comp_h_samp[0] * m_comp_v_samp[0];
- m_expanded_blocks_per_mcu = m_expanded_blocks_per_component * m_comps_in_frame;
- m_expanded_blocks_per_row = m_max_mcus_per_row * m_expanded_blocks_per_mcu;
- // Freq. domain chroma upsampling is only supported for H2V2 subsampling factor (the most common one I've seen).
- m_freq_domain_chroma_upsample = false;
-#if JPGD_SUPPORT_FREQ_DOMAIN_UPSAMPLING
- m_freq_domain_chroma_upsample = (m_expanded_blocks_per_mcu == 4*3);
-#endif
- if (m_freq_domain_chroma_upsample)
- m_pSample_buf = (uint8 *)alloc(m_expanded_blocks_per_row * 64);
- else
- m_pSample_buf = (uint8 *)alloc(m_max_blocks_per_row * 64);
-
- m_total_lines_left = m_image_y_size;
-
- m_mcu_lines_left = 0;
-
- create_look_ups();
-}
-
-// The coeff_buf series of methods originally stored the coefficients
-// into a "virtual" file which was located in EMS, XMS, or a disk file. A cache
-// was used to make this process more efficient. Now, we can store the entire
-// thing in RAM.
-jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y)
-{
- coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf));
-
- cb->block_num_x = block_num_x;
- cb->block_num_y = block_num_y;
- cb->block_len_x = block_len_x;
- cb->block_len_y = block_len_y;
- cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_t);
- cb->pData = (uint8 *)alloc(cb->block_size * block_num_x * block_num_y, true);
- return cb;
-}
-
-inline jpgd_block_t *jpeg_decoder::coeff_buf_getp(coeff_buf *cb, int block_x, int block_y)
-{
- JPGD_ASSERT((block_x < cb->block_num_x) && (block_y < cb->block_num_y));
- return (jpgd_block_t *)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x));
-}
-
-// The following methods decode the various types of m_blocks encountered
-// in progressively encoded images.
-void jpeg_decoder::decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y)
-{
- int s, r;
- jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);
-
- if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0)
- {
- r = pD->get_bits_no_markers(s);
- s = JPGD_HUFF_EXTEND(r, s);
- }
-
- pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]);
-
- p[0] = static_cast<jpgd_block_t>(s << pD->m_successive_low);
-}
-
-void jpeg_decoder::decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y)
-{
- if (pD->get_bits_no_markers(1))
- {
- jpgd_block_t *p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);
-
- p[0] |= (1 << pD->m_successive_low);
- }
-}
-
-void jpeg_decoder::decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y)
-{
- int k, s, r;
-
- if (pD->m_eob_run)
- {
- pD->m_eob_run--;
- return;
- }
-
- jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
-
- for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++)
- {
- unsigned int idx = pD->m_comp_ac_tab[component_id];
- JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES);
- s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
-
- r = s >> 4;
- s &= 15;
-
- if (s)
- {
- if ((k += r) > 63)
- pD->stop_decoding(JPGD_DECODE_ERROR);
-
- r = pD->get_bits_no_markers(s);
- s = JPGD_HUFF_EXTEND(r, s);
-
- p[g_ZAG[k]] = static_cast<jpgd_block_t>(s << pD->m_successive_low);
- }
- else
- {
- if (r == 15)
- {
- if ((k += 15) > 63)
- pD->stop_decoding(JPGD_DECODE_ERROR);
- }
- else
- {
- pD->m_eob_run = 1 << r;
-
- if (r)
- pD->m_eob_run += pD->get_bits_no_markers(r);
-
- pD->m_eob_run--;
-
- break;
- }
- }
- }
-}
-
-void jpeg_decoder::decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y)
-{
- int s, k, r;
- int p1 = 1 << pD->m_successive_low;
- int m1 = (-1) << pD->m_successive_low;
- jpgd_block_t *p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
- JPGD_ASSERT(pD->m_spectral_end <= 63);
-
- k = pD->m_spectral_start;
-
- if (pD->m_eob_run == 0)
- {
- for ( ; k <= pD->m_spectral_end; k++)
- {
- unsigned int idx = pD->m_comp_ac_tab[component_id];
- JPGD_ASSERT(idx < JPGD_MAX_HUFF_TABLES);
- s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
-
- r = s >> 4;
- s &= 15;
-
- if (s)
- {
- if (s != 1)
- pD->stop_decoding(JPGD_DECODE_ERROR);
-
- if (pD->get_bits_no_markers(1))
- s = p1;
- else
- s = m1;
- }
- else
- {
- if (r != 15)
- {
- pD->m_eob_run = 1 << r;
-
- if (r)
- pD->m_eob_run += pD->get_bits_no_markers(r);
-
- break;
- }
- }
-
- do
- {
- jpgd_block_t *this_coef = p + g_ZAG[k & 63];
-
- if (*this_coef != 0)
- {
- if (pD->get_bits_no_markers(1))
- {
- if ((*this_coef & p1) == 0)
- {
- if (*this_coef >= 0)
- *this_coef = static_cast<jpgd_block_t>(*this_coef + p1);
- else
- *this_coef = static_cast<jpgd_block_t>(*this_coef + m1);
- }
- }
- }
- else
- {
- if (--r < 0)
- break;
- }
-
- k++;
-
- } while (k <= pD->m_spectral_end);
-
- if ((s) && (k < 64))
- {
- p[g_ZAG[k]] = static_cast<jpgd_block_t>(s);
- }
- }
- }
-
- if (pD->m_eob_run > 0)
- {
- for ( ; k <= pD->m_spectral_end; k++)
- {
- jpgd_block_t *this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis
-
- if (*this_coef != 0)
- {
- if (pD->get_bits_no_markers(1))
- {
- if ((*this_coef & p1) == 0)
- {
- if (*this_coef >= 0)
- *this_coef = static_cast<jpgd_block_t>(*this_coef + p1);
- else
- *this_coef = static_cast<jpgd_block_t>(*this_coef + m1);
- }
- }
- }
- }
-
- pD->m_eob_run--;
- }
-}
-
-// Decode a scan in a progressively encoded image.
-void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func)
-{
- int mcu_row, mcu_col, mcu_block;
- int block_x_mcu[JPGD_MAX_COMPONENTS], m_block_y_mcu[JPGD_MAX_COMPONENTS];
-
- memset(m_block_y_mcu, 0, sizeof(m_block_y_mcu));
-
- for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++)
- {
- int component_num, component_id;
-
- memset(block_x_mcu, 0, sizeof(block_x_mcu));
-
- for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
- {
- int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;
-
- if ((m_restart_interval) && (m_restarts_left == 0))
- process_restart();
-
- for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
- {
- component_id = m_mcu_org[mcu_block];
-
- decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, m_block_y_mcu[component_id] + block_y_mcu_ofs);
-
- if (m_comps_in_scan == 1)
- block_x_mcu[component_id]++;
- else
- {
- if (++block_x_mcu_ofs == m_comp_h_samp[component_id])
- {
- block_x_mcu_ofs = 0;
-
- if (++block_y_mcu_ofs == m_comp_v_samp[component_id])
- {
- block_y_mcu_ofs = 0;
- block_x_mcu[component_id] += m_comp_h_samp[component_id];
- }
- }
- }
- }
-
- m_restarts_left--;
- }
-
- if (m_comps_in_scan == 1)
- m_block_y_mcu[m_comp_list[0]]++;
- else
- {
- for (component_num = 0; component_num < m_comps_in_scan; component_num++)
- {
- component_id = m_comp_list[component_num];
- m_block_y_mcu[component_id] += m_comp_v_samp[component_id];
- }
- }
- }
-}
-
-// Decode a progressively encoded image.
-void jpeg_decoder::init_progressive()
-{
- int i;
-
- if (m_comps_in_frame == 4)
- stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);
-
- // Allocate the coefficient buffers.
- for (i = 0; i < m_comps_in_frame; i++)
- {
- m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1);
- m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8);
- }
-
- for ( ; ; )
- {
- int dc_only_scan, refinement_scan;
- pDecode_block_func decode_block_func;
-
- if (!init_scan())
- break;
-
- dc_only_scan = (m_spectral_start == 0);
- refinement_scan = (m_successive_high != 0);
-
- if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63))
- stop_decoding(JPGD_BAD_SOS_SPECTRAL);
-
- if (dc_only_scan)
- {
- if (m_spectral_end)
- stop_decoding(JPGD_BAD_SOS_SPECTRAL);
- }
- else if (m_comps_in_scan != 1) /* AC scans can only contain one component */
- stop_decoding(JPGD_BAD_SOS_SPECTRAL);
-
- if ((refinement_scan) && (m_successive_low != m_successive_high - 1))
- stop_decoding(JPGD_BAD_SOS_SUCCESSIVE);
-
- if (dc_only_scan)
- {
- if (refinement_scan)
- decode_block_func = decode_block_dc_refine;
- else
- decode_block_func = decode_block_dc_first;
- }
- else
- {
- if (refinement_scan)
- decode_block_func = decode_block_ac_refine;
- else
- decode_block_func = decode_block_ac_first;
- }
-
- decode_scan(decode_block_func);
-
- m_bits_left = 16;
- get_bits(16);
- get_bits(16);
- }
-
- m_comps_in_scan = m_comps_in_frame;
-
- for (i = 0; i < m_comps_in_frame; i++)
- m_comp_list[i] = i;
-
- calc_mcu_block_order();
-}
-
-void jpeg_decoder::init_sequential()
-{
- if (!init_scan())
- stop_decoding(JPGD_UNEXPECTED_MARKER);
-}
-
-void jpeg_decoder::decode_start()
-{
- init_frame();
-
- if (m_progressive_flag)
- init_progressive();
- else
- init_sequential();
-}
-
-void jpeg_decoder::decode_init(jpeg_decoder_stream *pStream)
-{
- init(pStream);
- locate_sof_marker();
-}
-
-jpeg_decoder::jpeg_decoder(jpeg_decoder_stream *pStream)
-{
- if (setjmp(m_jmp_state))
- return;
- decode_init(pStream);
-}
-
-int jpeg_decoder::begin_decoding()
-{
- if (m_ready_flag)
- return JPGD_SUCCESS;
-
- if (m_error_code)
- return JPGD_FAILED;
-
- if (setjmp(m_jmp_state))
- return JPGD_FAILED;
-
- decode_start();
-
- m_ready_flag = true;
-
- return JPGD_SUCCESS;
-}
-
-jpeg_decoder::~jpeg_decoder()
-{
- free_all_blocks();
-}
-
-jpeg_decoder_file_stream::jpeg_decoder_file_stream()
-{
- m_pFile = NULL;
- m_eof_flag = false;
- m_error_flag = false;
-}
-
-void jpeg_decoder_file_stream::close()
-{
- if (m_pFile)
- {
- fclose(m_pFile);
- m_pFile = NULL;
- }
-
- m_eof_flag = false;
- m_error_flag = false;
-}
-
-jpeg_decoder_file_stream::~jpeg_decoder_file_stream()
-{
- close();
-}
-
-bool jpeg_decoder_file_stream::open(const char *Pfilename)
-{
- close();
-
- m_eof_flag = false;
- m_error_flag = false;
+ y += 64 * 6 - 64 * 2;
+ c += 64 * 6 - 8;
+ }
+ }
+
+ uint32_t jpeg_decoder::H2V2ConvertFiltered()
+ {
+ const uint BLOCKS_PER_MCU = 6;
+ int y = m_image_y_size - m_total_lines_left;
+ int row = y & 15;
+
+ const int half_image_y_size = (m_image_y_size >> 1) - 1;
+
+ uint8* d0 = m_pScan_line_0;
+
+ int c_y0 = (y - 1) >> 1;
+ int c_y1 = JPGD_MIN(c_y0 + 1, half_image_y_size);
+
+ const uint8_t* p_YSamples = m_pSample_buf;
+ const uint8_t* p_C0Samples = m_pSample_buf;
+ if ((c_y0 >= 0) && (((row & 15) == 0) || ((row & 15) == 15)) && (m_total_lines_left > 1))
+ {
+ assert(y > 0);
+ assert(m_sample_buf_prev_valid);
+
+ if ((row & 15) == 15)
+ p_YSamples = m_pSample_buf_prev;
+
+ p_C0Samples = m_pSample_buf_prev;
+ }
+
+ const int y_sample_base_ofs = ((row & 8) ? 128 : 0) + (row & 7) * 8;
+ const int y0_base = (c_y0 & 7) * 8 + 256;
+ const int y1_base = (c_y1 & 7) * 8 + 256;
+
+ const int half_image_x_size = (m_image_x_size >> 1) - 1;
+
+ static const uint8_t s_muls[2][2][4] =
+ {
+ { { 1, 3, 3, 9 }, { 3, 9, 1, 3 }, },
+ { { 3, 1, 9, 3 }, { 9, 3, 3, 1 } }
+ };
+
+ if (((row & 15) >= 1) && ((row & 15) <= 14))
+ {
+ assert((row & 1) == 1);
+ assert(((y + 1 - 1) >> 1) == c_y0);
+
+ assert(p_YSamples == m_pSample_buf);
+ assert(p_C0Samples == m_pSample_buf);
+
+ uint8* d1 = m_pScan_line_1;
+ const int y_sample_base_ofs1 = (((row + 1) & 8) ? 128 : 0) + ((row + 1) & 7) * 8;
+
+ for (int x = 0; x < m_image_x_size; x++)
+ {
+ int k = (x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7);
+ int y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)];
+ int y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)];
+
+ int c_x0 = (x - 1) >> 1;
+ int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);
+ c_x0 = JPGD_MAX(c_x0, 0);
+
+ int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7);
+ int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)];
+ int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)];
+
+ int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)];
+ int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)];
+
+ int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7);
+ int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)];
+ int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)];
+
+ int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)];
+ int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)];
+
+ {
+ const uint8_t* pMuls = &s_muls[row & 1][x & 1][0];
+ int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;
+ int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d0[0] = clamp(y_sample0 + rc);
+ d0[1] = clamp(y_sample0 + gc);
+ d0[2] = clamp(y_sample0 + bc);
+ d0[3] = 255;
+
+ d0 += 4;
+ }
+
+ {
+ const uint8_t* pMuls = &s_muls[(row + 1) & 1][x & 1][0];
+ int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;
+ int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d1[0] = clamp(y_sample1 + rc);
+ d1[1] = clamp(y_sample1 + gc);
+ d1[2] = clamp(y_sample1 + bc);
+ d1[3] = 255;
+
+ d1 += 4;
+ }
+
+ if (((x & 1) == 1) && (x < m_image_x_size - 1))
+ {
+ const int nx = x + 1;
+ assert(c_x0 == (nx - 1) >> 1);
+
+ k = (nx >> 4) * BLOCKS_PER_MCU * 64 + ((nx & 8) ? 64 : 0) + (nx & 7);
+ y_sample0 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs)];
+ y_sample1 = p_YSamples[check_sample_buf_ofs(k + y_sample_base_ofs1)];
+
+ {
+ const uint8_t* pMuls = &s_muls[row & 1][nx & 1][0];
+ int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;
+ int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d0[0] = clamp(y_sample0 + rc);
+ d0[1] = clamp(y_sample0 + gc);
+ d0[2] = clamp(y_sample0 + bc);
+ d0[3] = 255;
+
+ d0 += 4;
+ }
+
+ {
+ const uint8_t* pMuls = &s_muls[(row + 1) & 1][nx & 1][0];
+ int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;
+ int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d1[0] = clamp(y_sample1 + rc);
+ d1[1] = clamp(y_sample1 + gc);
+ d1[2] = clamp(y_sample1 + bc);
+ d1[3] = 255;
+
+ d1 += 4;
+ }
+
+ ++x;
+ }
+ }
+
+ return 2;
+ }
+ else
+ {
+ for (int x = 0; x < m_image_x_size; x++)
+ {
+ int y_sample = p_YSamples[check_sample_buf_ofs((x >> 4) * BLOCKS_PER_MCU * 64 + ((x & 8) ? 64 : 0) + (x & 7) + y_sample_base_ofs)];
+
+ int c_x0 = (x - 1) >> 1;
+ int c_x1 = JPGD_MIN(c_x0 + 1, half_image_x_size);
+ c_x0 = JPGD_MAX(c_x0, 0);
+
+ int a = (c_x0 >> 3) * BLOCKS_PER_MCU * 64 + (c_x0 & 7);
+ int cb00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base)];
+ int cr00_sample = p_C0Samples[check_sample_buf_ofs(a + y0_base + 64)];
+
+ int cb01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base)];
+ int cr01_sample = m_pSample_buf[check_sample_buf_ofs(a + y1_base + 64)];
+
+ int b = (c_x1 >> 3) * BLOCKS_PER_MCU * 64 + (c_x1 & 7);
+ int cb10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base)];
+ int cr10_sample = p_C0Samples[check_sample_buf_ofs(b + y0_base + 64)];
+
+ int cb11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base)];
+ int cr11_sample = m_pSample_buf[check_sample_buf_ofs(b + y1_base + 64)];
+
+ const uint8_t* pMuls = &s_muls[row & 1][x & 1][0];
+ int cb = (cb00_sample * pMuls[0] + cb01_sample * pMuls[1] + cb10_sample * pMuls[2] + cb11_sample * pMuls[3] + 8) >> 4;
+ int cr = (cr00_sample * pMuls[0] + cr01_sample * pMuls[1] + cr10_sample * pMuls[2] + cr11_sample * pMuls[3] + 8) >> 4;
+
+ int rc = m_crr[cr];
+ int gc = ((m_crg[cr] + m_cbg[cb]) >> 16);
+ int bc = m_cbb[cb];
+
+ d0[0] = clamp(y_sample + rc);
+ d0[1] = clamp(y_sample + gc);
+ d0[2] = clamp(y_sample + bc);
+ d0[3] = 255;
+
+ d0 += 4;
+ }
+
+ return 1;
+ }
+ }
+
+ // Y (1 block per MCU) to 8-bit grayscale
+ void jpeg_decoder::gray_convert()
+ {
+ int row = m_max_mcu_y_size - m_mcu_lines_left;
+ uint8* d = m_pScan_line_0;
+ uint8* s = m_pSample_buf + row * 8;
+
+ for (int i = m_max_mcus_per_row; i > 0; i--)
+ {
+ *(uint*)d = *(uint*)s;
+ *(uint*)(&d[4]) = *(uint*)(&s[4]);
+
+ s += 64;
+ d += 8;
+ }
+ }
+
+ // Find end of image (EOI) marker, so we can return to the user the exact size of the input stream.
+ void jpeg_decoder::find_eoi()
+ {
+ if (!m_progressive_flag)
+ {
+ // Attempt to read the EOI marker.
+ //get_bits_no_markers(m_bits_left & 7);
+
+ // Prime the bit buffer
+ m_bits_left = 16;
+ get_bits(16);
+ get_bits(16);
+
+ // The next marker _should_ be EOI
+ process_markers();
+ }
+
+ m_total_bytes_read -= m_in_buf_left;
+ }
+
+ int jpeg_decoder::decode_next_mcu_row()
+ {
+ if (::setjmp(m_jmp_state))
+ return JPGD_FAILED;
+
+ const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2));
+ if (chroma_y_filtering)
+ {
+ std::swap(m_pSample_buf, m_pSample_buf_prev);
+
+ m_sample_buf_prev_valid = true;
+ }
+
+ if (m_progressive_flag)
+ load_next_row();
+ else
+ decode_next_row();
+
+ // Find the EOI marker if that was the last row.
+ if (m_total_lines_left <= m_max_mcu_y_size)
+ find_eoi();
+
+ m_mcu_lines_left = m_max_mcu_y_size;
+ return 0;
+ }
+
+ int jpeg_decoder::decode(const void** pScan_line, uint* pScan_line_len)
+ {
+ if ((m_error_code) || (!m_ready_flag))
+ return JPGD_FAILED;
+
+ if (m_total_lines_left == 0)
+ return JPGD_DONE;
+
+ const bool chroma_y_filtering = ((m_flags & cFlagBoxChromaFiltering) == 0) && ((m_scan_type == JPGD_YH2V2) || (m_scan_type == JPGD_YH1V2));
+
+ bool get_another_mcu_row = false;
+ bool got_mcu_early = false;
+ if (chroma_y_filtering)
+ {
+ if (m_total_lines_left == m_image_y_size)
+ get_another_mcu_row = true;
+ else if ((m_mcu_lines_left == 1) && (m_total_lines_left > 1))
+ {
+ get_another_mcu_row = true;
+ got_mcu_early = true;
+ }
+ }
+ else
+ {
+ get_another_mcu_row = (m_mcu_lines_left == 0);
+ }
+
+ if (get_another_mcu_row)
+ {
+ int status = decode_next_mcu_row();
+ if (status != 0)
+ return status;
+ }
+
+ switch (m_scan_type)
+ {
+ case JPGD_YH2V2:
+ {
+ if ((m_flags & cFlagBoxChromaFiltering) == 0)
+ {
+ if (m_num_buffered_scanlines == 1)
+ {
+ *pScan_line = m_pScan_line_1;
+ }
+ else if (m_num_buffered_scanlines == 0)
+ {
+ m_num_buffered_scanlines = H2V2ConvertFiltered();
+ *pScan_line = m_pScan_line_0;
+ }
+
+ m_num_buffered_scanlines--;
+ }
+ else
+ {
+ if ((m_mcu_lines_left & 1) == 0)
+ {
+ H2V2Convert();
+ *pScan_line = m_pScan_line_0;
+ }
+ else
+ *pScan_line = m_pScan_line_1;
+ }
+
+ break;
+ }
+ case JPGD_YH2V1:
+ {
+ if ((m_flags & cFlagBoxChromaFiltering) == 0)
+ H2V1ConvertFiltered();
+ else
+ H2V1Convert();
+ *pScan_line = m_pScan_line_0;
+ break;
+ }
+ case JPGD_YH1V2:
+ {
+ if (chroma_y_filtering)
+ {
+ H1V2ConvertFiltered();
+ *pScan_line = m_pScan_line_0;
+ }
+ else
+ {
+ if ((m_mcu_lines_left & 1) == 0)
+ {
+ H1V2Convert();
+ *pScan_line = m_pScan_line_0;
+ }
+ else
+ *pScan_line = m_pScan_line_1;
+ }
+
+ break;
+ }
+ case JPGD_YH1V1:
+ {
+ H1V1Convert();
+ *pScan_line = m_pScan_line_0;
+ break;
+ }
+ case JPGD_GRAYSCALE:
+ {
+ gray_convert();
+ *pScan_line = m_pScan_line_0;
+
+ break;
+ }
+ }
+
+ *pScan_line_len = m_real_dest_bytes_per_scan_line;
+
+ if (!got_mcu_early)
+ {
+ m_mcu_lines_left--;
+ }
+
+ m_total_lines_left--;
+
+ return JPGD_SUCCESS;
+ }
+
+ // Creates the tables needed for efficient Huffman decoding.
+ void jpeg_decoder::make_huff_table(int index, huff_tables* pH)
+ {
+ int p, i, l, si;
+ uint8 huffsize[258];
+ uint huffcode[258];
+ uint code;
+ uint subtree;
+ int code_size;
+ int lastp;
+ int nextfreeentry;
+ int currententry;
+
+ pH->ac_table = m_huff_ac[index] != 0;
+
+ p = 0;
+
+ for (l = 1; l <= 16; l++)
+ {
+ for (i = 1; i <= m_huff_num[index][l]; i++)
+ {
+ if (p >= 257)
+ stop_decoding(JPGD_DECODE_ERROR);
+ huffsize[p++] = static_cast<uint8>(l);
+ }
+ }
+
+ assert(p < 258);
+ huffsize[p] = 0;
+
+ lastp = p;
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+
+ while (huffsize[p])
+ {
+ while (huffsize[p] == si)
+ {
+ if (p >= 257)
+ stop_decoding(JPGD_DECODE_ERROR);
+ huffcode[p++] = code;
+ code++;
+ }
+
+ code <<= 1;
+ si++;
+ }
+
+ memset(pH->look_up, 0, sizeof(pH->look_up));
+ memset(pH->look_up2, 0, sizeof(pH->look_up2));
+ memset(pH->tree, 0, sizeof(pH->tree));
+ memset(pH->code_size, 0, sizeof(pH->code_size));
+
+ nextfreeentry = -1;
+
+ p = 0;
+
+ while (p < lastp)
+ {
+ i = m_huff_val[index][p];
+
+ code = huffcode[p];
+ code_size = huffsize[p];
+
+ assert(i < JPGD_HUFF_CODE_SIZE_MAX_LENGTH);
+ pH->code_size[i] = static_cast<uint8>(code_size);
+
+ if (code_size <= 8)
+ {
+ code <<= (8 - code_size);
+
+ for (l = 1 << (8 - code_size); l > 0; l--)
+ {
+ if (code >= 256)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ pH->look_up[code] = i;
+
+ bool has_extrabits = false;
+ int extra_bits = 0;
+ int num_extra_bits = i & 15;
+
+ int bits_to_fetch = code_size;
+ if (num_extra_bits)
+ {
+ int total_codesize = code_size + num_extra_bits;
+ if (total_codesize <= 8)
+ {
+ has_extrabits = true;
+ extra_bits = ((1 << num_extra_bits) - 1) & (code >> (8 - total_codesize));
+
+ if (extra_bits > 0x7FFF)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ bits_to_fetch += num_extra_bits;
+ }
+ }
+
+ if (!has_extrabits)
+ pH->look_up2[code] = i | (bits_to_fetch << 8);
+ else
+ pH->look_up2[code] = i | 0x8000 | (extra_bits << 16) | (bits_to_fetch << 8);
+
+ code++;
+ }
+ }
+ else
+ {
+ subtree = (code >> (code_size - 8)) & 0xFF;
+
+ currententry = pH->look_up[subtree];
+
+ if (currententry == 0)
+ {
+ pH->look_up[subtree] = currententry = nextfreeentry;
+ pH->look_up2[subtree] = currententry = nextfreeentry;
+
+ nextfreeentry -= 2;
+ }
+
+ code <<= (16 - (code_size - 8));
+
+ for (l = code_size; l > 9; l--)
+ {
+ if ((code & 0x8000) == 0)
+ currententry--;
+
+ unsigned int idx = -currententry - 1;
+
+ if (idx >= JPGD_HUFF_TREE_MAX_LENGTH)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ if (pH->tree[idx] == 0)
+ {
+ pH->tree[idx] = nextfreeentry;
+
+ currententry = nextfreeentry;
+
+ nextfreeentry -= 2;
+ }
+ else
+ {
+ currententry = pH->tree[idx];
+ }
+
+ code <<= 1;
+ }
+
+ if ((code & 0x8000) == 0)
+ currententry--;
+
+ if ((-currententry - 1) >= JPGD_HUFF_TREE_MAX_LENGTH)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ pH->tree[-currententry - 1] = i;
+ }
+
+ p++;
+ }
+ }
+
+ // Verifies the quantization tables needed for this scan are available.
+ void jpeg_decoder::check_quant_tables()
+ {
+ for (int i = 0; i < m_comps_in_scan; i++)
+ if (m_quant[m_comp_quant[m_comp_list[i]]] == nullptr)
+ stop_decoding(JPGD_UNDEFINED_QUANT_TABLE);
+ }
+
+ // Verifies that all the Huffman tables needed for this scan are available.
+ void jpeg_decoder::check_huff_tables()
+ {
+ for (int i = 0; i < m_comps_in_scan; i++)
+ {
+ if ((m_spectral_start == 0) && (m_huff_num[m_comp_dc_tab[m_comp_list[i]]] == nullptr))
+ stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);
+
+ if ((m_spectral_end > 0) && (m_huff_num[m_comp_ac_tab[m_comp_list[i]]] == nullptr))
+ stop_decoding(JPGD_UNDEFINED_HUFF_TABLE);
+ }
+
+ for (int i = 0; i < JPGD_MAX_HUFF_TABLES; i++)
+ if (m_huff_num[i])
+ {
+ if (!m_pHuff_tabs[i])
+ m_pHuff_tabs[i] = (huff_tables*)alloc(sizeof(huff_tables));
+
+ make_huff_table(i, m_pHuff_tabs[i]);
+ }
+ }
+
+ // Determines the component order inside each MCU.
+ // Also calcs how many MCU's are on each row, etc.
+ bool jpeg_decoder::calc_mcu_block_order()
+ {
+ int component_num, component_id;
+ int max_h_samp = 0, max_v_samp = 0;
+
+ for (component_id = 0; component_id < m_comps_in_frame; component_id++)
+ {
+ if (m_comp_h_samp[component_id] > max_h_samp)
+ max_h_samp = m_comp_h_samp[component_id];
+
+ if (m_comp_v_samp[component_id] > max_v_samp)
+ max_v_samp = m_comp_v_samp[component_id];
+ }
+
+ for (component_id = 0; component_id < m_comps_in_frame; component_id++)
+ {
+ m_comp_h_blocks[component_id] = ((((m_image_x_size * m_comp_h_samp[component_id]) + (max_h_samp - 1)) / max_h_samp) + 7) / 8;
+ m_comp_v_blocks[component_id] = ((((m_image_y_size * m_comp_v_samp[component_id]) + (max_v_samp - 1)) / max_v_samp) + 7) / 8;
+ }
+
+ if (m_comps_in_scan == 1)
+ {
+ m_mcus_per_row = m_comp_h_blocks[m_comp_list[0]];
+ m_mcus_per_col = m_comp_v_blocks[m_comp_list[0]];
+ }
+ else
+ {
+ m_mcus_per_row = (((m_image_x_size + 7) / 8) + (max_h_samp - 1)) / max_h_samp;
+ m_mcus_per_col = (((m_image_y_size + 7) / 8) + (max_v_samp - 1)) / max_v_samp;
+ }
+
+ if (m_comps_in_scan == 1)
+ {
+ m_mcu_org[0] = m_comp_list[0];
+
+ m_blocks_per_mcu = 1;
+ }
+ else
+ {
+ m_blocks_per_mcu = 0;
+
+ for (component_num = 0; component_num < m_comps_in_scan; component_num++)
+ {
+ int num_blocks;
+
+ component_id = m_comp_list[component_num];
+
+ num_blocks = m_comp_h_samp[component_id] * m_comp_v_samp[component_id];
+
+ while (num_blocks--)
+ m_mcu_org[m_blocks_per_mcu++] = component_id;
+ }
+ }
+
+ if (m_blocks_per_mcu > m_max_blocks_per_mcu)
+ return false;
+
+ for (int mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
+ {
+ int comp_id = m_mcu_org[mcu_block];
+ if (comp_id >= JPGD_MAX_QUANT_TABLES)
+ return false;
+ }
+
+ return true;
+ }
+
+ // Starts a new scan.
+ int jpeg_decoder::init_scan()
+ {
+ if (!locate_sos_marker())
+ return JPGD_FALSE;
+
+ if (!calc_mcu_block_order())
+ return JPGD_FALSE;
+
+ check_huff_tables();
+
+ check_quant_tables();
+
+ memset(m_last_dc_val, 0, m_comps_in_frame * sizeof(uint));
+
+ m_eob_run = 0;
+
+ if (m_restart_interval)
+ {
+ m_restarts_left = m_restart_interval;
+ m_next_restart_num = 0;
+ }
+
+ fix_in_buffer();
+
+ return JPGD_TRUE;
+ }
+
+ // Starts a frame. Determines if the number of components or sampling factors
+ // are supported.
+ void jpeg_decoder::init_frame()
+ {
+ int i;
+
+ if (m_comps_in_frame == 1)
+ {
+ if ((m_comp_h_samp[0] != 1) || (m_comp_v_samp[0] != 1))
+ stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
+
+ m_scan_type = JPGD_GRAYSCALE;
+ m_max_blocks_per_mcu = 1;
+ m_max_mcu_x_size = 8;
+ m_max_mcu_y_size = 8;
+ }
+ else if (m_comps_in_frame == 3)
+ {
+ if (((m_comp_h_samp[1] != 1) || (m_comp_v_samp[1] != 1)) ||
+ ((m_comp_h_samp[2] != 1) || (m_comp_v_samp[2] != 1)))
+ stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
+
+ if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 1))
+ {
+ m_scan_type = JPGD_YH1V1;
+
+ m_max_blocks_per_mcu = 3;
+ m_max_mcu_x_size = 8;
+ m_max_mcu_y_size = 8;
+ }
+ else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 1))
+ {
+ m_scan_type = JPGD_YH2V1;
+ m_max_blocks_per_mcu = 4;
+ m_max_mcu_x_size = 16;
+ m_max_mcu_y_size = 8;
+ }
+ else if ((m_comp_h_samp[0] == 1) && (m_comp_v_samp[0] == 2))
+ {
+ m_scan_type = JPGD_YH1V2;
+ m_max_blocks_per_mcu = 4;
+ m_max_mcu_x_size = 8;
+ m_max_mcu_y_size = 16;
+ }
+ else if ((m_comp_h_samp[0] == 2) && (m_comp_v_samp[0] == 2))
+ {
+ m_scan_type = JPGD_YH2V2;
+ m_max_blocks_per_mcu = 6;
+ m_max_mcu_x_size = 16;
+ m_max_mcu_y_size = 16;
+ }
+ else
+ stop_decoding(JPGD_UNSUPPORTED_SAMP_FACTORS);
+ }
+ else
+ stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);
+
+ m_max_mcus_per_row = (m_image_x_size + (m_max_mcu_x_size - 1)) / m_max_mcu_x_size;
+ m_max_mcus_per_col = (m_image_y_size + (m_max_mcu_y_size - 1)) / m_max_mcu_y_size;
+
+ // These values are for the *destination* pixels: after conversion.
+ if (m_scan_type == JPGD_GRAYSCALE)
+ m_dest_bytes_per_pixel = 1;
+ else
+ m_dest_bytes_per_pixel = 4;
+
+ m_dest_bytes_per_scan_line = ((m_image_x_size + 15) & 0xFFF0) * m_dest_bytes_per_pixel;
+
+ m_real_dest_bytes_per_scan_line = (m_image_x_size * m_dest_bytes_per_pixel);
+
+ // Initialize two scan line buffers.
+ m_pScan_line_0 = (uint8*)alloc_aligned(m_dest_bytes_per_scan_line, true);
+ if ((m_scan_type == JPGD_YH1V2) || (m_scan_type == JPGD_YH2V2))
+ m_pScan_line_1 = (uint8*)alloc_aligned(m_dest_bytes_per_scan_line, true);
+
+ m_max_blocks_per_row = m_max_mcus_per_row * m_max_blocks_per_mcu;
+
+ // Should never happen
+ if (m_max_blocks_per_row > JPGD_MAX_BLOCKS_PER_ROW)
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ // Allocate the coefficient buffer, enough for one MCU
+ m_pMCU_coefficients = (jpgd_block_coeff_t *)alloc_aligned(m_max_blocks_per_mcu * 64 * sizeof(jpgd_block_coeff_t));
+
+ for (i = 0; i < m_max_blocks_per_mcu; i++)
+ m_mcu_block_max_zag[i] = 64;
+
+ m_pSample_buf = (uint8*)alloc_aligned(m_max_blocks_per_row * 64);
+ m_pSample_buf_prev = (uint8*)alloc_aligned(m_max_blocks_per_row * 64);
+
+ m_total_lines_left = m_image_y_size;
+
+ m_mcu_lines_left = 0;
+
+ create_look_ups();
+ }
+
+ // The coeff_buf series of methods originally stored the coefficients
+ // into a "virtual" file which was located in EMS, XMS, or a disk file. A cache
+ // was used to make this process more efficient. Now, we can store the entire
+ // thing in RAM.
+ jpeg_decoder::coeff_buf* jpeg_decoder::coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y)
+ {
+ coeff_buf* cb = (coeff_buf*)alloc(sizeof(coeff_buf));
+
+ cb->block_num_x = block_num_x;
+ cb->block_num_y = block_num_y;
+ cb->block_len_x = block_len_x;
+ cb->block_len_y = block_len_y;
+ cb->block_size = (block_len_x * block_len_y) * sizeof(jpgd_block_coeff_t);
+ cb->pData = (uint8*)alloc(cb->block_size * block_num_x * block_num_y, true);
+ return cb;
+ }
+
+ inline jpgd_block_coeff_t* jpeg_decoder::coeff_buf_getp(coeff_buf* cb, int block_x, int block_y)
+ {
+ if ((block_x >= cb->block_num_x) || (block_y >= cb->block_num_y))
+ stop_decoding(JPGD_DECODE_ERROR);
+
+ return (jpgd_block_coeff_t*)(cb->pData + block_x * cb->block_size + block_y * (cb->block_size * cb->block_num_x));
+ }
+
+ // The following methods decode the various types of m_blocks encountered
+ // in progressively encoded images.
+ void jpeg_decoder::decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y)
+ {
+ int s, r;
+ jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);
+
+ if ((s = pD->huff_decode(pD->m_pHuff_tabs[pD->m_comp_dc_tab[component_id]])) != 0)
+ {
+ if (s >= 16)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ r = pD->get_bits_no_markers(s);
+ s = JPGD_HUFF_EXTEND(r, s);
+ }
+
+ pD->m_last_dc_val[component_id] = (s += pD->m_last_dc_val[component_id]);
+
+ p[0] = static_cast<jpgd_block_coeff_t>(s << pD->m_successive_low);
+ }
+
+ void jpeg_decoder::decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y)
+ {
+ if (pD->get_bits_no_markers(1))
+ {
+ jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_dc_coeffs[component_id], block_x, block_y);
+
+ p[0] |= (1 << pD->m_successive_low);
+ }
+ }
+
+ void jpeg_decoder::decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y)
+ {
+ int k, s, r;
+
+ if (pD->m_eob_run)
+ {
+ pD->m_eob_run--;
+ return;
+ }
+
+ jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
+
+ for (k = pD->m_spectral_start; k <= pD->m_spectral_end; k++)
+ {
+ unsigned int idx = pD->m_comp_ac_tab[component_id];
+ if (idx >= JPGD_MAX_HUFF_TABLES)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
+
+ r = s >> 4;
+ s &= 15;
+
+ if (s)
+ {
+ if ((k += r) > 63)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ r = pD->get_bits_no_markers(s);
+ s = JPGD_HUFF_EXTEND(r, s);
+
+ p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(s << pD->m_successive_low);
+ }
+ else
+ {
+ if (r == 15)
+ {
+ if ((k += 15) > 63)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+ }
+ else
+ {
+ pD->m_eob_run = 1 << r;
+
+ if (r)
+ pD->m_eob_run += pD->get_bits_no_markers(r);
+
+ pD->m_eob_run--;
+
+ break;
+ }
+ }
+ }
+ }
+
+ void jpeg_decoder::decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y)
+ {
+ int s, k, r;
+
+ int p1 = 1 << pD->m_successive_low;
+
+ //int m1 = (-1) << pD->m_successive_low;
+ int m1 = static_cast<int>((UINT32_MAX << pD->m_successive_low));
+
+ jpgd_block_coeff_t* p = pD->coeff_buf_getp(pD->m_ac_coeffs[component_id], block_x, block_y);
+ if (pD->m_spectral_end > 63)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ k = pD->m_spectral_start;
+
+ if (pD->m_eob_run == 0)
+ {
+ for (; k <= pD->m_spectral_end; k++)
+ {
+ unsigned int idx = pD->m_comp_ac_tab[component_id];
+ if (idx >= JPGD_MAX_HUFF_TABLES)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ s = pD->huff_decode(pD->m_pHuff_tabs[idx]);
+
+ r = s >> 4;
+ s &= 15;
+
+ if (s)
+ {
+ if (s != 1)
+ pD->stop_decoding(JPGD_DECODE_ERROR);
+
+ if (pD->get_bits_no_markers(1))
+ s = p1;
+ else
+ s = m1;
+ }
+ else
+ {
+ if (r != 15)
+ {
+ pD->m_eob_run = 1 << r;
+
+ if (r)
+ pD->m_eob_run += pD->get_bits_no_markers(r);
+
+ break;
+ }
+ }
+
+ do
+ {
+ jpgd_block_coeff_t* this_coef = p + g_ZAG[k & 63];
+
+ if (*this_coef != 0)
+ {
+ if (pD->get_bits_no_markers(1))
+ {
+ if ((*this_coef & p1) == 0)
+ {
+ if (*this_coef >= 0)
+ *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + p1);
+ else
+ *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + m1);
+ }
+ }
+ }
+ else
+ {
+ if (--r < 0)
+ break;
+ }
+
+ k++;
+
+ } while (k <= pD->m_spectral_end);
+
+ if ((s) && (k < 64))
+ {
+ p[g_ZAG[k]] = static_cast<jpgd_block_coeff_t>(s);
+ }
+ }
+ }
+
+ if (pD->m_eob_run > 0)
+ {
+ for (; k <= pD->m_spectral_end; k++)
+ {
+ jpgd_block_coeff_t* this_coef = p + g_ZAG[k & 63]; // logical AND to shut up static code analysis
+
+ if (*this_coef != 0)
+ {
+ if (pD->get_bits_no_markers(1))
+ {
+ if ((*this_coef & p1) == 0)
+ {
+ if (*this_coef >= 0)
+ *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + p1);
+ else
+ *this_coef = static_cast<jpgd_block_coeff_t>(*this_coef + m1);
+ }
+ }
+ }
+ }
+
+ pD->m_eob_run--;
+ }
+ }
+
+ // Decode a scan in a progressively encoded image.
+ void jpeg_decoder::decode_scan(pDecode_block_func decode_block_func)
+ {
+ int mcu_row, mcu_col, mcu_block;
+ int block_x_mcu[JPGD_MAX_COMPONENTS], block_y_mcu[JPGD_MAX_COMPONENTS];
+
+ memset(block_y_mcu, 0, sizeof(block_y_mcu));
+
+ for (mcu_col = 0; mcu_col < m_mcus_per_col; mcu_col++)
+ {
+ int component_num, component_id;
+
+ memset(block_x_mcu, 0, sizeof(block_x_mcu));
+
+ for (mcu_row = 0; mcu_row < m_mcus_per_row; mcu_row++)
+ {
+ int block_x_mcu_ofs = 0, block_y_mcu_ofs = 0;
+
+ if ((m_restart_interval) && (m_restarts_left == 0))
+ process_restart();
+
+ for (mcu_block = 0; mcu_block < m_blocks_per_mcu; mcu_block++)
+ {
+ component_id = m_mcu_org[mcu_block];
+
+ decode_block_func(this, component_id, block_x_mcu[component_id] + block_x_mcu_ofs, block_y_mcu[component_id] + block_y_mcu_ofs);
+
+ if (m_comps_in_scan == 1)
+ block_x_mcu[component_id]++;
+ else
+ {
+ if (++block_x_mcu_ofs == m_comp_h_samp[component_id])
+ {
+ block_x_mcu_ofs = 0;
+
+ if (++block_y_mcu_ofs == m_comp_v_samp[component_id])
+ {
+ block_y_mcu_ofs = 0;
+ block_x_mcu[component_id] += m_comp_h_samp[component_id];
+ }
+ }
+ }
+ }
+
+ m_restarts_left--;
+ }
+
+ if (m_comps_in_scan == 1)
+ block_y_mcu[m_comp_list[0]]++;
+ else
+ {
+ for (component_num = 0; component_num < m_comps_in_scan; component_num++)
+ {
+ component_id = m_comp_list[component_num];
+ block_y_mcu[component_id] += m_comp_v_samp[component_id];
+ }
+ }
+ }
+ }
+
+ // Decode a progressively encoded image.
+ void jpeg_decoder::init_progressive()
+ {
+ int i;
+
+ if (m_comps_in_frame == 4)
+ stop_decoding(JPGD_UNSUPPORTED_COLORSPACE);
+
+ // Allocate the coefficient buffers.
+ for (i = 0; i < m_comps_in_frame; i++)
+ {
+ m_dc_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 1, 1);
+ m_ac_coeffs[i] = coeff_buf_open(m_max_mcus_per_row * m_comp_h_samp[i], m_max_mcus_per_col * m_comp_v_samp[i], 8, 8);
+ }
+
+ // See https://libjpeg-turbo.org/pmwiki/uploads/About/TwoIssueswiththeJPEGStandard.pdf
+ uint32_t total_scans = 0;
+ const uint32_t MAX_SCANS_TO_PROCESS = 1000;
+
+ for (; ; )
+ {
+ int dc_only_scan, refinement_scan;
+ pDecode_block_func decode_block_func;
+
+ if (!init_scan())
+ break;
+
+ dc_only_scan = (m_spectral_start == 0);
+ refinement_scan = (m_successive_high != 0);
+
+ if ((m_spectral_start > m_spectral_end) || (m_spectral_end > 63))
+ stop_decoding(JPGD_BAD_SOS_SPECTRAL);
+
+ if (dc_only_scan)
+ {
+ if (m_spectral_end)
+ stop_decoding(JPGD_BAD_SOS_SPECTRAL);
+ }
+ else if (m_comps_in_scan != 1) /* AC scans can only contain one component */
+ stop_decoding(JPGD_BAD_SOS_SPECTRAL);
+
+ if ((refinement_scan) && (m_successive_low != m_successive_high - 1))
+ stop_decoding(JPGD_BAD_SOS_SUCCESSIVE);
+
+ if (dc_only_scan)
+ {
+ if (refinement_scan)
+ decode_block_func = decode_block_dc_refine;
+ else
+ decode_block_func = decode_block_dc_first;
+ }
+ else
+ {
+ if (refinement_scan)
+ decode_block_func = decode_block_ac_refine;
+ else
+ decode_block_func = decode_block_ac_first;
+ }
+
+ decode_scan(decode_block_func);
+
+ m_bits_left = 16;
+ get_bits(16);
+ get_bits(16);
+
+ total_scans++;
+ if (total_scans > MAX_SCANS_TO_PROCESS)
+ stop_decoding(JPGD_TOO_MANY_SCANS);
+ }
+
+ m_comps_in_scan = m_comps_in_frame;
+
+ for (i = 0; i < m_comps_in_frame; i++)
+ m_comp_list[i] = i;
+
+ if (!calc_mcu_block_order())
+ stop_decoding(JPGD_DECODE_ERROR);
+ }
+
+ void jpeg_decoder::init_sequential()
+ {
+ if (!init_scan())
+ stop_decoding(JPGD_UNEXPECTED_MARKER);
+ }
+
+ void jpeg_decoder::decode_start()
+ {
+ init_frame();
+
+ if (m_progressive_flag)
+ init_progressive();
+ else
+ init_sequential();
+ }
+
+ void jpeg_decoder::decode_init(jpeg_decoder_stream* pStream, uint32_t flags)
+ {
+ init(pStream, flags);
+ locate_sof_marker();
+ }
+
+ jpeg_decoder::jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags)
+ {
+ if (::setjmp(m_jmp_state))
+ return;
+ decode_init(pStream, flags);
+ }
+
+ int jpeg_decoder::begin_decoding()
+ {
+ if (m_ready_flag)
+ return JPGD_SUCCESS;
+
+ if (m_error_code)
+ return JPGD_FAILED;
+
+ if (::setjmp(m_jmp_state))
+ return JPGD_FAILED;
+
+ decode_start();
+
+ m_ready_flag = true;
+
+ return JPGD_SUCCESS;
+ }
+
+ jpeg_decoder::~jpeg_decoder()
+ {
+ free_all_blocks();
+ }
+
+ jpeg_decoder_file_stream::jpeg_decoder_file_stream()
+ {
+ m_pFile = nullptr;
+ m_eof_flag = false;
+ m_error_flag = false;
+ }
+
+ void jpeg_decoder_file_stream::close()
+ {
+ if (m_pFile)
+ {
+ fclose(m_pFile);
+ m_pFile = nullptr;
+ }
+
+ m_eof_flag = false;
+ m_error_flag = false;
+ }
+
+ jpeg_decoder_file_stream::~jpeg_decoder_file_stream()
+ {
+ close();
+ }
+
+ bool jpeg_decoder_file_stream::open(const char* Pfilename)
+ {
+ close();
+
+ m_eof_flag = false;
+ m_error_flag = false;
#if defined(_MSC_VER)
- m_pFile = NULL;
- fopen_s(&m_pFile, Pfilename, "rb");
+ m_pFile = nullptr;
+ fopen_s(&m_pFile, Pfilename, "rb");
#else
- m_pFile = fopen(Pfilename, "rb");
+ m_pFile = fopen(Pfilename, "rb");
#endif
- return m_pFile != NULL;
-}
-
-int jpeg_decoder_file_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag)
-{
- if (!m_pFile)
- return -1;
-
- if (m_eof_flag)
- {
- *pEOF_flag = true;
- return 0;
- }
-
- if (m_error_flag)
- return -1;
-
- int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile));
- if (bytes_read < max_bytes_to_read)
- {
- if (ferror(m_pFile))
- {
- m_error_flag = true;
- return -1;
- }
-
- m_eof_flag = true;
- *pEOF_flag = true;
- }
-
- return bytes_read;
-}
-
-bool jpeg_decoder_mem_stream::open(const uint8 *pSrc_data, uint size)
-{
- close();
- m_pSrc_data = pSrc_data;
- m_ofs = 0;
- m_size = size;
- return true;
-}
-
-int jpeg_decoder_mem_stream::read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag)
-{
- *pEOF_flag = false;
-
- if (!m_pSrc_data)
- return -1;
-
- uint bytes_remaining = m_size - m_ofs;
- if ((uint)max_bytes_to_read > bytes_remaining)
- {
- max_bytes_to_read = bytes_remaining;
- *pEOF_flag = true;
- }
-
- memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read);
- m_ofs += max_bytes_to_read;
-
- return max_bytes_to_read;
-}
-
-unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps)
-{
- if (!actual_comps)
- return NULL;
- *actual_comps = 0;
-
- if ((!pStream) || (!width) || (!height) || (!req_comps))
- return NULL;
-
- if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4))
- return NULL;
-
- jpeg_decoder decoder(pStream);
- if (decoder.get_error_code() != JPGD_SUCCESS)
- return NULL;
-
- const int image_width = decoder.get_width(), image_height = decoder.get_height();
- *width = image_width;
- *height = image_height;
- *actual_comps = decoder.get_num_components();
-
- if (decoder.begin_decoding() != JPGD_SUCCESS)
- return NULL;
-
- const int dst_bpl = image_width * req_comps;
-
- uint8 *pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height);
- if (!pImage_data)
- return NULL;
-
- for (int y = 0; y < image_height; y++)
- {
- const uint8* pScan_line;
- uint scan_line_len;
- if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS)
- {
- jpgd_free(pImage_data);
- return NULL;
- }
-
- uint8 *pDst = pImage_data + y * dst_bpl;
-
- if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3)))
- memcpy(pDst, pScan_line, dst_bpl);
- else if (decoder.get_num_components() == 1)
- {
- if (req_comps == 3)
- {
- for (int x = 0; x < image_width; x++)
- {
- uint8 luma = pScan_line[x];
- pDst[0] = luma;
- pDst[1] = luma;
- pDst[2] = luma;
- pDst += 3;
- }
- }
- else
- {
- for (int x = 0; x < image_width; x++)
- {
- uint8 luma = pScan_line[x];
- pDst[0] = luma;
- pDst[1] = luma;
- pDst[2] = luma;
- pDst[3] = 255;
- pDst += 4;
- }
- }
- }
- else if (decoder.get_num_components() == 3)
- {
- if (req_comps == 1)
- {
- const int YR = 19595, YG = 38470, YB = 7471;
- for (int x = 0; x < image_width; x++)
- {
- int r = pScan_line[x*4+0];
- int g = pScan_line[x*4+1];
- int b = pScan_line[x*4+2];
- *pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16);
- }
- }
- else
- {
- for (int x = 0; x < image_width; x++)
- {
- pDst[0] = pScan_line[x*4+0];
- pDst[1] = pScan_line[x*4+1];
- pDst[2] = pScan_line[x*4+2];
- pDst += 3;
- }
- }
- }
- }
-
- return pImage_data;
-}
-
-unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps)
-{
- jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size);
- return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps);
-}
-
-unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps)
-{
- jpgd::jpeg_decoder_file_stream file_stream;
- if (!file_stream.open(pSrc_filename))
- return NULL;
- return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps);
-}
-
-} // namespace jpgd \ No newline at end of file
+ return m_pFile != nullptr;
+ }
+
+ int jpeg_decoder_file_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag)
+ {
+ if (!m_pFile)
+ return -1;
+
+ if (m_eof_flag)
+ {
+ *pEOF_flag = true;
+ return 0;
+ }
+
+ if (m_error_flag)
+ return -1;
+
+ int bytes_read = static_cast<int>(fread(pBuf, 1, max_bytes_to_read, m_pFile));
+ if (bytes_read < max_bytes_to_read)
+ {
+ if (ferror(m_pFile))
+ {
+ m_error_flag = true;
+ return -1;
+ }
+
+ m_eof_flag = true;
+ *pEOF_flag = true;
+ }
+
+ return bytes_read;
+ }
+
+ bool jpeg_decoder_mem_stream::open(const uint8* pSrc_data, uint size)
+ {
+ close();
+ m_pSrc_data = pSrc_data;
+ m_ofs = 0;
+ m_size = size;
+ return true;
+ }
+
+ int jpeg_decoder_mem_stream::read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag)
+ {
+ *pEOF_flag = false;
+
+ if (!m_pSrc_data)
+ return -1;
+
+ uint bytes_remaining = m_size - m_ofs;
+ if ((uint)max_bytes_to_read > bytes_remaining)
+ {
+ max_bytes_to_read = bytes_remaining;
+ *pEOF_flag = true;
+ }
+
+ memcpy(pBuf, m_pSrc_data + m_ofs, max_bytes_to_read);
+ m_ofs += max_bytes_to_read;
+
+ return max_bytes_to_read;
+ }
+
+ unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags)
+ {
+ if (!actual_comps)
+ return nullptr;
+ *actual_comps = 0;
+
+ if ((!pStream) || (!width) || (!height) || (!req_comps))
+ return nullptr;
+
+ if ((req_comps != 1) && (req_comps != 3) && (req_comps != 4))
+ return nullptr;
+
+ jpeg_decoder decoder(pStream, flags);
+ if (decoder.get_error_code() != JPGD_SUCCESS)
+ return nullptr;
+
+ const int image_width = decoder.get_width(), image_height = decoder.get_height();
+ *width = image_width;
+ *height = image_height;
+ *actual_comps = decoder.get_num_components();
+
+ if (decoder.begin_decoding() != JPGD_SUCCESS)
+ return nullptr;
+
+ const int dst_bpl = image_width * req_comps;
+
+ uint8* pImage_data = (uint8*)jpgd_malloc(dst_bpl * image_height);
+ if (!pImage_data)
+ return nullptr;
+
+ for (int y = 0; y < image_height; y++)
+ {
+ const uint8* pScan_line;
+ uint scan_line_len;
+ if (decoder.decode((const void**)&pScan_line, &scan_line_len) != JPGD_SUCCESS)
+ {
+ jpgd_free(pImage_data);
+ return nullptr;
+ }
+
+ uint8* pDst = pImage_data + y * dst_bpl;
+
+ if (((req_comps == 1) && (decoder.get_num_components() == 1)) || ((req_comps == 4) && (decoder.get_num_components() == 3)))
+ memcpy(pDst, pScan_line, dst_bpl);
+ else if (decoder.get_num_components() == 1)
+ {
+ if (req_comps == 3)
+ {
+ for (int x = 0; x < image_width; x++)
+ {
+ uint8 luma = pScan_line[x];
+ pDst[0] = luma;
+ pDst[1] = luma;
+ pDst[2] = luma;
+ pDst += 3;
+ }
+ }
+ else
+ {
+ for (int x = 0; x < image_width; x++)
+ {
+ uint8 luma = pScan_line[x];
+ pDst[0] = luma;
+ pDst[1] = luma;
+ pDst[2] = luma;
+ pDst[3] = 255;
+ pDst += 4;
+ }
+ }
+ }
+ else if (decoder.get_num_components() == 3)
+ {
+ if (req_comps == 1)
+ {
+ const int YR = 19595, YG = 38470, YB = 7471;
+ for (int x = 0; x < image_width; x++)
+ {
+ int r = pScan_line[x * 4 + 0];
+ int g = pScan_line[x * 4 + 1];
+ int b = pScan_line[x * 4 + 2];
+ *pDst++ = static_cast<uint8>((r * YR + g * YG + b * YB + 32768) >> 16);
+ }
+ }
+ else
+ {
+ for (int x = 0; x < image_width; x++)
+ {
+ pDst[0] = pScan_line[x * 4 + 0];
+ pDst[1] = pScan_line[x * 4 + 1];
+ pDst[2] = pScan_line[x * 4 + 2];
+ pDst += 3;
+ }
+ }
+ }
+ }
+
+ return pImage_data;
+ }
+
+ unsigned char* decompress_jpeg_image_from_memory(const unsigned char* pSrc_data, int src_data_size, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags)
+ {
+ jpgd::jpeg_decoder_mem_stream mem_stream(pSrc_data, src_data_size);
+ return decompress_jpeg_image_from_stream(&mem_stream, width, height, actual_comps, req_comps, flags);
+ }
+
+ unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags)
+ {
+ jpgd::jpeg_decoder_file_stream file_stream;
+ if (!file_stream.open(pSrc_filename))
+ return nullptr;
+ return decompress_jpeg_image_from_stream(&file_stream, width, height, actual_comps, req_comps, flags);
+ }
+
+} // namespace jpgd
diff --git a/thirdparty/jpeg-compressor/jpgd.h b/thirdparty/jpeg-compressor/jpgd.h
index 150b9a0b26..39136696ba 100644
--- a/thirdparty/jpeg-compressor/jpgd.h
+++ b/thirdparty/jpeg-compressor/jpgd.h
@@ -1,319 +1,351 @@
// jpgd.h - C++ class for JPEG decompression.
-// Public domain, Rich Geldreich <richgel99@gmail.com>
+// Richard Geldreich <richgel99@gmail.com>
+// See jpgd.cpp for license (Public Domain or Apache 2.0).
#ifndef JPEG_DECODER_H
#define JPEG_DECODER_H
#include <stdlib.h>
#include <stdio.h>
#include <setjmp.h>
+#include <assert.h>
+#include <stdint.h>
#ifdef _MSC_VER
- #define JPGD_NORETURN __declspec(noreturn)
+#define JPGD_NORETURN __declspec(noreturn)
#elif defined(__GNUC__)
- #define JPGD_NORETURN __attribute__ ((noreturn))
+#define JPGD_NORETURN __attribute__ ((noreturn))
#else
- #define JPGD_NORETURN
+#define JPGD_NORETURN
#endif
+#define JPGD_HUFF_TREE_MAX_LENGTH 512
+#define JPGD_HUFF_CODE_SIZE_MAX_LENGTH 256
+
namespace jpgd
{
- typedef unsigned char uint8;
- typedef signed short int16;
- typedef unsigned short uint16;
- typedef unsigned int uint;
- typedef signed int int32;
-
- // Loads a JPEG image from a memory buffer or a file.
- // req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA).
- // On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB).
- // Notes: For more control over where and how the source data is read, see the decompress_jpeg_image_from_stream() function below, or call the jpeg_decoder class directly.
- // Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp.
- unsigned char *decompress_jpeg_image_from_memory(const unsigned char *pSrc_data, int src_data_size, int *width, int *height, int *actual_comps, int req_comps);
- unsigned char *decompress_jpeg_image_from_file(const char *pSrc_filename, int *width, int *height, int *actual_comps, int req_comps);
-
- // Success/failure error codes.
- enum jpgd_status
- {
- JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1,
- JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE,
- JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS,
- JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH,
- JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER,
- JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS,
- JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE,
- JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER, JPGD_ASSERTION_ERROR,
- JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM
- };
-
- // Input stream interface.
- // Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available.
- // The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set.
- // It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer.
- // Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding.
- class jpeg_decoder_stream
- {
- public:
- jpeg_decoder_stream() { }
- virtual ~jpeg_decoder_stream() { }
-
- // The read() method is called when the internal input buffer is empty.
- // Parameters:
- // pBuf - input buffer
- // max_bytes_to_read - maximum bytes that can be written to pBuf
- // pEOF_flag - set this to true if at end of stream (no more bytes remaining)
- // Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0).
- // Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full.
- virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag) = 0;
- };
-
- // stdio FILE stream class.
- class jpeg_decoder_file_stream : public jpeg_decoder_stream
- {
- jpeg_decoder_file_stream(const jpeg_decoder_file_stream &);
- jpeg_decoder_file_stream &operator =(const jpeg_decoder_file_stream &);
-
- FILE *m_pFile;
- bool m_eof_flag, m_error_flag;
-
- public:
- jpeg_decoder_file_stream();
- virtual ~jpeg_decoder_file_stream();
-
- bool open(const char *Pfilename);
- void close();
-
- virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag);
- };
-
- // Memory stream class.
- class jpeg_decoder_mem_stream : public jpeg_decoder_stream
- {
- const uint8 *m_pSrc_data;
- uint m_ofs, m_size;
-
- public:
- jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { }
- jpeg_decoder_mem_stream(const uint8 *pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { }
-
- virtual ~jpeg_decoder_mem_stream() { }
-
- bool open(const uint8 *pSrc_data, uint size);
- void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; }
-
- virtual int read(uint8 *pBuf, int max_bytes_to_read, bool *pEOF_flag);
- };
-
- // Loads JPEG file from a jpeg_decoder_stream.
- unsigned char *decompress_jpeg_image_from_stream(jpeg_decoder_stream *pStream, int *width, int *height, int *actual_comps, int req_comps);
-
- enum
- {
- JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4,
- JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 8192, JPGD_MAX_HEIGHT = 16384, JPGD_MAX_WIDTH = 16384
- };
-
- typedef int16 jpgd_quant_t;
- typedef int16 jpgd_block_t;
-
- class jpeg_decoder
- {
- public:
- // Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc.
- // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline.
- jpeg_decoder(jpeg_decoder_stream *pStream);
-
- ~jpeg_decoder();
-
- // Call this method after constructing the object to begin decompression.
- // If JPGD_SUCCESS is returned you may then call decode() on each scanline.
- int begin_decoding();
-
- // Returns the next scan line.
- // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1).
- // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4).
- // Returns JPGD_SUCCESS if a scan line has been returned.
- // Returns JPGD_DONE if all scan lines have been returned.
- // Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info.
- int decode(const void** pScan_line, uint* pScan_line_len);
-
- inline jpgd_status get_error_code() const { return m_error_code; }
-
- inline int get_width() const { return m_image_x_size; }
- inline int get_height() const { return m_image_y_size; }
-
- inline int get_num_components() const { return m_comps_in_frame; }
-
- inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; }
- inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); }
-
- // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file).
- inline int get_total_bytes_read() const { return m_total_bytes_read; }
-
- private:
- jpeg_decoder(const jpeg_decoder &);
- jpeg_decoder &operator =(const jpeg_decoder &);
-
- typedef void (*pDecode_block_func)(jpeg_decoder *, int, int, int);
-
- struct huff_tables
- {
- bool ac_table;
- uint look_up[256];
- uint look_up2[256];
- uint8 code_size[256];
- uint tree[512];
- };
-
- struct coeff_buf
- {
- uint8 *pData;
- int block_num_x, block_num_y;
- int block_len_x, block_len_y;
- int block_size;
- };
-
- struct mem_block
- {
- mem_block *m_pNext;
- size_t m_used_count;
- size_t m_size;
- char m_data[1];
- };
-
- jmp_buf m_jmp_state;
- mem_block *m_pMem_blocks;
- int m_image_x_size;
- int m_image_y_size;
- jpeg_decoder_stream *m_pStream;
- int m_progressive_flag;
- uint8 m_huff_ac[JPGD_MAX_HUFF_TABLES];
- uint8* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size
- uint8* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size
- jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables
- int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported)
- int m_comps_in_frame; // # of components in frame
- int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor
- int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor
- int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector
- int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID
- int m_comp_h_blocks[JPGD_MAX_COMPONENTS];
- int m_comp_v_blocks[JPGD_MAX_COMPONENTS];
- int m_comps_in_scan; // # of components in scan
- int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan
- int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector
- int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector
- int m_spectral_start; // spectral selection start
- int m_spectral_end; // spectral selection end
- int m_successive_low; // successive approximation low
- int m_successive_high; // successive approximation high
- int m_max_mcu_x_size; // MCU's max. X size in pixels
- int m_max_mcu_y_size; // MCU's max. Y size in pixels
- int m_blocks_per_mcu;
- int m_max_blocks_per_row;
- int m_mcus_per_row, m_mcus_per_col;
- int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU];
- int m_total_lines_left; // total # lines left in image
- int m_mcu_lines_left; // total # lines left in this MCU
- int m_real_dest_bytes_per_scan_line;
- int m_dest_bytes_per_scan_line; // rounded up
- int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y)
- huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES];
- coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS];
- coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS];
- int m_eob_run;
- int m_block_y_mcu[JPGD_MAX_COMPONENTS];
- uint8* m_pIn_buf_ofs;
- int m_in_buf_left;
- int m_tem_flag;
- bool m_eof_flag;
- uint8 m_in_buf_pad_start[128];
- uint8 m_in_buf[JPGD_IN_BUF_SIZE + 128];
- uint8 m_in_buf_pad_end[128];
- int m_bits_left;
- uint m_bit_buf;
- int m_restart_interval;
- int m_restarts_left;
- int m_next_restart_num;
- int m_max_mcus_per_row;
- int m_max_blocks_per_mcu;
- int m_expanded_blocks_per_mcu;
- int m_expanded_blocks_per_row;
- int m_expanded_blocks_per_component;
- bool m_freq_domain_chroma_upsample;
- int m_max_mcus_per_col;
- uint m_last_dc_val[JPGD_MAX_COMPONENTS];
- jpgd_block_t* m_pMCU_coefficients;
- int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU];
- uint8* m_pSample_buf;
- int m_crr[256];
- int m_cbb[256];
- int m_crg[256];
- int m_cbg[256];
- uint8* m_pScan_line_0;
- uint8* m_pScan_line_1;
- jpgd_status m_error_code;
- bool m_ready_flag;
- int m_total_bytes_read;
-
- void free_all_blocks();
- JPGD_NORETURN void stop_decoding(jpgd_status status);
- void *alloc(size_t n, bool zero = false);
- void word_clear(void *p, uint16 c, uint n);
- void prep_in_buffer();
- void read_dht_marker();
- void read_dqt_marker();
- void read_sof_marker();
- void skip_variable_marker();
- void read_dri_marker();
- void read_sos_marker();
- int next_marker();
- int process_markers();
- void locate_soi_marker();
- void locate_sof_marker();
- int locate_sos_marker();
- void init(jpeg_decoder_stream * pStream);
- void create_look_ups();
- void fix_in_buffer();
- void transform_mcu(int mcu_row);
- void transform_mcu_expand(int mcu_row);
- coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y);
- inline jpgd_block_t *coeff_buf_getp(coeff_buf *cb, int block_x, int block_y);
- void load_next_row();
- void decode_next_row();
- void make_huff_table(int index, huff_tables *pH);
- void check_quant_tables();
- void check_huff_tables();
- void calc_mcu_block_order();
- int init_scan();
- void init_frame();
- void process_restart();
- void decode_scan(pDecode_block_func decode_block_func);
- void init_progressive();
- void init_sequential();
- void decode_start();
- void decode_init(jpeg_decoder_stream * pStream);
- void H2V2Convert();
- void H2V1Convert();
- void H1V2Convert();
- void H1V1Convert();
- void gray_convert();
- void expanded_convert();
- void find_eoi();
- inline uint get_char();
- inline uint get_char(bool *pPadding_flag);
- inline void stuff_char(uint8 q);
- inline uint8 get_octet();
- inline uint get_bits(int num_bits);
- inline uint get_bits_no_markers(int numbits);
- inline int huff_decode(huff_tables *pH);
- inline int huff_decode(huff_tables *pH, int& extrabits);
- static inline uint8 clamp(int i);
- static void decode_block_dc_first(jpeg_decoder *pD, int component_id, int block_x, int block_y);
- static void decode_block_dc_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y);
- static void decode_block_ac_first(jpeg_decoder *pD, int component_id, int block_x, int block_y);
- static void decode_block_ac_refine(jpeg_decoder *pD, int component_id, int block_x, int block_y);
- };
-
+ typedef unsigned char uint8;
+ typedef signed short int16;
+ typedef unsigned short uint16;
+ typedef unsigned int uint;
+ typedef signed int int32;
+
+ // Loads a JPEG image from a memory buffer or a file.
+ // req_comps can be 1 (grayscale), 3 (RGB), or 4 (RGBA).
+ // On return, width/height will be set to the image's dimensions, and actual_comps will be set to the either 1 (grayscale) or 3 (RGB).
+ // Notes: For more control over where and how the source data is read, see the decompress_jpeg_image_from_stream() function below, or call the jpeg_decoder class directly.
+ // Requesting a 8 or 32bpp image is currently a little faster than 24bpp because the jpeg_decoder class itself currently always unpacks to either 8 or 32bpp.
+ unsigned char* decompress_jpeg_image_from_memory(const unsigned char* pSrc_data, int src_data_size, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0);
+ unsigned char* decompress_jpeg_image_from_file(const char* pSrc_filename, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0);
+
+ // Success/failure error codes.
+ enum jpgd_status
+ {
+ JPGD_SUCCESS = 0, JPGD_FAILED = -1, JPGD_DONE = 1,
+ JPGD_BAD_DHT_COUNTS = -256, JPGD_BAD_DHT_INDEX, JPGD_BAD_DHT_MARKER, JPGD_BAD_DQT_MARKER, JPGD_BAD_DQT_TABLE,
+ JPGD_BAD_PRECISION, JPGD_BAD_HEIGHT, JPGD_BAD_WIDTH, JPGD_TOO_MANY_COMPONENTS,
+ JPGD_BAD_SOF_LENGTH, JPGD_BAD_VARIABLE_MARKER, JPGD_BAD_DRI_LENGTH, JPGD_BAD_SOS_LENGTH,
+ JPGD_BAD_SOS_COMP_ID, JPGD_W_EXTRA_BYTES_BEFORE_MARKER, JPGD_NO_ARITHMITIC_SUPPORT, JPGD_UNEXPECTED_MARKER,
+ JPGD_NOT_JPEG, JPGD_UNSUPPORTED_MARKER, JPGD_BAD_DQT_LENGTH, JPGD_TOO_MANY_BLOCKS,
+ JPGD_UNDEFINED_QUANT_TABLE, JPGD_UNDEFINED_HUFF_TABLE, JPGD_NOT_SINGLE_SCAN, JPGD_UNSUPPORTED_COLORSPACE,
+ JPGD_UNSUPPORTED_SAMP_FACTORS, JPGD_DECODE_ERROR, JPGD_BAD_RESTART_MARKER,
+ JPGD_BAD_SOS_SPECTRAL, JPGD_BAD_SOS_SUCCESSIVE, JPGD_STREAM_READ, JPGD_NOTENOUGHMEM, JPGD_TOO_MANY_SCANS
+ };
+
+ // Input stream interface.
+ // Derive from this class to read input data from sources other than files or memory. Set m_eof_flag to true when no more data is available.
+ // The decoder is rather greedy: it will keep on calling this method until its internal input buffer is full, or until the EOF flag is set.
+ // It the input stream contains data after the JPEG stream's EOI (end of image) marker it will probably be pulled into the internal buffer.
+ // Call the get_total_bytes_read() method to determine the actual size of the JPEG stream after successful decoding.
+ class jpeg_decoder_stream
+ {
+ public:
+ jpeg_decoder_stream() { }
+ virtual ~jpeg_decoder_stream() { }
+
+ // The read() method is called when the internal input buffer is empty.
+ // Parameters:
+ // pBuf - input buffer
+ // max_bytes_to_read - maximum bytes that can be written to pBuf
+ // pEOF_flag - set this to true if at end of stream (no more bytes remaining)
+ // Returns -1 on error, otherwise return the number of bytes actually written to the buffer (which may be 0).
+ // Notes: This method will be called in a loop until you set *pEOF_flag to true or the internal buffer is full.
+ virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag) = 0;
+ };
+
+ // stdio FILE stream class.
+ class jpeg_decoder_file_stream : public jpeg_decoder_stream
+ {
+ jpeg_decoder_file_stream(const jpeg_decoder_file_stream&);
+ jpeg_decoder_file_stream& operator =(const jpeg_decoder_file_stream&);
+
+ FILE* m_pFile;
+ bool m_eof_flag, m_error_flag;
+
+ public:
+ jpeg_decoder_file_stream();
+ virtual ~jpeg_decoder_file_stream();
+
+ bool open(const char* Pfilename);
+ void close();
+
+ virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag);
+ };
+
+ // Memory stream class.
+ class jpeg_decoder_mem_stream : public jpeg_decoder_stream
+ {
+ const uint8* m_pSrc_data;
+ uint m_ofs, m_size;
+
+ public:
+ jpeg_decoder_mem_stream() : m_pSrc_data(NULL), m_ofs(0), m_size(0) { }
+ jpeg_decoder_mem_stream(const uint8* pSrc_data, uint size) : m_pSrc_data(pSrc_data), m_ofs(0), m_size(size) { }
+
+ virtual ~jpeg_decoder_mem_stream() { }
+
+ bool open(const uint8* pSrc_data, uint size);
+ void close() { m_pSrc_data = NULL; m_ofs = 0; m_size = 0; }
+
+ virtual int read(uint8* pBuf, int max_bytes_to_read, bool* pEOF_flag);
+ };
+
+ // Loads JPEG file from a jpeg_decoder_stream.
+ unsigned char* decompress_jpeg_image_from_stream(jpeg_decoder_stream* pStream, int* width, int* height, int* actual_comps, int req_comps, uint32_t flags = 0);
+
+ enum
+ {
+ JPGD_IN_BUF_SIZE = 8192, JPGD_MAX_BLOCKS_PER_MCU = 10, JPGD_MAX_HUFF_TABLES = 8, JPGD_MAX_QUANT_TABLES = 4,
+ JPGD_MAX_COMPONENTS = 4, JPGD_MAX_COMPS_IN_SCAN = 4, JPGD_MAX_BLOCKS_PER_ROW = 16384, JPGD_MAX_HEIGHT = 32768, JPGD_MAX_WIDTH = 32768
+ };
+
+ typedef int16 jpgd_quant_t;
+ typedef int16 jpgd_block_coeff_t;
+
+ class jpeg_decoder
+ {
+ public:
+ enum
+ {
+ cFlagBoxChromaFiltering = 1,
+ cFlagDisableSIMD = 2
+ };
+
+ // Call get_error_code() after constructing to determine if the stream is valid or not. You may call the get_width(), get_height(), etc.
+ // methods after the constructor is called. You may then either destruct the object, or begin decoding the image by calling begin_decoding(), then decode() on each scanline.
+ jpeg_decoder(jpeg_decoder_stream* pStream, uint32_t flags = 0);
+
+ ~jpeg_decoder();
+
+ // Call this method after constructing the object to begin decompression.
+ // If JPGD_SUCCESS is returned you may then call decode() on each scanline.
+
+ int begin_decoding();
+
+ // Returns the next scan line.
+ // For grayscale images, pScan_line will point to a buffer containing 8-bit pixels (get_bytes_per_pixel() will return 1).
+ // Otherwise, it will always point to a buffer containing 32-bit RGBA pixels (A will always be 255, and get_bytes_per_pixel() will return 4).
+ // Returns JPGD_SUCCESS if a scan line has been returned.
+ // Returns JPGD_DONE if all scan lines have been returned.
+ // Returns JPGD_FAILED if an error occurred. Call get_error_code() for a more info.
+ int decode(const void** pScan_line, uint* pScan_line_len);
+
+ inline jpgd_status get_error_code() const { return m_error_code; }
+
+ inline int get_width() const { return m_image_x_size; }
+ inline int get_height() const { return m_image_y_size; }
+
+ inline int get_num_components() const { return m_comps_in_frame; }
+
+ inline int get_bytes_per_pixel() const { return m_dest_bytes_per_pixel; }
+ inline int get_bytes_per_scan_line() const { return m_image_x_size * get_bytes_per_pixel(); }
+
+ // Returns the total number of bytes actually consumed by the decoder (which should equal the actual size of the JPEG file).
+ inline int get_total_bytes_read() const { return m_total_bytes_read; }
+
+ private:
+ jpeg_decoder(const jpeg_decoder&);
+ jpeg_decoder& operator =(const jpeg_decoder&);
+
+ typedef void (*pDecode_block_func)(jpeg_decoder*, int, int, int);
+
+ struct huff_tables
+ {
+ bool ac_table;
+ uint look_up[256];
+ uint look_up2[256];
+ uint8 code_size[JPGD_HUFF_CODE_SIZE_MAX_LENGTH];
+ uint tree[JPGD_HUFF_TREE_MAX_LENGTH];
+ };
+
+ struct coeff_buf
+ {
+ uint8* pData;
+ int block_num_x, block_num_y;
+ int block_len_x, block_len_y;
+ int block_size;
+ };
+
+ struct mem_block
+ {
+ mem_block* m_pNext;
+ size_t m_used_count;
+ size_t m_size;
+ char m_data[1];
+ };
+
+ jmp_buf m_jmp_state;
+ uint32_t m_flags;
+ mem_block* m_pMem_blocks;
+ int m_image_x_size;
+ int m_image_y_size;
+ jpeg_decoder_stream* m_pStream;
+
+ int m_progressive_flag;
+
+ uint8 m_huff_ac[JPGD_MAX_HUFF_TABLES];
+ uint8* m_huff_num[JPGD_MAX_HUFF_TABLES]; // pointer to number of Huffman codes per bit size
+ uint8* m_huff_val[JPGD_MAX_HUFF_TABLES]; // pointer to Huffman codes per bit size
+ jpgd_quant_t* m_quant[JPGD_MAX_QUANT_TABLES]; // pointer to quantization tables
+ int m_scan_type; // Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 (CMYK111, CMYK4114 no longer supported)
+ int m_comps_in_frame; // # of components in frame
+ int m_comp_h_samp[JPGD_MAX_COMPONENTS]; // component's horizontal sampling factor
+ int m_comp_v_samp[JPGD_MAX_COMPONENTS]; // component's vertical sampling factor
+ int m_comp_quant[JPGD_MAX_COMPONENTS]; // component's quantization table selector
+ int m_comp_ident[JPGD_MAX_COMPONENTS]; // component's ID
+ int m_comp_h_blocks[JPGD_MAX_COMPONENTS];
+ int m_comp_v_blocks[JPGD_MAX_COMPONENTS];
+ int m_comps_in_scan; // # of components in scan
+ int m_comp_list[JPGD_MAX_COMPS_IN_SCAN]; // components in this scan
+ int m_comp_dc_tab[JPGD_MAX_COMPONENTS]; // component's DC Huffman coding table selector
+ int m_comp_ac_tab[JPGD_MAX_COMPONENTS]; // component's AC Huffman coding table selector
+ int m_spectral_start; // spectral selection start
+ int m_spectral_end; // spectral selection end
+ int m_successive_low; // successive approximation low
+ int m_successive_high; // successive approximation high
+ int m_max_mcu_x_size; // MCU's max. X size in pixels
+ int m_max_mcu_y_size; // MCU's max. Y size in pixels
+ int m_blocks_per_mcu;
+ int m_max_blocks_per_row;
+ int m_mcus_per_row, m_mcus_per_col;
+ int m_mcu_org[JPGD_MAX_BLOCKS_PER_MCU];
+ int m_total_lines_left; // total # lines left in image
+ int m_mcu_lines_left; // total # lines left in this MCU
+ int m_num_buffered_scanlines;
+ int m_real_dest_bytes_per_scan_line;
+ int m_dest_bytes_per_scan_line; // rounded up
+ int m_dest_bytes_per_pixel; // 4 (RGB) or 1 (Y)
+ huff_tables* m_pHuff_tabs[JPGD_MAX_HUFF_TABLES];
+ coeff_buf* m_dc_coeffs[JPGD_MAX_COMPONENTS];
+ coeff_buf* m_ac_coeffs[JPGD_MAX_COMPONENTS];
+ int m_eob_run;
+ int m_block_y_mcu[JPGD_MAX_COMPONENTS];
+ uint8* m_pIn_buf_ofs;
+ int m_in_buf_left;
+ int m_tem_flag;
+
+ uint8 m_in_buf_pad_start[64];
+ uint8 m_in_buf[JPGD_IN_BUF_SIZE + 128];
+ uint8 m_in_buf_pad_end[64];
+
+ int m_bits_left;
+ uint m_bit_buf;
+ int m_restart_interval;
+ int m_restarts_left;
+ int m_next_restart_num;
+ int m_max_mcus_per_row;
+ int m_max_blocks_per_mcu;
+
+ int m_max_mcus_per_col;
+ uint m_last_dc_val[JPGD_MAX_COMPONENTS];
+ jpgd_block_coeff_t* m_pMCU_coefficients;
+ int m_mcu_block_max_zag[JPGD_MAX_BLOCKS_PER_MCU];
+ uint8* m_pSample_buf;
+ uint8* m_pSample_buf_prev;
+ int m_crr[256];
+ int m_cbb[256];
+ int m_crg[256];
+ int m_cbg[256];
+ uint8* m_pScan_line_0;
+ uint8* m_pScan_line_1;
+ jpgd_status m_error_code;
+ int m_total_bytes_read;
+
+ bool m_ready_flag;
+ bool m_eof_flag;
+ bool m_sample_buf_prev_valid;
+ bool m_has_sse2;
+
+ inline int check_sample_buf_ofs(int ofs) const { assert(ofs >= 0); assert(ofs < m_max_blocks_per_row * 64); return ofs; }
+ void free_all_blocks();
+ JPGD_NORETURN void stop_decoding(jpgd_status status);
+ void* alloc(size_t n, bool zero = false);
+ void* alloc_aligned(size_t nSize, uint32_t align = 16, bool zero = false);
+ void word_clear(void* p, uint16 c, uint n);
+ void prep_in_buffer();
+ void read_dht_marker();
+ void read_dqt_marker();
+ void read_sof_marker();
+ void skip_variable_marker();
+ void read_dri_marker();
+ void read_sos_marker();
+ int next_marker();
+ int process_markers();
+ void locate_soi_marker();
+ void locate_sof_marker();
+ int locate_sos_marker();
+ void init(jpeg_decoder_stream* pStream, uint32_t flags);
+ void create_look_ups();
+ void fix_in_buffer();
+ void transform_mcu(int mcu_row);
+ coeff_buf* coeff_buf_open(int block_num_x, int block_num_y, int block_len_x, int block_len_y);
+ inline jpgd_block_coeff_t* coeff_buf_getp(coeff_buf* cb, int block_x, int block_y);
+ void load_next_row();
+ void decode_next_row();
+ void make_huff_table(int index, huff_tables* pH);
+ void check_quant_tables();
+ void check_huff_tables();
+ bool calc_mcu_block_order();
+ int init_scan();
+ void init_frame();
+ void process_restart();
+ void decode_scan(pDecode_block_func decode_block_func);
+ void init_progressive();
+ void init_sequential();
+ void decode_start();
+ void decode_init(jpeg_decoder_stream* pStream, uint32_t flags);
+ void H2V2Convert();
+ uint32_t H2V2ConvertFiltered();
+ void H2V1Convert();
+ void H2V1ConvertFiltered();
+ void H1V2Convert();
+ void H1V2ConvertFiltered();
+ void H1V1Convert();
+ void gray_convert();
+ void find_eoi();
+ inline uint get_char();
+ inline uint get_char(bool* pPadding_flag);
+ inline void stuff_char(uint8 q);
+ inline uint8 get_octet();
+ inline uint get_bits(int num_bits);
+ inline uint get_bits_no_markers(int numbits);
+ inline int huff_decode(huff_tables* pH);
+ inline int huff_decode(huff_tables* pH, int& extrabits);
+
+ // Clamps a value between 0-255.
+ static inline uint8 clamp(int i)
+ {
+ if (static_cast<uint>(i) > 255)
+ i = (((~i) >> 31) & 0xFF);
+ return static_cast<uint8>(i);
+ }
+ int decode_next_mcu_row();
+
+ static void decode_block_dc_first(jpeg_decoder* pD, int component_id, int block_x, int block_y);
+ static void decode_block_dc_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y);
+ static void decode_block_ac_first(jpeg_decoder* pD, int component_id, int block_x, int block_y);
+ static void decode_block_ac_refine(jpeg_decoder* pD, int component_id, int block_x, int block_y);
+ };
+
} // namespace jpgd
#endif // JPEG_DECODER_H
diff --git a/thirdparty/jpeg-compressor/jpgd_idct.h b/thirdparty/jpeg-compressor/jpgd_idct.h
new file mode 100644
index 0000000000..876425a959
--- /dev/null
+++ b/thirdparty/jpeg-compressor/jpgd_idct.h
@@ -0,0 +1,462 @@
+// Copyright 2009 Intel Corporation
+// All Rights Reserved
+//
+// Permission is granted to use, copy, distribute and prepare derivative works of this
+// software for any purpose and without fee, provided, that the above copyright notice
+// and this statement appear in all copies. Intel makes no representations about the
+// suitability of this software for any purpose. THIS SOFTWARE IS PROVIDED "AS IS."
+// INTEL SPECIFICALLY DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, AND ALL LIABILITY,
+// INCLUDING CONSEQUENTIAL AND OTHER INDIRECT DAMAGES, FOR THE USE OF THIS SOFTWARE,
+// INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PROPRIETARY RIGHTS, AND INCLUDING THE
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. Intel does not
+// assume any responsibility for any errors which may appear in this software nor any
+// responsibility to update it.
+//
+// From:
+// https://software.intel.com/sites/default/files/m/d/4/1/d/8/UsingIntelAVXToImplementIDCT-r1_5.pdf
+// https://software.intel.com/file/29048
+//
+// Requires SSE
+//
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+#include <immintrin.h>
+
+#ifdef _MSC_VER
+ #define JPGD_SIMD_ALIGN(type, name) __declspec(align(16)) type name
+#else
+ #define JPGD_SIMD_ALIGN(type, name) type name __attribute__((aligned(16)))
+#endif
+
+#define BITS_INV_ACC 4
+#define SHIFT_INV_ROW 16 - BITS_INV_ACC
+#define SHIFT_INV_COL 1 + BITS_INV_ACC
+const short IRND_INV_ROW = 1024 * (6 - BITS_INV_ACC); //1 << (SHIFT_INV_ROW-1)
+const short IRND_INV_COL = 16 * (BITS_INV_ACC - 3); // 1 << (SHIFT_INV_COL-1)
+const short IRND_INV_CORR = IRND_INV_COL - 1; // correction -1.0 and round
+
+JPGD_SIMD_ALIGN(short, shortM128_one_corr[8]) = {1, 1, 1, 1, 1, 1, 1, 1};
+JPGD_SIMD_ALIGN(short, shortM128_round_inv_row[8]) = {IRND_INV_ROW, 0, IRND_INV_ROW, 0, IRND_INV_ROW, 0, IRND_INV_ROW, 0};
+JPGD_SIMD_ALIGN(short, shortM128_round_inv_col[8]) = {IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL, IRND_INV_COL};
+JPGD_SIMD_ALIGN(short, shortM128_round_inv_corr[8])= {IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR, IRND_INV_CORR};
+JPGD_SIMD_ALIGN(short, shortM128_tg_1_16[8]) = {13036, 13036, 13036, 13036, 13036, 13036, 13036, 13036}; // tg * (2<<16) + 0.5
+JPGD_SIMD_ALIGN(short, shortM128_tg_2_16[8]) = {27146, 27146, 27146, 27146, 27146, 27146, 27146, 27146}; // tg * (2<<16) + 0.5
+JPGD_SIMD_ALIGN(short, shortM128_tg_3_16[8]) = {-21746, -21746, -21746, -21746, -21746, -21746, -21746, -21746}; // tg * (2<<16) + 0.5
+JPGD_SIMD_ALIGN(short, shortM128_cos_4_16[8]) = {-19195, -19195, -19195, -19195, -19195, -19195, -19195, -19195};// cos * (2<<16) + 0.5
+
+//-----------------------------------------------------------------------------
+// Table for rows 0,4 - constants are multiplied on cos_4_16
+// w15 w14 w11 w10 w07 w06 w03 w02
+// w29 w28 w25 w24 w21 w20 w17 w16
+// w31 w30 w27 w26 w23 w22 w19 w18
+//movq -> w05 w04 w01 w00
+JPGD_SIMD_ALIGN(short, shortM128_tab_i_04[]) = {
+ 16384, 21407, 16384, 8867,
+ 16384, -8867, 16384, -21407, // w13 w12 w09 w08
+ 16384, 8867, -16384, -21407, // w07 w06 w03 w02
+ -16384, 21407, 16384, -8867, // w15 w14 w11 w10
+ 22725, 19266, 19266, -4520, // w21 w20 w17 w16
+ 12873, -22725, 4520, -12873, // w29 w28 w25 w24
+ 12873, 4520, -22725, -12873, // w23 w22 w19 w18
+ 4520, 19266, 19266, -22725}; // w31 w30 w27 w26
+
+ // Table for rows 1,7 - constants are multiplied on cos_1_16
+//movq -> w05 w04 w01 w00
+JPGD_SIMD_ALIGN(short, shortM128_tab_i_17[]) = {
+ 22725, 29692, 22725, 12299,
+ 22725, -12299, 22725, -29692, // w13 w12 w09 w08
+ 22725, 12299, -22725, -29692, // w07 w06 w03 w02
+ -22725, 29692, 22725, -12299, // w15 w14 w11 w10
+ 31521, 26722, 26722, -6270, // w21 w20 w17 w16
+ 17855, -31521, 6270, -17855, // w29 w28 w25 w24
+ 17855, 6270, -31521, -17855, // w23 w22 w19 w18
+ 6270, 26722, 26722, -31521}; // w31 w30 w27 w26
+
+// Table for rows 2,6 - constants are multiplied on cos_2_16
+//movq -> w05 w04 w01 w00
+JPGD_SIMD_ALIGN(short, shortM128_tab_i_26[]) = {
+ 21407, 27969, 21407, 11585,
+ 21407, -11585, 21407, -27969, // w13 w12 w09 w08
+ 21407, 11585, -21407, -27969, // w07 w06 w03 w02
+ -21407, 27969, 21407, -11585, // w15 w14 w11 w10
+ 29692, 25172, 25172, -5906, // w21 w20 w17 w16
+ 16819, -29692, 5906, -16819, // w29 w28 w25 w24
+ 16819, 5906, -29692, -16819, // w23 w22 w19 w18
+ 5906, 25172, 25172, -29692}; // w31 w30 w27 w26
+// Table for rows 3,5 - constants are multiplied on cos_3_16
+//movq -> w05 w04 w01 w00
+JPGD_SIMD_ALIGN(short, shortM128_tab_i_35[]) = {
+ 19266, 25172, 19266, 10426,
+ 19266, -10426, 19266, -25172, // w13 w12 w09 w08
+ 19266, 10426, -19266, -25172, // w07 w06 w03 w02
+ -19266, 25172, 19266, -10426, // w15 w14 w11 w10
+ 26722, 22654, 22654, -5315, // w21 w20 w17 w16
+ 15137, -26722, 5315, -15137, // w29 w28 w25 w24
+ 15137, 5315, -26722, -15137, // w23 w22 w19 w18
+ 5315, 22654, 22654, -26722}; // w31 w30 w27 w26
+
+JPGD_SIMD_ALIGN(short, shortM128_128[8]) = { 128, 128, 128, 128, 128, 128, 128, 128 };
+
+void idctSSEShortU8(const short *pInput, uint8_t * pOutputUB)
+{
+ __m128i r_xmm0, r_xmm4;
+ __m128i r_xmm1, r_xmm2, r_xmm3, r_xmm5, r_xmm6, r_xmm7;
+ __m128i row0, row1, row2, row3, row4, row5, row6, row7;
+ short * pTab_i_04 = shortM128_tab_i_04;
+ short * pTab_i_26 = shortM128_tab_i_26;
+
+ //Get pointers for this input and output
+ pTab_i_04 = shortM128_tab_i_04;
+ pTab_i_26 = shortM128_tab_i_26;
+
+ //Row 1 and Row 3
+ r_xmm0 = _mm_load_si128((__m128i *) pInput);
+ r_xmm4 = _mm_load_si128((__m128i *) (&pInput[2*8]));
+
+ // *** Work on the data in xmm0
+ //low shuffle mask = 0xd8 = 11 01 10 00
+ //get short 2 and short 0 into ls 32-bits
+ r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8);
+
+ // copy short 2 and short 0 to all locations
+ r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
+
+ // add to those copies
+ r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
+
+ // shuffle mask = 0x55 = 01 01 01 01
+ // copy short 3 and short 1 to all locations
+ r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
+
+ // high shuffle mask = 0xd8 = 11 01 10 00
+ // get short 6 and short 4 into bit positions 64-95
+ // get short 7 and short 5 into bit positions 96-127
+ r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
+
+ // add to short 3 and short 1
+ r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
+
+ // shuffle mask = 0xaa = 10 10 10 10
+ // copy short 6 and short 4 to all locations
+ r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
+
+ // shuffle mask = 0xaa = 11 11 11 11
+ // copy short 7 and short 5 to all locations
+ r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
+
+ // add to short 6 and short 4
+ r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
+
+ // *** Work on the data in xmm4
+ // high shuffle mask = 0xd8 11 01 10 00
+ // get short 6 and short 4 into bit positions 64-95
+ // get short 7 and short 5 into bit positions 96-127
+ r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
+
+ // (xmm0 short 2 and short 0 plus pSi) + some constants
+ r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
+ r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
+ r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
+ r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &shortM128_tab_i_26[0]));
+ r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
+ r_xmm2 = r_xmm1;
+ r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
+ r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &shortM128_tab_i_26[8]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
+ r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
+ r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
+ r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &shortM128_tab_i_26[16]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
+ r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
+ r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &shortM128_tab_i_26[24]));
+ r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
+ r_xmm6 = r_xmm5;
+ r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
+ r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b);
+ row0 = _mm_packs_epi32(r_xmm0, r_xmm2);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7);
+ r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5);
+ r_xmm6 = _mm_srai_epi32(r_xmm6, 12);
+ r_xmm4 = _mm_srai_epi32(r_xmm4, 12);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b);
+ row2 = _mm_packs_epi32(r_xmm4, r_xmm6);
+
+ //Row 5 and row 7
+ r_xmm0 = _mm_load_si128((__m128i *) (&pInput[4*8]));
+ r_xmm4 = _mm_load_si128((__m128i *) (&pInput[6*8]));
+
+ r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8);
+ r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
+ r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
+ r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
+ r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
+ r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
+ r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
+ r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
+ r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
+ r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
+ r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
+ r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
+ r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
+ r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &shortM128_tab_i_26[0]));
+ r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
+ r_xmm2 = r_xmm1;
+ r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
+ r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &shortM128_tab_i_26[8]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
+ r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
+ r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
+ r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &shortM128_tab_i_26[16]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
+ r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
+ r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &shortM128_tab_i_26[24]));
+ r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
+ r_xmm6 = r_xmm5;
+ r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
+ r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b);
+ row4 = _mm_packs_epi32(r_xmm0, r_xmm2);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7);
+ r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5);
+ r_xmm6 = _mm_srai_epi32(r_xmm6, 12);
+ r_xmm4 = _mm_srai_epi32(r_xmm4, 12);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b);
+ row6 = _mm_packs_epi32(r_xmm4, r_xmm6);
+
+ //Row 4 and row 2
+ pTab_i_04 = shortM128_tab_i_35;
+ pTab_i_26 = shortM128_tab_i_17;
+ r_xmm0 = _mm_load_si128((__m128i *) (&pInput[3*8]));
+ r_xmm4 = _mm_load_si128((__m128i *) (&pInput[1*8]));
+
+ r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8);
+ r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
+ r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
+ r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
+ r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
+ r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
+ r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
+ r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
+ r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
+ r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
+ r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
+ r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
+ r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
+ r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &pTab_i_26[0]));
+ r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
+ r_xmm2 = r_xmm1;
+ r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
+ r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &pTab_i_26[8]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
+ r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
+ r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
+ r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &pTab_i_26[16]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
+ r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
+ r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &pTab_i_26[24]));
+ r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
+ r_xmm6 = r_xmm5;
+ r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
+ r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b);
+ row3 = _mm_packs_epi32(r_xmm0, r_xmm2);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7);
+ r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5);
+ r_xmm6 = _mm_srai_epi32(r_xmm6, 12);
+ r_xmm4 = _mm_srai_epi32(r_xmm4, 12);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b);
+ row1 = _mm_packs_epi32(r_xmm4, r_xmm6);
+
+ //Row 6 and row 8
+ r_xmm0 = _mm_load_si128((__m128i *) (&pInput[5*8]));
+ r_xmm4 = _mm_load_si128((__m128i *) (&pInput[7*8]));
+
+ r_xmm0 = _mm_shufflelo_epi16(r_xmm0, 0xd8);
+ r_xmm1 = _mm_shuffle_epi32(r_xmm0, 0);
+ r_xmm1 = _mm_madd_epi16(r_xmm1, *((__m128i *) pTab_i_04));
+ r_xmm3 = _mm_shuffle_epi32(r_xmm0, 0x55);
+ r_xmm0 = _mm_shufflehi_epi16(r_xmm0, 0xd8);
+ r_xmm3 = _mm_madd_epi16(r_xmm3, *((__m128i *) &pTab_i_04[16]));
+ r_xmm2 = _mm_shuffle_epi32(r_xmm0, 0xaa);
+ r_xmm0 = _mm_shuffle_epi32(r_xmm0, 0xff);
+ r_xmm2 = _mm_madd_epi16(r_xmm2, *((__m128i *) &pTab_i_04[8]));
+ r_xmm4 = _mm_shufflehi_epi16(r_xmm4, 0xd8);
+ r_xmm1 = _mm_add_epi32(r_xmm1, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_shufflelo_epi16(r_xmm4, 0xd8);
+ r_xmm0 = _mm_madd_epi16(r_xmm0, *((__m128i *) &pTab_i_04[24]));
+ r_xmm5 = _mm_shuffle_epi32(r_xmm4, 0);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm4, 0xaa);
+ r_xmm5 = _mm_madd_epi16(r_xmm5, *((__m128i *) &pTab_i_26[0]));
+ r_xmm1 = _mm_add_epi32(r_xmm1, r_xmm2);
+ r_xmm2 = r_xmm1;
+ r_xmm7 = _mm_shuffle_epi32(r_xmm4, 0x55);
+ r_xmm6 = _mm_madd_epi16(r_xmm6, *((__m128i *) &pTab_i_26[8]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm3);
+ r_xmm4 = _mm_shuffle_epi32(r_xmm4, 0xff);
+ r_xmm2 = _mm_sub_epi32(r_xmm2, r_xmm0);
+ r_xmm7 = _mm_madd_epi16(r_xmm7, *((__m128i *) &pTab_i_26[16]));
+ r_xmm0 = _mm_add_epi32(r_xmm0, r_xmm1);
+ r_xmm2 = _mm_srai_epi32(r_xmm2, 12);
+ r_xmm5 = _mm_add_epi32(r_xmm5, *((__m128i *) shortM128_round_inv_row));
+ r_xmm4 = _mm_madd_epi16(r_xmm4, *((__m128i *) &pTab_i_26[24]));
+ r_xmm5 = _mm_add_epi32(r_xmm5, r_xmm6);
+ r_xmm6 = r_xmm5;
+ r_xmm0 = _mm_srai_epi32(r_xmm0, 12);
+ r_xmm2 = _mm_shuffle_epi32(r_xmm2, 0x1b);
+ row5 = _mm_packs_epi32(r_xmm0, r_xmm2);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm7);
+ r_xmm6 = _mm_sub_epi32(r_xmm6, r_xmm4);
+ r_xmm4 = _mm_add_epi32(r_xmm4, r_xmm5);
+ r_xmm6 = _mm_srai_epi32(r_xmm6, 12);
+ r_xmm4 = _mm_srai_epi32(r_xmm4, 12);
+ r_xmm6 = _mm_shuffle_epi32(r_xmm6, 0x1b);
+ row7 = _mm_packs_epi32(r_xmm4, r_xmm6);
+
+ r_xmm1 = _mm_load_si128((__m128i *) shortM128_tg_3_16);
+ r_xmm2 = row5;
+ r_xmm3 = row3;
+ r_xmm0 = _mm_mulhi_epi16(row5, r_xmm1);
+
+ r_xmm1 = _mm_mulhi_epi16(r_xmm1, r_xmm3);
+ r_xmm5 = _mm_load_si128((__m128i *) shortM128_tg_1_16);
+ r_xmm6 = row7;
+ r_xmm4 = _mm_mulhi_epi16(row7, r_xmm5);
+
+ r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm2);
+ r_xmm5 = _mm_mulhi_epi16(r_xmm5, row1);
+ r_xmm1 = _mm_adds_epi16(r_xmm1, r_xmm3);
+ r_xmm7 = row6;
+
+ r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm3);
+ r_xmm3 = _mm_load_si128((__m128i *) shortM128_tg_2_16);
+ r_xmm2 = _mm_subs_epi16(r_xmm2, r_xmm1);
+ r_xmm7 = _mm_mulhi_epi16(r_xmm7, r_xmm3);
+ r_xmm1 = r_xmm0;
+ r_xmm3 = _mm_mulhi_epi16(r_xmm3, row2);
+ r_xmm5 = _mm_subs_epi16(r_xmm5, r_xmm6);
+ r_xmm4 = _mm_adds_epi16(r_xmm4, row1);
+ r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm4);
+ r_xmm0 = _mm_adds_epi16(r_xmm0, *((__m128i *) shortM128_one_corr));
+ r_xmm4 = _mm_subs_epi16(r_xmm4, r_xmm1);
+ r_xmm6 = r_xmm5;
+ r_xmm5 = _mm_subs_epi16(r_xmm5, r_xmm2);
+ r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i *) shortM128_one_corr));
+ r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm2);
+
+ //Intermediate results, needed later
+ __m128i temp3, temp7;
+ temp7 = r_xmm0;
+
+ r_xmm1 = r_xmm4;
+ r_xmm0 = _mm_load_si128((__m128i *) shortM128_cos_4_16);
+ r_xmm4 = _mm_adds_epi16(r_xmm4, r_xmm5);
+ r_xmm2 = _mm_load_si128((__m128i *) shortM128_cos_4_16);
+ r_xmm2 = _mm_mulhi_epi16(r_xmm2, r_xmm4);
+
+ //Intermediate results, needed later
+ temp3 = r_xmm6;
+
+ r_xmm1 = _mm_subs_epi16(r_xmm1, r_xmm5);
+ r_xmm7 = _mm_adds_epi16(r_xmm7, row2);
+ r_xmm3 = _mm_subs_epi16(r_xmm3, row6);
+ r_xmm6 = row0;
+ r_xmm0 = _mm_mulhi_epi16(r_xmm0, r_xmm1);
+ r_xmm5 = row4;
+ r_xmm5 = _mm_adds_epi16(r_xmm5, r_xmm6);
+ r_xmm6 = _mm_subs_epi16(r_xmm6, row4);
+ r_xmm4 = _mm_adds_epi16(r_xmm4, r_xmm2);
+
+ r_xmm4 = _mm_or_si128(r_xmm4, *((__m128i *) shortM128_one_corr));
+ r_xmm0 = _mm_adds_epi16(r_xmm0, r_xmm1);
+ r_xmm0 = _mm_or_si128(r_xmm0, *((__m128i *) shortM128_one_corr));
+
+ r_xmm2 = r_xmm5;
+ r_xmm5 = _mm_adds_epi16(r_xmm5, r_xmm7);
+ r_xmm1 = r_xmm6;
+ r_xmm5 = _mm_adds_epi16(r_xmm5, *((__m128i *) shortM128_round_inv_col));
+ r_xmm2 = _mm_subs_epi16(r_xmm2, r_xmm7);
+ r_xmm7 = temp7;
+ r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm3);
+ r_xmm6 = _mm_adds_epi16(r_xmm6, *((__m128i *) shortM128_round_inv_col));
+ r_xmm7 = _mm_adds_epi16(r_xmm7, r_xmm5);
+ r_xmm7 = _mm_srai_epi16(r_xmm7, SHIFT_INV_COL);
+ r_xmm1 = _mm_subs_epi16(r_xmm1, r_xmm3);
+ r_xmm1 = _mm_adds_epi16(r_xmm1, *((__m128i *) shortM128_round_inv_corr));
+ r_xmm3 = r_xmm6;
+ r_xmm2 = _mm_adds_epi16(r_xmm2, *((__m128i *) shortM128_round_inv_corr));
+ r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm4);
+
+ //Store results for row 0
+ //_mm_store_si128((__m128i *) pOutput, r_xmm7);
+ __m128i r0 = r_xmm7;
+
+ r_xmm6 = _mm_srai_epi16(r_xmm6, SHIFT_INV_COL);
+ r_xmm7 = r_xmm1;
+ r_xmm1 = _mm_adds_epi16(r_xmm1, r_xmm0);
+
+ //Store results for row 1
+ //_mm_store_si128((__m128i *) (&pOutput[1*8]), r_xmm6);
+ __m128i r1 = r_xmm6;
+
+ r_xmm1 = _mm_srai_epi16(r_xmm1, SHIFT_INV_COL);
+ r_xmm6 = temp3;
+ r_xmm7 = _mm_subs_epi16(r_xmm7, r_xmm0);
+ r_xmm7 = _mm_srai_epi16(r_xmm7, SHIFT_INV_COL);
+
+ //Store results for row 2
+ //_mm_store_si128((__m128i *) (&pOutput[2*8]), r_xmm1);
+ __m128i r2 = r_xmm1;
+
+ r_xmm5 = _mm_subs_epi16(r_xmm5, temp7);
+ r_xmm5 = _mm_srai_epi16(r_xmm5, SHIFT_INV_COL);
+
+ //Store results for row 7
+ //_mm_store_si128((__m128i *) (&pOutput[7*8]), r_xmm5);
+ __m128i r7 = r_xmm5;
+
+ r_xmm3 = _mm_subs_epi16(r_xmm3, r_xmm4);
+ r_xmm6 = _mm_adds_epi16(r_xmm6, r_xmm2);
+ r_xmm2 = _mm_subs_epi16(r_xmm2, temp3);
+ r_xmm6 = _mm_srai_epi16(r_xmm6, SHIFT_INV_COL);
+ r_xmm2 = _mm_srai_epi16(r_xmm2, SHIFT_INV_COL);
+
+ //Store results for row 3
+ //_mm_store_si128((__m128i *) (&pOutput[3*8]), r_xmm6);
+ __m128i r3 = r_xmm6;
+
+ r_xmm3 = _mm_srai_epi16(r_xmm3, SHIFT_INV_COL);
+
+ //Store results for rows 4, 5, and 6
+ //_mm_store_si128((__m128i *) (&pOutput[4*8]), r_xmm2);
+ //_mm_store_si128((__m128i *) (&pOutput[5*8]), r_xmm7);
+ //_mm_store_si128((__m128i *) (&pOutput[6*8]), r_xmm3);
+
+ __m128i r4 = r_xmm2;
+ __m128i r5 = r_xmm7;
+ __m128i r6 = r_xmm3;
+
+ r0 = _mm_add_epi16(*(const __m128i *)shortM128_128, r0);
+ r1 = _mm_add_epi16(*(const __m128i *)shortM128_128, r1);
+ r2 = _mm_add_epi16(*(const __m128i *)shortM128_128, r2);
+ r3 = _mm_add_epi16(*(const __m128i *)shortM128_128, r3);
+ r4 = _mm_add_epi16(*(const __m128i *)shortM128_128, r4);
+ r5 = _mm_add_epi16(*(const __m128i *)shortM128_128, r5);
+ r6 = _mm_add_epi16(*(const __m128i *)shortM128_128, r6);
+ r7 = _mm_add_epi16(*(const __m128i *)shortM128_128, r7);
+
+ ((__m128i *)pOutputUB)[0] = _mm_packus_epi16(r0, r1);
+ ((__m128i *)pOutputUB)[1] = _mm_packus_epi16(r2, r3);
+ ((__m128i *)pOutputUB)[2] = _mm_packus_epi16(r4, r5);
+ ((__m128i *)pOutputUB)[3] = _mm_packus_epi16(r6, r7);
+}
diff --git a/thirdparty/mbedtls/include/mbedtls/check_config.h b/thirdparty/mbedtls/include/mbedtls/check_config.h
index d076c2352f..93de091c4d 100644
--- a/thirdparty/mbedtls/include/mbedtls/check_config.h
+++ b/thirdparty/mbedtls/include/mbedtls/check_config.h
@@ -546,6 +546,23 @@
#error "MBEDTLS_SSL_PROTO_TLS1_2 defined, but not all prerequisites"
#endif
+#if (defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \
+ defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2)) && \
+ !(defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \
+ defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) )
+#error "One or more versions of the TLS protocol are enabled " \
+ "but no key exchange methods defined with MBEDTLS_KEY_EXCHANGE_xxxx"
+#endif
+
#if defined(MBEDTLS_SSL_PROTO_DTLS) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_1) && \
!defined(MBEDTLS_SSL_PROTO_TLS1_2)
@@ -669,6 +686,10 @@
#error "MBEDTLS_X509_CREATE_C defined, but not all prerequisites"
#endif
+#if defined(MBEDTLS_CERTS_C) && !defined(MBEDTLS_X509_USE_C)
+#error "MBEDTLS_CERTS_C defined, but not all prerequisites"
+#endif
+
#if defined(MBEDTLS_X509_CRT_PARSE_C) && ( !defined(MBEDTLS_X509_USE_C) )
#error "MBEDTLS_X509_CRT_PARSE_C defined, but not all prerequisites"
#endif
diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h
index 8e2ce03c32..e0a2e7f6d6 100644
--- a/thirdparty/mbedtls/include/mbedtls/version.h
+++ b/thirdparty/mbedtls/include/mbedtls/version.h
@@ -40,16 +40,16 @@
*/
#define MBEDTLS_VERSION_MAJOR 2
#define MBEDTLS_VERSION_MINOR 16
-#define MBEDTLS_VERSION_PATCH 5
+#define MBEDTLS_VERSION_PATCH 6
/**
* The single version number has the following structure:
* MMNNPP00
* Major version | Minor version | Patch version
*/
-#define MBEDTLS_VERSION_NUMBER 0x02100500
-#define MBEDTLS_VERSION_STRING "2.16.5"
-#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.5"
+#define MBEDTLS_VERSION_NUMBER 0x02100600
+#define MBEDTLS_VERSION_STRING "2.16.6"
+#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.6"
#if defined(MBEDTLS_VERSION_C)
diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c
index 040c20bd38..725e176df2 100644
--- a/thirdparty/mbedtls/library/ecp.c
+++ b/thirdparty/mbedtls/library/ecp.c
@@ -1938,6 +1938,20 @@ static int ecp_mul_comb_after_precomp( const mbedtls_ecp_group *grp,
final_norm:
#endif
+ /*
+ * Knowledge of the jacobian coordinates may leak the last few bits of the
+ * scalar [1], and since our MPI implementation isn't constant-flow,
+ * inversion (used for coordinate normalization) may leak the full value
+ * of its input via side-channels [2].
+ *
+ * [1] https://eprint.iacr.org/2003/191
+ * [2] https://eprint.iacr.org/2020/055
+ *
+ * Avoid the leak by randomizing coordinates before we normalize them.
+ */
+ if( f_rng != 0 )
+ MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, RR, f_rng, p_rng ) );
+
MBEDTLS_ECP_BUDGET( MBEDTLS_ECP_OPS_INV );
MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, RR ) );
@@ -2308,6 +2322,20 @@ static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) );
}
+ /*
+ * Knowledge of the projective coordinates may leak the last few bits of the
+ * scalar [1], and since our MPI implementation isn't constant-flow,
+ * inversion (used for coordinate normalization) may leak the full value
+ * of its input via side-channels [2].
+ *
+ * [1] https://eprint.iacr.org/2003/191
+ * [2] https://eprint.iacr.org/2020/055
+ *
+ * Avoid the leak by randomizing coordinates before we normalize them.
+ */
+ if( f_rng != NULL )
+ MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, R, f_rng, p_rng ) );
+
MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) );
cleanup:
diff --git a/thirdparty/mbedtls/library/ssl_cli.c b/thirdparty/mbedtls/library/ssl_cli.c
index afced7a99c..c5c3af69df 100644
--- a/thirdparty/mbedtls/library/ssl_cli.c
+++ b/thirdparty/mbedtls/library/ssl_cli.c
@@ -1417,6 +1417,19 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) );
+ /* Check that there is enough room for:
+ * - 2 bytes of version
+ * - 1 byte of cookie_len
+ */
+ if( mbedtls_ssl_hs_hdr_len( ssl ) + 3 > ssl->in_msglen )
+ {
+ MBEDTLS_SSL_DEBUG_MSG( 1,
+ ( "incoming HelloVerifyRequest message is too short" ) );
+ mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
+ MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
+ return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
+ }
+
/*
* struct {
* ProtocolVersion server_version;
@@ -1445,8 +1458,6 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
}
cookie_len = *p++;
- MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
-
if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len )
{
MBEDTLS_SSL_DEBUG_MSG( 1,
@@ -1455,6 +1466,7 @@ static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl )
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO );
}
+ MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len );
mbedtls_free( ssl->handshake->verify_cookie );
diff --git a/thirdparty/mbedtls/library/ssl_tls.c b/thirdparty/mbedtls/library/ssl_tls.c
index b8f35fec5d..cbec74fe8c 100644
--- a/thirdparty/mbedtls/library/ssl_tls.c
+++ b/thirdparty/mbedtls/library/ssl_tls.c
@@ -1004,8 +1004,6 @@ int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl )
#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
if( mbedtls_ssl_hw_record_init != NULL )
{
- int ret = 0;
-
MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) );
if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen,
@@ -2885,15 +2883,18 @@ static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl );
/*
* Swap transform_out and out_ctr with the alternative ones
*/
-static void ssl_swap_epochs( mbedtls_ssl_context *ssl )
+static int ssl_swap_epochs( mbedtls_ssl_context *ssl )
{
mbedtls_ssl_transform *tmp_transform;
unsigned char tmp_out_ctr[8];
+#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL)
+ int ret;
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
if( ssl->transform_out == ssl->handshake->alt_transform_out )
{
MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) );
- return;
+ return( 0 );
}
MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) );
@@ -2920,7 +2921,9 @@ static void ssl_swap_epochs( mbedtls_ssl_context *ssl )
return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED );
}
}
-#endif
+#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */
+
+ return( 0 );
}
/*
@@ -2957,7 +2960,8 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
ssl->handshake->cur_msg = ssl->handshake->flight;
ssl->handshake->cur_msg_p = ssl->handshake->flight->p + 12;
- ssl_swap_epochs( ssl );
+ if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
+ return( ret );
ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING;
}
@@ -2980,7 +2984,8 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
if( is_finished && ssl->handshake->cur_msg_p == ( cur->p + 12 ) )
{
MBEDTLS_SSL_DEBUG_MSG( 2, ( "swap epochs to send finished message" ) );
- ssl_swap_epochs( ssl );
+ if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
+ return( ret );
}
ret = ssl_get_remaining_payload_in_datagram( ssl );
@@ -3017,7 +3022,10 @@ int mbedtls_ssl_flight_transmit( mbedtls_ssl_context *ssl )
if( ( max_frag_len < 12 ) || ( max_frag_len == 12 && hs_len != 0 ) )
{
if( is_finished )
- ssl_swap_epochs( ssl );
+ {
+ if( ( ret = ssl_swap_epochs( ssl ) ) != 0 )
+ return( ret );
+ }
if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 )
return( ret );
@@ -3997,17 +4005,23 @@ static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl )
if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED )
{
+ int send_ret;
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "sending HelloVerifyRequest" ) );
+ MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network",
+ ssl->out_buf, len );
/* Don't check write errors as we can't do anything here.
* If the error is permanent we'll catch it later,
* if it's not, then hopefully it'll work next time. */
- (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len );
+ send_ret = ssl->f_send( ssl->p_bio, ssl->out_buf, len );
+ MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", send_ret );
+ (void) send_ret;
return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED );
}
if( ret == 0 )
{
- /* Got a valid cookie, partially reset context */
+ MBEDTLS_SSL_DEBUG_MSG( 1, ( "cookie is valid, resetting context" ) );
if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 )
{
MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret );
diff --git a/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c
index 2e0b0e8f6c..4d25303206 100644
--- a/thirdparty/mbedtls/library/x509.c
+++ b/thirdparty/mbedtls/library/x509.c
@@ -1063,7 +1063,7 @@ cleanup:
mbedtls_x509_crt_free( &clicert );
#else
((void) verbose);
-#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */
+#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */
return( ret );
}
diff --git a/thirdparty/misc/cubemap_coeffs.h b/thirdparty/misc/cubemap_coeffs.h
index 1db03ce7c4..15e4e1664b 100644
--- a/thirdparty/misc/cubemap_coeffs.h
+++ b/thirdparty/misc/cubemap_coeffs.h
@@ -21,8 +21,8 @@
#ifndef CUBEMAP_COEFFS_H
#define CUBEMAP_COEFFS_H
-const float low_quality_coeffs[7][5][6][4] = { { { { 0.0002037563, 0.0045063655, -0.0016408688, 0.00012037493 }, { -9.1834951e-05, -0.008947532, -8.1524405e-05, -3.9080094e-05 }, { -2.6038267e-05, -6.8409667e-05, 7.2175702e-05, 0.25492775 }, { -9.9426044e-05, 0.0025427756, -0.00074437925, 1.1773191e-05 }, { -3.2668211e-05, 0.0026930659, -4.824934e-05, -0.0006835048 }, { -0.0002864144, -0.0032220854, 0.0021558286, -0.00014573736 } }, { { 0.00030683201, 0.0026819548, -0.00060011756, -0.0067169226 }, { -0.0030993251, 0.0098575575, 0.0022416671, -8.9075401e-05 }, { 0.00052405626, 0.00057860515, 0.00011654518, -0.048018609 }, { 0.00010850967, -0.0088443512, -0.0018168095, 8.6633128e-05 }, { 0.003333989, -0.0050956447, -8.0414612e-05, 0.0049721239 }, { -4.0961436e-05, -8.5486984e-05, 0.0058683066, 2.2978359e-05 } }, { { 0.99999993, 0.99998625, 0.99999847, 0.99997743 }, { 0.99999519, 0.99991138, 0.99999748, 1 }, { 0.99999986, 0.99999983, 0.99999999, 0.96576708 }, { 0.99999999, 0.99995765, 0.99999807, 1 }, { 0.99999444, 0.99998339, 1, 0.99998741 }, { 0.99999996, 0.99999481, 0.99998046, 0.99999999 } }, { { -0.32267524, -0.65409377, -1.4666488, 0.87153305 }, { -1.264365, 0.89880861, -1.2245906, -0.88501403 }, { -0.31118682, -0.086150323, -0.58811532, 1.1317711 }, { -1.2193493, 1.250379, -1.0871569, -0.12694096 }, { -0.4012249, -0.47436307, -0.59661001, 2.7313005 }, { -1.3109856, 0.60929855, 0.55672643, -0.39880018 } }, { { 0.93273157, 0.59530745, 1.1994788, 0.19102276 }, { 1.2272239, 0.23245736, 1.2577607, 2.5491008 }, { 1.1210098, 0.83074953, 1.3049282, -0.001940633 }, { 1.5839111, 0.10520816, 1.150458, 2.3251789 }, { 0.688692, 0.59807498, 1.3374877, 0.095746692 }, { 1.3054173, 0.36604721, 0.065870226, 1.6496907 } } }, { { { 0.10348445, -4.6771514e-07, -0.011513131, 8.8921052e-05 }, { -0.042152043, 0.013143535, 0.00029120107, 0.036661611 }, { -0.04516036, 0.011438473, -0.0099289792, -0.011707897 }, { -0.034779497, 0.0090981166, -5.4202726e-05, 0.038592793 }, { -0.0071967376, -0.0056614418, -0.012278945, 0.0056867462 }, { -0.037678514, 0.011570177, 0.00029044557, 0.038583909 } }, { { 0.048320869, 1.4603673e-05, 0.0092672368, 0.00033289199 }, { 0.0071001761, -0.0090106091, -0.0027305905, -0.00221479 }, { -0.0027204116, 0.00017921587, 0.015296357, -0.00010306185 }, { 0.0079350203, -0.014772431, -1.2410913e-05, -0.0062296897 }, { 0.025087691, 0.00086046427, 0.015034685, -0.00078224706 }, { 0.00074587265, -0.014602074, 0.00027338224, -0.012848552 } }, { { 0.99345662, 1, 0.99989078, 0.99999994 }, { 0.99908598, 0.99987302, 0.99999623, 0.99932528 }, { 0.99897605, 0.99993456, 0.9998337, 0.99993145 }, { 0.99936351, 0.99984949, 1, 0.9992356 }, { 0.99965935, 0.9999836, 0.99981158, 0.99998352 }, { 0.99928963, 0.99982644, 0.99999992, 0.99917276 } }, { { 3.6882765, 0.15963861, 0.55983965, 0.4075649 }, { 2.1169304, 0.56463157, 0.52957047, 2.0117964 }, { 3.1080461, 0.09682931, 0.42125986, 0.089254784 }, { 1.4247315, 0.48411378, -0.17039102, 1.7431674 }, { 4.0339531, 0.14046159, 0.89848909, 0.011661811 }, { 1.9787852, 0.61750145, 0.63514194, 1.9359003 } }, { { 0.030848793, 1.4472743, 1.4356825, 1.4078009 }, { 0.37639678, 1.0793106, 1.1945413, 0.43983395 }, { 0.27451605, 1.5256415, 1.016769, 1.4850575 }, { 0.54580883, 1.1332879, 3.1331784, 0.60772955 }, { 0.11785158, 1.3928946, 0.94998805, 1.0377182 }, { 0.2842108, 1.0026911, 1.9064553, 0.27147854 } } }, { { { -0.096789259, 0.10326967, 0.0011799959, -0.03077328 }, { 0.08342021, 0.033260738, -0.00045864451, -0.021450568 }, { -0.093369441, -0.05807574, -0.033745214, 0.023817208 }, { 0.056747754, 0.031140512, 0.00019362509, -0.023727797 }, { -0.084538386, -0.040545412, -0.0076838784, 0.03424599 }, { 0.074312056, 0.027619787, 0.0015509082, -0.031043528 } }, { { -0.0085160473, -0.012179292, 0.0049910118, 0.020224799 }, { 0.022559343, -0.016273333, -0.0069382139, 0.00058083224 }, { -0.001115062, 0.035002846, -0.0038974773, -0.039378629 }, { 0.0014921617, -0.00058523872, -0.0011606685, 0.02807528 }, { -0.021454809, 0.052957852, -0.0022083677, -0.027956663 }, { -0.016486487, -0.0040233682, 0.00029949558, 0.021924605 } }, { { 0.99526846, 0.99457883, 0.99998685, 0.99932175 }, { 0.99625908, 0.99931422, 0.99997583, 0.99976974 }, { 0.99563091, 0.99769836, 0.99942287, 0.99894047 }, { 0.99838743, 0.99951485, 0.99999931, 0.99932416 }, { 0.99618922, 0.99777329, 0.99996804, 0.99902234 }, { 0.99709875, 0.9996104, 0.99999875, 0.99927754 } }, { { 3.0342011, 4.8022834, 1.3814123, 1.5280754 }, { 2.9043837, 1.7325954, 1.422223, 2.0569263 }, { 3.0358722, 5.3331504, 1.5680146, 1.6079289 }, { 3.2062833, 1.5368069, 1.0484709, 1.5399477 }, { 2.4471653, 4.0916696, 1.5060688, 1.5807009 }, { 2.6932695, 1.5161537, 1.3991175, 1.6301918 } }, { { 0.50787578, 0.17735471, 1.4006765, 1.0878482 }, { 0.69514518, 1.6765187, 1.2224869, 1.3461327 }, { 0.71381288, 0.17509216, 1.2712934, 0.94575821 }, { 1.1817337, 1.796984, 1.8671538, 1.5708691 }, { 0.55621228, 0.38291359, 1.4128781, 0.82625349 }, { 0.72441647, 1.005794, 1.5522327, 1.6032524 } } }, { { { -0.00041301094, -0.095882618, 0.26932618, -0.25137214 }, { 0.13737415, -0.12694293, -0.0090389663, 0.07227623 }, { -0.005236407, -0.0072961249, 0.27776083, -0.19536433 }, { 0.12781899, -0.042881667, -0.095979169, 0.088937396 }, { 0.037496084, -0.090547583, 0.22112334, -0.21930294 }, { 0.13353408, -0.084346121, -0.011365728, 0.043459312 } }, { { -0.05799135, -0.048612281, 0.02422989, 0.015536268 }, { -0.083144241, 0.039381032, 0.018705957, 0.029297922 }, { 0.026364989, -0.041927591, 0.036718516, 0.0050376168 }, { -0.11562256, 0.043521976, -0.014481644, 0.01529188 }, { -0.047859898, -0.057779647, -0.053171395, -0.0063193506 }, { -0.028781196, 0.041145059, -0.00018523142, 0.053524246 } }, { { 0.998317, 0.99420489, 0.96274416, 0.96776581 }, { 0.98702349, 0.99112796, 0.99978417, 0.99695425 }, { 0.99963867, 0.99909401, 0.95994827, 0.9807178 }, { 0.98503489, 0.99813175, 0.99527799, 0.99591983 }, { 0.99815003, 0.99421459, 0.97379529, 0.97563635 }, { 0.99062621, 0.99558667, 0.99993539, 0.99762039 } }, { { 2.3221943, 2.5383575, 4.3177232, 4.2016467 }, { 3.1936529, 3.0443024, 2.548962, 2.7636456 }, { 2.5923827, 2.3497949, 4.2471014, 4.1975975 }, { 3.3748785, 3.2836577, 2.9220414, 2.7175317 }, { 2.3290083, 2.5560991, 4.3572168, 4.4372585 }, { 3.1512055, 3.2863613, 2.4475378, 2.3620003 } }, { { 0.62833231, 0.52378061, 0.55845033, 0.64883444 }, { 0.76905594, 1.1017801, 1.8714048, 1.5664383 }, { 1.5283278, 1.2423369, 0.62247385, 1.0341956 }, { 0.77484548, 1.6866409, 1.0307399, 1.4224643 }, { 0.85627405, 0.72516079, 0.70094339, 0.7547877 }, { 1.202842, 1.7650605, 1.5938526, 0.97031337 } } }, { { { -0.078108035, -0.049518839, 0.26950139, -0.51522828 }, { 0.43015518, -0.045354216, 0.094550359, -0.2395012 }, { -0.079900522, -0.082582235, 0.24464909, -0.5234896 }, { 0.38422945, -0.023833644, 0.07334288, -0.22827313 }, { -0.075370379, -0.05156594, 0.19883182, -0.45064193 }, { 0.46285395, 0.021899343, 0.10155287, -0.25974773 } }, { { 0.068681419, -0.32175988, 0.15143274, -0.0066205388 }, { -0.17060226, 0.31051319, -0.080511981, -0.1593209 }, { 0.08167251, -0.32517768, 0.10937023, -0.06941926 }, { -0.14580685, 0.32474959, -0.081718057, -0.11068378 }, { 0.053961394, -0.29322836, 0.10408839, -0.02243046 }, { -0.030598471, 0.34332821, -0.091528353, -0.16299796 } }, { { 0.99457629, 0.9455255, 0.95101899, 0.85702741 }, { 0.88648824, 0.94948647, 0.99225906, 0.95773484 }, { 0.99345131, 0.94204015, 0.96342357, 0.84919939 }, { 0.9116513, 0.94549969, 0.99395321, 0.96728511 }, { 0.99569447, 0.95465076, 0.97449039, 0.89242295 }, { 0.88590629, 0.93896015, 0.99061071, 0.95182077 } }, { { 3.6380949, 4.1749529, 4.1351439, 4.8389883 }, { 5.256362, 4.2027959, 3.6096892, 3.9848645 }, { 3.5689427, 3.8620869, 4.0023981, 4.8268584 }, { 5.1128497, 4.468934, 3.5851596, 4.047485 }, { 3.7014988, 4.1310058, 4.2446872, 5.3049323 }, { 4.8659881, 4.3133002, 3.4582876, 3.8863853 } }, { { 1.6276316, 0.7747672, 1.0485958, 0.73900224 }, { 0.72010795, 0.65403093, 1.3179681, 0.65610074 }, { 1.5881174, 0.55108527, 1.0509725, 0.72153362 }, { 1.1389053, 1.0905142, 1.6661598, 0.9987548 }, { 1.977914, 0.83001686, 1.0571479, 0.80249183 }, { 0.94107069, 0.80840873, 0.95379751, 0.50386367 } } }, { { { 0.015525428, -0.48038019, -0.021799698, 0.43629156 }, { 0.045681247, -0.55039024, -0.54573329, 0.57817853 }, { -0.045869129, -0.42209953, -0.14040829, 0.37787106 }, { 0.66327604, -0.70070311, -0.55261635, 0.63446196 }, { 0.015397585, -0.43515767, -0.021927897, 0.4203714 }, { 0.85681772, -0.65394729, -0.67557236, 0.60104142 } }, { { -0.31503888, -0.26745648, 0.26817896, 0.26548747 }, { -0.93282124, -0.033621213, 0.68374802, -0.10858524 }, { -0.21723689, -0.17935495, 0.38521982, 0.2578335 }, { -0.39913153, 0.23555359, 0.59589456, -0.19075103 }, { -0.28851798, -0.24142459, 0.28279261, 0.24766617 }, { -0.29435977, -0.25850549, 0.57790878, -0.200546 } }, { { 0.94895177, 0.83528552, 0.96312243, 0.85974768 }, { 0.35743218, 0.8342303, 0.48442112, 0.80865248 }, { 0.97504059, 0.88863029, 0.9120807, 0.88923301 }, { 0.63305523, 0.67344611, 0.58268761, 0.74904744 }, { 0.95735066, 0.86738225, 0.9589304, 0.87289711 }, { 0.42333878, 0.71100482, 0.45784651, 0.77364753 } }, { { 5.3641275, 5.2550422, 5.3103777, 5.2851215 }, { 5.2657045, 6.2095784, 6.9549598, 4.9205516 }, { 5.163385, 5.3141038, 4.9907618, 5.3583852 }, { 6.1257061, 6.1102338, 6.9549598, 5.3129951 }, { 5.3138838, 5.3257842, 5.3133783, 5.2687156 }, { 5.8915091, 6.153324, 6.9549598, 4.9568971 } }, { { 3.1221918, 1.1882615, 2.6991784, 1.1185048 }, { -0.2322432, -0.16590163, 0.088416958, 0.057399579 }, { 3.4395383, 1.5836276, 2.6242352, 1.2873336 }, { -0.23767634, -0.79425452, 0.20477899, 0.40461516 }, { 2.2521751, 1.1933374, 2.3309484, 1.0185309 }, { -0.099258385, -0.2173726, 0.0736866, 0.15470436 } } }, { { { 0.066050217, -0.33053278, -0.13771479, 0.33278465 }, { 0.00084467977, -0.50077778, -0.30083482, 0.6494273 }, { 0.24880159, -0.30354993, -0.15417892, 0.38203296 }, { -0.073325098, -0.4778777, 0.10779844, 0.66683723 }, { 0.15703809, -0.36335455, -0.15657631, 0.35926503 }, { 0.26127617, -0.29524368, -0.14490804, 0.65461301 } }, { { -0.57970022, -0.33939622, 0.72169742, 0.320959 }, { -0.38698206, -0.12730306, 0.65810895, 0.026509232 }, { -0.6199708, -0.34745658, 0.68683659, 0.34547285 }, { -0.3613378, -0.14006845, 0.65917895, 0.038446867 }, { -0.57778101, -0.35057776, 0.57837882, 0.36488991 }, { -0.50051482, -0.019174387, 0.50816239, 0.02682636 } }, { { 0.8121484, 0.88065787, 0.67837119, 0.88670158 }, { 0.92208686, 0.85616327, 0.69021085, -0.75996148 }, { 0.74413303, 0.88720424, 0.71027063, 0.85714604 }, { 0.92954743, 0.86718726, 0.74421946, -0.74421095 }, { 0.80094204, 0.86317363, 0.8006009, 0.85894353 }, { 0.82536033, 0.95522956, 0.8489833, -0.75548802 } }, { { 5.7725061, 5.1565901, 5.6224483, 5.0847054 }, { 5.7717118, 6.4180057, 6.9797014, -0.03290957 }, { 5.7847117, 5.2015529, 5.614561, 5.2019388 }, { 6.2613999, 6.5807982, 6.9797014, -0.032764603 }, { 5.823775, 5.2332343, 5.826694, 5.197143 }, { 6.3463188, 5.8174311, 6.9797014, -0.032766769 } }, { { 2.96787, 1.3557735, 2.0749129, 1.3066609 }, { -0.92782801, 0.0079162579, -0.33479446, 2.699659e-05 }, { 2.1997063, 3.1083252, 2.6810949, 1.8276262 }, { -0.48654719, -0.10954189, -0.32175132, 5.490092e-05 }, { 3.1970446, 1.787085, 3.062849, 1.6274811 }, { -0.78882801, -0.34050184, -0.59962127, 3.6554198e-05 } } } };
+const float low_quality_coeffs[7][5][6][4] = { { { { 0.0002037563f, 0.0045063655f, -0.0016408688f, 0.00012037493f }, { -9.1834951e-05f, -0.008947532f, -8.1524405e-05f, -3.9080094e-05f }, { -2.6038267e-05f, -6.8409667e-05f, 7.2175702e-05f, 0.25492775f }, { -9.9426044e-05f, 0.0025427756f, -0.00074437925f, 1.1773191e-05f }, { -3.2668211e-05f, 0.0026930659f, -4.824934e-05f, -0.0006835048f }, { -0.0002864144f, -0.0032220854f, 0.0021558286f, -0.00014573736f } }, { { 0.00030683201f, 0.0026819548f, -0.00060011756f, -0.0067169226f }, { -0.0030993251f, 0.0098575575f, 0.0022416671f, -8.9075401e-05f }, { 0.00052405626f, 0.00057860515f, 0.00011654518f, -0.048018609f }, { 0.00010850967f, -0.0088443512f, -0.0018168095f, 8.6633128e-05f }, { 0.003333989f, -0.0050956447f, -8.0414612e-05f, 0.0049721239f }, { -4.0961436e-05f, -8.5486984e-05f, 0.0058683066f, 2.2978359e-05f } }, { { 0.99999993f, 0.99998625f, 0.99999847f, 0.99997743f }, { 0.99999519f, 0.99991138f, 0.99999748f, 1.0f }, { 0.99999986f, 0.99999983f, 0.99999999f, 0.96576708f }, { 0.99999999f, 0.99995765f, 0.99999807f, 1.0f }, { 0.99999444f, 0.99998339f, 1.0f, 0.99998741f }, { 0.99999996f, 0.99999481f, 0.99998046f, 0.99999999f } }, { { -0.32267524f, -0.65409377f, -1.4666488f, 0.87153305f }, { -1.264365f, 0.89880861f, -1.2245906f, -0.88501403f }, { -0.31118682f, -0.086150323f, -0.58811532f, 1.1317711f }, { -1.2193493f, 1.250379f, -1.0871569f, -0.12694096f }, { -0.4012249f, -0.47436307f, -0.59661001f, 2.7313005f }, { -1.3109856f, 0.60929855f, 0.55672643f, -0.39880018f } }, { { 0.93273157f, 0.59530745f, 1.1994788f, 0.19102276f }, { 1.2272239f, 0.23245736f, 1.2577607f, 2.5491008f }, { 1.1210098f, 0.83074953f, 1.3049282f, -0.001940633f }, { 1.5839111f, 0.10520816f, 1.150458f, 2.3251789f }, { 0.688692f, 0.59807498f, 1.3374877f, 0.095746692f }, { 1.3054173f, 0.36604721f, 0.065870226f, 1.6496907f } } }, { { { 0.10348445f, -4.6771514e-07f, -0.011513131f, 8.8921052e-05f }, { -0.042152043f, 0.013143535f, 0.00029120107f, 0.036661611f }, { -0.04516036f, 0.011438473f, -0.0099289792f, -0.011707897f }, { -0.034779497f, 0.0090981166f, -5.4202726e-05f, 0.038592793f }, { -0.0071967376f, -0.0056614418f, -0.012278945f, 0.0056867462f }, { -0.037678514f, 0.011570177f, 0.00029044557f, 0.038583909f } }, { { 0.048320869f, 1.4603673e-05f, 0.0092672368f, 0.00033289199f }, { 0.0071001761f, -0.0090106091f, -0.0027305905f, -0.00221479f }, { -0.0027204116f, 0.00017921587f, 0.015296357f, -0.00010306185f }, { 0.0079350203f, -0.014772431f, -1.2410913e-05f, -0.0062296897f }, { 0.025087691f, 0.00086046427f, 0.015034685f, -0.00078224706f }, { 0.00074587265f, -0.014602074f, 0.00027338224f, -0.012848552f } }, { { 0.99345662f, 1.0f, 0.99989078f, 0.99999994f }, { 0.99908598f, 0.99987302f, 0.99999623f, 0.99932528f }, { 0.99897605f, 0.99993456f, 0.9998337f, 0.99993145f }, { 0.99936351f, 0.99984949f, 1.0f, 0.9992356f }, { 0.99965935f, 0.9999836f, 0.99981158f, 0.99998352f }, { 0.99928963f, 0.99982644f, 0.99999992f, 0.99917276f } }, { { 3.6882765f, 0.15963861f, 0.55983965f, 0.4075649f }, { 2.1169304f, 0.56463157f, 0.52957047f, 2.0117964f }, { 3.1080461f, 0.09682931f, 0.42125986f, 0.089254784f }, { 1.4247315f, 0.48411378f, -0.17039102f, 1.7431674f }, { 4.0339531f, 0.14046159f, 0.89848909f, 0.011661811f }, { 1.9787852f, 0.61750145f, 0.63514194f, 1.9359003f } }, { { 0.030848793f, 1.4472743f, 1.4356825f, 1.4078009f }, { 0.37639678f, 1.0793106f, 1.1945413f, 0.43983395f }, { 0.27451605f, 1.5256415f, 1.016769f, 1.4850575f }, { 0.54580883f, 1.1332879f, 3.1331784f, 0.60772955f }, { 0.11785158f, 1.3928946f, 0.94998805f, 1.0377182f }, { 0.2842108f, 1.0026911f, 1.9064553f, 0.27147854f } } }, { { { -0.096789259f, 0.10326967f, 0.0011799959f, -0.03077328f }, { 0.08342021f, 0.033260738f, -0.00045864451f, -0.021450568f }, { -0.093369441f, -0.05807574f, -0.033745214f, 0.023817208f }, { 0.056747754f, 0.031140512f, 0.00019362509f, -0.023727797f }, { -0.084538386f, -0.040545412f, -0.0076838784f, 0.03424599f }, { 0.074312056f, 0.027619787f, 0.0015509082f, -0.031043528f } }, { { -0.0085160473f, -0.012179292f, 0.0049910118f, 0.020224799f }, { 0.022559343f, -0.016273333f, -0.0069382139f, 0.00058083224f }, { -0.001115062f, 0.035002846f, -0.0038974773f, -0.039378629f }, { 0.0014921617f, -0.00058523872f, -0.0011606685f, 0.02807528f }, { -0.021454809f, 0.052957852f, -0.0022083677f, -0.027956663f }, { -0.016486487f, -0.0040233682f, 0.00029949558f, 0.021924605f } }, { { 0.99526846f, 0.99457883f, 0.99998685f, 0.99932175f }, { 0.99625908f, 0.99931422f, 0.99997583f, 0.99976974f }, { 0.99563091f, 0.99769836f, 0.99942287f, 0.99894047f }, { 0.99838743f, 0.99951485f, 0.99999931f, 0.99932416f }, { 0.99618922f, 0.99777329f, 0.99996804f, 0.99902234f }, { 0.99709875f, 0.9996104f, 0.99999875f, 0.99927754f } }, { { 3.0342011f, 4.8022834f, 1.3814123f, 1.5280754f }, { 2.9043837f, 1.7325954f, 1.422223f, 2.0569263f }, { 3.0358722f, 5.3331504f, 1.5680146f, 1.6079289f }, { 3.2062833f, 1.5368069f, 1.0484709f, 1.5399477f }, { 2.4471653f, 4.0916696f, 1.5060688f, 1.5807009f }, { 2.6932695f, 1.5161537f, 1.3991175f, 1.6301918f } }, { { 0.50787578f, 0.17735471f, 1.4006765f, 1.0878482f }, { 0.69514518f, 1.6765187f, 1.2224869f, 1.3461327f }, { 0.71381288f, 0.17509216f, 1.2712934f, 0.94575821f }, { 1.1817337f, 1.796984f, 1.8671538f, 1.5708691f }, { 0.55621228f, 0.38291359f, 1.4128781f, 0.82625349f }, { 0.72441647f, 1.005794f, 1.5522327f, 1.6032524f } } }, { { { -0.00041301094f, -0.095882618f, 0.26932618f, -0.25137214f }, { 0.13737415f, -0.12694293f, -0.0090389663f, 0.07227623f }, { -0.005236407f, -0.0072961249f, 0.27776083f, -0.19536433f }, { 0.12781899f, -0.042881667f, -0.095979169f, 0.088937396f }, { 0.037496084f, -0.090547583f, 0.22112334f, -0.21930294f }, { 0.13353408f, -0.084346121f, -0.011365728f, 0.043459312f } }, { { -0.05799135f, -0.048612281f, 0.02422989f, 0.015536268f }, { -0.083144241f, 0.039381032f, 0.018705957f, 0.029297922f }, { 0.026364989f, -0.041927591f, 0.036718516f, 0.0050376168f }, { -0.11562256f, 0.043521976f, -0.014481644f, 0.01529188f }, { -0.047859898f, -0.057779647f, -0.053171395f, -0.0063193506f }, { -0.028781196f, 0.041145059f, -0.00018523142f, 0.053524246f } }, { { 0.998317f, 0.99420489f, 0.96274416f, 0.96776581f }, { 0.98702349f, 0.99112796f, 0.99978417f, 0.99695425f }, { 0.99963867f, 0.99909401f, 0.95994827f, 0.9807178f }, { 0.98503489f, 0.99813175f, 0.99527799f, 0.99591983f }, { 0.99815003f, 0.99421459f, 0.97379529f, 0.97563635f }, { 0.99062621f, 0.99558667f, 0.99993539f, 0.99762039f } }, { { 2.3221943f, 2.5383575f, 4.3177232f, 4.2016467f }, { 3.1936529f, 3.0443024f, 2.548962f, 2.7636456f }, { 2.5923827f, 2.3497949f, 4.2471014f, 4.1975975f }, { 3.3748785f, 3.2836577f, 2.9220414f, 2.7175317f }, { 2.3290083f, 2.5560991f, 4.3572168f, 4.4372585f }, { 3.1512055f, 3.2863613f, 2.4475378f, 2.3620003f } }, { { 0.62833231f, 0.52378061f, 0.55845033f, 0.64883444f }, { 0.76905594f, 1.1017801f, 1.8714048f, 1.5664383f }, { 1.5283278f, 1.2423369f, 0.62247385f, 1.0341956f }, { 0.77484548f, 1.6866409f, 1.0307399f, 1.4224643f }, { 0.85627405f, 0.72516079f, 0.70094339f, 0.7547877f }, { 1.202842f, 1.7650605f, 1.5938526f, 0.97031337f } } }, { { { -0.078108035f, -0.049518839f, 0.26950139f, -0.51522828f }, { 0.43015518f, -0.045354216f, 0.094550359f, -0.2395012f }, { -0.079900522f, -0.082582235f, 0.24464909f, -0.5234896f }, { 0.38422945f, -0.023833644f, 0.07334288f, -0.22827313f }, { -0.075370379f, -0.05156594f, 0.19883182f, -0.45064193f }, { 0.46285395f, 0.021899343f, 0.10155287f, -0.25974773f } }, { { 0.068681419f, -0.32175988f, 0.15143274f, -0.0066205388f }, { -0.17060226f, 0.31051319f, -0.080511981f, -0.1593209f }, { 0.08167251f, -0.32517768f, 0.10937023f, -0.06941926f }, { -0.14580685f, 0.32474959f, -0.081718057f, -0.11068378f }, { 0.053961394f, -0.29322836f, 0.10408839f, -0.02243046f }, { -0.030598471f, 0.34332821f, -0.091528353f, -0.16299796f } }, { { 0.99457629f, 0.9455255f, 0.95101899f, 0.85702741f }, { 0.88648824f, 0.94948647f, 0.99225906f, 0.95773484f }, { 0.99345131f, 0.94204015f, 0.96342357f, 0.84919939f }, { 0.9116513f, 0.94549969f, 0.99395321f, 0.96728511f }, { 0.99569447f, 0.95465076f, 0.97449039f, 0.89242295f }, { 0.88590629f, 0.93896015f, 0.99061071f, 0.95182077f } }, { { 3.6380949f, 4.1749529f, 4.1351439f, 4.8389883f }, { 5.256362f, 4.2027959f, 3.6096892f, 3.9848645f }, { 3.5689427f, 3.8620869f, 4.0023981f, 4.8268584f }, { 5.1128497f, 4.468934f, 3.5851596f, 4.047485f }, { 3.7014988f, 4.1310058f, 4.2446872f, 5.3049323f }, { 4.8659881f, 4.3133002f, 3.4582876f, 3.8863853f } }, { { 1.6276316f, 0.7747672f, 1.0485958f, 0.73900224f }, { 0.72010795f, 0.65403093f, 1.3179681f, 0.65610074f }, { 1.5881174f, 0.55108527f, 1.0509725f, 0.72153362f }, { 1.1389053f, 1.0905142f, 1.6661598f, 0.9987548f }, { 1.977914f, 0.83001686f, 1.0571479f, 0.80249183f }, { 0.94107069f, 0.80840873f, 0.95379751f, 0.50386367f } } }, { { { 0.015525428f, -0.48038019f, -0.021799698f, 0.43629156f }, { 0.045681247f, -0.55039024f, -0.54573329f, 0.57817853f }, { -0.045869129f, -0.42209953f, -0.14040829f, 0.37787106f }, { 0.66327604f, -0.70070311f, -0.55261635f, 0.63446196f }, { 0.015397585f, -0.43515767f, -0.021927897f, 0.4203714f }, { 0.85681772f, -0.65394729f, -0.67557236f, 0.60104142f } }, { { -0.31503888f, -0.26745648f, 0.26817896f, 0.26548747f }, { -0.93282124f, -0.033621213f, 0.68374802f, -0.10858524f }, { -0.21723689f, -0.17935495f, 0.38521982f, 0.2578335f }, { -0.39913153f, 0.23555359f, 0.59589456f, -0.19075103f }, { -0.28851798f, -0.24142459f, 0.28279261f, 0.24766617f }, { -0.29435977f, -0.25850549f, 0.57790878f, -0.200546f } }, { { 0.94895177f, 0.83528552f, 0.96312243f, 0.85974768f }, { 0.35743218f, 0.8342303f, 0.48442112f, 0.80865248f }, { 0.97504059f, 0.88863029f, 0.9120807f, 0.88923301f }, { 0.63305523f, 0.67344611f, 0.58268761f, 0.74904744f }, { 0.95735066f, 0.86738225f, 0.9589304f, 0.87289711f }, { 0.42333878f, 0.71100482f, 0.45784651f, 0.77364753f } }, { { 5.3641275f, 5.2550422f, 5.3103777f, 5.2851215f }, { 5.2657045f, 6.2095784f, 6.9549598f, 4.9205516f }, { 5.163385f, 5.3141038f, 4.9907618f, 5.3583852f }, { 6.1257061f, 6.1102338f, 6.9549598f, 5.3129951f }, { 5.3138838f, 5.3257842f, 5.3133783f, 5.2687156f }, { 5.8915091f, 6.153324f, 6.9549598f, 4.9568971f } }, { { 3.1221918f, 1.1882615f, 2.6991784f, 1.1185048f }, { -0.2322432f, -0.16590163f, 0.088416958f, 0.057399579f }, { 3.4395383f, 1.5836276f, 2.6242352f, 1.2873336f }, { -0.23767634f, -0.79425452f, 0.20477899f, 0.40461516f }, { 2.2521751f, 1.1933374f, 2.3309484f, 1.0185309f }, { -0.099258385f, -0.2173726f, 0.0736866f, 0.15470436f } } }, { { { 0.066050217f, -0.33053278f, -0.13771479f, 0.33278465f }, { 0.00084467977f, -0.50077778f, -0.30083482f, 0.6494273f }, { 0.24880159f, -0.30354993f, -0.15417892f, 0.38203296f }, { -0.073325098f, -0.4778777f, 0.10779844f, 0.66683723f }, { 0.15703809f, -0.36335455f, -0.15657631f, 0.35926503f }, { 0.26127617f, -0.29524368f, -0.14490804f, 0.65461301f } }, { { -0.57970022f, -0.33939622f, 0.72169742f, 0.320959f }, { -0.38698206f, -0.12730306f, 0.65810895f, 0.026509232f }, { -0.6199708f, -0.34745658f, 0.68683659f, 0.34547285f }, { -0.3613378f, -0.14006845f, 0.65917895f, 0.038446867f }, { -0.57778101f, -0.35057776f, 0.57837882f, 0.36488991f }, { -0.50051482f, -0.019174387f, 0.50816239f, 0.02682636f } }, { { 0.8121484f, 0.88065787f, 0.67837119f, 0.88670158f }, { 0.92208686f, 0.85616327f, 0.69021085f, -0.75996148f }, { 0.74413303f, 0.88720424f, 0.71027063f, 0.85714604f }, { 0.92954743f, 0.86718726f, 0.74421946f, -0.74421095f }, { 0.80094204f, 0.86317363f, 0.8006009f, 0.85894353f }, { 0.82536033f, 0.95522956f, 0.8489833f, -0.75548802f } }, { { 5.7725061f, 5.1565901f, 5.6224483f, 5.0847054f }, { 5.7717118f, 6.4180057f, 6.9797014f, -0.03290957f }, { 5.7847117f, 5.2015529f, 5.614561f, 5.2019388f }, { 6.2613999f, 6.5807982f, 6.9797014f, -0.032764603f }, { 5.823775f, 5.2332343f, 5.826694f, 5.197143f }, { 6.3463188f, 5.8174311f, 6.9797014f, -0.032766769f } }, { { 2.96787f, 1.3557735f, 2.0749129f, 1.3066609f }, { -0.92782801f, 0.0079162579f, -0.33479446f, 2.699659e-05f }, { 2.1997063f, 3.1083252f, 2.6810949f, 1.8276262f }, { -0.48654719f, -0.10954189f, -0.32175132f, 5.490092e-05f }, { 3.1970446f, 1.787085f, 3.062849f, 1.6274811f }, { -0.78882801f, -0.34050184f, -0.59962127f, 3.6554198e-05f } } } };
-const float high_quality_coeffs[7][5][3][24][4] = { { { { { -4.8355339e-06, -4.4902569e-05, -9.2632249e-05, -0.00053773136 }, { 0.0040143823, -0.00060900339, -0.0095301923, -0.0053956011 }, { -0.0005923892, -3.6901978e-05, -5.6694857e-06, -0.00017018564 }, { 0.0012441402, 0.02236187, 0.022751769, 0.0062788948 }, { 0.00013810055, -2.2709815e-05, 0.0054849671, -1.6599195e-05 }, { -0.020320408, -0.017066319, -0.017457746, 0.022910628 }, { 0.00024171724, 9.7419073e-05, -0.00047804272, -0.00010093683 }, { 7.6988167e-05, 1.8551597e-05, -5.7692813e-05, -3.332362e-05 }, { -0.00062766208, 2.713742e-05, 0.00026511682, 2.3841873e-05 }, { -0.00043656844, 0.0028645469, 0.0049817085, 0.0080221478 }, { -3.3210444e-05, -8.0852386e-05, -2.2111492e-06, -8.4430827e-05 }, { 0.010967284, 0.018811225, 0.017569463, -0.0046944996 }, { -0.00018391248, -0.00010462174, -0.00017726, -0.00018490133 }, { 0.00012591989, 0.015965386, 0.015964059, -0.0078018431 }, { -0.006125333, -8.2224165e-05, -0.00020500151, -0.00025207244 }, { -0.00016320041, -0.0001279242, 0.00014038799, 8.1359421e-05 }, { -0.00064341098, -0.0011265496, -0.0011634792, -0.00081607159 }, { 0.00089294825, 0.0061923653, 0.0052662392, -0.00058227469 }, { -2.4001308e-05, -1.3534224e-05, -1.4720478e-05, -2.5120827e-05 }, { 0.00029964918, -0.0045658543, -0.0045581938, 0.0017106208 }, { 7.5790173e-05, -1.8265415e-05, 1.5918205e-05, 5.8524021e-05 }, { 0.0011669872, -0.00017571882, -0.00017190275, -0.0023833977 }, { 0.0033487264, -0.0066535821, -0.0066413786, -0.0032332601 }, { -3.6468807e-05, -0.00068145131, -9.8190714e-05, -8.7169435e-05 } }, { { -0.0010440653, -8.9750644e-05, 4.971182e-05, 0.0044618878 }, { 0.0078333883, -0.00090884312, -0.00046920549, -0.002465051 }, { -0.0058778609, 0.0026554895, -0.00031880506, -0.00010649091 }, { -0.0015095448, 0.0094026506, 0.009492703, 0.0024572848 }, { 0.0047331786, 0.00070722401, 0.0028798817, -0.00039779892 }, { -0.0089878107, -0.0095474878, -0.0097187652, 0.008765907 }, { -4.0435321e-05, -0.00061813281, -0.0060490143, 0.0016259965 }, { -0.00014720558, -1.0601876e-05, 0.00014757138, 0.00016227641 }, { -0.010428289, -0.00031812813, -0.0016172213, -0.00012022134 }, { 0.0040517131, 0.0072972763, 0.0060433905, 0.0025041645 }, { 0.00014090924, 0.00027612853, 0.00015961665, 0.0002605418 }, { -0.00020653783, -0.00048482867, -0.00058472338, 0.00026413759 }, { 0.00056712638, 0.00026385353, 0.00035484947, 0.00033212447 }, { -0.00094663094, 0.0029891757, 0.0029887838, -0.0026583585 }, { -0.0017400246, 0.00042350567, 0.00086128207, 0.00039863587 }, { 0.00059604848, 0.00027495434, -0.00059956434, -4.4981673e-05 }, { -0.010211343, -0.0080580409, -0.0085333216, 0.0023258717 }, { 0.00042832593, 0.0056750222, 0.0048059635, -0.0092168281 }, { 3.0214612e-05, 4.540924e-06, 1.7239937e-05, 2.783598e-05 }, { 0.00029393335, -4.5128636e-05, -4.3089017e-05, 0.00030682556 }, { -4.7077735e-05, -1.3596835e-05, -0.0015338149, -7.4957991e-05 }, { -0.00097136844, 0.00018564298, 0.00021815754, 0.0015095577 }, { 0.00043929849, -0.0014691094, -0.0014671742, -0.00029365954 }, { 8.8554045e-05, 0.0062500772, 0.0001495049, 0.00021007601 } }, { { 0.0020307077, 0.0020947445, 0.0017438295, 0.0084822342 }, { -0.0069727503, -0.0010131005, 0.0055261321, -0.0020442588 }, { 0.00031035611, 0.00010839441, 3.7359209e-06, 4.3112837e-05 }, { 9.1207794e-05, 0.0050148169, 0.0051071455, 0.0033679057 }, { -0.00090101737, -0.00053793176, -0.0025829621, 0.0003241927 }, { -0.0019244714, -0.0033690472, -0.0035193497, 0.0027653636 }, { -0.00065476293, -0.00017787403, 0.00040383136, -0.00018123957 }, { -0.00030640434, -0.00018961553, -0.00011036218, -0.00015793049 }, { 0.001110592, -0.00021252645, 0.00015849587, -3.7758317e-05 }, { 0.00077967828, -0.0051765235, -0.0078505592, -0.010796339 }, { -1.2024951e-05, 6.48806e-05, -3.9409005e-05, 7.4639306e-05 }, { -0.00017352424, -0.00037802595, -0.00045639468, 0.00016843169 }, { -4.2866244e-05, -4.3730932e-06, 7.3574276e-05, 5.6076779e-05 }, { 0.00024802387, 0.0018053101, 0.0018042994, -0.0016700716 }, { 0.0082698262, -0.00014605077, 0.0004377682, 8.1585074e-05 }, { -4.494343e-06, 0.00019781519, -0.00058910268, -0.00027360572 }, { 0.0013016934, 0.0021020456, 0.0022718598, -0.0059377824 }, { 0.002185371, -0.0080788056, -0.0071952836, 0.0039688918 }, { 0.00013048617, 0.0001738124, 0.00012978924, 0.00013813358 }, { 0.00032386518, 0.00023046021, 0.00023064714, 0.00033762343 }, { 0.00023643771, 0.00019652953, 0.0013083597, 0.00024739959 }, { -0.0063957036, -0.0055319023, -0.0054742301, -0.0037204932 }, { -0.0005510683, -0.0007715413, -0.00077385934, -0.001009415 }, { 0.00017904616, -0.00096137522, 0.00030252599, -2.2478138e-05 } } }, { { { -0.00038948583, -0.00040817153, -0.00041280315, -0.0010985631 }, { 0.0025695337, 0.00042904308, 0.0054649973, -0.0055079106 }, { 0.00052050672, 2.2618679e-05, 0.00024058975, -0.00012632201 }, { -0.013468886, 0.0079396715, 0.0079402246, 0.026283756 }, { -7.922122e-05, -3.4761763e-06, -0.0041716347, 0.0001478739 }, { 0.023716381, -0.016415262, -0.015296927, -0.021050827 }, { 3.7654391e-05, 0.00012765816, -0.0001337099, 0.00051483398 }, { 0.00015671907, 0.00010686796, 2.1421097e-05, -2.2281569e-05 }, { 3.1779413e-06, 0.00010449913, -0.00018303614, 7.5382489e-05 }, { -0.00020526765, -0.0011333575, -0.0050720108, 0.0051482782 }, { 4.0450357e-05, 1.0808158e-05, -2.3316095e-05, 9.7767333e-06 }, { -0.019107229, 0.010907324, 0.0048969594, 0.017851514 }, { 7.4048796e-05, -7.041835e-06, 8.0226174e-05, 5.1714105e-05 }, { -0.016564627, 0.0023486944, 0.0023601429, 0.016005248 }, { -0.004528284, 3.6291049e-05, 2.4229636e-05, 0.0024853948 }, { 5.6882054e-05, 6.8805135e-05, 0.00013119897, 0.00010339801 }, { 0.00021183341, 0.0008203137, -7.204401e-05, 0.00062599728 }, { -0.00099314707, 0.0030198762, -0.0038989955, 0.00055571214 }, { -7.4247984e-05, -8.3993373e-05, -5.9133252e-05, -7.7411989e-05 }, { 0.0054296732, -0.00057858871, -0.00058417754, -0.005072911 }, { -0.00019259782, -0.00018772532, -4.2959783e-05, -0.0001827295 }, { -0.00029351865, 0.00013736372, 0.00016666048, 0.00020873447 }, { 0.0069341659, 0.0027612928, 0.0027538377, -0.0061770317 }, { 4.2584714e-05, -0.00037063589, -9.0693123e-06, 0.00011845784 } }, { { 0.0028834168, 0.0031807308, 0.0031352582, 0.01064051 }, { 0.0049297987, -4.2149356e-05, -0.0014926841, -0.0002300371 }, { 0.0020396303, -0.00066042794, -6.4359283e-05, 0.00017835163 }, { -0.0025767816, 0.0025148152, 0.0025224779, 0.0043006543 }, { -0.00042084416, -0.00013534305, 0.002453623, -4.0707749e-05 }, { -0.0001803055, -0.0010450606, -0.00084380806, 0.00014843677 }, { -0.0064067107, 0.00011012652, -0.0022552747, -0.00080508294 }, { -0.00017778763, -4.296789e-05, 0.00015343883, 0.00025036711 }, { 0.002825978, -0.00031945362, -0.00031987612, -0.00021117763 }, { 0.00032791249, -0.00049524542, 0.0049368722, -0.0017186408 }, { -0.0001685943, -0.00016766033, -0.0001755097, -0.00017067307 }, { 0.00023939157, -0.00011793706, -6.0620575e-05, -0.0002706595 }, { -2.9718673e-05, 3.5950879e-05, 1.839844e-05, -2.8718148e-05 }, { -0.0017260981, 0.00012145435, 0.0001236679, 0.0018292155 }, { 0.0036086706, 0.0001026898, -2.5518889e-05, -0.00019830236 }, { -0.00031546808, -0.00042107458, -0.00059963868, -0.00061472497 }, { -0.0074719522, 0.0015719596, -0.0033624165, -0.0092664101 }, { -0.0011285776, 0.0018601435, 0.00052060704, -1.5554679e-05 }, { 4.9853171e-05, 7.3650922e-05, 3.4080107e-05, 5.4255445e-05 }, { 0.00015102779, -2.58105e-05, -2.5851018e-05, -4.5185316e-05 }, { 0.0002057452, 0.00019037765, 0.0040052198, 0.00020046579 }, { 0.0027727314, 0.0040749211, 0.0036050794, 0.0034635222 }, { 0.00042503689, 0.00056027382, 0.00056052971, -8.2485044e-05 }, { -5.6309634e-05, 0.0019722025, 6.4267434e-05, -0.00020376412 } }, { { 0.0051607661, 0.0047835358, 0.0047658352, 0.0054281814 }, { -0.0040939561, 0.0012119183, -0.0023408179, -0.00055891234 }, { -0.0031939804, -0.0015954053, -0.00018570689, 0.00028849431 }, { -0.0075625096, 0.0033878734, 0.0033797415, 0.010242674 }, { -0.002293562, 0.00024245282, 0.0019455622, 0.0039550747 }, { 0.0090386754, -0.0086947671, -0.0082684939, -0.0075613346 }, { -0.00085735117, 3.4822634e-05, -0.0024653972, -0.00090964985 }, { -0.00013750587, -0.00010089501, 6.3555498e-05, 0.0002758494 }, { 0.0060496328, -0.00032664426, 0.0005979723, -0.00018819024 }, { 0.00072724184, 0.00082242885, 0.0045668772, -0.0054557456 }, { -9.6167811e-05, 7.9856612e-05, 0.00015672473, 8.0901183e-05 }, { 0.00038859448, -0.00025360755, -0.00017624981, -0.00049125519 }, { -8.8277361e-05, 2.4159527e-05, -0.00016014627, -2.7854246e-05 }, { -0.0037308647, 0.00041434141, 0.0004167221, 0.0037190244 }, { 0.00050696744, -4.6752715e-05, 0.00033183668, -0.0025882828 }, { -0.00015915702, -0.0002325901, -0.00036157415, -0.00016391937 }, { 0.00012320153, 0.0026711886, 0.0018414591, -0.0058215223 }, { -0.0029409983, -0.00015460743, 0.0031951665, 0.0074654329 }, { 9.9084813e-05, 9.1785865e-05, 5.9300007e-05, 0.00010463304 }, { 0.00024773341, -2.5723276e-05, -2.5709769e-05, -0.00015357475 }, { 0.000416633, 0.00028749584, -0.0038632071, 0.00039869488 }, { 0.00018344152, 3.0811778e-05, -0.00010240082, 0.00059301197 }, { 0.0019217461, 0.00034404024, 0.00034318823, -0.0015867375 }, { -0.00011928879, 0.001178769, -5.8655983e-05, -0.00028461439 } } }, { { { 0.99999992, 0.99999992, 0.99999991, 0.99999925 }, { 0.99998864, 0.99999972, 0.99993965, 0.99997027 }, { 0.99999969, 1, 0.99999997, 0.99999998 }, { 0.99990852, 0.99971841, 0.99970961, 0.9996348 }, { 0.99999999, 1, 0.99997626, 0.99999999 }, { 0.99951219, 0.9997196, 0.99973058, 0.99951587 }, { 0.99999997, 0.99999999, 0.99999988, 0.99999986 }, { 0.99999998, 0.99999999, 1, 1 }, { 0.9999998, 0.99999999, 0.99999995, 1 }, { 0.99999988, 0.99999525, 0.99997473, 0.99995457 }, { 1, 1, 1, 1 }, { 0.99975729, 0.99976356, 0.99983365, 0.99982963 }, { 0.99999998, 0.99999999, 0.99999998, 0.99999998 }, { 0.99986279, 0.99986979, 0.99986978, 0.99984147 }, { 0.99997099, 1, 0.99999998, 0.99999688 }, { 0.99999999, 0.99999999, 0.99999998, 0.99999999 }, { 0.99999977, 0.99999903, 0.99999932, 0.99999947 }, { 0.99999911, 0.99997627, 0.99997853, 0.99999968 }, { 1, 1, 1, 1 }, { 0.99998521, 0.99998941, 0.99998944, 0.99998567 }, { 0.99999998, 0.99999998, 1, 0.99999998 }, { 0.99999928, 0.99999998, 0.99999997, 0.99999714 }, { 0.99997035, 0.99997405, 0.99997415, 0.99997569 }, { 1, 0.9999997, 1, 0.99999999 } }, { { 0.00015966941, 0.00014262676, 0.00020165066, 0.00021618914 }, { 2.8140907e-06, -0.00020325872, 0.00017736728, 6.0386679e-05 }, { -0.0003187876, 5.8862288e-05, 6.2281085e-05, 1.7339908e-05 }, { -2.6587911e-05, -0.00011609007, -0.00011725093, -7.6114852e-05 }, { 0.00013665042, 5.2703844e-06, -0.00031293536, 3.8693931e-05 }, { -9.8143069e-05, -0.00012816332, -0.00012926252, -0.00010623032 }, { 0.00032342312, -1.9200091e-06, -0.00010691485, 6.3541059e-05 }, { -8.0643542e-06, 9.7622933e-06, 2.9924822e-05, -1.988333e-05 }, { 0.00025318464, 1.2588649e-05, 1.4665927e-05, 9.3294806e-06 }, { 2.6875391e-06, -2.4928123e-05, 2.251878e-05, 0.00011026808 }, { 1.767638e-05, 1.0309044e-05, 2.4765648e-05, 1.4397941e-05 }, { 6.9000935e-06, 1.0637078e-05, 1.087637e-05, 6.3065784e-06 }, { 5.532953e-05, 1.6231463e-05, 4.9564371e-05, 3.6623041e-05 }, { -1.6958729e-05, -3.1627491e-05, -3.1524511e-05, -2.9954116e-05 }, { 8.9045086e-05, 2.1005026e-05, 1.3016463e-05, 8.7863053e-05 }, { -2.75035e-05, -3.0440427e-05, -3.5356286e-05, 5.9609261e-06 }, { 0.0001586274, 4.0711165e-05, 3.1563135e-05, 0.0001385483 }, { 8.5548316e-06, 7.4531928e-05, -3.7017413e-05, 2.6874037e-05 }, { -1.3750655e-05, -8.2756032e-06, -2.7214983e-07, -1.4830115e-05 }, { -7.0798362e-07, -3.3187173e-07, -3.3266762e-07, -5.7113855e-07 }, { 4.3615512e-05, -4.4076433e-06, 8.9239586e-06, 3.7278531e-05 }, { -7.7366773e-06, 4.610399e-06, 4.3762687e-06, -5.64067e-06 }, { -3.2666125e-06, -1.0773146e-05, -1.0861965e-05, -1.3327232e-06 }, { -9.1178305e-06, 0.00030171207, -1.5395234e-05, -2.0695425e-07 } }, { { 0.00017159464, 0.00014699558, 0.00018752678, 0.0002227926 }, { -4.6524822e-05, -0.00010460271, 0.00034735325, 0.00010082238 }, { -6.8269006e-05, 1.4343751e-05, 7.7283393e-06, 2.5347136e-05 }, { -6.6149546e-05, -7.1168993e-05, -7.0621016e-05, -0.00015246746 }, { 7.12022e-05, 3.8790461e-05, -0.00023994449, 6.6792921e-05 }, { -0.00014735813, -0.00012658353, -0.00012162488, -0.00012106777 }, { 0.00015161388, -1.4439153e-05, -3.7629923e-06, 8.3140788e-06 }, { 4.0175416e-05, 2.5380268e-05, -2.2894421e-06, 4.6374378e-06 }, { 0.00028906023, 1.7695243e-05, 5.3790587e-06, 1.631859e-05 }, { 1.8890685e-05, -1.6898275e-05, 2.1007663e-05, 6.5179363e-05 }, { -3.9142595e-06, 2.5745488e-05, 1.0803197e-05, 2.7099749e-05 }, { 9.4245546e-06, 1.0010075e-05, 9.058324e-06, 9.8703427e-06 }, { -2.3441863e-06, 2.5490323e-05, -1.0097654e-05, 4.0554798e-05 }, { -4.1443921e-05, -1.996316e-05, -2.0000841e-05, -4.7495655e-05 }, { 0.00012591695, 5.6179903e-05, -1.8415869e-05, -3.8697972e-05 }, { 2.6719505e-05, 2.4195362e-06, 2.4287424e-05, 3.4703059e-05 }, { 7.3804931e-05, 4.9784871e-05, 3.1159931e-06, 0.00015857197 }, { -0.00010634331, -1.6427658e-05, -7.4874306e-05, -6.2620255e-05 }, { -4.2561214e-06, -1.6123179e-05, -1.5507273e-05, -1.2909924e-05 }, { -1.2210463e-06, 1.1546399e-06, 1.1413892e-06, -1.3465856e-06 }, { 3.4909884e-05, -1.2677793e-05, 0.00011543701, 2.413091e-05 }, { -2.1953323e-05, -4.6244252e-06, -3.5624435e-06, 4.2293671e-06 }, { -1.1392936e-05, -4.3970369e-06, -4.4264864e-06, -1.208518e-05 }, { -4.4002617e-05, 0.00020912348, -3.9617824e-05, -4.1725112e-05 } } }, { { { -0.32504349, -0.32502096, -0.32501094, -0.32423576 }, { -0.65602876, -0.65622598, -0.65567173, -0.65525128 }, { -1.4666488, -1.4666488, -1.4666488, -1.4666488 }, { 0.87168363, 0.87181364, 0.87181792, 0.8718169 }, { -1.264365, -1.264365, -1.264365, -1.264365 }, { 0.89917968, 0.89916889, 0.89916525, 0.89927374 }, { -1.2245906, -1.2245906, -1.2245906, -1.2245906 }, { -0.8885678, -0.88856217, -0.88856327, -0.88855044 }, { -0.31799095, -0.31916566, -0.31907669, -0.31918911 }, { -0.08987958, -0.090342401, -0.090004674, -0.090222398 }, { -0.59425693, -0.59433999, -0.59429118, -0.59433553 }, { 1.1317575, 1.1317475, 1.1317412, 1.1317494 }, { -1.2193493, -1.2193493, -1.2193493, -1.2193493 }, { 1.2506981, 1.250675, 1.250675, 1.2506569 }, { -1.08782, -1.0877793, -1.0878022, -1.0878025 }, { -0.13925598, -0.13932948, -0.13919658, -0.13913403 }, { -0.40394684, -0.4042314, -0.40436178, -0.40402218 }, { -0.47762966, -0.47745572, -0.47767784, -0.47713093 }, { -0.60177181, -0.60176862, -0.60177347, -0.60177079 }, { 2.7311956, 2.7311911, 2.7311911, 2.731191 }, { -1.3109856, -1.3109856, -1.3109856, -1.3109856 }, { 0.60942644, 0.60941369, 0.6094123, 0.60944198 }, { 0.55675448, 0.55672275, 0.55672303, 0.5567542 }, { -0.40637059, -0.4057945, -0.40635768, -0.40636681 } }, { { -0.0016154222, -0.0015930079, -0.0015828998, -0.00087447165 }, { -0.0011262472, -0.001324462, -0.00094895016, -0.00062188189 }, { 0, 0, 0, 0 }, { 9.7616744e-05, 0.00010718899, 0.00010718606, 0.00012665246 }, { 0, 0, 0, 0 }, { 0.00013476236, 6.982272e-05, 6.8208505e-05, 0.00014604742 }, { 0, 0, 0, 0 }, { -0.0031089951, -0.0031071196, -0.0031207245, -0.0031097054 }, { -0.0027808116, -0.0035049857, -0.0034100135, -0.0035192661 }, { -0.0018291474, -0.0019603285, -0.0018919656, -0.0019656229 }, { -0.0034301741, -0.0034912573, -0.0034474395, -0.0034893985 }, { -6.156701e-06, -9.8568527e-06, -1.2383692e-05, -9.9984205e-06 }, { 0, 0, 0, 0 }, { 0.00011838153, 0.00011008679, 0.00011008878, 0.00010536608 }, { -0.0006246638, -0.00058479459, -0.00061327452, -0.00061085433 }, { -0.0059197749, -0.0059778169, -0.0059586015, -0.0058798299 }, { -0.0013246996, -0.0016061786, -0.0016081246, -0.0014374546 }, { -0.001593227, -0.0014706843, -0.0015974008, -0.001341579 }, { -0.0027930604, -0.0027920013, -0.0027939865, -0.0027928528 }, { -1.8908723e-06, -4.266382e-06, -4.2210172e-06, -5.0155215e-06 }, { 0, 0, 0, 0 }, { 0.00018508026, 0.00019774537, 0.00019744661, 0.00019538593 }, { 2.3243747e-05, 1.7291398e-05, 1.7309712e-05, 2.9261396e-05 }, { -0.0041402471, -0.0037085946, -0.0041294876, -0.0041316136 } }, { { -0.0018899732, -0.0018719182, -0.0018661076, -0.0012234594 }, { -0.0012968123, -0.0012971446, -0.00093522854, -0.00066475268 }, { 0, 0, 0, 0 }, { 9.1054464e-05, 0.00014124217, 0.00014156806, 0.00012014953 }, { 0, 0, 0, 0 }, { 0.00017026995, 0.00010528413, 0.00010537941, 0.00015698848 }, { 0, 0, 0, 0 }, { -0.0025812972, -0.0025835894, -0.0025789321, -0.002554949 }, { -0.0035568863, -0.0042988014, -0.0042155548, -0.004312546 }, { -0.0024184575, -0.0025111277, -0.0024654994, -0.0023980076 }, { -0.0036993386, -0.0037113013, -0.0036987284, -0.0037094875 }, { -5.074861e-06, -1.1367399e-05, -1.4819989e-05, -9.2705899e-06 }, { 0, 0, 0, 0 }, { 0.00012570403, 0.00012150272, 0.00012149179, 0.00010579599 }, { -0.00062162762, -0.00058131015, -0.00060837583, -0.00060795256 }, { -0.00775735, -0.0077198081, -0.0078365948, -0.0077749317 }, { -0.0015325554, -0.0017125784, -0.001703195, -0.0015662859 }, { -0.0018130784, -0.00177106, -0.001858095, -0.0015845058 }, { -0.003668417, -0.0036659688, -0.0036693421, -0.0036680526 }, { -9.5804016e-06, -9.6276607e-06, -9.630607e-06, -1.2159056e-05 }, { 0, 0, 0, 0 }, { 0.00017930618, 0.00020084683, 0.00020150104, 0.00020810787 }, { 2.3869269e-05, 1.1024793e-05, 1.1041937e-05, 1.6467357e-05 }, { -0.004690782, -0.0044656761, -0.0046782065, -0.0046921455 } } }, { { { 0.23047932, 0.23043226, 0.23041471, 0.22922185 }, { 0.14990977, 0.15703656, 0.15110771, 0.15149153 }, { 0.30629171, 0.30426701, 0.30400037, 0.30403889 }, { 0.03476576, 0.036188528, 0.036216719, 0.037322097 }, { 0.31066251, 0.31090363, 0.31041565, 0.31057779 }, { 0.04875259, 0.046468595, 0.046486323, 0.046584523 }, { 0.31745458, 0.31874472, 0.32086369, 0.31880207 }, { 0.64054942, 0.64062862, 0.64051973, 0.64059059 }, { 0.27309038, 0.27480819, 0.27477284, 0.27486762 }, { 0.196647, 0.19687982, 0.19607604, 0.1957915 }, { 0.32867362, 0.32858008, 0.32856702, 0.328555 }, { -0.0026873031, -0.0042393446, -0.0057894907, -0.0041858859 }, { 0.40254624, 0.4024247, 0.4025598, 0.40243731 }, { 0.019362807, 0.018146218, 0.018146051, 0.019656613 }, { 0.29328089, 0.29403937, 0.29435036, 0.29403094 }, { 0.57111506, 0.57118505, 0.57099608, 0.57099266 }, { 0.16966612, 0.16993739, 0.17069399, 0.16991136 }, { 0.14989055, 0.1489484, 0.14995985, 0.15015916 }, { 0.33606014, 0.33606294, 0.33606393, 0.33605429 }, { 0.015421206, 0.015180692, 0.01518037, 0.015431139 }, { 0.33165237, 0.33185282, 0.33162592, 0.33166981 }, { 0.078137018, 0.078153855, 0.078165152, 0.078332343 }, { 0.002896946, 0.0026038621, 0.0026029604, 0.0022081151 }, { 0.41064398, 0.40987685, 0.41065341, 0.41059166 } }, { { -0.0024316111, -0.0024732789, -0.0024922144, -0.0035874346 }, { 0.0013306961, 0.004171802, 0.0027660627, 0.0023671465 }, { 0.0034411091, 0.0020878413, 0.0020874456, 0.0022028237 }, { -0.0032873976, -0.0021351911, -0.0021071363, -0.0028424534 }, { 0.0017995208, 0.0022319618, 0.0039270256, 0.0021249365 }, { -0.0019590835, -0.0012526895, -0.0012347747, -0.0021069943 }, { 0.0012319531, 0.002255621, 0.0030193583, 0.0020970822 }, { 0.0015144077, 0.0015110104, 0.0014803089, 0.0015340007 }, { -0.0036679996, -0.0028160114, -0.0028586497, -0.0027953731 }, { -0.005445786, -0.0052624873, -0.0054843188, -0.0053271749 }, { 0.00067154572, 0.0007530775, 0.00067974516, 0.00074462315 }, { -0.0035626119, -0.0034186877, -0.0038720517, -0.0040088745 }, { 0.003455851, 0.0035040061, 0.0034671486, 0.0035069881 }, { -0.0047789747, -0.0047994804, -0.0047996451, -0.0044008337 }, { 0.0032403482, 0.0033627856, 0.003429619, 0.0031153117 }, { -0.005027022, -0.0049812, -0.0049604573, -0.0050556194 }, { -0.0020728991, -0.0014784158, -0.001216894, -0.0019213729 }, { -0.00013808007, -0.00067270623, -0.00024001574, -0.00030691077 }, { 0.0004367104, 0.00043390709, 0.00043548166, 0.00043425516 }, { -0.00082746467, -0.00088151411, -0.00088152334, -0.0008043643 }, { 0.0030277712, 0.003133577, 0.0028529862, 0.0030362271 }, { -0.0058721937, -0.0059816331, -0.0059799345, -0.0058882832 }, { -0.0057032562, -0.0057401855, -0.0057416619, -0.0062417688 }, { -0.0014357888, -0.0020782049, -0.0014346823, -0.0014513767 } }, { { -0.0027051235, -0.0027087245, -0.0027052303, -0.0033594951 }, { 0.0028036195, 0.0030416572, 0.0014306948, 0.0017897371 }, { 0.0031113166, 0.0026432303, 0.0025937824, 0.0025394463 }, { -0.0036032904, -0.003447065, -0.0034344406, -0.0024163572 }, { 0.0023912799, 0.0025281229, 0.0038665087, 0.0024214034 }, { -0.0023543827, -0.0024294943, -0.0024539784, -0.0027742617 }, { 0.0020903896, 0.0026617586, 0.003395249, 0.0026261065 }, { 0.0019031008, 0.0019405475, 0.0019426085, 0.0019404325 }, { -0.0040413326, -0.0030964835, -0.0031020735, -0.0030826754 }, { -0.0064568993, -0.0062342438, -0.0064704698, -0.0065636744 }, { 0.0010788406, 0.0010092051, 0.0010264121, 0.00099891228 }, { -0.0040759201, -0.0059224283, -0.0066809927, -0.0049099348 }, { 0.0042962009, 0.0041909175, 0.0043195236, 0.0041900138 }, { -0.0062728983, -0.0070256154, -0.007025641, -0.0061758746 }, { 0.0036210401, 0.0039723998, 0.0042232048, 0.0042757707 }, { -0.0058693852, -0.0058583303, -0.0058544016, -0.005887725 }, { -0.0023099876, -0.0021136245, -0.0017298078, -0.0022483337 }, { -0.00017851962, -0.00014956209, 8.5676316e-05, -0.00024971669 }, { 0.0003734781, 0.00037078986, 0.00037364181, 0.00037070594 }, { -0.00030648905, -0.00038230535, -0.00038223043, -0.00028623253 }, { 0.0032871423, 0.0034163052, 0.0028276655, 0.0032991918 }, { -0.0061331695, -0.0063319797, -0.0063340119, -0.0064390374 }, { -0.0062172888, -0.0059787106, -0.0059793294, -0.0060406701 }, { -0.0018276142, -0.0022170788, -0.0018293949, -0.0018222824 } } } }, { { { { 0.13218089, -0.11654637, -0.11622196, -0.044208736 }, { 0.0074579257, 0.0038503609, 0.0013201096, 4.0415784e-05 }, { -0.025474487, -0.01209255, -0.016535858, 0.012704547 }, { -0.0016894103, -0.0081312144, -0.0033264609, 0.0011923269 }, { -0.068044876, 0.018276873, -0.074833897, 0.01308348 }, { 0.02665691, 0.013515118, 0.026440814, -0.0077037816 }, { 0.0023286096, -0.0025782652, 0.0021644694, -0.0042955294 }, { 0.051356261, -0.031058382, -0.085382962, -0.033103269 }, { -0.081609229, 0.0035270199, -0.015722417, 0.048773789 }, { 0.0023928418, -0.001243811, 0.011910492, -0.011621478 }, { -0.028953904, -0.029335777, -0.0057891432, 0.013874136 }, { -0.012473582, 0.001772629, -0.013983442, 0.014846792 }, { -0.016111661, 0.0018902323, 0.025910586, 0.042848276 }, { 0.026200626, 0.024007879, 0.0017667146, -0.016394032 }, { -0.0067006429, -0.0017968936, 0.009028659, 0.0044060413 }, { 0.019280611, 0.0449581, -0.042852227, -0.066012332 }, { -0.014451123, -0.047772741, -0.047475406, 0.098434178 }, { -0.0028954635, 0.010521833, -0.015741597, -0.00091666191 }, { 0.0020291956, -0.057966746, -0.04525094, 0.032711614 }, { 0.020563445, -0.0078684621, -0.015282237, -0.0019830466 }, { -0.019504171, 0.071338511, 0.0033729474, -0.0095772339 }, { 0.013056103, 0.018719519, 0.0096002937, -0.028774366 }, { -0.00038728577, -0.0010662982, -0.0014333502, 0.00059135695 }, { 0.073844752, -0.05666013, -0.1007151, -0.030440738 } }, { { 0.00017766639, -9.2398532e-05, -3.9442682e-05, -3.9559848e-05 }, { -0.0043956477, 0.00044042277, -0.00047491077, 9.4171117e-05 }, { -0.0042095545, -0.00910753, -0.0014295282, 0.0042595844 }, { 0.00070989004, -0.0009623012, 0.00084162653, -0.00015925965 }, { -0.0017587638, 0.0033199811, -0.00025544613, 0.00083644978 }, { 0.0051797987, 0.0015691893, -0.002324397, 0.0050776381 }, { 0.003911779, 0.00072639703, 2.102924e-05, -0.0029529332 }, { 0.0050240476, -0.00041452319, 3.1730448e-06, -0.0072697591 }, { -1.5023048e-05, 0.00032491246, -9.2151952e-05, 0.0035851726 }, { 0.0030984373, 0.0016428856, 0.0032974124, -0.0036034289 }, { -0.00044578206, -0.0035916409, 0.0028146658, 0.0068013321 }, { 0.00025716711, -0.0024772152, 0.0029660992, -0.0008783244 }, { -0.005543602, -0.00046453249, 0.006815884, 0.0069207512 }, { -0.0033541738, -0.0015140333, -0.004071746, -0.0020908789 }, { 0.0027932918, -0.0012517158, -0.0033509184, -0.001271572 }, { 0.0043481525, -0.00088858735, -0.0081538059, 0.00027985077 }, { 7.4017523e-05, -7.0080388e-05, -7.1766386e-05, 0.00020468758 }, { 0.00044507396, 0.010179106, -0.0048087449, 0.0013487105 }, { 0.00082148695, -0.00042640153, -0.0024255173, 0.0044486011 }, { -0.00026383509, -0.0031871528, -0.008203704, -0.00053957093 }, { -0.0002996462, 0.00070789605, 7.9300612e-05, -0.00024002209 }, { 0.0013722116, 0.0049176054, 0.0029283062, -0.000849108 }, { 0.00026545039, 0.0011783443, 0.00072103548, -0.0007355776 }, { 0.002192273, -0.00294318, 1.5452606e-05, -0.0020953993 } }, { { 2.4074136e-05, -2.4931598e-05, -1.0893587e-05, 1.080951e-05 }, { -0.0061635883, -0.0042963493, -0.00177783, -0.00080292808 }, { 0.0047868795, -0.0050472436, 0.0082439123, -0.0090979713 }, { 0.0017221077, 0.0067285193, 0.0031011872, -0.0019932567 }, { 0.0010926271, -0.0012170693, 0.00012875612, 0.00016441623 }, { -0.0048786273, -0.0041225634, -0.005591426, 0.0043469593 }, { -0.0070664098, -0.0012625813, -0.00022220241, -0.0026120468 }, { -0.0026689917, 0.00030860545, 1.9297947e-05, 0.001274799 }, { 0.0026769559, 0.00016106032, 0.00013829246, -0.0017239107 }, { -0.0042495789, 0.0010270326, -0.00078224804, -0.0019210019 }, { 0.0072385804, 0.0086418476, 0.0061428272, -0.0027142827 }, { 0.0019768127, -0.00057957046, 0.0047464783, -0.004599565 }, { 0.0093618867, -0.0010476542, -0.0038681572, -0.0065219521 }, { -0.0076406673, -0.0036729355, -0.0068804827, 0.0077571478 }, { 0.0012706397, -0.00042567505, -0.002521821, 6.0288127e-05 }, { -0.002041411, 0.000430125, 0.0073620925, 0.0021579456 }, { 0.00012145466, 4.1276616e-05, 4.2449608e-05, 9.8351262e-05 }, { 0.0014376278, -0.007439719, 0.0039006971, 0.00051135138 }, { -7.1665367e-05, 0.00023856335, 0.00015274881, -0.0096946274 }, { -0.00076804256, 0.0040182915, 0.012603411, -0.00059669891 }, { -0.00010641981, -0.00052355992, 0.00057481361, 0.00016456343 }, { -0.0027623375, -0.0036761364, -0.010480297, 0.0066006902 }, { 0.00049081404, 0.00077264749, 0.0021355718, -0.00029188425 }, { 0.00028566818, 0.00097678458, 0.00089022281, -0.00013760767 } } }, { { { -0.0098123577, 0.11017117, 0.11245143, -0.01173447 }, { 0.0036188505, -0.0025878518, -0.00043343726, -0.0038813197 }, { 0.013109746, -0.016775181, -0.0011093308, 0.00083465721 }, { -0.0042515898, -0.0028159364, 0.00027829209, -0.002907578 }, { -0.0081027554, -0.0019330574, 0.061872524, -0.037539524 }, { -0.012923735, 0.021011524, 0.002680406, 0.0034369108 }, { 0.0027819214, 0.0028657905, -0.0034177203, -0.0037322329 }, { -0.0036178174, 0.065792163, 0.13263475, 0.0055427994 }, { 0.027832309, -0.083372016, -0.058757582, 0.016164879 }, { -0.0082343898, 0.011782416, 0.011496052, -0.0027847616 }, { 0.0012516658, -0.014686832, -0.025073035, -0.020700577 }, { 0.0055718234, -0.011543219, -0.012867689, -0.0049474286 }, { 0.028869265, -0.035431559, 0.024976635, -0.01063055 }, { -0.0010657662, 0.014977146, 0.027109, 0.01612865 }, { -0.0021697493, 0.0044220507, 0.0055654161, -0.0032373397 }, { -0.018500666, -0.01979267, -0.0068480612, 0.03908391 }, { 0.063306878, 0.01934691, 0.019254616, -0.099824471 }, { 7.0580666e-05, -0.0015082457, -0.0056893693, 0.00022726294 }, { 0.0077067654, -0.014018834, -0.021406454, -0.0076589993 }, { -0.0013072394, 2.6765854e-05, 0.0028400803, 0.0037431063 }, { -0.025369581, -0.064039908, -0.020594137, -0.086807367 }, { -0.033639351, 0.010434758, 0.00082983507, 0.013145885 }, { 0.00029373395, 7.8193614e-05, 0.00048496415, 0.00062972215 }, { -0.0041597628, 0.024283117, -0.030148407, 0.011456515 } }, { { -1.3484857e-05, -3.7204145e-05, -1.5660577e-05, -2.4497955e-05 }, { -0.0068070249, 0.0041035892, 0.0034647689, 0.0035918321 }, { -0.0053613309, 0.0080593503, 0.0028507084, -0.0023104987 }, { 0.0048581064, 0.0039720065, -0.0019058129, 0.0047295789 }, { -0.00030675956, -0.0007787587, -0.00025201217, 0.00020777843 }, { -0.00026433336, -0.0093672701, -0.0053201627, -0.0059632173 }, { -0.0063062815, 0.0011995204, 0.0001870407, 0.0028197877 }, { -0.00053247524, -0.00066138217, -1.4959372e-05, -0.00036023628 }, { 0.00027591427, 0.00011309835, 2.2453632e-05, -0.00075736359 }, { 0.0015654886, 0.0018114616, -0.0004503446, -8.5866048e-05 }, { 0.003501393, 0.0037179893, 0.008328543, 0.013411108 }, { -0.0035136609, -0.0015054003, 0.0011903964, 0.0022551358 }, { -0.0083723767, 0.0061303554, -0.008056962, 0.0035035183 }, { -0.0023715655, -0.0070468331, -0.010219655, -0.0057856465 }, { -0.0011406634, -0.00021204595, -0.001693195, 0.0011051597 }, { 0.0011643412, 0.00037557194, 0.0048567739, -0.00063996433 }, { -3.1728174e-05, -2.9073903e-06, -3.0243209e-06, 2.579239e-05 }, { 0.00053152589, 0.0029635352, 0.0040743289, -0.00051381046 }, { -0.0017253584, 0.00012081524, 0.00012243664, -0.00063598215 }, { 0.0026711847, -0.0020733972, -0.0027860744, 0.0017065643 }, { 5.7762902e-05, 0.00092043577, -0.0035278882, 0.0007846087 }, { 0.0056127705, -0.0051893669, -0.0027072408, -0.0025630045 }, { -0.00059289151, -0.0004168408, -8.8118696e-05, -0.00073538101 }, { 0.0003388606, -0.00094234652, 3.013109e-05, -0.0010532484 } }, { { -2.9013996e-05, 6.1983083e-05, 2.8401438e-05, -3.4901557e-05 }, { 0.0045230474, -0.0021369843, -0.00422706, -0.0018918027 }, { 0.00017586142, 0.005389053, 0.0071352982, -0.0018278685 }, { -0.0012135723, -0.0035970727, 0.00078957165, -0.0017065397 }, { -0.00067051937, -1.9501585e-05, 4.1968766e-05, -0.0010958091 }, { -0.0015277626, -0.0039952533, -0.00049631478, 0.0018042745 }, { 0.0039376754, -0.00097834328, 6.5894634e-06, -0.0044189106 }, { -0.00067623039, 0.0004690807, 1.4532105e-07, 0.0032984829 }, { 0.0020787449, -0.0016586579, -0.00062367064, 0.0021545362 }, { 0.0016427801, 2.6710288e-05, 0.0016011535, -0.00077649869 }, { 0.0039999622, -0.0014968097, -0.0025647576, 0.0022783424 }, { 0.001558454, -0.00083803058, 0.0018955692, 0.0010432376 }, { 0.010555722, -0.010395022, 0.0050354965, -0.0016177699 }, { 0.00011370745, -0.009328355, -0.0063009522, 0.0024377458 }, { -0.00024433189, 0.00052920244, -0.0013213352, -0.0013503982 }, { -0.0057620093, 0.00095391746, -0.0034768563, 0.00093990705 }, { 0.00012108024, 4.1007202e-05, 4.2193381e-05, -0.00011043617 }, { 0.0038593696, -0.00074282979, -0.0093457897, 0.00027311164 }, { 0.0021514797, -7.8742315e-05, -0.0018813077, -0.0017625098 }, { 0.0038491118, 0.00022570776, -0.0061331041, 0.00014956617 }, { -0.00014676603, -0.00025053931, 0.003376287, -0.00014730695 }, { 0.0016439646, 0.0060569792, 0.00063058918, -0.0034810156 }, { 0.00011722835, 0.00032237223, -0.0012556553, -0.0006887808 }, { 0.00060814722, 0.0003708376, -0.00056515636, -0.00016801817 } } }, { { { 0.99117704, 0.98705585, 0.98683693, 0.9989534 }, { 0.99996564, 0.99998924, 0.99999903, 0.99999247 }, { 0.99958951, 0.99978616, 0.99986266, 0.99991895 }, { 0.99998953, 0.99996298, 0.99999443, 0.99999506 }, { 0.99764936, 0.9998311, 0.99527468, 0.99920949 }, { 0.9995611, 0.99968788, 0.99964679, 0.99996442 }, { 0.99999342, 0.99999257, 0.99999182, 0.99998381 }, { 0.99867384, 0.99734987, 0.98748052, 0.99943657 }, { 0.99627571, 0.99651225, 0.99814846, 0.99867903 }, { 0.99996323, 0.99992981, 0.99986298, 0.99992859 }, { 0.99957996, 0.99946171, 0.99966886, 0.99968945 }, { 0.99990668, 0.9999318, 0.99981943, 0.99987754 }, { 0.99945334, 0.99937032, 0.99935219, 0.99902503 }, { 0.99965614, 0.99959957, 0.99963092, 0.99973552 }, { 0.9999752, 0.99998861, 0.99994375, 0.99998505 }, { 0.99964293, 0.99879278, 0.99905795, 0.99705307 }, { 0.99788947, 0.99867085, 0.99868681, 0.99012413 }, { 0.99999581, 0.99994351, 0.99985991, 0.99999955 }, { 0.99996824, 0.99822008, 0.99874627, 0.99943549 }, { 0.9997877, 0.99996904, 0.99987919, 0.99999103 }, { 0.99948785, 0.99539425, 0.99978223, 0.99617908 }, { 0.99934875, 0.99977032, 0.99995357, 0.99949949 }, { 0.99999988, 0.99999943, 0.99999886, 0.99999963 }, { 0.99726107, 0.99809817, 0.99445842, 0.99947091 } }, { { -2.3481737e-05, -6.7307406e-06, -2.8605869e-06, -2.0372001e-06 }, { 6.6885689e-05, 4.5630281e-06, 3.5788218e-05, 1.0842484e-05 }, { -4.9278613e-05, -2.4660601e-05, 3.1625301e-06, 0.00019708279 }, { 1.2439158e-05, 3.0347865e-05, 8.6153947e-06, 1.0887256e-05 }, { -0.00012454598, -6.513709e-05, -3.5853483e-06, -3.4708286e-06 }, { -0.00013746339, 0.00013516333, 8.4535039e-05, 5.693766e-05 }, { -2.3674091e-05, -3.4690053e-06, 5.3812265e-07, -1.7613197e-05 }, { -0.00025790043, 3.0475251e-05, 2.1174795e-06, -0.00023630753 }, { -8.8624748e-06, 7.9175589e-06, -2.4258477e-07, -0.00017288313 }, { 4.0061469e-05, 0.00069846663, -0.00060299476, -0.00015396968 }, { 5.0667108e-06, 2.306363e-05, 0.00028636884, 3.6246633e-05 }, { 0.00032740524, -0.00037985037, -0.00014841039, -0.00012676016 }, { 8.7000758e-05, 0.00018530207, 1.7669124e-05, -0.00023199594 }, { 9.2332094e-05, 0.00013487652, 0.00034587506, -3.8853378e-05 }, { 6.9809868e-05, -0.00015411544, 0.0013505166, 1.4531796e-06 }, { -6.3782301e-05, 4.8545135e-05, -0.00027083794, 4.5129465e-05 }, { 3.0912438e-06, -3.2982361e-06, -3.3551612e-06, -1.7781589e-05 }, { 9.872609e-06, -2.9944213e-05, -4.5592652e-05, 1.5950681e-05 }, { 1.4767773e-05, -2.2486726e-05, -0.00010613341, -0.00015794394 }, { 2.4386215e-05, -1.1610334e-05, -4.4456294e-05, -5.0215596e-06 }, { -4.2741558e-06, 8.7714242e-06, -6.6343322e-05, 6.7010735e-05 }, { 0.00016489767, -3.3636771e-05, 5.1610504e-05, 5.2803593e-06 }, { 1.1649256e-05, 2.1169993e-05, 1.9755999e-05, 1.3389438e-05 }, { -0.00015815197, -0.00014316145, 2.6536218e-06, -4.6846396e-05 } }, { { -3.5109783e-06, -9.8530632e-06, -4.5020804e-06, 6.9233235e-08 }, { 9.9938991e-06, -2.0914089e-06, 3.5717699e-05, 3.2813664e-06 }, { 0.00012938219, 1.111062e-05, 8.0858608e-05, 0.00018147439 }, { 4.8657525e-06, 8.6580257e-06, 3.6742927e-06, 3.5828406e-06 }, { 6.9905696e-05, 2.0985073e-05, 6.8866215e-06, -4.2552499e-05 }, { 0.00012100208, 9.7821801e-05, 0.00013576456, 6.3686234e-05 }, { 1.954525e-06, -1.0727343e-06, 5.2332444e-07, -5.4034988e-06 }, { 0.00013699813, -2.226833e-05, 1.4994043e-06, 1.7110377e-05 }, { 0.0001678261, -0.00013844113, -3.4281745e-05, 5.3854072e-05 }, { -1.3018868e-05, 0.00022176303, 0.00016983401, 0.00038109805 }, { 0.00019016068, 0.00023448876, 2.643329e-05, 4.6842203e-05 }, { -1.2492528e-05, -0.00059486605, 0.00012427061, 8.1876965e-05 }, { 8.400564e-05, -0.00029859163, -4.884214e-05, 0.0002631806 }, { 0.00019907281, 0.00014046808, 0.00015482448, 4.0461099e-05 }, { -0.00024349239, 0.00081298441, 0.00084294728, 7.9617963e-05 }, { -6.0040835e-05, 3.2352918e-07, 0.00024295599, 0.00011067283 }, { -6.0027092e-06, 1.1975092e-06, 1.2248893e-06, -2.1293392e-05 }, { 1.4478736e-05, 6.8326918e-05, -7.8693614e-06, 9.2888155e-06 }, { -1.6982828e-05, 1.2094341e-05, -3.1693808e-05, 0.00028574477 }, { 3.4480942e-05, 2.6556008e-05, 0.00016193956, -1.8966503e-06 }, { -5.7726961e-06, 2.1091148e-05, 5.8963955e-05, -1.0834372e-05 }, { 0.0001214393, 1.4174882e-05, 0.0001371836, 0.00021757165 }, { 1.0140226e-05, 6.1641031e-06, 1.0590727e-05, 1.0893212e-05 }, { -1.7442656e-05, 4.2353331e-05, 7.4324714e-05, -1.9484775e-06 } } }, { { { 3.7217719, 3.6900797, 3.6899881, 3.6670816 }, { 0.067826319, 0.16468028, 0.083129199, 0.1336756 }, { 0.66338737, 0.23883566, 0.093361469, 0.10095622 }, { 0.27185537, 0.20781392, 0.32216624, 0.29876595 }, { 2.0776462, 2.0006156, 2.0243138, 2.080345 }, { 0.57695783, 0.18015147, -0.11440889, 0.14229144 }, { 0.63833683, 0.41431062, 0.44752994, 0.47594414 }, { 1.7890608, 1.962584, 1.9322155, 1.6588331 }, { 3.0538128, 3.108267, 3.1001573, 2.9593433 }, { -0.28383051, -0.27708376, -0.042513902, -0.085181891 }, { 0.3873435, 0.41697884, 0.39625427, 0.33250735 }, { -0.33498881, -0.40206929, -0.028905862, -0.48179632 }, { 1.1875033, 1.3535177, 1.2526197, 1.3337495 }, { 0.42579488, 0.24951727, 0.18976118, 0.20605317 }, { -0.53212666, -0.3861028, -0.75685995, -0.23411882 }, { 1.6910165, 1.686815, 1.5906473, 1.6528217 }, { 4.0570657, 4.0349492, 4.0350332, 4.0498099 }, { -0.017225465, -0.032503897, 0.46003211, 0.21602109 }, { 1.1196901, 1.00885, 0.91675568, 0.99635794 }, { -0.093891275, 0.0809352, -0.13783332, 0.27130678 }, { 1.9925136, 1.9829394, 1.8820721, 1.9542026 }, { 0.84563763, 0.48476746, 0.37907152, 0.70267878 }, { 0.37054708, 0.4228574, 0.6329822, 0.26197064 }, { 1.9618393, 1.8405969, 1.9440918, 1.901629 } }, { { -5.6047186e-06, 6.0454847e-06, 2.8365975e-06, 6.0894367e-06 }, { -0.00069876506, -0.00029642785, -0.00059516082, -0.00025400441 }, { -0.00020850504, -0.00012959593, -0.00032902532, -0.00058117893 }, { -0.00037901964, -0.00038062016, -0.00023777964, -0.00033714679 }, { -5.9894351e-05, -9.820791e-05, -5.9867157e-06, -6.258549e-06 }, { -0.00035424038, -8.7146215e-05, 3.0398362e-05, -0.00061406521 }, { 0.00014971442, 4.5936211e-05, -5.6259869e-06, 0.00013567035 }, { -0.00016180211, 3.1840487e-06, 3.8979157e-07, -0.00017131994 }, { -1.9877193e-05, 2.5768261e-05, 9.0577543e-06, -0.00013927462 }, { -0.0012323564, -0.00042892846, 7.2082106e-05, 0.00010999853 }, { -0.00034618449, -0.00017058897, -0.00016535057, -0.00096982024 }, { -0.00028039653, -7.155747e-05, -0.00075796707, 0.00062756458 }, { 6.6596276e-05, -7.9730809e-05, -8.0686754e-05, -2.9532397e-05 }, { -0.00084106867, -0.00036762453, 0.00012523548, -0.00052789663 }, { 7.6718268e-05, -0.0010042005, -0.00042802983, -0.0011951304 }, { -3.6972258e-05, 2.1447505e-06, -0.00035448623, -1.0620008e-05 }, { 2.8326169e-05, 2.2049468e-05, 2.2640575e-05, 1.7574827e-05 }, { -0.00014318496, -0.0004811524, -0.00049293303, -0.00067646484 }, { -2.7469144e-05, -5.9653763e-06, -1.3998899e-05, -0.00018475323 }, { -0.00017314302, -0.00010954727, -0.00040004932, 3.31106e-05 }, { -3.6093435e-06, -1.6125243e-05, -4.9195648e-05, 1.5586886e-05 }, { 0.0002059631, -0.0004024722, -0.00047984678, -9.8485329e-05 }, { -0.00094100913, -0.00073046048, -0.00052500163, -0.00068196784 }, { -2.2820197e-05, -5.9454557e-05, -6.2505468e-06, -2.6569804e-05 } }, { { 2.6015883e-05, 8.5398335e-06, 3.8473185e-06, 9.1409625e-06 }, { -0.00041459247, -0.0001855224, -0.00030529542, -0.00016322166 }, { -8.8427847e-05, -0.0002302048, -0.00038072959, -0.00076801295 }, { -0.00027717792, -0.00028594346, -0.00017910208, -0.00027291164 }, { 2.8409311e-05, -3.8005817e-05, -4.2266878e-06, -1.4520383e-05 }, { -0.0001088827, -0.00021924377, 3.9307406e-05, -0.00032488556 }, { 0.00027997916, 3.5103699e-05, -5.7448764e-06, 0.00010259251 }, { -4.7807894e-06, -2.9470863e-05, 2.6656233e-07, -0.00014346393 }, { 0.00015527098, -6.8528726e-05, -1.1206714e-05, 2.3422595e-05 }, { -0.0012763247, -0.00051503472, 0.00058055106, -0.00068688488 }, { -6.1232076e-06, -1.7073841e-05, -0.00033533389, -0.00078769935 }, { -0.00044113485, -0.00027577451, -0.0012008622, 0.00013071136 }, { 1.834948e-05, -0.00015615102, -0.00016449385, 3.6685217e-05 }, { -0.00063618257, -0.00032641968, -5.0281118e-05, -0.00041378992 }, { -0.0010181884, -0.0003871932, -0.00050061147, -0.0018967455 }, { -5.7650067e-05, -5.1145774e-06, -0.00017409773, 1.9512036e-05 }, { 1.5838743e-05, 2.503655e-05, 2.5679098e-05, 2.0053218e-05 }, { -0.00018055811, -0.00044345237, -7.9049557e-05, -0.00095669161 }, { -4.98611e-05, -1.1320605e-06, 3.7756645e-06, -8.7299215e-05 }, { -0.00011794063, -0.00015778552, -0.00036514881, 4.7288704e-05 }, { -5.1753817e-06, -1.5040527e-06, -2.836739e-05, -9.4945229e-06 }, { 0.00016873335, -0.00031983601, -0.00052281245, 0.00019034815 }, { -0.0011988594, -0.0010684975, -0.00057577023, -0.0009143845 }, { 5.0336006e-05, -1.356148e-05, 1.5582694e-05, -2.0666272e-05 } } }, { { { 0.012207721, 0.0044164612, 0.0022704542, 0.0042008503 }, { 0.29516302, 0.139976, 0.35038027, 0.13748343 }, { 0.1462123, 0.12114907, 0.28473665, 0.45762717 }, { 0.17976664, 0.19141553, 0.1209483, 0.16393769 }, { 0.044254492, 0.11383095, 0.0062726904, 0.023550537 }, { 0.14785458, 0.10151341, 0.045717467, 0.42243971 }, { -0.24205201, -0.033590842, 0.0032064617, -0.093924041 }, { 0.10866955, 0.016299431, 0.00081631108, 0.15856447 }, { 0.10108337, 0.057931152, 0.024463589, 0.21514346 }, { 0.47967783, 0.75472932, 0.5653649, 0.64752457 }, { 0.30082544, 0.15124922, 0.23567284, 0.47161499 }, { 0.54286166, 0.61049777, 0.61641378, 0.51181399 }, { 0.39328762, 0.25557559, 0.25875912, 0.22436901 }, { 0.45699569, 0.16989563, 0.2429263, 0.3924359 }, { 0.92996797, 1.1024806, 0.78045387, 1.2298879 }, { 0.19029829, -0.022675055, 0.28113642, 0.034941166 }, { 0.013203939, 0.013034069, 0.013414649, 0.011688038 }, { 0.076026927, 0.13838472, 0.29961655, 0.31531564 }, { 0.089182386, 0.010401684, 0.029374547, 0.22995838 }, { 0.052198894, 0.039866726, 0.11570972, -0.013818992 }, { 0.0062380932, 0.01788119, -0.20765047, 0.013339281 }, { 0.12436441, 0.17318651, 0.21554136, 0.18600144 }, { 0.38005287, 0.32135548, 0.28632777, 0.29211902 }, { 0.03798742, 0.0450845, 0.010912505, 0.039060104 } }, { { 0.00077914246, 0.00011130803, 8.1110229e-05, -0.00035312557 }, { 0.00051711901, 0.00029701387, 0.00040733345, 0.00034149723 }, { 0.00063893978, -0.00013702086, 0.00030866699, -0.00020070677 }, { 7.5899443e-05, 9.7456273e-05, -4.5352178e-05, 7.6172703e-06 }, { 0.00066250814, -0.00073033349, 0.00015225542, -0.0010197351 }, { 0.00040931533, -0.00043022747, 0.00093333285, 0.0002579685 }, { -0.00067488578, -0.0003706974, -0.00044487256, -0.00056555959 }, { 0.00075838366, -0.0021903789, -0.0026744174, -0.00047135202 }, { -0.00081050821, -0.0010297809, -0.00099480849, -0.00074914246 }, { 0.00063637392, 5.248783e-05, 0.00044645091, 0.00018028446 }, { 0.00067430392, 0.0004762628, -0.00032736685, 0.00041933609 }, { 6.2324555e-05, -1.6709531e-06, 0.00057418116, -0.0010360999 }, { -0.00038256183, -0.0010104012, -0.00045533693, -1.3888404e-05 }, { 0.00068274628, 0.00068411875, -0.00091273333, 0.00016211145 }, { -0.00039440715, 0.00027665323, -0.00035895503, 0.00013423207 }, { -0.00061939017, 0.00012140102, 0.00024178233, 0.00064755788 }, { -0.00052441128, -0.00050994483, -0.00051126044, 0.00066320373 }, { 0.00085915332, 0.0013567332, -0.00014328466, 0.00056098523 }, { -0.0012682676, 0.0029139719, 0.0019812291, -0.00053863027 }, { 0.0021895869, 0.00062956835, 0.0018161156, 0.00011699452 }, { -0.0010337306, 0.00016880497, -0.0014942346, -0.0034402453 }, { -0.0025336946, -0.00019468865, -0.00018045349, -5.4312149e-05 }, { 0.00021491979, 4.7651714e-05, -0.00044921151, 0.00046742044 }, { 0.0019408125, 0.00044842687, 0.0026003265, -0.00090116109 } }, { { -0.0006591255, 0.00022873584, 0.00026313866, -0.00060151354 }, { 0.00027198127, 0.00034252944, 0.00033246896, 0.00035232159 }, { -0.00034460639, -5.9085725e-05, 7.836454e-05, -0.00018946388 }, { 0.00018790551, 0.0001918358, 9.7031467e-05, 0.00015259869 }, { -0.0023033429, -0.0012945186, -0.00080964072, -0.00030432514 }, { -0.001359781, 0.00055828912, -0.00041912301, 0.00019263336 }, { -0.00042789448, -0.00018313775, -0.00030217124, -0.00028437496 }, { -0.0018340159, 0.00030654336, -0.00010781402, -0.0011985455 }, { -0.002103478, 0.00029492518, -0.00042283946, -0.001472689 }, { 0.00064558079, 0.00049703204, -0.00018932594, -0.00038268301 }, { -0.00097813334, -0.00057838807, 0.00079268109, 0.00039650774 }, { -0.00017335252, 0.00074363734, 0.0008194423, -0.00065923207 }, { -0.00075344545, -0.00026114262, -0.00054658657, -0.0013814943 }, { -0.00028279346, 0.00055730283, 0.00048990213, -0.00022186466 }, { 0.00013438509, -0.0001962818, -0.00036195953, 0.00042669461 }, { -0.00089003585, -0.0011600794, -0.0012554286, -0.0012892408 }, { -0.00067007058, -0.0010597247, -0.0010590421, 0.00044132516 }, { 0.0011626727, 0.001261033, -0.00072912018, 0.00076332442 }, { -0.001204702, -0.00011230019, 0.00036178615, -0.0017559004 }, { 0.00096282849, 0.001025959, 0.0011696947, 0.00046633555 }, { -0.00082328571, -0.00075771669, -0.0011629302, 0.00073458863 }, { -0.0016869269, -0.00035239862, -0.0004024204, -0.0016276971 }, { 0.00029053123, 0.00013409355, -0.00049087974, 0.00061969429 }, { -0.0013198997, -0.0018615784, -0.0025724061, -0.0015563017 } } } }, { { { { -0.072246889, -0.043157285, 0.043289306, 0.095998047 }, { 0.12597079, 0.24289541, -0.10930005, -0.24150539 }, { 0.031889347, -0.036238337, -0.014521983, -0.018963885 }, { -0.044155351, -0.0077170425, -0.043781059, 0.047982339 }, { 0.093995001, -0.0079510758, -0.04688882, -0.11125523 }, { 0.01700754, -0.0034361033, 0.055252382, -0.053119426 }, { -0.0014957087, -0.00063057103, 0.037930463, 0.017656646 }, { -0.017388477, -0.084085888, -0.067726647, 0.061397079 }, { -0.070625168, -0.061293011, -0.077366932, 0.11518646 }, { -0.14771316, -0.12543895, 0.052150789, 0.10530462 }, { -0.03609139, 0.001131616, -0.039549928, 0.03805765 }, { 0.064364205, 0.066758929, 0.045537002, -0.05510954 }, { 0.049051369, 0.098312455, -0.01079726, -0.11202623 }, { 0.033012208, -0.0013996988, -0.0049458824, -0.028981527 }, { 0.008617177, -0.00017670863, -0.0052380282, -0.0023438457 }, { -0.05901498, -0.050754807, -0.00011829844, 0.037297411 }, { -0.056264446, -0.03645315, -0.066412698, 0.019549244 }, { -0.11401603, -0.11856524, 0.12275022, 0.11635143 }, { -0.0011999881, -0.0016334327, -0.0056868938, 0.013393766 }, { 0.054526972, 0.033632235, 0.062591094, -0.0025531074 }, { 0.073041316, 0.073735243, -0.06935254, -0.11214186 }, { 0.034872822, -0.015473423, 0.037359975, -0.026829465 }, { -0.015137592, -0.0064462553, 0.011771178, 0.0025042048 }, { -0.038708904, -0.033968131, -0.044070885, 0.024422773 } }, { { -0.047895007, -0.016535938, 0.04855533, 0.018341613 }, { 0.004310087, 0.01519838, -0.0033290683, -0.013597406 }, { 0.0015859181, 0.016869623, -0.019279963, -0.01426933 }, { -0.0061048976, 0.031131561, 0.018085381, -0.017927117 }, { 0.052590378, 0.0066156852, -0.0025756141, -0.037241705 }, { 0.0083512619, 0.0046235666, 0.024122126, -0.013443654 }, { 0.0010672274, 0.00053123301, -0.0016276029, -0.04221993 }, { -0.0048754166, -0.021474788, -0.0039993317, 0.011831691 }, { -0.054685347, -0.050242732, -0.007606251, 0.043061893 }, { -7.5644942e-05, 0.00086632318, 0.0001960729, 0.0013264286 }, { 0.0042413724, -0.0057181522, 0.0065940983, -0.0078263328 }, { 0.0031260881, -0.0013520907, 0.025073658, -0.010841673 }, { 0.038353769, 0.06620308, -0.0072105562, -0.079188681 }, { 0.003099559, -0.0022927921, 0.021982683, -0.018991144 }, { 0.012285675, 0.0091834074, -0.0041874571, -0.032253924 }, { -0.014563556, 0.009843969, -0.010490279, 0.012979866 }, { -0.005492286, 0.064109426, -0.034795617, -0.020395732 }, { -0.023364141, -0.059336321, 0.080710391, 0.038948527 }, { 0.0028384819, 0.001822471, 0.0012903958, 0.012781079 }, { -0.004510518, -0.0020008272, 0.0017752876, 0.0077607089 }, { 0.032279653, 0.0041906079, -0.034682371, 0.0061335907 }, { -0.0082992317, -0.025250117, -0.017026845, -0.028345042 }, { -0.013132125, -0.026688493, -0.0014827793, -0.003236826 }, { 0.01650781, 0.002313574, -0.012897922, 0.026077933 } }, { { 0.062668058, 0.0081578851, 0.018952049, -0.012267283 }, { 0.0008567722, 0.0033246009, -0.0037620102, -0.0096317368 }, { -0.0083012273, 0.01184624, -0.01209373, 0.020208536 }, { 0.013862003, 0.019166381, 0.013235471, -0.026788736 }, { -0.021904217, -0.051018749, 0.0020330268, 0.006626371 }, { -0.015856131, 0.0028024655, -0.032825412, -0.018920906 }, { 0.0020870233, 0.0011616727, -0.0032704368, -0.027327141 }, { 0.01934969, 0.002427195, 0.049925128, -0.0061414889 }, { 0.013158375, 0.022248445, 0.040266734, -0.017583455 }, { 1.9024812e-05, 0.00071602053, 0.0012622199, 0.0018791611 }, { -0.0011857767, 0.0023417924, 0.026237548, -0.014687892 }, { -0.041419782, 0.024942194, -0.029143101, 0.036590943 }, { -0.015470651, -0.035208671, -0.038530514, 0.037434376 }, { -0.0029356279, 0.0023358079, 0.017641055, 0.0038203652 }, { -0.0030449623, -0.010187444, 0.0066142145, 0.0037433206 }, { 0.0080034603, 0.011463159, -0.0058129532, 0.011831147 }, { -0.0091743137, 0.045949289, 0.022412137, -0.0067531419 }, { 0.00069946656, -0.0068974782, 0.0091806954, 0.0022160793 }, { -0.0027530077, 0.00089797627, 0.0066153093, -0.010355635 }, { -0.019399018, -0.0085762573, 0.0208003, -0.027739023 }, { -0.014354809, -0.011971089, -0.0031124986, 0.044710091 }, { -0.011411144, 0.0073253411, -0.0087561348, -0.014838738 }, { 0.018837992, 0.00231775, -0.013982978, -0.0020044658 }, { 0.0012069362, 0.0012202952, 0.029106153, 0.00062793994 } } }, { { { 0.054154158, -0.11603661, -0.025631275, 0.054671866 }, { -0.2359715, 0.093194255, 0.21874866, -0.08378526 }, { 0.0089903397, 0.0087113885, -0.015445726, 0.011142042 }, { -0.0055372249, -0.0041494086, -0.033355186, -0.010136823 }, { -0.015010227, -0.0077144008, 0.13058394, -0.016779666 }, { -0.015855009, 0.014090685, 0.026549575, 0.025677527 }, { -0.00065423811, -0.0011506403, 0.028628751, 0.0086359197 }, { -0.010571292, 0.035861454, -0.025871285, -0.024827688 }, { 0.00010603924, 0.011433504, -0.052819957, -0.020208661 }, { 0.12243361, -0.14574398, -0.10091072, 0.054524772 }, { -0.014659734, -0.02291001, 0.010102434, -0.0099333349 }, { -0.0079939087, 0.023468399, 0.044548395, 0.04568814 }, { -0.048188816, 0.016469102, 0.084818672, -0.040634065 }, { 0.015089138, 0.025396216, 0.017000121, 0.010820807 }, { -0.0098155552, -0.00080001495, 0.0020122754, -0.00046896909 }, { -0.0018906417, -0.03909342, -0.020339049, -0.024007559 }, { -0.0012744487, -0.027829333, -0.05202457, -0.024366779 }, { 0.10406956, -0.092281421, -0.050420166, 0.10716663 }, { -0.0049603976, -0.0055370076, -0.0016910106, 0.012172389 }, { -0.0026486448, 0.038673757, -0.0016176887, 0.052692494 }, { -0.03722357, 0.055455783, 0.067738953, -0.0087990582 }, { -0.0026491637, 0.017275247, 0.010687117, 0.020312052 }, { -0.0016032469, 0.0090272843, -0.0079027514, -0.0050039898 }, { -0.0073653412, -0.033150577, 0.0082912493, -0.021457881 } }, { { -0.0059001999, 0.033600833, 0.066374213, -0.018058548 }, { -0.0037864945, -0.0064946131, 0.0018627774, 0.0044899139 }, { 0.0048961861, -0.0034770968, -0.0002311598, -0.0053935761 }, { 0.0090090757, 0.012149811, 0.0029969663, 0.0049403543 }, { -0.042874682, -0.0083455851, -0.0064437344, 0.0010579362 }, { 0.011866873, -0.017157526, -0.014724976, 0.0054373752 }, { -0.0006329516, -0.00024834697, 0.0015416168, -0.014246989 }, { 0.031530357, -0.052715858, -0.0063186617, -0.0070200141 }, { -0.0082273844, 0.053856605, 0.0096812384, 0.01684635 }, { -0.00017150577, 0.00097354737, 0.0013944706, 0.00085166684 }, { -0.013604545, 0.0089329355, -0.013809086, 0.0025044469 }, { -0.020284731, 0.0004724419, -0.045697697, -0.01844702 }, { 0.017874081, -0.0040537465, -0.023316716, -0.026344708 }, { 0.0092557469, -0.014456327, -0.0092919835, 0.0091758924 }, { 0.016058873, 0.0019220807, 0.0031692823, 0.0024577167 }, { -0.021184352, 0.021287579, -0.0048442696, 0.0095799112 }, { 0.035229915, -0.054291919, -0.013871324, 0.035585241 }, { 0.001275203, 0.011513119, 0.020184769, -0.0061701639 }, { 0.011353237, 0.0052697685, 0.0047637419, -0.020278005 }, { 0.0068266296, -0.01173749, 0.037482577, -0.0083236299 }, { 0.025699221, -0.03651135, -0.032342446, -0.0059784486 }, { 0.0029540635, -0.0021598269, 0.0028168477, 0.0044577193 }, { 0.0038274002, -0.0050806333, 0.007628551, 0.0027461742 }, { 0.0056567464, 0.006846664, -0.031161558, -0.0040832656 } }, { { 0.025668431, 0.0093723617, 7.4324163e-05, -0.023051436 }, { -0.010148124, 0.0018159908, 0.0072269566, 0.00082671261 }, { 0.0069741056, 0.023493533, 0.028507618, -0.026874125 }, { 0.0083316277, -0.024891629, 0.013623217, 0.0038373532 }, { -0.020992516, 0.070912136, -0.0014634877, -0.015680371 }, { 0.02178962, -0.003772636, -0.024578501, -0.047467019 }, { 0.0028586275, 0.0033445767, 0.0049576063, -0.017365739 }, { 0.0075721122, 0.010652219, -0.024031886, -0.0001146548 }, { 0.016381176, -0.044765924, -0.038036229, -0.014041395 }, { -0.00082564842, 0.00033107944, 0.00073792054, 0.0005712734 }, { 0.0080934887, 0.014534447, -0.0071347609, 0.0085413493 }, { -0.018211778, 0.0064443848, 0.017393403, 0.011490985 }, { -0.071531366, 0.030059694, 0.049103287, 0.0074609412 }, { 0.00770209, -0.017999995, -0.040048679, -0.0029073853 }, { 0.020442166, 0.0019454488, -0.019644905, 0.021793285 }, { 0.035171271, 0.0080192155, -0.023151504, 0.014168348 }, { -0.048901887, -0.0039613606, 0.0021703807, 0.030275152 }, { 0.044666116, -0.029756153, -0.015570779, 0.034470632 }, { -0.0078700362, 0.0037551741, 0.0003070052, -0.0031237403 }, { 0.015288427, -0.01284757, -0.0075319169, 0.026981487 }, { -0.0093872483, 0.013517073, -0.030221944, 0.058356065 }, { 0.0042326205, -0.016381154, 0.021475001, 0.01008732 }, { 0.0034929117, 0.020531314, -0.0085114063, 0.004821913 }, { 0.014314413, 0.01127037, -0.017197896, 0.0046932185 } } }, { { { 0.99591552, 0.99230689, 0.99873374, 0.99387895 }, { 0.96356049, 0.96556546, 0.96964041, 0.96677566 }, { 0.99945097, 0.99930521, 0.99977525, 0.99975808 }, { 0.99900933, 0.99996161, 0.99848418, 0.99879675 }, { 0.99545951, 0.99993863, 0.99032786, 0.9936502 }, { 0.99972964, 0.99989482, 0.99811938, 0.99825798 }, { 0.99999867, 0.99999914, 0.9988702, 0.99980681 }, { 0.99979292, 0.99581299, 0.99736843, 0.99780458 }, { 0.99750292, 0.99805433, 0.99560254, 0.9931383 }, { 0.98142286, 0.98133774, 0.99352772, 0.9929441 }, { 0.99924096, 0.99973689, 0.99916652, 0.99922617 }, { 0.99789446, 0.9974931, 0.99796885, 0.99743448 }, { 0.9976331, 0.99501931, 0.9963379, 0.99287411 }, { 0.99934104, 0.99967648, 0.99984325, 0.99952138 }, { 0.9999147, 0.99999966, 0.99998426, 0.99999714 }, { 0.99825531, 0.99794572, 0.99979313, 0.99901579 }, { 0.99841509, 0.99894779, 0.99643504, 0.99951192 }, { 0.98801309, 0.98864879, 0.99115599, 0.98740957 }, { 0.99998698, 0.99998334, 0.9999824, 0.99983621 }, { 0.99850879, 0.99868574, 0.99803794, 0.99860752 }, { 0.99663402, 0.99573479, 0.99528974, 0.99365325 }, { 0.99938825, 0.99973103, 0.99924472, 0.99943364 }, { 0.99988413, 0.99993848, 0.99989949, 0.99998434 }, { 0.99922338, 0.99887297, 0.998994, 0.9994714 } }, { { -0.0050599833, 0.003362263, 0.0035202243, -0.00056864904 }, { -0.0014675187, -0.0029154981, -0.00077796172, -0.0027392627 }, { -0.0010916411, 0.00078232803, 0.0014339533, -0.0020166729 }, { 0.011183745, 0.008298699, 0.011631254, 0.00030693508 }, { -0.0012964861, -0.00028098882, 0.00098513135, -0.0052243577 }, { 0.0091119501, 0.002780703, 0.011045274, 0.00334383 }, { 4.1103001e-05, 5.5767744e-05, 0.0030605577, 0.0022152241 }, { 0.00085375099, 0.0026952672, 0.0071937971, 0.0056504112 }, { -0.003773118, 0.0047936307, -4.5743022e-05, -0.0038357994 }, { 2.3815581e-05, 0.0002468657, 0.00013492048, -0.00018410816 }, { 0.0070959632, -0.00205589, 0.0056417297, 0.0030702073 }, { 0.010671769, 0.0074346008, 0.0012867659, 0.0075437523 }, { -0.0013037272, -0.0058374269, 0.0025899757, -0.0071565118 }, { 0.0030041304, 0.0018011397, 0.0093160386, 0.0082062863 }, { 0.0053156934, 0.0036543193, 0.0048724246, 0.0035118324 }, { -0.0053866158, 0.0024053442, 0.00052459148, 0.0090970513 }, { 0.011239324, -0.0010327051, -0.00097551594, 0.0044180668 }, { -0.0024379533, -0.0088232426, -0.012355568, -0.0031875953 }, { 0.0026244123, 0.0011858999, 0.0028110843, -0.001005442 }, { 0.0059514328, 0.0018892606, 0.0050231625, 0.0046700575 }, { 0.00050741664, 0.0096547476, -0.00079618251, 0.0024532112 }, { 0.0058717468, -0.0017457656, 0.0080261577, -0.00048009588 }, { 0.0025457914, 0.0016788968, 0.0013982313, 0.00073909928 }, { 0.0075035778, 0.011234409, 0.0079271096, 0.006672353 } }, { { 0.0095152396, 0.0011785006, -0.00081996856, 0.0018904938 }, { -0.0025430397, -0.0010236291, -0.0020168276, -0.0021827861 }, { 0.0036295778, 0.005406882, 0.0040788276, -0.0057729163 }, { -0.00029952998, 0.0024548208, 0.0088548836, 0.0019084209 }, { 0.0034184324, -0.0088925589, 0.00023040452, 0.00017437939 }, { 0.0037804595, 0.012156355, 0.0041276361, 0.012721488 }, { 7.4846461e-05, 0.00010580108, 0.013483417, 0.0024239851 }, { 0.00026411032, -0.00059353627, 0.0093564271, 0.0061507538 }, { 0.0016065383, -0.0027764641, 0.0013620195, 0.0010062065 }, { 9.7127925e-05, 0.00017275393, 1.0814607e-05, -0.00022627793 }, { 0.0048710612, -0.00014794569, 0.0082832436, -0.00072595412 }, { -0.0027392579, 0.0066783951, 0.00087397132, 0.001567366 }, { -0.003378151, 0.0025916338, -0.0025553201, 0.0030152022 }, { 0.0096818399, 0.0012695523, 0.0072489949, 0.016881099 }, { 0.0022796191, 0.0051693266, 0.0023373397, -0.0041448561 }, { -0.0002074582, 0.0035962454, -0.0007460719, 0.0025086317 }, { 0.0035784996, 0.003162753, 0.0022592918, 0.00024595998 }, { -0.0051294944, -0.0041428868, -0.0027597, -0.0039539398 }, { 0.0022410392, 0.00031263884, 0.0016376751, -0.0022787113 }, { 0.0025647038, 0.0074733037, 0.0051722028, 0.0024463612 }, { 0.0011787227, 0.0071159753, 0.0017217143, 0.0062717989 }, { 0.0046836737, 0.0038976423, 0.00062832002, 0.0027638154 }, { 0.0014142926, 0.0024903802, 0.0015757227, 0.0011628587 }, { 0.0016928585, 0.0043828548, 0.001653268, 0.011450696 } } }, { { { 2.8886078, 2.8900127, 2.7925705, 2.7895874 }, { 4.5455217, 4.5284714, 4.7042338, 4.6915273 }, { 0.96672505, 0.99303664, 0.98927606, 1.0351588 }, { 1.2743756, 1.2525364, 0.99649566, 0.94572778 }, { 2.6910679, 2.6922168, 2.8503404, 2.8246076 }, { 1.256075, 1.2325025, 1.5911826, 1.6091223 }, { 1.3601759, 1.3606869, 1.2793533, 1.240925 }, { 2.0291828, 2.0506809, 1.7341658, 1.6555689 }, { 2.6663531, 2.6921882, 3.1290975, 3.11849 }, { 5.3676887, 5.3663279, 5.3848664, 5.3852162 }, { 1.0586431, 1.0865889, 0.8196623, 0.8076665 }, { 1.6967251, 1.7305944, 1.5450413, 1.6347879 }, { 3.0908857, 3.0706775, 3.2974343, 3.3053965 }, { 1.2172073, 1.3839086, 1.5086796, 1.4295506 }, { 0.97676668, 1.0856738, 0.98747912, 1.0385491 }, { 1.5662275, 1.4603538, 1.784278, 1.6575438 }, { 2.1085757, 2.2092885, 2.1410448, 2.1518347 }, { 4.0214776, 4.006424, 3.7686967, 3.7771354 }, { 1.2089239, 1.2116036, 1.1244311, 1.0901017 }, { 1.1827246, 1.1472796, 1.7516784, 1.7833976 }, { 2.2113439, 2.197512, 2.2692963, 2.2787751 }, { 0.98819531, 1.057833, 1.3587301, 1.3890421 }, { 1.208957, 1.2247867, 1.2301205, 1.2325178 }, { 1.0499613, 1.1319197, 1.4067885, 1.3209087 } }, { { -0.002860931, -0.0033581281, -0.0047612075, -0.0030481839 }, { -0.0017370907, -0.0065700936, -0.0011051926, -0.0046915938 }, { -0.0006126207, 0.0010791181, -0.022876686, -0.015937275 }, { -0.010040922, -0.016433531, -0.0044976975, -0.029838315 }, { 0.00056888968, -0.0093450028, -0.00041549218, -0.0069079656 }, { -0.029781683, -0.019722587, 0.019472312, 0.0016798037 }, { -0.0015128736, -0.0012250172, -0.0091568262, -0.0091368119 }, { 0.0010846814, 0.0017189068, 0.012975603, -0.0051530971 }, { -0.026042808, -0.0090684857, -0.0021498742, -0.0032938309 }, { -0.0012792901, -0.0010431731, -0.0021366737, -0.0025526365 }, { -0.03218779, -0.013848893, -0.021872476, -0.029443623 }, { 0.008300061, 0.011951182, -0.011139414, 0.0098292843 }, { -0.0065854884, -0.020955083, -9.3843515e-05, -0.0078425688 }, { -0.054726229, -0.0073673428, -0.019267231, -0.03383648 }, { -0.049769726, 0.0065482059, -0.010189395, -0.0050480393 }, { 0.022565943, -0.020311569, 0.0091512717, -0.015600752 }, { -0.014418429, 0.0060070592, -0.0055296743, -0.003361885 }, { 8.8146509e-05, -0.0082609252, 0.0036746024, 0.0040108321 }, { 0.0010230427, 4.8153189e-06, 0.0052893378, -0.0096303521 }, { 0.0032909351, -0.010982824, 0.003880027, 0.0097699095 }, { -0.006528317, -0.012608887, -0.0057088008, -0.003867806 }, { -0.046599771, -0.024701737, -0.001078321, -0.0041018649 }, { -0.021680777, -0.021120711, 0.0055144734, -0.0031337995 }, { -0.030559213, 0.0089872726, -0.011166202, -0.0077587071 } }, { { -0.0059548858, -0.0040070313, -0.0062572119, -0.0047711065 }, { -0.0031938803, -0.005431389, -0.0026376521, -0.0046119366 }, { 0.0064917253, 0.013030824, -0.027850471, -0.011824849 }, { -0.032644485, -0.025045016, -0.0034396539, -0.039827623 }, { -0.007691681, -0.014095643, -0.0008171964, -0.0051336386 }, { -0.035626586, -0.021424668, 0.00035790929, 0.0099705685 }, { -0.0019006762, -0.0014887089, -0.0050782898, -0.0096835564 }, { -0.00087496879, 0.0052586834, 0.017041675, -0.00046753956 }, { -0.022489507, -0.0084834888, 0.0017184219, -0.0023910992 }, { -0.0010618265, -0.00085888729, -0.0020035777, -0.0024245283 }, { -0.029245834, -0.038977066, -0.013385246, -0.030312138 }, { -0.0028497869, 0.014205986, -0.0125692, 0.0037959624 }, { -0.0086377959, -0.019175965, -0.007684309, -0.005037677 }, { -0.063945685, -0.0060751259, -0.0057457302, -0.019079575 }, { -0.043745147, 0.013651906, -0.034067394, 0.0012111497 }, { 0.0086647574, -0.019171418, 0.020745219, -0.0055629951 }, { -0.024541273, 0.0072112135, -0.0078821942, -0.0085072621 }, { -0.0018227939, -0.0021153099, 0.008577002, 0.0043865151 }, { -0.013984752, -0.012209334, 0.00023638151, -0.0085025952 }, { -0.0099800075, -0.0095390578, 0.0081328135, 0.012673433 }, { -0.0099975551, -0.0028467616, -0.010712056, -0.0045012212 }, { -0.011329139, -0.0084709831, -0.0070232966, 0.0015504012 }, { -0.015334801, -0.0075637633, -0.01107439, -0.0094188163 }, { -0.017505269, -0.00013701888, -0.033955823, -0.034192649 } } }, { { { 0.16413327, 0.084074422, 0.10646123, 0.18806073 }, { 0.039511019, 0.058967072, 0.035166958, 0.052296507 }, { 0.26970995, 0.21576211, 0.2954278, 0.29870678 }, { 0.40442043, 0.38744132, 0.14502571, 0.24076804 }, { 0.22655046, 0.20912486, 0.015295019, 0.16442957 }, { 0.69235319, 0.6080183, 0.36756076, 0.23314717 }, { 0.085565328, 0.075535626, 0.22162979, 0.33140596 }, { 0.16109547, 0.11961895, 0.26619212, 0.25941009 }, { 0.27077686, 0.23481238, 0.063446408, 0.11614487 }, { 0.026116057, 0.027491327, 0.030421883, 0.039965345 }, { 0.33922592, 0.38039792, 0.27167385, 0.31510976 }, { 0.32744968, 0.22567102, 0.23116584, 0.18867836 }, { 0.29783431, 0.28054079, 0.26752139, 0.23889932 }, { 0.61721263, 0.60602797, 0.51283622, 0.47601102 }, { 0.51383952, 0.53111455, 0.44519064, 0.42875877 }, { 0.3485879, 0.35374178, 0.53292055, 0.53995494 }, { 0.4366997, 0.35554257, 0.14878367, 0.22083288 }, { 0.12855375, 0.16718264, 0.17583661, 0.11125895 }, { 0.35898096, 0.37222307, 0.35439108, 0.35956111 }, { 0.16773044, 0.25668894, 0.23246756, 0.1506316 }, { 0.36172813, 0.26938211, 0.20069185, 0.1714591 }, { 0.3998571, 0.23607244, 0.34121623, 0.29126696 }, { 0.31471307, 0.29500525, 0.39451396, 0.40013999 }, { 0.29554399, 0.28083636, 0.47190649, 0.47892938 } }, { { 0.01419653, -0.061214452, -0.032506906, 0.0078227125 }, { -0.015799432, 0.0136148, -0.0090824684, 0.013638505 }, { 0.023848919, 0.022034707, 0.022812846, 0.022790329 }, { -0.0026324255, -0.0053566952, 0.00027470228, 0.050203583 }, { 0.0035659857, -0.02015272, -0.039043616, 0.054511651 }, { 0.0052075445, 0.0051043119, -0.011801097, -0.0074336577 }, { 0.020735195, 0.01811747, 0.00808952, 0.01140964 }, { -0.0073139049, 0.011075347, 0.0057685988, 0.010251582 }, { 0.024813488, -0.01629986, -0.012536791, -0.01110061 }, { -0.014508648, -0.021444084, -0.023836972, -0.014258253 }, { 0.0079687141, -0.00092011446, 0.060249601, 0.033199468 }, { -0.020822483, -0.013924875, -0.005068391, -0.016928794 }, { -0.030059, -0.013887475, -0.045329289, -0.04449219 }, { 0.007264541, 0.0015213919, -0.0066322618, -0.0036449174 }, { 0.0057175046, 0.0012159867, -0.00054271896, 0.0020625484 }, { 0.0027083179, -0.0012554897, -0.0044854592, -0.0045242423 }, { -0.017906563, -0.028301884, -0.010139427, 0.0035851304 }, { -0.020245794, 0.01149232, 0.011320484, -0.013561794 }, { 0.0068048997, 0.011957759, 0.0046962412, -0.0015476541 }, { -0.0022514613, 0.019996868, 0.0051520398, -0.023405604 }, { 0.0055213198, 0.0070384134, 0.024405643, -0.02050399 }, { 0.039987541, 0.021127504, -0.012323503, -0.0041538161 }, { 0.0072321478, 0.0053097351, 0.0039966161, 0.013617175 }, { 0.030470642, 0.0044694115, -0.0024591651, -0.0027274707 } }, { { -0.040500402, -0.039657034, -0.017497359, -0.017857145 }, { -0.0015646885, -0.020957371, -0.0057356498, -0.0060587007 }, { 0.0070388709, -0.013205178, -0.00033412934, 0.02192306 }, { -0.0042317723, 0.020620857, -0.012309167, 0.065948811 }, { -0.016686589, 0.013616667, 0.030139062, -0.019023551 }, { 0.015181564, 0.008673659, -0.0014559576, -0.025916054 }, { 0.031630671, 0.027030197, -0.026982415, 0.025214731 }, { -0.003845127, -0.00062884599, -0.029488655, -0.0051457939 }, { -0.0032476351, 0.0021153707, -0.033110808, -0.033629213 }, { -0.0064637077, -0.010805748, -0.014982403, -0.0084641529 }, { 0.0087766042, 0.017780238, 0.026838871, 0.032580257 }, { 0.0010700985, -0.037414784, -0.0053773565, 0.0040969752 }, { -0.02637392, -0.050236074, -0.048422986, -0.069357813 }, { -0.0089483588, 0.0026259727, 0.0040142797, -0.010752754 }, { -0.0025658872, 0.0071106029, 0.015467367, 0.0012536589 }, { -0.0037247444, -0.0036991733, -0.015429566, -0.016148852 }, { -0.024788221, -0.045938054, -0.028679471, 0.011593494 }, { -0.032699114, -0.036800967, -0.033870575, -0.031842203 }, { 0.018156047, 0.02457546, 0.0209432, 0.015057433 }, { 0.0043152638, 0.025831372, -0.019608349, -0.026614397 }, { -0.0057047815, -0.013831909, 0.027613211, -0.043616864 }, { 0.014124478, -0.010786326, 0.010775415, -0.023241344 }, { 0.018337827, 0.0048735321, 0.018371717, 0.022106807 }, { 0.013619207, 0.022051384, 0.0082720974, -0.0030262071 } } } }, { { { { 0.083322661, 0.079807165, 0.03660117, -0.051657142 }, { -0.099216074, -0.0080141573, 0.10637241, 0.0367403 }, { 0.20813681, -0.0001361621, -0.20762563, -0.085913357 }, { -0.22091149, 0.10003156, -0.16122219, 0.31542901 }, { 0.16226908, 0.02665194, -0.012123307, -0.16559939 }, { -0.14025496, 0.025804505, 0.076174345, 0.20548591 }, { 0.0035713609, -0.0092551928, -0.099937652, 0.0038879391 }, { 0.12405732, -0.0053373497, -0.030865175, -0.060934551 }, { -0.0060175826, -0.026583926, -0.075326797, -0.0063155886 }, { 0.036389362, 0.054175433, 0.06490927, -0.038784258 }, { 0.30604876, -0.030813476, 0.011402956, -0.21074796 }, { -0.31769497, 0.046793931, -0.038212559, 0.21137297 }, { 0.12952945, 0.20720126, 0.08525845, -0.14568109 }, { -0.09735197, -0.17799099, -0.12256082, 0.038889119 }, { 0.002114572, 0.026037779, -0.0036772795, 0.13478173 }, { 0.094577863, 0.0057382415, -0.087017736, -0.059444148 }, { 0.054953104, 0.071323301, 0.097417831, 8.3254475e-05 }, { -0.11005534, 0.027214076, 0.0059378205, 0.02443999 }, { 0.27096654, 0.1864966, 0.034810947, -0.25886676 }, { -0.35626794, 0.037256657, -0.17795321, 0.52988269 }, { 0.14913899, -0.0086988732, -0.028760192, -0.21779266 }, { -0.16010301, -0.17699785, 0.017269826, 0.17878541 }, { -0.0049504093, -0.02387924, -0.04034852, -0.060461173 }, { 0.10405347, 0.0072745723, -0.10244372, -0.072981984 } }, { { 0.019363393, 5.327311e-05, 0.0075925373, 0.0019542034 }, { -0.051707557, 0.06554253, 0.0050626046, -0.0061857803 }, { 0.022891698, 0.014872273, -0.020436928, 0.0069081531 }, { -0.044566611, 0.019854557, 0.023600607, -0.0055387351 }, { 0.02283957, -0.067086756, 0.088865856, -0.033915007 }, { 0.0020254431, -0.16422426, 0.032495902, 0.012460808 }, { -0.017316175, 0.023440087, 0.011459595, 0.0043887872 }, { 0.027714908, -0.06907548, 0.013578806, -0.009848884 }, { 0.0044782488, 0.0079432606, 0.010143137, 0.023589488 }, { 0.014325082, 0.0075465848, -0.0079373813, -0.0056032635 }, { 0.025123579, 0.01904807, -0.0092328848, -0.019002052 }, { -0.02633985, -0.019560519, -0.065544737, 0.0073352606 }, { 0.044308433, -0.0032233834, 0.01324206, -0.00047128106 }, { -0.076577611, -0.021853603, -0.020190543, 0.0026420865 }, { -0.0029799448, -0.0083566545, 0.14896601, 0.0078617095 }, { 0.021033237, -0.08234711, -0.020642328, -0.0089829962 }, { 0.043793881, 0.0096494147, 0.035831274, -0.01294602 }, { -0.014064874, 0.066144489, 0.0143429, 0.015113964 }, { 0.043111732, 0.0029232804, -0.016912145, 0.012142059 }, { 0.0014186333, -0.0078590166, 0.065781153, -0.038375123 }, { 0.02255714, -0.030191796, -0.078373164, -0.0017593196 }, { -0.033878798, 0.016266579, 0.013539653, 0.043519216 }, { 0.019046482, 0.0080403173, -0.0010755939, 0.03305222 }, { 0.023206448, -0.054323067, -0.035173093, -0.010873592 } }, { { 0.014068291, -0.026418786, 0.016375695, 0.0048801469 }, { 0.024404214, 0.0073572002, -0.027247654, 0.00093849398 }, { 0.012741523, -0.012913063, 0.0054881373, -0.021780769 }, { -0.020497215, 0.057437717, 0.0031122704, 0.014713732 }, { 0.012765254, -0.052846334, 0.048042201, 0.0016578534 }, { 0.031245254, -0.0469321, -0.057199738, 0.012436479 }, { -0.0022837759, 0.0068501747, 0.010541107, -0.0005227683 }, { -0.0187059, 0.0025631581, -0.0082184266, 0.0026294483 }, { 0.0053899388, -0.0199458, 0.0023448066, 0.016215236 }, { 0.021117204, 0.010868775, -0.016412681, -0.016399297 }, { -0.0026199223, -0.011436548, 0.0031355049, 0.011933919 }, { 0.017940023, 0.090292392, -0.061029038, 0.016388845 }, { 0.0074493061, -0.045849358, -0.082612855, 0.025851315 }, { 0.061276666, -0.024654813, 0.035447334, -0.025952766 }, { -0.0068267167, -0.02207426, 0.003724368, 0.0070458116 }, { 0.021714649, -0.017552721, -0.037105408, 0.024398534 }, { 0.0092901891, -0.021559075, 0.009034776, -0.016574279 }, { -0.017218595, -0.041930302, 0.003369899, 0.017959363 }, { -0.0022510875, 0.028106616, -0.042936548, -0.041948028 }, { -0.017145551, -0.032331654, 0.021486923, -0.020295391 }, { -0.023196465, -0.088353584, 0.010086154, 0.018689553 }, { -0.024508386, -0.00058959302, -0.02867958, 0.019018994 }, { 0.0088748911, 0.012528454, -0.016636351, 0.0078166115 }, { 0.00066772723, 0.001693912, 0.032066885, 0.016951148 } } }, { { { 0.015200105, 0.071414961, -0.020616434, 0.0063982643 }, { -0.084578144, -0.12318522, -0.035470756, 0.057833574 }, { 0.19487946, 0.44043059, 0.10981527, -0.31907303 }, { -0.17774238, -0.30460726, -0.53133003, 0.31186606 }, { -0.1172677, 0.3183613, 0.10375266, -0.066515168 }, { 0.054176263, -0.12382077, -0.033807438, 0.039809238 }, { -5.3634009e-05, 0.004084452, 0.005103199, -0.060697866 }, { 0.06093199, 0.060355274, 0.049176467, -0.060579228 }, { 0.054611799, 9.0520863e-05, -0.048891261, -0.047609349 }, { -0.036428706, 0.06336736, 0.0020843807, 0.033254378 }, { 0.26975732, 0.51328693, 0.29976157, 0.049031141 }, { -0.28383516, -0.48219276, -0.27898799, -0.033028759 }, { -0.078976834, 0.14077934, 0.098587186, 0.051336328 }, { 0.076281206, -0.074223398, -0.053178835, -0.099578331 }, { -0.056377095, -0.00066113896, -0.11597726, 0.058805777 }, { -0.0027130032, 0.12007881, 0.0081935835, -0.10415807 }, { -0.019349408, 0.06206561, -0.0079099126, 0.079363093 }, { -0.059959607, -0.0591041, -0.047505451, -0.0031496967 }, { -0.11419194, 0.20904287, 0.53960104, 0.10467592 }, { -0.21312862, -0.34770872, -0.54593093, 0.23230512 }, { -0.073229448, 0.12913, 0.27728133, -0.050627706 }, { 0.082312471, -0.24529296, -0.12381516, 0.05577292 }, { 0.03015389, -0.0015805638, 0.024306632, -0.080697961 }, { 0.061367564, 0.056058289, 0.041197211, -0.015551356 } }, { { -0.029269776, -0.030251548, 0.01352869, 0.0084860712 }, { 0.053983187, 0.047657625, -0.026379004, 0.022474039 }, { 0.011898439, 0.045120742, -0.024430477, -0.081318878 }, { -0.0012641508, -0.018495044, -0.030127865, -0.0088483264 }, { 0.040728292, 0.010691761, -0.023566342, 0.028045232 }, { 0.014593998, 0.0047006468, -0.049032498, -0.011446808 }, { 0.00045433705, -0.0030610749, -0.010359449, -0.0026455857 }, { -0.0026794352, -0.032142744, 0.010153936, -0.0034586152 }, { 0.0097198782, 0.0051005644, 0.03482872, -0.0043676475 }, { -0.0012381415, -0.025746274, -0.0081178021, 0.0041481596 }, { -0.01598781, 0.0048815642, 0.06313106, -0.0062291669 }, { 0.072970618, -0.041153529, -0.007457013, 0.059776924 }, { 0.0024768493, 0.0093018711, 0.024827984, 0.043842172 }, { -0.012927661, -0.023256709, -0.0035951539, -0.069710027 }, { 0.0064149713, 0.0019783425, 0.010135188, 0.019449636 }, { -0.0071551675, 0.015761815, 0.0086309278, 0.038854386 }, { 0.020978109, -0.0056696814, 0.0025526797, -0.017352926 }, { -0.010711116, -0.0097050903, 0.0022304504, -0.0039308489 }, { 0.036904234, 0.025927127, 0.028330671, 0.051193417 }, { -0.00076391153, -0.077528792, -0.029763477, 0.0033945843 }, { -0.01775202, 0.034507636, 0.065392848, -0.017840909 }, { -0.019567742, -0.019880035, 0.055214211, -0.02206159 }, { 0.01110111, 0.0022938832, -0.011417507, 0.017692635 }, { 0.050208493, -0.028178909, 0.0065276591, -0.0056267473 } }, { { 0.0065622702, -0.0012303136, -0.0081183663, 0.00079383048 }, { 0.030775912, 0.052260356, -0.019758331, -0.020044147 }, { 0.019016537, -0.043070451, 0.035298744, -0.040592775 }, { 0.010468089, 0.00057085185, 0.0081761984, 0.0033382478 }, { 0.047189462, -0.052695409, 0.021849623, 0.033585939 }, { 0.0012065616, -0.050287476, -0.065085924, -0.039012886 }, { -0.012294892, 0.006839242, 0.0051165438, -2.0711078e-05 }, { -0.03292822, 0.015299577, 0.0029119931, 0.0073040242 }, { -0.0086784873, 0.0085910164, -0.0059378411, -0.010259049 }, { -0.014191355, -0.011172486, -0.01299927, 0.015386671 }, { 0.040453224, -0.041489173, 0.015047889, 0.064340197 }, { -0.020000046, 0.058477092, -0.0018150465, 0.048536972 }, { -0.006105982, 0.03437044, 0.0087640339, 0.032868283 }, { -0.027120362, 0.016579996, -0.01708524, 0.011178424 }, { 0.030535528, 0.0058718219, -0.031240404, 0.024241052 }, { 0.003729958, -0.055735848, -0.0055392842, 0.03447519 }, { -0.04084502, -0.01227488, 0.0062970198, -0.021996031 }, { 0.053671675, -0.067787009, 0.0053426012, -0.0080796738 }, { -0.021911856, 0.038395527, -0.07713235, 0.024805484 }, { -0.0034319194, 0.0052741327, 0.026402991, 0.0012916612 }, { -0.033119652, -0.0046506889, 0.045613946, -0.050230593 }, { -0.0054612035, -0.033482221, 0.084267507, -0.0224334 }, { -0.0063348693, -0.0074524817, -0.0029629355, 0.035493958 }, { -0.0073519185, 0.045139911, 0.0022901735, -0.041385515 } } }, { { { 0.99640669, 0.99424882, 0.99911727, 0.99864438 }, { 0.99146493, 0.99235134, 0.99369348, 0.99764995 }, { 0.95848895, 0.89778665, 0.9720248, 0.943828 }, { 0.95896077, 0.9472107, 0.83168251, 0.89623886 }, { 0.97975356, 0.94759472, 0.99452924, 0.98394744 }, { 0.98863213, 0.99196902, 0.99652121, 0.97785007 }, { 0.99999362, 0.99994883, 0.99498061, 0.99814861 }, { 0.99040248, 0.99816269, 0.99831309, 0.99630173 }, { 0.99848953, 0.99964658, 0.9959596, 0.99884607 }, { 0.9986735, 0.99651874, 0.99788899, 0.99869411 }, { 0.91299789, 0.85766372, 0.953946, 0.97631002 }, { 0.90471405, 0.87481454, 0.959534, 0.97684726 }, { 0.9884254, 0.96811612, 0.9914694, 0.98799879 }, { 0.99232241, 0.98122887, 0.99103524, 0.99426948 }, { 0.99840731, 0.99966074, 0.99324506, 0.98912879 }, { 0.99551377, 0.99274778, 0.99617307, 0.9927827 }, { 0.99830144, 0.99552039, 0.99521214, 0.99684577 }, { 0.99211525, 0.9978808, 0.99885333, 0.99969634 }, { 0.95579147, 0.95995838, 0.84120087, 0.96022443 }, { 0.90975235, 0.9368621, 0.81871367, 0.8156339 }, { 0.98610091, 0.99158952, 0.96035822, 0.97468107 }, { 0.98366238, 0.9531543, 0.99215501, 0.98230604 }, { 0.99953301, 0.9997136, 0.99888998, 0.99490315 }, { 0.99267663, 0.998401, 0.99388534, 0.99721201 } }, { { -0.0021537732, 0.010607958, -0.0066166595, -0.0027390442 }, { -0.0069401807, 0.0053215201, 0.0062121114, 0.013403291 }, { -0.0035740125, -0.021839368, 0.00042431197, -0.029478899 }, { -0.007886159, -0.0087705321, -0.010570968, 0.0040635318 }, { -0.0021772698, 0.00025306776, -0.0092725896, -0.0075657706 }, { -0.010438319, -0.0072866821, 0.009272756, 0.0043932916 }, { -0.00058203184, 0.0081284104, 0.027749999, 0.0035426599 }, { -0.003604276, -0.012244348, 0.0072177908, 0.0026686264 }, { 0.011192179, 0.0069527119, 0.017278396, -0.0053058312 }, { -0.020276487, -0.0063228657, 0.013968347, -0.0021534789 }, { -0.0037534313, 0.00061399133, -0.02126817, 0.0085256452 }, { 0.015620795, -0.022637876, 0.00069280338, 0.0054369037 }, { 0.0095244184, -0.0026896982, -0.0057963534, 0.0067237437 }, { -0.0085689961, -0.004816024, -0.00088793436, -0.0034021999 }, { 0.015428153, 0.019777562, -0.011217833, 0.0095744159 }, { -0.003802304, 0.0022643577, 0.0054254827, 0.025560756 }, { -0.0053298651, 0.021621993, -0.01864184, 0.019120967 }, { 0.015380344, -0.0027384467, 0.0010235928, 0.0062792725 }, { -0.001166873, -0.0049586656, -0.014850883, 0.00057841904 }, { 0.0032865456, -0.033386196, 0.0032068954, 0.02854738 }, { 0.010308266, -0.000233004, -0.020287643, 0.0044441043 }, { -0.0040523345, 0.0050367711, 0.01627907, -0.010032412 }, { 0.0073463987, 0.00073274858, 0.002814661, 0.030221018 }, { 0.0057509063, -0.011441338, 0.01894259, 0.0077856453 } }, { { -0.0053054924, 0.0037677068, 0.0066263851, 0.0011220287 }, { -0.02212139, 0.013769097, -0.0013834097, 0.014152363 }, { -0.0008493126, 0.021473024, -0.0039313241, -0.017764981 }, { -0.00081897848, -0.0074161164, 0.0038179092, -0.0035760615 }, { 0.014045643, 0.015317904, 0.0045966739, 0.0075917156 }, { 0.0035574126, -0.00017773424, -0.0010937491, -0.0017762282 }, { 0.0072018344, 0.012586227, 0.0138702, -0.0085424173 }, { -0.0055783456, -0.019909385, 0.01190919, -0.0065821489 }, { 1.7402026e-05, 0.0094513341, 0.015333305, -0.0072158969 }, { -0.0063049905, 0.0021776758, 0.014376378, 0.0072426401 }, { -0.0078049673, 0.028764242, -0.0024169449, 0.0077604105 }, { 0.00047536469, 0.029806623, 0.0017798261, 0.00087410198 }, { -0.0030498401, 0.0044874501, 0.0020382571, -0.0011101062 }, { -0.0057084397, -0.0013428994, -0.001024136, 0.0066188614 }, { 0.039201052, 0.015120258, -0.0082642793, 0.0051985023 }, { -0.0091203243, 0.020790215, 0.0025270937, 0.020092044 }, { -0.0029830063, 0.006602841, -0.00833601, 0.044852353 }, { 0.025206353, -0.0038915173, 0.00045914851, 0.0037840538 }, { 0.0014814254, -0.011573911, 0.046232337, -0.015228958 }, { -0.0071984443, 0.0090004063, 0.022942838, 0.016019787 }, { 0.0050929336, 0.0060892107, -0.0061771339, 0.0047850766 }, { -0.011634853, 0.0010276548, 0.022396644, -0.0021248711 }, { -0.012943002, 0.0016430074, 0.02034928, 0.024289705 }, { 0.0051047037, 0.010052556, 0.0020923265, -0.019043181 } } }, { { { 2.1627647, 2.1788232, 1.9290264, 1.8457806 }, { 2.526488, 2.3020441, 2.538915, 2.03484 }, { 3.9987521, 4.3952121, 3.906821, 4.1693278 }, { 4.0400466, 4.1069844, 5.2512999, 5.4283264 }, { 3.0141968, 3.3306035, 3.2224806, 3.2473051 }, { 2.9840674, 3.1294685, 3.2964833, 3.2929246 }, { 1.8346741, 1.8637353, 2.3037966, 2.0860888 }, { 2.691236, 2.6068079, 1.9349032, 2.1632935 }, { 1.9231956, 1.7251627, 2.1609654, 2.1155629 }, { 2.165771, 2.1908952, 1.777038, 2.0223741 }, { 4.5166991, 4.8674508, 3.918546, 3.378087 }, { 4.4502295, 4.5429338, 3.9552598, 3.3580272 }, { 3.0973598, 3.3953852, 2.2704362, 2.6488177 }, { 3.2110537, 3.3104376, 2.515002, 2.3267785 }, { 1.8303675, 1.7094345, 3.1787979, 2.5960104 }, { 2.4391795, 2.8730077, 2.3730261, 2.1545299 }, { 2.2130903, 2.1899209, 2.4997355, 1.9058674 }, { 2.6472893, 2.5455636, 2.1164596, 1.8341163 }, { 3.9428283, 4.0433678, 4.5430063, 4.2482776 }, { 4.1941673, 4.28852, 4.64044, 4.6644567 }, { 3.0873642, 2.649364, 3.6026133, 3.2426354 }, { 3.2415154, 3.5406745, 3.2976852, 3.3100246 }, { 1.8400289, 1.8404692, 1.889289, 2.0125184 }, { 2.7063995, 2.7229173, 2.6289878, 2.4313709 } }, { { -0.015335928, -0.043382119, -0.0054163805, -0.028249934 }, { -0.017200109, 0.0027582413, -0.079612821, -0.0013966663 }, { -0.027233584, -0.018783395, -0.01183278, -0.020918937 }, { -0.0036358348, -0.015712206, -0.0089146421, -0.0057117233 }, { 0.020392865, 0.017743746, -0.068597326, -0.030425581 }, { -0.041123673, -0.020767538, -0.0087941887, -0.0065248183 }, { -0.0055478408, -0.00082196865, 0.0088521402, -0.045916836 }, { -0.010506485, 0.0078523247, -0.030002306, -0.0015085765 }, { 0.01894068, -0.012424968, -0.034837214, -0.045009941 }, { -0.045299587, 0.02630478, -0.017175711, -0.043601235 }, { -0.046003661, -0.020588165, 0.034398873, -0.054653787 }, { -0.0042534368, 0.01325834, -0.0036369576, -0.079162988 }, { -0.028728556, 0.0051289128, 0.012104313, 0.010686997 }, { -0.066337767, 0.00059928728, -0.080303668, 0.011318772 }, { -0.031879871, 0.0011317962, -0.050259029, 0.0031596552 }, { -0.090121238, -0.011196084, -0.072456123, -0.00079731072 }, { -0.024243475, 0.021401076, -0.018209385, -0.0083196072 }, { -0.079888701, 0.0032806631, -0.12762259, -0.04652308 }, { 0.031806075, -0.034165157, -0.015255921, -0.049164663 }, { -0.0012051123, 0.030788487, 0.022291919, 0.0025694519 }, { 0.035836509, 0.0055365388, 0.026704836, 0.0001547235 }, { -0.012129747, -0.0094322145, -0.040637935, -0.12125388 }, { -0.027044986, 0.04531553, -0.033484589, -0.0059927923 }, { 0.0067188802, -0.051166351, -0.048822794, -0.025926988 } }, { { 0.022049053, 0.021265778, -0.040370641, -0.036232952 }, { -0.0058098424, -0.0042264198, -0.077428509, -0.04241654 }, { -0.0026825379, -0.029453318, -0.016181275, -0.028320229 }, { -0.012541692, -0.01345735, 0.00037814888, -0.0046052489 }, { -0.026527394, 0.020033638, -0.025683861, -0.084207169 }, { -0.0010459945, -0.036745215, -0.039772051, 0.024810839 }, { 0.012134618, 0.0068515798, -0.035286972, 0.043129595 }, { -0.077093357, -0.026872688, 0.032800133, -0.090326706 }, { 0.13930909, 0.0081274014, -0.08349188, -0.012200005 }, { -0.091693797, -0.012567011, -0.069736822, -0.0061444184 }, { -0.053061301, 0.003642159, 0.0052515175, -0.036957472 }, { 0.0043493933, -0.013069332, -0.014708126, -0.032765039 }, { -0.016116105, -0.022907609, -0.043503106, -0.013266465 }, { -0.072759977, -0.077354585, 0.0043827591, -0.013821612 }, { -0.032399073, -0.045305037, -0.021840791, 0.073996542 }, { -0.057239255, -0.056581235, -0.038880927, 0.044102943 }, { -0.026951489, -0.088667645, -0.013659704, 0.033527579 }, { 0.034815442, -0.028634059, -0.036666529, 0.011546036 }, { 0.026688447, -0.0081892129, -0.031138092, -0.041739155 }, { 0.0015665701, -0.012701682, 0.0013533943, -0.002849785 }, { 0.032994636, 0.008802974, 0.019032649, 0.0039042621 }, { -0.044544917, 0.0093201326, -0.017968915, 0.01936344 }, { -0.034794535, 0.043032983, -0.051072531, -0.040148303 }, { -0.0030398597, -0.027112065, -0.064007483, -0.01798277 } } }, { { { 0.22040906, 0.24911942, 0.41660708, 0.23632869 }, { 0.25894466, 0.1416669, 0.41902981, 0.35717608 }, { 0.26918091, 0.14566759, 0.2147652, 0.15769391 }, { 0.22500921, 0.12113361, 0.11151768, 0.12348609 }, { 0.25699055, 0.056819107, 0.3859882, 0.4585378 }, { 0.7304995, 0.20719358, 0.44455636, 0.42226989 }, { 0.43602897, 0.51049581, 0.41978824, 0.62521039 }, { 0.42004119, 0.52912054, 0.33314238, 0.38257921 }, { 0.55092562, 0.43085653, 0.31149977, 0.34391138 }, { 0.40391149, 0.48820255, 0.13569806, 0.36060266 }, { 0.13647907, 0.12061002, 0.20668806, 0.30221394 }, { 0.15583476, 0.13133696, 0.22775202, 0.35653823 }, { 0.56336195, 0.25684627, 0.11118383, 0.23109245 }, { 0.45430401, 0.42843367, 0.25496534, 0.097473509 }, { 0.3420223, 0.39418925, 0.26458947, 0.30588082 }, { 0.51345558, 0.3612731, 0.41151773, 0.25269512 }, { 0.29195176, 0.42659964, 0.47971993, 0.32714756 }, { 0.49222777, 0.28477645, 0.74993827, 0.43781271 }, { 0.098434481, 0.31164923, 0.14486345, 0.11466693 }, { 0.070833248, 0.20569754, 0.10233576, 0.047352701 }, { 0.51050902, 0.15597643, 0.1417112, 0.35581415 }, { 0.48261165, 0.14592221, 0.62554576, 0.5209765 }, { 0.33562628, 0.39920067, 0.28183433, 0.297464 }, { 0.366851, 0.59278666, 0.59095922, 0.48385165 } }, { { 0.13792051, 0.072076744, 0.094800532, 0.026318377 }, { 0.13607414, -0.061382542, 0.061800151, -0.020060553 }, { 0.028096406, 0.069282616, 0.010195109, -0.010461141 }, { 0.018651237, 0.02642439, 0.0077552848, -0.051151646 }, { 0.098299803, -0.0085081153, -0.011764584, 0.087405711 }, { 0.064082346, -0.04626424, -0.071480607, 0.064447268 }, { 0.022766233, 0.0167542, -0.021285286, -0.071637286 }, { -0.0202445, 0.011692601, 0.048325551, 0.0097755172 }, { -0.027775183, 0.016463115, 0.060050391, -0.034226107 }, { 0.019412547, 0.059977501, -0.0041737169, 0.031539317 }, { 0.013192979, 0.036015595, -0.049943198, 0.014112312 }, { -0.013272349, 0.035821037, -0.060503687, 0.095316821 }, { 0.038338785, -0.059038809, -0.044954172, -0.00051347307 }, { -0.039594082, 0.018205882, 0.13413799, 0.012292954 }, { 0.015177594, -0.0082493854, 0.00029420179, 0.010356248 }, { 0.100271, -0.13623174, 0.1121235, 0.068902399 }, { 0.025189636, 0.0014918434, 0.0088847718, -0.053714493 }, { 0.06487698, -0.097217547, -0.069537353, 0.032490984 }, { -0.030729608, 0.048956315, 0.016036034, 0.022485239 }, { 0.049839618, 0.01148525, -0.021032427, -0.019665817 }, { -0.0037762817, -0.030422275, -0.062343207, 0.057994884 }, { 0.014035184, -0.021387762, -0.080846143, -0.020681511 }, { -0.03594567, 0.026862531, 0.078975557, -0.034056659 }, { -0.014490672, 0.026128902, 0.045617611, 0.090192953 } }, { { 0.011904288, -0.014624471, 0.042023114, 0.019592867 }, { 0.032705848, 0.00038558691, 0.031901745, 0.027208951 }, { -0.044369719, -0.039761364, -0.013366816, -0.019308126 }, { -0.019051023, -0.00015767269, -0.082968285, -0.035266053 }, { -0.004775162, 0.010889271, 0.0089521094, 0.027037104 }, { 0.005616143, -0.00099668486, 0.0068716426, -0.12649184 }, { 0.018531199, 0.023881776, -0.053798787, -0.041912909 }, { -0.0036187094, 0.11590788, 0.025140733, 0.022280209 }, { -0.02994342, -0.026293799, -0.017204658, 0.044901944 }, { 0.079892089, 0.10816526, 0.14667807, 0.027301352 }, { -0.045296738, -0.066748968, -0.0099354431, -0.070369692 }, { -0.08357374, -0.043311901, 0.013163375, -0.0881777 }, { -0.065923811, -0.10382274, 0.090440302, -0.013617198 }, { -0.092578587, -0.010178017, -0.01416593, 0.0432333 }, { 0.055172515, 0.10021805, -0.0062782668, -0.11791805 }, { -0.039684132, -0.08934283, 0.020686084, -0.0013788117 }, { 0.064624676, 0.051773746, 0.0045383964, -0.037696971 }, { -0.066296373, 0.020570689, -0.017742721, -0.022651449 }, { -0.0061572447, -0.094510525, -0.094775804, -0.038022514 }, { 0.0055683313, 0.039513342, -0.096815654, -0.0065483011 }, { -0.03311602, -0.018395457, 0.0028464434, -0.088048272 }, { -0.073106109, -0.055187863, -0.093209932, -0.10155137 }, { 0.042841842, -0.005778703, 0.074069607, -0.025841052 }, { -0.018569637, 0.063144303, 0.02291584, 0.005525742 } } } }, { { { { -0.20809663, -0.18346453, -0.072140694, -0.0078104407 }, { -0.19490097, 0.25712922, 0.37640771, 0.11563399 }, { 0.26894915, -0.33477877, -0.093739129, -0.55078405 }, { -0.65794103, 0.09211629, -0.19166986, 0.5574327 }, { 0.45579532, 0.23202083, 0.19626303, -0.64130523 }, { -0.018763975, -0.24981569, -0.32514026, -0.11121342 }, { 0.22376238, 0.09515938, 0.071728264, -0.02790747 }, { -0.3053338, 0.34023365, 0.099862481, 0.26163964 }, { -0.21722968, -0.094881958, -0.086364431, -0.0081863581 }, { -0.16090709, 0.23527698, 0.28947119, 0.11309742 }, { 0.26447184, -0.33536416, -0.096418234, -0.26201294 }, { -0.56343769, -0.041662822, -0.24873841, 0.67122901 }, { 0.35362642, 0.2577592, 0.2009013, -0.74233681 }, { -0.047956299, -0.54973418, -0.4958485, -0.12453303 }, { 0.06917425, 0.080509853, 0.0090863722, -0.023518805 }, { -0.27000602, 0.083167162, 0.12715558, 0.12397839 }, { -0.11376964, -0.079199259, 0.019676685, -0.0094352472 }, { -0.19185851, 0.22193112, 0.28110877, -0.06422845 }, { 0.084091992, -0.16151548, 0.091400556, -0.28257376 }, { -0.53821376, 0.21718328, -0.2234907, 0.52302804 }, { 0.71322306, 0.042728493, 0.13229522, -0.61892094 }, { 0.15270046, -0.26304886, -0.33110633, -0.052728951 }, { 0.072398971, 0.25829764, 0.25881687, -0.020942042 }, { -0.26788161, 0.055822039, 0.33817103, 0.42061402 } }, { { 0.088248648, 0.091306255, 0.020476927, 0.0030144802 }, { 0.0087376707, 0.043816157, 0.0022807168, 0.016745414 }, { -0.13412414, 0.12686539, 0.060531476, 0.044582027 }, { 0.019204757, -0.0070891897, 0.091194602, 0.065258927 }, { -0.10429513, -0.027665602, -0.064350626, 0.0053147478 }, { 0.069218141, -0.035018324, -0.088257571, 0.019279642 }, { -0.073137338, 0.040764456, -0.022352804, 0.031743288 }, { 0.040325697, -0.12840825, -0.009582113, 0.034509657 }, { 0.081971224, -0.0035223125, -0.051728499, 0.0038899717 }, { 0.050968435, 0.022254651, 0.18781134, -0.032392139 }, { 0.024342518, 0.13929014, -0.019175435, -0.0011608234 }, { -0.0021942487, -0.01251222, 0.024263454, -0.063179344 }, { -0.13071776, -0.059221747, -0.034153238, 0.036561209 }, { 0.054124093, 0.070495803, 0.081441614, 0.051900357 }, { 0.027480327, 0.028940343, -0.01469313, 0.032388411 }, { -0.039696828, -0.0069393798, -0.011361641, 0.035031025 }, { -0.039730763, 0.0085971581, -0.0077461932, -0.040735188 }, { 0.10893368, 0.00014757217, 0.025489178, -0.11388774 }, { -0.0013816669, 0.0031148929, 0.10281666, -0.019860642 }, { -0.065093128, -0.11495815, 0.041783056, -0.091373461 }, { -0.044985581, 0.0012713031, -0.16078032, 0.17303747 }, { -0.038132358, -0.02995975, -0.037612782, 0.012575173 }, { 0.0042976619, 0.027014275, 0.017518808, 0.030405184 }, { -0.0015298607, 0.029297664, -0.1034349, 0.023450502 } }, { { 0.028785558, -0.028708377, -0.010459636, 2.8360915e-05 }, { 0.091634877, 0.021214811, 0.12282079, 0.080617943 }, { -0.29287977, 0.045481846, 0.014712563, 0.057317576 }, { -0.10728772, 0.03268482, 0.015167285, -0.011256231 }, { 0.09337321, 0.037150859, 0.052549202, -0.042671474 }, { -0.0041288689, -0.024299997, -0.11357403, -0.022045772 }, { -0.041469935, -0.0071353646, -0.0086607538, 0.008536762 }, { 0.033629272, -0.0070042955, -0.037864853, -0.0055907778 }, { 0.016404597, -0.0055321059, -0.020989839, -0.013771265 }, { 0.042552435, 0.04428518, 0.0030587466, 0.044894182 }, { -0.027600219, 0.026831779, 0.051120849, -0.032184808 }, { 0.13870554, 0.15273282, 0.049260112, 0.043371121 }, { -0.018453269, -0.18061413, 0.24805649, -0.031741165 }, { -0.085137374, 0.025935867, 0.015978067, 0.067726486 }, { 0.072393868, 0.0050430488, 0.0016664585, 0.0072097064 }, { 0.033840162, 0.082225764, -0.079387016, 0.033165625 }, { 0.033170766, 0.0012231618, -0.066984982, 0.051671704 }, { 0.017894231, -0.012267532, 0.045536123, -0.07327109 }, { 0.0073109731, -0.063797898, -0.13446413, 0.1408986 }, { -0.045702456, -0.1647051, -0.14336468, 0.054543693 }, { 0.0042448876, -0.13234456, 0.092181719, -0.10440841 }, { -0.060020212, -0.011098469, -0.030257182, -0.030922037 }, { -0.018118661, 0.00067983745, -0.0061776598, -0.031721273 }, { -0.019885189, 0.094157888, 0.014017961, -0.051373389 } } }, { { { 0.12415319, -0.13611564, -0.029441661, -0.14143497 }, { -0.26074418, 0.011913326, -0.033328425, 0.43248793 }, { 0.19336432, 0.37269586, 0.36803538, -0.51720719 }, { -0.15185913, -0.47431781, -0.6593667, 0.23163184 }, { 0.18276216, 0.19248743, 0.65453332, 0.54748087 }, { 0.17751443, -0.0020337696, 0.08506463, -0.40147769 }, { -0.11370932, 0.11523476, -0.010573025, 0.082295392 }, { -0.13666335, -0.32747478, -0.16897386, 0.15359006 }, { 0.11716326, -0.12259922, 0.0033396256, -0.13240653 }, { -0.27776876, -0.10222241, -0.039920479, 0.35499708 }, { 0.090003723, 0.3313923, 0.1871549, 0.003163675 }, { -0.51626118, -0.76341562, -0.56326874, 0.20153559 }, { -0.34172723, 0.26975563, 0.67520079, -0.1252004 }, { 0.45758078, -0.19142179, 0.064180031, -0.48748431 }, { -0.12800789, 0.1399912, 0.0077954775, 0.14379741 }, { -0.13042104, -0.45670817, -0.18831095, 0.0032738639 }, { 0.12446807, -0.11504524, -0.027331682, 0.03861758 }, { -0.31337986, -0.11842668, 0.033415325, 0.45344231 }, { 0.11463107, 0.077427841, 0.060880794, -0.069619455 }, { -0.37772106, -0.59628905, -0.65426572, 0.065297039 }, { 0.29532991, 0.75920243, 0.53294265, -0.15002562 }, { 0.3618333, 0.10488387, 0.36007528, -0.30963565 }, { -0.13738196, 0.20795596, 0.029274703, 0.18017599 }, { -0.10290023, -0.48517535, -0.33278584, 0.56477854 } }, { { -0.0047891472, 0.024629901, 0.015256654, -0.0084462001 }, { 0.056227746, -0.048057782, -0.15671312, 0.06418471 }, { -0.070093217, -0.018057199, 0.062026545, -0.051053726 }, { -0.0091221476, 0.0020547295, -0.087729813, -0.10164738 }, { 0.098917091, -0.066835916, 0.083151519, 0.006342544 }, { 0.0013540606, 0.038719082, 0.036333261, -0.053178668 }, { 0.0083787438, 0.0028359378, 0.0089872852, 0.031308249 }, { 0.014379686, -0.079563474, -0.079160006, -0.016352226 }, { 0.0091376645, -0.016678006, -0.044636785, -0.0011035265 }, { 0.0099146109, 0.027589302, -0.09494437, 0.07451767 }, { 0.017453983, 0.080674871, 0.06341808, 0.048820473 }, { 0.02794057, 0.058230195, -0.010793601, 0.091813872 }, { -0.049633232, -0.1142016, 0.036984283, 0.0034294865 }, { 0.047712957, 0.10161366, 0.13774722, 0.039503136 }, { 0.014194782, -0.014555183, -0.00053182909, 0.0019143477 }, { 0.0014900262, 0.0056176356, -0.034517871, -0.0010707988 }, { 0.013287784, -0.0073967933, -0.019271341, 0.016354896 }, { -0.10345626, 0.023536634, 0.027943639, -0.015686972 }, { -0.025193395, -0.10224801, 0.078686884, -0.048574399 }, { 0.15797878, -0.0012322757, -0.036096649, -0.23983963 }, { -0.10455507, -0.056368102, -0.06570944, 0.29104616 }, { 0.05155239, -0.040940824, -0.038367594, 0.058174485 }, { 0.010471732, -0.066952904, -0.047763843, -0.021124742 }, { -0.033555686, 0.0049111983, -0.026592789, 0.014438586 } }, { { -0.0048440946, 0.025915095, -0.018325403, 0.022133613 }, { 0.059240081, -0.031272176, -0.12967647, -0.17957913 }, { 0.0574837, 0.067005152, 0.024644254, 0.10786296 }, { 0.067084865, 0.008513386, 0.04077659, 0.10587924 }, { 0.026332643, 0.1072618, -0.098375042, -0.001724609 }, { -0.021386362, -0.0020174921, 0.16800158, 0.081359882 }, { -0.018204146, -0.026432136, -0.0068153455, -0.029997667 }, { -0.043221501, -0.016869967, -0.067406967, -0.024965804 }, { -0.0033879999, 0.031310818, -0.010853802, 0.00088944004 }, { -0.068991006, 0.087874253, -0.15737392, -0.088870044 }, { 0.061763806, -0.00072874343, -0.009915009, -0.0178225 }, { -0.07340717, 0.080339271, -0.0027124572, -0.13078641 }, { -0.023682834, 0.16512313, -0.15784472, 0.047978827 }, { 0.0063250439, -0.09953777, 0.094180888, 0.010565041 }, { 0.010047311, -0.042999009, -0.012483998, -0.016966759 }, { -0.048612679, 0.051708319, 0.015059148, 0.0036776472 }, { -0.011737015, -0.0027276603, 0.026535075, -0.065453876 }, { 0.056388137, 0.061461073, -0.12726984, -0.025578248 }, { 0.0016833003, 0.10878558, 0.13254828, -0.017098914 }, { -0.031606282, -0.072245098, 0.12724789, -0.21852899 }, { -0.062502612, -0.073402771, -0.049624729, 0.069066032 }, { -0.075837195, -0.10297347, -0.07249237, -0.11538062 }, { -0.015644005, 0.039474396, 0.074415075, -0.038881161 }, { -0.040175911, 0.034030267, 0.03947059, 0.014167463 } } }, { { { 0.97019677, 0.97355703, 0.99695983, 0.98991674 }, { 0.94552952, 0.96630359, 0.92585444, 0.89419404 }, { 0.9435447, 0.86545998, 0.92507456, 0.65508294 }, { 0.73759908, 0.87552111, 0.72697883, 0.79725496 }, { 0.87111918, 0.95347518, 0.73011435, 0.53758004 }, { 0.9839393, 0.96829127, 0.94183216, 0.90909143 }, { 0.96798791, 0.98876976, 0.99736817, 0.99621717 }, { 0.9423876, 0.88147679, 0.98054848, 0.95286662 }, { 0.96906348, 0.98791034, 0.99625801, 0.99116169 }, { 0.94707625, 0.9665378, 0.9563539, 0.9280011 }, { 0.96018435, 0.88187869, 0.97758711, 0.96505917 }, { 0.64499021, 0.64456248, 0.78794513, 0.71332673 }, { 0.87073007, 0.92778882, 0.70974824, 0.65822558 }, { 0.88787388, 0.81311133, 0.86603417, 0.86420517 }, { 0.98935782, 0.98687417, 0.99992833, 0.98932764 }, { 0.95398485, 0.88572054, 0.97384313, 0.99227952 }, { 0.98567955, 0.99019799, 0.99943274, 0.99920952 }, { 0.93004482, 0.96784384, 0.95909399, 0.88896838 }, { 0.98984254, 0.98382807, 0.99395144, 0.95671584 }, { 0.75342733, 0.77283296, 0.72248756, 0.84981055 }, { 0.63568318, 0.6494505, 0.83574524, 0.77099234 }, { 0.91965169, 0.95906448, 0.87218942, 0.94939213 }, { 0.98786871, 0.94341754, 0.96548269, 0.98341143 }, { 0.95794101, 0.87263324, 0.8802806, 0.71000638 } }, { { -0.0064390277, 0.051629953, -0.011423447, 0.032337826 }, { 0.055030538, 0.061305324, -0.016012659, 0.083766345 }, { 0.052467122, 0.018425134, -0.00054737782, 0.048038459 }, { 0.076436505, 0.016815709, -0.024174832, -0.00829119 }, { 0.057903371, 0.068822104, -0.0064003131, 0.00010695928 }, { 0.067104151, 0.067284611, 0.0074295447, 0.024215238 }, { 0.073380541, 0.01486405, 0.01523157, 0.012966612 }, { -0.0002536971, 0.010628632, 0.00045031869, 0.041891438 }, { 0.055922922, 0.0090823157, 0.011101162, 0.033807592 }, { -0.040264953, 0.022318628, -0.013682045, -0.016112502 }, { -0.034286564, 4.7089727e-05, -0.013030079, -0.012231424 }, { 0.027756308, 0.084041595, 0.018308393, 0.11564334 }, { 0.0026690817, 0.058149333, -0.013682964, 0.052975934 }, { -0.03852481, 0.063493354, 0.059460027, 0.047740976 }, { 0.026410264, -0.0073902435, 0.022353771, 0.012987341 }, { 0.035217135, -0.0023455309, -0.0055505614, 0.010102857 }, { 0.00075590283, 0.038624793, -0.0040614962, 0.070039437 }, { -0.02318411, 0.04527054, 0.013119286, 0.025335215 }, { 0.021268391, 0.044855911, 0.012622905, 0.04827088 }, { -0.0046678346, -0.01934799, 0.018393432, 0.09750434 }, { 0.12480373, 0.059151139, 0.055196092, 0.26701338 }, { -0.0096669036, 0.065624767, 0.016918517, 0.028425135 }, { 0.026488514, -0.0037618693, 0.0077028717, 0.041713399 }, { 0.018628451, 0.033145064, 0.029067918, -0.000924258 } }, { { -0.043525781, 0.028119778, -0.011653105, -0.020930158 }, { -0.028099186, 0.017594088, -0.099226445, 0.10408808 }, { 0.11750066, -0.0010629746, 0.018381448, 0.096538552 }, { 0.0010069446, 0.013799541, 0.1325137, 0.020820734 }, { -0.053571928, -0.0066793785, 0.14596488, -0.03272949 }, { 0.028507895, 0.015474376, -0.025411653, 0.037264272 }, { 0.033698911, 0.018088387, 0.0038898537, 0.03163178 }, { 0.0057766828, 0.015879322, 0.012557033, 0.071771631 }, { -0.0044521866, 0.0083963511, -0.0020426175, 0.023784146 }, { -0.011508765, 0.0075020051, 0.0018808294, 0.040843424 }, { 0.0085150894, 0.0056891711, 0.010134672, 0.046224768 }, { 0.040825446, 0.10099754, 0.021853299, 0.024507528 }, { -0.0055958303, -0.0060958, 0.1115321, -0.021701014 }, { 0.010487817, -0.010033143, -0.031203025, 0.054265436 }, { 0.0040500672, 0.0053935875, 0.018233022, 0.018797311 }, { 0.064057639, 0.014318185, 0.0199119, 0.014366235 }, { 0.02411682, 0.045454692, 0.0030084434, 0.019464939 }, { 0.012500289, 0.027734846, 0.0025097372, 0.047343669 }, { 0.037625829, -0.00064472688, 0.0557556, 0.04785655 }, { 0.0020433437, 0.019929208, 0.087936103, -0.036738471 }, { 0.020811556, 0.0915387, 0.055445303, -0.065132763 }, { 0.03911814, 0.043721622, 0.0074336204, -0.031370424 }, { 0.014072509, -0.014795458, 0.010517063, 0.022409628 }, { -0.0054107234, 0.055313602, 0.053556404, 0.048574319 } } }, { { { 3.4224197, 3.3162336, 3.1136621, 3.3189801 }, { 4.0715355, 3.5614196, 4.1797877, 4.0959601 }, { 4.3979407, 4.1858272, 4.3116447, 4.5467451 }, { 4.4920032, 4.0716439, 4.6107962, 4.5268016 }, { 5.6570832, 4.9036495, 4.7373547, 4.7259419 }, { 3.3277827, 3.6015237, 4.226646, 3.7939772 }, { 3.4893058, 3.3260638, 3.0626103, 3.1798705 }, { 3.6423735, 4.1092281, 3.3264203, 3.7325301 }, { 3.4756581, 3.2550256, 3.224671, 3.4093307 }, { 3.8511362, 3.4821381, 4.3232597, 3.7357164 }, { 3.6688024, 4.0797971, 3.4140927, 3.6881261 }, { 4.5298469, 4.7472506, 4.4046473, 4.7279944 }, { 4.1614448, 4.1242955, 4.6741969, 5.0037875 }, { 4.3148703, 4.3815566, 4.1976536, 3.9032858 }, { 3.2640506, 3.3214728, 2.9463564, 3.3562068 }, { 3.6729325, 3.9218642, 3.4550701, 3.4833871 }, { 3.435975, 3.3079446, 3.3432341, 3.3632985 }, { 3.8404619, 3.4716915, 3.858149, 3.8677391 }, { 3.3181827, 3.8403872, 4.0363918, 3.9604287 }, { 5.0916792, 5.2773748, 4.5404255, 4.377031 }, { 4.6514614, 4.7569957, 4.1233238, 4.4022582 }, { 3.6884833, 3.6283543, 4.1874612, 4.2963913 }, { 3.456705, 3.6250566, 3.5292789, 3.1420033 }, { 3.5986317, 4.0596074, 4.0696874, 4.5327067 } }, { { -0.12592901, -0.14780788, -0.11051274, -0.18767653 }, { -0.020435093, 0.0055221209, -0.021183195, -0.15159792 }, { 0.022498629, -0.025100789, -0.30939177, 0.016420202 }, { 0.21296442, -0.042976575, 0.082118132, 0.14574735 }, { -0.13608022, 0.16141834, -0.015091164, 0.044951541 }, { -0.08235774, -0.10333151, 0.089785432, -0.036620639 }, { -0.17664465, -0.015842477, -0.083075331, -0.15660828 }, { -0.11292423, -0.072894494, -0.068901923, -0.2283674 }, { -0.19063437, -0.071954393, 0.091375283, -0.26993547 }, { 0.042798331, -0.06495575, 0.050221766, 0.024602586 }, { -0.026228614, 0.0049810367, 0.046584088, -0.13067577 }, { 0.072779737, -0.023369437, -0.030275791, 0.19591126 }, { -0.018649072, 0.029208952, 0.012033439, 0.00094798196 }, { -0.094599446, 0.0070746366, -0.0007115864, -0.040175552 }, { -0.027599009, -0.068747365, 0.19480498, -0.19423733 }, { -0.076671551, 0.0075475135, 0.019853903, -0.012984601 }, { 0.064371855, -0.24044027, -0.043765356, 0.0016424127 }, { -0.076744435, 0.035881398, 0.12967612, 0.081825243 }, { -0.15224256, 0.032665115, -0.027927205, 0.076091133 }, { -0.0057973613, -0.14914213, -0.047678749, -0.037214457 }, { 0.10060085, -0.099197666, -0.22704457, -0.0020812401 }, { -0.070664558, -0.13179176, -0.014217065, -0.030410253 }, { -0.12286487, -0.046623366, -0.10695394, -0.0081383175 }, { -0.14561788, 0.02765909, 0.10439783, 0.033139041 } }, { { 0.0063171031, -0.0047223477, -0.056312039, -0.065065766 }, { -0.0059575982, -0.062348475, 0.069540315, -0.090331962 }, { 0.10218203, 0.050383376, -0.0089914697, -0.037837343 }, { -0.0037657879, 0.18278082, 0.079014627, -0.052587294 }, { -0.33929282, 0.018522098, 0.0078923893, 0.042545349 }, { 0.027294929, -0.086490439, -0.0057363347, -0.035932082 }, { -0.061716003, -0.14470599, 0.033117786, -0.08112808 }, { 0.16414856, 0.082471596, -0.058497326, 0.050552718 }, { -0.07627083, -0.0064181717, -0.031179581, -0.075705068 }, { -0.057808009, -0.00074561624, -0.23990956, 0.018671772 }, { 0.1677602, 0.10757253, 0.028015134, -0.23923178 }, { 0.078827365, 0.068682485, 0.056277532, -0.069749241 }, { 0.079502977, 0.05526585, 0.0089767144, -0.15319341 }, { -0.038594242, -0.055488998, -0.043132461, 0.054313031 }, { 0.12890592, -0.082639555, 0.22520491, -0.026781096 }, { -0.071292391, 0.064592881, -0.050368563, -0.072488866 }, { 0.092998671, 0.12152394, 0.033318795, -0.039691417 }, { -0.0049706273, -0.0014175115, -0.11634604, 0.15219284 }, { -0.012414906, 0.035583927, -0.072463074, -0.058394705 }, { -0.071558898, -0.00093653835, 0.013149622, 0.01495775 }, { -0.057103279, 0.013702583, -0.020242751, 0.04649072 }, { -0.083398977, -0.20123674, 0.062758815, -0.043671819 }, { 0.084479675, 0.17868517, -0.021185269, 0.15711776 }, { 0.11862504, 0.079985297, 0.063556911, 0.14639069 } } }, { { { 0.48018566, 0.17712962, 0.45065949, 0.76214707 }, { 0.37788335, 0.385421, 0.24766167, 0.3647243 }, { 0.45095873, 0.2634498, 0.37824131, 0.10713483 }, { 0.18808611, 0.27852978, 0.23671202, 0.23174978 }, { 0.39404781, -0.7399413, 0.28511918, 0.026007027 }, { 0.46587668, 0.46802177, 0.36697974, 0.23706778 }, { 0.48925391, 0.42086488, 0.49570155, 0.45137287 }, { 0.30655255, 0.35196398, 0.23019387, 0.50586011 }, { 0.45798975, 0.34137244, 0.33289763, 0.54218519 }, { 0.42271216, 0.38700914, 0.48791862, 0.15025833 }, { 0.7282781, 0.37956244, 0.25156645, 0.51632504 }, { 0.084933462, 0.15576738, 0.16469359, 0.29684651 }, { 0.34570877, 0.34912791, 0.26663435, 0.11188061 }, { 0.48552914, 0.19012867, 0.12677402, 0.1234341 }, { 0.2190939, 0.41431469, 0.64823269, 0.51846746 }, { 0.49289149, 0.29829354, 0.29090992, 0.36465152 }, { 0.50568056, 0.64150077, 0.40217634, 0.53523743 }, { 0.24945735, 0.47058801, 0.29099852, 0.25452114 }, { 0.49039753, 0.26327736, 0.39431507, 0.50632023 }, { 0.19678915, 0.031547614, 0.22295107, 0.26300048 }, { 0.12409997, 0.11506147, 0.19327618, 0.2174585 }, { 0.15319333, 0.39177705, 0.38498586, 0.25972804 }, { 0.69027161, 0.37279682, 0.31143504, 0.23440833 }, { 0.39682066, 0.3156927, 0.36369313, 0.14308402 } }, { { 0.15030994, 0.15410005, 0.0072554408, -0.22242826 }, { -0.032421729, 0.22531436, 0.22185899, -0.022703209 }, { 0.070341052, 0.30237173, 0.047916387, 0.03629681 }, { -0.024283222, 0.075614195, 0.013940033, -0.016841468 }, { 0.077729482, 0.19455394, -0.02162282, -0.018761003 }, { -0.22986895, 0.18914992, 0.14483608, 0.11173921 }, { 0.14132894, -0.0081864768, -0.11405791, 0.031777789 }, { 0.38775389, 0.0085565642, -0.057167843, 0.09784167 }, { 0.079102739, 0.030530894, 0.041954967, 0.02957611 }, { 0.076915126, 0.18656729, 0.044218872, 0.22478833 }, { 0.017173879, 0.11961351, -0.085099523, 0.22720323 }, { 0.030466202, 0.095221887, -0.042982583, -0.069264747 }, { 0.041170442, -0.090598444, -0.021082598, -0.028016784 }, { -0.082581617, -0.023712106, 0.32427665, 0.1010696 }, { 0.19197752, 0.10900527, -0.0053794951, 0.068553764 }, { 0.18674269, 0.028895321, -0.053421028, 0.063918058 }, { 0.044090722, -0.054247791, 0.05585954, -0.13406746 }, { 0.08358642, -0.032301886, 0.010371619, 0.099505528 }, { 0.16467816, 0.044994571, -0.0045949279, 0.0626774 }, { 0.12942209, 0.092097891, 0.019866495, 0.10340014 }, { 0.037094903, 0.13829877, 0.15116473, -0.048632499 }, { 0.10749044, 0.14329542, -0.061272024, -0.1536028 }, { 0.097716907, 0.044246181, 0.056664419, 0.15804873 }, { 0.031819999, 0.10132976, 0.079198524, 0.017871462 } }, { { 0.056219172, 0.08683492, -0.061488015, 0.065746152 }, { 0.088983664, 0.19773741, -0.096766599, 0.16352101 }, { -0.0097043787, -0.040925999, 0.097458334, 0.032319634 }, { -0.024873518, 0.057873123, -0.0059256291, -0.057498398 }, { -0.13355098, 0.39190863, 0.017449142, -0.0076009344 }, { 0.10319658, 0.22069551, -0.098795717, 0.10603434 }, { 0.090765308, 0.13803326, -0.070647945, 0.14557561 }, { -0.068457348, 0.058955208, -0.050501105, 0.02914144 }, { 0.10363866, 0.060231993, 0.027681685, 0.079659088 }, { 0.01269983, 0.11977996, -0.049648315, 0.089882363 }, { -0.072877286, 0.019348792, 0.13977764, 0.055396044 }, { 0.028834456, -0.1084196, -0.0043985215, -0.072640844 }, { -0.040232522, 0.051835989, -0.02198193, 0.016421295 }, { -0.087848469, -0.04621504, 0.099259188, -0.0025909067 }, { 0.3000131, 0.10526775, 0.016890366, 0.12892588 }, { -0.021028821, -0.024429075, 0.088067677, -0.084594075 }, { 0.086861805, -0.045902006, 0.0058222123, -0.0075466204 }, { 0.14411905, 0.036488937, 0.05091815, 0.16385101 }, { 0.1576814, 0.043890956, -0.064244298, -0.087234754 }, { -0.071100004, 0.16782304, -0.10860149, -0.1601076 }, { 0.032634641, -0.0025068263, -0.093802703, -0.076176546 }, { 0.1121451, 0.15584236, 0.070074778, 0.083736091 }, { 0.16981897, -0.078106227, 0.12480295, -0.0056807652 }, { -0.20300117, -0.017467249, 0.035504155, 0.056546123 } } } }, { { { { 0.014994926, 0.3118252, 0.12179235, -0.2013765 }, { -0.2622824, 0.28086607, 0.018805882, 0.72058929 }, { -0.0081002049, -0.28176506, -0.592214, -0.15032918 }, { 0.18913426, -0.24000825, 0.0020279072, -0.54749128 }, { 0.010237954, 0.76905205, 0.80173664, -0.016024595 }, { -0.53448318, 0.31204229, -0.16183732, 0.76857439 }, { -0.57639279, -0.63719194, -0.71354849, 0.56346054 }, { 0.49443258, 0.15067585, 0.31864726, -0.30570933 }, { -0.20756322, 0.2544828, -0.005298245, 0.0073796841 }, { -0.61822672, 0.21508574, 0.6362534, 0.30433278 }, { -0.0050327191, -0.278054, -0.3460806, 0.29967778 }, { 0.33983098, -0.11715664, -0.21761592, -0.068273894 }, { 0.5550354, 0.44369709, 0.64019993, -0.026032291 }, { -0.72587268, -0.33528197, -0.33592445, 0.53027141 }, { -0.47623191, -0.61767624, -0.61525655, 0.37823554 }, { 0.82869964, 0.219401, -0.018181789, -0.56937955 }, { -0.051792934, 0.3461701, 0.20915925, 0.078166496 }, { -0.26705611, 0.14439061, 0.0055054648, 0.463243 }, { -0.0019649711, -0.34119962, -0.29306531, -0.040223173 }, { 0.29285811, -0.32824753, -0.24768208, -0.29676955 }, { 0.87604898, 0.25374435, 0.2341931, -0.77851996 }, { -0.80404697, 0.011122158, 0.18899178, 0.55592668 }, { -0.78397618, -0.53690406, -0.59931185, 0.62348293 }, { 0.54613799, 0.080819658, 0.12590931, -0.60614071 } }, { { -0.12307869, -0.20242175, 0.21530167, -0.15608553 }, { 0.00052208688, 0.09998365, -0.067550225, -0.14009319 }, { 0.12621699, -0.089024022, 0.022656689, 0.18947331 }, { 0.34838897, -0.04936051, 0.25527451, -0.18942819 }, { 0.013210249, -0.043957685, -0.19088103, -0.034189573 }, { -0.0027790938, -0.026595097, 0.087083287, -0.12513839 }, { -0.038231564, 0.013328425, -0.0091503894, -0.005743873 }, { 0.17205702, -0.14956835, -0.0088915291, 0.18720588 }, { -0.049670195, 0.39532325, 0.080260299, 0.01811245 }, { 0.043555003, -0.30289197, -0.50878196, 0.27306166 }, { 0.02555972, -0.0068359476, 0.061097702, -0.43822038 }, { -0.10926471, 0.1870906, 0.12419548, 0.1245213 }, { -0.012443149, 0.040036941, 0.18601483, 0.02310445 }, { -0.10442982, 0.057455632, 0.13475314, -0.0019859122 }, { -0.068181593, -0.0033655904, 0.01922998, -0.020393828 }, { -0.10660626, 0.0020812455, 0.081209707, 0.077131932 }, { 0.088733212, -0.10430986, 0.45554817, -0.17113078 }, { 0.0046831409, 0.13247549, -0.1077727, 0.15382275 }, { 0.022346595, 0.022924261, -0.35016323, 0.2437608 }, { 0.029795657, 0.23046877, -0.020493651, -0.33214749 }, { -0.016101582, 0.042296203, 0.046779444, 0.037412394 }, { -0.02214903, -0.025218605, 0.14797485, -0.051723623 }, { 0.021321783, 0.010405115, 0.0075476201, 0.0082410917 }, { 0.040559796, 0.027927916, -0.012812736, -0.0096642379 } }, { { -0.055647079, 0.017595207, 0.34495838, -0.03055759 }, { -0.058415094, 0.027416036, 0.18568916, 0.13044498 }, { 0.01482217, -0.17300703, 0.027540135, -0.2744944 }, { 0.25558424, -0.15324455, -0.29751197, -0.11422984 }, { -0.068936732, -0.11425403, 0.094767025, -0.0020892558 }, { 0.040887892, 0.031622148, -0.095292456, -0.02460001 }, { -0.0026237665, 0.017734103, 0.01213911, 0.0056586962 }, { -0.052138375, 0.052245567, 0.04608449, -0.043004468 }, { -0.17693366, 0.0021023738, 0.13167397, -0.14062006 }, { -0.20900333, 0.0057695127, 0.13057243, 0.046715668 }, { -0.020569928, -0.08439655, -0.09683347, 0.038139385 }, { 0.18196242, 0.44461908, -0.11388512, -0.12413082 }, { 0.072801844, -0.0017236427, -0.0026756083, 0.049805114 }, { -0.092195952, -0.0076195172, -0.22763849, -0.11320887 }, { 0.016234922, 0.007258942, 0.078535592, -0.084829275 }, { -0.15320003, 0.057490618, -0.16065455, -0.17063675 }, { -0.012856124, 0.024818957, 0.097529739, 0.11569844 }, { -0.11141243, 0.26677735, 0.1319403, -0.15699502 }, { -0.021128161, -0.12370585, 0.056198856, -0.1836225 }, { -0.01871806, 0.025525037, 0.063822152, 0.066517944 }, { -0.013759301, 0.11401068, -0.04701374, -0.021321516 }, { 0.032714649, -3.161284e-06, 0.026930697, 0.00019593482 }, { 0.10575127, 0.016956425, 0.016873291, 0.0049304377 }, { -0.11938883, 0.31242334, 0.29347156, -0.19514533 } } }, { { { -0.17374661, -0.028781395, -0.25993234, 0.27242277 }, { -0.13675759, -0.62291002, -0.80742781, 0.54260546 }, { 0.16876581, -0.052588487, 0.22415557, -0.59669887 }, { 0.1769234, 0.64210979, 0.81157479, -0.2718564 }, { -0.99873125, -0.013258174, 0.58939675, 0.99930085 }, { -0.30883355, -0.71116337, -0.76218623, 0.096388818 }, { 0.65749012, -0.54533843, -0.57508599, -0.70359398 }, { -0.27406769, 0.61006308, 0.1873512, 0.2563151 }, { -0.78453523, -0.13585943, -0.048534939, 0.02085237 }, { 0.40938527, -0.76981396, -0.42506866, 0.22362984 }, { 0.29003079, -0.20624421, 0.1151133, -0.50558933 }, { 0.0070051806, 0.20763719, 0.59485798, -0.61562639 }, { -0.4371111, 0.48314196, 0.72981069, 0.99889301 }, { 0.58257878, -0.8603979, -0.94188892, -0.83140889 }, { 0.71858167, -0.49534538, -0.63421799, -0.84488463 }, { 0.016158248, 0.65330502, 0.82883727, -0.127372 }, { -0.50292264, -0.14848746, -0.20836533, 0.2471481 }, { -0.15815031, -0.63472031, -0.79826416, 0.15325573 }, { -0.010424343, -0.022843894, 0.099730136, -0.26040744 }, { 0.15069433, 0.31188588, 0.63836617, -0.25234477 }, { -0.36946506, 0.92093529, 0.96548808, 0.62354203 }, { -0.57070465, -0.99847512, -0.47855156, -0.079970605 }, { 0.077467525, -0.71134336, -0.67172579, -0.66364974 }, { -0.27299386, 0.89512951, 0.61598356, 0.49577277 } }, { { 0.070458859, -0.28774455, 0.21287043, -0.094689772 }, { 0.0029548085, -0.31404605, -0.039280892, -0.3652277 }, { -0.033729607, 0.041215792, 0.065844258, -0.21509418 }, { 0.39270582, 0.067526811, 0.15655351, 0.053346856 }, { 0.052704394, -0.087801294, 0.18655104, 0.056114808 }, { -0.074582751, -0.055177669, -0.22165519, 0.13272162 }, { -0.027850171, 0.0029849066, -0.0062314784, -0.010484316 }, { 0.20753796, -0.0087111988, -0.13875075, -0.06137521 }, { 0.089744421, 0.07271039, 0.099417029, -0.22157272 }, { -0.013209094, 0.048633419, -0.26528065, -0.15253703 }, { 0.052922007, 0.24859103, 0.14406684, 0.13857649 }, { 0.00096142813, 0.32643367, 0.17939549, -0.39761314 }, { 0.013505803, -0.036986517, -0.12729111, 0.15459921 }, { -0.00049722057, -0.047063275, -0.0018666598, 0.1067114 }, { -0.074221027, -0.00927958, -0.029535811, -0.024240068 }, { -0.12387933, 0.06626829, 0.16422781, 0.077740779 }, { 0.14560404, -0.082132455, 0.027268021, 0.18857832 }, { 0.10470732, -0.29519533, -0.23666419, 0.10917064 }, { 0.042550279, 0.02436036, -0.31865644, -0.024987356 }, { -0.030434576, 0.082115299, 0.17770796, 0.020944092 }, { -0.17365377, 0.13807361, 0.12476029, 0.072738061 }, { -0.11503962, -0.04022554, 0.028018434, -0.070211356 }, { -0.043677907, 0.0053361863, 0.0039019898, 0.0027489647 }, { 0.27060899, -0.0016552279, 0.14166067, -0.25461265 } }, { { 0.014703402, 0.094752279, -0.32162049, 0.082335322 }, { -0.31539882, 0.44394592, 0.44316202, -0.031456167 }, { -0.024148679, 0.082370612, -0.0031744796, 0.098610537 }, { 0.46130367, -0.19989896, -0.56118891, 0.11979937 }, { 0.11784636, 0.079971516, -0.16977121, 0.014922099 }, { 0.018367216, -0.076519762, 0.13801492, 0.039682415 }, { -0.0027614728, 0.0010389006, -0.023126227, 0.0027068473 }, { 0.22249856, -0.071302328, 0.23721977, 0.10734273 }, { 0.41478408, -0.36611101, 0.18031261, -0.11176768 }, { 0.15800457, 0.23829725, -0.0016193556, 0.2112867 }, { -0.14793833, -0.15378785, 0.0082778301, 0.27105519 }, { -0.064743588, 0.44794816, -0.12599819, 0.4310022 }, { 0.092725214, 0.033947737, 0.19969884, 0.0072363359 }, { -0.074190657, 0.005985921, 0.300818, -0.090919095 }, { 0.024238118, -0.010955859, -0.068086841, -0.021137349 }, { 0.12196721, -0.19977338, -0.64428422, -0.30808722 }, { 0.46567096, -0.042072501, -0.1778338, 0.34294059 }, { -0.32528695, 0.25699981, 0.49346557, -0.20743316 }, { 0.10422458, 0.049488574, 0.49098274, -0.34871439 }, { 0.16431875, -0.050748897, -0.18464312, -0.61695364 }, { -0.1753479, 0.033238479, -0.046267845, -0.012339883 }, { -0.16098841, 0.080519992, -0.11793031, 0.036790025 }, { 0.017193144, -0.0029212372, -0.0044153187, -0.0057094316 }, { 0.23481771, -0.1556448, -0.18775429, -0.013697353 } } }, { { { 0.98467622, 0.94970347, 0.95791534, 0.9408684 }, { 0.95525144, 0.73013516, 0.58966657, 0.43166004 }, { 0.98562289, 0.95804118, 0.77397471, 0.78825859 }, { 0.96588112, 0.72807352, 0.58424502, 0.79142113 }, { -0.049305848, 0.63904864, 0.099145551, -0.03377918 }, { 0.78673348, 0.62998117, 0.62680207, 0.63245759 }, { 0.48526085, 0.544603, 0.40015579, 0.43297544 }, { 0.82487776, 0.77789448, 0.92917353, 0.91697567 }, { 0.58431326, 0.95748667, 0.99880743, 0.99975533 }, { 0.67096902, 0.60093643, 0.64381538, 0.92594344 }, { 0.95700408, 0.93816272, 0.93111608, 0.80905665 }, { 0.94046044, 0.97116483, 0.77381347, 0.78507504 }, { 0.7077214, 0.7547892, 0.23983411, -0.039180128 }, { 0.3656649, 0.38379871, -0.00015338393, 0.16604667 }, { 0.50679735, 0.6108265, 0.46821675, 0.37829596 }, { 0.55946029, 0.72460731, 0.55919425, 0.81214734 }, { 0.86277825, 0.92634645, 0.95542467, 0.96581976 }, { 0.95061533, 0.75913205, 0.60228234, 0.87287949 }, { 0.99994373, 0.93971324, 0.95087677, 0.96466059 }, { 0.9442062, 0.89161694, 0.72879505, 0.92100486 }, { 0.30989313, 0.29579046, 0.11395771, 0.071428407 }, { 0.16674735, -0.054071458, 0.85747916, 0.82737551 }, { 0.61593841, 0.45356879, 0.43544204, 0.41332561 }, { 0.79196443, 0.43841915, 0.77763172, 0.62193473 } }, { { 0.028699614, 0.071974788, -0.028868668, 0.030119772 }, { -0.16988515, -0.35713152, 0.36877151, 0.37172103 }, { 0.024472009, 0.10373643, 0.052160621, -0.12998364 }, { 0.051999909, -0.1688679, 0.05813266, -0.11063347 }, { 0.026373007, 0.067310776, 0.34433164, 0.0017481699 }, { -0.017659611, -0.10215276, -0.23736187, 0.12678732 }, { -0.0019097928, 0.02067204, -0.030447136, -0.0093192388 }, { 0.10615435, 0.11124023, 0.04473958, 0.14369936 }, { 0.14791062, -0.034502091, 0.041456555, 0.06737059 }, { 0.22389399, 0.2668048, 0.25742349, 0.03724758 }, { 0.0046009946, 0.066632032, 0.097957775, 0.22969631 }, { 0.043253167, -0.013638494, 0.071328387, -0.19249903 }, { -0.023561087, 0.011490741, 0.19824644, -0.04133258 }, { -0.057507532, -0.039265903, 0.060469313, 0.37300659 }, { 0.027051207, -0.0086784396, -0.0055877341, -0.0315352 }, { 0.15724931, 0.0099485187, 0.22462997, 0.14112999 }, { 0.13909905, 0.026199511, -0.12430815, -0.076900423 }, { -0.022327596, -0.1975812, 0.49862652, -0.096026553 }, { 0.076782007, 0.041598482, 0.0033451155, 0.039947963 }, { 0.005353589, 0.070993946, 0.0068174778, -0.17805261 }, { -0.059912765, -0.17027417, -0.060069718, 0.1561139 }, { 0.017122435, 0.048532637, -0.05315926, 0.066962855 }, { 0.058014377, 0.021874362, 0.017248667, -0.0069413843 }, { 0.099274028, 0.040622241, 0.040435904, 0.14191123 } }, { { -0.13453832, 0.071519908, -0.1597656, -0.030758273 }, { -0.13511715, 0.32373425, 0.35851035, -0.18685481 }, { 0.021440457, 0.034442875, 0.14324368, 0.15754565 }, { -0.061440371, 0.16837735, 0.47887644, -0.036265812 }, { 0.55060811, 0.14095672, 0.13077418, 0.25515565 }, { -0.084599968, -0.084002143, 0.1542308, 0.044223437 }, { 0.0017727822, 0.025149715, -0.025479364, -0.0023658361 }, { 0.1619123, 0.069159159, -0.016343512, 0.026108175 }, { 0.3296525, 0.029456656, 0.039715069, 0.015958704 }, { -0.093419591, 0.37051381, -0.063182977, -0.017764112 }, { 0.11962535, 0.062511772, -0.070445145, 0.27768911 }, { 0.07458833, -0.16218828, 0.064111239, 0.43889373 }, { -0.0326486, -0.03666828, -0.17597139, 0.34213144 }, { 0.061334301, -0.0099525239, 0.21497301, 0.0074569296 }, { -0.016749445, 0.00054557189, 0.040331287, 0.066200794 }, { 0.20620866, 0.25268529, 0.46594276, 0.059651923 }, { 0.15170896, 0.041438057, 0.021708506, -0.15049245 }, { -0.14317538, 0.13548996, 0.37297491, 0.13718874 }, { 0.053339004, 0.015014013, -0.10418356, -0.13598877 }, { -0.02227412, 0.045548464, 0.21534467, -0.23828118 }, { -0.055326885, 0.11851609, 0.28938409, 0.041373996 }, { -0.1219532, 0.57338554, -0.094571555, 0.025008596 }, { 0.070380772, 0.016993506, 0.018073937, -0.015404818 }, { 0.17033841, 0.12449473, 0.10847869, -0.11141982 } } }, { { { 4.409738, 4.5071479, 5.4761817, 5.3214091 }, { 5.3741435, 4.6270256, 5.4786338, 5.323679 }, { 4.305776, 4.4890731, 4.6894257, 4.6068436 }, { 5.4930574, 4.9116386, 5.4097636, 4.9225404 }, { 5.1861828, 5.5144226, 5.1307797, 5.0804212 }, { 6.1194597, 6.0655136, 5.7369562, 6.1076578 }, { 6.9549598, 6.9281578, 6.9549598, 6.9549598 }, { 4.5030565, 4.5849566, 4.4830953, 4.4904323 }, { 5.3629211, 5.5524848, 4.5719135, 4.9103175 }, { 4.8906163, 5.3972226, 4.8806206, 5.1834202 }, { 4.5047396, 4.5984947, 4.7039612, 4.3422371 }, { 4.5956963, 5.6294962, 4.46025, 4.4827131 }, { 5.8454206, 6.000743, 5.4594428, 4.9952614 }, { 6.09642, 6.3979283, 4.9784963, 5.6878449 }, { 6.9549598, 6.9752898, 6.9549598, 6.9549598 }, { 6.2053562, 4.9984547, 5.3887395, 4.6221036 }, { 4.5265196, 4.3684629, 5.5819288, 5.4957366 }, { 5.2220057, 4.6118907, 5.5046208, 4.9190037 }, { 4.3408178, 4.4980303, 5.4937404, 5.6154153 }, { 4.4802186, 4.4666194, 4.8546878, 5.1764252 }, { 5.7384024, 5.9048089, 5.4636107, 5.0807017 }, { 5.1013817, 5.2237041, 6.0338955, 5.8869417 }, { 6.9414339, 6.9549598, 6.9549598, 6.9549598 }, { 4.3368412, 4.9692663, 4.7090567, 4.9023075 } }, { { 0.0093525884, -0.33796029, -0.4366682, -0.18161326 }, { -0.34446047, 0.10854359, -0.61563912, -0.16514117 }, { 0.055849315, 0.093045585, 0.36722184, 0.085665647 }, { -0.21881508, -0.036846235, -0.25226403, -0.012790033 }, { -0.14697546, -0.026656628, 0.2559775, 0.026279081 }, { 0.073189287, -0.074472165, -0.15439557, 0.020907645 }, { 0, -0.015078298, 0, 0 }, { 0.027540893, -0.30876053, -0.15680794, -0.18470107 }, { -0.072547269, -0.019227086, -0.26735769, -0.1362069 }, { 0.36907279, -0.28005156, 0.01966203, -0.10277819 }, { -0.26755862, 0.066747173, 0.60834173, -0.23356165 }, { -0.12357338, -0.41742338, 0.081840746, -0.14596222 }, { -0.068599762, -0.004402392, -0.17192993, -0.15797464 }, { -0.072923207, -0.02555551, -0.21075071, 0.047272919 }, { 0, 0.0115085, 0, 0 }, { 0.32527558, 0.066048741, -0.28639187, 0.45171914 }, { -0.158086, -0.049098981, -0.17226122, -0.50289857 }, { -0.39456648, 0.031970902, -0.74883626, 0.20536003 }, { 0.22864705, -0.0095988927, -0.1155595, -0.06240073 }, { 0.12336497, -0.34128076, 0.34341316, 0.083678547 }, { -0.032718317, 0.076359349, -0.30099369, -0.016865529 }, { -0.23491753, -0.17228011, -0.044893186, -0.057411459 }, { -0.0077848677, 0, 0, 0 }, { -0.18713605, -0.11612415, 0.30907006, 0.064707406 } }, { { -0.20768494, -0.15642062, -0.079474216, -0.020948121 }, { -0.18767308, -0.013722599, 0.15827086, -0.27421942 }, { -0.11484158, -0.29325715, 0.24426149, 0.34598577 }, { -0.095599056, 0.16784413, 0.23369965, 0.15036114 }, { 0.058496274, -0.064565923, -0.076598803, -0.11988702 }, { -0.03406356, -0.010863931, -0.036116475, 0.0077051595 }, { 0, -0.015078298, 0, 0 }, { -0.21271534, 0.31678528, 0.084310434, -0.039787477 }, { 0.057420352, -0.60894321, -0.14275706, -0.29178151 }, { -0.21477227, 0.091254596, -0.053659362, -0.13299553 }, { -0.24972574, 0.22261101, -0.59415755, -0.13299464 }, { -0.406027, 0.15018847, 0.33281927, 0.28006105 }, { -0.033198856, 0.013081228, 0.0098634494, -0.18858267 }, { -0.16914457, -0.014917022, -0.15618156, 0.038961385 }, { 0, 0.0115085, 0, 0 }, { 0.047340338, -0.052961301, 0.30193278, 0.38564757 }, { -0.2009302, -0.15247105, -0.32333852, 0.22878398 }, { -0.22934017, 0.022888443, 0.30911154, -0.12420416 }, { 0.21191356, -0.33281926, -0.13523708, -0.038546557 }, { 0.28507859, -0.012777666, 0.16285544, -0.12612215 }, { -0.057034227, 0.01719448, -0.037892291, -0.13064036 }, { -0.075888865, 0.041589292, 0.0089100653, -0.10775402 }, { 0.0075560462, 0, 0, 0 }, { -0.18120766, 0.16485298, 0.58949587, 0.072313493 } } }, { { { 0.60381773, 0.64633179, 0.92301353, 0.23720177 }, { 1.1128727, 0.42172315, 1.6605811, 0.22066721 }, { 0.55829912, 0.7107351, 0.47437673, 0.53646626 }, { 0.75684406, 0.65607146, 1.5264507, 0.12817954 }, { -0.25070514, 0.30263175, -0.21070678, -0.2264813 }, { -0.24745858, -0.26801252, 0.2750925, 0.055035565 }, { -0.018769156, -0.066023008, 0.10111114, 0.0089232736 }, { 0.41152465, 0.52508091, 0.4161358, 0.39058287 }, { 0.90919582, 1.2448772, 0.61547497, 0.51303689 }, { 0.2973136, 1.2348603, 0.24154398, 0.76087607 }, { 0.23369317, 0.68368068, 0.81024353, 0.35451079 }, { 0.69272073, 0.47014545, 0.61401877, 0.43768641 }, { -0.44449894, -0.10123077, -0.19173956, -0.15811184 }, { -0.089717, -0.068601549, -0.16704813, -0.29761406 }, { 0.0055968308, -0.089855929, -0.087150641, 0.2244144 }, { 0.38902787, 0.62620686, 1.3314901, 0.26038797 }, { 0.16776511, 0.32722251, 0.71914611, 0.53556119 }, { 0.63106992, 0.46256454, 1.785895, 0.17339911 }, { 0.72516261, 0.44941094, 0.81174974, 0.61247129 }, { 0.56877815, 0.20989179, 0.7607991, 0.017998645 }, { 0.016372087, 0.26062407, -0.32771461, -0.075930098 }, { -0.11957223, -0.22579003, -0.42587945, -0.0015549589 }, { 0.0049992009, 0.053511694, 0.00053268274, 0.022778575 }, { 0.19356675, 0.5564623, 0.74981777, 0.28733119 } }, { { 0.017029304, 0.22690356, 0.25927682, -0.048136042 }, { 0.52936856, -0.26082526, 0.12568074, -0.046727529 }, { 0.08949554, -0.019090555, 0.31477592, -0.067513409 }, { 0.056302335, -0.011819435, -0.063621104, 0.27092306 }, { 0.053971592, -0.17913246, -0.14991651, -0.044263405 }, { 0.29037749, -0.040498369, -0.33600753, 0.16250066 }, { -0.067102844, -0.17843768, 0.033172168, 0.13638573 }, { 0.057127881, -0.044468822, 0.33005778, 0.34775491 }, { -0.14300931, 0.022121077, -0.045281831, -0.065216583 }, { 0.084931489, 0.06688461, 0.15758114, -0.091330485 }, { -0.014274888, 0.29139103, 0.089163749, -0.18005467 }, { -0.2191522, -0.1333803, -0.31948964, -0.28536602 }, { 0.20298891, -0.0031882515, -0.15749696, -0.014977715 }, { -0.14016857, -0.17278064, 0.01369474, 0.10971499 }, { 0.018219806, 0.080447764, 0.0056022696, -0.043028475 }, { -0.076556403, -0.13038184, -0.23788273, 0.5849635 }, { 0.1038427, 0.18199702, 0.35294355, -0.0023601311 }, { 0.22294845, -0.37427713, 0.2907529, 0.26234219 }, { 0.40809306, 0.12982813, 0.42857338, 0.14064303 }, { 0.4265028, 0.18710053, 0.15310514, 0.067551813 }, { -0.18986488, -0.029676062, -0.087045959, -0.14788626 }, { -0.07865478, 0.011558295, -0.018262356, 0.38992629 }, { 0.22297641, 0.072192947, 0.064119712, 0.12862555 }, { -0.069262467, -0.14990585, 0.31342655, -0.15002022 } }, { { 0.25288162, -0.096551539, 0.051695506, 0.20925392 }, { 0.23093904, 0.096712594, 0.19826434, 0.32530694 }, { 0.14114785, 0.071010138, -0.17642029, 0.092260082 }, { 0.39001648, -0.17666595, 0.088397252, 0.1462816 }, { 0.12484597, 0.066920676, -0.16116194, 0.21758387 }, { 0.15625272, -0.00043631439, -0.07868976, -0.19261141 }, { -0.0142415, 0.06356153, 0.026276923, -0.024546668 }, { 0.097089221, 0.085426402, 0.11936115, 0.012042542 }, { 0.52509109, -0.22465399, -0.11490612, 0.023562122 }, { -0.12418278, 0.11985465, 0.087804943, 0.25283464 }, { 0.10716753, -0.036426901, 0.2469409, -0.095816257 }, { -0.095364501, 0.14001518, -0.068636804, -0.082487255 }, { 0.074490355, 0.25323233, 0.17863748, 0.12482145 }, { -0.019616587, -0.0053326518, 0.047558858, 0.066104462 }, { 0.12647102, 0.25712368, 0.12306783, -0.050252261 }, { -0.13375041, 0.17825067, 0.026649645, -0.33338076 }, { 0.16384463, -0.022241979, 0.17817325, 0.6808721 }, { 0.42075944, -0.024292721, -0.11323318, 0.45027063 }, { -0.023953485, 0.25719992, 0.28680108, 0.33600529 }, { 0.013445546, 0.22504275, 0.17408162, 0.52860686 }, { -0.098839039, -0.27017244, 0.10293505, -0.012472685 }, { 0.074267375, -0.0056418849, 0.17632358, 0.21754089 }, { 0.1491061, 0.017927571, -0.0217757, -0.0039381966 }, { 0.067239102, -0.74624136, 0.12992555, -0.058866581 } } } }, { { { { 0.1270204, 0.7650174, 0.55252173, 0.05956498 }, { -0.36870832, 0.31227245, 0.52167466, 0.4282174 }, { -0.036761861, -0.5477415, -0.76091563, -0.37583127 }, { 0.17129434, -0.14281209, -0.40463148, -0.56367877 }, { 0.07429238, 0.45420144, 0.41919765, 0.019225986 }, { -0.44125436, -0.05567539, 0.080551064, 0.54444995 }, { -0.36600455, -0.55359309, -0.3290331, 0.33946169 }, { 0.65253747, 0.015186649, 0.0665303, -0.64649501 }, { 0.05392469, 0.54355001, 0.7539307, -0.41089455 }, { -0.29264863, 0.49684721, 0.39184208, 0.47737193 }, { 0.10885354, -0.80803227, -0.7443769, -0.3736688 }, { 0.1939378, -0.079590275, -0.42241709, -0.75536039 }, { 0.44776697, 0.44884546, 0.427965, 0.3297221 }, { -0.34595785, 0.27723463, 0.12245317, 0.43884357 }, { 0.18467758, -0.55582608, -0.99421464, -0.0096027817 }, { 0.6672057, -0.038103784, -0.048616141, -0.68508055 }, { -0.016615937, 0.62001729, 0.50530563, -0.22211425 }, { -0.16823123, 0.31934529, 0.47092187, 0.4884373 }, { 0.03194189, -0.5624624, -0.44688229, 0.223814 }, { 0.17828041, -0.080017082, -0.44239439, -0.46726625 }, { 0.19895649, 0.82568772, 0.47859751, 0.064443297 }, { -0.47464217, 0.011895223, 0.01123465, -0.010697203 }, { -0.17670677, -0.66931423, -0.5814681, -0.01325001 }, { 0.65193874, -0.010713062, -0.007915928, -0.65520853 } }, { { -0.01027431, -0.0019056004, 0.0020213958, 0.0064495753 }, { 0.0058416688, 0.0051314639, 0.021497114, 0.005870592 }, { -0.00035518612, -0.00087553938, -0.0029318969, 0.0087577986 }, { -0.0048770476, -0.015949665, -0.034816051, -0.006104917 }, { 0.0015371362, -0.0012591621, 0.01241148, 0.00096621463 }, { 0.0032416133, 0.021025709, 0.0036344622, 0.0015436078 }, { -0.0093946276, 0.0046564763, 0.028177476, -0.01022744 }, { 0.00014675555, 0.030031482, -0.0092302407, -0.001999398 }, { -0.049980321, 0.024752279, 0.016684689, -0.0045230976 }, { 0.0067493834, 0.014071508, 0.0079316435, 0.034593704 }, { 0.01971715, -0.0037227013, -0.013430278, -0.024257585 }, { -0.004342319, 0.024001878, -0.013356442, -0.022792018 }, { -0.0051709665, -0.017029547, 0.040567567, 0.0052520812 }, { 0.0090399102, 0.0079604733, 0.00018765016, -0.0092868977 }, { -0.020304032, 0.0056590257, -0.0045373063, -0.018653318 }, { -9.9636934e-05, 0.002001886, 0.0046843544, 0.0055608043 }, { 0.0018025744, -0.0025962216, 0.0068285574, -0.014851062 }, { 0.00041645221, 0.0054738242, 0.0076769026, -0.013419208 }, { 0.0038347099, -0.0042555066, -0.0066470075, 0.0039146778 }, { -0.009084153, 0.024461537, 0.0034578066, -0.0054827001 }, { 0.0033463477, 0.0045594748, 0.00037604935, -0.01571513 }, { -0.012589588, 0.029678359, -0.019924871, -0.004708459 }, { -0.0002642682, -0.0051057336, -0.0042867302, -0.00041141781 }, { -0.00086487068, -0.0025170841, 0.0030062196, -0.0030385417 } }, { { -0.01027431, -0.0019056004, 0.0020213958, 0.0064495753 }, { 0.0058416688, 0.0051314639, 0.021497114, 0.005870592 }, { -0.00035518612, -0.00087553938, -0.0029318969, 0.0087577986 }, { -0.0048770476, -0.015949665, -0.034816051, -0.006104917 }, { 0.0015371362, -0.0012591621, 0.01241148, 0.00096621463 }, { 0.0032416133, 0.021025709, 0.0036344622, 0.0015436078 }, { -0.0093946276, 0.0046564763, 0.028177476, -0.01022744 }, { 0.00014675555, 0.030031482, -0.0092302407, -0.001999398 }, { -0.049980321, 0.024752279, 0.016684689, -0.0045230976 }, { 0.0067493834, 0.014071508, 0.0079316435, 0.034593704 }, { 0.01971715, -0.0037227013, -0.013430278, -0.024257585 }, { -0.004342319, 0.024001878, -0.013356442, -0.022792018 }, { -0.0051709665, -0.017029547, 0.040567567, 0.0052520812 }, { 0.0090399102, 0.0079604733, 0.00018765016, -0.0092868977 }, { -0.020304032, 0.0056590257, -0.0045373063, -0.018653318 }, { -9.9636934e-05, 0.002001886, 0.0046843544, 0.0055608043 }, { 0.0018025744, -0.0025962216, 0.0068285574, -0.014851062 }, { 0.00041645221, 0.0054738242, 0.0076769026, -0.013419208 }, { 0.0038347099, -0.0042555066, -0.0066470075, 0.0039146778 }, { -0.009084153, 0.024461537, 0.0034578066, -0.0054827001 }, { 0.0033463477, 0.0045594748, 0.00037604935, -0.01571513 }, { -0.012589588, 0.029678359, -0.019924871, -0.004708459 }, { -0.0002642682, -0.0051057336, -0.0042867302, -0.00041141781 }, { -0.00086487068, -0.0025170841, 0.0030062196, -0.0030385417 } } }, { { { -0.68772793, 0.19029367, -0.17427646, 0.60300616 }, { -0.29980532, -0.22397537, -0.4071009, 0.36277983 }, { 0.75628069, -0.13426242, 0.13645381, -0.74653491 }, { 0.14891408, -0.13497977, 0.36807879, -0.39814386 }, { -0.20608987, -0.076497863, -0.19510375, 0.34604256 }, { -0.02421123, -0.4588774, -0.64965351, 0.083039161 }, { 0.51918764, -0.30614677, -0.25791921, -0.40837612 }, { 0.028860181, 0.63152733, 0.5876224, -0.033139773 }, { -0.63418144, 0.046874151, 0.24431924, 0.71662556 }, { -0.29088451, -0.21455586, -0.73980807, 0.65038559 }, { 0.78663226, 0.00020858525, 0.40361403, -0.75720144 }, { 0.1998276, 0.54590973, 0.1773378, -0.35464319 }, { -0.40236144, 0.31362578, -0.34406026, 0.38120073 }, { -0.27845549, -0.46862161, -0.47141499, 0.095899189 }, { 0.6004921, 0.28051621, -0.011378178, -0.98141078 }, { 0.032724674, 0.66798127, 0.66430425, -0.05209965 }, { -0.59603974, -0.083198329, 0.34616224, 0.42082916 }, { -0.14262632, -0.21418442, -0.37504914, 0.32676687 }, { 0.58204273, 0.0067537174, -0.35923481, -0.40792038 }, { 0.15607366, 0.17215007, 0.34414936, -0.33566945 }, { -0.44862333, 0.004919013, 0.0076768115, 0.41897935 }, { -0.022062848, -0.39695079, -0.0062786656, 0.042925103 }, { 0.65953535, -0.15521993, 0.011867978, -0.57721165 }, { 0.031305912, 0.65627006, 0.66779002, -0.029815636 } }, { { 0.011457792, -0.011774949, -0.012205337, 0.0048139052 }, { -0.024024566, 0.018313023, -0.023210623, -0.0046351547 }, { 0.0039133571, 0.0046801024, -0.020590099, -0.0018568631 }, { -0.015369931, -0.0092621276, -0.026149742, 0.0010335971 }, { 0.032555144, -0.01336897, -0.022733265, -0.027997469 }, { -0.028161537, -0.00073877629, -0.023989631, 0.0055660453 }, { -0.012966193, 0.003944376, 0.025685982, -0.0017458044 }, { 0.00015626641, -0.009524206, 0.0083025026, -0.00049753811 }, { -0.02358661, 0.006370149, 0.00087066462, -0.00054248544 }, { -0.0024571244, -0.023218369, -0.010895303, -0.0095647684 }, { 0.0069970393, -0.00093403301, -0.0081922371, -0.00026359768 }, { 0.0065921354, 0.028846533, -0.045676337, 0.006070217 }, { 0.0045248423, -0.0084676847, 0.028756195, 0.020612871 }, { 0.0037691244, -0.0069385161, -0.00029501448, -0.0017839033 }, { -0.0048675353, -0.011930456, 0.0044251285, -0.00016323616 }, { -0.0012291164, -0.0019575288, 0.0078250029, -0.0011151155 }, { 0.00503333, -0.0094538968, 0.0092375183, 0.018207648 }, { 0.0080615812, -0.0073583459, -0.0166794, 0.016416158 }, { 0.002192959, -0.01153759, -0.0048668362, -0.0071123281 }, { -0.010116143, -0.010224552, 0.010897731, 0.00093792816 }, { 0.017199359, -0.0087516179, 0.0021169251, -0.020946959 }, { -0.01570063, 0.020087246, 0.014492818, -0.016014018 }, { 0.0023484072, 0.0015070243, -0.00045616273, -0.001211882 }, { 0.0018090492, -0.0012261901, 0.0012809284, 0.00096488905 } }, { { 0.011457792, -0.011774949, -0.012205337, 0.0048139052 }, { -0.024024566, 0.018313023, -0.023210623, -0.0046351547 }, { 0.0039133571, 0.0046801024, -0.020590099, -0.0018568631 }, { -0.015369931, -0.0092621276, -0.026149742, 0.0010335971 }, { 0.032555144, -0.01336897, -0.022733265, -0.027997469 }, { -0.028161537, -0.00073877629, -0.023989631, 0.0055660453 }, { -0.012966193, 0.003944376, 0.025685982, -0.0017458044 }, { 0.00015626641, -0.009524206, 0.0083025026, -0.00049753811 }, { -0.02358661, 0.006370149, 0.00087066462, -0.00054248544 }, { -0.0024571244, -0.023218369, -0.010895303, -0.0095647684 }, { 0.0069970393, -0.00093403301, -0.0081922371, -0.00026359768 }, { 0.0065921354, 0.028846533, -0.045676337, 0.006070217 }, { 0.0045248423, -0.0084676847, 0.028756195, 0.020612871 }, { 0.0037691244, -0.0069385161, -0.00029501448, -0.0017839033 }, { -0.0048675353, -0.011930456, 0.0044251285, -0.00016323616 }, { -0.0012291164, -0.0019575288, 0.0078250029, -0.0011151155 }, { 0.00503333, -0.0094538968, 0.0092375183, 0.018207648 }, { 0.0080615812, -0.0073583459, -0.0166794, 0.016416158 }, { 0.002192959, -0.01153759, -0.0048668362, -0.0071123281 }, { -0.010116143, -0.010224552, 0.010897731, 0.00093792816 }, { 0.017199359, -0.0087516179, 0.0021169251, -0.020946959 }, { -0.01570063, 0.020087246, 0.014492818, -0.016014018 }, { 0.0023484072, 0.0015070243, -0.00045616273, -0.001211882 }, { 0.0018090492, -0.0012261901, 0.0012809284, 0.00096488905 } } }, { { { 0.71476997, 0.61525336, 0.81507512, 0.79550964 }, { 0.87986984, 0.9232123, 0.74974956, 0.82765975 }, { 0.65321366, 0.82580437, 0.63434042, 0.54903231 }, { 0.97390084, 0.98050251, 0.83713283, 0.72370416 }, { 0.97570877, 0.88760866, 0.88668363, 0.9380218 }, { 0.89705541, 0.88675351, 0.75595095, 0.83467284 }, { 0.77232433, 0.77447327, 0.9084134, 0.84734569 }, { -0.75720667, -0.77520488, -0.80639546, -0.76219811 }, { 0.77130152, 0.83806694, 0.60983327, 0.56357207 }, { 0.91090229, 0.84089752, 0.54694041, 0.59085922 }, { 0.60775044, 0.58913818, 0.53197627, 0.53574024 }, { 0.96044628, 0.83405513, 0.88888419, 0.55105253 }, { 0.79850486, 0.83676557, 0.83574428, 0.86369517 }, { 0.89597751, 0.83876978, 0.87336884, 0.8934314 }, { 0.77801249, 0.78253947, 0.10680725, 0.19167855 }, { -0.74415432, -0.74320194, -0.74587957, -0.72660186 }, { 0.802783, 0.78016447, 0.79046691, 0.87952719 }, { 0.97537479, 0.92311625, 0.79848027, 0.80910594 }, { 0.8125306, 0.82679528, 0.81929639, 0.88516002 }, { 0.97152309, 0.98181547, 0.82815966, 0.81791703 }, { 0.87129411, 0.56410602, 0.87800085, 0.905706 }, { 0.87990229, 0.91776281, 0.99991718, 0.99902102 }, { 0.73060786, 0.72658464, 0.81348263, 0.81648708 }, { -0.75762512, -0.75445002, -0.74430762, -0.75485946 } }, { { 0.018332644, 0.0084005452, -0.0018937689, -0.0035491975 }, { 0.0016556654, 0.0049261013, -0.021796869, 0.0025973591 }, { -0.0019671758, 0.00051947074, 0.0071261223, 0.0056689139 }, { 0.00041901024, -0.0023903288, -0.0035639711, -0.0036673013 }, { 0.009963464, 0.00099195429, -0.0042516892, 0.0092605531 }, { 0.0034813664, 0.0028575465, -0.016343415, -0.0014475905 }, { 0.0053571039, 0.0051116063, 0.016171091, -0.00052744238 }, { 0.00013272575, -0.0095491849, 0.0070156475, 0.0017057538 }, { 0.028067438, -0.0086835729, -0.0087852674, 0.0035321054 }, { 0.0025007808, -0.0075654884, -0.012551417, -0.0068823899 }, { -0.00017607308, 0.002636122, -0.011272055, -0.010314896 }, { 0.010646599, 0.00042804331, 0.013900837, -0.01279076 }, { 0.0059898286, 0.012331371, -0.0073125296, 0.016248603 }, { 0.031579315, -0.0057840222, -0.00018304192, 0.005171422 }, { 0.010928513, 0.0092660887, 0.030404621, 0.0053167707 }, { -0.00014899672, -0.0035246494, 0.0075862845, -0.005861723 }, { 0.0067791918, 0.0021224495, -0.0071755505, -0.010370936 }, { 0.0015352958, -0.0025785166, -0.0092688001, 0.003966373 }, { 0.0036915074, -0.002306452, -0.005736452, -0.0033594125 }, { 0.0065128512, 0.006188005, 0.00088322638, -0.0016227066 }, { 0.0092720771, -0.0046684631, -7.3769604e-05, 0.013807013 }, { -0.0031421984, 0.010622679, 0.00041591214, 0.0032786075 }, { -0.0021421613, -0.0041675589, -0.0029529994, -0.00085350449 }, { -0.00069204344, -0.0010785124, 0.00097549628, 0.0025280456 } }, { { 0.018332644, 0.0084005452, -0.0018937689, -0.0035491975 }, { 0.0016556654, 0.0049261013, -0.021796869, 0.0025973591 }, { -0.0019671758, 0.00051947074, 0.0071261223, 0.0056689139 }, { 0.00041901024, -0.0023903288, -0.0035639711, -0.0036673013 }, { 0.009963464, 0.00099195429, -0.0042516892, 0.0092605531 }, { 0.0034813664, 0.0028575465, -0.016343415, -0.0014475905 }, { 0.0053571039, 0.0051116063, 0.016171091, -0.00052744238 }, { 0.00013272575, -0.0095491849, 0.0070156475, 0.0017057538 }, { 0.028067438, -0.0086835729, -0.0087852674, 0.0035321054 }, { 0.0025007808, -0.0075654884, -0.012551417, -0.0068823899 }, { -0.00017607308, 0.002636122, -0.011272055, -0.010314896 }, { 0.010646599, 0.00042804331, 0.013900837, -0.01279076 }, { 0.0059898286, 0.012331371, -0.0073125296, 0.016248603 }, { 0.031579315, -0.0057840222, -0.00018304192, 0.005171422 }, { 0.010928513, 0.0092660887, 0.030404621, 0.0053167707 }, { -0.00014899672, -0.0035246494, 0.0075862845, -0.005861723 }, { 0.0067791918, 0.0021224495, -0.0071755505, -0.010370936 }, { 0.0015352958, -0.0025785166, -0.0092688001, 0.003966373 }, { 0.0036915074, -0.002306452, -0.005736452, -0.0033594125 }, { 0.0065128512, 0.006188005, 0.00088322638, -0.0016227066 }, { 0.0092720771, -0.0046684631, -7.3769604e-05, 0.013807013 }, { -0.0031421984, 0.010622679, 0.00041591214, 0.0032786075 }, { -0.0021421613, -0.0041675589, -0.0029529994, -0.00085350449 }, { -0.00069204344, -0.0010785124, 0.00097549628, 0.0025280456 } } }, { { { 5.3792285, 5.1960477, 5.5112916, 5.6615254 }, { 5.0489877, 5.2428834, 5.1752035, 5.1109826 }, { 5.5205204, 5.7511938, 5.0202917, 4.9168865 }, { 4.9522523, 4.8880256, 5.1015936, 5.2858816 }, { 5.7256502, 5.7919759, 5.645241, 5.6035708 }, { 6.4076931, 6.4822111, 6.2642633, 6.3925959 }, { 6.9797014, 6.981436, 7.0028674, 6.9976464 }, { -0.03290957, -0.03290957, -0.03290957, -0.03290957 }, { 5.4977854, 5.7684965, 5.3463095, 4.8810492 }, { 4.9869047, 5.4896416, 4.9647805, 4.884877 }, { 5.3141219, 5.3357788, 4.7695434, 4.8709631 }, { 5.2056063, 5.407802, 5.2123857, 4.9428208 }, { 6.2188218, 6.17756, 6.2751008, 6.3672109 }, { 6.9105856, 6.7986798, 6.5712335, 6.5907061 }, { 6.9797014, 6.9797014, 5.6859993, 5.5642483 }, { -0.032764603, -0.032764603, -0.032764603, -0.032764603 }, { 5.7724142, 6.0929556, 5.99581, 5.9265164 }, { 4.9363192, 4.9823732, 5.1732995, 5.2475265 }, { 5.8365191, 5.9972902, 5.9778441, 5.9270668 }, { 4.8706768, 5.0194503, 5.155585, 5.2188041 }, { 6.1569904, 6.0563989, 6.0989699, 6.2139837 }, { 5.8727399, 5.8948086, 5.5734095, 5.5536103 }, { 6.9797014, 6.9797014, 6.9797014, 6.9797014 }, { -0.032766769, -0.032766769, -0.032766769, -0.032766769 } }, { { 0.0011802354, -0.006546101, -0.02103972, 0.0008654047 }, { -0.015460534, 0.017874544, 0.0029121134, 0.023511773 }, { -0.040909245, 0.011927691, 0.011991588, 0.01677931 }, { -0.015633544, -0.0042321141, 0.026623034, 0.0080414514 }, { 0.012614382, 0.0065080145, 0.035716738, -0.0080665814 }, { -0.0057849744, -0.017478461, -0.031219642, 0.00016446523 }, { 0, 0.00032235028, 0, 0 }, { 0, 0, 0, 0 }, { -0.068586697, -0.024228236, -0.012857221, -0.039493706 }, { -0.018078201, -0.015140979, 0.00072119173, -0.051249859 }, { -0.054228277, 0.0097895101, 0.0019832646, -0.011715411 }, { -0.042326208, -0.010160072, 0.037088052, -0.031848667 }, { 0.00067130897, -0.013966717, -0.017268559, -0.0074614576 }, { 0.070515961, 0.012848107, -0.0008396517, 0.0049006506 }, { 0, 0, -0.063014256, -0.0085124986 }, { 0, 0, 0, 0 }, { -0.040302299, 0.0048936307, 0.0064406394, 0.0034044871 }, { -0.010453589, 0.0035820836, -0.017384391, -0.038199947 }, { -0.044968611, -0.0088322127, 0.020303819, 0.0058131005 }, { -0.0056838535, 0.010211409, -0.010999927, -0.027621859 }, { 0.0064753811, -0.0059341242, -0.014902755, 0.0082868118 }, { -0.0013222735, 0.0028492181, -0.023523273, -0.02576271 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }, { { 0.0011802354, -0.006546101, -0.02103972, 0.00086540469 }, { -0.015460534, 0.017874544, 0.0029121134, 0.023511773 }, { -0.040909245, 0.011927691, 0.011991588, 0.01677931 }, { -0.015633544, -0.0042321141, 0.026623034, 0.0080414514 }, { 0.012614382, 0.0065080145, 0.035716738, -0.0080665814 }, { -0.0057849744, -0.017478461, -0.031219642, 0.00016446523 }, { 0, 0.00032235028, 0, 0 }, { 0, 0, 0, 0 }, { -0.068586697, -0.024228236, -0.012857221, -0.039493706 }, { -0.018078201, -0.015140979, 0.00072119173, -0.051249859 }, { -0.054228277, 0.0097895101, 0.0019832646, -0.011715411 }, { -0.042326208, -0.010160072, 0.037088052, -0.031848667 }, { 0.00067130897, -0.013966717, -0.017268559, -0.0074614576 }, { 0.070515961, 0.012848107, -0.0008396517, 0.0049006506 }, { 0, 0, -0.063014256, -0.0085124986 }, { 0, 0, 0, 0 }, { -0.040302299, 0.0048936307, 0.0064406394, 0.0034044871 }, { -0.010453589, 0.0035820836, -0.017384391, -0.038199947 }, { -0.044968611, -0.0088322127, 0.020303819, 0.0058131005 }, { -0.0056838535, 0.010211409, -0.010999927, -0.027621859 }, { 0.0064753811, -0.0059341242, -0.014902755, 0.0082868118 }, { -0.0013222735, 0.0028492181, -0.023523273, -0.02576271 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } } }, { { { 0.72189984, 0.22069996, 0.71952927, 0.77725949 }, { 0.4054405, 0.20582059, 0.2747016, 0.37612563 }, { 0.58887422, 0.27441131, 0.19468101, 0.21480554 }, { 0.46814145, 0.34317, 0.46068212, 0.13962064 }, { -0.18134132, -0.26668789, -0.60984999, -0.67879259 }, { -0.47870351, -0.34453227, 0.32494779, 0.10292971 }, { 0.087252967, 0.066950358, 0.31813819, 0.071094818 }, { -0.0031436256, 0.038245091, -0.0076651913, -0.015389479 }, { 1.2668531, 1.2894974, 0.40584018, 0.51755806 }, { 1.3207257, 1.3403747, 0.54924634, 0.40282713 }, { 0.78581828, 0.56379328, 0.27901993, 0.56429306 }, { 0.8748226, 1.0271253, 1.0085726, 0.3888545 }, { -0.22577636, -0.32895071, -0.2846317, -0.11679531 }, { 0.26477285, 0.3179447, -0.063393238, 0.024059773 }, { -0.15463395, -0.22721468, -0.20680404, -0.15700788 }, { 0.012107106, -0.0061245949, -0.024224367, 0.005040693 }, { 0.97943693, 0.64840429, 0.45106998, 0.40771935 }, { 0.49907853, 0.1562184, 0.34338458, 0.39710628 }, { 0.95047709, 0.53336107, 0.38318275, 0.44919148 }, { 0.41892697, 0.069965886, 0.45831656, 0.38821529 }, { -0.20216736, -0.43209441, -0.57684857, -0.40189427 }, { -0.63992377, -0.40683032, -0.59207903, -0.57251716 }, { -0.047117438, -0.1880015, -0.12265155, 0.00059988607 }, { -0.011836442, -0.010049497, -0.0026152072, 0.016137736 } }, { { 0.092068993, 0.0045466749, 0.0054574031, 0.02582156 }, { 0.022115456, -0.015664041, -0.022004653, 0.041431654 }, { 0.029951298, -0.0004408542, 0.0087496069, 0.017850027 }, { 0.029086373, 0.022116039, 0.044010315, 0.001644876 }, { 0.016256387, 0.0083249367, 0.019570849, -0.0021276222 }, { 0.0079070076, -0.024696939, 0.044311101, 0.023671132 }, { -0.0081796119, -0.0024995551, 0.033501743, -0.031958988 }, { 0.0065005403, -0.076642001, 0.015736477, 0.030966939 }, { 0.029110717, 0.039154477, -0.074376619, 0.025532063 }, { -0.10980761, 0.0038346834, 0.014449171, -0.030702653 }, { -0.00068350423, -0.037251569, -0.008409224, -0.026322878 }, { 0.035406012, 0.064176275, 0.031437854, -0.0344642 }, { 0.037145809, -0.024909212, 0.041030386, 0.035216105 }, { -0.093276646, -0.013904083, -0.019536023, -0.023834405 }, { 0.042751846, -0.03620164, 0.081115921, 0.018379967 }, { -0.023909625, 0.012833691, 0.048086442, -0.0097340268 }, { 0.039552712, -0.00026806514, 0.011646753, 0.0065939486 }, { 0.058985248, 0.020165701, 0.0076721521, 0.033274221 }, { 0.052889871, 0.0042520093, 0.016490396, 0.009287973 }, { 0.044305975, -0.0016263469, 0.041390177, 0.033541355 }, { 0.014595133, -0.004801042, -0.0049517302, 0.015714264 }, { 0.00075086205, 0.0080838736, -0.037611057, -0.030488441 }, { 0.0019178075, -0.0082517768, -0.002525773, 0.0043993022 }, { 0.023774971, 0.020335611, 0.0056643868, -0.032100338 } }, { { 0.092068993, 0.0045466749, 0.0054574031, 0.02582156 }, { 0.022115456, -0.015664041, -0.022004653, 0.041431654 }, { 0.029951298, -0.0004408542, 0.0087496069, 0.017850027 }, { 0.029086373, 0.022116039, 0.044010315, 0.001644876 }, { 0.016256387, 0.0083249367, 0.019570849, -0.0021276222 }, { 0.0079070076, -0.024696939, 0.044311101, 0.023671132 }, { -0.0081796119, -0.0024995551, 0.033501743, -0.031958988 }, { 0.0065005403, -0.076642001, 0.015736477, 0.030966939 }, { 0.029110717, 0.039154477, -0.074376619, 0.025532063 }, { -0.10980761, 0.0038346834, 0.014449171, -0.030702653 }, { -0.00068350423, -0.037251569, -0.008409224, -0.026322878 }, { 0.035406012, 0.064176275, 0.031437854, -0.0344642 }, { 0.037145809, -0.024909212, 0.041030386, 0.035216105 }, { -0.093276646, -0.013904083, -0.019536023, -0.023834405 }, { 0.042751846, -0.03620164, 0.081115921, 0.018379967 }, { -0.023909625, 0.012833691, 0.048086442, -0.0097340268 }, { 0.039552712, -0.00026806514, 0.011646753, 0.0065939486 }, { 0.058985248, 0.020165701, 0.0076721521, 0.033274221 }, { 0.052889871, 0.0042520093, 0.016490396, 0.009287973 }, { 0.044305975, -0.0016263469, 0.041390177, 0.033541355 }, { 0.014595133, -0.004801042, -0.0049517303, 0.015714264 }, { 0.00075086205, 0.0080838736, -0.037611057, -0.030488441 }, { 0.0019178075, -0.0082517768, -0.002525773, 0.0043993022 }, { 0.023774971, 0.020335611, 0.0056643868, -0.032100338 } } } } };
+const float high_quality_coeffs[7][5][3][24][4] = { { { { { -4.8355339e-06f, -4.4902569e-05f, -9.2632249e-05f, -0.00053773136f }, { 0.0040143823f, -0.00060900339f, -0.0095301923f, -0.0053956011f }, { -0.0005923892f, -3.6901978e-05f, -5.6694857e-06f, -0.00017018564f }, { 0.0012441402f, 0.02236187f, 0.022751769f, 0.0062788948f }, { 0.00013810055f, -2.2709815e-05f, 0.0054849671f, -1.6599195e-05f }, { -0.020320408f, -0.017066319f, -0.017457746f, 0.022910628f }, { 0.00024171724f, 9.7419073e-05f, -0.00047804272f, -0.00010093683f }, { 7.6988167e-05f, 1.8551597e-05f, -5.7692813e-05f, -3.332362e-05f }, { -0.00062766208f, 2.713742e-05f, 0.00026511682f, 2.3841873e-05f }, { -0.00043656844f, 0.0028645469f, 0.0049817085f, 0.0080221478f }, { -3.3210444e-05f, -8.0852386e-05f, -2.2111492e-06f, -8.4430827e-05f }, { 0.010967284f, 0.018811225f, 0.017569463f, -0.0046944996f }, { -0.00018391248f, -0.00010462174f, -0.00017726f, -0.00018490133f }, { 0.00012591989f, 0.015965386f, 0.015964059f, -0.0078018431f }, { -0.006125333f, -8.2224165e-05f, -0.00020500151f, -0.00025207244f }, { -0.00016320041f, -0.0001279242f, 0.00014038799f, 8.1359421e-05f }, { -0.00064341098f, -0.0011265496f, -0.0011634792f, -0.00081607159f }, { 0.00089294825f, 0.0061923653f, 0.0052662392f, -0.00058227469f }, { -2.4001308e-05f, -1.3534224e-05f, -1.4720478e-05f, -2.5120827e-05f }, { 0.00029964918f, -0.0045658543f, -0.0045581938f, 0.0017106208f }, { 7.5790173e-05f, -1.8265415e-05f, 1.5918205e-05f, 5.8524021e-05f }, { 0.0011669872f, -0.00017571882f, -0.00017190275f, -0.0023833977f }, { 0.0033487264f, -0.0066535821f, -0.0066413786f, -0.0032332601f }, { -3.6468807e-05f, -0.00068145131f, -9.8190714e-05f, -8.7169435e-05f } }, { { -0.0010440653f, -8.9750644e-05f, 4.971182e-05f, 0.0044618878f }, { 0.0078333883f, -0.00090884312f, -0.00046920549f, -0.002465051f }, { -0.0058778609f, 0.0026554895f, -0.00031880506f, -0.00010649091f }, { -0.0015095448f, 0.0094026506f, 0.009492703f, 0.0024572848f }, { 0.0047331786f, 0.00070722401f, 0.0028798817f, -0.00039779892f }, { -0.0089878107f, -0.0095474878f, -0.0097187652f, 0.008765907f }, { -4.0435321e-05f, -0.00061813281f, -0.0060490143f, 0.0016259965f }, { -0.00014720558f, -1.0601876e-05f, 0.00014757138f, 0.00016227641f }, { -0.010428289f, -0.00031812813f, -0.0016172213f, -0.00012022134f }, { 0.0040517131f, 0.0072972763f, 0.0060433905f, 0.0025041645f }, { 0.00014090924f, 0.00027612853f, 0.00015961665f, 0.0002605418f }, { -0.00020653783f, -0.00048482867f, -0.00058472338f, 0.00026413759f }, { 0.00056712638f, 0.00026385353f, 0.00035484947f, 0.00033212447f }, { -0.00094663094f, 0.0029891757f, 0.0029887838f, -0.0026583585f }, { -0.0017400246f, 0.00042350567f, 0.00086128207f, 0.00039863587f }, { 0.00059604848f, 0.00027495434f, -0.00059956434f, -4.4981673e-05f }, { -0.010211343f, -0.0080580409f, -0.0085333216f, 0.0023258717f }, { 0.00042832593f, 0.0056750222f, 0.0048059635f, -0.0092168281f }, { 3.0214612e-05f, 4.540924e-06f, 1.7239937e-05f, 2.783598e-05f }, { 0.00029393335f, -4.5128636e-05f, -4.3089017e-05f, 0.00030682556f }, { -4.7077735e-05f, -1.3596835e-05f, -0.0015338149f, -7.4957991e-05f }, { -0.00097136844f, 0.00018564298f, 0.00021815754f, 0.0015095577f }, { 0.00043929849f, -0.0014691094f, -0.0014671742f, -0.00029365954f }, { 8.8554045e-05f, 0.0062500772f, 0.0001495049f, 0.00021007601f } }, { { 0.0020307077f, 0.0020947445f, 0.0017438295f, 0.0084822342f }, { -0.0069727503f, -0.0010131005f, 0.0055261321f, -0.0020442588f }, { 0.00031035611f, 0.00010839441f, 3.7359209e-06f, 4.3112837e-05f }, { 9.1207794e-05f, 0.0050148169f, 0.0051071455f, 0.0033679057f }, { -0.00090101737f, -0.00053793176f, -0.0025829621f, 0.0003241927f }, { -0.0019244714f, -0.0033690472f, -0.0035193497f, 0.0027653636f }, { -0.00065476293f, -0.00017787403f, 0.00040383136f, -0.00018123957f }, { -0.00030640434f, -0.00018961553f, -0.00011036218f, -0.00015793049f }, { 0.001110592f, -0.00021252645f, 0.00015849587f, -3.7758317e-05f }, { 0.00077967828f, -0.0051765235f, -0.0078505592f, -0.010796339f }, { -1.2024951e-05f, 6.48806e-05f, -3.9409005e-05f, 7.4639306e-05f }, { -0.00017352424f, -0.00037802595f, -0.00045639468f, 0.00016843169f }, { -4.2866244e-05f, -4.3730932e-06f, 7.3574276e-05f, 5.6076779e-05f }, { 0.00024802387f, 0.0018053101f, 0.0018042994f, -0.0016700716f }, { 0.0082698262f, -0.00014605077f, 0.0004377682f, 8.1585074e-05f }, { -4.494343e-06f, 0.00019781519f, -0.00058910268f, -0.00027360572f }, { 0.0013016934f, 0.0021020456f, 0.0022718598f, -0.0059377824f }, { 0.002185371f, -0.0080788056f, -0.0071952836f, 0.0039688918f }, { 0.00013048617f, 0.0001738124f, 0.00012978924f, 0.00013813358f }, { 0.00032386518f, 0.00023046021f, 0.00023064714f, 0.00033762343f }, { 0.00023643771f, 0.00019652953f, 0.0013083597f, 0.00024739959f }, { -0.0063957036f, -0.0055319023f, -0.0054742301f, -0.0037204932f }, { -0.0005510683f, -0.0007715413f, -0.00077385934f, -0.001009415f }, { 0.00017904616f, -0.00096137522f, 0.00030252599f, -2.2478138e-05f } } }, { { { -0.00038948583f, -0.00040817153f, -0.00041280315f, -0.0010985631f }, { 0.0025695337f, 0.00042904308f, 0.0054649973f, -0.0055079106f }, { 0.00052050672f, 2.2618679e-05f, 0.00024058975f, -0.00012632201f }, { -0.013468886f, 0.0079396715f, 0.0079402246f, 0.026283756f }, { -7.922122e-05f, -3.4761763e-06f, -0.0041716347f, 0.0001478739f }, { 0.023716381f, -0.016415262f, -0.015296927f, -0.021050827f }, { 3.7654391e-05f, 0.00012765816f, -0.0001337099f, 0.00051483398f }, { 0.00015671907f, 0.00010686796f, 2.1421097e-05f, -2.2281569e-05f }, { 3.1779413e-06f, 0.00010449913f, -0.00018303614f, 7.5382489e-05f }, { -0.00020526765f, -0.0011333575f, -0.0050720108f, 0.0051482782f }, { 4.0450357e-05f, 1.0808158e-05f, -2.3316095e-05f, 9.7767333e-06f }, { -0.019107229f, 0.010907324f, 0.0048969594f, 0.017851514f }, { 7.4048796e-05f, -7.041835e-06f, 8.0226174e-05f, 5.1714105e-05f }, { -0.016564627f, 0.0023486944f, 0.0023601429f, 0.016005248f }, { -0.004528284f, 3.6291049e-05f, 2.4229636e-05f, 0.0024853948f }, { 5.6882054e-05f, 6.8805135e-05f, 0.00013119897f, 0.00010339801f }, { 0.00021183341f, 0.0008203137f, -7.204401e-05f, 0.00062599728f }, { -0.00099314707f, 0.0030198762f, -0.0038989955f, 0.00055571214f }, { -7.4247984e-05f, -8.3993373e-05f, -5.9133252e-05f, -7.7411989e-05f }, { 0.0054296732f, -0.00057858871f, -0.00058417754f, -0.005072911f }, { -0.00019259782f, -0.00018772532f, -4.2959783e-05f, -0.0001827295f }, { -0.00029351865f, 0.00013736372f, 0.00016666048f, 0.00020873447f }, { 0.0069341659f, 0.0027612928f, 0.0027538377f, -0.0061770317f }, { 4.2584714e-05f, -0.00037063589f, -9.0693123e-06f, 0.00011845784f } }, { { 0.0028834168f, 0.0031807308f, 0.0031352582f, 0.01064051f }, { 0.0049297987f, -4.2149356e-05f, -0.0014926841f, -0.0002300371f }, { 0.0020396303f, -0.00066042794f, -6.4359283e-05f, 0.00017835163f }, { -0.0025767816f, 0.0025148152f, 0.0025224779f, 0.0043006543f }, { -0.00042084416f, -0.00013534305f, 0.002453623f, -4.0707749e-05f }, { -0.0001803055f, -0.0010450606f, -0.00084380806f, 0.00014843677f }, { -0.0064067107f, 0.00011012652f, -0.0022552747f, -0.00080508294f }, { -0.00017778763f, -4.296789e-05f, 0.00015343883f, 0.00025036711f }, { 0.002825978f, -0.00031945362f, -0.00031987612f, -0.00021117763f }, { 0.00032791249f, -0.00049524542f, 0.0049368722f, -0.0017186408f }, { -0.0001685943f, -0.00016766033f, -0.0001755097f, -0.00017067307f }, { 0.00023939157f, -0.00011793706f, -6.0620575e-05f, -0.0002706595f }, { -2.9718673e-05f, 3.5950879e-05f, 1.839844e-05f, -2.8718148e-05f }, { -0.0017260981f, 0.00012145435f, 0.0001236679f, 0.0018292155f }, { 0.0036086706f, 0.0001026898f, -2.5518889e-05f, -0.00019830236f }, { -0.00031546808f, -0.00042107458f, -0.00059963868f, -0.00061472497f }, { -0.0074719522f, 0.0015719596f, -0.0033624165f, -0.0092664101f }, { -0.0011285776f, 0.0018601435f, 0.00052060704f, -1.5554679e-05f }, { 4.9853171e-05f, 7.3650922e-05f, 3.4080107e-05f, 5.4255445e-05f }, { 0.00015102779f, -2.58105e-05f, -2.5851018e-05f, -4.5185316e-05f }, { 0.0002057452f, 0.00019037765f, 0.0040052198f, 0.00020046579f }, { 0.0027727314f, 0.0040749211f, 0.0036050794f, 0.0034635222f }, { 0.00042503689f, 0.00056027382f, 0.00056052971f, -8.2485044e-05f }, { -5.6309634e-05f, 0.0019722025f, 6.4267434e-05f, -0.00020376412f } }, { { 0.0051607661f, 0.0047835358f, 0.0047658352f, 0.0054281814f }, { -0.0040939561f, 0.0012119183f, -0.0023408179f, -0.00055891234f }, { -0.0031939804f, -0.0015954053f, -0.00018570689f, 0.00028849431f }, { -0.0075625096f, 0.0033878734f, 0.0033797415f, 0.010242674f }, { -0.002293562f, 0.00024245282f, 0.0019455622f, 0.0039550747f }, { 0.0090386754f, -0.0086947671f, -0.0082684939f, -0.0075613346f }, { -0.00085735117f, 3.4822634e-05f, -0.0024653972f, -0.00090964985f }, { -0.00013750587f, -0.00010089501f, 6.3555498e-05f, 0.0002758494f }, { 0.0060496328f, -0.00032664426f, 0.0005979723f, -0.00018819024f }, { 0.00072724184f, 0.00082242885f, 0.0045668772f, -0.0054557456f }, { -9.6167811e-05f, 7.9856612e-05f, 0.00015672473f, 8.0901183e-05f }, { 0.00038859448f, -0.00025360755f, -0.00017624981f, -0.00049125519f }, { -8.8277361e-05f, 2.4159527e-05f, -0.00016014627f, -2.7854246e-05f }, { -0.0037308647f, 0.00041434141f, 0.0004167221f, 0.0037190244f }, { 0.00050696744f, -4.6752715e-05f, 0.00033183668f, -0.0025882828f }, { -0.00015915702f, -0.0002325901f, -0.00036157415f, -0.00016391937f }, { 0.00012320153f, 0.0026711886f, 0.0018414591f, -0.0058215223f }, { -0.0029409983f, -0.00015460743f, 0.0031951665f, 0.0074654329f }, { 9.9084813e-05f, 9.1785865e-05f, 5.9300007e-05f, 0.00010463304f }, { 0.00024773341f, -2.5723276e-05f, -2.5709769e-05f, -0.00015357475f }, { 0.000416633f, 0.00028749584f, -0.0038632071f, 0.00039869488f }, { 0.00018344152f, 3.0811778e-05f, -0.00010240082f, 0.00059301197f }, { 0.0019217461f, 0.00034404024f, 0.00034318823f, -0.0015867375f }, { -0.00011928879f, 0.001178769f, -5.8655983e-05f, -0.00028461439f } } }, { { { 0.99999992f, 0.99999992f, 0.99999991f, 0.99999925f }, { 0.99998864f, 0.99999972f, 0.99993965f, 0.99997027f }, { 0.99999969f, 1.0f, 0.99999997f, 0.99999998f }, { 0.99990852f, 0.99971841f, 0.99970961f, 0.9996348f }, { 0.99999999f, 1.0f, 0.99997626f, 0.99999999f }, { 0.99951219f, 0.9997196f, 0.99973058f, 0.99951587f }, { 0.99999997f, 0.99999999f, 0.99999988f, 0.99999986f }, { 0.99999998f, 0.99999999f, 1.0f, 1.0f }, { 0.9999998f, 0.99999999f, 0.99999995f, 1.0f }, { 0.99999988f, 0.99999525f, 0.99997473f, 0.99995457f }, { 1.0f, 1.0f, 1.0f, 1.0f }, { 0.99975729f, 0.99976356f, 0.99983365f, 0.99982963f }, { 0.99999998f, 0.99999999f, 0.99999998f, 0.99999998f }, { 0.99986279f, 0.99986979f, 0.99986978f, 0.99984147f }, { 0.99997099f, 1.0f, 0.99999998f, 0.99999688f }, { 0.99999999f, 0.99999999f, 0.99999998f, 0.99999999f }, { 0.99999977f, 0.99999903f, 0.99999932f, 0.99999947f }, { 0.99999911f, 0.99997627f, 0.99997853f, 0.99999968f }, { 1.0f, 1.0f, 1.0f, 1.0f }, { 0.99998521f, 0.99998941f, 0.99998944f, 0.99998567f }, { 0.99999998f, 0.99999998f, 1.0f, 0.99999998f }, { 0.99999928f, 0.99999998f, 0.99999997f, 0.99999714f }, { 0.99997035f, 0.99997405f, 0.99997415f, 0.99997569f }, { 1.0f, 0.9999997f, 1.0f, 0.99999999f } }, { { 0.00015966941f, 0.00014262676f, 0.00020165066f, 0.00021618914f }, { 2.8140907e-06f, -0.00020325872f, 0.00017736728f, 6.0386679e-05f }, { -0.0003187876f, 5.8862288e-05f, 6.2281085e-05f, 1.7339908e-05f }, { -2.6587911e-05f, -0.00011609007f, -0.00011725093f, -7.6114852e-05f }, { 0.00013665042f, 5.2703844e-06f, -0.00031293536f, 3.8693931e-05f }, { -9.8143069e-05f, -0.00012816332f, -0.00012926252f, -0.00010623032f }, { 0.00032342312f, -1.9200091e-06f, -0.00010691485f, 6.3541059e-05f }, { -8.0643542e-06f, 9.7622933e-06f, 2.9924822e-05f, -1.988333e-05f }, { 0.00025318464f, 1.2588649e-05f, 1.4665927e-05f, 9.3294806e-06f }, { 2.6875391e-06f, -2.4928123e-05f, 2.251878e-05f, 0.00011026808f }, { 1.767638e-05f, 1.0309044e-05f, 2.4765648e-05f, 1.4397941e-05f }, { 6.9000935e-06f, 1.0637078e-05f, 1.087637e-05f, 6.3065784e-06f }, { 5.532953e-05f, 1.6231463e-05f, 4.9564371e-05f, 3.6623041e-05f }, { -1.6958729e-05f, -3.1627491e-05f, -3.1524511e-05f, -2.9954116e-05f }, { 8.9045086e-05f, 2.1005026e-05f, 1.3016463e-05f, 8.7863053e-05f }, { -2.75035e-05f, -3.0440427e-05f, -3.5356286e-05f, 5.9609261e-06f }, { 0.0001586274f, 4.0711165e-05f, 3.1563135e-05f, 0.0001385483f }, { 8.5548316e-06f, 7.4531928e-05f, -3.7017413e-05f, 2.6874037e-05f }, { -1.3750655e-05f, -8.2756032e-06f, -2.7214983e-07f, -1.4830115e-05f }, { -7.0798362e-07f, -3.3187173e-07f, -3.3266762e-07f, -5.7113855e-07f }, { 4.3615512e-05f, -4.4076433e-06f, 8.9239586e-06f, 3.7278531e-05f }, { -7.7366773e-06f, 4.610399e-06f, 4.3762687e-06f, -5.64067e-06f }, { -3.2666125e-06f, -1.0773146e-05f, -1.0861965e-05f, -1.3327232e-06f }, { -9.1178305e-06f, 0.00030171207f, -1.5395234e-05f, -2.0695425e-07f } }, { { 0.00017159464f, 0.00014699558f, 0.00018752678f, 0.0002227926f }, { -4.6524822e-05f, -0.00010460271f, 0.00034735325f, 0.00010082238f }, { -6.8269006e-05f, 1.4343751e-05f, 7.7283393e-06f, 2.5347136e-05f }, { -6.6149546e-05f, -7.1168993e-05f, -7.0621016e-05f, -0.00015246746f }, { 7.12022e-05f, 3.8790461e-05f, -0.00023994449f, 6.6792921e-05f }, { -0.00014735813f, -0.00012658353f, -0.00012162488f, -0.00012106777f }, { 0.00015161388f, -1.4439153e-05f, -3.7629923e-06f, 8.3140788e-06f }, { 4.0175416e-05f, 2.5380268e-05f, -2.2894421e-06f, 4.6374378e-06f }, { 0.00028906023f, 1.7695243e-05f, 5.3790587e-06f, 1.631859e-05f }, { 1.8890685e-05f, -1.6898275e-05f, 2.1007663e-05f, 6.5179363e-05f }, { -3.9142595e-06f, 2.5745488e-05f, 1.0803197e-05f, 2.7099749e-05f }, { 9.4245546e-06f, 1.0010075e-05f, 9.058324e-06f, 9.8703427e-06f }, { -2.3441863e-06f, 2.5490323e-05f, -1.0097654e-05f, 4.0554798e-05f }, { -4.1443921e-05f, -1.996316e-05f, -2.0000841e-05f, -4.7495655e-05f }, { 0.00012591695f, 5.6179903e-05f, -1.8415869e-05f, -3.8697972e-05f }, { 2.6719505e-05f, 2.4195362e-06f, 2.4287424e-05f, 3.4703059e-05f }, { 7.3804931e-05f, 4.9784871e-05f, 3.1159931e-06f, 0.00015857197f }, { -0.00010634331f, -1.6427658e-05f, -7.4874306e-05f, -6.2620255e-05f }, { -4.2561214e-06f, -1.6123179e-05f, -1.5507273e-05f, -1.2909924e-05f }, { -1.2210463e-06f, 1.1546399e-06f, 1.1413892e-06f, -1.3465856e-06f }, { 3.4909884e-05f, -1.2677793e-05f, 0.00011543701f, 2.413091e-05f }, { -2.1953323e-05f, -4.6244252e-06f, -3.5624435e-06f, 4.2293671e-06f }, { -1.1392936e-05f, -4.3970369e-06f, -4.4264864e-06f, -1.208518e-05f }, { -4.4002617e-05f, 0.00020912348f, -3.9617824e-05f, -4.1725112e-05f } } }, { { { -0.32504349f, -0.32502096f, -0.32501094f, -0.32423576f }, { -0.65602876f, -0.65622598f, -0.65567173f, -0.65525128f }, { -1.4666488f, -1.4666488f, -1.4666488f, -1.4666488f }, { 0.87168363f, 0.87181364f, 0.87181792f, 0.8718169f }, { -1.264365f, -1.264365f, -1.264365f, -1.264365f }, { 0.89917968f, 0.89916889f, 0.89916525f, 0.89927374f }, { -1.2245906f, -1.2245906f, -1.2245906f, -1.2245906f }, { -0.8885678f, -0.88856217f, -0.88856327f, -0.88855044f }, { -0.31799095f, -0.31916566f, -0.31907669f, -0.31918911f }, { -0.08987958f, -0.090342401f, -0.090004674f, -0.090222398f }, { -0.59425693f, -0.59433999f, -0.59429118f, -0.59433553f }, { 1.1317575f, 1.1317475f, 1.1317412f, 1.1317494f }, { -1.2193493f, -1.2193493f, -1.2193493f, -1.2193493f }, { 1.2506981f, 1.250675f, 1.250675f, 1.2506569f }, { -1.08782f, -1.0877793f, -1.0878022f, -1.0878025f }, { -0.13925598f, -0.13932948f, -0.13919658f, -0.13913403f }, { -0.40394684f, -0.4042314f, -0.40436178f, -0.40402218f }, { -0.47762966f, -0.47745572f, -0.47767784f, -0.47713093f }, { -0.60177181f, -0.60176862f, -0.60177347f, -0.60177079f }, { 2.7311956f, 2.7311911f, 2.7311911f, 2.731191f }, { -1.3109856f, -1.3109856f, -1.3109856f, -1.3109856f }, { 0.60942644f, 0.60941369f, 0.6094123f, 0.60944198f }, { 0.55675448f, 0.55672275f, 0.55672303f, 0.5567542f }, { -0.40637059f, -0.4057945f, -0.40635768f, -0.40636681f } }, { { -0.0016154222f, -0.0015930079f, -0.0015828998f, -0.00087447165f }, { -0.0011262472f, -0.001324462f, -0.00094895016f, -0.00062188189f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 9.7616744e-05f, 0.00010718899f, 0.00010718606f, 0.00012665246f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.00013476236f, 6.982272e-05f, 6.8208505e-05f, 0.00014604742f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { -0.0031089951f, -0.0031071196f, -0.0031207245f, -0.0031097054f }, { -0.0027808116f, -0.0035049857f, -0.0034100135f, -0.0035192661f }, { -0.0018291474f, -0.0019603285f, -0.0018919656f, -0.0019656229f }, { -0.0034301741f, -0.0034912573f, -0.0034474395f, -0.0034893985f }, { -6.156701e-06f, -9.8568527e-06f, -1.2383692e-05f, -9.9984205e-06f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.00011838153f, 0.00011008679f, 0.00011008878f, 0.00010536608f }, { -0.0006246638f, -0.00058479459f, -0.00061327452f, -0.00061085433f }, { -0.0059197749f, -0.0059778169f, -0.0059586015f, -0.0058798299f }, { -0.0013246996f, -0.0016061786f, -0.0016081246f, -0.0014374546f }, { -0.001593227f, -0.0014706843f, -0.0015974008f, -0.001341579f }, { -0.0027930604f, -0.0027920013f, -0.0027939865f, -0.0027928528f }, { -1.8908723e-06f, -4.266382e-06f, -4.2210172e-06f, -5.0155215e-06f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.00018508026f, 0.00019774537f, 0.00019744661f, 0.00019538593f }, { 2.3243747e-05f, 1.7291398e-05f, 1.7309712e-05f, 2.9261396e-05f }, { -0.0041402471f, -0.0037085946f, -0.0041294876f, -0.0041316136f } }, { { -0.0018899732f, -0.0018719182f, -0.0018661076f, -0.0012234594f }, { -0.0012968123f, -0.0012971446f, -0.00093522854f, -0.00066475268f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 9.1054464e-05f, 0.00014124217f, 0.00014156806f, 0.00012014953f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.00017026995f, 0.00010528413f, 0.00010537941f, 0.00015698848f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { -0.0025812972f, -0.0025835894f, -0.0025789321f, -0.002554949f }, { -0.0035568863f, -0.0042988014f, -0.0042155548f, -0.004312546f }, { -0.0024184575f, -0.0025111277f, -0.0024654994f, -0.0023980076f }, { -0.0036993386f, -0.0037113013f, -0.0036987284f, -0.0037094875f }, { -5.074861e-06f, -1.1367399e-05f, -1.4819989e-05f, -9.2705899e-06f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.00012570403f, 0.00012150272f, 0.00012149179f, 0.00010579599f }, { -0.00062162762f, -0.00058131015f, -0.00060837583f, -0.00060795256f }, { -0.00775735f, -0.0077198081f, -0.0078365948f, -0.0077749317f }, { -0.0015325554f, -0.0017125784f, -0.001703195f, -0.0015662859f }, { -0.0018130784f, -0.00177106f, -0.001858095f, -0.0015845058f }, { -0.003668417f, -0.0036659688f, -0.0036693421f, -0.0036680526f }, { -9.5804016e-06f, -9.6276607e-06f, -9.630607e-06f, -1.2159056e-05f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.00017930618f, 0.00020084683f, 0.00020150104f, 0.00020810787f }, { 2.3869269e-05f, 1.1024793e-05f, 1.1041937e-05f, 1.6467357e-05f }, { -0.004690782f, -0.0044656761f, -0.0046782065f, -0.0046921455f } } }, { { { 0.23047932f, 0.23043226f, 0.23041471f, 0.22922185f }, { 0.14990977f, 0.15703656f, 0.15110771f, 0.15149153f }, { 0.30629171f, 0.30426701f, 0.30400037f, 0.30403889f }, { 0.03476576f, 0.036188528f, 0.036216719f, 0.037322097f }, { 0.31066251f, 0.31090363f, 0.31041565f, 0.31057779f }, { 0.04875259f, 0.046468595f, 0.046486323f, 0.046584523f }, { 0.31745458f, 0.31874472f, 0.32086369f, 0.31880207f }, { 0.64054942f, 0.64062862f, 0.64051973f, 0.64059059f }, { 0.27309038f, 0.27480819f, 0.27477284f, 0.27486762f }, { 0.196647f, 0.19687982f, 0.19607604f, 0.1957915f }, { 0.32867362f, 0.32858008f, 0.32856702f, 0.328555f }, { -0.0026873031f, -0.0042393446f, -0.0057894907f, -0.0041858859f }, { 0.40254624f, 0.4024247f, 0.4025598f, 0.40243731f }, { 0.019362807f, 0.018146218f, 0.018146051f, 0.019656613f }, { 0.29328089f, 0.29403937f, 0.29435036f, 0.29403094f }, { 0.57111506f, 0.57118505f, 0.57099608f, 0.57099266f }, { 0.16966612f, 0.16993739f, 0.17069399f, 0.16991136f }, { 0.14989055f, 0.1489484f, 0.14995985f, 0.15015916f }, { 0.33606014f, 0.33606294f, 0.33606393f, 0.33605429f }, { 0.015421206f, 0.015180692f, 0.01518037f, 0.015431139f }, { 0.33165237f, 0.33185282f, 0.33162592f, 0.33166981f }, { 0.078137018f, 0.078153855f, 0.078165152f, 0.078332343f }, { 0.002896946f, 0.0026038621f, 0.0026029604f, 0.0022081151f }, { 0.41064398f, 0.40987685f, 0.41065341f, 0.41059166f } }, { { -0.0024316111f, -0.0024732789f, -0.0024922144f, -0.0035874346f }, { 0.0013306961f, 0.004171802f, 0.0027660627f, 0.0023671465f }, { 0.0034411091f, 0.0020878413f, 0.0020874456f, 0.0022028237f }, { -0.0032873976f, -0.0021351911f, -0.0021071363f, -0.0028424534f }, { 0.0017995208f, 0.0022319618f, 0.0039270256f, 0.0021249365f }, { -0.0019590835f, -0.0012526895f, -0.0012347747f, -0.0021069943f }, { 0.0012319531f, 0.002255621f, 0.0030193583f, 0.0020970822f }, { 0.0015144077f, 0.0015110104f, 0.0014803089f, 0.0015340007f }, { -0.0036679996f, -0.0028160114f, -0.0028586497f, -0.0027953731f }, { -0.005445786f, -0.0052624873f, -0.0054843188f, -0.0053271749f }, { 0.00067154572f, 0.0007530775f, 0.00067974516f, 0.00074462315f }, { -0.0035626119f, -0.0034186877f, -0.0038720517f, -0.0040088745f }, { 0.003455851f, 0.0035040061f, 0.0034671486f, 0.0035069881f }, { -0.0047789747f, -0.0047994804f, -0.0047996451f, -0.0044008337f }, { 0.0032403482f, 0.0033627856f, 0.003429619f, 0.0031153117f }, { -0.005027022f, -0.0049812f, -0.0049604573f, -0.0050556194f }, { -0.0020728991f, -0.0014784158f, -0.001216894f, -0.0019213729f }, { -0.00013808007f, -0.00067270623f, -0.00024001574f, -0.00030691077f }, { 0.0004367104f, 0.00043390709f, 0.00043548166f, 0.00043425516f }, { -0.00082746467f, -0.00088151411f, -0.00088152334f, -0.0008043643f }, { 0.0030277712f, 0.003133577f, 0.0028529862f, 0.0030362271f }, { -0.0058721937f, -0.0059816331f, -0.0059799345f, -0.0058882832f }, { -0.0057032562f, -0.0057401855f, -0.0057416619f, -0.0062417688f }, { -0.0014357888f, -0.0020782049f, -0.0014346823f, -0.0014513767f } }, { { -0.0027051235f, -0.0027087245f, -0.0027052303f, -0.0033594951f }, { 0.0028036195f, 0.0030416572f, 0.0014306948f, 0.0017897371f }, { 0.0031113166f, 0.0026432303f, 0.0025937824f, 0.0025394463f }, { -0.0036032904f, -0.003447065f, -0.0034344406f, -0.0024163572f }, { 0.0023912799f, 0.0025281229f, 0.0038665087f, 0.0024214034f }, { -0.0023543827f, -0.0024294943f, -0.0024539784f, -0.0027742617f }, { 0.0020903896f, 0.0026617586f, 0.003395249f, 0.0026261065f }, { 0.0019031008f, 0.0019405475f, 0.0019426085f, 0.0019404325f }, { -0.0040413326f, -0.0030964835f, -0.0031020735f, -0.0030826754f }, { -0.0064568993f, -0.0062342438f, -0.0064704698f, -0.0065636744f }, { 0.0010788406f, 0.0010092051f, 0.0010264121f, 0.00099891228f }, { -0.0040759201f, -0.0059224283f, -0.0066809927f, -0.0049099348f }, { 0.0042962009f, 0.0041909175f, 0.0043195236f, 0.0041900138f }, { -0.0062728983f, -0.0070256154f, -0.007025641f, -0.0061758746f }, { 0.0036210401f, 0.0039723998f, 0.0042232048f, 0.0042757707f }, { -0.0058693852f, -0.0058583303f, -0.0058544016f, -0.005887725f }, { -0.0023099876f, -0.0021136245f, -0.0017298078f, -0.0022483337f }, { -0.00017851962f, -0.00014956209f, 8.5676316e-05f, -0.00024971669f }, { 0.0003734781f, 0.00037078986f, 0.00037364181f, 0.00037070594f }, { -0.00030648905f, -0.00038230535f, -0.00038223043f, -0.00028623253f }, { 0.0032871423f, 0.0034163052f, 0.0028276655f, 0.0032991918f }, { -0.0061331695f, -0.0063319797f, -0.0063340119f, -0.0064390374f }, { -0.0062172888f, -0.0059787106f, -0.0059793294f, -0.0060406701f }, { -0.0018276142f, -0.0022170788f, -0.0018293949f, -0.0018222824f } } } }, { { { { 0.13218089f, -0.11654637f, -0.11622196f, -0.044208736f }, { 0.0074579257f, 0.0038503609f, 0.0013201096f, 4.0415784e-05f }, { -0.025474487f, -0.01209255f, -0.016535858f, 0.012704547f }, { -0.0016894103f, -0.0081312144f, -0.0033264609f, 0.0011923269f }, { -0.068044876f, 0.018276873f, -0.074833897f, 0.01308348f }, { 0.02665691f, 0.013515118f, 0.026440814f, -0.0077037816f }, { 0.0023286096f, -0.0025782652f, 0.0021644694f, -0.0042955294f }, { 0.051356261f, -0.031058382f, -0.085382962f, -0.033103269f }, { -0.081609229f, 0.0035270199f, -0.015722417f, 0.048773789f }, { 0.0023928418f, -0.001243811f, 0.011910492f, -0.011621478f }, { -0.028953904f, -0.029335777f, -0.0057891432f, 0.013874136f }, { -0.012473582f, 0.001772629f, -0.013983442f, 0.014846792f }, { -0.016111661f, 0.0018902323f, 0.025910586f, 0.042848276f }, { 0.026200626f, 0.024007879f, 0.0017667146f, -0.016394032f }, { -0.0067006429f, -0.0017968936f, 0.009028659f, 0.0044060413f }, { 0.019280611f, 0.0449581f, -0.042852227f, -0.066012332f }, { -0.014451123f, -0.047772741f, -0.047475406f, 0.098434178f }, { -0.0028954635f, 0.010521833f, -0.015741597f, -0.00091666191f }, { 0.0020291956f, -0.057966746f, -0.04525094f, 0.032711614f }, { 0.020563445f, -0.0078684621f, -0.015282237f, -0.0019830466f }, { -0.019504171f, 0.071338511f, 0.0033729474f, -0.0095772339f }, { 0.013056103f, 0.018719519f, 0.0096002937f, -0.028774366f }, { -0.00038728577f, -0.0010662982f, -0.0014333502f, 0.00059135695f }, { 0.073844752f, -0.05666013f, -0.1007151f, -0.030440738f } }, { { 0.00017766639f, -9.2398532e-05f, -3.9442682e-05f, -3.9559848e-05f }, { -0.0043956477f, 0.00044042277f, -0.00047491077f, 9.4171117e-05f }, { -0.0042095545f, -0.00910753f, -0.0014295282f, 0.0042595844f }, { 0.00070989004f, -0.0009623012f, 0.00084162653f, -0.00015925965f }, { -0.0017587638f, 0.0033199811f, -0.00025544613f, 0.00083644978f }, { 0.0051797987f, 0.0015691893f, -0.002324397f, 0.0050776381f }, { 0.003911779f, 0.00072639703f, 2.102924e-05f, -0.0029529332f }, { 0.0050240476f, -0.00041452319f, 3.1730448e-06f, -0.0072697591f }, { -1.5023048e-05f, 0.00032491246f, -9.2151952e-05f, 0.0035851726f }, { 0.0030984373f, 0.0016428856f, 0.0032974124f, -0.0036034289f }, { -0.00044578206f, -0.0035916409f, 0.0028146658f, 0.0068013321f }, { 0.00025716711f, -0.0024772152f, 0.0029660992f, -0.0008783244f }, { -0.005543602f, -0.00046453249f, 0.006815884f, 0.0069207512f }, { -0.0033541738f, -0.0015140333f, -0.004071746f, -0.0020908789f }, { 0.0027932918f, -0.0012517158f, -0.0033509184f, -0.001271572f }, { 0.0043481525f, -0.00088858735f, -0.0081538059f, 0.00027985077f }, { 7.4017523e-05f, -7.0080388e-05f, -7.1766386e-05f, 0.00020468758f }, { 0.00044507396f, 0.010179106f, -0.0048087449f, 0.0013487105f }, { 0.00082148695f, -0.00042640153f, -0.0024255173f, 0.0044486011f }, { -0.00026383509f, -0.0031871528f, -0.008203704f, -0.00053957093f }, { -0.0002996462f, 0.00070789605f, 7.9300612e-05f, -0.00024002209f }, { 0.0013722116f, 0.0049176054f, 0.0029283062f, -0.000849108f }, { 0.00026545039f, 0.0011783443f, 0.00072103548f, -0.0007355776f }, { 0.002192273f, -0.00294318f, 1.5452606e-05f, -0.0020953993f } }, { { 2.4074136e-05f, -2.4931598e-05f, -1.0893587e-05f, 1.080951e-05f }, { -0.0061635883f, -0.0042963493f, -0.00177783f, -0.00080292808f }, { 0.0047868795f, -0.0050472436f, 0.0082439123f, -0.0090979713f }, { 0.0017221077f, 0.0067285193f, 0.0031011872f, -0.0019932567f }, { 0.0010926271f, -0.0012170693f, 0.00012875612f, 0.00016441623f }, { -0.0048786273f, -0.0041225634f, -0.005591426f, 0.0043469593f }, { -0.0070664098f, -0.0012625813f, -0.00022220241f, -0.0026120468f }, { -0.0026689917f, 0.00030860545f, 1.9297947e-05f, 0.001274799f }, { 0.0026769559f, 0.00016106032f, 0.00013829246f, -0.0017239107f }, { -0.0042495789f, 0.0010270326f, -0.00078224804f, -0.0019210019f }, { 0.0072385804f, 0.0086418476f, 0.0061428272f, -0.0027142827f }, { 0.0019768127f, -0.00057957046f, 0.0047464783f, -0.004599565f }, { 0.0093618867f, -0.0010476542f, -0.0038681572f, -0.0065219521f }, { -0.0076406673f, -0.0036729355f, -0.0068804827f, 0.0077571478f }, { 0.0012706397f, -0.00042567505f, -0.002521821f, 6.0288127e-05f }, { -0.002041411f, 0.000430125f, 0.0073620925f, 0.0021579456f }, { 0.00012145466f, 4.1276616e-05f, 4.2449608e-05f, 9.8351262e-05f }, { 0.0014376278f, -0.007439719f, 0.0039006971f, 0.00051135138f }, { -7.1665367e-05f, 0.00023856335f, 0.00015274881f, -0.0096946274f }, { -0.00076804256f, 0.0040182915f, 0.012603411f, -0.00059669891f }, { -0.00010641981f, -0.00052355992f, 0.00057481361f, 0.00016456343f }, { -0.0027623375f, -0.0036761364f, -0.010480297f, 0.0066006902f }, { 0.00049081404f, 0.00077264749f, 0.0021355718f, -0.00029188425f }, { 0.00028566818f, 0.00097678458f, 0.00089022281f, -0.00013760767f } } }, { { { -0.0098123577f, 0.11017117f, 0.11245143f, -0.01173447f }, { 0.0036188505f, -0.0025878518f, -0.00043343726f, -0.0038813197f }, { 0.013109746f, -0.016775181f, -0.0011093308f, 0.00083465721f }, { -0.0042515898f, -0.0028159364f, 0.00027829209f, -0.002907578f }, { -0.0081027554f, -0.0019330574f, 0.061872524f, -0.037539524f }, { -0.012923735f, 0.021011524f, 0.002680406f, 0.0034369108f }, { 0.0027819214f, 0.0028657905f, -0.0034177203f, -0.0037322329f }, { -0.0036178174f, 0.065792163f, 0.13263475f, 0.0055427994f }, { 0.027832309f, -0.083372016f, -0.058757582f, 0.016164879f }, { -0.0082343898f, 0.011782416f, 0.011496052f, -0.0027847616f }, { 0.0012516658f, -0.014686832f, -0.025073035f, -0.020700577f }, { 0.0055718234f, -0.011543219f, -0.012867689f, -0.0049474286f }, { 0.028869265f, -0.035431559f, 0.024976635f, -0.01063055f }, { -0.0010657662f, 0.014977146f, 0.027109f, 0.01612865f }, { -0.0021697493f, 0.0044220507f, 0.0055654161f, -0.0032373397f }, { -0.018500666f, -0.01979267f, -0.0068480612f, 0.03908391f }, { 0.063306878f, 0.01934691f, 0.019254616f, -0.099824471f }, { 7.0580666e-05f, -0.0015082457f, -0.0056893693f, 0.00022726294f }, { 0.0077067654f, -0.014018834f, -0.021406454f, -0.0076589993f }, { -0.0013072394f, 2.6765854e-05f, 0.0028400803f, 0.0037431063f }, { -0.025369581f, -0.064039908f, -0.020594137f, -0.086807367f }, { -0.033639351f, 0.010434758f, 0.00082983507f, 0.013145885f }, { 0.00029373395f, 7.8193614e-05f, 0.00048496415f, 0.00062972215f }, { -0.0041597628f, 0.024283117f, -0.030148407f, 0.011456515f } }, { { -1.3484857e-05f, -3.7204145e-05f, -1.5660577e-05f, -2.4497955e-05f }, { -0.0068070249f, 0.0041035892f, 0.0034647689f, 0.0035918321f }, { -0.0053613309f, 0.0080593503f, 0.0028507084f, -0.0023104987f }, { 0.0048581064f, 0.0039720065f, -0.0019058129f, 0.0047295789f }, { -0.00030675956f, -0.0007787587f, -0.00025201217f, 0.00020777843f }, { -0.00026433336f, -0.0093672701f, -0.0053201627f, -0.0059632173f }, { -0.0063062815f, 0.0011995204f, 0.0001870407f, 0.0028197877f }, { -0.00053247524f, -0.00066138217f, -1.4959372e-05f, -0.00036023628f }, { 0.00027591427f, 0.00011309835f, 2.2453632e-05f, -0.00075736359f }, { 0.0015654886f, 0.0018114616f, -0.0004503446f, -8.5866048e-05f }, { 0.003501393f, 0.0037179893f, 0.008328543f, 0.013411108f }, { -0.0035136609f, -0.0015054003f, 0.0011903964f, 0.0022551358f }, { -0.0083723767f, 0.0061303554f, -0.008056962f, 0.0035035183f }, { -0.0023715655f, -0.0070468331f, -0.010219655f, -0.0057856465f }, { -0.0011406634f, -0.00021204595f, -0.001693195f, 0.0011051597f }, { 0.0011643412f, 0.00037557194f, 0.0048567739f, -0.00063996433f }, { -3.1728174e-05f, -2.9073903e-06f, -3.0243209e-06f, 2.579239e-05f }, { 0.00053152589f, 0.0029635352f, 0.0040743289f, -0.00051381046f }, { -0.0017253584f, 0.00012081524f, 0.00012243664f, -0.00063598215f }, { 0.0026711847f, -0.0020733972f, -0.0027860744f, 0.0017065643f }, { 5.7762902e-05f, 0.00092043577f, -0.0035278882f, 0.0007846087f }, { 0.0056127705f, -0.0051893669f, -0.0027072408f, -0.0025630045f }, { -0.00059289151f, -0.0004168408f, -8.8118696e-05f, -0.00073538101f }, { 0.0003388606f, -0.00094234652f, 3.013109e-05f, -0.0010532484f } }, { { -2.9013996e-05f, 6.1983083e-05f, 2.8401438e-05f, -3.4901557e-05f }, { 0.0045230474f, -0.0021369843f, -0.00422706f, -0.0018918027f }, { 0.00017586142f, 0.005389053f, 0.0071352982f, -0.0018278685f }, { -0.0012135723f, -0.0035970727f, 0.00078957165f, -0.0017065397f }, { -0.00067051937f, -1.9501585e-05f, 4.1968766e-05f, -0.0010958091f }, { -0.0015277626f, -0.0039952533f, -0.00049631478f, 0.0018042745f }, { 0.0039376754f, -0.00097834328f, 6.5894634e-06f, -0.0044189106f }, { -0.00067623039f, 0.0004690807f, 1.4532105e-07f, 0.0032984829f }, { 0.0020787449f, -0.0016586579f, -0.00062367064f, 0.0021545362f }, { 0.0016427801f, 2.6710288e-05f, 0.0016011535f, -0.00077649869f }, { 0.0039999622f, -0.0014968097f, -0.0025647576f, 0.0022783424f }, { 0.001558454f, -0.00083803058f, 0.0018955692f, 0.0010432376f }, { 0.010555722f, -0.010395022f, 0.0050354965f, -0.0016177699f }, { 0.00011370745f, -0.009328355f, -0.0063009522f, 0.0024377458f }, { -0.00024433189f, 0.00052920244f, -0.0013213352f, -0.0013503982f }, { -0.0057620093f, 0.00095391746f, -0.0034768563f, 0.00093990705f }, { 0.00012108024f, 4.1007202e-05f, 4.2193381e-05f, -0.00011043617f }, { 0.0038593696f, -0.00074282979f, -0.0093457897f, 0.00027311164f }, { 0.0021514797f, -7.8742315e-05f, -0.0018813077f, -0.0017625098f }, { 0.0038491118f, 0.00022570776f, -0.0061331041f, 0.00014956617f }, { -0.00014676603f, -0.00025053931f, 0.003376287f, -0.00014730695f }, { 0.0016439646f, 0.0060569792f, 0.00063058918f, -0.0034810156f }, { 0.00011722835f, 0.00032237223f, -0.0012556553f, -0.0006887808f }, { 0.00060814722f, 0.0003708376f, -0.00056515636f, -0.00016801817f } } }, { { { 0.99117704f, 0.98705585f, 0.98683693f, 0.9989534f }, { 0.99996564f, 0.99998924f, 0.99999903f, 0.99999247f }, { 0.99958951f, 0.99978616f, 0.99986266f, 0.99991895f }, { 0.99998953f, 0.99996298f, 0.99999443f, 0.99999506f }, { 0.99764936f, 0.9998311f, 0.99527468f, 0.99920949f }, { 0.9995611f, 0.99968788f, 0.99964679f, 0.99996442f }, { 0.99999342f, 0.99999257f, 0.99999182f, 0.99998381f }, { 0.99867384f, 0.99734987f, 0.98748052f, 0.99943657f }, { 0.99627571f, 0.99651225f, 0.99814846f, 0.99867903f }, { 0.99996323f, 0.99992981f, 0.99986298f, 0.99992859f }, { 0.99957996f, 0.99946171f, 0.99966886f, 0.99968945f }, { 0.99990668f, 0.9999318f, 0.99981943f, 0.99987754f }, { 0.99945334f, 0.99937032f, 0.99935219f, 0.99902503f }, { 0.99965614f, 0.99959957f, 0.99963092f, 0.99973552f }, { 0.9999752f, 0.99998861f, 0.99994375f, 0.99998505f }, { 0.99964293f, 0.99879278f, 0.99905795f, 0.99705307f }, { 0.99788947f, 0.99867085f, 0.99868681f, 0.99012413f }, { 0.99999581f, 0.99994351f, 0.99985991f, 0.99999955f }, { 0.99996824f, 0.99822008f, 0.99874627f, 0.99943549f }, { 0.9997877f, 0.99996904f, 0.99987919f, 0.99999103f }, { 0.99948785f, 0.99539425f, 0.99978223f, 0.99617908f }, { 0.99934875f, 0.99977032f, 0.99995357f, 0.99949949f }, { 0.99999988f, 0.99999943f, 0.99999886f, 0.99999963f }, { 0.99726107f, 0.99809817f, 0.99445842f, 0.99947091f } }, { { -2.3481737e-05f, -6.7307406e-06f, -2.8605869e-06f, -2.0372001e-06f }, { 6.6885689e-05f, 4.5630281e-06f, 3.5788218e-05f, 1.0842484e-05f }, { -4.9278613e-05f, -2.4660601e-05f, 3.1625301e-06f, 0.00019708279f }, { 1.2439158e-05f, 3.0347865e-05f, 8.6153947e-06f, 1.0887256e-05f }, { -0.00012454598f, -6.513709e-05f, -3.5853483e-06f, -3.4708286e-06f }, { -0.00013746339f, 0.00013516333f, 8.4535039e-05f, 5.693766e-05f }, { -2.3674091e-05f, -3.4690053e-06f, 5.3812265e-07f, -1.7613197e-05f }, { -0.00025790043f, 3.0475251e-05f, 2.1174795e-06f, -0.00023630753f }, { -8.8624748e-06f, 7.9175589e-06f, -2.4258477e-07f, -0.00017288313f }, { 4.0061469e-05f, 0.00069846663f, -0.00060299476f, -0.00015396968f }, { 5.0667108e-06f, 2.306363e-05f, 0.00028636884f, 3.6246633e-05f }, { 0.00032740524f, -0.00037985037f, -0.00014841039f, -0.00012676016f }, { 8.7000758e-05f, 0.00018530207f, 1.7669124e-05f, -0.00023199594f }, { 9.2332094e-05f, 0.00013487652f, 0.00034587506f, -3.8853378e-05f }, { 6.9809868e-05f, -0.00015411544f, 0.0013505166f, 1.4531796e-06f }, { -6.3782301e-05f, 4.8545135e-05f, -0.00027083794f, 4.5129465e-05f }, { 3.0912438e-06f, -3.2982361e-06f, -3.3551612e-06f, -1.7781589e-05f }, { 9.872609e-06f, -2.9944213e-05f, -4.5592652e-05f, 1.5950681e-05f }, { 1.4767773e-05f, -2.2486726e-05f, -0.00010613341f, -0.00015794394f }, { 2.4386215e-05f, -1.1610334e-05f, -4.4456294e-05f, -5.0215596e-06f }, { -4.2741558e-06f, 8.7714242e-06f, -6.6343322e-05f, 6.7010735e-05f }, { 0.00016489767f, -3.3636771e-05f, 5.1610504e-05f, 5.2803593e-06f }, { 1.1649256e-05f, 2.1169993e-05f, 1.9755999e-05f, 1.3389438e-05f }, { -0.00015815197f, -0.00014316145f, 2.6536218e-06f, -4.6846396e-05f } }, { { -3.5109783e-06f, -9.8530632e-06f, -4.5020804e-06f, 6.9233235e-08f }, { 9.9938991e-06f, -2.0914089e-06f, 3.5717699e-05f, 3.2813664e-06f }, { 0.00012938219f, 1.111062e-05f, 8.0858608e-05f, 0.00018147439f }, { 4.8657525e-06f, 8.6580257e-06f, 3.6742927e-06f, 3.5828406e-06f }, { 6.9905696e-05f, 2.0985073e-05f, 6.8866215e-06f, -4.2552499e-05f }, { 0.00012100208f, 9.7821801e-05f, 0.00013576456f, 6.3686234e-05f }, { 1.954525e-06f, -1.0727343e-06f, 5.2332444e-07f, -5.4034988e-06f }, { 0.00013699813f, -2.226833e-05f, 1.4994043e-06f, 1.7110377e-05f }, { 0.0001678261f, -0.00013844113f, -3.4281745e-05f, 5.3854072e-05f }, { -1.3018868e-05f, 0.00022176303f, 0.00016983401f, 0.00038109805f }, { 0.00019016068f, 0.00023448876f, 2.643329e-05f, 4.6842203e-05f }, { -1.2492528e-05f, -0.00059486605f, 0.00012427061f, 8.1876965e-05f }, { 8.400564e-05f, -0.00029859163f, -4.884214e-05f, 0.0002631806f }, { 0.00019907281f, 0.00014046808f, 0.00015482448f, 4.0461099e-05f }, { -0.00024349239f, 0.00081298441f, 0.00084294728f, 7.9617963e-05f }, { -6.0040835e-05f, 3.2352918e-07f, 0.00024295599f, 0.00011067283f }, { -6.0027092e-06f, 1.1975092e-06f, 1.2248893e-06f, -2.1293392e-05f }, { 1.4478736e-05f, 6.8326918e-05f, -7.8693614e-06f, 9.2888155e-06f }, { -1.6982828e-05f, 1.2094341e-05f, -3.1693808e-05f, 0.00028574477f }, { 3.4480942e-05f, 2.6556008e-05f, 0.00016193956f, -1.8966503e-06f }, { -5.7726961e-06f, 2.1091148e-05f, 5.8963955e-05f, -1.0834372e-05f }, { 0.0001214393f, 1.4174882e-05f, 0.0001371836f, 0.00021757165f }, { 1.0140226e-05f, 6.1641031e-06f, 1.0590727e-05f, 1.0893212e-05f }, { -1.7442656e-05f, 4.2353331e-05f, 7.4324714e-05f, -1.9484775e-06f } } }, { { { 3.7217719f, 3.6900797f, 3.6899881f, 3.6670816f }, { 0.067826319f, 0.16468028f, 0.083129199f, 0.1336756f }, { 0.66338737f, 0.23883566f, 0.093361469f, 0.10095622f }, { 0.27185537f, 0.20781392f, 0.32216624f, 0.29876595f }, { 2.0776462f, 2.0006156f, 2.0243138f, 2.080345f }, { 0.57695783f, 0.18015147f, -0.11440889f, 0.14229144f }, { 0.63833683f, 0.41431062f, 0.44752994f, 0.47594414f }, { 1.7890608f, 1.962584f, 1.9322155f, 1.6588331f }, { 3.0538128f, 3.108267f, 3.1001573f, 2.9593433f }, { -0.28383051f, -0.27708376f, -0.042513902f, -0.085181891f }, { 0.3873435f, 0.41697884f, 0.39625427f, 0.33250735f }, { -0.33498881f, -0.40206929f, -0.028905862f, -0.48179632f }, { 1.1875033f, 1.3535177f, 1.2526197f, 1.3337495f }, { 0.42579488f, 0.24951727f, 0.18976118f, 0.20605317f }, { -0.53212666f, -0.3861028f, -0.75685995f, -0.23411882f }, { 1.6910165f, 1.686815f, 1.5906473f, 1.6528217f }, { 4.0570657f, 4.0349492f, 4.0350332f, 4.0498099f }, { -0.017225465f, -0.032503897f, 0.46003211f, 0.21602109f }, { 1.1196901f, 1.00885f, 0.91675568f, 0.99635794f }, { -0.093891275f, 0.0809352f, -0.13783332f, 0.27130678f }, { 1.9925136f, 1.9829394f, 1.8820721f, 1.9542026f }, { 0.84563763f, 0.48476746f, 0.37907152f, 0.70267878f }, { 0.37054708f, 0.4228574f, 0.6329822f, 0.26197064f }, { 1.9618393f, 1.8405969f, 1.9440918f, 1.901629f } }, { { -5.6047186e-06f, 6.0454847e-06f, 2.8365975e-06f, 6.0894367e-06f }, { -0.00069876506f, -0.00029642785f, -0.00059516082f, -0.00025400441f }, { -0.00020850504f, -0.00012959593f, -0.00032902532f, -0.00058117893f }, { -0.00037901964f, -0.00038062016f, -0.00023777964f, -0.00033714679f }, { -5.9894351e-05f, -9.820791e-05f, -5.9867157e-06f, -6.258549e-06f }, { -0.00035424038f, -8.7146215e-05f, 3.0398362e-05f, -0.00061406521f }, { 0.00014971442f, 4.5936211e-05f, -5.6259869e-06f, 0.00013567035f }, { -0.00016180211f, 3.1840487e-06f, 3.8979157e-07f, -0.00017131994f }, { -1.9877193e-05f, 2.5768261e-05f, 9.0577543e-06f, -0.00013927462f }, { -0.0012323564f, -0.00042892846f, 7.2082106e-05f, 0.00010999853f }, { -0.00034618449f, -0.00017058897f, -0.00016535057f, -0.00096982024f }, { -0.00028039653f, -7.155747e-05f, -0.00075796707f, 0.00062756458f }, { 6.6596276e-05f, -7.9730809e-05f, -8.0686754e-05f, -2.9532397e-05f }, { -0.00084106867f, -0.00036762453f, 0.00012523548f, -0.00052789663f }, { 7.6718268e-05f, -0.0010042005f, -0.00042802983f, -0.0011951304f }, { -3.6972258e-05f, 2.1447505e-06f, -0.00035448623f, -1.0620008e-05f }, { 2.8326169e-05f, 2.2049468e-05f, 2.2640575e-05f, 1.7574827e-05f }, { -0.00014318496f, -0.0004811524f, -0.00049293303f, -0.00067646484f }, { -2.7469144e-05f, -5.9653763e-06f, -1.3998899e-05f, -0.00018475323f }, { -0.00017314302f, -0.00010954727f, -0.00040004932f, 3.31106e-05f }, { -3.6093435e-06f, -1.6125243e-05f, -4.9195648e-05f, 1.5586886e-05f }, { 0.0002059631f, -0.0004024722f, -0.00047984678f, -9.8485329e-05f }, { -0.00094100913f, -0.00073046048f, -0.00052500163f, -0.00068196784f }, { -2.2820197e-05f, -5.9454557e-05f, -6.2505468e-06f, -2.6569804e-05f } }, { { 2.6015883e-05f, 8.5398335e-06f, 3.8473185e-06f, 9.1409625e-06f }, { -0.00041459247f, -0.0001855224f, -0.00030529542f, -0.00016322166f }, { -8.8427847e-05f, -0.0002302048f, -0.00038072959f, -0.00076801295f }, { -0.00027717792f, -0.00028594346f, -0.00017910208f, -0.00027291164f }, { 2.8409311e-05f, -3.8005817e-05f, -4.2266878e-06f, -1.4520383e-05f }, { -0.0001088827f, -0.00021924377f, 3.9307406e-05f, -0.00032488556f }, { 0.00027997916f, 3.5103699e-05f, -5.7448764e-06f, 0.00010259251f }, { -4.7807894e-06f, -2.9470863e-05f, 2.6656233e-07f, -0.00014346393f }, { 0.00015527098f, -6.8528726e-05f, -1.1206714e-05f, 2.3422595e-05f }, { -0.0012763247f, -0.00051503472f, 0.00058055106f, -0.00068688488f }, { -6.1232076e-06f, -1.7073841e-05f, -0.00033533389f, -0.00078769935f }, { -0.00044113485f, -0.00027577451f, -0.0012008622f, 0.00013071136f }, { 1.834948e-05f, -0.00015615102f, -0.00016449385f, 3.6685217e-05f }, { -0.00063618257f, -0.00032641968f, -5.0281118e-05f, -0.00041378992f }, { -0.0010181884f, -0.0003871932f, -0.00050061147f, -0.0018967455f }, { -5.7650067e-05f, -5.1145774e-06f, -0.00017409773f, 1.9512036e-05f }, { 1.5838743e-05f, 2.503655e-05f, 2.5679098e-05f, 2.0053218e-05f }, { -0.00018055811f, -0.00044345237f, -7.9049557e-05f, -0.00095669161f }, { -4.98611e-05f, -1.1320605e-06f, 3.7756645e-06f, -8.7299215e-05f }, { -0.00011794063f, -0.00015778552f, -0.00036514881f, 4.7288704e-05f }, { -5.1753817e-06f, -1.5040527e-06f, -2.836739e-05f, -9.4945229e-06f }, { 0.00016873335f, -0.00031983601f, -0.00052281245f, 0.00019034815f }, { -0.0011988594f, -0.0010684975f, -0.00057577023f, -0.0009143845f }, { 5.0336006e-05f, -1.356148e-05f, 1.5582694e-05f, -2.0666272e-05f } } }, { { { 0.012207721f, 0.0044164612f, 0.0022704542f, 0.0042008503f }, { 0.29516302f, 0.139976f, 0.35038027f, 0.13748343f }, { 0.1462123f, 0.12114907f, 0.28473665f, 0.45762717f }, { 0.17976664f, 0.19141553f, 0.1209483f, 0.16393769f }, { 0.044254492f, 0.11383095f, 0.0062726904f, 0.023550537f }, { 0.14785458f, 0.10151341f, 0.045717467f, 0.42243971f }, { -0.24205201f, -0.033590842f, 0.0032064617f, -0.093924041f }, { 0.10866955f, 0.016299431f, 0.00081631108f, 0.15856447f }, { 0.10108337f, 0.057931152f, 0.024463589f, 0.21514346f }, { 0.47967783f, 0.75472932f, 0.5653649f, 0.64752457f }, { 0.30082544f, 0.15124922f, 0.23567284f, 0.47161499f }, { 0.54286166f, 0.61049777f, 0.61641378f, 0.51181399f }, { 0.39328762f, 0.25557559f, 0.25875912f, 0.22436901f }, { 0.45699569f, 0.16989563f, 0.2429263f, 0.3924359f }, { 0.92996797f, 1.1024806f, 0.78045387f, 1.2298879f }, { 0.19029829f, -0.022675055f, 0.28113642f, 0.034941166f }, { 0.013203939f, 0.013034069f, 0.013414649f, 0.011688038f }, { 0.076026927f, 0.13838472f, 0.29961655f, 0.31531564f }, { 0.089182386f, 0.010401684f, 0.029374547f, 0.22995838f }, { 0.052198894f, 0.039866726f, 0.11570972f, -0.013818992f }, { 0.0062380932f, 0.01788119f, -0.20765047f, 0.013339281f }, { 0.12436441f, 0.17318651f, 0.21554136f, 0.18600144f }, { 0.38005287f, 0.32135548f, 0.28632777f, 0.29211902f }, { 0.03798742f, 0.0450845f, 0.010912505f, 0.039060104f } }, { { 0.00077914246f, 0.00011130803f, 8.1110229e-05f, -0.00035312557f }, { 0.00051711901f, 0.00029701387f, 0.00040733345f, 0.00034149723f }, { 0.00063893978f, -0.00013702086f, 0.00030866699f, -0.00020070677f }, { 7.5899443e-05f, 9.7456273e-05f, -4.5352178e-05f, 7.6172703e-06f }, { 0.00066250814f, -0.00073033349f, 0.00015225542f, -0.0010197351f }, { 0.00040931533f, -0.00043022747f, 0.00093333285f, 0.0002579685f }, { -0.00067488578f, -0.0003706974f, -0.00044487256f, -0.00056555959f }, { 0.00075838366f, -0.0021903789f, -0.0026744174f, -0.00047135202f }, { -0.00081050821f, -0.0010297809f, -0.00099480849f, -0.00074914246f }, { 0.00063637392f, 5.248783e-05f, 0.00044645091f, 0.00018028446f }, { 0.00067430392f, 0.0004762628f, -0.00032736685f, 0.00041933609f }, { 6.2324555e-05f, -1.6709531e-06f, 0.00057418116f, -0.0010360999f }, { -0.00038256183f, -0.0010104012f, -0.00045533693f, -1.3888404e-05f }, { 0.00068274628f, 0.00068411875f, -0.00091273333f, 0.00016211145f }, { -0.00039440715f, 0.00027665323f, -0.00035895503f, 0.00013423207f }, { -0.00061939017f, 0.00012140102f, 0.00024178233f, 0.00064755788f }, { -0.00052441128f, -0.00050994483f, -0.00051126044f, 0.00066320373f }, { 0.00085915332f, 0.0013567332f, -0.00014328466f, 0.00056098523f }, { -0.0012682676f, 0.0029139719f, 0.0019812291f, -0.00053863027f }, { 0.0021895869f, 0.00062956835f, 0.0018161156f, 0.00011699452f }, { -0.0010337306f, 0.00016880497f, -0.0014942346f, -0.0034402453f }, { -0.0025336946f, -0.00019468865f, -0.00018045349f, -5.4312149e-05f }, { 0.00021491979f, 4.7651714e-05f, -0.00044921151f, 0.00046742044f }, { 0.0019408125f, 0.00044842687f, 0.0026003265f, -0.00090116109f } }, { { -0.0006591255f, 0.00022873584f, 0.00026313866f, -0.00060151354f }, { 0.00027198127f, 0.00034252944f, 0.00033246896f, 0.00035232159f }, { -0.00034460639f, -5.9085725e-05f, 7.836454e-05f, -0.00018946388f }, { 0.00018790551f, 0.0001918358f, 9.7031467e-05f, 0.00015259869f }, { -0.0023033429f, -0.0012945186f, -0.00080964072f, -0.00030432514f }, { -0.001359781f, 0.00055828912f, -0.00041912301f, 0.00019263336f }, { -0.00042789448f, -0.00018313775f, -0.00030217124f, -0.00028437496f }, { -0.0018340159f, 0.00030654336f, -0.00010781402f, -0.0011985455f }, { -0.002103478f, 0.00029492518f, -0.00042283946f, -0.001472689f }, { 0.00064558079f, 0.00049703204f, -0.00018932594f, -0.00038268301f }, { -0.00097813334f, -0.00057838807f, 0.00079268109f, 0.00039650774f }, { -0.00017335252f, 0.00074363734f, 0.0008194423f, -0.00065923207f }, { -0.00075344545f, -0.00026114262f, -0.00054658657f, -0.0013814943f }, { -0.00028279346f, 0.00055730283f, 0.00048990213f, -0.00022186466f }, { 0.00013438509f, -0.0001962818f, -0.00036195953f, 0.00042669461f }, { -0.00089003585f, -0.0011600794f, -0.0012554286f, -0.0012892408f }, { -0.00067007058f, -0.0010597247f, -0.0010590421f, 0.00044132516f }, { 0.0011626727f, 0.001261033f, -0.00072912018f, 0.00076332442f }, { -0.001204702f, -0.00011230019f, 0.00036178615f, -0.0017559004f }, { 0.00096282849f, 0.001025959f, 0.0011696947f, 0.00046633555f }, { -0.00082328571f, -0.00075771669f, -0.0011629302f, 0.00073458863f }, { -0.0016869269f, -0.00035239862f, -0.0004024204f, -0.0016276971f }, { 0.00029053123f, 0.00013409355f, -0.00049087974f, 0.00061969429f }, { -0.0013198997f, -0.0018615784f, -0.0025724061f, -0.0015563017f } } } }, { { { { -0.072246889f, -0.043157285f, 0.043289306f, 0.095998047f }, { 0.12597079f, 0.24289541f, -0.10930005f, -0.24150539f }, { 0.031889347f, -0.036238337f, -0.014521983f, -0.018963885f }, { -0.044155351f, -0.0077170425f, -0.043781059f, 0.047982339f }, { 0.093995001f, -0.0079510758f, -0.04688882f, -0.11125523f }, { 0.01700754f, -0.0034361033f, 0.055252382f, -0.053119426f }, { -0.0014957087f, -0.00063057103f, 0.037930463f, 0.017656646f }, { -0.017388477f, -0.084085888f, -0.067726647f, 0.061397079f }, { -0.070625168f, -0.061293011f, -0.077366932f, 0.11518646f }, { -0.14771316f, -0.12543895f, 0.052150789f, 0.10530462f }, { -0.03609139f, 0.001131616f, -0.039549928f, 0.03805765f }, { 0.064364205f, 0.066758929f, 0.045537002f, -0.05510954f }, { 0.049051369f, 0.098312455f, -0.01079726f, -0.11202623f }, { 0.033012208f, -0.0013996988f, -0.0049458824f, -0.028981527f }, { 0.008617177f, -0.00017670863f, -0.0052380282f, -0.0023438457f }, { -0.05901498f, -0.050754807f, -0.00011829844f, 0.037297411f }, { -0.056264446f, -0.03645315f, -0.066412698f, 0.019549244f }, { -0.11401603f, -0.11856524f, 0.12275022f, 0.11635143f }, { -0.0011999881f, -0.0016334327f, -0.0056868938f, 0.013393766f }, { 0.054526972f, 0.033632235f, 0.062591094f, -0.0025531074f }, { 0.073041316f, 0.073735243f, -0.06935254f, -0.11214186f }, { 0.034872822f, -0.015473423f, 0.037359975f, -0.026829465f }, { -0.015137592f, -0.0064462553f, 0.011771178f, 0.0025042048f }, { -0.038708904f, -0.033968131f, -0.044070885f, 0.024422773f } }, { { -0.047895007f, -0.016535938f, 0.04855533f, 0.018341613f }, { 0.004310087f, 0.01519838f, -0.0033290683f, -0.013597406f }, { 0.0015859181f, 0.016869623f, -0.019279963f, -0.01426933f }, { -0.0061048976f, 0.031131561f, 0.018085381f, -0.017927117f }, { 0.052590378f, 0.0066156852f, -0.0025756141f, -0.037241705f }, { 0.0083512619f, 0.0046235666f, 0.024122126f, -0.013443654f }, { 0.0010672274f, 0.00053123301f, -0.0016276029f, -0.04221993f }, { -0.0048754166f, -0.021474788f, -0.0039993317f, 0.011831691f }, { -0.054685347f, -0.050242732f, -0.007606251f, 0.043061893f }, { -7.5644942e-05f, 0.00086632318f, 0.0001960729f, 0.0013264286f }, { 0.0042413724f, -0.0057181522f, 0.0065940983f, -0.0078263328f }, { 0.0031260881f, -0.0013520907f, 0.025073658f, -0.010841673f }, { 0.038353769f, 0.06620308f, -0.0072105562f, -0.079188681f }, { 0.003099559f, -0.0022927921f, 0.021982683f, -0.018991144f }, { 0.012285675f, 0.0091834074f, -0.0041874571f, -0.032253924f }, { -0.014563556f, 0.009843969f, -0.010490279f, 0.012979866f }, { -0.005492286f, 0.064109426f, -0.034795617f, -0.020395732f }, { -0.023364141f, -0.059336321f, 0.080710391f, 0.038948527f }, { 0.0028384819f, 0.001822471f, 0.0012903958f, 0.012781079f }, { -0.004510518f, -0.0020008272f, 0.0017752876f, 0.0077607089f }, { 0.032279653f, 0.0041906079f, -0.034682371f, 0.0061335907f }, { -0.0082992317f, -0.025250117f, -0.017026845f, -0.028345042f }, { -0.013132125f, -0.026688493f, -0.0014827793f, -0.003236826f }, { 0.01650781f, 0.002313574f, -0.012897922f, 0.026077933f } }, { { 0.062668058f, 0.0081578851f, 0.018952049f, -0.012267283f }, { 0.0008567722f, 0.0033246009f, -0.0037620102f, -0.0096317368f }, { -0.0083012273f, 0.01184624f, -0.01209373f, 0.020208536f }, { 0.013862003f, 0.019166381f, 0.013235471f, -0.026788736f }, { -0.021904217f, -0.051018749f, 0.0020330268f, 0.006626371f }, { -0.015856131f, 0.0028024655f, -0.032825412f, -0.018920906f }, { 0.0020870233f, 0.0011616727f, -0.0032704368f, -0.027327141f }, { 0.01934969f, 0.002427195f, 0.049925128f, -0.0061414889f }, { 0.013158375f, 0.022248445f, 0.040266734f, -0.017583455f }, { 1.9024812e-05f, 0.00071602053f, 0.0012622199f, 0.0018791611f }, { -0.0011857767f, 0.0023417924f, 0.026237548f, -0.014687892f }, { -0.041419782f, 0.024942194f, -0.029143101f, 0.036590943f }, { -0.015470651f, -0.035208671f, -0.038530514f, 0.037434376f }, { -0.0029356279f, 0.0023358079f, 0.017641055f, 0.0038203652f }, { -0.0030449623f, -0.010187444f, 0.0066142145f, 0.0037433206f }, { 0.0080034603f, 0.011463159f, -0.0058129532f, 0.011831147f }, { -0.0091743137f, 0.045949289f, 0.022412137f, -0.0067531419f }, { 0.00069946656f, -0.0068974782f, 0.0091806954f, 0.0022160793f }, { -0.0027530077f, 0.00089797627f, 0.0066153093f, -0.010355635f }, { -0.019399018f, -0.0085762573f, 0.0208003f, -0.027739023f }, { -0.014354809f, -0.011971089f, -0.0031124986f, 0.044710091f }, { -0.011411144f, 0.0073253411f, -0.0087561348f, -0.014838738f }, { 0.018837992f, 0.00231775f, -0.013982978f, -0.0020044658f }, { 0.0012069362f, 0.0012202952f, 0.029106153f, 0.00062793994f } } }, { { { 0.054154158f, -0.11603661f, -0.025631275f, 0.054671866f }, { -0.2359715f, 0.093194255f, 0.21874866f, -0.08378526f }, { 0.0089903397f, 0.0087113885f, -0.015445726f, 0.011142042f }, { -0.0055372249f, -0.0041494086f, -0.033355186f, -0.010136823f }, { -0.015010227f, -0.0077144008f, 0.13058394f, -0.016779666f }, { -0.015855009f, 0.014090685f, 0.026549575f, 0.025677527f }, { -0.00065423811f, -0.0011506403f, 0.028628751f, 0.0086359197f }, { -0.010571292f, 0.035861454f, -0.025871285f, -0.024827688f }, { 0.00010603924f, 0.011433504f, -0.052819957f, -0.020208661f }, { 0.12243361f, -0.14574398f, -0.10091072f, 0.054524772f }, { -0.014659734f, -0.02291001f, 0.010102434f, -0.0099333349f }, { -0.0079939087f, 0.023468399f, 0.044548395f, 0.04568814f }, { -0.048188816f, 0.016469102f, 0.084818672f, -0.040634065f }, { 0.015089138f, 0.025396216f, 0.017000121f, 0.010820807f }, { -0.0098155552f, -0.00080001495f, 0.0020122754f, -0.00046896909f }, { -0.0018906417f, -0.03909342f, -0.020339049f, -0.024007559f }, { -0.0012744487f, -0.027829333f, -0.05202457f, -0.024366779f }, { 0.10406956f, -0.092281421f, -0.050420166f, 0.10716663f }, { -0.0049603976f, -0.0055370076f, -0.0016910106f, 0.012172389f }, { -0.0026486448f, 0.038673757f, -0.0016176887f, 0.052692494f }, { -0.03722357f, 0.055455783f, 0.067738953f, -0.0087990582f }, { -0.0026491637f, 0.017275247f, 0.010687117f, 0.020312052f }, { -0.0016032469f, 0.0090272843f, -0.0079027514f, -0.0050039898f }, { -0.0073653412f, -0.033150577f, 0.0082912493f, -0.021457881f } }, { { -0.0059001999f, 0.033600833f, 0.066374213f, -0.018058548f }, { -0.0037864945f, -0.0064946131f, 0.0018627774f, 0.0044899139f }, { 0.0048961861f, -0.0034770968f, -0.0002311598f, -0.0053935761f }, { 0.0090090757f, 0.012149811f, 0.0029969663f, 0.0049403543f }, { -0.042874682f, -0.0083455851f, -0.0064437344f, 0.0010579362f }, { 0.011866873f, -0.017157526f, -0.014724976f, 0.0054373752f }, { -0.0006329516f, -0.00024834697f, 0.0015416168f, -0.014246989f }, { 0.031530357f, -0.052715858f, -0.0063186617f, -0.0070200141f }, { -0.0082273844f, 0.053856605f, 0.0096812384f, 0.01684635f }, { -0.00017150577f, 0.00097354737f, 0.0013944706f, 0.00085166684f }, { -0.013604545f, 0.0089329355f, -0.013809086f, 0.0025044469f }, { -0.020284731f, 0.0004724419f, -0.045697697f, -0.01844702f }, { 0.017874081f, -0.0040537465f, -0.023316716f, -0.026344708f }, { 0.0092557469f, -0.014456327f, -0.0092919835f, 0.0091758924f }, { 0.016058873f, 0.0019220807f, 0.0031692823f, 0.0024577167f }, { -0.021184352f, 0.021287579f, -0.0048442696f, 0.0095799112f }, { 0.035229915f, -0.054291919f, -0.013871324f, 0.035585241f }, { 0.001275203f, 0.011513119f, 0.020184769f, -0.0061701639f }, { 0.011353237f, 0.0052697685f, 0.0047637419f, -0.020278005f }, { 0.0068266296f, -0.01173749f, 0.037482577f, -0.0083236299f }, { 0.025699221f, -0.03651135f, -0.032342446f, -0.0059784486f }, { 0.0029540635f, -0.0021598269f, 0.0028168477f, 0.0044577193f }, { 0.0038274002f, -0.0050806333f, 0.007628551f, 0.0027461742f }, { 0.0056567464f, 0.006846664f, -0.031161558f, -0.0040832656f } }, { { 0.025668431f, 0.0093723617f, 7.4324163e-05f, -0.023051436f }, { -0.010148124f, 0.0018159908f, 0.0072269566f, 0.00082671261f }, { 0.0069741056f, 0.023493533f, 0.028507618f, -0.026874125f }, { 0.0083316277f, -0.024891629f, 0.013623217f, 0.0038373532f }, { -0.020992516f, 0.070912136f, -0.0014634877f, -0.015680371f }, { 0.02178962f, -0.003772636f, -0.024578501f, -0.047467019f }, { 0.0028586275f, 0.0033445767f, 0.0049576063f, -0.017365739f }, { 0.0075721122f, 0.010652219f, -0.024031886f, -0.0001146548f }, { 0.016381176f, -0.044765924f, -0.038036229f, -0.014041395f }, { -0.00082564842f, 0.00033107944f, 0.00073792054f, 0.0005712734f }, { 0.0080934887f, 0.014534447f, -0.0071347609f, 0.0085413493f }, { -0.018211778f, 0.0064443848f, 0.017393403f, 0.011490985f }, { -0.071531366f, 0.030059694f, 0.049103287f, 0.0074609412f }, { 0.00770209f, -0.017999995f, -0.040048679f, -0.0029073853f }, { 0.020442166f, 0.0019454488f, -0.019644905f, 0.021793285f }, { 0.035171271f, 0.0080192155f, -0.023151504f, 0.014168348f }, { -0.048901887f, -0.0039613606f, 0.0021703807f, 0.030275152f }, { 0.044666116f, -0.029756153f, -0.015570779f, 0.034470632f }, { -0.0078700362f, 0.0037551741f, 0.0003070052f, -0.0031237403f }, { 0.015288427f, -0.01284757f, -0.0075319169f, 0.026981487f }, { -0.0093872483f, 0.013517073f, -0.030221944f, 0.058356065f }, { 0.0042326205f, -0.016381154f, 0.021475001f, 0.01008732f }, { 0.0034929117f, 0.020531314f, -0.0085114063f, 0.004821913f }, { 0.014314413f, 0.01127037f, -0.017197896f, 0.0046932185f } } }, { { { 0.99591552f, 0.99230689f, 0.99873374f, 0.99387895f }, { 0.96356049f, 0.96556546f, 0.96964041f, 0.96677566f }, { 0.99945097f, 0.99930521f, 0.99977525f, 0.99975808f }, { 0.99900933f, 0.99996161f, 0.99848418f, 0.99879675f }, { 0.99545951f, 0.99993863f, 0.99032786f, 0.9936502f }, { 0.99972964f, 0.99989482f, 0.99811938f, 0.99825798f }, { 0.99999867f, 0.99999914f, 0.9988702f, 0.99980681f }, { 0.99979292f, 0.99581299f, 0.99736843f, 0.99780458f }, { 0.99750292f, 0.99805433f, 0.99560254f, 0.9931383f }, { 0.98142286f, 0.98133774f, 0.99352772f, 0.9929441f }, { 0.99924096f, 0.99973689f, 0.99916652f, 0.99922617f }, { 0.99789446f, 0.9974931f, 0.99796885f, 0.99743448f }, { 0.9976331f, 0.99501931f, 0.9963379f, 0.99287411f }, { 0.99934104f, 0.99967648f, 0.99984325f, 0.99952138f }, { 0.9999147f, 0.99999966f, 0.99998426f, 0.99999714f }, { 0.99825531f, 0.99794572f, 0.99979313f, 0.99901579f }, { 0.99841509f, 0.99894779f, 0.99643504f, 0.99951192f }, { 0.98801309f, 0.98864879f, 0.99115599f, 0.98740957f }, { 0.99998698f, 0.99998334f, 0.9999824f, 0.99983621f }, { 0.99850879f, 0.99868574f, 0.99803794f, 0.99860752f }, { 0.99663402f, 0.99573479f, 0.99528974f, 0.99365325f }, { 0.99938825f, 0.99973103f, 0.99924472f, 0.99943364f }, { 0.99988413f, 0.99993848f, 0.99989949f, 0.99998434f }, { 0.99922338f, 0.99887297f, 0.998994f, 0.9994714f } }, { { -0.0050599833f, 0.003362263f, 0.0035202243f, -0.00056864904f }, { -0.0014675187f, -0.0029154981f, -0.00077796172f, -0.0027392627f }, { -0.0010916411f, 0.00078232803f, 0.0014339533f, -0.0020166729f }, { 0.011183745f, 0.008298699f, 0.011631254f, 0.00030693508f }, { -0.0012964861f, -0.00028098882f, 0.00098513135f, -0.0052243577f }, { 0.0091119501f, 0.002780703f, 0.011045274f, 0.00334383f }, { 4.1103001e-05f, 5.5767744e-05f, 0.0030605577f, 0.0022152241f }, { 0.00085375099f, 0.0026952672f, 0.0071937971f, 0.0056504112f }, { -0.003773118f, 0.0047936307f, -4.5743022e-05f, -0.0038357994f }, { 2.3815581e-05f, 0.0002468657f, 0.00013492048f, -0.00018410816f }, { 0.0070959632f, -0.00205589f, 0.0056417297f, 0.0030702073f }, { 0.010671769f, 0.0074346008f, 0.0012867659f, 0.0075437523f }, { -0.0013037272f, -0.0058374269f, 0.0025899757f, -0.0071565118f }, { 0.0030041304f, 0.0018011397f, 0.0093160386f, 0.0082062863f }, { 0.0053156934f, 0.0036543193f, 0.0048724246f, 0.0035118324f }, { -0.0053866158f, 0.0024053442f, 0.00052459148f, 0.0090970513f }, { 0.011239324f, -0.0010327051f, -0.00097551594f, 0.0044180668f }, { -0.0024379533f, -0.0088232426f, -0.012355568f, -0.0031875953f }, { 0.0026244123f, 0.0011858999f, 0.0028110843f, -0.001005442f }, { 0.0059514328f, 0.0018892606f, 0.0050231625f, 0.0046700575f }, { 0.00050741664f, 0.0096547476f, -0.00079618251f, 0.0024532112f }, { 0.0058717468f, -0.0017457656f, 0.0080261577f, -0.00048009588f }, { 0.0025457914f, 0.0016788968f, 0.0013982313f, 0.00073909928f }, { 0.0075035778f, 0.011234409f, 0.0079271096f, 0.006672353f } }, { { 0.0095152396f, 0.0011785006f, -0.00081996856f, 0.0018904938f }, { -0.0025430397f, -0.0010236291f, -0.0020168276f, -0.0021827861f }, { 0.0036295778f, 0.005406882f, 0.0040788276f, -0.0057729163f }, { -0.00029952998f, 0.0024548208f, 0.0088548836f, 0.0019084209f }, { 0.0034184324f, -0.0088925589f, 0.00023040452f, 0.00017437939f }, { 0.0037804595f, 0.012156355f, 0.0041276361f, 0.012721488f }, { 7.4846461e-05f, 0.00010580108f, 0.013483417f, 0.0024239851f }, { 0.00026411032f, -0.00059353627f, 0.0093564271f, 0.0061507538f }, { 0.0016065383f, -0.0027764641f, 0.0013620195f, 0.0010062065f }, { 9.7127925e-05f, 0.00017275393f, 1.0814607e-05f, -0.00022627793f }, { 0.0048710612f, -0.00014794569f, 0.0082832436f, -0.00072595412f }, { -0.0027392579f, 0.0066783951f, 0.00087397132f, 0.001567366f }, { -0.003378151f, 0.0025916338f, -0.0025553201f, 0.0030152022f }, { 0.0096818399f, 0.0012695523f, 0.0072489949f, 0.016881099f }, { 0.0022796191f, 0.0051693266f, 0.0023373397f, -0.0041448561f }, { -0.0002074582f, 0.0035962454f, -0.0007460719f, 0.0025086317f }, { 0.0035784996f, 0.003162753f, 0.0022592918f, 0.00024595998f }, { -0.0051294944f, -0.0041428868f, -0.0027597f, -0.0039539398f }, { 0.0022410392f, 0.00031263884f, 0.0016376751f, -0.0022787113f }, { 0.0025647038f, 0.0074733037f, 0.0051722028f, 0.0024463612f }, { 0.0011787227f, 0.0071159753f, 0.0017217143f, 0.0062717989f }, { 0.0046836737f, 0.0038976423f, 0.00062832002f, 0.0027638154f }, { 0.0014142926f, 0.0024903802f, 0.0015757227f, 0.0011628587f }, { 0.0016928585f, 0.0043828548f, 0.001653268f, 0.011450696f } } }, { { { 2.8886078f, 2.8900127f, 2.7925705f, 2.7895874f }, { 4.5455217f, 4.5284714f, 4.7042338f, 4.6915273f }, { 0.96672505f, 0.99303664f, 0.98927606f, 1.0351588f }, { 1.2743756f, 1.2525364f, 0.99649566f, 0.94572778f }, { 2.6910679f, 2.6922168f, 2.8503404f, 2.8246076f }, { 1.256075f, 1.2325025f, 1.5911826f, 1.6091223f }, { 1.3601759f, 1.3606869f, 1.2793533f, 1.240925f }, { 2.0291828f, 2.0506809f, 1.7341658f, 1.6555689f }, { 2.6663531f, 2.6921882f, 3.1290975f, 3.11849f }, { 5.3676887f, 5.3663279f, 5.3848664f, 5.3852162f }, { 1.0586431f, 1.0865889f, 0.8196623f, 0.8076665f }, { 1.6967251f, 1.7305944f, 1.5450413f, 1.6347879f }, { 3.0908857f, 3.0706775f, 3.2974343f, 3.3053965f }, { 1.2172073f, 1.3839086f, 1.5086796f, 1.4295506f }, { 0.97676668f, 1.0856738f, 0.98747912f, 1.0385491f }, { 1.5662275f, 1.4603538f, 1.784278f, 1.6575438f }, { 2.1085757f, 2.2092885f, 2.1410448f, 2.1518347f }, { 4.0214776f, 4.006424f, 3.7686967f, 3.7771354f }, { 1.2089239f, 1.2116036f, 1.1244311f, 1.0901017f }, { 1.1827246f, 1.1472796f, 1.7516784f, 1.7833976f }, { 2.2113439f, 2.197512f, 2.2692963f, 2.2787751f }, { 0.98819531f, 1.057833f, 1.3587301f, 1.3890421f }, { 1.208957f, 1.2247867f, 1.2301205f, 1.2325178f }, { 1.0499613f, 1.1319197f, 1.4067885f, 1.3209087f } }, { { -0.002860931f, -0.0033581281f, -0.0047612075f, -0.0030481839f }, { -0.0017370907f, -0.0065700936f, -0.0011051926f, -0.0046915938f }, { -0.0006126207f, 0.0010791181f, -0.022876686f, -0.015937275f }, { -0.010040922f, -0.016433531f, -0.0044976975f, -0.029838315f }, { 0.00056888968f, -0.0093450028f, -0.00041549218f, -0.0069079656f }, { -0.029781683f, -0.019722587f, 0.019472312f, 0.0016798037f }, { -0.0015128736f, -0.0012250172f, -0.0091568262f, -0.0091368119f }, { 0.0010846814f, 0.0017189068f, 0.012975603f, -0.0051530971f }, { -0.026042808f, -0.0090684857f, -0.0021498742f, -0.0032938309f }, { -0.0012792901f, -0.0010431731f, -0.0021366737f, -0.0025526365f }, { -0.03218779f, -0.013848893f, -0.021872476f, -0.029443623f }, { 0.008300061f, 0.011951182f, -0.011139414f, 0.0098292843f }, { -0.0065854884f, -0.020955083f, -9.3843515e-05f, -0.0078425688f }, { -0.054726229f, -0.0073673428f, -0.019267231f, -0.03383648f }, { -0.049769726f, 0.0065482059f, -0.010189395f, -0.0050480393f }, { 0.022565943f, -0.020311569f, 0.0091512717f, -0.015600752f }, { -0.014418429f, 0.0060070592f, -0.0055296743f, -0.003361885f }, { 8.8146509e-05f, -0.0082609252f, 0.0036746024f, 0.0040108321f }, { 0.0010230427f, 4.8153189e-06f, 0.0052893378f, -0.0096303521f }, { 0.0032909351f, -0.010982824f, 0.003880027f, 0.0097699095f }, { -0.006528317f, -0.012608887f, -0.0057088008f, -0.003867806f }, { -0.046599771f, -0.024701737f, -0.001078321f, -0.0041018649f }, { -0.021680777f, -0.021120711f, 0.0055144734f, -0.0031337995f }, { -0.030559213f, 0.0089872726f, -0.011166202f, -0.0077587071f } }, { { -0.0059548858f, -0.0040070313f, -0.0062572119f, -0.0047711065f }, { -0.0031938803f, -0.005431389f, -0.0026376521f, -0.0046119366f }, { 0.0064917253f, 0.013030824f, -0.027850471f, -0.011824849f }, { -0.032644485f, -0.025045016f, -0.0034396539f, -0.039827623f }, { -0.007691681f, -0.014095643f, -0.0008171964f, -0.0051336386f }, { -0.035626586f, -0.021424668f, 0.00035790929f, 0.0099705685f }, { -0.0019006762f, -0.0014887089f, -0.0050782898f, -0.0096835564f }, { -0.00087496879f, 0.0052586834f, 0.017041675f, -0.00046753956f }, { -0.022489507f, -0.0084834888f, 0.0017184219f, -0.0023910992f }, { -0.0010618265f, -0.00085888729f, -0.0020035777f, -0.0024245283f }, { -0.029245834f, -0.038977066f, -0.013385246f, -0.030312138f }, { -0.0028497869f, 0.014205986f, -0.0125692f, 0.0037959624f }, { -0.0086377959f, -0.019175965f, -0.007684309f, -0.005037677f }, { -0.063945685f, -0.0060751259f, -0.0057457302f, -0.019079575f }, { -0.043745147f, 0.013651906f, -0.034067394f, 0.0012111497f }, { 0.0086647574f, -0.019171418f, 0.020745219f, -0.0055629951f }, { -0.024541273f, 0.0072112135f, -0.0078821942f, -0.0085072621f }, { -0.0018227939f, -0.0021153099f, 0.008577002f, 0.0043865151f }, { -0.013984752f, -0.012209334f, 0.00023638151f, -0.0085025952f }, { -0.0099800075f, -0.0095390578f, 0.0081328135f, 0.012673433f }, { -0.0099975551f, -0.0028467616f, -0.010712056f, -0.0045012212f }, { -0.011329139f, -0.0084709831f, -0.0070232966f, 0.0015504012f }, { -0.015334801f, -0.0075637633f, -0.01107439f, -0.0094188163f }, { -0.017505269f, -0.00013701888f, -0.033955823f, -0.034192649f } } }, { { { 0.16413327f, 0.084074422f, 0.10646123f, 0.18806073f }, { 0.039511019f, 0.058967072f, 0.035166958f, 0.052296507f }, { 0.26970995f, 0.21576211f, 0.2954278f, 0.29870678f }, { 0.40442043f, 0.38744132f, 0.14502571f, 0.24076804f }, { 0.22655046f, 0.20912486f, 0.015295019f, 0.16442957f }, { 0.69235319f, 0.6080183f, 0.36756076f, 0.23314717f }, { 0.085565328f, 0.075535626f, 0.22162979f, 0.33140596f }, { 0.16109547f, 0.11961895f, 0.26619212f, 0.25941009f }, { 0.27077686f, 0.23481238f, 0.063446408f, 0.11614487f }, { 0.026116057f, 0.027491327f, 0.030421883f, 0.039965345f }, { 0.33922592f, 0.38039792f, 0.27167385f, 0.31510976f }, { 0.32744968f, 0.22567102f, 0.23116584f, 0.18867836f }, { 0.29783431f, 0.28054079f, 0.26752139f, 0.23889932f }, { 0.61721263f, 0.60602797f, 0.51283622f, 0.47601102f }, { 0.51383952f, 0.53111455f, 0.44519064f, 0.42875877f }, { 0.3485879f, 0.35374178f, 0.53292055f, 0.53995494f }, { 0.4366997f, 0.35554257f, 0.14878367f, 0.22083288f }, { 0.12855375f, 0.16718264f, 0.17583661f, 0.11125895f }, { 0.35898096f, 0.37222307f, 0.35439108f, 0.35956111f }, { 0.16773044f, 0.25668894f, 0.23246756f, 0.1506316f }, { 0.36172813f, 0.26938211f, 0.20069185f, 0.1714591f }, { 0.3998571f, 0.23607244f, 0.34121623f, 0.29126696f }, { 0.31471307f, 0.29500525f, 0.39451396f, 0.40013999f }, { 0.29554399f, 0.28083636f, 0.47190649f, 0.47892938f } }, { { 0.01419653f, -0.061214452f, -0.032506906f, 0.0078227125f }, { -0.015799432f, 0.0136148f, -0.0090824684f, 0.013638505f }, { 0.023848919f, 0.022034707f, 0.022812846f, 0.022790329f }, { -0.0026324255f, -0.0053566952f, 0.00027470228f, 0.050203583f }, { 0.0035659857f, -0.02015272f, -0.039043616f, 0.054511651f }, { 0.0052075445f, 0.0051043119f, -0.011801097f, -0.0074336577f }, { 0.020735195f, 0.01811747f, 0.00808952f, 0.01140964f }, { -0.0073139049f, 0.011075347f, 0.0057685988f, 0.010251582f }, { 0.024813488f, -0.01629986f, -0.012536791f, -0.01110061f }, { -0.014508648f, -0.021444084f, -0.023836972f, -0.014258253f }, { 0.0079687141f, -0.00092011446f, 0.060249601f, 0.033199468f }, { -0.020822483f, -0.013924875f, -0.005068391f, -0.016928794f }, { -0.030059f, -0.013887475f, -0.045329289f, -0.04449219f }, { 0.007264541f, 0.0015213919f, -0.0066322618f, -0.0036449174f }, { 0.0057175046f, 0.0012159867f, -0.00054271896f, 0.0020625484f }, { 0.0027083179f, -0.0012554897f, -0.0044854592f, -0.0045242423f }, { -0.017906563f, -0.028301884f, -0.010139427f, 0.0035851304f }, { -0.020245794f, 0.01149232f, 0.011320484f, -0.013561794f }, { 0.0068048997f, 0.011957759f, 0.0046962412f, -0.0015476541f }, { -0.0022514613f, 0.019996868f, 0.0051520398f, -0.023405604f }, { 0.0055213198f, 0.0070384134f, 0.024405643f, -0.02050399f }, { 0.039987541f, 0.021127504f, -0.012323503f, -0.0041538161f }, { 0.0072321478f, 0.0053097351f, 0.0039966161f, 0.013617175f }, { 0.030470642f, 0.0044694115f, -0.0024591651f, -0.0027274707f } }, { { -0.040500402f, -0.039657034f, -0.017497359f, -0.017857145f }, { -0.0015646885f, -0.020957371f, -0.0057356498f, -0.0060587007f }, { 0.0070388709f, -0.013205178f, -0.00033412934f, 0.02192306f }, { -0.0042317723f, 0.020620857f, -0.012309167f, 0.065948811f }, { -0.016686589f, 0.013616667f, 0.030139062f, -0.019023551f }, { 0.015181564f, 0.008673659f, -0.0014559576f, -0.025916054f }, { 0.031630671f, 0.027030197f, -0.026982415f, 0.025214731f }, { -0.003845127f, -0.00062884599f, -0.029488655f, -0.0051457939f }, { -0.0032476351f, 0.0021153707f, -0.033110808f, -0.033629213f }, { -0.0064637077f, -0.010805748f, -0.014982403f, -0.0084641529f }, { 0.0087766042f, 0.017780238f, 0.026838871f, 0.032580257f }, { 0.0010700985f, -0.037414784f, -0.0053773565f, 0.0040969752f }, { -0.02637392f, -0.050236074f, -0.048422986f, -0.069357813f }, { -0.0089483588f, 0.0026259727f, 0.0040142797f, -0.010752754f }, { -0.0025658872f, 0.0071106029f, 0.015467367f, 0.0012536589f }, { -0.0037247444f, -0.0036991733f, -0.015429566f, -0.016148852f }, { -0.024788221f, -0.045938054f, -0.028679471f, 0.011593494f }, { -0.032699114f, -0.036800967f, -0.033870575f, -0.031842203f }, { 0.018156047f, 0.02457546f, 0.0209432f, 0.015057433f }, { 0.0043152638f, 0.025831372f, -0.019608349f, -0.026614397f }, { -0.0057047815f, -0.013831909f, 0.027613211f, -0.043616864f }, { 0.014124478f, -0.010786326f, 0.010775415f, -0.023241344f }, { 0.018337827f, 0.0048735321f, 0.018371717f, 0.022106807f }, { 0.013619207f, 0.022051384f, 0.0082720974f, -0.0030262071f } } } }, { { { { 0.083322661f, 0.079807165f, 0.03660117f, -0.051657142f }, { -0.099216074f, -0.0080141573f, 0.10637241f, 0.0367403f }, { 0.20813681f, -0.0001361621f, -0.20762563f, -0.085913357f }, { -0.22091149f, 0.10003156f, -0.16122219f, 0.31542901f }, { 0.16226908f, 0.02665194f, -0.012123307f, -0.16559939f }, { -0.14025496f, 0.025804505f, 0.076174345f, 0.20548591f }, { 0.0035713609f, -0.0092551928f, -0.099937652f, 0.0038879391f }, { 0.12405732f, -0.0053373497f, -0.030865175f, -0.060934551f }, { -0.0060175826f, -0.026583926f, -0.075326797f, -0.0063155886f }, { 0.036389362f, 0.054175433f, 0.06490927f, -0.038784258f }, { 0.30604876f, -0.030813476f, 0.011402956f, -0.21074796f }, { -0.31769497f, 0.046793931f, -0.038212559f, 0.21137297f }, { 0.12952945f, 0.20720126f, 0.08525845f, -0.14568109f }, { -0.09735197f, -0.17799099f, -0.12256082f, 0.038889119f }, { 0.002114572f, 0.026037779f, -0.0036772795f, 0.13478173f }, { 0.094577863f, 0.0057382415f, -0.087017736f, -0.059444148f }, { 0.054953104f, 0.071323301f, 0.097417831f, 8.3254475e-05f }, { -0.11005534f, 0.027214076f, 0.0059378205f, 0.02443999f }, { 0.27096654f, 0.1864966f, 0.034810947f, -0.25886676f }, { -0.35626794f, 0.037256657f, -0.17795321f, 0.52988269f }, { 0.14913899f, -0.0086988732f, -0.028760192f, -0.21779266f }, { -0.16010301f, -0.17699785f, 0.017269826f, 0.17878541f }, { -0.0049504093f, -0.02387924f, -0.04034852f, -0.060461173f }, { 0.10405347f, 0.0072745723f, -0.10244372f, -0.072981984f } }, { { 0.019363393f, 5.327311e-05f, 0.0075925373f, 0.0019542034f }, { -0.051707557f, 0.06554253f, 0.0050626046f, -0.0061857803f }, { 0.022891698f, 0.014872273f, -0.020436928f, 0.0069081531f }, { -0.044566611f, 0.019854557f, 0.023600607f, -0.0055387351f }, { 0.02283957f, -0.067086756f, 0.088865856f, -0.033915007f }, { 0.0020254431f, -0.16422426f, 0.032495902f, 0.012460808f }, { -0.017316175f, 0.023440087f, 0.011459595f, 0.0043887872f }, { 0.027714908f, -0.06907548f, 0.013578806f, -0.009848884f }, { 0.0044782488f, 0.0079432606f, 0.010143137f, 0.023589488f }, { 0.014325082f, 0.0075465848f, -0.0079373813f, -0.0056032635f }, { 0.025123579f, 0.01904807f, -0.0092328848f, -0.019002052f }, { -0.02633985f, -0.019560519f, -0.065544737f, 0.0073352606f }, { 0.044308433f, -0.0032233834f, 0.01324206f, -0.00047128106f }, { -0.076577611f, -0.021853603f, -0.020190543f, 0.0026420865f }, { -0.0029799448f, -0.0083566545f, 0.14896601f, 0.0078617095f }, { 0.021033237f, -0.08234711f, -0.020642328f, -0.0089829962f }, { 0.043793881f, 0.0096494147f, 0.035831274f, -0.01294602f }, { -0.014064874f, 0.066144489f, 0.0143429f, 0.015113964f }, { 0.043111732f, 0.0029232804f, -0.016912145f, 0.012142059f }, { 0.0014186333f, -0.0078590166f, 0.065781153f, -0.038375123f }, { 0.02255714f, -0.030191796f, -0.078373164f, -0.0017593196f }, { -0.033878798f, 0.016266579f, 0.013539653f, 0.043519216f }, { 0.019046482f, 0.0080403173f, -0.0010755939f, 0.03305222f }, { 0.023206448f, -0.054323067f, -0.035173093f, -0.010873592f } }, { { 0.014068291f, -0.026418786f, 0.016375695f, 0.0048801469f }, { 0.024404214f, 0.0073572002f, -0.027247654f, 0.00093849398f }, { 0.012741523f, -0.012913063f, 0.0054881373f, -0.021780769f }, { -0.020497215f, 0.057437717f, 0.0031122704f, 0.014713732f }, { 0.012765254f, -0.052846334f, 0.048042201f, 0.0016578534f }, { 0.031245254f, -0.0469321f, -0.057199738f, 0.012436479f }, { -0.0022837759f, 0.0068501747f, 0.010541107f, -0.0005227683f }, { -0.0187059f, 0.0025631581f, -0.0082184266f, 0.0026294483f }, { 0.0053899388f, -0.0199458f, 0.0023448066f, 0.016215236f }, { 0.021117204f, 0.010868775f, -0.016412681f, -0.016399297f }, { -0.0026199223f, -0.011436548f, 0.0031355049f, 0.011933919f }, { 0.017940023f, 0.090292392f, -0.061029038f, 0.016388845f }, { 0.0074493061f, -0.045849358f, -0.082612855f, 0.025851315f }, { 0.061276666f, -0.024654813f, 0.035447334f, -0.025952766f }, { -0.0068267167f, -0.02207426f, 0.003724368f, 0.0070458116f }, { 0.021714649f, -0.017552721f, -0.037105408f, 0.024398534f }, { 0.0092901891f, -0.021559075f, 0.009034776f, -0.016574279f }, { -0.017218595f, -0.041930302f, 0.003369899f, 0.017959363f }, { -0.0022510875f, 0.028106616f, -0.042936548f, -0.041948028f }, { -0.017145551f, -0.032331654f, 0.021486923f, -0.020295391f }, { -0.023196465f, -0.088353584f, 0.010086154f, 0.018689553f }, { -0.024508386f, -0.00058959302f, -0.02867958f, 0.019018994f }, { 0.0088748911f, 0.012528454f, -0.016636351f, 0.0078166115f }, { 0.00066772723f, 0.001693912f, 0.032066885f, 0.016951148f } } }, { { { 0.015200105f, 0.071414961f, -0.020616434f, 0.0063982643f }, { -0.084578144f, -0.12318522f, -0.035470756f, 0.057833574f }, { 0.19487946f, 0.44043059f, 0.10981527f, -0.31907303f }, { -0.17774238f, -0.30460726f, -0.53133003f, 0.31186606f }, { -0.1172677f, 0.3183613f, 0.10375266f, -0.066515168f }, { 0.054176263f, -0.12382077f, -0.033807438f, 0.039809238f }, { -5.3634009e-05f, 0.004084452f, 0.005103199f, -0.060697866f }, { 0.06093199f, 0.060355274f, 0.049176467f, -0.060579228f }, { 0.054611799f, 9.0520863e-05f, -0.048891261f, -0.047609349f }, { -0.036428706f, 0.06336736f, 0.0020843807f, 0.033254378f }, { 0.26975732f, 0.51328693f, 0.29976157f, 0.049031141f }, { -0.28383516f, -0.48219276f, -0.27898799f, -0.033028759f }, { -0.078976834f, 0.14077934f, 0.098587186f, 0.051336328f }, { 0.076281206f, -0.074223398f, -0.053178835f, -0.099578331f }, { -0.056377095f, -0.00066113896f, -0.11597726f, 0.058805777f }, { -0.0027130032f, 0.12007881f, 0.0081935835f, -0.10415807f }, { -0.019349408f, 0.06206561f, -0.0079099126f, 0.079363093f }, { -0.059959607f, -0.0591041f, -0.047505451f, -0.0031496967f }, { -0.11419194f, 0.20904287f, 0.53960104f, 0.10467592f }, { -0.21312862f, -0.34770872f, -0.54593093f, 0.23230512f }, { -0.073229448f, 0.12913f, 0.27728133f, -0.050627706f }, { 0.082312471f, -0.24529296f, -0.12381516f, 0.05577292f }, { 0.03015389f, -0.0015805638f, 0.024306632f, -0.080697961f }, { 0.061367564f, 0.056058289f, 0.041197211f, -0.015551356f } }, { { -0.029269776f, -0.030251548f, 0.01352869f, 0.0084860712f }, { 0.053983187f, 0.047657625f, -0.026379004f, 0.022474039f }, { 0.011898439f, 0.045120742f, -0.024430477f, -0.081318878f }, { -0.0012641508f, -0.018495044f, -0.030127865f, -0.0088483264f }, { 0.040728292f, 0.010691761f, -0.023566342f, 0.028045232f }, { 0.014593998f, 0.0047006468f, -0.049032498f, -0.011446808f }, { 0.00045433705f, -0.0030610749f, -0.010359449f, -0.0026455857f }, { -0.0026794352f, -0.032142744f, 0.010153936f, -0.0034586152f }, { 0.0097198782f, 0.0051005644f, 0.03482872f, -0.0043676475f }, { -0.0012381415f, -0.025746274f, -0.0081178021f, 0.0041481596f }, { -0.01598781f, 0.0048815642f, 0.06313106f, -0.0062291669f }, { 0.072970618f, -0.041153529f, -0.007457013f, 0.059776924f }, { 0.0024768493f, 0.0093018711f, 0.024827984f, 0.043842172f }, { -0.012927661f, -0.023256709f, -0.0035951539f, -0.069710027f }, { 0.0064149713f, 0.0019783425f, 0.010135188f, 0.019449636f }, { -0.0071551675f, 0.015761815f, 0.0086309278f, 0.038854386f }, { 0.020978109f, -0.0056696814f, 0.0025526797f, -0.017352926f }, { -0.010711116f, -0.0097050903f, 0.0022304504f, -0.0039308489f }, { 0.036904234f, 0.025927127f, 0.028330671f, 0.051193417f }, { -0.00076391153f, -0.077528792f, -0.029763477f, 0.0033945843f }, { -0.01775202f, 0.034507636f, 0.065392848f, -0.017840909f }, { -0.019567742f, -0.019880035f, 0.055214211f, -0.02206159f }, { 0.01110111f, 0.0022938832f, -0.011417507f, 0.017692635f }, { 0.050208493f, -0.028178909f, 0.0065276591f, -0.0056267473f } }, { { 0.0065622702f, -0.0012303136f, -0.0081183663f, 0.00079383048f }, { 0.030775912f, 0.052260356f, -0.019758331f, -0.020044147f }, { 0.019016537f, -0.043070451f, 0.035298744f, -0.040592775f }, { 0.010468089f, 0.00057085185f, 0.0081761984f, 0.0033382478f }, { 0.047189462f, -0.052695409f, 0.021849623f, 0.033585939f }, { 0.0012065616f, -0.050287476f, -0.065085924f, -0.039012886f }, { -0.012294892f, 0.006839242f, 0.0051165438f, -2.0711078e-05f }, { -0.03292822f, 0.015299577f, 0.0029119931f, 0.0073040242f }, { -0.0086784873f, 0.0085910164f, -0.0059378411f, -0.010259049f }, { -0.014191355f, -0.011172486f, -0.01299927f, 0.015386671f }, { 0.040453224f, -0.041489173f, 0.015047889f, 0.064340197f }, { -0.020000046f, 0.058477092f, -0.0018150465f, 0.048536972f }, { -0.006105982f, 0.03437044f, 0.0087640339f, 0.032868283f }, { -0.027120362f, 0.016579996f, -0.01708524f, 0.011178424f }, { 0.030535528f, 0.0058718219f, -0.031240404f, 0.024241052f }, { 0.003729958f, -0.055735848f, -0.0055392842f, 0.03447519f }, { -0.04084502f, -0.01227488f, 0.0062970198f, -0.021996031f }, { 0.053671675f, -0.067787009f, 0.0053426012f, -0.0080796738f }, { -0.021911856f, 0.038395527f, -0.07713235f, 0.024805484f }, { -0.0034319194f, 0.0052741327f, 0.026402991f, 0.0012916612f }, { -0.033119652f, -0.0046506889f, 0.045613946f, -0.050230593f }, { -0.0054612035f, -0.033482221f, 0.084267507f, -0.0224334f }, { -0.0063348693f, -0.0074524817f, -0.0029629355f, 0.035493958f }, { -0.0073519185f, 0.045139911f, 0.0022901735f, -0.041385515f } } }, { { { 0.99640669f, 0.99424882f, 0.99911727f, 0.99864438f }, { 0.99146493f, 0.99235134f, 0.99369348f, 0.99764995f }, { 0.95848895f, 0.89778665f, 0.9720248f, 0.943828f }, { 0.95896077f, 0.9472107f, 0.83168251f, 0.89623886f }, { 0.97975356f, 0.94759472f, 0.99452924f, 0.98394744f }, { 0.98863213f, 0.99196902f, 0.99652121f, 0.97785007f }, { 0.99999362f, 0.99994883f, 0.99498061f, 0.99814861f }, { 0.99040248f, 0.99816269f, 0.99831309f, 0.99630173f }, { 0.99848953f, 0.99964658f, 0.9959596f, 0.99884607f }, { 0.9986735f, 0.99651874f, 0.99788899f, 0.99869411f }, { 0.91299789f, 0.85766372f, 0.953946f, 0.97631002f }, { 0.90471405f, 0.87481454f, 0.959534f, 0.97684726f }, { 0.9884254f, 0.96811612f, 0.9914694f, 0.98799879f }, { 0.99232241f, 0.98122887f, 0.99103524f, 0.99426948f }, { 0.99840731f, 0.99966074f, 0.99324506f, 0.98912879f }, { 0.99551377f, 0.99274778f, 0.99617307f, 0.9927827f }, { 0.99830144f, 0.99552039f, 0.99521214f, 0.99684577f }, { 0.99211525f, 0.9978808f, 0.99885333f, 0.99969634f }, { 0.95579147f, 0.95995838f, 0.84120087f, 0.96022443f }, { 0.90975235f, 0.9368621f, 0.81871367f, 0.8156339f }, { 0.98610091f, 0.99158952f, 0.96035822f, 0.97468107f }, { 0.98366238f, 0.9531543f, 0.99215501f, 0.98230604f }, { 0.99953301f, 0.9997136f, 0.99888998f, 0.99490315f }, { 0.99267663f, 0.998401f, 0.99388534f, 0.99721201f } }, { { -0.0021537732f, 0.010607958f, -0.0066166595f, -0.0027390442f }, { -0.0069401807f, 0.0053215201f, 0.0062121114f, 0.013403291f }, { -0.0035740125f, -0.021839368f, 0.00042431197f, -0.029478899f }, { -0.007886159f, -0.0087705321f, -0.010570968f, 0.0040635318f }, { -0.0021772698f, 0.00025306776f, -0.0092725896f, -0.0075657706f }, { -0.010438319f, -0.0072866821f, 0.009272756f, 0.0043932916f }, { -0.00058203184f, 0.0081284104f, 0.027749999f, 0.0035426599f }, { -0.003604276f, -0.012244348f, 0.0072177908f, 0.0026686264f }, { 0.011192179f, 0.0069527119f, 0.017278396f, -0.0053058312f }, { -0.020276487f, -0.0063228657f, 0.013968347f, -0.0021534789f }, { -0.0037534313f, 0.00061399133f, -0.02126817f, 0.0085256452f }, { 0.015620795f, -0.022637876f, 0.00069280338f, 0.0054369037f }, { 0.0095244184f, -0.0026896982f, -0.0057963534f, 0.0067237437f }, { -0.0085689961f, -0.004816024f, -0.00088793436f, -0.0034021999f }, { 0.015428153f, 0.019777562f, -0.011217833f, 0.0095744159f }, { -0.003802304f, 0.0022643577f, 0.0054254827f, 0.025560756f }, { -0.0053298651f, 0.021621993f, -0.01864184f, 0.019120967f }, { 0.015380344f, -0.0027384467f, 0.0010235928f, 0.0062792725f }, { -0.001166873f, -0.0049586656f, -0.014850883f, 0.00057841904f }, { 0.0032865456f, -0.033386196f, 0.0032068954f, 0.02854738f }, { 0.010308266f, -0.000233004f, -0.020287643f, 0.0044441043f }, { -0.0040523345f, 0.0050367711f, 0.01627907f, -0.010032412f }, { 0.0073463987f, 0.00073274858f, 0.002814661f, 0.030221018f }, { 0.0057509063f, -0.011441338f, 0.01894259f, 0.0077856453f } }, { { -0.0053054924f, 0.0037677068f, 0.0066263851f, 0.0011220287f }, { -0.02212139f, 0.013769097f, -0.0013834097f, 0.014152363f }, { -0.0008493126f, 0.021473024f, -0.0039313241f, -0.017764981f }, { -0.00081897848f, -0.0074161164f, 0.0038179092f, -0.0035760615f }, { 0.014045643f, 0.015317904f, 0.0045966739f, 0.0075917156f }, { 0.0035574126f, -0.00017773424f, -0.0010937491f, -0.0017762282f }, { 0.0072018344f, 0.012586227f, 0.0138702f, -0.0085424173f }, { -0.0055783456f, -0.019909385f, 0.01190919f, -0.0065821489f }, { 1.7402026e-05f, 0.0094513341f, 0.015333305f, -0.0072158969f }, { -0.0063049905f, 0.0021776758f, 0.014376378f, 0.0072426401f }, { -0.0078049673f, 0.028764242f, -0.0024169449f, 0.0077604105f }, { 0.00047536469f, 0.029806623f, 0.0017798261f, 0.00087410198f }, { -0.0030498401f, 0.0044874501f, 0.0020382571f, -0.0011101062f }, { -0.0057084397f, -0.0013428994f, -0.001024136f, 0.0066188614f }, { 0.039201052f, 0.015120258f, -0.0082642793f, 0.0051985023f }, { -0.0091203243f, 0.020790215f, 0.0025270937f, 0.020092044f }, { -0.0029830063f, 0.006602841f, -0.00833601f, 0.044852353f }, { 0.025206353f, -0.0038915173f, 0.00045914851f, 0.0037840538f }, { 0.0014814254f, -0.011573911f, 0.046232337f, -0.015228958f }, { -0.0071984443f, 0.0090004063f, 0.022942838f, 0.016019787f }, { 0.0050929336f, 0.0060892107f, -0.0061771339f, 0.0047850766f }, { -0.011634853f, 0.0010276548f, 0.022396644f, -0.0021248711f }, { -0.012943002f, 0.0016430074f, 0.02034928f, 0.024289705f }, { 0.0051047037f, 0.010052556f, 0.0020923265f, -0.019043181f } } }, { { { 2.1627647f, 2.1788232f, 1.9290264f, 1.8457806f }, { 2.526488f, 2.3020441f, 2.538915f, 2.03484f }, { 3.9987521f, 4.3952121f, 3.906821f, 4.1693278f }, { 4.0400466f, 4.1069844f, 5.2512999f, 5.4283264f }, { 3.0141968f, 3.3306035f, 3.2224806f, 3.2473051f }, { 2.9840674f, 3.1294685f, 3.2964833f, 3.2929246f }, { 1.8346741f, 1.8637353f, 2.3037966f, 2.0860888f }, { 2.691236f, 2.6068079f, 1.9349032f, 2.1632935f }, { 1.9231956f, 1.7251627f, 2.1609654f, 2.1155629f }, { 2.165771f, 2.1908952f, 1.777038f, 2.0223741f }, { 4.5166991f, 4.8674508f, 3.918546f, 3.378087f }, { 4.4502295f, 4.5429338f, 3.9552598f, 3.3580272f }, { 3.0973598f, 3.3953852f, 2.2704362f, 2.6488177f }, { 3.2110537f, 3.3104376f, 2.515002f, 2.3267785f }, { 1.8303675f, 1.7094345f, 3.1787979f, 2.5960104f }, { 2.4391795f, 2.8730077f, 2.3730261f, 2.1545299f }, { 2.2130903f, 2.1899209f, 2.4997355f, 1.9058674f }, { 2.6472893f, 2.5455636f, 2.1164596f, 1.8341163f }, { 3.9428283f, 4.0433678f, 4.5430063f, 4.2482776f }, { 4.1941673f, 4.28852f, 4.64044f, 4.6644567f }, { 3.0873642f, 2.649364f, 3.6026133f, 3.2426354f }, { 3.2415154f, 3.5406745f, 3.2976852f, 3.3100246f }, { 1.8400289f, 1.8404692f, 1.889289f, 2.0125184f }, { 2.7063995f, 2.7229173f, 2.6289878f, 2.4313709f } }, { { -0.015335928f, -0.043382119f, -0.0054163805f, -0.028249934f }, { -0.017200109f, 0.0027582413f, -0.079612821f, -0.0013966663f }, { -0.027233584f, -0.018783395f, -0.01183278f, -0.020918937f }, { -0.0036358348f, -0.015712206f, -0.0089146421f, -0.0057117233f }, { 0.020392865f, 0.017743746f, -0.068597326f, -0.030425581f }, { -0.041123673f, -0.020767538f, -0.0087941887f, -0.0065248183f }, { -0.0055478408f, -0.00082196865f, 0.0088521402f, -0.045916836f }, { -0.010506485f, 0.0078523247f, -0.030002306f, -0.0015085765f }, { 0.01894068f, -0.012424968f, -0.034837214f, -0.045009941f }, { -0.045299587f, 0.02630478f, -0.017175711f, -0.043601235f }, { -0.046003661f, -0.020588165f, 0.034398873f, -0.054653787f }, { -0.0042534368f, 0.01325834f, -0.0036369576f, -0.079162988f }, { -0.028728556f, 0.0051289128f, 0.012104313f, 0.010686997f }, { -0.066337767f, 0.00059928728f, -0.080303668f, 0.011318772f }, { -0.031879871f, 0.0011317962f, -0.050259029f, 0.0031596552f }, { -0.090121238f, -0.011196084f, -0.072456123f, -0.00079731072f }, { -0.024243475f, 0.021401076f, -0.018209385f, -0.0083196072f }, { -0.079888701f, 0.0032806631f, -0.12762259f, -0.04652308f }, { 0.031806075f, -0.034165157f, -0.015255921f, -0.049164663f }, { -0.0012051123f, 0.030788487f, 0.022291919f, 0.0025694519f }, { 0.035836509f, 0.0055365388f, 0.026704836f, 0.0001547235f }, { -0.012129747f, -0.0094322145f, -0.040637935f, -0.12125388f }, { -0.027044986f, 0.04531553f, -0.033484589f, -0.0059927923f }, { 0.0067188802f, -0.051166351f, -0.048822794f, -0.025926988f } }, { { 0.022049053f, 0.021265778f, -0.040370641f, -0.036232952f }, { -0.0058098424f, -0.0042264198f, -0.077428509f, -0.04241654f }, { -0.0026825379f, -0.029453318f, -0.016181275f, -0.028320229f }, { -0.012541692f, -0.01345735f, 0.00037814888f, -0.0046052489f }, { -0.026527394f, 0.020033638f, -0.025683861f, -0.084207169f }, { -0.0010459945f, -0.036745215f, -0.039772051f, 0.024810839f }, { 0.012134618f, 0.0068515798f, -0.035286972f, 0.043129595f }, { -0.077093357f, -0.026872688f, 0.032800133f, -0.090326706f }, { 0.13930909f, 0.0081274014f, -0.08349188f, -0.012200005f }, { -0.091693797f, -0.012567011f, -0.069736822f, -0.0061444184f }, { -0.053061301f, 0.003642159f, 0.0052515175f, -0.036957472f }, { 0.0043493933f, -0.013069332f, -0.014708126f, -0.032765039f }, { -0.016116105f, -0.022907609f, -0.043503106f, -0.013266465f }, { -0.072759977f, -0.077354585f, 0.0043827591f, -0.013821612f }, { -0.032399073f, -0.045305037f, -0.021840791f, 0.073996542f }, { -0.057239255f, -0.056581235f, -0.038880927f, 0.044102943f }, { -0.026951489f, -0.088667645f, -0.013659704f, 0.033527579f }, { 0.034815442f, -0.028634059f, -0.036666529f, 0.011546036f }, { 0.026688447f, -0.0081892129f, -0.031138092f, -0.041739155f }, { 0.0015665701f, -0.012701682f, 0.0013533943f, -0.002849785f }, { 0.032994636f, 0.008802974f, 0.019032649f, 0.0039042621f }, { -0.044544917f, 0.0093201326f, -0.017968915f, 0.01936344f }, { -0.034794535f, 0.043032983f, -0.051072531f, -0.040148303f }, { -0.0030398597f, -0.027112065f, -0.064007483f, -0.01798277f } } }, { { { 0.22040906f, 0.24911942f, 0.41660708f, 0.23632869f }, { 0.25894466f, 0.1416669f, 0.41902981f, 0.35717608f }, { 0.26918091f, 0.14566759f, 0.2147652f, 0.15769391f }, { 0.22500921f, 0.12113361f, 0.11151768f, 0.12348609f }, { 0.25699055f, 0.056819107f, 0.3859882f, 0.4585378f }, { 0.7304995f, 0.20719358f, 0.44455636f, 0.42226989f }, { 0.43602897f, 0.51049581f, 0.41978824f, 0.62521039f }, { 0.42004119f, 0.52912054f, 0.33314238f, 0.38257921f }, { 0.55092562f, 0.43085653f, 0.31149977f, 0.34391138f }, { 0.40391149f, 0.48820255f, 0.13569806f, 0.36060266f }, { 0.13647907f, 0.12061002f, 0.20668806f, 0.30221394f }, { 0.15583476f, 0.13133696f, 0.22775202f, 0.35653823f }, { 0.56336195f, 0.25684627f, 0.11118383f, 0.23109245f }, { 0.45430401f, 0.42843367f, 0.25496534f, 0.097473509f }, { 0.3420223f, 0.39418925f, 0.26458947f, 0.30588082f }, { 0.51345558f, 0.3612731f, 0.41151773f, 0.25269512f }, { 0.29195176f, 0.42659964f, 0.47971993f, 0.32714756f }, { 0.49222777f, 0.28477645f, 0.74993827f, 0.43781271f }, { 0.098434481f, 0.31164923f, 0.14486345f, 0.11466693f }, { 0.070833248f, 0.20569754f, 0.10233576f, 0.047352701f }, { 0.51050902f, 0.15597643f, 0.1417112f, 0.35581415f }, { 0.48261165f, 0.14592221f, 0.62554576f, 0.5209765f }, { 0.33562628f, 0.39920067f, 0.28183433f, 0.297464f }, { 0.366851f, 0.59278666f, 0.59095922f, 0.48385165f } }, { { 0.13792051f, 0.072076744f, 0.094800532f, 0.026318377f }, { 0.13607414f, -0.061382542f, 0.061800151f, -0.020060553f }, { 0.028096406f, 0.069282616f, 0.010195109f, -0.010461141f }, { 0.018651237f, 0.02642439f, 0.0077552848f, -0.051151646f }, { 0.098299803f, -0.0085081153f, -0.011764584f, 0.087405711f }, { 0.064082346f, -0.04626424f, -0.071480607f, 0.064447268f }, { 0.022766233f, 0.0167542f, -0.021285286f, -0.071637286f }, { -0.0202445f, 0.011692601f, 0.048325551f, 0.0097755172f }, { -0.027775183f, 0.016463115f, 0.060050391f, -0.034226107f }, { 0.019412547f, 0.059977501f, -0.0041737169f, 0.031539317f }, { 0.013192979f, 0.036015595f, -0.049943198f, 0.014112312f }, { -0.013272349f, 0.035821037f, -0.060503687f, 0.095316821f }, { 0.038338785f, -0.059038809f, -0.044954172f, -0.00051347307f }, { -0.039594082f, 0.018205882f, 0.13413799f, 0.012292954f }, { 0.015177594f, -0.0082493854f, 0.00029420179f, 0.010356248f }, { 0.100271f, -0.13623174f, 0.1121235f, 0.068902399f }, { 0.025189636f, 0.0014918434f, 0.0088847718f, -0.053714493f }, { 0.06487698f, -0.097217547f, -0.069537353f, 0.032490984f }, { -0.030729608f, 0.048956315f, 0.016036034f, 0.022485239f }, { 0.049839618f, 0.01148525f, -0.021032427f, -0.019665817f }, { -0.0037762817f, -0.030422275f, -0.062343207f, 0.057994884f }, { 0.014035184f, -0.021387762f, -0.080846143f, -0.020681511f }, { -0.03594567f, 0.026862531f, 0.078975557f, -0.034056659f }, { -0.014490672f, 0.026128902f, 0.045617611f, 0.090192953f } }, { { 0.011904288f, -0.014624471f, 0.042023114f, 0.019592867f }, { 0.032705848f, 0.00038558691f, 0.031901745f, 0.027208951f }, { -0.044369719f, -0.039761364f, -0.013366816f, -0.019308126f }, { -0.019051023f, -0.00015767269f, -0.082968285f, -0.035266053f }, { -0.004775162f, 0.010889271f, 0.0089521094f, 0.027037104f }, { 0.005616143f, -0.00099668486f, 0.0068716426f, -0.12649184f }, { 0.018531199f, 0.023881776f, -0.053798787f, -0.041912909f }, { -0.0036187094f, 0.11590788f, 0.025140733f, 0.022280209f }, { -0.02994342f, -0.026293799f, -0.017204658f, 0.044901944f }, { 0.079892089f, 0.10816526f, 0.14667807f, 0.027301352f }, { -0.045296738f, -0.066748968f, -0.0099354431f, -0.070369692f }, { -0.08357374f, -0.043311901f, 0.013163375f, -0.0881777f }, { -0.065923811f, -0.10382274f, 0.090440302f, -0.013617198f }, { -0.092578587f, -0.010178017f, -0.01416593f, 0.0432333f }, { 0.055172515f, 0.10021805f, -0.0062782668f, -0.11791805f }, { -0.039684132f, -0.08934283f, 0.020686084f, -0.0013788117f }, { 0.064624676f, 0.051773746f, 0.0045383964f, -0.037696971f }, { -0.066296373f, 0.020570689f, -0.017742721f, -0.022651449f }, { -0.0061572447f, -0.094510525f, -0.094775804f, -0.038022514f }, { 0.0055683313f, 0.039513342f, -0.096815654f, -0.0065483011f }, { -0.03311602f, -0.018395457f, 0.0028464434f, -0.088048272f }, { -0.073106109f, -0.055187863f, -0.093209932f, -0.10155137f }, { 0.042841842f, -0.005778703f, 0.074069607f, -0.025841052f }, { -0.018569637f, 0.063144303f, 0.02291584f, 0.005525742f } } } }, { { { { -0.20809663f, -0.18346453f, -0.072140694f, -0.0078104407f }, { -0.19490097f, 0.25712922f, 0.37640771f, 0.11563399f }, { 0.26894915f, -0.33477877f, -0.093739129f, -0.55078405f }, { -0.65794103f, 0.09211629f, -0.19166986f, 0.5574327f }, { 0.45579532f, 0.23202083f, 0.19626303f, -0.64130523f }, { -0.018763975f, -0.24981569f, -0.32514026f, -0.11121342f }, { 0.22376238f, 0.09515938f, 0.071728264f, -0.02790747f }, { -0.3053338f, 0.34023365f, 0.099862481f, 0.26163964f }, { -0.21722968f, -0.094881958f, -0.086364431f, -0.0081863581f }, { -0.16090709f, 0.23527698f, 0.28947119f, 0.11309742f }, { 0.26447184f, -0.33536416f, -0.096418234f, -0.26201294f }, { -0.56343769f, -0.041662822f, -0.24873841f, 0.67122901f }, { 0.35362642f, 0.2577592f, 0.2009013f, -0.74233681f }, { -0.047956299f, -0.54973418f, -0.4958485f, -0.12453303f }, { 0.06917425f, 0.080509853f, 0.0090863722f, -0.023518805f }, { -0.27000602f, 0.083167162f, 0.12715558f, 0.12397839f }, { -0.11376964f, -0.079199259f, 0.019676685f, -0.0094352472f }, { -0.19185851f, 0.22193112f, 0.28110877f, -0.06422845f }, { 0.084091992f, -0.16151548f, 0.091400556f, -0.28257376f }, { -0.53821376f, 0.21718328f, -0.2234907f, 0.52302804f }, { 0.71322306f, 0.042728493f, 0.13229522f, -0.61892094f }, { 0.15270046f, -0.26304886f, -0.33110633f, -0.052728951f }, { 0.072398971f, 0.25829764f, 0.25881687f, -0.020942042f }, { -0.26788161f, 0.055822039f, 0.33817103f, 0.42061402f } }, { { 0.088248648f, 0.091306255f, 0.020476927f, 0.0030144802f }, { 0.0087376707f, 0.043816157f, 0.0022807168f, 0.016745414f }, { -0.13412414f, 0.12686539f, 0.060531476f, 0.044582027f }, { 0.019204757f, -0.0070891897f, 0.091194602f, 0.065258927f }, { -0.10429513f, -0.027665602f, -0.064350626f, 0.0053147478f }, { 0.069218141f, -0.035018324f, -0.088257571f, 0.019279642f }, { -0.073137338f, 0.040764456f, -0.022352804f, 0.031743288f }, { 0.040325697f, -0.12840825f, -0.009582113f, 0.034509657f }, { 0.081971224f, -0.0035223125f, -0.051728499f, 0.0038899717f }, { 0.050968435f, 0.022254651f, 0.18781134f, -0.032392139f }, { 0.024342518f, 0.13929014f, -0.019175435f, -0.0011608234f }, { -0.0021942487f, -0.01251222f, 0.024263454f, -0.063179344f }, { -0.13071776f, -0.059221747f, -0.034153238f, 0.036561209f }, { 0.054124093f, 0.070495803f, 0.081441614f, 0.051900357f }, { 0.027480327f, 0.028940343f, -0.01469313f, 0.032388411f }, { -0.039696828f, -0.0069393798f, -0.011361641f, 0.035031025f }, { -0.039730763f, 0.0085971581f, -0.0077461932f, -0.040735188f }, { 0.10893368f, 0.00014757217f, 0.025489178f, -0.11388774f }, { -0.0013816669f, 0.0031148929f, 0.10281666f, -0.019860642f }, { -0.065093128f, -0.11495815f, 0.041783056f, -0.091373461f }, { -0.044985581f, 0.0012713031f, -0.16078032f, 0.17303747f }, { -0.038132358f, -0.02995975f, -0.037612782f, 0.012575173f }, { 0.0042976619f, 0.027014275f, 0.017518808f, 0.030405184f }, { -0.0015298607f, 0.029297664f, -0.1034349f, 0.023450502f } }, { { 0.028785558f, -0.028708377f, -0.010459636f, 2.8360915e-05f }, { 0.091634877f, 0.021214811f, 0.12282079f, 0.080617943f }, { -0.29287977f, 0.045481846f, 0.014712563f, 0.057317576f }, { -0.10728772f, 0.03268482f, 0.015167285f, -0.011256231f }, { 0.09337321f, 0.037150859f, 0.052549202f, -0.042671474f }, { -0.0041288689f, -0.024299997f, -0.11357403f, -0.022045772f }, { -0.041469935f, -0.0071353646f, -0.0086607538f, 0.008536762f }, { 0.033629272f, -0.0070042955f, -0.037864853f, -0.0055907778f }, { 0.016404597f, -0.0055321059f, -0.020989839f, -0.013771265f }, { 0.042552435f, 0.04428518f, 0.0030587466f, 0.044894182f }, { -0.027600219f, 0.026831779f, 0.051120849f, -0.032184808f }, { 0.13870554f, 0.15273282f, 0.049260112f, 0.043371121f }, { -0.018453269f, -0.18061413f, 0.24805649f, -0.031741165f }, { -0.085137374f, 0.025935867f, 0.015978067f, 0.067726486f }, { 0.072393868f, 0.0050430488f, 0.0016664585f, 0.0072097064f }, { 0.033840162f, 0.082225764f, -0.079387016f, 0.033165625f }, { 0.033170766f, 0.0012231618f, -0.066984982f, 0.051671704f }, { 0.017894231f, -0.012267532f, 0.045536123f, -0.07327109f }, { 0.0073109731f, -0.063797898f, -0.13446413f, 0.1408986f }, { -0.045702456f, -0.1647051f, -0.14336468f, 0.054543693f }, { 0.0042448876f, -0.13234456f, 0.092181719f, -0.10440841f }, { -0.060020212f, -0.011098469f, -0.030257182f, -0.030922037f }, { -0.018118661f, 0.00067983745f, -0.0061776598f, -0.031721273f }, { -0.019885189f, 0.094157888f, 0.014017961f, -0.051373389f } } }, { { { 0.12415319f, -0.13611564f, -0.029441661f, -0.14143497f }, { -0.26074418f, 0.011913326f, -0.033328425f, 0.43248793f }, { 0.19336432f, 0.37269586f, 0.36803538f, -0.51720719f }, { -0.15185913f, -0.47431781f, -0.6593667f, 0.23163184f }, { 0.18276216f, 0.19248743f, 0.65453332f, 0.54748087f }, { 0.17751443f, -0.0020337696f, 0.08506463f, -0.40147769f }, { -0.11370932f, 0.11523476f, -0.010573025f, 0.082295392f }, { -0.13666335f, -0.32747478f, -0.16897386f, 0.15359006f }, { 0.11716326f, -0.12259922f, 0.0033396256f, -0.13240653f }, { -0.27776876f, -0.10222241f, -0.039920479f, 0.35499708f }, { 0.090003723f, 0.3313923f, 0.1871549f, 0.003163675f }, { -0.51626118f, -0.76341562f, -0.56326874f, 0.20153559f }, { -0.34172723f, 0.26975563f, 0.67520079f, -0.1252004f }, { 0.45758078f, -0.19142179f, 0.064180031f, -0.48748431f }, { -0.12800789f, 0.1399912f, 0.0077954775f, 0.14379741f }, { -0.13042104f, -0.45670817f, -0.18831095f, 0.0032738639f }, { 0.12446807f, -0.11504524f, -0.027331682f, 0.03861758f }, { -0.31337986f, -0.11842668f, 0.033415325f, 0.45344231f }, { 0.11463107f, 0.077427841f, 0.060880794f, -0.069619455f }, { -0.37772106f, -0.59628905f, -0.65426572f, 0.065297039f }, { 0.29532991f, 0.75920243f, 0.53294265f, -0.15002562f }, { 0.3618333f, 0.10488387f, 0.36007528f, -0.30963565f }, { -0.13738196f, 0.20795596f, 0.029274703f, 0.18017599f }, { -0.10290023f, -0.48517535f, -0.33278584f, 0.56477854f } }, { { -0.0047891472f, 0.024629901f, 0.015256654f, -0.0084462001f }, { 0.056227746f, -0.048057782f, -0.15671312f, 0.06418471f }, { -0.070093217f, -0.018057199f, 0.062026545f, -0.051053726f }, { -0.0091221476f, 0.0020547295f, -0.087729813f, -0.10164738f }, { 0.098917091f, -0.066835916f, 0.083151519f, 0.006342544f }, { 0.0013540606f, 0.038719082f, 0.036333261f, -0.053178668f }, { 0.0083787438f, 0.0028359378f, 0.0089872852f, 0.031308249f }, { 0.014379686f, -0.079563474f, -0.079160006f, -0.016352226f }, { 0.0091376645f, -0.016678006f, -0.044636785f, -0.0011035265f }, { 0.0099146109f, 0.027589302f, -0.09494437f, 0.07451767f }, { 0.017453983f, 0.080674871f, 0.06341808f, 0.048820473f }, { 0.02794057f, 0.058230195f, -0.010793601f, 0.091813872f }, { -0.049633232f, -0.1142016f, 0.036984283f, 0.0034294865f }, { 0.047712957f, 0.10161366f, 0.13774722f, 0.039503136f }, { 0.014194782f, -0.014555183f, -0.00053182909f, 0.0019143477f }, { 0.0014900262f, 0.0056176356f, -0.034517871f, -0.0010707988f }, { 0.013287784f, -0.0073967933f, -0.019271341f, 0.016354896f }, { -0.10345626f, 0.023536634f, 0.027943639f, -0.015686972f }, { -0.025193395f, -0.10224801f, 0.078686884f, -0.048574399f }, { 0.15797878f, -0.0012322757f, -0.036096649f, -0.23983963f }, { -0.10455507f, -0.056368102f, -0.06570944f, 0.29104616f }, { 0.05155239f, -0.040940824f, -0.038367594f, 0.058174485f }, { 0.010471732f, -0.066952904f, -0.047763843f, -0.021124742f }, { -0.033555686f, 0.0049111983f, -0.026592789f, 0.014438586f } }, { { -0.0048440946f, 0.025915095f, -0.018325403f, 0.022133613f }, { 0.059240081f, -0.031272176f, -0.12967647f, -0.17957913f }, { 0.0574837f, 0.067005152f, 0.024644254f, 0.10786296f }, { 0.067084865f, 0.008513386f, 0.04077659f, 0.10587924f }, { 0.026332643f, 0.1072618f, -0.098375042f, -0.001724609f }, { -0.021386362f, -0.0020174921f, 0.16800158f, 0.081359882f }, { -0.018204146f, -0.026432136f, -0.0068153455f, -0.029997667f }, { -0.043221501f, -0.016869967f, -0.067406967f, -0.024965804f }, { -0.0033879999f, 0.031310818f, -0.010853802f, 0.00088944004f }, { -0.068991006f, 0.087874253f, -0.15737392f, -0.088870044f }, { 0.061763806f, -0.00072874343f, -0.009915009f, -0.0178225f }, { -0.07340717f, 0.080339271f, -0.0027124572f, -0.13078641f }, { -0.023682834f, 0.16512313f, -0.15784472f, 0.047978827f }, { 0.0063250439f, -0.09953777f, 0.094180888f, 0.010565041f }, { 0.010047311f, -0.042999009f, -0.012483998f, -0.016966759f }, { -0.048612679f, 0.051708319f, 0.015059148f, 0.0036776472f }, { -0.011737015f, -0.0027276603f, 0.026535075f, -0.065453876f }, { 0.056388137f, 0.061461073f, -0.12726984f, -0.025578248f }, { 0.0016833003f, 0.10878558f, 0.13254828f, -0.017098914f }, { -0.031606282f, -0.072245098f, 0.12724789f, -0.21852899f }, { -0.062502612f, -0.073402771f, -0.049624729f, 0.069066032f }, { -0.075837195f, -0.10297347f, -0.07249237f, -0.11538062f }, { -0.015644005f, 0.039474396f, 0.074415075f, -0.038881161f }, { -0.040175911f, 0.034030267f, 0.03947059f, 0.014167463f } } }, { { { 0.97019677f, 0.97355703f, 0.99695983f, 0.98991674f }, { 0.94552952f, 0.96630359f, 0.92585444f, 0.89419404f }, { 0.9435447f, 0.86545998f, 0.92507456f, 0.65508294f }, { 0.73759908f, 0.87552111f, 0.72697883f, 0.79725496f }, { 0.87111918f, 0.95347518f, 0.73011435f, 0.53758004f }, { 0.9839393f, 0.96829127f, 0.94183216f, 0.90909143f }, { 0.96798791f, 0.98876976f, 0.99736817f, 0.99621717f }, { 0.9423876f, 0.88147679f, 0.98054848f, 0.95286662f }, { 0.96906348f, 0.98791034f, 0.99625801f, 0.99116169f }, { 0.94707625f, 0.9665378f, 0.9563539f, 0.9280011f }, { 0.96018435f, 0.88187869f, 0.97758711f, 0.96505917f }, { 0.64499021f, 0.64456248f, 0.78794513f, 0.71332673f }, { 0.87073007f, 0.92778882f, 0.70974824f, 0.65822558f }, { 0.88787388f, 0.81311133f, 0.86603417f, 0.86420517f }, { 0.98935782f, 0.98687417f, 0.99992833f, 0.98932764f }, { 0.95398485f, 0.88572054f, 0.97384313f, 0.99227952f }, { 0.98567955f, 0.99019799f, 0.99943274f, 0.99920952f }, { 0.93004482f, 0.96784384f, 0.95909399f, 0.88896838f }, { 0.98984254f, 0.98382807f, 0.99395144f, 0.95671584f }, { 0.75342733f, 0.77283296f, 0.72248756f, 0.84981055f }, { 0.63568318f, 0.6494505f, 0.83574524f, 0.77099234f }, { 0.91965169f, 0.95906448f, 0.87218942f, 0.94939213f }, { 0.98786871f, 0.94341754f, 0.96548269f, 0.98341143f }, { 0.95794101f, 0.87263324f, 0.8802806f, 0.71000638f } }, { { -0.0064390277f, 0.051629953f, -0.011423447f, 0.032337826f }, { 0.055030538f, 0.061305324f, -0.016012659f, 0.083766345f }, { 0.052467122f, 0.018425134f, -0.00054737782f, 0.048038459f }, { 0.076436505f, 0.016815709f, -0.024174832f, -0.00829119f }, { 0.057903371f, 0.068822104f, -0.0064003131f, 0.00010695928f }, { 0.067104151f, 0.067284611f, 0.0074295447f, 0.024215238f }, { 0.073380541f, 0.01486405f, 0.01523157f, 0.012966612f }, { -0.0002536971f, 0.010628632f, 0.00045031869f, 0.041891438f }, { 0.055922922f, 0.0090823157f, 0.011101162f, 0.033807592f }, { -0.040264953f, 0.022318628f, -0.013682045f, -0.016112502f }, { -0.034286564f, 4.7089727e-05f, -0.013030079f, -0.012231424f }, { 0.027756308f, 0.084041595f, 0.018308393f, 0.11564334f }, { 0.0026690817f, 0.058149333f, -0.013682964f, 0.052975934f }, { -0.03852481f, 0.063493354f, 0.059460027f, 0.047740976f }, { 0.026410264f, -0.0073902435f, 0.022353771f, 0.012987341f }, { 0.035217135f, -0.0023455309f, -0.0055505614f, 0.010102857f }, { 0.00075590283f, 0.038624793f, -0.0040614962f, 0.070039437f }, { -0.02318411f, 0.04527054f, 0.013119286f, 0.025335215f }, { 0.021268391f, 0.044855911f, 0.012622905f, 0.04827088f }, { -0.0046678346f, -0.01934799f, 0.018393432f, 0.09750434f }, { 0.12480373f, 0.059151139f, 0.055196092f, 0.26701338f }, { -0.0096669036f, 0.065624767f, 0.016918517f, 0.028425135f }, { 0.026488514f, -0.0037618693f, 0.0077028717f, 0.041713399f }, { 0.018628451f, 0.033145064f, 0.029067918f, -0.000924258f } }, { { -0.043525781f, 0.028119778f, -0.011653105f, -0.020930158f }, { -0.028099186f, 0.017594088f, -0.099226445f, 0.10408808f }, { 0.11750066f, -0.0010629746f, 0.018381448f, 0.096538552f }, { 0.0010069446f, 0.013799541f, 0.1325137f, 0.020820734f }, { -0.053571928f, -0.0066793785f, 0.14596488f, -0.03272949f }, { 0.028507895f, 0.015474376f, -0.025411653f, 0.037264272f }, { 0.033698911f, 0.018088387f, 0.0038898537f, 0.03163178f }, { 0.0057766828f, 0.015879322f, 0.012557033f, 0.071771631f }, { -0.0044521866f, 0.0083963511f, -0.0020426175f, 0.023784146f }, { -0.011508765f, 0.0075020051f, 0.0018808294f, 0.040843424f }, { 0.0085150894f, 0.0056891711f, 0.010134672f, 0.046224768f }, { 0.040825446f, 0.10099754f, 0.021853299f, 0.024507528f }, { -0.0055958303f, -0.0060958f, 0.1115321f, -0.021701014f }, { 0.010487817f, -0.010033143f, -0.031203025f, 0.054265436f }, { 0.0040500672f, 0.0053935875f, 0.018233022f, 0.018797311f }, { 0.064057639f, 0.014318185f, 0.0199119f, 0.014366235f }, { 0.02411682f, 0.045454692f, 0.0030084434f, 0.019464939f }, { 0.012500289f, 0.027734846f, 0.0025097372f, 0.047343669f }, { 0.037625829f, -0.00064472688f, 0.0557556f, 0.04785655f }, { 0.0020433437f, 0.019929208f, 0.087936103f, -0.036738471f }, { 0.020811556f, 0.0915387f, 0.055445303f, -0.065132763f }, { 0.03911814f, 0.043721622f, 0.0074336204f, -0.031370424f }, { 0.014072509f, -0.014795458f, 0.010517063f, 0.022409628f }, { -0.0054107234f, 0.055313602f, 0.053556404f, 0.048574319f } } }, { { { 3.4224197f, 3.3162336f, 3.1136621f, 3.3189801f }, { 4.0715355f, 3.5614196f, 4.1797877f, 4.0959601f }, { 4.3979407f, 4.1858272f, 4.3116447f, 4.5467451f }, { 4.4920032f, 4.0716439f, 4.6107962f, 4.5268016f }, { 5.6570832f, 4.9036495f, 4.7373547f, 4.7259419f }, { 3.3277827f, 3.6015237f, 4.226646f, 3.7939772f }, { 3.4893058f, 3.3260638f, 3.0626103f, 3.1798705f }, { 3.6423735f, 4.1092281f, 3.3264203f, 3.7325301f }, { 3.4756581f, 3.2550256f, 3.224671f, 3.4093307f }, { 3.8511362f, 3.4821381f, 4.3232597f, 3.7357164f }, { 3.6688024f, 4.0797971f, 3.4140927f, 3.6881261f }, { 4.5298469f, 4.7472506f, 4.4046473f, 4.7279944f }, { 4.1614448f, 4.1242955f, 4.6741969f, 5.0037875f }, { 4.3148703f, 4.3815566f, 4.1976536f, 3.9032858f }, { 3.2640506f, 3.3214728f, 2.9463564f, 3.3562068f }, { 3.6729325f, 3.9218642f, 3.4550701f, 3.4833871f }, { 3.435975f, 3.3079446f, 3.3432341f, 3.3632985f }, { 3.8404619f, 3.4716915f, 3.858149f, 3.8677391f }, { 3.3181827f, 3.8403872f, 4.0363918f, 3.9604287f }, { 5.0916792f, 5.2773748f, 4.5404255f, 4.377031f }, { 4.6514614f, 4.7569957f, 4.1233238f, 4.4022582f }, { 3.6884833f, 3.6283543f, 4.1874612f, 4.2963913f }, { 3.456705f, 3.6250566f, 3.5292789f, 3.1420033f }, { 3.5986317f, 4.0596074f, 4.0696874f, 4.5327067f } }, { { -0.12592901f, -0.14780788f, -0.11051274f, -0.18767653f }, { -0.020435093f, 0.0055221209f, -0.021183195f, -0.15159792f }, { 0.022498629f, -0.025100789f, -0.30939177f, 0.016420202f }, { 0.21296442f, -0.042976575f, 0.082118132f, 0.14574735f }, { -0.13608022f, 0.16141834f, -0.015091164f, 0.044951541f }, { -0.08235774f, -0.10333151f, 0.089785432f, -0.036620639f }, { -0.17664465f, -0.015842477f, -0.083075331f, -0.15660828f }, { -0.11292423f, -0.072894494f, -0.068901923f, -0.2283674f }, { -0.19063437f, -0.071954393f, 0.091375283f, -0.26993547f }, { 0.042798331f, -0.06495575f, 0.050221766f, 0.024602586f }, { -0.026228614f, 0.0049810367f, 0.046584088f, -0.13067577f }, { 0.072779737f, -0.023369437f, -0.030275791f, 0.19591126f }, { -0.018649072f, 0.029208952f, 0.012033439f, 0.00094798196f }, { -0.094599446f, 0.0070746366f, -0.0007115864f, -0.040175552f }, { -0.027599009f, -0.068747365f, 0.19480498f, -0.19423733f }, { -0.076671551f, 0.0075475135f, 0.019853903f, -0.012984601f }, { 0.064371855f, -0.24044027f, -0.043765356f, 0.0016424127f }, { -0.076744435f, 0.035881398f, 0.12967612f, 0.081825243f }, { -0.15224256f, 0.032665115f, -0.027927205f, 0.076091133f }, { -0.0057973613f, -0.14914213f, -0.047678749f, -0.037214457f }, { 0.10060085f, -0.099197666f, -0.22704457f, -0.0020812401f }, { -0.070664558f, -0.13179176f, -0.014217065f, -0.030410253f }, { -0.12286487f, -0.046623366f, -0.10695394f, -0.0081383175f }, { -0.14561788f, 0.02765909f, 0.10439783f, 0.033139041f } }, { { 0.0063171031f, -0.0047223477f, -0.056312039f, -0.065065766f }, { -0.0059575982f, -0.062348475f, 0.069540315f, -0.090331962f }, { 0.10218203f, 0.050383376f, -0.0089914697f, -0.037837343f }, { -0.0037657879f, 0.18278082f, 0.079014627f, -0.052587294f }, { -0.33929282f, 0.018522098f, 0.0078923893f, 0.042545349f }, { 0.027294929f, -0.086490439f, -0.0057363347f, -0.035932082f }, { -0.061716003f, -0.14470599f, 0.033117786f, -0.08112808f }, { 0.16414856f, 0.082471596f, -0.058497326f, 0.050552718f }, { -0.07627083f, -0.0064181717f, -0.031179581f, -0.075705068f }, { -0.057808009f, -0.00074561624f, -0.23990956f, 0.018671772f }, { 0.1677602f, 0.10757253f, 0.028015134f, -0.23923178f }, { 0.078827365f, 0.068682485f, 0.056277532f, -0.069749241f }, { 0.079502977f, 0.05526585f, 0.0089767144f, -0.15319341f }, { -0.038594242f, -0.055488998f, -0.043132461f, 0.054313031f }, { 0.12890592f, -0.082639555f, 0.22520491f, -0.026781096f }, { -0.071292391f, 0.064592881f, -0.050368563f, -0.072488866f }, { 0.092998671f, 0.12152394f, 0.033318795f, -0.039691417f }, { -0.0049706273f, -0.0014175115f, -0.11634604f, 0.15219284f }, { -0.012414906f, 0.035583927f, -0.072463074f, -0.058394705f }, { -0.071558898f, -0.00093653835f, 0.013149622f, 0.01495775f }, { -0.057103279f, 0.013702583f, -0.020242751f, 0.04649072f }, { -0.083398977f, -0.20123674f, 0.062758815f, -0.043671819f }, { 0.084479675f, 0.17868517f, -0.021185269f, 0.15711776f }, { 0.11862504f, 0.079985297f, 0.063556911f, 0.14639069f } } }, { { { 0.48018566f, 0.17712962f, 0.45065949f, 0.76214707f }, { 0.37788335f, 0.385421f, 0.24766167f, 0.3647243f }, { 0.45095873f, 0.2634498f, 0.37824131f, 0.10713483f }, { 0.18808611f, 0.27852978f, 0.23671202f, 0.23174978f }, { 0.39404781f, -0.7399413f, 0.28511918f, 0.026007027f }, { 0.46587668f, 0.46802177f, 0.36697974f, 0.23706778f }, { 0.48925391f, 0.42086488f, 0.49570155f, 0.45137287f }, { 0.30655255f, 0.35196398f, 0.23019387f, 0.50586011f }, { 0.45798975f, 0.34137244f, 0.33289763f, 0.54218519f }, { 0.42271216f, 0.38700914f, 0.48791862f, 0.15025833f }, { 0.7282781f, 0.37956244f, 0.25156645f, 0.51632504f }, { 0.084933462f, 0.15576738f, 0.16469359f, 0.29684651f }, { 0.34570877f, 0.34912791f, 0.26663435f, 0.11188061f }, { 0.48552914f, 0.19012867f, 0.12677402f, 0.1234341f }, { 0.2190939f, 0.41431469f, 0.64823269f, 0.51846746f }, { 0.49289149f, 0.29829354f, 0.29090992f, 0.36465152f }, { 0.50568056f, 0.64150077f, 0.40217634f, 0.53523743f }, { 0.24945735f, 0.47058801f, 0.29099852f, 0.25452114f }, { 0.49039753f, 0.26327736f, 0.39431507f, 0.50632023f }, { 0.19678915f, 0.031547614f, 0.22295107f, 0.26300048f }, { 0.12409997f, 0.11506147f, 0.19327618f, 0.2174585f }, { 0.15319333f, 0.39177705f, 0.38498586f, 0.25972804f }, { 0.69027161f, 0.37279682f, 0.31143504f, 0.23440833f }, { 0.39682066f, 0.3156927f, 0.36369313f, 0.14308402f } }, { { 0.15030994f, 0.15410005f, 0.0072554408f, -0.22242826f }, { -0.032421729f, 0.22531436f, 0.22185899f, -0.022703209f }, { 0.070341052f, 0.30237173f, 0.047916387f, 0.03629681f }, { -0.024283222f, 0.075614195f, 0.013940033f, -0.016841468f }, { 0.077729482f, 0.19455394f, -0.02162282f, -0.018761003f }, { -0.22986895f, 0.18914992f, 0.14483608f, 0.11173921f }, { 0.14132894f, -0.0081864768f, -0.11405791f, 0.031777789f }, { 0.38775389f, 0.0085565642f, -0.057167843f, 0.09784167f }, { 0.079102739f, 0.030530894f, 0.041954967f, 0.02957611f }, { 0.076915126f, 0.18656729f, 0.044218872f, 0.22478833f }, { 0.017173879f, 0.11961351f, -0.085099523f, 0.22720323f }, { 0.030466202f, 0.095221887f, -0.042982583f, -0.069264747f }, { 0.041170442f, -0.090598444f, -0.021082598f, -0.028016784f }, { -0.082581617f, -0.023712106f, 0.32427665f, 0.1010696f }, { 0.19197752f, 0.10900527f, -0.0053794951f, 0.068553764f }, { 0.18674269f, 0.028895321f, -0.053421028f, 0.063918058f }, { 0.044090722f, -0.054247791f, 0.05585954f, -0.13406746f }, { 0.08358642f, -0.032301886f, 0.010371619f, 0.099505528f }, { 0.16467816f, 0.044994571f, -0.0045949279f, 0.0626774f }, { 0.12942209f, 0.092097891f, 0.019866495f, 0.10340014f }, { 0.037094903f, 0.13829877f, 0.15116473f, -0.048632499f }, { 0.10749044f, 0.14329542f, -0.061272024f, -0.1536028f }, { 0.097716907f, 0.044246181f, 0.056664419f, 0.15804873f }, { 0.031819999f, 0.10132976f, 0.079198524f, 0.017871462f } }, { { 0.056219172f, 0.08683492f, -0.061488015f, 0.065746152f }, { 0.088983664f, 0.19773741f, -0.096766599f, 0.16352101f }, { -0.0097043787f, -0.040925999f, 0.097458334f, 0.032319634f }, { -0.024873518f, 0.057873123f, -0.0059256291f, -0.057498398f }, { -0.13355098f, 0.39190863f, 0.017449142f, -0.0076009344f }, { 0.10319658f, 0.22069551f, -0.098795717f, 0.10603434f }, { 0.090765308f, 0.13803326f, -0.070647945f, 0.14557561f }, { -0.068457348f, 0.058955208f, -0.050501105f, 0.02914144f }, { 0.10363866f, 0.060231993f, 0.027681685f, 0.079659088f }, { 0.01269983f, 0.11977996f, -0.049648315f, 0.089882363f }, { -0.072877286f, 0.019348792f, 0.13977764f, 0.055396044f }, { 0.028834456f, -0.1084196f, -0.0043985215f, -0.072640844f }, { -0.040232522f, 0.051835989f, -0.02198193f, 0.016421295f }, { -0.087848469f, -0.04621504f, 0.099259188f, -0.0025909067f }, { 0.3000131f, 0.10526775f, 0.016890366f, 0.12892588f }, { -0.021028821f, -0.024429075f, 0.088067677f, -0.084594075f }, { 0.086861805f, -0.045902006f, 0.0058222123f, -0.0075466204f }, { 0.14411905f, 0.036488937f, 0.05091815f, 0.16385101f }, { 0.1576814f, 0.043890956f, -0.064244298f, -0.087234754f }, { -0.071100004f, 0.16782304f, -0.10860149f, -0.1601076f }, { 0.032634641f, -0.0025068263f, -0.093802703f, -0.076176546f }, { 0.1121451f, 0.15584236f, 0.070074778f, 0.083736091f }, { 0.16981897f, -0.078106227f, 0.12480295f, -0.0056807652f }, { -0.20300117f, -0.017467249f, 0.035504155f, 0.056546123f } } } }, { { { { 0.014994926f, 0.3118252f, 0.12179235f, -0.2013765f }, { -0.2622824f, 0.28086607f, 0.018805882f, 0.72058929f }, { -0.0081002049f, -0.28176506f, -0.592214f, -0.15032918f }, { 0.18913426f, -0.24000825f, 0.0020279072f, -0.54749128f }, { 0.010237954f, 0.76905205f, 0.80173664f, -0.016024595f }, { -0.53448318f, 0.31204229f, -0.16183732f, 0.76857439f }, { -0.57639279f, -0.63719194f, -0.71354849f, 0.56346054f }, { 0.49443258f, 0.15067585f, 0.31864726f, -0.30570933f }, { -0.20756322f, 0.2544828f, -0.005298245f, 0.0073796841f }, { -0.61822672f, 0.21508574f, 0.6362534f, 0.30433278f }, { -0.0050327191f, -0.278054f, -0.3460806f, 0.29967778f }, { 0.33983098f, -0.11715664f, -0.21761592f, -0.068273894f }, { 0.5550354f, 0.44369709f, 0.64019993f, -0.026032291f }, { -0.72587268f, -0.33528197f, -0.33592445f, 0.53027141f }, { -0.47623191f, -0.61767624f, -0.61525655f, 0.37823554f }, { 0.82869964f, 0.219401f, -0.018181789f, -0.56937955f }, { -0.051792934f, 0.3461701f, 0.20915925f, 0.078166496f }, { -0.26705611f, 0.14439061f, 0.0055054648f, 0.463243f }, { -0.0019649711f, -0.34119962f, -0.29306531f, -0.040223173f }, { 0.29285811f, -0.32824753f, -0.24768208f, -0.29676955f }, { 0.87604898f, 0.25374435f, 0.2341931f, -0.77851996f }, { -0.80404697f, 0.011122158f, 0.18899178f, 0.55592668f }, { -0.78397618f, -0.53690406f, -0.59931185f, 0.62348293f }, { 0.54613799f, 0.080819658f, 0.12590931f, -0.60614071f } }, { { -0.12307869f, -0.20242175f, 0.21530167f, -0.15608553f }, { 0.00052208688f, 0.09998365f, -0.067550225f, -0.14009319f }, { 0.12621699f, -0.089024022f, 0.022656689f, 0.18947331f }, { 0.34838897f, -0.04936051f, 0.25527451f, -0.18942819f }, { 0.013210249f, -0.043957685f, -0.19088103f, -0.034189573f }, { -0.0027790938f, -0.026595097f, 0.087083287f, -0.12513839f }, { -0.038231564f, 0.013328425f, -0.0091503894f, -0.005743873f }, { 0.17205702f, -0.14956835f, -0.0088915291f, 0.18720588f }, { -0.049670195f, 0.39532325f, 0.080260299f, 0.01811245f }, { 0.043555003f, -0.30289197f, -0.50878196f, 0.27306166f }, { 0.02555972f, -0.0068359476f, 0.061097702f, -0.43822038f }, { -0.10926471f, 0.1870906f, 0.12419548f, 0.1245213f }, { -0.012443149f, 0.040036941f, 0.18601483f, 0.02310445f }, { -0.10442982f, 0.057455632f, 0.13475314f, -0.0019859122f }, { -0.068181593f, -0.0033655904f, 0.01922998f, -0.020393828f }, { -0.10660626f, 0.0020812455f, 0.081209707f, 0.077131932f }, { 0.088733212f, -0.10430986f, 0.45554817f, -0.17113078f }, { 0.0046831409f, 0.13247549f, -0.1077727f, 0.15382275f }, { 0.022346595f, 0.022924261f, -0.35016323f, 0.2437608f }, { 0.029795657f, 0.23046877f, -0.020493651f, -0.33214749f }, { -0.016101582f, 0.042296203f, 0.046779444f, 0.037412394f }, { -0.02214903f, -0.025218605f, 0.14797485f, -0.051723623f }, { 0.021321783f, 0.010405115f, 0.0075476201f, 0.0082410917f }, { 0.040559796f, 0.027927916f, -0.012812736f, -0.0096642379f } }, { { -0.055647079f, 0.017595207f, 0.34495838f, -0.03055759f }, { -0.058415094f, 0.027416036f, 0.18568916f, 0.13044498f }, { 0.01482217f, -0.17300703f, 0.027540135f, -0.2744944f }, { 0.25558424f, -0.15324455f, -0.29751197f, -0.11422984f }, { -0.068936732f, -0.11425403f, 0.094767025f, -0.0020892558f }, { 0.040887892f, 0.031622148f, -0.095292456f, -0.02460001f }, { -0.0026237665f, 0.017734103f, 0.01213911f, 0.0056586962f }, { -0.052138375f, 0.052245567f, 0.04608449f, -0.043004468f }, { -0.17693366f, 0.0021023738f, 0.13167397f, -0.14062006f }, { -0.20900333f, 0.0057695127f, 0.13057243f, 0.046715668f }, { -0.020569928f, -0.08439655f, -0.09683347f, 0.038139385f }, { 0.18196242f, 0.44461908f, -0.11388512f, -0.12413082f }, { 0.072801844f, -0.0017236427f, -0.0026756083f, 0.049805114f }, { -0.092195952f, -0.0076195172f, -0.22763849f, -0.11320887f }, { 0.016234922f, 0.007258942f, 0.078535592f, -0.084829275f }, { -0.15320003f, 0.057490618f, -0.16065455f, -0.17063675f }, { -0.012856124f, 0.024818957f, 0.097529739f, 0.11569844f }, { -0.11141243f, 0.26677735f, 0.1319403f, -0.15699502f }, { -0.021128161f, -0.12370585f, 0.056198856f, -0.1836225f }, { -0.01871806f, 0.025525037f, 0.063822152f, 0.066517944f }, { -0.013759301f, 0.11401068f, -0.04701374f, -0.021321516f }, { 0.032714649f, -3.161284e-06f, 0.026930697f, 0.00019593482f }, { 0.10575127f, 0.016956425f, 0.016873291f, 0.0049304377f }, { -0.11938883f, 0.31242334f, 0.29347156f, -0.19514533f } } }, { { { -0.17374661f, -0.028781395f, -0.25993234f, 0.27242277f }, { -0.13675759f, -0.62291002f, -0.80742781f, 0.54260546f }, { 0.16876581f, -0.052588487f, 0.22415557f, -0.59669887f }, { 0.1769234f, 0.64210979f, 0.81157479f, -0.2718564f }, { -0.99873125f, -0.013258174f, 0.58939675f, 0.99930085f }, { -0.30883355f, -0.71116337f, -0.76218623f, 0.096388818f }, { 0.65749012f, -0.54533843f, -0.57508599f, -0.70359398f }, { -0.27406769f, 0.61006308f, 0.1873512f, 0.2563151f }, { -0.78453523f, -0.13585943f, -0.048534939f, 0.02085237f }, { 0.40938527f, -0.76981396f, -0.42506866f, 0.22362984f }, { 0.29003079f, -0.20624421f, 0.1151133f, -0.50558933f }, { 0.0070051806f, 0.20763719f, 0.59485798f, -0.61562639f }, { -0.4371111f, 0.48314196f, 0.72981069f, 0.99889301f }, { 0.58257878f, -0.8603979f, -0.94188892f, -0.83140889f }, { 0.71858167f, -0.49534538f, -0.63421799f, -0.84488463f }, { 0.016158248f, 0.65330502f, 0.82883727f, -0.127372f }, { -0.50292264f, -0.14848746f, -0.20836533f, 0.2471481f }, { -0.15815031f, -0.63472031f, -0.79826416f, 0.15325573f }, { -0.010424343f, -0.022843894f, 0.099730136f, -0.26040744f }, { 0.15069433f, 0.31188588f, 0.63836617f, -0.25234477f }, { -0.36946506f, 0.92093529f, 0.96548808f, 0.62354203f }, { -0.57070465f, -0.99847512f, -0.47855156f, -0.079970605f }, { 0.077467525f, -0.71134336f, -0.67172579f, -0.66364974f }, { -0.27299386f, 0.89512951f, 0.61598356f, 0.49577277f } }, { { 0.070458859f, -0.28774455f, 0.21287043f, -0.094689772f }, { 0.0029548085f, -0.31404605f, -0.039280892f, -0.3652277f }, { -0.033729607f, 0.041215792f, 0.065844258f, -0.21509418f }, { 0.39270582f, 0.067526811f, 0.15655351f, 0.053346856f }, { 0.052704394f, -0.087801294f, 0.18655104f, 0.056114808f }, { -0.074582751f, -0.055177669f, -0.22165519f, 0.13272162f }, { -0.027850171f, 0.0029849066f, -0.0062314784f, -0.010484316f }, { 0.20753796f, -0.0087111988f, -0.13875075f, -0.06137521f }, { 0.089744421f, 0.07271039f, 0.099417029f, -0.22157272f }, { -0.013209094f, 0.048633419f, -0.26528065f, -0.15253703f }, { 0.052922007f, 0.24859103f, 0.14406684f, 0.13857649f }, { 0.00096142813f, 0.32643367f, 0.17939549f, -0.39761314f }, { 0.013505803f, -0.036986517f, -0.12729111f, 0.15459921f }, { -0.00049722057f, -0.047063275f, -0.0018666598f, 0.1067114f }, { -0.074221027f, -0.00927958f, -0.029535811f, -0.024240068f }, { -0.12387933f, 0.06626829f, 0.16422781f, 0.077740779f }, { 0.14560404f, -0.082132455f, 0.027268021f, 0.18857832f }, { 0.10470732f, -0.29519533f, -0.23666419f, 0.10917064f }, { 0.042550279f, 0.02436036f, -0.31865644f, -0.024987356f }, { -0.030434576f, 0.082115299f, 0.17770796f, 0.020944092f }, { -0.17365377f, 0.13807361f, 0.12476029f, 0.072738061f }, { -0.11503962f, -0.04022554f, 0.028018434f, -0.070211356f }, { -0.043677907f, 0.0053361863f, 0.0039019898f, 0.0027489647f }, { 0.27060899f, -0.0016552279f, 0.14166067f, -0.25461265f } }, { { 0.014703402f, 0.094752279f, -0.32162049f, 0.082335322f }, { -0.31539882f, 0.44394592f, 0.44316202f, -0.031456167f }, { -0.024148679f, 0.082370612f, -0.0031744796f, 0.098610537f }, { 0.46130367f, -0.19989896f, -0.56118891f, 0.11979937f }, { 0.11784636f, 0.079971516f, -0.16977121f, 0.014922099f }, { 0.018367216f, -0.076519762f, 0.13801492f, 0.039682415f }, { -0.0027614728f, 0.0010389006f, -0.023126227f, 0.0027068473f }, { 0.22249856f, -0.071302328f, 0.23721977f, 0.10734273f }, { 0.41478408f, -0.36611101f, 0.18031261f, -0.11176768f }, { 0.15800457f, 0.23829725f, -0.0016193556f, 0.2112867f }, { -0.14793833f, -0.15378785f, 0.0082778301f, 0.27105519f }, { -0.064743588f, 0.44794816f, -0.12599819f, 0.4310022f }, { 0.092725214f, 0.033947737f, 0.19969884f, 0.0072363359f }, { -0.074190657f, 0.005985921f, 0.300818f, -0.090919095f }, { 0.024238118f, -0.010955859f, -0.068086841f, -0.021137349f }, { 0.12196721f, -0.19977338f, -0.64428422f, -0.30808722f }, { 0.46567096f, -0.042072501f, -0.1778338f, 0.34294059f }, { -0.32528695f, 0.25699981f, 0.49346557f, -0.20743316f }, { 0.10422458f, 0.049488574f, 0.49098274f, -0.34871439f }, { 0.16431875f, -0.050748897f, -0.18464312f, -0.61695364f }, { -0.1753479f, 0.033238479f, -0.046267845f, -0.012339883f }, { -0.16098841f, 0.080519992f, -0.11793031f, 0.036790025f }, { 0.017193144f, -0.0029212372f, -0.0044153187f, -0.0057094316f }, { 0.23481771f, -0.1556448f, -0.18775429f, -0.013697353f } } }, { { { 0.98467622f, 0.94970347f, 0.95791534f, 0.9408684f }, { 0.95525144f, 0.73013516f, 0.58966657f, 0.43166004f }, { 0.98562289f, 0.95804118f, 0.77397471f, 0.78825859f }, { 0.96588112f, 0.72807352f, 0.58424502f, 0.79142113f }, { -0.049305848f, 0.63904864f, 0.099145551f, -0.03377918f }, { 0.78673348f, 0.62998117f, 0.62680207f, 0.63245759f }, { 0.48526085f, 0.544603f, 0.40015579f, 0.43297544f }, { 0.82487776f, 0.77789448f, 0.92917353f, 0.91697567f }, { 0.58431326f, 0.95748667f, 0.99880743f, 0.99975533f }, { 0.67096902f, 0.60093643f, 0.64381538f, 0.92594344f }, { 0.95700408f, 0.93816272f, 0.93111608f, 0.80905665f }, { 0.94046044f, 0.97116483f, 0.77381347f, 0.78507504f }, { 0.7077214f, 0.7547892f, 0.23983411f, -0.039180128f }, { 0.3656649f, 0.38379871f, -0.00015338393f, 0.16604667f }, { 0.50679735f, 0.6108265f, 0.46821675f, 0.37829596f }, { 0.55946029f, 0.72460731f, 0.55919425f, 0.81214734f }, { 0.86277825f, 0.92634645f, 0.95542467f, 0.96581976f }, { 0.95061533f, 0.75913205f, 0.60228234f, 0.87287949f }, { 0.99994373f, 0.93971324f, 0.95087677f, 0.96466059f }, { 0.9442062f, 0.89161694f, 0.72879505f, 0.92100486f }, { 0.30989313f, 0.29579046f, 0.11395771f, 0.071428407f }, { 0.16674735f, -0.054071458f, 0.85747916f, 0.82737551f }, { 0.61593841f, 0.45356879f, 0.43544204f, 0.41332561f }, { 0.79196443f, 0.43841915f, 0.77763172f, 0.62193473f } }, { { 0.028699614f, 0.071974788f, -0.028868668f, 0.030119772f }, { -0.16988515f, -0.35713152f, 0.36877151f, 0.37172103f }, { 0.024472009f, 0.10373643f, 0.052160621f, -0.12998364f }, { 0.051999909f, -0.1688679f, 0.05813266f, -0.11063347f }, { 0.026373007f, 0.067310776f, 0.34433164f, 0.0017481699f }, { -0.017659611f, -0.10215276f, -0.23736187f, 0.12678732f }, { -0.0019097928f, 0.02067204f, -0.030447136f, -0.0093192388f }, { 0.10615435f, 0.11124023f, 0.04473958f, 0.14369936f }, { 0.14791062f, -0.034502091f, 0.041456555f, 0.06737059f }, { 0.22389399f, 0.2668048f, 0.25742349f, 0.03724758f }, { 0.0046009946f, 0.066632032f, 0.097957775f, 0.22969631f }, { 0.043253167f, -0.013638494f, 0.071328387f, -0.19249903f }, { -0.023561087f, 0.011490741f, 0.19824644f, -0.04133258f }, { -0.057507532f, -0.039265903f, 0.060469313f, 0.37300659f }, { 0.027051207f, -0.0086784396f, -0.0055877341f, -0.0315352f }, { 0.15724931f, 0.0099485187f, 0.22462997f, 0.14112999f }, { 0.13909905f, 0.026199511f, -0.12430815f, -0.076900423f }, { -0.022327596f, -0.1975812f, 0.49862652f, -0.096026553f }, { 0.076782007f, 0.041598482f, 0.0033451155f, 0.039947963f }, { 0.005353589f, 0.070993946f, 0.0068174778f, -0.17805261f }, { -0.059912765f, -0.17027417f, -0.060069718f, 0.1561139f }, { 0.017122435f, 0.048532637f, -0.05315926f, 0.066962855f }, { 0.058014377f, 0.021874362f, 0.017248667f, -0.0069413843f }, { 0.099274028f, 0.040622241f, 0.040435904f, 0.14191123f } }, { { -0.13453832f, 0.071519908f, -0.1597656f, -0.030758273f }, { -0.13511715f, 0.32373425f, 0.35851035f, -0.18685481f }, { 0.021440457f, 0.034442875f, 0.14324368f, 0.15754565f }, { -0.061440371f, 0.16837735f, 0.47887644f, -0.036265812f }, { 0.55060811f, 0.14095672f, 0.13077418f, 0.25515565f }, { -0.084599968f, -0.084002143f, 0.1542308f, 0.044223437f }, { 0.0017727822f, 0.025149715f, -0.025479364f, -0.0023658361f }, { 0.1619123f, 0.069159159f, -0.016343512f, 0.026108175f }, { 0.3296525f, 0.029456656f, 0.039715069f, 0.015958704f }, { -0.093419591f, 0.37051381f, -0.063182977f, -0.017764112f }, { 0.11962535f, 0.062511772f, -0.070445145f, 0.27768911f }, { 0.07458833f, -0.16218828f, 0.064111239f, 0.43889373f }, { -0.0326486f, -0.03666828f, -0.17597139f, 0.34213144f }, { 0.061334301f, -0.0099525239f, 0.21497301f, 0.0074569296f }, { -0.016749445f, 0.00054557189f, 0.040331287f, 0.066200794f }, { 0.20620866f, 0.25268529f, 0.46594276f, 0.059651923f }, { 0.15170896f, 0.041438057f, 0.021708506f, -0.15049245f }, { -0.14317538f, 0.13548996f, 0.37297491f, 0.13718874f }, { 0.053339004f, 0.015014013f, -0.10418356f, -0.13598877f }, { -0.02227412f, 0.045548464f, 0.21534467f, -0.23828118f }, { -0.055326885f, 0.11851609f, 0.28938409f, 0.041373996f }, { -0.1219532f, 0.57338554f, -0.094571555f, 0.025008596f }, { 0.070380772f, 0.016993506f, 0.018073937f, -0.015404818f }, { 0.17033841f, 0.12449473f, 0.10847869f, -0.11141982f } } }, { { { 4.409738f, 4.5071479f, 5.4761817f, 5.3214091f }, { 5.3741435f, 4.6270256f, 5.4786338f, 5.323679f }, { 4.305776f, 4.4890731f, 4.6894257f, 4.6068436f }, { 5.4930574f, 4.9116386f, 5.4097636f, 4.9225404f }, { 5.1861828f, 5.5144226f, 5.1307797f, 5.0804212f }, { 6.1194597f, 6.0655136f, 5.7369562f, 6.1076578f }, { 6.9549598f, 6.9281578f, 6.9549598f, 6.9549598f }, { 4.5030565f, 4.5849566f, 4.4830953f, 4.4904323f }, { 5.3629211f, 5.5524848f, 4.5719135f, 4.9103175f }, { 4.8906163f, 5.3972226f, 4.8806206f, 5.1834202f }, { 4.5047396f, 4.5984947f, 4.7039612f, 4.3422371f }, { 4.5956963f, 5.6294962f, 4.46025f, 4.4827131f }, { 5.8454206f, 6.000743f, 5.4594428f, 4.9952614f }, { 6.09642f, 6.3979283f, 4.9784963f, 5.6878449f }, { 6.9549598f, 6.9752898f, 6.9549598f, 6.9549598f }, { 6.2053562f, 4.9984547f, 5.3887395f, 4.6221036f }, { 4.5265196f, 4.3684629f, 5.5819288f, 5.4957366f }, { 5.2220057f, 4.6118907f, 5.5046208f, 4.9190037f }, { 4.3408178f, 4.4980303f, 5.4937404f, 5.6154153f }, { 4.4802186f, 4.4666194f, 4.8546878f, 5.1764252f }, { 5.7384024f, 5.9048089f, 5.4636107f, 5.0807017f }, { 5.1013817f, 5.2237041f, 6.0338955f, 5.8869417f }, { 6.9414339f, 6.9549598f, 6.9549598f, 6.9549598f }, { 4.3368412f, 4.9692663f, 4.7090567f, 4.9023075f } }, { { 0.0093525884f, -0.33796029f, -0.4366682f, -0.18161326f }, { -0.34446047f, 0.10854359f, -0.61563912f, -0.16514117f }, { 0.055849315f, 0.093045585f, 0.36722184f, 0.085665647f }, { -0.21881508f, -0.036846235f, -0.25226403f, -0.012790033f }, { -0.14697546f, -0.026656628f, 0.2559775f, 0.026279081f }, { 0.073189287f, -0.074472165f, -0.15439557f, 0.020907645f }, { 0.0f, -0.015078298f, 0.0f, 0.0f }, { 0.027540893f, -0.30876053f, -0.15680794f, -0.18470107f }, { -0.072547269f, -0.019227086f, -0.26735769f, -0.1362069f }, { 0.36907279f, -0.28005156f, 0.01966203f, -0.10277819f }, { -0.26755862f, 0.066747173f, 0.60834173f, -0.23356165f }, { -0.12357338f, -0.41742338f, 0.081840746f, -0.14596222f }, { -0.068599762f, -0.004402392f, -0.17192993f, -0.15797464f }, { -0.072923207f, -0.02555551f, -0.21075071f, 0.047272919f }, { 0.0f, 0.0115085f, 0.0f, 0.0f }, { 0.32527558f, 0.066048741f, -0.28639187f, 0.45171914f }, { -0.158086f, -0.049098981f, -0.17226122f, -0.50289857f }, { -0.39456648f, 0.031970902f, -0.74883626f, 0.20536003f }, { 0.22864705f, -0.0095988927f, -0.1155595f, -0.06240073f }, { 0.12336497f, -0.34128076f, 0.34341316f, 0.083678547f }, { -0.032718317f, 0.076359349f, -0.30099369f, -0.016865529f }, { -0.23491753f, -0.17228011f, -0.044893186f, -0.057411459f }, { -0.0077848677f, 0.0f, 0.0f, 0.0f }, { -0.18713605f, -0.11612415f, 0.30907006f, 0.064707406f } }, { { -0.20768494f, -0.15642062f, -0.079474216f, -0.020948121f }, { -0.18767308f, -0.013722599f, 0.15827086f, -0.27421942f }, { -0.11484158f, -0.29325715f, 0.24426149f, 0.34598577f }, { -0.095599056f, 0.16784413f, 0.23369965f, 0.15036114f }, { 0.058496274f, -0.064565923f, -0.076598803f, -0.11988702f }, { -0.03406356f, -0.010863931f, -0.036116475f, 0.0077051595f }, { 0.0f, -0.015078298f, 0.0f, 0.0f }, { -0.21271534f, 0.31678528f, 0.084310434f, -0.039787477f }, { 0.057420352f, -0.60894321f, -0.14275706f, -0.29178151f }, { -0.21477227f, 0.091254596f, -0.053659362f, -0.13299553f }, { -0.24972574f, 0.22261101f, -0.59415755f, -0.13299464f }, { -0.406027f, 0.15018847f, 0.33281927f, 0.28006105f }, { -0.033198856f, 0.013081228f, 0.0098634494f, -0.18858267f }, { -0.16914457f, -0.014917022f, -0.15618156f, 0.038961385f }, { 0.0f, 0.0115085f, 0.0f, 0.0f }, { 0.047340338f, -0.052961301f, 0.30193278f, 0.38564757f }, { -0.2009302f, -0.15247105f, -0.32333852f, 0.22878398f }, { -0.22934017f, 0.022888443f, 0.30911154f, -0.12420416f }, { 0.21191356f, -0.33281926f, -0.13523708f, -0.038546557f }, { 0.28507859f, -0.012777666f, 0.16285544f, -0.12612215f }, { -0.057034227f, 0.01719448f, -0.037892291f, -0.13064036f }, { -0.075888865f, 0.041589292f, 0.0089100653f, -0.10775402f }, { 0.0075560462f, 0.0f, 0.0f, 0.0f }, { -0.18120766f, 0.16485298f, 0.58949587f, 0.072313493f } } }, { { { 0.60381773f, 0.64633179f, 0.92301353f, 0.23720177f }, { 1.1128727f, 0.42172315f, 1.6605811f, 0.22066721f }, { 0.55829912f, 0.7107351f, 0.47437673f, 0.53646626f }, { 0.75684406f, 0.65607146f, 1.5264507f, 0.12817954f }, { -0.25070514f, 0.30263175f, -0.21070678f, -0.2264813f }, { -0.24745858f, -0.26801252f, 0.2750925f, 0.055035565f }, { -0.018769156f, -0.066023008f, 0.10111114f, 0.0089232736f }, { 0.41152465f, 0.52508091f, 0.4161358f, 0.39058287f }, { 0.90919582f, 1.2448772f, 0.61547497f, 0.51303689f }, { 0.2973136f, 1.2348603f, 0.24154398f, 0.76087607f }, { 0.23369317f, 0.68368068f, 0.81024353f, 0.35451079f }, { 0.69272073f, 0.47014545f, 0.61401877f, 0.43768641f }, { -0.44449894f, -0.10123077f, -0.19173956f, -0.15811184f }, { -0.089717f, -0.068601549f, -0.16704813f, -0.29761406f }, { 0.0055968308f, -0.089855929f, -0.087150641f, 0.2244144f }, { 0.38902787f, 0.62620686f, 1.3314901f, 0.26038797f }, { 0.16776511f, 0.32722251f, 0.71914611f, 0.53556119f }, { 0.63106992f, 0.46256454f, 1.785895f, 0.17339911f }, { 0.72516261f, 0.44941094f, 0.81174974f, 0.61247129f }, { 0.56877815f, 0.20989179f, 0.7607991f, 0.017998645f }, { 0.016372087f, 0.26062407f, -0.32771461f, -0.075930098f }, { -0.11957223f, -0.22579003f, -0.42587945f, -0.0015549589f }, { 0.0049992009f, 0.053511694f, 0.00053268274f, 0.022778575f }, { 0.19356675f, 0.5564623f, 0.74981777f, 0.28733119f } }, { { 0.017029304f, 0.22690356f, 0.25927682f, -0.048136042f }, { 0.52936856f, -0.26082526f, 0.12568074f, -0.046727529f }, { 0.08949554f, -0.019090555f, 0.31477592f, -0.067513409f }, { 0.056302335f, -0.011819435f, -0.063621104f, 0.27092306f }, { 0.053971592f, -0.17913246f, -0.14991651f, -0.044263405f }, { 0.29037749f, -0.040498369f, -0.33600753f, 0.16250066f }, { -0.067102844f, -0.17843768f, 0.033172168f, 0.13638573f }, { 0.057127881f, -0.044468822f, 0.33005778f, 0.34775491f }, { -0.14300931f, 0.022121077f, -0.045281831f, -0.065216583f }, { 0.084931489f, 0.06688461f, 0.15758114f, -0.091330485f }, { -0.014274888f, 0.29139103f, 0.089163749f, -0.18005467f }, { -0.2191522f, -0.1333803f, -0.31948964f, -0.28536602f }, { 0.20298891f, -0.0031882515f, -0.15749696f, -0.014977715f }, { -0.14016857f, -0.17278064f, 0.01369474f, 0.10971499f }, { 0.018219806f, 0.080447764f, 0.0056022696f, -0.043028475f }, { -0.076556403f, -0.13038184f, -0.23788273f, 0.5849635f }, { 0.1038427f, 0.18199702f, 0.35294355f, -0.0023601311f }, { 0.22294845f, -0.37427713f, 0.2907529f, 0.26234219f }, { 0.40809306f, 0.12982813f, 0.42857338f, 0.14064303f }, { 0.4265028f, 0.18710053f, 0.15310514f, 0.067551813f }, { -0.18986488f, -0.029676062f, -0.087045959f, -0.14788626f }, { -0.07865478f, 0.011558295f, -0.018262356f, 0.38992629f }, { 0.22297641f, 0.072192947f, 0.064119712f, 0.12862555f }, { -0.069262467f, -0.14990585f, 0.31342655f, -0.15002022f } }, { { 0.25288162f, -0.096551539f, 0.051695506f, 0.20925392f }, { 0.23093904f, 0.096712594f, 0.19826434f, 0.32530694f }, { 0.14114785f, 0.071010138f, -0.17642029f, 0.092260082f }, { 0.39001648f, -0.17666595f, 0.088397252f, 0.1462816f }, { 0.12484597f, 0.066920676f, -0.16116194f, 0.21758387f }, { 0.15625272f, -0.00043631439f, -0.07868976f, -0.19261141f }, { -0.0142415f, 0.06356153f, 0.026276923f, -0.024546668f }, { 0.097089221f, 0.085426402f, 0.11936115f, 0.012042542f }, { 0.52509109f, -0.22465399f, -0.11490612f, 0.023562122f }, { -0.12418278f, 0.11985465f, 0.087804943f, 0.25283464f }, { 0.10716753f, -0.036426901f, 0.2469409f, -0.095816257f }, { -0.095364501f, 0.14001518f, -0.068636804f, -0.082487255f }, { 0.074490355f, 0.25323233f, 0.17863748f, 0.12482145f }, { -0.019616587f, -0.0053326518f, 0.047558858f, 0.066104462f }, { 0.12647102f, 0.25712368f, 0.12306783f, -0.050252261f }, { -0.13375041f, 0.17825067f, 0.026649645f, -0.33338076f }, { 0.16384463f, -0.022241979f, 0.17817325f, 0.6808721f }, { 0.42075944f, -0.024292721f, -0.11323318f, 0.45027063f }, { -0.023953485f, 0.25719992f, 0.28680108f, 0.33600529f }, { 0.013445546f, 0.22504275f, 0.17408162f, 0.52860686f }, { -0.098839039f, -0.27017244f, 0.10293505f, -0.012472685f }, { 0.074267375f, -0.0056418849f, 0.17632358f, 0.21754089f }, { 0.1491061f, 0.017927571f, -0.0217757f, -0.0039381966f }, { 0.067239102f, -0.74624136f, 0.12992555f, -0.058866581f } } } }, { { { { 0.1270204f, 0.7650174f, 0.55252173f, 0.05956498f }, { -0.36870832f, 0.31227245f, 0.52167466f, 0.4282174f }, { -0.036761861f, -0.5477415f, -0.76091563f, -0.37583127f }, { 0.17129434f, -0.14281209f, -0.40463148f, -0.56367877f }, { 0.07429238f, 0.45420144f, 0.41919765f, 0.019225986f }, { -0.44125436f, -0.05567539f, 0.080551064f, 0.54444995f }, { -0.36600455f, -0.55359309f, -0.3290331f, 0.33946169f }, { 0.65253747f, 0.015186649f, 0.0665303f, -0.64649501f }, { 0.05392469f, 0.54355001f, 0.7539307f, -0.41089455f }, { -0.29264863f, 0.49684721f, 0.39184208f, 0.47737193f }, { 0.10885354f, -0.80803227f, -0.7443769f, -0.3736688f }, { 0.1939378f, -0.079590275f, -0.42241709f, -0.75536039f }, { 0.44776697f, 0.44884546f, 0.427965f, 0.3297221f }, { -0.34595785f, 0.27723463f, 0.12245317f, 0.43884357f }, { 0.18467758f, -0.55582608f, -0.99421464f, -0.0096027817f }, { 0.6672057f, -0.038103784f, -0.048616141f, -0.68508055f }, { -0.016615937f, 0.62001729f, 0.50530563f, -0.22211425f }, { -0.16823123f, 0.31934529f, 0.47092187f, 0.4884373f }, { 0.03194189f, -0.5624624f, -0.44688229f, 0.223814f }, { 0.17828041f, -0.080017082f, -0.44239439f, -0.46726625f }, { 0.19895649f, 0.82568772f, 0.47859751f, 0.064443297f }, { -0.47464217f, 0.011895223f, 0.01123465f, -0.010697203f }, { -0.17670677f, -0.66931423f, -0.5814681f, -0.01325001f }, { 0.65193874f, -0.010713062f, -0.007915928f, -0.65520853f } }, { { -0.01027431f, -0.0019056004f, 0.0020213958f, 0.0064495753f }, { 0.0058416688f, 0.0051314639f, 0.021497114f, 0.005870592f }, { -0.00035518612f, -0.00087553938f, -0.0029318969f, 0.0087577986f }, { -0.0048770476f, -0.015949665f, -0.034816051f, -0.006104917f }, { 0.0015371362f, -0.0012591621f, 0.01241148f, 0.00096621463f }, { 0.0032416133f, 0.021025709f, 0.0036344622f, 0.0015436078f }, { -0.0093946276f, 0.0046564763f, 0.028177476f, -0.01022744f }, { 0.00014675555f, 0.030031482f, -0.0092302407f, -0.001999398f }, { -0.049980321f, 0.024752279f, 0.016684689f, -0.0045230976f }, { 0.0067493834f, 0.014071508f, 0.0079316435f, 0.034593704f }, { 0.01971715f, -0.0037227013f, -0.013430278f, -0.024257585f }, { -0.004342319f, 0.024001878f, -0.013356442f, -0.022792018f }, { -0.0051709665f, -0.017029547f, 0.040567567f, 0.0052520812f }, { 0.0090399102f, 0.0079604733f, 0.00018765016f, -0.0092868977f }, { -0.020304032f, 0.0056590257f, -0.0045373063f, -0.018653318f }, { -9.9636934e-05f, 0.002001886f, 0.0046843544f, 0.0055608043f }, { 0.0018025744f, -0.0025962216f, 0.0068285574f, -0.014851062f }, { 0.00041645221f, 0.0054738242f, 0.0076769026f, -0.013419208f }, { 0.0038347099f, -0.0042555066f, -0.0066470075f, 0.0039146778f }, { -0.009084153f, 0.024461537f, 0.0034578066f, -0.0054827001f }, { 0.0033463477f, 0.0045594748f, 0.00037604935f, -0.01571513f }, { -0.012589588f, 0.029678359f, -0.019924871f, -0.004708459f }, { -0.0002642682f, -0.0051057336f, -0.0042867302f, -0.00041141781f }, { -0.00086487068f, -0.0025170841f, 0.0030062196f, -0.0030385417f } }, { { -0.01027431f, -0.0019056004f, 0.0020213958f, 0.0064495753f }, { 0.0058416688f, 0.0051314639f, 0.021497114f, 0.005870592f }, { -0.00035518612f, -0.00087553938f, -0.0029318969f, 0.0087577986f }, { -0.0048770476f, -0.015949665f, -0.034816051f, -0.006104917f }, { 0.0015371362f, -0.0012591621f, 0.01241148f, 0.00096621463f }, { 0.0032416133f, 0.021025709f, 0.0036344622f, 0.0015436078f }, { -0.0093946276f, 0.0046564763f, 0.028177476f, -0.01022744f }, { 0.00014675555f, 0.030031482f, -0.0092302407f, -0.001999398f }, { -0.049980321f, 0.024752279f, 0.016684689f, -0.0045230976f }, { 0.0067493834f, 0.014071508f, 0.0079316435f, 0.034593704f }, { 0.01971715f, -0.0037227013f, -0.013430278f, -0.024257585f }, { -0.004342319f, 0.024001878f, -0.013356442f, -0.022792018f }, { -0.0051709665f, -0.017029547f, 0.040567567f, 0.0052520812f }, { 0.0090399102f, 0.0079604733f, 0.00018765016f, -0.0092868977f }, { -0.020304032f, 0.0056590257f, -0.0045373063f, -0.018653318f }, { -9.9636934e-05f, 0.002001886f, 0.0046843544f, 0.0055608043f }, { 0.0018025744f, -0.0025962216f, 0.0068285574f, -0.014851062f }, { 0.00041645221f, 0.0054738242f, 0.0076769026f, -0.013419208f }, { 0.0038347099f, -0.0042555066f, -0.0066470075f, 0.0039146778f }, { -0.009084153f, 0.024461537f, 0.0034578066f, -0.0054827001f }, { 0.0033463477f, 0.0045594748f, 0.00037604935f, -0.01571513f }, { -0.012589588f, 0.029678359f, -0.019924871f, -0.004708459f }, { -0.0002642682f, -0.0051057336f, -0.0042867302f, -0.00041141781f }, { -0.00086487068f, -0.0025170841f, 0.0030062196f, -0.0030385417f } } }, { { { -0.68772793f, 0.19029367f, -0.17427646f, 0.60300616f }, { -0.29980532f, -0.22397537f, -0.4071009f, 0.36277983f }, { 0.75628069f, -0.13426242f, 0.13645381f, -0.74653491f }, { 0.14891408f, -0.13497977f, 0.36807879f, -0.39814386f }, { -0.20608987f, -0.076497863f, -0.19510375f, 0.34604256f }, { -0.02421123f, -0.4588774f, -0.64965351f, 0.083039161f }, { 0.51918764f, -0.30614677f, -0.25791921f, -0.40837612f }, { 0.028860181f, 0.63152733f, 0.5876224f, -0.033139773f }, { -0.63418144f, 0.046874151f, 0.24431924f, 0.71662556f }, { -0.29088451f, -0.21455586f, -0.73980807f, 0.65038559f }, { 0.78663226f, 0.00020858525f, 0.40361403f, -0.75720144f }, { 0.1998276f, 0.54590973f, 0.1773378f, -0.35464319f }, { -0.40236144f, 0.31362578f, -0.34406026f, 0.38120073f }, { -0.27845549f, -0.46862161f, -0.47141499f, 0.095899189f }, { 0.6004921f, 0.28051621f, -0.011378178f, -0.98141078f }, { 0.032724674f, 0.66798127f, 0.66430425f, -0.05209965f }, { -0.59603974f, -0.083198329f, 0.34616224f, 0.42082916f }, { -0.14262632f, -0.21418442f, -0.37504914f, 0.32676687f }, { 0.58204273f, 0.0067537174f, -0.35923481f, -0.40792038f }, { 0.15607366f, 0.17215007f, 0.34414936f, -0.33566945f }, { -0.44862333f, 0.004919013f, 0.0076768115f, 0.41897935f }, { -0.022062848f, -0.39695079f, -0.0062786656f, 0.042925103f }, { 0.65953535f, -0.15521993f, 0.011867978f, -0.57721165f }, { 0.031305912f, 0.65627006f, 0.66779002f, -0.029815636f } }, { { 0.011457792f, -0.011774949f, -0.012205337f, 0.0048139052f }, { -0.024024566f, 0.018313023f, -0.023210623f, -0.0046351547f }, { 0.0039133571f, 0.0046801024f, -0.020590099f, -0.0018568631f }, { -0.015369931f, -0.0092621276f, -0.026149742f, 0.0010335971f }, { 0.032555144f, -0.01336897f, -0.022733265f, -0.027997469f }, { -0.028161537f, -0.00073877629f, -0.023989631f, 0.0055660453f }, { -0.012966193f, 0.003944376f, 0.025685982f, -0.0017458044f }, { 0.00015626641f, -0.009524206f, 0.0083025026f, -0.00049753811f }, { -0.02358661f, 0.006370149f, 0.00087066462f, -0.00054248544f }, { -0.0024571244f, -0.023218369f, -0.010895303f, -0.0095647684f }, { 0.0069970393f, -0.00093403301f, -0.0081922371f, -0.00026359768f }, { 0.0065921354f, 0.028846533f, -0.045676337f, 0.006070217f }, { 0.0045248423f, -0.0084676847f, 0.028756195f, 0.020612871f }, { 0.0037691244f, -0.0069385161f, -0.00029501448f, -0.0017839033f }, { -0.0048675353f, -0.011930456f, 0.0044251285f, -0.00016323616f }, { -0.0012291164f, -0.0019575288f, 0.0078250029f, -0.0011151155f }, { 0.00503333f, -0.0094538968f, 0.0092375183f, 0.018207648f }, { 0.0080615812f, -0.0073583459f, -0.0166794f, 0.016416158f }, { 0.002192959f, -0.01153759f, -0.0048668362f, -0.0071123281f }, { -0.010116143f, -0.010224552f, 0.010897731f, 0.00093792816f }, { 0.017199359f, -0.0087516179f, 0.0021169251f, -0.020946959f }, { -0.01570063f, 0.020087246f, 0.014492818f, -0.016014018f }, { 0.0023484072f, 0.0015070243f, -0.00045616273f, -0.001211882f }, { 0.0018090492f, -0.0012261901f, 0.0012809284f, 0.00096488905f } }, { { 0.011457792f, -0.011774949f, -0.012205337f, 0.0048139052f }, { -0.024024566f, 0.018313023f, -0.023210623f, -0.0046351547f }, { 0.0039133571f, 0.0046801024f, -0.020590099f, -0.0018568631f }, { -0.015369931f, -0.0092621276f, -0.026149742f, 0.0010335971f }, { 0.032555144f, -0.01336897f, -0.022733265f, -0.027997469f }, { -0.028161537f, -0.00073877629f, -0.023989631f, 0.0055660453f }, { -0.012966193f, 0.003944376f, 0.025685982f, -0.0017458044f }, { 0.00015626641f, -0.009524206f, 0.0083025026f, -0.00049753811f }, { -0.02358661f, 0.006370149f, 0.00087066462f, -0.00054248544f }, { -0.0024571244f, -0.023218369f, -0.010895303f, -0.0095647684f }, { 0.0069970393f, -0.00093403301f, -0.0081922371f, -0.00026359768f }, { 0.0065921354f, 0.028846533f, -0.045676337f, 0.006070217f }, { 0.0045248423f, -0.0084676847f, 0.028756195f, 0.020612871f }, { 0.0037691244f, -0.0069385161f, -0.00029501448f, -0.0017839033f }, { -0.0048675353f, -0.011930456f, 0.0044251285f, -0.00016323616f }, { -0.0012291164f, -0.0019575288f, 0.0078250029f, -0.0011151155f }, { 0.00503333f, -0.0094538968f, 0.0092375183f, 0.018207648f }, { 0.0080615812f, -0.0073583459f, -0.0166794f, 0.016416158f }, { 0.002192959f, -0.01153759f, -0.0048668362f, -0.0071123281f }, { -0.010116143f, -0.010224552f, 0.010897731f, 0.00093792816f }, { 0.017199359f, -0.0087516179f, 0.0021169251f, -0.020946959f }, { -0.01570063f, 0.020087246f, 0.014492818f, -0.016014018f }, { 0.0023484072f, 0.0015070243f, -0.00045616273f, -0.001211882f }, { 0.0018090492f, -0.0012261901f, 0.0012809284f, 0.00096488905f } } }, { { { 0.71476997f, 0.61525336f, 0.81507512f, 0.79550964f }, { 0.87986984f, 0.9232123f, 0.74974956f, 0.82765975f }, { 0.65321366f, 0.82580437f, 0.63434042f, 0.54903231f }, { 0.97390084f, 0.98050251f, 0.83713283f, 0.72370416f }, { 0.97570877f, 0.88760866f, 0.88668363f, 0.9380218f }, { 0.89705541f, 0.88675351f, 0.75595095f, 0.83467284f }, { 0.77232433f, 0.77447327f, 0.9084134f, 0.84734569f }, { -0.75720667f, -0.77520488f, -0.80639546f, -0.76219811f }, { 0.77130152f, 0.83806694f, 0.60983327f, 0.56357207f }, { 0.91090229f, 0.84089752f, 0.54694041f, 0.59085922f }, { 0.60775044f, 0.58913818f, 0.53197627f, 0.53574024f }, { 0.96044628f, 0.83405513f, 0.88888419f, 0.55105253f }, { 0.79850486f, 0.83676557f, 0.83574428f, 0.86369517f }, { 0.89597751f, 0.83876978f, 0.87336884f, 0.8934314f }, { 0.77801249f, 0.78253947f, 0.10680725f, 0.19167855f }, { -0.74415432f, -0.74320194f, -0.74587957f, -0.72660186f }, { 0.802783f, 0.78016447f, 0.79046691f, 0.87952719f }, { 0.97537479f, 0.92311625f, 0.79848027f, 0.80910594f }, { 0.8125306f, 0.82679528f, 0.81929639f, 0.88516002f }, { 0.97152309f, 0.98181547f, 0.82815966f, 0.81791703f }, { 0.87129411f, 0.56410602f, 0.87800085f, 0.905706f }, { 0.87990229f, 0.91776281f, 0.99991718f, 0.99902102f }, { 0.73060786f, 0.72658464f, 0.81348263f, 0.81648708f }, { -0.75762512f, -0.75445002f, -0.74430762f, -0.75485946f } }, { { 0.018332644f, 0.0084005452f, -0.0018937689f, -0.0035491975f }, { 0.0016556654f, 0.0049261013f, -0.021796869f, 0.0025973591f }, { -0.0019671758f, 0.00051947074f, 0.0071261223f, 0.0056689139f }, { 0.00041901024f, -0.0023903288f, -0.0035639711f, -0.0036673013f }, { 0.009963464f, 0.00099195429f, -0.0042516892f, 0.0092605531f }, { 0.0034813664f, 0.0028575465f, -0.016343415f, -0.0014475905f }, { 0.0053571039f, 0.0051116063f, 0.016171091f, -0.00052744238f }, { 0.00013272575f, -0.0095491849f, 0.0070156475f, 0.0017057538f }, { 0.028067438f, -0.0086835729f, -0.0087852674f, 0.0035321054f }, { 0.0025007808f, -0.0075654884f, -0.012551417f, -0.0068823899f }, { -0.00017607308f, 0.002636122f, -0.011272055f, -0.010314896f }, { 0.010646599f, 0.00042804331f, 0.013900837f, -0.01279076f }, { 0.0059898286f, 0.012331371f, -0.0073125296f, 0.016248603f }, { 0.031579315f, -0.0057840222f, -0.00018304192f, 0.005171422f }, { 0.010928513f, 0.0092660887f, 0.030404621f, 0.0053167707f }, { -0.00014899672f, -0.0035246494f, 0.0075862845f, -0.005861723f }, { 0.0067791918f, 0.0021224495f, -0.0071755505f, -0.010370936f }, { 0.0015352958f, -0.0025785166f, -0.0092688001f, 0.003966373f }, { 0.0036915074f, -0.002306452f, -0.005736452f, -0.0033594125f }, { 0.0065128512f, 0.006188005f, 0.00088322638f, -0.0016227066f }, { 0.0092720771f, -0.0046684631f, -7.3769604e-05f, 0.013807013f }, { -0.0031421984f, 0.010622679f, 0.00041591214f, 0.0032786075f }, { -0.0021421613f, -0.0041675589f, -0.0029529994f, -0.00085350449f }, { -0.00069204344f, -0.0010785124f, 0.00097549628f, 0.0025280456f } }, { { 0.018332644f, 0.0084005452f, -0.0018937689f, -0.0035491975f }, { 0.0016556654f, 0.0049261013f, -0.021796869f, 0.0025973591f }, { -0.0019671758f, 0.00051947074f, 0.0071261223f, 0.0056689139f }, { 0.00041901024f, -0.0023903288f, -0.0035639711f, -0.0036673013f }, { 0.009963464f, 0.00099195429f, -0.0042516892f, 0.0092605531f }, { 0.0034813664f, 0.0028575465f, -0.016343415f, -0.0014475905f }, { 0.0053571039f, 0.0051116063f, 0.016171091f, -0.00052744238f }, { 0.00013272575f, -0.0095491849f, 0.0070156475f, 0.0017057538f }, { 0.028067438f, -0.0086835729f, -0.0087852674f, 0.0035321054f }, { 0.0025007808f, -0.0075654884f, -0.012551417f, -0.0068823899f }, { -0.00017607308f, 0.002636122f, -0.011272055f, -0.010314896f }, { 0.010646599f, 0.00042804331f, 0.013900837f, -0.01279076f }, { 0.0059898286f, 0.012331371f, -0.0073125296f, 0.016248603f }, { 0.031579315f, -0.0057840222f, -0.00018304192f, 0.005171422f }, { 0.010928513f, 0.0092660887f, 0.030404621f, 0.0053167707f }, { -0.00014899672f, -0.0035246494f, 0.0075862845f, -0.005861723f }, { 0.0067791918f, 0.0021224495f, -0.0071755505f, -0.010370936f }, { 0.0015352958f, -0.0025785166f, -0.0092688001f, 0.003966373f }, { 0.0036915074f, -0.002306452f, -0.005736452f, -0.0033594125f }, { 0.0065128512f, 0.006188005f, 0.00088322638f, -0.0016227066f }, { 0.0092720771f, -0.0046684631f, -7.3769604e-05f, 0.013807013f }, { -0.0031421984f, 0.010622679f, 0.00041591214f, 0.0032786075f }, { -0.0021421613f, -0.0041675589f, -0.0029529994f, -0.00085350449f }, { -0.00069204344f, -0.0010785124f, 0.00097549628f, 0.0025280456f } } }, { { { 5.3792285f, 5.1960477f, 5.5112916f, 5.6615254f }, { 5.0489877f, 5.2428834f, 5.1752035f, 5.1109826f }, { 5.5205204f, 5.7511938f, 5.0202917f, 4.9168865f }, { 4.9522523f, 4.8880256f, 5.1015936f, 5.2858816f }, { 5.7256502f, 5.7919759f, 5.645241f, 5.6035708f }, { 6.4076931f, 6.4822111f, 6.2642633f, 6.3925959f }, { 6.9797014f, 6.981436f, 7.0028674f, 6.9976464f }, { -0.03290957f, -0.03290957f, -0.03290957f, -0.03290957f }, { 5.4977854f, 5.7684965f, 5.3463095f, 4.8810492f }, { 4.9869047f, 5.4896416f, 4.9647805f, 4.884877f }, { 5.3141219f, 5.3357788f, 4.7695434f, 4.8709631f }, { 5.2056063f, 5.407802f, 5.2123857f, 4.9428208f }, { 6.2188218f, 6.17756f, 6.2751008f, 6.3672109f }, { 6.9105856f, 6.7986798f, 6.5712335f, 6.5907061f }, { 6.9797014f, 6.9797014f, 5.6859993f, 5.5642483f }, { -0.032764603f, -0.032764603f, -0.032764603f, -0.032764603f }, { 5.7724142f, 6.0929556f, 5.99581f, 5.9265164f }, { 4.9363192f, 4.9823732f, 5.1732995f, 5.2475265f }, { 5.8365191f, 5.9972902f, 5.9778441f, 5.9270668f }, { 4.8706768f, 5.0194503f, 5.155585f, 5.2188041f }, { 6.1569904f, 6.0563989f, 6.0989699f, 6.2139837f }, { 5.8727399f, 5.8948086f, 5.5734095f, 5.5536103f }, { 6.9797014f, 6.9797014f, 6.9797014f, 6.9797014f }, { -0.032766769f, -0.032766769f, -0.032766769f, -0.032766769f } }, { { 0.0011802354f, -0.006546101f, -0.02103972f, 0.0008654047f }, { -0.015460534f, 0.017874544f, 0.0029121134f, 0.023511773f }, { -0.040909245f, 0.011927691f, 0.011991588f, 0.01677931f }, { -0.015633544f, -0.0042321141f, 0.026623034f, 0.0080414514f }, { 0.012614382f, 0.0065080145f, 0.035716738f, -0.0080665814f }, { -0.0057849744f, -0.017478461f, -0.031219642f, 0.00016446523f }, { 0.0f, 0.00032235028f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { -0.068586697f, -0.024228236f, -0.012857221f, -0.039493706f }, { -0.018078201f, -0.015140979f, 0.00072119173f, -0.051249859f }, { -0.054228277f, 0.0097895101f, 0.0019832646f, -0.011715411f }, { -0.042326208f, -0.010160072f, 0.037088052f, -0.031848667f }, { 0.00067130897f, -0.013966717f, -0.017268559f, -0.0074614576f }, { 0.070515961f, 0.012848107f, -0.0008396517f, 0.0049006506f }, { 0.0f, 0.0f, -0.063014256f, -0.0085124986f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { -0.040302299f, 0.0048936307f, 0.0064406394f, 0.0034044871f }, { -0.010453589f, 0.0035820836f, -0.017384391f, -0.038199947f }, { -0.044968611f, -0.0088322127f, 0.020303819f, 0.0058131005f }, { -0.0056838535f, 0.010211409f, -0.010999927f, -0.027621859f }, { 0.0064753811f, -0.0059341242f, -0.014902755f, 0.0082868118f }, { -0.0013222735f, 0.0028492181f, -0.023523273f, -0.02576271f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f } }, { { 0.0011802354f, -0.006546101f, -0.02103972f, 0.00086540469f }, { -0.015460534f, 0.017874544f, 0.0029121134f, 0.023511773f }, { -0.040909245f, 0.011927691f, 0.011991588f, 0.01677931f }, { -0.015633544f, -0.0042321141f, 0.026623034f, 0.0080414514f }, { 0.012614382f, 0.0065080145f, 0.035716738f, -0.0080665814f }, { -0.0057849744f, -0.017478461f, -0.031219642f, 0.00016446523f }, { 0.0f, 0.00032235028f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { -0.068586697f, -0.024228236f, -0.012857221f, -0.039493706f }, { -0.018078201f, -0.015140979f, 0.00072119173f, -0.051249859f }, { -0.054228277f, 0.0097895101f, 0.0019832646f, -0.011715411f }, { -0.042326208f, -0.010160072f, 0.037088052f, -0.031848667f }, { 0.00067130897f, -0.013966717f, -0.017268559f, -0.0074614576f }, { 0.070515961f, 0.012848107f, -0.0008396517f, 0.0049006506f }, { 0.0f, 0.0f, -0.063014256f, -0.0085124986f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { -0.040302299f, 0.0048936307f, 0.0064406394f, 0.0034044871f }, { -0.010453589f, 0.0035820836f, -0.017384391f, -0.038199947f }, { -0.044968611f, -0.0088322127f, 0.020303819f, 0.0058131005f }, { -0.0056838535f, 0.010211409f, -0.010999927f, -0.027621859f }, { 0.0064753811f, -0.0059341242f, -0.014902755f, 0.0082868118f }, { -0.0013222735f, 0.0028492181f, -0.023523273f, -0.02576271f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f } } }, { { { 0.72189984f, 0.22069996f, 0.71952927f, 0.77725949f }, { 0.4054405f, 0.20582059f, 0.2747016f, 0.37612563f }, { 0.58887422f, 0.27441131f, 0.19468101f, 0.21480554f }, { 0.46814145f, 0.34317f, 0.46068212f, 0.13962064f }, { -0.18134132f, -0.26668789f, -0.60984999f, -0.67879259f }, { -0.47870351f, -0.34453227f, 0.32494779f, 0.10292971f }, { 0.087252967f, 0.066950358f, 0.31813819f, 0.071094818f }, { -0.0031436256f, 0.038245091f, -0.0076651913f, -0.015389479f }, { 1.2668531f, 1.2894974f, 0.40584018f, 0.51755806f }, { 1.3207257f, 1.3403747f, 0.54924634f, 0.40282713f }, { 0.78581828f, 0.56379328f, 0.27901993f, 0.56429306f }, { 0.8748226f, 1.0271253f, 1.0085726f, 0.3888545f }, { -0.22577636f, -0.32895071f, -0.2846317f, -0.11679531f }, { 0.26477285f, 0.3179447f, -0.063393238f, 0.024059773f }, { -0.15463395f, -0.22721468f, -0.20680404f, -0.15700788f }, { 0.012107106f, -0.0061245949f, -0.024224367f, 0.005040693f }, { 0.97943693f, 0.64840429f, 0.45106998f, 0.40771935f }, { 0.49907853f, 0.1562184f, 0.34338458f, 0.39710628f }, { 0.95047709f, 0.53336107f, 0.38318275f, 0.44919148f }, { 0.41892697f, 0.069965886f, 0.45831656f, 0.38821529f }, { -0.20216736f, -0.43209441f, -0.57684857f, -0.40189427f }, { -0.63992377f, -0.40683032f, -0.59207903f, -0.57251716f }, { -0.047117438f, -0.1880015f, -0.12265155f, 0.00059988607f }, { -0.011836442f, -0.010049497f, -0.0026152072f, 0.016137736f } }, { { 0.092068993f, 0.0045466749f, 0.0054574031f, 0.02582156f }, { 0.022115456f, -0.015664041f, -0.022004653f, 0.041431654f }, { 0.029951298f, -0.0004408542f, 0.0087496069f, 0.017850027f }, { 0.029086373f, 0.022116039f, 0.044010315f, 0.001644876f }, { 0.016256387f, 0.0083249367f, 0.019570849f, -0.0021276222f }, { 0.0079070076f, -0.024696939f, 0.044311101f, 0.023671132f }, { -0.0081796119f, -0.0024995551f, 0.033501743f, -0.031958988f }, { 0.0065005403f, -0.076642001f, 0.015736477f, 0.030966939f }, { 0.029110717f, 0.039154477f, -0.074376619f, 0.025532063f }, { -0.10980761f, 0.0038346834f, 0.014449171f, -0.030702653f }, { -0.00068350423f, -0.037251569f, -0.008409224f, -0.026322878f }, { 0.035406012f, 0.064176275f, 0.031437854f, -0.0344642f }, { 0.037145809f, -0.024909212f, 0.041030386f, 0.035216105f }, { -0.093276646f, -0.013904083f, -0.019536023f, -0.023834405f }, { 0.042751846f, -0.03620164f, 0.081115921f, 0.018379967f }, { -0.023909625f, 0.012833691f, 0.048086442f, -0.0097340268f }, { 0.039552712f, -0.00026806514f, 0.011646753f, 0.0065939486f }, { 0.058985248f, 0.020165701f, 0.0076721521f, 0.033274221f }, { 0.052889871f, 0.0042520093f, 0.016490396f, 0.009287973f }, { 0.044305975f, -0.0016263469f, 0.041390177f, 0.033541355f }, { 0.014595133f, -0.004801042f, -0.0049517302f, 0.015714264f }, { 0.00075086205f, 0.0080838736f, -0.037611057f, -0.030488441f }, { 0.0019178075f, -0.0082517768f, -0.002525773f, 0.0043993022f }, { 0.023774971f, 0.020335611f, 0.0056643868f, -0.032100338f } }, { { 0.092068993f, 0.0045466749f, 0.0054574031f, 0.02582156f }, { 0.022115456f, -0.015664041f, -0.022004653f, 0.041431654f }, { 0.029951298f, -0.0004408542f, 0.0087496069f, 0.017850027f }, { 0.029086373f, 0.022116039f, 0.044010315f, 0.001644876f }, { 0.016256387f, 0.0083249367f, 0.019570849f, -0.0021276222f }, { 0.0079070076f, -0.024696939f, 0.044311101f, 0.023671132f }, { -0.0081796119f, -0.0024995551f, 0.033501743f, -0.031958988f }, { 0.0065005403f, -0.076642001f, 0.015736477f, 0.030966939f }, { 0.029110717f, 0.039154477f, -0.074376619f, 0.025532063f }, { -0.10980761f, 0.0038346834f, 0.014449171f, -0.030702653f }, { -0.00068350423f, -0.037251569f, -0.008409224f, -0.026322878f }, { 0.035406012f, 0.064176275f, 0.031437854f, -0.0344642f }, { 0.037145809f, -0.024909212f, 0.041030386f, 0.035216105f }, { -0.093276646f, -0.013904083f, -0.019536023f, -0.023834405f }, { 0.042751846f, -0.03620164f, 0.081115921f, 0.018379967f }, { -0.023909625f, 0.012833691f, 0.048086442f, -0.0097340268f }, { 0.039552712f, -0.00026806514f, 0.011646753f, 0.0065939486f }, { 0.058985248f, 0.020165701f, 0.0076721521f, 0.033274221f }, { 0.052889871f, 0.0042520093f, 0.016490396f, 0.009287973f }, { 0.044305975f, -0.0016263469f, 0.041390177f, 0.033541355f }, { 0.014595133f, -0.004801042f, -0.0049517303f, 0.015714264f }, { 0.00075086205f, 0.0080838736f, -0.037611057f, -0.030488441f }, { 0.0019178075f, -0.0082517768f, -0.002525773f, 0.0043993022f }, { 0.023774971f, 0.020335611f, 0.0056643868f, -0.032100338f } } } } };
#endif
diff --git a/thirdparty/misc/curl_hostcheck.c b/thirdparty/misc/curl_hostcheck.c
deleted file mode 100644
index feef232619..0000000000
--- a/thirdparty/misc/curl_hostcheck.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-/* This file is an amalgamation of hostcheck.c and most of rawstr.c
- from cURL. The contents of the COPYING file mentioned above are:
-
-COPYRIGHT AND PERMISSION NOTICE
-
-Copyright (c) 1996 - 2013, Daniel Stenberg, <daniel@haxx.se>.
-
-All rights reserved.
-
-Permission to use, copy, modify, and distribute this software for any purpose
-with or without fee is hereby granted, provided that the above copyright
-notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
-NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
-OR OTHER DEALINGS IN THE SOFTWARE.
-
-Except as contained in this notice, the name of a copyright holder shall not
-be used in advertising or otherwise to promote the sale, use or other dealings
-in this Software without prior written authorization of the copyright holder.
-*/
-
-#include "curl_hostcheck.h"
-#include <string.h>
-
-/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
- its behavior is altered by the current locale. */
-static char Curl_raw_toupper(char in)
-{
- switch (in) {
- case 'a':
- return 'A';
- case 'b':
- return 'B';
- case 'c':
- return 'C';
- case 'd':
- return 'D';
- case 'e':
- return 'E';
- case 'f':
- return 'F';
- case 'g':
- return 'G';
- case 'h':
- return 'H';
- case 'i':
- return 'I';
- case 'j':
- return 'J';
- case 'k':
- return 'K';
- case 'l':
- return 'L';
- case 'm':
- return 'M';
- case 'n':
- return 'N';
- case 'o':
- return 'O';
- case 'p':
- return 'P';
- case 'q':
- return 'Q';
- case 'r':
- return 'R';
- case 's':
- return 'S';
- case 't':
- return 'T';
- case 'u':
- return 'U';
- case 'v':
- return 'V';
- case 'w':
- return 'W';
- case 'x':
- return 'X';
- case 'y':
- return 'Y';
- case 'z':
- return 'Z';
- }
- return in;
-}
-
-/*
- * Curl_raw_equal() is for doing "raw" case insensitive strings. This is meant
- * to be locale independent and only compare strings we know are safe for
- * this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for
- * some further explanation to why this function is necessary.
- *
- * The function is capable of comparing a-z case insensitively even for
- * non-ascii.
- */
-
-static int Curl_raw_equal(const char *first, const char *second)
-{
- while(*first && *second) {
- if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
- /* get out of the loop as soon as they don't match */
- break;
- first++;
- second++;
- }
- /* we do the comparison here (possibly again), just to make sure that if the
- loop above is skipped because one of the strings reached zero, we must not
- return this as a successful match */
- return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
-}
-
-static int Curl_raw_nequal(const char *first, const char *second, size_t max)
-{
- while(*first && *second && max) {
- if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
- break;
- }
- max--;
- first++;
- second++;
- }
- if(0 == max)
- return 1; /* they are equal this far */
-
- return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
-}
-
-/*
- * Match a hostname against a wildcard pattern.
- * E.g.
- * "foo.host.com" matches "*.host.com".
- *
- * We use the matching rule described in RFC6125, section 6.4.3.
- * http://tools.ietf.org/html/rfc6125#section-6.4.3
- */
-
-static int hostmatch(const char *hostname, const char *pattern)
-{
- const char *pattern_label_end, *pattern_wildcard, *hostname_label_end;
- int wildcard_enabled;
- size_t prefixlen, suffixlen;
- pattern_wildcard = strchr(pattern, '*');
- if(pattern_wildcard == NULL)
- return Curl_raw_equal(pattern, hostname) ?
- CURL_HOST_MATCH : CURL_HOST_NOMATCH;
-
- /* We require at least 2 dots in pattern to avoid too wide wildcard
- match. */
- wildcard_enabled = 1;
- pattern_label_end = strchr(pattern, '.');
- if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
- pattern_wildcard > pattern_label_end ||
- Curl_raw_nequal(pattern, "xn--", 4)) {
- wildcard_enabled = 0;
- }
- if(!wildcard_enabled)
- return Curl_raw_equal(pattern, hostname) ?
- CURL_HOST_MATCH : CURL_HOST_NOMATCH;
-
- hostname_label_end = strchr(hostname, '.');
- if(hostname_label_end == NULL ||
- !Curl_raw_equal(pattern_label_end, hostname_label_end))
- return CURL_HOST_NOMATCH;
-
- /* The wildcard must match at least one character, so the left-most
- label of the hostname is at least as large as the left-most label
- of the pattern. */
- if(hostname_label_end - hostname < pattern_label_end - pattern)
- return CURL_HOST_NOMATCH;
-
- prefixlen = pattern_wildcard - pattern;
- suffixlen = pattern_label_end - (pattern_wildcard+1);
- return Curl_raw_nequal(pattern, hostname, prefixlen) &&
- Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
- suffixlen) ?
- CURL_HOST_MATCH : CURL_HOST_NOMATCH;
-}
-
-int Tool_Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
-{
- if(!match_pattern || !*match_pattern ||
- !hostname || !*hostname) /* sanity check */
- return 0;
-
- if(Curl_raw_equal(hostname, match_pattern)) /* trivial case */
- return 1;
-
- if(hostmatch(hostname,match_pattern) == CURL_HOST_MATCH)
- return 1;
- return 0;
-}
diff --git a/thirdparty/misc/curl_hostcheck.h b/thirdparty/misc/curl_hostcheck.h
deleted file mode 100644
index 1b7fbe81e3..0000000000
--- a/thirdparty/misc/curl_hostcheck.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef HEADER_TOOL_CURL_HOSTCHECK_H
-#define HEADER_TOOL_CURL_HOSTCHECK_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
- * \___|\___/|_| \_\_____|
- *
- * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
- *
- * This software is licensed as described in the file COPYING, which
- * you should have received as part of this distribution. The terms
- * are also available at http://curl.haxx.se/docs/copyright.html.
- *
- * You may opt to use, copy, modify, merge, publish, distribute and/or sell
- * copies of the Software, and permit persons to whom the Software is
- * furnished to do so, under the terms of the COPYING file.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ***************************************************************************/
-
-#define CURL_HOST_NOMATCH 0
-#define CURL_HOST_MATCH 1
-int Tool_Curl_cert_hostcheck(const char *match_pattern, const char *hostname);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* HEADER_CURL_HOSTCHECK_H */
-
diff --git a/thirdparty/misc/fastlz.c b/thirdparty/misc/fastlz.c
index 508f6ea2ae..b4d2dd3c29 100644
--- a/thirdparty/misc/fastlz.c
+++ b/thirdparty/misc/fastlz.c
@@ -1,9 +1,6 @@
- /*
- FastLZ - lightning-fast lossless compression library
-
- Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
- Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
- Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
+/*
+ FastLZ - Byte-aligned LZ77 compression library
+ Copyright (C) 2005-2020 Ariya Hidayat <ariya.hidayat@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -24,239 +21,375 @@
THE SOFTWARE.
*/
-#if !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
+#include "fastlz.h"
+
+#include <stdint.h>
/*
* Always check for bound when decompressing.
* Generally it is best to leave it defined.
*/
#define FASTLZ_SAFE
+#if defined(FASTLZ_USE_SAFE_DECOMPRESSOR) && (FASTLZ_USE_SAFE_DECOMPRESSOR == 0)
+#undef FASTLZ_SAFE
+#endif
/*
* Give hints to the compiler for branch prediction optimization.
*/
-#if defined(__GNUC__) && (__GNUC__ > 2)
-#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
-#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
+#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 2))
+#define FASTLZ_LIKELY(c) (__builtin_expect(!!(c), 1))
+#define FASTLZ_UNLIKELY(c) (__builtin_expect(!!(c), 0))
#else
-#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
-#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
+#define FASTLZ_LIKELY(c) (c)
+#define FASTLZ_UNLIKELY(c) (c)
#endif
-/*
- * Use inlined functions for supported systems.
- */
-#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
-#define FASTLZ_INLINE inline
-#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
-#define FASTLZ_INLINE __inline
-#else
-#define FASTLZ_INLINE
+#if defined(FASTLZ_SAFE)
+#define FASTLZ_BOUND_CHECK(cond) \
+ if (FASTLZ_UNLIKELY(!(cond))) return 0;
+#else
+#define FASTLZ_BOUND_CHECK(cond) \
+ do { \
+ } while (0)
#endif
-/*
- * Prevent accessing more than 8-bit at once, except on x86 architectures.
- */
-#if !defined(FASTLZ_STRICT_ALIGN)
-#define FASTLZ_STRICT_ALIGN
-#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */
-#undef FASTLZ_STRICT_ALIGN
-#elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */
-#undef FASTLZ_STRICT_ALIGN
-#elif defined(_M_IX86) /* Intel, MSVC */
-#undef FASTLZ_STRICT_ALIGN
-#elif defined(__386)
-#undef FASTLZ_STRICT_ALIGN
-#elif defined(_X86_) /* MinGW */
-#undef FASTLZ_STRICT_ALIGN
-#elif defined(__I86__) /* Digital Mars */
-#undef FASTLZ_STRICT_ALIGN
-#endif
-#endif
+#define MAX_COPY 32
+#define MAX_LEN 264 /* 256 + 8 */
+#define MAX_L1_DISTANCE 8192
+#define MAX_L2_DISTANCE 8191
+#define MAX_FARDISTANCE (65535 + MAX_L2_DISTANCE - 1)
+
+#define FASTLZ_READU16(p) ((p)[0] | (p)[1] << 8)
+
+#define HASH_LOG 13
+#define HASH_SIZE (1 << HASH_LOG)
+#define HASH_MASK (HASH_SIZE - 1)
+#define HASH_FUNCTION(v, p) \
+ { \
+ v = FASTLZ_READU16(p); \
+ v ^= FASTLZ_READU16(p + 1) ^ (v >> (16 - HASH_LOG)); \
+ v &= HASH_MASK; \
+ }
-/*
- * FIXME: use preprocessor magic to set this on different platforms!
- */
-typedef unsigned char flzuint8;
-typedef unsigned short flzuint16;
-typedef unsigned int flzuint32;
+int fastlz1_compress(const void* input, int length, void* output) {
+ const uint8_t* ip = (const uint8_t*)input;
+ const uint8_t* ip_bound = ip + length - 2;
+ const uint8_t* ip_limit = ip + length - 12 - 1;
+ uint8_t* op = (uint8_t*)output;
-/* prototypes */
-int fastlz_compress(const void* input, int length, void* output);
-int fastlz_compress_level(int level, const void* input, int length, void* output);
-int fastlz_decompress(const void* input, int length, void* output, int maxout);
+ const uint8_t* htab[HASH_SIZE];
+ uint32_t hval;
-#define MAX_COPY 32
-#define MAX_LEN 264 /* 256 + 8 */
-#define MAX_DISTANCE 8192
+ uint32_t copy;
-#if !defined(FASTLZ_STRICT_ALIGN)
-#define FASTLZ_READU16(p) *((const flzuint16*)(p))
-#else
-#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
-#endif
+ /* sanity check */
+ if (FASTLZ_UNLIKELY(length < 4)) {
+ if (length) {
+ /* create literal copy only */
+ *op++ = length - 1;
+ ip_bound++;
+ while (ip <= ip_bound) *op++ = *ip++;
+ return length + 1;
+ } else
+ return 0;
+ }
-#define HASH_LOG 13
-#define HASH_SIZE (1<< HASH_LOG)
-#define HASH_MASK (HASH_SIZE-1)
-#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
-
-#undef FASTLZ_LEVEL
-#define FASTLZ_LEVEL 1
-
-#undef FASTLZ_COMPRESSOR
-#undef FASTLZ_DECOMPRESSOR
-#define FASTLZ_COMPRESSOR fastlz1_compress
-#define FASTLZ_DECOMPRESSOR fastlz1_decompress
-static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
-static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
-#include "fastlz.c"
-
-#undef FASTLZ_LEVEL
-#define FASTLZ_LEVEL 2
-
-#undef MAX_DISTANCE
-#define MAX_DISTANCE 8191
-#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
-
-#undef FASTLZ_COMPRESSOR
-#undef FASTLZ_DECOMPRESSOR
-#define FASTLZ_COMPRESSOR fastlz2_compress
-#define FASTLZ_DECOMPRESSOR fastlz2_decompress
-static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
-static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
-#include "fastlz.c"
-
-int fastlz_compress(const void* input, int length, void* output)
-{
- /* for short block, choose fastlz1 */
- if(length < 65536)
- return fastlz1_compress(input, length, output);
+ /* initializes hash table */
+ for (hval = 0; hval < HASH_SIZE; ++hval) htab[hval] = ip;
- /* else... */
- return fastlz2_compress(input, length, output);
+ /* we start with literal copy */
+ copy = 2;
+ *op++ = MAX_COPY - 1;
+ *op++ = *ip++;
+ *op++ = *ip++;
+
+ /* main loop */
+ while (FASTLZ_LIKELY(ip < ip_limit)) {
+ const uint8_t* ref;
+ uint32_t distance;
+
+ /* minimum match length */
+ uint32_t len = 3;
+
+ /* comparison starting-point */
+ const uint8_t* anchor = ip;
+
+ /* find potential match */
+ HASH_FUNCTION(hval, ip);
+ ref = htab[hval];
+
+ /* update hash table */
+ htab[hval] = anchor;
+
+ /* calculate distance to the match */
+ distance = anchor - ref;
+
+ /* is this a match? check the first 3 bytes */
+ if (distance == 0 || (distance >= MAX_L1_DISTANCE) || *ref++ != *ip++ ||
+ *ref++ != *ip++ || *ref++ != *ip++)
+ goto literal;
+
+ /* last matched byte */
+ ip = anchor + len;
+
+ /* distance is biased */
+ distance--;
+
+ if (!distance) {
+ /* zero distance means a run */
+ uint8_t x = ip[-1];
+ while (ip < ip_bound)
+ if (*ref++ != x)
+ break;
+ else
+ ip++;
+ } else
+ for (;;) {
+ /* safe because the outer check against ip limit */
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ while (ip < ip_bound)
+ if (*ref++ != *ip++) break;
+ break;
+ }
+
+ /* if we have copied something, adjust the copy count */
+ if (copy) /* copy is biased, '0' means 1 byte copy */
+ *(op - copy - 1) = copy - 1;
+ else
+ /* back, to overwrite the copy count */
+ op--;
+
+ /* reset literal counter */
+ copy = 0;
+
+ /* length is biased, '1' means a match of 3 bytes */
+ ip -= 3;
+ len = ip - anchor;
+
+ /* encode the match */
+ if (FASTLZ_UNLIKELY(len > MAX_LEN - 2))
+ while (len > MAX_LEN - 2) {
+ *op++ = (7 << 5) + (distance >> 8);
+ *op++ = MAX_LEN - 2 - 7 - 2;
+ *op++ = (distance & 255);
+ len -= MAX_LEN - 2;
+ }
+
+ if (len < 7) {
+ *op++ = (len << 5) + (distance >> 8);
+ *op++ = (distance & 255);
+ } else {
+ *op++ = (7 << 5) + (distance >> 8);
+ *op++ = len - 7;
+ *op++ = (distance & 255);
+ }
+
+ /* update the hash at match boundary */
+ HASH_FUNCTION(hval, ip);
+ htab[hval] = ip++;
+ HASH_FUNCTION(hval, ip);
+ htab[hval] = ip++;
+
+ /* assuming literal copy */
+ *op++ = MAX_COPY - 1;
+
+ continue;
+
+ literal:
+ *op++ = *anchor++;
+ ip = anchor;
+ copy++;
+ if (FASTLZ_UNLIKELY(copy == MAX_COPY)) {
+ copy = 0;
+ *op++ = MAX_COPY - 1;
+ }
+ }
+
+ /* left-over as literal copy */
+ ip_bound++;
+ while (ip <= ip_bound) {
+ *op++ = *ip++;
+ copy++;
+ if (copy == MAX_COPY) {
+ copy = 0;
+ *op++ = MAX_COPY - 1;
+ }
+ }
+
+ /* if we have copied something, adjust the copy length */
+ if (copy)
+ *(op - copy - 1) = copy - 1;
+ else
+ op--;
+
+ return op - (uint8_t*)output;
}
-int fastlz_decompress(const void* input, int length, void* output, int maxout)
-{
- /* magic identifier for compression level */
- int level = ((*(const flzuint8*)input) >> 5) + 1;
+#if defined(FASTLZ_USE_MEMMOVE) && (FASTLZ_USE_MEMMOVE == 0)
- if(level == 1)
- return fastlz1_decompress(input, length, output, maxout);
- if(level == 2)
- return fastlz2_decompress(input, length, output, maxout);
+static void fastlz_memmove(uint8_t* dest, const uint8_t* src, uint32_t count) {
+ do {
+ *dest++ = *src++;
+ } while (--count);
+}
- /* unknown level, trigger error */
- return 0;
+static void fastlz_memcpy(uint8_t* dest, const uint8_t* src, uint32_t count) {
+ return fastlz_memmove(dest, src, count);
}
-int fastlz_compress_level(int level, const void* input, int length, void* output)
-{
- if(level == 1)
- return fastlz1_compress(input, length, output);
- if(level == 2)
- return fastlz2_compress(input, length, output);
+#else
- return 0;
+#include <string.h>
+
+static void fastlz_memmove(uint8_t* dest, const uint8_t* src, uint32_t count) {
+ if ((count > 4) && (dest >= src + count)) {
+ memmove(dest, src, count);
+ } else {
+ switch (count) {
+ default:
+ do {
+ *dest++ = *src++;
+ } while (--count);
+ break;
+ case 3:
+ *dest++ = *src++;
+ case 2:
+ *dest++ = *src++;
+ case 1:
+ *dest++ = *src++;
+ case 0:
+ break;
+ }
+ }
+}
+
+static void fastlz_memcpy(uint8_t* dest, const uint8_t* src, uint32_t count) {
+ memcpy(dest, src, count);
}
-#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
+#endif
-static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output)
-{
- const flzuint8* ip = (const flzuint8*) input;
- const flzuint8* ip_bound = ip + length - 2;
- const flzuint8* ip_limit = ip + length - 12;
- flzuint8* op = (flzuint8*) output;
+int fastlz1_decompress(const void* input, int length, void* output,
+ int maxout) {
+ const uint8_t* ip = (const uint8_t*)input;
+ const uint8_t* ip_limit = ip + length;
+ const uint8_t* ip_bound = ip_limit - 2;
+ uint8_t* op = (uint8_t*)output;
+ uint8_t* op_limit = op + maxout;
+ uint32_t ctrl = (*ip++) & 31;
+
+ while (1) {
+ if (ctrl >= 32) {
+ uint32_t len = (ctrl >> 5) - 1;
+ uint32_t ofs = (ctrl & 31) << 8;
+ const uint8_t* ref = op - ofs - 1;
+ if (len == 7 - 1) {
+ FASTLZ_BOUND_CHECK(ip <= ip_bound);
+ len += *ip++;
+ }
+ ref -= *ip++;
+ len += 3;
+ FASTLZ_BOUND_CHECK(op + len <= op_limit);
+ FASTLZ_BOUND_CHECK(ref >= (uint8_t*)output);
+ fastlz_memmove(op, ref, len);
+ op += len;
+ } else {
+ ctrl++;
+ FASTLZ_BOUND_CHECK(op + ctrl <= op_limit);
+ FASTLZ_BOUND_CHECK(ip + ctrl <= ip_limit);
+ fastlz_memcpy(op, ip, ctrl);
+ ip += ctrl;
+ op += ctrl;
+ }
- const flzuint8* htab[HASH_SIZE];
- const flzuint8** hslot;
- flzuint32 hval;
+ if (FASTLZ_UNLIKELY(ip > ip_bound)) break;
+ ctrl = *ip++;
+ }
+
+ return op - (uint8_t*)output;
+}
- flzuint32 copy;
+int fastlz2_compress(const void* input, int length, void* output) {
+ const uint8_t* ip = (const uint8_t*)input;
+ const uint8_t* ip_bound = ip + length - 2;
+ const uint8_t* ip_limit = ip + length - 12 - 1;
+ uint8_t* op = (uint8_t*)output;
+
+ const uint8_t* htab[HASH_SIZE];
+ uint32_t hval;
+
+ uint32_t copy;
/* sanity check */
- if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
- {
- if(length)
- {
+ if (FASTLZ_UNLIKELY(length < 4)) {
+ if (length) {
/* create literal copy only */
- *op++ = length-1;
+ *op++ = length - 1;
ip_bound++;
- while(ip <= ip_bound)
- *op++ = *ip++;
- return length+1;
- }
- else
+ while (ip <= ip_bound) *op++ = *ip++;
+ return length + 1;
+ } else
return 0;
}
/* initializes hash table */
- for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
- *hslot = ip;
+ for (hval = 0; hval < HASH_SIZE; ++hval) htab[hval] = ip;
/* we start with literal copy */
copy = 2;
- *op++ = MAX_COPY-1;
+ *op++ = MAX_COPY - 1;
*op++ = *ip++;
*op++ = *ip++;
/* main loop */
- while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
- {
- const flzuint8* ref;
- flzuint32 distance;
+ while (FASTLZ_LIKELY(ip < ip_limit)) {
+ const uint8_t* ref;
+ uint32_t distance;
/* minimum match length */
- flzuint32 len = 3;
+ uint32_t len = 3;
/* comparison starting-point */
- const flzuint8* anchor = ip;
+ const uint8_t* anchor = ip;
/* check for a run */
-#if FASTLZ_LEVEL==2
- if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
- {
+ if (ip[0] == ip[-1] && ip[0] == ip[1] && ip[1] == ip[2]) {
distance = 1;
ip += 3;
ref = anchor - 1 + 3;
goto match;
}
-#endif
/* find potential match */
- HASH_FUNCTION(hval,ip);
- hslot = htab + hval;
+ HASH_FUNCTION(hval, ip);
ref = htab[hval];
+ /* update hash table */
+ htab[hval] = anchor;
+
/* calculate distance to the match */
distance = anchor - ref;
- /* update hash table */
- *hslot = anchor;
-
/* is this a match? check the first 3 bytes */
- if(distance==0 ||
-#if FASTLZ_LEVEL==1
- (distance >= MAX_DISTANCE) ||
-#else
- (distance >= MAX_FARDISTANCE) ||
-#endif
- *ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
+ if (distance == 0 || (distance >= MAX_FARDISTANCE) || *ref++ != *ip++ ||
+ *ref++ != *ip++ || *ref++ != *ip++)
goto literal;
-#if FASTLZ_LEVEL==2
/* far, needs at least 5-byte match */
- if(distance >= MAX_DISTANCE)
- {
- if(*ip++ != *ref++ || *ip++!= *ref++)
- goto literal;
+ if (distance >= MAX_L2_DISTANCE) {
+ if (*ip++ != *ref++ || *ip++ != *ref++) goto literal;
len += 2;
}
-
- match:
-#endif
+
+ match:
/* last matched byte */
ip = anchor + len;
@@ -264,34 +397,33 @@ static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void*
/* distance is biased */
distance--;
- if(!distance)
- {
+ if (!distance) {
/* zero distance means a run */
- flzuint8 x = ip[-1];
- while(ip < ip_bound)
- if(*ref++ != x) break; else ip++;
- }
- else
- for(;;)
- {
- /* safe because the outer check against ip limit */
- if(*ref++ != *ip++) break;
- if(*ref++ != *ip++) break;
- if(*ref++ != *ip++) break;
- if(*ref++ != *ip++) break;
- if(*ref++ != *ip++) break;
- if(*ref++ != *ip++) break;
- if(*ref++ != *ip++) break;
- if(*ref++ != *ip++) break;
- while(ip < ip_bound)
- if(*ref++ != *ip++) break;
- break;
- }
+ uint8_t x = ip[-1];
+ while (ip < ip_bound)
+ if (*ref++ != x)
+ break;
+ else
+ ip++;
+ } else
+ for (;;) {
+ /* safe because the outer check against ip limit */
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ if (*ref++ != *ip++) break;
+ while (ip < ip_bound)
+ if (*ref++ != *ip++) break;
+ break;
+ }
/* if we have copied something, adjust the copy count */
- if(copy)
- /* copy is biased, '0' means 1 byte copy */
- *(op-copy-1) = copy-1;
+ if (copy) /* copy is biased, '0' means 1 byte copy */
+ *(op - copy - 1) = copy - 1;
else
/* back, to overwrite the copy count */
op--;
@@ -304,248 +436,156 @@ static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void*
len = ip - anchor;
/* encode the match */
-#if FASTLZ_LEVEL==2
- if(distance < MAX_DISTANCE)
- {
- if(len < 7)
- {
+ if (distance < MAX_L2_DISTANCE) {
+ if (len < 7) {
*op++ = (len << 5) + (distance >> 8);
*op++ = (distance & 255);
- }
- else
- {
+ } else {
*op++ = (7 << 5) + (distance >> 8);
- for(len-=7; len >= 255; len-= 255)
- *op++ = 255;
+ for (len -= 7; len >= 255; len -= 255) *op++ = 255;
*op++ = len;
*op++ = (distance & 255);
}
- }
- else
- {
+ } else {
/* far away, but not yet in the another galaxy... */
- if(len < 7)
- {
- distance -= MAX_DISTANCE;
+ if (len < 7) {
+ distance -= MAX_L2_DISTANCE;
*op++ = (len << 5) + 31;
*op++ = 255;
*op++ = distance >> 8;
*op++ = distance & 255;
- }
- else
- {
- distance -= MAX_DISTANCE;
+ } else {
+ distance -= MAX_L2_DISTANCE;
*op++ = (7 << 5) + 31;
- for(len-=7; len >= 255; len-= 255)
- *op++ = 255;
+ for (len -= 7; len >= 255; len -= 255) *op++ = 255;
*op++ = len;
*op++ = 255;
*op++ = distance >> 8;
*op++ = distance & 255;
}
}
-#else
-
- if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
- while(len > MAX_LEN-2)
- {
- *op++ = (7 << 5) + (distance >> 8);
- *op++ = MAX_LEN - 2 - 7 -2;
- *op++ = (distance & 255);
- len -= MAX_LEN-2;
- }
-
- if(len < 7)
- {
- *op++ = (len << 5) + (distance >> 8);
- *op++ = (distance & 255);
- }
- else
- {
- *op++ = (7 << 5) + (distance >> 8);
- *op++ = len - 7;
- *op++ = (distance & 255);
- }
-#endif
/* update the hash at match boundary */
- HASH_FUNCTION(hval,ip);
+ HASH_FUNCTION(hval, ip);
htab[hval] = ip++;
- HASH_FUNCTION(hval,ip);
+ HASH_FUNCTION(hval, ip);
htab[hval] = ip++;
/* assuming literal copy */
- *op++ = MAX_COPY-1;
+ *op++ = MAX_COPY - 1;
continue;
- literal:
- *op++ = *anchor++;
- ip = anchor;
- copy++;
- if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
- {
- copy = 0;
- *op++ = MAX_COPY-1;
- }
+ literal:
+ *op++ = *anchor++;
+ ip = anchor;
+ copy++;
+ if (FASTLZ_UNLIKELY(copy == MAX_COPY)) {
+ copy = 0;
+ *op++ = MAX_COPY - 1;
+ }
}
/* left-over as literal copy */
ip_bound++;
- while(ip <= ip_bound)
- {
+ while (ip <= ip_bound) {
*op++ = *ip++;
copy++;
- if(copy == MAX_COPY)
- {
+ if (copy == MAX_COPY) {
copy = 0;
- *op++ = MAX_COPY-1;
+ *op++ = MAX_COPY - 1;
}
}
/* if we have copied something, adjust the copy length */
- if(copy)
- *(op-copy-1) = copy-1;
+ if (copy)
+ *(op - copy - 1) = copy - 1;
else
op--;
-#if FASTLZ_LEVEL==2
/* marker for fastlz2 */
- *(flzuint8*)output |= (1 << 5);
-#endif
+ *(uint8_t*)output |= (1 << 5);
- return op - (flzuint8*)output;
+ return op - (uint8_t*)output;
}
-static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout)
-{
- const flzuint8* ip = (const flzuint8*) input;
- const flzuint8* ip_limit = ip + length;
- flzuint8* op = (flzuint8*) output;
- flzuint8* op_limit = op + maxout;
- flzuint32 ctrl = (*ip++) & 31;
- int loop = 1;
-
- do
- {
- const flzuint8* ref = op;
- flzuint32 len = ctrl >> 5;
- flzuint32 ofs = (ctrl & 31) << 8;
-
- if(ctrl >= 32)
- {
-#if FASTLZ_LEVEL==2
- flzuint8 code;
-#endif
- len--;
- ref -= ofs;
- if (len == 7-1)
-#if FASTLZ_LEVEL==1
- len += *ip++;
- ref -= *ip++;
-#else
- do
- {
+int fastlz2_decompress(const void* input, int length, void* output,
+ int maxout) {
+ const uint8_t* ip = (const uint8_t*)input;
+ const uint8_t* ip_limit = ip + length;
+ const uint8_t* ip_bound = ip_limit - 2;
+ uint8_t* op = (uint8_t*)output;
+ uint8_t* op_limit = op + maxout;
+ uint32_t ctrl = (*ip++) & 31;
+
+ while (1) {
+ if (ctrl >= 32) {
+ uint32_t len = (ctrl >> 5) - 1;
+ uint32_t ofs = (ctrl & 31) << 8;
+ const uint8_t* ref = op - ofs - 1;
+
+ uint8_t code;
+ if (len == 7 - 1) do {
+ FASTLZ_BOUND_CHECK(ip <= ip_bound);
code = *ip++;
len += code;
- } while (code==255);
+ } while (code == 255);
code = *ip++;
ref -= code;
+ len += 3;
/* match from 16-bit distance */
- if(FASTLZ_UNEXPECT_CONDITIONAL(code==255))
- if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
- {
- ofs = (*ip++) << 8;
- ofs += *ip++;
- ref = op - ofs - MAX_DISTANCE;
- }
-#endif
-
-#ifdef FASTLZ_SAFE
- if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
- return 0;
-
- if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
- return 0;
-#endif
-
- if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
- ctrl = *ip++;
- else
- loop = 0;
-
- if(ref == op)
- {
- /* optimize copy for a run */
- flzuint8 b = ref[-1];
- *op++ = b;
- *op++ = b;
- *op++ = b;
- for(; len; --len)
- *op++ = b;
- }
- else
- {
-#if !defined(FASTLZ_STRICT_ALIGN)
- const flzuint16* p;
- flzuint16* q;
-#endif
- /* copy from reference */
- ref--;
- *op++ = *ref++;
- *op++ = *ref++;
- *op++ = *ref++;
-
-#if !defined(FASTLZ_STRICT_ALIGN)
- /* copy a byte, so that now it's word aligned */
- if(len & 1)
- {
- *op++ = *ref++;
- len--;
+ if (FASTLZ_UNLIKELY(code == 255))
+ if (FASTLZ_LIKELY(ofs == (31 << 8))) {
+ FASTLZ_BOUND_CHECK(ip < ip_bound);
+ ofs = (*ip++) << 8;
+ ofs += *ip++;
+ ref = op - ofs - MAX_L2_DISTANCE - 1;
}
- /* copy 16-bit at once */
- q = (flzuint16*) op;
- op += len;
- p = (const flzuint16*) ref;
- for(len>>=1; len > 4; len-=4)
- {
- *q++ = *p++;
- *q++ = *p++;
- *q++ = *p++;
- *q++ = *p++;
- }
- for(; len; --len)
- *q++ = *p++;
-#else
- for(; len; --len)
- *op++ = *ref++;
-#endif
- }
- }
- else
- {
+ FASTLZ_BOUND_CHECK(op + len <= op_limit);
+ FASTLZ_BOUND_CHECK(ref >= (uint8_t*)output);
+ fastlz_memmove(op, ref, len);
+ op += len;
+ } else {
ctrl++;
-#ifdef FASTLZ_SAFE
- if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
- return 0;
- if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
- return 0;
-#endif
-
- *op++ = *ip++;
- for(--ctrl; ctrl; ctrl--)
- *op++ = *ip++;
-
- loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
- if(loop)
- ctrl = *ip++;
+ FASTLZ_BOUND_CHECK(op + ctrl <= op_limit);
+ FASTLZ_BOUND_CHECK(ip + ctrl <= ip_limit);
+ fastlz_memcpy(op, ip, ctrl);
+ ip += ctrl;
+ op += ctrl;
}
+
+ if (FASTLZ_UNLIKELY(ip >= ip_limit)) break;
+ ctrl = *ip++;
}
- while(FASTLZ_EXPECT_CONDITIONAL(loop));
- return op - (flzuint8*)output;
+ return op - (uint8_t*)output;
}
-#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
+int fastlz_compress(const void* input, int length, void* output) {
+ /* for short block, choose fastlz1 */
+ if (length < 65536) return fastlz1_compress(input, length, output);
+
+ /* else... */
+ return fastlz2_compress(input, length, output);
+}
+
+int fastlz_decompress(const void* input, int length, void* output, int maxout) {
+ /* magic identifier for compression level */
+ int level = ((*(const uint8_t*)input) >> 5) + 1;
+
+ if (level == 1) return fastlz1_decompress(input, length, output, maxout);
+ if (level == 2) return fastlz2_decompress(input, length, output, maxout);
+
+ /* unknown level, trigger error */
+ return 0;
+}
+
+int fastlz_compress_level(int level, const void* input, int length,
+ void* output) {
+ if (level == 1) return fastlz1_compress(input, length, output);
+ if (level == 2) return fastlz2_compress(input, length, output);
+
+ return 0;
+}
diff --git a/thirdparty/misc/fastlz.h b/thirdparty/misc/fastlz.h
index e5ca8dfc02..e53dbfbb56 100644
--- a/thirdparty/misc/fastlz.h
+++ b/thirdparty/misc/fastlz.h
@@ -1,9 +1,6 @@
/*
- FastLZ - lightning-fast lossless compression library
-
- Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
- Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
- Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
+ FastLZ - Byte-aligned LZ77 compression library
+ Copyright (C) 2005-2020 Ariya Hidayat <ariya.hidayat@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -27,15 +24,15 @@
#ifndef FASTLZ_H
#define FASTLZ_H
-#define FASTLZ_VERSION 0x000100
+#define FASTLZ_VERSION 0x000500
-#define FASTLZ_VERSION_MAJOR 0
-#define FASTLZ_VERSION_MINOR 0
-#define FASTLZ_VERSION_REVISION 0
+#define FASTLZ_VERSION_MAJOR 0
+#define FASTLZ_VERSION_MINOR 5
+#define FASTLZ_VERSION_REVISION 0
-#define FASTLZ_VERSION_STRING "0.1.0"
+#define FASTLZ_VERSION_STRING "0.5.0"
-#if defined (__cplusplus)
+#if defined(__cplusplus)
extern "C" {
#endif
@@ -51,9 +48,18 @@ extern "C" {
length (input buffer size).
The input buffer and the output buffer can not overlap.
+
+ Compression level can be specified in parameter level. At the moment,
+ only level 1 and level 2 are supported.
+ Level 1 is the fastest compression and generally useful for short data.
+ Level 2 is slightly slower but it gives better compression ratio.
+
+ Note that the compressed data, regardless of the level, can always be
+ decompressed using the function fastlz_decompress below.
*/
-int fastlz_compress(const void* input, int length, void* output);
+int fastlz_compress_level(int level, const void* input, int length,
+ void* output);
/**
Decompress a block of compressed data and returns the size of the
@@ -65,35 +71,27 @@ int fastlz_compress(const void* input, int length, void* output);
Decompression is memory safe and guaranteed not to write the output buffer
more than what is specified in maxout.
+
+ Note that the decompression will always work, regardless of the
+ compression level specified in fastlz_compress_level above (when
+ producing the compressed block).
*/
int fastlz_decompress(const void* input, int length, void* output, int maxout);
/**
- Compress a block of data in the input buffer and returns the size of
- compressed block. The size of input buffer is specified by length. The
- minimum input buffer size is 16.
+ DEPRECATED.
- The output buffer must be at least 5% larger than the input buffer
- and can not be smaller than 66 bytes.
-
- If the input is not compressible, the return value might be larger than
- length (input buffer size).
+ This is similar to fastlz_compress_level above, but with the level
+ automatically chosen.
- The input buffer and the output buffer can not overlap.
-
- Compression level can be specified in parameter level. At the moment,
- only level 1 and level 2 are supported.
- Level 1 is the fastest compression and generally useful for short data.
- Level 2 is slightly slower but it gives better compression ratio.
-
- Note that the compressed data, regardless of the level, can always be
- decompressed using the function fastlz_decompress above.
+ This function is deprecated and it will be completely removed in some future
+ version.
*/
-int fastlz_compress_level(int level, const void* input, int length, void* output);
+int fastlz_compress(const void* input, int length, void* output);
-#if defined (__cplusplus)
+#if defined(__cplusplus)
}
#endif
diff --git a/thirdparty/misc/hq2x.cpp b/thirdparty/misc/hq2x.cpp
deleted file mode 100644
index 9c089ba85c..0000000000
--- a/thirdparty/misc/hq2x.cpp
+++ /dev/null
@@ -1,2636 +0,0 @@
-/*
- * Copyright 2016 Bruno Ribeiro
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include "hq2x.h"
-
-#include "core/math/math_funcs.h"
-
-static const uint32_t AMASK = 0xFF000000;
-static const uint32_t YMASK = 0x00FF0000;
-static const uint32_t UMASK = 0x0000FF00;
-static const uint32_t VMASK = 0x000000FF;
-
-_FORCE_INLINE_ static uint32_t ARGBtoAYUV(
- uint32_t value )
-{
- uint32_t A, R, G, B, Y, U, V;
-//todo big endian check
- A = value >> 24;
- R = (value >> 16) & 0xFF;
- G = (value >> 8) & 0xFF;
- B = value & 0xFF;
-
- Y = Math::fast_ftoi( 0.299 * R + 0.587 * G + 0.114 * B);
- U = Math::fast_ftoi(-0.169 * R - 0.331 * G + 0.5 * B) + 128;
- V = Math::fast_ftoi( 0.5 * R - 0.419 * G - 0.081 * B) + 128;
- return (A << 24) + (Y << 16) + (U << 8) + V;
-}
-
-
-/*
- * Use this function for sharper images (good for cartoon style, used by DOSBOX)
- */
-
-_FORCE_INLINE_ static bool isDifferent(
- uint32_t color1,
- uint32_t color2,
- uint32_t trY,
- uint32_t trU,
- uint32_t trV,
- uint32_t trA )
-{
- color1 = ARGBtoAYUV(color1);
- color2 = ARGBtoAYUV(color2);
-
- uint32_t value;
-
- value = ((color1 & YMASK) - (color2 & YMASK));
- value = (value ^ (value >> 31)) - (value >> 31);
- if (value > trY) return true;
-
- value = ((color1 & UMASK) - (color2 & UMASK));
- value = (value ^ (value >> 31)) - (value >> 31);
- if (value > trU) return true;
-
- value = ((color1 & VMASK) - (color2 & VMASK));
- value = (value ^ (value >> 31)) - (value >> 31);
- if (value > trV) return true;
-
- value = ((color1 & AMASK) - (color2 & AMASK));
- value = (value ^ (value >> 31)) - (value >> 31);
- if (value > trA) return true;
-
- return false;
-
-}
-
-
-
-#define MASK_RB 0x00FF00FF
-#define MASK_G 0x0000FF00
-#define MASK_A 0xFF000000
-
-
-/**
- * @brief Mixes two colors using the given weights.
- */
-#define HQX_MIX_2(C0,C1,W0,W1) \
- ((((C0 & MASK_RB) * W0 + (C1 & MASK_RB) * W1) / (W0 + W1)) & MASK_RB) | \
- ((((C0 & MASK_G) * W0 + (C1 & MASK_G) * W1) / (W0 + W1)) & MASK_G) | \
- ((((((C0 & MASK_A) >> 8) * W0 + ((C1 & MASK_A) >> 8) * W1) / (W0 + W1)) << 8) & MASK_A)
-
-/**
- * @brief Mixes three colors using the given weights.
- */
-#define HQX_MIX_3(C0,C1,C2,W0,W1,W2) \
- ((((C0 & MASK_RB) * W0 + (C1 & MASK_RB) * W1 + (C2 & MASK_RB) * W2) / (W0 + W1 + W2)) & MASK_RB) | \
- ((((C0 & MASK_G) * W0 + (C1 & MASK_G) * W1 + (C2 & MASK_G) * W2) / (W0 + W1 + W2)) & MASK_G) | \
- ((((((C0 & MASK_A) >> 8) * W0 + ((C1 & MASK_A) >> 8) * W1 + ((C2 & MASK_A) >> 8) * W2) / (W0 + W1 + W2)) << 8) & MASK_A)
-
-
-#define MIX_00_4 *output = w[4];
-#define MIX_00_MIX_00_4_0_3_1 *output = HQX_MIX_2(w[4],w[0],3U,1U);
-#define MIX_00_4_3_3_1 *output = HQX_MIX_2(w[4],w[3],3U,1U);
-#define MIX_00_4_1_3_1 *output = HQX_MIX_2(w[4],w[1],3U,1U);
-#define MIX_00_3_1_1_1 *output = HQX_MIX_2(w[3],w[1],1U,1U);
-#define MIX_00_4_3_1_2_1_1 *output = HQX_MIX_3(w[4],w[3],w[1],2U,1U,1U);
-#define MIX_00_4_3_1_2_7_7 *output = HQX_MIX_3(w[4],w[3],w[1],2U,7U,7U);
-#define MIX_00_4_0_1_2_1_1 *output = HQX_MIX_3(w[4],w[0],w[1],2U,1U,1U);
-#define MIX_00_4_0_3_2_1_1 *output = HQX_MIX_3(w[4],w[0],w[3],2U,1U,1U);
-#define MIX_00_4_1_3_5_2_1 *output = HQX_MIX_3(w[4],w[1],w[3],5U,2U,1U);
-#define MIX_00_4_3_1_5_2_1 *output = HQX_MIX_3(w[4],w[3],w[1],5U,2U,1U);
-#define MIX_00_4_3_1_6_1_1 *output = HQX_MIX_3(w[4],w[3],w[1],6U,1U,1U);
-#define MIX_00_4_3_1_2_3_3 *output = HQX_MIX_3(w[4],w[3],w[1],2U,3U,3U);
-#define MIX_00_MIX_00_4_0_3_10 *output = HQX_MIX_3(w[4],w[3],w[1],14U,1U,1U);
-
-#define MIX_01_4 *(output + 1) = w[4];
-#define MIX_01_4_2_3_1 *(output + 1) = HQX_MIX_2(w[4],w[2],3U,1U);
-#define MIX_01_4_1_3_1 *(output + 1) = HQX_MIX_2(w[4],w[1],3U,1U);
-#define MIX_01_1_4_3_1 *(output + 1) = HQX_MIX_2(w[1],w[4],3U,1U);
-#define MIX_01_4_5_3_1 *(output + 1) = HQX_MIX_2(w[4],w[5],3U,1U);
-#define MIX_01_4_1_7_1 *(output + 1) = HQX_MIX_2(w[4],w[1],7U,1U);
-#define MIX_01_4_1_5_2_1_1 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],2U,1U,1U);
-#define MIX_01_4_2_5_2_1_1 *(output + 1) = HQX_MIX_3(w[4],w[2],w[5],2U,1U,1U);
-#define MIX_01_4_2_1_2_1_1 *(output + 1) = HQX_MIX_3(w[4],w[2],w[1],2U,1U,1U);
-#define MIX_01_4_5_1_5_2_1 *(output + 1) = HQX_MIX_3(w[4],w[5],w[1],5U,2U,1U);
-#define MIX_01_4_1_5_5_2_1 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],5U,2U,1U);
-#define MIX_01_4_1_5_6_1_1 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],6U,1U,1U);
-#define MIX_01_4_1_5_2_3_3 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],2U,3U,3U);
-#define MIX_01_4_2_3_10 *(output + 1) = HQX_MIX_3(w[4],w[1],w[5],14U,1U,1U);
-
-#define MIX_02_4 *(output + 2) = w[4];
-#define MIX_02_4_2_3_1 *(output + 2) = HQX_MIX_2(w[4],w[2],3U,1U);
-#define MIX_02_4_1_3_1 *(output + 2) = HQX_MIX_2(w[4],w[1],3U,1U);
-#define MIX_02_4_5_3_1 *(output + 2) = HQX_MIX_2(w[4],w[5],3U,1U);
-#define MIX_02_4_1_5_2_1_1 *(output + 2) = HQX_MIX_3(w[4],w[1],w[5],2U,1U,1U);
-#define MIX_02_4_1_5_2_7_7 *(output + 2) = HQX_MIX_3(w[4],w[1],w[5],2U,7U,7U);
-#define MIX_02_1_5_1_1 *(output + 2) = HQX_MIX_2(w[1],w[5],1U,1U);
-
-#define MIX_10_4 *(output + lineSize) = w[4];
-#define MIX_10_4_6_3_1 *(output + lineSize) = HQX_MIX_2(w[4],w[6],3U,1U);
-#define MIX_10_4_7_3_1 *(output + lineSize) = HQX_MIX_2(w[4],w[7],3U,1U);
-#define MIX_10_4_3_3_1 *(output + lineSize) = HQX_MIX_2(w[4],w[3],3U,1U);
-#define MIX_10_4_7_3_2_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,1U,1U);
-#define MIX_10_4_6_3_2_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[6],w[3],2U,1U,1U);
-#define MIX_10_4_6_7_2_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[6],w[7],2U,1U,1U);
-#define MIX_10_4_3_7_5_2_1 *(output + lineSize) = HQX_MIX_3(w[4],w[3],w[7],5U,2U,1U);
-#define MIX_10_4_7_3_5_2_1 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],5U,2U,1U);
-#define MIX_10_4_7_3_6_1_1 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],6U,1U,1U);
-#define MIX_10_4_7_3_2_3_3 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,3U,3U);
-#define MIX_10_4_6_3_10 *(output + lineSize) = HQX_MIX_3(w[4],w[7],w[3],14U,1U,1U);
-#define MIX_10_4_3_7_1 *(output + lineSize) = HQX_MIX_2(w[4],w[3],7U,1U);
-#define MIX_10_3_4_3_1 *(output + lineSize) = HQX_MIX_2(w[3],w[4],3U,1U);
-
-#define MIX_11_4 *(output + lineSize + 1) = w[4];
-#define MIX_11_4_8_3_1 *(output + lineSize + 1) = HQX_MIX_2(w[4],w[8],3U,1U);
-#define MIX_11_4_5_3_1 *(output + lineSize + 1) = HQX_MIX_2(w[4],w[5],3U,1U);
-#define MIX_11_4_7_3_1 *(output + lineSize + 1) = HQX_MIX_2(w[4],w[7],3U,1U);
-#define MIX_11_4_5_7_2_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],2U,1U,1U);
-#define MIX_11_4_8_7_2_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[8],w[7],2U,1U,1U);
-#define MIX_11_4_8_5_2_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[8],w[5],2U,1U,1U);
-#define MIX_11_4_7_5_5_2_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[7],w[5],5U,2U,1U);
-#define MIX_11_4_5_7_5_2_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],5U,2U,1U);
-#define MIX_11_4_5_7_6_1_1 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],6U,1U,1U);
-#define MIX_11_4_5_7_2_3_3 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],2U,3U,3U);
-#define MIX_11_4_8_3_10 *(output + lineSize + 1) = HQX_MIX_3(w[4],w[5],w[7],14U,1U,1U);
-
-#define MIX_12_4 *(output + lineSize + 2) = w[4];
-#define MIX_12_4_5_3_1 *(output + lineSize + 2) = HQX_MIX_2(w[4],w[5],3U,1U);
-#define MIX_12_4_5_7_1 *(output + lineSize + 2) = HQX_MIX_2(w[4],w[5],7U,1U);
-#define MIX_12_5_4_3_1 *(output + lineSize + 2) = HQX_MIX_2(w[5],w[4],3U,1U);
-
-#define MIX_20_4 *(output + lineSize + lineSize) = w[4];
-#define MIX_20_4_6_3_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[4],w[6],3U,1U);
-#define MIX_20_4_7_3_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[4],w[7],3U,1U);
-#define MIX_20_4_3_3_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[4],w[3],3U,1U);
-#define MIX_20_4_7_3_2_1_1 *(output + lineSize + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,1U,1U);
-#define MIX_20_4_7_3_2_7_7 *(output + lineSize + lineSize) = HQX_MIX_3(w[4],w[7],w[3],2U,7U,7U);
-#define MIX_20_7_3_1_1 *(output + lineSize + lineSize) = HQX_MIX_2(w[7],w[3],1U,1U);
-
-#define MIX_21_4 *(output + lineSize + lineSize + 1) = w[4];
-#define MIX_21_4_7_3_1 *(output + lineSize + lineSize + 1) = HQX_MIX_2(w[4],w[7],3U,1U);
-#define MIX_21_4_7_7_1 *(output + lineSize + lineSize + 1) = HQX_MIX_2(w[4],w[7],7U,1U);
-#define MIX_21_7_4_3_1 *(output + lineSize + lineSize + 1) = HQX_MIX_2(w[7],w[4],3U,1U);
-
-#define MIX_22_4 *(output + lineSize + lineSize + 2) = w[4];
-#define MIX_22_4_8_3_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[4],w[8],3U,1U);
-#define MIX_22_4_7_3_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[4],w[7],3U,1U);
-#define MIX_22_4_5_3_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[4],w[5],3U,1U);
-#define MIX_22_4_5_7_2_1_1 *(output + lineSize + lineSize + 2) = HQX_MIX_3(w[4],w[5],w[7],2U,1U,1U);
-#define MIX_22_4_5_7_2_7_7 *(output + lineSize + lineSize + 2) = HQX_MIX_3(w[4],w[5],w[7],2U,7U,7U);
-#define MIX_22_5_7_1_1 *(output + lineSize + lineSize + 2) = HQX_MIX_2(w[5],w[7],1U,1U);
-
-
-
-uint32_t *hq2x_resize(
- const uint32_t *image,
- uint32_t width,
- uint32_t height,
- uint32_t *output,
- uint32_t trY,
- uint32_t trU,
- uint32_t trV,
- uint32_t trA,
- bool wrapX,
- bool wrapY )
-{
- int lineSize = width * 2;
-
- int previous, next;
- uint32_t w[9];
-
- trY <<= 16;
- trU <<= 8;
- trA <<= 24;
-
- // iterates between the lines
- for (uint32_t row = 0; row < height; row++)
- {
- /*
- * Note: this function uses a 3x3 sliding window over the original image.
- *
- * +----+----+----+
- * | | | |
- * | w0 | w1 | w2 |
- * +----+----+----+
- * | | | |
- * | w3 | w4 | w5 |
- * +----+----+----+
- * | | | |
- * | w6 | w7 | w8 |
- * +----+----+----+
- */
-
- // adjusts the previous and next line pointers
- if (row > 0)
- previous = -width;
- else
- {
- if (wrapY)
- previous = width * (height - 1);
- else
- previous = 0;
- }
- if (row < height - 1)
- next = width;
- else
- {
- if (wrapY)
- next = -(width * (height - 1));
- else
- next = 0;
- }
-
- // iterates between the columns
- for (uint32_t col = 0; col < width; col++)
- {
- w[1] = *(image + previous);
- w[4] = *image;
- w[7] = *(image + next);
-
- if (col > 0)
- {
- w[0] = *(image + previous - 1);
- w[3] = *(image - 1);
- w[6] = *(image + next - 1);
- }
- else
- {
- if (wrapX)
- {
- w[0] = *(image + previous + width - 1);
- w[3] = *(image + width - 1);
- w[6] = *(image + next + width - 1);
- }
- else
- {
- w[0] = w[1];
- w[3] = w[4];
- w[6] = w[7];
- }
- }
-
- if (col < width - 1)
- {
- w[2] = *(image + previous + 1);
- w[5] = *(image + 1);
- w[8] = *(image + next + 1);
- }
- else
- {
- if (wrapX)
- {
- w[2] = *(image + previous - width + 1);
- w[5] = *(image - width + 1);
- w[8] = *(image + next - width + 1);
- }
- else
- {
- w[2] = w[1];
- w[5] = w[4];
- w[8] = w[7];
- }
- }
-
- int pattern = 0;
-
- // computes the pattern to be used considering the neighbor pixels
- for (int k = 0, flag = 1; k < 9; k++)
- {
- // ignores the central pixel
- if (k == 4) continue;
-
- if (w[k] != w[4])
- if (isDifferent(w[4], w[k], trY, trU, trV, trA)) pattern |= flag;
- flag <<= 1;
- }
-
- switch (pattern)
- {
- case 0:
- case 1:
- case 4:
- case 32:
- case 128:
- case 5:
- case 132:
- case 160:
- case 33:
- case 129:
- case 36:
- case 133:
- case 164:
- case 161:
- case 37:
- case 165:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_1_5_2_1_1
- MIX_10_4_7_3_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 2:
- case 34:
- case 130:
- case 162:
- MIX_00_4_0_3_2_1_1
- MIX_01_4_2_5_2_1_1
- MIX_10_4_7_3_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 16:
- case 17:
- case 48:
- case 49:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_7_3_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 64:
- case 65:
- case 68:
- case 69:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_1_5_2_1_1
- MIX_10_4_6_3_2_1_1
- MIX_11_4_8_5_2_1_1
- break;
- case 8:
- case 12:
- case 136:
- case 140:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_5_2_1_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 3:
- case 35:
- case 131:
- case 163:
- MIX_00_4_3_3_1
- MIX_01_4_2_5_2_1_1
- MIX_10_4_7_3_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 6:
- case 38:
- case 134:
- case 166:
- MIX_00_4_0_3_2_1_1
- MIX_01_4_5_3_1
- MIX_10_4_7_3_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 20:
- case 21:
- case 52:
- case 53:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_1_3_1
- MIX_10_4_7_3_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 144:
- case 145:
- case 176:
- case 177:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_7_3_2_1_1
- MIX_11_4_7_3_1
- break;
- case 192:
- case 193:
- case 196:
- case 197:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_1_5_2_1_1
- MIX_10_4_6_3_2_1_1
- MIX_11_4_5_3_1
- break;
- case 96:
- case 97:
- case 100:
- case 101:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_1_5_2_1_1
- MIX_10_4_3_3_1
- MIX_11_4_8_5_2_1_1
- break;
- case 40:
- case 44:
- case 168:
- case 172:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_5_2_1_1
- MIX_10_4_7_3_1
- MIX_11_4_5_7_2_1_1
- break;
- case 9:
- case 13:
- case 137:
- case 141:
- MIX_00_4_1_3_1
- MIX_01_4_1_5_2_1_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 18:
- case 50:
- MIX_00_4_0_3_2_1_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_7_3_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 80:
- case 81:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_6_3_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 72:
- case 76:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_5_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_8_5_2_1_1
- break;
- case 10:
- case 138:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_2_5_2_1_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 66:
- MIX_00_4_0_3_2_1_1
- MIX_01_4_2_5_2_1_1
- MIX_10_4_6_3_2_1_1
- MIX_11_4_8_5_2_1_1
- break;
- case 24:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 7:
- case 39:
- case 135:
- MIX_00_4_3_3_1
- MIX_01_4_5_3_1
- MIX_10_4_7_3_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 148:
- case 149:
- case 180:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_1_3_1
- MIX_10_4_7_3_2_1_1
- MIX_11_4_7_3_1
- break;
- case 224:
- case 228:
- case 225:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_1_5_2_1_1
- MIX_10_4_3_3_1
- MIX_11_4_5_3_1
- break;
- case 41:
- case 169:
- case 45:
- MIX_00_4_1_3_1
- MIX_01_4_1_5_2_1_1
- MIX_10_4_7_3_1
- MIX_11_4_5_7_2_1_1
- break;
- case 22:
- case 54:
- MIX_00_4_0_3_2_1_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_7_3_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 208:
- case 209:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_6_3_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 104:
- case 108:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_5_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_8_5_2_1_1
- break;
- case 11:
- case 139:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_2_5_2_1_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 19:
- case 51:
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_00_4_3_3_1
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_00_4_1_3_5_2_1
- MIX_01_4_1_5_2_3_3
- }
- MIX_10_4_7_3_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 146:
- case 178:
- MIX_00_4_0_3_2_1_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- MIX_11_4_7_3_1
- }
- else
- {
- MIX_01_4_1_5_2_3_3
- MIX_11_4_5_7_5_2_1
- }
- MIX_10_4_7_3_2_1_1
- break;
- case 84:
- case 85:
- MIX_00_4_3_1_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_01_4_1_3_1
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_01_4_5_1_5_2_1
- MIX_11_4_5_7_2_3_3
- }
- MIX_10_4_6_3_2_1_1
- break;
- case 112:
- case 113:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_2_1_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_10_4_3_3_1
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_10_4_7_3_5_2_1
- MIX_11_4_5_7_2_3_3
- }
- break;
- case 200:
- case 204:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_5_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- MIX_11_4_5_3_1
- }
- else
- {
- MIX_10_4_7_3_2_3_3
- MIX_11_4_7_5_5_2_1
- }
- break;
- case 73:
- case 77:
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_00_4_1_3_1
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_00_4_3_1_5_2_1
- MIX_10_4_7_3_2_3_3
- }
- MIX_01_4_1_5_2_1_1
- MIX_11_4_8_5_2_1_1
- break;
- case 42:
- case 170:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- MIX_10_4_7_3_1
- }
- else
- {
- MIX_00_4_3_1_2_3_3
- MIX_10_4_3_7_5_2_1
- }
- MIX_01_4_2_5_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 14:
- case 142:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- MIX_01_4_5_3_1
- }
- else
- {
- MIX_00_4_3_1_2_3_3
- MIX_01_4_1_5_5_2_1
- }
- MIX_10_4_6_7_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 67:
- MIX_00_4_3_3_1
- MIX_01_4_2_5_2_1_1
- MIX_10_4_6_3_2_1_1
- MIX_11_4_8_5_2_1_1
- break;
- case 70:
- MIX_00_4_0_3_2_1_1
- MIX_01_4_5_3_1
- MIX_10_4_6_3_2_1_1
- MIX_11_4_8_5_2_1_1
- break;
- case 28:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_3_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 152:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_7_3_1
- break;
- case 194:
- MIX_00_4_0_3_2_1_1
- MIX_01_4_2_5_2_1_1
- MIX_10_4_6_3_2_1_1
- MIX_11_4_5_3_1
- break;
- case 98:
- MIX_00_4_0_3_2_1_1
- MIX_01_4_2_5_2_1_1
- MIX_10_4_3_3_1
- MIX_11_4_8_5_2_1_1
- break;
- case 56:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_7_3_1
- MIX_11_4_8_7_2_1_1
- break;
- case 25:
- MIX_00_4_1_3_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 26:
- case 31:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_6_7_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 82:
- case 214:
- MIX_00_4_0_3_2_1_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_6_3_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 88:
- case 248:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_2_1_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 74:
- case 107:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_2_5_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_8_5_2_1_1
- break;
- case 27:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_2_3_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 86:
- MIX_00_4_0_3_2_1_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_6_3_2_1_1
- MIX_11_4_8_3_1
- break;
- case 216:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_6_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 106:
- MIX_00_MIX_00_4_0_3_1
- MIX_01_4_2_5_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_8_5_2_1_1
- break;
- case 30:
- MIX_00_MIX_00_4_0_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_6_7_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 210:
- MIX_00_4_0_3_2_1_1
- MIX_01_4_2_3_1
- MIX_10_4_6_3_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 120:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_2_1_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_8_3_1
- break;
- case 75:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_2_5_2_1_1
- MIX_10_4_6_3_1
- MIX_11_4_8_5_2_1_1
- break;
- case 29:
- MIX_00_4_1_3_1
- MIX_01_4_1_3_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 198:
- MIX_00_4_0_3_2_1_1
- MIX_01_4_5_3_1
- MIX_10_4_6_3_2_1_1
- MIX_11_4_5_3_1
- break;
- case 184:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_7_3_1
- MIX_11_4_7_3_1
- break;
- case 99:
- MIX_00_4_3_3_1
- MIX_01_4_2_5_2_1_1
- MIX_10_4_3_3_1
- MIX_11_4_8_5_2_1_1
- break;
- case 57:
- MIX_00_4_1_3_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_7_3_1
- MIX_11_4_8_7_2_1_1
- break;
- case 71:
- MIX_00_4_3_3_1
- MIX_01_4_5_3_1
- MIX_10_4_6_3_2_1_1
- MIX_11_4_8_5_2_1_1
- break;
- case 156:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_3_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_7_3_1
- break;
- case 226:
- MIX_00_4_0_3_2_1_1
- MIX_01_4_2_5_2_1_1
- MIX_10_4_3_3_1
- MIX_11_4_5_3_1
- break;
- case 60:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_3_1
- MIX_10_4_7_3_1
- MIX_11_4_8_7_2_1_1
- break;
- case 195:
- MIX_00_4_3_3_1
- MIX_01_4_2_5_2_1_1
- MIX_10_4_6_3_2_1_1
- MIX_11_4_5_3_1
- break;
- case 102:
- MIX_00_4_0_3_2_1_1
- MIX_01_4_5_3_1
- MIX_10_4_3_3_1
- MIX_11_4_8_5_2_1_1
- break;
- case 153:
- MIX_00_4_1_3_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_7_3_1
- break;
- case 58:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- MIX_10_4_7_3_1
- MIX_11_4_8_7_2_1_1
- break;
- case 83:
- MIX_00_4_3_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- MIX_10_4_6_3_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 92:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 202:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- MIX_01_4_2_5_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- MIX_11_4_5_3_1
- break;
- case 78:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- MIX_01_4_5_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- MIX_11_4_8_5_2_1_1
- break;
- case 154:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- MIX_10_4_6_7_2_1_1
- MIX_11_4_7_3_1
- break;
- case 114:
- MIX_00_4_0_3_2_1_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- MIX_10_4_3_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 89:
- MIX_00_4_1_3_1
- MIX_01_4_2_1_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 90:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 55:
- case 23:
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_00_4_3_3_1
- MIX_01_4
- }
- else
- {
- MIX_00_4_1_3_5_2_1
- MIX_01_4_1_5_2_3_3
- }
- MIX_10_4_7_3_2_1_1
- MIX_11_4_8_7_2_1_1
- break;
- case 182:
- case 150:
- MIX_00_4_0_3_2_1_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- MIX_11_4_7_3_1
- }
- else
- {
- MIX_01_4_1_5_2_3_3
- MIX_11_4_5_7_5_2_1
- }
- MIX_10_4_7_3_2_1_1
- break;
- case 213:
- case 212:
- MIX_00_4_3_1_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_01_4_1_3_1
- MIX_11_4
- }
- else
- {
- MIX_01_4_5_1_5_2_1
- MIX_11_4_5_7_2_3_3
- }
- MIX_10_4_6_3_2_1_1
- break;
- case 241:
- case 240:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_2_1_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_10_4_3_3_1
- MIX_11_4
- }
- else
- {
- MIX_10_4_7_3_5_2_1
- MIX_11_4_5_7_2_3_3
- }
- break;
- case 236:
- case 232:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_5_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- MIX_11_4_5_3_1
- }
- else
- {
- MIX_10_4_7_3_2_3_3
- MIX_11_4_7_5_5_2_1
- }
- break;
- case 109:
- case 105:
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_00_4_1_3_1
- MIX_10_4
- }
- else
- {
- MIX_00_4_3_1_5_2_1
- MIX_10_4_7_3_2_3_3
- }
- MIX_01_4_1_5_2_1_1
- MIX_11_4_8_5_2_1_1
- break;
- case 171:
- case 43:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- MIX_10_4_7_3_1
- }
- else
- {
- MIX_00_4_3_1_2_3_3
- MIX_10_4_3_7_5_2_1
- }
- MIX_01_4_2_5_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 143:
- case 15:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- MIX_01_4_5_3_1
- }
- else
- {
- MIX_00_4_3_1_2_3_3
- MIX_01_4_1_5_5_2_1
- }
- MIX_10_4_6_7_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 124:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_8_3_1
- break;
- case 203:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_2_5_2_1_1
- MIX_10_4_6_3_1
- MIX_11_4_5_3_1
- break;
- case 62:
- MIX_00_MIX_00_4_0_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_7_3_1
- MIX_11_4_8_7_2_1_1
- break;
- case 211:
- MIX_00_4_3_3_1
- MIX_01_4_2_3_1
- MIX_10_4_6_3_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 118:
- MIX_00_4_0_3_2_1_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_3_3_1
- MIX_11_4_8_3_1
- break;
- case 217:
- MIX_00_4_1_3_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_6_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 110:
- MIX_00_MIX_00_4_0_3_1
- MIX_01_4_5_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_8_5_2_1_1
- break;
- case 155:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_2_3_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_7_3_1
- break;
- case 188:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_3_1
- MIX_10_4_7_3_1
- MIX_11_4_7_3_1
- break;
- case 185:
- MIX_00_4_1_3_1
- MIX_01_4_2_1_2_1_1
- MIX_10_4_7_3_1
- MIX_11_4_7_3_1
- break;
- case 61:
- MIX_00_4_1_3_1
- MIX_01_4_1_3_1
- MIX_10_4_7_3_1
- MIX_11_4_8_7_2_1_1
- break;
- case 157:
- MIX_00_4_1_3_1
- MIX_01_4_1_3_1
- MIX_10_4_6_7_2_1_1
- MIX_11_4_7_3_1
- break;
- case 103:
- MIX_00_4_3_3_1
- MIX_01_4_5_3_1
- MIX_10_4_3_3_1
- MIX_11_4_8_5_2_1_1
- break;
- case 227:
- MIX_00_4_3_3_1
- MIX_01_4_2_5_2_1_1
- MIX_10_4_3_3_1
- MIX_11_4_5_3_1
- break;
- case 230:
- MIX_00_4_0_3_2_1_1
- MIX_01_4_5_3_1
- MIX_10_4_3_3_1
- MIX_11_4_5_3_1
- break;
- case 199:
- MIX_00_4_3_3_1
- MIX_01_4_5_3_1
- MIX_10_4_6_3_2_1_1
- MIX_11_4_5_3_1
- break;
- case 220:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 158:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_6_7_2_1_1
- MIX_11_4_7_3_1
- break;
- case 234:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- MIX_01_4_2_5_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_5_3_1
- break;
- case 242:
- MIX_00_4_0_3_2_1_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- MIX_10_4_3_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 59:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- MIX_10_4_7_3_1
- MIX_11_4_8_7_2_1_1
- break;
- case 121:
- MIX_00_4_1_3_1
- MIX_01_4_2_1_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 87:
- MIX_00_4_3_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_6_3_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 79:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_5_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- MIX_11_4_8_5_2_1_1
- break;
- case 122:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 94:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 218:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 91:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 229:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_1_5_2_1_1
- MIX_10_4_3_3_1
- MIX_11_4_5_3_1
- break;
- case 167:
- MIX_00_4_3_3_1
- MIX_01_4_5_3_1
- MIX_10_4_7_3_2_1_1
- MIX_11_4_5_7_2_1_1
- break;
- case 173:
- MIX_00_4_1_3_1
- MIX_01_4_1_5_2_1_1
- MIX_10_4_7_3_1
- MIX_11_4_5_7_2_1_1
- break;
- case 181:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_1_3_1
- MIX_10_4_7_3_2_1_1
- MIX_11_4_7_3_1
- break;
- case 186:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- MIX_10_4_7_3_1
- MIX_11_4_7_3_1
- break;
- case 115:
- MIX_00_4_3_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- MIX_10_4_3_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 93:
- MIX_00_4_1_3_1
- MIX_01_4_1_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 206:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- MIX_01_4_5_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- MIX_11_4_5_3_1
- break;
- case 205:
- case 201:
- MIX_00_4_1_3_1
- MIX_01_4_1_5_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4_6_3_1
- }
- else
- {
- MIX_10_4_7_3_6_1_1
- }
- MIX_11_4_5_3_1
- break;
- case 174:
- case 46:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_MIX_00_4_0_3_1
- }
- else
- {
- MIX_00_4_3_1_6_1_1
- }
- MIX_01_4_5_3_1
- MIX_10_4_7_3_1
- MIX_11_4_5_7_2_1_1
- break;
- case 179:
- case 147:
- MIX_00_4_3_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4_2_3_1
- }
- else
- {
- MIX_01_4_1_5_6_1_1
- }
- MIX_10_4_7_3_2_1_1
- MIX_11_4_7_3_1
- break;
- case 117:
- case 116:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_1_3_1
- MIX_10_4_3_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4_8_3_1
- }
- else
- {
- MIX_11_4_5_7_6_1_1
- }
- break;
- case 189:
- MIX_00_4_1_3_1
- MIX_01_4_1_3_1
- MIX_10_4_7_3_1
- MIX_11_4_7_3_1
- break;
- case 231:
- MIX_00_4_3_3_1
- MIX_01_4_5_3_1
- MIX_10_4_3_3_1
- MIX_11_4_5_3_1
- break;
- case 126:
- MIX_00_MIX_00_4_0_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_8_3_1
- break;
- case 219:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_2_3_1
- MIX_10_4_6_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 125:
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_00_4_1_3_1
- MIX_10_4
- }
- else
- {
- MIX_00_4_3_1_5_2_1
- MIX_10_4_7_3_2_3_3
- }
- MIX_01_4_1_3_1
- MIX_11_4_8_3_1
- break;
- case 221:
- MIX_00_4_1_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_01_4_1_3_1
- MIX_11_4
- }
- else
- {
- MIX_01_4_5_1_5_2_1
- MIX_11_4_5_7_2_3_3
- }
- MIX_10_4_6_3_1
- break;
- case 207:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- MIX_01_4_5_3_1
- }
- else
- {
- MIX_00_4_3_1_2_3_3
- MIX_01_4_1_5_5_2_1
- }
- MIX_10_4_6_3_1
- MIX_11_4_5_3_1
- break;
- case 238:
- MIX_00_MIX_00_4_0_3_1
- MIX_01_4_5_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- MIX_11_4_5_3_1
- }
- else
- {
- MIX_10_4_7_3_2_3_3
- MIX_11_4_7_5_5_2_1
- }
- break;
- case 190:
- MIX_00_MIX_00_4_0_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- MIX_11_4_7_3_1
- }
- else
- {
- MIX_01_4_1_5_2_3_3
- MIX_11_4_5_7_5_2_1
- }
- MIX_10_4_7_3_1
- break;
- case 187:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- MIX_10_4_7_3_1
- }
- else
- {
- MIX_00_4_3_1_2_3_3
- MIX_10_4_3_7_5_2_1
- }
- MIX_01_4_2_3_1
- MIX_11_4_7_3_1
- break;
- case 243:
- MIX_00_4_3_3_1
- MIX_01_4_2_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_10_4_3_3_1
- MIX_11_4
- }
- else
- {
- MIX_10_4_7_3_5_2_1
- MIX_11_4_5_7_2_3_3
- }
- break;
- case 119:
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_00_4_3_3_1
- MIX_01_4
- }
- else
- {
- MIX_00_4_1_3_5_2_1
- MIX_01_4_1_5_2_3_3
- }
- MIX_10_4_3_3_1
- MIX_11_4_8_3_1
- break;
- case 237:
- case 233:
- MIX_00_4_1_3_1
- MIX_01_4_1_5_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_6_3_10
- }
- MIX_11_4_5_3_1
- break;
- case 175:
- case 47:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_MIX_00_4_0_3_10
- }
- MIX_01_4_5_3_1
- MIX_10_4_7_3_1
- MIX_11_4_5_7_2_1_1
- break;
- case 183:
- case 151:
- MIX_00_4_3_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_2_3_10
- }
- MIX_10_4_7_3_2_1_1
- MIX_11_4_7_3_1
- break;
- case 245:
- case 244:
- MIX_00_4_3_1_2_1_1
- MIX_01_4_1_3_1
- MIX_10_4_3_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_8_3_10
- }
- break;
- case 250:
- MIX_00_MIX_00_4_0_3_1
- MIX_01_4_2_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 123:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_2_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_8_3_1
- break;
- case 95:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_6_3_1
- MIX_11_4_8_3_1
- break;
- case 222:
- MIX_00_MIX_00_4_0_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_6_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 252:
- MIX_00_4_0_1_2_1_1
- MIX_01_4_1_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_8_3_10
- }
- break;
- case 249:
- MIX_00_4_1_3_1
- MIX_01_4_2_1_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_6_3_10
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 235:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_2_5_2_1_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_6_3_10
- }
- MIX_11_4_5_3_1
- break;
- case 111:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_MIX_00_4_0_3_10
- }
- MIX_01_4_5_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_8_5_2_1_1
- break;
- case 63:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_MIX_00_4_0_3_10
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_7_3_1
- MIX_11_4_8_7_2_1_1
- break;
- case 159:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_2_3_10
- }
- MIX_10_4_6_7_2_1_1
- MIX_11_4_7_3_1
- break;
- case 215:
- MIX_00_4_3_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_2_3_10
- }
- MIX_10_4_6_3_2_1_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 246:
- MIX_00_4_0_3_2_1_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- MIX_10_4_3_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_8_3_10
- }
- break;
- case 254:
- MIX_00_MIX_00_4_0_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_8_3_10
- }
- break;
- case 253:
- MIX_00_4_1_3_1
- MIX_01_4_1_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_6_3_10
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_8_3_10
- }
- break;
- case 251:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- MIX_01_4_2_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_6_3_10
- }
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 239:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_MIX_00_4_0_3_10
- }
- MIX_01_4_5_3_1
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_6_3_10
- }
- MIX_11_4_5_3_1
- break;
- case 127:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_MIX_00_4_0_3_10
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_1_5_2_1_1
- }
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- {
- MIX_10_4
- }
- else
- {
- MIX_10_4_7_3_2_1_1
- }
- MIX_11_4_8_3_1
- break;
- case 191:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_MIX_00_4_0_3_10
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_2_3_10
- }
- MIX_10_4_7_3_1
- MIX_11_4_7_3_1
- break;
- case 223:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- {
- MIX_00_4
- }
- else
- {
- MIX_00_4_3_1_2_1_1
- }
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_2_3_10
- }
- MIX_10_4_6_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_5_7_2_1_1
- }
- break;
- case 247:
- MIX_00_4_3_3_1
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- {
- MIX_01_4
- }
- else
- {
- MIX_01_4_2_3_10
- }
- MIX_10_4_3_3_1
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- {
- MIX_11_4
- }
- else
- {
- MIX_11_4_8_3_10
- }
- break;
- case 255:
- if (isDifferent(w[3], w[1], trY, trU, trV, trA))
- MIX_00_4
- else
- MIX_00_MIX_00_4_0_3_10
-
- if (isDifferent(w[1], w[5], trY, trU, trV, trA))
- MIX_01_4
- else
- MIX_01_4_2_3_10
-
- if (isDifferent(w[7], w[3], trY, trU, trV, trA))
- MIX_10_4
- else
- MIX_10_4_6_3_10
-
- if (isDifferent(w[5], w[7], trY, trU, trV, trA))
- MIX_11_4
- else
- MIX_11_4_8_3_10
- break;
- }
- image++;
- output += 2;
- }
- output += lineSize;
- }
-
- return output;
-}
diff --git a/thirdparty/misc/hq2x.h b/thirdparty/misc/hq2x.h
deleted file mode 100644
index bebd917950..0000000000
--- a/thirdparty/misc/hq2x.h
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifndef HQ2X_H
-#define HQ2X_H
-
-#include "core/typedefs.h"
-
-
-uint32_t *hq2x_resize(
- const uint32_t *image,
- uint32_t width,
- uint32_t height,
- uint32_t *output,
- uint32_t trY = 0x30,
- uint32_t trU = 0x07,
- uint32_t trV = 0x06,
- uint32_t trA = 0x50,
- bool wrapX = false,
- bool wrapY = false );
-
-#endif // HQ2X_H
diff --git a/thirdparty/misc/r128.c b/thirdparty/misc/r128.c
new file mode 100644
index 0000000000..6b981aa693
--- /dev/null
+++ b/thirdparty/misc/r128.c
@@ -0,0 +1,2 @@
+#define R128_IMPLEMENTATION
+#include "r128.h"
diff --git a/thirdparty/misc/r128.h b/thirdparty/misc/r128.h
new file mode 100644
index 0000000000..1f7aab78fb
--- /dev/null
+++ b/thirdparty/misc/r128.h
@@ -0,0 +1,2123 @@
+/*
+r128.h: 128-bit (64.64) signed fixed-point arithmetic. Version 1.4.3
+
+COMPILATION
+-----------
+Drop this header file somewhere in your project and include it wherever it is
+needed. There is no separate .c file for this library. To get the code, in ONE
+file in your project, put:
+
+#define R128_IMPLEMENTATION
+
+before you include this file. You may also provide a definition for R128_ASSERT
+to force the library to use a custom assert macro.
+
+COMPILER/LIBRARY SUPPORT
+------------------------
+This library requires a C89 compiler with support for 64-bit integers. If your
+compiler does not support the long long data type, the R128_U64, etc. macros
+must be set appropriately. On x86 and x64 targets, Intel intrinsics are used
+for speed. If your compiler does not support these intrinsics, you can add
+#define R128_STDC_ONLY
+in your implementation file before including r128.h.
+
+The only C runtime library functionality used by this library is <assert.h>.
+This can be avoided by defining an R128_ASSERT macro in your implementation
+file. Since this library uses 64-bit arithmetic, this may implicitly add a
+runtime library dependency on 32-bit platforms.
+
+C++ SUPPORT
+-----------
+Operator overloads are supplied for C++ files that include this file. Since all
+C++ functions are declared inline (or static inline), the R128_IMPLEMENTATION
+file can be either C++ or C.
+
+LICENSE
+-------
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifndef H_R128_H
+#define H_R128_H
+
+#include <stddef.h>
+
+// 64-bit integer support
+// If your compiler does not have stdint.h, add appropriate defines for these macros.
+#if defined(_MSC_VER) && (_MSC_VER < 1600)
+# define R128_S32 __int32
+# define R128_U32 unsigned __int32
+# define R128_S64 __int64
+# define R128_U64 unsigned __int64
+# define R128_LIT_S64(x) x##i64
+# define R128_LIT_U64(x) x##ui64
+#else
+# include <stdint.h>
+# define R128_S32 int32_t
+# define R128_U32 uint32_t
+# define R128_S64 int64_t
+# define R128_U64 uint64_t
+# define R128_LIT_S64(x) x##ll
+# define R128_LIT_U64(x) x##ull
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct R128 {
+ R128_U64 lo;
+ R128_U64 hi;
+
+#ifdef __cplusplus
+ R128();
+ R128(double);
+ R128(int);
+ R128(R128_S64);
+ R128(R128_U64 low, R128_U64 high);
+
+ operator double() const;
+ operator R128_S64() const;
+ operator int() const;
+ operator bool() const;
+
+ bool operator!() const;
+ R128 operator~() const;
+ R128 operator-() const;
+ R128 &operator|=(const R128 &rhs);
+ R128 &operator&=(const R128 &rhs);
+ R128 &operator^=(const R128 &rhs);
+ R128 &operator+=(const R128 &rhs);
+ R128 &operator-=(const R128 &rhs);
+ R128 &operator*=(const R128 &rhs);
+ R128 &operator/=(const R128 &rhs);
+ R128 &operator%=(const R128 &rhs);
+ R128 &operator<<=(int amount);
+ R128 &operator>>=(int amount);
+#endif //__cplusplus
+} R128;
+
+// Type conversion
+extern void r128FromInt(R128 *dst, R128_S64 v);
+extern void r128FromFloat(R128 *dst, double v);
+extern R128_S64 r128ToInt(const R128 *v);
+extern double r128ToFloat(const R128 *v);
+
+// Copy
+extern void r128Copy(R128 *dst, const R128 *src);
+
+// Negate
+extern void r128Neg(R128 *dst, const R128 *src);
+
+// Bitwise operations
+extern void r128Not(R128 *dst, const R128 *src); // ~a
+extern void r128Or(R128 *dst, const R128 *a, const R128 *b); // a | b
+extern void r128And(R128 *dst, const R128 *a, const R128 *b); // a & b
+extern void r128Xor(R128 *dst, const R128 *a, const R128 *b); // a ^ b
+extern void r128Shl(R128 *dst, const R128 *src, int amount); // shift left by amount mod 128
+extern void r128Shr(R128 *dst, const R128 *src, int amount); // shift right logical by amount mod 128
+extern void r128Sar(R128 *dst, const R128 *src, int amount); // shift right arithmetic by amount mod 128
+
+// Arithmetic
+extern void r128Add(R128 *dst, const R128 *a, const R128 *b); // a + b
+extern void r128Sub(R128 *dst, const R128 *a, const R128 *b); // a - b
+extern void r128Mul(R128 *dst, const R128 *a, const R128 *b); // a * b
+extern void r128Div(R128 *dst, const R128 *a, const R128 *b); // a / b
+extern void r128Mod(R128 *dst, const R128 *a, const R128 *b); // a - toInt(a / b) * b
+
+extern void r128Sqrt(R128 *dst, const R128 *v); // sqrt(v)
+extern void r128Rsqrt(R128 *dst, const R128 *v); // 1 / sqrt(v)
+
+// Comparison
+extern int r128Cmp(const R128 *a, const R128 *b); // sign of a-b
+extern void r128Min(R128 *dst, const R128 *a, const R128 *b);
+extern void r128Max(R128 *dst, const R128 *a, const R128 *b);
+extern void r128Floor(R128 *dst, const R128 *v);
+extern void r128Ceil(R128 *dst, const R128 *v);
+extern int r128IsNeg(const R128 *v); // quick check for < 0
+
+// String conversion
+//
+typedef enum R128ToStringSign {
+ R128ToStringSign_Default, // no sign character for positive values
+ R128ToStringSign_Space, // leading space for positive values
+ R128ToStringSign_Plus, // leading '+' for positive values
+} R128ToStringSign;
+
+// Formatting options for use with r128ToStringOpt. The "defaults" correspond
+// to a format string of "%f".
+//
+typedef struct R128ToStringFormat {
+ // sign character for positive values. Default is R128ToStringSign_Default.
+ R128ToStringSign sign;
+
+ // minimum number of characters to write. Default is 0.
+ int width;
+
+ // place to the right of the decimal at which rounding is performed. If negative,
+ // a maximum of 20 decimal places will be written, with no trailing zeroes.
+ // (20 places is sufficient to ensure that r128FromString will convert back to the
+ // original value.) Default is -1. NOTE: This is not the same default that the C
+ // standard library uses for %f.
+ int precision;
+
+ // If non-zero, pads the output string with leading zeroes if the final result is
+ // fewer than width characters. Otherwise, leading spaces are used. Default is 0.
+ int zeroPad;
+
+ // Always print a decimal point, even if the value is an integer. Default is 0.
+ int decimal;
+
+ // Left-align output if width specifier requires padding.
+ // Default is 0 (right align).
+ int leftAlign;
+} R128ToStringFormat;
+
+// r128ToStringOpt: convert R128 to a decimal string, with formatting.
+//
+// dst and dstSize: specify the buffer to write into. At most dstSize bytes will be written
+// (including null terminator). No additional rounding is performed if dstSize is not large
+// enough to hold the entire string.
+//
+// opt: an R128ToStringFormat struct (q.v.) with formatting options.
+//
+// Uses the R128_decimal global as the decimal point character.
+// Always writes a null terminator, even if the destination buffer is not large enough.
+//
+// Number of bytes that will be written (i.e. how big does dst need to be?):
+// If width is specified: width + 1 bytes.
+// If precision is specified: at most precision + 22 bytes.
+// If neither is specified: at most 42 bytes.
+//
+// Returns the number of bytes that would have been written if dst was sufficiently large,
+// not including the final null terminator.
+//
+extern int r128ToStringOpt(char *dst, size_t dstSize, const R128 *v, const R128ToStringFormat *opt);
+
+// r128ToStringf: convert R128 to a decimal string, with formatting.
+//
+// dst and dstSize: specify the buffer to write into. At most dstSize bytes will be written
+// (including null terminator).
+//
+// format: a printf-style format specifier, as one would use with floating point types.
+// e.g. "%+5.2f". (The leading % and trailing f are optional.)
+// NOTE: This is NOT a full replacement for sprintf. Any characters in the format string
+// that do not correspond to a format placeholder are ignored.
+//
+// Uses the R128_decimal global as the decimal point character.
+// Always writes a null terminator, even if the destination buffer is not large enough.
+//
+// Number of bytes that will be written (i.e. how big does dst need to be?):
+// If the precision field is specified: at most max(width, precision + 21) + 1 bytes
+// Otherwise: at most max(width, 41) + 1 bytes.
+//
+// Returns the number of bytes that would have been written if dst was sufficiently large,
+// not including the final null terminator.
+//
+extern int r128ToStringf(char *dst, size_t dstSize, const char *format, const R128 *v);
+
+// r128ToString: convert R128 to a decimal string, with default formatting.
+// Equivalent to r128ToStringf(dst, dstSize, "%f", v).
+//
+// Uses the R128_decimal global as the decimal point character.
+// Always writes a null terminator, even if the destination buffer is not large enough.
+//
+// Will write at most 42 bytes (including NUL) to dst.
+//
+// Returns the number of bytes that would have been written if dst was sufficiently large,
+// not including the final null terminator.
+//
+extern int r128ToString(char *dst, size_t dstSize, const R128 *v);
+
+// r128FromString: Convert string to R128.
+//
+// The string can be formatted either as a decimal number with optional sign
+// or as hexadecimal with a prefix of 0x or 0X.
+//
+// endptr, if not NULL, is set to the character following the last character
+// used in the conversion.
+//
+extern void r128FromString(R128 *dst, const char *s, char **endptr);
+
+// Constants
+extern const R128 R128_min; // minimum (most negative) value
+extern const R128 R128_max; // maximum (most positive) value
+extern const R128 R128_smallest; // smallest positive value
+extern const R128 R128_zero; // zero
+extern const R128 R128_one; // 1.0
+
+extern char R128_decimal; // decimal point character used by r128From/ToString. defaults to '.'
+
+#ifdef __cplusplus
+}
+
+#include <limits>
+namespace std {
+template<>
+struct numeric_limits<R128>
+{
+ static const bool is_specialized = true;
+
+ static R128 min() throw() { return R128_min; }
+ static R128 max() throw() { return R128_max; }
+
+ static const int digits = 127;
+ static const int digits10 = 38;
+ static const bool is_signed = true;
+ static const bool is_integer = false;
+ static const bool is_exact = false;
+ static const int radix = 2;
+ static R128 epsilon() throw() { return R128_smallest; }
+ static R128 round_error() throw() { return R128_one; }
+
+ static const int min_exponent = 0;
+ static const int min_exponent10 = 0;
+ static const int max_exponent = 0;
+ static const int max_exponent10 = 0;
+
+ static const bool has_infinity = false;
+ static const bool has_quiet_NaN = false;
+ static const bool has_signaling_NaN = false;
+ static const float_denorm_style has_denorm = denorm_absent;
+ static const bool has_denorm_loss = false;
+
+ static R128 infinity() throw() { return R128_zero; }
+ static R128 quiet_NaN() throw() { return R128_zero; }
+ static R128 signaling_NaN() throw() { return R128_zero; }
+ static R128 denorm_min() throw() { return R128_zero; }
+
+ static const bool is_iec559 = false;
+ static const bool is_bounded = true;
+ static const bool is_modulo = true;
+
+ static const bool traps = numeric_limits<R128_U64>::traps;
+ static const bool tinyness_before = false;
+ static const float_round_style round_style = round_toward_zero;
+};
+} //namespace std
+
+inline R128::R128() {}
+
+inline R128::R128(double v)
+{
+ r128FromFloat(this, v);
+}
+
+inline R128::R128(int v)
+{
+ r128FromInt(this, v);
+}
+
+inline R128::R128(R128_S64 v)
+{
+ r128FromInt(this, v);
+}
+
+inline R128::R128(R128_U64 low, R128_U64 high)
+{
+ lo = low;
+ hi = high;
+}
+
+inline R128::operator double() const
+{
+ return r128ToFloat(this);
+}
+
+inline R128::operator R128_S64() const
+{
+ return r128ToInt(this);
+}
+
+inline R128::operator int() const
+{
+ return (int) r128ToInt(this);
+}
+
+inline R128::operator bool() const
+{
+ return lo || hi;
+}
+
+inline bool R128::operator!() const
+{
+ return !lo && !hi;
+}
+
+inline R128 R128::operator~() const
+{
+ R128 r;
+ r128Not(&r, this);
+ return r;
+}
+
+inline R128 R128::operator-() const
+{
+ R128 r;
+ r128Neg(&r, this);
+ return r;
+}
+
+inline R128 &R128::operator|=(const R128 &rhs)
+{
+ r128Or(this, this, &rhs);
+ return *this;
+}
+
+inline R128 &R128::operator&=(const R128 &rhs)
+{
+ r128And(this, this, &rhs);
+ return *this;
+}
+
+inline R128 &R128::operator^=(const R128 &rhs)
+{
+ r128Xor(this, this, &rhs);
+ return *this;
+}
+
+inline R128 &R128::operator+=(const R128 &rhs)
+{
+ r128Add(this, this, &rhs);
+ return *this;
+}
+
+inline R128 &R128::operator-=(const R128 &rhs)
+{
+ r128Sub(this, this, &rhs);
+ return *this;
+}
+
+inline R128 &R128::operator*=(const R128 &rhs)
+{
+ r128Mul(this, this, &rhs);
+ return *this;
+}
+
+inline R128 &R128::operator/=(const R128 &rhs)
+{
+ r128Div(this, this, &rhs);
+ return *this;
+}
+
+inline R128 &R128::operator%=(const R128 &rhs)
+{
+ r128Mod(this, this, &rhs);
+ return *this;
+}
+
+inline R128 &R128::operator<<=(int amount)
+{
+ r128Shl(this, this, amount);
+ return *this;
+}
+
+inline R128 &R128::operator>>=(int amount)
+{
+ r128Sar(this, this, amount);
+ return *this;
+}
+
+static inline R128 operator|(const R128 &lhs, const R128 &rhs)
+{
+ R128 r(lhs);
+ return r |= rhs;
+}
+
+static inline R128 operator&(const R128 &lhs, const R128 &rhs)
+{
+ R128 r(lhs);
+ return r &= rhs;
+}
+
+static inline R128 operator^(const R128 &lhs, const R128 &rhs)
+{
+ R128 r(lhs);
+ return r ^= rhs;
+}
+
+static inline R128 operator+(const R128 &lhs, const R128 &rhs)
+{
+ R128 r(lhs);
+ return r += rhs;
+}
+
+static inline R128 operator-(const R128 &lhs, const R128 &rhs)
+{
+ R128 r(lhs);
+ return r -= rhs;
+}
+
+static inline R128 operator*(const R128 &lhs, const R128 &rhs)
+{
+ R128 r(lhs);
+ return r *= rhs;
+}
+
+static inline R128 operator/(const R128 &lhs, const R128 &rhs)
+{
+ R128 r(lhs);
+ return r /= rhs;
+}
+
+static inline R128 operator%(const R128 &lhs, const R128 &rhs)
+{
+ R128 r(lhs);
+ return r %= rhs;
+}
+
+static inline R128 operator<<(const R128 &lhs, int amount)
+{
+ R128 r(lhs);
+ return r <<= amount;
+}
+
+static inline R128 operator>>(const R128 &lhs, int amount)
+{
+ R128 r(lhs);
+ return r >>= amount;
+}
+
+static inline bool operator<(const R128 &lhs, const R128 &rhs)
+{
+ return r128Cmp(&lhs, &rhs) < 0;
+}
+
+static inline bool operator>(const R128 &lhs, const R128 &rhs)
+{
+ return r128Cmp(&lhs, &rhs) > 0;
+}
+
+static inline bool operator<=(const R128 &lhs, const R128 &rhs)
+{
+ return r128Cmp(&lhs, &rhs) <= 0;
+}
+
+static inline bool operator>=(const R128 &lhs, const R128 &rhs)
+{
+ return r128Cmp(&lhs, &rhs) >= 0;
+}
+
+static inline bool operator==(const R128 &lhs, const R128 &rhs)
+{
+ return lhs.lo == rhs.lo && lhs.hi == rhs.hi;
+}
+
+static inline bool operator!=(const R128 &lhs, const R128 &rhs)
+{
+ return lhs.lo != rhs.lo || lhs.hi != rhs.hi;
+}
+
+#endif //__cplusplus
+#endif //H_R128_H
+
+#ifdef R128_IMPLEMENTATION
+
+#ifdef R128_DEBUG_VIS
+# define R128_DEBUG_SET(x) r128ToString(R128_last, sizeof(R128_last), x)
+#else
+# define R128_DEBUG_SET(x)
+#endif
+
+#define R128_SET2(x, l, h) do { (x)->lo = (R128_U64)(l); (x)->hi = (R128_U64)(h); } while(0)
+#define R128_R0(x) ((R128_U32)(x)->lo)
+#define R128_R2(x) ((R128_U32)(x)->hi)
+#if defined(_M_IX86)
+// workaround: MSVC x86's handling of 64-bit values is not great
+# define R128_SET4(x, r0, r1, r2, r3) do { \
+ ((R128_U32*)&(x)->lo)[0] = (R128_U32)(r0); \
+ ((R128_U32*)&(x)->lo)[1] = (R128_U32)(r1); \
+ ((R128_U32*)&(x)->hi)[0] = (R128_U32)(r2); \
+ ((R128_U32*)&(x)->hi)[1] = (R128_U32)(r3); \
+ } while(0)
+# define R128_R1(x) (((R128_U32*)&(x)->lo)[1])
+# define R128_R3(x) (((R128_U32*)&(x)->hi)[1])
+#else
+# define R128_SET4(x, r0, r1, r2, r3) do { (x)->lo = (R128_U64)(r0) | ((R128_U64)(r1) << 32); \
+ (x)->hi = (R128_U64)(r2) | ((R128_U64)(r3) << 32); } while(0)
+# define R128_R1(x) ((R128_U32)((x)->lo >> 32))
+# define R128_R3(x) ((R128_U32)((x)->hi >> 32))
+#endif
+
+#if defined(_M_X64)
+# define R128_INTEL 1
+# define R128_64BIT 1
+# ifndef R128_STDC_ONLY
+# include <intrin.h>
+# endif
+#elif defined(__x86_64__)
+# define R128_INTEL 1
+# define R128_64BIT 1
+# ifndef R128_STDC_ONLY
+# include <x86intrin.h>
+# endif
+#elif defined(_M_IX86)
+# define R128_INTEL 1
+# ifndef R128_STDC_ONLY
+# include <intrin.h>
+# endif
+#elif defined(__i386__)
+# define R128_INTEL 1
+# ifndef R128_STDC_ONLY
+# include <x86intrin.h>
+# endif
+#elif defined(_M_ARM)
+# ifndef R128_STDC_ONLY
+# include <intrin.h>
+# endif
+#elif defined(_M_ARM64)
+# define R128_64BIT 1
+# ifndef R128_STDC_ONLY
+# include <intrin.h>
+# endif
+#elif defined(__aarch64__)
+# define R128_64BIT 1
+#endif
+
+#ifndef R128_INTEL
+# define R128_INTEL 0
+#endif
+
+#ifndef R128_64BIT
+# define R128_64BIT 0
+#endif
+
+#ifndef R128_ASSERT
+# include <assert.h>
+# define R128_ASSERT(x) assert(x)
+#endif
+
+#include <stdlib.h> // for NULL
+
+static const R128ToStringFormat R128__defaultFormat = {
+ R128ToStringSign_Default,
+ 0,
+ -1,
+ 0,
+ 0,
+ 0
+};
+
+const R128 R128_min = { 0, R128_LIT_U64(0x8000000000000000) };
+const R128 R128_max = { R128_LIT_U64(0xffffffffffffffff), R128_LIT_U64(0x7fffffffffffffff) };
+const R128 R128_smallest = { 1, 0 };
+const R128 R128_zero = { 0, 0 };
+const R128 R128_one = { 0, 1 };
+char R128_decimal = '.';
+#ifdef R128_DEBUG_VIS
+char R128_last[42];
+#endif
+
+static int r128__clz64(R128_U64 x)
+{
+#if defined(R128_STDC_ONLY)
+ R128_U64 n = 64, y;
+ y = x >> 32; if (y) { n -= 32; x = y; }
+ y = x >> 16; if (y) { n -= 16; x = y; }
+ y = x >> 8; if (y) { n -= 8; x = y; }
+ y = x >> 4; if (y) { n -= 4; x = y; }
+ y = x >> 2; if (y) { n -= 2; x = y; }
+ y = x >> 1; if (y) { n -= 1; x = y; }
+ return (int)(n - x);
+#elif defined(_M_X64) || defined(_M_ARM64)
+ unsigned long idx;
+ if (_BitScanReverse64(&idx, x)) {
+ return 63 - (int)idx;
+ } else {
+ return 64;
+ }
+#elif defined(_MSC_VER)
+ unsigned long idx;
+ if (_BitScanReverse(&idx, (R128_U32)(x >> 32))) {
+ return 31 - (int)idx;
+ } else if (_BitScanReverse(&idx, (R128_U32)x)) {
+ return 63 - (int)idx;
+ } else {
+ return 64;
+ }
+#else
+ return x ? __builtin_clzll(x) : 64;
+#endif
+}
+
+#if !R128_64BIT
+// 32*32->64
+static R128_U64 r128__umul64(R128_U32 a, R128_U32 b)
+{
+# if defined(_M_IX86) && !defined(R128_STDC_ONLY) && !defined(__MINGW32__)
+ return __emulu(a, b);
+# elif defined(_M_ARM) && !defined(R128_STDC_ONLY)
+ return _arm_umull(a, b);
+# else
+ return a * (R128_U64)b;
+# endif
+}
+
+// 64/32->32
+static R128_U32 r128__udiv64(R128_U32 nlo, R128_U32 nhi, R128_U32 d, R128_U32 *rem)
+{
+# if defined(_M_IX86) && (_MSC_VER >= 1920) && !defined(R128_STDC_ONLY)
+ unsigned __int64 n = ((unsigned __int64)nhi << 32) | nlo;
+ return _udiv64(n, d, rem);
+# elif defined(_M_IX86) && !defined(R128_STDC_ONLY) && !defined(__MINGW32__)
+ __asm {
+ mov eax, nlo
+ mov edx, nhi
+ div d
+ mov ecx, rem
+ mov dword ptr [ecx], edx
+ }
+# elif defined(__i386__) && !defined(R128_STDC_ONLY)
+ R128_U32 q, r;
+ __asm("divl %4"
+ : "=a"(q), "=d"(r)
+ : "a"(nlo), "d"(nhi), "X"(d));
+ *rem = r;
+ return q;
+# else
+ R128_U64 n64 = ((R128_U64)nhi << 32) | nlo;
+ *rem = (R128_U32)(n64 % d);
+ return (R128_U32)(n64 / d);
+# endif
+}
+#elif !defined(_M_X64) || defined(R128_STDC_ONLY)
+#define r128__umul64(a, b) ((a) * (R128_U64)(b))
+static R128_U32 r128__udiv64(R128_U32 nlo, R128_U32 nhi, R128_U32 d, R128_U32 *rem)
+{
+ R128_U64 n64 = ((R128_U64)nhi << 32) | nlo;
+ *rem = (R128_U32)(n64 % d);
+ return (R128_U32)(n64 / d);
+}
+#endif //!R128_64BIT
+
+static void r128__neg(R128 *dst, const R128 *src)
+{
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(src != NULL);
+
+#if R128_INTEL && !defined(R128_STDC_ONLY)
+ {
+ unsigned char carry = 0;
+# if R128_64BIT
+ carry = _addcarry_u64(carry, ~src->lo, 1, &dst->lo);
+ carry = _addcarry_u64(carry, ~src->hi, 0, &dst->hi);
+# else
+ R128_U32 r0, r1, r2, r3;
+ carry = _addcarry_u32(carry, ~R128_R0(src), 1, &r0);
+ carry = _addcarry_u32(carry, ~R128_R1(src), 0, &r1);
+ carry = _addcarry_u32(carry, ~R128_R2(src), 0, &r2);
+ carry = _addcarry_u32(carry, ~R128_R3(src), 0, &r3);
+ R128_SET4(dst, r0, r1, r2, r3);
+# endif //R128_64BIT
+ }
+#else
+ if (src->lo) {
+ dst->lo = ~src->lo + 1;
+ dst->hi = ~src->hi;
+ } else {
+ dst->lo = 0;
+ dst->hi = ~src->hi + 1;
+ }
+#endif //R128_INTEL
+}
+
+// 64*64->128
+static void r128__umul128(R128 *dst, R128_U64 a, R128_U64 b)
+{
+#if defined(_M_X64) && !defined(R128_STDC_ONLY)
+ dst->lo = _umul128(a, b, &dst->hi);
+#elif R128_64BIT && !defined(_MSC_VER) && !defined(R128_STDC_ONLY)
+ unsigned __int128 p0 = a * (unsigned __int128)b;
+ dst->hi = (R128_U64)(p0 >> 64);
+ dst->lo = (R128_U64)p0;
+#else
+ R128_U32 alo = (R128_U32)a;
+ R128_U32 ahi = (R128_U32)(a >> 32);
+ R128_U32 blo = (R128_U32)b;
+ R128_U32 bhi = (R128_U32)(b >> 32);
+ R128_U64 p0, p1, p2, p3;
+
+ p0 = r128__umul64(alo, blo);
+ p1 = r128__umul64(alo, bhi);
+ p2 = r128__umul64(ahi, blo);
+ p3 = r128__umul64(ahi, bhi);
+
+ {
+#if R128_INTEL && !defined(R128_STDC_ONLY)
+ R128_U32 r0, r1, r2, r3;
+ unsigned char carry;
+
+ r0 = (R128_U32)(p0);
+ r1 = (R128_U32)(p0 >> 32);
+ r2 = (R128_U32)(p1 >> 32);
+ r3 = (R128_U32)(p3 >> 32);
+
+ carry = _addcarry_u32(0, r1, (R128_U32)p1, &r1);
+ carry = _addcarry_u32(carry, r2, (R128_U32)(p2 >> 32), &r2);
+ _addcarry_u32(carry, r3, 0, &r3);
+ carry = _addcarry_u32(0, r1, (R128_U32)p2, &r1);
+ carry = _addcarry_u32(carry, r2, (R128_U32)p3, &r2);
+ _addcarry_u32(carry, r3, 0, &r3);
+
+ R128_SET4(dst, r0, r1, r2, r3);
+#else
+ R128_U64 carry, lo, hi;
+ carry = ((R128_U64)(R128_U32)p1 + (R128_U64)(R128_U32)p2 + (p0 >> 32)) >> 32;
+
+ lo = p0 + ((p1 + p2) << 32);
+ hi = p3 + ((R128_U32)(p1 >> 32) + (R128_U32)(p2 >> 32)) + carry;
+
+ R128_SET2(dst, lo, hi);
+#endif
+ }
+#endif
+}
+
+// 128/64->64
+#if defined(_M_X64) && (_MSC_VER < 1920) && !defined(R128_STDC_ONLY) && !defined(__MINGW32__)
+// MSVC x64 provides neither inline assembly nor (pre-2019) a div intrinsic, so we do fake
+// "inline assembly" to avoid long division or outline assembly.
+#pragma code_seg(".text")
+__declspec(allocate(".text")) static const unsigned char r128__udiv128Code[] = {
+ 0x48, 0x8B, 0xC1, //mov rax, rcx
+ 0x49, 0xF7, 0xF0, //div rax, r8
+ 0x49, 0x89, 0x11, //mov qword ptr [r9], rdx
+ 0xC3 //ret
+};
+typedef R128_U64 (*r128__udiv128Proc)(R128_U64 nlo, R128_U64 nhi, R128_U64 d, R128_U64 *rem);
+static const r128__udiv128Proc r128__udiv128 = (r128__udiv128Proc)(void*)r128__udiv128Code;
+#else
+static R128_U64 r128__udiv128(R128_U64 nlo, R128_U64 nhi, R128_U64 d, R128_U64 *rem)
+{
+#if defined(_M_X64) && !defined(R128_STDC_ONLY) && !defined(__MINGW32__)
+ return _udiv128(nhi, nlo, d, rem);
+#elif defined(__x86_64__) && !defined(R128_STDC_ONLY)
+ R128_U64 q, r;
+ __asm("divq %4"
+ : "=a"(q), "=d"(r)
+ : "a"(nlo), "d"(nhi), "X"(d));
+ *rem = r;
+ return q;
+#else
+ R128_U64 tmp;
+ R128_U32 d0, d1;
+ R128_U32 n3, n2, n1, n0;
+ R128_U32 q0, q1;
+ R128_U32 r;
+ int shift;
+
+ R128_ASSERT(d != 0); //division by zero
+ R128_ASSERT(nhi < d); //overflow
+
+ // normalize
+ shift = r128__clz64(d);
+
+ if (shift) {
+ R128 tmp128;
+ R128_SET2(&tmp128, nlo, nhi);
+ r128Shl(&tmp128, &tmp128, shift);
+ n3 = R128_R3(&tmp128);
+ n2 = R128_R2(&tmp128);
+ n1 = R128_R1(&tmp128);
+ n0 = R128_R0(&tmp128);
+ d <<= shift;
+ } else {
+ n3 = (R128_U32)(nhi >> 32);
+ n2 = (R128_U32)nhi;
+ n1 = (R128_U32)(nlo >> 32);
+ n0 = (R128_U32)nlo;
+ }
+
+ d1 = (R128_U32)(d >> 32);
+ d0 = (R128_U32)d;
+
+ // first digit
+ R128_ASSERT(n3 <= d1);
+ if (n3 < d1) {
+ q1 = r128__udiv64(n2, n3, d1, &r);
+ } else {
+ q1 = 0xffffffffu;
+ r = n2 + d1;
+ }
+refine1:
+ if (r128__umul64(q1, d0) > ((R128_U64)r << 32) + n1) {
+ --q1;
+ if (r < ~d1 + 1) {
+ r += d1;
+ goto refine1;
+ }
+ }
+
+ tmp = ((R128_U64)n2 << 32) + n1 - (r128__umul64(q1, d0) + (r128__umul64(q1, d1) << 32));
+ n2 = (R128_U32)(tmp >> 32);
+ n1 = (R128_U32)tmp;
+
+ // second digit
+ R128_ASSERT(n2 <= d1);
+ if (n2 < d1) {
+ q0 = r128__udiv64(n1, n2, d1, &r);
+ } else {
+ q0 = 0xffffffffu;
+ r = n1 + d1;
+ }
+refine0:
+ if (r128__umul64(q0, d0) > ((R128_U64)r << 32) + n0) {
+ --q0;
+ if (r < ~d1 + 1) {
+ r += d1;
+ goto refine0;
+ }
+ }
+
+ tmp = ((R128_U64)n1 << 32) + n0 - (r128__umul64(q0, d0) + (r128__umul64(q0, d1) << 32));
+ n1 = (R128_U32)(tmp >> 32);
+ n0 = (R128_U32)tmp;
+
+ *rem = (((R128_U64)n1 << 32) + n0) >> shift;
+ return ((R128_U64)q1 << 32) + q0;
+#endif
+}
+#endif
+
+static int r128__ucmp(const R128 *a, const R128 *b)
+{
+ if (a->hi != b->hi) {
+ if (a->hi > b->hi) {
+ return 1;
+ } else {
+ return -1;
+ }
+ } else {
+ if (a->lo == b->lo) {
+ return 0;
+ } else if (a->lo > b->lo) {
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+}
+
+static void r128__umul(R128 *dst, const R128 *a, const R128 *b)
+{
+#if defined(_M_X64) && !defined(R128_STDC_ONLY)
+ R128_U64 t0, t1;
+ R128_U64 lo, hi = 0;
+ unsigned char carry;
+
+ t0 = _umul128(a->lo, b->lo, &t1);
+ carry = _addcarry_u64(0, t1, t0 >> 63, &lo);
+ _addcarry_u64(carry, hi, hi, &hi);
+
+ t0 = _umul128(a->lo, b->hi, &t1);
+ carry = _addcarry_u64(0, lo, t0, &lo);
+ _addcarry_u64(carry, hi, t1, &hi);
+
+ t0 = _umul128(a->hi, b->lo, &t1);
+ carry = _addcarry_u64(0, lo, t0, &lo);
+ _addcarry_u64(carry, hi, t1, &hi);
+
+ t0 = _umul128(a->hi, b->hi, &t1);
+ hi += t0;
+
+ R128_SET2(dst, lo, hi);
+#elif defined(__x86_64__) && !defined(R128_STDC_ONLY)
+ unsigned __int128 p0, p1, p2, p3;
+ p0 = a->lo * (unsigned __int128)b->lo;
+ p1 = a->lo * (unsigned __int128)b->hi;
+ p2 = a->hi * (unsigned __int128)b->lo;
+ p3 = a->hi * (unsigned __int128)b->hi;
+
+ p0 = (p3 << 64) + p2 + p1 + (p0 >> 64) + ((R128_U64)p0 >> 63);
+ dst->lo = (R128_U64)p0;
+ dst->hi = (R128_U64)(p0 >> 64);
+#else
+ R128 p0, p1, p2, p3, round;
+
+ r128__umul128(&p0, a->lo, b->lo);
+ round.hi = 0; round.lo = p0.lo >> 63;
+ p0.lo = p0.hi; p0.hi = 0; //r128Shr(&p0, &p0, 64);
+ r128Add(&p0, &p0, &round);
+
+ r128__umul128(&p1, a->hi, b->lo);
+ r128Add(&p0, &p0, &p1);
+
+ r128__umul128(&p2, a->lo, b->hi);
+ r128Add(&p0, &p0, &p2);
+
+ r128__umul128(&p3, a->hi, b->hi);
+ p3.hi = p3.lo; p3.lo = 0; //r128Shl(&p3, &p3, 64);
+ r128Add(&p0, &p0, &p3);
+
+ R128_SET2(dst, p0.lo, p0.hi);
+#endif
+}
+
+// Shift d left until the high bit is set, and shift n left by the same amount.
+// returns non-zero on overflow.
+static int r128__norm(R128 *n, R128 *d, R128_U64 *n2)
+{
+ R128_U64 d0, d1;
+ R128_U64 n0, n1;
+ int shift;
+
+ d1 = d->hi;
+ d0 = d->lo;
+ n1 = n->hi;
+ n0 = n->lo;
+
+ if (d1) {
+ shift = r128__clz64(d1);
+ if (shift) {
+ d1 = (d1 << shift) | (d0 >> (64 - shift));
+ d0 = d0 << shift;
+ *n2 = n1 >> (64 - shift);
+ n1 = (n1 << shift) | (n0 >> (64 - shift));
+ n0 = n0 << shift;
+ } else {
+ *n2 = 0;
+ }
+ } else {
+ shift = r128__clz64(d0);
+ if (r128__clz64(n1) <= shift) {
+ return 1; // overflow
+ }
+
+ if (shift) {
+ d1 = d0 << shift;
+ d0 = 0;
+ *n2 = (n1 << shift) | (n0 >> (64 - shift));
+ n1 = n0 << shift;
+ n0 = 0;
+ } else {
+ d1 = d0;
+ d0 = 0;
+ *n2 = n1;
+ n1 = n0;
+ n0 = 0;
+ }
+ }
+
+ R128_SET2(n, n0, n1);
+ R128_SET2(d, d0, d1);
+ return 0;
+}
+
+static void r128__udiv(R128 *quotient, const R128 *dividend, const R128 *divisor)
+{
+ R128 tmp;
+ R128_U64 d0, d1;
+ R128_U64 n1, n2, n3;
+ R128 q;
+
+ R128_ASSERT(dividend != NULL);
+ R128_ASSERT(divisor != NULL);
+ R128_ASSERT(quotient != NULL);
+ R128_ASSERT(divisor->hi != 0 || divisor->lo != 0); // divide by zero
+
+ // scale dividend and normalize
+ {
+ R128 n, d;
+ R128_SET2(&n, dividend->lo, dividend->hi);
+ R128_SET2(&d, divisor->lo, divisor->hi);
+ if (r128__norm(&n, &d, &n3)) {
+ R128_SET2(quotient, R128_max.lo, R128_max.hi);
+ return;
+ }
+
+ d1 = d.hi;
+ d0 = d.lo;
+ n2 = n.hi;
+ n1 = n.lo;
+ }
+
+ // first digit
+ R128_ASSERT(n3 <= d1);
+ {
+ R128 t0, t1;
+ t0.lo = n1;
+ if (n3 < d1) {
+ q.hi = r128__udiv128(n2, n3, d1, &t0.hi);
+ } else {
+ q.hi = R128_LIT_U64(0xffffffffffffffff);
+ t0.hi = n2 + d1;
+ }
+
+refine1:
+ r128__umul128(&t1, q.hi, d0);
+ if (r128__ucmp(&t1, &t0) > 0) {
+ --q.hi;
+ if (t0.hi < ~d1 + 1) {
+ t0.hi += d1;
+ goto refine1;
+ }
+ }
+ }
+
+ {
+ R128 t0, t1, t2;
+ t0.hi = n2;
+ t0.lo = n1;
+
+ r128__umul128(&t1, q.hi, d0);
+ r128__umul128(&t2, q.hi, d1);
+
+ t2.hi = t2.lo; t2.lo = 0; //r128Shl(&t2, &t2, 64);
+ r128Add(&tmp, &t1, &t2);
+ r128Sub(&tmp, &t0, &tmp);
+ }
+ n2 = tmp.hi;
+ n1 = tmp.lo;
+
+ // second digit
+ R128_ASSERT(n2 <= d1);
+ {
+ R128 t0, t1;
+ t0.lo = 0;
+ if (n2 < d1) {
+ q.lo = r128__udiv128(n1, n2, d1, &t0.hi);
+ } else {
+ q.lo = R128_LIT_U64(0xffffffffffffffff);
+ t0.hi = n1 + d1;
+ }
+
+ refine0:
+ r128__umul128(&t1, q.lo, d0);
+ if (r128__ucmp(&t1, &t0) > 0) {
+ --q.lo;
+ if (t0.hi < ~d1 + 1) {
+ t0.hi += d1;
+ goto refine0;
+ }
+ }
+ }
+
+ R128_SET2(quotient, q.lo, q.hi);
+}
+
+static R128_U64 r128__umod(R128 *n, R128 *d)
+{
+ R128_U64 d0, d1;
+ R128_U64 n3, n2, n1;
+ R128_U64 q;
+
+ R128_ASSERT(d != NULL);
+ R128_ASSERT(n != NULL);
+ R128_ASSERT(d->hi != 0 || d->lo != 0); // divide by zero
+
+ if (r128__norm(n, d, &n3)) {
+ return R128_LIT_U64(0xffffffffffffffff);
+ }
+
+ d1 = d->hi;
+ d0 = d->lo;
+ n2 = n->hi;
+ n1 = n->lo;
+
+ R128_ASSERT(n3 < d1);
+ {
+ R128 t0, t1;
+ t0.lo = n1;
+ q = r128__udiv128(n2, n3, d1, &t0.hi);
+
+ refine1:
+ r128__umul128(&t1, q, d0);
+ if (r128__ucmp(&t1, &t0) > 0) {
+ --q;
+ if (t0.hi < ~d1 + 1) {
+ t0.hi += d1;
+ goto refine1;
+ }
+ }
+ }
+
+ return q;
+}
+
+static int r128__format(char *dst, size_t dstSize, const R128 *v, const R128ToStringFormat *format)
+{
+ char buf[128];
+ R128 tmp;
+ R128_U64 whole;
+ char *cursor, *decimal, *dstp = dst;
+ int sign = 0;
+ int fullPrecision = 1;
+ int width, precision;
+ int padCnt, trail = 0;
+
+ R128_ASSERT(dst != NULL && dstSize > 0);
+ R128_ASSERT(v != NULL);
+ R128_ASSERT(format != NULL);
+
+ --dstSize;
+
+ R128_SET2(&tmp, v->lo, v->hi);
+ if (r128IsNeg(&tmp)) {
+ r128__neg(&tmp, &tmp);
+ sign = 1;
+ }
+
+ width = format->width;
+ if (width < 0) {
+ width = 0;
+ }
+
+ precision = format->precision;
+ if (precision < 0) {
+ // print a maximum of 20 digits
+ fullPrecision = 0;
+ precision = 20;
+ } else if (precision > sizeof(buf) - 21) {
+ trail = precision - (sizeof(buf) - 21);
+ precision -= trail;
+ }
+
+ whole = tmp.hi;
+ decimal = cursor = buf;
+
+ // fractional part first in case a carry into the whole part is required
+ if (tmp.lo || format->decimal) {
+ while (tmp.lo || (fullPrecision && precision)) {
+ if ((int)(cursor - buf) == precision) {
+ if ((R128_S64)tmp.lo < 0) {
+ // round up, propagate carry backwards
+ char *c;
+ for (c = cursor - 1; c >= buf; --c) {
+ char d = ++*c;
+ if (d <= '9') {
+ goto endfrac;
+ } else {
+ *c = '0';
+ }
+ }
+
+ // carry out into the whole part
+ whole++;
+ }
+
+ break;
+ }
+
+ r128__umul128(&tmp, tmp.lo, 10);
+ *cursor++ = (char)tmp.hi + '0';
+ }
+
+ endfrac:
+ if (format->decimal || precision) {
+ decimal = cursor;
+ *cursor++ = R128_decimal;
+ }
+ }
+
+ // whole part
+ do {
+ char digit = (char)(whole % 10);
+ whole /= 10;
+ *cursor++ = digit + '0';
+ } while (whole);
+
+#define R128__WRITE(c) do { if (dstp < dst + dstSize) *dstp = c; ++dstp; } while(0)
+
+ padCnt = width - (int)(cursor - buf) - 1;
+
+ // left padding
+ if (!format->leftAlign) {
+ char padChar = format->zeroPad ? '0' : ' ';
+ if (format->zeroPad) {
+ if (sign) {
+ R128__WRITE('-');
+ } else if (format->sign == R128ToStringSign_Plus) {
+ R128__WRITE('+');
+ } else if (format->sign == R128ToStringSign_Space) {
+ R128__WRITE(' ');
+ } else {
+ ++padCnt;
+ }
+ }
+
+ for (; padCnt > 0; --padCnt) {
+ R128__WRITE(padChar);
+ }
+ }
+
+ if (format->leftAlign || !format->zeroPad) {
+ if (sign) {
+ R128__WRITE('-');
+ } else if (format->sign == R128ToStringSign_Plus) {
+ R128__WRITE('+');
+ } else if (format->sign == R128ToStringSign_Space) {
+ R128__WRITE(' ');
+ } else {
+ ++padCnt;
+ }
+ }
+
+ {
+ char *i;
+
+ // reverse the whole part
+ for (i = cursor - 1; i >= decimal; --i) {
+ R128__WRITE(*i);
+ }
+
+ // copy the fractional part
+ for (i = buf; i < decimal; ++i) {
+ R128__WRITE(*i);
+ }
+ }
+
+ // right padding
+ if (format->leftAlign) {
+ char padChar = format->zeroPad ? '0' : ' ';
+ for (; padCnt > 0; --padCnt) {
+ R128__WRITE(padChar);
+ }
+ }
+
+ // trailing zeroes for very large precision
+ while (trail--) {
+ R128__WRITE('0');
+ }
+
+#undef R128__WRITE
+
+ if (dstp <= dst + dstSize) {
+ *dstp = '\0';
+ } else {
+ dst[dstSize] = '\0';
+ }
+ return (int)(dstp - dst);
+}
+
+void r128FromInt(R128 *dst, R128_S64 v)
+{
+ R128_ASSERT(dst != NULL);
+ dst->lo = 0;
+ dst->hi = (R128_U64)v;
+ R128_DEBUG_SET(dst);
+}
+
+void r128FromFloat(R128 *dst, double v)
+{
+ R128_ASSERT(dst != NULL);
+
+ if (v < -9223372036854775808.0) {
+ r128Copy(dst, &R128_min);
+ } else if (v >= 9223372036854775808.0) {
+ r128Copy(dst, &R128_max);
+ } else {
+ R128 r;
+ int sign = 0;
+
+ if (v < 0) {
+ v = -v;
+ sign = 1;
+ }
+
+ r.hi = (R128_U64)(R128_S64)v;
+ v -= (R128_S64)v;
+ r.lo = (R128_U64)(v * 18446744073709551616.0);
+
+ if (sign) {
+ r128__neg(&r, &r);
+ }
+
+ r128Copy(dst, &r);
+ }
+}
+
+void r128FromString(R128 *dst, const char *s, char **endptr)
+{
+ R128_U64 lo = 0, hi = 0;
+ R128_U64 base = 10;
+
+ int sign = 0;
+
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(s != NULL);
+
+ R128_SET2(dst, 0, 0);
+
+ // consume whitespace
+ for (;;) {
+ if (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n' || *s == '\v') {
+ ++s;
+ } else {
+ break;
+ }
+ }
+
+ // sign
+ if (*s == '-') {
+ sign = 1;
+ ++s;
+ } else if (*s == '+') {
+ ++s;
+ }
+
+ // parse base prefix
+ if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
+ base = 16;
+ s += 2;
+ }
+
+ // whole part
+ for (;; ++s) {
+ R128_U64 digit;
+
+ if ('0' <= *s && *s <= '9') {
+ digit = *s - '0';
+ } else if (base == 16 && 'a' <= *s && *s <= 'f') {
+ digit = *s - 'a' + 10;
+ } else if (base == 16 && 'A' <= *s && *s <= 'F') {
+ digit = *s - 'A' + 10;
+ } else {
+ break;
+ }
+
+ hi = hi * base + digit;
+ }
+
+ // fractional part
+ if (*s == R128_decimal) {
+ const char *exp = ++s;
+
+ // find the last digit and work backwards
+ for (;; ++s) {
+ if ('0' <= *s && *s <= '9') {
+ } else if (base == 16 && ('a' <= *s && *s <= 'f')) {
+ } else if (base == 16 && ('A' <= *s && *s <= 'F')) {
+ } else {
+ break;
+ }
+ }
+
+ for (--s; s >= exp; --s) {
+ R128_U64 digit, unused;
+
+ if ('0' <= *s && *s <= '9') {
+ digit = *s - '0';
+ } else if ('a' <= *s && *s <= 'f') {
+ digit = *s - 'a' + 10;
+ } else {
+ digit = *s - 'A' + 10;
+ }
+
+ lo = r128__udiv128(lo, digit, base, &unused);
+ }
+ }
+
+ R128_SET2(dst, lo, hi);
+ if (sign) {
+ r128__neg(dst, dst);
+ }
+
+ if (endptr) {
+ *endptr = (char *) s;
+ }
+}
+
+R128_S64 r128ToInt(const R128 *v)
+{
+ R128_ASSERT(v != NULL);
+ return (R128_S64)v->hi;
+}
+
+double r128ToFloat(const R128 *v)
+{
+ R128 tmp;
+ int sign = 0;
+ double d;
+
+ R128_ASSERT(v != NULL);
+
+ R128_SET2(&tmp, v->lo, v->hi);
+ if (r128IsNeg(&tmp)) {
+ r128__neg(&tmp, &tmp);
+ sign = 1;
+ }
+
+ d = tmp.hi + tmp.lo * (1 / 18446744073709551616.0);
+ if (sign) {
+ d = -d;
+ }
+
+ return d;
+}
+
+int r128ToStringOpt(char *dst, size_t dstSize, const R128 *v, const R128ToStringFormat *opt)
+{
+ return r128__format(dst, dstSize, v, opt);
+}
+
+int r128ToStringf(char *dst, size_t dstSize, const char *format, const R128 *v)
+{
+ R128ToStringFormat opts;
+
+ R128_ASSERT(dst != NULL && dstSize);
+ R128_ASSERT(format != NULL);
+ R128_ASSERT(v != NULL);
+
+ opts.sign = R128__defaultFormat.sign;
+ opts.precision = R128__defaultFormat.precision;
+ opts.zeroPad = R128__defaultFormat.zeroPad;
+ opts.decimal = R128__defaultFormat.decimal;
+ opts.leftAlign = R128__defaultFormat.leftAlign;
+
+ if (*format == '%') {
+ ++format;
+ }
+
+ // flags field
+ for (;; ++format) {
+ if (*format == ' ' && opts.sign != R128ToStringSign_Plus) {
+ opts.sign = R128ToStringSign_Space;
+ } else if (*format == '+') {
+ opts.sign = R128ToStringSign_Plus;
+ } else if (*format == '0') {
+ opts.zeroPad = 1;
+ } else if (*format == '-') {
+ opts.leftAlign = 1;
+ } else if (*format == '#') {
+ opts.decimal = 1;
+ } else {
+ break;
+ }
+ }
+
+ // width field
+ opts.width = 0;
+ for (;;) {
+ if ('0' <= *format && *format <= '9') {
+ opts.width = opts.width * 10 + *format++ - '0';
+ } else {
+ break;
+ }
+ }
+
+ // precision field
+ if (*format == '.') {
+ opts.precision = 0;
+ ++format;
+ for (;;) {
+ if ('0' <= *format && *format <= '9') {
+ opts.precision = opts.precision * 10 + *format++ - '0';
+ } else {
+ break;
+ }
+ }
+ }
+
+ return r128__format(dst, dstSize, v, &opts);
+}
+
+int r128ToString(char *dst, size_t dstSize, const R128 *v)
+{
+ return r128__format(dst, dstSize, v, &R128__defaultFormat);
+}
+
+void r128Copy(R128 *dst, const R128 *src)
+{
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(src != NULL);
+ dst->lo = src->lo;
+ dst->hi = src->hi;
+ R128_DEBUG_SET(dst);
+}
+
+void r128Neg(R128 *dst, const R128 *src)
+{
+ r128__neg(dst, src);
+ R128_DEBUG_SET(dst);
+}
+
+void r128Not(R128 *dst, const R128 *src)
+{
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(src != NULL);
+
+ dst->lo = ~src->lo;
+ dst->hi = ~src->hi;
+ R128_DEBUG_SET(dst);
+}
+
+void r128Or(R128 *dst, const R128 *a, const R128 *b)
+{
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(a != NULL);
+ R128_ASSERT(b != NULL);
+
+ dst->lo = a->lo | b->lo;
+ dst->hi = a->hi | b->hi;
+ R128_DEBUG_SET(dst);
+}
+
+void r128And(R128 *dst, const R128 *a, const R128 *b)
+{
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(a != NULL);
+ R128_ASSERT(b != NULL);
+
+ dst->lo = a->lo & b->lo;
+ dst->hi = a->hi & b->hi;
+ R128_DEBUG_SET(dst);
+}
+
+void r128Xor(R128 *dst, const R128 *a, const R128 *b)
+{
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(a != NULL);
+ R128_ASSERT(b != NULL);
+
+ dst->lo = a->lo ^ b->lo;
+ dst->hi = a->hi ^ b->hi;
+ R128_DEBUG_SET(dst);
+}
+
+void r128Shl(R128 *dst, const R128 *src, int amount)
+{
+ R128_U64 r[4];
+
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(src != NULL);
+
+#if defined(_M_IX86) && !defined(R128_STDC_ONLY) && !defined(__MINGW32__)
+ __asm {
+ // load src
+ mov edx, dword ptr[src]
+ mov ecx, amount
+
+ mov edi, dword ptr[edx]
+ mov esi, dword ptr[edx + 4]
+ mov ebx, dword ptr[edx + 8]
+ mov eax, dword ptr[edx + 12]
+
+ // shift mod 32
+ shld eax, ebx, cl
+ shld ebx, esi, cl
+ shld esi, edi, cl
+ shl edi, cl
+
+ // clear out low 12 bytes of stack
+ xor edx, edx
+ mov dword ptr[r], edx
+ mov dword ptr[r + 4], edx
+ mov dword ptr[r + 8], edx
+
+ // store shifted amount offset by count/32 bits
+ shr ecx, 5
+ and ecx, 3
+ mov dword ptr[r + ecx * 4 + 0], edi
+ mov dword ptr[r + ecx * 4 + 4], esi
+ mov dword ptr[r + ecx * 4 + 8], ebx
+ mov dword ptr[r + ecx * 4 + 12], eax
+ }
+#else
+
+ r[0] = src->lo;
+ r[1] = src->hi;
+
+ amount &= 127;
+ if (amount >= 64) {
+ r[1] = r[0] << (amount - 64);
+ r[0] = 0;
+ } else if (amount) {
+# ifdef _M_X64
+ r[1] = __shiftleft128(r[0], r[1], (char) amount);
+# else
+ r[1] = (r[1] << amount) | (r[0] >> (64 - amount));
+# endif
+ r[0] = r[0] << amount;
+ }
+#endif //_M_IX86
+
+ dst->lo = r[0];
+ dst->hi = r[1];
+ R128_DEBUG_SET(dst);
+}
+
+void r128Shr(R128 *dst, const R128 *src, int amount)
+{
+ R128_U64 r[4];
+
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(src != NULL);
+
+#if defined(_M_IX86) && !defined(R128_STDC_ONLY) && !defined(__MINGW32__)
+ __asm {
+ // load src
+ mov edx, dword ptr[src]
+ mov ecx, amount
+
+ mov edi, dword ptr[edx]
+ mov esi, dword ptr[edx + 4]
+ mov ebx, dword ptr[edx + 8]
+ mov eax, dword ptr[edx + 12]
+
+ // shift mod 32
+ shrd edi, esi, cl
+ shrd esi, ebx, cl
+ shrd ebx, eax, cl
+ shr eax, cl
+
+ // clear out high 12 bytes of stack
+ xor edx, edx
+ mov dword ptr[r + 20], edx
+ mov dword ptr[r + 24], edx
+ mov dword ptr[r + 28], edx
+
+ // store shifted amount offset by -count/32 bits
+ shr ecx, 5
+ and ecx, 3
+ neg ecx
+ mov dword ptr[r + ecx * 4 + 16], edi
+ mov dword ptr[r + ecx * 4 + 20], esi
+ mov dword ptr[r + ecx * 4 + 24], ebx
+ mov dword ptr[r + ecx * 4 + 28], eax
+ }
+#else
+ r[2] = src->lo;
+ r[3] = src->hi;
+
+ amount &= 127;
+ if (amount >= 64) {
+ r[2] = r[3] >> (amount - 64);
+ r[3] = 0;
+ } else if (amount) {
+#ifdef _M_X64
+ r[2] = __shiftright128(r[2], r[3], (char) amount);
+#else
+ r[2] = (r[2] >> amount) | (r[3] << (64 - amount));
+#endif
+ r[3] = r[3] >> amount;
+ }
+#endif
+
+ dst->lo = r[2];
+ dst->hi = r[3];
+ R128_DEBUG_SET(dst);
+}
+
+void r128Sar(R128 *dst, const R128 *src, int amount)
+{
+ R128_U64 r[4];
+
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(src != NULL);
+
+#if defined(_M_IX86) && !defined(R128_STDC_ONLY) && !defined(__MINGW32__)
+ __asm {
+ // load src
+ mov edx, dword ptr[src]
+ mov ecx, amount
+
+ mov edi, dword ptr[edx]
+ mov esi, dword ptr[edx + 4]
+ mov ebx, dword ptr[edx + 8]
+ mov eax, dword ptr[edx + 12]
+
+ // shift mod 32
+ shrd edi, esi, cl
+ shrd esi, ebx, cl
+ shrd ebx, eax, cl
+ sar eax, cl
+
+ // copy sign to high 12 bytes of stack
+ cdq
+ mov dword ptr[r + 20], edx
+ mov dword ptr[r + 24], edx
+ mov dword ptr[r + 28], edx
+
+ // store shifted amount offset by -count/32 bits
+ shr ecx, 5
+ and ecx, 3
+ neg ecx
+ mov dword ptr[r + ecx * 4 + 16], edi
+ mov dword ptr[r + ecx * 4 + 20], esi
+ mov dword ptr[r + ecx * 4 + 24], ebx
+ mov dword ptr[r + ecx * 4 + 28], eax
+ }
+#else
+ r[2] = src->lo;
+ r[3] = src->hi;
+
+ amount &= 127;
+ if (amount >= 64) {
+ r[2] = (R128_U64)((R128_S64)r[3] >> (amount - 64));
+ r[3] = (R128_U64)((R128_S64)r[3] >> 63);
+ } else if (amount) {
+ r[2] = (r[2] >> amount) | (R128_U64)((R128_S64)r[3] << (64 - amount));
+ r[3] = (R128_U64)((R128_S64)r[3] >> amount);
+ }
+#endif
+
+ dst->lo = r[2];
+ dst->hi = r[3];
+ R128_DEBUG_SET(dst);
+}
+
+void r128Add(R128 *dst, const R128 *a, const R128 *b)
+{
+ unsigned char carry = 0;
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(a != NULL);
+ R128_ASSERT(b != NULL);
+
+#if R128_INTEL && !defined(R128_STDC_ONLY)
+# if R128_64BIT
+ carry = _addcarry_u64(carry, a->lo, b->lo, &dst->lo);
+ carry = _addcarry_u64(carry, a->hi, b->hi, &dst->hi);
+# else
+ R128_U32 r0, r1, r2, r3;
+ carry = _addcarry_u32(carry, R128_R0(a), R128_R0(b), &r0);
+ carry = _addcarry_u32(carry, R128_R1(a), R128_R1(b), &r1);
+ carry = _addcarry_u32(carry, R128_R2(a), R128_R2(b), &r2);
+ carry = _addcarry_u32(carry, R128_R3(a), R128_R3(b), &r3);
+ R128_SET4(dst, r0, r1, r2, r3);
+# endif //R128_64BIT
+#else
+ {
+ R128_U64 r = a->lo + b->lo;
+ carry = r < a->lo;
+ dst->lo = r;
+ dst->hi = a->hi + b->hi + carry;
+ }
+#endif //R128_INTEL
+
+ R128_DEBUG_SET(dst);
+}
+
+void r128Sub(R128 *dst, const R128 *a, const R128 *b)
+{
+ unsigned char borrow = 0;
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(a != NULL);
+ R128_ASSERT(b != NULL);
+
+#if R128_INTEL && !defined(R128_STDC_ONLY)
+# if R128_64BIT
+ borrow = _subborrow_u64(borrow, a->lo, b->lo, &dst->lo);
+ borrow = _subborrow_u64(borrow, a->hi, b->hi, &dst->hi);
+# else
+ R128_U32 r0, r1, r2, r3;
+ borrow = _subborrow_u32(borrow, R128_R0(a), R128_R0(b), &r0);
+ borrow = _subborrow_u32(borrow, R128_R1(a), R128_R1(b), &r1);
+ borrow = _subborrow_u32(borrow, R128_R2(a), R128_R2(b), &r2);
+ borrow = _subborrow_u32(borrow, R128_R3(a), R128_R3(b), &r3);
+ R128_SET4(dst, r0, r1, r2, r3);
+# endif //R128_64BIT
+#else
+ {
+ R128_U64 r = a->lo - b->lo;
+ borrow = r > a->lo;
+ dst->lo = r;
+ dst->hi = a->hi - b->hi - borrow;
+ }
+#endif //R128_INTEL
+
+ R128_DEBUG_SET(dst);
+}
+
+void r128Mul(R128 *dst, const R128 *a, const R128 *b)
+{
+ int sign = 0;
+ R128 ta, tb, tc;
+
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(a != NULL);
+ R128_ASSERT(b != NULL);
+
+ R128_SET2(&ta, a->lo, a->hi);
+ R128_SET2(&tb, b->lo, b->hi);
+
+ if (r128IsNeg(&ta)) {
+ r128__neg(&ta, &ta);
+ sign = !sign;
+ }
+ if (r128IsNeg(&tb)) {
+ r128__neg(&tb, &tb);
+ sign = !sign;
+ }
+
+ r128__umul(&tc, &ta, &tb);
+ if (sign) {
+ r128__neg(&tc, &tc);
+ }
+
+ r128Copy(dst, &tc);
+}
+
+void r128Div(R128 *dst, const R128 *a, const R128 *b)
+{
+ int sign = 0;
+ R128 tn, td, tq;
+
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(a != NULL);
+ R128_ASSERT(b != NULL);
+
+ R128_SET2(&tn, a->lo, a->hi);
+ R128_SET2(&td, b->lo, b->hi);
+
+ if (r128IsNeg(&tn)) {
+ r128__neg(&tn, &tn);
+ sign = !sign;
+ }
+
+ if (td.lo == 0 && td.hi == 0) {
+ // divide by zero
+ if (sign) {
+ r128Copy(dst, &R128_min);
+ } else {
+ r128Copy(dst, &R128_max);
+ }
+ return;
+ } else if (r128IsNeg(&td)) {
+ r128__neg(&td, &td);
+ sign = !sign;
+ }
+
+ r128__udiv(&tq, &tn, &td);
+
+ if (sign) {
+ r128__neg(&tq, &tq);
+ }
+
+ r128Copy(dst, &tq);
+}
+
+void r128Mod(R128 *dst, const R128 *a, const R128 *b)
+{
+ int sign = 0;
+ R128 tn, td, tq;
+
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(a != NULL);
+ R128_ASSERT(b != NULL);
+
+ R128_SET2(&tn, a->lo, a->hi);
+ R128_SET2(&td, b->lo, b->hi);
+
+ if (r128IsNeg(&tn)) {
+ r128__neg(&tn, &tn);
+ sign = !sign;
+ }
+
+ if (td.lo == 0 && td.hi == 0) {
+ // divide by zero
+ if (sign) {
+ r128Copy(dst, &R128_min);
+ } else {
+ r128Copy(dst, &R128_max);
+ }
+ return;
+ } else if (r128IsNeg(&td)) {
+ r128__neg(&td, &td);
+ sign = !sign;
+ }
+
+ tq.hi = r128__umod(&tn, &td);
+ tq.lo = 0;
+
+ if (sign) {
+ tq.hi = ~tq.hi + 1;
+ }
+
+ r128Mul(&tq, &tq, b);
+ r128Sub(dst, a, &tq);
+}
+
+void r128Rsqrt(R128 *dst, const R128 *v)
+{
+ static const R128 threeHalves = { R128_LIT_U64(0x8000000000000000), 1 };
+ R128 x, est;
+ int i;
+
+ if ((R128_S64)v->hi < 0) {
+ r128Copy(dst, &R128_min);
+ return;
+ }
+
+ R128_SET2(&x, v->lo, v->hi);
+
+ // get initial estimate
+ if (x.hi) {
+ int shift = (64 + r128__clz64(x.hi)) >> 1;
+ est.lo = R128_LIT_U64(1) << shift;
+ est.hi = 0;
+ } else if (x.lo) {
+ int shift = r128__clz64(x.lo) >> 1;
+ est.hi = R128_LIT_U64(1) << shift;
+ est.lo = 0;
+ } else {
+ R128_SET2(dst, 0, 0);
+ return;
+ }
+
+ // x /= 2
+ r128Shr(&x, &x, 1);
+
+ // Newton-Raphson iterate
+ for (i = 0; i < 7; ++i) {
+ R128 newEst;
+
+ // newEst = est * (threeHalves - (x / 2) * est * est);
+ r128__umul(&newEst, &est, &est);
+ r128__umul(&newEst, &newEst, &x);
+ r128Sub(&newEst, &threeHalves, &newEst);
+ r128__umul(&newEst, &est, &newEst);
+
+ if (newEst.lo == est.lo && newEst.hi == est.hi) {
+ break;
+ }
+ R128_SET2(&est, newEst.lo, newEst.hi);
+ }
+
+ r128Copy(dst, &est);
+}
+
+void r128Sqrt(R128 *dst, const R128 *v)
+{
+ R128 x, est;
+ int i;
+
+ if ((R128_S64)v->hi < 0) {
+ r128Copy(dst, &R128_min);
+ return;
+ }
+
+ R128_SET2(&x, v->lo, v->hi);
+
+ // get initial estimate
+ if (x.hi) {
+ int shift = (63 - r128__clz64(x.hi)) >> 1;
+ r128Shr(&est, &x, shift);
+ } else if (x.lo) {
+ int shift = (1 + r128__clz64(x.lo)) >> 1;
+ r128Shl(&est, &x, shift);
+ } else {
+ R128_SET2(dst, 0, 0);
+ return;
+ }
+
+ // Newton-Raphson iterate
+ for (i = 0; i < 7; ++i) {
+ R128 newEst;
+
+ // newEst = (est + x / est) / 2
+ r128__udiv(&newEst, &x, &est);
+ r128Add(&newEst, &newEst, &est);
+ r128Shr(&newEst, &newEst, 1);
+
+ if (newEst.lo == est.lo && newEst.hi == est.hi) {
+ break;
+ }
+ R128_SET2(&est, newEst.lo, newEst.hi);
+ }
+
+ r128Copy(dst, &est);
+}
+
+int r128Cmp(const R128 *a, const R128 *b)
+{
+ R128_ASSERT(a != NULL);
+ R128_ASSERT(b != NULL);
+
+ if (a->hi == b->hi) {
+ if (a->lo == b->lo) {
+ return 0;
+ } else if (a->lo > b->lo) {
+ return 1;
+ } else {
+ return -1;
+ }
+ } else if ((R128_S64)a->hi > (R128_S64)b->hi) {
+ return 1;
+ } else {
+ return -1;
+ }
+}
+
+int r128IsNeg(const R128 *v)
+{
+ R128_ASSERT(v != NULL);
+
+ return (R128_S64)v->hi < 0;
+}
+
+void r128Min(R128 *dst, const R128 *a, const R128 *b)
+{
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(a != NULL);
+ R128_ASSERT(b != NULL);
+
+ if (r128Cmp(a, b) < 0) {
+ r128Copy(dst, a);
+ } else {
+ r128Copy(dst, b);
+ }
+}
+
+void r128Max(R128 *dst, const R128 *a, const R128 *b)
+{
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(a != NULL);
+ R128_ASSERT(b != NULL);
+
+ if (r128Cmp(a, b) > 0) {
+ r128Copy(dst, a);
+ } else {
+ r128Copy(dst, b);
+ }
+}
+
+void r128Floor(R128 *dst, const R128 *v)
+{
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(v != NULL);
+
+ if ((R128_S64)v->hi < 0) {
+ dst->hi = v->hi - (v->lo != 0);
+ } else {
+ dst->hi = v->hi;
+ }
+ dst->lo = 0;
+ R128_DEBUG_SET(dst);
+}
+
+void r128Ceil(R128 *dst, const R128 *v)
+{
+ R128_ASSERT(dst != NULL);
+ R128_ASSERT(v != NULL);
+
+ if ((R128_S64)v->hi > 0) {
+ dst->hi = v->hi + (v->lo != 0);
+ } else {
+ dst->hi = v->hi;
+ }
+ dst->lo = 0;
+ R128_DEBUG_SET(dst);
+}
+
+#endif //R128_IMPLEMENTATION
diff --git a/thirdparty/misc/stb_rect_pack.h b/thirdparty/misc/stb_rect_pack.h
new file mode 100644
index 0000000000..5c848de0e7
--- /dev/null
+++ b/thirdparty/misc/stb_rect_pack.h
@@ -0,0 +1,628 @@
+// stb_rect_pack.h - v1.00 - public domain - rectangle packing
+// Sean Barrett 2014
+//
+// Useful for e.g. packing rectangular textures into an atlas.
+// Does not do rotation.
+//
+// Not necessarily the awesomest packing method, but better than
+// the totally naive one in stb_truetype (which is primarily what
+// this is meant to replace).
+//
+// Has only had a few tests run, may have issues.
+//
+// More docs to come.
+//
+// No memory allocations; uses qsort() and assert() from stdlib.
+// Can override those by defining STBRP_SORT and STBRP_ASSERT.
+//
+// This library currently uses the Skyline Bottom-Left algorithm.
+//
+// Please note: better rectangle packers are welcome! Please
+// implement them to the same API, but with a different init
+// function.
+//
+// Credits
+//
+// Library
+// Sean Barrett
+// Minor features
+// Martins Mozeiko
+// github:IntellectualKitty
+//
+// Bugfixes / warning fixes
+// Jeremy Jaussaud
+// Fabian Giesen
+//
+// Version history:
+//
+// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
+// 0.99 (2019-02-07) warning fixes
+// 0.11 (2017-03-03) return packing success/fail result
+// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
+// 0.09 (2016-08-27) fix compiler warnings
+// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
+// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
+// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
+// 0.05: added STBRP_ASSERT to allow replacing assert
+// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
+// 0.01: initial release
+//
+// LICENSE
+//
+// See end of file for license information.
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// INCLUDE SECTION
+//
+
+#ifndef STB_INCLUDE_STB_RECT_PACK_H
+#define STB_INCLUDE_STB_RECT_PACK_H
+
+#define STB_RECT_PACK_VERSION 1
+
+#ifdef STBRP_STATIC
+#define STBRP_DEF static
+#else
+#define STBRP_DEF extern
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct stbrp_context stbrp_context;
+typedef struct stbrp_node stbrp_node;
+typedef struct stbrp_rect stbrp_rect;
+
+#ifdef STBRP_LARGE_RECTS
+typedef int stbrp_coord;
+#else
+typedef unsigned short stbrp_coord;
+#endif
+
+STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
+// Assign packed locations to rectangles. The rectangles are of type
+// 'stbrp_rect' defined below, stored in the array 'rects', and there
+// are 'num_rects' many of them.
+//
+// Rectangles which are successfully packed have the 'was_packed' flag
+// set to a non-zero value and 'x' and 'y' store the minimum location
+// on each axis (i.e. bottom-left in cartesian coordinates, top-left
+// if you imagine y increasing downwards). Rectangles which do not fit
+// have the 'was_packed' flag set to 0.
+//
+// You should not try to access the 'rects' array from another thread
+// while this function is running, as the function temporarily reorders
+// the array while it executes.
+//
+// To pack into another rectangle, you need to call stbrp_init_target
+// again. To continue packing into the same rectangle, you can call
+// this function again. Calling this multiple times with multiple rect
+// arrays will probably produce worse packing results than calling it
+// a single time with the full rectangle array, but the option is
+// available.
+//
+// The function returns 1 if all of the rectangles were successfully
+// packed and 0 otherwise.
+
+struct stbrp_rect
+{
+ // reserved for your use:
+ int id;
+
+ // input:
+ stbrp_coord w, h;
+
+ // output:
+ stbrp_coord x, y;
+ int was_packed; // non-zero if valid packing
+
+}; // 16 bytes, nominally
+
+
+STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
+// Initialize a rectangle packer to:
+// pack a rectangle that is 'width' by 'height' in dimensions
+// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
+//
+// You must call this function every time you start packing into a new target.
+//
+// There is no "shutdown" function. The 'nodes' memory must stay valid for
+// the following stbrp_pack_rects() call (or calls), but can be freed after
+// the call (or calls) finish.
+//
+// Note: to guarantee best results, either:
+// 1. make sure 'num_nodes' >= 'width'
+// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
+//
+// If you don't do either of the above things, widths will be quantized to multiples
+// of small integers to guarantee the algorithm doesn't run out of temporary storage.
+//
+// If you do #2, then the non-quantized algorithm will be used, but the algorithm
+// may run out of temporary storage and be unable to pack some rectangles.
+
+STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
+// Optionally call this function after init but before doing any packing to
+// change the handling of the out-of-temp-memory scenario, described above.
+// If you call init again, this will be reset to the default (false).
+
+
+STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
+// Optionally select which packing heuristic the library should use. Different
+// heuristics will produce better/worse results for different data sets.
+// If you call init again, this will be reset to the default.
+
+enum
+{
+ STBRP_HEURISTIC_Skyline_default=0,
+ STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
+ STBRP_HEURISTIC_Skyline_BF_sortHeight
+};
+
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// the details of the following structures don't matter to you, but they must
+// be visible so you can handle the memory allocations for them
+
+struct stbrp_node
+{
+ stbrp_coord x,y;
+ stbrp_node *next;
+};
+
+struct stbrp_context
+{
+ int width;
+ int height;
+ int align;
+ int init_mode;
+ int heuristic;
+ int num_nodes;
+ stbrp_node *active_head;
+ stbrp_node *free_head;
+ stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// IMPLEMENTATION SECTION
+//
+
+#ifdef STB_RECT_PACK_IMPLEMENTATION
+#ifndef STBRP_SORT
+#include <stdlib.h>
+#define STBRP_SORT qsort
+#endif
+
+#ifndef STBRP_ASSERT
+#include <assert.h>
+#define STBRP_ASSERT assert
+#endif
+
+#ifdef _MSC_VER
+#define STBRP__NOTUSED(v) (void)(v)
+#else
+#define STBRP__NOTUSED(v) (void)sizeof(v)
+#endif
+
+enum
+{
+ STBRP__INIT_skyline = 1
+};
+
+STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
+{
+ switch (context->init_mode) {
+ case STBRP__INIT_skyline:
+ STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
+ context->heuristic = heuristic;
+ break;
+ default:
+ STBRP_ASSERT(0);
+ }
+}
+
+STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
+{
+ if (allow_out_of_mem)
+ // if it's ok to run out of memory, then don't bother aligning them;
+ // this gives better packing, but may fail due to OOM (even though
+ // the rectangles easily fit). @TODO a smarter approach would be to only
+ // quantize once we've hit OOM, then we could get rid of this parameter.
+ context->align = 1;
+ else {
+ // if it's not ok to run out of memory, then quantize the widths
+ // so that num_nodes is always enough nodes.
+ //
+ // I.e. num_nodes * align >= width
+ // align >= width / num_nodes
+ // align = ceil(width/num_nodes)
+
+ context->align = (context->width + context->num_nodes-1) / context->num_nodes;
+ }
+}
+
+STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
+{
+ int i;
+#ifndef STBRP_LARGE_RECTS
+ STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
+#endif
+
+ for (i=0; i < num_nodes-1; ++i)
+ nodes[i].next = &nodes[i+1];
+ nodes[i].next = NULL;
+ context->init_mode = STBRP__INIT_skyline;
+ context->heuristic = STBRP_HEURISTIC_Skyline_default;
+ context->free_head = &nodes[0];
+ context->active_head = &context->extra[0];
+ context->width = width;
+ context->height = height;
+ context->num_nodes = num_nodes;
+ stbrp_setup_allow_out_of_mem(context, 0);
+
+ // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
+ context->extra[0].x = 0;
+ context->extra[0].y = 0;
+ context->extra[0].next = &context->extra[1];
+ context->extra[1].x = (stbrp_coord) width;
+#ifdef STBRP_LARGE_RECTS
+ context->extra[1].y = (1<<30);
+#else
+ context->extra[1].y = 65535;
+#endif
+ context->extra[1].next = NULL;
+}
+
+// find minimum y position if it starts at x1
+static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
+{
+ stbrp_node *node = first;
+ int x1 = x0 + width;
+ int min_y, visited_width, waste_area;
+
+ STBRP__NOTUSED(c);
+
+ STBRP_ASSERT(first->x <= x0);
+
+ #if 0
+ // skip in case we're past the node
+ while (node->next->x <= x0)
+ ++node;
+ #else
+ STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
+ #endif
+
+ STBRP_ASSERT(node->x <= x0);
+
+ min_y = 0;
+ waste_area = 0;
+ visited_width = 0;
+ while (node->x < x1) {
+ if (node->y > min_y) {
+ // raise min_y higher.
+ // we've accounted for all waste up to min_y,
+ // but we'll now add more waste for everything we've visted
+ waste_area += visited_width * (node->y - min_y);
+ min_y = node->y;
+ // the first time through, visited_width might be reduced
+ if (node->x < x0)
+ visited_width += node->next->x - x0;
+ else
+ visited_width += node->next->x - node->x;
+ } else {
+ // add waste area
+ int under_width = node->next->x - node->x;
+ if (under_width + visited_width > width)
+ under_width = width - visited_width;
+ waste_area += under_width * (min_y - node->y);
+ visited_width += under_width;
+ }
+ node = node->next;
+ }
+
+ *pwaste = waste_area;
+ return min_y;
+}
+
+typedef struct
+{
+ int x,y;
+ stbrp_node **prev_link;
+} stbrp__findresult;
+
+static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
+{
+ int best_waste = (1<<30), best_x, best_y = (1 << 30);
+ stbrp__findresult fr;
+ stbrp_node **prev, *node, *tail, **best = NULL;
+
+ // align to multiple of c->align
+ width = (width + c->align - 1);
+ width -= width % c->align;
+ STBRP_ASSERT(width % c->align == 0);
+
+ // if it can't possibly fit, bail immediately
+ if (width > c->width || height > c->height) {
+ fr.prev_link = NULL;
+ fr.x = fr.y = 0;
+ return fr;
+ }
+
+ node = c->active_head;
+ prev = &c->active_head;
+ while (node->x + width <= c->width) {
+ int y,waste;
+ y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
+ if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
+ // bottom left
+ if (y < best_y) {
+ best_y = y;
+ best = prev;
+ }
+ } else {
+ // best-fit
+ if (y + height <= c->height) {
+ // can only use it if it first vertically
+ if (y < best_y || (y == best_y && waste < best_waste)) {
+ best_y = y;
+ best_waste = waste;
+ best = prev;
+ }
+ }
+ }
+ prev = &node->next;
+ node = node->next;
+ }
+
+ best_x = (best == NULL) ? 0 : (*best)->x;
+
+ // if doing best-fit (BF), we also have to try aligning right edge to each node position
+ //
+ // e.g, if fitting
+ //
+ // ____________________
+ // |____________________|
+ //
+ // into
+ //
+ // | |
+ // | ____________|
+ // |____________|
+ //
+ // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
+ //
+ // This makes BF take about 2x the time
+
+ if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
+ tail = c->active_head;
+ node = c->active_head;
+ prev = &c->active_head;
+ // find first node that's admissible
+ while (tail->x < width)
+ tail = tail->next;
+ while (tail) {
+ int xpos = tail->x - width;
+ int y,waste;
+ STBRP_ASSERT(xpos >= 0);
+ // find the left position that matches this
+ while (node->next->x <= xpos) {
+ prev = &node->next;
+ node = node->next;
+ }
+ STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
+ y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
+ if (y + height <= c->height) {
+ if (y <= best_y) {
+ if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
+ best_x = xpos;
+ STBRP_ASSERT(y <= best_y);
+ best_y = y;
+ best_waste = waste;
+ best = prev;
+ }
+ }
+ }
+ tail = tail->next;
+ }
+ }
+
+ fr.prev_link = best;
+ fr.x = best_x;
+ fr.y = best_y;
+ return fr;
+}
+
+static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
+{
+ // find best position according to heuristic
+ stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
+ stbrp_node *node, *cur;
+
+ // bail if:
+ // 1. it failed
+ // 2. the best node doesn't fit (we don't always check this)
+ // 3. we're out of memory
+ if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
+ res.prev_link = NULL;
+ return res;
+ }
+
+ // on success, create new node
+ node = context->free_head;
+ node->x = (stbrp_coord) res.x;
+ node->y = (stbrp_coord) (res.y + height);
+
+ context->free_head = node->next;
+
+ // insert the new node into the right starting point, and
+ // let 'cur' point to the remaining nodes needing to be
+ // stiched back in
+
+ cur = *res.prev_link;
+ if (cur->x < res.x) {
+ // preserve the existing one, so start testing with the next one
+ stbrp_node *next = cur->next;
+ cur->next = node;
+ cur = next;
+ } else {
+ *res.prev_link = node;
+ }
+
+ // from here, traverse cur and free the nodes, until we get to one
+ // that shouldn't be freed
+ while (cur->next && cur->next->x <= res.x + width) {
+ stbrp_node *next = cur->next;
+ // move the current node to the free list
+ cur->next = context->free_head;
+ context->free_head = cur;
+ cur = next;
+ }
+
+ // stitch the list back in
+ node->next = cur;
+
+ if (cur->x < res.x + width)
+ cur->x = (stbrp_coord) (res.x + width);
+
+#ifdef _DEBUG
+ cur = context->active_head;
+ while (cur->x < context->width) {
+ STBRP_ASSERT(cur->x < cur->next->x);
+ cur = cur->next;
+ }
+ STBRP_ASSERT(cur->next == NULL);
+
+ {
+ int count=0;
+ cur = context->active_head;
+ while (cur) {
+ cur = cur->next;
+ ++count;
+ }
+ cur = context->free_head;
+ while (cur) {
+ cur = cur->next;
+ ++count;
+ }
+ STBRP_ASSERT(count == context->num_nodes+2);
+ }
+#endif
+
+ return res;
+}
+
+static int rect_height_compare(const void *a, const void *b)
+{
+ const stbrp_rect *p = (const stbrp_rect *) a;
+ const stbrp_rect *q = (const stbrp_rect *) b;
+ if (p->h > q->h)
+ return -1;
+ if (p->h < q->h)
+ return 1;
+ return (p->w > q->w) ? -1 : (p->w < q->w);
+}
+
+static int rect_original_order(const void *a, const void *b)
+{
+ const stbrp_rect *p = (const stbrp_rect *) a;
+ const stbrp_rect *q = (const stbrp_rect *) b;
+ return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
+}
+
+#ifdef STBRP_LARGE_RECTS
+#define STBRP__MAXVAL 0xffffffff
+#else
+#define STBRP__MAXVAL 0xffff
+#endif
+
+STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
+{
+ int i, all_rects_packed = 1;
+
+ // we use the 'was_packed' field internally to allow sorting/unsorting
+ for (i=0; i < num_rects; ++i) {
+ rects[i].was_packed = i;
+ }
+
+ // sort according to heuristic
+ STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
+
+ for (i=0; i < num_rects; ++i) {
+ if (rects[i].w == 0 || rects[i].h == 0) {
+ rects[i].x = rects[i].y = 0; // empty rect needs no space
+ } else {
+ stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
+ if (fr.prev_link) {
+ rects[i].x = (stbrp_coord) fr.x;
+ rects[i].y = (stbrp_coord) fr.y;
+ } else {
+ rects[i].x = rects[i].y = STBRP__MAXVAL;
+ }
+ }
+ }
+
+ // unsort
+ STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
+
+ // set was_packed flags and all_rects_packed status
+ for (i=0; i < num_rects; ++i) {
+ rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
+ if (!rects[i].was_packed)
+ all_rects_packed = 0;
+ }
+
+ // return the all_rects_packed status
+ return all_rects_packed;
+}
+#endif
+
+/*
+------------------------------------------------------------------------------
+This software is available under 2 licenses -- choose whichever you prefer.
+------------------------------------------------------------------------------
+ALTERNATIVE A - MIT License
+Copyright (c) 2017 Sean Barrett
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+------------------------------------------------------------------------------
+ALTERNATIVE B - Public Domain (www.unlicense.org)
+This is free and unencumbered software released into the public domain.
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
+software, either in source code form or as a compiled binary, for any purpose,
+commercial or non-commercial, and by any means.
+In jurisdictions that recognize copyright laws, the author or authors of this
+software dedicate any and all copyright interest in the software to the public
+domain. We make this dedication for the benefit of the public at large and to
+the detriment of our heirs and successors. We intend this dedication to be an
+overt act of relinquishment in perpetuity of all present and future rights to
+this software under copyright law.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------------------
+*/
diff --git a/thirdparty/misc/stb_vorbis.c b/thirdparty/misc/stb_vorbis.c
index 4ab8880d5d..b0d79b1724 100644
--- a/thirdparty/misc/stb_vorbis.c
+++ b/thirdparty/misc/stb_vorbis.c
@@ -1,4 +1,4 @@
-// Ogg Vorbis audio decoder - v1.17 - public domain
+// Ogg Vorbis audio decoder - v1.19 - public domain
// http://nothings.org/stb_vorbis/
//
// Original version written by Sean Barrett in 2007.
@@ -26,13 +26,16 @@
// Terje Mathisen Niklas Frykholm Andy Hill
// Casey Muratori John Bolton Gargaj
// Laurent Gomila Marc LeBlanc Ronny Chevalier
-// Bernhard Wodo Evan Balster alxprd@github
+// Bernhard Wodo Evan Balster github:alxprd
// Tom Beaumont Ingo Leitgeb Nicolas Guillemot
// Phillip Bennefall Rohit Thiago Goulart
-// manxorist@github saga musix github:infatum
-// Timur Gagiev Maxwell Koo
+// github:manxorist saga musix github:infatum
+// Timur Gagiev Maxwell Koo Peter Waller
+// github:audinowho Dougall Johnson
//
// Partial history:
+// 1.19 - 2020-02-05 - warnings
+// 1.18 - 2020-02-02 - fix seek bugs; parse header comments; misc warnings etc.
// 1.17 - 2019-07-08 - fix CVE-2019-13217..CVE-2019-13223 (by ForAllSecure)
// 1.16 - 2019-03-04 - fix warnings
// 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found
@@ -130,9 +133,20 @@ typedef struct
int max_frame_size;
} stb_vorbis_info;
+typedef struct
+{
+ char *vendor;
+
+ int comment_list_length;
+ char **comment_list;
+} stb_vorbis_comment;
+
// get general information about the file
extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f);
+// get ogg comments
+extern stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f);
+
// get the last error detected (clears it, too)
extern int stb_vorbis_get_error(stb_vorbis *f);
@@ -759,6 +773,10 @@ struct stb_vorbis
unsigned int temp_memory_required;
unsigned int setup_temp_memory_required;
+ char *vendor;
+ int comment_list_length;
+ char **comment_list;
+
// input config
#ifndef STB_VORBIS_NO_STDIO
FILE *f;
@@ -774,8 +792,11 @@ struct stb_vorbis
uint8 push_mode;
+ // the page to seek to when seeking to start, may be zero
uint32 first_audio_page_offset;
+ // p_first is the page on which the first audio packet ends
+ // (but not necessarily the page on which it starts)
ProbedPage p_first, p_last;
// memory management
@@ -888,7 +909,7 @@ static int error(vorb *f, enum STBVorbisError e)
#define array_size_required(count,size) (count*(sizeof(void *)+(size)))
#define temp_alloc(f,size) (f->alloc.alloc_buffer ? setup_temp_malloc(f,size) : alloca(size))
-#define temp_free(f,p) 0
+#define temp_free(f,p) (void)0
#define temp_alloc_save(f) ((f)->temp_offset)
#define temp_alloc_restore(f,p) ((f)->temp_offset = (p))
@@ -909,7 +930,7 @@ static void *make_block_array(void *mem, int count, int size)
static void *setup_malloc(vorb *f, int sz)
{
- sz = (sz+3) & ~3;
+ sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs.
f->setup_memory_required += sz;
if (f->alloc.alloc_buffer) {
void *p = (char *) f->alloc.alloc_buffer + f->setup_offset;
@@ -928,7 +949,7 @@ static void setup_free(vorb *f, void *p)
static void *setup_temp_malloc(vorb *f, int sz)
{
- sz = (sz+3) & ~3;
+ sz = (sz+7) & ~7; // round up to nearest 8 for alignment of future allocs.
if (f->alloc.alloc_buffer) {
if (f->temp_offset - sz < f->setup_offset) return NULL;
f->temp_offset -= sz;
@@ -940,7 +961,7 @@ static void *setup_temp_malloc(vorb *f, int sz)
static void setup_temp_free(vorb *f, void *p, int sz)
{
if (f->alloc.alloc_buffer) {
- f->temp_offset += (sz+3)&~3;
+ f->temp_offset += (sz+7)&~7;
return;
}
free(p);
@@ -1404,6 +1425,9 @@ static int capture_pattern(vorb *f)
static int start_page_no_capturepattern(vorb *f)
{
uint32 loc0,loc1,n;
+ if (f->first_decode && !IS_PUSH_MODE(f)) {
+ f->p_first.page_start = stb_vorbis_get_file_offset(f) - 4;
+ }
// stream structure version
if (0 != get8(f)) return error(f, VORBIS_invalid_stream_structure_version);
// header flag
@@ -1440,15 +1464,12 @@ static int start_page_no_capturepattern(vorb *f)
}
if (f->first_decode) {
int i,len;
- ProbedPage p;
len = 0;
for (i=0; i < f->segment_count; ++i)
len += f->segments[i];
len += 27 + f->segment_count;
- p.page_start = f->first_audio_page_offset;
- p.page_end = p.page_start + len;
- p.last_decoded_sample = loc0;
- f->p_first = p;
+ f->p_first.page_end = f->p_first.page_start + len;
+ f->p_first.last_decoded_sample = loc0;
}
f->next_seg = 0;
return TRUE;
@@ -1539,6 +1560,16 @@ static int get8_packet(vorb *f)
return x;
}
+static int get32_packet(vorb *f)
+{
+ uint32 x;
+ x = get8_packet(f);
+ x += get8_packet(f) << 8;
+ x += get8_packet(f) << 16;
+ x += (uint32) get8_packet(f) << 24;
+ return x;
+}
+
static void flush_packet(vorb *f)
{
while (get8_packet_raw(f) != EOP);
@@ -2130,47 +2161,7 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int
++class_set;
#endif
}
- } else if (ch == 1) {
- while (pcount < part_read) {
- int z = r->begin + pcount*r->part_size;
- int c_inter = 0, p_inter = z;
- if (pass == 0) {
- Codebook *c = f->codebooks+r->classbook;
- int q;
- DECODE(q,f,c);
- if (q == EOP) goto done;
- #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
- part_classdata[0][class_set] = r->classdata[q];
- #else
- for (i=classwords-1; i >= 0; --i) {
- classifications[0][i+pcount] = q % r->classifications;
- q /= r->classifications;
- }
- #endif
- }
- for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) {
- int z = r->begin + pcount*r->part_size;
- #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
- int c = part_classdata[0][class_set][i];
- #else
- int c = classifications[0][pcount];
- #endif
- int b = r->residue_books[c][pass];
- if (b >= 0) {
- Codebook *book = f->codebooks + b;
- if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size))
- goto done;
- } else {
- z += r->part_size;
- c_inter = 0;
- p_inter = z;
- }
- }
- #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE
- ++class_set;
- #endif
- }
- } else {
+ } else if (ch > 2) {
while (pcount < part_read) {
int z = r->begin + pcount*r->part_size;
int c_inter = z % ch, p_inter = z/ch;
@@ -3504,7 +3495,7 @@ static int vorbis_pump_first_frame(stb_vorbis *f)
}
#ifndef STB_VORBIS_NO_PUSHDATA_API
-static int is_whole_packet_present(stb_vorbis *f, int end_page)
+static int is_whole_packet_present(stb_vorbis *f)
{
// make sure that we have the packet available before continuing...
// this requires a full ogg parse, but we know we can fetch from f->stream
@@ -3524,8 +3515,6 @@ static int is_whole_packet_present(stb_vorbis *f, int end_page)
break;
}
// either this continues, or it ends it...
- if (end_page)
- if (s < f->segment_count-1) return error(f, VORBIS_invalid_stream);
if (s == f->segment_count)
s = -1; // set 'crosses page' flag
if (p > f->stream_end) return error(f, VORBIS_need_more_data);
@@ -3558,8 +3547,6 @@ static int is_whole_packet_present(stb_vorbis *f, int end_page)
if (q[s] < 255)
break;
}
- if (end_page)
- if (s < n-1) return error(f, VORBIS_invalid_stream);
if (s == n)
s = -1; // set 'crosses page' flag
if (p > f->stream_end) return error(f, VORBIS_need_more_data);
@@ -3576,6 +3563,7 @@ static int start_decoder(vorb *f)
int longest_floorlist=0;
// first page, first packet
+ f->first_decode = TRUE;
if (!start_page(f)) return FALSE;
// validate page flag
@@ -3633,6 +3621,41 @@ static int start_decoder(vorb *f)
if (!start_page(f)) return FALSE;
if (!start_packet(f)) return FALSE;
+
+ if (!next_segment(f)) return FALSE;
+
+ if (get8_packet(f) != VORBIS_packet_comment) return error(f, VORBIS_invalid_setup);
+ for (i=0; i < 6; ++i) header[i] = get8_packet(f);
+ if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup);
+ //file vendor
+ len = get32_packet(f);
+ f->vendor = (char*)setup_malloc(f, sizeof(char) * (len+1));
+ for(i=0; i < len; ++i) {
+ f->vendor[i] = get8_packet(f);
+ }
+ f->vendor[len] = (char)'\0';
+ //user comments
+ f->comment_list_length = get32_packet(f);
+ f->comment_list = (char**)setup_malloc(f, sizeof(char*) * (f->comment_list_length));
+
+ for(i=0; i < f->comment_list_length; ++i) {
+ len = get32_packet(f);
+ f->comment_list[i] = (char*)setup_malloc(f, sizeof(char) * (len+1));
+
+ for(j=0; j < len; ++j) {
+ f->comment_list[i][j] = get8_packet(f);
+ }
+ f->comment_list[i][len] = (char)'\0';
+ }
+
+ // framing_flag
+ x = get8_packet(f);
+ if (!(x & 1)) return error(f, VORBIS_invalid_setup);
+
+
+ skip(f, f->bytes_in_seg);
+ f->bytes_in_seg = 0;
+
do {
len = next_segment(f);
skip(f, len);
@@ -3644,7 +3667,7 @@ static int start_decoder(vorb *f)
#ifndef STB_VORBIS_NO_PUSHDATA_API
if (IS_PUSH_MODE(f)) {
- if (!is_whole_packet_present(f, TRUE)) {
+ if (!is_whole_packet_present(f)) {
// convert error in ogg header to write type
if (f->error == VORBIS_invalid_stream)
f->error = VORBIS_invalid_setup;
@@ -3947,7 +3970,7 @@ static int start_decoder(vorb *f)
g->sorted_order[j] = (uint8) p[j].id;
// precompute the neighbors
for (j=2; j < g->values; ++j) {
- int low,hi;
+ int low = 0,hi = 0;
neighbors(g->Xlist, j, &low,&hi);
g->neighbors[j][0] = low;
g->neighbors[j][1] = hi;
@@ -4132,7 +4155,6 @@ static int start_decoder(vorb *f)
f->temp_memory_required = imdct_mem;
}
- f->first_decode = TRUE;
if (f->alloc.alloc_buffer) {
assert(f->temp_offset == f->alloc.alloc_buffer_length_in_bytes);
@@ -4141,7 +4163,17 @@ static int start_decoder(vorb *f)
return error(f, VORBIS_outofmem);
}
- f->first_audio_page_offset = stb_vorbis_get_file_offset(f);
+ // @TODO: stb_vorbis_seek_start expects first_audio_page_offset to point to a page
+ // without PAGEFLAG_continued_packet, so this either points to the first page, or
+ // the page after the end of the headers. It might be cleaner to point to a page
+ // in the middle of the headers, when that's the page where the first audio packet
+ // starts, but we'd have to also correctly skip the end of any continued packet in
+ // stb_vorbis_seek_start.
+ if (f->next_seg == -1) {
+ f->first_audio_page_offset = stb_vorbis_get_file_offset(f);
+ } else {
+ f->first_audio_page_offset = 0;
+ }
return TRUE;
}
@@ -4149,6 +4181,13 @@ static int start_decoder(vorb *f)
static void vorbis_deinit(stb_vorbis *p)
{
int i,j;
+
+ setup_free(p, p->vendor);
+ for (i=0; i < p->comment_list_length; ++i) {
+ setup_free(p, p->comment_list[i]);
+ }
+ setup_free(p, p->comment_list);
+
if (p->residue_config) {
for (i=0; i < p->residue_count; ++i) {
Residue *r = p->residue_config+i;
@@ -4248,6 +4287,15 @@ stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f)
return d;
}
+stb_vorbis_comment stb_vorbis_get_comment(stb_vorbis *f)
+{
+ stb_vorbis_comment d;
+ d.vendor = f->vendor;
+ d.comment_list_length = f->comment_list_length;
+ d.comment_list = f->comment_list;
+ return d;
+}
+
int stb_vorbis_get_error(stb_vorbis *f)
{
int e = f->error;
@@ -4389,7 +4437,7 @@ int stb_vorbis_decode_frame_pushdata(
f->error = VORBIS__no_error;
// check that we have the entire packet in memory
- if (!is_whole_packet_present(f, FALSE)) {
+ if (!is_whole_packet_present(f)) {
*samples = 0;
return 0;
}
@@ -4625,8 +4673,8 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
{
ProbedPage left, right, mid;
int i, start_seg_with_known_loc, end_pos, page_start;
- uint32 delta, stream_length, padding;
- double offset, bytes_per_sample;
+ uint32 delta, stream_length, padding, last_sample_limit;
+ double offset = 0.0, bytes_per_sample = 0.0;
int probe = 0;
// find the last page and validate the target sample
@@ -4639,9 +4687,9 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
// indicates should be the granule position (give or take one)).
padding = ((f->blocksize_1 - f->blocksize_0) >> 2);
if (sample_number < padding)
- sample_number = 0;
+ last_sample_limit = 0;
else
- sample_number -= padding;
+ last_sample_limit = sample_number - padding;
left = f->p_first;
while (left.last_decoded_sample == ~0U) {
@@ -4654,9 +4702,12 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
assert(right.last_decoded_sample != ~0U);
// starting from the start is handled differently
- if (sample_number <= left.last_decoded_sample) {
- if (stb_vorbis_seek_start(f))
+ if (last_sample_limit <= left.last_decoded_sample) {
+ if (stb_vorbis_seek_start(f)) {
+ if (f->current_loc > sample_number)
+ return error(f, VORBIS_seek_failed);
return 1;
+ }
return 0;
}
@@ -4673,10 +4724,10 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
// first probe (interpolate)
double data_bytes = right.page_end - left.page_start;
bytes_per_sample = data_bytes / right.last_decoded_sample;
- offset = left.page_start + bytes_per_sample * (sample_number - left.last_decoded_sample);
+ offset = left.page_start + bytes_per_sample * (last_sample_limit - left.last_decoded_sample);
} else {
// second probe (try to bound the other side)
- double error = ((double) sample_number - mid.last_decoded_sample) * bytes_per_sample;
+ double error = ((double) last_sample_limit - mid.last_decoded_sample) * bytes_per_sample;
if (error >= 0 && error < 8000) error = 8000;
if (error < 0 && error > -8000) error = -8000;
offset += error * 2;
@@ -4707,14 +4758,16 @@ static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number)
}
// if we've just found the last page again then we're in a tricky file,
- // and we're close enough.
- if (mid.page_start == right.page_start)
- break;
-
- if (sample_number < mid.last_decoded_sample)
- right = mid;
- else
- left = mid;
+ // and we're close enough (if it wasn't an interpolation probe).
+ if (mid.page_start == right.page_start) {
+ if (probe >= 2 || delta <= 65536)
+ break;
+ } else {
+ if (last_sample_limit < mid.last_decoded_sample)
+ right = mid;
+ else
+ left = mid;
+ }
++probe;
}
@@ -4830,8 +4883,8 @@ int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number)
flush_packet(f);
}
}
- // the next frame will start with the sample
- assert(f->current_loc == sample_number);
+ // the next frame should start with the sample
+ if (f->current_loc != sample_number) return error(f, VORBIS_seek_failed);
return 1;
}
@@ -5173,7 +5226,7 @@ static void convert_samples_short(int buf_c, short **buffer, int b_offset, int d
int stb_vorbis_get_frame_short(stb_vorbis *f, int num_c, short **buffer, int num_samples)
{
- float **output;
+ float **output = NULL;
int len = stb_vorbis_get_frame_float(f, NULL, &output);
if (len > num_samples) len = num_samples;
if (len)
diff --git a/thirdparty/oidn/0001-window.h-case-sensitive.patch b/thirdparty/oidn/0001-window.h-case-sensitive.patch
new file mode 100644
index 0000000000..7b9c8e96c1
--- /dev/null
+++ b/thirdparty/oidn/0001-window.h-case-sensitive.patch
@@ -0,0 +1,13 @@
+diff --git a/thirdparty/oidn/common/platform.h b/thirdparty/oidn/common/platform.h
+index 205ac8981d..9373b617b5 100644
+--- a/thirdparty/oidn/common/platform.h
++++ b/thirdparty/oidn/common/platform.h
+@@ -19,7 +19,7 @@
+ #if defined(_WIN32)
+ #define WIN32_LEAN_AND_MEAN
+ #define NOMINMAX
+- #include <Windows.h>
++ #include <windows.h>
+ #elif defined(__APPLE__)
+ #include <sys/sysctl.h>
+ #endif
diff --git a/thirdparty/oidn/LICENSE.txt b/thirdparty/oidn/LICENSE.txt
new file mode 100644
index 0000000000..d645695673
--- /dev/null
+++ b/thirdparty/oidn/LICENSE.txt
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/thirdparty/oidn/common/barrier.h b/thirdparty/oidn/common/barrier.h
new file mode 100644
index 0000000000..b20f670053
--- /dev/null
+++ b/thirdparty/oidn/common/barrier.h
@@ -0,0 +1,52 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "platform.h"
+#include <mutex>
+#include <condition_variable>
+
+namespace oidn {
+
+ class Barrier
+ {
+ private:
+ std::mutex m;
+ std::condition_variable cv;
+ volatile int count;
+
+ public:
+ Barrier(int count) : count(count) {}
+
+ void wait()
+ {
+ std::unique_lock<std::mutex> lk(m);
+ count--;
+
+ if (count == 0)
+ {
+ lk.unlock();
+ cv.notify_all();
+ }
+ else
+ {
+ cv.wait(lk, [&]{ return count == 0; });
+ }
+ }
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/common/exception.h b/thirdparty/oidn/common/exception.h
new file mode 100644
index 0000000000..18069c6a7d
--- /dev/null
+++ b/thirdparty/oidn/common/exception.h
@@ -0,0 +1,45 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include <exception>
+#include "platform.h"
+
+namespace oidn {
+
+ class Exception : public std::exception
+ {
+ private:
+ Error error;
+ const char* message;
+
+ public:
+ Exception(Error error, const char* message)
+ : error(error), message(message) {}
+
+ Error code() const noexcept
+ {
+ return error;
+ }
+
+ const char* what() const noexcept override
+ {
+ return message;
+ }
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/common/platform.cpp b/thirdparty/oidn/common/platform.cpp
new file mode 100644
index 0000000000..59a14ff47c
--- /dev/null
+++ b/thirdparty/oidn/common/platform.cpp
@@ -0,0 +1,114 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#include "platform.h"
+
+namespace oidn {
+
+ // ----------------------------------------------------------------------------
+ // Common functions
+ // ----------------------------------------------------------------------------
+
+ void* alignedMalloc(size_t size, size_t alignment)
+ {
+ if (size == 0)
+ return nullptr;
+
+ assert((alignment & (alignment-1)) == 0);
+ void* ptr = _mm_malloc(size, alignment);
+
+ if (ptr == nullptr)
+ throw std::bad_alloc();
+
+ return ptr;
+ }
+
+ void alignedFree(void* ptr)
+ {
+ if (ptr)
+ _mm_free(ptr);
+ }
+
+ // ----------------------------------------------------------------------------
+ // System information
+ // ----------------------------------------------------------------------------
+
+ std::string getPlatformName()
+ {
+ std::string name;
+
+ #if defined(__linux__)
+ name = "Linux";
+ #elif defined(__FreeBSD__)
+ name = "FreeBSD";
+ #elif defined(__CYGWIN__)
+ name = "Cygwin";
+ #elif defined(_WIN32)
+ name = "Windows";
+ #elif defined(__APPLE__)
+ name = "macOS";
+ #elif defined(__unix__)
+ name = "Unix";
+ #else
+ return "Unknown";
+ #endif
+
+ #if defined(__x86_64__) || defined(_M_X64) || defined(__ia64__) || defined(__aarch64__)
+ name += " (64-bit)";
+ #else
+ name += " (32-bit)";
+ #endif
+
+ return name;
+ }
+
+ std::string getCompilerName()
+ {
+ #if defined(__INTEL_COMPILER)
+ int mayor = __INTEL_COMPILER / 100 % 100;
+ int minor = __INTEL_COMPILER % 100;
+ std::string version = "Intel Compiler ";
+ version += toString(mayor);
+ version += "." + toString(minor);
+ #if defined(__INTEL_COMPILER_UPDATE)
+ version += "." + toString(__INTEL_COMPILER_UPDATE);
+ #endif
+ return version;
+ #elif defined(__clang__)
+ return "Clang " __clang_version__;
+ #elif defined(__GNUC__)
+ return "GCC " __VERSION__;
+ #elif defined(_MSC_VER)
+ std::string version = toString(_MSC_FULL_VER);
+ version.insert(4, ".");
+ version.insert(9, ".");
+ version.insert(2, ".");
+ return "Visual C++ Compiler " + version;
+ #else
+ return "Unknown";
+ #endif
+ }
+
+ std::string getBuildName()
+ {
+ #if defined(NDEBUG)
+ return "Release";
+ #else
+ return "Debug";
+ #endif
+ }
+
+} // namespace oidn
diff --git a/thirdparty/oidn/common/platform.h b/thirdparty/oidn/common/platform.h
new file mode 100644
index 0000000000..9373b617b5
--- /dev/null
+++ b/thirdparty/oidn/common/platform.h
@@ -0,0 +1,131 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#if defined(_WIN32)
+ #define WIN32_LEAN_AND_MEAN
+ #define NOMINMAX
+ #include <windows.h>
+#elif defined(__APPLE__)
+ #include <sys/sysctl.h>
+#endif
+
+#include <xmmintrin.h>
+#include <cstdint>
+#include <climits>
+#include <limits>
+#include <atomic>
+#include <algorithm>
+#include <memory>
+#include <cmath>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <cassert>
+#include "include/OpenImageDenoise/oidn.hpp"
+
+namespace oidn {
+
+ // ----------------------------------------------------------------------------
+ // Macros
+ // ----------------------------------------------------------------------------
+
+ #if defined(_WIN32)
+ // Windows
+ #if !defined(__noinline)
+ #define __noinline __declspec(noinline)
+ #endif
+ #else
+ // Unix
+ #if !defined(__forceinline)
+ #define __forceinline inline __attribute__((always_inline))
+ #endif
+ #if !defined(__noinline)
+ #define __noinline __attribute__((noinline))
+ #endif
+ #endif
+
+ #ifndef UNUSED
+ #define UNUSED(x) ((void)x)
+ #endif
+ #ifndef MAYBE_UNUSED
+ #define MAYBE_UNUSED(x) UNUSED(x)
+ #endif
+
+ // ----------------------------------------------------------------------------
+ // Error handling and debugging
+ // ----------------------------------------------------------------------------
+
+ struct Verbose
+ {
+ int verbose;
+
+ Verbose(int v = 0) : verbose(v) {}
+ __forceinline bool isVerbose(int v = 1) const { return v <= verbose; }
+ };
+
+ #define OIDN_WARNING(message) { if (isVerbose()) std::cerr << "Warning: " << message << std::endl; }
+ #define OIDN_FATAL(message) throw std::runtime_error(message);
+
+ // ----------------------------------------------------------------------------
+ // Common functions
+ // ----------------------------------------------------------------------------
+
+ using std::min;
+ using std::max;
+
+ template<typename T>
+ __forceinline T clamp(const T& value, const T& minValue, const T& maxValue)
+ {
+ return min(max(value, minValue), maxValue);
+ }
+
+ void* alignedMalloc(size_t size, size_t alignment);
+ void alignedFree(void* ptr);
+
+ template<typename T>
+ inline std::string toString(const T& a)
+ {
+ std::stringstream sm;
+ sm << a;
+ return sm.str();
+ }
+
+#if defined(__APPLE__)
+ template<typename T>
+ bool getSysctl(const char* name, T& value)
+ {
+ int64_t result = 0;
+ size_t size = sizeof(result);
+
+ if (sysctlbyname(name, &result, &size, nullptr, 0) != 0)
+ return false;
+
+ value = T(result);
+ return true;
+ }
+#endif
+
+ // ----------------------------------------------------------------------------
+ // System information
+ // ----------------------------------------------------------------------------
+
+ std::string getPlatformName();
+ std::string getCompilerName();
+ std::string getBuildName();
+
+} // namespace oidn
diff --git a/thirdparty/oidn/common/ref.h b/thirdparty/oidn/common/ref.h
new file mode 100644
index 0000000000..de44603af2
--- /dev/null
+++ b/thirdparty/oidn/common/ref.h
@@ -0,0 +1,163 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "platform.h"
+
+namespace oidn {
+
+ class RefCount
+ {
+ private:
+ std::atomic<size_t> count;
+
+ public:
+ __forceinline RefCount(int count = 0) noexcept : count(count) {}
+
+ __forceinline size_t incRef() noexcept
+ {
+ return count.fetch_add(1) + 1;
+ }
+
+ __forceinline size_t decRef()
+ {
+ const size_t newCount = decRefKeep();
+ if (newCount == 0)
+ destroy();
+ return newCount;
+ }
+
+ __forceinline size_t decRefKeep() noexcept
+ {
+ return count.fetch_add(-1) - 1;
+ }
+
+ __forceinline void destroy()
+ {
+ delete this;
+ }
+
+ protected:
+ // Disable copying
+ RefCount(const RefCount&) = delete;
+ RefCount& operator =(const RefCount&) = delete;
+
+ virtual ~RefCount() noexcept = default;
+ };
+
+ template<typename T>
+ class Ref
+ {
+ private:
+ T* ptr;
+
+ public:
+ __forceinline Ref() noexcept : ptr(nullptr) {}
+ __forceinline Ref(std::nullptr_t) noexcept : ptr(nullptr) {}
+ __forceinline Ref(const Ref& other) noexcept : ptr(other.ptr) { if (ptr) ptr->incRef(); }
+ __forceinline Ref(Ref&& other) noexcept : ptr(other.ptr) { other.ptr = nullptr; }
+ __forceinline Ref(T* ptr) noexcept : ptr(ptr) { if (ptr) ptr->incRef(); }
+
+ template<typename Y>
+ __forceinline Ref(const Ref<Y>& other) noexcept : ptr(other.get()) { if (ptr) ptr->incRef(); }
+
+ template<typename Y>
+ __forceinline explicit Ref(Y* ptr) noexcept : ptr(ptr) { if (ptr) ptr->incRef(); }
+
+ __forceinline ~Ref() { if (ptr) ptr->decRef(); }
+
+ __forceinline Ref& operator =(const Ref& other)
+ {
+ if (other.ptr)
+ other.ptr->incRef();
+ if (ptr)
+ ptr->decRef();
+ ptr = other.ptr;
+ return *this;
+ }
+
+ __forceinline Ref& operator =(Ref&& other)
+ {
+ if (ptr)
+ ptr->decRef();
+ ptr = other.ptr;
+ other.ptr = nullptr;
+ return *this;
+ }
+
+ __forceinline Ref& operator =(T* other)
+ {
+ if (other)
+ other->incRef();
+ if (ptr)
+ ptr->decRef();
+ ptr = other;
+ return *this;
+ }
+
+ __forceinline Ref& operator =(std::nullptr_t)
+ {
+ if (ptr)
+ ptr->decRef();
+ ptr = nullptr;
+ return *this;
+ }
+
+ __forceinline operator bool() const noexcept { return ptr != nullptr; }
+
+ __forceinline T& operator *() const noexcept { return *ptr; }
+ __forceinline T* operator ->() const noexcept { return ptr; }
+
+ __forceinline T* get() const noexcept { return ptr; }
+
+ __forceinline T* detach() noexcept
+ {
+ T* res = ptr;
+ ptr = nullptr;
+ return res;
+ }
+ };
+
+ template<typename T> __forceinline bool operator < (const Ref<T>& a, const Ref<T>& b) noexcept { return a.ptr < b.ptr; }
+
+ template<typename T> __forceinline bool operator ==(const Ref<T>& a, std::nullptr_t) noexcept { return a.ptr == nullptr; }
+ template<typename T> __forceinline bool operator ==(std::nullptr_t, const Ref<T>& b) noexcept { return nullptr == b.ptr; }
+ template<typename T> __forceinline bool operator ==(const Ref<T>& a, const Ref<T>& b) noexcept { return a.ptr == b.ptr; }
+
+ template<typename T> __forceinline bool operator !=(const Ref<T>& a, std::nullptr_t) noexcept { return a.ptr != nullptr; }
+ template<typename T> __forceinline bool operator !=(std::nullptr_t, const Ref<T>& b) noexcept { return nullptr != b.ptr; }
+ template<typename T> __forceinline bool operator !=(const Ref<T>& a, const Ref<T>& b) noexcept { return a.ptr != b.ptr; }
+
+ template<typename T, typename... Args>
+ __forceinline Ref<T> makeRef(Args&&... args)
+ {
+ return Ref<T>(new T(std::forward<Args>(args)...));
+ }
+
+ template<typename T, typename Y>
+ __forceinline Ref<Y> staticRefCast(const Ref<T>& a)
+ {
+ return Ref<Y>(static_cast<Y*>(a.get()));
+ }
+
+ template<typename T, typename Y>
+ __forceinline Ref<Y> dynamicRefCast(const Ref<T>& a)
+ {
+ return Ref<Y>(dynamic_cast<Y*>(a.get()));
+ }
+
+} // namespace oidn
diff --git a/thirdparty/oidn/common/tensor.cpp b/thirdparty/oidn/common/tensor.cpp
new file mode 100644
index 0000000000..0249f2e141
--- /dev/null
+++ b/thirdparty/oidn/common/tensor.cpp
@@ -0,0 +1,83 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#include "exception.h"
+#include "tensor.h"
+
+namespace oidn {
+
+ std::map<std::string, Tensor> parseTensors(void* buffer)
+ {
+ char* input = (char*)buffer;
+
+ // Parse the magic value
+ const int magic = *(unsigned short*)input;
+ if (magic != 0x41D7)
+ throw Exception(Error::InvalidOperation, "invalid tensor archive");
+ input += sizeof(unsigned short);
+
+ // Parse the version
+ const int majorVersion = *(unsigned char*)input++;
+ const int minorVersion = *(unsigned char*)input++;
+ UNUSED(minorVersion);
+ if (majorVersion > 1)
+ throw Exception(Error::InvalidOperation, "unsupported tensor archive version");
+
+ // Parse the number of tensors
+ const int numTensors = *(int*)input;
+ input += sizeof(int);
+
+ // Parse the tensors
+ std::map<std::string, Tensor> tensorMap;
+ for (int i = 0; i < numTensors; ++i)
+ {
+ Tensor tensor;
+
+ // Parse the name
+ const int nameLen = *(unsigned char*)input++;
+ std::string name(input, nameLen);
+ input += nameLen;
+
+ // Parse the number of dimensions
+ const int ndims = *(unsigned char*)input++;
+
+ // Parse the shape of the tensor
+ tensor.dims.resize(ndims);
+ for (int i = 0; i < ndims; ++i)
+ tensor.dims[i] = ((int*)input)[i];
+ input += ndims * sizeof(int);
+
+ // Parse the format of the tensor
+ tensor.format = std::string(input, input + ndims);
+ input += ndims;
+
+ // Parse the data type of the tensor
+ const char type = *(unsigned char*)input++;
+ if (type != 'f') // only float32 is supported
+ throw Exception(Error::InvalidOperation, "unsupported tensor data type");
+
+ // Skip the data
+ tensor.data = (float*)input;
+ input += tensor.size() * sizeof(float);
+
+ // Add the tensor to the map
+ tensorMap.emplace(name, std::move(tensor));
+ }
+
+ return tensorMap;
+ }
+
+} // namespace oidn
diff --git a/thirdparty/oidn/common/tensor.h b/thirdparty/oidn/common/tensor.h
new file mode 100644
index 0000000000..48e7d1123d
--- /dev/null
+++ b/thirdparty/oidn/common/tensor.h
@@ -0,0 +1,66 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "platform.h"
+#include <vector>
+#include <map>
+
+namespace oidn {
+
+ template<typename T>
+ using shared_vector = std::shared_ptr<std::vector<T>>;
+
+ // Generic tensor
+ struct Tensor
+ {
+ float* data;
+ std::vector<int64_t> dims;
+ std::string format;
+ shared_vector<char> buffer; // optional, only for reference counting
+
+ __forceinline Tensor() : data(nullptr) {}
+
+ __forceinline Tensor(const std::vector<int64_t>& dims, const std::string& format)
+ : dims(dims),
+ format(format)
+ {
+ buffer = std::make_shared<std::vector<char>>(size() * sizeof(float));
+ data = (float*)buffer->data();
+ }
+
+ __forceinline operator bool() const { return data != nullptr; }
+
+ __forceinline int ndims() const { return (int)dims.size(); }
+
+ // Returns the number of values
+ __forceinline size_t size() const
+ {
+ size_t size = 1;
+ for (int i = 0; i < ndims(); ++i)
+ size *= dims[i];
+ return size;
+ }
+
+ __forceinline float& operator [](size_t i) { return data[i]; }
+ __forceinline const float& operator [](size_t i) const { return data[i]; }
+ };
+
+ // Parses tensors from a buffer
+ std::map<std::string, Tensor> parseTensors(void* buffer);
+
+} // namespace oidn
diff --git a/thirdparty/oidn/common/thread.cpp b/thirdparty/oidn/common/thread.cpp
new file mode 100644
index 0000000000..48c489c57b
--- /dev/null
+++ b/thirdparty/oidn/common/thread.cpp
@@ -0,0 +1,297 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#if defined(_MSC_VER)
+ #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned
+#endif
+
+#if defined(__APPLE__)
+ #include <mach/thread_act.h>
+ #include <mach/mach_init.h>
+#endif
+
+#include "thread.h"
+#include <fstream>
+
+namespace oidn {
+
+#if defined(_WIN32)
+
+ // --------------------------------------------------------------------------
+ // ThreadAffinity - Windows
+ // --------------------------------------------------------------------------
+
+ ThreadAffinity::ThreadAffinity(int numThreadsPerCore, int verbose)
+ : Verbose(verbose)
+ {
+ HMODULE hLib = GetModuleHandle(TEXT("kernel32"));
+ pGetLogicalProcessorInformationEx = (GetLogicalProcessorInformationExFunc)GetProcAddress(hLib, "GetLogicalProcessorInformationEx");
+ pSetThreadGroupAffinity = (SetThreadGroupAffinityFunc)GetProcAddress(hLib, "SetThreadGroupAffinity");
+
+ if (pGetLogicalProcessorInformationEx && pSetThreadGroupAffinity)
+ {
+ // Get logical processor information
+ PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX buffer = nullptr;
+ DWORD bufferSize = 0;
+
+ // First call the function with an empty buffer to get the required buffer size
+ BOOL result = pGetLogicalProcessorInformationEx(RelationProcessorCore, buffer, &bufferSize);
+ if (result || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ OIDN_WARNING("GetLogicalProcessorInformationEx failed");
+ return;
+ }
+
+ // Allocate the buffer
+ buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)malloc(bufferSize);
+ if (!buffer)
+ {
+ OIDN_WARNING("SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX allocation failed");
+ return;
+ }
+
+ // Call again the function but now with the properly sized buffer
+ result = pGetLogicalProcessorInformationEx(RelationProcessorCore, buffer, &bufferSize);
+ if (!result)
+ {
+ OIDN_WARNING("GetLogicalProcessorInformationEx failed");
+ free(buffer);
+ return;
+ }
+
+ // Iterate over the logical processor information structures
+ // There should be one structure for each physical core
+ char* ptr = (char*)buffer;
+ while (ptr < (char*)buffer + bufferSize)
+ {
+ PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX item = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)ptr;
+ if (item->Relationship == RelationProcessorCore && item->Processor.GroupCount > 0)
+ {
+ // Iterate over the groups
+ int numThreads = 0;
+ for (int group = 0; (group < item->Processor.GroupCount) && (numThreads < numThreadsPerCore); ++group)
+ {
+ GROUP_AFFINITY coreAffinity = item->Processor.GroupMask[group];
+ while ((coreAffinity.Mask != 0) && (numThreads < numThreadsPerCore))
+ {
+ // Extract the next set bit/thread from the mask
+ GROUP_AFFINITY threadAffinity = coreAffinity;
+ threadAffinity.Mask = threadAffinity.Mask & -threadAffinity.Mask;
+
+ // Push the affinity for this thread
+ affinities.push_back(threadAffinity);
+ oldAffinities.push_back(threadAffinity);
+ numThreads++;
+
+ // Remove this bit/thread from the mask
+ coreAffinity.Mask ^= threadAffinity.Mask;
+ }
+ }
+ }
+
+ // Next structure
+ ptr += item->Size;
+ }
+
+ // Free the buffer
+ free(buffer);
+ }
+ }
+
+ void ThreadAffinity::set(int threadIndex)
+ {
+ if (threadIndex >= (int)affinities.size())
+ return;
+
+ // Save the current affinity and set the new one
+ const HANDLE thread = GetCurrentThread();
+ if (!pSetThreadGroupAffinity(thread, &affinities[threadIndex], &oldAffinities[threadIndex]))
+ OIDN_WARNING("SetThreadGroupAffinity failed");
+ }
+
+ void ThreadAffinity::restore(int threadIndex)
+ {
+ if (threadIndex >= (int)affinities.size())
+ return;
+
+ // Restore the original affinity
+ const HANDLE thread = GetCurrentThread();
+ if (!pSetThreadGroupAffinity(thread, &oldAffinities[threadIndex], nullptr))
+ OIDN_WARNING("SetThreadGroupAffinity failed");
+ }
+
+#elif defined(__linux__)
+
+ // --------------------------------------------------------------------------
+ // ThreadAffinity - Linux
+ // --------------------------------------------------------------------------
+
+ ThreadAffinity::ThreadAffinity(int numThreadsPerCore, int verbose)
+ : Verbose(verbose)
+ {
+ std::vector<int> threadIds;
+
+ // Parse the thread/CPU topology
+ for (int cpuId = 0; ; cpuId++)
+ {
+ std::fstream fs;
+ std::string cpu = std::string("/sys/devices/system/cpu/cpu") + std::to_string(cpuId) + std::string("/topology/thread_siblings_list");
+ fs.open(cpu.c_str(), std::fstream::in);
+ if (fs.fail()) break;
+
+ int i;
+ int j = 0;
+ while ((j < numThreadsPerCore) && (fs >> i))
+ {
+ if (std::none_of(threadIds.begin(), threadIds.end(), [&](int id) { return id == i; }))
+ threadIds.push_back(i);
+
+ if (fs.peek() == ',')
+ fs.ignore();
+ j++;
+ }
+
+ fs.close();
+ }
+
+ #if 0
+ for (size_t i = 0; i < thread_ids.size(); ++i)
+ std::cout << "thread " << i << " -> " << thread_ids[i] << std::endl;
+ #endif
+
+ // Create the affinity structures
+ affinities.resize(threadIds.size());
+ oldAffinities.resize(threadIds.size());
+
+ for (size_t i = 0; i < threadIds.size(); ++i)
+ {
+ cpu_set_t affinity;
+ CPU_ZERO(&affinity);
+ CPU_SET(threadIds[i], &affinity);
+
+ affinities[i] = affinity;
+ oldAffinities[i] = affinity;
+ }
+ }
+
+ void ThreadAffinity::set(int threadIndex)
+ {
+ if (threadIndex >= (int)affinities.size())
+ return;
+
+ const pthread_t thread = pthread_self();
+
+ // Save the current affinity
+ if (pthread_getaffinity_np(thread, sizeof(cpu_set_t), &oldAffinities[threadIndex]) != 0)
+ {
+ OIDN_WARNING("pthread_getaffinity_np failed");
+ oldAffinities[threadIndex] = affinities[threadIndex];
+ return;
+ }
+
+ // Set the new affinity
+ if (pthread_setaffinity_np(thread, sizeof(cpu_set_t), &affinities[threadIndex]) != 0)
+ OIDN_WARNING("pthread_setaffinity_np failed");
+ }
+
+ void ThreadAffinity::restore(int threadIndex)
+ {
+ if (threadIndex >= (int)affinities.size())
+ return;
+
+ const pthread_t thread = pthread_self();
+
+ // Restore the original affinity
+ if (pthread_setaffinity_np(thread, sizeof(cpu_set_t), &oldAffinities[threadIndex]) != 0)
+ OIDN_WARNING("pthread_setaffinity_np failed");
+ }
+
+#elif defined(__APPLE__)
+
+ // --------------------------------------------------------------------------
+ // ThreadAffinity - macOS
+ // --------------------------------------------------------------------------
+
+ ThreadAffinity::ThreadAffinity(int numThreadsPerCore, int verbose)
+ : Verbose(verbose)
+ {
+ // Query the thread/CPU topology
+ int numPhysicalCpus;
+ int numLogicalCpus;
+
+ if (!getSysctl("hw.physicalcpu", numPhysicalCpus) || !getSysctl("hw.logicalcpu", numLogicalCpus))
+ {
+ OIDN_WARNING("sysctlbyname failed");
+ return;
+ }
+
+ if ((numLogicalCpus % numPhysicalCpus != 0) && (numThreadsPerCore > 1))
+ return; // this shouldn't happen
+ const int maxThreadsPerCore = numLogicalCpus / numPhysicalCpus;
+
+ // Create the affinity structures
+ // macOS doesn't support binding a thread to a specific core, but we can at least group threads which
+ // should be on the same core together
+ for (int core = 1; core <= numPhysicalCpus; ++core) // tags start from 1!
+ {
+ thread_affinity_policy affinity;
+ affinity.affinity_tag = core;
+
+ for (int thread = 0; thread < min(numThreadsPerCore, maxThreadsPerCore); ++thread)
+ {
+ affinities.push_back(affinity);
+ oldAffinities.push_back(affinity);
+ }
+ }
+ }
+
+ void ThreadAffinity::set(int threadIndex)
+ {
+ if (threadIndex >= (int)affinities.size())
+ return;
+
+ const auto thread = mach_thread_self();
+
+ // Save the current affinity
+ mach_msg_type_number_t policyCount = THREAD_AFFINITY_POLICY_COUNT;
+ boolean_t getDefault = FALSE;
+ if (thread_policy_get(thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&oldAffinities[threadIndex], &policyCount, &getDefault) != KERN_SUCCESS)
+ {
+ OIDN_WARNING("thread_policy_get failed");
+ oldAffinities[threadIndex] = affinities[threadIndex];
+ return;
+ }
+
+ // Set the new affinity
+ if (thread_policy_set(thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&affinities[threadIndex], THREAD_AFFINITY_POLICY_COUNT) != KERN_SUCCESS)
+ OIDN_WARNING("thread_policy_set failed");
+ }
+
+ void ThreadAffinity::restore(int threadIndex)
+ {
+ if (threadIndex >= (int)affinities.size())
+ return;
+
+ const auto thread = mach_thread_self();
+
+ // Restore the original affinity
+ if (thread_policy_set(thread, THREAD_AFFINITY_POLICY, (thread_policy_t)&oldAffinities[threadIndex], THREAD_AFFINITY_POLICY_COUNT) != KERN_SUCCESS)
+ OIDN_WARNING("thread_policy_set failed");
+ }
+
+#endif
+
+} // namespace oidn
diff --git a/thirdparty/oidn/common/thread.h b/thirdparty/oidn/common/thread.h
new file mode 100644
index 0000000000..2c731367da
--- /dev/null
+++ b/thirdparty/oidn/common/thread.h
@@ -0,0 +1,202 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "platform.h"
+
+#if !defined(_WIN32)
+ #include <pthread.h>
+ #include <sched.h>
+ #if defined(__APPLE__)
+ #include <mach/thread_policy.h>
+ #endif
+#endif
+
+#include <vector>
+#include <mutex>
+
+namespace oidn {
+
+ // --------------------------------------------------------------------------
+ // ThreadLocal
+ // --------------------------------------------------------------------------
+
+ // Wrapper which makes any variable thread-local
+ template<typename T>
+ class ThreadLocal : public Verbose
+ {
+ private:
+ #if defined(_WIN32)
+ DWORD key;
+ #else
+ pthread_key_t key;
+ #endif
+
+ std::vector<T*> instances;
+ std::mutex mutex;
+
+ public:
+ ThreadLocal(int verbose = 0)
+ : Verbose(verbose)
+ {
+ #if defined(_WIN32)
+ key = TlsAlloc();
+ if (key == TLS_OUT_OF_INDEXES)
+ OIDN_FATAL("TlsAlloc failed");
+ #else
+ if (pthread_key_create(&key, nullptr) != 0)
+ OIDN_FATAL("pthread_key_create failed");
+ #endif
+ }
+
+ ~ThreadLocal()
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ for (T* ptr : instances)
+ delete ptr;
+
+ #if defined(_WIN32)
+ if (!TlsFree(key))
+ OIDN_WARNING("TlsFree failed");
+ #else
+ if (pthread_key_delete(key) != 0)
+ OIDN_WARNING("pthread_key_delete failed");
+ #endif
+ }
+
+ T& get()
+ {
+ #if defined(_WIN32)
+ T* ptr = (T*)TlsGetValue(key);
+ #else
+ T* ptr = (T*)pthread_getspecific(key);
+ #endif
+
+ if (ptr)
+ return *ptr;
+
+ ptr = new T;
+ std::lock_guard<std::mutex> lock(mutex);
+ instances.push_back(ptr);
+
+ #if defined(_WIN32)
+ if (!TlsSetValue(key, ptr))
+ OIDN_FATAL("TlsSetValue failed");
+ #else
+ if (pthread_setspecific(key, ptr) != 0)
+ OIDN_FATAL("pthread_setspecific failed");
+ #endif
+
+ return *ptr;
+ }
+ };
+
+#if defined(_WIN32)
+
+ // --------------------------------------------------------------------------
+ // ThreadAffinity - Windows
+ // --------------------------------------------------------------------------
+
+ class ThreadAffinity : public Verbose
+ {
+ private:
+ typedef BOOL (WINAPI *GetLogicalProcessorInformationExFunc)(LOGICAL_PROCESSOR_RELATIONSHIP,
+ PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX,
+ PDWORD);
+
+ typedef BOOL (WINAPI *SetThreadGroupAffinityFunc)(HANDLE,
+ CONST GROUP_AFFINITY*,
+ PGROUP_AFFINITY);
+
+ GetLogicalProcessorInformationExFunc pGetLogicalProcessorInformationEx = nullptr;
+ SetThreadGroupAffinityFunc pSetThreadGroupAffinity = nullptr;
+
+ std::vector<GROUP_AFFINITY> affinities; // thread affinities
+ std::vector<GROUP_AFFINITY> oldAffinities; // original thread affinities
+
+ public:
+ ThreadAffinity(int numThreadsPerCore = INT_MAX, int verbose = 0);
+
+ int getNumThreads() const
+ {
+ return (int)affinities.size();
+ }
+
+ // Sets the affinity (0..numThreads-1) of the thread after saving the current affinity
+ void set(int threadIndex);
+
+ // Restores the affinity of the thread
+ void restore(int threadIndex);
+ };
+
+#elif defined(__linux__)
+
+ // --------------------------------------------------------------------------
+ // ThreadAffinity - Linux
+ // --------------------------------------------------------------------------
+
+ class ThreadAffinity : public Verbose
+ {
+ private:
+ std::vector<cpu_set_t> affinities; // thread affinities
+ std::vector<cpu_set_t> oldAffinities; // original thread affinities
+
+ public:
+ ThreadAffinity(int numThreadsPerCore = INT_MAX, int verbose = 0);
+
+ int getNumThreads() const
+ {
+ return (int)affinities.size();
+ }
+
+ // Sets the affinity (0..numThreads-1) of the thread after saving the current affinity
+ void set(int threadIndex);
+
+ // Restores the affinity of the thread
+ void restore(int threadIndex);
+ };
+
+#elif defined(__APPLE__)
+
+ // --------------------------------------------------------------------------
+ // ThreadAffinity - macOS
+ // --------------------------------------------------------------------------
+
+ class ThreadAffinity : public Verbose
+ {
+ private:
+ std::vector<thread_affinity_policy> affinities; // thread affinities
+ std::vector<thread_affinity_policy> oldAffinities; // original thread affinities
+
+ public:
+ ThreadAffinity(int numThreadsPerCore = INT_MAX, int verbose = 0);
+
+ int getNumThreads() const
+ {
+ return (int)affinities.size();
+ }
+
+ // Sets the affinity (0..numThreads-1) of the thread after saving the current affinity
+ void set(int threadIndex);
+
+ // Restores the affinity of the thread
+ void restore(int threadIndex);
+ };
+
+#endif
+
+} // namespace oidn
diff --git a/thirdparty/oidn/common/timer.h b/thirdparty/oidn/common/timer.h
new file mode 100644
index 0000000000..62aaaa1c33
--- /dev/null
+++ b/thirdparty/oidn/common/timer.h
@@ -0,0 +1,49 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "platform.h"
+#include <chrono>
+
+namespace oidn {
+
+ class Timer
+ {
+ private:
+ using clock = std::chrono::high_resolution_clock;
+
+ std::chrono::time_point<clock> start;
+
+ public:
+ Timer()
+ {
+ reset();
+ }
+
+ void reset()
+ {
+ start = clock::now();
+ }
+
+ double query() const
+ {
+ auto end = clock::now();
+ return std::chrono::duration_cast<std::chrono::duration<double>>(end - start).count();
+ }
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/api.cpp b/thirdparty/oidn/core/api.cpp
new file mode 100644
index 0000000000..7353fe4e25
--- /dev/null
+++ b/thirdparty/oidn/core/api.cpp
@@ -0,0 +1,408 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#ifdef _WIN32
+# define OIDN_API extern "C" __declspec(dllexport)
+#else
+# define OIDN_API extern "C" __attribute__ ((visibility ("default")))
+#endif
+
+// Locks the device that owns the specified object
+// Use *only* inside OIDN_TRY/CATCH!
+#define OIDN_LOCK(obj) \
+ std::lock_guard<std::mutex> lock(obj->getDevice()->getMutex());
+
+// Try/catch for converting exceptions to errors
+#define OIDN_TRY \
+ try {
+
+#define OIDN_CATCH(obj) \
+ } catch (Exception& e) { \
+ Device::setError(obj ? obj->getDevice() : nullptr, e.code(), e.what()); \
+ } catch (std::bad_alloc&) { \
+ Device::setError(obj ? obj->getDevice() : nullptr, Error::OutOfMemory, "out of memory"); \
+ } catch (mkldnn::error& e) { \
+ if (e.status == mkldnn_out_of_memory) \
+ Device::setError(obj ? obj->getDevice() : nullptr, Error::OutOfMemory, "out of memory"); \
+ else \
+ Device::setError(obj ? obj->getDevice() : nullptr, Error::Unknown, e.message); \
+ } catch (std::exception& e) { \
+ Device::setError(obj ? obj->getDevice() : nullptr, Error::Unknown, e.what()); \
+ } catch (...) { \
+ Device::setError(obj ? obj->getDevice() : nullptr, Error::Unknown, "unknown exception caught"); \
+ }
+
+#include "device.h"
+#include "filter.h"
+#include <mutex>
+
+namespace oidn {
+
+ namespace
+ {
+ __forceinline void checkHandle(void* handle)
+ {
+ if (handle == nullptr)
+ throw Exception(Error::InvalidArgument, "invalid handle");
+ }
+
+ template<typename T>
+ __forceinline void retainObject(T* obj)
+ {
+ if (obj)
+ {
+ obj->incRef();
+ }
+ else
+ {
+ OIDN_TRY
+ checkHandle(obj);
+ OIDN_CATCH(obj)
+ }
+ }
+
+ template<typename T>
+ __forceinline void releaseObject(T* obj)
+ {
+ if (obj == nullptr || obj->decRefKeep() == 0)
+ {
+ OIDN_TRY
+ checkHandle(obj);
+ OIDN_LOCK(obj);
+ obj->destroy();
+ OIDN_CATCH(obj)
+ }
+ }
+
+ template<>
+ __forceinline void releaseObject(Device* obj)
+ {
+ if (obj == nullptr || obj->decRefKeep() == 0)
+ {
+ OIDN_TRY
+ checkHandle(obj);
+ // Do NOT lock the device because it owns the mutex
+ obj->destroy();
+ OIDN_CATCH(obj)
+ }
+ }
+ }
+
+ OIDN_API OIDNDevice oidnNewDevice(OIDNDeviceType type)
+ {
+ Ref<Device> device = nullptr;
+ OIDN_TRY
+ if (type == OIDN_DEVICE_TYPE_CPU || type == OIDN_DEVICE_TYPE_DEFAULT)
+ device = makeRef<Device>();
+ else
+ throw Exception(Error::InvalidArgument, "invalid device type");
+ OIDN_CATCH(device)
+ return (OIDNDevice)device.detach();
+ }
+
+ OIDN_API void oidnRetainDevice(OIDNDevice hDevice)
+ {
+ Device* device = (Device*)hDevice;
+ retainObject(device);
+ }
+
+ OIDN_API void oidnReleaseDevice(OIDNDevice hDevice)
+ {
+ Device* device = (Device*)hDevice;
+ releaseObject(device);
+ }
+
+ OIDN_API void oidnSetDevice1b(OIDNDevice hDevice, const char* name, bool value)
+ {
+ Device* device = (Device*)hDevice;
+ OIDN_TRY
+ checkHandle(hDevice);
+ OIDN_LOCK(device);
+ device->set1i(name, value);
+ OIDN_CATCH(device)
+ }
+
+ OIDN_API void oidnSetDevice1i(OIDNDevice hDevice, const char* name, int value)
+ {
+ Device* device = (Device*)hDevice;
+ OIDN_TRY
+ checkHandle(hDevice);
+ OIDN_LOCK(device);
+ device->set1i(name, value);
+ OIDN_CATCH(device)
+ }
+
+ OIDN_API bool oidnGetDevice1b(OIDNDevice hDevice, const char* name)
+ {
+ Device* device = (Device*)hDevice;
+ OIDN_TRY
+ checkHandle(hDevice);
+ OIDN_LOCK(device);
+ return device->get1i(name);
+ OIDN_CATCH(device)
+ return false;
+ }
+
+ OIDN_API int oidnGetDevice1i(OIDNDevice hDevice, const char* name)
+ {
+ Device* device = (Device*)hDevice;
+ OIDN_TRY
+ checkHandle(hDevice);
+ OIDN_LOCK(device);
+ return device->get1i(name);
+ OIDN_CATCH(device)
+ return 0;
+ }
+
+ OIDN_API void oidnSetDeviceErrorFunction(OIDNDevice hDevice, OIDNErrorFunction func, void* userPtr)
+ {
+ Device* device = (Device*)hDevice;
+ OIDN_TRY
+ checkHandle(hDevice);
+ OIDN_LOCK(device);
+ device->setErrorFunction((ErrorFunction)func, userPtr);
+ OIDN_CATCH(device)
+ }
+
+ OIDN_API OIDNError oidnGetDeviceError(OIDNDevice hDevice, const char** outMessage)
+ {
+ Device* device = (Device*)hDevice;
+ OIDN_TRY
+ return (OIDNError)Device::getError(device, outMessage);
+ OIDN_CATCH(device)
+ if (outMessage) *outMessage = "";
+ return OIDN_ERROR_UNKNOWN;
+ }
+
+ OIDN_API void oidnCommitDevice(OIDNDevice hDevice)
+ {
+ Device* device = (Device*)hDevice;
+ OIDN_TRY
+ checkHandle(hDevice);
+ OIDN_LOCK(device);
+ device->commit();
+ OIDN_CATCH(device)
+ }
+
+ OIDN_API OIDNBuffer oidnNewBuffer(OIDNDevice hDevice, size_t byteSize)
+ {
+ Device* device = (Device*)hDevice;
+ OIDN_TRY
+ checkHandle(hDevice);
+ OIDN_LOCK(device);
+ Ref<Buffer> buffer = device->newBuffer(byteSize);
+ return (OIDNBuffer)buffer.detach();
+ OIDN_CATCH(device)
+ return nullptr;
+ }
+
+ OIDN_API OIDNBuffer oidnNewSharedBuffer(OIDNDevice hDevice, void* ptr, size_t byteSize)
+ {
+ Device* device = (Device*)hDevice;
+ OIDN_TRY
+ checkHandle(hDevice);
+ OIDN_LOCK(device);
+ Ref<Buffer> buffer = device->newBuffer(ptr, byteSize);
+ return (OIDNBuffer)buffer.detach();
+ OIDN_CATCH(device)
+ return nullptr;
+ }
+
+ OIDN_API void oidnRetainBuffer(OIDNBuffer hBuffer)
+ {
+ Buffer* buffer = (Buffer*)hBuffer;
+ retainObject(buffer);
+ }
+
+ OIDN_API void oidnReleaseBuffer(OIDNBuffer hBuffer)
+ {
+ Buffer* buffer = (Buffer*)hBuffer;
+ releaseObject(buffer);
+ }
+
+ OIDN_API void* oidnMapBuffer(OIDNBuffer hBuffer, OIDNAccess access, size_t byteOffset, size_t byteSize)
+ {
+ Buffer* buffer = (Buffer*)hBuffer;
+ OIDN_TRY
+ checkHandle(hBuffer);
+ OIDN_LOCK(buffer);
+ return buffer->map(byteOffset, byteSize);
+ OIDN_CATCH(buffer)
+ return nullptr;
+ }
+
+ OIDN_API void oidnUnmapBuffer(OIDNBuffer hBuffer, void* mappedPtr)
+ {
+ Buffer* buffer = (Buffer*)hBuffer;
+ OIDN_TRY
+ checkHandle(hBuffer);
+ OIDN_LOCK(buffer);
+ return buffer->unmap(mappedPtr);
+ OIDN_CATCH(buffer)
+ }
+
+ OIDN_API OIDNFilter oidnNewFilter(OIDNDevice hDevice, const char* type)
+ {
+ Device* device = (Device*)hDevice;
+ OIDN_TRY
+ checkHandle(hDevice);
+ OIDN_LOCK(device);
+ Ref<Filter> filter = device->newFilter(type);
+ return (OIDNFilter)filter.detach();
+ OIDN_CATCH(device)
+ return nullptr;
+ }
+
+ OIDN_API void oidnRetainFilter(OIDNFilter hFilter)
+ {
+ Filter* filter = (Filter*)hFilter;
+ retainObject(filter);
+ }
+
+ OIDN_API void oidnReleaseFilter(OIDNFilter hFilter)
+ {
+ Filter* filter = (Filter*)hFilter;
+ releaseObject(filter);
+ }
+
+ OIDN_API void oidnSetFilterImage(OIDNFilter hFilter, const char* name,
+ OIDNBuffer hBuffer, OIDNFormat format,
+ size_t width, size_t height,
+ size_t byteOffset,
+ size_t bytePixelStride, size_t byteRowStride)
+ {
+ Filter* filter = (Filter*)hFilter;
+ OIDN_TRY
+ checkHandle(hFilter);
+ checkHandle(hBuffer);
+ OIDN_LOCK(filter);
+ Ref<Buffer> buffer = (Buffer*)hBuffer;
+ if (buffer->getDevice() != filter->getDevice())
+ throw Exception(Error::InvalidArgument, "the specified objects are bound to different devices");
+ Image data(buffer, (Format)format, (int)width, (int)height, byteOffset, bytePixelStride, byteRowStride);
+ filter->setImage(name, data);
+ OIDN_CATCH(filter)
+ }
+
+ OIDN_API void oidnSetSharedFilterImage(OIDNFilter hFilter, const char* name,
+ void* ptr, OIDNFormat format,
+ size_t width, size_t height,
+ size_t byteOffset,
+ size_t bytePixelStride, size_t byteRowStride)
+ {
+ Filter* filter = (Filter*)hFilter;
+ OIDN_TRY
+ checkHandle(hFilter);
+ OIDN_LOCK(filter);
+ Image data(ptr, (Format)format, (int)width, (int)height, byteOffset, bytePixelStride, byteRowStride);
+ filter->setImage(name, data);
+ OIDN_CATCH(filter)
+ }
+
+ OIDN_API void oidnSetFilter1b(OIDNFilter hFilter, const char* name, bool value)
+ {
+ Filter* filter = (Filter*)hFilter;
+ OIDN_TRY
+ checkHandle(hFilter);
+ OIDN_LOCK(filter);
+ filter->set1i(name, int(value));
+ OIDN_CATCH(filter)
+ }
+
+ OIDN_API bool oidnGetFilter1b(OIDNFilter hFilter, const char* name)
+ {
+ Filter* filter = (Filter*)hFilter;
+ OIDN_TRY
+ checkHandle(hFilter);
+ OIDN_LOCK(filter);
+ return filter->get1i(name);
+ OIDN_CATCH(filter)
+ return false;
+ }
+
+ OIDN_API void oidnSetFilter1i(OIDNFilter hFilter, const char* name, int value)
+ {
+ Filter* filter = (Filter*)hFilter;
+ OIDN_TRY
+ checkHandle(hFilter);
+ OIDN_LOCK(filter);
+ filter->set1i(name, value);
+ OIDN_CATCH(filter)
+ }
+
+ OIDN_API int oidnGetFilter1i(OIDNFilter hFilter, const char* name)
+ {
+ Filter* filter = (Filter*)hFilter;
+ OIDN_TRY
+ checkHandle(hFilter);
+ OIDN_LOCK(filter);
+ return filter->get1i(name);
+ OIDN_CATCH(filter)
+ return 0;
+ }
+
+ OIDN_API void oidnSetFilter1f(OIDNFilter hFilter, const char* name, float value)
+ {
+ Filter* filter = (Filter*)hFilter;
+ OIDN_TRY
+ checkHandle(hFilter);
+ OIDN_LOCK(filter);
+ filter->set1f(name, value);
+ OIDN_CATCH(filter)
+ }
+
+ OIDN_API float oidnGetFilter1f(OIDNFilter hFilter, const char* name)
+ {
+ Filter* filter = (Filter*)hFilter;
+ OIDN_TRY
+ checkHandle(hFilter);
+ OIDN_LOCK(filter);
+ return filter->get1f(name);
+ OIDN_CATCH(filter)
+ return 0;
+ }
+
+ OIDN_API void oidnSetFilterProgressMonitorFunction(OIDNFilter hFilter, OIDNProgressMonitorFunction func, void* userPtr)
+ {
+ Filter* filter = (Filter*)hFilter;
+ OIDN_TRY
+ checkHandle(hFilter);
+ OIDN_LOCK(filter);
+ filter->setProgressMonitorFunction(func, userPtr);
+ OIDN_CATCH(filter)
+ }
+
+ OIDN_API void oidnCommitFilter(OIDNFilter hFilter)
+ {
+ Filter* filter = (Filter*)hFilter;
+ OIDN_TRY
+ checkHandle(hFilter);
+ OIDN_LOCK(filter);
+ filter->commit();
+ OIDN_CATCH(filter)
+ }
+
+ OIDN_API void oidnExecuteFilter(OIDNFilter hFilter)
+ {
+ Filter* filter = (Filter*)hFilter;
+ OIDN_TRY
+ checkHandle(hFilter);
+ OIDN_LOCK(filter);
+ filter->execute();
+ OIDN_CATCH(filter)
+ }
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/autoencoder.cpp b/thirdparty/oidn/core/autoencoder.cpp
new file mode 100644
index 0000000000..8ae2421fa6
--- /dev/null
+++ b/thirdparty/oidn/core/autoencoder.cpp
@@ -0,0 +1,519 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#include "autoencoder.h"
+
+namespace oidn {
+
+ // --------------------------------------------------------------------------
+ // AutoencoderFilter
+ // --------------------------------------------------------------------------
+
+ AutoencoderFilter::AutoencoderFilter(const Ref<Device>& device)
+ : Filter(device)
+ {
+ }
+
+ void AutoencoderFilter::setImage(const std::string& name, const Image& data)
+ {
+ if (name == "color")
+ color = data;
+ else if (name == "albedo")
+ albedo = data;
+ else if (name == "normal")
+ normal = data;
+ else if (name == "output")
+ output = data;
+
+ dirty = true;
+ }
+
+ void AutoencoderFilter::set1i(const std::string& name, int value)
+ {
+ if (name == "hdr")
+ hdr = value;
+ else if (name == "srgb")
+ srgb = value;
+ else if (name == "maxMemoryMB")
+ maxMemoryMB = value;
+
+ dirty = true;
+ }
+
+ int AutoencoderFilter::get1i(const std::string& name)
+ {
+ if (name == "hdr")
+ return hdr;
+ else if (name == "srgb")
+ return srgb;
+ else if (name == "maxMemoryMB")
+ return maxMemoryMB;
+ else if (name == "alignment")
+ return alignment;
+ else if (name == "overlap")
+ return overlap;
+ else
+ throw Exception(Error::InvalidArgument, "invalid parameter");
+ }
+
+ void AutoencoderFilter::set1f(const std::string& name, float value)
+ {
+ if (name == "hdrScale")
+ hdrScale = value;
+
+ dirty = true;
+ }
+
+ float AutoencoderFilter::get1f(const std::string& name)
+ {
+ if (name == "hdrScale")
+ return hdrScale;
+ else
+ throw Exception(Error::InvalidArgument, "invalid parameter");
+ }
+
+ void AutoencoderFilter::commit()
+ {
+ if (!dirty)
+ return;
+
+ {
+ if (mayiuse(avx512_common))
+ net = buildNet<16>();
+ else
+ net = buildNet<8>();
+ }
+
+ dirty = false;
+ }
+
+ void AutoencoderFilter::execute()
+ {
+ if (dirty)
+ throw Exception(Error::InvalidOperation, "changes to the filter are not committed");
+
+ if (!net)
+ return;
+
+ {
+ Progress progress;
+ progress.func = progressFunc;
+ progress.userPtr = progressUserPtr;
+ progress.taskCount = tileCountH * tileCountW;
+
+ // Iterate over the tiles
+ int tileIndex = 0;
+
+ for (int i = 0; i < tileCountH; ++i)
+ {
+ const int h = i * (tileH - 2*overlap); // input tile position (including overlap)
+ const int overlapBeginH = i > 0 ? overlap : 0; // overlap on the top
+ const int overlapEndH = i < tileCountH-1 ? overlap : 0; // overlap on the bottom
+ const int tileH1 = min(H - h, tileH); // input tile size (including overlap)
+ const int tileH2 = tileH1 - overlapBeginH - overlapEndH; // output tile size
+ const int alignOffsetH = tileH - roundUp(tileH1, alignment); // align to the bottom in the tile buffer
+
+ for (int j = 0; j < tileCountW; ++j)
+ {
+ const int w = j * (tileW - 2*overlap); // input tile position (including overlap)
+ const int overlapBeginW = j > 0 ? overlap : 0; // overlap on the left
+ const int overlapEndW = j < tileCountW-1 ? overlap : 0; // overlap on the right
+ const int tileW1 = min(W - w, tileW); // input tile size (including overlap)
+ const int tileW2 = tileW1 - overlapBeginW - overlapEndW; // output tile size
+ const int alignOffsetW = tileW - roundUp(tileW1, alignment); // align to the right in the tile buffer
+
+ // Set the input tile
+ inputReorder->setTile(h, w,
+ alignOffsetH, alignOffsetW,
+ tileH1, tileW1);
+
+ // Set the output tile
+ outputReorder->setTile(alignOffsetH + overlapBeginH, alignOffsetW + overlapBeginW,
+ h + overlapBeginH, w + overlapBeginW,
+ tileH2, tileW2);
+
+ //printf("Tile: %d %d -> %d %d\n", w+overlapBeginW, h+overlapBeginH, w+overlapBeginW+tileW2, h+overlapBeginH+tileH2);
+
+ // Denoise the tile
+ net->execute(progress, tileIndex);
+
+ // Next tile
+ tileIndex++;
+ }
+ }
+ }
+ }
+
+ void AutoencoderFilter::computeTileSize()
+ {
+ const int minTileSize = 3*overlap;
+ const int estimatedBytesPerPixel = mayiuse(avx512_common) ? estimatedBytesPerPixel16 : estimatedBytesPerPixel8;
+ const int64_t maxTilePixels = (int64_t(maxMemoryMB)*1024*1024 - estimatedBytesBase) / estimatedBytesPerPixel;
+
+ tileCountH = 1;
+ tileCountW = 1;
+ tileH = roundUp(H, alignment);
+ tileW = roundUp(W, alignment);
+
+ // Divide the image into tiles until the tile size gets below the threshold
+ while (int64_t(tileH) * tileW > maxTilePixels)
+ {
+ if (tileH > minTileSize && tileH > tileW)
+ {
+ tileCountH++;
+ tileH = max(roundUp(ceilDiv(H - 2*overlap, tileCountH), alignment) + 2*overlap, minTileSize);
+ }
+ else if (tileW > minTileSize)
+ {
+ tileCountW++;
+ tileW = max(roundUp(ceilDiv(W - 2*overlap, tileCountW), alignment) + 2*overlap, minTileSize);
+ }
+ else
+ break;
+ }
+
+ // Compute the final number of tiles
+ tileCountH = (H > tileH) ? ceilDiv(H - 2*overlap, tileH - 2*overlap) : 1;
+ tileCountW = (W > tileW) ? ceilDiv(W - 2*overlap, tileW - 2*overlap) : 1;
+
+ if (device->isVerbose(2))
+ {
+ std::cout << "Tile size : " << tileW << "x" << tileH << std::endl;
+ std::cout << "Tile count: " << tileCountW << "x" << tileCountH << std::endl;
+ }
+ }
+
+ template<int K>
+ std::shared_ptr<Executable> AutoencoderFilter::buildNet()
+ {
+ H = color.height;
+ W = color.width;
+
+ // Configure the network
+ int inputC;
+ void* weightPtr;
+
+ if (srgb && hdr)
+ throw Exception(Error::InvalidOperation, "srgb and hdr modes cannot be enabled at the same time");
+
+ if (color && !albedo && !normal && weightData.hdr)
+ {
+ inputC = 3;
+ weightPtr = hdr ? weightData.hdr : weightData.ldr;
+ }
+ else if (color && albedo && !normal && weightData.hdr_alb)
+ {
+ inputC = 6;
+ weightPtr = hdr ? weightData.hdr_alb : weightData.ldr_alb;
+ }
+ else if (color && albedo && normal && weightData.hdr_alb_nrm)
+ {
+ inputC = 9;
+ weightPtr = hdr ? weightData.hdr_alb_nrm : weightData.ldr_alb_nrm;
+ }
+ else
+ {
+ throw Exception(Error::InvalidOperation, "unsupported combination of input features");
+ }
+
+ if (!output)
+ throw Exception(Error::InvalidOperation, "output image not specified");
+
+ if ((color.format != Format::Float3)
+ || (albedo && albedo.format != Format::Float3)
+ || (normal && normal.format != Format::Float3)
+ || (output.format != Format::Float3))
+ throw Exception(Error::InvalidOperation, "unsupported image format");
+
+ if ((albedo && (albedo.width != W || albedo.height != H))
+ || (normal && (normal.width != W || normal.height != H))
+ || (output.width != W || output.height != H))
+ throw Exception(Error::InvalidOperation, "image size mismatch");
+
+ // Compute the tile size
+ computeTileSize();
+
+ // If the image size is zero, there is nothing else to do
+ if (H <= 0 || W <= 0)
+ return nullptr;
+
+ // Parse the weights
+ const auto weightMap = parseTensors(weightPtr);
+
+ // Create the network
+ std::shared_ptr<Network<K>> net = std::make_shared<Network<K>>(device, weightMap);
+
+ // Compute the tensor sizes
+ const auto inputDims = memory::dims({1, inputC, tileH, tileW});
+ const auto inputReorderDims = net->getInputReorderDims(inputDims, alignment); //-> concat0
+
+ const auto conv1Dims = net->getConvDims("conv1", inputReorderDims); //-> temp0
+ const auto conv1bDims = net->getConvDims("conv1b", conv1Dims); //-> temp1
+ const auto pool1Dims = net->getPoolDims(conv1bDims); //-> concat1
+ const auto conv2Dims = net->getConvDims("conv2", pool1Dims); //-> temp0
+ const auto pool2Dims = net->getPoolDims(conv2Dims); //-> concat2
+ const auto conv3Dims = net->getConvDims("conv3", pool2Dims); //-> temp0
+ const auto pool3Dims = net->getPoolDims(conv3Dims); //-> concat3
+ const auto conv4Dims = net->getConvDims("conv4", pool3Dims); //-> temp0
+ const auto pool4Dims = net->getPoolDims(conv4Dims); //-> concat4
+ const auto conv5Dims = net->getConvDims("conv5", pool4Dims); //-> temp0
+ const auto pool5Dims = net->getPoolDims(conv5Dims); //-> temp1
+ const auto upsample4Dims = net->getUpsampleDims(pool5Dims); //-> concat4
+ const auto concat4Dims = net->getConcatDims(upsample4Dims, pool4Dims);
+ const auto conv6Dims = net->getConvDims("conv6", concat4Dims); //-> temp0
+ const auto conv6bDims = net->getConvDims("conv6b", conv6Dims); //-> temp1
+ const auto upsample3Dims = net->getUpsampleDims(conv6bDims); //-> concat3
+ const auto concat3Dims = net->getConcatDims(upsample3Dims, pool3Dims);
+ const auto conv7Dims = net->getConvDims("conv7", concat3Dims); //-> temp0
+ const auto conv7bDims = net->getConvDims("conv7b", conv7Dims); //-> temp1
+ const auto upsample2Dims = net->getUpsampleDims(conv7bDims); //-> concat2
+ const auto concat2Dims = net->getConcatDims(upsample2Dims, pool2Dims);
+ const auto conv8Dims = net->getConvDims("conv8", concat2Dims); //-> temp0
+ const auto conv8bDims = net->getConvDims("conv8b", conv8Dims); //-> temp1
+ const auto upsample1Dims = net->getUpsampleDims(conv8bDims); //-> concat1
+ const auto concat1Dims = net->getConcatDims(upsample1Dims, pool1Dims);
+ const auto conv9Dims = net->getConvDims("conv9", concat1Dims); //-> temp0
+ const auto conv9bDims = net->getConvDims("conv9b", conv9Dims); //-> temp1
+ const auto upsample0Dims = net->getUpsampleDims(conv9bDims); //-> concat0
+ const auto concat0Dims = net->getConcatDims(upsample0Dims, inputReorderDims);
+ const auto conv10Dims = net->getConvDims("conv10", concat0Dims); //-> temp0
+ const auto conv10bDims = net->getConvDims("conv10b", conv10Dims); //-> temp1
+ const auto conv11Dims = net->getConvDims("conv11", conv10bDims); //-> temp0
+
+ const auto outputDims = memory::dims({1, 3, tileH, tileW});
+
+ // Allocate two temporary ping-pong buffers to decrease memory usage
+ const auto temp0Dims = getMaxTensorDims({
+ conv1Dims,
+ conv2Dims,
+ conv3Dims,
+ conv4Dims,
+ conv5Dims,
+ conv6Dims,
+ conv7Dims,
+ conv8Dims,
+ conv9Dims,
+ conv10Dims,
+ conv11Dims
+ });
+
+ const auto temp1Dims = getMaxTensorDims({
+ conv1bDims,
+ pool5Dims,
+ conv6bDims,
+ conv7bDims,
+ conv8bDims,
+ conv9bDims,
+ conv10bDims,
+ });
+
+ auto temp0 = net->allocTensor(temp0Dims);
+ auto temp1 = net->allocTensor(temp1Dims);
+
+ // Allocate enough memory to hold the concat outputs. Then use the first
+ // half to hold the previous conv output and the second half to hold the
+ // pool/orig image output. This works because everything is C dimension
+ // outermost, padded to K floats, and all the concats are on the C dimension.
+ auto concat0Dst = net->allocTensor(concat0Dims);
+ auto concat1Dst = net->allocTensor(concat1Dims);
+ auto concat2Dst = net->allocTensor(concat2Dims);
+ auto concat3Dst = net->allocTensor(concat3Dims);
+ auto concat4Dst = net->allocTensor(concat4Dims);
+
+ // Transfer function
+ std::shared_ptr<TransferFunction> transferFunc = makeTransferFunc();
+
+ // Autoexposure
+ if (auto tf = std::dynamic_pointer_cast<HDRTransferFunction>(transferFunc))
+ {
+ if (isnan(hdrScale))
+ net->addAutoexposure(color, tf);
+ else
+ tf->setExposure(hdrScale);
+ }
+
+ // Input reorder
+ auto inputReorderDst = net->castTensor(inputReorderDims, concat0Dst, upsample0Dims);
+ inputReorder = net->addInputReorder(color, albedo, normal,
+ transferFunc,
+ alignment, inputReorderDst);
+
+ // conv1
+ auto conv1 = net->addConv("conv1", inputReorder->getDst(), temp0);
+
+ // conv1b
+ auto conv1b = net->addConv("conv1b", conv1->getDst(), temp1);
+
+ // pool1
+ // Adjust pointer for pool1 to eliminate concat1
+ auto pool1Dst = net->castTensor(pool1Dims, concat1Dst, upsample1Dims);
+ auto pool1 = net->addPool(conv1b->getDst(), pool1Dst);
+
+ // conv2
+ auto conv2 = net->addConv("conv2", pool1->getDst(), temp0);
+
+ // pool2
+ // Adjust pointer for pool2 to eliminate concat2
+ auto pool2Dst = net->castTensor(pool2Dims, concat2Dst, upsample2Dims);
+ auto pool2 = net->addPool(conv2->getDst(), pool2Dst);
+
+ // conv3
+ auto conv3 = net->addConv("conv3", pool2->getDst(), temp0);
+
+ // pool3
+ // Adjust pointer for pool3 to eliminate concat3
+ auto pool3Dst = net->castTensor(pool3Dims, concat3Dst, upsample3Dims);
+ auto pool3 = net->addPool(conv3->getDst(), pool3Dst);
+
+ // conv4
+ auto conv4 = net->addConv("conv4", pool3->getDst(), temp0);
+
+ // pool4
+ // Adjust pointer for pool4 to eliminate concat4
+ auto pool4Dst = net->castTensor(pool4Dims, concat4Dst, upsample4Dims);
+ auto pool4 = net->addPool(conv4->getDst(), pool4Dst);
+
+ // conv5
+ auto conv5 = net->addConv("conv5", pool4->getDst(), temp0);
+
+ // pool5
+ auto pool5 = net->addPool(conv5->getDst(), temp1);
+
+ // upsample4
+ auto upsample4Dst = net->castTensor(upsample4Dims, concat4Dst);
+ auto upsample4 = net->addUpsample(pool5->getDst(), upsample4Dst);
+
+ // conv6
+ auto conv6 = net->addConv("conv6", concat4Dst, temp0);
+
+ // conv6b
+ auto conv6b = net->addConv("conv6b", conv6->getDst(), temp1);
+
+ // upsample3
+ auto upsample3Dst = net->castTensor(upsample3Dims, concat3Dst);
+ auto upsample3 = net->addUpsample(conv6b->getDst(), upsample3Dst);
+
+ // conv7
+ auto conv7 = net->addConv("conv7", concat3Dst, temp0);
+
+ // conv7b
+ auto conv7b = net->addConv("conv7b", conv7->getDst(), temp1);
+
+ // upsample2
+ auto upsample2Dst = net->castTensor(upsample2Dims, concat2Dst);
+ auto upsample2 = net->addUpsample(conv7b->getDst(), upsample2Dst);
+
+ // conv8
+ auto conv8 = net->addConv("conv8", concat2Dst, temp0);
+
+ // conv8b
+ auto conv8b = net->addConv("conv8b", conv8->getDst(), temp1);
+
+ // upsample1
+ auto upsample1Dst = net->castTensor(upsample1Dims, concat1Dst);
+ auto upsample1 = net->addUpsample(conv8b->getDst(), upsample1Dst);
+
+ // conv9
+ auto conv9 = net->addConv("conv9", concat1Dst, temp0);
+
+ // conv9b
+ auto conv9b = net->addConv("conv9b", conv9->getDst(), temp1);
+
+ // upsample0
+ auto upsample0Dst = net->castTensor(upsample0Dims, concat0Dst);
+ auto upsample0 = net->addUpsample(conv9b->getDst(), upsample0Dst);
+
+ // conv10
+ auto conv10 = net->addConv("conv10", concat0Dst, temp0);
+
+ // conv10b
+ auto conv10b = net->addConv("conv10b", conv10->getDst(), temp1);
+
+ // conv11
+ auto conv11 = net->addConv("conv11", conv10b->getDst(), temp0, false /* no relu */);
+
+ // Output reorder
+ outputReorder = net->addOutputReorder(conv11->getDst(), transferFunc, output);
+
+ net->finalize();
+ return net;
+ }
+
+ std::shared_ptr<TransferFunction> AutoencoderFilter::makeTransferFunc()
+ {
+ if (hdr)
+ return std::make_shared<PQXTransferFunction>();
+ else if (srgb)
+ return std::make_shared<LinearTransferFunction>();
+ else
+ return std::make_shared<GammaTransferFunction>();
+ }
+
+// Godot doesn't need Raytracing filters. Removing them saves space in the weights files.
+#if 0
+ // --------------------------------------------------------------------------
+ // RTFilter
+ // --------------------------------------------------------------------------
+
+ namespace weights
+ {
+ // LDR
+ extern unsigned char rt_ldr[]; // color
+ extern unsigned char rt_ldr_alb[]; // color, albedo
+ extern unsigned char rt_ldr_alb_nrm[]; // color, albedo, normal
+
+ // HDR
+ extern unsigned char rt_hdr[]; // color
+ extern unsigned char rt_hdr_alb[]; // color, albedo
+ extern unsigned char rt_hdr_alb_nrm[]; // color, albedo, normal
+ }
+
+ RTFilter::RTFilter(const Ref<Device>& device)
+ : AutoencoderFilter(device)
+ {
+ weightData.ldr = weights::rt_ldr;
+ weightData.ldr_alb = weights::rt_ldr_alb;
+ weightData.ldr_alb_nrm = weights::rt_ldr_alb_nrm;
+ weightData.hdr = weights::rt_hdr;
+ weightData.hdr_alb = weights::rt_hdr_alb;
+ weightData.hdr_alb_nrm = weights::rt_hdr_alb_nrm;
+ }
+#endif
+
+ // --------------------------------------------------------------------------
+ // RTLightmapFilter
+ // --------------------------------------------------------------------------
+
+ namespace weights
+ {
+ // HDR
+ extern unsigned char rtlightmap_hdr[]; // color
+ }
+
+ RTLightmapFilter::RTLightmapFilter(const Ref<Device>& device)
+ : AutoencoderFilter(device)
+ {
+ weightData.hdr = weights::rtlightmap_hdr;
+
+ hdr = true;
+ }
+
+ std::shared_ptr<TransferFunction> RTLightmapFilter::makeTransferFunc()
+ {
+ return std::make_shared<LogTransferFunction>();
+ }
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/autoencoder.h b/thirdparty/oidn/core/autoencoder.h
new file mode 100644
index 0000000000..97432f2bbd
--- /dev/null
+++ b/thirdparty/oidn/core/autoencoder.h
@@ -0,0 +1,116 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "filter.h"
+#include "network.h"
+#include "transfer_function.h"
+
+namespace oidn {
+
+ // --------------------------------------------------------------------------
+ // AutoencoderFilter - Direct-predicting autoencoder
+ // --------------------------------------------------------------------------
+
+ class AutoencoderFilter : public Filter
+ {
+ protected:
+ static constexpr int alignment = 32; // required spatial alignment in pixels (padding may be necessary)
+ static constexpr int receptiveField = 222; // receptive field in pixels
+ static constexpr int overlap = roundUp(receptiveField / 2, alignment); // required spatial overlap between tiles in pixels
+
+ static constexpr int estimatedBytesBase = 16*1024*1024; // estimated base memory usage
+ static constexpr int estimatedBytesPerPixel8 = 889; // estimated memory usage per pixel for K=8
+ static constexpr int estimatedBytesPerPixel16 = 2185; // estimated memory usage per pixel for K=16
+
+ Image color;
+ Image albedo;
+ Image normal;
+ Image output;
+ bool hdr = false;
+ float hdrScale = std::numeric_limits<float>::quiet_NaN();
+ bool srgb = false;
+ int maxMemoryMB = 6000; // approximate maximum memory usage in MBs
+
+ int H = 0; // image height
+ int W = 0; // image width
+ int tileH = 0; // tile height
+ int tileW = 0; // tile width
+ int tileCountH = 1; // number of tiles in H dimension
+ int tileCountW = 1; // number of tiles in W dimension
+
+ std::shared_ptr<Executable> net;
+ std::shared_ptr<Node> inputReorder;
+ std::shared_ptr<Node> outputReorder;
+
+ struct
+ {
+ void* ldr = nullptr;
+ void* ldr_alb = nullptr;
+ void* ldr_alb_nrm = nullptr;
+ void* hdr = nullptr;
+ void* hdr_alb = nullptr;
+ void* hdr_alb_nrm = nullptr;
+ } weightData;
+
+ explicit AutoencoderFilter(const Ref<Device>& device);
+ virtual std::shared_ptr<TransferFunction> makeTransferFunc();
+
+ public:
+ void setImage(const std::string& name, const Image& data) override;
+ void set1i(const std::string& name, int value) override;
+ int get1i(const std::string& name) override;
+ void set1f(const std::string& name, float value) override;
+ float get1f(const std::string& name) override;
+
+ void commit() override;
+ void execute() override;
+
+ private:
+ void computeTileSize();
+
+ template<int K>
+ std::shared_ptr<Executable> buildNet();
+
+ bool isCommitted() const { return bool(net); }
+ };
+
+ // --------------------------------------------------------------------------
+ // RTFilter - Generic ray tracing denoiser
+ // --------------------------------------------------------------------------
+
+// Godot doesn't need Raytracing filters. Removing them saves space in the weights files.
+#if 0
+ class RTFilter : public AutoencoderFilter
+ {
+ public:
+ explicit RTFilter(const Ref<Device>& device);
+ };
+#endif
+
+ // --------------------------------------------------------------------------
+ // RTLightmapFilter - Ray traced lightmap denoiser
+ // --------------------------------------------------------------------------
+
+ class RTLightmapFilter : public AutoencoderFilter
+ {
+ public:
+ explicit RTLightmapFilter(const Ref<Device>& device);
+ std::shared_ptr<TransferFunction> makeTransferFunc() override;
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/buffer.h b/thirdparty/oidn/core/buffer.h
new file mode 100644
index 0000000000..b95109152e
--- /dev/null
+++ b/thirdparty/oidn/core/buffer.h
@@ -0,0 +1,75 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "common.h"
+#include "device.h"
+
+namespace oidn {
+
+ class Device;
+
+ // Buffer which may or may not own its data
+ class Buffer : public RefCount
+ {
+ private:
+ char* ptr;
+ size_t byteSize;
+ bool shared;
+ Ref<Device> device;
+
+ public:
+ __forceinline Buffer(const Ref<Device>& device, size_t size)
+ : ptr((char*)alignedMalloc(size, 64)),
+ byteSize(size),
+ shared(false),
+ device(device) {}
+
+ __forceinline Buffer(const Ref<Device>& device, void* data, size_t size)
+ : ptr((char*)data),
+ byteSize(size),
+ shared(true),
+ device(device)
+ {
+ if (data == nullptr)
+ throw Exception(Error::InvalidArgument, "buffer pointer null");
+ }
+
+ __forceinline ~Buffer()
+ {
+ if (!shared)
+ alignedFree(ptr);
+ }
+
+ __forceinline char* data() { return ptr; }
+ __forceinline const char* data() const { return ptr; }
+ __forceinline size_t size() const { return byteSize; }
+
+ void* map(size_t offset, size_t size)
+ {
+ if (offset + size > byteSize)
+ throw Exception(Error::InvalidArgument, "buffer region out of range");
+
+ return ptr + offset;
+ }
+
+ void unmap(void* mappedPtr) {}
+
+ Device* getDevice() { return device.get(); }
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/common.h b/thirdparty/oidn/core/common.h
new file mode 100644
index 0000000000..6c87f377bc
--- /dev/null
+++ b/thirdparty/oidn/core/common.h
@@ -0,0 +1,133 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "common/platform.h"
+
+#include "mkl-dnn/include/mkldnn.hpp"
+#include "mkl-dnn/include/mkldnn_debug.h"
+#include "mkl-dnn/src/common/mkldnn_thread.hpp"
+#include "mkl-dnn/src/common/type_helpers.hpp"
+#include "mkl-dnn/src/cpu/jit_generator.hpp"
+
+#include "common/ref.h"
+#include "common/exception.h"
+#include "common/thread.h"
+#include "math.h"
+
+namespace oidn {
+
+ using namespace mkldnn;
+ using namespace mkldnn::impl::cpu;
+ using mkldnn::impl::parallel_nd;
+ using mkldnn::impl::memory_desc_matches_tag;
+
+
+ inline size_t getFormatBytes(Format format)
+ {
+ switch (format)
+ {
+ case Format::Undefined: return 1;
+ case Format::Float: return sizeof(float);
+ case Format::Float2: return sizeof(float)*2;
+ case Format::Float3: return sizeof(float)*3;
+ case Format::Float4: return sizeof(float)*4;
+ }
+ assert(0);
+ return 0;
+ }
+
+
+ inline memory::dims getTensorDims(const std::shared_ptr<memory>& mem)
+ {
+ const mkldnn_memory_desc_t& desc = mem->get_desc().data;
+ return memory::dims(&desc.dims[0], &desc.dims[desc.ndims]);
+ }
+
+ inline memory::data_type getTensorType(const std::shared_ptr<memory>& mem)
+ {
+ const mkldnn_memory_desc_t& desc = mem->get_desc().data;
+ return memory::data_type(desc.data_type);
+ }
+
+ // Returns the number of values in a tensor
+ inline size_t getTensorSize(const memory::dims& dims)
+ {
+ size_t res = 1;
+ for (int i = 0; i < (int)dims.size(); ++i)
+ res *= dims[i];
+ return res;
+ }
+
+ inline memory::dims getMaxTensorDims(const std::vector<memory::dims>& dims)
+ {
+ memory::dims result;
+ size_t maxSize = 0;
+
+ for (const auto& d : dims)
+ {
+ const size_t size = getTensorSize(d);
+ if (size > maxSize)
+ {
+ result = d;
+ maxSize = size;
+ }
+ }
+
+ return result;
+ }
+
+ inline size_t getTensorSize(const std::shared_ptr<memory>& mem)
+ {
+ return getTensorSize(getTensorDims(mem));
+ }
+
+
+ template<int K>
+ inline int getPadded(int dim)
+ {
+ return (dim + (K-1)) & ~(K-1);
+ }
+
+ template<int K>
+ inline memory::dims getPadded_nchw(const memory::dims& dims)
+ {
+ assert(dims.size() == 4);
+ memory::dims padDims = dims;
+ padDims[1] = getPadded<K>(dims[1]); // pad C
+ return padDims;
+ }
+
+
+ template<int K>
+ struct BlockedFormat;
+
+ template<>
+ struct BlockedFormat<8>
+ {
+ static constexpr memory::format_tag nChwKc = memory::format_tag::nChw8c;
+ static constexpr memory::format_tag OIhwKiKo = memory::format_tag::OIhw8i8o;
+ };
+
+ template<>
+ struct BlockedFormat<16>
+ {
+ static constexpr memory::format_tag nChwKc = memory::format_tag::nChw16c;
+ static constexpr memory::format_tag OIhwKiKo = memory::format_tag::OIhw16i16o;
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/device.cpp b/thirdparty/oidn/core/device.cpp
new file mode 100644
index 0000000000..0812624bb5
--- /dev/null
+++ b/thirdparty/oidn/core/device.cpp
@@ -0,0 +1,205 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#include "device.h"
+#include "autoencoder.h"
+
+namespace oidn {
+
+ thread_local Device::ErrorState Device::globalError;
+
+ Device::Device()
+ {
+ if (!mayiuse(sse41))
+ throw Exception(Error::UnsupportedHardware, "SSE4.1 support is required at minimum");
+ }
+
+ Device::~Device()
+ {
+ }
+
+ void Device::setError(Device* device, Error code, const std::string& message)
+ {
+ // Update the stored error only if the previous error was queried
+ if (device)
+ {
+ ErrorState& curError = device->error.get();
+
+ if (curError.code == Error::None)
+ {
+ curError.code = code;
+ curError.message = message;
+ }
+
+ // Print the error message in verbose mode
+ if (device->isVerbose())
+ std::cerr << "Error: " << message << std::endl;
+
+ // Call the error callback function
+ ErrorFunction errorFunc;
+ void* errorUserPtr;
+
+ {
+ std::lock_guard<std::mutex> lock(device->mutex);
+ errorFunc = device->errorFunc;
+ errorUserPtr = device->errorUserPtr;
+ }
+
+ if (errorFunc)
+ errorFunc(errorUserPtr, code, (code == Error::None) ? nullptr : message.c_str());
+ }
+ else
+ {
+ if (globalError.code == Error::None)
+ {
+ globalError.code = code;
+ globalError.message = message;
+ }
+ }
+ }
+
+ Error Device::getError(Device* device, const char** outMessage)
+ {
+ // Return and clear the stored error code, but keep the error message so pointers to it will
+ // remain valid until the next getError call
+ if (device)
+ {
+ ErrorState& curError = device->error.get();
+ const Error code = curError.code;
+ if (outMessage)
+ *outMessage = (code == Error::None) ? nullptr : curError.message.c_str();
+ curError.code = Error::None;
+ return code;
+ }
+ else
+ {
+ const Error code = globalError.code;
+ if (outMessage)
+ *outMessage = (code == Error::None) ? nullptr : globalError.message.c_str();
+ globalError.code = Error::None;
+ return code;
+ }
+ }
+
+ void Device::setErrorFunction(ErrorFunction func, void* userPtr)
+ {
+ errorFunc = func;
+ errorUserPtr = userPtr;
+ }
+
+ int Device::get1i(const std::string& name)
+ {
+ if (name == "numThreads")
+ return numThreads;
+ else if (name == "setAffinity")
+ return setAffinity;
+ else if (name == "verbose")
+ return verbose;
+ else if (name == "version")
+ return OIDN_VERSION;
+ else if (name == "versionMajor")
+ return OIDN_VERSION_MAJOR;
+ else if (name == "versionMinor")
+ return OIDN_VERSION_MINOR;
+ else if (name == "versionPatch")
+ return OIDN_VERSION_PATCH;
+ else
+ throw Exception(Error::InvalidArgument, "invalid parameter");
+ }
+
+ void Device::set1i(const std::string& name, int value)
+ {
+ if (name == "numThreads")
+ numThreads = value;
+ else if (name == "setAffinity")
+ setAffinity = value;
+ else if (name == "verbose")
+ {
+ verbose = value;
+ error.verbose = value;
+ }
+
+ dirty = true;
+ }
+
+ void Device::commit()
+ {
+ if (isCommitted())
+ throw Exception(Error::InvalidOperation, "device can be committed only once");
+
+ // Create the task arena
+ const int maxNumThreads = 1; //affinity ? affinity->getNumThreads() : tbb::this_task_arena::max_concurrency();
+ numThreads = (numThreads > 0) ? min(numThreads, maxNumThreads) : maxNumThreads;
+
+ dirty = false;
+
+ if (isVerbose())
+ print();
+ }
+
+ void Device::checkCommitted()
+ {
+ if (dirty)
+ throw Exception(Error::InvalidOperation, "changes to the device are not committed");
+ }
+
+ Ref<Buffer> Device::newBuffer(size_t byteSize)
+ {
+ checkCommitted();
+ return makeRef<Buffer>(Ref<Device>(this), byteSize);
+ }
+
+ Ref<Buffer> Device::newBuffer(void* ptr, size_t byteSize)
+ {
+ checkCommitted();
+ return makeRef<Buffer>(Ref<Device>(this), ptr, byteSize);
+ }
+
+ Ref<Filter> Device::newFilter(const std::string& type)
+ {
+ checkCommitted();
+
+ if (isVerbose())
+ std::cout << "Filter: " << type << std::endl;
+
+ Ref<Filter> filter;
+
+// Godot doesn't need Raytracing filters. Removing them saves space in the weights files.
+#if 0
+ if (type == "RT")
+ filter = makeRef<RTFilter>(Ref<Device>(this));
+#endif
+ if (type == "RTLightmap")
+ filter = makeRef<RTLightmapFilter>(Ref<Device>(this));
+ else
+ throw Exception(Error::InvalidArgument, "unknown filter type");
+
+ return filter;
+ }
+
+ void Device::print()
+ {
+ std::cout << std::endl;
+
+ std::cout << "Intel(R) Open Image Denoise " << OIDN_VERSION_STRING << std::endl;
+ std::cout << " Compiler: " << getCompilerName() << std::endl;
+ std::cout << " Build : " << getBuildName() << std::endl;
+ std::cout << " Platform: " << getPlatformName() << std::endl;
+
+ std::cout << std::endl;
+ }
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/device.h b/thirdparty/oidn/core/device.h
new file mode 100644
index 0000000000..93a83eb731
--- /dev/null
+++ b/thirdparty/oidn/core/device.h
@@ -0,0 +1,78 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "common.h"
+
+namespace oidn {
+
+ class Buffer;
+ class Filter;
+
+ class Device : public RefCount, public Verbose
+ {
+ private:
+ // Thread-safety
+ std::mutex mutex;
+
+ // Error handling
+ struct ErrorState
+ {
+ Error code = Error::None;
+ std::string message;
+ };
+
+ static thread_local ErrorState globalError;
+ ThreadLocal<ErrorState> error;
+ ErrorFunction errorFunc = nullptr;
+ void* errorUserPtr = nullptr;
+
+ // Parameters
+ int numThreads = 0; // autodetect by default
+ bool setAffinity = true;
+
+ bool dirty = true;
+
+ public:
+ Device();
+ ~Device();
+
+ static void setError(Device* device, Error code, const std::string& message);
+ static Error getError(Device* device, const char** outMessage);
+
+ void setErrorFunction(ErrorFunction func, void* userPtr);
+
+ int get1i(const std::string& name);
+ void set1i(const std::string& name, int value);
+
+ void commit();
+
+ Ref<Buffer> newBuffer(size_t byteSize);
+ Ref<Buffer> newBuffer(void* ptr, size_t byteSize);
+ Ref<Filter> newFilter(const std::string& type);
+
+ __forceinline Device* getDevice() { return this; }
+ __forceinline std::mutex& getMutex() { return mutex; }
+
+ private:
+ bool isCommitted() const { return false; }
+ void checkCommitted();
+
+ void print();
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/filter.cpp b/thirdparty/oidn/core/filter.cpp
new file mode 100644
index 0000000000..ec1f10af87
--- /dev/null
+++ b/thirdparty/oidn/core/filter.cpp
@@ -0,0 +1,27 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#include "filter.h"
+
+namespace oidn {
+
+ void Filter::setProgressMonitorFunction(ProgressMonitorFunction func, void* userPtr)
+ {
+ progressFunc = func;
+ progressUserPtr = userPtr;
+ }
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/filter.h b/thirdparty/oidn/core/filter.h
new file mode 100644
index 0000000000..935fa202f4
--- /dev/null
+++ b/thirdparty/oidn/core/filter.h
@@ -0,0 +1,52 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "common.h"
+#include "device.h"
+#include "image.h"
+
+namespace oidn {
+
+ class Filter : public RefCount
+ {
+ protected:
+ Ref<Device> device;
+
+ ProgressMonitorFunction progressFunc = nullptr;
+ void* progressUserPtr = nullptr;
+
+ bool dirty = true;
+
+ public:
+ explicit Filter(const Ref<Device>& device) : device(device) {}
+
+ virtual void setImage(const std::string& name, const Image& data) = 0;
+ virtual void set1i(const std::string& name, int value) = 0;
+ virtual int get1i(const std::string& name) = 0;
+ virtual void set1f(const std::string& name, float value) = 0;
+ virtual float get1f(const std::string& name) = 0;
+
+ void setProgressMonitorFunction(ProgressMonitorFunction func, void* userPtr);
+
+ virtual void commit() = 0;
+ virtual void execute() = 0;
+
+ Device* getDevice() { return device.get(); }
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/image.h b/thirdparty/oidn/core/image.h
new file mode 100644
index 0000000000..748f49c4e5
--- /dev/null
+++ b/thirdparty/oidn/core/image.h
@@ -0,0 +1,111 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "common.h"
+#include "buffer.h"
+
+namespace oidn {
+
+ struct Image
+ {
+ static constexpr int maxSize = 65536;
+
+ char* ptr; // pointer to the first pixel
+ int width; // width in number of pixels
+ int height; // height in number of pixels
+ size_t bytePixelStride; // pixel stride in number of *bytes*
+ size_t rowStride; // row stride in number of *pixel strides*
+ Format format; // pixel format
+ Ref<Buffer> buffer; // buffer containing the image data
+
+ Image() : ptr(nullptr), width(0), height(0), bytePixelStride(0), rowStride(0), format(Format::Undefined) {}
+
+ Image(void* ptr, Format format, int width, int height, size_t byteOffset, size_t inBytePixelStride, size_t inByteRowStride)
+ {
+ if (ptr == nullptr)
+ throw Exception(Error::InvalidArgument, "buffer pointer null");
+
+ init((char*)ptr + byteOffset, format, width, height, inBytePixelStride, inByteRowStride);
+ }
+
+ Image(const Ref<Buffer>& buffer, Format format, int width, int height, size_t byteOffset, size_t inBytePixelStride, size_t inByteRowStride)
+ {
+ init(buffer->data() + byteOffset, format, width, height, inBytePixelStride, inByteRowStride);
+
+ if (byteOffset + height * rowStride * bytePixelStride > buffer->size())
+ throw Exception(Error::InvalidArgument, "buffer region out of range");
+ }
+
+ void init(char* ptr, Format format, int width, int height, size_t inBytePixelStride, size_t inByteRowStride)
+ {
+ assert(width >= 0);
+ assert(height >= 0);
+ if (width > maxSize || height > maxSize)
+ throw Exception(Error::InvalidArgument, "image size too large");
+
+ this->ptr = ptr;
+ this->width = width;
+ this->height = height;
+
+ const size_t pixelSize = getFormatBytes(format);
+ if (inBytePixelStride != 0)
+ {
+ if (inBytePixelStride < pixelSize)
+ throw Exception(Error::InvalidArgument, "pixel stride smaller than pixel size");
+
+ this->bytePixelStride = inBytePixelStride;
+ }
+ else
+ {
+ this->bytePixelStride = pixelSize;
+ }
+
+ if (inByteRowStride != 0)
+ {
+ if (inByteRowStride < width * this->bytePixelStride)
+ throw Exception(Error::InvalidArgument, "row stride smaller than width * pixel stride");
+ if (inByteRowStride % this->bytePixelStride != 0)
+ throw Exception(Error::InvalidArgument, "row stride not integer multiple of pixel stride");
+
+ this->rowStride = inByteRowStride / this->bytePixelStride;
+ }
+ else
+ {
+ this->rowStride = width;
+ }
+
+ this->format = format;
+ }
+
+ __forceinline char* get(int y, int x)
+ {
+ return ptr + ((size_t(y) * rowStride + size_t(x)) * bytePixelStride);
+ }
+
+ __forceinline const char* get(int y, int x) const
+ {
+ return ptr + ((size_t(y) * rowStride + size_t(x)) * bytePixelStride);
+ }
+
+ operator bool() const
+ {
+ return ptr != nullptr;
+ }
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/input_reorder.h b/thirdparty/oidn/core/input_reorder.h
new file mode 100644
index 0000000000..966856afe9
--- /dev/null
+++ b/thirdparty/oidn/core/input_reorder.h
@@ -0,0 +1,232 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "node.h"
+#include "image.h"
+
+namespace oidn {
+
+ // Input reorder node
+ template<int K, class TransferFunction>
+ class InputReorderNode : public Node
+ {
+ private:
+ // Source
+ Image color;
+ Image albedo;
+ Image normal;
+
+ // Destination
+ std::shared_ptr<memory> dst;
+ float* dstPtr;
+ int C2;
+ int H2;
+ int W2;
+
+ // Tile
+ int h1Begin;
+ int w1Begin;
+ int h2Begin;
+ int w2Begin;
+ int H;
+ int W;
+
+ std::shared_ptr<TransferFunction> transferFunc;
+
+ public:
+ InputReorderNode(const Image& color,
+ const Image& albedo,
+ const Image& normal,
+ const std::shared_ptr<memory>& dst,
+ const std::shared_ptr<TransferFunction>& transferFunc)
+ : color(color), albedo(albedo), normal(normal),
+ dst(dst),
+ h1Begin(0), w1Begin(0),
+ H(color.height), W(color.width),
+ transferFunc(transferFunc)
+ {
+ const mkldnn_memory_desc_t& dstDesc = dst->get_desc().data;
+ assert(memory_desc_matches_tag(dstDesc, mkldnn_format_tag_t(BlockedFormat<K>::nChwKc)));
+ assert(dstDesc.ndims == 4);
+ assert(dstDesc.data_type == memory::data_type::f32);
+ assert(dstDesc.dims[0] == 1);
+ //assert(dstDesc.dims[1] >= getPadded<K>(C1));
+
+ dstPtr = (float*)dst->get_data_handle();
+ C2 = dstDesc.dims[1];
+ H2 = dstDesc.dims[2];
+ W2 = dstDesc.dims[3];
+ }
+
+ void setTile(int h1, int w1, int h2, int w2, int H, int W) override
+ {
+ h1Begin = h1;
+ w1Begin = w1;
+ h2Begin = h2;
+ w2Begin = w2;
+ this->H = H;
+ this->W = W;
+ }
+
+ void execute(stream& sm) override
+ {
+ assert(H + h1Begin <= color.height);
+ assert(W + w1Begin <= color.width);
+ assert(H + h2Begin <= H2);
+ assert(W + w2Begin <= W2);
+
+ parallel_nd(H2, [&](int h2)
+ {
+ const int h = h2 - h2Begin;
+
+ if (h >= 0 && h < H)
+ {
+ const int h1 = h + h1Begin;
+
+ // Zero pad
+ for (int w2 = 0; w2 < w2Begin; ++w2)
+ {
+ int c = 0;
+ while (c < C2)
+ store(h2, w2, c, 0.f);
+ }
+
+ // Reorder
+ for (int w = 0; w < W; ++w)
+ {
+ const int w1 = w + w1Begin;
+ const int w2 = w + w2Begin;
+
+ int c = 0;
+ storeColor(h2, w2, c, (float*)color.get(h1, w1));
+ if (albedo)
+ storeAlbedo(h2, w2, c, (float*)albedo.get(h1, w1));
+ if (normal)
+ storeNormal(h2, w2, c, (float*)normal.get(h1, w1));
+ while (c < C2)
+ store(h2, w2, c, 0.f);
+ }
+
+ // Zero pad
+ for (int w2 = W + w2Begin; w2 < W2; ++w2)
+ {
+ int c = 0;
+ while (c < C2)
+ store(h2, w2, c, 0.f);
+ }
+ }
+ else
+ {
+ // Zero pad
+ for (int w2 = 0; w2 < W2; ++w2)
+ {
+ int c = 0;
+ while (c < C2)
+ store(h2, w2, c, 0.f);
+ }
+ }
+ });
+ }
+
+ std::shared_ptr<memory> getDst() const override { return dst; }
+
+ private:
+ // Stores a single value
+ __forceinline void store(int h, int w, int& c, float value)
+ {
+ // Destination is in nChwKc format
+ float* dst_c = dstPtr + (H2*W2*K*(c/K)) + h*W2*K + w*K + (c%K);
+ *dst_c = value;
+ c++;
+ }
+
+ // Stores a color
+ __forceinline void storeColor(int h, int w, int& c, const float* values)
+ {
+ #pragma unroll
+ for (int i = 0; i < 3; ++i)
+ {
+ // Load the value
+ float x = values[i];
+
+ // Sanitize the value
+ x = maxSafe(x, 0.f);
+
+ // Apply the transfer function
+ x = transferFunc->forward(x);
+
+ // Store the value
+ store(h, w, c, x);
+ }
+ }
+
+ // Stores an albedo
+ __forceinline void storeAlbedo(int h, int w, int& c, const float* values)
+ {
+ #pragma unroll
+ for (int i = 0; i < 3; ++i)
+ {
+ // Load the value
+ float x = values[i];
+
+ // Sanitize the value
+ x = clampSafe(x, 0.f, 1.f);
+
+ // Store the value
+ store(h, w, c, x);
+ }
+ }
+
+ // Stores a normal
+ __forceinline void storeNormal(int h, int w, int& c, const float* values)
+ {
+ // Load the normal
+ float x = values[0];
+ float y = values[1];
+ float z = values[2];
+
+ // Compute the length of the normal
+ const float lengthSqr = sqr(x) + sqr(y) + sqr(z);
+
+ // Normalize the normal and transform it to [0..1]
+ if (isfinite(lengthSqr))
+ {
+ const float invLength = (lengthSqr > minVectorLengthSqr) ? rsqrt(lengthSqr) : 1.f;
+
+ const float scale = invLength * 0.5f;
+ const float offset = 0.5f;
+
+ x = x * scale + offset;
+ y = y * scale + offset;
+ z = z * scale + offset;
+ }
+ else
+ {
+ x = 0.f;
+ y = 0.f;
+ z = 0.f;
+ }
+
+ // Store the normal
+ store(h, w, c, x);
+ store(h, w, c, y);
+ store(h, w, c, z);
+ }
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/math.h b/thirdparty/oidn/core/math.h
new file mode 100644
index 0000000000..a844ef0d1d
--- /dev/null
+++ b/thirdparty/oidn/core/math.h
@@ -0,0 +1,78 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "common/platform.h"
+
+namespace oidn {
+
+ constexpr float minVectorLength = 1e-10f;
+ constexpr float minVectorLengthSqr = minVectorLength * minVectorLength;
+
+ using std::log;
+ using std::log2;
+ using std::exp;
+ using std::exp2;
+ using std::pow;
+ using std::isfinite;
+ using std::isnan;
+
+ __forceinline float sqr(float x)
+ {
+ return x * x;
+ }
+
+ __forceinline float rcp(float x)
+ {
+ __m128 r = _mm_rcp_ss(_mm_set_ss(x));
+ return _mm_cvtss_f32(_mm_sub_ss(_mm_add_ss(r, r), _mm_mul_ss(_mm_mul_ss(r, r), _mm_set_ss(x))));
+ }
+
+ __forceinline float rsqrt(float x)
+ {
+ __m128 r = _mm_rsqrt_ss(_mm_set_ss(x));
+ return _mm_cvtss_f32(_mm_add_ss(_mm_mul_ss(_mm_set_ss(1.5f), r),
+ _mm_mul_ss(_mm_mul_ss(_mm_mul_ss(_mm_set_ss(x), _mm_set_ss(-0.5f)), r), _mm_mul_ss(r, r))));
+ }
+
+ __forceinline float maxSafe(float value, float minValue)
+ {
+ return isfinite(value) ? max(value, minValue) : minValue;
+ }
+
+ __forceinline float clampSafe(float value, float minValue, float maxValue)
+ {
+ return isfinite(value) ? clamp(value, minValue, maxValue) : minValue;
+ }
+
+ // Returns ceil(a / b) for non-negative integers
+ template<class Int>
+ __forceinline constexpr Int ceilDiv(Int a, Int b)
+ {
+ //assert(a >= 0);
+ //assert(b > 0);
+ return (a + b - 1) / b;
+ }
+
+ // Returns a rounded up to multiple of b
+ template<class Int>
+ __forceinline constexpr Int roundUp(Int a, Int b)
+ {
+ return ceilDiv(a, b) * b;
+ }
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/network.cpp b/thirdparty/oidn/core/network.cpp
new file mode 100644
index 0000000000..4da32073cd
--- /dev/null
+++ b/thirdparty/oidn/core/network.cpp
@@ -0,0 +1,434 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#include "network.h"
+#include "upsample.h"
+#include "weights_reorder.h"
+#include <cstring>
+
+namespace oidn {
+
+ template<int K>
+ Network<K>::Network(const Ref<Device>& device, const std::map<std::string, Tensor>& weightMap)
+ : device(device),
+ eng(engine::cpu, 0),
+ sm(eng),
+ weightMap(weightMap)
+ {
+ }
+
+ template<int K>
+ void Network<K>::execute(const Progress& progress, int taskIndex)
+ {
+ if (progress.func)
+ {
+ const double value = double(taskIndex) / double(progress.taskCount);
+ if (!progress.func(progress.userPtr, value))
+ throw Exception(Error::Cancelled, "execution was cancelled");
+ }
+
+ for (size_t i = 0; i < nodes.size(); ++i)
+ {
+ nodes[i]->execute(sm);
+
+ if (progress.func)
+ {
+ const double value = (double(taskIndex) + double(i+1) / double(nodes.size())) / double(progress.taskCount);
+ if (!progress.func(progress.userPtr, value))
+ throw Exception(Error::Cancelled, "execution was cancelled");
+ }
+ }
+ }
+
+ template<int K>
+ std::shared_ptr<memory> Network<K>::allocTensor(const memory::dims& dims,
+ memory::format_tag format,
+ void* data)
+ {
+ if (format == memory::format_tag::any)
+ {
+ if (dims.size() == 4)
+ format = BlockedFormat<K>::nChwKc;
+ else if (dims.size() == 1)
+ format = memory::format_tag::x;
+ else
+ assert(0);
+ }
+ memory::desc desc(dims, memory::data_type::f32, format);
+ if (data == nullptr)
+ {
+ const size_t bytes = getTensorSize(dims) * sizeof(float);
+ if (format == BlockedFormat<K>::nChwKc)
+ activationAllocBytes += bytes;
+ totalAllocBytes += bytes;
+
+ return std::make_shared<memory>(desc, eng);
+ }
+ else
+ {
+ return std::make_shared<memory>(desc, eng, data);
+ }
+ }
+
+ template<int K>
+ std::shared_ptr<memory> Network<K>::castTensor(const memory::dims& dims,
+ const std::shared_ptr<memory>& src,
+ size_t srcOffset,
+ memory::format_tag format)
+ {
+ const mkldnn_memory_desc_t& srcDesc = src->get_desc().data;
+ MAYBE_UNUSED(srcDesc);
+ assert(srcDesc.data_type == memory::data_type::f32);
+ assert(getTensorSize(src) >= srcOffset + getTensorSize(dims));
+
+ if (format == memory::format_tag::any)
+ {
+ if (dims.size() == 4)
+ format = BlockedFormat<K>::nChwKc;
+ else if (dims.size() == 1)
+ format = memory::format_tag::x;
+ else
+ assert(0);
+ }
+ memory::desc desc(dims, memory::data_type::f32, format);
+ float* srcPtr = (float*)src->get_data_handle() + srcOffset;
+ return std::make_shared<memory>(desc, eng, srcPtr);
+ }
+
+ template<int K>
+ std::shared_ptr<memory> Network<K>::castTensor(const memory::dims& dims,
+ const std::shared_ptr<memory>& src,
+ const memory::dims& srcOffset)
+ {
+ return castTensor(dims, src, getTensorSize(srcOffset));
+ }
+
+ template<int K>
+ void Network<K>::zeroTensor(const std::shared_ptr<memory>& dst)
+ {
+ assert(getTensorType(dst) == memory::data_type::f32);
+ memset(dst->get_data_handle(), 0, getTensorSize(dst)*sizeof(float));
+ }
+
+ template<int K>
+ memory::dims Network<K>::getInputReorderDims(const memory::dims& srcDims, int alignment)
+ {
+ memory::dims dstDims = srcDims;
+ dstDims[1] = getPadded<K>(srcDims[1]); // round up C
+ dstDims[2] = roundUp(srcDims[2], memory::dim(alignment)); // round up H
+ dstDims[3] = roundUp(srcDims[3], memory::dim(alignment)); // round up W
+ return dstDims;
+ }
+
+ template<int K>
+ std::shared_ptr<Node> Network<K>::addInputReorder(const Image& color,
+ const Image& albedo,
+ const Image& normal,
+ const std::shared_ptr<TransferFunction>& transferFunc,
+ int alignment,
+ const std::shared_ptr<memory>& userDst)
+ {
+ assert(color);
+ int inputC = 3;
+ if (albedo) inputC += 3;
+ if (normal) inputC += 3;
+
+ memory::dims srcDims = {1, inputC, color.height, color.width};
+ memory::dims dstDims = getInputReorderDims(srcDims, alignment);
+
+ // Allocate padded memory
+ auto dst = userDst;
+ if (!dst)
+ dst = allocTensor(dstDims);
+
+ // Push node
+ std::shared_ptr<Node> node;
+
+ if (auto tf = std::dynamic_pointer_cast<LinearTransferFunction>(transferFunc))
+ node = std::make_shared<InputReorderNode<K, LinearTransferFunction>>(color, albedo, normal, dst, tf);
+ else if (auto tf = std::dynamic_pointer_cast<GammaTransferFunction>(transferFunc))
+ node = std::make_shared<InputReorderNode<K, GammaTransferFunction>>(color, albedo, normal, dst, tf);
+ else if (auto tf = std::dynamic_pointer_cast<LogTransferFunction>(transferFunc))
+ node = std::make_shared<InputReorderNode<K, LogTransferFunction>>(color, albedo, normal, dst, tf);
+ else if (auto tf = std::dynamic_pointer_cast<PQXTransferFunction>(transferFunc))
+ node = std::make_shared<InputReorderNode<K, PQXTransferFunction>>(color, albedo, normal, dst, tf);
+ else
+ assert(0);
+
+ nodes.push_back(node);
+ return node;
+ }
+
+ template<int K>
+ std::shared_ptr<Node> Network<K>::addOutputReorder(const std::shared_ptr<memory>& src,
+ const std::shared_ptr<TransferFunction>& transferFunc,
+ const Image& output)
+ {
+ memory::dims srcDims = getTensorDims(src);
+ assert(srcDims[1] == K);
+
+ // Push node
+ std::shared_ptr<Node> node;
+
+ if (auto tf = std::dynamic_pointer_cast<LinearTransferFunction>(transferFunc))
+ node = std::make_shared<OutputReorderNode<K, LinearTransferFunction>>(src, output, tf);
+ else if (auto tf = std::dynamic_pointer_cast<GammaTransferFunction>(transferFunc))
+ node = std::make_shared<OutputReorderNode<K, GammaTransferFunction>>(src, output, tf);
+ else if (auto tf = std::dynamic_pointer_cast<LogTransferFunction>(transferFunc))
+ node = std::make_shared<OutputReorderNode<K, LogTransferFunction>>(src, output, tf);
+ else if (auto tf = std::dynamic_pointer_cast<PQXTransferFunction>(transferFunc))
+ node = std::make_shared<OutputReorderNode<K, PQXTransferFunction>>(src, output, tf);
+ else
+ assert(0);
+
+ nodes.push_back(node);
+ return node;
+ }
+
+ template<int K>
+ memory::dims Network<K>::getConvDims(const std::string& name, const memory::dims& srcDims)
+ {
+ auto b = weightMap[name + "/b"];
+ memory::dims dstDims = srcDims;
+ dstDims[1] = getPadded<K>(b.dims[0]); // dstDims[C] = getPadded(OC)
+ return dstDims;
+ }
+
+ template<int K>
+ std::shared_ptr<Node> Network<K>::addConv(const std::string& name,
+ const std::shared_ptr<memory>& src,
+ const std::shared_ptr<memory>& userDst,
+ bool relu)
+ {
+ const memory::dims strides = {1, 1};
+ const memory::dims padding = {1, 1};
+
+ memory::dims srcDims = getTensorDims(src);
+
+ // Get the weights
+ const auto& W = weightMap[name + "/W"];
+ if (W.ndims() != 4 || W.format != "oihw")
+ throw Exception(Error::InvalidOperation, "invalid convolution weights");
+ memory::dims weightsDims = W.dims;
+ auto userWeights = allocTensor(weightsDims, memory::format_tag::oihw, W.data);
+
+ // Pad the weights
+ memory::dims weightsPadDims = weightsDims;
+ weightsPadDims[1] = getPadded<K>(weightsDims[1]); // IC
+ weightsPadDims[0] = getPadded<K>(weightsDims[0]); // OC
+ assert(srcDims[1] == weightsPadDims[1]); // srcDims[C] == weightsPadDims[IC]
+ auto weightsPad = allocTensor(weightsPadDims, memory::format_tag::oihw);
+ WeightsReorderNode<K>(userWeights, weightsPad).execute(sm);
+
+ // Get the biases
+ const auto& b = weightMap[name + "/b"];
+ if (b.ndims() != 1)
+ throw Exception(Error::InvalidOperation, "invalid convolution biases");
+ memory::dims biasDims = b.dims;
+
+ // Copy/pad the biases
+ memory::dims biasPadDims = {getPadded<K>(biasDims[0])};
+ auto bias = allocTensor(biasPadDims);
+ if (biasDims[0] != biasPadDims[0])
+ memset(bias->get_data_handle(), 0, biasPadDims[0]*sizeof(float));
+ memcpy(bias->get_data_handle(), b.data, biasDims[0]*sizeof(float));
+
+ // Allocate memory for destination
+ memory::dims dstDims = srcDims;
+ dstDims[1] = weightsPadDims[0]; // dstDims[C] = weightsPadDims[OC]
+
+ std::shared_ptr<memory> dst;
+ if (!userDst)
+ dst = allocTensor(dstDims);
+ else if (getTensorDims(userDst) == dstDims)
+ dst = userDst;
+ else
+ dst = castTensor(dstDims, userDst);
+
+ // Create a convolution
+ // Let the convolution primitive choose the weights format
+ auto weightsDesc = memory::desc({ weightsPadDims }, memory::data_type::f32, memory::format_tag::any);
+
+ auto convAlgo = (K == 16) ? convolution_winograd : convolution_direct;
+ auto convDesc = convolution_forward::desc(
+ prop_kind::forward_inference, convAlgo,
+ src->get_desc(),
+ weightsDesc,
+ bias->get_desc(),
+ dst->get_desc(),
+ strides, padding, padding, padding_kind::zero);
+
+ // Incorporate relu
+ mkldnn::primitive_attr convAttr;
+ if (relu)
+ {
+ mkldnn::post_ops ops;
+ ops.append_eltwise(
+ 1.f, // scale factor, not used
+ algorithm::eltwise_relu,
+ 0.f, // max with
+ 0.f // unused
+ );
+ convAttr.set_post_ops(ops);
+ }
+ convAttr.set_scratchpad_mode(scratchpad_mode_user);
+
+ auto convPrimDesc = convolution_forward::primitive_desc(convDesc, convAttr, eng);
+
+ // Reorder the weights to the final format, if necessary
+ auto weights = weightsPad;
+ if (convPrimDesc.weights_desc() != weightsPad->get_desc())
+ {
+ weights = std::make_shared<memory>(convPrimDesc.weights_desc(), eng);
+ ReorderNode(weightsPad, weights).execute(sm);
+ }
+
+ // Create convolution node and add it to the net
+ auto node = std::make_shared<ConvNode>(convPrimDesc, src, weights, bias, dst);
+ nodes.push_back(node);
+ return node;
+ }
+
+ template<int K>
+ memory::dims Network<K>::getPoolDims(const memory::dims& srcDims)
+ {
+ memory::dims dstDims = srcDims;
+ dstDims[2] /= 2; // H/2
+ dstDims[3] /= 2; // W/2
+ return dstDims;
+ }
+
+ template<int K>
+ std::shared_ptr<Node> Network<K>::addPool(const std::shared_ptr<memory>& src,
+ const std::shared_ptr<memory>& userDst)
+ {
+ const memory::dims kernel = {2, 2};
+ const memory::dims strides = {2, 2};
+ const memory::dims padding = {0, 0};
+
+ memory::dims srcDims = getTensorDims(src);
+ memory::dims dstDims = getPoolDims(srcDims);
+
+ std::shared_ptr<memory> dst;
+ if (!userDst)
+ dst = allocTensor(dstDims);
+ else if (getTensorDims(userDst) == dstDims)
+ dst = userDst;
+ else
+ dst = castTensor(dstDims, userDst);
+
+ auto poolDesc = pooling_forward::desc(
+ prop_kind::forward_inference, pooling_max,
+ src->get_desc(),
+ dst->get_desc(),
+ strides, kernel, padding, padding, padding_kind::zero);
+
+ mkldnn::primitive_attr poolAttr;
+ poolAttr.set_scratchpad_mode(scratchpad_mode_user);
+
+ auto poolPrimDesc = pooling_forward::primitive_desc(poolDesc, poolAttr, eng);
+
+ auto node = std::make_shared<PoolNode>(poolPrimDesc, src, dst);
+ nodes.push_back(node);
+ return node;
+ }
+
+ template<int K>
+ memory::dims Network<K>::getUpsampleDims(const memory::dims& srcDims)
+ {
+ memory::dims dstDims = srcDims;
+ dstDims[2] *= 2; // H*2
+ dstDims[3] *= 2; // W*2
+ return dstDims;
+ }
+
+ template<int K>
+ std::shared_ptr<Node> Network<K>::addUpsample(const std::shared_ptr<memory>& src,
+ const std::shared_ptr<memory>& userDst)
+ {
+ memory::dims srcDims = getTensorDims(src);
+ memory::dims dstDims = getUpsampleDims(srcDims);
+
+ std::shared_ptr<memory> dst;
+ if (!userDst)
+ dst = allocTensor(dstDims);
+ else if (getTensorDims(userDst) == dstDims)
+ dst = userDst;
+ else
+ dst = castTensor(dstDims, userDst);
+
+ // Create upsampling node and add it to net
+ auto node = std::make_shared<UpsampleNode<K>>(src, dst);
+ nodes.push_back(node);
+ return node;
+ }
+
+ template<int K>
+ memory::dims Network<K>::getConcatDims(const memory::dims& src1Dims, const memory::dims& src2Dims)
+ {
+ assert(src1Dims[0] == src2Dims[0]); // N
+ assert(src1Dims[2] == src2Dims[2]); // H
+ assert(src1Dims[3] == src2Dims[3]); // W
+
+ memory::dims dstDims = src1Dims;
+ dstDims[1] += src2Dims[1]; // C
+ return dstDims;
+ }
+
+ template<int K>
+ std::shared_ptr<Node> Network<K>::addAutoexposure(const Image& color,
+ const std::shared_ptr<HDRTransferFunction>& transferFunc)
+ {
+ auto node = std::make_shared<AutoexposureNode>(color, transferFunc);
+ nodes.push_back(node);
+ return node;
+ }
+
+ template <int K>
+ void Network<K>::finalize()
+ {
+ // Compute the size of the scratchpad
+ size_t scratchpadSize = 0;
+ for (const auto& node : nodes)
+ scratchpadSize = max(scratchpadSize, node->getScratchpadSize());
+
+ // Allocate the scratchpad
+ memory::dims scratchpadDims = { memory::dim(scratchpadSize) };
+ memory::desc scratchpadDesc(scratchpadDims, memory::data_type::u8, memory::format_tag::x);
+ auto scratchpad = std::make_shared<memory>(scratchpadDesc, eng);
+ activationAllocBytes += scratchpadSize;
+ totalAllocBytes += scratchpadSize;
+
+ // Set the scratchpad for the nodes
+ for (auto& node : nodes)
+ node->setScratchpad(scratchpad);
+
+ // Free the weights
+ weightMap.clear();
+
+ // Print statistics
+ if (device->isVerbose(2))
+ {
+ std::cout << "Activation bytes: " << activationAllocBytes << std::endl;
+ std::cout << "Scratchpad bytes: " << scratchpadSize << std::endl;
+ std::cout << "Total bytes : " << totalAllocBytes << std::endl;
+ }
+ }
+
+ template class Network<8>;
+ template class Network<16>;
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/network.h b/thirdparty/oidn/core/network.h
new file mode 100644
index 0000000000..7a696fd355
--- /dev/null
+++ b/thirdparty/oidn/core/network.h
@@ -0,0 +1,112 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#include "common/tensor.h"
+#include "image.h"
+#include "node.h"
+#include "input_reorder.h"
+#include "output_reorder.h"
+#include "transfer_function.h"
+
+#pragma once
+
+namespace oidn {
+
+ // Progress state
+ struct Progress
+ {
+ ProgressMonitorFunction func;
+ void* userPtr;
+ int taskCount;
+ };
+
+ class Executable
+ {
+ public:
+ virtual ~Executable() {}
+ virtual void execute(const Progress& progress, int taskIndex) = 0;
+ };
+
+ template<int K>
+ class Network : public Executable
+ {
+ public:
+ Network(const Ref<Device>& device, const std::map<std::string, Tensor>& weightMap);
+
+ void execute(const Progress& progress, int taskIndex) override;
+
+ std::shared_ptr<memory> allocTensor(const memory::dims& dims,
+ memory::format_tag format = memory::format_tag::any,
+ void* data = nullptr);
+
+ std::shared_ptr<memory> castTensor(const memory::dims& dims,
+ const std::shared_ptr<memory>& src,
+ size_t srcOffset = 0,
+ memory::format_tag format = memory::format_tag::any);
+
+ std::shared_ptr<memory> castTensor(const memory::dims& dims,
+ const std::shared_ptr<memory>& src,
+ const memory::dims& srcOffset);
+
+ void zeroTensor(const std::shared_ptr<memory>& dst);
+
+ memory::dims getInputReorderDims(const memory::dims& srcDims, int alignment);
+
+ std::shared_ptr<Node> addInputReorder(const Image& color,
+ const Image& albedo,
+ const Image& normal,
+ const std::shared_ptr<TransferFunction>& transferFunc,
+ int alignment,
+ const std::shared_ptr<memory>& userDst = nullptr);
+
+ std::shared_ptr<Node> addOutputReorder(const std::shared_ptr<memory>& src,
+ const std::shared_ptr<TransferFunction>& transferFunc,
+ const Image& output);
+
+ memory::dims getConvDims(const std::string& name, const memory::dims& srcDims);
+ std::shared_ptr<Node> addConv(const std::string& name,
+ const std::shared_ptr<memory>& src,
+ const std::shared_ptr<memory>& userDst = nullptr,
+ bool relu = true);
+
+ memory::dims getPoolDims(const memory::dims& srcDims);
+ std::shared_ptr<Node> addPool(const std::shared_ptr<memory>& src,
+ const std::shared_ptr<memory>& userDst = nullptr);
+
+ memory::dims getUpsampleDims(const memory::dims& srcDims);
+ std::shared_ptr<Node> addUpsample(const std::shared_ptr<memory>& src,
+ const std::shared_ptr<memory>& userDst = nullptr);
+
+ memory::dims getConcatDims(const memory::dims& src1Dims, const memory::dims& src2Dims);
+
+ std::shared_ptr<Node> addAutoexposure(const Image& color,
+ const std::shared_ptr<HDRTransferFunction>& transferFunc);
+
+ void finalize();
+
+ private:
+ Ref<Device> device;
+ engine eng;
+ stream sm;
+ std::vector<std::shared_ptr<Node>> nodes;
+ std::map<std::string, Tensor> weightMap;
+
+ // Memory allocation statistics
+ size_t activationAllocBytes = 0; // number of allocated activation bytes
+ size_t totalAllocBytes = 0; // total number of allocated bytes
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/node.h b/thirdparty/oidn/core/node.h
new file mode 100644
index 0000000000..b9ffe906df
--- /dev/null
+++ b/thirdparty/oidn/core/node.h
@@ -0,0 +1,142 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "common.h"
+#include <vector>
+
+namespace oidn {
+
+ class Node
+ {
+ public:
+ virtual ~Node() = default;
+
+ virtual void execute(stream& sm) = 0;
+
+ virtual std::shared_ptr<memory> getDst() const { return nullptr; }
+
+ virtual size_t getScratchpadSize() const { return 0; }
+ virtual void setScratchpad(const std::shared_ptr<memory>& mem) {}
+
+ virtual void setTile(int h1, int w1, int h2, int w2, int H, int W)
+ {
+ assert(0); // not supported
+ }
+ };
+
+ // Node wrapping an MKL-DNN primitive
+ class MklNode : public Node
+ {
+ private:
+ primitive prim;
+ std::unordered_map<int, memory> args;
+ std::shared_ptr<memory> scratchpad;
+
+ public:
+ MklNode(const primitive& prim, const std::unordered_map<int, memory>& args)
+ : prim(prim),
+ args(args)
+ {}
+
+ size_t getScratchpadSize() const override
+ {
+ const auto primDesc = prim.get_primitive_desc();
+ const mkldnn_memory_desc_t* scratchpadDesc = mkldnn_primitive_desc_query_md(primDesc, mkldnn_query_scratchpad_md, 0);
+ if (scratchpadDesc == nullptr)
+ return 0;
+ return mkldnn_memory_desc_get_size(scratchpadDesc);
+ }
+
+ void setScratchpad(const std::shared_ptr<memory>& mem) override
+ {
+ scratchpad = mem;
+ args.insert(std::make_pair(MKLDNN_ARG_SCRATCHPAD, *scratchpad));
+ }
+
+ void execute(stream& sm) override
+ {
+ prim.execute(sm, args);
+ }
+ };
+
+ // Convolution node
+ class ConvNode : public MklNode
+ {
+ private:
+ std::shared_ptr<memory> src;
+ std::shared_ptr<memory> weights;
+ std::shared_ptr<memory> bias;
+ std::shared_ptr<memory> dst;
+
+ public:
+ ConvNode(const convolution_forward::primitive_desc& desc,
+ const std::shared_ptr<memory>& src,
+ const std::shared_ptr<memory>& weights,
+ const std::shared_ptr<memory>& bias,
+ const std::shared_ptr<memory>& dst)
+ : MklNode(convolution_forward(desc),
+ { { MKLDNN_ARG_SRC, *src },
+ { MKLDNN_ARG_WEIGHTS, *weights },
+ { MKLDNN_ARG_BIAS, *bias },
+ { MKLDNN_ARG_DST, *dst } }),
+ src(src), weights(weights), bias(bias), dst(dst)
+ {}
+
+ std::shared_ptr<memory> getDst() const override { return dst; }
+ };
+
+ // Pooling node
+ class PoolNode : public MklNode
+ {
+ private:
+ std::shared_ptr<memory> src;
+ std::shared_ptr<memory> dst;
+
+ public:
+ PoolNode(const pooling_forward::primitive_desc& desc,
+ const std::shared_ptr<memory>& src,
+ const std::shared_ptr<memory>& dst)
+ : MklNode(pooling_forward(desc),
+ { { MKLDNN_ARG_SRC, *src },
+ { MKLDNN_ARG_DST, *dst } }),
+ src(src), dst(dst)
+ {}
+
+ std::shared_ptr<memory> getDst() const override { return dst; }
+ };
+
+ // Reorder node
+ class ReorderNode : public MklNode
+ {
+ private:
+ std::shared_ptr<memory> src;
+ std::shared_ptr<memory> dst;
+
+ public:
+ ReorderNode(const std::shared_ptr<memory>& src,
+ const std::shared_ptr<memory>& dst)
+ : MklNode(reorder(reorder::primitive_desc(*src, *dst)),
+ { { MKLDNN_ARG_SRC, *src },
+ { MKLDNN_ARG_DST, *dst } }),
+ src(src), dst(dst)
+ {}
+
+ std::shared_ptr<memory> getDst() const override { return dst; }
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/output_reorder.h b/thirdparty/oidn/core/output_reorder.h
new file mode 100644
index 0000000000..7918d48e15
--- /dev/null
+++ b/thirdparty/oidn/core/output_reorder.h
@@ -0,0 +1,126 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "node.h"
+#include "image.h"
+
+namespace oidn {
+
+ // Output reorder node
+ template<int K, class TransferFunction>
+ class OutputReorderNode : public Node
+ {
+ private:
+ // Source
+ std::shared_ptr<memory> src;
+ const float* srcPtr;
+ int H1;
+ int W1;
+
+ // Destination
+ Image output;
+
+ // Tile
+ int h1Begin;
+ int w1Begin;
+ int h2Begin;
+ int w2Begin;
+ int H;
+ int W;
+
+ std::shared_ptr<TransferFunction> transferFunc;
+
+ public:
+ OutputReorderNode(const std::shared_ptr<memory>& src,
+ const Image& output,
+ const std::shared_ptr<TransferFunction>& transferFunc)
+ : src(src),
+ output(output),
+ h1Begin(0), w1Begin(0),
+ h2Begin(0), w2Begin(0),
+ H(output.height), W(output.width),
+ transferFunc(transferFunc)
+ {
+ const mkldnn_memory_desc_t& srcDesc = src->get_desc().data;
+ MAYBE_UNUSED(srcDesc);
+ assert(memory_desc_matches_tag(srcDesc, mkldnn_format_tag_t(BlockedFormat<K>::nChwKc)));
+ assert(srcDesc.ndims == 4);
+ assert(srcDesc.data_type == memory::data_type::f32);
+ assert(srcDesc.dims[0] == 1);
+ // We assume output data is <= K OC
+ assert(srcDesc.dims[1] == K);
+
+ srcPtr = (float*)src->get_data_handle();
+ H1 = srcDesc.dims[2];
+ W1 = srcDesc.dims[3];
+ }
+
+ void setTile(int h1, int w1, int h2, int w2, int H, int W) override
+ {
+ h1Begin = h1;
+ w1Begin = w1;
+ h2Begin = h2;
+ w2Begin = w2;
+ this->H = H;
+ this->W = W;
+ }
+
+ void execute(stream& sm) override
+ {
+ assert(h1Begin + H <= H1);
+ assert(w1Begin + W <= W1);
+ assert(h2Begin + H <= output.height);
+ assert(w2Begin + W <= output.width);
+
+ const int C1 = K;
+
+ parallel_nd(H, [&](int h)
+ {
+ const int h1 = h + h1Begin;
+ const int h2 = h + h2Begin;
+
+ for (int w = 0; w < W; ++w)
+ {
+ const int w1 = w + w1Begin;
+ const int w2 = w + w2Begin;
+ float* dstPtr_C = (float*)output.get(h2, w2);
+
+ // Source is in nChwKc format. In this case C is 1 so this is really nhwc
+ const float* srcPtr_C = srcPtr + h1*W1*C1 + w1*C1;
+
+ #pragma unroll
+ for (int i = 0; i < 3; ++i)
+ {
+ // Load the value
+ float x = srcPtr_C[i];
+
+ // The CNN output may contain negative values or even NaNs, so it must be sanitized
+ x = maxSafe(x, 0.f);
+
+ // Apply the inverse transfer function
+ x = transferFunc->inverse(x);
+
+ // Sanitize and store the final value
+ dstPtr_C[i] = max(x, 0.f);
+ }
+ }
+ });
+ }
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/transfer_function.cpp b/thirdparty/oidn/core/transfer_function.cpp
new file mode 100644
index 0000000000..a33e3c84bc
--- /dev/null
+++ b/thirdparty/oidn/core/transfer_function.cpp
@@ -0,0 +1,95 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#include "transfer_function.h"
+
+namespace oidn {
+
+ const float LogTransferFunction::xScale = 1.f / log(LogTransferFunction::yMax + 1.f);
+ const float PQXTransferFunction::xScale = 1.f / PQXTransferFunction::pqxForward(PQXTransferFunction::yMax * PQXTransferFunction::yScale);
+
+ float AutoexposureNode::autoexposure(const Image& color)
+ {
+ assert(color.format == Format::Float3);
+ return 1.0f;
+
+ /*constexpr float key = 0.18f;
+ constexpr float eps = 1e-8f;
+ constexpr int K = 16; // downsampling amount
+
+ // Downsample the image to minimize sensitivity to noise
+ const int H = color.height; // original height
+ const int W = color.width; // original width
+ const int HK = (H + K/2) / K; // downsampled height
+ const int WK = (W + K/2) / K; // downsampled width
+
+ // Compute the average log luminance of the downsampled image
+ using Sum = std::pair<float, int>;
+
+ Sum sum =
+ tbb::parallel_reduce(
+ tbb::blocked_range2d<int>(0, HK, 0, WK),
+ Sum(0.f, 0),
+ [&](const tbb::blocked_range2d<int>& r, Sum sum) -> Sum
+ {
+ // Iterate over blocks
+ for (int i = r.rows().begin(); i != r.rows().end(); ++i)
+ {
+ for (int j = r.cols().begin(); j != r.cols().end(); ++j)
+ {
+ // Compute the average luminance in the current block
+ const int beginH = int(ptrdiff_t(i) * H / HK);
+ const int beginW = int(ptrdiff_t(j) * W / WK);
+ const int endH = int(ptrdiff_t(i+1) * H / HK);
+ const int endW = int(ptrdiff_t(j+1) * W / WK);
+
+ float L = 0.f;
+
+ for (int h = beginH; h < endH; ++h)
+ {
+ for (int w = beginW; w < endW; ++w)
+ {
+ const float* rgb = (const float*)color.get(h, w);
+
+ const float r = maxSafe(rgb[0], 0.f);
+ const float g = maxSafe(rgb[1], 0.f);
+ const float b = maxSafe(rgb[2], 0.f);
+
+ L += luminance(r, g, b);
+ }
+ }
+
+ L /= (endH - beginH) * (endW - beginW);
+
+ // Accumulate the log luminance
+ if (L > eps)
+ {
+ sum.first += log2(L);
+ sum.second++;
+ }
+ }
+ }
+
+ return sum;
+ },
+ [](Sum a, Sum b) -> Sum { return Sum(a.first+b.first, a.second+b.second); },
+ tbb::static_partitioner()
+ );
+
+ return (sum.second > 0) ? (key / exp2(sum.first / float(sum.second))) : 1.f;*/
+ }
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/transfer_function.h b/thirdparty/oidn/core/transfer_function.h
new file mode 100644
index 0000000000..35f2833092
--- /dev/null
+++ b/thirdparty/oidn/core/transfer_function.h
@@ -0,0 +1,201 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "image.h"
+#include "node.h"
+
+namespace oidn {
+
+ __forceinline float luminance(float r, float g, float b)
+ {
+ return 0.212671f * r + 0.715160f * g + 0.072169f * b;
+ }
+
+ // Color transfer function base class
+ class TransferFunction
+ {
+ public:
+ virtual ~TransferFunction() = default;
+
+ virtual float forward(float y) const = 0;
+ virtual float inverse(float x) const = 0;
+ };
+
+ // HDR transfer function base class
+ class HDRTransferFunction : public TransferFunction
+ {
+ protected:
+ static constexpr float yMax = 65504.f;
+
+ float exposure;
+ float rcpExposure;
+
+ public:
+ HDRTransferFunction(float exposure = 1.f)
+ {
+ setExposure(exposure);
+ }
+
+ void setExposure(float exposure)
+ {
+ this->exposure = exposure;
+ this->rcpExposure = (exposure != 0.f) ? (1.f / exposure) : 0.f;
+ }
+ };
+
+ // Linear transfer function (LDR)
+ class LinearTransferFunction : public TransferFunction
+ {
+ public:
+ __forceinline float forward(float y) const override
+ {
+ return min(y, 1.f);
+ }
+
+ __forceinline float inverse(float x) const override
+ {
+ return min(x, 1.f);
+ }
+ };
+
+ // 2.2 gamma transfer function (LDR)
+ class GammaTransferFunction : public TransferFunction
+ {
+ public:
+ __forceinline float forward(float y) const override
+ {
+ return min(pow(y, 1.f/2.2f), 1.f);
+ }
+
+ __forceinline float inverse(float x) const override
+ {
+ return min(pow(x, 2.2f), 1.f);
+ }
+ };
+
+ // Logarithmic transfer function (HDR)
+ // Compresses [0..65504] to [0..1]
+ class LogTransferFunction : public HDRTransferFunction
+ {
+ private:
+ static const float xScale;
+
+ public:
+ LogTransferFunction(float exposure = 1.f)
+ : HDRTransferFunction(exposure)
+ {
+ }
+
+ __forceinline float forward(float y) const override
+ {
+ return log(y * exposure + 1.f) * xScale;
+ }
+
+ __forceinline float inverse(float x) const override
+ {
+ return (exp(x * (1.f/xScale)) - 1.f) * rcpExposure;
+ }
+ };
+
+ // PQX transfer function (HDR)
+ // Compresses [0..65504] to [0..1]
+ class PQXTransferFunction : public HDRTransferFunction
+ {
+ private:
+ static constexpr float m1 = 2610.f / 4096.f / 4.f;
+ static constexpr float m2 = 2523.f / 4096.f * 128.f;
+ static constexpr float c1 = 3424.f / 4096.f;
+ static constexpr float c2 = 2413.f / 4096.f * 32.f;
+ static constexpr float c3 = 2392.f / 4096.f * 32.f;
+ static constexpr float a = 3711.f / 4096.f / 8.f;
+
+ static constexpr float yScale = 100.f / 10000.f;
+ static const float xScale;
+
+ public:
+ PQXTransferFunction(float exposure = 1.f)
+ : HDRTransferFunction(exposure)
+ {
+ }
+
+ __forceinline float forward(float y) const override
+ {
+ return pqxForward(y * exposure * yScale) * xScale;
+ }
+
+ __forceinline float inverse(float x) const override
+ {
+ return pqxInverse(x * (1.f/xScale)) * (1.f/yScale) * rcpExposure;
+ }
+
+ private:
+ static __forceinline float pqForward(float y)
+ {
+ const float yp = pow(y, m1);
+ return pow((c1 + c2 * yp) * rcp(1.f + c3 * yp), m2);
+ }
+
+ static __forceinline float pqxForward(float y)
+ {
+ if (y <= 1.f)
+ return pqForward(y);
+ else
+ return a * log(y) + 1.f;
+ }
+
+ static __forceinline float pqInverse(float x)
+ {
+ const float xp = pow(x, 1.f/m2);
+ return pow(max((xp - c1) * rcp(c2 - c3 * xp), 0.f), 1.f/m1);
+ }
+
+ static __forceinline float pqxInverse(float x)
+ {
+ if (x <= 1.f)
+ return pqInverse(x);
+ else
+ return exp((x - 1.f) * (1.f/a));
+ }
+ };
+
+ // Autoexposure node
+ class AutoexposureNode : public Node
+ {
+ private:
+ Image color;
+ std::shared_ptr<HDRTransferFunction> transferFunc;
+
+ public:
+ AutoexposureNode(const Image& color,
+ const std::shared_ptr<HDRTransferFunction>& transferFunc)
+ : color(color),
+ transferFunc(transferFunc)
+ {}
+
+ void execute(stream& sm) override
+ {
+ const float exposure = autoexposure(color);
+ //printf("exposure = %f\n", exposure);
+ transferFunc->setExposure(exposure);
+ }
+
+ private:
+ static float autoexposure(const Image& color);
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/upsample.h b/thirdparty/oidn/core/upsample.h
new file mode 100644
index 0000000000..f6cace44cd
--- /dev/null
+++ b/thirdparty/oidn/core/upsample.h
@@ -0,0 +1,92 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "node.h"
+
+namespace oidn {
+
+ // 2x2 nearest-neighbor upsampling node
+ template<int K>
+ class UpsampleNode : public Node
+ {
+ private:
+ std::shared_ptr<memory> src;
+ std::shared_ptr<memory> dst;
+
+ public:
+ UpsampleNode(const std::shared_ptr<memory>& src,
+ const std::shared_ptr<memory>& dst)
+ : src(src),
+ dst(dst)
+ {
+ const mkldnn_memory_desc_t& srcDesc = src->get_desc().data;
+ const mkldnn_memory_desc_t& dstDesc = dst->get_desc().data;
+ MAYBE_UNUSED(srcDesc);
+ MAYBE_UNUSED(dstDesc);
+ assert(memory_desc_matches_tag(srcDesc, mkldnn_format_tag_t(BlockedFormat<K>::nChwKc)));
+ assert(memory_desc_matches_tag(dstDesc, mkldnn_format_tag_t(BlockedFormat<K>::nChwKc)));
+ assert(srcDesc.ndims == 4);
+ assert(dstDesc.ndims == 4);
+ assert(srcDesc.data_type == memory::data_type::f32);
+ assert(dstDesc.data_type == memory::data_type::f32);
+ assert(srcDesc.dims[0] == 1);
+ assert(dstDesc.dims[0] == 1);
+ // 2x2 upsampling
+ assert(dstDesc.dims[2] == srcDesc.dims[2] * 2);
+ assert(dstDesc.dims[3] == srcDesc.dims[3] * 2);
+ }
+
+ void execute(stream& sm) override
+ {
+ const mkldnn_memory_desc_t& srcDesc = src->get_desc().data;
+
+ const float* srcPtr = (float*)src->get_data_handle();
+ float* dstPtr = (float*)dst->get_data_handle();
+
+ const int C = srcDesc.dims[1];
+ const int H = srcDesc.dims[2];
+ const int W = srcDesc.dims[3];
+ const int CK = C / K;
+
+ parallel_nd(CK, H, [&](int ck, int h)
+ {
+ const size_t offset = ck*H*W*K + h*W*K;
+ const float* srcPtr_line = srcPtr + offset;
+ float* dstPtr_line0 = dstPtr + offset * 4;
+ float* dstPtr_line1 = dstPtr_line0 + W*2*K; // next line
+
+ for (int w = 0; w < W; ++w)
+ {
+ #pragma unroll
+ for (int k = 0; k < K; k += 4)
+ {
+ const __m128 m = _mm_load_ps(&srcPtr_line[w*K + k]);
+
+ _mm_stream_ps(&dstPtr_line0[w*2*K + k], m);
+ _mm_stream_ps(&dstPtr_line0[w*2*K+K + k], m);
+ _mm_stream_ps(&dstPtr_line1[w*2*K + k], m);
+ _mm_stream_ps(&dstPtr_line1[w*2*K+K + k], m);
+ }
+ }
+ });
+ }
+
+ std::shared_ptr<memory> getDst() const override { return dst; }
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/core/weights_reorder.h b/thirdparty/oidn/core/weights_reorder.h
new file mode 100644
index 0000000000..6c5dacb8aa
--- /dev/null
+++ b/thirdparty/oidn/core/weights_reorder.h
@@ -0,0 +1,99 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include "node.h"
+
+namespace oidn {
+
+ // Reorders weights from oihw to padded oihw format
+ template<int K>
+ class WeightsReorderNode : public Node
+ {
+ private:
+ std::shared_ptr<memory> src;
+ std::shared_ptr<memory> dst;
+
+ public:
+ WeightsReorderNode(const std::shared_ptr<memory>& src,
+ const std::shared_ptr<memory>& dst)
+ : src(src),
+ dst(dst)
+ {
+ const mkldnn_memory_desc_t& srcDesc = src->get_desc().data;
+ const mkldnn_memory_desc_t& dstDesc = dst->get_desc().data;
+ MAYBE_UNUSED(srcDesc);
+ MAYBE_UNUSED(dstDesc);
+ assert(memory_desc_matches_tag(srcDesc, mkldnn_format_tag_t(memory::format_tag::oihw)));
+ assert(memory_desc_matches_tag(dstDesc, mkldnn_format_tag_t(memory::format_tag::oihw)));
+ assert(srcDesc.ndims == 4);
+ assert(dstDesc.ndims == 4);
+ assert(srcDesc.data_type == memory::data_type::f32);
+ assert(dstDesc.data_type == memory::data_type::f32);
+ assert(getPadded<K>(srcDesc.dims[0]) == dstDesc.dims[0]); // OC
+ assert(getPadded<K>(srcDesc.dims[1]) == dstDesc.dims[1]); // IC
+ assert(srcDesc.dims[2] == dstDesc.dims[2]);
+ assert(srcDesc.dims[3] == dstDesc.dims[3]);
+ }
+
+ void execute(stream& sm) override
+ {
+ const mkldnn_memory_desc_t& srcDesc = src->get_desc().data;
+ const mkldnn_memory_desc_t& dstDesc = dst->get_desc().data;
+
+ const float* srcPtr = (float*)src->get_data_handle();
+ float* dstPtr = (float*)dst->get_data_handle();
+
+ const int OC1 = srcDesc.dims[0];
+ const int OC2 = dstDesc.dims[0];
+ const int IC1 = srcDesc.dims[1];
+ const int IC2 = dstDesc.dims[1];
+ const int H = dstDesc.dims[2];
+ const int W = dstDesc.dims[3];
+
+ for (int oc = 0; oc < OC2; ++oc)
+ {
+ for (int ic = 0; ic < IC2; ++ic)
+ {
+ for (int h = 0; h < H; ++h)
+ {
+ for (int w = 0; w < W; ++w)
+ {
+ // Output is in oihw format
+ float* dstPtr_c = dstPtr + oc*IC2*H*W + ic*H*W + h*W + w;
+
+ if (oc < OC1 && ic < IC1)
+ {
+ // Input is in oihw format
+ const float* srcPtr_c = srcPtr + oc*IC1*H*W + ic*H*W + h*W + w;
+ *dstPtr_c = *srcPtr_c;
+ }
+ else
+ {
+ // padding
+ *dstPtr_c = 0;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ std::shared_ptr<memory> getDst() const override { return dst; }
+ };
+
+} // namespace oidn
diff --git a/thirdparty/oidn/include/OpenImageDenoise/oidn.h b/thirdparty/oidn/include/OpenImageDenoise/oidn.h
new file mode 100644
index 0000000000..57ba6baa21
--- /dev/null
+++ b/thirdparty/oidn/include/OpenImageDenoise/oidn.h
@@ -0,0 +1,214 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "version.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#ifndef OIDN_API
+#if defined(_WIN32) && !defined(OIDN_STATIC_LIB)
+# define OIDN_API __declspec(dllimport)
+#else
+# define OIDN_API
+#endif
+#endif
+
+// ----------------------------------------------------------------------------
+// Device
+// ----------------------------------------------------------------------------
+
+// Device types
+typedef enum
+{
+ OIDN_DEVICE_TYPE_DEFAULT = 0, // select device automatically
+
+ OIDN_DEVICE_TYPE_CPU = 1, // CPU device
+} OIDNDeviceType;
+
+// Error codes
+typedef enum
+{
+ OIDN_ERROR_NONE = 0, // no error occurred
+ OIDN_ERROR_UNKNOWN = 1, // an unknown error occurred
+ OIDN_ERROR_INVALID_ARGUMENT = 2, // an invalid argument was specified
+ OIDN_ERROR_INVALID_OPERATION = 3, // the operation is not allowed
+ OIDN_ERROR_OUT_OF_MEMORY = 4, // not enough memory to execute the operation
+ OIDN_ERROR_UNSUPPORTED_HARDWARE = 5, // the hardware (e.g. CPU) is not supported
+ OIDN_ERROR_CANCELLED = 6, // the operation was cancelled by the user
+} OIDNError;
+
+// Error callback function
+typedef void (*OIDNErrorFunction)(void* userPtr, OIDNError code, const char* message);
+
+// Device handle
+typedef struct OIDNDeviceImpl* OIDNDevice;
+
+// Creates a new device.
+OIDN_API OIDNDevice oidnNewDevice(OIDNDeviceType type);
+
+// Retains the device (increments the reference count).
+OIDN_API void oidnRetainDevice(OIDNDevice device);
+
+// Releases the device (decrements the reference count).
+OIDN_API void oidnReleaseDevice(OIDNDevice device);
+
+// Sets a boolean parameter of the device.
+OIDN_API void oidnSetDevice1b(OIDNDevice device, const char* name, bool value);
+
+// Sets an integer parameter of the device.
+OIDN_API void oidnSetDevice1i(OIDNDevice device, const char* name, int value);
+
+// Gets a boolean parameter of the device.
+OIDN_API bool oidnGetDevice1b(OIDNDevice device, const char* name);
+
+// Gets an integer parameter of the device (e.g. "version").
+OIDN_API int oidnGetDevice1i(OIDNDevice device, const char* name);
+
+// Sets the error callback function of the device.
+OIDN_API void oidnSetDeviceErrorFunction(OIDNDevice device, OIDNErrorFunction func, void* userPtr);
+
+// Returns the first unqueried error code stored in the device for the current
+// thread, optionally also returning a string message (if not NULL), and clears
+// the stored error. Can be called with a NULL device as well to check why a
+// device creation failed.
+OIDN_API OIDNError oidnGetDeviceError(OIDNDevice device, const char** outMessage);
+
+// Commits all previous changes to the device.
+// Must be called before first using the device (e.g. creating filters).
+OIDN_API void oidnCommitDevice(OIDNDevice device);
+
+// ----------------------------------------------------------------------------
+// Buffer
+// ----------------------------------------------------------------------------
+
+// Formats for images and other data stored in buffers
+typedef enum
+{
+ OIDN_FORMAT_UNDEFINED = 0,
+
+ // 32-bit single-precision floating point scalar and vector formats
+ OIDN_FORMAT_FLOAT = 1,
+ OIDN_FORMAT_FLOAT2 = 2,
+ OIDN_FORMAT_FLOAT3 = 3,
+ OIDN_FORMAT_FLOAT4 = 4,
+} OIDNFormat;
+
+// Access modes for mapping buffers
+typedef enum
+{
+ OIDN_ACCESS_READ = 0, // read-only access
+ OIDN_ACCESS_WRITE = 1, // write-only access
+ OIDN_ACCESS_READ_WRITE = 2, // read and write access
+ OIDN_ACCESS_WRITE_DISCARD = 3, // write-only access, previous contents discarded
+} OIDNAccess;
+
+// Buffer handle
+typedef struct OIDNBufferImpl* OIDNBuffer;
+
+// Creates a new buffer (data allocated and owned by the device).
+OIDN_API OIDNBuffer oidnNewBuffer(OIDNDevice device, size_t byteSize);
+
+// Creates a new shared buffer (data allocated and owned by the user).
+OIDN_API OIDNBuffer oidnNewSharedBuffer(OIDNDevice device, void* ptr, size_t byteSize);
+
+// Maps a region of the buffer to host memory.
+// If byteSize is 0, the maximum available amount of memory will be mapped.
+OIDN_API void* oidnMapBuffer(OIDNBuffer buffer, OIDNAccess access, size_t byteOffset, size_t byteSize);
+
+// Unmaps a region of the buffer.
+// mappedPtr must be a pointer returned by a previous call to oidnMapBuffer.
+OIDN_API void oidnUnmapBuffer(OIDNBuffer buffer, void* mappedPtr);
+
+// Retains the buffer (increments the reference count).
+OIDN_API void oidnRetainBuffer(OIDNBuffer buffer);
+
+// Releases the buffer (decrements the reference count).
+OIDN_API void oidnReleaseBuffer(OIDNBuffer buffer);
+
+// ----------------------------------------------------------------------------
+// Filter
+// ----------------------------------------------------------------------------
+
+// Progress monitor callback function
+typedef bool (*OIDNProgressMonitorFunction)(void* userPtr, double n);
+
+// Filter handle
+typedef struct OIDNFilterImpl* OIDNFilter;
+
+// Creates a new filter of the specified type (e.g. "RT").
+OIDN_API OIDNFilter oidnNewFilter(OIDNDevice device, const char* type);
+
+// Retains the filter (increments the reference count).
+OIDN_API void oidnRetainFilter(OIDNFilter filter);
+
+// Releases the filter (decrements the reference count).
+OIDN_API void oidnReleaseFilter(OIDNFilter filter);
+
+// Sets an image parameter of the filter (stored in a buffer).
+// If bytePixelStride and/or byteRowStride are zero, these will be computed automatically.
+OIDN_API void oidnSetFilterImage(OIDNFilter filter, const char* name,
+ OIDNBuffer buffer, OIDNFormat format,
+ size_t width, size_t height,
+ size_t byteOffset,
+ size_t bytePixelStride, size_t byteRowStride);
+
+// Sets an image parameter of the filter (owned by the user).
+// If bytePixelStride and/or byteRowStride are zero, these will be computed automatically.
+OIDN_API void oidnSetSharedFilterImage(OIDNFilter filter, const char* name,
+ void* ptr, OIDNFormat format,
+ size_t width, size_t height,
+ size_t byteOffset,
+ size_t bytePixelStride, size_t byteRowStride);
+
+// Sets a boolean parameter of the filter.
+OIDN_API void oidnSetFilter1b(OIDNFilter filter, const char* name, bool value);
+
+// Gets a boolean parameter of the filter.
+OIDN_API bool oidnGetFilter1b(OIDNFilter filter, const char* name);
+
+// Sets an integer parameter of the filter.
+OIDN_API void oidnSetFilter1i(OIDNFilter filter, const char* name, int value);
+
+// Gets an integer parameter of the filter.
+OIDN_API int oidnGetFilter1i(OIDNFilter filter, const char* name);
+
+// Sets a float parameter of the filter.
+OIDN_API void oidnSetFilter1f(OIDNFilter filter, const char* name, float value);
+
+// Gets a float parameter of the filter.
+OIDN_API float oidnGetFilter1f(OIDNFilter filter, const char* name);
+
+// Sets the progress monitor callback function of the filter.
+OIDN_API void oidnSetFilterProgressMonitorFunction(OIDNFilter filter, OIDNProgressMonitorFunction func, void* userPtr);
+
+// Commits all previous changes to the filter.
+// Must be called before first executing the filter.
+OIDN_API void oidnCommitFilter(OIDNFilter filter);
+
+// Executes the filter.
+OIDN_API void oidnExecuteFilter(OIDNFilter filter);
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/thirdparty/oidn/include/OpenImageDenoise/oidn.hpp b/thirdparty/oidn/include/OpenImageDenoise/oidn.hpp
new file mode 100644
index 0000000000..9f95a56fe1
--- /dev/null
+++ b/thirdparty/oidn/include/OpenImageDenoise/oidn.hpp
@@ -0,0 +1,468 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#include <algorithm>
+#include "oidn.h"
+
+namespace oidn {
+
+ // --------------------------------------------------------------------------
+ // Buffer
+ // --------------------------------------------------------------------------
+
+ // Formats for images and other data stored in buffers
+ enum class Format
+ {
+ Undefined = OIDN_FORMAT_UNDEFINED,
+
+ // 32-bit single-precision floating point scalar and vector formats
+ Float = OIDN_FORMAT_FLOAT,
+ Float2 = OIDN_FORMAT_FLOAT2,
+ Float3 = OIDN_FORMAT_FLOAT3,
+ Float4 = OIDN_FORMAT_FLOAT4,
+ };
+
+ // Access modes for mapping buffers
+ enum class Access
+ {
+ Read = OIDN_ACCESS_READ, // read-only access
+ Write = OIDN_ACCESS_WRITE, // write-only access
+ ReadWrite = OIDN_ACCESS_READ_WRITE, // read and write access
+ WriteDiscard = OIDN_ACCESS_WRITE_DISCARD, // write-only access, previous contents discarded
+ };
+
+ // Buffer object with automatic reference counting
+ class BufferRef
+ {
+ private:
+ OIDNBuffer handle;
+
+ public:
+ BufferRef() : handle(nullptr) {}
+ BufferRef(OIDNBuffer handle) : handle(handle) {}
+
+ BufferRef(const BufferRef& other) : handle(other.handle)
+ {
+ if (handle)
+ oidnRetainBuffer(handle);
+ }
+
+ BufferRef(BufferRef&& other) : handle(other.handle)
+ {
+ other.handle = nullptr;
+ }
+
+ BufferRef& operator =(const BufferRef& other)
+ {
+ if (&other != this)
+ {
+ if (other.handle)
+ oidnRetainBuffer(other.handle);
+ if (handle)
+ oidnReleaseBuffer(handle);
+ handle = other.handle;
+ }
+ return *this;
+ }
+
+ BufferRef& operator =(BufferRef&& other)
+ {
+ std::swap(handle, other.handle);
+ return *this;
+ }
+
+ BufferRef& operator =(OIDNBuffer other)
+ {
+ if (other)
+ oidnRetainBuffer(other);
+ if (handle)
+ oidnReleaseBuffer(handle);
+ handle = other;
+ return *this;
+ }
+
+ ~BufferRef()
+ {
+ if (handle)
+ oidnReleaseBuffer(handle);
+ }
+
+ OIDNBuffer getHandle() const
+ {
+ return handle;
+ }
+
+ operator bool() const
+ {
+ return handle != nullptr;
+ }
+
+ // Maps a region of the buffer to host memory.
+ // If byteSize is 0, the maximum available amount of memory will be mapped.
+ void* map(Access access = Access::ReadWrite, size_t byteOffset = 0, size_t byteSize = 0)
+ {
+ return oidnMapBuffer(handle, (OIDNAccess)access, byteOffset, byteSize);
+ }
+
+ // Unmaps a region of the buffer.
+ // mappedPtr must be a pointer returned by a previous call to map.
+ void unmap(void* mappedPtr)
+ {
+ oidnUnmapBuffer(handle, mappedPtr);
+ }
+ };
+
+ // --------------------------------------------------------------------------
+ // Filter
+ // --------------------------------------------------------------------------
+
+ // Progress monitor callback function
+ typedef bool (*ProgressMonitorFunction)(void* userPtr, double n);
+
+ // Filter object with automatic reference counting
+ class FilterRef
+ {
+ private:
+ OIDNFilter handle;
+
+ public:
+ FilterRef() : handle(nullptr) {}
+ FilterRef(OIDNFilter handle) : handle(handle) {}
+
+ FilterRef(const FilterRef& other) : handle(other.handle)
+ {
+ if (handle)
+ oidnRetainFilter(handle);
+ }
+
+ FilterRef(FilterRef&& other) : handle(other.handle)
+ {
+ other.handle = nullptr;
+ }
+
+ FilterRef& operator =(const FilterRef& other)
+ {
+ if (&other != this)
+ {
+ if (other.handle)
+ oidnRetainFilter(other.handle);
+ if (handle)
+ oidnReleaseFilter(handle);
+ handle = other.handle;
+ }
+ return *this;
+ }
+
+ FilterRef& operator =(FilterRef&& other)
+ {
+ std::swap(handle, other.handle);
+ return *this;
+ }
+
+ FilterRef& operator =(OIDNFilter other)
+ {
+ if (other)
+ oidnRetainFilter(other);
+ if (handle)
+ oidnReleaseFilter(handle);
+ handle = other;
+ return *this;
+ }
+
+ ~FilterRef()
+ {
+ if (handle)
+ oidnReleaseFilter(handle);
+ }
+
+ OIDNFilter getHandle() const
+ {
+ return handle;
+ }
+
+ operator bool() const
+ {
+ return handle != nullptr;
+ }
+
+ // Sets an image parameter of the filter (stored in a buffer).
+ void setImage(const char* name,
+ const BufferRef& buffer, Format format,
+ size_t width, size_t height,
+ size_t byteOffset = 0,
+ size_t bytePixelStride = 0, size_t byteRowStride = 0)
+ {
+ oidnSetFilterImage(handle, name,
+ buffer.getHandle(), (OIDNFormat)format,
+ width, height,
+ byteOffset,
+ bytePixelStride, byteRowStride);
+ }
+
+ // Sets an image parameter of the filter (owned by the user).
+ void setImage(const char* name,
+ void* ptr, Format format,
+ size_t width, size_t height,
+ size_t byteOffset = 0,
+ size_t bytePixelStride = 0, size_t byteRowStride = 0)
+ {
+ oidnSetSharedFilterImage(handle, name,
+ ptr, (OIDNFormat)format,
+ width, height,
+ byteOffset,
+ bytePixelStride, byteRowStride);
+ }
+
+ // Sets a boolean parameter of the filter.
+ void set(const char* name, bool value)
+ {
+ oidnSetFilter1b(handle, name, value);
+ }
+
+ // Sets an integer parameter of the filter.
+ void set(const char* name, int value)
+ {
+ oidnSetFilter1i(handle, name, value);
+ }
+
+ // Sets a float parameter of the filter.
+ void set(const char* name, float value)
+ {
+ oidnSetFilter1f(handle, name, value);
+ }
+
+ // Gets a parameter of the filter.
+ template<typename T>
+ T get(const char* name);
+
+ // Sets the progress monitor callback function of the filter.
+ void setProgressMonitorFunction(ProgressMonitorFunction func, void* userPtr = nullptr)
+ {
+ oidnSetFilterProgressMonitorFunction(handle, (OIDNProgressMonitorFunction)func, userPtr);
+ }
+
+ // Commits all previous changes to the filter.
+ void commit()
+ {
+ oidnCommitFilter(handle);
+ }
+
+ // Executes the filter.
+ void execute()
+ {
+ oidnExecuteFilter(handle);
+ }
+ };
+
+ // Gets a boolean parameter of the filter.
+ template<>
+ inline bool FilterRef::get(const char* name)
+ {
+ return oidnGetFilter1b(handle, name);
+ }
+
+ // Gets an integer parameter of the filter.
+ template<>
+ inline int FilterRef::get(const char* name)
+ {
+ return oidnGetFilter1i(handle, name);
+ }
+
+ // Gets a float parameter of the filter.
+ template<>
+ inline float FilterRef::get(const char* name)
+ {
+ return oidnGetFilter1f(handle, name);
+ }
+
+ // --------------------------------------------------------------------------
+ // Device
+ // --------------------------------------------------------------------------
+
+ // Device types
+ enum class DeviceType
+ {
+ Default = OIDN_DEVICE_TYPE_DEFAULT, // select device automatically
+
+ CPU = OIDN_DEVICE_TYPE_CPU, // CPU device
+ };
+
+ // Error codes
+ enum class Error
+ {
+ None = OIDN_ERROR_NONE, // no error occurred
+ Unknown = OIDN_ERROR_UNKNOWN, // an unknown error occurred
+ InvalidArgument = OIDN_ERROR_INVALID_ARGUMENT, // an invalid argument was specified
+ InvalidOperation = OIDN_ERROR_INVALID_OPERATION, // the operation is not allowed
+ OutOfMemory = OIDN_ERROR_OUT_OF_MEMORY, // not enough memory to execute the operation
+ UnsupportedHardware = OIDN_ERROR_UNSUPPORTED_HARDWARE, // the hardware (e.g. CPU) is not supported
+ Cancelled = OIDN_ERROR_CANCELLED, // the operation was cancelled by the user
+ };
+
+ // Error callback function
+ typedef void (*ErrorFunction)(void* userPtr, Error code, const char* message);
+
+ // Device object with automatic reference counting
+ class DeviceRef
+ {
+ private:
+ OIDNDevice handle;
+
+ public:
+ DeviceRef() : handle(nullptr) {}
+ DeviceRef(OIDNDevice handle) : handle(handle) {}
+
+ DeviceRef(const DeviceRef& other) : handle(other.handle)
+ {
+ if (handle)
+ oidnRetainDevice(handle);
+ }
+
+ DeviceRef(DeviceRef&& other) : handle(other.handle)
+ {
+ other.handle = nullptr;
+ }
+
+ DeviceRef& operator =(const DeviceRef& other)
+ {
+ if (&other != this)
+ {
+ if (other.handle)
+ oidnRetainDevice(other.handle);
+ if (handle)
+ oidnReleaseDevice(handle);
+ handle = other.handle;
+ }
+ return *this;
+ }
+
+ DeviceRef& operator =(DeviceRef&& other)
+ {
+ std::swap(handle, other.handle);
+ return *this;
+ }
+
+ DeviceRef& operator =(OIDNDevice other)
+ {
+ if (other)
+ oidnRetainDevice(other);
+ if (handle)
+ oidnReleaseDevice(handle);
+ handle = other;
+ return *this;
+ }
+
+ ~DeviceRef()
+ {
+ if (handle)
+ oidnReleaseDevice(handle);
+ }
+
+ OIDNDevice getHandle() const
+ {
+ return handle;
+ }
+
+ operator bool() const
+ {
+ return handle != nullptr;
+ }
+
+ // Sets a boolean parameter of the device.
+ void set(const char* name, bool value)
+ {
+ oidnSetDevice1b(handle, name, value);
+ }
+
+ // Sets an integer parameter of the device.
+ void set(const char* name, int value)
+ {
+ oidnSetDevice1i(handle, name, value);
+ }
+
+ // Gets a parameter of the device.
+ template<typename T>
+ T get(const char* name);
+
+ // Sets the error callback function of the device.
+ void setErrorFunction(ErrorFunction func, void* userPtr = nullptr)
+ {
+ oidnSetDeviceErrorFunction(handle, (OIDNErrorFunction)func, userPtr);
+ }
+
+ // Returns the first unqueried error code and clears the stored error.
+ // Can be called for a null device as well to check why a device creation failed.
+ Error getError()
+ {
+ return (Error)oidnGetDeviceError(handle, nullptr);
+ }
+
+ // Returns the first unqueried error code and string message, and clears the stored error.
+ // Can be called for a null device as well to check why a device creation failed.
+ Error getError(const char*& outMessage)
+ {
+ return (Error)oidnGetDeviceError(handle, &outMessage);
+ }
+
+ // Commits all previous changes to the device.
+ // Must be called before first using the device (e.g. creating filters).
+ void commit()
+ {
+ oidnCommitDevice(handle);
+ }
+
+ // Creates a new buffer (data allocated and owned by the device).
+ BufferRef newBuffer(size_t byteSize)
+ {
+ return oidnNewBuffer(handle, byteSize);
+ }
+
+ // Creates a new shared buffer (data allocated and owned by the user).
+ BufferRef newBuffer(void* ptr, size_t byteSize)
+ {
+ return oidnNewSharedBuffer(handle, ptr, byteSize);
+ }
+
+ // Creates a new filter of the specified type (e.g. "RT").
+ FilterRef newFilter(const char* type)
+ {
+ return oidnNewFilter(handle, type);
+ }
+ };
+
+ // Gets a boolean parameter of the device.
+ template<>
+ inline bool DeviceRef::get(const char* name)
+ {
+ return oidnGetDevice1b(handle, name);
+ }
+
+ // Gets an integer parameter of the device (e.g. "version").
+ template<>
+ inline int DeviceRef::get(const char* name)
+ {
+ return oidnGetDevice1i(handle, name);
+ }
+
+ // Creates a new device.
+ inline DeviceRef newDevice(DeviceType type = DeviceType::Default)
+ {
+ return DeviceRef(oidnNewDevice((OIDNDeviceType)type));
+ }
+
+} // namespace oidn
diff --git a/thirdparty/oidn/include/OpenImageDenoise/version.h b/thirdparty/oidn/include/OpenImageDenoise/version.h
new file mode 100644
index 0000000000..66b347c992
--- /dev/null
+++ b/thirdparty/oidn/include/OpenImageDenoise/version.h
@@ -0,0 +1,23 @@
+// ======================================================================== //
+// Copyright 2009-2019 Intel Corporation //
+// //
+// Licensed under the Apache License, Version 2.0 (the "License"); //
+// you may not use this file except in compliance with the License. //
+// You may obtain a copy of the License at //
+// //
+// http://www.apache.org/licenses/LICENSE-2.0 //
+// //
+// Unless required by applicable law or agreed to in writing, software //
+// distributed under the License is distributed on an "AS IS" BASIS, //
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
+// See the License for the specific language governing permissions and //
+// limitations under the License. //
+// ======================================================================== //
+
+#pragma once
+
+#define OIDN_VERSION_MAJOR 1
+#define OIDN_VERSION_MINOR 1
+#define OIDN_VERSION_PATCH 0
+#define OIDN_VERSION 10100
+#define OIDN_VERSION_STRING "1.1.0"
diff --git a/thirdparty/oidn/mkl-dnn/LICENSE b/thirdparty/oidn/mkl-dnn/LICENSE
new file mode 100644
index 0000000000..d13f7b7ca0
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/LICENSE
@@ -0,0 +1,214 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ ============================================================================
+
+ Intel MKL-DNN includes components with separate copyright
+ notices and license terms.
+
+ XByak, 3-clause BSD license
+ Copyright (c) 2007 MITSUNARI Shigeo
+ See full copyright notice and license text in src/cpu/xbyak/COPYRIGHT
+
+ gtest, 3-clause BSD license
+ Copyright 2008, Google Inc.
+ See full copyright notice and license text in tests/gtests/gtest/LICENSE
diff --git a/thirdparty/oidn/mkl-dnn/include/mkldnn.h b/thirdparty/oidn/mkl-dnn/include/mkldnn.h
new file mode 100644
index 0000000000..9b64994922
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/include/mkldnn.h
@@ -0,0 +1,1771 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MKLDNN_H
+#define MKLDNN_H
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+/* All symbols shall be internal unless marked as MKLDNN_API */
+#if defined _WIN32 || defined __CYGWIN__
+# define MKLDNN_HELPER_DLL_IMPORT __declspec(dllimport)
+# define MKLDNN_HELPER_DLL_EXPORT __declspec(dllexport)
+#else
+# if __GNUC__ >= 4
+# define MKLDNN_HELPER_DLL_IMPORT __attribute__ ((visibility ("default")))
+# define MKLDNN_HELPER_DLL_EXPORT __attribute__ ((visibility ("default")))
+# else
+# define MKLDNN_HELPER_DLL_IMPORT
+# define MKLDNN_HELPER_DLL_EXPORT
+# endif
+#endif
+
+#ifdef MKLDNN_DLL
+# ifdef MKLDNN_DLL_EXPORTS
+# define MKLDNN_API MKLDNN_HELPER_DLL_EXPORT
+# else
+# define MKLDNN_API MKLDNN_HELPER_DLL_IMPORT
+# endif
+#else
+# define MKLDNN_API
+#endif
+
+#if defined (__GNUC__)
+# define MKLDNN_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER)
+# define MKLDNN_DEPRECATED __declspec(deprecated)
+#else
+# define MKLDNN_DEPRECATED
+#endif
+
+#include "mkldnn_types.h"
+#include "mkldnn_version.h"
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup c_api C API
+ * @{ */
+
+/** @addtogroup c_api_primitive Primitive operations
+ * @{ */
+
+/** @addtogroup c_api_primitive_common Common primitive operations
+ * @{ */
+
+/** Creates a primitive descriptor @p iterator for given @p op_desc, @p attr,
+ * @p engine, and optionally a hint primitive descriptor from forward
+ * propagation (required for backward propagation). Pass @c NULL for forward
+ * propagation.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_desc_iterator_create(
+ mkldnn_primitive_desc_iterator_t *iterator,
+ const_mkldnn_op_desc_t op_desc, const_mkldnn_primitive_attr_t attr,
+ mkldnn_engine_t engine,
+ const_mkldnn_primitive_desc_t hint_forward_primitive_desc);
+
+/** Iterates over primitive descriptors. Returns #mkldnn_iterator_ends if no
+ * more primitive descriptors are available. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_desc_iterator_next(
+ mkldnn_primitive_desc_iterator_t iterator);
+
+/** Fetches the current primitive descriptor.
+ *
+ * @note
+ * The user should delete the fetched primitive descriptor using
+ * mkldnn_primitive_desc_destroy() once it is no longer needed. */
+mkldnn_primitive_desc_t MKLDNN_API mkldnn_primitive_desc_iterator_fetch(
+ const_mkldnn_primitive_desc_iterator_t iterator);
+
+/** Deletes a primitive descriptor @p iterator */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_desc_iterator_destroy(
+ mkldnn_primitive_desc_iterator_t iterator);
+
+/** Creates a @p primitive_desc using @p op_desc, @p attr, @p engine, and
+ * optionally a hint primitive descriptor from forward propagation. The call is
+ * equivalent to creating a primitive descriptor iterator, immediately fetching
+ * a primitive descriptor, and then destroying the iterator. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_desc_create(
+ mkldnn_primitive_desc_t *primitive_desc,
+ const_mkldnn_op_desc_t op_desc, const_mkldnn_primitive_attr_t attr,
+ mkldnn_engine_t engine,
+ const_mkldnn_primitive_desc_t hint_forward_primitive_desc);
+
+/** Makes a copy of a @p primitive_desc. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_desc_clone(
+ mkldnn_primitive_desc_t *primitive_desc,
+ const_mkldnn_primitive_desc_t existing_primitive_desc);
+
+/** Returns a constant reference to the attribute of a @p primitive_desc.
+ *
+ * @warning
+ * The user should not destroy the obtained @p attr.
+ *
+ * @warning
+ * The lifetime of an @p attr is the same as that of a @p primitive_desc,
+ * so it is illegal to use the @p attr once @p primitive_desc has been
+ * destroyed. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_desc_get_attr(
+ const_mkldnn_primitive_desc_t primitive_desc,
+ const_mkldnn_primitive_attr_t *attr);
+
+/** Deletes a @p primitive_desc. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_desc_destroy(
+ mkldnn_primitive_desc_t primitive_desc);
+
+/** Queries primitive descriptor
+ *
+ * One of the most typical use cases is to query a convolution primitive
+ * descriptor created with source, weights, and destination formats equal
+ * to #mkldnn_format_tag_any about the corresponding memory descriptors
+ * (@p what equals #mkldnn_query_src_md, #mkldnn_query_weights_md, and
+ * #mkldnn_query_dst_md respectively) to be able to prepare memory and
+ * create reorders if required.
+ *
+ * Another quite typical use case is to query an operation primitive
+ * descriptor for a workspace (@p what equals #mkldnn_query_workspace_md).
+ * The returned status #mkldnn_not_required indicates that a workspace is
+ * not required.
+ *
+ * A few other possibilities:
+ * - query an operation primitive descriptor for the underlying operation
+ * descriptor (#mkldnn_query_convolution_d, #mkldnn_query_eltwise_d,
+ * #mkldnn_query_rnn_d, etc.)
+ * - query an operation primitive descriptor for the implementation
+ * information string (#mkldnn_query_impl_info_str)
+ * - query an operation primitive descriptor for the number of inputs and
+ * outputs (#mkldnn_query_num_of_inputs_s32 and
+ * #mkldnn_query_num_of_outputs_s32 respectively)
+ *
+ * @sa mkldnn_query_t for more options
+ */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_desc_query(
+ const_mkldnn_primitive_desc_t primitive_desc, mkldnn_query_t what,
+ int index, void *result);
+
+/** Queries primitive descriptor for memory descriptor
+ *
+ * @returns NULL in case of any error.
+ *
+ * This is just a specialized version of mkldnn_primitive_desc_query
+ * used for convenience.
+ */
+const mkldnn_memory_desc_t MKLDNN_API *mkldnn_primitive_desc_query_md(
+ const_mkldnn_primitive_desc_t primitive_desc, mkldnn_query_t what,
+ int index);
+
+/** Queries primitive descriptor for signed 32bit int
+ *
+ * @returns 0 in case of any error (in particular if the queried entity is
+ * not of type int32_t). Note that 0 might also be the actual returned
+ * value.
+ *
+ * This is just a specialized version of mkldnn_primitive_desc_query
+ * used for convenience.
+ */
+int MKLDNN_API mkldnn_primitive_desc_query_s32(
+ const_mkldnn_primitive_desc_t primitive_desc, mkldnn_query_t what,
+ int index);
+
+/** Creates a @p primitive using a @p primitive_desc descriptor. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_create(
+ mkldnn_primitive_t *primitive,
+ const_mkldnn_primitive_desc_t primitive_desc);
+
+/** Executes a @p primitive using a @p stream, and @p nargs arguments
+ * @p args. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_execute(
+ const_mkldnn_primitive_t primitive, mkldnn_stream_t stream,
+ int nargs, const mkldnn_exec_arg_t *args);
+
+/** Retrieves a reference to the @p primitive_desc descriptor of given @p
+ * primitive.
+ *
+ * @warning
+ * The returned object must not be destroyed by the user. The @c const
+ * qualifier of the returned object prevents such attempts. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_get_primitive_desc(
+ const_mkldnn_primitive_t primitive,
+ const_mkldnn_primitive_desc_t *primitive_desc);
+
+/** Deletes a @p primitive. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_destroy(
+ mkldnn_primitive_t primitive);
+
+/** @} */
+
+/** @addtogroup c_api_attributes Attributes
+ * An extension for controlling primitive behavior.
+ * @{ */
+
+/** Creates an empty (default) @p attr attribute. All the parameters are set to
+ * default values.
+ *
+ * An empty attribute is used in primitive descriptor creation whenever it
+ * is not passed explicitly, e.g. in mkldnn_primitive_desc_create.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_attr_create(
+ mkldnn_primitive_attr_t *attr);
+
+/** Makes a copy of an @p existing_attr. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_attr_clone(
+ mkldnn_primitive_attr_t *attr,
+ const_mkldnn_primitive_attr_t existing_attr);
+
+/** Deletes an @p attr. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_attr_destroy(
+ mkldnn_primitive_attr_t attr);
+
+/** Returns the scratchpad @p mode set in the attribute @p attr */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_attr_get_scratchpad_mode(
+ const_mkldnn_primitive_attr_t attr, mkldnn_scratchpad_mode_t *mode);
+
+/** Sets scratchpad @p mode.
+ *
+ * The possible values are: #mkldnn_scratchpad_mode_library (default) and
+ * #mkldnn_scratchpad_mode_user. */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_attr_set_scratchpad_mode(
+ mkldnn_primitive_attr_t attr, mkldnn_scratchpad_mode_t mode);
+
+/** Returns @p count, correspondence scale @p mask, and a pointer to a constant
+ * floating point array of output @p scales for given @p attr, previously set
+ * by mkldnn_primitive_attr_set_output_scales.
+ *
+ * @warning
+ * The @p scales array points to the internal @p attr field, so the user
+ * should not modify or destroy @p scales.
+ *
+ * @warning
+ * The lifetime of @p scales is the same as that of the @p attr to which it
+ * belongs, so it is illegal to use @p scales after @p attr is destroyed.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_attr_get_output_scales(
+ const_mkldnn_primitive_attr_t attr, mkldnn_dim_t *count, int *mask,
+ const float **scales);
+
+/** Sets output @p scales for primitive operations. The number of elements @p
+ * count and correspondence scale @p mask are stored for future use.
+ *
+ * The @p mask argument defines the correspondence between the output tensor
+ * dimensions and the @p scales array. Set the i-th bit of @p mask to 1 to use a
+ * dedicated scaling factor for each slice of the output tensor over the i-th
+ * dimension. Set @p mask to 0 to use a common scaling factor for the whole
+ * output tensor.
+ *
+ * @note
+ * The dimension order is always native and does not depend on the actual
+ * layout used. Examples:
+ * - 2D dimensional data the order of dimensions is always: (n, c)
+ * - 4D dimensional data the order is always: (n, c, h, w)
+ * - 5D dimensional weights the order is always: (g, oc, ic, kh, kw)
+ *
+ * Example usage:
+ * @code
+ * int mb = 32, oc = 32, oh = 14, ow = 14; // convolution output params
+ * float scales[oc] = { ... }; // unique output scales per output channel
+ * int oc_dim = 1; // mb_dim = 0, channel_dim = 1, height_dim = 2, ...
+ *
+ * mkldnn_convolution_desc_t cd; // create & configure convolution op_desc
+ *
+ * mkldnn_primitive_attr_t attr;
+ * mkldnn_primitive_attr_create(&attr); // create default attributes
+ * mkldnn_primitive_attr_set_output_scales(attr, oc, 1 << oc_dim, scales);
+ *
+ * mkldnn_primitive_desc_t cpd;
+ * mkldnn_primitive_desc_create(&cpd, &cd, attr, NULL);
+ * @endcode
+ *
+ * @note
+ * There is no way to check that @p count corresponds to @p mask until an
+ * actual primitive descriptor is created, so it is the user's
+ * responsibility to set proper values. The following formula must hold:
+ *
+ * \f[count = \prod\limits_{d \in mask} output.dims[d]\f]
+ */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_attr_set_output_scales(
+ mkldnn_primitive_attr_t attr, mkldnn_dim_t count, int mask,
+ const float *scales);
+
+/** Returns @p post_ops for given @p attr.
+ *
+ * @warning
+ * @p post_ops points to the internal @p attr field, so the user should not
+ * modify or destroy @p post_ops. Also, the lifetime of @p post_ops is the
+ * same as that of the @p attr it belongs to, so it is illegal to use @p
+ * post_ops after @p attr has been destroyed.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_attr_get_post_ops(
+ const_mkldnn_primitive_attr_t attr, const_mkldnn_post_ops_t *post_ops);
+
+/** Sets configured @p post_ops to an attribute @p attr for future use (when
+ * primitive descriptor is being created).
+ *
+ * @note
+ * At this point in time, there is no way to check whether the primitive
+ * descriptor does or does not support a given sequence of post operations.
+ * Therefore the user should handle an error that might occur at the
+ * mkldnn_primitive_desc_create call.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_attr_set_post_ops(
+ mkldnn_primitive_attr_t attr, const_mkldnn_post_ops_t post_ops);
+
+/** @addtogroup c_api_attributes_post_ops Sequence of post operations
+ * An extension for performing extra operations after a base operation.
+ * @{ */
+
+/** Creates an empty sequence of post operations @p post_ops. */
+mkldnn_status_t MKLDNN_API mkldnn_post_ops_create(mkldnn_post_ops_t *post_ops);
+
+/** Deletes a @p post_ops sequence. */
+mkldnn_status_t MKLDNN_API mkldnn_post_ops_destroy(mkldnn_post_ops_t post_ops);
+
+/** Returns the @p length of post operations for given @p post_ops. */
+int MKLDNN_API mkldnn_post_ops_len(const_mkldnn_post_ops_t post_ops);
+
+/** Returns the type of post operation with index @p index in given
+ * @p post_ops. In case of error, returns #mkldnn_undefined_primitive. */
+mkldnn_primitive_kind_t MKLDNN_API mkldnn_post_ops_get_kind(
+ const_mkldnn_post_ops_t post_ops, int index);
+
+/** Appends accumulation (sum) post operation to the @p post_ops. Prior to
+ * accumulating the result, the previous value would be multiplied by @p scale.
+ *
+ * The kind of this post operation is #mkldnn_sum.
+ *
+ * This feature might improve performance for cases like residual learning
+ * blocks, where the result of convolution is accumulated to the previously
+ * computed activations. The parameter @p scale might be extreme for the
+ * integer-based computations when the result and previous activations have
+ * different logical scaling factors.
+ *
+ * In the simplest case when the accumulation is the only post operation, the
+ * computations would be:
+ * dst[] <- scale * dst[] + op(...) // instead of dst[] <- op(...)
+ *
+ * @note
+ * This post operation (as well as all the others) disregards the original
+ * layout of the destination; that is, the layout of the original
+ * destination is expected to be the same as the layout of the stored
+ * destination.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_post_ops_append_sum(
+ mkldnn_post_ops_t post_ops, float scale);
+
+/** Gets the parameters of the accumulation (sum) post operation with index
+ * @p index in the sequence of @p post_ops.
+ *
+ * @note
+ * If index @p index would not correspond to the accumulation post
+ * operation, the function returns #mkldnn_invalid_arguments.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_post_ops_get_params_sum(
+ const_mkldnn_post_ops_t post_ops, int index, float *scale);
+
+/** Appends eltwise post operation to the @p post_ops with given parameters
+ * @p kind, @p alpha, and @p beta (@sa mkldnn_eltwise_forward_desc_init and
+ * mkldnn_eltwise_desc_t).
+ *
+ * The kind of this post operation is #mkldnn_eltwise.
+ *
+ * In the simplest case when the eltwise is the only post operation, the
+ * computations would be:
+ * dst[] <- scale * eltwise_op ( op(...) ) // instead of dst[] <- op(...)
+ * where eltwise_op is configured with the given parameters.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_post_ops_append_eltwise(
+ mkldnn_post_ops_t post_ops, float scale, mkldnn_alg_kind_t alg,
+ float alpha, float beta);
+
+/** Gets the eltwise parameters of the post operation with index @p index in
+ * the sequence of @p post_ops.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_post_ops_get_params_eltwise(
+ const_mkldnn_post_ops_t post_ops, int index, float *scale,
+ mkldnn_alg_kind_t *alg, float *alpha, float *beta);
+
+/** @} */
+
+/** @} */
+
+/** @addtogroup c_api_memory Memory
+ * A primitive to describe and store data.
+ *
+ * The library supports various data types and formats. Memory hierarchy
+ * consists of three levels of abstraction:
+ * 1. **Memory descriptor** -- engine agnostic logical description of data
+ * (number of dimensions, dimensions themselves, and data type), and
+ * optionally the format/layout that describes the physical representation
+ * of data in memory. If the format is not known yet, one can pass
+ * #mkldnn_format_tag_any. This approach is used to allow compute-intensive
+ * primitives to specify the most appropriate format on their own with
+ * users required to reorder the data if the incoming format doesn't match
+ * the primitive's selection. Memory descriptor can be initialized with
+ * mkldnn_memory_desc_init_by_tag() or mkldnn_memory_desc_init_by_strides()
+ * functions, or by directly filling the mkldnn_memory_desc_t structure.
+ * The latter requires deep knowledge of how the physical data
+ * representation is mapped to the structure.
+ * The @ref understanding_memory_formats topic should shed some light on
+ * that.
+ * For the fully defined memory descriptors (i.e. where the format kind is
+ * not equal to #mkldnn_format_kind_any) a user can the size, using the
+ * mkldnn_memory_desc_get_size() function. As described in
+ * @ref understanding_memory_formats, the size of data sometimes cannot
+ * be computed as the product of dimensions times the size of the data
+ * type. So users are encouraged to use this function for better code
+ * portability.
+ * Two memory descriptors can be compared with mkldnn_memory_desc_equal().
+ * The comparison is especially useful when checking whether a primitive
+ * requires reorder from the user's data format to the primitive's format.
+ * 2. **Memory** -- an engine-specific object that handles the data and its
+ * description (a memory descriptor). For CPU enigne, the data handle is
+ * simply a pointer to @c void. The data handle can be queried using
+ * mkldnn_memory_get_data_handle() and set using
+ * mkldnn_memory_set_data_handle(). The latter function always sets the
+ * memory in the padding region to zero, which is the invariant maintained
+ * by all the primitives in Intel MKL-DNN.
+ * See @ref understanding_memory_formats for more details.
+ * A memory can be created using mkldnn_memory_create() function.
+ * A memory can also be queried for the underlying memory descriptor and
+ * engine using mkldnn_memory_get_memory_desc() and
+ * mkldnn_memory_get_engine() functions.
+ *
+ * Along with ordinary memory with all dimensions being positive, Intel
+ * MKL-DNN supports *zero-volume* memory with one or more dimensions set to
+ * zero. This is to support the NumPy\* convention.
+ * If a *zero-volume* memory is passed to a primitive, the primitive does
+ * not perform any computations on this memory. For example:
+ * - Convolution with `(0 batch, 3 input channels, 13 height, 13 width)`
+ * source and `(16 output channels, 3 inputs, channel, 3 height, 3 width)`
+ * weights would produce `(0 batch, 16 output channels, 11 height, 11 width)`
+ * destination (assuming strides are `1` and paddings are zero) and perform
+ * zero multiply-add operations.
+ * - Concatenation of three memories of shapes `(3, 4, 13, 13)`,
+ * `(3, 0, 13, 13)`, and `(3, 1, 13, 13)` along the second axis would produce
+ * the output of the shape `(3, 5, 13, 13)`, effectively ignoring the second
+ * input (however, if the user created a concatenation primitive descriptor
+ * with three inputs they should also provide all three memories to the
+ * concatenation primitive, including the one with zero second dimension).
+ * - However, Intel MKL-DNN would return an error when attempting to create a
+ * convolution with *zero-volume* memory passed for weights because such a
+ * convolution is not well-defined:
+ * ~~~
+ * dst(1, 16, 11, 11) <-- src(1, 0, 13, 13) (*) wei(16, 0, 3, 3)
+ * ~~~
+ * Should the values in the destination be zeroes or just not accessed at
+ * all? Moreover, backward pass w.r.t. weights in such cases is also not
+ * well-defined.
+ *
+ * Data handle of *zero-volume* memory is never accessed and hence can be
+ * unset (NULL in case of CPU engine).
+ *
+ * @sa @ref understanding_memory_formats
+ * @{ */
+
+/** Initializes a @p memory_desc memory descriptor using @p ndims, @p dims, @p
+ * data_type, and @p strides.
+ *
+ * The @p strides might be NULL, which means the order of physical dimensions
+ * is the same as the order of logical ones.
+ *
+ * @note The logical order of dimensions is defined by a primitive that
+ * consumes the memory.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_memory_desc_init_by_strides(
+ mkldnn_memory_desc_t *memory_desc, int ndims, const mkldnn_dims_t dims,
+ mkldnn_data_type_t data_type, const mkldnn_dims_t strides);
+
+/** Initializes a @p memory_desc memory descriptor using @p ndims, @p dims, @p
+ * data_type, and format @p tag.
+ *
+ * @p tag can be #mkldnn_format_tag_any, which allows a primitive to define
+ * the appropriate memory format. In this case, the @p format_kind would be set
+ * to #mkldnn_format_kind_any */
+mkldnn_status_t MKLDNN_API mkldnn_memory_desc_init_by_tag(
+ mkldnn_memory_desc_t *memory_desc, int ndims, const mkldnn_dims_t dims,
+ mkldnn_data_type_t data_type, mkldnn_format_tag_t tag);
+
+/** Initializes a @p memory_desc for a given @p parent_memory_desc, with
+ * @p dims sizes and @p offsets. May fail if layout used does not allow
+ * obtain desired submemory. In this case consider using `extract` or `insert`
+ * primitive */
+mkldnn_status_t MKLDNN_API mkldnn_memory_desc_init_submemory(
+ mkldnn_memory_desc_t *memory_desc,
+ const mkldnn_memory_desc_t *parent_memory_desc,
+ const mkldnn_dims_t dims, const mkldnn_dims_t offsets);
+
+/** Compares two memory descriptors.
+ * @return 1 if the descriptors are the same.
+ * @return 0 if the descriptors are different.
+ *
+ * Use this function to identify whether a reorder is required between the
+ * two memories */
+int MKLDNN_API mkldnn_memory_desc_equal(
+ const mkldnn_memory_desc_t *lhs,
+ const mkldnn_memory_desc_t *rhs);
+
+/** Returns the size (in bytes) that is required for given @p memory_desc */
+size_t MKLDNN_API mkldnn_memory_desc_get_size(
+ const mkldnn_memory_desc_t *memory_desc);
+
+/** Creates a memory for given @p memory_desc and @p engine. Also sets handle
+ * to @p native_handle.
+ * The @p native_handle can:
+ * - point to the user allocated memory, i.e. valid handle. In this case the
+ * library doesn't own allocated memory.
+ * - be MKLDNN_NATIVE_HANDLE_ALLOCATE to ask the library to allocate and
+ * attach memory. In this case the library owns allocated memory.
+ * - be MKLDNN_NATIVE_HANDLE_NONE to create mkldnn_memory w/o attached memory.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_memory_create(mkldnn_memory_t *memory,
+ const mkldnn_memory_desc_t *memory_desc, mkldnn_engine_t engine,
+ void *native_handle);
+
+/** Returns a @p memory_desc associated with @p memory. */
+mkldnn_status_t MKLDNN_API mkldnn_memory_get_memory_desc(
+ const_mkldnn_memory_t memory,
+ const mkldnn_memory_desc_t **memory_desc);
+
+/** Returns an @p engine associated with @p memory. */
+mkldnn_status_t MKLDNN_API mkldnn_memory_get_engine(
+ const_mkldnn_memory_t memory, mkldnn_engine_t *engine);
+
+/** For a @p memory, returns the data @p handle.
+ *
+ * For the CPU engine, the data handle is a pointer to the actual data. */
+mkldnn_status_t MKLDNN_API mkldnn_memory_get_data_handle(
+ const_mkldnn_memory_t memory, void **handle);
+
+/** For a @p memory, sets the data @p handle. */
+mkldnn_status_t MKLDNN_API mkldnn_memory_set_data_handle(
+ mkldnn_memory_t memory, void *handle);
+
+/** Deletes a @p memory. */
+mkldnn_status_t MKLDNN_API mkldnn_memory_destroy(mkldnn_memory_t memory);
+
+/** @} */
+
+/** @addtogroup c_api_reorder Reorder
+ * A primitive to copy data between memory formats.
+ * @{ */
+
+/** Initializes a @p reorder_primitive_desc using the description of the source
+ * (@p src_engine and @p src_md) and destination (@p dst_engine and @p dst_md)
+ * memory, and an @p attr attribute.
+ *
+ * Inputs:
+ * - input (#mkldnn_query_src_md, 0)
+ *
+ * Outputs:
+ * - output (#mkldnn_query_dst_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_reorder_primitive_desc_create(
+ mkldnn_primitive_desc_t *reorder_primitive_desc,
+ mkldnn_engine_t src_engine, const mkldnn_memory_desc_t *src_md,
+ mkldnn_engine_t dst_engine, const mkldnn_memory_desc_t *dst_md,
+ const_mkldnn_primitive_attr_t attr);
+
+/** @} */
+
+/** @addtogroup c_api_concat Concat
+ * A primitive to concatenate data by arbitrary dimension.
+ * @{ */
+
+/** Creates out-of-place @p concat_primitive_desc for concatenation of @p n
+ * inputs by @p concat_dimension with resulting @p output_desc memory
+ * descriptor. @p output_desc can be NULL or specified with the
+ * #mkldnn_format_kind_any format kind -- in this case, the appropriate memory
+ * format would be chosen automatically.
+ *
+ * Inputs:
+ * - input 0 (#mkldnn_query_src_md, 0)
+ * - input 1 (#mkldnn_query_src_md, 1)
+ * - ...
+ * - input @p n - 1 (#mkldnn_query_src_md, @p n - 1)
+ *
+ * Outputs:
+ * - output (#mkldnn_query_dst_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_concat_primitive_desc_create(
+ mkldnn_primitive_desc_t *concat_primitive_desc,
+ const mkldnn_memory_desc_t *dst_md,
+ int n, int concat_dimension,
+ const mkldnn_memory_desc_t *src_mds,
+ const_mkldnn_primitive_attr_t attr,
+ mkldnn_engine_t engine);
+
+/** @} */
+
+/** @addtogroup c_api_sum Sum
+ * A primitive to sum data.
+ * @{ */
+
+/** Creates out-of-place @p sum_primitive_desc for sum of @p n
+ * inputs multiplied by scale with resulting @p output_desc memory
+ * descriptor. @p output_desc can be NULL or specified with the
+ * #mkldnn_format_kind_any format kind -- in this case, the appropriate memory
+ * format would be chosen automatically.
+ *
+ * Inputs:
+ * - src 0 (#mkldnn_query_src_md, 0)
+ * - src 1 (#mkldnn_query_src_md, 1)
+ * - ...
+ * - src @p n - 1 (#mkldnn_query_src_md, @p n - 1)
+ *
+ * Outputs:
+ * - output (#mkldnn_query_dst_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_sum_primitive_desc_create(
+ mkldnn_primitive_desc_t *sum_primitive_desc,
+ const mkldnn_memory_desc_t *dst_mds,
+ int n, const float *scales,
+ const mkldnn_memory_desc_t *src_mds,
+ const_mkldnn_primitive_attr_t attr,
+ mkldnn_engine_t engine);
+
+/** @} */
+
+/** @addtogroup c_api_convolution Convolution
+ * A primitive to compute convolution using different algorithms.
+ *
+ * \f[dst[n][oc][oh][ow] =
+ * \sum_{kw=0}^{KW}\sum_{kh=0}^{KH}\sum_{ic=0}^{IC}
+ * src[n][ic][oh \cdot s_h - p_l[0] + kh][ow \cdot s_w - p_r[1] + kw]
+ * \cdot weights[g][oc][ic][kh][kw]
+ * + bias[g][oc],\f]
+ *
+ * where size of output spatial domain is given by
+ * \f$ OH = \left\lfloor{\frac{IH - KH + p_l[0] + p_r[0]}{s_h}}
+ * \right\rfloor + 1\f$,
+ * \f$ OW = \left\lfloor{\frac{IW - KW + p_l[1] + p_r[1]}{s_w}}
+ * \right\rfloor + 1\f$,
+ *
+ * and summation is carried over input channels \f$ic\f$ in
+ * group \f$g\f$, and \f$s_h, s_w\f$ are @p strides and
+ * \f$p_l, p_r\f$ are @p padding_l and @p padding_r.
+ * @{ */
+
+/** Initializes a convolution descriptor @p conv_desc for forward propagation
+ * using @p prop_kind (possible values are #mkldnn_forward_training and
+ * #mkldnn_forward_inference), @p alg_kind, memory descriptors, @p strides, @p
+ * padding_l, @p padding_r, and @p padding_kind. In order to create a
+ * convolution without bias, @p bias_desc should either be @c NULL or point to
+ * a descriptor with memory format kind equal to #mkldnn_format_kind_undef.
+ *
+ * @note If @p padding_r is @c NULL, the padding is supposed to be symmetric.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - weights (#mkldnn_query_weights_md, 0)
+ * - bias (#mkldnn_query_weights_md, 1), if created with bias
+ *
+ * Outputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_convolution_forward_desc_init(
+ mkldnn_convolution_desc_t *conv_desc, mkldnn_prop_kind_t prop_kind,
+ mkldnn_alg_kind_t alg_kind, const mkldnn_memory_desc_t *src_desc,
+ const mkldnn_memory_desc_t *weights_desc,
+ const mkldnn_memory_desc_t *bias_desc,
+ const mkldnn_memory_desc_t *dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t padding_l, const mkldnn_dims_t padding_r,
+ mkldnn_padding_kind_t padding_kind);
+
+/** Initializes a dilated convolution descriptor @p conv_desc for forward
+ * propagation using @p prop_kind (possible values are #mkldnn_forward_training
+ * and #mkldnn_forward_inference), @p alg_kind, memory descriptors, @p strides,
+ * @p dilates, @p padding_l, @p padding_r, and @p padding_kind.
+ * In order to create a dilated convolution without bias, @p bias_desc
+ * should either be @c NULL or point to a descriptor with memory format kind
+ * equals #mkldnn_format_kind_undef.
+ *
+ * @note If @p padding_r is @c NULL, the padding is supposed to be symmetric.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - weights (#mkldnn_query_weights_md, 0)
+ * - bias (#mkldnn_query_weights_md, 1), if created with bias
+ *
+ * Outputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_dilated_convolution_forward_desc_init(
+ mkldnn_convolution_desc_t *conv_desc, mkldnn_prop_kind_t prop_kind,
+ mkldnn_alg_kind_t alg_kind, const mkldnn_memory_desc_t *src_desc,
+ const mkldnn_memory_desc_t *weights_desc,
+ const mkldnn_memory_desc_t *bias_desc,
+ const mkldnn_memory_desc_t *dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t dilates, const mkldnn_dims_t padding_l,
+ const mkldnn_dims_t padding_r, mkldnn_padding_kind_t padding_kind);
+
+/** Initializes a convolution descriptor @p conv_desc for backward propagation
+ * with respect to data using @p alg_kind, memory descriptors, @p strides, @p
+ * padding_l, @p padding_r, and @p padding_kind.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ * - weights (#mkldnn_query_weights_md, 0)
+ *
+ * Outputs:
+ * - diff_src (#mkldnn_query_diff_src_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_convolution_backward_data_desc_init(
+ mkldnn_convolution_desc_t *conv_desc, mkldnn_alg_kind_t alg_kind,
+ const mkldnn_memory_desc_t *diff_src_desc,
+ const mkldnn_memory_desc_t *weights_desc,
+ const mkldnn_memory_desc_t *diff_dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t padding_l, const mkldnn_dims_t padding_r,
+ mkldnn_padding_kind_t padding_kind);
+
+/** Initializes a dilated convolution descriptor @p conv_desc for backward
+ * propagation with respect to data using @p alg_kind, memory descriptors, @p
+ * strides, @p dilates @p padding_l, @p padding_r, and @p padding_kind.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ * - weights (#mkldnn_query_weights_md, 0)
+ *
+ * Outputs:
+ * - diff_src (#mkldnn_query_diff_src_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_dilated_convolution_backward_data_desc_init(
+ mkldnn_convolution_desc_t *conv_desc, mkldnn_alg_kind_t alg_kind,
+ const mkldnn_memory_desc_t *diff_src_desc,
+ const mkldnn_memory_desc_t *weights_desc,
+ const mkldnn_memory_desc_t *diff_dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t dilates, const mkldnn_dims_t padding_l,
+ const mkldnn_dims_t padding_r, mkldnn_padding_kind_t padding_kind);
+
+/** Initializes a convolution descriptor @p conv_desc for backward propagation
+ * with respect to weights using @p alg_kind, memory descriptors, @p strides,
+ * @p padding_l, @p padding_r, and @p padding_kind.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ *
+ * Outputs:
+ * - diff_weights (#mkldnn_query_diff_weights_md, 0)
+ * - diff_bias (#mkldnn_query_diff_weights_md, 1), if created with bias
+ */
+mkldnn_status_t MKLDNN_API mkldnn_convolution_backward_weights_desc_init(
+ mkldnn_convolution_desc_t *conv_desc, mkldnn_alg_kind_t alg_kind,
+ const mkldnn_memory_desc_t *src_desc,
+ const mkldnn_memory_desc_t *diff_weights_desc,
+ const mkldnn_memory_desc_t *diff_bias_desc,
+ const mkldnn_memory_desc_t *diff_dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t padding_l, const mkldnn_dims_t padding_r,
+ mkldnn_padding_kind_t padding_kind);
+
+/** Initializes a convolution descriptor @p conv_desc for backward propagation
+ * with respect to weights using @p alg_kind, memory descriptors, @p strides,
+ * @p dilates @p padding_l, @p padding_r, and @p padding_kind.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ *
+ * Outputs:
+ * - diff_weights (#mkldnn_query_diff_weights_md, 0)
+ * - diff_bias (#mkldnn_query_diff_weights_md, 1), if created with bias
+ */
+mkldnn_status_t MKLDNN_API
+mkldnn_dilated_convolution_backward_weights_desc_init(
+ mkldnn_convolution_desc_t *conv_desc, mkldnn_alg_kind_t alg_kind,
+ const mkldnn_memory_desc_t *src_desc,
+ const mkldnn_memory_desc_t *diff_weights_desc,
+ const mkldnn_memory_desc_t *diff_bias_desc,
+ const mkldnn_memory_desc_t *diff_dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t dilates, const mkldnn_dims_t padding_l,
+ const mkldnn_dims_t padding_r, mkldnn_padding_kind_t padding_kind);
+
+/** @} */
+
+/** @addtogroup c_api_deconvolution Deconvolution
+ * A primitive to compute deconvolution using different algorithms.
+ *
+ * @{ */
+
+
+/** Initializes a deconvolution descriptor @p deconv_desc for forward
+ * propagation using @p prop_kind (possible values are #mkldnn_forward_training
+ * and #mkldnn_forward_inference), @p alg_kind, memory descriptors, @p strides,
+ * @p padding_l, @p padding_r, and @p padding_kind. In order to create a
+ * deconvolution without bias, @p bias_desc should either be @c NULL or point to
+ * a descriptor with memory format kind equals #mkldnn_format_kind_undef.
+ *
+ * @note If @p padding_r is @c NULL, the padding is supposed to be symmetric.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - weights (#mkldnn_query_weights_md, 0)
+ * - bias (#mkldnn_query_weights_md, 1), if created with bias
+ *
+ * Outputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_deconvolution_forward_desc_init(
+ mkldnn_deconvolution_desc_t *conv_desc, mkldnn_prop_kind_t prop_kind,
+ mkldnn_alg_kind_t alg_kind, const mkldnn_memory_desc_t *src_desc,
+ const mkldnn_memory_desc_t *weights_desc,
+ const mkldnn_memory_desc_t *bias_desc,
+ const mkldnn_memory_desc_t *dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t padding_l, const mkldnn_dims_t padding_r,
+ mkldnn_padding_kind_t padding_kind);
+
+/** Initializes a dilated deconvolution descriptor @p deconv_desc for forward
+ * propagation using @p prop_kind (possible values are #mkldnn_forward_training
+ * and #mkldnn_forward_inference), @p alg_kind, memory descriptors, @p strides,
+ * @p dilates, @p padding_l, @p padding_r, and @p padding_kind. In order to
+ * create a dilated deconvolution without bias, @p bias_desc should either be
+ * @c NULL or point to a descriptor with memory format kind equal
+ * #mkldnn_format_kind_undef.
+ *
+ * @note If @p padding_r is @c NULL, the padding is supposed to be symmetric.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - weights (#mkldnn_query_weights_md, 0)
+ * - bias (#mkldnn_query_weights_md, 1), if created with bias
+ *
+ * Outputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_dilated_deconvolution_forward_desc_init(
+ mkldnn_deconvolution_desc_t *conv_desc, mkldnn_prop_kind_t prop_kind,
+ mkldnn_alg_kind_t alg_kind, const mkldnn_memory_desc_t *src_desc,
+ const mkldnn_memory_desc_t *weights_desc,
+ const mkldnn_memory_desc_t *bias_desc,
+ const mkldnn_memory_desc_t *dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t dilates, const mkldnn_dims_t padding_l,
+ const mkldnn_dims_t padding_r, mkldnn_padding_kind_t padding_kind);
+
+/** Initializes a deconvolution descriptor @p conv_desc for backward propagation
+ * with respect to data using @p alg_kind, memory descriptors, @p strides, @p
+ * padding_l, @p padding_r, and @p padding_kind.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ * - weights (#mkldnn_query_weights_md, 0)
+ *
+ * Outputs:
+ * - diff_src (#mkldnn_query_diff_src_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_deconvolution_backward_data_desc_init(
+ mkldnn_deconvolution_desc_t *conv_desc, mkldnn_alg_kind_t alg_kind,
+ const mkldnn_memory_desc_t *diff_src_desc,
+ const mkldnn_memory_desc_t *weights_desc,
+ const mkldnn_memory_desc_t *diff_dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t padding_l, const mkldnn_dims_t padding_r,
+ mkldnn_padding_kind_t padding_kind);
+
+/** Initializes a dilated deconvolution descriptor @p conv_desc for backward
+ * propagation with respect to data using @p alg_kind, memory descriptors, @p
+ * strides, @p dilates, @p padding_l, @p padding_r, and @p padding_kind.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ * - weights (#mkldnn_query_weights_md, 0)
+ *
+ * Outputs:
+ * - diff_src (#mkldnn_query_diff_src_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_dilated_deconvolution_backward_data_desc_init(
+ mkldnn_deconvolution_desc_t *conv_desc, mkldnn_alg_kind_t alg_kind,
+ const mkldnn_memory_desc_t *diff_src_desc,
+ const mkldnn_memory_desc_t *weights_desc,
+ const mkldnn_memory_desc_t *diff_dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t dilates, const mkldnn_dims_t padding_l,
+ const mkldnn_dims_t padding_r, mkldnn_padding_kind_t padding_kind);
+
+/** Initializes a deconvolution descriptor @p conv_desc for backward propagation
+ * with respect to weights using @p alg_kind, memory descriptors, @p strides,
+ * @p padding_l, @p padding_r, and @p padding_kind.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ *
+ * Outputs:
+ * - diff_weights (#mkldnn_query_diff_weights_md, 0)
+ * - diff_bias (#mkldnn_query_diff_weights_md, 1), if created with bias
+ */
+mkldnn_status_t MKLDNN_API mkldnn_deconvolution_backward_weights_desc_init(
+ mkldnn_deconvolution_desc_t *conv_desc, mkldnn_alg_kind_t alg_kind,
+ const mkldnn_memory_desc_t *src_desc,
+ const mkldnn_memory_desc_t *diff_weights_desc,
+ const mkldnn_memory_desc_t *diff_bias_desc,
+ const mkldnn_memory_desc_t *diff_dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t padding_l, const mkldnn_dims_t padding_r,
+ mkldnn_padding_kind_t padding_kind);
+
+/** Initializes a dilated deconvolution descriptor @p conv_desc for backward
+ * propagation with respect to weights using @p alg_kind, memory descriptors,
+ * @p strides, @p dilates, @p padding_l, @p padding_r, and @p padding_kind.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ *
+ * Outputs:
+ * - diff_weights (#mkldnn_query_diff_weights_md, 0)
+ * - diff_bias (#mkldnn_query_diff_weights_md, 1), if created with bias
+ */
+mkldnn_status_t MKLDNN_API mkldnn_dilated_deconvolution_backward_weights_desc_init(
+ mkldnn_deconvolution_desc_t *conv_desc, mkldnn_alg_kind_t alg_kind,
+ const mkldnn_memory_desc_t *src_desc,
+ const mkldnn_memory_desc_t *diff_weights_desc,
+ const mkldnn_memory_desc_t *diff_bias_desc,
+ const mkldnn_memory_desc_t *diff_dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t dilates, const mkldnn_dims_t padding_l,
+ const mkldnn_dims_t padding_r, mkldnn_padding_kind_t padding_kind);
+
+/** @} */
+
+/** @addtogroup c_api_shuffle Shuffle
+ * A primitive to shuffle data along the axis.
+ * @{ */
+
+/** Initializes a @p shuffle_desc for forward propagation using @p prop_kind,
+ * memory descriptor @p data_desc, @p axis, and @p group_size.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ *
+ * Outputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ *
+ */
+mkldnn_status_t MKLDNN_API mkldnn_shuffle_forward_desc_init(
+ mkldnn_shuffle_desc_t *shuffle_desc, mkldnn_prop_kind_t prop_kind,
+ const mkldnn_memory_desc_t *data_desc, int axis,
+ mkldnn_dim_t group_size);
+
+/** Initializes a @p shuffle_desc for backward propagation using memory
+ * descriptor @p diff_data_desc, @p axis, and @p group_size.
+ *
+ *
+ * Inputs:
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ *
+ * Outputs:
+ * - diff_src (#mkldnn_query_diff_src_md, 0)
+ *
+ */
+mkldnn_status_t MKLDNN_API mkldnn_shuffle_backward_desc_init(
+ mkldnn_shuffle_desc_t *shuffle_desc,
+ const mkldnn_memory_desc_t *diff_data_desc, int axis,
+ mkldnn_dim_t group_size);
+
+/** @} */
+
+/** @addtogroup c_api_eltwise Eltwise
+ * A primitive to compute element-wise operations like parametric rectifier
+ * linear unit (ReLU).
+ *
+ * Both forward and backward passes support in-place operation; that is, src
+ * and dst point to the same memory for forward pass, and diff_dst and diff_src
+ * point to the same memory for backward pass.
+ *
+ * @warning Because the original src is required for backward pass, in-place
+ * forward pass in general cannot be applied during training. However, for some
+ * kinds of element-wise operations (namely ReLU with alpha parameter equals 0),
+ * dst and src can be interchangeable for the backward pass, which enables
+ * performing in-place forward even for training.
+ *
+ * @{ */
+
+/** Initializes an @p eltwise_desc for forward propagation using @p prop_kind
+ * (possible values are #mkldnn_forward_training and #mkldnn_forward_inference),
+ * @p alg_kind algorithm, memory descriptor @p data_desc, @p alpha, and
+ * @p beta parameters.
+ *
+ * @sa mkldnn_eltwise_desc_t for details.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ *
+ * Outputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_eltwise_forward_desc_init(
+ mkldnn_eltwise_desc_t *eltwise_desc, mkldnn_prop_kind_t prop_kind,
+ mkldnn_alg_kind_t alg_kind, const mkldnn_memory_desc_t *data_desc,
+ float alpha, float beta);
+
+/** Initializes an @p eltwise_desc for backward propagation using @p alg_kind
+ * algorithm memory descriptors @p diff_data_desc and @p data_desc, and the
+ * @p alpha and @p beta parameters.
+ *
+ * @sa mkldnn_eltwise_desc_t for details.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ *
+ * Outputs:
+ * - diff_src (#mkldnn_query_diff_src_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_eltwise_backward_desc_init(
+ mkldnn_eltwise_desc_t *eltwise_desc, mkldnn_alg_kind_t alg_kind,
+ const mkldnn_memory_desc_t *diff_data_desc,
+ const mkldnn_memory_desc_t *data_desc, float alpha, float beta);
+
+/** @} */
+
+/** @addtogroup c_api_softmax Softmax
+ * A primitive to perform softmax.
+ *
+ * \f[dst[u][c][in] =
+ * \frac{\exp(src[ou][c][in]) - \max\limits_{c}(src[ou][c][in])}
+ * {\sum\limits_{c}\{\exp(src[ou][c][in])
+ * - \max\limits_{c}(src[ou][c][in])\}},\f]
+ *
+ * where \f$ou, iu\f$ are outer and inner sizes repectively, defined
+ * by @p data_desc.dims and @p softmax_axis.
+ * @{ */
+
+/** Initializes a @p softmax_desc for forward propagation using @p prop_kind
+ * (possible values are #mkldnn_forward_training and #mkldnn_forward_inference)
+ * and memory descriptor @p data_desc.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ *
+ * Outputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_softmax_forward_desc_init(
+ mkldnn_softmax_desc_t *softmax_desc, mkldnn_prop_kind_t prop_kind,
+ const mkldnn_memory_desc_t *data_desc, int softmax_axis);
+
+/** Initializes a @p softmax_desc for backward propagation using memory
+ * descriptors @p diff_desc and @p data_desc.
+ *
+ * Inputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ *
+ * Outputs:
+ * - diff_src (#mkldnn_query_diff_src_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_softmax_backward_desc_init(
+ mkldnn_softmax_desc_t *softmax_desc,
+ const mkldnn_memory_desc_t *diff_desc,
+ const mkldnn_memory_desc_t *data_desc, int softmax_axis);
+
+/** @} */
+
+/** @addtogroup c_api_pooling Pooling
+ * A primitive to perform max or average pooling.
+ *
+ * Max pooling:
+ * \f[dst[n][oc][oh][ow] =
+ * \max\limits_{kw,kh}
+ * (src[n][ic][oh \cdot s_h - p_l[0] + kh][ow \cdot s_w - p_r[1] + kw]),\f]
+ *
+ * Average pooling:
+ * \f[dst[n][oc][oh][ow] =
+ * \frac{1}{KW \cdot KH}\sum\limits_{kw,kh}
+ * src[n][ic][oh \cdot s_h - p_l[0] + kh][ow \cdot s_w - p_r[1] + kw],\f]
+ *
+ * where \f$p_l, p_r\f$ are @p padding_l and @p padding_r respectively, and
+ * output spatial dimensions are calculated similarly to how they are done in
+ * convolution.
+ *
+ * During training, max pooling requires a workspace on forward
+ * (#mkldnn_forward_training) and backward (#mkldnn_backward) passes to
+ * save indices where maximum was found. The workspace layout is opaque, and
+ * the indices cannot be restored from it. However, one can use backward
+ * pooling to perform up-sampling (used in some detection topologies).
+ *
+ * @{ */
+
+/** Initializes a pooling descriptor @p pool_desc for forward propagation using
+ * @p prop_kind (possible values are #mkldnn_forward_training and
+ * #mkldnn_forward_inference), @p alg_kind, memory descriptors, and pooling
+ * parameters in the spatial domain: @p strides, @p kernel sizes, @p padding_l,
+ * @p padding_r, and @p padding_kind.
+ *
+ * @note If @p padding_r is @c NULL, the padding is supposed to be symmetric.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ *
+ * Outputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ * - workspace (#mkldnn_query_workspace_md, 0),
+ * if @p alg_kind = #mkldnn_pooling_max and
+ * @p prop_kind = #mkldnn_forward_training
+ */
+mkldnn_status_t MKLDNN_API mkldnn_pooling_forward_desc_init(
+ mkldnn_pooling_desc_t *pool_desc, mkldnn_prop_kind_t prop_kind,
+ mkldnn_alg_kind_t alg_kind, const mkldnn_memory_desc_t *src_desc,
+ const mkldnn_memory_desc_t *dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t kernel, const mkldnn_dims_t padding_l,
+ const mkldnn_dims_t padding_r, mkldnn_padding_kind_t padding_kind);
+
+/** Initializes a pooling descriptor @p pool_desc for backward propagation
+ * using @p alg_kind, memory descriptors, and pooling parameters in the spatial
+ * domain: @p strides, @p kernel sizes, @p padding_l, @p padding_r, and @p
+ * padding_kind.
+ *
+ * @note If @p padding_r is @c NULL, the padding is supposed to be symmetric.
+ *
+ * Inputs:
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ * - workspace (#mkldnn_query_workspace_md, 0),
+ * if @p alg_kind = #mkldnn_pooling_max
+ *
+ * Outputs:
+ * - diff_src (#mkldnn_query_diff_src_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_pooling_backward_desc_init(
+ mkldnn_pooling_desc_t *pool_desc, mkldnn_alg_kind_t alg_kind,
+ const mkldnn_memory_desc_t *diff_src_desc,
+ const mkldnn_memory_desc_t *diff_dst_desc, const mkldnn_dims_t strides,
+ const mkldnn_dims_t kernel, const mkldnn_dims_t padding_l,
+ const mkldnn_dims_t padding_r, mkldnn_padding_kind_t padding_kind);
+
+/** @} */
+
+/** @addtogroup c_api_lrn LRN
+ * A primitive to perform local response normalization (LRN) across or within
+ * channels.
+ *
+ * LRN accross channels:
+ * \f[dst[n][c][h][w] = \left\{k + \frac{\alpha}{n_{l}}
+ * \sum\limits_{i=-(n_{l}-1)/2}^{(n_{l}+1)/2}
+ * (src[n][c+i][h][w])^2\right\}^{-\beta}
+ * src[n][c][h][w],\f]
+ *
+ * LRN within channels:
+ * \f[dst[n][c][h][w] = \left\{k + \frac{\alpha}{n_{l}}
+ * \sum\limits_{i=-(n_{l}-1)/2}^{(n_{l}+1)/2}
+ * (src[n][c][h+i][w+i])^2\right\}^{-\beta}
+ * src[n][c][h][w],\f]
+ *
+ * where \f$n_{l}\f$ is the @p local_size.
+ *
+ * During training, LRN might or might not require a workspace on forward
+ * (#mkldnn_forward_training) and backward (#mkldnn_backward) passes. The
+ * behavior is implementation specific. Optimized implementations typically
+ * require a workspace and use it to save some intermediate results from the
+ * forward pass that accelerate computations on the backward pass.
+ *
+ * To check whether a workspace is required, query the LRN primitive descriptor
+ * for the workspace (#mkldnn_query_workspace_md). Success indicates that the
+ * workspace is required and its description will be returned.
+ * @sa mkldnn_primitive_desc_query and mkldnn_primitive_desc_query_pd
+ *
+ * @{ */
+
+/** Initializes an @p lrn_desc for forward propagation using @p prop_kind
+ * (possible values are #mkldnn_forward_training and #mkldnn_forward_inference),
+ * @p alg_kind, memory descriptor @p data_desc, and regularization
+ * parameters @p local_size, @p alpha, @p beta, and @p k.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ *
+ * Outputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ * - workspace (#mkldnn_query_workspace_md, 0),
+ * if the underlying implementation requires
+ */
+mkldnn_status_t MKLDNN_API mkldnn_lrn_forward_desc_init(
+ mkldnn_lrn_desc_t *lrn_desc, mkldnn_prop_kind_t prop_kind,
+ mkldnn_alg_kind_t alg_kind, const mkldnn_memory_desc_t *data_desc,
+ mkldnn_dim_t local_size, float alpha, float beta, float k);
+
+/** Initializes an @p lrn_desc for backward propagation using @p alg_kind,
+ * memory descriptors @p data_desc and @p diff_data_desc, and regularization
+ * parameters @p local_size, @p alpha, @p beta, and @p k.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ * - workspace (#mkldnn_query_workspace_md, 0),
+ * if the underlying implementation requires
+ *
+ * Outputs:
+ * - diff_src (#mkldnn_query_diff_src_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_lrn_backward_desc_init(
+ mkldnn_lrn_desc_t *lrn_desc, mkldnn_alg_kind_t alg_kind,
+ const mkldnn_memory_desc_t *diff_data_desc,
+ const mkldnn_memory_desc_t *data_desc, mkldnn_dim_t local_size,
+ float alpha, float beta, float k);
+
+/** @} */
+
+/** @addtogroup c_api_batch_normalization Batch Normalization
+ * A primitive to perform batch normalization.
+ *
+ * \f[dst[n][c][h][w] = \gamma[c] \frac{src[n][c][h][w] - \mu[c]}
+ * {\sqrt{\sigma[c] + eps}} + \beta[c],\f]
+ *
+ * where \f$\gamma[c], \beta[c]\f$ are weights and bias for a channel and,
+ *
+ * \f$\mu[c] = \frac{1}{NHW} \sum\limits_{whn} src[n][c][h][w]\f$,
+ * \f$\sigma[c] = \frac{1}{NHW} \sum\limits_{whn}
+ * (src[n][c][h][w] - \mu[c])^2\f$,
+ *
+ * and @c eps is a constant to improve numerical stability.
+ *
+ * Both forward and backward passes support in-place operation; that is, src
+ * and dst point to the same memory for forward pass, and diff_dst and diff_src
+ * point to the same memory for backward pass.
+ *
+ * Batch normalization supports different flavors controlled by
+ * mkldnn_batch_normalization_desc_t. For example, batch normalization can
+ * compute the mean and variance on its own or take them as inputs. It can
+ * either perform scaling and shifting using gamma and beta parameters or not.
+ * Optionally it can also perform a fused ReLU, which in case of training would
+ * also require a workspace.
+ *
+ * @sa mkldnn_batch_normalization_desc_t
+ * @{ */
+
+/** Initializes a batch normalization descriptor @p bnrm_desc for forward
+ * propagation using @p prop_kind (possible values are
+ * #mkldnn_forward_training and #mkldnn_forward_inference), memory descriptor
+ * @p data_desc, normalization parameter @p epsilon, and @p flags set using bit
+ * flags of type mkldnn_batch_normalization_desc_t.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - mean (#mkldnn_query_src_md, 1),
+ * if #mkldnn_use_global_stats bit-flags is set in @p flags
+ * - variance (#mkldnn_query_src_md, 2),
+ * if #mkldnn_use_global_stats bit-flags is set in @p flags
+ * - scale_and_shift (#mkldnn_query_weights_md, 0),
+ * if #mkldnn_use_scaleshift bit-flags is set in @p flags
+ *
+ * Outputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ * - mean (#mkldnn_query_dst_md, 1),
+ * if #mkldnn_use_global_stats bit-flags is not set in @p flags
+ * @p prop_kind = #mkldnn_forward_training
+ * - variance (#mkldnn_query_dst_md, 2),
+ * if #mkldnn_use_global_stats bit-flags is not set in @p flags
+ * and @p prop_kind = #mkldnn_forward_training
+ * - workspace (#mkldnn_query_workspace_md, 0),
+ * if #mkldnn_fuse_bn_relu bit-flags is set in @p flags
+ * and @p prop_kind = #mkldnn_forward_training
+ *
+ * @note In-place operation is supported; that is, dst points to the same memory
+ * as src.
+ *
+ * @sa mkldnn_batch_normalization_desc_t
+ */
+mkldnn_status_t MKLDNN_API mkldnn_batch_normalization_forward_desc_init(
+ mkldnn_batch_normalization_desc_t *bnrm_desc,
+ mkldnn_prop_kind_t prop_kind, const mkldnn_memory_desc_t *data_desc,
+ float epsilon, unsigned flags);
+
+/** Initializes a batch normalization descriptor @p bnrm_desc for backward
+ * propagation with respect to data and scale-shift parameters using memory
+ * descriptors @p data_desc and @p diff_data_desc, normalization parameter
+ * @p epsilon, and @p flags set using bit flags of type
+ * mkldnn_batch_normalization_desc_t.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - mean (#mkldnn_query_src_md, 1)
+ * - variance (#mkldnn_query_src_md, 2)
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ * - scale_and_shift (#mkldnn_query_weights_md, 0),
+ * if #mkldnn_use_scaleshift bit-flags is set in @p flags
+ * - workspace (#mkldnn_query_workspace_md, 0),
+ * if #mkldnn_fuse_bn_relu bit-flags is set in @p flags
+ *
+ * Outputs:
+ * - diff_src (#mkldnn_query_diff_src_md, 0)
+ * - diff_scale_and_shift (#mkldnn_query_diff_weights_md, 0),
+ * if #mkldnn_use_scaleshift bit-flags is set in @p flags
+ * and @p prop_kind = #mkldnn_backward
+ *
+ * @note in-place operation is supported,
+ * i.e. diff_src points to the same memory as diff_dst.
+ *
+ * @sa mkldnn_batch_normalization_desc_t
+ */
+mkldnn_status_t MKLDNN_API mkldnn_batch_normalization_backward_desc_init(
+ mkldnn_batch_normalization_desc_t *bnrm_desc,
+ mkldnn_prop_kind_t prop_kind,
+ const mkldnn_memory_desc_t *diff_data_desc,
+ const mkldnn_memory_desc_t *data_desc,
+ float epsilon, unsigned flags);
+
+/** @} */
+
+/** @addtogroup c_api_inner_product Inner product
+ * A primitive to compute an inner product.
+ *
+ * Inner product layer is also known as fully connected layer.
+ * With spatial dimension:
+ *
+ * \f[dst[n][oc] = \sum\limits_{ic, kh, kw}
+ * src[n][ic][kh][kw] \cdot weights[oc][ic][kh][kw]
+ * + bias[oc]\f]
+ * @{ */
+
+/** Initializes an inner product descriptor @p ip_desc for forward propagation
+ * using @p prop_kind (possible values are #mkldnn_forward_training and
+ * #mkldnn_forward_inference) and memory descriptors. In order to create an
+ * inner product without bias, @p bias_desc should be either @c NULL or a
+ * pointer to a descriptor with memory format kind equals
+ * #mkldnn_format_kind_undef.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - weights (#mkldnn_query_weights_md, 0)
+ * - bias (#mkldnn_query_weights_md, 1), if created with bias
+ *
+ * Outputs:
+ * - dst (#mkldnn_query_dst_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_inner_product_forward_desc_init(
+ mkldnn_inner_product_desc_t *ip_desc, mkldnn_prop_kind_t prop_kind,
+ const mkldnn_memory_desc_t *src_desc,
+ const mkldnn_memory_desc_t *weights_desc,
+ const mkldnn_memory_desc_t *bias_desc,
+ const mkldnn_memory_desc_t *dst_desc);
+
+/** Initializes an inner product descriptor @p ip_desc for backward propagation
+ * with respect to data using memory descriptors.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ * - weights (#mkldnn_query_weights_md, 0)
+ *
+ * Outputs:
+ * - diff_src (#mkldnn_query_diff_src_md, 0)
+ */
+mkldnn_status_t MKLDNN_API mkldnn_inner_product_backward_data_desc_init(
+ mkldnn_inner_product_desc_t *ip_desc,
+ const mkldnn_memory_desc_t *diff_src_desc,
+ const mkldnn_memory_desc_t *weights_desc,
+ const mkldnn_memory_desc_t *diff_dst_desc);
+
+/** Initializes an inner product descriptor @p ip_desc for backward propagation
+ * with respect to weights using memory descriptors.
+ *
+ * @note Memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - src (#mkldnn_query_src_md, 0)
+ * - diff_dst (#mkldnn_query_diff_dst_md, 0)
+ *
+ * Outputs:
+ * - diff_weights (#mkldnn_query_diff_weights_md, 0)
+ * - diff_bias (#mkldnn_query_diff_weights_md, 1), if created with bias
+ */
+mkldnn_status_t MKLDNN_API mkldnn_inner_product_backward_weights_desc_init(
+ mkldnn_inner_product_desc_t *ip_desc,
+ const mkldnn_memory_desc_t *src_desc,
+ const mkldnn_memory_desc_t *diff_weights_desc,
+ const mkldnn_memory_desc_t *diff_bias_desc,
+ const mkldnn_memory_desc_t *diff_dst_desc);
+
+/** @} */
+
+/** @addtogroup c_api_rnn RNN
+ * A primitive to compute the common recurrent layer.
+ * @todo add additional description for the group
+ * @{ */
+
+/**
+ * Initializes a recurrent cell descriptor @p rnn_cell_desc
+ * using @p rnn_cell_desc, @p kind (possible values are
+ * #mkldnn_vanilla_rnn, #mkldnn_vanilla_lstm, #mkldnn_vanilla_gru, and
+ * #mkldnn_gru_linear_before_reset),
+ * @p f (possible values are #mkldnn_eltwise_relu and
+ * #mkldnn_eltwise_tanh), @p flags, @p alpha, and @p clipping.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_rnn_cell_desc_init(
+ mkldnn_rnn_cell_desc_t *rnn_cell_desc,
+ mkldnn_alg_kind_t kind, mkldnn_alg_kind_t f,
+ unsigned int flags, float alpha, float clipping);
+
+/** Returns the number of gates of a particular @p rnn_cell_desc. */
+int MKLDNN_API mkldnn_rnn_cell_get_gates_count(
+ const mkldnn_rnn_cell_desc_t *rnn_cell_desc);
+
+/** Returns the number of states of a particular @p rnn_cell_desc. */
+int MKLDNN_API mkldnn_rnn_cell_get_states_count(
+ const mkldnn_rnn_cell_desc_t *rnn_cell_desc);
+
+/** Sets quantization @p scale and @p shift for RNN data tensors.
+ * For performance reasons, low precision configuration of RNN primitive
+ * expects input activations to have unsigned int8 data type. Scale and shift
+ * used to quantize floating point data to unsigned integer must be passed to
+ * RNN primitive using attributes.
+ * Example usage:
+ * @code
+ * // rnn parameters
+ * int l = 2, t = 2, mb = 32, sic = 32, slc = 32, dic = 32, dlc = 32;
+ * // activations quantization parameters
+ * float scale = ..., shift = ..;
+ *
+ * mkldnn_primitive_attr_t rnn_attr;
+ * // create default attributes
+ * mkldnn_primitive_attr_create(&rnn_attr);
+ *
+ * // set scale and shift for int8 quantization of activation
+ * mkldnn_primitive_attr_set_rnn_data_qparams(rnn_attr, scale, shift);
+ *
+ * // create & configure rnn op_desc
+ * mkldnn_rnn_desc_t rnn_d;
+ * mkldnn_primitive_desc_t rnn_pd;
+ * mkldnn_primitive_desc_create(&rnn_pd, &rnn_d, attr, engine, NULL);
+ * @endcode
+ * @note
+ * Quantization scale and shift are common for src_layer, src_iter,
+ * dst_iter and dst_layer.
+ */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_attr_set_rnn_data_qparams(
+ mkldnn_primitive_attr_t attr, const float scale, const float shift);
+
+/** Sets quantization scales @p weights_scales for RNN weights tensors.
+ * Low precision configuration of RNN primitive expects input weights to have
+ * signed int8 data type. Scales used to quantize floating point data
+ * to signed integer must be passed to RNN primitive using attributes.
+ * The @p mask argument defines correspondence between output tensor dimensions
+ * and the @p weights_scales array. Set i-th bit of @p mask to 1 to use
+ * dedicated scaling factor for each slice of the output tensor over i-th
+ * dimension. Set @p mask to 0 to use common scaling factor for the whole output
+ * tensor. Example usage:
+ * @code
+ * // rnn parameters
+ * int l = 2, t = 2, mb = 32, sic = 32, slc = 32, dic = 32, dlc = 32;
+ * // unique output scales per output channel
+ * float weights_scales[dic * n_gates] = { ... };
+ * // mask that specifies last two dimensions of ldigo format
+ * int mask = 0x3;
+ *
+ * mkldnn_primitive_attr_t attr;
+ * // create default attributes
+ * mkldnn_primitive_attr_create(&attr);
+ *
+ * // set output channel-wise weights scales
+ * mkldnn_primitive_attr_set_rnn_weights_qparams(attr, dic * n_gates, mask,
+ * weights_scales);
+ *
+ * // create & configure rnn op_desc
+ * mkldnn_rnn_desc_t rnn_d;
+ * mkldnn_primitive_desc_t rnn_pd;
+ * mkldnn_primitive_desc_create(&rnn_pd, &rnn_d, attr, engine, NULL);
+ * @endcode
+ * @note
+ * The dimension order is always native and does not depend on the actual
+ * layout used. For example, 5 dimensional weights always have
+ * (l, d, i, g, o) logical dimension ordering.
+ * @note
+ * Quantization sales are common for weights_layer and weights_iteration
+ * @note
+ * There is no way to check that @p count corresponds to @p mask until an
+ * actual primitive descriptor is created, so it is user's responsibility
+ * to set proper values. The following formula must be held:
+ *
+ * \f[count = \prod\limits_{d \in mask} output.dims[d]\f]
+ */
+mkldnn_status_t MKLDNN_API mkldnn_primitive_attr_set_rnn_weights_qparams (
+ mkldnn_primitive_attr_t attr, mkldnn_dim_t count, int mask,
+ const float *weights_scales);
+
+/** Initializes a rnn descriptor @p rnn_desc for forward propagation
+ * using @p prop_kind, @p rnn_cell_desc, @p direction, and memory descriptors.
+ * @note If @p prop_kind equals #mkldnn_forward_training, you must query a
+ * workspace memory descriptor before creating the primitive.
+ *
+ * @p src_iter_desc, @p bias_desc, and @p dst_iter_desc are allowed to either be
+ * @c NULL or point to a zero memory descriptor, which would indicate that the
+ * RNN primitive should not use them.
+ *
+ * @note All memory descriptors except @p src_iter_desc are allowed to be
+ * initialized with #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * Inputs:
+ * - src_layer (#mkldnn_query_src_md, 0)
+ * - src_iter (#mkldnn_query_src_md, 1), if used
+ * - weights_layer (#mkldnn_query_weights_md, 0)
+ * - weights_iter (#mkldnn_query_weights_md, 1)
+ * - bias (#mkldnn_query_weights_md, 2), if used
+ *
+ * Outputs:
+ * - dst_layer (#mkldnn_query_dst_md, 0)
+ * - dst_iter (#mkldnn_query_dst_md, 1), if used
+ * - workspace (#mkldnn_query_workspace_md, 0),
+ * if @p prop_kind equals #mkldnn_forward_training
+ */
+mkldnn_status_t MKLDNN_API mkldnn_rnn_forward_desc_init(
+ mkldnn_rnn_desc_t *rnn_desc, mkldnn_prop_kind_t prop_kind,
+ const mkldnn_rnn_cell_desc_t *rnn_cell_desc,
+ const mkldnn_rnn_direction_t direction,
+ const mkldnn_memory_desc_t *src_layer_desc,
+ const mkldnn_memory_desc_t *src_iter_desc,
+ const mkldnn_memory_desc_t *weights_layer_desc,
+ const mkldnn_memory_desc_t *weights_iter_desc,
+ const mkldnn_memory_desc_t *bias_desc,
+ const mkldnn_memory_desc_t *dst_layer_desc,
+ const mkldnn_memory_desc_t *dst_iter_desc);
+
+/** Initializes a rnn descriptor @p rnn_desc for backward propagation
+ * using @p prop_kind, @p rnn_cell_desc, @p direction, and memory descriptors.
+ *
+ * @note All memory descriptors are allowed to be initialized with
+ * #mkldnn_format_kind_any value of @p format_kind.
+ *
+ * @p src_iter_desc (simultaneously with @p diff_src_iter_desc),
+ * @p bias_desc (simultaneously with @p diff_bias_desc), and
+ * @p dst_iter_desc (simultaneously with @p diff_src_iter_desc) are allowed to
+ * either be @c NULL or point to a zero memory descriptor, which would indicate
+ * that the RNN primitive should not use them.
+ *
+ * Inputs:
+ * - src_layer (#mkldnn_query_src_md, 0)
+ * - src_iter (#mkldnn_query_src_md, 1), if used
+ * - weights_layer (#mkldnn_query_weights_md, 0)
+ * - weights_iter (#mkldnn_query_weights_md, 1)
+ * - bias (#mkldnn_query_weights_md, 2), if used
+ * - dst_layer (#mkldnn_query_dst_md, 0)
+ * - dst_iter (#mkldnn_query_dst_md, 1), if used
+ * - diff_dst_layer (#mkldnn_query_diff_dst_md, 0)
+ * - diff_dst_iter (#mkldnn_query_diff_dst_md, 1), if used
+ * - workspace (#mkldnn_query_workspace_md, 0)
+ *
+ * Outputs:
+ * - diff_src_layer (#mkldnn_query_diff_src_md, 0)
+ * - diff_src_iter (#mkldnn_query_diff_src_md, 1), if used
+ * - diff_weights_layer (#mkldnn_query_diff_weights_md, 0)
+ * - diff_weights_iter (#mkldnn_query_diff_weights_md, 1)
+ * - diff_bias (#mkldnn_query_diff_weights_md, 2), if used
+ */
+mkldnn_status_t MKLDNN_API mkldnn_rnn_backward_desc_init(
+ mkldnn_rnn_desc_t *rnn_desc, mkldnn_prop_kind_t prop_kind,
+ const mkldnn_rnn_cell_desc_t *rnn_cell_desc,
+ const mkldnn_rnn_direction_t direction,
+ const mkldnn_memory_desc_t *src_layer_desc,
+ const mkldnn_memory_desc_t *src_iter_desc,
+ const mkldnn_memory_desc_t *weights_layer_desc,
+ const mkldnn_memory_desc_t *weights_iter_desc,
+ const mkldnn_memory_desc_t *bias_desc,
+ const mkldnn_memory_desc_t *dst_layer_desc,
+ const mkldnn_memory_desc_t *dst_iter_desc,
+ const mkldnn_memory_desc_t *diff_src_layer_desc,
+ const mkldnn_memory_desc_t *diff_src_iter_desc,
+ const mkldnn_memory_desc_t *diff_weights_layer_desc,
+ const mkldnn_memory_desc_t *diff_weights_iter_desc,
+ const mkldnn_memory_desc_t *diff_bias_desc,
+ const mkldnn_memory_desc_t *diff_dst_layer,
+ const mkldnn_memory_desc_t *diff_dst_iter_desc);
+
+/** @} */
+
+/** @} */
+
+/** @addtogroup c_api_engine Engine operations
+ * @{ */
+
+/** Returns the number of engines of a particular @p kind. */
+size_t MKLDNN_API mkldnn_engine_get_count(mkldnn_engine_kind_t kind);
+
+/** Creates an @p engine of particular @p kind and @p index. */
+mkldnn_status_t MKLDNN_API mkldnn_engine_create(mkldnn_engine_t *engine,
+ mkldnn_engine_kind_t kind, size_t index);
+
+/** Returns the kind of an @p engine. */
+mkldnn_status_t MKLDNN_API mkldnn_engine_get_kind(mkldnn_engine_t engine,
+ mkldnn_engine_kind_t *kind);
+
+/** Destroys an @p engine. */
+mkldnn_status_t MKLDNN_API mkldnn_engine_destroy(mkldnn_engine_t engine);
+
+/** @} */
+
+/** @addtogroup c_api_stream Execution stream operations
+ * @{ */
+
+/** Creates an execution @p stream for @p engine and with @p flags. */
+mkldnn_status_t MKLDNN_API mkldnn_stream_create(mkldnn_stream_t *stream,
+ mkldnn_engine_t engine, unsigned flags);
+
+/** Destroys an execution @p stream. */
+mkldnn_status_t MKLDNN_API mkldnn_stream_destroy(mkldnn_stream_t stream);
+
+/** @} */
+
+/** @addtogroup c_api_service Service functions
+ * @{ */
+
+/** Sets verbosity level (print information to stdout).
+ * Possible levels are:
+ * - 0 -- no verbose output (default)
+ * - 1 -- primitive information at execution
+ * - 2 -- primitive information at creation and execution
+ *
+ * @note
+ * Dumping information might affect performance.
+ * This setting overrides the MKLDNN_VERBOSE environment variable. */
+mkldnn_status_t MKLDNN_API mkldnn_set_verbose(int level);
+
+/** Enables or disables dumping of JIT-generated code.
+ * The enable parameter can be:
+ * - 0 -- disable
+ * - any other value -- enable
+ *
+ * @note
+ * This setting overrides the MKLDNN_JIT_DUMP environment variable. */
+mkldnn_status_t MKLDNN_API mkldnn_set_jit_dump(int enable);
+
+/** Gets library version information.
+ * Version information includes:
+ * - major -- major version number
+ * - minor -- minor version number
+ * - patch -- patch release number
+ * - hash -- git commit hash */
+const mkldnn_version_t MKLDNN_API *mkldnn_version();
+
+/** @} */
+
+/** @addtogroup c_api_blas BLAS functions
+ * A subset of Basic Linear ALgebra (BLAS) functions to perform
+ * matrix-matrix multiplication.
+ * @{ */
+
+/** SGEMM performs a matrix-matrix multiplication operation defined as
+ *
+ * C := alpha*op( A )*op( B ) + beta*C
+ *
+ * where
+ * - op( X ) is one of op( X ) = X or op( X ) = X**T,
+ * - alpha and beta are scalars,
+ * - A, B and C are matrices, with op( A ) an m by k matrix, op( B ) a k by n matrix
+ * and C an m by n matrix.
+ *
+ * The matrices are assumed to be stored in column-major order (the elements
+ * in a matrix columns are contiguous in memory).
+ *
+ * @note
+ * The API is different from the standard BLAS routine
+ * because it returns mkldnn_status_t for error handling.
+ * XERBLA is not supported: no error message will be printed
+ * in case of incorrect parameters. */
+mkldnn_status_t MKLDNN_API mkldnn_sgemm(
+ const char *transa, const char *transb,
+ const mkldnn_dim_t *M, const mkldnn_dim_t *N, const mkldnn_dim_t *K,
+ const float *alpha, const float *A, const mkldnn_dim_t *lda,
+ const float *B, const mkldnn_dim_t *ldb,
+ const float *beta, float *C, const mkldnn_dim_t *ldc);
+
+/** gemm_s8u8s32 and gemm_s8s8s32 perform a matrix-matrix multiplication
+ * operation and add the result to a scalar-matrix product. For the final
+ * result, a vector is added to each row or column of the output matrix.
+ * The operation is defined as:
+ *
+ * C := alpha*(op(A) + A_offset) * (op(B) + B_offset) + beta*C + C_offset
+ *
+ * where
+ * - op( X ) = X or op( X ) = X**T,
+ * - A_offset is an m-by-k matrix with every element equal to the value oa,
+ * - B_offset is an k-by-n matrix with every element equal to the value ob,
+ * - C_offset is an m-by-n matrix defined by the oc array, size len:
+ * - if offsetc = F: len must be at least 1
+ * - if offsetc = C: len must be at least max(1, m)
+ * - if offsetc = R: len must be at least max(1, n)
+ * - alpha and beta are scalars, and A, B and C are matrices, with op( A )
+ * an m-by-k matrix, op( B ) a k-by-n matrix and C an m-by-n matrix.
+ *
+ * The matrices are assumed to be stored in column-major order (the elements
+ * in a matrix columns are contiguous in memory).
+ *
+ * @note
+ * The API is different compared with the standard BLAS routine
+ * because it returns mkldnn_status_t for error handling.
+ * XERBLA is not supported: no error message will be printed
+ * in case of incorrect parameters. */
+mkldnn_status_t MKLDNN_API mkldnn_gemm_s8u8s32(
+ const char *transa, const char *transb, const char *offsetc,
+ const mkldnn_dim_t *M, const mkldnn_dim_t *N, const mkldnn_dim_t *K,
+ const float *alpha,
+ const int8_t *A, const mkldnn_dim_t *lda, const int8_t *ao,
+ const uint8_t *B, const mkldnn_dim_t *ldb, const int8_t *bo,
+ const float *beta,
+ int32_t *c, const mkldnn_dim_t *ldc, const int32_t *co);
+
+mkldnn_status_t MKLDNN_API mkldnn_gemm_s8s8s32(
+ const char *transa, const char *transb, const char *offsetc,
+ const mkldnn_dim_t *M, const mkldnn_dim_t *N, const mkldnn_dim_t *K,
+ const float *alpha,
+ const int8_t *A, const mkldnn_dim_t *lda, const int8_t *ao,
+ const int8_t *B, const mkldnn_dim_t *ldb, const int8_t *bo,
+ const float *beta,
+ int32_t *c, const mkldnn_dim_t *ldc, const int32_t *co);
+/** @} */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/include/mkldnn.hpp b/thirdparty/oidn/mkl-dnn/include/mkldnn.hpp
new file mode 100644
index 0000000000..581400a013
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/include/mkldnn.hpp
@@ -0,0 +1,2615 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MKLDNN_HPP
+#define MKLDNN_HPP
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+#include <stdlib.h>
+#include <memory>
+#include <vector>
+#include <unordered_map>
+#include <algorithm>
+#include <iterator>
+
+#include "mkldnn.h"
+#endif
+
+namespace mkldnn {
+
+/// @addtogroup cpp_api C++ API
+/// @{
+
+/// @addtogroup cpp_api_utils Utils
+/// @{
+
+/// A class that provides the destructor for an Intel(R) MKL-DNN C handle
+template <typename T> class handle_traits {};
+
+/// A class for wrapping an Intel(R) MKL-DNN handle. It is used as the base
+/// class for primitive (#mkldnn_primitive_t), engine (#mkldnn_engine_t), and
+/// stream (#mkldnn_stream_t) handles. An object of the #mkldnn::handle class
+/// can be passed by value. This class enables wrapping:
+/// - Newly constructed handles.
+/// @n In this case, the constructed handle uses reference counting provided
+/// by @p std::shared_ptr with a proper deleter function specified through
+/// the @p handle_traits class.
+/// - Pre-existing handles returned by the Intel(R) MKL-DNN C API (for
+/// example, through mkldnn_primitive_get_primitive_desc()).
+/// @n In this case, an Intel(R) MKL-DNN C API handle is wrapped without a
+/// deleter because it is assumed that the handle wrapper for the original
+/// object deletes the handle (this model is similar to @p std::weak_ptr).
+template <typename T, typename traits=handle_traits<T>> class handle {
+private:
+ std::shared_ptr<typename std::remove_pointer<T>::type> _data;
+ handle(const handle &&) = delete;
+ handle &operator=(const handle &&other) = delete;
+protected:
+ bool operator==(const T other) const { return other == _data.get(); }
+ bool operator!=(const T other) const { return !(*this == other); }
+public:
+ /// Constructs a C handle wrapper.
+ /// @param t The C handle to wrap.
+ /// @param weak A flag to specify whether to construct a weak wrapper.
+ handle(T t = 0, bool weak = false): _data(0) {
+ reset(t, weak);
+ }
+
+ handle(const handle &other): _data(other._data) {}
+ handle &operator=(const handle &other) {
+ _data = other._data;
+ return *this;
+ }
+ /// Resets the value of a C handle.
+ /// @param t The new value of the C handle.
+ /// @param weak A flag to specify whether the wrapper should be weak.
+ void reset(T t, bool weak = false) {
+ auto dummy_destructor = [](T) { return decltype(traits::destructor(0))(0); };
+ _data.reset(t, weak ? dummy_destructor : traits::destructor);
+ }
+
+ /// Returns the value of the underlying C handle.
+ T get() const { return _data.get(); }
+
+ bool operator==(const handle &other) const { return other._data.get() == _data.get(); }
+ bool operator!=(const handle &other) const { return !(*this == other); }
+};
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+template <> struct handle_traits<mkldnn_memory_t> {
+ static constexpr auto destructor = &mkldnn_memory_destroy;
+};
+
+template <> struct handle_traits<mkldnn_primitive_desc_t> {
+ static constexpr auto destructor = &mkldnn_primitive_desc_destroy;
+};
+
+template <> struct handle_traits<mkldnn_primitive_t> {
+ static constexpr auto destructor = &mkldnn_primitive_destroy;
+};
+
+template <> struct handle_traits<mkldnn_primitive_desc_iterator_t> {
+ static constexpr auto destructor = &mkldnn_primitive_desc_iterator_destroy;
+};
+#endif
+
+struct memory;
+struct primitive_desc;
+
+/// Base class for all computational primitives.
+class primitive: public handle<mkldnn_primitive_t> {
+ friend struct error;
+ friend struct stream;
+ using handle::handle;
+public:
+ /// A proxy to C primitive kind enum
+ enum class kind {
+ undefined_primitive = mkldnn_undefined_primitive,
+ reorder = mkldnn_reorder,
+ concat = mkldnn_concat,
+ sum = mkldnn_sum,
+ convolution = mkldnn_convolution,
+ deconvolution = mkldnn_deconvolution,
+ shuffle = mkldnn_shuffle,
+ eltwise = mkldnn_eltwise,
+ softmax = mkldnn_softmax,
+ pooling = mkldnn_pooling,
+ lrn = mkldnn_lrn,
+ batch_normalization = mkldnn_batch_normalization,
+ inner_product = mkldnn_inner_product,
+ rnn = mkldnn_rnn,
+ };
+
+ primitive(const_mkldnn_primitive_desc_t c_pd);
+ primitive(const primitive_desc &pd);
+
+ /// Returns the descriptor of the underlying C API primitive.
+ inline const_mkldnn_primitive_desc_t get_primitive_desc() const;
+ // TODO: use the C++ API wrapper structure.
+
+ void execute(struct stream &astream,
+ const std::unordered_map<int, memory> &args) const;
+};
+
+inline mkldnn_primitive_kind_t convert_to_c(primitive::kind akind) {
+ return static_cast<mkldnn_primitive_kind_t>(akind);
+}
+/// Intel(R) MKL-DNN exception class.
+///
+/// This class captures the status returned by the failed C API function, error
+/// message, and, optionally, handle of the primitive that caused the error.
+struct error: public std::exception {
+ mkldnn_status_t status;
+ const char *message;
+
+ /// Constructs an error instance.
+ ///
+ /// @param astatus The error status returned by the C API.
+ /// @param amessage The error message.
+ error(mkldnn_status_t astatus, const char *amessage)
+ : status(astatus), message(amessage) {}
+
+ /// A convenience function for wrapping calls to the C API. Checks the
+ /// return status and throws an #error in case of failure.
+ ///
+ /// @param status The error status returned by the C API.
+ /// @param message The error message.
+ static void wrap_c_api(mkldnn_status_t status, const char *message) {
+ if (status != mkldnn_success)
+ throw error(status, message);
+ }
+};
+
+const_mkldnn_primitive_desc_t primitive::get_primitive_desc() const {
+ const_mkldnn_primitive_desc_t pd;
+ error::wrap_c_api(mkldnn_primitive_get_primitive_desc(get(), &pd),
+ "could not get primitive descriptor by primitive");
+ return pd;
+}
+/// @}
+
+/// @addtogroup cpp_api_enums Common data types and enumerations
+/// A proxy to @ref c_api_types in @ref c_api.
+///
+/// @{
+
+enum scratchpad_mode {
+ scratchpad_mode_library = mkldnn_scratchpad_mode_library,
+ scratchpad_mode_user = mkldnn_scratchpad_mode_user,
+};
+
+inline mkldnn_scratchpad_mode_t convert_to_c(scratchpad_mode mode) {
+ return static_cast<mkldnn_scratchpad_mode_t>(mode);
+}
+
+enum padding_kind {
+ zero = mkldnn_padding_zero
+};
+
+inline mkldnn_padding_kind_t convert_to_c(padding_kind kind) {
+ return static_cast<mkldnn_padding_kind_t>(kind);
+}
+
+enum prop_kind {
+ forward_training = mkldnn_forward_training,
+ forward_scoring = mkldnn_forward_scoring,
+ forward_inference = mkldnn_forward_inference,
+ forward = mkldnn_forward,
+ backward = mkldnn_backward,
+ backward_data = mkldnn_backward_data,
+ backward_weights = mkldnn_backward_weights,
+ backward_bias = mkldnn_backward_bias
+};
+
+inline mkldnn_prop_kind_t convert_to_c(prop_kind kind) {
+ return static_cast<mkldnn_prop_kind_t>(kind);
+}
+
+enum algorithm {
+ algorithm_undef = mkldnn_alg_kind_undef,
+ convolution_auto = mkldnn_convolution_auto,
+ convolution_direct = mkldnn_convolution_direct,
+ convolution_winograd = mkldnn_convolution_winograd,
+ deconvolution_direct = mkldnn_deconvolution_direct,
+ deconvolution_winograd = mkldnn_deconvolution_winograd,
+ eltwise_relu = mkldnn_eltwise_relu,
+ eltwise_tanh = mkldnn_eltwise_tanh,
+ eltwise_elu = mkldnn_eltwise_elu,
+ eltwise_square = mkldnn_eltwise_square,
+ eltwise_abs = mkldnn_eltwise_abs,
+ eltwise_sqrt = mkldnn_eltwise_sqrt,
+ eltwise_linear = mkldnn_eltwise_linear,
+ eltwise_bounded_relu = mkldnn_eltwise_bounded_relu,
+ eltwise_soft_relu = mkldnn_eltwise_soft_relu,
+ eltwise_logistic = mkldnn_eltwise_logistic,
+ lrn_across_channels = mkldnn_lrn_across_channels,
+ lrn_within_channel = mkldnn_lrn_within_channel,
+ pooling_max = mkldnn_pooling_max,
+ pooling_avg = mkldnn_pooling_avg,
+ pooling_avg_include_padding = mkldnn_pooling_avg_include_padding,
+ pooling_avg_exclude_padding = mkldnn_pooling_avg_exclude_padding,
+ vanilla_rnn = mkldnn_vanilla_rnn,
+ vanilla_lstm = mkldnn_vanilla_lstm,
+ vanilla_gru = mkldnn_vanilla_gru,
+ gru_linear_before_reset = mkldnn_gru_linear_before_reset
+};
+
+inline mkldnn_alg_kind_t convert_to_c(algorithm aalgorithm) {
+ return static_cast<mkldnn_alg_kind_t>(aalgorithm);
+}
+
+enum batch_normalization_flag {
+ use_global_stats = mkldnn_use_global_stats,
+ use_scale_shift = mkldnn_use_scaleshift,
+ fuse_bn_relu = mkldnn_fuse_bn_relu
+};
+
+inline mkldnn_batch_normalization_flag_t convert_to_c(
+ batch_normalization_flag aflag) {
+ return static_cast<mkldnn_batch_normalization_flag_t>(aflag);
+}
+
+enum rnn_direction {
+ unidirectional_left2right = mkldnn_unidirectional_left2right,
+ unidirectional_right2left = mkldnn_unidirectional_right2left,
+ unidirectional = mkldnn_unidirectional,
+ bidirectional_concat = mkldnn_bidirectional_concat,
+ bidirectional_sum = mkldnn_bidirectional_sum,
+};
+
+inline mkldnn_rnn_direction_t convert_to_c(rnn_direction adir) {
+ return static_cast<mkldnn_rnn_direction_t>(adir);
+}
+
+enum query {
+ undef = mkldnn_query_undef,
+
+ query_engine = mkldnn_query_engine,
+ primitive_kind = mkldnn_query_primitive_kind,
+
+ num_of_inputs_s32 = mkldnn_query_num_of_inputs_s32,
+ num_of_outputs_s32 = mkldnn_query_num_of_outputs_s32,
+
+ time_estimate_f64 = mkldnn_query_time_estimate_f64,
+ memory_consumption_s64 = mkldnn_query_memory_consumption_s64,
+
+ query_scratchpad_engine = mkldnn_query_scratchpad_engine,
+
+ impl_info_str = mkldnn_query_impl_info_str,
+
+ op_d = mkldnn_query_op_d,
+ convolution_d = mkldnn_query_convolution_d,
+ deconvolution_d = mkldnn_query_deconvolution_d,
+ shuffle_d = mkldnn_query_shuffle_d,
+ eltwise_d = mkldnn_query_eltwise_d,
+ softmax_d = mkldnn_query_softmax_d,
+ pooling_d = mkldnn_query_pooling_d,
+ lrn_d = mkldnn_query_lrn_d,
+ batch_normalization_d = mkldnn_query_batch_normalization_d,
+ inner_product_d = mkldnn_query_inner_product_d,
+ rnn_d = mkldnn_query_rnn_d,
+
+ src_md = mkldnn_query_src_md,
+ diff_src_md = mkldnn_query_diff_src_md,
+ weights_md = mkldnn_query_weights_md,
+ diff_weights_md = mkldnn_query_diff_weights_md,
+ dst_md = mkldnn_query_dst_md,
+ diff_dst_md = mkldnn_query_diff_dst_md,
+ workspace_md = mkldnn_query_workspace_md,
+ scratchpad_md = mkldnn_query_scratchpad_md,
+};
+
+inline mkldnn_query_t convert_to_c(query aquery) {
+ return static_cast<mkldnn_query_t>(aquery);
+}
+
+/// @}
+
+/// @addtogroup cpp_api_attr Attributes
+/// An extension for controlling primitive behavior.
+///
+/// @sa @ref c_api_attributes in @ref c_api
+/// @{
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+template <> struct handle_traits<mkldnn_post_ops_t> {
+ static constexpr auto destructor = &mkldnn_post_ops_destroy;
+};
+#endif
+
+struct post_ops: public handle<mkldnn_post_ops_t> {
+ post_ops() {
+ mkldnn_post_ops_t result;
+ error::wrap_c_api(mkldnn_post_ops_create(&result),
+ "could not create post operation sequence");
+ reset(result);
+ }
+
+ int len() const { return mkldnn_post_ops_len(get()); }
+
+ primitive::kind kind(int index) const {
+ error::wrap_c_api(
+ index < len() ? mkldnn_success : mkldnn_invalid_arguments,
+ "post_ops index is out of range");
+ return static_cast<primitive::kind>(mkldnn_post_ops_get_kind(get(),
+ index));
+ }
+
+ void append_sum(float scale = 1.) {
+ error::wrap_c_api(mkldnn_post_ops_append_sum(get(), scale),
+ "could not append sum");
+ }
+
+ void get_params_sum(int index, float &scale) const {
+ error::wrap_c_api(mkldnn_post_ops_get_params_sum(get(), index, &scale),
+ "could not get sum params");
+ }
+
+ void append_eltwise(float scale, algorithm alg, float alpha,
+ float beta) {
+ error::wrap_c_api(mkldnn_post_ops_append_eltwise(get(), scale,
+ convert_to_c(alg), alpha, beta),
+ "could not append eltwise");
+ }
+
+ void get_params_eltwise(int index, float &scale, algorithm &alg,
+ float &alpha, float &beta) const {
+ mkldnn_alg_kind_t c_alg;
+ error::wrap_c_api(mkldnn_post_ops_get_params_eltwise(get(), index,
+ &scale, &c_alg, &alpha, &beta),
+ "could not get eltwise params");
+ alg = static_cast<algorithm>(c_alg);
+ }
+};
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+template <> struct handle_traits<mkldnn_primitive_attr_t> {
+ static constexpr auto destructor = &mkldnn_primitive_attr_destroy;
+};
+#endif
+
+struct primitive_attr: public handle<mkldnn_primitive_attr_t> {
+ primitive_attr() {
+ mkldnn_primitive_attr_t result;
+ error::wrap_c_api(mkldnn_primitive_attr_create(&result),
+ "could not create a primitive attr");
+ reset(result);
+ }
+
+ scratchpad_mode get_scratchpad_mode() const {
+ mkldnn_scratchpad_mode_t result;
+ error::wrap_c_api(mkldnn_primitive_attr_get_scratchpad_mode(
+ get(), &result), "could not get scratchpad mode");
+ return scratchpad_mode(result);
+ }
+
+ void set_scratchpad_mode(scratchpad_mode mode) {
+ error::wrap_c_api(mkldnn_primitive_attr_set_scratchpad_mode(
+ get(), mkldnn::convert_to_c(mode)),
+ "could not set scratchpad mode");
+ }
+
+ void get_output_scales(int &mask, std::vector<float> &scales) const
+ {
+ mkldnn_dim_t count;
+ int c_mask;
+ const float *c_scales;
+ error::wrap_c_api(mkldnn_primitive_attr_get_output_scales(get(),
+ &count, &c_mask, &c_scales),
+ "could not get int output scales");
+ scales.resize(count);
+
+ mask = c_mask;
+ for (mkldnn_dim_t c = 0; c < count; ++c)
+ scales[c] = c_scales[c];
+ }
+
+ void set_output_scales(int mask, const std::vector<float> &scales)
+ {
+ error::wrap_c_api(mkldnn_primitive_attr_set_output_scales(get(),
+ (mkldnn_dim_t)scales.size(), mask, &scales[0]),
+ "could not set int output scales");
+ }
+
+ const post_ops get_post_ops() const {
+ post_ops result;
+ const_mkldnn_post_ops_t c_result;
+ error::wrap_c_api(mkldnn_primitive_attr_get_post_ops(get(), &c_result),
+ "could not get post operation sequence");
+ result.reset(const_cast<mkldnn_post_ops_t>(c_result), true);
+ return result;
+ }
+
+ void set_post_ops(post_ops ops) {
+ error::wrap_c_api(mkldnn_primitive_attr_set_post_ops(get(), ops.get()),
+ "could not set post operation sequence");
+ }
+
+ void set_rnn_data_qparams(const float scale, const float shift)
+ {
+ error::wrap_c_api(mkldnn_primitive_attr_set_rnn_data_qparams(get(),
+ scale, shift), "could not set rnn data int scale/shift");
+ }
+
+ void set_rnn_weights_qparams(int mask, const std::vector<float> &scales)
+ {
+ error::wrap_c_api(mkldnn_primitive_attr_set_rnn_weights_qparams(get(),
+ (int)scales.size(), mask, &scales[0]),
+ "could not set rnn weights int scales");
+ }
+};
+
+/// @}
+
+/// @addtogroup cpp_api_engine Engine
+/// Engine operations.
+///
+/// @sa @ref c_api_engine in @ref c_api
+/// @{
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+template <> struct handle_traits<mkldnn_engine_t> {
+ static constexpr auto destructor = &mkldnn_engine_destroy;
+};
+#endif
+
+/// An execution engine.
+struct engine: public handle<mkldnn_engine_t> {
+ friend class primitive;
+ // gcc bug??? using handle::handle;
+
+ /// Kinds of engines.
+ enum kind {
+ /// An unspecified engine
+ any = mkldnn_any_engine,
+ /// CPU engine
+ cpu = mkldnn_cpu,
+ };
+
+ /// Returns the number of engines of a certain kind.
+ ///
+ /// @param akind The kind of engines to count.
+
+ static size_t get_count(kind akind) {
+ return mkldnn_engine_get_count(convert_to_c(akind));
+ }
+
+ /// Constructs an engine.
+ ///
+ /// @param akind The kind of engine to construct.
+ /// @param index The index of the engine. Must be less than the value
+ /// returned by #get_count() for this particular kind of engine.
+
+ engine(kind akind, size_t index) {
+ mkldnn_engine_t aengine;
+ error::wrap_c_api(
+ mkldnn_engine_create(&aengine,
+ convert_to_c(akind), index),
+ "could not create an engine");
+ reset(aengine);
+ }
+
+ explicit engine(const mkldnn_engine_t& aengine)
+ : handle(aengine, true) {}
+
+ engine(const handle<mkldnn_primitive_desc_t> &pd) {
+ mkldnn_engine_t engine_q;
+ error::wrap_c_api(
+ mkldnn_primitive_desc_query(pd.get(),
+ mkldnn::convert_to_c(query_engine), 0, &engine_q),
+ "could not get engine from primitive_desc");
+ reset(engine_q, true);
+ }
+
+ template <class primitive_desc>
+ static engine query(const primitive_desc &pd) {
+ mkldnn_engine_t engine_q;
+ error::wrap_c_api(
+ mkldnn_primitive_desc_query(pd.get(),
+ mkldnn::convert_to_c(query_engine), 0, &engine_q),
+ "could not get engine from primitive_desc");
+
+ return engine(engine_q);
+ }
+
+private:
+ static mkldnn_engine_kind_t convert_to_c(kind akind) {
+ return static_cast<mkldnn_engine_kind_t>(akind);
+ }
+};
+
+/// @}
+
+/// @addtogroup cpp_api_stream Stream
+/// Execution stream operations
+///
+/// @sa @ref c_api_stream in @ref c_api
+/// @{
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+template <> struct handle_traits<mkldnn_stream_t> {
+ static constexpr auto destructor = &mkldnn_stream_destroy;
+};
+#endif
+
+struct stream: public handle<mkldnn_stream_t> {
+ using handle::handle;
+
+ enum: unsigned {
+ default_flags = mkldnn_stream_default_flags,
+ };
+
+ /// Constructs a stream.
+ stream(const engine &aengine,
+ unsigned flags = static_cast<unsigned>(default_flags)) {
+ mkldnn_stream_t astream;
+ error::wrap_c_api(mkldnn_stream_create(&astream, aengine.get(), flags),
+ "could not create a stream");
+ reset(astream);
+ }
+};
+
+/// @}
+
+/// @addtogroup cpp_api_memory_related Memory and memory related operations
+/// @{
+
+/// @addtogroup cpp_api_memory Memory
+/// A primitive to describe and store data.
+///
+/// For more information, refer to @ref c_api_memory in @ref c_api.
+/// @{
+
+/// Memory that describes the data.
+struct memory: public handle<mkldnn_memory_t> {
+ public:
+ typedef mkldnn_dim_t dim;
+ typedef std::vector<dim> dims;
+
+ template <typename T> static void validate_dims(const std::vector<T> &v) {
+ if (v.size() > MKLDNN_MAX_NDIMS)
+ throw error(mkldnn_invalid_arguments, "invalid dimensions");
+ }
+
+ /// Data type specification. See #mkldnn_data_type_t for a detailed
+ /// description.
+ enum data_type {
+ data_undef = mkldnn_data_type_undef,
+ f32 = mkldnn_f32,
+ s32 = mkldnn_s32,
+ s8 = mkldnn_s8,
+ u8 = mkldnn_u8,
+ };
+
+ /// Memory format tag specification. See #mkldnn_format_tag_t
+ /// for a detailed description.
+ enum format_tag {
+ format_tag_undef = mkldnn_format_tag_undef,
+ any = mkldnn_format_tag_any,
+ a = mkldnn_a,
+ ab = mkldnn_ab,
+ abc = mkldnn_abc,
+ abcd = mkldnn_abcd,
+ abcde = mkldnn_abcde,
+ abcdef = mkldnn_abcdef,
+ abdec = mkldnn_abdec,
+ acb = mkldnn_acb,
+ acbde = mkldnn_acbde,
+ acdb = mkldnn_acdb,
+ acdeb = mkldnn_acdeb,
+ ba = mkldnn_ba,
+ bac = mkldnn_bac,
+ bacd = mkldnn_bacd,
+ bcda = mkldnn_bcda,
+ cba = mkldnn_cba,
+ cdba = mkldnn_cdba,
+ cdeba = mkldnn_cdeba,
+ decab = mkldnn_decab,
+ Abc16a = mkldnn_Abc16a,
+ ABc16a16b = mkldnn_ABc16a16b,
+ aBc16b = mkldnn_aBc16b,
+ ABc16b16a = mkldnn_ABc16b16a,
+ Abc4a = mkldnn_Abc4a,
+ aBc4b = mkldnn_aBc4b,
+ ABc4b16a4b = mkldnn_ABc4b16a4b,
+ ABc4b4a = mkldnn_ABc4b4a,
+ ABc8a16b2a = mkldnn_ABc8a16b2a,
+ ABc8a8b = mkldnn_ABc8a8b,
+ aBc8b = mkldnn_aBc8b,
+ ABc8b16a2b = mkldnn_ABc8b16a2b,
+ ABc8b8a = mkldnn_ABc8b8a,
+ Abcd16a = mkldnn_Abcd16a,
+ ABcd16a16b = mkldnn_ABcd16a16b,
+ aBcd16b = mkldnn_aBcd16b,
+ ABcd16b16a = mkldnn_ABcd16b16a,
+ aBCd16b16c = mkldnn_aBCd16b16c,
+ aBCd16c16b = mkldnn_aBCd16c16b,
+ Abcd4a = mkldnn_Abcd4a,
+ aBcd4b = mkldnn_aBcd4b,
+ ABcd4b16a4b = mkldnn_ABcd4b16a4b,
+ ABcd4b4a = mkldnn_ABcd4b4a,
+ aBCd4c16b4c = mkldnn_aBCd4c16b4c,
+ aBCd4c4b = mkldnn_aBCd4c4b,
+ ABcd8a16b2a = mkldnn_ABcd8a16b2a,
+ ABcd8a8b = mkldnn_ABcd8a8b,
+ aBcd8b = mkldnn_aBcd8b,
+ ABcd8b16a2b = mkldnn_ABcd8b16a2b,
+ aBCd8b16c2b = mkldnn_aBCd8b16c2b,
+ ABcd8b8a = mkldnn_ABcd8b8a,
+ aBCd8b8c = mkldnn_aBCd8b8c,
+ aBCd8c16b2c = mkldnn_aBCd8c16b2c,
+ aBCd8c8b = mkldnn_aBCd8c8b,
+ Abcde16a = mkldnn_Abcde16a,
+ ABcde16a16b = mkldnn_ABcde16a16b,
+ aBcde16b = mkldnn_aBcde16b,
+ ABcde16b16a = mkldnn_ABcde16b16a,
+ aBCde16b16c = mkldnn_aBCde16b16c,
+ aBCde16c16b = mkldnn_aBCde16c16b,
+ aBCde2c8b4c = mkldnn_aBCde2c8b4c,
+ Abcde4a = mkldnn_Abcde4a,
+ aBcde4b = mkldnn_aBcde4b,
+ ABcde4b4a = mkldnn_ABcde4b4a,
+ aBCde4b4c = mkldnn_aBCde4b4c,
+ aBCde4c16b4c = mkldnn_aBCde4c16b4c,
+ aBCde4c4b = mkldnn_aBCde4c4b,
+ Abcde8a = mkldnn_Abcde8a,
+ ABcde8a8b = mkldnn_ABcde8a8b,
+ aBcde8b = mkldnn_aBcde8b,
+ ABcde8b16a2b = mkldnn_ABcde8b16a2b,
+ aBCde8b16c2b = mkldnn_aBCde8b16c2b,
+ ABcde8b8a = mkldnn_ABcde8b8a,
+ aBCde8b8c = mkldnn_aBCde8b8c,
+ aBCde8c16b2c = mkldnn_aBCde8c16b2c,
+ aBCde8c8b = mkldnn_aBCde8c8b,
+ aBcdef16b = mkldnn_aBcdef16b,
+ aBCdef16b16c = mkldnn_aBCdef16b16c,
+ aBCdef16c16b = mkldnn_aBCdef16c16b,
+ aBcdef4b = mkldnn_aBcdef4b,
+ aBCdef4c4b = mkldnn_aBCdef4c4b,
+ aBCdef8b8c = mkldnn_aBCdef8b8c,
+ aBCdef8c16b2c = mkldnn_aBCdef8c16b2c,
+ aBCdef8c8b = mkldnn_aBCdef8c8b,
+ aBdc16b = mkldnn_aBdc16b,
+ aBdc4b = mkldnn_aBdc4b,
+ aBdc8b = mkldnn_aBdc8b,
+ aBdec16b = mkldnn_aBdec16b,
+ aBdec4b = mkldnn_aBdec4b,
+ aBdec8b = mkldnn_aBdec8b,
+ aBdefc16b = mkldnn_aBdefc16b,
+ aBdefc4b = mkldnn_aBdefc4b,
+ aBdefc8b = mkldnn_aBdefc8b,
+ Acb16a = mkldnn_Acb16a,
+ Acb4a = mkldnn_Acb4a,
+ Acb8a = mkldnn_Acb8a,
+ aCBd16b16c = mkldnn_aCBd16b16c,
+ aCBde16b16c = mkldnn_aCBde16b16c,
+ Acdb16a = mkldnn_Acdb16a,
+ Acdb4a = mkldnn_Acdb4a,
+ Acdb8a = mkldnn_Acdb8a,
+ Acdeb16a = mkldnn_Acdeb16a,
+ Acdeb4a = mkldnn_Acdeb4a,
+ Acdeb8a = mkldnn_Acdeb8a,
+ BAc16a16b = mkldnn_BAc16a16b,
+ BAcd16a16b = mkldnn_BAcd16a16b,
+ format_tag_last = mkldnn_format_tag_last,
+
+ x = mkldnn_x,
+ nc = mkldnn_nc,
+ cn = mkldnn_cn,
+ ncw = mkldnn_ncw,
+ nwc = mkldnn_nwc,
+ nchw = mkldnn_nchw,
+ nhwc = mkldnn_nhwc,
+ chwn = mkldnn_chwn,
+ ncdhw = mkldnn_ncdhw,
+ ndhwc = mkldnn_ndhwc,
+ oi = mkldnn_oi,
+ io = mkldnn_io,
+ oiw = mkldnn_oiw,
+ wio = mkldnn_wio,
+ oihw = mkldnn_oihw,
+ hwio = mkldnn_hwio,
+ ihwo = mkldnn_ihwo,
+ iohw = mkldnn_iohw,
+ oidhw = mkldnn_oidhw,
+ dhwio = mkldnn_dhwio,
+ goiw = mkldnn_goiw,
+ goihw = mkldnn_goihw,
+ hwigo = mkldnn_hwigo,
+ giohw = mkldnn_giohw,
+ goidhw = mkldnn_goidhw,
+ tnc = mkldnn_tnc,
+ ntc = mkldnn_ntc,
+ ldsnc = mkldnn_ldsnc,
+ ldigo = mkldnn_ldigo,
+ ldgoi = mkldnn_ldgoi,
+ ldgo = mkldnn_ldgo,
+ nCdhw16c = mkldnn_nCdhw16c,
+ nCdhw4c = mkldnn_nCdhw4c,
+ nCdhw8c = mkldnn_nCdhw8c,
+ nChw16c = mkldnn_nChw16c,
+ nChw4c = mkldnn_nChw4c,
+ nChw8c = mkldnn_nChw8c,
+ nCw16c = mkldnn_nCw16c,
+ nCw4c = mkldnn_nCw4c,
+ nCw8c = mkldnn_nCw8c,
+ IOw16o16i = mkldnn_IOw16o16i,
+ OIw16i16o = mkldnn_OIw16i16o,
+ OIw16o16i = mkldnn_OIw16o16i,
+ Oiw16o = mkldnn_Oiw16o,
+ OIw4i16o4i = mkldnn_OIw4i16o4i,
+ OIw4i4o = mkldnn_OIw4i4o,
+ Oiw4o = mkldnn_Oiw4o,
+ OIw8i16o2i = mkldnn_OIw8i16o2i,
+ OIw8i8o = mkldnn_OIw8i8o,
+ OIw8o16i2o = mkldnn_OIw8o16i2o,
+ OIw8o8i = mkldnn_OIw8o8i,
+ Owi16o = mkldnn_Owi16o,
+ Owi4o = mkldnn_Owi4o,
+ Owi8o = mkldnn_Owi8o,
+ IOhw16o16i = mkldnn_IOhw16o16i,
+ Ohwi16o = mkldnn_Ohwi16o,
+ Ohwi4o = mkldnn_Ohwi4o,
+ Ohwi8o = mkldnn_Ohwi8o,
+ OIhw16i16o = mkldnn_OIhw16i16o,
+ OIhw16o16i = mkldnn_OIhw16o16i,
+ Oihw16o = mkldnn_Oihw16o,
+ OIhw4i16o4i = mkldnn_OIhw4i16o4i,
+ OIhw4i4o = mkldnn_OIhw4i4o,
+ Oihw4o = mkldnn_Oihw4o,
+ OIhw8i16o2i = mkldnn_OIhw8i16o2i,
+ OIhw8i8o = mkldnn_OIhw8i8o,
+ OIhw8o16i2o = mkldnn_OIhw8o16i2o,
+ OIhw8o8i = mkldnn_OIhw8o8i,
+ Odhwi16o = mkldnn_Odhwi16o,
+ Odhwi4o = mkldnn_Odhwi4o,
+ Odhwi8o = mkldnn_Odhwi8o,
+ OIdhw16i16o = mkldnn_OIdhw16i16o,
+ OIdhw16o16i = mkldnn_OIdhw16o16i,
+ Oidhw16o = mkldnn_Oidhw16o,
+ OIdhw4i4o = mkldnn_OIdhw4i4o,
+ Oidhw4o = mkldnn_Oidhw4o,
+ OIdhw8i16o2i = mkldnn_OIdhw8i16o2i,
+ OIdhw8i8o = mkldnn_OIdhw8i8o,
+ OIdhw8o8i = mkldnn_OIdhw8o8i,
+ gIOw16o16i = mkldnn_gIOw16o16i,
+ gOIw16i16o = mkldnn_gOIw16i16o,
+ gOIw16o16i = mkldnn_gOIw16o16i,
+ gOiw16o = mkldnn_gOiw16o,
+ gOIw4i16o4i = mkldnn_gOIw4i16o4i,
+ gOIw4i4o = mkldnn_gOIw4i4o,
+ gOiw4o = mkldnn_gOiw4o,
+ gOIw8i16o2i = mkldnn_gOIw8i16o2i,
+ gOIw8i8o = mkldnn_gOIw8i8o,
+ gOIw8o16i2o = mkldnn_gOIw8o16i2o,
+ gOIw8o8i = mkldnn_gOIw8o8i,
+ gOwi16o = mkldnn_gOwi16o,
+ gOwi4o = mkldnn_gOwi4o,
+ gOwi8o = mkldnn_gOwi8o,
+ gIOhw16o16i = mkldnn_gIOhw16o16i,
+ gOhwi16o = mkldnn_gOhwi16o,
+ gOhwi4o = mkldnn_gOhwi4o,
+ gOhwi8o = mkldnn_gOhwi8o,
+ Goihw16g = mkldnn_Goihw16g,
+ gOIhw16i16o = mkldnn_gOIhw16i16o,
+ gOIhw16o16i = mkldnn_gOIhw16o16i,
+ gOihw16o = mkldnn_gOihw16o,
+ gOIhw2i8o4i = mkldnn_gOIhw2i8o4i,
+ gOIhw4i16o4i = mkldnn_gOIhw4i16o4i,
+ gOIhw4i4o = mkldnn_gOIhw4i4o,
+ gOIhw4o4i = mkldnn_gOIhw4o4i,
+ gOihw4o = mkldnn_gOihw4o,
+ Goihw8g = mkldnn_Goihw8g,
+ gOIhw8i16o2i = mkldnn_gOIhw8i16o2i,
+ gOIhw8i8o = mkldnn_gOIhw8i8o,
+ gOIhw8o16i2o = mkldnn_gOIhw8o16i2o,
+ gOIhw8o8i = mkldnn_gOIhw8o8i,
+ gOdhwi16o = mkldnn_gOdhwi16o,
+ gOdhwi4o = mkldnn_gOdhwi4o,
+ gOdhwi8o = mkldnn_gOdhwi8o,
+ gOIdhw16i16o = mkldnn_gOIdhw16i16o,
+ gOIdhw16o16i = mkldnn_gOIdhw16o16i,
+ gOidhw16o = mkldnn_gOidhw16o,
+ gOIdhw4i4o = mkldnn_gOIdhw4i4o,
+ gOidhw4o = mkldnn_gOidhw4o,
+ gOIdhw8i16o2i = mkldnn_gOIdhw8i16o2i,
+ gOIdhw8i8o = mkldnn_gOIdhw8i8o,
+ gOIdhw8o8i = mkldnn_gOIdhw8o8i,
+ };
+
+ /// A memory descriptor.
+ struct desc {
+ friend struct memory;
+ /// The underlying C API data structure.
+ mkldnn_memory_desc_t data;
+
+ /// Constructs a zero memory descriptor
+ desc(): data() {}
+
+ /// Constructs a memory descriptor.
+ ///
+ /// @param adims Data dimensions
+ /// @param adata_type Data precision/type.
+ /// @param aformat Data layout format tag.
+ desc(const dims &adims, data_type adata_type,
+ format_tag aformat) {
+ validate_dims(adims);
+ error::wrap_c_api(mkldnn_memory_desc_init_by_tag(&data, (int)adims.size(),
+ adims.size() == 0 ? nullptr : &adims[0],
+ convert_to_c(adata_type), convert_to_c(aformat)),
+ "could not initialize a memory descriptor");
+ }
+
+ /// Constructs a memory descriptor from a C API data structure.
+ ///
+ /// @param adata A C API #mkldnn_memory_desc_t structure.
+ desc(const mkldnn_memory_desc_t &adata): data(adata) {}
+
+ /// Constructs a sub-memory descriptor
+ //
+ /// @param adims Sizes of a sub-memory
+ /// @param offsets Offsets of a sub-memory
+ desc submemory_desc(const dims &adims, const dims &offsets) {
+ mkldnn_memory_desc_t sub_md;
+ error::wrap_c_api(mkldnn_memory_desc_init_submemory(&sub_md,
+ &data, &adims[0], &offsets[0]),
+ "could not initialize a sub-memory");
+ return desc(sub_md);
+ }
+
+ /// Returns the number of bytes required to allocate the memory described
+ /// including the padding area.
+ size_t get_size() const { return mkldnn_memory_desc_get_size(&data); }
+
+ bool operator==(const desc &other) const {
+ return mkldnn_memory_desc_equal(&data, &other.data) != 0;
+ }
+
+ bool operator!=(const desc &other) const { return !operator==(other); }
+ };
+
+ /// Constructs a memory.
+ ///
+ /// @param md Memory descriptor.
+ /// @param aengine Engine.
+ /// @param ahandle Native handle.
+ memory(const desc &md, const engine &aengine, void *ahandle) {
+ mkldnn_memory_t result;
+ error::wrap_c_api(mkldnn_memory_create(&result, &md.data,
+ aengine.get(), ahandle), "could not create a memory");
+ reset(result);
+ }
+
+ /// Constructs a memory.
+ ///
+ /// @param md Memory descriptor.
+ /// @param aengine Engine.
+ memory(const desc &md, const engine &aengine)
+ : memory(md, aengine, MKLDNN_NATIVE_HANDLE_ALLOCATE) {}
+
+ /// Returns the descriptor of the memory.
+ desc get_desc() const {
+ const mkldnn_memory_desc_t *cdesc;
+ error::wrap_c_api(mkldnn_memory_get_memory_desc(get(), &cdesc),
+ "could not get memory descriptor from a memory");
+ return desc(*cdesc);
+ }
+
+ /// Returns the engine of the memory.
+ engine get_engine() const {
+ mkldnn_engine_t engine_q;
+ error::wrap_c_api(mkldnn_memory_get_engine(get(), &engine_q),
+ "could not get engine from a memory");
+ return engine(engine_q);
+ }
+
+ /// Returns a handle of the data contained in the memory.
+ ///
+ /// On the CPU engine, this is a pointer to the allocated memory.
+ void *get_data_handle() const {
+ void *handle;
+ error::wrap_c_api(mkldnn_memory_get_data_handle(get(), &handle),
+ "could not get native handle");
+ return handle;
+ }
+
+ void set_data_handle(void *handle) const {
+ error::wrap_c_api(mkldnn_memory_set_data_handle(get(), handle),
+ "could not set native handle");
+ }
+
+ // Must go away or be private:
+ static mkldnn_data_type_t convert_to_c(data_type adata_type) {
+ return static_cast<mkldnn_data_type_t>(adata_type);
+ }
+ static mkldnn_format_tag_t convert_to_c(format_tag aformat) {
+ return static_cast<mkldnn_format_tag_t>(aformat);
+ }
+};
+
+inline bool operator==(mkldnn_data_type_t a, memory::data_type b) {
+ return a == memory::convert_to_c(b);
+}
+inline bool operator!=(mkldnn_data_type_t a, memory::data_type b) {
+ return !(a == b);
+}
+inline bool operator==(memory::data_type a, mkldnn_data_type_t b) {
+ return b == a;
+}
+inline bool operator!=(memory::data_type a, mkldnn_data_type_t b) {
+ return !(a == b);
+}
+
+inline bool operator==(mkldnn_format_tag_t a, memory::format_tag b) {
+ return a == memory::convert_to_c(b);
+}
+inline bool operator!=(mkldnn_format_tag_t a, memory::format_tag b) {
+ return !(a == b);
+}
+inline bool operator==(memory::format_tag a, mkldnn_format_tag_t b) {
+ return b == a;
+}
+inline bool operator!=(memory::format_tag a, mkldnn_format_tag_t b) {
+ return !(a == b);
+}
+
+/// @}
+
+/// @addtogroup cpp_api_reorder Reorder
+/// A primitive to copy data between memory formats.
+///
+/// @sa @ref c_api_reorder in @ref c_api
+/// @{
+
+struct reorder : public primitive {
+ struct primitive_desc : public handle<mkldnn_primitive_desc_t> {
+ primitive_desc(const engine &src_engine, const memory::desc &src_md,
+ const engine &dst_engine, const memory::desc &dst_md,
+ const primitive_attr &aattr) {
+ mkldnn_primitive_desc_t result;
+ error::wrap_c_api(mkldnn_reorder_primitive_desc_create(&result,
+ src_engine.get(), &src_md.data,
+ dst_engine.get(), &dst_md.data, aattr.get()),
+ "could not create a reorder primitive descriptor");
+ reset(result);
+ }
+
+ primitive_desc(const engine &src_engine, const memory::desc &src_md,
+ const engine &dst_engine, const memory::desc &dst_md) {
+ mkldnn_primitive_desc_t result;
+ error::wrap_c_api(mkldnn_reorder_primitive_desc_create(&result,
+ src_engine.get(), &src_md.data,
+ dst_engine.get(), &dst_md.data, nullptr),
+ "could not create a reorder primitive descriptor");
+ reset(result);
+ }
+
+ primitive_desc(const memory &src, const memory &dst,
+ const primitive_attr &aattr) {
+ mkldnn_primitive_desc_t result;
+ auto src_md = src.get_desc();
+ auto dst_md = dst.get_desc();
+ error::wrap_c_api(mkldnn_reorder_primitive_desc_create(&result,
+ src.get_engine().get(), &src_md.data,
+ dst.get_engine().get(), &dst_md.data, aattr.get()),
+ "could not create a reorder primitive descriptor");
+ reset(result);
+ }
+
+ primitive_desc(const memory &src, const memory &dst) {
+ mkldnn_primitive_desc_t result;
+ auto src_md = src.get_desc();
+ auto dst_md = dst.get_desc();
+ error::wrap_c_api(mkldnn_reorder_primitive_desc_create(&result,
+ src.get_engine().get(), &src_md.data,
+ dst.get_engine().get(), &dst_md.data, nullptr),
+ "could not create a reorder primitive descriptor");
+ reset(result);
+ }
+
+ memory::desc scratchpad_desc() const {
+ const mkldnn_memory_desc_t *cdesc = mkldnn_primitive_desc_query_md(
+ get(), mkldnn::convert_to_c(scratchpad_md), 0);
+ if (cdesc == nullptr)
+ return memory::desc();
+ return memory::desc(*cdesc);
+ }
+
+ engine scratchpad_engine() {
+ mkldnn_engine_t engine_q;
+ error::wrap_c_api(
+ mkldnn_primitive_desc_query(get(),
+ mkldnn::convert_to_c(query_scratchpad_engine), 0, &engine_q),
+ "could not get scratchpad engine from reorder primitive_desc");
+
+ return engine(engine_q);
+ }
+
+ engine get_engine() { return engine::query(*this); }
+ };
+
+ reorder(const primitive_desc &pd): primitive(pd.get()) {}
+
+ reorder(const memory &src, const memory &dst):
+ primitive(primitive_desc(src, dst).get()) {}
+
+ void execute(stream astream, memory &src, memory &dst) {
+ primitive::execute(astream,
+ {{MKLDNN_ARG_FROM, src}, {MKLDNN_ARG_TO, dst}});
+ }
+};
+
+/// @}
+
+/// @addtogroup cpp_api_concat Concat
+/// A primitive to concatenate data by arbitrary dimension.
+///
+/// @sa @ref c_api_concat in @ref c_api
+/// @{
+
+struct concat : public primitive {
+ struct primitive_desc : public handle<mkldnn_primitive_desc_t> {
+ std::vector<mkldnn_memory_desc_t> cpp_to_c(
+ const std::vector<memory::desc> &srcs) {
+ std::vector<mkldnn_memory_desc_t> c_api_srcs;
+ c_api_srcs.reserve(srcs.size());
+ for (const auto &s : srcs) c_api_srcs.push_back(s.data);
+ return c_api_srcs;
+ }
+
+ primitive_desc(const memory::desc &dst, int concat_dimension,
+ const std::vector<memory::desc> &srcs, const engine &aengine) {
+ auto c_api_srcs = cpp_to_c(srcs);
+
+ mkldnn_primitive_desc_t result;
+ error::wrap_c_api(mkldnn_concat_primitive_desc_create(
+ &result, &dst.data, (int)c_api_srcs.size(),
+ concat_dimension, &c_api_srcs[0], nullptr, aengine.get()),
+ "could not create a concat primitive descriptor");
+ reset(result);
+ }
+
+ primitive_desc(int concat_dimension,
+ const std::vector<memory::desc> &srcs, const engine &aengine) {
+ auto c_api_srcs = cpp_to_c(srcs);
+
+ mkldnn_primitive_desc_t result;
+ error::wrap_c_api(mkldnn_concat_primitive_desc_create(
+ &result, nullptr, (int)c_api_srcs.size(),
+ concat_dimension, &c_api_srcs[0], nullptr, aengine.get()),
+ "could not create a concat primitive descriptor");
+ reset(result);
+ }
+
+ memory::desc dst_desc() const {
+ const mkldnn_memory_desc_t *cdesc = mkldnn_primitive_desc_query_md(
+ get(), mkldnn::convert_to_c(dst_md), 0);
+ error::wrap_c_api(
+ cdesc == nullptr ? mkldnn_runtime_error : mkldnn_success,
+ "could not get a dst memory descriptor");
+ return memory::desc(*cdesc);
+ }
+
+ memory::desc scratchpad_desc() const {
+ const mkldnn_memory_desc_t *cdesc = mkldnn_primitive_desc_query_md(
+ get(), mkldnn::convert_to_c(scratchpad_md), 0);
+ if (cdesc == nullptr)
+ return memory::desc();
+ return memory::desc(*cdesc);
+ }
+
+ engine get_engine() { return engine::query(*this); }
+ };
+
+ concat(const primitive_desc &pd): primitive(pd.get()) {}
+};
+
+/// @}
+
+/// @addtogroup cpp_api_sum Sum
+/// A primitive to sum data.
+///
+/// @sa @ref c_api_sum in @ref c_api
+/// @{
+
+struct sum : public primitive {
+ struct primitive_desc : public handle<mkldnn_primitive_desc_t> {
+ std::vector<mkldnn_memory_desc_t> cpp_to_c(
+ const std::vector<memory::desc> &srcs) {
+ std::vector<mkldnn_memory_desc_t> c_api_srcs;
+ c_api_srcs.reserve(srcs.size());
+ for (const auto &s : srcs) c_api_srcs.push_back(s.data);
+ return c_api_srcs;
+ }
+
+ primitive_desc(const memory::desc &dst,
+ const std::vector<float> &scales,
+ const std::vector<memory::desc> &srcs, const engine &aengine) {
+ error::wrap_c_api(scales.size() == srcs.size()
+ ? mkldnn_success : mkldnn_invalid_arguments,
+ "number of scales not equal to number of srcs");
+
+ auto c_api_srcs = cpp_to_c(srcs);
+
+ mkldnn_primitive_desc_t result;
+ error::wrap_c_api(mkldnn_sum_primitive_desc_create(
+ &result, &dst.data, (int)c_api_srcs.size(),
+ &scales[0], &c_api_srcs[0], nullptr, aengine.get()),
+ "could not create a sum primitive descriptor");
+ reset(result);
+ }
+
+ primitive_desc(const std::vector<float> &scales,
+ const std::vector<memory::desc> &srcs, const engine &aengine) {
+ error::wrap_c_api(scales.size() == srcs.size()
+ ? mkldnn_success : mkldnn_invalid_arguments,
+ "number of scales not equal to number of srcs");
+
+ auto c_api_srcs = cpp_to_c(srcs);
+ mkldnn_primitive_desc_t result;
+ error::wrap_c_api(mkldnn_sum_primitive_desc_create(&result,
+ nullptr, (int)c_api_srcs.size(), &scales[0],
+ &c_api_srcs[0], nullptr, aengine.get()),
+ "could not create a sum primitive descriptor");
+ reset(result);
+ }
+
+ memory::desc dst_desc() const {
+ const mkldnn_memory_desc_t *cdesc = mkldnn_primitive_desc_query_md(
+ get(), mkldnn::convert_to_c(dst_md), 0);
+ error::wrap_c_api(
+ cdesc == nullptr ? mkldnn_runtime_error : mkldnn_success,
+ "could not get a dst memory descriptor");
+ return memory::desc(*cdesc);
+ }
+
+ memory::desc scratchpad_desc() const {
+ const mkldnn_memory_desc_t *cdesc = mkldnn_primitive_desc_query_md(
+ get(), mkldnn::convert_to_c(scratchpad_md), 0);
+ if (cdesc == nullptr)
+ return memory::desc();
+ return memory::desc(*cdesc);
+ }
+
+ engine get_engine() { return engine::query(*this); }
+ };
+
+ sum(const primitive_desc &pd): primitive(pd.get()) {}
+};
+
+/// @}
+
+/// @}
+
+/// @addtogroup cpp_api_primitives Primitives
+/// @{
+
+/// @addtogroup cpp_api_primitive_descriptors Primitive descriptors
+/// @{
+
+/// A base class for all primitive descriptors.
+struct primitive_desc : public handle<mkldnn_primitive_desc_t> {
+ primitive_desc(const_mkldnn_op_desc_t desc, const primitive_attr *attr,
+ const engine &e, const_mkldnn_primitive_desc_t hint_fwd_pd) {
+ mkldnn_primitive_desc_iterator_t iterator = nullptr;
+ mkldnn_status_t status = mkldnn_primitive_desc_iterator_create(
+ &iterator, desc, attr ? attr->get() : nullptr, e.get(),
+ hint_fwd_pd);
+ error::wrap_c_api(status,
+ "could not create a primitive descriptor iterator");
+ pd_iterator.reset(iterator);
+ fetch_impl();
+ }
+
+ engine get_engine() { return engine::query(*this); }
+
+ primitive_attr get_primitive_attr() const {
+ const_mkldnn_primitive_attr_t const_cattr;
+ error::wrap_c_api(mkldnn_primitive_desc_get_attr(get(), &const_cattr),
+ "could not get attributes");
+ mkldnn_primitive_attr_t cattr;
+ error::wrap_c_api(mkldnn_primitive_attr_clone(&cattr, const_cattr),
+ "could not clone attributes");
+
+ primitive_attr attr;
+ attr.reset(cattr);
+ return attr;
+ }
+
+ /// Returns implementation name
+ const char *impl_info_str() const {
+ const char *res;
+ error::wrap_c_api(mkldnn_primitive_desc_query(get(),
+ mkldnn_query_impl_info_str, 0, &res),
+ "could not query implementation info string");
+ return res;
+ }
+
+ /// Queries the memory::dim value (same as int64_t)
+ memory::dim query_s64(query q) const {
+ memory::dim res;
+ mkldnn_status_t status = mkldnn_primitive_desc_query(get(),
+ mkldnn::convert_to_c(q), 0, &res);
+ return status == mkldnn_success ? res : 0;
+ }
+
+ /// Advances the next implementation for the given op descriptor.
+ ///
+ /// Returns:
+ /// - @c true on success
+ /// - @c false if the last implementation reached, and
+ /// the primitive descriptor itself is kept unchanged
+ bool next_impl() {
+ mkldnn_status_t status = mkldnn_primitive_desc_iterator_next(
+ pd_iterator.get());
+ if (status == mkldnn_iterator_ends) return false;
+ error::wrap_c_api(status, "primitive descriptor iterator next failed");
+
+ fetch_impl();
+ return true;
+ }
+
+ /// Queries and returns requested memory descriptor.
+ memory::desc query_md(query what, int idx = 0) const {
+ std::vector<query> valid_q{src_md, diff_src_md, weights_md,
+ diff_weights_md, dst_md, diff_dst_md, workspace_md, scratchpad_md};
+ if (!std::any_of(valid_q.cbegin(), valid_q.cend(),
+ [=](query q) { return what == q; }))
+ throw error(mkldnn_invalid_arguments, "invalid memory query");
+
+ const mkldnn_memory_desc_t *cdesc = mkldnn_primitive_desc_query_md(
+ get(), mkldnn::convert_to_c(what), idx);
+ if (cdesc == nullptr) return memory::desc();
+
+ return memory::desc(*cdesc);
+ }
+
+ // register specialized queries, e.g. src_desc()
+# define REG_QUERY_MD(name, what, idx) \
+ memory::desc name ## _desc() const { return query_md(what ## _md, idx); }
+
+ private:
+ handle<mkldnn_primitive_desc_iterator_t> pd_iterator;
+ void fetch_impl() {
+ mkldnn_primitive_desc_t pd = mkldnn_primitive_desc_iterator_fetch(
+ pd_iterator.get());
+ error::wrap_c_api(pd != nullptr ? mkldnn_success : mkldnn_runtime_error,
+ "could not fetch a primitive descriptor from the iterator");
+ reset(pd);
+ }
+};
+
+/// @}
+
+/// @addtogroup cpp_api_convolution Convolution
+/// A primitive to compute convolution using different algorithms.
+///
+/// @sa @ref c_api_convolution in @ref c_api
+/// @{
+
+struct convolution_forward: public primitive {
+ struct desc {
+ mkldnn_convolution_desc_t data;
+ desc(prop_kind aprop_kind, algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &bias_desc,
+ const memory::desc &dst_desc,
+ const memory::dims strides,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_convolution_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), convert_to_c(aalgorithm),
+ &src_desc.data, &weights_desc.data, &bias_desc.data,
+ &dst_desc.data, &strides[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a convolution forward descriptor");
+ }
+ desc(prop_kind aprop_kind, algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &dst_desc,
+ const memory::dims strides,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_convolution_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), convert_to_c(aalgorithm),
+ &src_desc.data, &weights_desc.data, nullptr,
+ &dst_desc.data, &strides[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a convolution forward descriptor");
+ }
+ desc(prop_kind aprop_kind, algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &bias_desc,
+ const memory::desc &dst_desc,
+ const memory::dims strides,
+ const memory::dims dilates,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(dilates);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(
+ mkldnn_dilated_convolution_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), convert_to_c(aalgorithm),
+ &src_desc.data, &weights_desc.data, &bias_desc.data,
+ &dst_desc.data, &strides[0], &dilates[0],
+ &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a dilated convolution forward descriptor");
+ }
+ desc(prop_kind aprop_kind, algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &dst_desc,
+ const memory::dims strides,
+ const memory::dims dilates,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(dilates);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(
+ mkldnn_dilated_convolution_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), convert_to_c(aalgorithm),
+ &src_desc.data, &weights_desc.data, nullptr,
+ &dst_desc.data, &strides[0], &dilates[0],
+ &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a dilated convolution forward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, nullptr) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, nullptr) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(weights, weights, 0);
+ REG_QUERY_MD(bias, weights, 1);
+ REG_QUERY_MD(dst, dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ convolution_forward(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct convolution_backward_data : public primitive {
+ struct desc {
+ mkldnn_convolution_desc_t data;
+ desc(algorithm aalgorithm,
+ const memory::desc &diff_src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_convolution_backward_data_desc_init(
+ &data, convert_to_c(aalgorithm), &diff_src_desc.data,
+ &weights_desc.data, &diff_dst_desc.data,
+ &strides[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a convolution backward data descriptor");
+ }
+ desc(algorithm aalgorithm,
+ const memory::desc &diff_src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims dilates,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(dilates);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(
+ mkldnn_dilated_convolution_backward_data_desc_init(
+ &data, convert_to_c(aalgorithm), &diff_src_desc.data,
+ &weights_desc.data, &diff_dst_desc.data,
+ &strides[0], &dilates[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a convolution backward data descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const convolution_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const convolution_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(diff_src, diff_src, 0);
+ REG_QUERY_MD(weights, weights, 0);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ convolution_backward_data(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct convolution_backward_weights : public primitive {
+ struct desc {
+ mkldnn_convolution_desc_t data;
+ desc(algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &diff_weights_desc,
+ const memory::desc &diff_bias_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_convolution_backward_weights_desc_init(
+ &data, convert_to_c(aalgorithm), &src_desc.data,
+ &diff_weights_desc.data, &diff_bias_desc.data,
+ &diff_dst_desc.data,
+ &strides[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a convolution backward weights descriptor");
+ }
+ desc(algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &diff_weights_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_convolution_backward_weights_desc_init(
+ &data, convert_to_c(aalgorithm), &src_desc.data,
+ &diff_weights_desc.data, nullptr, &diff_dst_desc.data,
+ &strides[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a convolution backward weights descriptor");
+ }
+ desc(algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &diff_weights_desc,
+ const memory::desc &diff_bias_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims dilates,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(dilates);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_dilated_convolution_backward_weights_desc_init(
+ &data, convert_to_c(aalgorithm), &src_desc.data,
+ &diff_weights_desc.data, &diff_bias_desc.data,
+ &diff_dst_desc.data,
+ &strides[0], &dilates[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a convolution backward weights descriptor");
+ }
+ desc(algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &diff_weights_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims dilates,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(dilates);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_dilated_convolution_backward_weights_desc_init(
+ &data, convert_to_c(aalgorithm), &src_desc.data,
+ &diff_weights_desc.data, nullptr, &diff_dst_desc.data,
+ &strides[0], &dilates[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a convolution backward weights descriptor");
+ }
+
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const convolution_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const convolution_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(diff_weights, diff_weights, 0);
+ REG_QUERY_MD(diff_bias, diff_weights, 1);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ convolution_backward_weights(const primitive_desc &pd): primitive(pd) {}
+};
+
+/// @}
+//
+/// @addtogroup cpp_api_deconvolution Deconvolution
+/// A primitive to compute deconvolution using different algorithms.
+///
+/// @sa @ref c_api_deconvolution in @ref c_api
+/// @{
+
+struct deconvolution_forward: public primitive {
+ struct desc {
+ mkldnn_deconvolution_desc_t data;
+ desc(prop_kind aprop_kind, algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &bias_desc,
+ const memory::desc &dst_desc,
+ const memory::dims strides,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_deconvolution_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), convert_to_c(aalgorithm),
+ &src_desc.data, &weights_desc.data, &bias_desc.data,
+ &dst_desc.data, &strides[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a deconvolution forward descriptor");
+ }
+ desc(prop_kind aprop_kind, algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &dst_desc,
+ const memory::dims strides,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_deconvolution_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), convert_to_c(aalgorithm),
+ &src_desc.data, &weights_desc.data, nullptr,
+ &dst_desc.data, &strides[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a deconvolution forward descriptor");
+ }
+ desc(prop_kind aprop_kind, algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &bias_desc,
+ const memory::desc &dst_desc,
+ const memory::dims strides,
+ const memory::dims dilates,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(dilates);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_dilated_deconvolution_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), convert_to_c(aalgorithm),
+ &src_desc.data, &weights_desc.data, &bias_desc.data,
+ &dst_desc.data, &strides[0], &dilates[0], &padding_l[0],
+ &padding_r[0], mkldnn::convert_to_c(apadding_kind)),
+ "could not create a dilated deconvolution forward descriptor");
+ }
+ desc(prop_kind aprop_kind, algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &dst_desc,
+ const memory::dims strides,
+ const memory::dims dilates,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(dilates);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_dilated_deconvolution_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), convert_to_c(aalgorithm),
+ &src_desc.data, &weights_desc.data, nullptr,
+ &dst_desc.data, &strides[0], &dilates[0], &padding_l[0],
+ &padding_r[0], mkldnn::convert_to_c(apadding_kind)),
+ "could not create a dilated deconvolution forward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, nullptr) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, nullptr) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(weights, weights, 0);
+ REG_QUERY_MD(bias, weights, 1);
+ REG_QUERY_MD(dst, dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ deconvolution_forward(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct deconvolution_backward_data : public primitive {
+ struct desc {
+ mkldnn_deconvolution_desc_t data;
+ desc(algorithm aalgorithm,
+ const memory::desc &diff_src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_deconvolution_backward_data_desc_init(
+ &data, convert_to_c(aalgorithm), &diff_src_desc.data,
+ &weights_desc.data, &diff_dst_desc.data,
+ &strides[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a deconvolution backward data descriptor");
+ }
+ desc(algorithm aalgorithm,
+ const memory::desc &diff_src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims dilates,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(dilates);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_dilated_deconvolution_backward_data_desc_init(
+ &data, convert_to_c(aalgorithm), &diff_src_desc.data,
+ &weights_desc.data, &diff_dst_desc.data,
+ &strides[0], &dilates[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a dilated deconvolution backward data descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const deconvolution_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const deconvolution_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(diff_src, diff_src, 0);
+ REG_QUERY_MD(weights, weights, 0);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ deconvolution_backward_data(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct deconvolution_backward_weights : public primitive {
+ struct desc {
+ mkldnn_deconvolution_desc_t data;
+ desc(algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &diff_weights_desc,
+ const memory::desc &diff_bias_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_deconvolution_backward_weights_desc_init(
+ &data, convert_to_c(aalgorithm), &src_desc.data,
+ &diff_weights_desc.data, &diff_bias_desc.data,
+ &diff_dst_desc.data,
+ &strides[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a deconvolution backward weights descriptor");
+ }
+ desc(algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &diff_weights_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_deconvolution_backward_weights_desc_init(
+ &data, convert_to_c(aalgorithm), &src_desc.data,
+ &diff_weights_desc.data, nullptr, &diff_dst_desc.data,
+ &strides[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a deconvolution backward weights descriptor");
+ }
+ desc(algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &diff_weights_desc,
+ const memory::desc &diff_bias_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims dilates,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(dilates);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_dilated_deconvolution_backward_weights_desc_init(
+ &data, convert_to_c(aalgorithm), &src_desc.data,
+ &diff_weights_desc.data, &diff_bias_desc.data,
+ &diff_dst_desc.data,
+ &strides[0], &dilates[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a dilated deconvolution backward weights descriptor");
+ }
+ desc(algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &diff_weights_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims strides,
+ const memory::dims dilates,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(dilates);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_dilated_deconvolution_backward_weights_desc_init(
+ &data, convert_to_c(aalgorithm), &src_desc.data,
+ &diff_weights_desc.data, nullptr, &diff_dst_desc.data,
+ &strides[0], &dilates[0], &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not create a dilated deconvolution backward weights descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const deconvolution_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const deconvolution_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(diff_weights, diff_weights, 0);
+ REG_QUERY_MD(diff_bias, diff_weights, 1);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ deconvolution_backward_weights(const primitive_desc &pd): primitive(pd) {}
+};
+
+/// @}
+
+/// @addtogroup cpp_api_lrn LRN
+/// A primitive to perform local response normalization (LRN) across or within
+/// channels.
+///
+/// @sa @ref c_api_lrn in @ref c_api
+/// @{
+
+struct lrn_forward : public primitive {
+ struct desc {
+ mkldnn_lrn_desc_t data;
+
+ desc(prop_kind aprop_kind, algorithm aalgorithm,
+ const memory::desc &src_desc, memory::dim local_size,
+ float alpha, float beta, float k = 1.f) {
+ error::wrap_c_api(mkldnn_lrn_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), convert_to_c(aalgorithm),
+ &src_desc.data, local_size, alpha, beta, k),
+ "could not create a lrn forward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, nullptr) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, nullptr) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(dst, dst, 0);
+ REG_QUERY_MD(workspace, workspace, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ lrn_forward(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct lrn_backward : public primitive {
+ struct desc {
+ mkldnn_lrn_desc_t data;
+
+ desc(algorithm aalgorithm, const memory::desc &data_desc,
+ const memory::desc &diff_data_desc, memory::dim local_size,
+ float alpha, float beta, float k = 1.f) {
+ error::wrap_c_api(mkldnn_lrn_backward_desc_init(&data,
+ convert_to_c(aalgorithm), &diff_data_desc.data,
+ &data_desc.data, local_size, alpha, beta, k),
+ "could not create a lrn backward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const lrn_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const lrn_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(diff_src, diff_src, 0);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(workspace, workspace, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ lrn_backward(const primitive_desc &pd): primitive(pd) {}
+};
+
+/// @}
+
+/// @addtogroup cpp_api_pooling Pooling
+/// A primitive to perform max or average pooling.
+///
+/// @sa @ref c_api_pooling in @ref c_api
+/// @{
+
+struct pooling_forward : public primitive {
+ struct desc {
+ mkldnn_pooling_desc_t data;
+ desc(prop_kind aprop_kind, algorithm aalgorithm,
+ const memory::desc &src_desc,
+ const memory::desc &dst_desc,
+ const memory::dims strides,
+ const memory::dims kernel,
+ const memory::dims padding_l,
+ const memory::dims padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(kernel);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_pooling_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind),
+ convert_to_c(aalgorithm),
+ &src_desc.data, &dst_desc.data,
+ &strides[0], &kernel[0],
+ &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not init a forward pooling descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, nullptr) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, nullptr) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(dst, dst, 0);
+ REG_QUERY_MD(workspace, workspace, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ pooling_forward(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct pooling_backward : public primitive {
+ struct desc {
+ mkldnn_pooling_desc_t data;
+ desc(algorithm aalgorithm,
+ const memory::desc &diff_src_desc,
+ const memory::desc &diff_dst_desc,
+ const memory::dims &strides,
+ const memory::dims &kernel,
+ const memory::dims &padding_l,
+ const memory::dims &padding_r,
+ const padding_kind apadding_kind) {
+ memory::validate_dims(strides);
+ memory::validate_dims(kernel);
+ memory::validate_dims(padding_l);
+ memory::validate_dims(padding_r);
+ error::wrap_c_api(mkldnn_pooling_backward_desc_init(&data,
+ convert_to_c(aalgorithm),
+ &diff_src_desc.data, &diff_dst_desc.data,
+ &strides[0], &kernel[0],
+ &padding_l[0], &padding_r[0],
+ mkldnn::convert_to_c(apadding_kind)),
+ "could not init a backward pooling descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const pooling_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const pooling_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(diff_src, diff_src, 0);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(workspace, workspace, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ pooling_backward(const primitive_desc &pd): primitive(pd) {}
+};
+
+/// @}
+
+/// @addtogroup cpp_api_eltwise Eltwise
+/// A primitive to compute element-wise operations like parametric rectifier
+/// linear unit (ReLU).
+///
+/// @sa @ref c_api_eltwise in @ref c_api
+/// @{
+
+struct eltwise_forward : public primitive {
+ struct desc {
+ mkldnn_eltwise_desc_t data;
+ template <typename T>
+ desc(prop_kind aprop_kind, algorithm alg_kind,
+ const memory::desc &src_desc, T alpha = 0, T beta = 0) {
+ error::wrap_c_api(mkldnn_eltwise_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind),
+ mkldnn::convert_to_c(alg_kind), &src_desc.data,
+ static_cast<float>(alpha), static_cast<float>(beta)),
+ "could not create a eltwise forward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, nullptr) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, nullptr) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(dst, dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ eltwise_forward(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct eltwise_backward : public primitive {
+ struct desc {
+ mkldnn_eltwise_desc_t data;
+
+ template <typename T>
+ desc(algorithm alg_kind, const memory::desc &diff_data_desc,
+ const memory::desc &data_desc, T alpha = 0, T beta = 0) {
+ error::wrap_c_api(mkldnn_eltwise_backward_desc_init(&data,
+ mkldnn::convert_to_c(alg_kind), &diff_data_desc.data,
+ &data_desc.data, static_cast<float>(alpha),
+ static_cast<float>(beta)),
+ "could not create a eltwise backward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const eltwise_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const eltwise_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(diff_src, diff_src, 0);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ eltwise_backward(const primitive_desc &pd): primitive(pd) {}
+};
+
+/// @}
+
+/// @addtogroup cpp_api_softmax Softmax
+/// A primitive to perform softmax.
+///
+/// @sa @ref c_api_softmax in @ref c_api
+/// @{
+
+struct softmax_forward : public primitive {
+ struct desc {
+ mkldnn_softmax_desc_t data;
+ desc(prop_kind aprop_kind, const memory::desc &data_desc,
+ int softmax_axis) {
+ error::wrap_c_api(mkldnn_softmax_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), &data_desc.data,
+ softmax_axis),
+ "could not create a softmax forward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, nullptr) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, nullptr) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(dst, dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ softmax_forward(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct softmax_backward : public primitive {
+ struct desc {
+ mkldnn_softmax_desc_t data;
+ desc(const memory::desc &diff_desc, const memory::desc &data_desc,
+ int softmax_axis) {
+ error::wrap_c_api(mkldnn_softmax_backward_desc_init(&data,
+ &diff_desc.data, &data_desc.data, softmax_axis),
+ "could not init a backward softmax descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const softmax_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const softmax_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(dst, dst, 0);
+ REG_QUERY_MD(diff_src, diff_src, 0);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(workspace, workspace, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ softmax_backward(const primitive_desc &pd): primitive(pd) {}
+};
+
+/// @}
+
+/// @addtogroup cpp_api_batch_norm Batch normalization
+/// A primitive to perform batch normalization.
+///
+/// @sa @ref c_api_batch_normalization in @ref c_api
+/// @{
+
+struct batch_normalization_forward : public primitive {
+ struct desc {
+ mkldnn_batch_normalization_desc_t data;
+ template <typename T>
+ desc(prop_kind aprop_kind, const memory::desc &src_desc, T epsilon,
+ unsigned flags) {
+ error::wrap_c_api(
+ mkldnn_batch_normalization_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), &src_desc.data,
+ static_cast<float>(epsilon), flags),
+ "could not create a batch normalization forward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, nullptr) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, nullptr) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(weights, weights, 0);
+ REG_QUERY_MD(dst, dst, 0);
+ REG_QUERY_MD(workspace, workspace, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+
+ memory::desc mean_desc() const { return stat_desc(mean); }
+ memory::desc variance_desc() const { return stat_desc(var); }
+
+ private:
+ enum { mean = 1, var = 2, };
+ memory::desc stat_desc(int kind) const {
+ mkldnn_batch_normalization_desc_t *p;
+ error::wrap_c_api(mkldnn_primitive_desc_query(
+ get(), mkldnn::convert_to_c(batch_normalization_d), 0, &p),
+ "could not get a batch-normalization descriptor");
+ return query_md(p->flags & use_global_stats ? src_md : dst_md, kind);
+ }
+ };
+
+ batch_normalization_forward(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct batch_normalization_backward : public primitive {
+ struct desc {
+ mkldnn_batch_normalization_desc_t data;
+ template <typename T>
+ desc(prop_kind aprop_kind, const memory::desc &diff_data_desc,
+ const memory::desc &data_desc, T epsilon, unsigned flags) {
+ error::wrap_c_api(
+ mkldnn_batch_normalization_backward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind),
+ &diff_data_desc.data, &data_desc.data,
+ static_cast<float>(epsilon), flags),
+ "could not create a batch normalization backward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const batch_normalization_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const batch_normalization_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(mean, src, 1);
+ REG_QUERY_MD(variance, src, 2);
+ REG_QUERY_MD(weights, weights, 0);
+ REG_QUERY_MD(dst, dst, 0);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(workspace, workspace, 0);
+
+ REG_QUERY_MD(diff_src, diff_src, 0);
+ REG_QUERY_MD(diff_weights, diff_weights, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ batch_normalization_backward(const primitive_desc &pd): primitive(pd) {}
+};
+
+/// @}
+
+/// @addtogroup cpp_api_inner_product Inner Product
+/// A primitive to compute an inner product.
+///
+/// @sa @ref c_api_inner_product in @ref c_api
+/// @{
+
+struct inner_product_forward: public primitive {
+ struct desc {
+ mkldnn_inner_product_desc_t data;
+ desc(prop_kind aprop_kind, const memory::desc &src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &bias_desc,
+ const memory::desc &dst_desc) {
+ error::wrap_c_api(
+ mkldnn_inner_product_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), &src_desc.data,
+ &weights_desc.data, &bias_desc.data, &dst_desc.data),
+ "could not create a inner product forward descriptor");
+ }
+
+ desc(prop_kind aprop_kind, const memory::desc &src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &dst_desc) {
+ error::wrap_c_api(
+ mkldnn_inner_product_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), &src_desc.data,
+ &weights_desc.data, nullptr, &dst_desc.data),
+ "could not create a inner product forward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, nullptr) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, nullptr) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(weights, weights, 0);
+ REG_QUERY_MD(bias, weights, 1);
+ REG_QUERY_MD(dst, dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ inner_product_forward(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct inner_product_backward_data: public primitive {
+ struct desc {
+ mkldnn_inner_product_desc_t data;
+ desc(const memory::desc &diff_src_desc,
+ const memory::desc &weights_desc,
+ const memory::desc &diff_dst_desc) {
+ error::wrap_c_api(
+ mkldnn_inner_product_backward_data_desc_init(&data,
+ &diff_src_desc.data, &weights_desc.data,
+ &diff_dst_desc.data),
+ "could not create a inner product backward data descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const inner_product_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const inner_product_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(diff_src, diff_src, 0);
+ REG_QUERY_MD(weights, weights, 0);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ inner_product_backward_data(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct inner_product_backward_weights: public primitive {
+ struct desc {
+ mkldnn_inner_product_desc_t data;
+ desc(const memory::desc &src_desc,
+ const memory::desc &diff_weights_desc,
+ const memory::desc &diff_bias_desc,
+ const memory::desc &diff_dst_desc) {
+ error::wrap_c_api(
+ mkldnn_inner_product_backward_weights_desc_init(
+ &data, &src_desc.data, &diff_weights_desc.data,
+ &diff_bias_desc.data, &diff_dst_desc.data),
+ "could not create a inner product backward weights descriptor");
+ }
+ desc(const memory::desc &src_desc,
+ const memory::desc &diff_weights_desc,
+ const memory::desc &diff_dst_desc) {
+ error::wrap_c_api(
+ mkldnn_inner_product_backward_weights_desc_init(
+ &data, &src_desc.data, &diff_weights_desc.data,
+ nullptr, &diff_dst_desc.data),
+ "could not create a inner product backward weights descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const inner_product_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const inner_product_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(diff_weights, diff_weights, 0);
+ REG_QUERY_MD(diff_bias, diff_weights, 1);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ inner_product_backward_weights(const primitive_desc &pd): primitive(pd) {}
+};
+
+/// @}
+
+/// @addtogroup cpp_api_rnn RNN
+/// A primitive to compute common recurrent layer.
+///
+/// @sa @ref c_api_rnn in @ref c_api
+/// @{
+
+struct rnn_cell {
+ struct desc {
+ mkldnn_rnn_cell_desc_t c_rnn_cell_;
+
+ desc(algorithm kind, algorithm activation_f) {
+ error::wrap_c_api(mkldnn_rnn_cell_desc_init(&c_rnn_cell_,
+ mkldnn::convert_to_c(kind),
+ mkldnn::convert_to_c(activation_f), 0U, 0, 0),
+ "could not init an rnn cell descriptor");
+ }
+ desc(algorithm kind): desc(kind, algorithm::algorithm_undef) {}
+
+ operator const mkldnn_rnn_cell_desc_t*() const { return &c_rnn_cell_; }
+
+ algorithm get_cell_kind() const
+ { return algorithm(c_rnn_cell_.cell_kind); }
+ algorithm get_activation() const
+ { return algorithm(c_rnn_cell_.activation_kind); }
+
+ float get_alpha() const { return c_rnn_cell_.alpha; }
+ void set_alpha(float alpha) {
+ c_rnn_cell_.flags |= mkldnn_rnn_cell_with_relu;
+ c_rnn_cell_.alpha = alpha;
+ }
+
+ float get_clipping() const { return c_rnn_cell_.clipping; }
+ void set_clipping(float clipping) {
+ c_rnn_cell_.flags |= mkldnn_rnn_cell_with_clipping;
+ c_rnn_cell_.clipping = clipping;
+ }
+
+ int get_gates_count() const {
+ return mkldnn_rnn_cell_get_gates_count(&c_rnn_cell_);
+ }
+ int get_state_count() const {
+ return mkldnn_rnn_cell_get_states_count(&c_rnn_cell_);
+ }
+ };
+};
+
+struct rnn_forward : public primitive {
+ struct desc {
+ mkldnn_rnn_desc_t data;
+ desc(prop_kind aprop_kind, rnn_cell::desc cell,
+ const rnn_direction direction,
+ const memory::desc &src_layer_desc,
+ const memory::desc &src_iter_desc,
+ const memory::desc &weights_layer_desc,
+ const memory::desc &weights_iter_desc,
+ const memory::desc &bias_desc,
+ const memory::desc &dst_layer_desc,
+ const memory::desc &dst_iter_desc
+ ) {
+ error::wrap_c_api(mkldnn_rnn_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), cell,
+ mkldnn::convert_to_c(direction),
+ &src_layer_desc.data, &src_iter_desc.data,
+ &weights_layer_desc.data, &weights_iter_desc.data,
+ &bias_desc.data,
+ &dst_layer_desc.data, &dst_iter_desc.data),
+ "could not create an RNN forward descriptor");
+ }
+
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, nullptr) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, nullptr) {}
+
+ REG_QUERY_MD(src_layer, src, 0);
+ REG_QUERY_MD(src_iter, src, 1);
+ REG_QUERY_MD(weights_layer, weights, 0);
+ REG_QUERY_MD(weights_iter, weights, 1);
+ REG_QUERY_MD(bias, weights, 2);
+ REG_QUERY_MD(dst_layer, dst, 0);
+ REG_QUERY_MD(dst_iter, dst, 1);
+ REG_QUERY_MD(workspace, workspace, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ rnn_forward(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct rnn_backward : public primitive {
+ struct desc {
+ mkldnn_rnn_desc_t data;
+ desc(prop_kind aprop_kind, rnn_cell::desc cell,
+ const rnn_direction direction,
+ const memory::desc &src_layer_desc,
+ const memory::desc &src_iter_desc,
+ const memory::desc &weights_layer_desc,
+ const memory::desc &weights_iter_desc,
+ const memory::desc &bias_desc,
+ const memory::desc &dst_layer_desc,
+ const memory::desc &dst_iter_desc,
+ const memory::desc &diff_src_layer_desc,
+ const memory::desc &diff_src_iter_desc,
+ const memory::desc &diff_weights_layer_desc,
+ const memory::desc &diff_weights_iter_desc,
+ const memory::desc &diff_bias_desc,
+ const memory::desc &diff_dst_layer_desc,
+ const memory::desc &diff_dst_iter_desc) {
+ error::wrap_c_api(mkldnn_rnn_backward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), cell,
+ mkldnn::convert_to_c(direction),
+ &src_layer_desc.data, &src_iter_desc.data,
+ &weights_layer_desc.data, &weights_iter_desc.data,
+ &bias_desc.data,
+ &dst_layer_desc.data, &dst_iter_desc.data,
+ &diff_src_layer_desc.data, &diff_src_iter_desc.data,
+ &diff_weights_layer_desc.data,
+ &diff_weights_iter_desc.data, &diff_bias_desc.data,
+ &diff_dst_layer_desc.data, &diff_dst_iter_desc.data),
+ "could not create an RNN backward descriptor");
+ }
+
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const rnn_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ primitive_desc(const desc &desc, const primitive_attr &attr, const engine &e,
+ const rnn_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, &attr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(src_layer, src, 0);
+ REG_QUERY_MD(src_iter, src, 1);
+ REG_QUERY_MD(weights_layer, weights, 0);
+ REG_QUERY_MD(weights_iter, weights, 1);
+ REG_QUERY_MD(bias, weights, 2);
+ REG_QUERY_MD(dst_layer, dst, 0);
+ REG_QUERY_MD(dst_iter, dst, 1);
+ REG_QUERY_MD(workspace, workspace, 0);
+
+ REG_QUERY_MD(diff_src_layer, diff_src, 0);
+ REG_QUERY_MD(diff_src_iter, diff_src, 1);
+ REG_QUERY_MD(diff_weights_layer, diff_weights, 0);
+ REG_QUERY_MD(diff_weights_iter, diff_weights, 1);
+ REG_QUERY_MD(diff_bias, diff_weights, 2);
+ REG_QUERY_MD(diff_dst_layer, diff_dst, 0);
+ REG_QUERY_MD(diff_dst_iter, diff_dst, 1);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ // With last iteration (with and without input src_iter)
+ rnn_backward(const primitive_desc &pd): primitive(pd) {}
+};
+
+/// @}
+
+/// @addtogroup cpp_api_shuffle Shuffle
+/// A primitive to shuffle data along the axis.
+///
+/// @sa @ref c_api_shuffle in @ref c_api
+/// @{
+
+struct shuffle_forward : public primitive {
+ struct desc {
+ mkldnn_shuffle_desc_t data;
+ desc(prop_kind aprop_kind, const memory::desc &data_desc,
+ int axis, int group_size) {
+ error::wrap_c_api(mkldnn_shuffle_forward_desc_init(&data,
+ mkldnn::convert_to_c(aprop_kind), &data_desc.data,
+ axis, group_size),
+ "could not create a shuffle forward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, nullptr) {}
+
+ REG_QUERY_MD(src, src, 0);
+ REG_QUERY_MD(dst, dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ shuffle_forward(const primitive_desc &pd): primitive(pd) {}
+};
+
+struct shuffle_backward : public primitive {
+ struct desc {
+ mkldnn_shuffle_desc_t data;
+ desc(const memory::desc &diff_data_desc, int axis, int group_size) {
+ error::wrap_c_api(mkldnn_shuffle_backward_desc_init(&data,
+ &diff_data_desc.data, axis, group_size),
+ "could not create a shuffle backward descriptor");
+ }
+ };
+
+ struct primitive_desc : public mkldnn::primitive_desc {
+ primitive_desc(const desc &desc, const engine &e,
+ const shuffle_forward::primitive_desc &hint_fwd_pd)
+ : mkldnn::primitive_desc(&desc.data, nullptr, e, hint_fwd_pd.get()) {}
+
+ REG_QUERY_MD(diff_src, diff_src, 0);
+ REG_QUERY_MD(diff_dst, diff_dst, 0);
+ REG_QUERY_MD(scratchpad, scratchpad, 0);
+ };
+
+ shuffle_backward(const primitive_desc &pd): primitive(pd) {}
+};
+
+/// @}
+
+/// @} Primitives
+
+/// @} C++ API
+
+#undef REG_QUERY_MD
+
+// implementation section
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+inline primitive::primitive(const_mkldnn_primitive_desc_t c_pd) {
+ mkldnn_primitive_t result;
+ error::wrap_c_api(mkldnn_primitive_create(&result, c_pd),
+ "could not create a primitive");
+ reset(result);
+}
+
+inline primitive::primitive(const primitive_desc &pd): primitive(pd.get()) {}
+
+inline void primitive::execute(stream &astream,
+ const std::unordered_map<int, memory> &args) const {
+ std::vector<mkldnn_exec_arg_t> c_args;
+ c_args.reserve(args.size());
+ for (const auto &a: args)
+ c_args.push_back({a.first, a.second.get()});
+
+ error::wrap_c_api(mkldnn_primitive_execute(get(), astream.get(),
+ (int)c_args.size(), c_args.data()),
+ "primitive execution fail");
+}
+#endif // DOXYGEN_SHOULD_SKIP_THIS
+
+} // namespace mkldnn
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/include/mkldnn_debug.h b/thirdparty/oidn/mkl-dnn/include/mkldnn_debug.h
new file mode 100644
index 0000000000..f4dc2fdfa6
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/include/mkldnn_debug.h
@@ -0,0 +1,98 @@
+/*******************************************************************************
+* Copyright 2018-2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/* DO NOT EDIT, AUTO-GENERATED */
+
+#ifndef MKLDNN_DEBUG_H
+#define MKLDNN_DEBUG_H
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+/* All symbols shall be internal unless marked as MKLDNN_API */
+#if defined _WIN32 || defined __CYGWIN__
+# define MKLDNN_HELPER_DLL_IMPORT __declspec(dllimport)
+# define MKLDNN_HELPER_DLL_EXPORT __declspec(dllexport)
+#else
+# if __GNUC__ >= 4
+# define MKLDNN_HELPER_DLL_IMPORT __attribute__ ((visibility ("default")))
+# define MKLDNN_HELPER_DLL_EXPORT __attribute__ ((visibility ("default")))
+# else
+# define MKLDNN_HELPER_DLL_IMPORT
+# define MKLDNN_HELPER_DLL_EXPORT
+# endif
+#endif
+
+#ifdef MKLDNN_DLL
+# ifdef MKLDNN_DLL_EXPORTS
+# define MKLDNN_API MKLDNN_HELPER_DLL_EXPORT
+# else
+# define MKLDNN_API MKLDNN_HELPER_DLL_IMPORT
+# endif
+#else
+# define MKLDNN_API
+#endif
+
+#if defined (__GNUC__)
+# define MKLDNN_DEPRECATED __attribute__((deprecated))
+#elif defined(_MSC_VER)
+# define MKLDNN_DEPRECATED __declspec(deprecated)
+#else
+# define MKLDNN_DEPRECATED
+#endif
+
+#include "mkldnn_types.h"
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char MKLDNN_API *mkldnn_status2str(mkldnn_status_t v);
+const char MKLDNN_API *mkldnn_dt2str(mkldnn_data_type_t v);
+const char MKLDNN_API *mkldnn_fmt_kind2str(mkldnn_format_kind_t v);
+const char MKLDNN_API *mkldnn_fmt_tag2str(mkldnn_format_tag_t v);
+const char MKLDNN_API *mkldnn_prop_kind2str(mkldnn_prop_kind_t v);
+const char MKLDNN_API *mkldnn_prim_kind2str(mkldnn_primitive_kind_t v);
+const char MKLDNN_API *mkldnn_alg_kind2str(mkldnn_alg_kind_t v);
+const char MKLDNN_API *mkldnn_rnn_direction2str(mkldnn_rnn_direction_t v);
+
+/** Forms a format string for a given memory descriptor.
+ *
+ * The format is defined as: 'dt:[p|o|0]:fmt_kind:fmt:extra'.
+ * Here:
+ * - dt -- data type
+ * - p -- indicates there is non-trivial padding
+ * - o -- indicates there is non-trivial padding offset
+ * - 0 -- indicates there is non-trivial offset0
+ * - fmt_kind -- format kind (blocked, wino, etc...)
+ * - fmt -- extended format string (format_kind specific)
+ * - extra -- shows extra fields (underspecified)
+ */
+int MKLDNN_API mkldnn_md2fmt_str(char *fmt_str, size_t fmt_str_len,
+ const mkldnn_memory_desc_t *md);
+
+/** Forms a dimension string for a given memory descriptor.
+ *
+ * The format is defined as: 'dim0xdim1x...xdimN
+ */
+int MKLDNN_API mkldnn_md2dim_str(char *dim_str, size_t dim_str_len,
+ const mkldnn_memory_desc_t *md);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/include/mkldnn_types.h b/thirdparty/oidn/mkl-dnn/include/mkldnn_types.h
new file mode 100644
index 0000000000..1b6c356982
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/include/mkldnn_types.h
@@ -0,0 +1,1415 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MKLDNN_TYPES_H
+#define MKLDNN_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+#include <stddef.h>
+#include <stdint.h>
+#endif
+
+/** @addtogroup c_api C API
+ * @{
+ *
+ * @addtogroup c_api_types Types
+ * @{
+ *
+ * @addtogroup c_api_types_generic Generic
+ * @{ */
+
+/** Intel(R) MKL-DNN Version type */
+typedef struct {
+ int major;
+ int minor;
+ int patch;
+ const char *hash;
+} mkldnn_version_t;
+
+/** Status values returned by Intel(R) MKL-DNN functions. */
+typedef enum {
+ /** The operation was successful */
+ mkldnn_success = 0,
+ /** The operation failed due to an out-of-memory condition */
+ mkldnn_out_of_memory = 1,
+ /** The operation failed and should be retried */
+ mkldnn_try_again = 2,
+ /** The operation failed because of incorrect function arguments */
+ mkldnn_invalid_arguments = 3,
+ /** The operation failed because a primitive was not ready for execution */
+ mkldnn_not_ready = 4,
+ /** The operation failed because requested functionality is not implemented
+ */
+ mkldnn_unimplemented = 5,
+ /** Primitive iterator passed over last primitive descriptor */
+ mkldnn_iterator_ends = 6,
+ /** Primitive or engine failed on execution */
+ mkldnn_runtime_error = 7,
+ /** Queried element is not required for given primitive */
+ mkldnn_not_required = 8,
+} mkldnn_status_t;
+
+/** Data type specification */
+typedef enum {
+ /** Undefined data type, used for empty memory descriptors. */
+ mkldnn_data_type_undef = 0,
+ /** 32-bit/single-precision floating point. */
+ mkldnn_f32 = 1,
+ /** 32-bit signed integer. */
+ mkldnn_s32 = 2,
+ /** 8-bit signed integer. */
+ mkldnn_s8 = 3,
+ /** 8-bit unsigned integer. */
+ mkldnn_u8 = 4,
+} mkldnn_data_type_t;
+
+/** Memory format kind */
+typedef enum {
+ /** Undefined memory format, used for empty memory descriptors. */
+ mkldnn_format_kind_undef = 0,
+ /** Unspecified format. The primitive selects a format automatically. */
+ mkldnn_format_kind_any,
+ /** A tensor in a generic format described by the stride and blocking
+ * values in each dimension. See #mkldnn_blocking_desc_t for more
+ * information. */
+ mkldnn_blocked,
+ /** Weights format used in 8bit Winograd convolution */
+ mkldnn_format_kind_wino,
+ /** Packed weights format used in RNN */
+ mkldnn_format_kind_rnn_packed,
+} mkldnn_format_kind_t;
+
+/** Memory format tag specification.
+ *
+ * Intel MKL-DNN formats describe physical data layout. The physical layout
+ * is described as a sequence of the dimensions as they are laid out in the
+ * memory (from the outer-most to the inner-most). Note that this order
+ * doesn't affect the logical order of the dimensions that is kept in the
+ * `dims` field of the mkldnn_memory_desc_t structure. The logical order of the
+ * dimensions is specified by the type of tensor.
+ *
+ * For example, CNN 5D tensor always has its logical dimensions in the order
+ * `(batch, channels, depth, height, width)`, while the physical layout might be
+ * #mkldnn_ncdhw or #mkldnn_ndhwc:
+ *
+ * ~~~cpp
+ * int batch = 2, channels = 16, depth = 13, height = 13, width = 13;
+ *
+ * int ndims = 5; // 5D tensor
+ * mkldnn_dims_t dims = {batch, channels, depth, height, width};
+ * mkldnn_memory_desc_t data_in_ncdhw;
+ * mkldnn_memory_desc_init_by_tag(
+ * &data_in_ncdhw, 5, dims, mkldnn_f32, mkldnn_ncdhw);
+ *
+ * // note that in both cases dims passed are the same
+ * mkldnn_memory_desc_t data_in_ndhwc;
+ * mkldnn_memory_desc_init_by_tag(
+ * &data_in_ndhwc, 5, dims, mkldnn_f32, mkldnn_ndhwc);
+ * ~~~
+ *
+ * The following notation applies to memory format names:
+ * - @c 'n' denotes the mini-batch dimension
+ * - @c 'c' denotes a channels dimension
+ * - When there are multiple channel dimensions (for example, in convolution
+ * weights tensor), @c 'i' and @c 'o' denote dimensions of input and output
+ * channels
+ * - @c 'd', @c 'h', and @c 'w' denote spatial depth, height, and width
+ * respectively
+ * - Upper-case letters indicate that the data is laid out in blocks
+ * for a particular dimension. In such cases, the format name contains both
+ * upper- and lower-case letters for that dimension with a lower-case letter
+ * preceded by the block size. For example: @c 'mkldnn_nChw8c' describes a
+ * format where the outermost dimension is mini-batch, followed by the
+ * channel block number, followed by the spatial height and width, and
+ * finally followed by 8-element channel blocks.
+ *
+ * @note
+ * Channel designations can be different. For example, both the @c
+ * 'mkldnn_nc' and @c 'mkldnn_io' formats can be used to describe a 2D
+ * tensor.
+ *
+ * @sa @ref understanding_memory_formats
+ */
+typedef enum {
+ /** Undefined memory format tag */
+ mkldnn_format_tag_undef = 0,
+ /** Undefined memory format tag.
+ * The primitive selects a format automatically. */
+ mkldnn_format_tag_any,
+
+ /* Semantic agnostic section */
+ /* The physical order of dimensions is defined by the permutation of the
+ * characters, assuming that ab..z defines the natural order.
+ */
+
+ /* Plain formats */
+
+ mkldnn_a,
+ mkldnn_ab,
+ mkldnn_abc,
+ mkldnn_abcd,
+ mkldnn_abcde,
+ mkldnn_abcdef,
+ mkldnn_abdec,
+ mkldnn_acb,
+ mkldnn_acbde,
+ mkldnn_acdb,
+ mkldnn_acdeb,
+ mkldnn_ba,
+ mkldnn_bac,
+ mkldnn_bacd,
+ mkldnn_bcda,
+ mkldnn_cba,
+ mkldnn_cdba,
+ mkldnn_cdeba,
+ mkldnn_decab,
+
+ /* Opaque blocked formats */
+
+ mkldnn_Abc16a,
+ mkldnn_ABc16a16b,
+ mkldnn_aBc16b,
+ mkldnn_ABc16b16a,
+ mkldnn_Abc4a,
+ mkldnn_aBc4b,
+ mkldnn_ABc4b16a4b,
+ mkldnn_ABc4b4a,
+ mkldnn_ABc8a16b2a,
+ mkldnn_ABc8a8b,
+ mkldnn_aBc8b,
+ mkldnn_ABc8b16a2b,
+ mkldnn_ABc8b8a,
+ mkldnn_Abcd16a,
+ mkldnn_ABcd16a16b,
+ mkldnn_aBcd16b,
+ mkldnn_ABcd16b16a,
+ mkldnn_aBCd16b16c,
+ mkldnn_aBCd16c16b,
+ mkldnn_Abcd4a,
+ mkldnn_aBcd4b,
+ mkldnn_ABcd4b16a4b,
+ mkldnn_ABcd4b4a,
+ mkldnn_aBCd4c16b4c,
+ mkldnn_aBCd4c4b,
+ mkldnn_ABcd8a16b2a,
+ mkldnn_ABcd8a8b,
+ mkldnn_aBcd8b,
+ mkldnn_ABcd8b16a2b,
+ mkldnn_aBCd8b16c2b,
+ mkldnn_ABcd8b8a,
+ mkldnn_aBCd8b8c,
+ mkldnn_aBCd8c16b2c,
+ mkldnn_aBCd8c8b,
+ mkldnn_Abcde16a,
+ mkldnn_ABcde16a16b,
+ mkldnn_aBcde16b,
+ mkldnn_ABcde16b16a,
+ mkldnn_aBCde16b16c,
+ mkldnn_aBCde16c16b,
+ mkldnn_aBCde2c8b4c,
+ mkldnn_Abcde4a,
+ mkldnn_aBcde4b,
+ mkldnn_ABcde4b4a,
+ mkldnn_aBCde4b4c,
+ mkldnn_aBCde4c16b4c,
+ mkldnn_aBCde4c4b,
+ mkldnn_Abcde8a,
+ mkldnn_ABcde8a8b,
+ mkldnn_aBcde8b,
+ mkldnn_ABcde8b16a2b,
+ mkldnn_aBCde8b16c2b,
+ mkldnn_ABcde8b8a,
+ mkldnn_aBCde8b8c,
+ mkldnn_aBCde8c16b2c,
+ mkldnn_aBCde8c8b,
+ mkldnn_aBcdef16b,
+ mkldnn_aBCdef16b16c,
+ mkldnn_aBCdef16c16b,
+ mkldnn_aBcdef4b,
+ mkldnn_aBCdef4c4b,
+ mkldnn_aBCdef8b8c,
+ mkldnn_aBCdef8c16b2c,
+ mkldnn_aBCdef8c8b,
+ mkldnn_aBdc16b,
+ mkldnn_aBdc4b,
+ mkldnn_aBdc8b,
+ mkldnn_aBdec16b,
+ mkldnn_aBdec4b,
+ mkldnn_aBdec8b,
+ mkldnn_aBdefc16b,
+ mkldnn_aBdefc4b,
+ mkldnn_aBdefc8b,
+ mkldnn_Acb16a,
+ mkldnn_Acb4a,
+ mkldnn_Acb8a,
+ mkldnn_aCBd16b16c,
+ mkldnn_aCBde16b16c,
+ mkldnn_Acdb16a,
+ mkldnn_Acdb4a,
+ mkldnn_Acdb8a,
+ mkldnn_Acdeb16a,
+ mkldnn_Acdeb4a,
+ mkldnn_Acdeb8a,
+ mkldnn_BAc16a16b,
+ mkldnn_BAcd16a16b,
+
+ /** Just a sentinel, not real memory format tag. Must be changed after new
+ * format tag is added. */
+ mkldnn_format_tag_last,
+
+ /* Aliases */
+
+ mkldnn_x = mkldnn_a,
+ mkldnn_nc = mkldnn_ab,
+ mkldnn_cn = mkldnn_ba,
+ mkldnn_ncw = mkldnn_abc,
+ mkldnn_nwc = mkldnn_acb,
+ mkldnn_nchw = mkldnn_abcd,
+ mkldnn_nhwc = mkldnn_acdb,
+ mkldnn_chwn = mkldnn_bcda,
+ mkldnn_ncdhw = mkldnn_abcde,
+ mkldnn_ndhwc = mkldnn_acdeb,
+
+ mkldnn_oi = mkldnn_ab,
+ mkldnn_io = mkldnn_ba,
+ mkldnn_oiw = mkldnn_abc,
+ mkldnn_wio = mkldnn_cba,
+ mkldnn_oihw = mkldnn_abcd,
+ mkldnn_hwio = mkldnn_cdba,
+ mkldnn_ihwo = mkldnn_bcda,
+ mkldnn_iohw = mkldnn_bacd,
+ mkldnn_oidhw = mkldnn_abcde,
+ mkldnn_dhwio = mkldnn_cdeba,
+ mkldnn_goiw = mkldnn_abcd,
+ mkldnn_goihw = mkldnn_abcde,
+ mkldnn_hwigo = mkldnn_decab,
+ mkldnn_giohw = mkldnn_acbde,
+ mkldnn_goidhw = mkldnn_abcdef,
+
+ /** 3D RNN data tensor in the format (seq_length, batch, input channels). */
+ mkldnn_tnc = mkldnn_abc,
+ /** 3D RNN data tensor in the format (batch, seq_length, input channels). */
+ mkldnn_ntc = mkldnn_bac,
+ /** 5D RNN states tensor in the format (num_layers, num_directions,
+ * num_states, batch, state channels). */
+ mkldnn_ldsnc = mkldnn_abcde,
+ /** 5D RNN weights tensor in the format (num_layers, num_directions,
+ * input_channels, num_gates, output_channels).
+ *
+ * - For LSTM cells, the gates order is input, forget, candidate
+ * and output gate.
+ * - For GRU cells, the gates order is update, reset and output gate. */
+ mkldnn_ldigo = mkldnn_abcde,
+ /** 5D RNN weights tensor in the format (num_layers, num_directions,
+ * num_gates, output_channels, input_channels).
+ *
+ * - For LSTM cells, the gates order is input, forget, candidate
+ * and output gate.
+ * - For GRU cells, the gates order is update, reset and output gate. */
+ mkldnn_ldgoi = mkldnn_abdec,
+ /** 4D RNN bias tensor in the format (num_layers, num_directions,
+ * num_gates, output_channels).
+ *
+ * - For LSTM cells, the gates order is input, forget, candidate
+ * and output gate.
+ * - For GRU cells, the gates order is update, reset and output gate. */
+ mkldnn_ldgo = mkldnn_abcd,
+
+ /* Opaque data types, are not to be used explicitly */
+
+ /* data */
+ mkldnn_nCdhw16c = mkldnn_aBcde16b,
+ mkldnn_nCdhw4c = mkldnn_aBcde4b,
+ mkldnn_nCdhw8c = mkldnn_aBcde8b,
+ mkldnn_nChw16c = mkldnn_aBcd16b,
+ mkldnn_nChw4c = mkldnn_aBcd4b,
+ mkldnn_nChw8c = mkldnn_aBcd8b,
+ mkldnn_nCw16c = mkldnn_aBc16b,
+ mkldnn_nCw4c = mkldnn_aBc4b,
+ mkldnn_nCw8c = mkldnn_aBc8b,
+
+ /* weights, 3D */
+ mkldnn_IOw16o16i = mkldnn_BAc16a16b,
+ mkldnn_OIw16i16o = mkldnn_ABc16b16a,
+ mkldnn_OIw16o16i = mkldnn_ABc16a16b,
+ mkldnn_Oiw16o = mkldnn_Abc16a,
+ mkldnn_OIw4i16o4i = mkldnn_ABc4b16a4b,
+ mkldnn_OIw4i4o = mkldnn_ABc4b4a,
+ mkldnn_Oiw4o = mkldnn_Abc4a,
+ mkldnn_OIw8i16o2i = mkldnn_ABc8b16a2b,
+ mkldnn_OIw8i8o = mkldnn_ABc8b8a,
+ mkldnn_OIw8o16i2o = mkldnn_ABc8a16b2a,
+ mkldnn_OIw8o8i = mkldnn_ABc8a8b,
+ mkldnn_Owi16o = mkldnn_Acb16a,
+ mkldnn_Owi4o = mkldnn_Acb4a,
+ mkldnn_Owi8o = mkldnn_Acb8a,
+
+ /* weights, 4D */
+ mkldnn_IOhw16o16i = mkldnn_BAcd16a16b,
+ mkldnn_Ohwi16o = mkldnn_Acdb16a,
+ mkldnn_Ohwi4o = mkldnn_Acdb4a,
+ mkldnn_Ohwi8o = mkldnn_Acdb8a,
+ mkldnn_OIhw16i16o = mkldnn_ABcd16b16a,
+ mkldnn_OIhw16o16i = mkldnn_ABcd16a16b,
+ mkldnn_Oihw16o = mkldnn_Abcd16a,
+ mkldnn_OIhw4i16o4i = mkldnn_ABcd4b16a4b,
+ mkldnn_OIhw4i4o = mkldnn_ABcd4b4a,
+ mkldnn_Oihw4o = mkldnn_Abcd4a,
+ mkldnn_OIhw8i16o2i = mkldnn_ABcd8b16a2b,
+ mkldnn_OIhw8i8o = mkldnn_ABcd8b8a,
+ mkldnn_OIhw8o16i2o = mkldnn_ABcd8a16b2a,
+ mkldnn_OIhw8o8i = mkldnn_ABcd8a8b,
+
+ /* weights, 5D */
+ mkldnn_Odhwi16o = mkldnn_Acdeb16a,
+ mkldnn_Odhwi4o = mkldnn_Acdeb4a,
+ mkldnn_Odhwi8o = mkldnn_Acdeb8a,
+ mkldnn_OIdhw16i16o = mkldnn_ABcde16b16a,
+ mkldnn_OIdhw16o16i = mkldnn_ABcde16a16b,
+ mkldnn_Oidhw16o = mkldnn_Abcde16a,
+ mkldnn_OIdhw4i4o = mkldnn_ABcde4b4a,
+ mkldnn_Oidhw4o = mkldnn_Abcde4a,
+ mkldnn_OIdhw8i16o2i = mkldnn_ABcde8b16a2b,
+ mkldnn_OIdhw8i8o = mkldnn_ABcde8b8a,
+ mkldnn_OIdhw8o8i = mkldnn_ABcde8a8b,
+
+ /* weights w/ groups, 3D */
+ mkldnn_Goiw16g = mkldnn_Abcd16a,
+ mkldnn_gIOw16o16i = mkldnn_aCBd16b16c,
+ mkldnn_gOIw16i16o = mkldnn_aBCd16c16b,
+ mkldnn_gOIw16o16i = mkldnn_aBCd16b16c,
+ mkldnn_gOiw16o = mkldnn_aBcd16b,
+ mkldnn_gOIw4i16o4i = mkldnn_aBCd4c16b4c,
+ mkldnn_gOIw4i4o = mkldnn_aBCd4c4b,
+ mkldnn_gOiw4o = mkldnn_aBcd4b,
+ mkldnn_gOIw8i16o2i = mkldnn_aBCd8c16b2c,
+ mkldnn_gOIw8i8o = mkldnn_aBCd8c8b,
+ mkldnn_gOIw8o16i2o = mkldnn_aBCd8b16c2b,
+ mkldnn_gOIw8o8i = mkldnn_aBCd8b8c,
+ mkldnn_gOwi16o = mkldnn_aBdc16b,
+ mkldnn_gOwi4o = mkldnn_aBdc4b,
+ mkldnn_gOwi8o = mkldnn_aBdc8b,
+
+ /* weights w/ groups, 4D */
+ mkldnn_gIOhw16o16i = mkldnn_aCBde16b16c,
+ mkldnn_gOhwi16o = mkldnn_aBdec16b,
+ mkldnn_gOhwi4o = mkldnn_aBdec4b,
+ mkldnn_gOhwi8o = mkldnn_aBdec8b,
+ mkldnn_Goihw16g = mkldnn_Abcde16a,
+ mkldnn_gOIhw16i16o = mkldnn_aBCde16c16b,
+ mkldnn_gOIhw16o16i = mkldnn_aBCde16b16c,
+ mkldnn_gOihw16o = mkldnn_aBcde16b,
+ mkldnn_gOIhw2i8o4i = mkldnn_aBCde2c8b4c,
+ mkldnn_gOIhw4i16o4i = mkldnn_aBCde4c16b4c,
+ mkldnn_gOIhw4i4o = mkldnn_aBCde4c4b,
+ mkldnn_gOIhw4o4i = mkldnn_aBCde4b4c,
+ mkldnn_gOihw4o = mkldnn_aBcde4b,
+ mkldnn_Goihw8g = mkldnn_Abcde8a,
+ mkldnn_gOIhw8i16o2i = mkldnn_aBCde8c16b2c,
+ mkldnn_gOIhw8i8o = mkldnn_aBCde8c8b,
+ mkldnn_gOIhw8o16i2o = mkldnn_aBCde8b16c2b,
+ mkldnn_gOIhw8o8i = mkldnn_aBCde8b8c,
+
+ /* weights w/ groups, 6D */
+ mkldnn_gOdhwi16o = mkldnn_aBdefc16b,
+ mkldnn_gOdhwi4o = mkldnn_aBdefc4b,
+ mkldnn_gOdhwi8o = mkldnn_aBdefc8b,
+ mkldnn_gOIdhw16i16o = mkldnn_aBCdef16c16b,
+ mkldnn_gOIdhw16o16i = mkldnn_aBCdef16b16c,
+ mkldnn_gOidhw16o = mkldnn_aBcdef16b,
+ mkldnn_gOIdhw4i4o = mkldnn_aBCdef4c4b,
+ mkldnn_gOidhw4o = mkldnn_aBcdef4b,
+ mkldnn_gOIdhw8i16o2i = mkldnn_aBCdef8c16b2c,
+ mkldnn_gOIdhw8i8o = mkldnn_aBCdef8c8b,
+ mkldnn_gOIdhw8o8i = mkldnn_aBCdef8b8c,
+} mkldnn_format_tag_t;
+
+/** Kinds of padding. Define how to interpret the data in padding regions. */
+typedef enum {
+ /** The data in padding regions is zero. */
+ mkldnn_padding_zero,
+} mkldnn_padding_kind_t;
+
+/** Kinds of propagation. */
+typedef enum {
+ /* TODO: suggest renames */
+ /** Undefined propagation type. */
+ mkldnn_prop_kind_undef = 0,
+ /** Forward data propagation (training mode). In this mode primitives
+ * perform computations necessary for subsequent backward propagation. */
+ mkldnn_forward_training = 64,
+ /** Forward data propagation (inference mode). In this mode primitives
+ * perform only computations that are necessary for inference and omit
+ * computations that are necessary only for backward propagation. */
+ mkldnn_forward_inference = 96,
+ /** Forward data propagation (alias for @c mkldnn_forward_inference) */
+ mkldnn_forward_scoring = mkldnn_forward_inference,
+ /** Forward data propagation (alias for @c mkldnn_forward_training) */
+ mkldnn_forward = mkldnn_forward_training,
+ /** Backward propagation (with respect to all parameters */
+ mkldnn_backward = 128,
+ /** Backward data propagation */
+ mkldnn_backward_data = 160,
+ /** Backward weights propagation */
+ mkldnn_backward_weights = 192,
+ /** Backward bias propagation */
+ mkldnn_backward_bias = 193,
+} mkldnn_prop_kind_t;
+
+/** Kinds of primitives. Used to implement a way to extend the library with new
+ * primitives without changing the ABI. */
+typedef enum {
+ /** Undefined primitive (XXX: why do we have it?). */
+ mkldnn_undefined_primitive,
+ /** A reorder primitive.*/
+ mkldnn_reorder,
+ /** A shuffle primitive.*/
+ mkldnn_shuffle,
+ /** A (out-of-place) concat primitive. */
+ mkldnn_concat,
+ /** A sum primitive. */
+ mkldnn_sum,
+ /** A convolution primitive. */
+ mkldnn_convolution,
+ /** A deconvolution primitive. */
+ mkldnn_deconvolution,
+ /** An element-wise primitive. */
+ mkldnn_eltwise,
+ /** A Softmax primitive. */
+ mkldnn_softmax,
+ /** A pooling primitive. */
+ mkldnn_pooling,
+ /** An LRN primitive. */
+ mkldnn_lrn,
+ /** An batch normalization primitive. */
+ mkldnn_batch_normalization,
+ /** An inner product primitive. */
+ mkldnn_inner_product,
+ /** A rnn primitive. */
+ mkldnn_rnn,
+} mkldnn_primitive_kind_t;
+
+/** Kinds of algorithms. */
+typedef enum {
+ mkldnn_alg_kind_undef,
+ /** Direct convolution */
+ mkldnn_convolution_direct = 0x1,
+ /** Winograd convolution */
+ mkldnn_convolution_winograd = 0x2,
+ /** Convolution algorithm(either direct or Winograd) is chosen just in time **/
+ mkldnn_convolution_auto = 0x3,
+ /** Direct deconvolution */
+ mkldnn_deconvolution_direct = 0xa,
+ /** Winograd deconvolution */
+ mkldnn_deconvolution_winograd = 0xb,
+ /** Eltwise: ReLU */
+ mkldnn_eltwise_relu = 0x1f,
+ /** Eltwise: hyperbolic tangent non-linearity (tanh) */
+ mkldnn_eltwise_tanh = 0x2f,
+ /** Eltwise: parametric exponential linear unit (elu) */
+ mkldnn_eltwise_elu = 0x3f,
+ /** Eltwise: square */
+ mkldnn_eltwise_square = 0x4f,
+ /** Eltwise: abs */
+ mkldnn_eltwise_abs = 0x5f,
+ /** Eltwise: square root */
+ mkldnn_eltwise_sqrt = 0x6f,
+ /** Eltwise: linear */
+ mkldnn_eltwise_linear = 0x7f,
+ /** Eltwise: bounded_relu */
+ mkldnn_eltwise_bounded_relu = 0x8f,
+ /** Eltwise: soft_relu */
+ mkldnn_eltwise_soft_relu = 0x9f,
+ /** Eltwise: logistic */
+ mkldnn_eltwise_logistic = 0xaf,
+ /** Max pooling */
+ mkldnn_pooling_max = 0x1ff,
+ /** Average pooling include padding */
+ mkldnn_pooling_avg_include_padding = 0x2ff,
+ /** Average pooling exclude padding */
+ mkldnn_pooling_avg_exclude_padding = 0x3ff,
+ mkldnn_pooling_avg = mkldnn_pooling_avg_exclude_padding,
+ /** Local response normalization (LRN) across multiple channels */
+ mkldnn_lrn_across_channels = 0xaff,
+ /** LRN within a single channel */
+ mkldnn_lrn_within_channel = 0xbff,
+ /** RNN cell */
+ mkldnn_vanilla_rnn = 0x1fff,
+ /** LSTM cell */
+ mkldnn_vanilla_lstm = 0x2fff,
+ /** GRU cell */
+ mkldnn_vanilla_gru = 0x3fff,
+ /** GRU cell with linear before reset
+ *
+ * Modification of original GRU cell. Differs from #mkldnn_vanilla_gru
+ * in how the new memory gate is calculated:
+ * \f[ c_t = tanh(W_c*x_t + b_{c_x} + r_t*(U_c*h_{t-1}+b_{c_h})) \f]
+ * Primitive expects 4 biases on input:
+ * \f$[b_{u}, b_{r}, b_{c_x}, b_{c_h}]\f$
+ * */
+ mkldnn_gru_linear_before_reset = 0x4fff,
+} mkldnn_alg_kind_t;
+
+/** Flags for batch-normalization primititve. */
+typedef enum {
+ /** Use global statistics
+ *
+ * If specified
+ * - on forward propagation use mean and variance provided by user (input)
+ * - on backward propagation reduces the amount of computations, since
+ * mean and variance are considered as constants
+ *
+ * If not specified:
+ * - on forward propagation mean and variance are computed and stored in
+ * output
+ * - on backward propagation compute full derivative wrt to data
+ */
+ mkldnn_use_global_stats = 0x1U,
+ /** Use scale and shift parameters
+ *
+ * If specified:
+ * - on forward propagation use scale and shift (aka scale and bias) for
+ * the batch normalization results
+ * - on backward propagation (for prop_kind == #mkldnn_backward) compute
+ * diff wrt to scale and shift (hence one extra output used)
+ *
+ * If no specified:
+ * - on backward propagation prop_kind == #mkldnn_backward_data has the
+ * same behavior as prop_kind == #mkldnn_backward
+ */
+ mkldnn_use_scaleshift = 0x2U,
+ /** Fuse with ReLU
+ *
+ * If specified:
+ * - on inference this option behaves the same as if the primitive were
+ * fused with ReLU via post ops API
+ * - on training primitive requires workspace (required to be able to
+ * perform backward pass)
+ */
+ mkldnn_fuse_bn_relu = 0x4U,
+} mkldnn_batch_normalization_flag_t;
+
+/** @} */
+
+/** @addtogroup c_api_types_memory Memory
+ * @{ */
+
+/** Maximum number of dimensions a tensor can have. Only restricts the amount
+ * of space used for the tensor description. Individual computational
+ * primitives may support only tensors of certain dimensions. */
+#define MKLDNN_MAX_NDIMS 12
+
+/** A type to describe tensor dimension. */
+typedef int64_t mkldnn_dim_t;
+
+/** A type to describe tensor dimensions. */
+typedef mkldnn_dim_t mkldnn_dims_t[MKLDNN_MAX_NDIMS];
+
+/** A type to describe strides within a tensor. */
+typedef mkldnn_dim_t mkldnn_strides_t[MKLDNN_MAX_NDIMS];
+
+/** Generic description of blocked data layout for most memory formats.
+ *
+ * @sa @ref understanding_memory_formats */
+typedef struct {
+ /** The strides between the outermost blocks.
+ * In case of plain (non-blocked) formats the strides between dimensions. */
+ mkldnn_dims_t strides;
+ /* Innermost section
+ * ASSUMPTION: the innermost blocks are always dense */
+ /** The number of innermost blocks, e.g. 3 in case of `OIhw_4i16o4i_` */
+ int inner_nblks;
+ /** The size of the blocks, e.g. `{4, 16, 4}` in case of `OIhw_4i16o4i` */
+ mkldnn_dims_t inner_blks;
+ /** The logical indices of the blocks, e.g. `{1, 0, 1}` in case of
+ * `4i16o4i`, because `i` is the 1st dim and `o` is the 0st dim */
+ mkldnn_dims_t inner_idxs;
+} mkldnn_blocking_desc_t;
+
+typedef enum {
+ /** Undefined memory format, used for empty memory descriptors. */
+ mkldnn_wino_undef = 0,
+ /** Tensors of weights for 2x3 winograd convolutions. */
+ mkldnn_wino_wei_aaOIoi,
+ mkldnn_wino_wei_aaOio,
+ mkldnn_wino_wei_aaOBiOo,
+ /** Tensor of weights for 4x3 convolution. */
+ mkldnn_wino_wei_OBaaIBOIio
+} mkldnn_wino_memory_format_t;
+
+/** Description of tensor of weights for winograd 2x3 convolution. */
+typedef struct {
+ mkldnn_wino_memory_format_t wino_format;
+ int r;
+ int alpha;
+ int ic;
+ int oc;
+ int ic_block;
+ int oc_block;
+ int ic2_block;
+ int oc2_block;
+ float adj_scale;
+ size_t size;
+} mkldnn_wino_desc_t;
+
+typedef enum {
+ mkldnn_packed_format_undef = 0,
+ mkldnn_ldigo_p,
+ mkldnn_ldgoi_p
+} mkldnn_rnn_packed_memory_format_t;
+
+/* Maximum number of parts of RNN weights tensor that require separate
+ * computation. */
+#define MKLDNN_RNN_MAX_N_PARTS 4
+
+/** Description of tensor of packed weights for rnn. */
+typedef struct {
+ mkldnn_rnn_packed_memory_format_t format;
+ int n_parts;
+ int n;
+ int parts[MKLDNN_RNN_MAX_N_PARTS];
+ size_t part_pack_size[MKLDNN_RNN_MAX_N_PARTS];
+ size_t offset_compensation;
+ size_t size;
+} mkldnn_rnn_packed_desc_t;
+
+typedef enum {
+ mkldnn_memory_extra_flag_none = 0x0U,
+ /** Indicates the weights have an additional buffer, that depends on the
+ * @p compensation_mask.
+ *
+ * For instance, in 4D case with the compensation mask equals (1 << 0)
+ * the additional buffer would consist of OC values:
+ * O[oc : 0,OC] =
+ * -128 * SUM(ic : 0,IC; kh : 0,KH; kw : 0,KW){ weights(oc, ic, kh, kw) }
+ */
+ mkldnn_memory_extra_flag_compensation_conv_s8s8 = 0x1U,
+ mkldnn_memory_extra_flag_scale_adjust = 0x2U,
+} mkldnn_memory_extra_flags_t;
+
+/** Description of extra information stored in memory */
+typedef struct {
+ /** The flags contain arbitrary extra information, such as compensation.
+ * @sa mkldnn_memory_extra_flags_t */
+ uint64_t flags;
+ /** Compensation mask */
+ int compensation_mask;
+ /** Scale applied to the data */
+ float scale_adjust;
+ /** For future backwards compatibility */
+ char reserved[64];
+} mkldnn_memory_extra_desc_t;
+
+/** Memory descriptor. The description is based on a number of dimensions,
+ * dimensions themselves, plus information about elements type and memory
+ * format. Additionally, contains format-specific descriptions of the data
+ * layout. */
+typedef struct {
+ /** Number of dimensions */
+ int ndims;
+ /** Dimensions in the following order:
+ * - CNN data tensors: mini-batch, channel, spatial
+ * (<code>{N, C, [[D,] H,] W}</code>)
+ * - CNN weight tensors: group (optional), output channel, input channel,
+ * spatial (<code>{[G,] O, I, [[D,] H,] W}</code>)
+ * - RNN data tensors: time, mini-batch, channels (<code>{T, N, C}</code>)
+ * or layers, directions, states, mini-batch, channels (<code>{L, D, S, N, C}</code>)
+ * - RNN weight tensor: layers, directions, input channel, gates, output channels
+ * (<code>{L, D, I, G, O}</code>).
+ *
+ * @note
+ * The order of dimensions does not depend on the memory format, so
+ * whether the data is laid out in #mkldnn_nchw or #mkldnn_nhwc
+ * the dims for 4D CN data tensor would be <code>{N, C, H, W}</code>.
+ */
+ mkldnn_dims_t dims;
+ /** Data type of the tensor elements. */
+ mkldnn_data_type_t data_type;
+
+ /** Size of the data including padding in each dimension. */
+ mkldnn_dims_t padded_dims;
+ /** Per-dimension offset from the padding to actual data, the top-level
+ * tensor with offsets applied must lie within the padding area. */
+ mkldnn_dims_t padded_offsets;
+
+ /** Offset from memory origin to the current block, non-zero only in
+ * a description of a memory sub-block. */
+ mkldnn_dim_t offset0;
+
+ /** Memory format kind. */
+ mkldnn_format_kind_t format_kind;
+ union {
+ /** Description of the data layout for memory formats that use
+ * blocking. */
+ mkldnn_blocking_desc_t blocking;
+ /** Tensor of weights for integer 8bit winograd convolution. */
+ mkldnn_wino_desc_t wino_desc;
+ /** Tensor of packed weights for RNN. */
+ mkldnn_rnn_packed_desc_t rnn_packed_desc;
+ /* ... other descriptions possible */
+ } format_desc;
+
+ mkldnn_memory_extra_desc_t extra;
+} mkldnn_memory_desc_t;
+
+/** @struct mkldnn_memory
+ * An opaque structure to describe a memory. */
+struct mkldnn_memory;
+
+/** A memory handle. */
+typedef struct mkldnn_memory *mkldnn_memory_t;
+
+/** A constant memory handle. */
+typedef const struct mkldnn_memory *const_mkldnn_memory_t;
+
+#define MKLDNN_NATIVE_HANDLE_NONE (NULL)
+#define MKLDNN_NATIVE_HANDLE_ALLOCATE ((void *)(size_t)-1)
+
+/** @} */
+
+/** @addtogroup c_api_types_op_descs Operation descriptors
+ * @{*/
+
+/** A pointer to any of the operation descriptors. */
+typedef void *mkldnn_op_desc_t;
+/** A pointer to any of the operation descriptors (constant variant). */
+typedef const void *const_mkldnn_op_desc_t;
+
+/** A descriptor of a convolution operation. */
+typedef struct {
+ /** The kind of primitive. Used for self-identifying the primitive
+ * descriptor. Must be #mkldnn_convolution. */
+ mkldnn_primitive_kind_t primitive_kind;
+ /** The kind of propagation. Possible values: #mkldnn_forward_training,
+ * #mkldnn_forward_inference, #mkldnn_backward_data,
+ * #mkldnn_backward_weights, and #mkldnn_backward_bias. */
+ mkldnn_prop_kind_t prop_kind;
+ /** The kind of the convolution algorithm. Possible values:
+ * #mkldnn_convolution_direct. */
+ mkldnn_alg_kind_t alg_kind;
+ /** Source memory descriptor. */
+ mkldnn_memory_desc_t src_desc;
+ /** Source gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_src_desc;
+ /** Weights memory descriptor. */
+ mkldnn_memory_desc_t weights_desc;
+ /** Weights gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_weights_desc;
+ /** Bias memory descriptor. */
+ mkldnn_memory_desc_t bias_desc;
+ /** Bias gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_bias_desc;
+ /** Destination memory descriptor. */
+ mkldnn_memory_desc_t dst_desc;
+ /** Destination gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_dst_desc;
+ /** Convolution strides in each spatial dimension. */
+ mkldnn_dims_t strides;
+ /** Convolution dilates in each spatial dimension. */
+ mkldnn_dims_t dilates;
+ /** Padding in each spatial dimension. padding[0] is a padding in the
+ * beginning (@p padding_l), padding[1] is a padding in the end (@p
+ * padding_r). */
+ mkldnn_dims_t padding[2];
+ /** The kind of padding to use. */
+ mkldnn_padding_kind_t padding_kind;
+ /** The accumulator data type. Initialized automatically. */
+ mkldnn_data_type_t accum_data_type;
+} mkldnn_convolution_desc_t;
+
+/** A descriptor of a deconvolution operation. */
+typedef mkldnn_convolution_desc_t mkldnn_deconvolution_desc_t;
+
+/** A descriptor of a shuffle operation. */
+typedef struct {
+ /** The kind of primitive. Used for self-identifying the primitive
+ * descriptor. Must be #mkldnn_convolution. */
+ mkldnn_primitive_kind_t primitive_kind;
+ /** The kind of propagation. Possible values: #mkldnn_forward_training,
+ * #mkldnn_forward_inference, and #mkldnn_backward_data. */
+ mkldnn_prop_kind_t prop_kind;
+ /** Source and destination memory descriptor,
+ * and source and destination gradient memory descriptor. */
+ mkldnn_memory_desc_t data_desc;
+ /** axis for shuffling. */
+ int axis;
+ /** number of groups in group convolution */
+ mkldnn_dim_t group_size;
+} mkldnn_shuffle_desc_t;
+
+/** A descriptor of a element-wise operation. */
+typedef struct {
+ /** The kind of primitive. Used for self-identifying the primitive
+ * descriptor. Must be #mkldnn_eltwise. */
+ mkldnn_primitive_kind_t primitive_kind;
+ /** The kind of propagation. Possible values: #mkldnn_forward_training,
+ * #mkldnn_forward_inference, #mkldnn_backward, and #mkldnn_backward_data.
+ */
+ mkldnn_prop_kind_t prop_kind;
+ /** The kind of eltwise algorithm. Possible values: #mkldnn_eltwise_relu,
+ * #mkldnn_eltwise_tanh, #mkldnn_eltwise_elu, #mkldnn_eltwise_square,
+ * #mkldnn_eltwise_abs, #mkldnn_eltwise_sqrt, #mkldnn_eltwise_linear,
+ * #mkldnn_eltwise_bounded_relu, #mkldnn_eltwise_soft_relu, and
+ * #mkldnn_eltwise_logistic. */
+ mkldnn_alg_kind_t alg_kind;
+ /** Source and destination memory descriptor. */
+ mkldnn_memory_desc_t data_desc;
+ /** Source and destination gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_data_desc;
+ /** Algorithm specific parameter.
+ * Accordance table:
+ * - #mkldnn_eltwise_relu: @p alpha -- negative slope, @p beta ignored
+ * - #mkldnn_eltwise_tanh: @p alpha and @p beta ignored
+ * - #mkldnn_eltwise_elu: @p alpha -- negative slope, @p beta ignored
+ * - #mkldnn_eltwise_square: @p alpha and @p beta ignored
+ * - #mkldnn_eltwise_abs: @p alpha and @p beta ignored
+ * - #mkldnn_eltwise_sqrt: @p alpha and @p beta ignored
+ * - #mkldnn_eltwise_linear: @p alpha -- scale, @p beta -- shift
+ * - #mkldnn_eltwise_bounded_relu: @p alpha -- upper bound, @p beta ignored
+ * - #mkldnn_eltwise_soft_relu: @p alpha and @p beta ignored
+ * - #mkldnn_eltwise_logistic: @p alpha and @p beta ignored
+ */
+ float alpha, beta;
+} mkldnn_eltwise_desc_t;
+
+/** A descriptor of a Softmax operation. */
+typedef struct {
+ /** The kind of primitive. Used for self-identifying the primitive
+ * descriptor. Must be #mkldnn_softmax. */
+ mkldnn_primitive_kind_t primitive_kind;
+ /** The kind of propagation. Possible values: #mkldnn_forward_training and
+ * #mkldnn_forward_inference. */
+ mkldnn_prop_kind_t prop_kind;
+ /** Source and destination memory descriptor. */
+ mkldnn_memory_desc_t data_desc;
+ /** Source and Destination of gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_desc;
+ /** The axis along which to perform the softmax. */
+ int softmax_axis;
+} mkldnn_softmax_desc_t;
+
+/** A descriptor of a pooling operation. */
+typedef struct {
+ /** The kind of primitive. Used for self-identifying the primitive
+ * descriptor. Must be #mkldnn_pooling. */
+ mkldnn_primitive_kind_t primitive_kind;
+ /** The kind of propagation. Possible values: #mkldnn_forward_training,
+ * #mkldnn_forward_inference, #mkldnn_backward, and #mkldnn_backward_data.
+ */
+ mkldnn_prop_kind_t prop_kind;
+ /** The kind of pooling algorithm. Possible values: #mkldnn_pooling_max and
+ * #mkldnn_pooling_avg. */
+ mkldnn_alg_kind_t alg_kind;
+ /** Source memory descriptor. */
+ mkldnn_memory_desc_t src_desc;
+ /** Source gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_src_desc;
+ /** Destination memory descriptor. */
+ mkldnn_memory_desc_t dst_desc;
+ /** Destination gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_dst_desc;
+ /** Pooling kernel strides for spatial dimensions. */
+ mkldnn_dims_t strides;
+ /** Pooling kernel spatial dimensions. */
+ mkldnn_dims_t kernel;
+ /** Padding in each spatial dimension. padding[0] is a padding in the
+ * beginning (@p padding_l), padding[1] is a padding in the end (@p
+ * padding_r). */
+ mkldnn_dims_t padding[2];
+ /** The kind of padding to use. */
+ mkldnn_padding_kind_t padding_kind;
+ /** The accumulator data type. Initialized automatically. */
+ mkldnn_data_type_t accum_data_type;
+} mkldnn_pooling_desc_t;
+
+/** A descriptor of a Local Response Normalization (LRN) operation. */
+typedef struct {
+ /** The kind of primitive. Used for self-identifying the primitive
+ * descriptor. Must be #mkldnn_lrn. */
+ mkldnn_primitive_kind_t primitive_kind;
+ /** The kind of propagation. Possible values: #mkldnn_forward_training,
+ * #mkldnn_forward_inference, #mkldnn_backward, and #mkldnn_backward_data.
+ */
+ mkldnn_prop_kind_t prop_kind;
+ /** LRN algorithm. Possible values: #mkldnn_lrn_within_channel and
+ * #mkldnn_lrn_across_channels. */
+ mkldnn_alg_kind_t alg_kind;
+ /** Source and destination memory descriptor. */
+ mkldnn_memory_desc_t data_desc;
+ /** Source and destination gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_data_desc;
+ /** The number of channels to sum over (for cross-channel LRN) or the side
+ * length of the square region to sum over (for within-channel LRN). */
+ mkldnn_dim_t local_size;
+ /** LRN alpha parameter. */
+ float lrn_alpha;
+ /** LRN beta parameter. */
+ float lrn_beta;
+ /** LRN k parameter. */
+ float lrn_k;
+} mkldnn_lrn_desc_t;
+
+/** A descriptor of a Batch Normalization operation. */
+typedef struct {
+ /** The kind of primitive. Used for self-identifying the primitive
+ * descriptor. Must be #mkldnn_batch_normalization. */
+ mkldnn_primitive_kind_t primitive_kind;
+ /** The kind of propagation. Possible values: #mkldnn_forward_training,
+ * #mkldnn_forward_inference, #mkldnn_backward, and #mkldnn_backward_data.
+ */
+ mkldnn_prop_kind_t prop_kind;
+ /** Source and destination memory descriptor. */
+ mkldnn_memory_desc_t data_desc;
+ /** Source and destination gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_data_desc;
+ /** Scale and shift data and gradient memory descriptors.
+ *
+ * Scaleshift memory descriptor uses 2D #mkldnn_nc format[2,Channels]. 1-st
+ * dimension contains gamma parameter, 2-nd dimension contains beta
+ * parameter. */
+ mkldnn_memory_desc_t data_scaleshift_desc;
+ mkldnn_memory_desc_t diff_data_scaleshift_desc;
+ /** Mean and variance data memory descriptors.
+ *
+ * Mean and variance memory descriptors use 1D #mkldnn_x format[Channels].
+ */
+ mkldnn_memory_desc_t mean_desc;
+ mkldnn_memory_desc_t variance_desc;
+ /** Batch normalization epsilon parameter. */
+ float batch_norm_epsilon;
+ unsigned flags;
+} mkldnn_batch_normalization_desc_t;
+
+/** A descriptor of an inner product operation. */
+typedef struct {
+ /** The kind of primitive. Used for self-identifying the primitive
+ * descriptor. Must be #mkldnn_inner_product. */
+ mkldnn_primitive_kind_t primitive_kind;
+ /** The kind of propagation. Possible values: #mkldnn_forward_training,
+ * #mkldnn_forward_inference, #mkldnn_backward_data,
+ * #mkldnn_backward_weights, and #mkldnn_backward_bias. */
+ mkldnn_prop_kind_t prop_kind;
+ /** Source memory descriptor. */
+ mkldnn_memory_desc_t src_desc;
+ /** Source gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_src_desc;
+ /** Weights memory descriptor. */
+ mkldnn_memory_desc_t weights_desc;
+ /** Weights gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_weights_desc;
+ /** Bias memory descriptor. */
+ mkldnn_memory_desc_t bias_desc;
+ /** Bias gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_bias_desc;
+ /** Destination memory descriptor. */
+ mkldnn_memory_desc_t dst_desc;
+ /** Destination gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_dst_desc;
+ /** The accumulator data type. Initialized automatically. */
+ mkldnn_data_type_t accum_data_type;
+} mkldnn_inner_product_desc_t;
+
+/** Flags for RNN cell. */
+typedef enum {
+ mkldnn_rnn_cell_with_relu = 0x1U,
+ mkldnn_rnn_cell_with_clipping = 0x2U,
+} mkldnn_rnn_cell_flags_t;
+
+typedef struct {
+ /** RNN cell kind. Must be one of #mkldnn_vanilla_rnn,
+ * #mkldnn_vanilla_lstm, #mkldnn_vanilla_gru,
+ * or #mkldnn_gru_linear_before_reset. */
+ mkldnn_alg_kind_t cell_kind;
+ /** Activation function used. Must be either #mkldnn_eltwise_relu or
+ * #mkldnn_eltwise_tanh. */
+ mkldnn_alg_kind_t activation_kind;
+ /** RNN cell flags */
+ unsigned int flags;
+ /** @c alpha is a negative slope parameter (used only if
+ * `(flags & #mkldnn_rnn_cell_with_relu) != 0`) */
+ float alpha;
+ /** clipping parameter (used only if
+ * `(flags & #mkldnn_rnn_cell_with_clipping) != 0`) */
+ float clipping;
+} mkldnn_rnn_cell_desc_t;
+
+/** A direction of RNN primitive execution. */
+typedef enum {
+ /* Unidirectional execution of RNN primitive from left to right. */
+ mkldnn_unidirectional_left2right,
+ /* Unidirectional execution of RNN primitive from right to left. */
+ mkldnn_unidirectional_right2left,
+ /* Bidirectional execution of RNN primitive with concatenation of the
+ * results. */
+ mkldnn_bidirectional_concat,
+ /* Bidirectional execution of RNN primitive with summation of the
+ * results. */
+ mkldnn_bidirectional_sum,
+ mkldnn_unidirectional = mkldnn_unidirectional_left2right,
+} mkldnn_rnn_direction_t;
+
+/** A descriptor for an RNN operation. */
+typedef struct {
+ /** The kind of primitive. Used for self-identifying the primitive
+ * descriptor. Must be #mkldnn_rnn. */
+ mkldnn_primitive_kind_t primitive_kind;
+ /** The kind of propagation. Possible values: #mkldnn_forward_training,
+ * #mkldnn_forward_inference, and #mkldnn_backward. */
+ mkldnn_prop_kind_t prop_kind;
+ /** The RNN cell desc. */
+ mkldnn_rnn_cell_desc_t cell_desc;
+ /** The direction of RNN primitive execution. */
+ mkldnn_rnn_direction_t direction;
+ /** Source layer memory descriptor. */
+ mkldnn_memory_desc_t src_layer_desc;
+ /** Source iteration memory descriptor. */
+ mkldnn_memory_desc_t src_iter_desc;
+ /** Weights layer memory descriptor. */
+ mkldnn_memory_desc_t weights_layer_desc;
+ /** Weights iteration memory descriptor. */
+ mkldnn_memory_desc_t weights_iter_desc;
+ /** Bias memory descriptor. */
+ mkldnn_memory_desc_t bias_desc;
+ /** Destination layer memory descriptor. */
+ mkldnn_memory_desc_t dst_layer_desc;
+ /** Destination iter memory descriptor. */
+ mkldnn_memory_desc_t dst_iter_desc;
+ /** Source gradient layer memory descriptor. */
+ mkldnn_memory_desc_t diff_src_layer_desc;
+ /** Source gradient iter memory descriptor. */
+ mkldnn_memory_desc_t diff_src_iter_desc;
+ /** Weights gradient layer memory descriptor. */
+ mkldnn_memory_desc_t diff_weights_layer_desc;
+ /** Weights gradient iter memory descriptor. */
+ mkldnn_memory_desc_t diff_weights_iter_desc;
+ /** Bias gradient memory descriptor. */
+ mkldnn_memory_desc_t diff_bias_desc;
+ /** Destination gradient layer memory descriptor. */
+ mkldnn_memory_desc_t diff_dst_layer_desc;
+ /** Destination gradient iteration memory descriptor. */
+ mkldnn_memory_desc_t diff_dst_iter_desc;
+} mkldnn_rnn_desc_t;
+
+/** @} */
+
+/** @addtogroup c_api_engine_types Engine
+ * @{ */
+
+/** @brief Kinds of engines. */
+typedef enum {
+ /** An unspecified engine. */
+ mkldnn_any_engine,
+ /** CPU engine. */
+ mkldnn_cpu,
+} mkldnn_engine_kind_t;
+
+/** @struct mkldnn_engine
+ * @brief An opaque structure to describe an engine. */
+struct mkldnn_engine;
+/** @brief An engine handle. */
+typedef struct mkldnn_engine *mkldnn_engine_t;
+#if 0
+/* FIXME: looks like this never happens */
+/** @brief A constant engine handle. */
+typedef const struct mkldnn_engine *const_mkldnn_engine_t;
+#endif
+
+/** @} */
+
+/** @addtogroup c_api_primitive_desc_iterators Primitive descriptor iterators
+ * @{ */
+
+/** @struct mkldnn_primitive_desc_iterator
+ * @brief An opaque structure to describe a primitive descriptor iterator. */
+struct mkldnn_primitive_desc_iterator;
+
+/** @brief A primitive descriptor iterator handle. */
+typedef struct mkldnn_primitive_desc_iterator
+ *mkldnn_primitive_desc_iterator_t;
+
+/** @brief A constant primitive descriptor iterator handle. */
+typedef const struct mkldnn_primitive_desc_iterator
+ *const_mkldnn_primitive_desc_iterator_t;
+
+/** @} */
+
+/** @addtogroup c_api_primitive_descs Primitive descriptors
+ * @{ */
+
+/** @struct mkldnn_primitive_desc
+ * @brief An opaque structure to describe a primitive descriptor. */
+struct mkldnn_primitive_desc;
+
+/** @brief A primitive descriptor handle. */
+typedef struct mkldnn_primitive_desc *mkldnn_primitive_desc_t;
+
+/** @brief A constant primitive descriptor handle. */
+typedef const struct mkldnn_primitive_desc *const_mkldnn_primitive_desc_t;
+
+/** @} */
+
+/** @addtogroup c_api_primitive_attr Primitive descriptor attributes
+ * @{ */
+
+/** Scratchpad mode */
+typedef enum {
+ /** The library manages scratchpad (default) */
+ mkldnn_scratchpad_mode_library,
+ /** A user shall query and provide the scratchpad memory to primitives */
+ mkldnn_scratchpad_mode_user,
+} mkldnn_scratchpad_mode_t;
+
+/** @struct mkldnn_primitive_attr
+ * @brief An opaque structure for primitive descriptor attributes.
+ *
+ * Attributes may contain:
+ * - output scales (to scale the result prior to storing it to the memory)
+ */
+struct mkldnn_primitive_attr;
+
+/** @brief A primitive descriptor attributes handle that controls primitive
+ * behavior. */
+typedef struct mkldnn_primitive_attr *mkldnn_primitive_attr_t;
+
+/** @brief A constant primitive descriptor attributes handle. */
+typedef const struct mkldnn_primitive_attr *const_mkldnn_primitive_attr_t;
+
+/** @struct mkldnn_post_ops
+ * @brief An opaque structure for a chain of post operations.
+ *
+ * mkldnn_post_ops can be used to perform some (trivial) operations like
+ * accumulation or eltwise after certain primitives like convolution.
+ *
+ * Post operations might be combined together, making a chain of post
+ * operations. For instance one can configure convolution followed by
+ * accumulation followed by eltwise. This might be especially beneficial
+ * for residual learning blocks.
+ *
+ * @warning
+ * Of course not all combinations are supported, so the user should handle
+ * errors accordingly.
+ *
+ * Supported post operations:
+ * - accumulation (base primitive: convolution)
+ * - eltwise (base primitive: convolution)
+ */
+struct mkldnn_post_ops;
+
+/** @brief A post operation chain handle. */
+typedef struct mkldnn_post_ops *mkldnn_post_ops_t;
+
+/** @brief A constant post operation chain handle. */
+typedef const struct mkldnn_post_ops *const_mkldnn_post_ops_t;
+
+/** @} */
+
+/** @addtogroup c_api_types_primitive Primitive
+ * @{ */
+
+/** @struct mkldnn_primitive
+ * An opaque structure to describe a primitive. */
+struct mkldnn_primitive;
+/** A primitive handle. */
+typedef struct mkldnn_primitive *mkldnn_primitive_t;
+/** A constant primitive handle. */
+typedef const struct mkldnn_primitive *const_mkldnn_primitive_t;
+
+/** @addtogroup c_api_types_arguments Argument indices
+ * @{ */
+
+#define MKLDNN_ARG_SRC_0 1
+#define MKLDNN_ARG_SRC MKLDNN_ARG_SRC_0
+#define MKLDNN_ARG_SRC_LAYER MKLDNN_ARG_SRC_0
+#define MKLDNN_ARG_FROM MKLDNN_ARG_SRC_0
+
+#define MKLDNN_ARG_SRC_1 2
+#define MKLDNN_ARG_SRC_ITER MKLDNN_ARG_SRC_1
+
+#define MKLDNN_ARG_DST_0 17
+#define MKLDNN_ARG_DST MKLDNN_ARG_DST_0
+#define MKLDNN_ARG_TO MKLDNN_ARG_DST_0
+#define MKLDNN_ARG_DST_LAYER MKLDNN_ARG_DST_0
+
+#define MKLDNN_ARG_DST_1 18
+#define MKLDNN_ARG_DST_ITER MKLDNN_ARG_DST_1
+
+#define MKLDNN_ARG_WEIGHTS_0 33
+#define MKLDNN_ARG_WEIGHTS MKLDNN_ARG_WEIGHTS_0
+#define MKLDNN_ARG_SCALE_SHIFT MKLDNN_ARG_WEIGHTS_0
+#define MKLDNN_ARG_WEIGHTS_LAYER MKLDNN_ARG_WEIGHTS_0
+
+#define MKLDNN_ARG_WEIGHTS_1 34
+#define MKLDNN_ARG_WEIGHTS_ITER MKLDNN_ARG_WEIGHTS_1
+
+#define MKLDNN_ARG_BIAS 41
+
+#define MKLDNN_ARG_MEAN 49
+#define MKLDNN_ARG_VARIANCE 50
+
+#define MKLDNN_ARG_WORKSPACE 64
+#define MKLDNN_ARG_SCRATCHPAD 80
+
+#define MKLDNN_ARG_DIFF_SRC_0 129
+#define MKLDNN_ARG_DIFF_SRC MKLDNN_ARG_DIFF_SRC_0
+#define MKLDNN_ARG_DIFF_SRC_LAYER MKLDNN_ARG_DIFF_SRC_0
+
+#define MKLDNN_ARG_DIFF_SRC_1 130
+#define MKLDNN_ARG_DIFF_SRC_ITER MKLDNN_ARG_DIFF_SRC_1
+
+#define MKLDNN_ARG_DIFF_DST_0 145
+#define MKLDNN_ARG_DIFF_DST MKLDNN_ARG_DIFF_DST_0
+#define MKLDNN_ARG_DIFF_DST_LAYER MKLDNN_ARG_DIFF_DST_0
+
+#define MKLDNN_ARG_DIFF_DST_1 146
+#define MKLDNN_ARG_DIFF_DST_ITER MKLDNN_ARG_DIFF_DST_1
+
+#define MKLDNN_ARG_DIFF_WEIGHTS_0 161
+#define MKLDNN_ARG_DIFF_WEIGHTS MKLDNN_ARG_DIFF_WEIGHTS_0
+#define MKLDNN_ARG_DIFF_SCALE_SHIFT MKLDNN_ARG_DIFF_WEIGHTS_0
+#define MKLDNN_ARG_DIFF_WEIGHTS_LAYER MKLDNN_ARG_DIFF_WEIGHTS_0
+
+#define MKLDNN_ARG_DIFF_WEIGHTS_1 162
+#define MKLDNN_ARG_DIFF_WEIGHTS_ITER MKLDNN_ARG_DIFF_WEIGHTS_1
+
+#define MKLDNN_ARG_DIFF_BIAS 169
+
+#define MKLDNN_ARG_MULTIPLE_SRC 1024
+#define MKLDNN_ARG_MULTIPLE_DST 2048
+
+/** @} */
+
+/** An auxiliary structure to specify primitive's inputs/outputs at execution
+ *
+ * @warning
+ * With this API it's impossible to preserve constness of memory, so all
+ * memories are passed w/o const qualifier. However only memories with
+ * output semantics might be changed during the execution */
+typedef struct {
+ int arg; /**< An argument index, e.g. MKLDNN_ARG_SRC */
+ mkldnn_memory_t memory; /**< Input/output memory */
+} mkldnn_exec_arg_t;
+
+/** @} */
+
+/** @addtogroup c_api_types_query Queries
+ * @{ */
+
+/** Primitive descriptor query specification
+ *
+ * For generic function mkldnn_primitive_desc_query(), the type of result must
+ * agree with the queried argument. The correspondence table:
+ * Query | type of result
+ * --------------------------------------------------------------
+ * #mkldnn_query_engine | mkldnn_engine_t *
+ * #mkldnn_query_scratchpad_engine | mkldnn_engine_t *
+ * #mkldnn_query_primitive_kind | mkldnn_primitive_kind_t *
+ * *_s32 | int *
+ * *_s64 | mkldnn_dim_t * (same as int64_t *)
+ * *_f64 | double *
+ * *_str | const char **
+ * #mkldnn_query_op_d | const_mkldnn_op_desc_t *
+ * *_md | const mkldnn_memory_desc_t **
+ * *_${op}_d | const mkldnn_${op}_desc_t **
+ * *_pd | const_mkldnn_primitive_desc_t *
+ *
+ * @note
+ * Rule of thumb: all opaque types and structures are returned by
+ * reference. All numbers are returned by value.
+ *
+ * @warning
+ * All returned references point to constant objects and are valid only
+ * during the lifetime of the queried primitive descriptor. Returned objects
+ * must not be destroyed by the user. If you need to keep the object longer
+ * than the lifetime of the queried primitive descriptor, use
+ * mkldnn_primitive_desc_clone() to make a copy. */
+typedef enum {
+ mkldnn_query_undef = 0, /**< no query */
+
+ mkldnn_query_engine, /**< execution engine */
+ mkldnn_query_primitive_kind, /**< primitive kind */
+
+ mkldnn_query_num_of_inputs_s32, /**< number of inputs expected */
+ mkldnn_query_num_of_outputs_s32, /**< number of outputs expected */
+
+ mkldnn_query_time_estimate_f64, /**< runtime estimation (seconds) */
+ mkldnn_query_memory_consumption_s64, /**< memory consumption -- extra
+ (scratch) memory, additional to all
+ inputs and outputs memory (bytes) */
+
+ mkldnn_query_scratchpad_engine, /**< scratchpad engine -- engine to be used
+ for creating scratchpad memory */
+
+ mkldnn_query_impl_info_str, /**< implementation name */
+
+ /* memory and op descriptor section */
+ mkldnn_query_some_d = 64, /**< stub */
+ mkldnn_query_op_d, /**< op descriptor */
+ mkldnn_query_convolution_d, /**< convolution descriptor */
+ mkldnn_query_deconvolution_d, /**< deconvolution descriptor */
+ mkldnn_query_shuffle_d, /**< shuffle descriptor */
+ mkldnn_query_eltwise_d, /**< eltwise descriptor */
+ mkldnn_query_softmax_d, /**< softmax descriptor */
+ mkldnn_query_pooling_d, /**< pooling descriptor */
+ mkldnn_query_lrn_d, /**< lrn descriptor */
+ mkldnn_query_batch_normalization_d, /**< batch normalization descriptor */
+ mkldnn_query_inner_product_d, /**< inner product descriptor */
+ mkldnn_query_rnn_d, /**< rnn descriptor */
+
+ /* memory descriptor section */
+ mkldnn_query_some_md = 128, /**< stub */
+ mkldnn_query_src_md, /**< source memory desc */
+ mkldnn_query_diff_src_md, /**< source gradient memory desc */
+ mkldnn_query_weights_md, /**< weights memory descriptor desc */
+ mkldnn_query_diff_weights_md, /**< weights grad. memory desc */
+ mkldnn_query_dst_md, /**< destination memory desc */
+ mkldnn_query_diff_dst_md, /**< destination grad. memory desc */
+ mkldnn_query_workspace_md, /**< workspace memory desc */
+ mkldnn_query_scratchpad_md, /**< scratchpad memory desc */
+} mkldnn_query_t;
+
+/** @} */
+
+/** @addtogroup c_api_types_stream Execution stream
+ * @{ */
+
+/** @brief Stream flags. */
+typedef enum {
+ /** A default stream configuration. */
+ mkldnn_stream_default_flags = 0x0U,
+} mkldnn_stream_flags_t;
+
+/** @struct mkldnn_stream
+ * An opaque structure to describe an execution stream. */
+struct mkldnn_stream;
+/** An execution stream handle. */
+typedef struct mkldnn_stream *mkldnn_stream_t;
+/** A constant execution stream handle. */
+typedef const struct mkldnn_stream *const_mkldnn_stream_t;
+
+/** @} */
+/** @} */
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/include/mkldnn_version.h b/thirdparty/oidn/mkl-dnn/include/mkldnn_version.h
new file mode 100644
index 0000000000..a2713deccb
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/include/mkldnn_version.h
@@ -0,0 +1,32 @@
+/*******************************************************************************
+* Copyright 2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MKLDNN_VERSION_H
+#define MKLDNN_VERSION_H
+
+/* Major version of MKL-DNN */
+#define MKLDNN_VERSION_MAJOR 0
+
+/* Minor version of MKL-DNN */
+#define MKLDNN_VERSION_MINOR 90
+
+/* Patch version of MKL-DNN */
+#define MKLDNN_VERSION_PATCH 0
+
+/* Git Commit Hash of MKL-DNN */
+#define MKLDNN_VERSION_HASH "096bda1ca23324879f2df5a129e610e4405f775c"
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/include/mkldnn_version.h.in b/thirdparty/oidn/mkl-dnn/include/mkldnn_version.h.in
new file mode 100644
index 0000000000..5ee0126188
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/include/mkldnn_version.h.in
@@ -0,0 +1,32 @@
+/*******************************************************************************
+* Copyright 2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MKLDNN_VERSION_H
+#define MKLDNN_VERSION_H
+
+/* Major version of MKL-DNN */
+#define MKLDNN_VERSION_MAJOR @MKLDNN_VERSION_MAJOR@
+
+/* Minor version of MKL-DNN */
+#define MKLDNN_VERSION_MINOR @MKLDNN_VERSION_MINOR@
+
+/* Patch version of MKL-DNN */
+#define MKLDNN_VERSION_PATCH @MKLDNN_VERSION_PATCH@
+
+/* Git Commit Hash of MKL-DNN */
+#define MKLDNN_VERSION_HASH "@MKLDNN_VERSION_HASH@"
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/batch_normalization.cpp b/thirdparty/oidn/mkl-dnn/src/common/batch_normalization.cpp
new file mode 100644
index 0000000000..1a51d8562b
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/batch_normalization.cpp
@@ -0,0 +1,104 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::alg_kind;
+using namespace mkldnn::impl::types;
+
+namespace {
+status_t bnrm_desc_init(batch_normalization_desc_t *bnrm_desc,
+ prop_kind_t prop_kind, const memory_desc_t *data_desc,
+ const memory_desc_t *diff_data_desc, float epsilon, unsigned flags) {
+ bool args_ok = true
+ && !any_null(bnrm_desc, data_desc)
+ && one_of(prop_kind, forward_training, forward_inference,
+ backward_data, backward)
+ && IMPLICATION(prop_kind & backward, diff_data_desc != nullptr);
+ if (!args_ok) return invalid_arguments;
+
+ auto bd = batch_normalization_desc_t();
+ bd.primitive_kind = primitive_kind::batch_normalization;
+ bd.prop_kind = prop_kind;
+
+ bd.data_desc = *data_desc;
+ bd.diff_data_desc = zero_md();
+ if ( one_of(bd.prop_kind,backward_data, backward) )
+ bd.diff_data_desc = *diff_data_desc;
+
+ dims_t scaleshift_dims = { 2, data_desc->dims[1] };
+ mkldnn_memory_desc_init_by_tag(&bd.data_scaleshift_desc, 2,
+ scaleshift_dims, data_type::f32, mkldnn_nc);
+ bd.diff_data_scaleshift_desc = zero_md();
+ if (bd.prop_kind == backward) {
+ bd.diff_data_scaleshift_desc = bd.data_scaleshift_desc;
+ }
+
+ dims_t stats_dims = { data_desc->dims[1] };
+ mkldnn_memory_desc_init_by_tag(&bd.mean_desc, 1, stats_dims,
+ data_type::f32, mkldnn_x);
+ bd.variance_desc = bd.mean_desc;
+ bd.batch_norm_epsilon = epsilon;
+
+ unsigned bnorm_flags =
+ mkldnn_use_global_stats | mkldnn_use_scaleshift | mkldnn_fuse_bn_relu;
+ if ((~bnorm_flags & flags) != 0) return invalid_arguments;
+
+ bd.flags = flags;
+
+ bool consistency = true
+ && utils::one_of(bd.data_desc.ndims, 2, 4, 5);
+ if (bd.prop_kind == backward_data)
+ consistency = consistency
+ && utils::one_of(bd.diff_data_desc.ndims, 2, 4, 5)
+ && array_cmp(bd.diff_data_desc.dims, bd.data_desc.dims,
+ bd.diff_data_desc.ndims);
+ if (!consistency) return invalid_arguments;
+
+ *bnrm_desc = bd;
+ return success;
+}
+}
+
+status_t mkldnn_batch_normalization_forward_desc_init(
+ batch_normalization_desc_t *bnrm_desc, prop_kind_t prop_kind,
+ const memory_desc_t *data_desc, float epsilon, unsigned flags) {
+ if (!one_of(prop_kind, forward_training, forward_inference))
+ return invalid_arguments;
+ return bnrm_desc_init(bnrm_desc, prop_kind, data_desc, nullptr,
+ epsilon, flags);
+}
+
+status_t mkldnn_batch_normalization_backward_desc_init(
+ batch_normalization_desc_t *bnrm_desc, prop_kind_t prop_kind,
+ const memory_desc_t *diff_data_desc, const memory_desc_t *data_desc,
+ float epsilon, unsigned flags) {
+ if (!one_of(prop_kind, backward, backward_data))
+ return invalid_arguments;
+ return bnrm_desc_init(bnrm_desc, prop_kind, data_desc, diff_data_desc,
+ epsilon, flags);
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/batch_normalization_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/batch_normalization_pd.hpp
new file mode 100644
index 0000000000..f61410b33c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/batch_normalization_pd.hpp
@@ -0,0 +1,240 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef BATCH_NORMALIZATION_PD_HPP
+#define BATCH_NORMALIZATION_PD_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "primitive_desc.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct batch_normalization_fwd_pd_t;
+
+struct batch_normalization_pd_t: public primitive_desc_t {
+ static constexpr auto base_pkind = primitive_kind::batch_normalization;
+
+ batch_normalization_pd_t(engine_t *engine,
+ const batch_normalization_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const batch_normalization_fwd_pd_t *hint_fwd_pd)
+ : primitive_desc_t(engine, attr, base_pkind)
+ , desc_(*adesc)
+ , hint_fwd_pd_(hint_fwd_pd)
+ , data_md_(desc_.data_desc)
+ , stat_md_(desc_.mean_desc)
+ , scaleshift_md_(desc_.data_scaleshift_desc)
+ , ws_md_()
+ {}
+
+ const batch_normalization_desc_t *desc() const { return &desc_; }
+ virtual const op_desc_t *op_desc() const override
+ { return reinterpret_cast<const op_desc_t *>(this->desc()); }
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual status_t query(query_t what, int idx, void *result) const override {
+ switch (what) {
+ case query::batch_normalization_d:
+ *(const batch_normalization_desc_t**)result = desc(); break;
+ default: return primitive_desc_t::query(what, idx, result);
+ }
+ return status::success;
+ }
+
+ /* common batch_normalization aux functions */
+
+ dim_t MB() const { return data_desc().dims[0]; }
+ dim_t C() const { return data_desc().dims[1]; }
+ dim_t D() const { return ndims() >= 5 ? data_desc().dims[ndims() - 3] : 1; }
+ dim_t H() const { return ndims() >= 4 ? data_desc().dims[ndims() - 2] : 1; }
+ dim_t W() const { return ndims() >= 3 ? data_desc().dims[ndims() - 1] : 1; }
+
+ int ndims() const { return desc_.data_desc.ndims; }
+
+ bool stats_is_src() const { return desc_.flags & mkldnn_use_global_stats; }
+ bool use_scaleshift() const { return desc_.flags & mkldnn_use_scaleshift; }
+ bool use_global_stats() const
+ { return desc_.flags & mkldnn_use_global_stats; }
+ bool fuse_bn_relu() const { return desc_.flags & mkldnn_fuse_bn_relu; }
+ bool with_relu_post_op() const {
+ const auto &p = this->attr()->post_ops_;
+ return p.len_ == 1 && p.entry_[0].is_relu(true, true);
+ }
+
+ bool is_fwd() const {
+ return utils::one_of(desc_.prop_kind, prop_kind::forward_training,
+ prop_kind::forward_inference);
+ }
+ bool is_bwd() const { return !this->is_fwd(); }
+ bool is_training() const
+ { return desc_.prop_kind == prop_kind::forward_training; }
+
+ bool has_zero_dim_memory() const
+ { return memory_desc_wrapper(desc_.data_desc).has_zero_dim(); }
+
+protected:
+ batch_normalization_desc_t desc_;
+ const batch_normalization_fwd_pd_t *hint_fwd_pd_;
+
+ memory_desc_t data_md_;
+ memory_desc_t stat_md_;
+ memory_desc_t scaleshift_md_;
+
+ memory_desc_t ws_md_;
+
+ void init_default_ws(size_t bits_per_element) {
+ const auto data_mdw = memory_desc_wrapper(data_md_);
+
+ const dim_t data_nelems = data_mdw.nelems(true);
+ const dim_t bits_per_byte = 8;
+ const dims_t ws_sz = { (dim_t)utils::div_up(
+ data_nelems * bits_per_element, bits_per_byte) };
+ mkldnn_memory_desc_init_by_tag(&ws_md_, 1, ws_sz, impl::data_type::u8,
+ format_tag::x);
+ }
+
+private:
+ const memory_desc_t &data_desc() const { return desc_.data_desc; }
+};
+
+struct batch_normalization_fwd_pd_t: public batch_normalization_pd_t {
+ typedef batch_normalization_fwd_pd_t base_class;
+ typedef batch_normalization_fwd_pd_t hint_class;
+
+ batch_normalization_fwd_pd_t(engine_t *engine,
+ const batch_normalization_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const batch_normalization_fwd_pd_t *hint_fwd_pd)
+ : batch_normalization_pd_t(engine, adesc, attr, hint_fwd_pd)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (arg == MKLDNN_ARG_SRC) return arg_usage_t::input;
+ if (arg == MKLDNN_ARG_DST) return arg_usage_t::output;
+
+ if (utils::one_of(arg, MKLDNN_ARG_MEAN, MKLDNN_ARG_VARIANCE)) {
+ if (stats_is_src()) return arg_usage_t::input;
+ if (!stats_is_src() && is_training()) return arg_usage_t::output;
+ return arg_usage_t::unused;
+ }
+
+ if (arg == MKLDNN_ARG_SCALE_SHIFT && use_scaleshift())
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_WORKSPACE && is_training() && fuse_bn_relu())
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override {
+ if (index == 0) return &data_md_;
+ if (stats_is_src() && (index == 1 || index == 2)) return &stat_md_;
+ return nullptr;
+ }
+
+ virtual const memory_desc_t *dst_md(int index = 0) const override {
+ if (index == 0) return &data_md_;
+ if (!stats_is_src() && is_training() && (index == 1 || index == 2))
+ return &stat_md_;
+ return nullptr;
+ }
+
+ virtual const memory_desc_t *weights_md(int index = 0) const override
+ { return index == 0 ? &scaleshift_md_ : nullptr; }
+
+ virtual const memory_desc_t *workspace_md(int index = 0) const override
+ { return index == 0 && is_training() && fuse_bn_relu() ? &ws_md_ : nullptr; }
+
+ const memory_desc_t *stat_md() const
+ { return stats_is_src() ? src_md(1) : dst_md(1); }
+
+ virtual int n_inputs() const override
+ { return 1 + 2 * stats_is_src() + use_scaleshift(); }
+ virtual int n_outputs() const override
+ { return 1 + (fuse_bn_relu() + 2 * (!stats_is_src())) * is_training(); }
+};
+
+struct batch_normalization_bwd_pd_t: public batch_normalization_pd_t {
+ typedef batch_normalization_bwd_pd_t base_class;
+ typedef batch_normalization_fwd_pd_t hint_class;
+
+ batch_normalization_bwd_pd_t(engine_t *engine,
+ const batch_normalization_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const batch_normalization_fwd_pd_t *hint_fwd_pd)
+ : batch_normalization_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , diff_data_md_(desc_.diff_data_desc)
+ , diff_scaleshift_md_(desc_.diff_data_scaleshift_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_SRC, MKLDNN_ARG_MEAN,
+ MKLDNN_ARG_VARIANCE, MKLDNN_ARG_DIFF_DST))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_SCALE_SHIFT && use_scaleshift())
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_WORKSPACE && fuse_bn_relu())
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_SRC)
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_DIFF_SCALE_SHIFT && use_scaleshift())
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &data_md_ : index <= 2 ? &stat_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 ? &diff_data_md_ : nullptr; }
+ virtual const memory_desc_t *diff_src_md(int index = 0) const override
+ { return index == 0 ? &diff_data_md_ : nullptr; }
+
+ virtual const memory_desc_t *weights_md(int index = 0) const override
+ { return index == 0 ? &scaleshift_md_ : nullptr; }
+ virtual const memory_desc_t *diff_weights_md(int index = 0) const override
+ { return index == 0 ? &diff_scaleshift_md_ : nullptr; }
+
+ virtual const memory_desc_t *workspace_md(int index = 0) const override
+ { return index == 0 && fuse_bn_relu() ? &ws_md_ : nullptr; }
+
+ const memory_desc_t *stat_md() const { return src_md(1); }
+
+ virtual int n_inputs() const override
+ { return 4 + use_scaleshift() + fuse_bn_relu(); }
+ virtual int n_outputs() const override
+ { return 1 + (desc_.prop_kind == prop_kind::backward); }
+
+protected:
+ memory_desc_t diff_data_md_;
+ memory_desc_t diff_scaleshift_md_;
+};
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/c_types_map.hpp b/thirdparty/oidn/mkl-dnn/src/common/c_types_map.hpp
new file mode 100644
index 0000000000..3d43a0fbee
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/c_types_map.hpp
@@ -0,0 +1,550 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef TYPE_MAPPING_HPP
+#define TYPE_MAPPING_HPP
+
+#include "mkldnn_types.h"
+
+namespace mkldnn {
+namespace impl {
+
+// TODO: autogenerate this
+
+using dim_t = mkldnn_dim_t;
+using dims_t = mkldnn_dims_t;
+using stride_t = mkldnn_dim_t;
+using strides_t = mkldnn_strides_t;
+
+using status_t = mkldnn_status_t;
+namespace status {
+ const status_t success = mkldnn_success;
+ const status_t out_of_memory = mkldnn_out_of_memory;
+ const status_t try_again = mkldnn_try_again;
+ const status_t invalid_arguments = mkldnn_invalid_arguments;
+ const status_t not_ready = mkldnn_not_ready;
+ const status_t unimplemented = mkldnn_unimplemented;
+ const status_t iterator_ends = mkldnn_iterator_ends;
+ const status_t runtime_error = mkldnn_runtime_error;
+ const status_t not_required = mkldnn_not_required;
+}
+
+using prop_kind_t = mkldnn_prop_kind_t;
+namespace prop_kind {
+ const prop_kind_t undef = mkldnn_prop_kind_undef;
+ const prop_kind_t forward_training = mkldnn_forward_training;
+ const prop_kind_t forward_inference = mkldnn_forward_inference;
+ const prop_kind_t forward_scoring = mkldnn_forward_scoring;
+ const prop_kind_t forward = mkldnn_forward;
+ const prop_kind_t backward = mkldnn_backward;
+ const prop_kind_t backward_data = mkldnn_backward_data;
+ const prop_kind_t backward_weights = mkldnn_backward_weights;
+ const prop_kind_t backward_bias = mkldnn_backward_bias;
+}
+
+using alg_kind_t = mkldnn_alg_kind_t;
+namespace alg_kind {
+ const alg_kind_t undef = mkldnn_alg_kind_undef;
+ const alg_kind_t convolution_auto = mkldnn_convolution_auto;
+ const alg_kind_t convolution_direct = mkldnn_convolution_direct;
+ const alg_kind_t convolution_winograd = mkldnn_convolution_winograd;
+ const alg_kind_t deconvolution_direct = mkldnn_deconvolution_direct;
+ const alg_kind_t deconvolution_winograd = mkldnn_deconvolution_winograd;
+ const alg_kind_t eltwise_relu = mkldnn_eltwise_relu;
+ const alg_kind_t eltwise_tanh = mkldnn_eltwise_tanh;
+ const alg_kind_t eltwise_elu = mkldnn_eltwise_elu;
+ const alg_kind_t eltwise_square = mkldnn_eltwise_square;
+ const alg_kind_t eltwise_abs = mkldnn_eltwise_abs;
+ const alg_kind_t eltwise_sqrt = mkldnn_eltwise_sqrt;
+ const alg_kind_t eltwise_linear = mkldnn_eltwise_linear;
+ const alg_kind_t eltwise_bounded_relu = mkldnn_eltwise_bounded_relu;
+ const alg_kind_t eltwise_soft_relu = mkldnn_eltwise_soft_relu;
+ const alg_kind_t eltwise_logistic = mkldnn_eltwise_logistic;
+ const alg_kind_t pooling_max = mkldnn_pooling_max;
+ const alg_kind_t pooling_avg = mkldnn_pooling_avg;
+ const alg_kind_t pooling_avg_include_padding = mkldnn_pooling_avg_include_padding;
+ const alg_kind_t pooling_avg_exclude_padding = mkldnn_pooling_avg_exclude_padding;
+ const alg_kind_t lrn_across_channels = mkldnn_lrn_across_channels;
+ const alg_kind_t lrn_within_channel = mkldnn_lrn_within_channel;
+ const alg_kind_t vanilla_rnn = mkldnn_vanilla_rnn;
+ const alg_kind_t vanilla_lstm = mkldnn_vanilla_lstm;
+ const alg_kind_t vanilla_gru = mkldnn_vanilla_gru;
+ const alg_kind_t gru_linear_before_reset = mkldnn_gru_linear_before_reset;
+}
+
+using data_type_t = mkldnn_data_type_t;
+namespace data_type {
+ const data_type_t undef = mkldnn_data_type_undef;
+ const data_type_t f32 = mkldnn_f32;
+ const data_type_t s32 = mkldnn_s32;
+ const data_type_t s8 = mkldnn_s8;
+ const data_type_t u8 = mkldnn_u8;
+}
+
+using scratchpad_mode_t = mkldnn_scratchpad_mode_t;
+namespace scratchpad_mode {
+ const scratchpad_mode_t library = mkldnn_scratchpad_mode_library;
+ const scratchpad_mode_t user = mkldnn_scratchpad_mode_user;
+}
+
+using rnn_packed_format_t = mkldnn_rnn_packed_memory_format_t;
+namespace rnn_packed_format {
+ const rnn_packed_format_t undef = mkldnn_packed_format_undef;
+ const rnn_packed_format_t ldigo_p = mkldnn_ldigo_p;
+ const rnn_packed_format_t ldgoi_p = mkldnn_ldgoi_p;
+}
+
+using format_kind_t = mkldnn_format_kind_t;
+namespace format_kind {
+ const format_kind_t undef = mkldnn_format_kind_undef;
+ const format_kind_t any = mkldnn_format_kind_any;
+ const format_kind_t blocked = mkldnn_blocked;
+ const format_kind_t wino = mkldnn_format_kind_wino;
+ const format_kind_t rnn_packed = mkldnn_format_kind_rnn_packed;
+}
+
+using format_tag_t = mkldnn_format_tag_t;
+namespace format_tag {
+ const format_tag_t undef = mkldnn_format_tag_undef;
+ const format_tag_t any = mkldnn_format_tag_any;
+ const format_tag_t a = mkldnn_a;
+ const format_tag_t ab = mkldnn_ab;
+ const format_tag_t abc = mkldnn_abc;
+ const format_tag_t abcd = mkldnn_abcd;
+ const format_tag_t abcde = mkldnn_abcde;
+ const format_tag_t abcdef = mkldnn_abcdef;
+ const format_tag_t abdec = mkldnn_abdec;
+ const format_tag_t acb = mkldnn_acb;
+ const format_tag_t acbde = mkldnn_acbde;
+ const format_tag_t acdb = mkldnn_acdb;
+ const format_tag_t acdeb = mkldnn_acdeb;
+ const format_tag_t ba = mkldnn_ba;
+ const format_tag_t bac = mkldnn_bac;
+ const format_tag_t bacd = mkldnn_bacd;
+ const format_tag_t bcda = mkldnn_bcda;
+ const format_tag_t cba = mkldnn_cba;
+ const format_tag_t cdba = mkldnn_cdba;
+ const format_tag_t cdeba = mkldnn_cdeba;
+ const format_tag_t decab = mkldnn_decab;
+ const format_tag_t Abc16a = mkldnn_Abc16a;
+ const format_tag_t ABc16a16b = mkldnn_ABc16a16b;
+ const format_tag_t aBc16b = mkldnn_aBc16b;
+ const format_tag_t ABc16b16a = mkldnn_ABc16b16a;
+ const format_tag_t Abc4a = mkldnn_Abc4a;
+ const format_tag_t aBc4b = mkldnn_aBc4b;
+ const format_tag_t ABc4b16a4b = mkldnn_ABc4b16a4b;
+ const format_tag_t ABc4b4a = mkldnn_ABc4b4a;
+ const format_tag_t ABc8a16b2a = mkldnn_ABc8a16b2a;
+ const format_tag_t ABc8a8b = mkldnn_ABc8a8b;
+ const format_tag_t aBc8b = mkldnn_aBc8b;
+ const format_tag_t ABc8b16a2b = mkldnn_ABc8b16a2b;
+ const format_tag_t ABc8b8a = mkldnn_ABc8b8a;
+ const format_tag_t Abcd16a = mkldnn_Abcd16a;
+ const format_tag_t ABcd16a16b = mkldnn_ABcd16a16b;
+ const format_tag_t aBcd16b = mkldnn_aBcd16b;
+ const format_tag_t ABcd16b16a = mkldnn_ABcd16b16a;
+ const format_tag_t aBCd16b16c = mkldnn_aBCd16b16c;
+ const format_tag_t aBCd16c16b = mkldnn_aBCd16c16b;
+ const format_tag_t Abcd4a = mkldnn_Abcd4a;
+ const format_tag_t aBcd4b = mkldnn_aBcd4b;
+ const format_tag_t ABcd4b16a4b = mkldnn_ABcd4b16a4b;
+ const format_tag_t ABcd4b4a = mkldnn_ABcd4b4a;
+ const format_tag_t aBCd4c16b4c = mkldnn_aBCd4c16b4c;
+ const format_tag_t aBCd4c4b = mkldnn_aBCd4c4b;
+ const format_tag_t ABcd8a16b2a = mkldnn_ABcd8a16b2a;
+ const format_tag_t ABcd8a8b = mkldnn_ABcd8a8b;
+ const format_tag_t aBcd8b = mkldnn_aBcd8b;
+ const format_tag_t ABcd8b16a2b = mkldnn_ABcd8b16a2b;
+ const format_tag_t aBCd8b16c2b = mkldnn_aBCd8b16c2b;
+ const format_tag_t ABcd8b8a = mkldnn_ABcd8b8a;
+ const format_tag_t aBCd8b8c = mkldnn_aBCd8b8c;
+ const format_tag_t aBCd8c16b2c = mkldnn_aBCd8c16b2c;
+ const format_tag_t aBCd8c8b = mkldnn_aBCd8c8b;
+ const format_tag_t Abcde16a = mkldnn_Abcde16a;
+ const format_tag_t ABcde16a16b = mkldnn_ABcde16a16b;
+ const format_tag_t aBcde16b = mkldnn_aBcde16b;
+ const format_tag_t ABcde16b16a = mkldnn_ABcde16b16a;
+ const format_tag_t aBCde16b16c = mkldnn_aBCde16b16c;
+ const format_tag_t aBCde16c16b = mkldnn_aBCde16c16b;
+ const format_tag_t aBCde2c8b4c = mkldnn_aBCde2c8b4c;
+ const format_tag_t Abcde4a = mkldnn_Abcde4a;
+ const format_tag_t aBcde4b = mkldnn_aBcde4b;
+ const format_tag_t ABcde4b4a = mkldnn_ABcde4b4a;
+ const format_tag_t aBCde4b4c = mkldnn_aBCde4b4c;
+ const format_tag_t aBCde4c16b4c = mkldnn_aBCde4c16b4c;
+ const format_tag_t aBCde4c4b = mkldnn_aBCde4c4b;
+ const format_tag_t Abcde8a = mkldnn_Abcde8a;
+ const format_tag_t ABcde8a8b = mkldnn_ABcde8a8b;
+ const format_tag_t aBcde8b = mkldnn_aBcde8b;
+ const format_tag_t ABcde8b16a2b = mkldnn_ABcde8b16a2b;
+ const format_tag_t aBCde8b16c2b = mkldnn_aBCde8b16c2b;
+ const format_tag_t ABcde8b8a = mkldnn_ABcde8b8a;
+ const format_tag_t aBCde8b8c = mkldnn_aBCde8b8c;
+ const format_tag_t aBCde8c16b2c = mkldnn_aBCde8c16b2c;
+ const format_tag_t aBCde8c8b = mkldnn_aBCde8c8b;
+ const format_tag_t aBcdef16b = mkldnn_aBcdef16b;
+ const format_tag_t aBCdef16b16c = mkldnn_aBCdef16b16c;
+ const format_tag_t aBCdef16c16b = mkldnn_aBCdef16c16b;
+ const format_tag_t aBcdef4b = mkldnn_aBcdef4b;
+ const format_tag_t aBCdef4c4b = mkldnn_aBCdef4c4b;
+ const format_tag_t aBCdef8b8c = mkldnn_aBCdef8b8c;
+ const format_tag_t aBCdef8c16b2c = mkldnn_aBCdef8c16b2c;
+ const format_tag_t aBCdef8c8b = mkldnn_aBCdef8c8b;
+ const format_tag_t aBdc16b = mkldnn_aBdc16b;
+ const format_tag_t aBdc4b = mkldnn_aBdc4b;
+ const format_tag_t aBdc8b = mkldnn_aBdc8b;
+ const format_tag_t aBdec16b = mkldnn_aBdec16b;
+ const format_tag_t aBdec4b = mkldnn_aBdec4b;
+ const format_tag_t aBdec8b = mkldnn_aBdec8b;
+ const format_tag_t aBdefc16b = mkldnn_aBdefc16b;
+ const format_tag_t aBdefc4b = mkldnn_aBdefc4b;
+ const format_tag_t aBdefc8b = mkldnn_aBdefc8b;
+ const format_tag_t Acb16a = mkldnn_Acb16a;
+ const format_tag_t Acb4a = mkldnn_Acb4a;
+ const format_tag_t Acb8a = mkldnn_Acb8a;
+ const format_tag_t aCBd16b16c = mkldnn_aCBd16b16c;
+ const format_tag_t aCBde16b16c = mkldnn_aCBde16b16c;
+ const format_tag_t Acdb16a = mkldnn_Acdb16a;
+ const format_tag_t Acdb4a = mkldnn_Acdb4a;
+ const format_tag_t Acdb8a = mkldnn_Acdb8a;
+ const format_tag_t Acdeb16a = mkldnn_Acdeb16a;
+ const format_tag_t Acdeb4a = mkldnn_Acdeb4a;
+ const format_tag_t Acdeb8a = mkldnn_Acdeb8a;
+ const format_tag_t BAc16a16b = mkldnn_BAc16a16b;
+ const format_tag_t BAcd16a16b = mkldnn_BAcd16a16b;
+ const format_tag_t last = mkldnn_format_tag_last;
+
+ const format_tag_t x = mkldnn_x;
+ const format_tag_t nc = mkldnn_nc;
+ const format_tag_t cn = mkldnn_cn;
+ const format_tag_t ncw = mkldnn_ncw;
+ const format_tag_t nwc = mkldnn_nwc;
+ const format_tag_t nchw = mkldnn_nchw;
+ const format_tag_t nhwc = mkldnn_nhwc;
+ const format_tag_t chwn = mkldnn_chwn;
+ const format_tag_t ncdhw = mkldnn_ncdhw;
+ const format_tag_t ndhwc = mkldnn_ndhwc;
+ const format_tag_t oi = mkldnn_oi;
+ const format_tag_t io = mkldnn_io;
+ const format_tag_t oiw = mkldnn_oiw;
+ const format_tag_t wio = mkldnn_wio;
+ const format_tag_t oihw = mkldnn_oihw;
+ const format_tag_t hwio = mkldnn_hwio;
+ const format_tag_t ihwo = mkldnn_ihwo;
+ const format_tag_t iohw = mkldnn_iohw;
+ const format_tag_t oidhw = mkldnn_oidhw;
+ const format_tag_t dhwio = mkldnn_dhwio;
+ const format_tag_t goiw = mkldnn_goiw;
+ const format_tag_t goihw = mkldnn_goihw;
+ const format_tag_t hwigo = mkldnn_hwigo;
+ const format_tag_t giohw = mkldnn_giohw;
+ const format_tag_t goidhw = mkldnn_goidhw;
+ const format_tag_t tnc = mkldnn_tnc;
+ const format_tag_t ntc = mkldnn_ntc;
+ const format_tag_t ldsnc = mkldnn_ldsnc;
+ const format_tag_t ldigo = mkldnn_ldigo;
+ const format_tag_t ldgoi = mkldnn_ldgoi;
+ const format_tag_t ldgo = mkldnn_ldgo;
+ const format_tag_t nCdhw16c = mkldnn_nCdhw16c;
+ const format_tag_t nCdhw4c = mkldnn_nCdhw4c;
+ const format_tag_t nCdhw8c = mkldnn_nCdhw8c;
+ const format_tag_t nChw16c = mkldnn_nChw16c;
+ const format_tag_t nChw4c = mkldnn_nChw4c;
+ const format_tag_t nChw8c = mkldnn_nChw8c;
+ const format_tag_t nCw16c = mkldnn_nCw16c;
+ const format_tag_t nCw4c = mkldnn_nCw4c;
+ const format_tag_t nCw8c = mkldnn_nCw8c;
+ const format_tag_t IOw16o16i = mkldnn_IOw16o16i;
+ const format_tag_t OIw16i16o = mkldnn_OIw16i16o;
+ const format_tag_t OIw16o16i = mkldnn_OIw16o16i;
+ const format_tag_t Oiw16o = mkldnn_Oiw16o;
+ const format_tag_t OIw4i16o4i = mkldnn_OIw4i16o4i;
+ const format_tag_t OIw4i4o = mkldnn_OIw4i4o;
+ const format_tag_t Oiw4o = mkldnn_Oiw4o;
+ const format_tag_t OIw8i16o2i = mkldnn_OIw8i16o2i;
+ const format_tag_t OIw8i8o = mkldnn_OIw8i8o;
+ const format_tag_t OIw8o16i2o = mkldnn_OIw8o16i2o;
+ const format_tag_t OIw8o8i = mkldnn_OIw8o8i;
+ const format_tag_t Owi16o = mkldnn_Owi16o;
+ const format_tag_t Owi4o = mkldnn_Owi4o;
+ const format_tag_t Owi8o = mkldnn_Owi8o;
+ const format_tag_t IOhw16o16i = mkldnn_IOhw16o16i;
+ const format_tag_t Ohwi16o = mkldnn_Ohwi16o;
+ const format_tag_t Ohwi4o = mkldnn_Ohwi4o;
+ const format_tag_t Ohwi8o = mkldnn_Ohwi8o;
+ const format_tag_t OIhw16i16o = mkldnn_OIhw16i16o;
+ const format_tag_t OIhw16o16i = mkldnn_OIhw16o16i;
+ const format_tag_t Oihw16o = mkldnn_Oihw16o;
+ const format_tag_t OIhw4i16o4i = mkldnn_OIhw4i16o4i;
+ const format_tag_t OIhw4i4o = mkldnn_OIhw4i4o;
+ const format_tag_t Oihw4o = mkldnn_Oihw4o;
+ const format_tag_t OIhw8i16o2i = mkldnn_OIhw8i16o2i;
+ const format_tag_t OIhw8i8o = mkldnn_OIhw8i8o;
+ const format_tag_t OIhw8o16i2o = mkldnn_OIhw8o16i2o;
+ const format_tag_t OIhw8o8i = mkldnn_OIhw8o8i;
+ const format_tag_t Odhwi16o = mkldnn_Odhwi16o;
+ const format_tag_t Odhwi4o = mkldnn_Odhwi4o;
+ const format_tag_t Odhwi8o = mkldnn_Odhwi8o;
+ const format_tag_t OIdhw16i16o = mkldnn_OIdhw16i16o;
+ const format_tag_t OIdhw16o16i = mkldnn_OIdhw16o16i;
+ const format_tag_t Oidhw16o = mkldnn_Oidhw16o;
+ const format_tag_t OIdhw4i4o = mkldnn_OIdhw4i4o;
+ const format_tag_t Oidhw4o = mkldnn_Oidhw4o;
+ const format_tag_t OIdhw8i16o2i = mkldnn_OIdhw8i16o2i;
+ const format_tag_t OIdhw8i8o = mkldnn_OIdhw8i8o;
+ const format_tag_t OIdhw8o8i = mkldnn_OIdhw8o8i;
+ const format_tag_t gIOw16o16i = mkldnn_gIOw16o16i;
+ const format_tag_t Goiw16g = mkldnn_Goiw16g;
+ const format_tag_t gOIw16i16o = mkldnn_gOIw16i16o;
+ const format_tag_t gOIw16o16i = mkldnn_gOIw16o16i;
+ const format_tag_t gOiw16o = mkldnn_gOiw16o;
+ const format_tag_t gOIw4i16o4i = mkldnn_gOIw4i16o4i;
+ const format_tag_t gOIw4i4o = mkldnn_gOIw4i4o;
+ const format_tag_t gOiw4o = mkldnn_gOiw4o;
+ const format_tag_t gOIw8i16o2i = mkldnn_gOIw8i16o2i;
+ const format_tag_t gOIw8i8o = mkldnn_gOIw8i8o;
+ const format_tag_t gOIw8o16i2o = mkldnn_gOIw8o16i2o;
+ const format_tag_t gOIw8o8i = mkldnn_gOIw8o8i;
+ const format_tag_t gOwi16o = mkldnn_gOwi16o;
+ const format_tag_t gOwi4o = mkldnn_gOwi4o;
+ const format_tag_t gOwi8o = mkldnn_gOwi8o;
+ const format_tag_t gIOhw16o16i = mkldnn_gIOhw16o16i;
+ const format_tag_t gOhwi16o = mkldnn_gOhwi16o;
+ const format_tag_t gOhwi4o = mkldnn_gOhwi4o;
+ const format_tag_t gOhwi8o = mkldnn_gOhwi8o;
+ const format_tag_t Goihw16g = mkldnn_Goihw16g;
+ const format_tag_t gOIhw16i16o = mkldnn_gOIhw16i16o;
+ const format_tag_t gOIhw16o16i = mkldnn_gOIhw16o16i;
+ const format_tag_t gOihw16o = mkldnn_gOihw16o;
+ const format_tag_t gOIhw2i8o4i = mkldnn_gOIhw2i8o4i;
+ const format_tag_t gOIhw4i16o4i = mkldnn_gOIhw4i16o4i;
+ const format_tag_t gOIhw4i4o = mkldnn_gOIhw4i4o;
+ const format_tag_t gOIhw4o4i = mkldnn_gOIhw4o4i;
+ const format_tag_t gOihw4o = mkldnn_gOihw4o;
+ const format_tag_t Goihw8g = mkldnn_Goihw8g;
+ const format_tag_t gOIhw8i16o2i = mkldnn_gOIhw8i16o2i;
+ const format_tag_t gOIhw8i8o = mkldnn_gOIhw8i8o;
+ const format_tag_t gOIhw8o16i2o = mkldnn_gOIhw8o16i2o;
+ const format_tag_t gOIhw8o8i = mkldnn_gOIhw8o8i;
+ const format_tag_t gOdhwi16o = mkldnn_gOdhwi16o;
+ const format_tag_t gOdhwi4o = mkldnn_gOdhwi4o;
+ const format_tag_t gOdhwi8o = mkldnn_gOdhwi8o;
+ const format_tag_t gOIdhw16i16o = mkldnn_gOIdhw16i16o;
+ const format_tag_t gOIdhw16o16i = mkldnn_gOIdhw16o16i;
+ const format_tag_t gOidhw16o = mkldnn_gOidhw16o;
+ const format_tag_t gOIdhw4i4o = mkldnn_gOIdhw4i4o;
+ const format_tag_t gOidhw4o = mkldnn_gOidhw4o;
+ const format_tag_t gOIdhw8i16o2i = mkldnn_gOIdhw8i16o2i;
+ const format_tag_t gOIdhw8i8o = mkldnn_gOIdhw8i8o;
+ const format_tag_t gOIdhw8o8i = mkldnn_gOIdhw8o8i;
+}
+
+using memory_extra_flags_t = mkldnn_memory_extra_flags_t;
+namespace memory_extra_flags {
+ const memory_extra_flags_t none = mkldnn_memory_extra_flag_none;
+ const memory_extra_flags_t compensation_conv_s8s8 = mkldnn_memory_extra_flag_compensation_conv_s8s8;
+ const memory_extra_flags_t scale_adjust = mkldnn_memory_extra_flag_scale_adjust;
+}
+
+using padding_kind_t = mkldnn_padding_kind_t;
+namespace padding_kind {
+ const padding_kind_t padding_zero = mkldnn_padding_zero;
+}
+
+using engine_kind_t = mkldnn_engine_kind_t;
+namespace engine_kind {
+ const engine_kind_t any_engine = mkldnn_any_engine;
+ const engine_kind_t cpu = mkldnn_cpu;
+}
+
+using primitive_kind_t = mkldnn_primitive_kind_t;
+namespace primitive_kind {
+ const primitive_kind_t undefined = mkldnn_undefined_primitive;
+ const primitive_kind_t reorder = mkldnn_reorder;
+ const primitive_kind_t concat = mkldnn_concat;
+ const primitive_kind_t sum = mkldnn_sum;
+ const primitive_kind_t convolution = mkldnn_convolution;
+ const primitive_kind_t deconvolution = mkldnn_deconvolution;
+ const primitive_kind_t shuffle = mkldnn_shuffle;
+ const primitive_kind_t eltwise = mkldnn_eltwise;
+ const primitive_kind_t softmax = mkldnn_softmax;
+ const primitive_kind_t pooling = mkldnn_pooling;
+ const primitive_kind_t lrn = mkldnn_lrn;
+ const primitive_kind_t batch_normalization = mkldnn_batch_normalization;
+ const primitive_kind_t inner_product = mkldnn_inner_product;
+ const primitive_kind_t rnn = mkldnn_rnn;
+}
+
+using query_t = mkldnn_query_t;
+namespace query {
+ const query_t undef = mkldnn_query_undef;
+
+ const query_t engine = mkldnn_query_engine;
+ const query_t primitive_kind = mkldnn_query_primitive_kind;
+
+ const query_t num_of_inputs_s32 = mkldnn_query_num_of_inputs_s32;
+ const query_t num_of_outputs_s32 = mkldnn_query_num_of_outputs_s32;
+
+ const query_t time_estimate_f64 = mkldnn_query_time_estimate_f64;
+ const query_t memory_consumption_s64 = mkldnn_query_memory_consumption_s64;
+
+ const query_t scratchpad_engine = mkldnn_query_scratchpad_engine;
+
+ const query_t impl_info_str = mkldnn_query_impl_info_str;
+
+ const query_t some_d = mkldnn_query_some_d;
+ const query_t op_d = mkldnn_query_op_d;
+ const query_t convolution_d = mkldnn_query_convolution_d;
+ const query_t deconvolution_d = mkldnn_query_deconvolution_d;
+ const query_t shuffle_d = mkldnn_query_shuffle_d;
+ const query_t eltwise_d = mkldnn_query_eltwise_d;
+ const query_t softmax_d = mkldnn_query_softmax_d;
+ const query_t pooling_d = mkldnn_query_pooling_d;
+ const query_t lrn_d = mkldnn_query_lrn_d;
+ const query_t batch_normalization_d = mkldnn_query_batch_normalization_d;
+ const query_t inner_product_d = mkldnn_query_inner_product_d;
+ const query_t rnn_d = mkldnn_query_rnn_d;
+
+ const query_t some_md = mkldnn_query_some_md;
+ const query_t src_md = mkldnn_query_src_md;
+ const query_t diff_src_md = mkldnn_query_diff_src_md;
+ const query_t weights_md = mkldnn_query_weights_md;
+ const query_t diff_weights_md = mkldnn_query_diff_weights_md;
+ const query_t dst_md = mkldnn_query_dst_md;
+ const query_t diff_dst_md = mkldnn_query_diff_dst_md;
+
+ const query_t workspace_md = mkldnn_query_workspace_md;
+ const query_t scratchpad_md = mkldnn_query_scratchpad_md;
+}
+
+using blocking_desc_t = mkldnn_blocking_desc_t;
+using rnn_packed_desc_t = mkldnn_rnn_packed_desc_t;
+using wino_desc_t = mkldnn_wino_desc_t;
+using memory_extra_desc_t = mkldnn_memory_extra_desc_t;
+using memory_desc_t = mkldnn_memory_desc_t;
+using convolution_desc_t = mkldnn_convolution_desc_t;
+using deconvolution_desc_t = mkldnn_deconvolution_desc_t;
+using shuffle_desc_t = mkldnn_shuffle_desc_t;
+using pooling_desc_t = mkldnn_pooling_desc_t;
+using eltwise_desc_t = mkldnn_eltwise_desc_t;
+using softmax_desc_t = mkldnn_softmax_desc_t;
+using lrn_desc_t = mkldnn_lrn_desc_t;
+using batch_normalization_desc_t = mkldnn_batch_normalization_desc_t;
+using inner_product_desc_t = mkldnn_inner_product_desc_t;
+
+using rnn_direction_t = mkldnn_rnn_direction_t;
+using rnn_cell_desc_t = mkldnn_rnn_cell_desc_t;
+using rnn_desc_t = mkldnn_rnn_desc_t;
+
+/* C op_desc_t, which eventually are just (void*) */
+using c_op_desc_t = mkldnn_op_desc_t;
+using const_c_op_desc_t = const_mkldnn_op_desc_t;
+
+struct op_desc_t {
+ union {
+ primitive_kind_t kind;
+ convolution_desc_t convolution;
+ deconvolution_desc_t deconvolution;
+ shuffle_desc_t shuffle;
+ pooling_desc_t pooling;
+ eltwise_desc_t eltwise;
+ softmax_desc_t softmax;
+ lrn_desc_t lrn;
+ batch_normalization_desc_t batch_normalization;
+ inner_product_desc_t inner_product;
+ rnn_desc_t rnn;
+ };
+
+ op_desc_t(const primitive_kind_t &_): kind(_) {}
+
+# define DECL_CTOR_AND_CONVERTERS(c_type, name) \
+ op_desc_t(const c_type &_): name(_) {} \
+ static op_desc_t *convert_from_c(c_type *_) \
+ { return reinterpret_cast<op_desc_t*>(_); } \
+ static const op_desc_t *convert_from_c(const c_type *_) \
+ { return reinterpret_cast<const op_desc_t*>(_); }
+
+ DECL_CTOR_AND_CONVERTERS(convolution_desc_t, convolution);
+ DECL_CTOR_AND_CONVERTERS(shuffle_desc_t, shuffle);
+ DECL_CTOR_AND_CONVERTERS(pooling_desc_t, pooling);
+ DECL_CTOR_AND_CONVERTERS(eltwise_desc_t, eltwise);
+ DECL_CTOR_AND_CONVERTERS(softmax_desc_t, softmax);
+ DECL_CTOR_AND_CONVERTERS(lrn_desc_t, lrn);
+ DECL_CTOR_AND_CONVERTERS(batch_normalization_desc_t, batch_normalization);
+ DECL_CTOR_AND_CONVERTERS(inner_product_desc_t, inner_product);
+ DECL_CTOR_AND_CONVERTERS(rnn_desc_t, rnn);
+
+# undef DECL_CTOR_AND_CONVERTERS
+};
+
+using engine_t = mkldnn_engine;
+using primitive_desc_iterator_t = mkldnn_primitive_desc_iterator;
+using primitive_desc_t = mkldnn_primitive_desc;
+using primitive_attr_t = mkldnn_primitive_attr;
+using post_ops_t = mkldnn_post_ops;
+using memory_t = mkldnn_memory;
+using primitive_t = mkldnn_primitive;
+
+using primitive_arg_index_t = int;
+
+using stream_flags_t = mkldnn_stream_flags_t;
+namespace stream_flags {
+ const stream_flags_t default_flags = mkldnn_stream_default_flags;
+}
+using stream_t = mkldnn_stream;
+
+/* forward declaration of the internal primitive_desc types */
+struct batch_normalization_bwd_pd_t;
+struct batch_normalization_fwd_pd_t;
+struct batch_normalization_pd_t;
+struct concat_pd_t;
+struct convolution_bwd_data_pd_t;
+struct convolution_bwd_weights_pd_t;
+struct convolution_fwd_pd_t;
+struct convolution_pd_t;
+struct deconvolution_bwd_data_pd_t;
+struct deconvolution_bwd_weights_pd_t;
+struct deconvolution_fwd_pd_t;
+struct deconvolution_pd_t;
+struct eltwise_bwd_pd_t;
+struct eltwise_fwd_pd_t;
+struct eltwise_pd_t;
+struct inner_product_bwd_data_pd_t;
+struct inner_product_bwd_weights_pd_t;
+struct inner_product_fwd_pd_t;
+struct inner_product_pd_t;
+struct lrn_bwd_pd_t;
+struct lrn_fwd_pd_t;
+struct lrn_pd_t;
+struct pooling_bwd_pd_t;
+struct pooling_fwd_pd_t;
+struct pooling_pd_t;
+struct reorder_pd_t;
+struct rnn_bwd_pd_t;
+struct rnn_fwd_pd_t;
+struct rnn_pd_t;
+struct shuffle_pd_t;
+struct softmax_bwd_pd_t;
+struct softmax_fwd_pd_t;
+struct softmax_pd_t;
+struct sum_pd_t;
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/concat.cpp b/thirdparty/oidn/mkl-dnn/src/common/concat.cpp
new file mode 100644
index 0000000000..ed4c35c6e9
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/concat.cpp
@@ -0,0 +1,86 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "engine.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "concat_pd.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+
+status_t mkldnn_concat_primitive_desc_create(primitive_desc_t **concat_pd,
+ const memory_desc_t *dst_md, int n, int concat_dim,
+ const memory_desc_t *src_mds,
+ const primitive_attr_t *attr,
+ engine_t *engine) {
+ bool args_ok = !any_null(concat_pd, src_mds) && n > 0;
+ if (!args_ok) return invalid_arguments;
+
+ const primitive_attr_t dummy_attr;
+ if (attr == NULL)
+ attr = &dummy_attr;
+
+ const int ndims = src_mds[0].ndims;
+ const dims_t &dims = src_mds[0].dims;
+ const data_type_t dt = src_mds[0].data_type;
+
+ int concat_dim_sz = dims[concat_dim];
+ for (int i = 1; i < n; ++i) {
+ if (src_mds[i].ndims != ndims) return invalid_arguments;
+ for (int d = 0; d < ndims; ++d) {
+ if (d == concat_dim) continue;
+ if (src_mds[i].dims[d] != dims[d])
+ return invalid_arguments;
+ }
+ if (src_mds[i].data_type != dt) return invalid_arguments;
+ concat_dim_sz += src_mds[i].dims[concat_dim];
+ }
+
+ memory_desc_t dummy_dst_md;
+ if (dst_md) {
+ if (dst_md->ndims != ndims) return invalid_arguments;
+ for (int d = 0; d < ndims; ++d) {
+ if (dst_md->dims[d] !=
+ (d == concat_dim ? concat_dim_sz : dims[d]))
+ return invalid_arguments;
+ }
+ } else {
+ dummy_dst_md = src_mds[0];
+ dummy_dst_md.dims[concat_dim] = concat_dim_sz;
+ dummy_dst_md.format_kind = format_kind::any;
+ dst_md = &dummy_dst_md;
+ }
+
+ auto c_pd = reinterpret_cast<concat_pd_t **>(concat_pd);
+
+ for (auto c = engine->get_concat_implementation_list(); *c; ++c) {
+ if ((*c)(c_pd, engine, attr, dst_md, n, concat_dim, src_mds)
+ == success) {
+ (*c_pd)->init_info();
+ (*c_pd)->init_scratchpad_md();
+ return success;
+ }
+ }
+ return unimplemented;
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/concat_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/concat_pd.hpp
new file mode 100644
index 0000000000..29311927e2
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/concat_pd.hpp
@@ -0,0 +1,211 @@
+/*******************************************************************************
+* Copyright 2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CONCAT_PD_HPP
+#define CONCAT_PD_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "primitive_desc.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct concat_pd_t: public primitive_desc_t {
+ concat_pd_t(engine_t *engine, const primitive_attr_t *attr,
+ const memory_desc_t *dst_md, int n, int concat_dim,
+ const memory_desc_t *src_mds)
+ : primitive_desc_t(engine, attr, primitive_kind::concat)
+ , n_(n), concat_dim_(concat_dim), dst_md_(*dst_md)
+ {
+ src_mds_.reserve(n_);
+ for (int i = 0; i < n_; ++i) src_mds_.push_back(src_mds[i]);
+ }
+
+ concat_pd_t(const concat_pd_t &rhs) = default;
+
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (arg >= MKLDNN_ARG_MULTIPLE_SRC
+ && arg < MKLDNN_ARG_MULTIPLE_SRC + n_inputs())
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DST)
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index < n_inputs() ? &src_mds_[index] : nullptr; }
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 ? &dst_md_ : nullptr; }
+
+ virtual int n_inputs() const override { return n_; }
+ virtual int n_outputs() const override { return 1; }
+
+ int concat_dim() const { return concat_dim_; }
+
+ const memory_desc_t *src_image_md(int index = 0) const
+ { return index < n_inputs() ? &src_image_mds_[index] : nullptr; }
+
+protected:
+ int n_, concat_dim_;
+ memory_desc_t dst_md_;
+ nstl::vector<memory_desc_t> src_mds_;
+
+ /* contains images of srcs in the dst memory (if possible)
+ * Lives here to simplify some implementations. An implementation might
+ * use this auxiliary array iff init() returned success */
+ nstl::vector<memory_desc_t> src_image_mds_;
+
+protected:
+ /* inits src_image_mds_ and dst_md_ in simple cases. The call may fail */
+ status_t init() {
+ bool ok = true
+ && set_default_params() == status::success
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ for (int i = 0; i < n_; ++i) {
+ const memory_desc_wrapper i_d(&src_mds_[i]);
+ if (!i_d.is_blocking_desc() || i_d.is_additional_buffer())
+ return status::unimplemented;
+ }
+
+ const int ndims = dst_md_.ndims;
+ int current_concat_dim_offset = 0;
+ for (int i = 0; i < n_; ++i) {
+ const int dim = src_mds_[i].dims[concat_dim_];
+ dims_t dims, offsets = {};
+ utils::array_copy(dims, dst_md_.dims, ndims);
+ dims[concat_dim_] = dim;
+ offsets[concat_dim_] = current_concat_dim_offset;
+
+ memory_desc_t src_img_d;
+ status_t status = mkldnn_memory_desc_init_submemory(&src_img_d,
+ &dst_md_, dims, offsets);
+ if (status != status::success) return status;
+ src_image_mds_.push_back(src_img_d);
+ current_concat_dim_offset += dim;
+ }
+
+ return status::success;
+ }
+
+ status_t set_default_params() {
+ if (dst_md_.format_kind != format_kind::any)
+ return status::success;
+
+ const int ndims = dst_md_.ndims;
+
+ /* The stupidest ever heuristics (but not the same as we had before):
+ * - Pick the first non-plain format;
+ * - If all formats are plain or it is not possible to create a
+ * blocked format for the output, pick the format of the plain input
+ * - If this fails as well, use plain layout (abcd...)
+ */
+ status_t status = status::unimplemented;
+ for (int i = 0; i < n_; ++i) {
+ const memory_desc_wrapper src_d(src_mds_[i]);
+ if (src_d.is_blocking_desc() && !src_d.is_plain()) {
+ status = memory_desc_init_by_blocking_desc(dst_md_,
+ src_d.blocking_desc());
+ if (status == status::success) break;
+ }
+ }
+
+ if (status == status::success) {
+ /* check if we can create a sub-memory for the dst */
+ bool desired_format_ok = true;
+ int current_concat_dim_offset = 0;
+ for (int i = 0; i < n_; ++i) {
+ const int dim = src_mds_[i].dims[concat_dim_];
+ dims_t dims, offsets = {};
+ utils::array_copy(dims, dst_md_.dims, ndims);
+ dims[concat_dim_] = dim;
+ offsets[concat_dim_] = current_concat_dim_offset;
+
+ memory_desc_t src_img_d;
+ status_t status = mkldnn_memory_desc_init_submemory(&src_img_d,
+ &dst_md_, dims, offsets);
+ if (status != status::success) {
+ desired_format_ok = false;
+ break;
+ }
+ current_concat_dim_offset += dim;
+ }
+
+ if (!desired_format_ok)
+ status = status::unimplemented;
+ }
+
+ /* if no success so far, try using the format of the first plain input */
+ if (status != status::success) {
+ for (int i = 0; i < n_; ++i) {
+ const memory_desc_wrapper src_d(src_mds_[i]);
+ if (src_d.is_blocking_desc() && src_d.is_plain()) {
+ status = memory_desc_init_by_blocking_desc(dst_md_,
+ memory_desc_wrapper(src_mds_[0]).blocking_desc());
+ if (status == status::success) return status;
+ }
+ }
+ }
+
+ /* the last line of defense: use plain abcd... format */
+ if (status != status::success)
+ status = memory_desc_init_by_strides(dst_md_, nullptr);
+
+ return status;
+ }
+};
+
+#define DECLARE_CONCAT_PD_t(impl_name, ...) \
+ static status_t create(concat_pd_t **concat_pd, \
+ engine_t *engine, const primitive_attr_t *attr, \
+ const memory_desc_t *dst_md, int n, int concat_dim, \
+ const memory_desc_t *src_mds) { \
+ using namespace status; \
+ auto _pd = new pd_t(engine, attr, dst_md, n, concat_dim, src_mds); \
+ if (_pd == nullptr) return out_of_memory; \
+ if (_pd->init() != success) { delete _pd; return unimplemented; } \
+ return safe_ptr_assign<concat_pd_t>(*concat_pd, _pd); \
+ } \
+ virtual status_t create_primitive(primitive_t **p) const override { \
+ double ms = get_msec(); \
+ auto ret = safe_ptr_assign<primitive_t>(*p, new (__VA_ARGS__)(this)); \
+ ms = get_msec() - ms; \
+ if (mkldnn_verbose()->level >= 2) { \
+ printf("mkldnn_verbose,create,%s,%g\n", this->info(), ms); \
+ fflush(0); \
+ } \
+ return ret; \
+ } \
+ virtual pd_t *clone() const override { return new pd_t(*this); } \
+ virtual const char *name() const override { return impl_name; } \
+
+#define DECLARE_CONCAT_PD_T(impl_name, ...) \
+ DECLARE_CONCAT_PD_t(impl_name, __VA_ARGS__)
+
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/convolution.cpp b/thirdparty/oidn/mkl-dnn/src/common/convolution.cpp
new file mode 100644
index 0000000000..0c5c02bcd1
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/convolution.cpp
@@ -0,0 +1,200 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::alg_kind;
+using namespace mkldnn::impl::types;
+
+namespace mkldnn {
+namespace impl {
+status_t conv_desc_init(convolution_desc_t *conv_desc,
+ prop_kind_t prop_kind, alg_kind_t alg_kind,
+ const memory_desc_t *src_desc, const memory_desc_t *weights_desc,
+ const memory_desc_t *bias_desc, const memory_desc_t *dst_desc,
+ const dims_t strides, const dims_t dilates,
+ const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ bool args_ok = true
+ && !any_null(conv_desc, src_desc, weights_desc, dst_desc, strides,
+ padding_l)
+ && one_of(alg_kind, convolution_auto, convolution_direct, convolution_winograd)
+ && one_of(padding_kind, padding_kind::padding_zero);
+ if (!args_ok) return invalid_arguments;
+
+ if (padding_r == nullptr) padding_r = padding_l;
+
+ auto cd = convolution_desc_t();
+ cd.primitive_kind = primitive_kind::convolution;
+ cd.prop_kind = prop_kind;
+ cd.alg_kind = alg_kind;
+
+ cd.diff_src_desc = cd.src_desc = zero_md();
+ cd.diff_dst_desc = cd.dst_desc = zero_md();
+ cd.diff_weights_desc = cd.weights_desc = zero_md();
+ cd.diff_bias_desc = cd.bias_desc = zero_md();
+
+ const bool is_fwd = one_of(prop_kind, forward_training, forward_inference);
+ const bool with_bias =
+ bias_desc && bias_desc->format_kind != format_kind::undef;
+ const bool with_groups = weights_desc->ndims == src_desc->ndims + 1;
+
+ (prop_kind == backward_data ? cd.diff_src_desc : cd.src_desc) = *src_desc;
+ (is_fwd ? cd.dst_desc : cd.diff_dst_desc) = *dst_desc;
+ (prop_kind == backward_weights ? cd.diff_weights_desc : cd.weights_desc) =
+ *weights_desc;
+ if (with_bias)
+ (prop_kind == backward_weights ? cd.diff_bias_desc : cd.bias_desc) =
+ *bias_desc;
+
+ int sp_dims = src_desc->ndims - 2;
+ utils::array_copy(cd.strides, strides, sp_dims);
+ utils::array_copy(cd.padding[0], padding_l, sp_dims);
+ utils::array_copy(cd.padding[1], padding_r, sp_dims);
+ if (dilates)
+ utils::array_copy(cd.dilates, dilates, sp_dims);
+ else
+ utils::array_set(cd.dilates, 0, sp_dims);
+
+ cd.padding_kind = padding_kind;
+ cd.accum_data_type = types::default_accum_data_type(src_desc->data_type,
+ weights_desc->data_type, dst_desc->data_type, prop_kind);
+
+ const int g = with_groups ? weights_desc->dims[0] : 1;
+ const int bias_dim = prop_kind == backward_data
+ ? src_desc->dims[1]
+ : dst_desc->dims[1];
+
+ bool consistency = true
+ && memory_desc_wrapper(weights_desc).nelems()
+ && src_desc->ndims == dst_desc->ndims
+ && utils::one_of(src_desc->ndims, 3, 4, 5)
+ && utils::one_of(weights_desc->ndims, src_desc->ndims,
+ src_desc->ndims + 1)
+ && (with_bias ? bias_desc->ndims == 1 : true)
+ && (with_bias ? bias_desc->dims[0] == bias_dim : true)
+ && src_desc->dims[0] == dst_desc->dims[0]
+ && src_desc->dims[1] == g * weights_desc->dims[with_groups + 1]
+ && dst_desc->dims[1] == g * weights_desc->dims[with_groups + 0];
+ for (int i = 2; i < src_desc->ndims; ++i)
+ {
+ int src = src_desc->dims[i];
+ int ker = weights_desc->dims[with_groups + i];
+ int dil = cd.dilates[i - 2];
+ int pad_l = padding_l[i - 2];
+ int pad_r = padding_r[i - 2];
+ int str = strides[i - 2];
+ int dst = dst_desc->dims[i];
+ int ker_range = 1 + (ker - 1) * (dil + 1);
+
+ if (str < 1) return invalid_arguments;
+ consistency = consistency
+ && dil >= 0
+ && pad_l >= 0
+ && pad_r + str > 0
+ && (src - ker_range + pad_l + pad_r) / str + 1 == dst;
+ }
+ if (!consistency) return invalid_arguments;
+
+ *conv_desc = cd;
+ return success;
+}
+}
+}
+
+status_t mkldnn_convolution_forward_desc_init(convolution_desc_t *conv_desc,
+ prop_kind_t prop_kind, alg_kind_t alg_kind,
+ const memory_desc_t *src_desc, const memory_desc_t *weights_desc,
+ const memory_desc_t *bias_desc, const memory_desc_t *dst_desc,
+ const dims_t strides, const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ if (!one_of(prop_kind, forward_training, forward_inference))
+ return invalid_arguments;
+ return mkldnn::impl::conv_desc_init(conv_desc, prop_kind, alg_kind, src_desc,
+ weights_desc, bias_desc, dst_desc, strides, nullptr,
+ padding_l, padding_r, padding_kind);
+}
+
+status_t mkldnn_dilated_convolution_forward_desc_init(
+ convolution_desc_t *conv_desc, prop_kind_t prop_kind,
+ alg_kind_t alg_kind, const memory_desc_t *src_desc,
+ const memory_desc_t *weights_desc, const memory_desc_t *bias_desc,
+ const memory_desc_t *dst_desc, const dims_t strides,
+ const dims_t dilates, const dims_t padding_l,
+ const dims_t padding_r, padding_kind_t padding_kind) {
+ if (!one_of(prop_kind, forward_training, forward_inference))
+ return invalid_arguments;
+ return mkldnn::impl::conv_desc_init(conv_desc, prop_kind, alg_kind, src_desc,
+ weights_desc, bias_desc, dst_desc, strides, dilates,
+ padding_l, padding_r, padding_kind);
+}
+
+status_t mkldnn_convolution_backward_data_desc_init(
+ convolution_desc_t *conv_desc, alg_kind_t alg_kind,
+ const memory_desc_t *diff_src_desc, const memory_desc_t *weights_desc,
+ const memory_desc_t *diff_dst_desc, const dims_t strides,
+ const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ return mkldnn::impl::conv_desc_init(conv_desc, backward_data, alg_kind, diff_src_desc,
+ weights_desc, nullptr, diff_dst_desc, strides, nullptr,
+ padding_l, padding_r, padding_kind);
+}
+
+status_t mkldnn_dilated_convolution_backward_data_desc_init(
+ convolution_desc_t *conv_desc, alg_kind_t alg_kind,
+ const memory_desc_t *diff_src_desc, const memory_desc_t *weights_desc,
+ const memory_desc_t *diff_dst_desc, const dims_t strides,
+ const dims_t dilates, const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ return mkldnn::impl::conv_desc_init(conv_desc, backward_data, alg_kind, diff_src_desc,
+ weights_desc, nullptr, diff_dst_desc, strides, dilates,
+ padding_l, padding_r, padding_kind);
+}
+
+status_t mkldnn_convolution_backward_weights_desc_init(
+ convolution_desc_t *conv_desc, alg_kind_t alg_kind,
+ const memory_desc_t *src_desc, const memory_desc_t *diff_weights_desc,
+ const memory_desc_t *diff_bias_desc,
+ const memory_desc_t *diff_dst_desc, const dims_t strides,
+ const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ return mkldnn::impl::conv_desc_init(conv_desc, backward_weights, alg_kind, src_desc,
+ diff_weights_desc, diff_bias_desc, diff_dst_desc, strides,
+ nullptr, padding_l, padding_r, padding_kind);
+}
+
+status_t mkldnn_dilated_convolution_backward_weights_desc_init(
+ convolution_desc_t *conv_desc, alg_kind_t alg_kind,
+ const memory_desc_t *src_desc, const memory_desc_t *diff_weights_desc,
+ const memory_desc_t *diff_bias_desc,
+ const memory_desc_t *diff_dst_desc, const dims_t strides,
+ const dims_t dilates, const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ return mkldnn::impl::conv_desc_init(conv_desc, backward_weights, alg_kind, src_desc,
+ diff_weights_desc, diff_bias_desc, diff_dst_desc, strides,
+ dilates, padding_l, padding_r, padding_kind);
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/convolution_pd.cpp b/thirdparty/oidn/mkl-dnn/src/common/convolution_pd.cpp
new file mode 100644
index 0000000000..9604e0acf5
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/convolution_pd.cpp
@@ -0,0 +1,56 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "utils.hpp"
+
+#include "convolution_pd.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+using namespace prop_kind;
+
+memory_desc_t *conv_prop_invariant_src_d(convolution_desc_t *desc) {
+ return desc->prop_kind == backward_data
+ ? &desc->diff_src_desc : &desc->src_desc;
+}
+
+memory_desc_t *conv_prop_invariant_wei_d(convolution_desc_t *desc) {
+ return desc->prop_kind == backward_weights
+ ? &desc->diff_weights_desc : &desc->weights_desc;
+}
+
+memory_desc_t *conv_prop_invariant_bia_d(convolution_desc_t *desc) {
+ return desc->prop_kind == backward_weights
+ ? &desc->diff_bias_desc : &desc->bias_desc;
+}
+
+memory_desc_t *conv_prop_invariant_dst_d(convolution_desc_t *desc) {
+ return utils::one_of(desc->prop_kind, forward_inference, forward_training)
+ ? &desc->dst_desc : &desc->diff_dst_desc;
+}
+
+const memory_desc_t *conv_prop_invariant_src_d(const convolution_desc_t *desc)
+{ return conv_prop_invariant_src_d(const_cast<convolution_desc_t *>(desc)); }
+const memory_desc_t *conv_prop_invariant_wei_d(const convolution_desc_t *desc)
+{ return conv_prop_invariant_wei_d(const_cast<convolution_desc_t *>(desc)); }
+const memory_desc_t *conv_prop_invariant_bia_d(const convolution_desc_t *desc)
+{ return conv_prop_invariant_bia_d(const_cast<convolution_desc_t *>(desc)); }
+const memory_desc_t *conv_prop_invariant_dst_d(const convolution_desc_t *desc)
+{ return conv_prop_invariant_dst_d(const_cast<convolution_desc_t *>(desc)); }
+
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/convolution_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/convolution_pd.hpp
new file mode 100644
index 0000000000..b10c36db49
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/convolution_pd.hpp
@@ -0,0 +1,348 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CONVOLUTION_PD_HPP
+#define CONVOLUTION_PD_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "primitive_desc.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+status_t conv_desc_init(convolution_desc_t *conv_desc,
+ prop_kind_t prop_kind, alg_kind_t alg_kind,
+ const memory_desc_t *src_desc, const memory_desc_t *weights_desc,
+ const memory_desc_t *bias_desc, const memory_desc_t *dst_desc,
+ const dims_t strides, const dims_t dilates,
+ const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind);
+
+memory_desc_t *conv_prop_invariant_src_d(convolution_desc_t *desc);
+memory_desc_t *conv_prop_invariant_wei_d(convolution_desc_t *desc);
+memory_desc_t *conv_prop_invariant_bia_d(convolution_desc_t *desc);
+memory_desc_t *conv_prop_invariant_dst_d(convolution_desc_t *desc);
+const memory_desc_t *conv_prop_invariant_src_d(const convolution_desc_t *desc);
+const memory_desc_t *conv_prop_invariant_wei_d(const convolution_desc_t *desc);
+const memory_desc_t *conv_prop_invariant_bia_d(const convolution_desc_t *desc);
+const memory_desc_t *conv_prop_invariant_dst_d(const convolution_desc_t *desc);
+
+struct convolution_fwd_pd_t;
+
+struct convolution_pd_t: public primitive_desc_t {
+ static constexpr auto base_pkind = primitive_kind::convolution;
+
+ convolution_pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : primitive_desc_t(engine, attr, base_pkind)
+ , desc_(*adesc)
+ , hint_fwd_pd_(hint_fwd_pd)
+ {}
+
+ const convolution_desc_t *desc() const { return &desc_; }
+ virtual const op_desc_t *op_desc() const override
+ { return reinterpret_cast<const op_desc_t *>(this->desc()); }
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual status_t query(query_t what, int idx, void *result) const override {
+ switch (what) {
+ case pkind_traits<base_pkind>::query_d:
+ *(const convolution_desc_t**)result = desc(); break;
+ default: return primitive_desc_t::query(what, idx, result);
+ }
+ return status::success;
+ }
+
+ /* common conv aux functions */
+
+ dim_t MB() const { return _src_md()->dims[0]; }
+
+ dim_t IC() const { return _src_md()->dims[1]; }
+ dim_t OC() const { return _dst_md()->dims[1]; }
+ dim_t G() const { return with_groups() ? _wei_md()->dims[0] : 1; }
+
+ dim_t ID() const { return ndims() >= 5 ? _src_md()->dims[ndims() - 3] : 1; }
+ dim_t IH() const { return ndims() >= 4 ? _src_md()->dims[ndims() - 2] : 1; }
+ dim_t IW() const { return _src_md()->dims[ndims() - 1]; }
+
+ dim_t OD() const { return ndims() >= 5 ? _dst_md()->dims[ndims() - 3] : 1; }
+ dim_t OH() const { return ndims() >= 4 ? _dst_md()->dims[ndims() - 2] : 1; }
+ dim_t OW() const { return _dst_md()->dims[ndims() - 1]; }
+
+ dim_t KD() const { return ndims() >= 5 ? _wei_md()->dims[ndims() + with_groups() - 3] : 1; }
+ dim_t KH() const { return ndims() >= 4 ? _wei_md()->dims[ndims() + with_groups() - 2] : 1; }
+ dim_t KW() const { return _wei_md()->dims[ndims() + with_groups() - 1]; }
+
+ dim_t KSD() const { return ndims() >= 5 ? desc_.strides[ndims() - 5] : 1; }
+ dim_t KSH() const { return ndims() >= 4 ? desc_.strides[ndims() - 4] : 1; }
+ dim_t KSW() const { return desc_.strides[ndims() - 3]; }
+
+ dim_t KDD() const { return ndims() >= 5 ? desc_.dilates[ndims() - 5] : 0; }
+ dim_t KDH() const { return ndims() >= 4 ? desc_.dilates[ndims() - 4] : 1; }
+ dim_t KDW() const { return desc_.dilates[ndims() - 3]; }
+
+ dim_t padFront() const { return ndims() >= 5 ? desc_.padding[0][ndims() - 5] : 0; }
+ dim_t padBack() const { return ndims() >= 5 ? desc_.padding[1][ndims() - 5] : 0; }
+ dim_t padT() const { return ndims() >= 4 ? desc_.padding[0][ndims() - 4] : 0; }
+ dim_t padB() const { return ndims() >= 4 ? desc_.padding[1][ndims() - 4] : 0; }
+ dim_t padL() const { return desc_.padding[0][ndims() - 3]; }
+ dim_t padR() const { return desc_.padding[1][ndims() - 3]; }
+
+ int ndims() const { return _src_md()->ndims; }
+
+ bool with_bias() const { return !memory_desc_wrapper(*_bia_md()).is_zero(); }
+ bool with_groups() const { return _wei_md()->ndims == ndims() + 1; }
+
+ bool is_fwd() const {
+ return utils::one_of(desc_.prop_kind, prop_kind::forward_training,
+ prop_kind::forward_inference);
+ }
+
+ bool has_zero_dim_memory() const {
+ const auto s_d = memory_desc_wrapper(*_src_md());
+ const auto d_d = memory_desc_wrapper(*_dst_md());
+ return s_d.has_zero_dim() || d_d.has_zero_dim();
+ }
+
+protected:
+ convolution_desc_t desc_;
+ const convolution_fwd_pd_t *hint_fwd_pd_;
+
+ bool set_default_formats_common_template(
+ memory_desc_t &src_md, format_tag_t src_tag,
+ memory_desc_t &wei_md, format_tag_t wei_tag,
+ memory_desc_t &dst_md, format_tag_t dst_tag,
+ memory_desc_t &bia_md) {
+ using namespace format_tag;
+
+# define IS_OK(f) \
+ do { if ((f) != status::success) return false; } while(0)
+ if (src_md.format_kind == format_kind::any
+ && !utils::one_of(src_tag, any, undef))
+ IS_OK(memory_desc_init_by_tag(src_md, src_tag));
+ if (dst_md.format_kind == format_kind::any
+ && !utils::one_of(dst_tag, any, undef))
+ IS_OK(memory_desc_init_by_tag(dst_md, dst_tag));
+ if (wei_md.format_kind == format_kind::any
+ && !utils::one_of(wei_tag, any, undef))
+ IS_OK(memory_desc_init_by_tag(wei_md, wei_tag));
+ if (with_bias() && bia_md.format_kind == format_kind::any)
+ IS_OK(memory_desc_init_by_tag(bia_md, x));
+# undef IS_OK
+
+ return true;
+ }
+
+ bool set_default_alg_kind(alg_kind_t alg_kind) {
+ assert(utils::one_of(alg_kind, alg_kind::convolution_direct,
+ alg_kind::convolution_winograd));
+ if (desc_.alg_kind == alg_kind::convolution_auto)
+ desc_.alg_kind = alg_kind;
+ return desc_.alg_kind == alg_kind;
+ }
+
+ bool expect_data_types(data_type_t src_dt, data_type_t wei_dt,
+ data_type_t bia_dt, data_type_t dst_dt, data_type_t acc_dt) const {
+ bool ok = true
+ && (src_dt == data_type::undef || _src_md()->data_type == src_dt)
+ && (wei_dt == data_type::undef || _wei_md()->data_type == wei_dt)
+ && (dst_dt == data_type::undef || _dst_md()->data_type == dst_dt)
+ && (acc_dt == data_type::undef || desc_.accum_data_type == acc_dt);
+ if (with_bias() && bia_dt != data_type::undef)
+ ok = ok && _bia_md()->data_type == bia_dt;
+ return ok;
+ }
+
+private:
+ const memory_desc_t *_src_md() const { return conv_prop_invariant_src_d(&desc_); }
+ const memory_desc_t *_wei_md() const { return conv_prop_invariant_wei_d(&desc_); }
+ const memory_desc_t *_bia_md() const { return conv_prop_invariant_bia_d(&desc_); }
+ const memory_desc_t *_dst_md() const { return conv_prop_invariant_dst_d(&desc_); }
+};
+
+struct convolution_fwd_pd_t: public convolution_pd_t {
+ typedef convolution_fwd_pd_t base_class;
+ typedef convolution_fwd_pd_t hint_class;
+
+ convolution_fwd_pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : convolution_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , src_md_(desc_.src_desc)
+ , weights_md_(desc_.weights_desc)
+ , bias_md_(desc_.bias_desc)
+ , dst_md_(desc_.dst_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_SRC, MKLDNN_ARG_WEIGHTS))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_BIAS && with_bias())
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DST)
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &src_md_ : nullptr; }
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 ? &dst_md_ : nullptr; }
+ virtual const memory_desc_t *weights_md(int index = 0) const override {
+ if (index == 0) return &weights_md_;
+ if (index == 1 && with_bias()) return &bias_md_;
+ return nullptr;
+ }
+
+ virtual int n_inputs() const override { return 2 + with_bias(); }
+ virtual int n_outputs() const override { return 1; }
+
+protected:
+ memory_desc_t src_md_;
+ memory_desc_t weights_md_;
+ memory_desc_t bias_md_;
+ memory_desc_t dst_md_;
+
+ bool set_default_formats_common(format_tag_t src_tag,
+ format_tag_t wei_tag, format_tag_t dst_tag) {
+ return set_default_formats_common_template(src_md_, src_tag,
+ weights_md_, wei_tag, dst_md_, dst_tag, bias_md_);
+ }
+};
+
+struct convolution_bwd_data_pd_t: public convolution_pd_t {
+ typedef convolution_bwd_data_pd_t base_class;
+ typedef convolution_fwd_pd_t hint_class;
+
+ convolution_bwd_data_pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : convolution_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , diff_src_md_(desc_.diff_src_desc)
+ , weights_md_(desc_.weights_desc)
+ , bias_md_(desc_.bias_desc)
+ , diff_dst_md_(desc_.diff_dst_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_WEIGHTS, MKLDNN_ARG_DIFF_DST))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_SRC)
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *diff_src_md(int index = 0) const override
+ { return index == 0 ? &diff_src_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 ? &diff_dst_md_ : nullptr; }
+ virtual const memory_desc_t *weights_md(int index = 0) const override {
+ if (index == 0) return &weights_md_;
+ if (index == 1 && with_bias()) return &bias_md_;
+ return nullptr;
+ }
+
+ virtual int n_inputs() const override { return 2 + with_bias(); }
+ virtual int n_outputs() const override { return 1; }
+
+ virtual bool support_bias() const { return false; }
+
+protected:
+ memory_desc_t diff_src_md_;
+ memory_desc_t weights_md_;
+ memory_desc_t bias_md_;
+ memory_desc_t diff_dst_md_;
+
+ bool set_default_formats_common(format_tag_t diff_src_tag,
+ format_tag_t wei_tag, format_tag_t diff_dst_tag) {
+ return set_default_formats_common_template(diff_src_md_, diff_src_tag,
+ weights_md_, wei_tag, diff_dst_md_, diff_dst_tag, bias_md_);
+ }
+};
+
+struct convolution_bwd_weights_pd_t: public convolution_pd_t {
+ typedef convolution_bwd_weights_pd_t base_class;
+ typedef convolution_fwd_pd_t hint_class;
+
+ convolution_bwd_weights_pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : convolution_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , src_md_(desc_.src_desc)
+ , diff_weights_md_(desc_.diff_weights_desc)
+ , diff_bias_md_(desc_.diff_bias_desc)
+ , diff_dst_md_(desc_.diff_dst_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_SRC, MKLDNN_ARG_DIFF_DST))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_WEIGHTS)
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_DIFF_BIAS && with_bias())
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &src_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 ? &diff_dst_md_ : nullptr; }
+ virtual const memory_desc_t *diff_weights_md(int index = 0) const override {
+ if (index == 0) return &diff_weights_md_;
+ if (index == 1 && with_bias()) return &diff_bias_md_;
+ return nullptr;
+ }
+
+ virtual int n_inputs() const override { return 2; }
+ virtual int n_outputs() const override { return 1 + with_bias(); }
+
+protected:
+ memory_desc_t src_md_;
+ memory_desc_t diff_weights_md_;
+ memory_desc_t diff_bias_md_;
+ memory_desc_t diff_dst_md_;
+
+ bool set_default_formats_common(format_tag_t src_tag,
+ format_tag_t diff_wei_tag, format_tag_t diff_dst_tag) {
+ return set_default_formats_common_template(src_md_, src_tag,
+ diff_weights_md_, diff_wei_tag, diff_dst_md_, diff_dst_tag,
+ diff_bias_md_);
+ }
+};
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/deconvolution.cpp b/thirdparty/oidn/mkl-dnn/src/common/deconvolution.cpp
new file mode 100644
index 0000000000..98063c1c37
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/deconvolution.cpp
@@ -0,0 +1,188 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn.h"
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::alg_kind;
+using namespace mkldnn::impl::types;
+
+namespace {
+status_t deconv_desc_init(deconvolution_desc_t *deconv_desc,
+ prop_kind_t prop_kind, alg_kind_t alg_kind,
+ const memory_desc_t *src_desc, const memory_desc_t *weights_desc,
+ const memory_desc_t *bias_desc, const memory_desc_t *dst_desc,
+ const dims_t strides, const dims_t dilates, const dims_t padding_l,
+ const dims_t padding_r, padding_kind_t padding_kind) {
+ bool args_ok = true
+ && !any_null(deconv_desc, src_desc, weights_desc, dst_desc, strides,
+ padding_l)
+ && one_of(alg_kind, deconvolution_direct, deconvolution_winograd)
+ && one_of(padding_kind, padding_kind::padding_zero);
+ if (!args_ok)
+ return invalid_arguments;
+
+ if (padding_r == nullptr)
+ padding_r = padding_l;
+
+ auto dd = deconvolution_desc_t();
+ dd.primitive_kind = primitive_kind::deconvolution;
+ dd.prop_kind = prop_kind;
+ dd.alg_kind = alg_kind;
+
+ dd.diff_src_desc = dd.src_desc = zero_md();
+ dd.diff_dst_desc = dd.dst_desc = zero_md();
+ dd.diff_weights_desc = dd.weights_desc = zero_md();
+ dd.diff_bias_desc = dd.bias_desc = zero_md();
+
+ const bool is_fwd = one_of(prop_kind, forward_training, forward_inference);
+ const bool with_bias
+ = bias_desc && bias_desc->format_kind != format_kind::undef;
+ const bool with_groups = weights_desc->ndims == src_desc->ndims + 1;
+
+ (prop_kind == backward_data ? dd.diff_src_desc : dd.src_desc) = *src_desc;
+ (is_fwd ? dd.dst_desc : dd.diff_dst_desc) = *dst_desc;
+ (prop_kind == backward_weights ? dd.diff_weights_desc : dd.weights_desc)
+ = *weights_desc;
+ if (with_bias)
+ (prop_kind == backward_weights ? dd.diff_bias_desc : dd.bias_desc)
+ = *bias_desc;
+
+ int sp_dims = src_desc->ndims - 2;
+ utils::array_copy(dd.strides, strides, sp_dims);
+ utils::array_copy(dd.padding[0], padding_l, sp_dims);
+ utils::array_copy(dd.padding[1], padding_r, sp_dims);
+ if (dilates)
+ utils::array_copy(dd.dilates, dilates, sp_dims);
+ else
+ utils::array_set(dd.dilates, 0, sp_dims);
+
+ dd.padding_kind = padding_kind;
+ dd.accum_data_type = types::default_accum_data_type(src_desc->data_type,
+ weights_desc->data_type, dst_desc->data_type, prop_kind);
+
+ const int g = with_groups ? weights_desc->dims[0] : 1;
+ bool consistency = true
+ && src_desc->ndims == dst_desc->ndims
+ && utils::one_of(src_desc->ndims, 3, 4, 5)
+ && utils::one_of(weights_desc->ndims, src_desc->ndims,
+ src_desc->ndims + 1)
+ && (with_bias ? bias_desc->ndims == 1 : true)
+ && (with_bias ? bias_desc->dims[0] == dst_desc->dims[1] : true)
+ && src_desc->dims[0] == dst_desc->dims[0]
+ && src_desc->dims[1] == g * weights_desc->dims[with_groups + 1]
+ && dst_desc->dims[1] == g * weights_desc->dims[with_groups + 0];
+ for (int i = 2; i < src_desc->ndims; ++i) {
+ int src = src_desc->dims[i];
+ int ker = weights_desc->dims[with_groups + i];
+ int dil = dd.dilates[i - 2];
+ int pad = padding_l[i - 2] + padding_r[i - 2];
+ int str = strides[i - 2];
+ int dst = dst_desc->dims[i];
+ int ker_range = 1 + (ker - 1) * (dil + 1);
+
+ consistency
+ = consistency && (dst - ker_range + pad) / str + 1 == src;
+ }
+ if (!consistency)
+ return invalid_arguments;
+
+ *deconv_desc = dd;
+ return success;
+}
+}
+
+status_t mkldnn_deconvolution_forward_desc_init(
+ deconvolution_desc_t *deconv_desc, prop_kind_t prop_kind,
+ alg_kind_t alg_kind, const memory_desc_t *src_desc,
+ const memory_desc_t *weights_desc, const memory_desc_t *bias_desc,
+ const memory_desc_t *dst_desc, const dims_t strides,
+ const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ if (!one_of(prop_kind, forward_training, forward_inference))
+ return invalid_arguments;
+ return deconv_desc_init(deconv_desc, prop_kind, alg_kind, src_desc,
+ weights_desc, bias_desc, dst_desc, strides, nullptr, padding_l,
+ padding_r, padding_kind);
+}
+
+status_t mkldnn_dilated_deconvolution_forward_desc_init(
+ deconvolution_desc_t *deconv_desc, prop_kind_t prop_kind,
+ alg_kind_t alg_kind, const memory_desc_t *src_desc,
+ const memory_desc_t *weights_desc, const memory_desc_t *bias_desc,
+ const memory_desc_t *dst_desc, const dims_t strides,
+ const dims_t dilates, const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ if (!one_of(prop_kind, forward_training, forward_inference))
+ return invalid_arguments;
+ return deconv_desc_init(deconv_desc, prop_kind, alg_kind, src_desc,
+ weights_desc, bias_desc, dst_desc, strides, dilates, padding_l,
+ padding_r, padding_kind);
+}
+
+status_t mkldnn_deconvolution_backward_data_desc_init(
+ deconvolution_desc_t *deconv_desc, alg_kind_t alg_kind,
+ const memory_desc_t *diff_src_desc, const memory_desc_t *weights_desc,
+ const memory_desc_t *diff_dst_desc, const dims_t strides,
+ const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ return deconv_desc_init(deconv_desc, backward_data, alg_kind, diff_src_desc,
+ weights_desc, nullptr, diff_dst_desc, strides, nullptr, padding_l,
+ padding_r, padding_kind);
+}
+
+status_t mkldnn_dilated_deconvolution_backward_data_desc_init(
+ deconvolution_desc_t *deconv_desc, alg_kind_t alg_kind,
+ const memory_desc_t *diff_src_desc, const memory_desc_t *weights_desc,
+ const memory_desc_t *diff_dst_desc, const dims_t strides,
+ const dims_t dilates, const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ return deconv_desc_init(deconv_desc, backward_data, alg_kind, diff_src_desc,
+ weights_desc, nullptr, diff_dst_desc, strides,dilates, padding_l,
+ padding_r, padding_kind);
+}
+
+status_t mkldnn_deconvolution_backward_weights_desc_init(
+ deconvolution_desc_t *deconv_desc, alg_kind_t alg_kind,
+ const memory_desc_t *src_desc, const memory_desc_t *diff_weights_desc,
+ const memory_desc_t *diff_bias_desc, const memory_desc_t *diff_dst_desc,
+ const dims_t strides, const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ return deconv_desc_init(deconv_desc, backward_weights, alg_kind, src_desc,
+ diff_weights_desc, diff_bias_desc, diff_dst_desc, strides, nullptr,
+ padding_l, padding_r, padding_kind);
+}
+
+status_t mkldnn_dilated_deconvolution_backward_weights_desc_init(
+ deconvolution_desc_t *deconv_desc, alg_kind_t alg_kind,
+ const memory_desc_t *src_desc, const memory_desc_t *diff_weights_desc,
+ const memory_desc_t *diff_bias_desc, const memory_desc_t *diff_dst_desc,
+ const dims_t strides, const dims_t dilates, const dims_t padding_l,
+ const dims_t padding_r, padding_kind_t padding_kind) {
+ return deconv_desc_init(deconv_desc, backward_weights, alg_kind, src_desc,
+ diff_weights_desc, diff_bias_desc, diff_dst_desc, strides, dilates,
+ padding_l, padding_r, padding_kind);
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/deconvolution_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/deconvolution_pd.hpp
new file mode 100644
index 0000000000..539e44bd9b
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/deconvolution_pd.hpp
@@ -0,0 +1,293 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef DECONVOLUTION_PD_HPP
+#define DECONVOLUTION_PD_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "convolution_pd.hpp"
+#include "primitive_desc.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct deconvolution_fwd_pd_t;
+
+struct deconvolution_pd_t: public primitive_desc_t {
+ static constexpr auto base_pkind = primitive_kind::deconvolution;
+
+ deconvolution_pd_t(engine_t *engine,
+ const deconvolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const deconvolution_fwd_pd_t *hint_fwd_pd)
+ : primitive_desc_t(engine, attr, base_pkind)
+ , desc_(*adesc)
+ , hint_fwd_pd_(hint_fwd_pd)
+ {}
+
+ const deconvolution_desc_t *desc() const { return &desc_; }
+ virtual const op_desc_t *op_desc() const override
+ { return reinterpret_cast<const op_desc_t *>(this->desc()); }
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual status_t query(query_t what, int idx, void *result) const override {
+ switch (what) {
+ case pkind_traits<base_pkind>::query_d:
+ *(const deconvolution_desc_t **)result = desc();
+ break;
+ default: return primitive_desc_t::query(what, idx, result);
+ }
+ return status::success;
+ }
+
+ /* common deconv aux functions (note that conv_desc_t == deconv_desc_t) */
+
+ dim_t MB() const { return conv_prop_invariant_src_d(&desc_)->dims[0]; }
+
+ dim_t IC() const { return conv_prop_invariant_src_d(&desc_)->dims[1]; }
+ dim_t OC() const { return conv_prop_invariant_dst_d(&desc_)->dims[1]; }
+ dim_t G() const
+ { return with_groups() ? conv_prop_invariant_wei_d(&desc_)->dims[0] : 1; }
+
+ dim_t ID() const {
+ return ndims() >= 5
+ ? conv_prop_invariant_src_d(&desc_)->dims[ndims() - 3] : 1;
+ }
+ dim_t IH() const {
+ return ndims() >= 4
+ ? conv_prop_invariant_src_d(&desc_)->dims[ndims() - 2] : 1;
+ }
+ dim_t IW() const {
+ return conv_prop_invariant_src_d(&desc_)->dims[ndims() - 1];
+ }
+
+ dim_t OD() const {
+ return ndims() >= 5
+ ? conv_prop_invariant_dst_d(&desc_)->dims[ndims() - 3] : 1;
+ }
+ dim_t OH() const {
+ return ndims() >= 4
+ ? conv_prop_invariant_dst_d(&desc_)->dims[ndims() - 2] : 1;
+ }
+ dim_t OW() const {
+ return conv_prop_invariant_dst_d(&desc_)->dims[ndims() - 1];
+ }
+
+ dim_t KD() const {
+ const int w_ndims = ndims() + with_groups();
+ return ndims() >= 5
+ ? conv_prop_invariant_wei_d(&desc_)->dims[w_ndims - 3] : 1;
+ }
+ dim_t KH() const {
+ const int w_ndims = ndims() + with_groups();
+ return ndims() >= 4
+ ? conv_prop_invariant_wei_d(&desc_)->dims[w_ndims - 2] : 1;
+ }
+ dim_t KW() const {
+ const int w_ndims = ndims() + with_groups();
+ return conv_prop_invariant_wei_d(&desc_)->dims[w_ndims - 1];
+ }
+
+ dim_t KSD() const { return ndims() >= 5 ? desc_.strides[ndims() - 5] : 1; }
+ dim_t KSH() const { return ndims() >= 4 ? desc_.strides[ndims() - 4] : 1; }
+ dim_t KSW() const { return desc_.strides[ndims() - 3]; }
+
+ dim_t KDD() const { return ndims() >= 5 ? desc_.dilates[ndims() - 5] : 0; }
+ dim_t KDH() const { return ndims() >= 4 ? desc_.dilates[ndims() - 4] : 1; }
+ dim_t KDW() const { return desc_.dilates[ndims() - 3]; }
+
+ dim_t padFront() const
+ { return ndims() >= 5 ? desc_.padding[0][ndims() - 5] : 0; }
+ dim_t padBack() const
+ { return ndims() >= 5 ? desc_.padding[1][ndims() - 5] : 0; }
+ dim_t padT() const
+ { return ndims() >= 4 ? desc_.padding[0][ndims() - 4] : 0; }
+ dim_t padB() const
+ { return ndims() >= 4 ? desc_.padding[1][ndims() - 4] : 0; }
+ dim_t padL() const { return desc_.padding[0][ndims() - 3]; }
+ dim_t padR() const { return desc_.padding[1][ndims() - 3]; }
+
+ bool with_bias() const {
+ return
+ !memory_desc_wrapper(*conv_prop_invariant_bia_d(&desc_)).is_zero();
+ }
+
+ bool with_groups() const
+ { return conv_prop_invariant_wei_d(&desc_)->ndims == ndims() + 1; }
+
+ int ndims() const { return conv_prop_invariant_src_d(&desc_)->ndims; }
+
+ bool is_fwd() const {
+ return utils::one_of(desc_.prop_kind, prop_kind::forward_training,
+ prop_kind::forward_inference);
+ }
+
+ bool has_zero_dim_memory() const {
+ const auto s_d = memory_desc_wrapper(*conv_prop_invariant_src_d(&desc_));
+ const auto d_d = memory_desc_wrapper(*conv_prop_invariant_dst_d(&desc_));
+ return s_d.has_zero_dim() || d_d.has_zero_dim();
+ }
+
+protected:
+ deconvolution_desc_t desc_;
+ const deconvolution_fwd_pd_t *hint_fwd_pd_;
+};
+
+struct deconvolution_fwd_pd_t: public deconvolution_pd_t {
+ typedef deconvolution_fwd_pd_t base_class;
+ typedef deconvolution_fwd_pd_t hint_class;
+
+ deconvolution_fwd_pd_t(engine_t *engine,
+ const deconvolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const deconvolution_fwd_pd_t *hint_fwd_pd)
+ : deconvolution_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , src_md_(desc_.src_desc)
+ , weights_md_(desc_.weights_desc)
+ , bias_md_(desc_.bias_desc)
+ , dst_md_(desc_.dst_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_SRC, MKLDNN_ARG_WEIGHTS))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_BIAS && with_bias())
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DST)
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &src_md_ : nullptr; }
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 ? &dst_md_ : nullptr; }
+ virtual const memory_desc_t *weights_md(int index = 0) const override {
+ if (index == 0) return &weights_md_;
+ if (index == 1 && with_bias()) return &bias_md_;
+ return nullptr;
+ }
+
+ virtual int n_inputs() const override { return 2 + with_bias(); }
+ virtual int n_outputs() const override { return 1; }
+
+protected:
+ memory_desc_t src_md_;
+ memory_desc_t weights_md_;
+ memory_desc_t bias_md_;
+ memory_desc_t dst_md_;
+};
+
+struct deconvolution_bwd_data_pd_t: public deconvolution_pd_t {
+ typedef deconvolution_bwd_data_pd_t base_class;
+ typedef deconvolution_fwd_pd_t hint_class;
+
+ deconvolution_bwd_data_pd_t(engine_t *engine,
+ const deconvolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const deconvolution_fwd_pd_t *hint_fwd_pd)
+ : deconvolution_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , diff_src_md_(desc_.diff_src_desc)
+ , weights_md_(desc_.weights_desc)
+ , diff_dst_md_(desc_.diff_dst_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_WEIGHTS, MKLDNN_ARG_DIFF_DST))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_SRC)
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *diff_src_md(int index = 0) const override
+ { return index == 0 ? &diff_src_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 ? &diff_dst_md_ : nullptr; }
+ virtual const memory_desc_t *weights_md(int index = 0) const override
+ { return index == 0 ? &weights_md_ : nullptr; }
+
+ virtual int n_inputs() const override { return 2; }
+ virtual int n_outputs() const override { return 1; }
+
+protected:
+ memory_desc_t diff_src_md_;
+ memory_desc_t weights_md_;
+ memory_desc_t diff_dst_md_;
+};
+
+struct deconvolution_bwd_weights_pd_t: public deconvolution_pd_t {
+ typedef deconvolution_bwd_weights_pd_t base_class;
+ typedef deconvolution_fwd_pd_t hint_class;
+
+ deconvolution_bwd_weights_pd_t(engine_t *engine,
+ const deconvolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const deconvolution_fwd_pd_t *hint_fwd_pd)
+ : deconvolution_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , src_md_(desc_.src_desc)
+ , diff_weights_md_(desc_.diff_weights_desc)
+ , diff_bias_md_(desc_.diff_bias_desc)
+ , diff_dst_md_(desc_.diff_dst_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_SRC, MKLDNN_ARG_DIFF_DST))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_WEIGHTS)
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_DIFF_BIAS && with_bias())
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &src_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 ? &diff_dst_md_ : nullptr; }
+ virtual const memory_desc_t *diff_weights_md(int index = 0) const override {
+ if (index == 0) return &diff_weights_md_;
+ if (index == 1 && with_bias()) return &diff_bias_md_;
+ return nullptr;
+ }
+
+ virtual int n_inputs() const override { return 2; }
+ virtual int n_outputs() const override { return 1 + with_bias(); }
+
+protected:
+ memory_desc_t src_md_;
+ memory_desc_t diff_weights_md_;
+ memory_desc_t diff_bias_md_;
+ memory_desc_t diff_dst_md_;
+};
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/eltwise.cpp b/thirdparty/oidn/mkl-dnn/src/common/eltwise.cpp
new file mode 100644
index 0000000000..f1708fca52
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/eltwise.cpp
@@ -0,0 +1,84 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::alg_kind;
+using namespace mkldnn::impl::types;
+
+namespace {
+status_t eltwise_desc_init(eltwise_desc_t *eltwise_desc, prop_kind_t prop_kind,
+ alg_kind_t alg_kind, const memory_desc_t *data_desc,
+ const memory_desc_t *diff_data_desc, float alpha, float beta) {
+ bool args_ok = true
+ && !any_null(eltwise_desc, data_desc)
+ && one_of(prop_kind, forward_training, forward_inference,
+ backward_data)
+ && one_of(alg_kind, eltwise_relu, eltwise_tanh, eltwise_elu,
+ eltwise_square, eltwise_abs, eltwise_sqrt, eltwise_linear,
+ eltwise_bounded_relu, eltwise_soft_relu, eltwise_logistic)
+ && IMPLICATION(prop_kind == backward_data, diff_data_desc != nullptr);
+ if (!args_ok) return invalid_arguments;
+
+ auto ed = eltwise_desc_t();
+ ed.primitive_kind = primitive_kind::eltwise;
+ ed.prop_kind = prop_kind;
+ ed.alg_kind = alg_kind;
+
+ ed.data_desc = *data_desc;
+ ed.diff_data_desc =
+ (ed.prop_kind == backward_data) ? *diff_data_desc : zero_md();
+
+ ed.alpha = alpha;
+ ed.beta = beta;
+
+ bool consistency = true
+ && IMPLICATION(ed.prop_kind == backward_data,
+ array_cmp(ed.diff_data_desc.dims, ed.data_desc.dims,
+ ed.diff_data_desc.ndims));
+ if (!consistency) return invalid_arguments;
+
+ *eltwise_desc = ed;
+ return success;
+}
+}
+
+status_t mkldnn_eltwise_forward_desc_init(eltwise_desc_t *eltwise_desc,
+ prop_kind_t prop_kind, alg_kind_t alg_kind,
+ const memory_desc_t *data_desc, float alpha, float beta) {
+ if (!one_of(prop_kind, forward_training, forward_inference))
+ return invalid_arguments;
+ return eltwise_desc_init(eltwise_desc, prop_kind, alg_kind, data_desc,
+ nullptr, alpha, beta);
+}
+
+status_t mkldnn_eltwise_backward_desc_init(eltwise_desc_t *eltwise_desc,
+ alg_kind_t alg_kind, const memory_desc_t *diff_data_desc,
+ const memory_desc_t *data_desc, float alpha, float beta) {
+ return eltwise_desc_init(eltwise_desc, backward_data, alg_kind, data_desc,
+ diff_data_desc, alpha, beta);
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/eltwise_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/eltwise_pd.hpp
new file mode 100644
index 0000000000..9fd260fcee
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/eltwise_pd.hpp
@@ -0,0 +1,161 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef ELTWISE_PD_HPP
+#define ELTWISE_PD_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "primitive_desc.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct eltwise_fwd_pd_t;
+
+struct eltwise_pd_t: public primitive_desc_t {
+ static constexpr auto base_pkind = primitive_kind::eltwise;
+
+ eltwise_pd_t(mkldnn::impl::engine_t *engine,
+ const eltwise_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const eltwise_fwd_pd_t *hint_fwd_pd)
+ : primitive_desc_t(engine, attr, base_pkind)
+ , desc_(*adesc)
+ , hint_fwd_pd_(hint_fwd_pd)
+ , data_md_(desc_.data_desc)
+ {}
+
+ const eltwise_desc_t *desc() const { return &desc_; }
+ virtual const op_desc_t *op_desc() const override
+ { return reinterpret_cast<const op_desc_t *>(this->desc()); }
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual status_t query(query_t what, int idx, void *result) const override {
+ switch (what) {
+ case query::eltwise_d:
+ *(const eltwise_desc_t**)result = desc(); break;
+ default: return primitive_desc_t::query(what, idx, result);
+ }
+ return status::success;
+ }
+
+ /* common eltwise aux functions */
+
+ dim_t MB() const { return data_desc().dims[0]; }
+ dim_t C() const { return data_desc().dims[1]; }
+ dim_t D() const { return ndims() >= 5 ? data_desc().dims[ndims() - 3] : 1; }
+ dim_t H() const { return ndims() >= 4 ? data_desc().dims[ndims() - 2] : 1; }
+ dim_t W() const { return ndims() >= 3 ? data_desc().dims[ndims() - 1] : 1; }
+
+ int ndims() const { return data_desc().ndims; }
+
+ bool is_fwd() const {
+ return utils::one_of(desc_.prop_kind, prop_kind::forward_training,
+ prop_kind::forward_inference);
+ }
+
+ bool has_zero_dim_memory() const
+ { return memory_desc_wrapper(desc_.data_desc).has_zero_dim(); }
+
+protected:
+ eltwise_desc_t desc_;
+ const eltwise_fwd_pd_t *hint_fwd_pd_;
+
+ memory_desc_t data_md_;
+
+private:
+ const memory_desc_t &data_desc() const { return desc_.data_desc; }
+};
+
+struct eltwise_fwd_pd_t: public eltwise_pd_t {
+ typedef eltwise_fwd_pd_t base_class;
+ typedef eltwise_fwd_pd_t hint_class;
+
+ eltwise_fwd_pd_t(mkldnn::impl::engine_t *engine,
+ const eltwise_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const eltwise_fwd_pd_t *hint_fwd_pd)
+ : eltwise_pd_t(engine, adesc, attr, hint_fwd_pd)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (arg == MKLDNN_ARG_SRC)
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DST)
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &data_md_ : nullptr; }
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 ? &data_md_ : nullptr; }
+
+ virtual int n_inputs() const override { return 1; }
+ virtual int n_outputs() const override { return 1; }
+
+ bool is_zero_preserved() const
+ { return math::eltwise_fwd_preserves_zero(desc_.alg_kind); }
+};
+
+struct eltwise_bwd_pd_t: public eltwise_pd_t {
+ typedef eltwise_bwd_pd_t base_class;
+ typedef eltwise_fwd_pd_t hint_class;
+
+ eltwise_bwd_pd_t(engine_t *engine,
+ const eltwise_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const eltwise_fwd_pd_t *hint_fwd_pd)
+ : eltwise_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , diff_data_md_(desc_.diff_data_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_SRC, MKLDNN_ARG_DIFF_DST))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_SRC)
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &data_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 ? &diff_data_md_ : nullptr; }
+ virtual const memory_desc_t *diff_src_md(int index = 0) const override
+ { return index == 0 ? &diff_data_md_ : nullptr; }
+
+ virtual int n_inputs() const override { return 2; }
+ virtual int n_outputs() const override { return 1; }
+
+ bool is_zero_preserved() const { return true; }
+
+protected:
+ memory_desc_t diff_data_md_;
+};
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/engine.cpp b/thirdparty/oidn/mkl-dnn/src/common/engine.cpp
new file mode 100644
index 0000000000..3b3e25456d
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/engine.cpp
@@ -0,0 +1,75 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn.h"
+#include "engine.hpp"
+#include "nstl.hpp"
+
+#include "c_types_map.hpp"
+#include "../cpu/cpu_engine.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+engine_factory_t *engine_factories[] = {
+ &cpu::engine_factory,
+ nullptr,
+};
+
+static inline engine_factory_t *get_engine_factory(engine_kind_t kind) {
+ for (engine_factory_t **ef = engine_factories; *ef; ef++)
+ if ((*ef)->kind() == kind)
+ return *ef;
+ return nullptr;
+}
+
+}
+}
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::status;
+
+size_t mkldnn_engine_get_count(engine_kind_t kind) {
+ engine_factory_t *ef = get_engine_factory(kind);
+ return ef != nullptr ? ef->count() : 0;
+}
+
+status_t mkldnn_engine_create(engine_t **engine,
+ engine_kind_t kind, size_t index) {
+ if (engine == nullptr)
+ return invalid_arguments;
+
+ engine_factory_t *ef = get_engine_factory(kind);
+ if (ef == nullptr || index >= ef->count())
+ return invalid_arguments;
+
+ return ef->engine_create(engine, index);
+}
+
+status_t mkldnn_engine_get_kind(engine_t *engine, engine_kind_t *kind) {
+ if (engine == nullptr)
+ return invalid_arguments;
+ *kind = engine->kind();
+ return success;
+}
+
+status_t mkldnn_engine_destroy(engine_t *engine) {
+ /* TODO: engine->dec_ref_count(); */
+ delete engine;
+ return success;
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/engine.hpp b/thirdparty/oidn/mkl-dnn/src/common/engine.hpp
new file mode 100644
index 0000000000..8ac8a29de5
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/engine.hpp
@@ -0,0 +1,119 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef ENGINE_HPP
+#define ENGINE_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "primitive.hpp"
+#include "utils.hpp"
+
+/** \brief An abstraction of an execution unit with shared resources
+ *
+ * Responsibilities:
+ * - Provide engine specific memory allocation
+ * - Provide engine specific primitive_desc_t creators
+ */
+struct mkldnn_engine: public mkldnn::impl::c_compatible {
+ mkldnn_engine(mkldnn::impl::engine_kind_t kind)
+ : kind_(kind)
+ {}
+ virtual ~mkldnn_engine() {}
+
+ /** get kind of the current engine */
+ virtual mkldnn::impl::engine_kind_t kind() const { return kind_; }
+
+ /** allocate memory */
+ virtual mkldnn::impl::status_t memory_create(
+ mkldnn::impl::memory_t **memory,
+ const mkldnn::impl::memory_desc_t *md,
+ void *handle) = 0;
+
+ /** implementation section (typedefs) */
+
+ // TODO: remove engine?
+ typedef mkldnn::impl::status_t (*reorder_primitive_desc_create_f)(
+ mkldnn::impl::reorder_pd_t **reorder_pd,
+ mkldnn::impl::engine_t *engine,
+ const mkldnn::impl::primitive_attr_t *attr,
+ mkldnn::impl::engine_t *src_engine,
+ const mkldnn::impl::memory_desc_t *src_md,
+ mkldnn::impl::engine_t *dst_engine,
+ const mkldnn::impl::memory_desc_t *dst_md);
+
+ typedef mkldnn::impl::status_t (*concat_primitive_desc_create_f)(
+ mkldnn::impl::concat_pd_t **concat_pd,
+ mkldnn::impl::engine_t *engine,
+ const mkldnn::impl::primitive_attr_t *attr,
+ const mkldnn::impl::memory_desc_t *dst_md,
+ int n, int concat_dim,
+ const mkldnn::impl::memory_desc_t *src_mds);
+
+ typedef mkldnn::impl::status_t (*sum_primitive_desc_create_f)(
+ mkldnn::impl::sum_pd_t **sum_pd,
+ mkldnn::impl::engine_t *engine,
+ const mkldnn::impl::primitive_attr_t *attr,
+ const mkldnn::impl::memory_desc_t *dst_md,
+ int n, const float *scales,
+ const mkldnn::impl::memory_desc_t *src_mds);
+
+ typedef mkldnn::impl::status_t (*primitive_desc_create_f)(
+ mkldnn::impl::primitive_desc_t **, const mkldnn::impl::op_desc_t *,
+ const mkldnn::impl::primitive_attr_t *attr,
+ mkldnn::impl::engine_t *, const mkldnn::impl::primitive_desc_t *);
+
+ /* implementation section */
+
+ /** return the list of reorder implementations. engine guarantees to return
+ * a NULL-terminated list */
+ virtual const reorder_primitive_desc_create_f*
+ get_reorder_implementation_list() const = 0;
+
+ /** return the list of concat implementations. engine guarantees to return
+ * a NULL-terminated list */
+ virtual const concat_primitive_desc_create_f*
+ get_concat_implementation_list() const = 0;
+
+ /** return the list of sum implementations. engine guarantees to return
+ * a NULL-terminated list */
+ virtual const sum_primitive_desc_create_f*
+ get_sum_implementation_list() const = 0;
+
+ /** return the list of implementations. engine guarantees to return a
+ * NULL-terminated list */
+ virtual const primitive_desc_create_f* get_implementation_list() const = 0;
+
+protected:
+ mkldnn::impl::engine_kind_t kind_;
+};
+
+namespace mkldnn {
+namespace impl {
+
+struct engine_factory_t: public c_compatible {
+ virtual size_t count() const = 0;
+ virtual engine_kind_t kind() const = 0;
+ virtual status_t engine_create(engine_t **engine, size_t index) const = 0;
+};
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/inner_product.cpp b/thirdparty/oidn/mkl-dnn/src/common/inner_product.cpp
new file mode 100644
index 0000000000..5a9f58cb1e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/inner_product.cpp
@@ -0,0 +1,106 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::types;
+
+namespace {
+status_t ip_desc_init(inner_product_desc_t *ip_desc, prop_kind_t prop_kind,
+ const memory_desc_t *src_desc, const memory_desc_t *weights_desc,
+ const memory_desc_t *bias_desc, const memory_desc_t *dst_desc) {
+ bool args_ok = !any_null(ip_desc, src_desc, weights_desc, dst_desc);
+ if (!args_ok) return invalid_arguments;
+
+ auto id = inner_product_desc_t();
+ id.primitive_kind = primitive_kind::inner_product;
+ id.prop_kind = prop_kind;
+
+ id.diff_src_desc = id.src_desc = zero_md();
+ id.diff_dst_desc = id.dst_desc = zero_md();
+ id.diff_weights_desc = id.weights_desc = zero_md();
+ id.diff_bias_desc = id.bias_desc = zero_md();
+
+ const bool is_fwd = one_of(prop_kind, forward_training, forward_inference);
+ const bool with_bias =
+ bias_desc && bias_desc->format_kind != format_kind::undef;
+
+ (prop_kind == backward_data ? id.diff_src_desc : id.src_desc) = *src_desc;
+ (is_fwd ? id.dst_desc : id.diff_dst_desc) = *dst_desc;
+ (prop_kind == backward_weights ? id.diff_weights_desc : id.weights_desc) =
+ *weights_desc;
+ if (with_bias)
+ (prop_kind == backward_weights ? id.diff_bias_desc : id.bias_desc) =
+ *bias_desc;
+
+ id.accum_data_type = types::default_accum_data_type(src_desc->data_type,
+ weights_desc->data_type, dst_desc->data_type, prop_kind);
+
+ bool consistency = true
+ && memory_desc_wrapper(weights_desc).nelems()
+ && one_of(src_desc->ndims, 2, 3, 4, 5)
+ && dst_desc->ndims == 2
+ && weights_desc->ndims == src_desc->ndims
+ && (with_bias ? bias_desc->ndims == 1 : true)
+ && (with_bias ? bias_desc->dims[0] == dst_desc->dims[1] : true)
+ && src_desc->dims[0] == dst_desc->dims[0]
+ && array_cmp(&src_desc->dims[1], &weights_desc->dims[1],
+ src_desc->ndims - 1)
+ && dst_desc->dims[1] == weights_desc->dims[0];
+ if (!consistency) return invalid_arguments;
+
+ *ip_desc = id;
+ return success;
+}
+}
+
+status_t mkldnn_inner_product_forward_desc_init(inner_product_desc_t *ip_desc,
+ prop_kind_t prop_kind, const memory_desc_t *src_desc,
+ const memory_desc_t *weights_desc, const memory_desc_t *bias_desc,
+ const memory_desc_t *dst_desc) {
+ if (!one_of(prop_kind, forward_training, forward_inference))
+ return invalid_arguments;
+ return ip_desc_init(ip_desc, prop_kind, src_desc, weights_desc, bias_desc,
+ dst_desc);
+}
+
+status_t mkldnn_inner_product_backward_data_desc_init(
+ inner_product_desc_t *ip_desc, const memory_desc_t *diff_src_desc,
+ const memory_desc_t *weights_desc, const memory_desc_t *diff_dst_desc)
+{
+ return ip_desc_init(ip_desc, backward_data, diff_src_desc, weights_desc,
+ nullptr, diff_dst_desc);
+}
+
+status_t mkldnn_inner_product_backward_weights_desc_init(
+ inner_product_desc_t *ip_desc, const memory_desc_t *src_desc,
+ const memory_desc_t *diff_weights_desc,
+ const memory_desc_t *diff_bias_desc,
+ const memory_desc_t *diff_dst_desc) {
+ return ip_desc_init(ip_desc, backward_weights, src_desc, diff_weights_desc,
+ diff_bias_desc, diff_dst_desc);
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/inner_product_pd.cpp b/thirdparty/oidn/mkl-dnn/src/common/inner_product_pd.cpp
new file mode 100644
index 0000000000..091cf0f5d6
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/inner_product_pd.cpp
@@ -0,0 +1,56 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "utils.hpp"
+
+#include "inner_product_pd.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+using namespace prop_kind;
+
+memory_desc_t *ip_prop_invariant_src_d(inner_product_desc_t *desc) {
+ return desc->prop_kind == backward_data
+ ? &desc->diff_src_desc : &desc->src_desc;
+}
+
+memory_desc_t *ip_prop_invariant_wei_d(inner_product_desc_t *desc) {
+ return desc->prop_kind == backward_weights
+ ? &desc->diff_weights_desc : &desc->weights_desc;
+}
+
+memory_desc_t *ip_prop_invariant_bia_d(inner_product_desc_t *desc) {
+ return desc->prop_kind == backward_weights
+ ? &desc->diff_bias_desc : &desc->bias_desc;
+}
+
+memory_desc_t *ip_prop_invariant_dst_d(inner_product_desc_t *desc) {
+ return utils::one_of(desc->prop_kind, forward_inference, forward_training)
+ ? &desc->dst_desc : &desc->diff_dst_desc;
+}
+
+const memory_desc_t *ip_prop_invariant_src_d(const inner_product_desc_t *desc)
+{ return ip_prop_invariant_src_d(const_cast<inner_product_desc_t *>(desc)); }
+const memory_desc_t *ip_prop_invariant_wei_d(const inner_product_desc_t *desc)
+{ return ip_prop_invariant_wei_d(const_cast<inner_product_desc_t *>(desc)); }
+const memory_desc_t *ip_prop_invariant_bia_d(const inner_product_desc_t *desc)
+{ return ip_prop_invariant_bia_d(const_cast<inner_product_desc_t *>(desc)); }
+const memory_desc_t *ip_prop_invariant_dst_d(const inner_product_desc_t *desc)
+{ return ip_prop_invariant_dst_d(const_cast<inner_product_desc_t *>(desc)); }
+
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/inner_product_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/inner_product_pd.hpp
new file mode 100644
index 0000000000..c426de632c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/inner_product_pd.hpp
@@ -0,0 +1,321 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef INNER_PRODUCT_PD_HPP
+#define INNER_PRODUCT_PD_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "primitive_desc.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+memory_desc_t *ip_prop_invariant_src_d(inner_product_desc_t *desc);
+memory_desc_t *ip_prop_invariant_wei_d(inner_product_desc_t *desc);
+memory_desc_t *ip_prop_invariant_bia_d(inner_product_desc_t *desc);
+memory_desc_t *ip_prop_invariant_dst_d(inner_product_desc_t *desc);
+const memory_desc_t *ip_prop_invariant_src_d(const inner_product_desc_t *desc);
+const memory_desc_t *ip_prop_invariant_wei_d(const inner_product_desc_t *desc);
+const memory_desc_t *ip_prop_invariant_bia_d(const inner_product_desc_t *desc);
+const memory_desc_t *ip_prop_invariant_dst_d(const inner_product_desc_t *desc);
+
+struct inner_product_fwd_pd_t;
+
+struct inner_product_pd_t: public primitive_desc_t {
+ static constexpr auto base_pkind = primitive_kind::inner_product;
+
+ inner_product_pd_t(engine_t *engine,
+ const inner_product_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const inner_product_fwd_pd_t *hint_fwd_pd)
+ : primitive_desc_t(engine, attr, base_pkind)
+ , desc_(*adesc)
+ , hint_fwd_pd_(hint_fwd_pd)
+ {}
+
+ const inner_product_desc_t *desc() const { return &desc_; }
+ virtual const op_desc_t *op_desc() const override
+ { return reinterpret_cast<const op_desc_t *>(this->desc()); }
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual status_t query(query_t what, int idx, void *result) const override {
+ switch (what) {
+ case query::inner_product_d:
+ *(const inner_product_desc_t**)result = desc(); break;
+ default: return primitive_desc_t::query(what, idx, result);
+ }
+ return status::success;
+ }
+
+ /* common inner_product aux functions */
+
+ dim_t MB() const { return ip_prop_invariant_src_d(&desc_)->dims[0]; }
+ dim_t IC() const { return ip_prop_invariant_src_d(&desc_)->dims[1]; }
+ dim_t OC() const { return ip_prop_invariant_dst_d(&desc_)->dims[1]; }
+
+ dim_t ID() const {
+ return ndims() >= 5
+ ? ip_prop_invariant_src_d(&desc_)->dims[ndims() - 3] : 1;
+ }
+ dim_t IH() const {
+ return ndims() >= 4
+ ? ip_prop_invariant_src_d(&desc_)->dims[ndims() - 2] : 1;
+ }
+ dim_t IW() const {
+ return ndims() >= 3
+ ? ip_prop_invariant_src_d(&desc_)->dims[ndims() - 1] : 1;
+ }
+
+ dim_t OD() const {
+ return ndims() >= 5
+ ? ip_prop_invariant_dst_d(&desc_)->dims[ndims() - 3] : 1;
+ }
+ dim_t OH() const {
+ return ndims() >= 4
+ ? ip_prop_invariant_dst_d(&desc_)->dims[ndims() - 2] : 1;
+ }
+ dim_t OW() const {
+ return ndims() >= 3
+ ? ip_prop_invariant_dst_d(&desc_)->dims[ndims() - 1] : 1;
+ }
+
+ dim_t KD() const {
+ return ndims() >= 5
+ ? ip_prop_invariant_wei_d(&desc_)->dims[ndims() - 3] : 1;
+ }
+ dim_t KH() const {
+ return ndims() >= 4
+ ? ip_prop_invariant_wei_d(&desc_)->dims[ndims() - 2] : 1;
+ }
+ dim_t KW() const {
+ return ndims() >= 3
+ ? ip_prop_invariant_wei_d(&desc_)->dims[ndims() - 1] : 1;
+ }
+
+ dim_t IC_total() const {
+ return utils::array_product(&ip_prop_invariant_src_d(&desc_)->dims[1],
+ ndims() - 1);
+ }
+
+ dim_t IC_total_padded() const {
+ auto src_d = desc()->prop_kind == prop_kind::backward_data
+ ? memory_desc_wrapper(diff_src_md())
+ : memory_desc_wrapper(src_md());
+ assert(src_d.is_blocking_desc());
+ if (!src_d.is_blocking_desc()) return -1;
+ return utils::array_product(src_d.padded_dims() + 1, ndims() - 1);
+ }
+
+ int ndims() const { return ip_prop_invariant_src_d(&desc_)->ndims; }
+
+ bool with_bias() const
+ { return !memory_desc_wrapper(*ip_prop_invariant_bia_d(&desc_)).is_zero(); }
+
+ bool has_zero_dim_memory() const {
+ const auto s_d = memory_desc_wrapper(*ip_prop_invariant_src_d(&desc_));
+ const auto d_d = memory_desc_wrapper(*ip_prop_invariant_dst_d(&desc_));
+ return s_d.has_zero_dim() || d_d.has_zero_dim();
+ }
+
+ bool is_fwd() const {
+ return utils::one_of(desc_.prop_kind, prop_kind::forward_training,
+ prop_kind::forward_inference);
+ }
+
+protected:
+ inner_product_desc_t desc_;
+ const inner_product_fwd_pd_t *hint_fwd_pd_;
+
+ status_t template_set_default_params(memory_desc_t &src_md,
+ memory_desc_t &weights_md, memory_desc_t &dst_md,
+ memory_desc_t *bias_md) {
+ using namespace format_tag;
+ if (src_md.format_kind == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(src_md,
+ utils::pick(ndims() - 2, nc, ncw, nchw, ncdhw)));
+ }
+ if (dst_md.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(dst_md, nc));
+ if (weights_md.format_kind == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(weights_md,
+ utils::pick(ndims() - 2, oi, oiw, oihw, oidhw)));
+ }
+ if (bias_md && bias_md->format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(*bias_md, x));
+ return status::success;
+ }
+};
+
+struct inner_product_fwd_pd_t: public inner_product_pd_t {
+ typedef inner_product_fwd_pd_t base_class;
+ typedef inner_product_fwd_pd_t hint_class;
+
+ inner_product_fwd_pd_t(engine_t *engine,
+ const inner_product_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const inner_product_fwd_pd_t *hint_fwd_pd)
+ : inner_product_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , src_md_(desc_.src_desc)
+ , weights_md_(desc_.weights_desc)
+ , bias_md_(desc_.bias_desc)
+ , dst_md_(desc_.dst_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_SRC, MKLDNN_ARG_WEIGHTS))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_BIAS && with_bias())
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DST)
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &src_md_ : nullptr; }
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 ? &dst_md_ : nullptr; }
+ virtual const memory_desc_t *weights_md(int index = 0) const override {
+ if (index == 0) return &weights_md_;
+ if (index == 1 && with_bias()) return &bias_md_;
+ return nullptr;
+ }
+
+ virtual int n_inputs() const override { return 2 + with_bias(); }
+ virtual int n_outputs() const override { return 1; }
+
+protected:
+ memory_desc_t src_md_;
+ memory_desc_t weights_md_;
+ memory_desc_t bias_md_;
+ memory_desc_t dst_md_;
+
+ status_t set_default_params() {
+ return template_set_default_params(src_md_, weights_md_, dst_md_,
+ &bias_md_);
+ }
+};
+
+struct inner_product_bwd_data_pd_t: public inner_product_pd_t {
+ typedef inner_product_bwd_data_pd_t base_class;
+ typedef inner_product_fwd_pd_t hint_class;
+
+ inner_product_bwd_data_pd_t(engine_t *engine,
+ const inner_product_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const inner_product_fwd_pd_t *hint_fwd_pd)
+ : inner_product_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , diff_src_md_(desc_.diff_src_desc)
+ , weights_md_(desc_.weights_desc)
+ , diff_dst_md_(desc_.diff_dst_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_WEIGHTS, MKLDNN_ARG_DIFF_DST))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_SRC)
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *diff_src_md(int index = 0) const override
+ { return index == 0 ? &diff_src_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 ? &diff_dst_md_ : nullptr; }
+ virtual const memory_desc_t *weights_md(int index = 0) const override
+ { return index == 0 ? &weights_md_ : nullptr; }
+
+ virtual int n_inputs() const override { return 2; }
+ virtual int n_outputs() const override { return 1; }
+
+protected:
+ memory_desc_t diff_src_md_;
+ memory_desc_t weights_md_;
+ memory_desc_t diff_dst_md_;
+
+ status_t set_default_params() {
+ return template_set_default_params(diff_src_md_, weights_md_,
+ diff_dst_md_, nullptr);
+ }
+};
+
+struct inner_product_bwd_weights_pd_t: public inner_product_pd_t {
+ typedef inner_product_bwd_weights_pd_t base_class;
+ typedef inner_product_fwd_pd_t hint_class;
+
+ inner_product_bwd_weights_pd_t(engine_t *engine,
+ const inner_product_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const inner_product_fwd_pd_t *hint_fwd_pd)
+ : inner_product_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , src_md_(desc_.src_desc)
+ , diff_weights_md_(desc_.diff_weights_desc)
+ , diff_bias_md_(desc_.diff_bias_desc)
+ , diff_dst_md_(desc_.diff_dst_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_SRC, MKLDNN_ARG_DIFF_DST))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_WEIGHTS)
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_DIFF_BIAS && with_bias())
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &src_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 ? &diff_dst_md_ : nullptr; }
+ virtual const memory_desc_t *diff_weights_md(int index = 0) const override {
+ if (index == 0) return &diff_weights_md_;
+ if (index == 1 && with_bias()) return &diff_bias_md_;
+ return nullptr;
+ }
+
+ virtual int n_inputs() const override { return 2; }
+ virtual int n_outputs() const override { return 1 + with_bias(); }
+
+protected:
+ memory_desc_t src_md_;
+ memory_desc_t diff_weights_md_;
+ memory_desc_t diff_bias_md_;
+ memory_desc_t diff_dst_md_;
+
+ status_t set_default_params() {
+ return template_set_default_params(src_md_, diff_weights_md_,
+ diff_dst_md_, &diff_bias_md_);
+ }
+};
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/lrn.cpp b/thirdparty/oidn/mkl-dnn/src/common/lrn.cpp
new file mode 100644
index 0000000000..fcf18b556f
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/lrn.cpp
@@ -0,0 +1,91 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::alg_kind;
+using namespace mkldnn::impl::types;
+
+namespace {
+status_t lrn_desc_init(lrn_desc_t *lrn_desc,
+ prop_kind_t prop_kind, alg_kind_t alg_kind,
+ const memory_desc_t *data_desc, const memory_desc_t *diff_data_desc,
+ dim_t local_size, float alpha, float beta, float k) {
+ bool args_ok = true
+ && !any_null(lrn_desc, data_desc)
+ && one_of(alg_kind, lrn_within_channel, lrn_across_channels)
+ && one_of(prop_kind, forward_training, forward_inference, backward_data)
+ && IMPLICATION(prop_kind == backward_data, diff_data_desc != nullptr);
+ if (!args_ok) return invalid_arguments;
+
+ auto ld = lrn_desc_t();
+ ld.primitive_kind = primitive_kind::lrn;
+ ld.prop_kind = prop_kind;
+ ld.alg_kind = alg_kind;
+
+ const bool is_fwd = one_of(prop_kind, forward_training, forward_inference);
+
+ ld.data_desc = *data_desc;
+ if (!is_fwd)
+ ld.diff_data_desc = *diff_data_desc;
+ else
+ ld.diff_data_desc = zero_md();
+ ld.local_size = local_size;
+ ld.lrn_alpha = alpha;
+ ld.lrn_beta = beta;
+ ld.lrn_k = k;
+
+ bool consistency = true
+ && ld.data_desc.ndims == 4;
+ if (ld.prop_kind == backward_data)
+ consistency = consistency
+ && ld.diff_data_desc.ndims == 4
+ && array_cmp(ld.diff_data_desc.dims, ld.data_desc.dims, 4);
+ if (!consistency) return invalid_arguments;
+
+ *lrn_desc = ld;
+ return success;
+}
+}
+
+status_t mkldnn_lrn_forward_desc_init(lrn_desc_t *lrn_desc,
+ prop_kind_t prop_kind, alg_kind_t alg_kind,
+ const memory_desc_t *data_desc, dim_t local_size, float alpha,
+ float beta, float k) {
+ if (!one_of(prop_kind, forward_training, forward_inference))
+ return invalid_arguments;
+ return lrn_desc_init(lrn_desc, prop_kind, alg_kind, data_desc, nullptr,
+ local_size, alpha, beta, k);
+}
+
+status_t mkldnn_lrn_backward_desc_init(lrn_desc_t *lrn_desc,
+ alg_kind_t alg_kind, const memory_desc_t *data_desc,
+ const memory_desc_t *diff_data_desc, dim_t local_size, float alpha,
+ float beta, float k) {
+ return lrn_desc_init(lrn_desc, backward_data, alg_kind, data_desc,
+ diff_data_desc, local_size, alpha, beta, k);
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/lrn_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/lrn_pd.hpp
new file mode 100644
index 0000000000..90886e9656
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/lrn_pd.hpp
@@ -0,0 +1,170 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef LRN_PD_HPP
+#define LRN_PD_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "primitive_desc.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct lrn_fwd_pd_t;
+
+struct lrn_pd_t: public primitive_desc_t {
+ static constexpr auto base_pkind = primitive_kind::lrn;
+
+ lrn_pd_t(engine_t *engine,
+ const lrn_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const lrn_fwd_pd_t *hint_fwd_pd)
+ : primitive_desc_t(engine, attr, base_pkind)
+ , desc_(*adesc)
+ , hint_fwd_pd_(hint_fwd_pd)
+ , data_md_(desc_.data_desc)
+ , ws_md_()
+ {}
+
+ const lrn_desc_t *desc() const { return &desc_; }
+ virtual const op_desc_t *op_desc() const override
+ { return reinterpret_cast<const op_desc_t *>(this->desc()); }
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual status_t query(query_t what, int idx, void *result) const override {
+ switch (what) {
+ case query::lrn_d:
+ *(const lrn_desc_t**)result = desc(); break;
+ default: return primitive_desc_t::query(what, idx, result);
+ }
+ return status::success;
+ }
+
+ /* common lrn aux functions */
+
+ dim_t MB() const { return data_desc().dims[0]; }
+ dim_t C() const { return data_desc().dims[1]; }
+ dim_t D() const { return ndims() >= 5 ? data_desc().dims[ndims() - 3] : 1; }
+ dim_t H() const { return ndims() >= 4 ? data_desc().dims[ndims() - 2] : 1; }
+ dim_t W() const { return ndims() >= 3 ? data_desc().dims[ndims() - 1] : 1; }
+
+ int ndims() const { return data_desc().ndims; }
+
+ bool has_zero_dim_memory() const
+ { return memory_desc_wrapper(desc_.data_desc).has_zero_dim(); }
+
+ bool is_fwd() const {
+ return utils::one_of(desc_.prop_kind, prop_kind::forward_training,
+ prop_kind::forward_inference);
+ }
+
+protected:
+ lrn_desc_t desc_;
+ const lrn_fwd_pd_t *hint_fwd_pd_;
+
+ memory_desc_t data_md_;
+ memory_desc_t ws_md_;
+
+private:
+ const memory_desc_t &data_desc() const { return desc_.data_desc; }
+};
+
+struct lrn_fwd_pd_t: public lrn_pd_t {
+ typedef lrn_fwd_pd_t base_class;
+ typedef lrn_fwd_pd_t hint_class;
+
+ lrn_fwd_pd_t(engine_t *engine,
+ const lrn_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const lrn_fwd_pd_t *hint_fwd_pd)
+ : lrn_pd_t(engine, adesc, attr, hint_fwd_pd)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (arg == MKLDNN_ARG_SRC)
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DST)
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_WORKSPACE && (workspace_md() != nullptr))
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &data_md_ : nullptr; }
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 ? &data_md_ : nullptr; }
+ virtual const memory_desc_t *workspace_md(int index = 0) const override
+ { return index == 0 && !types::is_zero_md(&ws_md_) ? &ws_md_ : nullptr; }
+
+ virtual int n_inputs() const override { return 1; }
+ virtual int n_outputs() const override
+ { return 1 + (workspace_md() != nullptr); }
+};
+
+struct lrn_bwd_pd_t: public lrn_pd_t {
+ typedef lrn_bwd_pd_t base_class;
+ typedef lrn_fwd_pd_t hint_class;
+
+ lrn_bwd_pd_t(engine_t *engine,
+ const lrn_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const lrn_fwd_pd_t *hint_fwd_pd)
+ : lrn_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , diff_data_md_(desc_.diff_data_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_SRC, MKLDNN_ARG_DIFF_DST))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_SRC)
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_WORKSPACE && (workspace_md() != nullptr))
+ return arg_usage_t::input;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &data_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 ? &diff_data_md_ : nullptr; }
+ virtual const memory_desc_t *diff_src_md(int index = 0) const override
+ { return index == 0 ? &diff_data_md_ : nullptr; }
+ virtual const memory_desc_t *workspace_md(int index = 0) const override
+ { return index == 0 && !types::is_zero_md(&ws_md_) ? &ws_md_ : nullptr; }
+
+ virtual int n_inputs() const override
+ { return 2 + (workspace_md() != nullptr); }
+ virtual int n_outputs() const override { return 1; }
+
+protected:
+ memory_desc_t diff_data_md_;
+};
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/math_utils.hpp b/thirdparty/oidn/mkl-dnn/src/common/math_utils.hpp
new file mode 100644
index 0000000000..3fddc0bd45
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/math_utils.hpp
@@ -0,0 +1,280 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MATH_UTILS_HPP
+#define MATH_UTILS_HPP
+
+#include <stdint.h>
+#include <math.h>
+
+#include "utils.hpp"
+#include "nstl.hpp"
+#include "mkldnn_traits.hpp"
+
+#if defined(MKLDNN_X86_64)
+#include "immintrin.h"
+#endif
+
+namespace mkldnn {
+namespace impl {
+namespace math {
+
+/** rounds @p f to an integer according to the mxcsr register */
+inline int mxcsr_round(float f) {
+#if defined(MKLDNN_X86_64)
+ return _mm_cvtss_si32(_mm_load_ss(&f));
+#else
+ return (int)nearbyintf(f); // optimism
+#endif
+}
+
+template <typename data_t, typename acc_t>
+inline typename utils::enable_if<!nstl::is_integral<data_t>::value,
+ typename utils::remove_reference<data_t>::type>::type
+saturate(const acc_t &x) {
+ return (typename utils::remove_reference<data_t>::type)x;
+}
+
+template <typename data_t, typename acc_t>
+inline typename utils::enable_if<nstl::is_integral<data_t>::value,
+ typename utils::remove_reference<data_t>::type>::type
+saturate(const acc_t &x) {
+ acc_t v = x;
+ if (v < (acc_t)nstl::numeric_limits<data_t>::lowest())
+ v = (acc_t)nstl::numeric_limits<data_t>::lowest();
+ if (v > (acc_t)nstl::numeric_limits<data_t>::max())
+ v = (acc_t)nstl::numeric_limits<data_t>::max();
+ return (typename utils::remove_reference<data_t>::type)v;
+}
+
+template <typename data_t>
+double saturate(const double &x) {
+ double v = x;
+ if (v < (double)nstl::numeric_limits<data_t>::lowest())
+ v = (double)nstl::numeric_limits<data_t>::lowest();
+ if (v > (double)nstl::numeric_limits<data_t>::max())
+ v = (double)nstl::numeric_limits<data_t>::max();
+ return v;
+}
+
+template <> inline int8_t saturate<int8_t, uint8_t>(const uint8_t &x) {
+ return x <= 127u ? x : 127;
+}
+
+template <> inline uint8_t saturate<uint8_t, int8_t>(const int8_t &x) {
+ return x >= 0 ? x : 0;
+}
+
+template <typename out_t>
+typename utils::enable_if<nstl::is_integral<out_t>::value, out_t>::type
+out_round(float v) { return (out_t)mxcsr_round(v); }
+
+template <typename out_t>
+typename utils::enable_if<nstl::is_integral<out_t>::value, out_t>::type
+out_round(double v) { return (out_t)mxcsr_round((float)v); }
+
+template <typename out_t>
+typename utils::enable_if<!nstl::is_integral<out_t>::value, out_t>::type
+out_round(float v) { return v; }
+
+inline int gcd(int a, int b) {
+ a = impl::nstl::abs(a);
+ b = impl::nstl::abs(b);
+ if (a < b) { int x = a; a = b; b = x; }
+
+ if (b == 0) return a;
+
+ int r;
+ while ((r = a % b) != 0) { a = b; b = r; }
+
+ return b;
+}
+
+template <typename T>
+inline bool is_pow2(const T& v) { return (v & (v - 1)) == 0; }
+
+/** returns floor(log2(v)), aka the position of the leftmost non-0 bit */
+inline int ilog2q(size_t v) {
+ if (v == 0)
+ return -1;
+
+ int p = 0;
+# define CP(pw) do { if (v >= (1ull << pw)) { v >>= pw; p += pw; } } while(0)
+ CP(32); CP(16); CP(8); CP(4); CP(2); CP(1);
+# undef CP
+ return p;
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U one_m_square(T x) {
+ return (U)(1 - x) * (1 + x);
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U x_m_square(T x) {
+ return (U)(1 - x) * x;
+}
+
+/* activation */
+template <typename T, typename A,
+ typename U = typename utils::remove_reference<T>::type>
+inline U relu_fwd(T s, A alpha) {
+ return s > 0 ? s : (U)(s * alpha);
+}
+template <typename T, typename A,
+ typename U = typename utils::remove_reference<T>::type>
+inline U relu_bwd(T dd, T s, A alpha) {
+ return s > 0 ? dd : (U)(dd * alpha);
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U tanh_fwd(T s) {
+ const float e = tanhf((float) s);
+ return (U)e;
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U tanh_bwd(T dd, T s) {
+ const float e = tanh_fwd<float>((float) s);
+ return (U)(dd * (1 - e) * (1 + e));
+}
+
+template <typename T, typename A,
+ typename U = typename utils::remove_reference<T>::type>
+inline U elu_fwd(T s, A alpha) {
+ return s > 0 ? s : (U)(alpha * (::expm1f((float)s)));
+}
+template <typename T, typename A,
+ typename U = typename utils::remove_reference<T>::type>
+ inline U elu_bwd(T dd, T s, A alpha) {
+ return (U)(dd * (s > 0 ? 1 : alpha * ::expf((float)s)));
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U square_fwd(T s) {
+ return s * s;
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U square_bwd(T dd, T s) {
+ return dd * 2 * s;
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U abs_fwd(T s) {
+ return s > 0 ? s : -s;
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U abs_bwd(T dd, T s) {
+ return s > 0 ? dd : s < 0 ? -dd : 0;
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U sqrt_fwd(T s) {
+ return s > 0 ? (U)(::sqrtf((float)(s))) : 0;
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U sqrt_bwd(T dd, T s) {
+ return s > 0
+ ? (U)(dd / (2 * ::sqrtf((float)(s))))
+ : 0;
+}
+
+template <typename T, typename A,
+ typename U = typename utils::remove_reference<T>::type>
+inline U linear_fwd(T s, A alpha, A beta) {
+ return (U)(alpha * s + beta);
+}
+
+template <typename T, typename A,
+ typename U = typename utils::remove_reference<T>::type>
+inline U linear_bwd(T dd, T s, A alpha, A beta) {
+ (void) s;
+ (void) beta;
+ return (U)(dd * alpha);
+}
+
+template <typename T, typename A,
+ typename U = typename utils::remove_reference<T>::type>
+inline U bounded_relu_fwd(T s, A alpha) {
+ s = s > 0 ? s : 0;
+ return s > alpha ? (U)(alpha) : s;
+}
+
+template <typename T, typename A,
+ typename U = typename utils::remove_reference<T>::type>
+inline U bounded_relu_bwd(T dd, T s, A alpha) {
+ return dd * (0 < s && s < alpha ? 1 : 0);
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U soft_relu_fwd(T s) {
+ float max_logf = 8.872284e+01; //::logf(FLT_MAX)
+ return s < max_logf ? (U)(::log1pf(::expf((float)s))) : s;
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U soft_relu_bwd(T dd, T s) {
+ return (U)(dd / (1 + ::expf((float)(-s))));
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U logistic_fwd(T s) {
+ U v = (U)(::expf((float) -s));
+ return 1 / (1 + v);
+}
+
+template <typename T, typename U = typename utils::remove_reference<T>::type>
+inline U logistic_bwd(T dd, T s) {
+ U v = logistic_fwd<T, U>(s);
+ return dd * v * (1 - v);
+}
+
+inline bool eltwise_fwd_preserves_zero(alg_kind_t alg, bool jit_impl = false) {
+ using namespace alg_kind;
+ using namespace utils;
+ const bool preserves_zero = true
+ && !one_of(alg, eltwise_linear, eltwise_soft_relu, eltwise_logistic)
+ && IMPLICATION(jit_impl, !one_of(alg, eltwise_elu, eltwise_tanh));
+ return preserves_zero;
+}
+
+inline float get_bias(const char *bias, size_t offset, data_type_t data_type)
+{
+ if (!bias)
+ return 0.0f;
+
+#define CASE(dt) \
+ case dt: return (float)((const prec_traits<dt>::type *)bias)[offset]
+
+ switch (data_type) {
+ CASE(data_type::s8);
+ CASE(data_type::u8);
+ CASE(data_type::s32);
+ CASE(data_type::f32);
+ default: assert(!"unimplemented");
+ }
+ return 0; // never happens (should probably be a NaN)
+#undef CASE
+}
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/memory.cpp b/thirdparty/oidn/mkl-dnn/src/common/memory.cpp
new file mode 100644
index 0000000000..cea849c96e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/memory.cpp
@@ -0,0 +1,238 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "engine.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::data_type;
+
+namespace {
+bool memory_desc_sanity_check(int ndims,const dims_t dims,
+ data_type_t data_type, format_kind_t format_kind) {
+ if (ndims == 0) return true;
+
+ bool ok = true
+ && dims != nullptr
+ && 0 < ndims && ndims <= MKLDNN_MAX_NDIMS
+ && one_of(data_type, f32, s32, s8, u8)
+ && format_kind != format_kind::undef;
+ if (!ok) return false;
+ for (int d = 0; d < ndims; ++d)
+ if (dims[d] < 0) return false;
+
+ return true;
+}
+
+bool memory_desc_sanity_check(const memory_desc_t *md) {
+ if (md == nullptr) return false;
+ return memory_desc_sanity_check(md->ndims, md->dims, md->data_type,
+ format_kind::any);
+}
+}
+
+status_t mkldnn_memory_desc_init_by_tag(memory_desc_t *memory_desc, int ndims,
+ const dims_t dims, data_type_t data_type, format_tag_t tag) {
+ if (any_null(memory_desc)) return invalid_arguments;
+ if (ndims == 0 || tag == format_tag::undef) {
+ *memory_desc = types::zero_md();
+ return success;
+ }
+
+ format_kind_t format_kind = types::format_tag_to_kind(tag);
+
+ /* memory_desc != 0 */
+ bool args_ok = !any_null(memory_desc)
+ && memory_desc_sanity_check(ndims, dims, data_type, format_kind);
+ if (!args_ok) return invalid_arguments;
+
+ auto md = memory_desc_t();
+ md.ndims = ndims;
+ array_copy(md.dims, dims, ndims);
+ md.data_type = data_type;
+ array_copy(md.padded_dims, dims, ndims);
+ md.format_kind = format_kind;
+
+ status_t status = success;
+ if (tag == format_tag::undef) {
+ status = invalid_arguments;
+ } else if (tag == format_tag::any) {
+ // nop
+ } else if (format_kind == format_kind::blocked) {
+ status = memory_desc_wrapper::compute_blocking(md, tag);
+ } else {
+ assert(!"unreachable");
+ status = invalid_arguments;
+ }
+
+ if (status == success)
+ *memory_desc = md;
+
+ return status;
+}
+
+status_t mkldnn_memory_desc_init_by_strides(memory_desc_t *memory_desc,
+ int ndims, const dims_t dims, data_type_t data_type,
+ const dims_t strides) {
+ if (any_null(memory_desc)) return invalid_arguments;
+ if (ndims == 0) {
+ *memory_desc = types::zero_md();
+ return success;
+ }
+
+ /* memory_desc != 0 */
+ bool args_ok = !any_null(memory_desc)
+ && memory_desc_sanity_check(ndims, dims, data_type, format_kind::any);
+ if (!args_ok) return invalid_arguments;
+
+ auto md = memory_desc_t();
+ md.ndims = ndims;
+ array_copy(md.dims, dims, ndims);
+ md.data_type = data_type;
+ array_copy(md.padded_dims, dims, ndims);
+ md.format_kind = format_kind::blocked;
+
+ dims_t default_strides = {0};
+ if (strides == nullptr) {
+ default_strides[md.ndims - 1] = 1;
+ for (int d = md.ndims - 2; d >= 0; --d)
+ default_strides[d] = default_strides[d + 1] * md.padded_dims[d + 1];
+ strides = default_strides;
+ } else {
+ /* TODO: add sanity check for the provided strides */
+ }
+
+ array_copy(md.format_desc.blocking.strides, strides, md.ndims);
+
+ *memory_desc = md;
+
+ return status::success;
+}
+
+status_t mkldnn_memory_desc_init_submemory(memory_desc_t *md,
+ const memory_desc_t *parent_md, const dims_t dims,
+ const dims_t offsets) {
+ if (any_null(md, parent_md) || !memory_desc_sanity_check(parent_md))
+ return invalid_arguments;
+
+ const memory_desc_wrapper src_d(parent_md);
+
+ for (int d = 0; d < src_d.ndims(); ++d) {
+ if (dims[d] < 0 || offsets[d] < 0
+ || (offsets[d] + dims[d] > src_d.dims()[d]))
+ return invalid_arguments;
+ }
+
+ if (src_d.format_kind() != format_kind::blocked)
+ return unimplemented;
+
+ dims_t blocks;
+ src_d.compute_blocks(blocks);
+
+ memory_desc_t dst_d = *parent_md;
+ auto &dst_d_blk = dst_d.format_desc.blocking;
+
+ /* TODO: put this into memory_desc_wrapper */
+ for (int d = 0; d < src_d.ndims(); ++d) {
+ /* very limited functionality for now */
+ const bool ok = true
+ && offsets[d] % blocks[d] == 0 /* [r1] */
+ && src_d.padded_offsets()[d] == 0
+ && (false
+ || dims[d] % blocks[d] == 0
+ || dims[d] < blocks[d]);
+ if (!ok)
+ return unimplemented;
+
+ const bool is_right_border = offsets[d] + dims[d] == src_d.dims()[d];
+
+ dst_d.dims[d] = dims[d];
+ dst_d.padded_dims[d] = is_right_border
+ ? src_d.padded_dims()[d] - offsets[d] : dst_d.dims[d];
+ dst_d.padded_offsets[d] = src_d.padded_offsets()[d];
+ dst_d.offset0 += /* [r1] */
+ offsets[d] / blocks[d] * dst_d_blk.strides[d];
+ }
+
+ *md = dst_d;
+
+ return success;
+}
+
+int mkldnn_memory_desc_equal(const memory_desc_t *lhs,
+ const memory_desc_t *rhs) {
+ if (lhs == rhs) return 1;
+ if (any_null(lhs, rhs)) return 0;
+ return memory_desc_wrapper(*lhs) == memory_desc_wrapper(*rhs);
+}
+
+size_t mkldnn_memory_desc_get_size(const memory_desc_t *md) {
+ if (md == nullptr) return 0;
+ return memory_desc_wrapper(*md).size();
+}
+
+status_t mkldnn_memory_create(memory_t **memory, const memory_desc_t *md,
+ engine_t *engine, void *handle) {
+ if (any_null(memory, engine)) return invalid_arguments;
+ memory_desc_t z_md = types::zero_md();
+ return engine->memory_create(memory, md ? md : &z_md, handle);
+}
+
+status_t mkldnn_memory_get_memory_desc(const memory_t *memory,
+ const memory_desc_t **md) {
+ if (any_null(memory, md)) return invalid_arguments;
+ *md = memory->md();
+ return success;
+}
+
+status_t mkldnn_memory_get_engine(const memory_t *memory, engine_t **engine) {
+ if (any_null(memory, engine)) return invalid_arguments;
+ *engine = memory->engine();
+ return success;
+}
+
+status_t mkldnn_memory_get_data_handle(const memory_t *memory,
+ void **handle) {
+ if (any_null(handle))
+ return invalid_arguments;
+ if (memory == nullptr) {
+ *handle = nullptr;
+ return success;
+ }
+ return memory->get_data_handle(handle);
+}
+
+status_t mkldnn_memory_set_data_handle(memory_t *memory, void *handle) {
+ if (any_null(memory)) return invalid_arguments;
+ return memory->set_data_handle(handle);
+}
+
+status_t mkldnn_memory_destroy(memory_t *memory) {
+ delete memory;
+ return success;
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/memory.hpp b/thirdparty/oidn/mkl-dnn/src/common/memory.hpp
new file mode 100644
index 0000000000..03dfee01ff
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/memory.hpp
@@ -0,0 +1,63 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MEMORY_HPP
+#define MEMORY_HPP
+
+#include <assert.h>
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+
+struct mkldnn_memory: public mkldnn::impl::c_compatible {
+ mkldnn_memory(mkldnn::impl::engine_t *engine,
+ const mkldnn::impl::memory_desc_t *md)
+ : engine_(engine), md_(*md) {}
+ virtual ~mkldnn_memory() {}
+
+ /** allocates/initializes memory */
+ virtual mkldnn::impl::status_t init() = 0;
+
+ /** returns memory's engine */
+ mkldnn::impl::engine_t *engine() const { return engine_; }
+ /** returns memory's description */
+ const mkldnn::impl::memory_desc_t *md() const { return &md_; }
+
+ /** returns data handle */
+ virtual mkldnn::impl::status_t get_data_handle(void **handle) const = 0;
+
+ /** sets data handle */
+ virtual mkldnn::impl::status_t set_data_handle(void *handle) = 0;
+
+ /** zeros padding */
+ virtual mkldnn::impl::status_t zero_pad() const
+ { return mkldnn::impl::status::success; }
+
+protected:
+ mkldnn::impl::engine_t *engine_;
+ const mkldnn::impl::memory_desc_t md_;
+
+private:
+ mkldnn_memory() = delete;
+ mkldnn_memory(const mkldnn_memory &) = delete;
+ mkldnn_memory(mkldnn_memory &&) = delete;
+ mkldnn_memory &operator=(const mkldnn_memory &) = delete;
+ mkldnn_memory &operator=(mkldnn_memory &&) = delete;
+};
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/memory_desc_wrapper.cpp b/thirdparty/oidn/mkl-dnn/src/common/memory_desc_wrapper.cpp
new file mode 100644
index 0000000000..8a99be33f3
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/memory_desc_wrapper.cpp
@@ -0,0 +1,212 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include <initializer_list>
+
+#include "c_types_map.hpp"
+#include "memory_desc_wrapper.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+status_t fill_blocked(memory_desc_t &md,
+ std::initializer_list<int> perm,
+ std::initializer_list<int> inner_blks,
+ std::initializer_list<int> inner_idxs) {
+ const bool ok = true
+ && perm.size() == (size_t)md.ndims
+ && inner_blks.size() == inner_idxs.size();
+ if (!ok) return status::invalid_arguments;
+
+ md.offset0 = 0;
+
+ blocking_desc_t &blk = md.format_desc.blocking;
+
+ dim_t block_size = 1;
+ dims_t blocks = {0};
+ utils::array_set(blocks, 1, md.ndims);
+
+ blk.inner_nblks = (int)inner_blks.size();
+
+ int iblk = 0;
+ for (const auto &b: inner_idxs)
+ blk.inner_idxs[iblk++] = b;
+
+ iblk = 0;
+ for (const auto &b: inner_blks) {
+ int dim = blk.inner_idxs[iblk];
+ block_size *= b;
+ blocks[dim] *= b;
+ blk.inner_blks[iblk++] = b;
+ }
+
+ utils::array_set(md.padded_offsets, 0, md.ndims);
+ for (int d = 0; d < md.ndims; ++d)
+ md.padded_dims[d] = utils::rnd_up(md.dims[d], blocks[d]);
+
+ dim_t stride = block_size;
+ // if only we use C++14, the initializer_list would have rbegin()/rend()...
+ for (int d = 0; d < md.ndims; ++d)
+ stride *= md.padded_dims[d] == 0 ? 1 : md.padded_dims[d] / blocks[d];
+
+ for (const auto &d: perm) {
+ if (md.padded_dims[d] == 0) {
+ blk.strides[d] = 1;
+ continue;
+ }
+ stride /= md.padded_dims[d] / blocks[d];
+ blk.strides[d] = stride;
+ }
+
+ assert(stride == block_size);
+
+ return status::success;
+}
+
+status_t memory_desc_wrapper::compute_blocking(memory_desc_t &memory_desc,
+ format_tag_t tag)
+{
+ using namespace format_tag;
+
+ if (memory_desc.ndims == 0) return status::invalid_arguments;
+
+# define C(tag, ... /* perm, inner_blks, inner_idxs */) \
+ case tag: return fill_blocked(memory_desc, __VA_ARGS__)
+
+ switch (tag) {
+ C(a, {0}, {}, {});
+ C(ab, {0, 1}, {}, {});
+ C(abc, {0, 1, 2}, {}, {});
+ C(abcd, {0, 1, 2, 3}, {}, {});
+ C(abcde, {0, 1, 2, 3, 4}, {}, {});
+ C(abcdef, {0, 1, 2, 3, 4, 5}, {}, {});
+ C(abdec, {0, 1, 3, 4, 2}, {}, {});
+ C(acb, {0, 2, 1}, {}, {});
+ C(acbde, {0, 2, 1, 3, 4}, {}, {});
+ C(acdb, {0, 2, 3, 1}, {}, {});
+ C(acdeb, {0, 2, 3, 4, 1}, {}, {});
+ C(ba, {1, 0}, {}, {});
+ C(bac, {1, 0, 2}, {}, {});
+ C(bacd, {1, 0, 2, 3}, {}, {});
+ C(bcda, {1, 2, 3, 0}, {}, {});
+ C(cba, {2, 1, 0}, {}, {});
+ C(cdba, {2, 3, 1, 0}, {}, {});
+ C(cdeba, {2, 3, 4, 1, 0}, {}, {});
+ C(decab, {3, 4, 2, 0, 1}, {}, {});
+
+ C(Abc4a, {0, 1, 2}, {4}, {0});
+ C(aBc4b, {0, 1, 2}, {4}, {1});
+ C(ABc4b16a4b, {0, 1, 2}, {4, 16, 4}, {1, 0, 1});
+ C(ABc4b4a, {0, 1, 2}, {4, 4}, {1, 0});
+ C(Abcd4a, {0, 1, 2, 3}, {4}, {0});
+ C(aBcd4b, {0, 1, 2, 3}, {4}, {1});
+ C(ABcd4b4a, {0, 1, 2, 3}, {4, 4}, {1, 0});
+ C(aBCd4c16b4c, {0, 1, 2, 3}, {4, 16, 4}, {2, 1, 2});
+ C(aBCd4c4b, {0, 1, 2, 3, 4}, {4, 4}, {2, 1});
+ C(Abcde4a, {0, 1, 2, 3, 4}, {4}, {0});
+ C(aBcde4b, {0, 1, 2, 3, 4}, {4}, {1});
+ C(ABcde4b4a, {0, 1, 2, 3, 4}, {4, 4}, {1, 0});
+ C(aBCde4c4b, {0, 1, 2, 3, 4}, {4, 4}, {2, 1});
+ C(aBcdef4b, {0, 1, 2, 3, 4, 5}, {4}, {1});
+ C(aBCdef4c4b, {0, 1, 2, 3, 4, 5}, {4, 4}, {2, 1});
+ C(aBdc4b, {0, 1, 3, 2}, {4}, {1});
+ C(aBdec4b, {0, 1, 3, 4, 2}, {4}, {1});
+ C(aBdefc4b, {0, 1, 3, 4, 5, 2}, {4}, {1});
+ C(Acb4a, {0, 2, 1}, {4}, {0});
+ C(Acdb4a, {0, 2, 3, 1}, {4}, {0});
+ C(Acdeb4a, {0, 2, 3, 4, 1}, {4}, {0});
+
+ C(Abc16a, {0, 1, 2}, {16}, {0});
+ C(ABc16a16b, {0, 1, 2}, {16, 16}, {0, 1});
+ C(aBc16b, {0, 1, 2}, {16}, {1});
+ C(ABc16b16a, {0, 1, 2}, {16, 16}, {1, 0});
+ C(ABc8a16b2a, {0, 1, 2}, {8, 16, 2}, {0, 1, 0});
+ C(ABc8a8b, {0, 1, 2}, {8, 8}, {0, 1});
+ C(aBc8b, {0, 1, 2}, {8}, {1});
+ C(ABc8b16a2b, {0, 1, 2}, {8, 16, 2}, {1, 0, 1});
+ C(ABc8b8a, {0, 1, 2}, {8, 8}, {1, 0});
+ C(Abcd16a, {0, 1, 2, 3}, {16}, {0});
+ C(ABcd16a16b, {0, 1, 2, 3}, {16, 16}, {0, 1});
+ C(aBcd16b, {0, 1, 2, 3}, {16}, {1});
+ C(ABcd16b16a, {0, 1, 2, 3}, {16, 16}, {1, 0});
+ C(aBCd16b16c, {0, 1, 2, 3}, {16, 16}, {1, 2});
+ C(aBCd16c16b, {0, 1, 2, 3}, {16, 16}, {2, 1});
+ C(ABcd4b16a4b, {0, 1, 2, 3}, {4, 16, 4}, {1, 0, 1});
+ C(ABcd8a16b2a, {0, 1, 2, 3}, {8, 16, 2}, {0, 1, 0});
+ C(ABcd8a8b, {0, 1, 2, 3}, {8, 8}, {0, 1});
+ C(aBcd8b, {0, 1, 2, 3}, {8}, {1});
+ C(ABcd8b16a2b, {0, 1, 2, 3}, {8, 16, 2}, {1, 0, 1});
+ C(aBCd8b16c2b, {0, 1, 2, 3}, {8, 16, 2}, {1, 2, 1});
+ C(ABcd8b8a, {0, 1, 2, 3}, {8, 8}, {1, 0});
+ C(aBCd8b8c, {0, 1, 2, 3}, {8, 8}, {1, 2});
+ C(aBCd8c16b2c, {0, 1, 2, 3}, {8, 16, 2}, {2, 1, 2});
+ C(aBCd8c8b, {0, 1, 2, 3}, {8, 8}, {2, 1});
+ C(Abcde16a, {0, 1, 2, 3, 4}, {16}, {0});
+ C(ABcde16a16b, {0, 1, 2, 3, 4}, {16, 16}, {0, 1});
+ C(aBcde16b, {0, 1, 2, 3, 4}, {16}, {1});
+ C(ABcde16b16a, {0, 1, 2, 3, 4}, {16, 16}, {1, 0});
+ C(aBCde16b16c, {0, 1, 2, 3, 4}, {16, 16}, {1, 2});
+ C(aBCde16c16b, {0, 1, 2, 3, 4}, {16, 16}, {2, 1});
+ C(aBCde2c8b4c, {0, 1, 2, 3, 4}, {2, 8, 4}, {2, 1, 2});
+ C(aBCde4b4c, {0, 1, 2, 3, 4}, {4, 4}, {1, 2});
+ C(aBCde4c16b4c, {0, 1, 2, 3, 4}, {4, 16, 4}, {2, 1, 2});
+ C(Abcde8a, {0, 1, 2, 3, 4}, {8}, {0});
+ C(ABcde8a8b, {0, 1, 2, 3, 4}, {8, 8}, {0, 1});
+ C(aBcde8b, {0, 1, 2, 3, 4}, {8}, {1});
+ C(ABcde8b16a2b, {0, 1, 2, 3, 4}, {8, 16, 2}, {1, 0, 1});
+ C(aBCde8b16c2b, {0, 1, 2, 3, 4}, {8, 16, 2}, {1, 2, 1});
+ C(ABcde8b8a, {0, 1, 2, 3, 4}, {8, 8}, {1, 0});
+ C(aBCde8b8c, {0, 1, 2, 3, 4}, {8, 8}, {1, 2});
+ C(aBCde8c16b2c, {0, 1, 2, 3, 4}, {8, 16, 2}, {2, 1, 2});
+ C(aBCde8c8b, {0, 1, 2, 3, 4}, {8, 8}, {2, 1});
+ C(aBcdef16b, {0, 1, 2, 3, 4, 5}, {16}, {1});
+ C(aBCdef16b16c, {0, 1, 2, 3, 4, 5}, {16, 16}, {1, 2});
+ C(aBCdef16c16b, {0, 1, 2, 3, 4, 5}, {16, 16}, {2, 1});
+ C(aBCdef8b8c, {0, 1, 2, 3, 4, 5}, {8, 8}, {1, 2});
+ C(aBCdef8c16b2c, {0, 1, 2, 3, 4, 5}, {8, 16, 2}, {2, 1, 2});
+ C(aBCdef8c8b, {0, 1, 2, 3, 4, 5}, {8, 8}, {2, 1});
+ C(aBdc16b, {0, 1, 3, 2}, {16}, {1});
+ C(aBdc8b, {0, 1, 3, 2}, {8}, {1});
+ C(aBdec16b, {0, 1, 3, 4, 2}, {16}, {1});
+ C(aBdec8b, {0, 1, 3, 4, 2}, {8}, {1});
+ C(aBdefc16b, {0, 1, 3, 4, 5, 2}, {16}, {1});
+ C(aBdefc8b, {0, 1, 3, 4, 5, 2}, {8}, {1});
+ C(Acb16a, {0, 2, 1}, {16}, {0});
+ C(Acb8a, {0, 2, 1}, {8}, {0});
+ C(aCBd16b16c, {0, 2, 1, 3}, {16, 16}, {1, 2});
+ C(aCBde16b16c, {0, 2, 1, 3, 4}, {16, 16}, {1, 2});
+ C(Acdb16a, {0, 2, 3, 1}, {16}, {0});
+ C(Acdb8a, {0, 2, 3, 1}, {8}, {0});
+ C(Acdeb16a, {0, 2, 3, 4, 1}, {16}, {0});
+ C(Acdeb8a, {0, 2, 3, 4, 1}, {8}, {0});
+ C(BAc16a16b, {1, 0, 2}, {16, 16}, {0, 1});
+ C(BAcd16a16b, {1, 0, 2, 3}, {16, 16}, {0, 1});
+ default: break;
+ }
+
+#undef C
+
+ return status::invalid_arguments;
+}
+
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/memory_desc_wrapper.hpp b/thirdparty/oidn/mkl-dnn/src/common/memory_desc_wrapper.hpp
new file mode 100644
index 0000000000..1758f9078a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/memory_desc_wrapper.hpp
@@ -0,0 +1,400 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MEMORY_DESC_WRAPPER_HPP
+#define MEMORY_DESC_WRAPPER_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "utils.hpp"
+
+#include "type_helpers.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+/** thin wrapper class over \struct memory_desc_t which allows easy
+ * manipulations with underlying C structure, which is taken by reference */
+struct memory_desc_wrapper: public c_compatible {
+ const memory_desc_t *md_;
+
+ /** constructor which takes a reference to a constant underlying C memory
+ * descriptor \param md */
+ memory_desc_wrapper(const memory_desc_t *md): md_(md) {}
+ memory_desc_wrapper(const memory_desc_t &md): memory_desc_wrapper(&md) {}
+
+ /* implementing attributes */
+ int ndims() const { return md_->ndims; }
+ const dims_t &dims() const { return md_->dims; }
+ data_type_t data_type() const { return md_->data_type; }
+
+ const dims_t &padded_dims() const { return md_->padded_dims; }
+ const dims_t &padded_offsets() const { return md_->padded_offsets; }
+ dim_t offset0() const { return md_->offset0; }
+
+ format_kind_t format_kind() const { return md_->format_kind; }
+
+ bool is_blocking_desc() const
+ { return format_kind() == format_kind::blocked; }
+ bool is_wino_desc() const
+ { return format_kind() == format_kind::wino; }
+ bool is_rnn_packed_desc() const
+ { return format_kind() == format_kind::rnn_packed; }
+
+ const blocking_desc_t &blocking_desc() const {
+ assert(is_blocking_desc());
+ return md_->format_desc.blocking;
+ }
+ const wino_desc_t &wino_desc() const {
+ assert(is_wino_desc());
+ return md_->format_desc.wino_desc;
+ }
+ const rnn_packed_desc_t &rnn_packed_desc() const {
+ assert(is_rnn_packed_desc());
+ return md_->format_desc.rnn_packed_desc;
+ }
+
+ const memory_extra_desc_t &extra() const { return md_->extra; }
+
+ /* some useful function */
+
+ /** returns the number of elements including padding if \param with_padding
+ * is true, and the number of data elements otherwise */
+ dim_t nelems(bool with_padding = false) const {
+ if (is_zero()) return 0;
+ return utils::array_product(
+ with_padding ? padded_dims() : dims(), ndims());
+ }
+
+ /** returns true if memory descriptor is zero */
+ bool is_zero() const { return ndims() == 0; }
+
+ /** returns true if memory descriptor contains zero as one of its dim */
+ bool has_zero_dim() const { return nelems() == 0; }
+
+ /** return the size of data type (a shortcut) */
+ size_t data_type_size() const
+ { return types::data_type_size(data_type()); }
+
+ /** return the size of data type of additional buffer */
+ size_t additional_buffer_data_size() const {
+ if (extra().flags & memory_extra_flags::compensation_conv_s8s8)
+ return sizeof(int32_t);
+ return 0;
+ }
+
+ /** return true if memory format has additional buffer */
+ bool is_additional_buffer() const {
+ return (extra().flags & memory_extra_flags::compensation_conv_s8s8);
+ }
+
+ /** returns the size of additional buffer */
+ size_t additional_buffer_size() const {
+ if (extra().flags & memory_extra_flags::compensation_conv_s8s8) {
+ int cmask = extra().compensation_mask;
+ assert(cmask == 1 || cmask == 3);
+ dim_t prod = 1;
+ for (int d = 0; d < ndims(); ++d)
+ if (cmask & (1<<d)) prod *= padded_dims()[d];
+ return prod * additional_buffer_data_size();
+ }
+
+ return 0;
+ }
+
+ /** returns the size required to store described memory
+ * note: if offset0 != 0 returns 0 (need to specify the behavior) */
+ size_t size() const {
+ if (is_zero() || has_zero_dim() || format_kind() == format_kind::any)
+ return 0;
+
+ if (format_kind() == format_kind::wino) {
+ return wino_desc().size;
+ } else if (format_kind() == format_kind::rnn_packed) {
+ return rnn_packed_desc().size;
+ } else {
+ if (offset0() != 0) return 0;
+
+ dims_t blocks = {0};
+ compute_blocks(blocks);
+
+ const auto &bd = blocking_desc();
+
+ size_t max_size = 0;
+ for (int d = 0; d < ndims(); ++d)
+ max_size = nstl::max<size_t>(max_size,
+ padded_dims()[d] / blocks[d] * bd.strides[d]);
+
+ if (max_size == 1 && bd.inner_nblks != 0) {
+ max_size = utils::array_product(bd.inner_blks, bd.inner_nblks);
+ }
+
+ return max_size * data_type_size() + additional_buffer_size();
+ }
+ }
+
+ /** returns true if data is dense in memory */
+ bool is_dense(bool with_padding = false) const {
+ if (utils::one_of(format_kind(), format_kind::undef, format_kind::any))
+ return false;
+ return nelems(with_padding) * data_type_size() == size();
+ }
+
+ /** returns true if memory desc is fully defined */
+ bool is_defined() const { return format_kind() != format_kind::any; }
+
+ /** returns true if the only (potentially) padded dim is \param dim */
+ bool only_padded_dim(int dim) const {
+ for (int d = 0; d < ndims(); ++d)
+ if (d != dim && dims()[d] != padded_dims()[d])
+ return false;
+ return true;
+ }
+
+ /** returns true if memory desc has blocked layout and block dims are 1s */
+ bool is_plain() const {
+ if (!is_blocking_desc()) return false;
+ return blocking_desc().inner_nblks == 0;
+ }
+
+ /** returns overall block sizes */
+ void compute_blocks(dims_t blocks) const {
+ if (!is_blocking_desc()) {
+ utils::array_set(blocks, 0, ndims());
+ return;
+ }
+
+ utils::array_set(blocks, 1, ndims());
+
+ const auto &bd = blocking_desc();
+ for (int iblk = 0; iblk < bd.inner_nblks; ++iblk)
+ blocks[bd.inner_idxs[iblk]] *= bd.inner_blks[iblk];
+ }
+
+ /* comparison section */
+
+ bool operator==(const memory_desc_wrapper &rhs) const
+ { return *this->md_ == *rhs.md_; }
+ bool operator!=(const memory_desc_wrapper &rhs) const
+ { return !operator==(rhs); }
+ bool operator==(const memory_desc_t &rhs) const
+ { return operator==(memory_desc_wrapper(rhs)); }
+ bool operator!=(const memory_desc_t &rhs) const
+ { return !operator==(rhs); }
+
+ /** returns true if data (w/o padding if with_padding == false and w/
+ * padding otherwise) have the same physical structure, i.e. dimensions,
+ * strides, and blocked structure. Depending on with_data_type flag
+ * data_type is taken or not taken into account. dim_start allows to check
+ * similarity for the logical part of data [dim_start .. ndims()].
+ * CAUTION: format kind any and undef are not similar to whatever, hence the
+ * following statement might be true: lhs == rhs && !lhs.similar_to(rhs) */
+ /* TODO: revise */
+ bool similar_to(const memory_desc_wrapper &rhs,
+ bool with_padding = true, bool with_data_type = true,
+ int dim_start = 0) const;
+
+ /** returns true if one memory can be reordered to another */
+ bool consistent_with(const memory_desc_wrapper &rhs) const;
+
+ /** returns true if the memory desc corresponds to the given format tag and
+ * strides.
+ * @sa memory_desc_matches_tag */
+ bool matches_tag(format_tag_t tag, const dims_t strides = nullptr) const {
+ return memory_desc_matches_tag(*md_, tag, strides);
+ }
+
+ /** returns matching tag (or undef if match is not found)
+ * XXX: This is a workaround that eventually should go away! */
+ template <typename... Tags>
+ format_tag_t matches_one_of_tag(Tags ...tags) const {
+ for (const auto tag: {tags...}) {
+ if (memory_desc_matches_tag(*md_, tag))
+ return tag;
+ }
+ return format_tag::undef;
+ }
+
+ /* offset section */
+
+ /** returns physical offset by logical one. logical offset is represented by
+ * an array \param pos. if \param is_pos_padded is true \param pos
+ * represents the position in already padded area */
+ dim_t off_v(const dims_t pos, bool is_pos_padded = false) const {
+ assert(is_blocking_desc());
+ const blocking_desc_t &blk = blocking_desc();
+
+ dims_t pos_copy = {0};
+ for (int d = 0; d < ndims(); ++d)
+ pos_copy[d] = pos[d] + (is_pos_padded ? 0 : padded_offsets()[d]);
+
+ dim_t phys_offset = offset0();
+
+ if (blk.inner_nblks > 0) {
+ dim_t blk_stride = 1;
+ for (int iblk = blk.inner_nblks - 1; iblk >= 0; --iblk) {
+ const int d = blk.inner_idxs[iblk];
+ const dim_t p = pos_copy[d] % blk.inner_blks[iblk];
+
+ phys_offset += p * blk_stride;
+
+ pos_copy[d] /= blk.inner_blks[iblk];
+
+ blk_stride *= blk.inner_blks[iblk];
+ }
+ }
+
+ for (int d = 0; d < ndims(); ++d) {
+ const dim_t p = pos_copy[d];
+ phys_offset += p * blk.strides[d];
+ }
+
+ return phys_offset;
+ }
+
+ /** returns physical offset by logical one. logical offset is represented by
+ * a scalar \param l_offset. if \param is_pos_padded is true, \param
+ * l_offset represents logical offset in already padded area */
+ dim_t off_l(dim_t l_offset, bool is_pos_padded = false) const {
+ assert(is_blocking_desc());
+ dims_t pos;
+ for (int rd = 0; rd < ndims(); ++rd) {
+ const int d = ndims() - 1 - rd;
+ const dim_t cur_dim = is_pos_padded ? padded_dims()[d] : dims()[d];
+ pos[d] = l_offset % cur_dim;
+ l_offset /= cur_dim;
+ }
+ return off_v(pos, is_pos_padded);
+ }
+
+ /** returns physical offset by logical one. logical offset is represented by
+ * a tuple of indices (\param xn, ..., \param x1, \param x0) */
+ template<typename... Args>
+ dim_t off(Args... args) const {
+ assert(sizeof...(args) == ndims());
+ dims_t pos = { args... };
+ return off_v(pos, false);
+ }
+
+ /** returns physical offset by logical one. logical offset is represented by
+ * a tuple of indices (\param xn, ..., \param x1, \param x0) in already
+ * padded area */
+ template<typename... Args>
+ dim_t off_padding(Args... args) const {
+ assert(sizeof...(args) == ndims());
+ dims_t pos = { args... };
+ return off_v(pos, true);
+ }
+
+ /** returns physical offset by logical one. Logical offset is represented by
+ * a tuple of block indices (\param bn, ..., \param b1, \param b0). It is a
+ * user responsibility to adjust the result to get offset within blocks */
+ template<typename ...Args>
+ dim_t blk_off(Args... args) const {
+ return _blk_off<sizeof...(args), Args...>(args...);
+ }
+
+ template<bool skip_first, typename T, typename ...Args>
+ dim_t blk_off(T xn, Args... args) const {
+ return skip_first
+ ? blk_off<Args...>(args...)
+ : blk_off<T, Args...>(xn, args...);
+ }
+
+ /* static functions section */
+ /* TODO: replace with non-static, once md_ becomes non-const ref */
+
+ static status_t compute_blocking(memory_desc_t &memory_desc,
+ format_tag_t tag);
+
+private:
+ /* TODO: put logical_offset in utils */
+ template<typename T>
+ dim_t logical_offset(T x0) const { return x0; }
+
+ template<typename T, typename... Args>
+ dim_t logical_offset(T xn, Args... args) const {
+ const size_t n_args = sizeof...(args);
+ return xn * utils::array_product<n_args>(
+ &dims()[ndims() - n_args]) + logical_offset(args...);
+ }
+
+ template<int ORIG_LEN, typename ...Void>
+ dim_t _blk_off() const { return offset0(); }
+
+ template<int ORIG_LEN, typename T, typename ...Args>
+ dim_t _blk_off(T xc, Args ...args) const {
+ assert(is_blocking_desc());
+ constexpr int dc = ORIG_LEN - sizeof...(args) - 1;
+ return xc * blocking_desc().strides[dc]
+ + _blk_off<ORIG_LEN, Args...>(args...);
+ }
+};
+
+inline bool memory_desc_wrapper::similar_to(const memory_desc_wrapper &rhs,
+ bool with_padding, bool with_data_type, int dim_start) const {
+ using namespace utils;
+
+ if (one_of(format_kind(), format_kind::undef, format_kind::any))
+ return false;
+ if (is_wino_desc() || is_rnn_packed_desc())
+ return false;
+
+ const int ds = dim_start;
+ const auto &blk = blocking_desc();
+ const auto &r_blk = rhs.blocking_desc();
+
+ return ndims() == rhs.ndims()
+ && dim_start <= ndims() /* guard */
+ && format_kind() == rhs.format_kind()
+ && IMPLICATION(with_data_type, data_type() == rhs.data_type())
+ && array_cmp(dims() + ds, rhs.dims() + ds, ndims() - ds)
+ && array_cmp(blk.strides + ds, r_blk.strides + ds, ndims() - ds)
+ && blk.inner_nblks == r_blk.inner_nblks
+ && array_cmp(blk.inner_blks, r_blk.inner_blks, blk.inner_nblks)
+ && array_cmp(blk.inner_idxs, r_blk.inner_idxs, blk.inner_nblks)
+ && IMPLICATION(with_padding, true
+ && array_cmp(padded_dims() + ds, rhs.padded_dims() + ds,
+ ndims() - ds)
+ && array_cmp(padded_offsets() + ds, rhs.padded_offsets() + ds,
+ ndims() - ds));
+}
+
+inline bool memory_desc_wrapper::consistent_with(
+ const memory_desc_wrapper &rhs) const {
+ if (ndims() == rhs.ndims()) {
+ for (int d = 0; d < ndims(); ++d) {
+ if (dims()[d] != rhs.dims()[d]) return false;
+ }
+ return true;
+ } else {
+ /* TODO: revise.
+ * is the following possible?
+ * [1, a, b] <--reorder--> [a, b]
+ * [a, 1, b] <--reorder--> [a, b]
+ * not, at least for now */
+ return false;
+ }
+}
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/memory_tracking.hpp b/thirdparty/oidn/mkl-dnn/src/common/memory_tracking.hpp
new file mode 100644
index 0000000000..ec077b308c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/memory_tracking.hpp
@@ -0,0 +1,295 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MEMORY_TRACKING_HPP
+#define MEMORY_TRACKING_HPP
+
+#include <assert.h>
+#include <unordered_map>
+
+#include "nstl.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace memory_tracking {
+
+/* Memory tracking capabilities
+ *
+ * The main purpose of this header file is to provide uniform way to register
+ * required memory for a scratchpad at a primitive descriptor creation time
+ * and then easily access it having only the base address of the scratchpad.
+ *
+ * Primitives might contain multiple disjoint parts that require temporary
+ * buffers (known as scratchpad) during their execution. A primitive descriptor
+ * should summarize all the needs into one single number -- the buffer size
+ * that would be requested from a user. At execution time, the corresponding
+ * primitive will receive a base pointer to a scratchpad. It then needs to
+ * provide each part of algorithm the corresponding piece of memory. Three main
+ * challenges here are:
+ * 1. Track correct offset (from the base scratchpad address) for each piece
+ * 2. Algorithm might require that different memory pieces to be aligned, so
+ * the scratchpad size is no more just a sum of size of the corresponding
+ * subparts.
+ * 3. While a primitive is responsible for its scratchpad, the implementation
+ * might use some other basic blocks (e.g. cpu_reducer) that also require
+ * scratchpad memory. So there should be a simple way of passing the
+ * information back and force between the main algorithm (a primitive) and
+ * auxiliary stuff that lives completely separately from it (e.g. reducer).
+ *
+ * To address these challenges this header file provides 3 structures:
+ * 1. registry_t -- the class the stores the information about requested
+ * memory. The information includes required size and desired
+ * alignment for each piece. This class is also responsible
+ * for computing the right offset to a given piece using the
+ * base pointer.
+ * This class is basically a ledger with all entries.
+ * Lives in primitive descriptors.
+ *
+ * 2. registrar_t -- the interface to a registry_t to book memory. Used at
+ * primitive descriptor creation time only. Contains a
+ * reference to the corresponding *mutable* registry.
+ * Always modifiable.
+ * Allows chaining (using prefixes).
+ *
+ * 3. grantor_t -- the interface to a registry_t to access memory. Used at
+ * primitive execution time only. Contains a reference to
+ * the corresponding *constant* registry and base pointer.
+ * Always constant.
+ * Allows chaining (using prefixes).
+ *
+ * Both registrar_t and grantor_t allow chaining with extra prefix provided.
+ * The feature is useful when a primitive offload a part of computations to
+ * some other primitives which require their own scratchpad space
+ * (e.g. reducer). Prefixes are used to avoid key collision in cases when
+ * multiple sub-primitive (e.g. multiple reducers) are used.
+ *
+ * A short example below demonstrates how to use aforementioned classes. In it
+ * the main primitive is convolution that uses scratchpad for keeping padded
+ * bias. It also needs a reducer, that needs its own space as well.
+ *
+ * ``` c++
+ * struct reducer_t {
+ * static void init(registrar_t &scratchpad) {
+ * // preserve space for the reduction (one page aligned)
+ * scratchpad.book(key_space, sizeof(float) * 980 * 1024, 4096);
+ * }
+ *
+ * void exec(const grantor_t &scratchpad) {
+ * // get the pointer to preserved space. scratchpad came from
+ * // upper primitive (convolution in this example)
+ * auto space = scratchpad.get<float>(key_reducer_space);
+ *
+ * space[:] += ...;
+ * }
+ * };
+ *
+ * struct conv_t {
+ * struct pd_t {
+ * void init() {
+ * registrar_t scratchpad(scratchpad_registry_);
+ *
+ * // preserve a space for padded bias (using default alignment)
+ * scratchpad.book(key_conv_padded_bias, 128);
+ *
+ * // create a proxy registrar for the reducer All entries made
+ * // by reducer would live in convolution's registry, but would
+ * // have their own `prefix`, so no interference with conv's
+ * // buffers.
+ * registrar_t reducer_scratchpad(scratchpad, prefix_reducer);
+ *
+ * reducer_t::init(reducer_scratchpad);
+ * }
+ *
+ * registry_t scratchpad_registry_;
+ * }
+ *
+ * void exec() {
+ * // get the base pointer to a scratchpad memory from a user
+ * void *scratchpad_ptr = this->input(MKLDNN_MEM_SCRATCHPAD);
+ *
+ * // create a grantor to the scratchpad (and provide the base
+ * // pointer).
+ * grantor_t scratchpad(pd()->scratchpad_registry_, scratchpad_ptr);
+ *
+ * // access the padded_bias (need only key name and the grantor)
+ * auto padded_bias = scratchpad.get<float>(key_conv_padded_bias);
+ *
+ * // to give the `right` grantor to reducer we need to add the
+ * // corresponding prefix, so that reducer would be able to access
+ * // its keys. The call is very similar to the one in pd_t::init
+ * // with only difference in types: grantor_t vs registrar_t.
+ * grantor_t reducer_scratchpad(scratchpad, prefix_reducer);
+ * reducer->exec(reducer_scratchpad);
+ * }
+ * };
+ * ```
+ */
+
+
+/* namespace with common keys and prefixes */
+namespace names {
+enum {
+ key_none = 0,
+ key_bnorm_tmp_mean,
+ key_bnorm_tmp_var,
+ key_bnorm_tmp_diff_ss,
+ key_bnorm_tmp_stats,
+ key_bnorm_reduction,
+ key_concat_iptrs,
+ key_concat_istrides,
+ key_concat_nelems,
+ key_concat_optrs,
+ key_conv_adjusted_scales,
+ key_conv_bia_reduction,
+ key_conv_gemm_col,
+ key_conv_gemm_imtr,
+ key_conv_int_dat_in_acc_dt,
+ key_conv_padded_bias,
+ key_conv_rtus_space,
+ key_conv_tr_diff_dst,
+ key_conv_tr_diff_dst_bctx,
+ key_conv_tr_src,
+ key_conv_tr_src_bctx,
+ key_conv_wei_reduction,
+ key_conv_wei_bia_reduction,
+ key_conv_wei_bia_reduction_bctx,
+ key_iprod_int_dat_in_acc_dt,
+ key_reducer_space,
+ key_reducer_space_bctx,
+ key_reorder_wino_plain,
+ key_reorder_wino_transform_space,
+ key_reorder_rnn_weights_quantization,
+ key_reorder_rnn_weights_reduction,
+ key_rnn_space,
+ key_rnn_ptrs_bia,
+ key_rnn_ptrs_wei_layer,
+ key_rnn_ptrs_wei_iter,
+ key_softmax_reduction,
+ key_wino_U,
+ key_wino_V,
+ key_wino_M,
+ key_barrier,
+};
+
+enum {
+ prefix_none = 0,
+ prefix_reducer_bia,
+ prefix_reducer_wei,
+};
+}
+
+// level 0: 00 00 00 xxx
+// level 1: 00 00 aa xxx
+// level 2: 00 aa bb xxx
+// level 3: aa bb cc xxx
+// max # of levels: 3 + 1 (base_level)
+// here:
+// xxx : [1 .. MAX_KEY) : key
+// aa, bb, cc : [1 .. MAX_PREFIX) : prefixes for levels 1, 2, and 3
+
+using key_t = uint32_t;
+enum { MAX_KEY = (1u << 10), MAX_PREFIX = (1u << 7), };
+
+/// generates global key based on a prefix and a local key
+inline key_t make_key(key_t prefix, key_t key) { return prefix + key; }
+
+/// generates global prefix based on the global parent and the local ones
+inline key_t make_prefix(key_t parent_prefix, key_t prefix)
+{ return MAX_PREFIX * parent_prefix + MAX_KEY * prefix; }
+
+struct registrar_t;
+struct grantor_t;
+
+struct registry_t {
+ void book(const key_t &key, size_t size, size_t alignment) {
+ if (size == 0) return;
+ assert(offset_map_.count(key) == 0);
+
+ size = utils::rnd_up(size, minimal_alignment);
+ alignment = nstl::max<size_t>(alignment, minimal_alignment);
+ offset_map_[key] = entry_t{size_, size, alignment};
+
+ size_ += size + alignment - minimal_alignment;
+ }
+
+ void *get(const key_t &key, void *base_ptr) const {
+ if (base_ptr == nullptr) { assert(size() == 0); return nullptr; }
+ if (offset_map_.count(key) != 1) return nullptr;
+
+ const auto &e = offset_map_.at(key);
+ base_ptr = utils::align_ptr<void>(base_ptr, minimal_alignment);
+ char *ptr = (char *)base_ptr + e.offset;
+ return utils::align_ptr<void>(ptr, e.alignment);
+ }
+
+ size_t size() const
+ { return size_ > 0 ? size_ + minimal_alignment - 1 : 0; }
+
+ registrar_t registrar();
+ grantor_t grantor(void *base_ptr) const;
+
+protected:
+ enum { minimal_alignment = 64 };
+ struct entry_t { size_t offset, size, alignment; };
+
+ std::unordered_map<key_t, entry_t> offset_map_;
+ size_t size_ = 0;
+};
+
+struct registrar_t {
+ enum { default_alignment = 64 };
+
+ registrar_t(registry_t &registry): registry_(registry), prefix_(0) {}
+ registrar_t(registrar_t &parent, const key_t &prefix)
+ : registry_(parent.registry_)
+ , prefix_(make_prefix(parent.prefix_, prefix)) {}
+
+ void book(const key_t &key, size_t size,
+ size_t alignment = default_alignment)
+ { registry_.book(make_key(prefix_, key), size, alignment); }
+
+protected:
+ registry_t &registry_;
+ const key_t prefix_;
+};
+
+struct grantor_t {
+ grantor_t(const registry_t &registry, void *base_ptr)
+ : registry_(registry), prefix_(0), base_ptr_(base_ptr) {}
+ grantor_t(const grantor_t &parent, const key_t &prefix)
+ : registry_(parent.registry_)
+ , prefix_(make_prefix(parent.prefix_, prefix))
+ , base_ptr_(parent.base_ptr_) {}
+
+ template <typename T = void> T *get(const key_t &key) const
+ { return (T *)registry_.get(make_key(prefix_, key), base_ptr_); }
+
+protected:
+ const registry_t &registry_;
+ const key_t prefix_;
+ void *base_ptr_;
+};
+
+inline registrar_t registry_t::registrar() { return registrar_t(*this); }
+inline grantor_t registry_t::grantor(void *base_ptr) const
+{ return grantor_t(*this, base_ptr); }
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/mkldnn_debug.cpp b/thirdparty/oidn/mkl-dnn/src/common/mkldnn_debug.cpp
new file mode 100644
index 0000000000..2ef4a8fddc
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/mkldnn_debug.cpp
@@ -0,0 +1,131 @@
+/*******************************************************************************
+* Copyright 2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <stdio.h>
+#include <cinttypes>
+
+#include "mkldnn_debug.h"
+#include "mkldnn_types.h"
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#define DPRINT(...) do { \
+ int l = snprintf(str + written_len, str_len, __VA_ARGS__); \
+ if (l < 0) return l; \
+ if ((size_t)l >= str_len) return -1; \
+ written_len += l; str_len -= l; \
+} while(0)
+
+int mkldnn_md2fmt_str(char *str, size_t str_len,
+ const mkldnn_memory_desc_t *mdesc) {
+ using namespace mkldnn::impl;
+
+ if (str == nullptr || str_len <= 1u)
+ return -1;
+
+ int written_len = 0;
+
+ if (mdesc == nullptr) {
+ DPRINT("%s::%s::",
+ mkldnn_dt2str(data_type::undef),
+ mkldnn_fmt_kind2str(format_kind::undef));
+ return written_len;
+ }
+
+ memory_desc_wrapper md(mdesc);
+
+ DPRINT("%s:", mkldnn_dt2str(md.data_type()));
+
+ bool padded_dims = false, padded_offsets = false;
+ for (int d = 0; d < md.ndims(); ++d) {
+ if (md.dims()[d] != md.padded_dims()[d]) padded_dims = true;
+ if (md.padded_offsets()[d] != 0) padded_offsets = true;
+ }
+ bool offset0 = md.offset0();
+ DPRINT("%s%s%s:",
+ padded_dims ? "p" : "",
+ padded_offsets ? "o" : "",
+ offset0 ? "0" : "");
+
+ DPRINT("%s:", mkldnn_fmt_kind2str(md.format_kind()));
+
+ if (!md.is_blocking_desc()) {
+ /* TODO: extend */
+ DPRINT("%s:", "");
+ } else {
+ const auto &blk = md.blocking_desc();
+
+ dims_t blocks;
+ md.compute_blocks(blocks);
+
+ char dim_chars[MKLDNN_MAX_NDIMS + 1];
+
+ bool plain = true;
+ for (int d = 0; d < md.ndims(); ++d) {
+ dim_chars[d] = (blocks[d] == 1 ? 'a' : 'A') + (char)d;
+ if (blocks[d] != 1) plain = false;
+ }
+
+ dims_t strides;
+ utils::array_copy(strides, blk.strides, md.ndims());
+ utils::simultaneous_sort(strides, dim_chars, md.ndims(),
+ [](dim_t a, dim_t b) { return b - a; });
+
+ dim_chars[md.ndims()] = '\0';
+ DPRINT("%s", dim_chars);
+
+ if (!plain) {
+ for (int iblk = 0; iblk < blk.inner_nblks; ++iblk) {
+ DPRINT("%d%c", (int)blk.inner_blks[iblk],
+ 'a' + (char)blk.inner_idxs[iblk]);
+ }
+ }
+
+ DPRINT("%s", ":");
+ }
+
+ DPRINT("f%lx", (long)md.extra().flags);
+
+ return written_len;
+}
+
+int mkldnn_md2dim_str(char *str, size_t str_len,
+ const mkldnn_memory_desc_t *mdesc) {
+ using namespace mkldnn::impl;
+
+ if (str == nullptr || str_len <= 1)
+ return -1;
+
+ int written_len = 0;
+
+ if (mdesc == nullptr || mdesc->ndims == 0) {
+ DPRINT("%s", "");
+ return written_len;
+ }
+
+ memory_desc_wrapper md(mdesc);
+
+ for (int d = 0; d < md.ndims() - 1; ++d)
+ DPRINT("%" PRId64 "x", md.dims()[d]);
+ DPRINT("%" PRId64, md.dims()[md.ndims() - 1]);
+
+ return written_len;
+}
+
+#undef DPRINT
diff --git a/thirdparty/oidn/mkl-dnn/src/common/mkldnn_debug_autogenerated.cpp b/thirdparty/oidn/mkl-dnn/src/common/mkldnn_debug_autogenerated.cpp
new file mode 100644
index 0000000000..16a8f7ea5e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/mkldnn_debug_autogenerated.cpp
@@ -0,0 +1,365 @@
+/*******************************************************************************
+* Copyright 2018-2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/* DO NOT EDIT, AUTO-GENERATED */
+
+#include <assert.h>
+
+#include "mkldnn_debug.h"
+#include "mkldnn_types.h"
+
+const char *mkldnn_status2str(mkldnn_status_t v) {
+ if (v == mkldnn_success) return "success";
+ if (v == mkldnn_out_of_memory) return "out_of_memory";
+ if (v == mkldnn_try_again) return "try_again";
+ if (v == mkldnn_invalid_arguments) return "invalid_arguments";
+ if (v == mkldnn_not_ready) return "not_ready";
+ if (v == mkldnn_unimplemented) return "unimplemented";
+ if (v == mkldnn_iterator_ends) return "iterator_ends";
+ if (v == mkldnn_runtime_error) return "runtime_error";
+ if (v == mkldnn_not_required) return "not_required";
+ assert(!"unknown status");
+ return "unknown status";
+}
+
+const char *mkldnn_dt2str(mkldnn_data_type_t v) {
+ if (v == mkldnn_data_type_undef) return "undef";
+ if (v == mkldnn_f32) return "f32";
+ if (v == mkldnn_s32) return "s32";
+ if (v == mkldnn_s8) return "s8";
+ if (v == mkldnn_u8) return "u8";
+ assert(!"unknown dt");
+ return "unknown dt";
+}
+
+const char *mkldnn_fmt_kind2str(mkldnn_format_kind_t v) {
+ if (v == mkldnn_format_kind_undef) return "undef";
+ if (v == mkldnn_format_kind_any) return "any";
+ if (v == mkldnn_blocked) return "blocked";
+ if (v == mkldnn_format_kind_wino) return "wino";
+ if (v == mkldnn_format_kind_rnn_packed) return "rnn_packed";
+ assert(!"unknown fmt_kind");
+ return "unknown fmt_kind";
+}
+
+const char *mkldnn_fmt_tag2str(mkldnn_format_tag_t v) {
+ if (v == mkldnn_format_tag_undef) return "undef";
+ if (v == mkldnn_format_tag_any) return "format_tag_any";
+ if (v == mkldnn_a) return "a";
+ if (v == mkldnn_ab) return "ab";
+ if (v == mkldnn_abc) return "abc";
+ if (v == mkldnn_abcd) return "abcd";
+ if (v == mkldnn_abcde) return "abcde";
+ if (v == mkldnn_abcdef) return "abcdef";
+ if (v == mkldnn_abdec) return "abdec";
+ if (v == mkldnn_acb) return "acb";
+ if (v == mkldnn_acbde) return "acbde";
+ if (v == mkldnn_acdb) return "acdb";
+ if (v == mkldnn_acdeb) return "acdeb";
+ if (v == mkldnn_ba) return "ba";
+ if (v == mkldnn_bac) return "bac";
+ if (v == mkldnn_bacd) return "bacd";
+ if (v == mkldnn_bcda) return "bcda";
+ if (v == mkldnn_cba) return "cba";
+ if (v == mkldnn_cdba) return "cdba";
+ if (v == mkldnn_cdeba) return "cdeba";
+ if (v == mkldnn_decab) return "decab";
+ if (v == mkldnn_Abc16a) return "Abc16a";
+ if (v == mkldnn_ABc16a16b) return "ABc16a16b";
+ if (v == mkldnn_aBc16b) return "aBc16b";
+ if (v == mkldnn_ABc16b16a) return "ABc16b16a";
+ if (v == mkldnn_Abc4a) return "Abc4a";
+ if (v == mkldnn_aBc4b) return "aBc4b";
+ if (v == mkldnn_ABc4b16a4b) return "ABc4b16a4b";
+ if (v == mkldnn_ABc4b4a) return "ABc4b4a";
+ if (v == mkldnn_ABc8a16b2a) return "ABc8a16b2a";
+ if (v == mkldnn_ABc8a8b) return "ABc8a8b";
+ if (v == mkldnn_aBc8b) return "aBc8b";
+ if (v == mkldnn_ABc8b16a2b) return "ABc8b16a2b";
+ if (v == mkldnn_ABc8b8a) return "ABc8b8a";
+ if (v == mkldnn_Abcd16a) return "Abcd16a";
+ if (v == mkldnn_ABcd16a16b) return "ABcd16a16b";
+ if (v == mkldnn_aBcd16b) return "aBcd16b";
+ if (v == mkldnn_ABcd16b16a) return "ABcd16b16a";
+ if (v == mkldnn_aBCd16b16c) return "aBCd16b16c";
+ if (v == mkldnn_aBCd16c16b) return "aBCd16c16b";
+ if (v == mkldnn_Abcd4a) return "Abcd4a";
+ if (v == mkldnn_aBcd4b) return "aBcd4b";
+ if (v == mkldnn_ABcd4b16a4b) return "ABcd4b16a4b";
+ if (v == mkldnn_ABcd4b4a) return "ABcd4b4a";
+ if (v == mkldnn_aBCd4c16b4c) return "aBCd4c16b4c";
+ if (v == mkldnn_aBCd4c4b) return "aBCd4c4b";
+ if (v == mkldnn_ABcd8a16b2a) return "ABcd8a16b2a";
+ if (v == mkldnn_ABcd8a8b) return "ABcd8a8b";
+ if (v == mkldnn_aBcd8b) return "aBcd8b";
+ if (v == mkldnn_ABcd8b16a2b) return "ABcd8b16a2b";
+ if (v == mkldnn_aBCd8b16c2b) return "aBCd8b16c2b";
+ if (v == mkldnn_ABcd8b8a) return "ABcd8b8a";
+ if (v == mkldnn_aBCd8b8c) return "aBCd8b8c";
+ if (v == mkldnn_aBCd8c16b2c) return "aBCd8c16b2c";
+ if (v == mkldnn_aBCd8c8b) return "aBCd8c8b";
+ if (v == mkldnn_Abcde16a) return "Abcde16a";
+ if (v == mkldnn_ABcde16a16b) return "ABcde16a16b";
+ if (v == mkldnn_aBcde16b) return "aBcde16b";
+ if (v == mkldnn_ABcde16b16a) return "ABcde16b16a";
+ if (v == mkldnn_aBCde16b16c) return "aBCde16b16c";
+ if (v == mkldnn_aBCde16c16b) return "aBCde16c16b";
+ if (v == mkldnn_aBCde2c8b4c) return "aBCde2c8b4c";
+ if (v == mkldnn_Abcde4a) return "Abcde4a";
+ if (v == mkldnn_aBcde4b) return "aBcde4b";
+ if (v == mkldnn_ABcde4b4a) return "ABcde4b4a";
+ if (v == mkldnn_aBCde4b4c) return "aBCde4b4c";
+ if (v == mkldnn_aBCde4c16b4c) return "aBCde4c16b4c";
+ if (v == mkldnn_aBCde4c4b) return "aBCde4c4b";
+ if (v == mkldnn_Abcde8a) return "Abcde8a";
+ if (v == mkldnn_ABcde8a8b) return "ABcde8a8b";
+ if (v == mkldnn_ABcde8b16a2b) return "ABcde8b16a2b";
+ if (v == mkldnn_aBCde8b16c2b) return "aBCde8b16c2b";
+ if (v == mkldnn_ABcde8b8a) return "ABcde8b8a";
+ if (v == mkldnn_aBCde8b8c) return "aBCde8b8c";
+ if (v == mkldnn_aBCde8c16b2c) return "aBCde8c16b2c";
+ if (v == mkldnn_aBCde8c8b) return "aBCde8c8b";
+ if (v == mkldnn_aBcdef16b) return "aBcdef16b";
+ if (v == mkldnn_aBCdef16b16c) return "aBCdef16b16c";
+ if (v == mkldnn_aBCdef16c16b) return "aBCdef16c16b";
+ if (v == mkldnn_aBcdef4b) return "aBcdef4b";
+ if (v == mkldnn_aBCdef4c4b) return "aBCdef4c4b";
+ if (v == mkldnn_aBCdef8b8c) return "aBCdef8b8c";
+ if (v == mkldnn_aBCdef8c16b2c) return "aBCdef8c16b2c";
+ if (v == mkldnn_aBCdef8c8b) return "aBCdef8c8b";
+ if (v == mkldnn_aBdc16b) return "aBdc16b";
+ if (v == mkldnn_aBdc4b) return "aBdc4b";
+ if (v == mkldnn_aBdc8b) return "aBdc8b";
+ if (v == mkldnn_aBdec16b) return "aBdec16b";
+ if (v == mkldnn_aBdec4b) return "aBdec4b";
+ if (v == mkldnn_aBdec8b) return "aBdec8b";
+ if (v == mkldnn_aBdefc16b) return "aBdefc16b";
+ if (v == mkldnn_aBdefc4b) return "aBdefc4b";
+ if (v == mkldnn_aBdefc8b) return "aBdefc8b";
+ if (v == mkldnn_Acb16a) return "Acb16a";
+ if (v == mkldnn_Acb4a) return "Acb4a";
+ if (v == mkldnn_Acb8a) return "Acb8a";
+ if (v == mkldnn_aCBd16b16c) return "aCBd16b16c";
+ if (v == mkldnn_aCBde16b16c) return "aCBde16b16c";
+ if (v == mkldnn_Acdb16a) return "Acdb16a";
+ if (v == mkldnn_Acdb4a) return "Acdb4a";
+ if (v == mkldnn_Acdb8a) return "Acdb8a";
+ if (v == mkldnn_Acdeb16a) return "Acdeb16a";
+ if (v == mkldnn_Acdeb4a) return "Acdeb4a";
+ if (v == mkldnn_Acdeb8a) return "Acdeb8a";
+ if (v == mkldnn_BAc16a16b) return "BAc16a16b";
+ if (v == mkldnn_BAcd16a16b) return "BAcd16a16b";
+ if (v == mkldnn_format_tag_last) return "format_tag_last";
+ if (v == mkldnn_x) return "x";
+ if (v == mkldnn_nc) return "nc";
+ if (v == mkldnn_cn) return "cn";
+ if (v == mkldnn_ncw) return "ncw";
+ if (v == mkldnn_nwc) return "nwc";
+ if (v == mkldnn_nchw) return "nchw";
+ if (v == mkldnn_nhwc) return "nhwc";
+ if (v == mkldnn_chwn) return "chwn";
+ if (v == mkldnn_ncdhw) return "ncdhw";
+ if (v == mkldnn_ndhwc) return "ndhwc";
+ if (v == mkldnn_oi) return "oi";
+ if (v == mkldnn_io) return "io";
+ if (v == mkldnn_oiw) return "oiw";
+ if (v == mkldnn_wio) return "wio";
+ if (v == mkldnn_oihw) return "oihw";
+ if (v == mkldnn_hwio) return "hwio";
+ if (v == mkldnn_ihwo) return "ihwo";
+ if (v == mkldnn_iohw) return "iohw";
+ if (v == mkldnn_oidhw) return "oidhw";
+ if (v == mkldnn_dhwio) return "dhwio";
+ if (v == mkldnn_goiw) return "goiw";
+ if (v == mkldnn_goihw) return "goihw";
+ if (v == mkldnn_hwigo) return "hwigo";
+ if (v == mkldnn_giohw) return "giohw";
+ if (v == mkldnn_goidhw) return "goidhw";
+ if (v == mkldnn_tnc) return "tnc";
+ if (v == mkldnn_ntc) return "ntc";
+ if (v == mkldnn_ldsnc) return "ldsnc";
+ if (v == mkldnn_ldigo) return "ldigo";
+ if (v == mkldnn_ldgoi) return "ldgoi";
+ if (v == mkldnn_ldgo) return "ldgo";
+ if (v == mkldnn_nCdhw16c) return "nCdhw16c";
+ if (v == mkldnn_nCdhw4c) return "nCdhw4c";
+ if (v == mkldnn_nCdhw8c) return "nCdhw8c";
+ if (v == mkldnn_nChw16c) return "nChw16c";
+ if (v == mkldnn_nChw4c) return "nChw4c";
+ if (v == mkldnn_nChw8c) return "nChw8c";
+ if (v == mkldnn_nCw16c) return "nCw16c";
+ if (v == mkldnn_nCw4c) return "nCw4c";
+ if (v == mkldnn_nCw8c) return "nCw8c";
+ if (v == mkldnn_IOw16o16i) return "IOw16o16i";
+ if (v == mkldnn_OIw16i16o) return "OIw16i16o";
+ if (v == mkldnn_OIw16o16i) return "OIw16o16i";
+ if (v == mkldnn_Oiw16o) return "Oiw16o";
+ if (v == mkldnn_OIw4i16o4i) return "OIw4i16o4i";
+ if (v == mkldnn_OIw4i4o) return "OIw4i4o";
+ if (v == mkldnn_Oiw4o) return "Oiw4o";
+ if (v == mkldnn_OIw8i16o2i) return "OIw8i16o2i";
+ if (v == mkldnn_OIw8i8o) return "OIw8i8o";
+ if (v == mkldnn_OIw8o16i2o) return "OIw8o16i2o";
+ if (v == mkldnn_OIw8o8i) return "OIw8o8i";
+ if (v == mkldnn_Owi16o) return "Owi16o";
+ if (v == mkldnn_Owi4o) return "Owi4o";
+ if (v == mkldnn_Owi8o) return "Owi8o";
+ if (v == mkldnn_IOhw16o16i) return "IOhw16o16i";
+ if (v == mkldnn_Ohwi16o) return "Ohwi16o";
+ if (v == mkldnn_Ohwi4o) return "Ohwi4o";
+ if (v == mkldnn_Ohwi8o) return "Ohwi8o";
+ if (v == mkldnn_OIhw16i16o) return "OIhw16i16o";
+ if (v == mkldnn_OIhw16o16i) return "OIhw16o16i";
+ if (v == mkldnn_Oihw16o) return "Oihw16o";
+ if (v == mkldnn_OIhw4i16o4i) return "OIhw4i16o4i";
+ if (v == mkldnn_OIhw4i4o) return "OIhw4i4o";
+ if (v == mkldnn_Oihw4o) return "Oihw4o";
+ if (v == mkldnn_OIhw8i16o2i) return "OIhw8i16o2i";
+ if (v == mkldnn_OIhw8i8o) return "OIhw8i8o";
+ if (v == mkldnn_OIhw8o16i2o) return "OIhw8o16i2o";
+ if (v == mkldnn_OIhw8o8i) return "OIhw8o8i";
+ if (v == mkldnn_Odhwi16o) return "Odhwi16o";
+ if (v == mkldnn_Odhwi4o) return "Odhwi4o";
+ if (v == mkldnn_Odhwi8o) return "Odhwi8o";
+ if (v == mkldnn_OIdhw16i16o) return "OIdhw16i16o";
+ if (v == mkldnn_OIdhw16o16i) return "OIdhw16o16i";
+ if (v == mkldnn_Oidhw16o) return "Oidhw16o";
+ if (v == mkldnn_OIdhw4i4o) return "OIdhw4i4o";
+ if (v == mkldnn_Oidhw4o) return "Oidhw4o";
+ if (v == mkldnn_OIdhw8i16o2i) return "OIdhw8i16o2i";
+ if (v == mkldnn_OIdhw8i8o) return "OIdhw8i8o";
+ if (v == mkldnn_OIdhw8o8i) return "OIdhw8o8i";
+ if (v == mkldnn_Goiw16g) return "Goiw16g";
+ if (v == mkldnn_gIOw16o16i) return "gIOw16o16i";
+ if (v == mkldnn_gOIw16i16o) return "gOIw16i16o";
+ if (v == mkldnn_gOIw16o16i) return "gOIw16o16i";
+ if (v == mkldnn_gOiw16o) return "gOiw16o";
+ if (v == mkldnn_gOIw4i16o4i) return "gOIw4i16o4i";
+ if (v == mkldnn_gOIw4i4o) return "gOIw4i4o";
+ if (v == mkldnn_gOiw4o) return "gOiw4o";
+ if (v == mkldnn_gOIw8i16o2i) return "gOIw8i16o2i";
+ if (v == mkldnn_gOIw8i8o) return "gOIw8i8o";
+ if (v == mkldnn_gOIw8o16i2o) return "gOIw8o16i2o";
+ if (v == mkldnn_gOIw8o8i) return "gOIw8o8i";
+ if (v == mkldnn_gOwi16o) return "gOwi16o";
+ if (v == mkldnn_gOwi4o) return "gOwi4o";
+ if (v == mkldnn_gOwi8o) return "gOwi8o";
+ if (v == mkldnn_gIOhw16o16i) return "gIOhw16o16i";
+ if (v == mkldnn_gOhwi16o) return "gOhwi16o";
+ if (v == mkldnn_gOhwi4o) return "gOhwi4o";
+ if (v == mkldnn_gOhwi8o) return "gOhwi8o";
+ if (v == mkldnn_Goihw16g) return "Goihw16g";
+ if (v == mkldnn_gOIhw16i16o) return "gOIhw16i16o";
+ if (v == mkldnn_gOIhw16o16i) return "gOIhw16o16i";
+ if (v == mkldnn_gOihw16o) return "gOihw16o";
+ if (v == mkldnn_gOIhw2i8o4i) return "gOIhw2i8o4i";
+ if (v == mkldnn_gOIhw4i16o4i) return "gOIhw4i16o4i";
+ if (v == mkldnn_gOIhw4i4o) return "gOIhw4i4o";
+ if (v == mkldnn_gOIhw4o4i) return "gOIhw4o4i";
+ if (v == mkldnn_gOihw4o) return "gOihw4o";
+ if (v == mkldnn_Goihw8g) return "Goihw8g";
+ if (v == mkldnn_gOIhw8i16o2i) return "gOIhw8i16o2i";
+ if (v == mkldnn_gOIhw8i8o) return "gOIhw8i8o";
+ if (v == mkldnn_gOIhw8o16i2o) return "gOIhw8o16i2o";
+ if (v == mkldnn_gOIhw8o8i) return "gOIhw8o8i";
+ if (v == mkldnn_gOdhwi16o) return "gOdhwi16o";
+ if (v == mkldnn_gOdhwi4o) return "gOdhwi4o";
+ if (v == mkldnn_gOdhwi8o) return "gOdhwi8o";
+ if (v == mkldnn_gOIdhw16i16o) return "gOIdhw16i16o";
+ if (v == mkldnn_gOIdhw16o16i) return "gOIdhw16o16i";
+ if (v == mkldnn_gOidhw16o) return "gOidhw16o";
+ if (v == mkldnn_gOIdhw4i4o) return "gOIdhw4i4o";
+ if (v == mkldnn_gOidhw4o) return "gOidhw4o";
+ if (v == mkldnn_gOIdhw8i16o2i) return "gOIdhw8i16o2i";
+ if (v == mkldnn_gOIdhw8i8o) return "gOIdhw8i8o";
+ if (v == mkldnn_gOIdhw8o8i) return "gOIdhw8o8i";
+ assert(!"unknown fmt_tag");
+ return "unknown fmt_tag";
+}
+
+const char *mkldnn_prop_kind2str(mkldnn_prop_kind_t v) {
+ if (v == mkldnn_prop_kind_undef) return "undef";
+ if (v == mkldnn_forward_training) return "forward_training";
+ if (v == mkldnn_forward_inference) return "forward_inference";
+ if (v == mkldnn_forward_scoring) return "forward_scoring";
+ if (v == mkldnn_forward) return "forward";
+ if (v == mkldnn_backward) return "backward";
+ if (v == mkldnn_backward_data) return "backward_data";
+ if (v == mkldnn_backward_weights) return "backward_weights";
+ if (v == mkldnn_backward_bias) return "backward_bias";
+ assert(!"unknown prop_kind");
+ return "unknown prop_kind";
+}
+
+const char *mkldnn_prim_kind2str(mkldnn_primitive_kind_t v) {
+ if (v == mkldnn_undefined_primitive) return "undef";
+ if (v == mkldnn_reorder) return "reorder";
+ if (v == mkldnn_shuffle) return "shuffle";
+ if (v == mkldnn_concat) return "concat";
+ if (v == mkldnn_sum) return "sum";
+ if (v == mkldnn_convolution) return "convolution";
+ if (v == mkldnn_deconvolution) return "deconvolution";
+ if (v == mkldnn_eltwise) return "eltwise";
+ if (v == mkldnn_softmax) return "softmax";
+ if (v == mkldnn_pooling) return "pooling";
+ if (v == mkldnn_lrn) return "lrn";
+ if (v == mkldnn_batch_normalization) return "batch_normalization";
+ if (v == mkldnn_inner_product) return "inner_product";
+ if (v == mkldnn_rnn) return "rnn";
+ assert(!"unknown prim_kind");
+ return "unknown prim_kind";
+}
+
+const char *mkldnn_alg_kind2str(mkldnn_alg_kind_t v) {
+ if (v == mkldnn_alg_kind_undef) return "undef";
+ if (v == mkldnn_convolution_direct) return "convolution_direct";
+ if (v == mkldnn_convolution_winograd) return "convolution_winograd";
+ if (v == mkldnn_convolution_auto) return "convolution_auto";
+ if (v == mkldnn_deconvolution_direct) return "deconvolution_direct";
+ if (v == mkldnn_deconvolution_winograd) return "deconvolution_winograd";
+ if (v == mkldnn_eltwise_relu) return "eltwise_relu";
+ if (v == mkldnn_eltwise_tanh) return "eltwise_tanh";
+ if (v == mkldnn_eltwise_elu) return "eltwise_elu";
+ if (v == mkldnn_eltwise_square) return "eltwise_square";
+ if (v == mkldnn_eltwise_abs) return "eltwise_abs";
+ if (v == mkldnn_eltwise_sqrt) return "eltwise_sqrt";
+ if (v == mkldnn_eltwise_linear) return "eltwise_linear";
+ if (v == mkldnn_eltwise_bounded_relu) return "eltwise_bounded_relu";
+ if (v == mkldnn_eltwise_soft_relu) return "eltwise_soft_relu";
+ if (v == mkldnn_eltwise_logistic) return "eltwise_logistic";
+ if (v == mkldnn_pooling_max) return "pooling_max";
+ if (v == mkldnn_pooling_avg_include_padding) return "pooling_avg_include_padding";
+ if (v == mkldnn_pooling_avg_exclude_padding) return "pooling_avg_exclude_padding";
+ if (v == mkldnn_pooling_avg) return "pooling_avg";
+ if (v == mkldnn_lrn_across_channels) return "lrn_across_channels";
+ if (v == mkldnn_lrn_within_channel) return "lrn_within_channel";
+ if (v == mkldnn_vanilla_rnn) return "vanilla_rnn";
+ if (v == mkldnn_vanilla_lstm) return "vanilla_lstm";
+ if (v == mkldnn_vanilla_gru) return "vanilla_gru";
+ if (v == mkldnn_gru_linear_before_reset) return "gru_linear_before_reset";
+ assert(!"unknown alg_kind");
+ return "unknown alg_kind";
+}
+
+const char *mkldnn_rnn_direction2str(mkldnn_rnn_direction_t v) {
+ if (v == mkldnn_unidirectional_left2right) return "unidirectional_left2right";
+ if (v == mkldnn_unidirectional_right2left) return "unidirectional_right2left";
+ if (v == mkldnn_bidirectional_concat) return "bidirectional_concat";
+ if (v == mkldnn_bidirectional_sum) return "bidirectional_sum";
+ if (v == mkldnn_unidirectional) return "unidirectional";
+ assert(!"unknown rnn_direction");
+ return "unknown rnn_direction";
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/mkldnn_thread.hpp b/thirdparty/oidn/mkl-dnn/src/common/mkldnn_thread.hpp
new file mode 100644
index 0000000000..7e5789e2c3
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/mkldnn_thread.hpp
@@ -0,0 +1,115 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MKLDNN_THREAD_HPP
+#define MKLDNN_THREAD_HPP
+
+#include "utils.hpp"
+#include "z_magic.hpp"
+
+#define MKLDNN_THR_SEQ 0
+#define MKLDNN_THR_OMP 1
+#define MKLDNN_THR_TBB 2
+
+/* Ideally this condition below should never happen (if the library is built
+ * using regular cmake). For the 3rd-party projects that build the library
+ * from the sources on their own try to guess the right threading... */
+#if !defined(MKLDNN_THR)
+# define MKLDNN_THR MKLDNN_THR_TBB
+#endif
+
+#if MKLDNN_THR == MKLDNN_THR_SEQ
+#define MKLDNN_THR_SYNC 1
+inline int mkldnn_get_max_threads() { return 1; }
+inline int mkldnn_get_num_threads() { return 1; }
+inline int mkldnn_get_thread_num() { return 0; }
+inline int mkldnn_in_parallel() { return 0; }
+inline void mkldnn_thr_barrier() {}
+
+#define PRAGMA_OMP(...)
+
+#elif MKLDNN_THR == MKLDNN_THR_OMP
+#include <omp.h>
+#define MKLDNN_THR_SYNC 1
+
+inline int mkldnn_get_max_threads() { return omp_get_max_threads(); }
+inline int mkldnn_get_num_threads() { return omp_get_num_threads(); }
+inline int mkldnn_get_thread_num() { return omp_get_thread_num(); }
+inline int mkldnn_in_parallel() { return omp_in_parallel(); }
+inline void mkldnn_thr_barrier() {
+# pragma omp barrier
+}
+
+#define PRAGMA_OMP(...) PRAGMA_MACRO(CHAIN2(omp, __VA_ARGS__))
+
+#elif MKLDNN_THR == MKLDNN_THR_TBB
+#include "tbb/task_arena.h"
+#include "tbb/parallel_for.h"
+#define MKLDNN_THR_SYNC 0
+
+inline int mkldnn_get_max_threads()
+{ return tbb::this_task_arena::max_concurrency(); }
+inline int mkldnn_get_num_threads() { return mkldnn_get_max_threads(); }
+inline int mkldnn_get_thread_num()
+{ return tbb::this_task_arena::current_thread_index(); }
+inline int mkldnn_in_parallel() { return 0; }
+inline void mkldnn_thr_barrier() { assert(!"no barrier in TBB"); }
+
+#define PRAGMA_OMP(...)
+
+#endif
+
+/* MSVC still supports omp 2.0 only */
+#if defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER)
+# define collapse(x)
+# define PRAGMA_OMP_SIMD(...)
+#else
+# define PRAGMA_OMP_SIMD(...) PRAGMA_MACRO(CHAIN2(omp, simd __VA_ARGS__))
+#endif // defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+
+namespace mkldnn {
+namespace impl {
+
+inline bool mkldnn_thr_syncable() { return MKLDNN_THR_SYNC == 1; }
+
+template <typename T, typename U>
+inline void balance211(T n, U team, U tid, T &n_start, T &n_end) {
+ T n_min = 1;
+ T &n_my = n_end;
+ if (team <= 1 || n == 0) {
+ n_start = 0;
+ n_my = n;
+ } else if (n_min == 1) {
+ // team = T1 + T2
+ // n = T1*n1 + T2*n2 (n1 - n2 = 1)
+ T n1 = utils::div_up(n, (T)team);
+ T n2 = n1 - 1;
+ T T1 = n - n2 * (T)team;
+ n_my = (T)tid < T1 ? n1 : n2;
+ n_start = (T)tid <= T1 ? tid * n1 : T1 * n1 + ((T)tid - T1) * n2;
+ }
+
+ n_end += n_start;
+}
+
+} // namespace impl
+} // namespace mkldnn
+
+#include "mkldnn_thread_parallel_nd.hpp"
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/mkldnn_thread_parallel_nd.hpp b/thirdparty/oidn/mkl-dnn/src/common/mkldnn_thread_parallel_nd.hpp
new file mode 100644
index 0000000000..50f9b29622
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/mkldnn_thread_parallel_nd.hpp
@@ -0,0 +1,277 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MKLDNN_THREAD_PARALLEL_ND_HPP
+#define MKLDNN_THREAD_PARALLEL_ND_HPP
+
+/* This header must be included by mkldnn_thread.hpp only */
+
+/* Functions:
+ * - parallel(nthr, f) - executes f in parallel using at most
+ * nthr threads. If nthr equals 0
+ * mkldnn_get_max_threads() threads is
+ * used
+ * - for_nd(ithr, nthr, dims..., f) - multidimensional for loop for already
+ * created threads
+ * - parallel_nd(dims..., f) - creates a parallel section and then
+ * calls for_nd
+ * - parallel_nd_in_omp(dims..., f) - queries current nthr and ithr and then
+ * calls for_nd (mostly for convenience)
+ */
+
+namespace mkldnn {
+namespace impl {
+
+/* general parallelization */
+template <typename F>
+void parallel(int nthr, F f) {
+ if (nthr == 0) nthr = mkldnn_get_max_threads();
+#if MKLDNN_THR == MKLDNN_THR_SEQ
+ assert(nthr == 1);
+ f(0, 1);
+#elif MKLDNN_THR == MKLDNN_THR_OMP
+ if (nthr == 1) { f(0, 1); return; }
+# pragma omp parallel num_threads(nthr)
+ f(mkldnn_get_thread_num(), mkldnn_get_num_threads());
+#elif MKLDNN_THR == MKLDNN_THR_TBB
+ if (nthr == 1) { f(0, 1); return; }
+ tbb::parallel_for(0, nthr, [&](int ithr) { f(ithr, nthr); }, tbb::static_partitioner());
+#endif
+}
+
+/* for_nd section */
+
+template <typename T0, typename F>
+void for_nd(const int ithr, const int nthr, const T0 &D0, F f) {
+ T0 start{0}, end{0};
+ balance211(D0, nthr, ithr, start, end);
+ for (T0 d0 = start; d0 < end; ++d0) f(d0);
+}
+
+template <typename T0, typename T1, typename F>
+void for_nd(const int ithr, const int nthr, const T0 &D0, const T1 &D1, F f) {
+ const size_t work_amount = (size_t)D0 * D1;
+ if (work_amount == 0) return;
+ size_t start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+
+ T0 d0{0}; T1 d1{0};
+ utils::nd_iterator_init(start, d0, D0, d1, D1);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ f(d0, d1);
+ utils::nd_iterator_step(d0, D0, d1, D1);
+ }
+}
+
+template <typename T0, typename T1, typename T2, typename F>
+void for_nd(const int ithr, const int nthr, const T0 &D0, const T1 &D1,
+ const T2 &D2, F f) {
+ const size_t work_amount = (size_t)D0 * D1 * D2;
+ if (work_amount == 0) return;
+ size_t start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+
+ T0 d0{0}; T1 d1{0}; T2 d2{0};
+ utils::nd_iterator_init(start, d0, D0, d1, D1, d2, D2);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ f(d0, d1, d2);
+ utils::nd_iterator_step(d0, D0, d1, D1, d2, D2);
+ }
+}
+
+template <typename T0, typename T1, typename T2, typename T3, typename F>
+void for_nd(const int ithr, const int nthr, const T0 &D0, const T1 &D1,
+ const T2 &D2, const T3 &D3, F f) {
+ const size_t work_amount = (size_t)D0 * D1 * D2 * D3;
+ if (work_amount == 0) return;
+ size_t start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+
+ T0 d0{0}; T1 d1{0}; T2 d2{0}; T3 d3{0};
+ utils::nd_iterator_init(start, d0, D0, d1, D1, d2, D2, d3, D3);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ f(d0, d1, d2, d3);
+ utils::nd_iterator_step(d0, D0, d1, D1, d2, D2, d3, D3);
+ }
+}
+
+template <typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename F>
+void for_nd(const int ithr, const int nthr, const T0 &D0, const T1 &D1,
+ const T2 &D2, const T3 &D3, const T4 &D4, F f) {
+ const size_t work_amount = (size_t)D0 * D1 * D2 * D3 * D4;
+ if (work_amount == 0) return;
+ size_t start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+
+ T0 d0{0}; T1 d1{0}; T2 d2{0}; T3 d3{0}; T4 d4{0};
+ utils::nd_iterator_init(start, d0, D0, d1, D1, d2, D2, d3, D3, d4, D4);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ f(d0, d1, d2, d3, d4);
+ utils::nd_iterator_step(d0, D0, d1, D1, d2, D2, d3, D3, d4, D4);
+ }
+}
+
+template <typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename F>
+void for_nd(const int ithr, const int nthr, const T0 &D0, const T1 &D1,
+ const T2 &D2, const T3 &D3, const T4 &D4, const T5 &D5, F f) {
+ const size_t work_amount = (size_t)D0 * D1 * D2 * D3 * D4 * D5;
+ if (work_amount == 0) return;
+ size_t start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+
+ T0 d0{0}; T1 d1{0}; T2 d2{0}; T3 d3{0}; T4 d4{0}; T5 d5{0};
+ utils::nd_iterator_init(start, d0, D0, d1, D1, d2, D2, d3, D3, d4, D4,
+ d5, D5);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ f(d0, d1, d2, d3, d4, d5);
+ utils::nd_iterator_step(d0, D0, d1, D1, d2, D2, d3, D3, d4, D4, d5, D5);
+ }
+}
+
+// Skip a lambda function in the parameter pack.
+template <typename T>
+constexpr size_t get_work_amount(const T &v) { return 1; }
+template <typename T, typename ...Args>
+constexpr size_t get_work_amount(const T &v, Args &&...args)
+{ return (size_t)v * get_work_amount(utils::forward<Args>(args)...); }
+
+/* parallel_nd and parallel_nd_in_omp section */
+
+#if MKLDNN_THR != MKLDNN_THR_TBB
+template <typename ...Args>
+void parallel_nd(Args &&...args) {
+#if MKLDNN_THR == MKLDNN_THR_SEQ
+ for_nd(0, 1, utils::forward<Args>(args)...);
+#elif MKLDNN_THR == MKLDNN_THR_OMP
+ const bool do_parallel = get_work_amount(utils::forward<Args>(args)...) > 1;
+# pragma omp parallel if (do_parallel)
+ {
+ const int nthr = !do_parallel ? 1 : mkldnn_get_num_threads();
+ const int ithr = !do_parallel ? 0 : mkldnn_get_thread_num();
+ for_nd(ithr, nthr, utils::forward<Args>(args)...);
+ }
+#endif
+}
+#else // MKLDNN_THR != MKLDNN_THR_TBB
+
+// gcc 4.8 has a bug with passing parameter pack to lambdas.
+// So have to explicitly instantiate all the cases.
+
+template <typename T0, typename F>
+void parallel_nd(const T0 &D0, F f) {
+ const size_t work_amount = (size_t)D0;
+ if (work_amount == 0) return;
+ tbb::parallel_for(tbb::blocked_range<size_t>(0, work_amount), [&](const tbb::blocked_range<size_t>& r) {
+ for (size_t iwork = r.begin(); iwork != r.end(); ++iwork) {
+ f(T0(iwork));
+ }
+ }, tbb::static_partitioner());
+}
+
+template <typename T0, typename T1, typename F>
+void parallel_nd(const T0 &D0, const T1 &D1, F f) {
+ const size_t work_amount = (size_t)D0 * D1;
+ if (work_amount == 0) return;
+ tbb::parallel_for(tbb::blocked_range<size_t>(0, work_amount), [&](const tbb::blocked_range<size_t>& r) {
+ T0 d0{0}; T1 d1{0};
+ utils::nd_iterator_init(r.begin(), d0, D0, d1, D1);
+ for (size_t iwork = r.begin(); iwork != r.end(); ++iwork) {
+ f(d0, d1);
+ utils::nd_iterator_step(d0, D0, d1, D1);
+ }
+ }, tbb::static_partitioner());
+}
+
+template <typename T0, typename T1, typename T2, typename F>
+void parallel_nd(const T0 &D0, const T1 &D1, const T2 &D2, F f) {
+ const size_t work_amount = (size_t)D0 * D1 * D2;
+ if (work_amount == 0) return;
+ tbb::parallel_for(tbb::blocked_range<size_t>(0, work_amount), [&](const tbb::blocked_range<size_t>& r) {
+ T0 d0{0}; T1 d1{0}; T2 d2{0};
+ utils::nd_iterator_init(r.begin(), d0, D0, d1, D1, d2, D2);
+ for (size_t iwork = r.begin(); iwork != r.end(); ++iwork) {
+ f(d0, d1, d2);
+ utils::nd_iterator_step(d0, D0, d1, D1, d2, D2);
+ }
+ }, tbb::static_partitioner());
+}
+
+template <typename T0, typename T1, typename T2, typename T3, typename F>
+void parallel_nd(const T0 &D0, const T1 &D1, const T2 &D2, const T3 &D3, F f) {
+ const size_t work_amount = (size_t)D0 * D1 * D2 * D3;
+ if (work_amount == 0) return;
+ tbb::parallel_for(tbb::blocked_range<size_t>(0, work_amount), [&](const tbb::blocked_range<size_t>& r) {
+ T0 d0{0}; T1 d1{0}; T2 d2{0}; T3 d3{0};
+ utils::nd_iterator_init(r.begin(), d0, D0, d1, D1, d2, D2, d3, D3);
+ for (size_t iwork = r.begin(); iwork != r.end(); ++iwork) {
+ f(d0, d1, d2, d3);
+ utils::nd_iterator_step(d0, D0, d1, D1, d2, D2, d3, D3);
+ }
+ }, tbb::static_partitioner());
+}
+
+template <typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename F>
+void parallel_nd(const T0 &D0, const T1 &D1, const T2 &D2, const T3 &D3,
+ const T4 &D4, F f) {
+ const size_t work_amount = (size_t)D0 * D1 * D2 * D3 * D4;
+ if (work_amount == 0) return;
+ tbb::parallel_for(tbb::blocked_range<size_t>(0, work_amount), [&](const tbb::blocked_range<size_t>& r) {
+ T0 d0{0}; T1 d1{0}; T2 d2{0}; T3 d3{0}; T4 d4{0};
+ utils::nd_iterator_init(r.begin(), d0, D0, d1, D1, d2, D2, d3, D3, d4, D4);
+ for (size_t iwork = r.begin(); iwork != r.end(); ++iwork) {
+ f(d0, d1, d2, d3, d4);
+ utils::nd_iterator_step(d0, D0, d1, D1, d2, D2, d3, D3, d4, D4);
+ }
+ }, tbb::static_partitioner());
+}
+
+template <typename T0, typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename F>
+void parallel_nd(const T0 &D0, const T1 &D1, const T2 &D2, const T3 &D3,
+ const T4 &D4, const T5 &D5, F f) {
+ const size_t work_amount = (size_t)D0 * D1 * D2 * D3 * D4 * D5;
+ if (work_amount == 0) return;
+ tbb::parallel_for(tbb::blocked_range<size_t>(0, work_amount), [&](const tbb::blocked_range<size_t>& r) {
+ T0 d0{0}; T1 d1{0}; T2 d2{0}; T3 d3{0}; T4 d4{0}; T5 d5{0};
+ utils::nd_iterator_init(r.begin(), d0, D0, d1, D1, d2, D2, d3, D3, d4, D4,
+ d5, D5);
+ for (size_t iwork = r.begin(); iwork != r.end(); ++iwork) {
+ f(d0, d1, d2, d3, d4, d5);
+ utils::nd_iterator_step(d0, D0, d1, D1, d2, D2, d3, D3, d4, D4, d5, D5);
+ }
+ }, tbb::static_partitioner());
+}
+#endif
+
+template <typename ...Args>
+void parallel_nd_in_omp(Args &&...args) {
+#if MKLDNN_THR == MKLDNN_THR_SEQ
+ for_nd(0, 1, utils::forward<Args>(args)...);
+#elif MKLDNN_THR == MKLDNN_THR_OMP
+ for_nd(mkldnn_get_thread_num(), mkldnn_get_num_threads(),
+ utils::forward<Args>(args)...);
+#elif MKLDNN_THR == MKLDNN_THR_TBB
+ assert(!"unsupported parallel_nd_in_omp()");
+#endif
+}
+
+} // namespace impl
+} // namespace mkldnn
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/mkldnn_traits.hpp b/thirdparty/oidn/mkl-dnn/src/common/mkldnn_traits.hpp
new file mode 100644
index 0000000000..aa671a0b6e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/mkldnn_traits.hpp
@@ -0,0 +1,77 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef MKLDNN_TRAITS_HPP
+#define MKLDNN_TRAITS_HPP
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "mkldnn.h"
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "utils.hpp"
+#include "z_magic.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+template <data_type_t> struct prec_traits {}; /* ::type -> float */
+template <typename> struct data_traits {}; /* ::data_type -> f32 */
+template <int> struct typesize_traits {}; /* ::data_type_size -> f32 */
+template <primitive_kind_t> struct pkind_traits {}; /* ::desc_type, ::query_d */
+
+template <> struct prec_traits<data_type::f32> { typedef float type; };
+template <> struct prec_traits<data_type::s32> { typedef int32_t type; };
+template <> struct prec_traits<data_type::s8> { typedef int8_t type; };
+template <> struct prec_traits<data_type::u8> { typedef uint8_t type; };
+
+template <> struct data_traits<float>
+{ static constexpr data_type_t data_type = data_type::f32; };
+template <> struct data_traits<int32_t>
+{ static constexpr data_type_t data_type = data_type::s32; };
+template <> struct data_traits<int8_t>
+{ static constexpr data_type_t data_type = data_type::s8; };
+template <> struct data_traits<uint8_t>
+{ static constexpr data_type_t data_type = data_type::u8; };
+
+template <> struct typesize_traits<4> { typedef float type; };
+template <> struct typesize_traits<2> { typedef int16_t type; };
+template <> struct typesize_traits<1> { typedef uint8_t type; };
+
+#define PKIND_TRAITS_INST(op) \
+template <> struct pkind_traits<primitive_kind::op> { \
+ typedef CONCAT2(op, _desc_t) desc_type; \
+ static constexpr query_t query_d = query::CONCAT2(op, _d); \
+}
+PKIND_TRAITS_INST(convolution);
+PKIND_TRAITS_INST(deconvolution);
+PKIND_TRAITS_INST(shuffle);
+PKIND_TRAITS_INST(eltwise);
+PKIND_TRAITS_INST(softmax);
+PKIND_TRAITS_INST(pooling);
+PKIND_TRAITS_INST(lrn);
+PKIND_TRAITS_INST(batch_normalization);
+PKIND_TRAITS_INST(inner_product);
+PKIND_TRAITS_INST(rnn);
+#undef PKIND_TRAITS_INST
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/nstl.hpp b/thirdparty/oidn/mkl-dnn/src/common/nstl.hpp
new file mode 100644
index 0000000000..f89ea999e2
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/nstl.hpp
@@ -0,0 +1,193 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef NSTL_HPP
+#define NSTL_HPP
+
+#include <stdint.h>
+#include <limits.h>
+#include <float.h>
+
+#include <vector>
+#include <map>
+
+#include "z_magic.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+void *malloc(size_t size, int alignment);
+void free(void *p);
+
+struct c_compatible {
+ enum { default_alignment = 64 };
+ static void *operator new(size_t sz) {
+ return malloc(sz, default_alignment);
+ }
+ static void *operator new(size_t sz, void *p) { UNUSED(sz); return p; }
+ static void *operator new[](size_t sz) {
+ return malloc(sz, default_alignment);
+ }
+ static void operator delete(void *p) { free(p); }
+ static void operator delete[](void *p) { free(p); }
+};
+
+namespace nstl {
+
+template<typename T>
+inline const T abs(const T& a) {
+ return a >= 0 ? a : -a;
+}
+
+template<typename T>
+inline const T& max(const T& a, const T& b) {
+ return a > b ? a : b;
+}
+
+template<typename T>
+inline const T& min(const T& a, const T& b) {
+ return a < b ? a : b;
+}
+
+template<typename T> void swap(T& t1, T& t2) {
+ T tmp(t1);
+ t1 = t2;
+ t2 = tmp;
+}
+
+// Rationale: MKL-DNN needs numeric limits implementation that does not
+// generate dependencies on C++ run-time libraries.
+
+template<typename T> struct numeric_limits;
+
+template<> struct numeric_limits<float> {
+ static constexpr float lowest() { return -FLT_MAX; }
+ static constexpr float max() { return FLT_MAX; }
+};
+
+template<> struct numeric_limits<int32_t> {
+ static constexpr int lowest() { return INT32_MIN; }
+ static constexpr int max() { return INT32_MAX; }
+};
+
+template<> struct numeric_limits<int16_t> {
+ static constexpr int16_t lowest() { return INT16_MIN; }
+ static constexpr int16_t max() { return INT16_MAX; }
+};
+
+template<> struct numeric_limits<int8_t> {
+ static constexpr int8_t lowest() { return INT8_MIN; }
+ static constexpr int8_t max() { return INT8_MAX; }
+};
+
+template<> struct numeric_limits<uint8_t> {
+ static constexpr uint8_t lowest() { return 0; }
+ static constexpr uint8_t max() { return UINT8_MAX; }
+};
+
+template<typename T> struct is_integral
+{ static constexpr bool value = false; };
+template<> struct is_integral<int32_t> { static constexpr bool value = true; };
+template<> struct is_integral<int16_t> { static constexpr bool value = true; };
+template<> struct is_integral<int8_t> { static constexpr bool value = true; };
+template<> struct is_integral<uint8_t> { static constexpr bool value = true; };
+
+template <typename T, typename U> struct is_same
+{ static constexpr bool value = false; };
+template <typename T> struct is_same<T, T>
+{ static constexpr bool value = true; };
+
+// Rationale: MKL-DNN needs container implementations that do not generate
+// dependencies on C++ run-time libraries.
+//
+// Implementation philosophy: caller is responsible to check if the operation
+// is valid. The only functions that have to return status are those that
+// depend on memory allocation or similar operations.
+//
+// This means that e.g. an operator [] does not have to check for boundaries.
+// The caller should have checked the boundaries. If it did not we crash and
+// burn: this is a bug in MKL-DNN and throwing an exception would not have been
+// recoverable.
+//
+// On the other hand, insert() or resize() or a similar operation needs to
+// return a status because the outcome depends on factors external to the
+// caller. The situation is probably also not recoverable also, but MKL-DNN
+// needs to be nice and report "out of memory" to the users.
+
+enum nstl_status_t {
+ success = 0,
+ out_of_memory
+};
+
+template <typename T> class vector: public c_compatible {
+private:
+ std::vector<T> _impl;
+public:
+ typedef typename std::vector<T>::iterator iterator;
+ typedef typename std::vector<T>::const_iterator const_iterator;
+ typedef typename std::vector<T>::size_type size_type;
+ vector() {}
+ vector(size_type n): _impl(n) {}
+ vector(size_type n, const T &value): _impl(n, value) {}
+ template <typename input_iterator>
+ vector(input_iterator first, input_iterator last): _impl(first, last) {}
+ ~vector() {}
+ size_type size() const { return _impl.size(); }
+ T& operator[] (size_type i) { return _impl[i]; }
+ const T& operator[] (size_type i) const { return _impl[i]; }
+ iterator begin() { return _impl.begin(); }
+ const_iterator begin() const { return _impl.begin(); }
+ iterator end() { return _impl.end(); }
+ const_iterator end() const { return _impl.end(); }
+ template <typename input_iterator>
+ nstl_status_t insert(iterator pos, input_iterator begin, input_iterator end)
+ {
+ _impl.insert(pos, begin, end);
+ return success;
+ }
+ void clear() { _impl.clear(); }
+ void push_back(const T& t) { _impl.push_back(t); }
+ void resize(size_type count) { _impl.resize(count); }
+ void reserve(size_type count) { _impl.reserve(count); }
+};
+
+template <typename Key, typename T> class map: public c_compatible {
+private:
+ std::map<Key, T> _impl;
+public:
+ typedef typename std::map<Key, T>::iterator iterator;
+ typedef typename std::map<Key, T>::const_iterator const_iterator;
+ typedef typename std::map<Key, T>::size_type size_type;
+ map() {}
+ ~map() {}
+ size_type size() const { return _impl.size(); }
+ T& operator[](const Key &k) { return _impl[k]; }
+ const T& operator[](const Key &k) const { return _impl[k]; }
+ iterator begin() { return _impl.begin(); }
+ const_iterator begin() const { return _impl.begin(); }
+ iterator end() { return _impl.end(); }
+ const_iterator end() const { return _impl.end(); }
+ template <typename input_iterator>
+ void clear() { _impl.clear(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/pooling.cpp b/thirdparty/oidn/mkl-dnn/src/common/pooling.cpp
new file mode 100644
index 0000000000..be96e654ff
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/pooling.cpp
@@ -0,0 +1,114 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::alg_kind;
+using namespace mkldnn::impl::types;
+
+namespace {
+status_t pooling_desc_init(pooling_desc_t *pool_desc,
+ prop_kind_t prop_kind, alg_kind_t alg_kind,
+ const memory_desc_t *src_desc, const memory_desc_t *dst_desc,
+ const dims_t strides, const dims_t kernel, const dims_t padding_l,
+ const dims_t padding_r, padding_kind_t padding_kind) {
+ bool args_ok = true
+ && !any_null(pool_desc, src_desc, dst_desc, strides, kernel, padding_l)
+ && one_of(alg_kind, pooling_max,
+ pooling_avg_include_padding,
+ pooling_avg_exclude_padding)
+ && one_of(padding_kind, padding_kind::padding_zero);
+ if (!args_ok) return invalid_arguments;
+
+ if (padding_r == nullptr) padding_r = padding_l;
+
+ auto pd = pooling_desc_t();
+ pd.primitive_kind = primitive_kind::pooling;
+ pd.prop_kind = prop_kind;
+ pd.alg_kind = alg_kind;
+ pd.src_desc.ndims = src_desc->ndims;
+
+ const bool is_fwd = one_of(prop_kind, forward_training, forward_inference);
+
+ pd.diff_src_desc = pd.src_desc = zero_md();
+ pd.diff_dst_desc = pd.dst_desc = zero_md();
+
+ (is_fwd ? pd.src_desc : pd.diff_src_desc) = *src_desc;
+ (is_fwd ? pd.dst_desc : pd.diff_dst_desc) = *dst_desc;
+
+ int sp_dims = src_desc->ndims - 2;
+ utils::array_copy(pd.strides, strides, sp_dims);
+ utils::array_copy(pd.kernel, kernel, sp_dims);
+ utils::array_copy(pd.padding[0], padding_l, sp_dims);
+ utils::array_copy(pd.padding[1], padding_r, sp_dims);
+
+ pd.padding_kind = padding_kind;
+ if (one_of(alg_kind, pooling_max, pooling_avg_include_padding,
+ pooling_avg_exclude_padding)) {
+ pd.accum_data_type = types::default_accum_data_type(
+ src_desc->data_type, dst_desc->data_type);
+ } else {
+ pd.accum_data_type = dst_desc->data_type;
+ }
+
+ bool consistency = true
+ && utils::one_of(src_desc->ndims, 4, 5)
+ && utils::one_of(dst_desc->ndims, 4, 5)
+ && src_desc->dims[0] == dst_desc->dims[0]
+ && src_desc->dims[1] == dst_desc->dims[1];
+ for (int i = 2; i < src_desc->ndims; ++i)
+ consistency = consistency && (
+ (src_desc->dims[i] - kernel[i - 2] + padding_l[i - 2]
+ + padding_r[i - 2]) / strides[i - 2] + 1
+ == dst_desc->dims[i]);
+ if (!consistency) return invalid_arguments;
+
+ *pool_desc = pd;
+ return success;
+}
+}
+
+status_t mkldnn_pooling_forward_desc_init(pooling_desc_t *pool_desc,
+ prop_kind_t prop_kind, alg_kind_t alg_kind,
+ const memory_desc_t *src_desc, const memory_desc_t *dst_desc,
+ const dims_t strides, const dims_t kernel, const dims_t padding_l,
+ const dims_t padding_r, padding_kind_t padding_kind) {
+ if (!one_of(prop_kind, forward_training, forward_inference))
+ return invalid_arguments;
+ return pooling_desc_init(pool_desc, prop_kind, alg_kind, src_desc,
+ dst_desc, strides, kernel, padding_l, padding_r, padding_kind);
+}
+
+status_t mkldnn_pooling_backward_desc_init(pooling_desc_t *pool_desc,
+ alg_kind_t alg_kind, const memory_desc_t *diff_src_desc,
+ const memory_desc_t *diff_dst_desc, const dims_t strides,
+ const dims_t kernel, const dims_t padding_l, const dims_t padding_r,
+ padding_kind_t padding_kind) {
+ return pooling_desc_init(pool_desc, prop_kind::backward_data, alg_kind,
+ diff_src_desc, diff_dst_desc, strides, kernel, padding_l,
+ padding_r, padding_kind);
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/pooling_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/pooling_pd.hpp
new file mode 100644
index 0000000000..4c9c009412
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/pooling_pd.hpp
@@ -0,0 +1,238 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef POOLING_PD_HPP
+#define POOLING_PD_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "primitive_desc.hpp"
+#include "type_helpers.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct pooling_fwd_pd_t;
+
+struct pooling_pd_t: public primitive_desc_t {
+ static constexpr auto base_pkind = primitive_kind::pooling;
+
+ pooling_pd_t(engine_t *engine,
+ const pooling_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const pooling_fwd_pd_t *hint_fwd_pd)
+ : primitive_desc_t(engine, attr, base_pkind)
+ , desc_(*adesc)
+ , hint_fwd_pd_(hint_fwd_pd)
+ , ws_md_()
+ {}
+
+ const pooling_desc_t *desc() const { return &desc_; }
+ virtual const op_desc_t *op_desc() const override
+ { return reinterpret_cast<const op_desc_t *>(this->desc()); }
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual status_t query(query_t what, int idx, void *result) const override {
+ switch (what) {
+ case query::pooling_d:
+ *(const pooling_desc_t**)result = desc(); break;
+ default: return primitive_desc_t::query(what, idx, result);
+ }
+ return status::success;
+ }
+
+ /* common pooling aux functions */
+
+ dim_t MB() const { return src_desc().dims[0]; }
+ dim_t C() const { return src_desc().dims[1]; }
+
+ dim_t ID() const { return ndims() >= 5 ? src_desc().dims[ndims() - 3] : 1; }
+ dim_t IH() const { return ndims() >= 4 ? src_desc().dims[ndims() - 2] : 1; }
+ dim_t IW() const { return src_desc().dims[ndims() - 1]; }
+
+ dim_t OD() const { return ndims() >= 5 ? dst_desc().dims[ndims() - 3] : 1; }
+ dim_t OH() const { return ndims() >= 4 ? dst_desc().dims[ndims() - 2] : 1; }
+ dim_t OW() const { return dst_desc().dims[ndims() - 1]; }
+
+ dim_t KD() const { return ndims() >= 5 ? desc_.kernel[ndims() - 5] : 1; }
+ dim_t KH() const { return ndims() >= 4 ? desc_.kernel[ndims() - 4] : 1; }
+ dim_t KW() const { return desc_.kernel[ndims() - 3]; }
+
+ dim_t KSD() const { return ndims() >= 5 ? desc_.strides[ndims() - 5] : 1; }
+ dim_t KSH() const { return ndims() >= 4 ? desc_.strides[ndims() - 4] : 1; }
+ dim_t KSW() const { return desc_.strides[ndims() - 3]; }
+
+ dim_t padFront() const
+ { return ndims() >= 5 ? desc_.padding[0][ndims() - 5] : 0; }
+ dim_t padBack() const
+ { return ndims() >= 5 ? desc_.padding[1][ndims() - 5] : 0; }
+ dim_t padT() const
+ { return ndims() >= 4 ? desc_.padding[0][ndims() - 4] : 0; }
+ dim_t padB() const
+ { return ndims() >= 4 ? desc_.padding[1][ndims() - 4] : 0; }
+ dim_t padL() const { return desc_.padding[0][ndims() - 3]; }
+ dim_t padR() const { return desc_.padding[1][ndims() - 3]; }
+
+ int ndims() const { return src_desc().ndims; }
+ bool is_3d() const { return ndims() == 5; }
+
+ bool has_zero_dim_memory() const
+ { return memory_desc_wrapper(src_desc()).has_zero_dim(); }
+
+ bool is_fwd() const {
+ return utils::one_of(desc_.prop_kind, prop_kind::forward_training,
+ prop_kind::forward_inference);
+ }
+
+protected:
+ pooling_desc_t desc_;
+ const pooling_fwd_pd_t *hint_fwd_pd_;
+
+ memory_desc_t ws_md_;
+
+ void init_default_ws() {
+ ws_md_ = is_fwd() ? *dst_md() : *diff_dst_md();
+ ws_md_.data_type = indices_data_type();
+ }
+
+ data_type_t indices_data_type() const {
+ /* the simplest way to express 256... */
+ const int u8_max = nstl::numeric_limits<
+ typename prec_traits<data_type::u8>::type>::max();
+ return utils::array_product(desc()->kernel, ndims()) <= u8_max
+ ? data_type::u8 : data_type::s32;
+ }
+
+private:
+ const memory_desc_t &src_desc() const
+ { return is_fwd() ? desc_.src_desc : desc_.diff_src_desc; }
+ const memory_desc_t &dst_desc() const
+ { return is_fwd() ? desc_.dst_desc : desc_.diff_dst_desc; }
+};
+
+struct pooling_fwd_pd_t: public pooling_pd_t {
+ typedef pooling_fwd_pd_t base_class;
+ typedef pooling_fwd_pd_t hint_class;
+
+ pooling_fwd_pd_t(engine_t *engine,
+ const pooling_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const pooling_fwd_pd_t *hint_fwd_pd)
+ : pooling_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , src_md_(desc_.src_desc)
+ , dst_md_(desc_.dst_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (arg == MKLDNN_ARG_SRC)
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DST)
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_WORKSPACE && (workspace_md() != nullptr))
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &src_md_ : nullptr; }
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 ? &dst_md_ : nullptr; }
+ virtual const memory_desc_t *workspace_md(int index = 0) const override
+ { return index == 0 && !types::is_zero_md(&ws_md_) ? &ws_md_ : nullptr; }
+
+ virtual int n_inputs() const override { return 1; }
+ virtual int n_outputs() const override
+ { return 1 + (workspace_md() != nullptr); }
+
+protected:
+ memory_desc_t src_md_;
+ memory_desc_t dst_md_;
+
+ virtual status_t set_default_params() {
+ if (dst_md()->format_kind != format_kind::any)
+ return status::success;
+
+ if (src_md()->format_kind != format_kind::blocked)
+ return status::unimplemented;
+
+ return memory_desc_init_by_blocking_desc(dst_md_,
+ src_md_.format_desc.blocking);
+ }
+};
+
+struct pooling_bwd_pd_t: public pooling_pd_t {
+ typedef pooling_bwd_pd_t base_class;
+ typedef pooling_fwd_pd_t hint_class;
+
+ pooling_bwd_pd_t(engine_t *engine,
+ const pooling_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const pooling_fwd_pd_t *hint_fwd_pd)
+ : pooling_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , diff_src_md_(desc_.diff_src_desc)
+ , diff_dst_md_(desc_.diff_dst_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (arg == MKLDNN_ARG_DIFF_DST)
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_SRC)
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_WORKSPACE && (workspace_md() != nullptr))
+ return arg_usage_t::input;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *diff_src_md(int index = 0) const override
+ { return index == 0 ? &diff_src_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 ? &diff_dst_md_ : nullptr; }
+ virtual const memory_desc_t *workspace_md(int index = 0) const override
+ { return index == 0 && !types::is_zero_md(&ws_md_) ? &ws_md_ : nullptr; }
+
+ virtual int n_inputs() const override
+ { return 1 + (workspace_md() != nullptr); }
+ virtual int n_outputs() const override { return 1; }
+
+protected:
+ memory_desc_t diff_src_md_;
+ memory_desc_t diff_dst_md_;
+
+ virtual status_t set_default_params() {
+ if (diff_src_md()->format_kind != format_kind::any)
+ return status::success;
+
+ if (diff_dst_md()->format_kind != format_kind::blocked)
+ return status::unimplemented;
+
+ return memory_desc_init_by_blocking_desc(diff_src_md_,
+ diff_dst_md_.format_desc.blocking);
+ }
+};
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/primitive.cpp b/thirdparty/oidn/mkl-dnn/src/common/primitive.cpp
new file mode 100644
index 0000000000..fdf6522f62
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/primitive.cpp
@@ -0,0 +1,103 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "engine.hpp"
+#include "primitive_desc.hpp"
+#include "primitive.hpp"
+#include "type_helpers.hpp"
+#include "stream.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::primitive_kind;
+
+namespace {
+// XXX: this is a huge hammer. This disables all and any msan checks on
+// primitives outputs.
+//
+// A proper approach would be an implementation-specific unpoisoning.
+void unpoison_outputs(const exec_args_t &args) {
+ for(const auto &arg: args) {
+ if (arg.second.is_const) continue;
+ auto *mem = arg.second.mem;
+ void *p;
+ mem->get_data_handle(&p);
+ size_t s = memory_desc_wrapper(*mem->md()).size();
+ msan_unpoison(p, s);
+ }
+}
+}
+
+status_t mkldnn_primitive_desc_destroy(primitive_desc_t *primitive_desc) {
+ if (primitive_desc) delete primitive_desc;
+ return success;
+}
+
+status_t mkldnn_primitive_create(primitive_t **primitive,
+ const primitive_desc_t *primitive_desc) {
+ if (utils::any_null(primitive, primitive_desc))
+ return invalid_arguments;
+ return primitive_desc->create_primitive(primitive);
+}
+
+status_t mkldnn_primitive_execute(const primitive_t *primitive,
+ stream_t *stream, int nargs, const mkldnn_exec_arg_t *c_args) {
+ bool ok = true
+ && !utils::any_null(primitive, stream)
+ && primitive->engine() == stream->engine()
+ && IMPLICATION(nargs > 0, c_args != nullptr);
+ if (!ok) return invalid_arguments;
+
+ exec_args_t args;
+ status_t status = cvt_primtive_args(primitive->pd(), nargs, c_args, args);
+ if (status != status::success) return status;
+
+ exec_ctx_t ctx(stream, std::move(args));
+
+ if (mkldnn_verbose()->level) {
+ double ms = get_msec();
+ status = primitive->execute(ctx);
+ ms = get_msec() - ms;
+ printf("mkldnn_verbose,exec,%s,%g\n", primitive->pd()->info(), ms);
+ fflush(0);
+ } else {
+ status = primitive->execute(ctx);
+ }
+
+ if (msan_enabled) unpoison_outputs(ctx.args());
+
+ return status;
+}
+
+status_t mkldnn_primitive_get_primitive_desc(const primitive_t *primitive,
+ const primitive_desc_t **primitive_desc) {
+ if (utils::any_null(primitive, primitive_desc))
+ return invalid_arguments;
+ return safe_ptr_assign<const primitive_desc_t>(*primitive_desc,
+ primitive->pd());
+}
+
+status_t mkldnn_primitive_destroy(primitive_t *primitive) {
+ if (primitive != nullptr)
+ delete primitive;
+ return success;
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/primitive.hpp b/thirdparty/oidn/mkl-dnn/src/common/primitive.hpp
new file mode 100644
index 0000000000..3b506d6d1f
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/primitive.hpp
@@ -0,0 +1,76 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef PRIMITIVE_HPP
+#define PRIMITIVE_HPP
+
+#include <assert.h>
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "primitive_desc.hpp"
+#include "primitive_exec_types.hpp"
+
+/** \brief A pure virtual primitive class
+ *
+ * Primitive contains links to its inputs & outputs, though it does not track
+ * their readiness on execution step.
+ *
+ * @remark @b Rational.
+ * Dependencies are essential through-out the whole MKL-DNN library, so it
+ * makes sense to include them on the very low level. On the other hand,
+ * tracking them should be a task for corresponding essence, like scheduler,
+ * stream or whatever. Primitive itself should know nothing about the
+ * environment it is running in.
+ *
+ * @note
+ * To make user experience better we should provide API which allows
+ * achieving the best (or good enough) performance when creating primitives
+ * in natural order: i.e. from bottom to top for forward pass and from top to
+ * bottom for backward pass. Please consider restriction [1] in Level 0.
+ */
+struct mkldnn_primitive: public mkldnn::impl::c_compatible {
+ mkldnn_primitive(const mkldnn::impl::primitive_desc_t *pd)
+ : pd_(pd->clone()) {}
+ virtual ~mkldnn_primitive() { delete pd_; }
+
+ /** returns primitive's engine */
+ mkldnn::impl::engine_t *engine() const { return pd_->engine(); }
+ /** returns primitive's inputs */
+ const mkldnn::impl::primitive_desc_t *pd() const { return pd_; }
+ /** returns primitive's kind */
+ mkldnn::impl::primitive_kind_t kind() const { return pd_->kind(); }
+
+ /** executes primitive with execution context @p ctx */
+ virtual mkldnn::impl::status_t execute(const mkldnn::impl::exec_ctx_t &ctx)
+ const = 0;
+
+protected:
+ const mkldnn::impl::primitive_desc_t *pd_;
+
+private:
+ mkldnn_primitive() = delete;
+ mkldnn_primitive(const mkldnn_primitive &) = delete;
+ mkldnn_primitive(mkldnn_primitive &&) = delete;
+ mkldnn_primitive &operator=(const mkldnn_primitive &) = delete;
+ mkldnn_primitive &operator=(mkldnn_primitive &&) = delete;
+};
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/primitive_attr.cpp b/thirdparty/oidn/mkl-dnn/src/common/primitive_attr.cpp
new file mode 100644
index 0000000000..9fd638842c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/primitive_attr.cpp
@@ -0,0 +1,290 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "primitive_attr.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::utils;
+
+namespace mkldnn {
+namespace impl {
+
+status_t scales_t::set(dim_t count, int mask, const float *scales) {
+ cleanup();
+
+ count_ = count;
+ mask_ = mask;
+
+ if (count_ == 1) {
+ scales_ = scales_buf_;
+ utils::array_set(scales_, scales[0], scales_buf_size);
+ } else {
+ scales_ = (float *)impl::malloc(count_ * sizeof(*scales_), 64);
+ if (scales_ == nullptr)
+ return status::out_of_memory;
+
+ for (dim_t c = 0; c < count_; ++c)
+ scales_[c] = scales[c];
+ }
+
+ return status::success;
+}
+
+}
+}
+
+status_t post_ops_t::append_sum(float scale) {
+ if (len_ == capacity)
+ return out_of_memory;
+
+ entry_[len_].kind = primitive_kind::sum;
+ entry_[len_].sum.scale = scale;
+
+ len_++;
+
+ return success;
+}
+
+status_t post_ops_t::append_eltwise(float scale, alg_kind_t alg, float alpha,
+ float beta) {
+ using namespace mkldnn::impl::alg_kind;
+ bool known_alg = one_of(alg, eltwise_relu, eltwise_tanh, eltwise_elu,
+ eltwise_square, eltwise_abs, eltwise_sqrt, eltwise_linear,
+ eltwise_bounded_relu, eltwise_soft_relu, eltwise_logistic);
+ if (!known_alg)
+ return invalid_arguments;
+
+ if (len_ == capacity)
+ return out_of_memory;
+
+ entry_[len_].kind = primitive_kind::eltwise;
+ entry_[len_].eltwise.scale = scale;
+ entry_[len_].eltwise.alg = alg;
+ entry_[len_].eltwise.alpha = alpha;
+ entry_[len_].eltwise.beta = beta;
+
+ len_++;
+
+ return success;
+}
+
+status_t primitive_attr_t::set_scratchpad_mode(
+ scratchpad_mode_t scratchpad_mode) {
+ using namespace mkldnn::impl::scratchpad_mode;
+
+ const bool ok = one_of(scratchpad_mode, library, user);
+ if (!ok)
+ return invalid_arguments;
+
+ scratchpad_mode_ = scratchpad_mode;
+ return success;
+}
+
+status_t primitive_attr_t::set_post_ops(const post_ops_t &post_ops) {
+ this->post_ops_ = post_ops;
+ return success;
+}
+
+/* Public C API */
+
+status_t mkldnn_primitive_attr_create(primitive_attr_t **attr) {
+ if (attr == nullptr)
+ return invalid_arguments;
+
+ return safe_ptr_assign<mkldnn_primitive_attr>(*attr,
+ new mkldnn_primitive_attr);
+}
+
+status_t mkldnn_primitive_attr_clone(primitive_attr_t **attr,
+ const primitive_attr_t *existing_attr) {
+ if (any_null(attr, existing_attr))
+ return invalid_arguments;
+
+ return safe_ptr_assign<mkldnn_primitive_attr>(*attr,
+ existing_attr->clone());
+}
+
+status_t mkldnn_primitive_attr_destroy(primitive_attr_t *attr) {
+ if (attr)
+ delete attr;
+
+ return success;
+}
+
+status_t mkldnn_primitive_attr_get_scratchpad_mode(
+ const primitive_attr_t *attr, scratchpad_mode_t *scratchpad_mode) {
+ if (any_null(attr, scratchpad_mode))
+ return invalid_arguments;
+
+ *scratchpad_mode = attr->scratchpad_mode_;
+
+ return success;
+}
+
+status_t mkldnn_primitive_attr_set_scratchpad_mode(
+ primitive_attr_t *attr, scratchpad_mode_t scratchpad_mode) {
+ if (any_null(attr))
+ return invalid_arguments;
+
+ return attr->set_scratchpad_mode(scratchpad_mode);
+}
+
+status_t mkldnn_primitive_attr_get_output_scales(const primitive_attr_t *attr,
+ dim_t *count, int *mask, const float **scales) {
+ if (any_null(attr, count, mask, scales))
+ return invalid_arguments;
+
+ *count = attr->output_scales_.count_;
+ *mask = attr->output_scales_.mask_;
+ *scales = attr->output_scales_.scales_;
+
+ return success;
+}
+
+status_t mkldnn_primitive_attr_set_output_scales(primitive_attr_t *attr,
+ dim_t count, int mask, const float *scales) {
+ bool ok = !any_null(attr, scales) && count > 0 && mask >= 0;
+ if (!ok)
+ return invalid_arguments;
+
+ return attr->output_scales_.set(count, mask, scales);
+}
+
+status_t mkldnn_primitive_attr_get_post_ops(const primitive_attr_t *attr,
+ const post_ops_t **post_ops) {
+ if (any_null(attr, post_ops))
+ return invalid_arguments;
+
+ *post_ops = &attr->post_ops_;
+ return success;
+}
+
+status_t mkldnn_primitive_attr_set_post_ops(primitive_attr_t *attr,
+ const post_ops_t *post_ops) {
+ if (any_null(attr, post_ops))
+ return invalid_arguments;
+
+ return attr->set_post_ops(*post_ops);
+}
+
+status_t mkldnn_post_ops_create(post_ops_t **post_ops) {
+ if (post_ops == nullptr)
+ return invalid_arguments;
+
+ return safe_ptr_assign<mkldnn_post_ops>(*post_ops, new mkldnn_post_ops);
+}
+
+status_t mkldnn_post_ops_destroy(post_ops_t *post_ops) {
+ if (post_ops)
+ delete post_ops;
+
+ return success;
+}
+
+int mkldnn_post_ops_len(const post_ops_t *post_ops) {
+ if (post_ops)
+ return post_ops->len_;
+
+ return 0;
+}
+
+primitive_kind_t mkldnn_post_ops_get_kind(const post_ops_t *post_ops,
+ int index) {
+ bool ok = post_ops && 0 <= index && index < post_ops->len_;
+ if (!ok)
+ return primitive_kind::undefined;
+
+ return post_ops->entry_[index].kind;
+}
+
+status_t mkldnn_post_ops_append_sum(post_ops_t *post_ops, float scale) {
+ if (post_ops == nullptr)
+ return invalid_arguments;
+
+ return post_ops->append_sum(scale);
+}
+
+namespace {
+bool simple_get_params_check(const post_ops_t *post_ops, int index,
+ primitive_kind_t kind) {
+ bool ok = true
+ && post_ops != nullptr
+ && 0 <= index
+ && index < post_ops->len_
+ && post_ops->entry_[index].kind == kind;
+ return ok;
+}
+}
+
+status_t mkldnn_post_ops_get_params_sum(const post_ops_t *post_ops, int index,
+ float *scale) {
+ bool ok = true
+ && simple_get_params_check(post_ops, index, primitive_kind::sum)
+ && !any_null(scale);
+ if (!ok)
+ return invalid_arguments;
+
+ *scale = post_ops->entry_[index].sum.scale;
+ return success;
+}
+
+status_t mkldnn_post_ops_append_eltwise(post_ops_t *post_ops, float scale,
+ alg_kind_t kind, float alpha, float beta) {
+ if (post_ops == nullptr)
+ return invalid_arguments;
+
+ return post_ops->append_eltwise(scale, kind, alpha, beta);
+}
+
+status_t mkldnn_post_ops_get_params_eltwise(const post_ops_t *post_ops,
+ int index, float *scale, alg_kind_t *alg, float *alpha, float *beta) {
+ bool ok = true
+ && simple_get_params_check(post_ops, index, primitive_kind::eltwise)
+ && !any_null(scale, alpha, beta);
+ if (!ok)
+ return invalid_arguments;
+
+ const auto &e = post_ops->entry_[index].eltwise;
+ *scale = e.scale;
+ *alg = e.alg;
+ *alpha = e.alpha;
+ *beta = e.beta;
+
+ return success;
+}
+
+status_t mkldnn_primitive_attr_set_rnn_data_qparams(
+ primitive_attr_t *attr, const float scale, const float shift) {
+ if (attr == nullptr)
+ return invalid_arguments;
+
+ return attr->rnn_data_qparams_.set(scale, shift);
+}
+
+status_t mkldnn_primitive_attr_set_rnn_weights_qparams(
+ primitive_attr_t *attr, dim_t count, int mask, const float *scales) {
+ bool ok = !any_null(attr, scales) && count > 0 && mask >= 0;
+ if (!ok)
+ return invalid_arguments;
+
+ return attr->rnn_weights_qparams_.set(count, mask, scales);
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/primitive_attr.hpp b/thirdparty/oidn/mkl-dnn/src/common/primitive_attr.hpp
new file mode 100644
index 0000000000..e2130c7ab1
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/primitive_attr.hpp
@@ -0,0 +1,183 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef PRIMITIVE_ATTR_HPP
+#define PRIMITIVE_ATTR_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct rnn_data_qparams_t : public c_compatible {
+ rnn_data_qparams_t() : scale_(1.), shift_(0.) {}
+ bool has_default_values() const { return (scale_ == 1. && shift_ == 0.); }
+
+ status_t set(float scale, float shift) {
+ scale_ = scale;
+ shift_ = shift;
+ return status::success;
+ }
+
+ float scale_;
+ float shift_;
+};
+
+struct scales_t: public c_compatible {
+ scales_t(): count_(1), mask_(0), scales_(scales_buf_)
+ { set(1.); }
+
+ scales_t(const scales_t &rhs): scales_t()
+ { set(rhs.count_, rhs.mask_, rhs.scales_); }
+
+ ~scales_t() { cleanup(); }
+
+ scales_t &operator=(const scales_t &rhs) {
+ if (&rhs == this)
+ return *this;
+ status_t status = set(rhs.count_, rhs.mask_, rhs.scales_);
+ assert(status == status::success);
+ (void)status;
+ return *this;
+ }
+
+ bool has_default_values() const {
+ for (dim_t c = 0; c < count_; ++c) {
+ if(scales_[c] != 1.) return false;
+ }
+ return true;
+ }
+
+ status_t set(dim_t count, int mask, const float *scales);
+ status_t set(float single_scale) { return this->set(1, 0, &single_scale); }
+
+ dim_t count_;
+ int mask_;
+ float *scales_;
+
+private:
+ enum { scales_buf_size = 16 };
+ float scales_buf_[scales_buf_size];
+
+ void cleanup() {
+ if (scales_ != scales_buf_ && scales_ != nullptr)
+ impl::free(scales_);
+
+ count_ = 1;
+ mask_ = 0;
+ scales_ = scales_buf_;
+ }
+};
+
+}
+}
+
+struct mkldnn_post_ops: public mkldnn::impl::c_compatible {
+ struct entry_t {
+ struct eltwise_t {
+ mkldnn::impl::alg_kind_t alg;
+ float scale, alpha, beta;
+ };
+
+ mkldnn::impl::primitive_kind_t kind;
+ union {
+ struct { float scale; } sum;
+ eltwise_t eltwise;
+ };
+
+ bool is_eltwise(bool require_scale_one = true) const {
+ using namespace mkldnn::impl;
+ return kind == primitive_kind::eltwise
+ && IMPLICATION(require_scale_one, eltwise.scale == 1.f);
+ }
+
+ bool is_relu(bool require_scale_one = true,
+ bool require_nslope_zero = true) const {
+ using namespace mkldnn::impl;
+ return is_eltwise(require_scale_one)
+ && eltwise.alg == alg_kind::eltwise_relu
+ && IMPLICATION(require_nslope_zero, eltwise.alpha == 0.f);
+ }
+
+ bool is_sum(bool require_scale_one = true) const {
+ using namespace mkldnn::impl;
+ return kind == primitive_kind::sum
+ && IMPLICATION(require_scale_one, sum.scale == 1.f);
+ }
+ };
+
+ mkldnn_post_ops(): len_(0) {}
+
+ mkldnn::impl::status_t append_sum(float scale);
+ mkldnn::impl::status_t append_eltwise(float scale,
+ mkldnn::impl::alg_kind_t alg, float alpha, float beta);
+
+ int find(mkldnn::impl::primitive_kind_t kind, int start = 0,
+ int stop = -1) const {
+ if (stop == -1) stop = len_;
+ stop = mkldnn::impl::nstl::min(stop, len_);
+ for (int idx = start; idx < stop; ++idx)
+ if (entry_[idx].kind == kind) return idx;
+ return -1;
+ }
+
+ bool has_default_values() const { return len_ == 0; }
+
+ bool contain(mkldnn::impl::primitive_kind_t kind, int index) const
+ { return find(kind, index, index + 1) == index; }
+
+ enum { capacity = 4 };
+
+ int len_;
+ entry_t entry_[capacity];
+};
+
+struct mkldnn_primitive_attr: public mkldnn::impl::c_compatible {
+ mkldnn_primitive_attr()
+ : scratchpad_mode_(mkldnn::impl::scratchpad_mode::library)
+ {}
+
+ mkldnn_primitive_attr *clone() const
+ { return new mkldnn_primitive_attr(*this); }
+
+ /** Returns true if the attributes have default values.
+ *
+ * @note The scratchpad_mode_ is not take into account */
+ bool has_default_values() const {
+ return true
+ && output_scales_.has_default_values()
+ && post_ops_.has_default_values()
+ && rnn_data_qparams_.has_default_values()
+ && rnn_weights_qparams_.has_default_values();
+ }
+
+ mkldnn::impl::status_t set_scratchpad_mode(
+ mkldnn::impl::scratchpad_mode_t scratchpad_mode);
+ mkldnn::impl::status_t set_post_ops(
+ const mkldnn::impl::post_ops_t &post_ops);
+
+ mkldnn::impl::scratchpad_mode_t scratchpad_mode_;
+ mkldnn::impl::scales_t output_scales_;
+ mkldnn::impl::post_ops_t post_ops_;
+ mkldnn::impl::rnn_data_qparams_t rnn_data_qparams_;
+ mkldnn::impl::scales_t rnn_weights_qparams_;
+};
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/primitive_desc.cpp b/thirdparty/oidn/mkl-dnn/src/common/primitive_desc.cpp
new file mode 100644
index 0000000000..723c41e05a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/primitive_desc.cpp
@@ -0,0 +1,78 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "primitive_desc.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::status;
+
+status_t primitive_desc_t::query(query_t what, int idx, void *result) const {
+ auto safe_ret_md = [&](const memory_desc_t *_) {
+ if (_ == nullptr) return not_required;
+ *(const memory_desc_t **)result = _;
+ return success;
+ };
+
+ switch (what) {
+ case query::engine: *(engine_t**)result = engine(); break;
+ case query::primitive_kind: *(primitive_kind_t*)result = kind(); break;
+
+ case query::scratchpad_engine:
+ *(engine_t**)result = scratchpad_engine(); break;
+
+ case query::memory_consumption_s64:
+ *(dim_t *)result = scratchpad_size(scratchpad_mode::library); break;
+
+ case query::op_d:
+ if (idx != 0 || op_desc() == nullptr) return invalid_arguments;
+ *(const_c_op_desc_t *)result
+ = static_cast<const_c_op_desc_t>(op_desc()); break;
+
+ case query::src_md: return safe_ret_md(src_md(idx));
+ case query::diff_src_md: return safe_ret_md(diff_src_md(idx));
+ case query::dst_md: return safe_ret_md(dst_md(idx));
+ case query::diff_dst_md: return safe_ret_md(diff_dst_md(idx));
+ case query::weights_md: return safe_ret_md(weights_md(idx));
+ case query::diff_weights_md: return safe_ret_md(diff_weights_md(idx));
+ case query::workspace_md:
+ if (idx != 0) return status::invalid_arguments;
+ return safe_ret_md(workspace_md(idx));
+ case query::scratchpad_md:
+ if (idx != 0) return status::invalid_arguments;
+ return safe_ret_md(scratchpad_md(idx));
+
+ case query::num_of_inputs_s32: *(int*)result = n_inputs(); break;
+ case query::num_of_outputs_s32: *(int*)result = n_outputs(); break;
+
+ case query::impl_info_str: *(const char **)result = name(); break;
+
+ default: return unimplemented;
+ }
+ return success;
+}
+
+status_t mkldnn_primitive_desc_get_attr(const primitive_desc_t *primitive_desc,
+ const primitive_attr_t **attr) {
+ if (utils::any_null(primitive_desc, attr))
+ return invalid_arguments;
+
+ *attr = primitive_desc->attr();
+ return success;
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/primitive_desc.hpp b/thirdparty/oidn/mkl-dnn/src/common/primitive_desc.hpp
new file mode 100644
index 0000000000..536dcfa1d0
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/primitive_desc.hpp
@@ -0,0 +1,174 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef PRIMITIVE_DESC_HPP
+#define PRIMITIVE_DESC_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "primitive_attr.hpp"
+#include "verbose.hpp"
+
+struct mkldnn_primitive_desc: public mkldnn::impl::c_compatible {
+ using md_t = mkldnn::impl::memory_desc_t;
+
+ mkldnn_primitive_desc(mkldnn::impl::engine_t *engine,
+ const mkldnn::impl::primitive_attr_t *attr,
+ mkldnn::impl::primitive_kind_t kind)
+ : engine_(engine), attr_(*attr), kind_(kind) { info_[0] = '\0'; }
+
+ mkldnn_primitive_desc(mkldnn::impl::engine_t *engine,
+ mkldnn::impl::primitive_kind_t kind)
+ : engine_(engine), kind_(kind) { info_[0] = '\0'; }
+
+ virtual mkldnn_primitive_desc *clone() const = 0;
+ virtual ~mkldnn_primitive_desc() {}
+
+ const mkldnn::impl::primitive_attr_t *attr() const { return &attr_; }
+ mkldnn::impl::engine_t *engine() const { return engine_; }
+ mkldnn::impl::primitive_kind_t kind() const { return kind_; }
+
+ virtual void init_info() {}
+ const char *info() const { return info_; }
+
+ mkldnn::impl::memory_tracking::registry_t &scratchpad_registry()
+ { return scratchpad_registry_; }
+ const mkldnn::impl::memory_tracking::registry_t &scratchpad_registry() const
+ { return scratchpad_registry_; }
+ virtual mkldnn::impl::engine_t *scratchpad_engine() const
+ { return engine_; }
+
+ virtual const mkldnn::impl::op_desc_t *op_desc() const { return nullptr; }
+
+ enum class arg_usage_t { unused, input, output };
+ virtual arg_usage_t arg_usage(
+ mkldnn::impl::primitive_arg_index_t arg) const {
+ using mkldnn::impl::types::is_zero_md;
+ if (arg == MKLDNN_ARG_SCRATCHPAD && !is_zero_md(scratchpad_md()))
+ return arg_usage_t::output;
+ return arg_usage_t::unused;
+ }
+
+# define DECLARE_MD_STUB(stub) \
+ virtual const mkldnn::impl::memory_desc_t *stub(int idx = 0) const \
+ { return nullptr; }
+
+ DECLARE_MD_STUB(input_md); DECLARE_MD_STUB(output_md);
+ DECLARE_MD_STUB(src_md); DECLARE_MD_STUB(diff_src_md);
+ DECLARE_MD_STUB(dst_md); DECLARE_MD_STUB(diff_dst_md);
+ DECLARE_MD_STUB(weights_md); DECLARE_MD_STUB(diff_weights_md);
+ DECLARE_MD_STUB(workspace_md);
+# undef DECLARE_MD_STUB
+
+ const mkldnn::impl::memory_desc_t *scratchpad_md(int idx = 0) const {
+ return idx == 0 ? &scratchpad_md_ : nullptr;
+ }
+
+ virtual void init_scratchpad_md() {
+ auto size = scratchpad_size(mkldnn::impl::scratchpad_mode::user);
+ mkldnn::impl::dims_t dims = { size };
+ mkldnn_memory_desc_init_by_tag(&scratchpad_md_, size ? 1 : 0, dims,
+ mkldnn::impl::data_type::u8, mkldnn_x);
+ }
+
+ /** returns the scratchpad size for the given scratchpad mode. */
+ mkldnn::impl::dim_t scratchpad_size(
+ mkldnn::impl::scratchpad_mode_t mode) const {
+ if (mode != attr_.scratchpad_mode_) return 0;
+ return scratchpad_registry().size();
+ }
+
+ virtual int n_inputs() const { return 0; }
+ virtual int n_outputs() const { return 0; }
+
+ virtual mkldnn::impl::status_t query(mkldnn::impl::query_t what, int idx,
+ void *result) const;
+
+ virtual mkldnn::impl::status_t create_primitive(
+ mkldnn::impl::primitive_t **primitive) const = 0;
+
+ virtual const char *name() const { return "mkldnn_primitive_desc"; }
+
+ /* static magic */
+
+ template<typename pd_t>
+ static mkldnn::impl::status_t create(mkldnn::impl::primitive_desc_t **pd,
+ const mkldnn::impl::op_desc_t *adesc,
+ const mkldnn::impl::primitive_attr_t *attr,
+ mkldnn::impl::engine_t *engine,
+ const mkldnn::impl::primitive_desc_t *hint_fwd) {
+ using namespace mkldnn::impl;
+ using namespace mkldnn::impl::status;
+ using pd_op_desc_t = typename pkind_traits<pd_t::base_pkind>::desc_type;
+ if (adesc->kind != pd_t::base_pkind) return invalid_arguments;
+ assert(hint_fwd ? hint_fwd->kind() == pd_t::base_pkind : true);
+ auto hint =
+ reinterpret_cast<const typename pd_t::hint_class *>(hint_fwd);
+ auto _pd = new pd_t(engine, (const pd_op_desc_t *)adesc, attr, hint);
+ if (_pd == nullptr) return out_of_memory;
+ if (_pd->init() != success) { delete _pd; return unimplemented; }
+ _pd->init_info();
+ _pd->init_scratchpad_md();
+ *pd = _pd;
+ return success;
+ }
+
+protected:
+ mkldnn::impl::engine_t *engine_;
+ mkldnn::impl::primitive_attr_t attr_;
+ mkldnn::impl::primitive_kind_t kind_;
+
+ mkldnn::impl::memory_desc_t scratchpad_md_;
+
+ char info_[MKLDNN_VERBOSE_BUF_LEN];
+
+ mkldnn::impl::memory_tracking::registry_t scratchpad_registry_;
+
+protected:
+ /** compares ws between fwd_pd and this (make sense to use for bwd_pd)
+ * Expectation: this already set workspace, and this workspace should
+ * exactly match the one from fwd_pd */
+ bool compare_ws(const mkldnn_primitive_desc *fwd_pd) const {
+ using namespace mkldnn::impl;
+ if (!workspace_md()) return true; // the impl lives fine w/o workspace
+ return fwd_pd && fwd_pd->workspace_md()
+ && *fwd_pd->workspace_md() == *workspace_md();
+ }
+};
+
+#define DECLARE_COMMON_PD_t(impl_name, ...) \
+ virtual pd_t *clone() const override { return new pd_t(*this); } \
+ virtual status_t create_primitive(primitive_t **p) const override { \
+ double ms = get_msec(); \
+ auto ret = safe_ptr_assign<primitive_t>(*p, new (__VA_ARGS__)(this)); \
+ ms = get_msec() - ms; \
+ if (mkldnn_verbose()->level >= 2) { \
+ printf("mkldnn_verbose,create,%s,%g\n", this->info(), ms); \
+ fflush(0); \
+ } \
+ return ret; \
+ } \
+ virtual const char *name() const override { return impl_name; }
+#define DECLARE_COMMON_PD_T(impl_name, ...) \
+ DECLARE_COMMON_PD_t(impl_name, __VA_ARGS__)
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/primitive_exec_types.cpp b/thirdparty/oidn/mkl-dnn/src/common/primitive_exec_types.cpp
new file mode 100644
index 0000000000..43e5a31ef3
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/primitive_exec_types.cpp
@@ -0,0 +1,90 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "memory.hpp"
+#include "primitive.hpp"
+#include "primitive_exec_types.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+status_t cvt_primtive_args(const primitive_desc_t *pd, int nargs,
+ const mkldnn_exec_arg_t *c_args, exec_args_t &args) {
+ using namespace status;
+
+ if (!IMPLICATION(nargs > 0, c_args != nullptr)) return invalid_arguments;
+
+ int n_inputs = 0;
+ int n_outputs = 0;
+
+ for (int i = 0; i < nargs; ++i) {
+ primitive_arg_index_t arg = c_args[i].arg;
+ auto *mem = c_args[i].memory;
+
+ switch (pd->arg_usage(arg)) {
+ case primitive_desc_t::arg_usage_t::input:
+ if (args.count(arg) != 0) return invalid_arguments;
+ args[arg] = {mem, true};
+ n_inputs++;
+ break;
+ case primitive_desc_t::arg_usage_t::output:
+ if (args.count(arg) != 0) return invalid_arguments;
+ args[arg] = {mem, false};
+ n_outputs++;
+ break;
+ case primitive_desc_t::arg_usage_t::unused:
+ break;
+ }
+ }
+
+ bool scratchpad_required = !types::is_zero_md(pd->scratchpad_md());
+
+ if (n_inputs != pd->n_inputs()) return invalid_arguments;
+ if (n_outputs != pd->n_outputs() + (scratchpad_required ? 1 : 0))
+ return invalid_arguments;
+
+ return success;
+}
+
+const void *exec_ctx_t::input(primitive_arg_index_t arg) const {
+ if (args_.count(arg) != 1) return nullptr;
+ const auto ma = args_.at(arg);
+ assert(ma.is_const);
+ void *ptr;
+ status_t status = ma.mem->get_data_handle(&ptr);
+ assert(status == status::success); MAYBE_UNUSED(status);
+ return ptr;
+}
+
+void *exec_ctx_t::output(primitive_arg_index_t arg) const {
+ if (args_.count(arg) != 1) return nullptr;
+ const auto ma = args_.at(arg);
+ assert(!ma.is_const);
+ void *ptr;
+ status_t status = ma.mem->get_data_handle(&ptr);
+ assert(status == status::success); MAYBE_UNUSED(status);
+ return ptr;
+}
+
+const memory_t *exec_ctx_t::memory(primitive_arg_index_t arg) const {
+ assert(args_.count(arg) == 1);
+ const auto ma = args_.at(arg);
+ assert(!ma.is_const);
+ return ma.mem;
+}
+
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/primitive_exec_types.hpp b/thirdparty/oidn/mkl-dnn/src/common/primitive_exec_types.hpp
new file mode 100644
index 0000000000..0645891da7
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/primitive_exec_types.hpp
@@ -0,0 +1,68 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef PRIMITIVE_EXEC_TYPES_HPP
+#define PRIMITIVE_EXEC_TYPES_HPP
+
+#include <unordered_map>
+
+#include "mkldnn_types.h"
+
+#include "c_types_map.hpp"
+#include "memory.hpp"
+#include "primitive_desc.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct memory_arg_t {
+ memory_t *mem;
+ bool is_const;
+};
+
+using exec_args_t = std::unordered_map<primitive_arg_index_t, memory_arg_t>;
+
+status_t cvt_primtive_args(const primitive_desc_t *pd, int nargs,
+ const mkldnn_exec_arg_t *c_args, exec_args_t &args);
+
+/** Primitive execution context (helps passing stream, memories, and events. */
+struct exec_ctx_t {
+ exec_ctx_t(const exec_ctx_t &) = default;
+ exec_ctx_t(exec_ctx_t &&) = default;
+
+ exec_ctx_t(stream_t *stream): stream_(stream) {}
+ exec_ctx_t(stream_t *stream, exec_args_t &&args)
+ : stream_(stream)
+ , args_(std::move(args)) {}
+
+ stream_t *stream() const { return stream_; }
+ const exec_args_t &args() const { return args_; }
+
+ /* tentative solution... TODO: replace with functions return memory_t */
+ const void *input(primitive_arg_index_t arg) const;
+ void *output(primitive_arg_index_t arg) const;
+
+ const memory_t *memory(primitive_arg_index_t arg) const;
+
+private:
+ stream_t *stream_;
+ exec_args_t args_;
+};
+
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/primitive_iterator.cpp b/thirdparty/oidn/mkl-dnn/src/common/primitive_iterator.cpp
new file mode 100644
index 0000000000..5a1cd7d379
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/primitive_iterator.cpp
@@ -0,0 +1,89 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "engine.hpp"
+#include "primitive_desc.hpp"
+#include "type_helpers.hpp"
+#include "primitive_iterator.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::status;
+
+status_t mkldnn_primitive_desc_iterator_create(
+ primitive_desc_iterator_t **iterator, const_c_op_desc_t c_op_desc,
+ const primitive_attr_t *attr, engine_t *engine,
+ const primitive_desc_t *hint_fwd_pd) {
+ const op_desc_t *op_desc = (const op_desc_t *)c_op_desc;
+
+ auto it = new primitive_desc_iterator_t(engine, op_desc, attr, hint_fwd_pd);
+ if (it == nullptr) return out_of_memory;
+
+ ++(*it);
+ if (*it == it->end()) {
+ delete it;
+ return unimplemented;
+ }
+
+ *iterator = it;
+ return success;
+}
+
+status_t mkldnn_primitive_desc_iterator_next(
+ primitive_desc_iterator_t *iterator) {
+ if (iterator == nullptr) return invalid_arguments;
+ ++(*iterator);
+ return *iterator == iterator->end() ? iterator_ends : success;
+}
+
+primitive_desc_t *mkldnn_primitive_desc_iterator_fetch(
+ const primitive_desc_iterator_t *iterator) {
+ if (iterator == nullptr) return nullptr;
+ return *(*iterator);
+}
+
+status_t mkldnn_primitive_desc_clone(primitive_desc_t **primitive_desc,
+ const primitive_desc_t *existing_primitive_desc) {
+ if (utils::any_null(primitive_desc, existing_primitive_desc))
+ return invalid_arguments;
+ return safe_ptr_assign<primitive_desc_t>(*primitive_desc,
+ existing_primitive_desc->clone());
+}
+
+status_t mkldnn_primitive_desc_iterator_destroy(
+ primitive_desc_iterator_t *iterator) {
+ if (iterator != nullptr)
+ delete iterator;
+ return success;
+}
+
+status_t mkldnn_primitive_desc_create(primitive_desc_t **primitive_desc,
+ const_c_op_desc_t c_op_desc, const primitive_attr_t *attr,
+ engine_t *engine, const primitive_desc_t *hint_fwd_pd) {
+ const op_desc_t *op_desc = (const op_desc_t *)c_op_desc;
+
+ mkldnn_primitive_desc_iterator it(engine, op_desc, attr, hint_fwd_pd);
+ ++it;
+ if (it == it.end()) return unimplemented;
+
+ return safe_ptr_assign<primitive_desc_t>(*primitive_desc, *it);
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/primitive_iterator.hpp b/thirdparty/oidn/mkl-dnn/src/common/primitive_iterator.hpp
new file mode 100644
index 0000000000..4e88ab3aa5
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/primitive_iterator.hpp
@@ -0,0 +1,79 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+#ifndef PRIMITIVE_ITERATOR_HPP
+#define PRIMITIVE_ITERATOR_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "engine.hpp"
+#include "primitive_desc.hpp"
+#include "type_helpers.hpp"
+
+struct mkldnn_primitive_desc_iterator: public mkldnn::impl::c_compatible {
+ using pd_create_f = mkldnn::impl::engine_t::primitive_desc_create_f;
+
+ mkldnn_primitive_desc_iterator(mkldnn::impl::engine_t *engine, const mkldnn::impl::op_desc_t *op_desc,
+ const mkldnn::impl::primitive_attr_t *attr, const mkldnn::impl::primitive_desc_t *hint_fwd_pd)
+ : idx_(-1), engine_(engine), pd_(nullptr), op_desc_(op_desc)
+ , attr_(attr ? *attr : mkldnn::impl::primitive_attr_t()), hint_fwd_pd_(hint_fwd_pd)
+ , impl_list_(engine_->get_implementation_list()), last_idx_(0)
+ {
+ while (impl_list_[last_idx_] != nullptr) ++last_idx_;
+ }
+ ~mkldnn_primitive_desc_iterator() { if (pd_) delete pd_; }
+
+ bool operator==(const mkldnn::impl::primitive_desc_iterator_t& rhs) const
+ { return idx_ == rhs.idx_ && engine_ == rhs.engine_; }
+ bool operator!=(const mkldnn::impl::primitive_desc_iterator_t& rhs) const
+ { return !operator==(rhs); }
+
+ mkldnn::impl::primitive_desc_iterator_t end() const
+ { return mkldnn_primitive_desc_iterator(engine_, last_idx_); }
+
+ mkldnn::impl::primitive_desc_iterator_t &operator++() {
+ if (pd_) { delete pd_; pd_ = nullptr; }
+ while (++idx_ != last_idx_) {
+ auto s = impl_list_[idx_](&pd_, op_desc_, &attr_, engine_,
+ hint_fwd_pd_);
+ if (s == mkldnn::impl::status::success) break;
+ }
+ return *this;
+ }
+
+ mkldnn::impl::primitive_desc_t *operator*() const {
+ if (*this == end() || pd_ == nullptr) return nullptr;
+ return pd_->clone();
+ }
+
+protected:
+ int idx_;
+ mkldnn::impl::engine_t *engine_;
+ mkldnn::impl::primitive_desc_t *pd_;
+ const mkldnn::impl::op_desc_t *op_desc_;
+ const mkldnn::impl::primitive_attr_t attr_;
+ const mkldnn::impl::primitive_desc_t *hint_fwd_pd_;
+ const pd_create_f *impl_list_;
+ int last_idx_;
+
+private:
+ mkldnn_primitive_desc_iterator(mkldnn::impl::engine_t *engine, int last_idx)
+ : idx_(last_idx), engine_(engine), pd_(nullptr)
+ , op_desc_(nullptr), hint_fwd_pd_(nullptr)
+ , impl_list_(nullptr), last_idx_(last_idx) {}
+};
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/query.cpp b/thirdparty/oidn/mkl-dnn/src/common/query.cpp
new file mode 100644
index 0000000000..835cd73581
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/query.cpp
@@ -0,0 +1,59 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "engine.hpp"
+#include "primitive_desc.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+
+status_t mkldnn_primitive_desc_query(const primitive_desc_t *primitive_desc,
+ query_t what, int index, void *result) {
+ if (any_null(primitive_desc, result))
+ return invalid_arguments;
+
+ return primitive_desc->query(what, index, result);
+}
+
+const memory_desc_t *mkldnn_primitive_desc_query_md(
+ const primitive_desc_t *primitive_desc, query_t what, int index) {
+ const memory_desc_t *res_md = nullptr;
+ bool args_ok = true
+ && primitive_desc != nullptr
+ && (what & query::some_md) == query::some_md
+ && what != query::some_md
+ && mkldnn_primitive_desc_query(primitive_desc,
+ what, index, &res_md) == success;
+ return args_ok ? res_md : nullptr;
+}
+
+int mkldnn_primitive_desc_query_s32(const primitive_desc_t *primitive_desc,
+ query_t what, int index) {
+ int res_s32;
+ bool args_ok = primitive_desc != nullptr
+ && one_of(what, query::num_of_inputs_s32, query::num_of_outputs_s32)
+ && mkldnn_primitive_desc_query(primitive_desc, what, index, &res_s32)
+ == success;
+ return args_ok ? res_s32 : 0;
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/reorder.cpp b/thirdparty/oidn/mkl-dnn/src/common/reorder.cpp
new file mode 100644
index 0000000000..d11f1a0361
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/reorder.cpp
@@ -0,0 +1,68 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "engine.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "reorder_pd.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+
+status_t mkldnn_reorder_primitive_desc_create(
+ primitive_desc_t **reorder_pd,
+ engine_t *src_engine, const memory_desc_t *src_md,
+ engine_t *dst_engine, const memory_desc_t *dst_md,
+ const primitive_attr_t *attr) {
+ if (any_null(reorder_pd, src_engine, src_md, dst_engine, dst_md))
+ return invalid_arguments;
+
+ auto s_ek = src_engine->kind();
+ auto d_ek = dst_engine->kind();
+ if (!IMPLICATION(s_ek != d_ek, one_of(engine_kind::cpu, s_ek, d_ek)))
+ return invalid_arguments;
+
+ auto r_pd = reinterpret_cast<reorder_pd_t **>(reorder_pd);
+ auto s_mdw = memory_desc_wrapper(*src_md);
+ auto d_mdw = memory_desc_wrapper(*dst_md);
+
+ if (!s_mdw.consistent_with(d_mdw))
+ return invalid_arguments;
+
+ auto e = (s_ek != engine_kind::cpu) ? src_engine : dst_engine;
+
+ const primitive_attr_t dummy_attr;
+ if (attr == NULL)
+ attr = &dummy_attr;
+
+ for (auto r = e->get_reorder_implementation_list(); *r; ++r) {
+ if ((*r)(r_pd, e, attr, src_engine, src_md, dst_engine, dst_md)
+ == success) {
+ (*r_pd)->init_info();
+ (*r_pd)->init_scratchpad_md();
+ return success;
+ }
+ }
+ return unimplemented;
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/reorder_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/reorder_pd.hpp
new file mode 100644
index 0000000000..963cb0f58a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/reorder_pd.hpp
@@ -0,0 +1,85 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef REORDER_PD_HPP
+#define REORDER_PD_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "primitive_attr.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct reorder_pd_t: public primitive_desc_t {
+ reorder_pd_t(engine_t *engine, const primitive_attr_t *attr,
+ engine_t *src_engine, const memory_desc_t *src_md,
+ engine_t *dst_engine, const memory_desc_t *dst_md)
+ : primitive_desc_t(engine, attr, primitive_kind::reorder)
+ , src_engine_(src_engine)
+ , dst_engine_(dst_engine)
+ , scratchpad_engine_(nullptr)
+ , src_md_(*src_md)
+ , dst_md_(*dst_md)
+ {}
+
+ virtual const op_desc_t *op_desc() const override { return nullptr; }
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (arg == MKLDNN_ARG_FROM)
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_TO)
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &src_md_ : nullptr; }
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 ? &dst_md_ : nullptr; }
+
+ virtual int n_inputs() const override { return 1; }
+ virtual int n_outputs() const override { return 1; }
+
+ float alpha() const { return attr()->output_scales_.scales_[0]; }
+ float beta() const {
+ const int sum_idx = attr()->post_ops_.find(primitive_kind::sum);
+ return sum_idx == -1 ? 0 : attr()->post_ops_.entry_[sum_idx].sum.scale;
+ }
+ virtual mkldnn::impl::engine_t *scratchpad_engine() const override
+ { return scratchpad_engine_; }
+
+protected:
+ engine_t *src_engine_;
+ engine_t *dst_engine_;
+ engine_t *scratchpad_engine_;
+
+ memory_desc_t src_md_;
+ memory_desc_t dst_md_;
+};
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/rnn.cpp b/thirdparty/oidn/mkl-dnn/src/common/rnn.cpp
new file mode 100644
index 0000000000..36967431a6
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/rnn.cpp
@@ -0,0 +1,400 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+#include "cpu/gemm/os_blas.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::types;
+using namespace mkldnn::impl::utils;
+
+namespace {
+memory_desc_t copy_maybe_null(const memory_desc_t *md) {
+ return md ? *md : zero_md();
+}
+
+rnn_desc_t zero_rnn_desc() {
+ auto rd = rnn_desc_t();
+ rd.src_layer_desc = zero_md();
+ rd.src_iter_desc = zero_md();
+ rd.weights_layer_desc = zero_md();
+ rd.weights_iter_desc = zero_md();
+ rd.bias_desc = zero_md();
+ rd.dst_layer_desc = zero_md();
+ rd.dst_iter_desc = zero_md();
+ rd.diff_src_layer_desc = zero_md();
+ rd.diff_src_iter_desc = zero_md();
+ rd.diff_weights_layer_desc = zero_md();
+ rd.diff_weights_iter_desc = zero_md();
+ rd.diff_bias_desc = zero_md();
+ rd.diff_dst_layer_desc = zero_md();
+ rd.diff_dst_iter_desc = zero_md();
+ return rd;
+}
+}
+
+/* Public C Api */
+
+status_t mkldnn_rnn_cell_desc_init(rnn_cell_desc_t *rnn_cell_desc,
+ mkldnn_alg_kind_t cell_kind, mkldnn_alg_kind_t act_f,
+ unsigned int flags, float alpha, float clipping) {
+ using namespace mkldnn::impl::alg_kind;
+
+ bool args_ok = true
+ && one_of(cell_kind, vanilla_rnn, vanilla_lstm, vanilla_gru,
+ gru_linear_before_reset)
+ && IMPLICATION(cell_kind == vanilla_rnn,
+ one_of(act_f, eltwise_relu, eltwise_tanh, eltwise_logistic));
+ if (!args_ok)
+ return invalid_arguments;
+
+ auto rcd = mkldnn_rnn_cell_desc_t();
+
+ rcd.cell_kind = cell_kind;
+ rcd.activation_kind = act_f;
+ rcd.flags = flags;
+ rcd.alpha = rcd.flags & mkldnn_rnn_cell_with_relu ? alpha : 0;
+ rcd.clipping = rcd.flags & mkldnn_rnn_cell_with_clipping ? clipping : 0;
+
+ *rnn_cell_desc = rcd;
+
+ return success;
+}
+
+int mkldnn_rnn_cell_get_gates_count(const rnn_cell_desc_t *rnn_cell_desc) {
+ switch (rnn_cell_desc->cell_kind) {
+ case mkldnn::impl::alg_kind::vanilla_rnn: return 1;
+ case mkldnn::impl::alg_kind::vanilla_gru: return 3;
+ case mkldnn::impl::alg_kind::gru_linear_before_reset: return 3;
+ case mkldnn::impl::alg_kind::vanilla_lstm: return 4;
+ default: assert(!"unknown cell kind"); return 0;
+ }
+ return 0;
+}
+
+int mkldnn_rnn_cell_get_states_count(const rnn_cell_desc_t *rnn_cell_desc) {
+ switch (rnn_cell_desc->cell_kind) {
+ case mkldnn::impl::alg_kind::vanilla_rnn: return 1;
+ case mkldnn::impl::alg_kind::vanilla_gru: return 1;
+ case mkldnn::impl::alg_kind::gru_linear_before_reset: return 1;
+ case mkldnn::impl::alg_kind::vanilla_lstm: return 2;
+ default: assert(!"unknown cell kind"); return 0;
+ }
+ return 0;
+}
+
+status_t check_data_type_consistency_fwd(const rnn_cell_desc_t *rnn_cell_desc,
+ prop_kind_t prop_kind, const memory_desc_t *src_layer_desc,
+ const memory_desc_t *src_iter_desc,
+ const memory_desc_t *weights_layer_desc,
+ const memory_desc_t *weights_iter_desc, const memory_desc_t *bias_desc,
+ const memory_desc_t *dst_layer_desc,
+ const memory_desc_t *dst_iter_desc) {
+ using namespace data_type;
+ data_type_t src_layer_dt = src_layer_desc->data_type;
+ data_type_t dst_layer_dt = dst_layer_desc->data_type;
+ data_type_t weights_iter_dt = weights_iter_desc->data_type;
+ data_type_t weights_layer_dt = weights_layer_desc->data_type;
+
+ bool is_f32 = everyone_is(f32, src_layer_dt, dst_layer_dt, weights_iter_dt,
+ weights_layer_dt)
+ && IMPLICATION(!is_zero_md(src_iter_desc),
+ src_iter_desc->data_type == f32)
+ && IMPLICATION(!is_zero_md(dst_iter_desc),
+ dst_iter_desc->data_type == f32)
+ && IMPLICATION(!is_zero_md(bias_desc), bias_desc->data_type == f32);
+
+#if USE_MKL_PACKED_GEMM
+ bool is_u8u8u8 = src_layer_dt == u8
+ && IMPLICATION(!is_zero_md(src_iter_desc),
+ src_iter_desc->data_type == u8)
+ && IMPLICATION(!is_zero_md(dst_iter_desc),
+ dst_iter_desc->data_type == u8)
+ && one_of(dst_layer_dt, u8, f32)
+ && everyone_is(s8, weights_iter_dt, weights_layer_dt)
+ && IMPLICATION(!is_zero_md(bias_desc), bias_desc->data_type == f32);
+
+ bool is_f32u8f32 = src_layer_dt == u8
+ && IMPLICATION(!is_zero_md(src_iter_desc),
+ src_iter_desc->data_type == f32)
+ && IMPLICATION(!is_zero_md(dst_iter_desc),
+ dst_iter_desc->data_type == f32)
+ && one_of(dst_layer_dt, u8, f32)
+ && everyone_is(s8, weights_iter_dt, weights_layer_dt)
+ && IMPLICATION(!is_zero_md(bias_desc), bias_desc->data_type == f32);
+
+ bool is_inference = prop_kind == prop_kind::forward_inference;
+ bool is_lstm = rnn_cell_desc->cell_kind == mkldnn_vanilla_lstm;
+
+ return (is_f32 || ((is_u8u8u8 || is_f32u8f32) && is_lstm && is_inference))
+ ? success
+ : unimplemented;
+#else
+ return is_f32 ? success : unimplemented;
+#endif
+}
+
+status_t check_dim_consistency(const rnn_cell_desc_t *rnn_cell_desc,
+ rnn_direction_t direction, int L, int D, int T, int N, int S, int G,
+ int SLC, int SIC, int DLC, int DIC, const memory_desc_t *src_layer_desc,
+ const memory_desc_t *src_iter_desc,
+ const memory_desc_t *weights_layer_desc,
+ const memory_desc_t *weights_iter_desc, const memory_desc_t *bias_desc,
+ const memory_desc_t *dst_layer_desc,
+ const memory_desc_t *dst_iter_desc) {
+ bool args_ok;
+
+ // * algorithm specific
+ args_ok = true
+ && IMPLICATION(rnn_cell_desc->cell_kind == alg_kind::vanilla_gru,
+ DIC == SIC);
+ if (!args_ok) return invalid_arguments;
+ int extra_bias =
+ rnn_cell_desc->cell_kind == alg_kind::gru_linear_before_reset;
+
+ // * on num layers
+ args_ok = true
+ && L == weights_layer_desc->dims[0]
+ && L == weights_iter_desc->dims[0]
+ && IMPLICATION(!is_zero_md(bias_desc), L == bias_desc->dims[0])
+ && IMPLICATION(!is_zero_md(src_iter_desc), L == src_iter_desc->dims[0])
+ && IMPLICATION(!is_zero_md(dst_iter_desc), L == dst_iter_desc->dims[0]);
+ if (!args_ok) return invalid_arguments;
+
+ // * on num directions
+ args_ok = true
+ && D == weights_layer_desc->dims[1]
+ && D == weights_iter_desc->dims[1]
+ && IMPLICATION(!is_zero_md(bias_desc), D == bias_desc->dims[1])
+ && IMPLICATION(!is_zero_md(src_iter_desc), D == src_iter_desc->dims[1])
+ && IMPLICATION(!is_zero_md(dst_iter_desc), D == dst_iter_desc->dims[1]);
+ if (!args_ok) return invalid_arguments;
+
+ // * on num iterations
+ args_ok = true
+ && T == src_layer_desc->dims[0]
+ && T == dst_layer_desc->dims[0];
+ if (!args_ok) return invalid_arguments;
+
+ // * on mb
+ args_ok = true
+ && N == src_layer_desc->dims[1]
+ && N == dst_layer_desc->dims[1]
+ && IMPLICATION(!is_zero_md(src_iter_desc), N == src_iter_desc->dims[3])
+ && IMPLICATION(!is_zero_md(dst_iter_desc), N == dst_iter_desc->dims[3]);
+ if (!args_ok) return invalid_arguments;
+
+ // * on num gates
+ args_ok = true
+ && G == mkldnn_rnn_cell_get_gates_count(rnn_cell_desc)
+ && G == weights_layer_desc->dims[3]
+ && G == weights_iter_desc->dims[3]
+ && IMPLICATION(!is_zero_md(bias_desc),
+ G + extra_bias == bias_desc->dims[2]);
+ if (!args_ok) return invalid_arguments;
+
+ // * on num states
+ args_ok = true
+ && S == mkldnn_rnn_cell_get_states_count(rnn_cell_desc)
+ && IMPLICATION(!is_zero_md(src_iter_desc), S == src_iter_desc->dims[2])
+ && IMPLICATION(!is_zero_md(dst_iter_desc), S == dst_iter_desc->dims[2]);
+ if (!args_ok) return invalid_arguments;
+
+ // * on slc
+ args_ok = true
+ && SLC == weights_layer_desc->dims[2]
+ && SLC == src_layer_desc->dims[2];
+ if (!args_ok) return invalid_arguments;
+
+ // * on sic
+ args_ok = true
+ && SIC == weights_iter_desc->dims[2]
+ && IMPLICATION(!is_zero_md(src_iter_desc),
+ SIC == src_iter_desc->dims[4]);
+ if (!args_ok) return invalid_arguments;
+
+ // * on dlc
+ int dlc_multiplier = (direction == mkldnn_bidirectional_concat) ? 2 : 1;
+ args_ok = true
+ && DLC == dlc_multiplier * DIC
+ && DLC == dst_layer_desc->dims[2];
+ if (!args_ok) return invalid_arguments;
+
+ // * on dic
+ args_ok = true
+ && DIC == weights_layer_desc->dims[4]
+ && DIC == weights_iter_desc->dims[4]
+ && IMPLICATION(!is_zero_md(bias_desc), DIC == bias_desc->dims[3])
+ && IMPLICATION(!is_zero_md(dst_iter_desc),
+ DIC == dst_iter_desc->dims[4]);
+ if (!args_ok) return invalid_arguments;
+
+ // * unrolling/fusion conditions
+ args_ok = true
+ && IMPLICATION(L > 1, (dlc_multiplier * SLC) == DLC)
+ && IMPLICATION(T > 1, SIC == DIC);
+ if (!args_ok) return invalid_arguments;
+
+ return success;
+}
+
+status_t MKLDNN_API mkldnn_rnn_forward_desc_init(mkldnn_rnn_desc_t *rnn_desc,
+ prop_kind_t prop_kind, const rnn_cell_desc_t *rnn_cell_desc,
+ const rnn_direction_t direction, const memory_desc_t *src_layer_desc,
+ const memory_desc_t *src_iter_desc,
+ const memory_desc_t *weights_layer_desc,
+ const memory_desc_t *weights_iter_desc, const memory_desc_t *bias_desc,
+ const memory_desc_t *dst_layer_desc,
+ const memory_desc_t *dst_iter_desc) {
+ bool args_ok = true && rnn_cell_desc != nullptr
+ && !any_null(src_layer_desc, weights_layer_desc, weights_iter_desc,
+ dst_layer_desc);
+ if (!args_ok) return invalid_arguments;
+
+ //check dimensions consistency
+ int L = weights_layer_desc->dims[0];
+ int T = src_layer_desc->dims[0];
+ int N = src_layer_desc->dims[1];
+ const int D = one_of(direction, mkldnn_unidirectional_left2right,
+ mkldnn_unidirectional_right2left) ?
+ 1 :
+ 2;
+ int G = mkldnn_rnn_cell_get_gates_count(rnn_cell_desc);
+ int S = mkldnn_rnn_cell_get_states_count(rnn_cell_desc);
+ int SLC = src_layer_desc->dims[2];
+ int SIC = weights_iter_desc->dims[2];
+ int DLC = dst_layer_desc->dims[2];
+ int DIC = weights_layer_desc->dims[4];
+
+ CHECK(check_dim_consistency(rnn_cell_desc, direction, L, D, T, N, S,
+ G, SLC, SIC, DLC, DIC, src_layer_desc, src_iter_desc,
+ weights_layer_desc, weights_iter_desc, bias_desc, dst_layer_desc,
+ dst_iter_desc));
+
+ CHECK(check_data_type_consistency_fwd(rnn_cell_desc, prop_kind,
+ src_layer_desc, src_iter_desc, weights_layer_desc,
+ weights_iter_desc, bias_desc, dst_layer_desc, dst_iter_desc));
+
+ // Create the descriptor
+ mkldnn_rnn_desc_t rd = zero_rnn_desc();
+
+ rd.primitive_kind = primitive_kind::rnn;
+ rd.prop_kind = prop_kind;
+ rd.cell_desc = *rnn_cell_desc;
+ rd.direction = direction;
+ rd.src_layer_desc = copy_maybe_null(src_layer_desc);
+ rd.src_iter_desc = copy_maybe_null(src_iter_desc);
+ rd.weights_layer_desc = copy_maybe_null(weights_layer_desc);
+ rd.weights_iter_desc = copy_maybe_null(weights_iter_desc);
+ rd.bias_desc = copy_maybe_null(bias_desc);
+ rd.dst_layer_desc = copy_maybe_null(dst_layer_desc);
+ rd.dst_iter_desc = copy_maybe_null(dst_iter_desc);
+
+ *rnn_desc = rd;
+
+ return success;
+}
+
+status_t MKLDNN_API mkldnn_rnn_backward_desc_init(mkldnn_rnn_desc_t *rnn_desc,
+ prop_kind_t prop_kind, const rnn_cell_desc_t *rnn_cell_desc,
+ const rnn_direction_t direction, const memory_desc_t *src_layer_desc,
+ const memory_desc_t *src_iter_desc,
+ const memory_desc_t *weights_layer_desc,
+ const memory_desc_t *weights_iter_desc, const memory_desc_t *bias_desc,
+ const memory_desc_t *dst_layer_desc, const memory_desc_t *dst_iter_desc,
+ const memory_desc_t *diff_src_layer_desc,
+ const memory_desc_t *diff_src_iter_desc,
+ const memory_desc_t *diff_weights_layer_desc,
+ const memory_desc_t *diff_weights_iter_desc,
+ const memory_desc_t *diff_bias_desc,
+ const memory_desc_t *diff_dst_layer_desc,
+ const memory_desc_t *diff_dst_iter_desc) {
+ bool args_ok = true
+ && !any_null(src_layer_desc, weights_layer_desc, weights_iter_desc,
+ dst_layer_desc, diff_src_layer_desc,
+ diff_weights_layer_desc, diff_weights_iter_desc,
+ diff_dst_layer_desc);
+ if (!args_ok)
+ return invalid_arguments;
+
+ auto xnor_md = [=](const memory_desc_t *a_md, const memory_desc_t *b_md) {
+ return is_zero_md(a_md) == is_zero_md(b_md);
+ };
+
+ args_ok = args_ok && xnor_md(bias_desc, diff_bias_desc)
+ && xnor_md(dst_iter_desc, diff_dst_iter_desc)
+ && xnor_md(src_iter_desc, diff_src_iter_desc);
+ if (!args_ok)
+ return invalid_arguments;
+
+ //check dimensions consistency
+ int L = weights_layer_desc->dims[0];
+ int T = src_layer_desc->dims[0];
+ int N = src_layer_desc->dims[1];
+ const int D = one_of(direction, mkldnn_unidirectional_left2right,
+ mkldnn_unidirectional_right2left) ?
+ 1 :
+ 2;
+ int G = mkldnn_rnn_cell_get_gates_count(rnn_cell_desc);
+ int S = mkldnn_rnn_cell_get_states_count(rnn_cell_desc);
+ int SLC = src_layer_desc->dims[2];
+ int SIC = weights_iter_desc->dims[2];
+ int DLC = dst_layer_desc->dims[2];
+ int DIC = weights_layer_desc->dims[4];
+
+ status_t st = check_dim_consistency(rnn_cell_desc, direction, L, D, T, N, S,
+ G, SLC, SIC, DLC, DIC, src_layer_desc, src_iter_desc,
+ weights_layer_desc, weights_iter_desc, bias_desc, dst_layer_desc,
+ dst_iter_desc);
+ if (st != success) return st;
+
+ st = check_dim_consistency(rnn_cell_desc, direction, L, D, T, N, S,
+ G, SLC, SIC, DLC, DIC, diff_src_layer_desc, diff_src_iter_desc,
+ diff_weights_layer_desc, diff_weights_iter_desc, diff_bias_desc,
+ diff_dst_layer_desc, diff_dst_iter_desc);
+ if (st != success) return st;
+
+ mkldnn_rnn_desc_t rd = zero_rnn_desc();
+
+ rd.primitive_kind = primitive_kind::rnn;
+ rd.prop_kind = prop_kind;
+ rd.cell_desc = *rnn_cell_desc;
+ rd.direction = direction;
+
+ rd.src_layer_desc = copy_maybe_null(src_layer_desc);
+ rd.src_iter_desc = copy_maybe_null(src_iter_desc);
+ rd.weights_layer_desc = copy_maybe_null(weights_layer_desc);
+ rd.weights_iter_desc = copy_maybe_null(weights_iter_desc);
+ rd.bias_desc = copy_maybe_null(bias_desc);
+ rd.dst_layer_desc = copy_maybe_null(dst_layer_desc);
+ rd.dst_iter_desc = copy_maybe_null(dst_iter_desc);
+ rd.diff_src_layer_desc = copy_maybe_null(diff_src_layer_desc);
+ rd.diff_src_iter_desc = copy_maybe_null(diff_src_iter_desc);
+ rd.diff_weights_layer_desc = copy_maybe_null(diff_weights_layer_desc);
+ rd.diff_weights_iter_desc = copy_maybe_null(diff_weights_iter_desc);
+ rd.diff_bias_desc = copy_maybe_null(diff_bias_desc);
+ rd.diff_dst_layer_desc = copy_maybe_null(diff_dst_layer_desc);
+ rd.diff_dst_iter_desc = copy_maybe_null(diff_dst_iter_desc);
+
+ *rnn_desc = rd;
+
+ return success;
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/rnn_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/rnn_pd.hpp
new file mode 100644
index 0000000000..1ee2ba1114
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/rnn_pd.hpp
@@ -0,0 +1,280 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef RNN_PD_HPP
+#define RNN_PD_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "primitive_desc.hpp"
+#include "type_helpers.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct rnn_fwd_pd_t;
+
+struct rnn_pd_t : public primitive_desc_t {
+ static constexpr auto base_pkind = primitive_kind::rnn;
+
+ rnn_pd_t(engine_t *engine,
+ const rnn_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const rnn_fwd_pd_t *hint_fwd_pd)
+ : primitive_desc_t(engine, attr, base_pkind)
+ , desc_(*adesc)
+ , hint_fwd_pd_(hint_fwd_pd)
+ , src_layer_md_(desc_.src_layer_desc)
+ , src_iter_md_(desc_.src_iter_desc)
+ , weights_layer_md_(desc_.weights_layer_desc)
+ , weights_iter_md_(desc_.weights_iter_desc)
+ , bias_md_(desc_.bias_desc)
+ , dst_layer_md_(desc_.dst_layer_desc)
+ , dst_iter_md_(desc_.dst_iter_desc)
+ , ws_md_()
+ {}
+
+ const rnn_desc_t *desc() const { return &desc_; }
+ virtual const op_desc_t *op_desc() const override
+ { return reinterpret_cast<const op_desc_t *>(this->desc()); }
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual status_t query(query_t what, int idx, void *result) const override {
+ switch (what) {
+ case query::rnn_d: *(const rnn_desc_t **)result = desc(); break;
+ default: return primitive_desc_t::query(what, idx, result);
+ }
+ return status::success;
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override {
+ if (index == 0) return &src_layer_md_;
+ if (index == 1 && with_src_iter()) return &src_iter_md_;
+ return nullptr;
+ }
+ virtual const memory_desc_t *weights_md(int index = 0) const override {
+ if (index == 0) return &weights_layer_md_;
+ if (index == 1) return &weights_iter_md_;
+ if (index == 2 && with_bias()) return &bias_md_;
+ return nullptr;
+ }
+ virtual const memory_desc_t *dst_md(int index = 0) const override {
+ if (index == 0) return &dst_layer_md_;
+ if (index == 1 && with_dst_iter()) return &dst_iter_md_;
+ return nullptr;
+ }
+ virtual const memory_desc_t *workspace_md(int index = 0) const override
+ { return index == 0 && !types::is_zero_md(&ws_md_) ? &ws_md_ : nullptr; }
+
+ /* common pooling aux functions */
+
+ bool is_training() const {
+ return utils::one_of(desc_.prop_kind, prop_kind::forward_training,
+ prop_kind::backward);
+ }
+
+ bool is_fwd() const {
+ return utils::one_of(desc_.prop_kind, prop_kind::forward_training,
+ prop_kind::forward_inference);
+ }
+
+ dim_t T() const { return desc_.src_layer_desc.dims[0]; }
+ dim_t MB() const { return desc_.src_layer_desc.dims[1]; }
+
+ dim_t L() const { return desc_.weights_layer_desc.dims[0]; }
+ dim_t D() const { return desc_.weights_layer_desc.dims[1]; }
+
+ dim_t SIC() const { return desc_.weights_iter_desc.dims[2]; }
+
+ dim_t SLC() const { return desc_.weights_layer_desc.dims[2]; }
+ dim_t G() const { return desc_.weights_layer_desc.dims[3]; }
+ dim_t DIC() const { return desc_.weights_layer_desc.dims[4]; }
+
+ dim_t DLC() const { return desc_.dst_layer_desc.dims[2]; }
+
+ bool with_bias() const
+ { return !memory_desc_wrapper(desc_.bias_desc).is_zero(); }
+
+ bool with_src_iter() const
+ { return !(memory_desc_wrapper(desc_.src_iter_desc).is_zero()); }
+
+ bool with_dst_iter() const
+ { return !memory_desc_wrapper(desc_.dst_iter_desc).is_zero(); }
+
+ mkldnn::impl::alg_kind_t cell_kind() const
+ { return desc_.cell_desc.cell_kind; }
+ mkldnn::impl::alg_kind_t activation_kind() const
+ { return desc_.cell_desc.activation_kind; }
+
+ bool is_lbr() const
+ { return cell_kind() == mkldnn_gru_linear_before_reset; }
+
+ mkldnn_rnn_direction_t direction() const { return desc_.direction; }
+
+protected:
+ rnn_desc_t desc_;
+ const rnn_fwd_pd_t *hint_fwd_pd_;
+
+ memory_desc_t src_layer_md_;
+ memory_desc_t src_iter_md_;
+ memory_desc_t weights_layer_md_;
+ memory_desc_t weights_iter_md_;
+ memory_desc_t bias_md_;
+ memory_desc_t dst_layer_md_;
+ memory_desc_t dst_iter_md_;
+
+ memory_desc_t ws_md_;
+};
+
+struct rnn_fwd_pd_t: public rnn_pd_t {
+ typedef rnn_fwd_pd_t base_class;
+ typedef rnn_fwd_pd_t hint_class;
+
+ rnn_fwd_pd_t(engine_t *engine,
+ const rnn_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const rnn_fwd_pd_t *hint_fwd_pd)
+ : rnn_pd_t(engine, adesc, attr, hint_fwd_pd)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (arg == MKLDNN_ARG_SRC_LAYER)
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_SRC_ITER && with_src_iter())
+ return arg_usage_t::input;
+
+ if (utils::one_of(arg, MKLDNN_ARG_WEIGHTS_LAYER,
+ MKLDNN_ARG_WEIGHTS_ITER))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_BIAS && with_bias())
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DST_LAYER)
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_DST_ITER && with_dst_iter())
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_WORKSPACE && is_training())
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual int n_inputs() const override
+ { return 3 + with_bias() + with_src_iter(); }
+ virtual int n_outputs() const override
+ { return 1 + with_dst_iter() + is_training(); }
+};
+
+struct rnn_bwd_pd_t : public rnn_pd_t {
+ typedef rnn_bwd_pd_t base_class;
+ typedef rnn_fwd_pd_t hint_class;
+
+ rnn_bwd_pd_t(engine_t *engine,
+ const rnn_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const rnn_fwd_pd_t *hint_fwd_pd)
+ : rnn_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , diff_src_layer_md_(desc_.diff_src_layer_desc)
+ , diff_src_iter_md_(desc_.diff_src_iter_desc)
+ , diff_weights_layer_md_(desc_.diff_weights_layer_desc)
+ , diff_weights_iter_md_(desc_.diff_weights_iter_desc)
+ , diff_bias_md_(desc_.diff_bias_desc)
+ , diff_dst_layer_md_(desc_.diff_dst_layer_desc)
+ , diff_dst_iter_md_(desc_.diff_dst_iter_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_SRC_LAYER, MKLDNN_ARG_DST_LAYER,
+ MKLDNN_ARG_DIFF_DST_LAYER))
+ return arg_usage_t::input;
+
+ if (with_src_iter()) {
+ if (arg == MKLDNN_ARG_SRC_ITER)
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_SRC_ITER)
+ return arg_usage_t::output;
+ }
+
+ if (utils::one_of(arg, MKLDNN_ARG_WEIGHTS_LAYER,
+ MKLDNN_ARG_WEIGHTS_ITER))
+ return arg_usage_t::input;
+
+ if (with_bias()) {
+ if (arg == MKLDNN_ARG_BIAS)
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_BIAS)
+ return arg_usage_t::output;
+ }
+
+ if (utils::one_of(arg, MKLDNN_ARG_DST_ITER, MKLDNN_ARG_DIFF_DST_ITER)
+ && with_dst_iter())
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_WORKSPACE)
+ return arg_usage_t::input;
+
+ if (utils::one_of(arg, MKLDNN_ARG_DIFF_SRC_LAYER,
+ MKLDNN_ARG_DIFF_WEIGHTS_LAYER,
+ MKLDNN_ARG_DIFF_WEIGHTS_ITER))
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *diff_src_md(int index = 0) const override {
+ if (index == 0) return &diff_src_layer_md_;
+ if (index == 1 && with_src_iter()) return &diff_src_iter_md_;
+ return nullptr;
+ }
+ virtual const memory_desc_t *diff_weights_md(
+ int index = 0) const override {
+ if (index == 0) return &diff_weights_layer_md_;
+ if (index == 1) return &diff_weights_iter_md_;
+ if (index == 2 && with_bias()) return &diff_bias_md_;
+ return nullptr;
+ }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override {
+ if (index == 0) return &diff_dst_layer_md_;
+ if (index == 1 && with_dst_iter()) return &diff_dst_iter_md_;
+ return nullptr;
+ }
+
+ virtual int n_inputs() const override
+ { return 6 + with_src_iter() + with_bias() + 2 * with_dst_iter(); }
+ virtual int n_outputs() const override
+ { return 3 + with_src_iter() + with_bias(); }
+
+protected:
+ memory_desc_t diff_src_layer_md_;
+ memory_desc_t diff_src_iter_md_;
+ memory_desc_t diff_weights_layer_md_;
+ memory_desc_t diff_weights_iter_md_;
+ memory_desc_t diff_bias_md_;
+ memory_desc_t diff_dst_layer_md_;
+ memory_desc_t diff_dst_iter_md_;
+};
+
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/scratchpad.cpp b/thirdparty/oidn/mkl-dnn/src/common/scratchpad.cpp
new file mode 100644
index 0000000000..6bc14fc72a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/scratchpad.cpp
@@ -0,0 +1,112 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "scratchpad.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+/* Allocating memory buffers on a page boundary to reduce TLB/page misses */
+const size_t page_size = 2097152;
+
+/*
+ Implementation of the scratchpad_t interface that is compatible with
+ a concurrent execution
+*/
+struct concurent_scratchpad_t : public scratchpad_t {
+ concurent_scratchpad_t(size_t size) {
+ size_ = size;
+ scratchpad_ = (char *) malloc(size, page_size);
+ assert(scratchpad_ != nullptr);
+ }
+
+ ~concurent_scratchpad_t() {
+ free(scratchpad_);
+ }
+
+ virtual char *get() const {
+ return scratchpad_;
+ }
+
+private:
+ char *scratchpad_;
+ size_t size_;
+};
+
+/*
+ Implementation of the scratchpad_t interface that uses a global
+ scratchpad
+*/
+
+struct global_scratchpad_t : public scratchpad_t {
+ global_scratchpad_t(size_t size) {
+ if (size > size_) {
+ if (scratchpad_ != nullptr) free(scratchpad_);
+ size_ = size;
+ scratchpad_ = (char *) malloc(size, page_size);
+ assert(scratchpad_ != nullptr);
+ }
+ reference_count_++;
+ }
+
+ ~global_scratchpad_t() {
+ reference_count_--;
+ if (reference_count_ == 0) {
+ free(scratchpad_);
+ scratchpad_ = nullptr;
+ size_ = 0;
+ }
+ }
+
+ virtual char *get() const {
+ return scratchpad_;
+ }
+
+private:
+ /*
+ Using thread-local here is unnecessary and even buggy! All threads
+ actually share the same scratchpad, which is created and queried only
+ on the main thread. If the scratchpad is queried on some thread other
+ than the one it was created on (e.g. the application calls the API from
+ multiple threads), thread-local causes a segfault because the scratchpad
+ is uninitialized on the current thread.
+ */
+ /*thread_local*/ static char *scratchpad_;
+ /*thread_local*/ static size_t size_;
+ /*thread_local*/ static unsigned int reference_count_;
+};
+
+/*thread_local*/ char *global_scratchpad_t::scratchpad_ = nullptr;
+/*thread_local*/ size_t global_scratchpad_t::size_ = 0;
+/*thread_local*/ unsigned int global_scratchpad_t::reference_count_ = 0;
+
+
+/*
+ Scratchpad creation routine
+*/
+scratchpad_t *create_scratchpad(size_t size) {
+#ifndef MKLDNN_ENABLE_CONCURRENT_EXEC
+ return new global_scratchpad_t(size);
+#else
+ return new concurent_scratchpad_t(size);
+#endif
+}
+
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/scratchpad.hpp b/thirdparty/oidn/mkl-dnn/src/common/scratchpad.hpp
new file mode 100644
index 0000000000..f7a246bc99
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/scratchpad.hpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef COMMON_SCRATCHPAD_HPP
+#define COMMON_SCRATCHPAD_HPP
+
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct scratchpad_t {
+ virtual ~scratchpad_t() {}
+ virtual char *get() const = 0;
+};
+
+scratchpad_t *create_scratchpad(size_t size);
+
+}
+}
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/shuffle.cpp b/thirdparty/oidn/mkl-dnn/src/common/shuffle.cpp
new file mode 100644
index 0000000000..e32e735224
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/shuffle.cpp
@@ -0,0 +1,72 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::types;
+
+namespace {
+status_t shuffle_desc_init(shuffle_desc_t *shuffle_desc, prop_kind_t prop_kind,
+ const memory_desc_t *data_desc, int axis, dim_t group_size) {
+ bool args_ok = true
+ && !any_null(shuffle_desc, data_desc)
+ && one_of(prop_kind, forward_training, forward_inference,
+ backward, backward_data)
+ && axis >= 0 && axis < data_desc->ndims
+ && group_size > 0 && group_size <= data_desc->dims[axis];
+ if (!args_ok) return invalid_arguments;
+
+ auto sd = shuffle_desc_t();
+ sd.primitive_kind = primitive_kind::shuffle;
+ sd.prop_kind = prop_kind;
+ sd.data_desc = *data_desc;
+ sd.axis = axis;
+ sd.group_size = group_size;
+
+ bool consistency = true
+ && sd.data_desc.dims[axis] % sd.group_size == 0;
+ if (!consistency) return invalid_arguments;
+
+ *shuffle_desc = sd;
+ return success;
+}
+}
+
+status_t mkldnn_shuffle_forward_desc_init(shuffle_desc_t *shuffle_desc,
+ prop_kind_t prop_kind, const memory_desc_t *data_desc, int axis,
+ dim_t group_size) {
+ if (!one_of(prop_kind, forward_training, forward_inference))
+ return invalid_arguments;
+ return shuffle_desc_init(shuffle_desc, prop_kind, data_desc, axis,
+ group_size);
+}
+
+status_t mkldnn_shuffle_backward_desc_init(shuffle_desc_t *shuffle_desc,
+ const memory_desc_t *diff_data_desc, int axis, dim_t group_size) {
+ return shuffle_desc_init(shuffle_desc, backward_data, diff_data_desc, axis,
+ group_size);
+}
+
+// vim: et ts=5 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/shuffle_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/shuffle_pd.hpp
new file mode 100644
index 0000000000..cc5553fe7f
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/shuffle_pd.hpp
@@ -0,0 +1,121 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef SHUFFLE_PD_HPP
+#define SHUFFLE_PD_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "primitive_desc.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct shuffle_pd_t: public primitive_desc_t {
+ static constexpr auto base_pkind = primitive_kind::shuffle;
+
+ typedef shuffle_pd_t base_class;
+ typedef shuffle_pd_t hint_class;
+
+ shuffle_pd_t(engine_t *engine,
+ const shuffle_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const shuffle_pd_t *hint_fwd_pd)
+ : primitive_desc_t(engine, attr, base_pkind)
+ , desc_(*adesc)
+ , hint_fwd_pd_(hint_fwd_pd)
+ , data_md_(desc_.data_desc)
+ {}
+
+ const shuffle_desc_t *desc() const { return &desc_; }
+ virtual const op_desc_t *op_desc() const override
+ { return reinterpret_cast<const op_desc_t *>(this->desc()); }
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual status_t query(query_t what, int idx, void *result) const override {
+ switch (what) {
+ case query::shuffle_d:
+ *(const shuffle_desc_t**)result = desc(); break;
+ default: return primitive_desc_t::query(what, idx, result);
+ }
+ return status::success;
+ }
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (is_fwd()) {
+ if (arg == MKLDNN_ARG_SRC)
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DST)
+ return arg_usage_t::output;
+ } else {
+ if (arg == MKLDNN_ARG_DIFF_DST)
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_SRC)
+ return arg_usage_t::output;
+ }
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 && is_fwd() ? &data_md_ : nullptr; }
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 && is_fwd() ? &data_md_ : nullptr; }
+
+ virtual const memory_desc_t *diff_src_md(int index = 0) const override
+ { return index == 0 && !is_fwd() ? &data_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 && !is_fwd() ? &data_md_ : nullptr; }
+
+ virtual int n_inputs() const override { return 1; }
+ virtual int n_outputs() const override { return 1; }
+
+ /* shuffle aux functions */
+
+ dim_t MB() const { return data_md()->dims[0]; }
+ dim_t C() const { return ndims() >= 2 ? data_md()->dims[1] : 1; }
+ dim_t D() const { return ndims() >= 5 ? data_md()->dims[ndims() - 3] : 1; }
+ dim_t H() const { return ndims() >= 4 ? data_md()->dims[ndims() - 2] : 1; }
+ dim_t W() const { return ndims() >= 3 ? data_md()->dims[ndims() - 1] : 1; }
+
+ int ndims() const { return data_md()->ndims; }
+
+ int axis() const { return desc_.axis; }
+ dim_t group_size() const { return desc_.group_size; }
+ dim_t axis_size() const { return data_md()->dims[axis()]; }
+
+ bool is_fwd() const {
+ return utils::one_of(desc_.prop_kind, prop_kind::forward_training,
+ prop_kind::forward_inference);
+ }
+
+ const memory_desc_t *data_md() const { return &data_md_; }
+
+protected:
+ shuffle_desc_t desc_;
+ const shuffle_pd_t *hint_fwd_pd_;
+ memory_desc_t data_md_;
+};
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/softmax.cpp b/thirdparty/oidn/mkl-dnn/src/common/softmax.cpp
new file mode 100644
index 0000000000..82848e3d1f
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/softmax.cpp
@@ -0,0 +1,68 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "memory_desc_wrapper.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::alg_kind;
+using namespace mkldnn::impl::types;
+
+namespace {
+status_t softmax_desc_init(softmax_desc_t *softmax_desc, prop_kind_t prop_kind,
+ const memory_desc_t *data_desc, const memory_desc_t *diff_desc, int softmax_axis) {
+ bool args_ok = true
+ && !any_null(softmax_desc, data_desc)
+ && 0 <= softmax_axis
+ && softmax_axis < data_desc->ndims;
+ if (!args_ok) return invalid_arguments;
+
+ auto sd = softmax_desc_t();
+ sd.primitive_kind = primitive_kind::softmax;
+ sd.prop_kind = prop_kind;
+
+ bool is_bwd = (sd.prop_kind == backward_data);
+ sd.data_desc = *data_desc;
+ sd.diff_desc = is_bwd ? *diff_desc : zero_md();
+ sd.softmax_axis = softmax_axis;
+
+ *softmax_desc = sd;
+ return success;
+}
+}
+
+status_t mkldnn_softmax_forward_desc_init(softmax_desc_t *softmax_desc,
+ prop_kind_t prop_kind, const memory_desc_t *data_desc,
+ int softmax_axis) {
+ if (!one_of(prop_kind, forward_inference, forward_training))
+ return invalid_arguments;
+ return softmax_desc_init(softmax_desc, prop_kind, data_desc, nullptr, softmax_axis);
+}
+
+status_t mkldnn_softmax_backward_desc_init(softmax_desc_t *softmax_desc,
+ const memory_desc_t *diff_desc, const mkldnn_memory_desc_t *data_desc,
+ int softmax_axis) {
+ return softmax_desc_init(softmax_desc, prop_kind::backward_data,
+ data_desc, diff_desc, softmax_axis);
+}
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/softmax_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/softmax_pd.hpp
new file mode 100644
index 0000000000..8a16ce901c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/softmax_pd.hpp
@@ -0,0 +1,161 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef SOFTMAX_PD_HPP
+#define SOFTMAX_PD_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "primitive_desc.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct softmax_fwd_pd_t;
+
+struct softmax_pd_t: public primitive_desc_t {
+ static constexpr auto base_pkind = primitive_kind::softmax;
+
+ softmax_pd_t(engine_t *engine,
+ const softmax_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const softmax_fwd_pd_t *hint_fwd_pd)
+ : primitive_desc_t(engine, attr, base_pkind)
+ , desc_(*adesc)
+ , hint_fwd_pd_(hint_fwd_pd)
+ , data_md_(desc_.data_desc)
+ {}
+
+ const softmax_desc_t *desc() const { return &desc_; }
+ virtual const op_desc_t *op_desc() const override
+ { return reinterpret_cast<const op_desc_t *>(this->desc()); }
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual status_t query(query_t what, int idx, void *result) const override {
+ switch (what) {
+ case query::softmax_d:
+ *(const softmax_desc_t**)result = desc(); break;
+ default: return primitive_desc_t::query(what, idx, result);
+ }
+ return status::success;
+ }
+
+ /* common softmax aux functions */
+
+ dim_t MB() const { return data_desc().dims[0]; }
+ dim_t C() const { return data_desc().dims[1]; }
+ dim_t D() const { return ndims() >= 5 ? data_desc().dims[ndims() - 3] : 1; }
+ dim_t H() const { return ndims() >= 4 ? data_desc().dims[ndims() - 2] : 1; }
+ dim_t W() const { return ndims() >= 3 ? data_desc().dims[ndims() - 1] : 1; }
+
+ int ndims() const { return data_desc().ndims; }
+
+ bool is_fwd() const {
+ return utils::one_of(desc_.prop_kind, prop_kind::forward_training,
+ prop_kind::forward_inference);
+ }
+
+protected:
+ softmax_desc_t desc_;
+ const softmax_fwd_pd_t *hint_fwd_pd_;
+
+ memory_desc_t data_md_;
+
+private:
+ const memory_desc_t &data_desc() const { return desc_.data_desc; }
+};
+
+struct softmax_fwd_pd_t: public softmax_pd_t {
+ typedef softmax_fwd_pd_t base_class;
+ typedef softmax_fwd_pd_t hint_class;
+
+ softmax_fwd_pd_t(engine_t *engine,
+ const softmax_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const softmax_fwd_pd_t *hint_fwd_pd)
+ : softmax_pd_t(engine, adesc, attr, hint_fwd_pd)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (arg == MKLDNN_ARG_SRC)
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DST)
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_WORKSPACE && (workspace_md() != nullptr))
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index == 0 ? &data_md_ : nullptr; }
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 ? &data_md_ : nullptr; }
+
+ virtual int n_inputs() const override { return 1; }
+ virtual int n_outputs() const override
+ { return 1 + (workspace_md() != nullptr); }
+};
+
+struct softmax_bwd_pd_t: public softmax_pd_t {
+ typedef softmax_bwd_pd_t base_class;
+ typedef softmax_fwd_pd_t hint_class;
+
+ softmax_bwd_pd_t(engine_t *engine,
+ const softmax_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const softmax_fwd_pd_t *hint_fwd_pd)
+ : softmax_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , diff_data_md_(desc_.diff_desc)
+ {}
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (utils::one_of(arg, MKLDNN_ARG_DST, MKLDNN_ARG_DIFF_DST))
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DIFF_SRC)
+ return arg_usage_t::output;
+
+ if (arg == MKLDNN_ARG_WORKSPACE && (workspace_md() != nullptr))
+ return arg_usage_t::input;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 ? &data_md_ : nullptr; }
+ virtual const memory_desc_t *diff_dst_md(int index = 0) const override
+ { return index == 0 ? &diff_data_md_ : nullptr; }
+ virtual const memory_desc_t *diff_src_md(int index = 0) const override
+ { return index == 0 ? &diff_data_md_ : nullptr; }
+
+ virtual int n_inputs() const override
+ { return 2 + (workspace_md() != nullptr); }
+ virtual int n_outputs() const override { return 1; }
+
+protected:
+ memory_desc_t diff_data_md_;
+};
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/stream.cpp b/thirdparty/oidn/mkl-dnn/src/common/stream.cpp
new file mode 100644
index 0000000000..00af8935c0
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/stream.cpp
@@ -0,0 +1,46 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "engine.hpp"
+#include "stream.hpp"
+#include "utils.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::status;
+
+/* API */
+
+status_t mkldnn_stream_create(stream_t **stream, engine_t *engine,
+ unsigned flags) {
+ bool args_ok = true
+ && !utils::any_null(stream, engine)
+ && flags == stream_flags::default_flags;
+ if (!args_ok)
+ return invalid_arguments;
+
+ return safe_ptr_assign<stream_t>(*stream, new stream_t(engine, flags));
+}
+
+status_t mkldnn_stream_destroy(stream_t *stream) {
+ delete stream;
+ return success;
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/stream.hpp b/thirdparty/oidn/mkl-dnn/src/common/stream.hpp
new file mode 100644
index 0000000000..f010e5f6ed
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/stream.hpp
@@ -0,0 +1,44 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef STREAM_HPP
+#define STREAM_HPP
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "engine.hpp"
+
+struct mkldnn_stream: public mkldnn::impl::c_compatible {
+ mkldnn_stream(mkldnn::impl::engine_t *engine, unsigned flags)
+ : engine_(engine), flags_(flags) {}
+ virtual ~mkldnn_stream() {}
+
+ /** returns stream's engine */
+ mkldnn::impl::engine_t *engine() const { return engine_; }
+
+ /** returns stream's kind */
+ unsigned flags() const { return flags_; }
+
+protected:
+ mkldnn::impl::engine_t *engine_;
+ unsigned flags_;
+};
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/sum.cpp b/thirdparty/oidn/mkl-dnn/src/common/sum.cpp
new file mode 100644
index 0000000000..365663c0f8
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/sum.cpp
@@ -0,0 +1,79 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "engine.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "sum_pd.hpp"
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::status;
+
+status_t mkldnn_sum_primitive_desc_create(primitive_desc_t **sum_pd,
+ const memory_desc_t *dst_md, int n, const float *scales,
+ const memory_desc_t *src_mds, const primitive_attr_t *attr,
+ engine_t *engine) {
+ bool args_ok = !any_null(sum_pd, src_mds, scales) && n > 0;
+ if (!args_ok) return invalid_arguments;
+
+ const primitive_attr_t dummy_attr;
+ if (attr == NULL)
+ attr = &dummy_attr;
+
+ const int ndims = src_mds[0].ndims;
+ const dims_t &dims = src_mds[0].dims;
+ const data_type_t dt = src_mds[0].data_type;
+
+ for (int i = 1; i < n; ++i) {
+ if (src_mds[i].ndims != ndims) return invalid_arguments;
+ for (int d = 0; d < ndims; ++d) {
+ if (src_mds[i].dims[d] != dims[d])
+ return invalid_arguments;
+ }
+ if (src_mds[i].data_type != dt) return invalid_arguments;
+ }
+
+ memory_desc_t dummy_dst_md;
+ if (dst_md) {
+ if (dst_md->ndims != ndims) return invalid_arguments;
+ for (int d = 0; d < ndims; ++d) {
+ if (dst_md->dims[d] != dims[d])
+ return invalid_arguments;
+ }
+ } else {
+ dummy_dst_md = src_mds[0];
+ dummy_dst_md.format_kind = format_kind::any;
+ dst_md = &dummy_dst_md;
+ }
+
+ auto s_pd = reinterpret_cast<sum_pd_t **>(sum_pd);
+
+ for (auto s = engine->get_sum_implementation_list(); *s; ++s) {
+ if ((*s)(s_pd, engine, attr, dst_md, n, scales, src_mds) == success) {
+ (*s_pd)->init_info();
+ (*s_pd)->init_scratchpad_md();
+ return success;
+ }
+ }
+ return unimplemented;
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/sum_pd.hpp b/thirdparty/oidn/mkl-dnn/src/common/sum_pd.hpp
new file mode 100644
index 0000000000..80254667df
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/sum_pd.hpp
@@ -0,0 +1,143 @@
+/*******************************************************************************
+* Copyright 2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef SUM_PD_HPP
+#define SUM_PD_HPP
+
+#include <assert.h>
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "primitive_desc.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct sum_pd_t: public primitive_desc_t {
+ sum_pd_t(engine_t *engine, const primitive_attr_t *attr,
+ const memory_desc_t *dst_md, int n, const float *scales,
+ const memory_desc_t *src_mds)
+ : primitive_desc_t(engine, attr, primitive_kind::sum)
+ , n_(n), dst_md_(*dst_md)
+ {
+ scales_.reserve(n_);
+ for (int i = 0; i < n_; ++i) scales_.push_back(scales[i]);
+ src_mds_.reserve(n_);
+ for (int i = 0; i < n_; ++i) src_mds_.push_back(src_mds[i]);
+ }
+
+ virtual void init_info() override { impl::init_info(this, this->info_); }
+
+ virtual arg_usage_t arg_usage(primitive_arg_index_t arg) const override {
+ if (arg >= MKLDNN_ARG_MULTIPLE_SRC
+ && arg < MKLDNN_ARG_MULTIPLE_SRC + n_inputs())
+ return arg_usage_t::input;
+
+ if (arg == MKLDNN_ARG_DST)
+ return arg_usage_t::output;
+
+ return primitive_desc_t::arg_usage(arg);
+ }
+
+ virtual const memory_desc_t *src_md(int index = 0) const override
+ { return index < n_inputs() ? &src_mds_[index] : nullptr; }
+ virtual const memory_desc_t *dst_md(int index = 0) const override
+ { return index == 0 ? &dst_md_ : nullptr; }
+
+ virtual int n_inputs() const override { return n_; }
+ virtual int n_outputs() const override { return 1; }
+
+ const float *scales() const { return &scales_[0]; }
+
+protected:
+ int n_;
+ nstl::vector<float> scales_;
+ memory_desc_t dst_md_;
+ nstl::vector<memory_desc_t> src_mds_;
+
+protected:
+ /* inits dst_md_ in simple cases. The call may fail. */
+ status_t init() {
+ for (int i = 0; i < n_; ++i) {
+ const memory_desc_wrapper src_d(&src_mds_[i]);
+ if (!src_d.is_blocking_desc() || src_d.is_additional_buffer())
+ return status::unimplemented;
+ }
+ bool ok = true
+ && set_default_params() == status::success
+ && attr()->has_default_values();
+ return ok ? status::success : status::unimplemented;
+ }
+
+ status_t set_default_params() {
+ if (dst_md_.format_kind != format_kind::any)
+ return status::success;
+
+ /* The stupidest ever heuristics (but not the same as we had before):
+ * - Pick the first non-plain format;
+ * - If all formats are plain, pick the format of the first input
+ */
+ for (int i = 0; i < n_; ++i) {
+ const memory_desc_wrapper src_d(src_mds_[i]);
+ if (!src_d.is_plain() && src_d.is_blocking_desc()) {
+ return memory_desc_init_by_blocking_desc(dst_md_,
+ src_d.blocking_desc());
+ }
+ }
+
+ if (src_mds_[0].format_kind != format_kind::blocked)
+ return status::unimplemented;
+
+ dst_md_ = src_mds_[0];
+
+ return status::success;
+ }
+};
+
+#define DECLARE_SUM_PD_t(impl_name, ...) \
+ static status_t create(sum_pd_t **sum_pd, \
+ engine_t *engine, const primitive_attr_t *attr, \
+ const memory_desc_t *dst_md, int n, const float *scales, \
+ const memory_desc_t *src_mds) { \
+ using namespace status; \
+ auto _pd = new pd_t(engine, attr, dst_md, n, scales, src_mds); \
+ if (_pd == nullptr) return out_of_memory; \
+ if (_pd->init() != success) { delete _pd; return unimplemented; } \
+ return safe_ptr_assign<sum_pd_t>(*sum_pd, _pd); \
+ } \
+ virtual status_t create_primitive(primitive_t **p) const override { \
+ double ms = get_msec(); \
+ auto ret = safe_ptr_assign<primitive_t>(*p, new (__VA_ARGS__)(this)); \
+ ms = get_msec() - ms; \
+ if (mkldnn_verbose()->level >= 2) { \
+ printf("mkldnn_verbose,create,%s,%g\n", this->info(), ms); \
+ fflush(0); \
+ } \
+ return ret; \
+ } \
+ virtual pd_t *clone() const override { return new pd_t(*this); } \
+ virtual const char *name() const override { return impl_name; } \
+
+#define DECLARE_SUM_PD_T(impl_name, ...) \
+ DECLARE_SUM_PD_t(impl_name, __VA_ARGS__)
+
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/tag_traits.hpp b/thirdparty/oidn/mkl-dnn/src/common/tag_traits.hpp
new file mode 100644
index 0000000000..a408f45980
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/tag_traits.hpp
@@ -0,0 +1,200 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef TAG_TRAITS_HPP
+#define TAG_TRAITS_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+enum class block_dim_t {
+ _,
+ _A, _B,
+ _AB, _BC,
+};
+
+enum class inner_blk_t {
+ _,
+ _4a, _4b,
+ _8a, _8b,
+ _16a, _16b,
+
+ _4b4a, _4b4c, _4c4b,
+ _8a8b, _8b8a, _8b8c, _8c8b,
+ _16a16b, _16a4b, _16b16a, _16b4c, _16b16c, _16c16b,
+
+ _2c8b4c, _8a16b2a, _4b16a4b, _8b16a2b, _8b16c2b, _4c16b4c, _8c16b2c,
+};
+
+/** returns the offset within the block for weights blocked over oc and ic */
+template <inner_blk_t f>
+constexpr int AB_or_BC_blk_off(int x0, int x1) {
+ using ib = inner_blk_t;
+ static_assert(utils::one_of(f, ib::_4b4a, ib::_4b4c, ib::_4c4b, ib::_8a8b,
+ ib::_8b8a, ib::_8b8c, ib::_8c8b, ib::_16a16b, ib::_16a4b,
+ ib::_16b16a, ib::_16b4c, ib::_16b16c, ib::_16c16b, ib::_2c8b4c,
+ ib::_8a16b2a, ib::_4b16a4b, ib::_8b16a2b, ib::_8b16c2b,
+ ib::_4c16b4c, ib::_8c16b2c),
+ "unexpected inner_blk format");
+ return false ? 0
+ : (f == ib::_4b4c) ? 4 * x0 + x1
+ : (f == ib::_4b4a || f == ib::_4c4b) ? 4 * x1 + x0
+ : (f == ib::_8a8b || f == ib::_8b8c) ? 8 * x0 + x1
+ : (f == ib::_8b8a || f == ib::_8c8b) ? 8 * x1 + x0
+ : (f == ib::_16a16b || f == ib::_16b16c) ? 16 * x0 + x1
+ : (f == ib::_16b16a || f == ib::_16c16b) ? 16 * x1 + x0
+ : (f == ib::_16a4b || f == ib::_16b4c) ? 4 * x0 + x1
+ : (f == ib::_8a16b2a || f == ib::_8b16c2b) ? (x0 / 2) * 32 + x1 * 2 + x0 % 2
+ : (f == ib::_4b16a4b || f == ib::_4c16b4c) ? (x1 / 4) * 64 + x0 * 4 + x1 % 4
+ : (f == ib::_8b16a2b || f == ib::_8c16b2c) ? (x1 / 2) * 32 + x0 * 2 + x1 % 2
+ : (f == ib::_2c8b4c) ? (x1 / 4) * 32 + x0 * 4 + x1 % 4
+ : INT_MIN;
+}
+
+template <inner_blk_t b> struct inner_blk_traits {
+ using ib = inner_blk_t;
+};
+
+template <format_tag_t> struct tag_traits {
+ // block_dim_t block_dims;
+ // inner_blk_t inner_blks;
+ // int ndims;
+};
+
+#define DECL_TRAITS(_tag, _blk_fmt, _inner_blk, _ndims) \
+template <> struct tag_traits<format_tag::_tag> { \
+ static constexpr block_dim_t block_dims = block_dim_t::_blk_fmt; \
+ static constexpr inner_blk_t inner_blks = inner_blk_t::_inner_blk; \
+ static constexpr int ndims = _ndims; \
+}
+
+DECL_TRAITS(a, _, _, 1);
+DECL_TRAITS(ab, _, _, 2);
+DECL_TRAITS(abc, _, _, 3);
+DECL_TRAITS(abcd, _, _, 4);
+DECL_TRAITS(abcde, _, _, 5);
+DECL_TRAITS(abcdef, _, _, 6);
+DECL_TRAITS(abdec, _, _, 5);
+DECL_TRAITS(acb, _, _, 3);
+DECL_TRAITS(acbde, _, _, 5);
+DECL_TRAITS(acdb, _, _, 4);
+DECL_TRAITS(acdeb, _, _, 5);
+DECL_TRAITS(ba, _, _, 2);
+DECL_TRAITS(bac, _, _, 3);
+DECL_TRAITS(bacd, _, _, 4);
+DECL_TRAITS(bcda, _, _, 4);
+DECL_TRAITS(cba, _, _, 3);
+DECL_TRAITS(cdba, _, _, 4);
+DECL_TRAITS(cdeba, _, _, 5);
+DECL_TRAITS(decab, _, _, 5);
+
+DECL_TRAITS(Abc4a, _A, _4a, 3);
+DECL_TRAITS(aBc4b, _B, _4b, 3);
+DECL_TRAITS(ABc4b16a4b, _AB, _4b16a4b, 3);
+DECL_TRAITS(ABc4b4a, _AB, _4b4a, 3);
+DECL_TRAITS(Abcd4a, _A, _4a, 4);
+DECL_TRAITS(aBcd4b, _B, _4b, 4);
+DECL_TRAITS(ABcd4b4a, _AB, _4b4a, 4);
+DECL_TRAITS(aBCd4c16b4c, _BC, _4c16b4c, 4);
+DECL_TRAITS(aBCd4c4b, _BC, _4c4b, 4);
+DECL_TRAITS(Abcde4a, _A, _4a, 5);
+DECL_TRAITS(aBcde4b, _B, _4b, 5);
+DECL_TRAITS(ABcde4b4a, _AB, _4b4a, 5);
+DECL_TRAITS(aBCde4c4b, _BC, _4c4b, 5);
+DECL_TRAITS(aBcdef4b, _B, _4b, 6);
+DECL_TRAITS(aBCdef4c4b, _BC, _4c4b, 6);
+DECL_TRAITS(aBdc4b, _B, _4b, 4);
+DECL_TRAITS(aBdec4b, _B, _4b, 5);
+DECL_TRAITS(aBdefc4b, _B, _4b, 6);
+DECL_TRAITS(Acb4a, _A, _4a, 3);
+DECL_TRAITS(Acdb4a, _A, _4a, 4);
+DECL_TRAITS(Acdeb4a, _A, _4a, 5);
+
+DECL_TRAITS(Abc16a, _A, _16a, 3);
+DECL_TRAITS(ABc16a16b, _AB, _16a16b, 3);
+DECL_TRAITS(aBc16b, _B, _16b, 3);
+DECL_TRAITS(ABc16b16a, _AB, _16b16a, 3);
+DECL_TRAITS(ABc8a16b2a, _AB, _8a16b2a, 3);
+DECL_TRAITS(ABc8a8b, _AB, _8a8b, 3);
+DECL_TRAITS(aBc8b, _B, _8b, 3);
+DECL_TRAITS(ABc8b16a2b, _AB, _8b16a2b, 3);
+DECL_TRAITS(ABc8b8a, _AB, _8b8a, 3);
+DECL_TRAITS(Abcd16a, _A, _16a, 4);
+DECL_TRAITS(ABcd16a16b, _AB, _16a16b, 4);
+DECL_TRAITS(aBcd16b, _B, _16b, 4);
+DECL_TRAITS(ABcd16b16a, _AB, _16b16a, 4);
+DECL_TRAITS(aBCd16b16c, _BC, _16b16c, 4);
+DECL_TRAITS(aBCd16c16b, _BC, _16c16b, 4);
+DECL_TRAITS(ABcd4b16a4b, _AB, _4b16a4b, 4);
+DECL_TRAITS(ABcd8a16b2a, _AB, _8a16b2a, 4);
+DECL_TRAITS(ABcd8a8b, _AB, _8a8b, 4);
+DECL_TRAITS(aBcd8b, _B, _8b, 4);
+DECL_TRAITS(ABcd8b16a2b, _AB, _8b16a2b, 4);
+DECL_TRAITS(aBCd8b16c2b, _BC, _8b16c2b, 4);
+DECL_TRAITS(ABcd8b8a, _AB, _8b8a, 4);
+DECL_TRAITS(aBCd8b8c, _BC, _8b8c, 4);
+DECL_TRAITS(aBCd8c16b2c, _BC, _8c16b2c, 4);
+DECL_TRAITS(aBCd8c8b, _BC, _8c8b, 4);
+DECL_TRAITS(Abcde16a, _A, _16a, 5);
+DECL_TRAITS(ABcde16a16b, _AB, _16a16b, 5);
+DECL_TRAITS(aBcde16b, _B, _16b, 5);
+DECL_TRAITS(ABcde16b16a, _AB, _16b16a, 5);
+DECL_TRAITS(aBCde16b16c, _BC, _16b16c, 5);
+DECL_TRAITS(aBCde16c16b, _BC, _16c16b, 5);
+DECL_TRAITS(aBCde4c16b4c, _BC, _4c16b4c, 5);
+DECL_TRAITS(Abcde8a, _A, _8a, 5);
+DECL_TRAITS(ABcde8a8b, _AB, _8a8b, 5);
+DECL_TRAITS(aBcde8b, _B, _8b, 5);
+DECL_TRAITS(ABcde8b16a2b, _AB, _8b16a2b, 5);
+DECL_TRAITS(aBCde8b16c2b, _BC, _8b16c2b, 5);
+DECL_TRAITS(ABcde8b8a, _AB, _8b8a, 5);
+DECL_TRAITS(aBCde8b8c, _BC, _8b8c, 5);
+DECL_TRAITS(aBCde2c8b4c, _BC, _2c8b4c, 5);
+DECL_TRAITS(aBCde8c16b2c, _BC, _8c16b2c, 5);
+DECL_TRAITS(aBCde4b4c, _BC, _4b4c, 5);
+DECL_TRAITS(aBCde8c8b, _BC, _8c8b, 5);
+DECL_TRAITS(aBcdef16b, _B, _16b, 6);
+DECL_TRAITS(aBCdef16b16c, _BC, _16b16c, 6);
+DECL_TRAITS(aBCdef16c16b, _BC, _16c16b, 6);
+DECL_TRAITS(aBCdef8b8c, _BC, _8b8c, 6);
+DECL_TRAITS(aBCdef8c16b2c, _BC, _8c16b2c, 6);
+DECL_TRAITS(aBCdef8c8b, _BC, _8c8b, 6);
+DECL_TRAITS(aBdc16b, _B, _16b, 4);
+DECL_TRAITS(aBdc8b, _B, _8b, 4);
+DECL_TRAITS(aBdec16b, _B, _16b, 5);
+DECL_TRAITS(aBdec8b, _B, _8b, 5);
+DECL_TRAITS(aBdefc16b, _B, _16b, 6);
+DECL_TRAITS(aBdefc8b, _B, _8b, 6);
+DECL_TRAITS(Acb16a, _A, _16a, 3);
+DECL_TRAITS(Acb8a, _A, _8a, 3);
+DECL_TRAITS(aCBd16b16c, _BC, _16b16c, 4);
+DECL_TRAITS(aCBde16b16c, _BC, _16b16c, 5);
+DECL_TRAITS(Acdb16a, _A, _16a, 4);
+DECL_TRAITS(Acdb8a, _A, _8a, 4);
+DECL_TRAITS(Acdeb16a, _A, _16a, 5);
+DECL_TRAITS(Acdeb8a, _A, _8a, 5);
+DECL_TRAITS(BAc16a16b, _AB, _16a16b, 3);
+DECL_TRAITS(BAcd16a16b, _AB, _16a16b, 4);
+
+} // namespace impl
+} // namespace mkldnn
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/type_helpers.hpp b/thirdparty/oidn/mkl-dnn/src/common/type_helpers.hpp
new file mode 100644
index 0000000000..4f06368738
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/type_helpers.hpp
@@ -0,0 +1,348 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef TYPE_HELPERS_HPP
+#define TYPE_HELPERS_HPP
+
+#include <assert.h>
+#include <math.h>
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "mkldnn_traits.hpp"
+#include "nstl.hpp"
+#include "utils.hpp"
+#include "math_utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+template <typename T>
+status_t safe_ptr_assign(T * &lhs, T* rhs) {
+ if (rhs == nullptr) return status::out_of_memory;
+ lhs = rhs;
+ return status::success;
+}
+
+template <typename T, typename U> struct is_subset
+{ static constexpr bool value = false; };
+template <typename T> struct is_subset<T, T>
+{ static constexpr bool value = true; };
+template <typename T> struct is_subset<T,
+ typename utils::enable_if<nstl::is_integral<T>::value, float>::type>
+{ static constexpr bool value = true; };
+#define ISSPEC(t1, t2) template <> \
+ struct is_subset<t1, t2> { static constexpr bool value = true; }
+ISSPEC(int16_t, int32_t);
+ISSPEC(int8_t, int32_t);
+ISSPEC(uint8_t, int32_t);
+ISSPEC(int8_t, int16_t);
+ISSPEC(uint8_t, int16_t);
+#undef ISSPEC
+
+inline bool operator==(const memory_desc_t &lhs, const memory_desc_t &rhs);
+
+namespace types {
+
+inline size_t data_type_size(data_type_t data_type) {
+ using namespace data_type;
+ switch (data_type) {
+ case f32: return sizeof(prec_traits<f32>::type);
+ case s32: return sizeof(prec_traits<s32>::type);
+ case s8: return sizeof(prec_traits<s8>::type);
+ case u8: return sizeof(prec_traits<u8>::type);
+ case data_type::undef:
+ default: assert(!"unknown data_type");
+ }
+ return 0; /* not supposed to be reachable */
+}
+
+inline format_kind_t format_tag_to_kind(format_tag_t tag) {
+ switch (tag) {
+ case format_tag::undef: return format_kind::undef;
+ case format_tag::any: return format_kind::any;
+ case format_tag::last: return format_kind::undef;
+ default: return format_kind::blocked;
+ }
+
+ assert(!"unreachable");
+ return format_kind::undef;
+}
+
+inline bool memory_extra_desc_is_equal(const memory_extra_desc_t &lhs,
+ const memory_extra_desc_t &rhs) {
+ return true
+ && lhs.flags == rhs.flags
+ && IMPLICATION(lhs.flags & memory_extra_flags::compensation_conv_s8s8,
+ lhs.compensation_mask == rhs.compensation_mask)
+ && IMPLICATION(lhs.flags & memory_extra_flags::scale_adjust,
+ lhs.scale_adjust == rhs.scale_adjust);
+}
+
+inline bool blocking_desc_is_equal(const blocking_desc_t &lhs,
+ const blocking_desc_t &rhs, int ndims = MKLDNN_MAX_NDIMS) {
+ using mkldnn::impl::utils::array_cmp;
+ return true
+ && lhs.inner_nblks == rhs.inner_nblks
+ && array_cmp(lhs.strides, rhs.strides, ndims)
+ && array_cmp(lhs.inner_blks, rhs.inner_blks, lhs.inner_nblks)
+ && array_cmp(lhs.inner_idxs, rhs.inner_idxs, lhs.inner_nblks);
+}
+
+inline bool wino_desc_is_equal(const wino_desc_t &lhs,
+ const wino_desc_t &rhs) {
+ return lhs.wino_format == rhs.wino_format
+ && lhs.alpha == rhs.alpha
+ && lhs.ic == rhs.ic
+ && lhs.oc == rhs.oc
+ && lhs.ic_block == rhs.ic_block
+ && lhs.oc_block == rhs.oc_block
+ && lhs.ic2_block == rhs.ic2_block
+ && lhs.oc2_block == rhs.oc2_block
+ && lhs.r == rhs.r;
+}
+
+inline bool rnn_packed_desc_is_equal(
+ const rnn_packed_desc_t &lhs, const rnn_packed_desc_t &rhs) {
+ bool ok = true
+ && lhs.format == rhs.format
+ && lhs.n_parts == rhs.n_parts
+ && lhs.offset_compensation == rhs.offset_compensation
+ && lhs.size == rhs.size
+ && lhs.n == rhs.n;
+ if (!ok)
+ return false;
+
+ for (int i = 0; i < rhs.n_parts; i++)
+ ok = ok && lhs.parts[i] == rhs.parts[i];
+ for (int i = 0; i < rhs.n_parts; i++)
+ ok = ok && lhs.part_pack_size[i] == rhs.part_pack_size[i];
+ return ok;
+}
+
+inline memory_desc_t zero_md() {
+ auto zero = memory_desc_t();
+ return zero;
+}
+
+inline bool is_zero_md(const memory_desc_t *md) {
+ return md == nullptr || *md == zero_md();
+}
+
+inline data_type_t default_accum_data_type(data_type_t src_dt,
+ data_type_t dst_dt) {
+ using namespace utils;
+ using namespace data_type;
+
+ if (one_of(f32, src_dt, dst_dt)) return f32;
+ if (one_of(s32, src_dt, dst_dt)) return s32;
+
+ if (one_of(s8, src_dt, dst_dt) || one_of(u8, src_dt, dst_dt)) return s32;
+
+ assert(!"unimplemented use-case: no default parameters available");
+ return dst_dt;
+}
+
+inline data_type_t default_accum_data_type(data_type_t src_dt,
+ data_type_t wei_dt, data_type_t dst_dt, prop_kind_t prop_kind) {
+ using namespace utils;
+ using namespace data_type;
+ using namespace prop_kind;
+
+ /* prop_kind doesn't matter */
+ if (everyone_is(f32, src_dt, wei_dt, dst_dt)) return f32;
+
+ if (one_of(prop_kind, forward_training, forward_inference)) {
+ if ((src_dt == u8 || src_dt == s8)
+ && wei_dt == s8 && one_of(dst_dt, f32, s32, s8, u8))
+ return s32;
+ } else if (prop_kind == backward_data) {
+ if (one_of(src_dt, f32, s32, s8, u8) && wei_dt == s8 &&
+ one_of(dst_dt, s8, u8))
+ return s32;
+ }
+
+ assert(!"unimplemented use-case: no default parameters available");
+ return dst_dt;
+}
+
+}
+
+inline bool operator==(const memory_desc_t &lhs, const memory_desc_t &rhs) {
+ using namespace mkldnn::impl::utils;
+ bool base_equal = true
+ && lhs.ndims == rhs.ndims
+ && array_cmp(lhs.dims, rhs.dims, lhs.ndims)
+ && lhs.data_type == rhs.data_type
+ && array_cmp(lhs.padded_dims, rhs.padded_dims, lhs.ndims)
+ && array_cmp(lhs.padded_offsets, rhs.padded_offsets, lhs.ndims)
+ && lhs.offset0 == rhs.offset0
+ && lhs.format_kind == rhs.format_kind;
+ if (!base_equal) return false;
+ if (!types::memory_extra_desc_is_equal(lhs.extra, rhs.extra)) return false;
+ if (lhs.format_kind == format_kind::blocked)
+ return types::blocking_desc_is_equal(lhs.format_desc.blocking,
+ rhs.format_desc.blocking, lhs.ndims);
+ else if (lhs.format_kind == format_kind::wino)
+ return types::wino_desc_is_equal(lhs.format_desc.wino_desc,
+ rhs.format_desc.wino_desc);
+ else if (lhs.format_kind == format_kind::rnn_packed)
+ return types::rnn_packed_desc_is_equal(lhs.format_desc.rnn_packed_desc,
+ rhs.format_desc.rnn_packed_desc);
+ return true;
+}
+
+inline bool operator!=(const memory_desc_t &lhs, const memory_desc_t &rhs) {
+ return !operator==(lhs, rhs);
+}
+
+inline status_t memory_desc_init_by_strides(memory_desc_t &md,
+ const dims_t strides) {
+ return mkldnn_memory_desc_init_by_strides(
+ &md, md.ndims, md.dims, md.data_type, strides);
+}
+
+inline status_t memory_desc_init_by_tag(memory_desc_t &md, format_tag_t tag,
+ const dims_t strides = nullptr) {
+ status_t status = mkldnn_memory_desc_init_by_tag(
+ &md, md.ndims, md.dims, md.data_type, tag);
+ if (status != status::success || strides == nullptr)
+ return status;
+
+ /* TODO: add consistency check */
+
+ for (int d = 0; d < md.ndims; ++d)
+ md.format_desc.blocking.strides[d] = strides[d];
+
+ return status::success;
+}
+
+/** inits memory descriptor based on logical dimensions kept in @p md, and the
+ * blocking structure @p blk.
+ *
+ * @note blk.strides represent the order only (from smaller to bigger)
+ *
+ * TODO: move md related functions to one single place
+ */
+inline status_t memory_desc_init_by_blocking_desc(memory_desc_t &md,
+ const blocking_desc_t &blk) {
+ dims_t blocks = {0};
+ utils::array_set(blocks, 1, md.ndims);
+ dim_t block_size = 1;
+ for (int iblk = 0; iblk < blk.inner_nblks; ++iblk) {
+ blocks[blk.inner_idxs[iblk]] *= blk.inner_blks[iblk];
+ block_size *= blk.inner_blks[iblk];
+ }
+
+ for (int d = 0; d < md.ndims; ++d) {
+ md.padded_dims[d] = utils::rnd_up(md.dims[d], blocks[d]);
+ md.padded_offsets[d] = 0;
+ }
+ md.offset0 = 0;
+
+ md.format_kind = format_kind::blocked;
+ auto &mblk = md.format_desc.blocking;
+ mblk = blk;
+
+ const int ndims = nstl::min(MKLDNN_MAX_NDIMS, md.ndims); // make GCC 5 happy
+ utils::array_copy(mblk.strides, blk.strides, ndims);
+
+ int perm[MKLDNN_MAX_NDIMS];
+ for (int d = 0; d < ndims; ++d) perm[d] = d;
+
+ utils::simultaneous_sort(mblk.strides, perm, ndims,
+ [](stride_t a, stride_t b) { return b - a; });
+
+ dim_t stride = block_size;
+ for (int _d = ndims - 1; _d >= 0; --_d) {
+ const int d = perm[_d];
+ md.format_desc.blocking.strides[d] = stride;
+ stride *= md.padded_dims[d] / blocks[d];
+ }
+
+ md.extra = utils::zero<memory_extra_desc_t>();
+
+ return status::success;
+}
+
+/** returns true if memory desc @p md corresponds to the given format tag and
+ * strides.
+ * If strides are not passed (or passed as nullptr) the dense structure is
+ * assumed (i.e. the one that mkldnn_memory_desc_init_by_tag() returns).
+ * Strides might contain `0` value, indicating the stride must match the one
+ * that mkldnn_memory_desc_init_by_tag() returns.
+ * Strides might contain `-1` values, that would be ignored during the
+ * comparison. For instance, this can be used if a stride along minibatch
+ * doesn't matter. */
+inline bool memory_desc_matches_tag(const memory_desc_t &md, format_tag_t tag,
+ const dims_t strides = nullptr) {
+ if (md.format_kind != types::format_tag_to_kind(tag))
+ return false;
+
+ memory_desc_t md_gold;
+ status_t status = mkldnn_memory_desc_init_by_tag(
+ &md_gold, md.ndims, md.dims, md.data_type, tag);
+ if (status != status::success) return false;
+
+ if (md.format_kind != format_kind::blocked)
+ return false; // unimplemented yet
+
+ const auto &blk = md.format_desc.blocking;
+ const auto &blk_gold = md_gold.format_desc.blocking;
+
+ using utils::array_cmp;
+ bool same_blocks = true
+ && blk.inner_nblks == blk_gold.inner_nblks
+ && array_cmp(blk.inner_blks, blk_gold.inner_blks, blk.inner_nblks)
+ && array_cmp(blk.inner_idxs, blk_gold.inner_idxs, blk.inner_nblks);
+
+ if (!same_blocks)
+ return false;
+
+ if (strides == nullptr)
+ return array_cmp(blk.strides, blk_gold.strides, md.ndims);
+
+ for (int d = 0; d < md.ndims; ++d) {
+ dim_t stride = strides[d];
+ if (stride == -1) continue;
+ if (stride == 0) stride = blk_gold.strides[d];
+ if (blk.strides[d] != stride) return false;
+ }
+
+ return true;
+}
+
+/** returns matching tag (or undef if match is not found)
+ * XXX: This is a workaround that eventually should go away! */
+template <typename... Tags>
+format_tag_t memory_desc_matches_one_of_tag(const memory_desc_t &md,
+ Tags ...tags) {
+ for (const auto tag: {tags...}) {
+ if (memory_desc_matches_tag(md, tag))
+ return tag;
+ }
+ return format_tag::undef;
+}
+
+}
+}
+
+#include "memory_desc_wrapper.hpp"
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/utils.cpp b/thirdparty/oidn/mkl-dnn/src/common/utils.cpp
new file mode 100644
index 0000000000..d23f4682dc
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/utils.cpp
@@ -0,0 +1,135 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <string.h>
+#ifdef _WIN32
+#include <malloc.h>
+#include <windows.h>
+#endif
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "mkldnn.h"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+int getenv(const char *name, char *buffer, int buffer_size) {
+ if (name == NULL || buffer_size < 0 || (buffer == NULL && buffer_size > 0))
+ return INT_MIN;
+
+ int result = 0;
+ int term_zero_idx = 0;
+ size_t value_length = 0;
+
+#ifdef _WIN32
+ value_length = GetEnvironmentVariable(name, buffer, buffer_size);
+#else
+ const char *value = ::getenv(name);
+ value_length = value == NULL ? 0 : strlen(value);
+#endif
+
+ if (value_length > INT_MAX)
+ result = INT_MIN;
+ else {
+ int int_value_length = (int)value_length;
+ if (int_value_length >= buffer_size) {
+ result = -int_value_length;
+ } else {
+ term_zero_idx = int_value_length;
+ result = int_value_length;
+#ifndef _WIN32
+ strncpy(buffer, value, value_length);
+#endif
+ }
+ }
+
+ if (buffer != NULL)
+ buffer[term_zero_idx] = '\0';
+ return result;
+}
+
+int getenv_int(const char *name, int default_value)
+{
+ int value = default_value;
+ // # of digits in the longest 32-bit signed int + sign + terminating null
+ const int len = 12;
+ char value_str[len];
+ if (getenv(name, value_str, len) > 0)
+ value = atoi(value_str);
+ return value;
+}
+
+FILE *fopen(const char *filename, const char *mode) {
+#ifdef _WIN32
+ FILE *fp = NULL;
+ return ::fopen_s(&fp, filename, mode) ? NULL : fp;
+#else
+ return ::fopen(filename, mode);
+#endif
+}
+
+void *malloc(size_t size, int alignment) {
+ void *ptr;
+
+#ifdef _WIN32
+ ptr = _aligned_malloc(size, alignment);
+ int rc = ptr ? 0 : -1;
+#else
+ int rc = ::posix_memalign(&ptr, alignment, size);
+#endif
+
+ return (rc == 0) ? ptr : 0;
+}
+
+void free(void *p) {
+#ifdef _WIN32
+ _aligned_free(p);
+#else
+ ::free(p);
+#endif
+}
+
+// Atomic operations
+int32_t fetch_and_add(int32_t *dst, int32_t val) {
+#ifdef _WIN32
+ return InterlockedExchangeAdd(reinterpret_cast<long*>(dst), val);
+#else
+ return __sync_fetch_and_add(dst, val);
+#endif
+}
+
+static int jit_dump_flag = 0;
+static bool jit_dump_flag_initialized = false;
+bool jit_dump_enabled() {
+ if (!jit_dump_flag_initialized) {
+ jit_dump_flag = getenv_int("MKLDNN_JIT_DUMP");
+ jit_dump_flag_initialized = true;
+ }
+ return jit_dump_flag != 0;
+}
+
+}
+}
+
+mkldnn_status_t mkldnn_set_jit_dump(int enabled) {
+ using namespace mkldnn::impl::status;
+ mkldnn::impl::jit_dump_flag = enabled;
+ mkldnn::impl::jit_dump_flag_initialized = true;
+ return success;
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/utils.hpp b/thirdparty/oidn/mkl-dnn/src/common/utils.hpp
new file mode 100644
index 0000000000..d5a8ec5139
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/utils.hpp
@@ -0,0 +1,370 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef UTILS_HPP
+#define UTILS_HPP
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <stdint.h>
+
+#if defined(__x86_64__) || defined(_M_X64)
+#define MKLDNN_X86_64
+#endif
+
+#define MSAN_ENABLED 0
+#if defined(__has_feature)
+#if __has_feature(memory_sanitizer)
+#undef MSAN_ENABLED
+#define MSAN_ENABLED 1
+#include <sanitizer/msan_interface.h>
+#endif
+#endif
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "z_magic.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+// Sanity check for 64 bits
+static_assert(sizeof(void*) == 8, "Intel(R) MKL-DNN supports 64 bit only");
+
+#define CHECK(f) do { \
+ status_t status = f; \
+ if (status != status::success) \
+ return status; \
+} while (0)
+
+#define IMPLICATION(cause, effect) (!(cause) || !!(effect))
+
+namespace utils {
+
+/* a bunch of std:: analogues to be compliant with any msvs version
+ *
+ * Rationale: msvs c++ (and even some c) headers contain special pragma that
+ * injects msvs-version check into object files in order to abi-mismatches
+ * during the static linking. This makes sense if e.g. std:: objects are passed
+ * through between application and library, which is not the case for mkl-dnn
+ * (since there is no any c++-rt dependent stuff, ideally...). */
+
+/* SFINAE helper -- analogue to std::enable_if */
+template<bool expr, class T = void> struct enable_if {};
+template<class T> struct enable_if<true, T> { typedef T type; };
+
+/* analogue std::conditional */
+template <bool, typename, typename> struct conditional {};
+template <typename T, typename F> struct conditional<true, T, F>
+{ typedef T type; };
+template <typename T, typename F> struct conditional<false, T, F>
+{ typedef F type; };
+
+template <bool, typename, bool, typename, typename> struct conditional3 {};
+template <typename T, typename FT, typename FF>
+struct conditional3<true, T, false, FT, FF> { typedef T type; };
+template <typename T, typename FT, typename FF>
+struct conditional3<false, T, true, FT, FF> { typedef FT type; };
+template <typename T, typename FT, typename FF>
+struct conditional3<false, T, false, FT, FF> { typedef FF type; };
+
+template <bool, typename U, U, U> struct conditional_v {};
+template <typename U, U t, U f> struct conditional_v<true, U, t, f>
+{ static constexpr U value = t; };
+template <typename U, U t, U f> struct conditional_v<false, U, t, f>
+{ static constexpr U value = f; };
+
+template <typename T> struct remove_reference { typedef T type; };
+template <typename T> struct remove_reference<T&> { typedef T type; };
+template <typename T> struct remove_reference<T&&> { typedef T type; };
+
+template <typename T>
+inline T&& forward(typename utils::remove_reference<T>::type &t)
+{ return static_cast<T&&>(t); }
+template <typename T>
+inline T&& forward(typename utils::remove_reference<T>::type &&t)
+{ return static_cast<T&&>(t); }
+
+template <typename T>
+inline typename remove_reference<T>::type zero()
+{ auto zero = typename remove_reference<T>::type(); return zero; }
+
+template <typename T, typename P>
+inline bool everyone_is(T val, P item) { return val == item; }
+template <typename T, typename P, typename... Args>
+inline bool everyone_is(T val, P item, Args... item_others) {
+ return val == item && everyone_is(val, item_others...);
+}
+
+template <typename T, typename P>
+constexpr bool one_of(T val, P item) { return val == item; }
+template <typename T, typename P, typename... Args>
+constexpr bool one_of(T val, P item, Args... item_others) {
+ return val == item || one_of(val, item_others...);
+}
+
+template <typename... Args>
+inline bool any_null(Args... ptrs) { return one_of(nullptr, ptrs...); }
+
+template<typename T>
+inline void array_copy(T *dst, const T *src, size_t size) {
+ for (size_t i = 0; i < size; ++i) dst[i] = src[i];
+}
+template<typename T>
+inline bool array_cmp(const T *a1, const T *a2, size_t size) {
+ for (size_t i = 0; i < size; ++i) if (a1[i] != a2[i]) return false;
+ return true;
+}
+template<typename T, typename U>
+inline void array_set(T *arr, const U& val, size_t size) {
+ for (size_t i = 0; i < size; ++i) arr[i] = static_cast<T>(val);
+}
+
+namespace product_impl {
+template<size_t> struct int2type{};
+
+template <typename T>
+constexpr int product_impl(const T *arr, int2type<0>) { return arr[0]; }
+
+template <typename T, size_t num>
+inline T product_impl(const T *arr, int2type<num>) {
+ return arr[0]*product_impl(arr+1, int2type<num-1>()); }
+}
+
+template <size_t num, typename T>
+inline T array_product(const T *arr) {
+ return product_impl::product_impl(arr, product_impl::int2type<num-1>());
+}
+
+template<typename T, typename R = T>
+inline R array_product(const T *arr, size_t size) {
+ R prod = 1;
+ for (size_t i = 0; i < size; ++i) prod *= arr[i];
+ return prod;
+}
+
+/** sorts an array of values using @p comparator. While sorting the array
+ * of value, the function permutes an array of @p keys accordingly.
+ *
+ * @note The arrays of @p keys can be omitted. In this case the function
+ * sorts the array of @vals only.
+ */
+template <typename T, typename U, typename F>
+inline void simultaneous_sort(T *vals, U *keys, size_t size, F comparator) {
+ if (size == 0) return;
+
+ for (size_t i = 0; i < size - 1; ++i) {
+ bool swapped = false;
+
+ for (size_t j = 0; j < size - i - 1; j++) {
+ if (comparator(vals[j], vals[j + 1]) > 0) {
+ nstl::swap(vals[j], vals[j + 1]);
+ if (keys) nstl::swap(keys[j], keys[j + 1]);
+ swapped = true;
+ }
+ }
+
+ if (swapped == false) break;
+ }
+}
+
+template <typename T, typename U>
+inline typename remove_reference<T>::type div_up(const T a, const U b) {
+ assert(b);
+ return (a + b - 1) / b;
+}
+
+template <typename T, typename U>
+inline typename remove_reference<T>::type rnd_up(const T a, const U b) {
+ return div_up(a, b) * b;
+}
+
+template <typename T, typename U>
+inline typename remove_reference<T>::type rnd_dn(const T a, const U b) {
+ return (a / b) * b;
+}
+
+template <typename T> T *align_ptr(T *ptr, uintptr_t alignment)
+{ return (T *)(((uintptr_t)ptr + alignment - 1) & ~(alignment - 1)); }
+
+template <typename T, typename U, typename V>
+inline U this_block_size(const T offset, const U max, const V block_size) {
+ assert(offset < max);
+ // TODO (Roma): can't use nstl::max() due to circular dependency... we
+ // need to fix this
+ const T block_boundary = offset + block_size;
+ if (block_boundary > max)
+ return max - offset;
+ else
+ return block_size;
+}
+
+template<typename T>
+inline T nd_iterator_init(T start) { return start; }
+template<typename T, typename U, typename W, typename... Args>
+inline T nd_iterator_init(T start, U &x, const W &X, Args &&... tuple) {
+ start = nd_iterator_init(start, utils::forward<Args>(tuple)...);
+ x = start % X;
+ return start / X;
+}
+
+inline bool nd_iterator_step() { return true; }
+template<typename U, typename W, typename... Args>
+inline bool nd_iterator_step(U &x, const W &X, Args &&... tuple) {
+ if (nd_iterator_step(utils::forward<Args>(tuple)...) ) {
+ x = (x + 1) % X;
+ return x == 0;
+ }
+ return false;
+}
+
+template<typename U, typename W, typename Y>
+inline bool nd_iterator_jump(U &cur, const U end, W &x, const Y &X)
+{
+ U max_jump = end - cur;
+ U dim_jump = X - x;
+ if (dim_jump <= max_jump) {
+ x = 0;
+ cur += dim_jump;
+ return true;
+ } else {
+ cur += max_jump;
+ x += max_jump;
+ return false;
+ }
+}
+template<typename U, typename W, typename Y, typename... Args>
+inline bool nd_iterator_jump(U &cur, const U end, W &x, const Y &X,
+ Args &&... tuple)
+{
+ if (nd_iterator_jump(cur, end, utils::forward<Args>(tuple)...)) {
+ x = (x + 1) % X;
+ return x == 0;
+ }
+ return false;
+}
+
+template <typename T>
+inline T pick(size_t i, const T &x0) { return x0; }
+template <typename T, typename ...Args>
+inline T pick(size_t i, const T &x0, Args &&... args) {
+ return i == 0 ? x0 : pick(i - 1, utils::forward<Args>(args)...);
+}
+
+template <typename T>
+T pick_by_prop_kind(prop_kind_t prop_kind, const T &val_fwd_inference,
+ const T &val_fwd_training, const T &val_bwd_d, const T &val_bwd_w) {
+ switch (prop_kind) {
+ case prop_kind::forward_inference: return val_fwd_inference;
+ case prop_kind::forward_training: return val_fwd_training;
+ case prop_kind::backward_data: return val_bwd_d;
+ case prop_kind::backward_weights: return val_bwd_w;
+ default: assert(!"unsupported prop_kind");
+ }
+ return T();
+}
+
+template <typename T>
+T pick_by_prop_kind(prop_kind_t prop_kind,
+ const T &val_fwd, const T &val_bwd_d, const T &val_bwd_w)
+{ return pick_by_prop_kind(prop_kind, val_fwd, val_fwd, val_bwd_d, val_bwd_w); }
+
+template <typename Telem, size_t Tdims>
+struct array_offset_calculator {
+ template <typename... Targs>
+ array_offset_calculator(Telem *base, Targs... Fargs) : _dims{ Fargs... }
+ {
+ _base_ptr = base;
+ }
+ template <typename... Targs>
+ inline Telem &operator()(Targs... Fargs)
+ {
+ return *(_base_ptr + _offset(1, Fargs...));
+ }
+
+private:
+ template <typename... Targs>
+ inline size_t _offset(size_t const dimension, size_t element)
+ {
+ return element;
+ }
+
+ template <typename... Targs>
+ inline size_t _offset(size_t const dimension, size_t theta, size_t element)
+ {
+ return element + (_dims[dimension] * theta);
+ }
+
+ template <typename... Targs>
+ inline size_t _offset(size_t const dimension, size_t theta, size_t element,
+ Targs... Fargs)
+ {
+ size_t t_prime = element + (_dims[dimension] * theta);
+ return _offset(dimension + 1, t_prime, Fargs...);
+ }
+
+ Telem *_base_ptr;
+ const int _dims[Tdims];
+};
+
+}
+
+int32_t fetch_and_add(int32_t *dst, int32_t val);
+inline void yield_thread() {}
+
+// Reads an environment variable 'name' and stores its string value in the
+// 'buffer' of 'buffer_size' bytes on success.
+//
+// - Returns the length of the environment variable string value (excluding
+// the terminating 0) if it is set and its contents (including the terminating
+// 0) can be stored in the 'buffer' without truncation.
+//
+// - Returns negated length of environment variable string value and writes
+// "\0" to the buffer (if it is not NULL) if the 'buffer_size' is to small to
+// store the value (including the terminating 0) without truncation.
+//
+// - Returns 0 and writes "\0" to the buffer (if not NULL) if the environment
+// variable is not set.
+//
+// - Returns INT_MIN if the 'name' is NULL.
+//
+// - Returns INT_MIN if the 'buffer_size' is negative.
+//
+// - Returns INT_MIN if the 'buffer' is NULL and 'buffer_size' is greater than
+// zero. Passing NULL 'buffer' with 'buffer_size' set to 0 can be used to
+// retrieve the length of the environment variable value string.
+//
+int getenv(const char *name, char *buffer, int buffer_size);
+// Reads an integer from the environment
+int getenv_int(const char *name, int default_value = 0);
+bool jit_dump_enabled();
+FILE *fopen(const char *filename, const char *mode);
+
+constexpr int msan_enabled = MSAN_ENABLED;
+inline void msan_unpoison(void *ptr, size_t size) {
+#if MSAN_ENABLED
+ __msan_unpoison(ptr, size);
+#endif
+}
+
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/common/verbose.cpp b/thirdparty/oidn/mkl-dnn/src/common/verbose.cpp
new file mode 100644
index 0000000000..89a57772cf
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/verbose.cpp
@@ -0,0 +1,665 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <stdlib.h>
+#ifndef _WIN32
+#include <sys/time.h>
+#endif
+
+#include "mkldnn.h"
+#include "mkldnn_version.h"
+#include "c_types_map.hpp"
+#include "verbose.hpp"
+#include "cpu/cpu_isa_traits.hpp"
+
+#include "batch_normalization_pd.hpp"
+#include "pooling_pd.hpp"
+#include "concat_pd.hpp"
+#include "reorder_pd.hpp"
+#include "convolution_pd.hpp"
+#include "rnn_pd.hpp"
+#include "deconvolution_pd.hpp"
+#include "shuffle_pd.hpp"
+#include "eltwise_pd.hpp"
+#include "softmax_pd.hpp"
+#include "inner_product_pd.hpp"
+#include "sum_pd.hpp"
+#include "lrn_pd.hpp"
+
+/* MKL-DNN CPU ISA info */
+#define ISA_ANY "No instruction set specific optimizations"
+#define SSE42 "Intel(R) Streaming SIMD Extensions 4.2 (Intel(R) SSE4.2)"
+#define AVX "Intel(R) Advanced Vector Extensions (Intel(R) AVX)"
+#define AVX2 "Intel(R) Advanced Vector Extensions 2 (Intel(R) AVX2)"
+#define AVX512_COMMON "Intel(R) Advanced Vector Extensions 512 (Intel(R) " \
+ "AVX-512)"
+#define AVX512_CORE "Intel(R) Advanced Vector Extensions 512 (Intel(R) " \
+ "AVX-512) with AVX512BW, AVX512VL, and AVX512DQ extensions"
+#define AVX512_CORE_VNNI "Intel(R) AVX512-Deep Learning Boost (Intel(R) " \
+ "AVX512-DL Boost)"
+#define AVX512_MIC "Intel(R) Advanced Vector Extensions 512 (Intel(R) " \
+ "AVX-512) with AVX512CD, AVX512ER, and AVX512PF extensions"
+#define AVX512_MIC_4OPS "Intel(R) Advanced Vector Extensions 512 (Intel(R) " \
+ "AVX-512) with AVX512_4FMAPS and AVX512_4VNNIW extensions"
+
+namespace mkldnn {
+namespace impl {
+
+static verbose_t verbose;
+static bool initialized;
+static bool version_printed = false;
+
+const verbose_t *mkldnn_verbose() {
+#if !defined(DISABLE_VERBOSE)
+ if (!initialized) {
+ const int len = 2;
+ char val[len] = {0};
+ if (getenv("MKLDNN_VERBOSE", val, len) == 1)
+ verbose.level = atoi(val);
+ initialized = true;
+ }
+ if (!version_printed && verbose.level > 0) {
+ printf("mkldnn_verbose,info,"
+ "Intel(R) MKL-DNN v%d.%d.%d (Git Hash %s),%s\n",
+ mkldnn_version()->major, mkldnn_version()->minor,
+ mkldnn_version()->patch, mkldnn_version()->hash,
+ get_isa_info());
+ version_printed = true;
+ }
+#else
+ verbose.level = 0;
+#endif
+ return &verbose;
+}
+
+double get_msec() {
+#ifdef _WIN32
+ static LARGE_INTEGER frequency;
+ if (frequency.QuadPart == 0)
+ QueryPerformanceFrequency(&frequency);
+ LARGE_INTEGER now;
+ QueryPerformanceCounter(&now);
+ return 1e+3 * now.QuadPart / frequency.QuadPart;
+#else
+ struct timeval time;
+ gettimeofday(&time, NULL);
+ return 1e+3 * time.tv_sec + 1e-3 * time.tv_usec;
+#endif
+}
+
+const char *get_isa_info() {
+ using namespace mkldnn::impl::cpu;
+ if (mayiuse(avx512_mic_4ops)) return AVX512_MIC_4OPS;
+ if (mayiuse(avx512_mic)) return AVX512_MIC;
+ if (mayiuse(avx512_core_vnni)) return AVX512_CORE_VNNI;
+ if (mayiuse(avx512_core)) return AVX512_CORE;
+ if (mayiuse(avx512_common)) return AVX512_COMMON;
+ if (mayiuse(avx2)) return AVX2;
+ if (mayiuse(avx)) return AVX;
+ if (mayiuse(sse42)) return SSE42;
+ return ISA_ANY;
+}
+
+/* init_info section */
+namespace {
+#if !defined(DISABLE_VERBOSE)
+#define MKLDNN_VERBOSE_DAT_LEN 256
+#define MKLDNN_VERBOSE_AUX_LEN 384
+#define MKLDNN_VERBOSE_PRB_LEN 384
+
+#define DECL_DAT_AUX_PRB_STRS() \
+ int dat_written = 0, aux_written = 0, prb_written = 0; \
+ MAYBE_UNUSED((dat_written * aux_written * prb_written)); \
+ char dat_str[MKLDNN_VERBOSE_DAT_LEN] = {'\0'}; MAYBE_UNUSED(dat_str); \
+ char aux_str[MKLDNN_VERBOSE_AUX_LEN] = {'\0'}; MAYBE_UNUSED(aux_str); \
+ char prb_str[MKLDNN_VERBOSE_PRB_LEN] = {'\0'}; MAYBE_UNUSED(prb_str)
+
+#define DFMT "%" PRId64
+
+void clear_buf(char *buf, int &written) {
+ /* TODO: do it better */
+ buf[0] = '#';
+ buf[1] = '\0';
+ written = 1;
+}
+
+#define DPRINT(buf, buf_len, written, ...) do { \
+ int l = snprintf(buf + written, buf_len - written, __VA_ARGS__); \
+ if (l < 0 || written + l > buf_len) { \
+ clear_buf(buf, written); \
+ } else { \
+ written += l; \
+ } \
+} while(0)
+
+// XXX: Outputs strings corresponding to memory formats used for data tensors.
+void format_prb_desc_str(char *str, int len, const memory_desc_t *md) {
+ const auto dims = md->dims;
+ int written = 0;
+ if (md->ndims == 1)
+ DPRINT(str, len, written,
+ "x" DFMT, dims[0]);
+ else if (md->ndims == 2)
+ DPRINT(str, len, written,
+ "mb" DFMT "ic" DFMT, dims[0], dims[1]);
+ else if (md->ndims == 3)
+ DPRINT(str, len, written,
+ "mb" DFMT "ic" DFMT "iw" DFMT,
+ dims[0], dims[1], dims[2]);
+ else if (md->ndims == 4)
+ DPRINT(str, len, written,
+ "mb" DFMT "ic" DFMT "ih" DFMT "iw" DFMT,
+ dims[0], dims[1], dims[2], dims[3]);
+ else if (md->ndims == 5)
+ DPRINT(str, len, written,
+ "mb" DFMT "ic" DFMT "id" DFMT "ih" DFMT "iw" DFMT,
+ dims[0], dims[1], dims[2], dims[3], dims[4]);
+ else
+ mkldnn_md2dim_str(str, len, md);
+}
+
+void verbose_templ(char *buffer, mkldnn_primitive_kind_t prim_kind,
+ const char *impl_str, mkldnn_prop_kind_t prop_kind,
+ const char *data_str, const char *aux_str, const char *prb_str) {
+ MAYBE_UNUSED(verbose_templ);
+ int written = 0;
+ DPRINT(buffer, MKLDNN_VERBOSE_BUF_LEN, written, "%s,%s,%s,%s,%s,%s",
+ mkldnn_prim_kind2str(prim_kind), impl_str,
+ mkldnn_prop_kind2str(prop_kind), data_str, aux_str, prb_str);
+}
+
+template <typename pd_t> static void init_info_bnorm(pd_t *s, char *buffer) {
+ DECL_DAT_AUX_PRB_STRS();
+
+ if (1) { // data
+ auto md = s->src_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "data_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // diff data
+ auto md = s->diff_src_md();
+ if (md) {
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " diff_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ }
+
+ DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
+ "flags:%u", s->desc()->flags);
+
+ format_prb_desc_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->src_md());
+
+ verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
+ aux_str, prb_str);
+}
+
+template <typename pd_t> static void init_info_conv(pd_t *s, char *buffer) {
+ DECL_DAT_AUX_PRB_STRS();
+
+ if (1) { // src
+ auto md = s->desc()->prop_kind == prop_kind::backward_data
+ ? s->diff_src_md() : s->src_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // wei
+ auto md = s->desc()->prop_kind == prop_kind::backward_weights
+ ? s->diff_weights_md() : s->weights_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " wei_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // bia
+ auto md = s->desc()->prop_kind == prop_kind::backward_weights
+ ? s->diff_weights_md(1) : s->weights_md(1);
+ if (md) {
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " bia_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ }
+ if (1) { // dst
+ auto md = !s->is_fwd() ? s->diff_dst_md() : s->dst_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " dst_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+
+ DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
+ "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind));
+
+ if (s->ndims() == 5) {
+ if (s->with_groups())
+ DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
+ "mb" DFMT "_g" DFMT "ic" DFMT "oc" DFMT
+ "_id" DFMT "od" DFMT "kd" DFMT "sd" DFMT "dd" DFMT "pd" DFMT
+ "_ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "dh" DFMT "ph" DFMT
+ "_iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "dw" DFMT "pw" DFMT,
+ s->MB(), s->G(), s->IC(), s->OC(),
+ s->ID(), s->OD(), s->KD(), s->KSD(), s->KDD(), s->padFront(),
+ s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(),
+ s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL());
+ else
+ DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
+ "mb" DFMT "_ic" DFMT "oc" DFMT
+ "_id" DFMT "od" DFMT "kd" DFMT "sd" DFMT "dd" DFMT "pd" DFMT
+ "_ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "dh" DFMT "ph" DFMT
+ "_iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "dw" DFMT "pw" DFMT,
+ s->MB(), s->IC(), s->OC(),
+ s->ID(), s->OD(), s->KD(), s->KSD(), s->KDD(), s->padFront(),
+ s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(),
+ s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL());
+ } else {
+ if (s->with_groups())
+ DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
+ "mb" DFMT "_g" DFMT "ic" DFMT "oc" DFMT
+ "_ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "dh" DFMT "ph" DFMT
+ "_iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "dw" DFMT "pw" DFMT,
+ s->MB(), s->G(), s->IC(), s->OC(),
+ s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(),
+ s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL());
+ else
+ DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
+ "mb" DFMT "_ic" DFMT "oc" DFMT
+ "_ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "dh" DFMT "ph" DFMT
+ "_iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "dw" DFMT "pw" DFMT,
+ s->MB(), s->IC(), s->OC(),
+ s->IH(), s->OH(), s->KH(), s->KSH(), s->KDH(), s->padT(),
+ s->IW(), s->OW(), s->KW(), s->KSW(), s->KDW(), s->padL());
+ }
+
+ verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
+ aux_str, prb_str);
+}
+
+template <typename pd_t> static void init_info_shuffle(pd_t *s, char *buffer) {
+ DECL_DAT_AUX_PRB_STRS();
+
+ auto md = s->is_fwd() ? s->src_md() : s->diff_dst_md();
+
+ if (1) { // data
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "data_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+
+ DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
+ "axis:%d group_size:" DFMT, s->axis(), s->group_size());
+
+ mkldnn_md2dim_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, md);
+
+ verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
+ aux_str, prb_str);
+}
+
+template <typename pd_t> static void init_info_eltwise(pd_t *s, char *buffer) {
+ DECL_DAT_AUX_PRB_STRS();
+
+ if (1) { // data
+ auto md = s->src_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "data_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // diff data
+ auto md = s->diff_src_md();
+ if (md) {
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " diff_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ }
+
+ DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
+ "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind));
+
+ mkldnn_md2dim_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->src_md());
+
+ verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
+ aux_str, prb_str);
+}
+
+template <typename pd_t> static void init_info_iprod(pd_t *s, char *buffer) {
+ DECL_DAT_AUX_PRB_STRS();
+
+ if (1) { // src
+ auto md = s->desc()->prop_kind == prop_kind::backward_data
+ ? s->diff_src_md() : s->src_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // wei
+ auto md = s->desc()->prop_kind == prop_kind::backward_weights
+ ? s->diff_weights_md() : s->weights_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " wei_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // bia
+ auto md = s->desc()->prop_kind == prop_kind::backward_weights
+ ? s->diff_weights_md(1) : s->weights_md(1);
+ if (md) {
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " bia_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ }
+ if (1) { // dst
+ auto md = !s->is_fwd() ? s->diff_dst_md() : s->dst_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " dst_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+
+ DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
+ "mb" DFMT "ic" DFMT "oc" DFMT, s->MB(), s->IC_total(), s->OC());
+
+ verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
+ aux_str, prb_str);
+}
+
+template <typename pd_t> static void init_info_lrn(pd_t *s, char *buffer) {
+ DECL_DAT_AUX_PRB_STRS();
+
+ if (1) { // data
+ auto md = s->src_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "data_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // diff data
+ auto md = s->diff_src_md();
+ if (md) {
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " diff_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ }
+
+ DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
+ "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind));
+
+ format_prb_desc_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->src_md());
+
+ verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
+ aux_str, prb_str);
+}
+
+template <typename pd_t> static void init_info_mem(pd_t *s, char *buffer) {
+ DECL_DAT_AUX_PRB_STRS();
+
+ if (1) { // src
+ auto md = s->src_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // dst
+ auto md = s->dst_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " dst_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+
+ DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
+ "num:%d", s->n_inputs());
+
+ mkldnn_md2dim_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->dst_md());
+
+ verbose_templ(buffer, s->kind(), s->name(), prop_kind::undef, dat_str,
+ aux_str, prb_str);
+}
+
+template <typename pd_t> static void init_info_pool(pd_t *s, char *buffer) {
+ DECL_DAT_AUX_PRB_STRS();
+
+ if (1) { // src
+ auto md = s->is_fwd() ? s->src_md() : s->diff_src_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // dst
+ auto md = s->is_fwd() ? s->dst_md() : s->diff_dst_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " dst_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // ws
+ auto md = s->workspace_md();
+ if (md) {
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " ws_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ }
+
+ DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
+ "alg:%s", mkldnn_alg_kind2str(s->desc()->alg_kind));
+
+ if (s->is_3d()) {
+ DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
+ "mb" DFMT "ic" DFMT "_"
+ "id" DFMT "od" DFMT "kd" DFMT "sd" DFMT "pd" DFMT "_"
+ "ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "ph" DFMT "_"
+ "iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "pw" DFMT "",
+ s->MB(), s->C(),
+ s->ID(), s->OD(), s->KD(), s->KSD(), s->padFront(),
+ s->IH(), s->OH(), s->KH(), s->KSH(), s->padT(),
+ s->IW(), s->OW(), s->KW(), s->KSW(), s->padL());
+ } else {
+ DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
+ "mb" DFMT "ic" DFMT "_"
+ "ih" DFMT "oh" DFMT "kh" DFMT "sh" DFMT "ph" DFMT "_"
+ "iw" DFMT "ow" DFMT "kw" DFMT "sw" DFMT "pw" DFMT,
+ s->MB(), s->C(),
+ s->IH(), s->OH(), s->KH(), s->KSH(), s->padT(),
+ s->IW(), s->OW(), s->KW(), s->KSW(), s->padL());
+ }
+
+ verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
+ aux_str, prb_str);
+}
+
+template <typename pd_t> static void init_info_softmax(pd_t *s, char *buffer) {
+ DECL_DAT_AUX_PRB_STRS();
+
+ if (1) { // data
+ auto md = s->dst_md();
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "data_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // diff data
+ auto md = s->diff_src_md();
+ if (md) {
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " diff_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ }
+
+ mkldnn_md2dim_str(prb_str, MKLDNN_VERBOSE_PRB_LEN, s->dst_md());
+
+ verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
+ aux_str, prb_str);
+}
+
+template <typename pd_t> static void init_info_rnn(pd_t *s, char *buffer) {
+ DECL_DAT_AUX_PRB_STRS();
+
+ if (1) { // src layer
+ auto md = s->is_fwd() ? s->src_md(0) : s->diff_src_md(0);
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_layer_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // src iter
+ auto md = s->is_fwd() ? s->src_md(1) : s->diff_src_md(1);
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "src_iter_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // wei_layer
+ auto md = s->is_fwd() ? s->weights_md(0) : s->diff_weights_md(0);
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " wei_layer_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // wei_iter
+ auto md = s->is_fwd() ? s->weights_md(1) : s->diff_weights_md(1);
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " wei_layer_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // bias
+ auto md = s->is_fwd() ? s->weights_md(2) : s->diff_weights_md(2);
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, " bias_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // dst layer
+ auto md = s->is_fwd() ? s->dst_md(0) : s->diff_dst_md(0);
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "dst_layer_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+ if (1) { // dst iter
+ auto md = s->is_fwd() ? s->dst_md(1) : s->diff_dst_md(1);
+ DPRINT(dat_str, MKLDNN_VERBOSE_DAT_LEN, dat_written, "dst_iter_");
+ int l = mkldnn_md2fmt_str(dat_str + dat_written,
+ MKLDNN_VERBOSE_DAT_LEN - dat_written, md);
+ if (l >= 0) dat_written += l; else clear_buf(dat_str, dat_written);
+ }
+
+ alg_kind_t alg_kind = s->cell_kind();
+ rnn_direction_t rnn_dir = s->direction();
+ DPRINT(aux_str, MKLDNN_VERBOSE_AUX_LEN, aux_written,
+ "alg:%s_%s", mkldnn_alg_kind2str(alg_kind),
+ mkldnn_rnn_direction2str(rnn_dir));
+
+ DPRINT(prb_str, MKLDNN_VERBOSE_PRB_LEN, prb_written,
+ "l" DFMT "t" DFMT "mb" DFMT
+ "sic" DFMT "slc" DFMT "dic" DFMT "dlc" DFMT,
+ s->L(), s->T(), s->MB(),
+ s->SIC(), s->SLC(), s->DIC(), s->DLC());
+
+ verbose_templ(buffer, s->kind(), s->name(), s->desc()->prop_kind, dat_str,
+ aux_str, prb_str);
+}
+
+#undef DPRINT
+
+#else // !defined(DISABLE_VERBOSE)
+
+#define DEFINE_STUB(name) \
+ template <typename pd_t> \
+ static void CONCAT2(init_info_, name)(pd_t *s, char *buffer) \
+ { UNUSED(s); UNUSED(buffer); }
+
+DEFINE_STUB(bnorm);
+DEFINE_STUB(conv);
+DEFINE_STUB(eltwise);
+DEFINE_STUB(iprod);
+DEFINE_STUB(lrn);
+DEFINE_STUB(mem);
+DEFINE_STUB(pool);
+DEFINE_STUB(softmax);
+DEFINE_STUB(rnn);
+DEFINE_STUB(shuffle);
+#undef DEFINE_STUB
+
+#endif // !defined(DISABLE_VERBOSE)
+}
+
+void init_info(batch_normalization_pd_t *s, char *b)
+{ init_info_bnorm(s, b); }
+void init_info(concat_pd_t *s, char *b)
+{ init_info_mem(s, b); }
+void init_info(convolution_pd_t *s, char *b)
+{ init_info_conv(s, b); }
+void init_info(deconvolution_pd_t *s, char *b)
+{ init_info_conv(s, b); }
+void init_info(eltwise_pd_t *s, char *b)
+{ init_info_eltwise(s, b); }
+void init_info(inner_product_pd_t *s, char *b)
+{ init_info_iprod(s, b); }
+void init_info(lrn_pd_t *s, char *b)
+{ init_info_lrn(s, b); }
+void init_info(pooling_pd_t *s, char *b)
+{ init_info_pool(s, b); }
+void init_info(reorder_pd_t *s, char *b)
+{ init_info_mem(s, b); }
+void init_info(rnn_pd_t *s, char *b)
+{ init_info_rnn(s, b); }
+void init_info(shuffle_pd_t *s, char *b)
+{ init_info_shuffle(s, b); }
+void init_info(softmax_pd_t *s, char *b)
+{ init_info_softmax(s, b); }
+void init_info(sum_pd_t *s, char *b)
+{ init_info_mem(s, b); }
+
+}
+}
+
+mkldnn_status_t mkldnn_set_verbose(int level) {
+ using namespace mkldnn::impl::status;
+ if (level < 0 || level > 2) return invalid_arguments;
+ mkldnn::impl::verbose.level = level;
+ mkldnn::impl::initialized = true;
+ return success;
+}
+
+const mkldnn_version_t *mkldnn_version() {
+ static mkldnn_version_t ver = {
+ MKLDNN_VERSION_MAJOR,
+ MKLDNN_VERSION_MINOR,
+ MKLDNN_VERSION_PATCH,
+ MKLDNN_VERSION_HASH};
+ return &ver;
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/common/verbose.hpp b/thirdparty/oidn/mkl-dnn/src/common/verbose.hpp
new file mode 100644
index 0000000000..e3049750cb
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/verbose.hpp
@@ -0,0 +1,62 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef VERBOSE_HPP
+#define VERBOSE_HPP
+
+#include <stdio.h>
+#include <cinttypes>
+
+#include "mkldnn_debug.h"
+#include "c_types_map.hpp"
+#include "utils.hpp"
+#include "z_magic.hpp"
+
+namespace mkldnn {
+namespace impl {
+
+struct verbose_t {
+ int level;
+};
+
+const verbose_t *mkldnn_verbose();
+double get_msec();
+const char *get_isa_info();
+
+#if !defined(DISABLE_VERBOSE)
+#define MKLDNN_VERBOSE_BUF_LEN 1024
+#else
+#define MKLDNN_VERBOSE_BUF_LEN 1
+#endif
+
+void init_info(batch_normalization_pd_t *s, char *buffer);
+void init_info(concat_pd_t *s, char *buffer);
+void init_info(convolution_pd_t *s, char *buffer);
+void init_info(deconvolution_pd_t *s, char *buffer);
+void init_info(eltwise_pd_t *s, char *buffer);
+void init_info(inner_product_pd_t *s, char *buffer);
+void init_info(lrn_pd_t *s, char *buffer);
+void init_info(pooling_pd_t *s, char *buffer);
+void init_info(reorder_pd_t *s, char *buffer);
+void init_info(rnn_pd_t *s, char *buffer);
+void init_info(shuffle_pd_t *s, char *buffer);
+void init_info(softmax_pd_t *s, char *buffer);
+void init_info(sum_pd_t *s, char *buffer);
+
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/common/z_magic.hpp b/thirdparty/oidn/mkl-dnn/src/common/z_magic.hpp
new file mode 100644
index 0000000000..520bd4710b
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/common/z_magic.hpp
@@ -0,0 +1,46 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef Z_MAGIC_HPP
+#define Z_MAGIC_HPP
+
+#define CHAIn2(a,b) a b
+#define CHAIN2(a,b) CHAIn2(a,b)
+
+#define CONCAt2(a,b) a ## b
+#define CONCAT2(a,b) CONCAt2(a,b)
+
+#define STRINGIFy(s) #s
+#define STRINGIFY(s) STRINGIFy(s)
+
+#ifdef _MSC_VER
+# define PRAGMA_MACRo(x) __pragma(x)
+# define PRAGMA_MACRO(x) PRAGMA_MACRo(x)
+#else
+# define PRAGMA_MACRo(x) _Pragma(#x)
+# define PRAGMA_MACRO(x) PRAGMA_MACRo(x)
+#endif
+
+#define UNUSED(x) ((void)x)
+#define MAYBE_UNUSED(x) UNUSED(x)
+
+#if defined(_WIN32) && !defined(__GNUC__)
+#define __PRETTY_FUNCTION__ __FUNCSIG__
+#endif
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_barrier.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_barrier.cpp
new file mode 100644
index 0000000000..7cf7822d90
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_barrier.cpp
@@ -0,0 +1,112 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "cpu_barrier.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace simple_barrier {
+
+void generate(jit_generator &code, Xbyak::Reg64 reg_ctx,
+ Xbyak::Reg64 reg_nthr) {
+# define BAR_CTR_OFF offsetof(ctx_t, ctr)
+# define BAR_SENSE_OFF offsetof(ctx_t, sense)
+ using namespace Xbyak;
+
+ Xbyak::Reg64 reg_tmp = [&]() {
+ /* returns register which is neither reg_ctx nor reg_nthr */
+ Xbyak::Reg64 regs[] = { util::rax, util::rbx, util::rcx };
+ for (size_t i = 0; i < sizeof(regs) / sizeof(regs[0]); ++i)
+ if (!utils::one_of(regs[i], reg_ctx, reg_nthr))
+ return regs[i];
+ return regs[0]; /* should not happen */
+ }();
+
+ Label barrier_exit_label, barrier_exit_restore_label, spin_label;
+
+ code.cmp(reg_nthr, 1);
+ code.jbe(barrier_exit_label);
+
+ code.push(reg_tmp);
+
+ /* take and save current sense */
+ code.mov(reg_tmp, code.ptr[reg_ctx + BAR_SENSE_OFF]);
+ code.push(reg_tmp);
+ code.mov(reg_tmp, 1);
+
+ if (mayiuse(avx512_mic)) {
+ code.prefetchwt1(code.ptr[reg_ctx + BAR_CTR_OFF]);
+ code.prefetchwt1(code.ptr[reg_ctx + BAR_CTR_OFF]);
+ }
+
+ code.lock(); code.xadd(code.ptr[reg_ctx + BAR_CTR_OFF], reg_tmp);
+ code.add(reg_tmp, 1);
+ code.cmp(reg_tmp, reg_nthr);
+ code.pop(reg_tmp); /* restore previous sense */
+ code.jne(spin_label);
+
+ /* the last thread {{{ */
+ code.mov(code.qword[reg_ctx + BAR_CTR_OFF], 0); // reset ctx
+
+ // notify waiting threads
+ code.not_(reg_tmp);
+ code.mov(code.ptr[reg_ctx + BAR_SENSE_OFF], reg_tmp);
+ code.jmp(barrier_exit_restore_label);
+ /* }}} the last thread */
+
+ code.CodeGenerator::L(spin_label);
+ code.pause();
+ code.cmp(reg_tmp, code.ptr[reg_ctx + BAR_SENSE_OFF]);
+ code.je(spin_label);
+
+ code.CodeGenerator::L(barrier_exit_restore_label);
+ code.pop(reg_tmp);
+
+ code.CodeGenerator::L(barrier_exit_label);
+# undef BAR_CTR_OFF
+# undef BAR_SENSE_OFF
+}
+
+/** jit barrier generator */
+struct jit_t: public jit_generator {
+ void (*barrier)(ctx_t *ctx, size_t nthr);
+
+ jit_t() {
+ generate(*this, abi_param1, abi_param2);
+ ret();
+ barrier = reinterpret_cast<decltype(barrier)>(const_cast<uint8_t*>(
+ this->getCode()));
+ }
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_t)
+};
+
+void barrier(ctx_t *ctx, int nthr) {
+ static jit_t j; /* XXX: constructed on load ... */
+ j.barrier(ctx, nthr);
+}
+
+}
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_barrier.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_barrier.hpp
new file mode 100644
index 0000000000..0f55e33aa8
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_barrier.hpp
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_BARRIER_HPP
+#define CPU_BARRIER_HPP
+
+#include <assert.h>
+
+#include "jit_generator.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace simple_barrier {
+
+STRUCT_ALIGN(64,
+struct ctx_t {
+ enum { CACHE_LINE_SIZE = 64 };
+ volatile size_t ctr;
+ char pad1[CACHE_LINE_SIZE - 1 * sizeof(size_t)];
+ volatile size_t sense;
+ char pad2[CACHE_LINE_SIZE - 1 * sizeof(size_t)];
+});
+
+inline void ctx_init(ctx_t *ctx) { *ctx = utils::zero<ctx_t>(); }
+void barrier(ctx_t *ctx, int nthr);
+
+/** injects actual barrier implementation into another jitted code
+ * @params:
+ * code -- jit_generator object where the barrier is to be injected
+ * reg_ctx -- read-only register with pointer to the barrier context
+ * reg_nnthr -- read-only register with the # of synchronizing threads
+ */
+void generate(jit_generator &code, Xbyak::Reg64 reg_ctx,
+ Xbyak::Reg64 reg_nthr);
+
+}
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_pd.hpp
new file mode 100644
index 0000000000..1ed5ad57b9
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_pd.hpp
@@ -0,0 +1,40 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_BATCH_NORMALIZATION_PD_HPP
+#define CPU_BATCH_NORMALIZATION_PD_HPP
+
+#include "batch_normalization_pd.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_batch_normalization_fwd_pd_t: public batch_normalization_fwd_pd_t {
+ using batch_normalization_fwd_pd_t::batch_normalization_fwd_pd_t;
+};
+
+struct cpu_batch_normalization_bwd_pd_t: public batch_normalization_bwd_pd_t {
+ using batch_normalization_bwd_pd_t::batch_normalization_bwd_pd_t;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_utils.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_utils.cpp
new file mode 100644
index 0000000000..b8d5c4fcaf
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_utils.cpp
@@ -0,0 +1,140 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "utils.hpp"
+
+#include "jit_generator.hpp"
+
+#include "cpu_batch_normalization_utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+namespace bnorm_utils {
+
+void cache_balance(size_t working_set_size, dim_t C_blks,
+ dim_t &C_blks_per_iter, int64_t &iters) {
+ int nthrs = mkldnn_get_max_threads();
+ int l3_size = get_cache_size(3, true) * nthrs / 2;
+
+ C_blks_per_iter = l3_size / working_set_size;
+
+ if (C_blks_per_iter == 0)
+ C_blks_per_iter = 1;
+ if (C_blks_per_iter > C_blks)
+ C_blks_per_iter = C_blks;
+
+ iters = (C_blks + C_blks_per_iter - 1) / C_blks_per_iter;
+}
+
+bool thread_balance(bool do_blocking, bool spatial_thr_allowed, int ithr,
+ int nthr, dim_t N, dim_t C_blks, dim_t SP, int &C_ithr, int &C_nthr,
+ dim_t &C_blk_s, dim_t &C_blk_e, int &N_ithr, int &N_nthr, dim_t &N_s,
+ dim_t &N_e, int &S_ithr, int &S_nthr, dim_t &S_s, dim_t &S_e) {
+ if (nthr <= C_blks || !mkldnn_thr_syncable()) {
+ C_ithr = ithr; C_nthr = nthr;
+ N_ithr = 0; N_nthr = 1;
+ S_ithr = 0; S_nthr = 1;
+ N_s = 0; N_e = N; S_s = 0; S_e = SP;
+ balance211(C_blks, C_nthr, C_ithr, C_blk_s, C_blk_e);
+ } else {
+ if (do_blocking) {
+ N_nthr = (int)nstl::min<dim_t>(N, nthr);
+ C_nthr = (int)nstl::min<dim_t>(C_blks, nthr / N_nthr);
+ S_nthr = (int)nstl::min<dim_t>(SP, nthr / (C_nthr * N_nthr));
+ } else {
+ C_nthr = (int)math::gcd((dim_t)nthr, C_blks);
+ N_nthr = (int)nstl::min<dim_t>(N, nthr / C_nthr);
+ S_nthr = (int)nstl::min<dim_t>(SP, nthr / (C_nthr * N_nthr));
+ }
+
+ if (!spatial_thr_allowed)
+ S_nthr = 1;
+
+ if (S_nthr < 1) S_nthr = 1;
+ if (ithr < C_nthr * N_nthr * S_nthr) {
+ N_ithr = (ithr / S_nthr) % N_nthr ;
+ C_ithr = ithr / (N_nthr * S_nthr);
+ S_ithr = ithr % S_nthr;
+ balance211(C_blks, C_nthr, C_ithr, C_blk_s, C_blk_e);
+ balance211(N, N_nthr, N_ithr, N_s, N_e);
+ balance211(SP, S_nthr, S_ithr, S_s, S_e);
+ } else {
+ S_ithr = N_ithr = C_ithr = -ithr;
+ S_s = S_e = N_s = N_e = C_blk_s = C_blk_e = -1;
+ }
+ }
+
+ // spatial_thr_allowed is meant to help maintain
+ // consistent decisions about spatial threading
+ // between mutiple invocations of this routine.
+ // It is caller's responsibility to check the
+ // return value and pass it as a flag to the
+ // next call if needed.
+ if (S_nthr == 1)
+ spatial_thr_allowed = false;
+
+ return spatial_thr_allowed;
+}
+
+bool is_spatial_thr(const batch_normalization_pd_t *bdesc, int simd_w,
+ int data_size) {
+ if (!mkldnn_thr_syncable()) return false;
+
+ dim_t nthr = mkldnn_get_max_threads();
+ dim_t SP = bdesc->W() * bdesc->D() * bdesc->H();
+ dim_t C_PADDED = memory_desc_wrapper(bdesc->src_md())
+ .padded_dims()[1];
+ assert(C_PADDED % simd_w == 0);
+
+ size_t data = bdesc->MB() * C_PADDED * SP * data_size;
+ size_t l3_size_ = get_cache_size(3, true) * nthr / 2;
+ bool do_blocking = (data >= l3_size_ / 2 && l3_size_ > 0);
+ dim_t C_blks_per_iter{ 1 }, iters{ 1 };
+ dim_t C_blks = C_PADDED / simd_w;
+
+ if (do_blocking) {
+ int num_tensors = bdesc->is_fwd() ? 1 : 2;
+ size_t working_set_size
+ = (bdesc->MB() * SP * simd_w * data_size) * num_tensors;
+ cache_balance(working_set_size, C_blks, C_blks_per_iter, iters);
+ }
+
+ // Spatial threading decision made in this function shall be consistent
+ // with thread_balance() behavior.
+ C_blks = do_blocking ? C_blks_per_iter : C_blks;
+
+ if (nthr <= C_blks) return false;
+
+ dim_t S_nthr = 1;
+ if (do_blocking) {
+ dim_t N_nthr = nstl::min(bdesc->MB(), nthr);
+ dim_t C_nthr = nstl::min(C_blks, nthr / N_nthr);
+ S_nthr = nstl::min(SP, nthr / (C_nthr * N_nthr));
+ } else {
+ dim_t C_nthr = math::gcd(nthr, C_blks);
+ dim_t N_nthr = nstl::min(bdesc->MB(), nthr / C_nthr);
+ S_nthr = nstl::min(SP, nthr / (C_nthr * N_nthr));
+ }
+
+ return S_nthr > 1;
+}
+
+}
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_utils.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_utils.hpp
new file mode 100644
index 0000000000..0daef0716c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_batch_normalization_utils.hpp
@@ -0,0 +1,43 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_BATCH_NORMALIZATION_UTILS_HPP
+#define CPU_BATCH_NORMALIZATION_UTILS_HPP
+
+#include "batch_normalization_pd.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+namespace bnorm_utils {
+
+void cache_balance(size_t working_set_size, dim_t C_blks,
+ dim_t &C_blks_per_iter, int64_t &iters);
+
+bool thread_balance(bool do_blocking, bool spatial_thr_allowed, int ithr,
+ int nthr, dim_t N, dim_t C_blks, dim_t SP, int &C_ithr, int &C_nthr,
+ dim_t &C_blk_s, dim_t &C_blk_e, int &N_ithr, int &N_nthr, dim_t &N_s,
+ dim_t &N_e, int &S_ithr, int &S_nthr, dim_t &S_s, dim_t &S_e);
+
+bool is_spatial_thr(const batch_normalization_pd_t *bdesc, int simd_w,
+ int data_size);
+
+}
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_concat.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_concat.cpp
new file mode 100644
index 0000000000..b926491202
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_concat.cpp
@@ -0,0 +1,51 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "cpu_engine.hpp"
+
+/*
+#include "cpu/ref_concat.hpp"
+#include "cpu/simple_concat.hpp"
+*/
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using cpd_create_f = mkldnn::impl::engine_t::concat_primitive_desc_create_f;
+
+namespace {
+#define INSTANCE(...) __VA_ARGS__::pd_t::create
+static const cpd_create_f cpu_concat_impl_list[] = {
+ /*
+ INSTANCE(simple_concat_t<data_type::f32>),
+ INSTANCE(simple_concat_t<data_type::u8>),
+ INSTANCE(simple_concat_t<data_type::s8>),
+ INSTANCE(simple_concat_t<data_type::s32>),
+ INSTANCE(ref_concat_t),
+ */
+ nullptr,
+};
+#undef INSTANCE
+}
+
+const cpd_create_f *cpu_engine_t::get_concat_implementation_list() const {
+ return cpu_concat_impl_list;
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_concat_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_concat_pd.hpp
new file mode 100644
index 0000000000..0b01bcf163
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_concat_pd.hpp
@@ -0,0 +1,41 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_CONCAT_PD_HPP
+#define CPU_CONCAT_PD_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "concat_pd.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_concat_pd_t: public concat_pd_t {
+ using concat_pd_t::concat_pd_t;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_convolution_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_convolution_pd.hpp
new file mode 100644
index 0000000000..52a38a2294
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_convolution_pd.hpp
@@ -0,0 +1,74 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_CONVOLUTION_PD_HPP
+#define CPU_CONVOLUTION_PD_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "convolution_pd.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_convolution_fwd_pd_t: public convolution_fwd_pd_t {
+ using convolution_fwd_pd_t::convolution_fwd_pd_t;
+
+ bool has_padded_dst() const {
+ memory_desc_wrapper dst_d(&dst_md_);
+ return OC() != dst_d.padded_dims()[1];
+ }
+
+ bool wants_padded_bias() const {
+ if (!with_bias()) return false;
+ return has_padded_dst();
+ }
+
+ bool wants_zero_pad_dst(bool jit_impl = true) const {
+ if (!has_padded_dst()) return false;
+ const auto &po = attr()->post_ops_;
+ int idx;
+ if ((idx = po.find(primitive_kind::eltwise)) == -1) return false;
+ return !math::eltwise_fwd_preserves_zero(po.entry_[idx].eltwise.alg,
+ jit_impl);
+ }
+};
+
+struct cpu_convolution_bwd_data_pd_t: public convolution_bwd_data_pd_t {
+ using convolution_bwd_data_pd_t::convolution_bwd_data_pd_t;
+};
+
+struct cpu_convolution_bwd_weights_pd_t: public convolution_bwd_weights_pd_t {
+ using convolution_bwd_weights_pd_t::convolution_bwd_weights_pd_t;
+
+ bool wants_padded_bias() const {
+ if (!with_bias()) return false;
+ memory_desc_wrapper diff_dst_d(&diff_dst_md_);
+ return OC() != diff_dst_d.padded_dims()[1];
+ }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_deconvolution_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_deconvolution_pd.hpp
new file mode 100644
index 0000000000..164c8601d7
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_deconvolution_pd.hpp
@@ -0,0 +1,46 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_DECONVOLUTION_PD_HPP
+#define CPU_DECONVOLUTION_PD_HPP
+
+#include <assert.h>
+
+#include "deconvolution_pd.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_deconvolution_fwd_pd_t: public deconvolution_fwd_pd_t {
+ using deconvolution_fwd_pd_t::deconvolution_fwd_pd_t;
+};
+
+struct cpu_deconvolution_bwd_data_pd_t: public deconvolution_bwd_data_pd_t {
+ using deconvolution_bwd_data_pd_t::deconvolution_bwd_data_pd_t;
+};
+
+struct cpu_deconvolution_bwd_weights_pd_t: public deconvolution_bwd_weights_pd_t {
+ using deconvolution_bwd_weights_pd_t::deconvolution_bwd_weights_pd_t;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_eltwise_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_eltwise_pd.hpp
new file mode 100644
index 0000000000..c52f00026e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_eltwise_pd.hpp
@@ -0,0 +1,45 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_ELTWISE_PD_HPP
+#define CPU_ELTWISE_PD_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "eltwise_pd.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_eltwise_fwd_pd_t: public eltwise_fwd_pd_t {
+ using eltwise_fwd_pd_t::eltwise_fwd_pd_t;
+};
+
+struct cpu_eltwise_bwd_pd_t: public eltwise_bwd_pd_t {
+ using eltwise_bwd_pd_t::eltwise_bwd_pd_t;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_engine.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_engine.cpp
new file mode 100644
index 0000000000..ce0a3667ad
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_engine.cpp
@@ -0,0 +1,324 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "type_helpers.hpp"
+#include "verbose.hpp"
+
+#include "cpu_engine.hpp"
+#include "cpu_memory.hpp"
+
+//#include "cpu/rnn/ref_rnn.hpp"
+
+//#include "cpu/jit_avx512_core_x8s8s32x_1x1_convolution.hpp"
+//#include "cpu/jit_avx512_common_1x1_convolution.hpp"
+#include "cpu/jit_avx512_core_fp32_wino_conv_4x3.hpp"
+#include "cpu/jit_avx512_common_convolution_winograd.hpp"
+//#include "cpu/jit_avx512_core_x8s8s32x_convolution.hpp"
+#include "cpu/jit_avx512_common_convolution.hpp"
+//#include "cpu/jit_avx2_1x1_convolution.hpp"
+//#include "cpu/jit_sse42_1x1_convolution.hpp"
+#include "cpu/jit_avx2_convolution.hpp"
+#include "cpu/jit_sse42_convolution.hpp"
+//#include "cpu/gemm_convolution.hpp"
+//#include "cpu/gemm_x8s8s32x_convolution.hpp"
+//#include "cpu/ref_convolution.hpp"
+//#include "cpu/jit_avx512_core_x8s8s32x_deconvolution.hpp"
+//#include "cpu/jit_avx512_core_x8s8s32x_1x1_deconvolution.hpp"
+//#include "cpu/ref_deconvolution.hpp"
+//#include "cpu/ref_shuffle.hpp"
+//#include "cpu/jit_uni_eltwise.hpp"
+//#include "cpu/ref_eltwise.hpp"
+//#include "cpu/ref_softmax.hpp"
+#include "cpu/jit_uni_pooling.hpp"
+//#include "cpu/jit_uni_i8i8_pooling.hpp"
+//#include "cpu/ref_pooling.hpp"
+//#include "cpu/nchw_pooling.hpp"
+//#include "cpu/nhwc_pooling.hpp"
+//#include "cpu/jit_avx512_common_lrn.hpp"
+//#include "cpu/jit_uni_lrn.hpp"
+//#include "cpu/ref_lrn.hpp"
+//#include "cpu/jit_uni_batch_normalization.hpp"
+//#include "cpu/ref_batch_normalization.hpp"
+//#include "cpu/ncsp_batch_normalization.hpp"
+//#include "cpu/nspc_batch_normalization.hpp"
+//#include "cpu/ref_inner_product.hpp"
+//#include "cpu/gemm_inner_product.hpp"
+//#include "cpu/gemm_x8s8s32x_inner_product.hpp"
+//#include "cpu/jit_uni_dw_convolution.hpp"
+//#include "cpu/jit_avx512_core_u8s8s32x_wino_convolution.hpp"
+#include "cpu/jit_avx512_core_fp32_wino_conv_2x3.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+status_t cpu_engine_t::memory_create(memory_t **memory,
+ const memory_desc_t *md, void *handle) {
+ auto _memory = new cpu_memory_t(this, md, handle);
+ if (_memory == nullptr)
+ return status::out_of_memory;
+
+ status_t status = _memory->init();
+ if (status != status::success) {
+ delete _memory;
+ return status;
+ }
+
+ return safe_ptr_assign<memory_t>(*memory, _memory);
+}
+
+using pd_create_f = mkldnn::impl::engine_t::primitive_desc_create_f;
+
+namespace {
+using namespace mkldnn::impl::data_type;
+
+#define INSTANCE(...) &primitive_desc_t::create<__VA_ARGS__::pd_t>
+static const pd_create_f cpu_impl_list[] = {
+ /* RNN */
+ /*
+ INSTANCE(ref_rnn_fwd_f32_t),
+ INSTANCE(ref_rnn_fwd_u8s8_t),
+ INSTANCE(ref_rnn_bwd_f32_t),
+ */
+ /* conv */
+ /*
+ INSTANCE(jit_avx512_common_dw_convolution_fwd_t),
+ INSTANCE(jit_avx512_common_dw_convolution_bwd_data_t),
+ INSTANCE(jit_avx512_common_dw_convolution_bwd_weights_t),
+ INSTANCE(jit_avx512_common_1x1_convolution_fwd_f32_t),
+ INSTANCE(jit_avx512_common_1x1_convolution_bwd_data_f32_t),
+ INSTANCE(jit_avx512_common_1x1_convolution_bwd_weights_t),
+ */
+ INSTANCE(jit_avx512_core_fp32_wino_conv_2x3_fwd_t),
+ INSTANCE(jit_avx512_core_fp32_wino_conv_4x3_fwd_t),
+ //INSTANCE(jit_avx512_core_fp32_wino_conv_4x3_bwd_data_t),
+ //INSTANCE(jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_t),
+ INSTANCE(jit_avx512_common_convolution_winograd_fwd_t),
+ //INSTANCE(jit_avx512_common_convolution_winograd_bwd_data_t),
+ //INSTANCE(jit_avx512_common_convolution_winograd_bwd_weights_t),
+ INSTANCE(jit_avx512_common_convolution_fwd_t<f32>),
+ //INSTANCE(jit_avx512_common_convolution_bwd_data_t<f32>),
+ //INSTANCE(jit_avx512_common_convolution_bwd_weights_t<f32>),
+ /*
+ INSTANCE(jit_avx2_dw_convolution_fwd_t),
+ INSTANCE(jit_avx2_dw_convolution_bwd_data_t),
+ INSTANCE(jit_avx2_dw_convolution_bwd_weights_t),
+ INSTANCE(jit_avx2_1x1_convolution_fwd_t),
+ INSTANCE(jit_avx2_1x1_convolution_bwd_data_t),
+ INSTANCE(jit_avx2_1x1_convolution_bwd_weights_t),
+ INSTANCE(jit_sse42_dw_convolution_fwd_t),
+ INSTANCE(jit_sse42_dw_convolution_bwd_data_t),
+ INSTANCE(jit_sse42_dw_convolution_bwd_weights_t),
+ INSTANCE(jit_sse42_1x1_convolution_fwd_t),
+ */
+ INSTANCE(jit_avx2_convolution_fwd_t),
+ //INSTANCE(jit_avx2_convolution_bwd_data_t),
+ //INSTANCE(jit_avx2_convolution_bwd_weights_t),
+ INSTANCE(jit_sse42_convolution_fwd_t),
+ /*
+ INSTANCE(gemm_convolution_fwd_t),
+ INSTANCE(gemm_convolution_bwd_data_t),
+ INSTANCE(gemm_convolution_bwd_weights_t),
+ INSTANCE(ref_convolution_fwd_t<f32>),
+ INSTANCE(ref_convolution_bwd_data_t<f32, f32, f32, f32>),
+ INSTANCE(ref_convolution_bwd_weights_t<f32, f32, f32, f32>),
+ */
+ /* conv (int) */
+ /*
+ INSTANCE(jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<f32>),
+ INSTANCE(jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<s32>),
+ INSTANCE(jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<s8>),
+ INSTANCE(jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<u8>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<u8,f32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<u8,s32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<u8,u8>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<u8,s8>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<s8,f32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<s8,s32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<s8,u8>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<s8,s8>),
+ INSTANCE(jit_avx512_core_x8s8s32x_convolution_fwd_t<u8,f32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_convolution_fwd_t<u8,s32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_convolution_fwd_t<u8,u8>),
+ INSTANCE(jit_avx512_core_x8s8s32x_convolution_fwd_t<u8,s8>),
+ INSTANCE(jit_avx512_core_x8s8s32x_convolution_fwd_t<s8,f32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_convolution_fwd_t<s8,s32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_convolution_fwd_t<s8,u8>),
+ INSTANCE(jit_avx512_core_x8s8s32x_convolution_fwd_t<s8,s8>),
+ INSTANCE(_gemm_x8s8s32x_convolution_fwd_t<u8, s32>),
+ INSTANCE(_gemm_x8s8s32x_convolution_fwd_t<u8, u8>),
+ INSTANCE(_gemm_x8s8s32x_convolution_fwd_t<u8, s8>),
+ INSTANCE(_gemm_x8s8s32x_convolution_fwd_t<u8, f32>),
+ INSTANCE(_gemm_x8s8s32x_convolution_fwd_t<s8, s32>),
+ INSTANCE(_gemm_x8s8s32x_convolution_fwd_t<s8, u8>),
+ INSTANCE(_gemm_x8s8s32x_convolution_fwd_t<s8, s8>),
+ INSTANCE(_gemm_x8s8s32x_convolution_fwd_t<s8, f32>),
+ INSTANCE(_gemm_u8s8s32x_convolution_bwd_data_t<s32>),
+ INSTANCE(_gemm_u8s8s32x_convolution_bwd_data_t<u8>),
+ INSTANCE(_gemm_u8s8s32x_convolution_bwd_data_t<s8>),
+ INSTANCE(_gemm_u8s8s32x_convolution_bwd_data_t<f32>),
+ INSTANCE(ref_convolution_fwd_t<u8, s8, f32, s32>),
+ INSTANCE(ref_convolution_fwd_t<u8, s8, s32, s32>),
+ INSTANCE(ref_convolution_fwd_t<u8, s8, s8, s32>),
+ INSTANCE(ref_convolution_fwd_t<u8, s8, u8, s32>),
+ INSTANCE(ref_convolution_bwd_data_t<f32, s8, u8, s32>),
+ INSTANCE(ref_convolution_bwd_data_t<s32, s8, u8, s32>),
+ INSTANCE(ref_convolution_bwd_data_t<s8, s8, u8, s32>),
+ INSTANCE(ref_convolution_bwd_data_t<u8, s8, u8, s32>),
+ */
+ /* deconv */
+ /*
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t<u8,f32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t<u8,s32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t<u8,u8>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t<u8,s8>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t<s8,f32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t<s8,s32>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t<s8,u8>),
+ INSTANCE(jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t<s8,s8>),
+ INSTANCE(_jit_avx512_core_x8s8s32x_deconvolution_fwd_t<u8,s32>),
+ INSTANCE(_jit_avx512_core_x8s8s32x_deconvolution_fwd_t<u8,u8>),
+ INSTANCE(_jit_avx512_core_x8s8s32x_deconvolution_fwd_t<u8,s8>),
+ INSTANCE(_jit_avx512_core_x8s8s32x_deconvolution_fwd_t<u8,f32>),
+ INSTANCE(_jit_avx512_core_x8s8s32x_deconvolution_fwd_t<s8,s32>),
+ INSTANCE(_jit_avx512_core_x8s8s32x_deconvolution_fwd_t<s8,u8>),
+ INSTANCE(_jit_avx512_core_x8s8s32x_deconvolution_fwd_t<s8,s8>),
+ INSTANCE(_jit_avx512_core_x8s8s32x_deconvolution_fwd_t<s8,f32>),
+ INSTANCE(ref_deconvolution_bwd_weights_t),
+ INSTANCE(ref_deconvolution_bwd_data_t),
+ INSTANCE(ref_deconvolution_fwd_t),
+ */
+ /* shuffle */
+ /*
+ INSTANCE(ref_shuffle_t<4>), // f32 or s32
+ INSTANCE(ref_shuffle_t<1>), // s8 or u8
+ */
+ /* eltwise */
+ /*
+ INSTANCE(jit_uni_eltwise_fwd_t<avx512_common>),
+ INSTANCE(jit_uni_eltwise_bwd_t<avx512_common>),
+ INSTANCE(jit_uni_eltwise_fwd_t<avx2>),
+ INSTANCE(jit_uni_eltwise_bwd_t<avx2>),
+ INSTANCE(jit_uni_eltwise_fwd_t<sse42>),
+ INSTANCE(jit_uni_eltwise_bwd_t<sse42>),
+ INSTANCE(ref_eltwise_fwd_t<f32>),
+ INSTANCE(ref_eltwise_bwd_t<f32>),
+ */
+ /* eltwise (int) */
+ /*
+ INSTANCE(ref_eltwise_fwd_t<s32>),
+ INSTANCE(ref_eltwise_fwd_t<s8>),
+ INSTANCE(ref_eltwise_fwd_t<u8>),
+ INSTANCE(ref_eltwise_bwd_t<s32>),
+ */
+ /* softmax */
+ /*
+ INSTANCE(ref_softmax_fwd_t<f32>),
+ INSTANCE(ref_softmax_bwd_t<f32>),
+ */
+ /* pool */
+ INSTANCE(jit_uni_pooling_fwd_t<avx512_common>),
+ //INSTANCE(jit_uni_pooling_bwd_t<avx512_common>),
+ INSTANCE(jit_uni_pooling_fwd_t<avx>),
+ //INSTANCE(jit_uni_pooling_bwd_t<avx>),
+ INSTANCE(jit_uni_pooling_fwd_t<sse42>),
+ //INSTANCE(jit_uni_pooling_bwd_t<sse42>),
+ /*
+ INSTANCE(nchw_pooling_fwd_t<f32>),
+ INSTANCE(nchw_pooling_bwd_t<f32>),
+ INSTANCE(nhwc_pooling_fwd_t<f32>),
+ INSTANCE(nhwc_pooling_bwd_t<f32>),
+ INSTANCE(ref_pooling_fwd_t<f32>),
+ INSTANCE(ref_pooling_bwd_t<f32>),
+ */
+ /* pool (int) */
+ /*
+ INSTANCE(jit_uni_i8i8_pooling_fwd_t<avx512_core>),
+ INSTANCE(jit_uni_i8i8_pooling_fwd_t<avx2>),
+ INSTANCE(ref_pooling_fwd_t<s32>),
+ INSTANCE(ref_pooling_fwd_t<s8, s32>),
+ INSTANCE(ref_pooling_fwd_t<u8, s32>),
+ INSTANCE(ref_pooling_bwd_t<s32>),
+ */
+ /* lrn */
+ /*
+ INSTANCE(jit_avx512_common_lrn_fwd_t),
+ INSTANCE(jit_avx512_common_lrn_bwd_t),
+ INSTANCE(jit_uni_lrn_fwd_t<avx2>),
+ INSTANCE(jit_uni_lrn_bwd_t<avx2>),
+ INSTANCE(jit_uni_lrn_fwd_t<sse42>),
+ INSTANCE(ref_lrn_fwd_t<f32>),
+ INSTANCE(ref_lrn_bwd_t<f32>),
+ */
+ /* batch normalization */
+ /*
+ INSTANCE(jit_uni_batch_normalization_fwd_t<avx512_common>),
+ INSTANCE(jit_uni_batch_normalization_bwd_t<avx512_common>),
+ INSTANCE(jit_uni_batch_normalization_fwd_t<avx2>),
+ INSTANCE(jit_uni_batch_normalization_bwd_t<avx2>),
+ INSTANCE(jit_uni_batch_normalization_fwd_t<sse42>),
+ INSTANCE(jit_uni_batch_normalization_bwd_t<sse42>),
+ INSTANCE(ncsp_batch_normalization_fwd_t),
+ INSTANCE(ncsp_batch_normalization_bwd_t),
+ INSTANCE(nspc_batch_normalization_fwd_t),
+ INSTANCE(nspc_batch_normalization_bwd_t),
+ INSTANCE(ref_batch_normalization_fwd_t<f32>),
+ INSTANCE(ref_batch_normalization_bwd_t<f32>),
+ INSTANCE(ref_batch_normalization_fwd_t<s8>),
+ */
+ /* inner product */
+ /*
+ INSTANCE(gemm_inner_product_fwd_t<f32>),
+ INSTANCE(gemm_inner_product_bwd_data_t<f32>),
+ INSTANCE(gemm_inner_product_bwd_weights_t<f32>),
+ INSTANCE(ref_inner_product_fwd_t<f32>),
+ INSTANCE(ref_inner_product_bwd_data_t<f32, f32, f32, f32>),
+ INSTANCE(ref_inner_product_bwd_weights_t<f32>),
+ */
+ /* inner product (int) */
+ /*
+ INSTANCE(gemm_x8s8s32x_inner_product_fwd_t<u8, u8>),
+ INSTANCE(gemm_x8s8s32x_inner_product_fwd_t<u8, s8>),
+ INSTANCE(gemm_x8s8s32x_inner_product_fwd_t<u8, s32>),
+ INSTANCE(gemm_x8s8s32x_inner_product_fwd_t<u8, f32>),
+ INSTANCE(gemm_x8s8s32x_inner_product_fwd_t<s8, u8>),
+ INSTANCE(gemm_x8s8s32x_inner_product_fwd_t<s8, s8>),
+ INSTANCE(gemm_x8s8s32x_inner_product_fwd_t<s8, s32>),
+ INSTANCE(gemm_x8s8s32x_inner_product_fwd_t<s8, f32>),
+ INSTANCE(ref_inner_product_fwd_t<u8, s8, u8, s32>),
+ INSTANCE(ref_inner_product_fwd_t<u8, s8, s8, s32>),
+ INSTANCE(ref_inner_product_fwd_t<u8, s8, s32, s32>),
+ INSTANCE(ref_inner_product_fwd_t<u8, s8, f32, s32>),
+ */
+ /* eol */
+ nullptr,
+};
+#undef INSTANCE
+}
+
+const pd_create_f* cpu_engine_t::get_implementation_list() const {
+ return cpu_impl_list;
+}
+
+cpu_engine_factory_t engine_factory;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_engine.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_engine.hpp
new file mode 100644
index 0000000000..e4c877ee05
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_engine.hpp
@@ -0,0 +1,70 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_ENGINE_HPP
+#define CPU_ENGINE_HPP
+
+#include <assert.h>
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "../common/engine.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+class cpu_engine_t: public engine_t {
+public:
+ cpu_engine_t(): engine_t(engine_kind::cpu) {}
+
+ /* implementation part */
+
+ virtual status_t memory_create(memory_t **memory,
+ const memory_desc_t *md, void *handle) override;
+
+ virtual const concat_primitive_desc_create_f*
+ get_concat_implementation_list() const override;
+ virtual const reorder_primitive_desc_create_f*
+ get_reorder_implementation_list() const override;
+ virtual const sum_primitive_desc_create_f*
+ get_sum_implementation_list() const override;
+ virtual const primitive_desc_create_f*
+ get_implementation_list() const override;
+};
+
+class cpu_engine_factory_t: public engine_factory_t {
+public:
+ virtual size_t count() const override { return 1; }
+ virtual engine_kind_t kind() const override { return engine_kind::cpu; }
+ virtual status_t engine_create(engine_t **engine,
+ size_t index) const override {
+ assert(index == 0);
+ *engine = new cpu_engine_t();
+ return status::success;
+ };
+};
+
+extern cpu_engine_factory_t engine_factory;
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_inner_product_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_inner_product_pd.hpp
new file mode 100644
index 0000000000..5880d3450c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_inner_product_pd.hpp
@@ -0,0 +1,84 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_INNER_PRODUCT_PD_HPP
+#define CPU_INNER_PRODUCT_PD_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "inner_product_pd.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace {
+inline bool dense_gemm_consitency_check(const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &wei_d, const memory_desc_wrapper &dst_d) {
+ using namespace utils;
+
+ auto strides_compatible = [&]() {
+ bool ok = true;
+ auto w_str = wei_d.blocking_desc().strides;
+ auto d_str = src_d.blocking_desc().strides;
+ for (int i = 1; i < src_d.ndims() - 1; i++) {
+ ok = ok && w_str[i] / d_str[i] == w_str[i + 1] / d_str[i + 1];
+ }
+ return ok && one_of(w_str[1] / d_str[1], 1, wei_d.padded_dims()[0]);
+ };
+ return true && src_d.is_blocking_desc() && wei_d.is_blocking_desc()
+ && src_d.ndims() == wei_d.ndims()
+ && src_d.blocking_desc().inner_nblks
+ == wei_d.blocking_desc().inner_nblks
+ && utils::one_of(src_d.blocking_desc().inner_nblks, 0, 1)
+ && array_cmp(src_d.blocking_desc().inner_blks,
+ wei_d.blocking_desc().inner_blks,
+ wei_d.blocking_desc().inner_nblks)
+ && array_cmp(src_d.blocking_desc().inner_idxs,
+ wei_d.blocking_desc().inner_idxs,
+ wei_d.blocking_desc().inner_nblks)
+ && strides_compatible()
+ && dst_d.matches_tag(format_tag::nc)
+ && src_d.only_padded_dim(1)
+ && wei_d.only_padded_dim(1)
+ && src_d.padded_dims()[1] == wei_d.padded_dims()[1]
+ && src_d.is_dense(true)
+ && dst_d.is_dense()
+ && wei_d.is_dense(true);
+}
+}
+
+struct cpu_inner_product_fwd_pd_t: public inner_product_fwd_pd_t {
+ using inner_product_fwd_pd_t::inner_product_fwd_pd_t;
+};
+
+struct cpu_inner_product_bwd_data_pd_t: public inner_product_bwd_data_pd_t {
+ using inner_product_bwd_data_pd_t::inner_product_bwd_data_pd_t;
+};
+
+struct cpu_inner_product_bwd_weights_pd_t: public inner_product_bwd_weights_pd_t {
+ using inner_product_bwd_weights_pd_t::inner_product_bwd_weights_pd_t;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_isa_traits.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_isa_traits.hpp
new file mode 100644
index 0000000000..da6e9dac8e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_isa_traits.hpp
@@ -0,0 +1,151 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_ISA_TRAITS_HPP
+#define CPU_ISA_TRAITS_HPP
+
+#include <type_traits>
+
+#define XBYAK64
+#define XBYAK_NO_OP_NAMES
+/* in order to make selinux happy memory that would be marked with X-bit should
+ * be obtained with mmap */
+#define XBYAK_USE_MMAP_ALLOCATOR
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+/* turn off `size_t to other-type implicit casting` warning
+ * currently we have a lot of jit-generated instructions that
+ * take uint32_t, but we pass size_t (e.g. due to using sizeof).
+ * FIXME: replace size_t parameters with the appropriate ones */
+#pragma warning (disable: 4267)
+#endif
+#include "xbyak/xbyak.h"
+#include "xbyak/xbyak_util.h"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+typedef enum {
+ isa_any,
+ sse41,
+ sse42,
+ avx,
+ avx2,
+ avx512_common,
+ avx512_core,
+ avx512_core_vnni,
+ avx512_mic,
+ avx512_mic_4ops,
+} cpu_isa_t;
+
+template <cpu_isa_t> struct cpu_isa_traits {}; /* ::vlen -> 32 (for avx2) */
+
+template <> struct cpu_isa_traits<sse42> {
+ typedef Xbyak::Xmm Vmm;
+ static constexpr int vlen_shift = 4;
+ static constexpr int vlen = 16;
+ static constexpr int n_vregs = 16;
+};
+template <> struct cpu_isa_traits<avx> {
+ typedef Xbyak::Ymm Vmm;
+ static constexpr int vlen_shift = 5;
+ static constexpr int vlen = 32;
+ static constexpr int n_vregs = 16;
+};
+template <> struct cpu_isa_traits<avx2>:
+ public cpu_isa_traits<avx> {};
+
+template <> struct cpu_isa_traits<avx512_common> {
+ typedef Xbyak::Zmm Vmm;
+ static constexpr int vlen_shift = 6;
+ static constexpr int vlen = 64;
+ static constexpr int n_vregs = 32;
+};
+template <> struct cpu_isa_traits<avx512_core>:
+ public cpu_isa_traits<avx512_common> {};
+
+template <> struct cpu_isa_traits<avx512_mic>:
+ public cpu_isa_traits<avx512_common> {};
+
+template <> struct cpu_isa_traits<avx512_mic_4ops>:
+ public cpu_isa_traits<avx512_common> {};
+
+namespace {
+
+static Xbyak::util::Cpu cpu;
+static inline bool mayiuse(const cpu_isa_t cpu_isa) {
+ using namespace Xbyak::util;
+
+ switch (cpu_isa) {
+ case sse41:
+ case sse42:
+ // FIXME: SSE4.2 is actually NOT required
+ //return cpu.has(Cpu::tSSE42);
+ return cpu.has(Cpu::tSSE41);
+ case avx:
+ return cpu.has(Cpu::tAVX);
+ case avx2:
+ return cpu.has(Cpu::tAVX2);
+ case avx512_common:
+ return cpu.has(Cpu::tAVX512F);
+ case avx512_core:
+ return true
+ && cpu.has(Cpu::tAVX512F)
+ && cpu.has(Cpu::tAVX512BW)
+ && cpu.has(Cpu::tAVX512VL)
+ && cpu.has(Cpu::tAVX512DQ);
+ case avx512_core_vnni:
+ return true
+ && cpu.has(Cpu::tAVX512F)
+ && cpu.has(Cpu::tAVX512BW)
+ && cpu.has(Cpu::tAVX512VL)
+ && cpu.has(Cpu::tAVX512DQ)
+ && cpu.has(Cpu::tAVX512_VNNI);
+ case avx512_mic:
+ return true
+ && cpu.has(Cpu::tAVX512F)
+ && cpu.has(Cpu::tAVX512CD)
+ && cpu.has(Cpu::tAVX512ER)
+ && cpu.has(Cpu::tAVX512PF);
+ case avx512_mic_4ops:
+ return true
+ && mayiuse(avx512_mic)
+ && cpu.has(Cpu::tAVX512_4FMAPS)
+ && cpu.has(Cpu::tAVX512_4VNNIW);
+ case isa_any:
+ return true;
+ }
+ return false;
+}
+}
+
+/* whatever is required to generate string literals... */
+#include "z_magic.hpp"
+#define JIT_IMPL_NAME_HELPER(prefix, isa, suffix_if_any) \
+ (isa == sse42 ? prefix STRINGIFY(sse42) : \
+ (isa == avx ? prefix STRINGIFY(avx) : \
+ (isa == avx2 ? prefix STRINGIFY(avx2) : \
+ (isa == avx512_common ? prefix STRINGIFY(avx512_common) : \
+ (isa == avx512_core ? prefix STRINGIFY(avx512_core) : \
+ (isa == avx512_mic ? prefix STRINGIFY(avx512_mic) : \
+ (isa == avx512_mic_4ops ? prefix STRINGIFY(avx512_mic_4ops) : \
+ prefix suffix_if_any)))))))
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_lrn_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_lrn_pd.hpp
new file mode 100644
index 0000000000..49988f4c2d
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_lrn_pd.hpp
@@ -0,0 +1,42 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_LRN_PD_HPP
+#define CPU_LRN_PD_HPP
+
+#include <assert.h>
+
+#include "lrn_pd.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_lrn_fwd_pd_t: public lrn_fwd_pd_t {
+ using lrn_fwd_pd_t::lrn_fwd_pd_t;
+};
+
+struct cpu_lrn_bwd_pd_t: public lrn_bwd_pd_t {
+ using lrn_bwd_pd_t::lrn_bwd_pd_t;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_memory.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_memory.cpp
new file mode 100644
index 0000000000..3c0624cf46
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_memory.cpp
@@ -0,0 +1,277 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "mkldnn_traits.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_memory.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::data_type;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::format_tag;
+
+enum blk_kind_t { a, b, c, ab, ba, bc, cb };
+
+template <data_type_t dt, blk_kind_t blk_kind, int blksize>
+void typed_zero_pad_blk(
+ const memory_desc_wrapper &m_d, typename prec_traits<dt>::type *data) {
+ using data_t = typename prec_traits<dt>::type;
+ const auto &dims = m_d.dims();
+ const auto &pdims = m_d.padded_dims();
+ const auto &blk = m_d.blocking_desc();
+ auto dim_is_blocked = [&](int dim) {
+ for (int i = 0; i < blk.inner_nblks; i++)
+ if (blk.inner_idxs[i] == dim)
+ return true;
+ return false;
+ };
+ bool A_blocked = dim_is_blocked(0), B_blocked = dim_is_blocked(1),
+ C_blocked = dim_is_blocked(2);
+
+ assert(blk.inner_nblks < 4);
+ assert((A_blocked || B_blocked || C_blocked) || (A_blocked && B_blocked)
+ || (C_blocked && B_blocked));
+
+ const int a_tail_s = A_blocked ? dims[0] % blksize : 0;
+ const int b_tail_s = B_blocked ? dims[1] % blksize : 0;
+ const int c_tail_s = C_blocked ? dims[2] % blksize : 0;
+ assert(a_tail_s || b_tail_s || c_tail_s);
+
+ const int A = A_blocked ? pdims[0] / blksize : dims[0];
+ const int B = B_blocked ? pdims[1] / blksize : dims[1];
+ const int C = C_blocked ? pdims[2] / blksize : dims[2];
+ const int D = m_d.ndims() > 3 ? dims[3] : 1;
+ const int E = m_d.ndims() > 4 ? dims[4] : 1;
+ const int F = m_d.ndims() > 5 ? dims[5] : 1;
+ const int inner_blk = blk.inner_nblks == 3 ? blk.inner_blks[2] : 1;
+
+ auto zeroize_tail = [&](data_t *d, const int tail_s) {
+ for (int b = tail_s; b < blksize; ++b)
+ d[b] = 0;
+ };
+ auto zeroize_tail_inner = [&](data_t *d, const int tail_s) {
+ for (int b1 = 0; b1 < blksize; ++b1)
+ for (int b2 = tail_s; b2 < blksize; ++b2)
+ d[(b1 / inner_blk) * blksize * inner_blk + inner_blk * b2
+ + b1 % inner_blk]
+ = 0;
+ };
+ auto zeroize_tail_outer = [&](data_t *d, const int tail_s) {
+ for (int b1 = tail_s; b1 < blksize; ++b1)
+ for (int b2 = 0; b2 < blksize; ++b2)
+ d[(b1 / inner_blk) * blksize * inner_blk + inner_blk * b2
+ + b1 % inner_blk]
+ = 0;
+ };
+
+ if (c_tail_s) {
+ parallel_nd(A, B, D, E, F, [&](int a, int b, int d, int e, int f) {
+ auto x = &data[m_d.blk_off(a, b, C - 1, d, e, f)];
+ if (blk_kind == c)
+ zeroize_tail(x, c_tail_s);
+ else if (blk_kind == bc)
+ zeroize_tail_inner(x, c_tail_s);
+ else if (blk_kind == cb)
+ zeroize_tail_outer(x, c_tail_s);
+ });
+ }
+
+ if (b_tail_s) {
+ parallel_nd(A, C, D, E, F, [&](int a, int c, int d, int e, int f) {
+ auto x = &data[m_d.blk_off(a, B - 1, c, d, e, f)];
+ if (blk_kind == b)
+ zeroize_tail(x, b_tail_s);
+ else if (blk_kind == ab || blk_kind == cb)
+ zeroize_tail_inner(x, b_tail_s);
+ else if (blk_kind == ba || blk_kind == bc)
+ zeroize_tail_outer(x, b_tail_s);
+ });
+ }
+
+ if (a_tail_s) {
+ parallel_nd(B, C, D, E, F, [&](int b, int c, int d, int e, int f) {
+ auto x = &data[m_d.blk_off(A - 1, b, c, d, e, f)];
+ if (blk_kind == a)
+ zeroize_tail(x, a_tail_s);
+ else if (blk_kind == ba)
+ zeroize_tail_inner(x, a_tail_s);
+ else if (blk_kind == ab)
+ zeroize_tail_outer(x, a_tail_s);
+ });
+ }
+}
+
+/*
+ * all
+ */
+template <data_type_t dt>
+void typed_zero_pad_generic_blocked(
+ const memory_desc_wrapper &m_d, typename prec_traits<dt>::type *data) {
+ const int ndims = m_d.ndims();
+ const auto &dims = m_d.dims();
+ const auto &pdims = m_d.padded_dims();
+
+ const ptrdiff_t nelems = (ptrdiff_t)m_d.nelems(true);
+
+ /* [D_0] .. [D_k][D_k+1] .. [D_ndim - 1]
+ * | \ /
+ * | ---------------------
+ * has contiguous
+ * padding
+ *
+ * step <-- D_k+1 * ... * D_ndims-1
+ * step_dim <-- k
+ */
+
+ ptrdiff_t step = 1;
+ int step_dim = ndims - 1;
+ for (; step_dim >= 0; --step_dim) {
+ if (dims[step_dim] != pdims[step_dim])
+ break;
+ step *= dims[step_dim];
+ }
+
+ assert(step_dim >= 0 && "no zero padding is required");
+ if (step_dim < 0)
+ return;
+
+ parallel_nd(nelems / step, [&](ptrdiff_t e1) {
+ bool need_zero = false;
+
+ ptrdiff_t idx = e1;
+ for (int d = step_dim; d >= 0; --d) {
+ if (idx % pdims[d] >= dims[d]) {
+ need_zero = true;
+ break;
+ }
+ idx /= pdims[d];
+ }
+
+ if (need_zero) {
+ for (ptrdiff_t e0 = 0; e0 < step; ++e0)
+ data[m_d.off_l(e1 * step + e0, true)] = 0;
+ }
+ });
+}
+
+template <data_type_t dt>
+status_t cpu_memory_t::typed_zero_pad() const {
+ const memory_desc_wrapper mdw(md());
+
+ if (mdw.format_kind() != format_kind::blocked)
+ return unimplemented;
+
+ if (mdw.nelems(false) == mdw.nelems(true))
+ return success;
+
+ auto *data = (typename prec_traits<dt>::type *)data_;
+ auto blk = mdw.blocking_desc();
+
+ auto get_blksize = [&](int ind) {
+ int blksize = 1;
+ for (int i = 0; i < blk.inner_nblks; i++) {
+ if (blk.inner_idxs[i] == ind)
+ blksize *= blk.inner_blks[i];
+ }
+ return blksize;
+ };
+ const int blksize = get_blksize(blk.inner_idxs[0]);
+
+# define CASE(blksize_, blk_kind) \
+ do { \
+ if (blksize == blksize_) { \
+ typed_zero_pad_blk<dt, blk_kind, blksize_>(mdw, data); \
+ return success; \
+ } \
+ } while(0)
+
+ switch (blk.inner_nblks) {
+ case 1:
+ if (blk.inner_idxs[0] == 0) {
+ CASE(4, a);
+ CASE(8, a);
+ CASE(16, a);
+ } else if (blk.inner_idxs[0] == 1) {
+ CASE(4, b);
+ CASE(8, b);
+ CASE(16, b);
+ }
+ break;
+ case 2:
+ case 3:
+ if (!IMPLICATION(blk.inner_nblks == 3,
+ blk.inner_idxs[0] == blk.inner_idxs[2]))
+ break;
+
+ if (blk.inner_idxs[0] == 0 && blk.inner_idxs[1] == 1) {
+ CASE(4, ab);
+ CASE(8, ab);
+ CASE(16, ab);
+ } else if (blk.inner_idxs[0] == 1 && blk.inner_idxs[1] == 0) {
+ CASE(4, ba);
+ CASE(8, ba);
+ CASE(16, ba);
+ }
+ if (blk.inner_idxs[0] == 1 && blk.inner_idxs[1] == 2) {
+ CASE(4, bc);
+ CASE(8, bc);
+ CASE(16, bc);
+ } else if (blk.inner_idxs[0] == 2 && blk.inner_idxs[1] == 1) {
+ CASE(4, cb);
+ CASE(8, cb);
+ CASE(16, cb);
+ }
+ break;
+ default: break;
+ }
+
+# undef CASE
+
+ // the last line of defence
+ typed_zero_pad_generic_blocked<dt>(mdw, data);
+ return success;
+}
+
+status_t cpu_memory_t::zero_pad() const {
+ memory_desc_wrapper mdw(md());
+ const bool skip_zeroing = false
+ || data_ == nullptr
+ || mdw.is_zero()
+ || !mdw.is_blocking_desc();
+ if (skip_zeroing) return success;
+
+ switch (mdw.data_type()) {
+ case f32: return typed_zero_pad<f32>();
+ case s32: return typed_zero_pad<s32>();
+ case s8: return typed_zero_pad<s8>();
+ case u8: return typed_zero_pad<u8>();
+ default: assert(!"memory is undefined"); return unimplemented;
+ }
+ return unimplemented;
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_memory.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_memory.hpp
new file mode 100644
index 0000000000..2c01bcc6af
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_memory.hpp
@@ -0,0 +1,89 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_MEMORY_HPP
+#define CPU_MEMORY_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory.hpp"
+#include "memory_desc_wrapper.hpp"
+
+#include "cpu_engine.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_memory_t: public memory_t {
+ cpu_memory_t(cpu_engine_t *engine, const memory_desc_t *md, void *handle)
+ : memory_t(engine, md)
+ , own_data_(handle == MKLDNN_NATIVE_HANDLE_ALLOCATE)
+ , data_((char *)handle) {}
+
+ cpu_memory_t(cpu_engine_t *engine, const memory_desc_t *md)
+ : cpu_memory_t(engine, md, nullptr) {}
+
+ ~cpu_memory_t() { if (own_data_) free(data_); }
+
+ virtual status_t init() override {
+ if (own_data_) {
+ data_ = nullptr;
+ const size_t size = memory_desc_wrapper(this->md()).size();
+ if (size) {
+ data_ = (char *)malloc(size, 64);
+ if (data_ == nullptr)
+ return status::out_of_memory;
+ }
+ }
+ return zero_pad();
+ }
+
+ cpu_engine_t *engine() const { return (cpu_engine_t *)memory_t::engine(); }
+
+ virtual status_t get_data_handle(void **handle) const override {
+ *handle = static_cast<void *>(data_);
+ return status::success;
+ }
+
+ virtual mkldnn::impl::status_t set_data_handle(void *handle) override {
+ if (own_data_) { free(data_); own_data_ = false; }
+ data_ = static_cast<char *>(handle);
+ return zero_pad();
+ }
+
+ virtual mkldnn::impl::status_t zero_pad() const override;
+
+private:
+ bool own_data_;
+ char *data_;
+
+ template <mkldnn::impl::data_type_t>
+ mkldnn::impl::status_t typed_zero_pad() const;
+
+ cpu_memory_t(const cpu_memory_t &) = delete;
+ cpu_memory_t &operator=(const cpu_memory_t &) = delete;
+ cpu_memory_t &operator=(cpu_memory_t &&) = delete;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_pooling_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_pooling_pd.hpp
new file mode 100644
index 0000000000..ac2daa415e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_pooling_pd.hpp
@@ -0,0 +1,40 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_POOLING_PD_HPP
+#define CPU_POOLING_PD_HPP
+
+#include "pooling_pd.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_pooling_fwd_pd_t: public pooling_fwd_pd_t {
+ using pooling_fwd_pd_t::pooling_fwd_pd_t;
+};
+
+struct cpu_pooling_bwd_pd_t: public pooling_bwd_pd_t {
+ using pooling_bwd_pd_t::pooling_bwd_pd_t;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_primitive.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_primitive.hpp
new file mode 100644
index 0000000000..56127f36c2
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_primitive.hpp
@@ -0,0 +1,83 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_PRIMITIVE_HPP
+#define CPU_PRIMITIVE_HPP
+
+#include "mkldnn.h"
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "primitive.hpp"
+#include "scratchpad.hpp"
+
+#define CTX_IN_MEM(type, arg) static_cast<type>(ctx.input(arg))
+#define CTX_OUT_MEM(type, arg) static_cast<type>(ctx.output(arg))
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_memory_t;
+
+struct cpu_primitive_t: public primitive_t {
+ cpu_primitive_t(const primitive_desc_t *pd,
+ bool use_global_scratchpad = false)
+ : primitive_t(pd)
+ , scratchpad_buffer_(nullptr)
+ , global_scratchpad_(nullptr)
+ {
+ const size_t scratchpad_size =
+ this->pd()->scratchpad_size(scratchpad_mode::library);
+
+ if (scratchpad_size) {
+ if (use_global_scratchpad)
+ global_scratchpad_ = create_scratchpad(scratchpad_size);
+ else
+ scratchpad_buffer_ = malloc(scratchpad_size, 64);
+ }
+ }
+
+ virtual ~cpu_primitive_t() {
+ delete global_scratchpad_;
+ free(scratchpad_buffer_);
+ }
+
+protected:
+ memory_tracking::grantor_t scratchpad(const exec_ctx_t &ctx) const {
+ void *ptr = nullptr;
+ if (pd()->attr()->scratchpad_mode_ == scratchpad_mode::user) {
+ ptr = CTX_OUT_MEM(void *, MKLDNN_ARG_SCRATCHPAD);
+ } else {
+ ptr = global_scratchpad_
+ ? global_scratchpad_->get() : scratchpad_buffer_;
+ }
+
+ return pd()->scratchpad_registry().grantor(ptr);
+ }
+
+private:
+ void *scratchpad_buffer_;
+ scratchpad_t *global_scratchpad_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reducer.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reducer.cpp
new file mode 100644
index 0000000000..1d41ac5cea
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reducer.cpp
@@ -0,0 +1,544 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "mkldnn_thread.hpp"
+#include "mkldnn_types.h"
+#include "nstl.hpp"
+#include "utils.hpp"
+
+#include "cpu_reducer.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace memory_tracking::names;
+
+void reduce_balancer_t::balance() {
+ using namespace nstl;
+ using namespace utils;
+
+ assert(nthr_ > 0 && job_size_ > 0 && njobs_ > 0 && reduction_size_ > 0);
+
+ const int job_complexity = 1;
+
+ const int min_njobs_per_group = max(1, njobs_ / nthr_);
+ const int max_njobs_per_group = max(1,
+ static_cast<int>(max_buffer_size_ / (nthr_ * job_size_)));
+
+ /* initial guess */
+ int ngroups = min(njobs_ / min_njobs_per_group, nthr_);
+ int nthr_per_group = syncable_ ? min(nthr_ / ngroups, reduction_size_) : 1;
+ int njobs_per_group_ub = div_up(njobs_, ngroups);
+
+ /* rough upper-bound estimation, will be fixed during brute force */
+ size_t thread_complexity_ub = njobs_ * job_size_ * reduction_size_;
+
+ /* brute force parameters for the best balance... */
+ for (int c_njobs_per_group = min_njobs_per_group;
+ c_njobs_per_group < njobs_; ++c_njobs_per_group) {
+ /* current assumption */
+ int c_ngroups = min(njobs_ / c_njobs_per_group, nthr_);
+ int c_nthr_per_group = syncable_
+ ? min(nthr_ / c_ngroups, reduction_size_) : 1;
+ int c_njobs_per_group_ub = div_up(njobs_, c_ngroups);
+
+ if (c_nthr_per_group > 1 && c_njobs_per_group_ub > max_njobs_per_group)
+ continue;
+
+ int c_thread_reduction_ub = div_up(reduction_size_, c_nthr_per_group);
+ size_t c_group_size_ub = job_size_ * c_njobs_per_group_ub;
+ size_t c_thread_complexity_ub = c_group_size_ub * (
+ job_complexity * c_thread_reduction_ub
+ + (c_nthr_per_group != 1));
+
+ if (c_thread_complexity_ub < thread_complexity_ub) {
+ ngroups = c_ngroups;
+ nthr_per_group = c_nthr_per_group;
+ njobs_per_group_ub = c_njobs_per_group_ub;
+ thread_complexity_ub = c_thread_complexity_ub;
+ }
+ }
+
+ assert(njobs_per_group_ub <= max_njobs_per_group || nthr_per_group == 1);
+ assert(ngroups * nthr_per_group <= nthr_);
+ assert((size_t)njobs_per_group_ub * job_size_ * nthr_ <= max_buffer_size_
+ || nthr_per_group == 1); /* no reduction buffer overflow */
+ assert(IMPLICATION(!syncable_, nthr_per_group == 1));
+
+ ngroups_ = ngroups;
+ nthr_per_group_ = nthr_per_group;
+ njobs_per_group_ub_ = njobs_per_group_ub;
+}
+
+/* reducer jit-ted driver */
+
+using namespace Xbyak;
+
+template <impl::data_type_t data_type>
+struct reducer_2d_driver_t: public c_compatible {
+ typedef typename prec_traits<data_type>::type data_t;
+
+ reducer_2d_driver_t(int n_src, size_t src_ld,
+ size_t src_step, size_t dst_step, bool nullify_dst)
+ : n_src_(n_src), src_ld_(src_ld), src_step_(src_step)
+ , dst_step_(dst_step), nullify_dst_(nullify_dst), ker_(nullptr) {}
+ virtual ~reducer_2d_driver_t() {}
+ void operator()(data_t *dst, const data_t *srcs, size_t ny, size_t nx)
+ { assert(ker_); ker_(dst, srcs, ny, nx); }
+
+protected:
+ int n_src_;
+ size_t src_ld_, src_step_, dst_step_;
+ bool nullify_dst_;
+ void (*ker_)(data_t *dst, const data_t *srcs, size_t ny, size_t nx);
+};
+
+template <impl::data_type_t data_type, cpu_isa_t isa>
+struct reducer_2d_driver_f_s_32_t: public reducer_2d_driver_t<data_type>,
+ public jit_generator
+{
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(reducer_2d_driver_f_s_32_t)
+
+ /* cpu specific part */
+ using Vmm = typename utils::conditional<isa == avx2, Ymm, Zmm>::type;
+ const AddressFrame &vmmword = (isa == avx2) ? yword : zword;
+ void uni_vadd(const Xmm& x1, const Xmm& x2, const Operand& op)
+ { if (data_type == data_type::f32) vaddps(x1, x2, op);
+ else vpaddd(x1, x2, op); }
+ void uni_add(const Xmm& x1, const Operand& op)
+ { if (data_type == data_type::f32) addss(x1, op); else paddd(x1, op); }
+
+ const int vlen = cpu_isa_traits<isa>::vlen;
+ const int typesize
+ = sizeof(typename mkldnn::impl::prec_traits<data_type>::type);
+ Xbyak::Reg64 reg_dst = abi_param1;
+ Xbyak::Reg64 reg_src = abi_param2;
+ Xbyak::Reg64 reg_ny = abi_param3;
+ Xbyak::Reg64 reg_nx = abi_param4;
+
+ Xbyak::Reg64 reg_x = rax;
+ Xbyak::Reg64 reg_src_id = r10;
+
+ reducer_2d_driver_f_s_32_t(int n_src, size_t src_ld, size_t src_step,
+ size_t dst_step, bool nullify_dst)
+ : reducer_2d_driver_t<data_type>(n_src, src_ld, src_step,
+ dst_step, nullify_dst)
+ { generate(); }
+
+ void nullify_dst(int nloads, int load_len) {
+ UNUSED(load_len);
+ for (int i = 0; i < nloads; ++i)
+ uni_vpxor(Vmm(i), Vmm(i), Vmm(i));
+ /* prefetches[dst] ? */
+ }
+
+ void load_dst(int nloads, int load_len) {
+ for (int i = 0; i < nloads; ++i) {
+ if (load_len == typesize)
+ movd(Xmm(i), ptr[reg_dst + i * load_len]);
+ else if (load_len == vlen)
+ vmovups(Vmm(i), ptr[reg_dst + i * load_len]);
+ else
+ assert(!"unsupported");
+ }
+ }
+
+ void store_dst(int nloads, int load_len) {
+ for (int i = 0; i < nloads; ++i) {
+ if (load_len == typesize)
+ movd(ptr[reg_dst + i * load_len], Xmm(i));
+ else if (load_len == vlen)
+ vmovups(ptr[reg_dst + i * load_len], Vmm(i));
+ else
+ assert(!"unsupported");
+ }
+ }
+
+ void accumulate(int nloads, int load_len, size_t base_off) {
+ for (int i = 0; i < nloads; ++i) {
+ size_t off = base_off + i * load_len;
+
+ if (load_len == typesize)
+ uni_add(Xmm(i), ptr[reg_src + off]);
+ else if (load_len == vlen)
+ uni_vadd(Vmm(i), Vmm(i), vmmword[reg_src + off]);
+ else
+ assert(!"unsupported");
+ }
+ }
+
+ void loop_x() {
+ const int nloads[] = {cpu_isa_traits<isa>::n_vregs, 1, 1};
+ const int nbranches = sizeof(nloads) / sizeof(nloads[0]);
+
+ const int load_len[nbranches] = {vlen, vlen, typesize};
+ Label loop_x_label[nbranches + 1];
+
+ mov(reg_x, reg_nx);
+
+ for (int id = 0; id < nbranches; ++id) {
+ L(loop_x_label[id]);
+
+ cmp(reg_x, nloads[id] * load_len[id]);
+ jl(loop_x_label[id + 1], T_NEAR);
+
+ if (this->nullify_dst_)
+ nullify_dst(nloads[id], load_len[id]);
+ else
+ load_dst(nloads[id], load_len[id]);
+
+ if (nloads[id] > 1) {
+ Label loop_srcs;
+ mov(reg_src_id, this->n_src_);
+ L(loop_srcs);
+
+ accumulate(nloads[id], load_len[id], 0);
+ add(reg_src, this->src_ld_ * typesize);
+
+ dec(reg_src_id);
+ jnz(loop_srcs, T_NEAR);
+
+ sub(reg_src, this->n_src_ * this->src_ld_ * typesize);
+ } else {
+ for (int src_id = 0; src_id < this->n_src_; ++src_id) {
+ const size_t base_off = src_id * this->src_ld_ * typesize;
+ accumulate(nloads[id], load_len[id], base_off);
+ }
+ }
+
+ store_dst(nloads[id], load_len[id]);
+
+ add(reg_src, nloads[id] * load_len[id]);
+ add(reg_dst, nloads[id] * load_len[id]);
+
+ sub(reg_x, nloads[id] * load_len[id]);
+
+ jmp(loop_x_label[id], T_NEAR);
+ }
+
+ L(loop_x_label[nbranches]);
+
+ /* restore address registers */
+ sub(reg_src, reg_nx);
+ sub(reg_dst, reg_nx);
+ }
+
+ void generate() {
+ assert(isa == avx2 || isa == avx512_common || isa == avx512_mic);
+
+ preamble();
+
+ shl(reg_nx, 2);
+
+ Label ny_loop;
+ L(ny_loop);
+
+ loop_x();
+
+ add(reg_dst, this->dst_step_ * typesize);
+ add(reg_src, this->src_step_ * typesize);
+
+ dec(reg_ny);
+ jnz(ny_loop, T_NEAR);
+
+ postamble();
+ this->ker_ = reinterpret_cast<decltype(this->ker_)>(
+ const_cast<uint8_t*>(this->getCode()));
+ }
+};
+
+template <impl::data_type_t data_type>
+inline reducer_2d_driver_t<data_type> *create_reduce_2d_drv(int n_src,
+ size_t src_ld, size_t src_step, size_t dst_step, bool nullify_dst) {
+ if (mayiuse(avx512_common))
+ return new reducer_2d_driver_f_s_32_t<data_type, avx512_common>(n_src,
+ src_ld, src_step, dst_step, nullify_dst);
+ else if (mayiuse(avx2))
+ return new reducer_2d_driver_f_s_32_t<data_type, avx2>(n_src, src_ld,
+ src_step, dst_step, nullify_dst);
+ assert(!"unimplemented");
+ return nullptr;
+}
+
+/* cpu_reducer_t */
+
+template <impl::data_type_t data_type>
+void cpu_reducer_t<data_type>::conf_t::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad) const {
+ if (balancer_.nthr_per_group_ == 1) return;
+
+ const size_t space_size = balancer_.ngroups_
+ * (balancer_.nthr_per_group_ - 1)
+ * cpu_reducer_t<data_type>::space_per_thread(balancer_);
+ scratchpad.book(key_reducer_space, sizeof(data_t) * space_size, PAGE_4K);
+ scratchpad.book(key_reducer_space_bctx,
+ sizeof(simple_barrier::ctx_t) * balancer_.ngroups_);
+}
+
+template <impl::data_type_t data_type>
+cpu_reducer_t<data_type>::cpu_reducer_t(const conf_t &conf)
+ : conf_(conf), drv_(nullptr)
+{
+ if (balancer().nthr_per_group_ == 1) return;
+
+ drv_ = create_reduce_2d_drv<data_type>(balancer().nthr_per_group_ - 1,
+ space_per_thread(balancer()), 0, 0, false);
+}
+
+template <impl::data_type_t data_type>
+cpu_reducer_t<data_type>::~cpu_reducer_t() { delete drv_; }
+
+template <impl::data_type_t data_type>
+typename cpu_reducer_t<data_type>::data_t *
+cpu_reducer_t<data_type>::get_local_ptr(int ithr, data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const {
+ const int id_in_grp = balancer().id_in_group(ithr);
+
+ /* threads 0 from each group writes directly to the destination */
+ if (id_in_grp == 0)
+ return dst + balancer().ithr_job_off(ithr) * balancer().job_size_;
+
+ const int grp_id = balancer().group_id(ithr);
+ const int offset_factor = grp_id * (balancer().nthr_per_group_ - 1)
+ + (id_in_grp - 1);
+
+ auto space = scratchpad.template get<data_t>(key_reducer_space);
+ return space + offset_factor * space_per_thread(balancer());
+}
+
+template <impl::data_type_t data_type>
+void cpu_reducer_t<data_type>::reduce_nolock(int ithr, data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const {
+ bool redundant_reduction = balancer().nthr_per_group_ == 1
+ || balancer().idle(ithr);
+ if (redundant_reduction) return;
+
+#ifdef SIMPLE_IMPL
+ if (balancer().id_in_group(ithr) != 0)
+ return; /* only threads 0 do the reduction */
+
+ const int njobs_in_grp = balancer().ithr_njobs(ithr);
+ data_t *d = get_local_ptr(ithr, dst, scratchpad);
+ for (int id_in_grp = 1; id_in_grp < balancer_.nthr_per_group_; ++id_in_grp)
+ {
+ const data_t *space = get_local_ptr(ithr + id_in_grp, dst, scratchpad);
+ for (size_t i = 0; i < (size_t)njobs_in_grp * balancer().job_size_; ++i)
+ d[i] += space[i];
+ }
+#else
+ using namespace utils;
+
+ const int id_in_grp = balancer().id_in_group(ithr);
+ const int njobs_in_grp = balancer().ithr_njobs(ithr);
+ const size_t cl = 64 / sizeof(data_t);
+
+ const size_t reduction_size = njobs_in_grp * balancer().job_size_;
+ size_t start{0}, end{0};
+ balance211(div_up(reduction_size, cl), balancer().nthr_per_group_,
+ id_in_grp, start, end);
+
+ if (start == end) return;
+
+ data_t *d = get_local_ptr(ithr - id_in_grp, dst, scratchpad) + start * cl;
+ const data_t *space = get_local_ptr(ithr - id_in_grp + 1, dst, scratchpad)
+ + start * cl;
+ const size_t len = nstl::min(end * cl, reduction_size) - start * cl;
+
+ (*drv_)(d, space, 1, len);
+#endif
+}
+
+template struct cpu_reducer_t<data_type::f32>;
+template struct cpu_reducer_t<data_type::s32>;
+
+/* cpu_reducer_2d_t */
+
+template <impl::data_type_t data_type>
+void cpu_reducer_2d_t<data_type>::conf_t::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad) const {
+ if (balancer_.nthr_per_group_ == 1) return;
+
+ const size_t space_size = balancer_.ngroups_ * balancer_.nthr_per_group_
+ * cpu_reducer_2d_t<data_type>::space_per_thread(balancer_);
+ scratchpad.book(key_reducer_space, sizeof(data_t) * space_size);
+ scratchpad.book(key_reducer_space_bctx,
+ sizeof(simple_barrier::ctx_t) * balancer_.ngroups_);
+}
+
+template <impl::data_type_t data_type>
+cpu_reducer_2d_t<data_type>::cpu_reducer_2d_t(const conf_t &conf)
+ : conf_(conf), drv_(nullptr)
+{
+ if (balancer().nthr_per_group_ == 1) return;
+
+ drv_ = create_reduce_2d_drv<data_type>(balancer().nthr_per_group_,
+ space_per_thread(balancer()), conf_.job_size_x_, conf_.dst_x_,
+ true);
+}
+
+template <impl::data_type_t data_type>
+cpu_reducer_2d_t<data_type>::~cpu_reducer_2d_t() { delete drv_; }
+
+template <impl::data_type_t data_type>
+typename cpu_reducer_2d_t<data_type>::data_t *cpu_reducer_2d_t<data_type>::
+get_local_ptr(int ithr, const memory_tracking::grantor_t &scratchpad) const {
+ const int id_in_grp = balancer().id_in_group(ithr);
+ const int grp_id = balancer().group_id(ithr);
+ const int offset_factor = grp_id * balancer().nthr_per_group_ + id_in_grp;
+ auto space = scratchpad.template get<data_t>(key_reducer_space);
+ return space + offset_factor * space_per_thread(balancer());
+}
+
+template <impl::data_type_t data_type>
+int cpu_reducer_2d_t<data_type>::choose_x_blocking(int nx, int ny,
+ int nthr_per_grp) const {
+ // find x_blocking for better balance reducing work between threads
+ assert(conf_.x_block_ > 0 && nx > conf_.x_block_
+ && nx % conf_.x_block_ == 0);
+ int x_blocking = nx / conf_.x_block_;
+ int min_x_blocking =
+ utils::div_up(x_blocking, nstl::max(1, nthr_per_grp / ny));
+ while (true) {
+ if (x_blocking % 2 == 0 && x_blocking >= min_x_blocking * 2)
+ x_blocking /= 2;
+ else if (x_blocking % 3 == 0 && x_blocking >= min_x_blocking * 3)
+ x_blocking /= 3;
+ else
+ break;
+ }
+ if (x_blocking >= min_x_blocking * 4) x_blocking = 1;
+ x_blocking *= conf_.x_block_;
+ return x_blocking;
+}
+
+template <impl::data_type_t data_type>
+void cpu_reducer_2d_t<data_type>::reduce_block(const data_t* space_base,
+ data_t *dst, int job, int start_y, int start_x,
+ int ny_start, int nx_start, int ny_step, int nx_step) const {
+ data_t *d = dst + (start_y + ny_start) * conf_.dst_x_
+ + start_x + nx_start;
+ const data_t *space = space_base + job * balancer().job_size_
+ + ny_start * conf_.job_size_x_ + nx_start;
+#ifdef SIMPLE_IMPL
+ for (int idg = 0; idg < balancer().nthr_per_group_; ++idg) {
+ const data_t *w = &space[idg * space_per_thread(balancer())];
+ for (int y = 0; y < ny_step; ++y)
+ for (int x = 0; x < nx_step; ++x) {
+ d[y * conf_.dst_x_ + x]
+ = (idg == 0 ? 0 : d[y * conf_.dst_x_ + x])
+ + w[y * conf_.job_size_x_ + x];
+ }
+ }
+#else
+ (*drv_)(d, space, ny_step, nx_step);
+#endif
+}
+
+template <impl::data_type_t data_type>
+void cpu_reducer_2d_t<data_type>::reduce_nolock(int ithr, data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const {
+ bool redundant_reduction = balancer().nthr_per_group_ == 1
+ || balancer().idle(ithr);
+ if (redundant_reduction) return;
+
+ const int id_in_grp = balancer().id_in_group(ithr);
+ const int njobs_in_grp = balancer().ithr_njobs(ithr);
+ const int njobs_x = utils::div_up(conf_.dst_x_, conf_.job_size_x_);
+ const int global_job_start = balancer().ithr_job_off(ithr);
+
+ const data_t *space_base = get_local_ptr(ithr - id_in_grp, scratchpad);
+
+ const int pr_grps = nstl::min(njobs_in_grp, balancer().nthr_per_group_);
+ const int pr_nthr_per_grp = balancer().nthr_per_group_ / pr_grps;
+
+ if (id_in_grp >= pr_grps * pr_nthr_per_grp)
+ return; /* idle */
+
+ const int pr_my_grp = id_in_grp / pr_nthr_per_grp;
+ const int pr_my_id = id_in_grp % pr_nthr_per_grp;
+
+ int pr_job_start{0}, pr_job_end{0};
+ balance211(njobs_in_grp, pr_grps, pr_my_grp, pr_job_start, pr_job_end);
+
+ for (int j = pr_job_start; j < pr_job_end; ++j) {
+ const int global_job = global_job_start + j;
+ const int j_y = global_job / njobs_x;
+ const int j_x = global_job % njobs_x;
+ const int start_y = j_y * conf_.job_size_y_;
+ const int start_x = j_x * conf_.job_size_x_;
+ const int ny = nstl::min(conf_.dst_y_ - start_y, conf_.job_size_y_);
+ const int nx = nstl::min(conf_.dst_x_ - start_x, conf_.job_size_x_);
+ int x_blocking = choose_x_blocking(nx, ny, pr_nthr_per_grp);
+
+ int nxy_start{0}, nxy_end{0};
+ balance211(ny * nx / x_blocking, pr_nthr_per_grp, pr_my_id,
+ nxy_start, nxy_end);
+ if (nxy_start == nxy_end) continue;
+ nxy_start *= x_blocking;
+ nxy_end *= x_blocking;
+
+ int nxy = nxy_start;
+ if (nxy % nx != 0) {
+ int nx_step = nstl::min(nx - nxy % nx, nxy_end - nxy);
+ reduce_block(space_base, dst, j, start_y, start_x,
+ nxy / nx, nxy % nx, 1, nx_step);
+ nxy += nx_step;
+ }
+ if ((nxy_end - nxy) > nx) {
+ int ny_step = (nxy_end - nxy) / nx;
+ reduce_block(space_base, dst, j, start_y, start_x,
+ nxy / nx, nxy % nx, ny_step, nx);
+ nxy += nx * ny_step;
+ }
+ if ((nxy_end - nxy) > 0) {
+ reduce_block(space_base, dst, j, start_y, start_x,
+ nxy / nx, nxy % nx, 1, nxy_end - nxy);
+ }
+ }
+}
+
+template struct cpu_reducer_2d_t<data_type::f32>;
+template struct cpu_reducer_2d_t<data_type::s32>;
+
+/* accumulator section */
+
+template <impl::data_type_t data_type>
+cpu_accumulator_1d_t<data_type>::cpu_accumulator_1d_t(): drv_(nullptr) {
+ drv_ = create_reduce_2d_drv<data_type>(1, 0, 0, 0, false);
+}
+
+template <impl::data_type_t data_type>
+cpu_accumulator_1d_t<data_type>::~cpu_accumulator_1d_t() {
+ delete drv_;
+}
+
+template <impl::data_type_t data_type>
+void cpu_accumulator_1d_t<data_type>::accumulate(data_t *dst,
+ const data_t *src, size_t size) {
+ (*drv_)(dst, src, 1, size);
+}
+
+template struct cpu_accumulator_1d_t<data_type::f32>;
+template struct cpu_accumulator_1d_t<data_type::s32>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reducer.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reducer.hpp
new file mode 100644
index 0000000000..27f5939cd2
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reducer.hpp
@@ -0,0 +1,334 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REDUCER_HPP
+#define CPU_REDUCER_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+#include "mkldnn_types.h"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+
+#include "cpu_barrier.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+/** class to perform balancing over 3D array
+ *
+ * Conceptually the reduction happens according to the picture below:
+ *
+ * <--job_size->
+ * +-----------+ +-----------+ +-----------+ ^
+ * | | | | | | |
+ * | | | | | | |
+ * | 1 | | 2 | . . . | njobs | | reduction_size
+ * | | | | | | |
+ * | | | | | | |
+ * +-----------+ +-----------+ +-----------+ v
+ *
+ * | | | | | | | | |
+ * v v v v v v v v v
+ * ===================================================== vertical reduction
+ *
+ * +-----------+ +-----------+ . . . +-----------+ result
+ *
+ * In a simple case the result must be contiguous in memory.
+ * @class cpu_reducer_t is an implementation.
+ *
+ * Threads are divided into groups. The groups are independent of each other.
+ * Each group may work on several jobs (the distribution is not uniform, since
+ * njobs might be not a multiple of groups). Threads within a group work on
+ * different parts of the reduction dimension. Thread 0 in each group is called
+ * master (@sa reduce_balancer_t::master()).
+ *
+ * If threading driver does not allow sync between sub-group of threads (e.g.
+ * Intel(R) TBB) the # of thread per group is enforced to be 1.
+ */
+struct reduce_balancer_t {
+ reduce_balancer_t() { init(1, 1, 1, 1, 0); } /* trivial balance */
+ reduce_balancer_t(int nthr, int job_size, int njobs, int reduction_size,
+ size_t max_buffer_size)
+ { init(nthr, job_size, njobs, reduction_size, max_buffer_size); }
+
+ reduce_balancer_t &init(int nthr, int job_size, int njobs,
+ int reduction_size, size_t max_buffer_size)
+ {
+ syncable_ = mkldnn_thr_syncable();
+ nthr_ = nthr;
+ job_size_ = job_size;
+ njobs_ = njobs;
+ reduction_size_ = reduction_size;
+ max_buffer_size_ = max_buffer_size;
+ balance();
+ return *this;
+ }
+
+ bool syncable_;
+ int nthr_;
+ int job_size_, njobs_, reduction_size_;
+
+ int ngroups_; /** number of independent work (thread) groups */
+ int nthr_per_group_; /** number of threads within a single work group */
+ int njobs_per_group_ub_; /** the max # of jobs within a work group */
+
+ bool master(int ithr) const { return id_in_group(ithr) == 0; }
+ bool idle(int ithr) const { return ithr >= nthr_per_group_ * ngroups_; }
+
+ int group_id(int ithr) const { return ithr / nthr_per_group_; }
+ int id_in_group(int ithr) const { return ithr % nthr_per_group_; }
+
+ int grp_njobs(int grp) const {
+ if (grp >= ngroups_) return 0;
+ return njobs_ / ngroups_ + (grp < njobs_ % ngroups_);
+ }
+ int grp_job_off(int grp) const {
+ if (grp >= ngroups_) return njobs_;
+ return njobs_ / ngroups_ * grp + nstl::min(grp, njobs_ % ngroups_);
+ }
+
+ int ithr_njobs(int ithr) const { return grp_njobs(group_id(ithr)); }
+ int ithr_job_off(int ithr) const { return grp_job_off(group_id(ithr)); }
+
+private:
+ size_t max_buffer_size_;
+ void balance();
+};
+
+/** forward declaration of reduce driver */
+template <impl::data_type_t data_type> struct reducer_2d_driver_t;
+
+/** class to perform a reduction over 3D array
+ *
+ * Balancing is based on @class reduce_balancer_t.
+ * Restrictions: the result of the reduction must be contiguous in memory. *
+ * The reduction happens according to the picture below (once more):
+ *
+ * <--job_size->
+ * +-----------+ +-----------+ +-----------+ ^
+ * | | | | | | |
+ * | | | | | | |
+ * | 1 | | 2 | . . . | njobs | | reduction_size
+ * | | | | | | |
+ * | | | | | | |
+ * +-----------+ +-----------+ +-----------+ v
+ *
+ * | | | | | | | | |
+ * v v v v v v v v v
+ * ===================================================== vertical reduction
+ *
+ * +-----------+ +-----------+ . . . +-----------+ (contiguous) result
+ *
+ * An example how work might be shared is shown below.
+ *
+ * In this example group 0 owns 2 (independent) jobs -- 2 big squares.
+ * The number of threads per group is also 2 (thread 0 of group 0 and thread 1
+ * of group 0). Master threads (i.e. threads with id 0 in corresponding group)
+ * from each group put the partial result directly into destination memory,
+ * while all the other threads with-in the group use workspace (on the picture
+ * the only thread 1). Once intermediate results obtained each group reduces
+ * corresponding part (own jobs) to the destination memory.
+ *
+ * <------- group 0 ------->
+ *
+ * +-----------+ +-----------+ ^
+ * | | | | | thread 0 of reduces to the dest-memory
+ * | | | | | group 0 +-----------+ +-----------+
+ * |- - - - - -| |- - - - - -| X
+ * | | | | | thread 1 of reduces to workspace[tid=1]:
+ * | | | | | group 0 +-----------+ +-----------+
+ * +-----------+ +-----------+ v
+ * | | | | | |
+ * v v v v v v
+ * ((barrier)) =============================
+ *
+ * dest-memory: +-----------+ +-----------+
+ */
+template <impl::data_type_t data_type>
+struct cpu_reducer_t {
+ typedef typename prec_traits<data_type>::type data_t;
+
+ struct conf_t {
+ conf_t() = default;
+ conf_t &init(const reduce_balancer_t &balancer)
+ { balancer_ = balancer; return *this; }
+
+ void init_scratchpad(memory_tracking::registrar_t &scratchpad) const;
+
+ reduce_balancer_t balancer_;
+ };
+
+ cpu_reducer_t(const conf_t &conf);
+ ~cpu_reducer_t();
+
+ /** initializes reducer.
+ * Must be called from a single thread prior to actual usage */
+ void init(const memory_tracking::grantor_t &scratchpad) const {
+ if (balancer().nthr_per_group_ == 1) return;
+
+ auto bctx = scratchpad.template get<simple_barrier::ctx_t>(
+ memory_tracking::names::key_reducer_space_bctx);
+ for (int i = 0; i < balancer().ngroups_; ++i)
+ simple_barrier::ctx_init(&bctx[i]);
+ }
+
+ /** for given thread returns the pointer where to put partial results.
+ * Reduction destination @p dst must be provided as well (master threads
+ * from each group will use it for partial result to reduce memory
+ * pressure).
+ *
+ * @note: job offset is already applied by get_local_ptr(), which means all
+ * threads should start writing from the very beginning of returned
+ * address.
+ */
+ data_t *get_local_ptr(int ithr, data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const;
+
+ /** performs the reduction with built-in synchronization. */
+ void reduce(int ithr, data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const {
+ bool redundant_reduction = balancer().nthr_per_group_ == 1
+ || balancer().idle(ithr);
+ if (redundant_reduction) return;
+
+ auto bctx = scratchpad.template get<simple_barrier::ctx_t>(
+ memory_tracking::names::key_reducer_space_bctx);
+ simple_barrier::barrier(&bctx[balancer().group_id(ithr)],
+ balancer().nthr_per_group_);
+
+ reduce_nolock(ithr, dst, scratchpad);
+ }
+
+ const reduce_balancer_t &balancer() const { return conf_.balancer_; }
+
+private:
+ static size_t space_per_thread(const reduce_balancer_t &balancer)
+ { return balancer.njobs_per_group_ub_ * balancer.job_size_; }
+
+ /* The scratchpad is organized as follows:
+ *
+ * data_t space[nthr_][njobs_per_group_ub_][jobs_size_];
+ * simple_barrier::ctx_t barriers[groups_]; */
+
+ const conf_t conf_;
+ reducer_2d_driver_t<data_type> *drv_;
+
+ void reduce_nolock(int ithr, data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const;
+};
+
+template <impl::data_type_t data_type>
+struct cpu_reducer_2d_t {
+ typedef typename prec_traits<data_type>::type data_t;
+
+ struct conf_t {
+ conf_t() = default;
+ conf_t &init(const reduce_balancer_t &balancer, int job_size_x,
+ int job_size_y, int x_block, int dst_x, int dst_y) {
+ balancer_ = balancer;
+ job_size_x_ = job_size_x;
+ job_size_y_ = job_size_y;
+ x_block_ = x_block;
+ dst_x_ = dst_x;
+ dst_y_ = dst_y;
+ return *this;
+ }
+
+ void init_scratchpad(memory_tracking::registrar_t &scratchpad) const;
+
+ reduce_balancer_t balancer_;
+ int job_size_x_, job_size_y_, x_block_, dst_x_, dst_y_;
+ };
+
+ cpu_reducer_2d_t(const conf_t &conf);
+ ~cpu_reducer_2d_t();
+
+ /** initializes reducer.
+ * Must be called from a single thread prior to actual usage */
+ void init(const memory_tracking::grantor_t &scratchpad) const {
+ if (balancer().nthr_per_group_ == 1) return;
+
+ auto bctx = scratchpad.template get<simple_barrier::ctx_t>(
+ memory_tracking::names::key_reducer_space_bctx);
+ for (int i = 0; i < balancer().ngroups_; ++i)
+ simple_barrier::ctx_init(&bctx[i]);
+ }
+
+ /** for given thread returns the pointer where to put partial results */
+ data_t *get_local_ptr(int ithr,
+ const memory_tracking::grantor_t &scratchpad) const;
+
+ /** performs the reduction with built-in synchronization. */
+ void reduce(int ithr, data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const {
+ bool redundant_reduction = balancer().nthr_per_group_ == 1
+ || balancer().idle(ithr);
+ if (redundant_reduction) return;
+
+ auto bctx = scratchpad.template get<simple_barrier::ctx_t>(
+ memory_tracking::names::key_reducer_space_bctx);
+ simple_barrier::barrier(&bctx[balancer().group_id(ithr)],
+ balancer().nthr_per_group_);
+
+ reduce_nolock(ithr, dst, scratchpad);
+ }
+
+ const reduce_balancer_t &balancer() const { return conf_.balancer_; }
+
+private:
+ static size_t space_per_thread(const reduce_balancer_t &balancer)
+ { return balancer.njobs_per_group_ub_ * balancer.job_size_; }
+
+ /* The scratchpad is organized as follows:
+ *
+ * data_t space[nthr_][njobs_per_group_ub_][jobs_size_];
+ * simple_barrier::ctx_t barriers[groups_]; */
+
+ const conf_t conf_;
+ reducer_2d_driver_t<data_type> *drv_;
+
+ int choose_x_blocking(int nx, int ny, int nthr_per_grp) const;
+ void reduce_block(const data_t* space_base, data_t *dst,
+ int job, int start_y, int start_x,
+ int ny_start, int nx_start, int ny_step, int nx_step) const;
+ void reduce_nolock(int ithr, data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const;
+};
+
+/** simple 1d accumulator: y[:] += x[:] */
+template <impl::data_type_t data_type>
+struct cpu_accumulator_1d_t {
+ typedef typename prec_traits<data_type>::type data_t;
+
+ cpu_accumulator_1d_t();
+ ~cpu_accumulator_1d_t();
+ void accumulate(data_t *dst, const data_t *src, size_t size);
+
+ reducer_2d_driver_t<data_type> *drv_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reorder.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reorder.cpp
new file mode 100644
index 0000000000..82be70353d
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reorder.cpp
@@ -0,0 +1,262 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "cpu_engine.hpp"
+#include "cpu_primitive.hpp"
+#include "cpu_reorder_pd.hpp"
+#include "cpu_memory.hpp"
+#include "type_helpers.hpp"
+
+#include "cpu/jit_uni_reorder.hpp"
+#include "cpu/simple_reorder.hpp"
+#include "cpu/wino_reorder.hpp"
+#include "cpu/rnn/rnn_reorders.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using rpd_create_f = mkldnn::impl::engine_t::reorder_primitive_desc_create_f;
+
+namespace {
+using namespace mkldnn::impl::data_type;
+using namespace mkldnn::impl::format_tag;
+
+#define REG_SR(idt, ifmt, odt, ofmt, ...) \
+ simple_reorder_t<idt, ifmt, odt, ofmt, __VA_ARGS__>::pd_t::create
+
+#define REG_SR_BIDIR(idt, ifmt, odt, ofmt) \
+ REG_SR(idt, ifmt, odt, ofmt, fmt_order::keep), \
+ REG_SR(idt, ifmt, odt, ofmt, fmt_order::reverse)
+
+#define REG_SR_DIRECT_COPY(idt, odt) \
+ REG_SR(idt, any, odt, any, fmt_order::any, spec::direct_copy), \
+ REG_SR(idt, any, odt, any, fmt_order::any, spec::direct_copy_except_dim_0)
+
+static const rpd_create_f cpu_reorder_impl_list[] = {
+ /* winograd */
+ wino_reorder_t<f32, f32>::pd_t::create,
+ //wino_reorder_t<f32, s8>::pd_t::create,
+
+ /* rnn reorders */
+ rnn_data_reorder_t<f32, u8>::pd_t::create,
+ rnn_weights_reorder_t<f32, f32>::pd_t::create,
+ rnn_weights_reorder_t<f32, s8>::pd_t::create,
+
+ /* conv reorders w/ compensation */
+ REG_SR(f32, any, s8, hwio, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(f32, any, s8, hwigo, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(s8, any, s8, hwio, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(s8, any, s8, hwigo, fmt_order::keep, spec::conv_s8s8),
+
+ REG_SR(f32, oiw, s8, OIw4i16o4i, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(f32, goiw, s8, gOIw4i16o4i, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(s8, oiw, s8, OIw4i16o4i, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(s8, goiw, s8, gOIw4i16o4i, fmt_order::keep, spec::conv_s8s8),
+
+ REG_SR(f32, oihw, s8, OIhw4i16o4i, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(f32, goihw, s8, gOIhw4i16o4i, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(s8, oihw, s8, OIhw4i16o4i, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(s8, goihw, s8, gOIhw4i16o4i, fmt_order::keep, spec::conv_s8s8),
+
+ REG_SR(f32, goihw, s8, gOIhw2i8o4i, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(s8, goihw, s8, gOIhw2i8o4i, fmt_order::keep, spec::conv_s8s8),
+
+ REG_SR(f32, goihw, s8, gOIhw4o4i, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(s8, goihw, s8, gOIhw4o4i, fmt_order::keep, spec::conv_s8s8),
+
+ REG_SR(f32, goiw, s8, Goiw16g, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(s8, goiw, s8, Goiw16g, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(f32, goihw, s8, Goihw16g, fmt_order::keep, spec::conv_s8s8),
+ REG_SR(s8, goihw, s8, Goihw16g, fmt_order::keep, spec::conv_s8s8),
+
+ /* regular reorders */
+
+#if defined(__INTEL_COMPILER) || (defined(__GNUC__) && !defined(__clang__))
+ /* Direct copy for icc which is faster than jitted code;
+ * Direct copy for gcc which might or might not be faster than jitted
+ * code, but still worth it because doesn't require jitting, i.e. much
+ * faster creation time. This is tentative solution and should be removed
+ * later (when we will cache jitted code?...). */
+ REG_SR_DIRECT_COPY(f32, f32),
+#endif
+
+#ifdef __INTEL_COMPILER
+ /* direct copy for icc, which is faster than jitted code */
+ /*
+ REG_SR_DIRECT_COPY(f32, s32),
+ REG_SR_DIRECT_COPY(f32, s8),
+ REG_SR_DIRECT_COPY(f32, u8),
+ REG_SR_DIRECT_COPY(s32, f32),
+ REG_SR_DIRECT_COPY(s32, s32),
+ REG_SR_DIRECT_COPY(s32, s8),
+ REG_SR_DIRECT_COPY(s32, u8),
+ REG_SR_DIRECT_COPY(s8, f32),
+ REG_SR_DIRECT_COPY(s8, s32),
+ REG_SR_DIRECT_COPY(s8, s8),
+ REG_SR_DIRECT_COPY(s8, u8),
+ REG_SR_DIRECT_COPY(u8, f32),
+ REG_SR_DIRECT_COPY(u8, s32),
+ REG_SR_DIRECT_COPY(u8, s8),
+ REG_SR_DIRECT_COPY(u8, u8),
+ */
+#endif
+
+ /* jit */
+ jit_uni_reorder_create,
+
+ /* fp32: flat <-> blocked with tail */
+ /*
+ REG_SR_BIDIR(f32, any, f32, nCw4c),
+ REG_SR_BIDIR(f32, any, f32, nCw8c),
+ REG_SR_BIDIR(f32, any, f32, OIw4i4o),
+ REG_SR_BIDIR(f32, any, f32, OIw8i8o),
+ REG_SR_BIDIR(f32, any, f32, OIw8o8i),
+ REG_SR_BIDIR(f32, any, f32, gOIw4i4o),
+ REG_SR_BIDIR(f32, any, f32, gOIw8i8o),
+ REG_SR_BIDIR(f32, any, f32, gOIw8o8i),
+
+ REG_SR_BIDIR(f32, any, f32, nCw16c),
+ REG_SR_BIDIR(f32, any, f32, OIw16o16i),
+ REG_SR_BIDIR(f32, any, f32, OIw16i16o),
+ REG_SR_BIDIR(f32, any, f32, IOw16o16i),
+ REG_SR_BIDIR(f32, any, f32, gOIw16o16i),
+ REG_SR_BIDIR(f32, any, f32, gOIw16i16o),
+ REG_SR_BIDIR(f32, any, f32, gIOw16o16i),
+
+ REG_SR_BIDIR(f32, any, f32, nChw4c),
+ REG_SR_BIDIR(f32, any, f32, nChw8c),
+ REG_SR_BIDIR(f32, any, f32, OIhw4i4o),
+ REG_SR_BIDIR(f32, any, f32, Ohwi8o),
+
+ REG_SR_BIDIR(f32, any, f32, OIhw8i8o),
+ REG_SR_BIDIR(f32, any, f32, OIhw8o8i),
+ REG_SR_BIDIR(f32, any, f32, gOIhw4i4o),
+ REG_SR_BIDIR(f32, any, f32, gOIhw4o4i),
+ REG_SR_BIDIR(f32, any, f32, gOhwi8o),
+ REG_SR_BIDIR(f32, any, f32, gOIhw8i8o),
+ REG_SR_BIDIR(f32, any, f32, gOIhw8o8i),
+
+ REG_SR_BIDIR(f32, any, f32, nChw16c),
+ REG_SR_BIDIR(f32, any, f32, Oihw4o),
+ REG_SR_BIDIR(f32, any, f32, Oihw16o),
+ REG_SR_BIDIR(f32, any, f32, Ohwi4o),
+ REG_SR_BIDIR(f32, any, f32, Ohwi16o),
+ REG_SR_BIDIR(f32, any, f32, OIhw16o16i),
+ REG_SR_BIDIR(f32, any, f32, OIhw16i16o),
+ REG_SR_BIDIR(f32, any, f32, IOhw16o16i),
+ REG_SR_BIDIR(f32, any, f32, gOihw4o),
+ REG_SR_BIDIR(f32, any, f32, gOihw16o),
+ REG_SR_BIDIR(f32, any, f32, gOhwi4o),
+ REG_SR_BIDIR(f32, any, f32, gOhwi16o),
+ REG_SR_BIDIR(f32, any, f32, gOIhw16o16i),
+ REG_SR_BIDIR(f32, any, f32, gOIhw16i16o),
+ REG_SR_BIDIR(f32, any, f32, gIOhw16o16i),
+
+ REG_SR_BIDIR(f32, any, f32, nCdhw4c),
+ REG_SR_BIDIR(f32, any, f32, nCdhw8c),
+ REG_SR_BIDIR(f32, any, f32, OIdhw4i4o),
+ REG_SR_BIDIR(f32, any, f32, Odhwi8o),
+ REG_SR_BIDIR(f32, any, f32, OIdhw8i8o),
+ REG_SR_BIDIR(f32, any, f32, OIdhw8o8i),
+ REG_SR_BIDIR(f32, any, f32, gOIdhw4i4o),
+ REG_SR_BIDIR(f32, any, f32, gOdhwi8o),
+ REG_SR_BIDIR(f32, any, f32, gOIdhw8i8o),
+ REG_SR_BIDIR(f32, any, f32, gOIdhw8o8i),
+
+ REG_SR_BIDIR(f32, any, f32, nCdhw16c),
+ REG_SR_BIDIR(f32, any, f32, Oidhw4o),
+ REG_SR_BIDIR(f32, any, f32, Oidhw16o),
+ REG_SR_BIDIR(f32, any, f32, Odhwi16o),
+ REG_SR_BIDIR(f32, any, f32, OIdhw16o16i),
+ REG_SR_BIDIR(f32, any, f32, OIdhw16i16o),
+ REG_SR_BIDIR(f32, any, f32, gOidhw4o),
+ REG_SR_BIDIR(f32, any, f32, gOidhw16o),
+ REG_SR_BIDIR(f32, any, f32, gOdhwi16o),
+ REG_SR_BIDIR(f32, any, f32, gOIdhw16o16i),
+ REG_SR_BIDIR(f32, any, f32, gOIdhw16i16o),
+ */
+
+ /* fp32: blocked <-> blocked with tail */
+ REG_SR_BIDIR(f32, nCw8c, f32, nCw16c),
+ REG_SR_BIDIR(f32, nChw8c, f32, nChw16c),
+ REG_SR_BIDIR(f32, nCdhw8c, f32, nCdhw16c),
+
+ /* int: flat <-> blocked with tail */
+ /*
+ REG_SR_BIDIR(f32, any, s32, nChw16c),
+ REG_SR_BIDIR(f32, any, s8, nChw16c),
+ REG_SR_BIDIR(f32, any, u8, nChw16c),
+ REG_SR_BIDIR(s32, any, f32, nChw16c),
+ REG_SR_BIDIR(s32, any, s32, nChw16c),
+ REG_SR_BIDIR(s32, any, s8, nChw16c),
+ REG_SR_BIDIR(s32, any, u8, nChw16c),
+ REG_SR_BIDIR(s8, any, f32, nChw16c),
+ REG_SR_BIDIR(s8, any, s32, nChw16c),
+ REG_SR_BIDIR(s8, any, s8, nChw16c),
+ REG_SR_BIDIR(s8, any, u8, nChw16c),
+ REG_SR_BIDIR(u8, any, f32, nChw16c),
+ REG_SR_BIDIR(u8, any, s32, nChw16c),
+ REG_SR_BIDIR(u8, any, s8, nChw16c),
+ REG_SR_BIDIR(u8, any, u8, nChw16c),
+
+ REG_SR_BIDIR(f32, any, f32, OIhw4i16o4i),
+ REG_SR_BIDIR(f32, any, s8, OIhw4i16o4i),
+ REG_SR_BIDIR(s8, any, f32, OIhw4i16o4i),
+ REG_SR_BIDIR(s8, any, s8, OIhw4i16o4i),
+ REG_SR_BIDIR(f32, any, s8, gOIhw4i16o4i),
+ REG_SR_BIDIR(s8, any, f32, gOIhw4i16o4i),
+ REG_SR_BIDIR(f32, any, f32, gOIhw4i16o4i),
+ REG_SR_BIDIR(s8, any, s8, gOIhw4i16o4i),
+ */
+
+ /* reference: the last line of defence */
+ /*
+ REG_SR(f32, any, f32, any, fmt_order::any, spec::reference),
+ REG_SR(f32, any, s32, any, fmt_order::any, spec::reference),
+ REG_SR(f32, any, s8, any, fmt_order::any, spec::reference),
+ REG_SR(f32, any, u8, any, fmt_order::any, spec::reference),
+
+ REG_SR(s32, any, f32, any, fmt_order::any, spec::reference),
+ REG_SR(s32, any, s32, any, fmt_order::any, spec::reference),
+ REG_SR(s32, any, s8, any, fmt_order::any, spec::reference),
+ REG_SR(s32, any, u8, any, fmt_order::any, spec::reference),
+
+ REG_SR(s8, any, f32, any, fmt_order::any, spec::reference),
+ REG_SR(s8, any, s32, any, fmt_order::any, spec::reference),
+ REG_SR(s8, any, s8, any, fmt_order::any, spec::reference),
+ REG_SR(s8, any, u8, any, fmt_order::any, spec::reference),
+
+ REG_SR(u8, any, f32, any, fmt_order::any, spec::reference),
+ REG_SR(u8, any, s32, any, fmt_order::any, spec::reference),
+ REG_SR(u8, any, u8, any, fmt_order::any, spec::reference),
+ REG_SR(u8, any, s8, any, fmt_order::any, spec::reference),
+ */
+
+ /* eol */
+ nullptr,
+};
+}
+
+const rpd_create_f *cpu_engine_t::get_reorder_implementation_list() const {
+ return cpu_reorder_impl_list;
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reorder_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reorder_pd.hpp
new file mode 100644
index 0000000000..1622eb6849
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_reorder_pd.hpp
@@ -0,0 +1,48 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REORDER_PD_HPP
+#define CPU_REORDER_PD_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "reorder_pd.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_reorder_pd_t: public reorder_pd_t {
+ using reorder_pd_t::reorder_pd_t;
+
+ status_t init() {
+ const auto &post_ops = attr()->post_ops_;
+ bool args_ok = IMPLICATION(post_ops.len_ != 0, post_ops.len_ == 1
+ && post_ops.entry_[0].kind == primitive_kind::sum);
+ scratchpad_engine_ = src_engine_;
+ return args_ok ? status::success : status::unimplemented;
+ }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_shuffle_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_shuffle_pd.hpp
new file mode 100644
index 0000000000..f16587b99f
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_shuffle_pd.hpp
@@ -0,0 +1,41 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_SHUFFLE_PD_HPP
+#define CPU_SHUFFLE_PD_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "shuffle_pd.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_shuffle_pd_t: public shuffle_pd_t {
+ using shuffle_pd_t::shuffle_pd_t;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_softmax_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_softmax_pd.hpp
new file mode 100644
index 0000000000..3a39eab974
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_softmax_pd.hpp
@@ -0,0 +1,45 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_SOFTMAX_PD_HPP
+#define CPU_SOFTMAX_PD_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "softmax_pd.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_softmax_fwd_pd_t: public softmax_fwd_pd_t {
+ using softmax_fwd_pd_t::softmax_fwd_pd_t;
+};
+
+struct cpu_softmax_bwd_pd_t: public softmax_bwd_pd_t {
+ using softmax_bwd_pd_t::softmax_bwd_pd_t;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_sum.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_sum.cpp
new file mode 100644
index 0000000000..1ab5d9f174
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_sum.cpp
@@ -0,0 +1,48 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "cpu_engine.hpp"
+
+/*
+#include "cpu/ref_sum.hpp"
+#include "cpu/simple_sum.hpp"
+*/
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using spd_create_f = mkldnn::impl::engine_t::sum_primitive_desc_create_f;
+
+namespace {
+#define INSTANCE(...) __VA_ARGS__::pd_t::create
+static const spd_create_f cpu_sum_impl_list[] = {
+ /*
+ INSTANCE(simple_sum_t<data_type::f32>),
+ INSTANCE(ref_sum_t),
+ */
+ nullptr,
+};
+#undef INSTANCE
+}
+
+const spd_create_f *cpu_engine_t::get_sum_implementation_list() const {
+ return cpu_sum_impl_list;
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/cpu_sum_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_sum_pd.hpp
new file mode 100644
index 0000000000..0965129f9b
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/cpu_sum_pd.hpp
@@ -0,0 +1,39 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_SUM_PD_HPP
+#define CPU_SUM_PD_HPP
+
+#include "c_types_map.hpp"
+#include "sum_pd.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_sum_pd_t: public sum_pd_t {
+ using sum_pd_t::sum_pd_t;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/gemm_utils_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/gemm_utils_f32.cpp
new file mode 100644
index 0000000000..a9810dec28
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/gemm_utils_f32.cpp
@@ -0,0 +1,372 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+#include <cmath>
+
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+#include "gemm_utils_f32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+namespace gemm_utils {
+#define BM_NOCOPY_AVX 64
+#define BN_NOCOPY_AVX 48
+#define BK_NOCOPY_AVX 384
+#define BN_LARGE_NOCOPY_AVX 192
+#define BM_SMALL_NOCOPY_AVX 16
+#define BN_SMALL_NOCOPY_AVX 1
+#define BK_SMALL_NOCOPY_AVX 4
+// Determine number of threads for each dimension of a 3-D partitioning
+// algorithm based on input parameters
+// m/n/k - First/second/third parameter for GEMM
+// nthrs - total available number of threads
+// nthrs_m/nthrs_n/nthrs_k - number of threads to use in each dimension
+// BM/BN/BK - blocking values
+void calc_nthr_nocopy_avx(int m, int n, int k,
+ int nthrs, int *nthrs_m, int *nthrs_n, int *nthrs_k, int *BM, int *BN,
+ int *BK)
+{
+ int nthr, nthr_m, nthr_n, nthr_k;
+ int MB, NB, KB;
+
+ nthr = nthrs;
+ nthr_m = (m + BM_NOCOPY_AVX - 1) / BM_NOCOPY_AVX;
+ nthr_n = (n + BN_NOCOPY_AVX - 1) / BN_NOCOPY_AVX;
+ nthr_k = 1;
+
+ // Partition along K dimension
+ // - if threading allows having barriers (e.g. OMP)
+ // - if there is not enough parallelism along M or N
+ if (mkldnn_thr_syncable()) {
+ int nthr_other = nthr_k = 1;
+ while ((nthr_m * nthr_n * nthr_other < nthr)
+ && (k / (nthr_other + 1) > BK_NOCOPY_AVX)) {
+ nthr_other++;
+ if ((nthr / nthr_other) * nthr_other > 0.9 * nthr)
+ nthr_k = nthr_other;
+ }
+ }
+ nthr /= nthr_k;
+
+ if (nthr_m == 1)
+ nthr_n = nthr;
+ if (nthr_n == 1)
+ nthr_m = nthr;
+
+ // Simple partition reduction
+ while (nthr_m * nthr_n > nthr)
+ if (nthr_m > nthr_n)
+ nthr_m--;
+ else
+ nthr_n--;
+ while (nthr_m * nthr_n < nthr)
+ if (nthr_m < nthr_n)
+ nthr_m++;
+ else
+ nthr_n++;
+
+ if ((nthr_m * nthr_n > nthr) && (nthr_m > 1) && (nthr_n > 1)) {
+
+ if (nthr_m <= nthr_n) {
+ nthr_m = (int)sqrt((double)nthr);
+ if (nthr_m > (m + BM_SMALL_NOCOPY_AVX - 1) / BM_SMALL_NOCOPY_AVX)
+ nthr_m = (m + BM_SMALL_NOCOPY_AVX - 1) / BM_SMALL_NOCOPY_AVX;
+ nthr_n = nthr / nthr_m;
+
+ while ((nthr_m > 1) && (nthr_m * nthr_n != nthr)) {
+ nthr_m--;
+ nthr_n = nthr / nthr_m;
+ }
+ } else {
+ nthr_n = (int)sqrt((double)nthr);
+ if (nthr_n > (n + BN_SMALL_NOCOPY_AVX - 1) / BN_SMALL_NOCOPY_AVX)
+ nthr_n = (n + BN_SMALL_NOCOPY_AVX - 1) / BN_SMALL_NOCOPY_AVX;
+ nthr_m = nthr / nthr_n;
+
+ while ((nthr_n > 1) && (nthr_m * nthr_n != nthr)) {
+ nthr_n--;
+ nthr_m = nthr / nthr_n;
+ }
+ }
+ }
+
+ MB = (m + nthr_m - 1) / nthr_m + BM_SMALL_NOCOPY_AVX - 1;
+ MB -= MB % BM_SMALL_NOCOPY_AVX;
+ NB = (n + nthr_n - 1) / nthr_n + BN_SMALL_NOCOPY_AVX - 1;
+ NB -= NB % BN_SMALL_NOCOPY_AVX;
+ KB = (k + nthr_k - 1) / nthr_k + BK_SMALL_NOCOPY_AVX - 1;
+ KB -= KB % BK_SMALL_NOCOPY_AVX;
+
+ if (MB * nthr_m > m)
+ nthr_m = (m + MB - 1) / MB;
+ if (NB * nthr_n > n)
+ nthr_n = (n + NB - 1) / NB;
+ if (KB * nthr_k > k)
+ nthr_k = (k + KB - 1) / KB;
+
+ *nthrs_m = nthr_m;
+ *nthrs_n = nthr_n;
+ *nthrs_k = nthr_k;
+
+ *BM = MB;
+ *BN = NB;
+ *BK = KB;
+}
+#undef BM_NOCOPY_AVX
+#undef BN_NOCOPY_AVX
+#undef BK_NOCOPY_AVX
+#undef BN_LARGE_NOCOPY_AVX
+#undef BM_SMALL_NOCOPY_AVX
+#undef BN_SMALL_NOCOPY_AVX
+#undef BK_SMALL_NOCOPY_AVX
+
+#define BM_NOCOPY_AVX512_COMMON 32
+#define BN_NOCOPY_AVX512_COMMON 64
+#define BK_NOCOPY_AVX512_COMMON 192
+#define BN_LARGE_NOCOPY_AVX512_COMMON 192
+#define BM_SMALL_NOCOPY_AVX512_COMMON 16
+#define BN_SMALL_NOCOPY_AVX512_COMMON 1
+#define BK_SMALL_NOCOPY_AVX512_COMMON 4
+// Determine number of threads for each dimension of a 3-D partitioning
+// algorithm based on input parameters
+// m/n/k - First/second/third parameter for GEMM
+// nthrs - total available number of threads
+// nthrs_m/nthrs_n/nthrs_k - number of threads to use in each dimension
+// BM/BN/BK - blocking values
+void calc_nthr_nocopy_avx512_common(int m,
+ int n, int k, int nthrs, int *nthrs_m, int *nthrs_n, int *nthrs_k,
+ int *BM, int *BN, int *BK)
+{
+ int nthr, nthr_m, nthr_n, nthr_k = 1;
+ int MB, NB, KB;
+ nthr = nthrs;
+
+ int counter = 0;
+ float ratio_float = 1.;
+ int ratio = 1;
+ nthr = nthrs;
+ int nthr_m_gt_n;
+
+ // Partition along K dimension
+ // - if threading allows having barriers (e.g. OMP)
+ // - if there is not enough parallelism along M or N
+ if (mkldnn_thr_syncable()) {
+ if (n <= 2 * BN_NOCOPY_AVX512_COMMON &&
+ m <= 2 * BM_NOCOPY_AVX512_COMMON * nthr) {
+ nthr_k = k / BK_NOCOPY_AVX512_COMMON;
+ if (nthr_k > nthr / 4)
+ nthr_k = nthr / 4;
+ if (nthr_k < 1)
+ nthr_k = 1;
+
+ while ((nthr_k > 1) && (nthr % nthr_k)) {
+ nthr_k--;
+ }
+ nthr /= nthr_k;
+ } else {
+ nthr_k = 1;
+ }
+ }
+ nthr_m = (m + BM_NOCOPY_AVX512_COMMON - 1) / BM_NOCOPY_AVX512_COMMON;
+ nthr_n = (n + BN_NOCOPY_AVX512_COMMON - 1) / BN_NOCOPY_AVX512_COMMON;
+
+ if (nthr_m < 1)
+ nthr_m = 1;
+ if (nthr_n < 1)
+ nthr_n = 1;
+
+ nthr_m_gt_n = nthr_m > nthr_n ? 1 : 0;
+ ratio_float = (float)nthr_m / nthr_n;
+
+ if (nthr_m_gt_n)
+ ratio = (int)ratio_float;
+ else
+ ratio = (int)(1. / ratio_float);
+
+ // scale down nthr_m and nthr_n if they are too large
+ while (nthr_m * nthr_n > 4 * nthr) {
+ nthr_m /= 2;
+ nthr_n /= 2;
+ }
+
+ if (nthr_m < 1)
+ nthr_m = 1;
+ if (nthr_n < 1)
+ nthr_n = 1;
+
+ // Simple partition reduction
+ counter = 0;
+ while (nthr_m * nthr_n > nthr) {
+ if (nthr_m > nthr_n) {
+ if (counter < ratio)
+ nthr_m--;
+ else {
+ nthr_n--;
+ counter = -1;
+ }
+ } else {
+ if (counter < ratio)
+ nthr_n--;
+ else {
+ nthr_m--;
+ counter = -1;
+ }
+ }
+ counter++;
+ }
+
+ // Simple partition increment
+ counter = 0;
+ while (nthr_m * nthr_n < 0.95 * nthr) {
+ if (nthr_m > nthr_n) {
+ if (counter < ratio)
+ nthr_m++;
+ else {
+ nthr_n++;
+ counter = -1;
+ }
+ } else {
+ if (counter < ratio)
+ nthr_n++;
+ else {
+ nthr_m++;
+ counter = -1;
+ }
+ }
+ counter++;
+ }
+
+ // if nothing works out, then this should work
+ if ((nthr_m * nthr_n > nthr)) {
+
+ if (nthr_m <= nthr_n) {
+ nthr_m = (int)sqrt((double)nthr);
+ if (nthr_m > (m + BM_SMALL_NOCOPY_AVX512_COMMON - 1)
+ / BM_SMALL_NOCOPY_AVX512_COMMON)
+ nthr_m = (m + BM_SMALL_NOCOPY_AVX512_COMMON - 1)
+ / BM_SMALL_NOCOPY_AVX512_COMMON;
+ nthr_n = nthr / nthr_m;
+
+ while ((nthr_m > 1) && (nthr_m * nthr_n != nthr)) {
+ nthr_m--;
+ nthr_n = nthr / nthr_m;
+ }
+ } else {
+ nthr_n = (int)sqrt((double)nthr);
+ if (nthr_n > (n + BN_SMALL_NOCOPY_AVX512_COMMON - 1)
+ / BN_SMALL_NOCOPY_AVX512_COMMON)
+ nthr_n = (n + BN_SMALL_NOCOPY_AVX512_COMMON - 1)
+ / BN_SMALL_NOCOPY_AVX512_COMMON;
+ nthr_m = nthr / nthr_n;
+
+ while ((nthr_n > 1) && (nthr_m * nthr_n != nthr)) {
+ nthr_n--;
+ nthr_m = nthr / nthr_n;
+ }
+ }
+ }
+
+ MB = (m + nthr_m - 1) / nthr_m + BM_SMALL_NOCOPY_AVX512_COMMON - 1;
+ MB -= MB % BM_SMALL_NOCOPY_AVX512_COMMON;
+ NB = (n + nthr_n - 1) / nthr_n + BN_SMALL_NOCOPY_AVX512_COMMON - 1;
+ NB -= NB % BN_SMALL_NOCOPY_AVX512_COMMON;
+ KB = (k + nthr_k - 1) / nthr_k + BK_SMALL_NOCOPY_AVX512_COMMON - 1;
+ KB -= KB % BK_SMALL_NOCOPY_AVX512_COMMON;
+
+ if (MB * nthr_m > m)
+ nthr_m = (m + MB - 1) / MB;
+ if (NB * nthr_n > n)
+ nthr_n = (n + NB - 1) / NB;
+ if (KB * nthr_k > k)
+ nthr_k = (k + KB - 1) / KB;
+
+ *nthrs_m = nthr_m;
+ *nthrs_n = nthr_n;
+ *nthrs_k = nthr_k;
+
+ *BM = MB;
+ *BN = NB;
+ *BK = KB;
+}
+#undef BM_NOCOPY_AVX512_COMMON
+#undef BN_NOCOPY_AVX512_COMMON
+#undef BK_NOCOPY_AVX512_COMMON
+#undef BN_LARGE_NOCOPY_AVX512_COMMON
+#undef BM_SMALL_NOCOPY_AVX512_COMMON
+#undef BN_SMALL_NOCOPY_AVX512_COMMON
+#undef BK_SMALL_NOCOPY_AVX512_COMMON
+
+// Partition n values as equally as possible among nthr threads
+// and set the offset (t_offset) and number of values (t_block) for ithr
+// Assumption: 0 <= ithr < nthr
+void partition_unit_diff(
+ int ithr, int nthr, int n, int *t_offset, int *t_block)
+{
+ int band = n / nthr;
+ if (band == 0)
+ band = 1;
+ int tail = n - band * nthr;
+ if (tail < 0)
+ tail = 0;
+
+ if (ithr < tail) {
+ band++;
+ *t_offset = band * ithr;
+ *t_block = band;
+ } else {
+ *t_offset = band * ithr + tail;
+ *t_block = band;
+ }
+
+ if (*t_offset >= n) {
+ *t_offset = 0;
+ *t_block = 0;
+ }
+
+ if (*t_offset + *t_block > n) {
+ *t_block = n - *t_offset;
+ }
+}
+
+// Sum the m*n values from p_src into p_dst, assuming the two-dimensional
+// arrays have leading dimensions ld_src and ld_dst, respectively
+template<typename data_t>
+void sum_two_matrices(int m, int n,
+ data_t * __restrict p_src, dim_t ld_src,
+ data_t * __restrict p_dst, dim_t ld_dst)
+{
+ int i, j;
+ for (j = 0; j < n; j++) {
+ for (i = 0; i < m; i++) {
+ p_dst[i + j * ld_dst] += p_src[i + j * ld_src];
+ }
+ }
+}
+
+template
+void sum_two_matrices<float>(int m, int n,
+ float * __restrict p_src, dim_t ld_src,
+ float * __restrict p_dst, dim_t ld_dst);
+
+template
+void sum_two_matrices<double>(int m, int n,
+ double * __restrict p_src, dim_t ld_src,
+ double * __restrict p_dst, dim_t ld_dst);
+}
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/gemm_utils_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/gemm_utils_f32.hpp
new file mode 100644
index 0000000000..3352298b4a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/gemm_utils_f32.hpp
@@ -0,0 +1,72 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef GEMM_UTILS_HPP
+#define GEMM_UTILS_HPP
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace gemm_utils {
+// Alias for any dimension related variable.
+typedef ptrdiff_t dim_t;
+
+template <typename T, bool isTransA, bool isTransB>
+struct gemm_traits {};
+
+template <bool isTransA, bool isTransB>
+struct gemm_traits<double, isTransA, isTransB> {
+ static constexpr int m = 8;
+ static constexpr int n = 6;
+ static constexpr int BM = 4032;
+ static constexpr int BN = isTransA ? 96 : 192;
+ static constexpr int BK = isTransB ? 96 : 512;
+};
+
+template <bool isTransA, bool isTransB>
+struct gemm_traits<float, isTransA, isTransB> {
+ static constexpr int m = 16;
+ static constexpr int n = 6;
+ static constexpr int BM = 4032;
+ static constexpr int BN = isTransA ? 96 : 48;
+ static constexpr int BK = isTransB ? 96 : 256;
+};
+
+template <typename T>
+using unroll_factor = gemm_traits<T, false, false>;
+
+template <typename data_t>
+void sum_two_matrices(int m, int n,
+ data_t * __restrict p_src, dim_t ld_src,
+ data_t * __restrict p_dst, dim_t ld_dst);
+
+void calc_nthr_nocopy_avx512_common(int m,
+ int n, int k, int nthrs, int *nthrs_m, int *nthrs_n, int *nthrs_k,
+ int *BM, int *BN, int *BK);
+
+void calc_nthr_nocopy_avx(int m, int n, int k,
+ int nthrs, int *nthrs_m, int *nthrs_n, int *nthrs_k, int *BM, int *BN,
+ int *BK);
+
+void partition_unit_diff(
+ int ithr, int nthr, int n, int *t_offset, int *t_block);
+};
+
+}
+}
+}
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx512_common_gemm_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx512_common_gemm_f32.cpp
new file mode 100644
index 0000000000..d7be43e392
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx512_common_gemm_f32.cpp
@@ -0,0 +1,2131 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <cmath>
+#include <mutex>
+
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "ref_gemm_f32.hpp"
+#include "gemm_utils_f32.hpp"
+#include "jit_avx512_common_gemm_f32.hpp"
+
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+#define CACHE_LINE_SIZE 64
+
+#define STACKSIZE get_size_of_abi_save_regs()
+#ifdef _WIN32
+#define STACK_K_CAPACITY 32
+#else
+#define STACK_K_CAPACITY 2048
+#endif
+#define SIZE 4
+#define OFFSET 128
+#define BASE_SHIFT 2
+#define SECOND_FETCH unroll_n
+#define UNROLL_M 48
+#define UNROLL_N 8
+
+namespace avx512_common_gemm_f32 {
+using namespace gemm_utils;
+
+struct xbyak_gemm : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_common_gemm_f32_xbyak_gemm)
+
+ xbyak_gemm(char isTransA, char isTransB, float beta, bool hasBias = false,
+ void *code_ptr = nullptr,
+ size_t code_size = 80 * Xbyak::DEFAULT_MAX_CODE_SIZE)
+ : jit_generator(code_ptr, code_size)
+ {
+ using namespace Xbyak;
+
+ enum { ver_avx512_core, ver_avx512_mic } ver =
+ mayiuse(avx512_core) ? ver_avx512_core : ver_avx512_mic;
+
+ bool isBeta0 = (beta == 0.0);
+ bool isBetaN = (!isBeta0 && beta != 1.0);
+
+ // various definitions for convenience
+ auto ARG_M = abi_param1;
+ auto ARG_N = abi_param2;
+ auto K = abi_param3;
+ auto ARG_ALPHA = abi_param4;
+#ifdef _WIN32
+ auto ARG_A = ptr[rsp + OFFSET_SHADOWSPACE + STACKSIZE];
+ auto ARG_LDA = qword[rsp + OFFSET_SHADOWSPACE +
+ sizeof(float *) + STACKSIZE];
+ const auto stackOffset = OFFSET_SHADOWSPACE +
+ sizeof(float *) + STACKSIZE;
+ auto A = rsi;
+ auto LDA = rdi;
+#else
+ auto ARG_A = r8;
+ auto ARG_LDA = r9;
+ const auto stackOffset = STACKSIZE;
+ auto A = ARG_A;
+ auto LDA = ARG_LDA;
+#endif
+ auto ARG_B = ptr[rsp + 8 + stackOffset];
+ auto ARG_LDB = ptr[rsp + 16 + stackOffset];
+ auto ARG_BETA = ptr[rsp + 24 + stackOffset];
+ auto ARG_C = ptr[rsp + 32 + stackOffset];
+ auto ARG_LDC = ptr[rsp + 40 + stackOffset];
+ auto ARG_BIAS = ptr[rsp + 48 + stackOffset];
+ auto ARG_WS = ptr[rsp + 56 + stackOffset];
+
+ auto B = r11;
+ auto LDB = rbx;
+ auto LDC = r13;
+ auto LL = rax;
+ auto AO1 = abi_param2;
+ auto BO1 = abi_param4;
+ auto BO2 = rbp;
+ auto CO1 = r14;
+ auto CO2 = r15;
+ auto LDB3 = r10;
+ auto LDA4 = abi_param1;
+ auto AA = r12;
+ auto BIAS1 = abi_param1;
+
+ auto M = qword[rsp + 0];
+ auto N = qword[rsp + 8];
+ auto FLAG = qword[rsp + 16];
+ auto I = qword[rsp + 24];
+ auto C = qword[rsp + 32];
+ auto BIAS = qword[rsp + 40];
+ auto ALPHA = qword[rsp + 48];
+ auto BETA = qword[rsp + 64];
+ auto ORIG_A = qword[rsp + 80];
+ auto ORIG_SP = qword[rsp + 120];
+
+ auto ZSTRIDE = zmm4;
+ auto VALPHA = zmm6;
+ auto VBETA = zmm7;
+ auto VBIAS1 = zmm1;
+ auto VBIAS2 = zmm2;
+ auto VBIAS3 = zmm3;
+
+ auto PREFETCHSIZEA = ver == ver_avx512_core ? 48 : 80;
+ auto PREFETCHSIZEB = 16;
+
+ Zmm regs[] = { zmm8, zmm9, zmm10, zmm11, zmm12, zmm13, zmm14, zmm15,
+ zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23, zmm24,
+ zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31 };
+
+ // Function for packing if needed
+ auto do_pack = [&](int unroll_m) {
+ Label pack2, pack3, pack4, pack10;
+
+ mov(BO1, A);
+ lea(AO1, ptr[rsp + 128 + OFFSET * SIZE]);
+ mov(LL, K);
+ sar(LL, 2);
+ jle(pack3, T_NEAR);
+ align(16);
+
+ L(pack2);
+ if (!isTransA) {
+ for (int i = 0; i < 4; i++) {
+ vmovups(zmm0 | k1, ptr[BO1 + (0 * 16 - OFFSET) * SIZE]);
+ if (unroll_m > 16)
+ vmovups(zmm1 | k2, ptr[BO1 + (1 * 16 - OFFSET) * SIZE]);
+ if (unroll_m > 32)
+ vmovups(zmm2 | k3, ptr[BO1 + (2 * 16 - OFFSET) * SIZE]);
+ add(BO1, LDA);
+
+ vmovups(ptr[AO1 + (unroll_m * i + 0 * 16 - OFFSET) * SIZE]
+ | k1,
+ zmm0);
+ if (unroll_m > 16)
+ vmovups(ptr[AO1
+ + (unroll_m * i + 1 * 16 - OFFSET)
+ * SIZE]
+ | k2,
+ zmm1);
+ if (unroll_m > 32)
+ vmovups(ptr[AO1
+ + (unroll_m * i + 2 * 16 - OFFSET)
+ * SIZE]
+ | k3,
+ zmm2);
+ }
+ } else {
+ for (int i = 0; i < 4; i++) {
+ kmovw(k4, k1);
+ vgatherqps(ymm5 | k4,
+ ptr[BO1 + ZSTRIDE + (i - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO1 + LDA * 8]);
+ kshiftrw(k4, k1, 8);
+ vgatherqps(ymm6 | k4,
+ ptr[BO2 + ZSTRIDE + (i - OFFSET) * SIZE]);
+ vshuff64x2(zmm0, zmm5, zmm6, 0x44);
+
+ if (unroll_m > 16) {
+ lea(BO2, ptr[BO2 + LDA * 8]);
+ kmovw(k4, k2);
+ vgatherqps(ymm5 | k4,
+ ptr[BO2 + ZSTRIDE + (i - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDA * 8]);
+ kshiftrw(k4, k2, 8);
+ vgatherqps(ymm6 | k4,
+ ptr[BO2 + ZSTRIDE + (i - OFFSET) * SIZE]);
+ vshuff64x2(zmm1, zmm5, zmm6, 0x44);
+ }
+
+ if (unroll_m > 32) {
+ lea(BO2, ptr[BO2 + LDA * 8]);
+ kmovw(k4, k3);
+ vgatherqps(ymm5 | k4,
+ ptr[BO2 + ZSTRIDE + (i - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDA * 8]);
+ kshiftrw(k4, k3, 8);
+ vgatherqps(ymm6 | k4,
+ ptr[BO2 + ZSTRIDE + (i - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDA * 8]);
+ vshuff64x2(zmm2, zmm5, zmm6, 0x44);
+ }
+
+ vmovups(ptr[AO1 + (unroll_m * i + 0 * 16 - OFFSET) * SIZE],
+ zmm0 | k1);
+ if (unroll_m > 16)
+ vmovups(ptr[AO1
+ + (unroll_m * i + 1 * 16 - OFFSET)
+ * SIZE],
+ zmm1 | k2);
+ if (unroll_m > 32)
+ vmovups(ptr[AO1
+ + (unroll_m * i + 2 * 16 - OFFSET)
+ * SIZE],
+ zmm2 | k3);
+ }
+ add(BO1, 4 * SIZE);
+ }
+ add(AO1, unroll_m * 4 * SIZE);
+
+ sub(LL, 1);
+ jg(pack2, T_NEAR);
+ align(16);
+
+ L(pack3);
+ mov(LL, K);
+ and_(LL, 3);
+ jle(pack10, T_NEAR);
+ align(16);
+
+ L(pack4);
+ if (!isTransA) {
+ vmovups(zmm0 | k1, ptr[BO1 + (0 * 16 - OFFSET) * SIZE]);
+ if (unroll_m > 16)
+ vmovups(zmm1 | k2, ptr[BO1 + (1 * 16 - OFFSET) * SIZE]);
+ if (unroll_m > 32)
+ vmovups(zmm2 | k3, ptr[BO1 + (2 * 16 - OFFSET) * SIZE]);
+ add(BO1, LDA);
+ } else {
+ kmovw(k4, k1);
+ vgatherqps(ymm5 | k4, ptr[BO1 + ZSTRIDE + (0 - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO1 + LDA * 8]);
+ kshiftrw(k4, k1, 8);
+ vgatherqps(ymm6 | k4, ptr[BO2 + ZSTRIDE + (0 - OFFSET) * SIZE]);
+ vshuff64x2(zmm0, zmm5, zmm6, 0x44);
+
+ if (unroll_m > 16) {
+ lea(BO2, ptr[BO2 + LDA * 8]);
+ kmovw(k4, k2);
+ vgatherqps(ymm5 | k4,
+ ptr[BO2 + ZSTRIDE + (0 - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDA * 8]);
+ kshiftrw(k4, k2, 8);
+ vgatherqps(ymm6 | k4,
+ ptr[BO2 + ZSTRIDE + (0 - OFFSET) * SIZE]);
+ vshuff64x2(zmm1, zmm5, zmm6, 0x44);
+ }
+
+ if (unroll_m > 32) {
+ lea(BO2, ptr[BO2 + LDA * 8]);
+ kmovw(k4, k3);
+ vgatherqps(ymm5 | k4,
+ ptr[BO2 + ZSTRIDE + (0 - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDA * 8]);
+ kshiftrw(k4, k3, 8);
+ vgatherqps(ymm6 | k4,
+ ptr[BO2 + ZSTRIDE + (0 - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDA * 8]);
+ vshuff64x2(zmm2, zmm5, zmm6, 0x44);
+ }
+ add(BO1, SIZE);
+ }
+
+ vmovups(ptr[AO1 + (unroll_m * 0 + 0 * 16 - OFFSET) * SIZE],
+ zmm0 | k1);
+ if (unroll_m > 16)
+ vmovups(ptr[AO1 + (unroll_m * 0 + 1 * 16 - OFFSET) * SIZE],
+ zmm1 | k2);
+ if (unroll_m > 32)
+ vmovups(ptr[AO1 + (unroll_m * 0 + 2 * 16 - OFFSET) * SIZE],
+ zmm2 | k3);
+
+ add(AO1, unroll_m * SIZE);
+ sub(LL, 1);
+ jg(pack4, T_NEAR);
+ align(16);
+
+ L(pack10);
+ };
+
+ // Function to update C, covering masking and other considerations
+ auto update = [&](Zmm reg, bool useCO1, int offset, int mask,
+ bool useScale = false) {
+ vmulps(reg, reg, VALPHA);
+ if (!isBeta0) {
+ if (!useScale) {
+ switch (mask) {
+ case 0:
+ if (useCO1)
+ vmovups(zmm0, ptr[CO1 + offset * SIZE]);
+ else
+ vmovups(zmm0, ptr[CO2 + offset * SIZE]);
+ break;
+ case 1:
+ if (useCO1)
+ vmovups(zmm0 | k1 | T_z, ptr[CO1 + offset * SIZE]);
+ else
+ vmovups(zmm0 | k1 | T_z, ptr[CO2 + offset * SIZE]);
+ break;
+ case 2:
+ if (useCO1)
+ vmovups(zmm0 | k2 | T_z, ptr[CO1 + offset * SIZE]);
+ else
+ vmovups(zmm0 | k2 | T_z, ptr[CO2 + offset * SIZE]);
+ break;
+ case 3:
+ if (useCO1)
+ vmovups(zmm0 | k3 | T_z, ptr[CO1 + offset * SIZE]);
+ else
+ vmovups(zmm0 | k3 | T_z, ptr[CO2 + offset * SIZE]);
+ break;
+ }
+ } else {
+ switch (mask) {
+ case 0:
+ if (useCO1)
+ vmovups(zmm0, ptr[CO1 + LDC + offset * SIZE]);
+ else
+ vmovups(zmm0, ptr[CO2 + LDC + offset * SIZE]);
+ break;
+ case 1:
+ if (useCO1)
+ vmovups(zmm0 | k1 | T_z,
+ ptr[CO1 + LDC + offset * SIZE]);
+ else
+ vmovups(zmm0 | k1 | T_z,
+ ptr[CO2 + LDC + offset * SIZE]);
+ break;
+ case 2:
+ if (useCO1)
+ vmovups(zmm0 | k2 | T_z,
+ ptr[CO1 + LDC + offset * SIZE]);
+ else
+ vmovups(zmm0 | k2 | T_z,
+ ptr[CO2 + LDC + offset * SIZE]);
+ break;
+ case 3:
+ if (useCO1)
+ vmovups(zmm0 | k3 | T_z,
+ ptr[CO1 + LDC + offset * SIZE]);
+ else
+ vmovups(zmm0 | k3 | T_z,
+ ptr[CO2 + LDC + offset * SIZE]);
+ break;
+ }
+ }
+ if (!isBetaN) {
+ vaddps(zmm0, reg, zmm0);
+ } else {
+ vfmadd132ps(zmm0, reg, VBETA);
+ }
+ if (!useScale) {
+ switch (mask) {
+ case 0:
+ if (useCO1)
+ vmovups(ptr[CO1 + offset * SIZE], zmm0);
+ else
+ vmovups(ptr[CO2 + offset * SIZE], zmm0);
+ break;
+ case 1:
+ if (useCO1)
+ vmovups(ptr[CO1 + offset * SIZE], zmm0 | k1);
+ else
+ vmovups(ptr[CO2 + offset * SIZE], zmm0 | k1);
+ break;
+ case 2:
+ if (useCO1)
+ vmovups(ptr[CO1 + offset * SIZE], zmm0 | k2);
+ else
+ vmovups(ptr[CO2 + offset * SIZE], zmm0 | k2);
+ break;
+ case 3:
+ if (useCO1)
+ vmovups(ptr[CO1 + offset * SIZE], zmm0 | k3);
+ else
+ vmovups(ptr[CO2 + offset * SIZE], zmm0 | k3);
+ break;
+ }
+ } else {
+ switch (mask) {
+ case 0:
+ if (useCO1)
+ vmovups(ptr[CO1 + LDC + offset * SIZE], zmm0);
+ else
+ vmovups(ptr[CO2 + LDC + offset * SIZE], zmm0);
+ break;
+ case 1:
+ if (useCO1)
+ vmovups(ptr[CO1 + LDC + offset * SIZE], zmm0 | k1);
+ else
+ vmovups(ptr[CO2 + LDC + offset * SIZE], zmm0 | k1);
+ break;
+ case 2:
+ if (useCO1)
+ vmovups(ptr[CO1 + LDC + offset * SIZE], zmm0 | k2);
+ else
+ vmovups(ptr[CO2 + LDC + offset * SIZE], zmm0 | k2);
+ break;
+ case 3:
+ if (useCO1)
+ vmovups(ptr[CO1 + LDC + offset * SIZE], zmm0 | k3);
+ else
+ vmovups(ptr[CO2 + LDC + offset * SIZE], zmm0 | k3);
+ break;
+ }
+ }
+ } else {
+ if (!useScale) {
+ switch (mask) {
+ case 0:
+ if (useCO1)
+ vmovups(ptr[CO1 + offset * SIZE], reg);
+ else
+ vmovups(ptr[CO2 + offset * SIZE], reg);
+ break;
+ case 1:
+ if (useCO1)
+ vmovups(ptr[CO1 + offset * SIZE], reg | k1);
+ else
+ vmovups(ptr[CO2 + offset * SIZE], reg | k1);
+ break;
+ case 2:
+ if (useCO1)
+ vmovups(ptr[CO1 + offset * SIZE], reg | k2);
+ else
+ vmovups(ptr[CO2 + offset * SIZE], reg | k2);
+ break;
+ case 3:
+ if (useCO1)
+ vmovups(ptr[CO1 + offset * SIZE], reg | k3);
+ else
+ vmovups(ptr[CO2 + offset * SIZE], reg | k3);
+ break;
+ }
+ } else {
+ switch (mask) {
+ case 0:
+ if (useCO1)
+ vmovups(ptr[CO1 + LDC + offset * SIZE], reg);
+ else
+ vmovups(ptr[CO2 + LDC + offset * SIZE], reg);
+ break;
+ case 1:
+ if (useCO1)
+ vmovups(ptr[CO1 + LDC + offset * SIZE], reg | k1);
+ else
+ vmovups(ptr[CO2 + LDC + offset * SIZE], reg | k1);
+ break;
+ case 2:
+ if (useCO1)
+ vmovups(ptr[CO1 + LDC + offset * SIZE], reg | k2);
+ else
+ vmovups(ptr[CO2 + LDC + offset * SIZE], reg | k2);
+ break;
+ case 3:
+ if (useCO1)
+ vmovups(ptr[CO1 + LDC + offset * SIZE], reg | k3);
+ else
+ vmovups(ptr[CO2 + LDC + offset * SIZE], reg | k3);
+ break;
+ }
+ }
+ }
+ vpxorq(reg, reg, reg);
+ };
+
+ // Loop with unroll_n - 2 FMAs; called by innerkernel
+ auto fmaloop = [&](int unroll_m, int unroll_n, int iteration) {
+ for (int i = 2; i < unroll_n; i++) {
+ if (ver == ver_avx512_core) {
+ if (!isTransB) {
+ switch (i) {
+ case 2:
+ vbroadcastss(
+ zmm3,
+ ptr[BO1 + LDB * 2
+ + (iteration - OFFSET) * SIZE]);
+ break;
+ case 3:
+ vbroadcastss(
+ zmm3,
+ ptr[BO1 + LDB3
+ + (iteration - OFFSET) * SIZE]);
+ break;
+ case 4:
+ vbroadcastss(zmm3,
+ ptr[BO2 + (iteration - OFFSET) * SIZE]);
+ break;
+ case 5:
+ vbroadcastss(
+ zmm3,
+ ptr[BO2 + LDB * 1
+ + (iteration - OFFSET) * SIZE]);
+ break;
+ case 6:
+ vbroadcastss(
+ zmm3,
+ ptr[BO2 + LDB * 2
+ + (iteration - OFFSET) * SIZE]);
+ break;
+ case 7:
+ vbroadcastss(
+ zmm3,
+ ptr[BO2 + LDB3
+ + (iteration - OFFSET) * SIZE]);
+ break;
+ }
+ } else {
+ vbroadcastss(zmm3, ptr[BO1 + (i - OFFSET) * SIZE]);
+ }
+ vfmadd231ps(regs[i], zmm3, zmm0);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[i + 8], zmm3, zmm1);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[i + 16], zmm3, zmm2);
+ } else {
+ if (!isTransB) {
+ switch (i) {
+ case 2:
+ vfmadd231ps(regs[i], zmm0,
+ zword_b[BO1 + LDB * 2
+ + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[i + 8], zmm1,
+ zword_b[BO1 + LDB * 2
+ + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[i + 16], zmm2,
+ zword_b[BO1 + LDB * 2
+ + (iteration - OFFSET) * SIZE]);
+ break;
+ case 3:
+ vfmadd231ps(regs[i], zmm0,
+ zword_b[BO1 + LDB3
+ + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[i + 8], zmm1,
+ zword_b[BO1 + LDB3
+ + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[i + 16], zmm2,
+ zword_b[BO1 + LDB3
+ + (iteration - OFFSET) * SIZE]);
+ break;
+ case 4:
+ vfmadd231ps(regs[i], zmm0,
+ zword_b[BO2 + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[i + 8], zmm1,
+ zword_b[BO2 + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[i + 16], zmm2,
+ zword_b[BO2 + (iteration - OFFSET) * SIZE]);
+ break;
+ case 5:
+ vfmadd231ps(regs[i], zmm0,
+ zword_b[BO2 + LDB * 1
+ + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[i + 8], zmm1,
+ zword_b[BO2 + LDB * 1
+ + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[i + 16], zmm2,
+ zword_b[BO2 + LDB * 1
+ + (iteration - OFFSET) * SIZE]);
+ break;
+ case 6:
+ vfmadd231ps(regs[i], zmm0,
+ zword_b[BO2 + LDB * 2
+ + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[i + 8], zmm1,
+ zword_b[BO2 + LDB * 2
+ + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[i + 16], zmm2,
+ zword_b[BO2 + LDB * 2
+ + (iteration - OFFSET) * SIZE]);
+ break;
+ case 7:
+ vfmadd231ps(regs[i], zmm0,
+ zword_b[BO2 + LDB3
+ + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[i + 8], zmm1,
+ zword_b[BO2 + LDB3
+ + (iteration - OFFSET) * SIZE]);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[i + 16], zmm2,
+ zword_b[BO2 + LDB3
+ + (iteration - OFFSET) * SIZE]);
+ break;
+ }
+ } else {
+ vfmadd231ps(
+ regs[i], zmm0, zword_b[BO1 + (i - OFFSET) * SIZE]);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[i + 8], zmm1,
+ zword_b[BO1 + (i - OFFSET) * SIZE]);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[i + 16], zmm2,
+ zword_b[BO1 + (i - OFFSET) * SIZE]);
+ }
+ }
+ }
+ };
+
+ // Innerkernel; called by kernel
+ auto innerkernel = [&](int unroll_m, int unroll_n, bool isDirect,
+ bool isCopy, bool doCPrefetch, bool isUnmasked = true) {
+ for (int i = 0; i < 8; i++) {
+ if (!isDirect) {
+ prefetcht0(ptr[AO1
+ + (PREFETCHSIZEA + i * unroll_m + 0 * 16 - OFFSET)
+ * SIZE]);
+ if (unroll_m >= 32)
+ prefetcht0(ptr[AO1
+ + (PREFETCHSIZEA + i * unroll_m + 1 * 16 - OFFSET)
+ * SIZE]);
+ if (unroll_m >= 48)
+ prefetcht0(ptr[AO1
+ + (PREFETCHSIZEA + i * unroll_m + 2 * 16 - OFFSET)
+ * SIZE]);
+ } else {
+ prefetcht0(ptr[AO1 + LDA4 + (16 * 0 * SIZE)]);
+ if (unroll_m >= 32)
+ prefetcht0(ptr[AO1 + LDA4 + (16 * 1 * SIZE)]);
+ if (unroll_m >= 48)
+ prefetcht0(ptr[AO1 + LDA4 + (16 * 2 * SIZE)]);
+ }
+
+ if (!isDirect) {
+ if (i != 0) {
+ if (isUnmasked || unroll_m > 16) {
+ vmovups(zmm0,
+ ptr[AO1
+ + (unroll_m * i + 0 * 16 - OFFSET)
+ * SIZE]);
+ } else {
+ vmovups(zmm0 | k1 | T_z,
+ ptr[AO1
+ + (unroll_m * i + 0 * 16 - OFFSET)
+ * SIZE]);
+ }
+ if (unroll_m >= 32) {
+ if (isUnmasked || unroll_m > 32) {
+ vmovups(zmm1, ptr[AO1
+ + (unroll_m * i + 1 * 16
+ - OFFSET)
+ * SIZE]);
+ } else {
+ vmovups(zmm1 | k2 | T_z,
+ ptr[AO1
+ + (unroll_m * i + 1 * 16
+ - OFFSET)
+ * SIZE]);
+ }
+ }
+ if (unroll_m >= 48) {
+ if (isUnmasked) {
+ vmovups(zmm2, ptr[AO1
+ + (unroll_m * i + 2 * 16
+ - OFFSET)
+ * SIZE]);
+ } else {
+ vmovups(zmm2 | k3 | T_z,
+ ptr[AO1
+ + (unroll_m * i + 2 * 16
+ - OFFSET)
+ * SIZE]);
+ }
+ }
+ }
+ } else {
+ if (isUnmasked || unroll_m > 16) {
+ vmovups(zmm0, ptr[AO1 + (0 * 16 - OFFSET) * SIZE]);
+ } else {
+ vmovups(zmm0 | k1 | T_z,
+ ptr[AO1 + (0 * 16 - OFFSET) * SIZE]);
+ }
+ if (unroll_m >= 32) {
+ if (isUnmasked || unroll_m > 32) {
+ vmovups(zmm1, ptr[AO1 + (1 * 16 - OFFSET) * SIZE]);
+ } else {
+ vmovups(zmm1 | k2 | T_z,
+ ptr[AO1 + (1 * 16 - OFFSET) * SIZE]);
+ }
+ }
+ if (unroll_m >= 48) {
+ if (isUnmasked) {
+ vmovups(zmm2, ptr[AO1 + (2 * 16 - OFFSET) * SIZE]);
+ } else {
+ vmovups(zmm2 | k3 | T_z,
+ ptr[AO1 + (2 * 16 - OFFSET) * SIZE]);
+ }
+ }
+ add(AO1, LDA);
+ }
+
+ if (ver == ver_avx512_core) {
+ if (!isTransB) {
+ vbroadcastss(zmm3, ptr[BO1 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(zmm3, ptr[BO1 + (0 - OFFSET) * SIZE]);
+ }
+ vfmadd231ps(regs[0], zmm3, zmm0);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[0 + 8], zmm3, zmm1);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[0 + 16], zmm3, zmm2);
+ } else {
+ if (!isTransB) {
+ vfmadd231ps(regs[0], zmm0,
+ zword_b[BO1 + (i - OFFSET) * SIZE]);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[0 + 8], zmm1,
+ zword_b[BO1 + (i - OFFSET) * SIZE]);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[0 + 16], zmm2,
+ zword_b[BO1 + (i - OFFSET) * SIZE]);
+ } else {
+ vfmadd231ps(regs[0], zmm0,
+ zword_b[BO1 + (0 - OFFSET) * SIZE]);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[0 + 8], zmm1,
+ zword_b[BO1 + (0 - OFFSET) * SIZE]);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[0 + 16], zmm2,
+ zword_b[BO1 + (0 - OFFSET) * SIZE]);
+ }
+ }
+
+ if (unroll_n >= i + 1) {
+ if (!isTransB) {
+ switch (i) {
+ case 0:
+ prefetcht0(
+ ptr[BO1 + (PREFETCHSIZEB - OFFSET) * SIZE]);
+ break;
+ case 1:
+ prefetcht0(ptr[BO1 + LDB
+ + (PREFETCHSIZEB - OFFSET) * SIZE]);
+ break;
+ case 2:
+ prefetcht0(ptr[BO1 + LDB * 2
+ + (PREFETCHSIZEB - OFFSET) * SIZE]);
+ break;
+ case 3:
+ prefetcht0(ptr[BO1 + LDB3
+ + (PREFETCHSIZEB - OFFSET) * SIZE]);
+ break;
+ case 4:
+ prefetcht0(
+ ptr[BO2 + (PREFETCHSIZEB - OFFSET) * SIZE]);
+ break;
+ case 5:
+ prefetcht0(ptr[BO2 + LDB
+ + (PREFETCHSIZEB - OFFSET) * SIZE]);
+ break;
+ case 6:
+ prefetcht0(ptr[BO2 + LDB * 2
+ + (PREFETCHSIZEB - OFFSET) * SIZE]);
+ break;
+ case 7:
+ prefetcht0(ptr[BO2 + LDB3
+ + (PREFETCHSIZEB - OFFSET) * SIZE]);
+ break;
+ }
+ }
+ }
+
+ if (unroll_n >= 2) {
+ if (ver == ver_avx512_core) {
+ if (!isTransB) {
+ vbroadcastss(zmm3,
+ ptr[BO1 + LDB * 1 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(zmm3, ptr[BO1 + (1 - OFFSET) * SIZE]);
+ }
+ vfmadd231ps(regs[1], zmm3, zmm0);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[1 + 8], zmm3, zmm1);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[1 + 16], zmm3, zmm2);
+ } else {
+ if (!isTransB) {
+ vfmadd231ps(regs[1], zmm0,
+ zword_b[BO1 + LDB * 1 + (i - OFFSET) * SIZE]);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[1 + 8], zmm1,
+ zword_b[BO1 + LDB * 1
+ + (i - OFFSET) * SIZE]);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[1 + 16], zmm2,
+ zword_b[BO1 + LDB * 1
+ + (i - OFFSET) * SIZE]);
+ } else {
+ vfmadd231ps(regs[1], zmm0,
+ zword_b[BO1 + (1 - OFFSET) * SIZE]);
+ if (unroll_m >= 32)
+ vfmadd231ps(regs[1 + 8], zmm1,
+ zword_b[BO1 + (1 - OFFSET) * SIZE]);
+ if (unroll_m >= 48)
+ vfmadd231ps(regs[1 + 16], zmm2,
+ zword_b[BO1 + (1 - OFFSET) * SIZE]);
+ }
+ }
+ }
+
+ if (isCopy) {
+ if (isUnmasked || unroll_m > 16) {
+ vmovups(ptr[LDA4
+ + (unroll_m * i + 0 * 16 - OFFSET)
+ * SIZE],
+ zmm0);
+ } else {
+ vmovups(ptr[LDA4
+ + (unroll_m * i + 0 * 16 - OFFSET)
+ * SIZE],
+ zmm0 | k1);
+ }
+ if (unroll_m >= 32) {
+ if (isUnmasked || unroll_m > 32) {
+ vmovups(ptr[LDA4
+ + (unroll_m * i + 1 * 16 - OFFSET)
+ * SIZE],
+ zmm1);
+ } else {
+ vmovups(ptr[LDA4
+ + (unroll_m * i + 1 * 16 - OFFSET)
+ * SIZE],
+ zmm1 | k2);
+ }
+ }
+ if (unroll_m >= 48) {
+ if (isUnmasked) {
+ vmovups(ptr[LDA4
+ + (unroll_m * i + 2 * 16 - OFFSET)
+ * SIZE],
+ zmm2);
+ } else {
+ vmovups(ptr[LDA4
+ + (unroll_m * i + 2 * 16 - OFFSET)
+ * SIZE],
+ zmm2 | k3);
+ }
+ }
+ if (i == 7)
+ sub(LDA4, -unroll_m * 8 * SIZE);
+ }
+ fmaloop(unroll_m, unroll_n, i);
+
+ if (i == 1) {
+ if (doCPrefetch) {
+ if (ver == ver_avx512_core)
+ prefetchw(ptr[CO2 + 0 * 16 * SIZE]);
+ else
+ prefetcht0(ptr[CO2 + 0 * 16 * SIZE]);
+ }
+ }
+ if (i == 3) {
+ if (doCPrefetch && unroll_m >= 32) {
+ if (ver == ver_avx512_core)
+ prefetchw(ptr[CO2 + 1 * 16 * SIZE]);
+ else
+ prefetcht0(ptr[CO2 + 1 * 16 * SIZE]);
+ }
+ if (!isTransA) {
+ if (ver == ver_avx512_core)
+ prefetcht0(ptr[AA + 16 * 0 * SIZE]);
+ else
+ prefetcht2(ptr[AA + 16 * 0 * SIZE]);
+ }
+ }
+ if (i == 5) {
+ if (doCPrefetch) {
+ if (unroll_m >= 48) {
+ if (ver == ver_avx512_core)
+ prefetchw(ptr[CO2 + 2 * 16 * SIZE]);
+ else
+ prefetcht0(ptr[CO2 + 2 * 16 * SIZE]);
+ }
+ add(CO2, LDC);
+ }
+ if (!isTransA) {
+ if (unroll_m >= 32) {
+ if (ver == ver_avx512_core)
+ prefetcht0(ptr[AA + 16 * 1 * SIZE]);
+ else
+ prefetcht2(ptr[AA + 16 * 1 * SIZE]);
+ }
+ }
+ }
+
+ if (isTransB) {
+ prefetcht0(ptr[BO1 + BO2]);
+ add(BO1, LDB);
+ }
+ } // end of for loop
+
+ if (!isTransB) {
+ sub(BO1, -8 * SIZE);
+ if (unroll_n >= 4)
+ sub(BO2, -8 * SIZE);
+ }
+ if (!isTransA) {
+ if (unroll_m >= 48) {
+ if (ver == ver_avx512_core)
+ prefetcht0(ptr[AA + 16 * 2 * SIZE]);
+ else
+ prefetcht2(ptr[AA + 16 * 2 * SIZE]);
+ }
+ lea(AA, ptr[AA + LDA]);
+ }
+
+ if (!isDirect) {
+ if (isUnmasked || unroll_m > 16) {
+ vmovups(zmm0,
+ ptr[AO1 + (unroll_m * 8 + 0 * 16 - OFFSET) * SIZE]);
+ } else {
+ vmovups(zmm0 | k1 | T_z,
+ ptr[AO1 + (unroll_m * 8 + 0 * 16 - OFFSET) * SIZE]);
+ }
+ if (unroll_m >= 32) {
+ if (isUnmasked || unroll_m > 32) {
+ vmovups(zmm1, ptr[AO1
+ + (unroll_m * 8 + 1 * 16 - OFFSET)
+ * SIZE]);
+ } else {
+ vmovups(zmm1 | k2 | T_z,
+ ptr[AO1
+ + (unroll_m * 8 + 1 * 16 - OFFSET)
+ * SIZE]);
+ }
+ }
+ if (unroll_m >= 48) {
+ if (isUnmasked) {
+ vmovups(zmm2, ptr[AO1
+ + (unroll_m * 8 + 2 * 16 - OFFSET)
+ * SIZE]);
+ } else {
+ vmovups(zmm2 | k3 | T_z,
+ ptr[AO1
+ + (unroll_m * 8 + 2 * 16 - OFFSET)
+ * SIZE]);
+ }
+ }
+ sub(AO1, -unroll_m * 8 * SIZE);
+ }
+
+ sub(LL, 1);
+ };
+
+ // Main kernel; does prefetching and calls innerkernel
+ // After calculating results in registers, writes back to C matrix by
+ // calling update
+ auto kernel = [&](int unroll_m, int unroll_n, bool isDirect,
+ bool isCopy, bool isUnmasked = true) {
+ if (!isDirect) {
+ lea(AO1, ptr[rsp + 128 + OFFSET * SIZE]);
+ } else {
+ mov(AO1, A);
+ }
+
+ if (isCopy) {
+ lea(LDA4, ptr[rsp + 128 + OFFSET * SIZE]);
+ } else {
+ auto step = ver == ver_avx512_core ? 2 : 4;
+ lea(LDA4, ptr[LDA * step + (16 - 1 - OFFSET) * SIZE]);
+ }
+
+ if (isTransB) {
+ lea(BO2, ptr[LDB * 4 + (16 / 2 - 1 - OFFSET) * SIZE]);
+ }
+
+ if (!isDirect) {
+ if (isUnmasked || unroll_m > 16) {
+ vmovups(zmm0,
+ ptr[AO1 + (unroll_m * 0 + 0 * 16 - OFFSET) * SIZE]);
+ } else {
+ vmovups(zmm0 | k1 | T_z,
+ ptr[AO1 + (unroll_m * 0 + 0 * 16 - OFFSET) * SIZE]);
+ }
+ if (unroll_m >= 32) {
+ if (isUnmasked || unroll_m > 32) {
+ vmovups(zmm1, ptr[AO1
+ + (unroll_m * 0 + 1 * 16 - OFFSET)
+ * SIZE]);
+ } else {
+ vmovups(zmm1 | k2 | T_z,
+ ptr[AO1
+ + (unroll_m * 0 + 1 * 16 - OFFSET)
+ * SIZE]);
+ }
+ }
+ if (unroll_m >= 48) {
+ if (isUnmasked) {
+ vmovups(zmm2, ptr[AO1
+ + (unroll_m * 0 + 2 * 16 - OFFSET)
+ * SIZE]);
+ } else {
+ vmovups(zmm2 | k3 | T_z,
+ ptr[AO1
+ + (unroll_m * 0 + 2 * 16 - OFFSET)
+ * SIZE]);
+ }
+ }
+ }
+
+ Label kernel12, kernel13, kernel14, kernel15, kernel16, kernel18;
+
+ mov(LL, K);
+ sar(LL, 3);
+ sub(LL, SECOND_FETCH);
+ jle(kernel13, T_NEAR);
+ align(16);
+
+ L(kernel12);
+ innerkernel(
+ unroll_m, unroll_n, isDirect, isCopy, false, isUnmasked);
+ jg(kernel12, T_NEAR);
+ align(16);
+
+ L(kernel13);
+ lea(CO2, ptr[CO1 + (16 - 1) * SIZE]);
+ add(LL, unroll_n);
+ jle(kernel15, T_NEAR);
+ align(16);
+
+ L(kernel14);
+ innerkernel(unroll_m, unroll_n, isDirect, isCopy, true, isUnmasked);
+ jg(kernel14, T_NEAR);
+ align(16);
+
+ L(kernel15);
+ mov(LL, K);
+ and_(LL, 7);
+ jle(kernel18, T_NEAR);
+ align(16);
+
+ L(kernel16);
+ if (isDirect) {
+ if (isUnmasked || unroll_m > 16) {
+ vmovups(zmm0, ptr[AO1 + (0 * 16 - OFFSET) * SIZE]);
+ } else {
+ vmovups(zmm0 | k1 | T_z,
+ ptr[AO1 + (0 * 16 - OFFSET) * SIZE]);
+ }
+ if (unroll_m >= 32) {
+ if (isUnmasked || unroll_m > 32) {
+ vmovups(zmm1, ptr[AO1 + (1 * 16 - OFFSET) * SIZE]);
+ } else {
+ vmovups(zmm1 | k2 | T_z,
+ ptr[AO1 + (1 * 16 - OFFSET) * SIZE]);
+ }
+ }
+ if (unroll_m >= 48) {
+ if (isUnmasked) {
+ vmovups(zmm2, ptr[AO1 + (2 * 16 - OFFSET) * SIZE]);
+ } else {
+ vmovups(zmm2 | k3 | T_z,
+ ptr[AO1 + (2 * 16 - OFFSET) * SIZE]);
+ }
+ }
+ add(AO1, LDA);
+ }
+
+ for (int i = 0; i < unroll_n; i++) {
+ if (!isTransB) {
+ switch (i) {
+ case 0:
+ vbroadcastss(zmm3, ptr[BO1 + (0 - OFFSET) * SIZE]);
+ break;
+ case 1:
+ vbroadcastss(
+ zmm3, ptr[BO1 + LDB * 1 + (0 - OFFSET) * SIZE]);
+ break;
+ case 2:
+ vbroadcastss(
+ zmm3, ptr[BO1 + LDB * 2 + (0 - OFFSET) * SIZE]);
+ break;
+ case 3:
+ vbroadcastss(
+ zmm3, ptr[BO1 + LDB3 + (0 - OFFSET) * SIZE]);
+ break;
+ case 4:
+ vbroadcastss(zmm3, ptr[BO2 + (0 - OFFSET) * SIZE]);
+ break;
+ case 5:
+ vbroadcastss(
+ zmm3, ptr[BO2 + LDB * 1 + (0 - OFFSET) * SIZE]);
+ break;
+ case 6:
+ vbroadcastss(
+ zmm3, ptr[BO2 + LDB * 2 + (0 - OFFSET) * SIZE]);
+ break;
+ case 7:
+ vbroadcastss(
+ zmm3, ptr[BO2 + LDB3 + (0 - OFFSET) * SIZE]);
+ break;
+ }
+ } else {
+ vbroadcastss(zmm3, ptr[BO1 + (i - OFFSET) * SIZE]);
+ }
+ vfmadd231ps(regs[i], zmm3, zmm0);
+ if (unroll_m >= 32) {
+ vfmadd231ps(regs[i + 8], zmm3, zmm1);
+ }
+ if (unroll_m >= 48) {
+ vfmadd231ps(regs[i + 16], zmm3, zmm2);
+ }
+ }
+
+ if (isCopy) {
+ if (isUnmasked || unroll_m > 16) {
+ vmovups(ptr[LDA4 + (unroll_m * 0 + 0 * 16 - OFFSET) * SIZE],
+ zmm0);
+ } else {
+ vmovups(ptr[LDA4 + (unroll_m * 0 + 0 * 16 - OFFSET) * SIZE],
+ zmm0 | k1);
+ }
+ if (unroll_m >= 32) {
+ if (isUnmasked || unroll_m > 32) {
+ vmovups(ptr[LDA4
+ + (unroll_m * 0 + 1 * 16 - OFFSET)
+ * SIZE],
+ zmm1);
+ } else {
+ vmovups(ptr[LDA4
+ + (unroll_m * 0 + 1 * 16 - OFFSET)
+ * SIZE],
+ zmm1 | k2);
+ }
+ }
+ if (unroll_m >= 48) {
+ if (isUnmasked) {
+ vmovups(ptr[LDA4
+ + (unroll_m * 0 + 2 * 16 - OFFSET)
+ * SIZE],
+ zmm2);
+ } else {
+ vmovups(ptr[LDA4
+ + (unroll_m * 0 + 2 * 16 - OFFSET)
+ * SIZE],
+ zmm2 | k3);
+ }
+ }
+ sub(LDA4, -unroll_m * SIZE);
+ }
+
+ if (!isDirect) {
+ if (isUnmasked || unroll_m > 16) {
+ vmovups(zmm0,
+ ptr[AO1 + (unroll_m * 1 + 0 * 16 - OFFSET) * SIZE]);
+ } else {
+ vmovups(zmm0 | k1 | T_z,
+ ptr[AO1 + (unroll_m * 1 + 0 * 16 - OFFSET) * SIZE]);
+ }
+ if (unroll_m >= 32) {
+ if (isUnmasked || unroll_m > 32) {
+ vmovups(zmm1, ptr[AO1
+ + (unroll_m * 1 + 1 * 16 - OFFSET)
+ * SIZE]);
+ } else {
+ vmovups(zmm1 | k2 | T_z,
+ ptr[AO1
+ + (unroll_m * 1 + 1 * 16 - OFFSET)
+ * SIZE]);
+ }
+ }
+ if (unroll_m >= 48) {
+ if (isUnmasked) {
+ vmovups(zmm2, ptr[AO1
+ + (unroll_m * 1 + 2 * 16 - OFFSET)
+ * SIZE]);
+ } else {
+ vmovups(zmm2 | k3 | T_z,
+ ptr[AO1
+ + (unroll_m * 1 + 2 * 16 - OFFSET)
+ * SIZE]);
+ }
+ }
+ sub(AO1, -unroll_m * SIZE);
+ }
+
+ if (!isTransB) {
+ sub(BO1, -SIZE);
+ if (unroll_n >= 4) {
+ sub(BO2, -SIZE);
+ }
+ } else {
+ add(BO1, LDB);
+ }
+
+ sub(LL, 1);
+ jg(kernel16, T_NEAR);
+ align(16);
+
+ L(kernel18);
+ vbroadcastss(VALPHA, ALPHA);
+
+ if (isBetaN) {
+ vbroadcastss(VBETA, BETA);
+ }
+
+ // Write back the results; all beta cases need to be handled
+ if (hasBias) {
+ mov(BIAS1, BIAS);
+ if (isUnmasked || unroll_m > 16)
+ vmovups(VBIAS1, ptr[BIAS1 + 0 * SIZE]);
+ else
+ vmovups(VBIAS1 | k1 | T_z, ptr[BIAS1 + 0 * SIZE]);
+ if (unroll_m >= 32) {
+ if (isUnmasked || unroll_m > 32)
+ vmovups(VBIAS2, ptr[BIAS1 + 16 * SIZE]);
+ else
+ vmovups(VBIAS2 | k2 | T_z, ptr[BIAS1 + 16 * SIZE]);
+ }
+ if (unroll_m >= 48) {
+ if (isUnmasked)
+ vmovups(VBIAS3, ptr[BIAS1 + 32 * SIZE]);
+ else
+ vmovups(VBIAS3 | k3 | T_z, ptr[BIAS1 + 32 * SIZE]);
+ }
+ }
+
+ for (int i = 0; i < unroll_n; i++) {
+ bool useScale = i % 2 != 0;
+ bool useCO1 = i < 2;
+ if (i == 2)
+ lea(CO2, ptr[CO1 + LDC * 2]);
+ if (i == 4 || i == 6)
+ lea(CO2, ptr[CO2 + LDC * 2]);
+ if (hasBias)
+ vaddps(regs[i], VBIAS1, regs[i]);
+ if (isUnmasked || unroll_m > 16) {
+ update(regs[i], useCO1, 0, 0, useScale);
+ } else {
+ update(regs[i], useCO1, 0, 1, useScale);
+ }
+ if (unroll_m >= 32) {
+ if (hasBias)
+ vaddps(regs[i + 8], VBIAS2, regs[i + 8]);
+ if (isUnmasked || unroll_m > 32) {
+ update(regs[i + 8], useCO1, 16, 0, useScale);
+ } else {
+ update(regs[i + 8], useCO1, 16, 2, useScale);
+ }
+ }
+ if (unroll_m >= 48) {
+ if (hasBias)
+ vaddps(regs[i + 16], VBIAS3, regs[i + 16]);
+ if (isUnmasked) {
+ update(regs[i + 16], useCO1, 32, 0, useScale);
+ } else {
+ update(regs[i + 16], useCO1, 32, 3, useScale);
+ }
+ }
+ }
+
+ switch (unroll_n) {
+ case 1: add(CO1, LDC); break;
+ case 2: lea(CO1, ptr[CO1 + LDC * 2]); break;
+ case 3: lea(CO1, ptr[CO2 + LDC * 1]); break;
+ case 4: lea(CO1, ptr[CO2 + LDC * 2]); break;
+ case 5: lea(CO1, ptr[CO2 + LDC * 1]); break;
+ case 6: lea(CO1, ptr[CO2 + LDC * 2]); break;
+ case 7: lea(CO1, ptr[CO2 + LDC * 1]); break;
+ case 8: lea(CO1, ptr[CO2 + LDC * 2]); break;
+ }
+
+ // Compute next address of B
+ if (!isTransB) {
+ lea(rax, ptr[K * SIZE]);
+ switch (unroll_n) {
+ case 1:
+ add(BO1, LDB);
+ add(BO2, LDB);
+ break;
+ case 2:
+ lea(BO1, ptr[BO1 + LDB * 2]);
+ lea(BO2, ptr[BO2 + LDB * 2]);
+ break;
+ case 3:
+ lea(BO1, ptr[BO1 + LDB3]);
+ lea(BO2, ptr[BO2 + LDB3]);
+ break;
+ case 4:
+ lea(BO1, ptr[BO1 + LDB * 4]);
+ lea(BO2, ptr[BO2 + LDB * 4]);
+ break;
+ case 5:
+ lea(BO1, ptr[BO1 + LDB * 4]);
+ add(BO1, LDB);
+ lea(BO2, ptr[BO2 + LDB * 4]);
+ add(BO2, LDB);
+ break;
+ case 6:
+ lea(BO1, ptr[BO1 + LDB3 * 2]);
+ lea(BO2, ptr[BO2 + LDB3 * 2]);
+ break;
+ case 7:
+ lea(BO1, ptr[BO1 + LDB * 8]);
+ sub(BO1, LDB);
+ lea(BO2, ptr[BO2 + LDB * 8]);
+ sub(BO2, LDB);
+ break;
+ case 8:
+ lea(BO1, ptr[BO1 + LDB * 8]);
+ lea(BO2, ptr[BO2 + LDB * 8]);
+ break;
+ }
+ sub(BO1, rax);
+ sub(BO2, rax);
+ } else {
+ mov(rax, LDB);
+ imul(rax, K);
+ sub(BO1, rax);
+ add(BO1, unroll_n * SIZE);
+ }
+ };
+
+ // High-level subroutine; does packing if needed, then splits C matrix.
+ // Operates on chunks of 48 rows, 8 columns at a time (handling tail
+ // cases appropriately by doing 32 or 16 rows, and/or with masking,
+ // and/or fewer columns).
+ auto subloop = [&](int unroll_m) {
+ Label l_subloop_20x[8], l_subloop_mask_20x[8];
+ Label l_subloop_30x[8], l_subloop_mask_30x[8];
+
+ Label subloop11, subloop11mask;
+ Label subloop30, subloop30mask;
+ Label subloop31, subloop31mask;
+ Label subloop96;
+ Label subloop98, subloop98mask;
+ Label subloop99;
+
+ // Create mask
+ mov(BO1, rcx);
+ mov(rcx, M);
+ sub(rcx, unroll_m - 16);
+ mov(CO1, 16);
+ cmp(rcx, 16);
+
+ cmovg(rcx, CO1);
+ mov(rax, 1);
+ sal(rax, cl);
+ sub(rax, 1);
+ mov(rcx, 0xffff);
+
+ if (unroll_m == 16) {
+ kmovw(k1, eax);
+ } else if (unroll_m == 32) {
+ kmovw(k1, ecx);
+ kmovw(k2, eax);
+ } else {
+ kmovw(k1, ecx);
+ kmovw(k2, ecx);
+ kmovw(k3, eax);
+ }
+ mov(rcx, BO1);
+
+ and_(rax, 0xffff);
+ cmp(rax, 0xffff);
+ jne(subloop96, T_NEAR);
+
+ if (isTransA) {
+ do_pack(unroll_m);
+ }
+
+ mov(CO1, C);
+ add(C, unroll_m * SIZE);
+
+ mov(BO1, B);
+ if (!isTransB) {
+ lea(BO2, ptr[B + LDB * 4]);
+ }
+
+ if (!isTransA) {
+ lea(AA, ptr[A + (unroll_m + 16 - 1 - OFFSET) * SIZE]);
+ cmp(M, UNROLL_M);
+ jg(subloop98, T_NEAR);
+
+ mov(AA, ORIG_A);
+ lea(AA, ptr[AA + (16 - 1 - OFFSET) * SIZE]);
+ L(subloop98);
+ }
+
+ mov(LL, N);
+ mov(I, LL);
+ if (!isTransA) {
+ // If N is too small, skip copy operation
+ cmp(LL, UNROLL_N * 3);
+ jle(subloop30, T_NEAR);
+
+ // If A is not aligned to cache line
+ cmp(FLAG, 0);
+ je(subloop30, T_NEAR);
+ } else {
+ cmp(LL, UNROLL_N);
+ jl(l_subloop_20x[1], T_NEAR);
+ }
+ align(16);
+
+ if (!isTransA) {
+ kernel(unroll_m, UNROLL_N, true, true);
+ } else {
+ kernel(unroll_m, UNROLL_N, false, false);
+ }
+
+ sub(I, UNROLL_N);
+ cmp(I, UNROLL_N);
+ jl(l_subloop_20x[1], T_NEAR);
+ align(16);
+
+ L(subloop11);
+ kernel(unroll_m, UNROLL_N, false, false);
+ sub(I, UNROLL_N);
+ cmp(I, UNROLL_N);
+ jge(subloop11, T_NEAR);
+ align(16);
+
+ for (int i = 1; i <= 7; i++) {
+ L(l_subloop_20x[i]);
+ cmp(I, i);
+ if (i < 7) {
+ jne(l_subloop_20x[i + 1], T_NEAR);
+ } else {
+ jne(subloop99, T_NEAR);
+ }
+ kernel(unroll_m, i, false, false);
+ jmp(subloop99, T_NEAR);
+ align(16);
+ }
+
+ if (!isTransA) {
+ L(subloop30);
+ cmp(I, UNROLL_N);
+ jl(l_subloop_30x[1], T_NEAR);
+ align(16);
+
+ L(subloop31);
+ kernel(unroll_m, UNROLL_N, true, false);
+ sub(I, UNROLL_N);
+ cmp(I, UNROLL_N);
+ jge(subloop31, T_NEAR);
+ align(16);
+
+ for (int i = 1; i <= 7; i++) {
+ L(l_subloop_30x[i]);
+ cmp(I, i);
+ if (i < 7) {
+ jne(l_subloop_30x[i + 1], T_NEAR);
+ } else {
+ jne(subloop99, T_NEAR);
+ }
+ kernel(unroll_m, i, true, false);
+ if (i < 7)
+ jmp(subloop99, T_NEAR);
+ align(16);
+ }
+ }
+ jmp(subloop99, T_NEAR);
+ align(16);
+
+ L(subloop96);
+ if (isTransA) {
+ do_pack(unroll_m);
+ }
+
+ mov(CO1, C);
+ add(C, unroll_m * SIZE);
+ mov(BO1, B);
+ if (!isTransB) {
+ lea(BO2, ptr[B + LDB * 4]);
+ }
+
+ if (!isTransA) {
+ lea(AA, ptr[A + (unroll_m + 16 - 1 - OFFSET) * SIZE]);
+ cmp(M, UNROLL_M);
+ jg(subloop98mask, T_NEAR);
+ mov(AA, ORIG_A);
+ lea(AA, ptr[AA + (16 - 1 - OFFSET) * SIZE]);
+ L(subloop98mask);
+ }
+
+ mov(LL, N);
+ mov(I, LL);
+ if (!isTransA) {
+ // If N is too small, skip copy operation
+ cmp(LL, UNROLL_N * 3);
+ jle(subloop30mask, T_NEAR);
+
+ // If A is not aligned to cache line
+ cmp(FLAG, 0);
+ je(subloop30mask, T_NEAR);
+ } else {
+ cmp(LL, UNROLL_N);
+ jl(l_subloop_mask_20x[1], T_NEAR);
+ }
+ align(16);
+
+ if (!isTransA) {
+ kernel(unroll_m, UNROLL_N, true, true, false);
+ } else {
+ kernel(unroll_m, UNROLL_N, false, false, false);
+ }
+
+ sub(I, UNROLL_N);
+ cmp(I, UNROLL_N);
+ jl(l_subloop_mask_20x[1], T_NEAR);
+ align(16);
+
+ L(subloop11mask);
+ kernel(unroll_m, UNROLL_N, false, false, false);
+ sub(I, UNROLL_N);
+ cmp(I, UNROLL_N);
+ jge(subloop11mask, T_NEAR);
+ align(16);
+
+ for (int i = 1; i <= 7; i++) {
+ L(l_subloop_mask_20x[i]);
+ cmp(I, i);
+ if (i < 7) {
+ jne(l_subloop_mask_20x[i + 1], T_NEAR);
+ } else {
+ jne(subloop99, T_NEAR);
+ }
+ kernel(unroll_m, i, false, false, false);
+ jmp(subloop99, T_NEAR);
+ align(16);
+ }
+
+ if (!isTransA) {
+ L(subloop30mask);
+ cmp(I, UNROLL_N);
+ jl(l_subloop_mask_30x[1], T_NEAR);
+ align(16);
+
+ L(subloop31mask);
+ kernel(unroll_m, UNROLL_N, true, false, false);
+ sub(I, UNROLL_N);
+ cmp(I, UNROLL_N);
+ jge(subloop31mask, T_NEAR);
+ align(16);
+
+ for (int i = 1; i <= 7; i++) {
+ L(l_subloop_mask_30x[i]);
+ cmp(I, i);
+ if (i < 7) {
+ jne(l_subloop_mask_30x[i + 1], T_NEAR);
+ } else {
+ jne(subloop99, T_NEAR);
+ }
+ kernel(unroll_m, i, true, false, false);
+ if (i < 7)
+ jmp(subloop99, T_NEAR);
+ align(16);
+ }
+ }
+
+ L(subloop99);
+ // Compute address for A
+ if (!isTransA) {
+ add(A, unroll_m * SIZE);
+ } else {
+ mov(rax, LDA);
+ imul(rax, rax, unroll_m);
+ add(A, rax);
+ }
+
+ // Compute next address of BIAS
+ if (hasBias) {
+ add(BIAS, unroll_m * SIZE);
+ }
+ };
+
+ preamble();
+
+ Label buffer_in_ws, buffer_allocated;
+
+ // Get the registers
+ mov(B, ARG_B);
+ mov(LDB, ARG_LDB);
+ mov(r15, ARG_BETA);
+ mov(r12, ARG_C);
+ if (hasBias)
+ mov(r10, ARG_BIAS);
+ mov(LDC, ARG_LDC);
+ mov(rbp, rsp);
+
+ vmovss(xmm0, ptr[ARG_ALPHA]);
+ vmovss(xmm1, ptr[r15]);
+
+#if _WIN32
+ mov(A, ARG_A);
+ mov(LDA, ARG_LDA);
+#endif
+
+ cmp(K, STACK_K_CAPACITY);
+ jg(buffer_in_ws, T_NEAR);
+
+ // Create buffer and align to 4kB page
+ lea(rax, ptr[K * SIZE]);
+ imul(rax, rax, 0x30);
+ add(rax, 256);
+ sub(rsp, rax);
+ and_(rsp, -PAGE_4K);
+ jmp(buffer_allocated, T_NEAR);
+
+ L(buffer_in_ws);
+ mov(rsp, ARG_WS);
+
+ L(buffer_allocated);
+
+ mov(ORIG_SP, rbp);
+ mov(M, ARG_M);
+ mov(N, ARG_N);
+ mov(C, r12);
+ if (hasBias)
+ mov(BIAS, r10);
+ vmovss(ALPHA, xmm0);
+ vmovss(BETA, xmm1);
+ sub(A, -OFFSET * SIZE);
+ sub(B, -OFFSET * SIZE);
+ mov(ORIG_A, A);
+ sal(LDA, BASE_SHIFT);
+ sal(LDB, BASE_SHIFT);
+ sal(LDC, BASE_SHIFT);
+ lea(LDB3, ptr[LDB + LDB * 2]);
+
+ if (isTransA) {
+ vpbroadcastq(zmm2, LDA);
+ vpxorq(ZSTRIDE, ZSTRIDE, ZSTRIDE);
+ mov(rax, -2);
+ kmovw(k4, eax);
+
+ for (int i = 0; i < 6; i++) {
+ vpaddq(ZSTRIDE | k4, ZSTRIDE, zmm2);
+ kshiftlw(k4, k4, 1);
+ }
+ vpaddq(ZSTRIDE | k4, ZSTRIDE, zmm2);
+ }
+
+ // Check A alignment and leading dimension; take copy-based path as
+ // needed
+ mov(rax, LDA);
+ or_(rax, A);
+ and_(rax, ver == ver_avx512_core ? 0x07 : 0x3f);
+ mov(FLAG, rax);
+
+ for (int i = 8; i < 16; i++) {
+ for (int j = 0; j < 3; j++) {
+ vpxorq(Zmm(i + 8 * j), Zmm(i + 8 * j), Zmm(i + 8 * j));
+ }
+ }
+
+ Label main0, main1, main2, main999;
+
+ cmp(M, 32);
+ jle(main0, T_NEAR);
+ align(16);
+
+ L(main1);
+ subloop(48);
+ sub(M, UNROLL_M);
+ cmp(M, 32);
+ jg(main1, T_NEAR);
+ align(16);
+
+ L(main0);
+ cmp(M, 16);
+ jle(main2, T_NEAR);
+
+ subloop(32);
+ jmp(main999, T_NEAR);
+ align(16);
+
+ L(main2);
+ cmp(M, 0);
+ jle(main999, T_NEAR);
+ subloop(16);
+ align(16);
+
+ L(main999);
+ // Restore original stack
+ mov(rsp, ORIG_SP);
+
+ vzeroupper();
+ postamble();
+
+ ker_ = this->getCode<ker_t>();
+ }
+
+ typedef void (*ker_t)(dim_t m, dim_t n, dim_t k,
+ const float *alpha, const float *a, dim_t lda,
+ const float *b, dim_t ldb, const float *beta, float *c,
+ dim_t ldc, const float *bias, float *ws);
+
+ void operator()(dim_t m, dim_t n, dim_t k,
+ const float *alpha, const float *a, dim_t lda,
+ const float *b, dim_t ldb, const float *beta, float *c,
+ dim_t ldc, const float *bias, float *ws) const
+ {
+ ker_(m, n, k, alpha, a, lda, b, ldb, beta, c, ldc, bias, ws);
+ }
+
+private:
+ ker_t ker_;
+};
+
+const xbyak_gemm *get_xbyak_gemm(
+ bool isTransA, bool isTransB, float beta, bool hasBias) {
+ auto beta_idx = [](float beta) {
+ return (beta == 0.0) ? 0 : (beta == 1.0 ? 1 : 2);
+ };
+
+ // Kernel table [isTransA][isTransB][hasBias][beta (0, 1, other)]
+ static xbyak_gemm *kernel_table[2][2][2][3];
+ static std::once_flag initialized;
+ std::call_once(initialized, [=]{
+ for (bool isTransA: {false, true})
+ for (bool isTransB: {false, true})
+ for (bool hasBias: {false, true})
+ for (float beta: {0.0f, 1.0f, 2.0f}) {
+ // nocopy sgemm with bias for beta != 0.0 is not supported
+ if (hasBias && beta != 0.0)
+ continue;
+ kernel_table[isTransA][isTransB][hasBias][beta_idx(beta)] =
+ new xbyak_gemm(isTransA, isTransB, beta, hasBias);
+ }
+ });
+
+ return kernel_table[isTransA][isTransB][hasBias][beta_idx(beta)];
+}
+
+void sgemm_nocopy_driver(const char *transa,
+ const char *transb, int m, int n, int k, const float *alpha,
+ const float *a, dim_t lda, const float *b, dim_t ldb, const float *beta,
+ float *c, dim_t ldc, const float *bias, float *ws)
+{
+ bool isTransA = (*transa == 'T' || *transa == 't');
+ bool isTransB = (*transb == 'T' || *transb == 't');
+
+ int Bm, sizeM, Bn, sizeN, Bk, sizeK;
+
+ int i, j;
+
+ if ((m <= 0) || (n <= 0))
+ return;
+
+ if ((k <= 0) || (alpha[0] == 0.)) {
+
+ if (beta[0] == 0.) {
+ for (j = 0; j < n; j++)
+ for (i = 0; i < m; i++)
+ c[i + j * ldc] = 0.0;
+ } else if (beta[0] != 1.) {
+ for (j = 0; j < n; j++)
+ for (i = 0; i < m; i++)
+ c[i + j * ldc] *= beta[0];
+ }
+
+ return;
+ }
+
+ assert(IMPLICATION(bias != nullptr, *beta == 0.0));
+
+ // XXX: this happens on every thread...
+ bool hasBias = (bias != nullptr);
+ auto ker_bn = get_xbyak_gemm(isTransA, isTransB, *beta, hasBias);
+ auto ker_b1 = get_xbyak_gemm(isTransA, isTransB, 1.0, false);
+ auto ker_b0 = get_xbyak_gemm(isTransA, isTransB, 0.0, false);
+ assert(ker_bn && ker_b1 && ker_b0);
+
+ int BM = 4032, BN, BK;
+ if (mayiuse(avx512_core)) {
+ BN = isTransA ? 384 : 64;
+ BK = 384;
+ } else {
+ BN = isTransA ? 96 : 64;
+ BK = isTransB ? 96 : 192;
+ if (!isTransA && !isTransB)
+ BK = 128;
+ }
+ const float *curA, *curB, *curBias = nullptr;
+ float *curC;
+
+ for (Bk = 0; Bk < k; Bk += sizeK) {
+ sizeK = k - Bk;
+ if (sizeK >= BK * 2)
+ sizeK = BK;
+ else {
+ if (sizeK > BK)
+ sizeK = (sizeK + 1) / 2;
+ }
+
+ for (Bm = 0; Bm < m; Bm += sizeM) {
+ sizeM = m - Bm;
+ if (sizeM >= BM * 2)
+ sizeM = BM;
+ else {
+ if (sizeM > BM + BM / 2)
+ sizeM = (sizeM + 1) / 2;
+ }
+
+ for (Bn = 0; Bn < n; Bn += sizeN) {
+ sizeN = n - Bn;
+ if (sizeN >= BN * 2)
+ sizeN = BN;
+ else {
+ if (sizeN > BN + BN / 2)
+ sizeN = (sizeN + 1) / 2;
+ }
+
+ if (!isTransA) {
+ curA = a + Bm + Bk * lda;
+ } else {
+ curA = a + Bk + Bm * lda;
+ }
+ if (!isTransB) {
+ curB = b + Bk + Bn * ldb;
+ } else {
+ curB = b + Bn + Bk * ldb;
+ }
+ curC = c + Bm + (size_t)Bn * ldc;
+ if (bias != nullptr) {
+ if (Bk == 0) {
+ curBias = bias + Bm;
+ } else {
+ curBias = nullptr;
+ }
+ }
+ if (Bk == 0) {
+ if (*beta == 0.0 && bias == nullptr)
+ (*ker_b0)((dim_t)sizeM, (dim_t)sizeN, (dim_t)sizeK,
+ alpha, curA, lda, curB, ldb, beta, curC, ldc,
+ curBias, ws);
+ else
+ (*ker_bn)((dim_t)sizeM, (dim_t)sizeN, (dim_t)sizeK,
+ alpha, curA, lda, curB, ldb, beta, curC, ldc,
+ curBias, ws);
+ } else {
+ (*ker_b1)((dim_t)sizeM, (dim_t)sizeN, (dim_t)sizeK,
+ alpha, curA, lda, curB, ldb, beta, curC, ldc,
+ curBias, ws);
+ }
+ }
+ }
+ }
+}
+
+}
+
+mkldnn_status_t jit_avx512_common_gemm_f32(
+ const char *transa, const char *transb,
+ const int *p_m, const int *p_n, const int *p_k, const float *p_alpha,
+ const float *A, const int *p_lda, const float *B, const int *p_ldb,
+ const float *p_beta, float *C, const int *p_ldc, const float *bias)
+{
+ using namespace mkldnn::impl::utils;
+ using namespace avx512_common_gemm_f32;
+ using namespace gemm_utils;
+
+ if (*p_beta != 0 && bias)
+ return ref_gemm(transa, transb, p_m, p_n, p_k,
+ p_alpha, A, p_lda, B, p_lda, p_beta, C, p_ldc, bias);
+
+ int nthr = (mkldnn_in_parallel()) ? 1 : mkldnn_get_max_threads();
+
+ int m = *p_m;
+ int n = *p_n;
+ int k = *p_k;
+ dim_t lda = *p_lda;
+ dim_t ldb = *p_ldb;
+ dim_t ldc = *p_ldc;
+ float beta = *p_beta;
+ int MB, NB, KB;
+
+ int nthr_m, nthr_n, nthr_k, nthr_mn;
+
+ // Determine threading partitioning
+ calc_nthr_nocopy_avx512_common(
+ m, n, k, nthr, &nthr_m, &nthr_n, &nthr_k, &MB, &NB, &KB);
+ assert(IMPLICATION(!mkldnn_thr_syncable(), nthr_k == 1));
+
+ // May not happen, but just in case
+ if (nthr < nthr_m * nthr_n * nthr_k)
+ nthr = nthr_m * nthr_n * nthr_k;
+
+ nthr_mn = nthr_m * nthr_n;
+
+ unsigned char * ompstatus_ = nullptr;
+ unsigned char volatile *ompstatus = nullptr;
+
+ float *c_buffers = nullptr;
+ float *ws_buffers = nullptr;
+
+ if (nthr_k > 1) {
+ ompstatus_ = (unsigned char *) malloc(
+ nthr * CACHE_LINE_SIZE,
+ CACHE_LINE_SIZE);
+ ompstatus = (unsigned char volatile *) ompstatus_;
+ assert(ompstatus);
+
+ for (int i = 0; i < nthr; i++)
+ ompstatus[i * CACHE_LINE_SIZE] = 0;
+
+ c_buffers = (float *)malloc(nthr_m * nthr_n * (nthr_k - 1) * MB * NB
+ * sizeof(float), PAGE_4K);
+ }
+
+ const size_t ws_elems_per_thr = (size_t)k * 48 + 64;
+ const size_t ws_size_per_thr
+ = rnd_up(ws_elems_per_thr * sizeof(float), PAGE_4K);
+ if (k > STACK_K_CAPACITY) {
+ ws_buffers = (float *)malloc(nthr * ws_size_per_thr, PAGE_4K);
+ }
+
+ parallel_nd(nthr, [&](const int ithr) {
+ int ithr_m, ithr_n, ithr_k, ithr_mn;
+ int m_from, m_to, myM;
+ int n_from, n_to, myN;
+ int k_from, k_to, myK;
+ int cbase, ibase;
+ const float *myA, *myB, *myBias = nullptr;
+ float *myC = C, myBeta;
+ float *ws = ws_buffers ?
+ ws_buffers + ithr * ws_size_per_thr / sizeof(float) : 0;
+ dim_t ld = ldc;
+
+ int sum_later = (mkldnn_get_num_threads() < nthr_m * nthr_n * nthr_k);
+
+ if (ithr < nthr_m * nthr_n * nthr_k) {
+
+ ithr_mn = ithr % nthr_mn;
+ ithr_m = ithr_mn % nthr_m;
+ ithr_n = ithr_mn / nthr_m;
+ ithr_k = ithr / nthr_mn;
+
+ /* swap ithr_k for performance improvement */
+ if (ithr_k == 0)
+ ithr_k = nthr_k - 1;
+ else if (ithr_k == nthr_k - 1)
+ ithr_k = 0;
+
+ m_from = MB * (ithr_m);
+ m_to = MB * (ithr_m + 1);
+ if (m_to > m)
+ m_to = m;
+ myM = m_to - m_from;
+
+ n_from = NB * (ithr_n);
+ n_to = NB * (ithr_n + 1);
+ if (n_to > n)
+ n_to = n;
+ myN = n_to - n_from;
+
+ k_from = KB * (ithr_k);
+ k_to = KB * (ithr_k + 1);
+ if (k_to > k)
+ k_to = k;
+ myK = k_to - k_from;
+
+ cbase = (ithr_m + nthr_m * ithr_n) * (nthr_k - 1);
+ ibase = (ithr_m + nthr_m * ithr_n) * nthr_k;
+
+ if ((myM > 0) && (myN > 0)) {
+
+ if (*transa == 'N' || *transa == 'n') {
+ myA = &(A[m_from + k_from * lda]);
+ } else {
+ myA = &(A[k_from + m_from * lda]);
+ }
+ if (*transb == 'N' || *transb == 'n') {
+ myB = &(B[k_from + n_from * ldb]);
+ } else {
+ myB = &(B[n_from + k_from * ldb]);
+ }
+ if (ithr_k == 0) {
+ myC = &(C[m_from + n_from * ldc]);
+ myBeta = beta;
+ ld = ldc;
+ if (bias)
+ myBias = &(bias[m_from]);
+ } else {
+ myC = c_buffers + (dim_t)MB * NB * (cbase + ithr_k - 1);
+ myBeta = 0.0;
+ ld = MB;
+ myBias = nullptr;
+ }
+
+ sgemm_nocopy_driver(transa, transb, myM, myN, myK, p_alpha, myA,
+ lda, myB, ldb, &myBeta, myC, ld, myBias, ws);
+
+ if (nthr_k > 1 && !sum_later)
+ ompstatus[(ibase + ithr_k) * CACHE_LINE_SIZE] = 1;
+ }
+
+ if (nthr_k > 1 && !sum_later) {
+
+ // sum matrices partitioned along K dimension
+ int n1, n2;
+
+ partition_unit_diff(ithr_k, nthr_k, myN, &n1, &n2);
+
+ if (ithr_k > 0) {
+
+ myC = c_buffers + (dim_t)MB * NB * (cbase + ithr_k - 1)
+ + (dim_t)n1 * MB;
+ /* need to wait until main thread finishes */
+ while (ompstatus[ibase * CACHE_LINE_SIZE] != 1) {
+ };
+
+ /* my cache is hot */
+ sum_two_matrices(myM, n2, myC, MB,
+ &C[m_from + (n_from + n1) * ldc], ldc);
+ }
+
+ for (int ik = 1; ik < nthr_k; ++ik) {
+ if (ik != ithr_k) {
+
+ myC = c_buffers + (dim_t)MB * NB * (cbase + ik - 1)
+ + (dim_t)n1 * MB;
+
+ while (ompstatus[(ibase + ik) * CACHE_LINE_SIZE] != 1) {
+ };
+
+ sum_two_matrices(myM, n2, myC, MB,
+ &C[m_from + (n_from + n1) * ldc], ldc);
+ }
+ }
+ }
+ }
+ });
+
+
+ // handle C summation later
+ if (nthr_k > 1 && ompstatus[0] == 0) {
+
+ parallel_nd(nthr, [&](const int ithr) {
+ int ithr_m, ithr_n, ithr_k, ithr_mn;
+ int m_from, m_to, myM;
+ int n_from, n_to, myN;
+ int cbase;
+ float *myC = C;
+
+ if (ithr < nthr_m * nthr_n * nthr_k) {
+
+ ithr_mn = ithr % nthr_mn;
+ ithr_m = ithr_mn % nthr_m;
+ ithr_n = ithr_mn / nthr_m;
+ ithr_k = ithr / nthr_mn;
+
+ /* swap ithr_k for performance improvement */
+ if (ithr_k == 0)
+ ithr_k = nthr_k - 1;
+ else if (ithr_k == nthr_k - 1)
+ ithr_k = 0;
+
+ m_from = MB * (ithr_m);
+ m_to = MB * (ithr_m + 1);
+ if (m_to > m)
+ m_to = m;
+ myM = m_to - m_from;
+
+ n_from = NB * (ithr_n);
+ n_to = NB * (ithr_n + 1);
+ if (n_to > n)
+ n_to = n;
+ myN = n_to - n_from;
+
+ cbase = (ithr_m + nthr_m * ithr_n) * (nthr_k - 1);
+
+ if (nthr_k > 1) {
+ // sum matrices partitioned along K dimension
+ int n1, n2;
+
+ partition_unit_diff(ithr_k, nthr_k, myN, &n1, &n2);
+
+ if (ithr_k > 0) {
+
+ myC = c_buffers + (dim_t)MB * NB * (cbase + ithr_k - 1)
+ + (dim_t)n1 * MB;
+
+ /* my cache is hot */
+ sum_two_matrices(myM, n2, myC, MB,
+ &C[m_from + (n_from + n1) * ldc], ldc);
+ }
+
+ for (int ik = 1; ik < nthr_k; ++ik) {
+ if (ik != ithr_k) {
+
+ myC = c_buffers + (dim_t)MB * NB * (cbase + ik - 1)
+ + (dim_t)n1 * MB;
+
+ sum_two_matrices(myM, n2, myC, MB,
+ &C[m_from + (n_from + n1) * ldc], ldc);
+ }
+ }
+ }
+ }
+ });
+ }
+
+ free(c_buffers);
+ free(ompstatus_);
+ free(ws_buffers);
+
+ return mkldnn_success;
+}
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx512_common_gemm_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx512_common_gemm_f32.hpp
new file mode 100644
index 0000000000..d581b7fd71
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx512_common_gemm_f32.hpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_AVX512_COMMON_GEMM_F32_HPP
+#define JIT_AVX512_COMMON_GEMM_F32_HPP
+
+#include "mkldnn_types.h"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+mkldnn_status_t jit_avx512_common_gemm_f32(
+ const char *transa, const char *transb, const int *M,
+ const int *N, const int *K, const float *alpha, const float *A,
+ const int *lda, const float *B, const int *ldb, const float *beta,
+ float *C, const int *ldc, const float *bias = nullptr);
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx_gemm_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx_gemm_f32.cpp
new file mode 100644
index 0000000000..60d4220837
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx_gemm_f32.cpp
@@ -0,0 +1,2705 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <cmath>
+#include <mutex>
+
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "ref_gemm_f32.hpp"
+#include "gemm_utils_f32.hpp"
+#include "jit_avx_gemm_f32.hpp"
+
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+#define CACHE_LINE_SIZE 64
+
+#define STACKSIZE get_size_of_abi_save_regs()
+#if _WIN32
+#define STACK_K_CAPACITY 128
+#else
+#define STACK_K_CAPACITY 8192
+#endif
+#define SIZE 4
+#define OFFSET 32
+#define BASE_SHIFT 2
+#define SECOND_FETCH 14
+
+namespace avx_gemm_f32 {
+using namespace gemm_utils;
+
+struct xbyak_gemm : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx_gemm_f32_xbyak_gemm)
+
+ xbyak_gemm(char isTransA, char isTransB, float beta, bool hasBias = false,
+ void *code_ptr = nullptr,
+ size_t code_size = 80 * Xbyak::DEFAULT_MAX_CODE_SIZE)
+ : jit_generator(code_ptr, code_size)
+ {
+ using namespace Xbyak;
+
+ const bool is_avx2 = mayiuse(avx2);
+ assert(IMPLICATION(!is_avx2, mayiuse(avx)));
+
+ const int UNROLL_M = is_avx2 ? 16 : 8;
+ const int UNROLL_N = 6;
+
+ bool isBeta0 = (beta == 0.0);
+ bool isBetaN = (!isBeta0 && beta != 1.0);
+
+ // various definitions for convenience
+ auto ARG_M = abi_param1;
+ auto ARG_N = abi_param2;
+ auto K = abi_param3;
+ auto ARG_ALPHA = abi_param4;
+#ifdef _WIN32
+ auto ARG_A = ptr[rsp + OFFSET_SHADOWSPACE + STACKSIZE];
+ auto ARG_LDA = qword[rsp + OFFSET_SHADOWSPACE +
+ sizeof(float *) + STACKSIZE];
+ const auto stackOffset = OFFSET_SHADOWSPACE +
+ sizeof(float *) + STACKSIZE;
+ auto A = rsi;
+ auto LDA = rdi;
+#else
+ auto ARG_A = r8;
+ auto ARG_LDA = r9;
+ const auto stackOffset = STACKSIZE;
+ auto A = ARG_A;
+ auto LDA = ARG_LDA;
+#endif
+ auto ARG_B = ptr[rsp + 8 + stackOffset];
+ auto ARG_LDB = ptr[rsp + 16 + stackOffset];
+ auto ARG_BETA = ptr[rsp + 24 + stackOffset];
+ auto ARG_C = ptr[rsp + 32 + stackOffset];
+ auto ARG_LDC = ptr[rsp + 40 + stackOffset];
+ auto ARG_BIAS = ptr[rsp + 48 + stackOffset];
+ auto ARG_WS = ptr[rsp + 56 + stackOffset];
+
+ auto B = r11;
+ auto LDB = rbx;
+ auto LDC = r13;
+ auto LL = rax;
+ auto AO1 = abi_param2;
+ auto BO1 = abi_param4;
+ auto BO2 = rbp;
+ auto CO1 = r14;
+ auto CO2 = r15;
+ auto LDB3 = r10;
+ auto LDA4 = abi_param1;
+ auto AA = r12;
+ auto BIAS1 = abi_param1;
+
+ auto M = qword[rsp + 0];
+ auto N = qword[rsp + 8];
+ auto FLAG = qword[rsp + 16];
+ auto I = qword[rsp + 24];
+ auto C = qword[rsp + 32];
+ auto BIAS = qword[rsp + 40];
+ auto ALPHA = qword[rsp + 48];
+ auto BETA = qword[rsp + 64];
+ auto ORIG_A = qword[rsp + 80];
+ auto MASK = dword[rsp + 88];
+ auto STRIDE = qword[rsp + 120];
+ auto ORIG_SP = qword[rsp + 152];
+
+ auto VALPHA = ymm1;
+ auto VBETA = ymm2;
+ auto VMASK = ymm3;
+ auto VBIAS1 = ymm2;
+ auto VBIAS2 = ymm4;
+
+ auto PREFETCHSIZEA = 128;
+ auto PREFETCHSIZEB = (!isTransB) ? -16 : 0;
+
+ // Function for packing if needed
+ auto do_pack = [&](
+ int unroll_m, bool isLoad1Unmasked, bool isLoad2Unmasked) {
+ Label pack2, pack3, pack4, pack10;
+
+ int regIdx;
+ Reg64 reg;
+
+ mov(BO1, A);
+ lea(AO1, ptr[rsp + 256 + OFFSET * SIZE]);
+
+ if (isTransA) {
+ lea(BO2, ptr[BO1 + LDA * 4]);
+ lea(CO1, ptr[LDA + LDA * 2]);
+ vmovupd(ymm7, STRIDE);
+ }
+
+ mov(LL, K);
+ sar(LL, 2);
+ jle(pack3, T_NEAR);
+ align(16);
+
+ L(pack2);
+ if (!isTransA) {
+ for (int i = 0; i < 4; i++) {
+ regIdx = (i % 2 == 0) ? 4 : 6;
+ if (isLoad1Unmasked) {
+ vmovups(Ymm(regIdx),
+ ptr[BO1 + (0 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(Ymm(regIdx), VMASK,
+ ptr[BO1 + (0 * 8 - OFFSET) * SIZE]);
+ }
+ if (unroll_m > 8) {
+ if (isLoad2Unmasked) {
+ vmovups(Ymm(regIdx + 1),
+ ptr[BO1 + (1 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(Ymm(regIdx + 1), VMASK,
+ ptr[BO1 + (1 * 8 - OFFSET) * SIZE]);
+ }
+ }
+ add(BO1, LDA);
+
+ vmovups(ptr[AO1 + (unroll_m * i + 0 * 8 - OFFSET) * SIZE],
+ Ymm(regIdx));
+ if (unroll_m > 8) {
+ vmovups(ptr[AO1
+ + (unroll_m * i + 1 * 8 - OFFSET)
+ * SIZE],
+ Ymm(regIdx + 1));
+ }
+ }
+
+ } else {
+ if (isLoad1Unmasked) {
+ for (int i = 0; i < 2; i++) {
+ reg = (i % 2 == 0) ? BO1 : BO2;
+ vmovups(xmm0, ptr[reg + (0 * 8 - OFFSET) * SIZE]);
+ vmovups(xmm1,
+ ptr[reg + LDA * 1 + (0 * 8 - OFFSET) * SIZE]);
+ lea(BO2, ptr[reg + LDA * 2]);
+ vunpcklps(xmm4, xmm0, xmm1);
+ vunpckhps(xmm5, xmm0, xmm1);
+ vmovups(xmm0, ptr[BO2 + (0 * 8 - OFFSET) * SIZE]);
+ vmovups(xmm1,
+ ptr[BO2 + LDA * 1 + (0 * 8 - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDA * 2]);
+ vunpcklps(xmm6, xmm0, xmm1);
+ vunpckhps(xmm2, xmm0, xmm1);
+
+ vunpcklpd(xmm0, xmm4, xmm6);
+ vunpckhpd(xmm1, xmm4, xmm6);
+ vmovups(ptr[AO1
+ + (unroll_m * 0 + i * 4 - OFFSET)
+ * SIZE],
+ xmm0);
+ vmovups(ptr[AO1
+ + (unroll_m * 1 + i * 4 - OFFSET)
+ * SIZE],
+ xmm1);
+ vunpcklpd(xmm0, xmm5, xmm2);
+ vunpckhpd(xmm1, xmm5, xmm2);
+ vmovups(ptr[AO1
+ + (unroll_m * 2 + i * 4 - OFFSET)
+ * SIZE],
+ xmm0);
+ vmovups(ptr[AO1
+ + (unroll_m * 3 + i * 4 - OFFSET)
+ * SIZE],
+ xmm1);
+ }
+ } else if (is_avx2) {
+ for (int i = 0; i < 2; i++) {
+ vmovaps(xmm4, xmm3);
+ vgatherqps(xmm0,
+ ptr[BO1 + ymm7 + ((2 * i) - OFFSET) * SIZE],
+ xmm4);
+ vmovaps(xmm4, xmm3);
+ vgatherqps(xmm1,
+ ptr[BO1 + ymm7 + ((2 * i + 1) - OFFSET) * SIZE],
+ xmm4);
+
+ vmovups(ptr[AO1
+ + (unroll_m * (2 * i) + 0 * 4 - OFFSET)
+ * SIZE],
+ xmm0);
+ vmovups(ptr[AO1
+ + (unroll_m * (2 * i + 1) + 0 * 4
+ - OFFSET)
+ * SIZE],
+ xmm1);
+ }
+
+ lea(BO2, ptr[BO1 + LDA * 4]);
+
+ for (int i = 0; i < 2; i++) {
+ vextractf128(xmm4, ymm3, 1);
+ vgatherqps(xmm0,
+ ptr[BO2 + ymm7 + ((2 * i) - OFFSET) * SIZE],
+ xmm4);
+ vextractf128(xmm4, ymm3, 1);
+ vgatherqps(xmm1,
+ ptr[BO2 + ymm7 + ((2 * i + 1) - OFFSET) * SIZE],
+ xmm4);
+
+ vmovups(ptr[AO1
+ + (unroll_m * (2 * i) + 1 * 4 - OFFSET)
+ * SIZE],
+ xmm0);
+ vmovups(ptr[AO1
+ + (unroll_m * (2 * i + 1) + 1 * 4
+ - OFFSET)
+ * SIZE],
+ xmm1);
+ }
+
+ lea(BO2, ptr[BO2 + LDA * 4]);
+ } else {
+ vxorps(xmm4, xmm4, xmm4);
+ lea(BO2, ptr[BO1 + LDA * 4]);
+
+ auto el_cp = [&](int section, int ld_step) {
+ RegExp src_addr = section == 0 ? BO1 : BO2;
+ if (ld_step == 1 || ld_step == 2)
+ src_addr = src_addr + LDA * ld_step;
+ else if (ld_step == 3)
+ src_addr = src_addr + CO1;
+ src_addr = src_addr - OFFSET * SIZE;
+
+ vmovups(Xmm(ld_step % 2), ptr[src_addr]);
+ RegExp dst_addr = AO1
+ + (ld_step + section * 4 - OFFSET) * SIZE;
+ for (int off = 0; off < 4; ++off)
+ pextrd(ptr[dst_addr + unroll_m * off * SIZE],
+ Xmm(ld_step % 2), off);
+ };
+
+ Label l_end;
+ el_cp(0, 0); cmp(M, 4 * 0 + 0 + 1); je(l_end, T_NEAR);
+ el_cp(0, 1); cmp(M, 4 * 0 + 1 + 1); je(l_end, T_NEAR);
+ el_cp(0, 2); cmp(M, 4 * 0 + 2 + 1); je(l_end, T_NEAR);
+ el_cp(0, 3); cmp(M, 4 * 0 + 3 + 1); je(l_end, T_NEAR);
+ el_cp(1, 0); cmp(M, 4 * 1 + 0 + 1); je(l_end, T_NEAR);
+ el_cp(1, 1); cmp(M, 4 * 1 + 1 + 1); je(l_end, T_NEAR);
+ el_cp(1, 2);
+ L(l_end);
+
+ lea(BO2, ptr[BO2 + LDA * 4]);
+ }
+
+ if (unroll_m >= 16) {
+ assert(is_avx2);
+ if (isLoad2Unmasked) {
+ for (int i = 0; i < 2; i++) {
+ vmovups(xmm0, ptr[BO2 + (0 * 8 - OFFSET) * SIZE]);
+ vmovups(xmm1, ptr[BO2 + LDA * 1
+ + (0 * 8 - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDA * 2]);
+ vunpcklps(xmm4, xmm0, xmm1);
+ vunpckhps(xmm5, xmm0, xmm1);
+ vmovups(xmm0, ptr[BO2 + (0 * 8 - OFFSET) * SIZE]);
+ vmovups(xmm1, ptr[BO2 + LDA * 1
+ + (0 * 8 - OFFSET) * SIZE]);
+ if (i == 0)
+ lea(BO2, ptr[BO2 + LDA * 2]);
+ vunpcklps(xmm6, xmm0, xmm1);
+ vunpckhps(xmm2, xmm0, xmm1);
+
+ vunpcklpd(xmm0, xmm4, xmm6);
+ vunpckhpd(xmm1, xmm4, xmm6);
+ vmovups(ptr[AO1
+ + (unroll_m * 0 + (i + 2) * 4
+ - OFFSET)
+ * SIZE],
+ xmm0);
+ vmovups(ptr[AO1
+ + (unroll_m * 1 + (i + 2) * 4
+ - OFFSET)
+ * SIZE],
+ xmm1);
+ vunpcklpd(xmm0, xmm5, xmm2);
+ vunpckhpd(xmm1, xmm5, xmm2);
+ vmovups(ptr[AO1
+ + (unroll_m * 2 + (i + 2) * 4
+ - OFFSET)
+ * SIZE],
+ xmm0);
+ vmovups(ptr[AO1
+ + (unroll_m * 3 + (i + 2) * 4
+ - OFFSET)
+ * SIZE],
+ xmm1);
+ }
+ } else {
+ for (int i = 0; i < 2; i++) {
+ vmovaps(xmm4, xmm3);
+ vgatherqps(xmm0,
+ ptr[BO2 + ymm7 + ((2 * i) - OFFSET) * SIZE],
+ xmm4);
+ vmovaps(xmm4, xmm3);
+ vgatherqps(xmm1,
+ ptr[BO2 + ymm7
+ + ((2 * i + 1) - OFFSET) * SIZE],
+ xmm4);
+
+ vmovups(ptr[AO1
+ + (unroll_m * (2 * i) + 2 * 4
+ - OFFSET)
+ * SIZE],
+ xmm0);
+ vmovups(ptr[AO1
+ + (unroll_m * (2 * i + 1) + 2 * 4
+ - OFFSET)
+ * SIZE],
+ xmm1);
+ }
+
+ lea(BO2, ptr[BO2 + LDA * 4]);
+
+ for (int i = 0; i < 2; i++) {
+ vextractf128(xmm4, ymm3, 1);
+ vgatherqps(xmm0,
+ ptr[BO2 + ymm7 + ((2 * i) - OFFSET) * SIZE],
+ xmm4);
+ vextractf128(xmm4, ymm3, 1);
+ vgatherqps(xmm1,
+ ptr[BO2 + ymm7
+ + ((2 * i + 1) - OFFSET) * SIZE],
+ xmm4);
+
+ vmovups(ptr[AO1
+ + (unroll_m * (2 * i) + 3 * 4
+ - OFFSET)
+ * SIZE],
+ xmm0);
+ vmovups(ptr[AO1
+ + (unroll_m * (2 * i + 1) + 3 * 4
+ - OFFSET)
+ * SIZE],
+ xmm1);
+ }
+
+ lea(BO2, ptr[BO2 + LDA * 4]);
+ }
+ }
+ add(BO1, (4 * SIZE));
+ }
+
+ add(AO1, unroll_m * 4 * SIZE);
+ sub(LL, 1);
+ jg(pack2, T_NEAR);
+ align(16);
+
+ L(pack3);
+ mov(LL, K);
+ and_(LL, 3);
+ jle(pack10, T_NEAR);
+ align(16);
+
+ L(pack4);
+ if (!isTransA) {
+ if (isLoad1Unmasked) {
+ vmovups(ymm4, ptr[BO1 + (0 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm4, VMASK, ptr[BO1 + (0 * 8 - OFFSET) * SIZE]);
+ }
+ if (unroll_m > 8) {
+ if (isLoad2Unmasked) {
+ vmovups(ymm5, ptr[BO1 + (1 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm5, VMASK,
+ ptr[BO1 + (1 + 8 - OFFSET) * SIZE]);
+ }
+ }
+ add(BO1, LDA);
+ vmovups(ptr[AO1 + (unroll_m * 0 + 0 * 8 - OFFSET) * SIZE],
+ ymm4);
+ if (unroll_m > 8) {
+ vmovups(ptr[AO1 + (unroll_m * 0 + 1 * 8 - OFFSET) * SIZE],
+ ymm5);
+ }
+ } else {
+ if (isLoad1Unmasked) {
+ for (int i = 0; i < 2; i++) {
+ reg = (i % 2 == 0) ? BO1 : BO2;
+ vmovss(Xmm(i + 1), ptr[reg + (0 * 8 - OFFSET) * SIZE]);
+ vmovss(xmm0,
+ ptr[reg + LDA * 1 + (0 * 8 - OFFSET) * SIZE]);
+ lea(BO2, ptr[reg + LDA * 2]);
+ vunpcklps(Xmm(i + 1), Xmm(i + 1), Xmm(0));
+ }
+ vunpcklpd(xmm1, xmm1, xmm2);
+ vmovups(ptr[AO1 + (unroll_m * 0 + 0 * 4 - OFFSET) * SIZE],
+ xmm1);
+
+ for (int i = 0; i < 2; i++) {
+ vmovss(Xmm(i + 1), ptr[BO2 + (0 * 8 - OFFSET) * SIZE]);
+ vmovss(xmm0,
+ ptr[BO2 + LDA * 1 + (0 * 8 - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDA * 2]);
+ vunpcklps(Xmm(i + 1), Xmm(i + 1), Xmm(0));
+ }
+ vunpcklpd(xmm1, xmm1, xmm2);
+ vmovups(ptr[AO1 + (unroll_m * 0 + 1 * 4 - OFFSET) * SIZE],
+ xmm1);
+ } else if (is_avx2) {
+ vmovaps(xmm4, xmm3);
+ vgatherqps(xmm1, ptr[BO1 + ymm7 + (0 * 8 - OFFSET) * SIZE],
+ xmm4);
+ lea(BO2, ptr[BO1 + LDA * 4]);
+ vmovups(ptr[AO1 + (unroll_m * 0 + 0 * 4 - OFFSET) * SIZE],
+ xmm1);
+
+ vextractf128(xmm4, ymm3, 1);
+ vgatherqps(xmm1, ptr[BO2 + ymm7 + (0 * 8 - OFFSET) * SIZE],
+ xmm4);
+ lea(BO2, ptr[BO2 + LDA * 4]);
+ vmovups(ptr[AO1 + (unroll_m * 0 + 1 * 4 - OFFSET) * SIZE],
+ xmm1);
+ } else {
+ vxorps(xmm4, xmm4, xmm4);
+ lea(BO2, ptr[BO1 + LDA * 4]);
+
+ auto el_cp = [&](int section, int ld_step) {
+ RegExp src_addr = section == 0 ? BO1 : BO2;
+ if (ld_step == 1 || ld_step == 2)
+ src_addr = src_addr + LDA * ld_step;
+ else if (ld_step == 3)
+ src_addr = src_addr + CO1;
+ src_addr = src_addr - OFFSET * SIZE;
+
+ vmovss(xmm1, ptr[src_addr]);
+ RegExp dst_addr = AO1
+ + (ld_step + section * 4 - OFFSET) * SIZE;
+ movss(ptr[dst_addr], xmm1);
+ };
+
+ Label l_end;
+ el_cp(0, 0); cmp(M, 4 * 0 + 0 + 1); je(l_end, T_NEAR);
+ el_cp(0, 1); cmp(M, 4 * 0 + 1 + 1); je(l_end, T_NEAR);
+ el_cp(0, 2); cmp(M, 4 * 0 + 2 + 1); je(l_end, T_NEAR);
+ el_cp(0, 3); cmp(M, 4 * 0 + 3 + 1); je(l_end, T_NEAR);
+ el_cp(1, 0); cmp(M, 4 * 1 + 0 + 1); je(l_end, T_NEAR);
+ el_cp(1, 1); cmp(M, 4 * 1 + 1 + 1); je(l_end, T_NEAR);
+ el_cp(1, 2);
+ L(l_end);
+
+ lea(BO2, ptr[BO2 + LDA * 4]);
+ }
+
+ if (unroll_m >= 16) {
+ assert(is_avx2);
+ if (isLoad2Unmasked) {
+ for (int i = 0; i < 2; i++) {
+ vmovss(Xmm(i + 1),
+ ptr[BO2 + (0 * 8 - OFFSET) * SIZE]);
+ vmovss(xmm0, ptr[BO2 + LDA * 1
+ + (0 * 8 - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDA * 2]);
+ vunpcklps(Xmm(i + 1), Xmm(i + 1), Xmm(0));
+ }
+ vunpcklpd(xmm1, xmm1, xmm2);
+ } else {
+ vmovaps(xmm4, xmm3);
+ vgatherqps(xmm1,
+ ptr[BO2 + ymm7 + (0 * 8 - OFFSET) * SIZE],
+ xmm4);
+ lea(BO2, ptr[BO2 + LDA * 4]);
+ }
+ vmovups(ptr[AO1 + (unroll_m * 0 + 2 * 4 - OFFSET) * SIZE],
+ xmm1);
+
+ if (isLoad2Unmasked) {
+ for (int i = 0; i < 2; i++) {
+ vmovss(Xmm(i + 1),
+ ptr[BO2 + (0 * 8 - OFFSET) * SIZE]);
+ vmovss(xmm0, ptr[BO2 + LDA * 1
+ + (0 * 8 - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDA * 2]);
+ vunpcklps(Xmm(i + 1), Xmm(i + 1), Xmm(0));
+ }
+ vunpcklpd(xmm1, xmm1, xmm2);
+ } else {
+ vextractf128(xmm4, ymm3, 1);
+ vgatherqps(xmm1,
+ ptr[BO2 + ymm7 + (0 * 8 - OFFSET) * SIZE],
+ xmm4);
+ }
+ vmovups(ptr[AO1 + (unroll_m * 0 + 3 * 4 - OFFSET) * SIZE],
+ xmm1);
+ }
+ add(BO1, SIZE);
+ }
+
+ add(AO1, unroll_m * SIZE);
+ sub(LL, 1);
+ jg(pack4, T_NEAR);
+ align(16);
+
+ L(pack10);
+ };
+
+ // Fused multiply add; may become one or two instructions
+ auto fma = [&](bool useFma, Ymm reg0, Ymm reg1, Ymm reg2,
+ bool overWrite = false) {
+ if (useFma) {
+ if (is_avx2) {
+ vfmadd231ps(reg2, reg1, reg0);
+ } else {
+ assert(UNROLL_M == 8);
+ auto tent_vreg = overWrite ? reg1 : ymm1;
+ vmulps(tent_vreg, reg1, reg0);
+ vaddps(reg2, reg2, tent_vreg);
+ }
+ } else {
+ if (!overWrite) {
+ vmulps(ymm15, reg1, reg0);
+ vaddps(reg2, reg2, ymm15);
+ } else {
+ vmulps(reg1, reg1, reg0);
+ vaddps(reg2, reg2, reg1);
+ }
+ }
+ };
+
+ // Inner kernel with k=8
+ auto innerkernel8 = [&](int unroll_m, int unroll_n,
+ bool isLoad1Unmasked, bool isLoad2Unmasked, bool isDirect,
+ bool isCopy, bool useFma, Ymm reg00, Ymm reg01, Ymm reg02,
+ Ymm reg03, Ymm reg04, Ymm reg05, Ymm reg06, Ymm reg07,
+ Ymm reg08, Ymm reg09, Ymm reg10, Ymm reg11, Ymm reg12,
+ Ymm reg13, Ymm reg14, Ymm reg15, Ymm reg16, Ymm reg17,
+ Ymm reg18, Ymm reg19, Ymm reg20, Ymm reg21, Ymm reg22,
+ Ymm reg23) {
+
+ Ymm fmareg;
+
+ if (!isDirect) {
+ prefetcht0(ptr[AO1 + (PREFETCHSIZEA + 0) * SIZE]);
+ } else {
+ prefetcht0(ptr[AO1 + LDA4]);
+ }
+
+ for (int i = 0; i < 8; i++) {
+ if (isDirect) {
+ if (isLoad1Unmasked) {
+ vmovups(ymm0, ptr[AO1 + (0 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm0, VMASK,
+ ptr[AO1 + (0 * 8 - OFFSET) * SIZE]);
+ }
+ if (unroll_m >= 16) {
+ if (isLoad2Unmasked) {
+ vmovups(ymm1, ptr[AO1 + (1 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm1, VMASK,
+ ptr[AO1 + (1 * 8 - OFFSET) * SIZE]);
+ }
+ }
+ add(AO1, LDA);
+ }
+
+ if (!isTransB) {
+ vbroadcastss(ymm2, ptr[BO1 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (0 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg00 : reg12;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg06 : reg18;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ if (i == 0) {
+ if (!isTransB) {
+ prefetcht0(ptr[BO1 + PREFETCHSIZEB * SIZE]);
+ }
+ }
+ if (unroll_n >= 2) {
+ if (!isTransB) {
+ if (i == 1) {
+ prefetcht0(ptr[BO1 + LDB + PREFETCHSIZEB * SIZE]);
+ }
+ vbroadcastss(
+ ymm2, ptr[BO1 + LDB * 1 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (1 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg01 : reg13;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg07 : reg19;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (isCopy) {
+ vmovups(ptr[LDA4 + (unroll_m * i + 0 * 8 - OFFSET) * SIZE],
+ ymm0);
+ if (unroll_m >= 16) {
+ vmovups(ptr[LDA4
+ + (unroll_m * i + 1 * 8 - OFFSET)
+ * SIZE],
+ ymm1);
+ }
+ if (i == 7) {
+ sub(LDA4, -unroll_m * 8 * SIZE);
+ }
+ }
+
+ if (unroll_n >= 3) {
+ if (!isTransB) {
+ if (i == 2) {
+ prefetcht0(
+ ptr[BO1 + LDB * 2 + PREFETCHSIZEB * SIZE]);
+ }
+ vbroadcastss(
+ ymm2, ptr[BO1 + LDB * 2 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (2 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg02 : reg14;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg08 : reg20;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (i == 7) {
+ if (!isTransB) {
+ sub(BO1, -8 * SIZE);
+ }
+ }
+
+ if (unroll_n >= 4) {
+ if (!isTransB) {
+ if (i == 3) {
+ prefetcht0(ptr[BO2 + PREFETCHSIZEB * SIZE]);
+ }
+ vbroadcastss(ymm2, ptr[BO2 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (3 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg03 : reg15;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg09 : reg21;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (unroll_n >= 5) {
+ if (!isTransB) {
+ if (i == 4) {
+ prefetcht0(ptr[BO2 + LDB + PREFETCHSIZEB * SIZE]);
+ }
+ vbroadcastss(
+ ymm2, ptr[BO2 + LDB * 1 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (4 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg04 : reg16;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg10 : reg22;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (unroll_n >= 6) {
+ if (!isTransB) {
+ if (i == 5) {
+ prefetcht0(
+ ptr[BO2 + LDB * 2 + PREFETCHSIZEB * SIZE]);
+ }
+ vbroadcastss(
+ ymm2, ptr[BO2 + LDB * 2 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (5 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg05 : reg17;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg11 : reg23;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+ if (isTransB) {
+ prefetcht0(ptr[BO1 + BO2]);
+ add(BO1, LDB);
+ }
+
+ if (i == 0) {
+ if (unroll_m >= 4) {
+ if (!isDirect) {
+ prefetcht0(
+ ptr[AO1 + (PREFETCHSIZEA + 2 * 8) * SIZE]);
+ } else {
+ prefetcht0(ptr[AO1 + LDA4]);
+ }
+ }
+ }
+ if (i == 1 || i == 2) {
+ if (unroll_m >= 8) {
+ if (!isDirect) {
+ prefetcht0(ptr[AO1
+ + (PREFETCHSIZEA + (2 + 2 * i) * 8)
+ * SIZE]);
+ } else {
+ prefetcht0(ptr[AO1 + LDA4]);
+ }
+ }
+ }
+ if (i == 3 || i == 4 || i == 5 || i == 6) {
+ if (unroll_m >= 16) {
+ if (!isDirect) {
+ prefetcht0(ptr[AO1
+ + (PREFETCHSIZEA + (2 + 2 * i) * 8)
+ * SIZE]);
+ } else {
+ prefetcht0(ptr[AO1 + LDA4]);
+ }
+ }
+ }
+ if (i == 7) {
+ if (!isTransB) {
+ if (unroll_n >= 4) {
+ sub(BO2, -8 * SIZE);
+ }
+ }
+ if (!isTransA) {
+ prefetcht2(ptr[AA]);
+ lea(AA, ptr[AA + LDA]);
+ }
+ }
+
+ if (!isDirect) {
+ if (isLoad1Unmasked) {
+ vmovups(ymm0,
+ ptr[AO1
+ + (unroll_m * (i + 1) + 0 * 8 - OFFSET)
+ * SIZE]);
+ } else {
+ vmaskmovps(
+ ymm0, VMASK,
+ ptr[AO1
+ + (unroll_m * (i + 1) + 0 * 8 - OFFSET)
+ * SIZE]);
+ }
+ if (unroll_m >= 16) {
+ if (isLoad2Unmasked) {
+ vmovups(ymm1, ptr[AO1
+ + (unroll_m * (i + 1) + 1 * 8
+ - OFFSET)
+ * SIZE]);
+ } else {
+ vmaskmovps(ymm1, VMASK,
+ ptr[AO1
+ + (unroll_m * (i + 1) + 1 * 8
+ - OFFSET)
+ * SIZE]);
+ }
+ }
+ }
+ }
+
+ if (!isDirect) {
+ sub(AO1, -unroll_m * 8 * SIZE);
+ }
+ sub(LL, 1);
+
+ };
+
+ // Inner kernel with k=4
+ auto innerkernel4 = [&](int unroll_m, int unroll_n,
+ bool isLoad1Unmasked, bool isLoad2Unmasked, bool isDirect,
+ bool isCopy, bool useFma, Ymm reg00, Ymm reg01, Ymm reg02,
+ Ymm reg03, Ymm reg04, Ymm reg05, Ymm reg06, Ymm reg07,
+ Ymm reg08, Ymm reg09, Ymm reg10, Ymm reg11, Ymm reg12,
+ Ymm reg13, Ymm reg14, Ymm reg15, Ymm reg16, Ymm reg17,
+ Ymm reg18, Ymm reg19, Ymm reg20, Ymm reg21, Ymm reg22,
+ Ymm reg23) {
+
+ Ymm fmareg;
+
+ if (!isDirect) {
+ prefetcht0(ptr[AO1 + (PREFETCHSIZEA + 0) * SIZE]);
+ } else {
+ prefetcht0(ptr[AO1 + LDA4]);
+ }
+
+ for (int i = 0; i < 4; i++) {
+ if (isDirect) {
+ if (isLoad1Unmasked) {
+ vmovups(ymm0, ptr[AO1 + (0 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm0, VMASK,
+ ptr[AO1 + (0 * 8 - OFFSET) * SIZE]);
+ }
+ if (unroll_m >= 16) {
+ if (isLoad2Unmasked) {
+ vmovups(ymm1, ptr[AO1 + (1 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm1, VMASK,
+ ptr[AO1 + (1 * 8 - OFFSET) * SIZE]);
+ }
+ }
+ add(AO1, LDA);
+ }
+
+ if (!isTransB) {
+ vbroadcastss(ymm2, ptr[BO1 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (0 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg00 : reg12;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg06 : reg18;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ if (i == 0) {
+ if (!isTransB) {
+ prefetcht0(ptr[BO1 + PREFETCHSIZEB * SIZE]);
+ }
+ }
+ if (unroll_n >= 2) {
+ if (!isTransB) {
+ if (i == 1) {
+ prefetcht0(ptr[BO1 + LDB + PREFETCHSIZEB * SIZE]);
+ }
+ vbroadcastss(
+ ymm2, ptr[BO1 + LDB * 1 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (1 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg01 : reg13;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg07 : reg19;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (isCopy) {
+ vmovups(ptr[LDA4 + (unroll_m * i + 0 * 8 - OFFSET) * SIZE],
+ ymm0);
+ if (unroll_m >= 16) {
+ vmovups(ptr[LDA4
+ + (unroll_m * i + 1 * 8 - OFFSET)
+ * SIZE],
+ ymm1);
+ }
+ if (i == 3) {
+ sub(LDA4, -unroll_m * 4 * SIZE);
+ }
+ }
+
+ if (unroll_n >= 3) {
+ if (!isTransB) {
+ if (i == 2) {
+ prefetcht0(
+ ptr[BO1 + LDB * 2 + PREFETCHSIZEB * SIZE]);
+ }
+ vbroadcastss(
+ ymm2, ptr[BO1 + LDB * 2 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (2 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg02 : reg14;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg08 : reg20;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (i == 7) {
+ if (!isTransB) {
+ sub(BO1, -8 * SIZE);
+ }
+ }
+
+ if (unroll_n >= 4) {
+ if (!isTransB) {
+ if (i == 3) {
+ prefetcht0(ptr[BO2 + PREFETCHSIZEB * SIZE]);
+ }
+ vbroadcastss(ymm2, ptr[BO2 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (3 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg03 : reg15;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg09 : reg21;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (unroll_n >= 5) {
+ if (!isTransB) {
+ if (i == 4) {
+ prefetcht0(ptr[BO2 + LDB + PREFETCHSIZEB * SIZE]);
+ }
+ vbroadcastss(
+ ymm2, ptr[BO2 + LDB * 1 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (4 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg04 : reg16;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg10 : reg22;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (unroll_n >= 6) {
+ if (!isTransB) {
+ if (i == 5) {
+ prefetcht0(
+ ptr[BO2 + LDB * 2 + PREFETCHSIZEB * SIZE]);
+ }
+ vbroadcastss(
+ ymm2, ptr[BO2 + LDB * 2 + (i - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (5 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg05 : reg17;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg11 : reg23;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+ if (isTransB) {
+ prefetcht0(ptr[BO1 + BO2]);
+ add(BO1, LDB);
+ }
+
+ if (i == 0) {
+ if (unroll_m >= 4) {
+ if (!isDirect) {
+ prefetcht0(
+ ptr[AO1 + (PREFETCHSIZEA + 2 * 8) * SIZE]);
+ } else {
+ prefetcht0(ptr[AO1 + LDA4]);
+ }
+ }
+ }
+ if (i == 1 || i == 2) {
+ if (unroll_m >= 8) {
+ if (!isDirect) {
+ prefetcht0(ptr[AO1
+ + (PREFETCHSIZEA + (2 + 2 * i) * 8)
+ * SIZE]);
+ } else {
+ prefetcht0(ptr[AO1 + LDA4]);
+ }
+ }
+ }
+ if (i == 3) {
+ if (!isTransB) {
+ sub(BO1, -4 * SIZE);
+ if (unroll_n >= 4) {
+ sub(BO2, -4 * SIZE);
+ }
+ }
+ }
+
+ if (!isDirect) {
+ if (isLoad1Unmasked) {
+ vmovups(ymm0,
+ ptr[AO1
+ + (unroll_m * (i + 1) + 0 * 8 - OFFSET)
+ * SIZE]);
+ } else {
+ vmaskmovps(
+ ymm0, VMASK,
+ ptr[AO1
+ + (unroll_m * (i + 1) + 0 * 8 - OFFSET)
+ * SIZE]);
+ }
+ if (unroll_m >= 16) {
+ if (isLoad2Unmasked) {
+ vmovups(ymm1, ptr[AO1
+ + (unroll_m * (i + 1) + 1 * 8
+ - OFFSET)
+ * SIZE]);
+ } else {
+ vmaskmovps(ymm1, VMASK,
+ ptr[AO1
+ + (unroll_m * (i + 1) + 1 * 8
+ - OFFSET)
+ * SIZE]);
+ }
+ }
+ }
+ }
+
+ if (!isDirect) {
+ sub(AO1, -unroll_m * 4 * SIZE);
+ }
+
+ };
+
+ // Inner kernel with k=2
+ auto innerkernel2 = [&](int unroll_m, int unroll_n,
+ bool isLoad1Unmasked, bool isLoad2Unmasked, bool isDirect,
+ bool isCopy, bool useFma, Ymm reg00, Ymm reg01, Ymm reg02,
+ Ymm reg03, Ymm reg04, Ymm reg05, Ymm reg06, Ymm reg07,
+ Ymm reg08, Ymm reg09, Ymm reg10, Ymm reg11, Ymm reg12,
+ Ymm reg13, Ymm reg14, Ymm reg15, Ymm reg16, Ymm reg17,
+ Ymm reg18, Ymm reg19, Ymm reg20, Ymm reg21, Ymm reg22,
+ Ymm reg23) {
+
+ Ymm fmareg;
+
+ for (int i = 0; i < 2; i++) {
+ if (isDirect) {
+ if (isLoad1Unmasked) {
+ vmovups(ymm0, ptr[AO1 + (0 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm0, VMASK,
+ ptr[AO1 + (0 * 8 - OFFSET) * SIZE]);
+ }
+ if (unroll_m >= 16) {
+ if (isLoad2Unmasked) {
+ vmovups(ymm1, ptr[AO1 + (1 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm1, VMASK,
+ ptr[AO1 + (1 * 8 - OFFSET) * SIZE]);
+ }
+ }
+ add(AO1, LDA);
+ }
+
+ if (!isTransB) {
+ vbroadcastss(ymm2, ptr[BO1 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (0 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg00 : reg12;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg06 : reg18;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ if (unroll_n >= 2) {
+ if (!isTransB) {
+ vbroadcastss(
+ ymm2, ptr[BO1 + LDB * 1 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (1 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg01 : reg13;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg07 : reg19;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (unroll_n >= 3) {
+ if (!isTransB) {
+ if (i == 2) {
+ prefetcht0(
+ ptr[BO1 + LDB * 2 + PREFETCHSIZEB * SIZE]);
+ }
+ vbroadcastss(
+ ymm2, ptr[BO1 + LDB * 2 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (2 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg02 : reg14;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg08 : reg20;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (unroll_n >= 4) {
+ if (!isTransB) {
+ vbroadcastss(ymm2, ptr[BO2 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (3 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg03 : reg15;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg09 : reg21;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (unroll_n >= 5) {
+ if (!isTransB) {
+ vbroadcastss(
+ ymm2, ptr[BO2 + LDB * 1 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (4 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg04 : reg16;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg10 : reg22;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (unroll_n >= 6) {
+ if (!isTransB) {
+ vbroadcastss(
+ ymm2, ptr[BO2 + LDB * 2 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (5 - OFFSET) * SIZE]);
+ }
+ fmareg = (i % 2 == 0) ? reg05 : reg17;
+ fma(useFma, ymm0, ymm2, fmareg);
+ if (unroll_m >= 16) {
+ fmareg = (i % 2 == 0) ? reg11 : reg23;
+ fma(useFma, ymm1, ymm2, fmareg);
+ }
+ }
+
+ if (isCopy) {
+ vmovups(ptr[LDA4 + (unroll_m * 0 + 0 * 8 - OFFSET) * SIZE],
+ ymm0);
+ if (unroll_m >= 16) {
+ vmovups(ptr[LDA4
+ + (unroll_m * 0 + 1 * 8 - OFFSET)
+ * SIZE],
+ ymm1);
+ }
+ sub(LDA4, -unroll_m * SIZE);
+ }
+
+ if (!isDirect) {
+ if (isLoad1Unmasked) {
+ vmovups(ymm0, ptr[AO1
+ + (unroll_m * 1 + 0 * 8 - OFFSET)
+ * SIZE]);
+ } else {
+ vmaskmovps(ymm0, VMASK,
+ ptr[AO1
+ + (unroll_m * 1 + 0 * 8 - OFFSET)
+ * SIZE]);
+ }
+ if (unroll_m >= 16) {
+ if (isLoad2Unmasked) {
+ vmovups(ymm1,
+ ptr[AO1
+ + (unroll_m * 1 + 1 * 8 - OFFSET)
+ * SIZE]);
+ } else {
+ vmaskmovps(ymm1, VMASK,
+ ptr[AO1
+ + (unroll_m * 1 + 1 * 8 - OFFSET)
+ * SIZE]);
+ }
+ }
+ sub(AO1, -unroll_m * SIZE);
+ }
+
+ if (!isTransB) {
+ sub(BO1, -SIZE);
+ if (unroll_n >= 4) {
+ sub(BO2, -SIZE);
+ }
+ } else {
+ add(BO1, LDB);
+ }
+ }
+
+ };
+
+ // Inner kernel with k=1
+ auto innerkernel1 = [&](int unroll_m, int unroll_n,
+ bool isLoad1Unmasked, bool isLoad2Unmasked, bool isDirect,
+ bool isCopy, bool useFma, Ymm reg00, Ymm reg01, Ymm reg02,
+ Ymm reg03, Ymm reg04, Ymm reg05, Ymm reg06, Ymm reg07,
+ Ymm reg08, Ymm reg09, Ymm reg10, Ymm reg11) {
+
+ if (isDirect) {
+ if (isLoad1Unmasked) {
+ vmovups(ymm0, ptr[AO1 + (0 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm0, VMASK, ptr[AO1 + (0 * 8 - OFFSET) * SIZE]);
+ }
+ if (unroll_m >= 16) {
+ if (isLoad2Unmasked) {
+ vmovups(ymm1, ptr[AO1 + (1 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm1, VMASK,
+ ptr[AO1 + (1 * 8 - OFFSET) * SIZE]);
+ }
+ }
+ add(AO1, LDA);
+ }
+
+ if (!isTransB) {
+ vbroadcastss(ymm2, ptr[BO1 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (0 - OFFSET) * SIZE]);
+ }
+ fma(useFma, ymm0, ymm2, reg00);
+ if (unroll_m >= 16) {
+ fma(useFma, ymm1, ymm2, reg06);
+ }
+
+ if (unroll_n >= 2) {
+ if (!isTransB) {
+ vbroadcastss(
+ ymm2, ptr[BO1 + LDB * 1 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (1 - OFFSET) * SIZE]);
+ }
+ fma(useFma, ymm0, ymm2, reg01);
+ if (unroll_m >= 16) {
+ fma(useFma, ymm1, ymm2, reg07);
+ }
+ }
+
+ if (unroll_n >= 3) {
+ if (!isTransB) {
+ vbroadcastss(
+ ymm2, ptr[BO1 + LDB * 2 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (2 - OFFSET) * SIZE]);
+ }
+ fma(useFma, ymm0, ymm2, reg02);
+ if (unroll_m >= 16) {
+ fma(useFma, ymm1, ymm2, reg08);
+ }
+ }
+
+ if (unroll_n >= 4) {
+ if (!isTransB) {
+ vbroadcastss(ymm2, ptr[BO2 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (3 - OFFSET) * SIZE]);
+ }
+ fma(useFma, ymm0, ymm2, reg03);
+ if (unroll_m >= 16) {
+ fma(useFma, ymm1, ymm2, reg09);
+ }
+ }
+
+ if (unroll_n >= 5) {
+ if (!isTransB) {
+ vbroadcastss(
+ ymm2, ptr[BO2 + LDB * 1 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (4 - OFFSET) * SIZE]);
+ }
+ fma(useFma, ymm0, ymm2, reg04);
+ if (unroll_m >= 16) {
+ fma(useFma, ymm1, ymm2, reg10);
+ }
+ }
+
+ if (unroll_n >= 6) {
+ if (!isTransB) {
+ vbroadcastss(
+ ymm2, ptr[BO2 + LDB * 2 + (0 - OFFSET) * SIZE]);
+ } else {
+ vbroadcastss(ymm2, ptr[BO1 + (5 - OFFSET) * SIZE]);
+ }
+ fma(useFma, ymm0, ymm2, reg05);
+ if (unroll_m >= 16) {
+ fma(useFma, ymm1, ymm2, reg11);
+ }
+ }
+
+ if (isCopy) {
+ vmovups(ptr[LDA4 + (unroll_m * 0 + 0 * 8 - OFFSET) * SIZE],
+ ymm0);
+ if (unroll_m >= 16) {
+ vmovups(ptr[LDA4 + (unroll_m * 0 + 1 * 8 - OFFSET) * SIZE],
+ ymm1);
+ }
+ sub(LDA4, -unroll_m * SIZE);
+ }
+
+ if (!isDirect) {
+ if (isLoad1Unmasked) {
+ vmovups(ymm0,
+ ptr[AO1 + (unroll_m * 1 + 0 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm0, VMASK,
+ ptr[AO1 + (unroll_m * 1 + 0 * 8 - OFFSET) * SIZE]);
+ }
+ if (unroll_m >= 16) {
+ if (isLoad2Unmasked) {
+ vmovups(ymm1, ptr[AO1
+ + (unroll_m * 1 + 1 * 8 - OFFSET)
+ * SIZE]);
+ } else {
+ vmaskmovps(ymm1, VMASK,
+ ptr[AO1
+ + (unroll_m * 1 + 1 * 8 - OFFSET)
+ * SIZE]);
+ }
+ }
+ sub(AO1, -unroll_m * SIZE);
+ }
+
+ if (!isTransB) {
+ sub(BO1, -SIZE);
+ if (unroll_n >= 4) {
+ sub(BO2, -SIZE);
+ }
+ } else {
+ add(BO1, LDB);
+ }
+
+ };
+
+ // Main kernel; does prefetching and calls innerkernel{1,2,4,8} as
+ // appropriate
+ // After calculating results in registers, writes back to C matrix
+ auto kernel = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy, bool useFma,
+ Ymm reg00 = Ymm(4), Ymm reg01 = Ymm(5), Ymm reg02 = Ymm(6),
+ Ymm reg03 = Ymm(7), Ymm reg04 = Ymm(8), Ymm reg05 = Ymm(9),
+ Ymm reg06 = Ymm(10), Ymm reg07 = Ymm(11), Ymm reg08 = Ymm(12),
+ Ymm reg09 = Ymm(13), Ymm reg10 = Ymm(14), Ymm reg11 = Ymm(15),
+ Ymm reg12 = Ymm(4), Ymm reg13 = Ymm(5), Ymm reg14 = Ymm(6),
+ Ymm reg15 = Ymm(7), Ymm reg16 = Ymm(8), Ymm reg17 = Ymm(9),
+ Ymm reg18 = Ymm(10), Ymm reg19 = Ymm(11), Ymm reg20 = Ymm(12),
+ Ymm reg21 = Ymm(13), Ymm reg22 = Ymm(14), Ymm reg23 = Ymm(15)) {
+ if (!isDirect) {
+ lea(AO1, ptr[rsp + 256 + OFFSET * SIZE]);
+ } else {
+ mov(AO1, A);
+ }
+
+ if (isCopy) {
+ lea(LDA4, ptr[rsp + 256 + OFFSET * SIZE]);
+ } else {
+ lea(LDA4, ptr[LDA * 8 + (8 - 1 - OFFSET) * SIZE]);
+ }
+
+ if (isTransB) {
+ lea(BO2, ptr[LDB * 4 + (8 - 1 - OFFSET) * SIZE]);
+ lea(BO2, ptr[BO2 + LDB * 2]);
+ }
+
+ if (!isDirect) {
+ if (isLoad1Unmasked) {
+ vmovups(ymm0,
+ ptr[AO1 + (unroll_m * 0 + 0 * 8 - OFFSET) * SIZE]);
+ } else {
+ vmaskmovps(ymm0, VMASK,
+ ptr[AO1 + (unroll_m * 0 + 0 * 8 - OFFSET) * SIZE]);
+ }
+ if (unroll_m >= 16) {
+ if (isLoad2Unmasked) {
+ vmovups(ymm1, ptr[AO1
+ + (unroll_m * 0 + 1 * 8 - OFFSET)
+ * SIZE]);
+ } else {
+ vmaskmovps(ymm1, VMASK,
+ ptr[AO1
+ + (unroll_m * 0 + 1 * 8 - OFFSET)
+ * SIZE]);
+ }
+ }
+ }
+
+ for (int i = 4; i < 10; i++) {
+ vxorps(Ymm(i), Ymm(i), Ymm(i));
+ vxorps(Ymm(i + 6), Ymm(i + 6), Ymm(i + 6));
+ }
+
+ mov(LL, K);
+ sar(LL, 3);
+
+ Label kernel12, kernel13, kernel14, kernel15;
+ Label kernel16, kernel17, kernel18;
+
+ sub(LL, SECOND_FETCH);
+ jle(kernel13, T_NEAR);
+ align(16);
+
+ L(kernel12);
+ innerkernel8(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, useFma, reg00, reg01, reg02, reg03, reg04,
+ reg05, reg06, reg07, reg08, reg09, reg10, reg11, reg12,
+ reg13, reg14, reg15, reg16, reg17, reg18, reg19, reg20,
+ reg21, reg22, reg23);
+ jg(kernel12, T_NEAR);
+ align(16);
+
+ L(kernel13);
+ prefetcht0(ptr[CO1 + (unroll_m - 1) * SIZE]);
+ if (unroll_n >= 2)
+ prefetcht0(ptr[CO1 + LDC + (unroll_m - 1) * SIZE]);
+ if (unroll_n >= 3)
+ prefetcht0(ptr[CO1 + LDC * 2 + (unroll_m - 1) * SIZE]);
+ if (unroll_n >= 4)
+ prefetcht0(ptr[CO2 + (unroll_m - 1) * SIZE]);
+ if (unroll_n >= 5)
+ prefetcht0(ptr[CO2 + LDC + (unroll_m - 1) * SIZE]);
+ if (unroll_n >= 6)
+ prefetcht0(ptr[CO2 + LDC * 2 + (unroll_m - 1) * SIZE]);
+
+ add(LL, SECOND_FETCH);
+ jle(kernel15, T_NEAR);
+ align(16);
+
+ L(kernel14);
+ innerkernel8(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, useFma, reg00, reg01, reg02, reg03, reg04,
+ reg05, reg06, reg07, reg08, reg09, reg10, reg11, reg12,
+ reg13, reg14, reg15, reg16, reg17, reg18, reg19, reg20,
+ reg21, reg22, reg23);
+ jg(kernel14, T_NEAR);
+ align(16);
+
+ L(kernel15);
+ test(K, 4);
+ jle(kernel16, T_NEAR);
+ innerkernel4(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, useFma, reg00, reg01, reg02, reg03, reg04,
+ reg05, reg06, reg07, reg08, reg09, reg10, reg11, reg12,
+ reg13, reg14, reg15, reg16, reg17, reg18, reg19, reg20,
+ reg21, reg22, reg23);
+
+ L(kernel16);
+ test(K, 2);
+ jle(kernel17, T_NEAR);
+ innerkernel2(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, useFma, reg00, reg01, reg02, reg03, reg04,
+ reg05, reg06, reg07, reg08, reg09, reg10, reg11, reg12,
+ reg13, reg14, reg15, reg16, reg17, reg18, reg19, reg20,
+ reg21, reg22, reg23);
+ align(16);
+
+ L(kernel17);
+ if (unroll_m == 16) {
+ if (unroll_n <= 3) {
+ vaddps(reg00, reg00, reg12);
+ vaddps(reg01, reg01, reg13);
+ vaddps(reg02, reg02, reg14);
+ vaddps(reg06, reg06, reg18);
+ vaddps(reg07, reg07, reg19);
+ vaddps(reg08, reg08, reg20);
+ }
+ }
+
+ if (unroll_m <= 8) {
+ vaddps(reg00, reg00, reg12);
+ vaddps(reg01, reg01, reg13);
+ vaddps(reg02, reg02, reg14);
+ vaddps(reg03, reg03, reg15);
+ vaddps(reg04, reg04, reg16);
+ vaddps(reg05, reg05, reg17);
+ }
+
+ test(K, 1);
+ jle(kernel18, T_NEAR);
+ innerkernel1(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, useFma, reg00, reg01, reg02, reg03, reg04,
+ reg05, reg06, reg07, reg08, reg09, reg10, reg11);
+ align(16);
+
+ L(kernel18);
+ vbroadcastss(VALPHA, ALPHA);
+
+ if (isBetaN) {
+ vbroadcastss(VBETA, BETA);
+ }
+
+ // Write back the results; all beta and bias cases need to be
+ // handled
+ switch (unroll_n) {
+ case 1: mov(rax, LDC); break;
+ case 2: lea(rax, ptr[LDC * 2]); break;
+ case 3: lea(rax, ptr[LDC + LDC * 2]); break;
+ case 4: lea(rax, ptr[LDC + LDC * 4]); break;
+ case 5:
+ lea(rax, ptr[LDC * 4]);
+ add(rax, LDC);
+ break;
+ case 6:
+ lea(rax, ptr[LDC + LDC * 2]);
+ add(rax, rax);
+ break;
+ }
+
+ if (hasBias) {
+ mov(BIAS1, BIAS);
+ if (isLoad1Unmasked) {
+ vmovups(VBIAS1, ptr[BIAS1 + 0 * SIZE]);
+ } else {
+ vmaskmovps(VBIAS1, VMASK, ptr[BIAS1 + 0 * SIZE]);
+ }
+ }
+
+ for (int i = 0; i < unroll_n; i++) {
+ vmulps(Ymm(i + 4), Ymm(i + 4), VALPHA);
+ if (!isBeta0) {
+ if (isLoad1Unmasked) {
+ switch (i) {
+ case 0: vmovups(ymm0, ptr[CO1 + 0 * SIZE]); break;
+ case 1: vmovups(ymm0, ptr[CO1 + LDC + 0 * SIZE]); break;
+ case 2:
+ vmovups(ymm0, ptr[CO1 + LDC * 2 + 0 * SIZE]);
+ break;
+ case 3: vmovups(ymm0, ptr[CO2 + 0 * SIZE]); break;
+ case 4: vmovups(ymm0, ptr[CO2 + LDC + 0 * SIZE]); break;
+ case 5:
+ vmovups(ymm0, ptr[CO2 + LDC * 2 + 0 * SIZE]);
+ break;
+ }
+ } else {
+ switch (i) {
+ case 0:
+ vmaskmovps(ymm0, VMASK, ptr[CO1 + 0 * SIZE]);
+ break;
+ case 1:
+ vmaskmovps(ymm0, VMASK, ptr[CO1 + LDC + 0 * SIZE]);
+ break;
+ case 2:
+ vmaskmovps(
+ ymm0, VMASK, ptr[CO1 + LDC * 2 + 0 * SIZE]);
+ break;
+ case 3:
+ vmaskmovps(ymm0, VMASK, ptr[CO2 + 0 * SIZE]);
+ break;
+ case 4:
+ vmaskmovps(ymm0, VMASK, ptr[CO2 + LDC + 0 * SIZE]);
+ break;
+ case 5:
+ vmaskmovps(
+ ymm0, VMASK, ptr[CO2 + LDC * 2 + 0 * SIZE]);
+ break;
+ }
+ }
+
+ if (!isBetaN) {
+ vaddps(Ymm(i + 4), ymm0, Ymm(i + 4));
+ } else {
+ fma(useFma, VBETA, ymm0, Ymm(i + 4), true);
+ }
+ }
+ if (hasBias) {
+ vaddps(Ymm(i + 4), VBIAS1, Ymm(i + 4));
+ }
+ if (isLoad1Unmasked) {
+ switch (i) {
+ case 0: vmovups(ptr[CO1 + 0 * SIZE], Ymm(i + 4)); break;
+ case 1:
+ vmovups(ptr[CO1 + LDC + 0 * SIZE], Ymm(i + 4));
+ break;
+ case 2:
+ vmovups(ptr[CO1 + LDC * 2 + 0 * SIZE], Ymm(i + 4));
+ break;
+ case 3: vmovups(ptr[CO2 + 0 * SIZE], Ymm(i + 4)); break;
+ case 4:
+ vmovups(ptr[CO2 + LDC + 0 * SIZE], Ymm(i + 4));
+ break;
+ case 5:
+ vmovups(ptr[CO2 + LDC * 2 + 0 * SIZE], Ymm(i + 4));
+ break;
+ }
+ } else {
+ switch (i) {
+ case 0:
+ vmaskmovps(ptr[CO1 + 0 * SIZE], VMASK, Ymm(i + 4));
+ break;
+ case 1:
+ vmaskmovps(
+ ptr[CO1 + LDC + 0 * SIZE], VMASK, Ymm(i + 4));
+ break;
+ case 2:
+ vmaskmovps(ptr[CO1 + LDC * 2 + 0 * SIZE], VMASK,
+ Ymm(i + 4));
+ break;
+ case 3:
+ vmaskmovps(ptr[CO2 + 0 * SIZE], VMASK, Ymm(i + 4));
+ break;
+ case 4:
+ vmaskmovps(
+ ptr[CO2 + LDC + 0 * SIZE], VMASK, Ymm(i + 4));
+ break;
+ case 5:
+ vmaskmovps(ptr[CO2 + LDC * 2 + 0 * SIZE], VMASK,
+ Ymm(i + 4));
+ break;
+ }
+ }
+
+ if (unroll_m >= 16) {
+ // Re-use ymm4 (VBIAS2)
+ if (i == 0) {
+ if (hasBias) {
+ if (isLoad1Unmasked) {
+ vmovups(VBIAS2, ptr[BIAS1 + 8 * SIZE]);
+ } else {
+ vmaskmovps(
+ VBIAS2, VMASK, ptr[BIAS1 + 8 * SIZE]);
+ }
+ }
+ }
+ vmulps(Ymm(i + 10), Ymm(i + 10), VALPHA);
+ if (!isBeta0) {
+ if (isLoad2Unmasked) {
+ switch (i) {
+ case 0: vmovups(ymm0, ptr[CO1 + 8 * SIZE]); break;
+ case 1:
+ vmovups(ymm0, ptr[CO1 + LDC + 8 * SIZE]);
+ break;
+ case 2:
+ vmovups(ymm0, ptr[CO1 + LDC * 2 + 8 * SIZE]);
+ break;
+ case 3: vmovups(ymm0, ptr[CO2 + 8 * SIZE]); break;
+ case 4:
+ vmovups(ymm0, ptr[CO2 + LDC + 8 * SIZE]);
+ break;
+ case 5:
+ vmovups(ymm0, ptr[CO2 + LDC * 2 + 8 * SIZE]);
+ break;
+ }
+ } else {
+ switch (i) {
+ case 0:
+ vmaskmovps(ymm0, VMASK, ptr[CO1 + 8 * SIZE]);
+ break;
+ case 1:
+ vmaskmovps(
+ ymm0, VMASK, ptr[CO1 + LDC + 8 * SIZE]);
+ break;
+ case 2:
+ vmaskmovps(ymm0, VMASK,
+ ptr[CO1 + LDC * 2 + 8 * SIZE]);
+ break;
+ case 3:
+ vmaskmovps(ymm0, VMASK, ptr[CO2 + 8 * SIZE]);
+ break;
+ case 4:
+ vmaskmovps(
+ ymm0, VMASK, ptr[CO2 + LDC + 8 * SIZE]);
+ break;
+ case 5:
+ vmaskmovps(ymm0, VMASK,
+ ptr[CO2 + LDC * 2 + 8 * SIZE]);
+ break;
+ }
+ }
+ if (!isBetaN) {
+ vaddps(Ymm(i + 10), ymm0, Ymm(i + 10));
+ } else {
+ fma(useFma, VBETA, ymm0, Ymm(i + 10), true);
+ }
+ }
+ if (hasBias) {
+ vaddps(Ymm(i + 10), VBIAS2, Ymm(i + 10));
+ }
+ if (isLoad2Unmasked) {
+ switch (i) {
+ case 0:
+ vmovups(ptr[CO1 + 8 * SIZE], Ymm(i + 10));
+ break;
+ case 1:
+ vmovups(ptr[CO1 + LDC + 8 * SIZE], Ymm(i + 10));
+ break;
+ case 2:
+ vmovups(ptr[CO1 + LDC * 2 + 8 * SIZE], Ymm(i + 10));
+ break;
+ case 3:
+ vmovups(ptr[CO2 + 8 * SIZE], Ymm(i + 10));
+ break;
+ case 4:
+ vmovups(ptr[CO2 + LDC + 8 * SIZE], Ymm(i + 10));
+ break;
+ case 5:
+ vmovups(ptr[CO2 + LDC * 2 + 8 * SIZE], Ymm(i + 10));
+ break;
+ }
+ } else {
+ switch (i) {
+ case 0:
+ vmaskmovps(ptr[CO1 + 8 * SIZE], VMASK, Ymm(i + 10));
+ break;
+ case 1:
+ vmaskmovps(ptr[CO1 + LDC + 8 * SIZE], VMASK,
+ Ymm(i + 10));
+ break;
+ case 2:
+ vmaskmovps(ptr[CO1 + LDC * 2 + 8 * SIZE], VMASK,
+ Ymm(i + 10));
+ break;
+ case 3:
+ vmaskmovps(ptr[CO2 + 8 * SIZE], VMASK, Ymm(i + 10));
+ break;
+ case 4:
+ vmaskmovps(ptr[CO2 + LDC + 8 * SIZE], VMASK,
+ Ymm(i + 10));
+ break;
+ case 5:
+ vmaskmovps(ptr[CO2 + LDC * 2 + 8 * SIZE], VMASK,
+ Ymm(i + 10));
+ break;
+ }
+ }
+ }
+ if (i == 2)
+ add(CO1, rax);
+ }
+ if (unroll_n >= 4) {
+ add(CO2, rax);
+ }
+
+ // Compute next address of B
+ if (!isTransB) {
+ lea(rax, ptr[K * SIZE]);
+ switch (unroll_n) {
+ case 1:
+ add(BO1, LDB);
+ add(BO2, LDB);
+ break;
+ case 2:
+ lea(BO1, ptr[BO1 + LDB * 2]);
+ lea(BO2, ptr[BO2 + LDB * 2]);
+ break;
+ case 3:
+ lea(BO1, ptr[BO1 + LDB3]);
+ lea(BO2, ptr[BO2 + LDB3]);
+ break;
+ case 4:
+ lea(BO1, ptr[BO1 + LDB * 4]);
+ lea(BO2, ptr[BO2 + LDB * 4]);
+ break;
+ case 5:
+ lea(BO1, ptr[BO1 + LDB * 4]);
+ add(BO1, LDB);
+ lea(BO2, ptr[BO2 + LDB * 4]);
+ add(BO2, LDB);
+ break;
+ case 6:
+ lea(BO1, ptr[BO1 + LDB3 * 2]);
+ lea(BO2, ptr[BO2 + LDB3 * 2]);
+ break;
+ }
+ sub(BO1, rax);
+ sub(BO2, rax);
+ } else {
+ mov(rax, LDB);
+ imul(rax, K);
+ sub(BO1, rax);
+ add(BO1, unroll_n * SIZE);
+ }
+ };
+
+ auto kernel_16x6 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy) {
+ kernel(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, true);
+ };
+
+ auto kernel_16x5 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy) {
+ kernel(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, true);
+ };
+
+ auto kernel_16x4 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy) {
+ kernel(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, true);
+ };
+
+ auto kernel_16x3 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy,
+ bool useFma = true) {
+ kernel(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, useFma, Ymm(4), Ymm(5), Ymm(6), Ymm(7),
+ Ymm(8), Ymm(9), Ymm(10), Ymm(11), Ymm(12), Ymm(13), Ymm(14),
+ Ymm(15), Ymm(7), Ymm(8), Ymm(9), Ymm(7), Ymm(8), Ymm(9),
+ Ymm(13), Ymm(14), Ymm(15));
+ };
+
+ auto kernel_16x2 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy) {
+ kernel_16x3(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, false);
+ };
+
+ auto kernel_16x1 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy) {
+ kernel_16x3(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, false);
+ };
+
+ auto kernel_8x6 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy,
+ bool useFma = true) {
+ kernel(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, useFma, Ymm(4), Ymm(5), Ymm(6), Ymm(7),
+ Ymm(8), Ymm(9), Ymm(10), Ymm(11), Ymm(12), Ymm(13), Ymm(14),
+ Ymm(15), Ymm(10), Ymm(11), Ymm(12), Ymm(13), Ymm(14),
+ Ymm(15));
+ };
+
+ auto kernel_8x5 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy) {
+ kernel_8x6(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy);
+ };
+
+ auto kernel_8x4 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy) {
+ kernel_8x6(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy);
+ };
+
+ auto kernel_8x3 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy,
+ bool useFma = true) {
+ kernel(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, useFma, Ymm(4), Ymm(5), Ymm(6), Ymm(7),
+ Ymm(8), Ymm(9), Ymm(10), Ymm(11), Ymm(12), Ymm(13), Ymm(14),
+ Ymm(15), Ymm(7), Ymm(8), Ymm(9), Ymm(7), Ymm(8), Ymm(9),
+ Ymm(13), Ymm(14), Ymm(15));
+ };
+
+ auto kernel_8x2 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy) {
+ kernel_8x3(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, false);
+ };
+
+ auto kernel_8x1 = [&](int unroll_m, int unroll_n, bool isLoad1Unmasked,
+ bool isLoad2Unmasked, bool isDirect, bool isCopy) {
+ kernel_8x3(unroll_m, unroll_n, isLoad1Unmasked, isLoad2Unmasked,
+ isDirect, isCopy, false);
+ };
+
+ // High-level subroutine; does packing if needed, then splits C matrix.
+ // Operates on chunks of 16 rows, 6 columns at a time (handling tail
+ // cases appropriately).
+ // Masking is used for tail cases where M is not divisible by 8.
+ auto subloop = [&](
+ int unroll_m, bool isLoad1Unmasked, bool isLoad2Unmasked) {
+ if (isTransA) {
+ do_pack(unroll_m, isLoad1Unmasked, isLoad2Unmasked);
+ }
+
+ Label subloop11, subloop11mask;
+ Label subloop20, subloop21, subloop22, subloop23;
+ Label subloop24, subloop25;
+ Label subloop30, subloop31, subloop32, subloop33;
+ Label subloop34, subloop35;
+ Label subloop98, subloop98mask;
+ Label subloop99, subloop99mask;
+
+ mov(CO1, C);
+ lea(CO2, ptr[CO1 + LDC * 2]);
+ add(CO2, LDC);
+ add(C, unroll_m * SIZE);
+ mov(BO1, B);
+ if (!isTransB) {
+ lea(BO2, qword[B + LDB3]);
+ }
+
+ if (!isTransA) {
+ lea(AA, ptr[A + (unroll_m * 2 - 1 - OFFSET) * SIZE]);
+ cmp(M, UNROLL_M);
+ jg(subloop98, T_NEAR);
+
+ mov(AA, ORIG_A);
+ lea(AA, ptr[AA + (unroll_m - 1 - OFFSET) * SIZE]);
+ L(subloop98);
+ }
+
+ mov(LL, N);
+ mov(I, LL);
+ if (!isTransA) {
+ // If N is too small, skip copy operation
+ cmp(LL, UNROLL_N * 3);
+ jle(subloop30, T_NEAR);
+
+ // If A is not aligned to cache line
+ cmp(FLAG, 0);
+ je(subloop30, T_NEAR);
+ } else {
+ cmp(LL, UNROLL_N);
+ jl(subloop20, T_NEAR);
+ }
+ align(16);
+
+ if (!isTransA) {
+ if (unroll_m == 16) {
+ kernel_16x6(unroll_m, UNROLL_N, isLoad1Unmasked,
+ isLoad2Unmasked, true, true);
+ } else {
+ kernel_8x6(unroll_m, UNROLL_N, isLoad1Unmasked,
+ isLoad2Unmasked, true, true);
+ }
+ } else {
+ if (unroll_m == 16) {
+ kernel_16x6(unroll_m, UNROLL_N, isLoad1Unmasked,
+ isLoad2Unmasked, false, false);
+ } else {
+ kernel_8x6(unroll_m, UNROLL_N, isLoad1Unmasked,
+ isLoad2Unmasked, false, false);
+ }
+ }
+
+ sub(I, UNROLL_N);
+ cmp(I, UNROLL_N);
+ jl(subloop20, T_NEAR);
+ align(16);
+
+ L(subloop11);
+ if (unroll_m == 16) {
+ kernel_16x6(unroll_m, UNROLL_N, isLoad1Unmasked,
+ isLoad2Unmasked, false, false);
+ } else {
+ kernel_8x6(unroll_m, UNROLL_N, isLoad1Unmasked, isLoad2Unmasked,
+ false, false);
+ }
+ sub(I, UNROLL_N);
+ cmp(I, UNROLL_N);
+ jge(subloop11, T_NEAR);
+ align(16);
+
+ L(subloop20);
+ cmp(I, 1);
+ jne(subloop21, T_NEAR);
+ if (unroll_m == 16) {
+ kernel_16x1(unroll_m, 1, isLoad1Unmasked, isLoad2Unmasked,
+ false, false);
+ } else {
+ kernel_8x1(unroll_m, 1, isLoad1Unmasked, isLoad2Unmasked, false,
+ false);
+ }
+ jmp(subloop99, T_NEAR);
+ align(16);
+
+ L(subloop21);
+ cmp(I, 2);
+ jne(subloop22, T_NEAR);
+ if (unroll_m == 16) {
+ kernel_16x2(unroll_m, 2, isLoad1Unmasked, isLoad2Unmasked,
+ false, false);
+ } else {
+ kernel_8x2(unroll_m, 2, isLoad1Unmasked, isLoad2Unmasked, false,
+ false);
+ }
+ jmp(subloop99, T_NEAR);
+ align(16);
+
+ L(subloop22);
+ cmp(I, 3);
+ jne(subloop23, T_NEAR);
+ if (unroll_m == 16) {
+ kernel_16x3(unroll_m, 3, isLoad1Unmasked, isLoad2Unmasked,
+ false, false);
+ } else {
+ kernel_8x3(unroll_m, 3, isLoad1Unmasked, isLoad2Unmasked, false,
+ false);
+ }
+ jmp(subloop99, T_NEAR);
+ align(16);
+
+ L(subloop23);
+ cmp(I, 4);
+ jne(subloop24, T_NEAR);
+ if (unroll_m == 16) {
+ kernel_16x4(unroll_m, 4, isLoad1Unmasked, isLoad2Unmasked,
+ false, false);
+ } else {
+ kernel_8x4(unroll_m, 4, isLoad1Unmasked, isLoad2Unmasked, false,
+ false);
+ }
+ jmp(subloop99, T_NEAR);
+ align(16);
+
+ L(subloop24);
+ cmp(I, 5);
+ jne(subloop99, T_NEAR);
+ if (unroll_m == 16) {
+ kernel_16x5(unroll_m, 5, isLoad1Unmasked, isLoad2Unmasked,
+ false, false);
+ } else {
+ kernel_8x5(unroll_m, 5, isLoad1Unmasked, isLoad2Unmasked, false,
+ false);
+ }
+ jmp(subloop99, T_NEAR);
+ align(16);
+
+ if (!isTransA) {
+ L(subloop30);
+ cmp(I, UNROLL_N);
+ jl(subloop25, T_NEAR);
+ align(16);
+
+ L(subloop31);
+ if (unroll_m == 16) {
+ kernel_16x6(unroll_m, UNROLL_N, isLoad1Unmasked,
+ isLoad2Unmasked, true, false);
+ } else {
+ kernel_8x6(unroll_m, UNROLL_N, isLoad1Unmasked,
+ isLoad2Unmasked, true, false);
+ }
+ sub(I, UNROLL_N);
+ cmp(I, UNROLL_N);
+ jge(subloop31, T_NEAR);
+ align(16);
+
+ L(subloop25);
+ cmp(I, 1);
+ jne(subloop32, T_NEAR);
+ if (unroll_m == 16) {
+ kernel_16x1(unroll_m, 1, isLoad1Unmasked, isLoad2Unmasked,
+ true, false);
+ } else {
+ kernel_8x1(unroll_m, 1, isLoad1Unmasked, isLoad2Unmasked,
+ true, false);
+ }
+ jmp(subloop99, T_NEAR);
+ align(16);
+
+ L(subloop32);
+ cmp(I, 2);
+ jne(subloop33, T_NEAR);
+ if (unroll_m == 16) {
+ kernel_16x2(unroll_m, 2, isLoad1Unmasked, isLoad2Unmasked,
+ true, false);
+ } else {
+ kernel_8x2(unroll_m, 2, isLoad1Unmasked, isLoad2Unmasked,
+ true, false);
+ }
+ jmp(subloop99, T_NEAR);
+ align(16);
+
+ L(subloop33);
+ cmp(I, 3);
+ jne(subloop34, T_NEAR);
+ if (unroll_m == 16) {
+ kernel_16x3(unroll_m, 3, isLoad1Unmasked, isLoad2Unmasked,
+ true, false);
+ } else {
+ kernel_8x3(unroll_m, 3, isLoad1Unmasked, isLoad2Unmasked,
+ true, false);
+ }
+ jmp(subloop99, T_NEAR);
+ align(16);
+
+ L(subloop34);
+ cmp(I, 4);
+ jne(subloop35, T_NEAR);
+ if (unroll_m == 16) {
+ kernel_16x4(unroll_m, 4, isLoad1Unmasked, isLoad2Unmasked,
+ true, false);
+ } else {
+ kernel_8x4(unroll_m, 4, isLoad1Unmasked, isLoad2Unmasked,
+ true, false);
+ }
+ jmp(subloop99, T_NEAR);
+ align(16);
+
+ L(subloop35);
+ cmp(I, 5);
+ jne(subloop99, T_NEAR);
+ if (unroll_m == 16) {
+ kernel_16x5(unroll_m, 5, isLoad1Unmasked, isLoad2Unmasked,
+ true, false);
+ } else {
+ kernel_8x5(unroll_m, 5, isLoad1Unmasked, isLoad2Unmasked,
+ true, false);
+ }
+ align(16);
+ }
+
+ L(subloop99);
+ // Compute address for A
+ if (!isTransA) {
+ add(A, unroll_m * SIZE);
+ } else {
+ mov(rax, LDA);
+ imul(rax, rax, unroll_m);
+ add(A, rax);
+ }
+
+ // Compute next address of BIAS
+ if (hasBias) {
+ add(BIAS, unroll_m * SIZE);
+ }
+ };
+
+ preamble();
+
+ Label buffer_in_ws, buffer_allocated;
+
+ // Get the registers
+ mov(B, ARG_B);
+ mov(LDB, ARG_LDB);
+ mov(r15, ARG_BETA);
+ mov(r12, ARG_C);
+ if (hasBias)
+ mov(r10, ARG_BIAS);
+ mov(LDC, ARG_LDC);
+ mov(rbp, rsp);
+
+ vmovss(xmm0, ptr[ARG_ALPHA]);
+ vmovss(xmm1, ptr[r15]);
+
+#if _WIN32
+ mov(A, ARG_A);
+ mov(LDA, ARG_LDA);
+#endif
+
+ cmp(K, STACK_K_CAPACITY);
+ jg(buffer_in_ws, T_NEAR);
+
+ // Create buffer and align to 4kB page
+ lea(rax, ptr[K * SIZE]);
+ sal(rax, 4);
+ add(rax, 256);
+ sub(rsp, rax);
+ and_(rsp, -PAGE_4K);
+ jmp(buffer_allocated, T_NEAR);
+
+ L(buffer_in_ws);
+ mov(rsp, ARG_WS);
+
+ L(buffer_allocated);
+
+ mov(ORIG_SP, rbp);
+ mov(M, ARG_M);
+ mov(N, ARG_N);
+ mov(C, r12);
+ if (hasBias)
+ mov(BIAS, r10);
+ vmovss(ALPHA, xmm0);
+ vmovss(BETA, xmm1);
+ sub(A, -OFFSET * SIZE);
+ sub(B, -OFFSET * SIZE);
+ mov(ORIG_A, A);
+ sal(LDA, BASE_SHIFT);
+ sal(LDB, BASE_SHIFT);
+ sal(LDC, BASE_SHIFT);
+ lea(LDB3, ptr[LDB + LDB * 2]);
+
+ for (int i = 0; i < 8; i++) {
+ mov(dword[rsp + 88 + i * 4], i);
+ }
+
+ if (isTransA && is_avx2) {
+ movq(xmm0, LDA);
+ vpbroadcastq(ymm1, xmm0);
+ vinsertf128(ymm0, ymm0, xmm0, 1);
+ vpermilpd(ymm0, ymm0, 5);
+ vpaddq(ymm1, ymm1, ymm1);
+ vperm2f128(ymm1, ymm1, ymm1, 8);
+ vpaddq(ymm0, ymm0, ymm1);
+ vmovups(STRIDE, ymm0);
+ }
+
+ // Check A alignment and leading dimension; take copy-based path as
+ // needed
+ mov(rax, LDA);
+ or_(rax, A);
+ and_(rax, 0x1f);
+ mov(FLAG, rax);
+
+ Label main0, main1, main2, main3, main999;
+
+ cmp(M, UNROLL_M);
+ jl(main0, T_NEAR);
+ align(16);
+
+ L(main1);
+ subloop(UNROLL_M, true, true);
+ sub(M, UNROLL_M);
+ cmp(M, UNROLL_M);
+ jge(main1, T_NEAR);
+ align(16);
+
+ L(main0);
+ cmp(M, 0);
+ jle(main999, T_NEAR);
+
+ if (UNROLL_M > 8) {
+ cmp(M, 8);
+ jle(main2, T_NEAR);
+
+ sub(M, 8);
+ vbroadcastss(VMASK, M);
+ vpcmpgtd(VMASK, VMASK, MASK);
+
+ subloop(16, true, false);
+ jmp(main999, T_NEAR);
+ align(16);
+
+ L(main2);
+ cmp(M, 8);
+ jne(main3, T_NEAR);
+ subloop(8, true, true);
+ jmp(main999, T_NEAR);
+ }
+
+ align(16);
+
+ L(main3);
+ vbroadcastss(VMASK, M);
+ if (is_avx2) {
+ vpcmpgtd(VMASK, VMASK, MASK);
+ } else {
+ auto xmask = Xmm(VMASK.getIdx());
+ auto xmm_tmp = xmm4;
+
+ vextractf128(xmm_tmp, VMASK, 1);
+ vpcmpgtd(xmask, xmask, MASK);
+ vpcmpgtd(xmm_tmp, xmm_tmp, dword[rsp + 88 + 4 * 4]); // MASK + 4
+ vinsertf128(VMASK, VMASK, xmm_tmp, 1);
+ }
+ subloop(8, false, false);
+ align(16);
+
+ L(main999);
+ // Restore original stack
+ mov(rsp, ORIG_SP);
+
+ vzeroupper();
+ postamble();
+
+ ker_ = this->getCode<ker_t>();
+ }
+
+ typedef void (*ker_t)(dim_t m, dim_t n, dim_t k,
+ const float *alpha, const float *a, dim_t lda,
+ const float *b, dim_t ldb, const float *beta, float *c,
+ dim_t ldc, const float *bias, float *ws);
+
+ void operator()(dim_t m, dim_t n, dim_t k,
+ const float *alpha, const float *a, dim_t lda,
+ const float *b, dim_t ldb, const float *beta, float *c,
+ dim_t ldc, const float *bias, float *ws) const
+ {
+ ker_(m, n, k, alpha, a, lda, b, ldb, beta, c, ldc, bias, ws);
+ }
+
+private:
+ ker_t ker_;
+};
+
+const xbyak_gemm *get_xbyak_gemm(
+ bool isTransA, bool isTransB, float beta, bool hasBias) {
+ auto beta_idx = [](float beta) {
+ return (beta == 0.0) ? 0 : (beta == 1.0 ? 1 : 2);
+ };
+
+ // Kernel table [isTransA][isTransB][hasBias][beta (0, 1, other)]
+ static xbyak_gemm *kernel_table[2][2][2][3];
+ static std::once_flag initialized;
+ std::call_once(initialized, [=]{
+ for (bool isTransA: {false, true})
+ for (bool isTransB: {false, true})
+ for (bool hasBias: {false, true})
+ for (float beta: {0.0f, 1.0f, 2.0f}) {
+ // nocopy sgemm with bias for beta != 0.0 is not supported
+ if (hasBias && beta != 0.0)
+ continue;
+ kernel_table[isTransA][isTransB][hasBias][beta_idx(beta)] =
+ new xbyak_gemm(isTransA, isTransB, beta, hasBias);
+ }
+ });
+
+ return kernel_table[isTransA][isTransB][hasBias][beta_idx(beta)];
+}
+
+void sgemm_nocopy_driver(const char *transa,
+ const char *transb, int m, int n, int k, const float *alpha,
+ const float *a, dim_t lda, const float *b, dim_t ldb, const float *beta,
+ float *c, dim_t ldc, const float *bias, float *ws)
+{
+ bool isTransA = (*transa == 'T' || *transa == 't');
+ bool isTransB = (*transb == 'T' || *transb == 't');
+
+ int Bm, sizeM, Bn, sizeN, Bk, sizeK;
+
+ int i, j;
+
+ if ((m <= 0) || (n <= 0))
+ return;
+
+ if ((k <= 0) || (alpha[0] == 0.)) {
+
+ if (beta[0] == 0.) {
+ for (j = 0; j < n; j++)
+ for (i = 0; i < m; i++)
+ c[i + j * ldc] = 0.0;
+ } else if (beta[0] != 1.) {
+ for (j = 0; j < n; j++)
+ for (i = 0; i < m; i++)
+ c[i + j * ldc] *= beta[0];
+ }
+
+ return;
+ }
+
+ assert(IMPLICATION(bias != nullptr, *beta == 0.0));
+
+ // XXX: this happens on every thread...
+ bool hasBias = (bias != nullptr);
+ auto ker_bn = get_xbyak_gemm(isTransA, isTransB, *beta, hasBias);
+ auto ker_b1 = get_xbyak_gemm(isTransA, isTransB, 1.0, false);
+ auto ker_b0 = get_xbyak_gemm(isTransA, isTransB, 0.0, false);
+ assert(ker_bn && ker_b1 && ker_b0);
+
+ int BM = 4032;
+ int BN = isTransA ? 96 : 48;
+ int BK = isTransB ? 96 : 256;
+ const float *curA, *curB, *curBias = nullptr;
+ float *curC;
+
+ for (Bk = 0; Bk < k; Bk += sizeK) {
+ sizeK = k - Bk;
+ if (sizeK >= BK * 2)
+ sizeK = BK;
+ else {
+ if (sizeK > BK)
+ sizeK = (sizeK + 1) / 2;
+ }
+
+ for (Bm = 0; Bm < m; Bm += sizeM) {
+ sizeM = m - Bm;
+ if (sizeM >= BM * 2)
+ sizeM = BM;
+ else {
+ if (sizeM > BM + BM / 2)
+ sizeM = (sizeM + 1) / 2;
+ }
+
+ for (Bn = 0; Bn < n; Bn += sizeN) {
+ sizeN = n - Bn;
+ if (sizeN >= BN * 2)
+ sizeN = BN;
+ else {
+ if (sizeN > BN + BN / 2)
+ sizeN = (sizeN + 1) / 2;
+ }
+
+ if (!isTransA) {
+ curA = a + Bm + Bk * lda;
+ } else {
+ curA = a + Bk + Bm * lda;
+ }
+ if (!isTransB) {
+ curB = b + Bk + Bn * ldb;
+ } else {
+ curB = b + Bn + Bk * ldb;
+ }
+ curC = c + Bm + (size_t)Bn * ldc;
+ if (bias != nullptr) {
+ if (Bk == 0) {
+ curBias = bias + Bm;
+ } else {
+ curBias = nullptr;
+ }
+ }
+ if (Bk == 0) {
+ if (*beta == 0.0 && bias == nullptr)
+ (*ker_b0)((dim_t)sizeM, (dim_t)sizeN, (dim_t)sizeK,
+ alpha, curA, lda, curB, ldb, beta, curC, ldc,
+ curBias, ws);
+ else
+ (*ker_bn)((dim_t)sizeM, (dim_t)sizeN, (dim_t)sizeK,
+ alpha, curA, lda, curB, ldb, beta, curC, ldc,
+ curBias, ws);
+ } else {
+ (*ker_b1)((dim_t)sizeM, (dim_t)sizeN, (dim_t)sizeK,
+ alpha, curA, lda, curB, ldb, beta, curC, ldc,
+ curBias, ws);
+ }
+ }
+ }
+ }
+}
+
+}
+
+mkldnn_status_t jit_avx_gemm_f32(
+ const char *transa, const char *transb,
+ const int *p_m, const int *p_n, const int *p_k, const float *p_alpha,
+ const float *A, const int *p_lda, const float *B, const int *p_ldb,
+ const float *p_beta, float *C, const int *p_ldc, const float *bias)
+{
+ using namespace mkldnn::impl::utils;
+ using namespace avx_gemm_f32;
+ using namespace gemm_utils;
+
+ if (*p_beta != 0 && bias)
+ return ref_gemm(transa, transb, p_m, p_n, p_k,
+ p_alpha, A, p_lda, B, p_lda, p_beta, C, p_ldc, bias);
+
+ int nthr = (mkldnn_in_parallel()) ? 1 : mkldnn_get_max_threads();
+
+ int m = *p_m;
+ int n = *p_n;
+ int k = *p_k;
+ dim_t lda = *p_lda;
+ dim_t ldb = *p_ldb;
+ dim_t ldc = *p_ldc;
+ float beta = *p_beta;
+ int MB, NB, KB;
+
+ int nthr_m, nthr_n, nthr_k, nthr_mn;
+
+ // Determine threading partitioning
+ calc_nthr_nocopy_avx(
+ m, n, k, nthr, &nthr_m, &nthr_n, &nthr_k, &MB, &NB, &KB);
+ assert(IMPLICATION(!mkldnn_thr_syncable(), nthr_k == 1));
+
+ // May not happen, but just in case
+ if (nthr < nthr_m * nthr_n * nthr_k)
+ nthr = nthr_m * nthr_n * nthr_k;
+
+ nthr_mn = nthr_m * nthr_n;
+
+ unsigned char * ompstatus_ = nullptr;
+ unsigned char volatile *ompstatus = nullptr;
+
+ float *c_buffers = nullptr;
+ float *ws_buffers = nullptr;
+
+ if (nthr_k > 1) {
+ ompstatus_ = (unsigned char *) malloc(
+ nthr * CACHE_LINE_SIZE,
+ CACHE_LINE_SIZE);
+ ompstatus = (unsigned char volatile *) ompstatus_;
+ assert(ompstatus);
+
+ for (int i = 0; i < nthr; i++)
+ ompstatus[i * CACHE_LINE_SIZE] = 0;
+
+ c_buffers = (float *)malloc(nthr_m * nthr_n * (nthr_k - 1) * MB * NB
+ * sizeof(float), PAGE_4K);
+ }
+
+ const size_t ws_elems_per_thr = (size_t)k * 16 + 64;
+ const size_t ws_size_per_thr
+ = rnd_up(ws_elems_per_thr * sizeof(float), PAGE_4K);
+ if (k > STACK_K_CAPACITY) {
+ ws_buffers = (float *)malloc(nthr * ws_size_per_thr, PAGE_4K);
+ }
+
+ parallel_nd(nthr, [&](const int ithr) {
+ int ithr_m, ithr_n, ithr_k, ithr_mn;
+ int m_from, m_to, myM;
+ int n_from, n_to, myN;
+ int k_from, k_to, myK;
+ int cbase, ibase;
+ const float *myA, *myB, *myBias = nullptr;
+ float *myC = C, myBeta;
+ float *ws = ws_buffers ?
+ ws_buffers + ithr * ws_size_per_thr / sizeof(float) : 0;
+ dim_t ld = ldc;
+
+ int sum_later = (mkldnn_get_num_threads() < nthr_m * nthr_n * nthr_k);
+
+ if (ithr < nthr_m * nthr_n * nthr_k) {
+
+ ithr_mn = ithr % nthr_mn;
+ ithr_m = ithr_mn % nthr_m;
+ ithr_n = ithr_mn / nthr_m;
+ ithr_k = ithr / nthr_mn;
+
+ /* swap ithr_k for performance improvement */
+ if (ithr_k == 0)
+ ithr_k = nthr_k - 1;
+ else if (ithr_k == nthr_k - 1)
+ ithr_k = 0;
+
+ m_from = MB * (ithr_m);
+ m_to = MB * (ithr_m + 1);
+ if (m_to > m)
+ m_to = m;
+ myM = m_to - m_from;
+
+ n_from = NB * (ithr_n);
+ n_to = NB * (ithr_n + 1);
+ if (n_to > n)
+ n_to = n;
+ myN = n_to - n_from;
+
+ k_from = KB * (ithr_k);
+ k_to = KB * (ithr_k + 1);
+ if (k_to > k)
+ k_to = k;
+ myK = k_to - k_from;
+
+ cbase = (ithr_m + nthr_m * ithr_n) * (nthr_k - 1);
+ ibase = (ithr_m + nthr_m * ithr_n) * nthr_k;
+
+ if ((myM > 0) && (myN > 0)) {
+
+ if (*transa == 'N' || *transa == 'n') {
+ myA = &(A[m_from + k_from * lda]);
+ } else {
+ myA = &(A[k_from + m_from * lda]);
+ }
+ if (*transb == 'N' || *transb == 'n') {
+ myB = &(B[k_from + n_from * ldb]);
+ } else {
+ myB = &(B[n_from + k_from * ldb]);
+ }
+ if (ithr_k == 0) {
+ myC = &(C[m_from + n_from * ldc]);
+ myBeta = beta;
+ ld = ldc;
+ if (bias)
+ myBias = &(bias[m_from]);
+ } else {
+ myC = c_buffers + (dim_t)MB * NB * (cbase + ithr_k - 1);
+ myBeta = 0.0;
+ ld = MB;
+ myBias = nullptr;
+ }
+
+ sgemm_nocopy_driver(transa, transb, myM, myN, myK, p_alpha, myA,
+ lda, myB, ldb, &myBeta, myC, ld, myBias, ws);
+
+ if (nthr_k > 1 && !sum_later)
+ ompstatus[(ibase + ithr_k) * CACHE_LINE_SIZE] = 1;
+ }
+
+ if (nthr_k > 1 && !sum_later) {
+
+ // sum matrices partitioned along K dimension
+ int n1, n2;
+
+ partition_unit_diff(ithr_k, nthr_k, myN, &n1, &n2);
+
+ if (ithr_k > 0) {
+
+ myC = c_buffers + (dim_t)MB * NB * (cbase + ithr_k - 1)
+ + (dim_t)n1 * MB;
+ /* need to wait until main thread finishes */
+ while (ompstatus[ibase * CACHE_LINE_SIZE] != 1) {
+ };
+
+ /* my cache is hot */
+ sum_two_matrices(myM, n2, myC, MB,
+ &C[m_from + (n_from + n1) * ldc], ldc);
+ }
+
+ for (int ik = 1; ik < nthr_k; ++ik) {
+ if (ik != ithr_k) {
+
+ myC = c_buffers + (dim_t)MB * NB * (cbase + ik - 1)
+ + (dim_t)n1 * MB;
+
+ while (ompstatus[(ibase + ik) * CACHE_LINE_SIZE] != 1) {
+ };
+
+ sum_two_matrices(myM, n2, myC, MB,
+ &C[m_from + (n_from + n1) * ldc], ldc);
+ }
+ }
+ }
+ }
+ });
+
+ // handle C summation later
+ if (nthr_k > 1 && ompstatus[0] == 0) {
+
+ parallel_nd(nthr, [&](const int ithr) {
+ int ithr_m, ithr_n, ithr_k, ithr_mn;
+ int m_from, m_to, myM;
+ int n_from, n_to, myN;
+ int cbase;
+ float *myC = C;
+
+ if (ithr < nthr_m * nthr_n * nthr_k) {
+
+ ithr_mn = ithr % nthr_mn;
+ ithr_m = ithr_mn % nthr_m;
+ ithr_n = ithr_mn / nthr_m;
+ ithr_k = ithr / nthr_mn;
+
+ /* swap ithr_k for performance improvement */
+ if (ithr_k == 0)
+ ithr_k = nthr_k - 1;
+ else if (ithr_k == nthr_k - 1)
+ ithr_k = 0;
+
+ m_from = MB * (ithr_m);
+ m_to = MB * (ithr_m + 1);
+ if (m_to > m)
+ m_to = m;
+ myM = m_to - m_from;
+
+ n_from = NB * (ithr_n);
+ n_to = NB * (ithr_n + 1);
+ if (n_to > n)
+ n_to = n;
+ myN = n_to - n_from;
+
+ cbase = (ithr_m + nthr_m * ithr_n) * (nthr_k - 1);
+
+ if (nthr_k > 1) {
+ // sum matrices partitioned along K dimension
+ int n1, n2;
+
+ partition_unit_diff(ithr_k, nthr_k, myN, &n1, &n2);
+
+ if (ithr_k > 0) {
+
+ myC = c_buffers + (dim_t)MB * NB * (cbase + ithr_k - 1)
+ + (dim_t)n1 * MB;
+
+ /* my cache is hot */
+ sum_two_matrices(myM, n2, myC, MB,
+ &C[m_from + (n_from + n1) * ldc], ldc);
+ }
+
+ for (int ik = 1; ik < nthr_k; ++ik) {
+ if (ik != ithr_k) {
+
+ myC = c_buffers + (dim_t)MB * NB * (cbase + ik - 1)
+ + (dim_t)n1 * MB;
+
+ sum_two_matrices(myM, n2, myC, MB,
+ &C[m_from + (n_from + n1) * ldc], ldc);
+ }
+ }
+ }
+ }
+ });
+ }
+
+
+ free(c_buffers);
+ free(ompstatus_);
+ free(ws_buffers);
+
+ return mkldnn_success;
+}
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx_gemm_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx_gemm_f32.hpp
new file mode 100644
index 0000000000..aabf520a3c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/jit_avx_gemm_f32.hpp
@@ -0,0 +1,37 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_AVX_GEMM_F32_HPP
+#define JIT_AVX_GEMM_F32_HPP
+
+#include "mkldnn_types.h"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+mkldnn_status_t jit_avx_gemm_f32(
+ const char *transa, const char *transb, const int *M,
+ const int *N, const int *K, const float *alpha, const float *A,
+ const int *lda, const float *B, const int *ldb, const float *beta,
+ float *C, const int *ldc, const float *bias = nullptr);
+
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/ref_gemm_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/ref_gemm_f32.cpp
new file mode 100644
index 0000000000..5147885a89
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/ref_gemm_f32.cpp
@@ -0,0 +1,346 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn_types.h"
+
+#include "mkldnn_thread.hpp"
+#include "nstl.hpp"
+#include "utils.hpp"
+
+#include "jit_generator.hpp"
+
+#include "gemm_utils_f32.hpp"
+#include "ref_gemm_f32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::utils;
+using namespace gemm_utils;
+
+namespace {
+
+template <typename data_t>
+void copy_A(
+ bool isTransA, int K, const data_t *A, const dim_t lda, data_t *ws) {
+ for (int k = 0; k < K; k++) {
+ PRAGMA_OMP_SIMD()
+ for (int i = 0; i < unroll_factor<data_t>::m; i++) {
+ ws[i] = isTransA ? A[i * lda + k] : A[i + k * lda];
+ }
+ ws += unroll_factor<data_t>::m;
+ }
+}
+
+template <typename data_t, bool isTransA, bool isTransB>
+void kernel_mxn(int K, const data_t *A, const dim_t lda,
+ const data_t *B, const dim_t ldb, data_t *C, const dim_t ldc,
+ const data_t alpha, const data_t beta) {
+ data_t c[unroll_factor<data_t>::m * unroll_factor<data_t>::n] =
+ { static_cast<data_t>(0.) };
+ for (int k = 0; k < K; k++) {
+ for (int j = 0; j < unroll_factor<data_t>::n; j++) {
+ data_t b = isTransB ? B[j + k * ldb] : B[k + j * ldb];
+ PRAGMA_OMP_SIMD()
+ for (int i = 0; i < unroll_factor<data_t>::m; i++) {
+ data_t a = isTransA ? A[i * lda + k] : A[i + lda * k];
+ c[i + unroll_factor<data_t>::m * j] += a * b;
+ }
+ }
+ }
+ for (int j = 0; j < unroll_factor<data_t>::n; j++) {
+ PRAGMA_OMP_SIMD()
+ for (int i = 0; i < unroll_factor<data_t>::m; i++) {
+ C[i + j * ldc] = (beta == static_cast<data_t>(0.))
+ ? alpha * c[i + unroll_factor<data_t>::m * j]
+ : alpha * c[i + unroll_factor<data_t>::m * j]
+ + beta * C[i + j * ldc];
+ }
+ }
+}
+
+template <typename data_t, bool isTransA, bool isTransB>
+void block_ker(const int M, const int N, const int K,
+ const data_t *A, const dim_t lda, const data_t *B, const dim_t ldb,
+ data_t *C, const dim_t ldc, const data_t alpha, const data_t beta,
+ data_t *ws, bool do_copy) {
+ int Nu = rnd_dn(N, unroll_factor<data_t>::n);
+ int Mu = rnd_dn(M, unroll_factor<data_t>::m);
+ for (int i = 0; i < Mu; i += unroll_factor<data_t>::m) {
+ for (int j = 0; j < Nu; j += unroll_factor<data_t>::n) {
+ const data_t *b = isTransB ? &B[j] : &B[j * ldb];
+ const data_t *a = isTransA ? &A[i * lda] : &A[i];
+ if (do_copy) {
+ if (j == 0) {
+ copy_A<data_t>(isTransA, K, a, lda, ws);
+ }
+ kernel_mxn<data_t, false, isTransB>(
+ K, ws, unroll_factor<data_t>::m, b, ldb,
+ &C[i + j * ldc], ldc, alpha, beta);
+ } else {
+ kernel_mxn<data_t, isTransA, isTransB>(
+ K, a, lda, b, ldb, &C[i + j * ldc], ldc, alpha, beta);
+ }
+ }
+ }
+ // tail processing
+ for (int i = 0; i < M; i++) {
+ for (int j = Nu; j < N; j++) {
+ data_t c = beta == static_cast<data_t>(0.)
+ ? static_cast<data_t>(0.)
+ : beta * C[i + j * ldc];
+ for (int p = 0; p < K; p++) {
+ data_t b = isTransB ? B[j + p * ldb] : B[p + j * ldb];
+ data_t a = isTransA ? A[p + i * lda] : A[i + p * lda];
+ c += alpha * a * b;
+ }
+ C[i + j * ldc] = c;
+ }
+ }
+ for (int i = Mu; i < M; i++) {
+ for (int j = 0; j < Nu; j++) {
+ data_t c = beta == static_cast<data_t>(0.)
+ ? static_cast<data_t>(0.)
+ : beta * C[i + j * ldc];
+ for (int p = 0; p < K; p++) {
+ data_t b = isTransB ? B[j + p * ldb] : B[p + j * ldb];
+ data_t a = isTransA ? A[p + i * lda] : A[i + p * lda];
+ c += alpha * a * b;
+ }
+ C[i + j * ldc] = c;
+ }
+ }
+}
+
+template <typename data_t, bool isTransA, bool isTransB>
+void gemm_ithr(const int M, const int N, const int K, const data_t alpha,
+ const data_t *A, const dim_t lda, const data_t *B, const dim_t ldb,
+ const data_t beta, data_t *C, const dim_t ldc, bool do_copy,
+ data_t *ws) {
+ constexpr int BM = gemm_traits<data_t, isTransA, isTransB>::BM;
+ constexpr int BN = gemm_traits<data_t, isTransA, isTransB>::BN;
+ constexpr int BK = gemm_traits<data_t, isTransA, isTransB>::BK;
+
+ const data_t *curA;
+ const data_t *curB;
+ data_t *curC;
+
+ if ((M <= 0) || (N <= 0))
+ return;
+
+ if ((K <= 0) || (alpha == static_cast<data_t>(0))) {
+ dim_t MN = N * M;
+ if (beta == static_cast<data_t>(0.)) {
+ for (dim_t j = 0; j < MN; j++)
+ C[j] = static_cast<data_t>(0.);
+ } else if (beta != static_cast<data_t>(1.)) {
+ for (dim_t j = 0; j < MN; j++)
+ C[j] *= beta;
+ }
+ return;
+ }
+
+ for (int Bk = 0; Bk < K; Bk += BK) {
+ int kb = nstl::min(K - Bk, BK);
+ for (int Bm = 0; Bm < M; Bm += BM) {
+ int mb = nstl::min(M - Bm, BM);
+ for (int Bn = 0; Bn < N; Bn += BN) {
+ int nb = nstl::min(N - Bn, BN);
+ curA = isTransA ? A + Bk + Bm * lda : A + Bm + Bk * lda;
+ curB = isTransB ? B + Bn + Bk * ldb : B + Bk + Bn * ldb;
+ curC = C + Bm + Bn * ldc;
+ if (Bk == 0) {
+ block_ker<data_t, isTransA, isTransB>(mb, nb, kb, curA, lda,
+ curB, ldb, curC, ldc, alpha, beta, ws, do_copy);
+ } else {
+ block_ker<data_t, isTransA, isTransB>(mb, nb, kb, curA, lda,
+ curB, ldb, curC, ldc, alpha, static_cast<data_t>(1.0),
+ ws, do_copy);
+ }
+ }
+ }
+ }
+}
+
+}
+
+template <typename data_t>
+mkldnn_status_t ref_gemm(
+ const char *transa_, const char *transb_, const int *M_,
+ const int *N_, const int *K_, const data_t *alpha_, const data_t *A,
+ const int *lda_, const data_t *B, const int *ldb_, const data_t *beta_,
+ data_t *C, const int *ldc_, const data_t *bias) {
+
+ bool isTransA = (*transa_ == 'T' || *transa_ == 't');
+ bool isTransB = (*transb_ == 'T' || *transb_ == 't');
+ const int M = *M_, N = *N_, K = *K_;
+ const dim_t lda = *lda_, ldb = *ldb_, ldc = *ldc_;
+ const data_t alpha = *alpha_, beta = *beta_;
+
+ int max_nthr = mkldnn_in_parallel() ? 1 : mkldnn_get_max_threads();
+ int nthr_m, nthr_n, nthr_k;
+ int MB, NB, KB;
+ // thread balancing over M, N, K & size of blocking dimensions
+ calc_nthr_nocopy_avx(
+ M, N, K, max_nthr, &nthr_m, &nthr_n, &nthr_k, &MB, &NB, &KB);
+ assert(IMPLICATION(!mkldnn_thr_syncable(), nthr_k == 1));
+
+ data_t *c_buffers = nullptr;
+ data_t *ws_buffers = nullptr;
+ if (nthr_k > 1) {
+ c_buffers = (data_t *)malloc(nthr_m * nthr_n * (nthr_k - 1) * MB * NB
+ * sizeof(data_t), PAGE_4K);
+ if (!c_buffers) {
+ nthr_k = 1;
+ KB = K;
+ }
+ }
+
+ bool do_copy = (NB / unroll_factor<data_t>::n > 3);
+ const int nthr_mn = nthr_m * nthr_n;
+ const int nthr = nthr_mn * nthr_k;
+ const size_t ws_elems_per_thr = K * unroll_factor<data_t>::m;
+ const size_t ws_size_per_thr
+ = rnd_up(ws_elems_per_thr * sizeof(data_t), PAGE_4K);
+ if (do_copy) {
+ ws_buffers = (data_t*)malloc(nthr * ws_size_per_thr, PAGE_4K);
+ if (!ws_buffers)
+ do_copy = false;
+ }
+
+ auto get_thr_block = [&](int &from, int &to, int &myN, int NB, int N,
+ int ithr) {
+ from = NB * (ithr);
+ to = NB * (ithr + 1);
+ if (to > N)
+ to = N;
+ myN = to - from;
+ };
+
+ parallel_nd(nthr, [&](const int ithr) {
+ int ithr_mn = ithr % nthr_mn;
+ int ithr_m = ithr_mn % nthr_m;
+ int ithr_n = ithr_mn / nthr_m;
+ int ithr_k = ithr / nthr_mn;
+
+ int cbase = (ithr_m + nthr_m * ithr_n) * (nthr_k - 1);
+
+ data_t *ws = do_copy
+ ? ws_buffers + ithr * ws_size_per_thr / sizeof(data_t)
+ : nullptr;
+
+ int m_from = 0, m_to = 0, myM = 0, n_from = 0, n_to = 0, myN = 0,
+ k_from = 0, k_to = 0, myK = 0;
+
+ get_thr_block(m_from, m_to, myM, MB, M, ithr_m);
+ get_thr_block(n_from, n_to, myN, NB, N, ithr_n);
+ get_thr_block(k_from, k_to, myK, KB, K, ithr_k);
+
+ if (myM > 0 && myN > 0) {
+ data_t myBeta, *myC;
+ dim_t ld;
+ if (ithr_k == 0) {
+ myC = &(C[m_from + n_from * ldc]);
+ myBeta = beta;
+ ld = ldc;
+ } else {
+ myC = c_buffers + (dim_t)MB * NB * (cbase + ithr_k - 1);
+ myBeta = 0.0f;
+ ld = MB;
+ }
+ const data_t *myA = isTransA
+ ? &(A[k_from + m_from * lda])
+ : &(A[m_from + k_from * lda]);
+ const data_t *myB = isTransB
+ ? &(B[n_from + k_from * ldb])
+ : &(B[k_from + n_from * ldb]);
+
+ if (!isTransA) {
+ if (!isTransB) {
+ gemm_ithr<data_t, false, false>(myM, myN, myK, alpha, myA,
+ lda, myB, ldb, myBeta, myC, ld, do_copy, ws);
+ } else {
+ gemm_ithr<data_t, false, true>(myM, myN, myK, alpha, myA,
+ lda, myB, ldb, myBeta, myC, ld, do_copy, ws);
+ }
+ } else {
+ if (!isTransB) {
+ gemm_ithr<data_t, true, false>(myM, myN, myK, alpha, myA,
+ lda, myB, ldb, myBeta, myC, ld, do_copy, ws);
+ } else {
+ gemm_ithr<data_t, true, true>(myM, myN, myK, alpha, myA,
+ lda, myB, ldb, myBeta, myC, ld, do_copy, ws);
+ }
+ }
+ }
+ });
+
+ if (nthr_k > 1) {
+ parallel_nd(nthr, [&](const int ithr) {
+ int ithr_mn = ithr % nthr_mn;
+ int ithr_m = ithr_mn % nthr_m;
+ int ithr_k = ithr / nthr_mn;
+ int ithr_n = ithr_mn / nthr_m;
+
+ int n_from = 0, n_to = 0, myN = 0;
+ int m_from = 0, m_to = 0, myM = 0;
+
+ int cbase = (ithr_m + nthr_m * ithr_n) * (nthr_k - 1);
+
+ get_thr_block(n_from, n_to, myN, NB, N, ithr_n);
+ get_thr_block(m_from, m_to, myM, MB, M, ithr_m);
+
+ // sum matrices partitioned along K dimension
+ int offset = 0, block = 0;
+ gemm_utils::partition_unit_diff(ithr_k, nthr_k, myN, &offset,
+ &block);
+ for (int ik = 1; ik < nthr_k; ++ik) {
+ data_t *myC = c_buffers
+ + MB * ((dim_t)NB * (cbase + ik - 1) + offset);
+
+ gemm_utils::sum_two_matrices(myM, block, myC, MB,
+ &C[m_from + (n_from + offset) * ldc], ldc);
+ }
+ });
+ }
+
+ if (bias) {
+ parallel_nd(N, M, [&](int i, int j) {
+ C[i*ldc + j] += bias[j];
+ });
+ }
+
+ free(ws_buffers);
+ free(c_buffers);
+
+ return mkldnn_success;
+}
+
+template mkldnn_status_t ref_gemm<float>(
+ const char *transa_, const char *transb_,
+ const int *M_, const int *N_, const int *K_, const float *alpha_,
+ const float *A, const int *lda_, const float *B, const int *ldb_,
+ const float *beta_, float *C, const int *ldc_, const float *bias);
+
+template mkldnn_status_t ref_gemm<double>(
+ const char *transa_, const char *transb_,
+ const int *M_, const int *N_, const int *K_, const double *alpha_,
+ const double *A, const int *lda_, const double *B, const int *ldb_,
+ const double *beta_, double *C, const int *ldc_, const double *bias);
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/ref_gemm_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/ref_gemm_f32.hpp
new file mode 100644
index 0000000000..7c90ba6277
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/f32/ref_gemm_f32.hpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef REF_GEMM_F32_HPP
+#define REF_GEMM_F32_HPP
+
+#include "mkldnn_types.h"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <typename data_t>
+mkldnn_status_t ref_gemm(const char *transa, const char *transb, const int *M,
+ const int *N, const int *K, const data_t *alpha, const data_t *A,
+ const int *lda, const data_t *B, const int *ldb, const data_t *beta,
+ data_t *C, const int *ldc, const data_t *bias);
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp
new file mode 100644
index 0000000000..3dbe07d743
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp
@@ -0,0 +1,280 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn.h"
+
+#include "mkldnn_traits.hpp"
+#include "nstl.hpp"
+
+#include "jit_generator.hpp"
+
+#include "gemm.hpp"
+
+#include "f32/jit_avx512_common_gemm_f32.hpp"
+#include "f32/jit_avx_gemm_f32.hpp"
+#include "f32/ref_gemm_f32.hpp"
+
+#include "s8x8s32/jit_avx512_core_gemm_s8u8s32.hpp"
+#include "s8x8s32/simple_gemm_s8s8s32.hpp"
+#include "s8x8s32/ref_gemm_s8x8s32.hpp"
+
+#include "os_blas.hpp"
+
+/* USE_MKL USE_CBLAS effect
+ * ------- --------- ------
+ * yes yes use Intel(R) MKL CBLAS
+ * yes no use jit
+ * no yes system-dependent CBLAS
+ * no no use jit
+ */
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+mkldnn_status_t check_gemm_input(const char *transa, const char *transb,
+ const int *M, const int *N, const int *K, const int *lda,
+ const int *ldb, const int *ldc, const float *alpha, const float *beta,
+ const bool with_bias) {
+ if (utils::any_null(transa, transb, M, N, K, lda, ldb, ldc, alpha, beta))
+ return mkldnn_invalid_arguments;
+ if (with_bias && *beta != 0)
+ return mkldnn_unimplemented;
+ bool consistency = true
+ && utils::one_of(*transa, 'T', 't', 'N', 'n')
+ && utils::one_of(*transb, 'T', 't', 'N', 'n')
+ && *M >= 0
+ && *N >= 0
+ && *K >= 0;
+
+ if (!consistency)
+ return mkldnn_invalid_arguments;
+ bool isTransA = utils::one_of(*transa, 'T', 't');
+ bool isTransB = utils::one_of(*transb, 'T', 't');
+ int nrowA = isTransA ? *K : *M;
+ int nrowB = isTransB ? *N : *K;
+ consistency = true
+ && *lda >= nstl::max(1, nrowA)
+ && *ldb >= nstl::max(1, nrowB)
+ && *ldc >= nstl::max(1, *M);
+ if (!consistency)
+ return mkldnn_invalid_arguments;
+
+ return mkldnn_success;
+}
+
+mkldnn_status_t check_gemm_x8x8x32_input(const char *offsetc,
+ const char *transa, const char *transb, const int *M, const int *N,
+ const int *K, const int *lda, const int *ldb, const int *ldc,
+ const float *alpha, const float *beta, const bool with_bias) {
+ if (offsetc == nullptr)
+ return mkldnn_invalid_arguments;
+ if (!utils::one_of(*offsetc, 'F', 'f', 'C', 'c', 'R', 'r'))
+ return mkldnn_invalid_arguments;
+
+ return check_gemm_input(transa, transb, M, N, K, lda, ldb, ldc, alpha,
+ beta, with_bias);
+}
+
+mkldnn_status_t extended_sgemm(const char *transa, const char *transb,
+ const int *M, const int *N, const int *K, const float *alpha,
+ const float *A, const int *lda, const float *B, const int *ldb,
+ const float *beta, float *C, const int *ldc,
+ const float *bias, const bool force_jit_gemm) {
+ mkldnn_status_t status = check_gemm_input(transa, transb, M, N, K,
+ lda, ldb, ldc, alpha, beta, bias != nullptr);
+ if (status != mkldnn_success)
+ return status;
+
+#ifdef USE_CBLAS
+ if (!force_jit_gemm) {
+ bool trA = *transa == 't' || *transa == 'T';
+ bool trB = *transb == 't' || *transb == 'T';
+ CBLAS_TRANSPOSE Cblas_trA = trA ? CblasTrans : CblasNoTrans;
+ CBLAS_TRANSPOSE Cblas_trB = trB ? CblasTrans : CblasNoTrans;
+ cblas_sgemm(CblasColMajor, Cblas_trA, Cblas_trB,
+ *M, *N, *K, *alpha, A, *lda, B, *ldb, *beta, C, *ldc);
+
+ if (bias) {
+ // Add bias if necessary (bias is applied to columns of C)
+ cblas_int incx = 1, incy = 1;
+ parallel_nd(*N, [&](int n) {
+ ptrdiff_t offset = (ptrdiff_t)n * (*ldc);
+ cblas_saxpy(*M, 1.0, bias, incx, C + offset, incy);
+ });
+ }
+ return mkldnn_success;
+ }
+#endif
+
+ if (mayiuse(avx512_common))
+ return jit_avx512_common_gemm_f32(transa, transb,
+ M, N, K, alpha, A, lda, B, ldb, beta, C, ldc, bias);
+ else if (mayiuse(avx))
+ return jit_avx_gemm_f32(transa, transb,
+ M, N, K, alpha, A, lda, B, ldb, beta, C, ldc, bias);
+ else
+ return ref_gemm<float>(transa, transb,
+ M, N, K, alpha, A, lda, B, ldb, beta, C, ldc, bias);
+}
+
+template <typename b_dt>
+mkldnn_status_t gemm_s8x8s32(const char *transa, const char *transb,
+ const char *offsetc, const int *M, const int *N, const int *K,
+ const float *alpha, const int8_t *A, const int *LDA, const int8_t *ao,
+ const b_dt *B, const int *LDB, const int8_t *bo, const float *beta,
+ int32_t *C, const int *LDC, const int32_t *co) {
+ mkldnn_status_t status = check_gemm_x8x8x32_input(offsetc, transa, transb,
+ M, N, K, LDA, LDB, LDC, alpha, beta, false);
+ if (status != mkldnn_success)
+ return status;
+
+ if (*M == 0 || *N == 0 || *K == 0)
+ return mkldnn_success;
+
+#if USE_MKL_IGEMM
+ bool OCisR = (*offsetc == 'R' || *offsetc == 'r');
+ bool OCisC = (*offsetc == 'C' || *offsetc == 'c');
+ bool AisN = (*transa == 'N' || *transa == 'n');
+ bool BisN = (*transb == 'N' || *transb == 'n');
+
+ if (data_traits<b_dt>::data_type == data_type::u8) {
+ CBLAS_TRANSPOSE Cblas_trA = AisN ? CblasNoTrans : CblasTrans;
+ CBLAS_TRANSPOSE Cblas_trB = BisN ? CblasNoTrans : CblasTrans;
+ CBLAS_OFFSET Cblas_offsetc =
+ OCisR
+ ? CblasRowOffset
+ : OCisC
+ ? CblasColOffset
+ : CblasFixOffset;
+ cblas_gemm_s8u8s32(CblasColMajor, Cblas_trA, Cblas_trB, Cblas_offsetc,
+ *M, *N, *K, *alpha, A, *LDA, *ao, (uint8_t *)B, *LDB, *bo,
+ *beta, C, *LDC, co);
+ return mkldnn_success;
+ } else {
+ assert(data_traits<b_dt>::data_type == data_type::s8);
+ // TODO CBLAS implementation of gemm_s8s8s32 goes here.
+ // mkldnn_gemm_s8s8s32 doesn't support non-zero ao and bo
+ if (utils::everyone_is(0, *ao, *bo)) {
+ return simple_gemm_s8s8s32(transa, transb, offsetc, M,
+ N, K, alpha, A, LDA, ao, (int8_t *)B, LDB, bo, beta,
+ C, LDC, co);
+ } else {
+ return ref_gemm_s8x8s32(transa, transb, offsetc, M, N, K,
+ alpha, A, LDA, ao, B, LDB, bo, beta, C, LDC, co);
+ }
+ }
+#else
+ cpu_isa_t isa = isa_any;
+ if (mayiuse(avx512_core_vnni)) {
+ isa = avx512_core_vnni;
+ } else if (mayiuse(avx512_core)) {
+ isa = avx512_core;
+ }
+
+ if (data_traits<b_dt>::data_type == data_type::u8) {
+ switch (isa) {
+ case avx512_core:
+ case avx512_core_vnni:
+ return jit_avx512_core_gemm_s8u8s32(transa, transb, offsetc, M,
+ N, K, alpha, A, LDA, ao, (uint8_t *)B, LDB, bo, beta,
+ C, LDC, co);
+ default:
+ return ref_gemm_s8x8s32(transa, transb, offsetc, M, N, K,
+ alpha, A, LDA, ao, B, LDB, bo, beta, C, LDC, co);
+ }
+ } else {
+ assert(data_traits<b_dt>::data_type == data_type::s8);
+ // mkldnn_gemm_s8s8s32 doesn't support non-zero ao and bo
+ if ((mayiuse(avx512_core) || mayiuse(avx512_core_vnni))
+ && *ao == 0 && *bo == 0) {
+ return simple_gemm_s8s8s32(transa, transb, offsetc, M,
+ N, K, alpha, A, LDA, ao, (int8_t *)B, LDB, bo, beta,
+ C, LDC, co);
+ } else {
+ return ref_gemm_s8x8s32(transa, transb, offsetc, M, N, K,
+ alpha, A, LDA, ao, B, LDB, bo, beta, C, LDC, co);
+ }
+ }
+#endif
+}
+
+template
+mkldnn_status_t gemm_s8x8s32(const char *transa, const char *transb,
+ const char *offsetc, const int *M, const int *N, const int *K,
+ const float *alpha, const int8_t *A, const int *LDA, const int8_t *ao,
+ const int8_t *B, const int *LDB, const int8_t *bo, const float *beta,
+ int32_t *C, const int *LDC, const int32_t *co);
+
+template
+mkldnn_status_t gemm_s8x8s32(const char *transa, const char *transb,
+ const char *offsetc, const int *M, const int *N, const int *K,
+ const float *alpha, const int8_t *A, const int *LDA, const int8_t *ao,
+ const uint8_t *B, const int *LDB, const int8_t *bo, const float *beta,
+ int32_t *C, const int *LDC, const int32_t *co);
+
+}
+}
+}
+
+using namespace mkldnn::impl;
+using namespace mkldnn::impl::cpu;
+
+mkldnn_status_t mkldnn_sgemm(const char *transa, const char *transb,
+ const int64_t *M, const int64_t *N, const int64_t *K, const float *alpha,
+ const float *A, const int64_t *lda, const float *B, const int64_t *ldb,
+ const float *beta, float *C, const int64_t *ldc) {
+ int M_s32 = (int)*M;
+ int N_s32 = (int)*N;
+ int K_s32 = (int)*K;
+ int lda_s32 = (int)*lda;
+ int ldb_s32 = (int)*ldb;
+ int ldc_s32 = (int)*ldc;
+
+ return extended_sgemm(transa, transb, &M_s32, &N_s32, &K_s32,
+ alpha, A, &lda_s32, B, &ldb_s32, beta, C, &ldc_s32);
+}
+
+mkldnn_status_t mkldnn_gemm_s8u8s32(const char *transa, const char *transb,
+ const char *offsetc, const int64_t *M, const int64_t *N, const int64_t *K,
+ const float *alpha, const int8_t *A, const int64_t *lda, const int8_t *ao,
+ const uint8_t *B, const int64_t *ldb, const int8_t *bo, const float *beta,
+ int32_t *C, const int64_t *ldc, const int32_t *co) {
+ int M_s32 = (int)*M;
+ int N_s32 = (int)*N;
+ int K_s32 = (int)*K;
+ int lda_s32 = (int)*lda;
+ int ldb_s32 = (int)*ldb;
+ int ldc_s32 = (int)*ldc;
+ return gemm_s8x8s32(transa, transb, offsetc, &M_s32, &N_s32, &K_s32,
+ alpha, A, &lda_s32, ao, B, &ldb_s32, bo, beta, C, &ldc_s32, co);
+}
+
+mkldnn_status_t mkldnn_gemm_s8s8s32(const char *transa, const char *transb,
+ const char *offsetc, const int64_t *M, const int64_t *N, const int64_t *K,
+ const float *alpha, const int8_t *A, const int64_t *lda, const int8_t *ao,
+ const int8_t *B, const int64_t *ldb, const int8_t *bo, const float *beta,
+ int32_t *C, const int64_t *ldc, const int32_t *co) {
+ int M_s32 = (int)*M;
+ int N_s32 = (int)*N;
+ int K_s32 = (int)*K;
+ int lda_s32 = (int)*lda;
+ int ldb_s32 = (int)*ldb;
+ int ldc_s32 = (int)*ldc;
+
+ return gemm_s8x8s32<int8_t>(transa, transb, offsetc, &M_s32, &N_s32, &K_s32,
+ alpha, A, &lda_s32, ao, B, &ldb_s32, bo, beta, C, &ldc_s32, co);
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.hpp
new file mode 100644
index 0000000000..dc15ff7130
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.hpp
@@ -0,0 +1,58 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef GEMM_HPP
+#define GEMM_HPP
+
+#include "mkldnn_types.h"
+#include "os_blas.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+mkldnn_status_t extended_sgemm(const char *transa, const char *transb,
+ const int *M, const int *N, const int *K, const float *alpha,
+ const float *A, const int *lda, const float *B, const int *ldb,
+ const float *beta, float *C, const int *ldc,
+ const float *bias = nullptr, bool force_jit_gemm = false);
+
+template <typename b_dt>
+mkldnn_status_t gemm_s8x8s32(const char *transa, const char *transb,
+ const char *offsetc, const int *M, const int *N, const int *K,
+ const float *alpha, const int8_t *A, const int *lda, const int8_t *ao,
+ const b_dt *B, const int *ldb, const int8_t *bo, const float *beta,
+ int32_t *c, const int *ldc, const int32_t *co);
+
+#ifdef USE_CBLAS
+#define GEMM_IMPL_STR "gemm:blas"
+#else
+#define GEMM_IMPL_STR "gemm:jit"
+#endif
+
+#if USE_MKL_IGEMM
+#define IGEMM_S8U8S32_IMPL_STR "igemm_s8u8s32:blas"
+#define IGEMM_S8S8S32_IMPL_STR "igemm_s8s8s32:blas"
+#else
+#define IGEMM_S8U8S32_IMPL_STR "igemm_s8u8s32:jit"
+#define IGEMM_S8S8S32_IMPL_STR "igemm_s8s8s32:jit"
+#endif
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/os_blas.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/os_blas.hpp
new file mode 100644
index 0000000000..4d34ede0bd
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/os_blas.hpp
@@ -0,0 +1,86 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef OS_BLAS_HPP
+#define OS_BLAS_HPP
+
+/** \file
+ * Common stuff respecting USE_MKL and USE_CBLAS compile flags
+ *
+ * USE_MKL USE_CBLAS effect
+ * ------- --------- ------
+ * yes yes normal compile: jit *may* be preferred over Intel(R) MKL CBLAS
+ * yes no jit calls OK; assert if cblas is ever called
+ * no yes system-dependent CBLAS
+ * no no gemm convolution (or other blas) N/A; create stubs
+ */
+
+#if defined(USE_MKL)
+
+#include "mkl_version.h"
+
+#define USE_MKL_PACKED_GEMM (INTEL_MKL_VERSION >= 20190001)
+#define USE_MKL_IGEMM \
+ (INTEL_MKL_VERSION >= 20180000 && __INTEL_MKL_BUILD_DATE >= 20170628)
+
+#include "mkl_cblas.h"
+#if !defined(USE_CBLAS)
+#define cblas_sgemm(...) assert(!"CBLAS is unavailable")
+#endif
+
+#else /* defined(USE_MKL) */
+
+#define USE_MKL_PACKED_GEMM 0
+#define USE_MKL_IGEMM 0
+
+#if defined(_SX)
+/* TODO: _SX should also define USE_CBLAS in case the later is available */
+extern "C" {
+#include "cblas.h" // CHECK: does SX also have a fortran API sgemm?
+}
+
+#elif defined(USE_CBLAS)
+#include "cblas.h" // Maybe a system/cmake cblas works for you?
+#else
+/* put the stubs to make a code compilable but not workable */
+#define cblas_sgemm(...) assert(!"CBLAS is unavailable")
+#endif /* defined(_SX) */
+
+#endif /* defined(USE_MKL) */
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+#if defined(USE_MKL) && defined(USE_CBLAS)
+typedef MKL_INT cblas_int;
+
+#elif defined(USE_CBLAS)
+typedef int cblas_int;
+
+#if defined(_SX)
+/* this cblas.h is peculiar... */
+typedef CBLAS_ORDER CBLAS_LAYOUT;
+#endif
+#endif
+
+}
+}
+}
+
+#endif /* OS_BLAS_HPP */
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/common.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/common.hpp
new file mode 100644
index 0000000000..dde72f4a17
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/common.hpp
@@ -0,0 +1,206 @@
+/*******************************************************************************
+* Copyright 2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#define GEMM_CODE_SIZE (4096L * 32)
+
+#define AVX512_UNROLL_M 48
+#define AVX512_UNROLL_N 8
+#define AVX512_UNROLL_K 1
+#define AVX512_BM 9984
+#define AVX512_BN 384
+#define AVX512_BK 768
+#define AVX512_BK_VNNI 1536
+#define AVX512_BK_TRADITIONAL 384
+#define AVX512_BLOCKING_SMALL_K 48
+#define AVX512_BN_SMALL_K 24
+
+
+#define PAGESIZE 4096
+
+#define PADD_BYTESIZE_ONPAGE(x, size) (((x) * (size) + PAGESIZE - 1) / PAGESIZE) * PAGESIZE
+#define NEXT_THR_STRIDE(x, size) (PADD_BYTESIZE_ONPAGE(x, size)) / size
+
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+enum {
+ PARTITION_1D_ROW,
+ PARTITION_1D_COL,
+ PARTITION_2D_COL_MAJOR,
+ PARTITION_2D = PARTITION_2D_COL_MAJOR,
+};
+
+enum {
+ COPY_NONE,
+ COPY_A,
+};
+
+enum {
+ NO_OFFSET,
+ FIX_OFFSET,
+ COL_OFFSET,
+ ROW_OFFSET,
+};
+
+// Alias for any dimension related variable.
+typedef long long int dim_t;
+
+typedef struct {
+ // Interface arguments.
+ int transa, transb, offsetc;
+ dim_t m, n, k;
+ dim_t lda, ldb, ldc;
+ const int8_t *a;
+ const uint8_t *b;
+ int32_t *c;
+ const float *alpha, *beta;
+
+ int8_t ao, bo;
+ const int32_t *co;
+
+ // Kernel parameters.
+ dim_t um, un, uk, bm, bn, bk;
+ dim_t bn_small_k, bk_traditional, blocking_small_k;
+
+ int (*copyA)(const dim_t *m, const dim_t *n, const int8_t *a,
+ const dim_t *lda, const int8_t *alpha, int8_t *b,
+ const dim_t *dummy1, const dim_t *dummy2, int32_t *row_col_sum);
+
+ int (*copyB)(const dim_t *m, const dim_t *n, const uint8_t *a,
+ const dim_t *lda, const uint8_t *alpha, uint8_t *b,
+ const dim_t *dummy1, const dim_t *dummy2, int32_t *row_col_sum);
+
+ int (*kernel)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ int (*kernel_b)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ int (*kernel_r)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ int (*kernel_c)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ int (*kernel_b0)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ int (*kernel_b0_b)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ int (*kernel_b0_r)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ int (*kernel_b0_c)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ // Gemv kernels
+ void (*gemv_s8u8s32_kernel)(const dim_t, const dim_t, const float,
+ const int8_t*, const dim_t, const uint8_t*,
+ const float, int32_t*);
+
+ void (*gemv_u8s8s32_kernel)(const dim_t, const dim_t, const float,
+ const uint8_t*, const dim_t, const int8_t*,
+ const float, int32_t*);
+
+ // Gemv parameters
+ int swap;
+
+} blas_t;
+
+
+class jit_avx512_core_u8_copy_an_kern : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_u8_copy_an_kern);
+
+ public:
+ jit_avx512_core_u8_copy_an_kern();
+};
+
+class jit_avx512_core_u8_copy_at_kern : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_u8_copy_at_kern);
+
+ public:
+ jit_avx512_core_u8_copy_at_kern();
+};
+
+class jit_avx512_core_u8_copy_bn_kern : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_u8_copy_bn_kern);
+
+ public:
+ jit_avx512_core_u8_copy_bn_kern();
+};
+
+class jit_avx512_core_u8_copy_bt_kern : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_u8_copy_bt_kern);
+
+ public:
+ jit_avx512_core_u8_copy_bt_kern();
+};
+
+class jit_avx512_core_u8_copy_sum_an_kern : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_u8_copy_sum_an_kern);
+
+ public:
+ jit_avx512_core_u8_copy_sum_an_kern();
+};
+
+class jit_avx512_core_u8_copy_sum_at_kern : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_u8_copy_sum_at_kern);
+
+ public:
+ jit_avx512_core_u8_copy_sum_at_kern();
+};
+
+class jit_avx512_core_u8_copy_sum_bn_kern : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_u8_copy_sum_bn_kern);
+
+ public:
+ jit_avx512_core_u8_copy_sum_bn_kern();
+};
+
+class jit_avx512_core_u8_copy_sum_bt_kern : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_u8_copy_sum_bt_kern);
+
+ public:
+ jit_avx512_core_u8_copy_sum_bt_kern();
+};
+
+}
+}
+}
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/gemv.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/gemv.hpp
new file mode 100644
index 0000000000..db9dd9ef97
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/gemv.hpp
@@ -0,0 +1,28 @@
+/*******************************************************************************
+* Copyright 2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "common.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+int gemm_s8u8s32_jump_to_gemv_s8u8s32(blas_t *arg);
+int gemv_threading_driver(blas_t *arg);
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32.cpp
new file mode 100644
index 0000000000..e4b8e1cde2
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32.cpp
@@ -0,0 +1,1409 @@
+/*******************************************************************************
+* Copyright 2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <cstdint>
+#include <mutex>
+
+#include "common.hpp"
+#include "mkldnn_types.h"
+#include "nstl.hpp"
+#include "utils.hpp"
+
+#include "jit_avx512_core_gemm_s8u8s32.hpp"
+#include "jit_avx512_core_gemm_s8u8s32_kern.hpp"
+#include "jit_avx512_core_kernel_gemv_s8u8s32_kern.hpp"
+#include "gemv.hpp"
+
+#if defined(_MSC_VER)
+#include <malloc.h>
+#endif
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+typedef struct {
+ int nthrs_m, nthrs_n;
+ int partition;
+ int copy_type;
+} blas_thread_t;
+
+static inline void round_to_nearest(int32_t *rounded_val, double fp_val) {
+ if (fp_val >= 0.) {
+ fp_val += 0.5;
+ if (fp_val > INT32_MAX) {
+ fp_val = INT32_MAX;
+ }
+ } else {
+ fp_val -= 0.5;
+ if (fp_val < INT32_MIN) {
+ fp_val = INT32_MIN;
+ }
+ }
+ *rounded_val = (int32_t) fp_val;
+}
+
+static inline void add_results(const dim_t m, const dim_t n, const dim_t k,
+ const float alpha, const float beta, const int32_t *c_partial_sum,
+ const dim_t ldcp, int32_t *c_data, const dim_t ldc,
+ const int32_t *a_row_sum, const int32_t *b_col_sum, const int8_t ao,
+ const int8_t bo, const int32_t *co, const int offsetc)
+{
+ for (dim_t j = 0; j < n; ++j) {
+ for (dim_t i = 0; i < m; ++i) {
+ int32_t ctemp = c_partial_sum[i + j * ldcp];
+
+ if (alpha == 1.0f) {
+ if (beta == 0.0f) {
+ c_data[i + j * ldc] = ctemp;
+ } else {
+ double c_float = (double) beta
+ * (double) c_data[i + j * ldc];
+ c_float += (double) ctemp;
+ round_to_nearest(&c_data[i + j * ldc], c_float);
+ }
+ } else if (alpha == -1.0f) {
+ if (beta == 0.0f) {
+ c_data[i + j * ldc] = -ctemp;
+ } else {
+ double c_float = (double) beta
+ * (double) c_data[i + j * ldc];
+ c_float -= (double) ctemp;
+ round_to_nearest(&c_data[i + j * ldc], c_float);
+ }
+ } else {
+ if (beta == 0.0f) {
+ double c_float = alpha * (double) ctemp;
+ round_to_nearest(&c_data[i + j * ldc], c_float);
+ } else {
+ double c_float = alpha * (double) ctemp +
+ beta * (double) c_data[i + j * ldc];
+ round_to_nearest(&c_data[i + j * ldc], c_float);
+ }
+ }
+
+ if (offsetc == FIX_OFFSET) {
+ c_data[i + j * ldc] += co[0];
+ } else if (offsetc == ROW_OFFSET) {
+ c_data[i + j * ldc] += co[j];
+ } else if (offsetc == COL_OFFSET) {
+ c_data[i + j * ldc] += co[i];
+ }
+ }
+ }
+}
+
+// TODO Find a better place for those functions.
+static inline dim_t ld_padd(const dim_t x)
+{
+ return ((x + ((2048 / sizeof(int32_t)) - 1)) / (2048 / sizeof(int32_t)))
+ * (2048 / sizeof(int32_t)) + (64 / sizeof(int32_t));
+}
+
+void igemm_inner_kernel(const dim_t m, const dim_t n, const dim_t k,
+ const int8_t *a, const uint8_t *b, float beta, int32_t *c,
+ const dim_t ldc, const int32_t *a_row_sum, const int32_t *b_col_sum,
+ const int32_t *co, const int offsetc, const blas_t *arg)
+{
+ int8_t ao = arg->ao;
+ int8_t bo = arg->bo;
+ int32_t co_0 = (offsetc == NO_OFFSET)? 0 : co[0];
+
+ // Since m and n are limited by blocking, stack overflow may not happen;
+ // it's up to 32kB
+#if !defined(_MSC_VER)
+ int32_t col_offset[m];
+ int32_t row_offset[n];
+#else
+ int32_t *col_offset = (int32_t *) _alloca(sizeof(*col_offset) * m);
+ int32_t *row_offset = (int32_t *) _alloca(sizeof(*row_offset) * n);
+#endif
+
+ int col_req = 0;
+ int row_req = 0;
+
+ if ((bo != 0) || (offsetc == COL_OFFSET))
+ col_req = 1;
+ if ((ao != 0) || (offsetc == ROW_OFFSET))
+ row_req = 1;
+
+ // It needs one of colum or row offsets, but it doesn't need both
+ if (((ao != 0) && (bo != 0)) || ((offsetc == FIX_OFFSET) && (co_0 != 0))) {
+ if ((col_req == 0) && (row_req == 0)) {
+ if (m <= n) {
+ col_req = 1;
+ } else {
+ row_req = 1;
+ }
+ }
+ }
+
+ if (col_req) {
+ for (dim_t i = 0; i < m; i++)
+ col_offset[i] = 0;
+
+ if (offsetc == COL_OFFSET) {
+ for (dim_t i = 0; i < m; i++)
+ col_offset[i] += co[i];
+ }
+
+ if (bo != 0) {
+ for (dim_t i = 0; i < m; i++)
+ col_offset[i] += bo * a_row_sum[i];
+ }
+ }
+
+ if (row_req) {
+ for (dim_t i = 0; i < n; i++)
+ row_offset[i] = 0;
+
+ if (offsetc == ROW_OFFSET) {
+ for (dim_t i = 0; i < n; i++)
+ row_offset[i] += co[i];
+ }
+
+ if (ao != 0) {
+ for (dim_t i = 0; i < n; i++)
+ row_offset[i] += ao * b_col_sum[i];
+ }
+ }
+
+ if ((offsetc == FIX_OFFSET) && (co_0 != 0)) {
+ if (col_req) {
+ for (dim_t i = 0; i < m; i++)
+ col_offset[i] += co_0;
+ } else {
+ for (dim_t i = 0; i < n; i++)
+ row_offset[i] += co_0;
+ }
+ }
+
+ if ((ao != 0) && (bo != 0)) {
+ if (col_req) {
+ for (dim_t i = 0; i < m; i++)
+ col_offset[i] += (int32_t) k * ao * bo;
+ } else {
+ for (dim_t i = 0; i < n; i++)
+ row_offset[i] += (int32_t) k * ao * bo;
+ }
+ }
+
+ if (col_req == 0) {
+ if (row_req == 0) {
+ if (beta == 0.0) {
+ arg->kernel_b0(&m, &n, &k, NULL, a, b, c, ldc, col_offset,
+ row_offset);
+ } else {
+ arg->kernel(&m, &n, &k, NULL, a, b, c, ldc, col_offset,
+ row_offset);
+ }
+ } else {
+ if (beta == 0.0) {
+ arg->kernel_b0_r(&m, &n, &k, NULL, a, b, c, ldc, col_offset,
+ row_offset);
+ } else {
+ arg->kernel_r(&m, &n, &k, NULL, a, b, c, ldc, col_offset,
+ row_offset);
+ }
+ }
+ } else {
+ if (row_req == 0) {
+ if (beta == 0.0) {
+ arg->kernel_b0_c(&m, &n, &k, NULL, a, b, c, ldc, col_offset,
+ row_offset);
+ } else {
+ arg->kernel_c(&m, &n, &k, NULL, a, b, c, ldc, col_offset,
+ row_offset);
+ }
+ } else {
+ if (beta == 0.0) {
+ arg->kernel_b0_b(&m, &n, &k, NULL, a, b, c, ldc, col_offset,
+ row_offset);
+ } else {
+ arg->kernel_b(&m, &n, &k, NULL, a, b, c, ldc, col_offset,
+ row_offset);
+ }
+ }
+ }
+}
+
+static inline void *align(void *ptr, size_t alignment)
+{
+ return (void *) utils::rnd_up((uintptr_t) ptr, alignment);
+}
+
+static int gemm_kernel_driver(const dim_t m, const dim_t n, const dim_t k,
+ const int8_t *a, const uint8_t *b, int32_t *c, const int32_t *co,
+ const blas_t *arg)
+{
+ dim_t lda = arg->lda;
+ dim_t ldb = arg->ldb;
+ dim_t ldc = arg->ldc;
+ int8_t ao = arg->ao;
+ int8_t bo = arg->bo;
+ float alpha = *arg->alpha;
+ float beta = *arg->beta;
+
+ if (m <= 0 || n <= 0) {
+ return 0;
+ }
+
+ // Padding along K dimension.
+ dim_t k_padd = 0;
+ if (k <= arg->bk_traditional) {
+ k_padd = utils::rnd_up(k, arg->uk);
+ k_padd = nstl::max(128LL, k_padd);
+ } else if (k < 2 * arg->bk) {
+ k_padd = utils::rnd_up(k / 2, arg->uk);
+ } else {
+ k_padd = arg->bk;
+ }
+
+ // Padding along M dimension.
+ dim_t m_padd = utils::rnd_up(nstl::min(nstl::max(m, arg->um), arg->bm),
+ arg->um);
+
+ // Padding along N dimension.
+ dim_t n_padd = 0;
+ if (k < arg->blocking_small_k) {
+ n_padd = utils::rnd_up(nstl::min(nstl::max(n, arg->un),
+ arg->bn_small_k), arg->un);
+ } else {
+ n_padd = utils::rnd_up(nstl::min(nstl::max(n, arg->un), arg->bn),
+ arg->un);
+ }
+
+ // Padding for temporary buffer for C
+ dim_t ldc_buf = ld_padd(m_padd);
+
+ dim_t strideAm = (arg->transa == 0)? 1 : lda;
+ dim_t strideAn = (arg->transa != 0)? 1 : lda;
+ dim_t strideBm = (arg->transb == 0)? 1 : ldb;
+ dim_t strideBn = (arg->transb != 0)? 1 : ldb;
+
+ size_t a_buf_nelems = m_padd * k_padd;
+ size_t b_buf_nelems = k_padd * n_padd;
+ size_t a_row_sum_nelems = m_padd;
+ size_t b_col_sum_nelems = n_padd;
+
+ size_t mem_size = a_buf_nelems * sizeof(*a) + PAGE_4K
+ + b_buf_nelems * sizeof(*b) + PAGE_4K
+ + a_row_sum_nelems * sizeof(*c) + PAGE_4K
+ + b_col_sum_nelems * sizeof(*c) + PAGE_4K;
+
+ bool need_c_buffer = alpha != 1.0f || (beta != 1 && beta != 0);
+ if (need_c_buffer) {
+ size_t c_buf_nelems = ldc_buf * n_padd;
+ mem_size += c_buf_nelems * sizeof(*c) + PAGE_4K;
+ }
+
+ char *mem = (char *) malloc(mem_size, 128);
+
+ if (!mem) {
+ return -1;
+ }
+
+ int8_t *bufferA = (int8_t *) align(mem, PAGE_4K);
+ uint8_t *bufferB = (uint8_t *) align(bufferA + a_buf_nelems, PAGE_4K);
+ int32_t *a_row_sum = (int32_t *) align(bufferB + b_buf_nelems, PAGE_4K);
+ int32_t *b_col_sum = (int32_t *) align(a_row_sum + a_row_sum_nelems,
+ PAGE_4K);
+
+ int32_t *bufferC = NULL;
+ if (need_c_buffer) {
+ bufferC = (int32_t *) align(b_col_sum + b_col_sum_nelems, PAGE_4K);
+ }
+
+ float beta_saved = beta;
+
+ int a_block_copied = 0;
+ dim_t sizeM = 0;
+ for (dim_t Bm = 0; Bm < m; Bm += sizeM) {
+ sizeM = m - Bm;
+ if (sizeM > m_padd)
+ sizeM = m_padd;
+
+ dim_t sizeK = 0;
+ for (dim_t Bk = 0; Bk < k; Bk += sizeK) {
+ sizeK = k - Bk;
+ if (sizeK > k_padd)
+ sizeK = k_padd;
+
+ // Scale C blocks by beta only for the first time
+ if (Bk == 0)
+ beta = beta_saved;
+ else
+ beta = 1.0f;
+
+ // Apply C offset when to the last k-block of the partial sum.
+ int offsetc = NO_OFFSET;
+ if (Bk + sizeK == k)
+ offsetc = arg->offsetc;
+
+ dim_t sizeN = 0;
+ for (dim_t Bn = 0; Bn < n; Bn += sizeN) {
+ sizeN = n - Bn;
+ if (sizeN > n_padd)
+ sizeN = n_padd;
+
+ const uint8_t *b_block = b + Bk * strideBm + Bn * strideBn;
+ arg->copyB(&sizeK, &sizeN, b_block, &ldb, NULL, bufferB, NULL,
+ NULL, b_col_sum);
+
+ dim_t sizeUM = 0;
+ for (dim_t Um = 0; Um < sizeM; Um += sizeUM) {
+ sizeUM = sizeM - Um;
+ if (sizeUM > arg->um)
+ sizeUM = arg->um;
+
+ /*
+ * Use the whole A buffer only if we have multiple B blocks
+ * for k-dimension, otherwise we are wasting cache to store
+ * B and C blocks.
+ */
+ dim_t Um_forA = 0;
+ if (sizeN < n)
+ Um_forA = Um;
+
+ const int8_t *a_block = a + (Bm + Um) * strideAm
+ + Bk * strideAn;
+ if (!a_block_copied) {
+ arg->copyA(&sizeK, &sizeUM, a_block, &lda, NULL,
+ bufferA + Um_forA * sizeK, NULL, NULL,
+ a_row_sum + Um_forA);
+ }
+
+ int32_t *c_block = c + (Bm + Um) + Bn * ldc;
+ dim_t co_stride = 0;
+ if (offsetc == FIX_OFFSET) {
+ co_stride = 0;
+ } else if (offsetc == ROW_OFFSET) {
+ co_stride = Bn;
+ } else if (offsetc == COL_OFFSET) {
+ co_stride = Bm + Um;
+ }
+ if (need_c_buffer) {
+ igemm_inner_kernel(sizeUM, sizeN, sizeK,
+ bufferA + Um_forA * sizeK, bufferB, 0.0f,
+ bufferC + Um, ldc_buf, a_row_sum + Um_forA,
+ b_col_sum, NULL, NO_OFFSET, arg);
+
+ // Finish the block adding the necessary alpha, beta
+ // and offsets.
+ add_results(sizeUM, sizeN, sizeK, alpha, beta,
+ bufferC + Um, ldc_buf, c_block, ldc,
+ a_row_sum + Um_forA, b_col_sum, ao, bo,
+ co + co_stride, offsetc);
+ } else {
+ igemm_inner_kernel(sizeUM, sizeN, sizeK,
+ bufferA + Um_forA * sizeK, bufferB, beta,
+ c_block, ldc, a_row_sum + Um_forA, b_col_sum,
+ co + co_stride, offsetc, arg);
+ }
+ }
+ a_block_copied = 1;
+ }
+ a_block_copied = 0;
+ }
+ }
+
+ free(mem);
+
+ return 0;
+}
+
+static int kernel_driver_parallel_acopiedbcopy(const dim_t m, const dim_t n,
+ const dim_t k, const int8_t *bufferA, const uint8_t *b,
+ const float beta, int32_t *c, const int offsetc, const int32_t *co,
+ const int32_t *a_row_sum, const blas_t *arg)
+{
+ dim_t ldb = arg->ldb;
+ dim_t ldc = arg->ldc;
+ int8_t ao = arg->ao;
+ int8_t bo = arg->bo;
+ float alpha = *arg->alpha;
+
+ if (m <= 0 || n <= 0) {
+ return 0;
+ }
+
+ // Padding along N dimension.
+ dim_t n_padd = 0;
+ if (k < arg->blocking_small_k) {
+ n_padd = utils::rnd_up(nstl::min(nstl::max(n, arg->un),
+ arg->bn_small_k), arg->un);
+ } else {
+ n_padd = utils::rnd_up(nstl::min(nstl::max(n, arg->un), arg->bn),
+ arg->un);
+ }
+
+ // Padding for temporary buffer for C
+ dim_t ldc_buf = ld_padd(m);
+
+ dim_t strideBn = (arg->transb != 0)? 1 : ldb;
+
+ size_t b_buf_nelems = k * n_padd;
+ size_t b_col_sum_nelems = n_padd;
+
+ size_t mem_size = b_buf_nelems * sizeof(*b) + PAGE_4K
+ + b_col_sum_nelems * sizeof(*c) + PAGE_4K;
+
+ bool need_c_buffer = alpha != 1.0f || (beta != 1 && beta != 0);
+ if (need_c_buffer) {
+ size_t c_buf_nelems = ldc_buf * n_padd;
+ mem_size += c_buf_nelems * sizeof(*c) + PAGE_4K;
+ }
+
+ char *mem = (char *) malloc(mem_size, 128);
+
+ if (!mem) {
+ return -1;
+ }
+
+ uint8_t *bufferB = (uint8_t *) align(mem, PAGE_4K);
+ int32_t *b_col_sum = (int32_t *) align(bufferB + b_buf_nelems, PAGE_4K);
+
+ int32_t *bufferC = NULL;
+ if (need_c_buffer) {
+ bufferC = (int32_t *) align(b_col_sum + b_col_sum_nelems, PAGE_4K);
+ }
+
+ dim_t sizeN = 0;
+ for (dim_t Bn = 0; Bn < n; Bn += sizeN) {
+ sizeN = n - Bn;
+ if (sizeN > n_padd)
+ sizeN = n_padd;
+
+ // Implement the kernel here.
+ const uint8_t *b_block = b + Bn * strideBn;
+ arg->copyB(&k, &sizeN, b_block, &ldb, NULL, bufferB, NULL, NULL,
+ b_col_sum);
+
+ dim_t co_stride = 0;
+ if (offsetc == FIX_OFFSET) {
+ co_stride = 0;
+ } else if (offsetc == ROW_OFFSET) {
+ co_stride = Bn;
+ } else if (offsetc == COL_OFFSET) {
+ co_stride = 0;
+ }
+ int32_t *c_block = c + Bn * ldc;
+ if (need_c_buffer) {
+ igemm_inner_kernel(m, sizeN, k, bufferA, bufferB, 0.0f, bufferC,
+ ldc_buf, a_row_sum, b_col_sum, NULL, NO_OFFSET, arg);
+
+ // Finish the block adding the necessary alpha, beta and offsets.
+ add_results(m, sizeN, k, alpha, beta, bufferC, ldc_buf, c_block,
+ ldc, a_row_sum, b_col_sum, ao, bo, co + co_stride,
+ offsetc);
+ } else {
+ igemm_inner_kernel(m, sizeN, k, bufferA, bufferB, beta, c_block,
+ ldc, a_row_sum, b_col_sum, co + co_stride, offsetc, arg);
+ }
+ }
+
+ free(mem);
+
+ return 0;
+
+}
+
+#define N2D_MAX_AVX512 384
+#define M2D_MIN_AVX512 384
+#define VECLEN 16
+#define NCONS 1
+static inline void set_thread_opts_avx512(int *p_nthrs,
+ blas_thread_t *thread_info, const blas_t *arg)
+{
+ int nthrs = *p_nthrs;
+ dim_t m = arg->m;
+ dim_t n = arg->n;
+
+ thread_info->nthrs_m = 0;
+ thread_info->nthrs_n = 0;
+ thread_info->copy_type = COPY_NONE; // By default don't do parallel copy.
+
+ int condition_2D_bsrc = -1;
+ if ((256 * m > nthrs * n) && (nthrs * m < 256 * n)) {
+ condition_2D_bsrc = 1;
+ } else {
+ condition_2D_bsrc = 0;
+ }
+
+ int condition_1D_copya = 0;
+ if ((m >= 1000) && (n >= nthrs * N2D_MAX_AVX512 / 4)) {
+ condition_2D_bsrc = 0;
+ condition_1D_copya = 1;
+ }
+
+ // If offset is non-zero, we need to keep 1D_copya to reduce update overhead
+ if (arg->ao != 0 || arg->bo != 0 || arg->co[0] != 0
+ || arg->offsetc != FIX_OFFSET) {
+ condition_2D_bsrc = 0;
+ condition_1D_copya = 1;
+ }
+
+ if (condition_2D_bsrc == 1) {
+ int nthrs_m = 1;
+ int nthrs_n = nthrs;
+
+ while ((nthrs_n % 2 == 0) &&
+ (n / nthrs > N2D_MAX_AVX512 ||
+ n / nthrs_n <= N2D_MAX_AVX512 / 2) &&
+ (m / nthrs_m >= 2 * M2D_MIN_AVX512) &&
+ (nthrs_m < 4)) {
+ nthrs_m *= 2;
+ nthrs_n /= 2;
+ }
+
+ thread_info->nthrs_m = nthrs_m;
+ thread_info->nthrs_n = nthrs_n;
+ thread_info->partition = PARTITION_2D;
+
+ // Reset the total number of threads that will be used.
+ *p_nthrs = nthrs_m * nthrs_n;
+
+ } else if (condition_1D_copya && mkldnn_thr_syncable()) {
+ // Use parallel copy A algorithm
+ thread_info->copy_type = COPY_A;
+ thread_info->partition = PARTITION_1D_COL;
+ } else {
+ if ((m > n) && (m / nthrs >= VECLEN || n < NCONS * nthrs)) {
+ thread_info->partition = PARTITION_1D_ROW;
+ } else {
+ thread_info->partition = PARTITION_1D_COL;
+ }
+ }
+}
+#undef N2D_MAX_AVX512
+#undef M2D_MIN_AVX512
+#undef VECLEN
+#undef NCONS
+
+static inline void partition_1d(const int ithr, const int nthrs, const dim_t n,
+ dim_t *t_offset, dim_t *t_block)
+{
+ dim_t band = n / nthrs;
+
+ dim_t tail = n - (nthrs - 1) * band;
+ if (tail > (band + 1))
+ band++;
+ tail = n - (nthrs - 1) * band;
+
+ if (ithr < (nthrs - 1))
+ *t_block = band;
+ else
+ *t_block = tail;
+
+ *t_offset = ithr * band;
+
+ if (*t_offset >= n) {
+ *t_block = 0;
+ *t_offset = 0;
+ } else if ((*t_offset + *t_block) > n) {
+ *t_block = n - *t_offset;
+ }
+}
+
+static inline void partition_2d(const int ithr, int *nthrs, const int ithr_i,
+ const int ithr_j, const int nthrs_m, const int nthrs_n, const dim_t m,
+ const dim_t n, dim_t *p_m_disp, dim_t *p_m_band, dim_t *p_n_disp,
+ dim_t *p_n_band)
+{
+ dim_t m_disp = 0, n_disp = 0;
+ dim_t m_band = 0, n_band = 0;
+
+ int mdiv = nthrs_m;
+ int ndiv = nthrs_n;
+
+ dim_t m_bandt = m / mdiv; /* size per thread */
+ dim_t n_bandt = n / ndiv; /* size per thread */
+ int firstmgroup = mdiv - 1;
+ int firstngroup = ndiv - 1;
+ dim_t firstmval = m_bandt;
+ dim_t firstnval = n_bandt;
+
+ int mthr_used = mdiv;
+ if (m - (mdiv - 1) * m_bandt > m_bandt + 1) {
+ if (m - (mdiv - 1) * m_bandt > mdiv)
+ ++m_bandt;
+
+ firstmval = m_bandt + 1;
+ mthr_used = (int) (m / firstmval);
+
+ if (mthr_used * firstmval < m)
+ ++mthr_used;
+
+ firstmgroup = mthr_used - 1;
+ }
+
+ int nthr_used = ndiv;
+ if (n - (ndiv - 1) * n_bandt > n_bandt + 1) {
+ firstnval = n_bandt + 1;
+ nthr_used = (int) (n / firstnval);
+
+ if (nthr_used * firstnval < n)
+ ++nthr_used;
+
+ firstngroup = nthr_used - 1;
+ }
+
+ *nthrs = mthr_used * nthr_used;
+
+ if (ithr < *nthrs) {
+ if (ithr_i < firstmgroup) {
+ m_band = firstmval;
+ m_disp = ithr_i * firstmval;
+ } else if (ithr_i <= mthr_used - 2) {
+ m_band = m_bandt;
+ m_disp = firstmgroup * firstmval + (ithr_i - firstmgroup) * m_bandt;
+ } else {
+ m_disp = firstmgroup * firstmval
+ + (mthr_used - 1 - firstmgroup) * m_bandt;
+ m_band = nstl::max(0LL, m - m_disp);
+ }
+
+ if (ithr_j < firstngroup) {
+ n_band = firstnval;
+ n_disp = ithr_j * firstnval;
+ } else if (ithr_j <= nthr_used - 2) {
+ n_band = n_bandt;
+ n_disp = firstngroup * firstnval + (ithr_j - firstngroup) * n_bandt;
+ } else {
+ n_disp = firstngroup * firstnval
+ + (nthr_used - 1 - firstngroup) * n_bandt;
+ n_band = nstl::max(0LL, n - n_disp);
+ }
+ m_disp = nstl::max(nstl::min(m_disp, m - 1), 0LL);
+ n_disp = nstl::max(nstl::min(n_disp, n - 1), 0LL);
+ }
+
+ if (ithr < *nthrs) {
+ *p_m_disp = m_disp;
+ *p_n_disp = n_disp;
+ *p_m_band = m_band;
+ *p_n_band = n_band;
+ } else {
+ *p_m_disp = 0;
+ *p_n_disp = 0;
+ *p_m_band = 0;
+ *p_n_band = 0;
+ }
+
+ return;
+}
+
+static inline void decompose_matrices(const int ithr, int *nthrs, dim_t *m,
+ dim_t *n, dim_t *k, const int8_t **a, const uint8_t **b, int32_t **c,
+ const int32_t **co, const blas_thread_t *thread_info, const blas_t *arg)
+{
+ dim_t strideAm = (arg->transa == 0)? 1 : arg->lda;
+ dim_t strideBn = (arg->transb != 0)? 1 : arg->ldb;
+ int offsetc = arg->offsetc;
+
+ switch (thread_info->partition) {
+ case PARTITION_1D_ROW:
+ {
+ dim_t offset = 0;
+ dim_t block = 0;
+ partition_1d(ithr, *nthrs, arg->m, &offset, &block);
+
+ *m = block;
+ *n = arg->n;
+ *k = arg->k;
+
+ // Set matrix A.
+ *a = arg->a + offset * strideAm;
+
+ // Set matrix B.
+ *b = arg->b;
+
+ // Set matrix C.
+ *c = arg->c + offset;
+
+ // Set offset vector for C matrix
+ dim_t co_stride = 0;
+ if (offsetc == FIX_OFFSET) {
+ co_stride = 0;
+ } else if (offsetc == ROW_OFFSET) {
+ co_stride = 0;
+ } else if (offsetc == COL_OFFSET) {
+ co_stride = offset;
+ }
+ *co = arg->co + co_stride;
+ break;
+ }
+
+ case PARTITION_1D_COL:
+ {
+ dim_t offset = 0;
+ dim_t block = 0;
+ partition_1d(ithr, *nthrs, arg->n, &offset, &block);
+
+ *m = arg->m;
+ *n = block;
+ *k = arg->k;
+
+ // Set matrix A.
+ *a = arg->a;
+
+ // Set matrix B.
+ *b = arg->b + offset * strideBn;
+
+ // Set matrix C.
+ *c = arg->c + offset * arg->ldc;
+
+ // Set offset vector for C matrix
+ dim_t co_stride = 0;
+ if (offsetc == FIX_OFFSET) {
+ co_stride = 0;
+ } else if (offsetc == ROW_OFFSET) {
+ co_stride = offset;
+ } else if (offsetc == COL_OFFSET) {
+ co_stride = 0;
+ }
+ *co = arg->co + co_stride;
+ break;
+ }
+
+ case PARTITION_2D_COL_MAJOR:
+ {
+ int nthrs_m = thread_info->nthrs_m;
+ int nthrs_n = thread_info->nthrs_n;
+ int ithr_i = ithr % nthrs_m;
+ int ithr_j = ithr / nthrs_m;
+
+ dim_t m_disp = 0;
+ dim_t m_band = 0;
+ dim_t n_disp = 0;
+ dim_t n_band = 0;
+
+ partition_2d(ithr, nthrs, ithr_i, ithr_j, nthrs_m, nthrs_n,
+ arg->m, arg->n, &m_disp, &m_band, &n_disp, &n_band);
+
+ *m = m_band;
+ *n = n_band;
+ *k = arg->k;
+
+ // Set matrix A.
+ *a = arg->a + m_disp * strideAm;
+
+ // Set matrix B.
+ *b = arg->b + n_disp * strideBn;
+
+ // Set matrix C.
+ *c = arg->c + m_disp + n_disp * arg->ldc;
+
+ // Set offset vector for C matrix
+ dim_t co_stride = 0;
+ if (offsetc == FIX_OFFSET) {
+ co_stride = 0;
+ } else if (offsetc == ROW_OFFSET) {
+ co_stride = n_disp;
+ } else if (offsetc == COL_OFFSET) {
+ co_stride = m_disp;
+ }
+ *co = arg->co + co_stride;
+ break;
+ }
+ }
+}
+
+#define MULTIPLIER 10
+static int parallel_a_copy(const int ithr, const int nthrs, const dim_t m,
+ const dim_t n, const dim_t k, const int8_t *a, const uint8_t *b,
+ int32_t *c, const int32_t *co, const blas_t *arg,
+ char **p_shared_mem)
+{
+ const dim_t lda = arg->lda;
+ const dim_t ldb = arg->ldb;
+ const dim_t strideAm = (arg->transa == 0)? 1 : lda;
+ const dim_t strideAn = (arg->transa != 0)? 1 : lda;
+ const dim_t strideBm = (arg->transb == 0)? 1 : ldb;
+
+ // Padding along M dimension.
+ dim_t m_padd = utils::rnd_up(nstl::min(nstl::max(m, arg->um), arg->bm),
+ arg->um);
+
+ // Padding along K dimension.
+ dim_t k_padd = 0;
+ if (k <= arg->bk_traditional) {
+ k_padd = utils::rnd_up(k, arg->uk);
+ k_padd = nstl::max(128LL, k_padd);
+ } else if (k < 2 * arg->bk) {
+ k_padd = utils::rnd_up(k / 2, arg->uk);
+ } else {
+ k_padd = arg->bk;
+ }
+
+ m_padd *= nthrs > MULTIPLIER ? MULTIPLIER : nthrs;
+ if (m_padd > m) {
+ m_padd = utils::rnd_up(m, arg->um);
+ }
+
+ size_t a_buf_nelems = m_padd * k_padd;
+
+ // Allocate shared memory for A and its row sum buffers in master thread.
+ if (ithr == 0) { // If thread master
+ size_t a_row_sum_nelems = m_padd;
+
+ size_t mem_size = (a_buf_nelems * sizeof(*a) + PAGE_4K)
+ + a_row_sum_nelems * sizeof(*c) + PAGE_4K;
+
+ *p_shared_mem = (char *) malloc(mem_size, 128);
+
+ }
+ mkldnn_thr_barrier();
+
+ char *mem = *p_shared_mem;
+ int8_t *bufferA = (int8_t *) align(mem, PAGE_4K);
+ int32_t *a_row_sum = (int32_t *) align(bufferA + a_buf_nelems, PAGE_4K);
+
+ if (!mem) {
+ return -1;
+ }
+
+ int result = 0; // Return status
+
+ dim_t sizeK = 0;
+ for (dim_t Bk = 0; Bk < k; Bk += sizeK) {
+ sizeK = k - Bk;
+ if (sizeK > k_padd)
+ sizeK = k_padd;
+
+ // Scale C blocks by beta only for the first term of partial sum.
+ float beta = 1.0f;
+ if (Bk == 0)
+ beta = *(arg->beta);
+
+ // Apply C offset for the last k-block of the partial sum.
+ int offsetc = NO_OFFSET;
+ if (Bk + sizeK == k)
+ offsetc = arg->offsetc;
+
+ dim_t sizeM = 0;
+ for (dim_t Bm = 0; Bm < m; Bm += sizeM) {
+ sizeM = m - Bm;
+ if (sizeM > m_padd)
+ sizeM = m_padd;
+
+ if (ithr < nthrs) {
+ dim_t band = (sizeM + nthrs - 1) / nthrs;
+ band = utils::rnd_up(band, arg->um);
+
+ dim_t offset = band * ithr;
+
+ // If offset is too large don't use that thread for copying.
+ if (offset >= sizeM) {
+ offset = 0;
+ band = 0;
+ }
+
+ // Handle the tail of the copy.
+ if (offset + band > sizeM) {
+ band = sizeM - offset;
+ }
+
+ if (band > 0) {
+ const int8_t *a_block = a + (Bm + offset) * strideAm
+ + Bk * strideAn;
+ arg->copyA(&sizeK, &band, a_block, &lda, NULL,
+ bufferA + offset * sizeK, NULL, NULL,
+ a_row_sum + offset);
+ }
+ }
+ mkldnn_thr_barrier(); // Wait for finishing parallel copy.
+
+ const uint8_t *b_block = b + Bk * strideBm;
+ int32_t *c_block = c + Bm;
+ dim_t co_stride = 0;
+ if (offsetc == FIX_OFFSET) {
+ co_stride = 0;
+ } else if (offsetc == ROW_OFFSET) {
+ co_stride = 0;
+ } else if (offsetc == COL_OFFSET) {
+ co_stride = Bm;
+ }
+
+ result = kernel_driver_parallel_acopiedbcopy(sizeM, n, sizeK,
+ bufferA, b_block, beta, c_block, offsetc, co + co_stride,
+ a_row_sum, arg);
+
+ mkldnn_thr_barrier(); // Wait for kernel computations to finish.
+ }
+ }
+
+ // Free memory allocated in master thread
+ if (ithr == 0) {
+ free(mem);
+ }
+
+ return result;
+}
+#undef MULTIPLIER
+
+static inline void get_omp_thread_count(dim_t m, dim_t n, dim_t k,
+ double fp_per_cycle, int *nthrs)
+{
+ double omp_overhead_small_core = 3.0e+3;
+ double omp_intercept_big_core = 4.0e+3;
+ double omp_slope_big_core = 5.0e+2;
+
+ double gemm_cycles = 8.0 * m * n * k / fp_per_cycle;
+
+ int i = *nthrs;
+
+ // Use a different model for omp overheads if nthrs is <= 4
+ if (*nthrs <= 4 && omp_overhead_small_core > 0) {
+ double omp_cycles = omp_overhead_small_core;
+ if (gemm_cycles < omp_cycles) {
+ *nthrs = 1;
+ return;
+ } else {
+ while (i > 1) {
+ if (omp_cycles * i < gemm_cycles * (i - 1)) break;
+ --i;
+ }
+ }
+ } else {
+ if (gemm_cycles < (omp_intercept_big_core + 2 * omp_slope_big_core)) {
+ *nthrs = 1;
+ return;
+ }
+
+ // adaptive decrement to march faster·
+ while (i > 1) {
+ double omp_cycles = omp_intercept_big_core + i * omp_slope_big_core;
+ if (omp_cycles * i < gemm_cycles * (i - 1))
+ break;
+
+ if (i < 10)
+ i -= 2;
+ else if (i < 30)
+ i -= 4;
+ else
+ i -= 8;
+ }
+ }
+
+ if (i < 1)
+ i = 1;
+
+ *nthrs = i;
+}
+
+#define CACHE_LINE_SIZE 64
+static int gemm_threading_driver(blas_t *arg)
+{
+ if ((arg->m <= 0) || (arg->n <= 0))
+ return mkldnn_success;
+
+ if (gemm_s8u8s32_jump_to_gemv_s8u8s32(arg)) {
+ return mkldnn_success;
+ }
+
+ int nthr = (mkldnn_in_parallel()) ? 1 : mkldnn_get_max_threads();
+ get_omp_thread_count(arg->m, arg->n, arg->k, 64.0, &nthr);
+
+ if (nthr == 1) {
+ return gemm_kernel_driver(arg->m, arg->n, arg->k, arg->a, arg->b,
+ arg->c, arg->co, arg);
+ }
+
+ int *results = (int *) malloc(sizeof(*results) * nthr * CACHE_LINE_SIZE,
+ PAGE_4K);
+
+ if (!results) {
+ return -1;
+ }
+
+ for (int i = 0; i < nthr; i++) {
+ results[i * CACHE_LINE_SIZE] = 0; // Initialize to success
+ }
+
+ char *shared_mem = NULL;
+
+ parallel(nthr, [&](const int ithr, const int nthr) {
+ int nthrs = nthr;
+ if (nthrs == 1) {
+ results[0] = gemm_kernel_driver(arg->m, arg->n, arg->k, arg->a,
+ arg->b, arg->c, arg->co, arg);
+ } else {
+ blas_thread_t thread_info;
+ set_thread_opts_avx512(&nthrs, &thread_info, arg);
+
+ const int8_t *a = NULL;
+ const uint8_t *b = NULL;
+ int32_t *c = NULL;
+ const int32_t *co = NULL;
+ dim_t m = -1;
+ dim_t n = -1;
+ dim_t k = -1;
+ decompose_matrices(ithr, &nthrs, &m, &n, &k, &a, &b, &c, &co,
+ &thread_info, arg);
+
+ if (ithr < nthrs) {
+ switch (thread_info.copy_type) {
+ case COPY_A:
+ results[ithr * CACHE_LINE_SIZE] =
+ parallel_a_copy(ithr, nthrs, m, n, k, a, b, c, co, arg,
+ &shared_mem);
+ break;
+
+ default:
+ case COPY_NONE:
+ results[ithr * CACHE_LINE_SIZE] =
+ gemm_kernel_driver(m, n, k, a, b, c, co, arg);
+ break;
+ }
+ }
+ }
+ });
+
+ int result = 0; // Initialize to success
+ for (int i = 0; i < nthr; i++) {
+ if (results[i] != 0) {
+ result = results[i * CACHE_LINE_SIZE];
+ break;
+ }
+ }
+
+ free(results);
+
+ return result;
+}
+#undef CACHE_LINE_SIZE
+
+static jit_avx512_core_u8_copy_an_kern *copy_an;
+static jit_avx512_core_u8_copy_at_kern *copy_at;
+static jit_avx512_core_u8_copy_bn_kern *copy_bn;
+static jit_avx512_core_u8_copy_bt_kern *copy_bt;
+static jit_avx512_core_u8_copy_sum_an_kern *copy_sum_an;
+static jit_avx512_core_u8_copy_sum_at_kern *copy_sum_at;
+static jit_avx512_core_u8_copy_sum_bn_kern *copy_sum_bn;
+static jit_avx512_core_u8_copy_sum_bt_kern *copy_sum_bt;
+static jit_avx512_core_gemm_s8u8s32_kern *kernel;
+static jit_avx512_core_gemm_s8u8s32_kern *kernel_b;
+static jit_avx512_core_gemm_s8u8s32_kern *kernel_r;
+static jit_avx512_core_gemm_s8u8s32_kern *kernel_c;
+static jit_avx512_core_gemm_s8u8s32_kern *kernel_b0;
+static jit_avx512_core_gemm_s8u8s32_kern *kernel_b0_b;
+static jit_avx512_core_gemm_s8u8s32_kern *kernel_b0_r;
+static jit_avx512_core_gemm_s8u8s32_kern *kernel_b0_c;
+static jit_avx512_core_gemv_s8u8s32_kern *gemv_s8u8s32_kernel;
+static jit_avx512_core_gemv_s8u8s32_kern *gemv_u8s8s32_kernel;
+
+static void jit_init(blas_t *arg)
+{
+ static int (*copyAn)(const dim_t *m, const dim_t *n, const int8_t *a,
+ const dim_t *lda, const int8_t *alpha, int8_t *b,
+ const dim_t *dummy1, const dim_t *dummy2, int32_t *row_col_sum);
+
+ static int (*copyAt)(const dim_t *m, const dim_t *n, const int8_t *a,
+ const dim_t *lda, const int8_t *alpha, int8_t *b,
+ const dim_t *dummy1, const dim_t *dummy2, int32_t *row_col_sum);
+
+ static int (*copyBn)(const dim_t *m, const dim_t *n, const uint8_t *a,
+ const dim_t *lda, const uint8_t *alpha, uint8_t *b,
+ const dim_t *dummy1, const dim_t *dummy2, int32_t *row_col_sum);
+
+ static int (*copyBt)(const dim_t *m, const dim_t *n, const uint8_t *a,
+ const dim_t *lda, const uint8_t *alpha, uint8_t *b,
+ const dim_t *dummy1, const dim_t *dummy2, int32_t *row_col_sum);
+
+ static int (*copySumAn)(const dim_t *m, const dim_t *n, const int8_t *a,
+ const dim_t *lda, const int8_t *alpha, int8_t *b,
+ const dim_t *dummy1, const dim_t *dummy2, int32_t *row_col_sum);
+
+ static int (*copySumAt)(const dim_t *m, const dim_t *n, const int8_t *a,
+ const dim_t *lda, const int8_t *alpha, int8_t *b,
+ const dim_t *dummy1, const dim_t *dummy2, int32_t *row_col_sum);
+
+ static int (*copySumBn)(const dim_t *m, const dim_t *n, const uint8_t *a,
+ const dim_t *lda, const uint8_t *alpha, uint8_t *b,
+ const dim_t *dummy1, const dim_t *dummy2, int32_t *row_col_sum);
+
+ static int (*copySumBt)(const dim_t *m, const dim_t *n, const uint8_t *a,
+ const dim_t *lda, const uint8_t *alpha, uint8_t *b,
+ const dim_t *dummy1, const dim_t *dummy2, int32_t *row_col_sum);
+
+ static int (*kern)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ static int (*kern_b)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ static int (*kern_r)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ static int (*kern_c)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ static int (*kern_b0)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ static int (*kern_b0_b)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ static int (*kern_b0_r)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ static int (*kern_b0_c)(const dim_t *m, const dim_t *n, const dim_t *k,
+ const float *alpha, const int8_t *a, const uint8_t *b, int32_t *c,
+ const dim_t ldc, const int32_t *col_offset,
+ const int32_t *row_offset);
+
+ static void (*gemv_s8u8s32_kern)(const dim_t, const dim_t, const float,
+ const int8_t*, const dim_t, const uint8_t*,
+ const float, int32_t*);
+
+ static void (*gemv_u8s8s32_kern)(const dim_t, const dim_t, const float,
+ const uint8_t*, const dim_t, const int8_t*,
+ const float, int32_t*);
+
+ if (mayiuse(avx512_core_vnni)) {
+ arg->um = AVX512_UNROLL_M;
+ arg->un = AVX512_UNROLL_N;
+ arg->uk = AVX512_UNROLL_K;
+ arg->bm = AVX512_BM;
+ arg->bn = AVX512_BN;
+ arg->bk = AVX512_BK_VNNI;
+
+ arg->bk_traditional = AVX512_BK_TRADITIONAL;
+ arg->bn_small_k = AVX512_BN_SMALL_K;
+ arg->blocking_small_k = AVX512_BLOCKING_SMALL_K;
+ } else {
+ arg->um = AVX512_UNROLL_M;
+ arg->un = AVX512_UNROLL_N;
+ arg->uk = AVX512_UNROLL_K;
+ arg->bm = AVX512_BM;
+ arg->bn = AVX512_BN;
+ arg->bk = AVX512_BK;
+
+ arg->bk_traditional = AVX512_BK_TRADITIONAL;
+ arg->bn_small_k = AVX512_BN_SMALL_K;
+ arg->blocking_small_k = AVX512_BLOCKING_SMALL_K;
+ }
+
+ static std::once_flag initialized;
+ std::call_once(initialized, []{
+
+ copy_an = new jit_avx512_core_u8_copy_an_kern();
+ copy_at = new jit_avx512_core_u8_copy_at_kern();
+ copy_bn = new jit_avx512_core_u8_copy_bn_kern();
+ copy_bt = new jit_avx512_core_u8_copy_bt_kern();
+
+ copy_sum_an = new jit_avx512_core_u8_copy_sum_an_kern();
+ copy_sum_at = new jit_avx512_core_u8_copy_sum_at_kern();
+ copy_sum_bn = new jit_avx512_core_u8_copy_sum_bn_kern();
+ copy_sum_bt = new jit_avx512_core_u8_copy_sum_bt_kern();
+
+ kernel = new jit_avx512_core_gemm_s8u8s32_kern(false, false, false);
+ kernel_b = new jit_avx512_core_gemm_s8u8s32_kern(false, true, true);
+ kernel_r = new jit_avx512_core_gemm_s8u8s32_kern(false, false, true);
+ kernel_c = new jit_avx512_core_gemm_s8u8s32_kern(false, true, false);
+ kernel_b0 = new jit_avx512_core_gemm_s8u8s32_kern(true, false, false);
+ kernel_b0_b = new jit_avx512_core_gemm_s8u8s32_kern(true, true, true);
+ kernel_b0_r = new jit_avx512_core_gemm_s8u8s32_kern(true, false, true);
+ kernel_b0_c = new jit_avx512_core_gemm_s8u8s32_kern(true, true, false);
+
+ gemv_s8u8s32_kernel = new jit_avx512_core_gemv_s8u8s32_kern();
+ gemv_u8s8s32_kernel = new jit_avx512_core_gemv_s8u8s32_kern();
+
+
+ copyAn = copy_an->getCode<int (*)(const dim_t *, const dim_t *,
+ const int8_t *, const dim_t *, const int8_t *, int8_t *,
+ const dim_t *, const dim_t *, int32_t *)>();
+
+ copyAt = copy_at->getCode<int (*)(const dim_t *, const dim_t *,
+ const int8_t *, const dim_t *, const int8_t *, int8_t *,
+ const dim_t *, const dim_t *, int32_t *)>();
+
+ copyBn = copy_bn->getCode<int (*)(const dim_t *, const dim_t *,
+ const uint8_t *, const dim_t *, const uint8_t *, uint8_t *,
+ const dim_t *, const dim_t *, int32_t *)>();
+
+ copyBt = copy_bt->getCode<int (*)(const dim_t *, const dim_t *,
+ const uint8_t *, const dim_t *, const uint8_t *, uint8_t *,
+ const dim_t *, const dim_t *, int32_t *)>();
+
+ copySumAn = copy_sum_an->getCode<int (*)(const dim_t *, const dim_t *,
+ const int8_t *, const dim_t *, const int8_t *, int8_t *,
+ const dim_t *, const dim_t *, int32_t *)>();
+
+ copySumAt = copy_sum_at->getCode<int (*)(const dim_t *, const dim_t *,
+ const int8_t *, const dim_t *, const int8_t *, int8_t *,
+ const dim_t *, const dim_t *, int32_t *)>();
+
+ copySumBn = copy_sum_bn->getCode<int (*)(const dim_t *, const dim_t *,
+ const uint8_t *, const dim_t *, const uint8_t *, uint8_t *,
+ const dim_t *, const dim_t *, int32_t *)>();
+
+ copySumBt = copy_sum_bt->getCode<int (*)(const dim_t *, const dim_t *,
+ const uint8_t *, const dim_t *, const uint8_t *, uint8_t *,
+ const dim_t *, const dim_t *, int32_t *)>();
+
+ kern = kernel->getCode<int (*)(const dim_t *, const dim_t *,
+ const dim_t *, const float *, const int8_t *, const uint8_t *,
+ int32_t *, const dim_t, const int32_t *, const int32_t *)>();
+
+ kern_b = kernel_b->getCode<int (*)(const dim_t *, const dim_t *,
+ const dim_t *, const float *, const int8_t *, const uint8_t *,
+ int32_t *, const dim_t, const int32_t *, const int32_t *)>();
+
+ kern_r = kernel_r->getCode<int (*)(const dim_t *, const dim_t *,
+ const dim_t *, const float *, const int8_t *, const uint8_t *,
+ int32_t *, const dim_t, const int32_t *, const int32_t *)>();
+
+ kern_c = kernel_c->getCode<int (*)(const dim_t *, const dim_t *,
+ const dim_t *, const float *, const int8_t *, const uint8_t *,
+ int32_t *, const dim_t, const int32_t *, const int32_t *)>();
+
+ kern_b0 = kernel_b0->getCode<int (*)(const dim_t *, const dim_t *,
+ const dim_t *, const float *, const int8_t *, const uint8_t *,
+ int32_t *, const dim_t, const int32_t *, const int32_t *)>();
+
+ kern_b0_b = kernel_b0_b->getCode<int (*)(const dim_t *, const dim_t *,
+ const dim_t *, const float *, const int8_t *, const uint8_t *,
+ int32_t *, const dim_t, const int32_t *, const int32_t *)>();
+
+ kern_b0_r = kernel_b0_r->getCode<int (*)(const dim_t *, const dim_t *,
+ const dim_t *, const float *, const int8_t *, const uint8_t *,
+ int32_t *, const dim_t, const int32_t *, const int32_t *)>();
+
+ kern_b0_c = kernel_b0_c->getCode<int (*)(const dim_t *, const dim_t *,
+ const dim_t *, const float *, const int8_t *, const uint8_t *,
+ int32_t *, const dim_t, const int32_t *, const int32_t *)>();
+
+ gemv_s8u8s32_kern =
+ gemv_s8u8s32_kernel -> generate<jit_avx512_core_gemv_s8u8s32_kern::gemv_s8u8s32_kernel_t>
+ (mayiuse(avx512_core_vnni));
+ gemv_u8s8s32_kern =
+ gemv_u8s8s32_kernel -> generate<jit_avx512_core_gemv_s8u8s32_kern::gemv_u8s8s32_kernel_t>
+ (mayiuse(avx512_core_vnni));
+ });
+
+ if (arg->bo == 0) { // No need to compute A row sum if bo is zero
+ if (arg->transa == 0) {
+ arg->copyA = copyAn;
+ } else {
+ arg->copyA = copyAt;
+ }
+ } else {
+ if (arg->transa == 0) {
+ arg->copyA = copySumAn;
+ } else {
+ arg->copyA = copySumAt;
+ }
+ }
+
+ if (arg->ao == 0) { // No need to compute B column sum if ao is zero
+ if (arg->transb == 0) {
+ arg->copyB = copyBn;
+ } else {
+ arg->copyB = copyBt;
+ }
+ } else {
+ if (arg->transb == 0) {
+ arg->copyB = copySumBn;
+ } else {
+ arg->copyB = copySumBt;
+ }
+ }
+
+ arg->kernel = kern;
+ arg->kernel_b = kern_b;
+ arg->kernel_r = kern_r;
+ arg->kernel_c = kern_c;
+ arg->kernel_b0 = kern_b0;
+ arg->kernel_b0_b = kern_b0_b;
+ arg->kernel_b0_r = kern_b0_r;
+ arg->kernel_b0_c = kern_b0_c;
+ arg -> gemv_s8u8s32_kernel = gemv_s8u8s32_kern;
+ arg -> gemv_u8s8s32_kernel = gemv_u8s8s32_kern;
+}
+
+mkldnn_status_t jit_avx512_core_gemm_s8u8s32(
+ const char *transA, const char *transB, const char *offsetC,
+ const int *m, const int *n, const int *k,
+ const float *alpha, const int8_t *a, const int *lda, const int8_t *oa,
+ const uint8_t *b, const int *ldb, const int8_t *ob,
+ const float *beta, int32_t *c, const int *ldc, const int32_t *oc)
+{
+ char transa = *transA;
+ char transb = *transB;
+ char offsetc = *offsetC;
+
+ blas_t args;
+
+ // Initialize blas structure
+ args.m = *m;
+ args.n = *n;
+ args.k = *k;
+ args.alpha = alpha;
+ args.a = a;
+ args.lda = *lda;
+ args.b = b;
+ args.ldb = *ldb;
+ args.beta = beta;
+ args.c = c;
+ args.ldc = *ldc;
+ args.transa = (transa == 'N' || transa == 'n') ? 0 : 1;
+ args.transb = (transb == 'N' || transb == 'n') ? 0 : 1;
+ args.um = 0;
+ args.un = 0;
+ args.bm = 0;
+ args.bn = 0;
+ args.bk = 0;
+ args.copyA = NULL;
+ args.copyB = NULL;
+ args.kernel = NULL;
+ args.kernel_b0 = NULL;
+ args.ao = *oa;
+ args.bo = *ob;
+ args.co = oc;
+
+ if (offsetc == 'F' || offsetc == 'f') {
+ args.offsetc = FIX_OFFSET;
+ } else if (offsetc == 'R' || offsetc == 'r') {
+ args.offsetc = ROW_OFFSET;
+ } else { // offsetc == 'C' || offsetc == 'c'
+ args.offsetc = COL_OFFSET;
+ }
+
+ jit_init(&args);
+ int result = gemm_threading_driver(&args);
+
+ return (result < 0) ? mkldnn_out_of_memory : mkldnn_success;
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32.hpp
new file mode 100644
index 0000000000..b2e2902a12
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32.hpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_AVX512_CORE_GEMM_S8U8S32_HPP
+#define JIT_AVX512_CORE_GEMM_S8U8S32_HPP
+
+#include <cstdint>
+#include "mkldnn_types.h"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+mkldnn_status_t jit_avx512_core_gemm_s8u8s32(
+ const char *transA, const char *transB, const char *offsetC,
+ const int *m, const int *n, const int *k,
+ const float *alpha, const int8_t *a, const int *lda, const int8_t *oa,
+ const uint8_t *b, const int *ldb, const int8_t *ob,
+ const float *beta, int32_t *c, const int *ldc, const int32_t *oc);
+
+}
+}
+}
+
+#endif // JIT_AVX512_CORE_GEMM_S8U8S32_HPP
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32_kern.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32_kern.cpp
new file mode 100644
index 0000000000..57554a1852
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32_kern.cpp
@@ -0,0 +1,539 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "jit_avx512_core_gemm_s8u8s32_kern.hpp"
+
+
+#ifdef _WIN32
+static const bool is_windows = 1;
+#else
+static const bool is_windows = 0;
+#endif
+
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace Xbyak;
+
+
+
+
+// Convert between vector register lengths.
+static inline Xmm make_xmm(const Xmm &v) { return Xmm(v.getIdx()); }
+static inline Ymm make_ymm(const Xmm &v) { return Ymm(v.getIdx()); }
+
+// Load from or store to C.
+void jit_avx512_core_gemm_s8u8s32_kern::c_load(const Xbyak::Xmm &dst,
+ const Xbyak::Address &src, int nelems)
+{
+ switch (nelems) {
+ default: vmovups(dst, src); break;
+ case 8: vmovups(make_ymm(dst), src); break;
+ case 4: vmovups(make_xmm(dst), src); break;
+ case 2: vmovlps(make_xmm(dst), src); break;
+ case 1: vmovss(make_xmm(dst), src); break;
+ }
+}
+void jit_avx512_core_gemm_s8u8s32_kern::c_store(const Xbyak::Address &dst,
+ const Xbyak::Xmm &src, int nelems)
+{
+ switch (nelems) {
+ default: vmovups(dst, src); break;
+ case 8: vmovups(dst, make_ymm(src)); break;
+ case 4: vmovups(dst, make_xmm(src)); break;
+ case 2: vmovsd(dst, make_xmm(src)); break;
+ case 1: vmovss(dst, make_xmm(src)); break;
+ }
+}
+
+// Perform length-4 dot product accumulations of unsigned and signed bytes
+// in parallel.
+// Use vpdpbusd if VNNI available, otherwise emulate.
+void jit_avx512_core_gemm_s8u8s32_kern::dot_product(const Xmm &dst,
+ const Xmm &src1, const Xmm &src2)
+{
+ if (vnni)
+ vpdpbusd(dst, src1, src2);
+ else {
+ vpmaddubsw(dp_scratch, src1, src2);
+ vpmaddwd(dp_scratch, ones, dp_scratch);
+ vpaddd(dst, dst, dp_scratch);
+ }
+}
+
+// Inner kernel.
+void jit_avx512_core_gemm_s8u8s32_kern::kernel_loop(int unroll_m, int unroll_n,
+ bool cfetch)
+{
+ int um_vecs = (unroll_m + 15) >> 4;
+ Label label_kernel_loop;
+
+ L_aligned(label_kernel_loop); {
+ for (int h = 0; h < 4; h++) {
+ for (int j = 0; j < unroll_n; j++) {
+ const Zmm b = b_regs[j & 1];
+
+ vpbroadcastd(b, ptr[BO + isize *
+ (2 * j + 2 * h * unroll_n - offset_b)]);
+ dot_product(c_regs[0][j], b, a_regs[0]);
+
+ if (j == 1 && !(h & 1))
+ prefetch_b(ptr[BO + isize * (prefetch_size_b
+ + 2 * h * unroll_n - offset_b)]);
+ else if (j % 3 == 0)
+ prefetch_a(ptr[AO + isize * (prefetch_size_a
+ + 32 * (j / 3) + 2 * h * unroll_m - offset_a)]);
+
+ for (int i = 1; i < um_vecs; i++)
+ dot_product(c_regs[i][j], b, a_regs[i]);
+
+ if (cfetch && (j == std::min(1, unroll_n - 1))) {
+ if (h == 3)
+ lea(CO2, ptr[CO2 + LDC]);
+ else if (h < um_vecs)
+ prefetch_c(ptr[CO2 + (16 * h * size)]);
+ }
+
+ if (h == 3 && j == std::min(3, unroll_n - 1))
+ lea(AA, ptr[AA + (32 * isize)]);
+ }
+
+ for (int i = 0; i < um_vecs; i++)
+ vmovups(a_regs[i], ptr[AO + isize *
+ (32 * i + 2 * (h + 1) * unroll_m - offset_a)]);
+
+ if (h == 2)
+ prefetch_x(ptr[AA - (offset_a * isize)]);
+ }
+
+ add(AO, 8 * isize * unroll_m);
+ add(BO, 8 * isize * unroll_n);
+ sub(LoopCount, 1);
+ jg(label_kernel_loop, T_NEAR);
+ }
+}
+
+// k remainder loop for kernel.
+void jit_avx512_core_gemm_s8u8s32_kern::remainder_kernel(int unroll_m,
+ int unroll_n, int unroll_k, int bwidth)
+{
+ if ((unroll_m > IGEMM_UNROLL_M) || (unroll_n > IGEMM_UNROLL_N)
+ || (unroll_m < 0) || (unroll_n < 0))
+ return;
+
+ int um_vecs = (unroll_m + 15) >> 4;
+
+ for (int h = 0; h < unroll_k; h++) {
+ for (int j = 0; j < unroll_n; j++) {
+ Zmm b = b_regs[j & 1];
+ auto b_src = ptr[BO + (-isize * offset_b
+ + bwidth * (j + h * unroll_n))];
+
+ switch (bwidth) {
+ case 4:
+ vpbroadcastd(b, b_src);
+ break;
+ case 2:
+ vpbroadcastw(b, b_src);
+ break;
+ case 1:
+ vpbroadcastb(b, b_src);
+ break;
+ }
+ for (int i = 0; i < um_vecs; i++)
+ dot_product(c_regs[i][j], b, a_regs[i]);
+ }
+
+ if (unroll_k > 1) {
+ for (int i = 0; i < um_vecs; i++)
+ vmovups(a_regs[i], ptr[AO + isize * (32 * i
+ + (h + 1) * 2 * unroll_m - offset_a)]);
+ }
+ }
+
+ add(AO, unroll_k * unroll_m * bwidth);
+ add(BO, unroll_k * unroll_n * bwidth);
+}
+
+// Inner loop.
+void jit_avx512_core_gemm_s8u8s32_kern::innerloop(int unroll_m, int unroll_n)
+{
+ if ((unroll_m > IGEMM_UNROLL_M) || (unroll_n > IGEMM_UNROLL_N)
+ || (unroll_m < 0) || (unroll_n < 0))
+ return;
+
+ int um_vecs = (unroll_m + 15) >> 4;
+ int stage1 = unroll_n, stage2 = unroll_n;
+
+ Label label_kernel_loop_1, label_k_main_loop_2, label_kernel_loop_2;
+ Label label_k_main_loop_3, label_kernel_loop_3;
+ Label label_k_remainder_loop_begin, label_k_rem_4, label_k_rem_2;
+ Label label_k_rem_1, label_update_begin;
+
+ mov(AO, A);
+ for (int i = 0; i < um_vecs; i++)
+ vmovups(a_regs[i], ptr[AO + isize * (32 * i - offset_a)]);
+
+ mov(LoopCount, K);
+ sar(LoopCount, 4);
+ jle(label_k_remainder_loop_begin, T_NEAR);
+
+ // Main k loops, broken into three parts to time C prefetching.
+ sub(LoopCount, stage1 + stage2);
+ jle(label_k_main_loop_2, T_NEAR);
+
+ kernel_loop(unroll_m, unroll_n, false);
+
+ L_aligned(label_k_main_loop_2);
+ lea(CO2, ptr[CO1 + size * (std::min(unroll_m, 16) - 1)]);
+ add(LoopCount, stage1);
+ jle(label_k_main_loop_3, T_NEAR);
+
+ kernel_loop(unroll_m, unroll_n, true);
+
+ L_aligned(label_k_main_loop_3);
+ lea(CO2, ptr[CO1 + size * (std::min(unroll_m, 16) - 1)]);
+ add(LoopCount, stage2);
+ jle(label_k_remainder_loop_begin, T_NEAR);
+
+ kernel_loop(unroll_m, unroll_n, true);
+
+ // k remainder handling
+ L_aligned(label_k_remainder_loop_begin);
+ mov(LoopCount, K);
+ test(LoopCount, 8);
+ je(label_k_rem_4, T_NEAR);
+
+ remainder_kernel(unroll_m, unroll_n, 2, 4);
+
+ L_aligned(label_k_rem_4);
+ mov(LoopCount, K);
+ test(LoopCount, 4);
+ je(label_k_rem_2, T_NEAR);
+
+ remainder_kernel(unroll_m, unroll_n, 1, 4);
+
+ L_aligned(label_k_rem_2);
+ mov(LoopCount, K);
+ test(LoopCount, 2);
+ je(label_k_rem_1, T_NEAR);
+
+ Zmm zero = zmm6;
+ Zmm tmp = zmm5;
+
+ vpxorq(zero, zero, zero);
+ for (int i = 0; i < um_vecs; i++) {
+ Zmm a = a_regs[i];
+ vbroadcasti64x4(a, ptr[AO + isize * (16 * i - offset_a)]);
+ vpunpcklwd(tmp, a, zero);
+ vpunpckhwd(a, a, zero);
+ vshufi32x4(a, tmp, a, 0x44);
+ vshufi32x4(a, a, a, 0xD8);
+ }
+
+ remainder_kernel(unroll_m, unroll_n, 1, 2);
+
+ L_aligned(label_k_rem_1);
+ mov(LoopCount, K);
+ test(LoopCount, 1);
+ je(label_update_begin, T_NEAR);
+
+ vpxorq(zero, zero, zero);
+ for (int i = 0; i < um_vecs; i++) {
+ Zmm a = a_regs[i];
+ vbroadcasti32x4(a, ptr[AO + isize * (8 * i - offset_a)]);
+ vpunpcklbw(tmp, a, zero);
+ vpunpckhbw(a, a, zero);
+ vinsertf128(make_ymm(a), make_ymm(tmp), make_xmm(a), 1);
+ vpunpcklwd(tmp, a, zero);
+ vpunpckhwd(a, a, zero);
+ vshufi32x4(a, tmp, a, 0x44);
+ vshufi32x4(a, a, a, 0xD8);
+ }
+
+ remainder_kernel(unroll_m, unroll_n, 1, 1);
+
+ // Add offsets and update C.
+ L_aligned(label_update_begin);
+
+ if (enable_offset_r) {
+ // Add row offsets.
+ mov(rax, coffset_ry);
+ for (int j = 0; j < unroll_n; j++) {
+ Zmm row_offset = zmm0;
+
+ vbroadcastss(row_offset, ptr[rax + size * j]);
+
+ for (int i = 0; i < um_vecs; i++)
+ vpaddd(c_regs[i][j], c_regs[i][j], row_offset);
+ }
+ add(coffset_ry, size * unroll_n);
+ }
+
+ if (enable_offset_c) {
+ // Add column offsets.
+ mov(rax, coffset_cy);
+ for (int i = 0; i < um_vecs; i++) {
+ Zmm col_offset = zmm0;
+
+ c_load(col_offset, ptr[rax + size * 16 * i], unroll_m);
+
+ for (int j = 0; j < unroll_n; j++)
+ vpaddd(c_regs[i][j], c_regs[i][j], col_offset);
+ }
+ }
+
+ Reg64 LDC3 = rax;
+ lea(LDC3, ptr[LDC + LDC * 2]);
+
+ // C updates.
+ int c_off_j = 0;
+ for (int j = 0; j < unroll_n; j++) {
+ if (j > 0 && (j & 3) == 0) {
+ lea(CO1, ptr[CO1 + LDC * 4]);
+ c_off_j += 4;
+ }
+
+ int jj = j - c_off_j;
+
+ for (int i = 0; i < um_vecs; i++) {
+ Zmm c = c_regs[i][j];
+ Zmm c_old = zmm0;
+ decltype(LDC * jj) ldc_mult = (jj == 3) ? LDC3 : LDC * jj;
+
+ auto c_mem = ptr[CO1 + ldc_mult + size * 16 * i];
+
+ if (beta_zero)
+ c_store(c_mem, c, unroll_m);
+ else {
+ c_load(c_old, c_mem, unroll_m);
+ vpaddd(c_old, c, c_old);
+ c_store(c_mem, c_old, unroll_m);
+ }
+
+ vpxorq(c, c, c);
+ }
+ }
+
+ lea(CO1, ptr[CO1 + LDC * (unroll_n - c_off_j)]);
+}
+
+// Outer loop.
+void jit_avx512_core_gemm_s8u8s32_kern::outerloop(int unroll_x, int unroll_y,
+ Label *&cur_outerloop_label)
+{
+ Label label_m_loop, label_n_loop, label_n_remainder_loops[6];
+
+ L(*cur_outerloop_label);
+ cur_outerloop_label++;
+ if (unroll_x >= IGEMM_UNROLL_M) {
+ mov(J, M);
+ cmp(J, unroll_x);
+ jl(*cur_outerloop_label, T_NEAR); // Jump to next outerloop label.
+ } else {
+ test(J, unroll_x);
+ jle(*cur_outerloop_label, T_NEAR);
+ }
+
+ L_aligned(label_m_loop); {
+ mov(CO1, C);
+ add(C, unroll_x * size);
+
+ mov(BO, B);
+
+ mov(AA, K);
+ imul(AA, AA, unroll_x * isize);
+ lea(AA, ptr[A + AA + isize * prefetch_size_a]);
+
+ if (enable_offset_c) {
+ mov(rax, coffset_cx);
+ mov(coffset_cy, rax);
+ add(rax, unroll_x * size);
+ mov(coffset_cx, rax);
+ }
+
+ if (enable_offset_r) {
+ mov(rax, coffset_rx);
+ mov(coffset_ry, rax);
+ }
+
+ mov(I, N);
+ cmp(I, unroll_y);
+ jl(label_n_remainder_loops[0], T_NEAR);
+
+ L_aligned(label_n_loop); {
+ innerloop(unroll_x, unroll_y);
+ sub(I, unroll_y);
+ cmp(I, unroll_y);
+ jge(label_n_loop, T_NEAR);
+ }
+
+ align(16);
+
+ int label_idx = 0;
+ for (int uy = 16; uy > 0; uy >>= 1) {
+ L(label_n_remainder_loops[label_idx++]);
+ if (unroll_y > uy) {
+ test(I, uy);
+ jle(label_n_remainder_loops[label_idx], T_NEAR);
+
+ innerloop(unroll_x, uy);
+ align(16);
+ }
+ }
+ L(label_n_remainder_loops[label_idx]);
+
+ mov(A, AO);
+ if (unroll_x >= IGEMM_UNROLL_M) {
+ sub(J, unroll_x);
+ cmp(J, unroll_x);
+ jge(label_m_loop);
+ }
+ }
+
+ align(16);
+}
+
+void jit_avx512_core_gemm_s8u8s32_kern::generate()
+{
+ // Prologue
+ preamble();
+ sub(rsp, stack_alloc_size);
+
+ if (is_windows) {
+ mov(A, arg_a);
+ mov(B, arg_b);
+ }
+
+ mov(C, arg_c);
+ mov(LDC, arg_ldc);
+
+ sub(A, -offset_a * isize);
+ sub(B, -offset_b * isize);
+
+ mov(M, qword[M]);
+ mov(N, qword[N]);
+ mov(K, qword[K]);
+
+ lea(LDC, ptr[LDC * size]);
+
+ if (enable_offset_c) {
+ mov(rax, arg_coffset_c);
+ mov(coffset_cx, rax);
+ }
+ if (enable_offset_r) {
+ mov(rax, arg_coffset_r);
+ mov(coffset_rx, rax);
+ }
+
+ for (int i = 0; i < (max_unroll_m >> 4); i++) {
+ for (int j = 0; j < max_unroll_n; j++) {
+ auto &c = c_regs[i][j];
+ vpxorq(c, c, c);
+ }
+ }
+
+ if (!vnni) {
+ mov(rax, 1);
+ movq(make_xmm(ones), rax);
+ vpbroadcastw(ones, make_xmm(ones));
+ }
+
+ Label outerloop_labels[8];
+ Label *cur_outerloop_label = &outerloop_labels[0];
+
+ // Main m loop.
+ outerloop(IGEMM_UNROLL_M, IGEMM_UNROLL_N, cur_outerloop_label);
+
+ // m remainder loops.
+ for (int um = 32; um > 0; um >>= 1)
+ if (IGEMM_UNROLL_M > um)
+ outerloop(um, IGEMM_UNROLL_N, cur_outerloop_label);
+
+ L(*cur_outerloop_label);
+
+ // Epilogue.
+ add(rsp, stack_alloc_size);
+ postamble();
+}
+
+
+jit_avx512_core_gemm_s8u8s32_kern::jit_avx512_core_gemm_s8u8s32_kern(bool
+ beta_zero_, bool enable_offset_c_, bool enable_offset_r_) :
+ jit_generator(nullptr, 100000), arg_a(0), arg_b(0), arg_c(0), arg_ldc(0),
+ arg_coffset_c(0), arg_coffset_r(0), coffset_cx(0), coffset_cy(0),
+ coffset_rx(0), coffset_ry(0)
+{
+ beta_zero = beta_zero_;
+ enable_offset_c = enable_offset_c_;
+ enable_offset_r = enable_offset_r_;
+ vnni = mayiuse(avx512_core_vnni);
+
+ // Assign integer registers
+ M = is_windows ? rcx : rdi;
+ N = is_windows ? rdx : rsi;
+ K = is_windows ? r8 : rdx;
+ A = is_windows ? rsi : r8;
+ B = r9;
+ C = r10;
+ LDC = r11;
+ I = r12;
+ J = r13;
+ LoopCount = rax;
+ AO = r14;
+ BO = r15;
+ CO1 = rbx;
+ CO2 = rbp;
+ AA = is_windows ? rdi : rcx;
+
+ // Assign vector registers
+ dp_scratch = zmm6;
+ ones = zmm7;
+ for (int i = 0; i < (max_unroll_m >> 4); i++)
+ a_regs[i] = Zmm(i);
+ b_regs[0] = zmm4;
+ b_regs[1] = zmm5;
+
+ int rn = 0;
+ for (int i = 0; i < (max_unroll_m >> 4); i++)
+ for (int j = 0; j < max_unroll_n; j++)
+ c_regs[i][j] = Zmm(8 + rn++);
+
+ // Assign stack variables.
+ stack_alloc_size = 32;
+ auto args_offset = stack_alloc_size + get_size_of_abi_save_regs()
+ + 8 + (is_windows ? 48 : 0);
+
+ arg_a = ptr[rsp + (args_offset - 16)];
+ arg_b = ptr[rsp + (args_offset - 8)];
+ arg_c = ptr[rsp + (args_offset + 0)];
+ arg_ldc = ptr[rsp + (args_offset + 8)];
+ arg_coffset_c = ptr[rsp + (args_offset + 16)];
+ arg_coffset_r = ptr[rsp + (args_offset + 24)];
+
+ coffset_cx = qword[rsp + 0];
+ coffset_cy = qword[rsp + 8];
+ coffset_rx = qword[rsp + 16];
+ coffset_ry = qword[rsp + 24];
+
+ generate();
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32_kern.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32_kern.hpp
new file mode 100644
index 0000000000..e8efcc1cc8
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemm_s8u8s32_kern.hpp
@@ -0,0 +1,101 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef IGEMM_KERNEL_GENERATOR_HPP
+#define IGEMM_KERNEL_GENERATOR_HPP
+
+#include "jit_generator.hpp"
+
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+class jit_avx512_core_gemm_s8u8s32_kern : public jit_generator {
+public:
+ jit_avx512_core_gemm_s8u8s32_kern(bool beta_zero_, bool enable_offset_c_,
+ bool enable_offset_r_);
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_gemm_s8u8s32_kern);
+
+protected:
+ bool beta_zero;
+ bool enable_offset_c, enable_offset_r;
+ bool vnni;
+
+ void prefetch_a(const Xbyak::Address &src) {
+ prefetcht0(src);
+ }
+ void prefetch_b(const Xbyak::Address &src) {
+ prefetcht0(src);
+ }
+ void prefetch_c(const Xbyak::Address &src) {
+ prefetchw(src);
+ }
+ void prefetch_x(const Xbyak::Address &src) {
+ prefetcht0(src);
+ }
+
+ void c_load(const Xbyak::Xmm &dst, const Xbyak::Address &src, int nelems);
+ void c_store(const Xbyak::Address &dst, const Xbyak::Xmm &src, int nelems);
+
+ void dot_product(const Xbyak::Xmm &dst, const Xbyak::Xmm &src1,
+ const Xbyak::Xmm &src2);
+ void kernel_loop(int unroll_m, int unroll_n, bool cfetch);
+ void remainder_kernel(int unroll_m, int unroll_n, int unroll_k, int bwidth);
+ void innerloop(int unroll_m, int unroll_n);
+ void outerloop(int unroll_x, int unroll_y, Xbyak::Label *&outerloop_label);
+
+ void generate();
+
+
+private:
+ static const int IGEMM_UNROLL_M = 48;
+ static const int IGEMM_UNROLL_N = 8;
+
+ static const int isize = 2;
+ static const int size = 4;
+
+ // Prefetch configuration
+ static const int prefetch_size_a = 32 * 5;
+ static const int prefetch_size_b = 32 * 4;
+
+ static const int offset_a = 256, offset_b = 256;
+ static const int max_unroll_m = 48, max_unroll_n = 8;
+
+ // Integer register assignments
+ Xbyak::Reg64 M, N, K, A, B, C, LDC, I, J, LoopCount;
+ Xbyak::Reg64 AO, BO, CO1, CO2, AA;
+
+ // Vector register assignments
+ Xbyak::Zmm dp_scratch, ones, a_regs[max_unroll_m >> 4], b_regs[2];
+ Xbyak::Zmm c_regs[max_unroll_m >> 4][max_unroll_n];
+
+ // Stack variable assignments
+ int stack_alloc_size;
+ Xbyak::Address arg_a, arg_b, arg_c, arg_ldc, arg_coffset_c, arg_coffset_r;
+ Xbyak::Address coffset_cx, coffset_cy, coffset_rx, coffset_ry;
+
+ void L_aligned(Xbyak::Label &label, int alignment = 16) {
+ align(alignment);
+ L(label);
+ }
+};
+
+}
+}
+}
+
+#endif /* header guard */
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemv_s8u8s32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemv_s8u8s32.cpp
new file mode 100644
index 0000000000..4f0b10dadd
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_gemv_s8u8s32.cpp
@@ -0,0 +1,290 @@
+/*******************************************************************************
+ * Copyright 2019 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+
+#include "gemv.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+int gemm_s8u8s32_jump_to_gemv_s8u8s32(blas_t *arg) {
+
+ blas_t arg_gemv = *arg;
+
+ if ((arg -> offsetc == FIX_OFFSET) && // Fix offset
+ (arg -> ao == 0) &&
+ (arg -> bo == 0) &&
+ (arg -> co[0] == 0) &&
+ (*(arg -> alpha) == 1.0f) &&
+ ((*(arg -> beta) == 1.0f) || *(arg -> beta) == 0.0f)) {
+
+ if (arg -> n == 1) {
+
+ if (arg -> transa == 1) { // A transpose
+ arg_gemv.n = arg -> k;
+ arg_gemv.ldc = 1;
+ arg_gemv.swap = 0;
+ if (arg -> transb == 0) { // B non transpose
+ arg_gemv.ldb = 1;
+ }
+ // B transpose arg_gemv.ldb = arg -> ldb
+ gemv_threading_driver(&arg_gemv);
+ return 1;
+ }
+ }
+
+ if (arg -> m == 1) {
+
+ if (arg -> transb == 0) { // B non transpose
+ arg_gemv.transa = 1;
+ arg_gemv.m = arg -> n;
+ arg_gemv.n = arg -> k;
+ arg_gemv.a = (int8_t *) arg -> b;
+ arg_gemv.lda = arg -> ldb;
+ arg_gemv.b = (uint8_t *) arg -> a;
+ arg_gemv.swap = 1;
+ if (arg -> transa == 0) { // A non transpose
+ arg_gemv.ldb = arg -> lda;
+ }
+ else { // A transpose
+ arg_gemv.ldb = 1;
+ }
+ gemv_threading_driver(&arg_gemv);
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+int gemv_kernel_driver(blas_t *arg) {
+
+ dim_t m = arg -> m;
+ dim_t n = arg -> n;
+ uint8_t *a = (uint8_t *) arg -> a;
+ dim_t lda = arg -> lda;
+ int8_t *b = (int8_t *) arg -> b;
+ float beta = *(arg -> beta);
+
+ if (arg -> swap) {
+ arg -> gemv_u8s8s32_kernel(m, n, 1.0f, a, lda, b, beta, arg -> c);
+ }
+ else {
+ arg -> gemv_s8u8s32_kernel(arg -> m, arg -> n, 1.0f, arg -> a,
+ arg -> lda, arg -> b, *(arg -> beta), arg -> c);
+ }
+
+ return 0;
+}
+
+int gemv_threading_driver(blas_t *arg) {
+
+ dim_t nthr_m, nthr_n = 1;
+ dim_t MB, NB, UM = 16, UN = 64;
+ dim_t BLOCKM = 192, BLOCKN = 3072;
+ int status;
+ dim_t i;
+
+ dim_t nthr = (mkldnn_in_parallel()) ? 1 : mkldnn_get_max_threads();
+
+ uint8_t *new_x = NULL;
+ int32_t *tmp_y = NULL, *new_y = NULL;
+
+ dim_t m = arg -> m, n = arg -> n;
+
+ blas_t arg_seq = *arg;
+ float zero = 0.0f;
+
+ nthr_m = std::min(std::max(m / BLOCKM, (dim_t) 1), nthr);
+ MB = m / nthr_m;
+ MB = (((MB / UM) * UM) == MB) ? MB : (MB / UM) * UM + UM;
+ nthr_m = (((m / MB) * MB) == m) ? m / MB : m / MB + 1;
+ nthr_m = std::min(std::max(nthr_m, (dim_t) 1), nthr);
+
+ while ((nthr_m * (nthr_n + 1) <= nthr) && ((n / (nthr_n + 1)) >= BLOCKN)) {
+ nthr_n++;
+ }
+
+ NB = n / nthr_n;
+ NB = (((NB / UN) * UN) == NB) ? NB : (NB / UN) * UN + UN;
+ nthr_n = (((n / NB) * NB) == n) ? n / NB : n / NB + 1;
+ nthr_n = std::min(std::max(nthr_n, (dim_t) 1), nthr / nthr_m);
+
+ nthr = nthr_m * nthr_n;
+
+ if (arg -> ldb != 1) {
+ new_x = (uint8_t *)malloc(n, 64);
+ if (new_x == NULL)
+ return 1;
+ for (i = 0; i < n; i++) {
+ new_x[i] = (arg -> b)[i * arg -> ldb];
+ }
+ arg_seq.b = new_x;
+ arg_seq.ldb = 1;
+ }
+ else new_x = (uint8_t *) arg -> b;
+
+ if (arg -> ldc != 1) {
+ new_y = (int32_t *) malloc(nthr_m * PADD_BYTESIZE_ONPAGE(MB, sizeof(int32_t)), 64);
+ if (new_y == NULL) {
+ if (arg -> ldb != 1) {
+ free(new_x);
+ }
+ return 1;
+ }
+ }
+
+ // GEMV computation
+ if (nthr == 1) {
+
+ if (arg -> ldc != 1) {
+ if (*(arg -> beta) != 0.0f) {
+ for (i = 0; i < m; i++) {
+ new_y[i] = arg -> c[i * arg -> ldc];
+ }
+ }
+ }
+
+ status = gemv_kernel_driver(&arg_seq);
+
+ if (arg -> ldc != 1) {
+ for (i = 0; i < m; i++) {
+ arg -> c[i * arg -> ldc] = new_y[i];
+ }
+ }
+
+ if (arg -> ldb != 1) {
+ free(new_x);
+ }
+ if (arg -> ldc != 1) {
+ free(new_y);
+ }
+ return status;
+ }
+
+ if (nthr_n > 1) {
+ tmp_y = (int32_t *) malloc((nthr_n - 1) * PADD_BYTESIZE_ONPAGE(m, sizeof(int32_t)), PAGESIZE);
+ if (tmp_y == NULL) {
+ if (arg -> ldb != 1) {
+ free(new_x);
+ }
+ return 1;
+ }
+ }
+
+ parallel_nd((int) nthr, [&](const dim_t ithr) {
+
+ dim_t m_from, m_to, myM;
+ dim_t n_from, n_to, myN;
+
+ dim_t n_id, m_id;
+ dim_t loc_incy = 1;
+ int32_t *loc_y;
+
+ blas_t arg_loc = arg_seq;
+ int j;
+
+ m_id = ithr / nthr_n;
+ n_id = ithr % nthr_n;
+
+ m_from = MB * m_id;
+ m_to = MB * (m_id + 1);
+ if ((m_to > m) || (m_id == nthr_m - 1))
+ m_to = m;
+
+ myM = m_to - m_from;
+
+ n_from = NB * n_id;
+ n_to = NB * (n_id + 1);
+ if ((n_to > n) || (n_id == nthr_n - 1))
+ n_to = n;
+
+ myN = n_to - n_from;
+
+ if (n_id != 0) {
+ arg_loc.beta = &zero;
+ loc_y = tmp_y + (NEXT_THR_STRIDE(m, sizeof(int32_t))) * (n_id - 1) + m_from;
+ }
+ else {
+ if (arg -> ldc == 1) {
+ loc_y = arg_seq.c + m_from;
+ }
+ else {
+ // need to copy the block of c in new_y
+ loc_y = new_y + m_id * NEXT_THR_STRIDE(MB, sizeof(int32_t));
+ if (*(arg -> beta) != 0.0f) {
+ for (j = 0; j < myM; j++) {
+ loc_y[j] = arg -> c[(m_from + j) * arg -> ldc];
+ }
+ }
+ }
+ }
+
+ arg_loc.m = myM;
+ arg_loc.n = myN;
+ arg_loc.a = arg_seq.a + m_from * arg_seq.lda + n_from;
+ arg_loc.b = arg_seq.b + n_from;
+ arg_loc.c = loc_y;
+ arg_loc.ldc = loc_incy;
+
+ gemv_kernel_driver(&arg_loc);
+
+ if ((n_id == 0) && (arg -> ldc != 1)) {
+ for (j = 0; j < myM; j++) {
+ arg -> c[(m_from + j) * arg -> ldc] = loc_y[j];
+ }
+ }
+
+ });
+
+ if (nthr_n > 1) {
+ parallel_nd((int) nthr_m, [&](const dim_t ithr) {
+
+ dim_t j, j_from, j_to, ii;
+ int32_t acc;
+
+ j_from = MB * ithr;
+ j_to = MB * (ithr + 1);
+ if ((j_to > m) || (ithr == nthr - 1))
+ j_to = m;
+
+ for (j = j_from; j < j_to; j++) {
+ acc = 0;
+ for (ii = 0; ii < nthr_n - 1; ii++) {
+ acc += tmp_y[ii * NEXT_THR_STRIDE(m, sizeof(int32_t)) + j];
+ }
+ (arg -> c)[j * arg -> ldc] += acc;
+ }
+ });
+ free(tmp_y);
+ }
+
+ if (arg -> ldb != 1) {
+ free(new_x);
+ }
+
+ if (arg -> ldc != 1) {
+ free(new_y);
+ }
+
+ return 0;
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_kernel_gemv_s8u8s32_kern.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_kernel_gemv_s8u8s32_kern.cpp
new file mode 100644
index 0000000000..c57a8c1d12
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_kernel_gemv_s8u8s32_kern.cpp
@@ -0,0 +1,411 @@
+/*******************************************************************************
+ * Copyright 2019 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+
+#include "jit_avx512_core_kernel_gemv_s8u8s32_kern.hpp"
+
+#ifdef _WIN32
+#define is_windows 1
+#else
+#define is_windows 0
+#endif
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+void jit_avx512_core_gemv_s8u8s32_kern::vnni(Xbyak::Zmm acc, Xbyak::Zmm b,
+ Xbyak::Zmm a, Xbyak::Zmm tmp,
+ Xbyak::Zmm one, bool swap,
+ int use_vnni) {
+
+ if (use_vnni) {
+ if (swap)
+ vpdpbusd(acc, a, b);
+ else
+ vpdpbusd(acc, b, a);
+ }
+
+ else {
+ if (swap)
+ vpmaddubsw(tmp, a, b);
+ else
+ vpmaddubsw(tmp, b, a);
+ vpmaddwd(tmp, tmp, one);
+ vpaddd(acc, tmp, acc);
+ }
+
+}
+
+void jit_avx512_core_gemv_s8u8s32_kern::n_loop_body(int start_a_idx, int start_acc_idx,
+ int b_idx, int nreg_acc,
+ Xbyak::Reg64 A, Xbyak::Reg64 lda,
+ Xbyak::Reg64 X, Xbyak::Zmm tmp,
+ Xbyak::Zmm one, bool swap, int use_vnni,
+ int use_mask, Xbyak::Opmask mask_n) {
+
+ int i;
+ int nreg_A = nreg_acc / 2 + (nreg_acc % 2);
+
+ // load X + j
+ if (use_mask)
+ vmovdqu8(Xbyak::Zmm(b_idx) | mask_n | T_z, ptr[X]);
+ else
+ vmovdqu8(Xbyak::Zmm(b_idx), ptr[X]);
+
+ xor_(r14, r14);
+ // load values of A
+ for (i = 0; i < nreg_A; i++) {
+ if (use_mask)
+ vmovdqu8(Xbyak::Zmm(start_a_idx + i) | mask_n | T_z, ptr[A + r14]);
+ else
+ vmovdqu8(Xbyak::Zmm(start_a_idx + i), ptr[A + r14]);
+ add(r14, lda);
+ }
+
+ for (i = 0; i < nreg_A; i++) {
+ // vnni (acc, b, a, tmp, one, swap, use_vnni)
+ vnni(Xbyak::Zmm(start_acc_idx + i), Xbyak::Zmm(b_idx),
+ Xbyak::Zmm(start_a_idx + i), tmp, one, swap, use_vnni);
+ }
+
+ for (i = 0; i < nreg_A - (nreg_acc % 2); i++) {
+ if (use_mask)
+ vmovdqu8(Xbyak::Zmm(start_a_idx + i) | mask_n | T_z, ptr[A + r14]);
+ else
+ vmovdqu8(Xbyak::Zmm(start_a_idx + i), ptr[A + r14]);
+ add(r14, lda);
+ }
+
+ for (i = 0; i < nreg_A - (nreg_acc % 2); i++) {
+ vnni(Xbyak::Zmm(start_acc_idx + i + nreg_A), Xbyak::Zmm(b_idx),
+ Xbyak::Zmm(start_a_idx + i), tmp, one, swap, use_vnni);
+ }
+
+}
+
+void jit_avx512_core_gemv_s8u8s32_kern::shuffle_and_add(Xbyak::Zmm dest, Xbyak::Zmm A,
+ Xbyak::Zmm B, Xbyak::Zmm C,
+ Xbyak::Zmm D) {
+
+ vshufi32x4(dest, A, C, 0x44);
+ vshufi32x4(A, A, C, 0xEE);
+ vpaddd(C, dest, A); // C = A0 + A2|A1 + A3|C0 + C2|C1 + C3
+
+ vshufi32x4(dest, B, D, 0x44);
+ vshufi32x4(B, B, D, 0xEE);
+ vpaddd(D, dest, B); // D = B0 + B2|B1 + B3|D0 + D2|D1 + D3
+
+ vshufi32x4(A, C, D, 0x88);
+ vshufi32x4(B, C, D, 0xDD);
+ vpaddd(dest, A, B); // dest = SAi|SBi|SCi|SDi
+
+}
+
+void jit_avx512_core_gemv_s8u8s32_kern::update_c(int nreg_acc, Xbyak::Reg64 Y,
+ int start_a_idx, int start_acc_idx,
+ Xbyak::Xmm beta, int use_mask,
+ Xbyak::Opmask mask_m) {
+
+ int l, i, k, j, last_it;
+ Xbyak::Label store_label;
+
+ l = 0;
+ for (k = 0; k < nreg_acc; k += 8) {
+ for (i = 0, j = k; i < 8; i += 4, j += 2) {
+ if (j < nreg_acc) {
+ // shuffle per block of 4 registers
+ shuffle_and_add(Xbyak::Zmm(start_a_idx + l), // dest
+ Xbyak::Zmm(start_acc_idx + j), // A = acc0
+ Xbyak::Zmm(start_acc_idx + 1 + j), // B = acc1
+ Xbyak::Zmm(start_acc_idx + 4 + j), // C = acc4
+ Xbyak::Zmm(start_acc_idx + 5 + j)); // D = acc5
+
+ // extract low and high from dest and hadd
+ vextracti32x8(Xbyak::Ymm(start_a_idx + l + 1), Xbyak::Zmm(start_a_idx + l), 0);
+ vextracti32x8(Xbyak::Ymm(start_a_idx + l + 2), Xbyak::Zmm(start_a_idx + l), 1);
+ vphaddd(Xbyak::Ymm(start_a_idx + l),
+ Xbyak::Ymm(start_a_idx + l + 1),
+ Xbyak::Ymm(start_a_idx + l + 2));
+ }
+ l++;
+ }
+
+ vphaddd(Xbyak::Ymm(start_a_idx + l),
+ Xbyak::Ymm(start_a_idx + l - 2),
+ Xbyak::Ymm(start_a_idx + l - 1));
+
+ l++;
+ }
+
+ // eventually add with C and store new value
+ vxorps(Xbyak::Ymm(start_a_idx),
+ Xbyak::Ymm(start_a_idx),
+ Xbyak::Ymm(start_a_idx));
+ vucomiss(beta, Xbyak::Ymm(start_a_idx));
+ je(store_label, T_NEAR);
+
+ // beta = 1
+ for (k = 0, l = 2; k < nreg_acc; k += 8, l += 3) {
+ // load Y and add
+ last_it = (k + 8) > nreg_acc;
+ if (use_mask && last_it)
+ vmovdqu32(Xbyak::Ymm(start_a_idx + k / 8) | mask_m | T_z, ptr[Y + (k / 8) * 32]);
+ else
+ vmovdqu32(Xbyak::Ymm(start_a_idx + k / 8), ptr[Y + (k / 8) * 32]);
+
+ vpaddd(Xbyak::Ymm(start_a_idx + l),
+ Xbyak::Ymm(start_a_idx + l),
+ Xbyak::Ymm(start_a_idx + k / 8));
+ }
+
+ // store
+ aligned_label(store_label);
+ for (k = 0, l = 2; k < nreg_acc; k += 8, l += 3) {
+ last_it = (k + 8) > nreg_acc;
+ if (use_mask && last_it)
+ vmovdqu32(ptr[Y + (k / 8) * 32], Xbyak::Ymm(start_a_idx + l) | mask_m);
+ else
+ vmovdqu32(ptr[Y + (k / 8) * 32], Xbyak::Ymm(start_a_idx + l));
+ }
+
+}
+
+template <typename T>
+T jit_avx512_core_gemv_s8u8s32_kern::generate(int use_vnni) {
+
+ Xbyak::Opmask mask_n = k1, mask_m = k2;
+ Xbyak::Label one_label, m_tail_label, m_loop_label, n_loop_label;
+ Xbyak::Label n_tail_label, update_c_label, end_label;
+ constexpr unsigned int n_labels = (1 << unroll_m) - 1;
+ Xbyak::Label m_tail_label_case[n_labels];
+ Xbyak::Label n_loop_label_case[n_labels];
+ Xbyak::Label n_tail_label_case[n_labels];
+ Xbyak::Label update_c_label_case[n_labels];
+
+ int i, ii;
+
+ Xbyak::Zmm one, tmp;
+ Xbyak::Reg64 n = abi_param2, m = abi_param1;
+ Xbyak::Reg64 A = is_windows ? abi_param4 : abi_param3;
+ Xbyak::Reg64 lda = is_windows ? abi_param3 : abi_param4;
+ Xbyak::Reg64 X = is_windows ? rdi : r8;
+ Xbyak::Xmm beta = xmm1;
+ Xbyak::Reg64 Y = is_windows ? rsi : r9;
+
+ bool swap = !std::is_same<T, gemv_s8u8s32_kernel_t>::value;
+
+ // Windows: read on the stack lda, X, beta, Y
+
+ int zmm_idx = 1;
+ int nreg_acc = 1 << unroll_m;
+ int nreg_A = 1 << (unroll_m - 1);
+ int nreg_A_acc = nreg_acc + nreg_A;
+
+ if (!use_vnni) {
+ // set a zmm register to one
+ tmp = Xbyak::Zmm(0);
+ one = Xbyak::Zmm(zmm_idx + 1);
+ zmm_idx += 2; // one + tmp
+ }
+ else {
+ beta = xmm0;
+ }
+
+ preamble();
+
+ if (is_windows) {
+ mov(lda, ptr[rsp + get_size_of_abi_save_regs() + 40]);
+ mov(X, ptr[rsp + get_size_of_abi_save_regs() + 48]);
+ movss(beta, ptr[rsp + get_size_of_abi_save_regs() + 56]);
+ mov(Y, ptr[rsp + get_size_of_abi_save_regs() + 64]);
+ }
+
+ if (use_vnni && !is_windows) {
+ movaps(beta, xmm1);
+ }
+
+ mov(rax, (1 << unroll_n) - 1);
+ kmovq(k3, rax);
+
+ and_(rax, n); // rax contains n & ((1 << unroll_n) - 1)
+ mov(rbx, 1);
+ shlx(rbx, rbx, rax);
+ sub(rbx, 1);
+ kmovq(mask_n, rbx);
+ // mask_n set (AVX512 only), can use rax and rbx again
+
+ // set mask_m for update of the C matrix
+ // load/store on the C matrix use Ymm so tail according to Ymm size
+ mov(rax, 7); // 8 * 32 = 256 Ymm size
+ and_(rax, m); // rax contains m & 7
+ mov(rbx, 1);
+ shlx(rbx, rbx, rax);
+ sub(rbx, 1);
+ kmovq(mask_m, rbx);
+ // mask_m set (AVX512 only), can use rax and rbx again
+
+ // setup register of ones when VNNI instructions not available
+ if (!use_vnni) {
+ vmovdqu16(one, ptr[rip + one_label]);
+ }
+
+ // M loop
+ // base pointer for A rax contains a + i * lda
+ // Loop stop when rax >= a + (m & mask_um) * lda = rbx
+ // loop increment r10 = um * lda
+ // rbp = Y + i
+ mov(rax, A); // i = 0
+ mov(rbx, m);
+ and_(rbx, mask_um);
+ imul(rbx, lda);
+ add(rbx, A);
+ mov(r10, lda);
+ sal(r10, unroll_m);
+ mov(rbp, Y);
+
+ // N loop
+ // base pointer for X r11 contains x + j
+ // Loop stop when r11 >= x + n & mask_un = r12
+ // loop increment un
+ // r13 = rax + j = A + i * lda + j
+ mov(r12, n);
+ and_(r12, mask_un);
+ add(r12, X);
+
+ // M loop
+ aligned_label(m_loop_label);
+ cmp(rax, rbx);
+ jge(m_tail_label, T_NEAR);
+
+ // enter M loop
+ for(i = 0; i < nreg_acc; i++) {
+ vpxorq(Xbyak::Zmm(i + zmm_idx + nreg_A),
+ Xbyak::Zmm(i + zmm_idx + nreg_A),
+ Xbyak::Zmm(i + zmm_idx + nreg_A));
+ }
+
+ // N loop
+ mov(r11, X); // j = 0
+ mov(r13, rax);
+ aligned_label(n_loop_label);
+ cmp(r11, r12);
+ jge(n_tail_label, T_NEAR);
+
+ // enter N loop
+
+ n_loop_body(zmm_idx, zmm_idx + nreg_A, zmm_idx + nreg_A_acc, nreg_acc,
+ r13, lda, r11, tmp, one, swap, use_vnni, 0, mask_n);
+
+ // increment rax with un
+ add(r11, 1 << unroll_n);
+ add(r13, 1 << unroll_n);
+ jmp(n_loop_label, T_NEAR);
+ // end N loop
+
+ // N tail
+ aligned_label(n_tail_label);
+
+ ktestq(mask_n, k3);
+ je(update_c_label, T_NEAR);
+ n_loop_body(zmm_idx, zmm_idx + nreg_A, zmm_idx + nreg_A_acc, nreg_acc,
+ r13, lda, r11, tmp, one, swap, use_vnni, 1, mask_n);
+
+ // update C matrix
+ aligned_label(update_c_label);
+
+ update_c(nreg_acc, rbp, zmm_idx, zmm_idx + nreg_A, beta, 0, mask_m);
+
+ // increment rax with um * lda
+ add(rax, r10);
+ add(rbp, 1 << (unroll_m + 2));
+ jmp(m_loop_label, T_NEAR);
+ // end M loop
+
+ // M tail
+ aligned_label(m_tail_label);
+
+ // r10 will contain m_tail = m % unroll_m = m & (1 << unroll_m) - 1
+ mov(r10, m);
+ and_(r10, (1 << unroll_m) - 1);
+ for (ii = 1; ii < 1 << unroll_m; ii++) {
+ aligned_label(m_tail_label_case[ii-1]);
+ cmp(r10, ii);
+ if (ii == (1 << unroll_m) - 1)
+ jne(end_label, T_NEAR);
+ else
+ jne(m_tail_label_case[ii], T_NEAR);
+
+ // m_tail = i, use i accumulators
+
+ for(i = 0; i < ii; i++) {
+ vpxorq(Xbyak::Zmm(i + zmm_idx + nreg_A),
+ Xbyak::Zmm(i + zmm_idx + nreg_A),
+ Xbyak::Zmm(i + zmm_idx + nreg_A));
+ }
+
+ // N loop
+ mov(r11, X); // j = 0
+ mov(r13, rax);
+ aligned_label(n_loop_label_case[ii - 1]);
+ cmp(r11, r12);
+ jge(n_tail_label_case[ii - 1], T_NEAR);
+
+ n_loop_body(zmm_idx, zmm_idx + nreg_A, zmm_idx + nreg_A_acc, ii, r13,
+ lda, r11, tmp, one, swap, use_vnni, 0, mask_n);
+
+ // increment rax with un
+ add(r11, 1 << unroll_n);
+ add(r13, 1 << unroll_n);
+ jmp(n_loop_label_case[ii - 1], T_NEAR);
+ // end N loop
+
+ // N tail
+ aligned_label(n_tail_label_case[ii - 1]);
+ ktestq(mask_n, k3);
+ je(update_c_label_case[ii - 1], T_NEAR);
+ n_loop_body(zmm_idx, zmm_idx + nreg_A, zmm_idx + nreg_A_acc, ii, r13,
+ lda, r11, tmp, one, swap, use_vnni, 1, mask_n);
+
+ // update C matrix
+ aligned_label(update_c_label_case[ii - 1]);
+ update_c(ii, rbp, zmm_idx, zmm_idx + nreg_A, beta, 1, mask_m);
+
+ if (ii < ((1 << unroll_m) - 1))
+ jmp(end_label, T_NEAR);
+ }
+
+ aligned_label(end_label);
+
+ postamble();
+
+ if (!use_vnni) {
+ aligned_label(one_label);
+ for (i = 0; i < size_vec_reg/8; i++)
+ dq(0x0001000100010001);
+ }
+
+ return (T) getCode();
+}
+
+template jit_avx512_core_gemv_s8u8s32_kern::gemv_s8u8s32_kernel_t
+jit_avx512_core_gemv_s8u8s32_kern::generate<jit_avx512_core_gemv_s8u8s32_kern::gemv_s8u8s32_kernel_t>(int);
+
+template jit_avx512_core_gemv_s8u8s32_kern::gemv_u8s8s32_kernel_t
+jit_avx512_core_gemv_s8u8s32_kern::generate<jit_avx512_core_gemv_s8u8s32_kern::gemv_u8s8s32_kernel_t>(int);
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_kernel_gemv_s8u8s32_kern.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_kernel_gemv_s8u8s32_kern.hpp
new file mode 100644
index 0000000000..9ea23a5f56
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_kernel_gemv_s8u8s32_kern.hpp
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * Copyright 2019 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+
+#include "jit_generator.hpp"
+#include "common.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+class jit_avx512_core_gemv_s8u8s32_kern : jit_generator {
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_gemv_s8u8s32_kern);
+
+ // assumes untoll_{m,n} are a power of 2
+ static constexpr unsigned int unroll_m = 4; // real unrolling factor is 2^unroll_m
+ const int mask_um = 0xFFFFFFF0;
+ static constexpr unsigned int unroll_n = 6; // real unrolling factor is 2^unroll_n
+ const int mask_un = 0xFFFFFFC0;
+ const int size_vec_reg = 64; // bytes
+
+ void aligned_label(Xbyak::Label &label, int alignment = 16) {
+ align(alignment);
+ L(label);
+ }
+
+ void vnni(Xbyak::Zmm, Xbyak::Zmm, Xbyak::Zmm, Xbyak::Zmm, Xbyak::Zmm, bool, int);
+ void n_loop_body(int, int, int, int, Xbyak::Reg64, Xbyak::Reg64,
+ Xbyak::Reg64, Xbyak::Zmm, Xbyak::Zmm, bool, int, int, Xbyak::Opmask);
+ void shuffle_and_add(Xbyak::Zmm, Xbyak::Zmm, Xbyak::Zmm, Xbyak::Zmm, Xbyak::Zmm);
+ void update_c(int, Xbyak::Reg64, int, int, Xbyak::Xmm, int, Xbyak::Opmask);
+
+public:
+ jit_avx512_core_gemv_s8u8s32_kern() : jit_generator(nullptr, GEMM_CODE_SIZE) {};
+
+ // m, n, alpha, a, lda, x, beta, y
+ typedef void (*gemv_s8u8s32_kernel_t)(const dim_t, const dim_t, const float,
+ const int8_t*, const dim_t, const uint8_t*,
+ const float, int32_t*);
+ typedef void (*gemv_u8s8s32_kernel_t)(const dim_t, const dim_t, const float,
+ const uint8_t*, const dim_t, const int8_t*,
+ const float, int32_t*);
+
+ template <typename T>
+ T generate(int use_vnni);
+
+};
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_an_kern.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_an_kern.cpp
new file mode 100644
index 0000000000..544cd2ff25
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_an_kern.cpp
@@ -0,0 +1,819 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "jit_generator.hpp"
+#include "common.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+jit_avx512_core_u8_copy_an_kern::jit_avx512_core_u8_copy_an_kern(): jit_generator(nullptr, GEMM_CODE_SIZE)
+{
+
+#ifndef _WIN32
+#define M rdi
+#define N rsi
+#define A rdx
+#define LDA rcx
+#define ALPHA r8
+#define B r9
+
+#define I rax
+#define A1 r10
+#define A2 r8
+#define LDA3 r11
+
+#else
+
+#define M rcx
+#define N rdx
+#define A r8
+#define LDA r9
+#define ALPHA rax
+#define B rdi
+
+#define I rax
+#define A1 rsi
+#define A2 r10
+#define LDA3 r11
+
+#define ARG_ALPHA 40+stacksize+rsp
+#define ARG_B 48+stacksize+rsp
+
+#endif
+
+inLocalLabel();
+{
+
+Xbyak::Label l170;
+Xbyak::Label l1f0;
+Xbyak::Label l20;
+Xbyak::Label l224;
+Xbyak::Label l234;
+Xbyak::Label l240;
+Xbyak::Label l254;
+Xbyak::Label l32c;
+Xbyak::Label l34;
+Xbyak::Label l388;
+Xbyak::Label l3b0;
+Xbyak::Label l3c0;
+Xbyak::Label l3cc;
+Xbyak::Label l3dc;
+Xbyak::Label l454;
+Xbyak::Label l48c;
+Xbyak::Label l4a8;
+Xbyak::Label l4b8;
+Xbyak::Label l4c4;
+Xbyak::Label l4d8;
+Xbyak::Label l570;
+Xbyak::Label l5c4;
+Xbyak::Label l5f0;
+Xbyak::Label l60c;
+Xbyak::Label l61c;
+Xbyak::Label l628;
+Xbyak::Label l638;
+Xbyak::Label l6b0;
+Xbyak::Label l6f4;
+Xbyak::Label l720;
+Xbyak::Label l73c;
+Xbyak::Label l74c;
+Xbyak::Label l758;
+Xbyak::Label l76c;
+Xbyak::Label l804;
+Xbyak::Label l858;
+Xbyak::Label l88c;
+Xbyak::Label l8a4;
+Xbyak::Label l8b2;
+Xbyak::Label l8bc;
+Xbyak::Label l8cc;
+Xbyak::Label l944;
+Xbyak::Label l98c;
+Xbyak::Label l9b0;
+Xbyak::Label l9c8;
+Xbyak::Label l9d8;
+
+ preamble();
+#ifdef _WIN32
+ auto stacksize = get_size_of_abi_save_regs();
+ mov(ALPHA, ptr[ARG_ALPHA]);
+ mov(B, ptr[ARG_B]);
+#endif
+
+ mov(M, qword[M]);
+ mov(N, qword[N]);
+ mov(LDA, qword[LDA]);
+ lea(LDA3, ptr[LDA+LDA*2]);
+ sub(A, -128);
+ sub(B, -128);
+ cmp(N, 0x30);
+ jl(l234, T_NEAR);
+ align(4);
+
+L(l20);
+ mov(A1, A);
+ add(A, 0x30);
+ mov(I, M);
+ sar(I, 0x2);
+ jle(l170, T_NEAR);
+ align(4);
+
+L(l34);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ movdqa(xmm4, xmm0);
+ punpcklbw(xmm0, xmm1);
+ punpckhbw(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpcklbw(xmm2, xmm3);
+ punpckhbw(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqa(xmm2, xmm4);
+ punpcklwd(xmm4, xmm5);
+ punpckhwd(xmm2, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ movdqu(xword[B-0x60], xmm4);
+ movdqu(xword[B-0x50], xmm2);
+ movdqu(xmm0, xword[A1-0x70]);
+ movdqu(xmm1, xword[A1+LDA*1-0x70]);
+ movdqu(xmm2, xword[A1+LDA*2-0x70]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x70]);
+ movdqa(xmm4, xmm0);
+ punpcklbw(xmm0, xmm1);
+ punpckhbw(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpcklbw(xmm2, xmm3);
+ punpckhbw(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqa(xmm2, xmm4);
+ punpcklwd(xmm4, xmm5);
+ punpckhwd(xmm2, xmm5);
+ movdqu(xword[B-0x40], xmm0);
+ movdqu(xword[B-0x30], xmm1);
+ movdqu(xword[B-0x20], xmm4);
+ movdqu(xword[B-0x10], xmm2);
+ movdqu(xmm0, xword[A1-0x60]);
+ movdqu(xmm1, xword[A1+LDA*1-0x60]);
+ movdqu(xmm2, xword[A1+LDA*2-0x60]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x60]);
+ lea(A1, ptr[A1+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpcklbw(xmm0, xmm1);
+ punpckhbw(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpcklbw(xmm2, xmm3);
+ punpckhbw(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqa(xmm2, xmm4);
+ punpcklwd(xmm4, xmm5);
+ punpckhwd(xmm2, xmm5);
+ movdqu(xword[B], xmm0);
+ movdqu(xword[B+0x10], xmm1);
+ movdqu(xword[B+0x20], xmm4);
+ movdqu(xword[B+0x30], xmm2);
+ sub(B, -192);
+ dec(I);
+ jg(l34, T_NEAR);
+ align(4);
+
+L(l170);
+ test(M, 0x2);
+ jle(l1f0, T_NEAR);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1-0x70]);
+ movdqu(xmm2, xword[A1-0x60]);
+ add(A1, LDA);
+ movdqu(xmm3, xword[A1-0x80]);
+ movdqu(xmm4, xword[A1-0x70]);
+ movdqu(xmm5, xword[A1-0x60]);
+ add(A1, LDA);
+ movdqa(xmm6, xmm0);
+ punpcklbw(xmm0, xmm3);
+ punpckhbw(xmm6, xmm3);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm6);
+ movdqa(xmm6, xmm1);
+ punpcklbw(xmm1, xmm4);
+ punpckhbw(xmm6, xmm4);
+ movdqu(xword[B-0x60], xmm1);
+ movdqu(xword[B-0x50], xmm6);
+ movdqa(xmm6, xmm2);
+ punpcklbw(xmm2, xmm5);
+ punpckhbw(xmm6, xmm5);
+ movdqu(xword[B-0x40], xmm2);
+ movdqu(xword[B-0x30], xmm6);
+ sub(B, -96);
+ align(4);
+
+L(l1f0);
+ test(M, 0x1);
+ jle(l224, T_NEAR);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1-0x70]);
+ movdqu(xmm2, xword[A1-0x60]);
+ add(A1, LDA);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ movdqu(xword[B-0x60], xmm2);
+ sub(B, -48);
+ align(4);
+
+L(l224);
+ sub(N, 0x30);
+ cmp(N, 0x30);
+ jge(l20, T_NEAR);
+ align(4);
+
+L(l234);
+ cmp(N, 0x20);
+ jl(l3c0, T_NEAR);
+ align(4);
+
+L(l240);
+ mov(A1, A);
+ add(A, 0x20);
+ mov(I, M);
+ sar(I, 0x2);
+ jle(l32c, T_NEAR);
+ align(4);
+
+L(l254);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ movdqa(xmm4, xmm0);
+ punpcklbw(xmm0, xmm1);
+ punpckhbw(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpcklbw(xmm2, xmm3);
+ punpckhbw(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqa(xmm2, xmm4);
+ punpcklwd(xmm4, xmm5);
+ punpckhwd(xmm2, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ movdqu(xword[B-0x60], xmm4);
+ movdqu(xword[B-0x50], xmm2);
+ movdqu(xmm0, xword[A1-0x70]);
+ movdqu(xmm1, xword[A1+LDA*1-0x70]);
+ movdqu(xmm2, xword[A1+LDA*2-0x70]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x70]);
+ lea(A1, ptr[A1+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpcklbw(xmm0, xmm1);
+ punpckhbw(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpcklbw(xmm2, xmm3);
+ punpckhbw(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqa(xmm2, xmm4);
+ punpcklwd(xmm4, xmm5);
+ punpckhwd(xmm2, xmm5);
+ movdqu(xword[B-0x40], xmm0);
+ movdqu(xword[B-0x30], xmm1);
+ movdqu(xword[B-0x20], xmm4);
+ movdqu(xword[B-0x10], xmm2);
+ sub(B, -128);
+ dec(I);
+ jg(l254, T_NEAR);
+ align(4);
+
+L(l32c);
+ test(M, 0x2);
+ jle(l388, T_NEAR);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1-0x70]);
+ add(A1, LDA);
+ movdqu(xmm2, xword[A1-0x80]);
+ movdqu(xmm3, xword[A1-0x70]);
+ add(A1, LDA);
+ movdqa(xmm4, xmm0);
+ punpcklbw(xmm0, xmm2);
+ punpckhbw(xmm4, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm4);
+ movdqa(xmm4, xmm1);
+ punpcklbw(xmm1, xmm3);
+ punpckhbw(xmm4, xmm3);
+ movdqu(xword[B-0x60], xmm1);
+ movdqu(xword[B-0x50], xmm4);
+ sub(B, -64);
+ align(4);
+
+L(l388);
+ test(M, 0x1);
+ jle(l3b0, T_NEAR);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1-0x70]);
+ add(A1, LDA);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ sub(B, -32);
+ align(4);
+
+L(l3b0);
+ sub(N, 0x20);
+ cmp(N, 0x20);
+ jge(l240, T_NEAR);
+ align(4);
+
+L(l3c0);
+ cmp(N, 0x10);
+ jl(l4b8, T_NEAR);
+ align(4);
+
+L(l3cc);
+ mov(A1, A);
+ add(A, 0x10);
+ mov(I, M);
+ sar(I, 0x2);
+ jle(l454, T_NEAR);
+ align(4);
+
+L(l3dc);
+ movdqu(xmm0, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqu(xmm1, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqu(xmm2, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqu(xmm3, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqa(xmm4, xmm0);
+ punpcklbw(xmm0, xmm1);
+ punpckhbw(xmm4, xmm1);
+ movdqa(xmm1, xmm2);
+ punpcklbw(xmm2, xmm3);
+ punpckhbw(xmm1, xmm3);
+ movdqa(xmm3, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm3, xmm2);
+ movdqa(xmm2, xmm4);
+ punpcklwd(xmm4, xmm1);
+ punpckhwd(xmm2, xmm1);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm3);
+ movdqu(xword[B-0x60], xmm4);
+ movdqu(xword[B-0x50], xmm2);
+ sub(B, -64);
+ dec(I);
+ jg(l3dc, T_NEAR);
+ align(4);
+
+L(l454);
+ test(M, 0x2);
+ jle(l48c, T_NEAR);
+ movdqu(xmm0, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqu(xmm1, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqa(xmm2, xmm0);
+ punpcklbw(xmm0, xmm1);
+ punpckhbw(xmm2, xmm1);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm2);
+ sub(B, -32);
+ align(4);
+
+L(l48c);
+ test(M, 0x1);
+ jle(l4a8, T_NEAR);
+ movdqu(xmm0, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l4a8);
+ sub(N, 0x10);
+ cmp(N, 0x10);
+ jge(l3cc, T_NEAR);
+ align(4);
+
+L(l4b8);
+ cmp(N, 0x8);
+ jl(l61c, T_NEAR);
+ align(4);
+
+L(l4c4);
+ mov(A1, A);
+ add(A, 0x8);
+ mov(I, M);
+ sar(I, 0x3);
+ jle(l570, T_NEAR);
+ align(4);
+
+L(l4d8);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqu(xword[B-0x60], xmm0);
+ movdqu(xword[B-0x50], xmm1);
+ sub(B, -64);
+ dec(I);
+ jg(l4d8, T_NEAR);
+ align(4);
+
+L(l570);
+ test(M, 0x4);
+ jle(l5c4, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ sub(B, -32);
+ align(4);
+
+L(l5c4);
+ test(M, 0x2);
+ jle(l5f0, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l5f0);
+ test(M, 0x1);
+ jle(l60c, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l60c);
+ sub(N, 0x8);
+ cmp(N, 0x8);
+ jge(l4c4, T_NEAR);
+ align(4);
+
+L(l61c);
+ cmp(N, 0x4);
+ jl(l74c, T_NEAR);
+ align(4);
+
+L(l628);
+ mov(A1, A);
+ add(A, 0x4);
+ mov(I, M);
+ sar(I, 0x3);
+ jle(l6b0, T_NEAR);
+ align(4);
+
+L(l638);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ sub(B, -32);
+ dec(I);
+ jg(l638, T_NEAR);
+ align(4);
+
+L(l6b0);
+ test(M, 0x4);
+ jle(l6f4, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l6f4);
+ test(M, 0x2);
+ jle(l720, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l720);
+ test(M, 0x1);
+ jle(l73c, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l73c);
+ sub(N, 0x4);
+ cmp(N, 0x4);
+ jge(l628, T_NEAR);
+ align(4);
+
+L(l74c);
+ cmp(N, 0x2);
+ jl(l8b2, T_NEAR);
+ align(4);
+
+L(l758);
+ mov(A1, A);
+ add(A, 0x2);
+ mov(LDA3, M);
+ sar(LDA3, 0x3);
+ jle(l804, T_NEAR);
+ align(4);
+
+L(l76c);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm4, eax, 0x0);
+ punpcklbw(xmm1, xmm2);
+ punpcklbw(xmm3, xmm4);
+ punpcklwd(xmm1, xmm3);
+ punpcklqdq(xmm0, xmm1);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ dec(LDA3);
+ jg(l76c, T_NEAR);
+ align(4);
+
+L(l804);
+ test(M, 0x4);
+ jle(l858, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l858);
+ test(M, 0x2);
+ jle(l88c, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l88c);
+ test(M, 0x1);
+ jle(l8a4, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ mov(word[B-0x80], ax);
+ sub(B, -2);
+ align(4);
+
+L(l8a4);
+ sub(N, 0x2);
+ cmp(N, 0x2);
+ jge(l758, T_NEAR);
+ align(4);
+
+L(l8b2);
+ cmp(N, 0x1);
+ jl(l9d8, T_NEAR);
+ align(4);
+
+L(l8bc);
+ mov(A1, A);
+ add(A, 0x1);
+ mov(LDA3, M);
+ sar(LDA3, 0x3);
+ jle(l944, T_NEAR);
+ align(4);
+
+L(l8cc);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x7);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ dec(LDA3);
+ jg(l8cc, T_NEAR);
+ align(4);
+
+L(l944);
+ test(M, 0x4);
+ jle(l98c, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x3);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l98c);
+ test(M, 0x2);
+ jle(l9b0, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ mov(byte[B-0x80], al);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ mov(byte[B-0x7f], al);
+ sub(B, -2);
+ align(4);
+
+L(l9b0);
+ test(M, 0x1);
+ jle(l9c8, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ mov(byte[B-0x80], al);
+ sub(B, -1);
+ align(4);
+
+L(l9c8);
+ sub(N, 0x1);
+ cmp(N, 0x1);
+ jge(l8bc, T_NEAR);
+ align(4);
+
+L(l9d8);
+
+ postamble();
+}
+outLocalLabel();
+
+#undef M
+#undef N
+#undef A
+#undef LDA
+#undef ALPHA
+#undef B
+#undef I
+#undef A1
+#undef A2
+#undef LDA3
+#ifdef _WIN32
+#undef ARG_ALPHA
+#undef ARG_B
+#endif
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_at_kern.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_at_kern.cpp
new file mode 100644
index 0000000000..1c11fc6cef
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_at_kern.cpp
@@ -0,0 +1,2209 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "jit_generator.hpp"
+#include "common.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+jit_avx512_core_u8_copy_at_kern::jit_avx512_core_u8_copy_at_kern(): jit_generator(nullptr, GEMM_CODE_SIZE)
+{
+
+#ifndef _WIN32
+#define M rdi
+#define N rsi
+#define A rdx
+#define LDA rcx
+#define ALPHA r8
+#define B r9
+
+#define I rax
+#define A1 r10
+#define A2 r8
+#define LDA3 r11
+
+#else
+
+#define M rcx
+#define N rdx
+#define A r8
+#define LDA r9
+#define ALPHA rax
+#define B rdi
+
+#define I rax
+#define A1 rsi
+#define A2 r10
+#define LDA3 r11
+
+#define ARG_ALPHA 40+stacksize+rsp
+#define ARG_B 48+stacksize+rsp
+
+#endif
+
+inLocalLabel();
+{
+
+Xbyak::Label l1014;
+Xbyak::Label l1390;
+Xbyak::Label l159c;
+Xbyak::Label l173c;
+Xbyak::Label l18e4;
+Xbyak::Label l1a7c;
+Xbyak::Label l1a8c;
+Xbyak::Label l1a98;
+Xbyak::Label l1ab4;
+Xbyak::Label l1c64;
+Xbyak::Label l1d74;
+Xbyak::Label l1e50;
+Xbyak::Label l1f2c;
+Xbyak::Label l1ffc;
+Xbyak::Label l20;
+Xbyak::Label l200c;
+Xbyak::Label l2018;
+Xbyak::Label l2034;
+Xbyak::Label l2110;
+Xbyak::Label l21a0;
+Xbyak::Label l2210;
+Xbyak::Label l2284;
+Xbyak::Label l22f0;
+Xbyak::Label l2300;
+Xbyak::Label l230c;
+Xbyak::Label l2324;
+Xbyak::Label l2398;
+Xbyak::Label l23e8;
+Xbyak::Label l242c;
+Xbyak::Label l2474;
+Xbyak::Label l24b4;
+Xbyak::Label l24c4;
+Xbyak::Label l24d0;
+Xbyak::Label l24e8;
+Xbyak::Label l2520;
+Xbyak::Label l254c;
+Xbyak::Label l2578;
+Xbyak::Label l25a8;
+Xbyak::Label l25c8;
+Xbyak::Label l25d6;
+Xbyak::Label l25e0;
+Xbyak::Label l25f0;
+Xbyak::Label l260c;
+Xbyak::Label l262c;
+Xbyak::Label l264c;
+Xbyak::Label l2668;
+Xbyak::Label l2680;
+Xbyak::Label l2690;
+Xbyak::Label l44;
+Xbyak::Label l58c;
+Xbyak::Label l8b0;
+Xbyak::Label lb14;
+Xbyak::Label ld84;
+Xbyak::Label lfdc;
+Xbyak::Label lfec;
+Xbyak::Label lff8;
+
+ preamble();
+#ifdef _WIN32
+ auto stacksize = get_size_of_abi_save_regs();
+ mov(ALPHA, ptr[ARG_ALPHA]);
+ mov(B, ptr[ARG_B]);
+#endif
+
+ mov(N, qword[N]);
+ mov(M, qword[M]);
+ mov(LDA, qword[LDA]);
+ sub(A, -128);
+ sub(B, -128);
+ lea(LDA3, ptr[LDA+LDA*2]);
+ cmp(N, 0x30);
+ jl(lfec, T_NEAR);
+ align(4);
+
+L(l20);
+ mov(A1, A);
+ mov(I, LDA);
+ shl(I, 0x5);
+ lea(I, ptr[I+LDA*8]);
+ lea(I, ptr[I+LDA*8]);
+ add(A, I);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l58c, T_NEAR);
+ align(4);
+
+L(l44);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B+0x40], xmm1);
+ movdqu(xword[B+0x100], xmm4);
+ movdqu(xword[B+0x1c0], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ movdqu(xword[B+0x50], xmm1);
+ movdqu(xword[B+0x110], xmm4);
+ movdqu(xword[B+0x1d0], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x60], xmm0);
+ movdqu(xword[B+0x60], xmm1);
+ movdqu(xword[B+0x120], xmm4);
+ movdqu(xword[B+0x1e0], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x50], xmm0);
+ movdqu(xword[B+0x70], xmm1);
+ movdqu(xword[B+0x130], xmm4);
+ movdqu(xword[B+0x1f0], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x40], xmm0);
+ movdqu(xword[B+0x80], xmm1);
+ movdqu(xword[B+0x140], xmm4);
+ movdqu(xword[B+0x200], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x30], xmm0);
+ movdqu(xword[B+0x90], xmm1);
+ movdqu(xword[B+0x150], xmm4);
+ movdqu(xword[B+0x210], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x20], xmm0);
+ movdqu(xword[B+0xa0], xmm1);
+ movdqu(xword[B+0x160], xmm4);
+ movdqu(xword[B+0x220], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x10], xmm0);
+ movdqu(xword[B+0xb0], xmm1);
+ movdqu(xword[B+0x170], xmm4);
+ movdqu(xword[B+0x230], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B], xmm0);
+ movdqu(xword[B+0xc0], xmm1);
+ movdqu(xword[B+0x180], xmm4);
+ movdqu(xword[B+0x240], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B+0x10], xmm0);
+ movdqu(xword[B+0xd0], xmm1);
+ movdqu(xword[B+0x190], xmm4);
+ movdqu(xword[B+0x250], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B+0x20], xmm0);
+ movdqu(xword[B+0xe0], xmm1);
+ movdqu(xword[B+0x1a0], xmm4);
+ movdqu(xword[B+0x260], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B+0x30], xmm0);
+ movdqu(xword[B+0xf0], xmm1);
+ movdqu(xword[B+0x1b0], xmm4);
+ movdqu(xword[B+0x270], xmm3);
+ sub(A1, -16);
+ sub(B, -768);
+ dec(I);
+ jg(l44, T_NEAR);
+ align(4);
+
+L(l58c);
+ test(M, 0x8);
+ jle(l8b0, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ movq(xmm2, qword[A1+LDA*2-0x80]);
+ movq(xmm3, qword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B+0x40], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ movdqu(xword[B+0x50], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x60], xmm0);
+ movdqu(xword[B+0x60], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x50], xmm0);
+ movdqu(xword[B+0x70], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x40], xmm0);
+ movdqu(xword[B+0x80], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x30], xmm0);
+ movdqu(xword[B+0x90], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x20], xmm0);
+ movdqu(xword[B+0xa0], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x10], xmm0);
+ movdqu(xword[B+0xb0], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B], xmm0);
+ movdqu(xword[B+0xc0], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B+0x10], xmm0);
+ movdqu(xword[B+0xd0], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B+0x20], xmm0);
+ movdqu(xword[B+0xe0], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B+0x30], xmm0);
+ movdqu(xword[B+0xf0], xmm1);
+ sub(A1, -8);
+ sub(B, -384);
+ align(4);
+
+L(l8b0);
+ test(M, 0x4);
+ jle(lb14, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ movd(xmm2, dword[A1+LDA*2-0x80]);
+ movd(xmm3, dword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x60], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x50], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x40], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x30], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x20], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x10], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B+0x10], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B+0x20], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B+0x30], xmm0);
+ sub(A1, -4);
+ sub(B, -192);
+ align(4);
+
+L(lb14);
+ test(M, 0x2);
+ jle(ld84, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A1+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x7);
+ movdqu(xword[B-0x80], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqu(xword[B-0x70], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqu(xword[B-0x60], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqu(xword[B-0x50], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqu(xword[B-0x40], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqu(xword[B-0x30], xmm0);
+ sub(A1, -2);
+ sub(B, -96);
+ align(4);
+
+L(ld84);
+ test(M, 0x1);
+ jle(lfdc, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xf);
+ movdqu(xword[B-0x80], xmm0);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xf);
+ movdqu(xword[B-0x70], xmm0);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xf);
+ movdqu(xword[B-0x60], xmm0);
+ sub(B, -48);
+ align(4);
+
+L(lfdc);
+ sub(N, 0x30);
+ cmp(N, 0x30);
+ jge(l20, T_NEAR);
+ align(4);
+
+L(lfec);
+ cmp(N, 0x20);
+ jl(l1a8c, T_NEAR);
+ align(4);
+
+L(lff8);
+ mov(A1, A);
+ mov(I, LDA);
+ shl(I, 0x5);
+ add(A, I);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l1390, T_NEAR);
+ align(4);
+
+L(l1014);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B], xmm1);
+ movdqu(xword[B+0x80], xmm4);
+ movdqu(xword[B+0x100], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ movdqu(xword[B+0x10], xmm1);
+ movdqu(xword[B+0x90], xmm4);
+ movdqu(xword[B+0x110], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x60], xmm0);
+ movdqu(xword[B+0x20], xmm1);
+ movdqu(xword[B+0xa0], xmm4);
+ movdqu(xword[B+0x120], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x50], xmm0);
+ movdqu(xword[B+0x30], xmm1);
+ movdqu(xword[B+0xb0], xmm4);
+ movdqu(xword[B+0x130], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x40], xmm0);
+ movdqu(xword[B+0x40], xmm1);
+ movdqu(xword[B+0xc0], xmm4);
+ movdqu(xword[B+0x140], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x30], xmm0);
+ movdqu(xword[B+0x50], xmm1);
+ movdqu(xword[B+0xd0], xmm4);
+ movdqu(xword[B+0x150], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x20], xmm0);
+ movdqu(xword[B+0x60], xmm1);
+ movdqu(xword[B+0xe0], xmm4);
+ movdqu(xword[B+0x160], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x10], xmm0);
+ movdqu(xword[B+0x70], xmm1);
+ movdqu(xword[B+0xf0], xmm4);
+ movdqu(xword[B+0x170], xmm3);
+ sub(A1, -16);
+ sub(B, -512);
+ dec(I);
+ jg(l1014, T_NEAR);
+ align(4);
+
+L(l1390);
+ test(M, 0x8);
+ jle(l159c, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ movq(xmm2, qword[A1+LDA*2-0x80]);
+ movq(xmm3, qword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ movdqu(xword[B+0x10], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x60], xmm0);
+ movdqu(xword[B+0x20], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x50], xmm0);
+ movdqu(xword[B+0x30], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x40], xmm0);
+ movdqu(xword[B+0x40], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x30], xmm0);
+ movdqu(xword[B+0x50], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x20], xmm0);
+ movdqu(xword[B+0x60], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x10], xmm0);
+ movdqu(xword[B+0x70], xmm1);
+ sub(A1, -8);
+ sub(B, -256);
+ align(4);
+
+L(l159c);
+ test(M, 0x4);
+ jle(l173c, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ movd(xmm2, dword[A1+LDA*2-0x80]);
+ movd(xmm3, dword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x60], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x50], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x40], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x30], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x20], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x10], xmm0);
+ sub(A1, -4);
+ sub(B, -128);
+ align(4);
+
+L(l173c);
+ test(M, 0x2);
+ jle(l18e4, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A1+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x7);
+ movdqu(xword[B-0x80], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqu(xword[B-0x70], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqu(xword[B-0x60], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqu(xword[B-0x50], xmm0);
+ sub(A1, -2);
+ sub(B, -64);
+ align(4);
+
+L(l18e4);
+ test(M, 0x1);
+ jle(l1a7c, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xf);
+ movdqu(xword[B-0x80], xmm0);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xf);
+ movdqu(xword[B-0x70], xmm0);
+ sub(B, -32);
+ align(4);
+
+L(l1a7c);
+ sub(N, 0x20);
+ cmp(N, 0x20);
+ jge(lff8, T_NEAR);
+ align(4);
+
+L(l1a8c);
+ cmp(N, 0x10);
+ jl(l200c, T_NEAR);
+ align(4);
+
+L(l1a98);
+ mov(A1, A);
+ mov(I, LDA);
+ shl(I, 0x4);
+ add(A, I);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l1c64, T_NEAR);
+ align(4);
+
+L(l1ab4);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x40], xmm1);
+ movdqu(xword[B], xmm4);
+ movdqu(xword[B+0x40], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ movdqu(xword[B-0x30], xmm1);
+ movdqu(xword[B+0x10], xmm4);
+ movdqu(xword[B+0x50], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x60], xmm0);
+ movdqu(xword[B-0x20], xmm1);
+ movdqu(xword[B+0x20], xmm4);
+ movdqu(xword[B+0x60], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x50], xmm0);
+ movdqu(xword[B-0x10], xmm1);
+ movdqu(xword[B+0x30], xmm4);
+ movdqu(xword[B+0x70], xmm3);
+ sub(A1, -16);
+ sub(B, -256);
+ dec(I);
+ jg(l1ab4, T_NEAR);
+ align(4);
+
+L(l1c64);
+ test(M, 0x8);
+ jle(l1d74, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ movq(xmm2, qword[A1+LDA*2-0x80]);
+ movq(xmm3, qword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x40], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ movdqu(xword[B-0x30], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x60], xmm0);
+ movdqu(xword[B-0x20], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x50], xmm0);
+ movdqu(xword[B-0x10], xmm1);
+ sub(A1, -8);
+ sub(B, -128);
+ align(4);
+
+L(l1d74);
+ test(M, 0x4);
+ jle(l1e50, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ movd(xmm2, dword[A1+LDA*2-0x80]);
+ movd(xmm3, dword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x60], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x50], xmm0);
+ sub(A1, -4);
+ sub(B, -64);
+ align(4);
+
+L(l1e50);
+ test(M, 0x2);
+ jle(l1f2c, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A1+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x7);
+ movdqu(xword[B-0x80], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ movdqu(xword[B-0x70], xmm0);
+ sub(A1, -2);
+ sub(B, -32);
+ align(4);
+
+L(l1f2c);
+ test(M, 0x1);
+ jle(l1ffc, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ pinsrb(xmm0, eax, 0xf);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l1ffc);
+ sub(N, 0x10);
+ cmp(N, 0x10);
+ jge(l1a98, T_NEAR);
+ align(4);
+
+L(l200c);
+ cmp(N, 0x8);
+ jl(l2300, T_NEAR);
+ align(4);
+
+L(l2018);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*4]);
+ lea(I, ptr[A1+LDA*8]);
+ mov(A, I);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l2110, T_NEAR);
+ align(4);
+
+L(l2034);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ sub(A1, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x60], xmm1);
+ movdqu(xword[B-0x40], xmm4);
+ movdqu(xword[B-0x20], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ sub(A2, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ movdqu(xword[B-0x50], xmm1);
+ movdqu(xword[B-0x30], xmm4);
+ movdqu(xword[B-0x10], xmm3);
+ sub(B, -128);
+ dec(I);
+ jg(l2034, T_NEAR);
+ align(4);
+
+L(l2110);
+ test(M, 0x8);
+ jle(l21a0, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ movq(xmm2, qword[A1+LDA*2-0x80]);
+ movq(xmm3, qword[A1+LDA3*1-0x80]);
+ sub(A1, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x60], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ movdqu(xword[B-0x50], xmm1);
+ sub(B, -64);
+ align(4);
+
+L(l21a0);
+ test(M, 0x4);
+ jle(l2210, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ movd(xmm2, dword[A1+LDA*2-0x80]);
+ movd(xmm3, dword[A1+LDA3*1-0x80]);
+ sub(A1, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ sub(B, -32);
+ align(4);
+
+L(l2210);
+ test(M, 0x2);
+ jle(l2284, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A1+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A1+LDA3*1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x7);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l2284);
+ test(M, 0x1);
+ jle(l22f0, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1+LDA3*1-0x80]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ pinsrb(xmm0, eax, 0x7);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l22f0);
+ sub(N, 0x8);
+ cmp(N, 0x8);
+ jge(l2018, T_NEAR);
+ align(4);
+
+L(l2300);
+ cmp(N, 0x4);
+ jl(l24c4, T_NEAR);
+ align(4);
+
+L(l230c);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*2]);
+ lea(I, ptr[A1+LDA*4]);
+ mov(A, I);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l2398, T_NEAR);
+ align(4);
+
+L(l2324);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ sub(A1, -16);
+ movdqu(xmm2, xword[A2-0x80]);
+ movdqu(xmm3, xword[A2+LDA*1-0x80]);
+ sub(A2, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ movdqu(xword[B-0x60], xmm4);
+ movdqu(xword[B-0x50], xmm3);
+ sub(B, -64);
+ dec(I);
+ jg(l2324, T_NEAR);
+ align(4);
+
+L(l2398);
+ test(M, 0x8);
+ jle(l23e8, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ sub(A1, -8);
+ movq(xmm2, qword[A2-0x80]);
+ movq(xmm3, qword[A2+LDA*1-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ sub(B, -32);
+ align(4);
+
+L(l23e8);
+ test(M, 0x4);
+ jle(l242c, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ sub(A1, -4);
+ movd(xmm2, dword[A2-0x80]);
+ movd(xmm3, dword[A2+LDA*1-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l242c);
+ test(M, 0x2);
+ jle(l2474, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA*1-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x3);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l2474);
+ test(M, 0x1);
+ jle(l24b4, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x3);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l24b4);
+ sub(N, 0x4);
+ cmp(N, 0x4);
+ jge(l230c, T_NEAR);
+ align(4);
+
+L(l24c4);
+ cmp(N, 0x2);
+ jl(l25d6, T_NEAR);
+ align(4);
+
+L(l24d0);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*1]);
+ lea(I, ptr[A1+LDA*2]);
+ mov(A, I);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l2520, T_NEAR);
+ align(4);
+
+L(l24e8);
+ movdqu(xmm0, xword[A1-0x80]);
+ sub(A1, -16);
+ movdqu(xmm1, xword[A2-0x80]);
+ sub(A2, -16);
+ movdqa(xmm2, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm2, xmm1);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm2);
+ sub(B, -32);
+ dec(I);
+ jg(l24e8, T_NEAR);
+ align(4);
+
+L(l2520);
+ test(M, 0x8);
+ jle(l254c, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ sub(A1, -8);
+ movq(xmm1, qword[A2-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l254c);
+ test(M, 0x4);
+ jle(l2578, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ sub(A1, -4);
+ movd(xmm1, dword[A2-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l2578);
+ test(M, 0x2);
+ jle(l25a8, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x1);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l25a8);
+ test(M, 0x1);
+ jle(l25c8, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ mov(byte[B-0x80], al);
+ mov(al, byte[A2-0x80]);
+ mov(byte[B-0x7f], al);
+ sub(B, -2);
+ align(4);
+
+L(l25c8);
+ sub(N, 0x2);
+ cmp(N, 0x2);
+ jge(l24d0, T_NEAR);
+ align(4);
+
+L(l25d6);
+ cmp(N, 0x1);
+ jl(l2690, T_NEAR);
+ align(4);
+
+L(l25e0);
+ mov(A1, A);
+ add(A, LDA);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l260c, T_NEAR);
+ align(4);
+
+L(l25f0);
+ movdqu(xmm0, xword[A1-0x80]);
+ sub(A1, -16);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ dec(I);
+ jg(l25f0, T_NEAR);
+ align(4);
+
+L(l260c);
+ test(M, 0x8);
+ jle(l262c, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ sub(A1, -8);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l262c);
+ test(M, 0x4);
+ jle(l264c, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ sub(A1, -4);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l264c);
+ test(M, 0x2);
+ jle(l2668, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ mov(word[B-0x80], ax);
+ sub(A1, -2);
+ sub(B, -2);
+ align(4);
+
+L(l2668);
+ test(M, 0x1);
+ jle(l2680, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ mov(byte[B-0x80], al);
+ sub(B, -1);
+ align(4);
+
+L(l2680);
+ sub(N, 0x1);
+ cmp(N, 0x1);
+ jge(l25e0, T_NEAR);
+ align(4);
+
+L(l2690);
+
+ postamble();
+}
+outLocalLabel();
+
+#undef M
+#undef N
+#undef A
+#undef LDA
+#undef ALPHA
+#undef B
+#undef I
+#undef A1
+#undef A2
+#undef LDA3
+#ifdef _WIN32
+#undef ARG_ALPHA
+#undef ARG_B
+#endif
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_bn_kern.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_bn_kern.cpp
new file mode 100644
index 0000000000..56c36ee14a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_bn_kern.cpp
@@ -0,0 +1,564 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "jit_generator.hpp"
+#include "common.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+jit_avx512_core_u8_copy_bn_kern::jit_avx512_core_u8_copy_bn_kern(): jit_generator(nullptr, GEMM_CODE_SIZE)
+{
+
+#ifndef _WIN32
+#define M rdi
+#define N rsi
+#define A rdx
+#define LDA rcx
+#define ALPHA r8
+#define B r9
+
+#define I rax
+#define A1 r10
+#define A2 r8
+#define LDA3 r11
+
+#else
+
+#define M rcx
+#define N rdx
+#define A r8
+#define LDA r9
+#define ALPHA rax
+#define B rdi
+
+#define I rax
+#define A1 rsi
+#define A2 r10
+#define LDA3 r11
+
+#define ARG_ALPHA 40+stacksize+rsp
+#define ARG_B 48+stacksize+rsp
+
+#endif
+
+inLocalLabel();
+{
+
+Xbyak::Label l118;
+Xbyak::Label l1a8;
+Xbyak::Label l20;
+Xbyak::Label l218;
+Xbyak::Label l28c;
+Xbyak::Label l2f8;
+Xbyak::Label l308;
+Xbyak::Label l314;
+Xbyak::Label l32c;
+Xbyak::Label l3a0;
+Xbyak::Label l3c;
+Xbyak::Label l3f0;
+Xbyak::Label l434;
+Xbyak::Label l47c;
+Xbyak::Label l4bc;
+Xbyak::Label l4cc;
+Xbyak::Label l4d8;
+Xbyak::Label l4f0;
+Xbyak::Label l528;
+Xbyak::Label l554;
+Xbyak::Label l580;
+Xbyak::Label l5b0;
+Xbyak::Label l5d0;
+Xbyak::Label l5de;
+Xbyak::Label l5e8;
+Xbyak::Label l5f8;
+Xbyak::Label l614;
+Xbyak::Label l634;
+Xbyak::Label l654;
+Xbyak::Label l670;
+Xbyak::Label l688;
+Xbyak::Label l698;
+
+ preamble();
+#ifdef _WIN32
+ auto stacksize = get_size_of_abi_save_regs();
+ mov(ALPHA, ptr[ARG_ALPHA]);
+ mov(B, ptr[ARG_B]);
+#endif
+
+ mov(N, qword[N]);
+ mov(M, qword[M]);
+ mov(LDA, qword[LDA]);
+ sub(A, -128);
+ sub(B, -128);
+ lea(LDA3, ptr[LDA+LDA*2]);
+ cmp(N, 0x8);
+ jl(l308, T_NEAR);
+ align(4);
+
+L(l20);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*4]);
+ lea(I, ptr[A1+LDA*8]);
+ mov(A, I);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l118, T_NEAR);
+ align(4);
+
+L(l3c);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ sub(A1, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x60], xmm1);
+ movdqu(xword[B-0x40], xmm4);
+ movdqu(xword[B-0x20], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ sub(A2, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ movdqu(xword[B-0x50], xmm1);
+ movdqu(xword[B-0x30], xmm4);
+ movdqu(xword[B-0x10], xmm3);
+ sub(B, -128);
+ dec(I);
+ jg(l3c, T_NEAR);
+ align(4);
+
+L(l118);
+ test(M, 0x8);
+ jle(l1a8, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ movq(xmm2, qword[A1+LDA*2-0x80]);
+ movq(xmm3, qword[A1+LDA3*1-0x80]);
+ sub(A1, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x60], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ movdqu(xword[B-0x50], xmm1);
+ sub(B, -64);
+ align(4);
+
+L(l1a8);
+ test(M, 0x4);
+ jle(l218, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ movd(xmm2, dword[A1+LDA*2-0x80]);
+ movd(xmm3, dword[A1+LDA3*1-0x80]);
+ sub(A1, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ sub(B, -32);
+ align(4);
+
+L(l218);
+ test(M, 0x2);
+ jle(l28c, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A1+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A1+LDA3*1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x7);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l28c);
+ test(M, 0x1);
+ jle(l2f8, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1+LDA3*1-0x80]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ pinsrb(xmm0, eax, 0x7);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l2f8);
+ sub(N, 0x8);
+ cmp(N, 0x8);
+ jge(l20, T_NEAR);
+ align(4);
+
+L(l308);
+ cmp(N, 0x4);
+ jl(l4cc, T_NEAR);
+ align(4);
+
+L(l314);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*2]);
+ lea(I, ptr[A1+LDA*4]);
+ mov(A, I);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l3a0, T_NEAR);
+ align(4);
+
+L(l32c);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ sub(A1, -16);
+ movdqu(xmm2, xword[A2-0x80]);
+ movdqu(xmm3, xword[A2+LDA*1-0x80]);
+ sub(A2, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ movdqu(xword[B-0x60], xmm4);
+ movdqu(xword[B-0x50], xmm3);
+ sub(B, -64);
+ dec(I);
+ jg(l32c, T_NEAR);
+ align(4);
+
+L(l3a0);
+ test(M, 0x8);
+ jle(l3f0, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ sub(A1, -8);
+ movq(xmm2, qword[A2-0x80]);
+ movq(xmm3, qword[A2+LDA*1-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ sub(B, -32);
+ align(4);
+
+L(l3f0);
+ test(M, 0x4);
+ jle(l434, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ sub(A1, -4);
+ movd(xmm2, dword[A2-0x80]);
+ movd(xmm3, dword[A2+LDA*1-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l434);
+ test(M, 0x2);
+ jle(l47c, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA*1-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x3);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l47c);
+ test(M, 0x1);
+ jle(l4bc, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x3);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l4bc);
+ sub(N, 0x4);
+ cmp(N, 0x4);
+ jge(l314, T_NEAR);
+ align(4);
+
+L(l4cc);
+ cmp(N, 0x2);
+ jl(l5de, T_NEAR);
+ align(4);
+
+L(l4d8);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*1]);
+ lea(I, ptr[A1+LDA*2]);
+ mov(A, I);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l528, T_NEAR);
+ align(4);
+
+L(l4f0);
+ movdqu(xmm0, xword[A1-0x80]);
+ sub(A1, -16);
+ movdqu(xmm1, xword[A2-0x80]);
+ sub(A2, -16);
+ movdqa(xmm2, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm2, xmm1);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm2);
+ sub(B, -32);
+ dec(I);
+ jg(l4f0, T_NEAR);
+ align(4);
+
+L(l528);
+ test(M, 0x8);
+ jle(l554, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ sub(A1, -8);
+ movq(xmm1, qword[A2-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l554);
+ test(M, 0x4);
+ jle(l580, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ sub(A1, -4);
+ movd(xmm1, dword[A2-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l580);
+ test(M, 0x2);
+ jle(l5b0, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x1);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l5b0);
+ test(M, 0x1);
+ jle(l5d0, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ mov(byte[B-0x80], al);
+ mov(al, byte[A2-0x80]);
+ mov(byte[B-0x7f], al);
+ sub(B, -2);
+ align(4);
+
+L(l5d0);
+ sub(N, 0x2);
+ cmp(N, 0x2);
+ jge(l4d8, T_NEAR);
+ align(4);
+
+L(l5de);
+ cmp(N, 0x1);
+ jl(l698, T_NEAR);
+ align(4);
+
+L(l5e8);
+ mov(A1, A);
+ add(A, LDA);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l614, T_NEAR);
+ align(4);
+
+L(l5f8);
+ movdqu(xmm0, xword[A1-0x80]);
+ sub(A1, -16);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ dec(I);
+ jg(l5f8, T_NEAR);
+ align(4);
+
+L(l614);
+ test(M, 0x8);
+ jle(l634, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ sub(A1, -8);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l634);
+ test(M, 0x4);
+ jle(l654, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ sub(A1, -4);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l654);
+ test(M, 0x2);
+ jle(l670, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ mov(word[B-0x80], ax);
+ sub(A1, -2);
+ sub(B, -2);
+ align(4);
+
+L(l670);
+ test(M, 0x1);
+ jle(l688, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ mov(byte[B-0x80], al);
+ sub(B, -1);
+ align(4);
+
+L(l688);
+ sub(N, 0x1);
+ cmp(N, 0x1);
+ jge(l5e8, T_NEAR);
+ align(4);
+
+L(l698);
+
+ postamble();
+}
+outLocalLabel();
+
+#undef M
+#undef N
+#undef A
+#undef LDA
+#undef ALPHA
+#undef B
+#undef I
+#undef A1
+#undef A2
+#undef LDA3
+#ifdef _WIN32
+#undef ARG_ALPHA
+#undef ARG_B
+#endif
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_bt_kern.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_bt_kern.cpp
new file mode 100644
index 0000000000..53e99d94de
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_bt_kern.cpp
@@ -0,0 +1,501 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "jit_generator.hpp"
+#include "common.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+jit_avx512_core_u8_copy_bt_kern::jit_avx512_core_u8_copy_bt_kern(): jit_generator(nullptr, GEMM_CODE_SIZE)
+{
+
+#ifndef _WIN32
+#define M rdi
+#define N rsi
+#define A rdx
+#define LDA rcx
+#define ALPHA r8
+#define B r9
+
+#define I rax
+#define A1 r10
+#define A2 r8
+#define LDA3 r11
+
+#else
+
+#define M rcx
+#define N rdx
+#define A r8
+#define LDA r9
+#define ALPHA rax
+#define B rdi
+
+#define I rax
+#define A1 rsi
+#define A2 r10
+#define LDA3 r11
+
+#define ARG_ALPHA 40+stacksize+rsp
+#define ARG_B 48+stacksize+rsp
+
+#endif
+
+inLocalLabel();
+{
+
+Xbyak::Label l120;
+Xbyak::Label l14c;
+Xbyak::Label l168;
+Xbyak::Label l178;
+Xbyak::Label l184;
+Xbyak::Label l194;
+Xbyak::Label l20;
+Xbyak::Label l20c;
+Xbyak::Label l250;
+Xbyak::Label l27c;
+Xbyak::Label l298;
+Xbyak::Label l2a8;
+Xbyak::Label l2b4;
+Xbyak::Label l2c8;
+Xbyak::Label l34;
+Xbyak::Label l360;
+Xbyak::Label l3b4;
+Xbyak::Label l3e8;
+Xbyak::Label l400;
+Xbyak::Label l40e;
+Xbyak::Label l418;
+Xbyak::Label l428;
+Xbyak::Label l4a0;
+Xbyak::Label l4e8;
+Xbyak::Label l50c;
+Xbyak::Label l524;
+Xbyak::Label l534;
+Xbyak::Label lcc;
+
+ preamble();
+#ifdef _WIN32
+ auto stacksize = get_size_of_abi_save_regs();
+ mov(ALPHA, ptr[ARG_ALPHA]);
+ mov(B, ptr[ARG_B]);
+#endif
+
+ mov(M, qword[M]);
+ mov(N, qword[N]);
+ mov(LDA, qword[LDA]);
+ lea(LDA3, ptr[LDA+LDA*2]);
+ sub(A, -128);
+ sub(B, -128);
+ cmp(N, 0x8);
+ jl(l178, T_NEAR);
+ align(4);
+
+L(l20);
+ mov(A1, A);
+ add(A, 0x8);
+ mov(I, M);
+ sar(I, 0x3);
+ jle(lcc, T_NEAR);
+ align(4);
+
+L(l34);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqu(xword[B-0x60], xmm0);
+ movdqu(xword[B-0x50], xmm1);
+ sub(B, -64);
+ dec(I);
+ jg(l34, T_NEAR);
+ align(4);
+
+L(lcc);
+ test(M, 0x4);
+ jle(l120, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ sub(B, -32);
+ align(4);
+
+L(l120);
+ test(M, 0x2);
+ jle(l14c, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l14c);
+ test(M, 0x1);
+ jle(l168, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l168);
+ sub(N, 0x8);
+ cmp(N, 0x8);
+ jge(l20, T_NEAR);
+ align(4);
+
+L(l178);
+ cmp(N, 0x4);
+ jl(l2a8, T_NEAR);
+ align(4);
+
+L(l184);
+ mov(A1, A);
+ add(A, 0x4);
+ mov(I, M);
+ sar(I, 0x3);
+ jle(l20c, T_NEAR);
+ align(4);
+
+L(l194);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ movdqu(xword[B-0x70], xmm0);
+ sub(B, -32);
+ dec(I);
+ jg(l194, T_NEAR);
+ align(4);
+
+L(l20c);
+ test(M, 0x4);
+ jle(l250, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l250);
+ test(M, 0x2);
+ jle(l27c, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l27c);
+ test(M, 0x1);
+ jle(l298, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l298);
+ sub(N, 0x4);
+ cmp(N, 0x4);
+ jge(l184, T_NEAR);
+ align(4);
+
+L(l2a8);
+ cmp(N, 0x2);
+ jl(l40e, T_NEAR);
+ align(4);
+
+L(l2b4);
+ mov(A1, A);
+ add(A, 0x2);
+ mov(LDA3, M);
+ sar(LDA3, 0x3);
+ jle(l360, T_NEAR);
+ align(4);
+
+L(l2c8);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm4, eax, 0x0);
+ punpcklbw(xmm1, xmm2);
+ punpcklbw(xmm3, xmm4);
+ punpcklwd(xmm1, xmm3);
+ punpcklqdq(xmm0, xmm1);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ dec(LDA3);
+ jg(l2c8, T_NEAR);
+ align(4);
+
+L(l360);
+ test(M, 0x4);
+ jle(l3b4, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l3b4);
+ test(M, 0x2);
+ jle(l3e8, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l3e8);
+ test(M, 0x1);
+ jle(l400, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ mov(word[B-0x80], ax);
+ sub(B, -2);
+ align(4);
+
+L(l400);
+ sub(N, 0x2);
+ cmp(N, 0x2);
+ jge(l2b4, T_NEAR);
+ align(4);
+
+L(l40e);
+ cmp(N, 0x1);
+ jl(l534, T_NEAR);
+ align(4);
+
+L(l418);
+ mov(A1, A);
+ add(A, 0x1);
+ mov(LDA3, M);
+ sar(LDA3, 0x3);
+ jle(l4a0, T_NEAR);
+ align(4);
+
+L(l428);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x7);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ dec(LDA3);
+ jg(l428, T_NEAR);
+ align(4);
+
+L(l4a0);
+ test(M, 0x4);
+ jle(l4e8, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x3);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l4e8);
+ test(M, 0x2);
+ jle(l50c, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ mov(byte[B-0x80], al);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ mov(byte[B-0x7f], al);
+ sub(B, -2);
+ align(4);
+
+L(l50c);
+ test(M, 0x1);
+ jle(l524, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ mov(byte[B-0x80], al);
+ sub(B, -1);
+ align(4);
+
+L(l524);
+ sub(N, 0x1);
+ cmp(N, 0x1);
+ jge(l418, T_NEAR);
+ align(4);
+
+L(l534);
+
+ postamble();
+}
+outLocalLabel();
+
+#undef M
+#undef N
+#undef A
+#undef LDA
+#undef ALPHA
+#undef B
+#undef I
+#undef A1
+#undef A2
+#undef LDA3
+#ifdef _WIN32
+#undef ARG_ALPHA
+#undef ARG_B
+#endif
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_an_kern.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_an_kern.cpp
new file mode 100644
index 0000000000..49a312fc88
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_an_kern.cpp
@@ -0,0 +1,1283 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "jit_generator.hpp"
+#include "common.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+jit_avx512_core_u8_copy_sum_an_kern::jit_avx512_core_u8_copy_sum_an_kern(): jit_generator(nullptr, GEMM_CODE_SIZE)
+{
+
+#ifndef _WIN32
+#define M rdi
+#define N rsi
+#define A rdx
+#define LDA rcx
+#define ALPHA r8
+#define B r9
+
+#define I rax
+#define A1 r10
+#define A2 r8
+#define LDA3 r11
+
+#define ARG_BIAS 24+stacksize+rsp
+
+#else
+
+#define M rcx
+#define N rdx
+#define A r8
+#define LDA r9
+#define ALPHA rax
+#define B rdi
+
+#define I rax
+#define A1 rsi
+#define A2 r10
+#define LDA3 r11
+
+#define ARG_ALPHA 40+stacksize+rsp
+#define ARG_B 48+stacksize+rsp
+#define ARG_BIAS 72+stacksize+rsp
+
+#endif
+
+inLocalLabel();
+{
+
+Xbyak::Label l1024;
+Xbyak::Label l1090;
+Xbyak::Label l10d4;
+Xbyak::Label l10fc;
+Xbyak::Label l111a;
+Xbyak::Label l1124;
+Xbyak::Label l113c;
+Xbyak::Label l11d4;
+Xbyak::Label l1234;
+Xbyak::Label l1278;
+Xbyak::Label l129c;
+Xbyak::Label l12bc;
+Xbyak::Label l20;
+Xbyak::Label l2a0;
+Xbyak::Label l3c0;
+Xbyak::Label l438;
+Xbyak::Label l480;
+Xbyak::Label l48c;
+Xbyak::Label l4c8;
+Xbyak::Label l5c;
+Xbyak::Label l6a8;
+Xbyak::Label l7b4;
+Xbyak::Label l850;
+Xbyak::Label l89c;
+Xbyak::Label l8a8;
+Xbyak::Label l8d0;
+Xbyak::Label l9d0;
+Xbyak::Label la64;
+Xbyak::Label lab8;
+Xbyak::Label lae8;
+Xbyak::Label laf4;
+Xbyak::Label lb14;
+Xbyak::Label lc30;
+Xbyak::Label lcc8;
+Xbyak::Label ld1c;
+Xbyak::Label ld54;
+Xbyak::Label ld78;
+Xbyak::Label ld84;
+Xbyak::Label ld9c;
+Xbyak::Label le58;
+Xbyak::Label lebc;
+Xbyak::Label lef8;
+Xbyak::Label lf1c;
+Xbyak::Label lf3c;
+Xbyak::Label lf48;
+Xbyak::Label lf60;
+
+ preamble();
+ auto stacksize = get_size_of_abi_save_regs();
+#ifdef _WIN32
+ mov(ALPHA, ptr[ARG_ALPHA]);
+ mov(B, ptr[ARG_B]);
+#endif
+
+ mov(M, qword[M]);
+ mov(N, qword[N]);
+ mov(LDA, qword[LDA]);
+ lea(LDA3, ptr[LDA+LDA*2]);
+ sub(A, -128);
+ sub(B, -128);
+ cmp(N, 0x30);
+ jl(l480, T_NEAR);
+ align(4);
+
+L(l20);
+ mov(A1, A);
+ add(A, 0x30);
+ vxorps(ymm8, ymm8, ymm8);
+ vxorps(ymm9, ymm9, ymm9);
+ vxorps(ymm10, ymm10, ymm10);
+ vxorps(ymm11, ymm11, ymm11);
+ vxorps(ymm12, ymm12, ymm12);
+ vxorps(ymm13, ymm13, ymm13);
+ vxorps(ymm14, ymm14, ymm14);
+ vxorps(ymm15, ymm15, ymm15);
+ mov(I, M);
+ sar(I, 0x2);
+ jle(l2a0, T_NEAR);
+ align(4);
+
+L(l5c);
+ vmovdqu(xmm0, xword[A1-0x80]);
+ vmovdqu(xmm1, xword[A1+LDA*1-0x80]);
+ vmovdqu(xmm2, xword[A1+LDA*2-0x80]);
+ vmovdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ vpunpcklbw(xmm4, xmm0, xmm1);
+ vpunpckhbw(xmm5, xmm0, xmm1);
+ vpunpcklbw(xmm6, xmm2, xmm3);
+ vpunpckhbw(xmm7, xmm2, xmm3);
+ vpunpcklwd(xmm0, xmm4, xmm6);
+ vpunpckhwd(xmm1, xmm4, xmm6);
+ vpunpcklwd(xmm2, xmm5, xmm7);
+ vpunpckhwd(xmm3, xmm5, xmm7);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm1);
+ vmovhlps(xmm7, xmm1, xmm1);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm8, ymm8, ymm5);
+ vmovdqu(xword[B-0x80], xmm0);
+ vmovdqu(xword[B-0x70], xmm1);
+ vpmovsxbw(ymm5, xmm2);
+ vmovhlps(xmm6, xmm2, xmm2);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm3);
+ vmovhlps(xmm7, xmm3, xmm3);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm9, ymm9, ymm5);
+ vmovdqu(xword[B-0x60], xmm2);
+ vmovdqu(xword[B-0x50], xmm3);
+ vmovdqu(xmm0, xword[A1-0x70]);
+ vmovdqu(xmm1, xword[A1+LDA*1-0x70]);
+ vmovdqu(xmm2, xword[A1+LDA*2-0x70]);
+ vmovdqu(xmm3, xword[A1+LDA3*1-0x70]);
+ vpunpcklbw(xmm4, xmm0, xmm1);
+ vpunpckhbw(xmm5, xmm0, xmm1);
+ vpunpcklbw(xmm6, xmm2, xmm3);
+ vpunpckhbw(xmm7, xmm2, xmm3);
+ vpunpcklwd(xmm0, xmm4, xmm6);
+ vpunpckhwd(xmm1, xmm4, xmm6);
+ vpunpcklwd(xmm2, xmm5, xmm7);
+ vpunpckhwd(xmm3, xmm5, xmm7);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm1);
+ vmovhlps(xmm7, xmm1, xmm1);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm10, ymm10, ymm5);
+ vmovdqu(xword[B-0x40], xmm0);
+ vmovdqu(xword[B-0x30], xmm1);
+ vpmovsxbw(ymm5, xmm2);
+ vmovhlps(xmm6, xmm2, xmm2);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm3);
+ vmovhlps(xmm7, xmm3, xmm3);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm11, ymm11, ymm5);
+ vmovdqu(xword[B-0x20], xmm2);
+ vmovdqu(xword[B-0x10], xmm3);
+ vmovdqu(xmm0, xword[A1-0x60]);
+ vmovdqu(xmm1, xword[A1+LDA*1-0x60]);
+ vmovdqu(xmm2, xword[A1+LDA*2-0x60]);
+ vmovdqu(xmm3, xword[A1+LDA3*1-0x60]);
+ lea(A1, ptr[A1+LDA*4]);
+ vpunpcklbw(xmm4, xmm0, xmm1);
+ vpunpckhbw(xmm5, xmm0, xmm1);
+ vpunpcklbw(xmm6, xmm2, xmm3);
+ vpunpckhbw(xmm7, xmm2, xmm3);
+ vpunpcklwd(xmm0, xmm4, xmm6);
+ vpunpckhwd(xmm1, xmm4, xmm6);
+ vpunpcklwd(xmm2, xmm5, xmm7);
+ vpunpckhwd(xmm3, xmm5, xmm7);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm1);
+ vmovhlps(xmm7, xmm1, xmm1);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm12, ymm12, ymm5);
+ vmovdqu(xword[B], xmm0);
+ vmovdqu(xword[B+0x10], xmm1);
+ vpmovsxbw(ymm5, xmm2);
+ vmovhlps(xmm6, xmm2, xmm2);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm3);
+ vmovhlps(xmm7, xmm3, xmm3);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm13, ymm13, ymm5);
+ vmovdqu(xword[B+0x20], xmm2);
+ vmovdqu(xword[B+0x30], xmm3);
+ sub(B, -192);
+ dec(I);
+ jg(l5c, T_NEAR);
+ align(4);
+
+L(l2a0);
+ test(M, 0x2);
+ jle(l3c0, T_NEAR);
+ vmovdqu(xmm0, xword[A1-0x80]);
+ vmovdqu(xmm1, xword[A1-0x70]);
+ vmovdqu(xmm2, xword[A1-0x60]);
+ add(A1, LDA);
+ vmovdqu(xmm6, xword[A1-0x80]);
+ vmovdqu(xmm4, xword[A1-0x70]);
+ vmovdqu(xmm5, xword[A1-0x60]);
+ add(A1, LDA);
+ vpunpcklbw(xmm3, xmm0, xmm6);
+ vpunpckhbw(xmm0, xmm0, xmm6);
+ vpmovsxbw(ymm7, xmm3);
+ vmovhlps(xmm6, xmm3, xmm3);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm7, ymm7, ymm6);
+ vpmovsxwd(ymm7, xmm7);
+ vpaddd(ymm8, ymm8, ymm7);
+ vmovdqu(xword[B-0x80], xmm3);
+ vpmovsxbw(ymm7, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm7, ymm7, ymm6);
+ vpmovsxwd(ymm7, xmm7);
+ vpaddd(ymm9, ymm9, ymm7);
+ vmovdqu(xword[B-0x70], xmm0);
+ vpunpcklbw(xmm3, xmm1, xmm4);
+ vpunpckhbw(xmm0, xmm1, xmm4);
+ vpmovsxbw(ymm7, xmm3);
+ vmovhlps(xmm6, xmm3, xmm3);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm7, ymm7, ymm6);
+ vpmovsxwd(ymm7, xmm7);
+ vpaddd(ymm10, ymm10, ymm7);
+ vmovdqu(xword[B-0x60], xmm3);
+ vpmovsxbw(ymm7, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm7, ymm7, ymm6);
+ vpmovsxwd(ymm7, xmm7);
+ vpaddd(ymm11, ymm11, ymm7);
+ vmovdqu(xword[B-0x50], xmm0);
+ vpunpcklbw(xmm3, xmm2, xmm5);
+ vpunpckhbw(xmm0, xmm2, xmm5);
+ vpmovsxbw(ymm7, xmm3);
+ vmovhlps(xmm6, xmm3, xmm3);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm7, ymm7, ymm6);
+ vpmovsxwd(ymm7, xmm7);
+ vpaddd(ymm12, ymm12, ymm7);
+ vmovdqu(xword[B-0x40], xmm3);
+ vpmovsxbw(ymm7, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm7, ymm7, ymm6);
+ vpmovsxwd(ymm7, xmm7);
+ vpaddd(ymm13, ymm13, ymm7);
+ vmovdqu(xword[B-0x30], xmm0);
+ sub(B, -96);
+ align(4);
+
+L(l3c0);
+ test(M, 0x1);
+ jle(l438, T_NEAR);
+ vmovdqu(xmm0, xword[A1-0x80]);
+ vmovdqu(xmm1, xword[A1-0x70]);
+ vmovdqu(xmm2, xword[A1-0x60]);
+ add(A1, LDA);
+ vpmovsxbd(ymm7, xmm0);
+ vpaddd(ymm8, ymm8, ymm7);
+ vmovhlps(xmm7, xmm0, xmm0);
+ vpmovsxbd(ymm7, xmm7);
+ vpaddd(ymm9, ymm9, ymm7);
+ vmovdqu(xword[B-0x80], xmm0);
+ vpmovsxbd(ymm7, xmm1);
+ vpaddd(ymm10, ymm10, ymm7);
+ vmovhlps(xmm7, xmm1, xmm1);
+ vpmovsxbd(ymm7, xmm7);
+ vpaddd(ymm11, ymm11, ymm7);
+ vmovdqu(xword[B-0x70], xmm1);
+ vpmovsxbd(ymm7, xmm2);
+ vpaddd(ymm12, ymm12, ymm7);
+ vmovhlps(xmm7, xmm2, xmm2);
+ vpmovsxbd(ymm7, xmm7);
+ vpaddd(ymm13, ymm13, ymm7);
+ vmovdqu(xword[B-0x60], xmm2);
+ sub(B, -48);
+ align(4);
+
+L(l438);
+ mov(A1, qword[ARG_BIAS]);
+ vmovdqu(yword[A1], ymm8);
+ vmovdqu(yword[A1+0x20], ymm9);
+ vmovdqu(yword[A1+0x40], ymm10);
+ vmovdqu(yword[A1+0x60], ymm11);
+ vmovdqu(yword[A1+0x80], ymm12);
+ vmovdqu(yword[A1+0xa0], ymm13);
+ add(qword[ARG_BIAS], 0xc0);
+ sub(N, 0x30);
+ cmp(N, 0x30);
+ jge(l20, T_NEAR);
+ vzeroupper();
+ align(4);
+
+L(l480);
+ cmp(N, 0x20);
+ jl(l89c, T_NEAR);
+ align(4);
+
+L(l48c);
+ mov(A1, A);
+ add(A, 0x20);
+ pxor(xmm8, xmm8);
+ pxor(xmm9, xmm9);
+ pxor(xmm10, xmm10);
+ pxor(xmm11, xmm11);
+ pxor(xmm12, xmm12);
+ pxor(xmm13, xmm13);
+ pxor(xmm14, xmm14);
+ pxor(xmm15, xmm15);
+ mov(I, M);
+ sar(I, 0x2);
+ jle(l6a8, T_NEAR);
+ align(4);
+
+L(l4c8);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ movdqa(xmm4, xmm0);
+ punpcklbw(xmm0, xmm1);
+ punpckhbw(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpcklbw(xmm2, xmm3);
+ punpckhbw(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqa(xmm2, xmm4);
+ punpcklwd(xmm4, xmm5);
+ punpckhwd(xmm2, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B-0x60], xmm4);
+ pmovsxbw(xmm5, xmm2);
+ movhlps(xmm6, xmm2);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B-0x50], xmm2);
+ movdqu(xmm0, xword[A1-0x70]);
+ movdqu(xmm1, xword[A1+LDA*1-0x70]);
+ movdqu(xmm2, xword[A1+LDA*2-0x70]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x70]);
+ lea(A1, ptr[A1+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpcklbw(xmm0, xmm1);
+ punpckhbw(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpcklbw(xmm2, xmm3);
+ punpckhbw(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ movdqa(xmm2, xmm4);
+ punpcklwd(xmm4, xmm5);
+ punpckhwd(xmm2, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm12, xmm5);
+ movdqu(xword[B-0x40], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm13, xmm5);
+ movdqu(xword[B-0x30], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ movdqu(xword[B-0x20], xmm4);
+ pmovsxbw(xmm5, xmm2);
+ movhlps(xmm6, xmm2);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm15, xmm5);
+ movdqu(xword[B-0x10], xmm2);
+ sub(B, -128);
+ dec(I);
+ jg(l4c8, T_NEAR);
+ align(4);
+
+L(l6a8);
+ test(M, 0x2);
+ jle(l7b4, T_NEAR);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1-0x70]);
+ add(A1, LDA);
+ movdqu(xmm2, xword[A1-0x80]);
+ movdqu(xmm3, xword[A1-0x70]);
+ add(A1, LDA);
+ movdqa(xmm4, xmm0);
+ punpcklbw(xmm0, xmm2);
+ punpckhbw(xmm4, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm4);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm11, xmm6);
+ movdqu(xword[B-0x70], xmm4);
+ movdqa(xmm4, xmm1);
+ punpcklbw(xmm1, xmm3);
+ punpckhbw(xmm4, xmm3);
+ pmovsxbw(xmm5, xmm1);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm12, xmm5);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm13, xmm6);
+ movdqu(xword[B-0x60], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm15, xmm6);
+ movdqu(xword[B-0x50], xmm4);
+ sub(B, -64);
+ align(4);
+
+L(l7b4);
+ test(M, 0x1);
+ jle(l850, T_NEAR);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1-0x70]);
+ add(A1, LDA);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm8, xmm5);
+ pshufd(xmm6, xmm0, 0x55);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ pshufd(xmm5, xmm0, 0xaa);
+ pmovsxbd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ pshufd(xmm6, xmm0, 0xff);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm11, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbd(xmm5, xmm1);
+ paddd(xmm12, xmm5);
+ pshufd(xmm6, xmm1, 0x55);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm13, xmm6);
+ pshufd(xmm5, xmm1, 0xaa);
+ pmovsxbd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ pshufd(xmm6, xmm1, 0xff);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm15, xmm6);
+ movdqu(xword[B-0x70], xmm1);
+ sub(B, -32);
+ align(4);
+
+L(l850);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm8);
+ movdqu(xword[A1+0x10], xmm9);
+ movdqu(xword[A1+0x20], xmm10);
+ movdqu(xword[A1+0x30], xmm11);
+ movdqu(xword[A1+0x40], xmm12);
+ movdqu(xword[A1+0x50], xmm13);
+ movdqu(xword[A1+0x60], xmm14);
+ movdqu(xword[A1+0x70], xmm15);
+ add(qword[ARG_BIAS], 0x80);
+ sub(N, 0x20);
+ cmp(N, 0x20);
+ jge(l48c, T_NEAR);
+ align(4);
+
+L(l89c);
+ cmp(N, 0x10);
+ jl(lae8, T_NEAR);
+ align(4);
+
+L(l8a8);
+ mov(A1, A);
+ add(A, 0x10);
+ pxor(xmm8, xmm8);
+ pxor(xmm9, xmm9);
+ pxor(xmm10, xmm10);
+ pxor(xmm11, xmm11);
+ mov(I, M);
+ sar(I, 0x2);
+ jle(l9d0, T_NEAR);
+ align(4);
+
+L(l8d0);
+ movdqu(xmm0, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqu(xmm1, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqu(xmm2, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqu(xmm3, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqa(xmm4, xmm0);
+ punpcklbw(xmm0, xmm1);
+ punpckhbw(xmm4, xmm1);
+ movdqa(xmm1, xmm2);
+ punpcklbw(xmm2, xmm3);
+ punpckhbw(xmm1, xmm3);
+ movdqa(xmm3, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm3, xmm2);
+ movdqa(xmm2, xmm4);
+ punpcklwd(xmm4, xmm1);
+ punpckhwd(xmm2, xmm1);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm3);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ pmovsxbw(xmm5, xmm2);
+ movhlps(xmm6, xmm2);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B-0x60], xmm4);
+ movdqu(xword[B-0x50], xmm2);
+ sub(B, -64);
+ dec(I);
+ jg(l8d0, T_NEAR);
+ align(4);
+
+L(l9d0);
+ test(M, 0x2);
+ jle(la64, T_NEAR);
+ movdqu(xmm0, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqu(xmm1, xword[A1-0x80]);
+ add(A1, LDA);
+ movdqa(xmm2, xmm0);
+ punpcklbw(xmm0, xmm1);
+ punpckhbw(xmm2, xmm1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ pmovsxbw(xmm5, xmm2);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movhlps(xmm6, xmm2);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm11, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm2);
+ sub(B, -32);
+ align(4);
+
+L(la64);
+ test(M, 0x1);
+ jle(lab8, T_NEAR);
+ movdqu(xmm0, xword[A1-0x80]);
+ add(A1, LDA);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm8, xmm5);
+ pshufd(xmm6, xmm0, 0x55);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ pshufd(xmm5, xmm0, 0xaa);
+ pmovsxbd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ pshufd(xmm6, xmm0, 0xff);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm11, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(lab8);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm8);
+ movdqu(xword[A1+0x10], xmm9);
+ movdqu(xword[A1+0x20], xmm10);
+ movdqu(xword[A1+0x30], xmm11);
+ add(qword[ARG_BIAS], 0x40);
+ sub(N, 0x10);
+ cmp(N, 0x10);
+ jge(l8a8, T_NEAR);
+ align(4);
+
+L(lae8);
+ cmp(N, 0x8);
+ jl(ld78, T_NEAR);
+ align(4);
+
+L(laf4);
+ mov(A1, A);
+ add(A, 0x8);
+ pxor(xmm8, xmm8);
+ pxor(xmm9, xmm9);
+ mov(I, M);
+ sar(I, 0x3);
+ jle(lc30, T_NEAR);
+ align(4);
+
+L(lb14);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x60], xmm0);
+ movdqu(xword[B-0x50], xmm1);
+ sub(B, -64);
+ dec(I);
+ jg(lb14, T_NEAR);
+ align(4);
+
+L(lc30);
+ test(M, 0x4);
+ jle(lcc8, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ sub(B, -32);
+ align(4);
+
+L(lcc8);
+ test(M, 0x2);
+ jle(ld1c, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(ld1c);
+ test(M, 0x1);
+ jle(ld54, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ pmovsxbd(xmm5, xmm0);
+ pshufd(xmm6, xmm0, 0x55);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm8, xmm5);
+ paddd(xmm9, xmm6);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(ld54);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm8);
+ movdqu(xword[A1+0x10], xmm9);
+ add(qword[ARG_BIAS], 0x20);
+ sub(N, 0x8);
+ cmp(N, 0x8);
+ jge(laf4, T_NEAR);
+ align(4);
+
+L(ld78);
+ cmp(N, 0x4);
+ jl(lf3c, T_NEAR);
+ align(4);
+
+L(ld84);
+ mov(A1, A);
+ add(A, 0x4);
+ pxor(xmm7, xmm7);
+ mov(I, M);
+ sar(I, 0x3);
+ jle(le58, T_NEAR);
+ align(4);
+
+L(ld9c);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ sub(B, -32);
+ dec(I);
+ jg(ld9c, T_NEAR);
+ align(4);
+
+L(le58);
+ test(M, 0x4);
+ jle(lebc, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(lebc);
+ test(M, 0x2);
+ jle(lef8, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(lef8);
+ test(M, 0x1);
+ jle(lf1c, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(lf1c);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x10);
+ sub(N, 0x4);
+ cmp(N, 0x4);
+ jge(ld84, T_NEAR);
+ align(4);
+
+L(lf3c);
+ cmp(N, 0x2);
+ jl(l111a, T_NEAR);
+ align(4);
+
+L(lf48);
+ mov(A1, A);
+ add(A, 0x2);
+ pxor(xmm7, xmm7);
+ mov(LDA3, M);
+ sar(LDA3, 0x3);
+ jle(l1024, T_NEAR);
+ align(4);
+
+L(lf60);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm4, eax, 0x0);
+ punpcklbw(xmm1, xmm2);
+ punpcklbw(xmm3, xmm4);
+ punpcklwd(xmm1, xmm3);
+ punpcklqdq(xmm0, xmm1);
+ pshufd(xmm6, xmm0, 0xd8);
+ pmovsxbw(xmm5, xmm6);
+ movhlps(xmm6, xmm6);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ dec(LDA3);
+ jg(lf60, T_NEAR);
+ align(4);
+
+L(l1024);
+ test(M, 0x4);
+ jle(l1090, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l1090);
+ test(M, 0x2);
+ jle(l10d4, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l10d4);
+ test(M, 0x1);
+ jle(l10fc, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ mov(word[B-0x80], ax);
+ sub(B, -2);
+ align(4);
+
+L(l10fc);
+ mov(A1, qword[ARG_BIAS]);
+ movq(qword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x8);
+ sub(N, 0x2);
+ cmp(N, 0x2);
+ jge(lf48, T_NEAR);
+ align(4);
+
+L(l111a);
+ cmp(N, 0x1);
+ jl(l12bc, T_NEAR);
+ align(4);
+
+L(l1124);
+ mov(A1, A);
+ add(A, 0x1);
+ pxor(xmm7, xmm7);
+ mov(LDA3, M);
+ sar(LDA3, 0x3);
+ jle(l11d4, T_NEAR);
+ align(4);
+
+L(l113c);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x7);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ dec(LDA3);
+ jg(l113c, T_NEAR);
+ align(4);
+
+L(l11d4);
+ test(M, 0x4);
+ jle(l1234, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x3);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l1234);
+ test(M, 0x2);
+ jle(l1278, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x0);
+ mov(byte[B-0x80], al);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ mov(byte[B-0x7f], al);
+ sub(B, -2);
+ align(4);
+
+L(l1278);
+ test(M, 0x1);
+ jle(l129c, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ mov(byte[B-0x80], al);
+ sub(B, -1);
+ align(4);
+
+L(l129c);
+ mov(A1, qword[ARG_BIAS]);
+ movd(dword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x4);
+ sub(N, 0x1);
+ cmp(N, 0x1);
+ jge(l1124, T_NEAR);
+ align(4);
+
+L(l12bc);
+
+ postamble();
+}
+outLocalLabel();
+
+#undef M
+#undef N
+#undef A
+#undef LDA
+#undef ALPHA
+#undef B
+#undef I
+#undef A1
+#undef A2
+#undef LDA3
+#ifdef _WIN32
+#undef ARG_ALPHA
+#undef ARG_B
+#endif
+#undef ARG_BIAS
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_at_kern.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_at_kern.cpp
new file mode 100644
index 0000000000..a4f4ff09c6
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_at_kern.cpp
@@ -0,0 +1,3163 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "jit_generator.hpp"
+#include "common.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+jit_avx512_core_u8_copy_sum_at_kern::jit_avx512_core_u8_copy_sum_at_kern(): jit_generator(nullptr, GEMM_CODE_SIZE)
+{
+
+#ifndef _WIN32
+#define M rdi
+#define N rsi
+#define A rdx
+#define LDA rcx
+#define ALPHA r8
+#define B r9
+
+#define I rax
+#define A1 r10
+#define A2 r8
+#define LDA3 r11
+
+#define ARG_BIAS 24+stacksize+rsp
+
+#else
+
+#define M rcx
+#define N rdx
+#define A r8
+#define LDA r9
+#define ALPHA rax
+#define B rdi
+
+#define I rax
+#define A1 rsi
+#define A2 r10
+#define LDA3 r11
+
+#define ARG_ALPHA 40+stacksize+rsp
+#define ARG_B 48+stacksize+rsp
+#define ARG_BIAS 72+stacksize+rsp
+
+#endif
+
+inLocalLabel();
+{
+
+Xbyak::Label l1750;
+Xbyak::Label l1b6c;
+Xbyak::Label l1e14;
+Xbyak::Label l20;
+Xbyak::Label l2068;
+Xbyak::Label l226c;
+Xbyak::Label l22b8;
+Xbyak::Label l22c4;
+Xbyak::Label l22f4;
+Xbyak::Label l26b4;
+Xbyak::Label l28cc;
+Xbyak::Label l2a2c;
+Xbyak::Label l2b5c;
+Xbyak::Label l2c64;
+Xbyak::Label l2c94;
+Xbyak::Label l2ca0;
+Xbyak::Label l2cc8;
+Xbyak::Label l2eac;
+Xbyak::Label l2fc0;
+Xbyak::Label l3078;
+Xbyak::Label l3118;
+Xbyak::Label l319c;
+Xbyak::Label l31c0;
+Xbyak::Label l31cc;
+Xbyak::Label l31ec;
+Xbyak::Label l32e4;
+Xbyak::Label l3378;
+Xbyak::Label l33dc;
+Xbyak::Label l3434;
+Xbyak::Label l347c;
+Xbyak::Label l349c;
+Xbyak::Label l34a8;
+Xbyak::Label l34c8;
+Xbyak::Label l3558;
+Xbyak::Label l35b0;
+Xbyak::Label l35f4;
+Xbyak::Label l3638;
+Xbyak::Label l366c;
+Xbyak::Label l368a;
+Xbyak::Label l3694;
+Xbyak::Label l36a8;
+Xbyak::Label l36ec;
+Xbyak::Label l3728;
+Xbyak::Label l3760;
+Xbyak::Label l3794;
+Xbyak::Label l37b8;
+Xbyak::Label l37d8;
+Xbyak::Label l5cc;
+Xbyak::Label l6c;
+Xbyak::Label l968;
+Xbyak::Label lc80;
+Xbyak::Label lf1c;
+Xbyak::Label lf64;
+Xbyak::Label lf70;
+Xbyak::Label lfb4;
+
+ preamble();
+ auto stacksize = get_size_of_abi_save_regs();
+#ifdef _WIN32
+ mov(ALPHA, ptr[ARG_ALPHA]);
+ mov(B, ptr[ARG_B]);
+#endif
+
+ mov(N, qword[N]);
+ mov(M, qword[M]);
+ mov(LDA, qword[LDA]);
+ sub(A, -128);
+ sub(B, -128);
+ lea(LDA3, ptr[LDA+LDA*2]);
+ cmp(N, 0x30);
+ jl(lf64, T_NEAR);
+ align(4);
+
+L(l20);
+ mov(A1, A);
+ mov(I, LDA);
+ shl(I, 0x5);
+ lea(I, ptr[I+LDA*8]);
+ lea(I, ptr[I+LDA*8]);
+ add(A, I);
+ vxorps(ymm8, ymm8, ymm8);
+ vxorps(ymm9, ymm9, ymm9);
+ vxorps(ymm10, ymm10, ymm10);
+ vxorps(ymm11, ymm11, ymm11);
+ vxorps(ymm12, ymm12, ymm12);
+ vxorps(ymm13, ymm13, ymm13);
+ vxorps(ymm14, ymm14, ymm14);
+ vxorps(ymm15, ymm15, ymm15);
+ mov(I, M);
+ sar(I, 0x3);
+ jle(l5cc, T_NEAR);
+ align(4);
+
+L(l6c);
+ vmovq(xmm0, qword[A1-0x80]);
+ vmovq(xmm1, qword[A1+LDA*1-0x80]);
+ vmovq(xmm2, qword[A1+LDA*2-0x80]);
+ vmovq(xmm3, qword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ vpunpckldq(xmm1, xmm0, xmm1);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm1, xmm3);
+ vpunpckhqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B-0x80], xmm0);
+ vmovdqu(xword[B+0x40], xmm1);
+ vmovq(xmm2, qword[A2-0x80]);
+ vmovq(xmm3, qword[A2+LDA*1-0x80]);
+ vmovq(xmm4, qword[A2+LDA*2-0x80]);
+ vmovq(xmm5, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpckldq(xmm5, xmm4, xmm5);
+ vpunpcklqdq(xmm2, xmm3, xmm5);
+ vpunpckhqdq(xmm3, xmm3, xmm5);
+ vmovdqu(xword[B-0x70], xmm2);
+ vmovdqu(xword[B+0x50], xmm3);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm2);
+ vmovhlps(xmm7, xmm2, xmm2);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm8, ymm8, ymm5);
+ vpmovsxbw(ymm5, xmm1);
+ vmovhlps(xmm6, xmm1, xmm1);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm3);
+ vmovhlps(xmm7, xmm3, xmm3);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm8, ymm8, ymm5);
+ vmovq(xmm0, qword[A2-0x80]);
+ vmovq(xmm1, qword[A2+LDA*1-0x80]);
+ vmovq(xmm2, qword[A2+LDA*2-0x80]);
+ vmovq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm1, xmm0, xmm1);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm1, xmm3);
+ vpunpckhqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B-0x60], xmm0);
+ vmovdqu(xword[B+0x60], xmm1);
+ vmovq(xmm2, qword[A2-0x80]);
+ vmovq(xmm3, qword[A2+LDA*1-0x80]);
+ vmovq(xmm4, qword[A2+LDA*2-0x80]);
+ vmovq(xmm5, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpckldq(xmm5, xmm4, xmm5);
+ vpunpcklqdq(xmm2, xmm3, xmm5);
+ vpunpckhqdq(xmm3, xmm3, xmm5);
+ vmovdqu(xword[B-0x50], xmm2);
+ vmovdqu(xword[B+0x70], xmm3);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm2);
+ vmovhlps(xmm7, xmm2, xmm2);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm9, ymm9, ymm5);
+ vpmovsxbw(ymm5, xmm1);
+ vmovhlps(xmm6, xmm1, xmm1);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm3);
+ vmovhlps(xmm7, xmm3, xmm3);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm9, ymm9, ymm5);
+ vmovq(xmm0, qword[A2-0x80]);
+ vmovq(xmm1, qword[A2+LDA*1-0x80]);
+ vmovq(xmm2, qword[A2+LDA*2-0x80]);
+ vmovq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm1, xmm0, xmm1);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm1, xmm3);
+ vpunpckhqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B-0x40], xmm0);
+ vmovdqu(xword[B+0x80], xmm1);
+ vmovq(xmm2, qword[A2-0x80]);
+ vmovq(xmm3, qword[A2+LDA*1-0x80]);
+ vmovq(xmm4, qword[A2+LDA*2-0x80]);
+ vmovq(xmm5, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpckldq(xmm5, xmm4, xmm5);
+ vpunpcklqdq(xmm2, xmm3, xmm5);
+ vpunpckhqdq(xmm3, xmm3, xmm5);
+ vmovdqu(xword[B-0x30], xmm2);
+ vmovdqu(xword[B+0x90], xmm3);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm2);
+ vmovhlps(xmm7, xmm2, xmm2);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm10, ymm10, ymm5);
+ vpmovsxbw(ymm5, xmm1);
+ vmovhlps(xmm6, xmm1, xmm1);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm3);
+ vmovhlps(xmm7, xmm3, xmm3);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm10, ymm10, ymm5);
+ vmovq(xmm0, qword[A2-0x80]);
+ vmovq(xmm1, qword[A2+LDA*1-0x80]);
+ vmovq(xmm2, qword[A2+LDA*2-0x80]);
+ vmovq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm1, xmm0, xmm1);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm1, xmm3);
+ vpunpckhqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B-0x20], xmm0);
+ vmovdqu(xword[B+0xa0], xmm1);
+ vmovq(xmm2, qword[A2-0x80]);
+ vmovq(xmm3, qword[A2+LDA*1-0x80]);
+ vmovq(xmm4, qword[A2+LDA*2-0x80]);
+ vmovq(xmm5, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpckldq(xmm5, xmm4, xmm5);
+ vpunpcklqdq(xmm2, xmm3, xmm5);
+ vpunpckhqdq(xmm3, xmm3, xmm5);
+ vmovdqu(xword[B-0x10], xmm2);
+ vmovdqu(xword[B+0xb0], xmm3);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm2);
+ vmovhlps(xmm7, xmm2, xmm2);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm11, ymm11, ymm5);
+ vpmovsxbw(ymm5, xmm1);
+ vmovhlps(xmm6, xmm1, xmm1);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm3);
+ vmovhlps(xmm7, xmm3, xmm3);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm11, ymm11, ymm5);
+ vmovq(xmm0, qword[A2-0x80]);
+ vmovq(xmm1, qword[A2+LDA*1-0x80]);
+ vmovq(xmm2, qword[A2+LDA*2-0x80]);
+ vmovq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm1, xmm0, xmm1);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm1, xmm3);
+ vpunpckhqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B], xmm0);
+ vmovdqu(xword[B+0xc0], xmm1);
+ vmovq(xmm2, qword[A2-0x80]);
+ vmovq(xmm3, qword[A2+LDA*1-0x80]);
+ vmovq(xmm4, qword[A2+LDA*2-0x80]);
+ vmovq(xmm5, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpckldq(xmm5, xmm4, xmm5);
+ vpunpcklqdq(xmm2, xmm3, xmm5);
+ vpunpckhqdq(xmm3, xmm3, xmm5);
+ vmovdqu(xword[B+0x10], xmm2);
+ vmovdqu(xword[B+0xd0], xmm3);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm2);
+ vmovhlps(xmm7, xmm2, xmm2);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm12, ymm12, ymm5);
+ vpmovsxbw(ymm5, xmm1);
+ vmovhlps(xmm6, xmm1, xmm1);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm3);
+ vmovhlps(xmm7, xmm3, xmm3);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm12, ymm12, ymm5);
+ vmovq(xmm0, qword[A2-0x80]);
+ vmovq(xmm1, qword[A2+LDA*1-0x80]);
+ vmovq(xmm2, qword[A2+LDA*2-0x80]);
+ vmovq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm1, xmm0, xmm1);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm1, xmm3);
+ vpunpckhqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B+0x20], xmm0);
+ vmovdqu(xword[B+0xe0], xmm1);
+ vmovq(xmm2, qword[A2-0x80]);
+ vmovq(xmm3, qword[A2+LDA*1-0x80]);
+ vmovq(xmm4, qword[A2+LDA*2-0x80]);
+ vmovq(xmm5, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm3, xmm2, xmm3);
+ vpunpckldq(xmm5, xmm4, xmm5);
+ vpunpcklqdq(xmm2, xmm3, xmm5);
+ vpunpckhqdq(xmm3, xmm3, xmm5);
+ vmovdqu(xword[B+0x30], xmm2);
+ vmovdqu(xword[B+0xf0], xmm3);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm2);
+ vmovhlps(xmm7, xmm2, xmm2);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm13, ymm13, ymm5);
+ vpmovsxbw(ymm5, xmm1);
+ vmovhlps(xmm6, xmm1, xmm1);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm3);
+ vmovhlps(xmm7, xmm3, xmm3);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm13, ymm13, ymm5);
+ sub(A1, -8);
+ sub(B, -384);
+ dec(I);
+ jg(l6c, T_NEAR);
+ align(4);
+
+L(l5cc);
+ test(M, 0x4);
+ jle(l968, T_NEAR);
+ vmovd(xmm0, dword[A1-0x80]);
+ vmovd(xmm1, dword[A1+LDA*1-0x80]);
+ vmovd(xmm2, dword[A1+LDA*2-0x80]);
+ vmovd(xmm3, dword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ vpunpckldq(xmm0, xmm0, xmm1);
+ vpunpckldq(xmm2, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm0, xmm2);
+ vmovdqu(xword[B-0x80], xmm0);
+ vmovd(xmm1, dword[A2-0x80]);
+ vmovd(xmm2, dword[A2+LDA*1-0x80]);
+ vmovd(xmm3, dword[A2+LDA*2-0x80]);
+ vmovd(xmm4, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm1, xmm1, xmm2);
+ vpunpckldq(xmm3, xmm3, xmm4);
+ vpunpcklqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B-0x70], xmm1);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm1);
+ vmovhlps(xmm7, xmm1, xmm1);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm8, ymm8, ymm5);
+ vmovd(xmm0, dword[A2-0x80]);
+ vmovd(xmm1, dword[A2+LDA*1-0x80]);
+ vmovd(xmm2, dword[A2+LDA*2-0x80]);
+ vmovd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm0, xmm0, xmm1);
+ vpunpckldq(xmm2, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm0, xmm2);
+ vmovdqu(xword[B-0x60], xmm0);
+ vmovd(xmm1, dword[A2-0x80]);
+ vmovd(xmm2, dword[A2+LDA*1-0x80]);
+ vmovd(xmm3, dword[A2+LDA*2-0x80]);
+ vmovd(xmm4, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm1, xmm1, xmm2);
+ vpunpckldq(xmm3, xmm3, xmm4);
+ vpunpcklqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B-0x50], xmm1);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm1);
+ vmovhlps(xmm7, xmm1, xmm1);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm9, ymm9, ymm5);
+ vmovd(xmm0, dword[A2-0x80]);
+ vmovd(xmm1, dword[A2+LDA*1-0x80]);
+ vmovd(xmm2, dword[A2+LDA*2-0x80]);
+ vmovd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm0, xmm0, xmm1);
+ vpunpckldq(xmm2, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm0, xmm2);
+ vmovdqu(xword[B-0x40], xmm0);
+ vmovd(xmm1, dword[A2-0x80]);
+ vmovd(xmm2, dword[A2+LDA*1-0x80]);
+ vmovd(xmm3, dword[A2+LDA*2-0x80]);
+ vmovd(xmm4, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm1, xmm1, xmm2);
+ vpunpckldq(xmm3, xmm3, xmm4);
+ vpunpcklqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B-0x30], xmm1);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm1);
+ vmovhlps(xmm7, xmm1, xmm1);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm10, ymm10, ymm5);
+ vmovd(xmm0, dword[A2-0x80]);
+ vmovd(xmm1, dword[A2+LDA*1-0x80]);
+ vmovd(xmm2, dword[A2+LDA*2-0x80]);
+ vmovd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm0, xmm0, xmm1);
+ vpunpckldq(xmm2, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm0, xmm2);
+ vmovdqu(xword[B-0x20], xmm0);
+ vmovd(xmm1, dword[A2-0x80]);
+ vmovd(xmm2, dword[A2+LDA*1-0x80]);
+ vmovd(xmm3, dword[A2+LDA*2-0x80]);
+ vmovd(xmm4, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm1, xmm1, xmm2);
+ vpunpckldq(xmm3, xmm3, xmm4);
+ vpunpcklqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B-0x10], xmm1);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm1);
+ vmovhlps(xmm7, xmm1, xmm1);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm11, ymm11, ymm5);
+ vmovd(xmm0, dword[A2-0x80]);
+ vmovd(xmm1, dword[A2+LDA*1-0x80]);
+ vmovd(xmm2, dword[A2+LDA*2-0x80]);
+ vmovd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm0, xmm0, xmm1);
+ vpunpckldq(xmm2, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm0, xmm2);
+ vmovdqu(xword[B], xmm0);
+ vmovd(xmm1, dword[A2-0x80]);
+ vmovd(xmm2, dword[A2+LDA*1-0x80]);
+ vmovd(xmm3, dword[A2+LDA*2-0x80]);
+ vmovd(xmm4, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm1, xmm1, xmm2);
+ vpunpckldq(xmm3, xmm3, xmm4);
+ vpunpcklqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B+0x10], xmm1);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm1);
+ vmovhlps(xmm7, xmm1, xmm1);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm12, ymm12, ymm5);
+ vmovd(xmm0, dword[A2-0x80]);
+ vmovd(xmm1, dword[A2+LDA*1-0x80]);
+ vmovd(xmm2, dword[A2+LDA*2-0x80]);
+ vmovd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm0, xmm0, xmm1);
+ vpunpckldq(xmm2, xmm2, xmm3);
+ vpunpcklqdq(xmm0, xmm0, xmm2);
+ vmovdqu(xword[B+0x20], xmm0);
+ vmovd(xmm1, dword[A2-0x80]);
+ vmovd(xmm2, dword[A2+LDA*1-0x80]);
+ vmovd(xmm3, dword[A2+LDA*2-0x80]);
+ vmovd(xmm4, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpunpckldq(xmm1, xmm1, xmm2);
+ vpunpckldq(xmm3, xmm3, xmm4);
+ vpunpcklqdq(xmm1, xmm1, xmm3);
+ vmovdqu(xword[B+0x30], xmm1);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxbw(ymm6, xmm1);
+ vmovhlps(xmm7, xmm1, xmm1);
+ vpmovsxbw(ymm7, xmm7);
+ vphaddw(ymm6, ymm6, ymm7);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm13, ymm13, ymm5);
+ sub(A1, -4);
+ sub(B, -192);
+ align(4);
+
+L(l968);
+ test(M, 0x2);
+ jle(lc80, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x1);
+ mov(ax, word[A1+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x2);
+ mov(ax, word[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ vpinsrw(xmm0, xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrw(xmm0, xmm0, eax, 0x7);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm8, ymm8, ymm5);
+ vmovdqu(xword[B-0x80], xmm0);
+ mov(ax, word[A2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrw(xmm0, xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm9, ymm9, ymm5);
+ vmovdqu(xword[B-0x70], xmm0);
+ mov(ax, word[A2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrw(xmm0, xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm10, ymm10, ymm5);
+ vmovdqu(xword[B-0x60], xmm0);
+ mov(ax, word[A2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrw(xmm0, xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm11, ymm11, ymm5);
+ vmovdqu(xword[B-0x50], xmm0);
+ mov(ax, word[A2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrw(xmm0, xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm12, ymm12, ymm5);
+ vmovdqu(xword[B-0x40], xmm0);
+ mov(ax, word[A2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrw(xmm0, xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ vpinsrw(xmm0, xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ vpmovsxbw(ymm5, xmm0);
+ vmovhlps(xmm6, xmm0, xmm0);
+ vpmovsxbw(ymm6, xmm6);
+ vphaddw(ymm5, ymm5, ymm6);
+ vpmovsxwd(ymm5, xmm5);
+ vpaddd(ymm13, ymm13, ymm5);
+ vmovdqu(xword[B-0x30], xmm0);
+ sub(A1, -2);
+ sub(B, -96);
+ align(4);
+
+L(lc80);
+ test(M, 0x1);
+ jle(lf1c, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x1);
+ mov(al, byte[A1+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x2);
+ mov(al, byte[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0xf);
+ vpmovsxbd(ymm7, xmm0);
+ vpaddd(ymm8, ymm8, ymm7);
+ vmovhlps(xmm7, xmm0, xmm0);
+ vpmovsxbd(ymm7, xmm7);
+ vpaddd(ymm9, ymm9, ymm7);
+ vmovdqu(xword[B-0x80], xmm0);
+ mov(al, byte[A2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x0);
+ mov(al, byte[A2+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x1);
+ mov(al, byte[A2+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x2);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0xf);
+ vpmovsxbd(ymm7, xmm0);
+ vpaddd(ymm10, ymm10, ymm7);
+ vmovhlps(xmm7, xmm0, xmm0);
+ vpmovsxbd(ymm7, xmm7);
+ vpaddd(ymm11, ymm11, ymm7);
+ vmovdqu(xword[B-0x70], xmm0);
+ mov(al, byte[A2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x0);
+ mov(al, byte[A2+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x1);
+ mov(al, byte[A2+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x2);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ vpinsrb(xmm0, xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ vpinsrb(xmm0, xmm0, eax, 0xf);
+ vpmovsxbd(ymm7, xmm0);
+ vpaddd(ymm12, ymm12, ymm7);
+ vmovhlps(xmm7, xmm0, xmm0);
+ vpmovsxbd(ymm7, xmm7);
+ vpaddd(ymm13, ymm13, ymm7);
+ vmovdqu(xword[B-0x60], xmm0);
+ sub(B, -48);
+ align(4);
+
+L(lf1c);
+ mov(A1, qword[ARG_BIAS]);
+ vmovdqu(yword[A1], ymm8);
+ vmovdqu(yword[A1+0x20], ymm9);
+ vmovdqu(yword[A1+0x40], ymm10);
+ vmovdqu(yword[A1+0x60], ymm11);
+ vmovdqu(yword[A1+0x80], ymm12);
+ vmovdqu(yword[A1+0xa0], ymm13);
+ add(qword[ARG_BIAS], 0xc0);
+ sub(N, 0x30);
+ cmp(N, 0x30);
+ jge(l20, T_NEAR);
+ vzeroupper();
+ align(4);
+
+L(lf64);
+ cmp(N, 0x20);
+ jl(l22b8, T_NEAR);
+ align(4);
+
+L(lf70);
+ mov(A1, A);
+ mov(I, LDA);
+ shl(I, 0x5);
+ add(A, I);
+ pxor(xmm8, xmm8);
+ pxor(xmm9, xmm9);
+ pxor(xmm10, xmm10);
+ pxor(xmm11, xmm11);
+ pxor(xmm12, xmm12);
+ pxor(xmm13, xmm13);
+ pxor(xmm14, xmm14);
+ pxor(xmm15, xmm15);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l1750, T_NEAR);
+ align(4);
+
+L(lfb4);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B+0x80], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B+0x100], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B+0x10], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B+0x90], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B+0x110], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B-0x60], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B+0x20], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B+0xa0], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B+0x120], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B-0x50], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B+0x30], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B+0xb0], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B+0x130], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm12, xmm5);
+ movdqu(xword[B-0x40], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm12, xmm5);
+ movdqu(xword[B+0x40], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm12, xmm5);
+ movdqu(xword[B+0xc0], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm12, xmm5);
+ movdqu(xword[B+0x140], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm13, xmm5);
+ movdqu(xword[B-0x30], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm13, xmm5);
+ movdqu(xword[B+0x50], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm13, xmm5);
+ movdqu(xword[B+0xd0], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm13, xmm5);
+ movdqu(xword[B+0x150], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ movdqu(xword[B-0x20], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ movdqu(xword[B+0x60], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ movdqu(xword[B+0xe0], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ movdqu(xword[B+0x160], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm15, xmm5);
+ movdqu(xword[B-0x10], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm15, xmm5);
+ movdqu(xword[B+0x70], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm15, xmm5);
+ movdqu(xword[B+0xf0], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm15, xmm5);
+ movdqu(xword[B+0x170], xmm3);
+ sub(A1, -16);
+ sub(B, -512);
+ dec(I);
+ jg(lfb4, T_NEAR);
+ align(4);
+
+L(l1750);
+ test(M, 0x8);
+ jle(l1b6c, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ movq(xmm2, qword[A1+LDA*2-0x80]);
+ movq(xmm3, qword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B+0x10], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B-0x60], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B+0x20], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B-0x50], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B+0x30], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm12, xmm5);
+ movdqu(xword[B-0x40], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm12, xmm5);
+ movdqu(xword[B+0x40], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm13, xmm5);
+ movdqu(xword[B-0x30], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm13, xmm5);
+ movdqu(xword[B+0x50], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ movdqu(xword[B-0x20], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ movdqu(xword[B+0x60], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm15, xmm5);
+ movdqu(xword[B-0x10], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm15, xmm5);
+ movdqu(xword[B+0x70], xmm1);
+ sub(A1, -8);
+ sub(B, -256);
+ align(4);
+
+L(l1b6c);
+ test(M, 0x4);
+ jle(l1e14, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ movd(xmm2, dword[A1+LDA*2-0x80]);
+ movd(xmm3, dword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B-0x60], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B-0x50], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm12, xmm5);
+ movdqu(xword[B-0x40], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm13, xmm5);
+ movdqu(xword[B-0x30], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ movdqu(xword[B-0x20], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm15, xmm5);
+ movdqu(xword[B-0x10], xmm0);
+ sub(A1, -4);
+ sub(B, -128);
+ align(4);
+
+L(l1e14);
+ test(M, 0x2);
+ jle(l2068, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A1+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x7);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm11, xmm6);
+ movdqu(xword[B-0x70], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm12, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm13, xmm6);
+ movdqu(xword[B-0x60], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ lea(A2, ptr[A2+LDA*4]);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm15, xmm6);
+ movdqu(xword[B-0x50], xmm0);
+ sub(A1, -2);
+ sub(B, -64);
+ align(4);
+
+L(l2068);
+ test(M, 0x1);
+ jle(l226c, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xf);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm8, xmm5);
+ pshufd(xmm6, xmm0, 0x55);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ pshufd(xmm5, xmm0, 0xaa);
+ pmovsxbd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ pshufd(xmm6, xmm0, 0xff);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm11, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xf);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm12, xmm5);
+ pshufd(xmm6, xmm0, 0x55);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm13, xmm6);
+ pshufd(xmm5, xmm0, 0xaa);
+ pmovsxbd(xmm5, xmm5);
+ paddd(xmm14, xmm5);
+ pshufd(xmm6, xmm0, 0xff);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm15, xmm6);
+ movdqu(xword[B-0x70], xmm0);
+ sub(B, -32);
+ align(4);
+
+L(l226c);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm8);
+ movdqu(xword[A1+0x10], xmm9);
+ movdqu(xword[A1+0x20], xmm10);
+ movdqu(xword[A1+0x30], xmm11);
+ movdqu(xword[A1+0x40], xmm12);
+ movdqu(xword[A1+0x50], xmm13);
+ movdqu(xword[A1+0x60], xmm14);
+ movdqu(xword[A1+0x70], xmm15);
+ add(qword[ARG_BIAS], 0x80);
+ sub(N, 0x20);
+ cmp(N, 0x20);
+ jge(lf70, T_NEAR);
+ align(4);
+
+L(l22b8);
+ cmp(N, 0x10);
+ jl(l2c94, T_NEAR);
+ align(4);
+
+L(l22c4);
+ mov(A1, A);
+ mov(I, LDA);
+ shl(I, 0x4);
+ add(A, I);
+ pxor(xmm8, xmm8);
+ pxor(xmm9, xmm9);
+ pxor(xmm10, xmm10);
+ pxor(xmm11, xmm11);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l26b4, T_NEAR);
+ align(4);
+
+L(l22f4);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x40], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B+0x40], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x30], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B+0x10], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B+0x50], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B-0x60], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B-0x20], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B+0x20], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B+0x60], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B-0x50], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B-0x10], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B+0x30], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B+0x70], xmm3);
+ sub(A1, -16);
+ sub(B, -256);
+ dec(I);
+ jg(l22f4, T_NEAR);
+ align(4);
+
+L(l26b4);
+ test(M, 0x8);
+ jle(l28cc, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ movq(xmm2, qword[A1+LDA*2-0x80]);
+ movq(xmm3, qword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x40], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x30], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B-0x60], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B-0x20], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B-0x50], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B-0x10], xmm1);
+ sub(A1, -8);
+ sub(B, -128);
+ align(4);
+
+L(l28cc);
+ test(M, 0x4);
+ jle(l2a2c, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ movd(xmm2, dword[A1+LDA*2-0x80]);
+ movd(xmm3, dword[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movdqu(xword[B-0x60], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm11, xmm5);
+ movdqu(xword[B-0x50], xmm0);
+ sub(A1, -4);
+ sub(B, -64);
+ align(4);
+
+L(l2a2c);
+ test(M, 0x2);
+ jle(l2b5c, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A1+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x7);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ pinsrw(xmm0, eax, 0x7);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm11, xmm6);
+ movdqu(xword[B-0x70], xmm0);
+ sub(A1, -2);
+ sub(B, -32);
+ align(4);
+
+L(l2b5c);
+ test(M, 0x1);
+ jle(l2c64, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1+LDA3*1-0x80]);
+ lea(A2, ptr[A1+LDA*4]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0x7);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x8);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x9);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xa);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ lea(A2, ptr[A2+LDA*4]);
+ pinsrb(xmm0, eax, 0xb);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0xc);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0xd);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0xe);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ pinsrb(xmm0, eax, 0xf);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm8, xmm5);
+ pshufd(xmm6, xmm0, 0x55);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ pshufd(xmm5, xmm0, 0xaa);
+ pmovsxbd(xmm5, xmm5);
+ paddd(xmm10, xmm5);
+ pshufd(xmm6, xmm0, 0xff);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm11, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l2c64);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm8);
+ movdqu(xword[A1+0x10], xmm9);
+ movdqu(xword[A1+0x20], xmm10);
+ movdqu(xword[A1+0x30], xmm11);
+ add(qword[ARG_BIAS], 0x40);
+ sub(N, 0x10);
+ cmp(N, 0x10);
+ jge(l22c4, T_NEAR);
+ align(4);
+
+L(l2c94);
+ cmp(N, 0x8);
+ jl(l31c0, T_NEAR);
+ align(4);
+
+L(l2ca0);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*4]);
+ lea(I, ptr[A1+LDA*8]);
+ mov(A, I);
+ pxor(xmm8, xmm8);
+ pxor(xmm9, xmm9);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l2eac, T_NEAR);
+ align(4);
+
+L(l2cc8);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ sub(A1, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x60], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x40], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x20], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ sub(A2, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x50], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x30], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x10], xmm3);
+ sub(B, -128);
+ dec(I);
+ jg(l2cc8, T_NEAR);
+ align(4);
+
+L(l2eac);
+ test(M, 0x8);
+ jle(l2fc0, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ movq(xmm2, qword[A1+LDA*2-0x80]);
+ movq(xmm3, qword[A1+LDA3*1-0x80]);
+ sub(A1, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x60], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x50], xmm1);
+ sub(B, -64);
+ align(4);
+
+L(l2fc0);
+ test(M, 0x4);
+ jle(l3078, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ movd(xmm2, dword[A1+LDA*2-0x80]);
+ movd(xmm3, dword[A1+LDA3*1-0x80]);
+ sub(A1, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ sub(B, -32);
+ align(4);
+
+L(l3078);
+ test(M, 0x2);
+ jle(l3118, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A1+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A1+LDA3*1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x7);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l3118);
+ test(M, 0x1);
+ jle(l319c, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1+LDA3*1-0x80]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ pinsrb(xmm0, eax, 0x7);
+ pmovsxbd(xmm5, xmm0);
+ pshufd(xmm6, xmm0, 0x55);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm8, xmm5);
+ paddd(xmm9, xmm6);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l319c);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm8);
+ movdqu(xword[A1+0x10], xmm9);
+ add(qword[ARG_BIAS], 0x20);
+ sub(N, 0x8);
+ cmp(N, 0x8);
+ jge(l2ca0, T_NEAR);
+ align(4);
+
+L(l31c0);
+ cmp(N, 0x4);
+ jl(l349c, T_NEAR);
+ align(4);
+
+L(l31cc);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*2]);
+ lea(I, ptr[A1+LDA*4]);
+ mov(A, I);
+ pxor(xmm7, xmm7);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l32e4, T_NEAR);
+ align(4);
+
+L(l31ec);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ sub(A1, -16);
+ movdqu(xmm2, xword[A2-0x80]);
+ movdqu(xmm3, xword[A2+LDA*1-0x80]);
+ sub(A2, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x70], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x60], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x50], xmm3);
+ sub(B, -64);
+ dec(I);
+ jg(l31ec, T_NEAR);
+ align(4);
+
+L(l32e4);
+ test(M, 0x8);
+ jle(l3378, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ sub(A1, -8);
+ movq(xmm2, qword[A2-0x80]);
+ movq(xmm3, qword[A2+LDA*1-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x70], xmm1);
+ sub(B, -32);
+ align(4);
+
+L(l3378);
+ test(M, 0x4);
+ jle(l33dc, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ sub(A1, -4);
+ movd(xmm2, dword[A2-0x80]);
+ movd(xmm3, dword[A2+LDA*1-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l33dc);
+ test(M, 0x2);
+ jle(l3434, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA*1-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x3);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l3434);
+ test(M, 0x1);
+ jle(l347c, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x3);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l347c);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x10);
+ sub(N, 0x4);
+ cmp(N, 0x4);
+ jge(l31cc, T_NEAR);
+ align(4);
+
+L(l349c);
+ cmp(N, 0x2);
+ jl(l368a, T_NEAR);
+ align(4);
+
+L(l34a8);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*1]);
+ lea(I, ptr[A1+LDA*2]);
+ mov(A, I);
+ pxor(xmm7, xmm7);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l3558, T_NEAR);
+ align(4);
+
+L(l34c8);
+ movdqu(xmm0, xword[A1-0x80]);
+ sub(A1, -16);
+ movdqu(xmm1, xword[A2-0x80]);
+ sub(A2, -16);
+ movdqa(xmm2, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm2, xmm1);
+ pshufd(xmm6, xmm0, 0xd8);
+ pmovsxbw(xmm5, xmm6);
+ movhlps(xmm6, xmm6);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pshufd(xmm6, xmm2, 0xd8);
+ pmovsxbw(xmm5, xmm6);
+ movhlps(xmm6, xmm6);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x70], xmm2);
+ sub(B, -32);
+ dec(I);
+ jg(l34c8, T_NEAR);
+ align(4);
+
+L(l3558);
+ test(M, 0x8);
+ jle(l35b0, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ sub(A1, -8);
+ movq(xmm1, qword[A2-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ pshufd(xmm6, xmm0, 0xd8);
+ pmovsxbw(xmm5, xmm6);
+ movhlps(xmm6, xmm6);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l35b0);
+ test(M, 0x4);
+ jle(l35f4, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ sub(A1, -4);
+ movd(xmm1, dword[A2-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l35f4);
+ test(M, 0x2);
+ jle(l3638, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l3638);
+ test(M, 0x1);
+ jle(l366c, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(byte[B-0x80], al);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(byte[B-0x7f], al);
+ sub(B, -2);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ align(4);
+
+L(l366c);
+ mov(A1, qword[ARG_BIAS]);
+ movq(qword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x8);
+ sub(N, 0x2);
+ cmp(N, 0x2);
+ jge(l34a8, T_NEAR);
+ align(4);
+
+L(l368a);
+ cmp(N, 0x1);
+ jl(l37d8, T_NEAR);
+ align(4);
+
+L(l3694);
+ mov(A1, A);
+ add(A, LDA);
+ pxor(xmm7, xmm7);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l36ec, T_NEAR);
+ align(4);
+
+L(l36a8);
+ movdqu(xmm0, xword[A1-0x80]);
+ sub(A1, -16);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ dec(I);
+ jg(l36a8, T_NEAR);
+ align(4);
+
+L(l36ec);
+ test(M, 0x8);
+ jle(l3728, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ sub(A1, -8);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l3728);
+ test(M, 0x4);
+ jle(l3760, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ sub(A1, -4);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l3760);
+ test(M, 0x2);
+ jle(l3794, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ mov(word[B-0x80], ax);
+ sub(A1, -2);
+ sub(B, -2);
+ align(4);
+
+L(l3794);
+ test(M, 0x1);
+ jle(l37b8, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ mov(byte[B-0x80], al);
+ sub(B, -1);
+ align(4);
+
+L(l37b8);
+ mov(A1, qword[ARG_BIAS]);
+ movd(dword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x4);
+ sub(N, 0x1);
+ cmp(N, 0x1);
+ jge(l3694, T_NEAR);
+ align(4);
+
+L(l37d8);
+
+ postamble();
+}
+outLocalLabel();
+
+#undef M
+#undef N
+#undef A
+#undef LDA
+#undef ALPHA
+#undef B
+#undef I
+#undef A1
+#undef A2
+#undef LDA3
+#ifdef _WIN32
+#undef ARG_ALPHA
+#undef ARG_B
+#endif
+#undef ARG_BIAS
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_bn_kern.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_bn_kern.cpp
new file mode 100644
index 0000000000..c7f1393c9d
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_bn_kern.cpp
@@ -0,0 +1,821 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "jit_generator.hpp"
+#include "common.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+jit_avx512_core_u8_copy_sum_bn_kern::jit_avx512_core_u8_copy_sum_bn_kern(): jit_generator(nullptr, GEMM_CODE_SIZE)
+{
+
+#ifndef _WIN32
+#define M rdi
+#define N rsi
+#define A rdx
+#define LDA rcx
+#define ALPHA r8
+#define B r9
+
+#define I rax
+#define A1 r10
+#define A2 r8
+#define LDA3 r11
+
+#define ARG_BIAS 24+stacksize+rsp
+
+#else
+
+#define M rcx
+#define N rdx
+#define A r8
+#define LDA r9
+#define ALPHA rax
+#define B rdi
+
+#define I rax
+#define A1 rsi
+#define A2 r10
+#define LDA3 r11
+
+#define ARG_ALPHA 40+stacksize+rsp
+#define ARG_B 48+stacksize+rsp
+#define ARG_BIAS 72+stacksize+rsp
+
+#endif
+
+inLocalLabel();
+{
+
+Xbyak::Label l20;
+Xbyak::Label l22c;
+Xbyak::Label l340;
+Xbyak::Label l3f8;
+Xbyak::Label l48;
+Xbyak::Label l498;
+Xbyak::Label l51c;
+Xbyak::Label l540;
+Xbyak::Label l54c;
+Xbyak::Label l56c;
+Xbyak::Label l664;
+Xbyak::Label l6f8;
+Xbyak::Label l75c;
+Xbyak::Label l7b4;
+Xbyak::Label l7fc;
+Xbyak::Label l81c;
+Xbyak::Label l828;
+Xbyak::Label l848;
+Xbyak::Label l8d8;
+Xbyak::Label l930;
+Xbyak::Label l974;
+Xbyak::Label l9b8;
+Xbyak::Label l9ec;
+Xbyak::Label la0a;
+Xbyak::Label la14;
+Xbyak::Label la28;
+Xbyak::Label la6c;
+Xbyak::Label laa8;
+Xbyak::Label lae0;
+Xbyak::Label lb14;
+Xbyak::Label lb38;
+Xbyak::Label lb58;
+
+ preamble();
+ auto stacksize = get_size_of_abi_save_regs();
+#ifdef _WIN32
+ mov(ALPHA, ptr[ARG_ALPHA]);
+ mov(B, ptr[ARG_B]);
+#endif
+
+ mov(N, qword[N]);
+ mov(M, qword[M]);
+ mov(LDA, qword[LDA]);
+ sub(A, -128);
+ sub(B, -128);
+ lea(LDA3, ptr[LDA+LDA*2]);
+ cmp(N, 0x8);
+ jl(l540, T_NEAR);
+ align(4);
+
+L(l20);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*4]);
+ lea(I, ptr[A1+LDA*8]);
+ mov(A, I);
+ pxor(xmm8, xmm8);
+ pxor(xmm9, xmm9);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l22c, T_NEAR);
+ align(4);
+
+L(l48);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ movdqu(xmm2, xword[A1+LDA*2-0x80]);
+ movdqu(xmm3, xword[A1+LDA3*1-0x80]);
+ sub(A1, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x60], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x40], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x20], xmm3);
+ movdqu(xmm0, xword[A2-0x80]);
+ movdqu(xmm1, xword[A2+LDA*1-0x80]);
+ movdqu(xmm2, xword[A2+LDA*2-0x80]);
+ movdqu(xmm3, xword[A2+LDA3*1-0x80]);
+ sub(A2, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x50], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x30], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x10], xmm3);
+ sub(B, -128);
+ dec(I);
+ jg(l48, T_NEAR);
+ align(4);
+
+L(l22c);
+ test(M, 0x8);
+ jle(l340, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ movq(xmm2, qword[A1+LDA*2-0x80]);
+ movq(xmm3, qword[A1+LDA3*1-0x80]);
+ sub(A1, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x60], xmm1);
+ movq(xmm0, qword[A2-0x80]);
+ movq(xmm1, qword[A2+LDA*1-0x80]);
+ movq(xmm2, qword[A2+LDA*2-0x80]);
+ movq(xmm3, qword[A2+LDA3*1-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x50], xmm1);
+ sub(B, -64);
+ align(4);
+
+L(l340);
+ test(M, 0x4);
+ jle(l3f8, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ movd(xmm2, dword[A1+LDA*2-0x80]);
+ movd(xmm3, dword[A1+LDA3*1-0x80]);
+ sub(A1, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A2-0x80]);
+ movd(xmm1, dword[A2+LDA*1-0x80]);
+ movd(xmm2, dword[A2+LDA*2-0x80]);
+ movd(xmm3, dword[A2+LDA3*1-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ sub(B, -32);
+ align(4);
+
+L(l3f8);
+ test(M, 0x2);
+ jle(l498, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A1+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A1+LDA3*1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x3);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x4);
+ mov(ax, word[A2+LDA*1-0x80]);
+ pinsrw(xmm0, eax, 0x5);
+ mov(ax, word[A2+LDA*2-0x80]);
+ pinsrw(xmm0, eax, 0x6);
+ mov(ax, word[A2+LDA3*1-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x7);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l498);
+ test(M, 0x1);
+ jle(l51c, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1+LDA3*1-0x80]);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A2+LDA*2-0x80]);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A2+LDA3*1-0x80]);
+ pinsrb(xmm0, eax, 0x7);
+ pmovsxbd(xmm5, xmm0);
+ pshufd(xmm6, xmm0, 0x55);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm8, xmm5);
+ paddd(xmm9, xmm6);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l51c);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm8);
+ movdqu(xword[A1+0x10], xmm9);
+ add(qword[ARG_BIAS], 0x20);
+ sub(N, 0x8);
+ cmp(N, 0x8);
+ jge(l20, T_NEAR);
+ align(4);
+
+L(l540);
+ cmp(N, 0x4);
+ jl(l81c, T_NEAR);
+ align(4);
+
+L(l54c);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*2]);
+ lea(I, ptr[A1+LDA*4]);
+ mov(A, I);
+ pxor(xmm7, xmm7);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l664, T_NEAR);
+ align(4);
+
+L(l56c);
+ movdqu(xmm0, xword[A1-0x80]);
+ movdqu(xmm1, xword[A1+LDA*1-0x80]);
+ sub(A1, -16);
+ movdqu(xmm2, xword[A2-0x80]);
+ movdqu(xmm3, xword[A2+LDA*1-0x80]);
+ sub(A2, -16);
+ movdqa(xmm4, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm4, xmm1);
+ movdqa(xmm5, xmm2);
+ punpckldq(xmm2, xmm3);
+ punpckhdq(xmm5, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ movdqa(xmm3, xmm4);
+ punpcklqdq(xmm4, xmm5);
+ punpckhqdq(xmm3, xmm5);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x70], xmm1);
+ pmovsxbw(xmm5, xmm4);
+ movhlps(xmm6, xmm4);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x60], xmm4);
+ pmovsxbw(xmm5, xmm3);
+ movhlps(xmm6, xmm3);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x50], xmm3);
+ sub(B, -64);
+ dec(I);
+ jg(l56c, T_NEAR);
+ align(4);
+
+L(l664);
+ test(M, 0x8);
+ jle(l6f8, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ movq(xmm1, qword[A1+LDA*1-0x80]);
+ sub(A1, -8);
+ movq(xmm2, qword[A2-0x80]);
+ movq(xmm3, qword[A2+LDA*1-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklqdq(xmm0, xmm2);
+ punpckhqdq(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x70], xmm1);
+ sub(B, -32);
+ align(4);
+
+L(l6f8);
+ test(M, 0x4);
+ jle(l75c, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ movd(xmm1, dword[A1+LDA*1-0x80]);
+ sub(A1, -4);
+ movd(xmm2, dword[A2-0x80]);
+ movd(xmm3, dword[A2+LDA*1-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ punpckldq(xmm2, xmm3);
+ punpcklqdq(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l75c);
+ test(M, 0x2);
+ jle(l7b4, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1+LDA*1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x1);
+ mov(ax, word[A2-0x80]);
+ pinsrw(xmm0, eax, 0x2);
+ mov(ax, word[A2+LDA*1-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x3);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l7b4);
+ test(M, 0x1);
+ jle(l7fc, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A2+LDA*1-0x80]);
+ pinsrb(xmm0, eax, 0x3);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l7fc);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x10);
+ sub(N, 0x4);
+ cmp(N, 0x4);
+ jge(l54c, T_NEAR);
+ align(4);
+
+L(l81c);
+ cmp(N, 0x2);
+ jl(la0a, T_NEAR);
+ align(4);
+
+L(l828);
+ mov(A1, A);
+ lea(A2, ptr[A1+LDA*1]);
+ lea(I, ptr[A1+LDA*2]);
+ mov(A, I);
+ pxor(xmm7, xmm7);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(l8d8, T_NEAR);
+ align(4);
+
+L(l848);
+ movdqu(xmm0, xword[A1-0x80]);
+ sub(A1, -16);
+ movdqu(xmm1, xword[A2-0x80]);
+ sub(A2, -16);
+ movdqa(xmm2, xmm0);
+ punpckldq(xmm0, xmm1);
+ punpckhdq(xmm2, xmm1);
+ pshufd(xmm6, xmm0, 0xd8);
+ pmovsxbw(xmm5, xmm6);
+ movhlps(xmm6, xmm6);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ pshufd(xmm6, xmm2, 0xd8);
+ pmovsxbw(xmm5, xmm6);
+ movhlps(xmm6, xmm6);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x70], xmm2);
+ sub(B, -32);
+ dec(I);
+ jg(l848, T_NEAR);
+ align(4);
+
+L(l8d8);
+ test(M, 0x8);
+ jle(l930, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ sub(A1, -8);
+ movq(xmm1, qword[A2-0x80]);
+ sub(A2, -8);
+ punpckldq(xmm0, xmm1);
+ pshufd(xmm6, xmm0, 0xd8);
+ pmovsxbw(xmm5, xmm6);
+ movhlps(xmm6, xmm6);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l930);
+ test(M, 0x4);
+ jle(l974, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ sub(A1, -4);
+ movd(xmm1, dword[A2-0x80]);
+ sub(A2, -4);
+ punpckldq(xmm0, xmm1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l974);
+ test(M, 0x2);
+ jle(l9b8, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ sub(A1, -2);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A2-0x80]);
+ sub(A2, -2);
+ pinsrw(xmm0, eax, 0x1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l9b8);
+ test(M, 0x1);
+ jle(l9ec, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ mov(byte[B-0x80], al);
+ mov(al, byte[A2-0x80]);
+ pinsrb(xmm0, eax, 0x1);
+ mov(byte[B-0x7f], al);
+ sub(B, -2);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ align(4);
+
+L(l9ec);
+ mov(A1, qword[ARG_BIAS]);
+ movq(qword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x8);
+ sub(N, 0x2);
+ cmp(N, 0x2);
+ jge(l828, T_NEAR);
+ align(4);
+
+L(la0a);
+ cmp(N, 0x1);
+ jl(lb58, T_NEAR);
+ align(4);
+
+L(la14);
+ mov(A1, A);
+ add(A, LDA);
+ pxor(xmm7, xmm7);
+ mov(I, M);
+ sar(I, 0x4);
+ jle(la6c, T_NEAR);
+ align(4);
+
+L(la28);
+ movdqu(xmm0, xword[A1-0x80]);
+ sub(A1, -16);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ dec(I);
+ jg(la28, T_NEAR);
+ align(4);
+
+L(la6c);
+ test(M, 0x8);
+ jle(laa8, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ sub(A1, -8);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(laa8);
+ test(M, 0x4);
+ jle(lae0, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ sub(A1, -4);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(lae0);
+ test(M, 0x2);
+ jle(lb14, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ mov(word[B-0x80], ax);
+ sub(A1, -2);
+ sub(B, -2);
+ align(4);
+
+L(lb14);
+ test(M, 0x1);
+ jle(lb38, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrb(xmm0, eax, 0x0);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ mov(byte[B-0x80], al);
+ sub(B, -1);
+ align(4);
+
+L(lb38);
+ mov(A1, qword[ARG_BIAS]);
+ movd(dword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x4);
+ sub(N, 0x1);
+ cmp(N, 0x1);
+ jge(la14, T_NEAR);
+ align(4);
+
+L(lb58);
+
+ postamble();
+}
+outLocalLabel();
+
+#undef M
+#undef N
+#undef A
+#undef LDA
+#undef ALPHA
+#undef B
+#undef I
+#undef A1
+#undef A2
+#undef LDA3
+#ifdef _WIN32
+#undef ARG_ALPHA
+#undef ARG_B
+#endif
+#undef ARG_BIAS
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_bt_kern.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_bt_kern.cpp
new file mode 100644
index 0000000000..afe4f1713e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/jit_avx512_core_u8_copy_sum_bt_kern.cpp
@@ -0,0 +1,647 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "jit_generator.hpp"
+#include "common.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+jit_avx512_core_u8_copy_sum_bt_kern::jit_avx512_core_u8_copy_sum_bt_kern(): jit_generator(nullptr, GEMM_CODE_SIZE)
+{
+
+#ifndef _WIN32
+#define M rdi
+#define N rsi
+#define A rdx
+#define LDA rcx
+#define ALPHA r8
+#define B r9
+
+#define I rax
+#define A1 r10
+#define A2 r8
+#define LDA3 r11
+
+#define ARG_BIAS 24+stacksize+rsp
+
+#else
+
+#define M rcx
+#define N rdx
+#define A r8
+#define LDA r9
+#define ALPHA rax
+#define B rdi
+
+#define I rax
+#define A1 rsi
+#define A2 r10
+#define LDA3 r11
+
+#define ARG_ALPHA 40+stacksize+rsp
+#define ARG_B 48+stacksize+rsp
+#define ARG_BIAS 72+stacksize+rsp
+
+#endif
+
+inLocalLabel();
+{
+
+Xbyak::Label l15c;
+Xbyak::Label l1f4;
+Xbyak::Label l20;
+Xbyak::Label l248;
+Xbyak::Label l280;
+Xbyak::Label l2a4;
+Xbyak::Label l2b0;
+Xbyak::Label l2c8;
+Xbyak::Label l384;
+Xbyak::Label l3e8;
+Xbyak::Label l40;
+Xbyak::Label l424;
+Xbyak::Label l448;
+Xbyak::Label l468;
+Xbyak::Label l474;
+Xbyak::Label l48c;
+Xbyak::Label l550;
+Xbyak::Label l5bc;
+Xbyak::Label l600;
+Xbyak::Label l628;
+Xbyak::Label l646;
+Xbyak::Label l650;
+Xbyak::Label l668;
+Xbyak::Label l700;
+Xbyak::Label l760;
+Xbyak::Label l7a4;
+Xbyak::Label l7c8;
+Xbyak::Label l7e8;
+
+ preamble();
+ auto stacksize = get_size_of_abi_save_regs();
+#ifdef _WIN32
+ mov(ALPHA, ptr[ARG_ALPHA]);
+ mov(B, ptr[ARG_B]);
+#endif
+
+ mov(M, qword[M]);
+ mov(N, qword[N]);
+ mov(LDA, qword[LDA]);
+ lea(LDA3, ptr[LDA+LDA*2]);
+ sub(A, -128);
+ sub(B, -128);
+ cmp(N, 0x8);
+ jl(l2a4, T_NEAR);
+ align(4);
+
+L(l20);
+ mov(A1, A);
+ add(A, 0x8);
+ pxor(xmm8, xmm8);
+ pxor(xmm9, xmm9);
+ mov(I, M);
+ sar(I, 0x3);
+ jle(l15c, T_NEAR);
+ align(4);
+
+L(l40);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x60], xmm0);
+ movdqu(xword[B-0x50], xmm1);
+ sub(B, -64);
+ dec(I);
+ jg(l40, T_NEAR);
+ align(4);
+
+L(l15c);
+ test(M, 0x4);
+ jle(l1f4, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm2, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm3, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ movdqa(xmm1, xmm0);
+ punpcklwd(xmm0, xmm2);
+ punpckhwd(xmm1, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ pmovsxbw(xmm5, xmm1);
+ movhlps(xmm6, xmm1);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm9, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movdqu(xword[B-0x70], xmm1);
+ sub(B, -32);
+ align(4);
+
+L(l1f4);
+ test(M, 0x2);
+ jle(l248, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ movq(xmm1, qword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm8, xmm5);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm6, xmm6);
+ pmovsxwd(xmm6, xmm6);
+ paddd(xmm9, xmm6);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l248);
+ test(M, 0x1);
+ jle(l280, T_NEAR);
+ movq(xmm0, qword[A1-0x80]);
+ add(A1, LDA);
+ pmovsxbd(xmm5, xmm0);
+ pshufd(xmm6, xmm0, 0x55);
+ pmovsxbd(xmm6, xmm6);
+ paddd(xmm8, xmm5);
+ paddd(xmm9, xmm6);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l280);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm8);
+ movdqu(xword[A1+0x10], xmm9);
+ add(qword[ARG_BIAS], 0x20);
+ sub(N, 0x8);
+ cmp(N, 0x8);
+ jge(l20, T_NEAR);
+ align(4);
+
+L(l2a4);
+ cmp(N, 0x4);
+ jl(l468, T_NEAR);
+ align(4);
+
+L(l2b0);
+ mov(A1, A);
+ add(A, 0x4);
+ pxor(xmm7, xmm7);
+ mov(I, M);
+ sar(I, 0x3);
+ jle(l384, T_NEAR);
+ align(4);
+
+L(l2c8);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x70], xmm0);
+ sub(B, -32);
+ dec(I);
+ jg(l2c8, T_NEAR);
+ align(4);
+
+L(l384);
+ test(M, 0x4);
+ jle(l3e8, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm2, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm3, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ movhlps(xmm6, xmm0);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ align(4);
+
+L(l3e8);
+ test(M, 0x2);
+ jle(l424, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ add(A1, LDA);
+ movd(xmm1, dword[A1-0x80]);
+ add(A1, LDA);
+ punpcklbw(xmm0, xmm1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l424);
+ test(M, 0x1);
+ jle(l448, T_NEAR);
+ movd(xmm0, dword[A1-0x80]);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l448);
+ mov(A1, qword[ARG_BIAS]);
+ movdqu(xword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x10);
+ sub(N, 0x4);
+ cmp(N, 0x4);
+ jge(l2b0, T_NEAR);
+ align(4);
+
+L(l468);
+ cmp(N, 0x2);
+ jl(l646, T_NEAR);
+ align(4);
+
+L(l474);
+ mov(A1, A);
+ add(A, 0x2);
+ pxor(xmm7, xmm7);
+ mov(LDA3, M);
+ sar(LDA3, 0x3);
+ jle(l550, T_NEAR);
+ align(4);
+
+L(l48c);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm4, eax, 0x0);
+ punpcklbw(xmm1, xmm2);
+ punpcklbw(xmm3, xmm4);
+ punpcklwd(xmm1, xmm3);
+ punpcklqdq(xmm0, xmm1);
+ pshufd(xmm6, xmm0, 0xd8);
+ pmovsxbw(xmm5, xmm6);
+ movhlps(xmm6, xmm6);
+ pmovsxbw(xmm6, xmm6);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movdqu(xword[B-0x80], xmm0);
+ sub(B, -16);
+ dec(LDA3);
+ jg(l48c, T_NEAR);
+ align(4);
+
+L(l550);
+ test(M, 0x4);
+ jle(l5bc, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm2, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm3, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ punpcklbw(xmm2, xmm3);
+ punpcklwd(xmm0, xmm2);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ align(4);
+
+L(l5bc);
+ test(M, 0x2);
+ jle(l600, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm0, eax, 0x0);
+ mov(ax, word[A1-0x80]);
+ add(A1, LDA);
+ pinsrw(xmm1, eax, 0x0);
+ punpcklbw(xmm0, xmm1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l600);
+ test(M, 0x1);
+ jle(l628, T_NEAR);
+ mov(ax, word[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ mov(word[B-0x80], ax);
+ sub(B, -2);
+ align(4);
+
+L(l628);
+ mov(A1, qword[ARG_BIAS]);
+ movq(qword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x8);
+ sub(N, 0x2);
+ cmp(N, 0x2);
+ jge(l474, T_NEAR);
+ align(4);
+
+L(l646);
+ cmp(N, 0x1);
+ jl(l7e8, T_NEAR);
+ align(4);
+
+L(l650);
+ mov(A1, A);
+ add(A, 0x1);
+ pxor(xmm7, xmm7);
+ mov(LDA3, M);
+ sar(LDA3, 0x3);
+ jle(l700, T_NEAR);
+ align(4);
+
+L(l668);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x3);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x4);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x5);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x6);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x7);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm6);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movq(qword[B-0x80], xmm0);
+ sub(B, -8);
+ dec(LDA3);
+ jg(l668, T_NEAR);
+ align(4);
+
+L(l700);
+ test(M, 0x4);
+ jle(l760, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x0);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x1);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x2);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x3);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ movd(dword[B-0x80], xmm0);
+ sub(B, -4);
+ align(4);
+
+L(l760);
+ test(M, 0x2);
+ jle(l7a4, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x0);
+ mov(byte[B-0x80], al);
+ mov(al, byte[A1-0x80]);
+ add(A1, LDA);
+ pinsrb(xmm0, eax, 0x1);
+ pmovsxbw(xmm5, xmm0);
+ phaddw(xmm5, xmm5);
+ pmovsxwd(xmm5, xmm5);
+ paddd(xmm7, xmm5);
+ mov(byte[B-0x7f], al);
+ sub(B, -2);
+ align(4);
+
+L(l7a4);
+ test(M, 0x1);
+ jle(l7c8, T_NEAR);
+ mov(al, byte[A1-0x80]);
+ pinsrw(xmm0, eax, 0x0);
+ pmovsxbd(xmm5, xmm0);
+ paddd(xmm7, xmm5);
+ mov(byte[B-0x80], al);
+ sub(B, -1);
+ align(4);
+
+L(l7c8);
+ mov(A1, qword[ARG_BIAS]);
+ movd(dword[A1], xmm7);
+ add(qword[ARG_BIAS], 0x4);
+ sub(N, 0x1);
+ cmp(N, 0x1);
+ jge(l650, T_NEAR);
+ align(4);
+
+L(l7e8);
+
+ postamble();
+}
+outLocalLabel();
+
+#undef M
+#undef N
+#undef A
+#undef LDA
+#undef ALPHA
+#undef B
+#undef I
+#undef A1
+#undef A2
+#undef LDA3
+#ifdef _WIN32
+#undef ARG_ALPHA
+#undef ARG_B
+#endif
+#undef ARG_BIAS
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/ref_gemm_s8x8s32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/ref_gemm_s8x8s32.cpp
new file mode 100644
index 0000000000..4fc11afcbc
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/ref_gemm_s8x8s32.cpp
@@ -0,0 +1,116 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <cstdint>
+
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "../f32/ref_gemm_f32.hpp"
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <typename b_dt>
+mkldnn_status_t ref_gemm_s8x8s32(const char *transa, const char *transb,
+ const char *offsetc, const int *M, const int *N, const int *K,
+ const float *alpha, const int8_t *A, const int *LDA, const int8_t *ao,
+ const b_dt *B, const int *LDB, const int8_t *bo, const float *beta,
+ int32_t *C, const int *LDC, const int32_t *co) {
+
+ if (*M == 0 || *N == 0 || *K == 0)
+ return mkldnn_success;
+
+ bool OCisR = (*offsetc == 'R' || *offsetc == 'r');
+ bool OCisC = (*offsetc == 'C' || *offsetc == 'c');
+ bool AisN = (*transa == 'N' || *transa == 'n');
+ bool BisN = (*transb == 'N' || *transb == 'n');
+
+ int m = *M, n = *N, k = *K, lda = *LDA, ldb = *LDB, ldc = *LDC;
+ size_t sizeA = AisN ? lda * k : lda * m;
+ size_t sizeB = BisN ? ldb * n : ldb * k;
+ size_t sizeC = ldc * n;
+
+ double *dA = (double *)malloc(sizeA * sizeof(double), PAGE_4K);
+ double *dB = (double *)malloc(sizeB * sizeof(double), PAGE_4K);
+ double *dC = (double *)malloc(sizeC * sizeof(double), PAGE_4K);
+
+ if (utils::any_null(dA, dB, dC)) {
+ free(dA);
+ free(dB);
+ free(dC);
+ return mkldnn_out_of_memory;
+ }
+
+ auto da_setter = [=] (int i, int j, double v) { dA[j * lda + i] = v; };
+ auto db_setter = [=] (int i, int j, double v) { dB[j * ldb + i] = v; };
+
+ auto ia_accessor = [=] (int i, int j) { return A[j * lda + i]; };
+ auto ib_accessor = [=] (int i, int j) { return B[j * ldb + i]; };
+
+ const int a_rows = AisN ? m : k;
+ const int a_cols = AisN ? k : m;
+ mkldnn::impl::parallel_nd(a_cols, a_rows, [&](int j, int i) {
+ da_setter(i, j,
+ static_cast<double>(ia_accessor(i, j)) + static_cast<double>(ao[0]));
+ });
+
+ const int b_rows = BisN ? k : n;
+ const int b_cols = BisN ? n : k;
+ mkldnn::impl::parallel_nd(b_cols, b_rows, [&](int j, int i) {
+ db_setter(i, j,
+ static_cast<double>(ib_accessor(i, j)) + static_cast<double>(bo[0]));
+ });
+ double one = 1.0, zero = 0.0;
+ ref_gemm<double>(transa, transb, M, N, K, &one, dA, LDA, dB, LDB, &zero,
+ dC, LDC, nullptr);
+
+ auto i2d = [=] (int32_t v) { return static_cast<double>(v); };
+ auto f2d = [=] (float v) { return static_cast<double>(v); };
+
+ mkldnn::impl::parallel_nd(n, m, [&] (int j, int i) {
+ double coffset = OCisR ? i2d(co[j]) : OCisC ? i2d(co[i]) : i2d(co[0]);
+ double val = ((*beta == 0.0f) ? 0.0 : f2d(*beta) * i2d(C[i + j * ldc]))
+ + f2d(*alpha) * dC[i + j * ldc] + coffset;
+ C[i + j * ldc] = math::out_round<int32_t>(math::saturate<int32_t>(val));
+ });
+
+ free(dA);
+ free(dB);
+ free(dC);
+ return mkldnn_success;
+}
+
+template mkldnn_status_t ref_gemm_s8x8s32<uint8_t>(
+ const char *transa, const char *transb, const char *offsetc,
+ const int *M, const int *N, const int *K,
+ const float *alpha, const int8_t *A, const int *LDA, const int8_t *ao,
+ const uint8_t *B, const int *LDB, const int8_t *bo,
+ const float *beta, int32_t *C, const int *LDC, const int32_t *co);
+
+template mkldnn_status_t ref_gemm_s8x8s32<int8_t>(
+ const char *transa, const char *transb, const char *offsetc,
+ const int *M, const int *N, const int *K,
+ const float *alpha, const int8_t *A, const int *LDA, const int8_t *ao,
+ const int8_t *B, const int *LDB, const int8_t *bo,
+ const float *beta, int32_t *C, const int *LDC, const int32_t *co);
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/ref_gemm_s8x8s32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/ref_gemm_s8x8s32.hpp
new file mode 100644
index 0000000000..6c0370ae99
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/ref_gemm_s8x8s32.hpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef REF_GEMM_S8X8S32_HPP
+#define REF_GEMM_S8X8S32_HPP
+
+#include <stdint.h>
+
+#include "mkldnn_types.h"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <typename b_dt>
+mkldnn_status_t ref_gemm_s8x8s32(const char *transa, const char *transb,
+ const char *offsetc, const int *M, const int *N, const int *K,
+ const float *alpha, const int8_t *A, const int *LDA, const int8_t *ao,
+ const b_dt *B, const int *LDB, const int8_t *bo, const float *beta,
+ int32_t *C, const int *LDC, const int32_t *co);
+
+}
+}
+}
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/simple_gemm_s8s8s32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/simple_gemm_s8s8s32.cpp
new file mode 100644
index 0000000000..de1035f3b2
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/simple_gemm_s8s8s32.cpp
@@ -0,0 +1,180 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "common.hpp"
+#include "nstl.hpp"
+#include "math_utils.hpp"
+
+#include "../gemm.hpp"
+#include "jit_avx512_core_gemm_s8u8s32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+void compensation_init(const char *offsetC, int32_t *compensation, int len,
+ const int32_t *oc) {
+ bool OCisC = (*offsetC == 'C' || *offsetC == 'c');
+ bool OCisF = (*offsetC == 'F' || *offsetC == 'f');
+
+ if (OCisF && (*oc) != 0) {
+ for (int i = 0; i < len; i++)
+ compensation[i] = *oc;
+ } else if (OCisC) {
+ for (int i = 0; i < len; i++)
+ compensation[i] = oc[i];
+ } else {
+ parallel_nd(len, [=](int i) { compensation[i] = 0; });
+ }
+}
+
+void compensation_compute(bool transa, int m, int k, float alpha,
+ const int8_t *a, int lda, int32_t *compensation) {
+ if (!transa) {
+ const int L2_cache_size = get_cache_size(2, true);
+ const int blocking_factor = nstl::min(k, L2_cache_size / lda + 1);
+ const int npanels = k / blocking_factor;
+ const bool has_tile = k % blocking_factor > 0;
+
+ parallel_nd(npanels, m, [&](int j, int i) {
+ int32_t val = 0;
+ for (int jb = 0; jb < blocking_factor; jb++) {
+ val += a[(i + (ptrdiff_t)j * blocking_factor * lda)
+ + (ptrdiff_t)jb * lda];
+ }
+ if (alpha != 1.0f) {
+ val = math::out_round<int32_t>(math::saturate<int32_t>(
+ (double)val * alpha * -128.0));
+ } else {
+ val *= -128;
+ }
+ fetch_and_add(&compensation[i], val);
+ });
+
+ if (has_tile) {
+ parallel_nd(m, [=](int i) {
+ int32_t val = 0;
+ for (int j = npanels * blocking_factor; j < k; j++) {
+ val += a[i + (ptrdiff_t)j * lda];
+ }
+ if (alpha != 1.0f) {
+ val = math::out_round<int32_t>(math::saturate<int32_t>(
+ (double)val * alpha * -128.0));
+ } else {
+ val *= -128;
+ }
+ fetch_and_add(&compensation[i], val);
+ });
+ }
+ } else {
+ parallel_nd(m, [=](int i) {
+ int32_t val = 0;
+ for (int j = 0; j < k; j++) {
+ val += a[j + (ptrdiff_t)i * lda];
+ }
+ if (alpha != 1.0f) {
+ val = math::out_round<int32_t>(math::saturate<int32_t>(
+ (double)val * alpha * -128.0));
+ } else {
+ val *= -128;
+ }
+ compensation[i] += val;
+ });
+ }
+}
+
+void copy_and_shift_b(bool transb, int k, int n, uint8_t *b_u8, int ldb_u8,
+ const int8_t *b_s8, int ldb_s8) {
+ const int b_cols = transb ? k : n;
+
+ parallel_nd(b_cols, [=](int j) {
+ const int b_rows = transb ? n : k;
+
+ uint8_t *pb_u8 = b_u8 + j * ldb_u8;
+ const int8_t *pb_s8 = b_s8 + j * ldb_s8;
+
+ for (int i = 0; i < b_rows; i++) {
+ (*pb_u8) = (*pb_s8) + 128;
+ pb_u8++;
+ pb_s8++;
+ }
+ });
+}
+
+/**
+ * gemm_s8s8s32 operation is defined as follows:
+ * C = alpha * op(A) * (op(B) + B_shift) + beta * C + C_offset + compensation
+ *
+ * where
+ * - compensation is a vector of length m that contains computed compensation
+ * that may contain C_offset if applicable. The compensation is applied inside
+ * gemm_s8u8s32 as a C_offset
+ * - B_shift is a k-by-n matrix, every element of B_shift is equal to 128
+ *
+ * What is the compensation:
+ * In order to prepare the matrix B for gemm_s8u8s32 call the B_shift is applied:
+ * C = alpha * op(A) * (op(B) + B_shift) + beta * C + C_offset =
+ * alpha * op(A) * op(B) + alpha * op(A) * B_shift + beta * C + C_offset
+ * compensation = -alpha * op(A) * B_shift
+ * Since B_shift is a matrix, every element of which is equal to 128 then
+ * - if op(A) = A: compensation contains sum of the elements in each row
+ * scaled by -128 * alpha
+ * - if op(A) = A**T: compensation contains sum of the elements in each column
+ * scaled by -128 * alpha
+ *
+ * The rest of parameters is described in mkldnn.h
+ */
+mkldnn_status_t simple_gemm_s8s8s32(
+ const char *transA, const char *transB, const char *offsetC,
+ const int *m, const int *n, const int *k,
+ const float *alpha, const int8_t *a, const int *lda, const int8_t *oa,
+ const int8_t *b, const int *ldb, const int8_t *ob,
+ const float *beta, int32_t *c, const int *ldc, const int32_t *oc) {
+ if (*oa != 0 || *ob != 0) return mkldnn_unimplemented;
+
+ int M = *m, N = *n, K = *k;
+ bool transa = (*transA == 'T' || *transA == 't');
+ bool transb = (*transB == 'T' || *transB == 't');
+ int ld = transb ? N : K;
+
+ uint8_t *b_u8 = (uint8_t *)malloc(sizeof(uint8_t) * K * N, 64);
+ int32_t *compensation = (int32_t *)malloc(sizeof(int32_t) * M, 64);
+
+ if (utils::any_null(b_u8, compensation)) {
+ free(b_u8);
+ free(compensation);
+ return mkldnn_out_of_memory;
+ }
+
+ compensation_init(offsetC, compensation, M, oc);
+ compensation_compute(transa, M, K, *alpha, a, *lda, compensation);
+ copy_and_shift_b(transb, K, N, b_u8, ld, b, *ldb);
+
+ gemm_s8x8s32(transA, transB, "C", m, n, k, alpha, a, lda, oa, b_u8,
+ &ld, ob, beta, c, ldc, compensation);
+
+ if ((*offsetC == 'R' || *offsetC == 'r'))
+ parallel_nd(M, N,
+ [=](int i, int j) { c[i + (ptrdiff_t)j * *ldc] += oc[j]; });
+
+ free(b_u8);
+ free(compensation);
+
+ return mkldnn_success;
+}
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/simple_gemm_s8s8s32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/simple_gemm_s8s8s32.hpp
new file mode 100644
index 0000000000..03a3d2f7e0
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm/s8x8s32/simple_gemm_s8s8s32.hpp
@@ -0,0 +1,37 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef SIMPLE_GEMM_S8S8S32_HPP
+#define SIMPLE_GEMM_S8S8S32_HPP
+
+#include <stdint.h>
+#include "mkldnn_types.h"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+mkldnn_status_t simple_gemm_s8s8s32(
+ const char *transA, const char *transB, const char *offsetC,
+ const int *m, const int *n, const int *k,
+ const float *alpha, const int8_t *a, const int *lda, const int8_t *oa,
+ const int8_t *b, const int *ldb, const int8_t *ob,
+ const float *beta, int32_t *c, const int *ldc, const int32_t *oc);
+}
+}
+}
+
+#endif // SIMPLE_GEMM_S8S8S32_HPP
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution.cpp
new file mode 100644
index 0000000000..604a728b47
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution.cpp
@@ -0,0 +1,307 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn_types.h"
+
+#include "c_types_map.hpp"
+#include "gemm_convolution.hpp"
+#include "utils.hpp"
+#include "type_helpers.hpp"
+#include "mkldnn_thread.hpp"
+#include "ref_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+
+void gemm_convolution_fwd_t::execute_forward(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ auto col = scratchpad(ctx).get<data_t>(key_conv_gemm_col);
+
+ const jit_gemm_conv_conf_t &jcp = this->pd()->jcp_;
+
+ const int M = jcp.os * jcp.od;
+ const size_t src_step = jcp.ic * jcp.ih * jcp.iw * jcp.id;
+ const size_t dst_step = jcp.oc * M;
+ const size_t weights_g_size = jcp.ic * jcp.oc * jcp.ks;
+
+ assert(IMPLICATION(
+ jcp.id != 1, jcp.oh_block == jcp.oh && jcp.ow_block == jcp.ow));
+ assert(IMPLICATION(jcp.ow_block != jcp.ow, jcp.oh_block == 1));
+
+ const int K = jcp.ic * jcp.ks;
+ const int N = jcp.oc;
+
+ if (jcp.im2col_sz && jcp.id != 1)
+ parallel_nd(jcp.im2col_sz * jcp.nthr,
+ [&](ptrdiff_t i) { col[i] = (data_t)0; });
+
+ const int nb_oh = div_up(jcp.oh, jcp.oh_block);
+ const int nb_ow = div_up(jcp.ow, jcp.ow_block);
+ const size_t work_amount = jcp.ngroups * jcp.mb * jcp.od * nb_oh * nb_ow;
+ parallel(jcp.nthr, [&](const int ithr, const int nthr) {
+ data_t *_col = col + (ptrdiff_t)ithr * jcp.im2col_sz;
+
+ int g{ 0 }, n{ 0 }, od{ 0 }, ohb{ 0 }, owb{ 0 };
+ size_t start = 0, end = 0;
+
+ balance211(work_amount, nthr, ithr, start, end);
+ nd_iterator_init(start, g, jcp.ngroups, n, jcp.mb, od, jcp.od, ohb,
+ nb_oh, owb, nb_ow);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ int oh = ohb * jcp.oh_block;
+ int ow = owb * jcp.ow_block;
+ const data_t *_src = src + (n * jcp.ngroups + g) * src_step;
+ const data_t *_weights = weights + g * weights_g_size;
+ data_t *_dst_im = dst + (n * jcp.ngroups + g) * dst_step;
+ const int h_step = nstl::min(jcp.oh_block, jcp.oh - oh);
+ const int w_step = nstl::min(jcp.ow_block, jcp.ow - ow);
+ if (jcp.im2col_sz) {
+ if (jcp.id == 1)
+ jit_gemm_convolution_utils::im2col(
+ jcp, _src, _col, oh, h_step, ow, w_step);
+ else
+ jit_gemm_convolution_utils::im2col_3d(jcp, _src, _col, od);
+ }
+
+ const data_t one = 1.0;
+
+ const int m = h_step * w_step;
+ const int LDA = jcp.im2col_sz ? m : M;
+ data_t *_dst = _dst_im + od * jcp.os + oh * jcp.ow + ow;
+
+ extended_sgemm("N", "N", &m, &N, &K, &one,
+ jcp.im2col_sz ? _col : _src + od * m, &LDA, _weights, &K,
+ &this->beta_, _dst, &M);
+
+ data_t *d = _dst;
+ if (eltwise_) {
+ // fast branch for ReLU case
+ if (eltwise_->alg_ == alg_kind::eltwise_relu) {
+ parallel_nd(jcp.oc, [&](const int oc) {
+ data_t b = jcp.with_bias ? bias[g * jcp.oc + oc] : 0;
+ data_t *d_ = d + oc * M;
+ PRAGMA_OMP_SIMD()
+ for (int oS = 0; oS < m; ++oS) {
+ d_[oS] += b;
+ if (d_[oS] < 0) d_[oS] *= eltwise_->alpha_;
+ }
+ });
+ } else {
+ parallel_nd(jcp.oc, [&](const int oc) {
+ data_t b = jcp.with_bias ? bias[g * jcp.oc + oc] : 0;
+ data_t *d_ = d + oc * M;
+ PRAGMA_OMP_SIMD()
+ for (int oS = 0; oS < m; ++oS) {
+ d_[oS] += b;
+ d_[oS] = eltwise_->compute_scalar(d_[oS]);
+ }
+ });
+ }
+ } else if (jcp.with_bias) {
+ parallel_nd(jcp.oc, [&](const int oc) {
+ data_t b = bias[g * jcp.oc + oc];
+ data_t *d_ = d + oc * M;
+ PRAGMA_OMP_SIMD()
+ for (int oS = 0; oS < m; ++oS) {
+ d_[oS] += b;
+ }
+ });
+ }
+ nd_iterator_step(g, jcp.ngroups, n, jcp.mb, od, jcp.od, ohb, nb_oh,
+ owb, nb_ow);
+ }
+ });
+}
+
+void gemm_convolution_bwd_data_t::execute_backward_data(
+ const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ auto col = scratchpad(ctx).get<data_t>(key_conv_gemm_col);
+
+ const jit_gemm_conv_conf_t &jcp = this->pd()->jcp_;
+
+ const int M = jcp.os * jcp.od;
+ const size_t src_step = jcp.ic * jcp.ih * jcp.iw * jcp.id;
+ const size_t dst_step = jcp.oc * M;
+ const size_t weights_g_size = jcp.ic * jcp.oc * jcp.ks;
+
+ const int m = jcp.os;
+ const int K = jcp.oc;
+ const int N = jcp.ic * jcp.ks;
+ const int LDC = jcp.im2col_sz ? m : M;
+
+ const size_t work_amount = (size_t)jcp.ngroups * jcp.mb;
+
+ if (jcp.id > 1) {
+ const ptrdiff_t diff_src_sz = (ptrdiff_t)(work_amount * src_step);
+ parallel_nd(diff_src_sz, [&](ptrdiff_t i) { diff_src[i] = (data_t)0; });
+ }
+
+ parallel(jcp.nthr, [&](const int ithr, const int nthr) {
+ data_t *_col = col + (ptrdiff_t)ithr * jcp.im2col_sz;
+
+ int g{0}, n{0};
+ size_t start = 0, end = 0;
+ balance211(work_amount, nthr, ithr, start, end);
+ nd_iterator_init(start, g, jcp.ngroups, n, jcp.mb);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+
+ data_t *_diff_src = diff_src + (n * jcp.ngroups + g)*src_step;
+ const data_t *_weights = weights + g * weights_g_size;
+ for (int od = 0; od < jcp.od; ++od) {
+ const data_t *_diff_dst = diff_dst + (n * jcp.ngroups + g)
+ *dst_step + od * m;
+
+ const data_t zero = 0.0, one = 1.0;
+ extended_sgemm("N", "T", &m, &N, &K, &one, _diff_dst, &M,
+ _weights, &N, &zero,
+ jcp.im2col_sz ? _col:_diff_src + od * m, &LDC);
+
+ if (jcp.im2col_sz) {
+ if (jcp.id == 1)
+ jit_gemm_convolution_utils::col2im(jcp, _col,
+ _diff_src);
+ else
+ jit_gemm_convolution_utils::col2im_3d(jcp, _col,
+ _diff_src, od);
+ }
+ }
+ nd_iterator_step(g, jcp.ngroups, n, jcp.mb);
+ }
+ });
+}
+
+void gemm_convolution_bwd_weights_t::execute_backward_weights(
+ const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_weights = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_WEIGHTS);
+ auto diff_bias = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_BIAS);
+
+ auto col = scratchpad(ctx).get<data_t>(key_conv_gemm_col);
+ auto wei_reduction = scratchpad(ctx).get<data_t>(key_conv_wei_reduction);
+
+ const jit_gemm_conv_conf_t &jcp = this->pd()->jcp_;
+
+ const int K = jcp.os * jcp.od;
+ const size_t src_step = jcp.ic * jcp.ih * jcp.iw * jcp.id;
+ const size_t dst_step = jcp.oc * K;
+ const size_t weights_g_size = jcp.ic * jcp.oc * jcp.ks;
+
+ const int k = jcp.os;
+ const int N = jcp.oc;
+ const int M = jcp.ic * jcp.ks;
+ const int LDA = jcp.im2col_sz ? k : K;
+
+ parallel_nd(jcp.im2col_sz * jcp.nthr,
+ [&](ptrdiff_t i) { col[i] = (data_t)0; });
+
+ parallel(jcp.nthr, [&](const int ithr, const int nthr) {
+ int ithr_g, nthr_g, ithr_mb, nthr_mb;
+ size_t g_start{0}, g_end{0}, mb_start{0}, mb_end{0};
+
+ const int mb_for_balance = jcp.need_wei_reduction ? jcp.mb : 1;
+ jit_gemm_convolution_utils::bwd_weights_balance(ithr, nthr, jcp.ngroups,
+ mb_for_balance, ithr_g, nthr_g, ithr_mb, nthr_mb);
+
+ assert(IMPLICATION(!jcp.need_wei_reduction, nthr_mb == 1));
+ const int need_reduction = nthr_mb != 1;
+
+ if (ithr_g != -1 && ithr_mb != -1) {
+ balance211((size_t)jcp.ngroups, nthr_g, ithr_g, g_start, g_end);
+ balance211((size_t)jcp.mb, nthr_mb, ithr_mb, mb_start, mb_end);
+
+ assert(IMPLICATION((g_end - g_start) > 1, need_reduction == 0));
+
+ data_t *_col = col + (ptrdiff_t)ithr * jcp.im2col_sz;
+ data_t *weights_reduce_base = wei_reduction
+ + ithr_g * nthr_mb * weights_g_size;
+ data_t *weights_reduce = weights_reduce_base
+ + ithr_mb * weights_g_size;
+
+ for (size_t g = g_start; g < g_end; ++g) {
+ data_t *_diff_weights = need_reduction
+ ? weights_reduce : (diff_weights + g * weights_g_size);
+ for (size_t mb = mb_start; mb < mb_end; ++mb) {
+ const data_t *_src = src + (mb*jcp.ngroups+g)*src_step;
+ for (int od = 0; od < jcp.od; ++od) {
+ const data_t *_diff_dst = diff_dst
+ + (mb*jcp.ngroups+g)*dst_step + od * k;
+
+ if (jcp.im2col_sz) {
+ if (jcp.id == 1)
+ jit_gemm_convolution_utils::im2col(
+ jcp, _src, _col, 0, jcp.oh, 0, jcp.ow);
+ else
+ jit_gemm_convolution_utils::im2col_3d(jcp, _src,
+ _col, od);
+ }
+
+ const data_t zero = 0.0, one = 1.0;
+ extended_sgemm(
+ "T", "N", &M, &N, &k, &one,
+ jcp.im2col_sz ? _col : _src + od * k,
+ &LDA, _diff_dst, &K,
+ mb == mb_start && od == 0 ? &zero : &one,
+ _diff_weights, &M);
+ }
+ }
+ }
+ if (need_reduction) {
+ mkldnn_thr_barrier();
+ data_t *weights_base = diff_weights + g_start * weights_g_size;
+ jit_gemm_convolution_utils::bwd_weights_reduction_par(
+ ithr_mb, nthr_mb, jcp, weights_reduce_base, weights_base);
+ }
+ } else
+ if (need_reduction) { mkldnn_thr_barrier(); }
+ });
+
+ if (jcp.with_bias) {
+ parallel_nd(jcp.ngroups, jcp.oc, [&](int g, int oc) {
+ data_t db = 0;
+ size_t offset_ = (size_t)g * dst_step + (size_t)oc * K;
+ for (int mb = 0; mb < jcp.mb; ++mb)
+ {
+ size_t offset = offset_ + (size_t)mb * jcp.ngroups * dst_step;
+ for (int od = 0; od < jcp.od; ++od)
+ for (int oh = 0; oh < jcp.oh; ++oh)
+ PRAGMA_OMP_SIMD(reduction(+:db))
+ for (int ow = 0; ow < jcp.ow; ++ow) {
+ db += diff_dst[offset];
+ offset++;
+ }
+ }
+ diff_bias[g*jcp.oc+oc] = db;
+ });
+ }
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution.hpp
new file mode 100644
index 0000000000..302e46369a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution.hpp
@@ -0,0 +1,250 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_GEMM_CONVOLUTION_HPP
+#define CPU_JIT_GEMM_CONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+
+#include "gemm_convolution_utils.hpp"
+#include "gemm/gemm.hpp"
+#include "ref_eltwise.hpp"
+
+#include "cpu_convolution_pd.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct gemm_convolution_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc, const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(GEMM_IMPL_STR, gemm_convolution_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats_common(dat_tag(), wei_tag(), dat_tag())
+ && post_ops_ok()
+ && memory_desc_matches_tag(*src_md(), dat_tag())
+ && memory_desc_matches_tag(*dst_md(), dat_tag())
+ && memory_desc_matches_tag(*weights_md(), wei_tag());
+ if (!ok) return status::unimplemented;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ return jit_gemm_convolution_utils::init_conf(jcp_, scratchpad,
+ *desc(), src_md(), weights_md(0), dst_md(),
+ mkldnn_get_max_threads());
+ }
+
+ jit_gemm_conv_conf_t jcp_;
+
+ protected:
+ format_tag_t dat_tag() const {
+ using namespace format_tag;
+ return utils::pick(ndims() - 3, ncw, nchw, ncdhw);
+ }
+
+ format_tag_t wei_tag() const {
+ using namespace format_tag;
+ return with_groups()
+ ? utils::pick(ndims() - 3, goiw, goihw, goidhw)
+ : utils::pick(ndims() - 3, oiw, oihw, oidhw);
+ }
+
+ bool post_ops_ok() const {
+ auto const &po = attr()->post_ops_;
+ auto is_eltwise = [&](int idx)
+ { return po.entry_[idx].is_eltwise(); };
+ auto is_sum = [&](int idx) { return po.entry_[idx].is_sum(); };
+
+ switch (po.len_) {
+ case 0: return true; // no post_ops
+ case 1: return is_eltwise(0) || is_sum(0); // sum OR eltwise
+ case 2: return is_sum(0) && is_eltwise(1); // sum -> eltwise
+ default: return false;
+ }
+ return false;
+ }
+ };
+
+ gemm_convolution_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd, true)
+ , eltwise_(nullptr)
+ {
+ const auto &post_ops = pd()->attr()->post_ops_;
+ const data_t one = 1.0, zero = 0.0;
+ beta_ = post_ops.find(primitive_kind::sum) >= 0 ? one : zero;
+
+ const int entry_idx = post_ops.find(primitive_kind::eltwise);
+ if (entry_idx != -1) eltwise_ = new ref_eltwise_scalar_fwd_t(
+ post_ops.entry_[entry_idx].eltwise);
+ }
+
+ ~gemm_convolution_fwd_t() { delete eltwise_; }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ data_t beta_;
+
+ ref_eltwise_scalar_fwd_t* eltwise_;
+};
+
+struct gemm_convolution_bwd_data_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_data_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc, const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_data_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(GEMM_IMPL_STR, gemm_convolution_bwd_data_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_data
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::undef, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats_common(dat_tag(), wei_tag(), dat_tag())
+ && memory_desc_matches_tag(*diff_src_md(), dat_tag())
+ && memory_desc_matches_tag(*diff_dst_md(), dat_tag())
+ && memory_desc_matches_tag(*weights_md(), wei_tag());
+ if (!ok) return status::unimplemented;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ return jit_gemm_convolution_utils::init_conf(jcp_, scratchpad,
+ *desc(), diff_src_md(), weights_md(0), diff_dst_md(),
+ mkldnn_get_max_threads());
+ }
+
+ jit_gemm_conv_conf_t jcp_;
+
+ protected:
+ format_tag_t dat_tag() const {
+ using namespace format_tag;
+ return utils::pick(ndims() - 3, ncw, nchw, ncdhw);
+ }
+
+ format_tag_t wei_tag() const {
+ using namespace format_tag;
+ return with_groups()
+ ? utils::pick(ndims() - 3, goiw, goihw, goidhw)
+ : utils::pick(ndims() - 3, oiw, oihw, oidhw);
+ }
+ };
+
+ gemm_convolution_bwd_data_t(const pd_t *apd)
+ : cpu_primitive_t(apd, true) {}
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_data(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_data(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+struct gemm_convolution_bwd_weights_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_weights_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_weights_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(GEMM_IMPL_STR, gemm_convolution_bwd_weights_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_weights
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats_common(dat_tag(), wei_tag(), dat_tag())
+ && memory_desc_matches_tag(*src_md(), dat_tag())
+ && memory_desc_matches_tag(*diff_dst_md(), dat_tag())
+ && memory_desc_matches_tag(*diff_weights_md(), wei_tag());
+ if (!ok) return status::unimplemented;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ return jit_gemm_convolution_utils::init_conf(jcp_, scratchpad,
+ *desc(), src_md(), diff_weights_md(0), diff_dst_md(),
+ mkldnn_get_max_threads());
+ }
+
+ jit_gemm_conv_conf_t jcp_;
+
+ protected:
+ format_tag_t dat_tag() const {
+ using namespace format_tag;
+ return utils::pick(ndims() - 3, ncw, nchw, ncdhw);
+ }
+
+ format_tag_t wei_tag() const {
+ using namespace format_tag;
+ return with_groups()
+ ? utils::pick(ndims() - 3, goiw, goihw, goidhw)
+ : utils::pick(ndims() - 3, oiw, oihw, oidhw);
+ }
+ };
+
+ gemm_convolution_bwd_weights_t(const pd_t *apd)
+ : cpu_primitive_t(apd, true) {}
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_weights(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_weights(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution_utils.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution_utils.cpp
new file mode 100644
index 0000000000..f133b1e62b
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution_utils.cpp
@@ -0,0 +1,771 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn_types.h"
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+#include "cpu_isa_traits.hpp"
+
+#include "gemm_convolution_utils.hpp"
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::utils;
+using namespace prop_kind;
+using namespace data_type;
+
+namespace jit_gemm_convolution_utils {
+
+void im2col_3d(const jit_gemm_conv_conf_t &jcp, const float *im, float *col,
+ int od)
+{
+ const size_t OHW = jcp.oh * jcp.ow;
+ const size_t im_step = jcp.ih * jcp.iw * jcp.id;
+ const size_t col_step = jcp.ks * OHW;
+
+ parallel_nd(jcp.ic, [&](int ic) {
+ const float *__restrict im_loc = im + ic * im_step;
+ float *__restrict col_loc = col + ic * col_step;
+ int id = od * jcp.stride_d - jcp.f_pad;
+ for (int kd = 0; kd < jcp.kd; ++kd) {
+ float *__restrict col_ = col_loc + kd * jcp.kh * jcp.kw * OHW;
+ if (id < 0 || id >= jcp.id) {
+ int ih_ = -jcp.t_pad;
+ for (int kh = 0; kh < jcp.kh; ++kh) {
+ int ih = ih_;
+ for (int oh = 0; oh < jcp.oh; ++oh) {
+ if (ih < 0 || ih >= jcp.ih) {
+ ih += jcp.stride_h;
+ continue;
+ }
+ int iw_ = -jcp.l_pad;
+ for (int kw = 0; kw < jcp.kw; ++kw) {
+ int iw = iw_;
+ for (int ow = 0; ow < jcp.ow; ++ow) {
+ if (iw < 0 || iw >= jcp.iw) {
+ iw += jcp.stride_w;
+ continue;
+ }
+
+ const size_t col_idx = kw * OHW + oh * jcp.ow
+ + ow;
+
+ col_[col_idx] = 0;
+ iw += jcp.stride_w;
+ }
+ iw_ += (1 + jcp.dilate_w);
+ }
+ ih += jcp.stride_h;
+ }
+ ih_ += (1 + jcp.dilate_h);
+ col_ += jcp.kw * OHW;
+ }
+ } else {
+ const float *__restrict im_ = im_loc + id * jcp.ih * jcp.iw;
+ int ih_ = -jcp.t_pad;
+ for (int kh = 0; kh < jcp.kh; ++kh) {
+ int ih = ih_;
+ for (int oh = 0; oh < jcp.oh; ++oh) {
+ if (ih < 0 || ih >= jcp.ih) {
+ ih += jcp.stride_h;
+ continue;
+ }
+ int iw_ = -jcp.l_pad;
+ for (int kw = 0; kw < jcp.kw; ++kw) {
+ int iw = iw_;
+ for (int ow = 0; ow < jcp.ow; ++ow) {
+ if (iw < 0 || iw >= jcp.iw) {
+ iw += jcp.stride_w;
+ continue;
+ }
+
+ const size_t col_idx = kw * OHW + oh * jcp.ow
+ + ow;
+ const size_t im_idx = ih * jcp.iw + iw;
+
+ col_[col_idx] = im_[im_idx];
+ iw += jcp.stride_w;
+ }
+ iw_ += (1 + jcp.dilate_w);
+ }
+ ih += jcp.stride_h;
+ }
+ ih_ += (1 + jcp.dilate_h);
+ col_ += jcp.kw * OHW;
+ }
+ }
+ id += (1 + jcp.dilate_d);
+ }
+ });
+}
+
+/* col[ic][kh][kw][oh][ow] <-- im2col(im[ic][ih][iw]) */
+void im2col(const jit_gemm_conv_conf_t &jcp, const float *__restrict im,
+ float *__restrict col, int hs, int hb, int ws, int wb) {
+ const size_t im_step = jcp.is;
+ const size_t col_step = jcp.ks * hb * wb;
+ if (jcp.stride_w == 1) {
+ // Generated code is more optimized for stride_w == 1
+ // because innermost loop is by width
+ auto ker = [&](int ic, int kh, int kw, int oh) {
+ const float *__restrict im_ = im + ic * im_step;
+ float *__restrict col_
+ = col + ic * col_step + ((kh * jcp.kw + kw) * hb + oh) * wb;
+
+ const int ih = (oh + hs) * jcp.stride_h - jcp.t_pad
+ + kh * (1 + jcp.dilate_h);
+ if (ih < 0 || ih >= jcp.ih) {
+ for (int ow = 0; ow < wb; ++ow)
+ col_[ow] = 0.f;
+ } else {
+ for (int ow = 0; ow < wb; ++ow) {
+ const int iw = ow + ws - jcp.l_pad + kw * (1 + jcp.dilate_w);
+ if (iw < 0 || iw >= jcp.iw)
+ col_[ow] = 0.f;
+ else {
+ const size_t im_idx = ih * jcp.iw + iw;
+ col_[ow] = im_[im_idx];
+ }
+ }
+ }
+ };
+
+ if (jcp.outer_threading) {
+ for (int ic = 0; ic < jcp.ic; ic++)
+ for (int kh = 0; kh < jcp.kh; kh++)
+ for (int kw = 0; kw < jcp.kw; kw++)
+ for (int oh = 0; oh < hb; oh++)
+ ker(ic, kh, kw, oh);
+ }
+ else {
+ parallel_nd(jcp.ic, jcp.kh, jcp.kw, hb, ker);
+ }
+ } else if (jcp.ic == 1) {
+ parallel_nd(jcp.kh, hb, [&](int kh, int oh) {
+ const int ih = (oh + hs) * jcp.stride_h - jcp.t_pad
+ + kh * (1 + jcp.dilate_h);
+ if (ih < 0 || ih >= jcp.ih)
+ for (int kw = 0; kw < jcp.kw; ++kw) {
+ for (int ow = 0; ow < wb; ++ow) {
+ const size_t col_idx
+ = ((kh * jcp.kw + kw) * hb + oh) * wb + ow;
+ col[col_idx] = 0;
+ }
+ }
+ else
+ for (int kw = 0; kw < jcp.kw; ++kw) {
+ for (int ow = 0; ow < wb; ++ow) {
+ const int iw = (ow + ws) * jcp.stride_w - jcp.l_pad
+ + kw * (1 + jcp.dilate_w);
+ const size_t col_idx
+ = ((kh * jcp.kw + kw) * hb + oh) * wb + ow;
+ const size_t im_idx = ih * jcp.iw + iw;
+ if (iw < 0 || iw >= jcp.iw)
+ col[col_idx] = 0;
+ else
+ col[col_idx] = im[im_idx];
+ }
+ }
+ });
+ } else {
+
+ parallel_nd(jcp.ic, jcp.kh, jcp.kw, hb,
+ [&](int ic, int kh, int kw, int oh) {
+ const float *__restrict im_ = im + ic * im_step;
+ float *__restrict col_ = col + ic * col_step
+ + ((kh * jcp.kw + kw) * hb + oh) * wb;
+
+ const int ih = (oh + hs) * jcp.stride_h - jcp.t_pad
+ + kh * (1 + jcp.dilate_h);
+ if (ih < 0 || ih >= jcp.ih) {
+ for (int ow = 0; ow < wb; ++ow)
+ col_[ow] = 0.f;
+ } else {
+ for (int ow = 0; ow < wb; ++ow) {
+ const int iw = (ow + ws) * jcp.stride_w - jcp.l_pad
+ + kw * (1 + jcp.dilate_w);
+ const size_t im_idx = ih * jcp.iw + iw;
+ if (iw < 0 || iw >= jcp.iw)
+ col_[ow] = 0.f;
+ else
+ col_[ow] = im_[im_idx];
+ }
+ }
+ });
+ }
+}
+
+inline int limit(int low, int upper, int value) {
+ return nstl::max(low, nstl::min(upper, value));
+}
+
+/* col[kh][kw][ic][oh][ow] <-- im2col_u8(im[ih][iw][ic]) */
+template <typename T>
+void im2col_u8(const jit_gemm_conv_conf_t &jcp, const T *__restrict im,
+ T *__restrict imtr, uint8_t *__restrict col, int hs, int hb, int ws,
+ int wb) {
+ uint8_t shift = jcp.signed_input ? 128 : 0;
+ const int dh = 1 + jcp.dilate_h;
+ const int dw = 1 + jcp.dilate_w;
+ const int sh = jcp.stride_h;
+ const int sw = jcp.stride_w;
+ const int im_iw_stride = jcp.ic * jcp.ngroups;
+ const int im_ih_stride = jcp.iw * im_iw_stride;
+ const int tp = jcp.t_pad;
+ const int lp = jcp.l_pad;
+
+ if (jcp.outer_threading && sh == 1 && sw == 1 && dh == 1 && dw == 1) {
+ /* im[ih][iw][ic] --> imtr[ic][ih][iw] --> col[kh][kw][ic][oh][ow] */
+ const int hp = hs - tp;
+ const int wp = ws - lp;
+ const int ih_start = limit(0, jcp.ih, hp);
+ const int ih_end = limit(0, jcp.ih, hp + hb + jcp.kh);
+ const int iw_start = limit(0, jcp.iw, wp);
+ const int iw_end = limit(0, jcp.iw, wp + wb + jcp.kw);
+
+ const int ihb = ih_end - ih_start;
+ const int iwb = iw_end - iw_start;
+
+ const int imtr_ic_stride = ihb * iwb;
+ const ptrdiff_t imtr_idx_shift = ih_start * iwb + iw_start;
+ for (int ic = 0; ic < jcp.ic; ic++) {
+ const ptrdiff_t imtr_idx_ic = ic * imtr_ic_stride - imtr_idx_shift;
+ for (int ih = ih_start; ih < ih_end; ih++) {
+ const ptrdiff_t im_idx_ih = ic + ih * im_ih_stride;
+ const ptrdiff_t imtr_idx_ih = imtr_idx_ic + ih * iwb;
+ for (int iw = iw_start; iw < iw_end; iw++)
+ imtr[imtr_idx_ih + iw] = im[im_idx_ih + iw * im_iw_stride];
+ }
+ }
+
+ const int col_ic_str = hb * wb;
+ const int col_kw_stride = jcp.ic * col_ic_str;
+ const int col_kh_stride = jcp.kw * col_kw_stride;
+
+ const int oh_init = ih_start - hp;
+ const int ow_init = iw_start - wp;
+ for (int kh = 0; kh < jcp.kh; kh++) {
+ const ptrdiff_t col_idx_kh = kh * col_kh_stride;
+ const int oh_kh = oh_init - kh;
+ const int oh_start = limit(0, hb, oh_kh);
+ const int oh_end = limit(0, hb, oh_kh + ihb);
+ for (int kw = 0; kw < jcp.kw; kw++) {
+ const ptrdiff_t col_idx_kw
+ = col_idx_kh + kw * jcp.ic * col_ic_str;
+ const int ow_kw = ow_init - kw;
+ const int imtr_shift = oh_kh * iwb + ow_kw;
+ const int ow_start = limit(0, wb, ow_kw);
+ const int ow_end = limit(0, wb, ow_kw + iwb);
+ for (int ic = 0; ic < jcp.ic; ic++) {
+ const ptrdiff_t col_idx_ic = col_idx_kw + ic * col_ic_str;
+ const int imtr_idx_ic = ic * imtr_ic_stride - imtr_shift;
+ for (int oh = 0; oh < oh_start; oh++) {
+ const ptrdiff_t col_idx_oh = col_idx_ic + oh * wb;
+ for (int ow = 0; ow < wb; ++ow)
+ col[col_idx_oh + ow] = shift;
+ }
+ for (int oh = oh_start; oh < oh_end; oh++) {
+ const ptrdiff_t col_idx_oh = col_idx_ic + oh * wb;
+ const ptrdiff_t imtr_idx_oh = imtr_idx_ic + oh * iwb;
+ for (int ow = 0; ow < ow_start; ++ow)
+ col[col_idx_oh + ow] = shift;
+ for (int ow = ow_start; ow < ow_end; ++ow)
+ col[col_idx_oh + ow]
+ = imtr[imtr_idx_oh + ow] + shift;
+ for (int ow = ow_end; ow < wb; ++ow)
+ col[col_idx_oh + ow] = shift;
+ }
+ for (int oh = oh_end; oh < hb; oh++) {
+ const ptrdiff_t col_idx_oh = col_idx_ic + oh * wb;
+ for (int ow = 0; ow < wb; ++ow)
+ col[col_idx_oh + ow] = shift;
+ }
+ }
+ }
+ }
+ } else {
+ parallel_nd(jcp.kh, jcp.kw, jcp.ic, hb,
+ [&](int kh, int kw, int ic, int oh) {
+ const int hp = tp - kh * dh;
+ const int ih = (oh + hs) * sh - hp;
+ const ptrdiff_t col_idx_base
+ = (((kh * jcp.kw + kw) * jcp.ic + ic) * hb + oh) * wb;
+ if (ih < 0 || ih >= jcp.ih)
+ for (int ow = 0; ow < wb; ow++)
+ col[col_idx_base + ow] = shift;
+ else {
+ const int wp = lp - kw * dw;
+ const int ow_start = limit(0, wb, div_up(wp, sw) - ws);
+ const int ow_end
+ = limit(0, wb, div_up(jcp.iw + wp, sw) - ws);
+ for (int ow = 0; ow < ow_start; ow++)
+ col[col_idx_base + ow] = shift;
+ const int iw_base = ws * sw - wp;
+ const ptrdiff_t im_idx_base = ih * im_ih_stride + ic;
+ for (int ow = ow_start; ow < ow_end; ow++) {
+ const int iw = iw_base + ow * sw;
+ const ptrdiff_t im_idx
+ = im_idx_base + iw * im_iw_stride;
+ col[col_idx_base + ow] = im[im_idx] + shift;
+ }
+ for (int ow = ow_end; ow < wb; ow++)
+ col[col_idx_base + ow] = shift;
+ }
+ });
+ }
+}
+
+template void im2col_u8<int8_t>(const jit_gemm_conv_conf_t &jcp,
+ const int8_t *__restrict im, int8_t *__restrict imtr,
+ uint8_t *__restrict col, int hs, int hb, int ws, int wb);
+template void im2col_u8<uint8_t>(const jit_gemm_conv_conf_t &jcp,
+ const uint8_t *__restrict im, uint8_t *__restrict imtr,
+ uint8_t *__restrict col, int hs, int hb, int ws, int wb);
+
+/* im[ih][iw][ic] <-- col2im_s32(col[oh][ow][kh][kw][ic]) */
+void col2im_s32(const jit_gemm_conv_conf_t &jcp, const int32_t *__restrict col,
+ int32_t *__restrict im)
+{
+ parallel(0, [&](const int ithr, const int nthr) {
+ int h_nthr = nstl::min(jcp.ih, nthr);
+ int w_nthr = nstl::min(jcp.iw, nthr / h_nthr);
+ int h_ithr = 1, h_s = 0, h_e = 0, w_ithr = 1, w_s = 0, w_e = 0;
+ if (ithr < h_nthr * w_nthr) {
+ h_ithr = ithr / w_nthr;
+ w_ithr = ithr % w_nthr;
+ balance211(jcp.ih, h_nthr, h_ithr, h_s, h_e);
+ balance211(jcp.iw, w_nthr, w_ithr, w_s, w_e);
+ } else {
+ h_ithr = w_ithr = -ithr;
+ h_s = h_e = w_s = w_e = -1;
+ }
+
+ for (int ih = h_s; ih < h_e; ++ih) {
+ for (int iw = w_s; iw < w_e; ++iw) {
+ PRAGMA_OMP_SIMD()
+ for (int ic = 0; ic < jcp.ic; ++ic) {
+ im[(ih * jcp.iw + iw) * jcp.ic + ic] = 0;
+ }
+ }
+ }
+
+ // TODO: reduce region: [0.. oh] --> [h_s * sh .. h_e * sh]
+ for (int oh = 0; oh < jcp.oh; ++oh) {
+ for (int ow = 0; ow < jcp.ow; ++ow) {
+ for (int kh = 0; kh < jcp.kh; ++kh) {
+ const int ih = oh * jcp.stride_h
+ - jcp.t_pad + kh * (1 + jcp.dilate_h);
+ if (ih < h_s || ih >= h_e) continue;
+
+ for (int kw = 0; kw < jcp.kw; ++kw) {
+ const int iw = ow * jcp.stride_w
+ - jcp.l_pad + kw * (1 + jcp.dilate_w);
+ if (iw < w_s || iw >= w_e) continue;
+
+ const size_t col_idx = (((oh * jcp.ow + ow) * jcp.kh
+ + kh) * jcp.kw + kw) * jcp.ic;
+ const size_t im_idx
+ = (ih * jcp.iw + iw) * jcp.ic;
+ PRAGMA_OMP_SIMD()
+ for (int ic = 0; ic < jcp.ic; ++ic) {
+ im[im_idx + ic] += col[col_idx + ic];
+ }
+ }
+ }
+ }
+ }
+ });
+}
+
+void col2im_3d(const jit_gemm_conv_conf_t &jcp, const float *col, float *im,
+ int od)
+{
+ parallel_nd(jcp.ic, [&](int ic) {
+ const float *__restrict col_ = col + (size_t)ic * jcp.ks * jcp.os;
+ float *__restrict im_ic = im + (size_t)ic * jcp.ih * jcp.iw * jcp.id;
+
+ int id = od * jcp.stride_d - jcp.f_pad;
+ for (int kd = 0; kd < jcp.kd; ++kd) {
+ if (id < 0 || id >= jcp.id) {
+ col_ += jcp.kh * jcp.kw * jcp.os;
+ id += (1 + jcp.dilate_d);
+ continue;
+ }
+
+ float *__restrict im_ = im_ic + id * jcp.ih * jcp.iw;
+
+ for (int oh = 0; oh < jcp.oh; ++oh) {
+ for (int kh = 0; kh < jcp.kh; ++kh) {
+ const int ih = oh * jcp.stride_h - jcp.t_pad
+ + kh * (1 + jcp.dilate_h);
+ if (ih < 0 || ih >= jcp.ih) continue;
+
+ for (int ow = 0; ow < jcp.ow; ++ow) {
+ for (int kw = 0; kw < jcp.kw; ++kw) {
+ const int iw = ow * jcp.stride_w - jcp.l_pad
+ + kw * (1 + jcp.dilate_w);
+ if (iw < 0 || iw >= jcp.iw) continue;
+
+ const size_t col_idx = ((kh*jcp.kw + kw)*jcp.oh+oh)*jcp.ow+ow;
+ const size_t im_idx = ih*jcp.iw + iw;
+ im_[im_idx] += col_[col_idx];
+ }}
+ }}
+
+ col_ += jcp.kh * jcp.kw * jcp.os;
+ id += (1 + jcp.dilate_d);
+ }
+ });
+}
+
+void col2im(const jit_gemm_conv_conf_t &jcp, const float *col, float *im) {
+ const size_t col_step = jcp.ks * jcp.os;
+ const size_t im_step = jcp.ih * jcp.iw;
+ const int iS = jcp.ih * jcp.iw;
+
+ parallel_nd(jcp.ic, [&](int ic) {
+ float *__restrict im_ = im + ic * im_step;
+ const float *__restrict col_ = col + ic * col_step;
+ PRAGMA_OMP_SIMD()
+ for (int is = 0; is < iS; ++is) im_[is] = 0.;
+
+ for (int kh = 0; kh < jcp.kh; ++kh) {
+ for (int oh = 0; oh < jcp.oh; ++oh) {
+ const int ih =
+ oh * jcp.stride_h - jcp.t_pad + kh * (1 + jcp.dilate_h);
+ if (ih < 0 || ih >= jcp.ih) continue;
+
+ for (int kw = 0; kw < jcp.kw; ++kw) {
+ for (int ow = 0; ow < jcp.ow; ++ow) {
+ const int iw =
+ ow * jcp.stride_w - jcp.l_pad + kw * (1 + jcp.dilate_w);
+ if (iw < 0 || iw >= jcp.iw) continue;
+
+ const size_t col_idx = ((kh*jcp.kw + kw)*jcp.oh+oh)*jcp.ow+ow;
+ const size_t im_idx = ih*jcp.iw + iw;
+ im_[im_idx] += col_[col_idx];
+ }
+ }
+ }
+ }
+ });
+}
+
+status_t init_conf(jit_gemm_conv_conf_t &jcp,
+ memory_tracking::registrar_t &scratchpad, const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d, const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d, int max_threads) {
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+ const int ndims = src_d.ndims();
+ const int is_1d = ndims == 3;
+ const int is_3d = ndims == 5;
+
+ jcp.prop_kind = cd.prop_kind;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+ jcp.id = is_3d ? src_d.dims()[2] : 1;
+ jcp.ih = is_1d ? 1 : src_d.dims()[ndims - 2];
+ jcp.iw = src_d.dims()[ndims - 1];
+ jcp.od = is_3d ? dst_d.dims()[2] : 1;
+ jcp.oh = is_1d ? 1 : dst_d.dims()[ndims - 2];
+ jcp.ow = dst_d.dims()[ndims - 1];
+
+ jcp.kd = is_3d ? weights_d.dims()[with_groups + 2] : 1;
+ jcp.kh = is_1d ? 1 : weights_d.dims()[with_groups + ndims - 2];
+ jcp.kw = weights_d.dims()[with_groups + ndims - 1];
+
+ jcp.f_pad = is_3d ? cd.padding[0][0] : 0;
+ jcp.t_pad = is_1d ? 0 : cd.padding[0][ndims - 4];
+ jcp.l_pad = cd.padding[0][ndims - 3];
+
+ jcp.stride_d = is_3d ? cd.strides[0] : 1;
+ jcp.stride_h = is_1d ? 1 : cd.strides[ndims - 4];
+ jcp.stride_w = cd.strides[ndims - 3];
+
+ jcp.dilate_d = is_3d ? cd.dilates[0] : 0;
+ jcp.dilate_h = is_1d ? 0 : cd.dilates[ndims - 4];
+ jcp.dilate_w = cd.dilates[ndims - 3];
+
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef
+ || cd.diff_bias_desc.format_kind != format_kind::undef;
+
+ jcp.is = jcp.ih * jcp.iw;
+ jcp.os = jcp.oh * jcp.ow;
+ jcp.ks = jcp.kh * jcp.kw * jcp.kd;
+
+ jcp.signed_input = src_d.data_type() == data_type::s8;
+
+ jcp.im2col_sz = !everyone_is(true,
+ jcp.ow == jcp.iw, jcp.oh == jcp.ih, jcp.od == jcp.id,
+ jcp.stride_w == 1, jcp.stride_h == 1, jcp.stride_d == 1,
+ jcp.ks == 1, !jcp.signed_input)
+ ? (ptrdiff_t)jcp.ic * jcp.ks * jcp.os : 0;
+
+ jcp.outer_threading = false;
+
+ bool is_int8_conv = utils::one_of(src_d.data_type(), s32, s8, u8)
+ && weights_d.data_type() == s8;
+
+ const int vlen = mayiuse(avx512_common)
+ ? cpu_isa_traits<avx512_common>::vlen
+ : mayiuse(avx)
+ ? cpu_isa_traits<avx>::vlen
+ : mayiuse(sse42) ? cpu_isa_traits<sse42>::vlen : 4;
+ const int simd_w = vlen / (is_int8_conv ? 1 : 4);
+
+ const bool is_bwd_d = jcp.prop_kind == backward_data;
+ const bool is_bwd_w = jcp.prop_kind == backward_weights;
+ const bool is_fwd = !is_bwd_d && !is_bwd_w;
+ jcp.oh_block = is_fwd ? jcp.oh : jcp.ih;
+ jcp.ow_block = is_fwd ? jcp.ow : jcp.iw;
+
+ using namespace memory_tracking::names;
+ bool is_depthwise = jcp.ic == 1 && jcp.oc == 1 && jcp.ngroups != 1;
+
+ // TODO: maybe mitigate blocking restriction
+ const int wei_size = jcp.oc * jcp.ic * jcp.kh * jcp.kw;
+ const int L2 = get_cache_size(2, true)
+ / (is_int8_conv ? sizeof(int8_t) : sizeof(float));
+ bool is_blocking_applicable = true
+ && is_fwd && jcp.im2col_sz
+ && jcp.id == 1 && jcp.od == 1
+ && jcp.dilate_h == 0 && jcp.dilate_w == 0
+ && !is_depthwise
+ && wei_size < L2/2;
+ if (is_blocking_applicable) {
+ // looking for oh and ow blocking
+ int h_block{ jcp.oh_block }, w_block{ jcp.ow_block };
+ const int ic = jcp.ic;
+ const int oc = jcp.oc;
+ const int iw = jcp.iw;
+ const int ow = jcp.ow;
+ const int oh = jcp.oh;
+ const int os = oh * ow;
+
+ // 1. cache requirement
+ int row_size = ic * ow * jcp.ks + 2 * (ic * iw + oc * ow);
+ if (is_int8_conv) {
+ // Heuristic rule: gemm needed a lot of memory for internal usage
+ row_size *= 5;
+ // memory for accumulators
+ row_size += oc * ow * sizeof(uint32_t);
+ // memory for transposition
+ row_size += ic * iw;
+ }
+
+ h_block = nstl::max(1, nstl::min(oh, div_up(L2, row_size)));
+ if (h_block == 1) {
+ int col_size = ic * jcp.ks + 2 * (ic + oc);
+ if (is_int8_conv) {
+ col_size *= 5;
+ col_size += oc * sizeof(uint32_t);
+ col_size += ic;
+ }
+ w_block = nstl::max(1, nstl::min(ow, div_up(L2, col_size)));
+ }
+
+ // 2. threading requirement
+ if (h_block != oh)
+ h_block = nstl::max(1, rnd_dn(h_block, 4));
+ if (w_block != ow)
+ w_block = nstl::max(1, rnd_dn(w_block, simd_w));
+
+ float thr_eff = 0.f;
+ float thr_eff_treshold = 0.9f;
+ if (w_block == ow) {
+ do {
+ int nb_h = div_up(oh, h_block);
+ size_t work = jcp.ngroups * jcp.mb * jcp.od * nb_h;
+ float disb = (float)oh / rnd_up(oh, h_block);
+ thr_eff = (float)work / rnd_up(work, max_threads);
+ thr_eff = (thr_eff + disb) / 2.f;
+ if (thr_eff >= thr_eff_treshold)
+ break;
+ h_block = rnd_dn(h_block - 4, 4);
+ } while (h_block > 0);
+ }
+ if (thr_eff < thr_eff_treshold) // we didn't find suitable h_block
+ {
+ h_block = 1;
+ int nb_h = oh;
+ do {
+ int nb_w = div_up(ow, w_block);
+ size_t work_amount = jcp.ngroups * jcp.mb * nb_h * nb_w;
+ float disb = (float)ow / rnd_up(ow, w_block);
+ thr_eff = (float)work_amount / rnd_up(work_amount, max_threads);
+ thr_eff = (thr_eff + disb) / 2.f;
+ if (thr_eff > thr_eff_treshold)
+ break;
+ w_block = rnd_dn(w_block - simd_w, simd_w);
+ } while (w_block > 0);
+ }
+ h_block = nstl::max(1, h_block);
+ w_block = nstl::max(1, w_block);
+ const size_t inner_work = div_up(os, simd_w) * div_up(oc, simd_w);
+ const float inner_thr_eff
+ = (float)inner_work / rnd_up(inner_work, max_threads);
+ if (thr_eff >= inner_thr_eff / 2 && h_block > 0 && w_block > 0) {
+ jcp.oh_block = h_block;
+ jcp.ow_block = w_block;
+ jcp.outer_threading = true;
+ }
+ // updating jcp.im2col_sz
+ if (jcp.oh_block != 1)
+ jcp.ow_block = ow;
+ jcp.im2col_sz = (ptrdiff_t)ic * jcp.ks * jcp.oh_block * jcp.ow_block;
+ }
+ // For threading selection in bwd_d we do:
+ // 1. Rough estimation of efficiency for inner and outer threading.
+ // 2. Gemm size estimation in assumption that it does not work
+ // so effectively for small sizes.
+ // 64K - this is heuristic gemm size per thread threshold.
+ const int gemm_thrld = 64 * 1024;
+
+ if (is_int8_conv) {
+ if (is_fwd) {
+ if (!jcp.outer_threading) {
+ bool is_depthwise = jcp.ic == 1 && jcp.oc == 1 && jcp.ngroups != 1;
+ const size_t outer_work = jcp.ngroups * jcp.mb;
+ const float outer_thr_eff
+ = (float)outer_work / rnd_up(outer_work, max_threads);
+ const size_t inner_work
+ = div_up(jcp.is, simd_w) * div_up(jcp.ic, simd_w);
+ const float inner_thr_eff
+ = (float)inner_work / rnd_up(inner_work, max_threads);
+ jcp.outer_threading = (is_depthwise
+ || (jcp.is / max_threads < 64 && jcp.mb != 1))
+ && (outer_thr_eff / inner_thr_eff >= 1.f
+ || (jcp.os * jcp.ic * jcp.oc) / max_threads < gemm_thrld);
+ }
+ jcp.nthr = jcp.outer_threading ? max_threads : 1;
+ scratchpad.book(key_conv_gemm_col,
+ sizeof(int8_t) * jcp.nthr * jcp.im2col_sz);
+ scratchpad.book(key_conv_int_dat_in_acc_dt,
+ sizeof(int32_t) * jcp.nthr * jcp.oh_block * jcp.ow_block * jcp.oc);
+ scratchpad.book(key_conv_gemm_imtr,
+ sizeof(int8_t) * jcp.nthr * jcp.is * jcp.ic);
+ } else if (is_bwd_d) {
+ bool is_depthwise = jcp.ic == 1 && jcp.oc == 1 && jcp.ngroups != 1;
+ const size_t outer_work = jcp.ngroups * jcp.mb;
+ const float outer_thr_eff
+ = (float)outer_work / rnd_up(outer_work, max_threads);
+ const size_t inner_work
+ = div_up(jcp.is, simd_w) * div_up(jcp.ic, simd_w);
+ const float inner_thr_eff
+ = (float)inner_work / rnd_up(inner_work, max_threads);
+ jcp.outer_threading = (is_depthwise
+ || (jcp.is / max_threads < 64 && jcp.mb != 1))
+ && (outer_thr_eff / inner_thr_eff >= 1.f
+ || (jcp.is * jcp.ic * jcp.oc) / max_threads < gemm_thrld);
+
+ jcp.nthr = jcp.outer_threading ? max_threads : 1;
+ scratchpad.book(key_conv_gemm_col,
+ sizeof(int32_t) * jcp.nthr * jcp.im2col_sz);
+ scratchpad.book(key_conv_int_dat_in_acc_dt,
+ sizeof(int32_t) * jcp.nthr * jcp.is * jcp.ic);
+ } else if (is_bwd_w) {
+ assert(!"unimplemented prop_kind");
+ return status::unimplemented;
+ }
+ } else {
+ if (is_fwd) {
+ if (!jcp.outer_threading) {
+ const size_t outer_work_amount = jcp.ngroups * jcp.mb * jcp.od;
+ const float outer_thr_eff = (float)outer_work_amount
+ / rnd_up(outer_work_amount, max_threads);
+ const size_t inner_work_amount
+ = div_up(jcp.os, simd_w) * div_up(jcp.oc, simd_w);
+ const float inner_thr_eff = (float)inner_work_amount
+ / rnd_up(inner_work_amount, max_threads);
+ jcp.outer_threading = jcp.os / max_threads < 512
+ && IMPLICATION(jcp.od == 1, jcp.mb != 1 || jcp.ngroups > 2)
+ && (outer_thr_eff / inner_thr_eff >= 1.f
+ || (jcp.os * jcp.ic * jcp.oc) / max_threads < gemm_thrld);
+ }
+ } else if (is_bwd_d) {
+ const size_t outer_work_amount = jcp.ngroups * jcp.mb;
+ const float outer_thr_eff = (float)outer_work_amount
+ / rnd_up(outer_work_amount, max_threads);
+ const size_t inner_work
+ = div_up(jcp.is, simd_w) * div_up(jcp.ic, simd_w);
+ const float inner_thr_eff = (float)inner_work
+ / rnd_up(inner_work, max_threads);
+ jcp.outer_threading = (jcp.os / max_threads < 512 || jcp.ks < 64)
+ && (jcp.mb != 1 || jcp.ngroups > 2)
+ && (outer_thr_eff / inner_thr_eff >= 1.f
+ || (jcp.is * jcp.ic * jcp.oc) / max_threads < gemm_thrld);
+ } else if (is_bwd_w)
+ jcp.outer_threading = jcp.os / max_threads < 256
+ && (jcp.mb != 1 || jcp.ngroups > 2);
+
+ jcp.nthr = jcp.outer_threading ? max_threads : 1;
+ scratchpad.book(key_conv_gemm_col,
+ sizeof(float) * jcp.nthr * jcp.im2col_sz);
+
+ if (is_bwd_w) {
+ jcp.need_wei_reduction = mkldnn_thr_syncable()
+ ? jcp.mb != 1 && jcp.nthr != 1 : false;
+ scratchpad.book(key_conv_wei_reduction,
+ sizeof(float) * jcp.nthr * jcp.ngroups * weights_d.size());
+ }
+ }
+
+ return status::success;
+}
+
+void bwd_weights_balance(int ithr, int nthr, int ngroups, int mb, int &ithr_g,
+ int &nthr_g, int &ithr_mb, int &nthr_mb) {
+ nthr_g = nstl::min(ngroups, nthr);
+ nthr_mb = nstl::min(mb, nthr / nthr_g);
+ if (ithr / nthr_mb >= ngroups) {
+ ithr_g = ithr_mb = -1;
+ } else {
+ ithr_g = ithr / nthr_mb;
+ ithr_mb = ithr % nthr_mb;
+ }
+}
+
+void bwd_weights_reduction_par(int ithr, int nthr,
+ const jit_gemm_conv_conf_t &jcp, const float *weights_reduce_ws,
+ float *weights) {
+ const size_t weights_g_size = jcp.ic * jcp.oc * jcp.ks;
+
+ size_t weights_start{0}, weights_end{0};
+ balance211(weights_g_size, nthr, ithr, weights_start, weights_end);
+
+ for (int i = 0; i < nthr; ++i) {
+ const float *ws_i = weights_reduce_ws + i * weights_g_size;
+ for (size_t s = weights_start; s < weights_end; ++s)
+ weights[s] = (i == 0 ? 0 : weights[s]) + ws_i[s];
+ }
+}
+
+};
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution_utils.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution_utils.hpp
new file mode 100644
index 0000000000..e006789344
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_convolution_utils.hpp
@@ -0,0 +1,66 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_GEMM_CONVOLUTION_UTILS_HPP
+#define CPU_JIT_GEMM_CONVOLUTION_UTILS_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_engine.hpp"
+#include "jit_primitive_conf.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace jit_gemm_convolution_utils {
+
+void im2col_3d(const jit_gemm_conv_conf_t &jcp, const float *im, float *col,
+ int od);
+void im2col(const jit_gemm_conv_conf_t &jcp, const float *__restrict im,
+ float *__restrict col, int hs, int hb, int ws, int wb);
+template <typename T>
+void im2col_u8(const jit_gemm_conv_conf_t &jcp, const T *__restrict im,
+ T* __restrict imtr, uint8_t *__restrict col,
+ int hs, int hb, int ws, int wb);
+
+void col2im_s32(const jit_gemm_conv_conf_t &jcp, const int32_t *__restrict col,
+ int32_t *__restrict im);
+void col2im_3d(const jit_gemm_conv_conf_t &jcp, const float *col, float *im,
+ int od);
+void col2im(const jit_gemm_conv_conf_t &jcp, const float *col, float *im);
+
+status_t init_conf(jit_gemm_conv_conf_t &jcp,
+ memory_tracking::registrar_t &scratchpad, const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d, const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d, int max_threads);
+
+void bwd_weights_balance(int ithr, int nthr, int ngroups, int mb,
+ int &ithr_g, int &nthr_g, int &ithr_mb, int &nthr_mb);
+void bwd_weights_reduction_par(int ithr, int nthr,
+ const jit_gemm_conv_conf_t &jcp, const float *weights_reduce_ws,
+ float *weights);
+
+}
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm_inner_product.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_inner_product.cpp
new file mode 100644
index 0000000000..2872122f0d
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_inner_product.cpp
@@ -0,0 +1,156 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "mkldnn_thread.hpp"
+
+#include "gemm_inner_product.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::data_type;
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::primitive_kind;
+
+template <impl::data_type_t data_type>
+void gemm_inner_product_fwd_t<data_type>::execute_forward(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const int MB = pd()->MB();
+ const int OC = pd()->OC();
+ const int IC = pd()->IC_total_padded();
+
+ bool wei_tr = !memory_desc_matches_one_of_tag(
+ *pd()->weights_md(), hwio, dhwio, io);
+
+ const auto &post_ops = pd()->attr()->post_ops_;
+ const bool do_relu = post_ops.len_ == 1;
+
+ float alpha = 1.0, beta = 0.0;
+ extended_sgemm(wei_tr ? "T" : "N", "N", &OC, &MB, &IC, &alpha, weights,
+ wei_tr ? &IC : &OC, src, &IC, &beta, dst, &OC, bias);
+
+ if (do_relu) {
+ float nslope = post_ops.entry_[0].eltwise.alpha;
+ parallel_nd(MB, OC, [&](int mb, int oc) {
+ size_t dst_off = mb * OC + oc;
+ if (dst[dst_off] < 0)
+ dst[dst_off] *= nslope;
+ });
+ }
+}
+
+template <impl::data_type_t data_type>
+void gemm_inner_product_bwd_data_t<data_type>::execute_backward_data(
+ const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const int MB = pd()->MB();
+ const int OC = pd()->OC();
+ const int IC = pd()->IC_total_padded();
+
+ bool wei_tr = memory_desc_matches_one_of_tag(
+ *pd()->weights_md(), hwio, dhwio, io);
+
+ float alpha = 1.0, beta = 0.0;
+ extended_sgemm(wei_tr ? "T" : "N", "N", &IC, &MB, &OC, &alpha, weights,
+ wei_tr ? &OC : &IC, diff_dst, &OC, &beta, diff_src, &IC);
+}
+
+template <impl::data_type_t data_type>
+void gemm_inner_product_bwd_weights_t<data_type>::execute_backward_weights(
+ const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_weights = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_WEIGHTS);
+ auto diff_bias = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_BIAS);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_bias_d(pd()->diff_weights_md(1));
+
+ diff_dst += diff_dst_d.offset0();
+
+ const int MB = pd()->MB();
+ const int OC = pd()->OC();
+ const int IC = pd()->IC_total_padded();
+
+ bool wei_tr = memory_desc_matches_one_of_tag(
+ *pd()->diff_weights_md(), hwio, dhwio, io);
+
+ float alpha = 1.0, beta = 0.0;
+ if (wei_tr)
+ extended_sgemm("N", "T", &OC, &IC, &MB, &alpha, diff_dst, &OC, src, &IC,
+ &beta, diff_weights, &OC);
+ else
+ extended_sgemm("N", "T", &IC, &OC, &MB, &alpha, src, &IC, diff_dst, &OC,
+ &beta, diff_weights, &IC);
+
+ if (diff_bias) {
+ diff_bias += diff_bias_d.offset0();
+ constexpr int blksize = 8;
+ const int OC_blocks = OC / blksize;
+ const int rem_OC = OC % blksize;
+ parallel(0, [&](const int ithr, const int nthr) {
+ int oc_st{0}, oc_e{0};
+ balance211(OC_blocks, nthr, ithr, oc_st, oc_e);
+ oc_st = oc_st * blksize;
+ oc_e = oc_e * blksize;
+
+ PRAGMA_OMP_SIMD()
+ for (int oc = oc_st; oc < oc_e; ++oc) {
+ diff_bias[oc] = diff_dst[oc];
+ }
+
+ for (int mb = 1; mb < MB; ++mb) {
+ PRAGMA_OMP_SIMD()
+ for (int oc = oc_st; oc < oc_e; ++oc) {
+ diff_bias[oc] += diff_dst[mb * OC + oc];
+ }
+ }
+
+ if (rem_OC != 0 && ithr == nthr-1) {
+ for (int oc = OC_blocks * blksize; oc < OC; oc++)
+ diff_bias[oc] = diff_dst[oc];
+ for (int mb = 1; mb < MB; ++mb) {
+ for (int oc = OC_blocks * blksize; oc < OC; oc++) {
+ diff_bias[oc] += diff_dst[mb * OC + oc];
+ }
+ }
+ }
+ });
+ }
+}
+
+template struct gemm_inner_product_fwd_t<data_type::f32>;
+template struct gemm_inner_product_bwd_data_t<data_type::f32>;
+template struct gemm_inner_product_bwd_weights_t<data_type::f32>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm_inner_product.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_inner_product.hpp
new file mode 100644
index 0000000000..acf0a49b9a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_inner_product.hpp
@@ -0,0 +1,157 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_GEMM_INNER_PRODUCT_HPP
+#define CPU_GEMM_INNER_PRODUCT_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "gemm/gemm.hpp"
+
+#include "cpu_inner_product_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t data_type>
+struct gemm_inner_product_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_inner_product_fwd_pd_t {
+ using cpu_inner_product_fwd_pd_t::cpu_inner_product_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T(GEMM_IMPL_STR, gemm_inner_product_fwd_t);
+
+ status_t init() {
+ using namespace utils;
+
+ bool ok = true
+ && set_default_params() == status::success
+ && is_fwd()
+ && !has_zero_dim_memory()
+ && everyone_is(data_type,
+ src_md()->data_type,
+ weights_md()->data_type,
+ dst_md()->data_type,
+ with_bias() ? weights_md(1)->data_type : data_type)
+ && attr()->output_scales_.has_default_values()
+ && attr()->post_ops_.len_ <= 1
+ && IMPLICATION(attr()->post_ops_.len_ == 1,
+ attr()->post_ops_.entry_[0].is_relu(true, false))
+ && dense_gemm_consitency_check(src_md(), weights_md(),
+ dst_md());
+ return ok ? status::success : status::unimplemented;
+ }
+ };
+
+ gemm_inner_product_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t data_type>
+struct gemm_inner_product_bwd_data_t: public cpu_primitive_t {
+ struct pd_t: public cpu_inner_product_bwd_data_pd_t {
+ using cpu_inner_product_bwd_data_pd_t::cpu_inner_product_bwd_data_pd_t;
+
+ DECLARE_COMMON_PD_T(GEMM_IMPL_STR, gemm_inner_product_bwd_data_t);
+
+ status_t init() {
+ bool ok = true
+ && set_default_params() == status::success
+ && desc()->prop_kind == prop_kind::backward_data
+ && !has_zero_dim_memory()
+ && utils::everyone_is(data_type,
+ diff_src_md()->data_type,
+ weights_md()->data_type,
+ diff_dst_md()->data_type)
+ && attr()->has_default_values()
+ && dense_gemm_consitency_check(diff_src_md(), weights_md(),
+ diff_dst_md());
+ return ok ? status::success : status::unimplemented;
+ }
+ };
+
+ gemm_inner_product_bwd_data_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_data(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_data(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t data_type>
+struct gemm_inner_product_bwd_weights_t: public cpu_primitive_t {
+ struct pd_t: public cpu_inner_product_bwd_weights_pd_t {
+ using cpu_inner_product_bwd_weights_pd_t::cpu_inner_product_bwd_weights_pd_t;
+
+ DECLARE_COMMON_PD_T(GEMM_IMPL_STR, gemm_inner_product_bwd_weights_t);
+
+ status_t init() {
+ bool ok = true
+ && set_default_params() == status::success
+ && desc()->prop_kind == prop_kind::backward_weights
+ && !has_zero_dim_memory()
+ && utils::everyone_is(data_type,
+ src_md()->data_type,
+ diff_weights_md()->data_type,
+ diff_dst_md()->data_type,
+ with_bias() ? diff_weights_md(1)->data_type : data_type)
+ && attr()->has_default_values()
+ && dense_gemm_consitency_check(src_md(), diff_weights_md(),
+ diff_dst_md());
+
+ return ok ? status::success : status::unimplemented;
+ }
+ };
+
+ gemm_inner_product_bwd_weights_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_weights(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_weights(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_convolution.cpp
new file mode 100644
index 0000000000..fed7e4d693
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_convolution.cpp
@@ -0,0 +1,740 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "utils.hpp"
+#include "type_helpers.hpp"
+#include "mkldnn_thread.hpp"
+#include "math_utils.hpp"
+
+#include "simple_q10n.hpp"
+
+#include "gemm/gemm.hpp"
+#include "gemm_x8s8s32x_convolution.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::math;
+using namespace mkldnn::impl::memory_tracking::names;
+
+template <data_type_t src_type, data_type_t dst_type>
+void _gemm_x8s8s32x_convolution_fwd_t<src_type, dst_type>::
+execute_forward(const exec_ctx_t &ctx) const {
+ auto src_base = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto wei_base = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bia_base = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto dst_base = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ auto scratchpad = this->scratchpad(ctx);
+
+ const jit_gemm_conv_conf_t &jcp = this->pd()->jcp_;
+
+ assert(IMPLICATION(
+ jcp.id != 1, jcp.oh_block == jcp.oh && jcp.ow_block == jcp.ow));
+ assert(IMPLICATION(jcp.ow_block != jcp.ow, jcp.oh_block == 1));
+
+ parallel(jcp.nthr, [&](const int ithr, const int nthr) {
+ execute_forward_thr(ithr, nthr, src_base, wei_base, bia_base, dst_base,
+ scratchpad);
+ });
+}
+
+template <data_type_t src_type, data_type_t dst_type>
+_gemm_x8s8s32x_convolution_fwd_t<src_type, dst_type>::pp_ker_t::pp_ker_t(
+ const pd_t *pd)
+ : ker_(nullptr)
+ , jcp_(pd->jcp_)
+ , OC_(pd->jcp_.oc)
+ , OS_(pd->jcp_.os)
+ , bias_data_type_(data_type::undef)
+ , bias_data_type_size_(0)
+ , scale_idx_mult_(0)
+ , do_bias_(false)
+ , do_relu_(false)
+ , do_sum_(false)
+{
+ using namespace types;
+
+ const auto dst_md = memory_desc_wrapper(pd->dst_md());
+ dst_os_stride_ = dst_md.blk_off(0, 0, 0, 1);
+
+ scale_idx_mult_ = (pd->attr()->output_scales_.mask_ == (1 << 1));
+
+ auto &post_ops = pd->attr()->post_ops_;
+
+ int entry_idx = -1;
+ for (int idx = 0; idx < post_ops.len_; ++idx) {
+ const auto &e = post_ops.entry_[idx];
+ if (e.is_relu(true, false)) {
+ entry_idx = idx;
+ break;
+ }
+ }
+ do_relu_ = entry_idx >= 0;
+
+ do_signed_scaling_ = jcp_.signed_input;
+
+ do_sum_ = post_ops.contain(primitive_kind::sum, 0);
+ do_bias_ = pd->with_bias();
+ bias_data_type_ = pd->desc()->bias_desc.data_type;
+ if (do_bias_) {
+ assert(bias_data_type_ != data_type::undef);
+ bias_data_type_size_ = data_type_size(bias_data_type_);
+ }
+ const size_t vlen_start
+ = cpu_isa_traits<avx512_common>::vlen / sizeof(float);
+
+ for (size_t i = vlen_start; i > 0; i--) {
+ if (OC_ % i == 0) {
+ vlen_ = i;
+ break;
+ }
+ }
+
+ if (!mayiuse(avx512_core))
+ // use fallback code for older CPUs
+ return;
+ else
+ generate();
+}
+
+template <data_type_t src_type, data_type_t dst_type>
+void _gemm_x8s8s32x_convolution_fwd_t<src_type, dst_type>::pp_ker_t::generate()
+{
+ using namespace Xbyak;
+ using namespace utils;
+
+ // TODO: clean-up
+ Reg64 reg_param = abi_param1;
+ Reg64 reg_dst = rdx;
+ Reg64 reg_acc = rax;
+ Reg64 reg_bias = rbx;
+ Reg64 reg_scales = rsi;
+
+ Reg64 reg_len = r8;
+ Reg64 reg_tmp = rcx; // intentional for shifting purposes
+ Reg64 reg_oc_offset = r9;
+ Reg64 reg_rem_mask_short = r10;
+ Reg64 reg_rem_mask_vlen = r11;
+ Opmask kreg_rem_mask_short = k1;
+ Opmask kreg_rem_mask_vlen = k3;
+ Opmask kreg_relu_cmp = k2;
+
+ const size_t vlen = vlen_;
+
+ Zmm vreg_zero = Zmm(0);
+ Zmm vreg_scale = Zmm(1);
+ Zmm vreg_nslope = Zmm(2);
+ Zmm vreg_sum_scale = Zmm(3);
+ Zmm vreg_signed_scale = Zmm(4);
+
+ size_t def_unroll = 4;
+ size_t max_unroll = 12;
+ size_t zmm_step = 2;
+ if (do_sum_) {
+ max_unroll = 8;
+ zmm_step = 3;
+ }
+
+ auto vreg_dst = [&](int idx) {
+ return Zmm(5 + idx * zmm_step + 0);
+ };
+ auto vreg_bias = [&](int idx) {
+ return Zmm(5 + idx * zmm_step + 1);
+ };
+ auto vreg_prev_dst = [&](int idx) {
+ return Zmm(5 + idx * zmm_step + 2);
+ };
+
+ preamble();
+
+#define PARAM_OFF(x) offsetof(ker_args, x)
+ mov(reg_dst, ptr[reg_param + PARAM_OFF(dst)]);
+ mov(reg_acc, ptr[reg_param + PARAM_OFF(acc)]);
+ mov(reg_bias, ptr[reg_param + PARAM_OFF(bias)]);
+ mov(reg_scales, ptr[reg_param + PARAM_OFF(scales)]);
+ mov(reg_len, ptr[reg_param + PARAM_OFF(len)]);
+ mov(reg_oc_offset, ptr[reg_param + PARAM_OFF(oc_offset)]);
+ vbroadcastss(vreg_nslope, ptr[reg_param + PARAM_OFF(nslope)]);
+ vbroadcastss(vreg_sum_scale, ptr[reg_param + PARAM_OFF(sum_scale)]);
+ vbroadcastss(vreg_signed_scale, ptr[reg_param + PARAM_OFF(signed_scale)]);
+ if (scale_idx_mult_ == 0)
+ vbroadcastss(vreg_scale, dword[reg_scales]);
+
+#undef PARAM_OFF
+
+ mov(reg_rem_mask_vlen, 1);
+ shl(reg_rem_mask_vlen, vlen);
+ sub(reg_rem_mask_vlen, 1);
+ kmovq(kreg_rem_mask_vlen, reg_rem_mask_vlen);
+
+ if (do_relu_ || dst_type == data_type::u8)
+ vxorps(vreg_zero, vreg_zero, vreg_zero);
+
+ // Load accumulated value, convert to float, apply sum (if any),
+ // bias (if any), scaling, and relu (if any);
+ // then convert to destination type and store
+ auto compute = [&](size_t offset, int idx, bool apply_mask) {
+ auto acc_addr = ptr[reg_acc + offset * sizeof(acc_data_t)];
+
+ if (scale_idx_mult_ > 0) {
+ assert(scale_idx_mult_ == 1);
+ auto scale_addr = ptr[reg_scales + offset * sizeof(float)];
+ auto vreg_scale_ = vreg_scale;
+ if (apply_mask)
+ vreg_scale_ = vreg_scale_ | kreg_rem_mask_short;
+ else
+ vreg_scale_ = vreg_scale_ | kreg_rem_mask_vlen;
+ vmovups(vreg_scale_, scale_addr);
+ }
+
+ auto vreg_dst_ = vreg_dst(idx);
+ if (apply_mask)
+ vreg_dst_ = vreg_dst_ | kreg_rem_mask_short;
+ else
+ vreg_dst_ = vreg_dst_ | kreg_rem_mask_vlen;
+ vcvtdq2ps(vreg_dst_, acc_addr);
+
+ if (do_signed_scaling_)
+ vmulps(vreg_dst(idx), vreg_dst(idx), vreg_signed_scale);
+
+ if (do_bias_) {
+ auto bias_addr = ptr[reg_bias + offset * bias_data_type_size_];
+ auto vreg_bias_ = vreg_bias(idx);
+ if (apply_mask)
+ vreg_bias_ = vreg_bias_ | kreg_rem_mask_short;
+ else
+ vreg_bias_ = vreg_bias_ | kreg_rem_mask_vlen;
+
+ switch (bias_data_type_) {
+ case data_type::s8:
+ vpmovsxbd(vreg_bias_, bias_addr);
+ break;
+ case data_type::u8:
+ vpmovzxbd(vreg_bias_, bias_addr);
+ break;
+ case data_type::s32:
+ case data_type::f32:
+ vmovups(vreg_bias_, bias_addr);
+ break;
+ default: assert(!"unimplemented");
+ }
+ if (bias_data_type_ != data_type::f32)
+ vcvtdq2ps(vreg_bias(idx), vreg_bias(idx));
+ vaddps(vreg_dst(idx), vreg_dst(idx), vreg_bias(idx));
+ }
+
+ vmulps(vreg_dst(idx), vreg_dst(idx), vreg_scale);
+
+ auto dst_addr = ptr[reg_dst + offset * sizeof(dst_data_t)];
+
+ if (do_sum_)
+ {
+ auto vreg_prev_dst_ = vreg_prev_dst(idx);
+ if (apply_mask)
+ vreg_prev_dst_ = vreg_prev_dst_ | kreg_rem_mask_short;
+ else
+ vreg_prev_dst_ = vreg_prev_dst_ | kreg_rem_mask_vlen;
+
+ switch (dst_type) {
+ case data_type::f32:
+ case data_type::s32: vmovups(vreg_prev_dst_, dst_addr); break;
+ case data_type::s8: vpmovsxbd(vreg_prev_dst_, dst_addr); break;
+ case data_type::u8: vpmovzxbd(vreg_prev_dst_, dst_addr); break;
+ default: assert(!"unsupported data type");
+ }
+ if (dst_type != data_type::f32)
+ vcvtdq2ps(vreg_prev_dst(idx), vreg_prev_dst(idx));
+
+ vfmadd231ps(vreg_dst(idx), vreg_prev_dst(idx), vreg_sum_scale);
+ }
+
+ if (do_relu_) {
+ vcmpps(kreg_relu_cmp, vreg_dst(idx), vreg_zero, _cmp_lt_os);
+ vmulps(vreg_dst(idx) | kreg_relu_cmp, vreg_dst(idx), vreg_nslope);
+ }
+
+ if (dst_type != data_type::f32) {
+ vcvtps2dq(vreg_dst(idx), vreg_dst(idx));
+ }
+
+ if (dst_type == data_type::u8)
+ vpmaxsd(vreg_dst(idx), vreg_dst(idx), vreg_zero);
+
+ switch (dst_type) {
+ case data_type::s8:
+ vpmovsdb(dst_addr, vreg_dst_);
+ break;
+ case data_type::u8:
+ vpmovusdb(dst_addr, vreg_dst_);
+ break;
+ case data_type::f32:
+ case data_type::s32:
+ vmovups(dst_addr, vreg_dst_);
+ break;
+ default: assert(!"unimplemented");
+ }
+ };
+
+ // Advance all pointers by an immediate
+ auto advance_ptrs_imm = [&](size_t offset) {
+ add(reg_dst, offset * sizeof(dst_data_t));
+ add(reg_acc, offset * sizeof(acc_data_t));
+ if (scale_idx_mult_) {
+ assert(scale_idx_mult_ == 1);
+ add(reg_scales, offset * sizeof(float));
+ }
+ if (do_bias_)
+ add(reg_bias, offset * bias_data_type_size_);
+ };
+
+ // Advance all pointers by a value stored in a register
+ auto advance_ptrs_reg = [&](Reg64 offset) {
+ lea(reg_dst, ptr[reg_dst + offset * sizeof(dst_data_t)]);
+ lea(reg_acc, ptr[reg_acc + offset * sizeof(acc_data_t)]);
+ if (scale_idx_mult_) {
+ assert(scale_idx_mult_ == 1);
+ lea(reg_scales, ptr[reg_scales + offset * sizeof(float)]);
+ }
+ if (do_bias_)
+ lea(reg_bias, ptr[reg_bias + offset * bias_data_type_size_]);
+ };
+
+ // Rewind pointers that point to data that is indexed by output channel
+ // (bias or per-oc scaling factors)
+ auto rewind_ptrs = [&]() {
+ if (do_bias_)
+ sub(reg_bias, OC_ * bias_data_type_size_);
+ if (scale_idx_mult_) {
+ assert(scale_idx_mult_ == 1);
+ sub(reg_scales, OC_ * sizeof(float));
+ }
+ add(reg_dst, (dst_os_stride_ - OC_) * sizeof(dst_data_t));
+ };
+
+ // <--------- OC --------------->
+ //
+ // ^ ................+..............+-------------+.......................
+ // | . : not accessed |Prologue loop| .
+ // | . +--------------+-------------+ .
+ // . | | .
+ // O . | Main loop (unrolled) | .
+ // S . | | .
+ // . +--------------+-------------+ .
+ // | . | Epilogue loop|not accessed : .
+ // v ................+--------------+.............+.......................
+
+ Label prologue_end;
+ cmp(reg_oc_offset, 0);
+ je(prologue_end, T_NEAR);
+
+ // Prologue loop
+ {
+ mov(reg_tmp, OC_);
+ sub(reg_tmp, reg_oc_offset);
+ cmp(reg_tmp, reg_len);
+ cmovg(reg_tmp, reg_len);
+ sub(reg_len, reg_tmp);
+
+ Label prologue_loop, prologue_loop_tail, prologue_loop_end;
+ cmp(reg_tmp, vlen);
+ jle(prologue_loop_tail, T_NEAR);
+ L(prologue_loop); {
+ compute(0, 0, false);
+ advance_ptrs_imm(vlen);
+ sub(reg_tmp, vlen);
+ cmp(reg_tmp, vlen);
+ jge(prologue_loop, T_NEAR);
+ }
+
+ L(prologue_loop_tail);
+ mov(reg_rem_mask_short, 1);
+ // cl == reg_tmp because reg_tmp <= vlen here
+ shl(reg_rem_mask_short, cl);
+ sub(reg_rem_mask_short, 1);
+ jz(prologue_loop_end, T_NEAR);
+
+ kmovq(kreg_rem_mask_short, reg_rem_mask_short);
+ compute(0, 0, true);
+ advance_ptrs_reg(reg_tmp);
+
+ L(prologue_loop_end);
+ rewind_ptrs();
+ }
+ L(prologue_end);
+
+ // Main loop
+ Label main_loop_end;
+ {
+ cmp(reg_len, OC_);
+ jle(main_loop_end, T_NEAR);
+
+ Label main_loop;
+ L(main_loop); {
+ size_t OC_loop, OC_tail;
+ if (OC_ < max_unroll * vlen) {
+ // Fully unroll small loops
+ OC_loop = 0;
+ OC_tail = OC_;
+ }
+ else {
+ OC_loop = vlen * def_unroll;
+ OC_tail = OC_ % OC_loop;
+ }
+
+ assert(!!OC_loop || !!OC_tail);
+
+ if (OC_tail % vlen) {
+ int vlen_tail = OC_tail % vlen;
+ unsigned tail_mask = (1 << vlen_tail) - 1;
+ mov(reg_tmp, tail_mask);
+ kmovq(kreg_rem_mask_short, reg_tmp);
+ }
+
+ if (OC_loop) {
+ mov(reg_tmp, rnd_dn(OC_, OC_loop));
+ Label oc_loop;
+ L(oc_loop); {
+ for (size_t offset = 0; offset < OC_loop; offset += vlen)
+ compute(offset, offset / vlen, false);
+ advance_ptrs_imm(OC_loop);
+ sub(reg_tmp, OC_loop);
+ jnz(oc_loop);
+ }
+ }
+
+ if (OC_tail) {
+ for (size_t offset = 0; offset < OC_tail; offset += vlen) {
+ bool use_mask = (offset + vlen) > OC_tail;
+ compute(offset, offset / vlen, use_mask);
+ }
+ advance_ptrs_imm(OC_tail);
+ }
+
+ rewind_ptrs();
+ sub(reg_len, OC_);
+ cmp(reg_len, OC_);
+ jge(main_loop, T_NEAR);
+ }
+ }
+ L(main_loop_end);
+
+ // Epilogue loop
+ Label epilogue_end;
+ {
+ cmp(reg_len, 0);
+ je(epilogue_end, T_NEAR);
+
+ Label epilogue_loop, epilogue_loop_tail;
+ cmp(reg_len, vlen);
+ jle(epilogue_loop_tail, T_NEAR);
+ L(epilogue_loop); {
+ compute(0, 0, false);
+ sub(reg_len, vlen);
+ advance_ptrs_imm(vlen);
+ cmp(reg_len, vlen);
+ jge(epilogue_loop, T_NEAR);
+ }
+
+ L(epilogue_loop_tail);
+ mov(reg_tmp, reg_len); // reg_tmp is rcx, and we need cl for the shift
+ mov(reg_rem_mask_short, 1);
+ shl(reg_rem_mask_short, cl); // reg_tmp == rcx and reg_tail < vlen
+ sub(reg_rem_mask_short, 1);
+ jz(epilogue_end, T_NEAR);
+ kmovq(kreg_rem_mask_short, reg_rem_mask_short);
+ compute(0, 0, true);
+ }
+
+ L(epilogue_end);
+
+ postamble();
+
+ ker_ = getCode<decltype(ker_)>();
+}
+
+template <data_type_t src_type, data_type_t dst_type>
+void _gemm_x8s8s32x_convolution_fwd_t<src_type, dst_type>::pp_ker_t::operator ()
+ (dst_data_t *dst, const acc_data_t *acc, const char *bias,
+ const float *scales, float nslope, float sum_scale, float signed_scale,
+ int g, size_t start, size_t end)
+{
+ using math::get_bias;
+
+ if (end <= start)
+ return;
+
+ if (ker_) {
+ // JIT
+ ker_args args;
+ size_t oc_offset = start % OC_;
+ size_t os_offset = start / OC_;
+ args.acc = acc + start;
+ args.dst = dst + os_offset * dst_os_stride_ + oc_offset;
+ args.bias = bias + (g * jcp_.oc + oc_offset) * bias_data_type_size_;
+ args.scales = scales + scale_idx_mult_ * (g * jcp_.oc + oc_offset);
+ args.nslope = nslope;
+ args.sum_scale = sum_scale;
+ args.signed_scale = signed_scale;
+ args.len = end - start;
+ args.oc_offset = oc_offset;
+ ker_(&args);
+ }
+ else {
+ // Fallback
+ const size_t first_oc = start % OC_;
+ const size_t last_oc = (end - 1) % OC_;
+ const size_t first_os = start / OC_;
+ const size_t last_os = (end - 1) / OC_;
+ for (size_t os = first_os; os <= last_os; os++) {
+ const size_t start_oc = (os == first_os) ? first_oc : 0;
+ const size_t end_oc = (os == last_os) ? last_oc : OC_ - 1;
+ for (size_t oc = start_oc; oc <= end_oc; oc++) {
+ const size_t acc_off = os * jcp_.oc + oc;
+ const size_t dst_off = os * dst_os_stride_ + oc;
+
+ float d = (float)(acc[acc_off]);
+ if (jcp_.signed_input)
+ d *= signed_scale;
+
+ if (do_bias_)
+ d += get_bias(bias, g * jcp_.oc + oc,
+ bias_data_type_);
+
+ d *= scales[(g * jcp_.oc + oc) * scale_idx_mult_];
+ if (do_sum_)
+ d += sum_scale * dst[dst_off];
+ if (do_relu_ && d < 0)
+ d *= nslope;
+ dst[dst_off] = qz_a1b0<float, dst_data_t>()(d);
+ }
+ }
+ }
+};
+
+template <data_type_t src_type, data_type_t dst_type>
+void _gemm_x8s8s32x_convolution_fwd_t<src_type, dst_type>::
+execute_forward_thr(const int ithr, const int nthr, const src_data_t *src_base,
+ const wei_data_t *wei_base, const char *bia_base, dst_data_t *dst_base,
+ const memory_tracking::grantor_t &scratchpad) const {
+ const jit_gemm_conv_conf_t &jcp = this->pd()->jcp_;
+
+ const auto src_md = memory_desc_wrapper(pd()->src_md());
+ const size_t src_mb_stride = src_md.blk_off(1);
+ const size_t src_g_stride = src_md.blk_off(0, 1) * jcp.ic;
+
+ const auto wei_md = memory_desc_wrapper(pd()->weights_md(0));
+ const size_t wei_g_stride = pd()->with_groups() ? wei_md.blk_off(1) : 0;
+
+ const auto dst_md = memory_desc_wrapper(pd()->dst_md());
+ const size_t dst_mb_stride = dst_md.blk_off(1);
+ const size_t dst_g_stride = dst_md.blk_off(0, 1) * jcp.oc;
+
+ const float *scales = pd()->attr()->output_scales_.scales_;
+
+ const auto &post_ops = pd()->attr()->post_ops_;
+ const bool do_sum = post_ops.contain(primitive_kind::sum, 0);
+ const float sum_scale = do_sum ? post_ops.entry_[0].sum.scale : 0;
+
+ float nslope = 0;
+ for (int idx = 0; idx < post_ops.len_; ++idx) {
+ const auto &e = post_ops.entry_[idx];
+ if (e.is_relu(true, false)) {
+ nslope = e.eltwise.alpha;
+ break;
+ }
+ }
+
+ auto col = scratchpad.get<uint8_t>(key_conv_gemm_col)
+ + (ptrdiff_t)ithr * jcp.im2col_sz;
+ src_data_t *__restrict imtr = scratchpad.get<src_data_t>(key_conv_gemm_imtr)
+ + (ptrdiff_t)ithr * jcp.is * jcp.ic;
+ auto acc = scratchpad.get<acc_data_t>(key_conv_int_dat_in_acc_dt)
+ + (ptrdiff_t)ithr * jcp.oh_block * jcp.ow_block * jcp.oc;
+
+ const ptrdiff_t offset = (ptrdiff_t)jcp.ngroups * jcp.ks * jcp.ic * jcp.oc;
+ const int32_t *_wei_comp = (const int32_t *)(wei_base + offset);
+
+ int g{ 0 }, n{ 0 }, ohb{ 0 }, owb{ 0 };
+ size_t start = 0, end = 0;
+
+ const int nb_oh = div_up(jcp.oh, jcp.oh_block);
+ const int nb_ow = div_up(jcp.ow, jcp.ow_block);
+ const size_t work_amount = jcp.ngroups * jcp.mb * nb_oh * nb_ow;
+ balance211(work_amount, nthr, ithr, start, end);
+ nd_iterator_init(start, n, jcp.mb, g, jcp.ngroups, ohb,
+ nb_oh, owb, nb_ow);
+
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ int oh = ohb * jcp.oh_block;
+ int ow = owb * jcp.ow_block;
+ const src_data_t *__restrict src = src_base + n * src_mb_stride
+ + g * src_g_stride;
+ const wei_data_t *__restrict wei = wei_base + g * wei_g_stride;
+ dst_data_t *__restrict dst =
+ dst_base + n * dst_mb_stride + g * dst_g_stride;
+ const int32_t *wei_comp = _wei_comp + g * jcp.oc;
+ const int h_step = nstl::min(jcp.oh_block, jcp.oh - oh);
+ const int w_step = nstl::min(jcp.ow_block, jcp.ow - ow);
+
+ if (jcp.im2col_sz)
+ jit_gemm_convolution_utils::im2col_u8<src_data_t>(
+ jcp, src, imtr, col, oh, h_step, ow, w_step);
+
+ const int M = jcp.oc;
+ const int K = jcp.ks * jcp.ic;
+ const int N = h_step * w_step;
+ const int LDA = M * jcp.ngroups;
+ const int LDB = jcp.im2col_sz ? N : K;
+ const char *BT = jcp.im2col_sz ? "T" : "N";
+ const int8_t off_a = 0, off_b = 0;
+ const int32_t off_c = 0;
+ const float onef = 1.0, zerof = 0.0;
+ gemm_s8x8s32("N", BT, jcp.signed_input ? "C" : "F",
+ &M, &N, &K, &onef, wei, &LDA, &off_a,
+ jcp.im2col_sz ? col : (uint8_t *)src, &LDB, &off_b,
+ &zerof, acc, &M, jcp.signed_input ? wei_comp : &off_c);
+
+ auto wei_adj_scale =
+ (wei_md.extra().flags | memory_extra_flags::scale_adjust)
+ ? wei_md.extra().scale_adjust : 1.f;
+
+ parallel(0, [&](int ithr, int nthr) {
+ size_t start, end;
+ balance211((size_t)N * jcp.oc, nthr, ithr, start, end);
+ (*pp_ker_)(dst + (oh * jcp.ow + ow) * pp_ker_->dst_os_stride_,
+ acc, bia_base, scales, nslope, sum_scale,
+ 1.f / wei_adj_scale, g, start, end);
+ });
+
+ nd_iterator_step(n, jcp.mb, g, jcp.ngroups, ohb, nb_oh,
+ owb, nb_ow);
+ }
+}
+
+template <data_type_t dst_type>
+void _gemm_u8s8s32x_convolution_bwd_data_t<dst_type>::
+execute_backward_data(const exec_ctx_t &ctx) const {
+ auto diff_dst_base = CTX_IN_MEM(const diff_dst_data_t *, MKLDNN_ARG_DIFF_DST);
+ auto wei_base = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bia_base = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto diff_src_base = CTX_OUT_MEM(diff_src_data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ auto scratchpad = this->scratchpad(ctx);
+
+ const jit_gemm_conv_conf_t &jcp = this->pd()->jcp_;
+
+ parallel(jcp.nthr, [&](const int ithr, const int nthr) {
+ execute_backward_data_thr(ithr, nthr, diff_dst_base, wei_base,
+ bia_base, diff_src_base, scratchpad);
+ });
+}
+
+template <data_type_t dst_type>
+void _gemm_u8s8s32x_convolution_bwd_data_t<dst_type>::
+execute_backward_data_thr(const int ithr, const int nthr,
+ const diff_dst_data_t *diff_dst_base, const wei_data_t *wei_base,
+ const char *bia_base, diff_src_data_t *diff_src_base,
+ const memory_tracking::grantor_t &scratchpad) const
+{
+ const jit_gemm_conv_conf_t &jcp = this->pd()->jcp_;
+
+ const auto diff_dst_md = memory_desc_wrapper(pd()->diff_dst_md());
+ const size_t diff_dst_mb_stride = diff_dst_md.blk_off(1);
+ const size_t diff_dst_g_stride = diff_dst_md.blk_off(0, 1) * jcp.oc;
+
+ const auto wei_md = memory_desc_wrapper(pd()->weights_md(0));
+ const size_t wei_g_stride = pd()->with_groups() ? wei_md.blk_off(1) : 0;
+
+ const auto diff_src_md = memory_desc_wrapper(pd()->diff_src_md());
+ const size_t diff_src_mb_stride = diff_src_md.blk_off(1);
+ const size_t diff_src_g_stride = diff_src_md.blk_off(0, 1) * jcp.ic;
+ const size_t diff_src_os_stride = diff_src_md.blk_off(0, 0, 0, 1);
+
+ /* scale_idx_mult = 1 for per_oc scales and 0, otherwise */
+ const int scale_idx_mult = pd()->attr()->output_scales_.mask_ == (1 << 1);
+ const float *scales = pd()->attr()->output_scales_.scales_;
+ const size_t work_amount = jcp.ngroups * jcp.mb;
+
+ auto col = scratchpad.get<acc_data_t>(key_conv_gemm_col)
+ + (ptrdiff_t)ithr * jcp.im2col_sz;
+ auto acc = scratchpad.get<acc_data_t>(key_conv_int_dat_in_acc_dt)
+ + (ptrdiff_t)ithr * jcp.is * jcp.ic;
+
+ int n{0}, g{0};
+ size_t start = 0, end = 0;
+
+ balance211(work_amount, nthr, ithr, start, end);
+ nd_iterator_init(start, n, jcp.mb, g, jcp.ngroups);
+
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ const diff_dst_data_t *diff_dst = diff_dst_base
+ + n * diff_dst_mb_stride + g * diff_dst_g_stride;
+ const wei_data_t *wei = wei_base + g * wei_g_stride;
+ diff_src_data_t *diff_src = diff_src_base + n * diff_src_mb_stride
+ + g * diff_src_g_stride;
+
+ const int M = jcp.ks * jcp.ic;
+ const int N = jcp.os;
+ const int K = jcp.oc;
+ const int8_t off_a = 0, off_b = 0;
+ const int32_t off_c = 0;
+ const float onef = 1.0, zerof = 0.0;
+ const int LD = K * jcp.ngroups;
+
+ gemm_s8x8s32("T", "N", "F", &M, &N, &K, &onef,
+ wei, &LD, &off_a, diff_dst, &LD, &off_b,
+ &zerof, jcp.im2col_sz ? col : acc, &M, &off_c);
+
+ if (jcp.im2col_sz)
+ jit_gemm_convolution_utils::col2im_s32(jcp, col, acc);
+
+ parallel_nd(jcp.is, jcp.ic, [&](int is, int ic) {
+ float d = (float)acc[is * jcp.ic + ic];
+ if (jcp.with_bias)
+ d += get_bias(bia_base, g * jcp.ic + ic,
+ pd()->desc()->bias_desc.data_type);
+ d *= scales[(g * jcp.ic + ic) * scale_idx_mult];
+ const size_t diff_src_off = is * diff_src_os_stride + ic;
+ diff_src[diff_src_off] =
+ qz_a1b0<float, diff_src_data_t>()(d);
+ });
+ nd_iterator_step(n, jcp.mb, g, jcp.ngroups);
+ }
+}
+
+using namespace data_type;
+
+template struct _gemm_x8s8s32x_convolution_fwd_t<u8, f32>;
+template struct _gemm_x8s8s32x_convolution_fwd_t<u8, s32>;
+template struct _gemm_x8s8s32x_convolution_fwd_t<u8, s8>;
+template struct _gemm_x8s8s32x_convolution_fwd_t<u8, u8>;
+
+template struct _gemm_x8s8s32x_convolution_fwd_t<s8, f32>;
+template struct _gemm_x8s8s32x_convolution_fwd_t<s8, s32>;
+template struct _gemm_x8s8s32x_convolution_fwd_t<s8, s8>;
+template struct _gemm_x8s8s32x_convolution_fwd_t<s8, u8>;
+
+template struct _gemm_u8s8s32x_convolution_bwd_data_t<f32>;
+template struct _gemm_u8s8s32x_convolution_bwd_data_t<s32>;
+template struct _gemm_u8s8s32x_convolution_bwd_data_t<s8>;
+template struct _gemm_u8s8s32x_convolution_bwd_data_t<u8>;
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_convolution.hpp
new file mode 100644
index 0000000000..9e77b890d5
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_convolution.hpp
@@ -0,0 +1,266 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef GEMM_X8S8S32X_CONVOLUTION_HPP
+#define GEMM_X8S8S32X_CONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "jit_primitive_conf.hpp"
+#include "jit_generator.hpp"
+#include "gemm_convolution_utils.hpp"
+
+#include "gemm/gemm.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <data_type_t src_type, data_type_t dst_type>
+struct _gemm_x8s8s32x_convolution_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(IGEMM_S8U8S32_IMPL_STR,
+ _gemm_x8s8s32x_convolution_fwd_t<src_type, dst_type>);
+
+ status_t init() {
+ using namespace data_type;
+
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(src_type, s8, data_type::undef, dst_type,
+ s32)
+ && IMPLICATION(with_bias(), utils::one_of(
+ desc()->bias_desc.data_type, f32, s32, s8, u8))
+ && !has_zero_dim_memory()
+ && set_default_formats_common(
+ dat_tag(), format_tag::any, dat_tag())
+ && post_ops_ok()
+ && memory_desc_matches_tag(*src_md(), dat_tag())
+ && memory_desc_matches_tag(*dst_md(), dat_tag())
+ && set_or_check_wei_format();
+ if (!ok) return status::unimplemented;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ return jit_gemm_convolution_utils::init_conf(jcp_, scratchpad,
+ *desc(), src_md(), weights_md(0), dst_md(),
+ mkldnn_get_max_threads());
+ }
+
+ jit_gemm_conv_conf_t jcp_;
+
+ protected:
+ format_tag_t dat_tag() const { return format_tag::nhwc; }
+
+ bool set_or_check_wei_format() {
+ using namespace format_tag;
+
+ const bool is_src_s8 = src_md_.data_type == data_type::s8;
+
+ memory_desc_t want_wei_md = weights_md_;
+ memory_desc_init_by_tag(want_wei_md, with_groups() ? hwigo : hwio);
+
+ if (is_src_s8) {
+ want_wei_md.extra.flags = 0
+ | memory_extra_flags::compensation_conv_s8s8
+ | memory_extra_flags::scale_adjust;
+ want_wei_md.extra.compensation_mask = (1 << 0)
+ + (with_groups() ? (1 << 1) : 0);
+ want_wei_md.extra.scale_adjust =
+ mayiuse(avx512_core_vnni) ? 1.f : 0.5f;
+ }
+
+ if (weights_md_.format_kind == format_kind::any) {
+ weights_md_ = want_wei_md;
+ return true;
+ }
+
+ return weights_md_ == want_wei_md;
+ }
+
+ bool post_ops_ok() const {
+ using namespace mkldnn::impl::primitive_kind;
+ auto const &po = attr()->post_ops_;
+ auto is_relu = [&](int idx) {
+ return po.entry_[idx].is_relu(true, false); };
+
+ switch (po.len_) {
+ case 0: return true;
+ case 1: return is_relu(0) || po.contain(sum, 0);
+ case 2: return po.contain(sum, 0) && is_relu(1);
+ default: return false;
+ }
+ return false;
+ }
+ };
+
+ _gemm_x8s8s32x_convolution_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd, true), pp_ker_(nullptr)
+ { pp_ker_ = new pp_ker_t(pd()); }
+ ~_gemm_x8s8s32x_convolution_fwd_t() { delete pp_ker_; }
+
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<data_type::s8>::type wei_data_t;
+ typedef typename prec_traits<dst_type>::type dst_data_t;
+ typedef typename prec_traits<data_type::s32>::type acc_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ // XXX: this is throwaway code that will become unnecessary when we have a
+ // sufficiently advanced igemm jit generator that supports quantization,
+ // relu, and whatnot
+ class pp_ker_t : jit_generator {
+ public:
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(
+ _gemm_x8s8s32x_convolution_fwd_t::pp_kernel);
+ pp_ker_t(const pd_t *pd);
+
+ void operator()(dst_data_t *dst, const acc_data_t *acc,
+ const char *bias, const float *scales,
+ float nslope, float sum_scale, float signed_scale,
+ int g, size_t start, size_t end);
+
+ size_t dst_os_stride_;
+
+ private:
+ void generate();
+
+ struct ker_args {
+ dst_data_t *dst;
+ const acc_data_t *acc;
+ const char *bias;
+ const float *scales;
+ float nslope;
+ float sum_scale;
+ float signed_scale;
+ size_t len;
+ size_t oc_offset;
+ };
+ void(*ker_)(const ker_args *args);
+
+ const jit_gemm_conv_conf_t &jcp_;
+ size_t OC_;
+ size_t OS_;
+ data_type_t bias_data_type_;
+ size_t bias_data_type_size_;
+ size_t scale_idx_mult_;
+ bool do_bias_;
+ bool do_relu_;
+ bool do_sum_;
+ bool do_signed_scaling_;
+ size_t vlen_;
+ };
+
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ void execute_forward(const exec_ctx_t &ctx) const;
+ void execute_forward_thr(const int ithr, const int nthr,
+ const src_data_t *src_base, const wei_data_t *wei_base,
+ const char *bia_base, dst_data_t *dst_base,
+ const memory_tracking::grantor_t &scratchpad) const;
+
+ int nthr_;
+ pp_ker_t *pp_ker_;
+
+};
+
+template <data_type_t dst_type>
+struct _gemm_u8s8s32x_convolution_bwd_data_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_data_pd_t{
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc, const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_data_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(IGEMM_S8U8S32_IMPL_STR,
+ _gemm_u8s8s32x_convolution_bwd_data_t<dst_type>);
+
+ status_t init() {
+ using namespace data_type;
+
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_data
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(dst_type, s8, data_type::undef, u8, s32)
+ && IMPLICATION(with_bias(), utils::one_of(
+ desc()->bias_desc.data_type, f32, s32, s8, u8))
+ && !has_zero_dim_memory()
+ && set_default_formats_common(dat_tag(), wei_tag(), dat_tag())
+ && attr()->post_ops_.has_default_values()
+ && memory_desc_matches_tag(*diff_src_md(), dat_tag())
+ && memory_desc_matches_tag(*diff_dst_md(), dat_tag())
+ && memory_desc_matches_tag(*weights_md(), wei_tag());
+ if (!ok) return status::unimplemented;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ return jit_gemm_convolution_utils::init_conf(jcp_, scratchpad,
+ *desc(), diff_src_md(), weights_md(), diff_dst_md(),
+ mkldnn_get_max_threads());
+ }
+
+ virtual bool support_bias() const override { return true; }
+
+ jit_gemm_conv_conf_t jcp_;
+
+ protected:
+ format_tag_t dat_tag() const { return format_tag::nhwc; }
+
+ format_tag_t wei_tag() const {
+ return with_groups() ? format_tag::hwigo : format_tag::hwio;
+ }
+ };
+
+ _gemm_u8s8s32x_convolution_bwd_data_t(const pd_t *apd)
+ : cpu_primitive_t(apd, true) {}
+
+ typedef typename prec_traits<data_type::u8>::type diff_dst_data_t;
+ typedef typename prec_traits<data_type::s8>::type wei_data_t;
+ typedef typename prec_traits<dst_type>::type diff_src_data_t;
+ typedef typename prec_traits<data_type::s32>::type acc_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_data(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_data(const exec_ctx_t &ctx) const;
+ void execute_backward_data_thr(const int ithr, const int nthr,
+ const diff_dst_data_t *diff_dst_base, const wei_data_t *wei_base,
+ const char *bia_base, diff_src_data_t *diff_src_base,
+ const memory_tracking::grantor_t &scratchpad) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_inner_product.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_inner_product.cpp
new file mode 100644
index 0000000000..1e435a233a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_inner_product.cpp
@@ -0,0 +1,453 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+#include "simple_q10n.hpp"
+
+#include "gemm/gemm.hpp"
+#include "gemm_x8s8s32x_inner_product.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace math;
+using namespace format_tag;
+using namespace memory_tracking::names;
+
+template<data_type_t src_type, data_type_t dst_type>
+gemm_x8s8s32x_inner_product_fwd_t<src_type, dst_type>::pp_kernel_t::pp_kernel_t(
+ const pd_t *pd, bool dst_is_acc)
+ : ker_(nullptr), OC_(pd->OC())
+ , bias_data_type_(data_type::undef), bias_data_type_size_(0)
+ , scale_idx_mult_(0), do_bias_(false), do_relu_(false)
+{
+ using namespace types;
+
+ scale_idx_mult_ = (pd->attr()->output_scales_.mask_ == (1 << 1));
+
+ auto &post_ops = pd->attr()->post_ops_;
+ do_relu_ = post_ops.len_ == 1;
+ do_bias_ = pd->with_bias();
+ bias_data_type_ = pd->desc()->bias_desc.data_type;
+ if (do_bias_) {
+ assert(bias_data_type_ != data_type::undef);
+ bias_data_type_size_ = data_type_size(bias_data_type_);
+ }
+
+ if (!mayiuse(avx512_core))
+ // use fallback code for older CPUs since they do not have optimized
+ // x8s8s32 GEMM anyways. The configuration variables above are used by
+ // the fallback code.
+ return;
+ else
+ generate();
+}
+
+template<data_type_t src_type, data_type_t dst_type>
+void gemm_x8s8s32x_inner_product_fwd_t<src_type, dst_type>::pp_kernel_t::generate()
+{
+ using namespace Xbyak;
+ using namespace utils;
+
+ // TODO: clean-up
+ Reg64 reg_param = abi_param1;
+ Reg64 reg_dst = rdx;
+ Reg64 reg_acc = rax;
+ Reg64 reg_bias = rbx;
+ Reg64 reg_scales = rsi;
+
+ Reg64 reg_len = r8;
+ Reg64 reg_tmp = rcx; // intentional for shifting purposes
+ Reg64 reg_oc_offset = r9;
+ Reg64 reg_rem_mask = r10;
+ Opmask kreg_rem_mask = k1;
+ Opmask kreg_relu_cmp = k2;
+
+ const size_t vlen = cpu_isa_traits<avx512_common>::vlen / sizeof(float);
+
+ Zmm vreg_zero = Zmm(0);
+ Zmm vreg_scale = Zmm(1);
+ Zmm vreg_nslope = Zmm(2);
+
+ auto vreg_dst = [&](int idx) { return Zmm(3 + idx * 2 + 0); };
+ auto vreg_bias = [&](int idx) { return Zmm(3 + idx * 2 + 1); };
+
+ preamble();
+
+#define PARAM_OFF(x) offsetof(ker_args, x)
+ mov(reg_dst, ptr[reg_param + PARAM_OFF(dst)]);
+ mov(reg_acc, ptr[reg_param + PARAM_OFF(acc)]);
+ mov(reg_bias, ptr[reg_param + PARAM_OFF(bias)]);
+ mov(reg_scales, ptr[reg_param + PARAM_OFF(scales)]);
+ mov(reg_len, ptr[reg_param + PARAM_OFF(len)]);
+ mov(reg_oc_offset, ptr[reg_param + PARAM_OFF(oc_offset)]);
+ vbroadcastss(vreg_nslope, ptr[reg_param + PARAM_OFF(nslope)]);
+ if (scale_idx_mult_ == 0)
+ vbroadcastss(vreg_scale, dword[reg_scales]);
+#undef PARAM_OFF
+
+ if (do_relu_ || dst_type == data_type::u8)
+ vxorps(vreg_zero, vreg_zero, vreg_zero);
+
+ // Load accumulated value, convert to float, apply bias (if any), scaling,
+ // and relu (if any); then convert to destination type and store
+ auto compute = [&](size_t offset, int idx, bool apply_mask) {
+ auto acc_addr = ptr[reg_acc + offset * sizeof(acc_data_t)];
+
+ if (scale_idx_mult_ > 0) {
+ assert(scale_idx_mult_ == 1);
+ auto scale_addr = ptr[reg_scales + offset * sizeof(float)];
+ auto vreg_scale_ = vreg_scale;
+ if (apply_mask)
+ vreg_scale_ = vreg_scale_ | kreg_rem_mask;
+ vmovups(vreg_scale, scale_addr);
+ }
+
+ auto vreg_dst_ = vreg_dst(idx);
+ if (apply_mask)
+ vreg_dst_ = vreg_dst_ | kreg_rem_mask;
+ vcvtdq2ps(vreg_dst_, acc_addr);
+
+ if (do_bias_) {
+ auto bias_addr = ptr[reg_bias + offset * bias_data_type_size_];
+ auto vreg_bias_ = vreg_bias(idx);
+ if (apply_mask)
+ vreg_bias_ = vreg_bias_ | kreg_rem_mask;
+
+ switch (bias_data_type_) {
+ case data_type::s8:
+ vpmovsxbd(vreg_bias_, bias_addr);
+ break;
+ case data_type::u8:
+ vpmovzxbd(vreg_bias_, bias_addr);
+ break;
+ case data_type::s32:
+ case data_type::f32:
+ vmovups(vreg_bias_, bias_addr);
+ break;
+ default: assert(!"unimplemented");
+ }
+ if (bias_data_type_ != data_type::f32)
+ vcvtdq2ps(vreg_bias(idx), vreg_bias(idx));
+ vaddps(vreg_dst(idx), vreg_dst(idx), vreg_bias(idx));
+ }
+
+ vmulps(vreg_dst(idx), vreg_dst(idx), vreg_scale);
+ if (do_relu_) {
+ vcmpps(kreg_relu_cmp, vreg_dst(idx), vreg_zero, _cmp_lt_os);
+ vmulps(vreg_dst(idx) | kreg_relu_cmp, vreg_dst(idx), vreg_nslope);
+ }
+
+ if (dst_type == data_type::u8)
+ vmaxps(vreg_dst(idx), vreg_dst(idx), vreg_zero);
+
+ if (dst_type != data_type::f32) {
+ vcvtps2dq(vreg_dst(idx), vreg_dst(idx));
+ }
+
+ auto dst_addr = ptr[reg_dst + offset * sizeof(dst_data_t)];
+ switch (dst_type) {
+ case data_type::s8:
+ vpmovsdb(dst_addr, vreg_dst_);
+ break;
+ case data_type::u8:
+ vpmovusdb(dst_addr, vreg_dst_);
+ break;
+ case data_type::f32:
+ case data_type::s32:
+ vmovups(dst_addr, vreg_dst_);
+ break;
+ default: assert(!"unimplemented");
+ }
+ };
+
+ // Advance all pointers by an immediate
+ auto advance_ptrs_imm = [&](size_t offset) {
+ add(reg_dst, offset * sizeof(dst_data_t));
+ add(reg_acc, offset * sizeof(acc_data_t));
+ if (scale_idx_mult_) {
+ assert(scale_idx_mult_ == 1);
+ add(reg_scales, offset * sizeof(float));
+ }
+ if (do_bias_)
+ add(reg_bias, offset * bias_data_type_size_);
+ };
+
+ // Advance all pointers by a value stored in a register
+ auto advance_ptrs_reg = [&](Reg64 offset) {
+ lea(reg_dst, ptr[reg_dst + offset * sizeof(dst_data_t)]);
+ lea(reg_acc, ptr[reg_acc + offset * sizeof(acc_data_t)]);
+ if (scale_idx_mult_) {
+ assert(scale_idx_mult_ == 1);
+ lea(reg_scales, ptr[reg_scales + offset * sizeof(float)]);
+ }
+ if (do_bias_)
+ lea(reg_bias, ptr[reg_bias + offset * bias_data_type_size_]);
+ };
+
+ // Rewind pointers that point to data that is indixed by output channel
+ // (bias or per-oc scaling factors)
+ auto rewind_ptrs = [&]() {
+ if (do_bias_)
+ sub(reg_bias, OC_ * bias_data_type_size_);
+ if (scale_idx_mult_) {
+ assert(scale_idx_mult_ == 1);
+ sub(reg_scales, OC_ * sizeof(float));
+ }
+ };
+
+ // <-------------------- OC ------------------------------->
+ //
+ // ^ +....................+----------------------------------+
+ // | : not accessed | Prologue loop |
+ // | +--------------------+----------------------------------+
+ // | |
+ // M | Main loop (unrolled) |
+ // B | |
+ // +--------------------------------+----------------------+
+ // | | Epilogue loop | not accessed :
+ // v +--------------------------------+......................+
+
+ Label prologue_end;
+ cmp(reg_oc_offset, 0);
+ je(prologue_end, T_NEAR);
+
+ // Prologue loop
+ {
+ mov(reg_tmp, OC_);
+ sub(reg_tmp, reg_oc_offset);
+ cmp(reg_tmp, reg_len);
+ cmovg(reg_tmp, reg_len);
+ sub(reg_len, reg_tmp);
+
+ Label prologue_loop, prologue_loop_tail, prologue_loop_end;
+ cmp(reg_tmp, vlen);
+ jle(prologue_loop_tail, T_NEAR); // Skips for reg_tmp == 16 too (?)
+ L(prologue_loop); {
+ compute(0, 0, false);
+ advance_ptrs_imm(vlen);
+ sub(reg_tmp, vlen);
+ cmp(reg_tmp, vlen);
+ jge(prologue_loop, T_NEAR);
+ }
+
+ L(prologue_loop_tail);
+ mov(reg_rem_mask, 1);
+ shl(reg_rem_mask, cl); // cl == reg_tmp because reg_tmp <= vlen here
+ sub(reg_rem_mask, 1);
+ jz(prologue_loop_end, T_NEAR);
+
+ kmovq(kreg_rem_mask, reg_rem_mask);
+ compute(0, 0, true);
+ advance_ptrs_reg(reg_tmp);
+
+ L(prologue_loop_end);
+ rewind_ptrs();
+ }
+ L(prologue_end);
+
+ // Main loop
+ Label main_loop_end;
+ {
+ cmp(reg_len, OC_);
+ jle(main_loop_end, T_NEAR);
+
+ Label main_loop;
+ L(main_loop); {
+ size_t def_unroll = 4;
+ size_t max_unroll = 13;
+
+ size_t OC_loop, OC_tail;
+ if (OC_ < max_unroll * vlen) {
+ // Fully unroll small loops
+ OC_loop = 0;
+ OC_tail = OC_;
+ } else {
+ OC_loop = vlen * def_unroll;
+ OC_tail = OC_ % OC_loop;
+ }
+
+ assert(!!OC_loop || !!OC_tail);
+
+ if (OC_tail % vlen) {
+ int vlen_tail = OC_tail % vlen;
+ unsigned tail_mask = (1 << vlen_tail) - 1;
+ mov(reg_tmp, tail_mask);
+ kmovq(kreg_rem_mask, reg_tmp);
+ }
+
+ if (OC_loop) {
+ mov(reg_tmp, rnd_dn(OC_, OC_loop));
+ Label oc_loop;
+ L(oc_loop); {
+ for (size_t offset = 0; offset < OC_loop; offset += vlen)
+ compute(offset, offset / vlen, false);
+ advance_ptrs_imm(OC_loop);
+ sub(reg_tmp, OC_loop);
+ jnz(oc_loop);
+ }
+ }
+
+ if (OC_tail) {
+ for (size_t offset = 0; offset < OC_tail; offset += vlen) {
+ bool use_mask = (offset + vlen) > OC_tail;
+ compute(offset, offset / vlen, use_mask);
+ }
+ advance_ptrs_imm(OC_tail);
+ }
+
+ rewind_ptrs();
+ sub(reg_len, OC_);
+ cmp(reg_len, OC_);
+ jge(main_loop, T_NEAR);
+ }
+ }
+ L(main_loop_end);
+
+ // Epilogue loop
+ Label epilogue_end;
+ {
+ cmp(reg_len, 0);
+ je(epilogue_end, T_NEAR);
+
+ Label epilogue_loop, epilogue_loop_tail;
+ cmp(reg_len, vlen);
+ jle(epilogue_loop_tail, T_NEAR); // Skips for reg_len == 16 (?)
+ L(epilogue_loop); {
+ compute(0, 0, false);
+ sub(reg_len, vlen);
+ advance_ptrs_imm(vlen);
+ cmp(reg_len, vlen);
+ jge(epilogue_loop, T_NEAR);
+ }
+
+ L(epilogue_loop_tail);
+ mov(reg_tmp, reg_len); // reg_tmp is rcx, and we need cl for the shift
+ mov(reg_rem_mask, 1);
+ shl(reg_rem_mask, cl); // reg_tmp == rcx and reg_tail < vlen == 16
+ sub(reg_rem_mask, 1);
+ jz(epilogue_end, T_NEAR);
+ kmovq(kreg_rem_mask, reg_rem_mask);
+ compute(0, 0, true);
+ }
+
+ L(epilogue_end);
+
+ postamble();
+
+ ker_ = getCode<decltype(ker_)>();
+}
+
+template<data_type_t src_type, data_type_t dst_type>
+void gemm_x8s8s32x_inner_product_fwd_t<src_type, dst_type>::pp_kernel_t::operator ()(
+ dst_data_t *dst, const acc_data_t *acc,
+ const char *bias, const float *scales, float nslope,
+ size_t start, size_t end)
+{
+ using math::get_bias;
+
+ if (end <= start)
+ return;
+
+ if (ker_) {
+ // JIT
+ ker_args args;
+ size_t oc_offset = start % OC_;
+ args.dst = dst + start;
+ args.acc = acc + start;
+ args.bias = bias + oc_offset * bias_data_type_size_;
+ args.scales = scales + scale_idx_mult_ * oc_offset;
+ args.nslope = nslope;
+ args.len = end - start;
+ args.oc_offset = oc_offset;
+ ker_(&args);
+ } else {
+ // Fallback
+ size_t oc = start % OC_;
+ for (size_t i = start; i < end; i++) {
+ float d = (float)acc[i];
+ float b = get_bias(bias, oc, bias_data_type_);
+ d = d + b;
+ d *= scales[oc * scale_idx_mult_];
+ if (do_relu_ && d < 0)
+ d *= nslope;
+ dst[i] = qz_a1b0<float, dst_data_t>()(d);
+ oc = (oc == OC_ - 1) ? 0 : oc + 1;
+ }
+ }
+};
+
+template <data_type_t src_type, data_type_t dst_type>
+void gemm_x8s8s32x_inner_product_fwd_t<src_type, dst_type>::execute_forward(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ const int MB = pd()->MB();
+ const int OC = pd()->OC();
+
+ bool wei_tr = memory_desc_matches_one_of_tag(
+ *pd()->weights_md(), oiw, oihw, oidhw, oi);
+
+ const int M = OC;
+ const int N = MB;
+ const int K = pd()->IC_total_padded();
+ const int8_t off_a = 0, off_b = 0;
+ const int32_t off_c = 0;
+
+ const float *scales = pd()->attr()->output_scales_.scales_;
+
+ const auto &post_ops = pd()->attr()->post_ops_;
+ const bool do_relu = post_ops.len_ == 1;
+ const float nslope = do_relu ? post_ops.entry_[0].eltwise.alpha : 0.f;
+
+ acc_data_t *acc = pd()->dst_is_acc_
+ ? (acc_data_t *)dst
+ : scratchpad(ctx).template get<acc_data_t>(key_iprod_int_dat_in_acc_dt);
+
+ const float onef = 1.0, zerof = 0.0;
+ gemm_s8x8s32(wei_tr ? "T" : "N", "N", "F", &M, &N, &K, &onef, weights,
+ wei_tr ? &K : &M, &off_a, src, &K, &off_b, &zerof, acc, &M, &off_c);
+
+ if (!pd()->attr()->has_default_values() || !pd()->dst_is_acc_
+ || pd()->with_bias()) {
+ const bool force_sequential = MB * OC < 2000;
+ parallel(force_sequential ? 1 : 0, [&](int ithr, int nthr) {
+ size_t start, end;
+ balance211((size_t)OC * MB, nthr, ithr, start, end);
+ (*pp_kernel_)(dst, acc, bias, scales, nslope, start, end);
+ });
+ }
+}
+
+using namespace data_type;
+
+template struct gemm_x8s8s32x_inner_product_fwd_t<u8, f32>;
+template struct gemm_x8s8s32x_inner_product_fwd_t<u8, s32>;
+template struct gemm_x8s8s32x_inner_product_fwd_t<u8, s8>;
+template struct gemm_x8s8s32x_inner_product_fwd_t<u8, u8>;
+template struct gemm_x8s8s32x_inner_product_fwd_t<s8, f32>;
+template struct gemm_x8s8s32x_inner_product_fwd_t<s8, s32>;
+template struct gemm_x8s8s32x_inner_product_fwd_t<s8, s8>;
+template struct gemm_x8s8s32x_inner_product_fwd_t<s8, u8>;
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_inner_product.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_inner_product.hpp
new file mode 100644
index 0000000000..ac6a5c8f85
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/gemm_x8s8s32x_inner_product.hpp
@@ -0,0 +1,166 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef GEMM_X8S8S32X_INNER_PRODUCT_HPP
+#define GEMM_X8S8S32X_INNER_PRODUCT_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "gemm/gemm.hpp"
+#include "jit_generator.hpp"
+
+#include "cpu_inner_product_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t src_type, impl::data_type_t dst_type>
+struct gemm_x8s8s32x_inner_product_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_inner_product_fwd_pd_t {
+ using cpu_inner_product_fwd_pd_t::cpu_inner_product_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T(src_type == data_type::u8
+ ? IGEMM_S8U8S32_IMPL_STR
+ : IGEMM_S8S8S32_IMPL_STR,
+ gemm_x8s8s32x_inner_product_fwd_t);
+
+ status_t init() {
+ using namespace data_type;
+
+ bool ok = true
+ && set_default_params() == status::success
+ && is_fwd()
+ && !has_zero_dim_memory()
+ && src_md()->data_type == src_type
+ && dst_md()->data_type == dst_type
+ && weights_md()->data_type == s8
+ && IMPLICATION(with_bias(), utils::one_of(
+ weights_md(1)->data_type, f32, s32, s8, u8))
+ && attr()->post_ops_.len_ <= 1
+ && IMPLICATION(attr()->post_ops_.len_,
+ attr()->post_ops_.entry_[0].is_relu(true, false))
+ && dense_gemm_consitency_check(src_md(), weights_md(),
+ dst_md());
+ if (!ok) return status::unimplemented;
+
+ dst_is_acc_ = utils::one_of(dst_type, s32, f32);
+
+ init_scratchpad();
+
+ return status::success;
+ }
+
+ bool dst_is_acc_;
+
+ protected:
+ status_t set_default_params() {
+ using namespace format_tag;
+ if (src_md_.format_kind == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(src_md_,
+ utils::pick(ndims() - 2, nc, nwc, nhwc, ndhwc)));
+ }
+ if (dst_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(dst_md_, nc));
+ if (weights_md_.format_kind == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(weights_md_,
+ utils::pick(ndims() - 2, io, wio, hwio, dhwio)));
+ }
+ return inner_product_fwd_pd_t::set_default_params();
+ }
+
+ private:
+ void init_scratchpad() {
+ if (!dst_is_acc_) {
+ auto scratchpad = scratchpad_registry().registrar();
+ scratchpad.book(
+ memory_tracking::names::key_iprod_int_dat_in_acc_dt,
+ sizeof(acc_data_t) * MB() * OC());
+ }
+ }
+ };
+
+ gemm_x8s8s32x_inner_product_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd, true)
+ { pp_kernel_ = new pp_kernel_t(apd, pd()->dst_is_acc_); }
+ ~gemm_x8s8s32x_inner_product_fwd_t() { delete pp_kernel_; }
+
+ typedef typename prec_traits<dst_type>::type data_t;
+
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<data_type::s8>::type wei_data_t;
+ typedef typename prec_traits<dst_type>::type dst_data_t;
+ typedef typename prec_traits<data_type::s32>::type acc_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ // XXX: this is throwaway code that will become unnecessary when we have a
+ // sufficiently advanced igemm jit generator that supports quantization,
+ // relu, and whatnot
+ class pp_kernel_t: jit_generator {
+ public:
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(
+ gemm_x8s8s32x_inner_product_fwd_t::pp_kernel);
+ pp_kernel_t(const pd_t *pd, bool dst_is_acc);
+
+ void operator()(dst_data_t *dst, const acc_data_t *acc,
+ const char *bias, const float *scales, float nslope,
+ size_t start, size_t end);
+ private:
+ void generate();
+
+ struct ker_args {
+ dst_data_t *dst;
+ const acc_data_t *acc;
+ const char *bias;
+ const float *scales;
+ float nslope;
+ size_t len;
+ size_t oc_offset;
+ };
+ void (*ker_)(const ker_args *args);
+
+ size_t OC_;
+ data_type_t bias_data_type_;
+ size_t bias_data_type_size_;
+ size_t scale_idx_mult_;
+ bool do_bias_;
+ bool do_relu_;
+ };
+
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ pp_kernel_t *pp_kernel_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_conv_kernel_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_conv_kernel_f32.cpp
new file mode 100644
index 0000000000..6fa251d465
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_conv_kernel_f32.cpp
@@ -0,0 +1,674 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+* Copyright 2018 YANDEX LLC
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_memory.hpp"
+
+#include "jit_avx2_1x1_conv_kernel_f32.hpp"
+
+#define GET_OFF(field) offsetof(jit_1x1_conv_call_s, field)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::utils;
+
+using namespace Xbyak;
+
+void jit_avx2_1x1_conv_kernel_f32::generate_bcast_loop(int load_loop_blk)
+{
+ mov(aux1_reg_bcast_data, reg_bcast_data);
+ mov(aux_reg_output_data, reg_output_data);
+ mov(bcast_loop_iter, reg_bcast_loop_work);
+
+ Label bcast_loop, bcast_loop_tail;
+
+ cmp(bcast_loop_iter, jcp.ur);
+ jl(bcast_loop_tail, T_NEAR);
+
+ L(bcast_loop); {
+ assert(jcp.bcast_block % jcp.ur == 0);
+ int num_substeps = jcp.bcast_block / jcp.ur;
+ assert(num_substeps > 0 && num_substeps < 10);
+ for (int i = 0; i < num_substeps; i++) {
+ generate_reduce_loop(load_loop_blk, jcp.ur);
+ if (i < num_substeps - 1) {
+ add(aux1_reg_bcast_data, jcp.bcast_loop_bcast_substep);
+ add(aux_reg_output_data, jcp.bcast_loop_output_substep);
+ } else {
+ add(aux1_reg_bcast_data, jcp.bcast_loop_bcast_step
+ - (num_substeps - 1) * jcp.bcast_loop_bcast_substep);
+ add(aux_reg_output_data, jcp.bcast_loop_output_step
+ - (num_substeps - 1) * jcp.bcast_loop_output_substep);
+ }
+ }
+ sub(bcast_loop_iter, jcp.bcast_block);
+ cmp(bcast_loop_iter, jcp.bcast_block);
+ jge(bcast_loop, T_NEAR);
+ }
+
+ L(bcast_loop_tail);
+ if (jcp.ur_tail) {
+ Label bcast_loop_tail_out;
+ cmp(bcast_loop_iter, 0);
+ jz(bcast_loop_tail_out, T_NEAR);
+ generate_reduce_loop(load_loop_blk, jcp.ur_tail);
+ L(bcast_loop_tail_out);
+ }
+}
+
+void jit_avx2_1x1_conv_kernel_f32::generate_reduce_loop(
+ int load_loop_blk, int ur)
+{
+ auto vreg_load = [=](int i) {
+ return Ymm(ur * load_loop_blk + i);
+ };
+
+ auto vreg_accum = [=](int i, int j) {
+ return Ymm(j * load_loop_blk + i);
+ };
+
+ auto bias_ptr = [=](int i) {
+ return ptr[reg_bias_data + sizeof(float) * jcp.oc_block * i];
+ };
+
+ auto bcast_ptr = [=](int u, int j) {
+ assert(j < jcp.ur);
+ assert(u <= jcp.reduce_loop_unroll);
+ size_t offt;
+ if (one_of(jcp.prop_kind,
+ forward_training, forward_inference, backward_data))
+ {
+ assert(jcp.reduce_loop_unroll == (jcp.prop_kind == backward_data)
+ ? jcp.oc_block : jcp.ic_block);
+ auto height = (jcp.prop_kind == backward_data) ? jcp.os : jcp.is;
+ offt = (u == jcp.reduce_loop_unroll)
+ ? (height + j) * jcp.reduce_loop_unroll
+ : j * jcp.reduce_loop_unroll + u;
+ } else
+ offt = u * jcp.ic_block + j;
+ return ptr[aux_reg_bcast_data + sizeof(float) * offt];
+ };
+
+ auto load_ptr = [=](int u, int i) {
+ size_t offt;
+ size_t u0 = u % jcp.reduce_loop_unroll;
+ size_t u1 = u / jcp.reduce_loop_unroll;
+ switch (jcp.prop_kind) {
+ case backward_data:
+ offt = (i * jcp.oc_block + u0) * jcp.ic_block;
+ break;
+ case backward_weights:
+ offt = (i * jcp.os + u0) * jcp.oc_block;
+ break;
+ default:
+ offt = (i * jcp.ic + u0) * jcp.oc_block;
+ }
+ return ptr[aux_reg_load_data
+ + u1 * jcp.reduce_loop_load_step + sizeof(float) * offt];
+ };
+
+ auto output_ptr = [=](int i, int j) {
+ switch (jcp.prop_kind) {
+ case backward_data:
+ return ptr[aux_reg_output_data +
+ (i * jcp.is + j) * jcp.ic_block * sizeof(float)];
+ case backward_weights:
+ return ptr[aux_reg_output_data
+ + (i ? reg_output_stride * i : 0) // TODO: Xbyak should allow 0 scale
+ + sizeof(float) * jcp.oc_block * j];
+ default:
+ return ptr[aux_reg_output_data +
+ (i * jcp.os + j) * jcp.oc_block * sizeof(float)];
+ }
+ };
+
+ auto init = [=]() {
+ Label init_done, init_zero;
+
+ if (jcp.with_bias && one_of(jcp.prop_kind, forward_training,
+ forward_inference)) {
+ test(reg_reduce_pos_flag, FLAG_REDUCE_FIRST);
+ jz(init_zero);
+
+ for (int i = 0; i < load_loop_blk; i++)
+ for (int j = 0; j < ur; ++j)
+ vmovups(vreg_accum(i, j), bias_ptr(i));
+ jmp(init_done);
+ }
+
+ L(init_zero);
+ for (int i = 0; i < load_loop_blk; ++i)
+ for (int j = 0; j < ur; ++j) {
+ auto r = vreg_accum(i, j);
+ vxorps(r, r, r);
+ }
+
+ L(init_done);
+ for (int i = 0; i < load_loop_blk; ++i)
+ vmovups(vreg_load(i), load_ptr(0, i));
+ vbroadcastss(vreg_bcast, bcast_ptr(0, 0));
+ };
+
+ auto store = [=]() {
+ Label store_noadd;
+
+ if (!jcp.with_sum) {
+ test(reg_reduce_pos_flag, FLAG_REDUCE_FIRST);
+ jnz(store_noadd, T_NEAR);
+ }
+
+ for (int j = 0; j < ur; ++j)
+ for (int i = 0; i < load_loop_blk; ++i) {
+ auto r = vreg_accum(i, j);
+ vaddps(r, r, output_ptr(i, j));
+ }
+
+ L(store_noadd);
+
+ if (jcp.with_eltwise) {
+ assert(ur * load_loop_blk < 14);
+
+ Label store_norelu;
+ test(reg_reduce_pos_flag, FLAG_REDUCE_LAST);
+ jz(store_norelu, T_NEAR);
+
+ eltwise_injector_->compute_vector_range(0, ur * load_loop_blk);
+
+ L(store_norelu);
+ }
+
+ for (int j = 0; j < ur; ++j)
+ for (int i = 0; i < load_loop_blk; ++i) {
+ vmovups(output_ptr(i, j), vreg_accum(i, j));
+ }
+ };
+
+ auto fma_block = [=](bool last_block) {
+ for (int u = 0; u < jcp.reduce_loop_unroll; ++u) {
+ for (int j = 0; j < ur; ++j) {
+ for (int i = 0; i < load_loop_blk; ++i) {
+ if (mayiuse(avx2))
+ vfmadd231ps(vreg_accum(i, j), vreg_load(i), vreg_bcast);
+ else { // Intel(R) Advanced Vector Extensions (Intel(R) AVX) support
+ vmulps(vtmp, vreg_bcast, vreg_load(i));
+ vaddps(vreg_accum(i, j), vreg_accum(i, j), vtmp);
+ }
+ if (j == ur - 1 && !(last_block
+ && u == jcp.reduce_loop_unroll - 1))
+ vmovups(vreg_load(i), load_ptr(u + 1, i));
+ }
+ if (j < ur - 1)
+ vbroadcastss(vreg_bcast, bcast_ptr(u, j + 1));
+ }
+ if (!last_block || u < jcp.reduce_loop_unroll - 1)
+ vbroadcastss(vreg_bcast, bcast_ptr(u + 1, 0));
+ }
+ };
+
+ Label reduce_loop, reduce_loop_tail;
+
+ mov(aux_reg_load_data, reg_load_data);
+ mov(aux_reg_bcast_data, aux1_reg_bcast_data);
+
+ init();
+
+ mov(reduce_loop_iter, reg_reduce_loop_work);
+ sub(reduce_loop_iter, jcp.reduce_loop_unroll);
+ jle(reduce_loop_tail, T_NEAR);
+
+ L(reduce_loop); {
+ fma_block(false);
+ add(aux_reg_bcast_data, jcp.reduce_loop_bcast_step);
+ add(aux_reg_load_data, jcp.reduce_loop_load_step);
+ sub(reduce_loop_iter, jcp.reduce_loop_unroll);
+ jg(reduce_loop, T_NEAR);
+ }
+
+ L(reduce_loop_tail);
+ fma_block(true);
+
+ store();
+}
+
+void jit_avx2_1x1_conv_kernel_f32::generate_diff_bias_loop(int load_loop_blk)
+{
+ if (!jcp.with_bias || jcp.prop_kind != backward_weights)
+ return;
+
+ Label diff_bias_loop, diff_bias_loop_out, diff_bias_init_out;
+ Label diff_bias_load;
+
+ auto diff_bias_ptr = [=](int i) {
+ return ptr[reg_diff_bias_data + i * jcp.oc_block * sizeof(float)];
+ };
+
+ auto load_ptr = [=](int u, int i) {
+ return ptr[aux_reg_load_data
+ + (i * jcp.os + u) * jcp.oc_block * sizeof(float)];
+ };
+
+ auto diff_bias_reg = [=](int i) { return Ymm(i); };
+
+ mov(reg_diff_bias_data, ptr[rsp + reg_diff_bias_data_stack_offt]);
+ cmp(reg_diff_bias_data, 0);
+ je(diff_bias_loop_out, T_NEAR);
+
+ test(reg_reduce_pos_flag, FLAG_REDUCE_FIRST);
+ jz(diff_bias_load, T_NEAR);
+
+ for (int i = 0; i < load_loop_blk; ++i) {
+ auto r = diff_bias_reg(i);
+ vxorps(r, r, r);
+ }
+ jmp(diff_bias_init_out, T_NEAR);
+
+ L(diff_bias_load);
+ for (int i = 0; i < load_loop_blk; ++i)
+ vmovups(diff_bias_reg(i), diff_bias_ptr(i));
+
+ L(diff_bias_init_out);
+ mov(aux_reg_load_data, reg_load_data);
+ mov(reduce_loop_iter, reg_reduce_loop_work);
+ L(diff_bias_loop); {
+ for(int u = 0; u < jcp.reduce_loop_unroll; ++u)
+ for (int i = 0; i < load_loop_blk; ++i)
+ vaddps(diff_bias_reg(i), diff_bias_reg(i), load_ptr(u, i));
+ assert(jcp.reduce_dim % jcp.reduce_loop_unroll == 0);
+ add(aux_reg_load_data, jcp.reduce_loop_load_step);
+ sub(reduce_loop_iter, jcp.reduce_loop_unroll);
+ jnz(diff_bias_loop, T_NEAR);
+ }
+
+ for (int i = 0; i < load_loop_blk; i++)
+ vmovups(diff_bias_ptr(i), diff_bias_reg(i));
+ add(reg_diff_bias_data, load_loop_blk * jcp.oc_block * sizeof(float));
+ mov(ptr[rsp + reg_diff_bias_data_stack_offt], reg_diff_bias_data);
+
+ L(diff_bias_loop_out);
+}
+
+void jit_avx2_1x1_conv_kernel_f32::generate()
+{
+ preamble();
+
+ mov(reg_bcast_data, ptr[param1 + GET_OFF(bcast_data)]);
+ mov(reg_load_data, ptr[param1 + GET_OFF(load_data)]);
+ mov(reg_output_data, ptr[param1 + GET_OFF(output_data)]);
+ if (jcp.with_bias) {
+ if (jcp.prop_kind == backward_weights) {
+ sub(rsp, stack_space_needed);
+ mov(reg_diff_bias_data, ptr[param1 + GET_OFF(bias_data)]);
+ mov(ptr[rsp + reg_diff_bias_data_stack_offt], reg_diff_bias_data);
+ } else
+ mov(reg_bias_data, ptr[param1 + GET_OFF(bias_data)]);
+ }
+
+ mov(reg_load_loop_work, ptr[param1 + GET_OFF(load_dim)]);
+ mov(reg_bcast_loop_work, ptr[param1 + GET_OFF(bcast_dim)]);
+ mov(reg_reduce_loop_work, ptr[param1 + GET_OFF(reduce_dim)]);
+ mov(reg_reduce_pos_flag, ptr[param1 + GET_OFF(first_last_flag)]);
+ if (jcp.prop_kind == backward_weights)
+ mov(reg_output_stride, ptr[param1 + GET_OFF(output_stride)]);
+
+ auto generate_load_loop_body = [=] (int load_loop_blk) {
+ generate_bcast_loop(load_loop_blk);
+ add(reg_load_data, load_loop_blk * jcp.load_loop_load_step);
+ switch (jcp.prop_kind) {
+ case forward_training:
+ case forward_inference:
+ add(reg_bias_data, load_loop_blk * jcp.oc_block * sizeof(float));
+ add(reg_output_data,
+ load_loop_blk * jcp.os * jcp.oc_block * sizeof(float));
+ break;
+ case backward_data:
+ add(reg_output_data,
+ load_loop_blk * jcp.is * jcp.ic_block * sizeof(float));
+ break;
+ case backward_weights:
+ for (int i = 0; i < load_loop_blk; i++)
+ add(reg_output_data, reg_output_stride);
+ break;
+ default:
+ assert(!"invalid prop_kind");
+ }
+ sub(reg_load_loop_work, load_loop_blk * jcp.load_loop_iter_step);
+ };
+
+ Label load_loop_blk_8;
+ Label load_loop_blk_16;
+ Label load_loop_blk_24;
+ Label load_loop_blk_end;
+
+ cmp(reg_load_loop_work, 8);
+ jle(load_loop_blk_8, T_NEAR);
+
+ cmp(reg_load_loop_work, 32);
+ je(load_loop_blk_16, T_NEAR);
+
+ cmp(reg_load_loop_work, 16);
+ jle(load_loop_blk_16, T_NEAR);
+
+ L(load_loop_blk_24); {
+ generate_diff_bias_loop(3);
+ generate_load_loop_body(3);
+ cmp(reg_load_loop_work, 32);
+ je(load_loop_blk_16);
+ cmp(reg_load_loop_work, 24);
+ jge(load_loop_blk_24);
+ }
+
+ cmp(reg_load_loop_work, 8);
+ jle(load_loop_blk_8, T_NEAR);
+
+ L(load_loop_blk_16); {
+ generate_diff_bias_loop(2);
+ generate_load_loop_body(2);
+ cmp(reg_load_loop_work, 16);
+ jge(load_loop_blk_16);
+ }
+
+ L(load_loop_blk_8); {
+ cmp(reg_load_loop_work, 0);
+ je(load_loop_blk_end, T_NEAR);
+ generate_diff_bias_loop(1);
+ generate_load_loop_body(1);
+ }
+
+ L(load_loop_blk_end);
+
+ if (jcp.with_bias && jcp.prop_kind == backward_weights)
+ add(rsp, 8);
+
+ postamble();
+
+ if (jcp.with_eltwise)
+ eltwise_injector_->prepare_table();
+}
+
+bool jit_avx2_1x1_conv_kernel_f32::post_ops_ok(
+ jit_1x1_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ const auto &p = attr.post_ops_;
+
+ auto is_eltwise = [&](int idx) { return p.entry_[idx].is_eltwise(); };
+ auto is_sum = [&](int idx) { return p.entry_[idx].is_sum(); };
+
+ switch (p.len_) {
+ case 0: return true; // no post_ops
+ case 1: return is_eltwise(0) || is_sum(0); // sum OR eltwise
+ case 2: return is_sum(0) && is_eltwise(1); // sum -> eltwise
+ default: return false;
+ }
+
+ return false;
+}
+
+status_t jit_avx2_1x1_conv_kernel_f32::init_conf(jit_1x1_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d, const memory_desc_wrapper &dst_d,
+ const primitive_attr_t &attr)
+{
+ if (!mayiuse(avx)) return status::unimplemented;
+
+ // TODO (Roma): this code is duplicated from the generic kernel; maybe the
+ // configuration struct could do some stuff below
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+ const int ndims = src_d.ndims();
+
+ jcp.prop_kind = cd.prop_kind;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+
+ jcp.ih = (ndims == 3) ? 1 : src_d.dims()[2];
+ jcp.iw = src_d.dims()[ndims - 1];
+ jcp.oh = (ndims == 3) ? 1 : dst_d.dims()[2];
+ jcp.ow = dst_d.dims()[ndims - 1];
+
+ jcp.kh = (ndims == 3) ? 1 : weights_d.dims()[with_groups + 2];
+ jcp.kw = weights_d.dims()[with_groups + ndims - 1];
+
+ jcp.t_pad = (ndims == 3) ? 0 : cd.padding[0][0];
+ jcp.l_pad = cd.padding[0][ndims - 3];
+
+ jcp.stride_h = (ndims == 3) ? 1 : cd.strides[0];
+ jcp.stride_w = cd.strides[ndims - 3];
+
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+
+ jcp.os = jcp.oh * jcp.ow;
+ jcp.is = jcp.ih * jcp.iw;
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ jcp.with_sum = p.find(primitive_kind::sum) != -1;
+ const int eltwise_ind = p.find(primitive_kind::eltwise);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise) {
+ jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+ if (!mayiuse(avx2) && jcp.eltwise.alg != alg_kind::eltwise_relu)
+ return status::unimplemented;
+ }
+
+ const int is_bwd_d = jcp.prop_kind == backward_data;
+
+ format_tag_t dat_tag = ndims == 3 ? nCw8c : nChw8c;
+ format_tag_t wei_tag = with_groups
+ ? utils::pick(2 * ndims - 6 + is_bwd_d, gOIw8i8o, gOIw8o8i, gOIhw8i8o,
+ gOIhw8o8i)
+ : utils::pick(2 * ndims - 6 + is_bwd_d, OIw8i8o, OIw8o8i, OIhw8i8o,
+ OIhw8o8i);
+
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ jcp.dst_tag = dst_d.matches_one_of_tag(dat_tag);
+ jcp.wei_tag = weights_d.matches_one_of_tag(wei_tag);
+
+ const int simd_w = 8;
+
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ jcp.ic = rnd_up(jcp.ic, simd_w);
+
+ bool args_ok = true
+ && jcp.ngroups == 1
+ && jcp.src_tag == dat_tag
+ && jcp.wei_tag == wei_tag
+ && jcp.dst_tag == dat_tag;
+ if (!args_ok) return status::unimplemented;
+
+ args_ok = true
+ && jcp.ih == jcp.oh && jcp.iw == jcp.ow
+ && jcp.oc % simd_w == 0 && jcp.ic % simd_w == 0
+ && jcp.t_pad == 0 && jcp.l_pad == 0
+ && jcp.stride_w == 1 && jcp.stride_h == 1 // TODO: support some strides
+ && jcp.kh == 1 && jcp.kw == 1;
+ if (!args_ok) return status::unimplemented;
+
+ // TODO: remove this restriction
+ // optimized 1x1 bwd_w does not support Intel AVX
+ if (jcp.prop_kind == backward_weights && !mayiuse(avx2))
+ return status::unimplemented;
+
+ jcp.ic_block = jcp.oc_block = simd_w;
+
+ jcp.ur = mayiuse(avx2) ? 4 : 3; // Intel AVX support
+
+ int load_blocking{ 0 };
+ int load_blocking_max{ 0 };
+ int bcast_blocking{ 0 };
+ int bcast_blocking_max{ 0 };
+ int reduce_blocking{ 0 };
+
+ if (one_of(jcp.prop_kind, forward_training, forward_inference)) {
+ jcp.reduce_dim = jcp.ic;
+ jcp.reduce_block = jcp.ic_block;
+
+ jcp.load_dim = jcp.oc;
+ jcp.load_block = jcp.oc_block;
+
+ jcp.bcast_dim = jcp.is;
+ jcp.bcast_block = jcp.ur;
+
+ jcp.reduce_loop_unroll = jcp.reduce_block;
+ jcp.reduce_loop_bcast_step
+ = jcp.reduce_loop_unroll * jcp.is * sizeof(float);
+ jcp.reduce_loop_load_step
+ = jcp.reduce_loop_unroll * jcp.oc_block * sizeof(float);
+
+ jcp.bcast_loop_output_step = jcp.ur * jcp.oc_block * sizeof(float);
+ jcp.bcast_loop_output_substep = -1; // unused
+ jcp.bcast_loop_bcast_step = jcp.ur * jcp.ic_block * sizeof(float);
+ jcp.bcast_loop_bcast_substep = -1; // unused
+
+ jcp.load_loop_load_step = jcp.ic * jcp.oc_block * sizeof(float);
+ jcp.load_loop_iter_step = jcp.oc_block;
+
+ load_blocking = 120; // assumes the kernel is jcp.ur x 3
+ load_blocking_max = 144;
+ bcast_blocking = 128; // affects load balancing across threads
+ bcast_blocking_max = 192;
+ reduce_blocking = 128; // affects L1$ utilization
+ } else if (jcp.prop_kind == backward_data) {
+ jcp.reduce_dim = jcp.oc;
+ jcp.reduce_block = jcp.oc_block;
+
+ jcp.load_dim = jcp.ic;
+ jcp.load_block = jcp.oc_block;
+
+ jcp.bcast_dim = jcp.os;
+ jcp.bcast_block = jcp.ur;
+
+ jcp.reduce_loop_unroll = jcp.reduce_block;
+ jcp.reduce_loop_bcast_step
+ = jcp.reduce_loop_unroll * jcp.os * sizeof(float);
+ jcp.reduce_loop_load_step
+ = jcp.reduce_loop_unroll * jcp.ic * sizeof(float);
+
+ jcp.bcast_loop_output_step = jcp.ur * jcp.ic_block * sizeof(float);
+ jcp.bcast_loop_output_substep = -1; // unused
+ jcp.bcast_loop_bcast_step = jcp.ur * jcp.oc_block * sizeof(float);
+ jcp.bcast_loop_bcast_substep = -1; // unused
+
+ jcp.load_loop_load_step = jcp.oc_block * jcp.ic_block * sizeof(float);
+ jcp.load_loop_iter_step = jcp.ic_block;
+
+ load_blocking = 96; // assumes the kernel is jcp.ur x 3
+ load_blocking_max = 144;
+ bcast_blocking = 128; // affects load balancing across threads
+ bcast_blocking_max = 196;
+ reduce_blocking = 64; // affects L1$ utilization
+ } else if (jcp.prop_kind == backward_weights) {
+ jcp.reduce_dim = jcp.os;
+ jcp.reduce_block = 1;
+
+ jcp.load_dim = jcp.oc;
+ jcp.load_block = jcp.oc_block;
+
+ jcp.bcast_dim = jcp.ic;
+ jcp.bcast_block = jcp.ic_block;
+
+ jcp.reduce_loop_unroll = jcp.reduce_block;
+ jcp.reduce_loop_bcast_step
+ = jcp.reduce_loop_unroll * jcp.ic_block * sizeof(float);
+ jcp.reduce_loop_load_step
+ = jcp.reduce_loop_unroll * jcp.oc_block * sizeof(float);
+
+ jcp.bcast_loop_output_step = jcp.oc_block * jcp.ic_block * sizeof(float);
+ jcp.bcast_loop_output_substep = jcp.oc_block * jcp.ur * sizeof(float);
+ jcp.bcast_loop_bcast_step = jcp.ic_block * jcp.is * sizeof(float);
+ jcp.bcast_loop_bcast_substep = jcp.ur * sizeof(float);
+
+ jcp.load_loop_load_step = jcp.oc_block * jcp.os * sizeof(float);
+ jcp.load_loop_iter_step = jcp.oc_block;
+
+ /* --- */
+
+ load_blocking = div_up(jcp.load_dim, jcp.load_block);
+ while (true) {
+ if (load_blocking <= 32) break;
+ else if (load_blocking % 2 == 0) load_blocking /= 2;
+ else if (load_blocking % 3 == 0) load_blocking /= 3;
+ else break;
+ }
+ load_blocking *= jcp.load_block;
+ load_blocking_max = load_blocking;
+ assert(jcp.load_dim % load_blocking == 0);
+
+ bcast_blocking = div_up(jcp.bcast_dim, jcp.bcast_block);
+ while (true) {
+ if (bcast_blocking <= 9) break;
+ else if (bcast_blocking % 2 == 0) bcast_blocking /= 2;
+ else if (bcast_blocking % 3 == 0) bcast_blocking /= 3;
+ else break;
+ }
+ bcast_blocking *= jcp.bcast_block;
+ bcast_blocking_max = bcast_blocking;
+ assert(jcp.bcast_dim % bcast_blocking == 0);
+
+ reduce_blocking = 128; // affects L1$ utilization
+ } else
+ return status::unimplemented;
+
+ assert(load_blocking);
+ assert(load_blocking_max);
+ assert(bcast_blocking);
+ assert(bcast_blocking_max);
+ assert(reduce_blocking);
+
+ assert(jcp.bcast_block % jcp.ur == 0);
+ jcp.ur_tail = jcp.bcast_dim % jcp.ur;
+
+ jcp.nb_bcast_blocking = bcast_blocking / jcp.bcast_block;
+ jcp.nb_bcast_blocking_max = bcast_blocking_max / jcp.bcast_block;
+ jcp.nb_load_blocking = load_blocking / jcp.load_block;
+ jcp.nb_load_blocking_max = load_blocking_max / jcp.load_block;
+ jcp.nb_reduce_blocking = reduce_blocking / jcp.reduce_block;
+
+ jcp.nb_bcast = div_up(jcp.bcast_dim, jcp.bcast_block);
+ jcp.nb_load = div_up(jcp.load_dim, jcp.load_block);
+ jcp.nb_reduce = div_up(jcp.reduce_dim, jcp.reduce_block);
+
+ return status::success;
+}
+
+void jit_avx2_1x1_conv_kernel_f32::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad,
+ const jit_1x1_conv_conf_t &jcp) {
+ using namespace mkldnn::impl::memory_tracking::names;
+
+ if (jcp.prop_kind != backward_data && jcp.oc != jcp.oc_without_padding)
+ scratchpad.book(key_conv_padded_bias, sizeof(float) * jcp.oc);
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_conv_kernel_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_conv_kernel_f32.hpp
new file mode 100644
index 0000000000..bfdeb2b18d
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_conv_kernel_f32.hpp
@@ -0,0 +1,110 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_AVX2_1x1_CONV_KERNEL_F32_HPP
+#define JIT_AVX2_1x1_CONV_KERNEL_F32_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+
+#include "cpu_memory.hpp"
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+#include "jit_uni_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_avx2_1x1_conv_kernel_f32: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx2_1x1_conv_kernel_f32)
+
+ jit_avx2_1x1_conv_kernel_f32(jit_1x1_conv_conf_t ajcp,
+ const primitive_attr_t &attr)
+ : jcp(ajcp), attr_(attr), eltwise_injector_(nullptr)
+ {
+ if (jcp.with_eltwise)
+ eltwise_injector_ = new jit_uni_eltwise_injector_f32<avx2>(this,
+ jcp.eltwise);
+
+ this->generate();
+ jit_ker = (void (*)(jit_1x1_conv_call_s *))this->getCode();
+ }
+
+ ~jit_avx2_1x1_conv_kernel_f32() {
+ delete eltwise_injector_;
+ }
+
+ static bool post_ops_ok(jit_1x1_conv_conf_t &jcp,
+ const primitive_attr_t &attr);
+
+ static status_t init_conf(jit_1x1_conv_conf_t &jcp,
+ const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d,
+ const primitive_attr_t &attr);
+
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_1x1_conv_conf_t &jcp);
+
+ jit_1x1_conv_conf_t jcp;
+ const primitive_attr_t &attr_;
+ void (*jit_ker)(jit_1x1_conv_call_s *);
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ using ymm_t = const Xbyak::Ymm;
+
+ reg64_t reg_bcast_data = rax;
+ reg64_t reg_load_data = rsi;
+ reg64_t reg_output_data = rbx;
+ reg64_t aux_reg_bcast_data = rdx;
+ reg64_t aux1_reg_bcast_data = abi_not_param1;
+ reg64_t aux_reg_load_data = abi_param1;
+ reg64_t aux_reg_output_data = rbp;
+ reg64_t reg_load_loop_work = r9;
+ reg64_t reg_bcast_loop_work = r10;
+ reg64_t reg_reduce_loop_work = r11;
+ reg64_t load_loop_iter = r13;
+ reg64_t bcast_loop_iter = r14;
+ reg64_t reduce_loop_iter = r15;
+ reg64_t imm_addr64 = reduce_loop_iter;
+ reg64_t reg_reduce_pos_flag = r8;
+ reg64_t reg_output_stride = r12;
+ reg64_t reg_bias_data = r12;
+ reg64_t reg_diff_bias_data = bcast_loop_iter;
+
+ int reg_diff_bias_data_stack_offt = 0;
+ int stack_space_needed = 8;
+
+ ymm_t vreg_bcast = ymm_t(15);
+ ymm_t vtmp = ymm_t(14);
+
+ jit_uni_eltwise_injector_f32<avx2> *eltwise_injector_;
+
+ void generate_bcast_loop(int load_loop_blk);
+ void generate_reduce_loop(int load_loop_blk, int ur);
+ void generate_diff_bias_loop(int load_loop_blk);
+
+ void generate();
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_convolution.cpp
new file mode 100644
index 0000000000..f116ac9056
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_convolution.cpp
@@ -0,0 +1,545 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_generator.hpp"
+
+#include "jit_avx2_1x1_convolution.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+
+#define data_blk_off(f, n, c, h, w) \
+ ((ndims == 3) \
+ ? (f).blk_off(n, c, w) \
+ : (f).blk_off(n, c, h, w))
+
+/* convolution forward */
+
+void jit_avx2_1x1_convolution_fwd_t::execute_forward(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+ auto rtus_space = scratchpad(ctx).get<data_t>(key_conv_rtus_space);
+
+ const int work_amount = jcp.mb * jcp.ngroups * jcp.nb_bcast;
+ const int ndims = dst_d.ndims();
+
+ const int stride_h = (ndims == 3) ? 1 : pd()->desc()->strides[0];
+ const int stride_w = pd()->desc()->strides[ndims - 3];
+ const int pad_t = (ndims == 3) ? 0 : pd()->desc()->padding[0][0];
+ const int pad_l = pd()->desc()->padding[0][ndims - 3];
+
+ auto step = [](int default_step, int remaining, int tail_step) {
+ assert(default_step <= tail_step);
+ return remaining < tail_step ? remaining : default_step;
+ };
+
+ auto ker = [&](const int ithr, const int nthr) {
+ // TODO (Roma): remove this restriction
+ assert(jcp.stride_w == 1 && jcp.stride_h == 1);
+
+ auto p = jit_1x1_conv_call_s();
+ auto rp = rtus_driver_t<avx2>::call_params_t();
+
+ const int nb_oc = jcp.nb_load;
+ const int nb_ic = jcp.nb_reduce;
+ const int nb_ic_blocking = jcp.nb_reduce_blocking;
+ const int os_block = jcp.bcast_block;
+
+ int start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+
+ int iwork = start;
+ while (iwork < end) {
+ int n{0}, g{0}, osb{0};
+ nd_iterator_init(iwork, n, jcp.mb, g, jcp.ngroups, osb,
+ jcp.nb_bcast);
+
+ int bcast_step = step(jcp.nb_bcast_blocking, jcp.nb_bcast - osb,
+ jcp.nb_bcast_blocking_max);
+ bcast_step = nstl::min(bcast_step, end - iwork);
+
+ const int os = osb * os_block;
+ const int oh = os / jcp.ow;
+ const int ow = os % jcp.ow;
+
+ const int ih = nstl::max(oh * stride_h - pad_t, 0);
+ const int iw = nstl::max(ow * stride_w - pad_l, 0);
+ rp.iw_start = iw;
+
+ p.bcast_dim = this_block_size(os, jcp.os, bcast_step * os_block);
+ rp.os = p.bcast_dim;
+
+ int ocb = 0;
+ while (ocb < jcp.nb_load) {
+ const int load_step = step(jcp.nb_load_blocking,
+ jcp.nb_load - ocb, jcp.nb_load_blocking_max);
+
+ const int _ocb = g * nb_oc + ocb;
+ p.load_dim = this_block_size(ocb * jcp.oc_block, jcp.oc,
+ load_step * jcp.oc_block);
+ const size_t dst_off = data_blk_off(dst_d, n, _ocb, oh, ow);
+
+ p.output_data = &dst[dst_off];
+
+ p.bias_data = &bias[_ocb * jcp.oc_block];
+
+ for (int icb = 0; icb < nb_ic; icb += nb_ic_blocking) {
+ p.first_last_flag = 0
+ | (icb == 0 ? FLAG_REDUCE_FIRST : 0)
+ | (icb + nb_ic_blocking >= nb_ic
+ ? FLAG_REDUCE_LAST : 0);
+
+ p.reduce_dim = this_block_size(icb * jcp.ic_block, jcp.ic,
+ nb_ic_blocking * jcp.ic_block);
+ rp.icb = p.reduce_dim / jcp.reduce_block;
+
+ p.load_data = &weights[pd()->with_groups()
+ ? weights_d.blk_off(g, ocb, icb)
+ : weights_d.blk_off(ocb, icb)];
+
+ const int _icb = g * nb_ic + icb;
+ if (pd()->rtus_.reduce_src_) {
+ rp.ws = rtus_space
+ + ithr * pd()->rtus_.space_per_thread_
+ + _icb * jcp.is * jcp.ic_block;
+
+ if (ocb == 0) {
+ rp.src = src + data_blk_off(src_d, n, _icb, ih, iw);
+ rtus_driver_->ker_(&rp);
+ }
+
+ p.bcast_data = rp.ws;
+ } else
+ p.bcast_data = src + data_blk_off(src_d, n, _icb, ih, iw);
+
+ kernel_->jit_ker(&p);
+ }
+
+ ocb += load_step;
+ }
+
+ iwork += bcast_step;
+ }
+ };
+
+ if (pd()->wants_padded_bias()) {
+ auto padded_bias = scratchpad(ctx).get<data_t>(key_conv_padded_bias);
+ utils::array_copy(padded_bias, bias, jcp.oc_without_padding);
+ utils::array_set(padded_bias + jcp.oc_without_padding, 0.f,
+ jcp.oc - jcp.oc_without_padding);
+ bias = padded_bias;
+ }
+
+ parallel(0, ker);
+
+ if (pd()->wants_zero_pad_dst())
+ ctx.memory(MKLDNN_ARG_DST)->zero_pad();
+}
+
+/* convolution backward wtr data */
+
+void jit_avx2_1x1_convolution_bwd_data_t::execute_backward_data(
+ const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+
+ const auto &jcp = kernel_->jcp;
+ auto rtus_space = scratchpad(ctx).get<data_t>(key_conv_rtus_space);
+
+ // TODO (Roma): remove this restriction
+ assert(jcp.stride_w == 1 && jcp.stride_h == 1);
+ const int ndims = diff_dst_d.ndims();
+
+ const int stride_h = (ndims == 3) ? 1 : pd()->desc()->strides[0];
+ const int stride_w = pd()->desc()->strides[ndims - 3];
+ const int pad_t = (ndims == 3) ? 0 : pd()->desc()->padding[0][0];
+ const int pad_l = pd()->desc()->padding[0][ndims - 3];
+
+ const int nb_ic = jcp.nb_load;
+ const int nb_oc = jcp.nb_reduce;
+ const int os_block = jcp.bcast_block;
+ const int nb_oc_blocking = jcp.nb_reduce_blocking;
+
+ const int work_amount = jcp.mb * jcp.ngroups * jcp.nb_bcast;
+
+ auto step = [](int default_step, int remaining, int tail_step) {
+ assert(default_step <= tail_step);
+ return remaining < tail_step ? remaining : default_step;
+ };
+
+ auto ker = [&](const int ithr, const int nthr) {
+ auto p = jit_1x1_conv_call_s();
+ auto rp = rtus_driver_t<avx2>::call_params_t();
+
+ int start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+
+ int load_step = 0;
+ for (int icb = 0; icb < jcp.nb_load; icb += load_step) {
+ load_step = step(jcp.nb_load_blocking, jcp.nb_load - icb,
+ jcp.nb_load_blocking_max);
+
+ p.load_dim = this_block_size(icb * jcp.ic_block, jcp.ic,
+ load_step * jcp.ic_block);
+ rp.icb = p.load_dim / jcp.ic_block;
+
+ int bcast_step;
+ for (int iwork = start; iwork < end; iwork += bcast_step) {
+ int n{0}, g{0}, osb{0};
+ nd_iterator_init(iwork, n, jcp.mb, g, jcp.ngroups, osb,
+ jcp.nb_bcast);
+
+ bcast_step = step(jcp.nb_bcast_blocking, jcp.nb_bcast - osb,
+ jcp.nb_bcast_blocking_max);
+ bcast_step = nstl::min(bcast_step, end - iwork);
+
+ const int os = osb * os_block;
+ p.bcast_dim = this_block_size(os, jcp.os,
+ bcast_step * os_block);
+ rp.os = p.bcast_dim;
+
+ const int oh = os / jcp.ow;
+ const int ow = os % jcp.ow;
+ const int ih = nstl::max(oh * stride_h - pad_t, 0);
+ const int iw = nstl::max(ow * stride_w - pad_l, 0);
+ rp.iw_start = iw;
+
+ const int _icb = g * nb_ic + icb;
+ rp.src = diff_src + data_blk_off(diff_src_d, n, _icb, ih, iw);
+ if (pd()->rtus_.reduce_src_) {
+ rp.ws = rtus_space
+ + ithr * pd()->rtus_.space_per_thread_;
+ p.output_data = rp.ws;
+ } else
+ p.output_data = rp.src;
+
+ for (int ocb = 0; ocb < jcp.nb_reduce;
+ ocb += jcp.nb_reduce_blocking) {
+ const int _ocb = g * nb_oc + ocb;
+ size_t diff_dst_off = data_blk_off(diff_dst_d, n, _ocb, oh,
+ ow);
+ p.bcast_data = &diff_dst[diff_dst_off];
+
+ p.load_data = &weights[pd()->with_groups()
+ ? weights_d.blk_off(g, ocb, icb)
+ : weights_d.blk_off(ocb, icb)];
+
+ p.first_last_flag = ocb == 0 ? FLAG_REDUCE_FIRST : 0;
+
+ p.reduce_dim = this_block_size(ocb * jcp.oc_block, jcp.oc,
+ nb_oc_blocking * jcp.oc_block);
+
+ kernel_->jit_ker(&p);
+ }
+
+ if (pd()->rtus_.reduce_src_)
+ rtus_driver_->ker_(&rp);
+ }
+ }
+ };
+
+ parallel(0, ker);
+}
+
+/* convolution backward wtr weights */
+
+jit_avx2_1x1_convolution_bwd_weights_t::jit_avx2_1x1_convolution_bwd_weights_t(
+ const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , kernel_(nullptr)
+ , rtus_driver_(nullptr)
+{
+ kernel_ = new jit_avx2_1x1_conv_kernel_f32(pd()->jcp_, *pd()->attr());
+ reducer_weights_ =
+ new cpu_reducer_2d_t<data_type::f32>(pd()->reducer_wei_conf_);
+ reducer_bias_ = new cpu_reducer_t<data_type::f32>(pd()->reducer_bia_conf_);
+ init_rtus_driver<avx2>(this);
+}
+
+void jit_avx2_1x1_convolution_bwd_weights_t::execute_backward_weights(
+ const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_weights = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_WEIGHTS);
+ auto diff_bias_in = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_BIAS);
+
+ auto scratchpad = this->scratchpad(ctx);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper diff_weights_d(pd()->diff_weights_md(0));
+ const memory_desc_wrapper diff_bias_d(pd()->diff_weights_md(1));
+
+ const auto &jcp = kernel_->jcp;
+ auto rtus_space = scratchpad.get<data_t>(key_conv_rtus_space);
+
+ data_t *diff_bias = pd()->wants_padded_bias()
+ ? scratchpad.get<data_t>(key_conv_padded_bias) : diff_bias_in;
+
+ auto reducer_bia_scratchpad = memory_tracking::grantor_t(scratchpad,
+ prefix_reducer_bia);
+ auto rb = this->reducer_bias_;
+ rb->init(reducer_bia_scratchpad);
+
+ auto reducer_wei_scratchpad = memory_tracking::grantor_t(scratchpad,
+ prefix_reducer_wei);
+ auto rw = this->reducer_weights_;
+ rw->init(reducer_wei_scratchpad);
+
+ const int ndims = diff_dst_d.ndims();
+ // TODO (Roma): remove this restriction
+ assert(jcp.stride_w == 1 && jcp.stride_h == 1);
+
+ const int nb_ic = jcp.nb_bcast;
+ const int nb_ic_blocking = jcp.nb_bcast_blocking;
+ const int bcast_work = div_up(nb_ic, nb_ic_blocking);
+
+ const int nb_oc = jcp.nb_load;
+ const int nb_oc_blocking = jcp.nb_load_blocking;
+ const int load_work = div_up(nb_oc, nb_oc_blocking);
+
+ const int sp_dim = jcp.reduce_dim;
+ const int mb_sp_work = jcp.mb * sp_dim;
+
+ const int stride_h = (ndims == 3) ? 1 : pd()->desc()->strides[0];
+ const int stride_w = pd()->desc()->strides[ndims - 3];
+ const int pad_t = (ndims == 3) ? 0 : pd()->desc()->padding[0][0];
+ const int pad_l = pd()->desc()->padding[0][ndims - 3];
+
+ auto step = [](int default_step, int remaining, int tail_step) {
+ assert(default_step <= tail_step);
+ return remaining < tail_step ? remaining : default_step;
+ };
+
+ auto oc_ic_sp_loop = [=](int sp_start, int sp_end, bool first_image,
+ data_t *store_to, size_t store_to_ld, const data_t *diff_dst,
+ const data_t *src, int ithr) {
+ auto p = jit_1x1_conv_call_s();
+ auto rp = rtus_driver_t<avx2>::call_params_t();
+
+ p.output_stride = store_to_ld * sizeof(float);
+ const int sp_step_def = jcp.nb_reduce_blocking * jcp.reduce_block;
+
+ int oc_b_step = 0;
+ for (int oc_b = 0; oc_b < nb_oc_blocking; oc_b += oc_b_step) {
+ oc_b_step = step(12, nb_oc_blocking - oc_b, 18);
+ p.load_dim = oc_b_step * jcp.oc_block;
+
+ int ic_b_step = 0;
+ for (int ic_b = 0; ic_b < nb_ic_blocking; ic_b += ic_b_step) {
+ ic_b_step = step(12, nb_ic_blocking - ic_b, 18);
+ p.bcast_dim = ic_b_step * jcp.ic_block;
+ rp.icb = p.bcast_dim / jcp.ic_block;
+
+ p.output_data = store_to + oc_b * store_to_ld
+ + ic_b * jcp.ic_block * jcp.oc_block;
+
+ /* spatial reduction */
+ int sp_step = 0;
+ for (int sp = sp_start; sp < sp_end; sp += sp_step) {
+ sp_step = step(sp_step_def, sp_end - sp, 192);
+ p.reduce_dim = sp_step;
+ rp.os = p.reduce_dim;
+
+ p.first_last_flag = sp == sp_start && first_image
+ ? FLAG_REDUCE_FIRST : 0;
+
+ p.load_data = diff_dst
+ + (oc_b * jcp.reduce_dim + sp) * jcp.oc_block;
+
+ if (pd()->rtus_.reduce_src_) {
+ const int oh = sp / jcp.ow;
+ const int ow = sp % jcp.ow;
+
+ const int ih = nstl::max(oh * stride_h - pad_t, 0);
+ const int iw = nstl::max(ow * stride_w - pad_l, 0);
+ rp.iw_start = iw;
+
+ rp.ws = rtus_space
+ + ithr * pd()->rtus_.space_per_thread_
+ + (ic_b * jcp.is + sp) * jcp.ic_block;
+ if (ndims == 3)
+ rp.src = src
+ + iw * src_d.blocking_desc().strides[2];
+ else
+ rp.src = src
+ + ih * src_d.blocking_desc().strides[2]
+ + iw * src_d.blocking_desc().strides[3];
+
+ if (oc_b == 0)
+ rtus_driver_->ker_(&rp);
+
+ p.bcast_data = rp.ws;
+ } else
+ p.bcast_data = src
+ + (ic_b * jcp.reduce_dim + sp) * jcp.ic_block;
+
+ kernel_->jit_ker(&p);
+ }
+ }
+ }
+ };
+
+ auto ker = [&](const int ithr, const int nthr) {
+ assert(nthr == rw->balancer().nthr_);
+
+ const int w_njobs = rw->balancer().ithr_njobs(ithr);
+ if (w_njobs == 0) return;
+
+ /* setup: independent work (oc, ic) */
+ const int w_job_start = rw->balancer().ithr_job_off(ithr);
+ int g{0}, load_i{0}, bcast_i{0};
+ nd_iterator_init(w_job_start, g, jcp.ngroups, load_i, load_work,
+ bcast_i, bcast_work);
+
+ /* setup: reduction work (mb, sp) */
+ int mb_sp_start{0}, mb_sp_end{0};
+ balance211(mb_sp_work, rw->balancer().nthr_per_group_,
+ rw->balancer().id_in_group(ithr), mb_sp_start, mb_sp_end);
+ int img_start{0}, sp_start{0};
+ nd_iterator_init(mb_sp_start, img_start, jcp.mb, sp_start, sp_dim);
+
+ /* independent work */
+ for (int iwork = 0; iwork < w_njobs; ++iwork) {
+ const int oc_b = nb_oc_blocking * load_i;
+ const int ic_b = nb_ic_blocking * bcast_i;
+
+ const int _ic_b = g * nb_ic + ic_b;
+ const int _oc_b = g * nb_oc + oc_b;
+
+ data_t *store_to;
+ size_t store_to_ld;
+
+ if (rw->balancer().nthr_per_group_ == 1) {
+ const size_t off = pd()->with_groups()
+ ? diff_weights_d.blk_off(g, oc_b, ic_b)
+ : diff_weights_d.blk_off(oc_b, ic_b);
+ store_to = &diff_weights[off];
+ store_to_ld = jcp.ic * jcp.oc_block;
+ } else {
+ const size_t off = iwork * rw->balancer().job_size_;
+ store_to =
+ rw->get_local_ptr(ithr, reducer_wei_scratchpad) + off;
+ store_to_ld = nb_ic_blocking * jcp.ic_block * jcp.oc_block;
+ }
+
+ /* reduction work */
+ int img = img_start;
+ int sp = sp_start;
+ int sp_step = 0;
+ for (int mb_sp = mb_sp_start; mb_sp < mb_sp_end; mb_sp += sp_step)
+ {
+ sp_step = nstl::min(sp_dim - sp, mb_sp_end - mb_sp);
+
+ const bool first_image = img == img_start;
+ oc_ic_sp_loop(sp, sp + sp_step, first_image, store_to,
+ store_to_ld, &diff_dst[diff_dst_d.blk_off(img, _oc_b)],
+ &src[src_d.blk_off(img, _ic_b)], ithr);
+
+ sp = 0;
+ img += 1;
+ }
+
+ nd_iterator_step(g, jcp.ngroups, load_i, load_work, bcast_i,
+ bcast_work);
+ }
+ rw->reduce(ithr, diff_weights, reducer_wei_scratchpad);
+ };
+
+ auto ker_bias = [&](int ithr, int nthr) {
+ assert(nthr == rb->balancer().nthr_);
+
+ const int b_job_start = rb->balancer().ithr_job_off(ithr);
+ const int b_njobs = rb->balancer().ithr_njobs(ithr);
+
+ if (b_njobs == 0) return;
+
+ /* reduction dimension */
+ int img_start{0}, img_end{0};
+ balance211(jcp.mb, rb->balancer().nthr_per_group_,
+ rb->balancer().id_in_group(ithr), img_start, img_end);
+
+ /* jobs */
+ int g_start{0}, ocb_start{0};
+ nd_iterator_init(b_job_start, g_start, jcp.ngroups, ocb_start, nb_oc);
+
+ for (int img = img_start; img < img_end; ++img) {
+ int g = g_start, ocb = ocb_start;
+ for (int b_job_loc = 0; b_job_loc < b_njobs; ++b_job_loc) {
+ const size_t _oc = g * nb_oc + ocb;
+
+ const data_t *d_dst = &diff_dst[diff_dst_d.blk_off(img, _oc)];
+ data_t *d_bias =
+ rb->get_local_ptr(ithr, diff_bias, reducer_bia_scratchpad)
+ + b_job_loc * rb->balancer().job_size_;
+
+ if (img == img_start)
+ for (int o = 0; o < 8; ++o) d_bias[o] = 0.;
+
+ for (int hw = 0; hw < jcp.oh * jcp.ow; ++hw) {
+ PRAGMA_OMP_SIMD()
+ for (int o = 0; o < 8; ++o)
+ d_bias[o] += d_dst[o];
+ d_dst += 8;
+ }
+
+ nd_iterator_step(g, jcp.ngroups, ocb, nb_oc);
+ }
+ }
+ rb->reduce(ithr, diff_bias, reducer_bia_scratchpad);
+ };
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ ker(ithr, nthr);
+ if (pd()->with_bias())
+ ker_bias(ithr, nthr);
+ });
+
+ /* TODO: put this in ker_bias */
+ if (pd()->wants_padded_bias()) {
+ assert(jcp.ngroups == 1);
+ for (int oc = 0; oc < jcp.oc_without_padding; ++oc)
+ diff_bias_in[oc] = diff_bias[oc];
+ }
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_convolution.hpp
new file mode 100644
index 0000000000..9762242173
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_1x1_convolution.hpp
@@ -0,0 +1,344 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX2_1x1_CONVOLUTION_HPP
+#define CPU_JIT_AVX2_1x1_CONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+#include "cpu_reducer.hpp"
+
+#include "jit_avx2_1x1_conv_kernel_f32.hpp"
+#include "jit_uni_1x1_conv_utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_avx2_1x1_convolution_fwd_t: public cpu_primitive_t {
+ // TODO: (Roma) Code duplication duplication! Remove with templates
+ // (maybe...)!
+ struct pd_t: public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_(), rtus_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_1x1:", avx2, ""),
+ jit_avx2_1x1_convolution_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ const convolution_desc_t *conv_d = desc();
+ const memory_desc_t *src_d = src_md();
+ rtus_prepare(this, conv_d, src_d, dst_md());
+
+ status_t status = jit_avx2_1x1_conv_kernel_f32::init_conf(jcp_,
+ *conv_d, *src_d, *weights_md(), *dst_md(), *attr());
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx2_1x1_conv_kernel_f32::init_scratchpad(scratchpad, jcp_);
+
+ rtus_prepare_space_info(this, scratchpad);
+
+ return status::success;
+ }
+
+ jit_1x1_conv_conf_t jcp_;
+ reduce_to_unit_stride_t rtus_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c);
+ auto wei_tag = with_groups()
+ ? utils::pick(ndims() - 3, gOIw8i8o, gOIhw8i8o)
+ : utils::pick(ndims() - 3, OIw8i8o, OIhw8i8o);
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ template <cpu_isa_t isa, typename conv_t>
+ friend void init_rtus_driver(conv_t *self);
+
+ jit_avx2_1x1_convolution_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , kernel_(nullptr), rtus_driver_(nullptr)
+ {
+ kernel_ = new jit_avx2_1x1_conv_kernel_f32(pd()->jcp_, *pd()->attr());
+ init_rtus_driver<avx2>(this);
+ }
+
+ ~jit_avx2_1x1_convolution_fwd_t() {
+ delete kernel_;
+ delete rtus_driver_;
+ }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx2_1x1_conv_kernel_f32 *kernel_;
+ rtus_driver_t<avx2> *rtus_driver_;
+};
+
+struct jit_avx2_1x1_convolution_bwd_data_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_data_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_data_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_(), rtus_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_1x1:", avx2, ""),
+ jit_avx2_1x1_convolution_bwd_data_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_data
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::undef, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ const convolution_desc_t *conv_d = desc();
+ const memory_desc_t *diff_src_d = diff_src_md();
+ rtus_prepare(this, conv_d, diff_src_d, diff_dst_md());
+
+ status_t status = jit_avx2_1x1_conv_kernel_f32::init_conf(jcp_,
+ *conv_d, *diff_src_d, *weights_md(), *diff_dst_md(),
+ *attr());
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx2_1x1_conv_kernel_f32::init_scratchpad(scratchpad, jcp_);
+
+ rtus_prepare_space_info(this, scratchpad);
+
+ return status::success;
+ }
+
+ jit_1x1_conv_conf_t jcp_;
+ reduce_to_unit_stride_t rtus_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c);
+ auto wei_tag = with_groups()
+ ? utils::pick(ndims() - 3, gOIw8o8i, gOIhw8o8i)
+ : utils::pick(ndims() - 3, OIw8o8i, OIhw8o8i);
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ template <cpu_isa_t isa, typename conv_t>
+ friend void init_rtus_driver(conv_t *self);
+
+ jit_avx2_1x1_convolution_bwd_data_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , kernel_(nullptr)
+ , rtus_driver_(nullptr)
+ {
+ kernel_ = new jit_avx2_1x1_conv_kernel_f32(pd()->jcp_, *pd()->attr());
+ init_rtus_driver<avx2>(this);
+ }
+
+ ~jit_avx2_1x1_convolution_bwd_data_t() {
+ delete kernel_;
+ delete rtus_driver_;
+ }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_data(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_data(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx2_1x1_conv_kernel_f32 *kernel_;
+ rtus_driver_t<avx2> *rtus_driver_;
+};
+
+struct jit_avx2_1x1_convolution_bwd_weights_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_weights_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_weights_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_(), rtus_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_1x1:", avx2, ""),
+ jit_avx2_1x1_convolution_bwd_weights_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_weights
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ const convolution_desc_t *conv_d = desc();
+ const memory_desc_t *src_d = src_md();
+ rtus_prepare(this, conv_d, src_d, diff_dst_md());
+
+ status_t status = jit_avx2_1x1_conv_kernel_f32::init_conf(jcp_,
+ *conv_d, *src_d, *diff_weights_md(), *diff_dst_md(),
+ *attr());
+ if (status != status::success) return status;
+
+ init_balancers();
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx2_1x1_conv_kernel_f32::init_scratchpad(scratchpad, jcp_);
+
+ rtus_prepare_space_info(this, scratchpad);
+
+ auto reducer_bia_scratchpad = memory_tracking::registrar_t(
+ scratchpad, memory_tracking::names::prefix_reducer_bia);
+ reducer_bia_conf_.init_scratchpad(reducer_bia_scratchpad);
+
+ auto reducer_wei_scratchpad = memory_tracking::registrar_t(
+ scratchpad, memory_tracking::names::prefix_reducer_wei);
+ reducer_wei_conf_.init_scratchpad(reducer_wei_scratchpad);
+
+ return status::success;
+ }
+
+ jit_1x1_conv_conf_t jcp_;
+ cpu_reducer_t<data_type::f32>::conf_t reducer_bia_conf_;
+ cpu_reducer_2d_t<data_type::f32>::conf_t reducer_wei_conf_;
+ reduce_to_unit_stride_t rtus_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c);
+ auto wei_tag = with_groups()
+ ? utils::pick(ndims() - 3, gOIw8i8o, gOIhw8i8o)
+ : utils::pick(ndims() - 3, OIw8i8o, OIhw8i8o);
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+
+ private:
+ void init_balancers() {
+ const int ic_block = jcp_.bcast_block;
+ const int nb_ic = jcp_.nb_bcast;
+ const int nb_ic_blocking = jcp_.nb_bcast_blocking;
+ const int bcast_work = utils::div_up(nb_ic, nb_ic_blocking);
+
+ const int oc_block = jcp_.load_block;
+ const int nb_oc = jcp_.nb_load;
+ const int nb_oc_blocking = jcp_.nb_load_blocking;
+ const int load_work = utils::div_up(nb_oc, nb_oc_blocking);
+
+ const int job_size
+ = nb_oc_blocking * nb_ic_blocking * ic_block * oc_block;
+ const int njobs_x = bcast_work;
+ const int njobs_y = jcp_.ngroups * load_work;
+
+ const int max_threads = mkldnn_get_max_threads();
+ const size_t max_buffer_size = max_threads * job_size * 8;
+
+ if (with_bias()) {
+ reducer_bia_conf_.init(reduce_balancer_t(max_threads,
+ oc_block, jcp_.ngroups * jcp_.oc / oc_block,
+ jcp_.mb, max_buffer_size));
+ }
+
+ reducer_wei_conf_.init(
+ reduce_balancer_t(max_threads, job_size, njobs_y * njobs_x,
+ jcp_.mb * jcp_.nb_reduce, max_buffer_size),
+ job_size / nb_oc_blocking, nb_oc_blocking, ic_block,
+ nb_ic * ic_block * oc_block, nb_oc);
+ }
+ };
+
+ template <cpu_isa_t isa, typename conv_t>
+ friend void init_rtus_driver(conv_t *self);
+
+ jit_avx2_1x1_convolution_bwd_weights_t(const pd_t *apd);
+
+ ~jit_avx2_1x1_convolution_bwd_weights_t() {
+ delete kernel_;
+ delete rtus_driver_;
+ delete reducer_weights_;
+ delete reducer_bias_;
+ }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_weights(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_weights(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx2_1x1_conv_kernel_f32 *kernel_;
+ cpu_reducer_2d_t<data_type::f32> *reducer_weights_;
+ cpu_reducer_t<data_type::f32> *reducer_bias_;
+ rtus_driver_t<avx2> *rtus_driver_;
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.cpp
new file mode 100644
index 0000000000..e24770a2da
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.cpp
@@ -0,0 +1,1501 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+* Copyright 2018 YANDEX LLC
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+#include "cpu_memory.hpp"
+
+#include "jit_avx2_conv_kernel_f32.hpp"
+
+#define GET_OFF(field) offsetof(jit_conv_call_s, field)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+
+using namespace Xbyak;
+
+void jit_avx2_conv_fwd_kernel_f32::oh_step_unroll_kw(int ur_w,
+ int pad_l, int pad_r, int oc_blocks)
+{
+ int iw = jcp.iw;
+ int ih = jcp.ih;
+ int id = jcp.id;
+ int kw = jcp.kw;
+ int kh = jcp.kh;
+ int kd = jcp.kd;
+ int nb_ic = jcp.nb_ic;
+ int stride_w = jcp.stride_w;
+ int dilate_w = jcp.dilate_w + 1;
+ int ic_blk = jcp.ic_block;
+ int oc_blk = jcp.oc_block;
+
+ for (int ki = 0; ki < kw; ki++) {
+ int jj_start = nstl::max(0, div_up(pad_l - ki * dilate_w, stride_w));
+ int jj_end = ur_w
+ - nstl::max(0, div_up(ki*dilate_w+pad_r-(kw-1)*dilate_w, stride_w));
+ for (int ifm2 = 0; ifm2 < ic_blk; ifm2++) {
+ for (int jj = jj_start; jj < jj_end; jj++) {
+ size_t inp_off;
+ if (one_of(jcp.src_tag, ncw, nchw, ncdhw))
+ inp_off = sizeof(float)*((size_t)ifm2*id*ih*iw
+ + (ki*dilate_w + jj*stride_w - pad_l));
+ else
+ inp_off = sizeof(float)*((ki*dilate_w + jj*stride_w
+ - pad_l)*ic_blk + ifm2);
+ vbroadcastss(Ymm(oc_blocks * ur_w + jj),
+ make_safe_addr(aux_reg_input, inp_off, reg_long_offt));
+ }
+
+ for (int ii = 0; ii < oc_blocks; ii++) {
+ int ker_off = ii * nb_ic * kd * kh * kw * ic_blk * oc_blk
+ + ki * ic_blk * oc_blk + ifm2 * oc_blk;
+ vmovups(ymm15, ptr[aux_reg_kernel + sizeof(float) * ker_off]);
+ for (int jj = jj_start; jj < jj_end; jj++)
+ if (mayiuse(avx2))
+ vfmadd231ps(Ymm(ur_w * ii + jj),
+ Ymm(oc_blocks * ur_w + jj), ymm15);
+ else { // Intel(R) Advanced Vector Extensions (Intel(R) AVX) support
+ vmulps(ytmp, ymm15, Ymm(oc_blocks * ur_w + jj));
+ vaddps(Ymm(ur_w * ii + jj), Ymm(ur_w * ii + jj), ytmp);
+ }
+ }
+ }
+ }
+}
+
+void jit_avx2_conv_fwd_kernel_f32::oh_step_nopad(int ur_w,
+ int pad_l, int pad_r, char pad_tag,
+ int oc_blocks, char oc_blocks_tag)
+{
+ Label kw_loop;
+
+ int iw = jcp.iw;
+ int ih = jcp.ih;
+ int id = jcp.id;
+ int kw = jcp.kw;
+ int kh = jcp.kh;
+ int kd = jcp.kd;
+ int nb_ic = jcp.nb_ic;
+ int stride_w = jcp.stride_w;
+ int dilate_w = jcp.dilate_w + 1;
+ int ic_blk = jcp.ic_block;
+ int oc_blk = jcp.oc_block;
+
+ xor_(ki_iter, ki_iter);
+ L(kw_loop);
+ {
+ int jj_start = 0;
+ int jj_end = ur_w;
+ for (int ifm2 = 0; ifm2 < ic_blk; ifm2++) {
+ for (int jj = jj_start; jj < jj_end; jj++) {
+ size_t inp_off;
+ if (one_of(jcp.src_tag, ncw, nchw, ncdhw))
+ inp_off = sizeof(float)*((size_t)ifm2 * id * ih * iw
+ + (jj * stride_w - pad_l));
+ else
+ inp_off = sizeof(float)*((jj * stride_w - pad_l) * ic_blk
+ + ifm2);
+ vbroadcastss(Ymm(oc_blocks * ur_w + jj),
+ make_safe_addr(aux_reg_input, inp_off, reg_long_offt));
+ }
+ for (int ii = 0; ii < oc_blocks; ii++) {
+ int aux_kernel_offset =
+ ii * nb_ic * kd * kh * kw * ic_blk * oc_blk + ifm2 * oc_blk;
+ vmovups(ymm15, ptr[aux_reg_kernel
+ + sizeof(float) * aux_kernel_offset]);
+ for (int jj = jj_start; jj < jj_end; jj++)
+ if (mayiuse(avx2))
+ vfmadd231ps(Ymm(ur_w * ii + jj),
+ Ymm(oc_blocks * ur_w + jj), ymm15);
+ else { // Intel AVX support
+ vmulps(ytmp, ymm15, Ymm(oc_blocks * ur_w + jj));
+ vaddps(Ymm(ur_w * ii + jj), Ymm(ur_w * ii + jj), ytmp);
+ }
+ }
+ }
+ add(aux_reg_kernel, sizeof(float) * oc_blk * ic_blk);
+ add(aux_reg_input, sizeof(float) * (one_of(jcp.src_tag, ncw, nchw, ncdhw)
+ ? dilate_w : ic_blk * dilate_w));
+
+ inc(ki_iter);
+ cmp(ki_iter, kw);
+ jl(kw_loop, T_NEAR);
+ }
+}
+
+void jit_avx2_conv_fwd_kernel_f32::width_blk_step(int ur_w,
+ int pad_l, int pad_r, char pad_tag,
+ int oc_blocks, char oc_blocks_tag)
+{
+ int iw = jcp.iw;
+ int kw = jcp.kw;
+ int ow = jcp.ow;
+ int oh = jcp.oh;
+ int od = jcp.od;
+ int dilate_h = jcp.dilate_h + 1;
+ int dilate_w = jcp.dilate_w + 1;
+ int ic_blk = jcp.ic_block;
+ int oc_blk = jcp.oc_block;
+ const int inp_mult = one_of(jcp.src_tag, ncw, nchw, ncdhw)
+ ? 1 : ic_blk;
+ const int inp_off = one_of(jcp.src_tag, ncw, nchw, ncdhw)
+ ? dilate_w : ic_blk * dilate_w;
+
+ Label init_done, init_first;
+
+ if (!jcp.with_sum) {
+ test(reg_ci_flag, FLAG_IC_FIRST);
+ jne(init_first, T_NEAR);
+ }
+
+ for (int ii = 0; ii < oc_blocks; ii++) {
+ for (int jj = 0; jj < ur_w; jj++) {
+ size_t offt =
+ sizeof(float) * ((size_t)ii * od * oh * ow + jj) * oc_blk;
+ vmovups(Ymm(ur_w * ii + jj),
+ make_safe_addr(reg_output, offt, reg_long_offt));
+ }
+ }
+
+ if (jcp.with_sum && jcp.with_bias) {
+ test(reg_ci_flag, FLAG_IC_FIRST);
+ je(init_done, T_NEAR);
+
+ for (int ii = 0; ii < oc_blocks; ii++)
+ for (int jj = 0; jj < ur_w; jj++)
+ vaddps(Ymm(ur_w * ii + jj), Ymm(ur_w * ii + jj),
+ yword[reg_bias + sizeof(float) * ii * oc_blk]);
+ }
+
+ jmp(init_done);
+
+ L(init_first);
+ if (this->jcp.with_bias) {
+ for (int ii = 0; ii < oc_blocks; ii++)
+ for (int jj = 0; jj < ur_w; jj++)
+ vmovups(Ymm(ur_w * ii + jj),
+ yword[reg_bias + sizeof(float) * ii * oc_blk]);
+ } else {
+ for (int ii = 0; ii < oc_blocks; ii++)
+ for (int jj = 0; jj < ur_w; jj++)
+ uni_vpxor(Ymm(ur_w * ii + jj), Ymm(ur_w * ii + jj), Ymm(ur_w * ii + jj));
+ }
+
+ L(init_done);
+
+ if (one_of(jcp.ndims, 3, 4)) {
+ mov(aux_reg_input, reg_input);
+ mov(aux_reg_kernel, reg_kernel);
+ }
+
+ Label skip_kh_loop, skip_kd_loop, kd_loop;
+ if (jcp.ndims == 5) {
+ push(reg_output);
+ push(oi_iter);
+
+ mov(reg_ki, ptr[param1 + GET_OFF(kd_padding)]);
+ mov(aux_reg_ker_d, ptr[param1 + GET_OFF(filt)]);
+ mov(aux_reg_inp_d, reg_input);
+
+ if ((jcp.dilate_d >= jcp.id)
+ || (jcp.kd - 1) * (jcp.dilate_d + 1) < jcp.f_pad) {
+ cmp(reg_ki, 0);
+ je(skip_kd_loop, T_NEAR);
+ }
+ L(kd_loop);
+ mov(kj, ptr[param1 + GET_OFF(kh_padding)]);
+ } else {
+ mov(kj, reg_kh);
+ }
+
+ if (jcp.ndims == 5) {
+ mov(aux_reg_input, aux_reg_inp_d);
+ mov(aux_reg_kernel, aux_reg_ker_d);
+ }
+
+ if ((jcp.dilate_h >= jcp.ih)
+ || (jcp.kh - 1) * (jcp.dilate_h + 1) < nstl::max(jcp.t_pad, jcp.b_pad)) {
+ cmp(kj, 0);
+ je(skip_kh_loop, T_NEAR);
+ }
+ Label kh_loop;
+ L(kh_loop);
+ {
+ if (jcp.kw >= 5 && pad_l == 0 && pad_r == 0) {
+ oh_step_nopad(ur_w, pad_l, pad_r, pad_tag, oc_blocks,
+ oc_blocks_tag);
+ sub(aux_reg_input, sizeof(float) * kw * inp_off);
+ add(aux_reg_input, sizeof(float) * iw * dilate_h * inp_mult);
+ } else {
+ oh_step_unroll_kw(ur_w, pad_l, pad_r, oc_blocks);
+ add(aux_reg_kernel, sizeof(float) * kw * oc_blk * ic_blk);
+ add(aux_reg_input, sizeof(float) * iw * dilate_h * inp_mult);
+ }
+
+ dec(kj);
+ cmp(kj, 0);
+ jg(kh_loop, T_NEAR);
+ }
+
+ L(skip_kh_loop);
+
+ if (jcp.ndims == 5) {
+ add(aux_reg_inp_d,
+ sizeof(float) * (jcp.dilate_d + 1) * jcp.ih * jcp.iw * inp_mult);
+ add(aux_reg_ker_d, sizeof(float) * jcp.kw * jcp.kh * jcp.oc_block
+ * jcp.ic_block);
+
+ dec(reg_ki);
+ cmp(reg_ki, 0);
+ jg(kd_loop, T_NEAR);
+ L(skip_kd_loop);
+
+ pop(oi_iter);
+ pop(reg_output);
+ }
+
+ Label regular_store;
+
+ if (jcp.with_eltwise) {
+ test(reg_ci_flag, FLAG_IC_LAST);
+ je(regular_store, T_NEAR);
+
+ eltwise_injector_->compute_vector_range(0, oc_blocks * ur_w);
+
+ L(regular_store);
+ }
+
+ for (int ii = 0; ii < oc_blocks; ii++) {
+ for (int jj = 0; jj < ur_w; jj++) {
+ const size_t o_off
+ = sizeof(float) * ((size_t)ii * od * oh * ow + jj) * oc_blk;
+ Ymm reg_out = Ymm(ur_w * ii + jj);
+ vmovups(make_safe_addr(reg_output, o_off, reg_long_offt), reg_out);
+ }
+ }
+}
+
+inline void jit_avx2_conv_fwd_kernel_f32::solve_common(
+ int oc_blocks, char oc_blocks_tag)
+{
+ int ur_w = jcp.ur_w;
+ int ur_w_tail = jcp.ur_w_tail;
+ int n_oi = jcp.ow / ur_w;
+ int iw = jcp.iw;
+ int kw = jcp.kw;
+ int ic_blk = jcp.ic_block;
+ int oc_blk = jcp.oc_block;
+ int dilate_w = jcp.dilate_w + 1;
+ int str_w = jcp.stride_w;
+ const int inp_mult = one_of(jcp.src_tag, ncw, nchw, ncdhw) ? 1 : ic_blk;
+
+ int l_pad = jcp.l_pad;
+ int r_pad = nstl::max(0, (int(jcp.ow) - 1) * str_w + (kw - 1) * dilate_w
+ - (iw + l_pad - 1));
+ int r_pad1 = (ur_w * n_oi - 1) * str_w + (kw - 1) * dilate_w
+ - (iw + l_pad - 1);
+ if (r_pad1 > 0) n_oi--;
+
+ if (l_pad > 0) {
+ n_oi--;
+ if (n_oi < 0 && r_pad1 > 0)
+ width_blk_step(ur_w, l_pad, r_pad1,
+ 'l', oc_blocks, oc_blocks_tag); // "lrpad"
+ else
+ width_blk_step(ur_w, l_pad, 0,
+ 'l', oc_blocks, oc_blocks_tag); // "lpad"
+ add(reg_input, sizeof(float) * (ur_w * str_w - l_pad) * inp_mult);
+ add(reg_output, sizeof(float) * ur_w * oc_blk);
+ }
+
+ Label ow_loop;
+ xor_(oi_iter, oi_iter);
+
+ if (n_oi > 0) {
+ L(ow_loop);
+
+ width_blk_step(ur_w, 0, 0,
+ 'm', oc_blocks, oc_blocks_tag); // "middle"
+ add(reg_input, sizeof(float) * ur_w * str_w * inp_mult);
+ add(reg_output, sizeof(float) * ur_w * oc_blk);
+
+ inc(oi_iter);
+ cmp(oi_iter, n_oi);
+ jl(ow_loop, T_NEAR);
+ }
+
+ if (r_pad1 > 0 && n_oi >=0) {
+ width_blk_step(ur_w, 0, r_pad1,
+ 'r', oc_blocks, oc_blocks_tag); // "rpad"
+ add(reg_input, sizeof(float) * ur_w * str_w * inp_mult);
+ add(reg_output, sizeof(float) * ur_w * oc_blk);
+ }
+
+ if (ur_w_tail != 0)
+ width_blk_step(ur_w_tail, 0, r_pad,
+ 't', oc_blocks, oc_blocks_tag); // "tail"
+}
+
+void jit_avx2_conv_fwd_kernel_f32::generate()
+{
+ this->preamble();
+
+ mov(reg_input, ptr[this->param1 + GET_OFF(src)]);
+ mov(reg_output, ptr[this->param1 + GET_OFF(dst)]);
+ mov(reg_kernel, ptr[this->param1 + GET_OFF(filt)]);
+ if (jcp.with_bias)
+ mov(reg_bias, ptr[this->param1 + GET_OFF(bias)]);
+ mov(reg_kh, ptr[this->param1 + GET_OFF(kh_padding)]);
+ mov(reg_ci_flag, ptr[this->param1 + GET_OFF(flags)]);
+ mov(reg_oc_blocks, ptr[this->param1 + GET_OFF(oc_blocks)]);
+
+ int nb_oc_tail = jcp.nb_oc % jcp.nb_oc_blocking;
+ Label tail, exit;
+
+ if (jcp.nb_oc > jcp.nb_oc_blocking) {
+ cmp(reg_oc_blocks, jcp.nb_oc_blocking);
+ jne(nb_oc_tail ? tail : exit, T_NEAR);
+
+ solve_common(jcp.nb_oc_blocking, '0' + jcp.nb_oc_blocking);
+ jmp(exit, T_NEAR);
+
+ if (nb_oc_tail) {
+ L(tail);
+ cmp(reg_oc_blocks, nb_oc_tail);
+ jne(exit, T_NEAR);
+ solve_common(nb_oc_tail, '0' + nb_oc_tail);
+ }
+
+ L(exit);
+ } else if (jcp.nb_oc == jcp.nb_oc_blocking) {
+ solve_common(jcp.nb_oc_blocking, '0' + jcp.nb_oc_blocking);
+ } else {
+ solve_common(nb_oc_tail, '0' + nb_oc_tail);
+ }
+
+ this->postamble();
+
+ if (jcp.with_eltwise)
+ eltwise_injector_->prepare_table();
+}
+
+bool jit_avx2_conv_fwd_kernel_f32::post_ops_ok(
+ jit_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ const auto &p = attr.post_ops_;
+
+ auto is_eltwise = [&](int idx) { return p.entry_[idx].is_eltwise(); };
+ auto is_sum = [&](int idx) { return p.entry_[idx].is_sum(); };
+
+ switch (p.len_) {
+ case 0: return true; // no post_ops
+ case 1: return is_eltwise(0) || is_sum(0); // sum OR eltwise
+ case 2: return is_sum(0) && is_eltwise(1); // sum -> eltwise
+ default: return false;
+ }
+
+ return false;
+}
+
+status_t jit_avx2_conv_fwd_kernel_f32::init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d, const memory_desc_wrapper &dst_d,
+ const primitive_attr_t &attr)
+{
+ if (!mayiuse(avx)) return status::unimplemented;
+
+ jcp.prop_kind = cd.prop_kind;
+
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+ int ndims = src_d.ndims();
+ jcp.ndims = ndims;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+
+ jcp.id = (ndims == 5) ? src_d.dims()[2] : 1;
+ jcp.ih = (ndims == 3) ? 1 : src_d.dims()[ndims-2];
+ jcp.iw = src_d.dims()[ndims-1];
+ jcp.od = (ndims == 5) ? dst_d.dims()[2] : 1;
+ jcp.oh = (ndims == 3) ? 1 :dst_d.dims()[ndims-2];
+ jcp.ow = dst_d.dims()[ndims-1];
+ jcp.kd = (ndims == 5) ? weights_d.dims()[with_groups + 2] : 1;
+ jcp.kh = (ndims == 3) ? 1 : weights_d.dims()[with_groups + ndims-2];
+ jcp.kw = weights_d.dims()[with_groups + ndims-1];
+
+ jcp.f_pad = (ndims == 5) ? cd.padding[0][0] : 0;
+ jcp.t_pad = (ndims == 3) ? 0 : cd.padding[0][ndims-4];
+ jcp.l_pad = cd.padding[0][ndims-3];
+ jcp.stride_d = (ndims == 5) ? cd.strides[0] : 1;
+ jcp.stride_h = (ndims == 3) ? 1 :cd.strides[ndims-4];
+ jcp.stride_w = cd.strides[ndims-3];
+
+ jcp.dilate_d = (ndims == 5) ? cd.dilates[0] : 0;
+ jcp.dilate_h = (ndims == 3) ? 0 : cd.dilates[ndims-4];
+ jcp.dilate_w = cd.dilates[ndims-3];
+
+ jcp.b_pad = (jcp.oh - 1) * jcp.stride_h + (jcp.kh - 1) * (jcp.dilate_h + 1)
+ - (jcp.ih + jcp.t_pad - 1);
+
+ if (ndims == 3) {
+ jcp.src_tag = src_d.matches_one_of_tag(ncw, nwc, nCw8c);
+ jcp.wei_tag = weights_d.matches_one_of_tag(
+ Owi8o, gOwi8o, OIw8i8o, gOIw8i8o);
+ jcp.dst_tag = dst_d.matches_one_of_tag(nCw8c);
+ } else if (ndims == 4) {
+ jcp.src_tag = src_d.matches_one_of_tag(nchw, nhwc, nChw8c);
+ jcp.wei_tag = weights_d.matches_one_of_tag(
+ Ohwi8o, gOhwi8o, OIhw8i8o, gOIhw8i8o);
+ jcp.dst_tag = dst_d.matches_one_of_tag(nChw8c);
+ } else if (ndims == 5) {
+ jcp.src_tag = src_d.matches_one_of_tag(ncdhw, ndhwc, nCdhw8c);
+ jcp.wei_tag = weights_d.matches_one_of_tag(
+ Odhwi8o, gOdhwi8o, OIdhw8i8o, gOIdhw8i8o);
+ jcp.dst_tag = dst_d.matches_one_of_tag(nCdhw8c);
+ }
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ jcp.with_sum = p.find(primitive_kind::sum) != -1;
+ const int eltwise_ind = p.find(primitive_kind::eltwise);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise) {
+ jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+ if (!mayiuse(avx2) && jcp.eltwise.alg != alg_kind::eltwise_relu)
+ return status::unimplemented;
+ }
+
+ const int simd_w = 8;
+ const bool flat = jcp.ic < simd_w;
+ const bool mimo = !flat;
+
+
+ /* Grouped channel offset to support 'non-blocked data' format for
+ * convolution sizes with '(input_channel / ngroups) < simd' */
+ jcp.nonblk_group_off =
+ one_of(jcp.src_tag, ncw, nchw, ncdhw) && jcp.ngroups > 1 ? jcp.ic : 1;
+
+ bool ok_to_pad_channels = true
+ && jcp.ngroups == 1;
+
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ if (mimo)
+ jcp.ic = rnd_up(jcp.ic, simd_w);
+ }
+
+ bool args_ok = true
+ && IMPLICATION(flat, true
+ && one_of(jcp.src_tag, ncw, nwc, nchw, nhwc, ncdhw, ndhwc)
+ && one_of(jcp.wei_tag, Owi8o, gOwi8o, Ohwi8o, gOhwi8o, Odhwi8o,
+ gOdhwi8o))
+ && IMPLICATION(mimo, true
+ && one_of(jcp.src_tag, nCw8c, nChw8c, nCdhw8c)
+ && one_of(jcp.wei_tag, OIw8i8o, gOIw8i8o, OIhw8i8o, gOIhw8i8o,
+ OIdhw8i8o, gOIdhw8i8o))
+ && one_of(jcp.dst_tag, nCw8c, nChw8c, nCdhw8c);
+ if (!args_ok) return status::unimplemented;
+
+ jcp.ur_h = 1; /* no code-unrolling by h so far */
+ jcp.ur_w = 3;
+
+ jcp.oc_block = simd_w;
+ jcp.nb_oc = jcp.oc / jcp.oc_block;
+
+ jcp.nb_oc_blocking = 4; /* the optimal value for the kernel */
+
+ // Intel AVX and Intel AVX2 kernels need 2 and 1 temporary YMMs, respectively
+ // Thus, we can only assign 14 or 15 YMMs for data storage
+ const int num_avail_regs = mayiuse(avx2) ? 15 : 14;
+ if (!mayiuse(avx2)) {
+ if ((jcp.nb_oc_blocking + 1) * jcp.ur_w > num_avail_regs) {
+ // current register assignment requires more YMMs than available
+ // adjust one of nb_oc_block, ur_w preserving to ur_w >= l_pad
+ if (jcp.ur_w > jcp.l_pad && jcp.ur_w > 1)
+ jcp.ur_w -= 1;
+ else
+ for (int b = 3; b > 1; b--)
+ if (jcp.nb_oc % b == 0) {
+ jcp.nb_oc_blocking = b;
+ break;
+ }
+ }
+ }
+
+ if (jcp.ow < jcp.ur_w) jcp.ur_w = jcp.ow;
+ jcp.ur_w_tail = jcp.ow % jcp.ur_w;
+
+ args_ok = true
+ && jcp.oc % simd_w == 0
+ && jcp.l_pad <= jcp.ur_w
+ && IMPLICATION(jcp.kw > 7, (jcp.t_pad == 0 && jcp.l_pad == 0)
+ || (jcp.stride_w == 1 && jcp.stride_h == 1))
+ && IMPLICATION(mimo, jcp.ic % simd_w == 0);
+ if (!args_ok) return status::unimplemented;
+
+ int r_pad_no_tail = nstl::max(0, (jcp.ow - jcp.ur_w_tail - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1) - (jcp.iw + jcp.l_pad - 1));
+
+ if (r_pad_no_tail > jcp.ur_w * jcp.stride_w && jcp.ow / jcp.ur_w > 1) {
+ /* recalculate ur_w, nb_oc_blocking and ur_w_tail */
+ jcp.ur_w = nstl::min(r_pad_no_tail / jcp.stride_w + jcp.ur_w_tail,
+ nstl::min(jcp.ow, num_avail_regs / 2));
+ jcp.nb_oc_blocking = (num_avail_regs - jcp.ur_w) / jcp.ur_w;
+ jcp.ur_w_tail = jcp.ow % jcp.ur_w;
+ /* check again ... */
+ r_pad_no_tail = nstl::max(0, (jcp.ow - jcp.ur_w_tail - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1) - (jcp.iw + jcp.l_pad - 1));
+ if (jcp.ur_w < nstl::max(jcp.l_pad, r_pad_no_tail))
+ return status::unimplemented;
+ }
+ assert(jcp.nb_oc_blocking > 0);
+ assert(jcp.ur_w * (jcp.nb_oc_blocking + 1) <= num_avail_regs);
+
+ jcp.ic_block = (jcp.ic % simd_w != 0) ? jcp.ic : simd_w;
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+
+ if (one_of(jcp.prop_kind, forward_training, forward_inference)) {
+ jcp.nb_ic_blocking = 12;
+ jcp.nb_ic_blocking_max = 16;
+ } else {
+ jcp.nb_ic_blocking = 1;
+ jcp.nb_ic_blocking_max = jcp.nb_ic_blocking;
+ }
+
+ return status::success;
+}
+
+void jit_avx2_conv_fwd_kernel_f32::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad, const jit_conv_conf_t &jcp) {
+ if (jcp.with_bias && jcp.oc != jcp.oc_without_padding)
+ scratchpad.book(key_conv_padded_bias, sizeof(float) * jcp.oc);
+}
+
+void jit_avx2_conv_bwd_data_kernel_f32::compute_loop(int ur_w, int l_overflow,
+ int r_overflow)
+{
+ int kw = jcp.kw;
+ int kh = jcp.kh;
+ int kd = jcp.kd;
+ int iw = jcp.iw;
+ int ih = jcp.ih;
+ int id = jcp.id;
+ int ow = jcp.ow;
+
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ int nb_ic_block = jcp.nb_ic_blocking;
+ int stride_w = jcp.stride_w;
+ int stride_h = jcp.stride_h;
+
+ Label kd_loop, skip_kd_loop;
+ Label oc_loop, skip_oc_loop;
+
+ for (int ii = 0; ii < nb_ic_block; ii++)
+ for (int jj = 0; jj < ur_w; jj++) {
+ uni_vpxor(Ymm(ur_w * ii + jj), Ymm(ur_w * ii + jj),
+ Ymm(ur_w * ii + jj));
+ }
+
+ if (one_of(jcp.ndims, 3, 4)) {
+ cmp(reg_channel_work, 0);
+ jle(skip_oc_loop, T_NEAR);
+ xor_(reg_channel, reg_channel);
+
+ mov(aux_reg_ddst_oc_loop, reg_ddst);
+ mov(aux_reg_kernel_oc_loop, reg_kernel);
+
+ L(oc_loop);
+ mov(aux_reg_ddst, aux_reg_ddst_oc_loop);
+ mov(aux_reg_kernel, aux_reg_kernel_oc_loop);
+ }
+
+ if (jcp.ndims == 5) {
+ assert(jcp.nb_oc_blocking == 1);
+ push(oi_iter);
+
+ mov(reg_ki, ptr[this->param1 + GET_OFF(kd_padding)]);
+ mov(aux_reg_dst_d, reg_ddst);
+ mov(aux_reg_ker_d, ptr[this->param1 + GET_OFF(filt)]);
+
+ L(kd_loop);
+ mov(kj, ptr[this->param1 + GET_OFF(kh_padding)]);
+ } else {
+ mov(kj, reg_kh);
+ }
+
+ if (jcp.ndims == 5) {
+ mov(aux_reg_ddst, aux_reg_dst_d);
+ mov(aux_reg_kernel, aux_reg_ker_d);
+ }
+
+ Label kh_loop, skip_kh_loop;
+ cmp(kj, 0);
+ jle(skip_kh_loop, T_NEAR);
+ L(kh_loop); {
+ for (int ki = 0; ki < kw; ki++) {
+ int jj_start = get_iw_start(ki, l_overflow); // 0;
+ int jj_end = get_iw_end(ur_w, ki, r_overflow); // ur_w;
+ for (int ofm2 = 0; ofm2 < jcp.oc_block; ofm2++) {
+
+ for (int jj = jj_start ; jj < jj_end; jj += stride_w) {
+ int aux_output_offset
+ = (jj + jcp.l_pad - ki) / stride_w * jcp.oc_block + ofm2;
+ vbroadcastss(Ymm(nb_ic_block * ur_w + jj / stride_w),
+ ptr[aux_reg_ddst
+ + sizeof(float) * aux_output_offset]);
+ }
+
+ for (int ii = 0; ii < nb_ic_block; ii++) {
+ int aux_kernel_offset
+ = ii * kd * kh * kw * jcp.ic_block * jcp.oc_block
+ + ki * jcp.ic_block * jcp.oc_block
+ + ofm2 * jcp.ic_block;
+ vmovups(ymm15,
+ ptr[aux_reg_kernel
+ + sizeof(float) * aux_kernel_offset]);
+ for (int jj = jj_start; jj < jj_end; jj += stride_w)
+ vfmadd231ps(Ymm(ur_w * ii + jj),
+ Ymm(nb_ic_block * ur_w + jj / stride_w), ymm15);
+ }
+ }
+ }
+ add(aux_reg_kernel, sizeof(float) * stride_h * kw * oc_block
+ * ic_block);
+ sub(aux_reg_ddst, sizeof(float) * ow * oc_block);
+
+ dec(kj);
+ cmp(kj, 0);
+ jg(kh_loop, T_NEAR);
+ }
+ L(skip_kh_loop);
+
+ if (jcp.ndims == 5) {
+ sub(aux_reg_dst_d,
+ sizeof(float) * (jcp.dilate_d + 1) * jcp.oh * ow * ic_block);
+ add(aux_reg_ker_d,
+ sizeof(float) * jcp.kw * jcp.kh * oc_block * ic_block);
+
+ dec(reg_ki);
+ cmp(reg_ki, 0);
+ jg(kd_loop, T_NEAR);
+ L(skip_kd_loop);
+
+ pop(oi_iter);
+ }
+
+ if (one_of(jcp.ndims, 3, 4)) {
+ int ddst_oc_shift = sizeof(float) * jcp.od * jcp.oh * jcp.ow
+ * jcp.oc_block;
+ int kernel_oc_shift = sizeof(float) * jcp.kd * jcp.kh * jcp.kw
+ * jcp.ic * jcp.oc_block;
+
+ add(aux_reg_ddst_oc_loop, ddst_oc_shift);
+ add(aux_reg_kernel_oc_loop, kernel_oc_shift);
+
+ inc(reg_channel);
+ cmp(reg_channel, reg_channel_work);
+ jl(oc_loop, T_NEAR);
+
+ L(skip_oc_loop);
+ mov(reg_channel, ptr[param1 + GET_OFF(channel)]);
+ }
+
+ Label no_update_label;
+ cmp(reg_channel, 0);
+ je(no_update_label, T_NEAR);
+ for (int ii = 0; ii < nb_ic_block; ii++) {
+ for (int jj = 0; jj < ur_w; jj++) {
+ size_t offt =
+ sizeof(float) * ((size_t)ii * id * ih * iw + jj) * ic_block;
+ vmovups(Ymm(15),
+ make_safe_addr(reg_dsrc, offt, reg_long_offt));
+ vaddps(Ymm(ur_w * ii + jj), Ymm(ur_w * ii + jj),
+ Ymm(15));
+
+ }
+ }
+ L(no_update_label);
+
+ for (int ii = 0; ii < nb_ic_block; ii++)
+ for (int jj = 0; jj < ur_w; jj++) {
+ size_t offt =
+ sizeof(float) * ((size_t)ii * id * ih * iw + jj) * ic_block;
+ vmovups(make_safe_addr(reg_dsrc, offt, reg_long_offt),
+ Ymm(ur_w * ii + jj));
+ }
+}
+
+void jit_avx2_conv_bwd_data_kernel_f32::generate() {
+ preamble();
+
+ mov(reg_dsrc, ptr[this->param1 + GET_OFF(src)]);
+ mov(reg_ddst, ptr[this->param1 + GET_OFF(dst)]);
+ mov(reg_kernel, ptr[this->param1 + GET_OFF(filt)]);
+ mov(reg_kh, ptr[this->param1 + GET_OFF(kh_padding)]);
+ mov(reg_channel, ptr[param1 + GET_OFF(channel)]);
+ mov(reg_channel_work, ptr[param1 + GET_OFF(ch_blocks)]);
+
+ int ddst_shift = sizeof(float) * (jcp.ur_w / jcp.stride_w) * jcp.ic_block;
+ int dsrc_shift = sizeof(float) * jcp.ur_w * jcp.oc_block;
+
+ int l_overflow = nstl::max(0, (jcp.kw - 1 - jcp.l_pad) / jcp.stride_w);
+ int r_overflow = nstl::max(0, (jcp.kw - 1
+ - nstl::max(0, jcp.r_pad)) / jcp.stride_w);
+ int r_overflow1 = nstl::max(0, (jcp.kw - 1
+ - nstl::max(0, jcp.r_pad) - jcp.ur_w_tail) / jcp.stride_w);
+
+ int n_oi = jcp.iw / jcp.ur_w;
+ if (r_overflow1 > 0)
+ n_oi--;
+
+ if (jcp.ur_w == jcp.iw) {
+ compute_loop(jcp.ur_w, l_overflow, r_overflow);
+ } else if (n_oi == 0) {
+ compute_loop(jcp.ur_w, l_overflow, r_overflow1);
+ add(reg_dsrc, dsrc_shift);
+ add(reg_ddst, ddst_shift);
+ if (jcp.ur_w_tail != 0)
+ compute_loop(jcp.ur_w_tail, 0, r_overflow);
+ } else {
+ xor_(oi_iter, oi_iter);
+ if (l_overflow > 0) {
+ compute_loop(jcp.ur_w, l_overflow, 0);
+ add(reg_dsrc, dsrc_shift);
+ add(reg_ddst, ddst_shift);
+ inc(oi_iter);
+ }
+
+ if ((l_overflow <= 0 && n_oi > 0) || (l_overflow > 0 && n_oi > 1)) {
+ Label ow_loop;
+ L(ow_loop); {
+ compute_loop(jcp.ur_w, 0, 0);
+ add(reg_dsrc, dsrc_shift);
+ add(reg_ddst, ddst_shift);
+ inc(oi_iter);
+ cmp(oi_iter, n_oi); jl(ow_loop, T_NEAR);
+ }
+ }
+
+ if (r_overflow1 > 0 ) {
+ compute_loop(jcp.ur_w, 0, r_overflow1);
+ add(reg_dsrc, dsrc_shift);
+ add(reg_ddst, ddst_shift);
+ }
+
+ if (jcp.ur_w_tail != 0)
+ compute_loop(jcp.ur_w_tail, 0, r_overflow);
+ }
+
+ this->postamble();
+}
+
+status_t jit_avx2_conv_bwd_data_kernel_f32::init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &diff_src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &diff_dst_d)
+{
+ if (!mayiuse(avx2)) return status::unimplemented;
+
+ const bool with_groups = weights_d.ndims() == diff_src_d.ndims() + 1;
+
+ int ndims = diff_src_d.ndims();
+ jcp.ndims = ndims;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = diff_src_d.dims()[0];
+
+ jcp.oc = diff_dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = diff_src_d.dims()[1] / jcp.ngroups;
+
+ jcp.id = (ndims == 5) ? diff_src_d.dims()[2] : 1;
+ jcp.ih = (ndims == 3) ? 1 : diff_src_d.dims()[ndims-2];
+ jcp.iw = diff_src_d.dims()[ndims-1];
+ jcp.od = (ndims == 5) ? diff_dst_d.dims()[2] : 1;
+ jcp.oh = (ndims == 3) ? 1 : diff_dst_d.dims()[ndims-2];
+ jcp.ow = diff_dst_d.dims()[ndims-1];
+
+ jcp.kd = (ndims == 5) ? weights_d.dims()[with_groups + 2] : 1;
+ jcp.kh = (ndims == 3) ? 1 : weights_d.dims()[with_groups + ndims - 2];
+ jcp.kw = weights_d.dims()[with_groups + ndims - 1];
+
+ jcp.f_pad = (ndims == 5) ? cd.padding[0][0] : 0;
+ jcp.t_pad = (ndims == 3) ? 0 : cd.padding[0][ndims-4];
+ jcp.l_pad = cd.padding[0][ndims-3];
+
+ jcp.stride_d = (ndims == 5) ? cd.strides[0] : 1;
+ jcp.stride_h = (ndims == 3) ? 1 : cd.strides[ndims-4];
+ jcp.stride_w = cd.strides[ndims-3];
+
+ jcp.dilate_d = (ndims == 5) ? cd.dilates[0] : 0;
+ jcp.dilate_h = (ndims == 3) ? 0 : cd.dilates[ndims-4];
+ jcp.dilate_w = cd.dilates[ndims-3];
+
+ const int simd_w = 8;
+
+ /* derivatives */
+ jcp.idp = jcp.id + 2 * jcp.f_pad;
+ jcp.ihp = jcp.ih + 2 * jcp.t_pad;
+ jcp.iwp = jcp.iw + 2 * jcp.l_pad;
+ jcp.ohp = jcp.oh; /* do we really need */
+ jcp.owp = jcp.ow; /* padded output ??? */
+
+ bool ok_to_pad_channels = true
+ && jcp.ngroups == 1;
+
+ /* gemm-based convolution performs better in these cases */
+ if (jcp.ic < simd_w && jcp.kw > 3 && jcp.stride_w > 1)
+ return status::unimplemented;
+
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ jcp.ic = rnd_up(jcp.ic, simd_w);
+ }
+
+ jcp.ic_block = (jcp.ic % simd_w) ? 1 : simd_w;
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+
+ jcp.oc_block = simd_w;
+ if (jcp.oc % jcp.oc_block) return status::unimplemented;
+ jcp.nb_oc = jcp.oc / jcp.oc_block;
+
+ jcp.ur_h = 1; /* no code-unrolling by h so far */
+ jcp.nb_ic_blocking = 1;
+ jcp.nb_oc_blocking = 1;
+ jcp.ur_w = 1;
+
+ if(one_of(ndims, 3, 4) && jcp.ow < 40)
+ jcp.nb_oc_blocking = jcp.ow < 15 ? 4 : 2;
+
+ if (ndims == 3) {
+ jcp.src_tag = diff_src_d.matches_one_of_tag(nCw8c);
+ jcp.wei_tag = weights_d.matches_one_of_tag(OIw8i8o, gOIw8o8i);
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(nCw8c);
+ } else if (ndims == 4) {
+ jcp.src_tag = diff_src_d.matches_one_of_tag(nChw8c);
+ jcp.wei_tag = weights_d.matches_one_of_tag(OIhw8o8i, gOIhw8o8i);
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(nChw8c);
+ } else if (ndims == 5) {
+ jcp.src_tag = diff_src_d.matches_one_of_tag(nCdhw8c);
+ jcp.wei_tag = weights_d.matches_one_of_tag(OIdhw8o8i, gOIdhw8o8i);
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(nCdhw8c);
+ }
+
+ bool args_ok = true
+ && one_of(jcp.src_tag, nCw8c, nChw8c, nCdhw8c)
+ && one_of(jcp.wei_tag, gOIw8o8i, OIw8i8o, gOIhw8o8i, OIhw8o8i,
+ gOIdhw8o8i, OIdhw8o8i)
+ && one_of(jcp.dst_tag, nCw8c, nChw8c, nCdhw8c)
+ && jcp.stride_w == jcp.stride_h
+ && jcp.stride_d == 1
+ && jcp.dilate_d == 0
+ && jcp.dilate_h == 0
+ && jcp.dilate_w == 0
+ && jcp.ic % simd_w == 0
+ && jcp.oc % simd_w == 0
+ && jcp.od == (jcp.idp - jcp.kd) / jcp.stride_d + 1
+ && jcp.oh == (jcp.ihp - jcp.kh) / jcp.stride_h + 1
+ && jcp.ow == (jcp.iwp - jcp.kw) / jcp.stride_w + 1;
+ if (!args_ok) return status::unimplemented;
+ jcp.r_pad = (jcp.ow - 1) * jcp.stride_w + jcp.kw - jcp.iw - jcp.l_pad;
+ jcp.b_pad = (jcp.oh - 1) * jcp.stride_h + jcp.kh - jcp.ih - jcp.t_pad;
+ int l_overflow = nstl::max(0, (jcp.kw - 1 - jcp.l_pad) / jcp.stride_w);
+
+ const int max_regs = 15; /* Maximun number of registers available for
+ result accumulation and delta dst data.
+ One additional register is reserved for weights
+ data. */
+
+ /* Find the best blocking with maximum number of fma instructions
+ per ur_w * nb_ic_blocking compute loops. Number of required registers
+ is num_regs = ur_w * nb_ic_blocking + ur_w / stride_w <= max_regs.
+ ur_w must be divisible by stride_w */
+ if (jcp.stride_w + 1 > max_regs) /* Minimal possible registers
+ distribution exceeds max_regs */
+ return status::unimplemented;
+
+ int best_nfmas = 0;
+ for (int b = 1; b <= 4; b++)
+ {
+ if (jcp.nb_ic % b != 0)
+ continue;
+
+ for (int u = jcp.stride_w;
+ u * b + u / jcp.stride_w <= max_regs && u < jcp.iw + jcp.stride_w;
+ u += jcp.stride_w)
+ {
+ int ur_w = nstl::min(u, jcp.iw);
+ /* maximum 1 step with l_overflow so far */
+ if (l_overflow * jcp.stride_w > ur_w && ur_w != jcp.iw)
+ continue;
+ int nfmas = utils::div_up(ur_w, jcp.stride_w) * b;
+ if (nfmas > best_nfmas
+ || (nfmas == best_nfmas && jcp.ur_w < ur_w)) {
+ jcp.ur_w = ur_w;
+ jcp.nb_ic_blocking = b;
+ best_nfmas = nfmas;
+ }
+ }
+ }
+ if (best_nfmas == 0) /* can't find appropriate blocking */
+ return status::unimplemented;
+
+ jcp.ur_w_tail = jcp.iw % jcp.ur_w;
+
+ int r_overflow_no_tail = nstl::max(0, (jcp.kw - 1 - jcp.ur_w_tail
+ - nstl::max(0, jcp.r_pad) - jcp.ur_w_tail) / jcp.stride_w);
+ /* maximum 1 ur_w block with r_overflow so far */
+ if (r_overflow_no_tail * jcp.stride_w > jcp.ur_w)
+ return status::unimplemented;
+
+ if ((jcp.iw > jcp.ur_w) && (jcp.ur_w % jcp.stride_w != 0))
+ return status::unimplemented;
+
+ return status::success;
+}
+
+void jit_avx2_conv_bwd_data_kernel_f32::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad, const jit_conv_conf_t &jcp) {
+ UNUSED(scratchpad);
+ UNUSED(jcp);
+}
+
+void jit_avx2_conv_bwd_weights_kernel_f32::generate() {
+ this->preamble();
+
+ mov(reg_input, ptr[this->param1 + GET_OFF(src)]);
+ mov(reg_output, ptr[this->param1 + GET_OFF(dst)]);
+ mov(reg_kernel, ptr[this->param1 + GET_OFF(filt)]);
+ compute_oh_loop_common();
+ this->postamble();
+}
+
+status_t jit_avx2_conv_bwd_weights_kernel_f32::init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &diff_weights_d,
+ const memory_desc_wrapper &diff_dst_d) {
+ if (!mayiuse(avx2)) return status::unimplemented;
+
+ const bool with_groups = diff_weights_d.ndims() == src_d.ndims() + 1;
+ int ndims = src_d.ndims();
+ jcp.ndims = ndims;
+
+ jcp.ngroups = with_groups ? diff_weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+
+ jcp.oc = diff_dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+
+ jcp.id = (ndims == 5) ? src_d.dims()[2] : 1;
+ jcp.ih = (ndims == 3) ? 1 : src_d.dims()[ndims-2];
+ jcp.iw = src_d.dims()[ndims-1];
+ jcp.od = (ndims == 5) ? diff_dst_d.dims()[2] : 1;
+ jcp.oh = (ndims == 3) ? 1 : diff_dst_d.dims()[ndims-2];
+ jcp.ow = diff_dst_d.dims()[ndims-1];
+
+ jcp.kd = (ndims == 5) ? diff_weights_d.dims()[with_groups + 2] : 1;
+ jcp.kh = (ndims == 3) ? 1 : diff_weights_d.dims()[with_groups + ndims-2];
+ jcp.kw = diff_weights_d.dims()[with_groups + ndims-1];
+
+ jcp.f_pad = (ndims == 5) ? cd.padding[0][0] : 0;
+ jcp.t_pad = (ndims == 3) ? 0 : cd.padding[0][ndims-4];
+ jcp.l_pad = cd.padding[0][ndims-3];
+
+ jcp.stride_d = (ndims == 5) ? cd.strides[0] : 1;
+ jcp.stride_h = (ndims == 3) ? 1 : cd.strides[ndims-4];
+ jcp.stride_w = cd.strides[ndims-3];
+
+ jcp.dilate_d = (ndims == 5) ? cd.dilates[0] : 0;
+ jcp.dilate_h = (ndims == 3) ? 0 : cd.dilates[ndims-4];
+ jcp.dilate_w = cd.dilates[ndims-3];
+
+ if (ndims == 3) {
+ jcp.src_tag = src_d.matches_one_of_tag(ncw, nwc, nCw8c);
+ jcp.wei_tag = diff_weights_d.matches_one_of_tag(
+ Owi8o, gOwi8o, OIw8i8o, gOIw8i8o);
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(nCw8c);
+ } else if (ndims == 4) {
+ jcp.src_tag = src_d.matches_one_of_tag(nchw, nhwc, nChw8c);
+ jcp.wei_tag = diff_weights_d.matches_one_of_tag(
+ Ohwi8o, gOhwi8o, OIhw8i8o, gOIhw8i8o);
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(nChw8c);
+ } else if (ndims == 5) {
+ jcp.src_tag = src_d.matches_one_of_tag(ncdhw, ndhwc, nCdhw8c);
+ jcp.wei_tag = diff_weights_d.matches_one_of_tag(
+ Odhwi8o, gOdhwi8o, OIdhw8i8o, gOIdhw8i8o);
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(nCdhw8c);
+ }
+ jcp.with_bias = cd.diff_bias_desc.format_kind != format_kind::undef;
+
+ const bool flat = jcp.ic == 3;
+ const bool mimo = !flat;
+
+ const int simd_w = 8;
+
+ jcp.b_pad = nstl::max(
+ 0, (jcp.oh - 1) * jcp.stride_h + jcp.kh - jcp.ih - jcp.t_pad);
+ jcp.r_pad = nstl::max(
+ 0, (jcp.ow - 1) * jcp.stride_w + jcp.kw - jcp.iw - jcp.l_pad);
+
+ int back_pad = nstl::max(0, (jcp.od - 1) * jcp.stride_d + jcp.kd - jcp.id
+ - jcp.f_pad);
+ if (ndims == 5)
+ if (jcp.f_pad != 0 || back_pad != 0)
+ return status::unimplemented;
+
+ const int max_h_pad = ((jcp.kh - 1) * (jcp.dilate_h + 1) + 1);
+ const int max_w_pad = ((jcp.kw - 1) * (jcp.dilate_w + 1) + 1);
+ const bool boundaries_ok = true
+ && jcp.t_pad < max_h_pad && jcp.b_pad < max_h_pad
+ && jcp.l_pad < max_w_pad && jcp.r_pad < max_w_pad;
+ if (!boundaries_ok)
+ return status::unimplemented;
+
+ bool ok_to_pad_channels = true
+ && jcp.ngroups == 1;
+
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ if (mimo)
+ jcp.ic = rnd_up(jcp.ic, simd_w);
+ }
+
+ bool args_ok = true
+ && IMPLICATION(flat, true
+ && one_of(jcp.src_tag, ncw, nwc, nchw, nhwc, ncdhw, ndhwc)
+ && one_of(jcp.wei_tag, Owi8o, gOwi8o, Ohwi8o, gOhwi8o, Odhwi8o,
+ gOdhwi8o))
+ && IMPLICATION(mimo, true
+ && one_of(jcp.src_tag, nCw8c, nChw8c, nCdhw8c)
+ && one_of(jcp.wei_tag, OIw8i8o, gOIw8i8o, OIhw8i8o, gOIhw8i8o,
+ OIdhw8i8o, gOIdhw8i8o))
+ && one_of(jcp.dst_tag, nCw8c, nChw8c, nCdhw8c)
+ && IMPLICATION(mimo, jcp.ic % simd_w == 0)
+ && jcp.oc % simd_w == 0
+ && jcp.kw < 14
+ && jcp.kh <= jcp.t_pad + jcp.ih /* [bwd_w:r1] */
+ && jcp.kh <= jcp.ih /* [bwd_w:r2] */
+ && jcp.kd <= jcp.f_pad + jcp.id
+ && jcp.kd <= jcp.id
+ && jcp.t_pad < jcp.kh /* XXX: must fix the kernel! */
+ && jcp.dilate_d == 0
+ && jcp.dilate_h == 0
+ && jcp.dilate_w == 0;
+ if (!args_ok) return status::unimplemented;
+
+ jcp.ic_block = (jcp.ic % simd_w != 0) ? jcp.ic : simd_w;
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+
+ jcp.oc_block = simd_w;
+ jcp.nb_oc = jcp.oc / jcp.oc_block;
+ jcp.nb_ic_blocking = jcp.nb_oc_blocking = 1;
+
+ return status::success;
+}
+
+void jit_avx2_conv_bwd_weights_kernel_f32::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad, const jit_conv_conf_t &jcp) {
+ if (jcp.with_bias && jcp.oc != jcp.oc_without_padding)
+ scratchpad.book(key_conv_padded_bias, sizeof(float) * jcp.oc);
+}
+
+inline void jit_avx2_conv_bwd_weights_kernel_f32::od_step_comeback_pointers()
+{
+ Label kd_comeback_loop;
+ mov(kj, jcp.kd); //FIXME (Anton): this works only if f_pad = back_pad = 0
+ L(kd_comeback_loop); {
+ const int inp_mult = one_of(jcp.src_tag, ncw, nchw, ncdhw)
+ ? 1 : jcp.ic_block;
+ sub(aux_reg_input, sizeof(float) * jcp.iw * jcp.ih * inp_mult);
+ sub(aux_reg_kernel, sizeof(float) * jcp.kw * jcp.kh * jcp.ic_block
+ * jcp.oc_block);
+ dec(kj);
+ cmp(kj, 0);
+ jg(kd_comeback_loop, T_NEAR);
+ }
+}
+
+inline void jit_avx2_conv_bwd_weights_kernel_f32::oh_step_comeback_pointers()
+{
+ mov(kj, reg_kh);
+ Label kh_comeback_loop;
+ L(kh_comeback_loop); {
+ const int inp_mult = one_of(jcp.src_tag, ncw, nchw, ncdhw)
+ ? 1 : jcp.ic_block;
+ sub(reg_input, sizeof(float) * jcp.iw * inp_mult);
+ sub(reg_kernel, sizeof(float) * jcp.kw * jcp.ic_block * jcp.oc_block);
+ dec(kj);
+ cmp(kj, 0);
+ jg(kh_comeback_loop, T_NEAR);
+ }
+}
+
+inline void jit_avx2_conv_bwd_weights_kernel_f32::compute_ic_block_step(
+ int ur_w, int pad_l, int pad_r, int ic_block_step, int input_offset,
+ int kernel_offset, int output_offset)
+{
+ const int kw = jcp.kw;
+ const int ic_block = jcp.ic_block;
+ const int oc_block = jcp.oc_block;
+ for (int i_kw = 0; i_kw < kw; i_kw++)
+ for (int i_ic = 0; i_ic < ic_block_step; i_ic++) {
+ size_t off
+ = sizeof(float) * (i_kw * ic_block + i_ic) * jcp.oc_block
+ + kernel_offset;
+ vmovups(Ymm(i_kw * ic_block_step + i_ic), yword[reg_kernel + off]);
+ }
+
+ for (int i_ur = 0; i_ur < ur_w; i_ur++) {
+ vmovups(Ymm(kw * ic_block_step + 0),
+ yword[reg_output
+ + sizeof(float) * i_ur * oc_block + output_offset]);
+
+ for (int i_kw = 0; i_kw < kw; i_kw++) {
+ int i_iw = i_ur * jcp.stride_w + i_kw;
+ if (i_iw - pad_l < 0
+ || i_iw > (ur_w - 1) * jcp.stride_w + kw - 1 - pad_r)
+ continue;
+ for (int i_ic = 0; i_ic < ic_block_step; i_ic++) {
+ size_t i_off = (size_t)input_offset + sizeof(float)*(
+ one_of(jcp.src_tag, ncw, nchw, ncdhw)
+ ? (i_iw - pad_l) + i_ic
+ * ((size_t)jcp.id * jcp.ih * jcp.iw)
+ : (i_iw - pad_l) * ic_block + i_ic);
+ vbroadcastss(Ymm(kw * ic_block_step + 1),
+ make_safe_addr(reg_input, i_off, reg_long_offt));
+ vfmadd231ps(Ymm(i_kw * ic_block_step + i_ic),
+ Ymm(kw * ic_block_step + 0),
+ Ymm(kw * ic_block_step + 1));
+ }
+ }
+ }
+
+ for (int i_kw = 0; i_kw < kw; i_kw++)
+ for (int i_ic = 0; i_ic < ic_block_step; i_ic++) {
+ size_t off
+ = sizeof(float) * (i_kw * ic_block + i_ic) * jcp.oc_block
+ + kernel_offset;
+ vmovups(yword[reg_kernel + off],
+ Ymm(i_kw * ic_block_step + i_ic));
+ }
+}
+
+inline void jit_avx2_conv_bwd_weights_kernel_f32::compute_oh_step_disp()
+{
+ int ic_block_step;
+ if (one_of(jcp.src_tag, ncw, nchw, ncdhw)) {
+ ic_block_step = jcp.kw >= 5 ? 1 : jcp.ic_block;
+ } else {
+ ic_block_step = jcp.kw > 7 ? 1
+ : jcp.kw > 3 ? 2
+ : jcp.kw > 1 ? 4 : 8;
+ }
+
+ const int max_ur_w = jcp.ow > 56 ? 14 : 28;
+
+ if (jcp.ow <= max_ur_w)
+ compute_oh_step_unroll_ow(ic_block_step, max_ur_w);
+ else
+ compute_oh_step_common(ic_block_step, max_ur_w);
+
+ if (jcp.ndims == 5) {
+ od_step_comeback_pointers();
+ mov(reg_input, aux_reg_input);
+ mov(reg_kernel, aux_reg_kernel);
+ } else {
+ oh_step_comeback_pointers();
+ }
+}
+
+inline void jit_avx2_conv_bwd_weights_kernel_f32::compute_oh_step_unroll_ow(
+ int ic_block_step, int max_ur_w)
+{
+ UNUSED(max_ur_w);
+
+ const int ic_block = jcp.ic_block;
+ const int oc_block = jcp.oc_block;
+ int inp_mul = one_of(jcp.src_tag, ncw, nchw, ncdhw) ? 1 : jcp.ic_block;
+ Label kd_loop;
+
+ const int r_pad
+ = nstl::max(0,
+ (jcp.ow - 1) * jcp.stride_w + jcp.kw - jcp.iw - jcp.l_pad);
+
+ if (jcp.ndims == 5) {
+ mov(aux_reg_input, reg_input);
+ mov(aux_reg_kernel, reg_kernel);
+ mov(ki, jcp.kd);
+ L(kd_loop);
+ mov(reg_input, aux_reg_input);
+ mov(reg_kernel, aux_reg_kernel);
+ }
+
+ mov(kj, reg_kh);
+ Label kh_loop;
+ L(kh_loop); {
+ xor_(b_ic, b_ic);
+ Label ic_block_loop;
+ L(ic_block_loop); {
+ compute_ic_block_step(jcp.ow, jcp.l_pad, r_pad, ic_block_step, 0,
+ 0, 0);
+ size_t inp_icblk_stride = sizeof(float) * ic_block_step
+ * (one_of(jcp.src_tag, ncw, nchw, ncdhw)
+ ? jcp.id*jcp.ih*jcp.iw : 1);
+ safe_add(reg_input, inp_icblk_stride, reg_long_offt);
+ add(reg_kernel, sizeof(float) * ic_block_step * oc_block);
+ add(b_ic, ic_block_step);
+ cmp(b_ic, ic_block);
+ jl(ic_block_loop, T_NEAR);
+ }
+ if(one_of(jcp.src_tag, ncw, nchw, ncdhw)) {
+ size_t offt = sizeof(float) * jcp.id * jcp.ih * jcp.iw * ic_block;
+ safe_sub(reg_input, offt, reg_long_offt);
+ add(reg_input, sizeof(float) * jcp.iw);
+ } else {
+ add(reg_input, sizeof(float) * (jcp.iw - 1) * ic_block);
+ }
+ add(reg_kernel, sizeof(float) * (jcp.kw - 1) * ic_block * oc_block);
+ dec(kj);
+ cmp(kj, 0);
+ jg(kh_loop, T_NEAR);
+ }
+
+ if (jcp.ndims == 5) {
+ add(aux_reg_input, sizeof(float) * jcp.ih * jcp.iw * inp_mul);
+ add(aux_reg_kernel, sizeof(float) * jcp.kh * jcp.kw * ic_block
+ * oc_block);
+ dec(ki);
+ cmp(ki, 0);
+ jg(kd_loop, T_NEAR);
+ }
+
+}
+
+inline void jit_avx2_conv_bwd_weights_kernel_f32::compute_oh_step_common(
+ int ic_block_step, int max_ur_w)
+{
+ const int ic_block = jcp.ic_block;
+ const int oc_block = jcp.oc_block;
+ const int stride_w = jcp.stride_w;
+ int inp_mul = one_of(jcp.src_tag, ncw, nchw, ncdhw) ? 1 : jcp.ic_block;
+ Label kd_loop;
+
+ const int r_pad = jcp.r_pad;
+
+ int ur_w = nstl::min(jcp.ow, max_ur_w);
+ int ur_w_trips = jcp.ow / ur_w;
+ int ur_w_tail = jcp.ow % ur_w;
+ if ((ur_w_tail == 0 && r_pad != 0) || r_pad >= ur_w_tail) {
+ if (ur_w_trips > 1) {
+ ur_w_tail += ur_w;
+ ur_w_trips--;
+ } else {
+ ur_w_tail += (ur_w - ur_w / 2);
+ ur_w = ur_w / 2;
+ }
+ }
+ const int inp_mult = one_of(jcp.src_tag, ncw, nchw, ncdhw) ? 1 : ic_block;
+
+ int input_comeback = (ur_w_trips * ur_w * stride_w - jcp.l_pad) * inp_mult;
+ int output_comeback = ur_w_trips * ur_w * oc_block;
+
+ if (jcp.ndims == 5) {
+ mov(aux_reg_input, reg_input);
+ mov(aux_reg_kernel, reg_kernel);
+ mov(ki, jcp.kd);
+ L(kd_loop);
+ mov(reg_input, aux_reg_input);
+ mov(reg_kernel, aux_reg_kernel);
+ }
+
+ mov(kj, reg_kh);
+ Label kh_loop;
+ L(kh_loop); {
+ xor_(b_ic, b_ic);
+ Label ic_block_loop;
+ L(ic_block_loop); {
+ if (jcp.l_pad != 0) {
+ ur_w_trips--;
+ compute_ic_block_step(ur_w,
+ jcp.l_pad, 0, ic_block_step, 0, 0, 0);
+ add(reg_input, sizeof(float)
+ * (ur_w * stride_w - jcp.l_pad) * inp_mult);
+ add(reg_output, sizeof(float) * ur_w * oc_block);
+ }
+
+ if (ur_w_trips > 0) {
+ xor_(reg_ur_w_trips, reg_ur_w_trips);
+ Label ow_block_loop;
+ L(ow_block_loop); {
+ compute_ic_block_step(ur_w, 0, 0, ic_block_step, 0, 0, 0);
+ add(reg_input, sizeof(float) * ur_w * stride_w * inp_mult);
+ add(reg_output, sizeof(float) * ur_w * oc_block);
+
+ inc(reg_ur_w_trips);
+ cmp(reg_ur_w_trips, ur_w_trips);
+ jl(ow_block_loop, T_NEAR);
+ }
+ }
+
+ if (ur_w_tail > 0)
+ compute_ic_block_step(ur_w_tail,
+ 0, r_pad, ic_block_step, 0, 0, 0);
+
+ sub(reg_input, sizeof(float) * input_comeback);
+ sub(reg_output, sizeof(float) * output_comeback);
+
+ size_t inp_icblk_stride = sizeof(float) * ic_block_step
+ * (one_of(jcp.src_tag, ncw, nchw, ncdhw)
+ ? jcp.id*jcp.ih*jcp.iw : 1);
+ safe_add(reg_input, inp_icblk_stride, reg_long_offt);
+ add(reg_kernel, sizeof(float) * ic_block_step * oc_block);
+
+ add(b_ic, ic_block_step);
+ cmp(b_ic, jcp.ic_block);
+ jl(ic_block_loop, T_NEAR);
+ }
+ if (one_of(jcp.src_tag, ncw, nchw, ncdhw)) {
+ size_t offt = sizeof(float) * jcp.id * jcp.ih * jcp.iw * ic_block;
+ safe_sub(reg_input, offt, reg_long_offt);
+ add(reg_input, sizeof(float) * jcp.iw);
+ } else {
+ add(reg_input, sizeof(float) * (jcp.iw - 1) * ic_block);
+ }
+ add(reg_kernel, sizeof(float) * (jcp.kw - 1) * ic_block * oc_block);
+ dec(kj);
+ cmp(kj, 0);
+ jg(kh_loop, T_NEAR);
+ }
+
+ if (jcp.ndims == 5) {
+ add(aux_reg_input, sizeof(float) * jcp.ih * jcp.iw * inp_mul);
+ add(aux_reg_kernel, sizeof(float) * jcp.kh * jcp.kw * ic_block
+ * oc_block);
+ dec(ki);
+ cmp(ki, 0);
+ jg(kd_loop, T_NEAR);
+ }
+
+}
+
+inline void jit_avx2_conv_bwd_weights_kernel_f32::compute_oh_loop_common()
+{
+ const int icoc_block = jcp.ic_block * jcp.oc_block;
+ const int t_pad = jcp.t_pad;
+ const int stride_h = jcp.stride_h;
+ const int inp_mult = one_of(jcp.src_tag, ncw, nchw, ncdhw)
+ ? 1 : jcp.ic_block;
+ int b_pad = jcp.b_pad;
+
+ Label oh_tpad_loop, oh_loop, oh_loop_end;
+
+ mov(reg_kh, jcp.kh);
+ xor_(reg_ih_count, reg_ih_count);
+ xor_(reg_oj, reg_oj);
+ if (t_pad > 0) {
+ assert(jcp.kh <= t_pad + jcp.ih); /* [bwd_w:r1] */
+ mov(reg_kh, jcp.kh <= t_pad + jcp.ih ? jcp.kh - t_pad : jcp.ih);
+ add(reg_kernel, sizeof(float) * t_pad * jcp.kw * icoc_block);
+
+ L(oh_tpad_loop); {
+ compute_oh_step_disp();
+ add(reg_output, sizeof(float) * jcp.ow * jcp.oc_block);
+ sub(reg_kernel, sizeof(float) * stride_h * jcp.kw * icoc_block);
+
+ inc(reg_oj);
+ add(reg_ih_count, stride_h);
+ add(reg_kh, stride_h);
+
+ /* the overlap between input and kernel may not reach kernel size.
+ * so far we do not support that (until we put constant here) */
+ const int final_inp_ker_overlap = jcp.kh; /* [bwd_w:r2] */
+ cmp(reg_kh, final_inp_ker_overlap);
+ jl(oh_tpad_loop, T_NEAR);
+ }
+
+ if (t_pad % stride_h != 0) {
+ int inp_corr = stride_h - t_pad % stride_h;
+ add(reg_kernel, sizeof(float) * inp_corr * jcp.kw * icoc_block);
+ add(reg_input, sizeof(float) * inp_corr * jcp.iw * inp_mult);
+ }
+ }
+ cmp(reg_ih_count, jcp.ih + t_pad - jcp.kh + 1);
+ jge(oh_loop_end, T_NEAR);
+ cmp(reg_oj, jcp.oh);
+ jge(oh_loop, T_NEAR);
+
+ mov(reg_kh, jcp.kh);
+ L(oh_loop); {
+ compute_oh_step_disp();
+ add(reg_input, sizeof(float) * stride_h * jcp.iw * inp_mult);
+ add(reg_output, sizeof(float) * jcp.ow * jcp.oc_block);
+
+ inc(reg_oj);
+ add(reg_ih_count, stride_h);
+
+ cmp(reg_ih_count, jcp.ih + t_pad - jcp.kh + 1);
+ jge(oh_loop_end, T_NEAR);
+
+ cmp(reg_oj, jcp.oh);
+ jl(oh_loop, T_NEAR);
+ }
+ L(oh_loop_end);
+ if (b_pad > 0) {
+ Label oh_bpad_loop, oh_bpad_loop_end;
+ cmp(reg_oj, jcp.oh);
+ jge(oh_bpad_loop_end, T_NEAR);
+
+ mov(reg_kh, jcp.ih + t_pad);
+ sub(reg_kh, reg_ih_count);
+ L(oh_bpad_loop); {
+ compute_oh_step_disp();
+ add(reg_input, sizeof(float) * stride_h * jcp.iw * inp_mult);
+ add(reg_output, sizeof(float) * jcp.ow * jcp.oc_block);
+
+ sub(reg_kh, stride_h);
+ cmp(reg_kh, 0);
+ jle(oh_bpad_loop_end, T_NEAR);
+
+ inc(reg_oj);
+ cmp(reg_oj, jcp.oh);
+ jl(oh_bpad_loop, T_NEAR);
+ }
+ L(oh_bpad_loop_end);
+ }
+}
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.hpp
new file mode 100644
index 0000000000..412c50c9ee
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_conv_kernel_f32.hpp
@@ -0,0 +1,225 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_AVX2_CONV_KERNEL_F32_HPP
+#define JIT_AVX2_CONV_KERNEL_F32_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+
+#include "cpu_memory.hpp"
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+#include "jit_uni_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_avx2_conv_fwd_kernel_f32: public jit_generator {
+ jit_avx2_conv_fwd_kernel_f32(jit_conv_conf_t ajcp,
+ const primitive_attr_t &attr)
+ : jcp(ajcp), attr_(attr), eltwise_injector_(nullptr)
+ {
+ if (jcp.with_eltwise)
+ eltwise_injector_ = new jit_uni_eltwise_injector_f32<avx2>(this,
+ jcp.eltwise);
+
+ this->generate();
+ jit_ker = (void (*)(jit_conv_call_s *))this->getCode();
+ }
+
+ ~jit_avx2_conv_fwd_kernel_f32() {
+ delete eltwise_injector_;
+ }
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx2_conv_fwd_kernel_f32)
+
+ static bool post_ops_ok(jit_conv_conf_t &jcp,
+ const primitive_attr_t &attr);
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d,
+ const primitive_attr_t &attr);
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_conf_t &jcp);
+
+ jit_conv_conf_t jcp;
+ const primitive_attr_t &attr_;
+ void (*jit_ker)(jit_conv_call_s *);
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ reg64_t reg_input = rax;
+ reg64_t aux_reg_input = r8;
+ reg64_t reg_kernel = rdx;
+ reg64_t aux_reg_kernel = r9;
+ reg64_t reg_output = rsi;
+ reg64_t reg_bias = rbx;
+
+ reg64_t aux_reg_inp_d = r11;
+ reg64_t aux_reg_ker_d = abi_not_param1;
+
+ reg64_t reg_ki = rsi;
+ reg64_t kj = r10;
+ reg64_t oi_iter = r11;
+ reg64_t ki_iter = r12;
+ reg64_t reg_kh = abi_not_param1;
+ reg64_t reg_oc_blocks = r14;
+ reg64_t imm_addr64 = r15;
+ reg64_t reg_long_offt = r15;
+ Xbyak::Reg32 reg_ci_flag = r13d;
+
+ Xbyak::Ymm ytmp = Xbyak::Ymm(14);
+
+ jit_uni_eltwise_injector_f32<avx2> *eltwise_injector_;
+
+ inline void oh_step_unroll_kw(int ur_w, int pad_l, int pad_r,
+ int oc_blocks);
+ inline void oh_step_nopad(int ur_w, int pad_l, int pad_r,
+ char pad_label, int oc_blocks, char oc_blocks_label);
+ inline void width_blk_step(int ur_w, int pad_l, int pad_r,
+ char pad_label, int oc_blocks, char oc_blocks_label);
+ inline void solve_common(int oc_blocks, char oc_blocks_label);
+
+ void generate();
+};
+
+struct jit_avx2_conv_bwd_data_kernel_f32: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx2_conv_bwd_data_kernel_f32)
+
+ jit_avx2_conv_bwd_data_kernel_f32(jit_conv_conf_t ajcp): jcp(ajcp)
+ {
+ this->generate();
+ jit_ker = (void (*)(jit_conv_call_s *))this->getCode();
+ }
+
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &diff_src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &diff_dst_d);
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_conf_t &jcp);
+
+ jit_conv_conf_t jcp;
+ void (*jit_ker)(jit_conv_call_s *);
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+
+ reg64_t reg_ddst = rax;
+ reg64_t aux_reg_ddst = r8;
+ reg64_t reg_kernel = rdx;
+ reg64_t aux_reg_kernel = r10;
+ reg64_t reg_dsrc = rsi;
+ reg64_t aux_reg_ddst_oc_loop = rbx; // used in ndims < 5 case only
+ reg64_t aux_reg_kernel_oc_loop = abi_not_param1; /* used in ndims < 5
+ case only */
+
+ reg64_t aux_reg_dst_d = r12; // used in ndims == 5 case only
+ reg64_t aux_reg_ker_d = r14; // used in ndims == 5 case only
+
+ reg64_t reg_ki = abi_not_param1; // used in ndims == 5 case only
+ reg64_t kj = r11;
+ reg64_t oi_iter = r12;
+ reg64_t reg_kh = r14;
+ reg64_t reg_channel = r13; // used in ndims < 5 case only
+ reg64_t reg_channel_work = r9; // used in ndims < 5 case only
+ reg64_t reg_long_offt = r15;
+
+ inline void compute_loop(int ur_w, int l_overflow, int r_overflow);
+
+ void generate();
+
+ inline int get_iw_start(int ki, int l_overflow)
+ {
+ int res = (jcp.iw - 1 + jcp.r_pad) % jcp.stride_w
+ + l_overflow * jcp.stride_w
+ - (jcp.kw - 1 - ki) * (jcp.dilate_w + 1);
+ while (res < 0)
+ res += jcp.stride_w;
+
+ return res;
+ }
+
+ inline int get_iw_end(int ur_w, int ki, int r_overflow)
+ {
+ if (utils::one_of(ur_w, jcp.iw, jcp.ur_w_tail))
+ ur_w += nstl::min(0, jcp.r_pad); // remove negative padding
+ int res = (ur_w - 1 + jcp.l_pad) % jcp.stride_w
+ + r_overflow * jcp.stride_w - ki * (jcp.dilate_w + 1);
+ while (res < 0)
+ res += jcp.stride_w;
+
+ return ur_w - res;
+ }
+};
+
+struct jit_avx2_conv_bwd_weights_kernel_f32: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx2_conv_bwd_weights_kernel_f32)
+
+ jit_avx2_conv_bwd_weights_kernel_f32(jit_conv_conf_t ajcp): jcp(ajcp)
+ {
+ this->generate();
+ jit_ker = (void (*)(jit_conv_call_s *))this->getCode();
+ }
+
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &diff_weights_d,
+ const memory_desc_wrapper &diff_dst_d);
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_conf_t &jcp);
+
+ jit_conv_conf_t jcp;
+ void (*jit_ker)(jit_conv_call_s *);
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ reg64_t reg_input = rax;
+ reg64_t reg_kernel = rdx;
+ reg64_t reg_output = rsi;
+ reg64_t b_ic = abi_not_param1;
+ reg64_t kj = r8;
+ reg64_t reg_kh = r9;
+ reg64_t reg_ur_w_trips = r10;
+ reg64_t reg_tmp = r11;
+ reg64_t reg_oj = r15;
+ reg64_t reg_ih_count = rbx;
+ reg64_t aux_reg_input = r12;
+ reg64_t aux_reg_kernel = r13;
+ reg64_t ki = r14;
+ reg64_t reg_long_offt = r11;
+
+ inline void od_step_comeback_pointers();
+ inline void oh_step_comeback_pointers();
+ inline void compute_ic_block_step(int ur_w, int pad_l, int pad_r,
+ int ic_block_step, int input_offset, int kernel_offset,
+ int output_offset);
+ inline void compute_oh_step_disp();
+ inline void compute_oh_step_unroll_ow(int ic_block_step, int max_ur_w);
+ inline void compute_oh_step_common(int ic_block_step, int max_ur_w);
+ inline void compute_oh_loop_common();
+
+ void generate();
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_convolution.cpp
new file mode 100644
index 0000000000..13f61e84fe
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_convolution.cpp
@@ -0,0 +1,410 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_avx2_convolution.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+
+#define src_blk_off(f, n, c, d, h, w) \
+ (pd()->ndims() == 3) \
+ ? (f).blk_off(n, c, w) \
+ : (pd()->ndims() == 4) \
+ ? (f).blk_off(n, c, h, w) \
+ : (f).blk_off(n, c, d, h, w)
+
+#define wht_blk_off_(f, g, ...) \
+ pd()->with_groups() ? (f).blk_off(g, __VA_ARGS__) : (f).blk_off(__VA_ARGS__)
+#define wht_blk_off(f, g, oc, ic, kd, kh, kw) \
+ (pd()->ndims() == 3) \
+ ? wht_blk_off_(f, g, oc, ic, kw) \
+ : (pd()->ndims() == 4) \
+ ? wht_blk_off_(f, g, oc, ic, kh, kw) \
+ : wht_blk_off_(f, g, oc, ic, kd, kh, kw)
+
+void jit_avx2_convolution_fwd_t::execute_forward(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ const auto &jcp = kernel_->jcp;
+
+ int ocb_work = div_up(jcp.nb_oc, jcp.nb_oc_blocking);
+ const size_t work_amount = jcp.mb * jcp.ngroups * ocb_work * jcp.od
+ * jcp.oh;
+
+ auto ker = [&](const int ithr, const int nthr) {
+ size_t start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+
+ int icbb = 0;
+ while (icbb < jcp.nb_ic) {
+ int icb_step = jcp.nb_ic_blocking;
+ int icb_step_rem = jcp.nb_ic - icbb;
+ if (icb_step_rem < jcp.nb_ic_blocking_max)
+ icb_step = icb_step_rem;
+
+ size_t n{0}, g{0}, ocbb{0}, oh{0}, od{0};
+ nd_iterator_init(start, n, jcp.mb, g, jcp.ngroups, ocbb, ocb_work,
+ od, jcp.od, oh, jcp.oh);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ int ocb = ocbb * jcp.nb_oc_blocking;
+ int ocb_num = jcp.nb_oc_blocking;
+
+ for (int icb = icbb; icb < icbb + icb_step; ++icb) {
+ auto par_conv = jit_conv_call_s();
+
+ const int ij = oh * jcp.stride_h;
+ const int i_t_overflow = nstl::max(0, jcp.t_pad - ij);
+ const int i_b_overflow = nstl::max(jcp.ih, ij
+ + (jcp.kh-1) * (jcp.dilate_h+1) - jcp.t_pad+1) - jcp.ih;
+
+ const int dj = od * jcp.stride_d;
+ const int d_t_overflow = nstl::max(0, jcp.f_pad - dj);
+ const int d_b_overflow = nstl::max(jcp.id, dj
+ + (jcp.kd-1) * (jcp.dilate_d+1) - jcp.f_pad+1) - jcp.id;
+
+ const size_t _oc = g * jcp.nb_oc + ocb;
+ const size_t _ic = g * jcp.nb_ic * jcp.nonblk_group_off + icb;
+
+ const int ih = nstl::max(ij - jcp.t_pad
+ + div_up(i_t_overflow,
+ (jcp.dilate_h+1)) * (jcp.dilate_h + 1), 0);
+
+ const int id = nstl::max(dj - jcp.f_pad
+ + div_up(d_t_overflow,
+ (jcp.dilate_d+1)) * (jcp.dilate_d + 1), 0);
+
+ par_conv.src = &src[src_blk_off(src_d, n,
+ jcp.ic == 3 ? 0 : _ic, id, ih, 0)];
+
+ par_conv.dst = &dst[src_blk_off(dst_d, n, _oc, od, oh, 0)];
+
+ const int wh = div_up(i_t_overflow, (jcp.dilate_h + 1));
+ const int wd = div_up(d_t_overflow, (jcp.dilate_d + 1));
+ par_conv.filt = &weights[wht_blk_off(weights_d, g, ocb,
+ jcp.ic == 3 ? 0 : icb, wd, wh, 0)];
+
+ if (icb == 0) {
+ if (bias)
+ par_conv.bias =
+ &bias[bias_d.blk_off(_oc * jcp.oc_block)];
+ par_conv.flags |= FLAG_IC_FIRST;
+ }
+
+ if (jcp.with_eltwise && icb + 1 == jcp.nb_ic) {
+ par_conv.flags |= FLAG_IC_LAST;
+ }
+
+ par_conv.oc_blocks =
+ nstl::min(ocb + ocb_num, jcp.nb_oc) - ocb;
+
+ par_conv.kw_padding = 0;
+ const int kh_padding = jcp.kh
+ - div_up(i_t_overflow, (jcp.dilate_h + 1))
+ - div_up(i_b_overflow, (jcp.dilate_h + 1));
+ par_conv.kh_padding = nstl::max(0, kh_padding);
+
+ const int kd_padding = jcp.kd
+ - div_up(d_t_overflow, (jcp.dilate_d + 1))
+ - div_up(d_b_overflow, (jcp.dilate_d + 1));
+ par_conv.kd_padding = nstl::max(0, kd_padding);
+
+ kernel_->jit_ker(&par_conv);
+ }
+ nd_iterator_step(n, jcp.mb, g, jcp.ngroups, ocbb, ocb_work,
+ od, jcp.od, oh, jcp.oh);
+ }
+ icbb += icb_step;
+ }
+ };
+
+ if (pd()->wants_padded_bias()) {
+ auto padded_bias = scratchpad(ctx).get<data_t>(key_conv_padded_bias);
+ utils::array_copy(padded_bias, bias, jcp.oc_without_padding);
+ utils::array_set(padded_bias + jcp.oc_without_padding, 0.f,
+ jcp.oc - jcp.oc_without_padding);
+ bias = padded_bias;
+ }
+
+ parallel(0, ker);
+
+ if (pd()->wants_zero_pad_dst())
+ ctx.memory(MKLDNN_ARG_DST)->zero_pad();
+}
+
+void jit_avx2_convolution_bwd_data_t::execute_backward_data(
+ const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+
+ int icb_work = jcp.nb_ic / jcp.nb_ic_blocking;
+ int ih_block_size = jcp.ih;
+ int num_ih_blocks = utils::div_up(jcp.ih, ih_block_size);
+ size_t work_amount = jcp.mb * jcp.ngroups * icb_work * num_ih_blocks;
+ if (work_amount < (size_t)2 * mkldnn_get_max_threads()) {
+ ih_block_size = 1;
+ num_ih_blocks = utils::div_up(jcp.ih, ih_block_size);
+ work_amount *= num_ih_blocks;
+ }
+
+ auto ker = [&](const int ithr, const int nthr) {
+ size_t start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+
+ size_t n{0}, g{0}, icbb{0}, ihb{0};
+ nd_iterator_init(start, n, jcp.mb, g, jcp.ngroups, icbb, icb_work,
+ ihb, num_ih_blocks);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ for (int oc = 0; oc < jcp.nb_oc; oc += jcp.nb_oc_blocking)
+ for (int id = 0; id < jcp.id; ++id) {
+ auto par_conv = jit_conv_call_s();
+
+ const int idp = jcp.id + 2 * jcp.f_pad;
+ const int d_t_overflow = nstl::max(0,
+ jcp.kd - 1 - id - jcp.f_pad);
+ const int back_pad = idp - jcp.id - jcp.f_pad;
+ const int d_b_overflow = nstl::max(0,
+ jcp.kd - 1 - (jcp.id - 1 - id) - back_pad);
+ const int od = id + jcp.f_pad - d_b_overflow;
+
+ int ih_start = ihb * ih_block_size;
+ int ih_end = nstl::min(jcp.ih, ih_start + ih_block_size);
+ for (int ih = ih_start; ih < ih_end; ++ih) {
+
+ const int i_t_overflow = nstl::max(0, (jcp.kh - 1
+ - ih - jcp.t_pad) / jcp.stride_h);
+ const int i_b_overflow = nstl::max(0, (jcp.kh - jcp.ih
+ + ih - jcp.b_pad) / jcp.stride_h);
+ int overflow_kh_hi = jcp.kh - 1 - abs((jcp.ih - 1
+ + jcp.b_pad - ih) % jcp.stride_h);
+ int overflow_kh_lo = (ih + jcp.t_pad) % jcp.stride_h;
+
+ par_conv.kd_padding = jcp.kd - d_t_overflow - d_b_overflow;
+ par_conv.kh_padding = (overflow_kh_hi - overflow_kh_lo)
+ / jcp.stride_h + 1 - i_t_overflow - i_b_overflow;
+ par_conv.kw_padding = 0;
+
+ const int k_lo = overflow_kh_lo
+ + i_b_overflow * jcp.stride_h;
+ const int oh = (ih + jcp.t_pad - k_lo) / jcp.stride_h;
+
+ par_conv.src = &diff_src[src_blk_off(diff_src_d, n,
+ /*jcp.ic == 3 ? 0 :*/
+ g * jcp.nb_ic + jcp.nb_ic_blocking * icbb, id, ih, 0)];
+ par_conv.dst = &diff_dst[src_blk_off(diff_dst_d,
+ n, g * jcp.nb_oc + oc, od, oh, 0)];
+ par_conv.filt = &weights[wht_blk_off(weights_d, g, oc,
+ jcp.ic == 3 ? 0 : jcp.nb_ic_blocking * icbb,
+ d_b_overflow, k_lo, 0)];
+
+ par_conv.src_prf = nullptr;
+ par_conv.dst_prf = nullptr;
+ par_conv.filt_prf = nullptr;
+ par_conv.channel = oc;
+ par_conv.ch_blocks = nstl::min(jcp.nb_oc - oc,
+ jcp.nb_oc_blocking);
+
+ kernel_->jit_ker(&par_conv);
+ }
+ }
+ nd_iterator_step(n, jcp.mb, g, jcp.ngroups, icbb, icb_work, ihb,
+ num_ih_blocks);
+ }
+ };
+
+ parallel(0, ker);
+}
+
+void jit_avx2_convolution_bwd_weights_t::execute_backward_weights(
+ const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_weights = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_WEIGHTS);
+ auto diff_bias_in = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_BIAS);
+
+ auto scratchpad = this->scratchpad(ctx);
+
+ data_t *diff_bias = pd()->wants_padded_bias()
+ ? scratchpad.get<data_t>(key_conv_padded_bias) : diff_bias_in;
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_weights_d(pd()->diff_weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+
+ auto reducer_bia_scratchpad = memory_tracking::grantor_t(scratchpad,
+ prefix_reducer_bia);
+ auto rb = this->reducer_bias_;
+ rb->init(reducer_bia_scratchpad);
+
+ auto reducer_wei_scratchpad = memory_tracking::grantor_t(scratchpad,
+ prefix_reducer_wei);
+ auto rw = this->reducer_weights_;
+ rw->init(reducer_wei_scratchpad);
+
+ auto ker = [&](int ithr, int nthr) {
+ assert(nthr == rw->balancer().nthr_);
+
+ const int w_job_start = rw->balancer().ithr_job_off(ithr);
+ const int w_njobs = rw->balancer().ithr_njobs(ithr);
+
+ if (w_njobs == 0) return;
+
+ /* reduction dimension */
+ int img_od_start{0}, img_od_end{0}, img{0}, od_s{0};
+ balance211(jcp.mb * jcp.od, rw->balancer().nthr_per_group_,
+ rw->balancer().id_in_group(ithr), img_od_start, img_od_end);
+
+ int img_start = img_od_start, img_end = img_od_end;
+ nd_iterator_init(img_start, img, jcp.mb, od_s, jcp.od);
+ const int img_first = img;
+
+ /* jobs */
+ int g_start{0}, ocb_start{0}, icb_start{0};
+ nd_iterator_init(w_job_start, g_start, jcp.ngroups, ocb_start,
+ jcp.nb_oc, icb_start, jcp.nb_ic);
+
+ while (img_start < img_end) {
+ int g = g_start, ocb = ocb_start, icb = icb_start;
+
+ const int work_rem = img_end - img_start;
+ const int od_e = od_s + work_rem > jcp.od ? jcp.od : od_s + work_rem;
+ const int id_s = od_s * jcp.stride_d;
+ const int idp = jcp.id + jcp.f_pad + jcp.back_pad;
+
+ if (id_s < idp - jcp.back_pad - jcp.kd + 1)
+ for (int w_job_loc = 0; w_job_loc < w_njobs; ++w_job_loc) {
+ const size_t _oc = g * jcp.nb_oc + ocb;
+ const size_t _ic = g * jcp.nb_ic + icb;
+
+ /* TODO: put dw <-- 0 in kernel */
+ if (img == img_first)
+ array_set(rw->get_local_ptr(ithr, diff_weights,
+ reducer_wei_scratchpad) +
+ w_job_loc * rw->balancer().job_size_, 0,
+ rw->balancer().job_size_);
+
+ for (int od = od_s; od < od_e; ++od) {
+ const int id = od * jcp.stride_d;
+ if (id >= jcp.id - jcp.back_pad - jcp.kd + 1) break;
+
+ auto par_conv = jit_conv_call_s();
+ par_conv.src = &src[src_blk_off(src_d, img, _ic, id, 0, 0)];
+ par_conv.dst =
+ &diff_dst[src_blk_off(diff_dst_d, img, _oc, od, 0, 0)];
+ par_conv.filt = rw->get_local_ptr(ithr, diff_weights,
+ reducer_wei_scratchpad) +
+ w_job_loc * rw->balancer().job_size_;
+
+ kernel_->jit_ker(&par_conv);
+ }
+ nd_iterator_step(g, jcp.ngroups, ocb, jcp.nb_oc, icb,
+ jcp.nb_ic);
+ }
+ nd_iterator_jump(img_start, img_end, img, jcp.mb, od_s, jcp.od);
+ }
+ rw->reduce(ithr, diff_weights, reducer_wei_scratchpad);
+ };
+
+ auto ker_bias = [&](int ithr, int nthr) {
+ assert(nthr == rb->balancer().nthr_);
+
+ const int b_job_start = rb->balancer().ithr_job_off(ithr);
+ const int b_njobs = rb->balancer().ithr_njobs(ithr);
+
+ if (b_njobs == 0) return;
+
+ /* reduction dimension */
+ int img_start{0}, img_end{0};
+ balance211(jcp.mb, rb->balancer().nthr_per_group_,
+ rb->balancer().id_in_group(ithr), img_start, img_end);
+
+ /* jobs */
+ int g_start{0}, ocb_start{0};
+ nd_iterator_init(b_job_start, g_start, jcp.ngroups, ocb_start,
+ jcp.nb_oc);
+
+ for (int img = img_start; img < img_end; ++img) {
+ int g = g_start, ocb = ocb_start;
+ for (int b_job_loc = 0; b_job_loc < b_njobs; ++b_job_loc) {
+ const size_t _oc = g * jcp.nb_oc + ocb;
+
+ const data_t *d_dst = &diff_dst[diff_dst_d.blk_off(img, _oc)];
+ data_t *d_bias = rb->get_local_ptr(ithr, diff_bias,
+ reducer_bia_scratchpad) +
+ b_job_loc * rb->balancer().job_size_;
+
+ if (img == img_start)
+ for (int o = 0; o < 8; ++o)
+ d_bias[o] = 0.;
+
+ for (int dhw = 0; dhw < jcp.od * jcp.oh * jcp.ow; ++dhw) {
+ PRAGMA_OMP_SIMD()
+ for (int o = 0; o < 8; ++o)
+ d_bias[o] += d_dst[o];
+ d_dst += 8;
+ }
+
+ nd_iterator_step(g, jcp.ngroups, ocb, jcp.nb_oc);
+ }
+ }
+ rb->reduce(ithr, diff_bias, reducer_bia_scratchpad);
+ };
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ ker(ithr, nthr);
+ if (pd()->with_bias())
+ ker_bias(ithr, nthr);
+ });
+
+ /* TODO: put this in ker_bias */
+ if (pd()->wants_padded_bias()) {
+ assert(jcp.ngroups == 1);
+ for (int oc = 0; oc < jcp.oc_without_padding; ++oc)
+ diff_bias_in[oc] = diff_bias[oc];
+ }
+}
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_convolution.hpp
new file mode 100644
index 0000000000..bb65bce79c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx2_convolution.hpp
@@ -0,0 +1,302 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX2_CONVOLUTION_HPP
+#define CPU_JIT_AVX2_CONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_reducer.hpp"
+
+#include "jit_avx2_conv_kernel_f32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_avx2_convolution_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", avx2, ""),
+ jit_avx2_convolution_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_avx2_conv_fwd_kernel_f32::init_conf(jcp_,
+ *desc(), src_md(), weights_md(), dst_md(), *attr());
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx2_conv_fwd_kernel_f32::init_scratchpad(scratchpad, jcp_);
+
+ return status::success;
+ }
+
+ jit_conv_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ const bool flat = IC() < 8;
+ auto src_tag = flat
+ ? utils::pick(ndims() - 3, ncw, nchw, ncdhw)
+ : utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c);
+ auto dst_tag =
+ utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c);
+ auto wei_tag = with_groups()
+ ? utils::pick(2 * ndims() - 6 + flat, gOIw8i8o, gOwi8o,
+ gOIhw8i8o, gOhwi8o, gOIdhw8i8o, gOdhwi8o)
+ : utils::pick(2 * ndims() - 6 + flat, OIw8i8o, Owi8o,
+ OIhw8i8o, Ohwi8o, OIdhw8i8o, Odhwi8o);
+
+ return set_default_formats_common(src_tag, wei_tag, dst_tag);
+ }
+ };
+
+ jit_avx2_convolution_fwd_t(const pd_t *apd): cpu_primitive_t(apd)
+ { kernel_ = new jit_avx2_conv_fwd_kernel_f32(pd()->jcp_, *pd()->attr()); }
+ ~jit_avx2_convolution_fwd_t() { delete kernel_; }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx2_conv_fwd_kernel_f32 *kernel_;
+};
+
+struct jit_avx2_convolution_bwd_data_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_data_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_data_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_()
+ {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", avx2, ""),
+ jit_avx2_convolution_bwd_data_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_data
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::undef, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_avx2_conv_bwd_data_kernel_f32::init_conf(
+ jcp_, *desc(), *diff_src_md(), *weights_md(),
+ *diff_dst_md());
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx2_conv_bwd_data_kernel_f32::init_scratchpad(scratchpad,
+ jcp_);
+
+ return status::success;
+ }
+
+ jit_conv_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c);
+ auto wei_tag = with_groups()
+ ? utils::pick(ndims() - 3, gOIw8o8i, gOIhw8o8i, gOIdhw8o8i)
+ : utils::pick(ndims() - 3, OIw8o8i, OIhw8o8i, OIdhw8o8i);
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ jit_avx2_convolution_bwd_data_t(const pd_t *apd): cpu_primitive_t(apd)
+ { kernel_ = new jit_avx2_conv_bwd_data_kernel_f32(pd()->jcp_); }
+ ~jit_avx2_convolution_bwd_data_t() { delete kernel_; }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_data(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_data(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx2_conv_bwd_data_kernel_f32 *kernel_;
+};
+
+struct jit_avx2_convolution_bwd_weights_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_weights_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_weights_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", avx2, ""),
+ jit_avx2_convolution_bwd_weights_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_weights
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_avx2_conv_bwd_weights_kernel_f32::init_conf(
+ jcp_, *desc(), *src_md(), *diff_weights_md(),
+ *diff_dst_md());
+ if (status != status::success) return status;
+
+ init_balancers();
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx2_conv_bwd_weights_kernel_f32::init_scratchpad(scratchpad,
+ jcp_);
+
+ auto reducer_bia_scratchpad = memory_tracking::registrar_t(
+ scratchpad, memory_tracking::names::prefix_reducer_bia);
+ reducer_bia_conf_.init_scratchpad(reducer_bia_scratchpad);
+
+ auto reducer_wei_scratchpad = memory_tracking::registrar_t(
+ scratchpad, memory_tracking::names::prefix_reducer_wei);
+ reducer_wei_conf_.init_scratchpad(reducer_wei_scratchpad);
+
+ return status::success;
+ }
+
+ jit_conv_conf_t jcp_;
+ cpu_reducer_t<data_type::f32>::conf_t reducer_bia_conf_;
+ cpu_reducer_t<data_type::f32>::conf_t reducer_wei_conf_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+ const bool flat = IC() == 3;
+
+ auto src_tag = flat
+ ? utils::pick(ndims() - 3, ncw, nchw, ncdhw)
+ : utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c);
+ auto dst_tag =
+ utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c);
+ auto wei_tag = with_groups()
+ ? utils::pick(2 * ndims() - 6 + flat, gOIw8i8o, gOwi8o,
+ gOIhw8i8o, gOhwi8o, gOIdhw8i8o, gOdhwi8o)
+ : utils::pick(2 * ndims() - 6 + flat, OIw8i8o, Owi8o,
+ OIhw8i8o, Ohwi8o, OIdhw8i8o, Odhwi8o);
+
+ return set_default_formats_common(src_tag, wei_tag, dst_tag);
+ }
+
+ private:
+ void init_balancers() {
+ const int max_threads = mkldnn_get_max_threads();
+ const size_t max_buffer_size = 1<<21; /* just a heuristic */
+
+ if(with_bias()) {
+ reducer_bia_conf_.init(reduce_balancer_t(max_threads,
+ jcp_.oc_block, jcp_.ngroups * jcp_.nb_oc, jcp_.mb,
+ max_buffer_size));
+ }
+
+ reducer_wei_conf_.init(reduce_balancer_t(max_threads,
+ jcp_.kd * jcp_.kh * jcp_.kw
+ * jcp_.ic_block * jcp_.oc_block,
+ jcp_.ngroups * jcp_.nb_ic * jcp_.nb_oc,
+ jcp_.mb * jcp_.od, max_buffer_size));
+ }
+ };
+
+ jit_avx2_convolution_bwd_weights_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , kernel_(nullptr)
+ , reducer_weights_(nullptr)
+ , reducer_bias_(nullptr)
+ {
+ kernel_ = new jit_avx2_conv_bwd_weights_kernel_f32(pd()->jcp_);
+ reducer_bias_ =
+ new cpu_reducer_t<data_type::f32>(pd()->reducer_bia_conf_);
+ reducer_weights_ =
+ new cpu_reducer_t<data_type::f32>(pd()->reducer_wei_conf_);
+ }
+
+ ~jit_avx2_convolution_bwd_weights_t() {
+ delete kernel_;
+ delete reducer_weights_;
+ delete reducer_bias_;
+ }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_weights(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_weights(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx2_conv_bwd_weights_kernel_f32 *kernel_;
+ cpu_reducer_t<data_type::f32> *reducer_weights_, *reducer_bias_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_conv_kernel.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_conv_kernel.cpp
new file mode 100644
index 0000000000..635b83b2bf
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_conv_kernel.cpp
@@ -0,0 +1,1255 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <float.h>
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_memory.hpp"
+#include "cpu_barrier.hpp"
+
+#include "jit_uni_1x1_conv_utils.hpp"
+#include "jit_avx512_common_1x1_conv_kernel.hpp"
+
+#define GET_OFF(field) offsetof(jit_1x1_conv_call_s, field)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::utils;
+
+using namespace Xbyak;
+
+void jit_avx512_common_1x1_conv_kernel::bcast_loop(int load_loop_blk)
+{
+ mov(aux1_reg_bcast_data, reg_bcast_data);
+ mov(aux_reg_bcast_data, reg_bcast_data);
+
+ mov(aux_reg_output_data, reg_output_data);
+ mov(bcast_loop_iter, EVEX_compress_addr(rsp, bcast_loop_work_offt));
+
+ if (jcp.ver == ver_4fma)
+ {
+ Label bcast_loop;
+ Label bcast_loop_wraparound;
+ Label bcast_loop_out;
+ Label bcast_loop_ur_full;
+
+ cmp(bcast_loop_iter, jcp.ur);
+ jle(bcast_loop_wraparound, T_NEAR);
+
+ L(bcast_loop); {
+ assert(jcp.bcast_block % jcp.ur == 0);
+ int num_substeps = jcp.bcast_block / jcp.ur;
+ assert(num_substeps > 0 && num_substeps < 10);
+ for (int i = 0; i < num_substeps; i++) {
+ reduce_loop(load_loop_blk, jcp.ur, i, false);
+ if (i < num_substeps - 1) {
+ add(aux1_reg_bcast_data, jcp.bcast_loop_bcast_substep);
+ add(aux_reg_output_data, jcp.bcast_loop_output_substep);
+ }
+ else {
+ add(aux1_reg_bcast_data, jcp.bcast_loop_bcast_step
+ - (num_substeps - 1) * jcp.bcast_loop_bcast_substep);
+ add(aux_reg_output_data, jcp.bcast_loop_output_step
+ - (num_substeps - 1) * jcp.bcast_loop_output_substep);
+ }
+ }
+ sub(bcast_loop_iter, jcp.bcast_block);
+ cmp(bcast_loop_iter, jcp.bcast_block);
+ jg(bcast_loop, T_NEAR);
+ }
+
+ L(bcast_loop_wraparound);
+ if (jcp.ur_tail) {
+ je(bcast_loop_ur_full, T_NEAR);
+ reduce_loop(load_loop_blk, jcp.ur_tail, 0, true);
+ jmp(bcast_loop_out, T_NEAR);
+ }
+ L(bcast_loop_ur_full);
+ reduce_loop(load_loop_blk, jcp.ur, 0, true);
+ L(bcast_loop_out);
+ }
+ else
+ {
+ Label bcast_loop;
+ Label bcast_loop_tail;
+
+ cmp(bcast_loop_iter, jcp.ur);
+ jl(bcast_loop_tail, T_NEAR);
+
+ L(bcast_loop); {
+ assert(jcp.bcast_block % jcp.ur == 0);
+ int num_substeps = jcp.bcast_block / jcp.ur;
+ assert(num_substeps > 0 && num_substeps < 10);
+ for (int i = 0; i < num_substeps; i++) {
+ reduce_loop(load_loop_blk, jcp.ur, i, false);
+ if (i < num_substeps - 1) {
+ add(aux1_reg_bcast_data, jcp.bcast_loop_bcast_substep);
+ add(aux_reg_output_data, jcp.bcast_loop_output_substep);
+ }
+ else {
+ add(aux1_reg_bcast_data, jcp.bcast_loop_bcast_step
+ - (num_substeps - 1) * jcp.bcast_loop_bcast_substep);
+ add(aux_reg_output_data, jcp.bcast_loop_output_step
+ - (num_substeps - 1) * jcp.bcast_loop_output_substep);
+ }
+ }
+ sub(bcast_loop_iter, jcp.bcast_block);
+ cmp(bcast_loop_iter, jcp.bcast_block);
+ jge(bcast_loop, T_NEAR);
+ }
+
+ L(bcast_loop_tail);
+ if (jcp.ur_tail) {
+ Label bcast_loop_tail_out;
+ cmp(bcast_loop_iter, 0);
+ jz(bcast_loop_tail_out, T_NEAR);
+ reduce_loop(load_loop_blk, jcp.ur_tail, 0, true);
+ L(bcast_loop_tail_out);
+ }
+ }
+}
+
+void jit_avx512_common_1x1_conv_kernel::reduce_loop(int load_loop_blk,
+ int ur, int substep, bool wraparound)
+{
+ auto vreg_load = [=](int i_load, int i_fma) {
+ return Zmm(utils::rnd_up(ur * load_loop_blk, jcp.fma_step)
+ + jcp.fma_step * i_load + i_fma);
+ };
+
+ auto vreg_accum = [=](int i_load, int i_ur) {
+ return Zmm(i_ur * load_loop_blk + i_load);
+ };
+
+ auto bias_ptr = [=](int i_load) {
+ return EVEX_compress_addr(reg_bias_data,
+ jcp.typesize_out * jcp.oc_block * i_load);
+ };
+
+ auto bcast_ptr = [=](int i_reduce, int i_ur, bool bcast) {
+ assert(i_ur < jcp.ur);
+ assert(i_reduce <= jcp.reduce_loop_unroll);
+ int offt;
+ if (one_of(jcp.prop_kind, forward_training, forward_inference,
+ backward_data)) {
+ assert(jcp.reduce_loop_unroll == jcp.reduce_block);
+ offt = (i_reduce == jcp.reduce_loop_unroll)
+ ? (jcp.bcast_dim + i_ur) * jcp.reduce_loop_unroll
+ : i_ur * jcp.reduce_loop_unroll + i_reduce;
+ } else {
+ if (jcp.transpose_src) {
+ const int reduce_group = i_reduce / 4;
+ const int reduce_shift = i_reduce % 4;
+ offt = 4 * (reduce_group * jcp.ic_block + i_ur) + reduce_shift;
+ }
+ else
+ offt = i_reduce * jcp.ic_block + i_ur;
+ }
+ return EVEX_compress_addr(aux_reg_bcast_data, jcp.typesize_in * offt,
+ bcast);
+ };
+
+ auto load_ptr = [=](int i_reduce, int i_load) {
+ int offt;
+ int u0 = i_reduce % jcp.reduce_loop_unroll;
+ int u1 = i_reduce / jcp.reduce_loop_unroll;
+ offt = (i_load * jcp.reduce_dim + u0) * jcp.load_block;
+ return EVEX_compress_addr(aux_reg_load_data,
+ u1 * jcp.reduce_loop_load_step
+ + jcp.typesize_in * offt);
+ };
+
+ auto output_ptr = [=](int i_load, int i_ur) {
+ if (one_of(jcp.prop_kind, forward_training, forward_inference,
+ backward_data))
+ return EVEX_compress_addr(aux_reg_output_data,
+ (i_load * jcp.bcast_dim + i_ur) * jcp.load_block
+ * jcp.typesize_out);
+ else
+ return ptr[aux_reg_output_data +
+ (i_load
+ ? reg_output_stride * i_load
+ : 0) // TODO: Xbyak should allow 0 scale
+ + jcp.typesize_out * jcp.load_block * i_ur];
+ };
+
+ auto init = [=]() {
+ Label init_done;
+ Label init_zero;
+
+ if (jcp.with_sum) {
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load) {
+ for (int i_ur = 0; i_ur < ur; ++i_ur) {
+ mic_prefetcht1(output_ptr(i_load, i_ur));
+ }
+ }
+ }
+
+ if (jcp.with_bias
+ && one_of(jcp.prop_kind, forward_training, forward_inference)) {
+ test(reg_reduce_pos_flag, FLAG_REDUCE_FIRST);
+ jz(init_zero, T_NEAR);
+
+ for (int i_load = 0; i_load < load_loop_blk; i_load++)
+ for (int i_ur = 0; i_ur < ur; ++i_ur)
+ vmovups(vreg_accum(i_load, i_ur), bias_ptr(i_load));
+ jmp(init_done, T_NEAR);
+ }
+
+ L(init_zero);
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load)
+ for (int i_ur = 0; i_ur < ur; ++i_ur) {
+ auto r = vreg_accum(i_load, i_ur);
+ vpxord(r, r, r);
+ }
+ L(init_done);
+ };
+
+ auto store = [=]() {
+ Label store_noadd;
+ if (!jcp.with_sum) {
+ test(reg_reduce_pos_flag, FLAG_REDUCE_FIRST);
+ jnz(store_noadd, T_NEAR);
+ }
+
+ for (int i_ur = 0; i_ur < ur; ++i_ur)
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load) {
+ auto r = vreg_accum(i_load, i_ur);
+ vaddps(r, r, output_ptr(i_load, i_ur));
+ }
+
+ L(store_noadd);
+ if (jcp.with_eltwise) {
+ Label store_noeltwise;
+ test(reg_reduce_pos_flag, FLAG_REDUCE_LAST);
+ jz(store_noeltwise, T_NEAR);
+
+ eltwise_injector_->compute_vector_range(0, ur * load_loop_blk);
+
+ L(store_noeltwise);
+ }
+
+ auto store_output = [=](bool output_is_aligned) {
+ for (int i_ur = 0; i_ur < ur; ++i_ur)
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load)
+ if (output_is_aligned && jcp.use_vmovntps)
+ vmovntps(output_ptr(i_load, i_ur),
+ vreg_accum(i_load, i_ur));
+ else
+ vmovups(output_ptr(i_load, i_ur),
+ vreg_accum(i_load, i_ur));
+ };
+
+ Label unaligned_store, end_store;
+ test(aux_reg_output_data, cpu_isa_traits<avx512_common>::vlen - 1);
+ jnz(unaligned_store, T_NEAR);
+ store_output(true);
+ jmp(end_store, T_NEAR);
+ L(unaligned_store); {
+ store_output(false);
+ }
+ L(end_store);
+ };
+
+ auto prefetch_callback = [=](int ur, int i_reduce, int i_ur, int i_load,
+ bool last_block, bool wraparound, int reduce_step)
+ {
+ bool pf_ker_l1 = true;
+ bool pf_ker_l2 = wraparound;
+ int n_ops = (jcp.reduce_loop_unroll / reduce_step) * ur * load_loop_blk;
+ int i_op = (i_reduce / reduce_step) * ur * load_loop_blk +
+ i_ur * load_loop_blk + i_load;
+
+ int n_pf_ker_l1 = pf_ker_l1 ? jcp.reduce_block : 0;
+ int n_pf_ker_l2 = pf_ker_l2 && wraparound ? jcp.reduce_block : 0;
+ int n_pf_out_l1 = jcp.use_vmovntps ? 0 : ur;
+
+ int pf_inp_ops = n_ops / 2; // # of operations during which to pf input
+ int pf_inp_trigger;
+ if (jcp.prop_kind == backward_weights)
+ pf_inp_trigger = nstl::max(1, pf_inp_ops / jcp.reduce_block);
+ else
+ pf_inp_trigger = nstl::max(1, pf_inp_ops / ur);
+
+ int n_other_pf =
+ load_loop_blk * (n_pf_ker_l1 + n_pf_ker_l2 + n_pf_out_l1);
+ int n_other_pf_ops = n_ops - pf_inp_ops;
+ int other_pf_trigger
+ = n_other_pf ? nstl::max(1, n_other_pf_ops / n_other_pf) : 0;
+
+ if (i_op < pf_inp_ops && i_op % pf_inp_trigger == 0) {
+ // input prefetches have the highest priority b/c the
+ // first iteration of the kernel block touches all the
+ // cache lines
+ int i_pf = i_op / pf_inp_trigger;
+ auto pf_reg = wraparound && last_block
+ ? reg_bcast_data
+ : (last_block ? aux1_reg_bcast_data
+ : aux_reg_bcast_data);
+ int offt = i_pf;
+ if (jcp.prop_kind == backward_weights) {
+ offt += wraparound && last_block
+ ? 0
+ : (last_block ? jcp.is : jcp.reduce_block);
+ offt *= jcp.bcast_block;
+ } else {
+ offt += wraparound && last_block
+ ? 0
+ : (last_block ? jcp.ur : jcp.bcast_dim);
+ offt *= jcp.reduce_block;
+ }
+ mic_prefetcht0(ptr[pf_reg + offt * jcp.typesize_in]);
+ } else if (i_op >= pf_inp_ops && n_other_pf) {
+ // remaining prefetches are spread among the rest of the
+ // operations; prefetches for output take priority
+ // TODO: spread L2 prefetches among L1 prefetches
+ i_op -= pf_inp_ops;
+ if (i_op % other_pf_trigger == 0) {
+ int i_pf = i_op / (load_loop_blk * other_pf_trigger);
+ if (i_pf < n_pf_ker_l2) {
+ int offt = (i_pf + (i_load + 1) * jcp.reduce_dim)
+ * jcp.load_block;
+ mic_prefetcht1(ptr[aux_reg_load_data
+ + offt * jcp.typesize_in]);
+ } else if (i_pf < n_pf_ker_l2 + n_pf_ker_l1) {
+ i_pf -= n_pf_ker_l2;
+ auto pf_reg = last_block ? reg_load_data
+ : aux_reg_load_data;
+ int offt = (i_pf + i_load * jcp.reduce_dim
+ + (last_block
+ ? (wraparound ? jcp.reduce_dim : 0)
+ : jcp.reduce_block))
+ * jcp.load_block;
+ mic_prefetcht0(ptr[pf_reg + offt * jcp.typesize_in]);
+ } else if (i_pf < n_pf_ker_l1 + n_pf_ker_l2 + n_pf_out_l1) {
+ i_pf -= n_pf_ker_l1 + n_pf_ker_l2;
+ int offt = i_pf * jcp.load_block;
+ mic_prefetcht0(ptr[aux_reg_output_data
+ + offt * jcp.typesize_out]);
+ }
+ }
+ }
+ };
+
+ auto fma_block = [=](bool last_block) {
+ assert(jcp.reduce_loop_unroll % jcp.fma_step == 0);
+
+ int reduce_step = jcp.fma_step;
+
+ for (int i_reduce = 0; i_reduce < jcp.reduce_loop_unroll;
+ i_reduce += reduce_step) {
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load) {
+ // if transposed input data used and if spatial size is
+ // not divided by transpose step (4) then for last reduce step
+ // we should load only needed load_registers data
+ // and clear remaining
+ if (jcp.transpose_src && jcp.is % jcp.fma_step && last_block
+ && i_reduce == jcp.reduce_loop_unroll - reduce_step) {
+ Label load_all;
+ Label load_finish;
+ test(reg_reduce_pos_flag, FLAG_SP_LAST);
+ jz(load_all, T_NEAR);
+
+ const int n_loads = jcp.is % jcp.fma_step;
+ for (int i_fma = 0; i_fma < jcp.fma_step; i_fma++) {
+ if (i_fma < n_loads)
+ vmovups(vreg_load(i_load, i_fma),
+ load_ptr(i_reduce + i_fma, i_load));
+ else
+ vpxord(vreg_load(i_load, i_fma),
+ vreg_load(i_load, i_fma),
+ vreg_load(i_load, i_fma));
+ }
+ jmp(load_finish);
+
+ L(load_all);
+ for (int i_fma = 0; i_fma < jcp.fma_step; i_fma++) {
+ vmovups(vreg_load(i_load, i_fma),
+ load_ptr(i_reduce + i_fma, i_load));
+ }
+ L(load_finish);
+ } else {
+ for (int i_fma = 0; i_fma < jcp.fma_step; i_fma++) {
+ vmovups(vreg_load(i_load, i_fma),
+ load_ptr(i_reduce + i_fma, i_load));
+ }
+ }
+ }
+
+ for (int i_ur = 0; i_ur < ur; ++i_ur) {
+ if (jcp.ver == ver_avx512_core && jcp.expl_bcast
+ && load_loop_blk > 1)
+ vbroadcastss(vreg_bcast, bcast_ptr(i_reduce, i_ur, false));
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load) {
+ if (jcp.ver == ver_4fma)
+ v4fmaddps(vreg_accum(i_load, i_ur),
+ vreg_load(i_load, 0),
+ bcast_ptr(i_reduce, i_ur, false));
+ else if (jcp.ver == ver_avx512_core && jcp.expl_bcast
+ && load_loop_blk > 1)
+ vfmadd231ps(vreg_accum(i_load, i_ur),
+ vreg_load(i_load, 0), vreg_bcast);
+ else
+ vfmadd231ps(vreg_accum(i_load, i_ur),
+ vreg_load(i_load, 0),
+ bcast_ptr(i_reduce, i_ur, true));
+ prefetch_callback(ur, i_reduce, i_ur, i_load,
+ last_block, wraparound, reduce_step);
+ }
+ }
+ }
+ };
+ Label reduce_loop;
+ Label reduce_loop_tail;
+
+ mov(aux_reg_load_data, reg_load_data);
+
+ mov(aux_reg_bcast_data, aux1_reg_bcast_data);
+ init();
+
+ mov(reduce_loop_iter, reg_reduce_loop_work);
+ sub(reduce_loop_iter, jcp.reduce_loop_unroll);
+ jle(reduce_loop_tail, T_NEAR);
+
+ L(reduce_loop); {
+ fma_block(false);
+ add(aux_reg_bcast_data, jcp.reduce_loop_bcast_step);
+ add(aux_reg_load_data, jcp.reduce_loop_load_step);
+ sub(reduce_loop_iter, jcp.reduce_loop_unroll);
+ jg(reduce_loop, T_NEAR);
+ }
+
+ L(reduce_loop_tail);
+ fma_block(true);
+
+ store();
+}
+
+void jit_avx512_common_1x1_conv_kernel::generate()
+{
+ preamble();
+
+ mov(reg_bcast_data, ptr[param1 + GET_OFF(bcast_data)]);
+ mov(reg_load_data, ptr[param1 + GET_OFF(load_data)]);
+ mov(reg_output_data, ptr[param1 + GET_OFF(output_data)]);
+
+ sub(rsp, stack_space_needed);
+
+ if (jcp.with_bias)
+ mov(reg_bias_data, ptr[param1 + GET_OFF(bias_data)]);
+
+ mov(reg_load_loop_work, ptr[param1 + GET_OFF(load_dim)]);
+ mov(reg_bcast_loop_work, ptr[param1 + GET_OFF(bcast_dim)]);
+ mov(EVEX_compress_addr(rsp, bcast_loop_work_offt), reg_bcast_loop_work);
+ mov(reg_reduce_loop_work, ptr[param1 + GET_OFF(reduce_dim)]);
+ mov(reg_reduce_pos_flag, ptr[param1 + GET_OFF(first_last_flag)]);
+ if (one_of(jcp.prop_kind, forward_training, forward_inference))
+ mov(reg_relu_ns, reinterpret_cast<size_t>(&jcp.eltwise.alpha));
+ if (jcp.prop_kind == backward_weights)
+ mov(reg_output_stride, ptr[param1 + GET_OFF(output_stride)]);
+
+ auto load_loop_body = [=](int load_loop_blk) {
+ bcast_loop(load_loop_blk);
+ add(reg_load_data, load_loop_blk * jcp.load_loop_load_step);
+ switch (jcp.prop_kind) {
+ case forward_training:
+ case forward_inference:
+ add(reg_bias_data,
+ load_loop_blk * jcp.load_block * jcp.typesize_out);
+ add(reg_output_data,
+ load_loop_blk * jcp.bcast_dim * jcp.load_block *
+ jcp.typesize_out);
+ break;
+ case backward_data:
+ add(reg_output_data,
+ load_loop_blk * jcp.bcast_dim * jcp.load_block *
+ jcp.typesize_out);
+ break;
+ case backward_weights:
+ for (int i_load = 0; i_load < load_loop_blk; i_load++)
+ add(reg_output_data, reg_output_stride);
+ break;
+ default:
+ assert(!"invalid prop_kind");
+ }
+ sub(reg_load_loop_work, load_loop_blk * jcp.load_loop_iter_step);
+ };
+
+ const int simd_w = 16;
+
+ Label load_loop_blk[7];
+
+ static const int ur_cases_fma_embd_bcast[] = { 2, 4, 5, 8, 14, 32 };
+ static const int ur_cases_fma_expl_bcast[] = { 2, 5, 6, 9, 14, 32 };
+ static const int ur_cases_4fma[] = { 2, 4, 6, 12, 32 };
+
+ const int size_ur_cases_fma
+ = (jcp.ver == ver_avx512_core && jcp.expl_bcast) ?
+ sizeof(ur_cases_fma_expl_bcast) :
+ sizeof(ur_cases_fma_embd_bcast);
+ const int size_ur_cases_4fma = sizeof(ur_cases_4fma);
+
+ const int *ur_cases_fma = (jcp.ver == ver_avx512_core && jcp.expl_bcast) ?
+ ur_cases_fma_expl_bcast :
+ ur_cases_fma_embd_bcast;
+ const int *ur_cases = jcp.ver == ver_4fma ? ur_cases_4fma : ur_cases_fma;
+ const int num_ur_cases =
+ (jcp.ver == ver_4fma ? size_ur_cases_4fma : size_ur_cases_fma)
+ / sizeof(*ur_cases);
+
+ for (int ur_idx = num_ur_cases - 1; ur_idx > 0; ur_idx--) {
+ int label_idx = num_ur_cases - ur_idx - 1;
+ if (jcp.ur <= ur_cases[ur_idx]) {
+ cmp(reg_load_loop_work, simd_w * (label_idx + 1));
+ jle(load_loop_blk[label_idx], T_NEAR);
+ }
+ }
+
+ for (int ur_idx = 0; ur_idx < num_ur_cases; ur_idx++) {
+ if (jcp.ur <= ur_cases[ur_idx]) {
+ int label_idx = num_ur_cases - ur_idx - 1;
+ L(load_loop_blk[label_idx]);
+ {
+ if (label_idx == 0) {
+ cmp(reg_load_loop_work, 0);
+ je(load_loop_blk[num_ur_cases], T_NEAR);
+ }
+ load_loop_body(label_idx + 1);
+ if (label_idx - 1 > 0) {
+ cmp(reg_load_loop_work, 2 * label_idx * simd_w);
+ je(load_loop_blk[label_idx - 1], T_NEAR);
+ }
+ cmp(reg_load_loop_work, (label_idx + 1) * simd_w);
+ jge(load_loop_blk[label_idx]);
+ }
+ for (int idx = label_idx - 1; idx > 0; --idx) {
+ cmp(reg_load_loop_work, simd_w * (idx + 1));
+ je(load_loop_blk[idx], T_NEAR);
+ }
+ if (ur_idx < num_ur_cases - 2) {
+ cmp(reg_load_loop_work, simd_w);
+ jle(load_loop_blk[0], T_NEAR);
+ }
+ }
+ }
+ L(load_loop_blk[num_ur_cases]);
+
+ add(rsp, stack_space_needed);
+
+ postamble();
+
+ if (jcp.with_eltwise)
+ eltwise_injector_->prepare_table();
+}
+
+bool jit_avx512_common_1x1_conv_kernel::post_ops_ok(
+ jit_1x1_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ const auto &p = attr.post_ops_;
+
+ auto is_eltwise = [&](int idx) { return p.entry_[idx].is_eltwise(); };
+ auto is_sum = [&](int idx) { return p.entry_[idx].is_sum(); };
+
+ switch (p.len_) {
+ case 0: return true; // no post_ops
+ case 1: return is_eltwise(0) || is_sum(0); // sum OR eltwise
+ case 2: return is_sum(0) && is_eltwise(1); // sum -> eltwise
+ default: return false;
+ }
+
+ return false;
+}
+
+status_t jit_avx512_common_1x1_conv_kernel::init_conf(jit_1x1_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d, const memory_desc_wrapper &dst_d,
+ const primitive_attr_t &attr, int nthreads, bool reduce_src) {
+ if (!mayiuse(avx512_common)) return status::unimplemented;
+
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+ const int simd_w = cpu_isa_traits<avx512_common>::vlen / sizeof(float);
+ const int ndims = src_d.ndims();
+
+ jcp.prop_kind = cd.prop_kind;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+
+ jcp.oc_without_padding = dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+
+ bool ok_to_pad_channels = true
+ && jcp.ngroups == 1
+ && src_d.data_type() == data_type::f32;
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ jcp.ic = rnd_up(jcp.ic, simd_w);
+ }
+
+ jcp.ih = (ndims == 3) ? 1 : src_d.dims()[2];
+ jcp.iw = src_d.dims()[ndims - 1];
+ jcp.oh = (ndims == 3) ? 1 : dst_d.dims()[2];
+ jcp.ow = dst_d.dims()[ndims - 1];
+
+ jcp.kh = (ndims == 3) ? 1 : weights_d.dims()[with_groups + 2];
+ jcp.kw = weights_d.dims()[with_groups + ndims - 1];
+
+ jcp.t_pad = (ndims == 3) ? 0 : cd.padding[0][0];
+ jcp.l_pad = cd.padding[0][ndims - 3];
+
+ jcp.stride_h = (ndims == 3) ? 1 : cd.strides[0];
+ jcp.stride_w = cd.strides[ndims - 3];
+
+ jcp.with_bias = pick_by_prop_kind(jcp.prop_kind, cd.bias_desc.format_kind,
+ format_kind::undef, cd.diff_bias_desc.format_kind)
+ != format_kind::undef;
+
+ jcp.os = jcp.oh * jcp.ow;
+ jcp.is = jcp.ih * jcp.iw;
+ jcp.tr_is = rnd_up(jcp.is, 4);
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ jcp.with_sum = p.find(primitive_kind::sum) != -1;
+ const int eltwise_ind = p.find(primitive_kind::eltwise);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise) {
+ jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+ if (dst_d.data_type() == data_type::s32) return status::unimplemented;
+ }
+
+ auto dat_tag = pick(ndims - 3, nCw16c, nChw16c);
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ jcp.dst_tag = dst_d.matches_one_of_tag(dat_tag);
+
+ bool args_ok = true
+ && jcp.ngroups == 1
+ && jcp.src_tag == dat_tag
+ && jcp.dst_tag == dat_tag;
+ if (!args_ok) return status::unimplemented;
+
+ args_ok = true
+ && jcp.oc % simd_w == 0 && jcp.ic % simd_w == 0
+ && jcp.t_pad == 0 && jcp.l_pad == 0
+ && jcp.stride_w == 1 && jcp.stride_h == 1 // TODO: support some strides
+ && jcp.kh == 1 && jcp.kw == 1;
+ if (!args_ok) return status::unimplemented;
+
+ jcp.ic_block = jcp.oc_block = simd_w;
+ jcp.transpose_src = false;
+
+ if (everyone_is(data_type::f32, src_d.data_type(),
+ weights_d.data_type(), dst_d.data_type()))
+ {
+ const int is_bwd_d = jcp.prop_kind == backward_data;
+ format_tag_t wei_tag = with_groups
+ ? pick(2 * ndims - 6 + is_bwd_d, gOIw16i16o, gIOw16o16i,
+ gOIhw16i16o, gIOhw16o16i)
+ : pick(2 * ndims - 6 + is_bwd_d, OIw16i16o, IOw16o16i,
+ OIhw16i16o, IOhw16o16i);
+
+ jcp.wei_tag = weights_d.matches_one_of_tag(wei_tag);
+ if (jcp.wei_tag != wei_tag)
+ return status::unimplemented;
+
+ if (jcp.prop_kind != backward_weights && mayiuse(avx512_mic_4ops) &&
+ ((jcp.prop_kind == backward_data) ? jcp.oc_block : jcp.ic_block) % 4
+ == 0) {
+ jcp.ver = ver_4fma;
+ jcp.fma_step = 4;
+ } else if (jcp.prop_kind == backward_weights && mayiuse(avx512_mic_4ops)
+ && !reduce_src
+ /* Heuristic condition for relation of src size to oc. Otherwise
+ the src transposition overhead exceed the benefit from 4fma
+ */
+ && ((jcp.is * jcp.ic) / jcp.oc <= 2048)
+ && mkldnn_thr_syncable()
+ )
+ {
+ jcp.transpose_src = true;
+ jcp.ver = ver_4fma;
+ jcp.fma_step = 4;
+ } else {
+ jcp.ver = (mayiuse(avx512_core)) ? ver_avx512_core : ver_fma;
+ jcp.fma_step = 1;
+ }
+ jcp.typesize_in = sizeof(prec_traits<data_type::f32>::type);
+ jcp.typesize_out = sizeof(prec_traits<data_type::f32>::type);
+ } else {
+ return status::unimplemented;
+ }
+
+ /* once all the formats are set, check the padding consistency */
+ args_ok = true
+ && jcp.ic <= src_d.padded_dims()[1]
+ && jcp.oc <= dst_d.padded_dims()[1]
+ && jcp.ic <= weights_d.padded_dims()[with_groups + 1]
+ && jcp.oc <= weights_d.padded_dims()[with_groups + 0];
+ if (!args_ok) return status::unimplemented;
+
+ const int SMALL_SPATIAL = 10;
+ const int BIG_SPATIAL = 28;
+ const int BIG_REDUCE_DIM = 1024;
+ const int BIG_LOAD_DIM = 256;
+
+ int load_blocking{ 0 };
+ int load_blocking_max{ 0 };
+ int bcast_blocking{ 0 };
+ int bcast_blocking_max{ 0 };
+ int reduce_blocking{ 0 };
+ int reduce_blocking_max{ 0 };
+
+ jcp.load_grp_count = 1;
+
+ const int L1_capacity = get_cache_size(1, true) / sizeof(float);
+ const int L2_size = get_cache_size(2, true) / sizeof(float);
+ const int L2_capacity = (L2_size * 3) / 4;
+
+ if (one_of(jcp.prop_kind, forward_training, forward_inference,
+ backward_data)) {
+ if (one_of(jcp.prop_kind, forward_training, forward_inference)) {
+ jcp.reduce_dim = jcp.ic;
+ jcp.reduce_block = jcp.ic_block;
+
+ jcp.load_dim = jcp.oc;
+ jcp.load_block = jcp.oc_block;
+
+ jcp.bcast_dim = jcp.is;
+ } else {
+ jcp.reduce_dim = jcp.oc;
+ jcp.reduce_block = jcp.oc_block;
+
+ jcp.load_dim = jcp.ic;
+ jcp.load_block = jcp.ic_block;
+
+ jcp.bcast_dim = jcp.os;
+ }
+ jcp.reduce_loop_unroll = jcp.reduce_block;
+ jcp.reduce_loop_bcast_step
+ = jcp.reduce_loop_unroll * jcp.bcast_dim * jcp.typesize_in;
+
+ jcp.reduce_loop_load_step
+ = jcp.reduce_loop_unroll * jcp.load_block * jcp.typesize_in;
+ jcp.load_loop_load_step
+ = jcp.reduce_dim * jcp.load_block * jcp.typesize_in;
+
+ // adjusting registry blocking
+ int max_regs, min_regs, size_treshold, ur_step;
+ const int spatial
+ = (one_of(jcp.prop_kind, forward_training, forward_inference)) ?
+ jcp.oh :
+ jcp.ih;
+ if (jcp.ver == ver_avx512_core && (8 * jcp.mb) / nthreads >= 1) {
+ max_regs = 9;
+ min_regs = 6;
+ size_treshold = 14;
+ ur_step = 1;
+ jcp.expl_bcast = true;
+
+ if (jcp.load_dim > 128 && jcp.load_dim < BIG_LOAD_DIM
+ && spatial > SMALL_SPATIAL && spatial < BIG_SPATIAL) {
+ max_regs = 6;
+ min_regs = 5;
+ }
+ } else {
+ max_regs = jcp.ver == ver_4fma ? 28 : 30;
+ min_regs = 9;
+ size_treshold = jcp.ver == ver_4fma ? 28 : 14;
+ ur_step = jcp.ver == ver_4fma ? 4 : 1;
+ jcp.expl_bcast = false;
+ jcp.use_vmovntps = true;
+ }
+ jcp.ur = 1;
+ for (int ur_w = max_regs; ur_w >= min_regs; ur_w -= ur_step) {
+ if ((spatial >= size_treshold && spatial % ur_w == 0)
+ || (spatial < size_treshold && jcp.os % ur_w == 0)) {
+ jcp.ur = ur_w;
+ break;
+ }
+ }
+ if (jcp.ur == 1) {
+ jcp.ur = nstl::min(max_regs, jcp.os);
+ int os_tail = jcp.os % max_regs;
+ for (int i = max_regs; i >= min_regs; i -= ur_step) {
+ int i_tail = jcp.os % i;
+ if (i_tail > os_tail || i_tail == 0) {
+ jcp.ur = i;
+ os_tail = i_tail;
+ if (i_tail == 0)
+ break;
+ }
+ }
+ }
+
+ jcp.reduce_loop_unroll = jcp.reduce_block;
+ jcp.reduce_loop_bcast_step
+ = jcp.reduce_loop_unroll * jcp.bcast_dim * jcp.typesize_in;
+
+ jcp.bcast_block = jcp.ur;
+
+ jcp.bcast_loop_output_step = jcp.ur * jcp.load_block * jcp.typesize_out;
+ jcp.bcast_loop_output_substep = -1; // unused
+ jcp.bcast_loop_bcast_step = jcp.ur * jcp.reduce_block * jcp.typesize_in;
+ jcp.bcast_loop_bcast_substep = -1; // unused
+
+ jcp.load_loop_iter_step = jcp.load_block;
+
+ if (jcp.prop_kind == backward_data)
+ jcp.loop_order = loop_lbr;
+ else
+ jcp.loop_order = reduce_src ? loop_blr : loop_lbr;
+
+ int nb_bcast = div_up(jcp.bcast_dim, jcp.bcast_block);
+ int nb_reduce = div_up(jcp.reduce_dim, jcp.reduce_block);
+ int nb_load = div_up(jcp.load_dim, jcp.load_block);
+
+ if (jcp.ver == ver_avx512_core && jcp.expl_bcast) {
+ if (jcp.load_dim <= BIG_LOAD_DIM && spatial > SMALL_SPATIAL
+ && spatial < BIG_SPATIAL)
+ reduce_blocking = nstl::min(jcp.reduce_dim, 80);
+ else if (spatial > SMALL_SPATIAL)
+ reduce_blocking = nstl::min(jcp.reduce_dim, 512);
+ else
+ reduce_blocking = nstl::min(jcp.reduce_dim, 256);
+
+ if ((jcp.mb > 28 && spatial >= 28)
+ || (jcp.mb > 112 && spatial >= 17))
+ jcp.use_vmovntps = true;
+ else
+ jcp.use_vmovntps = false;
+ } else {
+
+ reduce_blocking = nb_reduce;
+ if (spatial <= SMALL_SPATIAL && jcp.reduce_dim >= BIG_REDUCE_DIM)
+ reduce_blocking = 16;
+ else if (spatial > SMALL_SPATIAL
+ && jcp.reduce_dim >= BIG_REDUCE_DIM)
+ reduce_blocking = 8;
+ reduce_blocking = best_divider(nb_reduce, 1, reduce_blocking, true);
+ reduce_blocking *= jcp.reduce_block;
+ }
+
+ // Check input data cache aliasing.
+ // For other ISA constants may be updated.
+ // 64 * 1024 is chosen due to 1MB L2 16-way cache.
+ // 7 is empirical value. It is about half of 16.
+ // So we leave about half of the set for other data - weights, dst
+ int way_size = (64 * 1024) / jcp.typesize_in;
+ int max_hits = 7;
+ if (jcp.bcast_dim * reduce_blocking > way_size * max_hits) {
+ int nrb = reduce_blocking / simd_w;
+ int sp = jcp.bcast_dim;
+ int wl = way_size / simd_w;
+ for (int start_off = 0; start_off < jcp.ur; start_off++) {
+ for (int off = start_off, hits = 0; off < sp * nrb; off += wl) {
+ if (off % sp >= jcp.ur || ++hits < max_hits)
+ continue;
+ int max_r_blocking = simd_w * nstl::max(1, (off + wl) / sp);
+ reduce_blocking
+ = nstl::min(reduce_blocking, max_r_blocking);
+ break;
+ }
+ }
+ }
+
+ if (reduce_blocking < jcp.reduce_dim) {
+ jcp.use_vmovntps = false;
+ if (jcp.prop_kind == backward_data)
+ jcp.loop_order = reduce_src ? loop_lbr : loop_rlb;
+ else
+ jcp.loop_order = reduce_src ? loop_rbl : loop_rlb;
+ }
+ load_blocking = jcp.load_dim;
+
+ int load_size = jcp.load_dim * jcp.reduce_dim;
+ int bcast_size = jcp.mb * jcp.ngroups * jcp.bcast_dim * jcp.reduce_dim;
+
+ if (jcp.ver == ver_avx512_core && nthreads <= 28 && jcp.mb < nthreads
+ && nb_load * nb_bcast > nthreads) {
+ // Some heuristic here
+ float calc_koef = 0.01, best_cost = FLT_MAX;
+ int n_lgc = nthreads;
+ float ratio = (float)load_size / (float)bcast_size;
+ int best_lgc = ratio > 1 ? n_lgc : 1;
+ auto calc_job_cost = [&](int lb, int tg, float mem_k) {
+ int bb_size = jcp.mb * div_up(nb_bcast, tg);
+ float calc_size = (float)(bb_size * jcp.ur)
+ * (lb * jcp.load_block) * jcp.reduce_dim;
+ float mem_size = (float)(bb_size * jcp.ur + lb * jcp.load_block)
+ * jcp.reduce_dim;
+ return calc_koef * calc_size + mem_k * mem_size;
+ };
+ for (int lgc, ilgc = 0; ilgc < n_lgc; ilgc++) {
+ lgc = ratio > 1 ? n_lgc - ilgc : ilgc + 1;
+ int min_lb = nb_load / lgc;
+ int max_lb = div_up(nb_load, lgc);
+ int min_tg = nthreads / lgc;
+ int max_tg = div_up(nthreads, lgc);
+ // Some heuristic here
+ float mem_koef = (max_tg == 1) ? 1.f : 1.3f;
+ float job_cost = 0.;
+ if (nthreads % lgc < nb_load % lgc) {
+ job_cost = calc_job_cost(max_lb, min_tg, mem_koef);
+ } else {
+ auto job_cost1 = calc_job_cost(max_lb, max_tg, mem_koef);
+ auto job_cost2 = calc_job_cost(min_lb, min_tg, mem_koef);
+ job_cost = nstl::max(job_cost1, job_cost2);
+ }
+
+ if (job_cost < best_cost) {
+ best_lgc = lgc;
+ best_cost = job_cost;
+ }
+ }
+ jcp.load_grp_count = best_lgc;
+ load_blocking = div_up(nb_load, jcp.load_grp_count) * jcp.load_block;
+ } else {
+ jcp.load_grp_count = div_up(nthreads, jcp.mb * jcp.ngroups * nb_bcast);
+ jcp.load_grp_count = best_divider(
+ nthreads, jcp.load_grp_count, 2 * jcp.load_grp_count, false);
+ }
+
+ if (jcp.ver == ver_avx512_core && jcp.expl_bcast && jcp.bcast_dim <= 64
+ && load_size >= L2_size) {
+ jcp.load_grp_count = nstl::max(jcp.load_grp_count, 4);
+ } else if (jcp.bcast_dim <= 49 && jcp.mb <= nthreads
+ && jcp.load_dim > 512 && jcp.load_dim / jcp.reduce_dim >= 4) {
+ jcp.load_grp_count = nstl::max(jcp.load_grp_count, 2);
+ load_blocking = jcp.load_block;
+ }
+
+ if (jcp.ver == ver_4fma && jcp.bcast_dim * jcp.mb < jcp.load_dim
+ && jcp.oh * jcp.ow > 64
+ && IMPLICATION(reduce_src, jcp.load_dim < 1024)) {
+ /* Looking for best loading dimension blocking
+ * to get the best thread and data read/write efficiency
+ * by finding the optimal 'load_chunk' value
+ * Example:
+ * for 72 threads and convolution with mb=1, ih=iw=7, oc = 512
+ * the 'best' load_chunk value should be 1
+ * TODO: remove heuristic constants in above condition
+ * TODO: check this blocking for other ISA
+ */
+ float best_eff = -1.f;
+ int best_lgc = 1;
+
+ for (int load_chunk = 1; load_chunk <= nb_load; load_chunk++) {
+ int lgc = div_up(nb_load, load_chunk);
+ if (lgc > nthreads)
+ continue;
+ int thr_per_grp = div_up(nthreads, lgc);
+ int bcast_per_thr = div_up(jcp.mb * nb_bcast, thr_per_grp)
+ * jcp.bcast_block;
+ int load_per_thr = load_chunk * simd_w;
+ float data_norm = (bcast_per_thr + load_per_thr) / 2.f;
+ float data_eff = (bcast_per_thr * load_per_thr)
+ / (data_norm * data_norm);
+ float thr_eff_over_grp = (float)nstl::max(1, nthreads / lgc)
+ / div_up(nthreads, lgc);
+ float thr_eff_in_grp = ((float)jcp.mb * nb_bcast)
+ / rnd_up(jcp.mb * nb_bcast, thr_per_grp);
+ float thr_eff = thr_eff_over_grp * thr_eff_in_grp;
+ float load_eff = (float)nb_load / rnd_up(nb_load, lgc);
+ float overall_eff = data_eff + thr_eff + load_eff;
+ if (overall_eff > best_eff) {
+ best_eff = overall_eff;
+ best_lgc = lgc;
+ }
+ }
+ jcp.load_grp_count = best_lgc;
+ load_blocking
+ = div_up(nb_load, jcp.load_grp_count) * jcp.load_block;
+ }
+ bcast_blocking = div_up(jcp.mb * jcp.ngroups * nb_bcast,
+ div_up(nthreads, jcp.load_grp_count))
+ * jcp.bcast_block;
+ bcast_blocking = nstl::min(jcp.bcast_dim, bcast_blocking);
+ bcast_blocking = rnd_up(bcast_blocking, jcp.bcast_block);
+
+ int space_for_bcast
+ = (L2_capacity - /* kernel_size - */
+ 2 * jcp.load_block * reduce_blocking
+ - jcp.ur * reduce_blocking - 3 * 1024);
+ if (jcp.reduce_dim * jcp.bcast_dim > L2_capacity)
+ space_for_bcast /= 2;
+
+ int bcast_in_cache
+ = nstl::max(jcp.bcast_block, space_for_bcast / reduce_blocking);
+ bcast_blocking = nstl::min(
+ bcast_blocking, rnd_dn(bcast_in_cache, jcp.bcast_block));
+
+ load_blocking_max = load_blocking;
+ bcast_blocking_max = bcast_blocking * 3 / 2;
+ reduce_blocking_max = reduce_blocking;
+
+ } else if (jcp.prop_kind == backward_weights) {
+
+ jcp.use_vmovntps = false;
+ if (jcp.is > SMALL_SPATIAL * SMALL_SPATIAL && jcp.ver == ver_4fma)
+ jcp.use_vmovntps = true;
+
+ if (jcp.transpose_src)
+ jcp.reduce_dim = jcp.tr_is;
+ else
+ jcp.reduce_dim = jcp.is;
+
+ if (jcp.ver == ver_4fma) {
+ // reduce_block should be divided by fma_step
+ jcp.reduce_block = best_divider(jcp.reduce_dim, 4, 16, true, 4);
+ } else {
+ jcp.reduce_block = best_divider(jcp.reduce_dim, 7, 16, true);
+ if (jcp.reduce_dim % jcp.reduce_block != 0)
+ jcp.reduce_block = best_divider(jcp.iw, 4, jcp.iw, false);
+ if (jcp.reduce_block > 256) {
+ jcp.reduce_block = 1;
+ }
+
+ }
+
+ jcp.load_dim = jcp.oc;
+ jcp.load_block = jcp.oc_block;
+
+ jcp.bcast_dim = jcp.ic;
+ jcp.bcast_block = jcp.ic_block;
+
+ if (jcp.ver == ver_avx512_core && jcp.reduce_block <= 19) {
+ // if reduce_block is big then generated JIT code may be big
+ // for small values of ur because reduce_loop_unroll = reduce_block
+ jcp.ur = jcp.bcast_block / 2;
+ jcp.expl_bcast = true;
+ } else {
+ jcp.ur = jcp.bcast_block;
+ jcp.expl_bcast = false;
+ }
+
+ jcp.reduce_loop_unroll = jcp.reduce_block;
+ jcp.reduce_loop_bcast_step
+ = jcp.reduce_loop_unroll * jcp.ic_block * jcp.typesize_in;
+ jcp.reduce_loop_load_step
+ = jcp.reduce_loop_unroll * jcp.oc_block * jcp.typesize_in;
+
+ jcp.bcast_loop_output_step =
+ jcp.oc_block * jcp.ic_block * jcp.typesize_out;
+ jcp.bcast_loop_output_substep =
+ jcp.oc_block * jcp.ur * jcp.typesize_out;
+ jcp.bcast_loop_bcast_step =
+ jcp.ic_block * jcp.reduce_dim * jcp.typesize_in;
+ jcp.bcast_loop_bcast_substep = jcp.ur * jcp.typesize_in;
+
+ jcp.load_loop_load_step = jcp.oc_block * jcp.os * jcp.typesize_in;
+ jcp.load_loop_iter_step = jcp.oc_block;
+
+ /* --- */
+ balance(jcp, nthreads);
+
+ load_blocking = div_up(jcp.load_dim, jcp.load_block);
+ load_blocking = best_divider(load_blocking, 16, load_blocking, false);
+ load_blocking *= jcp.load_block;
+
+ load_blocking_max = load_blocking;
+ assert(jcp.load_dim % load_blocking == 0);
+
+ int max_bcast_blocking = div_up(jcp.bcast_dim, jcp.bcast_block);
+ int min_bcast_blocking = 5;
+
+ bcast_blocking = div_up(jcp.bcast_dim, jcp.bcast_block);
+ bcast_blocking = best_divider(
+ bcast_blocking, min_bcast_blocking, max_bcast_blocking, false);
+ bcast_blocking *= jcp.bcast_block;
+ bcast_blocking_max = bcast_blocking;
+ assert(jcp.bcast_dim % bcast_blocking == 0);
+
+ // for reduction balance
+ if (jcp.ver == ver_avx512_core) {
+ int max_reduce_blocking
+ = nstl::min(L1_capacity / jcp.ur, jcp.reduce_dim);
+ int min_reduce_blocking = nstl::min(
+ L1_capacity / jcp.ur, nstl::max(jcp.iw, jcp.ih));
+ reduce_blocking = best_divider(jcp.reduce_dim, min_reduce_blocking,
+ max_reduce_blocking, true);
+ reduce_blocking
+ = nstl::max(rnd_dn(reduce_blocking, jcp.reduce_block),
+ jcp.reduce_block);
+ } else {
+ int max_reduce_blocking = L2_capacity
+ / ((bcast_blocking + load_blocking) * jcp.reduce_block);
+ max_reduce_blocking = nstl::min(max_reduce_blocking,
+ (L1_capacity / (jcp.bcast_block)) / jcp.reduce_block);
+
+ int num_jobs = div_up(jcp.load_dim, load_blocking)
+ * div_up(jcp.bcast_dim, bcast_blocking);
+ int threads_per_job = nstl::max(1, nthreads / num_jobs);
+ reduce_blocking = div_up(jcp.mb * jcp.reduce_dim, jcp.reduce_block);
+ reduce_blocking = div_up(reduce_blocking, threads_per_job);
+
+ reduce_blocking = best_divider(reduce_blocking,
+ max_reduce_blocking - 2, max_reduce_blocking, true);
+ reduce_blocking *= jcp.reduce_block;
+ }
+
+ reduce_blocking_max = rnd_dn(reduce_blocking * 3 / 2, jcp.reduce_block);
+ } else
+ return status::unimplemented;
+
+ assert(load_blocking);
+ assert(load_blocking_max);
+ assert(bcast_blocking);
+ assert(bcast_blocking_max);
+ assert(reduce_blocking);
+ assert(reduce_blocking_max);
+ assert(load_blocking % jcp.load_block == 0);
+ assert(reduce_blocking % jcp.reduce_block == 0);
+ assert(load_blocking_max % jcp.load_block == 0);
+ assert(reduce_blocking_max % jcp.reduce_block == 0);
+ if (jcp.ver == ver_4fma) {
+ assert(jcp.reduce_loop_unroll % jcp.fma_step == 0);
+ assert(jcp.reduce_dim % jcp.reduce_loop_unroll == 0);
+ }
+
+ assert(jcp.bcast_block % jcp.ur == 0);
+ assert(jcp.reduce_dim % jcp.reduce_block == 0);
+
+ jcp.ur_tail = jcp.bcast_dim % jcp.ur;
+
+ jcp.nb_bcast_blocking = bcast_blocking / jcp.bcast_block;
+ jcp.nb_bcast_blocking_max = bcast_blocking_max / jcp.bcast_block;
+ jcp.nb_load_blocking = load_blocking / jcp.load_block;
+ jcp.nb_load_blocking_max = load_blocking_max / jcp.load_block;
+ jcp.nb_reduce_blocking = reduce_blocking / jcp.reduce_block;
+ jcp.nb_reduce_blocking_max = reduce_blocking_max / jcp.reduce_block;
+
+ jcp.nb_bcast = div_up(jcp.bcast_dim, jcp.bcast_block);
+ jcp.nb_load = div_up(jcp.load_dim, jcp.load_block);
+ jcp.nb_reduce = div_up(jcp.reduce_dim, jcp.reduce_block);
+
+ return status::success;
+}
+
+void jit_avx512_common_1x1_conv_kernel::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad,
+ const jit_1x1_conv_conf_t &jcp) {
+ using namespace mkldnn::impl::memory_tracking::names;
+
+ if (jcp.prop_kind != backward_data && jcp.with_bias
+ && jcp.oc != jcp.oc_without_padding)
+ scratchpad.book(key_conv_padded_bias, jcp.typesize_out * jcp.oc);
+
+ if (jcp.prop_kind == backward_weights) {
+ const size_t wei_size = (size_t)jcp.ngroups * jcp.oc * jcp.ic;
+ scratchpad.book(key_conv_wei_reduction,
+ jcp.typesize_out * wei_size * (jcp.nthr_mb - 1));
+ }
+
+ if (jcp.transpose_src) {
+ const size_t tr_src_size =
+ (size_t)jcp.nthr_mb * jcp.ngroups * jcp.ic * jcp.tr_is;
+ scratchpad.book(key_conv_tr_src, jcp.typesize_out * tr_src_size);
+ scratchpad.book(key_conv_tr_src_bctx,
+ sizeof(simple_barrier::ctx_t) * jcp.nthr);
+ }
+}
+
+void jit_avx512_common_1x1_conv_kernel::balance(jit_1x1_conv_conf_t &jcp,
+ int nthreads)
+{
+ // initialize jcp reduction threading properties
+ jcp.nthr = jcp.nthr_mb = jcp.nthr_g = jcp.nthr_oc_b = jcp.nthr_ic_b = 1;
+ if (nthreads < jcp.ngroups) {
+ /* simplification... fortunately it doesn't hurt much */
+ return;
+ }
+ const int nb_bcast = div_up(jcp.bcast_dim, jcp.bcast_block);
+ const int nb_load = div_up(jcp.load_dim, jcp.load_block);
+ const int nb_reduce = div_up(jcp.reduce_dim, jcp.reduce_block);
+
+ jcp.nthr_g = jcp.ngroups;
+ const int nthr = nthreads / jcp.nthr_g;
+
+ auto calc_mem_cost = [=](int nthr_mb, int nthr_oc_b, int nthr_ic_b) {
+ /* calculate per thread memory cost (read/write). high level
+ * optimizer tries to minimize memory consumption. few notes: (n1)
+ * unclear why, but that essentially helps first convolution...
+ * (n2) assuming the reduction over minibatch is always there:
+ * - instead of 8 it should be 5 here (write ~= 2 read):
+ * kernel: temporal workspace 1 write
+ * reduction: 1 read from workspace and 1 write to the diff_wei
+ * - but experiments showed 8 works better than 5 or 6... */
+ int bcast_koeff = 1;
+ int load_koeff = 1;
+ int output_koeff = 12;
+ if (jcp.transpose_src) {
+ bcast_koeff = 5;
+ load_koeff = 1;
+ output_koeff = 8;
+ }
+ return 0
+ + (size_t)bcast_koeff * div_up(jcp.mb * nb_reduce, nthr_mb)
+ * div_up(jcp.ngroups, jcp.nthr_g)
+ * div_up(nb_bcast, nthr_ic_b) * jcp.ic_block * jcp.reduce_block
+ / jcp.stride_h / jcp.stride_w /* (n1) */
+ + (size_t)load_koeff * div_up(jcp.mb * nb_reduce, nthr_mb)
+ * div_up(jcp.ngroups, jcp.nthr_g)
+ * div_up(nb_load, nthr_oc_b) * jcp.oc_block * jcp.reduce_block
+ + (size_t)output_koeff /* (n2) */
+ * div_up(jcp.ngroups, jcp.nthr_g) * div_up(nb_load, nthr_oc_b)
+ * div_up(nb_bcast, nthr_ic_b) * jcp.ic_block
+ * jcp.oc_block;
+ };
+
+ int nthr_mb = 1, nthr_oc_b = 1, nthr_ic_b = 1;
+ auto best_mem_cost = calc_mem_cost(nthr_mb, nthr_oc_b, nthr_ic_b);
+
+ /* step 1: find the best thread distribution with lowest memory cost */
+ const int nthr_mb_max = nstl::min(nthr, jcp.mb * nb_reduce);
+ for (nthr_mb = 1; nthr_mb <= nthr_mb_max; ++nthr_mb) {
+ const int nthr_par = nthr / nthr_mb;
+ const int nthr_oc_b_max = nstl::min(nthr_par, nb_load);
+ for (nthr_oc_b = 1; nthr_oc_b <= nthr_oc_b_max; ++nthr_oc_b) {
+ nthr_ic_b = nstl::min(nthr_par / nthr_oc_b, nb_bcast);
+ auto mem_cost = calc_mem_cost(nthr_mb, nthr_oc_b, nthr_ic_b);
+ if (mem_cost <= best_mem_cost) {
+ best_mem_cost = mem_cost;
+ jcp.nthr_mb = nthr_mb;
+ jcp.nthr_oc_b = nthr_oc_b;
+ jcp.nthr_ic_b = nthr_ic_b;
+ }
+ }
+
+ if (!mkldnn_thr_syncable()) { assert(nthr_mb == 1); break; }
+ }
+ if (jcp.nthr_mb > nthreads / 2 && jcp.nthr_mb < nthreads)
+ jcp.nthr_mb = nstl::min(jcp.mb, nthreads);
+
+ jcp.nthr = jcp.nthr_mb * jcp.nthr_g * jcp.nthr_oc_b * jcp.nthr_ic_b;
+ assert(jcp.nthr <= nthreads);
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_conv_kernel.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_conv_kernel.hpp
new file mode 100644
index 0000000000..d2ae017943
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_conv_kernel.hpp
@@ -0,0 +1,108 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_AVX512_COMMON_1x1_CONV_KERNEL_HPP
+#define JIT_AVX512_COMMON_1x1_CONV_KERNEL_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+#include "jit_uni_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_avx512_common_1x1_conv_kernel : public jit_generator {
+ jit_avx512_common_1x1_conv_kernel(jit_1x1_conv_conf_t ajcp,
+ const primitive_attr_t &attr)
+ : jcp(ajcp), attr_(attr), eltwise_injector_(nullptr)
+ {
+ if (jcp.with_eltwise)
+ eltwise_injector_ = new jit_uni_eltwise_injector_f32<avx512_common>(
+ this, jcp.eltwise);
+
+ this->generate();
+ jit_ker = (void (*)(jit_1x1_conv_call_s *)) this->getCode();
+ }
+
+ ~jit_avx512_common_1x1_conv_kernel() {
+ delete eltwise_injector_;
+ }
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_common_1x1_conv_kernel)
+
+ static bool post_ops_ok(jit_1x1_conv_conf_t &jcp,
+ const primitive_attr_t &attr);
+
+ static status_t init_conf(jit_1x1_conv_conf_t &jcp,
+ const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d,
+ const primitive_attr_t &attr,
+ int nthreads, bool reduce_src);
+
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_1x1_conv_conf_t &jcp);
+
+ jit_1x1_conv_conf_t jcp;
+ const primitive_attr_t &attr_;
+ void (*jit_ker)(jit_1x1_conv_call_s *);
+
+ private:
+ using reg64_t = const Xbyak::Reg64;
+ using zmm_t = const Xbyak::Zmm;
+
+ reg64_t reg_bcast_data = r8;
+ reg64_t reg_load_data = r10;
+ reg64_t reg_output_data = r9;
+ reg64_t aux_reg_bcast_data = r14;
+ reg64_t aux1_reg_bcast_data = rbx;
+ reg64_t aux_reg_load_data = r15;
+ reg64_t imm_addr64 = aux_reg_load_data;
+ reg64_t aux_reg_output_data = abi_not_param1;
+ reg64_t reg_load_loop_work = rsi;
+ reg64_t reg_reduce_loop_work = r11;
+ reg64_t bcast_loop_iter = rdx;
+ reg64_t reduce_loop_iter = abi_param1;
+ reg64_t reg_reduce_pos_flag = rax;
+ reg64_t reg_output_stride = r13;
+ reg64_t reg_bias_data = r12;
+ reg64_t reg_relu_ns = r13;
+ reg64_t reg_bcast_loop_work = aux1_reg_bcast_data;
+
+ Xbyak::Zmm vreg_bcast = Xbyak::Zmm(31);
+
+ jit_uni_eltwise_injector_f32<avx512_common> *eltwise_injector_;
+
+ int bcast_loop_work_offt = 0;
+ int stack_space_needed = 16;
+
+ void bcast_loop(int load_loop_blk);
+ void reduce_loop(int load_loop_blk, int ur, int substep, bool wraparound);
+
+ void generate();
+ static void balance(jit_1x1_conv_conf_t &jcp, int nthreads);
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_convolution.cpp
new file mode 100644
index 0000000000..54d58c8a39
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_convolution.cpp
@@ -0,0 +1,816 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_generator.hpp"
+
+#include "jit_avx512_common_1x1_convolution.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+
+#define data_blk_off(f, n, c, h, w) \
+ ((ndims == 3) \
+ ? (f).blk_off(n, c, w) \
+ : (f).blk_off(n, c, h, w))
+
+
+namespace {
+template <typename T, typename U>
+void balance2D(U nthr, U ithr, T ny, T &ny_start, T &ny_end,
+ T nx, T &nx_start, T &nx_end, T nx_divider)
+{
+ const int grp_count = nstl::min(nx_divider, nthr);
+ const int grp_size_big = nthr / grp_count + 1;
+ const int grp_size_small = nthr / grp_count;
+ const int n_grp_big = nthr % grp_count;
+ const int threads_in_big_groups = n_grp_big * grp_size_big;
+
+ const int ithr_bound_distance = ithr - threads_in_big_groups;
+ T grp, grp_ithr, grp_nthr;
+ if (ithr_bound_distance < 0) { // ithr in first groups
+ grp = ithr / grp_size_big;
+ grp_ithr = ithr % grp_size_big;
+ grp_nthr = grp_size_big;
+ } else { // ithr in last groups
+ grp = n_grp_big + ithr_bound_distance / grp_size_small;
+ grp_ithr = ithr_bound_distance % grp_size_small;
+ grp_nthr = grp_size_small;
+ }
+
+ balance211(nx, grp_count, grp, nx_start, nx_end);
+ balance211(ny, grp_nthr, grp_ithr, ny_start, ny_end);
+}
+}
+/* convolution forward */
+
+template <data_type_t src_type, data_type_t wei_type, data_type_t dst_type>
+void jit_avx512_common_1x1_convolution_fwd_t<src_type, wei_type, dst_type>::
+execute_forward(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const dst_data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ auto scratchpad = this->scratchpad(ctx);
+
+ const auto &jcp = kernel_->jcp;
+ if (pd()->wants_padded_bias()) {
+ auto padded_bias = scratchpad.template get<dst_data_t>(
+ key_conv_padded_bias);
+ utils::array_copy(padded_bias, bias, jcp.oc_without_padding);
+ utils::array_set(padded_bias + jcp.oc_without_padding, 0.f,
+ jcp.oc - jcp.oc_without_padding);
+ bias = padded_bias;
+ }
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ execute_forward_thr(ithr, nthr, src, weights, bias, dst, scratchpad);
+ });
+
+ if (pd()->wants_zero_pad_dst())
+ ctx.memory(MKLDNN_ARG_DST)->zero_pad();
+}
+
+template <data_type_t src_type, data_type_t wei_type, data_type_t dst_type>
+void jit_avx512_common_1x1_convolution_fwd_t<src_type, wei_type, dst_type>::
+execute_forward_thr(const int ithr, const int nthr, const src_data_t *src,
+ const wei_data_t *weights, const dst_data_t *bias, dst_data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const {
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+ auto rtus_space = scratchpad.get<src_data_t>(key_conv_rtus_space);
+
+ const int ndims = src_d.ndims();
+ const int stride_h = (ndims == 3) ? 1 : pd()->desc()->strides[0];
+ const int stride_w = pd()->desc()->strides[ndims - 3];
+ const int pad_t = (ndims == 3) ? 0 : pd()->desc()->padding[0][0];
+ const int pad_l = pd()->desc()->padding[0][ndims - 3];
+
+ const int work_amount = jcp.mb * jcp.ngroups * jcp.nb_bcast;
+
+ auto step = [](int default_step, int remaining, int tail_step) {
+ assert(default_step <= tail_step);
+ return remaining < tail_step ? remaining : default_step;
+ };
+
+ auto p = jit_1x1_conv_call_s();
+
+ auto rp = rtus_driver_t<avx512_common>::call_params_t();
+
+ const int nb_oc = jcp.nb_load;
+ const int nb_ic = jcp.nb_reduce;
+ const int nb_ic_blocking = jcp.nb_reduce_blocking;
+ const int os_block = jcp.bcast_block;
+
+ int bcast_start{0}, bcast_end{0}, ocb_start{0}, ocb_end{0};
+ balance2D(nthr, ithr, work_amount, bcast_start, bcast_end,
+ jcp.nb_load, ocb_start, ocb_end, jcp.load_grp_count);
+
+ auto init_bcast = [&](int iwork, int &n, int &g, int &bcast_step,
+ int &oh, int &ow, int &ih, int &iw)
+ {
+ int osb{0};
+ nd_iterator_init(iwork, n, jcp.mb, g, jcp.ngroups, osb,
+ jcp.nb_bcast);
+ bcast_step = step(jcp.nb_bcast_blocking, jcp.nb_bcast - osb,
+ jcp.nb_bcast_blocking_max);
+ bcast_step = nstl::min(bcast_step, bcast_end - iwork);
+
+ const int os = osb * os_block;
+ oh = os / jcp.ow;
+ ow = os % jcp.ow;
+
+ ih = nstl::max(oh * stride_h - pad_t, 0);
+ iw = nstl::max(ow * stride_w - pad_l, 0);
+ rp.iw_start = iw;
+
+ p.bcast_dim = this_block_size(os, jcp.os,
+ bcast_step * os_block);
+ rp.os = p.bcast_dim;
+ };
+
+ auto init_load = [&](int ocb, int &load_step)
+ {
+ load_step = step(jcp.nb_load_blocking, ocb_end - ocb,
+ jcp.nb_load_blocking_max);
+ p.load_dim = this_block_size(ocb * jcp.oc_block,
+ ocb_end * jcp.oc_block, load_step * jcp.oc_block);
+ };
+
+ auto init_reduce = [&](int icb)
+ {
+ const int nb_ic_blocking_step =
+ nstl::min(icb + nb_ic_blocking, nb_ic) - icb;
+ p.first_last_flag = 0
+ | (icb == 0 ? FLAG_REDUCE_FIRST : 0)
+ | (icb + nb_ic_blocking_step >= nb_ic
+ ? FLAG_REDUCE_LAST : 0);
+
+ p.reduce_dim = this_block_size(icb * jcp.ic_block,
+ jcp.ic, nb_ic_blocking_step * jcp.ic_block);
+ rp.icb = p.reduce_dim / jcp.reduce_block;
+ };
+
+ auto inner_ker = [&](int ocb, int icb, int n, int g, int oh, int ow,
+ int ih, int iw)
+ {
+
+ const int _ocb = g * nb_oc + ocb;
+ const size_t dst_off = data_blk_off(dst_d, n, _ocb, oh, ow);
+
+ p.output_data = &dst[dst_off];
+ p.bias_data = &bias[_ocb * jcp.oc_block];
+ p.load_data = &weights[pd()->with_groups()
+ ? weights_d.blk_off(g, ocb, icb)
+ : weights_d.blk_off(ocb, icb)];
+
+ const int _icb = g * nb_ic + icb;
+ if (pd()->rtus_.reduce_src_) {
+ rp.ws = rtus_space + ithr * pd()->rtus_.space_per_thread_
+ + _icb * jcp.is * jcp.ic_block;
+ if (ocb == ocb_start) {
+ rp.src = src + data_blk_off(src_d, n, _icb, ih, iw);
+ rtus_driver_->ker_(&rp);
+ }
+ p.bcast_data = rp.ws;
+ } else
+ p.bcast_data = src + data_blk_off(src_d, n, _icb, ih, iw);
+
+ kernel_->jit_ker(&p);
+ };
+
+ if (jcp.loop_order == loop_rlb) {
+ for (int icb = 0; icb < nb_ic; icb += nb_ic_blocking) {
+ init_reduce(icb);
+ int ocb = ocb_start;
+ while (ocb < ocb_end) {
+ int load_step;
+ init_load(ocb, load_step);
+ int iwork = bcast_start;
+ while (iwork < bcast_end) {
+ int n, g, bcast_step, oh, ow, ih, iw;
+ init_bcast(iwork, n, g, bcast_step, oh, ow, ih, iw);
+ inner_ker(ocb, icb, n, g, oh, ow, ih, iw);
+ iwork += bcast_step;
+ }
+ ocb += load_step;
+ }
+ }
+ } else if (jcp.loop_order == loop_lbr) {
+ int ocb = ocb_start;
+ while (ocb < ocb_end) {
+ int load_step;
+ init_load(ocb, load_step);
+ int iwork = bcast_start;
+ while (iwork < bcast_end) {
+ int n, g, bcast_step, oh, ow, ih, iw;
+ init_bcast(iwork, n, g, bcast_step, oh, ow, ih, iw);
+ for (int icb = 0; icb < nb_ic; icb += nb_ic_blocking) {
+ init_reduce(icb);
+ inner_ker(ocb, icb, n, g, oh, ow, ih, iw);
+ }
+ iwork += bcast_step;
+ }
+ ocb += load_step;
+ }
+ } else if (jcp.loop_order == loop_rbl) {
+ for (int icb = 0; icb < nb_ic; icb += nb_ic_blocking) {
+ init_reduce(icb);
+ int iwork = bcast_start;
+ while (iwork < bcast_end) {
+ int n, g, bcast_step, oh, ow, ih, iw;
+ init_bcast(iwork, n, g, bcast_step, oh, ow, ih, iw);
+ int ocb = ocb_start;
+ while (ocb < ocb_end) {
+ int load_step;
+ init_load(ocb, load_step);
+ inner_ker(ocb, icb, n, g, oh, ow, ih, iw);
+ ocb += load_step;
+ }
+ iwork += bcast_step;
+ }
+ }
+ } else if (jcp.loop_order == loop_blr) {
+ int iwork = bcast_start;
+ while (iwork < bcast_end) {
+ int n, g, bcast_step, oh, ow, ih, iw;
+ init_bcast(iwork, n, g, bcast_step, oh, ow, ih, iw);
+ int ocb = ocb_start;
+ while (ocb < ocb_end) {
+ int load_step;
+ init_load(ocb, load_step);
+ for (int icb = 0; icb < nb_ic; icb += nb_ic_blocking) {
+ init_reduce(icb);
+ inner_ker(ocb, icb, n, g, oh, ow, ih, iw);
+ }
+ ocb += load_step;
+ }
+ iwork += bcast_step;
+ }
+ } else {
+ assert(!"unsupported loop order");
+ }
+}
+
+
+template struct jit_avx512_common_1x1_convolution_fwd_t<data_type::f32>;
+/* convolution backward wtr data */
+
+template <data_type_t diff_dst_type, data_type_t wei_type,
+ data_type_t diff_src_type>
+void jit_avx512_common_1x1_convolution_bwd_data_t<diff_dst_type, wei_type,
+ diff_src_type>::execute_backward_data(const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const diff_dst_data_t *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(diff_src_data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+
+ const auto &jcp = kernel_->jcp;
+ auto rtus_space = scratchpad(ctx).template get<diff_src_data_t>(
+ key_conv_rtus_space);
+
+ const int ndims = diff_src_d.ndims();
+
+ // TODO (Roma): remove this restriction
+ assert(jcp.stride_w == 1 && jcp.stride_h == 1);
+
+ const int stride_h = (ndims == 3) ? 1 : pd()->desc()->strides[0];
+ const int stride_w = pd()->desc()->strides[ndims - 3];
+ const int pad_t = (ndims == 3) ? 0 : pd()->desc()->padding[0][0];
+ const int pad_l = pd()->desc()->padding[0][ndims - 3];
+
+ const int nb_ic = jcp.nb_load;
+ const int nb_oc = jcp.nb_reduce;
+ const int os_block = jcp.bcast_block;
+ const int nb_oc_blocking = jcp.nb_reduce_blocking;
+
+ const int work_amount = jcp.mb * jcp.ngroups * jcp.nb_bcast;
+
+ auto step = [](int default_step, int remaining, int tail_step) {
+ assert(default_step <= tail_step);
+ return remaining < tail_step ? remaining : default_step;
+ };
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ auto p = jit_1x1_conv_call_s();
+ auto rp = rtus_driver_t<avx512_common>::call_params_t();
+
+ int bcast_start{0}, bcast_end{0}, icb_start{0}, icb_end{0};
+ balance2D(nthr, ithr, work_amount, bcast_start, bcast_end,
+ jcp.nb_load, icb_start, icb_end, jcp.load_grp_count);
+
+ bool reduce_outer = (jcp.loop_order == loop_rbl
+ || jcp.loop_order == loop_rlb);
+ int nboc_outer = reduce_outer ? nb_oc : 1;
+ int ocb_outer_step = reduce_outer ? nb_oc_blocking : 1;
+
+ int nboc_inner = reduce_outer ? 1 : nb_oc;
+ int ocb_inner_step = reduce_outer ? 1 : nb_oc_blocking;
+
+ for (int ocb_outer = 0; ocb_outer < nboc_outer;
+ ocb_outer += ocb_outer_step) {
+ size_t cur_ocb_outer =
+ nstl::min(ocb_outer + ocb_outer_step, nboc_outer) - ocb_outer;
+
+ int load_step = 0;
+ for (int icb = icb_start; icb < icb_end; icb += load_step) {
+ load_step = step(jcp.nb_load_blocking, jcp.nb_load - icb,
+ jcp.nb_load_blocking_max);
+
+ p.load_dim = this_block_size(icb * jcp.ic_block,
+ icb_end * jcp.ic_block, load_step * jcp.ic_block);
+ rp.icb = p.load_dim / jcp.ic_block;
+
+ int bcast_step;
+ for (int iwork = bcast_start; iwork < bcast_end;
+ iwork += bcast_step)
+ {
+ int n{0}, g{0}, osb{0};
+ nd_iterator_init(iwork, n, jcp.mb, g, jcp.ngroups, osb,
+ jcp.nb_bcast);
+
+ bcast_step = step(jcp.nb_bcast_blocking, jcp.nb_bcast - osb,
+ jcp.nb_bcast_blocking_max);
+ bcast_step = nstl::min(bcast_step, bcast_end - iwork);
+
+ const int os = osb * os_block;
+ p.bcast_dim = this_block_size(os, jcp.os,
+ bcast_step * os_block);
+ rp.os = p.bcast_dim;
+
+ const int oh = os / jcp.ow;
+ const int ow = os % jcp.ow;
+ const int ih = nstl::max(oh * stride_h - pad_t, 0);
+ const int iw = nstl::max(ow * stride_w - pad_l, 0);
+ rp.iw_start = iw;
+
+ const int _icb = g * nb_ic + icb;
+ rp.src = diff_src + data_blk_off(diff_src_d, n, _icb, ih, iw);
+ if (pd()->rtus_.reduce_src_) {
+ rp.ws = rtus_space
+ + ithr * pd()->rtus_.space_per_thread_;
+ p.output_data = rp.ws;
+ } else
+ p.output_data = rp.src;
+
+ for (int ocb_inner = 0; ocb_inner < nboc_inner;
+ ocb_inner += ocb_inner_step) {
+ int cur_ocb_inner =
+ nstl::min(ocb_inner + ocb_inner_step, nboc_inner) -
+ ocb_inner;
+
+ int ocb = reduce_outer ? ocb_outer : ocb_inner;
+ int nb_oc_blocking_step = reduce_outer
+ ? cur_ocb_outer : cur_ocb_inner;
+ const int _ocb = g * nb_oc + ocb;
+ size_t diff_dst_off = data_blk_off(diff_dst_d, n, _ocb, oh, ow);
+ p.bcast_data = &diff_dst[diff_dst_off];
+
+ p.load_data = &weights[pd()->with_groups()
+ ? weights_d.blk_off(g, ocb, icb)
+ : weights_d.blk_off(ocb, icb)];
+
+ p.first_last_flag = ocb == 0 ? FLAG_REDUCE_FIRST : 0;
+
+ p.reduce_dim = this_block_size(ocb * jcp.oc_block,
+ jcp.oc, nb_oc_blocking_step * jcp.oc_block);
+
+ kernel_->jit_ker(&p);
+ }
+ if (pd()->rtus_.reduce_src_)
+ rtus_driver_->ker_(&rp);
+ }
+ }
+ }
+ });
+}
+
+template struct jit_avx512_common_1x1_convolution_bwd_data_t<data_type::f32>;
+
+/* convolution backward wtr weights */
+
+#define wht_blk_off(d, g, ...) \
+ (pd()->with_groups() \
+ ? (d).blk_off((g), __VA_ARGS__) \
+ : (d).blk_off(__VA_ARGS__))
+
+jit_avx512_common_1x1_convolution_bwd_weights_t ::
+ jit_avx512_common_1x1_convolution_bwd_weights_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , kernel_(nullptr), acc_ker_(nullptr), reducer_bias_(nullptr)
+ , trans_kernel_(nullptr), rtus_driver_(nullptr)
+{
+ kernel_ = new jit_avx512_common_1x1_conv_kernel(pd()->jcp_, *pd()->attr());
+ acc_ker_ = new cpu_accumulator_1d_t<data_type::f32>();
+ reducer_bias_ = new cpu_reducer_t<data_type::f32>(pd()->reducer_bia_conf_);
+ init_rtus_driver<avx512_common>(this);
+
+ const auto &jcp = kernel_->jcp;
+
+ if (jcp.transpose_src) {
+ auto tp = jit_transpose4x16_src_t();
+ tp.src_pf0_distance = 4;
+ tp.tr_src_pf0_distance = 0;
+ tp.src_pf1 = true;
+ tp.tr_src_pf1 = false;
+ trans_kernel_ = new jit_transpose4x16_src(&jcp, &tp);
+ }
+}
+
+void jit_avx512_common_1x1_convolution_bwd_weights_t::execute_backward_weights(
+ const exec_ctx_t &ctx) const
+{
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_weights = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_WEIGHTS);
+ auto diff_bias_in = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_BIAS);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper diff_weights_d(pd()->diff_weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+
+ const auto scratchpad = this->scratchpad(ctx);
+
+ auto rtus_space = scratchpad.get<data_t>(key_conv_rtus_space);
+ data_t *diff_bias = pd()->wants_padded_bias()
+ ? scratchpad.get<data_t>(key_conv_padded_bias) : diff_bias_in;
+ auto wei_reduction = scratchpad.get<data_t>(key_conv_wei_reduction);
+
+ /* prepare src transposition barriers */
+ auto tr_src = scratchpad.get<data_t>(key_conv_tr_src);
+ auto tr_src_bctx = scratchpad.get<simple_barrier::ctx_t>(
+ key_conv_tr_src_bctx);
+ if (jcp.transpose_src) {
+ for (int i = 0; i < jcp.nthr; ++i)
+ simple_barrier::ctx_init(&tr_src_bctx[i]);
+ }
+
+ const int ndims = src_d.ndims();
+ const int wei_size = jcp.ngroups * jcp.oc * jcp.ic;
+
+ simple_barrier::ctx_t reduction_barrier;
+ simple_barrier::ctx_init(&reduction_barrier);
+
+ const auto reducer_bia_scratchpad = memory_tracking::grantor_t(scratchpad,
+ prefix_reducer_bia);
+ auto rb = this->reducer_bias_;
+ rb->init(reducer_bia_scratchpad);
+
+ // TODO (Roma): remove this restriction
+ assert(jcp.stride_w == 1 && jcp.stride_h == 1);
+
+ const int nb_ic = jcp.nb_bcast;
+ const int nb_ic_blocking = jcp.nb_bcast_blocking;
+
+ const int nb_oc = jcp.nb_load;
+ const int nb_oc_blocking = jcp.nb_load_blocking;
+
+ const int sp_nb = jcp.nb_reduce;
+ const int mb_sp_work = jcp.mb * sp_nb;
+
+ const int stride_h = (ndims == 3) ? 1 : pd()->desc()->strides[0];
+ const int stride_w = pd()->desc()->strides[ndims - 3];
+ const int pad_t = (ndims == 3) ? 0 : pd()->desc()->padding[0][0];
+ const int pad_l = pd()->desc()->padding[0][ndims - 3];
+
+ auto step = [](int default_step, int remaining, int tail_step) {
+ assert(default_step <= tail_step);
+ return remaining < tail_step ? remaining : default_step;
+ };
+
+ // TODO: use memory descriptor with the same fmt as src
+ // (or use a macro :))
+ auto tr_src_off = [&](int img, int icb, int is) {
+ const size_t tr_chn_size = jcp.tr_is * jcp.ic_block;
+ const size_t tr_img_size = tr_chn_size * nb_ic * jcp.ngroups;
+ return img * tr_img_size + icb * tr_chn_size + is * jcp.ic_block;
+ };
+
+ auto uker_trans = [&](int ithr_mb, int img, int sp_b_start, int sp_size,
+ int g_start, int g_work, int ic_b_start, int ic_b_work,
+ int ithr, int nthr, int first_ic_b)
+ {
+ const int work_amount = g_work * ic_b_work;
+
+ int start{ 0 }, end{ 0 };
+ balance211(work_amount, nthr, ithr, start, end);
+
+ int g{ 0 }, ic_b{ 0 };
+ nd_iterator_init(start, g, g_work, ic_b, ic_b_work);
+ g += g_start;
+ const int ic_b_tr = g * nb_ic + first_ic_b + ic_b;
+ ic_b += ic_b_start;
+
+ const int _ic = g * nb_ic + ic_b;
+
+ const int is = sp_b_start * jcp.reduce_block;
+ const int ih = is / jcp.iw;
+ const int iw = is % jcp.iw;
+
+ const int src1_off = data_blk_off(src_d, img, _ic, ih, iw);
+ data_t *src1 = (data_t *)&src[src1_off];
+ data_t *tr_src1 = &tr_src[tr_src_off(ithr_mb, ic_b_tr, is)];
+
+ assert(jcp.ic_block == 16);
+ const int src_stride = jcp.is * jcp.ic_block;
+ const int tr_src_stride = jcp.tr_is * jcp.ic_block;
+
+ const int my_work = end - start;
+ for (int iwork = 0; iwork < my_work; iwork++) {
+ auto par_trans = jit_src_transpose_s();
+ assert(sp_size % 4 == 0 || sp_size % 4 == jcp.is % 4);
+ par_trans.size = sp_size;
+ par_trans.src = src1;
+ par_trans.tr_src = tr_src1;
+ par_trans.src_prf = src1 + 64 * 16;
+ par_trans.tr_src_prf = tr_src1 + 80 * 16;
+ trans_kernel_->jit_ker(&par_trans);
+
+ src1 += src_stride;
+ tr_src1 += tr_src_stride;
+ }
+ };
+
+ auto ker = [&](const int ithr, const int nthr) {
+ assert(nthr == jcp.nthr);
+ assert(IMPLICATION(!mkldnn_thr_syncable(), jcp.nthr_mb == 1));
+
+ const int ithr_ic_b = ithr % jcp.nthr_ic_b;
+ const int ithr_oc_b = ithr / jcp.nthr_ic_b % jcp.nthr_oc_b;
+ const int ithr_g = ithr / jcp.nthr_ic_b / jcp.nthr_oc_b % jcp.nthr_g;
+ const int ithr_mb = ithr / jcp.nthr_ic_b / jcp.nthr_oc_b /
+ jcp.nthr_g;
+
+ const int ithr_but_oc
+ = (ithr_mb * jcp.nthr_g + ithr_g) * jcp.nthr_ic_b + ithr_ic_b;
+
+ /* reduction dimension */
+ int mb_sp_b_start{ 0 }, mb_sp_b_end{ 0 };
+ if (jcp.transpose_src && jcp.nthr_mb < jcp.mb / 2) {
+ // it's preferable to parallelize by mb if possible
+ int img_start{ 0 }, img_end{ 0 };
+ balance211(jcp.mb, jcp.nthr_mb, ithr_mb, img_start, img_end);
+ mb_sp_b_start = img_start * sp_nb;
+ mb_sp_b_end = img_end * sp_nb;
+ }
+ else {
+ balance211(mb_sp_work, jcp.nthr_mb, ithr_mb, mb_sp_b_start,
+ mb_sp_b_end);
+ }
+
+ /* independent dimensions */
+ int g_start{ 0 }, oc_b_start{ 0 }, ic_b_start{ 0 };
+ int g_end{ 0 }, oc_b_end{ 0 }, ic_b_end{ 0 };
+
+ balance211(jcp.ngroups, jcp.nthr_g, ithr_g, g_start, g_end);
+ balance211(jcp.nb_load, jcp.nthr_oc_b, ithr_oc_b, oc_b_start,
+ oc_b_end);
+ balance211(jcp.nb_bcast, jcp.nthr_ic_b, ithr_ic_b, ic_b_start,
+ ic_b_end);
+
+ const int g_work = g_end - g_start;
+ const int oc_b_work = oc_b_end - oc_b_start;
+ const int ic_b_work = ic_b_end - ic_b_start;
+
+ data_t *diff_wei = ithr_mb == 0
+ ? diff_weights : wei_reduction + (ithr_mb - 1) * wei_size;
+
+ int sp_b_step = 0;
+ for (int mb_sp_b = mb_sp_b_start; mb_sp_b < mb_sp_b_end;
+ mb_sp_b += sp_b_step) {
+ int img{ 0 }, sp_b{ 0 };
+ nd_iterator_init(mb_sp_b, img, jcp.mb, sp_b, sp_nb);
+ sp_b_step = step(jcp.nb_reduce_blocking,
+ nstl::min(sp_nb - sp_b, mb_sp_b_end - mb_sp_b),
+ jcp.nb_reduce_blocking_max);
+
+ for (int g = g_start; g < g_end; ++g) {
+ int load_step = 0;
+ int bcast_step = 0;
+ for (int ic_b = ic_b_start; ic_b < ic_b_end;
+ ic_b += bcast_step) {
+ bcast_step = step(nb_ic_blocking, ic_b_end - ic_b,
+ jcp.nb_bcast_blocking_max);
+ if (jcp.transpose_src) {
+ if (jcp.nthr_oc_b > 1)
+ simple_barrier::barrier(
+ &tr_src_bctx[ithr_but_oc], jcp.nthr_oc_b);
+ const int sp_size
+ = nstl::min(sp_b_step * jcp.reduce_block,
+ jcp.is - sp_b * jcp.reduce_block);
+ uker_trans(ithr_mb, img, sp_b, sp_size, g, 1, ic_b,
+ bcast_step, ithr_oc_b, jcp.nthr_oc_b, ic_b_start);
+ if (jcp.nthr_oc_b > 1)
+ simple_barrier::barrier(
+ &tr_src_bctx[ithr_but_oc], jcp.nthr_oc_b);
+ }
+
+ for (int oc_b = oc_b_start; oc_b < oc_b_end;
+ oc_b += load_step) {
+ load_step = step(nb_oc_blocking, oc_b_end - oc_b,
+ jcp.nb_load_blocking_max);
+ const int _ic_b = g * nb_ic + ic_b;
+ const int _ic_b_tr = g * nb_ic + ic_b_start;
+ const int _oc_b = g * nb_oc + oc_b;
+
+ data_t *store_to;
+
+ const size_t off
+ = wht_blk_off(diff_weights_d, g, oc_b, ic_b);
+ store_to = diff_wei + off;
+
+ const data_t *diff_src = jcp.transpose_src ?
+ &tr_src[tr_src_off(ithr_mb, _ic_b_tr, 0)] :
+ &src[src_d.blk_off(img, _ic_b)];
+
+ int sp_b_end = sp_b + sp_b_step;
+ const data_t *pdiff_dst
+ = &diff_dst[diff_dst_d.blk_off(img, _oc_b)];
+ const data_t *local_src = diff_src;
+
+ auto p = jit_1x1_conv_call_s();
+ auto rp = rtus_driver_t<avx512_common>::call_params_t();
+
+ p.output_stride
+ = jcp.ic * jcp.oc_block * jcp.typesize_out;
+
+ p.load_dim = load_step * jcp.oc_block;
+
+ p.bcast_dim = bcast_step * jcp.ic_block;
+ rp.icb = bcast_step;
+ p.output_data = store_to;
+
+ p.reduce_dim = sp_b_step * jcp.reduce_block;
+ rp.os = p.reduce_dim;
+
+ p.first_last_flag = 0
+ | (mb_sp_b == mb_sp_b_start ? FLAG_REDUCE_FIRST : 0)
+ | (sp_b_end == sp_nb ? FLAG_SP_LAST : 0);
+
+ int sp = sp_b * jcp.reduce_block;
+ p.load_data = pdiff_dst + sp * jcp.oc_block;
+
+ if (pd()->rtus_.reduce_src_) {
+ const int oh = sp / jcp.ow;
+ const int ow = sp % jcp.ow;
+
+ const int ih = nstl::max(oh * stride_h - pad_t, 0);
+ const int iw = nstl::max(ow * stride_w - pad_l, 0);
+ rp.iw_start = iw;
+
+ rp.ws = rtus_space
+ + ithr * pd()->rtus_.space_per_thread_
+ + sp * jcp.ic_block;
+
+ if (ndims == 3)
+ rp.src = local_src + iw
+ * src_d.blocking_desc().strides[2];
+ else
+ rp.src = local_src + ih
+ * src_d.blocking_desc().strides[2]
+ + iw * src_d.blocking_desc().strides[3];
+ rtus_driver_->ker_(&rp);
+
+ p.bcast_data = rp.ws;
+ } else
+ p.bcast_data = local_src + sp * jcp.ic_block;
+
+ kernel_->jit_ker(&p);
+ }
+ }
+ }
+ }
+
+ /* diff_weights[:] += sum(wei_reduction[thr_mb][:]) */
+ if (jcp.nthr_mb > 1) {
+ simple_barrier::barrier(&reduction_barrier, jcp.nthr);
+ const int work = g_work * oc_b_work * ic_b_work;
+ int start{ 0 }, end{ 0 };
+ balance211(work, jcp.nthr_mb, ithr_mb, start, end);
+ if (start == end)
+ return;
+
+ for (int thr_mb = 1; thr_mb < jcp.nthr_mb; ++thr_mb) {
+ int w = start;
+ int sub_g_start{ 0 }, sub_oc_b_start{ 0 },
+ sub_ic_b_start{ 0 };
+ nd_iterator_init(w, sub_g_start, g_work, sub_oc_b_start,
+ oc_b_work, sub_ic_b_start, ic_b_work);
+ while (w < end) {
+ const int g = g_start + sub_g_start;
+ const int oc_b = oc_b_start + sub_oc_b_start;
+ const int ic_b = ic_b_start + sub_ic_b_start;
+
+ const int acc_size
+ = nstl::min(end - w, ic_b_work - sub_ic_b_start)
+ * jcp.ic_block * jcp.oc_block;
+
+ const size_t off
+ = wht_blk_off(diff_weights_d, g, oc_b, ic_b);
+ data_t *d = diff_weights + off;
+ data_t *s = wei_reduction + (thr_mb - 1) * wei_size + off;
+
+ acc_ker_->accumulate(d, s, acc_size);
+
+ nd_iterator_jump(w, end, sub_g_start, g_work,
+ sub_oc_b_start, oc_b_work, sub_ic_b_start,
+ ic_b_work);
+ }
+ }
+ }
+ };
+
+ auto ker_bias = [&](int ithr, int nthr) {
+ assert(nthr == rb->balancer().nthr_);
+
+ const int b_job_start = rb->balancer().ithr_job_off(ithr);
+ const int b_njobs = rb->balancer().ithr_njobs(ithr);
+
+ if (b_njobs == 0)
+ return;
+
+ /* reduction dimension */
+ int img_start{ 0 }, img_end{ 0 };
+
+ balance211(jcp.mb, rb->balancer().nthr_per_group_,
+ rb->balancer().id_in_group(ithr), img_start, img_end);
+
+ /* jobs */
+ int g_start{ 0 }, ocb_start{ 0 };
+ nd_iterator_init(
+ b_job_start, g_start, jcp.ngroups, ocb_start, jcp.nb_load);
+
+ for (int img = img_start; img < img_end; ++img) {
+ int g = g_start, ocb = ocb_start;
+ for (int b_job_loc = 0; b_job_loc < b_njobs; ++b_job_loc) {
+ const size_t _oc = g * jcp.nb_load + ocb;
+
+ const data_t *d_dst = &diff_dst[diff_dst_d.blk_off(img, _oc)];
+ data_t *d_bias = rb->get_local_ptr(ithr, diff_bias,
+ reducer_bia_scratchpad)
+ + b_job_loc * rb->balancer().job_size_;
+
+ if (img == img_start)
+ for (int o = 0; o < 16; ++o)
+ d_bias[o] = 0.;
+
+ for (int hw = 0; hw < jcp.oh * jcp.ow; ++hw) {
+ PRAGMA_OMP_SIMD()
+ for (int o = 0; o < 16; ++o)
+ d_bias[o] += d_dst[o];
+ d_dst += 16;
+ }
+
+ nd_iterator_step(g, jcp.ngroups, ocb, jcp.nb_load);
+ }
+ }
+ rb->reduce(ithr, diff_bias, reducer_bia_scratchpad);
+ };
+
+ parallel(jcp.nthr, [&](const int ithr, const int nthr) {
+ ker(ithr, jcp.nthr);
+ if (pd()->with_bias())
+ ker_bias(ithr, jcp.nthr);
+ });
+
+ /* TODO: put this in ker_bias */
+ if (pd()->wants_padded_bias()) {
+ assert(jcp.ngroups == 1);
+ utils::array_copy(diff_bias_in, diff_bias, jcp.oc_without_padding);
+ }
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_convolution.hpp
new file mode 100644
index 0000000000..2e9fda76d6
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_1x1_convolution.hpp
@@ -0,0 +1,344 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_COMMON_1x1_CONVOLUTION_HPP
+#define CPU_JIT_AVX512_COMMON_1x1_CONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+#include "cpu_reducer.hpp"
+
+#include "jit_avx512_common_1x1_conv_kernel.hpp"
+#include "jit_uni_1x1_conv_utils.hpp"
+#include "jit_transpose_src_utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t src_type,
+ impl::data_type_t wei_type = src_type,
+ impl::data_type_t dst_type = src_type>
+struct jit_avx512_common_1x1_convolution_fwd_t : public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_(), rtus_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_1x1:", avx512_common, ""),
+ jit_avx512_common_1x1_convolution_fwd_t);
+
+ status_t init() {
+ using namespace utils;
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(src_type, wei_type, dst_type, dst_type,
+ data_type::undef)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ const convolution_desc_t *conv_d = desc();
+ const memory_desc_t *src_d = src_md();
+ rtus_prepare(this, conv_d, src_d, dst_md());
+
+ status_t status = jit_avx512_common_1x1_conv_kernel::init_conf(
+ jcp_, *conv_d, *src_d, *weights_md(), *dst_md(), *attr(),
+ mkldnn_get_max_threads(), rtus_.reduce_src_);
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx512_common_1x1_conv_kernel::init_scratchpad(scratchpad,
+ jcp_);
+
+ rtus_prepare_space_info(this, scratchpad);
+
+ return status::success;
+ }
+
+ jit_1x1_conv_conf_t jcp_;
+ reduce_to_unit_stride_t rtus_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = utils::pick(ndims() - 3, nCw16c, nChw16c, nCdhw16c);
+ auto wei_tag = utils::pick(2 * ndims() - 6 + with_groups(),
+ OIw16i16o, gOIw16i16o, OIhw16i16o, gOIhw16i16o);
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ template <cpu_isa_t isa, typename conv_t>
+ friend void init_rtus_driver(conv_t *self);
+
+ jit_avx512_common_1x1_convolution_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , kernel_(nullptr), rtus_driver_(nullptr)
+ {
+ kernel_ =
+ new jit_avx512_common_1x1_conv_kernel(pd()->jcp_, *pd()->attr());
+ init_rtus_driver<avx512_common>(this);
+ }
+
+ ~jit_avx512_common_1x1_convolution_fwd_t() {
+ delete kernel_;
+ delete rtus_driver_;
+ }
+
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<wei_type>::type wei_data_t;
+ typedef typename prec_traits<dst_type>::type dst_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+ private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ void execute_forward_thr(const int ithr, const int nthr,
+ const src_data_t *src, const wei_data_t *weights,
+ const dst_data_t *bias, dst_data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx512_common_1x1_conv_kernel *kernel_;
+ rtus_driver_t<avx512_common> *rtus_driver_;
+};
+
+using jit_avx512_common_1x1_convolution_fwd_f32_t
+ = jit_avx512_common_1x1_convolution_fwd_t<data_type::f32>;
+
+template <impl::data_type_t diff_dst_type,
+ impl::data_type_t wei_type = diff_dst_type,
+ impl::data_type_t diff_src_type = diff_dst_type>
+struct jit_avx512_common_1x1_convolution_bwd_data_t : public cpu_primitive_t {
+ struct pd_t : public cpu_convolution_bwd_data_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_data_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_(), rtus_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_1x1:", avx512_common, ""),
+ jit_avx512_common_1x1_convolution_bwd_data_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_data
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(diff_src_type, wei_type, data_type::undef,
+ diff_dst_type, data_type::undef)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ const convolution_desc_t *conv_d = desc();
+ const memory_desc_t *diff_src_d = diff_src_md();
+ rtus_prepare(this, conv_d, diff_src_d, diff_dst_md());
+
+ status_t status = jit_avx512_common_1x1_conv_kernel::init_conf(
+ jcp_, *conv_d, *diff_src_d, *weights_md(), *diff_dst_md(),
+ *attr(), mkldnn_get_max_threads(), rtus_.reduce_src_);
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx512_common_1x1_conv_kernel::init_scratchpad(scratchpad,
+ jcp_);
+
+ rtus_prepare_space_info(this, scratchpad);
+
+ return status::success;
+ }
+
+ // TODO (Roma): structs conf header cleanup
+ jit_1x1_conv_conf_t jcp_;
+ reduce_to_unit_stride_t rtus_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = utils::pick(ndims() - 3, nCw16c, nChw16c, nCdhw16c);
+ auto wei_tag = utils::pick(2 * ndims() - 6 + with_groups(),
+ IOw16o16i, gIOw16o16i, IOhw16o16i, gIOhw16o16i);
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ template <cpu_isa_t isa, typename conv_t>
+ friend void init_rtus_driver(conv_t *self);
+
+ jit_avx512_common_1x1_convolution_bwd_data_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , kernel_(nullptr), rtus_driver_(nullptr)
+ {
+ kernel_ = new jit_avx512_common_1x1_conv_kernel(pd()->jcp_,
+ *pd()->attr());
+ init_rtus_driver<avx512_common>(this);
+ }
+
+ ~jit_avx512_common_1x1_convolution_bwd_data_t() {
+ delete kernel_;
+ delete rtus_driver_;
+ }
+
+ typedef typename prec_traits<diff_dst_type>::type diff_dst_data_t;
+ typedef typename prec_traits<wei_type>::type wei_data_t;
+ typedef typename prec_traits<diff_src_type>::type diff_src_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_data(ctx);
+ return status::success;
+ }
+
+ private:
+ void execute_backward_data(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx512_common_1x1_conv_kernel *kernel_;
+ rtus_driver_t<avx512_common> *rtus_driver_;
+};
+
+using jit_avx512_common_1x1_convolution_bwd_data_f32_t
+ = jit_avx512_common_1x1_convolution_bwd_data_t<data_type::f32>;
+
+struct jit_avx512_common_1x1_convolution_bwd_weights_t : public cpu_primitive_t
+{
+ struct pd_t : public cpu_convolution_bwd_weights_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_weights_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_(), rtus_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_1x1:", avx512_common, ""),
+ jit_avx512_common_1x1_convolution_bwd_weights_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_weights
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ const convolution_desc_t *conv_d = desc();
+ const memory_desc_t *src_d = src_md();
+ rtus_prepare(this, conv_d, src_d, diff_dst_md());
+
+ status_t status = jit_avx512_common_1x1_conv_kernel::init_conf(
+ jcp_, *conv_d, *src_d, *diff_weights_md(), *diff_dst_md(),
+ *attr(), mkldnn_get_max_threads(), rtus_.reduce_src_);
+ if (status != status::success) return status;
+
+ init_balancers();
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx512_common_1x1_conv_kernel::init_scratchpad(scratchpad,
+ jcp_);
+
+ auto reducer_bia_scratchpad = memory_tracking::registrar_t(
+ scratchpad, memory_tracking::names::prefix_reducer_bia);
+ reducer_bia_conf_.init_scratchpad(reducer_bia_scratchpad);
+
+ rtus_prepare_space_info(this, scratchpad);
+
+ return status::success;
+ }
+
+ // TODO (Roma): structs conf header cleanup
+ jit_1x1_conv_conf_t jcp_;
+ cpu_reducer_t<data_type::f32>::conf_t reducer_bia_conf_;
+ reduce_to_unit_stride_t rtus_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = utils::pick(ndims() - 3, nCw16c, nChw16c, nCdhw16c);
+ auto wei_tag = utils::pick(2 * ndims() - 6 + with_groups(),
+ OIw16i16o, gOIw16i16o, OIhw16i16o, gOIhw16i16o);
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+
+ private:
+ void init_balancers() {
+ const size_t max_buffer_size = jcp_.nthr * 3 * 5 * 5 * 16 * 16;
+ if (with_bias()) {
+ reducer_bia_conf_.init(reduce_balancer_t(jcp_.nthr,
+ jcp_.oc_block, jcp_.ngroups * jcp_.nb_load,
+ jcp_.mb, max_buffer_size));
+ }
+ }
+ };
+
+ template <cpu_isa_t isa, typename conv_t>
+ friend void init_rtus_driver(conv_t *self);
+
+ jit_avx512_common_1x1_convolution_bwd_weights_t(const pd_t *apd);
+
+ ~jit_avx512_common_1x1_convolution_bwd_weights_t() {
+ delete kernel_;
+ delete acc_ker_;
+ delete reducer_bias_;
+ delete rtus_driver_;
+ delete trans_kernel_;
+ }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_weights(ctx);
+ return status::success;
+ }
+
+ private:
+ void execute_backward_weights(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx512_common_1x1_conv_kernel *kernel_;
+ cpu_accumulator_1d_t<data_type::f32> *acc_ker_;
+ cpu_reducer_t<data_type::f32> *reducer_bias_;
+ jit_transpose4x16_src *trans_kernel_;
+ rtus_driver_t<avx512_common> *rtus_driver_;
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_kernel.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_kernel.cpp
new file mode 100644
index 0000000000..235fb02fef
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_kernel.cpp
@@ -0,0 +1,4539 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_barrier.hpp"
+
+#include "jit_avx512_common_conv_kernel.hpp"
+
+#define GET_OFF(field) offsetof(jit_conv_call_s, field)
+#define KNx_L2_EFFECTIVE_CAPACITY ((512-64)*1024)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+using namespace Xbyak;
+
+namespace {
+
+constexpr auto small_spatial = 14;
+unsigned int L1_cache_size = get_cache_size(1, true);
+
+inline void pick_loop_order(jit_conv_conf_t &jcp) {
+ using namespace prop_kind;
+ assert(one_of(jcp.prop_kind,
+ forward_training, forward_inference, backward_data));
+ auto w = (jcp.prop_kind == backward_data) ? jcp.iw : jcp.ow;
+ auto h = (jcp.prop_kind == backward_data) ? jcp.ih : jcp.oh;
+
+ // ow-threading is currently implemented for forward only
+ // TODO: single code for fwd and bwd after ow-thr for bwd
+ // meaningless switch was removed
+ if (jcp.prop_kind == backward_data) {
+ jcp.loop_order = (w <= small_spatial && h <= small_spatial)
+ ? loop_cgn : loop_gnc;
+ } else {
+ jcp.loop_order = (w <= small_spatial && h <= small_spatial)
+ ? loop_cwgn : loop_gncw;
+ }
+}
+
+inline bool is_1stconv(const jit_conv_conf_t &jcp) {
+ if (mayiuse(avx512_core))
+ return (jcp.ic < 16 && jcp.ngroups == 1);
+ else
+ return one_of(jcp.ic, 1, 3);
+}
+
+inline bool is_ow_threading_on(const jit_conv_conf_t &jcp) {
+ return (jcp.nb_ow > 1);
+}
+
+inline bool is_owb_prefetching(const jit_conv_conf_t &jcp) {
+ return (jcp.ver == ver_4fma && is_ow_threading_on(jcp));
+}
+
+}
+
+template<typename Vmm>
+void _jit_avx512_common_conv_fwd_kernel<Vmm>::prepare_output(int ur_w)
+{
+ for (int k = 0; k < jcp.nb_oc_blocking; k++)
+ for (int j = 0; j < ur_w; j++) {
+ Vmm vmm = vmm_out(j, k);
+ vpxord(vmm, vmm, vmm);
+ if (!is_owb_prefetching(jcp)) {
+ size_t aux_output_offset = get_output_offset(j, k);
+ mic_prefetcht1(EVEX_compress_addr_safe(reg_out_prf,
+ aux_output_offset, reg_out_long_offt));
+ }
+ }
+}
+
+template<typename Vmm>
+void _jit_avx512_common_conv_fwd_kernel<Vmm>::store_output(int ur_w)
+{
+ Label no_update_label, store_label, eltwise_label;
+
+ mov(reg_channel, ptr[param1 + GET_OFF(channel)]);
+ if (jcp.with_bias) {
+ mov(reg_bias, ptr[param1 + GET_OFF(bias)]);
+ }
+
+ if (!jcp.with_sum) {
+ cmp(reg_channel, 0);
+ je(no_update_label, T_NEAR);
+ }
+
+ for (int k = 0; k < jcp.nb_oc_blocking; k++)
+ for (int j = 0; j < ur_w; j++) {
+ Vmm vmm = vmm_out(j, k);
+ size_t aux_output_offset = get_output_offset(j, k);
+ vaddps(vmm,
+ make_safe_addr(reg_out, aux_output_offset, reg_out_long_offt));
+ }
+
+ if (!jcp.with_sum) {
+ jmp(eltwise_label, T_NEAR);
+ } else {
+ cmp(reg_channel, 0);
+ jne(eltwise_label, T_NEAR);
+ }
+
+ L(no_update_label);
+ if (jcp.with_bias) {
+ for (int k = 0; k < jcp.nb_oc_blocking; k++) {
+ int bias_offset = jcp.typesize_out * k * jcp.oc_block;
+ for (int j = 0; j < ur_w; j++) {
+ Vmm vmm = vmm_out(j, k);
+ vaddps(vmm, EVEX_compress_addr(reg_bias, bias_offset));
+ }
+ mic_prefetcht1(EVEX_compress_addr(reg_bias, bias_offset + 64));
+ }
+ }
+
+ L(eltwise_label);
+ if (jcp.with_eltwise) {
+ cmp(reg_channel, jcp.nb_ic - 1);
+ jl(store_label, T_NEAR);
+
+ if (ur_w == jcp.ur_w) {
+ eltwise_injector_->compute_vector_range(0,
+ jcp.nb_oc_blocking * jcp.ur_w);
+ } else {
+ for (int k = 0; k < jcp.nb_oc_blocking; k++)
+ eltwise_injector_->compute_vector_range(k * jcp.ur_w,
+ k * jcp.ur_w + ur_w);
+ }
+ }
+
+ L(store_label);
+ for (int k = 0; k < jcp.nb_oc_blocking; k++)
+ for (int j = 0; j < ur_w; j++) {
+ Vmm vmm = vmm_out(j, k);
+ size_t aux_output_offset = (size_t)typesize *
+ ((size_t)k * jcp.od * jcp.oh * jcp.ow + j) * jcp.oc_block;
+ vmovups(EVEX_compress_addr_safe(reg_out, aux_output_offset,
+ reg_out_long_offt), vmm);
+ if (!is_owb_prefetching(jcp))
+ mic_prefetcht0(EVEX_compress_addr_safe(reg_out_prf,
+ aux_output_offset, reg_out_long_offt));
+ }
+}
+
+template<typename Vmm>
+void _jit_avx512_common_conv_fwd_kernel<Vmm>::compute_loop_4fma_1st(int ur_w,
+ int pad_l, int pad_r)
+{
+}
+
+template<>
+void _jit_avx512_common_conv_fwd_kernel<Zmm>::compute_loop_4fma_1st(int ur_w,
+ int pad_l, int pad_r)
+{
+ assert(jcp.dilate_d == 0 && jcp.dilate_h == 0 && jcp.dilate_w == 0);
+
+ int iw = jcp.iw;
+ int ih = jcp.ih;
+ int kw = jcp.kw;
+ int stride_w = jcp.stride_w;
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+
+ Label kh_label, kd_label;
+
+ if (one_of(jcp.ndims, 3, 4)) {
+ mov(aux_reg_inp, reg_inp);
+ mov(aux_reg_ker, reg_ker);
+ mov(aux_reg_inp_prf, reg_inp_prf);
+ }
+
+ size_t max_input_offset = (size_t)jcp.typesize_in
+ * ((size_t)(kw + ur_w * stride_w - pad_l)
+ + (size_t)ic_block * iw * ih * jcp.id);
+ assert(reg_inp_prf == reg_long_offt);
+ if (max_input_offset > INT_MAX) push(reg_inp_prf);
+
+ if (jcp.ndims == 5) {
+ push(reg_out_prf);
+ push(reg_out);
+
+ mov(reg_ki, ptr[param1 + GET_OFF(kd_padding)]);
+ mov(aux_reg_ker_d, ptr[param1 + GET_OFF(filt)]);
+ mov(aux_reg_inp_d, reg_inp);
+ mov(aux_reg_inp_d_prf, reg_inp_prf);
+
+ L(kd_label);
+ }
+ mov(reg_kj, reg_kh);
+ if (jcp.ndims == 5) {
+ mov(aux_reg_inp, aux_reg_inp_d);
+ mov(aux_reg_ker, aux_reg_ker_d);
+ mov(aux_reg_inp_prf, aux_reg_inp_d_prf);
+ }
+
+ L(kh_label);
+ for (int ki = 0; ki < kw; ki += 4) {
+ for (int ic = 0; ic < ic_block; ic++) {
+ for (int i = 0; i < 4; i++) {
+ int aux_ker_offset
+ = jcp.typesize_in
+ * ((ki + i) * oc_block
+ + ic * kw * jcp.kh * jcp.kd * oc_block);
+ if (ki + i < kw)
+ vmovups(vmm_ker(i),
+ EVEX_compress_addr(aux_reg_ker, aux_ker_offset));
+ else
+ vpxord(vmm_ker(i), vmm_ker(i), vmm_ker(i));
+ }
+
+ int j_start = get_ow_start(ki, pad_l);
+ int j_end = get_ow_end(ur_w, ki, pad_r);
+
+ for (int j = j_start, prf_count=0; j < j_end; j++) {
+ size_t aux_input_offset = (size_t)jcp.typesize_in
+ * ((size_t)(ki + j * stride_w
+ - pad_l) + (size_t)ic * iw * ih * jcp.id);
+ v4fmaddps(vmm_out(j, 0), vmm_ker(0),
+ EVEX_compress_addr_safe(aux_reg_inp, aux_input_offset,
+ reg_long_offt));
+ if (ki + prf_count < kw && prf_count < 4
+ && ((ki < 2 && j % 4) || j % 2)) {
+ int aux_ker_offset = jcp.typesize_in
+ * ((ki + prf_count) * oc_block
+ + ic * kw * jcp.kh * jcp.kd * oc_block + kw * oc_block);
+ mic_prefetcht0(EVEX_compress_addr(aux_reg_ker,
+ aux_ker_offset));
+ prf_count++;
+ }
+ if (ki == 0
+ && j % (64 / (stride_w * jcp.typesize_in)) == 0) {
+ mic_prefetcht0(EVEX_compress_addr_safe(aux_reg_inp_prf,
+ aux_input_offset, reg_long_offt));
+ }
+ if (ki == 1
+ && j % (64 / (stride_w * jcp.typesize_in)) == 0) {
+ mic_prefetcht0(EVEX_compress_addr_safe(aux_reg_inp,
+ aux_input_offset+jcp.typesize_in * iw, reg_long_offt));
+ }
+ }
+ }
+ }
+ add(aux_reg_ker, jcp.typesize_in * kw * oc_block);
+ add(aux_reg_inp, jcp.typesize_in * iw);
+ add(aux_reg_inp_prf, jcp.typesize_in * iw);
+
+ dec(reg_kj);
+ cmp(reg_kj, 0);
+ jg(kh_label, T_NEAR);
+
+ if (jcp.ndims == 5) {
+ add(aux_reg_inp_d, typesize * jcp.ih * jcp.iw);
+ add(aux_reg_ker_d, typesize * jcp.kw * jcp.kh * oc_block);
+ add(aux_reg_inp_d_prf, typesize * jcp.ih * jcp.iw);
+
+ dec(reg_ki);
+ cmp(reg_ki, 0);
+ jg(kd_label, T_NEAR);
+
+ pop(reg_out);
+ pop(reg_out_prf);
+ }
+
+ if (max_input_offset > INT_MAX) pop(reg_inp_prf);
+}
+
+template<typename Vmm>
+void _jit_avx512_common_conv_fwd_kernel<Vmm>::compute_loop_4fma(int ur_w,
+ int pad_l, int pad_r)
+{
+}
+
+template<>
+void _jit_avx512_common_conv_fwd_kernel<Zmm>::compute_loop_4fma(int ur_w,
+ int pad_l, int pad_r)
+{
+ int stride_w = jcp.stride_w;
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ Label kh_label, last_iter_label, loop_end_label, kd_label;
+ int ker_load_number = 4;
+ int shift_kernel_ptr = typesize * jcp.kw * jcp.oc_block * jcp.ic_block;
+ int shift_input_ptr = typesize * (jcp.dilate_h + 1) * jcp.iw * jcp.ic_block;
+
+ bool check_last_kh = (jcp.kh > 3);
+ bool pref_current_inp = (jcp.iw < 14 || jcp.iw > 28);
+
+ int oi_ipref_t0 = get_ow_start(0, pad_l);
+ int ow_end_ipref = get_ow_end(ur_w, 0, pad_r);
+
+ assert(jcp.oc % jcp.nb_oc_blocking == 0);
+
+ auto kernel_offset = [=](int ocb, int ic, int ki) {
+ int blk_idx = ocb * jcp.nb_ic * jcp.kh * jcp.kw * jcp.kd + ki;
+ int blk_offset = blk_idx * jcp.oc_block * jcp.ic_block;
+ int ic_offset = ic * jcp.oc_block;
+ return typesize * (blk_offset + ic_offset);
+ };
+ auto kernel_loads = [=](int ki, int ic, int kk) {
+ for (int ii = 0; ii < ker_load_number; ii++) {
+ int aux_kernel_offset = kernel_offset(kk, ic + ii, ki);
+ vmovups(vmm_ker(ii),
+ EVEX_compress_addr(aux_reg_ker, aux_kernel_offset));
+ }
+ };
+ auto prefetch_inp_next_kh = [&](int ki, int ki_start, int cnt0, int cnt1) {
+ if (cnt1 >= ker_load_number && cnt0 >= ker_load_number
+ && ki >= ki_start && oi_ipref_t0 < ow_end_ipref) {
+ int aux_inp_offset
+ = typesize
+ * ((oi_ipref_t0 * stride_w - pad_l) * ic_block
+ + (jcp.dilate_h + 1) * jcp.iw * ic_block);
+ prefetcht0(EVEX_compress_addr(aux_reg_inp,
+ aux_inp_offset));
+ oi_ipref_t0++;
+ }
+ };
+
+ if (one_of(jcp.ndims, 3, 4)) {
+ mov(aux_reg_inp, reg_inp);
+ mov(aux_reg_ker, reg_ker);
+ mov(aux_reg_ker_prf, reg_ker_prf);
+ mov(aux_reg_inp_prf, reg_inp_prf);
+ }
+
+ if (jcp.ndims == 5) {
+ push(reg_out_prf);
+ push(reg_out);
+
+ mov(reg_ki, ptr[param1 + GET_OFF(kd_padding)]);
+ mov(aux_reg_ker_d, ptr[param1 + GET_OFF(filt)]);
+ mov(aux_reg_inp_d, reg_inp);
+ mov(aux_reg_inp_d_prf, reg_inp_prf);
+ mov(aux_reg_ker_d_prf, reg_ker_prf);
+ L(kd_label);
+ mov(reg_kj, ptr[param1 + GET_OFF(kh_padding)]);
+ } else {
+ mov(reg_kj, reg_kh);
+ }
+ if (jcp.ndims == 5) {
+ mov(aux_reg_inp, aux_reg_inp_d);
+ mov(aux_reg_ker, aux_reg_ker_d);
+ mov(aux_reg_ker_prf, aux_reg_ker_d_prf);
+ mov(aux_reg_inp_prf, aux_reg_inp_d_prf);
+ }
+
+ align(16);
+ L(kh_label);
+ int kw = jcp.kw;
+ if (check_last_kh) {
+ for (int ki = 0; ki < kw; ki++)
+ for (int ic = 0; ic < ic_block; ic += 4)
+ for (int kk = 0; kk < jcp.nb_oc_blocking; kk++) {
+ bool last_kernel_loads = (kk == jcp.nb_oc_blocking - 1
+ && ki == kw - 1 && (ic + 4) == ic_block);
+
+ if (last_kernel_loads) {
+ cmp(reg_kj, 1);
+ je(last_iter_label, T_NEAR);
+ }
+
+ kernel_loads(ki, ic, kk);
+ for (int oi = get_ow_start(ki, pad_l), prf_count_t1 = 0,
+ prf_count_t0 = 0;
+ oi < get_ow_end(ur_w, ki, pad_r); oi++) {
+ int aux_input_offset = typesize
+ * ((ki * (jcp.dilate_w + 1) + oi * stride_w
+ - pad_l) * ic_block
+ + ic);
+ v4fmaddps(vmm_out(oi, kk), vmm_ker(0),
+ EVEX_compress_addr(aux_reg_inp, aux_input_offset));
+
+ if (oi % 2) {
+ if (prf_count_t0 < 4) {
+ int aux_kernel_prf;
+ if (last_kernel_loads)
+ aux_kernel_prf= kernel_offset(0,
+ prf_count_t0 + ic + 4
+ - ic_block, 0) + typesize * kw
+ * oc_block * ic_block;
+ else
+ aux_kernel_prf = kernel_offset(kk, ic + 4
+ + prf_count_t0, ki);
+ mic_prefetcht0(EVEX_compress_addr(aux_reg_ker,
+ aux_kernel_prf));
+ prf_count_t0++;
+ } else if (prf_count_t1 < 4) {
+ mic_prefetcht1(EVEX_compress_addr(
+ aux_reg_ker_prf, kernel_offset(kk, ic
+ + prf_count_t1, ki)));
+ prf_count_t1++;
+ }
+ } else
+ prefetch_inp_next_kh(ki, 2, prf_count_t0,
+ prf_count_t1);
+ }
+
+ if (last_kernel_loads) {
+ jmp(loop_end_label, T_NEAR);
+
+ L(last_iter_label);
+
+ kernel_loads(ki, ic, kk);
+ for (int oi = get_ow_start(ki, pad_l), prf_count_t1 = 0,
+ prf_count_t0 = 0;
+ oi < get_ow_end(ur_w, ki, pad_r); oi++) {
+ int aux_input_offset = typesize
+ * ((ki * (jcp.dilate_w + 1) + oi * stride_w
+ - pad_l) * ic_block
+ + ic);
+ v4fmaddps(vmm_out(oi, kk), vmm_ker(0),
+ EVEX_compress_addr(aux_reg_inp,
+ aux_input_offset));
+ if (oi % 2) {
+ if (prf_count_t0 < 4) {
+ mic_prefetcht0(EVEX_compress_addr(
+ aux_reg_ker_prf, kernel_offset(0,
+ prf_count_t0, 0)));
+ prf_count_t0++;
+ } else if (prf_count_t1 < 4) {
+ mic_prefetcht1(EVEX_compress_addr(
+ aux_reg_ker_prf, kernel_offset(kk,
+ ic + prf_count_t1, ki)));
+ prf_count_t1++;
+ }
+ }
+ }
+ L(loop_end_label);
+ }
+ }
+ } else {
+ for (int ki = 0; ki < kw; ki++)
+ for (int ic = 0; ic < ic_block; ic += 4)
+ for (int kk = 0; kk < jcp.nb_oc_blocking; kk++) {
+ kernel_loads(ki, ic, kk);
+ for (int oi = get_ow_start(ki, pad_l),
+ prf_count_t1 = 0, prf_count_t0 = 0;
+ oi < get_ow_end(ur_w, ki, pad_r); oi++) {
+ int aux_input_offset = typesize
+ * ((ki * (jcp.dilate_w + 1) + oi * stride_w
+ - pad_l) * ic_block + ic);
+ v4fmaddps(vmm_out(oi, kk), vmm_ker(0),
+ EVEX_compress_addr(aux_reg_inp,
+ aux_input_offset));
+
+ if (!is_owb_prefetching(jcp)) {
+ if ((oi % 2) && (prf_count_t1 < 4)) {
+ mic_prefetcht1(EVEX_compress_addr(
+ aux_reg_ker_prf, kernel_offset(kk,
+ ic + prf_count_t1, ki)));
+ prf_count_t1++;
+ }
+ } else {
+ if (!(ki == 0 && ic == 0)
+ && !(ki == kw-1 && ic == 0) &&
+ (oi % 2) && (prf_count_t1 < 4)
+ ) {
+ mic_prefetcht0(EVEX_compress_addr(
+ aux_reg_ker, kernel_offset(kk,
+ ic + 4 + prf_count_t0, ki)));
+ prf_count_t0++;
+ }
+ }
+ if (!is_owb_prefetching(jcp)) {
+ if (pref_current_inp) {
+ if (ki == 0 && ic == 0 && kk == 0)
+ mic_prefetcht0(EVEX_compress_addr(
+ aux_reg_inp,
+ aux_input_offset + shift_input_ptr));
+ } else {
+ if (ki == 1 && ic == 0 && kk == 0)
+ mic_prefetcht1(EVEX_compress_addr(
+ aux_reg_inp_prf, aux_input_offset));
+ }
+ } else {
+ int inp_mult = jcp.is_1stconv ? 1 : jcp.ic_block;
+ int inp_shift
+ = jcp.typesize_in * ur_w * stride_w * inp_mult;
+ bool kk_pref_slot = kk ? oi % 2 : !(oi % 2);
+ if (ki == 0 && ic == 0 && kk_pref_slot)
+ mic_prefetcht1(EVEX_compress_addr(
+ aux_reg_inp,
+ aux_input_offset + inp_shift));
+
+ if (ki == kw - 1 && ic == 0 && kk_pref_slot)
+ mic_prefetcht0(EVEX_compress_addr(
+ aux_reg_inp,
+ aux_input_offset + inp_shift));
+ }
+ }
+ }
+ }
+
+ add(aux_reg_ker, shift_kernel_ptr);
+ add(aux_reg_inp, shift_input_ptr);
+ add(aux_reg_ker_prf, shift_kernel_ptr);
+ add(aux_reg_inp_prf, shift_input_ptr);
+
+ dec(reg_kj);
+ cmp(reg_kj, 0);
+ jg(kh_label, T_NEAR);
+
+ if (jcp.ndims == 5) {
+ add(aux_reg_inp_d,
+ typesize * (jcp.dilate_d + 1) * jcp.ih * jcp.iw * jcp.ic_block);
+ add(aux_reg_ker_d, typesize * jcp.kw * jcp.kh * jcp.oc_block
+ * jcp.ic_block);
+ add(aux_reg_inp_d_prf,
+ typesize * (jcp.dilate_d + 1) * jcp.ih * jcp.iw * jcp.ic_block);
+ add(aux_reg_ker_d_prf, typesize * jcp.kw * jcp.kh * jcp.oc_block
+ * jcp.ic_block);
+
+ dec(reg_ki);
+ cmp(reg_ki, 0);
+ jg(kd_label, T_NEAR);
+
+ pop(reg_out);
+ pop(reg_out_prf);
+ }
+}
+
+template<typename Vmm>
+void _jit_avx512_common_conv_fwd_kernel<Vmm>::compute_loop_fma(int ur_w,
+ int pad_l, int pad_r)
+{
+ bool prf_ker = true;
+ bool prf_inp = true;
+ int ih = jcp.ih;
+ int stride_w = jcp.stride_w;
+ int id = jcp.id;
+ int iw = jcp.iw;
+ int kw = jcp.kw;
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ int nb_oc_block = jcp.nb_oc_blocking;
+ Label kh_label, kd_label;
+
+ int ker_pipeline_depth = 4;
+ assert(ker_reg_base_idx + ker_pipeline_depth <= 32);
+ assert(oc_block >= ker_pipeline_depth);
+
+ int num_ker_loads = ic_block * nb_oc_block * kw;
+ int num_ker_prfs = prf_ker ? num_ker_loads : 0;
+ int num_inp_prfs = prf_inp ?
+ ur_w * nstl::min(kw, stride_w) + nstl::max(0, kw - stride_w) :
+ 0;
+ if (jcp.is_1stconv && prf_inp) {
+ num_inp_prfs = div_up(num_inp_prfs, jcp.simd_w) * ic_block;
+ }
+ int num_prfs = num_ker_prfs + num_inp_prfs;
+ int num_fmas = num_ker_loads * ur_w;
+ int prf_inst_spacing
+ = (prf_ker || prf_inp) ? nstl::max(1, num_fmas / num_prfs) : 1;
+ int prf_inst_trigger = (num_fmas % prf_inst_spacing) / 2;
+ int inp_mul = !jcp.is_1stconv ? ic_block : 1;
+
+ if (one_of(jcp.ndims, 3, 4)) {
+ mov(aux_reg_inp, reg_inp);
+ mov(aux_reg_ker, reg_ker);
+ mov(aux_reg_inp_prf, reg_inp_prf);
+ mov(aux_reg_ker_prf, reg_ker_prf);
+ }
+
+ size_t max_input_offset = (size_t)jcp.typesize_in * ic_block * iw * ih * id;
+ assert(reg_inp_prf == reg_long_offt);
+ if (max_input_offset > INT_MAX) push(reg_inp_prf);
+
+
+ if (jcp.ndims == 5) {
+ push(reg_out_prf);
+ push(reg_out);
+
+ mov(reg_ki, ptr[param1 + GET_OFF(kd_padding)]);
+ mov(aux_reg_ker_d, ptr[param1 + GET_OFF(filt)]);
+ mov(aux_reg_inp_d, reg_inp);
+ mov(aux_reg_inp_d_prf, reg_inp_prf);
+ mov(aux_reg_ker_d_prf, reg_ker_prf);
+
+ L(kd_label);
+ mov(reg_kj, ptr[param1 + GET_OFF(kh_padding)]);
+ } else {
+ mov(reg_kj, reg_kh);
+ }
+
+ if (jcp.ndims == 5) {
+ mov(aux_reg_inp, aux_reg_inp_d);
+ mov(aux_reg_ker, aux_reg_ker_d);
+ mov(aux_reg_ker_prf, aux_reg_ker_d_prf);
+ mov(aux_reg_inp_prf, aux_reg_inp_d_prf);
+ }
+
+ align(16);
+ L(kh_label);
+ {
+ int step = 0;
+ int ker_prfs = 0;
+ for (int ki = 0; ki < kw; ki++) {
+ for (int ic = 0; ic < ic_block; ic++) {
+ int aux_kernel_offset = 0;
+ if (step == 0) {
+ for (int i = 0; i < ker_pipeline_depth; i++) {
+ aux_kernel_offset = get_kernel_offset(ki, ic, 0, i);
+ vmovups(vmm_ker(i), EVEX_compress_addr(
+ aux_reg_ker, aux_kernel_offset));
+ }
+ } else if (step < num_ker_loads - ker_pipeline_depth + 1) {
+ int load_offset = ker_pipeline_depth - 1;
+ int ker_load_reg_idx
+ = (step + load_offset) % ker_pipeline_depth;
+ aux_kernel_offset
+ = get_kernel_offset(ki, ic, 0, load_offset);
+ vmovups(vmm_ker(ker_load_reg_idx),
+ EVEX_compress_addr(aux_reg_ker, aux_kernel_offset));
+ }
+
+ bool ker_prf_inserted = false;
+ Vmm vmm_kernel = vmm_ker(step % ker_pipeline_depth);
+ int j_start = get_ow_start(ki, pad_l);
+ int j_end = get_ow_end(ur_w, ki, pad_r);
+ for (int j = j_start; j < j_end; j++) {
+ size_t aux_input_offset = get_input_offset(ki, ic, j, pad_l);
+ auto addr = EVEX_compress_addr_safe(aux_reg_inp,
+ aux_input_offset, reg_long_offt, true);
+ vfmadd231ps(vmm_out(j, 0), vmm_kernel, addr);
+ int fma_idx = step * ur_w + j;
+ int prf_slot_idx = fma_idx / prf_inst_spacing;
+ if (fma_idx % prf_inst_spacing == prf_inst_trigger) {
+ if (prf_ker && !ker_prf_inserted
+ && ker_prfs < num_ker_prfs) {
+ int ker_prf_offset
+ = jcp.typesize_in * ker_prfs * jcp.oc_block;
+ mic_prefetcht2(EVEX_compress_addr(
+ aux_reg_ker_prf, ker_prf_offset));
+ ker_prf_inserted = true;
+ ker_prfs++;
+ } else if (prf_inp) {
+ int inp_prf_idx = prf_slot_idx - ker_prfs;
+ if (inp_prf_idx < num_inp_prfs) {
+ size_t inp_prf_stride = nstl::max(kw, stride_w);
+ size_t inp_prf_offset;
+ if (!jcp.is_1stconv) {
+ inp_prf_offset
+ = ic_block * jcp.typesize_in
+ * ((inp_prf_idx / kw)
+ * inp_prf_stride
+ + (inp_prf_idx % kw));
+ } else {
+ size_t ic_prf_stride =
+ (size_t)jcp.typesize_in * iw * ih * id;
+ size_t iw_prf_stride
+ = jcp.typesize_in * jcp.simd_w;
+ inp_prf_offset = ((inp_prf_idx / ic_block)
+ * iw_prf_stride
+ + (inp_prf_idx % ic_block)
+ * ic_prf_stride);
+ }
+ mic_prefetcht0(EVEX_compress_addr_safe(
+ aux_reg_inp_prf, inp_prf_offset,
+ reg_long_offt));
+ }
+ }
+ }
+ }
+ step++;
+ }
+ }
+ add(aux_reg_ker, jcp.typesize_in * kw * oc_block * ic_block);
+ if (prf_ker)
+ add(aux_reg_ker_prf, jcp.typesize_in * kw * oc_block * ic_block);
+ add(aux_reg_inp, jcp.typesize_in * (jcp.dilate_h + 1) * iw * inp_mul);
+ if (prf_inp)
+ add(aux_reg_inp_prf,
+ jcp.typesize_in * (jcp.dilate_h + 1) * iw * inp_mul);
+ dec(reg_kj);
+ cmp(reg_kj, 0);
+ jg(kh_label, T_NEAR);
+ }
+
+
+ if (jcp.ndims == 5) {
+ add(aux_reg_inp_d,
+ typesize * (jcp.dilate_d + 1) * jcp.ih * jcp.iw * inp_mul);
+ add(aux_reg_ker_d, typesize * jcp.kw * jcp.kh * jcp.oc_block
+ * jcp.ic_block);
+ add(aux_reg_inp_d_prf,
+ typesize * (jcp.dilate_d + 1) * jcp.ih * jcp.iw * inp_mul);
+ add(aux_reg_ker_d_prf, typesize * jcp.kw * jcp.kh * jcp.oc_block
+ * jcp.ic_block);
+
+ dec(reg_ki);
+ cmp(reg_ki, 0);
+ jg(kd_label, T_NEAR);
+
+ pop(reg_out);
+ pop(reg_out_prf);
+ }
+ if (max_input_offset > INT_MAX) pop(reg_inp_prf);
+}
+
+template<typename Vmm>
+void _jit_avx512_common_conv_fwd_kernel<Vmm>::compute_loop_fma_core(int ur_w,
+ int pad_l, int pad_r)
+{
+ int kw = jcp.kw;
+ int stride_w = jcp.stride_w;
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ int nb_oc_block = jcp.nb_oc_blocking;
+ Label kh_label, kd_label;
+ int shift_kernel_ptr = jcp.typesize_in * jcp.kw * jcp.oc_block
+ * jcp.ic_block;
+ int inp_mul = !jcp.is_1stconv ? ic_block : 1;
+ int shift_input_ptr = jcp.typesize_in * (jcp.dilate_h + 1) * jcp.iw
+ * inp_mul;
+
+
+ auto input_offset = [=](int oi, int ic, int ki) {
+ return (size_t)jcp.typesize_in
+ * ((size_t)(ki * (jcp.dilate_w + 1) + oi * stride_w - pad_l)
+ * inp_mul + (size_t)ic
+ * (!jcp.is_1stconv ? 1 : (size_t)jcp.iw * jcp.ih * jcp.id));
+ };
+
+ if (one_of(jcp.ndims, 3, 4)) {
+ mov(aux_reg_inp, reg_inp);
+ mov(aux_reg_ker, reg_ker);
+ }
+
+ if (jcp.ndims == 5) {
+ push(reg_out);
+
+ mov(reg_ki, ptr[param1 + GET_OFF(kd_padding)]);
+ mov(aux_reg_ker_d, ptr[param1 + GET_OFF(filt)]);
+ mov(aux_reg_inp_d, reg_inp);
+
+ L(kd_label);
+ mov(reg_kj, ptr[param1 + GET_OFF(kh_padding)]);
+ } else {
+ mov(reg_kj, reg_kh);
+ }
+
+ if (jcp.ndims == 5) {
+ mov(aux_reg_inp, aux_reg_inp_d);
+ mov(aux_reg_ker, aux_reg_ker_d);
+ }
+
+ L(kh_label);
+ {
+ for (int ki = 0; ki < kw; ki++) {
+ int jj_start = get_ow_start(ki, pad_l);
+ int jj_end = get_ow_end(ur_w, ki, pad_r);
+ for (int ic = 0; ic < ic_block; ic++) {
+ if (jcp.kernel_kind == expl_bcast) {
+ for (int jj = jj_start; jj < jj_end; jj++) {
+ size_t aux_input_offset = input_offset(jj, ic, ki);
+ vbroadcastss(vmm_inp(jj, nb_oc_block),
+ EVEX_compress_addr_safe(aux_reg_inp,
+ aux_input_offset, reg_long_offt));
+ }
+ }
+ for (int ii = 0; ii < nb_oc_block; ii++) {
+ int aux_kernel_offset = jcp.typesize_in
+ * (ii * jcp.nb_ic * jcp.kh * jcp.kw * jcp.kd * ic_block
+ * oc_block + ki * ic_block * oc_block + ic * oc_block);
+ if (jj_end - jj_start > 0)
+ vmovups(vmm_wei, EVEX_compress_addr(aux_reg_ker,
+ aux_kernel_offset));
+ for (int jj = jj_start; jj < jj_end; jj++)
+ if (jcp.kernel_kind == expl_bcast)
+ vfmadd231ps(vmm_out(jj, ii),
+ vmm_inp(jj, nb_oc_block), vmm_wei);
+ else {
+ size_t aux_input_offset = input_offset(jj, ic, ki);
+ vfmadd231ps(vmm_out(jj, ii), vmm_wei,
+ EVEX_compress_addr_safe(aux_reg_inp,
+ aux_input_offset, reg_long_offt, true));
+ }
+ }
+ }
+ }
+ add(aux_reg_ker, shift_kernel_ptr);
+ add(aux_reg_inp, shift_input_ptr);
+ dec(reg_kj);
+ cmp(reg_kj, 0);
+ jg(kh_label, T_NEAR);
+ }
+
+ if (jcp.ndims == 5) {
+ add(aux_reg_inp_d,
+ typesize * (jcp.dilate_d + 1) * jcp.ih * jcp.iw * inp_mul);
+ add(aux_reg_ker_d, typesize * jcp.kw * jcp.kh * jcp.oc_block
+ * jcp.ic_block);
+
+ dec(reg_ki);
+ cmp(reg_ki, 0);
+ jg(kd_label, T_NEAR);
+
+ pop(reg_out);
+ }
+}
+
+template<typename Vmm>
+void _jit_avx512_common_conv_fwd_kernel<Vmm>::compute_loop(int ur_w,
+ int pad_l, int pad_r)
+{
+ if (jcp.ndims == 5) push(reg_oi);
+
+ prepare_output(ur_w);
+
+ Label skip_compute_loop;
+ if (jcp.ndims == 5) {
+ if ((jcp.dilate_d >= jcp.id)
+ || (jcp.kd - 1) * (jcp.dilate_d + 1) < nstl::max(jcp.f_pad, jcp.back_pad)) {
+ mov(reg_kj, ptr[param1 + GET_OFF(kd_padding)]);
+ cmp(reg_kj, 0);
+ je(skip_compute_loop, T_NEAR);
+ }
+ }
+ if ((jcp.dilate_h >= jcp.ih)
+ || (jcp.kh - 1) * (jcp.dilate_h + 1) < nstl::max(jcp.t_pad, jcp.b_pad)) {
+ mov(reg_kj, ptr[param1 + GET_OFF(kh_padding)]);
+ cmp(reg_kj, 0);
+ je(skip_compute_loop, T_NEAR);
+ }
+
+ if (jcp.ver == ver_4fma)
+ if(jcp.is_1stconv)
+ compute_loop_4fma_1st(ur_w, pad_l, pad_r);
+ else
+ compute_loop_4fma(ur_w, pad_l, pad_r);
+ else if (jcp.ver == ver_fma)
+ if ((jcp.is_1stconv && jcp.kernel_kind != expl_bcast)
+ || mayiuse(avx512_mic))
+ compute_loop_fma(ur_w, pad_l, pad_r);
+ else
+ if (jcp.kernel_kind == embd_bcast && jcp.nb_oc_blocking == 1)
+ compute_loop_fma(ur_w, pad_l, pad_r);
+ else
+ compute_loop_fma_core(ur_w, pad_l, pad_r);
+ else
+ assert(!"unknown convolution version");
+
+ L(skip_compute_loop);
+ store_output(ur_w);
+ if (jcp.ndims == 5) pop(reg_oi);
+}
+
+template<typename Vmm>
+void _jit_avx512_common_conv_fwd_kernel<Vmm>::generate()
+{
+ int iw = jcp.iw;
+ int ow = jcp.ow;
+ int ow_block = jcp.ow_block;
+ int nb_ow = jcp.nb_ow;
+ int kw = jcp.kw;
+ int l_pad = jcp.l_pad;
+ int ur_w = jcp.ur_w;
+ int ur_w_tail = jcp.ur_w_tail;
+ int dilate_w = jcp.dilate_w + 1;
+ int stride_w = jcp.stride_w;
+
+ int inp_mult = jcp.is_1stconv ? 1 : jcp.ic_block;
+ int inp_shift_pad = jcp.typesize_in * (ur_w * stride_w - l_pad) * inp_mult;
+ int inp_shift = jcp.typesize_in * ur_w * stride_w * inp_mult;
+ int inp_shift_pad_second_block = -1 * jcp.typesize_in * l_pad * inp_mult;
+ int out_shift = jcp.typesize_out * ur_w * jcp.oc_block;
+
+ preamble();
+ mov(reg_inp, ptr[param1 + GET_OFF(src)]);
+ mov(reg_out, ptr[param1 + GET_OFF(dst)]);
+ mov(reg_ker, ptr[param1 + GET_OFF(filt)]);
+ mov(reg_ker_prf, ptr[param1 + GET_OFF(filt_prf)]);
+ mov(reg_kh, ptr[param1 + GET_OFF(kh_padding)]);
+
+ int r_pad = nstl::max(
+ 0, (ow - 1) * stride_w + (kw - 1) * dilate_w - (iw + l_pad - 1));
+ int n_oi = ow / ur_w;
+ int r_pad1 = (ur_w * n_oi - 1) * stride_w + (kw - 1) * dilate_w
+ - (iw + l_pad - 1);
+
+ if (!is_ow_threading_on(jcp)) {
+ // ow is being processed as a whole - with left and right paddings
+ if (r_pad1 > 0) n_oi--;
+
+ if (ow == ur_w) {
+ mov(reg_inp_prf, ptr[param1 + GET_OFF(src_prf)]);
+ mov(reg_out_prf, ptr[param1 + GET_OFF(dst_prf)]);
+ compute_loop(ur_w, l_pad, r_pad);
+ } else {
+ mov(reg_inp_prf, reg_inp);
+ mov(reg_out_prf, reg_out);
+ if (n_oi == 0) {
+ add(reg_inp_prf, inp_shift_pad);
+ add(reg_out_prf, out_shift);
+ compute_loop(ur_w, l_pad, r_pad1);
+ add(reg_inp, inp_shift_pad);
+ add(reg_out, out_shift);
+ if (ur_w_tail != 0) {
+ add(reg_inp_prf, inp_shift);
+ add(reg_out_prf, out_shift);
+ compute_loop(ur_w_tail, 0, r_pad);
+ }
+ } else {
+ xor_(reg_oi, reg_oi);
+ if (l_pad > 0) {
+ add(reg_inp_prf, inp_shift_pad);
+ add(reg_out_prf, out_shift);
+ compute_loop(ur_w, l_pad, 0);
+ add(reg_inp, inp_shift_pad);
+ add(reg_out, out_shift);
+ inc(reg_oi);
+ }
+ if ((l_pad <= 0 && n_oi > 0) || (l_pad > 0 && n_oi > 1)) {
+ Label ow_loop_label;
+ L(ow_loop_label);
+ {
+ add(reg_inp_prf, inp_shift);
+ add(reg_out_prf, out_shift);
+ compute_loop(ur_w, 0, 0);
+ add(reg_inp, inp_shift);
+ add(reg_out, out_shift);
+ inc(reg_oi);
+ cmp(reg_oi, n_oi);
+ jl(ow_loop_label, T_NEAR);
+ }
+ }
+ if (r_pad1 > 0) {
+ add(reg_inp_prf, inp_shift);
+ add(reg_out_prf, out_shift);
+ compute_loop(ur_w, 0, r_pad1);
+ add(reg_inp, inp_shift);
+ add(reg_out, out_shift);
+ }
+ if (ur_w_tail != 0) {
+ add(reg_inp_prf, inp_shift);
+ add(reg_out_prf, out_shift);
+ compute_loop(ur_w_tail, 0, r_pad);
+ }
+ }
+ }
+ } else {
+ // ow block is only processed.
+ // Number of block is passed as parameter owb,
+ // and padding processing depends on this number.
+
+ Label end_label, last_oi_label, middle_ow_blocks_label, tail_label;
+ Label oi_loop_label, oi_loop_start_label, oi_loop_end_label;
+
+ assert(ow_block % ur_w == 0);
+ int n_oi_not_last_ow_block = ow_block / ur_w;
+ // to simplify code (and general regs usage),
+ // size of ow block must be >= 2 * ur_w
+ assert(n_oi_not_last_ow_block > 1);
+ int n_oi_next_last_ow_block = n_oi_not_last_ow_block;
+ int n_oi_first_ow_block = n_oi_not_last_ow_block;
+
+ int n_oi_last_ow_block = (ow - ow_block * (nb_ow-1)) / ur_w;
+
+ // prepare right padding
+ bool next_last_ow_block_padded = r_pad1 > 0 && n_oi_last_ow_block == 0;
+ bool first_ow_block_padded = next_last_ow_block_padded && jcp.nb_ow == 2;
+ bool last_ow_block_padded = r_pad1 > 0 && n_oi_last_ow_block > 0;
+
+ if (last_ow_block_padded) n_oi_last_ow_block--;
+ else if (first_ow_block_padded) n_oi_first_ow_block--;
+ else if (next_last_ow_block_padded) n_oi_next_last_ow_block--;
+
+ mov(reg_owb, ptr[param1 + GET_OFF(owb)]);
+ cmp(reg_owb, 0); // is that the first ow-block ?
+ jg(middle_ow_blocks_label, T_NEAR);
+
+ // the first ow block, compute left padding
+
+ mov(reg_oi, n_oi_first_ow_block);
+ mov(reg_inp_prf, reg_inp);
+ mov(reg_out_prf, reg_out);
+
+ if (l_pad > 0) {
+ mov(reg_ker_prf, ptr[param1 + GET_OFF(filt_prf)]);
+ add(reg_inp_prf, inp_shift_pad);
+ add(reg_out_prf, out_shift);
+ compute_loop(ur_w, l_pad, 0);
+ add(reg_inp, inp_shift_pad);
+ add(reg_out, out_shift);
+ dec(reg_oi);
+ }
+ jmp(oi_loop_label, T_NEAR);
+
+ // middle or last ow block entry
+
+ L(middle_ow_blocks_label);
+
+ if (l_pad > 0) {
+ // just to consider left padding, not compute
+ add(reg_inp, inp_shift_pad_second_block);
+ add(reg_inp_prf, inp_shift_pad_second_block);
+ }
+
+ // set number of iteration for oi-loop
+ cmp(reg_owb, jcp.nb_ow - 1); // last ow-block ?
+ mov(reg_oi, n_oi_last_ow_block);
+ je(oi_loop_label, T_NEAR);
+ cmp(reg_owb, jcp.nb_ow - 2); // next to last ow-block ?
+ mov(reg_oi, n_oi_next_last_ow_block);
+ je(oi_loop_label, T_NEAR);
+ mov(reg_oi, n_oi_not_last_ow_block); // other middle ow-blocks
+
+ // oi loop w/o padding
+ L(oi_loop_label);
+ mov(reg_ker_prf, ptr[param1 + GET_OFF(filt_prf)]);
+ L(oi_loop_start_label);
+ cmp(reg_oi, 0);
+ jle(oi_loop_end_label, T_NEAR);
+
+ add(reg_inp_prf, inp_shift);
+ add(reg_out_prf, out_shift);
+ compute_loop(ur_w, 0, 0);
+ add(reg_inp, inp_shift);
+ add(reg_out, out_shift);
+ dec(reg_oi);
+ jmp(oi_loop_start_label, T_NEAR);
+ L(oi_loop_end_label);
+
+ mov(reg_owb, ptr[param1 + GET_OFF(owb)]);
+
+ cmp(reg_owb, 0); // first ow-block ?
+ if (first_ow_block_padded) {
+ je(last_oi_label, T_NEAR);
+ } else {
+ je(end_label, T_NEAR);
+ }
+ cmp(reg_owb, jcp.nb_ow - 2); // next to last ow-block ?
+ jl(end_label, T_NEAR);
+ if (next_last_ow_block_padded) {
+ je(last_oi_label, T_NEAR);
+ } else {
+ je(end_label, T_NEAR);
+ }
+ // that is last block
+ if (!last_ow_block_padded) {
+ jmp(tail_label, T_NEAR);
+ }
+
+ // last oi block with right padding
+ L(last_oi_label);
+ mov(reg_ker_prf, ptr[param1 + GET_OFF(filt_prf)]);
+ add(reg_inp_prf, inp_shift);
+ add(reg_out_prf, out_shift);
+ compute_loop(ur_w, 0, r_pad1);
+ add(reg_inp, inp_shift);
+ add(reg_out, out_shift);
+
+ mov(reg_owb, ptr[param1 + GET_OFF(owb)]);
+ cmp(reg_owb, jcp.nb_ow - 1); // last ow_block?
+ jl(end_label, T_NEAR);
+
+ L(tail_label);
+ mov(reg_ker_prf, ptr[param1 + GET_OFF(filt_prf)]);
+ if (ur_w_tail != 0) {
+ add(reg_inp_prf, inp_shift);
+ add(reg_out_prf, out_shift);
+ compute_loop(ur_w_tail, 0, r_pad);
+ }
+ L(end_label);
+ }
+ postamble();
+
+ if (jcp.with_eltwise)
+ eltwise_injector_->prepare_table();
+}
+
+bool jit_avx512_common_conv_fwd_kernel::post_ops_ok(
+ jit_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ const auto &p = attr.post_ops_;
+
+ auto is_eltwise = [&](int idx) { return p.entry_[idx].is_eltwise(); };
+ auto is_sum = [&](int idx) { return p.entry_[idx].is_sum(); };
+
+ switch (p.len_) {
+ case 0: return true; // no post_ops
+ case 1: return is_eltwise(0) || is_sum(0); // sum OR eltwise
+ case 2: return is_sum(0) && is_eltwise(1); // sum -> eltwise
+ default: return false;
+ }
+
+ return false;
+}
+
+status_t jit_avx512_common_conv_fwd_kernel::init_conf(
+ jit_conv_conf_t &jcp, const convolution_desc_t &cd,
+ memory_desc_t &src_md, memory_desc_t &weights_md,
+ memory_desc_t &dst_md, memory_desc_t &bias_md,
+ const primitive_attr_t &attr, int nthreads)
+{
+ using namespace prop_kind;
+
+ if (!mayiuse(avx512_common))
+ return status::unimplemented;
+
+ const memory_desc_wrapper src_d(&src_md);
+ const memory_desc_wrapper weights_d(&weights_md);
+ const memory_desc_wrapper dst_d(&dst_md);
+ const memory_desc_wrapper bias_d(&bias_md);
+
+ const int regs = 28;
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+ int ndims = src_d.ndims();
+
+ jcp = zero<decltype(jcp)>();
+ jcp.ndims = ndims;
+ jcp.prop_kind = cd.prop_kind;
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+ jcp.id = (ndims == 5) ? src_d.dims()[2] : 1;
+ jcp.ih = (ndims == 3) ? 1 : src_d.dims()[ndims-2];
+ jcp.iw = src_d.dims()[ndims-1];
+ jcp.od = (ndims == 5) ? dst_d.dims()[2] : 1;
+ jcp.oh = (ndims == 3) ? 1 : dst_d.dims()[ndims-2];
+ jcp.ow = dst_d.dims()[ndims-1];
+ jcp.kd = (ndims == 5) ? weights_d.dims()[with_groups + 2] : 1;
+ jcp.kh = (ndims == 3) ? 1 : weights_d.dims()[with_groups + ndims-2];
+ jcp.kw = weights_d.dims()[with_groups + ndims-1];
+ jcp.f_pad = (ndims == 5) ? cd.padding[0][0] : 0;
+ jcp.t_pad = (ndims == 3) ? 0 : cd.padding[0][ndims-4];
+ jcp.l_pad = cd.padding[0][ndims-3];
+ jcp.stride_d = (ndims == 5) ? cd.strides[0] : 1;
+ jcp.stride_h = (ndims == 3) ? 1 : cd.strides[ndims-4];
+ jcp.stride_w = cd.strides[ndims-3];
+
+ jcp.dilate_d = (ndims == 5) ? cd.dilates[0] : 0;
+ jcp.dilate_h = (ndims == 3) ? 0 : cd.dilates[ndims-4];
+ jcp.dilate_w = cd.dilates[ndims-3];
+
+ jcp.b_pad = (jcp.oh - 1) * jcp.stride_h + (jcp.kh - 1) * (jcp.dilate_h + 1)
+ - (jcp.ih + jcp.t_pad - 1);
+ jcp.back_pad = (jcp.od - 1) * jcp.stride_d
+ + (jcp.kd - 1) * (jcp.dilate_d + 1) - (jcp.id + jcp.f_pad - 1);
+
+ jcp.is_1stconv = is_1stconv(jcp);
+
+ bool ok_to_pad_channels = true
+ && jcp.ngroups == 1
+ && src_d.data_type() == data_type::f32;
+
+ const int full_simd_w = cpu_isa_traits<avx512_common>::vlen / sizeof(float);
+ jcp.simd_w = full_simd_w;
+ bool ok_to_try_xmm = true
+ && mayiuse(avx512_core)
+ && src_d.data_type() == data_type::f32
+ && !jcp.is_1stconv
+ && !ok_to_pad_channels
+ && (jcp.ic % jcp.simd_w != 0 || jcp.oc % jcp.simd_w != 0)
+ && (jcp.ic % 8 != 0 || jcp.oc % 8 != 0);
+ if (ok_to_try_xmm)
+ jcp.simd_w = 4;
+
+ jcp.oc_block = jcp.simd_w;
+ jcp.ic_block = jcp.is_1stconv ? jcp.ic : jcp.simd_w;
+ jcp.aligned_threads = 0;
+
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, jcp.oc_block);
+ jcp.ic = rnd_up(jcp.ic, jcp.ic_block);
+ }
+ bool args_ok = true
+ && jcp.oc % jcp.oc_block == 0
+ && jcp.ic % jcp.ic_block == 0;
+ if (!args_ok)
+ return status::unimplemented;
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ jcp.with_sum = p.find(primitive_kind::sum) != -1;
+ const int eltwise_ind = p.find(primitive_kind::eltwise);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise) {
+ jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+ if (dst_d.data_type() == data_type::s32) return status::unimplemented;
+ }
+
+ auto src_tag = jcp.is_1stconv
+ ? pick(ndims - 3, ncw, nchw, ncdhw)
+ : ((jcp.simd_w == 4)
+ ? pick(ndims - 3, nCw4c, nChw4c, nCdhw4c)
+ : pick(ndims - 3, nCw16c, nChw16c, nCdhw16c));
+ auto dst_tag = (jcp.simd_w == 4)
+ ? pick(ndims - 3, nCw4c, nChw4c, nCdhw4c)
+ : pick(ndims - 3, nCw16c, nChw16c, nCdhw16c);
+ auto wei_tag = with_groups
+ ? ((jcp.simd_w == 4)
+ ? pick(ndims - 3, gOIw4i4o, gOIhw4i4o, gOIdhw4i4o)
+ : pick(ndims - 3, gOIw16i16o, gOIhw16i16o, gOIdhw16i16o))
+ : ((jcp.simd_w == 4)
+ ? pick(ndims - 3, OIw4i4o, OIhw4i4o, OIdhw4i4o)
+ : pick(ndims - 3, OIw16i16o, OIhw16i16o, OIdhw16i16o));
+
+ if (src_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(src_md, src_tag));
+ jcp.src_tag = src_tag;
+ } else {
+ jcp.src_tag = src_d.matches_one_of_tag(src_tag);
+ }
+ if (jcp.src_tag != src_tag)
+ return status::unimplemented;
+
+ if (dst_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(dst_md, dst_tag));
+ jcp.dst_tag = dst_tag;
+ } else {
+ jcp.dst_tag = dst_d.matches_one_of_tag(dst_tag);
+ }
+ if (jcp.dst_tag != dst_tag)
+ return status::unimplemented;
+
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+ if (jcp.with_bias) {
+ if (bias_d.format_kind() == format_kind::any)
+ CHECK(memory_desc_init_by_tag(bias_md, x));
+ }
+
+ if (mayiuse(avx512_common) &&
+ src_d.data_type() == data_type::f32
+ && weights_d.data_type() == data_type::f32
+ && dst_d.data_type() == data_type::f32) {
+ jcp.ver = ver_fma;
+ jcp.typesize_in = sizeof(float);
+ jcp.typesize_out = sizeof(float);
+ if (mayiuse(avx512_mic_4ops))
+ jcp.ver = ver_4fma;
+
+ if (jcp.is_1stconv) {
+ // TODO: fix & remove constraints below
+ bool not_for_4fma
+ = IMPLICATION(everyone_is(0, jcp.l_pad, jcp.t_pad),
+ nstl::max(jcp.kw, jcp.kh) < 7);
+ bool is_dilated
+ = !everyone_is(0, jcp.dilate_d, jcp.dilate_h, jcp.dilate_w);
+ if (one_of(true, not_for_4fma, is_dilated))
+ jcp.ver = ver_fma;
+ if (jcp.ver == ver_4fma) {
+ wei_tag = with_groups
+ ? ((jcp.simd_w == 4)
+ ? pick(ndims - 3, gOiw4o, gOihw4o, gOidhw4o)
+ : pick(ndims - 3, gOiw16o, gOihw16o, gOidhw16o))
+ : ((jcp.simd_w == 4)
+ ? pick(ndims - 3, Oiw4o, Oihw4o, Oidhw4o)
+ : pick(ndims - 3, Oiw16o, Oihw16o, Oidhw16o));
+ } else {
+ wei_tag = with_groups
+ ? ((jcp.simd_w == 4)
+ ? pick(ndims - 3, gOwi4o, gOhwi4o, gOdhwi4o)
+ : pick(ndims - 3, gOwi16o, gOhwi16o, gOdhwi16o))
+ : ((jcp.simd_w == 4)
+ ? pick(ndims - 3, Owi4o, Ohwi4o, Odhwi4o)
+ : pick(ndims - 3, Owi16o, Ohwi16o, Odhwi16o));
+ }
+ }
+ } else {
+ return status::unimplemented;
+ }
+
+ if (weights_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(weights_md, wei_tag));
+ jcp.wei_tag = wei_tag;
+ } else {
+ jcp.wei_tag = weights_d.matches_one_of_tag(wei_tag);
+ }
+ if (jcp.wei_tag != wei_tag)
+ return status::unimplemented;
+
+ if (jcp.is_1stconv) {
+ jcp.ur_w = nstl::min(jcp.ow, regs);
+ } else {
+ // avx512_core guard - just to avoid possible regression for other archs
+ if (jcp.ver == ver_fma && mayiuse(avx512_core)) {
+ jcp.ur_w = nstl::min(jcp.ow, regs);
+ } else {
+ for (int ur_w = regs; ur_w > 0; --ur_w) {
+ if (jcp.ow % ur_w == 0) {
+ jcp.ur_w = ur_w;
+ break;
+ }
+ }
+ }
+ if ((ndims == 5 && jcp.ur_w <= 8) || (jcp.ur_w <= 1)) {
+ jcp.ur_w = nstl::min(jcp.ow, regs);
+ }
+ }
+ // TODO (Tanya): currently applied to Segnet convolutions only.
+ // Need to try for other topologies
+ if (jcp.ow > 150 && jcp.ur_w < regs/2)
+ jcp.ur_w = regs;
+
+ int n_oi = (jcp.ow / jcp.ur_w);
+ int r_pad = (jcp.ur_w * n_oi - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1) - (jcp.iw + jcp.l_pad - 1);
+ if (jcp.l_pad > 0 && r_pad > 0)
+ n_oi--;
+
+ bool large_code_size = jcp.ur_w != jcp.ow && jcp.l_pad > 0 && r_pad > 0
+ && ((jcp.l_pad <= 0 && n_oi > 0) || (jcp.l_pad > 0 && n_oi > 1));
+ if (large_code_size) {
+ const int max_code_size = 24 * 1024;
+ const int num_ops_per_reg = 6 + jcp.ic_block * jcp.kw;
+ int mult = 1;
+ if (jcp.l_pad > 0) mult += 1;
+ if (r_pad > 0) mult += 1;
+ for (int ur_w = jcp.ur_w; ur_w > regs/2; --ur_w) {
+ if (ur_w * mult * num_ops_per_reg * 9.0 < max_code_size) {
+ jcp.ur_w = ur_w;
+ break;
+ }
+ }
+ }
+
+ /* Grouped channel offset to support 'non-blocked data' format for
+ * convolution sizes with '(input_channel / ngroups) < simd' */
+ jcp.nonblk_group_off
+ = (jcp.ngroups > 1 && one_of(jcp.src_tag, ncw, nchw, ncdhw)) ?
+ jcp.ic :
+ 1;
+
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+ jcp.nb_oc = jcp.oc / jcp.oc_block;
+ jcp.nb_ic_blocking = jcp.nb_oc_blocking = 1;
+
+ auto is_ow_threading_applicable = [=]() {
+ return (true && !jcp.is_1stconv && one_of(jcp.ndims, 3, 4)
+ && IMPLICATION(mayiuse(avx512_mic),
+ jcp.ver == ver_4fma
+ && IMPLICATION(jcp.mb != 1,
+ jcp.ih == 1 && jcp.kh == 1)));
+ };
+
+ if (jcp.ver == ver_4fma && !jcp.is_1stconv) {
+ if ((jcp.kw <= 5 && jcp.kh <= 5 && jcp.kw == jcp.kh && jcp.ow <= 8
+ && jcp.oh <= 8 && jcp.ow == jcp.oh)
+ || (jcp.stride_h != 1 && jcp.ur_w < jcp.ow)) {
+ if (jcp.nb_oc % 2 == 0) {
+ jcp.nb_oc_blocking = 2;
+ jcp.ur_w = nstl::min(jcp.ow, regs / jcp.nb_oc_blocking);
+ }
+ } else {
+ for (int i = jcp.nb_oc; i > 0; i--)
+ if (i * jcp.ur_w <= regs && jcp.nb_oc % i == 0) {
+ jcp.nb_oc_blocking = i;
+ break;
+ }
+ }
+ if (jcp.ver == ver_4fma && is_ow_threading_applicable()) {
+ if (jcp.nb_oc % 2 == 0 && jcp.ur_w < jcp.ow
+ && jcp.ow != 2 * jcp.ur_w) {
+ jcp.nb_oc_blocking = 2;
+ jcp.ur_w = nstl::min(jcp.ow, regs / jcp.nb_oc_blocking);
+ }
+ }
+ }
+
+ jcp.ow_block = jcp.ow;
+
+ auto get_thr_eff = [=](int nb_oc_blocking, int ow_block) {
+ int nb_ow = div_up(jcp.ow, ow_block);
+ int nb_oc_chunks = div_up(jcp.nb_oc, nb_oc_blocking);
+ int work_amount = jcp.mb * jcp.oh * nb_oc_chunks * nb_ow;
+ float disbalance = (float)jcp.ow / rnd_up(jcp.ow, ow_block);
+ float thr_eff = disbalance * (float)work_amount
+ / rnd_up(work_amount, nthreads);
+ return thr_eff;
+ };
+
+ auto get_ow_block = [=](int nb_oc_blocking, int ur_w, float &eff) {
+ int res_ow_block = jcp.ow;
+ eff = get_thr_eff(nb_oc_blocking, res_ow_block);
+ if (!is_ow_threading_applicable())
+ return res_ow_block;
+
+ int L2_part = (get_cache_size(2) * 7 / 8) / typesize;
+ if (jcp.ver == ver_4fma)
+ L2_part /= 2;
+ int size_src_chunk = jcp.ic_block * ur_w * jcp.kh;
+ int size_dst_chunk = jcp.oc_block * nb_oc_blocking * ur_w;
+ int size_wei_chunk = jcp.oc_block * nb_oc_blocking * jcp.ic_block
+ * jcp.kw * jcp.kh;
+ int nurw_cache = (L2_part - 2 * size_wei_chunk)
+ / (2 * size_dst_chunk + 2 * size_src_chunk);
+ // current design of generate() requires ow_block >= 2 * ur_w
+ int ow_block_cache = ur_w * nstl::max(2, nurw_cache);
+
+ int ow_block_thr = ow_block_cache;
+ eff = get_thr_eff(nb_oc_blocking, ow_block_thr);
+
+ int max_nb_ow = div_up(jcp.ow, 2 * ur_w);
+ int start_nb_ow = div_up(jcp.ow, ow_block_thr);
+ for (int nb_ow = start_nb_ow; nb_ow <= max_nb_ow; nb_ow++) {
+ int ow_block
+ = nstl::min(rnd_up(div_up(jcp.ow, nb_ow), ur_w), jcp.ow);
+ float eff_threshold = (jcp.ver == ver_4fma) ? 0.8f : 0.9f;
+ if (ow_block < nb_oc_blocking * jcp.oc_block && eff > eff_threshold)
+ break;
+ if (div_up(jcp.ow, ow_block) != nb_ow)
+ continue;
+ float thr_eff = get_thr_eff(nb_oc_blocking, ow_block);
+ float eff_step = (jcp.ver == ver_4fma) ? 1.1f : 1.f;
+ if (ow_block >= 2 * ur_w && thr_eff > eff_step * eff) {
+ ow_block_thr = ow_block;
+ eff = thr_eff;
+ }
+ eff_threshold = (jcp.ver == ver_4fma) ? 0.9f : 0.98f;
+ if (eff > eff_threshold)
+ break;
+ }
+ res_ow_block = nstl::min(jcp.ow, nstl::max(2 * ur_w, ow_block_thr));
+ eff = get_thr_eff(nb_oc_blocking, res_ow_block);
+ return res_ow_block;
+ };
+
+
+ if (jcp.ver == ver_fma && mayiuse(avx512_core)) {
+ int try_nb_oc_blocking = 2;
+ unsigned int ker_inp_size = typesize * div_up(jcp.iw, jcp.stride_w)
+ * jcp.ic_block * jcp.kh * jcp.kd;
+ unsigned int ker_out_size = typesize * jcp.ow * jcp.oc_block
+ * try_nb_oc_blocking;
+ unsigned int ker_wei_size = typesize * jcp.kh * jcp.kw * jcp.ic_block
+ * jcp.oc_block * try_nb_oc_blocking * jcp.kd;
+ unsigned int ker_total_size = ker_inp_size + ker_out_size
+ + ker_wei_size;
+
+ bool embd_bcast_condition = true
+ && (jcp.kw == 3 && jcp.ow <= 28 && ker_total_size < L1_cache_size)
+ && !(jcp.kw == 3 && jcp.ow == 13 && jcp.ic >= 192)
+ && !(jcp.kw == 3 && jcp.ow == 28 && jcp.ic >= 512);
+
+ if (jcp.mb == 1) {
+ unsigned int inp_size = jcp.mb * div_up(jcp.ih, jcp.stride_h)
+ * div_up(jcp.iw, jcp.stride_w) * jcp.ic;
+ unsigned int wei_size = jcp.ic * jcp.oc * jcp.kh * jcp.kw;
+
+ // Estimate whether we need to limit the number of threads
+ // and calculate this number. Includes some heuristic.
+ int oc_chunks = jcp.nb_oc / jcp.nb_oc_blocking;
+ int work_amount = jcp.mb * jcp.ngroups * oc_chunks * jcp.oh;
+ int job_size_min = work_amount / nthreads;
+ int job_size_max = div_up(work_amount, nthreads);
+ int ch_max = rnd_up(jcp.oh, job_size_max);
+ int ch_min = (job_size_min == 0)
+ ? jcp.oh
+ : rnd_up(jcp.oh, job_size_min);
+ bool not_aligned_max = ch_max % jcp.oh != 0 && ch_max / jcp.oh < 2
+ && (jcp.oh != 8 || ch_max / jcp.oh > 1);
+ bool not_aligned_min = ch_min % jcp.oh != 0 && ch_min / jcp.oh < 2
+ && (jcp.oh != 8 || ch_min / jcp.oh > 1);
+ bool eligible_case = (jcp.stride_h == 1 && jcp.stride_w == 1)
+ || nthreads > oc_chunks;
+ if (jcp.loop_order == loop_cgn && oc_chunks > 1 && nthreads > 1
+ && wei_size / inp_size > 24
+ && (not_aligned_max || not_aligned_min)
+ && eligible_case) {
+ // Try to find nthreads > mkldnn_get_max_threads() / 2 such
+ // that oc_chunks is a multiple of nthreads, or nthreads is a
+ // multiple of oc_chunks. Otherwise, keep default value.
+ // TODO: implement a task-based alternative without throttling.
+ jcp.aligned_threads = nthreads;
+ for (int i = nthreads; i > nthreads / 2; i--) {
+ if (oc_chunks % i == 0 || i % oc_chunks == 0) {
+ jcp.aligned_threads = i;
+ break;
+ }
+ }
+ }
+ }
+
+ if (jcp.kw > 3
+ || (jcp.stride_w == 1 && jcp.stride_h == 1
+ && embd_bcast_condition)
+ || ((jcp.stride_w != 1 || jcp.stride_h != 1)
+ && ((jcp.mb <= 16 && (jcp.oc <= 192 || jcp.oh <= 10)
+ && embd_bcast_condition)))
+ || (jcp.mb == 1
+ && (jcp.ur_w >= jcp.ow || jcp.is_1stconv
+ || (jcp.ow <= 147 && jcp.oc <= 96)))) {
+ jcp.kernel_kind = embd_bcast;
+ jcp.ur_w = nstl::min(jcp.ow, regs);
+ jcp.nb_ic_blocking = jcp.nb_oc_blocking = 1;
+ if (ker_total_size < L1_cache_size && jcp.ow <= 8 && jcp.kh <= 3
+ && jcp.kw <= 3 && jcp.nb_oc % try_nb_oc_blocking == 0
+ && IMPLICATION(jcp.is_1stconv, jcp.mb == 1)
+ && IMPLICATION(jcp.mb == 1, jcp.ur_w < jcp.ow)) {
+ jcp.nb_oc_blocking = try_nb_oc_blocking;
+ jcp.ur_w = nstl::min(jcp.ow, 31 / (jcp.nb_oc_blocking + 1));
+ }
+ } else {
+ jcp.kernel_kind = expl_bcast;
+ jcp.nb_ic_blocking = 1;
+ if (IMPLICATION(jcp.is_1stconv, jcp.mb > 1)) {
+ float best_thr_eff = 0.f;
+ int best_nb_oc_blocking = 1;
+ for (int i = nstl::min(jcp.nb_oc, 5); i > 0; i--) {
+ if (jcp.nb_oc % i == 0) {
+ float thr_eff;
+ int ur_w = nstl::min(jcp.ow, 31 / (i + 1));
+ get_ow_block(i, ur_w, thr_eff);
+ if (thr_eff > 1.05f * best_thr_eff) {
+ best_nb_oc_blocking = i;
+ best_thr_eff = thr_eff;
+ }
+ }
+ }
+ jcp.nb_oc_blocking = best_nb_oc_blocking;
+ jcp.ur_w = nstl::min(jcp.ow, 31 / (jcp.nb_oc_blocking + 1));
+ }
+ }
+ }
+
+ jcp.ur_w_tail = jcp.ow % jcp.ur_w;
+
+ args_ok = true
+ && jcp.l_pad <= jcp.ur_w
+ && jcp.ic <= src_d.padded_dims()[1]
+ && jcp.oc <= dst_d.padded_dims()[1]
+ && jcp.ic <= weights_d.padded_dims()[with_groups + 1]
+ && jcp.oc <= weights_d.padded_dims()[with_groups + 0];
+ if (!args_ok)
+ return status::unimplemented;
+
+ int r_pad_no_tail = nstl::max(0, (jcp.ow - jcp.ur_w_tail - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1)
+ - (jcp.iw + jcp.l_pad - 1));
+ if (r_pad_no_tail > jcp.ur_w)
+ return status::unimplemented;
+
+ pick_loop_order(jcp);
+
+ jcp.nb_ic_L2 = jcp.nb_ic;
+
+ float thr_eff;
+ jcp.ow_block = get_ow_block(jcp.nb_oc_blocking, jcp.ur_w, thr_eff);
+ jcp.nb_ow = div_up(jcp.ow, jcp.ow_block);
+
+ const int L2_size = get_cache_size(2, true) / sizeof(float);
+ // Source and output data needs to fit in L2,
+ // leaving some space for weights and prefetching.
+ int h_L2 = int(((0.6f * L2_size) / jcp.simd_w
+ - nstl::min(0, jcp.kh - jcp.stride_h) * jcp.iw)
+ / (jcp.stride_h * jcp.iw + jcp.ow));
+ jcp.h_blocking = nstl::max(1, nstl::min(jcp.oh, h_L2));
+
+ if (jcp.ver == ver_4fma) {
+ if (!is_ow_threading_on(jcp)) {
+ for (int divf = 2, temp_nb = jcp.nb_ic_L2; divf <= jcp.nb_ic;
+ divf++) {
+ size_t l2_src
+ = (size_t)jcp.iw * jcp.ic_block * jcp.ih * temp_nb * jcp.id;
+ size_t l2_dst = (size_t)jcp.ow * jcp.oc_block * jcp.nb_oc_blocking
+ * jcp.oh * jcp.od;
+ size_t l2_filt = (size_t)jcp.kw * jcp.oc_block * jcp.ic_block
+ * jcp.kh * jcp.nb_oc_blocking * temp_nb * jcp.kd;
+ if (4 * (l2_src + l2_dst + l2_filt) > KNx_L2_EFFECTIVE_CAPACITY) {
+ if (jcp.kh == 3 && jcp.oh == 7) {
+ jcp.nb_ic_L2 = 1;
+ break;
+ }
+ temp_nb = (jcp.nb_ic_L2 % divf == 0 ? jcp.nb_ic_L2 / divf
+ : jcp.nb_ic_L2);
+ } else {
+ jcp.nb_ic_L2 = temp_nb;
+ break;
+ }
+ }
+ } else if (jcp.ic > 64) {
+ jcp.nb_ic_L2 = 2; /* according to performance data*/
+ }
+ }
+
+ return status::success;
+}
+
+void jit_avx512_common_conv_fwd_kernel::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad, const jit_conv_conf_t &jcp) {
+ if (jcp.with_bias && jcp.oc != jcp.oc_without_padding)
+ scratchpad.book(key_conv_padded_bias, jcp.typesize_out * jcp.oc);
+}
+
+void jit_avx512_common_conv_bwd_data_kernel_f32::prepare_output(int ur_w)
+{
+ for (int k = 0; k < jcp.nb_ic_blocking; k++) {
+ for (int j = 0; j < ur_w; j++) {
+ Zmm zmm = zmm_out(j, k);
+ vpxord(zmm, zmm, zmm);
+ size_t aux_src_offset
+ = (size_t)typesize * ((size_t)k * jcp.ih * jcp.iw * jcp.id + j)
+ * jcp.ic_block;
+ mic_prefetcht1(EVEX_compress_addr_safe(reg_src_prf, aux_src_offset,
+ reg_long_offt));
+ }
+ }
+}
+
+void jit_avx512_common_conv_bwd_data_kernel_f32::store_output(int ur_w)
+{
+ Label no_update_label;
+
+ mov(reg_channel, ptr[param + GET_OFF(channel)]);
+ cmp(reg_channel, 0);
+ je(no_update_label, T_NEAR);
+ for (int k = 0; k < jcp.nb_ic_blocking; k++) {
+ for (int j = 0; j < ur_w; j++) {
+ Zmm zmm = zmm_out(j, k);
+ size_t aux_src_offset = (size_t)typesize
+ * ((size_t)k * jcp.ih * jcp.iw * jcp.id + j) * jcp.ic_block;
+ vaddps(zmm, EVEX_compress_addr_safe(reg_src, aux_src_offset,
+ reg_long_offt));
+ }
+ }
+
+ L(no_update_label);
+ for (int k = 0; k < jcp.nb_ic_blocking; k++) {
+ for (int j = 0; j < ur_w; j++) {
+ Zmm zmm = zmm_out(j, k);
+ size_t aux_src_offset = (size_t)typesize
+ * ((size_t)k * jcp.ih * jcp.iw * jcp.id + j) * jcp.ic_block;
+ vmovups(EVEX_compress_addr_safe(reg_src, aux_src_offset,
+ reg_long_offt), zmm);
+ mic_prefetcht0(EVEX_compress_addr_safe(reg_src_prf, aux_src_offset,
+ reg_long_offt));
+ }
+ }
+}
+
+void jit_avx512_common_conv_bwd_data_kernel_f32::compute_loop_4fma(
+ int ur_w, int l_overflow, int r_overflow)
+{
+ int ow = jcp.ow;
+ int kw = jcp.kw;
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ Label kh_label, last_iter_label, loop_end_label, kd_label;
+ int ker_load_number = 4;
+ int shift_ker_ptr = typesize * kw * oc_block * ic_block;
+ int shift_dst_ptr = typesize * ow * oc_block;
+ int ii_dpref_t0 = get_iw_start(0, l_overflow);
+ int iw_end_ipref = get_iw_end(ur_w, 0, r_overflow);
+
+ bool check_last_kh = (jcp.kh > 3);
+ auto kernel_offset = [=](int icb, int oc, int ki) {
+ int blk_idx = icb * jcp.kh * jcp.kw * jcp.kd + ki;
+ int blk_offset = blk_idx * jcp.oc_block * jcp.ic_block;
+ int oc_offset = oc * jcp.oc_block;
+ return typesize * (blk_offset + oc_offset);
+ };
+ auto kernel_loads = [=](int ki, int oc, int kk) {
+ for (int ii = 0; ii < ker_load_number; ii++) {
+ int aux_kernel_offset = kernel_offset(kk, oc + ii, ki);
+ vmovups(zmm_ker(ii),
+ EVEX_compress_addr(aux_reg_ker, aux_kernel_offset));
+ }
+ };
+ auto prefetch_dst_next_kh = [&](int ki, int ki_start, int cnt0, int cnt1) {
+ if (cnt1 >= ker_load_number && cnt0 >= ker_load_number
+ && ki >= ki_start && ii_dpref_t0 < iw_end_ipref) {
+ int aux_dst_offset = typesize * ((ii_dpref_t0
+ + jcp.l_pad) * oc_block + jcp.ow * oc_block);
+ prefetcht0(EVEX_compress_addr(aux_reg_dst, aux_dst_offset));
+ ii_dpref_t0++;
+ }
+ };
+
+ if (one_of(jcp.ndims, 3, 4)) {
+ mov(aux_reg_dst, reg_dst);
+ mov(aux_reg_ker, reg_ker);
+ mov(aux_reg_dst_prf, reg_dst_prf);
+ mov(aux_reg_ker_prf, reg_ker_prf);
+ }
+
+ if (jcp.ndims == 5) {
+ push(reg_src_prf);
+ push(reg_src);
+
+ mov(reg_ki, ptr[param + GET_OFF(kd_padding)]);
+ mov(aux_reg_dst_d, reg_dst);
+ mov(aux_reg_ker_d, ptr[param + GET_OFF(filt)]);
+ mov(aux_reg_dst_d_prf, reg_dst_prf);
+ mov(aux_reg_ker_d_prf, reg_ker_prf);
+
+ L(kd_label);
+ mov(reg_kj, ptr[param + GET_OFF(kh_padding)]);
+ } else {
+ mov(reg_kj, reg_kh);
+ }
+
+ if (jcp.ndims == 5) {
+ mov(aux_reg_dst, aux_reg_dst_d);
+ mov(aux_reg_ker, aux_reg_ker_d);
+ mov(aux_reg_dst_prf, aux_reg_dst_d_prf);
+ mov(aux_reg_ker_prf, aux_reg_ker_d_prf);
+ }
+
+ align(16);
+ L(kh_label);
+ if (check_last_kh) {
+ for (int ki = 0; ki < kw; ki++)
+ for (int oc = 0; oc < oc_block; oc += 4)
+ for (int kk = 0; kk < jcp.nb_ic_blocking; kk++) {
+ bool last_kernel_loads = (kk == jcp.nb_ic_blocking - 1
+ && ki == kw - 1 && (oc + 4) == oc_block);
+
+ if (last_kernel_loads) {
+ cmp(reg_kj, 1);
+ je(last_iter_label, T_NEAR);
+ }
+
+ kernel_loads(ki, oc, kk);
+ for (int ii = get_iw_start(ki, l_overflow),
+ prf_count_t0 = 0, prf_count_t1 = 0;
+ ii < get_iw_end(ur_w, ki, r_overflow); ii++) {
+ int aux_dst_offset = typesize
+ * ((ii + jcp.l_pad - ki) * oc_block + oc);
+ v4fmaddps(zmm_out(ii, kk), zmm_ker(0),
+ EVEX_compress_addr(aux_reg_dst, aux_dst_offset));
+
+ if (ii % 2) {
+ if (prf_count_t0 < 4) {
+ int aux_kernel_prf;
+ if (last_kernel_loads)
+ aux_kernel_prf= kernel_offset(0, prf_count_t0
+ + oc + 4 - oc_block, 0) + typesize * kw
+ * oc_block * ic_block;
+ else
+ aux_kernel_prf = kernel_offset(kk, oc + 4
+ + prf_count_t0, ki);
+ mic_prefetcht0(EVEX_compress_addr(aux_reg_ker,
+ aux_kernel_prf));
+ prf_count_t0++;
+ } else if (prf_count_t1 < 4) {
+ mic_prefetcht1(EVEX_compress_addr(aux_reg_ker_prf,
+ kernel_offset(kk, oc + prf_count_t1, ki)));
+ prf_count_t1++;
+ }
+ } else
+ prefetch_dst_next_kh(ki, 2, prf_count_t0, prf_count_t1);
+ }
+ if (last_kernel_loads) {
+ jmp(loop_end_label, T_NEAR);
+
+ L(last_iter_label);
+
+ kernel_loads(ki, oc, kk);
+ for (int ii = get_iw_start(ki, l_overflow),
+ prf_count_t0 = 0, prf_count_t1 = 0;
+ ii < get_iw_end(ur_w, ki, r_overflow); ii++) {
+ int aux_dst_offset = typesize
+ * ((ii + jcp.l_pad - ki) * oc_block + oc);
+ v4fmaddps(zmm_out(ii, kk), zmm_ker(0),
+ EVEX_compress_addr(aux_reg_dst, aux_dst_offset));
+ if (ii % 2) {
+ if (prf_count_t0 < 4) {
+ mic_prefetcht0(EVEX_compress_addr(aux_reg_ker_prf,
+ kernel_offset(0, prf_count_t0, 0)));
+ prf_count_t0++;
+ } else if (prf_count_t1 < 4) {
+ mic_prefetcht1(EVEX_compress_addr(aux_reg_ker_prf,
+ kernel_offset(kk, oc + prf_count_t1, ki)));
+ prf_count_t1++;
+ }
+ }
+ }
+ L(loop_end_label);
+ }
+ }
+ } else {
+ for (int ki = 0; ki < kw; ki++)
+ for (int oc = 0; oc < oc_block; oc += 4)
+ for (int kk = 0; kk < jcp.nb_ic_blocking; kk++) {
+ kernel_loads(ki, oc, kk);
+
+ for (int ii = get_iw_start(ki, l_overflow), prf_count_t1 = 0;
+ ii < get_iw_end(ur_w, ki, r_overflow); ii++) {
+ int aux_dst_offset = typesize
+ * ((ii + jcp.l_pad - ki) * oc_block + oc);
+ v4fmaddps(zmm_out(ii, kk), zmm_ker(0),
+ EVEX_compress_addr(aux_reg_dst, aux_dst_offset));
+ if ((ii % 2) && (prf_count_t1 < 4)) {
+ mic_prefetcht1(EVEX_compress_addr(
+ aux_reg_ker_prf, kernel_offset(kk,
+ oc + prf_count_t1, ki)));
+ prf_count_t1++;
+ }
+ if ( ki == 1 && oc == 0 && kk == 0)
+ mic_prefetcht1(EVEX_compress_addr(
+ aux_reg_dst_prf, aux_dst_offset));
+ }
+ }
+ }
+
+ add(aux_reg_ker, shift_ker_ptr);
+ sub(aux_reg_dst, shift_dst_ptr);
+ add(aux_reg_ker_prf, shift_ker_ptr);
+ sub(aux_reg_dst_prf, shift_dst_ptr);
+
+ dec(reg_kj);
+ cmp(reg_kj, 0);
+ jg(kh_label, T_NEAR);
+
+ if (jcp.ndims == 5) {
+ sub(aux_reg_dst_d, typesize * (jcp.oh * ow) * ic_block);
+ add(aux_reg_ker_d, typesize * jcp.kw * jcp.kh * oc_block * ic_block);
+ sub(aux_reg_dst_d_prf, typesize * (jcp.oh * ow) * ic_block);
+ add(aux_reg_ker_d_prf, typesize * jcp.kw * jcp.kh *oc_block * ic_block);
+
+ dec(reg_ki);
+ cmp(reg_ki, 0);
+ jg(kd_label, T_NEAR);
+
+ pop(reg_src);
+ pop(reg_src_prf);
+ }
+}
+
+void jit_avx512_common_conv_bwd_data_kernel_f32::compute_loop_fma(
+ int ur_w, int l_overflow, int r_overflow)
+{
+ Label kh_label, kd_label;
+ int kw = jcp.kw;
+ int ow = jcp.ow;
+
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ int l_pad = jcp.l_pad;
+ int dilate_w = jcp.dilate_w + 1;
+ int stride_w = jcp.stride_w;
+ int stride_h = jcp.stride_h;
+
+ int ker_pipeline_depth = 4;
+ assert(ker_reg_base_idx + ker_pipeline_depth <= 32);
+ assert(oc_block >= ker_pipeline_depth);
+
+ int num_ker_loads = oc_block * kw;
+ int num_inp_prfs = ur_w * nstl::min(kw, stride_w)
+ + nstl::max(0, kw - stride_w);
+ int num_prfs = num_ker_loads + num_inp_prfs;
+ int num_fmas = num_ker_loads * ur_w / stride_w;
+ int prf_inst_spacing = nstl::max(1, num_fmas / num_prfs);
+ int prf_inst_trigger = (num_fmas % prf_inst_spacing) / 2;
+
+ if (one_of(jcp.ndims, 3, 4)) {
+ mov(aux_reg_dst, reg_dst);
+ mov(aux_reg_ker, reg_ker);
+
+ mov(aux_reg_dst_prf, reg_dst_prf);
+ mov(aux_reg_ker_prf, reg_ker_prf);
+ }
+
+ if (jcp.ndims == 5) {
+ push(reg_src_prf);
+ push(reg_src);
+
+ mov(reg_ki, ptr[param + GET_OFF(kd_padding)]);
+ mov(aux_reg_dst_d, reg_dst);
+ mov(aux_reg_ker_d, ptr[param + GET_OFF(filt)]);
+ mov(aux_reg_dst_d_prf, reg_dst_prf);
+ mov(aux_reg_ker_d_prf, reg_ker_prf);
+
+ L(kd_label);
+ mov(reg_kj, ptr[param + GET_OFF(kh_padding)]);
+ } else {
+ mov(reg_kj, reg_kh);
+ }
+
+ if (jcp.ndims == 5) {
+ mov(aux_reg_dst, aux_reg_dst_d);
+ mov(aux_reg_ker, aux_reg_ker_d);
+ mov(aux_reg_dst_prf, aux_reg_dst_d_prf);
+ mov(aux_reg_ker_prf, aux_reg_ker_d_prf);
+ }
+
+ L(kh_label); {
+ int step = 0;
+ int ker_prfs = 0;
+ for (int ki = 0; ki < kw; ki++) {
+ for (int oc = 0; oc < oc_block; oc++) {
+ if (step == 0) {
+ for (int i = 0; i < ker_pipeline_depth; i++) {
+ int aux_kernel_offset = typesize * ((oc + i) * oc_block
+ + ki * ic_block * oc_block);
+ vmovups(zmm_ker(i), EVEX_compress_addr(
+ aux_reg_ker, aux_kernel_offset));
+ }
+ } else if (step < num_ker_loads - ker_pipeline_depth + 1) {
+ int load_offset = ker_pipeline_depth - 1;
+ int ker_load_reg_idx
+ = (step + load_offset) % ker_pipeline_depth;
+ int aux_kernel_offset = typesize * ((oc + load_offset)
+ * oc_block + ki * ic_block * oc_block);
+ vmovups(zmm_ker(ker_load_reg_idx),
+ EVEX_compress_addr(aux_reg_ker, aux_kernel_offset));
+ }
+
+ bool ker_prf_inserted = false;
+ auto zmm_kernel = zmm_ker(step % ker_pipeline_depth);
+
+ int jj_start = get_iw_start(ki, l_overflow);
+ int jj_end = get_iw_end(ur_w, ki, r_overflow);
+ assert(stride_w != 1
+ || jj_start == nstl::max(0,
+ l_overflow - (kw - 1 - ki) * dilate_w));
+ assert(stride_w != 1
+ || jj_end == ur_w - nstl::max(0,
+ r_overflow - ki * dilate_w));
+
+ for (int jj = jj_start; jj < jj_end; jj += stride_w) {
+ assert((jj + l_pad - ki * dilate_w) % stride_w == 0);
+ int aux_dst_offset = typesize *
+ (((jj + l_pad - ki * dilate_w)
+ / stride_w) * jcp.oc_block + oc);
+ vfmadd231ps(zmm_out(jj, 0), zmm_kernel,
+ EVEX_compress_addr(aux_reg_dst, aux_dst_offset, true));
+
+ int fma_idx = (step * ur_w + jj) / stride_w;
+ int prf_slot_idx = fma_idx / prf_inst_spacing;
+ if (fma_idx % prf_inst_spacing == prf_inst_trigger) {
+ if (!ker_prf_inserted && ker_prfs < num_ker_loads) {
+ int ker_prf_offset = typesize
+ * ker_prfs * jcp.oc_block;
+ mic_prefetcht1(EVEX_compress_addr(
+ aux_reg_ker_prf, ker_prf_offset));
+ ker_prf_inserted = true;
+ ker_prfs++;
+ } else {
+ int inp_prf_idx = prf_slot_idx - ker_prfs;
+ if (inp_prf_idx < num_inp_prfs) {
+ int inp_prf_offset
+ = ic_block * typesize
+ * ((inp_prf_idx / kw) * kw
+ + (inp_prf_idx % kw));
+ mic_prefetcht0(EVEX_compress_addr(
+ aux_reg_dst_prf, inp_prf_offset));
+ }
+ }
+ }
+ }
+ step++;
+ }
+ }
+
+ add(aux_reg_ker, typesize * stride_h * kw * oc_block * ic_block);
+ sub(aux_reg_dst, typesize * (jcp.dilate_h + 1) * ow * oc_block);
+ add(aux_reg_ker_prf, typesize * stride_h * kw * oc_block * ic_block);
+ sub(aux_reg_dst_prf, typesize * (jcp.dilate_h + 1) * ow * oc_block);
+
+ dec(reg_kj);
+ cmp(reg_kj, 0);
+ jg(kh_label, T_NEAR);
+ }
+ if (jcp.ndims == 5) {
+ sub(aux_reg_dst_d,
+ typesize * (jcp.dilate_d + 1) * jcp.oh * ow * ic_block);
+ add(aux_reg_ker_d, typesize * jcp.stride_d * jcp.kw * jcp.kh
+ * oc_block * ic_block);
+ sub(aux_reg_dst_d_prf,
+ typesize * (jcp.dilate_d + 1) * jcp.oh * ow * ic_block);
+ add(aux_reg_ker_d_prf, typesize * jcp.stride_d * jcp.kw * jcp.kh
+ * oc_block * ic_block);
+
+ dec(reg_ki);
+ cmp(reg_ki, 0);
+ jg(kd_label, T_NEAR);
+ }
+
+ if (jcp.ndims == 5)
+ {
+ pop(reg_src);
+ pop(reg_src_prf);
+ }
+}
+
+void jit_avx512_common_conv_bwd_data_kernel_f32::compute_loop_fma_core(
+ int ur_w, int l_overflow, int r_overflow)
+{
+ int kw = jcp.kw;
+ int ow = jcp.ow;
+ int dilate_w = jcp.dilate_w + 1;
+ int stride_w = jcp.stride_w;
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ int nb_ic_block = jcp.nb_ic_blocking;
+ Label kh_label, kd_label;
+
+ int shift_ker_ptr = typesize * kw * oc_block * ic_block;
+ int shift_dst_ptr = typesize * (jcp.dilate_h + 1) * ow * oc_block;
+
+ auto output_offset = [=](int oi, int oc, int ki) {
+ return typesize *
+ (((oi + jcp.l_pad - ki * dilate_w) / stride_w) * oc_block + oc);
+ };
+ auto kernel_offset = [=](int icb, int oc, int ki) {
+ int blk_idx = icb * jcp.kh * jcp.kw * jcp.kd + ki;
+ int blk_offset = blk_idx * jcp.oc_block * jcp.ic_block;
+ int oc_offset = oc * jcp.oc_block;
+ return typesize * (blk_offset + oc_offset);
+ };
+
+ if (one_of(jcp.ndims, 3, 4)) {
+ mov(aux_reg_dst, reg_dst);
+ mov(aux_reg_ker, reg_ker);
+ }
+
+ if (jcp.ndims == 5) {
+ push(reg_src_prf);
+ push(reg_src);
+
+ mov(reg_ki, ptr[param + GET_OFF(kd_padding)]);
+ mov(aux_reg_dst_d, reg_dst);
+ mov(aux_reg_ker_d, ptr[param + GET_OFF(filt)]);
+
+ L(kd_label);
+ mov(reg_kj, ptr[param + GET_OFF(kh_padding)]);
+ } else {
+ mov(reg_kj, reg_kh);
+ }
+
+ if (jcp.ndims == 5) {
+ mov(aux_reg_dst, aux_reg_dst_d);
+ mov(aux_reg_ker, aux_reg_ker_d);
+ }
+
+ L(kh_label);
+ {
+ for (int ki = 0; ki < kw; ki++) {
+ int jj_start = get_iw_start(ki, l_overflow);
+ int jj_end = get_iw_end(ur_w, ki, r_overflow);
+ for (int oc = 0; oc < oc_block; oc++) {
+ if (jcp.kernel_kind == expl_bcast) {
+ for (int jj = jj_start; jj < jj_end; jj++) {
+ int aux_output_offset = output_offset(jj, oc, ki);
+ vbroadcastss(zmm_inp(jj, nb_ic_block),
+ ptr[aux_reg_dst + aux_output_offset]);
+ }
+ }
+ for (int ii = 0; ii < nb_ic_block; ii++) {
+ int aux_kernel_offset = kernel_offset(ii, oc, ki);
+ if (jj_end - jj_start > 0)
+ vmovups(zmm_wei, EVEX_compress_addr(aux_reg_ker,
+ aux_kernel_offset));
+ for (int jj = jj_start; jj < jj_end; jj += stride_w)
+ if (jcp.kernel_kind == expl_bcast)
+ vfmadd231ps(zmm_out(jj, ii),
+ zmm_inp(jj, nb_ic_block), zmm_wei);
+ else
+ vfmadd231ps(zmm_out(jj, ii), zmm_wei,
+ EVEX_compress_addr(aux_reg_dst,
+ output_offset(jj, oc, ki), true));
+ }
+ }
+ }
+ add(aux_reg_ker, shift_ker_ptr);
+ sub(aux_reg_dst, shift_dst_ptr);
+ dec(reg_kj);
+ cmp(reg_kj, 0);
+ jg(kh_label, T_NEAR);
+ }
+
+ if (jcp.ndims == 5) {
+ sub(aux_reg_dst_d,
+ typesize * (jcp.dilate_d + 1) * jcp.oh * ow * ic_block);
+ add(aux_reg_ker_d, typesize * jcp.kw * jcp.kh * oc_block * ic_block);
+
+ dec(reg_ki);
+ cmp(reg_ki, 0);
+ jg(kd_label, T_NEAR);
+
+ pop(reg_src);
+ pop(reg_src_prf);
+ }
+}
+
+inline void jit_avx512_common_conv_bwd_data_kernel_f32::compute_loop(
+ int ur_w, int l_overflow, int r_overflow)
+{
+ if (jcp.ndims == 5) push(reg_oi);
+
+ prepare_output(ur_w);
+
+ Label skip_compute_loop;
+ if (jcp.ndims == 5) {
+ mov(reg_kj, ptr[param + GET_OFF(kd_padding)]);
+ cmp(reg_kj, 0);
+ je(skip_compute_loop, T_NEAR);
+ }
+ mov(reg_kj, ptr[param + GET_OFF(kh_padding)]);
+ cmp(reg_kj, 0);
+ je(skip_compute_loop, T_NEAR);
+
+ if (jcp.ver == ver_4fma)
+ compute_loop_4fma(ur_w, l_overflow, r_overflow);
+ else if (jcp.ver == ver_fma)
+ if (mayiuse(avx512_mic))
+ compute_loop_fma(ur_w, l_overflow, r_overflow);
+ else
+ if (jcp.kernel_kind == embd_bcast && jcp.nb_ic_blocking == 1)
+ compute_loop_fma(ur_w, l_overflow, r_overflow);
+ else
+ compute_loop_fma_core(ur_w, l_overflow, r_overflow);
+ else
+ assert("!unknown convolution version");
+
+ L(skip_compute_loop);
+ store_output(ur_w);
+ if (jcp.ndims == 5) pop(reg_oi);
+}
+
+void jit_avx512_common_conv_bwd_data_kernel_f32::generate()
+{
+ int iw = jcp.iw;
+ int kw = jcp.kw;
+ int ur_w = jcp.ur_w;
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ int ur_w_tail = jcp.ur_w_tail;
+ int dilate_w = jcp.dilate_w + 1;
+ int stride_w = jcp.stride_w;
+
+ int dst_shift = jcp.typesize_in * (ur_w / stride_w) * ic_block;
+ int src_shift = jcp.typesize_out * ur_w * oc_block;
+
+ preamble();
+
+ mov(reg_src, ptr[param + GET_OFF(src)]);
+ mov(reg_dst, ptr[param + GET_OFF(dst)]);
+ mov(reg_ker, ptr[param + GET_OFF(filt)]);
+
+ mov(reg_kh, ptr[param + GET_OFF(kh_padding)]);
+ mov(reg_src_prf, ptr[param + GET_OFF(src_prf)]);
+ mov(reg_dst_prf, ptr[param + GET_OFF(dst_prf)]);
+ mov(reg_ker_prf, ptr[param + GET_OFF(filt_prf)]);
+
+ int l_overflow = nstl::max(0, ((kw - 1) * dilate_w - jcp.l_pad) / stride_w);
+ int r_overflow = nstl::max(0, ((kw - 1) * dilate_w
+ - nstl::max(0, jcp.r_pad)) / stride_w);
+ int r_overflow1 = nstl::max(0, ((kw - 1) * dilate_w
+ - nstl::max(0, jcp.r_pad) - ur_w_tail) / stride_w);
+
+ int n_oi = iw / ur_w;
+ if (r_overflow1 > 0) n_oi--;
+
+ if (ur_w == iw) {
+ compute_loop(ur_w, l_overflow, r_overflow);
+ } else if (n_oi == 0) {
+ compute_loop(ur_w, l_overflow, r_overflow1);
+ add(reg_src, src_shift);
+ add(reg_dst, dst_shift);
+ add(reg_src_prf, src_shift);
+ add(reg_dst_prf, dst_shift);
+ if (ur_w_tail != 0)
+ compute_loop(ur_w_tail, 0, r_overflow);
+ } else {
+ xor_(reg_oi, reg_oi);
+ if (l_overflow > 0) {
+ compute_loop(ur_w, l_overflow, 0);
+ add(reg_src, src_shift);
+ add(reg_dst, dst_shift);
+ add(reg_src_prf, src_shift);
+ add(reg_dst_prf, dst_shift);
+
+ inc(reg_oi);
+ }
+ if ((l_overflow <= 0 && n_oi > 0)
+ || (l_overflow > 0 && n_oi > 1)) {
+ Label ow_loop_label;
+ L(ow_loop_label); {
+ compute_loop(ur_w, 0, 0);
+ add(reg_src, src_shift);
+ add(reg_dst, dst_shift);
+ add(reg_src_prf, src_shift);
+ add(reg_dst_prf, dst_shift);
+
+ inc(reg_oi);
+ cmp(reg_oi, n_oi);
+ jl(ow_loop_label, T_NEAR);
+ }
+ }
+ if (r_overflow1 > 0) {
+ compute_loop(ur_w, 0, r_overflow1);
+ add(reg_src, src_shift);
+ add(reg_dst, dst_shift);
+ add(reg_src_prf, src_shift);
+ add(reg_dst_prf, dst_shift);
+ }
+ if (ur_w_tail != 0) {
+ compute_loop(ur_w_tail, 0, r_overflow);
+ }
+ }
+
+ postamble();
+}
+
+status_t jit_avx512_common_conv_bwd_data_kernel_f32::init_conf(
+ jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd,
+ const memory_desc_wrapper &diff_src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &diff_dst_d)
+{
+ if (!mayiuse(avx512_common)) return status::unimplemented;
+
+ jcp = zero<decltype(jcp)>();
+
+ jcp.simd_w = cpu_isa_traits<avx512_common>::vlen / sizeof(float);
+ const bool with_groups = weights_d.ndims() == diff_src_d.ndims() + 1;
+ int ndims = diff_src_d.ndims();
+
+ jcp.ndims = ndims;
+ jcp.prop_kind = cd.prop_kind;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = diff_src_d.dims()[0];
+
+ jcp.oc = diff_dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = diff_src_d.dims()[1] / jcp.ngroups;
+
+ jcp.id = (ndims == 5) ? diff_src_d.dims()[2] : 1;
+ jcp.ih = (ndims == 3) ? 1 : diff_src_d.dims()[ndims-2];
+ jcp.iw = diff_src_d.dims()[ndims-1];
+ jcp.od = (ndims == 5) ? diff_dst_d.dims()[2] : 1;
+ jcp.oh = (ndims == 3) ? 1 : diff_dst_d.dims()[ndims-2];
+ jcp.ow = diff_dst_d.dims()[ndims-1];
+
+ jcp.kd = (ndims == 5) ? weights_d.dims()[with_groups + 2] : 1;
+ jcp.kh = (ndims == 3) ? 1 : weights_d.dims()[with_groups + ndims - 2];
+ jcp.kw = weights_d.dims()[with_groups + ndims - 1];
+
+ jcp.f_pad = (ndims == 5) ? cd.padding[0][0] : 0;
+ jcp.t_pad = (ndims == 3) ? 0 : cd.padding[0][ndims-4];
+ jcp.l_pad = cd.padding[0][ndims-3];
+
+ jcp.stride_d = (ndims == 5) ? cd.strides[0] : 1;
+ jcp.stride_h = (ndims == 3) ? 1 : cd.strides[ndims-4];
+ jcp.stride_w = cd.strides[ndims-3];
+
+ jcp.dilate_d = (ndims == 5) ? cd.dilates[0] : 0;
+ jcp.dilate_h = (ndims == 3) ? 0 : cd.dilates[ndims-4];
+ jcp.dilate_w = cd.dilates[ndims-3];
+ if ((jcp.dilate_w != 0 && jcp.stride_w != 1)
+ || (jcp.dilate_d != 0 && jcp.stride_d != 1)
+ || (jcp.dilate_h != 0 && jcp.stride_h != 1))
+ return status::unimplemented;
+
+ jcp.r_pad = (jcp.ow - 1) * jcp.stride_w + (jcp.kw - 1) * (jcp.dilate_w + 1)
+ - (jcp.iw + jcp.l_pad - 1);
+ jcp.b_pad = (jcp.oh - 1) * jcp.stride_h + (jcp.kh - 1) * (jcp.dilate_h + 1)
+ - (jcp.ih + jcp.t_pad - 1);
+ jcp.back_pad = (jcp.od - 1) * jcp.stride_d
+ + (jcp.kd - 1) * (jcp.dilate_d + 1) - (jcp.id + jcp.f_pad - 1);
+
+ jcp.aligned_threads = 0;
+
+ jcp.is_1stconv = false;
+
+ jcp.oc_block = jcp.simd_w;
+ jcp.ic_block = jcp.is_1stconv ? jcp.ic : jcp.simd_w;
+
+ bool ok_to_pad_channels = true
+ && jcp.ngroups == 1
+ && diff_src_d.data_type() == data_type::f32;
+
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, jcp.oc_block);
+ jcp.ic = rnd_up(jcp.ic, jcp.ic_block);
+ }
+
+ auto dat_tag = pick(ndims - 3, nCw16c, nChw16c, nCdhw16c);
+ auto wei_tag = with_groups
+ ? pick(ndims - 3, gOIw16o16i, gOIhw16o16i, gOIdhw16o16i)
+ : pick(ndims - 3, OIw16o16i, OIhw16o16i, OIdhw16o16i);
+ jcp.src_tag = diff_src_d.matches_one_of_tag(dat_tag);
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(dat_tag);
+
+ bool args_ok = true
+ && jcp.oc % jcp.oc_block == 0
+ && jcp.ic % jcp.ic_block == 0
+ && jcp.src_tag == dat_tag
+ && jcp.dst_tag == dat_tag;
+ if (!args_ok)
+ return status::unimplemented;
+
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+ jcp.nb_oc = jcp.oc / jcp.oc_block;
+
+ jcp.ur_w = jcp.stride_w;
+
+ int regs = 28;
+ if (jcp.iw <= regs)
+ jcp.ur_w = jcp.iw;
+ else {
+ for (int ur_w = regs; ur_w > 0; --ur_w)
+ if (ur_w % jcp.stride_w == 0) {
+ jcp.ur_w = ur_w;
+ break;
+ }
+ }
+ int l_overflow = nstl::max(0, ((jcp.kw - 1) * (jcp.dilate_w + 1)
+ - jcp.l_pad) / jcp.stride_w);
+ int r_overflow1 = nstl::max(0, ((jcp.kw - 1) * (jcp.dilate_w + 1)
+ - nstl::max(0, jcp.r_pad) - jcp.iw % jcp.ur_w) / jcp.stride_w);
+ int n_oi = jcp.iw / jcp.ur_w;
+ if (r_overflow1 > 0) n_oi--;
+
+ if (mayiuse(avx512_common)
+ && diff_dst_d.data_type() == data_type::f32
+ && weights_d.data_type() == data_type::f32
+ && diff_src_d.data_type() == data_type::f32) {
+ jcp.ver = ver_fma;
+ jcp.typesize_in = sizeof(float);
+ jcp.typesize_out = sizeof(float);
+ if (mayiuse(avx512_mic_4ops)
+ && jcp.stride_w == 1 && jcp.stride_h == 1 && jcp.stride_d == 1) {
+ jcp.ver = ver_4fma;
+ }
+ } else {
+ return status::unimplemented;
+ }
+
+ jcp.wei_tag = weights_d.matches_one_of_tag(wei_tag);
+ if (jcp.wei_tag != wei_tag)
+ return status::unimplemented;
+
+ if (!utils::everyone_is(0, jcp.dilate_d, jcp.dilate_h, jcp.dilate_w)
+ && jcp.ver != ver_fma)
+ return status::unimplemented;
+
+ jcp.nb_ic_blocking = jcp.nb_oc_blocking = 1;
+ if (jcp.ver == ver_4fma) {
+ if (jcp.kw == 3 && jcp.kh == 3 && jcp.iw == 7 && jcp.ih == 7) {
+ jcp.nb_ic_blocking = 2;
+ } else {
+ for (int i = jcp.nb_ic; i > 0; i--)
+ if (i * jcp.ur_w <= regs && jcp.nb_ic % i == 0) {
+ jcp.nb_ic_blocking = i;
+ break;
+ }
+ }
+ }
+
+ jcp.loop_order = loop_gnc;
+
+ bool large_code_size = (jcp.ur_w != jcp.ow)
+ && ((l_overflow <= 0 && n_oi > 0) ||(l_overflow > 0 && n_oi > 1))
+ && (r_overflow1 > 0) && (l_overflow > 0);
+ if (large_code_size) {
+ const int max_code_size = 24 * 1024;
+ const int num_ops_per_reg = 6 + jcp.oc_block * jcp.kw;
+ int mult = 1;
+ if (l_overflow > 0) mult += 1;
+ if (r_overflow1 > 0) mult += 1;
+ for (int ur_w = jcp.ur_w; ur_w > regs/2; --ur_w) {
+ if ((ur_w / jcp.stride_w) * mult * num_ops_per_reg * 9.2
+ < max_code_size) {
+ if (ur_w % jcp.stride_w == 0) {
+ jcp.ur_w = ur_w;
+ break;
+ }
+ }
+ }
+ }
+
+ if (jcp.ver == ver_fma && mayiuse(avx512_core)) {
+ int try_nb_ic_blocking = 2;
+ unsigned int ker_inp_size = typesize * jcp.iw * jcp.ic_block
+ * try_nb_ic_blocking * jcp.kh;
+ unsigned int ker_out_size = typesize * jcp.ow * jcp.oc_block;
+ unsigned int ker_wei_size = typesize * jcp.kh * jcp.kw * jcp.ic_block
+ * jcp.oc_block * try_nb_ic_blocking;
+ unsigned int ker_total_size = ker_inp_size + ker_out_size
+ + ker_wei_size;
+ if (!(jcp.kw == 1 || (jcp.kw == 5 && jcp.iw < 8)
+ || (jcp.kw < 5 && ((jcp.iw <= 5 || (jcp.iw > 8 && jcp.iw <= 13))
+ || ker_total_size > L1_cache_size )))
+ || jcp.stride_h > 1 || jcp.stride_d > 1) {
+ jcp.kernel_kind = embd_bcast;
+ jcp.ur_w = nstl::min(jcp.iw, regs);
+ jcp.nb_ic_blocking = jcp.nb_oc_blocking = 1;
+ if (!(jcp.kw > 3 || (jcp.kw == 3 && ker_total_size < L1_cache_size
+ && jcp.ow > 8)) && jcp.stride_h == 1)
+ if (jcp.nb_ic % try_nb_ic_blocking == 0) {
+ jcp.nb_ic_blocking = try_nb_ic_blocking;
+ jcp.ur_w = 31 / (jcp.nb_ic_blocking + 1);
+ if (jcp.iw < jcp.ur_w) jcp.ur_w = jcp.iw;
+ }
+ } else {
+ jcp.kernel_kind = expl_bcast;
+ jcp.nb_oc_blocking = 1;
+ jcp.nb_ic_blocking = 4;
+ if (jcp.nb_ic < jcp.nb_ic_blocking) jcp.nb_ic_blocking = jcp.nb_ic;
+ if (jcp.nb_ic % jcp.nb_ic_blocking != 0)
+ for (int i = jcp.nb_ic_blocking; i > 0; i--)
+ if (jcp.nb_ic % i == 0) {
+ jcp.nb_ic_blocking = i;
+ break;
+ }
+ jcp.ur_w = 31 / (jcp.nb_ic_blocking + 1);
+ if (jcp.iw < jcp.ur_w) jcp.ur_w = jcp.iw;
+ }
+ }
+ jcp.ur_w_tail = jcp.iw % jcp.ur_w;
+
+ if (l_overflow * jcp.stride_w > jcp.ur_w)
+ return status::unimplemented;
+ int r_overflow_no_tail = nstl::max(0, ((jcp.kw - 1) * (jcp.dilate_w + 1)
+ - nstl::max(0, jcp.r_pad) - jcp.ur_w_tail) / jcp.stride_w);
+ if (r_overflow_no_tail * jcp.stride_w > jcp.ur_w)
+ return status::unimplemented;
+ if ((jcp.iw > jcp.ur_w) && (jcp.ur_w % jcp.stride_w != 0))
+ return status::unimplemented;
+
+ pick_loop_order(jcp);
+
+ jcp.nb_oc_L2 = jcp.nb_oc;
+ if (jcp.ver == ver_4fma && (jcp.kh < 5 && jcp.kw < 5)) {
+ for (int divf = 2, temp_nb = jcp.nb_oc_L2; divf <= jcp.nb_oc;
+ divf++) {
+ size_t l2_src = jcp.iw * jcp.ic_block * jcp.nb_ic_blocking * jcp.ih
+ * jcp.id;
+ size_t l2_dst = jcp.ow * jcp.oc_block * temp_nb * jcp.oh * jcp.od;
+ size_t l2_filt = jcp.kw * jcp.oc_block * jcp.ic_block * jcp.kh
+ * jcp.kd * jcp.nb_ic_blocking * temp_nb;
+ if (4 * (l2_src + l2_dst + l2_filt) > KNx_L2_EFFECTIVE_CAPACITY) {
+ if (jcp.kh == 3 && jcp.ih == 7) {
+ jcp.nb_oc_L2 = 1;
+ break;
+ }
+ temp_nb = (jcp.nb_oc_L2 % divf == 0 ? jcp.nb_oc_L2 / divf
+ : jcp.nb_oc_L2);
+ } else {
+ jcp.nb_oc_L2 = temp_nb;
+ break;
+ }
+ }
+ }
+
+ args_ok = true
+ && jcp.ic <= diff_src_d.padded_dims()[1]
+ && jcp.oc <= diff_dst_d.padded_dims()[1]
+ && jcp.ic <= weights_d.padded_dims()[with_groups + 1]
+ && jcp.oc <= weights_d.padded_dims()[with_groups + 0];
+ if (!args_ok) return status::unimplemented;
+
+ return status::success;
+}
+
+void jit_avx512_common_conv_bwd_data_kernel_f32::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad, const jit_conv_conf_t &jcp) {
+ UNUSED(scratchpad);
+ UNUSED(jcp);
+}
+
+const int jit_avx512_common_conv_bwd_weights_kernel_f32::max_ur_w = 28;
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::od_step_comeback_pointers()
+{
+ Label kd_comeback_label;
+
+ /* 'depth' loop count bound by 'kd_work_size' */
+ mov(kj, reg_kd_count);
+ L(kd_comeback_label); {
+ int inp_mult = jcp.is_1stconv ? 1 : jcp.ic_block;
+ int iw = jcp.ver == ver_4fma ? jcp.tr_iw : jcp.iw;
+ sub(reg_input,
+ jcp.typesize_in * (jcp.dilate_d + 1) * jcp.ih * iw * inp_mult);
+ sub(reg_kernel,
+ jcp.typesize_out * jcp.kh * jcp.kw * jcp.ic_block * jcp.oc_block);
+ dec(kj);
+ cmp(kj, 0);
+ jg(kd_comeback_label, T_NEAR);
+ }
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::oh_step_comeback_pointers()
+{
+ Label kh_comeback_label, kd_comeback_label;
+ mov(kj, reg_kh);
+ L(kh_comeback_label); {
+ int inp_mult = jcp.is_1stconv ? 1 : jcp.ic_block;
+ int iw = jcp.ver == ver_4fma ? jcp.tr_iw : jcp.iw;
+ sub(reg_input, jcp.typesize_in * (jcp.dilate_h + 1) * iw * inp_mult);
+ sub(reg_kernel,
+ jcp.typesize_out * jcp.kw * jcp.ic_block * jcp.oc_block);
+ dec(kj);
+ cmp(kj, 0);
+ jg(kh_comeback_label, T_NEAR);
+ }
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::compute_ic_block_step_fma(
+ int ur_w, int pad_l, int pad_r,
+ int ic_block_step, int input_offset, int kernel_offset,
+ int output_offset, bool input_wraparound)
+{
+
+ int kw = jcp.kw;
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ for (int i_kw = 0; i_kw < kw; i_kw++)
+ for (int i_ic = 0; i_ic < ic_block_step; i_ic++)
+ vmovups(Zmm(i_kw * ic_block_step + i_ic),
+ EVEX_compress_addr(reg_kernel, typesize * (i_kw * ic_block
+ + i_ic) * jcp.oc_block + kernel_offset));
+
+ for (int i_ur = 0; i_ur < ur_w; i_ur++) {
+ if (i_ur == 0) {
+ vmovups(Zmm(kw * ic_block_step + (i_ur + 0) % 4),
+ EVEX_compress_addr(reg_output, typesize * (i_ur + 0)
+ * oc_block + output_offset));
+ if (ur_w > 1) vmovups(Zmm(kw * ic_block_step + (i_ur + 1) % 4),
+ EVEX_compress_addr(reg_output, typesize * (i_ur + 1) * oc_block
+ + output_offset));
+ if (ur_w > 2) vmovups(Zmm(kw * ic_block_step + (i_ur + 2) % 4),
+ EVEX_compress_addr(reg_output, typesize * (i_ur + 2) * oc_block
+ + output_offset));
+ if (ur_w > 3) vmovups(Zmm(kw * ic_block_step + (i_ur + 3) % 4),
+ EVEX_compress_addr(reg_output, typesize * (i_ur + 3) * oc_block
+ + output_offset));
+ } else if (i_ur + 3 < ur_w)
+ vmovups(Zmm(kw * ic_block_step + (i_ur + 3) % 4),
+ EVEX_compress_addr(reg_output, typesize * (i_ur + 3) * oc_block
+ + output_offset));
+
+ for (int i_kw = 0; i_kw < kw; i_kw++) {
+ int i_iw = i_ur * jcp.stride_w + i_kw * (jcp.dilate_w + 1);
+ if (i_iw - pad_l < 0 || i_iw > (ur_w - 1) * jcp.stride_w +
+ (kw - 1) * (jcp.dilate_w + 1) - pad_r) continue;
+ for (int i_ic = 0; i_ic < ic_block_step; i_ic++) {
+ const size_t i_offset = (size_t)input_offset
+ + (size_t)typesize * (jcp.ver == ver_4fma
+ ? (i_iw - pad_l + i_ic * jcp.tr_iw)
+ : (jcp.is_1stconv
+ ? (i_iw - pad_l) + (size_t)i_ic
+ * ((size_t)jcp.ih*jcp.iw*jcp.id)
+ : (i_iw - pad_l) * ic_block + i_ic));
+ vfmadd231ps(Zmm(i_kw * ic_block_step + i_ic),
+ Zmm(kw * ic_block_step + i_ur % 4),
+ EVEX_compress_addr_safe(reg_input, i_offset, reg_long_offt,
+ true));
+ }
+ }
+ }
+
+ for (int i_kw = 0; i_kw < kw; i_kw++)
+ for (int i_ic = 0; i_ic < ic_block_step; i_ic++)
+ vmovups(EVEX_compress_addr(reg_kernel, typesize
+ * (i_kw * ic_block + i_ic) * jcp.oc_block + kernel_offset),
+ Zmm(i_kw * ic_block_step + i_ic));
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::compute_ic_block_step_4fma(
+ int ur_w, int pad_l, int pad_r,
+ int ic_block_step, int input_offset, int kernel_offset,
+ int output_offset, bool input_wraparound)
+{
+ // TODO: add prefetches to fma version as well
+
+ assert(jcp.ver == ver_4fma);
+
+ int kw = jcp.kw;
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+
+ auto zmm_ker = [=](int i_kw, int i_ic) {
+ return Zmm(i_kw * ic_block_step + i_ic);
+ };
+
+ auto ker_addr = [=](int i_kw, int i_ic) {
+ size_t local_offset
+ = jcp.typesize_out * (i_kw * ic_block + i_ic) * jcp.oc_block;
+ return EVEX_compress_addr(reg_kernel, local_offset + kernel_offset);
+ };
+
+ auto inp_addr = [=](int i_iw, int i_ic, ptrdiff_t extra_offset = 0) {
+ int stride = jcp.tr_iw * (jcp.is_1stconv ? jcp.ih : 1);
+ int local_offset = jcp.typesize_in * (i_iw + i_ic * stride);
+ return EVEX_compress_addr(reg_input,
+ local_offset + input_offset + extra_offset);
+ };
+
+ auto zmm_out = [=](int i_iw) {
+ // TODO: move reg calc to global member funcs
+ const int out_zmm_base_idx = 28;
+ return Zmm(out_zmm_base_idx + i_iw % 4);
+ };
+
+ auto out_addr = [=](int i_ur) {
+ return EVEX_compress_addr(reg_output,
+ jcp.typesize_in * i_ur * oc_block + output_offset);
+ };
+
+ auto pf_callback = [=](int i_ur, int i_kw, int i_ic) {
+ assert(i_ur % 4 == 0);
+ if (i_ur == 0)
+ prefetcht1(ker_addr(i_kw, i_ic));
+ if (i_ur + 4 >= ur_w)
+ prefetcht0(ker_addr(i_kw, i_ic));
+
+ const ptrdiff_t next_input_block_offset
+ = jcp.typesize_in * ic_block_step * jcp.tr_iw;
+ if (i_ur % 16 == 4 && i_kw == 0) {
+ if (i_ur + 16 < ur_w)
+ prefetcht0(inp_addr(i_ur + 16, i_ic));
+ else
+ prefetcht0(inp_addr(0, i_ic, next_input_block_offset));
+ }
+ if (i_ur % 16 == 4 && i_kw == 1) {
+ if (input_wraparound)
+ prefetcht1(inp_addr(i_ur, i_ic, -input_offset));
+ else
+ prefetcht1(inp_addr(i_ur, i_ic, next_input_block_offset));
+ }
+ };
+
+ for (int i_kw = 0; i_kw < kw; i_kw++)
+ for (int i_ic = 0; i_ic < ic_block_step; i_ic++) {
+ auto zmm = zmm_ker(i_kw, i_ic);
+ vpxord(zmm, zmm, zmm);
+ }
+
+ for (int i_ur = 0; i_ur < ur_w; i_ur += 4) {
+
+ for (int i = 0; i < 4; i++) {
+ auto zmm = zmm_out(i_ur + i);
+ if (i_ur + i < ur_w)
+ vmovups(zmm, out_addr(i_ur + i));
+ else
+ vpxord(zmm, zmm, zmm);
+ prefetcht0(out_addr(i_ur + i + 4));
+ }
+
+ for (int i_kw = 0; i_kw < kw; i_kw++)
+ for (int i_ic = 0; i_ic < ic_block_step; i_ic++) {
+ int i_iw = i_ur + i_kw;
+ v4fmaddps(zmm_ker(i_kw, i_ic),
+ zmm_out(i_ur), inp_addr(i_iw, i_ic));
+ pf_callback(i_ur, i_kw, i_ic);
+ }
+ }
+
+ for (int i_kw = 0; i_kw < kw; i_kw++)
+ for (int i_ic = 0; i_ic < ic_block_step; i_ic++) {
+ auto addr = ker_addr(i_kw, i_ic);
+ auto zmm = zmm_ker(i_kw, i_ic);
+ vaddps(zmm, zmm, addr);
+ vmovups(addr, zmm);
+ }
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::compute_ic_block_step(
+ int ur_w, int pad_l, int pad_r,
+ int ic_block_step, int input_offset, int kernel_offset,
+ int output_offset, bool input_wraparound)
+{
+ if (jcp.ver == ver_4fma)
+ compute_ic_block_step_4fma(ur_w, pad_l, pad_r,
+ ic_block_step, input_offset, kernel_offset, output_offset,
+ input_wraparound);
+ else if (jcp.ver == ver_fma)
+ compute_ic_block_step_fma(ur_w, pad_l, pad_r,
+ ic_block_step, input_offset, kernel_offset, output_offset,
+ input_wraparound);
+ else
+ assert(!"unknown convolution version");
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32
+ ::compute_oh_step_unroll_ow_icblock(
+ int ic_block_step, int max_ur_w)
+{
+ UNUSED(max_ur_w);
+
+ Label kh_label, kd_label;
+
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ int inp_mul = !jcp.is_1stconv ? ic_block : 1;
+ int iw = jcp.ver == ver_4fma ? jcp.tr_iw : jcp.iw;
+ int ow = jcp.ow;
+
+ int r_pad = nstl::max(0, (ow - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1) - (jcp.iw + jcp.l_pad - 1));
+ int l_pad = jcp.l_pad;
+
+ if (jcp.ndims == 5) {
+ L(kd_label);
+ mov(reg_input, aux_reg_input);
+ mov(reg_kernel, aux_reg_kernel);
+ }
+
+ mov(kj, reg_kh);
+ L(kh_label);
+ {
+ for (int i_b_ic = 0; i_b_ic < jcp.ic_block; i_b_ic += ic_block_step) {
+ const int input_offset = jcp.typesize_in
+ * (jcp.ver == ver_4fma ? i_b_ic * iw : i_b_ic);
+ compute_ic_block_step(jcp.ur_w, l_pad, r_pad, ic_block_step,
+ input_offset, jcp.typesize_out * i_b_ic * jcp.oc_block, 0,
+ i_b_ic + ic_block_step >= jcp.ic_block);
+ }
+ add(reg_input, jcp.typesize_in * (jcp.dilate_h + 1) * iw * inp_mul);
+ add(reg_kernel, jcp.typesize_out * jcp.kw * ic_block * oc_block);
+ dec(kj);
+ cmp(kj, 0);
+ jg(kh_label, T_NEAR);
+ }
+
+ if (jcp.ndims == 5) {
+ add(aux_reg_input,
+ jcp.typesize_in * (jcp.dilate_d + 1) * jcp.ih * iw * inp_mul);
+ add(aux_reg_kernel, jcp.typesize_out * jcp.kh * jcp.kw * ic_block
+ * oc_block);
+ dec(ki);
+ cmp(ki, 0);
+ jg(kd_label, T_NEAR);
+ }
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32
+ ::compute_oh_step_unroll_ow(
+ int ic_block_step, int max_ur_w)
+{
+ Label kh_label, ic_block_label, kd_label;
+
+ UNUSED(max_ur_w);
+
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+
+ int ow = jcp.ow;
+
+ int r_pad = nstl::max(0,
+ (ow - 1) * jcp.stride_w + (jcp.kw - 1) * (jcp.dilate_w + 1)
+ - (jcp.iw + jcp.l_pad - 1));
+ int l_pad = jcp.l_pad;
+
+ if (jcp.ndims == 5) {
+ L(kd_label);
+ mov(reg_input, aux_reg_input);
+ mov(reg_kernel, aux_reg_kernel);
+ }
+
+ mov(kj, reg_kh);
+ L(kh_label);
+ {
+ xor_(b_ic, b_ic);
+ L(ic_block_label); {
+ compute_ic_block_step(ow, l_pad, r_pad, ic_block_step,
+ 0, 0, 0);
+ size_t inp_icblk_stride = jcp.is_1stconv
+ ? (size_t)jcp.ih * jcp.iw * jcp.id
+ : (jcp.ver == ver_4fma ? jcp.tr_iw : 1);
+ size_t input_offset
+ = inp_icblk_stride * jcp.typesize_in * ic_block_step;
+ safe_add(reg_input, input_offset, reg_long_offt);
+ add(reg_kernel, jcp.typesize_out * ic_block_step * oc_block);
+ add(b_ic, ic_block_step);
+ cmp(b_ic, jcp.ic_block);
+ jl(ic_block_label, T_NEAR);
+ }
+
+ if (jcp.is_1stconv) {
+ size_t input_offset
+ = (size_t)jcp.typesize_in * jcp.id * jcp.ih * jcp.iw * ic_block;
+ safe_sub(reg_input, input_offset, reg_long_offt);
+ add(reg_input, jcp.typesize_in * (jcp.dilate_h + 1) * jcp.iw);
+ } else if (jcp.ver != ver_4fma) {
+ add(reg_input, jcp.typesize_in
+ * ((jcp.dilate_h + 1) * jcp.iw - 1) * ic_block);
+ }
+ add(reg_kernel, jcp.typesize_out * (jcp.kw - 1) * ic_block * oc_block);
+ dec(kj);
+ cmp(kj, 0);
+ jg(kh_label, T_NEAR);
+ }
+ if (jcp.ndims == 5) {
+ add(aux_reg_input, jcp.typesize_in * (jcp.dilate_d + 1) * jcp.ih
+ * jcp.iw * (jcp.is_1stconv ? 1 : ic_block));
+ add(aux_reg_kernel, jcp.typesize_out * jcp.kh * jcp.kw * ic_block
+ * oc_block);
+ dec(ki);
+ cmp(ki, 0);
+ jg(kd_label, T_NEAR);
+ }
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32
+ ::compute_oh_step_common(
+ int ic_block_step, int max_ur_w)
+{
+ Label kh_label, ic_block_label, ow_block_label, kd_label;
+
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+
+ int ow = jcp.ow;
+ int r_pad = nstl::max(0, (ow - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1) - (jcp.iw + jcp.l_pad - 1));
+ int l_pad = jcp.ver == ver_4fma ? 0 : jcp.l_pad;
+
+ int ur_w = nstl::min(ow, max_ur_w);
+ int ur_w_trips = ow / ur_w;
+ int ur_w_tail = ow % ur_w;
+ if ((ur_w_tail == 0 && r_pad != 0)
+ || r_pad >= ur_w_tail) {
+ if (ur_w_trips > 1) {
+ ur_w_tail += ur_w;
+ ur_w_trips--;
+ } else {
+ ur_w_tail += (ur_w - ur_w / 2);
+ ur_w = ur_w / 2;
+ }
+ }
+
+ int inp_mult = (jcp.is_1stconv || jcp.ver == ver_4fma) ? 1 : ic_block;
+ int input_comeback = (ur_w_trips * ur_w * jcp.stride_w - l_pad) * inp_mult;
+ int output_comeback = ur_w_trips * ur_w * oc_block;
+
+ if (jcp.ndims == 5) {
+ L(kd_label);
+ mov(reg_input, aux_reg_input);
+ mov(reg_kernel, aux_reg_kernel);
+ }
+
+ mov(kj, reg_kh);
+ L(kh_label); {
+ xor_(b_ic, b_ic);
+ L(ic_block_label); {
+ if (l_pad != 0) {
+ ur_w_trips--;
+ compute_ic_block_step(ur_w, l_pad, 0, ic_block_step, 0, 0, 0);
+ add(reg_input, jcp.typesize_in * (ur_w * jcp.stride_w - l_pad)
+ * inp_mult);
+ add(reg_output, jcp.typesize_in * ur_w * oc_block);
+ }
+
+ if (ur_w_trips > 0) {
+ xor_(reg_ur_w_trips, reg_ur_w_trips);
+ L(ow_block_label); {
+ compute_ic_block_step(ur_w, 0, 0, ic_block_step, 0, 0, 0);
+ add(reg_input, jcp.typesize_in * ur_w * jcp.stride_w
+ * inp_mult);
+ add(reg_output, jcp.typesize_in * ur_w * oc_block);
+
+ inc(reg_ur_w_trips);
+ cmp(reg_ur_w_trips, ur_w_trips);
+ jl(ow_block_label, T_NEAR);
+ }
+ }
+
+ if (ur_w_tail > 0) compute_ic_block_step(ur_w_tail, 0, r_pad,
+ ic_block_step, 0, 0, 0);
+
+ sub(reg_input, jcp.typesize_in * input_comeback);
+ sub(reg_output, jcp.typesize_in * output_comeback);
+ int inp_icblk_stride = jcp.is_1stconv
+ ? jcp.ih * jcp.iw * jcp.id
+ : (jcp.ver == ver_4fma ? jcp.tr_iw : 1);
+ size_t input_offset
+ = inp_icblk_stride * jcp.typesize_in * ic_block_step;
+ safe_add(reg_input, input_offset, reg_long_offt);
+ add(reg_kernel, jcp.typesize_out * ic_block_step * oc_block);
+
+ add(b_ic, ic_block_step);
+ cmp(b_ic, jcp.ic_block);
+ jl(ic_block_label, T_NEAR);
+ }
+ if (jcp.is_1stconv) {
+ size_t input_offset
+ = (size_t)jcp.typesize_in * jcp.id * jcp.ih * jcp.iw * ic_block;
+ safe_sub(reg_input, input_offset, reg_long_offt);
+ add(reg_input, jcp.typesize_in * (jcp.dilate_h + 1) * jcp.iw);
+ } else if (jcp.ver != ver_4fma) {
+ add(reg_input, jcp.typesize_in
+ * ((jcp.dilate_h + 1 ) * jcp.iw - 1) * ic_block);
+ }
+ add(reg_kernel, jcp.typesize_out * (jcp.kw - 1) * ic_block * oc_block);
+ dec(kj);
+ cmp(kj, 0);
+ jg(kh_label, T_NEAR);
+ }
+ if (jcp.ndims == 5) {
+ add(aux_reg_input, jcp.typesize_in * (jcp.dilate_d + 1) * jcp.ih
+ * jcp.iw * (jcp.is_1stconv ? 1 : ic_block));
+ add(aux_reg_kernel, jcp.typesize_out * jcp.kh * jcp.kw * ic_block
+ * oc_block);
+ dec(ki);
+ cmp(ki, 0);
+ jg(kd_label, T_NEAR);
+ }
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32
+ ::compute_oh_step_disp()
+{
+ int ic_block_step = jcp.kw <= 3 ? 8 : (jcp.kw <= 7 ? 4 : 2);
+ if (jcp.is_1stconv) {
+ bool large_code = jcp.kw >= 7 && (jcp.l_pad > 0 || jcp.t_pad > 0);
+ ic_block_step
+ = (jcp.kw * jcp.ic_block <= 28 && !large_code) ? jcp.ic_block : 1;
+ }
+
+ bool too_large_to_unroll
+ = (jcp.kw > 1 || jcp.kh > 1 || jcp.kd > 1)
+ && (jcp.stride_w > 1 || jcp.stride_h > 1 || jcp.stride_d > 1);
+
+ int ow = jcp.ow;
+ if (jcp.ndims == 5) {
+ /* NOTE: reg_kd_count = aux_reg_input = r12. The following order of
+ * 'movs' must be guaranteed. */
+ mov(ki, reg_kd_count);
+ push(reg_kd_count);
+ mov(aux_reg_input, reg_input);
+ mov(aux_reg_kernel, reg_kernel);
+ }
+
+ if (jcp.kw <= 3 && ow <= 16 && !too_large_to_unroll)
+ compute_oh_step_unroll_ow_icblock(ic_block_step, max_ur_w);
+ else if (ow <= max_ur_w)
+ compute_oh_step_unroll_ow(ic_block_step, max_ur_w);
+ else
+ compute_oh_step_common(ic_block_step, max_ur_w);
+
+ if (jcp.ndims == 5) {
+ mov(reg_input, aux_reg_input);
+ mov(reg_kernel, aux_reg_kernel);
+ pop(reg_kd_count);
+ od_step_comeback_pointers();
+ } else {
+ oh_step_comeback_pointers();
+ }
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::maybe_zero_kernel()
+{
+ Label skip_zeroing, zeroing_loop;
+
+ mov(reg_tmp, ptr[param + GET_OFF(channel)]);
+ cmp(reg_tmp, 0);
+ jz(skip_zeroing, T_NEAR);
+
+ Zmm zero = Zmm(0);
+ vpxord(zero, zero, zero);
+ xor_(reg_tmp, reg_tmp);
+ L(zeroing_loop); {
+ assert(jcp.oc_block * jcp.typesize_out
+ == cpu_isa_traits<avx512_common>::vlen);
+ for (int ic1 = 0; ic1 < jcp.ic_block; ic1++)
+ vmovups(ptr[reg_kernel + reg_tmp + ic1 * jcp.oc_block
+ * jcp.typesize_out], zero);
+ add(reg_tmp, jcp.ic_block * jcp.oc_block * jcp.typesize_out);
+ cmp(reg_tmp, jcp.ic_block * jcp.oc_block * jcp.kw * jcp.kh * jcp.kd
+ * jcp.typesize_out);
+ jnz(zeroing_loop);
+ }
+
+ L(skip_zeroing);
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::bias_kernel()
+{
+ Label skip_bias, bias_loop, skip_load_bias;
+
+ mov(reg_tmp, ptr[param + GET_OFF(flags)]);
+ test(reg_tmp,reg_tmp);
+ jne(skip_bias, T_NEAR);
+
+ mov(reg_bias, ptr[param + GET_OFF(bias)]);
+ mov(reg_output, ptr[param + GET_OFF(dst)]);
+ vpxord(Zmm(1), Zmm(1), Zmm(1));
+
+ mov(reg_tmp, ptr[param + GET_OFF(channel)]);
+ cmp(reg_tmp, 0);
+ jne(skip_load_bias, T_NEAR);
+ vmovups(Zmm(1), ptr[reg_bias]);
+
+ L(skip_load_bias);
+
+ mov(reg_oi, ptr[param + GET_OFF(d_worksize)]);
+ sub(reg_oi, ptr[param + GET_OFF(d_index)]);
+ mov(reg_tmp, jcp.oc_block * jcp.ow * jcp.oh * jcp.typesize_out);
+ imul(reg_oi, reg_tmp);
+
+ xor_(reg_tmp, reg_tmp);
+ L(bias_loop); {
+ vmovups(Zmm(0), ptr[reg_output + reg_tmp]);
+ vaddps(Zmm(1), Zmm(1), Zmm(0));
+ add(reg_tmp, jcp.oc_block * jcp.typesize_out);
+ cmp(reg_tmp, reg_oi);
+ jl(bias_loop);
+ }
+ vmovups(EVEX_compress_addr(reg_bias,0), Zmm(1));
+
+ L(skip_bias);
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32
+ ::compute_oh_loop_common()
+{
+ int b_pad = jcp.b_pad;
+ int t_pad = jcp.t_pad;
+ bool is_dilated = jcp.dilate_h != 0;
+ int dilate_h = jcp.dilate_h + 1;
+ int stride_h = jcp.stride_h;
+ const int inp_mult = jcp.is_1stconv ? 1 : jcp.ic_block;
+ int iw = jcp.ver == ver_4fma ? jcp.tr_iw : jcp.iw;
+ Label oh_label, oh_label_end, oh_tpad_label, oh_tpad_tail_label,
+ oh_bpad_label, oh_bpad_label_end, od_label, od_label_end,
+ oh_dilate_label_shift, oh_dilate_label_noshift, oh_dilate_label_end;
+
+ int ow = jcp.ow;
+
+ mov(reg_kh, jcp.kh);
+ xor_(reg_ih_count, reg_ih_count);
+ xor_(reg_oj, reg_oj);
+ /* Compute 'top' edge */
+ if (t_pad > 0) {
+ const int kh_range = 1 + (jcp.kh - 1) * dilate_h;
+ const int overflow
+ = nstl::max(0, jcp.kh - div_up(t_pad + jcp.ih, dilate_h));
+ const int underflow = div_up(t_pad, dilate_h);
+ const int initial_inp_ker_overlap = jcp.kh - overflow - underflow;
+ mov(reg_kh, initial_inp_ker_overlap);
+ add(reg_kernel, jcp.typesize_out * underflow * jcp.kw * jcp.ic_block
+ * jcp.oc_block);
+ // generate loop to process kernel while it remains within t_pad + ih
+ if (kh_range < t_pad + jcp.ih) {
+ if (is_dilated) {
+ const int tail = t_pad % dilate_h;
+ const int shift = tail == 0 ? 0 : dilate_h - tail;
+ mov(reg_tmp, shift);
+ if (tail != 0)
+ add(reg_input, jcp.typesize_in * shift * iw * inp_mult);
+ }
+ L(oh_tpad_label); {
+ compute_oh_step_disp();
+ add(reg_output, jcp.typesize_in * ow * jcp.oc_block);
+ if (is_dilated) {
+ inc(reg_tmp);
+ cmp(reg_tmp, dilate_h);
+ jl(oh_dilate_label_shift, T_NEAR);
+ // unshift input as new kernel element enters
+ sub(reg_input, jcp.typesize_in * (dilate_h - 1) * iw * inp_mult);
+ xor_(reg_tmp, reg_tmp);
+ }
+ // kernel overlap only changes when (t_pad + oj) % dilate_h == 0
+ sub(reg_kernel, jcp.typesize_out * stride_h * jcp.kw
+ * jcp.ic_block * jcp.oc_block);
+ add(reg_kh, stride_h);
+ if (is_dilated) {
+ jmp(oh_dilate_label_noshift, T_NEAR);
+ L(oh_dilate_label_shift);
+ // shift input as old kernel element progresses
+ add(reg_input, jcp.typesize_in * stride_h * iw * inp_mult);
+ L(oh_dilate_label_noshift);
+ }
+ inc(reg_oj);
+ add(reg_ih_count, stride_h);
+
+ // final number of kernel elements that overlap with input
+ const int final_inp_ker_overlap
+ = nstl::min(jcp.kh, div_up(jcp.ih, dilate_h));
+ cmp(reg_kh, final_inp_ker_overlap);
+ jl(oh_tpad_label, T_NEAR);
+ }
+ }
+ // need second loop to process kernel if it is larger than the input
+ // (does not apply to dilations as they must have unit stride)
+ if (kh_range >= jcp.ih + (t_pad % stride_h == 0 ? stride_h :
+ t_pad % stride_h)) {
+ assert(!is_dilated);
+ mov(reg_kh, jcp.ih);
+ L(oh_tpad_tail_label); {
+ compute_oh_step_disp();
+ add(reg_output, jcp.typesize_in * ow * jcp.oc_block);
+ sub(reg_kernel, jcp.typesize_out * stride_h * jcp.kw
+ * jcp.ic_block * jcp.oc_block);
+
+ inc(reg_oj);
+ add(reg_ih_count, stride_h);
+
+ cmp(reg_ih_count, nstl::min(t_pad, jcp.oh * stride_h));
+ jl(oh_tpad_tail_label, T_NEAR);
+ }
+ }
+ // correct any excess shifts to kernel and input
+ // (does not apply to dilations as they must have unit stride,
+ // kernel must fit inside input, and padding is smaller than input)
+ if (t_pad <= jcp.oh * stride_h) {
+ // kernel has moved beyond padding (adjust for stride effects)
+ if (t_pad % stride_h != 0) {
+ assert(!is_dilated);
+ int inp_corr = stride_h - t_pad % stride_h;
+ add(reg_kernel, jcp.typesize_out * inp_corr * jcp.kw
+ * jcp.ic_block * jcp.oc_block);
+ add(reg_input, jcp.typesize_in * inp_corr * iw * inp_mult);
+ }
+ } else {
+ // kernel still overlaps padding (complete reset)
+ assert(!is_dilated);
+ sub(reg_kernel, jcp.typesize_out * (t_pad - jcp.oh * stride_h)
+ * jcp.kw * jcp.ic_block * jcp.oc_block);
+ }
+ }
+
+ cmp(reg_ih_count, jcp.ihp - b_pad - (jcp.kh - 1) * dilate_h);
+ jge(oh_label_end, T_NEAR);
+ cmp(reg_oj, jcp.oh);
+ jge(oh_label, T_NEAR);
+
+ /* Compute middle block(s) */
+ mov(reg_kh, jcp.kh);
+ L(oh_label); {
+ compute_oh_step_disp();
+ add(reg_input, jcp.typesize_in * stride_h * iw * inp_mult);
+ add(reg_output, jcp.typesize_in * ow * jcp.oc_block);
+
+ inc(reg_oj);
+ add(reg_ih_count, stride_h);
+
+ cmp(reg_ih_count, jcp.ihp - b_pad - (jcp.kh - 1) * dilate_h);
+ jge(oh_label_end, T_NEAR);
+
+ cmp(reg_oj, jcp.oh);
+ jl(oh_label, T_NEAR);
+ }
+ L(oh_label_end);
+
+ /* Compute bottom edge */
+ if (b_pad > 0) {
+ cmp(reg_oj, jcp.oh);
+ jge(oh_bpad_label_end, T_NEAR);
+
+ if (is_dilated) {
+ mov(reg_kh, jcp.kh - 1); // assumes unit stride for dilations
+ mov(reg_tmp, 0);
+ } else {
+ mov(reg_kh, jcp.ihp - b_pad);
+ sub(reg_kh, reg_ih_count);
+ }
+ L(oh_bpad_label);
+ {
+ compute_oh_step_disp();
+ add(reg_input, jcp.typesize_in * stride_h * iw * inp_mult);
+ add(reg_output, jcp.typesize_in * ow * jcp.oc_block);
+ if (is_dilated) {
+ inc(reg_tmp);
+ cmp(reg_tmp, dilate_h);
+ jl(oh_dilate_label_end, T_NEAR);
+ xor_(reg_tmp, reg_tmp);
+ }
+ sub(reg_kh, stride_h);
+ cmp(reg_kh, 0);
+ jle(oh_bpad_label_end, T_NEAR);
+ if (is_dilated)
+ L(oh_dilate_label_end);
+
+ inc(reg_oj);
+ cmp(reg_oj, jcp.oh);
+ jl(oh_bpad_label, T_NEAR);
+ }
+ L(oh_bpad_label_end);
+ }
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::compute_d_loop_common() {
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ const int inp_mult = jcp.is_1stconv ? 1 : jcp.ic_block;
+ int iw = jcp.ver == ver_4fma ? jcp.tr_iw : jcp.iw;
+ int ow = jcp.ow;
+ const int input_backpad_overlap
+ = div_up(jcp.id + jcp.f_pad - (jcp.kd - 1), jcp.stride_d);
+
+ const size_t filter_shift
+ = jcp.typesize_out * jcp.kh * jcp.kw * ic_block * oc_block;
+ const size_t input_shift = jcp.typesize_in * jcp.ih * iw * inp_mult;
+ const size_t output_shift = jcp.typesize_in * jcp.oh * ow * jcp.oc_block;
+
+ Label d_loop_label, loop_end_label, common_block_label, fpad_end_label,
+ backpad_end_label, backpad_label;
+
+ if (jcp.with_bias) bias_kernel();
+
+ /* initially offset 'kd' by f_pad */
+ add(reg_kernel, ptr[param + GET_OFF(kd_offset)]);
+
+ mov(reg_input_d, ptr[param + GET_OFF(src)]);
+ mov(reg_output_d, ptr[param + GET_OFF(dst)]);
+ mov(reg_d_index, ptr[param + GET_OFF(d_index)]);
+ mov(reg_kd_count, ptr[param + GET_OFF(kd_padding)]);
+
+ cmp(reg_d_index, ptr[param + GET_OFF(d_worksize)]);
+ jge(loop_end_label, T_NEAR);
+
+ L(d_loop_label);
+
+ mov(reg_input, reg_input_d);
+ mov(reg_output, reg_output_d);
+
+ push(reg_input_d);
+ push(reg_output_d);
+ push(reg_d_index);
+
+ compute_oh_loop_common();
+
+ pop(reg_d_index);
+ pop(reg_output_d);
+ pop(reg_input_d);
+
+ /* Compute 'front' edge */
+ if (jcp.f_pad > 0) {
+
+ /* Check if within fpad region */
+ cmp(reg_d_index, div_up(jcp.f_pad, jcp.stride_d));
+ jge(fpad_end_label, T_NEAR);
+
+ /* Fpad steps */
+ sub(reg_kernel, filter_shift * jcp.stride_d);
+ add(reg_kd_count, jcp.stride_d);
+
+ /* Final number of kernel elements that overlap with input */
+ const int inp_ker_overlap = nstl::min(jcp.kd, jcp.id);
+ cmp(reg_kd_count, inp_ker_overlap);
+ jl(common_block_label, T_NEAR);
+
+ /* Correct any excess shifts to kernel and input */
+ if (jcp.f_pad <= jcp.od * jcp.stride_d) {
+ /* Filter has moved beyond padding (adjust for stride effects) */
+ if (jcp.f_pad % jcp.stride_d != 0) {
+ int inp_corr = jcp.stride_d - jcp.f_pad % jcp.stride_d;
+ add(reg_kernel, filter_shift * inp_corr);
+ add(reg_input_d, input_shift * inp_corr);
+ }
+ } else {
+ /* Filter still overlaps padding (complete reset) */
+ sub(reg_kernel, (jcp.f_pad - jcp.od * jcp.stride_d) * filter_shift);
+ }
+
+ /* Apply correction */
+ mov(reg_kd_count, jcp.kd);
+ jmp(common_block_label);
+
+ L(fpad_end_label);
+ }
+
+ /* Compute bottom edge */
+ if (jcp.back_pad > 0) {
+
+ /* Check if within back_pad region */
+ cmp(reg_d_index, input_backpad_overlap - 1);
+ jl(backpad_end_label, T_NEAR);
+ jg(backpad_label, T_NEAR);
+
+ /* Execute overlap correction between the filter and the initial
+ * back_pad region. */
+ mov(reg_kd_count,
+ jcp.id + jcp.f_pad - input_backpad_overlap * jcp.stride_d);
+ jmp(backpad_end_label, T_NEAR);
+
+ L(backpad_label);
+ sub(reg_kd_count, jcp.stride_d);
+ cmp(reg_kd_count, 0);
+ jle(loop_end_label, T_NEAR);
+
+ L(backpad_end_label);
+ }
+
+ /* Compute middle block */
+ add(reg_input_d, input_shift * jcp.stride_d);
+
+ /* Execute common block and loop */
+ L(common_block_label);
+ add(reg_output_d, output_shift);
+ inc(reg_d_index);
+ cmp(reg_d_index, ptr[param + GET_OFF(d_worksize)]);
+ jl(d_loop_label, T_NEAR);
+
+ L(loop_end_label);
+}
+
+bool jit_avx512_common_conv_bwd_weights_kernel_f32::compute_full_spat_loop() {
+ // FIXME: use register mapping from the class declaration
+ bool ok = jcp.ver == ver_4fma
+ && everyone_is(0, jcp.dilate_h, jcp.dilate_w)
+ && everyone_is(1, jcp.stride_h, jcp.stride_w);
+ if (!ok) return false;
+ if (jcp.l_pad != jcp.kw / 2 || jcp.t_pad != jcp.kh / 2)
+ return false;
+
+ // General code layout:
+ //
+ // Blocking over OH -- top level
+ // (Reduces L2 pressure; not very useful right now)
+ // Loop over all KHxKW kernel -- emit_kh_kw_loop()
+ // Loop over OH block -- emit_h_loop()
+ // Loop over OW blocks -- emit_fma_block()
+ // (Supports both fully unrolled and partially unrolled versions to
+ // reduce code size)
+ // Loop over OW block -- emit_fma_step()
+
+ int max_working_set_size = 128 * 1024;
+ int pad_ow = jcp.ow;
+
+ int inp_row_size = jcp.ic_block * jcp.tr_iw * jcp.typesize_in;
+ int out_row_size = jcp.oc_block * pad_ow * jcp.typesize_in;
+ int row_size = inp_row_size + out_row_size;
+
+ int h_block_size = jcp.oh;
+ int working_set_size = row_size * h_block_size;
+
+ if (working_set_size > max_working_set_size) {
+ int opt_working_set_size = 48 * 1024;
+ assert(opt_working_set_size < max_working_set_size);
+
+ while (working_set_size > opt_working_set_size) {
+ for (int i = 2; i <= h_block_size; i++)
+ if (i == h_block_size)
+ h_block_size = h_block_size / 2;
+ else if (h_block_size % i == 0) {
+ h_block_size = h_block_size / i;
+ break;
+ }
+ working_set_size = row_size * h_block_size;
+
+ if (h_block_size == 1 && working_set_size > opt_working_set_size)
+ return false;
+ }
+ }
+
+ // NB1: t_pad <= oh_block_size and b_pad <= last_oh_block_size (see below)
+ if (h_block_size < nstl::max(1, jcp.t_pad)
+ || jcp.b_pad > (jcp.oh % h_block_size == 0 ? h_block_size
+ : jcp.oh % h_block_size))
+ return false;
+
+ // check that we can use simple arithmetic for prefetch address
+ // calculations
+ // TODO: we need some traits for this check (Roma)
+ int cache_line_size = 64;
+ assert(jcp.ic_block * typesize == 64);
+ assert(jcp.oc_block * typesize == 64);
+
+ int num_inp_l2_pfs = jcp.tr_iw * h_block_size;
+ int avg_h_loop_len = h_block_size;
+ int num_inp_l2_pfs_per_fma_block
+ = div_up(num_inp_l2_pfs, avg_h_loop_len * jcp.kw * jcp.kh);
+ int num_out_l2_pfs = pad_ow * h_block_size;
+ int num_out_l2_pfs_per_fma_block
+ = div_up(num_out_l2_pfs, avg_h_loop_len * jcp.kw * jcp.kh);
+
+ Opmask reg_h_block = k1; // 32-bit only on Intel(R) Xeon Phi(TM) processors
+ Reg64 reg_kh = rax;
+ Reg64 reg_kw = rbx;
+ Reg64 reg_tmp = abi_not_param1;
+ Reg32 reg_tmp_w = reg_tmp.cvt32();
+ Reg64 reg_ohs = rdx;
+ Reg64 reg_ihs = rsi;
+ Reg64 reg_h = r8;
+ Reg64 reg_i = r9;
+ Reg64 reg_j = r10;
+
+ Reg64 reg_inp = r13;
+ Reg64 reg_out = r14;
+ Reg64 reg_ker = r15;
+
+ Reg64 reg_inp_pf_l1 = rbp;
+
+ Reg64 reg_inp_pf_l2 = r11;
+ Reg64 reg_out_pf_l2 = r12;
+
+ Xmm reg_inp_pf_save = xmm17;
+ Xmm reg_out_pf_save = xmm18;
+
+ Reg64 reg_inp_save = abi_param1;
+ Reg64 reg_out_save = reg_tmp;
+
+ auto zmm_out = [&](int oi) { return Zmm(24 + oi % 8); };
+ auto zmm_ker = [&](int ic1) { return Zmm(ic1); };
+ auto inp_addr = [&](int oi, int ic1) {
+ return ptr[reg_inp + (ic1 * jcp.tr_iw + oi) * jcp.typesize_in];
+ };
+ auto out_addr = [&](int oi, int oj = 0) {
+ assert(jcp.ver == ver_4fma);
+ return ptr[reg_out
+ + ((oi + oj * jcp.ow) * jcp.oc_block) * jcp.typesize_in];
+ };
+ auto ker_addr = [&](int ic1) {
+ return ptr[reg_ker + ic1 * jcp.oc_block * jcp.typesize_out];
+ };
+
+ auto emit_block = [&](int h_block_size,
+ bool is_last_block, bool is_last_kh_kw_iter, bool is_last_row)
+ {
+ // TODO: add an fma version (Roma)
+ auto pad_ow = jcp.ow;
+
+ int ow4u = rnd_up(pad_ow, 4);
+ int def_step_size = 16;
+
+ bool has_w_tail = (pad_ow % def_step_size != 0
+ || pad_ow % 4 != 0);
+ bool full_w_unroll = pad_ow / def_step_size < 2 + has_w_tail;
+
+ auto emit_step = [&](int ur_ow,
+ int num_inp_l1_pfs_per_fma_step,
+ int num_inp_l2_pfs_per_fma_step,
+ int num_out_l2_pfs_per_fma_step, bool is_w_tail)
+ {
+ bool block_wraparound = is_w_tail && is_last_row;
+
+ assert(ur_ow % 4 == 0);
+ int tail_size = ow4u % ur_ow;
+ int this_ur_ow
+ = (is_w_tail && tail_size) ? tail_size : ur_ow;
+ int ow_last_chunk4 = pad_ow % 4;
+ int ow_zero_tail4 = ow_last_chunk4
+ ? 4 - ow_last_chunk4 : 0;
+
+ auto emit_out_pf = [&](int oi) {
+#if 1
+ if (oi + def_step_size < ur_ow || !block_wraparound)
+ mic_prefetcht0(ptr[reg_out
+ + ((def_step_size + oi)
+ * jcp.oc_block * jcp.typesize_in)]);
+ else {
+ assert(block_wraparound);
+ assert(oi + def_step_size >= ur_ow);
+ mic_prefetcht0(ptr[reg_out_save
+ + ((oi + def_step_size - ur_ow)
+ * jcp.oc_block * jcp.typesize_in)]);
+ }
+#else
+ // XXX: This is an alternative prefetching strategy that
+ // always prefetches the next row. Keeping it here for
+ // future experiments (Roma)
+ if (!block_wraparound)
+ mic_prefetcht0(ptr[reg_out
+ + (jcp.ow + oi) * jcp.oc_block * jcp.typesize_in]);
+ else
+ mic_prefetcht0(ptr[reg_out + reg_ohs
+ - ((h_block_size - 1) * jcp.ow
+ - oi) * jcp.oc_block * jcp.typesize_in]);
+#endif
+ if (oi < num_out_l2_pfs_per_fma_step)
+ mic_prefetcht1(ptr[reg_out_pf_l2
+ + oi * jcp.oc_block * jcp.typesize_in]);
+ };
+
+ auto emit_inp_pf = [&](int oi4, int ic1) {
+ int pf_slot_idx = ic1 + oi4 / 4 * jcp.ic_block;
+ int num_pf_slots = jcp.ic_block * ur_ow / 4;
+
+ int num_pfs = num_inp_l1_pfs_per_fma_step
+ + num_inp_l2_pfs_per_fma_step;
+ int pf_freq = nstl::max(1, num_pf_slots / num_pfs);
+
+ if (pf_slot_idx % pf_freq)
+ return;
+
+ int pf_idx = pf_slot_idx / pf_freq;
+
+ if (pf_idx < num_inp_l2_pfs_per_fma_step)
+ mic_prefetcht1(ptr[reg_inp_pf_l2
+ + pf_idx * jcp.ic_block * jcp.typesize_in]);
+ else {
+ pf_idx -= num_inp_l2_pfs_per_fma_step;
+ // prefetch the 'tail' of the cache line because most of
+ // the accesses are not aligned
+ mic_prefetcht0(ptr[reg_inp_pf_l1
+ + pf_idx * jcp.ic_block * jcp.typesize_in
+ + cache_line_size - jcp.typesize_in]);
+ }
+ };
+
+ auto numloads = 4;
+
+ int steps = this_ur_ow;
+ for (int oi4 = 0; oi4 < steps; oi4 += numloads) {
+ for (int oi1 = 0; oi1 < numloads; oi1++) {
+ int oi = oi4 + oi1;
+ if (!is_w_tail || oi < (this_ur_ow - ow_zero_tail4)) {
+ vmovups(zmm_out(oi), out_addr(oi));
+ emit_out_pf(oi);
+ } else {
+ auto zmm = zmm_out(oi);
+ vpxord(zmm, zmm, zmm);
+ }
+ }
+
+ for (int ic1 = 0; ic1 < jcp.ic_block; ic1++) {
+ if (jcp.ver == ver_4fma) {
+ v4fmaddps(zmm_ker(ic1),
+ zmm_out(oi4), inp_addr(oi4, ic1));
+ } else {
+ assert(!"unknown convolution version");
+ }
+ emit_inp_pf(oi4, ic1);
+ }
+ }
+ };
+
+ // Input is transposed and padded but we only access about jcp.iw
+ // elements so use that to compute the # of cache lines in each 'row'
+ int num_inp_l1_pfs
+ = div_up(jcp.iw * jcp.typesize_in, cache_line_size) * jcp.ic_block;
+
+ if (full_w_unroll) {
+ emit_step(ow4u, num_inp_l1_pfs,
+ num_inp_l2_pfs_per_fma_block,
+ num_out_l2_pfs_per_fma_block, true);
+ add(reg_inp_pf_l2, num_inp_l2_pfs_per_fma_block * cache_line_size);
+ add(reg_out_pf_l2, num_out_l2_pfs_per_fma_block * cache_line_size);
+ } else {
+ Label w_loop;
+ int num_w_iters = pad_ow / def_step_size;
+ int num_w_iters_full = num_w_iters + has_w_tail;
+ int num_inp_l1_pfs_per_fma_step
+ = div_up(num_inp_l1_pfs, num_w_iters_full);
+ int num_inp_l2_pfs_per_fma_step
+ = div_up(num_inp_l2_pfs_per_fma_block, num_w_iters_full);
+ int num_out_l2_pfs_per_fma_step
+ = div_up(num_out_l2_pfs_per_fma_block, num_w_iters_full);
+ mov(reg_i, num_w_iters);
+ L(w_loop); {
+ emit_step(def_step_size, num_inp_l1_pfs_per_fma_step,
+ num_inp_l2_pfs_per_fma_step,
+ num_out_l2_pfs_per_fma_step, false);
+ add(reg_inp, def_step_size * jcp.typesize_in);
+ add(reg_out, def_step_size * jcp.oc_block * jcp.typesize_in);
+ add(reg_inp_pf_l1,
+ num_inp_l1_pfs_per_fma_step * cache_line_size);
+ add(reg_inp_pf_l2,
+ num_inp_l2_pfs_per_fma_step * cache_line_size);
+ add(reg_out_pf_l2,
+ num_out_l2_pfs_per_fma_step * cache_line_size);
+ sub(reg_i, 1);
+ jnz(w_loop);
+ }
+ if (has_w_tail) {
+ emit_step(def_step_size, num_inp_l1_pfs_per_fma_step,
+ num_inp_l2_pfs_per_fma_step,
+ num_out_l2_pfs_per_fma_step, true);
+ add(reg_inp_pf_l2,
+ num_inp_l2_pfs_per_fma_step * cache_line_size);
+ add(reg_out_pf_l2,
+ num_out_l2_pfs_per_fma_step * cache_line_size);
+ }
+ // reset reg_inp and reg_out because emit_h_loop expects
+ // unmodified pointers
+ int w_offset = num_w_iters * def_step_size;
+ sub(reg_inp, w_offset * jcp.typesize_in);
+ sub(reg_out, w_offset * jcp.oc_block * jcp.typesize_in);
+ }
+ };
+
+ auto emit_h_loop = [&](int h_block_size,
+ bool is_last_block, bool is_last_kh_kw_iter)
+ {
+ Label h_loop, skip_h_loop;
+ mov(reg_j, 1);
+ cmp(reg_j, reg_h);
+ je(skip_h_loop, T_NEAR);
+ L(h_loop); {
+
+ lea(reg_inp_pf_l1,
+ ptr[reg_inp + jcp.tr_iw * jcp.ic_block * jcp.typesize_in]);
+ emit_block(h_block_size,
+ is_last_block, is_last_kh_kw_iter, false);
+
+ add(reg_inp, jcp.tr_iw * jcp.ic_block * jcp.typesize_in);
+ add(reg_out, pad_ow * jcp.oc_block * jcp.typesize_in);
+ add(reg_j, 1);
+ cmp(reg_j, reg_h);
+ jb(h_loop);
+ }
+
+ L(skip_h_loop);
+
+ for (int ic1 = 0; ic1 < jcp.ic_block; ic1++)
+ mic_prefetcht0(ker_addr(ic1));
+
+ lea(reg_inp_pf_l1, ptr[reg_inp_save + reg_kw * jcp.typesize_in]);
+ emit_block(h_block_size, is_last_block, is_last_kh_kw_iter, true);
+ };
+
+ auto emit_kh_kw_loop = [&](bool is_first_block, bool is_last_block,
+ int h_block_size)
+ {
+ xor_(reg_kh, reg_kh);
+ Label kh_loop, kh_loop_end;
+
+ int last_oh_block_size
+ = jcp.oh - rnd_up(jcp.oh - h_block_size, h_block_size);
+ int oh_block_size = (is_last_block) ? last_oh_block_size : h_block_size;
+ // NB1: t_pad <= oh_block_size and b_pad <= last_oh_block_size
+ int ih_block_size = oh_block_size - 1 + jcp.kh
+ - is_first_block * jcp.t_pad - is_last_block * jcp.b_pad;
+
+ L(kh_loop); {
+ // determine starting indices for this block
+ if (is_first_block) {
+ xor_(reg_tmp, reg_tmp);
+ mov(reg_ohs, jcp.t_pad);
+ sub(reg_ohs, reg_kh);
+ cmovb(reg_ohs, reg_tmp);
+
+ mov(reg_ihs, reg_ohs);
+ sub(reg_ihs, jcp.t_pad);
+ add(reg_ihs, reg_kh);
+ } else {
+ xor_(reg_ohs, reg_ohs);
+ mov(reg_ihs, reg_kh);
+ }
+
+ // determine effective size of block based on padding
+ mov(reg_tmp, oh_block_size);
+ sub(reg_tmp, reg_ohs);
+ mov(reg_h, ih_block_size);
+ sub(reg_h, reg_ihs);
+ cmp(reg_tmp, reg_h);
+ cmovb(reg_h, reg_tmp);
+
+ Label kh_loop_work;
+ cmp(reg_h, 0);
+ jg(kh_loop_work, T_NEAR);
+
+ // empty h loop for this jcp.kh:
+ // - set the output to 0 if necessary
+ // - move ker pt
+ // - jump to the end
+ sub(reg_h, 1);
+ Label skip_ker_zeroing;
+
+ // The reg_ker ptr has highest bit set if the output needs to be
+ // zeroed. Those who have byte-aligned their data will suffer the
+ // consiquences :(
+ // TODO: move the flag to a mask register? (Roma)
+ test(reg_ker, 1);
+ jz(skip_ker_zeroing, T_NEAR);
+
+ Label zeroing_loop;
+ vpxord(zmm0, zmm0, zmm0);
+ and_(reg_ker, ~1); // temporarily clear the zeroing flag
+ mov(reg_tmp, jcp.kw);
+ L(zeroing_loop); {
+ for (int ic1 = 0; ic1 < jcp.ic_block; ic1++)
+ vmovups(ker_addr(ic1), zmm0);
+ add(reg_ker, jcp.oc_block * jcp.ic_block * jcp.typesize_out);
+ sub(reg_tmp, 1);
+ jnz(zeroing_loop, T_NEAR);
+ }
+ // restore the zeroing flag (it will be cleared after the end of
+ // emit_kh_kw_loop, but we may need it until then)
+ or_(reg_ker, 1);
+ jmp(kh_loop_end, T_NEAR);
+
+ L(skip_ker_zeroing);
+ add(reg_ker, jcp.oc_block * jcp.ic_block * jcp.kw
+ * jcp.typesize_out);
+ jmp(kh_loop_end, T_NEAR);
+
+ L(kh_loop_work);
+
+ mul_by_const(reg_ihs, reg_tmp,
+ jcp.tr_iw * jcp.ic_block * jcp.typesize_in);
+ mul_by_const(reg_ohs, reg_tmp,
+ pad_ow * jcp.oc_block * jcp.typesize_in);
+
+ add(reg_inp, reg_ihs);
+ add(reg_out, reg_ohs);
+
+ Label kw_loop;
+ xor_(reg_kw, reg_kw);
+ L(kw_loop); {
+ for (int ic1 = 0; ic1 < jcp.ic_block; ic1++) {
+ auto zmm = zmm_ker(ic1);
+ vpxord(zmm, zmm, zmm);
+ mic_prefetcht1(ker_addr(ic1));
+ }
+
+ mov(reg_out_save, reg_out);
+ mov(reg_inp_save, reg_inp);
+ lea(reg_inp, ptr[reg_inp + reg_kw * jcp.typesize_in]);
+
+#if 0
+ // XXX: Generate code with special prefetches when switching
+ // blocks or at the end of the last block. Disabled to reduce
+ // code size and because there's no performance benefit (Roma)
+ Label regular_h_loop, end_h_loop;
+ cmp(reg_kw, jcp.kw - 1);
+ jne(regular_h_loop, T_NEAR);
+ cmp(reg_kh, jcp.kh - 1);
+ jne(regular_h_loop, T_NEAR);
+
+ emit_h_loop(oh_block_size, is_last_block, true);
+ jmp(end_h_loop, T_NEAR);
+
+ L(regular_h_loop);
+ emit_h_loop(oh_block_size, is_last_block, false);
+
+ L(end_h_loop);
+#else
+ emit_h_loop(oh_block_size, is_last_block, false);
+#endif
+
+ mov(reg_out, reg_out_save);
+ mov(reg_inp, reg_inp_save);
+
+ Label do_store;
+ // The reg_ker ptr has highest bit set if the output needs to
+ // be zeroed. Those who have byte-aligned their data will
+ // suffer the consiquences :(
+ mov(reg_tmp, reg_ker);
+ and_(reg_ker, ~1);
+ test(reg_tmp, 1);
+ jnz(do_store, T_NEAR);
+
+ for (int ic1 = 0; ic1 < jcp.ic_block; ic1++) {
+ auto zmm = zmm_ker(ic1);
+ if (jcp.ver == ver_4fma) {
+ vaddps(zmm, ker_addr(ic1));
+ } else {
+ assert(!"unknown convolution version");
+ }
+ }
+
+ L(do_store);
+ for (int ic1 = 0; ic1 < jcp.ic_block; ic1++) {
+ auto zmm = zmm_ker(ic1);
+ vmovups(ker_addr(ic1), zmm);
+ }
+
+ mov(reg_ker, reg_tmp);
+ add(reg_ker, jcp.ic_block * jcp.oc_block * jcp.typesize_out);
+ add(reg_kw, 1);
+ cmp(reg_kw, jcp.kw);
+ jl(kw_loop);
+ }
+
+ sub(reg_inp, reg_ihs);
+ sub(reg_out, reg_ohs);
+
+
+ L(kh_loop_end);
+ add(reg_kh, 1);
+ cmp(reg_kh, jcp.kh);
+ jl(kh_loop);
+ }
+ };
+
+ mov(reg_inp, ptr[param + GET_OFF(src)]);
+ mov(reg_out, ptr[param + GET_OFF(dst)]);
+ mov(reg_ker, ptr[param + GET_OFF(filt)]);
+ mov(reg_inp_pf_l2, ptr[param + GET_OFF(src_prf)]);
+ mov(reg_out_pf_l2, ptr[param + GET_OFF(dst_prf)]);
+ mov(reg_tmp, ptr[param + GET_OFF(channel)]);
+ or_(reg_ker, reg_tmp);
+
+ bool single_kh_kw_loop = (h_block_size == jcp.oh);
+
+ size_t inp_row_step = jcp.tr_iw * jcp.ic_block * jcp.typesize_in;
+ size_t first_inp_block_step = inp_row_step * (h_block_size - jcp.t_pad);
+ size_t inp_block_step = inp_row_step * h_block_size;
+ size_t out_block_step = pad_ow * jcp.oc_block * jcp.typesize_in
+ * h_block_size;
+
+ if (!single_kh_kw_loop) {
+ // Save the original prefetch pointers from the OpenMP driver
+ vmovq(reg_inp_pf_save, reg_inp_pf_l2);
+ vmovq(reg_out_pf_save, reg_out_pf_l2);
+ mov(reg_inp_pf_l2, reg_inp);
+ add(reg_inp_pf_l2, first_inp_block_step);
+ mov(reg_out_pf_l2, reg_out);
+ add(reg_out_pf_l2, out_block_step);
+ }
+ emit_kh_kw_loop(true, single_kh_kw_loop, h_block_size);
+
+ if (!single_kh_kw_loop) {
+ size_t ker_reset_offset
+ = jcp.oc_block * jcp.ic_block * jcp.typesize_out * jcp.kw * jcp.kh;
+ sub(reg_ker, ker_reset_offset);
+ and_(reg_ker, ~1); // Clear the zeroing flag for subsequent updates
+
+ add(reg_inp, first_inp_block_step);
+ add(reg_out, out_block_step);
+ mov(reg_inp_pf_l2, reg_inp);
+ add(reg_inp_pf_l2, inp_block_step);
+ mov(reg_out_pf_l2, reg_out);
+ add(reg_out_pf_l2, out_block_step);
+
+ int num_innermost_iters = div_up(jcp.oh, h_block_size) - 2;
+ if (num_innermost_iters > 0) {
+ Label h_block_loop;
+
+ mov(reg_tmp_w, num_innermost_iters);
+ kmovw(reg_h_block, reg_tmp_w);
+ L(h_block_loop); {
+ emit_kh_kw_loop(false, false, h_block_size);
+ sub(reg_ker, ker_reset_offset);
+ add(reg_inp, inp_row_step * h_block_size);
+ add(reg_out, out_block_step);
+ mov(reg_inp_pf_l2, reg_inp);
+ add(reg_inp_pf_l2, inp_block_step);
+ mov(reg_out_pf_l2, reg_out);
+ add(reg_out_pf_l2, out_block_step);
+ kmovw(reg_tmp_w, reg_h_block);
+ sub(reg_tmp_w, 1);
+ kmovw(reg_h_block, reg_tmp_w);
+ jnz(h_block_loop);
+ }
+ }
+
+ // Restore the original prefetch pointers that came from the OpenMP
+ // driver
+ vmovq(reg_inp_pf_l2, reg_inp_pf_save);
+ vmovq(reg_out_pf_l2, reg_out_pf_save);
+ emit_kh_kw_loop(false, true, h_block_size);
+ }
+
+ return true;
+}
+
+bool jit_avx512_common_conv_bwd_weights_kernel_f32
+ ::flat_4ops_compute() {
+ const auto &j = jcp;
+ const bool ok = j.ver == ver_4fma && j.is_1stconv
+ && everyone_is(0, j.dilate_h, j.dilate_w);
+ if (!ok) return false;
+
+ Reg64 reg_ptr_tr_src = r8;
+ Reg64 reg_ptr_dst = r9;
+ Reg64 reg_ptr_wei = r10;
+ Reg64 reg_ptr_bia = r11;
+
+ Reg64 reg_kh_step = rax;
+ Reg64 reg_oh = abi_not_param1;
+ Reg64 reg_kh = rdx;
+
+ Reg32 reg_flag_save = ebx;
+ Reg32 reg_flag = esi;
+
+ Zmm vbia(31);
+
+ auto zmm_wei = [&](int kh, int kw) {
+ return Zmm(8 + kh * j.kw + kw);
+ };
+ auto zmm_dst = [&](int ow) {
+ return Zmm(ow % 8);
+ };
+
+ auto addr_tr_src = [&](int kh, int iw) {
+ return ptr[reg_ptr_tr_src
+ + (kh * j.stride_w * j.tr_ld + iw) * jcp.typesize_in];
+ };
+ auto addr_dst = [&](int ow) {
+ return ptr[reg_ptr_dst + ow * jcp.oc_block * jcp.typesize_in];
+ };
+ auto addr_wei = [&](int kh, int kw) {
+ return ptr[reg_ptr_wei + (kh * j.kw + kw) * j.oc_block
+ * jcp.typesize_out];
+ };
+
+ auto emit_fma_block = [&](int kh_step) {
+ for (int kh = 0; kh < kh_step; ++kh) {
+ for (int kw = 0; kw < j.kw; ++kw) {
+ auto vwei = zmm_wei(kh, kw);
+ vpxord(vwei, vwei, vwei);
+ }
+ }
+
+ for (int ow = 0; ow < j.ow; ow += 4) {
+ for (int _ow = ow; _ow < ow + 4; ++_ow) {
+ auto vdst = zmm_dst(_ow);
+ if (_ow < j.ow)
+ vmovups(vdst, addr_dst(_ow));
+ else
+ vpxord(vdst, vdst, vdst);
+ }
+
+ for (int kh = 0; kh < kh_step; ++kh) {
+ for (int kw = 0; kw < j.kw; ++kw) {
+ const int iw = ow + (kw % j.stride_w) * j.tr_ld
+ + (kw / j.stride_w);
+ v4fmaddps(zmm_wei(kh, kw), zmm_dst(ow),
+ addr_tr_src(kh, iw));
+ if (1 && kh == 0 && kw < 4) {
+ prefetcht1(ptr[reg_ptr_dst
+ + (j.ow + ow + kw) * jcp.oc_block
+ * jcp.typesize_in]);
+ }
+ if (j.with_bias && kh_step == 1) { /* [bwd_w:b:r1] */
+ const int off = kw + 4 - j.kw;
+ if (off >= 0 && ow + off < j.ow)
+ vaddps(vbia, vbia, zmm_dst(ow + off));
+ }
+ }
+ }
+ }
+
+ Label l_store;
+ test(reg_flag, FLAG_MB_FIRST);
+ jnz(l_store, T_NEAR);
+ for (int kh = 0; kh < kh_step; ++kh) {
+ for (int kw = 0; kw < j.kw; ++kw)
+ vaddps(zmm_wei(kh, kw), addr_wei(kh, kw));
+ }
+ L(l_store);
+ for (int kh = 0; kh < kh_step; ++kh) {
+ for (int kw = 0; kw < j.kw; ++kw)
+ vmovups(addr_wei(kh, kw), zmm_wei(kh, kw));
+ }
+ };
+
+ auto emit_kh_loop = [&]() {
+ const int kh_step_rem = j.kh % j.kh_step;
+ xor_(reg_kh, reg_kh);
+ mov(reg_kh_step, j.kh_step);
+
+ Label l_kh_loop;
+ L(l_kh_loop); {
+ Label l_done;
+
+ if (kh_step_rem != 0) {
+ Label l_keep_kh_step;
+ cmp(reg_kh, j.kh - j.kh_step);
+ jle(l_keep_kh_step, T_NEAR);
+
+ mov(reg_kh_step, kh_step_rem);
+ emit_fma_block(kh_step_rem);
+ jmp(l_done, T_NEAR);
+
+ L(l_keep_kh_step);
+ }
+
+ emit_fma_block(j.kh_step);
+
+ L(l_done);
+
+ add(reg_ptr_tr_src, j.kh_step * j.stride_w * j.tr_ld
+ * jcp.typesize_in);
+ add(reg_ptr_wei, j.kh_step * j.kw * j.oc_block * jcp.typesize_out);
+ add(reg_kh, j.kh_step);
+
+ cmp(reg_kh, j.kh);
+ jl(l_kh_loop, T_NEAR);
+ }
+
+ const int kh_steps = rnd_up(j.kh, j.kh_step);
+ sub(reg_ptr_tr_src, kh_steps * j.stride_w * j.tr_ld * jcp.typesize_in);
+ sub(reg_ptr_wei, kh_steps * j.kw * j.oc_block * jcp.typesize_out);
+ };
+
+ auto emit_oh_loop = [&]() {
+ mov(reg_oh, j.oh);
+
+ Label l_oh_loop;
+ L(l_oh_loop); {
+ Label l_restore_mb_flag, l_jump;
+
+ cmp(reg_oh, j.oh);
+ je(l_restore_mb_flag, T_NEAR);
+
+ and_(reg_flag, ~FLAG_MB_FIRST);
+ jmp(l_jump, T_NEAR);
+
+ L(l_restore_mb_flag);
+ mov(reg_flag, reg_flag_save);
+
+ L(l_jump);
+
+ emit_kh_loop();
+
+ add(reg_ptr_tr_src, j.stride_h * j.stride_w * j.tr_ld
+ * jcp.typesize_in);
+ add(reg_ptr_dst, j.ow * j.oc_block * jcp.typesize_in);
+
+ dec(reg_oh);
+ jnz(l_oh_loop, T_NEAR);
+ }
+ };
+
+ auto emit_bia_store = [&]() {
+ if (!j.with_bias) return;
+
+ Label l_bia_store, l_bia_skip;
+ test(reg_flag, FLAG_IC_FIRST);
+ jz(l_bia_skip);
+
+ test(reg_flag, FLAG_MB_FIRST);
+ jnz(l_bia_store, T_NEAR);
+ vaddps(vbia, ptr[reg_ptr_bia]);
+ L(l_bia_store);
+ vmovups(ptr[reg_ptr_bia], vbia);
+ L(l_bia_skip);
+ };
+
+ mov(reg_ptr_tr_src, ptr[param + GET_OFF(src)]);
+ mov(reg_ptr_dst, ptr[param + GET_OFF(dst)]);
+ mov(reg_ptr_wei, ptr[param + GET_OFF(filt)]);
+ mov(reg_ptr_bia, ptr[param + GET_OFF(bias)]);
+ mov(reg_flag_save, ptr[param + GET_OFF(flags)]);
+
+ vpxord(vbia, vbia, vbia);
+ emit_oh_loop();
+ emit_bia_store();
+
+ return true;
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::compute_loop()
+{
+ if (flat_4ops_compute())
+ return;
+ if (compute_full_spat_loop())
+ return;
+
+ maybe_zero_kernel();
+
+ if (jcp.ndims == 5) compute_d_loop_common();
+ else compute_oh_loop_common();
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::generate()
+{
+ preamble();
+
+ mov(reg_input, ptr[param + GET_OFF(src)]);
+ mov(reg_output, ptr[param + GET_OFF(dst)]);
+ mov(reg_kernel, ptr[param + GET_OFF(filt)]);
+
+ compute_loop();
+
+ postamble();
+}
+
+status_t jit_avx512_common_conv_bwd_weights_kernel_f32::init_conf(
+ jit_conv_conf_t &jcp, const convolution_desc_t &cd,
+ memory_desc_t &src_md, memory_desc_t &diff_weights_md,
+ memory_desc_t &diff_bias_md, memory_desc_t &diff_dst_md) {
+ if (!mayiuse(avx512_common))
+ return status::unimplemented;
+
+ const memory_desc_wrapper src_d(&src_md);
+ const memory_desc_wrapper diff_weights_d(&diff_weights_md);
+ const memory_desc_wrapper diff_bias_d(&diff_bias_md);
+ const memory_desc_wrapper diff_dst_d(&diff_dst_md);
+
+ const bool with_groups = diff_weights_d.ndims() == src_d.ndims() + 1;
+ int ndims = src_d.ndims();
+
+ jcp = zero<decltype(jcp)>();
+
+ jcp.simd_w = cpu_isa_traits<avx512_common>::vlen / sizeof(float);
+ jcp.ndims = ndims;
+ jcp.prop_kind = cd.prop_kind;
+
+ jcp.ngroups = with_groups ? diff_weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+
+ jcp.oc = diff_dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+
+ jcp.id = (ndims == 5) ? src_d.dims()[2] : 1;
+ jcp.ih = (ndims == 3) ? 1 : src_d.dims()[ndims-2];
+ jcp.iw = src_d.dims()[ndims-1];
+ jcp.od = (ndims == 5) ? diff_dst_d.dims()[2] : 1;
+ jcp.oh = (ndims == 3) ? 1 : diff_dst_d.dims()[ndims-2];
+ jcp.ow = diff_dst_d.dims()[ndims-1];
+
+ jcp.kd = (ndims == 5) ? diff_weights_d.dims()[with_groups + 2] : 1;
+ jcp.kh = (ndims == 3) ? 1 : diff_weights_d.dims()[with_groups + ndims-2];
+ jcp.kw = diff_weights_d.dims()[with_groups + ndims-1];
+
+ jcp.f_pad = (ndims == 5) ? cd.padding[0][0] : 0;
+ jcp.t_pad = (ndims == 3) ? 0 : cd.padding[0][ndims-4];
+ jcp.l_pad = cd.padding[0][ndims-3];
+
+ jcp.stride_d = (ndims == 5) ? cd.strides[0] : 1;
+ jcp.stride_h = (ndims == 3) ? 1 : cd.strides[ndims-4];
+ jcp.stride_w = cd.strides[ndims-3];
+
+ jcp.dilate_d = (ndims == 5) ? cd.dilates[0] : 0;
+ jcp.dilate_h = (ndims == 3) ? 0 : cd.dilates[ndims-4];
+ jcp.dilate_w = cd.dilates[ndims-3];
+
+ const int kh_range = 1 + (jcp.kh - 1) * (jcp.dilate_h + 1);
+ bool ok = true
+ // general condition to simplify dilations
+ && IMPLICATION(jcp.dilate_d != 0, jcp.stride_d == 1)
+ && IMPLICATION(jcp.dilate_h != 0, jcp.stride_h == 1)
+ && IMPLICATION(jcp.dilate_w != 0, jcp.stride_w == 1)
+ // special condition to simplify dilations in compute_oh_loop_common
+ && IMPLICATION(jcp.dilate_h != 0, kh_range <= jcp.ih);
+ if (!ok)
+ return status::unimplemented;
+
+ jcp.r_pad = nstl::max(0, (jcp.ow - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1) - (jcp.iw + jcp.l_pad - 1));
+ jcp.b_pad = nstl::max(0, (jcp.oh - 1) * jcp.stride_h
+ + (jcp.kh - 1) * (jcp.dilate_h + 1) - (jcp.ih + jcp.t_pad - 1));
+ jcp.back_pad = nstl::max(0, (jcp.od - 1) * jcp.stride_d
+ + (jcp.kd - 1) * (jcp.dilate_d + 1) - (jcp.id + jcp.f_pad - 1));
+
+ /* XXX: currently, does not support dilation_d > 0 */
+ if (ndims == 5)
+ if (jcp.dilate_d > 0)
+ return status::unimplemented;
+
+ jcp.ihp = jcp.ih + jcp.t_pad + jcp.b_pad;
+ jcp.iwp = jcp.iw + jcp.l_pad + jcp.r_pad;
+ jcp.ohp = jcp.oh;
+ jcp.owp = jcp.ow;
+ jcp.aligned_threads = 0;
+
+ /* check for the 1st convolution */
+ jcp.is_1stconv = is_1stconv(jcp);
+
+ jcp.oc_block = jcp.simd_w;
+
+ bool ok_to_pad_channels = true
+ && jcp.ngroups == 1
+ && src_d.data_type() == data_type::f32;
+
+ if (ok_to_pad_channels)
+ jcp.oc = rnd_up(jcp.oc, jcp.simd_w);
+
+ if (jcp.oc % jcp.oc_block)
+ return status::unimplemented;
+
+ auto dst_tag = pick(ndims - 3, nCw16c, nChw16c, nCdhw16c);
+ auto wei_tag = with_groups
+ ? pick(ndims - 3, gOIw16i16o, gOIhw16i16o, gOIdhw16i16o)
+ : pick(ndims - 3, OIw16i16o, OIhw16i16o, OIdhw16i16o);
+
+ if (diff_dst_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(diff_dst_md, dst_tag));
+ jcp.dst_tag = dst_tag;
+ } else {
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(dst_tag);
+ }
+ if (jcp.dst_tag != dst_tag)
+ return status::unimplemented;
+
+ /* conditions on bias memory */
+ jcp.with_bias = cd.diff_bias_desc.format_kind != format_kind::undef;
+ if (jcp.with_bias) {
+ if (diff_bias_d.format_kind() == format_kind::any)
+ CHECK(memory_desc_init_by_tag(diff_bias_md, x));
+ }
+
+ jcp.nb_oc = jcp.oc / jcp.oc_block;
+
+ /* kernel applicability check wrt boundaries
+ * the conditions are quite general across the kernels we have,
+ * but ideally the check should belong to a specific kernel... */
+ const int max_pad = ((jcp.kh - 1) * (jcp.dilate_h + 1) + 1) / 2;
+ const bool boundaries_ok = true
+ && jcp.t_pad <= max_pad
+ && jcp.b_pad <= max_pad
+ && IMPLICATION(jcp.f_pad > 0, jcp.kd < jcp.id + jcp.f_pad)
+ && jcp.f_pad < jcp.kd;
+ if (!boundaries_ok)
+ return status::unimplemented;
+
+ /* yet another common check */
+ if (jcp.kw > 14)
+ return status::unimplemented;
+
+ /* setting register strategy */
+ for (int ur_w = nstl::min(max_ur_w, jcp.ow); ur_w > 0; --ur_w) {
+ if (jcp.ow % ur_w == 0) { jcp.ur_w = ur_w; break; }
+ }
+
+ if (jcp.is_1stconv) {
+ auto src_tag = pick(ndims - 3, ncw, nchw, ncdhw);
+ if (src_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(src_md, src_tag));
+ jcp.src_tag = src_tag;
+ } else {
+ jcp.src_tag = src_d.matches_one_of_tag(src_tag);
+ if (jcp.ic == 1 && jcp.src_tag != src_tag)
+ jcp.src_tag = src_d.matches_one_of_tag(
+ pick(ndims - 3, nwc, nhwc, ndhwc));
+ }
+ if (jcp.src_tag == format_tag::undef)
+ return status::unimplemented;
+
+ const bool src_ok = true
+ && utils::everyone_is(data_type::f32,
+ src_d.data_type(), diff_weights_d.data_type(),
+ diff_dst_d.data_type())
+ && one_of(jcp.ic, 1, 2, 3)
+ && jcp.ngroups == 1;
+ if (!src_ok)
+ return status::unimplemented;
+
+ const int tr_ld = rnd_up(div_up(jcp.iw + jcp.l_pad + jcp.r_pad,
+ jcp.stride_w), 16);
+ const int kh_step = nstl::max((28 - jcp.with_bias) / jcp.kw, 1);
+ const int kh_step_rem = jcp.kh % kh_step;
+
+ const auto wei_4fma_tag = with_groups
+ ? pick(ndims - 3, gOiw16o, gOihw16o, gOidhw16o)
+ : pick(ndims - 3, Oiw16o, Oihw16o, Oidhw16o);
+
+ auto current_wei_tag = format_tag::undef;
+ if (diff_weights_d.format_kind() != format_kind::any)
+ current_wei_tag = diff_weights_d.matches_one_of_tag(wei_4fma_tag);
+
+ const bool use_4fma = true
+ && one_of(ndims, 3, 4)
+ && mayiuse(avx512_mic_4ops)
+ && mkldnn_thr_syncable()
+ && everyone_is(0, jcp.dilate_d, jcp.dilate_h, jcp.dilate_w)
+ && everyone_is(0, jcp.l_pad, jcp.r_pad, jcp.t_pad, jcp.b_pad)
+ && jcp.kw <= 28 - jcp.with_bias
+ && jcp.stride_w == 4
+ && tr_ld / jcp.simd_w <= 4 /* [bwd_w:tr_src:r1] */
+ && IMPLICATION(jcp.with_bias, kh_step_rem == 1) /* [bwd_w:b:r1] */
+ && IMPLICATION(diff_weights_d.format_kind() != format_kind::any,
+ current_wei_tag == wei_4fma_tag);
+
+ if (use_4fma) {
+ jcp.ver = ver_4fma;
+ jcp.kh_step = kh_step;
+ jcp.tr_ld = tr_ld;
+ jcp.ic_block = 1;
+ if (diff_weights_d.format_kind() == format_kind::any)
+ CHECK(memory_desc_init_by_tag(diff_weights_md, wei_4fma_tag));
+ jcp.wei_tag = wei_4fma_tag;
+ } else {
+ jcp.ver = ver_fma;
+ jcp.ic_block = jcp.ic;
+
+ wei_tag = with_groups
+ ? pick(ndims - 3, gOwi16o, gOhwi16o, gOdhwi16o)
+ : pick(ndims - 3, Owi16o, Ohwi16o, Odhwi16o);
+
+ if (diff_weights_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(diff_weights_md, wei_tag));
+ jcp.wei_tag = wei_tag;
+ } else {
+ jcp.wei_tag = diff_weights_d.matches_one_of_tag(wei_tag);
+ }
+ if (jcp.wei_tag != wei_tag)
+ return status::unimplemented;
+ }
+
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+ } else {
+ auto src_tag = pick(ndims - 3, nCw16c, nChw16c, nCdhw16c);
+ if (src_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(src_md, src_tag));
+ jcp.src_tag = src_tag;
+ } else {
+ jcp.src_tag = src_d.matches_one_of_tag(src_tag);
+ }
+ if (jcp.src_tag != src_tag)
+ return status::unimplemented;
+
+ if (diff_weights_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(diff_weights_md, wei_tag));
+ jcp.wei_tag = wei_tag;
+ } else {
+ jcp.wei_tag = diff_weights_d.matches_one_of_tag(wei_tag);
+ }
+ if (jcp.wei_tag != wei_tag)
+ return status::unimplemented;
+
+ jcp.ic_block = jcp.simd_w;
+ if (ok_to_pad_channels)
+ jcp.ic = rnd_up(jcp.ic, jcp.ic_block);
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+ if ((mayiuse(avx512_mic) || mayiuse(avx512_core))
+ && utils::everyone_is(data_type::f32,
+ src_d.data_type(), diff_weights_d.data_type(),
+ diff_dst_d.data_type())) {
+ jcp.ver = ver_fma;
+ if (one_of(ndims, 3, 4) && mayiuse(avx512_mic_4ops) && jcp.stride_w == 1 &&
+ everyone_is(0, jcp.dilate_d, jcp.dilate_h, jcp.dilate_w) &&
+ mkldnn_thr_syncable()) {
+ jcp.ver = ver_4fma;
+ }
+ } else {
+ return status::unimplemented;
+ }
+ if (jcp.ver == ver_4fma) {
+ jcp.ur_w = jcp.ow;
+ // XXX, BUGBUGBUG, but not a FIXME: this assumes that it's OK to
+ // cross the right boundary. The only requirement is not to have
+ // NaNs there because another multiplicand is always guaranteed to
+ // be zero. This also may require the top-level driver to allocate
+ // four extra guarding elements at the very end of the buffer.
+ // I'm not proud of this hack, but it improves performance by
+ // about 5-10% depending on the dimensions (Roma)
+
+ const int tr_round = 4;
+
+ jcp.tr_iw = rnd_up(jcp.iw + jcp.kw - 1, tr_round);
+ jcp.tr_src_num_guard_elems = tr_round; // upper bound
+ }
+ }
+
+ if (utils::one_of(jcp.ver, ver_4fma, ver_fma)) {
+ jcp.typesize_in = sizeof(float);
+ jcp.typesize_out = sizeof(float);
+ } else
+ return status::unimplemented;
+
+ bool args_ok = true
+ && jcp.ic % jcp.ic_block == 0
+ && jcp.oc % jcp.oc_block == 0
+ && jcp.ic <= src_d.padded_dims()[1]
+ && jcp.oc <= diff_dst_d.padded_dims()[1]
+ && jcp.ic <= diff_weights_d.padded_dims()[with_groups + 1]
+ && jcp.oc <= diff_weights_d.padded_dims()[with_groups + 0];
+ if (!args_ok) return status::unimplemented;
+
+ { // balancing
+ int nthr, nthr_mb, nthr_g, nthr_oc_b, nthr_ic_b;
+ balance(jcp, nthr, nthr_mb, nthr_g, nthr_oc_b, nthr_ic_b);
+ jcp.nthr = nthr;
+ jcp.nthr_mb = nthr_mb;
+ jcp.nthr_g = nthr_g;
+ jcp.nthr_oc_b = nthr_oc_b;
+ jcp.nthr_ic_b = nthr_ic_b;
+ }
+
+ return status::success;
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad, const jit_conv_conf_t &jcp) {
+ if (jcp.ver == ver_4fma) {
+ if (jcp.is_1stconv) {
+ const size_t tr_src_size =
+ jcp.nthr / jcp.nthr_oc_b * jcp.ih * jcp.stride_w * jcp.tr_ld;
+ scratchpad.book(key_conv_tr_src, jcp.typesize_in * tr_src_size);
+ } else {
+ // XXX: See the comment about tr_iw and guarding elements in
+ // jit_avx512_common_conv_bwd_weights_kernel_f32::init_conf()
+ const size_t max_nthr = jcp.nthr_mb * jcp.ngroups * jcp.nb_ic;
+ const size_t min_tr_src_size_per_thr
+ = jcp.ih * jcp.ic_block * jcp.tr_iw;
+ const size_t tr_src_size = max_nthr * min_tr_src_size_per_thr
+ + jcp.tr_src_num_guard_elems;
+ scratchpad.book(key_conv_tr_src, jcp.typesize_in * tr_src_size);
+ }
+
+ /* prepare synchronization contexts */
+ if (jcp.nthr_oc_b > 1) {
+ const int tr_src_bctx_size = jcp.nthr / jcp.nthr_oc_b;
+ scratchpad.book(key_conv_tr_src_bctx,
+ sizeof(simple_barrier::ctx_t) * tr_src_bctx_size);
+ }
+ }
+
+ if (jcp.nthr_mb > 1) {
+ const int wei_size = jcp.ngroups * jcp.oc * jcp.ic
+ * jcp.kh * jcp.kw * jcp.kd;
+ const int bia_size = jcp.ngroups * jcp.oc;
+ const size_t wei_bia_reduction_size = wei_size + bia_size;
+
+ scratchpad.book(key_conv_wei_bia_reduction,
+ jcp.typesize_out * wei_bia_reduction_size * (jcp.nthr_mb - 1));
+ scratchpad.book(key_conv_wei_bia_reduction_bctx,
+ sizeof(simple_barrier::ctx_t));
+ }
+
+ if (jcp.with_bias && jcp.oc != jcp.oc_without_padding)
+ scratchpad.book(key_conv_padded_bias, jcp.typesize_out * jcp.oc);
+}
+
+void jit_avx512_common_conv_bwd_weights_kernel_f32::balance(
+ const jit_conv_conf_t &j, int &nthr_, int &nthr_mb_, int &nthr_g_,
+ int &nthr_oc_b_, int &nthr_ic_b_)
+{
+ nthr_ = nthr_mb_ = nthr_g_ = nthr_oc_b_ = nthr_ic_b_ = 1;
+
+ const int max_threads = mkldnn_get_max_threads();
+
+ if (max_threads < j.ngroups) {
+ /* simplification... fortunately it doesn't hurt much */
+ return;
+ }
+
+ if (!mkldnn_thr_syncable() && j.ver == ver_4fma) {
+ // should not happen -- the driver is not ready
+ // for TBB-like non-synchronous threading yet
+ return;
+ }
+
+ if (j.ver == ver_4fma && j.is_1stconv) {
+ nthr_g_ = 1;
+ nthr_oc_b_ = 1;
+ nthr_ic_b_ = nstl::min(j.nb_ic, max_threads);
+ nthr_mb_ = nstl::min(max_threads / nthr_ic_b_, j.mb);
+ nthr_ = nthr_mb_ * nthr_oc_b_ * nthr_ic_b_ * nthr_g_;
+ return;
+ }
+
+ nthr_g_ = j.ngroups;
+ const int nthr = max_threads / nthr_g_;
+
+ auto calc_mem_cost = [=](int nthr_mb, int nthr_oc_b, int nthr_ic_b) {
+ /* calculate per thread memory cost (read/write). high level optimizer
+ * tries to minimize memory consumption. few notes:
+ * (n1) unclear why, but that essentially helps first convolution...
+ * (n2) assuming the reduction over minibatch is always there:
+ * - instead of 8 it should be 5 here (write ~= 2 read):
+ * kernel: temporal workspace 1 write
+ * reduction: 1 read from workspace and 1 write to the diff_wei
+ * - but experiments showed 8 works better than 5 or 6... */
+
+ const int src_coef = j.ver == ver_4fma ? 4 : 1;
+ const int dst_coef = 1;
+ const int wei_coef = 8;
+
+ return 0
+ + src_coef
+ * div_up(j.mb, nthr_mb) * div_up(j.ngroups, nthr_g_)
+ * div_up(j.nb_ic, nthr_ic_b) * j.ic_block * j.ih * j.iw * j.id
+ / j.stride_d / j.stride_h / j.stride_w /* (n1) */
+ + dst_coef
+ * div_up(j.mb, nthr_mb) * div_up(j.ngroups, nthr_g_)
+ * div_up(j.nb_oc, nthr_oc_b) * j.oc_block * j.oh * j.ow * j.od
+ + wei_coef /* (n2) */
+ * div_up(j.ngroups, nthr_g_)
+ * div_up(j.nb_oc, nthr_oc_b) * div_up(j.nb_ic, nthr_ic_b)
+ * j.kh * j.kw * j.kd * j.ic_block * j.oc_block;
+ };
+
+ int best_mem_cost = calc_mem_cost(nthr_mb_, nthr_oc_b_, nthr_ic_b_);
+
+ /* step 1: find the best thread distribution with lowest memory cost */
+ const int nthr_mb_max = nstl::min(nthr, j.mb * j.od);
+ for (int nthr_mb = 1; nthr_mb <= nthr_mb_max; ++nthr_mb) {
+ const int nthr_par = nthr / nthr_mb;
+ const int nthr_oc_b_max = nstl::min(nthr_par, j.nb_oc);
+ for (int nthr_oc_b = 1; nthr_oc_b <= nthr_oc_b_max; ++nthr_oc_b) {
+ int nthr_ic_b = nstl::min(nthr_par / nthr_oc_b, j.nb_ic);
+
+ int mem_cost = calc_mem_cost(nthr_mb, nthr_oc_b, nthr_ic_b);
+ if (mem_cost <= best_mem_cost) {
+ best_mem_cost = mem_cost;
+ nthr_mb_ = nthr_mb;
+ nthr_oc_b_ = nthr_oc_b;
+ nthr_ic_b_ = nthr_ic_b;
+ }
+ }
+
+ if (!mkldnn_thr_syncable()) { assert(nthr_mb == 1); break; }
+ }
+
+ if (!mayiuse(avx512_mic)) {
+ auto calc_comp_cost = [=](int nthr_mb, int nthr_oc_b, int nthr_ic_b) {
+ return 1
+ * div_up(j.mb, nthr_mb)
+ * div_up(j.ngroups, nthr_g_)
+ * div_up(j.nb_oc, nthr_oc_b)
+ * div_up(j.nb_ic, nthr_ic_b);
+ };
+
+ /* step 2: search for a thread distribution with lower compute cost.
+ * the constrains:
+ * - memory cost cannot exceed 110% of the best found in the step 1
+ * - unless compute cost is 133% lower than the current best case
+ * note: both constants were found empirically */
+ int best_comp_cost = calc_comp_cost(nthr_mb_, nthr_oc_b_, nthr_ic_b_);
+ for (int nthr_mb = 1; nthr_mb <= nthr_mb_max; ++nthr_mb) {
+ const int nthr_par = nthr / nthr_mb;
+ const int nthr_oc_b_max = nstl::min(nthr_par, j.nb_oc);
+ for (int nthr_oc_b = 1; nthr_oc_b <= nthr_oc_b_max; ++nthr_oc_b) {
+ int nthr_ic_b = nstl::min(nthr_par / nthr_oc_b, j.nb_ic);
+ int mem_cost = calc_mem_cost(nthr_mb, nthr_oc_b, nthr_ic_b);
+ int comp_cost = calc_comp_cost(nthr_mb, nthr_oc_b, nthr_ic_b);
+
+ const bool opt1 = comp_cost <= best_comp_cost
+ && mem_cost < 1.1 * best_mem_cost;
+ const bool opt2 = 4 * comp_cost <= 3 * best_comp_cost;
+
+ if (opt1 || opt2) {
+ best_comp_cost = comp_cost;
+ nthr_mb_ = nthr_mb;
+ nthr_oc_b_ = nthr_oc_b;
+ nthr_ic_b_ = nthr_ic_b;
+ }
+ }
+
+ if (!mkldnn_thr_syncable()) { assert(nthr_mb == 1); break; }
+ }
+ }
+
+ if (nthr_mb_ > max_threads/2 && nthr_mb_ < max_threads)
+ nthr_mb_ = nstl::min(j.mb * j.od, max_threads);
+ nthr_ = nthr_mb_ * nthr_g_ * nthr_oc_b_ * nthr_ic_b_;
+
+ assert(nthr_ <= max_threads);
+ assert(IMPLICATION(!mkldnn_thr_syncable(), nthr_mb_ == 1));
+}
+
+template struct _jit_avx512_common_conv_fwd_kernel<Zmm>;
+template struct _jit_avx512_common_conv_fwd_kernel<Xmm>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_kernel.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_kernel.hpp
new file mode 100644
index 0000000000..f76770797a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_kernel.hpp
@@ -0,0 +1,423 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_AVX512_COMMON_CONV_KERNEL_F32_HPP
+#define JIT_AVX512_COMMON_CONV_KERNEL_F32_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+#include "jit_uni_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template<typename Vmm>
+struct _jit_avx512_common_conv_fwd_kernel : public jit_generator {
+
+ _jit_avx512_common_conv_fwd_kernel(jit_conv_conf_t ajcp,
+ const primitive_attr_t &attr)
+ : jcp(ajcp), attr_(attr), eltwise_injector_(nullptr)
+ {
+ if (jcp.with_eltwise)
+ eltwise_injector_ = new jit_uni_eltwise_injector_f32<avx512_common>(
+ this, jcp.eltwise);
+
+ generate();
+ jit_ker_ = (void (*)(jit_conv_call_s *))getCode();
+ }
+
+ ~_jit_avx512_common_conv_fwd_kernel() {
+ delete eltwise_injector_;
+ }
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(_jit_avx512_common_conv_fwd_kernel)
+
+ jit_conv_conf_t jcp;
+ const primitive_attr_t &attr_;
+ void (*jit_ker_)(jit_conv_call_s *);
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ enum {
+ typesize = sizeof(float),
+ ker_reg_base_idx = 28,
+ };
+
+ reg64_t param = abi_param1;
+ reg64_t reg_inp = r8;
+ reg64_t reg_ker = r9;
+ reg64_t reg_out = r10;
+
+ reg64_t reg_inp_prf = r11;
+ reg64_t reg_ker_prf = r12;
+ reg64_t reg_out_prf = r13;
+ reg64_t reg_owb = r12;
+
+ reg64_t aux_reg_inp = r14;
+ reg64_t aux_reg_ker = r15;
+
+ reg64_t aux_reg_inp_prf = rsi;
+ reg64_t aux_reg_ker_prf = rdx;
+
+ reg64_t reg_channel = rsi;
+ reg64_t reg_bias = rdx;
+
+ reg64_t aux_reg_ker_d = r9;
+ reg64_t aux_reg_inp_d = rbx;
+ reg64_t aux_reg_inp_d_prf = r13;
+ reg64_t aux_reg_ker_d_prf = abi_not_param1;
+ reg64_t reg_ki = r10;
+
+ reg64_t reg_kj = rax;
+ reg64_t reg_relu_ns = rax;
+ reg64_t reg_oi = rbx;
+ reg64_t reg_kh = abi_not_param1;
+
+ reg64_t reg_tmp = rbp;
+
+ reg64_t reg_ic_loop = rdx;
+ reg64_t reg_inp_loop = rsi;
+
+ reg64_t reg_init_flag = r13;
+ reg64_t reg_bias_ptr = param;
+
+ reg64_t aux_reg_ic = r12;
+ reg64_t reg_binp = rax;
+ reg64_t reg_bout = r11;
+ reg64_t aux1_reg_inp = rbx;
+ reg64_t aux_reg_out = abi_not_param1;
+
+ reg64_t reg_long_offt = r11;
+ reg64_t reg_out_long_offt = r14;
+
+ inline Vmm vmm_ker(int i_ic) {
+ assert(i_ic < 4);
+ return Vmm(ker_reg_base_idx + i_ic);
+ }
+
+ inline Vmm vmm_out(int i_ur, int i_oc) {
+ int idx = i_ur + i_oc * jcp.ur_w;
+ assert(idx < ker_reg_base_idx);
+ return Vmm(idx);
+ }
+
+ inline Vmm vmm_inp(int i_ic, int nb_x_blocking) {
+ int idx = i_ic + nb_x_blocking * jcp.ur_w;
+ assert(idx < 31);
+ return Vmm(idx);
+ }
+
+ Xbyak::Reg64 imm_addr64 = r15;
+ Vmm vmm_wei = Vmm(31);
+
+ jit_uni_eltwise_injector_f32<avx512_common> *eltwise_injector_;
+
+ inline void prepare_output(int ur_w);
+ inline void store_output(int ur_w);
+ inline void compute_loop_fma(int ur_w, int pad_l, int pad_r);
+ inline void compute_loop_fma_core(int ur_w, int pad_l, int pad_r);
+ inline void compute_loop_4fma(int ur_w, int pad_l, int pad_r);
+ inline void compute_loop_4fma_1st(int ur_w, int pad_l, int pad_r);
+ inline void compute_loop(int ur_w, int pad_l, int pad_r);
+
+ void generate();
+
+ inline size_t get_output_offset(int oi, int n_oc_block) {
+ return (size_t)jcp.typesize_out * ((size_t)n_oc_block * jcp.oh
+ * jcp.ow * jcp.od + oi) * jcp.oc_block;
+ }
+
+ inline size_t get_input_offset(int ki, int ic, int oi, int pad_l) {
+ size_t iw_str = !jcp.is_1stconv ? jcp.ic_block : 1;
+ size_t ic_str = !jcp.is_1stconv ? 1 : (size_t)jcp.iw * jcp.ih * jcp.id;
+ return (size_t)jcp.typesize_in * ((size_t)(ki * (jcp.dilate_w + 1)
+ + oi * jcp.stride_w - pad_l) * iw_str + ic * ic_str);
+ }
+
+ inline int get_kernel_offset(int ki,int ic,int n_oc_block,int ker_number) {
+ return jcp.typesize_in * jcp.oc_block
+ * (n_oc_block * jcp.nb_ic * jcp.ic_block * jcp.kh * jcp.kw * jcp.kd
+ + (ic + ker_number) + ki * jcp.ic_block);
+ }
+
+ inline int get_ow_start(int ki, int pad_l) {
+ return nstl::max(0,
+ utils::div_up(pad_l - ki * (jcp.dilate_w + 1), jcp.stride_w));
+ }
+
+ inline int get_ow_end(int ur_w, int ki, int pad_r) {
+ return ur_w - nstl::max(0, utils::div_up(pad_r
+ - (jcp.kw - 1 - ki)
+ * (jcp.dilate_w + 1),
+ jcp.stride_w));
+ }
+};
+
+struct jit_avx512_common_conv_fwd_kernel {
+
+ jit_avx512_common_conv_fwd_kernel(jit_conv_conf_t ajcp,
+ const primitive_attr_t &attr) :
+ jit_ker(nullptr),
+ zmm_kernel_(nullptr),
+ xmm_kernel_(nullptr) {
+ int ch_block = ajcp.is_depthwise ? ajcp.ch_block : ajcp.oc_block;
+ switch (ch_block) {
+ case 16:
+ zmm_kernel_ =
+ new _jit_avx512_common_conv_fwd_kernel<Xbyak::Zmm>(
+ ajcp, attr);
+ jit_ker = zmm_kernel_->jit_ker_;
+ return;
+ case 4:
+ xmm_kernel_ =
+ new _jit_avx512_common_conv_fwd_kernel<Xbyak::Xmm>(
+ ajcp, attr);
+ jit_ker = xmm_kernel_->jit_ker_;
+ return;
+ default:
+ assert(!"invalid channel blocking");
+ }
+ }
+
+ ~jit_avx512_common_conv_fwd_kernel() {
+ delete xmm_kernel_;
+ delete zmm_kernel_;
+ }
+
+ enum {
+ typesize = sizeof(float)
+ };
+
+ static bool post_ops_ok(jit_conv_conf_t &jcp,
+ const primitive_attr_t &attr);
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd,
+ memory_desc_t &src_pd,
+ memory_desc_t &weights_pd,
+ memory_desc_t &dst_pd,
+ memory_desc_t &bias_pd,
+ const primitive_attr_t &attr,
+ int nthreads);
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_conf_t &jcp);
+
+ void(*jit_ker)(jit_conv_call_s *);
+ _jit_avx512_common_conv_fwd_kernel<Xbyak::Zmm> *zmm_kernel_;
+ _jit_avx512_common_conv_fwd_kernel<Xbyak::Xmm> *xmm_kernel_;
+};
+
+struct jit_avx512_common_conv_bwd_data_kernel_f32: public jit_generator {
+
+ jit_avx512_common_conv_bwd_data_kernel_f32(jit_conv_conf_t ajcp): jcp(ajcp)
+ {
+ generate();
+ jit_ker = (void (*)(jit_conv_call_s *))getCode();
+ }
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_common_conv_bwd_data_kernel_f32)
+
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd,
+ const memory_desc_wrapper &diff_src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &diff_dst_d);
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_conf_t &jcp);
+
+ jit_conv_conf_t jcp;
+ void (*jit_ker)(jit_conv_call_s *);
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ enum {
+ typesize = sizeof(float),
+ ker_reg_base_idx = 28,
+ };
+
+ reg64_t param = abi_param1;
+ reg64_t reg_dst = r8;
+ reg64_t reg_ker = r9;
+ reg64_t reg_src = r10;
+
+ reg64_t reg_dst_prf = r11;
+ reg64_t reg_ker_prf = r12;
+ reg64_t reg_src_prf = r13;
+
+ reg64_t aux_reg_dst = r14;
+ reg64_t aux_reg_ker = r15;
+
+ reg64_t aux_reg_dst_prf = rsi;
+ reg64_t aux_reg_ker_prf = rdx;
+
+ reg64_t aux_reg_dst_d_prf = r13;
+ reg64_t aux_reg_dst_d = rbx;
+ reg64_t aux_reg_ker_d_prf = abi_not_param1;
+ reg64_t aux_reg_ker_d = r9;
+ reg64_t reg_ki = r10;
+
+ reg64_t reg_kj = rax;
+ reg64_t reg_oi = rbx;
+ reg64_t reg_kh = abi_not_param1;
+
+ reg64_t reg_channel = rsi;
+
+ reg64_t reg_tmp = rbp;
+ reg64_t reg_long_offt = r14;
+
+ inline Xbyak::Zmm zmm_ker(int i_ic) {
+ assert(i_ic < 4);
+ return Xbyak::Zmm(ker_reg_base_idx + i_ic);
+ }
+ inline Xbyak::Zmm zmm_inp(int i_ic, int nb_x_blocking) {
+ int idx = i_ic + nb_x_blocking * jcp.ur_w;
+ assert(idx < 31);
+ return Xbyak::Zmm(idx);
+ }
+ inline Xbyak::Zmm zmm_out(int i_ur, int i_oc) {
+ int idx = i_ur + i_oc * jcp.ur_w;
+ assert(idx < ker_reg_base_idx);
+ return Xbyak::Zmm(idx);
+ }
+
+ Xbyak::Zmm zmm_wei = Xbyak::Zmm(31);
+
+ inline void prepare_output(int ur_w);
+ inline void store_output(int ur_w);
+ inline void compute_loop_4fma(int ur_w, int l_overflow, int r_overflow);
+ inline void compute_loop_fma(int ur_w, int l_overflow, int r_overflow);
+ inline void compute_loop_fma_core(int ur_w, int l_overflow, int r_overflow);
+ inline void compute_loop(int ur_w, int l_overflow, int r_overflow);
+ void generate();
+
+ inline int get_iw_start(int ki, int l_overflow)
+ {
+ int res = (jcp.iw - 1 + jcp.r_pad) % jcp.stride_w
+ + l_overflow * jcp.stride_w
+ - (jcp.kw - 1 - ki) * (jcp.dilate_w + 1);
+ while (res < 0)
+ res += jcp.stride_w;
+
+ return res;
+ }
+
+ inline int get_iw_end(int ur_w, int ki, int r_overflow)
+ {
+ if (utils::one_of(ur_w, jcp.iw, jcp.ur_w_tail))
+ ur_w += nstl::min(0, jcp.r_pad); // remove negative padding
+ int res = (ur_w - 1 + jcp.l_pad) % jcp.stride_w
+ + r_overflow * jcp.stride_w - ki * (jcp.dilate_w + 1);
+ while (res < 0)
+ res += jcp.stride_w;
+
+ return ur_w - res;
+ }
+};
+
+struct jit_avx512_common_conv_bwd_weights_kernel_f32 : public jit_generator {
+
+ jit_avx512_common_conv_bwd_weights_kernel_f32(jit_conv_conf_t ajcp)
+ : jcp(ajcp)
+ {
+ generate();
+ jit_ker = (void (*)(jit_conv_call_s *))getCode();
+ }
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_common_conv_bwd_weights_kernel_f32)
+
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd,
+ memory_desc_t &src_md,
+ memory_desc_t &diff_weights_md,
+ memory_desc_t &diff_bias_md,
+ memory_desc_t &diff_dst_md);
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_conf_t &jcp);
+
+ jit_conv_conf_t jcp;
+ void (*jit_ker)(jit_conv_call_s *);
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ enum {typesize = sizeof(float)};
+ static const int max_ur_w;
+
+ reg64_t param = abi_param1;
+ reg64_t reg_input = rax;
+ reg64_t reg_kernel = rdx;
+ reg64_t reg_output = rsi;
+ reg64_t b_ic = abi_not_param1;
+ reg64_t kj = r8;
+ reg64_t reg_kh = r9;
+ reg64_t reg_ur_w_trips = r10;
+ reg64_t reg_oj = r15;
+ reg64_t reg_ih_count = rbx;
+ reg64_t reg_tmp = r14;
+ reg64_t reg_long_offt = r14;
+
+ reg64_t ki = r11;
+ reg64_t reg_kd_count = r12;
+ reg64_t reg_oi = r12;
+ reg64_t reg_d_index = r13;
+ reg64_t reg_input_d = r15;
+ reg64_t reg_output_d = rbx;
+ reg64_t aux_reg_input = r12;
+ reg64_t aux_reg_kernel = r13;
+ reg64_t reg_bias = rbx;
+
+ inline void bias_kernel();
+ inline void maybe_zero_kernel();
+ inline void compute_oh_step_unroll_ow_icblock(int ic_block_step,
+ int max_ur_w);
+ inline void od_step_comeback_pointers();
+ inline void oh_step_comeback_pointers();
+ inline void compute_oh_step_unroll_ow(int ic_block_step, int max_ur_w);
+ inline void compute_ic_block_step(int ur_w,
+ int pad_l, int pad_r, int ic_block_step,
+ int input_offset, int kernel_offset, int output_offset,
+ bool input_wraparound = false);
+ inline void compute_ic_block_step_fma(int ur_w,
+ int pad_l, int pad_r, int ic_block_step,
+ int input_offset, int kernel_offset, int output_offset,
+ bool input_wraparound);
+ inline void compute_ic_block_step_4fma(int ur_w,
+ int pad_l, int pad_r, int ic_block_step,
+ int input_offset, int kernel_offset, int output_offset,
+ bool input_wraparound);
+ inline void compute_oh_step_common(int ic_block_step, int max_ur_w);
+ inline void compute_oh_step_disp();
+ inline void compute_oh_loop_common();
+ inline void compute_d_loop_common();
+
+ inline bool compute_full_spat_loop();
+ inline bool flat_4ops_compute();
+
+ inline void compute_loop();
+
+ void generate();
+
+ static void balance(const jit_conv_conf_t &j, int &nthr, int &nthr_mb,
+ int &nthr_g, int &nthr_oc_b, int &nthr_ic_b);
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_winograd_kernel_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_winograd_kernel_f32.cpp
new file mode 100644
index 0000000000..1bdcd0d6a8
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_winograd_kernel_f32.cpp
@@ -0,0 +1,1163 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+#include "cpu_memory.hpp"
+
+#include <math.h>
+
+#include "jit_avx512_common_conv_winograd_kernel_f32.hpp"
+
+#ifndef KERNEL_SIZE_THRESHOLD
+#define KERNEL_SIZE_THRESHOLD 16
+#endif
+
+#define MIN_REQUIRED_DIMN_REG_BLOCK 14
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace {
+
+using namespace mkldnn::impl::utils;
+
+unsigned int L1_cache_size = get_cache_size(1, true);
+unsigned int L2_cache_size = get_cache_size(2, true);
+unsigned int LLC_data_size = get_cache_size(3, false);
+
+// the test funtion takes jcp, the candidate and the current best.
+// it returns true if the new candidate is better
+int get_divisor_satisfying_cond(jit_conv_winograd_conf_t &jcp, int number,
+ int default_best, bool (*test)(jit_conv_winograd_conf_t &, int, int))
+{
+ int best_divisor = default_best;
+ auto test_num
+ = [&best_divisor, test](jit_conv_winograd_conf_t &jcp, int num) {
+ if (test(jcp, num, best_divisor)) {
+ best_divisor = num;
+ }
+ };
+
+ for (int divisor = 1; divisor <= ::sqrt(number); divisor++) {
+ if (number % divisor == 0) {
+ test_num(jcp, divisor);
+ test_num(jcp, number / divisor);
+ }
+ }
+
+ return best_divisor;
+}
+
+namespace {
+bool is_winograd_faster_than_direct(const jit_conv_winograd_conf_t &jcp) {
+ if (jcp.ver == ver_4fma)
+ return jcp.mb >= 32;
+ else
+ return jcp.mb >= 16;
+}
+}
+
+/* assumes 512 bits registers */
+/* TODO: add support for strides */
+/* TODO: handle the prefetch distance automatically */
+typedef enum cache_t_ { L1, L2, L3 } cache_t;
+
+template <typename data_t>
+struct prefetcher_t {
+ prefetcher_t(jit_generator *generator, Xbyak::Reg64 reg_base_addr,
+ cache_t cache_type, size_t block_size, /* in number of elements*/
+ int nb_instructions_in_block, int fma_ipc)
+ : cg_(generator)
+ , reg_base_addr_(reg_base_addr)
+ , cache_type_(cache_type)
+ , cache_block_size_(block_size)
+ {
+ nb_cache_lines_to_prefetch_ = cache_block_size_ / (64 / sizeof(data_t));
+ prefetch_spread_
+ = div_up(nb_instructions_in_block, nb_cache_lines_to_prefetch_);
+ prefetch_blk_
+ = div_up(nb_cache_lines_to_prefetch_, nb_instructions_in_block);
+
+ /* assumption: when fetch in Li, data is already in L(i+1) */
+ int cache_latency;
+ switch (cache_type_) {
+ case L1: cache_latency = 14; break;
+ case L2:
+ case L3:
+ default: cache_latency = 250; break;
+ }
+
+ prefetch_distance_ = div_up(cache_latency, nb_cache_lines_to_prefetch_);
+ }
+
+ void prefetch(int instruction_number)
+ {
+ if (instruction_number % prefetch_spread_ == 0) {
+ for (int i = 0; (i < prefetch_blk_)
+ && (prefetches_issued_ < nb_cache_lines_to_prefetch_);
+ i++, prefetches_issued_++) {
+ prefetch_inst_(cg_->EVEX_compress_addr(
+ reg_base_addr_, (cache_block_size_ * prefetch_distance_)
+ * sizeof(data_t)
+ + (prefetches_issued_ * 64)));
+ }
+ }
+ }
+
+private:
+ void prefetch_inst_(const Xbyak::Address &addr)
+ {
+ switch (cache_type_) {
+ case L1: cg_->prefetcht0(addr); break;
+ case L2: cg_->prefetcht1(addr); break;
+ case L3: cg_->prefetcht2(addr); break;
+ default:
+ break; // TODO: raise an exception or put an assert
+ }
+ }
+
+ jit_generator *cg_;
+ Xbyak::Reg64 reg_base_addr_;
+ cache_t cache_type_;
+ int cache_block_size_ = 0;
+ int nb_cache_lines_to_prefetch_ = 0;
+ int prefetches_issued_ = 0;
+ int prefetch_spread_ = 0;
+ int prefetch_blk_ = 0;
+ int prefetch_distance_ = 0;
+};
+
+// utilities to support kernel parameter selection
+bool check_cond1(int dimN_reg_block, int dimK_block, int dimK_reg_block,
+ int dimM_block, int dimM_simd_block, float C)
+{
+ float lhs = (dimM_block * dimN_reg_block * dimM_simd_block
+ + dimM_block * dimK_block * dimK_reg_block
+ * dimM_simd_block
+ + dimK_block * dimN_reg_block * dimK_reg_block)
+ * (float)sizeof(float);
+ float rhs = C * L1_cache_size;
+ return (lhs < rhs);
+}
+
+bool check_cond1_bis(int dimN_reg_block, int dimK_block, int dimK_reg_block,
+ int dimM_block, int dimM_simd_block, float C)
+{
+ float lhs = (dimM_block * dimK_block * dimK_reg_block * dimM_simd_block
+ + dimK_block * dimN_reg_block * dimK_reg_block)
+ * (float)sizeof(float);
+ float rhs = C * L1_cache_size;
+ return (lhs < rhs);
+}
+
+bool check_cond2(int nb_dimN_reg_block, int dimN_reg_block, int dimK_nb_block,
+ int dimK_block, int dimK_reg_block, int dimM_block, int dimM_simd_block,
+ float C)
+{
+ float lhs = (nb_dimN_reg_block * dimM_block * dimN_reg_block * dimM_simd_block
+ + dimK_nb_block * dimM_block * dimK_block * dimK_reg_block
+ * dimM_simd_block
+ + nb_dimN_reg_block * dimK_nb_block * dimK_block
+ * dimN_reg_block * dimK_reg_block)
+ * (float)sizeof(float);
+ float rhs = C * L2_cache_size;
+ return (lhs < rhs);
+}
+}
+
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::utils;
+using namespace Xbyak;
+
+void _jit_avx512_common_conv_winograd_data_kernel_f32::gemm_loop_generate(
+ bool is_beta_zero)
+{
+ // const int dimK_simd_block = jcp.dimK_reg_block;
+
+ // for (int dimM_block =0; dimM_block < jcp.dimM_block; dimM_block++)
+ // for (int dimK_block = 0; dimK_block < jcp.dimK_block; dimK_block++)
+ // for (int dimK_reg_block= 0; dimK_reg_block < jcp.dimK_reg_block;
+ // dimK_reg_block++)
+ // for (int tile =0; tile < jcp.dimN_reg_block; tile++)
+ // C[dimM_block][tile] +=
+ // A[dimM_block][dimK_block][dimK_reg_block] *
+ // broadcast(B[dimK_block][tile][dimK_reg_block]);
+ // 1) We do register blocking on A[dimM_block][dimK_block][dimK_reg_block],
+ // so we load it before the loop on tile
+ // 2) the loop on tile must be fully unrolled. Don't know about the one on
+ // dimK_reg_block. I think it should be
+
+ auto inner_loops = [=]() {
+ Label dimM_block_loop, dimK_block_loop;
+ const int inc_dimK_reg_block = jcp.ver == ver_4fma ? 4 : 1;
+ const int fma_ipc = jcp.ver == ver_4fma ? 1 : 2;
+
+ prefetcher_t<float> L1_pf(this, reg_srcB, L1,
+ jcp.dimN_reg_block * jcp.dimK_reg_block,
+ jcp.dimK_reg_block * jcp.dimN_reg_block / inc_dimK_reg_block,
+ fma_ipc);
+ prefetcher_t<float> L2_pf(this, reg_srcB, L2,
+ jcp.dimN_reg_block * jcp.dimK_reg_block,
+ jcp.dimK_reg_block * jcp.dimN_reg_block / inc_dimK_reg_block,
+ fma_ipc);
+
+ if (jcp.dimM_block > 1) {
+ mov(reg_dimM_block_loop_cnt, jcp.dimM_block);
+ L(dimM_block_loop);
+ }
+ {
+ // First, we zero the accumulators if first nb_ic iteration,
+ // otherwise we load them
+ for (int tile = 0; tile < jcp.dimN_reg_block; tile++) {
+ Zmm zmm(jcp.zmm_start + tile);
+ if (is_beta_zero)
+ vpxord(zmm, zmm, zmm);
+ else
+ vmovups(zmm, zword[reg_dstC + 64 * tile]);
+ }
+
+ if (jcp.dimK_block > 1) {
+ mov(reg_dimK_block_loop_cnt, jcp.dimK_block);
+ L(dimK_block_loop);
+ }
+ {
+ auto load_A = [=](int reg_idx, int offset) {
+ for (int i = 0; i < inc_dimK_reg_block; i++)
+ vmovups(Zmm(reg_idx + i),
+ zword[reg_srcA + 64 * (offset + i)]);
+ };
+
+ // Used when doing double buffering
+ int next = 0;
+ if (jcp.double_buffering) {
+ load_A(next, 0);
+ }
+ for (int dimK_reg_block = 0;
+ dimK_reg_block < jcp.dimK_reg_block;
+ dimK_reg_block += inc_dimK_reg_block) {
+ int current;
+ /* Loading the next vector from A */
+ current = next;
+ if (jcp.double_buffering) {
+ next = (dimK_reg_block + inc_dimK_reg_block)
+ % (2 * inc_dimK_reg_block);
+ load_A(next, dimK_reg_block + inc_dimK_reg_block);
+ } else {
+ next = 0;
+ load_A(next, dimK_reg_block);
+ }
+ /* Performing the fmas */
+ for (int tile = 0; tile < jcp.dimN_reg_block; tile++) {
+ Zmm zmm(jcp.zmm_start + tile);
+ if (jcp.ver != ver_avx512_core)
+ L1_pf.prefetch(
+ dimK_reg_block * jcp.dimN_reg_block + tile);
+ if (jcp.ver == ver_4fma)
+ v4fmaddps(zmm, Zmm(current),
+ EVEX_compress_addr(reg_srcB,
+ 64 * tile + dimK_reg_block * 4));
+ else
+ vfmadd231ps(zmm, Zmm(current),
+ EVEX_compress_addr(reg_srcB,
+ 64 * tile + dimK_reg_block * 4,
+ true));
+ if (jcp.ver != ver_avx512_core)
+ L2_pf.prefetch(
+ dimK_reg_block * jcp.dimN_reg_block + tile);
+ }
+ }
+
+ add(reg_srcA, jcp.dimK_reg_block * 64);
+ add(reg_srcB, jcp.dimN_reg_block * 64);
+ if (jcp.dimK_block > 1) {
+ sub(reg_dimK_block_loop_cnt, 1);
+ jnz(dimK_block_loop);
+ }
+ }
+
+
+ auto store_output = [=](bool output_is_aligned) {
+ for (int tile = 0; tile < jcp.dimN_reg_block; tile++) {
+ Zmm zmm(jcp.zmm_start + tile);
+ if (output_is_aligned
+ && jcp.dimK_nb_block == 1
+ && (jcp.dimN * jcp.dimM * alpha * alpha
+ * sizeof(float) > 2 * LLC_data_size))
+ vmovntps(zword[reg_dstC + 64 * tile], zmm);
+ else
+ vmovups(zword[reg_dstC + 64 * tile], zmm);
+ }
+ };
+
+ Label unaligned_store, end_store;
+ test(reg_dstC, cpu_isa_traits<avx512_common>::vlen - 1);
+ jnz(unaligned_store, T_NEAR);
+ store_output(true);
+ jmp(end_store, T_NEAR);
+ L(unaligned_store); {
+ store_output(false);
+ }
+ L(end_store);
+
+ if (jcp.dimM_block > 1) {
+ sub(reg_srcB, jcp.dimK_block * jcp.dimN_reg_block * 64);
+ add(reg_dstC, jcp.dimN_reg_block * 64);
+ sub(reg_dimM_block_loop_cnt, 1);
+ jnz(dimM_block_loop);
+ }
+ }
+ };
+
+ /* Preamble */
+ preamble();
+
+ /* kernel */
+ inner_loops();
+
+ /* Postamble */
+ postamble();
+ ret();
+}
+
+status_t _jit_avx512_common_conv_winograd_data_kernel_f32::init_conf_common(
+ jit_conv_winograd_conf_t &jcp, const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d, const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d)
+{
+
+ if (mayiuse(avx512_core))
+ return status::unimplemented;
+ else if (!mayiuse(avx512_common))
+ return status::unimplemented;
+ else if (mayiuse(avx512_mic_4ops))
+ jcp.ver = ver_4fma;
+ else
+ jcp.ver = ver_fma;
+
+ jcp.nthr = mkldnn_get_max_threads();
+
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+ jcp.ih = src_d.dims()[2];
+ jcp.iw = src_d.dims()[3];
+ jcp.oh = dst_d.dims()[2];
+ jcp.ow = dst_d.dims()[3];
+ jcp.kh = weights_d.dims()[with_groups + 2];
+ jcp.kw = weights_d.dims()[with_groups + 3];
+ jcp.t_pad = cd.padding[0][0];
+ jcp.l_pad = cd.padding[0][1];
+ jcp.stride_h = cd.strides[0];
+ jcp.stride_w = cd.strides[1];
+ jcp.dilate_h = cd.dilates[0];
+ jcp.dilate_w = cd.dilates[1];
+ jcp.r_pad = nstl::max(
+ 0, (jcp.ow - 1) * jcp.stride_w + jcp.kw - jcp.iw - jcp.l_pad);
+ jcp.b_pad = nstl::max(
+ 0, (jcp.oh - 1) * jcp.stride_h + jcp.kh - jcp.ih - jcp.t_pad);
+ jcp.ihp = jcp.ih + jcp.t_pad + jcp.b_pad;
+ jcp.iwp = jcp.iw + jcp.l_pad + jcp.r_pad;
+ jcp.ohp = jcp.oh;
+ jcp.owp = jcp.ow;
+
+ bool ok_to_pad_channels = jcp.ngroups == 1;
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ jcp.ic = rnd_up(jcp.ic, simd_w);
+ }
+
+ if (!IMPLICATION(cd.alg_kind == alg_kind::convolution_auto,
+ is_winograd_faster_than_direct(jcp)))
+ return status::unimplemented;
+
+ // Checking conditions not supported by these kernels
+ if (jcp.ngroups != 1)
+ return status::unimplemented;
+ if ((jcp.kh != 3) || (jcp.kw != 3))
+ return status::unimplemented;
+ if ((jcp.dilate_h != 0) || (jcp.dilate_w != 0))
+ return status::unimplemented;
+ if ((jcp.stride_h != 1) || (jcp.stride_w != 1))
+ return status::unimplemented;
+ if ((jcp.ic % simd_w) != 0 || (jcp.oc % simd_w) != 0)
+ return status::unimplemented;
+
+ format_tag_t dat_tag = nChw16c;
+ format_tag_t wei_tag = with_groups ? gOIhw16i16o : OIhw16i16o;
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ jcp.wei_tag = weights_d.matches_one_of_tag(wei_tag);
+ jcp.dst_tag = dst_d.matches_one_of_tag(dat_tag);
+
+ if (jcp.src_tag != dat_tag) return status::unimplemented;
+ if (jcp.wei_tag != wei_tag) return status::unimplemented;
+ if (jcp.dst_tag != dat_tag) return status::unimplemented;
+
+ bool layout_consistency = true
+ && jcp.ic <= src_d.padded_dims()[1]
+ && jcp.oc <= dst_d.padded_dims()[1]
+ && jcp.ic <= weights_d.padded_dims()[with_groups + 1]
+ && jcp.oc <= weights_d.padded_dims()[with_groups + 0];
+ if (!layout_consistency) return status::unimplemented;
+
+ return status::success;
+}
+
+
+status_t set_wsched_DATA_W_S_G_D_avx512_common(jit_conv_winograd_conf_t &jcp) {
+
+ auto test_cond_dimN_reg_block = [](jit_conv_winograd_conf_t &jcp,
+ int dimN_reg_block, int current_best) {
+ return (dimN_reg_block >= MIN_REQUIRED_DIMN_REG_BLOCK)
+ && (dimN_reg_block < jcp.nb_reg)
+ && (dimN_reg_block < current_best);
+ };
+ jcp.dimN_reg_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimN, jcp.dimN, test_cond_dimN_reg_block);
+
+ if (jcp.dimN_reg_block >= jcp.nb_reg) {
+ auto test_cond_dimN_reg_block = [](jit_conv_winograd_conf_t &jcp,
+ int dimN_reg_block, int current_best) {
+ return (dimN_reg_block < jcp.nb_reg)
+ && (dimN_reg_block > current_best);
+ };
+
+ jcp.dimN_reg_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimN, 1, test_cond_dimN_reg_block);
+ }
+
+ //********************* Choosing dimK_block **********************//
+ auto test_cond1_dimK_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimK_block, int current_best) {
+ return check_cond1(jcp.dimN_reg_block, dimK_block, jcp.dimK_reg_block,
+ 1, jcp.dimM_simd_block, .75f)
+ && (dimK_block > current_best);
+ };
+
+ auto test_cond1_bis_dimK_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimK_block, int current_best) {
+ return check_cond1_bis(jcp.dimN_reg_block, dimK_block,
+ jcp.dimK_reg_block, 1, jcp.dimM_simd_block, .9f)
+ && (dimK_block > current_best);
+ };
+
+ jcp.dimK_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimK / jcp.dimK_reg_block, 1, test_cond1_bis_dimK_block);
+ // If we are not able to use streams, we fall back to condition [1]
+ if (jcp.dimK_block < jcp.dimK / jcp.dimK_reg_block)
+ jcp.dimK_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimK / jcp.dimK_reg_block, 1, test_cond1_dimK_block);
+ jcp.dimK_nb_block = (jcp.dimK / jcp.dimK_reg_block) / jcp.dimK_block;
+
+ //********************* Choosing dimM_block **********************//
+ jcp.dimM_simd_block = 16;
+ /*XXX: Why C=0.5 here but C=0.75 for dimK_block?*/
+ auto test_cond1_dimM_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimM_block, int current_best) {
+ return check_cond1(jcp.dimN_reg_block, jcp.dimK_block,
+ jcp.dimK_reg_block, dimM_block, jcp.dimM_simd_block, .5f)
+ && (dimM_block > current_best);
+ };
+
+ auto test_cond1_bis_dimM_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimM_block, int current_best) {
+ return check_cond1_bis(jcp.dimN_reg_block, jcp.dimK_block,
+ jcp.dimK_reg_block, dimM_block, jcp.dimM_simd_block, .3f)
+ && (dimM_block > current_best);
+ };
+
+ if (jcp.dimK_block < jcp.dimK / jcp.dimK_reg_block)
+ jcp.dimM_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimM / jcp.dimM_simd_block, 1, test_cond1_dimM_block);
+ else
+ jcp.dimM_block = get_divisor_satisfying_cond(jcp,
+ jcp.dimM / jcp.dimM_simd_block, 1, test_cond1_bis_dimM_block);
+ jcp.dimM_nb_block = (jcp.dimM / jcp.dimM_simd_block) / jcp.dimM_block;
+
+ //******************* Choosing dimN_block *******************//
+ auto test_cond2_dimN_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimN_block, int current_best) {
+ return check_cond2(dimN_block, jcp.dimN_reg_block, jcp.dimK_nb_block,
+ jcp.dimK_block, jcp.dimK_reg_block, jcp.dimM_block,
+ jcp.dimM_simd_block, .5f)
+ && (dimN_block > current_best);
+ };
+
+ jcp.dimN_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimN / jcp.dimN_reg_block, 1, test_cond2_dimN_block);
+ jcp.dimN_nb_block = jcp.dimN / (jcp.dimN_reg_block * jcp.dimN_block);
+ jcp.sched_policy = WSCHED_DATA_W_S_G_D;
+ return status::success;
+}
+
+status_t _jit_avx512_common_conv_winograd_data_kernel_f32::init_conf_kernel(
+ jit_conv_winograd_conf_t &jcp, int dimM, int dimN, int dimK)
+{
+ jcp.dimK_reg_block = 16;
+ jcp.dimM_simd_block = 16;
+
+ // TODO: replace double buffering with nuple buffering to maximize register
+ // usage.
+ // the choice of the number of buffers will then come after choosing
+ // dimN_reg_block
+ jcp.double_buffering = true;
+ if (jcp.double_buffering)
+ jcp.zmm_start = 2 * ((jcp.ver == ver_4fma) ? 4 : 2);
+ else
+ jcp.zmm_start = 1;
+ jcp.nb_reg = 32 - jcp.zmm_start;
+
+ jcp.dimN = dimN;
+ jcp.dimK = dimK;
+ jcp.dimM = dimM;
+
+ jcp.sched_policy = WSCHED_INVALID;
+ set_wsched_DATA_W_S_G_D_avx512_common(jcp);
+
+ assert(jcp.sched_policy == WSCHED_DATA_W_S_G_D);
+ return status::success;
+}
+
+bool jit_avx512_common_conv_winograd_fwd_kernel_f32::post_ops_ok(
+ jit_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ const auto &p = attr.post_ops_;
+
+ auto is_relu = [&](int idx) { return p.entry_[idx].is_relu(); };
+ auto is_sum = [&](int idx) { return p.entry_[idx].is_sum(); };
+
+ switch (p.len_) {
+ case 0: return true; // no post_ops
+ case 1: return is_relu(0) || is_sum(0); // relu or sum
+ case 2: return (is_sum(0) && is_relu(1)) ||
+ (is_relu(0) && is_sum(1)); // sum->relu or relu->sum
+ case 3: return is_relu(0) && is_sum(1) && is_relu(2); // relu->sum->relu
+ default: return false;
+ }
+
+ return false;
+}
+
+status_t jit_avx512_common_conv_winograd_fwd_kernel_f32::init_conf(
+ jit_conv_winograd_conf_t &jcp, const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d, const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d, const primitive_attr_t &attr) {
+ status_t st = init_conf_common(jcp, cd, src_d, weights_d, dst_d);
+
+ if (st != status::success)
+ return st;
+
+ // Winograd specific initialization
+ jcp.itiles = (jcp.ow + tile_size - 1) / tile_size;
+ jcp.jtiles = (jcp.oh + tile_size - 1) / tile_size;
+ jcp.ntiles = jcp.mb * jcp.itiles * jcp.jtiles;
+
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ const int eltwise_ind = p.find(primitive_kind::eltwise, 0, 1);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise) jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+ jcp.with_sum = p.find(primitive_kind::sum, 0) != -1;
+
+ status_t res = init_conf_kernel(jcp, jcp.oc, jcp.ntiles, jcp.ic);
+ jcp.ic_simd_block = jcp.dimK_reg_block;
+ jcp.ic_block = jcp.dimK_block;
+ jcp.nb_ic = jcp.dimK_nb_block;
+ jcp.oc_simd_block = jcp.dimM_simd_block;
+ jcp.oc_block = jcp.dimM_block;
+ jcp.nb_oc = jcp.dimM_nb_block;
+ jcp.tile_block_ur = jcp.dimN_reg_block;
+ jcp.nb_tile_block_ur = jcp.dimN_block;
+ jcp.tile_block = jcp.dimN_nb_block;
+ jcp.tile_4fma_padding = 0; // only relevant for backward weights
+
+ return res;
+}
+
+status_t jit_avx512_common_conv_winograd_bwd_data_kernel_f32::init_conf(
+ jit_conv_winograd_conf_t &jcp, const convolution_desc_t &cd,
+ const memory_desc_wrapper &diff_src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &diff_dst_d)
+{
+ status_t st = init_conf_common(jcp, cd, diff_src_d, weights_d, diff_dst_d);
+
+ if (st != status::success)
+ return st;
+
+ jcp.itiles = (jcp.iw + tile_size - 1) / tile_size;
+ jcp.jtiles = (jcp.ih + tile_size - 1) / tile_size;
+ jcp.ntiles = jcp.mb * jcp.itiles * jcp.jtiles;
+
+ status_t res = init_conf_kernel(jcp, jcp.ic, jcp.ntiles, jcp.oc);
+ jcp.oc_simd_block = jcp.dimK_reg_block;
+ jcp.oc_block = jcp.dimK_block;
+ jcp.nb_oc = jcp.dimK_nb_block;
+ jcp.ic_simd_block = jcp.dimM_simd_block;
+ jcp.ic_block = jcp.dimM_block;
+ jcp.nb_ic = jcp.dimM_nb_block;
+ jcp.tile_block_ur = jcp.dimN_reg_block;
+ jcp.nb_tile_block_ur = jcp.dimN_block;
+ jcp.tile_block = jcp.dimN_nb_block;
+ jcp.tile_4fma_padding = 0; // only relevant for backward weights
+
+ return res;
+}
+
+void jit_avx512_common_conv_winograd_bwd_weights_kernel_f32::transpose_ker_generate()
+{
+ auto load_B = [=](int reg_idx, int offset) {
+ for (int i = 0; i < 4; i++) {
+ vmovups(Zmm(reg_idx + i), zword[reg_origB + (offset + i) * jcp.dimN_reg_block * sizeof(float)]);
+ }
+ };
+
+ preamble();
+ int curr = 0;
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ int origB_offset = (j * alpha + i) * jcp.dimK_4fma;
+ size_t transB_offset = (size_t)(j * alpha + i) * jcp.dimK_nb_block *
+ jcp.dimN_block * jcp.dimK_block * jcp.dimK_reg_block *
+ jcp.dimK_4fma * jcp.dimN_reg_block * sizeof(float);
+ mov(reg_transB_idx, transB_offset);
+ for (int tb = 0; tb < jcp.dimK_4fma; tb+=4) {
+ /*double buffering to hide load latencies*/
+ int next = (curr + 4) % 8;
+ if (i == 0 && tb == 0) {
+ load_B(0, origB_offset);
+ }
+ if (tb + 4 < (jcp.dimK_4fma -1)) {
+ load_B(next, origB_offset + 4);
+ } else if (i < alpha - 1) {
+ load_B(next, origB_offset + jcp.dimK_4fma);
+ }
+
+ vunpcklps(Zmm(8), Zmm(curr), Zmm(curr + 1));
+ vunpcklps(Zmm(9), Zmm(curr + 2), Zmm(curr + 3));
+ vunpckhps(Zmm(curr), Zmm(curr), Zmm(curr + 1));
+ vunpckhps(Zmm(curr + 1), Zmm(curr + 2), Zmm(curr + 3));
+
+ vunpcklpd(Zmm(curr + 2), Zmm(8), Zmm(9));
+ vunpckhpd(Zmm(curr + 3), Zmm(8), Zmm(9));
+
+ vunpcklpd(Zmm(8), Zmm(curr), Zmm(curr + 1));
+ vunpckhpd(Zmm(9), Zmm(curr), Zmm(curr + 1));
+
+ vmovntps(zword[reg_transB + reg_transB_idx
+ + sizeof(float) * tb * jcp.dimN_reg_block],
+ Zmm(curr+2));
+ vmovntps(zword[reg_transB + reg_transB_idx
+ + sizeof(float) * (tb + 1) * jcp.dimN_reg_block],
+ Zmm(curr+3));
+ vmovntps(zword[reg_transB + reg_transB_idx
+ + sizeof(float) * (tb + 2) * jcp.dimN_reg_block],
+ Zmm(8));
+ vmovntps(zword[reg_transB + reg_transB_idx
+ + sizeof(float) * (tb + 3) * jcp.dimN_reg_block],
+ Zmm(9));
+ curr = next;
+
+ }
+ }
+ }
+ postamble();
+ ret();
+}
+void jit_avx512_common_conv_winograd_bwd_weights_kernel_f32::gemm_loop_generate(
+ bool is_first_tile)
+{
+ // for (int ofm2 = 0; ofm2 < jcp.oc_block; ofm2++)
+ // for (int ifm2 = 0; ifm2 < jcp.ic_block; ifm2++)
+ // for (int nb_tile_block_ur = 0; nb_tile_block_ur <
+ // jcp.nb_tile_block_ur; nb_tile_block_ur++)
+ // for (int tile_block_ur = 0; tile_block_ur <
+ // jcp.tile_block_ur; tile_block_ur++)
+ // for (int ifm3 = 0; ifm3 < jcp.ic_reg_block; ++ifm3)
+ // U[ofm2][ifm2][ofm3][ifm3][0:oc_simd_block] +=
+ // M[ofm2][ofm3][nb_tile_block_ur][tile_block_ur][0:oc_simd_block]
+ // *
+ // broadcast(V[ifm2][nb_tile_block_ur][ifm3][tile_block_ur])
+ auto inner_loops = [=]() {
+ int inc_fma = jcp.ver == ver_4fma ? 4 : 1;
+ const int fma_ipc = jcp.ver == ver_4fma ? 1 : 2;
+ prefetcher_t<float> L1_pf(this, reg_srcB, L1,
+ jcp.dimK_reg_block * jcp.dimN_reg_block * jcp.dimK_4fma,
+ jcp.dimK_reg_block * jcp.dimN_reg_block * jcp.dimK_4fma
+ / inc_fma,
+ fma_ipc);
+ prefetcher_t<float> L2_pf(this, reg_srcB, L2,
+ jcp.dimK_reg_block * jcp.dimN_reg_block * jcp.dimK_4fma,
+ jcp.dimK_reg_block * jcp.dimN_reg_block * jcp.dimK_4fma
+ / inc_fma,
+ fma_ipc);
+
+ auto load_A = [=](int reg_idx, int offset) {
+ for (int i = 0; i < inc_fma; i++) {
+ vmovups(Zmm(reg_idx + i),
+ zword[reg_srcA +
+ sizeof(float) * jcp.dimM_simd_block * (offset + i)]);
+ }
+ };
+
+ Label dimM_block_loop, dimK_block_loop, dimN_block_loop;
+ if (jcp.dimM_block > 1) {
+ mov(reg_dimM_block_loop_cnt, jcp.dimM_block);
+ L(dimM_block_loop);
+ }
+ { /************* OC_block (M) loop ***********/
+ if (jcp.dimN_block > 1) {
+ mov(reg_dimN_block_loop_cnt, jcp.dimN_block);
+ L(dimN_block_loop);
+ }
+ { /*************** IC_block (N) loop *********/
+ for (int dimN_reg_block = 0;
+ dimN_reg_block < jcp.dimN_reg_block; ++dimN_reg_block) {
+ Zmm zmm(jcp.zmm_start + dimN_reg_block);
+ if (is_first_tile)
+ vpxord(zmm, zmm, zmm);
+ else
+ vmovups(zmm, zword[reg_dstC +
+ dimN_reg_block * jcp.dimM_simd_block *
+ sizeof(float)]);
+ }
+
+ if (jcp.dimK_block > 1) {
+ mov(reg_dimK_block_loop_cnt, jcp.dimK_block);
+ L(dimK_block_loop);
+ }
+ { /************* nb_tile_ur(K) loop ********/
+ int next = 0;
+ if (jcp.double_buffering) {
+ load_A(next, 0);
+ }
+ for (int dimK_reg_block = 0;
+ dimK_reg_block < jcp.dimK_reg_block;
+ dimK_reg_block++) {
+ int srcB_offset = dimK_reg_block * jcp.dimK_4fma
+ * jcp.dimN_reg_block;
+ for (int dimK_4fma = 0; dimK_4fma < jcp.dimK_4fma;
+ dimK_4fma += inc_fma) {
+ int current = next;
+ if (jcp.double_buffering) {
+ next = (dimK_reg_block * jcp.dimK_4fma
+ + dimK_4fma + inc_fma)
+ % (2 * inc_fma);
+ load_A(next, dimK_reg_block * jcp.dimK_4fma
+ + dimK_4fma + inc_fma);
+ } else {
+ next = 0;
+ load_A(next, dimK_reg_block * jcp.dimK_4fma
+ + dimK_4fma);
+ }
+ for (int dimN_reg_block = 0;
+ dimN_reg_block < jcp.dimN_reg_block;
+ ++dimN_reg_block) {
+ L1_pf.prefetch(srcB_offset / inc_fma
+ + dimK_4fma / inc_fma
+ * jcp.dimN_reg_block
+ + dimN_reg_block);
+ L2_pf.prefetch(srcB_offset / inc_fma
+ + dimK_4fma / inc_fma
+ * jcp.dimN_reg_block
+ + dimN_reg_block);
+ if (jcp.ver == ver_4fma) {
+ int srcB_trans_offset = (dimK_4fma / 4) * 64
+ + dimK_4fma % 4;
+ v4fmaddps(
+ Zmm(jcp.zmm_start + dimN_reg_block),
+ Zmm(current),
+ EVEX_compress_addr(reg_srcB,
+ sizeof(float) * (
+ srcB_offset +
+ srcB_trans_offset +
+ (dimN_reg_block % 4) * 16 +
+ (dimN_reg_block / 4) * 4)));
+ } else {
+ vfmadd231ps(
+ Zmm(jcp.zmm_start + dimN_reg_block),
+ Zmm(current),
+ EVEX_compress_addr(reg_srcB,
+ sizeof(float) * (srcB_offset + dimN_reg_block),
+ true));
+ }
+ }
+ }
+ }
+ }
+
+ add(reg_srcA, jcp.dimK_reg_block * jcp.dimK_4fma
+ * jcp.dimM_simd_block * sizeof(float));
+ add(reg_srcB, jcp.dimK_reg_block * jcp.dimN_reg_block
+ * jcp.dimK_4fma * sizeof(float));
+ if (jcp.dimK_block > 1) {
+ sub(reg_dimK_block_loop_cnt, 1);
+ jnz(dimK_block_loop);
+ }
+
+ /******** Write C back to memory *******/
+ for (int dimN_reg_block = 0;
+ dimN_reg_block < jcp.dimN_reg_block; ++dimN_reg_block) {
+ Zmm zmm(jcp.zmm_start + dimN_reg_block);
+ vmovups(zword[reg_dstC +
+ dimN_reg_block * jcp.dimM_simd_block * sizeof(float)],
+ zmm);
+ }
+
+ sub(reg_srcA, jcp.dimK_block * jcp.dimK_reg_block *
+ jcp.dimK_4fma * jcp.dimM_simd_block * sizeof(float));
+ add(reg_dstC, jcp.dimN_reg_block * jcp.dimM_simd_block
+ * sizeof(float));
+ if (jcp.dimN_block > 1) {
+ sub(reg_dimN_block_loop_cnt, 1);
+ jnz(dimN_block_loop);
+ }
+ }
+
+ if (jcp.dimM_block > 1) {
+ sub(reg_srcB, jcp.dimN_block * jcp.dimK_block
+ * jcp.dimK_reg_block * jcp.dimN_reg_block
+ * jcp.dimK_4fma * sizeof(float));
+ add(reg_srcA, jcp.dimK_block * jcp.dimK_reg_block
+ * jcp.dimK_4fma * jcp.dimM_simd_block * sizeof(float));
+ sub(reg_dimM_block_loop_cnt, 1);
+ jnz(dimM_block_loop);
+ }
+ }
+ };
+
+ /* Preamble */
+ // register used to handle long fma encoding
+ preamble();
+ mov(reg_srcA, reg_srcA_const);
+ inner_loops();
+
+ /* Postamble */
+ postamble();
+ ret();
+}
+
+namespace {
+bool check_cond1_wu(int dimM_block, int dimM_simdw, int dimK_block,
+ int dimK_reg_block, int dimK_4fma, int dimN_reg_block, float C)
+{
+ float lhs = 1.0f * dimM_block * dimN_reg_block * dimM_simdw;
+ lhs += dimM_block * dimK_block * dimK_reg_block * dimK_4fma * dimM_simdw;
+ lhs += dimK_block * dimN_reg_block * dimK_reg_block * dimK_4fma;
+ lhs *= sizeof(float);
+ float rhs = C * L1_cache_size;
+ return (lhs <= rhs);
+}
+
+bool check_cond1bis_wu(int dimM_block, int dimM_simdw, int dimK_block,
+ int dimK_reg_block, int dimK_4fma, int dimN_reg_block, float C)
+{
+ float lhs = 1.0f * dimM_block * dimK_block * dimK_reg_block * dimK_4fma
+ * dimM_simdw;
+ lhs += dimK_block * dimN_reg_block * dimK_reg_block * dimK_4fma;
+ lhs *= sizeof(float);
+ float rhs = C * L1_cache_size;
+ return (lhs <= rhs);
+}
+
+bool check_cond2bis_wu(int dimM_block, int dimM_simdw, int dimK_block,
+ int dimK_reg_block, int dimK_4fma, int dimN_block, int dimN_reg_block,
+ float C)
+{
+ float lhs = 1.0f * dimM_block * dimM_simdw * dimK_block * dimK_reg_block
+ * dimK_4fma;
+ lhs += dimK_block * dimK_reg_block * dimK_4fma * dimN_block
+ * dimN_reg_block;
+ lhs *= sizeof(float);
+ float rhs = C * L2_cache_size;
+ return (lhs <= rhs);
+}
+
+bool check_cond2_wu(int dimM_block, int dimM_simdw, int dimK_block,
+ int dimK_reg_block, int dimK_4fma, int dimN_block, int dimN_reg_block,
+ float C)
+{
+ float lhs = 1.0f * dimM_block * dimM_simdw * dimN_block * dimN_reg_block;
+ lhs += dimM_block * dimM_simdw * dimK_block * dimK_reg_block * dimK_4fma;
+ lhs += dimK_block * dimK_reg_block * dimK_4fma * dimN_block
+ * dimN_reg_block;
+ lhs *= sizeof(float);
+ float rhs = C * L2_cache_size;
+ return (lhs <= rhs);
+}
+} // namespace
+
+status_t set_wsched_WEI_S_D_G_W_avx512_common(jit_conv_winograd_conf_t &jcp)
+{
+ /*************** Choose dimN_reg_block (ic_simd_block)
+ * *******************************/
+ jcp.dimN = jcp.ic;
+ /*Hardcoded to 16 because N = ic for bwd weights and
+ innermost dimension for ic is assumed 16 in src transforms. This
+ choice covers load latencies while maintaining simplicity of kernel
+ for POR topologies. FIXME in future??: Will not work for future topologies
+ when ic%16 != 0*/
+ jcp.dimN_reg_block = jcp.ic_simd_block;
+
+ /****************************** Choose dimK_block
+ * **************************/
+ // No freedom for choosing dimM_simd_block because ic_simd_block
+ // is determined by input data format
+ jcp.dimM_simd_block = jcp.oc_simd_block;
+
+ auto test_cond1bis_dimK_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimK_block, int current_best) {
+ return check_cond1bis_wu(1, jcp.dimM_simd_block, dimK_block, 1,
+ jcp.dimK_4fma, jcp.dimN_reg_block, 0.4f)
+ && (dimK_block > current_best);
+ };
+
+ auto test_cond1_dimK_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimK_block, int current_best) {
+ return check_cond1_wu(1, jcp.dimM_simd_block, dimK_block, 1,
+ jcp.dimK_4fma, jcp.dimN_reg_block, 0.4f)
+ && (dimK_block > current_best);
+ };
+
+ auto test_cond2bis_dimK_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimK_block, int current_best) {
+ return check_cond2bis_wu(1, jcp.dimM_simd_block, dimK_block, 1,
+ jcp.dimK_4fma, 1, jcp.dimN_reg_block, 0.5f)
+ && (dimK_block > current_best);
+ };
+
+ auto test_cond2_dimK_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimK_block, int current_best) {
+ return check_cond2_wu(1, jcp.dimM_simd_block, dimK_block, 1,
+ jcp.dimK_4fma, 1, jcp.dimN_reg_block, 0.1f)
+ && (dimK_block > current_best);
+ };
+
+ jcp.dimK_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimK / jcp.dimK_4fma, 1, test_cond2bis_dimK_block);
+ if (jcp.dimK_block < jcp.dimK / jcp.dimK_4fma)
+ jcp.dimK_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimK / jcp.dimK_4fma, 1, test_cond2_dimK_block);
+
+ jcp.dimK_reg_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimK_block, 1, test_cond1bis_dimK_block);
+ if (jcp.dimK_reg_block < jcp.dimK_block) {
+ jcp.dimK_reg_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimK_block, 1, test_cond1_dimK_block);
+ }
+ jcp.dimK_block /= jcp.dimK_reg_block;
+ jcp.dimK_nb_block
+ = jcp.dimK / jcp.dimK_4fma / jcp.dimK_reg_block / jcp.dimK_block;
+ jcp.tile_block_ur = jcp.dimK_reg_block;
+ jcp.nb_tile_block_ur = jcp.dimK_block;
+ jcp.tile_block = jcp.dimK_nb_block;
+
+ /***************************** Chose dimN block
+ * ****************************/
+ auto test_cond2_dimN_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimN_block, int current_best) {
+ return check_cond2_wu(1, jcp.dimM_simd_block, jcp.dimK_block,
+ jcp.dimK_reg_block, jcp.dimK_4fma, dimN_block,
+ jcp.dimN_reg_block, 0.5f)
+ && (dimN_block > current_best);
+ };
+
+ jcp.dimN_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimN / jcp.dimN_reg_block, 1, test_cond2_dimN_block);
+ jcp.ic_block = jcp.dimN_block;
+ jcp.dimN_nb_block = jcp.dimN / jcp.dimN_reg_block / jcp.dimN_block;
+ jcp.nb_ic = jcp.dimN_nb_block;
+
+ /********************************* Choose dimM block
+ * ************************/
+ jcp.dimM = jcp.oc;
+
+ auto test_cond1_dimM_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimM_block, int current_best) {
+ return check_cond1_wu(dimM_block, jcp.dimM_simd_block, 1,
+ jcp.dimK_reg_block, jcp.dimK_4fma, jcp.dimN_reg_block,
+ 1.0f)
+ && (dimM_block > current_best)
+ && (jcp.dimM / jcp.dimM_simd_block / dimM_block) >= 2;
+ };
+
+ jcp.dimM_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimM / jcp.dimM_simd_block, 1, test_cond1_dimM_block);
+ jcp.dimM_nb_block = (jcp.dimM / jcp.dimM_simd_block) / jcp.dimM_block;
+
+ jcp.sched_policy = WSCHED_WEI_S_D_G_W;
+ return status::success;
+}
+
+status_t jit_avx512_common_conv_winograd_bwd_weights_kernel_f32::init_conf(
+ jit_conv_winograd_conf_t &jcp, const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d, const memory_desc_wrapper &diff_dst_d,
+ const memory_desc_wrapper &diff_weights_d)
+{
+ jcp.nthr = mkldnn_get_max_threads();
+
+ const bool with_groups = diff_weights_d.ndims() == src_d.ndims() + 1;
+
+ jcp.ngroups = with_groups ? diff_weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+ jcp.oc = diff_dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+ jcp.ih = src_d.dims()[2];
+ jcp.iw = src_d.dims()[3];
+ jcp.oh = diff_dst_d.dims()[2];
+ jcp.ow = diff_dst_d.dims()[3];
+ jcp.kh = diff_weights_d.dims()[with_groups + 2];
+ jcp.kw = diff_weights_d.dims()[with_groups + 3];
+ jcp.t_pad = cd.padding[0][0];
+ jcp.l_pad = cd.padding[0][1];
+ jcp.stride_h = cd.strides[0];
+ jcp.stride_w = cd.strides[1];
+ jcp.r_pad = nstl::max(
+ 0, (jcp.ow - 1) * jcp.stride_w + jcp.kw - jcp.iw - jcp.l_pad);
+ jcp.b_pad = nstl::max(
+ 0, (jcp.oh - 1) * jcp.stride_h + jcp.kh - jcp.ih - jcp.t_pad);
+ jcp.ihp = jcp.ih + jcp.t_pad + jcp.b_pad;
+ jcp.iwp = jcp.iw + jcp.l_pad + jcp.r_pad;
+ jcp.ohp = jcp.oh;
+ jcp.owp = jcp.ow;
+ jcp.with_bias = (cd.diff_bias_desc.format_kind != format_kind::undef);
+ jcp.dilate_h = cd.dilates[0];
+ jcp.dilate_w = cd.dilates[1];
+
+ bool ok_to_pad_channels = jcp.ngroups == 1;
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ jcp.ic = rnd_up(jcp.ic, simd_w);
+ }
+
+ if (mayiuse(avx512_core))
+ return status::unimplemented;
+ if (!mayiuse(avx512_common))
+ return status::unimplemented;
+ else if (mayiuse(avx512_mic_4ops))
+ jcp.ver = ver_4fma;
+ else
+ jcp.ver = ver_fma;
+
+ if (!IMPLICATION(cd.alg_kind == alg_kind::convolution_auto,
+ is_winograd_faster_than_direct(jcp)))
+ return status::unimplemented;
+ // Winograd specific initialization
+ jcp.itiles = (jcp.ow + tile_size - 1) / tile_size;
+ jcp.jtiles = (jcp.oh + tile_size - 1) / tile_size;
+ jcp.ntiles = jcp.mb * jcp.itiles * jcp.jtiles;
+
+ // Winograd kernel works only for 3x3 convolution with stride 1
+ if (jcp.ngroups != 1)
+ return status::unimplemented;
+ if ((jcp.kh != 3) || (jcp.kw != 3))
+ return status::unimplemented;
+ if ((jcp.dilate_h != 0) || (jcp.dilate_w != 0))
+ return status::unimplemented;
+ if ((jcp.stride_h != 1) || (jcp.stride_w != 1))
+ return status::unimplemented;
+ if ((jcp.ic % simd_w) != 0 || (jcp.oc % simd_w) != 0)
+ return status::unimplemented;
+
+ format_tag_t dat_tag = nChw16c;
+ format_tag_t wei_tag = with_groups ? gOIhw16i16o : OIhw16i16o;
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ jcp.wei_tag = diff_weights_d.matches_one_of_tag(wei_tag);
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(dat_tag);
+
+ if (jcp.src_tag != dat_tag) return status::unimplemented;
+ if (jcp.wei_tag != wei_tag) return status::unimplemented;
+ if (jcp.dst_tag != dat_tag) return status::unimplemented;
+
+ bool layout_consistency = true
+ && jcp.ic <= src_d.padded_dims()[1]
+ && jcp.oc <= diff_dst_d.padded_dims()[1]
+ && jcp.ic <= diff_weights_d.padded_dims()[with_groups + 1]
+ && jcp.oc <= diff_weights_d.padded_dims()[with_groups + 0];
+ if (!layout_consistency) return status::unimplemented;
+
+ /*************************** New Kernel Parameters
+ * *****************************/
+ jcp.ic_simd_block = simd_w;
+ jcp.oc_simd_block = simd_w;
+ jcp.dimK_4fma = 1;
+ jcp.tile_4fma_padding = 0;
+
+#define MAX_4FMA_UR 8
+ if (jcp.ver == ver_4fma) {
+ auto test_cond_4fma = [](jit_conv_winograd_conf_t &jcp, int dimK_4fma,
+ int current_best) {
+ return (dimK_4fma % 4 == 0) && (dimK_4fma <= MAX_4FMA_UR)
+ && (dimK_4fma > current_best);
+ };
+ jcp.dimK_4fma = get_divisor_satisfying_cond(
+ jcp, jcp.itiles * jcp.jtiles, 4, test_cond_4fma);
+ if (jcp.dimK_4fma == 1)
+ jcp.dimK_4fma = 4;
+ if ((jcp.itiles * jcp.jtiles) % jcp.dimK_4fma != 0)
+ jcp.tile_4fma_padding = jcp.dimK_4fma
+ - ((jcp.itiles * jcp.jtiles) % jcp.dimK_4fma);
+ }
+
+ jcp.tile_4fma = jcp.dimK_4fma;
+ /*NOTE: When (itiles * jtiles) % dimK_4fma != 0, transpose in diff_src
+ * transform
+ * will not work correctly, this is solved by applying padding.*/
+ jcp.dimK = jcp.mb * (jcp.itiles * jcp.jtiles + jcp.tile_4fma_padding);
+ jcp.dimN = jcp.ic;
+ jcp.dimM = jcp.oc;
+
+ jcp.double_buffering = true;
+ if (jcp.double_buffering)
+ jcp.zmm_start = jcp.ver == ver_4fma ? 8 : 2;
+ else
+ jcp.zmm_start = jcp.ver == ver_4fma ? 4 : 1;
+ jcp.nb_reg = 32 - jcp.zmm_start;
+
+ jcp.sched_policy = WSCHED_INVALID;
+ status_t res = set_wsched_WEI_S_D_G_W_avx512_common(jcp);
+ assert(jcp.sched_policy == WSCHED_WEI_S_D_G_W);
+
+ jcp.tile_block_ur = jcp.dimK_reg_block;
+ jcp.nb_tile_block_ur = jcp.dimK_block;
+ jcp.tile_block = jcp.dimK_nb_block;
+
+ jcp.ic_block = jcp.dimN_block;
+ jcp.nb_ic = jcp.dimN_nb_block;
+
+ jcp.oc_block = jcp.dimM_block;
+ jcp.nb_oc = jcp.dimM_nb_block;
+
+ return res;
+
+}
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_winograd_kernel_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_winograd_kernel_f32.hpp
new file mode 100644
index 0000000000..6c117143f5
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_conv_winograd_kernel_f32.hpp
@@ -0,0 +1,179 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_AVX512_COMMON_CONV_WINOGRAD_KERNEL_F32_HPP
+#define JIT_AVX512_COMMON_CONV_WINOGRAD_KERNEL_F32_HPP
+
+#include "c_types_map.hpp"
+#include "cpu_memory.hpp"
+
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+//alpha determines the output tile_size
+constexpr int alpha = 6;
+constexpr int tile_size = 4;
+//simd length used for vectorization
+constexpr int simd_w = 16;
+
+struct _jit_avx512_common_conv_winograd_data_kernel_f32 : public jit_generator {
+ _jit_avx512_common_conv_winograd_data_kernel_f32(
+ jit_conv_winograd_conf_t ajcp)
+ : jcp(ajcp)
+ {
+ //******************* First iter kernel ********************//
+ this->gemm_loop_generate(true);
+ gemm_loop_ker_first_iter
+ = (decltype(gemm_loop_ker_first_iter)) this->getCode();
+
+ //************** Subsequent iterations kernel **************//
+ if (jcp.dimK_nb_block > 1) {
+ align();
+ const Xbyak::uint8 *addr = getCurr();
+ this->gemm_loop_generate(false);
+ gemm_loop_ker = (decltype(gemm_loop_ker))addr;
+ }
+ }
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(_jit_avx512_common_conv_winograd_data_kernel_f32)
+
+ static status_t init_conf_common(jit_conv_winograd_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d);
+
+ static status_t init_conf_kernel(
+ jit_conv_winograd_conf_t &jcp, int dimM, int dimN, int dimK);
+
+ jit_conv_winograd_conf_t jcp;
+ void (*gemm_loop_ker)(float *, const float *, const float *);
+ void (*gemm_loop_ker_first_iter)(float *, const float *, const float *);
+
+protected:
+ using reg64_t = const Xbyak::Reg64;
+ enum { typesize = sizeof(float) };
+
+ void gemm_loop_generate(bool is_beta_zero);
+
+ /* registers used for GEMM */
+ reg64_t reg_dstC = abi_param1;
+ reg64_t reg_srcA = abi_param2;
+ reg64_t reg_srcB = abi_param3;
+
+ reg64_t reg_dimM_block_loop_cnt = r10;
+ reg64_t reg_dimK_block_loop_cnt = r11;
+};
+
+struct jit_avx512_common_conv_winograd_fwd_kernel_f32
+ : _jit_avx512_common_conv_winograd_data_kernel_f32 {
+ using _jit_avx512_common_conv_winograd_data_kernel_f32::
+ _jit_avx512_common_conv_winograd_data_kernel_f32;
+
+ static bool post_ops_ok(jit_conv_conf_t &jcp, const primitive_attr_t &attr);
+
+ static status_t init_conf(jit_conv_winograd_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d, const primitive_attr_t &attr);
+};
+
+struct jit_avx512_common_conv_winograd_bwd_data_kernel_f32
+ : public _jit_avx512_common_conv_winograd_data_kernel_f32 {
+ using _jit_avx512_common_conv_winograd_data_kernel_f32::
+ _jit_avx512_common_conv_winograd_data_kernel_f32;
+
+ static status_t init_conf(jit_conv_winograd_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &diff_src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &diff_dst_d);
+};
+
+struct jit_avx512_common_conv_winograd_bwd_weights_kernel_f32
+ : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(_jit_avx512_common_conv_winograd_bwd_weights_kernel_f32)
+
+ jit_avx512_common_conv_winograd_bwd_weights_kernel_f32(
+ jit_conv_winograd_conf_t ajcp)
+ : jcp(ajcp)
+ {
+
+ //******************* First iter kernel ********************//
+ {
+ align();
+ const Xbyak::uint8 *addr = getCurr();
+ this->gemm_loop_generate(true);
+ gemm_loop_ker_first_iter = (decltype(gemm_loop_ker_first_iter))addr;
+ }
+
+ if (jcp.tile_block > 1) {
+ align();
+ const Xbyak::uint8 *addr = getCurr();
+ this->gemm_loop_generate(false);
+ gemm_loop_ker = (decltype(gemm_loop_ker))addr;
+ }
+
+ if (jcp.ver == ver_4fma) {
+ align();
+ const Xbyak::uint8 *addr = getCurr();
+ this->transpose_ker_generate();
+ transpose_4fma_ker = (decltype(transpose_4fma_ker))addr;
+ }
+ }
+
+ static status_t init_conf(jit_conv_winograd_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &diff_dst_d,
+ const memory_desc_wrapper &diff_weights_d);
+
+ jit_conv_winograd_conf_t jcp;
+ void (*gemm_loop_ker)(float *, const float *, const float *);
+ void (*gemm_loop_ker_first_iter)(float *, const float *, const float *);
+ void (*transpose_4fma_ker)(float *, float *);
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ enum { typesize = sizeof(float) };
+
+ void gemm_loop_generate(bool is_first_tile);
+ void transpose_ker_generate();
+
+ reg64_t reg_origB = abi_param2;
+ reg64_t reg_transB = abi_param1;
+
+ reg64_t reg_dstC = abi_param1;
+ reg64_t reg_srcA_const = abi_param2;
+ reg64_t reg_srcB = abi_param3;
+
+ reg64_t reg_sp = rsp;
+ reg64_t reg_srcA = r9;
+ reg64_t reg_nb_ic = r10;
+ reg64_t reg_loop_cpt = r11;
+ reg64_t reg_transB_idx = r13;
+
+ /* Registers used by new kernel */
+ reg64_t reg_dimM_block_loop_cnt = r10;
+ reg64_t reg_dimK_block_loop_cnt = r12;
+ reg64_t reg_dimN_block_loop_cnt = r11;
+};
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution.cpp
new file mode 100644
index 0000000000..abddc19221
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution.cpp
@@ -0,0 +1,1526 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_avx512_common_convolution.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+
+using namespace nstl;
+
+using jit_conv_ker_t = void (*)(jit_conv_call_s *);
+
+#define PIPELINE(field) \
+ do { \
+ p.field = p.field ## _prf; \
+ p.field ## _prf = field; \
+ } while (0)
+
+inline void jit_conv_ker_pipeline(jit_conv_ker_t ker, jit_conv_call_s &p,
+ const void *src, const void *dst, const void *filt, const void *bias,
+ int channel, int kh_padding)
+{
+ PIPELINE(src);
+ PIPELINE(dst);
+ PIPELINE(filt);
+ PIPELINE(bias);
+ PIPELINE(channel);
+ PIPELINE(kh_padding);
+
+ if (p.src)
+ ker(&p);
+}
+// The special case for the driver with ow-parallelization (FWD)
+// TODO: implement it for BWD_D and BWD_W too
+inline void jit_conv_ker_pipeline_ow_thr(jit_conv_ker_t ker, jit_conv_call_s &p,
+ const void *src, const void *dst, const void *filt, const void *bias,
+ int channel, int kh_padding, int owb)
+{
+ PIPELINE(src);
+ PIPELINE(dst);
+ PIPELINE(filt);
+ PIPELINE(bias);
+ PIPELINE(channel);
+ PIPELINE(kh_padding);
+ PIPELINE(owb);
+
+ if (p.src)
+ ker(&p);
+}
+
+inline void jit_conv_3d_ker_pipeline(jit_conv_ker_t ker, jit_conv_call_s &p,
+ const void *src, const void *dst, const void *filt, const void *bias,
+ int channel, int kh_padding, int kd_padding)
+{
+ PIPELINE(src);
+ PIPELINE(dst);
+ PIPELINE(filt);
+ PIPELINE(bias);
+ PIPELINE(channel);
+ PIPELINE(kh_padding);
+ PIPELINE(kd_padding);
+
+ if (p.src)
+ ker(&p);
+}
+// The special case for the driver with ow-parallelization (FWD)
+// TODO: implement it for BWD_D and BWD_W too
+inline void jit_conv_3d_ker_pipeline_ow_thr(jit_conv_ker_t ker,
+ jit_conv_call_s &p, const void *src, const void *dst, const void *filt,
+ const void *bias, int channel, int kh_padding, int kd_padding, int owb)
+{
+ PIPELINE(src);
+ PIPELINE(dst);
+ PIPELINE(filt);
+ PIPELINE(bias);
+ PIPELINE(channel);
+ PIPELINE(kh_padding);
+ PIPELINE(kd_padding);
+ PIPELINE(owb);
+
+ if (p.src)
+ ker(&p);
+}
+
+void jit_conv_3d_ker_bwd_w_pipeline(jit_conv_ker_t ker, jit_conv_call_s &p,
+ const void *src, const void *dst, const void *filt, const void *bias,
+ int channel, int d_index, int d_worksize,
+ int kd_padding /* kd_work_size */, size_t kd_offset) {
+ PIPELINE(src);
+ PIPELINE(dst);
+ PIPELINE(filt);
+ PIPELINE(bias);
+ PIPELINE(channel);
+ PIPELINE(kd_padding);
+ PIPELINE(d_worksize);
+ PIPELINE(d_index);
+ PIPELINE(kd_offset);
+
+ if (p.src)
+ ker(&p);
+}
+#define wht_blk_off(d, g, ...) \
+ (pd()->with_groups() \
+ ? (d).blk_off((g), __VA_ARGS__) \
+ : (d).blk_off(__VA_ARGS__))
+
+template <data_type_t src_type, data_type_t wei_type, data_type_t dst_type>
+void jit_avx512_common_convolution_fwd_t<src_type, wei_type,
+ dst_type>::prepare_padded_bias(const dst_data_t *&bias,
+ const memory_tracking::grantor_t &scratchpad) const {
+ if (!pd()->wants_padded_bias()) return;
+
+ auto padded_bias = scratchpad.template get<dst_data_t>(
+ key_conv_padded_bias);
+ utils::array_copy(padded_bias, bias, pd()->jcp_.oc_without_padding);
+ utils::array_set(padded_bias + pd()->jcp_.oc_without_padding,
+ (dst_data_t)0, pd()->jcp_.oc - pd()->jcp_.oc_without_padding);
+ bias = padded_bias;
+}
+
+template <data_type_t src_type, data_type_t wei_type,
+ data_type_t dst_type>
+void jit_avx512_common_convolution_fwd_t<src_type, wei_type, dst_type>::
+execute_forward_1d(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const dst_data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ prepare_padded_bias(bias, this->scratchpad(ctx));
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+
+ const auto &jcp = pd()->jcp_;
+ assert(jcp.nb_oc % jcp.nb_oc_blocking == 0);
+
+ int oc_chunks = jcp.nb_oc / jcp.nb_oc_blocking;
+ int work_amount = jcp.mb * jcp.ngroups * oc_chunks * jcp.nb_ow;
+
+ int nthr;
+ if (jcp.aligned_threads)
+ nthr = jcp.aligned_threads;
+ else
+ nthr = mkldnn_get_max_threads();
+
+ parallel(nthr, [&](const int ithr, const int nthr) {
+ int start{0}, end{0}, start_copy;
+ balance211(work_amount, nthr, ithr, start, end);
+ start_copy = start;
+
+ auto par_conv = jit_conv_call_s();
+ size_t src_c_stride = src_d.blk_off(0, 1);
+ size_t wht_ic_stride = wht_blk_off(weights_d, 0, 0, 1);
+
+ for (int icb_l2 = 0 ; icb_l2 < jcp.nb_ic; icb_l2 += jcp.nb_ic_L2) {
+ start = start_copy;
+ int n{0}, g{0}, occ{0}, owb{0};
+
+ if (jcp.loop_order == loop_cwgn) {
+ int dummy{0};
+ nd_iterator_init(start, occ, oc_chunks, owb, jcp.nb_ow,
+ g, jcp.ngroups, n, jcp.mb, dummy, 1);
+ } else if (jcp.loop_order == loop_gncw) {
+ int dummy{0};
+ nd_iterator_init(start, g, jcp.ngroups, n, jcp.mb, occ,
+ oc_chunks, owb, jcp.nb_ow, dummy, 1);
+ } else {
+ assert(!"unsupported loop order");
+ }
+
+ while (start < end) {
+ int ocb = occ * jcp.nb_oc_blocking;
+ int g_ocb = g * jcp.nb_oc + ocb;
+ int g_oc = g_ocb * jcp.oc_block;
+ int g_icb = g * jcp.nb_ic * jcp.nonblk_group_off;
+
+ int ow_s = owb * jcp.ow_block;
+ int iw_s = ow_s * jcp.stride_w;
+ auto bias_w = bias ? bias + g_oc : nullptr;
+ auto dst_w = dst + dst_d.blk_off(n, g_ocb, ow_s);
+ auto src_w = src + src_d.blk_off(n, g_icb + icb_l2, iw_s);
+ auto wht_w = weights + wht_blk_off(weights_d, g, ocb, icb_l2);
+
+ for (int icb = icb_l2;
+ icb < min(jcp.nb_ic, icb_l2 + jcp.nb_ic_L2); ++icb) {
+ jit_conv_ker_pipeline_ow_thr(kernel_->jit_ker, par_conv,
+ src_w, dst_w, wht_w, bias_w, icb, 1, owb);
+
+ src_w += src_c_stride;
+ wht_w += wht_ic_stride;
+ }
+ if (jcp.loop_order == loop_cwgn) {
+ int dummy{0};
+ nd_iterator_jump(start, end, occ, oc_chunks, owb, jcp.nb_ow,
+ g, jcp.ngroups, n, jcp.mb, dummy, 1);
+ } else if (jcp.loop_order == loop_gncw) {
+ int dummy{0};
+ nd_iterator_jump(start, end, g, jcp.ngroups, n, jcp.mb,
+ occ, oc_chunks, owb, jcp.nb_ow, dummy, 1);
+ } else {
+ assert(!"unsupported loop order");
+ }
+ }
+ }
+ jit_conv_ker_pipeline_ow_thr(kernel_->jit_ker, par_conv,
+ src, dst, weights, bias, 0, 0, 0);
+ });
+}
+
+template <data_type_t src_type, data_type_t wei_type,
+ data_type_t dst_type>
+void jit_avx512_common_convolution_fwd_t<src_type, wei_type, dst_type>::
+execute_forward_2d(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const dst_data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ prepare_padded_bias(bias, this->scratchpad(ctx));
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+
+ const auto &jcp = pd()->jcp_;
+ assert(jcp.nb_oc % jcp.nb_oc_blocking == 0);
+
+ int oc_chunks = jcp.nb_oc / jcp.nb_oc_blocking;
+ int work_amount = jcp.mb * jcp.ngroups * oc_chunks * jcp.oh * jcp.nb_ow;
+
+ int nthr;
+ if (jcp.aligned_threads)
+ nthr = jcp.aligned_threads;
+ else
+ nthr = mkldnn_get_max_threads();
+
+ parallel(nthr, [&](const int ithr, const int nthr) {
+ int start{0}, end{0}, start_copy;
+ balance211(work_amount, nthr, ithr, start, end);
+ start_copy = start;
+
+ auto par_conv = jit_conv_call_s();
+ size_t src_h_stride = src_d.blk_off(0, 0, 1);
+ size_t src_c_stride = src_d.blk_off(0, 1);
+ size_t dst_h_stride = dst_d.blk_off(0, 0, 1);
+ size_t wht_h_stride = wht_blk_off(weights_d, 0, 0, 0, 1);
+ size_t wht_ic_stride = wht_blk_off(weights_d, 0, 0, 1);
+
+ for (int icb_l2 = 0 ; icb_l2 < jcp.nb_ic; icb_l2 += jcp.nb_ic_L2) {
+ start = start_copy;
+ int n{0}, g{0}, occ{0}, oh_s{0}, owb{0};
+
+ if (jcp.loop_order == loop_cwgn)
+ nd_iterator_init(start, occ, oc_chunks, owb, jcp.nb_ow,
+ g, jcp.ngroups, n, jcp.mb, oh_s, jcp.oh);
+ else if (jcp.loop_order == loop_gncw)
+ nd_iterator_init(start, g, jcp.ngroups, n, jcp.mb,
+ occ, oc_chunks, owb, jcp.nb_ow, oh_s, jcp.oh);
+ else
+ assert(!"unsupported loop order");
+
+ while (start < end) {
+ int ocb = occ * jcp.nb_oc_blocking;
+ int g_ocb = g * jcp.nb_oc + ocb;
+ int g_oc = g_ocb * jcp.oc_block;
+ int g_icb = g * jcp.nb_ic * jcp.nonblk_group_off;
+
+ int work_rem = end - start;
+
+ int ow_s = owb * jcp.ow_block;
+ int iw_s = ow_s * jcp.stride_w;
+ int oh_e = oh_s + work_rem > jcp.oh ? jcp.oh : oh_s + work_rem;
+ auto bias_w = bias ? bias + g_oc : nullptr;
+
+ for (int oh_b = oh_s; oh_b < oh_e; oh_b += jcp.h_blocking) {
+ int ih_b = -jcp.t_pad + oh_b * jcp.stride_h;
+
+ auto dst_w = dst + dst_d.blk_off(n, g_ocb, oh_b, ow_s);
+ auto src_w
+ = src + src_d.blk_off(n, g_icb + icb_l2, ih_b, iw_s);
+ auto wht_w
+ = weights + wht_blk_off(weights_d, g, ocb, icb_l2);
+
+ for (int icb = icb_l2;
+ icb < min(jcp.nb_ic, icb_l2 + jcp.nb_ic_L2);
+ ++icb) {
+ auto src_c = src_w;
+ auto dst_c = dst_w;
+ for (int oj = oh_b, ij = ih_b;
+ oj < min(oh_e, oh_b + jcp.h_blocking);
+ ++oj, ij += jcp.stride_h) {
+ int dilate_h = jcp.dilate_h + 1;
+ int i_t_overflow = div_up(max(0, -ij), dilate_h);
+ int i_b_overflow = div_up(max(0, ij - jcp.ih
+ + (jcp.kh - 1) * dilate_h + 1), dilate_h);
+ int kh_padding = nstl::max(
+ 0, jcp.kh - i_t_overflow - i_b_overflow);
+
+ auto aux_src = src_c
+ + i_t_overflow * dilate_h * src_h_stride;
+ auto aux_wht = wht_w + i_t_overflow * wht_h_stride;
+
+ jit_conv_ker_pipeline_ow_thr(kernel_->jit_ker,
+ par_conv, aux_src, dst_c, aux_wht, bias_w, icb,
+ kh_padding, owb);
+
+ src_c += src_h_stride * jcp.stride_h;
+ dst_c += dst_h_stride;
+ }
+ src_w += src_c_stride;
+ wht_w += wht_ic_stride;
+ }
+ }
+
+ if (jcp.loop_order == loop_cwgn)
+ nd_iterator_jump(start, end, occ, oc_chunks, owb, jcp.nb_ow,
+ g, jcp.ngroups, n, jcp.mb, oh_s, jcp.oh);
+ else if (jcp.loop_order == loop_gncw)
+ nd_iterator_jump(start, end, g, jcp.ngroups, n, jcp.mb, occ,
+ oc_chunks, owb, jcp.nb_ow, oh_s, jcp.oh);
+ else
+ assert(!"unsupported loop order");
+ }
+ }
+
+ jit_conv_ker_pipeline_ow_thr(kernel_->jit_ker, par_conv,
+ src, dst, weights, bias, 0, 0, 0);
+ });
+}
+
+template <data_type_t src_type, data_type_t wei_type,
+ data_type_t dst_type>
+void jit_avx512_common_convolution_fwd_t<src_type, wei_type, dst_type>::
+execute_forward_3d(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const dst_data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ prepare_padded_bias(bias, this->scratchpad(ctx));
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ const auto &jcp = pd()->jcp_;
+ assert(jcp.nb_oc % jcp.nb_oc_blocking == 0);
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ int oc_chunks = jcp.nb_oc / jcp.nb_oc_blocking;
+ int start{0}, end{0}, start_copy;
+ int work_amount = jcp.mb * jcp.ngroups * oc_chunks * jcp.od * jcp.oh
+ * jcp.nb_ow;
+ balance211(work_amount, nthr, ithr, start, end);
+ start_copy = start;
+
+ auto par_conv = jit_conv_call_s();
+ size_t src_d_stride = src_d.blk_off(0, 0, 1);
+ size_t src_h_stride = src_d.blk_off(0, 0, 0, 1);
+ size_t src_c_stride = src_d.blk_off(0, 1);
+ size_t dst_h_stride = dst_d.blk_off(0, 0, 0, 1);
+ size_t wht_d_stride = wht_blk_off(weights_d, 0, 0, 0, 1);
+ size_t wht_h_stride = wht_blk_off(weights_d, 0, 0, 0, 0, 1);
+ size_t wht_ic_stride = wht_blk_off(weights_d, 0, 0, 1);
+
+ for (int icb_l2 = 0 ; icb_l2 < jcp.nb_ic; icb_l2 += jcp.nb_ic_L2) {
+ start = start_copy;
+ int n{0}, g{0}, occ{0}, oh_s{0}, od_s{0}, owb{0};
+
+ if (jcp.loop_order == loop_cwgn)
+ nd_iterator_init(start,
+ occ, oc_chunks, owb, jcp.nb_ow, g, jcp.ngroups, n, jcp.mb,
+ od_s, jcp.od, oh_s, jcp.oh);
+ else if (jcp.loop_order == loop_gncw)
+ nd_iterator_init(start,
+ g, jcp.ngroups, n, jcp.mb, occ, oc_chunks, owb, jcp.nb_ow,
+ od_s, jcp.od, oh_s, jcp.oh);
+ else
+ assert(!"unsupported loop order");
+
+ while (start < end) {
+ int ocb = occ * jcp.nb_oc_blocking;
+ int g_ocb = g * jcp.nb_oc + ocb;
+ int g_oc = g_ocb * jcp.oc_block;
+ int g_icb = g * jcp.nb_ic * jcp.nonblk_group_off;
+
+ int work_rem = end - start;
+ int ih_s = -jcp.t_pad + oh_s * jcp.stride_h;
+ int ow_s = owb * jcp.ow_block;
+ int iw_s = ow_s * jcp.stride_w;
+ int oh_e = oh_s + work_rem > jcp.oh ? jcp.oh : oh_s + work_rem;
+
+ int id_s = -jcp.f_pad + od_s * jcp.stride_d;
+
+ int dilate_d = jcp.dilate_d + 1;
+ int d_t_overflow = div_up(max(0, -id_s), dilate_d);
+ int d_b_overflow = div_up(
+ max(0, id_s - jcp.id + (jcp.kd - 1) * dilate_d + 1),
+ dilate_d);
+ int kd_padding = nstl::max(0,
+ jcp.kd - d_t_overflow - d_b_overflow);
+
+ auto bias_w = bias ? bias + bias_d.blk_off(g_oc) : 0;
+ auto dst_w = dst + dst_d.blk_off(n, g_ocb, od_s, oh_s, ow_s);
+ auto src_w = src + src_d.blk_off(n, g_icb + icb_l2, id_s, ih_s,
+ iw_s) + d_t_overflow * dilate_d * src_d_stride;
+ auto wht_w = weights + wht_blk_off(weights_d, g, ocb, icb_l2)
+ + d_t_overflow * wht_d_stride;
+
+ for (int icb = icb_l2;
+ icb < min(jcp.nb_ic, icb_l2 + jcp.nb_ic_L2); ++icb) {
+ auto src_c = src_w;
+ auto dst_c = dst_w;
+ for (int oj = oh_s, ij = ih_s;
+ oj < oh_e; ++oj, ij += jcp.stride_h)
+ {
+ int dilate_h = jcp.dilate_h + 1;
+ int i_t_overflow = div_up(max(0, -ij), dilate_h);
+ int i_b_overflow = div_up(
+ max(0, ij - jcp.ih + (jcp.kh - 1) * dilate_h
+ + 1),
+ dilate_h);
+ int kh_padding = nstl::max(0,
+ jcp.kh - i_t_overflow - i_b_overflow);
+ jit_conv_3d_ker_pipeline_ow_thr(kernel_->jit_ker,
+ par_conv,
+ src_c + i_t_overflow * dilate_h * src_h_stride,
+ dst_c, wht_w + i_t_overflow * wht_h_stride,
+ bias_w, icb, kh_padding, kd_padding, owb);
+
+ src_c += src_h_stride * jcp.stride_h;
+ dst_c += dst_h_stride;
+ }
+ src_w += src_c_stride;
+ wht_w += wht_ic_stride;
+ }
+
+ if (jcp.loop_order == loop_cwgn)
+ nd_iterator_jump(start, end,
+ occ, oc_chunks, owb, jcp.nb_ow, g, jcp.ngroups, n, jcp.mb,
+ od_s, jcp.od, oh_s, jcp.oh);
+ else if (jcp.loop_order == loop_gncw)
+ nd_iterator_jump(start, end,
+ g, jcp.ngroups, n, jcp.mb, occ, oc_chunks, owb, jcp.nb_ow,
+ od_s, jcp.od, oh_s, jcp.oh);
+ else
+ assert(!"unsupported loop order");
+ }
+ }
+ jit_conv_3d_ker_pipeline(kernel_->jit_ker, par_conv,
+ src, dst, weights, bias, 0, 0, 0);
+ });
+}
+
+template struct jit_avx512_common_convolution_fwd_t<data_type::f32>;
+
+template <data_type_t diff_dst_type, data_type_t wei_type,
+ data_type_t diff_src_type>
+void jit_avx512_common_convolution_bwd_data_t<diff_dst_type, wei_type,
+ diff_src_type>::execute_backward_data_1d(const exec_ctx_t &ctx) const
+{
+ auto diff_dst = CTX_IN_MEM(const diff_dst_data_t *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(diff_src_data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ int start{0}, end{0}, start_copy;
+ int ic_chunks = jcp.nb_ic / jcp.nb_ic_blocking;
+ int work_amount = jcp.ngroups * jcp.mb * ic_chunks * jcp.ih;
+ balance211(work_amount, nthr, ithr, start, end);
+ start_copy = start;
+
+ auto par_conv = jit_conv_call_s();
+ size_t diff_dst_c_stride = diff_dst_d.blk_off(0, 1);
+ size_t wht_oc_stride = wht_blk_off(weights_d, 0, 1);
+
+ for (int ocb_l2 = 0; ocb_l2 < jcp.nb_oc; ocb_l2 += jcp.nb_oc_L2) {
+ start = start_copy;
+ int n{0}, g{0}, icc{0};
+ if (jcp.loop_order == loop_cgn) {
+ int dummy{0};
+ nd_iterator_init(start, icc, ic_chunks, g, jcp.ngroups, n,
+ jcp.mb, dummy, 1);
+ } else if (jcp.loop_order == loop_gnc) {
+ int dummy{0};
+ nd_iterator_init(start, g, jcp.ngroups, n, jcp.mb, icc,
+ ic_chunks, dummy, 1);
+ } else {
+ assert(!"unsupported loop order");
+ }
+
+ while (start < end) {
+ int icb = icc * jcp.nb_ic_blocking;
+ int g_icb = g * jcp.nb_ic + icb;
+ int g_ocb = g * jcp.nb_oc;
+
+ auto diff_src_w = diff_src + diff_src_d.blk_off(n, g_icb);
+ auto diff_dst_w = diff_dst
+ + diff_dst_d.blk_off(n, g_ocb + ocb_l2);
+ auto wht_w = weights + wht_blk_off(weights_d, g, ocb_l2, icb);
+
+ for (int ocb = ocb_l2;
+ ocb < min(jcp.nb_oc, ocb_l2 + jcp.nb_oc_L2); ++ocb) {
+ jit_conv_ker_pipeline(kernel_->jit_ker, par_conv,
+ diff_src_w, diff_dst_w, wht_w, 0, ocb, 1);
+ diff_dst_w += diff_dst_c_stride;
+ wht_w += wht_oc_stride;
+ }
+
+ if (jcp.loop_order == loop_cgn) {
+ int dummy{0};
+ nd_iterator_jump(start, end, icc, ic_chunks, g, jcp.ngroups,
+ n, jcp.mb, dummy, 1);
+ } else if (jcp.loop_order == loop_gnc) {
+ int dummy{0};
+ nd_iterator_jump(start, end, g, jcp.ngroups, n, jcp.mb, icc,
+ ic_chunks, dummy, 1);
+ } else {
+ assert(!"unsupported loop order");
+ }
+ }
+ }
+
+ jit_conv_ker_pipeline(kernel_->jit_ker, par_conv,
+ diff_src, diff_dst, weights, 0, 0, 1);
+ });
+}
+
+template <data_type_t diff_dst_type, data_type_t wei_type,
+ data_type_t diff_src_type>
+void jit_avx512_common_convolution_bwd_data_t<diff_dst_type, wei_type,
+ diff_src_type>::execute_backward_data_2d(const exec_ctx_t &ctx) const
+{
+ auto diff_dst = CTX_IN_MEM(const diff_dst_data_t *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(diff_src_data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ int start{0}, end{0}, start_copy;
+ int ic_chunks = jcp.nb_ic / jcp.nb_ic_blocking;
+ int work_amount = jcp.ngroups * jcp.mb * ic_chunks * jcp.ih;
+ balance211(work_amount, nthr, ithr, start, end);
+ start_copy = start;
+
+ auto par_conv = jit_conv_call_s();
+ size_t diff_src_h_stride = diff_src_d.blk_off(0, 0, 1);
+ size_t diff_dst_h_stride = diff_dst_d.blk_off(0, 0, 1);
+ size_t diff_dst_c_stride = diff_dst_d.blk_off(0, 1);
+ size_t wht_h_stride = wht_blk_off(weights_d, 0, 0, 0, 1);
+ size_t wht_oc_stride = wht_blk_off(weights_d, 0, 1);
+
+ bool is_fast_path = jcp.dilate_h == 0 && jcp.stride_h == 1;
+
+ for (int ocb_l2 = 0; ocb_l2 < jcp.nb_oc; ocb_l2 += jcp.nb_oc_L2) {
+ start = start_copy;
+ int n{0}, g{0}, icc{0}, ih_s{0};
+ if (jcp.loop_order == loop_cgn)
+ nd_iterator_init(start,
+ icc, ic_chunks, g, jcp.ngroups, n, jcp.mb, ih_s, jcp.ih);
+ else if (jcp.loop_order == loop_gnc)
+ nd_iterator_init(start,
+ g, jcp.ngroups, n, jcp.mb, icc, ic_chunks, ih_s, jcp.ih);
+ else
+ assert(!"unsupported loop order");
+
+ while (start < end) {
+ int icb = icc * jcp.nb_ic_blocking;
+ int g_icb = g * jcp.nb_ic + icb;
+ int g_ocb = g * jcp.nb_oc;
+
+ int work_rem = end - start;
+ int ih_e = ih_s + work_rem > jcp.ih ? jcp.ih : ih_s + work_rem;
+
+ auto diff_src_w = diff_src + diff_src_d.blk_off(n, g_icb);
+ auto diff_dst_w = diff_dst
+ + diff_dst_d.blk_off(n, g_ocb + ocb_l2);
+ auto wht_w = weights + wht_blk_off(weights_d, g, ocb_l2, icb);
+
+ for (int ocb = ocb_l2;
+ ocb < min(jcp.nb_oc, ocb_l2 + jcp.nb_oc_L2); ++ocb) {
+ for (int ij = ih_s; ij < ih_e; ++ij) {
+ int oj, k_len, k_lo;
+ if (is_fast_path) { // dilate == 0 && stride == 1
+ int i_t_overflow = max(0, jcp.kh - 1 - ij
+ - jcp.t_pad);
+ int i_b_overflow = max(0, jcp.kh - jcp.ih + ij
+ - jcp.b_pad);
+ k_len = jcp.kh - i_t_overflow - i_b_overflow;
+ k_lo = i_b_overflow;
+ oj = ij + jcp.t_pad - i_b_overflow;
+ } else if (jcp.dilate_h != 0) { // stride == 1
+ int dilate_h = jcp.dilate_h + 1;
+ // Note: use div_up to account for "holes" in filter
+ int i_t_overflow
+ = div_up(max(0, (jcp.kh - 1) * dilate_h
+ - ij - jcp.t_pad), dilate_h);
+ int i_b_overflow
+ = div_up(max(0, (jcp.kh - 1) * dilate_h + 1
+ - jcp.ih + ij - jcp.b_pad), dilate_h);
+ k_len = jcp.kh - i_t_overflow - i_b_overflow;
+ k_lo = i_b_overflow;
+ oj = ij + jcp.t_pad - i_b_overflow * dilate_h;
+ } else { // dilate == 0
+ int i_t_overflow = max(0, (jcp.kh - 1 - ij
+ - jcp.t_pad) / jcp.stride_h);
+ int i_b_overflow = max(0, (jcp.kh - jcp.ih + ij
+ - jcp.b_pad) / jcp.stride_h);
+ int overflow_kh_hi = jcp.kh - 1 - abs((jcp.ih - 1
+ + jcp.b_pad - ij) % jcp.stride_h);
+ int overflow_kh_lo = (ij + jcp.t_pad)
+ % jcp.stride_h;
+
+ k_len = (overflow_kh_hi - overflow_kh_lo)
+ / jcp.stride_h + 1 - i_t_overflow
+ - i_b_overflow;
+ k_lo = overflow_kh_lo + i_b_overflow * jcp.stride_h;
+ oj = (ij + jcp.t_pad - k_lo) / jcp.stride_h;
+ }
+ assert(k_len >= 0);
+
+ jit_conv_ker_pipeline(kernel_->jit_ker, par_conv,
+ diff_src_w + ij * diff_src_h_stride,
+ diff_dst_w + oj * diff_dst_h_stride,
+ wht_w + k_lo * wht_h_stride,
+ 0, ocb, k_len);
+ }
+ diff_dst_w += diff_dst_c_stride;
+ wht_w += wht_oc_stride;
+ }
+
+ if (jcp.loop_order == loop_cgn)
+ nd_iterator_jump(start, end,
+ icc, ic_chunks, g, jcp.ngroups, n, jcp.mb, ih_s, jcp.ih);
+ else if (jcp.loop_order == loop_gnc)
+ nd_iterator_jump(start, end,
+ g, jcp.ngroups, n, jcp.mb, icc, ic_chunks, ih_s, jcp.ih);
+ else
+ assert(!"unsupported loop order");
+ }
+ }
+
+ jit_conv_ker_pipeline(kernel_->jit_ker, par_conv,
+ diff_src, diff_dst, weights, 0, 0, 1);
+ });
+}
+
+template <data_type_t diff_dst_type, data_type_t wei_type,
+ data_type_t diff_src_type>
+void jit_avx512_common_convolution_bwd_data_t<diff_dst_type, wei_type,
+ diff_src_type>::execute_backward_data_3d(const exec_ctx_t &ctx) const
+{
+ auto diff_dst = CTX_IN_MEM(const diff_dst_data_t *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(diff_src_data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ int start{0}, end{0}, start_copy;
+ int ic_chunks = jcp.nb_ic / jcp.nb_ic_blocking;
+ int work_amount = jcp.ngroups * jcp.mb * ic_chunks * jcp.id * jcp.ih;
+ balance211(work_amount, nthr, ithr, start, end);
+ start_copy = start;
+
+ auto par_conv = jit_conv_call_s();
+ size_t diff_src_h_stride = diff_src_d.blk_off(0, 0, 0, 1);
+ size_t diff_src_d_stride = diff_src_d.blk_off(0, 0, 1);
+ size_t diff_dst_h_stride = diff_dst_d.blk_off(0, 0, 0, 1);
+ size_t diff_dst_d_stride = diff_dst_d.blk_off(0, 0, 1);
+ size_t diff_dst_c_stride = diff_dst_d.blk_off(0, 1);
+ size_t wht_h_stride = wht_blk_off(weights_d, 0, 0, 0, 0, 1);
+ size_t wht_d_stride = wht_blk_off(weights_d, 0, 0, 0, 1);
+ size_t wht_oc_stride = wht_blk_off(weights_d, 0, 1);
+
+ bool is_fast_path_d = jcp.dilate_d == 0 && jcp.stride_d == 1;
+ bool is_fast_path_h = jcp.dilate_h == 0 && jcp.stride_h == 1;
+
+ for (int ocb_l2 = 0; ocb_l2 < jcp.nb_oc; ocb_l2 += jcp.nb_oc_L2) {
+ start = start_copy;
+ int n{0}, g{0}, icc{0}, ih_s{0}, id_s{0};
+ if (jcp.loop_order == loop_cgn)
+ nd_iterator_init(start,
+ icc, ic_chunks, g, jcp.ngroups, n, jcp.mb, id_s, jcp.id,
+ ih_s, jcp.ih);
+ else if (jcp.loop_order == loop_gnc)
+ nd_iterator_init(start,
+ g, jcp.ngroups, n, jcp.mb, icc, ic_chunks, id_s, jcp.id,
+ ih_s, jcp.ih);
+ else
+ assert(!"unsupported loop order");
+
+ while (start < end) {
+ int icb = icc * jcp.nb_ic_blocking;
+ int g_icb = g * jcp.nb_ic + icb;
+ int g_ocb = g * jcp.nb_oc;
+
+ int work_rem = end - start;
+ int ih_e = ih_s + work_rem > jcp.ih ? jcp.ih : ih_s + work_rem;
+ int d_len = 0, d_lo = 0, d_oj = 0;
+ if (is_fast_path_d) { // dilate == 0 && stride == 1
+ int d_t_overflow = max(0, jcp.kd - 1 - id_s
+ - jcp.f_pad);
+ int d_b_overflow = max(0, jcp.kd - jcp.id + id_s
+ - jcp.back_pad);
+ d_len = jcp.kd - d_t_overflow - d_b_overflow;
+ d_lo = d_b_overflow;
+ d_oj = id_s + jcp.f_pad - d_b_overflow;
+ } else if (jcp.dilate_d != 0) { // stride == 1
+ int dilate_d = jcp.dilate_d + 1;
+ // Note: use div_up to account for "holes" in filter
+ int d_t_overflow = div_up(max(0, (jcp.kd - 1) * dilate_d
+ - id_s - jcp.f_pad), dilate_d);
+ int d_b_overflow = div_up(max(0, (jcp.kd - 1) * dilate_d + 1
+ - jcp.id + id_s - jcp.back_pad), dilate_d);
+ d_len = jcp.kd - d_t_overflow - d_b_overflow;
+ d_lo = d_b_overflow;
+ d_oj = id_s + jcp.f_pad - d_b_overflow * dilate_d;
+ } else { // dilate == 0
+ int d_t_overflow = max(0, (jcp.kd - 1 - id_s
+ - jcp.f_pad) / jcp.stride_d);
+ int d_b_overflow = max(0, (jcp.kd - jcp.id + id_s
+ - jcp.back_pad) / jcp.stride_d);
+ int overflow_kd_hi = jcp.kd - 1 - abs((jcp.id - 1
+ + jcp.back_pad - id_s) % jcp.stride_d);
+ int overflow_kd_lo = (id_s + jcp.f_pad)
+ % jcp.stride_d;
+
+ d_len = (overflow_kd_hi - overflow_kd_lo)
+ / jcp.stride_d + 1 - d_t_overflow
+ - d_b_overflow;
+ d_lo = overflow_kd_lo + d_b_overflow * jcp.stride_d;
+ d_oj = (id_s + jcp.f_pad - d_lo) / jcp.stride_d;
+ }
+ assert(d_len >= 0);
+
+ auto diff_src_w = diff_src + diff_src_d.blk_off(n, g_icb)
+ + id_s * diff_src_d_stride;
+ auto diff_dst_w = diff_dst
+ + diff_dst_d.blk_off(n, g_ocb + ocb_l2)
+ + d_oj * diff_dst_d_stride;
+ auto wht_w = weights + wht_blk_off(weights_d, g, ocb_l2, icb)
+ + d_lo * wht_d_stride;
+
+ for (int ocb = ocb_l2;
+ ocb < min(jcp.nb_oc, ocb_l2 + jcp.nb_oc_L2); ++ocb) {
+ for (int ij = ih_s; ij < ih_e; ++ij) {
+ int oj, k_len, k_lo;
+ if (is_fast_path_h) { // dilate == 0 && stride == 1
+ int i_t_overflow = max(0, jcp.kh - 1 - ij
+ - jcp.t_pad);
+ int i_b_overflow = max(0, jcp.kh - jcp.ih + ij
+ - jcp.b_pad);
+ k_len = jcp.kh - i_t_overflow - i_b_overflow;
+ k_lo = i_b_overflow;
+ oj = ij + jcp.t_pad - i_b_overflow;
+ } else if (jcp.dilate_h != 0) { // stride == 1
+ int dilate_h = jcp.dilate_h + 1;
+ // Note: use div_up to account for "holes" in filter
+ int i_t_overflow
+ = div_up(max(0, (jcp.kh - 1) * dilate_h
+ - ij - jcp.t_pad), dilate_h);
+ int i_b_overflow
+ = div_up(max(0, (jcp.kh - 1) * dilate_h + 1
+ - jcp.ih + ij - jcp.b_pad), dilate_h);
+ k_len = jcp.kh - i_t_overflow - i_b_overflow;
+ k_lo = i_b_overflow;
+ oj = ij + jcp.t_pad - i_b_overflow * dilate_h;
+ } else { // dilate == 0
+ int i_t_overflow = max(0, (jcp.kh - 1 - ij
+ - jcp.t_pad) / jcp.stride_h);
+ int i_b_overflow = max(0, (jcp.kh - jcp.ih + ij
+ - jcp.b_pad) / jcp.stride_h);
+ int overflow_kh_hi = jcp.kh - 1 - abs((jcp.ih - 1
+ + jcp.b_pad - ij) % jcp.stride_h);
+ int overflow_kh_lo = (ij + jcp.t_pad)
+ % jcp.stride_h;
+
+ k_len = (overflow_kh_hi - overflow_kh_lo)
+ / jcp.stride_h + 1 - i_t_overflow
+ - i_b_overflow;
+ k_lo = overflow_kh_lo + i_b_overflow * jcp.stride_h;
+ oj = (ij + jcp.t_pad - k_lo) / jcp.stride_h;
+ }
+ assert(k_len >= 0);
+
+ jit_conv_3d_ker_pipeline(kernel_->jit_ker, par_conv,
+ diff_src_w + ij * diff_src_h_stride,
+ diff_dst_w + oj * diff_dst_h_stride,
+ wht_w + k_lo * wht_h_stride,
+ 0, ocb, k_len, d_len);
+ }
+ diff_dst_w += diff_dst_c_stride;
+ wht_w += wht_oc_stride;
+ }
+
+ if (jcp.loop_order == loop_cgn)
+ nd_iterator_jump(start, end,
+ icc, ic_chunks, g, jcp.ngroups, n, jcp.mb, id_s, jcp.id,
+ ih_s, jcp.ih);
+ else if (jcp.loop_order == loop_gnc)
+ nd_iterator_jump(start, end,
+ g, jcp.ngroups, n, jcp.mb, icc, ic_chunks, id_s, jcp.id,
+ ih_s, jcp.ih);
+ else
+ assert(!"unsupported loop order");
+ }
+ }
+
+ jit_conv_3d_ker_pipeline(kernel_->jit_ker, par_conv,
+ diff_src, diff_dst, weights, 0, 0, 1, 1);
+ });
+}
+
+template struct jit_avx512_common_convolution_bwd_data_t<data_type::f32>;
+
+template <data_type_t src_type, data_type_t diff_dst_type,
+ data_type_t diff_weights_type>
+jit_avx512_common_convolution_bwd_weights_t<src_type, diff_dst_type,
+ diff_weights_type>::
+jit_avx512_common_convolution_bwd_weights_t(const pd_t *apd)
+ : cpu_primitive_t(apd), kernel_(nullptr)
+ , trans_kernel_(nullptr), acc_ker_(nullptr), reducer_bias_(nullptr)
+{
+ const auto &j = pd()->jcp_;
+
+ nthr_ = j.nthr;
+ nthr_mb_ = j.nthr_mb;
+ nthr_g_ = j.nthr_g;
+ nthr_oc_b_ = j.nthr_oc_b;
+ nthr_ic_b_ = j.nthr_ic_b;
+
+ kernel_ = new jit_avx512_common_conv_bwd_weights_kernel_f32(j);
+
+ if (j.ver == ver_4fma)
+ trans_kernel_ = create_trans_src(&j);
+
+ if (nthr_mb_ > 1)
+ acc_ker_ = new cpu_accumulator_1d_t<diff_weights_type>();
+
+ reducer_bias_ =
+ new cpu_reducer_t<diff_weights_type>(pd()->reducer_bia_conf_);
+}
+
+template <data_type_t src_type, data_type_t diff_dst_type,
+ data_type_t diff_weights_type>
+struct jit_avx512_common_convolution_bwd_weights_t<src_type, diff_dst_type,
+ diff_weights_type>::thread_info_t {
+ const src_data_t *src;
+ const diff_dst_data_t *diff_dst;
+ const diff_weights_data_t *diff_weights;
+ diff_weights_data_t *diff_bias;
+
+ const memory_tracking::grantor_t scratchpad;
+
+ src_data_t *tr_src;
+ simple_barrier::ctx_t *tr_src_bctx;
+
+ diff_dst_data_t *tr_diff_dst;
+ simple_barrier::ctx_t *tr_diff_dst_bctx;
+
+ diff_weights_data_t *wei_bia_reduction;
+ simple_barrier::ctx_t *wei_bia_reduction_bctx;
+
+ int ithr;
+ int ithr_ic_b, ithr_oc_b, ithr_g, ithr_mb;
+ int ithr_but_oc;
+ int ithr_but_ic;
+
+ int img_start = 0, img_end = 0, img_work;
+ int g_start = 0, g_end = 0, g_work;
+ int oc_b_start = 0, oc_b_end = 0, oc_b_work;
+ int ic_b_start = 0, ic_b_end = 0, ic_b_work;
+
+ thread_info_t(const jit_avx512_common_convolution_bwd_weights_t *self,
+ const exec_ctx_t &ctx, int ithr)
+ : scratchpad(self->scratchpad(ctx)), ithr(ithr)
+ {
+ diff_dst = CTX_IN_MEM(const diff_dst_data_t *, MKLDNN_ARG_DIFF_DST);
+ src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ diff_weights = CTX_OUT_MEM(diff_weights_data_t *, MKLDNN_ARG_DIFF_WEIGHTS);
+ diff_bias = self->pd()->wants_padded_bias()
+ ? scratchpad.template get<diff_weights_data_t>(
+ key_conv_padded_bias)
+ : CTX_OUT_MEM(diff_weights_data_t *, MKLDNN_ARG_DIFF_BIAS);
+
+ tr_src = scratchpad.template get<src_data_t>(key_conv_tr_src);
+ tr_src_bctx = scratchpad.template get<simple_barrier::ctx_t>(
+ key_conv_tr_src_bctx);
+
+ tr_diff_dst = scratchpad.template get<diff_dst_data_t>(
+ key_conv_tr_diff_dst);
+ tr_diff_dst_bctx = scratchpad.template get<simple_barrier::ctx_t>(
+ key_conv_tr_diff_dst_bctx);
+
+ wei_bia_reduction = scratchpad.template get<diff_weights_data_t>(
+ key_conv_wei_bia_reduction);
+ wei_bia_reduction_bctx = scratchpad.template get<simple_barrier::ctx_t>(
+ key_conv_wei_bia_reduction_bctx);
+
+ ithr_ic_b = ithr % self->nthr_ic_b_;
+ ithr_oc_b = ithr / self->nthr_ic_b_ % self->nthr_oc_b_;
+ ithr_g = ithr / self->nthr_ic_b_ / self->nthr_oc_b_ % self->nthr_g_;
+ ithr_mb = ithr / self->nthr_ic_b_ / self->nthr_oc_b_ / self->nthr_g_;
+
+ ithr_but_oc = (ithr_mb * self->nthr_g_ + ithr_g) * self->nthr_ic_b_
+ + ithr_ic_b;
+
+ ithr_but_ic = (ithr_mb * self->nthr_g_ + ithr_g) * self->nthr_oc_b_
+ + ithr_oc_b;
+
+ const auto &jcp = self->kernel_->jcp;
+
+ /* reduction dimension */
+ balance211(jcp.mb*jcp.od, self->nthr_mb_, ithr_mb, img_start, img_end);
+ img_work = img_end - img_start;
+
+ /* independent dimensions */
+ balance211(jcp.ngroups, self->nthr_g_, ithr_g, g_start, g_end);
+ g_work = g_end - g_start;
+
+ balance211(jcp.nb_oc, self->nthr_oc_b_, ithr_oc_b, oc_b_start,
+ oc_b_end);
+ oc_b_work = oc_b_end - oc_b_start;
+
+ balance211(jcp.nb_ic, self->nthr_ic_b_, ithr_ic_b, ic_b_start,
+ ic_b_end);
+ ic_b_work = ic_b_end - ic_b_start;
+ }
+};
+
+template <data_type_t src_type, data_type_t diff_dst_type,
+ data_type_t diff_weights_type>
+void jit_avx512_common_convolution_bwd_weights_t<src_type, diff_dst_type,
+ diff_weights_type>::compute_diff_weights(const thread_info_t *ti) const {
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_weights_d(pd()->diff_weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+ const int wei_size = jcp.ngroups * jcp.oc * jcp.ic * jcp.kh*jcp.kw*jcp.kd;
+
+ diff_weights_data_t *diff_wei = ti->ithr_mb == 0
+ ? (diff_weights_data_t*)ti->diff_weights
+ : ti->wei_bia_reduction + (ti->ithr_mb - 1) * wei_size;
+ diff_weights_data_t *diff_bia = ti->ithr_mb == 0
+ ? (diff_weights_data_t*)ti->diff_bias
+ : ti->wei_bia_reduction + (nthr_mb_ - 1) * wei_size
+ + (ti->ithr_mb - 1) * jcp.ngroups * jcp.oc;
+
+ // TODO: use memory descriptor with the same fmt as src (or use a macro :))
+ auto tr_src_off = [&](int ithr_mb, int ic, int ij) {
+ const size_t tr_row_size = jcp.tr_iw * jcp.ic_block;
+ const size_t tr_chn_size = tr_row_size * jcp.ih;
+ const size_t tr_img_size = tr_chn_size * jcp.nb_ic * jcp.ngroups;
+
+ return ti->ithr_mb * tr_img_size + ic * tr_chn_size + ij * tr_row_size;
+ };
+
+ auto uker_trans = [&](int img) {
+ const int work_amount = ti->g_work * ti->ic_b_work * jcp.ih;
+
+ int start{0}, end{0};
+ balance211(work_amount, nthr_oc_b_, ti->ithr_oc_b, start, end);
+ const int my_work = end - start;
+
+ int g{0}, ic_b{0}, j{0};
+ nd_iterator_init(start, g, ti->g_work, ic_b, ti->ic_b_work, j, jcp.ih);
+ g += ti->g_start;
+ ic_b += ti->ic_b_start;
+
+ const int _ic = g * jcp.nb_ic + ic_b;
+ src_data_t *src1 = (src_data_t*)&ti->src[src_d.blk_off(img, _ic, j)];
+ src_data_t *tr_src1 = &ti->tr_src[tr_src_off(ti->ithr_mb, _ic, j)];
+
+ assert(jcp.ic_block == 16);
+ const int src_stride = jcp.iw * jcp.ic_block;
+ const int tr_src_stride = jcp.tr_iw * jcp.ic_block;
+
+ const int pf_depth = 2;
+ struct { src_data_t *src, *tr_src; } pf_circ_buf[pf_depth];
+
+ for (int iwork = 0; iwork < my_work + pf_depth - 1; iwork++) {
+ pf_circ_buf[iwork % pf_depth] = {src1, tr_src1};
+
+ if (iwork >= pf_depth - 1) {
+ int old_idx = (iwork - pf_depth + 1) % pf_depth;
+ auto ctx = jit_trans_src_t::ctx_t();
+ ctx.src = pf_circ_buf[old_idx].src;
+ ctx.tr_src = pf_circ_buf[old_idx].tr_src;
+ ctx.src_prf = src1;
+ ctx.tr_src_prf = tr_src1;
+ (*trans_kernel_)(&ctx);
+ }
+ src1 += src_stride;
+ tr_src1 += tr_src_stride;
+ }
+#if 0
+ // reference transposition
+ const int l_pad = jcp.l_pad;
+ const int iwlp = l_pad + jcp.iw;
+ const int tr_iw = jcp.tr_iw;
+
+ for (size_t iwork = start; iwork < end; iwork++) {
+ PRAGMA_OMP_SIMD()
+# pragma unroll
+ for (int i = 0; i < l_pad; i++)
+ for (int j = 0; j < jcp.ic_block; j++)
+ tr_src1[j * jcp.tr_iw + i] = (src_data_t)0.0;
+
+ PRAGMA_OMP_SIMD()
+# pragma unroll
+ for (int i = l_pad; i < iwlp; i++)
+ for (int j = 0; j < jcp.ic_block; j++)
+ tr_src1[j * jcp.tr_iw + i]
+ = (src_data_t)src1[(i - l_pad) * 16 + j];
+
+ PRAGMA_OMP_SIMD()
+# pragma unroll
+ for (int i = iwlp; i < tr_iw; i++)
+ for (int j = 0; j < jcp.ic_block; j++)
+ tr_src1[j * jcp.tr_iw + i] = (src_data_t)0.0;
+
+ src1 += src_stride;
+ tr_src1 += tr_src_stride;
+ }
+#endif
+ };
+
+ if (jcp.is_1stconv && jcp.ver == ver_4fma) {
+ /* prepare contexts */
+ auto tr_ctx = jit_trans_src_t::ctx_t();
+ tr_ctx.tr_src = ti->tr_src
+ + ti->ithr_but_oc * jcp.ih * jcp.stride_w * jcp.tr_ld;
+
+ assert(IMPLICATION(!mkldnn_thr_syncable(), nthr_oc_b_ == 1));
+ tr_ctx.nthr_oc_b = nthr_oc_b_;
+ int ih_start{0}, ih_end{0};
+ balance211(jcp.ih, nthr_oc_b_, ti->ithr_oc_b, ih_start, ih_end);
+ tr_ctx.tr_src_ih_start = ih_start;
+ tr_ctx.tr_src_ih_end = ih_end;
+ tr_ctx.tr_src_bctx = ti->tr_src_bctx + ti->ithr_but_oc;
+
+ auto p = jit_conv_call_s();
+ p.src = tr_ctx.tr_src;
+
+ /* zero diff_bias if applicable */
+ if (jcp.with_bias && ti->ithr_ic_b == 0) {
+ assert(jcp.oc_block == 16);
+ for (int oc_b = ti->ic_b_start; oc_b < ti->oc_b_end; ++oc_b) {
+ diff_weights_data_t *db = &diff_bia[oc_b * 16];
+ for (int o = 0; o < 16; ++o)
+ db[o] = 0;
+ }
+ }
+
+ for (int img = ti->img_start; img < ti->img_end; ++img) {
+ p.flags = (img == ti->img_start) * FLAG_MB_FIRST;
+
+ for (int g = ti->g_start; g < ti->g_end; ++g) {
+ for (int ic_b = ti->ic_b_start; ic_b < ti->ic_b_end; ++ic_b) {
+ const int _ic = g * jcp.nb_ic + ic_b;
+ tr_ctx.src = &ti->src[src_d.blk_off(img, _ic)];
+
+ (*trans_kernel_)(&tr_ctx);
+
+ if (ic_b == 0)
+ p.flags |= FLAG_IC_FIRST;
+ else
+ p.flags &= ~FLAG_IC_FIRST;
+
+ for (int oc_b = ti->oc_b_start; oc_b < ti->oc_b_end; ++oc_b) {
+ const int _oc = g * jcp.nb_oc + oc_b;
+ p.dst = &ti->diff_dst[diff_dst_d.blk_off(img, _oc)];
+
+ const size_t off =
+ wht_blk_off(diff_weights_d, g, oc_b, ic_b);
+ p.filt = diff_wei + off;
+ p.bias = diff_bia + _oc * jcp.oc_block;
+
+ kernel_->jit_ker(&p);
+ }
+ }
+ }
+ }
+ } else {
+ for (int img = ti->img_start; img < ti->img_end; ++img) {
+ auto p = jit_conv_call_s();
+
+ if (jcp.ver == ver_4fma) {
+ /* tr_src[nb_ic][ih][16][~iw~] <- src[nb_ic][ih][iw][16] */
+ using simple_barrier::barrier;
+ if (nthr_oc_b_ > 1)
+ barrier(&ti->tr_src_bctx[ti->ithr_but_oc], nthr_oc_b_);
+ uker_trans(img);
+ if (nthr_oc_b_ > 1)
+ barrier(&ti->tr_src_bctx[ti->ithr_but_oc], nthr_oc_b_);
+ }
+
+ for (int g = ti->g_start; g < ti->g_end; ++g) {
+ for (int oc_b = ti->oc_b_start; oc_b < ti->oc_b_end; ++oc_b) {
+ for (int ic_b = ti->ic_b_start; ic_b < ti->ic_b_end; ++ic_b) {
+ const int _oc = g * jcp.nb_oc + oc_b;
+ const int _ic = g * jcp.nb_ic + ic_b;
+
+ jit_conv_ker_pipeline(kernel_->jit_ker, p,
+ jcp.ver == ver_4fma
+ ? &ti->tr_src[tr_src_off(ti->ithr_mb, _ic, 0)]
+ : &ti->src[src_d.blk_off(img, _ic)],
+ &ti->diff_dst[diff_dst_d.blk_off(img, _oc)],
+ diff_wei + wht_blk_off(diff_weights_d, g, oc_b, ic_b),
+ 0, (img == ti->img_start), 0);
+
+ }
+ }
+ }
+
+ const int _oc = ti->g_start * jcp.nb_oc + ti->oc_b_start;
+ const int _ic = ti->g_start * jcp.nb_ic + ti->ic_b_start;
+ jit_conv_ker_pipeline(kernel_->jit_ker, p,
+ jcp.ver == ver_4fma
+ ? &ti->tr_src[tr_src_off(ti->ithr_mb, _ic, 0)]
+ : &ti->src[src_d.blk_off(img + 1, _ic)],
+ &ti->diff_dst[diff_dst_d.blk_off(img + 1, _oc)],
+ diff_wei + wht_blk_off(
+ diff_weights_d, ti->g_start,
+ ti->oc_b_start, ti->ic_b_start),
+ 0, 0, 0);
+ }
+ }
+}
+
+template <data_type_t src_type, data_type_t diff_dst_type,
+ data_type_t diff_weights_type>
+void jit_avx512_common_convolution_bwd_weights_t<src_type, diff_dst_type,
+ diff_weights_type>::compute_diff_weights_3d(const thread_info_t *ti) const
+{
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_weights_d(pd()->diff_weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+ const int wei_size
+ = jcp.ngroups * jcp.oc * jcp.ic * jcp.kh * jcp.kw * jcp.kd;
+
+ diff_weights_data_t *diff_wei = ti->ithr_mb == 0
+ ? (diff_weights_data_t*)ti->diff_weights
+ : ti->wei_bia_reduction + (ti->ithr_mb - 1) * wei_size;
+ diff_weights_data_t *diff_bia = ti->ithr_mb == 0
+ ? (diff_weights_data_t*)ti->diff_bias
+ : ti->wei_bia_reduction + (nthr_mb_ - 1) * wei_size
+ + (ti->ithr_mb - 1) * jcp.ngroups * jcp.oc;
+
+ const int inp_mult = jcp.is_1stconv ? 1 : jcp.ic_block;
+ const int input_step = jcp.ih * jcp.iw * inp_mult;
+ const int output_step = jcp.ow * jcp.oh * jcp.oc_block;
+ int img{0}, od_s{0};
+ int img_start = ti->img_start, img_end = ti->img_end;
+ nd_iterator_init(img_start, img, jcp.mb, od_s, jcp.od);
+ const int img_first = img;
+
+ while (img_start < img_end) {
+ auto p = jit_conv_call_s();
+
+ int work_rem = img_end - img_start;
+ const int od_e = od_s + work_rem > jcp.od ? jcp.od : od_s + work_rem;
+ const int id_s = od_s * jcp.stride_d;
+ const int ik_overlap = nstl::max(0, id_s - jcp.f_pad);
+ const int kd_front_pad = nstl::max(0, jcp.f_pad - id_s);
+ const int kd_back_pad
+ = nstl::max(0, id_s - jcp.f_pad - jcp.id + jcp.kd);
+ int kd_pad_off = nstl::min(jcp.kd - 1, kd_front_pad) * jcp.kh * jcp.kw
+ * jcp.ic_block * jcp.oc_block * jcp.typesize_out;
+
+ for (int g = ti->g_start; g < ti->g_end; ++g) {
+ for (int oc_b = ti->oc_b_start; oc_b < ti->oc_b_end; ++oc_b) {
+ for (int ic_b = ti->ic_b_start; ic_b < ti->ic_b_end; ++ic_b) {
+ const int _oc = g * jcp.nb_oc + oc_b;
+ const int _ic = g * jcp.nb_ic + ic_b;
+
+ auto src = &ti->src[src_d.blk_off(img, _ic)
+ + ik_overlap * input_step];
+ auto dst = &ti->diff_dst[diff_dst_d.blk_off(img, _oc)
+ + od_s * output_step];
+
+ jit_conv_3d_ker_bwd_w_pipeline(kernel_->jit_ker, p, src, dst,
+ diff_wei + wht_blk_off(diff_weights_d, g, oc_b, ic_b),
+ diff_bia + _oc * 16, (img == img_first), od_s, od_e,
+ jcp.kd - kd_front_pad - kd_back_pad, kd_pad_off);
+
+ if (ic_b == 0) p.flags = 0;
+ else p.flags = 1;
+ }
+ }
+ }
+
+ const int _oc = ti->g_start * jcp.nb_oc + ti->oc_b_start;
+ const int _ic = ti->g_start * jcp.nb_ic + ti->ic_b_start;
+ jit_conv_3d_ker_bwd_w_pipeline(kernel_->jit_ker, p,
+ &ti->src[src_d.blk_off(img + 1, _ic)],
+ &ti->diff_dst[diff_dst_d.blk_off(img + 1, _oc)],
+ diff_wei + wht_blk_off(diff_weights_d, ti->g_start,
+ ti->oc_b_start, ti->ic_b_start),
+ diff_bia, 0, 0, 0, 0, 0);
+ nd_iterator_jump(img_start, img_end, img, jcp.mb, od_s, jcp.od);
+ }
+}
+
+template <data_type_t src_type, data_type_t diff_dst_type,
+ data_type_t diff_weights_type>
+void jit_avx512_common_convolution_bwd_weights_t<src_type, diff_dst_type,
+ diff_weights_type>::reduce_diff_weights(const thread_info_t *ti) const {
+ const memory_desc_wrapper diff_weights_d(pd()->diff_weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+ const int wei_size = jcp.ngroups * jcp.oc * jcp.ic * jcp.kh * jcp.kw;
+ const int bia_size = jcp.ngroups * jcp.oc;
+ const diff_weights_data_t *diff_bias_ws
+ = ti->wei_bia_reduction + (nthr_mb_ - 1) * wei_size;
+
+ /* diff_weights[:] += sum(wei_reduction_[thr_mb][:]) */
+ simple_barrier::barrier(ti->wei_bia_reduction_bctx, nthr_);
+
+ const int ic_b_kh_work = ti->ic_b_work * jcp.kh;
+ const int work = ti->g_work * ti->oc_b_work * ic_b_kh_work;
+
+ int start{0}, end{0};
+ balance211(work, nthr_mb_, ti->ithr_mb, start, end);
+ if (start == end) return;
+
+ for (int thr_mb = 1; thr_mb < nthr_mb_; ++thr_mb) {
+ int w = start;
+ int sub_g_start{0}, sub_oc_b_start{0}, sub_ic_b_kh_start{0};
+ nd_iterator_init(w, sub_g_start, ti->g_work, sub_oc_b_start,
+ ti->oc_b_work, sub_ic_b_kh_start, ic_b_kh_work);
+ while (w < end) {
+ const int g = ti->g_start + sub_g_start;
+ const int oc_b = ti->oc_b_start + sub_oc_b_start;
+ const int ic_b = ti->ic_b_start + sub_ic_b_kh_start / jcp.kh;
+ const int kh = sub_ic_b_kh_start % jcp.kh;
+
+ const int acc_size
+ = nstl::min(end - w, ic_b_kh_work - sub_ic_b_kh_start)
+ * jcp.kw * jcp.ic_block * jcp.oc_block;
+
+ const size_t off
+ = wht_blk_off(diff_weights_d, g, oc_b, ic_b, kh);
+
+ diff_weights_data_t *d
+ = (diff_weights_data_t *)ti->diff_weights + off;
+ diff_weights_data_t *s
+ = ti->wei_bia_reduction + (thr_mb - 1) * wei_size + off;
+
+ acc_ker_->accumulate(d, s, acc_size);
+
+ nd_iterator_jump(w, end, sub_g_start, ti->g_work, sub_oc_b_start,
+ ti->oc_b_work, sub_ic_b_kh_start, ic_b_kh_work);
+ }
+
+ if (jcp.with_bias && jcp.is_1stconv && jcp.ver == ver_4fma) {
+ if (ti->ithr == 0)
+ acc_ker_->accumulate((diff_weights_data_t *)ti->diff_bias,
+ diff_bias_ws, bia_size);
+ diff_bias_ws += bia_size;
+ }
+ }
+}
+
+template <data_type_t src_type, data_type_t diff_dst_type,
+ data_type_t diff_weights_type>
+void jit_avx512_common_convolution_bwd_weights_t<src_type, diff_dst_type,
+ diff_weights_type>::reduce_diff_weights_3d(const thread_info_t *ti) const {
+ const memory_desc_wrapper diff_weights_d(pd()->diff_weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+ const int wei_size = jcp.ngroups * jcp.oc * jcp.ic * jcp.kh * jcp.kw
+ * jcp.kd;
+
+ /* diff_weights[:] += sum(wei_reduction_[thr_mb][:]) */
+ simple_barrier::barrier(ti->wei_bia_reduction_bctx, nthr_);
+
+ const int ic_b_kh_work = ti->ic_b_work * jcp.kd;
+ const int work = ti->g_work * ti->oc_b_work * ic_b_kh_work;
+
+ int start{0}, end{0};
+ balance211(work, nthr_mb_, ti->ithr_mb, start, end);
+ if (start == end) return;
+
+ for (int thr_mb = 1; thr_mb < nthr_mb_; ++thr_mb) {
+ int w = start;
+ int sub_g_start{0}, sub_oc_b_start{0}, sub_ic_b_kh_start{0};
+ nd_iterator_init(w, sub_g_start, ti->g_work, sub_oc_b_start,
+ ti->oc_b_work, sub_ic_b_kh_start, ic_b_kh_work);
+ while (w < end) {
+ const int g = ti->g_start + sub_g_start;
+ const int oc_b = ti->oc_b_start + sub_oc_b_start;
+ const int ic_b = ti->ic_b_start + sub_ic_b_kh_start / jcp.kd;
+ const int kd = sub_ic_b_kh_start % jcp.kd;
+
+ const int acc_size
+ = nstl::min(end - w, ic_b_kh_work - sub_ic_b_kh_start)
+ * jcp.kw * jcp.ic_block * jcp.oc_block * jcp.kh;
+
+ const size_t off
+ = wht_blk_off(diff_weights_d, g, oc_b, ic_b, kd);
+ diff_weights_data_t *d
+ = (diff_weights_data_t *)ti->diff_weights + off;
+ diff_weights_data_t *s
+ = ti->wei_bia_reduction + (thr_mb - 1) * wei_size + off;
+ acc_ker_->accumulate(d, s, acc_size);
+
+ nd_iterator_jump(w, end, sub_g_start, ti->g_work, sub_oc_b_start,
+ ti->oc_b_work, sub_ic_b_kh_start, ic_b_kh_work);
+ }
+ }
+}
+
+template <data_type_t src_type, data_type_t diff_dst_type,
+ data_type_t diff_weights_type>
+void jit_avx512_common_convolution_bwd_weights_t<src_type, diff_dst_type,
+ diff_weights_type>::compute_diff_bias(const thread_info_t *ti) const {
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+
+ auto rb = this->reducer_bias_;
+ assert(nthr_ == rb->balancer().nthr_);
+
+ const auto reducer_bia_scratchpad = memory_tracking::grantor_t(
+ ti->scratchpad, prefix_reducer_bia);
+
+ const auto &jcp = kernel_->jcp;
+
+ if (jcp.with_bias && jcp.is_1stconv && jcp.ver == ver_4fma) return;
+
+ const int b_job_start = rb->balancer().ithr_job_off(ti->ithr);
+ const int b_njobs = rb->balancer().ithr_njobs(ti->ithr);
+
+ if (b_njobs == 0) return;
+
+ /* reduction dimension */
+ int img_start{0}, img_end{0};
+ balance211(jcp.mb, rb->balancer().nthr_per_group_,
+ rb->balancer().id_in_group(ti->ithr), img_start, img_end);
+
+ /* jobs */
+ int g_start{0}, ocb_start{0};
+ nd_iterator_init(b_job_start, g_start, jcp.ngroups, ocb_start, jcp.nb_oc);
+ for (int img = img_start; img < img_end; ++img) {
+ int g = g_start, ocb = ocb_start;
+ for (int b_job_loc = 0; b_job_loc < b_njobs; ++b_job_loc) {
+ const size_t _oc = g * jcp.nb_oc + ocb;
+
+ const diff_dst_data_t *d_dst
+ = &ti->diff_dst[diff_dst_d.blk_off(img, _oc)];
+ diff_weights_data_t *d_bias = rb->get_local_ptr(ti->ithr,
+ ti->diff_bias, reducer_bia_scratchpad)
+ + b_job_loc * rb->balancer().job_size_;
+
+ if (img == img_start)
+ for (int o = 0; o < 16; ++o)
+ d_bias[o] = 0;
+ for (int hw = 0; hw < jcp.oh * jcp.ow * jcp.od; ++hw) {
+ PRAGMA_OMP_SIMD()
+ for (int o = 0; o < 16; ++o)
+ d_bias[o] += d_dst[o];
+ d_dst += 16;
+ }
+
+ nd_iterator_step(g, jcp.ngroups, ocb, jcp.nb_oc);
+ }
+ }
+
+ rb->reduce(ti->ithr, ti->diff_bias, reducer_bia_scratchpad);
+}
+
+template <data_type_t src_type, data_type_t diff_dst_type,
+ data_type_t diff_weights_type>
+void jit_avx512_common_convolution_bwd_weights_t<src_type, diff_dst_type,
+ diff_weights_type>::compute_diff_bias_3d(const thread_info_t *ti) const {
+
+ const auto &jcp = kernel_->jcp;
+
+ const size_t wei_size = (size_t)jcp.ngroups * jcp.oc * jcp.ic * jcp.kh
+ * jcp.kw * jcp.kd;
+ const int bia_size = jcp.ngroups * jcp.oc;
+ const diff_weights_data_t *diff_bias_ws
+ = ti->wei_bia_reduction + (size_t)(nthr_mb_ - 1) * wei_size;
+
+ if (nthr_mb_ > 1) mkldnn_thr_barrier();
+
+ if (ti->ithr == 0)
+ {
+ for (int thr_mb = 1; thr_mb < nthr_mb_; ++thr_mb) {
+ acc_ker_->accumulate(ti->diff_bias, diff_bias_ws, bia_size);
+ diff_bias_ws += bia_size;
+ }
+ }
+}
+
+template <data_type_t src_type, data_type_t diff_dst_type,
+ data_type_t diff_weights_type>
+void jit_avx512_common_convolution_bwd_weights_t<src_type, diff_dst_type,
+ diff_weights_type>::prepare_scratchpad_data(const exec_ctx_t &ctx) const
+{
+ const auto &j = pd()->jcp_;
+ auto scratchpad = this->scratchpad(ctx);
+
+ if (j.ver == ver_4fma) {
+ if (!j.is_1stconv) {
+ // XXX: See the comment about tr_iw and guarding elements in
+ // jit_avx512_common_conv_bwd_weights_kernel_f32::init_conf()
+ const int max_nthr = j.nthr_mb * j.ngroups * j.nb_ic;
+ const int min_tr_src_size_per_thr = j.ih * j.ic_block * j.tr_iw;
+
+ auto tr_src = scratchpad.template get<src_data_t>(key_conv_tr_src);
+ /* to avoid NaNs in computations we zero tail num_guard_elems for
+ * each possible thread group */
+
+ for (int ithr = 1; ithr <= max_nthr; ++ithr) {
+ src_data_t *ts = &tr_src[ithr * min_tr_src_size_per_thr];
+ for (int i = 0; i < j.tr_src_num_guard_elems; ++i)
+ ts[i] = 0;
+ }
+ }
+
+ if (j.nthr_oc_b > 1) {
+ const int tr_src_bctx_size = j.nthr / j.nthr_oc_b;
+ auto tr_src_bctx = scratchpad.template get<simple_barrier::ctx_t>(
+ key_conv_tr_src_bctx);
+ for (int i = 0; i < tr_src_bctx_size; ++i)
+ simple_barrier::ctx_init(&tr_src_bctx[i]);
+ }
+ }
+
+ if (nthr_mb_ > 1) {
+ simple_barrier::ctx_init(scratchpad.template get<simple_barrier::ctx_t>(
+ key_conv_wei_bia_reduction_bctx));
+ }
+
+ const auto reducer_bia_scratchpad = memory_tracking::grantor_t(scratchpad,
+ prefix_reducer_bia);
+ auto rb = this->reducer_bias_;
+ rb->init(reducer_bia_scratchpad);
+}
+
+template <data_type_t src_type, data_type_t diff_dst_type,
+ data_type_t diff_weights_type>
+void jit_avx512_common_convolution_bwd_weights_t<src_type, diff_dst_type,
+ diff_weights_type>::execute_backward_weights(const exec_ctx_t &ctx) const {
+ prepare_scratchpad_data(ctx);
+
+ parallel(nthr_, [&](const int ithr, const int nthr) {
+ assert(nthr_ == nthr);
+
+ thread_info_t thread_info(this, ctx, ithr);
+
+ if (utils::one_of(pd()->ndims(), 3, 4)) {
+ compute_diff_weights(&thread_info);
+ if (nthr_mb_ > 1) reduce_diff_weights(&thread_info);
+ if (pd()->with_bias()) compute_diff_bias(&thread_info);
+ } else if (pd()->ndims() == 5) {
+ compute_diff_weights_3d(&thread_info);
+ if (nthr_mb_ > 1) reduce_diff_weights_3d(&thread_info);
+ if (pd()->with_bias()) compute_diff_bias_3d(&thread_info);
+ } else {
+ assert(false);
+ }
+ });
+
+ /* TODO: put that into compute_diff_bias() */
+ if (pd()->wants_padded_bias()) {
+ auto diff_bias = scratchpad(ctx).template get<const diff_weights_data_t>(
+ key_conv_padded_bias);
+ auto diff_bias_in = CTX_OUT_MEM(diff_weights_data_t *, MKLDNN_ARG_DIFF_BIAS);
+ for (int oc = 0; oc < pd()->jcp_.oc_without_padding; ++oc)
+ diff_bias_in[oc] = diff_bias[oc];
+ }
+}
+
+template struct jit_avx512_common_convolution_bwd_weights_t<data_type::f32>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution.hpp
new file mode 100644
index 0000000000..3341c3ebe0
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution.hpp
@@ -0,0 +1,302 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_COMMON_CONVOLUTION_HPP
+#define CPU_JIT_AVX512_COMMON_CONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "cpu_barrier.hpp"
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+#include "cpu_reducer.hpp"
+
+#include "jit_transpose_src_utils.hpp"
+#include "jit_avx512_common_conv_kernel.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t src_type,
+ impl::data_type_t wei_type = src_type,
+ impl::data_type_t dst_type = src_type>
+struct jit_avx512_common_convolution_fwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_()
+ {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", avx512_common, ""),
+ jit_avx512_common_convolution_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(src_type, wei_type, dst_type, dst_type,
+ data_type::undef)
+ && !has_zero_dim_memory();
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_avx512_common_conv_fwd_kernel::init_conf(
+ jcp_, *desc(), src_md_, weights_md_, dst_md_, bias_md_,
+ *attr(), mkldnn_get_max_threads());
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx512_common_conv_fwd_kernel::init_scratchpad(scratchpad,
+ jcp_);
+
+ return status;
+ }
+
+ jit_conv_conf_t jcp_;
+ };
+
+ jit_avx512_common_convolution_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ {
+ kernel_ = new jit_avx512_common_conv_fwd_kernel(pd()->jcp_,
+ *pd()->attr());
+ }
+ ~jit_avx512_common_convolution_fwd_t() { delete kernel_; }
+
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<wei_type>::type wei_data_t;
+ typedef typename prec_traits<dst_type>::type dst_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ if (pd()->ndims() == 3)
+ execute_forward_1d(ctx);
+ else if (pd()->ndims() == 4)
+ execute_forward_2d(ctx);
+ else if (pd()->ndims() == 5)
+ execute_forward_3d(ctx);
+ else
+ assert(false);
+
+ if (pd()->wants_zero_pad_dst())
+ ctx.memory(MKLDNN_ARG_DST)->zero_pad();
+
+ return status::success;
+ }
+
+private:
+ void prepare_padded_bias(const dst_data_t *&bias,
+ const memory_tracking::grantor_t &scratchpad) const;
+ void execute_forward_1d(const exec_ctx_t &ctx) const;
+ void execute_forward_2d(const exec_ctx_t &ctx) const;
+ void execute_forward_3d(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx512_common_conv_fwd_kernel *kernel_;
+};
+
+template <impl::data_type_t diff_dst_type,
+ impl::data_type_t wei_type = diff_dst_type,
+ impl::data_type_t diff_src_type = diff_dst_type>
+struct jit_avx512_common_convolution_bwd_data_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_data_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_data_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_()
+ {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", avx512_common, ""),
+ jit_avx512_common_convolution_bwd_data_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_data
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(diff_src_type, wei_type,
+ data_type::undef, diff_dst_type, data_type::undef)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ status_t status =
+ jit_avx512_common_conv_bwd_data_kernel_f32::init_conf(jcp_,
+ *desc(), *diff_src_md(), *weights_md(), *diff_dst_md());
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx512_common_conv_bwd_data_kernel_f32::init_scratchpad(
+ scratchpad, jcp_);
+
+ return status::success;
+ }
+
+ jit_conv_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = utils::pick(ndims() - 3, nCw16c, nChw16c, nCdhw16c);
+ auto wei_tag = utils::pick(2 * ndims() - 6 + with_groups(),
+ OIw16o16i, gOIw16o16i, OIhw16o16i, gOIhw16o16i,
+ OIdhw16o16i, gOIdhw16o16i);
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ jit_avx512_common_convolution_bwd_data_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ { kernel_ = new jit_avx512_common_conv_bwd_data_kernel_f32(pd()->jcp_); }
+ ~jit_avx512_common_convolution_bwd_data_t() { delete kernel_; };
+
+ typedef typename prec_traits<diff_dst_type>::type diff_dst_data_t;
+ typedef typename prec_traits<wei_type>::type wei_data_t;
+ typedef typename prec_traits<diff_src_type>::type diff_src_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ if (pd()->ndims() == 3)
+ execute_backward_data_1d(ctx);
+ else if (pd()->ndims() == 4)
+ execute_backward_data_2d(ctx);
+ else if (pd()->ndims() == 5)
+ execute_backward_data_3d(ctx);
+ else
+ assert(false);
+ return status::success;
+ }
+
+private:
+ void execute_backward_data_1d(const exec_ctx_t &ctx) const;
+ void execute_backward_data_2d(const exec_ctx_t &ctx) const;
+ void execute_backward_data_3d(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx512_common_conv_bwd_data_kernel_f32 *kernel_;
+};
+
+template <impl::data_type_t src_type,
+ impl::data_type_t diff_dst_type = src_type,
+ impl::data_type_t diff_weights_type = src_type>
+struct jit_avx512_common_convolution_bwd_weights_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_weights_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_weights_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", avx512_common, ""),
+ jit_avx512_common_convolution_bwd_weights_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_weights
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(src_type, diff_weights_type,
+ diff_weights_type, diff_dst_type, data_type::undef)
+ && !has_zero_dim_memory();
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_avx512_common_conv_bwd_weights_kernel_f32::
+ init_conf(jcp_, *desc(), src_md_, diff_weights_md_,
+ diff_bias_md_, diff_dst_md_);
+ if (status != status::success) return status;
+
+ init_balancers();
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx512_common_conv_bwd_weights_kernel_f32::init_scratchpad(
+ scratchpad, jcp_);
+
+ auto reducer_bia_scratchpad = memory_tracking::registrar_t(
+ scratchpad, memory_tracking::names::prefix_reducer_bia);
+ reducer_bia_conf_.init_scratchpad(reducer_bia_scratchpad);
+
+ return status;
+ }
+
+ jit_conv_conf_t jcp_;
+ typename cpu_reducer_t<diff_weights_type>::conf_t reducer_bia_conf_;
+
+ private:
+ void init_balancers() {
+ const size_t max_buffer_size = jcp_.nthr * 3 * 5 * 5 * 16 * 16;
+ if (with_bias()) {
+ reducer_bia_conf_.init(reduce_balancer_t(jcp_.nthr,
+ jcp_.oc_block, jcp_.ngroups * jcp_.nb_oc, jcp_.mb,
+ max_buffer_size));
+ }
+ }
+ };
+
+ jit_avx512_common_convolution_bwd_weights_t(const pd_t *apd);
+ ~jit_avx512_common_convolution_bwd_weights_t() {
+ delete kernel_;
+ if (trans_kernel_)
+ delete trans_kernel_;
+ if (acc_ker_)
+ delete acc_ker_;
+ delete reducer_bias_;
+ }
+
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<diff_dst_type>::type diff_dst_data_t;
+ typedef typename prec_traits<diff_weights_type>::type diff_weights_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_weights(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_weights(const exec_ctx_t &ctx) const;
+ void prepare_scratchpad_data(const exec_ctx_t &ctx) const;
+ struct thread_info_t;
+ void compute_diff_weights(const thread_info_t *) const;
+ void compute_diff_weights_3d(const thread_info_t *) const;
+ void reduce_diff_weights(const thread_info_t *) const;
+ void reduce_diff_weights_3d(const thread_info_t *) const;
+ void compute_diff_bias(const thread_info_t *) const;
+ void compute_diff_bias_3d(const thread_info_t *) const;
+
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ int nthr_, nthr_mb_, nthr_g_, nthr_oc_b_, nthr_ic_b_;
+
+ jit_avx512_common_conv_bwd_weights_kernel_f32 *kernel_;
+ jit_trans_src_t *trans_kernel_;
+ cpu_accumulator_1d_t<diff_weights_type> *acc_ker_;
+ cpu_reducer_t<diff_weights_type> *reducer_bias_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution_winograd.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution_winograd.cpp
new file mode 100644
index 0000000000..62247c0264
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution_winograd.cpp
@@ -0,0 +1,1215 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifdef __INTEL_COMPILER
+#include <immintrin.h>
+#endif
+
+#include "mkldnn_types.h"
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_avx512_common_convolution_winograd.hpp"
+
+#ifndef _MSC_VER
+#define pragma_unroll _Pragma("unroll")
+#else
+#define pragma_unroll
+#endif
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace memory_tracking::names;
+
+namespace {
+
+unsigned int LLC_cache_size = get_cache_size(3, false);
+
+void inline load_ps(float *dest, const float *src_mem) {
+#ifdef __INTEL_COMPILER
+ __m512 *Iv512 = (__m512 *)dest;
+ Iv512[0] = _mm512_load_ps(src_mem);
+#else
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) dest[v] = src_mem[v];
+#endif
+}
+
+void inline store_output(float *dest, const float *data, bool streamout) {
+#ifdef __INTEL_COMPILER
+ if (streamout)
+ _mm512_stream_ps(dest, *((__m512 *)data));
+ else
+ _mm512_store_ps(dest, *((__m512 *)data));
+#else
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++)
+ dest[v] = data[v];
+#endif
+}
+
+void inline accum_output(
+ float *dest, float *data, bool streamout, bool with_relu_postsum) {
+#ifdef __INTEL_COMPILER
+ __m512 _data = _mm512_loadu_ps(data);
+ __m512 _dest = _mm512_loadu_ps(dest);
+ _data = _mm512_add_ps(_data, _dest);
+ if (with_relu_postsum)
+ _data = _mm512_max_ps(_data, _mm512_setzero_ps());
+ if (streamout)
+ _mm512_stream_ps(dest, _data);
+ else
+ _mm512_store_ps(dest, _data);
+#else
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++)
+ data[v] += dest[v];
+
+ if (with_relu_postsum) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++)
+ if (data[v] < 0.f)
+ data[v] = 0.f;
+ }
+
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++)
+ dest[v] = data[v];
+#endif
+}
+}
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::utils;
+
+void trans_W_4x4_3x3(float Fw_[6][6][16][16], float F[3][3][16][16]) {
+ float Fw[6][16];
+ float T[6][3][16];
+ float t0[16];
+ float t1[16];
+ float t2[16];
+
+ for (int j = 0; j < 16; j++) {
+#pragma unroll
+ for (int i = 0; i < 3; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int k = 0; k < 16; k++) {
+ t0[k] = 0.26890756302521f * F[2][i][j][k];
+ t1[k] = -t0[k] - 0.688403361344538f * F[0][i][j][k];
+ t2[k] = t0[k] + 0.119514472455649f * F[0][i][j][k];
+
+ T[0][i][k] = 1.13777777777778f * F[0][i][j][k];
+ T[1][i][k] = t1[k] - 0.430252100840336f * F[1][i][j][k];
+ T[2][i][k] = t1[k] + 0.430252100840336f * F[1][i][j][k];
+ T[3][i][k] = t2[k] + 0.179271708683473f * F[1][i][j][k];
+ T[4][i][k] = t2[k] - 0.179271708683473f * F[1][i][j][k];
+ T[5][i][k] = F[2][i][j][k];
+ }
+ }
+#pragma unroll
+ for (int i = 0; i < 6; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int k = 0; k < 16; k++) {
+ t0[k] = 0.26890756302521f * T[i][2][k];
+ t1[k] = -t0[k] - 0.688403361344538f * T[i][0][k];
+ t2[k] = t0[k] + 0.119514472455649f * T[i][0][k];
+
+ Fw[0][k] = 1.13777777777778f * T[i][0][k];
+ Fw[1][k] = t1[k] - 0.430252100840336f * T[i][1][k];
+ Fw[2][k] = t1[k] + 0.430252100840336f * T[i][1][k];
+ Fw[3][k] = t2[k] + 0.179271708683473f * T[i][1][k];
+ Fw[4][k] = t2[k] - 0.179271708683473f * T[i][1][k];
+ Fw[5][k] = T[i][2][k];
+#pragma unroll
+ for (int l = 0; l < 6; l++) {
+ Fw_[i][l][j][k] = Fw[l][k];
+ }
+ }
+ }
+ }
+}
+
+void trans_O_4x4_3x3(float Mw[6][6][16], float O[4][4][16]) {
+ float T[4][6][16];
+ float t0[16];
+ float t1[16];
+ float t2[16];
+ float t3[16];
+
+#pragma unroll
+ for (int i = 0; i < 6; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < 16; v++) {
+ t0[v] = Mw[1][i][v] + Mw[2][i][v];
+ t1[v] = Mw[3][i][v] + Mw[4][i][v];
+ t2[v] = Mw[1][i][v] - Mw[2][i][v];
+ t3[v] = Mw[3][i][v] - Mw[4][i][v];
+
+ T[0][i][v] = t0[v] + t1[v] + Mw[0][i][v];
+ T[1][i][v] = t2[v] * 0.625f + t3[v] * 1.5f;
+ T[2][i][v] = t0[v] * 0.390625f + t1[v] * 2.25f;
+ T[3][i][v] = t2[v] * 0.244140625f + t3[v] * 3.375f + Mw[5][i][v];
+ }
+ }
+#pragma unroll
+ for (int i = 0; i < 4; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < 16; v++) {
+ t0[v] = T[i][1][v] + T[i][2][v];
+ t1[v] = T[i][3][v] + T[i][4][v];
+ t2[v] = T[i][1][v] - T[i][2][v];
+ t3[v] = T[i][3][v] - T[i][4][v];
+
+ O[i][0][v] = t0[v] + t1[v] + T[i][0][v];
+ O[i][1][v] = t2[v] * 0.625f + t3[v] * 1.5f;
+ O[i][2][v] = t0[v] * 0.390625f + t1[v] * 2.25f;
+ O[i][3][v] = t2[v] * 0.244140625f + t3[v] * 3.375f + T[i][5][v];
+ }
+ }
+}
+
+
+void trans_W_3x3_4x4(float Fw[6][6][16], float F[4][6][16])
+{
+ const float rcp3 = 1.0f / 3.0f;
+ const float rcp4 = 1.0f / 4.0f;
+ const float rcp6 = 1.0f / 6.0f;
+ const float rcp12 = 1.0f / 12.0f;
+ const float rcp24 = 1.0f / 24.0f;
+ float t0[16];
+ float t1[16];
+ float t2[16];
+ float t3[16];
+ float t4[16];
+ float T[6][4][16];
+
+pragma_unroll
+ for (int i = 0; i < 4; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < 16; j++) {
+ t0[j] = F[2][i][j] * rcp6;
+ t1[j] = F[0][i][j] * -rcp6 - t0[j];
+ t2[j] = F[0][i][j] * rcp24 + t0[j];
+ t3[j] = (F[1][i][j] + F[3][i][j]) * rcp6;
+ t4[j] = F[1][i][j] * rcp12 + F[3][i][j] * rcp3;
+
+ T[0][i][j] = F[0][i][j] * rcp4;
+ T[1][i][j] = t1[j] - t3[j];
+ T[2][i][j] = t1[j] + t3[j];
+ T[3][i][j] = t2[j] + t4[j];
+ T[4][i][j] = t2[j] - t4[j];
+ T[5][i][j] = F[3][i][j];
+ }
+ }
+pragma_unroll
+ for (int i = 0; i < 6; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < 16; j++) {
+ t0[j] = T[i][2][j] * rcp6;
+ t1[j] = T[i][0][j] * -rcp6 - t0[j];
+ t2[j] = T[i][0][j] * rcp24 + t0[j];
+ t3[j] = (T[i][1][j] + T[i][3][j]) * rcp6;
+ t4[j] = T[i][1][j] * rcp12 + T[i][3][j] * rcp3;
+
+ Fw[i][0][j] = T[i][0][j] * rcp4;
+ Fw[i][1][j] = t1[j] - t3[j];
+ Fw[i][2][j] = t1[j] + t3[j];
+ Fw[i][3][j] = t2[j] + t4[j];
+ Fw[i][4][j] = t2[j] - t4[j];
+ Fw[i][5][j] = T[i][3][j];
+ }
+ }
+}
+
+void trans_O_3x3_4x4(float Mw[6][6][16][16], float M[3][3][16][16])
+{
+ float T[4][6][16];
+ float M_[3][16];
+ float t0[16];
+ float t1[16];
+ float t2[16];
+
+ for (int j = 0; j < 16; j++) {
+pragma_unroll
+ for (int i = 0; i < 6; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int l = 0; l < 16; l++) {
+ t0[l] = Mw[1][i][j][l] + Mw[2][i][j][l];
+ t1[l] = Mw[3][i][j][l] + Mw[4][i][j][l];
+ t2[l] = t1[l] * 4.0f + Mw[5][i][j][l];
+
+ T[0][i][l] = Mw[0][i][j][l] + t0[l] + t1[l];
+ T[1][i][l] = (Mw[1][i][j][l] - Mw[2][i][j][l]) +
+ 2.0f * (Mw[3][i][j][l] - Mw[4][i][j][l]);
+ T[2][i][l] = t0[l] + t2[l];
+ }
+ }
+pragma_unroll
+ for (int i = 0; i < 3; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int l = 0; l < 16; l++) {
+ t0[l] = T[i][1][l] + T[i][2][l];
+ t1[l] = T[i][3][l] + T[i][4][l];
+ t2[l] = t1[l] * 4.0f + T[i][5][l];
+
+ M_[0][l] = T[i][0][l] + t0[l] + t1[l];
+ M_[1][l] = (T[i][1][l] - T[i][2][l]) +
+ 2.0f * (T[i][3][l] - T[i][4][l]);
+ M_[2][l] = t0[l] + t2[l];
+
+ for (int k = 0; k < 3; k++) {
+ M[i][k][j][l] = M_[k][l];
+ }
+ }
+ }
+ }
+}
+
+void trans_I_4x4_3x3(float Iw[6][6][16], float I[6][6][16])
+{
+ float T[6][6][16];
+ float t0[16];
+ float t1[16];
+ float t2[16];
+ float t3[16];
+ float t4[16];
+ float t5[16];
+
+pragma_unroll
+ for (int i = 0; i < 6; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < 16; v++) {
+ t0[v] = I[2][i][v] * -2.25f + I[4][i][v];
+ t1[v] = I[1][i][v] * -2.25f + I[3][i][v];
+ t2[v] = I[2][i][v] * -0.390625f + I[4][i][v];
+ t3[v] = I[1][i][v] * -0.390625f + I[3][i][v];
+ t4[v] = I[0][i][v] * 0.87890625f + I[4][i][v];
+ t5[v] = I[1][i][v] * 0.87890625f + I[5][i][v];
+
+ T[0][i][v] = I[2][i][v] * -2.640625f + t4[v];
+ T[1][i][v] = t1[v] * 0.625f + t0[v];
+ T[2][i][v] = t1[v] * -0.625f + t0[v];
+ T[3][i][v] = t3[v] * 1.5f + t2[v];
+ T[4][i][v] = t3[v] * -1.5f + t2[v];
+ T[5][i][v] = I[3][i][v] * -2.640625f + t5[v];
+ }
+ }
+
+pragma_unroll
+ for (int i = 0; i < 6; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < 16; v++) {
+ t0[v] = T[i][2][v] * -2.25f + T[i][4][v];
+ t1[v] = T[i][1][v] * -2.25f + T[i][3][v];
+ t2[v] = T[i][2][v] * -0.390625f + T[i][4][v];
+ t3[v] = T[i][1][v] * -0.390625f + T[i][3][v];
+ t4[v] = T[i][0][v] * 0.87890625f + T[i][4][v];
+ t5[v] = T[i][1][v] * 0.87890625f + T[i][5][v];
+
+ Iw[i][0][v] = T[i][2][v] * -2.640625f + t4[v];
+ Iw[i][1][v] = t1[v] * 0.625f + t0[v];
+ Iw[i][2][v] = t1[v] * -0.625f + t0[v];
+ Iw[i][3][v] = t3[v] * 1.5f + t2[v];
+ Iw[i][4][v] = t3[v] * -1.5f + t2[v];
+ Iw[i][5][v] = T[i][3][v] * -2.640625f + t5[v];
+ }
+ }
+}
+
+void trans_W_3x3_4x4_wu(float Fw[6][6][16], float F[4][6][16])
+{
+ float T[6][4][16];
+ float t0[16];
+ float t1[16];
+ float t2[16];
+ float t3[16];
+ float t4[16];
+
+pragma_unroll
+ for (int i = 0; i < 4; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < 16; v++) {
+ t0[v] = F[2][i][v] * 0.26890756302521f;
+ t1[v] = F[0][i][v] * -0.688403361344538f - t0[v];
+ t2[v] = F[0][i][v] * 0.119514472455649f + t0[v];
+ t3[v] = F[1][i][v] * 0.430252100840336f +
+ F[3][i][v] * 0.168067226890756f;
+ t4[v] = F[1][i][v] * 0.179271708683473f +
+ F[3][i][v] * 0.403361344537815f;
+
+ T[0][i][v] = F[0][i][v] * 1.13777777777778f;
+ T[1][i][v] = t1[v] - t3[v];
+ T[2][i][v] = t1[v] + t3[v];
+ T[3][i][v] = t2[v] + t4[v];
+ T[4][i][v] = t2[v] - t4[v];
+ T[5][i][v] = F[3][i][v];
+ }
+ }
+pragma_unroll
+ for (int i = 0; i < 6; i++) {
+ for (int v = 0; v < 16; v++) {
+ t0[v] = T[i][2][v] * 0.26890756302521f;
+ t1[v] = T[i][0][v] * -0.688403361344538f - t0[v];
+ t2[v] = T[i][0][v] * 0.119514472455649f + t0[v];
+ t3[v] = T[i][1][v] * 0.430252100840336f +
+ T[i][3][v] * 0.168067226890756f;
+ t4[v] = T[i][1][v] * 0.179271708683473f +
+ T[i][3][v] * 0.403361344537815f;
+
+ Fw[i][0][v] = T[i][0][v] * 1.13777777777778f;
+ Fw[i][1][v] = t1[v] - t3[v];
+ Fw[i][2][v] = t1[v] + t3[v];
+ Fw[i][3][v] = t2[v] + t4[v];
+ Fw[i][4][v] = t2[v] - t4[v];
+ Fw[i][5][v] = T[i][3][v];
+ }
+ }
+}
+
+void trans_O_3x3_4x4_wu(float Mw[6][6][16][16], float M[3][3][16][16])
+{
+ float T[3][6][16];
+ float t0[16];
+ float t1[16];
+ float t2[16];
+ float M_[3][16];
+
+ for (int j = 0; j < 16; j++) {
+pragma_unroll
+ for (int i = 0; i < 6; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < 16; v++) {
+ t0[v] = Mw[1][i][j][v] + Mw[2][i][j][v];
+ t1[v] = Mw[3][i][j][v] + Mw[4][i][j][v];
+ t2[v] = t1[v] * 2.25f + Mw[5][i][j][v];
+
+ T[0][i][v] = Mw[0][i][j][v] + t0[v] + t1[v];
+ T[1][i][v] = 0.625f * (Mw[1][i][j][v] - Mw[2][i][j][v]) +
+ 1.5f * (Mw[3][i][j][v] - Mw[4][i][j][v]);
+ T[2][i][v] = t0[v] * 0.390625f + t2[v];
+ }
+ }
+pragma_unroll
+ for (int i = 0; i < 3; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < 16; v++) {
+ t0[v] = T[i][1][v] + T[i][2][v];
+ t1[v] = T[i][3][v] + T[i][4][v];
+ t2[v] = t1[v] * 2.25f + T[i][5][v];
+
+ M_[0][v] = T[i][0][v] + t0[v] + t1[v];
+ M_[1][v] = 0.625f * (T[i][1][v] - T[i][2][v]) +
+ 1.5f * (T[i][3][v] - T[i][4][v]);
+ M_[2][v] = t0[v] * 0.390625f + t2[v];
+ }
+
+pragma_unroll
+ for (int k = 0; k < 3; k++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < 16; v++) {
+ M[i][k][j][v] = M_[k][v];
+ }
+ }
+ }
+ }
+}
+
+template <bool is_fwd>
+void input_transform_data(int image, const jit_conv_winograd_conf_t &jcp,
+ float *inp, float *tinp, bool streamout = true)
+{
+ const int inpw = is_fwd ? jcp.iw : jcp.ow;
+ const int inph = is_fwd ? jcp.ih : jcp.oh;
+ const int l_pad = is_fwd ? jcp.l_pad : jcp.iw + jcp.r_pad - jcp.ow;
+ const int t_pad = is_fwd ? jcp.t_pad : jcp.ih + jcp.t_pad - jcp.oh;
+ const int wp_max = inpw + l_pad;
+ const int hp_max = inph + t_pad;
+ float Iw[alpha][alpha][simd_w];
+ float I[alpha][alpha][simd_w];
+
+ array_offset_calculator<float, 5> input(inp,
+ jcp.mb, jcp.dimK/simd_w, inph, inpw,
+ simd_w);
+ array_offset_calculator<float, 8> output(tinp,
+ jcp.dimN_nb_block, alpha, alpha,
+ jcp.dimN_block, jcp.dimK_nb_block, jcp.dimK_block,
+ jcp.dimN_reg_block, jcp.dimK_reg_block);
+
+ int tile_base_index = image * jcp.itiles * jcp.jtiles;
+ int tile_block_ur = tile_base_index % jcp.tile_block_ur;
+ int nb_tile_block_ur =
+ (tile_base_index / jcp.tile_block_ur) % jcp.nb_tile_block_ur;
+ int tile_block =
+ (tile_base_index / jcp.tile_block_ur) / jcp.nb_tile_block_ur;
+
+ for (int tj = 0; tj < jcp.jtiles; tj++) {
+ for (int ti = 0; ti < jcp.itiles; ti++) {
+ for (int j = 0; j < alpha; j++) {
+ int ydim = tj * tile_size + j;
+ if ((t_pad <= ydim) && (ydim < hp_max)) {
+ float *pinp_j = inp + (ydim - t_pad) * inpw * 16 ;
+ for (int i = 0; i < alpha; i++) {
+ int xdim = ti * tile_size + i;
+ if ((l_pad <= xdim) && (xdim < wp_max)) {
+ float *pinp_i = pinp_j + (xdim - l_pad) * 16;
+ load_ps(I[j][i], pinp_i);
+ } else {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ I[j][i][v] = 0.0f;
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < alpha; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ I[j][i][v] = 0.0f;
+ }
+ }
+ }
+ }
+
+ trans_I_4x4_3x3(Iw, I);
+
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ store_output(&(output(tile_block, j, i,
+ nb_tile_block_ur, 0, 0,
+ tile_block_ur, 0)),
+ Iw[j][i], streamout);
+ }
+ }
+ tile_block_ur++;
+ if (tile_block_ur >= jcp.tile_block_ur) {
+ tile_block_ur = 0;
+ nb_tile_block_ur++;
+ }
+ if (nb_tile_block_ur >= jcp.nb_tile_block_ur) {
+ nb_tile_block_ur = 0;
+ tile_block++;
+ }
+ }
+ }
+}
+
+template <bool is_fwd>
+void weight_transform_data(const jit_conv_winograd_conf_t &jcp,
+ float *wp, float *twp)
+{
+ const int kh = 3;
+ const int kw = 3;
+ array_offset_calculator<float, 6> input(wp,
+ jcp.oc/jcp.oc_simd_block,
+ jcp.ic/jcp.ic_simd_block,
+ jcp.kh, jcp.kw,
+ simd_w, simd_w);
+ array_offset_calculator<float, 8> output(twp,
+ jcp.dimM_nb_block,
+ alpha, alpha,
+ jcp.dimK_nb_block,
+ jcp.dimM_block, jcp.dimK_block,
+ simd_w, simd_w);
+ float Fw[alpha][alpha][simd_w][simd_w];
+ float F[kh][kw][simd_w][simd_w];
+
+ for (int j = 0; j < kh; j++) {
+ for (int i = 0; i < kw; i++) {
+ for (int v1 = 0; v1 < simd_w; v1++) {
+ float *base_inp = is_fwd
+ ? &(input(0, 0, j, i, v1, 0))
+ : &(input(0, 0, 2 - j, 2 - i, v1, 0));
+ PRAGMA_OMP_SIMD()
+ for (int v2 = 0; v2 < simd_w; v2++) {
+ if (is_fwd)
+ F[j][i][v1][v2] = *(base_inp + v2);
+ else
+ F[j][i][v2][v1] = *(base_inp + v2);
+ }
+ }
+ }
+ }
+
+ trans_W_4x4_3x3(Fw, F);
+
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ for (int v1 = 0; v1 < simd_w; v1++) {
+ PRAGMA_OMP_SIMD()
+ for (int v2 = 0; v2 < simd_w; v2++) {
+ output(0, j, i, 0, 0, 0, v1, v2) = Fw[j][i][v1][v2];
+ }
+ }
+ }
+ }
+}
+
+template <bool is_fwd, bool with_bias, bool with_relu_presum, bool with_sum>
+void output_transform_data(int image, const jit_conv_winograd_conf_t &jcp,
+ const post_ops_t &p_ops, float *toutp, float *pout_b, float *bias,
+ bool streamout = true) {
+ float Ow[alpha][alpha][simd_w];
+ float O[tile_size][tile_size][simd_w];
+ int outw = is_fwd ? jcp.ow : jcp.iw;
+ int outh = is_fwd ? jcp.oh : jcp.ih;
+
+ /* Prepare for PostOps */
+ bool with_relu_postsum = p_ops.find(primitive_kind::eltwise, 1) != -1;
+
+ array_offset_calculator<float, 8> input(toutp,
+ jcp.dimN_nb_block, jcp.dimM_nb_block,
+ alpha, alpha,
+ jcp.dimN_block, jcp.dimM_block,
+ jcp.dimN_reg_block, jcp.dimM_simd_block);
+
+ int tile_base_index = image * jcp.itiles * jcp.jtiles;
+ int tile_block_ur = tile_base_index % jcp.tile_block_ur;
+ int nb_tile_block_ur =
+ (tile_base_index / jcp.tile_block_ur) % jcp.nb_tile_block_ur;
+ int tile_block =
+ (tile_base_index / jcp.tile_block_ur) / jcp.nb_tile_block_ur;
+
+ for (int tj = 0; tj < jcp.jtiles; tj++) {
+ for (int ti = 0; ti < jcp.itiles; ti++) {
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ Ow[j][i][v] = input(tile_block, 0,
+ j, i,
+ nb_tile_block_ur, 0,
+ tile_block_ur, v);
+ }
+ }
+ }
+
+ trans_O_4x4_3x3(Ow, O);
+
+ for (int j = 0; j < tile_size; j++) {
+ int ydim = tj * tile_size + j;
+ if (ydim < outh) {
+ float *pout_j = pout_b + ydim * outw * simd_w;
+ for (int i = 0; i < tile_size; i++) {
+ int xdim = ti * tile_size + i;
+ if (xdim < outw) {
+ float *pout_i = pout_j + xdim * simd_w;
+ if (is_fwd) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ O[j][i][v] += with_bias ? bias[v] : 0.f;
+ O[j][i][v] = true
+ && with_relu_presum && O[j][i][v] < 0.f
+ ? O[j][i][v]
+ * jcp.eltwise.alpha
+ : O[j][i][v];
+ }
+ }
+ if (with_sum)
+ accum_output(pout_i, O[j][i], streamout,
+ with_relu_postsum);
+ else
+ store_output(pout_i, O[j][i], streamout);
+ }
+ }
+ }
+ }
+ tile_block_ur++;
+ if (tile_block_ur >= jcp.tile_block_ur) {
+ tile_block_ur = 0;
+ nb_tile_block_ur++;
+ }
+ if (nb_tile_block_ur >= jcp.nb_tile_block_ur) {
+ nb_tile_block_ur = 0;
+ tile_block++;
+ }
+ }
+ }
+}
+
+template <bool ver_4fma>
+void diff_src_transform_bwd_weights(int image, jit_conv_winograd_conf_t conv,
+ float *inp, float *tinp, float *Iw_temp,
+ void (*transpose_4fma_ker)(float *, float *))
+{
+
+ const int ifwp = conv.iw + conv.l_pad;
+ const int ifhp = conv.ih + conv.t_pad;
+ float I[alpha][alpha][simd_w];
+ float Iw[alpha][alpha][simd_w];
+
+ array_offset_calculator<float, 4> Iw_trans_temp(Iw_temp,
+ alpha, alpha, conv.tile_4fma, simd_w);
+ array_offset_calculator<float, 5> input(inp,
+ conv.mb, conv.ic/simd_w, conv.ih, conv.iw, simd_w);
+ array_offset_calculator<float, 8> output(tinp,
+ conv.nb_ic, alpha, alpha,
+ conv.tile_block, conv.ic_block,
+ conv.nb_tile_block_ur, conv.tile_block_ur,
+ conv.ic_simd_block * conv.tile_4fma);
+
+ int tile_base_index =
+ image * (conv.itiles * conv.jtiles + conv.tile_4fma_padding);
+ int tile_4fma = 0;
+ int tile_block_ur = (tile_base_index / conv.tile_4fma) % conv.tile_block_ur;
+ int nb_tile_block_ur =
+ (tile_base_index / conv.tile_4fma / conv.tile_block_ur)
+ % conv.nb_tile_block_ur;
+ int tile_block = (tile_base_index / conv.tile_4fma / conv.tile_block_ur)
+ / conv.nb_tile_block_ur;
+
+ for (int tj = 0; tj < conv.jtiles; tj++) {
+ for (int ti = 0; ti < conv.itiles; ti++) {
+ for (int j = 0; j < alpha; j++) {
+ int ydim = tj * tile_size + j;
+ if ((conv.t_pad <= ydim) && ydim < ifhp) {
+ for (int i = 0; i < alpha; i++) {
+ int xdim = ti * tile_size + i;
+ if ((conv.l_pad <= xdim) && xdim < ifwp) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ I[j][i][v] = input(0, 0,
+ ydim - conv.t_pad,
+ xdim - conv.l_pad, v);
+ }
+ } else {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ I[j][i][v] = 0.0f;
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < alpha; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ I[j][i][v] = 0.0f;
+ }
+ }
+ }
+ }
+ trans_I_4x4_3x3(Iw, I);
+
+ if (ver_4fma) {
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ float *Iw_temp_base = &(Iw_trans_temp(j, i,
+ tile_4fma, 0));
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ Iw_temp_base[v] = Iw[j][i][v];
+ }
+ }
+ }
+ tile_4fma++;
+ if (tile_4fma == conv.tile_4fma) {
+ float *outp = &(output(0, 0, 0,
+ tile_block, 0,
+ nb_tile_block_ur, tile_block_ur, 0));
+ transpose_4fma_ker(outp, (float *)Iw_temp);
+ tile_4fma = 0;
+ tile_block_ur++;
+ }
+ } else {
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ store_output(&(output(0, j, i,
+ tile_block, 0,
+ nb_tile_block_ur, tile_block_ur, 0)),
+ Iw[j][i], true);
+ }
+ }
+ tile_block_ur++;
+ }
+
+ if (tile_block_ur == conv.tile_block_ur) {
+ tile_block_ur = 0;
+ ++nb_tile_block_ur;
+ }
+ if (nb_tile_block_ur == conv.nb_tile_block_ur) {
+ nb_tile_block_ur = 0;
+ tile_block++;
+ }
+ }
+ }
+
+ if (ver_4fma && tile_4fma < conv.tile_4fma && conv.tile_4fma_padding != 0) {
+
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ for (int tb = tile_4fma; tb < conv.tile_4fma; tb++) {
+ float *Iw_temp_base = &(Iw_trans_temp(j, i, tb, 0));
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ Iw_temp_base[v] = 0;
+ }
+ }
+ }
+ }
+ float *outp = &(output(0, 0, 0,
+ tile_block, 0,
+ nb_tile_block_ur, tile_block_ur, 0));
+ transpose_4fma_ker(outp, (float *)Iw_temp);
+ }
+}
+
+template <bool with_bias>
+void diff_dst_transform_bwd_weights(int image, jit_conv_winograd_conf_t conv,
+ float *inp, float *tinp, float *dbias)
+{
+
+ const int total_tiles = conv.itiles * conv.jtiles + conv.tile_4fma_padding;
+ float I[alpha][alpha][simd_w];
+ float Iw[alpha][alpha][simd_w];
+
+ array_offset_calculator<float, 5> input(inp,
+ conv.mb, conv.oc/simd_w, conv.oh, conv.ow, conv.oc_simd_block);
+ array_offset_calculator<float, 8> output(tinp,
+ conv.nb_oc, alpha, alpha,
+ conv.tile_block, conv.oc_block,
+ conv.nb_tile_block_ur,
+ conv.tile_block_ur * conv.tile_4fma, conv.oc_simd_block);
+
+ int tile_base_index = image * total_tiles;
+ int tile_block_ur = tile_base_index % (conv.tile_block_ur * conv.tile_4fma);
+ int nb_tile_block_ur =
+ (tile_base_index / conv.tile_block_ur / conv.tile_4fma)
+ % conv.nb_tile_block_ur;
+ int tile_block = (tile_base_index / conv.tile_block_ur / conv.tile_4fma)
+ / conv.nb_tile_block_ur;
+
+ for (int tj = 0; tj < conv.jtiles; tj++) {
+ for (int ti = 0; ti < conv.itiles; ti++) {
+ for (int j = 0; j < alpha; j++) {
+ int ydim = tj * tile_size + j;
+ if (ydim < conv.oh) {
+ for (int i = 0; i < alpha; i++) {
+ int xdim = ti * tile_size + i;
+ if (xdim < conv.ow) {
+ float *input_base = &(input(0, 0, ydim, xdim, 0));
+
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ I[j][i][v] = input_base[v];
+ }
+ if (with_bias && j < tile_size && i < tile_size) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ dbias[v] += input_base[v];
+ }
+ }
+ } else {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ I[j][i][v] = 0.0f;
+ }
+ }
+ }
+ } else {
+ for (int i = 0; i < alpha; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ I[j][i][v] = 0.0f;
+ }
+ }
+ }
+ }
+
+ trans_W_3x3_4x4_wu(Iw, I);
+
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ store_output(&(output(0, j, i,
+ tile_block, 0,
+ nb_tile_block_ur,
+ tile_block_ur, 0)),
+ Iw[j][i], true);
+ }
+ }
+ tile_block_ur++;
+ if (tile_block_ur >= conv.tile_block_ur * conv.tile_4fma) {
+ tile_block_ur = 0;
+ nb_tile_block_ur++;
+ }
+ if (nb_tile_block_ur >= conv.nb_tile_block_ur) {
+ nb_tile_block_ur = 0;
+ tile_block++;
+ }
+ }
+ }
+}
+
+void diff_weights_transform_bwd_weights(jit_conv_winograd_conf_t conv,
+ float *wp, float *twp)
+{
+ const int kh = 3;
+ const int kw = 3;
+ float Fw[alpha][alpha][simd_w][simd_w];
+ float F[kh][kw][simd_w][simd_w];
+
+ array_offset_calculator<float, 8> input(twp,
+ conv.nb_ic, conv.nb_oc,
+ alpha, alpha,
+ conv.oc_block, conv.ic_block,
+ conv.ic_simd_block, conv.oc_simd_block);
+ array_offset_calculator<float, 6> output(wp,
+ conv.oc/simd_w, conv.ic/simd_w,
+ conv.kh, conv.kw,
+ conv.ic_simd_block, conv.oc_simd_block);
+
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ for (int v = 0; v < conv.ic_simd_block; v++) {
+ PRAGMA_OMP_SIMD()
+ for (int k = 0; k < conv.oc_simd_block; k++) {
+ Fw[j][i][v][k] = input(0, 0, j, i, 0, 0, v, k);
+ }
+ }
+ }
+ }
+
+ trans_O_3x3_4x4_wu(Fw, F);
+
+ for (int j = 0; j < kh; j++) {
+ for (int i = 0; i < kw; i++) {
+ for (int v = 0; v < conv.ic_simd_block; v++) {
+ store_output(&(output(0, 0, j, i, v, 0)),
+ F[j][i][v], true);
+ }
+ }
+ }
+}
+
+template <bool is_fwd>
+void _jit_avx512_common_convolution_winograd_t<is_fwd>::_execute_data_W_S_G_D(
+ float *inp_ptr, float *out_ptr, float *wei_ptr, float *bias_ptr,
+ const memory_tracking::grantor_t &scratchpad) const {
+ const auto &jcp = kernel_->jcp;
+ const auto &p_ops = attr_->post_ops_;
+
+ const int inph = is_fwd ? jcp.ih : jcp.oh;
+ const int inpw = is_fwd ? jcp.iw : jcp.ow;
+ const int outh = is_fwd ? jcp.oh : jcp.ih;
+ const int outw = is_fwd ? jcp.ow : jcp.iw;
+
+ /* Note that jcp.with_eltwise is true for both fused conv+relu primitive
+ * and conv primitive with PostOps with relu before sum
+ * (PostOps relu after sum is handled later) */
+ auto output_transform = jcp.with_bias
+ ? (jcp.with_eltwise
+ ? (jcp.with_sum
+ ? output_transform_data<is_fwd, true, true, true>
+ : output_transform_data<is_fwd, true, true, false>)
+ : (jcp.with_sum
+ ? output_transform_data<is_fwd, true, false, true>
+ : output_transform_data<is_fwd, true, false, false>))
+ : (jcp.with_eltwise
+ ? (jcp.with_sum
+ ? output_transform_data<is_fwd, false, true, true>
+ : output_transform_data<is_fwd, false, true, false>)
+ : (jcp.with_sum
+ ? output_transform_data<is_fwd, false, false, true>
+ : output_transform_data<is_fwd, false, false, false>));
+
+ /* Notation:
+ FWD: dimM:oc, dimN:ntiles, dimK:ic,
+ BWD: dimM:ic, dimN:ntiles, dimK:oc,
+ FWD/BWD: V: src/diff_dst transform, U:weight transform,
+ M:dst/diff_src transform */
+ array_offset_calculator<float, 5> input(inp_ptr,
+ jcp.mb, jcp.dimK/jcp.dimK_reg_block, inph, inpw,
+ jcp.dimK_reg_block);
+ array_offset_calculator<float, 5> output(out_ptr,
+ jcp.mb, jcp.dimM/jcp.dimM_simd_block, outh, outw,
+ jcp.dimM_simd_block);
+ array_offset_calculator<float, 6> weights(wei_ptr,
+ jcp.oc/jcp.oc_simd_block, jcp.ic/jcp.ic_simd_block, jcp.kh, jcp.kw,
+ jcp.ic_simd_block, jcp.oc_simd_block);
+ array_offset_calculator<float, 2> bias(bias_ptr,
+ jcp.dimM/jcp.dimM_simd_block, jcp.dimM_simd_block);
+
+ array_offset_calculator<float, 8> M(is_fwd
+ ? scratchpad.template get<float>(key_wino_M)
+ : scratchpad.template get<float>(key_wino_V),
+ jcp.dimN_nb_block, jcp.dimM_nb_block,
+ alpha, alpha,
+ jcp.dimN_block, jcp.dimM_block,
+ jcp.dimN_reg_block, jcp.dimM_simd_block);
+ array_offset_calculator<float, 8> U(
+ scratchpad.template get<float>(key_wino_U),
+ jcp.dimM_nb_block,
+ alpha, alpha,
+ jcp.dimK_nb_block,
+ jcp.dimM_block, jcp.dimK_block,
+ jcp.dimK_reg_block, jcp.dimM_simd_block);
+ array_offset_calculator<float, 8> V(is_fwd
+ ? scratchpad.template get<float>(key_wino_V)
+ : scratchpad.template get<float>(key_wino_M),
+ jcp.dimN_nb_block, alpha, alpha,
+ jcp.dimN_block, jcp.dimK_nb_block,
+ jcp.dimK_block, jcp.dimN_reg_block, jcp.dimK_reg_block);
+
+ bool V_streamout = jcp.dimN * jcp.dimK * alpha * alpha * sizeof(float)
+ > 2 * LLC_cache_size ? true : false;
+
+ const bool output_is_aligned = ((size_t)out_ptr & (64 - 1)) == 0;
+
+ const bool wants_padded_bias = jcp.with_bias
+ && jcp.oc_without_padding != jcp.oc;
+ float last_slice_bias[simd_w] = {0};
+ if (wants_padded_bias) {
+ for (int oc = 0; oc < jcp.oc_without_padding % jcp.oc_simd_block; ++oc)
+ last_slice_bias[oc] = bias(jcp.dimM / jcp.dimM_simd_block - 1, oc);
+ }
+
+ {
+ parallel_nd(jcp.mb, jcp.dimK_nb_block, jcp.dimK_block,
+ [&](int img, int K_blk1, int K_blk2) {
+ input_transform_data<is_fwd>(img, jcp,
+ &(input(img, K_blk1 * jcp.dimK_block + K_blk2, 0, 0, 0)),
+ &(V(0, 0, 0, 0, K_blk1, K_blk2, 0, 0)), V_streamout);
+ });
+
+ parallel_nd(jcp.nb_oc, jcp.nb_ic, jcp.oc_block, jcp.ic_block,
+ [&](int ofm1, int ifm1, int ofm2, int ifm2) {
+ float *U_base_ptr = is_fwd
+ ? &(U(ofm1, 0, 0, ifm1, ofm2, ifm2, 0, 0))
+ : &(U(ifm1, 0, 0, ofm1, ifm2, ofm2, 0, 0));
+ weight_transform_data<is_fwd>(jcp,
+ &(weights(ofm1 * jcp.oc_block + ofm2,
+ ifm1 * jcp.ic_block + ifm2, 0, 0, 0, 0)), U_base_ptr);
+ });
+
+ parallel_nd(jcp.dimN_nb_block, alpha, alpha, jcp.dimM_nb_block, jcp.dimN_block,
+ [&](int N_blk1, int oj, int oi, int M_blk1, int N_blk2) {
+
+ kernel_->gemm_loop_ker_first_iter(
+ (float *)&(M(N_blk1, M_blk1, oj, oi,
+ N_blk2, 0, 0, 0)),
+ (const float *)&(U(M_blk1, oj, oi,
+ 0, 0, 0, 0, 0)),
+ (const float *)&(V(N_blk1, oj, oi,
+ N_blk2, 0, 0, 0, 0)));
+ for (int K_blk1 = 1; K_blk1 < jcp.dimK_nb_block; K_blk1++) {
+ kernel_->gemm_loop_ker(
+ (float *)&(M(N_blk1, M_blk1, oj, oi,
+ N_blk2, 0, 0, 0)),
+ (const float *)&(U(M_blk1, oj, oi,
+ K_blk1, 0, 0, 0, 0)),
+ (const float *)&(V(N_blk1, oj, oi,
+ N_blk2, K_blk1,
+ 0, 0, 0)));
+ }
+
+ });
+
+ parallel_nd(jcp.mb, jcp.dimM_nb_block, jcp.dimM_block,
+ [&](int img, int M_blk1, int M_blk2) {
+
+ const int M_blk = M_blk1 * jcp.dimM_block + M_blk2;
+
+ float *bias_ptr = wants_padded_bias
+ && M_blk == jcp.dimM / jcp.dimM_simd_block - 1
+ ? last_slice_bias : &bias(M_blk, 0);
+
+ output_transform(img, jcp, p_ops,
+ &(M(0, M_blk1, 0, 0, 0, M_blk2, 0, 0)),
+ &(output(img, M_blk, 0, 0, 0)),
+ bias_ptr, output_is_aligned);
+
+ });
+
+ }
+}
+
+template struct _jit_avx512_common_convolution_winograd_t<true>;
+template struct _jit_avx512_common_convolution_winograd_t<false>;
+
+void jit_avx512_common_convolution_winograd_bwd_weights_t::
+_maybe_execute_diff_bias_copy(float *diff_bias,
+ const memory_tracking::grantor_t &scratchpad) const {
+ if (pd()->wants_padded_bias()) {
+ auto padded_bias = scratchpad.get<float>(key_conv_padded_bias);
+ for (int oc = 0; oc < pd()->jcp_.oc_without_padding; ++oc)
+ diff_bias[oc] = padded_bias[oc];
+ }
+}
+
+void jit_avx512_common_convolution_winograd_bwd_weights_t::
+_execute_backward_weights_S_D_G_W(const exec_ctx_t &ctx,
+ const memory_tracking::grantor_t &scratchpad) const {
+ auto ptr_diff_dst = CTX_IN_MEM(const float *, MKLDNN_ARG_DIFF_DST);
+ auto ptr_src = CTX_IN_MEM(const float *, MKLDNN_ARG_SRC);
+ auto ptr_diff_weights = CTX_OUT_MEM(float *, MKLDNN_ARG_DIFF_WEIGHTS);
+ auto ptr_diff_bias = CTX_OUT_MEM(float *, MKLDNN_ARG_DIFF_BIAS);
+
+ const auto &jcp = kernel_->jcp;
+ const int nthreads = jcp.nthr;
+
+ auto diff_src_transform_bwd_weights_ver = jcp.ver == ver_4fma ?
+ diff_src_transform_bwd_weights<true> :
+ diff_src_transform_bwd_weights<false>;
+ auto diff_dst_transform_bwd_weights_ver = jcp.with_bias
+ ? diff_dst_transform_bwd_weights<true>
+ : diff_dst_transform_bwd_weights<false>;
+
+ array_offset_calculator<float, 5> src((float *)ptr_src,
+ jcp.mb, jcp.ic/simd_w, jcp.ih, jcp.iw, simd_w);
+ array_offset_calculator<float, 5> diff_dst((float *)ptr_diff_dst,
+ jcp.mb, jcp.oc/simd_w, jcp.oh, jcp.ow, simd_w);
+ array_offset_calculator<float, 6> diff_weights(ptr_diff_weights,
+ jcp.oc/simd_w, jcp.ic/simd_w, jcp.kh, jcp.kw, simd_w, simd_w);
+ array_offset_calculator<float, 2> diff_bias(pd()->wants_padded_bias()
+ ? scratchpad.get<float>(key_conv_padded_bias) : ptr_diff_bias,
+ jcp.oc/simd_w, simd_w);
+
+ array_offset_calculator<float, 8> U(
+ scratchpad.get<float>(key_wino_U),
+ jcp.nb_ic, jcp.nb_oc,
+ alpha, alpha,
+ jcp.oc_block, jcp.ic_block,
+ jcp.ic_simd_block, jcp.oc_simd_block);
+
+ array_offset_calculator<float, 8> M(
+ scratchpad.get<float>(key_wino_M),
+ jcp.nb_oc, alpha, alpha,
+ jcp.tile_block, jcp.oc_block,
+ jcp.nb_tile_block_ur, jcp.tile_block_ur * jcp.tile_4fma,
+ jcp.oc_simd_block);
+ array_offset_calculator<float, 8> V(
+ scratchpad.get<float>(key_wino_V),
+ jcp.nb_ic, alpha, alpha,
+ jcp.tile_block, jcp.ic_block,
+ jcp.nb_tile_block_ur, jcp.tile_block_ur,
+ jcp.ic_simd_block * jcp.tile_4fma);
+
+ const int trans_buffer_size = alpha * alpha * jcp.tile_4fma
+ * jcp.ic_simd_block;
+ array_offset_calculator<float, 2> trans_buffer(
+ scratchpad.get<float>(key_conv_tr_src),
+ nthreads,
+ trans_buffer_size);
+
+ array_offset_calculator<float, 2> diff_bias_prv(
+ scratchpad.get<float>(key_conv_bia_reduction),
+ nthreads,
+ jcp.oc);
+
+PRAGMA_OMP(parallel num_threads(nthreads))
+ {
+ if (jcp.with_bias) {
+ parallel_nd_in_omp(nthreads, jcp.oc, [&](int ithr, int ofm) {
+ diff_bias_prv(ithr, ofm) = 0.0f;
+ });
+
+PRAGMA_OMP(for nowait)
+ for (int bofm = 0; bofm < jcp.oc / simd_w; bofm++) {
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++)
+ diff_bias(bofm, v) = 0.0f;
+ }
+ }
+
+ const int ithread = mkldnn_get_thread_num();
+
+ parallel_nd_in_omp(jcp.mb, jcp.nb_ic, jcp.ic_block,
+ [&](int img, int ifm1, int ifm2) {
+ float *transb = jcp.ver == ver_4fma
+ ? &(trans_buffer(ithread, 0))
+ : NULL;
+ diff_src_transform_bwd_weights_ver(img, jcp,
+ &(src(img, ifm1 * jcp.ic_block + ifm2,
+ 0, 0, 0)),
+ &(V(ifm1, 0, 0, 0, ifm2, 0, 0, 0)),
+ transb,
+ kernel_->transpose_4fma_ker);
+ });
+
+ parallel_nd_in_omp(jcp.mb, jcp.nb_oc, jcp.oc_block,
+ [&](int img, int ofm1, int ofm2) {
+ float *dbias = jcp.with_bias
+ ? &(diff_bias_prv(ithread,
+ simd_w * (ofm1 * jcp.oc_block + ofm2)))
+ : NULL;
+ diff_dst_transform_bwd_weights_ver(img, jcp,
+ &(diff_dst(img, ofm1 * jcp.oc_block + ofm2,
+ 0, 0, 0)),
+ &(M(ofm1, 0, 0, 0, ofm2, 0, 0, 0)),
+ dbias);
+ });
+
+PRAGMA_OMP(barrier)
+
+ for (int ifm1 = 0; ifm1 < jcp.nb_ic; ifm1++) {
+ parallel_nd_in_omp(alpha, alpha, jcp.nb_oc,
+ [&](int oj, int oi, int ofm1) {
+ kernel_->gemm_loop_ker_first_iter(
+ (float *)&(U(ifm1, ofm1, oj, oi,
+ 0, 0, 0, 0)),
+ (const float *)&(M(ofm1, oj, oi,
+ 0, 0, 0, 0, 0)),
+ (const float *)&(V(ifm1, oj, oi,
+ 0, 0, 0, 0, 0)));
+ for (int tile_block = 1; tile_block < jcp.tile_block;
+ tile_block++) {
+ kernel_->gemm_loop_ker((float *)&(U(ifm1, ofm1,
+ oj, oi,
+ 0, 0, 0, 0)),
+ (const float *)&(M(ofm1, oj, oi, tile_block,
+ 0, 0, 0, 0)),
+ (const float *)&(V(ifm1, oj, oi, tile_block,
+ 0, 0, 0, 0)));
+ }
+ });
+ }
+
+PRAGMA_OMP(barrier)
+
+ parallel_nd_in_omp(jcp.nb_ic, jcp.nb_oc, jcp.oc_block, jcp.ic_block,
+ [&](int ifm1, int ofm1, int ofm2, int ifm2) {
+ diff_weights_transform_bwd_weights(jcp,
+ &(diff_weights(ofm1 * jcp.oc_block + ofm2,
+ ifm1 * jcp.ic_block + ifm2, 0, 0, 0, 0)),
+ &(U(ifm1, ofm1, 0, 0, ofm2, ifm2, 0, 0)));
+ });
+
+ if (jcp.with_bias) {
+PRAGMA_OMP(for)
+ for (int ofm1 = 0; ofm1 < jcp.oc / simd_w; ofm1++) {
+ for (int ithr = 0; ithr < nthreads; ithr++) {
+ float* base_bias_ptr = &(diff_bias(ofm1, 0));
+ float* base_bias_prv_ptr = &(diff_bias_prv(
+ ithr * jcp.oc + ofm1 * simd_w));
+ PRAGMA_OMP_SIMD()
+ for (int ofm2 = 0; ofm2 < simd_w; ofm2++) {
+ base_bias_ptr[ofm2] += base_bias_prv_ptr[ofm2];
+ }
+ }
+ }
+ }
+ }
+
+ _maybe_execute_diff_bias_copy(ptr_diff_bias, scratchpad);
+}
+
+}
+}
+}
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution_winograd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution_winograd.hpp
new file mode 100644
index 0000000000..6c76f37c72
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_convolution_winograd.hpp
@@ -0,0 +1,318 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_COMMON_CONVOLUTION_WINOGRAD_HPP
+#define CPU_JIT_AVX512_COMMON_CONVOLUTION_WINOGRAD_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "jit_avx512_common_conv_winograd_kernel_f32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace winograd_avx512_common {
+inline void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_winograd_conf_t &jcp) {
+ using namespace memory_tracking::names;
+
+ size_t U_sz = (size_t)alpha * alpha * jcp.ic * jcp.oc;
+ size_t V_sz = (size_t)alpha * alpha * jcp.mb * jcp.ic
+ * (jcp.itiles * jcp.jtiles + jcp.tile_4fma_padding);
+ size_t M_sz = (size_t)alpha * alpha * jcp.mb * jcp.oc
+ * (jcp.itiles * jcp.jtiles + jcp.tile_4fma_padding);
+
+ scratchpad.book(key_wino_U, sizeof(float) * U_sz, PAGE_2M);
+ scratchpad.book(key_wino_V, sizeof(float) * V_sz, PAGE_2M);
+ scratchpad.book(key_wino_M, sizeof(float) * M_sz, PAGE_2M);
+
+ if (jcp.sched_policy == WSCHED_WEI_S_D_G_W) {
+ const int nthr = mkldnn_get_max_threads();
+
+ size_t tr_src_sz = jcp.ver != ver_4fma ? 0 : (size_t)nthr
+ * alpha * alpha * jcp.tile_4fma * jcp.ic_simd_block;
+ scratchpad.book(key_conv_tr_src, sizeof(float) * tr_src_sz, PAGE_2M);
+
+ size_t br_sz = jcp.with_bias ? nthr * jcp.oc : 0;
+ scratchpad.book(key_conv_bia_reduction, sizeof(float) * br_sz, PAGE_2M);
+
+ size_t padded_bias_sz =
+ jcp.with_bias && jcp.oc_without_padding != jcp.oc ? jcp.oc : 0;
+ scratchpad.book(key_conv_padded_bias, sizeof(float) * padded_bias_sz);
+ }
+}
+}
+
+template <bool is_fwd>
+struct _jit_avx512_common_convolution_winograd_t {
+ _jit_avx512_common_convolution_winograd_t(
+ const jit_conv_winograd_conf_t &jcp, const primitive_attr_t *attr)
+ : kernel_(nullptr), attr_(attr) {
+ kernel_ = new _jit_avx512_common_conv_winograd_data_kernel_f32(jcp);
+ }
+
+ ~_jit_avx512_common_convolution_winograd_t() { delete kernel_; }
+
+ protected:
+ void _execute_data_W_S_G_D(float *inp_ptr, float *out_ptr,
+ float *wei_ptr, float *bias_ptr,
+ const memory_tracking::grantor_t &scratchpad) const;
+ _jit_avx512_common_conv_winograd_data_kernel_f32 *kernel_;
+ const primitive_attr_t *attr_;
+};
+
+struct jit_avx512_common_convolution_winograd_fwd_t
+ : _jit_avx512_common_convolution_winograd_t<true>
+ , public cpu_primitive_t
+ {
+ struct pd_t : public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_wino:", avx512_common, ""),
+ jit_avx512_common_convolution_winograd_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && utils::one_of(desc()->alg_kind,
+ alg_kind::convolution_auto,
+ alg_kind::convolution_winograd)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_avx512_common_conv_winograd_fwd_kernel_f32::
+ init_conf(jcp_, *desc(), *src_md(), *weights_md(), *dst_md(),
+ *attr());
+ if (status != status::success) return status;
+ set_default_alg_kind(alg_kind::convolution_winograd);
+
+ auto scratchpad = scratchpad_registry().registrar();
+ winograd_avx512_common::init_scratchpad(scratchpad, jcp_);
+
+ return status;
+ }
+
+ jit_conv_winograd_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+ auto wei_tag = with_groups() ? gOIhw16i16o : OIhw16i16o;
+ return set_default_formats_common(nChw16c, wei_tag, nChw16c);
+ }
+ };
+
+ jit_avx512_common_convolution_winograd_fwd_t(const pd_t *apd)
+ : _jit_avx512_common_convolution_winograd_t<true>(apd->jcp_, apd->attr())
+ , cpu_primitive_t(apd, true) {}
+
+ ~jit_avx512_common_convolution_winograd_fwd_t(){};
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override
+ {
+ auto src = CTX_IN_MEM(const float *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const float *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const float *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(float *, MKLDNN_ARG_DST);
+ this->_execute_data_W_S_G_D((float *)src, dst, (float *)weights,
+ (float *)bias, this->scratchpad(ctx));
+ return status::success;
+ }
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+struct jit_avx512_common_convolution_winograd_bwd_data_t
+ : _jit_avx512_common_convolution_winograd_t<false>,
+ public cpu_primitive_t {
+ struct pd_t : public cpu_convolution_bwd_data_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_data_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_wino:", avx512_common, ""),
+ jit_avx512_common_convolution_winograd_bwd_data_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_data
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::undef, data_type::f32, data_type::f32)
+ && utils::one_of(desc()->alg_kind,
+ alg_kind::convolution_auto,
+ alg_kind::convolution_winograd)
+ && !has_zero_dim_memory()
+ && set_default_formats()
+ && mkldnn_thr_syncable();
+ if (!ok) return status::unimplemented;
+
+ status_t status =
+ jit_avx512_common_conv_winograd_bwd_data_kernel_f32::init_conf(
+ jcp_, *desc(), *diff_src_md(), *weights_md(),
+ *diff_dst_md());
+ if (status != status::success) return status;
+ set_default_alg_kind(alg_kind::convolution_winograd);
+
+ auto scratchpad = scratchpad_registry().registrar();
+ winograd_avx512_common::init_scratchpad(scratchpad, jcp_);
+
+ return status;
+ }
+
+ jit_conv_winograd_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+ auto wei_tag = with_groups() ? gOIhw16i16o : OIhw16i16o;
+ return set_default_formats_common(nChw16c, wei_tag, nChw16c);
+ }
+ };
+
+ jit_avx512_common_convolution_winograd_bwd_data_t(const pd_t *apd)
+ : _jit_avx512_common_convolution_winograd_t<false>(apd->jcp_, apd->attr())
+ , cpu_primitive_t(apd, true) {}
+
+ ~jit_avx512_common_convolution_winograd_bwd_data_t(){};
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ auto diff_dst = CTX_IN_MEM(const float *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const float *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(float *, MKLDNN_ARG_DIFF_SRC);
+ this->_execute_data_W_S_G_D((float *)diff_dst, diff_src,
+ (float *)weights, nullptr, this->scratchpad(ctx));
+ return status::success;
+ }
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+struct jit_avx512_common_convolution_winograd_bwd_weights_t
+ : public cpu_primitive_t {
+ struct pd_t : public cpu_convolution_bwd_weights_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_weights_pd_t(engine, adesc, attr,
+ hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_wino:", avx512_common, ""),
+ jit_avx512_common_convolution_winograd_bwd_weights_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_weights
+ && utils::one_of(desc()->alg_kind,
+ alg_kind::convolution_auto,
+ alg_kind::convolution_winograd)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats()
+ && mkldnn_thr_syncable();
+ if (!ok) return status::unimplemented;
+
+ status_t status =
+ jit_avx512_common_conv_winograd_bwd_weights_kernel_f32::
+ init_conf(jcp_, *desc(), *src_md(), *diff_dst_md(),
+ *diff_weights_md());
+ if (status != status::success) return status;
+ set_default_alg_kind(alg_kind::convolution_winograd);
+
+ auto scratchpad = scratchpad_registry().registrar();
+ winograd_avx512_common::init_scratchpad(scratchpad, jcp_);
+
+ return status;
+ }
+
+ jit_conv_winograd_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+ auto wei_tag = with_groups() ? gOIhw16i16o : OIhw16i16o;
+ return set_default_formats_common(nChw16c, wei_tag, nChw16c);
+ }
+ };
+
+ jit_avx512_common_convolution_winograd_bwd_weights_t(const pd_t *apd)
+ : cpu_primitive_t(apd, true), kernel_(nullptr)
+ {
+ kernel_ = new jit_avx512_common_conv_winograd_bwd_weights_kernel_f32(
+ pd()->jcp_);
+ }
+
+ ~jit_avx512_common_convolution_winograd_bwd_weights_t()
+ { delete kernel_; }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override
+ {
+ _execute_backward_weights_S_D_G_W(ctx, scratchpad(ctx));
+ return status::success;
+ }
+
+private:
+ void _execute_backward_weights_S_D_G_W(const exec_ctx_t &ctx,
+ const memory_tracking::grantor_t &scratchpad) const;
+ void _maybe_execute_diff_bias_copy(float *diff_bias,
+ const memory_tracking::grantor_t &scratchpad) const;
+
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ jit_avx512_common_conv_winograd_bwd_weights_kernel_f32 *kernel_;
+};
+
+void trans_W_4x4_3x3(float Fw_[6][6][16][16], float F[3][3][16][16]);
+void trans_O_4x4_3x3(float Mw[6][6][16], float O[4][4][16]);
+void trans_W_3x3_4x4(float Fw[6][6][16], float F[4][6][16]);
+void trans_O_3x3_4x4(float Mw[6][6][16][16], float M[3][3][16][16]);
+void trans_I_4x4_3x3(float Iw[6][6][16], float I[6][6][16]);
+void trans_W_3x3_4x4_wu(float Fw[6][6][16], float F[4][6][16]);
+void trans_O_3x3_4x4_wu(float Mw[6][6][16][16], float M[3][3][16][16]);
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_lrn.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_lrn.cpp
new file mode 100644
index 0000000000..d4a451c021
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_lrn.cpp
@@ -0,0 +1,853 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_avx512_common_lrn.hpp"
+
+#include "jit_generator.hpp"
+
+#define FWD_RBC 4
+#define BWD_RBC 3
+
+#define XMM_SIZE (4*sizeof(float))
+#define ZMM_SIZE (vlen)
+#define BUFFER_BLOCK (XMM_SIZE + ZMM_SIZE + XMM_SIZE)
+#define BUFFER_NEXT_OFFSET (XMM_SIZE + ZMM_SIZE)
+#define SRC_PREV_OFFSET (vlen - XMM_SIZE)
+
+#define IRB_LOOP(statement) for(int irb = 0; irb < loop_size; irb++) { \
+ statement;\
+}
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::utils;
+
+using namespace Xbyak;
+
+enum params { vsize = 16, vlen = 64};
+
+typedef struct {
+ const float *src;
+ float *dst, *ws0, *ws1;
+} jit_args_fwd_t;
+
+typedef struct {
+ const float *src, *diff_dst, *ws0, *ws1;
+ float *diff_src;
+} jit_args_bwd_t;
+
+struct nChw16c_across {
+/* version:
+ * -1: channels 0..15,
+ * 1: channels C-16 .. C-1,
+ * 0: other channels
+ * 3: channels only for this kernel(without prev and next)
+ */
+ int H, W, version;
+ nChw16c_across(int h, int w, int v) : H(h), W(w), version(v) {}
+};
+
+struct jit_avx512_common_lrn_fwd_t::jit_avx512_common_lrn_kernel_f32:
+ public jit_generator {
+ int HW, W;
+ bool is_first;
+ bool is_last;
+ bool is_single;
+
+ Reg64 src = rax;
+ Reg64 dst = r8;
+ Reg64 scratch0 = rdx;
+ Reg64 scratch1 = rsi;
+ Reg64 imm_addr64 = rbx;
+
+ Zmm zalpha = zmm0;
+ Xmm xalpha = xmm0;
+ Zmm zk = zmm1;
+ Xmm xk = xmm1;
+
+ Reg64 param = abi_param1;
+ Reg64 t = rsp;
+ Reg64 hw = r9;
+
+ int xsrc_prev = 2;
+ int zsrc = 7;
+ int xsrc_next = 3;
+ int zc = 7;
+
+ int za = 2;
+ int zb = 3;
+ int zd = 5;
+ int ze = 6;
+ int zsum = 4;
+ int zdst = 2;
+ int zbase = 3;
+ int zsum2 = 5;
+
+ prop_kind_t pk;
+ int use_h_parallelism;
+
+ float alpha, k;
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_common_lrn_kernel_f32)
+
+ void (*ker)(jit_args_fwd_t *);
+ void operator()(jit_args_fwd_t *arg) { ker(arg); }
+
+ enum {
+ prf0_offt = 1*FWD_RBC,
+ prf2_offt = 8*FWD_RBC
+ };
+
+ inline void compute_loop(int loop_size_param)
+ {
+ // loop_size - param for IRB_LOOP macro
+ int loop_size = FWD_RBC;
+
+ auto xreg = [=](int irb, int i) {
+ return Xmm(irb*3 + i);
+ };
+
+ auto zreg = [=](int irb, int i) {
+ return Zmm(irb*7 + i);
+ };
+
+ if (!is_first && !is_single) {
+ IRB_LOOP(mic_prefetcht0(ptr[src + (irb + prf0_offt - HW)*vlen]));
+ IRB_LOOP(mic_prefetcht2(ptr[src + (irb + prf2_offt - HW)*vlen]));
+ }
+ IRB_LOOP(mic_prefetcht0(EVEX_compress_addr(src, (irb + prf0_offt)*vlen)));
+ IRB_LOOP(mic_prefetcht2(EVEX_compress_addr(src, (irb + prf2_offt)*vlen)));
+ if (!is_last && !is_single) {
+ IRB_LOOP(mic_prefetcht0(ptr[src + (irb + prf0_offt + HW)*vlen]));
+ IRB_LOOP(mic_prefetcht2(ptr[src + (irb + prf2_offt + HW)*vlen]));
+ }
+ if (pk != prop_kind::forward_inference) {
+ IRB_LOOP(mic_prefetcht0(EVEX_compress_addr(scratch0,
+ (irb + prf0_offt)*vlen)));
+ IRB_LOOP(mic_prefetcht2(EVEX_compress_addr(scratch0,
+ (irb + prf2_offt)*vlen)));
+ }
+ IRB_LOOP(mic_prefetcht0(EVEX_compress_addr(dst, (irb + prf0_offt)*vlen)));
+ IRB_LOOP(mic_prefetcht2(EVEX_compress_addr(dst, (irb + prf2_offt)*vlen)));
+ if (pk != prop_kind::forward_inference) {
+ IRB_LOOP(mic_prefetcht0(EVEX_compress_addr(scratch1,
+ (irb + prf0_offt) * vlen)));
+ IRB_LOOP(mic_prefetcht2(EVEX_compress_addr(scratch1,
+ (irb + prf2_offt) * vlen)));
+ }
+
+ loop_size = loop_size_param;
+ if (loop_size == 0)
+ return;
+ if (!is_first && !is_single) {
+ IRB_LOOP(vmovups(xreg(irb, xsrc_prev),
+ ptr[src + (irb - HW) * vlen + SRC_PREV_OFFSET]));
+ }
+ IRB_LOOP(vmovups(zreg(irb, zsrc), EVEX_compress_addr(src,irb*vlen)));
+ if (!is_last && !is_single) {
+ IRB_LOOP(vmovups(xreg(irb, xsrc_next),
+ ptr[src + (irb + HW) * vlen]));
+ }
+
+ if (!is_first && !is_single) {
+ IRB_LOOP(vmovups(ptr[t + irb*BUFFER_BLOCK],
+ xreg(irb, xsrc_prev)));
+ }
+ IRB_LOOP(vmovups(EVEX_compress_addr(t, irb*BUFFER_BLOCK + XMM_SIZE),
+ zreg(irb, zsrc)));
+ if (!is_last && !is_single) {
+ IRB_LOOP(vmovups(ptr[t + irb*BUFFER_BLOCK + BUFFER_NEXT_OFFSET],
+ xreg(irb, xsrc_next)));
+ }
+
+ IRB_LOOP(vmovups(zreg(irb, za), EVEX_compress_addr(t, irb*BUFFER_BLOCK
+ + XMM_SIZE - 2*sizeof(float))));
+ IRB_LOOP(vmovups(zreg(irb, zb), EVEX_compress_addr(t, irb*BUFFER_BLOCK
+ + XMM_SIZE - sizeof(float))));
+ IRB_LOOP(vmovups(zreg(irb, zd), EVEX_compress_addr(t, irb*BUFFER_BLOCK
+ + XMM_SIZE + sizeof(float))));
+ IRB_LOOP(vmovups(zreg(irb, ze), EVEX_compress_addr(t, irb*BUFFER_BLOCK
+ + XMM_SIZE + 2*sizeof(float))));
+
+ assert(zc == zsrc);
+ IRB_LOOP(vmulps(zreg(irb, zsum), zreg(irb, zc), zreg(irb, zc)));
+
+ IRB_LOOP(vfmadd231ps(zreg(irb, zsum), zreg(irb, za), zreg(irb, za)));
+ IRB_LOOP(vfmadd231ps(zreg(irb, zsum), zreg(irb, zb), zreg(irb, zb)));
+ IRB_LOOP(vfmadd231ps(zreg(irb, zsum), zreg(irb, zd), zreg(irb, zd)));
+ IRB_LOOP(vfmadd231ps(zreg(irb, zsum), zreg(irb, ze), zreg(irb, ze)));
+
+ IRB_LOOP(vfmadd132ps(zreg(irb, zsum), zk, zalpha));
+
+ IRB_LOOP(vmovaps(zreg(irb, zbase), zreg(irb, zsum)));
+
+ IRB_LOOP(vmulps(zreg(irb, zsum2), zreg(irb, zsum), zreg(irb, zsum)));
+ IRB_LOOP(vmulps(zreg(irb, zsum), zreg(irb, zsum), zreg(irb, zsum2)));
+
+ IRB_LOOP(vsqrtps(zreg(irb, zsum), zreg(irb, zsum)));
+ IRB_LOOP(vsqrtps(zreg(irb, zsum), zreg(irb, zsum)));
+
+ if (pk != prop_kind::forward_inference) {
+ IRB_LOOP(vmovups(EVEX_compress_addr(scratch0, irb*vlen),
+ zreg(irb, zsum)));
+ }
+ IRB_LOOP(vdivps(zreg(irb, zdst), zreg(irb, zsrc), zreg(irb, zsum)));
+ IRB_LOOP(vmovups(EVEX_compress_addr(dst, irb*vlen), zreg(irb, zdst)));
+ if (pk != prop_kind::forward_inference) {
+ /* ws1 = zdst / zbase = zsrc / (zbase^1.75) */
+ IRB_LOOP(vdivps(zreg(irb, zsum), zreg(irb, zdst), zreg(irb, zbase)));
+ IRB_LOOP(vmovups(EVEX_compress_addr(scratch1, irb*vlen),
+ zreg(irb, zsum)));
+ }
+ }
+
+ jit_avx512_common_lrn_kernel_f32(
+ const struct nChw16c_across &J,
+ prop_kind_t prop_kind,
+ int use_h_parallel,
+ float A,
+ float K,
+ void *code_ptr = nullptr,
+ size_t code_size = 2 * Xbyak::DEFAULT_MAX_CODE_SIZE)
+ : jit_generator(code_ptr, code_size)
+ , pk(prop_kind)
+ , use_h_parallelism(use_h_parallel)
+ , alpha(A)
+ , k(K)
+ {
+ this->preamble();
+
+ mov(src, ptr[param + 0]);
+ mov(dst, ptr[param + 8]);
+ if (pk != prop_kind::forward_inference)
+ {
+ mov(scratch0, ptr[param + 16]);
+ mov(scratch1, ptr[param + 24]);
+ }
+ is_first = J.version == -1 || J.version == -2;
+ is_last = J.version == +1 || J.version == -2;
+ is_single = J.version == 3;
+
+ W = J.W;
+ HW = J.W*J.H;
+ int LSB = use_h_parallelism ? W : HW;
+
+ sub(t, FWD_RBC*BUFFER_BLOCK);
+ mov(imm_addr64, float2int(this->alpha));
+ movq(xalpha, imm_addr64);
+ vbroadcastss(zalpha, xalpha);
+
+ mov(imm_addr64, float2int(this->k));
+ movq(xk, imm_addr64);
+ vbroadcastss(zk, xk);
+
+ if (is_first || is_single) {
+ vxorps(xmm2, xmm2, xmm2);
+ for(int irb = 0; irb < FWD_RBC; irb++) {
+ vmovups(ptr[t + irb*BUFFER_BLOCK], xmm2);
+ }
+ }
+ if (is_last || is_single) {
+ vxorps(xmm2, xmm2, xmm2);
+ for(int irb = 0; irb < FWD_RBC; irb++) {
+ vmovups(ptr[t + irb*BUFFER_BLOCK + BUFFER_NEXT_OFFSET],
+ xmm2);
+ }
+ }
+
+ int LSREST = LSB % FWD_RBC;
+ int LS = LSB - LSREST;
+
+ Label lrn_loop;
+
+ if (LS > 0) {
+ mov(hw, LS);
+
+ L(lrn_loop);
+ {
+ compute_loop(FWD_RBC);
+
+ add(src, FWD_RBC*vlen);
+ add(dst, FWD_RBC*vlen);
+ if (pk != prop_kind::forward_inference)
+ {
+ add(scratch0, FWD_RBC*vlen);
+ add(scratch1, FWD_RBC*vlen);
+ }
+
+ for(int irb = 0; irb < FWD_RBC; irb++)
+ dec(hw);
+ cmp(hw, 0);
+ jne(lrn_loop, T_NEAR);
+ }
+ }
+
+ compute_loop(LSREST);
+
+ add(t, FWD_RBC*BUFFER_BLOCK);
+ this->postamble();
+
+ ker = reinterpret_cast<decltype(ker)>(const_cast<uint8_t*>(
+ this->getCode()));
+ }
+};
+
+status_t jit_avx512_common_lrn_fwd_t::pd_t::init() {
+ using namespace prop_kind;
+ using namespace alg_kind;
+
+ const memory_desc_wrapper data_d(src_md());
+ bool ok = true
+ && mayiuse(avx512_common)
+ && is_fwd()
+ && !has_zero_dim_memory()
+ && everyone_is(data_type::f32, data_d.data_type())
+ && data_d.ndims() == 4
+ && data_d.dims()[1] % vsize == 0
+ && attr()->has_default_values();
+ if (!ok) return unimplemented;
+
+ if (desc()->prop_kind == forward_training) {
+ dims_t ws_dims = { MB(), C(), H(), 2*W() };
+ mkldnn_memory_desc_init_by_tag(&ws_md_, 4, ws_dims, data_type::f32,
+ format_tag::nChw16c);
+ }
+
+ bool args_ok_across = true
+ && desc()->alg_kind == lrn_across_channels
+ && desc()->local_size == 5
+ && desc()->lrn_beta == 0.75
+ && data_d.matches_tag(format_tag::nChw16c);
+
+ return args_ok_across ? success : unimplemented;
+}
+
+jit_avx512_common_lrn_fwd_t::jit_avx512_common_lrn_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , use_h_parallelism(0), ker_(nullptr), ker_first_(nullptr)
+ , ker_last_(nullptr) {
+ using namespace alg_kind;
+ const int C = pd()->C();
+ const int H = pd()->H();
+ const int W = pd()->W();
+ const int ls = pd()->desc()->local_size;
+ const float alpha = pd()->desc()->lrn_alpha / ls;
+ const float k = pd()->desc()->lrn_k;
+
+ auto pk = pd()->desc()->prop_kind;
+
+ use_h_parallelism = H > 28 ? 1 : 0;
+
+ if (C / vsize == 1) {
+ ker_ = new jit_avx512_common_lrn_kernel_f32(nChw16c_across(H, W, 3), pk,
+ use_h_parallelism, alpha, k);
+ } else {
+ ker_ = new jit_avx512_common_lrn_kernel_f32(nChw16c_across(H, W, 0), pk,
+ use_h_parallelism, alpha, k);
+ ker_first_ = new jit_avx512_common_lrn_kernel_f32(
+ nChw16c_across(H, W, -1), pk, use_h_parallelism, alpha, k);
+ ker_last_ = new jit_avx512_common_lrn_kernel_f32(
+ nChw16c_across(H, W, +1), pk, use_h_parallelism, alpha, k);
+ }
+}
+
+jit_avx512_common_lrn_fwd_t::~jit_avx512_common_lrn_fwd_t()
+{ delete ker_; delete ker_first_; delete ker_last_; }
+
+void jit_avx512_common_lrn_fwd_t::execute_forward(const exec_ctx_t &ctx) const
+{
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+ auto ws = CTX_OUT_MEM(data_t *, MKLDNN_ARG_WORKSPACE);
+
+ const int N = pd()->MB();
+ const int C = pd()->C();
+ const int H = pd()->H();
+ const int W = pd()->W();
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ size_t start{0}, end{0};
+ const int C16 = C / vsize;
+ const size_t work_amount = use_h_parallelism ? N*C16*H : N*C16;
+
+ balance211(work_amount, nthr, ithr, start, end);
+ if (use_h_parallelism) {
+ int n{0}, c16{0}, h{0};
+ nd_iterator_init(start, n, N, c16, C16, h, H);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ auto offset = n*C*H*W + c16*H*W*vsize
+ + h*W*vsize;
+ auto ws_offset0 = n*C*H*2*W + c16*H*2*W*vsize
+ + h*2*W*vsize;
+ auto ws_offset1 = ws_offset0 + W*vsize;
+
+ jit_args_fwd_t args;
+ args.src = &src[offset];
+ args.dst = &dst[offset];
+ args.ws0 = &ws[ws_offset0];
+ args.ws1 = &ws[ws_offset1];
+
+ if (C16 == 1)
+ (*ker_)(&args);
+ else if (c16 == 0)
+ (*ker_first_)(&args);
+ else if (c16 == C16 - 1)
+ (*ker_last_)(&args);
+ else
+ (*ker_)(&args);
+ nd_iterator_step(n, N, c16, C16, h, H);
+ }
+ } else {
+ int n{0}, c16{0};
+ nd_iterator_init(start, n, N, c16, C16);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ auto offset = n*C*H*W + c16*H*W*vsize;
+ auto ws_offset0 = n*C*H*2*W + c16*H*2*W*vsize;
+ auto ws_offset1 = ws_offset0 + H*W*vsize;
+
+ jit_args_fwd_t args;
+ args.src = &src[offset];
+ args.dst = &dst[offset];
+ args.ws0 = &ws[ws_offset0];
+ args.ws1 = &ws[ws_offset1];
+
+ if (C16 == 1)
+ (*ker_)(&args);
+ else if (c16 == 0)
+ (*ker_first_)(&args);
+ else if (c16 == C16 - 1)
+ (*ker_last_)(&args);
+ else
+ (*ker_)(&args);
+
+ nd_iterator_step(n, N, c16, C16);
+ }
+ }
+ });
+}
+
+struct jit_avx512_common_lrn_bwd_t::jit_avx512_common_lrn_kernel_f32:
+ public jit_generator {
+ int HW, W;
+ bool is_first;
+ bool is_last;
+ bool is_single;
+
+ Reg64 src = rax;
+ Reg64 diffsrc = r8;
+ Reg64 diffdst = r9;
+ Reg64 workspace0 = rdx;
+ Reg64 workspace1 = rsi;
+ Reg64 imm_addr64 = rbx;
+
+ Zmm znalphabeta = zmm0;
+ Xmm xnalphabeta = xmm0;
+
+ Reg64 param = abi_param1;
+ Reg64 t = rsp;
+ Reg64 hw = r10;
+
+ int xws1_prev = 1;
+ int xdiffdst_prev = 2;
+ int zws1 = 1;
+
+ int zsrc = 1;
+ int zdiffdst = 5;
+ int zdiffsrc = 6;
+
+ int xws1_next = 1;
+ int xdiffdst_next = 3;
+
+ int za = 1;
+ int zb = 2;
+ int zd = 3;
+ int ze = 4;
+ int zws0 = 2;
+
+ float nalphabeta;
+
+ int use_h_parallelism;
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_common_lrn_kernel_f32)
+
+ void (*ker)(jit_args_bwd_t *);
+ void operator()(jit_args_bwd_t *arg) { ker(arg); }
+
+ enum {
+ prf0_offt = 1*BWD_RBC,
+ prf2_offt = 8*BWD_RBC
+ };
+
+ inline void compute_loop(int loop_size_param, int prefetchL1,
+ int prefetchL2)
+ {
+ // loop_size - param for IRB_LOOP macro
+ int loop_size = loop_size_param;
+
+ auto xreg = [=](int irb, int i) {
+ return Xmm(irb*6 + i);
+ };
+
+ auto zreg = [=](int irb, int i) {
+ return Zmm(irb*6 + i);
+ };
+
+// ---- prefetching -------------------------------------------
+ if (!is_first && !is_single) {
+ if (prefetchL1)
+ IRB_LOOP(mic_prefetcht0(ptr[workspace1 + (irb + prf0_offt
+ - 2 * HW) * vlen]));
+ if (prefetchL1)
+ IRB_LOOP(mic_prefetcht0(ptr[diffdst + (irb + prf0_offt
+ - HW) * vlen]));
+ }
+
+ if (prefetchL1)
+ IRB_LOOP(mic_prefetcht0(ptr[src + (irb + prf0_offt)*vlen]));
+ if (prefetchL2)
+ IRB_LOOP(mic_prefetcht2(ptr[src + (irb + prf2_offt)*vlen]));
+
+ if (prefetchL1)
+ IRB_LOOP(mic_prefetcht0(ptr[workspace1 + (irb + prf0_offt)*vlen]));
+
+ if (prefetchL1)
+ IRB_LOOP(mic_prefetcht0(ptr[diffdst + (irb + prf0_offt)*vlen]));
+
+ if (!is_last && !is_single) {
+ if (prefetchL1)
+ IRB_LOOP(mic_prefetcht0(ptr[workspace1 + (irb + prf0_offt
+ + 2 * HW) * vlen]));
+ if (prefetchL2)
+ IRB_LOOP(mic_prefetcht2(ptr[workspace1 + (irb + prf2_offt
+ + 2 * HW) * vlen]));
+
+ if (prefetchL1)
+ IRB_LOOP(mic_prefetcht0(ptr[diffdst + (irb + prf0_offt
+ + HW) * vlen]));
+ if (prefetchL2)
+ IRB_LOOP(mic_prefetcht2(ptr[diffdst + (irb + prf2_offt
+ + HW) * vlen]));
+ }
+ if (prefetchL1)
+ IRB_LOOP(mic_prefetcht0(ptr[workspace0 + (irb + prf0_offt)*vlen]));
+ if (prefetchL2)
+ IRB_LOOP(mic_prefetcht2(ptr[workspace0 + (irb + prf2_offt)*vlen]));
+// -----------------------------------------------------------
+
+ if (loop_size_param == 0)
+ return;
+
+ if (!is_first && !is_single) {
+ IRB_LOOP(vmovups(xreg(irb, xws1_prev), ptr[workspace1 + (irb
+ - 2 * HW) * vlen + SRC_PREV_OFFSET]));
+ IRB_LOOP(vmovups(xreg(irb, xdiffdst_prev), ptr[diffdst + (irb
+ - HW) * vlen + SRC_PREV_OFFSET]));
+ IRB_LOOP(vmulps(xreg(irb, xdiffdst_prev), xreg(irb, xdiffdst_prev),
+ xreg(irb, xws1_prev)));
+ }
+
+ IRB_LOOP(vmovups(zreg(irb, zws1),
+ EVEX_compress_addr(workspace1, irb*vlen)));
+ IRB_LOOP(vmovups(zreg(irb, zdiffdst),
+ EVEX_compress_addr(diffdst, irb*vlen)));
+ IRB_LOOP(vmulps(zreg(irb, zdiffsrc), zreg(irb, zdiffdst),
+ zreg(irb, zws1)));
+
+ if (!is_last && !is_single) {
+ IRB_LOOP(vmovups(xreg(irb, xws1_next), ptr[workspace1 + (irb
+ + 2 * HW) * vlen]));
+ IRB_LOOP(vmovups(xreg(irb, xdiffdst_next), ptr[diffdst + (irb
+ + HW) * vlen]));
+ IRB_LOOP(vmulps(xreg(irb, xdiffdst_next), xreg(irb, xdiffdst_next),
+ xreg(irb, xws1_next)));
+ }
+
+ if (!is_first && !is_single) {
+ IRB_LOOP(vmovups(ptr[t + irb*BUFFER_BLOCK],
+ xreg(irb, xdiffdst_prev)));
+ }
+ IRB_LOOP(vmovups(EVEX_compress_addr(t, irb*BUFFER_BLOCK + XMM_SIZE),
+ zreg(irb, zdiffsrc)));
+ if (!is_last && !is_single) {
+ IRB_LOOP(vmovups(ptr[t + irb*BUFFER_BLOCK + BUFFER_NEXT_OFFSET],
+ xreg(irb, xdiffdst_next)));
+ }
+
+ IRB_LOOP(vmovups(zreg(irb, za), EVEX_compress_addr(t, irb*BUFFER_BLOCK
+ + XMM_SIZE - 2*sizeof(float))));
+ IRB_LOOP(vmovups(zreg(irb, zb), EVEX_compress_addr(t, irb*BUFFER_BLOCK
+ + XMM_SIZE - 1*sizeof(float))));
+ IRB_LOOP(vmovups(zreg(irb, zd), EVEX_compress_addr(t, irb*BUFFER_BLOCK
+ + XMM_SIZE + 1*sizeof(float))));
+ IRB_LOOP(vmovups(zreg(irb, ze), EVEX_compress_addr(t, irb*BUFFER_BLOCK
+ + XMM_SIZE + 2*sizeof(float))));
+ IRB_LOOP(vaddps(zreg(irb, zdiffsrc), zreg(irb, zdiffsrc),
+ zreg(irb, za)));
+ assert(zsrc == za);
+ IRB_LOOP(vmovups(zreg(irb, zsrc), EVEX_compress_addr(src, irb*vlen)));
+ IRB_LOOP(vaddps(zreg(irb, zdiffsrc), zreg(irb, zdiffsrc),
+ zreg(irb, zb)));
+ IRB_LOOP(vaddps(zreg(irb, zdiffsrc), zreg(irb, zdiffsrc),
+ zreg(irb, zd)));
+ IRB_LOOP(vaddps(zreg(irb, zdiffsrc), zreg(irb, zdiffsrc),
+ zreg(irb, ze)));
+ IRB_LOOP(vmulps(zreg(irb, zsrc), zreg(irb, zsrc), znalphabeta));
+
+ IRB_LOOP(vmovups(zreg(irb, zws0),
+ EVEX_compress_addr(workspace0, irb*vlen)));
+ IRB_LOOP(vdivps(zreg(irb, zdiffdst), zreg(irb, zdiffdst),
+ zreg(irb, zws0)));
+ IRB_LOOP(vfmadd213ps(zreg(irb, zdiffsrc), zreg(irb, zsrc),
+ zreg(irb, zdiffdst)));
+
+ Label unaligned_store, end_store;
+ test(diffsrc, vlen - 1);
+ jnz(unaligned_store, T_NEAR);
+ IRB_LOOP(uni_vmovntps(EVEX_compress_addr(diffsrc, irb*vlen),
+ zreg(irb, zdiffsrc)));
+ jmp(end_store, T_NEAR);
+ L(unaligned_store); {
+ IRB_LOOP(uni_vmovups(EVEX_compress_addr(diffsrc, irb*vlen),
+ zreg(irb, zdiffsrc)));
+ }
+ L(end_store);
+ }
+
+ jit_avx512_common_lrn_kernel_f32(
+ const struct nChw16c_across &J,
+ float A,
+ float B,
+ int use_h_parallel,
+ void *code_ptr = nullptr,
+ size_t code_size = 1 * Xbyak::DEFAULT_MAX_CODE_SIZE)
+ : jit_generator(code_ptr, code_size)
+ , nalphabeta(-2*A*B)
+ , use_h_parallelism(use_h_parallel)
+ {
+ this->preamble();
+
+ mov(src, ptr[param + 0]);
+ mov(diffdst, ptr[param + 8]);
+ mov(workspace0, ptr[param + 16]);
+ mov(workspace1, ptr[param + 24]);
+ mov(diffsrc, ptr[param + 32]);
+
+ W = J.W;
+ HW = J.H*J.W;
+ int LSB = this->use_h_parallelism ? W : HW;
+
+ sub(t, BWD_RBC*BUFFER_BLOCK);
+ mov(imm_addr64, float2int(this->nalphabeta));
+ movq(xnalphabeta, imm_addr64);
+ vbroadcastss(znalphabeta, xnalphabeta);
+
+ is_first = J.version == -1 || J.version == -2;
+ is_last = J.version == +1 || J.version == +2;
+ is_single = J.version == 3;
+
+ if (is_first || is_single) {
+ vxorps(xmm1, xmm1, xmm1);
+ for(int irb = 0; irb < BWD_RBC; irb++) {
+ vmovups(ptr[t + irb*BUFFER_BLOCK], xmm1);
+ }
+ }
+ if (is_last || is_single) {
+ vxorps(xmm1, xmm1, xmm1);
+ for(int irb = 0; irb < BWD_RBC; irb++) {
+ vmovups(ptr[t + irb*BUFFER_BLOCK + BUFFER_NEXT_OFFSET], xmm1);
+ }
+ }
+
+ int LSREST = LSB % BWD_RBC;
+ int LS = LSB - LSREST;
+
+ Label lrn_loop;
+
+ if (LS > 0) {
+ mov(hw, LS);
+
+ L(lrn_loop);
+ {
+ compute_loop(BWD_RBC, 1, 1);
+
+ add(src, BWD_RBC*vlen);
+ add(diffsrc, BWD_RBC*vlen);
+ add(diffdst, BWD_RBC*vlen);
+ add(workspace0, BWD_RBC*vlen);
+ add(workspace1, BWD_RBC*vlen);
+
+ for(int irb = 0; irb < BWD_RBC; irb++)
+ dec(hw);
+ cmp(hw, 0);
+ jne(lrn_loop, T_NEAR);
+ }
+ }
+
+ compute_loop(LSREST, 1, this->use_h_parallelism ? 0 : 1);
+
+ add(t, BWD_RBC*BUFFER_BLOCK);
+ this->postamble();
+
+ ker = reinterpret_cast<decltype(ker)>(const_cast<uint8_t*>(
+ this->getCode()));
+ }
+
+};
+
+status_t jit_avx512_common_lrn_bwd_t::pd_t::init() {
+ using namespace alg_kind;
+
+ const memory_desc_wrapper data_d(src_md());
+ bool ok = true
+ && mayiuse(avx512_common)
+ && !is_fwd()
+ && utils::everyone_is(data_type::f32, data_d.data_type())
+ && !has_zero_dim_memory()
+ && data_d.ndims() == 4
+ && data_d.dims()[1] % vsize == 0
+ && attr()->has_default_values();
+ if (!ok) return unimplemented;
+
+ dims_t ws_dims = { MB(), C(), H(), 2*W() };
+ mkldnn_memory_desc_init_by_tag(&ws_md_, 4, ws_dims, data_type::f32,
+ format_tag::nChw16c);
+
+ if (!compare_ws(hint_fwd_pd_)) return unimplemented;
+
+ bool args_ok_across = true
+ && desc()->alg_kind == lrn_across_channels
+ && desc()->local_size == 5
+ && desc()->lrn_beta == 0.75
+ && data_d.matches_tag(format_tag::nChw16c);
+
+ return args_ok_across ? success : unimplemented;
+}
+
+jit_avx512_common_lrn_bwd_t::jit_avx512_common_lrn_bwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , use_h_parallelism(0), ker_(nullptr), ker_first_(nullptr)
+ , ker_last_(nullptr) {
+ const int C = pd()->C();
+ const int H = pd()->H();
+ const int W = pd()->W();
+ const int ls = pd()->desc()->local_size;
+ const float alpha = pd()->desc()->lrn_alpha / ls;
+ const float beta = pd()->desc()->lrn_beta;
+
+ use_h_parallelism = H > 28 ? 1 : 0;
+
+ if (C / vsize == 1) {
+ ker_ = new jit_avx512_common_lrn_kernel_f32(nChw16c_across(H, W, 3),
+ alpha, beta, use_h_parallelism);
+ } else {
+ ker_ = new jit_avx512_common_lrn_kernel_f32(nChw16c_across(H, W, 0),
+ alpha, beta, use_h_parallelism);
+ ker_first_ = new jit_avx512_common_lrn_kernel_f32(
+ nChw16c_across(H, W, -1), alpha, beta, use_h_parallelism);
+ ker_last_ = new jit_avx512_common_lrn_kernel_f32(
+ nChw16c_across(H, W, +1), alpha, beta, use_h_parallelism);
+ }
+}
+
+jit_avx512_common_lrn_bwd_t::~jit_avx512_common_lrn_bwd_t()
+{ delete ker_; delete ker_first_; delete ker_last_; }
+
+void jit_avx512_common_lrn_bwd_t::execute_backward(const exec_ctx_t &ctx) const
+{
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto ws = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WORKSPACE);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const int N = pd()->MB();
+ const int C = pd()->C();
+ const int H = pd()->H();
+ const int W = pd()->W();
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ size_t start{0}, end{0};
+ const int C16 = C / vsize;
+ const size_t work_amount = use_h_parallelism ? N*C16*H : N*C16;
+
+ balance211(work_amount, nthr, ithr, start, end);
+ if (use_h_parallelism) {
+ int n{0}, c16{0}, h{0};
+ nd_iterator_init(start, n, N, h, H, c16, C16);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ auto offset = n*C*H*W + c16*H*W*vsize
+ + h*W*vsize;
+ auto ws_offset0 = n*C*H*2*W + c16*H*2*W*vsize
+ + h*2*W*vsize;
+ auto ws_offset1 = ws_offset0 + W*vsize;
+
+ jit_args_bwd_t args;
+ args.src = &src[offset];
+ args.diff_dst = &diff_dst[offset];
+ args.ws0 = &ws[ws_offset0];
+ args.ws1 = &ws[ws_offset1];
+ args.diff_src = &diff_src[offset];
+
+ if (C16 == 1)
+ (*ker_)(&args);
+ else if (c16 == 0)
+ (*ker_first_)(&args);
+ else if (c16 == C16 - 1)
+ (*ker_last_)(&args);
+ else
+ (*ker_)(&args);
+ nd_iterator_step(n, N, h, H, c16, C16);
+ }
+ } else {
+ int n{0}, c16{0};
+ nd_iterator_init(start, n, N, c16, C16);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ auto offset = n*C*H*W + c16*H*W*vsize;
+ auto ws_offset0 = n*C*H*2*W + c16*H*2*W*vsize;
+ auto ws_offset1 = ws_offset0 + H*W*vsize;
+
+ jit_args_bwd_t args;
+ args.src = &src[offset];
+ args.diff_dst = &diff_dst[offset];
+ args.ws0 = &ws[ws_offset0];
+ args.ws1 = &ws[ws_offset1];
+ args.diff_src = &diff_src[offset];
+
+ if (C16 == 1)
+ (*ker_)(&args);
+ else if (c16 == 0)
+ (*ker_first_)(&args);
+ else if (c16 == C16 - 1)
+ (*ker_last_)(&args);
+ else
+ (*ker_)(&args);
+
+ nd_iterator_step(n, N, c16, C16);
+ }
+ }
+ });
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_lrn.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_lrn.hpp
new file mode 100644
index 0000000000..37fbb9b3e5
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_common_lrn.hpp
@@ -0,0 +1,96 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_COMMON_LRN_HPP
+#define CPU_JIT_AVX512_COMMON_LRN_HPP
+
+#include "c_types_map.hpp"
+
+#include "cpu_isa_traits.hpp"
+#include "cpu_lrn_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_avx512_common_lrn_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_lrn_fwd_pd_t {
+ using cpu_lrn_fwd_pd_t::cpu_lrn_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", avx512_common, ""),
+ jit_avx512_common_lrn_fwd_t);
+
+ status_t init();
+ };
+
+ jit_avx512_common_lrn_fwd_t(const pd_t *apd);
+ ~jit_avx512_common_lrn_fwd_t();
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ int use_h_parallelism;
+ struct jit_avx512_common_lrn_kernel_f32;
+ jit_avx512_common_lrn_kernel_f32 *ker_, *ker_first_, *ker_last_;
+};
+
+struct jit_avx512_common_lrn_bwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_lrn_bwd_pd_t {
+ using cpu_lrn_bwd_pd_t::cpu_lrn_bwd_pd_t;
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", avx512_common, ""),
+ jit_avx512_common_lrn_bwd_t);
+
+ status_t init();
+ };
+
+ jit_avx512_common_lrn_bwd_t(const pd_t *apd);
+ ~jit_avx512_common_lrn_bwd_t();
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ int use_h_parallelism;
+ struct jit_avx512_common_lrn_kernel_f32;
+ jit_avx512_common_lrn_kernel_f32 *ker_, *ker_first_, *ker_last_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_2x3.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_2x3.cpp
new file mode 100644
index 0000000000..c58d3fa0a6
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_2x3.cpp
@@ -0,0 +1,1103 @@
+/*******************************************************************************
+ * Copyright 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_avx512_core_fp32_wino_conv_2x3.hpp"
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::format_kind;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+using namespace Xbyak;
+
+/// SRC TRANSFORMS /////////////////////////////////////////////////////////////
+struct jit_avx512_core_fp32_wino_conv_2x3_src_trans_t: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(
+ jit_avx512_core_fp32_wino_conv_2x3_src_trans_t)
+
+ jit_conv_conf_2x3_wino_t jcp;
+
+ struct call_params_t {
+ const void *src;
+ const void *wino_src;
+ const void *v_y_masks;
+ const void *v_x_masks;
+ };
+ void (*ker_)(const call_params_t *);
+
+ jit_avx512_core_fp32_wino_conv_2x3_src_trans_t(
+ jit_conv_conf_2x3_wino_t ajcp, const primitive_attr_t &attr)
+ : jcp(ajcp) {
+ generate();
+ ker_ =
+ reinterpret_cast<decltype(ker_)>(const_cast<uint8_t*>(getCode()));
+ }
+
+ void generate();
+
+ Zmm vreg_inp(int i) {
+ assert(i < jcp.alpha * jcp.alpha);
+ return Zmm(31 - i);
+ }
+
+ Zmm vreg_tmp(int i) {
+ assert(i < jcp.alpha * jcp.alpha);
+ return Zmm(15 - i);
+ }
+
+ Zmm vreg_out(int i) {
+ assert(i < jcp.alpha * jcp.alpha);
+ return Zmm(31 - i);
+ }
+
+ Opmask y_mask = Opmask(1);
+ Opmask r_mask = Opmask(2);
+ Opmask x_mask(int id) {
+ assert (id < 4);
+ return Opmask(3 + id);
+ }
+
+ Reg64 reg_ptr_v_y_masks = r12;
+ Reg64 reg_ptr_v_x_masks = r11;
+
+ Reg64 reg_aux_ptr_src = r10;
+ Reg64 reg_aux_ptr_dst = r9;
+
+ Reg64 reg_ic_block = r8;
+
+};
+
+void jit_avx512_core_fp32_wino_conv_2x3_src_trans_t::generate() {
+ Label ic_block_label;
+
+ const int load_block = 16;
+ int out_offset = 0, inp_offset = 0;
+ preamble();
+
+#define READ_PARAM(reg, field) \
+ mov(reg, ptr[abi_param1 + offsetof(call_params_t, field)])
+ READ_PARAM(reg_aux_ptr_src, src);
+ READ_PARAM(reg_aux_ptr_dst, wino_src);
+ READ_PARAM(reg_ptr_v_y_masks, v_y_masks);
+ READ_PARAM(reg_ptr_v_x_masks, v_x_masks);
+#undef READ_PARAM
+
+ for (int i = 0; i < jcp.alpha; i++) {
+ kmovw(x_mask(i), ptr[reg_ptr_v_x_masks + sizeof(int16_t) * i]);
+ }
+ mov(reg_ic_block, jcp.ic / load_block);
+ L(ic_block_label);
+ {
+ for (int y = 0; y < jcp.alpha; y++) {
+ kmovw(y_mask, ptr[reg_ptr_v_y_masks + sizeof(int16_t) * y]);
+ for (int x = 0; x < jcp.alpha; x++) {
+ Zmm zmm = vreg_inp(y * jcp.alpha + x);
+
+ vxorps(zmm, zmm, zmm);
+ kandw(r_mask, y_mask, x_mask(x));
+ inp_offset = sizeof(float)
+ * ((-jcp.t_pad + y) * jcp.iw * load_block
+ + (-jcp.l_pad + x) * load_block);
+ vmovups(zmm | r_mask,
+ EVEX_compress_addr(reg_aux_ptr_src, inp_offset));
+ }
+ }
+ for (int y = 0; y < jcp.alpha; y++) {
+ vsubps(vreg_tmp(y * jcp.alpha + 0), vreg_inp(y * jcp.alpha + 0),
+ vreg_inp(y * jcp.alpha + 2));
+ vaddps(vreg_tmp(y * jcp.alpha + 1), vreg_inp(y * jcp.alpha + 1),
+ vreg_inp(y * jcp.alpha + 2));
+ vsubps(vreg_tmp(y * jcp.alpha + 2), vreg_inp(y * jcp.alpha + 2),
+ vreg_inp(y * jcp.alpha + 1));
+ vsubps(vreg_tmp(y * jcp.alpha + 3), vreg_inp(y * jcp.alpha + 1),
+ vreg_inp(y * jcp.alpha + 3));
+ }
+ for (int x = 0; x < jcp.alpha; x++) {
+ vsubps(vreg_out(x + 0 * jcp.alpha), vreg_tmp(x + jcp.alpha * 0),
+ vreg_tmp(x + jcp.alpha * 2));
+ vaddps(vreg_out(x + 1 * jcp.alpha), vreg_tmp(x + jcp.alpha * 1),
+ vreg_tmp(x + jcp.alpha * 2));
+ vsubps(vreg_out(x + 2 * jcp.alpha), vreg_tmp(x + jcp.alpha * 2),
+ vreg_tmp(x + jcp.alpha * 1));
+ vsubps(vreg_out(x + 3 * jcp.alpha), vreg_tmp(x + jcp.alpha * 1),
+ vreg_tmp(x + jcp.alpha * 3));
+ }
+
+ for (int i = 0; i < 16; i++) {
+ out_offset = sizeof(float) * (jcp.inp_stride * i);
+ vmovups(EVEX_compress_addr(reg_aux_ptr_dst, out_offset),
+ vreg_out(i));
+ }
+
+ add(reg_aux_ptr_src, sizeof(float) * jcp.ih * jcp.iw * load_block);
+ add(reg_aux_ptr_dst, sizeof(float) * load_block);
+ }
+ dec(reg_ic_block);
+ cmp(reg_ic_block, 0);
+ jg(ic_block_label, T_NEAR);
+ postamble();
+}
+
+/// DST TRANSFORMS /////////////////////////////////////////////////////////////
+struct jit_avx512_core_fp32_wino_conv_2x3_dst_trans_t: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(
+ jit_avx512_core_fp32_wino_conv_2x3_dst_trans_t)
+
+ jit_conv_conf_2x3_wino_t jcp;
+ const primitive_attr_t &attr_;
+
+ struct call_params_t {
+ const void *wino_dst;
+ const void *dst;
+ const void *v_y_masks;
+ const void *v_x_masks;
+
+ const void *bias;
+ const void *scales;
+ };
+ void (*ker_)(const call_params_t *);
+
+ jit_avx512_core_fp32_wino_conv_2x3_dst_trans_t(
+ jit_conv_conf_2x3_wino_t ajcp, const primitive_attr_t &attr)
+ : jcp(ajcp), attr_(attr) {
+ generate();
+ ker_ = reinterpret_cast<decltype(ker_)>(
+ const_cast<uint8_t *>(getCode()));
+ }
+
+ void generate();
+ bool maybe_relu(int position);
+
+ Zmm vreg_inp(int i) { // 16
+ assert(i < jcp.alpha * jcp.alpha);
+ return Zmm(31 - i);
+ }
+
+ Zmm vreg_stg(int id) { // 8
+ const int id_reg_stg = jcp.alpha * jcp.alpha + id;
+ assert(id_reg_stg < jcp.alpha * jcp.alpha + 8);
+ return Zmm(31 - id_reg_stg);
+ }
+
+ Zmm vreg_out(int id) { // 4
+ const int id_reg_out = jcp.alpha * jcp.alpha + 8 + id;
+ assert(id_reg_out < jcp.alpha * jcp.alpha + 12);
+ return Zmm(31 - id_reg_out);
+ }
+
+ Zmm vreg_tmp(int id) { // 2
+ const int id_reg_tmp = jcp.alpha * jcp.alpha + 12 + id;
+ assert(id_reg_tmp < jcp.alpha * jcp.alpha + 14);
+ return Zmm(31 - id_reg_tmp);
+ }
+
+ Zmm vreg_zero = Zmm(0);
+ Zmm vreg_prev_dst = Zmm(0);
+ Zmm vreg_bias = Zmm(2);
+
+ Opmask y_mask = Opmask(1);
+ Opmask r_mask = Opmask(2);
+ Opmask x_mask(int id) {
+ assert (id < 4);
+ return Opmask(3 + id);
+ }
+
+ Reg64 reg_ptr_v_y_masks = r12;
+ Reg64 reg_ptr_v_x_masks = r11;
+
+ Reg64 reg_aux_ptr_src = r10;
+ Reg64 reg_aux_ptr_dst = r9;
+
+ Reg64 reg_oc_block = r8;
+
+ Reg64 reg_ptr_bias = rbx;
+ Reg64 reg_ptr_scales = abi_not_param1;
+ Reg64 reg_ptr_sum_scale = rdx;
+};
+
+bool jit_avx512_core_fp32_wino_conv_2x3_dst_trans_t::maybe_relu(int position) {
+ using namespace primitive_kind;
+ const auto &p = attr_.post_ops_;
+
+ if (position == 0) {
+ /* relu before sum */
+ return false
+ || p.contain(eltwise, 0);
+ } else if (position == 1) {
+ /* relu after sum */
+ const int sum_idx = p.contain(sum, 0)
+ ? 0 : (p.contain(sum, 1) ? 1 : -1);
+ if (sum_idx == -1)
+ return false;
+
+ return false
+ || p.contain(eltwise, sum_idx + 1);
+ }
+
+ return false;
+}
+
+void jit_avx512_core_fp32_wino_conv_2x3_dst_trans_t::generate() {
+ Label oc_block_label;
+
+ const int load_block = 16;
+
+ auto loop_body = [=]() {
+ const auto &p = attr_.post_ops_;
+ const int sum_idx = p.find(primitive_kind::sum);
+ const float *p_sum_scale = (sum_idx != -1)
+ ? &p.entry_[sum_idx].sum.scale
+ : nullptr;
+ if (p_sum_scale && *p_sum_scale != 1.f)
+ mov(reg_ptr_sum_scale, (size_t)p_sum_scale);
+
+ for (int i = 0; i < 16; i++) {
+ int internal_offset = sizeof(float) * jcp.out_stride * i;
+ vmovups(vreg_inp(i),
+ EVEX_compress_addr(reg_aux_ptr_src, internal_offset));
+ }
+ for (int y = 0; y < jcp.alpha; y++) {
+ vaddps(vreg_tmp(0), vreg_inp(y * 4 + 0), vreg_inp(y * 4 + 1));
+ vaddps(vreg_stg(y * 2), vreg_tmp(0), vreg_inp(y * 4 + 2));
+
+ vsubps(vreg_tmp(1), vreg_inp(y * 4 + 1), vreg_inp(y * 4 + 2));
+ vsubps(vreg_stg(y * 2+1), vreg_tmp(1), vreg_inp(y * 4 + 3));
+ }
+ for (int x = 0; x < jcp.m; x++) {
+ vaddps(vreg_tmp(0), vreg_stg(x), vreg_stg(x+2 * 1));
+ vaddps(vreg_out(x), vreg_tmp(0), vreg_stg(x+2 * 2));
+
+ vsubps(vreg_tmp(1), vreg_stg(x+2 * 1), vreg_stg(x+2 * 2));
+ vsubps(vreg_out(x+2), vreg_tmp(1), vreg_stg(x+2 * 3));
+ }
+
+
+ if (jcp.with_bias) {
+ auto bias_addr = ptr [ reg_ptr_bias ];
+ vmovups(vreg_bias, bias_addr);
+ }
+ for (int y = 0; y < jcp.m; y++) {
+ kmovw(y_mask, ptr[ reg_ptr_v_y_masks + sizeof(int16_t) * y ]);
+ for (int x = 0; x < jcp.m; x++) {
+ kandw(r_mask, y_mask, x_mask(x));
+
+ int i = y * jcp.m + x;
+ int offset = sizeof(float) *
+ (y * jcp.ow * jcp.oc_block + x * jcp.oc_block);
+ Address addr = EVEX_compress_addr(reg_aux_ptr_dst, offset);
+
+ Zmm zmm = vreg_out(i);
+ if (jcp.with_bias)
+ vaddps(zmm, zmm, vreg_bias);
+ vmulps(zmm, zmm, ptr [reg_ptr_scales]);
+
+ if (maybe_relu(0)) {
+ vxorps(vreg_zero, vreg_zero, vreg_zero);
+ vmaxps(zmm, vreg_zero, zmm);
+ }
+ if (p_sum_scale) { // post_op: sum
+ vxorps(vreg_prev_dst, vreg_prev_dst, vreg_prev_dst);
+ vmovups(vreg_prev_dst | r_mask, addr);
+ if (*p_sum_scale == 1.f)
+ vaddps(zmm, vreg_prev_dst);
+ else
+ vfmadd231ps(zmm, vreg_prev_dst,
+ zword_b[reg_ptr_sum_scale]);
+ }
+ if (maybe_relu(1)) {
+ vxorps(vreg_zero, vreg_zero, vreg_zero);
+ vmaxps(zmm, vreg_zero, zmm);
+ }
+
+ vmovups(addr, zmm | r_mask);
+ }
+ }
+ };
+
+ preamble();
+
+#define READ_PARAM(reg, field) \
+ mov(reg, ptr[abi_param1 + offsetof(call_params_t, field)])
+ READ_PARAM(reg_aux_ptr_src, wino_dst);
+ READ_PARAM(reg_aux_ptr_dst, dst);
+ READ_PARAM(reg_ptr_v_y_masks, v_y_masks);
+ READ_PARAM(reg_ptr_v_x_masks, v_x_masks);
+ READ_PARAM(reg_ptr_bias, bias);
+ READ_PARAM(reg_ptr_scales, scales);
+#undef READ_PARAM
+
+ for (int i = 0; i < jcp.alpha * jcp.alpha; i++)
+ vxorps(vreg_inp(i), vreg_inp(i), vreg_inp(i));
+
+ for (int i = 0; i < jcp.alpha; i++)
+ kmovw(x_mask(i), ptr[reg_ptr_v_x_masks + sizeof(int16_t) * i]);
+
+ int oc_blocks = 1;
+ oc_blocks = jcp.oc / load_block;
+ mov(reg_oc_block, oc_blocks);
+ L(oc_block_label);
+ {
+ loop_body();
+ add(reg_aux_ptr_src, sizeof(float) * load_block);
+ add(reg_aux_ptr_dst, sizeof(float) * jcp.oh * jcp.ow * load_block);
+
+ add(reg_ptr_scales, jcp.is_oc_scale * sizeof(float) * load_block);
+ add(reg_ptr_bias, jcp.typesize_bia * load_block);
+ }
+ dec(reg_oc_block);
+ cmp(reg_oc_block, 0);
+ jg(oc_block_label, T_NEAR);
+
+ sub(reg_ptr_scales, jcp.is_oc_scale * sizeof(float) * load_block);
+ sub(reg_ptr_bias, oc_blocks * jcp.typesize_bia * load_block);
+
+ postamble();
+
+}
+
+/// GEMM kernel ////////////////////////////////////////////////////////////////
+struct jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t)
+ jit_conv_conf_2x3_wino_t jcp;
+
+ struct call_params_t {
+ const void *src;
+ const void *dst;
+ const void *wei;
+ const void *dst_b;
+ };
+ void (*ker_)(const call_params_t *);
+
+ void generate();
+ static bool post_ops_ok(jit_conv_conf_2x3_wino_t &jcp,
+ const primitive_attr_t &attr);
+
+ jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t(
+ jit_conv_conf_2x3_wino_t ajcp, const primitive_attr_t &attr)
+ : jcp(ajcp) {
+ generate();
+ ker_ = reinterpret_cast<decltype(ker_)>(
+ const_cast<uint8_t *>(getCode()));
+ }
+
+ static status_t init_conf(
+ jit_conv_conf_2x3_wino_t &jcp, const convolution_desc_t &cd,
+ memory_desc_t &src_md, memory_desc_t &weights_md,
+ memory_desc_t &dst_md, memory_desc_t &bias_md,
+ const primitive_attr_t &attr,
+ memory_desc_t& expect_wei_md);
+
+ Zmm vreg_out(int n, int m) {
+ const int id_reg_out = n * jcp.m_block + m;
+ assert(id_reg_out < jcp.n2_block * jcp.m_block);
+ return Zmm(31 - id_reg_out);
+ }
+ Zmm vreg_wei(int i) {
+ assert (31 - jcp.n2_block * jcp.m_block - i > 1);
+ return Zmm(31 - jcp.n2_block * jcp.m_block - i);
+ }
+
+ Zmm vreg_src = Zmm(0);
+ Zmm vreg_one = Zmm(1);
+ Zmm vreg_tmp = Zmm(2);
+
+ Reg64 reg_ptr_src = r15;
+
+ Reg64 reg_aux_dst = r12;
+ Reg64 reg_aux_dst2 = r11;
+ Reg64 reg_aux_wei = r10;
+ Reg64 reg_aux_wei2 = r9;
+ Reg64 reg_aux_src = r8;
+ Reg64 reg_aux_src2 = rax;
+
+ Reg64 reg_mb = rbx;
+ Reg64 reg_nnb = rdx;
+ Reg64 reg_K = rsi;
+
+};
+
+bool jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t::post_ops_ok(
+ jit_conv_conf_2x3_wino_t &jcp, const primitive_attr_t &attr) {
+ using namespace primitive_kind;
+ const auto &p = attr.post_ops_;
+
+ auto is_relu = [&](int idx) { return p.entry_[idx].is_relu(); };
+
+ switch (p.len_) {
+ case 0: return true;
+ case 1: return is_relu(0) || p.contain(sum, 0);
+ case 2: return (p.contain(sum, 0) && is_relu(1)) ||
+ (p.contain(sum, 1) && is_relu(0));
+ case 3: return is_relu(0) && p.contain(sum, 1) && is_relu(2);
+ default: return false;
+ }
+
+ return false;
+}
+
+void jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t::generate() {
+ Label nnb_loop_label, K_loop_label, mb_loop_label;
+
+ preamble();
+#define READ_PARAM(reg, field) \
+ mov(reg, ptr[abi_param1 + offsetof(call_params_t, field)])
+ READ_PARAM(reg_ptr_src, src);
+ READ_PARAM(reg_aux_dst, dst);
+ READ_PARAM(reg_aux_wei, wei);
+#undef READ_PARAM
+
+ if (!jcp.small_mb) {
+ mov(reg_nnb, jcp.n_chunks);
+ L(nnb_loop_label);
+ }
+ mov(reg_aux_dst2, reg_aux_dst);
+ mov(reg_aux_src, reg_ptr_src);
+ mov(reg_mb, jcp.M / jcp.m_block);
+ L(mb_loop_label);
+ {
+ int nb2 = 0;
+ for (nb2 = 0; nb2 < jcp.n2_block; nb2++) {
+ for (int m = 0; m < jcp.m_block; m++) {
+ vxorps(vreg_out(nb2, m), vreg_out(nb2, m), vreg_out(nb2, m));
+ }
+ }
+ mov(reg_aux_src2, reg_aux_src);
+ mov(reg_aux_wei2, reg_aux_wei);
+
+ mov(reg_K, jcp.k_chunks);
+ L(K_loop_label); {
+ int wei_offset = 0;
+ for (int _i = 0; _i < jcp.k2_block; _i++) {
+ for (int nb2 = 0; nb2 < jcp.n2_block; nb2++) {
+ if (jcp.small_mb) {
+ int wei_offset = sizeof(float)
+ * ((nb2 * jcp.nb_ic * jcp.ic_block
+ * jcp.oc_block)
+ + _i * jcp.oc_block);
+ vmovups(vreg_wei(nb2),
+ EVEX_compress_addr(reg_aux_wei2, wei_offset));
+ } else {
+ vmovups(vreg_wei(nb2),
+ EVEX_compress_addr(reg_aux_wei2,
+ sizeof(float) * wei_offset));
+ wei_offset += jcp.oc_block;
+ }
+ }
+ for (int m = 0; m < jcp.m_block; m++) {
+ int inp_offset = sizeof(float) * (m * jcp.K + _i);
+ if (jcp.n2_block > 1) {
+ vbroadcastss(vreg_src,
+ EVEX_compress_addr(reg_aux_src2, inp_offset));
+ for (int nb2 = 0; nb2 < jcp.n2_block; nb2++)
+ vfmadd231ps(vreg_out(nb2, m), vreg_wei(nb2),
+ vreg_src);
+ } else {
+ vfmadd231ps(vreg_out(0, m), vreg_wei(0),
+ EVEX_compress_addr(reg_aux_src2, inp_offset, true));
+ }
+ }
+ }
+ add(reg_aux_src2, sizeof(float) * jcp.ic_block);
+ if (jcp.small_mb)
+ add(reg_aux_wei2, sizeof(float) * jcp.oc_block * jcp.ic_block);
+ else
+ add(reg_aux_wei2,
+ sizeof(float) * jcp.k2_block * jcp.n2_block
+ * jcp.oc_block);
+ }
+ dec(reg_K);
+ cmp(reg_K, 0);
+ jg(K_loop_label, T_NEAR);
+
+ for (int m = 0; m < jcp.m_block; m++) {
+ int nb2 = 0;
+ for (nb2 = 0; nb2 < jcp.n2_block; nb2++) {
+ int offset = sizeof(float) *
+ (m * jcp.N + nb2 * jcp.oc_block);
+ vmovups(EVEX_compress_addr(reg_aux_dst2,offset),
+ vreg_out(nb2, m));
+ }
+ }
+ add(reg_aux_src, sizeof(float) * jcp.m_block * jcp.K);
+ add(reg_aux_dst2, sizeof(float) * jcp.m_block * jcp.N);
+ }
+ dec(reg_mb);
+ cmp(reg_mb, 0);
+ jg(mb_loop_label, T_NEAR);
+
+ if (!jcp.small_mb) {
+ add(reg_aux_dst, sizeof(float) * jcp.n2_block * jcp.oc_block);
+ add(reg_aux_wei,
+ sizeof(float) * jcp.k_chunks * jcp.ic_block * jcp.n2_block
+ * jcp.oc_block);
+
+ dec(reg_nnb);
+ cmp(reg_nnb, 0);
+ jg(nnb_loop_label, T_NEAR);
+ }
+ postamble();
+}
+
+namespace {
+bool is_winograd_faster_than_direct(const jit_conv_conf_2x3_wino_t &jcp) {
+ return jcp.mb >= 4;
+}
+}
+
+status_t jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t ::init_conf(
+ jit_conv_conf_2x3_wino_t &jcp, const convolution_desc_t &cd,
+ memory_desc_t &src_md, memory_desc_t &wei_md,
+ memory_desc_t &dst_md, memory_desc_t &bias_md,
+ const primitive_attr_t &attr, memory_desc_t &expect_wei_md) {
+ const memory_desc_wrapper src_d(&src_md);
+ const memory_desc_wrapper wei_d(&wei_md);
+ const memory_desc_wrapper dst_d(&dst_md);
+ const memory_desc_wrapper bias_d(&bias_md);
+
+ const bool with_groups = wei_d.ndims() == src_d.ndims() + 1;
+
+ jcp.nthr = mkldnn_get_max_threads();
+
+ jcp.ngroups = with_groups ? wei_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+ jcp.ih = src_d.dims()[2];
+ jcp.iw = src_d.dims()[3];
+ jcp.oh = dst_d.dims()[2];
+ jcp.ow = dst_d.dims()[3];
+ jcp.kh = wei_d.dims()[with_groups + 2];
+ jcp.kw = wei_d.dims()[with_groups + 3];
+ jcp.t_pad = cd.padding[0][0];
+ jcp.b_pad = cd.padding[1][0];
+ jcp.l_pad = cd.padding[0][1];
+ jcp.r_pad = cd.padding[1][1];
+ jcp.stride_h = cd.strides[0];
+ jcp.stride_w = cd.strides[1];
+ jcp.dilate_h = cd.dilates[0];
+ jcp.dilate_w = cd.dilates[1];
+
+ jcp.m = 2;
+ jcp.r = 3;
+ jcp.alpha = jcp.m + jcp.r - 1;
+ int simdw = 16;
+
+ format_tag_t dat_tag = format_tag::nChw16c;
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ jcp.dst_tag = dst_d.matches_one_of_tag(dat_tag);
+
+ if (jcp.src_tag != dat_tag) return status::unimplemented;
+ if (jcp.dst_tag != dat_tag) return status::unimplemented;
+
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ bool ok_to_pad_channels = jcp.ngroups == 1;
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, simdw);
+ jcp.ic = rnd_up(jcp.ic, simdw);
+ }
+
+ jcp.ver = ver_avx512_core;
+ if (!(mayiuse(avx512_core)))
+ return status::unimplemented;
+
+ if (!IMPLICATION(cd.alg_kind == alg_kind::convolution_auto,
+ is_winograd_faster_than_direct(jcp)))
+ return status::unimplemented;
+
+ if (src_d.data_type() != data_type::f32)
+ return status::unimplemented;
+ if (wei_d.data_type() != data_type::f32)
+ return status::unimplemented;
+ if (dst_d.data_type() != data_type::f32)
+ return status::unimplemented;
+
+ jcp.ic_block = simdw;
+ jcp.oc_block = simdw;
+
+ bool ok = true && jcp.kh == 3 && jcp.kw == 3 && jcp.ngroups == 1
+ && jcp.oc % jcp.oc_block == 0 && jcp.ic % jcp.ic_block == 0
+ && jcp.stride_h == 1 && jcp.stride_w == 1 && jcp.dilate_h == 0
+ && jcp.dilate_w == 0 && jcp.t_pad == jcp.b_pad
+ && jcp.l_pad == jcp.r_pad && jcp.t_pad < 2 && jcp.t_pad >= 0
+ && jcp.l_pad < 2 && jcp.l_pad >= 0;
+ if (!ok)
+ return status::unimplemented;
+
+ const int L2_cap = get_cache_size(2, true) / sizeof(float);
+ const int L3_capacity = get_cache_size(3, false) / sizeof(float);
+ int a = jcp.alpha;
+ int aa = a * a;
+ int mb = jcp.mb;
+ int ic = jcp.ic;
+ int oc = jcp.oc;
+ int ih = jcp.ih;
+ int iw = jcp.iw;
+ auto wei_sz = (float)aa * ic * oc;
+ auto inp_sz = (float)mb * ih * iw * ic;
+ auto sp_sz = (float)mb * ih * iw;
+
+ /* Heuristics here. Numbers '28','196' is an observation from data. */
+ if (wei_sz / inp_sz > 5)
+ jcp.small_mb = true;
+ else
+ jcp.small_mb = false;
+
+ if (mb > nstl::min(jcp.nthr, 28)
+ || (!jcp.small_mb
+ && (wei_sz >= 0.9f * L2_cap
+ || inp_sz > L2_cap * jcp.nthr + L3_capacity))
+ || (jcp.small_mb && sp_sz > 196))
+ return status::unimplemented;
+
+ jcp.bia_dt = jcp.with_bias ? cd.bias_desc.data_type : data_type::undef;
+ jcp.dst_dt = cd.dst_desc.data_type;
+
+ jcp.typesize_bia
+ = jcp.with_bias ? types::data_type_size(bias_d.data_type()) : 0;
+
+ jcp.nb_oc = jcp.oc / jcp.oc_block;
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+
+ const int skx_free_regs = 30;
+
+ auto find_m_n2_blocks = [=](int xb, int yb, int &M, int &m_block,
+ int &n2_block, float &reg_eff) {
+ M = (xb * yb) / jcp.alpha;
+ int max_m_block = m_block = nstl::min(M, skx_free_regs);
+ int max_n2_block = n2_block = nstl::min(jcp.nb_oc, skx_free_regs);
+ reg_eff = 0;
+ for (int im = max_m_block; im > 0; im--) {
+ for (int in2 = max_n2_block; in2 > 0; in2--) {
+ int used_regs = in2 * im + in2;
+ float cur_reg_eff = ((float)in2 * im) / (im + in2) / 2.5f;
+ if (M % im || jcp.nb_oc % in2 || used_regs > skx_free_regs
+ || cur_reg_eff <= reg_eff)
+ continue;
+ reg_eff = cur_reg_eff;
+ m_block = im;
+ n2_block = in2;
+ }
+ }
+ };
+
+ int oh = jcp.oh;
+ int ow = jcp.ow;
+ int nb_oc = jcp.nb_oc;
+ int Z = ic + oc;
+ int Y = ic * oc;
+ const int L3_cap_per_core = get_cache_size(3, true) / sizeof(float);
+
+ /* Selecting xb and yb blocking */
+ int min_yb = jcp.alpha;
+ int min_xb = jcp.alpha;
+ int max_yb = nstl::max(min_yb, rnd_up(ih, 2));
+ int max_xb = nstl::max(min_xb, rnd_up(iw, 2));
+ float best_eff = 0.f;
+ for (int ix = max_xb; ix >= min_xb; ix -= 2) {
+ if (rnd_up(ow, ix) < iw - 2)
+ continue;
+ for (int iy = max_yb; iy >= min_yb; iy -= 2) {
+ if (rnd_up(oh, iy) < ih - 2)
+ continue;
+ int ex_y = rnd_up(oh, iy);
+ int ex_x = rnd_up(ow, ix);
+ float work_eff = (float)(ih * iw) / (ex_y * ex_x);
+
+ int M, m_block, n2_b;
+ float reg_eff, thr_eff, par_eff, mem_eff, req_mem;
+
+ find_m_n2_blocks(ix, iy, M, m_block, n2_b, reg_eff);
+
+ /* outer parallelization */
+ int nblocks = mb * div_up(ih, iy) * div_up(iw, ix);
+ thr_eff = (float)nblocks / rnd_up(nblocks, jcp.nthr);
+
+ mem_eff = 1.f;
+ req_mem = (((float)ix + 2) * (iy + 2) + aa * M) * Z + aa * Y;
+ if (req_mem > L2_cap / 2) {
+ if (req_mem > ((L2_cap + L3_cap_per_core) * 4) / 7)
+ mem_eff /= (n2_b + 1) / 2.f;
+ else
+ mem_eff /= (n2_b + 1) / 3.f;
+ }
+
+ float outer_eff = thr_eff + work_eff + reg_eff + mem_eff;
+
+ /* inner parallelization */
+ int bsz = iy * ix / a;
+ int gemmw = aa * (nb_oc / n2_b);
+ int bsz_r = rnd_up(bsz, jcp.nthr);
+ int gemmw_r = rnd_up(gemmw, jcp.nthr);
+ thr_eff = ((float)Z * bsz / bsz_r + Y * gemmw / gemmw_r) / (Z + Y);
+
+ req_mem = (float)ix * iy * (ic + simdw * n2_b) + simdw * n2_b * ic;
+ mem_eff = nstl::min(1.f, L2_cap / req_mem);
+ int M_per_thr = nstl::max(2, div_up(aa, jcp.nthr));
+ int oc_per_thr =
+ nstl::min(oc, div_up(aa * (nb_oc / n2_b), jcp.nthr));
+ req_mem = (float)aa * oc_per_thr * ic + M_per_thr * M * Z;
+ if (req_mem > L2_cap)
+ mem_eff = 0.1f;
+ par_eff = 1 / (2.f * nblocks);
+
+ float inner_eff = thr_eff + work_eff + mem_eff + par_eff;
+
+ float eff = jcp.small_mb ? inner_eff : outer_eff;
+ if (eff > best_eff) {
+ best_eff = eff;
+ jcp.yb = iy;
+ jcp.xb = ix;
+ jcp.M = M;
+ jcp.m_block = m_block;
+ jcp.n2_block = n2_b;
+ }
+ }
+ }
+
+ assert(jcp.xb % 2 == 0 && jcp.yb % 2 == 0);
+
+ jcp.inp_stride = jcp.M * jcp.ic;
+ jcp.out_stride = jcp.M * jcp.oc;
+ jcp.wei_stride = jcp.ic * jcp.oc;
+ jcp.bia_stride = jcp.oc;
+
+ jcp.N = jcp.oc;
+ jcp.K = jcp.ic;
+
+ jcp.n_block = jcp.oc_block;
+ jcp.k_block = jcp.ic_block;
+
+ assert(jcp.M % jcp.m_block == 0);
+ assert(jcp.nb_oc % jcp.n2_block == 0);
+
+ jcp.n_chunks = jcp.nb_oc / jcp.n2_block;
+ jcp.k2_block = jcp.ic_block;
+ jcp.k_chunks = jcp.K / jcp.k2_block;
+
+ const auto &oscales = attr.output_scales_;
+ jcp.is_oc_scale = oscales.mask_ == 1 << 1;
+ assert(IMPLICATION(!jcp.is_oc_scale, oscales.mask_ == 0));
+
+ /* re-create weights primitive descriptor
+ and set weights wino_blocking */
+ expect_wei_md.format_kind = format_kind::wino;
+ expect_wei_md.data_type = data_type::f32;
+ mkldnn_wino_desc_t &wd = expect_wei_md.format_desc.wino_desc;
+ wd.wino_format
+ = jcp.small_mb ? mkldnn_wino_wei_aaOio : mkldnn_wino_wei_aaOBiOo;
+ wd.r = jcp.r;
+ wd.alpha = jcp.alpha;
+ wd.ic = jcp.ic;
+ wd.oc = jcp.oc;
+ wd.ic_block = jcp.ic_block;
+ wd.oc_block = jcp.oc_block;
+ wd.oc2_block = jcp.n2_block;
+ wd.ic2_block = 1;
+ wd.adj_scale = 1.f;
+ size_t max_size = sizeof(float) * jcp.alpha * jcp.alpha * jcp.ic * jcp.oc;
+ wd.size = max_size;
+
+ return status::success;
+}
+////////////////////////////////////////////////////////////////////////////////
+
+status_t jit_avx512_core_fp32_wino_conv_2x3_fwd_t
+ ::pd_t::jit_conf(memory_desc_t& expect_wei_md) {
+ return jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t::init_conf(
+ jcp_, *this->desc(), this->src_md_, this->weights_md_,
+ this->dst_md_,this->bias_md_, *this->attr(), expect_wei_md);
+}
+
+jit_avx512_core_fp32_wino_conv_2x3_fwd_t::
+ jit_avx512_core_fp32_wino_conv_2x3_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+{
+ kernel_ = new jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t(
+ pd()->jcp_, *pd()->attr());
+ src_trans_ = new jit_avx512_core_fp32_wino_conv_2x3_src_trans_t(
+ pd()->jcp_, *pd()->attr());
+ dst_trans_ = new jit_avx512_core_fp32_wino_conv_2x3_dst_trans_t(
+ pd()->jcp_, *pd()->attr());
+}
+
+jit_avx512_core_fp32_wino_conv_2x3_fwd_t
+ ::~jit_avx512_core_fp32_wino_conv_2x3_fwd_t() {
+ delete kernel_;
+ delete src_trans_;
+ delete dst_trans_;
+}
+
+void jit_avx512_core_fp32_wino_conv_2x3_fwd_t::execute_forward_mbN(
+ const float *src, const float *wei, const float *bia, float *dst,
+ const memory_tracking::grantor_t &scratchpad) const
+{
+ const auto &jcp = kernel_->jcp;
+ const auto &oscales = pd()->attr()->output_scales_;
+
+ const size_t wino_size_offset =
+ (size_t)(pd()->jcp_.yb / 2) * (pd()->jcp_.xb / 2) + (pd()->jcp_.xb);
+ const size_t size_wino_src = wino_size_offset * pd()->jcp_.ic * 16;
+ const size_t size_wino_dst = wino_size_offset * pd()->jcp_.oc * 16;
+
+ if (pd()->wants_padded_bias()) {
+ auto padded_bias = scratchpad.get<float>(key_conv_padded_bias);
+ utils::array_copy(padded_bias, bia, jcp.oc_without_padding);
+ utils::array_set(padded_bias + jcp.oc_without_padding, 0.f,
+ jcp.oc - jcp.oc_without_padding);
+ bia = padded_bias;
+ }
+
+ auto ptr_V = scratchpad.get<float>(key_wino_V);
+ auto ptr_M = scratchpad.get<float>(key_wino_M);
+
+ parallel_nd(jcp.mb, div_up(jcp.oh,jcp.yb), div_up(jcp.ow, jcp.xb),
+ [&](int mb, int tile_y_b, int tile_x_b) {
+ int tile_y = tile_y_b * jcp.yb;
+ int tile_x = tile_x_b * jcp.xb;
+
+ int ithr = mkldnn_get_thread_num();
+ auto wino_src = ptr_V + size_wino_src * ithr;
+ auto wino_dst = ptr_M + size_wino_dst * ithr;
+
+ auto src_trans_p =
+ jit_avx512_core_fp32_wino_conv_2x3_src_trans_t
+ ::call_params_t();
+ auto dst_trans_p =
+ jit_avx512_core_fp32_wino_conv_2x3_dst_trans_t
+ ::call_params_t();
+ auto gemm_p = jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t ::
+ call_params_t();
+
+ /* transformation of input tensor to winograd domain */
+ for (int y_in_block = 0; y_in_block < jcp.yb; y_in_block += 2) {
+ for (int x_in_block = 0; x_in_block < jcp.xb;
+ x_in_block += 2) {
+
+ unsigned short v_y_masks[4], v_x_masks[4];
+
+ int y = y_in_block + tile_y;
+ int x = x_in_block + tile_x;
+ int m = (y_in_block / 2) * (jcp.xb / 2)
+ + (x_in_block / 2);
+
+ int v_ys = nstl::max(0, jcp.t_pad - y);
+ int v_ye = nstl::min(jcp.alpha,
+ nstl::max(0, jcp.ih + jcp.t_pad - y));
+
+ int v_xs = nstl::max(0, jcp.l_pad - x);
+ int v_xe = nstl::min(jcp.alpha,
+ nstl::max(0, jcp.iw + jcp.l_pad - x));
+
+#pragma unroll(4)
+ for (int i = 0; i < jcp.alpha; i++) {
+ v_y_masks[i] = (i < v_ys || i >= v_ye) ? 0 : 0xffff;
+ v_x_masks[i] = (i < v_xs || i >= v_xe) ? 0 : 0xffff;
+ }
+ auto local_s = src
+ + mb * jcp.nb_ic * jcp.ih * jcp.iw
+ * jcp.ic_block
+ + y * jcp.iw * jcp.ic_block + x * jcp.ic_block;
+ auto local_w = wino_src + m * jcp.ic;
+
+ src_trans_p.src = local_s;
+ src_trans_p.wino_src = local_w;
+ src_trans_p.v_y_masks = v_y_masks;
+ src_trans_p.v_x_masks = v_x_masks;
+
+ src_trans_->ker_(&src_trans_p);
+ }
+ }
+ /* gemms */
+ for (int tile_ij = 0; tile_ij < 16; tile_ij++) {
+ int offset = (tile_ij + ithr) % 16;
+ gemm_p.src = wino_src + jcp.inp_stride * offset;
+ gemm_p.dst = wino_dst + jcp.out_stride * offset;
+ gemm_p.wei = wei + jcp.wei_stride * offset;
+
+ kernel_->ker_(&gemm_p);
+ }
+
+ /* transformation from winograd domain to output tensor */
+ for (int y_in_block = 0; y_in_block < jcp.yb; y_in_block += 2) {
+ for (int x_in_block = 0; x_in_block < jcp.xb;
+ x_in_block += 2) {
+ unsigned short v_y_masks[2], v_x_masks[2];
+
+ int y = y_in_block + tile_y;
+ int x = x_in_block + tile_x;
+ int m = (y_in_block / 2) * (jcp.xb / 2)
+ + (x_in_block / 2);
+
+#pragma unroll(2)
+ for (int i = 0; i < jcp.m; i++) {
+ v_x_masks[i] = (x + i < jcp.ow) ? 0xffff : 0;
+ v_y_masks[i] = (y + i < jcp.oh) ? 0xffff : 0;
+ }
+ auto local_d = dst
+ + mb * jcp.nb_oc * jcp.oh * jcp.ow
+ * jcp.oc_block
+ + y * jcp.ow * jcp.oc_block + x * jcp.oc_block;
+ auto local_w = wino_dst + m * jcp.oc;
+
+ auto scales = oscales.scales_;
+ dst_trans_p.dst = local_d;
+ dst_trans_p.wino_dst = local_w;
+ dst_trans_p.v_y_masks = v_y_masks;
+ dst_trans_p.v_x_masks = v_x_masks;
+
+ dst_trans_p.scales = scales;
+ dst_trans_p.bias = bia;
+
+ dst_trans_->ker_(&dst_trans_p);
+ }
+ }
+ });
+}
+
+void jit_avx512_core_fp32_wino_conv_2x3_fwd_t::execute_forward_small_mb(
+ const float *src, const float *wei, const float *bia, float *dst,
+ const memory_tracking::grantor_t &scratchpad) const
+{
+ const auto &jcp = kernel_->jcp;
+ const auto &oscales = pd()->attr()->output_scales_;
+
+ if (pd()->wants_padded_bias()) {
+ auto padded_bias = scratchpad.get<float>(key_conv_padded_bias);
+ utils::array_copy(padded_bias, bia, jcp.oc_without_padding);
+ utils::array_set(padded_bias + jcp.oc_without_padding, 0.f,
+ jcp.oc - jcp.oc_without_padding);
+ bia = padded_bias;
+ }
+
+ auto ptr_V = scratchpad.get<float>(key_wino_V);
+ auto ptr_M = scratchpad.get<float>(key_wino_M);
+
+ for (int mb = 0; mb < jcp.mb; mb++) {
+ for (int tile_y = 0; tile_y < jcp.oh; tile_y += jcp.yb) {
+ for (int tile_x = 0; tile_x < jcp.ow; tile_x += jcp.xb) {
+ /* transformation of input tensor to winograd domain */
+ parallel_nd(div_up(jcp.yb, 2), div_up(jcp.xb, 2),
+ [&](int y_in_block_b, int x_in_block_b) {
+ int y_in_block = y_in_block_b * 2;
+ int x_in_block = x_in_block_b * 2;
+
+ auto src_trans_p = jit_avx512_core_fp32_wino_conv_2x3_src_trans_t ::
+ call_params_t();
+
+ unsigned short v_y_masks[4], v_x_masks[4];
+
+ int y = y_in_block + tile_y;
+ int x = x_in_block + tile_x;
+ int m = (y_in_block / 2) * (jcp.xb / 2) + (x_in_block / 2);
+
+ int v_ys = nstl::max(0, jcp.t_pad - y);
+ int v_ye = nstl::min(
+ jcp.alpha, nstl::max(0, jcp.ih + jcp.t_pad - y));
+
+ int v_xs = nstl::max(0, jcp.l_pad - x);
+ int v_xe = nstl::min(
+ jcp.alpha, nstl::max(0, jcp.iw + jcp.l_pad - x));
+
+#pragma unroll(4)
+ for (int i = 0; i < jcp.alpha; i++) {
+ v_y_masks[i] = (i < v_ys || i >= v_ye) ? 0 : 0xffff;
+ v_x_masks[i] = (i < v_xs || i >= v_xe) ? 0 : 0xffff;
+ }
+ auto local_s = src
+ + mb * jcp.nb_ic * jcp.ih * jcp.iw * jcp.ic_block
+ + y * jcp.iw * jcp.ic_block + x * jcp.ic_block;
+ auto local_w = ptr_V + m * jcp.ic;
+
+ src_trans_p.src = local_s;
+ src_trans_p.wino_src = local_w;
+ src_trans_p.v_y_masks = v_y_masks;
+ src_trans_p.v_x_masks = v_x_masks;
+
+ src_trans_->ker_(&src_trans_p);
+ });
+
+ /* gemms */
+ parallel_nd(16, jcp.n_chunks, [&](int tile_ij, int nnb) {
+ auto gemm_p = jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t ::
+ call_params_t();
+
+ gemm_p.src = ptr_V + jcp.inp_stride * tile_ij;
+ gemm_p.dst = ptr_M + jcp.out_stride * tile_ij
+ + nnb * jcp.n2_block * jcp.n_block;
+ gemm_p.wei = wei + jcp.wei_stride * tile_ij
+ + nnb * jcp.n2_block * jcp.n_block * jcp.K;
+
+ kernel_->ker_(&gemm_p);
+ });
+
+ /* transformation from winograd domain to output tensor */
+
+ parallel_nd(div_up(jcp.yb, 2), div_up(jcp.xb, 2),
+ [&](int y_in_block_b, int x_in_block_b) {
+ int y_in_block = y_in_block_b * 2;
+ int x_in_block = x_in_block_b * 2;
+
+ auto dst_trans_p = jit_avx512_core_fp32_wino_conv_2x3_dst_trans_t ::
+ call_params_t();
+
+ unsigned short v_y_masks[2], v_x_masks[2];
+
+ int y = y_in_block + tile_y;
+ int x = x_in_block + tile_x;
+ int m = (y_in_block / 2) * (jcp.xb / 2) + (x_in_block / 2);
+
+#pragma unroll(2)
+ for (int i = 0; i < jcp.m; i++) {
+ v_x_masks[i] = (x + i < jcp.ow) ? 0xffff : 0;
+ v_y_masks[i] = (y + i < jcp.oh) ? 0xffff : 0;
+ }
+ auto local_d = dst
+ + mb * jcp.nb_oc * jcp.oh * jcp.ow * jcp.oc_block
+ + y * jcp.ow * jcp.oc_block + x * jcp.oc_block;
+ auto local_w = ptr_M + m * jcp.oc;
+
+ auto scales = oscales.scales_;
+ dst_trans_p.dst = local_d;
+ dst_trans_p.wino_dst = local_w;
+ dst_trans_p.v_y_masks = v_y_masks;
+ dst_trans_p.v_x_masks = v_x_masks;
+
+ dst_trans_p.scales = scales;
+ dst_trans_p.bias = bia;
+
+ dst_trans_->ker_(&dst_trans_p);
+ });
+ }}}
+}
+
+} // namespace cpu
+} // namespace impl
+} // namespace mkldnn
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_2x3.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_2x3.hpp
new file mode 100644
index 0000000000..7e38b07f5a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_2x3.hpp
@@ -0,0 +1,144 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_CORE_FP32_WINO_CONV_2x3_HPP
+#define CPU_JIT_AVX512_CORE_FP32_WINO_CONV_2x3_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "jit_primitive_conf.hpp"
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t;
+struct jit_avx512_core_fp32_wino_conv_2x3_src_trans_t;
+struct jit_avx512_core_fp32_wino_conv_2x3_dst_trans_t;
+
+struct jit_avx512_core_fp32_wino_conv_2x3_fwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_fp32_wino_2x3:", avx512_core, ""),
+ jit_avx512_core_fp32_wino_conv_2x3_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::forward_inference
+ && utils::one_of(desc()->alg_kind,
+ alg_kind::convolution_auto,
+ alg_kind::convolution_winograd)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ memory_desc_t expect_wei_md = *weights_md();
+ status_t jit_conf_result = jit_conf(expect_wei_md);
+ if (jit_conf_result != status::success) return jit_conf_result;
+ set_default_alg_kind(alg_kind::convolution_winograd);
+
+ if (weights_md_.format_kind == format_kind::any)
+ weights_md_ = expect_wei_md;
+ if (weights_md_ != expect_wei_md)
+ return status::unimplemented;
+
+ init_scratchpad();
+
+ return status::success;
+ }
+
+ jit_conv_conf_2x3_wino_t jcp_;
+
+ protected:
+ status_t jit_conf(memory_desc_t& expect_wei_md);
+
+ void init_scratchpad() {
+ using namespace memory_tracking::names;
+
+ auto scratchpad = scratchpad_registry().registrar();
+
+ int wino_size_offset = (jcp_.yb / 2) * (jcp_.xb / 2) + jcp_.xb;
+
+ size_t V_sz = (size_t)jcp_.ic * 16 * wino_size_offset * jcp_.nthr;
+ scratchpad.book(key_wino_V, sizeof(float) * V_sz, PAGE_4K);
+
+ size_t M_sz = (size_t)jcp_.oc * 16 * wino_size_offset * jcp_.nthr;
+ scratchpad.book(key_wino_M, sizeof(float) * M_sz, PAGE_4K);
+
+ if (wants_padded_bias()) {
+ assert(jcp_.ngroups == 1);
+ scratchpad.book(key_conv_padded_bias, sizeof(float) * jcp_.oc);
+ }
+ }
+
+ bool set_default_formats() {
+ using namespace format_tag;
+ return set_default_formats_common(nChw16c, any, nChw16c);
+ }
+ };
+
+ jit_avx512_core_fp32_wino_conv_2x3_fwd_t(const pd_t *apd);
+ ~jit_avx512_core_fp32_wino_conv_2x3_fwd_t();
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ auto src = CTX_IN_MEM(const float *, MKLDNN_ARG_SRC);
+ auto wei = CTX_IN_MEM(const float *, MKLDNN_ARG_WEIGHTS);
+ auto bia = CTX_IN_MEM(const float *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(float *, MKLDNN_ARG_DST);
+
+ if (pd()->jcp_.small_mb)
+ execute_forward_small_mb(src, wei, bia, dst, this->scratchpad(ctx));
+ else
+ execute_forward_mbN(src, wei, bia, dst, this->scratchpad(ctx));
+
+ return status::success;
+ }
+
+private:
+ void execute_forward_small_mb(const float *src, const float *wei,
+ const float *bia, float *dst,
+ const memory_tracking::grantor_t &scratchpad) const;
+ void execute_forward_mbN(const float *src, const float *wei,
+ const float *bia, float *dst,
+ const memory_tracking::grantor_t &scratchpad) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx512_core_fp32_wino_conv_2x3_fwd_ker_t *kernel_;
+ jit_avx512_core_fp32_wino_conv_2x3_src_trans_t *src_trans_;
+ jit_avx512_core_fp32_wino_conv_2x3_dst_trans_t *dst_trans_;
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3.cpp
new file mode 100644
index 0000000000..96325e3ade
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3.cpp
@@ -0,0 +1,1020 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifdef __INTEL_COMPILER
+#include <immintrin.h>
+#endif
+
+#include "mkldnn_types.h"
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_avx512_core_fp32_wino_conv_4x3.hpp"
+
+#ifndef _MSC_VER
+#define pragma_unroll _Pragma("unroll")
+#else
+#define pragma_unroll
+#endif
+
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+
+template <bool is_fwd>
+void _jit_avx512_core_fp32_wino_conv_4x3_t<is_fwd>
+::weight_transform_data(const jit_conv_winograd_conf_t &jcp,
+ float *wp, float *twp) const
+{
+ float G[] = {0.26890756302521f, 0.688403361344538f, 0.119514472455649f,
+ 1.13777777777778f, 0.430252100840336f, 0.179271708683473f};
+ const int kh = 3;
+ const int kw = 3;
+ float Fw[alpha][alpha][simd_w][simd_w];
+ float F[kh][kw][simd_w][simd_w];
+ float T[alpha][3][simd_w];
+ auto p = jit_wino_transform_call_s();
+
+ p.src = wp;
+ p.dst = twp;
+ p.G = G;
+ p.M = F;
+ p.Mw = Fw;
+ p.T = T;
+
+ kernel_->weights_transform_data_ker(&p);
+}
+
+template<bool is_fwd>
+void _jit_avx512_core_fp32_wino_conv_4x3_t<is_fwd>::output_transform_data
+(int image, const jit_conv_winograd_conf_t &jcp,
+ const post_ops_t &p_ops, float *toutp, float *pout_b, float *bias) const {
+
+ float G[] = {0.625f, 1.5f, 0.390625f, 2.25f, 0.244140625f, 3.375f};
+ float Ow[alpha][alpha][simd_w];
+ float O[tile_size][tile_size][simd_w];
+ float T[tile_size][alpha][simd_w];
+
+ auto p = jit_wino_transform_call_s();
+ p.src = toutp;
+ p.dst = pout_b;
+ p.G = G;
+ p.M = O;
+ p.Mw = Ow;
+ p.T = T;
+ p.bias = bias;
+
+ int tile_base_index = image * jcp.itiles * jcp.jtiles;
+ int tile_block_ur = tile_base_index % jcp.tile_block_ur;
+ int nb_tile_block_ur =
+ (tile_base_index / jcp.tile_block_ur) % jcp.nb_tile_block_ur;
+ int tile_block =
+ (tile_base_index / jcp.tile_block_ur) / jcp.nb_tile_block_ur;
+
+ for (int tj = 0; tj < jcp.jtiles; tj++) {
+ for (int ti = 0; ti < jcp.itiles; ti++) {
+
+ p.tile_block_ur = tile_block_ur;
+ p.nb_tile_block_ur = nb_tile_block_ur;
+ p.tile_block = tile_block;
+ p.tj = tj;
+ p.ti = ti;
+
+ kernel_->output_transform_data_ker(&p);
+
+ tile_block_ur++;
+ if (tile_block_ur >= jcp.tile_block_ur) {
+ tile_block_ur = 0;
+ nb_tile_block_ur++;
+ }
+ if (nb_tile_block_ur >= jcp.nb_tile_block_ur) {
+ nb_tile_block_ur = 0;
+ tile_block++;
+ }
+ }
+ }
+}
+
+template<bool is_fwd>
+void _jit_avx512_core_fp32_wino_conv_4x3_t<is_fwd>
+::output_transform_tileblock_data(int tile_block,
+ const jit_conv_winograd_conf_t &jcp, const post_ops_t &p_ops,
+ float *toutp, float *outp, float *bias) const {
+
+ float G[] = {0.625f, 1.5f, 0.390625f, 2.25f, 0.244140625f, 3.375f};
+ float Ow[alpha][alpha][simd_w];
+ float O[tile_size][tile_size][simd_w];
+ float T[tile_size][alpha][simd_w];
+
+ auto p = jit_wino_transform_call_s();
+ p.src = toutp;
+ p.dst = outp;
+ p.G = G;
+ p.M = O;
+ p.Mw = Ow;
+ p.T = T;
+ p.bias = bias;
+
+ int outw = is_fwd ? jcp.ow : jcp.iw;
+ int outh = is_fwd ? jcp.oh : jcp.ih;
+
+ int tile_index = tile_block * jcp.nb_tile_block_ur * jcp.tile_block_ur;
+
+ for (int nb_tile_block_ur = 0;
+ nb_tile_block_ur < jcp.nb_tile_block_ur;
+ nb_tile_block_ur++) {
+
+ for (int tile_block_ur = 0; tile_block_ur < jcp.tile_block_ur;
+ tile_block_ur++) {
+ int img = tile_index / (jcp.jtiles * jcp.itiles);
+ int ti = tile_index % jcp.itiles;
+ int tj = (tile_index / jcp.itiles) % jcp.jtiles;
+
+ p.tile_block_ur = tile_block_ur;
+ p.nb_tile_block_ur = nb_tile_block_ur;
+ p.tile_block = tile_block;
+ p.tj = tj;
+ p.ti = ti;
+ p.dst = outp + img * (jcp.dimM / jcp.dimM_simd_block)
+ * outh * outw * jcp.dimM_simd_block;
+
+ kernel_->output_transform_data_ker(&p);
+
+ tile_index++;
+ }
+ }
+}
+
+
+template<bool is_fwd>
+void _jit_avx512_core_fp32_wino_conv_4x3_t<is_fwd>
+ ::input_transform_data(int image, const jit_conv_winograd_conf_t &jcp,
+ float *inp, float *tinp) const
+{
+ float G[] = {-2.25f, -0.390625f, 0.87890625f, -2.640625f,
+ 0.625f, -0.625f, 1.5f, -1.5f, -2.640625f};
+
+ float Iw[alpha][alpha][simd_w];
+ float I[alpha][alpha][simd_w];
+ float T[alpha][alpha][simd_w];
+
+ auto p = jit_wino_transform_call_s();
+
+ p.src = inp;
+ p.dst = tinp;
+ p.G = G;
+ p.M = I;
+ p.Mw = Iw;
+ p.T = T;
+
+ int tile_base_index = image * jcp.itiles * jcp.jtiles;
+ int tile_block_ur = tile_base_index % jcp.tile_block_ur;
+ int nb_tile_block_ur =
+ (tile_base_index / jcp.tile_block_ur) % jcp.nb_tile_block_ur;
+ int tile_block =
+ (tile_base_index / jcp.tile_block_ur) / jcp.nb_tile_block_ur;
+
+ for (int tj = 0; tj < jcp.jtiles; tj++) {
+ for (int ti = 0; ti < jcp.itiles; ti++) {
+
+ p.tile_block_ur = tile_block_ur;
+ p.nb_tile_block_ur = nb_tile_block_ur;
+ p.tile_block = tile_block;
+ p.tj = tj;
+ p.ti = ti;
+
+ kernel_->input_transform_data_ker(&p);
+
+ tile_block_ur++;
+ if (tile_block_ur >= jcp.tile_block_ur) {
+ tile_block_ur = 0;
+ nb_tile_block_ur++;
+ }
+ if (nb_tile_block_ur >= jcp.nb_tile_block_ur) {
+ nb_tile_block_ur = 0;
+ tile_block++;
+ }
+ }
+ }
+}
+
+template <bool is_fwd>
+void _jit_avx512_core_fp32_wino_conv_4x3_t<is_fwd>
+ ::input_transform_tileblock_data(int tile_block,
+ const jit_conv_winograd_conf_t &jcp,
+ float *inp, float *tinp) const
+{
+ float G[] = {-2.25f, -0.390625f, 0.87890625f, -2.640625f,
+ 0.625f, -0.625f, 1.5f, -1.5f, -2.640625f};
+ float Iw[alpha][alpha][simd_w];
+ float I[alpha][alpha][simd_w];
+ float T[alpha][alpha][simd_w];
+
+ const int inph = is_fwd ? jcp.ih : jcp.oh;
+ const int inpw = is_fwd ? jcp.iw : jcp.ow;
+
+ array_offset_calculator<float, 5> input(inp,
+ jcp.mb, jcp.dimK / simd_w, inph, inpw, simd_w);
+ array_offset_calculator<float, 7> output(tinp,
+ alpha, alpha,
+ jcp.dimN_block, jcp.dimK_nb_block, jcp.dimK_block,
+ jcp.dimN_reg_block, jcp.dimK_reg_block);
+
+ auto p = jit_wino_transform_call_s();
+
+ p.dst = tinp;
+ p.G = G;
+ p.M = I;
+ p.Mw = Iw;
+ p.T = T;
+
+
+ int tile_index = tile_block * jcp.nb_tile_block_ur * jcp.tile_block_ur;
+
+ for (int nb_tile_block_ur = 0;
+ nb_tile_block_ur < jcp.nb_tile_block_ur;
+ nb_tile_block_ur++) {
+
+ for (int tile_block_ur = 0; tile_block_ur < jcp.tile_block_ur;
+ tile_block_ur++) {
+
+ int img = tile_index / (jcp.jtiles * jcp.itiles);
+ int ti = tile_index % jcp.itiles;
+ int tj = (tile_index / jcp.itiles) % jcp.jtiles;
+ float *pinp_b = &(input(img, 0, 0, 0, 0));
+
+ p.src = pinp_b;
+ p.tile_block_ur = tile_block_ur;
+ p.nb_tile_block_ur = nb_tile_block_ur;
+ p.tj = tj;
+ p.ti = ti;
+
+ kernel_->input_transform_data_ker(&p);
+
+ tile_index++;
+ }
+ }
+}
+
+template <bool is_fwd>
+void _jit_avx512_core_fp32_wino_conv_4x3_t<is_fwd>::_execute_data_W_S_G_D(
+ float *inp_ptr, float *out_ptr, float *wei_ptr, float *bias_ptr,
+ const memory_tracking::grantor_t &scratchpad) const {
+ const auto &jcp = kernel_->jcp;
+ const auto &p_ops = attr_->post_ops_;
+
+ const int inph = is_fwd ? jcp.ih : jcp.oh;
+ const int inpw = is_fwd ? jcp.iw : jcp.ow;
+ const int outh = is_fwd ? jcp.oh : jcp.ih;
+ const int outw = is_fwd ? jcp.ow : jcp.iw;
+
+ /* Notation:
+ FWD: dimM:oc, dimN:ntiles, dimK:ic,
+ BWD: dimM:ic, dimN:ntiles, dimK:oc,
+ FWD/BWD: V: src/diff_dst transform, U:weight transform,
+ M:dst/diff_src transform */
+ array_offset_calculator<float, 5> input(inp_ptr,
+ jcp.mb, jcp.dimK/jcp.dimK_reg_block, inph, inpw,
+ jcp.dimK_reg_block);
+ array_offset_calculator<float, 5> output(out_ptr,
+ jcp.mb, jcp.dimM/jcp.dimM_simd_block, outh, outw,
+ jcp.dimM_simd_block);
+ array_offset_calculator<float, 6> weights(wei_ptr,
+ jcp.oc/jcp.oc_simd_block, jcp.ic/jcp.ic_simd_block, jcp.kh, jcp.kw,
+ jcp.ic_simd_block, jcp.oc_simd_block);
+ array_offset_calculator<float, 2> bias(bias_ptr,
+ jcp.dimM/jcp.dimM_simd_block, jcp.dimM_simd_block);
+
+ array_offset_calculator<float, 8> M(is_fwd
+ ? scratchpad.template get<float>(key_wino_M)
+ : scratchpad.template get<float>(key_wino_V),
+ jcp.dimN_nb_block, jcp.dimM_nb_block,
+ alpha, alpha,
+ jcp.dimN_block, jcp.dimM_block * jcp.dimM_reg_block,
+ jcp.dimN_reg_block, jcp.dimM_simd_block);
+
+ auto wino_wei = (jcp.prop_kind == prop_kind::forward_inference)
+ ? wei_ptr
+ : scratchpad.template get<float>(key_wino_U);
+
+ array_offset_calculator<float, 8> U(wino_wei,
+ jcp.dimM_nb_block,
+ alpha, alpha,
+ jcp.dimK_nb_block,
+ jcp.dimM_block * jcp.dimM_reg_block, jcp.dimK_block,
+ jcp.dimK_reg_block, jcp.dimM_simd_block);
+ array_offset_calculator<float, 8> V(is_fwd
+ ? scratchpad.template get<float>(key_wino_V)
+ : scratchpad.template get<float>(key_wino_M),
+ jcp.dimN_nb_block, alpha, alpha,
+ jcp.dimN_block, jcp.dimK_nb_block,
+ jcp.dimK_block, jcp.dimN_reg_block, jcp.dimK_reg_block);
+
+ const bool wants_padded_bias = jcp.with_bias
+ && jcp.oc_without_padding != jcp.oc;
+ float last_slice_bias[simd_w] = {0};
+ if (wants_padded_bias) {
+ for (int oc = 0; oc < jcp.oc_without_padding % jcp.oc_simd_block; ++oc)
+ last_slice_bias[oc] = bias(jcp.dimM / jcp.dimM_simd_block - 1, oc);
+ }
+
+ {
+
+ parallel_nd(jcp.mb, jcp.dimK_nb_block, jcp.dimK_block,
+ [&](int img, int K_blk1, int K_blk2) {
+ input_transform_data(img, jcp,
+ &(input(img, K_blk1 * jcp.dimK_block + K_blk2,
+ 0, 0, 0)),
+ &(V(0, 0, 0, 0, K_blk1, K_blk2, 0, 0)));
+ });
+
+ if (jcp.prop_kind != prop_kind::forward_inference) {
+ parallel_nd(jcp.nb_oc, jcp.nb_ic, (jcp.oc_block * jcp.oc_reg_block),
+ (jcp.ic_block * jcp.ic_reg_block),
+ [&](int ofm1, int ifm1, int ofm2, int ifm2) {
+ float *U_base_ptr = is_fwd
+ ? &(U(ofm1, 0, 0, ifm1, ofm2, ifm2, 0, 0))
+ : &(U(ifm1, 0, 0, ofm1, ifm2, ofm2, 0, 0));
+ weight_transform_data(jcp,
+ &(weights(
+ ofm1 * jcp.oc_block * jcp.oc_reg_block + ofm2,
+ ifm1 * jcp.ic_block * jcp.ic_reg_block + ifm2,
+ 0, 0, 0, 0)),
+ U_base_ptr);
+ });
+ }
+
+ parallel_nd(jcp.dimN_nb_block, alpha, alpha, jcp.dimM_nb_block,
+ [&](int N_blk1, int oj, int oi, int M_blk1) {
+ for (int K_blk1 = 0; K_blk1 < jcp.dimK_nb_block;
+ K_blk1++)
+ for (int N_blk2 = 0; N_blk2 < jcp.dimN_block; N_blk2++)
+ kernel_->gemm_loop_ker(
+ (float *)&(M(N_blk1, M_blk1, oj, oi,
+ N_blk2, 0, 0, 0)),
+ (const float *)&(U(M_blk1, oj, oi,
+ K_blk1, 0, 0, 0, 0)),
+ (const float *)&(V(N_blk1, oj, oi,
+ N_blk2, K_blk1, 0, 0, 0)), K_blk1);
+ });
+
+ parallel_nd(jcp.mb, jcp.dimM_nb_block, (jcp.dimM_block * jcp.dimM_reg_block),
+ [&](int img, int M_blk1, int M_blk2) {
+ const int M_blk =
+ M_blk1 * jcp.dimM_block * jcp.dimM_reg_block + M_blk2;
+
+ float *bias_ptr = wants_padded_bias
+ && M_blk == jcp.dimM / jcp.dimM_simd_block - 1
+ ? last_slice_bias : &bias(M_blk, 0);
+ output_transform_data(img, jcp, p_ops,
+ &(M(0, M_blk1, 0, 0, 0, M_blk2, 0, 0)),
+ &(output(img, M_blk, 0, 0, 0)), bias_ptr);
+ });
+
+ }
+}
+
+template <bool is_fwd>
+void _jit_avx512_core_fp32_wino_conv_4x3_t<is_fwd>::_execute_data_W_SGD(
+ float *inp_ptr, float *out_ptr, float *wei_ptr, float *bias_ptr,
+ const memory_tracking::grantor_t &scratchpad) const {
+ const auto &jcp = kernel_->jcp;
+ const auto &p_ops = attr_->post_ops_;
+
+ const int inph = is_fwd ? jcp.ih : jcp.oh;
+ const int inpw = is_fwd ? jcp.iw : jcp.ow;
+ const int outh = is_fwd ? jcp.oh : jcp.ih;
+ const int outw = is_fwd ? jcp.ow : jcp.iw;
+
+ array_offset_calculator<float, 5> input(inp_ptr,
+ jcp.mb, jcp.dimK/jcp.dimK_reg_block, inph, inpw, jcp.dimK_reg_block);
+ array_offset_calculator<float, 5> output(out_ptr,
+ jcp.mb, jcp.dimM/jcp.dimM_simd_block, outh, outw, jcp.dimM_simd_block);
+ array_offset_calculator<float, 6> weights(wei_ptr,
+ jcp.oc/jcp.oc_simd_block, jcp.ic/jcp.ic_simd_block, jcp.kh, jcp.kw,
+ jcp.ic_simd_block, jcp.oc_simd_block);
+ array_offset_calculator<float, 2> bias(bias_ptr,
+ jcp.oc/jcp.oc_simd_block, jcp.oc_simd_block);
+
+ auto wino_wei = (jcp.prop_kind == prop_kind::forward_inference)
+ ? wei_ptr
+ : scratchpad.template get<float>(key_wino_U);
+
+ array_offset_calculator<float, 8> U(wino_wei,
+ jcp.dimM_nb_block,
+ alpha, alpha,
+ jcp.dimK_nb_block,
+ jcp.dimM_block * jcp.dimM_reg_block, jcp.dimK_block,
+ jcp.dimK_reg_block, jcp.dimM_simd_block);
+
+ array_offset_calculator<float, 8> M(is_fwd
+ ? scratchpad.template get<float>(key_wino_M)
+ : scratchpad.template get<float>(key_wino_V),
+ 0, jcp.dimM_nb_block, alpha, alpha,
+ jcp.dimN_block, jcp.dimM_block * jcp.dimM_reg_block,
+ jcp.dimN_reg_block, jcp.dimM_simd_block);
+ array_offset_calculator<float, 8> V(is_fwd
+ ? scratchpad.template get<float>(key_wino_V)
+ : scratchpad.template get<float>(key_wino_M),
+ 0, alpha, alpha, jcp.dimN_block,
+ jcp.dimK_nb_block, jcp.dimK_block,
+ jcp.dimN_reg_block, jcp.dimK_reg_block);
+
+ const bool wants_padded_bias = jcp.with_bias
+ && jcp.oc_without_padding != jcp.oc;
+ float last_slice_bias[simd_w] = {0};
+ if (wants_padded_bias) {
+ for (int oc = 0; oc < jcp.oc_without_padding % jcp.oc_simd_block; ++oc)
+ last_slice_bias[oc] = bias(jcp.dimM / jcp.dimM_simd_block - 1, oc);
+ }
+
+ if (jcp.prop_kind != prop_kind::forward_inference) {
+
+ parallel_nd(jcp.nb_oc, jcp.nb_ic, (jcp.oc_block * jcp.oc_reg_block), (jcp.ic_block * jcp.ic_reg_block),
+ [&](int ofm1, int ifm1, int ofm2, int ifm2) {
+ float *U_base_ptr = is_fwd
+ ? &(U(ofm1, 0, 0, ifm1, ofm2, ifm2, 0, 0))
+ : &(U(ifm1, 0, 0, ofm1, ifm2, ofm2, 0, 0));
+ weight_transform_data(jcp,
+ &(weights(
+ ofm1 * jcp.oc_block * jcp.oc_reg_block + ofm2,
+ ifm1 * jcp.ic_block * jcp.ic_reg_block + ifm2,
+ 0, 0, 0, 0)),
+ U_base_ptr);
+ });
+ }
+
+ parallel_nd(jcp.tile_block, [&](int tile_block) {
+ int ithr = mkldnn_get_thread_num();
+
+ for (int K_blk1 = 0; K_blk1 < jcp.dimK_nb_block; K_blk1++) {
+ for (int K_blk2 = 0; K_blk2 < jcp.dimK_block; K_blk2++) {
+
+ input_transform_tileblock_data(
+ tile_block, jcp,
+ &(input(0, K_blk1 * jcp.dimK_block + K_blk2, 0, 0, 0)),
+ &(V(ithr, 0, 0, 0, K_blk1, K_blk2, 0, 0)));
+ }
+ }
+
+ for (int oj = 0; oj < alpha; oj++) {
+ for (int oi = 0; oi < alpha; oi++) {
+ for (int M_blk1 = 0; M_blk1 < jcp.dimM_nb_block; M_blk1++)
+ for (int K_blk1 = 0; K_blk1 < jcp.dimK_nb_block; K_blk1++)
+ for (int N_blk = 0; N_blk < jcp.dimN_block; N_blk++)
+ kernel_->gemm_loop_ker(
+ (float *)&(M(ithr, M_blk1, oj, oi,
+ N_blk, 0, 0, 0)),
+ (const float *)&(U(M_blk1, oj, oi, K_blk1,
+ 0, 0, 0, 0)),
+ (const float *)&(V(ithr, oj, oi,
+ N_blk, K_blk1, 0, 0, 0)), K_blk1);
+ }
+ }
+
+ for (int M_blk1 = 0; M_blk1 < jcp.dimM_nb_block; M_blk1++) {
+ for (int M_blk2 = 0; M_blk2 < jcp.dimM_block * jcp.dimM_reg_block;
+ M_blk2++) {
+ const int M_blk =
+ M_blk1 * jcp.dimM_block * jcp.dimM_reg_block + M_blk2;
+
+ float *bias_ptr = wants_padded_bias
+ && M_blk == jcp.dimM / jcp.dimM_simd_block - 1
+ ? last_slice_bias : &bias(M_blk, 0);
+
+ output_transform_tileblock_data(tile_block, jcp, p_ops,
+ &(M(ithr, M_blk1, 0, 0, 0, M_blk2, 0, 0)),
+ &(output(0, M_blk, 0, 0, 0)), bias_ptr);
+ }
+ }
+ });
+}
+
+template struct _jit_avx512_core_fp32_wino_conv_4x3_t<true>;
+template struct _jit_avx512_core_fp32_wino_conv_4x3_t<false>;
+
+namespace {
+
+void subarray_sum(size_t num_arrs, float *output, size_t nelems,
+ float *input_ptrs[], size_t input_starts[], size_t input_ends[]) {
+ using namespace nstl;
+ const size_t block_size = 16 * 1024 / sizeof(float);
+ const size_t blocks_number = nelems / block_size;
+ const size_t tail = nelems % block_size;
+
+PRAGMA_OMP(parallel)
+ {
+ const int ithr = mkldnn_get_thread_num();
+ const int nthr = mkldnn_get_num_threads();
+ size_t start{ 0 }, end{ 0 };
+ balance211(blocks_number, nthr, ithr, start, end);
+
+ for (size_t nb = start; nb < end; ++nb) {
+ size_t start_e = nb * block_size;
+ size_t end_e = start_e + block_size;
+ size_t input_start = max(start_e, min(input_starts[0], end_e));
+ size_t input_end = max(start_e, min(input_ends[0], end_e));
+
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start_e; e < input_start; e++) {
+ output[e] = 0.f;
+ }
+
+ PRAGMA_OMP_SIMD()
+ for (size_t e = input_start; e < input_end; e++) {
+ output[e] = input_ptrs[0][e];
+ }
+
+ PRAGMA_OMP_SIMD()
+ for (size_t e = input_end; e < end_e; e++) {
+ output[e] = 0.f;
+ }
+
+ for (size_t a = 1; a < num_arrs; a++) {
+ input_start = max(start_e, input_starts[a]);
+ input_end = min(input_ends[a], end_e);
+
+ PRAGMA_OMP_SIMD()
+ for (size_t e = input_start; e < input_end; e++) {
+ output[e] += input_ptrs[a][e];
+ }
+ }
+ }
+
+ if (tail != 0 && ithr == nthr - 1) {
+ size_t start_e = nelems - tail;
+ size_t end_e = nelems;
+ size_t input_start = max(start_e, min(input_starts[0], end_e));
+ size_t input_end = max(start_e, min(input_ends[0], end_e));
+
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start_e; e < input_start; e++) {
+ output[e] = 0.f;
+ }
+
+ PRAGMA_OMP_SIMD()
+ for (size_t e = input_start; e < input_end; e++) {
+ output[e] = input_ptrs[0][e];
+ }
+
+ PRAGMA_OMP_SIMD()
+ for (size_t e = input_end; e < end_e; e++) {
+ output[e] = 0.f;
+ }
+
+ for (size_t a = 1; a < num_arrs; a++) {
+ input_start = max(start_e, input_starts[a]);
+ input_end = min(input_ends[a], end_e);
+
+ PRAGMA_OMP_SIMD()
+ for (size_t e = input_start; e < input_end; e++) {
+ output[e] += input_ptrs[a][e];
+ }
+ }
+ }
+ }
+}
+
+const int max_threads_number = 1024;
+
+// Sum to the first buffer array
+void array_sum(size_t num_arrs, float *output,
+ size_t nelems, float *input_ptrs[], bool reduce_to_first = true) {
+ const size_t block_size = 16 * 1024 / sizeof(float);
+ const size_t blocks_number = nelems / block_size;
+ const size_t tail = nelems % block_size;
+
+PRAGMA_OMP(parallel)
+ {
+ const size_t ithr = mkldnn_get_thread_num();
+ const size_t nthr = mkldnn_get_num_threads();
+ size_t start{ 0 }, end{ 0 };
+ balance211(blocks_number, nthr, ithr, start, end);
+
+ for (size_t nb = start; nb < end; ++nb) {
+ size_t start_e = nb * block_size;
+ size_t end_e = start_e + block_size;
+ if (!reduce_to_first) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start_e; e < end_e; e++) {
+ output[e] = input_ptrs[0][e];
+ }
+ }
+ for (size_t a = 1; a < num_arrs; a++) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start_e; e < end_e; e++) {
+ output[e] += input_ptrs[a][e];
+ }
+ }
+ }
+
+ if (tail != 0 && ithr == nthr - 1) {
+ size_t start_e = nelems - tail;
+ size_t end_e = nelems;
+ if (!reduce_to_first) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start_e; e < end_e; e++) {
+ output[e] = input_ptrs[0][e];
+ }
+ }
+ for (size_t a = 1; a < num_arrs; a++) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start_e; e < end_e; e++) {
+ output[e] += input_ptrs[a][e];
+ }
+ }
+ }
+ }
+}
+} //bwdw namespace
+
+void jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_t::
+_execute_backward_weights_SDGtWo(const float *ptr_src,
+ const float *ptr_diff_dst, float *ptr_diff_weights,
+ float *ptr_diff_bias,
+ const memory_tracking::grantor_t &scratchpad) const {
+ const auto &jcp = kernel_->jcp;
+ const int nthreads = jcp.nthr;
+
+ array_offset_calculator<float, 5> src((float *)ptr_src,
+ jcp.mb, jcp.ic / simd_w, jcp.ih, jcp.iw, simd_w);
+ array_offset_calculator<float, 5> diff_dst((float *)ptr_diff_dst,
+ jcp.mb, jcp.oc / simd_w, jcp.oh, jcp.ow, simd_w);
+ array_offset_calculator<float, 6> diff_weights(ptr_diff_weights,
+ jcp.oc / simd_w, jcp.ic / simd_w, jcp.kh, jcp.kw, simd_w, simd_w);
+
+ array_offset_calculator<float, 8> Us(scratchpad.get<float>(key_wino_U),
+ 0, alpha, alpha,
+ jcp.oc_block, jcp.ic_block,
+ jcp.ic_simd_block,
+ jcp.oc_reg_block,
+ jcp.oc_simd_block);
+
+ const int U_sz = nthreads * alpha * alpha * jcp.oc / jcp.nb_oc
+ * jcp.ic / jcp.nb_ic;
+ array_offset_calculator<float, 7>diff_weights_prv(
+ scratchpad.get<float>(key_wino_U) + U_sz,
+ 0, jcp.oc / simd_w, jcp.ic / simd_w, jcp.kh, jcp.kw, simd_w, simd_w);
+
+ array_offset_calculator<float, 8> M(scratchpad.get<float>(key_wino_M),
+ 0, alpha, alpha,
+ jcp.oc_block,
+ jcp.nb_tile_block_ur,
+ jcp.tile_block_ur,
+ jcp.oc_reg_block,
+ jcp.oc_simd_block);
+
+ array_offset_calculator<float, 7> V(scratchpad.get<float>(key_wino_V),
+ 0, alpha, alpha,
+ jcp.ic_block,
+ jcp.nb_tile_block_ur,
+ jcp.tile_block_ur,
+ jcp.ic_simd_block);
+
+ array_offset_calculator<float, 2> diff_bias_prv(
+ scratchpad.get<float>(key_conv_bia_reduction), nthreads, jcp.oc);
+
+ auto trans_ker_p = jit_wino_transform_call_s();
+ float I[alpha][alpha][simd_w];
+ float T[alpha][alpha][simd_w];
+ float G_I_3x3_4x4[9] = {-2.25f, -0.390625f, 0.87890625f, -2.640625f,
+ 0.625f, -0.625f, 1.5f, -1.5f, -2.640625f};
+ float G_W_3x3_4x4[8] = {0.26890756302521f, -0.688403361344538f, 0.119514472455649f,
+ 0.430252100840336f, 0.168067226890756f, 0.179271708683473f, 0.403361344537815f,
+ 1.13777777777778f};
+ float G_O_3x3_4x4[4] = {2.25f, 0.625f, 1.5f, 0.390625f};
+
+PRAGMA_OMP(parallel num_threads(nthreads) firstprivate(trans_ker_p, I, T))
+{
+ if (jcp.with_bias) {
+ parallel_nd_in_omp(nthreads, jcp.oc / simd_w,
+ [&](int ithr, int ofm){
+ float *pdbias = &(diff_bias_prv(ithr, ofm * simd_w));
+ PRAGMA_OMP_SIMD()
+ for (int v = 0; v < simd_w; v++) {
+ pdbias[v] = 0.0f;
+ }
+ });
+ }
+
+ int ithr = mkldnn_get_thread_num();
+ for (int ifm1 = 0; ifm1 < jcp.nb_ic; ++ifm1) {
+ int first_tblk = 0;
+PRAGMA_OMP(for)
+ for (int tblk1 = 0; tblk1 < jcp.tile_block; ++tblk1) {
+ int tile_index = tblk1 * jcp.nb_tile_block_ur * jcp.tile_block_ur;
+ int img = tile_index / (jcp.itiles * jcp.jtiles);
+ trans_ker_p.ti = tile_index % jcp.itiles;
+ trans_ker_p.tj = (tile_index / jcp.itiles) % jcp.jtiles;
+ trans_ker_p.M = I;
+ trans_ker_p.T = T;
+ trans_ker_p.G = G_I_3x3_4x4;
+ for (int ifm2 = 0; ifm2 < jcp.ic_block; ++ifm2) {
+ int ifm = ifm1 * jcp.ic_block + ifm2;
+ trans_ker_p.src = (float *)&(src(img, ifm, 0, 0, 0));
+ trans_ker_p.dst = (float *)&(V(ithr, 0, 0, ifm2, 0, 0, 0));
+ kernel_->src_transform(&trans_ker_p);
+ }
+
+ for (int ofm1 = 0; ofm1 < jcp.nb_oc; ++ofm1) {
+ trans_ker_p.G = G_W_3x3_4x4;
+ for (int ofm2 = 0; ofm2 < jcp.oc_block; ++ofm2) {
+ int ofm = (ofm1 * jcp.oc_block + ofm2) * jcp.oc_reg_block;
+ trans_ker_p.src = (float *)&(diff_dst(img, ofm, 0, 0, 0));
+ trans_ker_p.dst = (float *)&(M(ithr, 0, 0, ofm2, 0, 0, 0, 0));
+ if (jcp.with_bias && ifm1 == 0) {
+ trans_ker_p.bias = (float *)&(diff_bias_prv(ithr, ofm * simd_w));
+ kernel_->diff_dst_transform_wbias(&trans_ker_p);
+ } else {
+ kernel_->diff_dst_transform(&trans_ker_p);
+ }
+ }
+
+ for (int oj = 0; oj < alpha; ++oj) {
+ for (int oi = 0; oi < alpha; ++oi) {
+ kernel_->gemm_loop_ker_first_iter(
+ &(Us(ithr, oj, oi, 0, 0, 0, 0, 0)),
+ &(M(ithr, oj, oi, 0, 0, 0, 0, 0)),
+ &(V(ithr, oj, oi, 0, 0, 0, 0)));
+ }
+ }
+ trans_ker_p.G = G_O_3x3_4x4;
+ for (int ofm2 = 0; ofm2 < jcp.oc_block; ++ofm2) {
+ for (int ofm3 = 0; ofm3 < jcp.oc_reg_block; ++ofm3) {
+ int ofm = (ofm1 * jcp.oc_block + ofm2) * jcp.oc_reg_block
+ + ofm3;
+ for (int ifm2 = 0; ifm2 < jcp.ic_block; ++ifm2) {
+ int ifm = ifm1 * jcp.ic_block + ifm2;
+ trans_ker_p.src = (float *)&(Us(ithr, 0, 0,
+ ofm2, ifm2, 0, ofm3, 0));
+ trans_ker_p.dst = (float *)&(diff_weights_prv(ithr,
+ ofm, ifm, 0, 0, 0, 0));
+ if (first_tblk == 0) {
+ kernel_->diff_weights_transform(&trans_ker_p);
+ } else {
+ kernel_->diff_weights_transform_accum(&trans_ker_p);
+ }
+ }
+ }
+ }
+ }
+ ++first_tblk;
+ }
+ }
+}
+
+ // Reduce diff-weights
+ {
+ float *output = ptr_diff_weights;
+ float *input_base = scratchpad.get<float>(key_wino_U) + U_sz;
+ int nelems = jcp.oc * jcp.ic * jcp.kh * jcp.kw;
+ float *input_ptrs[max_threads_number];
+ for (int i = 0; i < nthreads; ++i) {
+ input_ptrs[i] = input_base + nelems * i;
+ }
+ array_sum(nthreads, output, nelems, input_ptrs, false);
+
+ if (jcp.with_bias) {
+ output = ptr_diff_bias;
+ input_base = scratchpad.get<float>(key_conv_bia_reduction);
+ for (int i = 0; i < nthreads; ++i) {
+ input_ptrs[i] = input_base + jcp.oc * i;
+ }
+ array_sum(nthreads, output, jcp.oc_without_padding, input_ptrs,
+ false);
+ }
+ }
+}
+
+void jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_t::
+_execute_backward_weights_S_D_Giot_W(const float *ptr_src,
+ const float *ptr_diff_dst, float *ptr_diff_weights,
+ float *ptr_diff_bias,
+ const memory_tracking::grantor_t &scratchpad) const {
+ const auto &jcp = kernel_->jcp;
+ const int nthreads = jcp.nthr;
+
+ array_offset_calculator<float, 5> src((float *)ptr_src,
+ jcp.mb, jcp.ic / simd_w, jcp.ih, jcp.iw, simd_w);
+ array_offset_calculator<float, 5> diff_dst((float *)ptr_diff_dst,
+ jcp.mb, jcp.oc / simd_w, jcp.oh, jcp.ow, simd_w);
+ array_offset_calculator<float, 6> diff_weights((float *)ptr_diff_weights,
+ jcp.oc / simd_w, jcp.ic / simd_w, jcp.kh, jcp.kw, simd_w, simd_w);
+ array_offset_calculator<float, 1> diff_bias((float *)ptr_diff_bias, jcp.oc);
+
+ array_offset_calculator<float, 9> U(scratchpad.get<float>(key_wino_U),
+ jcp.nb_ic, jcp.nb_oc,
+ alpha, alpha,
+ jcp.oc_block, jcp.ic_block,
+ jcp.ic_simd_block,
+ jcp.oc_reg_block,
+ jcp.oc_simd_block);
+
+ const int U_size = jcp.oc * jcp.ic * alpha * alpha;
+ array_offset_calculator<float, 10> Us(
+ scratchpad.get<float>(key_wino_U) + U_size,
+ 0, jcp.nb_ic, jcp.nb_oc,
+ alpha, alpha,
+ jcp.oc_block, jcp.ic_block,
+ jcp.ic_simd_block,
+ jcp.oc_reg_block,
+ jcp.oc_simd_block);
+
+ array_offset_calculator<float, 9> M(scratchpad.get<float>(key_wino_M),
+ jcp.nb_oc,
+ jcp.tile_block,
+ alpha, alpha,
+ jcp.oc_block,
+ jcp.nb_tile_block_ur,
+ jcp.tile_block_ur ,
+ jcp.oc_reg_block,
+ jcp.oc_simd_block);
+
+ array_offset_calculator<float, 8> V(scratchpad.get<float>(key_wino_V),
+ jcp.nb_ic,
+ jcp.tile_block,
+ alpha, alpha,
+ jcp.ic_block,
+ jcp.nb_tile_block_ur, jcp.tile_block_ur,
+ jcp.ic_simd_block);
+
+ array_offset_calculator<float, 2> diff_bias_prv(
+ scratchpad.get<float>(key_conv_bia_reduction), nthreads, jcp.oc);
+
+ size_t input_starts[max_threads_number] = {0};
+ size_t input_ends[max_threads_number] = {0};
+ size_t first_tblk = 0;
+
+ auto trans_ker_p = jit_wino_transform_call_s();
+ float G_I_3x3_4x4[9] = {-2.25f, -0.390625f, 0.87890625f, -2.640625f,
+ 0.625f, -0.625f, 1.5f, -1.5f, -2.640625f};
+ float G_W_3x3_4x4[8] = {0.26890756302521f, -0.688403361344538f,
+ 0.119514472455649f, 0.430252100840336f, 0.168067226890756f,
+ 0.179271708683473f, 0.403361344537815f, 1.13777777777778f};
+ float G_O_3x3_4x4[4] = {2.25f, 0.625f, 1.5f, 0.390625f};
+ float I[alpha][alpha][simd_w];
+ float T[alpha][alpha][simd_w];
+
+PRAGMA_OMP(parallel firstprivate(first_tblk, trans_ker_p, I, T))
+{
+ if (jcp.with_bias) {
+ parallel_nd_in_omp(nthreads, jcp.oc, [&](int ithr, int ofm) {
+ diff_bias_prv(ithr, ofm) = 0.0f;
+ });
+ }
+
+ trans_ker_p.G = G_I_3x3_4x4;
+ trans_ker_p.M = I;
+ trans_ker_p.T = T;
+
+ parallel_nd_in_omp(jcp.nb_ic, jcp.ic_block, jcp.mb,
+ [&](int ifm1, int ifm2, int img){
+ size_t ifm = ifm1 * jcp.ic_block + ifm2;
+ size_t tile_base_index = img * (jcp.itiles * jcp.jtiles);
+ size_t tblk3 = tile_base_index % jcp.tile_block_ur;
+ size_t tblk2 = (tile_base_index / jcp.tile_block_ur)
+ % jcp.nb_tile_block_ur;
+ size_t tblk1 = (tile_base_index / jcp.tile_block_ur)
+ / jcp.nb_tile_block_ur;
+ trans_ker_p.tile_count = tblk2 * jcp.tile_block_ur + tblk3;
+ trans_ker_p.src = (float *)&(src(img, ifm, 0, 0, 0));
+ trans_ker_p.dst = (float *)&(V(ifm1, tblk1, 0, 0, ifm2, 0, 0, 0));
+ kernel_->src_transform(&trans_ker_p);
+ });
+
+ int ithr = mkldnn_get_thread_num();
+ trans_ker_p.G = G_W_3x3_4x4;
+ parallel_nd_in_omp(jcp.nb_oc, jcp.oc_block, jcp.mb,
+ [&](int ofm1, int ofm2, int img){
+ int ofm = (ofm1 * jcp.oc_block + ofm2) * jcp.oc_reg_block;
+ size_t tile_base_index = img * (jcp.itiles * jcp.jtiles);
+ size_t tblk3 = tile_base_index % jcp.tile_block_ur;
+ size_t tblk2 = (tile_base_index / jcp.tile_block_ur)
+ % jcp.nb_tile_block_ur;
+ size_t tblk1 = (tile_base_index / jcp.tile_block_ur)
+ / jcp.nb_tile_block_ur;
+ trans_ker_p.tile_count = tblk2 * jcp.tile_block_ur + tblk3;
+ trans_ker_p.src = (float *)&(diff_dst(img, ofm, 0, 0, 0));
+ trans_ker_p.dst = (float *)&(M(ofm1, tblk1, 0, 0, ofm2, 0, 0, 0, 0));
+ if (jcp.with_bias) {
+ trans_ker_p.bias = (float *)&(diff_bias_prv(ithr, ofm * simd_w));
+ kernel_->diff_dst_transform_wbias(&trans_ker_p);
+ } else {
+ kernel_->diff_dst_transform(&trans_ker_p);
+ }
+ });
+
+ PRAGMA_OMP(barrier)
+
+ parallel_nd_in_omp(jcp.nb_ic, jcp.nb_oc, alpha, alpha, jcp.tile_block,
+ [&](int ifm1, int ofm1, int oj, int oi, int tblk1){
+ if (first_tblk == 0) {
+ input_starts[ithr] =
+ (float *)&(Us(ithr, ifm1, ofm1, oj, oi, 0, 0, 0,
+ 0, 0))
+ - (float *)&(Us(ithr, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0));
+ input_ends[ithr] = input_starts[ithr]
+ + jcp.oc_block * jcp.ic_block
+ * jcp.ic_simd_block * jcp.oc_reg_block
+ * jcp.oc_simd_block;
+ }
+ else if (tblk1 == 0) {
+ input_ends[ithr] += jcp.oc_block * jcp.ic_block
+ * jcp.ic_simd_block * jcp.oc_reg_block
+ * jcp.oc_simd_block;
+ }
+
+ if (first_tblk == 0 || tblk1 == 0) {
+ kernel_->gemm_loop_ker_first_iter(
+ &(Us(ithr, ifm1, ofm1, oj, oi,
+ 0, 0, 0, 0, 0)),
+ &(M(ofm1, tblk1, oj, oi, 0, 0, 0, 0, 0)),
+ &(V(ifm1, tblk1, oj, oi, 0, 0, 0, 0)));
+ } else {
+ kernel_->gemm_loop_ker(
+ &(Us(ithr, ifm1, ofm1, oj, oi,
+ 0, 0, 0, 0, 0)),
+ &(M(ofm1, tblk1, oj, oi, 0, 0, 0, 0, 0)),
+ &(V(ifm1, tblk1, oj, oi, 0, 0, 0, 0)));
+ }
+ ++first_tblk;
+ });
+}
+
+ // Reduce diff-weights
+ {
+ float *output = &(U(0, 0, 0, 0, 0, 0, 0, 0, 0));
+ size_t nelems = jcp.ic * jcp.oc * alpha * alpha;
+ float *input_ptrs[max_threads_number];
+ for (int i = 0; i < nthreads; ++i)
+ input_ptrs[i] = output + nelems * (i + 1);
+ subarray_sum(nthreads, output, nelems, input_ptrs,
+ input_starts, input_ends);
+ }
+
+ trans_ker_p.G = G_O_3x3_4x4;
+PRAGMA_OMP(parallel firstprivate(trans_ker_p))
+ {
+ parallel_nd_in_omp(jcp.nb_ic, jcp.nb_oc, jcp.oc_block, jcp.ic_block, jcp.oc_reg_block,
+ [&](int ifm1, int ofm1, int ofm2, int ifm2, int ofm3){
+ int ofm = (ofm1 * jcp.oc_block + ofm2)
+ * jcp.oc_reg_block + ofm3;
+ int ifm = ifm1 * jcp.ic_block + ifm2;
+ trans_ker_p.src = (float *)&(U(ifm1, ofm1, 0, 0,
+ ofm2, ifm2, 0, ofm3, 0));
+ trans_ker_p.dst = (float *)&(diff_weights(ofm, ifm,
+ 0, 0, 0, 0));
+ kernel_->diff_weights_transform(&trans_ker_p);
+ });
+ }
+
+ if (jcp.with_bias) {
+ parallel_nd(jcp.oc / simd_w, [&](int ofm1) {
+ float* pbias = &(diff_bias(ofm1 * simd_w));
+ float *pbias_prv = &(diff_bias_prv(0, ofm1 * simd_w));
+
+ const int blk_sz = ofm1 == jcp.oc / simd_w - 1
+ ? jcp.oc_without_padding - ofm1 * simd_w : simd_w;
+
+ PRAGMA_OMP_SIMD()
+ for (int ofm2 = 0; ofm2 < blk_sz; ++ofm2) {
+ pbias[ofm2] = pbias_prv[ofm2];
+ }
+
+ for (int ithr = 1; ithr < nthreads; ++ithr) {
+ pbias_prv = &(diff_bias_prv(ithr, ofm1 * simd_w));
+ PRAGMA_OMP_SIMD()
+ for (int ofm2 = 0; ofm2 < blk_sz; ++ofm2) {
+ pbias[ofm2] += pbias_prv[ofm2];
+ }
+ }
+ });
+ }
+}
+
+}
+}
+}
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3.hpp
new file mode 100644
index 0000000000..f1a56aac70
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3.hpp
@@ -0,0 +1,386 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_CORE_FP32_WINO_CONV_4x3_HPP
+#define CPU_JIT_AVX512_CORE_FP32_WINO_CONV_4x3_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "jit_avx512_core_fp32_wino_conv_4x3_kernel.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace winograd_avx512_core {
+inline void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_winograd_conf_t &jcp) {
+ using namespace utils;
+ using namespace memory_tracking::names;
+
+ size_t U_sz = (size_t)alpha * alpha * jcp.ic * jcp.oc;
+ size_t V_sz = (size_t)alpha * alpha * jcp.mb * jcp.ic * jcp.itiles
+ * jcp.jtiles;
+ size_t M_sz = (size_t)alpha * alpha * jcp.mb * jcp.oc * jcp.itiles
+ * jcp.jtiles;
+
+ switch (jcp.sched_policy) {
+ case WSCHED_DATA_W_SGD:
+ V_sz = (size_t)jcp.nthr * alpha * alpha * jcp.nb_tile_block_ur
+ * jcp.tile_block_ur * jcp.ic;
+ M_sz = (size_t)jcp.nthr * alpha * alpha * jcp.nb_tile_block_ur
+ * jcp.tile_block_ur * jcp.oc;
+ break;
+ case WSCHED_WEI_SDGtWo:
+ U_sz = (size_t)jcp.nthr * (alpha * alpha * jcp.oc
+ * (jcp.ic / jcp.nb_ic) + jcp.ic * jcp.oc * jcp.kh * jcp.kw);
+ M_sz = (size_t)jcp.nthr * alpha * alpha * (jcp.ntiles / jcp.tile_block)
+ * (jcp.oc / jcp.nb_oc);
+ V_sz = (size_t)jcp.nthr * alpha * alpha * (jcp.ntiles / jcp.tile_block)
+ * (jcp.ic / jcp.nb_ic);
+ break;
+ case WSCHED_WEI_S_D_Giot_W:
+ U_sz = (size_t)(jcp.nthr + 1) * alpha * alpha * jcp.ic * jcp.oc;
+ M_sz = (size_t)alpha * alpha * jcp.oc * jcp.ntiles;
+ V_sz = (size_t)alpha * alpha * jcp.ic * jcp.ntiles;
+ break;
+ default: break;
+ }
+
+ scratchpad.book(key_wino_U, sizeof(float) * U_sz, PAGE_2M);
+ scratchpad.book(key_wino_V, sizeof(float) * V_sz, PAGE_2M);
+ scratchpad.book(key_wino_M, sizeof(float) * M_sz, PAGE_2M);
+
+ if (one_of(jcp.sched_policy, WSCHED_WEI_SDGtWo, WSCHED_WEI_S_D_Giot_W)) {
+ size_t br_sz = (size_t)jcp.nthr * jcp.oc;
+ scratchpad.book(key_conv_bia_reduction, sizeof(float) * br_sz, PAGE_2M);
+ }
+}
+}
+
+template <bool is_fwd>
+struct _jit_avx512_core_fp32_wino_conv_4x3_t {
+
+ _jit_avx512_core_fp32_wino_conv_4x3_t(
+ const jit_conv_winograd_conf_t &jcp, const primitive_attr_t *attr)
+ : kernel_(nullptr), attr_(attr) {
+ kernel_ = new _jit_avx512_core_fp32_wino_conv_4x3_data_kernel(jcp);
+ }
+
+ ~_jit_avx512_core_fp32_wino_conv_4x3_t() { delete kernel_; }
+
+ protected:
+ void weight_transform_data(const jit_conv_winograd_conf_t &jcp,
+ float *wp, float *twp) const;
+ void input_transform_data(int image,
+ const jit_conv_winograd_conf_t &jcp,
+ float *inp, float *tinp) const;
+ void input_transform_tileblock_data(int tile_block,
+ const jit_conv_winograd_conf_t &jcp,
+ float *inp, float *tinp) const;
+ void output_transform_data(int image,
+ const jit_conv_winograd_conf_t &jcp,
+ const post_ops_t &p_ops, float *toutp, float *pout_b,
+ float *bias) const;
+ void output_transform_tileblock_data(int tile_block,
+ const jit_conv_winograd_conf_t &jcp, const post_ops_t &p_ops,
+ float *toutp, float *outp, float *bias) const;
+ void _execute_data_W_S_G_D(float *inp_ptr, float *out_ptr,
+ float *wei_ptr, float *bias_ptr,
+ const memory_tracking::grantor_t &scratchpad) const;
+ void _execute_data_W_SGD(float *inp_ptr, float *out_ptr,
+ float *wei_ptr, float *bias_ptr,
+ const memory_tracking::grantor_t &scratchpad) const;
+ _jit_avx512_core_fp32_wino_conv_4x3_data_kernel *kernel_;
+ const primitive_attr_t *attr_;
+};
+
+struct jit_avx512_core_fp32_wino_conv_4x3_fwd_t
+ : _jit_avx512_core_fp32_wino_conv_4x3_t<true>
+ , public cpu_primitive_t
+ {
+ struct pd_t : public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_wino_4x3:", avx512_core, ""),
+ jit_avx512_core_fp32_wino_conv_4x3_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && utils::one_of(desc()->alg_kind,
+ alg_kind::convolution_auto,
+ alg_kind::convolution_winograd)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_avx512_core_fp32_wino_conv_4x3_fwd_kernel::
+ init_conf(jcp_, *desc(), src_md_, weights_md_, dst_md_,
+ *attr());
+ if (status != status::success) return status;
+ set_default_alg_kind(alg_kind::convolution_winograd);
+
+ auto scratchpad = scratchpad_registry().registrar();
+ winograd_avx512_core::init_scratchpad(scratchpad, jcp_);
+
+ return status;
+ }
+
+ jit_conv_winograd_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+ auto wei_fmt = desc()->prop_kind == prop_kind::forward_training
+ ? (with_groups() ? gOIhw16i16o : OIhw16i16o) : any;
+ return set_default_formats_common(nChw16c, wei_fmt, nChw16c);
+ }
+ };
+
+ jit_avx512_core_fp32_wino_conv_4x3_fwd_t(const pd_t *apd)
+ : _jit_avx512_core_fp32_wino_conv_4x3_t<true>(apd->jcp_, apd->attr())
+ , cpu_primitive_t(apd, true)
+ {}
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ auto src = CTX_IN_MEM(const float *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const float *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const float *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(float *, MKLDNN_ARG_DST);
+
+ auto scratchpad = this->scratchpad(ctx);
+
+ switch ((pd()->jcp_).sched_policy) {
+ case WSCHED_DATA_W_S_G_D:
+ this->_execute_data_W_S_G_D((float *)src, dst, (float *)weights,
+ (float *)bias, scratchpad);
+ break;
+ case WSCHED_DATA_W_SGD:
+ this->_execute_data_W_SGD((float *)src, dst, (float *)weights,
+ (float *)bias, scratchpad);
+ break;
+ default:
+ break;
+ }
+ return status::success;
+ }
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+struct jit_avx512_core_fp32_wino_conv_4x3_bwd_data_t
+ : _jit_avx512_core_fp32_wino_conv_4x3_t<false>,
+ public cpu_primitive_t {
+ struct pd_t : public cpu_convolution_bwd_data_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_data_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_wino_4x3:", avx512_core, ""),
+ jit_avx512_core_fp32_wino_conv_4x3_bwd_data_t);
+
+ status_t init() {
+ bool ok = true
+ && mkldnn_thr_syncable()
+ && desc()->prop_kind == prop_kind::backward_data
+ && utils::one_of(desc()->alg_kind,
+ alg_kind::convolution_auto,
+ alg_kind::convolution_winograd)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::undef, data_type::f32, data_type::f32)
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_avx512_core_fp32_wino_conv_4x3_bwd_data_kernel
+ ::init_conf(jcp_, *desc(), *diff_src_md(), *weights_md(),
+ *diff_dst_md());
+ if (status != status::success) return status;
+ set_default_alg_kind(alg_kind::convolution_winograd);
+
+ auto scratchpad = scratchpad_registry().registrar();
+ winograd_avx512_core::init_scratchpad(scratchpad, jcp_);
+
+ return status;
+ }
+
+ jit_conv_winograd_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+ auto wei_fmt = with_groups() ? gOIhw16i16o : OIhw16i16o;
+ return set_default_formats_common(nChw16c, wei_fmt, nChw16c);
+ }
+ };
+
+ jit_avx512_core_fp32_wino_conv_4x3_bwd_data_t(const pd_t *apd)
+ : _jit_avx512_core_fp32_wino_conv_4x3_t<false>(apd->jcp_, apd->attr())
+ , cpu_primitive_t(apd, true)
+ {}
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ auto diff_dst = CTX_IN_MEM(const float *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const float *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(float *, MKLDNN_ARG_DIFF_SRC);
+
+ auto scratchpad = this->scratchpad(ctx);
+
+ switch ((pd()->jcp_).sched_policy) {
+ case WSCHED_DATA_W_S_G_D:
+ this->_execute_data_W_S_G_D((float *)diff_dst, diff_src,
+ (float *)weights, NULL, scratchpad);
+ break;
+
+ case WSCHED_DATA_W_SGD:
+ this->_execute_data_W_SGD((float *)diff_dst, diff_src,
+ (float *)weights, NULL, scratchpad);
+ break;
+
+ default:
+ break;
+ }
+
+ return status::success;
+ }
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+struct jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_t
+ : public cpu_primitive_t {
+ struct pd_t : public cpu_convolution_bwd_weights_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_weights_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_wino_4x3:", avx512_core, ""),
+ jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_t);
+
+ status_t init() {
+ bool ok = true
+ && mkldnn_thr_syncable()
+ && desc()->prop_kind == prop_kind::backward_weights
+ && utils::one_of(desc()->alg_kind,
+ alg_kind::convolution_auto,
+ alg_kind::convolution_winograd)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && set_default_formats();
+ if (!ok)
+ return status::unimplemented;
+
+ status_t status =
+ jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_kernel::
+ init_conf(jcp_, *desc(), *src_md(), *diff_dst_md(),
+ *diff_weights_md());
+ if (status != status::success) return status;
+ set_default_alg_kind(alg_kind::convolution_winograd);
+
+ auto scratchpad = scratchpad_registry().registrar();
+ winograd_avx512_core::init_scratchpad(scratchpad, jcp_);
+
+ return status;
+ }
+
+ jit_conv_winograd_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+ auto wei_fmt = with_groups() ? gOIhw16i16o : OIhw16i16o;
+ return set_default_formats_common(nChw16c, wei_fmt, nChw16c);
+ }
+ };
+
+ jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_t(const pd_t *apd)
+ : cpu_primitive_t(apd, true)
+ , kernel_(nullptr)
+ {
+ kernel_ = new jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_kernel(
+ pd()->jcp_);
+ }
+
+ ~jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_t()
+ {
+ delete kernel_;
+ }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ auto diff_dst = CTX_IN_MEM(const float *, MKLDNN_ARG_DIFF_DST);
+ auto src = CTX_IN_MEM(const float *, MKLDNN_ARG_SRC);
+ auto diff_weights = CTX_OUT_MEM(float *, MKLDNN_ARG_DIFF_WEIGHTS);
+ auto diff_bias = CTX_OUT_MEM(float *, MKLDNN_ARG_DIFF_BIAS);
+
+ switch (kernel_->jcp.sched_policy) {
+ case WSCHED_WEI_SDGtWo:
+ _execute_backward_weights_SDGtWo(src, diff_dst, diff_weights,
+ diff_bias, scratchpad(ctx));
+ break;
+ case WSCHED_WEI_S_D_Giot_W:
+ _execute_backward_weights_S_D_Giot_W(src, diff_dst, diff_weights,
+ diff_bias, scratchpad(ctx));
+ break;
+ default:
+ assert(kernel_->jcp.sched_policy != WSCHED_INVALID);
+ break;
+ }
+ return status::success;
+ }
+
+private:
+ void _execute_backward_weights_SDGtWo(const float *src,
+ const float *diff_dst, float *diff_weights, float *diff_bias,
+ const memory_tracking::grantor_t &scratchpad) const;
+ void _execute_backward_weights_S_D_Giot_W(const float *src,
+ const float *diff_dst, float *diff_weights, float *diff_bias,
+ const memory_tracking::grantor_t &scratchpad) const;
+
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_kernel *kernel_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3_kernel.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3_kernel.cpp
new file mode 100644
index 0000000000..0d64a2d13a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3_kernel.cpp
@@ -0,0 +1,2596 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include <math.h>
+
+#include "jit_avx512_core_fp32_wino_conv_4x3_kernel.hpp"
+
+#define GET_OFF(field) offsetof(jit_wino_transform_call_s, field)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace {
+
+using namespace mkldnn::impl::utils;
+
+unsigned int L1_cache_size = get_cache_size(1, true);
+unsigned int L2_cache_size = get_cache_size(2, true);
+unsigned int LLC_data_size = get_cache_size(3, false);
+
+// the test funtion takes jcp, the candidate and the current best.
+// it returns true if the new candidate is better
+int get_divisor_satisfying_cond(jit_conv_winograd_conf_t &jcp, int number,
+ int default_best, bool (*test)(jit_conv_winograd_conf_t &, int, int))
+{
+ int best_divisor = default_best;
+ auto test_num
+ = [&best_divisor, test](jit_conv_winograd_conf_t &jcp, int num) {
+ if (test(jcp, num, best_divisor)) {
+ best_divisor = num;
+ }
+ };
+
+ for (int divisor = 1; divisor <= ::sqrt(number); divisor++) {
+ if (number % divisor == 0) {
+ test_num(jcp, divisor);
+ test_num(jcp, number / divisor);
+ }
+ }
+
+ return best_divisor;
+}
+
+namespace {
+bool is_winograd_faster_than_direct(const jit_conv_winograd_conf_t &jcp) {
+ /* Determines if current winograd implementation is faster than direct.
+ Following conditions are empirical and based on performance data */
+ unsigned int ncores_per_socket =
+ cpu.getNumCores(Xbyak::util::IntelCpuTopologyLevel::CoreLevel);
+ unsigned int nthreads = mkldnn_get_max_threads();
+
+ if (jcp.prop_kind == prop_kind::forward_inference) {
+ return jcp.mb >= 4;
+ } else if (nthreads > ncores_per_socket) {
+ double src_dst_transforms_per_core = alpha * alpha
+ * (jcp.ic + jcp.oc)
+ * jcp.mb * ((jcp.oh + tile_size - 1) / tile_size)
+ * ((jcp.ow + tile_size - 1) / tile_size)
+ * sizeof(float) / 1024. / 1024. / nthreads;
+ double wei_transform = alpha * alpha
+ * jcp.ic * jcp.oc * sizeof(float) /1024. / 1024.;
+
+ if (jcp.prop_kind == prop_kind::backward_weights) {
+ if (src_dst_transforms_per_core < 0.3
+ || (src_dst_transforms_per_core <= 28 && wei_transform < 4))
+ return false;
+ else
+ return true;
+ } else {
+ if (src_dst_transforms_per_core < 2.0 || wei_transform < 0.02)
+ return false;
+ }
+ }
+
+ return jcp.mb > 8;
+}
+}
+
+/* assumes 512 bits registers */
+/* TODO: add support for strides */
+/* TODO: handle the prefetch distance automatically */
+typedef enum cache_t_ { L1, L2, L3 } cache_t;
+
+template <typename data_t>
+struct prefetcher_t {
+ prefetcher_t(jit_generator *generator, Xbyak::Reg64 reg_base_addr,
+ cache_t cache_type, size_t block_size, /* in number of elements*/
+ int nb_instructions_in_block, int fma_ipc)
+ : cg_(generator)
+ , reg_base_addr_(reg_base_addr)
+ , cache_type_(cache_type)
+ , cache_block_size_(block_size)
+ {
+ nb_cache_lines_to_prefetch_ = cache_block_size_ / (64 / sizeof(data_t));
+ prefetch_spread_
+ = div_up(nb_instructions_in_block, nb_cache_lines_to_prefetch_);
+ prefetch_blk_
+ = div_up(nb_cache_lines_to_prefetch_, nb_instructions_in_block);
+
+ /* assumption: when fetch in Li, data is already in L(i+1) */
+ int cache_latency;
+ switch (cache_type_) {
+ case L1: cache_latency = 14; break;
+ case L2: cache_latency = 250; break;
+ case L3: cache_latency = 250; break;
+ }
+
+ prefetch_distance_ = div_up(cache_latency, nb_cache_lines_to_prefetch_);
+ }
+
+ void prefetch(int instruction_number)
+ {
+ if (instruction_number % prefetch_spread_ == 0) {
+ for (int i = 0; (i < prefetch_blk_)
+ && (prefetches_issued_ < nb_cache_lines_to_prefetch_);
+ i++, prefetches_issued_++) {
+ prefetch_inst_(cg_->EVEX_compress_addr(
+ reg_base_addr_, (cache_block_size_ * prefetch_distance_)
+ * sizeof(data_t)
+ + (prefetches_issued_ * 64)));
+ }
+ }
+ }
+
+private:
+ void prefetch_inst_(const Xbyak::Address &addr)
+ {
+ switch (cache_type_) {
+ case L1: cg_->prefetcht0(addr); break;
+ case L2: cg_->prefetcht1(addr); break;
+ case L3: cg_->prefetcht2(addr); break;
+ default:
+ break; // TODO: raise an exception or put an assert
+ }
+ }
+
+ jit_generator *cg_;
+ Xbyak::Reg64 reg_base_addr_;
+ cache_t cache_type_;
+ int cache_block_size_ = 0;
+ int nb_cache_lines_to_prefetch_ = 0;
+ int prefetches_issued_ = 0;
+ int prefetch_spread_ = 0;
+ int prefetch_blk_ = 0;
+ int prefetch_distance_ = 0;
+};
+
+// utilities to support kernel parameter selection
+bool check_L2_block_per_thread(jit_conv_winograd_conf_t &jcp,
+ int dimN_block, float C2_min, float C2_max) {
+ float block_size = alpha * alpha * (2*(jcp.oc + jcp.ic)
+ * dimN_block * jcp.dimN_reg_block
+ + div_up(jcp.ic * jcp.oc,mkldnn_get_max_threads())) * (float)sizeof(float);
+ float L2_lb = C2_min * L2_cache_size;
+ float L2_ub = C2_max * L2_cache_size;
+ return (block_size > L2_lb && block_size < L2_ub);
+}
+
+bool check_L1_block_gemm(jit_conv_winograd_conf_t &jcp, int dimK_block,
+ int dimM_block, float C1_min, float C1_max) {
+ float gemm_block_size = (dimM_block * jcp.dimM_simd_block * dimK_block
+ * jcp.dimK_reg_block * jcp.dimM_reg_block
+ + dimK_block * jcp.dimK_reg_block * jcp.dimN_reg_block
+ + dimM_block * jcp.dimM_simd_block * jcp.dimN_reg_block)
+ * (float)sizeof(float);
+ float L1_lb = C1_min * L1_cache_size;
+ float L1_ub = C1_max * L1_cache_size;
+ return (gemm_block_size > L1_lb && gemm_block_size < L1_ub);
+}
+bool check_cond1(int dimN_reg_block, int dimK_block, int dimK_reg_block,
+ int dimM_block, int dimM_reg_block, int dimM_simd_block, float C)
+{
+ float lhs = (dimM_block * dimN_reg_block * dimM_simd_block * dimM_reg_block
+ + dimM_block * dimK_block * dimK_reg_block
+ * dimM_simd_block * dimM_reg_block
+ + dimK_block * dimN_reg_block * dimK_reg_block)
+ * (float)sizeof(float);
+ float rhs = C * L1_cache_size;
+ return (lhs < rhs);
+}
+bool check_cond1_bis(int dimN_reg_block, int dimK_block, int dimK_reg_block,
+ int dimM_block, int dimM_reg_block, int dimM_simd_block, float C)
+{
+ float lhs = (dimM_block * dimM_reg_block * dimK_block * dimK_reg_block
+ * dimM_simd_block + dimK_block * dimN_reg_block * dimK_reg_block)
+ * (float)sizeof(float);
+ float rhs = C * L1_cache_size;
+ return (lhs < rhs);
+}
+bool check_cond2(int nb_dimN_reg_block, int dimN_reg_block, int dimK_nb_block,
+ int dimK_block, int dimK_reg_block, int dimM_block, int dimM_reg_block,
+ int dimM_simd_block, float C)
+{
+ float lhs = (nb_dimN_reg_block * dimM_block * dimN_reg_block
+ * dimM_simd_block * dimM_reg_block
+ + dimK_nb_block * dimM_block * dimK_block * dimK_reg_block
+ * dimM_simd_block * dimM_reg_block
+ + nb_dimN_reg_block * dimK_nb_block * dimK_block
+ * dimN_reg_block * dimK_reg_block)
+ * (float)sizeof(float);
+ float rhs = C * L2_cache_size;
+ return (lhs < rhs);
+}
+
+bool check_kernel_cond(int dimM_block, int dimM_reg_block, int dimM_simd_block,
+ int dimN_block, int dimN_reg_block, int dimK, float C1, float C2)
+{
+ float A_size = dimM_block * dimM_reg_block * dimM_simd_block * dimK
+ * (float)sizeof(float);
+ float B_size = dimN_block * dimN_reg_block * dimK
+ * (float)sizeof(float);
+ return (A_size > C1 * L2_cache_size && B_size > C2 * L2_cache_size);
+}
+}
+
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::utils;
+using namespace Xbyak;
+
+void _jit_avx512_core_fp32_wino_conv_4x3_data_kernel::gemm_loop_generate()
+{
+ // for (int dimM_block =0; dimM_block < jcp.dimM_block; dimM_block++)
+ // for (int dimM_reg_block =0; dimM_reg_block < jcp.dimM_reg_block;
+ // dimM_reg_block++) // unrolled
+ // for (int dimK_block = 0; dimK_block < jcp.dimK_block; dimK_block++)
+ // for (int dimK_reg_block= 0; dimK_reg_block < jcp.dimK_reg_block;
+ // dimK_reg_block++) // unrolled
+ // for (int tile =0; tile < jcp.dimN_reg_block; tile++)
+ // C[dimM_block][dimM_reg_block][tile] +=
+ // A[dimM_block][dimM_reg_block][dimK_block][dimK_reg_block]
+ // * broadcast(B[dimK_block][tile][dimK_reg_block]);
+ // Notes:
+ // jcp.kernel_kind defines embedded or explicit broadcast
+ // dimM_reg_block=1 for embedded bcast kernel
+
+ auto zmm_srcA = [=]() {
+ return Xbyak::Zmm(0);
+ };
+ auto zmm_srcB = [=](int tile) {
+ int idx = 1 + tile;
+ assert(idx < 1 + jcp.dimN_reg_block);
+ return Xbyak::Zmm(idx);
+ };
+ auto zmm_dstC = [=](int dimM_reg_block, int tile) {
+ int idx{0};
+ if (jcp.kernel_kind == embd_bcast)
+ idx = 1 + tile;
+ else
+ idx = 1 + jcp.dimN_reg_block
+ + dimM_reg_block * jcp.dimN_reg_block + tile;
+ assert(idx < 32);
+ return Xbyak::Zmm(idx);
+ };
+
+ auto prepare_output = [=]() {
+ for (int dimM_reg_block = 0; dimM_reg_block < jcp.dimM_reg_block;
+ dimM_reg_block++) {
+ for (int tile = 0; tile < jcp.dimN_reg_block; tile++) {
+ Zmm zmm = zmm_dstC(dimM_reg_block, tile);
+ vpxord(zmm, zmm, zmm);
+ }
+ }
+ };
+ auto store_output = [=](bool output_is_aligned) {
+ Label save;
+ cmp(reg_is_beta_zero, 0);
+ je(save, T_NEAR);
+
+ for (int dimM_reg_block = 0; dimM_reg_block < jcp.dimM_reg_block;
+ dimM_reg_block++) {
+ for (int tile = 0; tile < jcp.dimN_reg_block; tile++) {
+ Zmm zmm = zmm_dstC(dimM_reg_block,tile);
+ int output_offset
+ = jcp.dimN_reg_block * dimM_reg_block * 64 + tile * 64;
+ vaddps(zmm, zmm, EVEX_compress_addr(reg_dstC, output_offset));
+ }
+ }
+
+ L(save);
+ for (int dimM_reg_block = 0; dimM_reg_block < jcp.dimM_reg_block;
+ dimM_reg_block++) {
+ for (int tile = 0; tile < jcp.dimN_reg_block; tile++) {
+ Zmm zmm = zmm_dstC(dimM_reg_block,tile);
+ int output_offset
+ = jcp.dimN_reg_block * dimM_reg_block * 64 + tile * 64;
+
+ // In W_SGD, output will be reused.
+ if (output_is_aligned
+ && jcp.dimK_nb_block == 1
+ && jcp.sched_policy == WSCHED_DATA_W_S_G_D
+ && (jcp.dimN * jcp.dimM * alpha * alpha
+ * sizeof(float) > 2 * LLC_data_size))
+ vmovntps(EVEX_compress_addr(reg_dstC, output_offset), zmm);
+ else vmovups(EVEX_compress_addr(reg_dstC, output_offset), zmm);
+ }
+ }
+ };
+
+ auto inner_loops = [=]() {
+ Label dimM_block_loop, dimK_block_loop;
+
+ if (jcp.dimM_block > 1) {
+ mov(reg_dimM_block_loop_cnt, jcp.dimM_block);
+ L(dimM_block_loop);
+ }
+
+ prepare_output();
+
+ if (jcp.dimK_block > 1) {
+ mov(reg_dimK_block_loop_cnt, jcp.dimK_block);
+ L(dimK_block_loop);
+ }
+
+ for (int dimK_reg_block = 0;
+ dimK_reg_block < jcp.dimK_reg_block;
+ dimK_reg_block ++) {
+
+ if (jcp.kernel_kind == expl_bcast) {
+ for (int tile = 0; tile < jcp.dimN_reg_block; tile++) {
+ vbroadcastss(zmm_srcB(tile),
+ ptr[reg_srcB + 64 * tile + dimK_reg_block * 4]);
+ }
+ }
+
+ /* Performing the fmas */
+
+ for (int dimM_reg_block = 0; dimM_reg_block < jcp.dimM_reg_block;
+ dimM_reg_block++) {
+
+ vmovups(zmm_srcA(),
+ zword[reg_srcA
+ + jcp.dimK_reg_block * jcp.dimK_block * 64
+ * dimM_reg_block
+ + dimK_reg_block * 64]
+ );
+
+ for (int tile = 0; tile < jcp.dimN_reg_block; tile++) {
+ if (jcp.kernel_kind == expl_bcast)
+ vfmadd231ps(zmm_dstC(dimM_reg_block, tile), zmm_srcA(),
+ zmm_srcB(tile));
+ else
+ vfmadd231ps(zmm_dstC(dimM_reg_block, tile), zmm_srcA(),
+ EVEX_compress_addr(reg_srcB,
+ 64 * tile + dimK_reg_block * 4, true));
+ }
+ }
+ }
+ add(reg_srcA, jcp.dimK_reg_block * 64);
+ add(reg_srcB, jcp.dimN_reg_block * 64);
+ if (jcp.dimK_block > 1) {
+ sub(reg_dimK_block_loop_cnt, 1);
+ jnz(dimK_block_loop);
+ }
+
+ Label unaligned_store, end_store;
+ test(reg_dstC, cpu_isa_traits<avx512_core>::vlen - 1);
+ jnz(unaligned_store, T_NEAR);
+ store_output(true);
+ jmp(end_store, T_NEAR);
+ L(unaligned_store); {
+ store_output(false);
+ }
+ L(end_store);
+
+ if (jcp.dimM_block > 1) {
+ sub(reg_srcB, jcp.dimK_block * jcp.dimN_reg_block * 64);
+ add(reg_dstC, jcp.dimM_reg_block * jcp.dimN_reg_block * 64);
+ if (jcp.kernel_kind == expl_bcast) {
+ add(reg_srcA,
+ (jcp.dimM_reg_block-1) * jcp.dimK_reg_block * 64
+ * jcp.dimK_block);
+ }
+ sub(reg_dimM_block_loop_cnt, 1);
+ jnz(dimM_block_loop);
+ }
+ };
+
+ /* Preamble */
+ preamble();
+
+ /* kernel */
+ inner_loops();
+
+ /* Postamble */
+ postamble();
+ ret();
+}
+
+void _jit_avx512_core_fp32_wino_conv_4x3_data_kernel
+ ::weights_transform_data_ker_generate()
+{
+ bool is_fwd = one_of(jcp.prop_kind,
+ mkldnn_forward_training, mkldnn_forward_inference);
+ int kh = jcp.kh;
+ int kw = jcp.kw;
+
+ auto zmm_temp = Xbyak::Zmm(31);
+ auto zmm_zero = Xbyak::Zmm(30);
+
+ auto zmm_M = [=](int i) {
+ return Xbyak::Zmm(i);
+ };
+ auto zmm_MT = [=](int i) {
+ return Xbyak::Zmm(i + simd_w);
+ };
+
+ auto zmm_G = [=](int i) {
+ return Xbyak::Zmm(i);
+ };
+ auto zmm_F = [=](int i) {
+ return Xbyak::Zmm(alpha + i);
+ };
+ auto zmm_T = [=](int i) {
+ return Xbyak::Zmm(alpha + 3 + i);
+ };
+ auto zmm_t = [=](int i) {
+ return Xbyak::Zmm(2 * alpha + 3 + i);
+ };
+
+ auto zmm_load = [=](int i) {
+ return Xbyak::Zmm(i);
+ };
+
+ auto init_G = [=]() {
+ mov(wreg_temp, ptr[param1 + GET_OFF(G)]);
+ for (int i = 0; i < alpha; i++) {
+ vbroadcastss(zmm_G(i), ptr[wreg_temp + i * typesize]);
+ }
+ vpxord(zmm_zero, zmm_zero, zmm_zero);
+ };
+
+ auto trans16x16 = [=]() {
+ for (int i = 0; i < simd_w; i+=2 ) {
+ vmovups(zmm_M(i), ptr[wreg_M + i * simd_w * 4]);
+ vmovups(zmm_M(i+1), ptr[wreg_M + (i + 1) * simd_w * 4]);
+ vunpcklps(zmm_MT(i), zmm_M(i), zmm_M(i+1));
+ vunpckhps(zmm_MT(i+1), zmm_M(i), zmm_M(i+1));
+ }
+ for (int i = 0; i < simd_w; i+=4 ) {
+ vunpcklpd(zmm_M(i), zmm_MT(i), zmm_MT(i+2));
+ vunpckhpd(zmm_M(i+1), zmm_MT(i), zmm_MT(i+2));
+ vunpcklpd(zmm_M(i+2), zmm_MT(i+1), zmm_MT(i+3));
+ vunpckhpd(zmm_M(i+3), zmm_MT(i+1), zmm_MT(i+3));
+ }
+ for (int i = 0; i < simd_w; i += 8) {
+ vshuff32x4(zmm_MT(i), zmm_M(i), zmm_M(i + 4), 0x88);
+ vshuff32x4(zmm_MT(i+1), zmm_M(i+1), zmm_M(i + 5), 0x88);
+ vshuff32x4(zmm_MT(i+2), zmm_M(i+2), zmm_M(i + 6), 0x88);
+ vshuff32x4(zmm_MT(i+3), zmm_M(i+3), zmm_M(i + 7), 0x88);
+ vshuff32x4(zmm_MT(i+4), zmm_M(i), zmm_M(i + 4), 0xdd);
+ vshuff32x4(zmm_MT(i+5), zmm_M(i+1), zmm_M(i + 5), 0xdd);
+ vshuff32x4(zmm_MT(i+6), zmm_M(i+2), zmm_M(i + 6), 0xdd);
+ vshuff32x4(zmm_MT(i+7), zmm_M(i+3), zmm_M(i + 7), 0xdd);
+ }
+ {
+ int i = 0;
+ int mask = 0x88;
+ vshuff32x4(zmm_M(0), zmm_MT(i), zmm_MT(i + 8), mask);
+ vmovups(ptr[wreg_MT + 0 * 16 * 4], zmm_M(0));
+ vshuff32x4(zmm_M(1), zmm_MT(i + 1), zmm_MT(i + 9), mask);
+ vmovups(ptr[wreg_MT + 1 * 16 * 4], zmm_M(1));
+ vshuff32x4(zmm_M(2), zmm_MT(i + 2), zmm_MT(i + 10), mask);
+ vmovups(ptr[wreg_MT + 2 * 16 * 4], zmm_M(2));
+ vshuff32x4(zmm_M(3), zmm_MT(i + 3), zmm_MT(i + 11), mask);
+ vmovups(ptr[wreg_MT + 3 * 16 * 4], zmm_M(3));
+ vshuff32x4(zmm_M(4), zmm_MT(i + 4), zmm_MT(i + 12), mask);
+ vmovups(ptr[wreg_MT + 4 * 16 * 4], zmm_M(4));
+ vshuff32x4(zmm_M(5), zmm_MT(i + 5), zmm_MT(i + 13), mask);
+ vmovups(ptr[wreg_MT + 5 * 16 * 4], zmm_M(5));
+ vshuff32x4(zmm_M(6), zmm_MT(i + 6), zmm_MT(i + 14), mask);
+ vmovups(ptr[wreg_MT + 6 * 16 * 4], zmm_M(6));
+ vshuff32x4(zmm_M(7), zmm_MT(i + 7), zmm_MT(i + 15), mask);
+ vmovups(ptr[wreg_MT + 7 * 16 * 4], zmm_M(7));
+ mask = 0xdd;
+ vshuff32x4(zmm_M(8), zmm_MT(i), zmm_MT(i + 8), mask);
+ vmovups(ptr[wreg_MT + 8 * 16 * 4], zmm_M(8));
+ vshuff32x4(zmm_M(9), zmm_MT(i + 1), zmm_MT(i + 9), mask);
+ vmovups(ptr[wreg_MT + 9 * 16 * 4], zmm_M(9));
+ vshuff32x4(zmm_M(10), zmm_MT(i + 2), zmm_MT(i + 10), mask);
+ vmovups(ptr[wreg_MT + 10 * 16 * 4], zmm_M(10));
+ vshuff32x4(zmm_M(11), zmm_MT(i + 3), zmm_MT(i + 11), mask);
+ vmovups(ptr[wreg_MT + 11 * 16 * 4], zmm_M(11));
+ vshuff32x4(zmm_M(12), zmm_MT(i + 4), zmm_MT(i + 12), mask);
+ vmovups(ptr[wreg_MT + 12 * 16 * 4], zmm_M(12));
+ vshuff32x4(zmm_M(13), zmm_MT(i + 5), zmm_MT(i + 13), mask);
+ vmovups(ptr[wreg_MT + 13 * 16 * 4], zmm_M(13));
+ vshuff32x4(zmm_M(14), zmm_MT(i + 6), zmm_MT(i + 14), mask);
+ vmovups(ptr[wreg_MT + 14 * 16 * 4], zmm_M(14));
+ vshuff32x4(zmm_M(15), zmm_MT(i + 7), zmm_MT(i + 15), mask);
+ vmovups(ptr[wreg_MT + 15 * 16 * 4], zmm_M(15));
+ }
+ };
+
+ auto load_src = [=]() {
+ mov(wreg_src, ptr[param1 + GET_OFF(src)]);
+ mov(wreg_F, ptr[param1 + GET_OFF(M)]);
+ for (int j = 0; j < kh; j++) {
+ for (int i = 0; i < kw; i++) {
+ if (is_fwd) {
+ for (int v1 = 0; v1 < simd_w; v1++) {
+ int offset_src = (j * kw * simd_w * simd_w
+ + i * simd_w * simd_w + v1 * simd_w) * typesize;
+ int offset_F = (j * kw * simd_w * simd_w
+ + i * simd_w * simd_w + v1 * simd_w) * typesize;
+ vmovups(zmm_temp, ptr[wreg_src + offset_src]);
+ vmovups(ptr[wreg_F + offset_F], zmm_temp);
+ }
+ } else {
+ int offset_src = ((2 - j) * kw * simd_w * simd_w
+ + (2 - i) * simd_w * simd_w) * typesize;
+ int offset_F = (j * kw * simd_w * simd_w
+ + i * simd_w * simd_w) * typesize;
+ lea(wreg_M, ptr[wreg_src + offset_src]);
+ lea(wreg_MT, ptr[wreg_F + offset_F]);
+ trans16x16();
+ }
+ }
+ }
+ };
+
+ auto store_dst = [=]() {
+ mov(wreg_dst, ptr[param1 + GET_OFF(dst)]);
+ mov(wreg_Fw, ptr[param1 + GET_OFF(Mw)]);
+
+ Label Loop_j;
+ mov(wreg_cnt_j, 0);
+ mov(wreg_dst_aux, wreg_dst);
+ mov(wreg_Fw_aux, wreg_Fw);
+
+ int dim5 = jcp.dimK_nb_block * (jcp.dimM_block * jcp.dimM_reg_block)
+ * jcp.dimK_block * simd_w * simd_w;
+
+ L(Loop_j);
+ {
+ for (int i = 0; i < alpha; i++) {
+ // touch pages
+ vmovups(zmm_load(0), ptr[wreg_Fw_aux
+ + (i * simd_w * simd_w) * typesize]);
+ mov(wreg_dst_idx, i * dim5 * typesize);
+ vmovntps(ptr[wreg_dst_aux + wreg_dst_idx], zmm_load(0));
+ }
+ for (int i = 0; i < alpha; i++) {
+ for (int v1 = 1; v1 < simd_w; v1++) {
+ int offset_Fw = (i * simd_w * simd_w + v1 * simd_w)
+ * typesize;
+ vmovups(zmm_load(v1), ptr[wreg_Fw_aux + offset_Fw]);
+ }
+ mov(wreg_dst_idx, i * dim5 * typesize);
+ for (int v1 = 1; v1 < simd_w; v1++) {
+ int offset_dst = v1 * simd_w * typesize;
+ vmovntps(ptr[wreg_dst_aux + wreg_dst_idx + offset_dst],
+ zmm_load(v1));
+ }
+ }
+ add(wreg_Fw_aux, alpha * simd_w * simd_w * typesize);
+ add(wreg_dst_aux, alpha * dim5 * typesize);
+ add(wreg_cnt_j, 1);
+ cmp(wreg_cnt_j, alpha);
+ jl(Loop_j, T_NEAR);
+ }
+ };
+
+ auto trans_W_4x4_3x3 = [=]() {
+ auto fma4 = [=](Zmm dst, Zmm a, Zmm b, Zmm c) {
+ vmovups(dst, a);
+ vfmadd231ps(dst, b, c);
+ };
+ auto fms4 = [=](Zmm dst, Zmm a, Zmm b, Zmm c) {
+ vmulps(zmm_temp, b, c);
+ vsubps(dst, a, zmm_temp);
+ };
+ auto fnms4 = [=](Zmm dst, Zmm a, Zmm b, Zmm c) {
+ vsubps(dst, zmm_zero, a);
+ vfnmadd231ps(dst, b, c);
+ };
+
+ mov(wreg_Fw, ptr[param1 + GET_OFF(Mw)]);
+ mov(wreg_F, ptr[param1 + GET_OFF(M)]);
+ mov(wreg_T, ptr[param1 + GET_OFF(T)]);
+
+ Label Loop_j;
+ mov(wreg_cnt_j, 0);
+ L(Loop_j);
+ mov(wreg_F_aux, wreg_F);
+ mov(wreg_Fw_aux, wreg_Fw);
+ mov(wreg_temp, wreg_cnt_j);
+ shl(wreg_temp, 4 + 2);
+ lea(wreg_F_aux, ptr[wreg_F + wreg_temp]);
+ lea(wreg_Fw_aux, ptr[wreg_Fw + wreg_temp]);
+
+ for (int i = 0; i < 3; i++) {
+ for (int idx = 0; idx < 3; idx ++) {
+ vmovups(zmm_F(idx), ptr[wreg_F_aux + (idx * 3 * simd_w
+ * simd_w + i * simd_w * simd_w) * typesize]);
+ }
+ vmulps(zmm_t(0), zmm_G(0), zmm_F(2));
+ fnms4(zmm_t(1), zmm_t(0), zmm_G(1), zmm_F(0));
+ fma4(zmm_t(2), zmm_t(0), zmm_G(2), zmm_F(0));
+
+ vmulps(zmm_T(0), zmm_G(3), zmm_F(0));
+ fms4(zmm_T(1), zmm_t(1), zmm_G(4), zmm_F(1));
+ fma4(zmm_T(2), zmm_t(1), zmm_G(4), zmm_F(1));
+ fma4(zmm_T(3), zmm_t(2), zmm_G(5), zmm_F(1));
+ fms4(zmm_T(4), zmm_t(2), zmm_G(5), zmm_F(1));
+ vmovaps(zmm_T(5), zmm_F(2));
+
+ for (int idx = 0; idx < 6; idx ++) {
+ vmovups(ptr[wreg_T + (idx * 3 * simd_w + i * simd_w)
+ * typesize], zmm_T(idx));
+ }
+ }
+ for (int i = 0; i < 6; i++) {
+
+ for (int idx = 0; idx < 3; idx ++) {
+ vmovups(zmm_T(idx), ptr[wreg_T
+ + (i * 3 * simd_w + idx * simd_w) * typesize]);
+ }
+ vmulps(zmm_t(0), zmm_G(0), zmm_T(2));
+ fnms4(zmm_t(1), zmm_t(0), zmm_G(1), zmm_T(0));
+ fma4(zmm_t(2), zmm_t(0), zmm_G(2), zmm_T(0));
+
+ vmulps(zmm_F(0), zmm_G(3), zmm_T(0));
+ fms4(zmm_F(1), zmm_t(1), zmm_G(4), zmm_T(1));
+ fma4(zmm_F(2), zmm_t(1), zmm_G(4), zmm_T(1));
+ fma4(zmm_F(3), zmm_t(2), zmm_G(5), zmm_T(1));
+ fms4(zmm_F(4), zmm_t(2), zmm_G(5), zmm_T(1));
+ vmovaps(zmm_F(5), zmm_T(2));
+
+ for (int l = 0; l < 6; l++) {
+ vmovups(ptr[wreg_Fw_aux + (i * 6 * simd_w * simd_w
+ + l * simd_w * simd_w) * typesize], zmm_F(l));
+ }
+ }
+ add(wreg_cnt_j, 1);
+ cmp(wreg_cnt_j, 16);
+ jl(Loop_j, T_NEAR);
+ };
+
+ auto inner_loops = [=]() {
+ load_src();
+ init_G();
+ trans_W_4x4_3x3();
+ store_dst();
+ };
+
+ preamble();
+ inner_loops();
+ postamble();
+}
+
+void _jit_avx512_core_fp32_wino_conv_4x3_data_kernel
+ ::output_transform_data_ker_generate()
+{
+ bool is_fwd = one_of(jcp.prop_kind,
+ mkldnn_forward_training, mkldnn_forward_inference);
+ int outw = is_fwd ? jcp.ow : jcp.iw;
+ int outh = is_fwd ? jcp.oh : jcp.ih;
+ bool not_tiled = jcp.sched_policy == WSCHED_DATA_W_S_G_D;
+ bool with_bias = jcp.with_bias;
+ bool with_relu = jcp.with_eltwise;
+ bool with_relu_postsum = jcp.with_relu_postsum;
+ bool with_sum = jcp.with_sum;
+
+ auto zmm_zero = Xbyak::Zmm(0);
+ auto zmm_temp = Xbyak::Zmm(31);
+ auto zmm_G = [=](int i) {
+ return Xbyak::Zmm(1 + i);
+ };
+ auto zmm_O = [=](int i) {
+ return Xbyak::Zmm(1 + alpha + i);
+ };
+ auto zmm_T = [=](int i) {
+ return Xbyak::Zmm(1 + 2 * alpha + i);
+ };
+ auto zmm_t = [=](int i) {
+ return Xbyak::Zmm(1 + 3 * alpha + i);
+ };
+
+ auto init_G = [=]() {
+ mov(oreg_temp, ptr[param1 + GET_OFF(G)]);
+ for (int i = 0; i < 6; i++) {
+ vbroadcastss(zmm_G(i), ptr[oreg_temp + i * typesize]);
+ }
+ };
+
+ auto load_src = [=]() {
+ mov(oreg_Ow, ptr[param1 + GET_OFF(Mw)]);
+ mov(oreg_src, ptr[param1 + GET_OFF(src)]);
+
+ mov(oreg_nb_tile_block_ur, ptr[param1 + GET_OFF(nb_tile_block_ur)]);
+ imul(oreg_nb_tile_block_ur, oreg_nb_tile_block_ur,
+ (jcp.dimM_block * jcp.dimM_reg_block) * jcp.dimN_reg_block
+ * jcp.dimM_simd_block * typesize);
+ add(oreg_src, oreg_nb_tile_block_ur);
+
+ mov(oreg_tile_block_ur, ptr[param1 + GET_OFF(tile_block_ur)]);
+ imul(oreg_tile_block_ur, oreg_tile_block_ur,
+ jcp.dimM_simd_block * typesize);
+ add(oreg_src, oreg_tile_block_ur);
+
+ if (not_tiled) {
+ mov(oreg_tile_block, ptr[param1 + GET_OFF(tile_block)]);
+ imul(oreg_tile_block, oreg_tile_block,
+ jcp.dimM_nb_block * alpha * alpha * jcp.dimN_block
+ * (jcp.dimM_block * jcp.dimM_reg_block) * jcp.dimN_reg_block
+ * jcp.dimM_simd_block * typesize);
+ add(oreg_src, oreg_tile_block);
+ }
+
+ int last4dim = jcp.dimN_block * (jcp.dimM_block * jcp.dimM_reg_block)
+ * jcp.dimN_reg_block * jcp.dimM_simd_block * typesize;
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ int j_base_offset = j * alpha * last4dim;
+ int i_base_offset = i * last4dim;
+ vmovups(zmm_temp, ptr[oreg_src + j_base_offset + i_base_offset]);
+ vmovups(ptr[oreg_Ow + (j * alpha * simd_w + i * simd_w)
+ * typesize], zmm_temp);
+ }
+ }
+ };
+
+ auto store_dst = [=]() {
+ vpxord(zmm_zero, zmm_zero, zmm_zero);
+ mov(oreg_dst, ptr[param1 + GET_OFF(dst)]);
+ mov(oreg_O, ptr[param1 + GET_OFF(M)]);
+ mov(oreg_ydim, ptr[param1 + GET_OFF(tj)]);
+ shl(oreg_ydim, 2); // tj * tile_size (==4)
+ mov(oreg_xdim, ptr[param1 + GET_OFF(ti)]);
+ shl(oreg_xdim, 2); // ti * tilesize (==4)
+
+ if (with_bias)
+ mov(oreg_bias, ptr[param1 + GET_OFF(bias)]);
+
+ auto store_one = [=](int j, int i, bool is_aligned) {
+ auto zmm_O = Xbyak::Zmm(31);
+ auto zmm_relu_ns = Xbyak::Zmm(30);
+ auto xmm_relu_ns = Xbyak::Xmm(30);
+ int offset = (j * tile_size * simd_w + i * simd_w) * typesize;
+
+ vmovups(zmm_O, ptr[oreg_O + offset]);
+ if (is_fwd) {
+ if (with_bias) {
+ vaddps(zmm_O, zmm_O, ptr[oreg_bias]);
+ }
+ if (with_relu) {
+ if (jcp.eltwise.alpha == 0) {
+ vmaxps(zmm_O, zmm_O, zmm_zero);
+ } else {
+ Opmask kmask = Opmask(7);
+ mov(imm_addr64, float2int(jcp.eltwise.alpha));
+ vmovq(xmm_relu_ns, imm_addr64);
+ vbroadcastss(zmm_relu_ns, xmm_relu_ns);
+ vcmpps(kmask, zmm_O, zmm_zero, _cmp_lt_os);
+ vmulps(zmm_O | kmask, zmm_O, zmm_relu_ns);
+ }
+ }
+ }
+ if (with_sum) {
+ vaddps(zmm_O, zmm_O, ptr[oreg_out_j + oreg_temp]);
+ if (with_relu_postsum) // orig: with_relu_postsum
+ vmaxps(zmm_O, zmm_O, zmm_zero);
+ }
+ if (is_aligned)
+ vmovntps(ptr[oreg_out_j + oreg_temp], zmm_O);
+ else
+ vmovups(ptr[oreg_out_j + oreg_temp], zmm_O);
+ };
+
+ auto i_loop = [=](int j, bool is_aligned) {
+ for (int i = 0; i < tile_size; i++) {
+ Label next;
+ mov(oreg_temp, oreg_xdim);
+ add(oreg_temp, i);
+ cmp(oreg_temp, outw);
+ jge(next, T_NEAR);
+ shl(oreg_temp, 4 + 2); // * 16 * 4
+
+ store_one(j, i, is_aligned);
+
+ L(next);
+ }
+ };
+
+
+ for (int j = 0; j < tile_size; j++) {
+ Label next, unaligned;
+ mov(oreg_temp, oreg_ydim);
+ add(oreg_temp, j);
+ cmp(oreg_temp, outh);
+ jge(next, T_NEAR);
+
+ mov(oreg_out_j, oreg_dst);
+ imul(oreg_temp, oreg_temp, outw * simd_w * typesize);
+ add(oreg_out_j, oreg_temp);
+
+ test(oreg_dst, 63);
+ jnz(unaligned, T_NEAR);
+
+ i_loop(j, true);
+ jmp(next, T_NEAR);
+
+ L(unaligned);
+ i_loop(j, false);
+
+ L(next);
+ }
+ };
+
+ auto trans_O_4x4_3x3 = [=]() {
+ auto fma2 = [=](Zmm dst, Zmm v1, Zmm u1, Zmm v2, Zmm u2){
+ vmulps(dst, v1, u1);
+ vfmadd231ps(dst, v2, u2);
+ };
+ mov(oreg_Ow, ptr[param1 + GET_OFF(Mw)]);
+ mov(oreg_T, ptr[param1 + GET_OFF(T)]);
+ mov(oreg_O, ptr[param1 + GET_OFF(M)]);
+
+ for (int i = 0; i < alpha; i++) {
+ for (int j = 0; j < alpha; j++) {
+ vmovups(zmm_O(j), ptr[oreg_Ow + (j * alpha * simd_w
+ + i * simd_w) * typesize]);
+ }
+
+ vaddps(zmm_t(0), zmm_O(1), zmm_O(2));
+ vaddps(zmm_t(1), zmm_O(3), zmm_O(4));
+ vsubps(zmm_t(2), zmm_O(1), zmm_O(2));
+ vsubps(zmm_t(3), zmm_O(3), zmm_O(4));
+
+ vaddps(zmm_T(0), zmm_t(0), zmm_t(1));
+ vaddps(zmm_T(0), zmm_T(0), zmm_O(0));
+ fma2(zmm_T(1), zmm_t(2), zmm_G(0), zmm_t(3), zmm_G(1));
+ fma2(zmm_T(2), zmm_t(0), zmm_G(2), zmm_t(1), zmm_G(3));
+ fma2(zmm_T(3), zmm_t(2), zmm_G(4), zmm_t(3), zmm_G(5));
+ vaddps(zmm_T(3), zmm_T(3), zmm_O(5));
+
+ for (int j = 0; j < tile_size; j++) {
+ vmovups(ptr[oreg_T + (j * alpha * simd_w
+ + i * simd_w) * typesize], zmm_T(j));
+ }
+ }
+ for (int j = 0; j < tile_size; j++) {
+ for (int i = 0; i < alpha; i++) {
+ vmovups(zmm_T(i), ptr[oreg_T + (j * alpha * simd_w
+ + i * simd_w) * typesize]);
+ }
+ vaddps(zmm_t(0), zmm_T(1), zmm_T(2));
+ vaddps(zmm_t(1), zmm_T(3), zmm_T(4));
+ vsubps(zmm_t(2), zmm_T(1), zmm_T(2));
+ vsubps(zmm_t(3), zmm_T(3), zmm_T(4));
+
+ vaddps(zmm_O(0), zmm_t(0), zmm_t(1));
+ vaddps(zmm_O(0), zmm_O(0), zmm_T(0));
+ fma2(zmm_O(1), zmm_t(2), zmm_G(0), zmm_t(3), zmm_G(1));
+ fma2(zmm_O(2), zmm_t(0), zmm_G(2), zmm_t(1), zmm_G(3));
+ fma2(zmm_O(3), zmm_t(2), zmm_G(4), zmm_t(3), zmm_G(5));
+ vaddps(zmm_O(3), zmm_O(3), zmm_T(5));
+
+ for (int i = 0; i < tile_size; i++) {
+ vmovups(ptr[oreg_O + (j * tile_size * simd_w
+ + i * simd_w) * typesize], zmm_O(i));
+ }
+ }
+ };
+
+ auto inner_loops = [=]() {
+ init_G();
+ load_src();
+ trans_O_4x4_3x3();
+ store_dst();
+ };
+
+ preamble();
+ inner_loops();
+ postamble();
+}
+
+void _jit_avx512_core_fp32_wino_conv_4x3_data_kernel
+ ::input_transform_data_ker_generate()
+{
+ bool is_fwd = one_of(jcp.prop_kind,
+ mkldnn_forward_training, mkldnn_forward_inference);
+ int inpw = is_fwd ? jcp.iw : jcp.ow;
+ int inph = is_fwd ? jcp.ih : jcp.oh;
+ int l_pad = is_fwd ? jcp.l_pad : jcp.iw + jcp.r_pad - jcp.ow;
+ int t_pad = is_fwd ? jcp.t_pad : jcp.ih + jcp.t_pad - jcp.oh;
+ int wp_max = inpw + l_pad;
+ int hp_max = inph + t_pad;
+ bool not_tiled = jcp.sched_policy == WSCHED_DATA_W_S_G_D;
+ int G_size = 9;
+
+ auto zmm_zero = Xbyak::Zmm(0);
+ auto zmm_temp = Xbyak::Zmm(31);
+ auto zmm_G = [=](int i) {
+ return Xbyak::Zmm(1 + i);
+ };
+ auto zmm_I = [=](int i) {
+ return Xbyak::Zmm(1 + G_size + i);
+ };
+ auto zmm_T = [=](int i) {
+ return Xbyak::Zmm(1 + G_size + alpha + i);
+ };
+ auto zmm_t = [=](int i) {
+ return Xbyak::Zmm(1 + G_size + 2 * alpha + i);
+ };
+
+ auto init_G = [=]() {
+ mov(ireg_temp, ptr[param1 + GET_OFF(G)]);
+ for (int i = 0; i < G_size; i++) {
+ vbroadcastss(zmm_G(i), ptr[ireg_temp + i * typesize]);
+ }
+ };
+
+ auto load_src = [=]() {
+ mov(ireg_src, ptr[param1 + GET_OFF(src)]); // base addr of inp
+ mov(ireg_I, ptr[param1 + GET_OFF(M)]);
+
+ xor_(ireg_zero, ireg_zero);
+ vpxord(zmm_zero, zmm_zero, zmm_zero);
+
+ mov(ireg_ydim, ptr[param1 + GET_OFF(tj)]);
+ shl(ireg_ydim, 2); // tj * tile_size (==4)
+ mov(ireg_xdim, ptr[param1 + GET_OFF(ti)]);
+ shl(ireg_xdim, 2); // ti * tilesize (==4)
+
+ for (int j = 0; j < alpha; j++) {
+ mov(ireg_temp, ireg_ydim);
+ add(ireg_temp, j);
+
+ mov(ireg_mask_j, 0xffff);
+ cmp(ireg_temp, t_pad);
+ cmovl(ireg_mask_j, ireg_zero);
+ cmp(ireg_temp, hp_max);
+ cmovge(ireg_mask_j, ireg_zero);
+
+ sub(ireg_temp, t_pad);
+ imul(ireg_temp, ireg_temp, inpw * simd_w * typesize);
+ mov(ireg_inp_j, ireg_src);
+ add(ireg_inp_j, ireg_temp);
+
+ for (int i = 0; i < alpha; i++) {
+
+ mov(ireg_temp, ireg_xdim);
+ add(ireg_temp, i);
+
+ mov(ireg_mask, 0xffff);
+ cmp(ireg_temp, l_pad);
+ cmovl(ireg_mask, ireg_zero);
+ cmp(ireg_temp, wp_max);
+ cmovge(ireg_mask, ireg_zero);
+ and_(ireg_mask, ireg_mask_j);
+
+ sub(ireg_temp, l_pad);
+ shl(ireg_temp, 4 + 2);
+
+ vpxord(zmm_temp, zmm_temp, zmm_temp);
+ Opmask kmask = Opmask(7);
+ kmovw(kmask, ireg_mask_32);
+ vmovups(zmm_temp | kmask, ptr[ireg_inp_j + ireg_temp]);
+ vmovups(ptr[ireg_I + (j * alpha * simd_w + i * simd_w)
+ * typesize], zmm_temp);
+ }
+ }
+ };
+
+ auto store_Iw = [=]() {
+
+ mov(ireg_Iw, ptr[param1 + GET_OFF(Mw)]);
+ mov(ireg_output, ptr[param1 + GET_OFF(dst)]);
+
+ bool streamout
+ = jcp.dimN * jcp.dimK * alpha * alpha * sizeof(float)
+ > 2 * LLC_data_size
+ ? true : false;
+
+ if (not_tiled) {
+ mov(ireg_tile_block, ptr[param1 + GET_OFF(tile_block)]);
+ imul(ireg_tile_block, ireg_tile_block,
+ alpha * alpha * jcp.dimN_block * jcp.dimK_nb_block
+ * jcp.dimK_block * jcp.dimN_reg_block * jcp.dimK_reg_block
+ * typesize);
+ }
+
+ mov(ireg_nb_tile_block_ur, ptr[param1 + GET_OFF(nb_tile_block_ur)]);
+ imul(ireg_nb_tile_block_ur, ireg_nb_tile_block_ur,
+ jcp.dimK_nb_block * jcp.dimK_block * jcp.dimN_reg_block
+ * jcp.dimK_reg_block * typesize);
+
+ mov(ireg_tile_block_ur, ptr[param1 + GET_OFF(tile_block_ur)]);
+ imul(ireg_tile_block_ur, ireg_tile_block_ur,
+ jcp.dimK_reg_block * typesize);
+
+ add(ireg_output, ireg_nb_tile_block_ur);
+ add(ireg_output, ireg_tile_block_ur);
+ if (not_tiled)
+ add(ireg_output, ireg_tile_block);
+
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ vmovups(zmm_temp,ptr[ireg_Iw + (j * alpha * simd_w
+ + i * simd_w) * typesize]);
+
+ int j_base_offset =
+ j * alpha * jcp.dimN_block * jcp.dimK_nb_block
+ * jcp.dimK_block * jcp.dimN_reg_block * jcp.dimK_reg_block
+ * typesize;
+ int i_base_offset =
+ i * jcp.dimN_block * jcp.dimK_nb_block * jcp.dimK_block
+ * jcp.dimN_reg_block * jcp.dimK_reg_block * typesize;
+
+ if (not_tiled && streamout)
+ vmovntps(ptr[ireg_output + j_base_offset + i_base_offset],
+ zmm_temp);
+ else
+ vmovups(ptr[ireg_output + j_base_offset + i_base_offset],
+ zmm_temp);
+ }
+ }
+ };
+
+ auto fma4 = [=](Zmm dst, Zmm a, Zmm b, Zmm c) {
+ vmulps(zmm_temp, a, b);
+ vaddps(dst, zmm_temp, c);
+ };
+
+ auto trans_I_4x4_3x3 = [=]() {
+ mov(ireg_Iw, ptr[param1 + GET_OFF(Mw)]);
+ mov(ireg_T, ptr[param1 + GET_OFF(T)]);
+ mov(ireg_I, ptr[param1 + GET_OFF(M)]);
+
+ mov(ireg_output, ptr[param1 + GET_OFF(dst)]); // for prefetch
+ for (int i = 0; i < alpha; i++) {
+ for (int idx = 0; idx < alpha; idx++) {
+ vmovups(zmm_I(idx), ptr[ireg_I + (idx * alpha * simd_w
+ + i * simd_w) * typesize]);
+ int j_base_offset =
+ i * alpha * jcp.dimN_block * jcp.dimK_nb_block
+ * jcp.dimK_block * jcp.dimN_reg_block * jcp.dimK_reg_block
+ * typesize;
+ int idx_base_offset =
+ idx * jcp.dimN_block * jcp.dimK_nb_block * jcp.dimK_block
+ * jcp.dimN_reg_block * jcp.dimK_reg_block * typesize;
+ prefetcht0(ptr[ireg_output + j_base_offset + idx_base_offset]);
+ }
+
+ fma4(zmm_t(0), zmm_I(2), zmm_G(0), zmm_I(4));
+ fma4(zmm_t(1), zmm_I(1), zmm_G(0), zmm_I(3));
+ fma4(zmm_t(2), zmm_I(2), zmm_G(1), zmm_I(4));
+ fma4(zmm_t(3), zmm_I(1), zmm_G(1), zmm_I(3));
+ fma4(zmm_t(4), zmm_I(0), zmm_G(2), zmm_I(4));
+ fma4(zmm_t(5), zmm_I(1), zmm_G(2), zmm_I(5));
+
+ fma4(zmm_T(0), zmm_I(2), zmm_G(3), zmm_t(4));
+ fma4(zmm_T(1), zmm_t(1), zmm_G(4), zmm_t(0));
+ fma4(zmm_T(2), zmm_t(1), zmm_G(5), zmm_t(0));
+ fma4(zmm_T(3), zmm_t(3), zmm_G(6), zmm_t(2));
+ fma4(zmm_T(4), zmm_t(3), zmm_G(7), zmm_t(2));
+ fma4(zmm_T(5), zmm_I(3), zmm_G(8), zmm_t(5));
+
+ for (int idx = 0; idx < alpha; idx++) {
+ vmovups(ptr[ireg_T + (idx * alpha * simd_w + i * simd_w)
+ * typesize],zmm_T(idx));
+ }
+ }
+ for (int i = 0; i < alpha; i++) {
+ for (int idx = 0; idx < alpha; idx++) {
+ vmovups(zmm_T(idx), ptr[ireg_T + (i * alpha * simd_w + idx
+ * simd_w) * typesize]);
+ }
+
+ fma4(zmm_t(0), zmm_T(2), zmm_G(0), zmm_T(4));
+ fma4(zmm_t(1), zmm_T(1), zmm_G(0), zmm_T(3));
+ fma4(zmm_t(2), zmm_T(2), zmm_G(1), zmm_T(4));
+ fma4(zmm_t(3), zmm_T(1), zmm_G(1), zmm_T(3));
+ fma4(zmm_t(4), zmm_T(0), zmm_G(2), zmm_T(4));
+ fma4(zmm_t(5), zmm_T(1), zmm_G(2), zmm_T(5));
+
+ fma4(zmm_I(0), zmm_T(2), zmm_G(3), zmm_t(4));
+ fma4(zmm_I(1), zmm_t(1), zmm_G(4), zmm_t(0));
+ fma4(zmm_I(2), zmm_t(1), zmm_G(5), zmm_t(0));
+ fma4(zmm_I(3), zmm_t(3), zmm_G(6), zmm_t(2));
+ fma4(zmm_I(4), zmm_t(3), zmm_G(7), zmm_t(2));
+ fma4(zmm_I(5), zmm_T(3), zmm_G(8), zmm_t(5));
+
+ for (int idx = 0; idx < alpha; idx++) {
+ vmovups(ptr[ireg_Iw + (i * alpha * simd_w + idx * simd_w)
+ * typesize],zmm_I(idx));
+ }
+ }
+ };
+
+ auto inner_loops = [=]() {
+ init_G();
+ load_src();
+ trans_I_4x4_3x3();
+ store_Iw();
+ };
+
+ preamble();
+ inner_loops();
+ postamble();
+}
+
+status_t _jit_avx512_core_fp32_wino_conv_4x3_data_kernel::init_conf_common(
+ jit_conv_winograd_conf_t &jcp, const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d, const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d)
+{
+ if (!mayiuse(avx512_core)) {
+ return status::unimplemented;
+ }
+
+ jcp.nthr = mkldnn_get_max_threads();
+
+ jcp.ver = ver_avx512_core;
+ jcp.prop_kind = cd.prop_kind;
+
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+ jcp.ih = src_d.dims()[2];
+ jcp.iw = src_d.dims()[3];
+ jcp.oh = dst_d.dims()[2];
+ jcp.ow = dst_d.dims()[3];
+ jcp.kh = weights_d.dims()[with_groups + 2];
+ jcp.kw = weights_d.dims()[with_groups + 3];
+ jcp.t_pad = cd.padding[0][0];
+ jcp.l_pad = cd.padding[0][1];
+ jcp.stride_h = cd.strides[0];
+ jcp.stride_w = cd.strides[1];
+ jcp.dilate_h = cd.dilates[0];
+ jcp.dilate_w = cd.dilates[1];
+ jcp.r_pad = nstl::max(
+ 0, (jcp.ow - 1) * jcp.stride_w + jcp.kw - jcp.iw - jcp.l_pad);
+ jcp.b_pad = nstl::max(
+ 0, (jcp.oh - 1) * jcp.stride_h + jcp.kh - jcp.ih - jcp.t_pad);
+ jcp.ihp = jcp.ih + jcp.t_pad + jcp.b_pad;
+ jcp.iwp = jcp.iw + jcp.l_pad + jcp.r_pad;
+ jcp.ohp = jcp.oh;
+ jcp.owp = jcp.ow;
+
+ bool ok_to_pad_channels = jcp.ngroups == 1;
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ jcp.ic = rnd_up(jcp.ic, simd_w);
+ }
+
+ // Checking conditions not supported by these kernels
+ if (!IMPLICATION(cd.alg_kind == alg_kind::convolution_auto,
+ is_winograd_faster_than_direct(jcp)))
+ return status::unimplemented;
+
+ if (jcp.ngroups != 1)
+ return status::unimplemented;
+ if ((jcp.kh != 3) || (jcp.kw != 3))
+ return status::unimplemented;
+ if ((jcp.dilate_h != 0) || (jcp.dilate_w != 0))
+ return status::unimplemented;
+ if ((jcp.stride_h != 1) || (jcp.stride_w != 1))
+ return status::unimplemented;
+ if ((jcp.ic % simd_w) != 0 || (jcp.oc % simd_w) != 0)
+ return status::unimplemented;
+
+ format_tag_t dat_tag = nChw16c;
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ jcp.dst_tag = dst_d.matches_one_of_tag(dat_tag);
+
+ if (jcp.src_tag != dat_tag) return status::unimplemented;
+ if (jcp.dst_tag != dat_tag) return status::unimplemented;
+
+ if (!one_of(weights_d.format_kind(), format_kind::any, format_kind::wino)) {
+ format_tag_t wei_tag = with_groups ? gOIhw16i16o : OIhw16i16o;
+ jcp.wei_tag = weights_d.matches_one_of_tag(wei_tag);
+ if (jcp.wei_tag != wei_tag)
+ return status::unimplemented;
+ }
+
+ bool layout_consistency = true
+ && jcp.ic <= src_d.padded_dims()[1]
+ && jcp.oc <= dst_d.padded_dims()[1]
+ && (one_of(weights_d.format_kind(),
+ format_kind::any, format_kind::wino)
+ || (jcp.ic <= weights_d.padded_dims()[with_groups + 1]
+ && jcp.oc <= weights_d.padded_dims()[with_groups + 0]));
+ if (!layout_consistency)
+ return status::unimplemented;
+
+ return status::success;
+}
+
+void set_kernel_dims_reg_block(jit_conv_winograd_conf_t &jcp) {
+
+ /* ----------- dimM reg block ---------------------*/
+ auto test_cond_dimM_reg_block = [](jit_conv_winograd_conf_t &jcp,
+ int dimM_reg_block, int current_best) {
+ int max_dimM_reg_block = jcp.kernel_kind == embd_bcast ? 1 : 4;
+ return (dimM_reg_block >= 1)
+ && (dimM_reg_block <= max_dimM_reg_block )
+ && (dimM_reg_block > current_best);
+ };
+ jcp.dimM_reg_block = get_divisor_satisfying_cond(jcp,
+ jcp.dimM/jcp.dimM_simd_block, 1, test_cond_dimM_reg_block);
+
+ /* ----------- dimN reg block ---------------------*/
+
+ auto test_cond_dimN_reg_block = [](jit_conv_winograd_conf_t &jcp,
+ int dimN_reg_block, int current_best) {
+ return jcp.kernel_kind == embd_bcast
+ ? dimN_reg_block < jcp.nb_reg && dimN_reg_block > current_best
+ : dimN_reg_block >= 1
+ && (dimN_reg_block * jcp.dimM_reg_block + dimN_reg_block)
+ < jcp.nb_reg
+ && dimN_reg_block > current_best;
+ };
+ jcp.dimN_reg_block = get_divisor_satisfying_cond(jcp,
+ jcp.dimN, 1, test_cond_dimN_reg_block);
+}
+
+status_t set_wsched_DATA_W_SGD_avx512_core(jit_conv_winograd_conf_t &jcp) {
+ if (jcp.ver != ver_avx512_core)
+ return status::unimplemented;
+
+ jcp.kernel_kind = embd_bcast;
+
+ set_kernel_dims_reg_block(jcp);
+
+ /*-------------- L2 blocking for dimN block ---------*/
+
+ auto test_cond_dimN_block = [](jit_conv_winograd_conf_t &jcp,
+ int dimN_block, int current_best) {
+ return check_L2_block_per_thread(jcp, dimN_block, 0.1, 2.0)
+ && (dimN_block > current_best)
+ && ((jcp.dimN / dimN_block / jcp.dimN_reg_block)
+ >= 1.5 * mkldnn_get_max_threads());
+ };
+
+ jcp.dimN_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimN / jcp.dimN_reg_block, 1, test_cond_dimN_block);
+ jcp.dimN_nb_block = jcp.dimN / jcp.dimN_block / jcp.dimN_reg_block;
+
+ if (check_L2_block_per_thread(jcp, jcp.dimN_block, 0.1, 3.2)
+ && (jcp.dimN_nb_block >= 1.5 * mkldnn_get_max_threads())) {
+
+ /* ------------------- L1 blocking for GEMM --------------*/
+ /* -------------------- Choose dimK block ----------------*/
+
+ auto test_cond_dimK_block = [](jit_conv_winograd_conf_t &jcp,
+ int dimK_block, int current_best) {
+ return check_L1_block_gemm(jcp, dimK_block, 1, 0.1, 0.5)
+ && (dimK_block > current_best);
+ };
+
+ jcp.dimK_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimK / jcp.dimK_reg_block, 1, test_cond_dimK_block);
+
+ if (check_L1_block_gemm(jcp, jcp.dimK_block, 1, 0.1, 1.0)) {
+ jcp.dimK_nb_block = jcp.dimK / jcp.dimK_block / jcp.dimK_reg_block;
+
+ /* -------------- Choose dimM block -------------------*/
+ auto test_cond_dimM_block = [](jit_conv_winograd_conf_t &jcp,
+ int dimM_block, int current_best) {
+ return check_L1_block_gemm(jcp, jcp.dimK_block, dimM_block,
+ 0.2, 0.5) && (dimM_block > current_best);
+ };
+
+ jcp.dimM_block = get_divisor_satisfying_cond(jcp,
+ jcp.dimM / (jcp.dimM_simd_block * jcp.dimM_reg_block), 1,
+ test_cond_dimM_block);
+ jcp.dimM_nb_block = jcp.dimM / jcp.dimM_block / jcp.dimM_reg_block
+ / jcp.dimM_simd_block;
+
+ jcp.sched_policy = WSCHED_DATA_W_SGD;
+ return status::success;
+ }
+
+ }
+ return status::unimplemented;
+}
+
+void set_kernel_blocking_DATA_W_S_G_D(jit_conv_winograd_conf_t &jcp) {
+
+ set_kernel_dims_reg_block(jcp);
+
+ //********************* Choosing dimK_block **********************//
+ auto test_cond1_dimK_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimK_block, int current_best) {
+ return check_cond1(jcp.dimN_reg_block, dimK_block, jcp.dimK_reg_block,
+ 1, jcp.dimM_reg_block, jcp.dimM_simd_block, .75f)
+ && (dimK_block > current_best);
+ };
+
+ auto test_cond1_bis_dimK_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimK_block, int current_best) {
+ return check_cond1_bis(jcp.dimN_reg_block, dimK_block,
+ jcp.dimK_reg_block, 1, jcp.dimM_reg_block,
+ jcp.dimM_simd_block, .9f)
+ && (dimK_block > current_best);
+ };
+
+ jcp.dimK_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimK / jcp.dimK_reg_block, 1, test_cond1_bis_dimK_block);
+ // If we are not able to use streams, we fall back to condition [1]
+ if (jcp.dimK_block < jcp.dimK / jcp.dimK_reg_block)
+ jcp.dimK_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimK / jcp.dimK_reg_block, 1, test_cond1_dimK_block);
+ jcp.dimK_nb_block = (jcp.dimK / jcp.dimK_reg_block) / jcp.dimK_block;
+
+ //********************* Choosing dimM_block **********************//
+ auto test_cond1_dimM_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimM_block, int current_best) {
+ return check_cond1(jcp.dimN_reg_block, jcp.dimK_block,
+ jcp.dimK_reg_block, dimM_block, jcp.dimM_reg_block,
+ jcp.dimM_simd_block, .5f)
+ && (dimM_block > current_best);
+ };
+
+ auto test_cond1_bis_dimM_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimM_block, int current_best) {
+ return check_cond1_bis(jcp.dimN_reg_block, jcp.dimK_block,
+ jcp.dimK_reg_block, dimM_block, jcp.dimM_reg_block,
+ jcp.dimM_simd_block, .3f)
+ && (dimM_block > current_best);
+ };
+
+ if (jcp.dimK_block < jcp.dimK / jcp.dimK_reg_block)
+ jcp.dimM_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimM / (jcp.dimM_simd_block*jcp.dimM_reg_block), 1,
+ test_cond1_dimM_block);
+ else
+ jcp.dimM_block = get_divisor_satisfying_cond(jcp,
+ jcp.dimM / (jcp.dimM_simd_block*jcp.dimM_reg_block), 1,
+ test_cond1_bis_dimM_block);
+ jcp.dimM_nb_block = jcp.dimM / (jcp.dimM_simd_block * jcp.dimM_block
+ * jcp.dimM_reg_block);
+
+ //******************* Choosing dimN_block *******************//
+ auto test_cond2_dimN_block = [](
+ jit_conv_winograd_conf_t &jcp, int dimN_block, int current_best) {
+ return check_cond2(dimN_block, jcp.dimN_reg_block, jcp.dimK_nb_block,
+ jcp.dimK_block, jcp.dimK_reg_block, jcp.dimM_block,
+ jcp.dimM_reg_block, jcp.dimM_simd_block, .9f)
+ && (dimN_block > current_best);
+ };
+
+ jcp.dimN_block = get_divisor_satisfying_cond(
+ jcp, jcp.dimN / jcp.dimN_reg_block, 1, test_cond2_dimN_block);
+ jcp.dimN_nb_block = jcp.dimN / (jcp.dimN_reg_block * jcp.dimN_block);
+}
+
+status_t set_wsched_DATA_W_S_G_D_avx512_core(jit_conv_winograd_conf_t &jcp) {
+
+ jcp.kernel_kind = expl_bcast;
+ set_kernel_blocking_DATA_W_S_G_D(jcp);
+ if (!(check_kernel_cond(jcp.dimM_block, jcp.dimM_reg_block,
+ jcp.dimM_simd_block, jcp.dimN_block, jcp.dimN_reg_block, jcp.dimK,
+ .1f, .35f))) {
+ jcp.kernel_kind = embd_bcast;
+ set_kernel_blocking_DATA_W_S_G_D(jcp);
+ }
+ jcp.sched_policy = WSCHED_DATA_W_S_G_D;
+ return status::success;
+}
+
+status_t _jit_avx512_core_fp32_wino_conv_4x3_data_kernel::init_conf_kernel(
+ jit_conv_winograd_conf_t &jcp, int dimM, int dimN, int dimK)
+{
+ jcp.nb_reg = 32;
+ jcp.dimN = dimN;
+ jcp.dimK = dimK;
+ jcp.dimM = dimM;
+ jcp.sched_policy = WSCHED_INVALID;
+
+ jcp.dimK_reg_block = 16;
+ jcp.dimM_simd_block = 16;
+
+ if (jcp.kernel_kind == embd_bcast) {
+ jcp.dimM_reg_block = 1;
+ }
+
+ if (!(set_wsched_DATA_W_SGD_avx512_core(jcp) == status::success))
+ set_wsched_DATA_W_S_G_D_avx512_core(jcp);
+
+ assert(jcp.sched_policy != WSCHED_INVALID);
+ return status::success;
+}
+
+bool jit_avx512_core_fp32_wino_conv_4x3_fwd_kernel::post_ops_ok(
+ jit_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ const auto &p = attr.post_ops_;
+
+ auto is_relu = [&](int idx) { return p.entry_[idx].is_relu(); };
+ auto is_sum = [&](int idx) { return p.entry_[idx].is_sum(); };
+
+ switch (p.len_) {
+ case 0: return true; // no post_ops
+ case 1: return is_relu(0) || is_sum(0); // relu or sum
+ case 2: return (is_sum(0) && is_relu(1))
+ || (is_relu(0) && is_sum(1)); // sum->relu or relu->sum
+ case 3: return is_relu(0) && is_sum(1) && is_relu(2); // relu->sum->relu
+ default: return false;
+ }
+
+ return false;
+}
+
+status_t jit_avx512_core_fp32_wino_conv_4x3_fwd_kernel::init_conf(
+ jit_conv_winograd_conf_t &jcp, const convolution_desc_t &cd,
+ const memory_desc_t &src_md, memory_desc_t &weights_md,
+ const memory_desc_t &dst_md, const primitive_attr_t &attr) {
+
+ status_t st = init_conf_common(jcp, cd, src_md, weights_md, dst_md);
+
+ if (st != status::success)
+ return st;
+
+ // Winograd specific initialization
+ jcp.itiles = (jcp.ow + tile_size - 1) / tile_size;
+ jcp.jtiles = (jcp.oh + tile_size - 1) / tile_size;
+ jcp.ntiles = jcp.mb * jcp.itiles * jcp.jtiles;
+
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ const int eltwise_ind = p.find(primitive_kind::eltwise, 0, 1);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise)
+ jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+
+ jcp.with_sum = p.find(primitive_kind::sum, 0) != -1;
+ jcp.with_relu_postsum = p.find(primitive_kind::eltwise, 1) != -1;
+
+ status_t res = init_conf_kernel(jcp, jcp.oc, jcp.ntiles, jcp.ic);
+
+ jcp.ic_simd_block = jcp.dimK_reg_block;
+ jcp.ic_block = jcp.dimK_block;
+ jcp.nb_ic = jcp.dimK_nb_block;
+ jcp.oc_simd_block = jcp.dimM_simd_block;
+ jcp.oc_block = jcp.dimM_block;
+ jcp.oc_reg_block = jcp.dimM_reg_block;
+ jcp.ic_reg_block = 1;
+ jcp.nb_oc = jcp.dimM_nb_block;
+ jcp.tile_block_ur = jcp.dimN_reg_block;
+ jcp.nb_tile_block_ur = jcp.dimN_block;
+ jcp.tile_block = jcp.dimN_nb_block;
+
+ /* re-create weights primitive descriptor
+ and set weights wino_blocking */
+ if (cd.prop_kind == mkldnn_forward_inference) {
+ memory_desc_t expect_wei_md = weights_md;
+
+ expect_wei_md.format_kind = format_kind::wino;
+ expect_wei_md.data_type = data_type::f32;
+ mkldnn_wino_desc_t &wd = expect_wei_md.format_desc.wino_desc;
+ wd.wino_format = mkldnn_wino_wei_OBaaIBOIio;
+ wd.r = 3;
+ wd.alpha = 6;
+
+ wd.ic = jcp.ic;
+ wd.oc = jcp.oc;
+ wd.ic_block = jcp.dimK_reg_block;
+ wd.oc_block = jcp.dimM_simd_block;
+ wd.ic2_block = jcp.dimK_block;
+ wd.oc2_block = jcp.dimM_block * jcp.dimM_reg_block;
+ size_t max_size = sizeof(float) * wd.alpha * wd.alpha * jcp.ic * jcp.oc;
+ wd.size = max_size;
+ wd.adj_scale = 1.f;
+
+ if (weights_md.format_kind == format_kind::any)
+ weights_md = expect_wei_md;
+ if (weights_md != expect_wei_md)
+ return status::unimplemented;
+ }
+
+ return res;
+}
+
+status_t jit_avx512_core_fp32_wino_conv_4x3_bwd_data_kernel::init_conf(
+ jit_conv_winograd_conf_t &jcp, const convolution_desc_t &cd,
+ const memory_desc_wrapper &diff_src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &diff_dst_d)
+{
+ status_t st = init_conf_common(jcp, cd, diff_src_d, weights_d, diff_dst_d);
+
+ if (st != status::success)
+ return st;
+
+ jcp.itiles = (jcp.iw + tile_size - 1) / tile_size;
+ jcp.jtiles = (jcp.ih + tile_size - 1) / tile_size;
+ jcp.ntiles = jcp.mb * jcp.itiles * jcp.jtiles;
+
+ status_t res = init_conf_kernel(jcp, jcp.ic, jcp.ntiles, jcp.oc);
+
+ jcp.oc_simd_block = jcp.dimK_reg_block;
+ jcp.oc_block = jcp.dimK_block;
+ jcp.nb_oc = jcp.dimK_nb_block;
+ jcp.ic_simd_block = jcp.dimM_simd_block;
+ jcp.ic_block = jcp.dimM_block;
+ jcp.ic_reg_block = jcp.dimM_reg_block;
+ jcp.oc_reg_block = 1;
+ jcp.nb_ic = jcp.dimM_nb_block;
+ jcp.tile_block_ur = jcp.dimN_reg_block;
+ jcp.nb_tile_block_ur = jcp.dimN_block;
+ jcp.tile_block = jcp.dimN_nb_block;
+
+ return res;
+}
+
+void jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_kernel::
+src_transform_generate() {
+ constexpr int G_size = 9;
+ const size_t ifwp = jcp.iw + jcp.l_pad;
+ const size_t ifhp = jcp.ih + jcp.t_pad;
+
+ auto zmm_G = [=](int i) {
+ return Xbyak::Zmm(i);
+ };
+ auto zmm_I = [=](int i) {
+ return Xbyak::Zmm(G_size + i);
+ };
+ auto zmm_T = [=](int i) {
+ return Xbyak::Zmm(G_size + alpha + i);
+ };
+ auto zmm_t = [=](int i) {
+ return Xbyak::Zmm(G_size + 2 * alpha + i);
+ };
+
+ auto init_G = [=]() {
+ mov(reg_G, ptr[reg_transp + GET_OFF(G)]);
+ for (int i = 0; i < G_size; i++) {
+ vbroadcastss(zmm_G(i), ptr[reg_G + i * typesize]);
+ }
+ };
+
+ auto load_src = [=]() {
+ mov(reg_I, ptr[reg_transp + GET_OFF(M)]);
+ xor_(reg_zero, reg_zero);
+
+ mov(reg_ydim, reg_tj);
+ shl(reg_ydim, 2); //tj * tile_size(=4)
+
+ for (int j = 0; j < alpha; j++) {
+ /* check if tile index is within physical spatial boundaries*/
+ mov(reg_maskj, 0xffff);
+ cmp(reg_ydim, jcp.t_pad);
+ cmovl(reg_maskj, reg_zero);
+ cmp(reg_ydim, ifhp);
+ cmovge(reg_maskj, reg_zero);
+
+ /*address offset for tile in src*/
+ mov(reg_src_offset, reg_ydim);
+ sub(reg_src_offset, jcp.t_pad); // tj*tile_size - t_pad
+ imul(reg_src_offset, reg_src_offset, jcp.iw);
+
+ mov(reg_xdim, reg_ti);
+ shl(reg_xdim, 2); // xdim = ti * tile_size
+
+ add(reg_src_offset, reg_xdim);
+ sub(reg_src_offset, jcp.l_pad);
+ imul(reg_src_offset, reg_src_offset, simd_w * typesize);
+ for (int i = 0; i < alpha; i++) {
+ /* check if tile index is within physical spatial boundaries*/
+ mov(reg_maski, 0xffff);
+ cmp(reg_xdim, jcp.l_pad);
+ cmovl(reg_maski, reg_zero);
+ cmp(reg_xdim, ifwp);
+ cmovge(reg_maski, reg_zero);
+ and_(reg_maski, reg_maskj);
+
+ Opmask kmask_src = Xbyak::Opmask(7);
+ auto zmm_src = Xbyak::Zmm(31);
+ kmovw(kmask_src, reg_maski_32);
+ vpxord(zmm_src, zmm_src, zmm_src);
+ vmovups(zmm_src | kmask_src, ptr[reg_src + reg_src_offset]);
+ vmovups(ptr[reg_I], zmm_src);
+
+ add(reg_xdim, 1); //xdim = ti * tile_size + i
+ add(reg_src_offset, simd_w * typesize);
+ add(reg_I, simd_w * typesize);
+ }
+ add(reg_ydim, 1);
+ }
+ };
+
+ auto fma4 = [=](Xbyak::Zmm dst, Xbyak::Zmm a, Xbyak::Zmm b, Xbyak::Zmm c) {
+ vmovups(dst, c);
+ vfmadd231ps(dst, a, b);
+ };
+
+ auto trans_I_3x3_4x4 = [=]() {
+ //Use 24 registers
+ mov(reg_I, ptr[reg_transp + GET_OFF(M)]);
+ mov(reg_T, ptr[reg_transp + GET_OFF(T)]);
+ for (int i = 0; i < alpha; i++) {
+ for (int j = 0; j < alpha; j++) {
+ size_t I_off = (j * alpha + i) * simd_w * typesize;
+ vmovups(zmm_I(j), ptr[reg_I + I_off]);
+ }
+
+ fma4(zmm_t(0), zmm_I(2), zmm_G(0), zmm_I(4));
+ fma4(zmm_t(1), zmm_I(1), zmm_G(0), zmm_I(3));
+ fma4(zmm_t(2), zmm_I(2), zmm_G(1), zmm_I(4));
+ fma4(zmm_t(3), zmm_I(1), zmm_G(1), zmm_I(3));
+ fma4(zmm_t(4), zmm_I(0), zmm_G(2), zmm_I(4));
+ fma4(zmm_t(5), zmm_I(1), zmm_G(2), zmm_I(5));
+
+ fma4(zmm_T(0), zmm_I(2), zmm_G(3), zmm_t(4));
+ fma4(zmm_T(1), zmm_t(1), zmm_G(4), zmm_t(0));
+ fma4(zmm_T(2), zmm_t(1), zmm_G(5), zmm_t(0));
+ fma4(zmm_T(3), zmm_t(3), zmm_G(6), zmm_t(2));
+ fma4(zmm_T(4), zmm_t(3), zmm_G(7), zmm_t(2));
+ fma4(zmm_T(5), zmm_I(3), zmm_G(8), zmm_t(5));
+
+ for (int j = 0; j < alpha; j++) {
+ vmovups(ptr[reg_T + (j * alpha + i) * simd_w * typesize],
+ zmm_T(j));
+ }
+
+ }
+
+ for (int j = 0; j < alpha; j++) {
+ for (int i = 0; i < alpha; i++) {
+ vmovups(zmm_T(i), ptr[reg_T + (j * alpha + i) * simd_w * typesize]);
+ }
+
+ fma4(zmm_t(0), zmm_T(2), zmm_G(0), zmm_T(4));
+ fma4(zmm_t(1), zmm_T(1), zmm_G(0), zmm_T(3));
+ fma4(zmm_t(2), zmm_T(2), zmm_G(1), zmm_T(4));
+ fma4(zmm_t(3), zmm_T(1), zmm_G(1), zmm_T(3));
+ fma4(zmm_t(4), zmm_T(0), zmm_G(2), zmm_T(4));
+ fma4(zmm_t(5), zmm_T(1), zmm_G(2), zmm_T(5));
+
+ fma4(zmm_I(0), zmm_T(2), zmm_G(3), zmm_t(4));
+ fma4(zmm_I(1), zmm_t(1), zmm_G(4), zmm_t(0));
+ fma4(zmm_I(2), zmm_t(1), zmm_G(5), zmm_t(0));
+ fma4(zmm_I(3), zmm_t(3), zmm_G(6), zmm_t(2));
+ fma4(zmm_I(4), zmm_t(3), zmm_G(7), zmm_t(2));
+ fma4(zmm_I(5), zmm_T(3), zmm_G(8), zmm_t(5));
+
+ for (int i = 0; i < alpha; i++) {
+ size_t dst_off = (j * alpha * jcp.ic_block
+ * jcp.nb_tile_block_ur * jcp.tile_block_ur
+ + i * jcp.ic_block * jcp.nb_tile_block_ur * jcp.tile_block_ur)
+ * simd_w * typesize;
+ vmovups(ptr[reg_dst + dst_off], zmm_I(i));
+ }
+ }
+ };
+
+ auto compute_transform_SDGtWo = [=]() {
+ mov(reg_ti, ptr[reg_transp + GET_OFF(ti)]);
+ mov(reg_tj, ptr[reg_transp + GET_OFF(tj)]);
+ mov(reg_src, ptr[reg_transp + GET_OFF(src)]);
+ mov(reg_dst, ptr[reg_transp + GET_OFF(dst)]);
+ xor_(reg_tile_count, reg_tile_count);
+ Label loop_mb, loop_jtiles, loop_itiles, done;
+ L(loop_mb);
+ {
+ L(loop_jtiles);
+ {
+ L(loop_itiles);
+ {
+ load_src();
+
+ trans_I_3x3_4x4();
+
+ add(reg_tile_count, 1);
+ cmp(reg_tile_count, jcp.nb_tile_block_ur * jcp.tile_block_ur);
+ jge(done);
+
+ add(reg_dst, simd_w * typesize);
+ add(reg_ti, 1);
+ cmp(reg_ti, jcp.itiles);
+ jl(loop_itiles);
+ }
+ xor_(reg_ti, reg_ti);
+ add(reg_tj, 1);
+ cmp(reg_tj, jcp.jtiles);
+ jl(loop_jtiles);
+ }
+ xor_(reg_tj, reg_tj);
+ add(reg_src, jcp.ic * jcp.iw * jcp.ih * typesize);
+ jmp(loop_mb);
+ }
+ L(done);
+ };
+
+ auto compute_transform = [=]() {
+ mov(reg_src, ptr[reg_transp + GET_OFF(src)]);
+ xor_(reg_ti, reg_ti);
+ xor_(reg_tj, reg_tj);
+
+ mov(reg_dst, ptr[reg_transp + GET_OFF(dst)]);
+ mov(reg_tile_count, ptr[reg_transp + GET_OFF(tile_count)]);
+ imul(reg_temp, reg_tile_count, simd_w * typesize);
+ add(reg_dst, reg_temp);
+
+ Label loop_jtiles, loop_itiles, next_tile_block, next_tile;
+ L(loop_jtiles);
+
+ {
+ L(loop_itiles);
+ {
+ load_src();
+
+ trans_I_3x3_4x4();
+
+ add(reg_tile_count, 1);
+ cmp(reg_tile_count, jcp.nb_tile_block_ur * jcp.tile_block_ur);
+ jge(next_tile_block);
+ add(reg_dst, simd_w * typesize);
+ jmp(next_tile);
+
+ L(next_tile_block);
+ sub(reg_dst, (jcp.nb_tile_block_ur * jcp.tile_block_ur - 1)
+ * simd_w * typesize);
+ size_t tblk_off = alpha * alpha * jcp.ic_block
+ * jcp.nb_tile_block_ur * jcp.tile_block_ur
+ * simd_w * typesize;
+ add(reg_dst, tblk_off);
+ xor_(reg_tile_count, reg_tile_count);
+
+ L(next_tile);
+ add(reg_ti, 1);
+ cmp(reg_ti, jcp.itiles);
+ jl(loop_itiles);
+ }
+ xor_(reg_ti, reg_ti);
+ add(reg_tj, 1);
+ cmp(reg_tj, jcp.jtiles);
+ jl(loop_jtiles);
+ }
+ };
+
+ preamble();
+ init_G();
+ if (jcp.sched_policy == WSCHED_WEI_SDGtWo)
+ compute_transform_SDGtWo();
+ else
+ compute_transform();
+ postamble();
+}
+
+void jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_kernel::
+diff_dst_transform_generate(bool with_bias) {
+
+ constexpr int G_size = 8;
+ auto zmm_G = [](int i) {
+ return Xbyak::Zmm(31);
+ };
+
+ auto zmm_src = [=](int j, int i) {
+ return Xbyak::Zmm(G_size + j * 4 + i);
+ };
+
+ auto zmm_bias = Xbyak::Zmm(31);
+
+ auto load_src = [=]() {
+ if (with_bias) vmovups(zmm_bias, ptr[reg_bias]);
+ mov(reg_ydim, reg_tj);
+ shl(reg_ydim, 2); //tj * tile_size(=4)
+ for (int j = 0; j < tile_size; j++) {
+ /* check if tile index is within physical spatial boundaries*/
+ mov(reg_maskj, 0xffff);
+ cmp(reg_ydim, jcp.oh);
+ cmovge(reg_maskj, reg_zero);
+
+ /*address offset for tile in src*/
+ mov(reg_src_offset, reg_ydim);
+ imul(reg_src_offset, reg_src_offset, jcp.ow);
+
+ mov(reg_xdim, reg_ti);
+ shl(reg_xdim, 2); // xdim = ti * tile_size
+
+ add(reg_src_offset, reg_xdim);
+ imul(reg_src_offset, reg_src_offset, simd_w * typesize);
+ for (int i = 0; i < tile_size; i++) {
+ /* check if tile index is within physical spatial boundaries*/
+ mov(reg_maski, 0xffff);
+ cmp(reg_xdim, jcp.ow);
+ cmovge(reg_maski, reg_zero);
+ and_(reg_maski, reg_maskj);
+
+ Opmask kmask_src = Xbyak::Opmask(7);
+ kmovw(kmask_src, reg_maski_32);
+ vpxord(zmm_src(j, i), zmm_src(j, i), zmm_src(j, i));
+ vmovups(zmm_src(j, i) | kmask_src, ptr[reg_src + reg_src_offset]);
+ if (with_bias) vaddps(zmm_bias | kmask_src, zmm_bias,
+ ptr[reg_src + reg_src_offset]);
+
+ add(reg_xdim, 1); //xdim = ti * tile_size + i
+ add(reg_src_offset, simd_w * typesize);
+ }
+ add(reg_ydim, 1);
+ }
+ if(with_bias) vmovups(ptr[reg_bias], zmm_bias);
+ };
+
+ auto zmm_t = [=](int i) {
+ return Xbyak::Zmm(G_size + 16 + i);
+ };
+
+ auto zmm_T = [=](int j, int i) {
+ return Xbyak::Zmm(j * 4 + i);
+ };
+
+ auto movps = [=](Xbyak::Reg64 reg_dst, size_t dst_off, Xbyak::Zmm a) {
+ if (jcp.sched_policy == WSCHED_WEI_SDGtWo)
+ vmovups(ptr[reg_dst + dst_off], a);
+ else
+ vmovntps(ptr[reg_dst + dst_off], a);
+ };
+
+ auto trans_W_3x3_4x4 = [=]() {
+ mov(reg_G, ptr[reg_transp + GET_OFF(G)]);
+ for (int i = 0; i < tile_size; i++) {
+ vbroadcastss(zmm_G(0), ptr[reg_G]);
+ vmulps(zmm_t(0), zmm_src(2, i), zmm_G(0));
+
+ vbroadcastss(zmm_G(1), ptr[reg_G + typesize]);
+ vmovups(zmm_t(1), zmm_t(0));
+ vfmsub231ps(zmm_t(1), zmm_src(0, i), zmm_G(1));
+
+ vbroadcastss(zmm_G(2), ptr[reg_G + 2 * typesize]);
+ vmovups(zmm_t(2), zmm_t(0));
+ vfmadd231ps(zmm_t(2), zmm_src(0, i), zmm_G(2));
+
+ vbroadcastss(zmm_G(3), ptr[reg_G + 3 * typesize]);
+ vmulps(zmm_t(3), zmm_src(1, i), zmm_G(3));
+
+ vbroadcastss(zmm_G(4), ptr[reg_G + 4 * typesize]);
+ vfmadd231ps(zmm_t(3), zmm_src(3, i), zmm_G(4));
+
+ vbroadcastss(zmm_G(5), ptr[reg_G + 5 * typesize]);
+ vmulps(zmm_t(4), zmm_src(1, i), zmm_G(5));
+
+ vbroadcastss(zmm_G(6), ptr[reg_G + 6 * typesize]);
+ vfmadd231ps(zmm_t(4), zmm_src(3, i), zmm_G(6));
+
+ vbroadcastss(zmm_G(7), ptr[reg_G + 7 * typesize]);
+ vmulps(zmm_T(0, i), zmm_src(0, i), zmm_G(7));
+ vsubps(zmm_T(1, i), zmm_t(1), zmm_t(3));
+ vaddps(zmm_T(2, i), zmm_t(1), zmm_t(3));
+ vaddps(zmm_T(3, i), zmm_t(2), zmm_t(4));
+ vsubps(zmm_T(4, i), zmm_t(2), zmm_t(4));
+ vmovups(zmm_T(5, i), zmm_src(3, i));
+ }
+
+ for (int j = 0; j < alpha; j++) {
+ vbroadcastss(zmm_G(0), ptr[reg_G]);
+ vmulps(zmm_t(0), zmm_T(j, 2), zmm_G(0));
+
+ vbroadcastss(zmm_G(1), ptr[reg_G + typesize]);
+ vmovups(zmm_t(1), zmm_t(0));
+ vfmsub231ps(zmm_t(1), zmm_T(j, 0), zmm_G(1));
+
+ vbroadcastss(zmm_G(2), ptr[reg_G + 2 * typesize]);
+ vmovups(zmm_t(2), zmm_t(0));
+ vfmadd231ps(zmm_t(2), zmm_T(j, 0), zmm_G(2));
+
+ vbroadcastss(zmm_G(3), ptr[reg_G + 3 * typesize]);
+ vmulps(zmm_t(3), zmm_T(j, 1), zmm_G(3));
+
+ vbroadcastss(zmm_G(4), ptr[reg_G + 4 * typesize]);
+ vfmadd231ps(zmm_t(3), zmm_T(j, 3), zmm_G(4));
+
+ vbroadcastss(zmm_G(5), ptr[reg_G + 5 * typesize]);
+ vmulps(zmm_t(4), zmm_T(j, 1), zmm_G(5));
+
+ vbroadcastss(zmm_G(6), ptr[reg_G + 6 * typesize]);
+ vfmadd231ps(zmm_t(4), zmm_T(j, 3), zmm_G(6));
+
+ vbroadcastss(zmm_G(7), ptr[reg_G + 7 * typesize]);
+ vmulps(zmm_t(0), zmm_T(j, 0), zmm_G(7));
+ vsubps(zmm_t(5), zmm_t(1), zmm_t(3));
+ vaddps(zmm_t(1), zmm_t(1), zmm_t(3));
+ vaddps(zmm_t(6), zmm_t(2), zmm_t(4));
+ vsubps(zmm_t(2), zmm_t(2), zmm_t(4));
+ vmovups(zmm_t(3), zmm_T(j, 3));
+
+ int alpha_offset = (jcp.oc / jcp.nb_oc)
+ * (jcp.ntiles / jcp.tile_block) * typesize;
+ int dst_off = j * alpha * alpha_offset;
+ movps(reg_dst, dst_off, zmm_t(0));
+ dst_off += alpha_offset;
+ movps(reg_dst, dst_off, zmm_t(5));
+ dst_off += alpha_offset;
+ movps(reg_dst, dst_off, zmm_t(1));
+ dst_off += alpha_offset;
+ movps(reg_dst, dst_off, zmm_t(6));
+ dst_off += alpha_offset;
+ movps(reg_dst, dst_off, zmm_t(2));
+ dst_off += alpha_offset;
+ movps(reg_dst, dst_off, zmm_t(3));
+ }
+
+ };
+ auto compute_transform_SDGtWo = [=]() {
+ mov(reg_src, ptr[reg_transp + GET_OFF(src)]);
+ mov(reg_dst, ptr[reg_transp + GET_OFF(dst)]);
+ if (with_bias) mov(reg_bias, ptr[reg_transp + GET_OFF(bias)]);
+
+ xor_(reg_zero, reg_zero);
+ xor_(reg_oc_ur, reg_oc_ur);
+ Label loop_mb, loop_jtiles, loop_itiles, loop_oc_ur, tiles_done;
+
+ L(loop_oc_ur);
+ {
+ mov(reg_ti, ptr[reg_transp + GET_OFF(ti)]);
+ mov(reg_tj, ptr[reg_transp + GET_OFF(tj)]);
+ xor_(reg_tile_count, reg_tile_count);
+ L(loop_mb);
+ {
+ L(loop_jtiles);
+ {
+ L(loop_itiles);
+ {
+ load_src();
+
+ trans_W_3x3_4x4();
+
+ add(reg_tile_count, 1);
+ cmp(reg_tile_count, jcp.nb_tile_block_ur * jcp.tile_block_ur);
+ jge(tiles_done);
+
+ add(reg_dst, jcp.oc_reg_block * simd_w * typesize);
+ add(reg_ti, 1);
+ cmp(reg_ti, jcp.itiles);
+ jl(loop_itiles);
+ }
+ xor_(reg_ti, reg_ti);
+ add(reg_tj, 1);
+ cmp(reg_tj, jcp.jtiles);
+ jl(loop_jtiles);
+ }
+ xor_(reg_tj, reg_tj);
+ add(reg_src, jcp.oc * jcp.ow * jcp.oh * typesize);
+ jmp(loop_mb);
+ }
+
+ L(tiles_done);
+ mov(reg_dst, ptr[reg_transp + GET_OFF(dst)]);
+ add(reg_dst, simd_w * typesize);
+ mov(reg_src, ptr[reg_transp + GET_OFF(src)]);
+ add(reg_src, jcp.oh * jcp.ow * simd_w * typesize);
+
+ if (with_bias) add(reg_bias, simd_w * typesize);
+ add(reg_oc_ur, 1);
+ cmp(reg_oc_ur, jcp.oc_reg_block);
+ jl(loop_oc_ur);
+ }
+ };
+
+ auto compute_transform = [=]() {
+ mov(reg_src, ptr[reg_transp + GET_OFF(src)]);
+ mov(reg_G, ptr[reg_transp + GET_OFF(G)]);
+ if (with_bias) mov(reg_bias, ptr[reg_transp + GET_OFF(bias)]);
+
+ mov(reg_dst, ptr[reg_transp + GET_OFF(dst)]);
+ mov(reg_tile_count, ptr[reg_transp + GET_OFF(tile_count)]);
+ imul(reg_temp, reg_tile_count, jcp.oc_reg_block * simd_w * typesize);
+ add(reg_dst, reg_temp);
+
+ xor_(reg_zero, reg_zero);
+ xor_(reg_oc_ur, reg_oc_ur);
+ Label loop_mb, loop_jtiles, loop_itiles, loop_oc_ur, next_tile_block, next_tile;
+
+ L(loop_oc_ur);
+ {
+ xor_(reg_ti, reg_ti);
+ xor_(reg_tj, reg_tj);
+
+ L(loop_jtiles);
+ {
+ L(loop_itiles);
+ {
+ load_src();
+
+ trans_W_3x3_4x4();
+
+ add(reg_tile_count, 1);
+ cmp(reg_tile_count, jcp.nb_tile_block_ur * jcp.tile_block_ur);
+ jge(next_tile_block);
+ add(reg_dst, jcp.oc_reg_block * simd_w * typesize);
+ jmp(next_tile);
+
+ L(next_tile_block);
+ sub(reg_dst, (jcp.nb_tile_block_ur * jcp.tile_block_ur - 1)
+ * jcp.oc_reg_block * simd_w * typesize);
+ int tblk_off = alpha * alpha * (jcp.oc/jcp.nb_oc)
+ * (jcp.ntiles/jcp.tile_block) * typesize;
+ add(reg_dst, tblk_off);
+ xor_(reg_tile_count, reg_tile_count);
+
+ L(next_tile);
+ add(reg_ti, 1);
+ cmp(reg_ti, jcp.itiles);
+ jl(loop_itiles);
+ }
+ xor_(reg_ti, reg_ti);
+ add(reg_tj, 1);
+ cmp(reg_tj, jcp.jtiles);
+ jl(loop_jtiles);
+ }
+
+ mov(reg_dst, ptr[reg_transp + GET_OFF(dst)]);
+ mov(reg_tile_count, ptr[reg_transp + GET_OFF(tile_count)]);
+ imul(reg_temp, reg_tile_count, jcp.oc_reg_block * simd_w * typesize);
+ add(reg_dst, reg_temp);
+ add(reg_dst, simd_w * typesize);
+ mov(reg_src, ptr[reg_transp + GET_OFF(src)]);
+ add(reg_src, jcp.oh * jcp.ow * simd_w * typesize);
+
+ if (with_bias) add(reg_bias, simd_w * typesize);
+ add(reg_oc_ur, 1);
+ cmp(reg_oc_ur, jcp.oc_reg_block);
+ jl(loop_oc_ur);
+ }
+ };
+
+ preamble();
+ if (jcp.sched_policy == WSCHED_WEI_SDGtWo) {
+ compute_transform_SDGtWo();
+ } else {
+ compute_transform();
+ }
+ postamble();
+}
+
+void jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_kernel::
+diff_weights_transform_generate(bool first_tile) {
+ int G_size = 4;
+
+ auto zmm_G = [](int i) {
+ return Xbyak::Zmm(i);
+ };
+
+ auto init_G = [=]() {
+ mov(reg_G, ptr[reg_transp + GET_OFF(G)]);
+ for (int i = 0; i < G_size; i++)
+ vbroadcastss(zmm_G(i), ptr[reg_G + i * typesize]);
+ };
+
+ auto zmm_src = [=](int i) {
+ return Xbyak::Zmm(G_size + i);
+ };
+
+ auto load_src = [=](int i) {
+ for (int j = 0; j < alpha; j++) {
+ size_t alpha_offset = jcp.oc_block * jcp.oc_reg_block
+ * jcp.ic_block * simd_w * simd_w * typesize;
+ size_t src_off = (j * alpha + i) * alpha_offset;
+ vmovups(zmm_src(j), EVEX_compress_addr(reg_src, src_off));
+ }
+ };
+
+ auto zmm_t = [=](int i) {
+ return Xbyak::Zmm(G_size + 6 + i);
+ };
+
+ auto zmm_T = [=](int j, int i) {
+ return Xbyak::Zmm(G_size + 6 + 3 + j * 6 + i);
+ };
+
+ auto zmm_dst = [=](int i) {
+ return Xbyak::Zmm(G_size + i);
+ };
+
+ auto zmm_temp = Xbyak::Zmm(31);
+
+ auto store_dst = [=](int j) {
+ for (int i = 0; i < jcp.kw; i++) {
+ size_t dst_off = (j * jcp.kw + i) * simd_w * simd_w * typesize;
+
+ if (!first_tile) {
+ vmovups(zmm_temp, EVEX_compress_addr(reg_dst, dst_off));
+ vaddps(zmm_dst(i), zmm_dst(i), zmm_temp);
+ }
+ vmovntps(EVEX_compress_addr(reg_dst, dst_off), zmm_dst(i));
+ }
+ };
+
+ auto compute_transform = [=] () {
+ mov(reg_src, ptr[reg_transp + GET_OFF(src)]);
+ mov(reg_dst, ptr[reg_transp + GET_OFF(dst)]);
+
+ xor_(reg_ic_simd, reg_ic_simd);
+ Label loop_ic_simd;
+ L(loop_ic_simd);
+ {
+ for (int i = 0; i < alpha; i++) {
+ load_src(i);
+
+ vaddps(zmm_t(0), zmm_src(1), zmm_src(2));
+ vaddps(zmm_t(1), zmm_src(3), zmm_src(4));
+ vmovups(zmm_t(2), zmm_src(5));
+ vfmadd231ps(zmm_t(2), zmm_t(1), zmm_G(0));
+
+ vaddps(zmm_T(0, i), zmm_src(0), zmm_t(0));
+ vaddps(zmm_T(0, i), zmm_T(0, i), zmm_t(1));
+ vsubps(zmm_T(1, i), zmm_src(1), zmm_src(2));
+ vmulps(zmm_T(1, i), zmm_T(1, i), zmm_G(1));
+ vsubps(zmm_temp, zmm_src(3), zmm_src(4));
+ vfmadd231ps(zmm_T(1, i), zmm_temp, zmm_G(2));
+ vmovups(zmm_T(2, i), zmm_t(2));
+ vfmadd231ps(zmm_T(2, i), zmm_t(0), zmm_G(3));
+ }
+
+ for (int j = 0; j < jcp.kh; j++) {
+ vaddps(zmm_t(0), zmm_T(j, 1), zmm_T(j, 2));
+ vaddps(zmm_t(1), zmm_T(j, 3), zmm_T(j, 4));
+ vmovups(zmm_t(2), zmm_T(j, 5));
+ vfmadd231ps(zmm_t(2), zmm_t(1), zmm_G(0));
+
+ vaddps(zmm_dst(0), zmm_T(j, 0), zmm_t(0));
+ vaddps(zmm_dst(0), zmm_dst(0), zmm_t(1));
+ vsubps(zmm_dst(1), zmm_T(j, 1), zmm_T(j, 2));
+ vmulps(zmm_dst(1), zmm_dst(1), zmm_G(1));
+ vsubps(zmm_temp, zmm_T(j, 3), zmm_T(j, 4));
+ vfmadd231ps(zmm_dst(1), zmm_temp, zmm_G(2));
+ vmovups(zmm_dst(2), zmm_t(2));
+ vfmadd231ps(zmm_dst(2), zmm_t(0), zmm_G(3));
+
+ store_dst(j);
+ }
+
+ add(reg_src, jcp.oc_reg_block * simd_w * typesize);
+ add(reg_dst, simd_w * typesize);
+ add(reg_ic_simd, 1);
+ cmp(reg_ic_simd, simd_w);
+ jl(loop_ic_simd);
+ }
+ };
+ preamble();
+ push(reg_EVEX_max_8b_offt);
+ mov(reg_EVEX_max_8b_offt, 2 * EVEX_max_8b_offt);
+ init_G();
+ compute_transform();
+ pop(reg_EVEX_max_8b_offt);
+ postamble();
+}
+
+void jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_kernel::gemm_loop_generate(
+ bool is_first_tile)
+{
+ auto zmm_srcA = [=]() {
+ return Xbyak::Zmm(0);
+ };
+
+ auto zmm_srcB = [=] (size_t N_ur){
+ return Xbyak::Zmm(N_ur + 1);
+ };
+
+ auto broadcastB = [=](size_t K_ur) {
+ for (int N_bcast = 0; N_bcast < jcp.dimN_bcast_ur; N_bcast++) {
+ size_t srcB_off = (K_ur * jcp.dimN_reg_block + N_bcast)
+ * sizeof(float);
+ vbroadcastss(zmm_srcB(N_bcast), EVEX_compress_addr(reg_srcB, srcB_off));
+ }
+ };
+
+ auto load_srcA = [=] (size_t K_ur, int M_ur) {
+ size_t srcA_off = (K_ur * jcp.dimM_reg_block * jcp.dimM_simd_block
+ + M_ur * jcp.dimM_simd_block) * sizeof(float);
+ vmovups(zmm_srcA(), EVEX_compress_addr(reg_srcA, srcA_off));
+ };
+
+ auto zmm_dstC = [=](size_t M_reg_ur, int N_bcast){
+ size_t idx = 1 // zmm_srcA
+ + jcp.dimN_bcast_ur // zmm_srcB
+ + M_reg_ur * jcp.dimN_bcast_ur + N_bcast;
+ assert(idx < 32);
+ return Xbyak::Zmm(idx);
+ };
+ auto prepare_accumm = [=](){
+ for (int M_reg_ur = 0; M_reg_ur < jcp.dimM_reg_block; M_reg_ur++) {
+ for (int N_bcast = 0; N_bcast < jcp.dimN_bcast_ur; N_bcast++) {
+ Zmm zmm = zmm_dstC(M_reg_ur, N_bcast);
+ vpxord(zmm, zmm, zmm);
+ }
+ }
+ };
+
+ auto store_dstC = [=](){
+ /******** Write C back to memory *******/
+ for (int M_reg = 0; M_reg < jcp.dimM_reg_block; M_reg++) {
+ for (int N_ur = 0; N_ur < jcp.dimN_bcast_ur; ++N_ur) {
+ Zmm zmm = zmm_dstC(M_reg, N_ur);
+ size_t C_off = (N_ur * jcp.dimM_reg_block * jcp.dimM_simd_block
+ + M_reg * jcp.dimM_simd_block) * sizeof(float);
+ if (!is_first_tile) {
+ vmovups(Xbyak::Zmm(0), EVEX_compress_addr(reg_dstC, C_off));
+ vaddps(zmm, zmm, Xbyak::Zmm(0));
+ }
+ vmovups(EVEX_compress_addr(reg_dstC, C_off), zmm);
+ }
+ }
+ };
+
+ auto inner_loops = [=]() {
+ Label dimM_block_loop, dimK_block_loop, dimN_block_loop, dimN_bcast_ur;
+
+ mov(reg_dimM_block_loop_cnt, jcp.dimM_block);
+ L(dimM_block_loop);
+ { /************* OC_block (M) loop ***********/
+ mov(reg_dimN_block_loop_cnt, jcp.dimN_block);
+ L(dimN_block_loop);
+ { /*************** IC_block (N) loop *********/
+
+ mov(reg_nb_dimN_bcast_ur, jcp.dimN_reg_block/jcp.dimN_bcast_ur);
+ L(dimN_bcast_ur);
+ {
+ prepare_accumm();
+
+ mov(reg_dimK_block_loop_cnt, jcp.dimK_block);
+ L(dimK_block_loop);
+ {
+ /************* nb_tile_ur(K) loop ********/
+ for (int K_ur = 0; K_ur < jcp.dimK_reg_block; K_ur++) {
+
+ broadcastB(K_ur);
+
+ for (int M_reg_ur = 0; M_reg_ur < jcp.dimM_reg_block; M_reg_ur++) {
+ load_srcA(K_ur, M_reg_ur);
+ for (int N_bcast = 0; N_bcast < jcp.dimN_bcast_ur; ++N_bcast) {
+ vfmadd231ps(zmm_dstC(M_reg_ur, N_bcast), zmm_srcA(),
+ zmm_srcB(N_bcast));
+ }
+ }
+ }
+ add(reg_srcA, jcp.dimK_reg_block
+ * jcp.dimM_reg_block * jcp.dimM_simd_block
+ * sizeof(float));
+ add(reg_srcB, jcp.dimK_reg_block
+ * jcp.dimN_reg_block
+ * sizeof(float));
+ sub(reg_dimK_block_loop_cnt, 1);
+ jnz(dimK_block_loop);
+ }
+
+ store_dstC();
+
+ sub(reg_srcA, jcp.dimK_block * jcp.dimK_reg_block
+ * jcp.dimM_reg_block * jcp.dimM_simd_block
+ * sizeof(float));
+ sub(reg_srcB, jcp.dimK_block * jcp.dimK_reg_block
+ * jcp.dimN_reg_block
+ * sizeof(float));
+ add(reg_srcB, jcp.dimN_bcast_ur * sizeof(float));
+ add(reg_dstC, jcp.dimN_bcast_ur
+ * jcp.dimM_reg_block * jcp.dimM_simd_block
+ * sizeof(float));
+ sub(reg_nb_dimN_bcast_ur, 1);
+ jnz(dimN_bcast_ur);
+ }
+
+ sub(reg_srcB, jcp.dimN_reg_block * sizeof(float));
+ add(reg_srcB, jcp.dimK_block
+ * jcp.dimK_reg_block
+ * jcp.dimN_reg_block * sizeof(float));
+ sub(reg_dimN_block_loop_cnt, 1);
+ jnz(dimN_block_loop);
+ }
+
+ sub(reg_srcB, jcp.dimN_block
+ * jcp.dimK_block * jcp.dimK_reg_block
+ * jcp.dimN_reg_block
+ * sizeof(float));
+ add(reg_srcA, jcp.dimK_block * jcp.dimK_reg_block
+ * jcp.dimM_reg_block * jcp.dimM_simd_block
+ * sizeof(float));
+ sub(reg_dimM_block_loop_cnt, 1);
+ jnz(dimM_block_loop);
+ }
+ };
+
+ /* Preamble */
+ preamble();
+
+ inner_loops();
+
+ /* Postamble */
+ postamble();
+ ret();
+}
+
+namespace {
+
+void set_jcp_WEI_params(jit_conv_winograd_conf_t &jcp) {
+/*M params*/
+ jcp.dimM_nb_block = jcp.dimM / jcp.dimM_block / jcp.dimM_reg_block
+ / jcp.dimM_simd_block;
+ jcp.oc_reg_block = jcp.dimM_reg_block;
+ jcp.oc_block = jcp.dimM_block;
+ jcp.nb_oc = jcp.dimM_nb_block;
+ /*N params*/
+ jcp.dimN_nb_block = jcp.dimN / jcp.dimN_block / jcp.dimN_reg_block;
+ jcp.ic_block = jcp.dimN_block;
+ jcp.nb_ic = jcp.dimN_nb_block;
+
+ /*K params*/
+ jcp.dimK_nb_block = jcp.dimK / jcp.dimK_block / jcp.dimK_reg_block;
+ jcp.tile_block_ur = jcp.dimK_reg_block;
+ jcp.nb_tile_block_ur = jcp.dimK_block;
+ jcp.tile_block = jcp.dimK_nb_block;
+}
+
+status_t set_wsched_WEI_SDGtWo(jit_conv_winograd_conf_t &jcp) {
+
+ size_t K_blk_ur, N_blk, M_blk;
+ /* IS this strategy feasible? */
+ auto test_MV_large_enough = [](jit_conv_winograd_conf_t &jcp) {
+ size_t M_sz = alpha * alpha * jcp.dimM * jcp.dimK * sizeof(float);
+ size_t V_sz = alpha * alpha * jcp.dimN * jcp.dimK * sizeof(float);
+ size_t nthreads = mkldnn_get_max_threads();
+ return (((V_sz + M_sz) / nthreads) >= 2 * L2_cache_size)
+ && (jcp.dimK / nthreads >= 1.0);
+ };
+
+ auto test_min_dimK_L1 = [](jit_conv_winograd_conf_t &jcp, int dimK_block_ur,
+ int max_block=1) {
+ size_t L1_block_M = jcp.dimM_reg_block * jcp.dimM_simd_block * dimK_block_ur * sizeof(float);
+ size_t L1_block_N = jcp.dimN_reg_block * dimK_block_ur * sizeof(float);
+ size_t M_L2_block = alpha * alpha * jcp.dimM * dimK_block_ur * sizeof(float);
+ size_t nthreads = mkldnn_get_max_threads();
+ bool load_balance=true;
+ if (!(jcp.dimK % nthreads)) {
+ load_balance = ((jcp.dimK / dimK_block_ur) % nthreads == 0);
+ }
+ return (L1_block_M + L1_block_N >= 0.1 * L1_cache_size)
+ && (L1_block_M + L1_block_N <= 0.5 * L1_cache_size)
+ && load_balance
+ && (M_L2_block < L2_cache_size);
+ };
+
+ auto test_dimK_ur = [](jit_conv_winograd_conf_t &jcp, int dimK_ur,
+ int useless_arg=0) {
+ return (dimK_ur >= 2) && (dimK_ur <= 8);
+ };
+
+ auto blocking_ok = [&](){
+ size_t M_L2_block = alpha * alpha * M_blk * jcp.dimM_reg_block * jcp.dimM_simd_block
+ * K_blk_ur * sizeof(float);
+ size_t V_L2_block = alpha * alpha * N_blk * jcp.dimN_reg_block
+ * K_blk_ur * sizeof(float);
+ size_t U_L2_block = alpha * alpha * M_blk * jcp.dimM_reg_block * jcp.dimM_simd_block
+ * N_blk * jcp.dimN_reg_block * sizeof(float);
+ size_t L2_block = M_L2_block + V_L2_block + U_L2_block;
+ /*Replace 2.375 with L2+L3 cache size*/
+ return (L2_block > 0.1 * L2_cache_size) && (L2_block <= 1.2 * L2_cache_size);
+ };
+
+ if (test_MV_large_enough(jcp)) {
+ if ((jcp.dimM/jcp.dimM_simd_block) % 2 == 0) {
+ jcp.dimM_reg_block = 2;
+ } else {
+ jcp.dimM_reg_block = 1;
+ }
+ jcp.dimM_simd_block = jcp.oc_simd_block;
+ jcp.dimN_reg_block = jcp.ic_simd_block;
+ jcp.dimN_bcast_ur = 8;
+ /*dimK_block and dimK_ur*/
+ size_t min_dimK_block_ur = get_divisor_satisfying_cond(jcp, jcp.dimK, 1, test_min_dimK_L1);
+
+ jcp.dimM_block = jcp.dimM/jcp.dimM_reg_block/jcp.dimM_simd_block;
+ jcp.dimN_block = jcp.dimN/jcp.dimN_reg_block;
+ for (K_blk_ur = min_dimK_block_ur; K_blk_ur >= 1; --K_blk_ur) {
+ if (test_min_dimK_L1(jcp, K_blk_ur) && !(jcp.dimK % K_blk_ur)) {
+ for (N_blk = jcp.dimN_block; N_blk >= 1; --N_blk) {
+ if (!(jcp.dimN_block % N_blk)) {
+ for (M_blk = jcp.dimM_block; M_blk >= 1; --M_blk) {
+ if (!(jcp.dimM_block % M_blk) && blocking_ok()) {
+ jcp.dimK_reg_block = get_divisor_satisfying_cond(jcp, K_blk_ur, 1, test_dimK_ur);
+ if (!test_dimK_ur(jcp, jcp.dimK_reg_block)) return status::unimplemented;
+ jcp.dimK_block = K_blk_ur / jcp.dimK_reg_block;
+ jcp.dimN_block = N_blk;
+ jcp.dimM_block = M_blk;
+ jcp.sched_policy = WSCHED_WEI_SDGtWo;
+ set_jcp_WEI_params(jcp);
+ jcp.nthr = nstl::min(mkldnn_get_max_threads(),
+ jcp.tile_block);
+ return status::success;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return status::unimplemented;
+}
+
+status_t set_wsched_WEI_S_D_Giot_W(jit_conv_winograd_conf_t &jcp) {
+ if ((jcp.dimM/jcp.dimM_simd_block) % 2 == 0) {
+ jcp.dimM_reg_block = 2;
+ } else {
+ jcp.dimM_reg_block = 1;
+ }
+ jcp.dimN_bcast_ur = 8;
+ jcp.dimN_reg_block = jcp.ic_simd_block;
+ jcp.dimM_simd_block = jcp.oc_simd_block;
+ jcp.dimN_block = jcp.dimN / jcp.dimN_reg_block;
+ jcp.dimM_block = jcp.dimM / jcp.dimM_reg_block / jcp.dimM_simd_block;
+ float C1 = 0.0, C2 = 0.0;
+ float C1_max = 0.5, C2_max = 1.4;
+ int N_blk, M_blk, K_blk_ur;
+
+ auto test_dimK_ur = [](jit_conv_winograd_conf_t &jcp, int dimK_ur,
+ int useless_arg=0) {
+ return (dimK_ur >= 2) && (dimK_ur <= 8);
+ };
+
+ auto blocking_ok = [&]() -> bool {
+ size_t L1_block_M = jcp.dimM_reg_block * jcp.dimM_simd_block * K_blk_ur * sizeof(float);
+ size_t L1_block_N = jcp.dimN_reg_block * K_blk_ur * sizeof(float);
+ bool L1_cond = ((L1_block_N + L1_block_M) >= C1 * L1_cache_size)
+ && ((L1_block_N + L1_block_M) <= C1_max * L1_cache_size);
+
+ size_t nb_N_blk = jcp.dimN/N_blk/jcp.dimN_reg_block;
+ size_t nb_M_blk = jcp.dimM/M_blk/jcp.dimM_reg_block/jcp.dimM_simd_block;
+ size_t nb_K_blk = jcp.dimK / K_blk_ur;
+ size_t nthreads = mkldnn_get_max_threads();
+ bool load_balance = (nb_K_blk * nb_N_blk * nb_M_blk) >= nthreads;
+ if (!(nb_K_blk % nthreads)) {
+ load_balance = load_balance && (nb_K_blk % nthreads == 0);
+ }
+
+ size_t V_L2_block = alpha * alpha * N_blk * jcp.dimN_reg_block * K_blk_ur * sizeof(float);
+
+ size_t L2_block = V_L2_block;
+ /*Replace 2.375 with L2+L3 cache size*/
+ bool L2_cond = (L2_block >= C2 * L2_cache_size) && (L2_block <= C2_max * L2_cache_size);
+ return L1_cond && load_balance && L2_cond;
+ };
+
+ for (K_blk_ur = jcp.dimK; K_blk_ur >= 1; --K_blk_ur) {
+ if (jcp.dimK % K_blk_ur == 0) {
+ for (N_blk = jcp.dimN_block; N_blk >= 1; --N_blk) {
+ if (jcp.dimN_block % N_blk == 0) {
+ for (M_blk = jcp.dimM_block; M_blk >= 1; --M_blk) {
+ if (jcp.dimM_block % M_blk == 0) {
+ if (blocking_ok()) {
+ jcp.dimN_block = N_blk;
+ jcp.dimM_block = M_blk;
+ jcp.dimK_reg_block = get_divisor_satisfying_cond(jcp, K_blk_ur, 1, test_dimK_ur);
+ jcp.dimK_block = K_blk_ur / jcp.dimK_reg_block;
+ jcp.sched_policy = WSCHED_WEI_S_D_Giot_W;
+ set_jcp_WEI_params(jcp);
+ return status::success;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ jcp.dimK_reg_block = 1;
+ jcp.dimK_block = 1;
+ jcp.sched_policy = WSCHED_WEI_S_D_Giot_W;
+ set_jcp_WEI_params(jcp);
+ return status::success;
+}
+} // namespace
+status_t jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_kernel::init_conf(
+ jit_conv_winograd_conf_t &jcp, const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d, const memory_desc_wrapper &diff_dst_d,
+ const memory_desc_wrapper &diff_weights_d) {
+ if (!mayiuse(avx512_core))
+ return status::unimplemented;
+ else
+ jcp.ver = ver_avx512_core;
+
+ jcp.nthr = mkldnn_get_max_threads();
+
+ jcp.prop_kind = cd.prop_kind;
+ const bool with_groups = diff_weights_d.ndims() == src_d.ndims() + 1;
+ jcp.mb = src_d.dims()[0];
+ jcp.ngroups = with_groups ? diff_weights_d.dims()[0] : 1;
+ jcp.oc = diff_dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+ jcp.ih = src_d.dims()[2];
+ jcp.iw = src_d.dims()[3];
+ jcp.oh = diff_dst_d.dims()[2];
+ jcp.ow = diff_dst_d.dims()[3];
+ jcp.kh = diff_weights_d.dims()[with_groups + 2];
+ jcp.kw = diff_weights_d.dims()[with_groups + 3];
+ jcp.t_pad = cd.padding[0][0];
+ jcp.l_pad = cd.padding[0][1];
+ jcp.stride_h = cd.strides[0];
+ jcp.stride_w = cd.strides[1];
+ jcp.r_pad = nstl::max(
+ 0, (jcp.ow - 1) * jcp.stride_w + jcp.kw - jcp.iw - jcp.l_pad);
+ jcp.b_pad = nstl::max(
+ 0, (jcp.oh - 1) * jcp.stride_h + jcp.kh - jcp.ih - jcp.t_pad);
+ jcp.ihp = jcp.ih + jcp.t_pad + jcp.b_pad;
+ jcp.iwp = jcp.iw + jcp.l_pad + jcp.r_pad;
+ jcp.ohp = jcp.oh;
+ jcp.owp = jcp.ow;
+ jcp.with_bias = (cd.diff_bias_desc.format_kind != format_kind::undef);
+ jcp.dilate_h = cd.dilates[0];
+ jcp.dilate_w = cd.dilates[1];
+
+ bool ok_to_pad_channels = jcp.ngroups == 1;
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ jcp.ic = rnd_up(jcp.ic, simd_w);
+ }
+
+ // Winograd specific initialization
+ jcp.itiles = (jcp.ow + tile_size - 1) / tile_size;
+ jcp.jtiles = (jcp.oh + tile_size - 1) / tile_size;
+ jcp.ntiles = jcp.mb * jcp.itiles * jcp.jtiles;
+
+ // Winograd kernel works only for 3x3 convolution with stride 1
+ if (!IMPLICATION(cd.alg_kind == alg_kind::convolution_auto,
+ is_winograd_faster_than_direct(jcp)))
+ return status::unimplemented;
+
+ if (jcp.ngroups != 1)
+ return status::unimplemented;
+ if ((jcp.kh != 3) || (jcp.kw != 3))
+ return status::unimplemented;
+ if ((jcp.dilate_h != 0) || (jcp.dilate_w != 0))
+ return status::unimplemented;
+ if ((jcp.stride_h != 1) || (jcp.stride_w != 1))
+ return status::unimplemented;
+ if ((jcp.ic % simd_w) != 0 || (jcp.oc % simd_w) != 0)
+ return status::unimplemented;
+
+ format_tag_t dat_tag = nChw16c;
+ format_tag_t wei_tag = with_groups ? gOIhw16i16o : OIhw16i16o;
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ jcp.wei_tag = diff_weights_d.matches_one_of_tag(wei_tag);
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(dat_tag);
+
+ if (jcp.src_tag != dat_tag) return status::unimplemented;
+ if (jcp.wei_tag != wei_tag) return status::unimplemented;
+ if (jcp.dst_tag != dat_tag) return status::unimplemented;
+
+ bool layout_consistency = true
+ && jcp.ic <= src_d.padded_dims()[1]
+ && jcp.oc <= diff_dst_d.padded_dims()[1]
+ && jcp.ic <= diff_weights_d.padded_dims()[with_groups + 1]
+ && jcp.oc <= diff_weights_d.padded_dims()[with_groups + 0];
+ if (!layout_consistency) return status::unimplemented;
+
+ /******************Kernel blocking Parameters ***********/
+ jcp.ic_simd_block = simd_w;
+ jcp.oc_simd_block = simd_w;
+
+ jcp.dimK = jcp.ntiles;
+ jcp.dimN = jcp.ic;
+ jcp.dimM = jcp.oc;
+ jcp.dimM_simd_block = jcp.oc_simd_block;
+ jcp.dimN_reg_block = jcp.ic_simd_block;
+ jcp.sched_policy = WSCHED_INVALID;
+ status_t res = set_wsched_WEI_SDGtWo(jcp);
+ if (res == status::unimplemented) {
+ res = set_wsched_WEI_S_D_Giot_W(jcp);
+ assert(res == status::success);
+ }
+ return res;
+}
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3_kernel.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3_kernel.hpp
new file mode 100644
index 0000000000..025a554d92
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_fp32_wino_conv_4x3_kernel.hpp
@@ -0,0 +1,291 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_AVX512_CORE_FP32_WINO_CONV_4x3_KERNEL_HPP
+#define JIT_AVX512_CORE_FP32_WINO_CONV_4x3_KERNEL_HPP
+
+#include "c_types_map.hpp"
+
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+
+#include "jit_avx512_common_conv_winograd_kernel_f32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct _jit_avx512_core_fp32_wino_conv_4x3_data_kernel
+ : public jit_generator {
+ _jit_avx512_core_fp32_wino_conv_4x3_data_kernel(
+ jit_conv_winograd_conf_t ajcp)
+ : jcp(ajcp) {
+ {
+ this->weights_transform_data_ker_generate();
+ weights_transform_data_ker
+ = (decltype(weights_transform_data_ker)) this->getCode();
+ }
+ {
+ align();
+ const Xbyak::uint8 *addr = getCurr();
+ this->input_transform_data_ker_generate();
+ input_transform_data_ker = (decltype(input_transform_data_ker))addr;
+ }
+ {
+ align();
+ const Xbyak::uint8 *addr = getCurr();
+ this->output_transform_data_ker_generate();
+ output_transform_data_ker
+ = (decltype(output_transform_data_ker))addr;
+ }
+ {
+ align();
+ const Xbyak::uint8 *addr = getCurr();
+ this->gemm_loop_generate();
+ gemm_loop_ker = (decltype(gemm_loop_ker))addr;
+ }
+ }
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(_jit_avx512_core_fp32_wino_conv_4x3_data_kernel)
+
+ static status_t init_conf_common(jit_conv_winograd_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d);
+
+ static status_t init_conf_kernel(
+ jit_conv_winograd_conf_t &jcp, int dimM, int dimN, int dimK);
+
+ jit_conv_winograd_conf_t jcp;
+ void (*gemm_loop_ker)(float *, const float *, const float *, const int);
+ void (*input_transform_data_ker)(jit_wino_transform_call_s *);
+ void (*output_transform_data_ker)(jit_wino_transform_call_s *);
+ void (*weights_transform_data_ker)(jit_wino_transform_call_s *);
+
+protected:
+ using reg64_t = const Xbyak::Reg64;
+ using reg32_t = const Xbyak::Reg32;
+ enum { typesize = sizeof(float) };
+
+ void gemm_loop_generate();
+ void input_transform_data_ker_generate();
+ void output_transform_data_ker_generate();
+ void weights_transform_data_ker_generate();
+
+ /* registers used for GEMM */
+ reg64_t reg_dstC = abi_param1;
+ reg64_t reg_srcA = abi_param2;
+ reg64_t reg_srcB = abi_param3;
+ reg64_t reg_is_beta_zero = abi_param4;
+
+ reg64_t reg_dimM_block_loop_cnt = r10;
+ reg64_t reg_dimK_block_loop_cnt = r11;
+
+ /* registers used for transforms*/
+ reg64_t param = abi_param1;
+
+ /* registers used for output_transform_data_ker */
+ reg64_t oreg_temp = abi_not_param1;
+ reg64_t oreg_Ow = r9;
+ reg64_t oreg_src = r11;
+ reg64_t oreg_tile_block = r12;
+ reg64_t oreg_tile_block_ur = r13;
+ reg64_t oreg_nb_tile_block_ur = r14;
+ reg64_t oreg_O = r8;
+ reg64_t oreg_T = r10;
+ reg64_t oreg_dst = r11;
+ reg64_t oreg_ydim = r14;
+ reg64_t oreg_xdim = r15;
+ reg64_t oreg_out_j = r12;
+ reg64_t oreg_bias = rbx;
+ reg64_t imm_addr64 = rax;
+
+ /* registers used for input_transform_data_ker */
+ reg64_t ireg_temp = abi_not_param1;
+ reg64_t ireg_jtiles = rax;
+ reg64_t ireg_itiles = rbx;
+ reg64_t ireg_I = r8;
+ reg64_t ireg_src = r13;
+ reg64_t ireg_ydim = r14;
+ reg64_t ireg_xdim = r15;
+ reg64_t ireg_inp_j = r12;
+ reg64_t ireg_inp_i = rdx;
+ reg64_t ireg_mask_j = r11;
+ reg64_t ireg_mask = rsi;
+ reg32_t ireg_mask_32 = esi;
+ reg64_t ireg_zero = r9;
+ reg64_t ireg_Iw = r9;
+ reg64_t ireg_T = r10;
+ reg64_t ireg_tile_block = r12;
+ reg64_t ireg_tile_block_ur = r13;
+ reg64_t ireg_nb_tile_block_ur = r14;
+ reg64_t ireg_output = r15;
+
+ /* registers used for wei transform */
+ reg64_t wreg_temp = abi_not_param1;
+ reg64_t wreg_F = r8;
+ reg64_t wreg_src = r9;
+ reg64_t wreg_MT = r15;
+ reg64_t wreg_M = r14;
+ reg64_t wreg_dst = r10;
+ reg64_t wreg_dst_aux = r9;
+ reg64_t wreg_dst_idx = r8;
+ reg64_t wreg_Fw = r11;
+ reg64_t wreg_T = r12;
+ reg64_t wreg_cnt_j = rdx;
+ reg64_t wreg_F_aux = r14;
+ reg64_t wreg_Fw_aux = r15;
+};
+
+struct jit_avx512_core_fp32_wino_conv_4x3_fwd_kernel
+ : _jit_avx512_core_fp32_wino_conv_4x3_data_kernel {
+ using _jit_avx512_core_fp32_wino_conv_4x3_data_kernel::
+ _jit_avx512_core_fp32_wino_conv_4x3_data_kernel;
+
+ static bool post_ops_ok(jit_conv_conf_t &jcp, const primitive_attr_t &attr);
+
+ static status_t init_conf(jit_conv_winograd_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_t &src_md,
+ memory_desc_t &weights_md, const memory_desc_t &dst_md,
+ const primitive_attr_t &attr);
+};
+
+struct jit_avx512_core_fp32_wino_conv_4x3_bwd_data_kernel
+ : public _jit_avx512_core_fp32_wino_conv_4x3_data_kernel {
+ using _jit_avx512_core_fp32_wino_conv_4x3_data_kernel::
+ _jit_avx512_core_fp32_wino_conv_4x3_data_kernel;
+
+ static status_t init_conf(jit_conv_winograd_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &diff_src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &diff_dst_d);
+};
+
+struct jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_kernel
+ : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(
+ _jit_avx512_core_conv_winograd_bwd_weights_kernel_f32)
+
+ jit_avx512_core_fp32_wino_conv_4x3_bwd_weights_kernel(
+ jit_conv_winograd_conf_t ajcp)
+ : jcp(ajcp)
+ {
+ //******************* First iter kernel ********************//
+ this->gemm_loop_generate(true);
+ gemm_loop_ker_first_iter = (decltype(gemm_loop_ker_first_iter))this->getCode();
+
+ align();
+ const Xbyak::uint8 *addr = getCurr();
+ this->src_transform_generate();
+ src_transform = (decltype(src_transform))addr;
+
+ if (jcp.with_bias) {
+ align();
+ addr = getCurr();
+ this->diff_dst_transform_generate(true);
+ diff_dst_transform_wbias = (decltype(diff_dst_transform_wbias))addr;
+ }
+
+ align();
+ addr = getCurr();
+ this->diff_dst_transform_generate(false);
+ diff_dst_transform = (decltype(diff_dst_transform))addr;
+
+ if (jcp.sched_policy != WSCHED_WEI_SDGtWo && jcp.tile_block > 1) {
+ align();
+ addr = getCurr();
+ this->gemm_loop_generate(false);
+ gemm_loop_ker = (decltype(gemm_loop_ker))addr;
+ }
+
+ align();
+ addr = getCurr();
+ this->diff_weights_transform_generate(true);
+ diff_weights_transform = (decltype(diff_weights_transform))addr;
+
+ if (jcp.sched_policy == WSCHED_WEI_SDGtWo) {
+ align();
+ addr = getCurr();
+ this->diff_weights_transform_generate(false);
+ diff_weights_transform_accum =
+ (decltype(diff_weights_transform_accum))addr;
+ };
+ }
+
+ static status_t init_conf(jit_conv_winograd_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &diff_dst_d,
+ const memory_desc_wrapper &diff_weights_d);
+
+ jit_conv_winograd_conf_t jcp;
+ void (*gemm_loop_ker)(float *, const float *, const float *);
+ void (*gemm_loop_ker_first_iter)(float *, const float *, const float *);
+ void (*src_transform)(jit_wino_transform_call_s *);
+ void (*diff_dst_transform)(jit_wino_transform_call_s *);
+ void (*diff_dst_transform_wbias)(jit_wino_transform_call_s *);
+ void (*diff_weights_transform)(jit_wino_transform_call_s *);
+ void (*diff_weights_transform_accum)(jit_wino_transform_call_s *);
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ using reg32_t = const Xbyak::Reg32;
+ enum { typesize = sizeof(float) };
+
+ void src_transform_generate();
+ void diff_dst_transform_generate(bool with_bias);
+ void diff_weights_transform_generate(bool first_tile);
+
+ /*registers common to transforms*/
+ reg64_t reg_transp = abi_param1;
+ reg64_t reg_ti = rbx;
+ reg64_t reg_tj = abi_not_param1;
+ reg64_t reg_src = r8;
+ reg64_t reg_dst = r9;
+ reg64_t reg_G = rsi; /*TODO: check if this is ok*/
+ reg64_t reg_temp = rsi;
+
+ /*registers common to src/diff_dst transform*/
+ reg64_t reg_I = r10;
+ reg64_t reg_ydim = r11;
+ reg64_t reg_xdim = r12;
+ reg64_t reg_src_offset = r13;
+ reg64_t reg_zero = r14;
+ reg64_t reg_tile_count = r15;
+ reg64_t reg_maski = rsi;
+ reg32_t reg_maski_32 = esi;
+ reg64_t reg_maskj = rdx;
+
+ reg64_t reg_T = rax;
+ reg64_t reg_oc_ur = rax;
+ reg64_t reg_ic_simd = r14;
+ reg64_t reg_bias = r10;
+
+ void gemm_loop_generate(bool is_first_tile);
+
+ reg64_t reg_dstC = abi_param1;
+ reg64_t reg_srcA = abi_param2;
+ reg64_t reg_srcB = abi_param3;
+
+ reg64_t reg_dimM_block_loop_cnt = r9;
+ reg64_t reg_dimN_block_loop_cnt = r10;
+ reg64_t reg_nb_dimN_bcast_ur = r11;
+ reg64_t reg_dimK_block_loop_cnt = r12;
+};
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_u8s8s32x_wino_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_u8s8s32x_wino_convolution.cpp
new file mode 100644
index 0000000000..002010ffa2
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_u8s8s32x_wino_convolution.cpp
@@ -0,0 +1,1284 @@
+/*******************************************************************************
+ * Copyright 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_avx512_core_u8s8s32x_wino_convolution.hpp"
+#include "jit_generator.hpp"
+
+#include <string.h>
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+using namespace Xbyak;
+
+namespace {
+ // Below scales are applied to source and weights data accordingly
+ // because this winograd implementation
+ // transforms source which may increase values up to 4x
+ // and transforms weights which may increase values up to 9/4x
+ const float adj_src_scale = 1.f / 4.f;
+ const float adj_wei_scale = 4.f / 9.f;
+ // Winograd transforms need ic and oc to be multiples of 16
+ const int load_block = 16;
+}
+
+/// SRC TRANSFORMS /////////////////////////////////////////////////////////////
+struct jit_avx512_core_u8s8s32x_wino_conv_src_trans_t: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(
+ jit_avx512_core_u8s8s32x_wino_conv_src_trans_t)
+
+ jit_conv_conf_2x3_wino_t jcp;
+ const primitive_attr_t &attr_;
+
+ struct call_params_t {
+ const void *src;
+ const void *wino_src;
+ const void *v_y_masks;
+ const void *v_x_masks;
+ };
+ void (*ker_)(const call_params_t *);
+
+ jit_avx512_core_u8s8s32x_wino_conv_src_trans_t(
+ jit_conv_conf_2x3_wino_t ajcp, const primitive_attr_t &attr)
+ : jcp(ajcp), attr_(attr), unsign_val_in_wino_domain(5) {
+ generate();
+ ker_ = reinterpret_cast<decltype(ker_)>(const_cast<uint8_t*>(getCode()));
+ }
+ void generate();
+
+ int reg_inp_ind(int i) {
+ assert(i < jcp.alpha * jcp.alpha);
+ return (31 - i);
+ }
+
+ Xmm vreg_inp(int i) {
+ return Xmm(reg_inp_ind(i));
+ }
+
+ Zmm zmm_inp(int i) {
+ return Zmm(reg_inp_ind(i));
+ }
+
+ Xmm vreg_tmp(int i) {
+ assert(i < jcp.alpha * jcp.alpha);
+ return Xmm(15 - i);
+ }
+ Xmm vreg_out(int i) {
+ assert(i < jcp.alpha * jcp.alpha);
+ return Xmm(31 - i);
+ }
+
+ Opmask y_mask = Opmask(1);
+ Opmask r_mask = Opmask(2);
+ Opmask x_mask(int id) {
+ assert(id < 4);
+ return Opmask(3 + id);
+ }
+
+ Reg64 reg_ptr_src = r14;
+ Reg64 reg_ptr_dst = r13;
+
+ Reg64 reg_ptr_v_y_masks = r12;
+ Reg64 reg_ptr_v_x_masks = r11;
+
+ Reg64 reg_aux_ptr_src = r10;
+ Reg64 reg_aux_ptr_dst = r9;
+
+ Reg64 reg_ic_block = r8;
+
+ int unsign_val_in_wino_domain;
+
+ Reg64 reg_scratch_src_alpha = rdx;
+ Xmm xmm_src_alpha = Xmm(0);
+ Zmm zmm_src_alpha = Zmm(0);
+
+ Reg64 reg_shift = rax;
+ Xmm xmm_shift = Xmm(1);
+ Xmm xmm_zero = Xmm(0);
+
+ Reg64 reg_maskx = rbx;
+ Reg64 reg_masky = rsi;
+ Reg64 reg_nomask = reg_maskx;
+};
+
+void jit_avx512_core_u8s8s32x_wino_conv_src_trans_t::generate() {
+ Label ic_block_label;
+ Label end_label;
+ Label mask_label;
+ Label nomask_label;
+
+ auto load_src = [=](bool mask) {
+ for (int y = 0; y < jcp.alpha; y++) {
+ if (mask)
+ kmovw(y_mask, ptr[reg_ptr_v_y_masks + sizeof(uint16_t) * y]);
+ for (int x = 0; x < jcp.alpha; x++) {
+ Zmm zmm_i = zmm_inp(y * jcp.alpha + x);
+ Xmm vreg_i = vreg_inp(y * jcp.alpha + x);
+ int inp_offset = sizeof(uint8_t)
+ * ((-jcp.t_pad + y) * jcp.iw * jcp.ic
+ + (-jcp.l_pad + x) * jcp.ic);
+ if (mask) {
+ kandw(r_mask, y_mask, x_mask(x));
+ vmovdqu8(vreg_i | r_mask | T_z,
+ EVEX_compress_addr(reg_aux_ptr_src, inp_offset));
+ } else {
+ vmovdqu8(vreg_i,
+ EVEX_compress_addr(reg_aux_ptr_src, inp_offset));
+ }
+ vpmovzxbd(zmm_i, vreg_i); // to int32
+ vcvtdq2ps(zmm_i, zmm_i); // to fp32
+ vmulps(zmm_i, zmm_i, zmm_src_alpha); // *alpha
+ vcvtps2dq(zmm_i, zmm_i); // to int32
+ vpmovusdb(vreg_i, zmm_i); // to u8
+ }
+ }
+ };
+
+ preamble();
+
+# define READ_PARAM(reg, field) \
+ mov(reg, ptr[abi_param1 + offsetof(call_params_t, field)])
+ READ_PARAM(reg_ptr_src, src);
+ READ_PARAM(reg_ptr_dst, wino_src);
+ READ_PARAM(reg_ptr_v_y_masks, v_y_masks);
+ READ_PARAM(reg_ptr_v_x_masks, v_x_masks);
+# undef READ_PARAM
+
+ mov(reg_maskx, ptr[reg_ptr_v_x_masks]);
+ mov(reg_masky, ptr[reg_ptr_v_y_masks]);
+ test(reg_maskx, reg_maskx);
+ jz(end_label, T_NEAR); // skip kernel if x mask is all 0's
+ test(reg_masky, reg_masky);
+ jz(end_label, T_NEAR); // skip kernel if y mask is all 0's
+ and_(reg_maskx, reg_masky);
+ mov(reg_nomask, reg_maskx);
+ not_(reg_nomask); // zero if x and y masks are all 1's
+
+ xor_(reg_shift, reg_shift);
+ mov(reg_shift.cvt8(), (int8_t)-128);
+
+ mov(reg_aux_ptr_src, reg_ptr_src);
+ mov(reg_aux_ptr_dst, reg_ptr_dst);
+
+ for (int i = 0; i < jcp.alpha; i++) {
+ kmovw(x_mask(i), ptr[reg_ptr_v_x_masks + sizeof(uint16_t) * i]);
+ }
+
+ mov(reg_scratch_src_alpha, float2int(adj_src_scale));
+
+ mov(reg_ic_block, jcp.ic / load_block);
+ L(ic_block_label);
+ {
+ vmovq(xmm_src_alpha, reg_scratch_src_alpha);
+ vbroadcastss(zmm_src_alpha, xmm_src_alpha);
+
+ test(reg_nomask, reg_nomask);
+ jz(nomask_label, T_NEAR);
+ load_src(true);
+ jmp(mask_label, T_NEAR);
+ L(nomask_label);
+ load_src(false);
+ L(mask_label);
+
+ for(int y = 0; y < 4; y++) {
+ vpsubb(vreg_tmp(y*4+0), vreg_inp(y*4+0), vreg_inp(y*4+2));
+ vpaddb(vreg_tmp(y*4+1), vreg_inp(y*4+1), vreg_inp(y*4+2));
+ vpsubb(vreg_tmp(y*4+2), vreg_inp(y*4+2), vreg_inp(y*4+1));
+ vpsubb(vreg_tmp(y*4+3), vreg_inp(y*4+1), vreg_inp(y*4+3));
+ }
+ for(int x = 0;x < 4; x++) {
+ vpsubb(vreg_out(x+0*4), vreg_tmp(x+4*0), vreg_tmp(x+4*2));
+ vpaddb(vreg_out(x+1*4), vreg_tmp(x+4*1), vreg_tmp(x+4*2));
+ vpsubb(vreg_out(x+2*4), vreg_tmp(x+4*2), vreg_tmp(x+4*1));
+ vpsubb(vreg_out(x+3*4), vreg_tmp(x+4*1), vreg_tmp(x+4*3));
+ }
+
+ vmovd(xmm_shift, reg_shift.cvt32());
+ vpxor(xmm_zero, xmm_zero, xmm_zero);
+ vpshufb(xmm_shift, xmm_shift, xmm_zero);
+
+ for (int i = 0; i < 16; i++) {
+ int out_offset = sizeof(uint8_t) * (jcp.inp_stride * i);
+ if (i != unsign_val_in_wino_domain)
+ vpsubb(vreg_out(i), vreg_out(i), Xmm(1));
+ vmovups(EVEX_compress_addr(reg_aux_ptr_dst, out_offset), vreg_out(i));
+ }
+
+ add(reg_aux_ptr_src, sizeof(uint8_t) * load_block);
+ add(reg_aux_ptr_dst, sizeof(uint8_t) * load_block);
+ }
+ dec(reg_ic_block);
+ jnz(ic_block_label, T_NEAR);
+
+ L(end_label);
+ postamble();
+}
+
+/// DST TRANSFORMS /////////////////////////////////////////////////////////////
+struct jit_avx512_core_u8s8s32x_wino_conv_dst_trans_t: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(
+ jit_avx512_core_u8s8s32x_wino_conv_dst_trans_t)
+
+ jit_conv_conf_2x3_wino_t jcp;
+ const primitive_attr_t &attr_;
+
+ struct call_params_t {
+ const void *wino_dst;
+ const void *dst;
+ const void *v_y_masks;
+ const void *v_x_masks;
+
+ const void *bias;
+ const void *scales;
+ };
+ void (*ker_)(const call_params_t *);
+
+ jit_avx512_core_u8s8s32x_wino_conv_dst_trans_t(
+ jit_conv_conf_2x3_wino_t ajcp, const primitive_attr_t &attr)
+ : jcp(ajcp), attr_(attr) {
+ generate();
+ ker_ = reinterpret_cast<decltype(ker_)>(const_cast<uint8_t*>(getCode()));
+ }
+
+ void generate();
+ bool maybe_relu(int position);
+
+ Zmm vreg_inp(int i) { // 16
+ assert(i < jcp.alpha * jcp.alpha);
+ return Zmm(31 - i);
+ }
+ Zmm vreg_stg(int id) { // 8
+ const int id_reg_stg = jcp.alpha * jcp.alpha + id;
+ assert(id < 8);
+ return Zmm(31 - id_reg_stg);
+ }
+ Zmm vreg_out(int id) { // 4
+ const int id_reg_out = jcp.alpha * jcp.alpha + 8 + id;
+ assert(id < 4);
+ return Zmm(31 - id_reg_out);
+ }
+ Xmm xmm_out(int id) { // 4
+ const int id_reg_out = jcp.alpha * jcp.alpha + 8 + id;
+ assert(id < 4);
+ return Xmm(31 - id_reg_out);
+ }
+ Zmm vreg_tmp(int id) { // 2
+ const int id_reg_tmp = jcp.alpha * jcp.alpha + 12 + id;
+ assert(id < 2);
+ return Zmm(31 - id_reg_tmp);
+ }
+
+ Zmm vreg_zero = Zmm(0);
+ Zmm vreg_bias = Zmm(1);
+ Zmm vreg_prev_dst = Zmm(2);
+ Zmm zmm_bias_alpha = Zmm(2);
+ Xmm xmm_bias_alpha = Xmm(2);
+
+ Opmask y_mask = Opmask(1);
+ Opmask r_mask = Opmask(2);
+ Opmask x_mask(int id) {
+ assert(id < 4);
+ return Opmask(3 + id);
+ }
+
+ Reg64 reg_scratch_bias_alpha = r15;
+
+ Reg64 reg_ptr_src = r14;
+ Reg64 reg_ptr_dst = r13;
+
+ Reg64 reg_ptr_v_y_masks = r12;
+ Reg64 reg_ptr_v_x_masks = r11;
+
+ Reg64 reg_aux_ptr_src = r10;
+ Reg64 reg_aux_ptr_dst = r9;
+
+ Reg64 reg_oc_block = r8;
+
+ Reg64 reg_ptr_bias = rbx;
+ Reg64 reg_ptr_scales = abi_not_param1;
+ Reg64 reg_ptr_sum_scale = rdx;
+};
+
+bool jit_avx512_core_u8s8s32x_wino_conv_dst_trans_t::maybe_relu(int position) {
+ using namespace primitive_kind;
+ const auto &p = attr_.post_ops_;
+
+ if (position == 0) {
+ /* relu before sum */
+ return false
+ || p.contain(eltwise, 0)
+ || (jcp.dst_dt == data_type::u8 && !p.contain(sum, 0));
+ } else if (position == 1) {
+ /* relu after sum */
+ const int sum_idx = p.contain(sum, 0)
+ ? 0 : (p.contain(sum, 1) ? 1 : -1);
+ if (sum_idx == -1)
+ return false;
+
+ return false
+ || p.contain(eltwise, sum_idx + 1)
+ || jcp.dst_dt == data_type::u8;
+ }
+
+ return false;
+}
+
+void jit_avx512_core_u8s8s32x_wino_conv_dst_trans_t::generate() {
+ Label oc_block_label;
+
+ auto loop_body = [=]() {
+ const auto &p = attr_.post_ops_;
+ const int sum_idx = p.find(primitive_kind::sum);
+ const float *p_sum_scale = (sum_idx != -1)
+ ? &p.entry_[sum_idx].sum.scale
+ : nullptr;
+ if (p_sum_scale && *p_sum_scale != 1.f)
+ mov(reg_ptr_sum_scale, (size_t)p_sum_scale);
+
+ for(int i = 0; i < 16; i++) {
+ int internal_offset = sizeof(int32_t) * jcp.out_stride * i;
+ vmovups(vreg_inp(i),
+ EVEX_compress_addr(reg_aux_ptr_src, internal_offset));
+ }
+ for(int y = 0; y < jcp.alpha; y++) {
+ vpaddd(vreg_tmp(0), vreg_inp(y*4 + 0), vreg_inp(y*4 + 1));
+ vpaddd(vreg_stg(y*2), vreg_tmp(0), vreg_inp(y*4 + 2));
+
+ vpsubd(vreg_tmp(1), vreg_inp(y*4 + 1), vreg_inp(y*4 + 2));
+ vpsubd(vreg_stg(y*2+1), vreg_tmp(1), vreg_inp(y*4 + 3));
+ }
+ for(int x = 0; x < jcp.m; x++) {
+ vpaddd(vreg_tmp(0), vreg_stg(x), vreg_stg(x+2*1));
+ vpaddd(vreg_out(x), vreg_tmp(0), vreg_stg(x+2*2));
+
+ vpsubd(vreg_tmp(1), vreg_stg(x+2*1), vreg_stg(x+2*2));
+ vpsubd(vreg_out(x+2), vreg_tmp(1), vreg_stg(x+2*3));
+ }
+
+
+ if (jcp.with_bias) {
+ vmovq(xmm_bias_alpha, reg_scratch_bias_alpha);
+ vbroadcastss(zmm_bias_alpha, xmm_bias_alpha);
+
+ auto bias_addr = ptr [ reg_ptr_bias ];
+ switch (jcp.bia_dt) {
+ case data_type::f32:
+ case data_type::s32: vmovups(vreg_bias, bias_addr); break;
+ case data_type::s8: vpmovsxbd(vreg_bias, bias_addr); break;
+ case data_type::u8: vpmovzxbd(vreg_bias, bias_addr); break;
+ default: assert(!"unsupported dst data type");
+ }
+ if (jcp.bia_dt != data_type::f32)
+ vcvtdq2ps(vreg_bias, vreg_bias);
+ vmulps(vreg_bias, vreg_bias, zmm_bias_alpha); // *alpha
+ }
+ for(int y = 0; y < jcp.m; y++) {
+ kmovw(y_mask, ptr[ reg_ptr_v_y_masks + sizeof(uint16_t) * y ]);
+ for(int x = 0; x < jcp.m; x++) {
+ kandw(r_mask, y_mask, x_mask(x));
+
+ int i = y * jcp.m + x;
+ int offset = jcp.typesize_out *
+ (y * jcp.ow * jcp.oc + x * jcp.oc);
+ Address addr = EVEX_compress_addr(reg_aux_ptr_dst, offset);
+
+ Zmm zmm = vreg_out(i);
+ Xmm xmm = xmm_out(i);
+ vcvtdq2ps(zmm, zmm);
+ if (jcp.with_bias)
+ vaddps(zmm, zmm, vreg_bias);
+ vmulps(zmm, zmm, ptr [reg_ptr_scales]);
+ if (maybe_relu(0))
+ vmaxps(zmm, vreg_zero, zmm);
+ if (p_sum_scale) { // post_op: sum
+ vpxord(vreg_prev_dst, vreg_prev_dst, vreg_prev_dst);
+ switch (jcp.dst_dt) {
+ case data_type::f32:
+ case data_type::s32:
+ vmovups(vreg_prev_dst | r_mask, addr); break;
+ case data_type::s8:
+ vpmovsxbd(vreg_prev_dst | r_mask, addr); break;
+ case data_type::u8:
+ vpmovzxbd(vreg_prev_dst | r_mask, addr); break;
+ default: assert(!"unknown dst_dt");
+ }
+ if (jcp.dst_dt != data_type::f32)
+ vcvtdq2ps(vreg_prev_dst, vreg_prev_dst);
+ if (*p_sum_scale == 1.f)
+ vaddps(zmm, vreg_prev_dst);
+ else
+ vfmadd231ps(zmm, vreg_prev_dst,
+ zword_b[reg_ptr_sum_scale]);
+ }
+ if (maybe_relu(1))
+ vmaxps(zmm, vreg_zero, zmm);
+ if (jcp.dst_dt != data_type::f32)
+ vcvtps2dq(zmm, zmm);
+ switch (jcp.dst_dt) {
+ case data_type::f32:
+ case data_type::s32:
+ vmovups(addr, zmm | r_mask); break;
+ case data_type::s8:
+ vpmovsdb(xmm, zmm); vmovups(addr, xmm | r_mask); break;
+ case data_type::u8:
+ vpmovusdb(xmm, zmm); vmovups(addr, xmm | r_mask); break;
+ default: assert(!"unknown dst_dt");
+ }
+ }
+ }
+ };
+
+ preamble();
+
+# define READ_PARAM(reg, field) \
+ mov(reg, ptr[abi_param1 + offsetof(call_params_t, field)])
+ READ_PARAM(reg_ptr_src, wino_dst);
+ READ_PARAM(reg_ptr_dst, dst);
+ READ_PARAM(reg_ptr_v_y_masks, v_y_masks);
+ READ_PARAM(reg_ptr_v_x_masks, v_x_masks);
+ READ_PARAM(reg_ptr_bias, bias);
+ READ_PARAM(reg_ptr_scales, scales);
+# undef READ_PARAM
+
+ if (jcp.with_bias)
+ mov(reg_scratch_bias_alpha, float2int(adj_src_scale * adj_wei_scale));
+
+ mov(reg_aux_ptr_src, reg_ptr_src);
+ mov(reg_aux_ptr_dst, reg_ptr_dst);
+
+ vpxord(vreg_zero, vreg_zero, vreg_zero);
+
+ for (int i = 0; i < jcp.m; i++)
+ kmovw(x_mask(i), ptr[reg_ptr_v_x_masks + sizeof(uint16_t) * i]);
+
+ int oc_blocks = jcp.oc / load_block;
+ mov(reg_oc_block, oc_blocks);
+ L(oc_block_label); {
+ loop_body();
+ add(reg_aux_ptr_src, sizeof(int32_t) * load_block);
+ add(reg_aux_ptr_dst, jcp.typesize_out * load_block);
+
+ add(reg_ptr_scales, jcp.is_oc_scale * sizeof(float) * load_block);
+ add(reg_ptr_bias, sizeof(jcp.typesize_bia) * load_block);
+ }
+ dec(reg_oc_block);
+ jnz(oc_block_label, T_NEAR);
+
+ postamble();
+
+}
+
+/// GEMM kernel ////////////////////////////////////////////////////////////////
+struct jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t)
+ jit_conv_conf_2x3_wino_t jcp;
+ const primitive_attr_t &attr_;
+
+ struct call_params_t {
+ const void *src;
+ const void *dst;
+ const void *wei;
+ const void *dst_b;
+ };
+ void (*ker_)(const call_params_t *);
+
+ void generate();
+ static bool post_ops_ok(jit_conv_conf_2x3_wino_t &jcp,
+ const primitive_attr_t &attr);
+
+ jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t(
+ jit_conv_conf_2x3_wino_t ajcp, const primitive_attr_t &attr)
+ : jcp(ajcp), attr_(attr)
+ {
+ generate();
+ ker_ = reinterpret_cast<decltype(ker_)>(const_cast<uint8_t*>(getCode()));
+ }
+
+ static status_t init_conf(
+ jit_conv_conf_2x3_wino_t &jcp, const convolution_desc_t &cd,
+ memory_desc_t &src_md, memory_desc_t &weights_md,
+ memory_desc_t &dst_md, memory_desc_t &bias_md,
+ const primitive_attr_t &attr);
+
+ Zmm vreg_out(int n, int m) {
+ const int id_reg_out = n * jcp.m_block + m;
+ assert(id_reg_out < jcp.n2_block * jcp.m_block);
+ return Zmm(31 - id_reg_out);
+ }
+ Zmm vreg_wei(int i) {
+ assert(31 - jcp.n2_block * jcp.m_block - i
+ > (jcp.ver == ver_vnni ? 0 : 2));
+ return Zmm(31 - jcp.n2_block * jcp.m_block - i);
+ }
+
+ Zmm vreg_src = Zmm(0);
+ Zmm vreg_one = Zmm(1);
+ Zmm vreg_tmp = Zmm(2);
+
+ Reg64 reg_ptr_src = r15;
+
+ Reg64 reg_aux_dst_b = r13;
+ Reg64 reg_aux_dst = r12;
+ Reg64 reg_aux_dst2 = r11;
+ Reg64 reg_aux_wei = r10;
+ Reg64 reg_aux_wei2 = r9;
+ Reg64 reg_aux_src = r8;
+ Reg64 reg_aux_src2 = rax;
+ Reg64 reg_mb = rbx;
+ Reg64 reg_nnb = abi_not_param1;
+ Reg64 reg_scratch = rdx;
+ Reg64 reg_K = rsi;
+};
+
+bool jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t::post_ops_ok(
+ jit_conv_conf_2x3_wino_t &jcp, const primitive_attr_t &attr) {
+ using namespace primitive_kind;
+ const auto &p = attr.post_ops_;
+
+ auto is_relu = [&](int idx) { return p.entry_[idx].is_relu(); };
+
+ switch (p.len_) {
+ case 0: return true;
+ case 1: return is_relu(0) || p.contain(sum, 0);
+ case 2: return (p.contain(sum, 0) && is_relu(1)) ||
+ (p.contain(sum, 1) && is_relu(0));
+ case 3: return is_relu(0) && p.contain(sum, 1) && is_relu(2);
+ default: return false;
+ }
+
+ return false;
+}
+
+void jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t::generate() {
+ Label nnb_loop_label, K_loop_label, mb_loop_label;
+
+ auto compute = [=](Zmm vreg_acc, Zmm vreg_wei, Zmm vreg_src) {
+ if (jcp.ver == ver_vnni) {
+ vpdpbusd(vreg_acc, vreg_src, vreg_wei);
+ } else {
+ vpmaddubsw(vreg_tmp, vreg_src, vreg_wei);
+ vpmaddwd(vreg_tmp, vreg_tmp, vreg_one);
+ vpaddd(vreg_acc, vreg_acc, vreg_tmp);
+ }
+ };
+
+ preamble();
+# define READ_PARAM(reg, field) \
+ mov(reg, ptr[abi_param1 + offsetof(call_params_t, field)])
+ READ_PARAM(reg_ptr_src, src);
+ READ_PARAM(reg_aux_dst, dst);
+ READ_PARAM(reg_aux_wei, wei);
+ READ_PARAM(reg_aux_dst_b, dst_b);
+# undef READ_PARAM
+
+ if (jcp.ver != ver_vnni) {
+ xor_(reg_scratch, reg_scratch);
+ Reg16 _t = reg_scratch.cvt16();
+ mov(_t, 0x1);
+ vpbroadcastw(vreg_one, _t);
+ }
+
+ if (!jcp.small_mb) {
+ mov(reg_nnb, jcp.n_chunks);
+ L(nnb_loop_label);
+ }
+ mov(reg_aux_dst2, reg_aux_dst);
+ mov(reg_aux_src, reg_ptr_src);
+ mov(reg_mb, jcp.M / jcp.m_block);
+ L(mb_loop_label);
+ {
+ for (int nb2 = 0; nb2 < jcp.n2_block; nb2++) {
+ for (int m = 0; m < jcp.m_block; m++) {
+ int offset = jcp.typesize_acc * nb2 * jcp.n_block;
+ vmovups(vreg_out(nb2, m),
+ EVEX_compress_addr(reg_aux_dst_b, offset));
+ }
+ }
+ mov(reg_aux_src2, reg_aux_src);
+ mov(reg_aux_wei2, reg_aux_wei);
+ mov(reg_K, jcp.k_chunks);
+ L(K_loop_label);
+ {
+ for (int k = 0; k < jcp.k2_block; k += 4) {
+ for (int nb2 = 0; nb2 < jcp.n2_block; nb2++) {
+ int wei_offset
+ = jcp.typesize_in * (nb2 * jcp.n_block * jcp.K);
+ vmovups(vreg_wei(nb2),
+ EVEX_compress_addr(reg_aux_wei2, wei_offset));
+ }
+ for (int m = 0; m < jcp.m_block; m++) {
+ int inp_offset = jcp.typesize_in * m * jcp.K;
+ vpbroadcastd(vreg_src,
+ EVEX_compress_addr(reg_aux_src2, inp_offset));
+ for (int nb2 = 0; nb2 < jcp.n2_block; nb2++)
+ compute(vreg_out(nb2, m), vreg_wei(nb2), vreg_src);
+ }
+ add(reg_aux_src2, jcp.typesize_in * 4);
+ add(reg_aux_wei2, jcp.typesize_in * 4 * jcp.n_block);
+ }
+ }
+ dec(reg_K);
+ jnz(K_loop_label, T_NEAR);
+
+ for (int m = 0; m < jcp.m_block; m++) {
+ for (int nb2 = 0; nb2 < jcp.n2_block; nb2++) {
+ int offset = jcp.typesize_acc * (m * jcp.N + nb2 * jcp.n_block);
+ vmovups(EVEX_compress_addr(reg_aux_dst2, offset),
+ vreg_out(nb2, m));
+ }
+ }
+ add(reg_aux_src, jcp.typesize_in * jcp.m_block * jcp.K);
+ add(reg_aux_dst2, jcp.typesize_acc * jcp.m_block * jcp.N);
+ }
+ dec(reg_mb);
+ jnz(mb_loop_label, T_NEAR);
+
+ if (!jcp.small_mb) {
+ add(reg_aux_dst, jcp.typesize_acc * jcp.n2_block * jcp.n_block);
+ add(reg_aux_dst_b, jcp.typesize_acc * jcp.n2_block * jcp.n_block);
+ add(reg_aux_wei, jcp.typesize_in * jcp.n2_block * jcp.n_block * jcp.K);
+
+ dec(reg_nnb);
+ jnz(nnb_loop_label, T_NEAR);
+ }
+
+ postamble();
+}
+namespace {
+bool is_winograd_faster_than_direct(const jit_conv_conf_2x3_wino_t &jcp) {
+ if (jcp.ver == ver_vnni) {
+ return (jcp.mb <= mkldnn_get_max_threads()
+ && (jcp.mb > 4
+ && jcp.ic > 64
+ && !(jcp.oc > 128 && jcp.ih < 14)))
+ || jcp.mb > mkldnn_get_max_threads();
+ }
+ return true;
+}
+}
+
+status_t jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t
+::init_conf(jit_conv_conf_2x3_wino_t &jcp,
+ const convolution_desc_t &cd, memory_desc_t &src_md,
+ memory_desc_t &wei_md, memory_desc_t &dst_md,
+ memory_desc_t &bias_md, const primitive_attr_t &attr) {
+ const memory_desc_wrapper src_d(&src_md);
+ const memory_desc_wrapper wei_d(&wei_md);
+ const memory_desc_wrapper dst_d(&dst_md);
+ const memory_desc_wrapper bias_d(&bias_md);
+
+ const bool with_groups = wei_d.ndims() == src_d.ndims() + 1;
+
+ jcp.nthr = mkldnn_get_max_threads();
+
+ jcp.ngroups = with_groups ? wei_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+ jcp.ih = src_d.dims()[2];
+ jcp.iw = src_d.dims()[3];
+ jcp.oh = dst_d.dims()[2];
+ jcp.ow = dst_d.dims()[3];
+ jcp.kh = wei_d.dims()[with_groups + 2];
+ jcp.kw = wei_d.dims()[with_groups + 3];
+ jcp.t_pad = cd.padding[0][0];
+ jcp.b_pad = cd.padding[1][0];
+ jcp.l_pad = cd.padding[0][1];
+ jcp.r_pad = cd.padding[1][1];
+ jcp.stride_h = cd.strides[0];
+ jcp.stride_w = cd.strides[1];
+ jcp.dilate_h = cd.dilates[0];
+ jcp.dilate_w = cd.dilates[1];
+
+ jcp.ver = ver_avx512_core;
+ if (!(mayiuse(avx512_core) &&
+ src_d.data_type() == data_type::u8
+ && wei_d.data_type() == data_type::s8
+ && one_of(dst_d.data_type(), data_type::f32, data_type::s32,
+ data_type::s8, data_type::u8)))
+ return status::unimplemented;
+ if (mayiuse(avx512_core_vnni))
+ jcp.ver = ver_vnni;
+
+ if (!IMPLICATION(cd.alg_kind == alg_kind::convolution_auto,
+ is_winograd_faster_than_direct(jcp)))
+ return status::unimplemented;
+
+ // block sizes needed for GEMM kernel
+ jcp.ic_block = 4;
+ jcp.oc_block = 16;
+
+ bool ok = true
+ && jcp.ngroups == 1
+ && jcp.oc % load_block == 0 && jcp.ic % load_block == 0
+ && jcp.oc % jcp.oc_block == 0 && jcp.ic % jcp.ic_block == 0
+ && everyone_is(3, jcp.kh, jcp.kw)
+ && everyone_is(1, jcp.stride_h, jcp.stride_w)
+ && everyone_is(0, jcp.dilate_h, jcp.dilate_w)
+ && jcp.t_pad == jcp.b_pad && jcp.l_pad == jcp.r_pad
+ && one_of(jcp.t_pad, 0, 1)
+ && one_of(jcp.l_pad, 0, 1);
+ if (!ok) return status::unimplemented;
+
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ jcp.bia_dt = jcp.with_bias ? cd.bias_desc.data_type : data_type::undef;
+ jcp.dst_dt = cd.dst_desc.data_type;
+
+ jcp.typesize_in = types::data_type_size(src_d.data_type());
+ jcp.typesize_out = types::data_type_size(dst_d.data_type());
+ jcp.typesize_acc = sizeof(int32_t);
+ jcp.typesize_bia = jcp.with_bias
+ ? types::data_type_size(bias_d.data_type())
+ : 0;
+
+ jcp.nb_oc = jcp.oc / jcp.oc_block;
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+
+ jcp.m = 2;
+ jcp.r = 3;
+ jcp.alpha = jcp.m + jcp.r - 1;
+
+ int aa = jcp.alpha * jcp.alpha;
+ int L1_cap = get_cache_size(1, true);
+ int L2_cap = get_cache_size(2, true);
+ // need 1 extra reg for bcast, and 2 tmp regs for non-vnni
+ int free_regs = jcp.ver == ver_vnni ? 31 : 29;
+
+ auto get_thr_eff = [&](int small_mb, int ix, int iy, int n2_b) {
+ float thr_eff;
+ float Z = (float)jcp.ic + jcp.oc;
+ float Y = (float)jcp.ic * jcp.oc;
+ if (small_mb == 0) { // outer par
+ int nblocks = jcp.mb * div_up(jcp.oh, iy) * div_up(jcp.ow, ix);
+ thr_eff = (float)nblocks / rnd_up(nblocks, jcp.nthr);
+ } else { // inner par
+ int tranw = iy * ix / jcp.alpha;
+ int gemmw = aa * (jcp.nb_oc / n2_b);
+ int tranw_r = rnd_up(tranw, jcp.nthr);
+ int gemmw_r = rnd_up(gemmw, jcp.nthr);
+ thr_eff = (Z * tranw / tranw_r + Y * gemmw / gemmw_r) / (Z + Y);
+ }
+ return thr_eff;
+ };
+
+ auto get_mem_eff = [&](int small_mb, int ix, int iy, int n2_b) {
+ float mem_eff, req_mem;
+ int M = ix * iy / jcp.alpha;
+ if (small_mb == 0) { // outer parallelization strategy
+ // memory for wino transforms (other memory has poor reuse)
+ req_mem = (float)aa * M * (jcp.ic + jcp.typesize_acc * jcp.oc);
+ mem_eff = req_mem < L1_cap ? 1.f : req_mem < L2_cap ? 0.5f : 0.f;
+ } else { // inner parallelization strategy
+ // memory used during gemm
+ int N = jcp.oc_block * n2_b;
+ req_mem = (float)jcp.ic * (M + N) + jcp.typesize_acc * M * N;
+ mem_eff = nstl::min(1.f, L2_cap / req_mem);
+ // memory used during wino transforms
+ int M_per_thr = div_up(M, jcp.nthr);
+ req_mem = (float)aa * M_per_thr
+ * (jcp.ic + jcp.typesize_acc * jcp.oc);
+ if (req_mem > L2_cap)
+ mem_eff = 0.1f;
+ }
+ return mem_eff;
+ };
+
+ auto get_tot_eff = [&](int small_mb, float thr_eff, float work_eff,
+ float mem_eff, float reg_eff) {
+ // these coefficients are chosen empirically
+ float mem_fac = 0.1f, reg_fac = 0.2f;
+ // normalized overhead relative to memory and register components
+ float tot_eff = 1.f + mem_fac * mem_eff + reg_fac * reg_eff;
+ // thread and work components affect all others
+ tot_eff *= thr_eff * work_eff;
+ return tot_eff;
+ };
+
+ auto find_m_n2_blocks = [&](bool small_mb, int ix, int iy, float work_eff,
+ int &m_block, int &n2_block, float &tot_eff) {
+ int M = (ix * iy) / jcp.alpha;
+ int max_m_block = nstl::min(M, free_regs);
+ int max_n2_block = nstl::min(jcp.nb_oc, free_regs);
+ tot_eff = 0.f;
+ for (int im = max_m_block; im > 0; im--) {
+ if (M % im)
+ continue;
+ for (int in2 = max_n2_block; in2 > 0; in2--) {
+ int used_regs = (im + 1) * in2;
+ float mem_eff = get_mem_eff(small_mb, ix, iy, in2);
+ float reg_eff = (float)(im * in2) / (im + in2);
+ float thr_eff = get_thr_eff(small_mb, ix, iy, in2);
+ float cur_tot_eff = get_tot_eff(
+ small_mb, thr_eff, work_eff, mem_eff, reg_eff);
+ if (jcp.nb_oc % in2 || used_regs > free_regs
+ || cur_tot_eff <= tot_eff)
+ continue;
+ tot_eff = cur_tot_eff;
+ m_block = im;
+ n2_block = in2;
+ }
+ }
+ };
+
+ /* Selecting xb and yb blocking */
+ int min_yb = jcp.m;
+ int min_xb = jcp.m;
+ int max_yb = nstl::max(min_yb, rnd_up(jcp.oh, 2));
+ int max_xb = nstl::max(min_xb, rnd_up(jcp.ow, 2));
+ float best_eff = 0.f;
+ for (int ix = min_xb; ix <= max_xb; ix += 2) {
+ assert(rnd_up(jcp.ow, ix) >= jcp.iw - 2);
+ for (int iy = max_yb; iy >= min_yb; iy -= 2) {
+ assert(rnd_up(jcp.oh, iy) >= jcp.ih - 2);
+
+ int m_b[2];
+ int n2_b[2];
+ bool small_mb;
+ float inner_eff, outer_eff, work_eff;
+
+ int tiled_area = rnd_up(jcp.oh, iy) * rnd_up(jcp.ow, ix);
+ work_eff = (float)jcp.oh * jcp.ow / tiled_area;
+ if (best_eff > 0.f && work_eff < 4.f / 9.f)
+ continue; // no gain from Winograd transformation
+
+ /* outer parallelization */
+ find_m_n2_blocks(0, ix, iy, work_eff, m_b[0], n2_b[0], outer_eff);
+
+ /* inner parallelization */
+ find_m_n2_blocks(1, ix, iy, work_eff, m_b[1], n2_b[1], inner_eff);
+
+ small_mb = inner_eff > outer_eff;
+ float eff = small_mb ? inner_eff : outer_eff;
+ if (eff > best_eff) {
+ best_eff = eff;
+ jcp.yb = iy;
+ jcp.xb = ix;
+ jcp.m_block = m_b[small_mb];
+ jcp.n2_block = n2_b[small_mb];
+ jcp.small_mb = small_mb;
+ }
+ }
+ }
+
+ assert((jcp.m_block + 1) * jcp.n2_block <= free_regs);
+ assert(jcp.xb % 2 == 0 && jcp.yb % 2 == 0);
+
+ jcp.mb_block = 1;
+ if (jcp.small_mb) {
+ // For small mb harness, set mb_block as large as possible subject to
+ // the constraint that winograd activations fit into available L3 cache
+ int L3_cap = get_cache_size(3, true);
+ int M = jcp.xb * jcp.yb / 4;
+ int wino_src_size = 16 * M * jcp.ic * jcp.typesize_in;
+ int wino_dst_size = 16 * M * jcp.oc * jcp.typesize_acc;
+ int max_mb_block = nstl::min(
+ jcp.mb, jcp.nthr * L3_cap / (wino_src_size + wino_dst_size));
+ for (int i = max_mb_block; i > 1; i--) {
+ if (jcp.mb % i == 0) {
+ jcp.mb_block = i;
+ break;
+ }
+ }
+ }
+ jcp.nb_mb = jcp.mb / jcp.mb_block;
+
+ jcp.M = jcp.mb_block * jcp.xb * jcp.yb / 4;
+ jcp.N = jcp.oc;
+ jcp.K = jcp.ic;
+
+ jcp.inp_stride = jcp.M * jcp.ic;
+ jcp.out_stride = jcp.M * jcp.oc;
+ jcp.wei_stride = jcp.ic * jcp.oc;
+ jcp.bia_stride = jcp.oc;
+
+ jcp.n_block = jcp.oc_block;
+ jcp.k_block = jcp.ic_block;
+
+ jcp.n_chunks = (jcp.N / jcp.n_block) / jcp.n2_block;
+
+ // We need jcp.k2_block to be a multiple of jcp.k_block = jcp.ic_block = 4
+ // and jcp.K = jcp.ic to be a multiple of jcp.k2_block. Since jcp.ic is
+ // a multiple of load_block = 16, we just use that for now.
+ jcp.k2_block = load_block;
+ jcp.k_chunks = jcp.K / jcp.k2_block;
+
+ const auto &oscales = attr.output_scales_;
+ jcp.is_oc_scale = oscales.mask_ == 1 << 1;
+ assert(IMPLICATION(!jcp.is_oc_scale, oscales.mask_ == 0));
+
+ /* re-create weights primitive descriptor
+ and set weights wino_blocking */
+ memory_desc_t expect_wei_md = wei_md;
+
+ expect_wei_md.format_kind = format_kind::wino;
+ expect_wei_md.data_type = data_type::s8;
+ mkldnn_wino_desc_t &wd = expect_wei_md.format_desc.wino_desc;
+ wd.wino_format = mkldnn_wino_wei_aaOIoi;
+ wd.r = jcp.r;
+ wd.alpha = jcp.alpha;
+ wd.ic = jcp.ic;
+ wd.oc = jcp.oc;
+ wd.ic_block = jcp.ic_block;
+ wd.oc_block = jcp.oc_block;
+ wd.oc2_block = jcp.n2_block;
+ wd.ic2_block = 1;
+ wd.adj_scale = adj_wei_scale;
+
+ size_t max_size = types::data_type_size(data_type::s8) *
+ jcp.alpha * jcp.alpha * jcp.ic * jcp.oc;
+ max_size += types::data_type_size(data_type::s32) *
+ jcp.alpha * jcp.alpha * jcp.oc;
+ wd.size = max_size;
+
+ if (wei_md.format_kind == format_kind::any)
+ wei_md = expect_wei_md;
+ if (wei_md != expect_wei_md)
+ return status::unimplemented;
+
+ const int tilesize = jcp.alpha * jcp.alpha;
+ const int numtiles = jcp.M;
+ const int alltiles = numtiles * tilesize;
+
+ jcp.size_wino_src
+ = utils::rnd_up(jcp.typesize_in * alltiles * jcp.ic, PAGE_4K)
+ / jcp.typesize_in;
+ jcp.size_wino_wei = tilesize * jcp.oc * jcp.ic;
+ jcp.size_wino_dst = alltiles * jcp.oc;
+
+ return status::success;
+}
+////////////////////////////////////////////////////////////////////////////////
+
+template <data_type_t dst_data_type>
+status_t jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<dst_data_type>::
+ pd_t::jit_conf() {
+ return jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t::init_conf(
+ jcp_, *this->desc(), this->src_md_, this->weights_md_,
+ this->dst_md_,this->bias_md_, *this->attr());
+}
+
+template <data_type_t dst_data_type>
+void jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<dst_data_type>::pd_t::
+init_scratchpad() {
+ auto scratchpad = this->scratchpad_registry().registrar();
+
+ int nthr_multiplier = jcp_.small_mb ? 1 : jcp_.nthr;
+ scratchpad.book(key_wino_V,
+ sizeof(src_data_t) * jcp_.size_wino_src * nthr_multiplier, PAGE_4K);
+ scratchpad.book(key_wino_M,
+ sizeof(acc_data_t) * jcp_.size_wino_dst * nthr_multiplier, PAGE_4K);
+
+ dim_t scale_count = attr()->output_scales_.count_;
+ scratchpad.book(key_conv_adjusted_scales,
+ sizeof(float) * nstl::max<dim_t>(scale_count, 16));
+}
+
+template <data_type_t dst_data_type>
+jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<dst_data_type>::
+ jit_avx512_core_u8s8s32x_wino_convolution_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+{
+ kernel_ = new jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t(
+ pd()->jcp_, *pd()->attr());
+ src_trans_ = new jit_avx512_core_u8s8s32x_wino_conv_src_trans_t(
+ pd()->jcp_, *pd()->attr());
+ dst_trans_ = new jit_avx512_core_u8s8s32x_wino_conv_dst_trans_t(
+ pd()->jcp_, *pd()->attr());
+}
+
+template <data_type_t dst_data_type>
+jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<dst_data_type>::
+ ~jit_avx512_core_u8s8s32x_wino_convolution_fwd_t() {
+ delete kernel_;
+ delete src_trans_;
+ delete dst_trans_;
+}
+
+template <data_type_t dst_data_type>
+const float *jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<dst_data_type>::
+adjust_oscales(const memory_tracking::grantor_t &scratchpad) const {
+ const float *oscales = pd()->attr()->output_scales_.scales_;
+ auto loc_scales = scratchpad.template get<float>(key_conv_adjusted_scales);
+ size_t count = pd()->attr()->output_scales_.count_;
+ float factor = 1.f / (adj_src_scale * adj_wei_scale);
+ if (count == 1)
+ utils::array_set(loc_scales, oscales[0] * factor, 16);
+ else
+ for (size_t c = 0; c < count; c++) loc_scales[c] = oscales[c] * factor;
+ return loc_scales;
+}
+
+template <data_type_t dst_data_type>
+void jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<dst_data_type>::
+execute_forward(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ const auto &jcp = kernel_->jcp;
+ if (jcp.small_mb)
+ execute_forward_small_mb(src, weights, bias, dst, this->scratchpad(ctx));
+ else
+ execute_forward_mbN(src, weights, bias, dst, this->scratchpad(ctx));
+}
+
+template <data_type_t dst_data_type>
+void jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<dst_data_type>::
+execute_forward_mbN(const src_data_t *src, const wei_data_t *wei,
+ const char *bia, dst_data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const {
+ const auto &jcp = kernel_->jcp;
+ const float *oscales = adjust_oscales(scratchpad);
+
+ auto dst_bias = (const acc_data_t *)(wei + jcp.size_wino_wei);
+ auto wino_src_base = scratchpad.template get<src_data_t>(key_wino_V);
+ auto wino_dst_base = scratchpad.template get<acc_data_t>(key_wino_M);
+
+ parallel_nd(jcp.mb, div_up(jcp.oh, jcp.yb), div_up(jcp.ow, jcp.xb),
+ [&](int mb, int tile_y_b, int tile_x_b) {
+
+ int tile_y = tile_y_b * jcp.yb;
+ int tile_x = tile_x_b * jcp.xb;
+
+ int ithr = mkldnn_get_thread_num();
+ auto wino_src = wino_src_base + jcp.size_wino_src * ithr;
+ auto wino_dst = wino_dst_base + jcp.size_wino_dst * ithr;
+
+ auto src_trans_p =
+ jit_avx512_core_u8s8s32x_wino_conv_src_trans_t::call_params_t();
+ auto dst_trans_p =
+ jit_avx512_core_u8s8s32x_wino_conv_dst_trans_t::call_params_t();
+ auto gemm_p =
+ jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t::call_params_t();
+
+ /* transformation of input tensor to winograd domain */
+ for (int y_in_block = 0; y_in_block < jcp.yb; y_in_block += 2) {
+ for (int x_in_block = 0; x_in_block < jcp.xb; x_in_block += 2) {
+ uint16_t v_y_masks[4], v_x_masks[4];
+
+ int y = y_in_block + tile_y;
+ int x = x_in_block + tile_x;
+ int m = (y_in_block / 2) * (jcp.xb / 2) + (x_in_block / 2);
+
+ int v_ys = nstl::max(0, jcp.t_pad - y);
+ int v_ye = nstl::min(jcp.alpha,
+ nstl::max(0, jcp.ih + jcp.t_pad - y));
+
+ int v_xs = nstl::max(0, jcp.l_pad - x);
+ int v_xe = nstl::min(jcp.alpha,
+ nstl::max(0, jcp.iw + jcp.l_pad - x));
+
+#pragma unroll(4)
+ for (int i = 0; i < jcp.alpha; i++) {
+ v_y_masks[i] = uint16_t(i < v_ys || i >= v_ye ? 0 : 0xffff);
+ v_x_masks[i] = uint16_t(i < v_xs || i >= v_xe ? 0 : 0xffff);
+ }
+ auto local_s = src
+ + mb * jcp.ih * jcp.iw * jcp.ic
+ + y * jcp.iw * jcp.ic + x * jcp.ic;
+ auto local_w = wino_src + m * jcp.ic;
+
+ src_trans_p.src = local_s;
+ src_trans_p.wino_src = local_w;
+ src_trans_p.v_y_masks = v_y_masks;
+ src_trans_p.v_x_masks = v_x_masks;
+
+ src_trans_->ker_(&src_trans_p);
+ }
+ }
+ /* gemms */
+ for (int tile_ij = 0; tile_ij < 16; tile_ij++) {
+ // start threads at different GEMMs to help bring weights into LLC
+ int offset = (tile_ij + ithr) % 16;
+ gemm_p.src = wino_src + jcp.inp_stride * offset;
+ gemm_p.dst = wino_dst + jcp.out_stride * offset;
+ gemm_p.wei = wei + jcp.wei_stride * offset;
+ gemm_p.dst_b = dst_bias + jcp.bia_stride * offset;
+
+ kernel_->ker_(&gemm_p);
+ }
+
+ /* transformation from winograd domain to output tensor */
+ for (int y_in_block = 0; y_in_block < jcp.yb; y_in_block += 2) {
+ for (int x_in_block = 0; x_in_block < jcp.xb; x_in_block += 2) {
+ uint16_t v_y_masks[2], v_x_masks[2];
+
+ int y = y_in_block + tile_y;
+ int x = x_in_block + tile_x;
+ int m = (y_in_block / 2) * (jcp.xb / 2) + (x_in_block / 2);
+
+#pragma unroll(2)
+ for (int i = 0; i < jcp.m; i++) {
+ v_x_masks[i] = uint16_t(x + i < jcp.ow ? 0xffff : 0);
+ v_y_masks[i] = uint16_t(y + i < jcp.oh ? 0xffff : 0);
+ }
+ auto local_d = dst
+ + mb * jcp.oh * jcp.ow * jcp.oc
+ + y * jcp.ow * jcp.oc + x * jcp.oc;
+ auto local_w = wino_dst + m * jcp.oc;
+
+ auto scales = oscales;
+ dst_trans_p.dst = local_d;
+ dst_trans_p.wino_dst = local_w;
+ dst_trans_p.v_y_masks = v_y_masks;
+ dst_trans_p.v_x_masks = v_x_masks;
+
+ dst_trans_p.scales = scales;
+ dst_trans_p.bias = bia;
+
+ dst_trans_->ker_(&dst_trans_p);
+ }
+ }
+ });
+}
+
+template <data_type_t dst_data_type>
+void jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<dst_data_type>::
+execute_forward_small_mb(const src_data_t *src, const wei_data_t *wei,
+ const char *bia, dst_data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const {
+ const auto &jcp = kernel_->jcp;
+ const float *oscales = adjust_oscales(scratchpad);
+
+ auto dst_bias = (const acc_data_t *)(wei + jcp.size_wino_wei);
+ auto wino_src = scratchpad.template get<src_data_t>(key_wino_V);
+ auto wino_dst = scratchpad.template get<acc_data_t>(key_wino_M);
+
+ for (int mbb = 0; mbb < jcp.nb_mb; mbb++) {
+ for (int tile_y = 0; tile_y < jcp.oh; tile_y += jcp.yb) {
+ for (int tile_x = 0; tile_x < jcp.ow; tile_x += jcp.xb) {
+ /* transformation of input tensor to winograd domain */
+ parallel_nd(div_up(jcp.yb, 2), div_up(jcp.xb, 2), jcp.mb_block,
+ [&](int y_in_block_b, int x_in_block_b, int mb) {
+ int y_in_block = y_in_block_b * 2;
+ int x_in_block = x_in_block_b * 2;
+
+ auto src_trans_p =
+ jit_avx512_core_u8s8s32x_wino_conv_src_trans_t::call_params_t();
+
+ uint16_t v_y_masks[4], v_x_masks[4];
+
+ int y = y_in_block + tile_y;
+ int x = x_in_block + tile_x;
+ int m = (mb * (jcp.yb / 2) + (y_in_block / 2)) * (jcp.xb / 2)
+ + (x_in_block / 2);
+
+ int v_ys = nstl::max(0, jcp.t_pad - y);
+ int v_ye = nstl::min(
+ jcp.alpha, nstl::max(0, jcp.ih + jcp.t_pad - y));
+
+ int v_xs = nstl::max(0, jcp.l_pad - x);
+ int v_xe = nstl::min(
+ jcp.alpha, nstl::max(0, jcp.iw + jcp.l_pad - x));
+
+#pragma unroll(4)
+ for (int i = 0; i < jcp.alpha; i++) {
+ v_y_masks[i] = uint16_t(i < v_ys || i >= v_ye ? 0 : 0xffff);
+ v_x_masks[i] = uint16_t(i < v_xs || i >= v_xe ? 0 : 0xffff);
+ }
+ auto local_s = src
+ + (mbb * jcp.mb_block + mb) * jcp.ih * jcp.iw * jcp.ic
+ + y * jcp.iw * jcp.ic + x * jcp.ic;
+ auto local_w = wino_src + m * jcp.ic;
+
+ src_trans_p.src = local_s;
+ src_trans_p.wino_src = local_w;
+ src_trans_p.v_y_masks = v_y_masks;
+ src_trans_p.v_x_masks = v_x_masks;
+
+ src_trans_->ker_(&src_trans_p);
+ });
+
+ /* gemms */
+ parallel_nd(16, jcp.n_chunks, [&](int tile_ij, int nnb) {
+ auto gemm_p = jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t::
+ call_params_t();
+
+ gemm_p.src = wino_src + jcp.inp_stride * tile_ij;
+ gemm_p.dst = wino_dst + jcp.out_stride * tile_ij
+ + nnb * jcp.n2_block * jcp.n_block;
+ gemm_p.wei = wei + jcp.wei_stride * tile_ij
+ + nnb * jcp.n2_block * jcp.n_block * jcp.K;
+ gemm_p.dst_b = dst_bias + jcp.bia_stride * tile_ij
+ + nnb * jcp.n2_block * jcp.n_block;
+
+ kernel_->ker_(&gemm_p);
+ });
+
+ /* transformation from winograd domain to output tensor */
+ parallel_nd(div_up(jcp.yb, 2), div_up(jcp.xb, 2), jcp.mb_block,
+ [&](int y_in_block_b, int x_in_block_b, int mb) {
+ int y_in_block = y_in_block_b * 2;
+ int x_in_block = x_in_block_b * 2;
+
+ auto dst_trans_p =
+ jit_avx512_core_u8s8s32x_wino_conv_dst_trans_t::call_params_t();
+
+ uint16_t v_y_masks[2], v_x_masks[2];
+
+ int y = y_in_block + tile_y;
+ int x = x_in_block + tile_x;
+ int m = (mb * (jcp.yb / 2) + (y_in_block / 2)) * (jcp.xb / 2)
+ + (x_in_block / 2);
+
+#pragma unroll(2)
+ for (int i = 0; i < jcp.m; i++) {
+ v_x_masks[i] = uint16_t(x + i < jcp.ow ? 0xffff : 0);
+ v_y_masks[i] = uint16_t(y + i < jcp.oh ? 0xffff : 0);
+ }
+ auto local_d = dst
+ + (mbb * jcp.mb_block + mb) * jcp.oh * jcp.ow * jcp.oc
+ + y * jcp.ow * jcp.oc + x * jcp.oc;
+ auto local_w = wino_dst + m * jcp.oc;
+
+ auto scales = oscales;
+ dst_trans_p.dst = local_d;
+ dst_trans_p.wino_dst = local_w;
+ dst_trans_p.v_y_masks = v_y_masks;
+ dst_trans_p.v_x_masks = v_x_masks;
+
+ dst_trans_p.scales = scales;
+ dst_trans_p.bias = bia;
+
+ dst_trans_->ker_(&dst_trans_p);
+ });
+ }}}
+}
+
+template struct jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<data_type::s8>;
+template struct jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<data_type::u8>;
+template struct jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<data_type::s32>;
+template struct jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<data_type::f32>;
+
+} // namespace cpu
+} // namespace impl
+} // namespace mkldnn
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_u8s8s32x_wino_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_u8s8s32x_wino_convolution.hpp
new file mode 100644
index 0000000000..9e6e57b051
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_u8s8s32x_wino_convolution.hpp
@@ -0,0 +1,128 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_CORE_U8S8S32X_WINO_CONVOLUTION_HPP
+#define CPU_JIT_AVX512_CORE_U8S8S32X_WINO_CONVOLUTION_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "jit_primitive_conf.hpp"
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t;
+struct jit_avx512_core_u8s8s32x_wino_conv_src_trans_t;
+struct jit_avx512_core_u8s8s32x_wino_conv_dst_trans_t;
+
+template <data_type_t dst_data_type>
+struct jit_avx512_core_u8s8s32x_wino_convolution_fwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_()
+ {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_int8_wino:", avx512_core, ""),
+ jit_avx512_core_u8s8s32x_wino_convolution_fwd_t<dst_data_type>);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && utils::one_of(desc()->alg_kind,
+ alg_kind::convolution_auto,
+ alg_kind::convolution_winograd)
+ && expect_data_types(data_type::u8, data_type::s8,
+ data_type::undef, dst_data_type, data_type::s32)
+ && IMPLICATION(with_bias(), utils::one_of(
+ desc()->bias_desc.data_type, data_type::f32,
+ data_type::s32, data_type::s8, data_type::u8))
+ && !has_zero_dim_memory()
+ && set_default_formats();
+
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_conf();
+ if (status != status::success) return status;
+ set_default_alg_kind(alg_kind::convolution_winograd);
+
+ init_scratchpad();
+
+ return status;
+ }
+
+ jit_conv_conf_2x3_wino_t jcp_;
+
+ protected:
+ status_t jit_conf();
+ void init_scratchpad();
+
+ bool set_default_formats() {
+ using namespace format_tag;
+ return set_default_formats_common(nhwc, any, nhwc);
+ }
+ };
+
+ typedef typename prec_traits<data_type::u8>::type src_data_t;
+ typedef typename prec_traits<data_type::s8>::type wei_data_t;
+ typedef typename prec_traits<data_type::s32>::type acc_data_t;
+ typedef typename prec_traits<dst_data_type>::type dst_data_t;
+
+ jit_avx512_core_u8s8s32x_wino_convolution_fwd_t(const pd_t *apd);
+ ~jit_avx512_core_u8s8s32x_wino_convolution_fwd_t();
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ const float *adjust_oscales(const memory_tracking::grantor_t &scratchpad)
+ const;
+ void execute_forward(const exec_ctx_t &ctx) const;
+ void execute_forward_small_mb(const src_data_t *src, const wei_data_t *wei,
+ const char *bia, dst_data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const;
+ void execute_forward_mbN(const src_data_t *src, const wei_data_t *wei,
+ const char *bia, dst_data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx512_core_u8s8s32x_wino_conv_fwd_ker_t *kernel_;
+ jit_avx512_core_u8s8s32x_wino_conv_src_trans_t *src_trans_;
+ jit_avx512_core_u8s8s32x_wino_conv_dst_trans_t *dst_trans_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_conv_kernel.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_conv_kernel.cpp
new file mode 100644
index 0000000000..f4ec29ab00
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_conv_kernel.cpp
@@ -0,0 +1,820 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_memory.hpp"
+
+#include "jit_uni_1x1_conv_utils.hpp"
+#include "jit_avx512_core_x8s8s32x_1x1_conv_kernel.hpp"
+
+#define GET_OFF(field) offsetof(jit_1x1_conv_call_s, field)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::utils;
+
+using namespace Xbyak;
+
+bool jit_avx512_core_x8s8s32x_1x1_conv_kernel::maybe_eltwise(int position)
+{
+ using namespace primitive_kind;
+ const auto &p = attr_.post_ops_;
+
+ if (position == 0) {
+ /* eltwise before sum */
+ return p.contain(eltwise, 0);
+ } else if (position == 1) {
+ /* eltwise after sum */
+ return p.contain(sum, 0) && p.contain(eltwise, 1);
+ }
+
+ return false;
+}
+
+void jit_avx512_core_x8s8s32x_1x1_conv_kernel::bcast_loop(int load_loop_blk)
+{
+ mov(aux1_reg_bcast_data, reg_bcast_data);
+ mov(aux_reg_bcast_data, reg_bcast_data);
+
+ mov(aux_reg_output_data, reg_output_data);
+ mov(bcast_loop_iter, EVEX_compress_addr(rsp, bcast_loop_work_off));
+
+ Label bcast_loop;
+ Label bcast_loop_tail;
+
+ cmp(bcast_loop_iter, jcp.ur);
+ jl(bcast_loop_tail, T_NEAR);
+
+ L(bcast_loop); {
+ assert(jcp.bcast_block % jcp.ur == 0);
+ int num_substeps = jcp.bcast_block / jcp.ur;
+ assert(num_substeps > 0 && num_substeps < 10);
+ for (int i = 0; i < num_substeps; i++) {
+ reduce_loop(load_loop_blk, jcp.ur, i, false);
+ if (i < num_substeps - 1) {
+ add(aux1_reg_bcast_data, jcp.bcast_loop_bcast_substep);
+ add(aux_reg_output_data, jcp.bcast_loop_output_substep);
+ }
+ else {
+ add(aux1_reg_bcast_data, jcp.bcast_loop_bcast_step
+ - (num_substeps - 1) * jcp.bcast_loop_bcast_substep);
+ int output_offset = jcp.bcast_loop_output_step
+ - (num_substeps - 1) * jcp.bcast_loop_output_substep;
+
+ add(aux_reg_output_data, output_offset);
+ }
+ }
+ sub(bcast_loop_iter, jcp.bcast_block);
+ cmp(bcast_loop_iter, jcp.bcast_block);
+ jge(bcast_loop, T_NEAR);
+ }
+
+ L(bcast_loop_tail);
+ if (jcp.ur_tail) {
+ Label bcast_loop_tail_out;
+ cmp(bcast_loop_iter, 0);
+ jz(bcast_loop_tail_out, T_NEAR);
+ reduce_loop(load_loop_blk, jcp.ur_tail, 0, true);
+ L(bcast_loop_tail_out);
+ }
+}
+
+void jit_avx512_core_x8s8s32x_1x1_conv_kernel::cvt2ps(data_type_t type_in,
+ zmm_t zmm_in, const Xbyak::Operand &op, bool mask_flag) {
+ zmm_t zmm = mask_flag ? zmm_in | ktail_mask | T_z : zmm_in;
+ switch (type_in) {
+ case data_type::f32:
+ case data_type::s32: vmovups(zmm, op); break;
+ case data_type::s8: vpmovsxbd(zmm, op); break;
+ case data_type::u8: vpmovzxbd(zmm, op); break;
+ default: assert(!"unsupported data type");
+ }
+ if (type_in != data_type::f32)
+ vcvtdq2ps(zmm_in, zmm_in);
+}
+
+void jit_avx512_core_x8s8s32x_1x1_conv_kernel::reduce_loop(int load_loop_blk,
+ int ur, int substep, bool wraparound)
+{
+ auto vreg_load = [=](int i_load) {
+ return Zmm(ur * load_loop_blk + i_load);
+ };
+
+ auto vreg_accum = [=](int i_load, int i_ur) {
+ return Zmm(i_ur * load_loop_blk + i_load);
+ };
+
+ auto zmm_bias_alpha = [=]() {
+ return Zmm(ur * load_loop_blk);
+ };
+
+ auto xmm_bias_alpha = [=]() {
+ return Xmm(ur * load_loop_blk);
+ };
+ auto bias_ptr = [=](int i_load) {
+ return EVEX_compress_addr(reg_bias_data,
+ jcp.typesize_bia * jcp.oc_block * i_load);
+ };
+
+ auto comp_ptr = [=](int i_load) {
+ return EVEX_compress_addr(reg_comp_data,
+ sizeof(int32_t) * jcp.oc_block * i_load);
+ };
+
+ auto scale_ptr = [=](int i_load) {
+ return EVEX_compress_addr(reg_ptr_scales,
+ jcp.is_oc_scale * (sizeof(float) * jcp.oc_block * i_load));
+ };
+
+ auto bcast_ptr = [=](int i_reduce, int i_ur, bool bcast) {
+ assert(i_ur < jcp.ur);
+ assert(i_reduce <= jcp.reduce_loop_unroll);
+ assert(jcp.reduce_loop_unroll == jcp.reduce_block);
+
+ int offt = (jcp.ic_without_padding * i_ur + i_reduce);
+
+ return EVEX_compress_addr(aux_reg_bcast_data, jcp.typesize_in * offt,
+ bcast);
+ };
+
+ auto load_ptr = [=](int i_reduce, int i_load) {
+ int u0 = i_reduce % jcp.reduce_loop_unroll;
+ int u1 = i_reduce / jcp.reduce_loop_unroll;
+
+ int offt = (i_load * jcp.reduce_dim + u0) * jcp.load_block;
+
+ return EVEX_compress_addr(aux_reg_load_data,
+ u1 * jcp.reduce_loop_load_step
+ + jcp.typesize_in * offt);
+ };
+
+ auto output_ptr = [=](int i_load, int i_ur) {
+ return EVEX_compress_addr(aux_reg_output_data,
+ jcp.typesize_out * (jcp.oc_without_padding * i_ur
+ + i_load * jcp.load_block));
+ };
+
+ auto init = [=]() {
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load)
+ for (int i_ur = 0; i_ur < ur; ++i_ur) {
+ auto r = vreg_accum(i_load, i_ur);
+ vpxord(r, r, r);
+ }
+ if (jcp.signed_input) {
+ xor_(reg_scratch, reg_scratch);
+ Reg8 _t8 = reg_scratch.cvt8();
+ mov(_t8, (int8_t)-128);
+ vpbroadcastb(zmm_shift, _t8);
+ }
+ };
+
+ auto store = [=](const bool mask_flag_in) {
+ const auto &p = attr_.post_ops_;
+ const int sum_idx = p.find(primitive_kind::sum);
+ const float *p_sum_scale = (sum_idx != -1)
+ ? &p.entry_[sum_idx].sum.scale
+ : nullptr;
+ mov(EVEX_compress_addr(rsp, reg_bcast_data_off), reg_bcast_data);
+ mov(reg_ptr_scales, EVEX_compress_addr(rsp, reg_ptr_sum_scale_off));
+ if (p_sum_scale && *p_sum_scale != 1.f) {
+ mov(EVEX_compress_addr(rsp, reg_load_data_off), reg_load_data);
+ mov(reg_ptr_sum_scale, (size_t)p_sum_scale);
+ }
+ if (jcp.signed_input && jcp.ver != ver_vnni) {
+ mov(reg_scratch, float2int(jcp.wei_adj_scale));
+ vmovq(xmm_bias_alpha(), reg_scratch);
+ vbroadcastss(zmm_bias_alpha(), xmm_bias_alpha());
+ }
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load) {
+ const bool mask_flag = mask_flag_in && i_load == load_loop_blk - 1;
+ auto zmm_bias = zmm_tmp;
+ auto zmm_comp = zmm_bcast;
+ if (jcp.with_bias) {
+ if (jcp.signed_input)
+ mov(reg_bias_data,
+ EVEX_compress_addr(rsp,reg_bias_data_off));
+ cvt2ps(jcp.bia_dt, zmm_bias, bias_ptr(i_load), mask_flag);
+ if (jcp.signed_input && jcp.ver != ver_vnni)
+ vmulps(zmm_bias, zmm_bias, zmm_bias_alpha());
+ }
+ if (jcp.signed_input) {
+ mov(reg_comp_data, EVEX_compress_addr(rsp, reg_comp_data_off));
+ cvt2ps(data_type::s32, zmm_comp, comp_ptr(i_load), mask_flag);
+ }
+
+ for (int i_ur = 0; i_ur < ur; ++i_ur) {
+ auto r = vreg_accum(i_load, i_ur);
+ vcvtdq2ps(r, r);
+ if (jcp.signed_input)
+ vaddps(r, r, zmm_comp);
+ if (jcp.with_bias)
+ vaddps(r, r, zmm_bias);
+
+ zmm_t mask_zmm = mask_flag ? r | ktail_mask | T_z : r;
+ vmulps(mask_zmm, r, scale_ptr(i_load));
+ }
+ }
+
+ if (maybe_eltwise(0))
+ eltwise_injector_->compute_vector_range(0, ur * load_loop_blk);
+
+ if (p_sum_scale) { // post_op: sum
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load) {
+ const bool mask_flag = mask_flag_in &&
+ i_load == load_loop_blk - 1;
+ for (int i_ur = 0; i_ur < ur; ++i_ur) {
+ vpxord(zmm_zero, zmm_zero, zmm_zero);
+ auto zmm_prev_dst = zmm_zero;
+
+ auto r = vreg_accum(i_load, i_ur);
+ cvt2ps(jcp.dst_dt, zmm_prev_dst, output_ptr(i_load, i_ur),
+ mask_flag);
+
+ if (*p_sum_scale == 1.f)
+ vaddps(r, zmm_prev_dst);
+ else
+ vfmadd231ps(r, zmm_prev_dst, zword_b[reg_ptr_sum_scale]);
+ }
+ }
+ }
+
+ if (maybe_eltwise(1))
+ eltwise_injector_->compute_vector_range(0, ur * load_loop_blk);
+
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load) {
+ const bool mask_flag = mask_flag_in &&
+ i_load == load_loop_blk - 1;
+ for (int i_ur = 0; i_ur < ur; ++i_ur) {
+ auto r = vreg_accum(i_load, i_ur);
+ if (jcp.dst_dt == data_type::u8) {
+ vpxord(zmm_zero, zmm_zero, zmm_zero);
+ vmaxps(r, zmm_zero, r);
+ }
+ if (jcp.dst_dt != data_type::f32)
+ vcvtps2dq(r, r);
+ }
+ for (int i_ur = 0; i_ur < ur; ++i_ur) {
+ auto r = vreg_accum(i_load, i_ur);
+ zmm_t r_zmm = mask_flag ? r | ktail_mask : r;
+
+ switch (jcp.dst_dt) {
+ case data_type::f32:
+ case data_type::s32:
+ vmovups(output_ptr(i_load, i_ur), r_zmm); break;
+ case data_type::s8:
+ vpmovsdb(output_ptr(i_load, i_ur), r_zmm); break;
+ case data_type::u8:
+ vpmovusdb(output_ptr(i_load, i_ur), r_zmm); break;
+ default: assert(!"unknown dst_dt");
+ }
+ }
+ }
+ mov(reg_bcast_data, EVEX_compress_addr(rsp, reg_bcast_data_off));
+ if (p_sum_scale && *p_sum_scale != 1.f)
+ mov(reg_load_data, EVEX_compress_addr(rsp, reg_load_data_off));
+ };
+
+ auto compute = [=](Zmm vreg_acc, Zmm vreg_wei, Zmm vreg_src) {
+ if (jcp.ver == ver_vnni) {
+ vpdpbusd(vreg_acc, vreg_src, vreg_wei);
+ } else {
+ vpmaddubsw(zmm_tmp, vreg_src, vreg_wei);
+ vpmaddwd(zmm_tmp, zmm_tmp, zmm_one);
+ vpaddd(vreg_acc, vreg_acc, zmm_tmp);
+ }
+ };
+
+ auto fma_block = [=](bool last_block) {
+ int reduce_step = 4;
+ int tail_size = jcp.ic_without_padding % reduce_step;
+ int loop_unroll = last_block && jcp.ic != jcp.ic_without_padding
+ ? rnd_up(jcp.ic_without_padding % jcp.ic_block, reduce_step)
+ : jcp.reduce_loop_unroll;
+ for (int i_reduce = 0; i_reduce < loop_unroll;
+ i_reduce += reduce_step) {
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load)
+ vmovups(vreg_load(i_load), load_ptr(i_reduce, i_load));
+ for (int i_ur = 0; i_ur < ur; ++i_ur) {
+ if (last_block && tail_size != 0
+ && i_reduce == loop_unroll - reduce_step) {
+ Xmm xmm_bcast = Xmm(zmm_bcast.getIdx());
+ for (int r = 0; r < tail_size; ++r)
+ vpinsrb(xmm_bcast, xmm_bcast, ptr[aux_reg_bcast_data
+ + jcp.ic_without_padding * i_ur + i_reduce + r], r);
+ vpbroadcastd(zmm_bcast, xmm_bcast);
+ } else {
+ vpbroadcastd(zmm_bcast, bcast_ptr(i_reduce, i_ur, false));
+ }
+ if (jcp.signed_input)
+ vpsubb(zmm_bcast, zmm_bcast, zmm_shift);
+ for (int i_load = 0; i_load < load_loop_blk; ++i_load) {
+ compute(vreg_accum(i_load, i_ur),
+ vreg_load(i_load), zmm_bcast);
+ }
+ }
+ }
+ };
+
+ Label reduce_loop;
+ Label reduce_loop_tail;
+
+ mov(aux_reg_load_data, reg_load_data);
+
+ mov(aux_reg_bcast_data, aux1_reg_bcast_data);
+ init();
+
+ mov(reduce_loop_iter, reg_reduce_loop_work);
+ sub(reduce_loop_iter, jcp.reduce_loop_unroll);
+ jle(reduce_loop_tail, T_NEAR);
+
+ L(reduce_loop); {
+ fma_block(false);
+ add(aux_reg_bcast_data, jcp.reduce_loop_bcast_step);
+ add(aux_reg_load_data, jcp.reduce_loop_load_step);
+ sub(reduce_loop_iter, jcp.reduce_loop_unroll);
+ jg(reduce_loop, T_NEAR);
+ }
+
+ L(reduce_loop_tail);
+ if (jcp.ic != jcp.ic_without_padding) {
+ fma_block(true);
+ } else {
+ fma_block(false);
+ }
+
+ if (jcp.oc_without_padding != jcp.oc) {
+ Label end_store, common_store;
+ mov(EVEX_compress_addr(rsp, reg_bcast_data_off), reg_bcast_data);
+
+ /*Check if it is the last load_loop_blk*/
+ sub(reg_load_loop_work, load_loop_blk * jcp.load_loop_iter_step);
+ cmp(reg_load_loop_work, 0);
+ jg(common_store, T_NEAR);
+
+ /*Check if it is the last ocb*/
+ test(reg_reduce_pos_flag, FLAG_OC_LAST);
+ jz(common_store, T_NEAR);
+
+ store(true);
+ jmp(end_store, T_NEAR);
+
+ L(common_store);
+ store(false);
+
+ L(end_store);
+
+ add(reg_load_loop_work, load_loop_blk * jcp.load_loop_iter_step);
+ } else {
+ store(false);
+ }
+}
+
+void jit_avx512_core_x8s8s32x_1x1_conv_kernel::generate()
+{
+ preamble();
+
+ xor_(reg_scratch, reg_scratch);
+ Reg16 _t = reg_scratch.cvt16();
+ mov(_t, 0x1);
+ vpbroadcastw(zmm_one, _t);
+
+ sub(rsp, stack_space_needed);
+
+ if (jcp.oc_without_padding != jcp.oc) {
+ int tail_size = jcp.oc_without_padding % jcp.oc_block;
+ int mask = (1 << tail_size) - 1;
+ Reg32 regw_tmp = reg_last_load.cvt32();
+ mov(regw_tmp, mask);
+ kmovw(ktail_mask, regw_tmp);
+ }
+
+ if (jcp.with_bias)
+ mov(reg_bias_data, ptr[param1 + GET_OFF(bias_data)]);
+ if (jcp.signed_input) {
+ mov(EVEX_compress_addr(rsp, reg_bias_data_off), reg_bias_data);
+ mov(reg_comp_data, ptr[param1 + GET_OFF(compensation)]);
+ mov(EVEX_compress_addr(rsp, reg_comp_data_off), reg_comp_data);
+ }
+ mov(reg_ptr_scales, ptr[param1 + GET_OFF(scales)]);
+ mov(EVEX_compress_addr(rsp, reg_ptr_sum_scale_off), reg_ptr_scales);
+ mov(reg_bcast_data, ptr[param1 + GET_OFF(bcast_data)]);
+ mov(reg_load_data, ptr[param1 + GET_OFF(load_data)]);
+ mov(reg_output_data, ptr[param1 + GET_OFF(output_data)]);
+
+ mov(reg_load_loop_work, ptr[param1 + GET_OFF(load_dim)]);
+ mov(reg_bcast_loop_work, ptr[param1 + GET_OFF(bcast_dim)]);
+ mov(EVEX_compress_addr(rsp, bcast_loop_work_off), reg_bcast_loop_work);
+ mov(reg_reduce_loop_work, ptr[param1 + GET_OFF(reduce_dim)]);
+ mov(reg_reduce_pos_flag, ptr[param1 + GET_OFF(first_last_flag)]);
+
+
+ auto load_loop_body = [=](int load_loop_blk) {
+ bcast_loop(load_loop_blk);
+ add(reg_load_data, load_loop_blk * jcp.load_loop_load_step);
+ if (jcp.with_bias) {
+ if (jcp.signed_input)
+ mov(reg_bias_data, EVEX_compress_addr(rsp, reg_bias_data_off));
+ add(reg_bias_data,
+ load_loop_blk * jcp.load_block * jcp.typesize_bia);
+ if (jcp.signed_input)
+ mov(EVEX_compress_addr(rsp, reg_bias_data_off), reg_bias_data);
+ }
+ if (jcp.signed_input) {
+ mov(reg_comp_data, EVEX_compress_addr(rsp, reg_comp_data_off));
+ add(reg_comp_data,
+ load_loop_blk * jcp.load_block * sizeof(int32_t));
+ mov(EVEX_compress_addr(rsp, reg_comp_data_off), reg_comp_data);
+ }
+ mov(EVEX_compress_addr(rsp, reg_bcast_data_off), reg_bcast_data);
+ mov(reg_ptr_scales, EVEX_compress_addr(rsp, reg_ptr_sum_scale_off));
+ add(reg_ptr_scales,
+ jcp.is_oc_scale * load_loop_blk * jcp.load_block * sizeof(float));
+ mov(EVEX_compress_addr(rsp, reg_ptr_sum_scale_off), reg_ptr_scales);
+ mov(reg_bcast_data, EVEX_compress_addr(rsp, reg_bcast_data_off));
+ add(reg_output_data,
+ load_loop_blk * jcp.load_block * jcp.typesize_out);
+ sub(reg_load_loop_work, load_loop_blk * jcp.load_loop_iter_step);
+ };
+
+ const int simd_w = 16;
+
+ Label load_loop_blk[7];
+
+ static const int ur_cases_fma_expl_bcast[] = { 2, 5, 6, 9, 14, 32 };
+ const int size_ur_cases_fma = sizeof(ur_cases_fma_expl_bcast);
+ const int *ur_cases_fma = ur_cases_fma_expl_bcast;
+ const int *ur_cases = ur_cases_fma;
+ const int num_ur_cases = (size_ur_cases_fma) / sizeof(*ur_cases);
+
+ for (int ur_idx = num_ur_cases - 1; ur_idx > 0; ur_idx--) {
+ int label_idx = num_ur_cases - ur_idx - 1;
+ if (jcp.ur <= ur_cases[ur_idx]) {
+ cmp(reg_load_loop_work, simd_w * (label_idx + 1));
+ jle(load_loop_blk[label_idx], T_NEAR);
+ }
+ }
+
+ for (int ur_idx = 0; ur_idx < num_ur_cases; ur_idx++) {
+ if (jcp.ur <= ur_cases[ur_idx]) {
+ int label_idx = num_ur_cases - ur_idx - 1;
+ L(load_loop_blk[label_idx]);
+ {
+ if (label_idx == 0) {
+ cmp(reg_load_loop_work, 0);
+ je(load_loop_blk[num_ur_cases], T_NEAR);
+ }
+
+ for (int _i = 1; _i <= label_idx + 1; _i++) {
+ prefetcht0(ptr [ reg_load_data + _i * jcp.ic * jcp.oc_block ]);
+ prefetcht1(ptr [ reg_output_data + _i * jcp.oc_block ]);
+ }
+
+ load_loop_body(label_idx + 1);
+ if (label_idx - 1 > 0) {
+ cmp(reg_load_loop_work, 2 * label_idx * simd_w);
+ je(load_loop_blk[label_idx - 1], T_NEAR);
+ }
+ cmp(reg_load_loop_work, (label_idx + 1) * simd_w);
+ jge(load_loop_blk[label_idx]);
+ }
+ for (int idx = label_idx - 1; idx > 0; --idx) {
+ cmp(reg_load_loop_work, simd_w * (idx + 1));
+ je(load_loop_blk[idx], T_NEAR);
+ }
+ if (ur_idx < num_ur_cases - 2) {
+ cmp(reg_load_loop_work, simd_w);
+ jle(load_loop_blk[0], T_NEAR);
+ }
+ }
+ }
+ L(load_loop_blk[num_ur_cases]);
+
+ add(rsp, stack_space_needed);
+
+ postamble();
+
+ if (jcp.with_eltwise)
+ eltwise_injector_->prepare_table();
+}
+
+bool jit_avx512_core_x8s8s32x_1x1_conv_kernel::post_ops_ok(
+ jit_1x1_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ using namespace primitive_kind;
+ const auto &p = attr.post_ops_;
+
+ auto is_eltwise = [&](int idx) { return p.entry_[idx].is_eltwise(); };
+
+ switch (p.len_) {
+ case 0: return true;
+ case 1: return is_eltwise(0) || p.contain(sum, 0);
+ case 2: return (p.contain(sum, 0) && is_eltwise(1))
+ || (p.contain(sum, 1) && is_eltwise(0));
+ default: return false;
+ }
+
+ return false;
+}
+
+status_t jit_avx512_core_x8s8s32x_1x1_conv_kernel::init_conf(
+ jit_1x1_conv_conf_t &jcp, const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d, const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d, const memory_desc_wrapper &bias_d,
+ const primitive_attr_t &attr, int nthreads, bool reduce_src) {
+ if (!mayiuse(avx512_core)) return status::unimplemented;
+
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+ if (!one_of(src_d.data_type(), data_type::u8, data_type::s8)
+ || weights_d.data_type() != data_type::s8
+ || !one_of(dst_d.data_type(),
+ data_type::f32, data_type::s32, data_type::s8, data_type::u8))
+ return status::unimplemented;
+ jcp.ver = ver_avx512_core;
+ if (mayiuse(avx512_core_vnni))
+ jcp.ver = ver_vnni;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+ jcp.ic_without_padding = jcp.ic;
+ jcp.ih = src_d.dims()[2];
+ jcp.iw = src_d.dims()[3];
+ jcp.oh = dst_d.dims()[2];
+ jcp.ow = dst_d.dims()[3];
+ jcp.kh = weights_d.dims()[with_groups + 2];
+ jcp.kw = weights_d.dims()[with_groups + 3];
+ jcp.t_pad = cd.padding[0][0];
+ jcp.l_pad = cd.padding[0][1];
+ jcp.stride_h = cd.strides[0];
+ jcp.stride_w = cd.strides[1];
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+
+ jcp.signed_input = (src_d.data_type() == data_type::s8) ? true : false;
+
+ jcp.os = jcp.oh * jcp.ow;
+ jcp.is = jcp.ih * jcp.iw;
+ jcp.tr_is = rnd_up(jcp.is, 4);
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ const int eltwise_ind = p.find(primitive_kind::eltwise);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise)
+ jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+
+ format_tag_t dat_tag = format_tag::nhwc;
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ jcp.dst_tag = dst_d.matches_one_of_tag(dat_tag);
+
+ bool args_ok = true
+ && jcp.ngroups == 1
+ && jcp.src_tag == dat_tag
+ && jcp.dst_tag == dat_tag;
+ if (!args_ok) return status::unimplemented;
+
+ const int simd_w = 16;
+
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ jcp.ic = rnd_up(jcp.ic, simd_w);
+
+ args_ok = true
+ && jcp.oc % simd_w == 0 && jcp.ic % simd_w == 0
+ && jcp.t_pad == 0 && jcp.l_pad == 0
+ && jcp.stride_w == 1 && jcp.stride_h == 1 // TODO: support some strides
+ && jcp.kh == 1 && jcp.kw == 1;
+ if (!args_ok) return status::unimplemented;
+
+ jcp.bia_dt = jcp.with_bias ? cd.bias_desc.data_type : data_type::undef;
+ jcp.dst_dt = cd.dst_desc.data_type;
+
+ jcp.ic_block = jcp.oc_block = simd_w;
+
+ jcp.typesize_in = types::data_type_size(src_d.data_type());
+ jcp.typesize_out = types::data_type_size(dst_d.data_type());
+ jcp.typesize_bia = jcp.with_bias
+ ? types::data_type_size(bias_d.data_type())
+ : 0;
+
+ const int SMALL_SPATIAL = 7 * 7;
+ const int BIG_REDUCE_DIM = 1024;
+
+ int load_blocking = 0;
+ int load_blocking_max = 0;
+ int bcast_blocking = 0;
+ int bcast_blocking_max = 0;
+ int reduce_blocking = 0;
+ int reduce_blocking_max = 0;
+ jcp.load_grp_count = 1;
+ jcp.use_vmovntps = false;
+
+ const int L2_size = get_cache_size(2, true) / sizeof(jcp.typesize_in);
+ const int L2_capacity = (L2_size * 3) / 4;
+
+ int size_treshold = 28;
+ int max_regs = 0;
+ int min_regs = 6;
+ if (jcp.ver == ver_vnni)
+ max_regs = ((jcp.oh > size_treshold && jcp.ow > size_treshold)
+ && (jcp.oc < 128 || jcp.ic < 128)) ? min_regs : 9;
+ else
+ max_regs = 8;
+ jcp.expl_bcast = true;
+
+ if (jcp.mb == 1 && jcp.ic > 128
+ && (jcp.oh <= size_treshold && jcp.ow <= size_treshold)) {
+ if (jcp.os <= SMALL_SPATIAL && jcp.oc * jcp.ic < L2_size)
+ max_regs = min_regs; // mobilenet_v2 performance improvement
+ jcp.ur = nstl::min(max_regs, jcp.os);
+ } else {
+ const int spatial = jcp.oh;
+ jcp.ur = 1;
+ for (int ur_w = max_regs; ur_w >= min_regs; ur_w--) {
+ if ((spatial >= size_treshold && spatial % ur_w == 0)
+ || (spatial < size_treshold && jcp.os % ur_w == 0)) {
+ jcp.ur = ur_w;
+ break;
+ }
+ }
+ if (jcp.ur == 1) {
+ jcp.ur = nstl::min(max_regs, jcp.os);
+ int os_tail = jcp.os % max_regs;
+ for (int i = max_regs; i >= min_regs; i--) {
+ int i_tail = jcp.os % i;
+ if (i_tail > os_tail || i_tail == 0) {
+ jcp.ur = i;
+ os_tail = i_tail;
+ if (i_tail == 0)
+ break;
+ }
+ }
+ }
+ }
+
+ jcp.reduce_dim = jcp.ic;
+ jcp.reduce_block = jcp.ic_block;
+
+ jcp.load_dim = jcp.oc;
+ jcp.load_block = jcp.oc_block;
+
+ jcp.bcast_dim = jcp.is;
+
+ jcp.bcast_block = jcp.ur;
+
+ jcp.reduce_loop_unroll = jcp.reduce_block;
+ jcp.reduce_loop_bcast_step
+ = jcp.reduce_loop_unroll * jcp.typesize_in;
+
+ jcp.reduce_loop_load_step
+ = jcp.reduce_loop_unroll * jcp.load_block * jcp.typesize_in;
+
+ jcp.bcast_loop_output_step = jcp.ur * jcp.oc_without_padding * jcp.typesize_out;
+ jcp.bcast_loop_output_substep = -1; // unused
+ jcp.bcast_loop_bcast_step = jcp.ur * jcp.ic_without_padding * jcp.typesize_in;
+ jcp.bcast_loop_bcast_substep = -1; // unused
+
+ jcp.load_loop_load_step
+ = jcp.reduce_dim * jcp.load_block * jcp.typesize_in;
+
+ jcp.load_loop_iter_step = jcp.load_block;
+
+ jcp.loop_order = reduce_src ? loop_blr : loop_lbr;
+
+ int nb_bcast = div_up(jcp.bcast_dim, jcp.bcast_block);
+ int nb_reduce = div_up(jcp.reduce_dim, jcp.reduce_block);
+
+ reduce_blocking = nb_reduce;
+ if (jcp.bcast_dim <= SMALL_SPATIAL && jcp.reduce_dim >= BIG_REDUCE_DIM)
+ reduce_blocking = 64;
+ else if (jcp.bcast_dim > SMALL_SPATIAL && jcp.reduce_dim >= BIG_REDUCE_DIM)
+ reduce_blocking = 16;
+ reduce_blocking = best_divider(nb_reduce, 1, reduce_blocking, true);
+ reduce_blocking *= jcp.reduce_block;
+
+ bool cmp_reduce = reduce_blocking <= jcp.reduce_dim;
+ if (cmp_reduce)
+ jcp.loop_order = reduce_src ? loop_rbl : loop_rlb;
+ load_blocking = jcp.load_dim;
+
+ jcp.load_grp_count = div_up(nthreads, jcp.mb * jcp.ngroups * nb_bcast);
+ jcp.load_grp_count = best_divider(
+ nthreads, jcp.load_grp_count, 2 * jcp.load_grp_count, false);
+
+ if (jcp.bcast_dim <= SMALL_SPATIAL && jcp.load_dim * jcp.reduce_dim >= L2_size) {
+ jcp.load_grp_count = nstl::max(jcp.load_grp_count, 4);
+ } else if (jcp.bcast_dim <= SMALL_SPATIAL && jcp.mb <= nthreads
+ && jcp.load_dim > 512 && jcp.load_dim / jcp.reduce_dim >= 4) {
+ jcp.load_grp_count = nstl::max(jcp.load_grp_count, 2); //
+ load_blocking = jcp.load_block;
+ }
+
+ bcast_blocking = div_up(jcp.mb * jcp.ngroups * nb_bcast,
+ div_up(nthreads, jcp.load_grp_count)) * jcp.bcast_block;
+ bcast_blocking = nstl::min(jcp.bcast_dim, bcast_blocking);
+ bcast_blocking = rnd_up(bcast_blocking, jcp.bcast_block);
+
+ int space_for_bcast
+ = (L2_capacity - /* kernel_size - */
+ 2 * jcp.load_block * reduce_blocking
+ - jcp.ur * reduce_blocking - 3 * 1024);
+ if (jcp.reduce_dim * jcp.bcast_dim > L2_capacity)
+ space_for_bcast /= 2;
+
+ int bcast_in_cache
+ = nstl::max(jcp.bcast_block, space_for_bcast / reduce_blocking);
+ bcast_blocking = nstl::min(
+ bcast_blocking, rnd_dn(bcast_in_cache, jcp.bcast_block));
+
+ load_blocking_max = load_blocking;
+ bcast_blocking_max = bcast_blocking * 3 / 2;
+ reduce_blocking_max = reduce_blocking;
+
+ assert(load_blocking);
+ assert(load_blocking_max);
+ assert(bcast_blocking);
+ assert(bcast_blocking_max);
+ assert(reduce_blocking);
+ assert(reduce_blocking_max);
+ assert(load_blocking % jcp.load_block == 0);
+ assert(reduce_blocking % jcp.reduce_block == 0);
+ assert(load_blocking_max % jcp.load_block == 0);
+ assert(reduce_blocking_max % jcp.reduce_block == 0);
+
+ assert(jcp.reduce_loop_unroll % 4 == 0);
+ assert(jcp.reduce_dim % jcp.reduce_loop_unroll == 0);
+
+ assert(jcp.bcast_block % jcp.ur == 0);
+ assert(jcp.reduce_dim % jcp.reduce_block == 0);
+
+ jcp.ur_tail = jcp.bcast_dim % jcp.ur;
+
+ jcp.nb_bcast_blocking = bcast_blocking / jcp.bcast_block;
+ jcp.nb_bcast_blocking_max = bcast_blocking_max / jcp.bcast_block;
+ jcp.nb_load_blocking = load_blocking / jcp.load_block;
+ jcp.nb_load_blocking_max = load_blocking_max / jcp.load_block;
+ jcp.nb_reduce_blocking = reduce_blocking / jcp.reduce_block;
+ jcp.nb_reduce_blocking_max = reduce_blocking_max / jcp.reduce_block;
+
+ jcp.nb_bcast = div_up(jcp.bcast_dim, jcp.bcast_block);
+ jcp.nb_load = div_up(jcp.load_dim, jcp.load_block);
+ jcp.nb_reduce = div_up(jcp.reduce_dim, jcp.reduce_block);
+
+ // miniumum size of load dim chunk for work distribution within threads
+ jcp.nb_load_chunk = 1;
+ // peformance improvements for googlenet_v3, mb=1;
+ // TODO: generalize this condition and rewrite it in appropriate manner
+ if (jcp.mb == 1 && jcp.nb_load % 4 == 0 && jcp.ic / jcp.oc >= 4
+ && jcp.ic * jcp.oc <= L2_size) {
+ jcp.nb_load_chunk = 4;
+ jcp.load_grp_count = nstl::max(jcp.nb_load / 4, jcp.load_grp_count);
+ }
+
+ const auto &oscales = attr.output_scales_;
+ jcp.is_oc_scale = oscales.mask_ == 1 << 1;
+ assert(IMPLICATION(!jcp.is_oc_scale, oscales.mask_ == 0));
+
+ jcp.wei_adj_scale =
+ (weights_d.extra().flags | memory_extra_flags::scale_adjust)
+ ? weights_d.extra().scale_adjust : 1.f;
+
+ return status::success;
+}
+
+void jit_avx512_core_x8s8s32x_1x1_conv_kernel::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad,
+ const jit_1x1_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ using namespace mkldnn::impl::memory_tracking::names;
+
+ if (jcp.signed_input && jcp.ver != ver_vnni) {
+ dim_t count = nstl::max<dim_t>(attr.output_scales_.count_, 16);
+ scratchpad.book(key_conv_adjusted_scales, sizeof(float) * count);
+ }
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_conv_kernel.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_conv_kernel.hpp
new file mode 100644
index 0000000000..22e9732a1f
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_conv_kernel.hpp
@@ -0,0 +1,131 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_AVX512_CORE_X8S8S32X_1X1_CONV_KERNEL_HPP
+#define JIT_AVX512_CORE_X8S8S32X_1X1_CONV_KERNEL_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+#include "jit_uni_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_avx512_core_x8s8s32x_1x1_conv_kernel: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_x8s8s32x_1x1_conv_fwd_ker_t)
+ jit_avx512_core_x8s8s32x_1x1_conv_kernel(jit_1x1_conv_conf_t ajcp,
+ const primitive_attr_t &attr) : jcp(ajcp), attr_(attr),
+ eltwise_injector_(nullptr)
+ {
+ if (jcp.with_eltwise)
+ eltwise_injector_ = new jit_uni_eltwise_injector_f32<avx512_common>(
+ this, jcp.eltwise);
+
+ this->generate();
+ jit_ker = (void (*)(jit_1x1_conv_call_s *)) this->getCode();
+ }
+
+ ~jit_avx512_core_x8s8s32x_1x1_conv_kernel() {
+ delete eltwise_injector_;
+ }
+
+ static bool post_ops_ok(jit_1x1_conv_conf_t &jcp,
+ const primitive_attr_t &attr);
+
+ static status_t init_conf(jit_1x1_conv_conf_t &jcp,
+ const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d,
+ const memory_desc_wrapper &bias_d,
+ const primitive_attr_t &attr,
+ int nthreads, bool reduce_src);
+
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_1x1_conv_conf_t &jcp, const primitive_attr_t &attr);
+
+ bool maybe_eltwise(int position);
+
+ jit_1x1_conv_conf_t jcp;
+ const primitive_attr_t &attr_;
+ void (*jit_ker)(jit_1x1_conv_call_s *);
+
+ private:
+ jit_uni_eltwise_injector_f32<avx512_common> *eltwise_injector_;
+
+ using reg64_t = const Xbyak::Reg64;
+ using zmm_t = const Xbyak::Zmm;
+ using mask_t = const Xbyak::Opmask;
+
+ reg64_t reg_bcast_data = r8;
+ reg64_t reg_ptr_scales = r8;
+ reg64_t reg_output_data = r9;
+ reg64_t reg_load_data = r10;
+ reg64_t reg_ptr_sum_scale = r10;
+ reg64_t reg_reduce_loop_work = r11;
+ reg64_t reg_bias_data = r12;
+ reg64_t reg_comp_data = r12;
+ reg64_t reg_scratch = r13;
+ reg64_t aux_reg_bcast_data = r14;
+ reg64_t aux_reg_load_data = r15;
+ reg64_t imm_addr64 = r15;
+ reg64_t reg_reduce_pos_flag = rax;
+ reg64_t aux1_reg_bcast_data = rbx;
+ reg64_t reg_bcast_loop_work = rbx;
+ reg64_t bcast_loop_iter = rdx; // Note: Fix me
+ reg64_t reg_load_loop_work = rsi;
+ reg64_t aux_reg_output_data = abi_not_param1;
+ reg64_t reduce_loop_iter = abi_param1;
+
+ reg64_t reg_last_load = r8;
+ mask_t ktail_mask = k6;
+
+ mask_t vmask = k7;
+
+ Xbyak::Zmm zmm_tmp = Xbyak::Zmm(28);
+ Xbyak::Zmm zmm_one = Xbyak::Zmm(29);
+ Xbyak::Zmm zmm_zero = Xbyak::Zmm(30);
+ Xbyak::Zmm zmm_bcast = Xbyak::Zmm(31);
+ Xbyak::Zmm zmm_shift = Xbyak::Zmm(30);
+
+ Xbyak::Zmm zmm_bias_alpha = Xbyak::Zmm(31);
+ Xbyak::Xmm xmm_bias_alpha = Xbyak::Xmm(31);
+
+ int bcast_loop_work_off = 0;
+ int reg_bias_data_off = 8;
+ int reg_bcast_data_off = 16;
+ int reg_load_data_off = 24;
+ int reg_ptr_sum_scale_off = 32;
+ int reg_comp_data_off = 40;
+ int stack_space_needed = 48;
+
+ void bcast_loop(int load_loop_blk);
+ void reduce_loop(int load_loop_blk, int ur, int substep, bool wraparound);
+
+ void generate();
+ void cvt2ps(data_type_t type_in, zmm_t zmm_in, const Xbyak::Operand &op,
+ bool mask_flag);
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_convolution.cpp
new file mode 100644
index 0000000000..0bf09fc677
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_convolution.cpp
@@ -0,0 +1,292 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_generator.hpp"
+
+#include "jit_avx512_core_x8s8s32x_1x1_convolution.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+
+namespace {
+template <typename T, typename U>
+void balance2D(U nthr, U ithr, T ny, T &ny_start, T &ny_end,
+ T nx, T &nx_start, T &nx_end, T nx_divider)
+{
+ const T grp_size = utils::div_up(nthr, nx_divider);
+ const T grp_count = utils::div_up(nthr, grp_size);
+
+ T grp = ithr / grp_size;
+ T grp_ithr = ithr % grp_size;
+ T grp_nthr = grp_size;
+ T first_grps = nthr % grp_count;
+ if (first_grps > 0 && grp >= first_grps) {
+ ithr -= first_grps * grp_size;
+ grp_nthr--;
+ grp = ithr / grp_nthr + first_grps;
+ grp_ithr = ithr % grp_nthr;
+ }
+ balance211(nx, grp_count, grp, nx_start, nx_end);
+ balance211(ny, grp_nthr, grp_ithr, ny_start, ny_end);
+}
+}
+
+/* convolution forward */
+template <data_type_t src_type, data_type_t dst_type>
+void jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<src_type, dst_type>::
+execute_forward(const exec_ctx_t &ctx) const
+{
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ auto scratchpad = this->scratchpad(ctx);
+
+ if (pd()->jcp_.signed_input && pd()->jcp_.ver != ver_vnni) {
+ auto local_scales = scratchpad.template get<float>(
+ key_conv_adjusted_scales);
+ auto scales = pd()->attr()->output_scales_.scales_;
+ size_t count = pd()->attr()->output_scales_.count_;
+ float factor = 1.f / pd()->jcp_.wei_adj_scale;
+ if (count == 1) {
+ utils::array_set(local_scales, scales[0] * factor, 16);
+ } else {
+ for (size_t c = 0; c < count; c++)
+ local_scales[c] = scales[c] * factor;
+ }
+ }
+
+ parallel(kernel_->jcp.nthr, [&](const int ithr, const int nthr) {
+ execute_forward_thr(ithr, nthr, src, weights, bias, dst, scratchpad);
+ });
+}
+
+template <data_type_t src_type, data_type_t dst_type>
+void jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<src_type, dst_type>
+::execute_forward_thr(const int ithr, const int nthr, const src_data_t *src,
+ const wei_data_t *weights, const char *bias, dst_data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const {
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+
+ const size_t bia_dt_size = pd()->with_bias()
+ ? types::data_type_size(pd()->desc()->bias_desc.data_type) : 0;
+
+ const auto &jcp = kernel_->jcp;
+ auto rtus_space = scratchpad.get<src_data_t>(key_conv_rtus_space);
+ auto local_scales = scratchpad.get<float>(key_conv_adjusted_scales);
+
+ const int work_amount = jcp.mb * jcp.ngroups * jcp.nb_bcast;
+
+ const int stride_h = pd()->desc()->strides[0];
+ const int stride_w = pd()->desc()->strides[1];
+ const int pad_t = pd()->desc()->padding[0][0];
+ const int pad_l = pd()->desc()->padding[0][1];
+
+ const auto &oscales = pd()->attr()->output_scales_;
+
+ int offset = jcp.ngroups * (jcp.oc / jcp.oc_block) * (jcp.ic / jcp.ic_block)
+ * jcp.oc_block * jcp.ic_block;
+ wei_data_t *w = const_cast<wei_data_t *>(weights);
+ int32_t* compensation = (jcp.signed_input)
+ ? reinterpret_cast<int32_t *>(w + offset) : 0;
+
+ auto step = [](int default_step, int remaining, int tail_step) {
+ assert(default_step <= tail_step);
+ return remaining < tail_step ? remaining : default_step;
+ };
+
+ auto p = jit_1x1_conv_call_s();
+
+ auto rp = rtus_driver_t<avx512_common>::call_params_t();
+ const int nb_oc = jcp.nb_load;
+ const int os_block = jcp.bcast_block;
+
+ int bcast_start{0}, bcast_end{0}, ocb_start{0}, ocb_end{0};
+ balance2D(nthr, ithr, work_amount, bcast_start, bcast_end,
+ jcp.nb_load / jcp.nb_load_chunk, ocb_start, ocb_end,
+ jcp.load_grp_count);
+ if (jcp.nb_load_chunk > 1) {
+ ocb_start *= jcp.nb_load_chunk;
+ ocb_end *= jcp.nb_load_chunk;
+ }
+
+ auto init_bcast = [&](int iwork, int &n, int &g, int &bcast_step,
+ int &oh, int &ow, int &ih, int &iw)
+ {
+ int osb{0};
+ nd_iterator_init(iwork, n, jcp.mb, g, jcp.ngroups, osb,
+ jcp.nb_bcast);
+ bcast_step = step(jcp.nb_bcast_blocking, jcp.nb_bcast - osb,
+ jcp.nb_bcast_blocking_max);
+ bcast_step = nstl::min(bcast_step, bcast_end - iwork);
+
+ const int os = osb * os_block;
+ oh = os / jcp.ow;
+ ow = os % jcp.ow;
+
+ ih = nstl::max(oh * stride_h - pad_t, 0);
+ iw = nstl::max(ow * stride_w - pad_l, 0);
+ rp.iw_start = iw;
+
+ p.bcast_dim = this_block_size(os, jcp.os,
+ bcast_step * os_block);
+ rp.os = p.bcast_dim;
+ };
+
+ auto init_load = [&](int ocb, int &load_step)
+ {
+ load_step = step(jcp.nb_load_blocking, ocb_end - ocb,
+ jcp.nb_load_blocking_max);
+ p.load_dim = this_block_size(ocb * jcp.oc_block,
+ ocb_end * jcp.oc_block, load_step * jcp.oc_block);
+
+ if (ocb + load_step >= nb_oc)
+ p.first_last_flag |= FLAG_OC_LAST;
+ else
+ p.first_last_flag &= ~FLAG_OC_LAST;
+
+ };
+
+ auto init_reduce = [&]()
+ {
+ p.reduce_dim = this_block_size(0, jcp.ic, jcp.ic);
+ rp.icb = p.reduce_dim / jcp.reduce_block;
+ };
+
+ auto inner_ker = [&](int ocb, int n, int g, int oh, int ow,
+ int ih, int iw)
+ {
+ const int icb = 0; // Start from the first IC block
+ const int _ocb = g * nb_oc + ocb;
+ const int _icb = g;
+
+ const size_t dst_off = dst_d.blk_off(n, _ocb * jcp.oc_block, oh, ow);
+
+ p.output_data = &dst[dst_off];
+ p.load_data = &weights[pd()->with_groups()
+ ? weights_d.blk_off(g, ocb, icb)
+ : weights_d.blk_off(ocb, icb)];
+ p.bias_data = &bias[_ocb * jcp.oc_block * bia_dt_size];
+ p.compensation = (jcp.signed_input)
+ ? &compensation[_ocb * jcp.oc_block] : 0;
+ p.scales = (jcp.signed_input && jcp.ver != ver_vnni)
+ ? &local_scales[jcp.is_oc_scale * _ocb * jcp.oc_block]
+ : &oscales.scales_[jcp.is_oc_scale * _ocb * jcp.oc_block];
+ if (pd()->rtus_.reduce_src_) {
+ rp.ws = rtus_space + ithr * pd()->rtus_.space_per_thread_
+ + _icb * jcp.is * jcp.ic_block;
+ if (ocb == ocb_start) {
+ rp.src = src + src_d.blk_off(n, _icb * jcp.ic_block, ih, iw);
+ rtus_driver_->ker_(&rp);
+ }
+ p.bcast_data = rp.ws;
+ } else
+ p.bcast_data = src + src_d.blk_off(n, _icb * jcp.ic_block, ih, iw);
+
+ kernel_->jit_ker(&p);
+ };
+
+ if (jcp.loop_order == loop_rlb) {
+ init_reduce();
+ int ocb = ocb_start;
+ while (ocb < ocb_end) {
+ int load_step;
+ init_load(ocb, load_step);
+ int iwork = bcast_start;
+ while (iwork < bcast_end) {
+ int n, g, bcast_step, oh, ow, ih, iw;
+ init_bcast(iwork, n, g, bcast_step, oh, ow, ih, iw);
+ inner_ker(ocb, n, g, oh, ow, ih, iw);
+ iwork += bcast_step;
+ }
+ ocb += load_step;
+ }
+ } else if (jcp.loop_order == loop_lbr) {
+ int ocb = ocb_start;
+ while (ocb < ocb_end) {
+ int load_step;
+ init_load(ocb, load_step);
+ int iwork = bcast_start;
+ while (iwork < bcast_end) {
+ int n, g, bcast_step, oh, ow, ih, iw;
+ init_bcast(iwork, n, g, bcast_step, oh, ow, ih, iw);
+ init_reduce();
+ inner_ker(ocb, n, g, oh, ow, ih, iw);
+ iwork += bcast_step;
+ }
+ ocb += load_step;
+ }
+ } else if (jcp.loop_order == loop_rbl) {
+ init_reduce();
+ int iwork = bcast_start;
+ while (iwork < bcast_end) {
+ int n, g, bcast_step, oh, ow, ih, iw;
+ init_bcast(iwork, n, g, bcast_step, oh, ow, ih, iw);
+ int ocb = ocb_start;
+ while (ocb < ocb_end) {
+ int load_step;
+ init_load(ocb, load_step);
+ inner_ker(ocb, n, g, oh, ow, ih, iw);
+ ocb += load_step;
+ }
+ iwork += bcast_step;
+ }
+ } else if (jcp.loop_order == loop_blr) {
+ int iwork = bcast_start;
+ while (iwork < bcast_end) {
+ int n, g, bcast_step, oh, ow, ih, iw;
+ init_bcast(iwork, n, g, bcast_step, oh, ow, ih, iw);
+ int ocb = ocb_start;
+ while (ocb < ocb_end) {
+ int load_step;
+ init_load(ocb, load_step);
+ init_reduce();
+ inner_ker(ocb, n, g, oh, ow, ih, iw);
+ ocb += load_step;
+ }
+ iwork += bcast_step;
+ }
+ } else {
+ assert(!"unsupported loop order");
+ }
+}
+
+using namespace data_type;
+template struct jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<u8, u8>;
+template struct jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<s8, u8>;
+template struct jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<u8, s8>;
+template struct jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<s8, s8>;
+template struct jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<u8, s32>;
+template struct jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<s8, s32>;
+template struct jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<u8, f32>;
+template struct jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<s8, f32>;
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_convolution.hpp
new file mode 100644
index 0000000000..ad9027ac17
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_convolution.hpp
@@ -0,0 +1,159 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_CORE_X8S8S32X_1X1_CONVOLUTION_HPP
+#define CPU_JIT_AVX512_CORE_X8S8S32X_1X1_CONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "jit_avx512_core_x8s8s32x_1x1_conv_kernel.hpp"
+#include "jit_uni_1x1_conv_utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template<impl::data_type_t src_type, impl::data_type_t dst_type>
+struct jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t : public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_(), rtus_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_int8_1x1:", avx512_core, ""),
+ jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t<
+ src_type, dst_type>);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(src_type, data_type::s8, data_type::undef,
+ dst_type, data_type::s32)
+ && IMPLICATION(with_bias(), utils::one_of(
+ desc()->bias_desc.data_type, data_type::f32,
+ data_type::s32, data_type::s8, data_type::u8))
+ && !has_zero_dim_memory()
+ && set_default_formats_common(dat_tag(), format_tag::any,
+ dat_tag())
+ && set_or_check_wei_format();
+ if (!ok) return status::unimplemented;
+
+ const convolution_desc_t *conv_d = desc();
+ const memory_desc_t *src_d = src_md();
+ rtus_prepare(this, conv_d, src_d, dst_md());
+
+ status_t status = jit_avx512_core_x8s8s32x_1x1_conv_kernel::
+ init_conf(jcp_, *conv_d, *src_d, *weights_md(), *dst_md(),
+ *weights_md(1), *attr(), mkldnn_get_max_threads(),
+ rtus_.reduce_src_);
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx512_core_x8s8s32x_1x1_conv_kernel::init_scratchpad(
+ scratchpad, jcp_, *attr());
+
+ rtus_prepare_space_info(this, scratchpad);
+
+ return status::success;
+ }
+
+ jit_1x1_conv_conf_t jcp_;
+ reduce_to_unit_stride_t rtus_;
+
+ protected:
+ format_tag_t dat_tag() const { return format_tag::nhwc; }
+
+ bool set_or_check_wei_format() {
+ using namespace format_tag;
+
+ const bool is_src_s8 = src_md_.data_type == data_type::s8;
+ format_tag_t wei_tag = with_groups() ? gOIhw4i16o4i : OIhw4i16o4i;
+
+ memory_desc_t want_wei_md = weights_md_;
+ memory_desc_init_by_tag(want_wei_md, wei_tag);
+ if (is_src_s8) {
+ want_wei_md.extra.flags = 0
+ | memory_extra_flags::compensation_conv_s8s8
+ | memory_extra_flags::scale_adjust;
+ want_wei_md.extra.compensation_mask = (1 << 0)
+ + (with_groups() ? (1 << 1) : 0);
+ want_wei_md.extra.scale_adjust =
+ mayiuse(avx512_core_vnni) ? 1.f : 0.5f;
+ }
+
+ if (weights_md_.format_kind == format_kind::any) {
+ weights_md_ = want_wei_md;
+ return true;
+ }
+
+ return weights_md_ == want_wei_md;
+ }
+ };
+
+ template <cpu_isa_t isa, typename conv_t>
+ friend void init_rtus_driver(conv_t *self);
+
+ jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , kernel_(nullptr), rtus_driver_(nullptr)
+ {
+ kernel_ = new jit_avx512_core_x8s8s32x_1x1_conv_kernel(pd()->jcp_,
+ *pd()->attr());
+ init_rtus_driver<avx512_common>(this);
+ }
+
+ ~jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t() {
+ delete kernel_;
+ delete rtus_driver_;
+ }
+
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<data_type::s8>::type wei_data_t;
+ typedef typename prec_traits<dst_type>::type dst_data_t;
+ typedef typename prec_traits<data_type::s32>::type acc_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+ private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ void execute_forward_thr(const int ithr, const int nthr,
+ const src_data_t *src, const wei_data_t *weights,
+ const char *bias, dst_data_t *dst,
+ const memory_tracking::grantor_t &scratchpad) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx512_core_x8s8s32x_1x1_conv_kernel *kernel_;
+ rtus_driver_t<avx512_common> *rtus_driver_;
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_deconvolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_deconvolution.hpp
new file mode 100644
index 0000000000..e89d068302
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_1x1_deconvolution.hpp
@@ -0,0 +1,140 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_CORE_X8S8S32X_1X1_DECONVOLUTION_HPP
+#define CPU_JIT_AVX512_CORE_X8S8S32X_1X1_DECONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+#include "type_helpers.hpp"
+#include "primitive_iterator.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_deconvolution_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "jit_uni_1x1_conv_utils.hpp"
+#include "jit_avx512_core_x8s8s32x_1x1_convolution.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t src_type, impl::data_type_t dst_type>
+struct jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t
+ : public cpu_primitive_t {
+ struct pd_t : public cpu_deconvolution_fwd_pd_t {
+ pd_t(engine_t *engine, const deconvolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const deconvolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_deconvolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , conv_pd_(nullptr) {}
+
+ pd_t(const pd_t &other)
+ : cpu_deconvolution_fwd_pd_t(other)
+ , conv_pd_(other.conv_pd_->clone())
+ {}
+
+ ~pd_t() { delete conv_pd_; }
+
+ DECLARE_COMMON_PD_T(conv_pd_->name(),
+ jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t<src_type, dst_type>);
+
+ status_t init_convolution() {
+ convolution_desc_t cd;
+ status_t status;
+
+ auto dd = desc();
+ status = conv_desc_init(&cd, prop_kind::forward_training,
+ alg_kind::convolution_direct, &(dd->src_desc),
+ &(dd->weights_desc), &(dd->bias_desc), &(dd->dst_desc),
+ dd->strides, dd->dilates, dd->padding[0], dd->padding[1],
+ dd->padding_kind);
+
+ if (status == status::success) {
+ status = mkldnn_primitive_desc::create<conv_pd_t>(
+ &conv_pd_, (op_desc_t *)&cd, &attr_, engine_, nullptr);
+ }
+
+ if (status == status::success)
+ status = set_default_params();
+
+ return status;
+ };
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && desc()->alg_kind == alg_kind::deconvolution_direct
+ && !has_zero_dim_memory()
+ && desc()->src_desc.data_type == src_type
+ && desc()->dst_desc.data_type == dst_type
+ && desc()->weights_desc.data_type == data_type::s8
+ && IMPLICATION(with_bias(), utils::one_of(
+ desc()->bias_desc.data_type, data_type::f32,
+ data_type::s32, data_type::s8, data_type::u8))
+ && desc()->accum_data_type == data_type::s32;
+ if (!ok) return status::unimplemented;
+
+ CHECK(init_convolution());
+
+ return status::success;
+ }
+
+ virtual void init_scratchpad_md() override {
+ const auto conv_1x1_pd = static_cast<conv_pd_t *>(conv_pd_);
+ scratchpad_md_ = *conv_1x1_pd->scratchpad_md();
+ }
+
+ protected:
+ status_t set_default_params() {
+ auto conv_1x1_pd_ = static_cast<conv_pd_t *>(conv_pd_);
+ src_md_ = *conv_1x1_pd_->src_md();
+ dst_md_ = *conv_1x1_pd_->dst_md();
+ weights_md_ = *conv_1x1_pd_->weights_md();
+ if (with_bias())
+ bias_md_ = *conv_1x1_pd_->weights_md(1);
+ return status::success;
+ }
+
+ using conv_pd_t = typename jit_avx512_core_x8s8s32x_1x1_convolution_fwd_t
+ <src_type, dst_type>::pd_t;
+ friend jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t;
+ primitive_desc_t *conv_pd_;
+ };
+
+ jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ { pd()->conv_pd_->create_primitive((primitive_t **)&conv_p_); }
+
+ ~jit_avx512_core_x8s8s32x_1x1_deconvolution_fwd_t()
+ { delete conv_p_; }
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ return conv_p_->execute(ctx);
+ }
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ primitive_t *conv_p_;
+};
+
+}
+}
+}
+
+#endif /* CPU_JIT_AVX512_CORE_X8S8S32X_1X1_DECONVOLUTION_HPP */
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_conv_kernel.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_conv_kernel.cpp
new file mode 100644
index 0000000000..10e98a00c4
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_conv_kernel.cpp
@@ -0,0 +1,1182 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_memory.hpp"
+
+#include "jit_avx512_core_x8s8s32x_conv_kernel.hpp"
+
+#define GET_OFF(field) offsetof(jit_conv_call_s, field)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+using namespace Xbyak;
+
+namespace {
+void pick_loop_order(jit_conv_conf_t &jcp, int nthr)
+{
+ jcp.loop_order = loop_cwgn;
+ if (jcp.ngroups > 1) {
+ jcp.loop_order = loop_ngcw;
+ if (jcp.mb < nthr)
+ jcp.loop_order = jcp.ndims == 3 ? loop_nwcg : loop_nhwcg;
+ }
+}
+}
+
+template<typename Vmm>
+bool _jit_avx512_core_x8s8s32x_fwd_kernel<Vmm>::maybe_eltwise(int position)
+{
+ using namespace primitive_kind;
+ const auto &p = attr_.post_ops_;
+
+ if (position == 0) {
+ /* eltwise before sum */
+ return p.contain(eltwise, 0);
+ } else if (position == 1) {
+ /* eltwise after sum */
+ return p.contain(sum, 0) && p.contain(eltwise, 1);
+ }
+
+ return false;
+}
+
+template<typename Vmm>
+void _jit_avx512_core_x8s8s32x_fwd_kernel<Vmm>::prepare_output(int ur_w)
+{
+ int nb_oc_block
+ = jcp.is_depthwise ? jcp.nb_ch_blocking : jcp.nb_oc_blocking;
+ for (int k = 0; k < nb_oc_block; k++)
+ for (int j = 0; j < ur_w; j++) {
+ Vmm vmm = vmm_out(j, k);
+ vpxord(vmm, vmm, vmm);
+ }
+ if (jcp.signed_input) {
+ xor_(reg_scratch, reg_scratch);
+ if (jcp.is_depthwise && !jcp.is_fast_depthwise) {
+ Reg32 _t32 = reg_scratch.cvt32();
+ mov(_t32, (uint32_t)128);
+ vpbroadcastd(vmm_shift, _t32);
+ } else {
+ Reg8 _t8 = reg_scratch.cvt8();
+ mov(_t8, (int8_t)128);
+ vpbroadcastb(vmm_shift, _t8);
+ }
+ }
+}
+
+template<typename Vmm>
+const Vmm _jit_avx512_core_x8s8s32x_fwd_kernel<Vmm>::
+ vmm_mask(const Vmm vmm_in, bool mask_flag, bool store) {
+ return vmm_in;
+}
+
+template<>
+const Zmm _jit_avx512_core_x8s8s32x_fwd_kernel<Zmm>::
+ vmm_mask(const Zmm zmm_in, bool mask_flag, bool store) {
+ return mask_flag ? (store ? zmm_in | ktail_mask : zmm_in | ktail_mask | T_z)
+ : zmm_in;
+}
+
+
+template<typename Vmm>
+void _jit_avx512_core_x8s8s32x_fwd_kernel<Vmm>::cvt2ps(data_type_t type_in,
+ const Vmm vmm_in, const Operand &op, bool mask_flag) {
+ //const Vmm vmm = mask_flag ? vmm_in | ktail_mask | T_z : vmm_in;
+ const Vmm vmm = vmm_mask(vmm_in, mask_flag);
+ switch (type_in) {
+ case data_type::f32:
+ case data_type::s32: vmovups(vmm, op); break;
+ case data_type::s8: vpmovsxbd(vmm, op); break;
+ case data_type::u8: vpmovzxbd(vmm, op); break;
+ default: assert(!"unsupported data type");
+ }
+ if (type_in != data_type::f32)
+ vcvtdq2ps(vmm_in, vmm_in);
+}
+
+template<typename Vmm>
+void _jit_avx512_core_x8s8s32x_fwd_kernel<Vmm>::compute_eltwise(int ur_w) {
+ int nb_oc_block
+ = jcp.is_depthwise ? jcp.nb_ch_blocking : jcp.nb_oc_blocking;
+ if (ur_w == jcp.ur_w)
+ eltwise_injector_->compute_vector_range(0, nb_oc_block * jcp.ur_w);
+ else
+ for (int k = 0; k < nb_oc_block; k++)
+ eltwise_injector_->compute_vector_range(k * jcp.ur_w,
+ k * jcp.ur_w + ur_w);
+}
+
+template<typename Vmm>
+void _jit_avx512_core_x8s8s32x_fwd_kernel<Vmm>::store_output(
+ int ur_w, bool last_oc_block_flag) {
+ int nb_oc_block
+ = jcp.is_depthwise ? jcp.nb_ch_blocking : jcp.nb_oc_blocking;
+ int oc_block = jcp.is_depthwise ? jcp.ch_block : jcp.oc_block;
+
+ mov(reg_bias, ptr[param1 + GET_OFF(bias)]);
+ mov(reg_ptr_scales, ptr[param1 + GET_OFF(scales)]);
+ if (jcp.signed_input)
+ mov(reg_compensation, ptr[param1 + GET_OFF(compensation)]);
+
+ const auto &p = attr_.post_ops_;
+ const int sum_idx = p.find(primitive_kind::sum);
+ const float *p_sum_scale = nullptr;
+ if (sum_idx != -1) {
+ const auto &p_entry = p.entry_[sum_idx];
+ p_sum_scale = &p_entry.sum.scale;
+ }
+
+ if (p_sum_scale && *p_sum_scale != 1.f)
+ mov(reg_ptr_sum_scale, (size_t)p_sum_scale);
+
+ if (jcp.signed_input && jcp.ver != ver_vnni) {
+ /* put 'wei_adj_scale = 0.5' for bias calculation */
+ mov(reg_bias_alpha, float2int(jcp.wei_adj_scale));
+ vmovq(xmm_bias_alpha(), reg_bias_alpha);
+ vbroadcastss(vmm_bias_alpha(), xmm_bias_alpha());
+ }
+
+ for (int k = 0; k < nb_oc_block; k++) {
+ const bool mask_flag = last_oc_block_flag && k == nb_oc_block - 1;
+ int scale_offset = jcp.is_oc_scale * (sizeof(float) * k * oc_block);
+ if (jcp.with_bias) {
+ int bias_offset = jcp.typesize_bia * k * oc_block;
+ auto bias_addr = EVEX_compress_addr(reg_bias, bias_offset);
+
+ cvt2ps(jcp.bia_dt, vmm_bias, bias_addr, mask_flag);
+ if (jcp.signed_input && jcp.ver != ver_vnni)
+ /* bias *= 0.5 */
+ vmulps(vmm_bias, vmm_bias, vmm_bias_alpha());
+ }
+ if (jcp.signed_input) {
+ int comp_offset = sizeof(int32_t) * k * oc_block;
+ auto comp_addr = EVEX_compress_addr(reg_compensation, comp_offset);
+
+ cvt2ps(data_type::s32, vmm_comp, comp_addr, mask_flag);
+ }
+ /* add to zmm_accum: compensation, bias and permute */
+ for (int j = 0; j < ur_w; j++) {
+ Vmm vmm = vmm_out(j, k);
+ if (jcp.is_fast_depthwise)
+ vpermd(zmm_out(j, k), zmm_permute, zmm_out(j, k));
+ vcvtdq2ps(vmm, vmm);
+ if (jcp.signed_input)
+ vaddps(vmm, vmm, vmm_comp);
+ if (jcp.with_bias)
+ vaddps(vmm, vmm, vmm_bias);
+
+ const Vmm vmm_k = vmm_mask(vmm, mask_flag);
+ vmulps(vmm_k, vmm,
+ EVEX_compress_addr(reg_ptr_scales, scale_offset));
+ }
+ }
+
+ /* Do post-ops */
+ if (maybe_eltwise(0)) compute_eltwise(ur_w);
+ if (p_sum_scale) { // post_op: sum
+ for (int k = 0; k < nb_oc_block; k++) {
+ const bool mask_flag = last_oc_block_flag && k == nb_oc_block - 1;
+ for (int j = 0; j < ur_w; j++) {
+ int aux_output_offset
+ = jcp.typesize_out
+ * (k * oc_block
+ + j * jcp.oc_without_padding * jcp.ngroups);
+ auto addr = EVEX_compress_addr(reg_out, aux_output_offset);
+ Vmm vmm = vmm_out(j, k);
+ cvt2ps(jcp.dst_dt, vmm_prev_dst, addr, mask_flag);
+ if (*p_sum_scale == 1.f)
+ vaddps(vmm, vmm_prev_dst);
+ else
+ vfmadd231ps(vmm, vmm_prev_dst, zword_b[reg_ptr_sum_scale]);
+ }
+ }
+ }
+ if (maybe_eltwise(1)) compute_eltwise(ur_w);
+
+ /* write out register to output_addr */
+ for (int k = 0; k < nb_oc_block; k++) {
+ const bool mask_flag = last_oc_block_flag && k == nb_oc_block - 1;
+ for (int j = 0; j < ur_w; j++) {
+ Vmm vmm = vmm_out(j, k);
+ if (jcp.dst_dt == data_type::u8) {
+ vpxord(vmm_zero, vmm_zero, vmm_zero);
+ vmaxps(vmm, vmm_zero, vmm);
+ }
+
+ if (jcp.dst_dt != data_type::f32) {
+ /* Note: using Zmm for rounding in Xmm/Ymm kernel
+ because there is no instruction to do rounding
+ from Xmm/Ymm -> Xmm/Ymm.
+ Embedded rounding is not supported for Xmm.
+ TODO: maybe avoid Zmm if it helps performance.*/
+ Zmm zmm = zmm_out(j, k);
+ vcvtps2dq(zmm, zmm);
+ }
+ }
+
+ for (int j = 0; j < ur_w; j++) {
+ int aux_output_offset = jcp.typesize_out
+ * (k * oc_block + j * jcp.oc_without_padding * jcp.ngroups);
+ auto addr = EVEX_compress_addr(reg_out, aux_output_offset);
+
+ Vmm vmm = vmm_out(j, k);
+ const Vmm r_vmm = vmm_mask(vmm, mask_flag, true);
+
+ switch (jcp.dst_dt) {
+ case data_type::f32:
+ case data_type::s32: vmovups(addr, r_vmm); break;
+ case data_type::s8: vpmovsdb(addr, r_vmm); break;
+ case data_type::u8: vpmovusdb(addr, r_vmm); break;
+ default: assert(!"unknown dst_dt");
+ }
+ }
+ }
+
+}
+
+template <typename Vmm>
+void _jit_avx512_core_x8s8s32x_fwd_kernel<Vmm>::compute_ker_dw(
+ int ur_w, int pad_l, int pad_r, ic_block_t last_ic_block_flag, bool h_padded) {
+ assert(!"invalid group blocking for depthwise convolution");
+}
+
+template <>
+void _jit_avx512_core_x8s8s32x_fwd_kernel<Zmm>::compute_ker_dw(
+ int ur_w, int pad_l, int pad_r, ic_block_t last_ic_block_flag, bool h_padded) {
+
+ auto input_spatial_index = [=](int oi, int ki) {
+ return (ki * (jcp.dilate_w + 1) + oi * jcp.stride_w - pad_l);
+ };
+
+ auto input_offset2 = [=](int ii, int ci) {
+ return jcp.typesize_in * (ii * jcp.ngroups + ci * jcp.ch_block);
+ };
+
+ auto input_offset3 = [=](int oi, int ci, int ki) {
+ return jcp.typesize_in * input_offset2(input_spatial_index(oi, ki), ci);
+ };
+
+ auto kernel_offset = [=](int ci, int ki) {
+ return jcp.typesize_in * ((ci * jcp.kh * jcp.kw + ki) * jcp.ch_block);
+ };
+
+ auto compute = [=](Zmm vreg_acc, Zmm vreg_wei, Zmm vreg_src) {
+ // okay for depthwise since src is zero-extended
+ if (jcp.ver == ver_vnni) {
+ vpdpbusd(vreg_acc, vreg_src, vreg_wei);
+ } else {
+ vpmaddwd(zmm_tmp, vreg_src, vreg_wei);
+ vpaddd(vreg_acc, vreg_acc, zmm_tmp);
+ }
+ };
+
+ int ii_start = 0;
+ int ii_end = -1;
+ if (jcp.is_resrc_depthwise && !h_padded) {
+ // find bounds of input spatial indices
+ bool first = true;
+ for (int ki = 0; ki < jcp.kw; ki++) {
+ int oi_start = get_ow_start(ki, pad_l);
+ int oi_end = get_ow_end(ur_w, ki, pad_r);
+ for (int oi = oi_start; oi < oi_end; oi++) {
+ int ii = input_spatial_index(oi, ki);
+ if (first || ii < ii_start)
+ ii_start = ii;
+ if (first || ii > ii_end)
+ ii_end = ii;
+ first = false;
+ }
+ }
+ }
+
+ if (jcp.signed_input) {
+ vpxord(zmm_shifted_zero, zmm_shifted_zero, zmm_shifted_zero);
+ vpaddb(zmm_shifted_zero, zmm_shifted_zero, vmm_shift);
+ }
+ for (int ci = 0; ci < jcp.nb_ch_blocking; ci++) {
+ const bool mask_flag = last_ic_block_flag != no_last_block
+ && ci == jcp.nb_ch_blocking - 1;
+ if (jcp.is_resrc_depthwise && !h_padded) {
+ // now we can load input once and reuse up to jcp.kw times
+ for (int ii = ii_start; ii <= ii_end; ii++) {
+ int aux_input_offset = input_offset2(ii, ci);
+ const Zmm zmm_inp_tmp = zmm_inp(ii, jcp.nb_ch_blocking);
+ const Zmm zmm_inp_msk = mask_flag
+ ? zmm_inp_tmp | ktail_mask | T_z
+ : zmm_inp_tmp;
+ if (jcp.is_fast_depthwise) {
+ assert(!mask_flag);
+ vbroadcasti32x4(zmm_inp_msk,
+ EVEX_compress_addr(aux_reg_inp, aux_input_offset));
+ } else {
+ vpmovzxbd(zmm_inp_msk,
+ EVEX_compress_addr(aux_reg_inp, aux_input_offset));
+ }
+ if (jcp.signed_input)
+ vpaddb(zmm_inp_tmp, zmm_inp_tmp, vmm_shift);
+ }
+ }
+ for (int ki = 0; ki < jcp.kw; ki++) {
+ int aux_kernel_offset = kernel_offset(ci, ki);
+ if (jcp.is_fast_depthwise) {
+ vbroadcasti32x4(zmm_wei,
+ EVEX_compress_addr(aux_reg_ker, aux_kernel_offset));
+ vmovdqu8(zmm_wei | kblend_mask | T_z, zmm_wei);
+ } else {
+ vpmovsxbd(zmm_wei,
+ EVEX_compress_addr(aux_reg_ker, aux_kernel_offset));
+ }
+ if (h_padded) {
+ assert(jcp.signed_input);
+ for (int oi = 0; oi < ur_w; oi++)
+ compute(zmm_out(oi, ci), zmm_wei, zmm_shifted_zero);
+ } else {
+ const Zmm r_zmm_src = mask_flag ? zmm_src | ktail_mask : zmm_src;
+ int oi_start = get_ow_start(ki, pad_l);
+ int oi_end = get_ow_end(ur_w, ki, pad_r);
+ int start_ = jcp.signed_input ? 0 : oi_start;
+ int end_ = jcp.signed_input ? ur_w : oi_end;
+ for (int oi = start_; oi < end_; oi++) {
+ if (oi >= oi_start && oi < oi_end) {
+ if (jcp.is_resrc_depthwise) {
+ int ii = input_spatial_index(oi, ki);
+ zmm_src = zmm_inp(ii, jcp.nb_ch_blocking);
+ } else {
+ int aux_input_offset = input_offset3(oi, ci, ki);
+ if (jcp.is_fast_depthwise) {
+ assert(!mask_flag);
+ vbroadcasti32x4(r_zmm_src,
+ EVEX_compress_addr(aux_reg_inp,
+ aux_input_offset));
+ } else {
+ vpmovzxbd(r_zmm_src,
+ EVEX_compress_addr(aux_reg_inp,
+ aux_input_offset));
+ }
+ if (jcp.signed_input)
+ vpaddb(zmm_src, zmm_src, vmm_shift);
+ }
+ } else if (jcp.signed_input) {
+ zmm_src = zmm_shifted_zero;
+ }
+ compute(zmm_out(oi, ci), zmm_wei, zmm_src);
+ }
+ }
+ }
+ }
+}
+
+template<typename Vmm>
+void _jit_avx512_core_x8s8s32x_fwd_kernel<Vmm>::compute_ker(int ur_w, int pad_l,
+ int pad_r, ic_block_t last_ic_block_flag, bool h_padded) {
+ if (jcp.is_depthwise)
+ return compute_ker_dw(ur_w, pad_l, pad_r, last_ic_block_flag, h_padded);
+
+ int kw = jcp.kw;
+ int stride_w = jcp.stride_w;
+ int ic_block = jcp.ic_block;
+ int oc_block = jcp.oc_block;
+ int ch_block_all = jcp.ch_block * ic_block * oc_block;
+
+ int nb_oc_block = jcp.nb_oc_blocking;
+
+ auto input_offset = [=](int oi, int ic, int ki) {
+ return jcp.typesize_in
+ * ((ki * (jcp.dilate_w + 1) + oi * stride_w - pad_l)
+ * jcp.ic_without_padding * jcp.ngroups + 4 * ic);
+ };
+ auto kernel_offset = [=](int ii, int ic, int ki) {
+ return jcp.typesize_in
+ * ((ii * jcp.nb_ic * jcp.kh * jcp.kw + ki) * ch_block_all
+ + 4 * ic * oc_block);
+ };
+ auto compute = [=](Vmm vreg_acc, Vmm vreg_wei, Vmm vreg_src) {
+ if (jcp.ver == ver_vnni) {
+ vpdpbusd(vreg_acc, vreg_src, vreg_wei);
+ } else {
+ vpmaddubsw(vmm_tmp, vreg_src, vreg_wei);
+ vpmaddwd(vmm_tmp, vmm_tmp, vmm_one);
+ vpaddd(vreg_acc, vreg_acc, vmm_tmp);
+ }
+ };
+
+ for (int ki = 0; ki < kw; ki++) {
+ int jj_start = get_ow_start(ki, pad_l);
+ int jj_end = get_ow_end(ur_w, ki, pad_r);
+ int tail_size = jcp.ic_without_padding % 4;
+ int _start = (jcp.signed_input) ? 0 : jj_start;
+ int _end = (jcp.signed_input) ? ur_w : jj_end;
+ /* Skip the last loads of input if (ic%16)/4 < ic_block/4 */
+ int icb = (last_ic_block_flag != no_last_block)
+ ? div_up((jcp.ic_without_padding % ic_block), 4)
+ : ic_block / 4;
+ for (int ic = 0; ic < icb; ic++) {
+ if (h_padded == true) {
+ /* fill padded area with shifted values */
+ Vmm inp = vmm_inp(0,nb_oc_block);
+ vpxord(inp, inp, inp);
+ vpaddb(inp, inp, vmm_shift);
+ } else {
+ for (int jj = _start; jj < _end; jj++) {
+ int aux_input_offset = input_offset(jj, ic, ki);
+ if (jj >= jj_start && jj < jj_end) {
+ if (last_ic_block_flag == last_sp_block
+ && tail_size != 0 && ic == icb - 1) {
+ Xmm xmm_tmp = Xmm(vmm_inp(jj, nb_oc_block).getIdx());
+ for (int r = 0; r < tail_size; ++r)
+ vpinsrb(xmm_tmp, xmm_tmp,
+ ptr[aux_reg_inp + aux_input_offset + r], r);
+ vpbroadcastd(vmm_inp(jj, nb_oc_block), xmm_tmp);
+ } else {
+ vpbroadcastd(vmm_inp(jj, nb_oc_block),
+ EVEX_compress_addr(
+ aux_reg_inp, aux_input_offset));
+ }
+ if (jcp.signed_input)
+ vpaddb(vmm_inp(jj, nb_oc_block),
+ vmm_inp(jj, nb_oc_block), vmm_shift);
+ } else {
+ /* fill padded area with shifted values */
+ if (jcp.signed_input) {
+ Vmm inp = vmm_inp(jj, nb_oc_block);
+ vpxord(inp, inp, inp);
+ vpaddb(inp, inp, vmm_shift);
+ }
+ }
+ }
+ }
+ for (int ii = 0; ii < nb_oc_block; ii++) {
+ int aux_kernel_offset = kernel_offset(ii, ic, ki);
+ vmovups(vmm_wei,
+ EVEX_compress_addr(aux_reg_ker, aux_kernel_offset));
+ for (int jj = _start; jj < _end; jj++) {
+ Vmm inp = (h_padded == true)
+ ? vmm_inp(0,nb_oc_block) : vmm_inp(jj, nb_oc_block);
+ compute(vmm_out(jj, ii), vmm_wei, inp);
+ }
+ }
+ }
+ }
+}
+
+template<typename Vmm>
+void _jit_avx512_core_x8s8s32x_fwd_kernel<Vmm>::kh_loop(
+ int ur_w, int pad_l, int pad_r, ic_block_t last_ic_block_flag) {
+ Label kh_label, skip_kh_loop;
+ Label t_overflow_label, no_t_overflow_label,
+ b_overflow_label, no_b_overflow_label;
+
+ int ch_block_all = jcp.ch_block * jcp.ic_block * jcp.oc_block;
+ int shift_kernel_ptr = jcp.typesize_in * jcp.kw * ch_block_all;
+ int shift_input_ptr = jcp.typesize_in * (jcp.dilate_h + 1) * jcp.iw
+ * jcp.ic_without_padding * jcp.ngroups;
+
+ mov(aux_reg_inp, reg_inp);
+ mov(aux_reg_ker, reg_ker);
+
+ if (jcp.signed_input && jcp.ndims > 3) {
+ mov(reg_overflow, ptr[param1 + GET_OFF(t_overflow)]);
+ cmp(reg_overflow, 0);
+ je(no_t_overflow_label, T_NEAR);
+ L(t_overflow_label); {
+ compute_ker(ur_w, pad_l, pad_r, last_ic_block_flag, true);
+
+ add(aux_reg_ker, shift_kernel_ptr);
+ dec(reg_overflow);
+ cmp(reg_overflow, 0);
+ jg(t_overflow_label, T_NEAR);
+ }
+ L(no_t_overflow_label);
+ }
+ mov(reg_kj, ptr[param1 + GET_OFF(kh_padding)]);
+ if ((jcp.signed_input) || (!jcp.signed_input &&
+ (jcp.kh - 1) * (jcp.dilate_h + 1) < nstl::max(jcp.t_pad, jcp.b_pad))) {
+ cmp(reg_kj, 0);
+ je(skip_kh_loop, T_NEAR);
+ }
+ L(kh_label); {
+ compute_ker(ur_w, pad_l, pad_r, last_ic_block_flag, false);
+
+ add(aux_reg_ker, shift_kernel_ptr);
+ add(aux_reg_inp, shift_input_ptr);
+ dec(reg_kj);
+ cmp(reg_kj, 0);
+ jg(kh_label, T_NEAR);
+ }
+ L(skip_kh_loop);
+ if (jcp.signed_input && jcp.ndims > 3) {
+ mov(reg_overflow, ptr[param1 + GET_OFF(b_overflow)]);
+ cmp(reg_overflow, 0);
+ je(no_b_overflow_label, T_NEAR);
+ L(b_overflow_label); {
+ compute_ker(ur_w, pad_l, pad_r, last_ic_block_flag, true);
+
+ add(aux_reg_ker, shift_kernel_ptr);
+ dec(reg_overflow);
+ cmp(reg_overflow, 0);
+ jg(b_overflow_label, T_NEAR);
+ }
+ L(no_b_overflow_label);
+ }
+}
+
+template<typename Vmm>
+void _jit_avx512_core_x8s8s32x_fwd_kernel<Vmm>::icb_loop(
+ int ur_w, int pad_l, int pad_r, bool is_last_sp_block)
+{
+ prepare_output(ur_w);
+
+ // IC loop
+ Label icb_label;
+ mov(reg_icb, jcp.nb_ic);
+ L(icb_label);
+ if (jcp.ngroups % jcp.ch_block != 0 || jcp.ic_without_padding != jcp.ic) {
+ Label common_ker, end_ker;
+
+ cmp(reg_icb, 1); // The last IC block
+ jne(common_ker, T_NEAR);
+
+ kh_loop(ur_w, pad_l, pad_r,
+ is_last_sp_block ? last_sp_block : last_ic_block);
+ jmp(end_ker, T_NEAR);
+
+ L(common_ker);
+ kh_loop(ur_w, pad_l, pad_r, no_last_block);
+
+ L(end_ker);
+ } else {
+ kh_loop(ur_w, pad_l, pad_r, no_last_block);
+ }
+ // End of IC Loop
+ int inp_step = jcp.ic_block;
+ int ker_step = jcp.kh * jcp.kw * jcp.oc_block * jcp.ic_block;
+ add(reg_inp, jcp.typesize_in * inp_step);
+ add(reg_ker, jcp.typesize_in * ker_step);
+
+ dec(reg_icb);
+ cmp(reg_icb, 0);
+ jg(icb_label, T_NEAR);
+
+ sub(reg_inp, jcp.typesize_in * inp_step * jcp.nb_ic);
+ sub(reg_ker, jcp.typesize_in * ker_step * jcp.nb_ic);
+
+ if (jcp.ngroups % jcp.ch_block != 0 || jcp.oc_without_padding != jcp.oc) {
+ Label common_store, end_store;
+
+ if (jcp.is_depthwise)
+ cmp(reg_oc_blocks, jcp.nb_ch - jcp.nb_ch_blocking);
+ else
+ cmp(reg_oc_blocks, jcp.nb_oc - jcp.nb_oc_blocking);
+
+ jne(common_store, T_NEAR);
+
+ store_output(ur_w, true); // last oc block
+ jmp(end_store, T_NEAR);
+
+ L(common_store);
+ store_output(ur_w, false);
+
+ L(end_store);
+ } else {
+ store_output(ur_w, false);
+ }
+}
+
+template<typename Vmm>
+void _jit_avx512_core_x8s8s32x_fwd_kernel<Vmm>::generate()
+{
+ Label permute_index_table;
+ int inp_shift_pad = jcp.typesize_in * (jcp.ur_w * jcp.stride_w - jcp.l_pad)
+ * jcp.ic_without_padding * jcp.ngroups;
+ int inp_shift_pad_second_block = -1 * jcp.typesize_in * jcp.l_pad
+ * jcp.ic_without_padding * jcp.ngroups;
+ int inp_shift = jcp.typesize_in *
+ (jcp.ur_w * jcp.stride_w * jcp.ic_without_padding
+ * jcp.ngroups);
+ int out_shift = jcp.typesize_out *
+ (jcp.ur_w * jcp.oc_without_padding * jcp.ngroups);
+ preamble();
+
+ if (jcp.is_depthwise) {
+ int idx = jcp.max_regs_ur - 1;
+ if (!jcp.is_resrc_depthwise)
+ zmm_src = Zmm(++idx);
+ if (jcp.ver != ver_vnni)
+ zmm_tmp = Zmm(++idx);
+ if (jcp.is_fast_depthwise)
+ zmm_permute = Zmm(++idx);
+ if (jcp.signed_input) {
+ zmm_shifted_zero = Zmm(++idx);
+ ++idx; // due to extra register used for shifts and compensations
+ }
+ assert(idx == ker_dw_reg_base_idx);
+ }
+
+ if (!jcp.is_depthwise && jcp.ver != ver_vnni) {
+ xor_(reg_scratch, reg_scratch);
+ Reg16 _t16 = reg_scratch.cvt16();
+ mov(_t16, 0x1);
+ vpbroadcastw(vmm_one, _t16);
+ }
+
+ mov(reg_inp, ptr[param1 + GET_OFF(src)]);
+ mov(reg_out, ptr[param1 + GET_OFF(dst)]);
+ mov(reg_ker, ptr[param1 + GET_OFF(filt)]);
+
+ if (jcp.ngroups % jcp.ch_block != 0 || jcp.oc_without_padding != jcp.oc) {
+ int tail_size = jcp.is_depthwise
+ ? jcp.ngroups % jcp.ch_block
+ : jcp.oc_without_padding % jcp.oc_block;
+ int mask = (1 << tail_size) - 1;
+ mov(reg_oc_blocks, ptr[param1 + GET_OFF(oc_blocks)]);
+ Reg32 regw_tmp = reg_oi.cvt32();
+ mov(regw_tmp, mask);
+ kmovw(ktail_mask, regw_tmp);
+ }
+ if (jcp.is_fast_depthwise) {
+ // prepare mask register for blending weights
+ mov(reg_scratch, 0x8888444422221111);
+ kmovq(kblend_mask, reg_scratch);
+ // load permute indices from data section
+ mov(reg_scratch, permute_index_table);
+ vmovdqu32(zmm_permute, ptr[reg_scratch]);
+ }
+
+ int r_pad = nstl::max(0, (jcp.ow - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1)
+ - (jcp.iw + jcp.l_pad - 1));
+ int n_oi = jcp.ow / jcp.ur_w;
+ int r_pad1 = (jcp.ur_w * n_oi - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1) - (jcp.iw + jcp.l_pad - 1);
+
+ if (jcp.nb_ow == 1) {
+ if (r_pad1 > 0 || jcp.ur_w_tail == 0)
+ n_oi--;
+
+ xor_(reg_oi, reg_oi);
+ if (jcp.ow == jcp.ur_w) {
+ icb_loop(jcp.ur_w, jcp.l_pad, r_pad, true);
+ } else {
+ if (n_oi == 0) {
+ icb_loop(jcp.ur_w, jcp.l_pad, r_pad1, jcp.ur_w_tail == 0);
+ add(reg_inp, inp_shift_pad);
+ add(reg_out, out_shift);
+ if (jcp.ur_w_tail != 0) {
+ icb_loop(jcp.ur_w_tail, 0, r_pad, true);
+ }
+ } else {
+ if (jcp.l_pad > 0) {
+ icb_loop(jcp.ur_w, jcp.l_pad, 0, false);
+ add(reg_inp, inp_shift_pad);
+ add(reg_out, out_shift);
+
+ inc(reg_oi);
+ }
+ if ((jcp.l_pad <= 0 && n_oi > 0) || (jcp.l_pad > 0 && n_oi > 1))
+ {
+ Label ow_loop_label;
+ L(ow_loop_label); {
+ icb_loop(jcp.ur_w, 0, 0, false);
+ add(reg_inp, inp_shift);
+ add(reg_out, out_shift);
+
+ inc(reg_oi);
+ cmp(reg_oi, n_oi);
+ jl(ow_loop_label, T_NEAR);
+ }
+ }
+ if (r_pad1 > 0 || jcp.ur_w_tail == 0) {
+ icb_loop(jcp.ur_w, 0, r_pad1, jcp.ur_w_tail == 0);
+ add(reg_inp, inp_shift);
+ add(reg_out, out_shift);
+ }
+ if (jcp.ur_w_tail != 0) {
+ icb_loop(jcp.ur_w_tail, 0, r_pad, true);
+ }
+ }
+ }
+ } else {
+ // ow block is only processed.
+ // Number of block is passed as parameter owb,
+ // and padding processing depends on this number.
+ Label end_label, last_oi_label, middle_ow_blocks_label, tail_label,
+ oi_loop_label, oi_loop_end_label;
+
+ assert(jcp.ow_block % jcp.ur_w == 0);
+ int n_oi_not_last_ow_block = jcp.ow_block / jcp.ur_w;
+ // to simplify code (and general regs usage),
+ // size of ow block must be >= 2 * ur_w
+ assert(n_oi_not_last_ow_block > 1);
+ int n_oi_next_last_ow_block = n_oi_not_last_ow_block;
+ int n_oi_first_ow_block = n_oi_not_last_ow_block;
+ int n_oi_last_ow_block
+ = (jcp.ow - jcp.ow_block * (jcp.nb_ow - 1)) / jcp.ur_w;
+ // prepare right padding
+ bool next_last_ow_block_padded = r_pad1 > 0 && n_oi_last_ow_block == 0;
+ bool first_ow_block_padded
+ = next_last_ow_block_padded && jcp.nb_ow == 2;
+ bool last_ow_block_padded
+ = (r_pad1 > 0 || jcp.ur_w_tail == 0) && n_oi_last_ow_block > 0;
+
+ if (last_ow_block_padded) n_oi_last_ow_block--;
+ else if (first_ow_block_padded) n_oi_first_ow_block--;
+ else if (next_last_ow_block_padded) n_oi_next_last_ow_block--;
+
+ mov(reg_owb, ptr[param1 + GET_OFF(owb)]);
+ cmp(reg_owb, 0); // is that the first ow-block ?
+ jg(middle_ow_blocks_label, T_NEAR);
+
+ // the first ow block, compute left padding
+ mov(reg_oi, n_oi_first_ow_block);
+ if (jcp.l_pad > 0) {
+ icb_loop(jcp.ur_w, jcp.l_pad, 0, false);
+ add(reg_inp, inp_shift_pad);
+ add(reg_out, out_shift);
+
+ dec(reg_oi);
+ }
+ jmp(oi_loop_label, T_NEAR);
+
+ // middle or last ow block entry
+ L(middle_ow_blocks_label);
+
+ if (jcp.l_pad > 0) {
+ // just to consider left padding, not compute
+ add(reg_inp, inp_shift_pad_second_block);
+ }
+
+ // set number of iteration for oi-loop
+ if (n_oi_last_ow_block != n_oi_not_last_ow_block) {
+ cmp(reg_owb, jcp.nb_ow - 1); // last ow-block ?
+ mov(reg_oi, n_oi_last_ow_block);
+ je(oi_loop_label, T_NEAR);
+ }
+
+ if (n_oi_next_last_ow_block != n_oi_not_last_ow_block) {
+ cmp(reg_owb, jcp.nb_ow - 2); // next to last ow-block ?
+
+ mov(reg_oi, n_oi_next_last_ow_block);
+ je(oi_loop_label, T_NEAR);
+ }
+ mov(reg_oi, n_oi_not_last_ow_block); // other middle ow-blocks
+
+ // oi loop w/o padding
+ L(oi_loop_label); {
+ cmp(reg_oi, 0);
+ jle(oi_loop_end_label, T_NEAR);
+
+ icb_loop(jcp.ur_w, 0, 0, false);
+
+ add(reg_inp, inp_shift);
+ add(reg_out, out_shift);
+ dec(reg_oi);
+
+ jmp(oi_loop_label, T_NEAR);
+ }
+ L(oi_loop_end_label);
+
+ mov(reg_owb, ptr[param1 + GET_OFF(owb)]);
+ cmp(reg_owb, 0); // first ow-block ?
+ if (first_ow_block_padded)
+ je(last_oi_label, T_NEAR);
+ else
+ je(end_label, T_NEAR);
+
+ cmp(reg_owb, jcp.nb_ow - 2); // next to last ow-block ?
+ jl(end_label, T_NEAR);
+ if (next_last_ow_block_padded)
+ je(last_oi_label, T_NEAR);
+ else
+ je(end_label, T_NEAR);
+
+ // that is last block
+ if (!last_ow_block_padded)
+ jmp(tail_label, T_NEAR);
+
+ // last oi block with right padding
+ L(last_oi_label);
+ icb_loop(jcp.ur_w, 0, r_pad1, jcp.ur_w_tail == 0);
+ add(reg_inp, inp_shift);
+ add(reg_out, out_shift);
+
+ mov(reg_owb, ptr[param1 + GET_OFF(owb)]);
+ cmp(reg_owb, jcp.nb_ow - 1); // last ow_block?
+ jl(end_label, T_NEAR);
+
+ // ur_w tail
+ L(tail_label);
+ if (jcp.ur_w_tail != 0) {
+ icb_loop(jcp.ur_w_tail, 0, r_pad, true);
+ }
+ L(end_label);
+ }
+ postamble();
+
+ if (jcp.with_eltwise)
+ eltwise_injector_->prepare_table();
+
+ if (jcp.is_fast_depthwise) {
+ align(64);
+ L(permute_index_table);
+ const uint32_t _idx[]
+ = { 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 };
+ for (size_t i = 0; i < sizeof(_idx) / sizeof(_idx[0]); ++i)
+ dd(_idx[i]);
+ }
+}
+
+bool jit_avx512_core_x8s8s32x_fwd_kernel::post_ops_ok(
+ jit_conv_conf_t &jcp, const primitive_attr_t &attr)
+{
+ using namespace primitive_kind;
+ const auto &p = attr.post_ops_;
+
+ auto is_eltwise = [&](int idx) { return p.entry_[idx].is_eltwise(); };
+
+ switch (p.len_) {
+ case 0: return true;
+ case 1: return is_eltwise(0) || p.contain(sum, 0);
+ case 2: return (p.contain(sum, 0) && is_eltwise(1)) ||
+ (p.contain(sum, 1) && is_eltwise(0));
+ default: return false;
+ }
+
+ return false;
+}
+
+status_t jit_avx512_core_x8s8s32x_fwd_kernel::init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, memory_desc_t &src_md,
+ memory_desc_t &weights_md, memory_desc_t &dst_md,
+ memory_desc_t &bias_md, const primitive_attr_t &attr,
+ int nthreads)
+{
+ using namespace prop_kind;
+
+ const memory_desc_wrapper src_d(&src_md);
+ const memory_desc_wrapper weights_d(&weights_md);
+ const memory_desc_wrapper dst_d(&dst_md);
+ const memory_desc_wrapper bias_d(&bias_md);
+
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+ int ndims = src_d.ndims();
+ bool is_1d = ndims == 3;
+
+ if (!(mayiuse(avx512_core)
+ && one_of(src_d.data_type(), data_type::u8, data_type::s8)
+ && weights_d.data_type() == data_type::s8
+ && one_of(dst_d.data_type(), data_type::f32, data_type::s32,
+ data_type::s8, data_type::u8)))
+ return status::unimplemented;
+
+ jcp = zero<decltype(jcp)>();
+ jcp.ndims = ndims;
+ jcp.prop_kind = cd.prop_kind;
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+ jcp.ic_without_padding = jcp.ic;
+ jcp.ih = is_1d ? 1 : src_d.dims()[ndims - 2];
+ jcp.iw = src_d.dims()[ndims - 1];
+ jcp.oh = is_1d ? 1 : dst_d.dims()[ndims - 2];
+ jcp.ow = dst_d.dims()[ndims - 1];
+ jcp.kh = is_1d ? 1 : weights_d.dims()[with_groups + ndims - 2];
+ jcp.kw = weights_d.dims()[with_groups + ndims - 1];
+ jcp.t_pad = is_1d ? 0 : cd.padding[0][ndims - 4];
+ jcp.l_pad = cd.padding[0][ndims - 3];
+ jcp.stride_h = is_1d ? 1 : cd.strides[ndims - 4];
+ jcp.stride_w = cd.strides[ndims - 3];
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+
+ jcp.ur_h = 1; /* no code-unrolling by h so far */
+
+ jcp.dilate_h = is_1d ? 0 : cd.dilates[ndims - 4];
+ jcp.dilate_w = cd.dilates[ndims - 3];
+
+ jcp.signed_input = (src_d.data_type() == data_type::s8) ? true : false;
+ jcp.is_depthwise = true && with_groups && everyone_is(1, jcp.ic, jcp.oc);
+
+ if (jcp.is_depthwise) {
+ jcp.ch_block = 16;
+ jcp.ic_block = 1;
+ jcp.oc_block = 1;
+ } else {
+ jcp.ch_block = 1;
+ jcp.ic_block = 16;
+ jcp.oc_block = 16;
+
+ if (jcp.ngroups == 1) {
+ /* For non grouped convolutions, pad channels by 16 if needed */
+ jcp.oc = rnd_up(jcp.oc, jcp.oc_block);
+ jcp.ic = rnd_up(jcp.ic, jcp.ic_block);
+ } else if (!is_1d && jcp.ngroups != 1 && jcp.ic % jcp.ic_block != 0) {
+ /* For grouped convolutions, MKL-DNN doesn't support padding.
+ Use Ymm when channels per group is multiple of 8,
+ Xmm when channels per group is multiple of 4 */
+ jcp.ic_block = jcp.ic % 8 == 0 ? 8 : 4;
+ jcp.oc_block = jcp.ic_block;
+ }
+ if (jcp.ic % jcp.ic_block !=0 || jcp.oc % jcp.oc_block != 0)
+ return status::unimplemented;
+ }
+
+ jcp.b_pad = (jcp.oh - 1) * jcp.stride_h + (jcp.kh - 1) * (jcp.dilate_h + 1)
+ - (jcp.ih + jcp.t_pad - 1);
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ const int eltwise_ind = p.find(primitive_kind::eltwise);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise)
+ jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+
+ jcp.ver = mayiuse(avx512_core_vnni) ? ver_vnni : ver_avx512_core;
+ jcp.is_fast_depthwise = true && jcp.is_depthwise && jcp.ver == ver_vnni
+ && jcp.ngroups % jcp.ch_block == 0; // for groups not multiple of 16
+ // would require byte masking
+ // for load from src
+ jcp.is_resrc_depthwise = jcp.is_depthwise && jcp.stride_w < jcp.kw
+ && jcp.kw < 4 && jcp.dilate_w == 0;
+ if (jcp.is_depthwise) {
+ jcp.max_regs_ur = 31 - jcp.is_fast_depthwise - !jcp.is_resrc_depthwise
+ - 2 * jcp.signed_input - (jcp.ver != ver_vnni);
+ } else {
+ jcp.max_regs_ur = jcp.ver == ver_vnni ? 31 : 28;
+ }
+
+ auto set_or_check_wei_format = [&]() {
+ using namespace format_tag;
+ format_tag_t wei_tag;
+ if (jcp.ic_block == 16 || jcp.ch_block == 16) {
+ if (is_1d) {
+ wei_tag = with_groups
+ ? jcp.is_depthwise ? Goiw16g : gOIw4i16o4i
+ : OIw4i16o4i;
+ } else {
+ wei_tag = with_groups
+ ? jcp.is_depthwise ? Goihw16g : gOIhw4i16o4i
+ : OIhw4i16o4i;
+ }
+ } else if (with_groups && jcp.ic_block == 8) {
+ wei_tag = gOIhw2i8o4i;
+ } else
+ wei_tag = gOIhw4o4i;
+
+ memory_desc_t want_wei_md = weights_md;
+ memory_desc_init_by_tag(want_wei_md, wei_tag);
+ if (jcp.signed_input) {
+ want_wei_md.extra.flags = 0
+ | memory_extra_flags::compensation_conv_s8s8
+ | memory_extra_flags::scale_adjust;
+ want_wei_md.extra.compensation_mask = (1 << 0)
+ + (with_groups && !jcp.is_depthwise ? (1 << 1) : 0);
+ want_wei_md.extra.scale_adjust =
+ mayiuse(avx512_core_vnni) ? 1.f : 0.5f;
+ }
+
+ if (weights_md.format_kind == format_kind::any) {
+ weights_md = want_wei_md;
+ return true;
+ }
+
+ return weights_md == want_wei_md;
+ };
+
+ if (!set_or_check_wei_format())
+ return status::unimplemented;
+
+ format_tag_t dat_tag = utils::pick(ndims - 3,
+ format_tag::nwc, format_tag::nhwc);
+
+ if (src_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(src_md, dat_tag));
+ jcp.src_tag = dat_tag;
+ } else {
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ }
+ if (jcp.src_tag != dat_tag)
+ return status::unimplemented;
+
+ if (dst_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(dst_md, dat_tag));
+ jcp.dst_tag = dat_tag;
+ } else {
+ jcp.dst_tag = dst_d.matches_one_of_tag(dat_tag);
+ }
+ if (jcp.dst_tag != dat_tag)
+ return status::unimplemented;
+
+ if (jcp.with_bias) {
+ if (bias_d.format_kind() == format_kind::any)
+ CHECK(memory_desc_init_by_tag(bias_md, format_tag::x));
+ }
+
+ jcp.bia_dt = jcp.with_bias ? cd.bias_desc.data_type : data_type::undef;
+ jcp.dst_dt = cd.dst_desc.data_type;
+
+ jcp.typesize_in = types::data_type_size(src_d.data_type());
+ jcp.typesize_out = types::data_type_size(dst_d.data_type());
+ jcp.typesize_bia = jcp.with_bias
+ ? types::data_type_size(bias_d.data_type())
+ : 0;
+
+ jcp.nb_ch = div_up(jcp.ngroups, jcp.ch_block);
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+ jcp.nb_oc = jcp.oc / jcp.oc_block;
+
+ // Try to use 4 channel-groups at a time to avoid false sharing (depthwise)
+ int nb_ch_blocking = 4;
+ for ( /* init above */ ; nb_ch_blocking > 1; nb_ch_blocking--)
+ if (jcp.nb_ch % nb_ch_blocking == 0)
+ break;
+ jcp.nb_ch_blocking = jcp.is_depthwise ? nb_ch_blocking : 1;
+
+ // If OC blocking is incommensurate with the number of OC blocks (general
+ // requirement for all convolutions), or if it results in an unrolling
+ // factor smaller than the left padding (special requirement for SSD:fc6),
+ // then search for a smaller OC blocking that satisfies both constraints.
+ auto is_oc_blocking_ok = [&](int block) {
+ int ur_w = nstl::min(jcp.ow, jcp.max_regs_ur / (block + 1));
+ return jcp.nb_oc % block == 0
+ && jcp.l_pad <= ur_w && jcp.ow % ur_w != 1;
+ };
+
+ // choose nb_oc work chunk size for distribution within threads
+ int max_threading_nb_oc_chunk = 4;
+ // Performance improvements for googlenet_v3 and resnet_50 with mb = 1;
+ // TODO: generalize this condition and rewrite it in appropriate manner
+ if (jcp.ver == ver_vnni && jcp.mb == 1 && jcp.kh == 3 && jcp.kw == 3
+ && jcp.stride_w == 1 && jcp.ic % 64 == 0)
+ max_threading_nb_oc_chunk = 2;
+ jcp.nb_oc_blocking_thr_chunk =
+ nstl::min(max_threading_nb_oc_chunk, jcp.nb_oc);
+ for (; jcp.nb_oc_blocking_thr_chunk > 1; jcp.nb_oc_blocking_thr_chunk--) {
+ if (is_oc_blocking_ok(jcp.nb_oc_blocking_thr_chunk))
+ break;
+ }
+
+ // choose oc blocking for computational kernel
+ jcp.nb_oc_blocking = jcp.nb_oc_blocking_thr_chunk;
+ // Performance improvements for googlenet_v3 with mb = 1;
+ // TODO: generalize this condition and rewrite it in appropriate manner
+ const int size_treshold_for_nb_oc_blocking_reduction = 17;
+ if (jcp.mb == 1 && jcp.ow <= size_treshold_for_nb_oc_blocking_reduction
+ && jcp.stride_w == 1
+ && !(jcp.kh == 1 && jcp.kw == 3)
+ && !(jcp.kh >= 7 && jcp.oc % 64 == 0)) {
+ const int max_nb_oc_blocking = 2;
+ jcp.nb_oc_blocking = nstl::min(max_nb_oc_blocking, jcp.nb_oc);
+ for (; jcp.nb_oc_blocking > 1; jcp.nb_oc_blocking--)
+ if (jcp.nb_oc_blocking_thr_chunk % jcp.nb_oc_blocking == 0
+ && is_oc_blocking_ok(jcp.nb_oc_blocking))
+ break;
+ }
+
+ if (jcp.is_resrc_depthwise)
+ jcp.ur_w = (jcp.max_regs_ur - jcp.kw + jcp.stride_w)
+ / (jcp.nb_ch_blocking + jcp.stride_w);
+ else
+ jcp.ur_w
+ = jcp.max_regs_ur / (jcp.is_depthwise ? jcp.nb_ch_blocking
+ : jcp.nb_oc_blocking + 1);
+ if (jcp.ow < jcp.ur_w)
+ jcp.ur_w = jcp.ow;
+ jcp.ur_w_tail = jcp.ow % jcp.ur_w;
+
+ jcp.ow_block = jcp.ow;
+ int base_work_amount = jcp.mb * jcp.nb_ch * jcp.oh
+ * (jcp.nb_oc / jcp.nb_oc_blocking_thr_chunk);
+ float best_thr_eff
+ = (float)base_work_amount / rnd_up(base_work_amount, nthreads);
+ int max_nb_ow = div_up(jcp.ow, 2 * jcp.ur_w);
+ for (int nb_ow = 1; nb_ow <= max_nb_ow; nb_ow++) {
+ int ow_block
+ = nstl::min(rnd_up(div_up(jcp.ow, nb_ow), jcp.ur_w), jcp.ow);
+ if (ow_block < jcp.nb_oc_blocking_thr_chunk * jcp.oc_block
+ && best_thr_eff > 0.8f)
+ break;
+ if (div_up(jcp.ow, ow_block) != nb_ow)
+ continue;
+ auto work_amount = base_work_amount * nb_ow;
+ float thr_eff = (float)work_amount / rnd_up(work_amount, nthreads);
+ if (ow_block >= 2 * jcp.ur_w && thr_eff > 1.1f * best_thr_eff) {
+ jcp.ow_block = ow_block;
+ best_thr_eff = thr_eff;
+ }
+ if (best_thr_eff > 0.9f)
+ break;
+ }
+ jcp.nb_ow = div_up(jcp.ow, jcp.ow_block);
+
+ bool args_ok = true
+ && jcp.oc % jcp.oc_block == 0
+ && jcp.l_pad <= jcp.ur_w
+ && IMPLICATION(!jcp.is_1stconv, jcp.ic % jcp.ic_block == 0);
+ if (!args_ok)
+ return status::unimplemented;
+
+ int r_pad_no_tail = nstl::max(0, (jcp.ow - jcp.ur_w_tail - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1)
+ - (jcp.iw + jcp.l_pad - 1));
+ if (r_pad_no_tail > jcp.ur_w)
+ return status::unimplemented;
+
+ pick_loop_order(jcp, nthreads);
+
+ jcp.nb_ic_L2 = jcp.nb_ic;
+
+ const auto &oscales = attr.output_scales_;
+ jcp.is_oc_scale = oscales.mask_ == 1 << 1;
+
+ assert(IMPLICATION(!jcp.is_oc_scale, oscales.mask_ == 0));
+
+ jcp.wei_adj_scale =
+ (weights_d.extra().flags | memory_extra_flags::scale_adjust)
+ ? weights_d.extra().scale_adjust : 1.f;
+
+ return status::success;
+}
+
+void jit_avx512_core_x8s8s32x_fwd_kernel::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad, const jit_conv_conf_t &jcp,
+ const primitive_attr_t &attr) {
+ if (jcp.signed_input && jcp.ver != ver_vnni) {
+ dim_t count = nstl::max(attr.output_scales_.count_, (dim_t)jcp.ic_block);
+ scratchpad.book(key_conv_adjusted_scales, sizeof(float) * count);
+ }
+}
+
+template struct _jit_avx512_core_x8s8s32x_fwd_kernel<Zmm>;
+template struct _jit_avx512_core_x8s8s32x_fwd_kernel<Ymm>;
+template struct _jit_avx512_core_x8s8s32x_fwd_kernel<Xmm>;
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_conv_kernel.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_conv_kernel.hpp
new file mode 100644
index 0000000000..d8a05ad53e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_conv_kernel.hpp
@@ -0,0 +1,239 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_CORE_X8S8S32X_CONV_KERNEL_HPP
+#define CPU_JIT_AVX512_CORE_X8S8S32X_CONV_KERNEL_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+#include "jit_uni_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template<typename Vmm>
+struct _jit_avx512_core_x8s8s32x_fwd_kernel : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(_jit_avx512_core_x8s8s32x_conv_fwd_ker_t)
+
+ enum { STATE_FIRST_DST_LOAD = 0x1U };
+
+ _jit_avx512_core_x8s8s32x_fwd_kernel(jit_conv_conf_t ajcp,
+ const primitive_attr_t &attr) : jcp(ajcp), attr_(attr),
+ eltwise_injector_(nullptr)
+ {
+ if (jcp.with_eltwise)
+ eltwise_injector_ = new jit_uni_eltwise_injector_f32<avx512_common>(
+ this, jcp.eltwise);
+
+ generate();
+ jit_ker_ = (void (*)(jit_conv_call_s *))getCode();
+ }
+
+ ~_jit_avx512_core_x8s8s32x_fwd_kernel() {
+ delete eltwise_injector_;
+ }
+
+ jit_conv_conf_t jcp;
+ const primitive_attr_t &attr_;
+ void (*jit_ker_)(jit_conv_call_s *);
+
+private:
+ jit_uni_eltwise_injector_f32<avx512_common> *eltwise_injector_;
+
+ enum {
+ typesize = sizeof(float),
+ ker_reg_base_idx = 28,
+ ker_dw_reg_base_idx = 30,
+ };
+ typedef enum {
+ no_last_block,
+ last_ic_block,
+ last_sp_block,
+ } ic_block_t;
+
+ /* data regs */
+ const Xbyak::Reg64 reg_ptr_scales = rax;
+ const Xbyak::Reg64 reg_inp = r8;
+ const Xbyak::Reg64 reg_ker = r9;
+ const Xbyak::Reg64 reg_out = r10;
+ const Xbyak::Reg64 aux_reg_inp = r11;
+ const Xbyak::Reg64 reg_ptr_sum_scale = r11;
+ const Xbyak::Reg64 aux_reg_ker = r12;
+ const Xbyak::Reg64 reg_compensation = r14;
+ /* counter regs */
+ const Xbyak::Reg64 reg_bias_alpha = abi_not_param1;
+ const Xbyak::Reg64 reg_oi = rbx;
+ const Xbyak::Reg64 reg_bias = rdx;
+ const Xbyak::Reg64 reg_oc_blocks = rsi;
+ const Xbyak::Reg64 reg_owb = aux_reg_ker;
+ const Xbyak::Reg64 reg_scratch = reg_compensation;
+ const Xbyak::Reg64 reg_kj = reg_ptr_scales;
+ const Xbyak::Reg64 reg_overflow = reg_ptr_scales;
+ const Xbyak::Reg64 reg_icb = reg_bias;
+
+ const Xbyak::Opmask ktail_mask = Xbyak::Opmask(2);
+ const Xbyak::Opmask kblend_mask = Xbyak::Opmask(3);
+
+ const Vmm vmm_wei = Vmm(31);
+ /* used during bias section of store_output */
+ const Vmm vmm_comp = Vmm(30); // only for signed input
+ const Vmm vmm_bias = Vmm(31);
+ /* used during post_op sum section of store_output */
+ const Vmm vmm_prev_dst = Vmm(31);
+ /* used during write-out section of store_output */
+ const Vmm vmm_zero = Vmm(31);
+
+ /* used in compute_ker (but set during prepare_output) */
+ const Vmm vmm_shift = vmm_comp; // only for signed input
+ /* used in compute_ker (but only for pre-VNNI machines) */
+ const Vmm vmm_tmp = Vmm(28); // not used for depthwise
+ const Vmm vmm_one = Vmm(29); // set at start of kernel, not used for depthwise.
+
+ /* registers use only for depthwise
+ groups are always blocked by 16(padded if needed),
+ hence use only Zmm registers */
+ const Xbyak::Zmm zmm_wei = Xbyak::Zmm(31);
+ Xbyak::Zmm zmm_tmp;
+ Xbyak::Zmm zmm_src;
+ Xbyak::Zmm zmm_shifted_zero;
+ Xbyak::Zmm zmm_permute;
+
+ Vmm vmm_out(int i_ur, int i_oc) {
+ int idx = i_ur + i_oc * jcp.ur_w;
+ assert(idx < (jcp.is_depthwise
+ ? ker_dw_reg_base_idx : ker_reg_base_idx));
+ return Vmm(idx);
+ }
+ Xbyak::Zmm zmm_out(int i_ur, int i_oc) {
+ int idx = i_ur + i_oc * jcp.ur_w;
+ assert(idx < (jcp.is_depthwise
+ ? ker_dw_reg_base_idx : ker_reg_base_idx));
+ return Xbyak::Zmm(idx);
+ }
+ Vmm vmm_inp(int i_ic, int nb_x_blocking) {
+ int idx = i_ic + nb_x_blocking * jcp.ur_w;
+ assert(idx < 31);
+ return Vmm(idx);
+ }
+ Xbyak::Zmm zmm_inp(int i_ic, int nb_x_blocking) {
+ int idx = i_ic + nb_x_blocking * jcp.ur_w;
+ assert(idx < 31);
+ return Xbyak::Zmm(idx);
+ }
+ Vmm vmm_bias_alpha() {
+ int nb_c_block = jcp.is_depthwise ? jcp.nb_ch_blocking : jcp.nb_oc_blocking;
+ return Vmm(nb_c_block * jcp.ur_w);
+ }
+ Xbyak::Xmm xmm_bias_alpha() {
+ int nb_c_block = jcp.is_depthwise ? jcp.nb_ch_blocking : jcp.nb_oc_blocking;
+ return Xbyak::Xmm(nb_c_block * jcp.ur_w);
+ }
+ int get_ow_start(int ki, int pad_l) {
+ return nstl::max(0,
+ utils::div_up(pad_l - ki * (jcp.dilate_w + 1), jcp.stride_w));
+ }
+ int get_ow_end(int ur_w, int ki, int pad_r) {
+ return ur_w - nstl::max(0, utils::div_up(pad_r
+ - (jcp.kw - 1 - ki)
+ * (jcp.dilate_w + 1),
+ jcp.stride_w));
+ }
+
+ bool maybe_eltwise(int position);
+ void prepare_output(int ur_w);
+ void store_output(int ur_w, bool last_oc_block_flag);
+ void compute_ker_dw(
+ int ur_w, int pad_l, int pad_r, ic_block_t last_ic_block_flag, bool h_padded);
+ void compute_ker(int ur_w, int pad_l, int pad_r,
+ ic_block_t last_ic_block_flag, bool h_padded = false);
+ void compute_eltwise(int ur_w);
+ void kh_loop(int ur_w, int pad_l, int pad_r, ic_block_t last_ic_block_flag);
+ void icb_loop(
+ int ur_w, int pad_l, int pad_r, bool is_last_spatial_block);
+ void generate();
+ void cvt2ps(data_type_t type_in, Vmm ymm_in, const Xbyak::Operand &op,
+ bool mask_flag);
+ const Vmm vmm_mask(const Vmm vmm_in, bool mask_flag, bool store = false);
+};
+
+struct jit_avx512_core_x8s8s32x_fwd_kernel {
+
+ jit_avx512_core_x8s8s32x_fwd_kernel(jit_conv_conf_t ajcp,
+ const primitive_attr_t &attr) :
+ jit_ker(nullptr),
+ zmm_kernel_(nullptr),
+ ymm_kernel_(nullptr),
+ xmm_kernel_(nullptr) {
+ int ch_block = ajcp.is_depthwise ? ajcp.ch_block : ajcp.ic_block;
+ switch (ch_block) {
+ case 16:
+ zmm_kernel_ =
+ new _jit_avx512_core_x8s8s32x_fwd_kernel<Xbyak::Zmm>(
+ ajcp, attr);
+ jit_ker = zmm_kernel_->jit_ker_;
+ return;
+ case 8:
+ ymm_kernel_ =
+ new _jit_avx512_core_x8s8s32x_fwd_kernel<Xbyak::Ymm>(
+ ajcp, attr);
+ jit_ker = ymm_kernel_->jit_ker_;
+ return;
+ case 4:
+ xmm_kernel_ =
+ new _jit_avx512_core_x8s8s32x_fwd_kernel<Xbyak::Xmm>(
+ ajcp, attr);
+ jit_ker = xmm_kernel_->jit_ker_;
+ return;
+ default:
+ assert(!"invalid channel blocking");
+ }
+ }
+
+ ~jit_avx512_core_x8s8s32x_fwd_kernel() {
+ delete xmm_kernel_;
+ delete ymm_kernel_;
+ delete zmm_kernel_;
+ }
+
+ static bool post_ops_ok(jit_conv_conf_t &jcp,
+ const primitive_attr_t &attr);
+
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd,
+ memory_desc_t &src_pd,
+ memory_desc_t &weights_pd,
+ memory_desc_t &dst_pd,
+ memory_desc_t &bias_pd,
+ const primitive_attr_t &attr,
+ int nthreads);
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_conf_t &jcp, const primitive_attr_t &attr);
+
+ void (*jit_ker)(jit_conv_call_s *);
+ _jit_avx512_core_x8s8s32x_fwd_kernel<Xbyak::Zmm> *zmm_kernel_;
+ _jit_avx512_core_x8s8s32x_fwd_kernel<Xbyak::Ymm> *ymm_kernel_;
+ _jit_avx512_core_x8s8s32x_fwd_kernel<Xbyak::Xmm> *xmm_kernel_;
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_convolution.cpp
new file mode 100644
index 0000000000..cdbf333d5e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_convolution.cpp
@@ -0,0 +1,423 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_avx512_core_x8s8s32x_convolution.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+
+using namespace nstl;
+
+using jit_conv_ker_t = void (*)(jit_conv_call_s *);
+
+#define wht_blk_off(d, g, ...) \
+ (pd()->with_groups() \
+ ? (d).blk_off((g), __VA_ARGS__) \
+ : (d).blk_off(__VA_ARGS__))
+
+template <data_type_t src_type, data_type_t dst_type>
+void jit_avx512_core_x8s8s32x_convolution_fwd_t<src_type,
+ dst_type>::execute_forward_1d(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ const size_t bia_dt_size = pd()->with_bias()
+ ? types::data_type_size(pd()->desc()->bias_desc.data_type) : 0;
+
+ const auto &jcp = pd()->jcp_;
+ assert(jcp.nb_oc % jcp.nb_oc_blocking == 0);
+ assert(jcp.nb_ch % jcp.nb_ch_blocking == 0);
+
+ const float *oscales = pd()->attr()->output_scales_.scales_;
+ if (jcp.signed_input && jcp.ver != ver_vnni) {
+ auto local_scales = scratchpad(ctx).template get<float>(
+ key_conv_adjusted_scales);
+ size_t count = pd()->attr()->output_scales_.count_;
+ float factor = 1.f / pd()->jcp_.wei_adj_scale;
+ if (count == 1) {
+ utils::array_set(local_scales, oscales[0] * factor, 16);
+ } else {
+ for (size_t c = 0; c < count; c++)
+ local_scales[c] = oscales[c] * factor;
+ }
+ oscales = local_scales;
+ }
+
+ size_t offset = weights_d.size() - weights_d.additional_buffer_size();
+ auto w = const_cast<wei_data_t *>(weights);
+ int32_t* compensation = (jcp.signed_input)
+ ? reinterpret_cast<int32_t *>(&w[offset]) : 0;
+ int oc_chunks = jcp.nb_oc / jcp.nb_oc_blocking;
+ int nb_groups = jcp.nb_ch / jcp.nb_ch_blocking;
+ int group_block = jcp.ch_block;
+ int work_amount = jcp.mb * nb_groups * oc_chunks * jcp.nb_ow;
+
+ parallel(0, [&](const int ithr, const int nthr) {
+
+ int start{ 0 }, end{ 0 };
+ balance211(work_amount, nthr, ithr, start, end);
+
+ auto p = jit_conv_call_s();
+
+ int n{ 0 }, gg{ 0 }, occ{ 0 }, owb{ 0 };
+ switch (jcp.loop_order) {
+ case loop_cwgn:
+ nd_iterator_init(start, occ, oc_chunks, owb, jcp.nb_ow, gg,
+ nb_groups, n, jcp.mb);
+ break;
+ case loop_gncw:
+ nd_iterator_init(start, gg, nb_groups, n, jcp.mb, occ, oc_chunks,
+ owb, jcp.nb_ow);
+ break;
+ case loop_ngcw:
+ nd_iterator_init(start, n, jcp.mb, gg, nb_groups, occ, oc_chunks,
+ owb, jcp.nb_ow);
+ break;
+ case loop_nwcg:
+ nd_iterator_init(start, n, jcp.mb, owb, jcp.nb_ow, occ, oc_chunks,
+ gg, nb_groups);
+ break;
+ default: assert(!"unsupported loop order");
+ }
+ while (start < end) {
+ int ocb = occ * jcp.nb_oc_blocking;
+ int gb = gg * jcp.nb_ch_blocking;
+ int g = gb * group_block;
+ int g_oc = (g * jcp.nb_oc + ocb) * jcp.oc_block;
+ int g_ic = g * jcp.nb_ic * jcp.ic_block;
+ int ow_s = owb * jcp.ow_block;
+ int iw_s = ow_s * jcp.stride_w;
+
+ p.bias = bias ? bias + (bias_d.blk_off(g_oc) * bia_dt_size) : 0;
+ p.compensation = (jcp.signed_input) ? compensation + g_oc : 0;
+ p.dst = dst + dst_d.blk_off(n, g_oc, ow_s);
+ p.src = src + src_d.blk_off(n, g_ic, iw_s);
+ p.filt = weights + wht_blk_off(weights_d, gb, ocb, 0);
+ p.scales = &oscales[jcp.is_oc_scale * g_oc];
+ p.oc_blocks = jcp.is_depthwise ? gb : ocb;
+ p.kh_padding = jcp.kh;
+ p.t_overflow = 0;
+ p.b_overflow = 0;
+ p.owb = owb;
+
+ kernel_->jit_ker(&p);
+
+ ++start;
+ switch (jcp.loop_order) {
+ case loop_cwgn:
+ nd_iterator_step(occ, oc_chunks, owb, jcp.nb_ow, gg, nb_groups,
+ n, jcp.mb);
+ break;
+ case loop_gncw:
+ nd_iterator_step(gg, nb_groups, n, jcp.mb, occ, oc_chunks, owb,
+ jcp.nb_ow);
+ break;
+ case loop_ngcw:
+ nd_iterator_step(n, jcp.mb, gg, nb_groups, occ, oc_chunks, owb,
+ jcp.nb_ow);
+ break;
+ case loop_nwcg:
+ nd_iterator_step(n, jcp.mb, owb, jcp.nb_ow, occ, oc_chunks, gg,
+ nb_groups);
+ break;
+ default: assert(!"unsupported loop order");
+ }
+ }
+ });
+}
+
+template <data_type_t src_type, data_type_t dst_type>
+void jit_avx512_core_x8s8s32x_convolution_fwd_t<src_type,
+ dst_type>::execute_forward_2d(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ const size_t bia_dt_size = pd()->with_bias()
+ ? types::data_type_size(pd()->desc()->bias_desc.data_type) : 0;
+
+ const auto &jcp = pd()->jcp_;
+ assert(jcp.ch_block == 1);
+ assert(jcp.nb_ch_blocking == 1);
+ assert(jcp.nb_oc % jcp.nb_oc_blocking == 0);
+ assert(jcp.nb_ch % jcp.nb_ch_blocking == 0);
+
+ const float *oscales = pd()->attr()->output_scales_.scales_;
+ if (jcp.signed_input && jcp.ver != ver_vnni) {
+ auto local_scales = scratchpad(ctx).template get<float>(
+ key_conv_adjusted_scales);
+ size_t count = pd()->attr()->output_scales_.count_;
+ float factor = 1.f / pd()->jcp_.wei_adj_scale;
+ if (count == 1) {
+ utils::array_set(local_scales, oscales[0] * factor, 16);
+ } else {
+ for (size_t c = 0; c < count; c++)
+ local_scales[c] = oscales[c] * factor;
+ }
+ oscales = local_scales;
+ }
+
+ size_t offset = weights_d.size() - weights_d.additional_buffer_size();
+ auto w = const_cast<wei_data_t *>(weights);
+ int32_t* compensation = (jcp.signed_input)
+ ? reinterpret_cast<int32_t *>(&w[offset]) : 0;
+ int oc_chunks = jcp.nb_oc / jcp.nb_oc_blocking_thr_chunk;
+ int nb_groups = jcp.nb_ch;
+ int work_amount = jcp.mb * nb_groups * oc_chunks * jcp.oh * jcp.nb_ow;
+
+ parallel(0, [&](const int ithr, const int nthr) {
+
+ int start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+
+ auto p = jit_conv_call_s();
+
+ size_t src_h_stride = src_d.blk_off(0, 0, 1);
+ size_t dst_h_stride = dst_d.blk_off(0, 0, 1);
+ size_t wht_h_stride = wht_blk_off(weights_d, 0, 0, 0, 1);
+
+ int n{ 0 }, g{ 0 }, occ{ 0 }, oh_s{ 0 }, owb{ 0 };
+ switch (jcp.loop_order) {
+ case loop_cwgn:
+ nd_iterator_init(start, occ, oc_chunks, owb, jcp.nb_ow, g,
+ nb_groups, n, jcp.mb, oh_s, jcp.oh);
+ break;
+ case loop_ngcw:
+ nd_iterator_init(start, n, jcp.mb, g, nb_groups, occ, oc_chunks,
+ owb, jcp.nb_ow, oh_s, jcp.oh);
+ break;
+ case loop_nhwcg:
+ nd_iterator_init(start, n, jcp.mb, oh_s, jcp.oh, owb, jcp.nb_ow,
+ occ, oc_chunks, g, nb_groups);
+ break;
+ default: assert(!"unsupported loop order");
+ }
+ while (start < end) {
+ for (int occ1 = 0; occ1 < jcp.nb_oc_blocking_thr_chunk;
+ occ1 += jcp.nb_oc_blocking) {
+ int ocb = occ * jcp.nb_oc_blocking_thr_chunk + occ1;
+ int g_oc = (g * jcp.nb_oc + ocb) * jcp.oc_block;
+
+ int g_ic = g * jcp.nb_ic * jcp.ic_block;
+
+ int work_rem = end - start;
+ int ih_s = -jcp.t_pad + oh_s * jcp.stride_h;
+ int oh_e = oh_s + work_rem > jcp.oh ? jcp.oh : oh_s + work_rem;
+ if (jcp.loop_order == loop_nhwcg)
+ oh_e = oh_s + 1; // step instead
+ int ow_s = owb * jcp.ow_block;
+ int iw_s = ow_s * jcp.stride_w;
+
+ auto bias_w = bias
+ ? bias + (bias_d.blk_off(g_oc) * bia_dt_size)
+ : 0;
+ int32_t *compensation_w = (jcp.signed_input)
+ ? compensation + g_oc : 0;
+
+ auto dst_w = dst + dst_d.blk_off(n, g_oc, oh_s, ow_s);
+ auto src_w = src + src_d.blk_off(n, g_ic, ih_s, iw_s);
+ auto wht_w = weights + wht_blk_off(weights_d, g, ocb, 0);
+
+ auto scales = &oscales[jcp.is_oc_scale * g_oc];
+
+ for (int oj = oh_s, ij = ih_s; oj < oh_e;
+ ++oj, ij += jcp.stride_h) {
+ int dilate_h = jcp.dilate_h + 1;
+ int i_t_overflow = nstl::min(jcp.kh,
+ div_up(max(0, -ij), dilate_h));
+ int i_b_overflow = nstl::min(jcp.kh, div_up(
+ max(0, ij - jcp.ih + (jcp.kh - 1) * dilate_h + 1),
+ dilate_h));
+ int kh_padding = nstl::max(0,
+ jcp.kh - i_t_overflow - i_b_overflow);
+
+ size_t wei_stride = (!jcp.signed_input)
+ ? i_t_overflow * wht_h_stride : 0;
+ p.src = src_w + i_t_overflow * dilate_h * src_h_stride;
+ p.dst = dst_w;
+ p.filt = wht_w + wei_stride;
+ p.bias = bias_w;
+ p.compensation = compensation_w;
+ p.oc_blocks = ocb;
+ p.kh_padding = kh_padding;
+ p.scales = scales;
+ p.t_overflow = i_t_overflow;
+ p.b_overflow = i_b_overflow;
+ p.owb = owb;
+
+ kernel_->jit_ker(&p);
+ src_w += src_h_stride * jcp.stride_h;
+ dst_w += dst_h_stride;
+ }
+ }
+ switch (jcp.loop_order) {
+ case loop_cwgn:
+ nd_iterator_jump(start, end, occ, oc_chunks, owb, jcp.nb_ow, g,
+ nb_groups, n, jcp.mb, oh_s, jcp.oh);
+ break;
+ case loop_ngcw:
+ nd_iterator_jump(start, end, n, jcp.mb, g, nb_groups, occ,
+ oc_chunks, owb, jcp.nb_ow, oh_s, jcp.oh);
+ break;
+ case loop_nhwcg:
+ ++start;
+ nd_iterator_step(n, jcp.mb, oh_s, jcp.oh, owb, jcp.nb_ow, occ,
+ oc_chunks, g, nb_groups);
+ break;
+ default: assert(!"unsupported loop order");
+ }
+ }
+ });
+}
+
+template <data_type_t src_type, data_type_t dst_type>
+void jit_avx512_core_x8s8s32x_convolution_fwd_t<src_type,
+ dst_type>::execute_forward_2d_dw(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ const size_t bia_dt_size = pd()->with_bias()
+ ? types::data_type_size(pd()->desc()->bias_desc.data_type) : 0;
+
+ const auto &jcp = pd()->jcp_;
+ assert(jcp.ic_block == 1);
+ assert(jcp.oc_block == 1);
+ assert(jcp.nb_ic == 1);
+ assert(jcp.nb_oc == 1);
+ assert(jcp.nb_oc_blocking == 1);
+ assert(jcp.nb_ch % jcp.nb_ch_blocking == 0);
+
+ const float *oscales = pd()->attr()->output_scales_.scales_;
+ if (jcp.signed_input && jcp.ver != ver_vnni) {
+ auto local_scales = scratchpad(ctx).template get<float>(
+ key_conv_adjusted_scales);
+ size_t count = pd()->attr()->output_scales_.count_;
+ float factor = 1.f / pd()->jcp_.wei_adj_scale;
+ if (count == 1) {
+ utils::array_set(local_scales, oscales[0] * factor, 16);
+ } else {
+ for (size_t c = 0; c < count; c++)
+ local_scales[c] = oscales[c] * factor;
+ }
+ oscales = local_scales;
+ }
+
+ size_t offset = weights_d.size() - weights_d.additional_buffer_size();
+ auto w = const_cast<wei_data_t *>(weights);
+ int32_t* compensation = (jcp.signed_input)
+ ? reinterpret_cast<int32_t *>(&w[offset]) : 0;
+ int nb_groups = jcp.nb_ch / jcp.nb_ch_blocking;
+ int group_block = jcp.ch_block;
+
+ parallel_nd(jcp.mb, jcp.oh, jcp.nb_ow, nb_groups,
+ [&](int n, int oh_s, int owb, int gg) {
+
+ auto p = jit_conv_call_s();
+
+ size_t src_h_stride = src_d.blk_off(0, 0, 1);
+ size_t wht_h_stride = wht_blk_off(weights_d, 0, 0, 0, 1);
+
+ int gb = gg * jcp.nb_ch_blocking;
+ int g = gb * group_block;
+
+ int ih_s = -jcp.t_pad + oh_s * jcp.stride_h;
+ int ow_s = owb * jcp.ow_block;
+ int iw_s = ow_s * jcp.stride_w;
+
+ auto bias_w = bias ? bias + (bias_d.blk_off(g) * bia_dt_size) : 0;
+ int32_t *compensation_w = jcp.signed_input ? compensation + g : 0;
+
+ auto dst_w = dst + dst_d.blk_off(n, g, oh_s, ow_s);
+ auto src_w = src + src_d.blk_off(n, g, ih_s, iw_s);
+ auto wht_w = weights + wht_blk_off(weights_d, gb, 0);
+
+ auto scales = &oscales[jcp.is_oc_scale * g];
+
+ int dilate_h = jcp.dilate_h + 1;
+ int i_t_overflow = nstl::min(jcp.kh, div_up(max(0, -ih_s), dilate_h));
+ int i_b_overflow = nstl::min(jcp.kh,
+ div_up(max(0, ih_s - jcp.ih + (jcp.kh - 1) * dilate_h + 1),
+ dilate_h));
+ int kh_padding = nstl::max(0, jcp.kh - i_t_overflow - i_b_overflow);
+
+ size_t wei_stride = jcp.signed_input ? 0 : i_t_overflow * wht_h_stride;
+ p.src = src_w + i_t_overflow * dilate_h * src_h_stride;
+ p.dst = dst_w;
+ p.filt = wht_w + wei_stride;
+ p.bias = bias_w;
+ p.compensation = compensation_w;
+ p.oc_blocks = gb;
+ p.kh_padding = kh_padding;
+ p.scales = scales;
+ p.t_overflow = i_t_overflow;
+ p.b_overflow = i_b_overflow;
+ p.owb = owb;
+
+ kernel_->jit_ker(&p);
+ });
+}
+
+template struct jit_avx512_core_x8s8s32x_convolution_fwd_t<
+ data_type::s8, data_type::u8>;
+template struct jit_avx512_core_x8s8s32x_convolution_fwd_t<
+ data_type::u8, data_type::u8>;
+template struct jit_avx512_core_x8s8s32x_convolution_fwd_t<
+ data_type::s8, data_type::s8>;
+template struct jit_avx512_core_x8s8s32x_convolution_fwd_t<
+ data_type::u8, data_type::s8>;
+template struct jit_avx512_core_x8s8s32x_convolution_fwd_t<
+ data_type::s8, data_type::s32>;
+template struct jit_avx512_core_x8s8s32x_convolution_fwd_t<
+ data_type::u8, data_type::s32>;
+template struct jit_avx512_core_x8s8s32x_convolution_fwd_t<
+ data_type::s8, data_type::f32>;
+template struct jit_avx512_core_x8s8s32x_convolution_fwd_t<
+ data_type::u8, data_type::f32>;
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_convolution.hpp
new file mode 100644
index 0000000000..203ebdf942
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_convolution.hpp
@@ -0,0 +1,115 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_CORE_X8S8S32X_CONVOLUTION_HPP
+#define CPU_JIT_AVX512_CORE_X8S8S32X_CONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "jit_avx512_core_x8s8s32x_conv_kernel.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t src_type, impl::data_type_t dst_type>
+struct jit_avx512_core_x8s8s32x_convolution_fwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_()
+ {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_int8:", avx512_core, ""),
+ jit_avx512_core_x8s8s32x_convolution_fwd_t<src_type, dst_type>);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(src_type, data_type::s8, data_type::undef,
+ dst_type, data_type::s32)
+ && IMPLICATION(with_bias(), utils::one_of(bias_md_.data_type,
+ data_type::f32, data_type::s32, data_type::s8,
+ data_type::u8))
+ && !has_zero_dim_memory();
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_avx512_core_x8s8s32x_fwd_kernel::init_conf(
+ jcp_, *desc(), src_md_, weights_md_, dst_md_, bias_md_,
+ *attr(), mkldnn_get_max_threads());
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx512_core_x8s8s32x_fwd_kernel::init_scratchpad(scratchpad,
+ jcp_, *attr());
+
+ return status;
+ }
+
+ jit_conv_conf_t jcp_;
+ };
+
+ jit_avx512_core_x8s8s32x_convolution_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ {
+ kernel_ = new jit_avx512_core_x8s8s32x_fwd_kernel(pd()->jcp_,
+ *pd()->attr());
+ }
+
+ ~jit_avx512_core_x8s8s32x_convolution_fwd_t() { delete kernel_; }
+
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<data_type::s8>::type wei_data_t;
+ typedef typename prec_traits<dst_type>::type dst_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override
+ {
+ const auto &_pd = pd();
+ if (_pd->ndims() == 3)
+ execute_forward_1d(ctx);
+ else if (_pd->jcp_.is_depthwise)
+ execute_forward_2d_dw(ctx);
+ else
+ execute_forward_2d(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward_1d(const exec_ctx_t &ctx) const;
+ void execute_forward_2d(const exec_ctx_t &ctx) const;
+ void execute_forward_2d_dw(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_avx512_core_x8s8s32x_fwd_kernel *kernel_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_deconvolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_deconvolution.cpp
new file mode 100644
index 0000000000..142af1f541
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_deconvolution.cpp
@@ -0,0 +1,1034 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "jit_avx512_core_x8s8s32x_deconvolution.hpp"
+
+#define GET_OFF(field) offsetof(jit_deconv_call_s, field)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+using namespace Xbyak;
+
+using namespace nstl;
+
+#define wht_blk_off(d, g, ...) \
+ (pd()->with_groups() ? (d).blk_off((g), __VA_ARGS__) : \
+ (d).blk_off(__VA_ARGS__))
+
+status_t jit_avx512_core_x8s8s32x_deconv_fwd_kernel::init_conf(
+ jit_conv_conf_t &jcp, const deconvolution_desc_t &cd,
+ memory_desc_t &src_md, memory_desc_t &weights_md,
+ memory_desc_t &dst_md, const bool with_bias,
+ memory_desc_t &bias_md, const primitive_attr_t &attr) {
+ const memory_desc_wrapper src_d(&src_md);
+ const memory_desc_wrapper dst_d(&dst_md);
+ const memory_desc_wrapper weights_d(&weights_md);
+ const memory_desc_wrapper bias_d(&bias_md);
+
+ if (!(mayiuse(avx512_core)
+ && one_of(src_d.data_type(), data_type::u8, data_type::s8)
+ && weights_d.data_type() == data_type::s8
+ && one_of(dst_d.data_type(), data_type::f32, data_type::s32,
+ data_type::s8, data_type::u8)))
+ return status::unimplemented;
+
+ jcp = zero<decltype(jcp)>();
+
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+ jcp.signed_input = src_d.data_type() == data_type::s8;
+ const int ndims = jcp.ndims = dst_d.ndims();
+ const bool is_1d = ndims == 3;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+ jcp.oc_without_padding = dst_d.dims()[1] / jcp.ngroups;
+ jcp.ic_without_padding = src_d.dims()[1] / jcp.ngroups;
+ jcp.is_depthwise = true && with_groups
+ && utils::everyone_is(1, jcp.ic_without_padding,
+ jcp.oc_without_padding);
+
+ /* TODO: future work, on hold until depthwise specialized kernel is
+ * implemented. */
+ if (jcp.is_depthwise && jcp.signed_input)
+ return status::unimplemented;
+
+ format_tag_t dat_tag = utils::pick(ndims - 3,
+ format_tag::nwc, format_tag::nhwc);
+
+ if (src_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(src_md, dat_tag));
+ jcp.src_tag = dat_tag;
+ } else {
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ }
+ if (jcp.src_tag != dat_tag)
+ return status::unimplemented;
+
+ if (dst_d.format_kind() == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(dst_md, dat_tag));
+ jcp.dst_tag = dat_tag;
+ } else {
+ jcp.dst_tag = dst_d.matches_one_of_tag(dat_tag);
+ }
+ if (jcp.dst_tag != dat_tag)
+ return status::unimplemented;
+
+ auto set_or_check_wei_format = [&]() {
+ using namespace format_tag;
+
+ format_tag_t wei_tag = is_1d
+ ? (jcp.is_depthwise
+ ? Goiw16g : (with_groups ? gOIw4i16o4i : OIw4i16o4i))
+ : (jcp.is_depthwise
+ ? Goihw16g : (with_groups ? gOIhw4i16o4i : OIhw4i16o4i));
+
+ memory_desc_t want_wei_md = weights_md;
+ memory_desc_init_by_tag(want_wei_md, wei_tag);
+ if (jcp.signed_input && !jcp.is_depthwise) {
+ want_wei_md.extra.flags = 0
+ | memory_extra_flags::compensation_conv_s8s8
+ | memory_extra_flags::scale_adjust;
+ want_wei_md.extra.compensation_mask = (1 << 0)
+ + (with_groups && !jcp.is_depthwise ? (1 << 1) : 0);
+ want_wei_md.extra.scale_adjust =
+ mayiuse(avx512_core_vnni) ? 1.f : 0.5f;
+ }
+
+ if (weights_md.format_kind == format_kind::any) {
+ weights_md = want_wei_md;
+ return true;
+ }
+
+ return weights_md == want_wei_md;
+ };
+
+ if (!set_or_check_wei_format())
+ return status::unimplemented;
+
+ jcp.with_bias = with_bias;
+ if (jcp.with_bias) {
+ if (bias_d.format_kind() == format_kind::any)
+ CHECK(memory_desc_init_by_tag(bias_md, format_tag::x));
+ }
+
+ jcp.prop_kind = cd.prop_kind;
+ jcp.mb = src_d.dims()[0];
+ jcp.ih = is_1d ? 1 : src_d.dims()[ndims - 2];
+ jcp.iw = src_d.dims()[ndims - 1];
+ jcp.oh = is_1d ? 1 : dst_d.dims()[ndims - 2];
+ jcp.ow = dst_d.dims()[ndims - 1];
+ jcp.kh = is_1d ? 1 : weights_d.dims()[with_groups + ndims - 2];
+ jcp.kw = weights_d.dims()[with_groups + ndims - 1];
+ jcp.t_pad = is_1d ? 0 : cd.padding[0][ndims - 4];
+ jcp.l_pad = cd.padding[0][ndims - 3];
+ jcp.stride_h = is_1d ? 1 : cd.strides[ndims - 4];
+ jcp.stride_w = cd.strides[ndims - 3];
+
+ if (jcp.is_depthwise) {
+ jcp.ch_block = 16;
+ jcp.oc_block = 1;
+ jcp.ic_block = 1;
+ } else {
+ jcp.ch_block = 1;
+ jcp.oc_block = 16;
+ jcp.ic_block = 16;
+
+ if (jcp.ngroups == 1) {
+ jcp.oc = utils::rnd_up(jcp.oc_without_padding, jcp.oc_block);
+ jcp.ic = utils::rnd_up(jcp.ic_without_padding, jcp.ic_block);
+ }
+ if (jcp.ic % jcp.ic_block != 0)
+ return status::unimplemented;
+ }
+
+ jcp.dilate_h = is_1d ? 0 : cd.dilates[ndims - 4];
+ jcp.dilate_w = cd.dilates[ndims - 3];
+
+ if (!IMPLICATION(jcp.dilate_h, jcp.stride_h == 1)
+ || !IMPLICATION(jcp.dilate_w, jcp.stride_w == 1))
+ return status::unimplemented;
+
+ /* padding: bottom and right */
+ jcp.b_pad = (jcp.ih - 1) * jcp.stride_h + (jcp.kh - 1) * (jcp.dilate_h + 1)
+ - (jcp.oh + jcp.t_pad - 1);
+ jcp.r_pad = (jcp.iw - 1) * jcp.stride_w + (jcp.kw - 1) * (jcp.dilate_w + 1)
+ - (jcp.ow + jcp.l_pad - 1);
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ const int eltwise_ind = p.find(primitive_kind::eltwise);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise)
+ jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+
+ jcp.ver = ver_avx512_core;
+ if (mayiuse(avx512_core_vnni))
+ jcp.ver = ver_vnni;
+ const auto &oscales = attr.output_scales_;
+ jcp.is_oc_scale = oscales.mask_ == 1 << 1;
+
+ assert(IMPLICATION(!jcp.is_oc_scale, oscales.mask_ == 0));
+
+ jcp.dst_dt = dst_d.data_type();
+ jcp.bia_dt = jcp.with_bias ? bias_d.data_type() : data_type::undef;
+ jcp.typesize_bia
+ = jcp.with_bias ? types::data_type_size(bias_d.data_type()) : 0;
+ jcp.typesize_in = types::data_type_size(src_d.data_type());
+ jcp.typesize_out = types::data_type_size(dst_d.data_type());
+
+ jcp.nb_ch = div_up(jcp.ngroups, jcp.ch_block);
+ jcp.nb_oc = jcp.oc / jcp.oc_block;
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+
+ /* kernel blocking params */
+ const int regs = jcp.ver == ver_vnni ? 30 : 28;
+ jcp.nb_oc_blocking = nstl::min(4, jcp.nb_oc);
+ for (; jcp.nb_oc_blocking > 1; jcp.nb_oc_blocking--)
+ if (jcp.nb_oc % jcp.nb_oc_blocking == 0
+ && jcp.l_pad <= regs / (jcp.nb_oc_blocking + 1))
+ break;
+
+ jcp.ur_w = regs / (jcp.nb_oc_blocking + 1);
+ int l_overflow = max(
+ 0, ((jcp.kw - 1) * (jcp.dilate_w + 1) - jcp.l_pad) / jcp.stride_w);
+
+ if (jcp.ow < jcp.ur_w) {
+ jcp.ur_w = jcp.ow;
+ jcp.ur_w_tail = 0;
+ } else {
+ for (; jcp.ur_w >= 1; jcp.ur_w--) {
+ /* ur_w should be multiple of stride_w in order
+ to simplify logic for get_ow_start and get_ow_end */
+ bool is_multiple_of_stride = jcp.ur_w % jcp.stride_w == 0;
+
+ /* boundary conditions:
+ These conditions ensure all elements close to boundary
+ are computed in a single call of compute loop */
+ bool left_boundary_covered = jcp.ur_w >= l_overflow * jcp.stride_w;
+ jcp.ur_w_tail = jcp.ow % jcp.ur_w;
+ int r_overflow_no_tail
+ = max(0, ((jcp.kw - 1) * (jcp.dilate_w + 1)
+ - max(0, jcp.r_pad) - jcp.ur_w_tail)
+ / jcp.stride_w);
+ bool right_boundary_covered
+ = jcp.ur_w >= r_overflow_no_tail * jcp.stride_w;
+
+ if (is_multiple_of_stride && left_boundary_covered
+ && right_boundary_covered)
+ break;
+ else if (jcp.ur_w == 1)
+ /* The boundary conditions above are also important
+ to maintain simplicity of calls to icb_loop,
+ if those conditions are not satisfied,
+ then special cases will need to be added
+ to use correct l_overflow/r_overflow values
+ when different iterations of compute loop
+ work on the locations close to boundary.
+ So to keep code simple, return unimplemented
+ for extreme case when a good ur_w cannot be found.
+ */
+ return status::unimplemented;
+ }
+ }
+
+ jcp.wei_adj_scale =
+ (weights_d.extra().flags | memory_extra_flags::scale_adjust)
+ ? weights_d.extra().scale_adjust : 1.f;
+
+ jcp.loop_order = jcp.ngroups > 1 ? loop_ngc : loop_cgn;
+ return status::success;
+}
+
+bool jit_avx512_core_x8s8s32x_deconv_fwd_kernel::maybe_eltwise(int position) {
+ using namespace primitive_kind;
+ const auto &p = attr_.post_ops_;
+
+ if (position == 0) {
+ /* eltwise before sum */
+ return p.contain(eltwise, 0);
+ } else if (position == 1) {
+ /* eltwise after sum */
+ return p.contain(sum, 0) && p.contain(eltwise, 1);
+ }
+ return false;
+}
+
+void jit_avx512_core_x8s8s32x_deconv_fwd_kernel::compute_eltwise(int ur_w) {
+ int nb_oc_block
+ = jcp.is_depthwise ? jcp.nb_ch_blocking : jcp.nb_oc_blocking;
+ eltwise_injector_->compute_vector_range(0, nb_oc_block * ur_w);
+}
+
+bool jit_avx512_core_x8s8s32x_deconv_fwd_kernel::post_ops_ok(
+ jit_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ using namespace primitive_kind;
+ const auto &p = attr.post_ops_;
+
+ auto is_eltwise = [&](int idx) { return p.entry_[idx].is_eltwise(); };
+
+ switch (p.len_) {
+ case 0: return true;
+ case 1: return is_eltwise(0) || p.contain(sum, 0);
+ case 2:
+ return (p.contain(sum, 0) && is_eltwise(1))
+ || (p.contain(sum, 1) && is_eltwise(0));
+ default: return false;
+ }
+
+ return false;
+}
+
+void jit_avx512_core_x8s8s32x_deconv_fwd_kernel::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad, const jit_conv_conf_t &jcp,
+ const primitive_attr_t &attr) {
+ if (jcp.signed_input && jcp.ver != ver_vnni) {
+ dim_t count = nstl::max<dim_t>(attr.output_scales_.count_, 16);
+ scratchpad.book(key_conv_adjusted_scales, sizeof(float) * count);
+ }
+}
+
+void jit_avx512_core_x8s8s32x_deconv_fwd_kernel::compute_ker(int ur_w,
+ int l_overflow, int r_overflow, ker_block_t last_ic_block_flag,
+ bool h_padded) {
+
+ const int ch_block_all = jcp.ch_block * jcp.ic_block * jcp.oc_block;
+ const int ur_w_stride = jcp.signed_input ? 1 : jcp.stride_w;
+
+ auto src_offset = [=](int oj, int icb, int ki) {
+ return jcp.typesize_in
+ * (((oj + jcp.l_pad - ki * (jcp.dilate_w + 1)) / jcp.stride_w)
+ * jcp.ngroups * jcp.ic_without_padding
+ + icb * 4);
+ };
+
+ auto kernel_offset = [=](int ocb, int icb, int ki) {
+ return jcp.typesize_in
+ * (ocb * jcp.nb_ic * jcp.kh * jcp.kw * ch_block_all
+ + icb * jcp.oc_block * jcp.ic_block / 4
+ + ki * ch_block_all);
+ };
+
+ auto compute = [=](zmm_t vreg_acc, zmm_t vreg_wei, zmm_t vreg_src) {
+ if (jcp.ver == ver_vnni) {
+ vpdpbusd(vreg_acc, vreg_src, vreg_wei);
+ } else if (jcp.is_depthwise) {
+ vpmulld(zmm_tmp, vreg_src, vreg_wei);
+ vpaddd(vreg_acc, vreg_acc, zmm_tmp);
+ } else {
+ vpmaddubsw(zmm_tmp, vreg_src, vreg_wei);
+ vpmaddwd(zmm_tmp, zmm_tmp, zmm_one);
+ vpaddd(vreg_acc, vreg_acc, zmm_tmp);
+ }
+ };
+
+ for (int ki = 0; ki < jcp.kw; ki++) {
+
+ int jj_start = get_ow_start(ki, l_overflow);
+ int jj_end = get_ow_end(ur_w, ki, r_overflow);
+
+ int _start = (jcp.signed_input) ? 0 : jj_start;
+ int _end = (jcp.signed_input) ? ur_w : jj_end;
+
+ int tail_size = jcp.ic_without_padding % 4;
+ int n_ic_blocks = jcp.is_depthwise ?
+ 1 :
+ (last_ic_block_flag & ~no_last_block ?
+ div_up(jcp.ic_without_padding % jcp.ic_block,
+ 4) :
+ jcp.ic_block / 4);
+
+ for (int icb1 = 0; icb1 < n_ic_blocks; icb1++) {
+ if (h_padded == true) {
+ /* fill padded area with shifted values */
+ Zmm inp = zmm_inp(0, jcp.nb_oc_blocking);
+ vpxord(inp, inp, inp);
+ vpsubb(inp, inp, zmm_shift);
+ } else {
+
+ for (int jj = _start; jj < _end; jj += ur_w_stride) {
+
+ int aux_src_off = src_offset(jj, icb1, ki);
+
+ if (jj >= jj_start && jj < jj_end
+ && ((jj + jcp.l_pad - ki) % jcp.stride_w == 0)) {
+ if (jcp.is_depthwise) {
+ vpmovzxbd(zmm_inp(jj, jcp.nb_oc_blocking),
+ EVEX_compress_addr(
+ aux_reg_src, aux_src_off));
+ } else if ((last_ic_block_flag & last_sp_block)
+ && tail_size != 0 && icb1 == n_ic_blocks - 1) {
+ xmm_t xmm_tmp = xmm_t(
+ zmm_inp(jj, jcp.nb_oc_blocking).getIdx());
+ for (int r = 0; r < tail_size; ++r)
+ vpinsrb(xmm_tmp, xmm_tmp,
+ ptr[aux_reg_src + aux_src_off + r], r);
+ vpbroadcastd(
+ zmm_inp(jj, jcp.nb_oc_blocking), xmm_tmp);
+ } else {
+ vpbroadcastd(zmm_inp(jj, jcp.nb_oc_blocking),
+ EVEX_compress_addr(
+ aux_reg_src, aux_src_off));
+ }
+ if (jcp.signed_input)
+ vpsubb(zmm_inp(jj, jcp.nb_oc_blocking),
+ zmm_inp(jj, jcp.nb_oc_blocking), zmm_shift);
+ } else {
+ /* fill padded area with shifted values */
+ if (jcp.signed_input) {
+ Zmm inp = zmm_inp(jj, jcp.nb_oc_blocking);
+ vpxord(inp, inp, inp);
+ vpsubb(inp, inp, zmm_shift);
+ }
+ }
+ }
+ }
+ for (int ocb = 0; ocb < jcp.nb_oc_blocking; ocb++) {
+ int aux_filt_off = kernel_offset(ocb, icb1, ki);
+
+ if (_end - _start > 0) {
+ if (jcp.is_depthwise)
+ vpmovsxbd(zmm_wei,
+ EVEX_compress_addr(aux_reg_filt, aux_filt_off));
+ else
+ vmovups(zmm_wei,
+ EVEX_compress_addr(aux_reg_filt, aux_filt_off));
+ }
+ for (int jj = _start; jj < _end; jj += ur_w_stride) {
+ Zmm inp = (h_padded == true) ?
+ zmm_inp(0, jcp.nb_oc_blocking) :
+ zmm_inp(jj, jcp.nb_oc_blocking);
+ compute(zmm_out(jj, ocb), zmm_wei, inp);
+ }
+ }
+ }
+ }
+}
+
+void jit_avx512_core_x8s8s32x_deconv_fwd_kernel::kh_loop(int ur_w,
+ int l_overflow, int r_overflow, ker_block_t last_ic_block_flag) {
+
+ int ch_block_all = jcp.ch_block * jcp.ic_block * jcp.oc_block;
+ int shift_src_ih = jcp.typesize_in * (jcp.dilate_h + 1) * jcp.iw
+ * jcp.ngroups * jcp.ic_without_padding;
+ const int stride_h = jcp.signed_input ? 1 : jcp.stride_h;
+ int shift_filt_kh = jcp.typesize_in * jcp.kw * ch_block_all * stride_h;
+
+ Label kh_loop_label, skip_kh_loop;
+ Label t_overflow_label, no_t_overflow_label, b_overflow_label,
+ no_b_overflow_label;
+
+ mov(aux_reg_src, reg_src);
+ mov(aux_reg_filt, reg_filt);
+
+ if (jcp.signed_input && jcp.ndims > 3) {
+ /* Weights are transposed, so first compute 'bottom' padding. */
+ mov(reg_overflow, ptr[param1 + GET_OFF(b_overflow)]);
+ cmp(reg_overflow, 0);
+ je(no_b_overflow_label, T_NEAR);
+ L(b_overflow_label); {
+ compute_ker(ur_w, 0, 0, last_ic_block_flag, true);
+
+ add(aux_reg_filt, shift_filt_kh);
+ dec(reg_overflow);
+ cmp(reg_overflow, 0);
+ jg(b_overflow_label, T_NEAR);
+ }
+ L(no_b_overflow_label);
+ }
+
+ mov(reg_kh, ptr[param1 + GET_OFF(kh_padding)]);
+
+ if (jcp.signed_input || ((!jcp.signed_input)
+ && ((min(jcp.t_pad, jcp.b_pad) < 0)
+ || ((jcp.kh - 1) * (jcp.dilate_h + 1)
+ < nstl::max(jcp.t_pad, jcp.b_pad))))) {
+ cmp(reg_kh, 0);
+ je(skip_kh_loop, T_NEAR);
+ }
+
+ L(kh_loop_label); {
+ compute_ker(ur_w, l_overflow, r_overflow, last_ic_block_flag, false);
+ sub(aux_reg_src, shift_src_ih);
+ add(aux_reg_filt, shift_filt_kh);
+ dec(reg_kh);
+
+ /* Insert weight compensation in stride 'holes' */
+ if (jcp.signed_input && jcp.stride_h > 1) {
+ Label kh_comp_loop;
+
+ cmp(reg_kh, 0);
+ je(skip_kh_loop, T_NEAR);
+ mov(reg_comp_strides, jcp.stride_h - 1);
+ L(kh_comp_loop);
+ {
+ compute_ker(
+ ur_w, 0, 0, last_ic_block_flag, true);
+ add(aux_reg_filt, shift_filt_kh);
+ dec(reg_comp_strides);
+ cmp(reg_comp_strides, 0);
+ jg(kh_comp_loop, T_NEAR);
+ }
+ }
+ cmp(reg_kh, 0);
+ jg(kh_loop_label, T_NEAR);
+ }
+ L(skip_kh_loop);
+ if (jcp.signed_input && jcp.ndims > 3) {
+ mov(reg_overflow, ptr[param1 + GET_OFF(t_overflow)]);
+ cmp(reg_overflow, 0);
+ je(no_t_overflow_label, T_NEAR);
+ L(t_overflow_label); {
+ compute_ker(ur_w, 0, 0, last_ic_block_flag, true);
+
+ add(aux_reg_filt, shift_filt_kh);
+ dec(reg_overflow);
+ cmp(reg_overflow, 0);
+ jg(t_overflow_label, T_NEAR);
+ }
+ L(no_t_overflow_label);
+ }
+}
+
+void jit_avx512_core_x8s8s32x_deconv_fwd_kernel::prepare_output(int ur_w) {
+ for (int ocb = 0; ocb < jcp.nb_oc_blocking; ocb++) {
+ for (int ur = 0; ur < ur_w; ur++) {
+ zmm_t zmm = zmm_out(ur, ocb);
+ vpxord(zmm, zmm, zmm);
+ }
+ }
+ if (jcp.signed_input) {
+ xor_(reg_scratch, reg_scratch);
+ Reg8 _t8 = reg_scratch.cvt8();
+ mov(_t8, (int8_t)-128);
+ vpbroadcastb(zmm_shift, _t8);
+ }
+}
+
+void jit_avx512_core_x8s8s32x_deconv_fwd_kernel::cvt2ps(
+ data_type_t type_in, zmm_t zmm_in, const Operand &op, bool mask_flag) {
+ zmm_t zmm = mask_flag ? zmm_in | ktail_mask | T_z : zmm_in;
+ switch (type_in) {
+ case data_type::f32:
+ case data_type::s32: vmovups(zmm, op); break;
+ case data_type::s8: vpmovsxbd(zmm, op); break;
+ case data_type::u8: vpmovzxbd(zmm, op); break;
+ default: assert(!"unsupported data type");
+ }
+ if (type_in != data_type::f32)
+ vcvtdq2ps(zmm_in, zmm_in);
+}
+
+void jit_avx512_core_x8s8s32x_deconv_fwd_kernel::store_output(
+ int ur_w, bool last_oc_block) {
+ mov(reg_bias, ptr[param1 + GET_OFF(bias)]);
+ mov(reg_ptr_scales, ptr[param1 + GET_OFF(scales)]);
+
+ if (jcp.signed_input)
+ mov(reg_compensation, ptr[param1 + GET_OFF(compensation)]);
+
+ const auto &p = attr_.post_ops_;
+ const int sum_idx = p.find(primitive_kind::sum);
+ const float *p_sum_scale
+ = (sum_idx != -1) ? &p.entry_[sum_idx].sum.scale : nullptr;
+ if (p_sum_scale && *p_sum_scale != 1.f)
+ mov(reg_ptr_sum_scale, (size_t)p_sum_scale);
+
+ if (jcp.with_bias && jcp.signed_input && jcp.ver != ver_vnni) {
+ mov(reg_bias_alpha, float2int(jcp.wei_adj_scale));
+ vmovq(xmm_bias_alpha(), reg_bias_alpha);
+ vbroadcastss(zmm_bias_alpha(), xmm_bias_alpha());
+ }
+
+ for (int ocb = 0; ocb < jcp.nb_oc_blocking; ocb++) {
+ const bool mask_flag = last_oc_block && ocb == jcp.nb_oc_blocking - 1;
+ int scale_offset
+ = jcp.is_oc_scale * (sizeof(float) * ocb * jcp.oc_block);
+
+ auto zmm_bias = zmm_tmp;
+ if (jcp.with_bias) {
+ int bias_offset = jcp.typesize_bia * ocb * jcp.oc_block;
+ auto bias_addr = EVEX_compress_addr(reg_bias, bias_offset);
+ cvt2ps(jcp.bia_dt, zmm_bias, bias_addr, mask_flag);
+ if (jcp.signed_input && jcp.ver != ver_vnni)
+ vmulps(zmm_bias, zmm_bias, zmm_bias_alpha());
+ }
+ if (jcp.signed_input) {
+ int comp_offset = sizeof(int32_t) * ocb * jcp.oc_block;
+ auto comp_addr = EVEX_compress_addr(reg_compensation, comp_offset);
+ cvt2ps(data_type::s32, zmm_comp, comp_addr, mask_flag);
+ }
+
+ for (int ur = 0; ur < ur_w; ur++) {
+ zmm_t zmm = zmm_out(ur, ocb);
+ vcvtdq2ps(zmm, zmm);
+ if (jcp.signed_input)
+ vaddps(zmm, zmm, zmm_comp);
+ if (jcp.with_bias)
+ vaddps(zmm, zmm, zmm_bias);
+ zmm_t mask_zmm = mask_flag ? zmm | ktail_mask | T_z : zmm;
+ vmulps(mask_zmm, zmm,
+ EVEX_compress_addr(reg_ptr_scales, scale_offset));
+ }
+ }
+ if (maybe_eltwise(0))
+ compute_eltwise(ur_w);
+ if (p_sum_scale) { // post_op: sum
+ for (int k = 0; k < jcp.nb_oc_blocking; k++) {
+ const bool mask_flag
+ = last_oc_block == 1 && k == jcp.nb_oc_blocking - 1;
+ for (int j = 0; j < ur_w; j++) {
+ int aux_output_offset
+ = jcp.typesize_out
+ * (k * jcp.oc_block
+ + j * jcp.oc_without_padding * jcp.ngroups);
+ auto addr = EVEX_compress_addr(reg_dst, aux_output_offset);
+ Zmm zmm = zmm_out(j, k);
+ cvt2ps(jcp.dst_dt, zmm_prev_dst, addr, mask_flag);
+ if (*p_sum_scale == 1.f)
+ vaddps(zmm, zmm_prev_dst);
+ else
+ vfmadd231ps(zmm, zmm_prev_dst, zword_b[reg_ptr_sum_scale]);
+ }
+ }
+ }
+ if (maybe_eltwise(1))
+ compute_eltwise(ur_w);
+
+ for (int ocb = 0; ocb < jcp.nb_oc_blocking; ocb++) {
+ const bool mask_flag = last_oc_block && ocb == jcp.nb_oc_blocking - 1;
+ for (int ur = 0; ur < ur_w; ur++) {
+ zmm_t zmm = zmm_out(ur, ocb);
+ if (jcp.dst_dt == data_type::u8) {
+ vpxord(zmm_zero, zmm_zero, zmm_zero);
+ vmaxps(zmm, zmm_zero, zmm);
+ }
+ if (jcp.dst_dt != data_type::f32)
+ vcvtps2dq(zmm, zmm);
+ }
+ for (int ur = 0; ur < ur_w; ur++) {
+ int aux_dst_off = jcp.typesize_out
+ * (ur * jcp.ngroups * jcp.oc_without_padding
+ + ocb * jcp.oc_block);
+ auto addr = EVEX_compress_addr(reg_dst, aux_dst_off);
+
+ zmm_t zmm = zmm_out(ur, ocb);
+ zmm_t r_zmm = mask_flag ? zmm | ktail_mask : zmm;
+ switch (jcp.dst_dt) {
+ case data_type::f32:
+ case data_type::s32: vmovups(addr, r_zmm); break;
+ case data_type::s8: vpmovsdb(addr, r_zmm); break;
+ case data_type::u8: vpmovusdb(addr, r_zmm); break;
+ default: assert(!"unknown dst_dt");
+ }
+ }
+ }
+}
+
+void jit_avx512_core_x8s8s32x_deconv_fwd_kernel::icb_loop(
+ int ur_w, int l_overflow, int r_overflow, bool is_last_sp_block) {
+
+ int shift_src_icb = jcp.typesize_in * jcp.ic_block;
+ int shift_filt_icb
+ = jcp.typesize_in * jcp.kh * jcp.kw * jcp.ic_block * jcp.oc_block;
+
+ prepare_output(ur_w);
+
+ Label skip_icb_loop, icb_loop_label;
+
+ mov(reg_icb, jcp.nb_ic);
+ L(icb_loop_label); {
+
+ if (jcp.ic_without_padding != jcp.ic) {
+ Label common_ker, end_ker;
+ cmp(reg_icb, 1);
+ jg(common_ker, T_NEAR);
+
+ kh_loop(ur_w, l_overflow, r_overflow,
+ is_last_sp_block ? last_sp_block : last_ic_block);
+ jmp(end_ker, T_NEAR);
+
+ L(common_ker);
+ kh_loop(ur_w, l_overflow, r_overflow, no_last_block);
+
+ L(end_ker);
+ } else {
+ kh_loop(ur_w, l_overflow, r_overflow, no_last_block);
+ }
+
+ add(reg_src, shift_src_icb);
+ add(reg_filt, shift_filt_icb);
+ dec(reg_icb);
+ cmp(reg_icb, 0);
+ jg(icb_loop_label, T_NEAR);
+ }
+
+ /* come-back pointers */
+ sub(reg_src, jcp.nb_ic * shift_src_icb);
+ sub(reg_filt, jcp.nb_ic * shift_filt_icb);
+ L(skip_icb_loop);
+
+ if (jcp.ngroups % jcp.ch_block != 0 || jcp.oc_without_padding != jcp.oc) {
+ Label common_store, end_store;
+ mov(reg_oc_blocks, ptr[param1 + GET_OFF(oc_blocks)]);
+ if (jcp.is_depthwise)
+ cmp(reg_oc_blocks, jcp.nb_ch - 1);
+ else
+ cmp(reg_oc_blocks, jcp.nb_oc - jcp.nb_oc_blocking);
+ jne(common_store, T_NEAR);
+
+ store_output(ur_w, true);
+ jmp(end_store, T_NEAR);
+
+ L(common_store);
+ store_output(ur_w, false);
+
+ L(end_store);
+
+ } else {
+ store_output(ur_w, false);
+ }
+}
+
+void jit_avx512_core_x8s8s32x_deconv_fwd_kernel::generate() {
+ preamble();
+
+ xor_(reg_scratch, reg_scratch);
+ Reg16 _t = reg_scratch.cvt16();
+ mov(_t, 0x1);
+ vpbroadcastw(zmm_one, _t);
+
+ if (jcp.ngroups % jcp.ch_block != 0 || jcp.oc_without_padding != jcp.oc) {
+ int tail_size = jcp.is_depthwise ?
+ jcp.ngroups % jcp.ch_block :
+ jcp.oc_without_padding % jcp.oc_block;
+ int mask = (1 << tail_size) - 1;
+ Reg32 regw_tmp = reg_nur_w.cvt32();
+ mov(regw_tmp, mask);
+ kmovw(ktail_mask, regw_tmp);
+ }
+
+ mov(reg_src, ptr[param1 + GET_OFF(src)]);
+ mov(reg_filt, ptr[param1 + GET_OFF(filt)]);
+ mov(reg_dst, ptr[param1 + GET_OFF(dst)]);
+
+ int dst_shift = jcp.typesize_out * jcp.ur_w * jcp.ngroups
+ * jcp.oc_without_padding;
+ int src_shift = jcp.typesize_in * (jcp.ur_w / jcp.stride_w) * jcp.ngroups
+ * jcp.ic_without_padding;
+
+ int l_overflow = max(
+ 0, ((jcp.kw - 1) * (jcp.dilate_w + 1) - jcp.l_pad) / jcp.stride_w);
+ int r_overflow
+ = max(0, ((jcp.kw - 1) * (jcp.dilate_w + 1) - max(0, jcp.r_pad))
+ / jcp.stride_w);
+
+ int r_overflow1
+ = nstl::max(0, ((jcp.kw - 1) * (jcp.dilate_w + 1)
+ - nstl::max(0, jcp.r_pad) - jcp.ur_w_tail)
+ / jcp.stride_w);
+ int nur_w = jcp.ow / jcp.ur_w;
+ if (r_overflow1 > 0)
+ nur_w--;
+
+ if (jcp.ur_w == jcp.ow) {
+ icb_loop(jcp.ur_w, l_overflow, r_overflow, true);
+ } else if (nur_w == 0) {
+ icb_loop(jcp.ur_w, l_overflow, r_overflow1, jcp.ur_w_tail == 0);
+ add(reg_src, src_shift);
+ add(reg_dst, dst_shift);
+ if (jcp.ur_w_tail != 0)
+ icb_loop(jcp.ur_w_tail, 0, r_overflow, true);
+ } else {
+ xor_(reg_nur_w, reg_nur_w);
+ if (l_overflow > 0) {
+ icb_loop(jcp.ur_w, l_overflow, 0, false);
+ add(reg_src, src_shift);
+ add(reg_dst, dst_shift);
+ inc(reg_nur_w);
+ }
+ if ((l_overflow <= 0 && nur_w > 0) || (l_overflow > 0 && nur_w > 1)) {
+ Label ow_loop_label;
+ L(ow_loop_label);
+ {
+ icb_loop(jcp.ur_w, 0, 0, false);
+ add(reg_src, src_shift);
+ add(reg_dst, dst_shift);
+ inc(reg_nur_w);
+ cmp(reg_nur_w, nur_w);
+ jl(ow_loop_label, T_NEAR);
+ }
+ }
+ if (r_overflow1 > 0) {
+ icb_loop(jcp.ur_w, 0, r_overflow1, jcp.ur_w_tail == 0);
+ add(reg_src, src_shift);
+ add(reg_dst, dst_shift);
+ }
+ if (jcp.ur_w_tail != 0) {
+ icb_loop(jcp.ur_w_tail, 0, r_overflow, true);
+ }
+ }
+ postamble();
+
+ if (jcp.with_eltwise)
+ eltwise_injector_->prepare_table();
+}
+
+template <data_type_t src_type, data_type_t dst_type>
+void _jit_avx512_core_x8s8s32x_deconvolution_fwd_t<src_type,
+ dst_type>::execute_forward_1d(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ auto &jcp = kernel_->jcp;
+
+ int oc_chunks = jcp.nb_oc / jcp.nb_oc_blocking;
+ int nb_groups = jcp.nb_ch;
+
+ const float *oscales = pd()->attr()->output_scales_.scales_;
+ if (jcp.signed_input && jcp.ver != ver_vnni) {
+ auto local_scales
+ = scratchpad(ctx).template get<float>(key_conv_adjusted_scales);
+ size_t count = pd()->attr()->output_scales_.count_;
+ float factor = 1.f / pd()->jcp_.wei_adj_scale;
+ if (count == 1) {
+ utils::array_set(local_scales, oscales[0] * factor, 16);
+ } else {
+ for (size_t c = 0; c < count; c++)
+ local_scales[c] = oscales[c] * factor;
+ }
+ oscales = local_scales;
+ }
+ size_t offset = (size_t)jcp.ngroups * jcp.oc * jcp.ic * jcp.kh * jcp.kw;
+ auto w = const_cast<wei_data_t *>(weights);
+ int32_t *compensation
+ = (jcp.signed_input) ? reinterpret_cast<int32_t *>(&w[offset]) : 0;
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ int start{ 0 }, end{ 0 };
+ int work_amount = jcp.mb * nb_groups * oc_chunks;
+ balance211(work_amount, nthr, ithr, start, end);
+
+ auto p = jit_deconv_call_s();
+
+ int n{ 0 }, g{ 0 }, occ{ 0 };
+ if (jcp.loop_order == loop_ngc)
+ nd_iterator_init(start, n, jcp.mb, g, nb_groups, occ, oc_chunks);
+ else if (jcp.loop_order == loop_cgn)
+ nd_iterator_init(start, occ, oc_chunks, g, nb_groups, n, jcp.mb);
+ else
+ assert(!"unsupported loop order");
+ while (start < end) {
+
+ int ocb = occ * jcp.nb_oc_blocking;
+ int g_oc = (g * jcp.ch_block * jcp.nb_oc + ocb) * jcp.oc_block;
+ int g_ic = g * jcp.ch_block * jcp.ic;
+
+ p.dst = dst + dst_d.blk_off(n, g_oc);
+ p.src = src + src_d.blk_off(n, g_ic);
+ p.filt = weights + wht_blk_off(weights_d, g, ocb, 0);
+ p.bias = jcp.with_bias ?
+ bias + (bias_d.blk_off(g_oc) * jcp.typesize_bia) :
+ 0;
+ p.compensation = (jcp.signed_input) ? compensation + g_oc : 0;
+ p.scales = &oscales[jcp.is_oc_scale * g_oc];
+ p.t_overflow = 0;
+ p.b_overflow = 0;
+ p.kh_padding = jcp.kh;
+ p.oc_blocks = jcp.is_depthwise ? g : ocb;
+
+ kernel_->jit_ker(&p);
+
+ ++start;
+ if (jcp.loop_order == loop_ngc)
+ nd_iterator_step(n, jcp.mb, g, nb_groups, occ, oc_chunks);
+ else if (jcp.loop_order == loop_cgn)
+ nd_iterator_step(occ, oc_chunks, g, nb_groups, n, jcp.mb);
+ else
+ assert(!"unsupported loop order");
+ }
+ });
+}
+
+template <data_type_t src_type, data_type_t dst_type>
+void _jit_avx512_core_x8s8s32x_deconvolution_fwd_t<src_type,
+ dst_type>::execute_forward_2d(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ auto &jcp = kernel_->jcp;
+
+ int oc_chunks = jcp.nb_oc / jcp.nb_oc_blocking;
+ int nb_groups = jcp.nb_ch;
+
+ size_t src_h_stride = src_d.blk_off(0, 0, 1);
+ size_t dst_h_stride = dst_d.blk_off(0, 0, 1);
+ size_t wht_kh_stride = wht_blk_off(weights_d, 0, 0, 0, 1);
+
+ const float *oscales = pd()->attr()->output_scales_.scales_;
+ if (jcp.signed_input && jcp.ver != ver_vnni) {
+ auto local_scales
+ = scratchpad(ctx).template get<float>(key_conv_adjusted_scales);
+ size_t count = pd()->attr()->output_scales_.count_;
+ float factor = 1.f / pd()->jcp_.wei_adj_scale;
+ if (count == 1) {
+ utils::array_set(local_scales, oscales[0] * factor, 16);
+ } else {
+ for (size_t c = 0; c < count; c++)
+ local_scales[c] = oscales[c] * factor;
+ }
+ oscales = local_scales;
+ }
+ size_t offset = (size_t)jcp.ngroups * jcp.oc * jcp.ic * jcp.kh * jcp.kw;
+ auto w = const_cast<wei_data_t *>(weights);
+ int32_t *compensation
+ = (jcp.signed_input) ? reinterpret_cast<int32_t *>(&w[offset]) : 0;
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ int start{ 0 }, end{ 0 };
+ int work_amount = jcp.mb * nb_groups * oc_chunks * jcp.oh;
+ balance211(work_amount, nthr, ithr, start, end);
+
+ auto p = jit_deconv_call_s();
+
+ /*loop order = cgn*/
+ int n{ 0 }, g{ 0 }, occ{ 0 }, oh_s{ 0 };
+ if (jcp.loop_order == loop_ngc)
+ nd_iterator_init(start, n, jcp.mb, g, nb_groups, occ, oc_chunks,
+ oh_s, jcp.oh);
+ else if (jcp.loop_order == loop_cgn)
+ nd_iterator_init(start, occ, oc_chunks, g, nb_groups, n, jcp.mb,
+ oh_s, jcp.oh);
+ else
+ assert(!"unsupported loop order");
+ while (start < end) {
+
+ int ocb = occ * jcp.nb_oc_blocking;
+ int g_oc = (g * jcp.ch_block * jcp.nb_oc + ocb) * jcp.oc_block;
+ int g_ic = g * jcp.ch_block * jcp.ic;
+ int work_rem = end - start;
+ int oh_e = oh_s + work_rem > jcp.oh ? jcp.oh : oh_s + work_rem;
+
+ auto dst_w = dst + dst_d.blk_off(n, g_oc);
+ auto src_w = src + src_d.blk_off(n, g_ic);
+ auto wht_w = weights + wht_blk_off(weights_d, g, ocb, 0);
+ auto bias_w = jcp.with_bias ?
+ bias + (bias_d.blk_off(g_oc) * jcp.typesize_bia) :
+ 0;
+ int32_t *compensation_w
+ = (jcp.signed_input) ? compensation + g_oc : 0;
+
+ auto scales = &oscales[jcp.is_oc_scale * g_oc];
+ for (int oj = oh_s; oj < oh_e; oj++) {
+ int ih_max = 0, kh_lo = 0, kh_len = 0;
+ if (jcp.dilate_h != 0 && jcp.stride_h == 1) {
+ /* dilation */
+ int dilate_h = jcp.dilate_h + 1;
+ // Note: use div_up to account for "holes" in filter
+ int o_t_overflow = div_up(
+ max(0, (jcp.kh - 1) * dilate_h - oj - jcp.t_pad),
+ dilate_h);
+ int o_b_overflow
+ = div_up(max(0, (jcp.kh - 1) * dilate_h + 1 - jcp.oh
+ + oj - jcp.b_pad),
+ dilate_h);
+ kh_len = jcp.kh - o_t_overflow - o_b_overflow;
+ kh_lo = o_b_overflow;
+ ih_max = oj + jcp.t_pad - o_b_overflow * dilate_h;
+ } else {
+ int o_t_overflow = max(
+ 0, (jcp.kh - (oj + 1 + jcp.t_pad)) / jcp.stride_h);
+ int o_b_overflow
+ = max(0, ((oj + jcp.kh) - (jcp.oh + jcp.b_pad))
+ / jcp.stride_h);
+ int overflow_kh_hi = jcp.kh - 1
+ - abs(jcp.oh + jcp.b_pad - (oj + 1)) % jcp.stride_h;
+ int overflow_kh_lo = (oj + jcp.t_pad) % jcp.stride_h;
+
+ kh_len = (overflow_kh_hi - overflow_kh_lo) / jcp.stride_h
+ + 1 - o_t_overflow - o_b_overflow;
+ kh_lo = overflow_kh_lo + o_b_overflow * jcp.stride_h;
+ ih_max = (oj + jcp.t_pad - kh_lo) / jcp.stride_h;
+ }
+
+ int wei_stride
+ = (!jcp.signed_input) ? kh_lo * wht_kh_stride : 0;
+ p.src = src_w + ih_max * src_h_stride;
+ p.dst = dst_w + oj * dst_h_stride;
+ p.filt = wht_w + wei_stride;
+ p.bias = bias_w;
+ p.compensation = compensation_w;
+ p.t_overflow = max(
+ 0, jcp.kh - (kh_lo + max(0, kh_len - 1) * jcp.stride_h
+ + 1));
+ p.b_overflow = kh_lo;
+ p.kh_padding = kh_len;
+ p.scales = scales;
+ p.oc_blocks = jcp.is_depthwise ? g : ocb;
+ kernel_->jit_ker(&p);
+ }
+ if (jcp.loop_order == loop_ngc)
+ nd_iterator_jump(start, end, n, jcp.mb, g, nb_groups, occ,
+ oc_chunks, oh_s, jcp.oh);
+ else if (jcp.loop_order == loop_cgn)
+ nd_iterator_jump(start, end, occ, oc_chunks, g, nb_groups, n,
+ jcp.mb, oh_s, jcp.oh);
+ else
+ assert(!"unsupported loop order");
+ }
+ });
+}
+
+template struct _jit_avx512_core_x8s8s32x_deconvolution_fwd_t<data_type::u8,
+ data_type::u8>;
+template struct _jit_avx512_core_x8s8s32x_deconvolution_fwd_t<data_type::u8,
+ data_type::s8>;
+template struct _jit_avx512_core_x8s8s32x_deconvolution_fwd_t<data_type::u8,
+ data_type::f32>;
+template struct _jit_avx512_core_x8s8s32x_deconvolution_fwd_t<data_type::u8,
+ data_type::s32>;
+template struct _jit_avx512_core_x8s8s32x_deconvolution_fwd_t<data_type::s8,
+ data_type::u8>;
+template struct _jit_avx512_core_x8s8s32x_deconvolution_fwd_t<data_type::s8,
+ data_type::s8>;
+template struct _jit_avx512_core_x8s8s32x_deconvolution_fwd_t<data_type::s8,
+ data_type::f32>;
+template struct _jit_avx512_core_x8s8s32x_deconvolution_fwd_t<data_type::s8,
+ data_type::s32>;
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_deconvolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_deconvolution.hpp
new file mode 100644
index 0000000000..901038fa48
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_avx512_core_x8s8s32x_deconvolution.hpp
@@ -0,0 +1,237 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX512_CORE_U8S8S32X_DECONVOLUTION_HPP
+#define CPU_JIT_AVX512_CORE_U8S8S32X_DECONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "cpu_primitive.hpp"
+#include "cpu_memory.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+#include "nstl.hpp"
+
+#include "cpu_deconvolution_pd.hpp"
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+#include "jit_uni_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+typedef enum {
+ no_last_block = 0x1U,
+ last_ic_block = 0x2U,
+ last_sp_block = 0x4U,
+} ker_block_t;
+
+struct jit_avx512_core_x8s8s32x_deconv_fwd_kernel : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_avx512_core_x8s8s32x_deconv_fwd_ker_t);
+
+ jit_avx512_core_x8s8s32x_deconv_fwd_kernel(
+ const jit_conv_conf_t &ajcp, const primitive_attr_t &attr)
+ : jcp(ajcp), attr_(attr), eltwise_injector_(nullptr) {
+ if (jcp.with_eltwise)
+ eltwise_injector_ = new jit_uni_eltwise_injector_f32<avx512_common>(
+ this, jcp.eltwise);
+ generate();
+ jit_ker = (void (*)(jit_deconv_call_s *))getCode();
+ }
+
+ ~jit_avx512_core_x8s8s32x_deconv_fwd_kernel() {
+ delete eltwise_injector_;
+ }
+
+ static bool post_ops_ok(jit_conv_conf_t &jcp,
+ const primitive_attr_t &attr);
+
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const deconvolution_desc_t &cd,
+ memory_desc_t &src_md,
+ memory_desc_t &weights_md,
+ memory_desc_t &dst_md,
+ const bool with_bias,
+ memory_desc_t &bias_md,
+ const primitive_attr_t &attr);
+
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_conf_t &jcp, const primitive_attr_t &attr);
+
+ const jit_conv_conf_t &jcp;
+ const primitive_attr_t &attr_;
+ void (*jit_ker)(jit_deconv_call_s *);
+private:
+ jit_uni_eltwise_injector_f32<avx512_common> *eltwise_injector_;
+ using reg64_t = const Xbyak::Reg64;
+ using zmm_t = const Xbyak::Zmm;
+ using xmm_t = const Xbyak::Xmm;
+
+ reg64_t reg_src = r8;
+ reg64_t reg_filt = r9;
+ reg64_t reg_dst = r10;
+ reg64_t param1 = abi_param1;
+ reg64_t reg_kh = abi_not_param1;
+ reg64_t reg_nur_w = rbx;
+ reg64_t reg_bias = rdx;
+ reg64_t reg_icb = reg_bias;
+ reg64_t reg_ptr_scales = rax;
+ reg64_t reg_oc_blocks = rsi;
+
+ reg64_t aux_reg_src = r11;
+ reg64_t aux_reg_filt = r12;
+
+ reg64_t reg_compensation = r14;
+ reg64_t reg_scratch = r14;
+ reg64_t reg_ptr_sum_scale = r11;
+ reg64_t reg_bias_alpha = abi_not_param1;
+ reg64_t reg_overflow = rax;
+ reg64_t reg_comp_strides = reg_overflow;
+
+ Xbyak::Opmask ktail_mask = Xbyak::Opmask(2);
+ zmm_t zmm_tmp = zmm_t(28);
+ zmm_t zmm_one = zmm_t(29);
+ /* used during write-out section of store_output */
+ zmm_t zmm_zero = zmm_t(31);
+ zmm_t zmm_wei = zmm_t(31);
+
+ /* signed input */
+ zmm_t zmm_shift = zmm_t(30);
+ zmm_t zmm_comp = zmm_t(30);
+ zmm_t zmm_bias = zmm_t(31);
+ zmm_t zmm_prev_dst = zmm_t(31);
+
+ zmm_t zmm_out(int i_ur, int i_oc) {
+ int idx = i_ur * jcp.nb_oc_blocking + i_oc;
+ assert(idx < 31);
+ return zmm_t(idx);
+ }
+ zmm_t zmm_inp(int i_ic, int nb_x_blocking) {
+ int idx = i_ic + nb_x_blocking * jcp.ur_w;
+ assert(idx < 31);
+ return zmm_t(idx);
+ }
+ zmm_t zmm_bias_alpha() {
+ return zmm_t(jcp.nb_oc_blocking * jcp.ur_w);
+ }
+ xmm_t xmm_bias_alpha() {
+ return xmm_t(jcp.nb_oc_blocking * jcp.ur_w);
+ }
+
+ int get_ow_start(int ki, int l_overflow) {
+ int res = (jcp.ow - 1 + jcp.r_pad) % jcp.stride_w
+ + l_overflow * jcp.stride_w
+ - (jcp.kw - 1 - ki) * (jcp.dilate_w + 1);
+ while (res < 0)
+ res += jcp.stride_w;
+ return res;
+ }
+
+ int get_ow_end(int ur_w, int ki, int r_overflow) {
+ if (utils::one_of(ur_w, jcp.ow, jcp.ur_w_tail))
+ ur_w += nstl::min(0, jcp.r_pad); // remove negative padding
+ int res = (ur_w - 1 + jcp.l_pad) % jcp.stride_w
+ + r_overflow * jcp.stride_w - ki * (jcp.dilate_w + 1);
+ while (res < 0)
+ res += jcp.stride_w;
+ return ur_w - res;
+ }
+ bool maybe_eltwise(int position);
+ void compute_eltwise(int ur_w);
+ void prepare_output(int ur_w);
+ void store_output(int ur_w, bool last_oc_block);
+ void compute_ker(int ur_w, int l_overflow, int r_overflow,
+ ker_block_t last_ic_block_flag, bool h_padded = false);
+ void kh_loop(int ur_w, int pad_l, int pad_r, ker_block_t last_ker_block);
+ void icb_loop(int ur_w, int pad_l, int pad_r, bool last_block);
+ void generate();
+ void cvt2ps(data_type_t type_in, zmm_t zmm_in, const Xbyak::Operand &op,
+ bool mask_flag);
+};
+
+template <impl::data_type_t src_type, impl::data_type_t dst_type>
+struct _jit_avx512_core_x8s8s32x_deconvolution_fwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_deconvolution_fwd_pd_t {
+ using cpu_deconvolution_fwd_pd_t::cpu_deconvolution_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_deconvolution:", avx512_core, ""),
+ _jit_avx512_core_x8s8s32x_deconvolution_fwd_t<src_type, dst_type>);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && (desc()->alg_kind & alg_kind::deconvolution_direct)
+ && desc()->src_desc.data_type == src_type
+ && desc()->dst_desc.data_type == dst_type
+ && IMPLICATION(with_bias(), utils::one_of(
+ desc()->bias_desc.data_type, data_type::f32,
+ data_type::s32, data_type::s8, data_type::u8))
+ && desc()->accum_data_type == data_type::s32;
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_avx512_core_x8s8s32x_deconv_fwd_kernel::
+ init_conf(jcp_, *desc(), src_md_, weights_md_, dst_md_,
+ with_bias(), bias_md_, *attr());
+
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_avx512_core_x8s8s32x_deconv_fwd_kernel::init_scratchpad(scratchpad,
+ jcp_, *attr());
+
+ return status::success;
+ }
+
+ jit_conv_conf_t jcp_;
+ };
+
+ _jit_avx512_core_x8s8s32x_deconvolution_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ {
+ kernel_ = new jit_avx512_core_x8s8s32x_deconv_fwd_kernel(pd()->jcp_,
+ *pd()->attr());
+ }
+
+ ~_jit_avx512_core_x8s8s32x_deconvolution_fwd_t() { delete kernel_; }
+
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<data_type::s8>::type wei_data_t;
+ typedef typename prec_traits<dst_type>::type dst_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ if(pd()->ndims() == 3)
+ execute_forward_1d(ctx);
+ else
+ execute_forward_2d(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward_1d(const exec_ctx_t &ctx) const;
+ void execute_forward_2d(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ jit_avx512_core_x8s8s32x_deconv_fwd_kernel *kernel_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_generator.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_generator.hpp
new file mode 100644
index 0000000000..c09592d5c9
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_generator.hpp
@@ -0,0 +1,773 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_AVX2_GENERATOR_HPP
+#define CPU_JIT_AVX2_GENERATOR_HPP
+
+#include <limits.h>
+
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "cpu_isa_traits.hpp"
+#include "jit_utils/jit_utils.hpp"
+
+#if defined(_WIN32) && !defined(__GNUC__)
+# define STRUCT_ALIGN(al, ...) __declspec(align(al)) __VA_ARGS__
+#else
+# define STRUCT_ALIGN(al, ...) __VA_ARGS__ __attribute__((__aligned__(al)))
+#endif
+
+#if defined(_WIN32)
+# define OFFSET_SHADOWSPACE 0x28
+#endif
+
+#define DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_name) \
+ const char *name() const override { return STRINGIFY(jit_name); } \
+ const char *source_file() const override { return __FILE__; }
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+// TODO: move this to jit_generator class?
+namespace {
+
+typedef enum {
+ PAGE_4K = 4096,
+ PAGE_2M = 2097152,
+} cpu_page_size_t;
+
+// TODO: move this somewhere else? Although this is only used by jit kernels
+// (Roma)
+static inline int float2int(float x) {
+ union {
+ float vfloat;
+ int vint;
+ } cvt;
+ cvt.vfloat = x;
+ return cvt.vint;
+}
+
+// TODO: A GPR class that hides ABI details from the JIT kernels and allows
+// numbering registers from 0 to 14 (x86_64) / 6 (x32) (gpr0, gpr1, ...) and
+// stack register (sr).
+//
+// This will allow using syntax like this:
+//
+// param = gpr0;
+// reg_input = gpr0;
+// reg_output = gpr1;
+// ...
+//
+// #ifndef XBYAK64
+// mov(param, ptr[sr])
+// #endif
+//
+// (Roma)
+
+#ifdef XBYAK64
+constexpr Xbyak::Operand::Code abi_save_gpr_regs[] = {
+ Xbyak::Operand::RBX, Xbyak::Operand::RBP, Xbyak::Operand::R12,
+ Xbyak::Operand::R13, Xbyak::Operand::R14, Xbyak::Operand::R15,
+#ifdef _WIN32
+ Xbyak::Operand::RDI, Xbyak::Operand::RSI,
+#endif
+};
+
+#ifdef _WIN32
+static const Xbyak::Reg64 abi_param1(Xbyak::Operand::RCX),
+ abi_param2(Xbyak::Operand::RDX),
+ abi_param3(Xbyak::Operand::R8),
+ abi_param4(Xbyak::Operand::R9),
+ abi_not_param1(Xbyak::Operand::RDI);
+#else
+static const Xbyak::Reg64 abi_param1(Xbyak::Operand::RDI),
+ abi_param2(Xbyak::Operand::RSI),
+ abi_param3(Xbyak::Operand::RDX),
+ abi_param4(Xbyak::Operand::RCX),
+ abi_param5(Xbyak::Operand::R8),
+ abi_param6(Xbyak::Operand::R9),
+ abi_not_param1(Xbyak::Operand::RCX);
+#endif
+#endif
+
+inline unsigned int get_cache_size(int level, bool per_core = true){
+ unsigned int l = level - 1;
+ // Currently, if XByak is not able to fetch the cache topology
+ // we default to 32KB of L1, 512KB of L2 and 1MB of L3 per core.
+ if (cpu.getDataCacheLevels() == 0){
+ const int L1_cache_per_core = 32000;
+ const int L2_cache_per_core = 512000;
+ const int L3_cache_per_core = 1024000;
+ int num_cores = per_core ? 1 : mkldnn_get_max_threads();
+ switch(l){
+ case(0): return L1_cache_per_core * num_cores;
+ case(1): return L2_cache_per_core * num_cores;
+ case(2): return L3_cache_per_core * num_cores;
+ default: return 0;
+ }
+ }
+ if (l < cpu.getDataCacheLevels()) {
+ return cpu.getDataCacheSize(l)
+ / (per_core ? cpu.getCoresSharingDataCache(l) : 1);
+ } else
+ return 0;
+}
+
+}
+
+class jit_generator : public Xbyak::CodeGenerator
+{
+private:
+ const size_t xmm_len = 16;
+#ifdef _WIN32
+ const size_t xmm_to_preserve_start = 6;
+ const size_t xmm_to_preserve = 10;
+#else
+ const size_t xmm_to_preserve_start = 0;
+ const size_t xmm_to_preserve = 0;
+#endif
+
+ const size_t num_abi_save_gpr_regs
+ = sizeof(abi_save_gpr_regs) / sizeof(abi_save_gpr_regs[0]);
+
+ const size_t size_of_abi_save_regs
+ = num_abi_save_gpr_regs * rax.getBit() / 8
+ + xmm_to_preserve * xmm_len;
+
+public:
+ enum {
+ _cmp_eq_oq = 0u,
+ _cmp_lt_os = 1u,
+ _cmp_le_os = 2u,
+ _cmp_neq_uq = 4u,
+ _cmp_nlt_us = 5u,
+ _cmp_nle_us = 6u,
+
+ _op_floor = 1u,
+ _op_mxcsr = 4u,
+ };
+
+ Xbyak::Reg64 param1 = abi_param1;
+ const int EVEX_max_8b_offt = 0x200;
+ const Xbyak::Reg64 reg_EVEX_max_8b_offt = rbp;
+
+ inline size_t get_size_of_abi_save_regs() {
+ return size_of_abi_save_regs;
+ }
+
+ void preamble() {
+ if (xmm_to_preserve) {
+ sub(rsp, xmm_to_preserve * xmm_len);
+ for (size_t i = 0; i < xmm_to_preserve; ++i)
+ movdqu(ptr[rsp + i * xmm_len], Xbyak::Xmm(xmm_to_preserve_start + i));
+ }
+ for (size_t i = 0; i < num_abi_save_gpr_regs; ++i)
+ push(Xbyak::Reg64(abi_save_gpr_regs[i]));
+ if (mayiuse(avx512_common)) {
+ mov(reg_EVEX_max_8b_offt, 2 * EVEX_max_8b_offt);
+ }
+ }
+
+ void mic_prefetcht0(Xbyak::Address a) {
+ if (mayiuse(avx512_mic))
+ prefetcht0(a);
+ }
+
+ void mic_prefetcht1(Xbyak::Address a) {
+ if (mayiuse(avx512_mic))
+ prefetcht1(a);
+ }
+
+ void mic_prefetcht2(Xbyak::Address a) {
+ if (mayiuse(avx512_mic))
+ prefetcht2(a);
+ }
+
+ void uni_vzeroupper() {
+ if (mayiuse(avx) && !mayiuse(avx512_mic))
+ vzeroupper();
+ }
+
+ void postamble() {
+ for (size_t i = 0; i < num_abi_save_gpr_regs; ++i)
+ pop(Xbyak::Reg64(abi_save_gpr_regs[num_abi_save_gpr_regs - 1 - i]));
+ if (xmm_to_preserve) {
+ for (size_t i = 0; i < xmm_to_preserve; ++i)
+ movdqu(Xbyak::Xmm(xmm_to_preserve_start + i), ptr[rsp + i * xmm_len]);
+ add(rsp, xmm_to_preserve * xmm_len);
+ }
+ uni_vzeroupper();
+ ret();
+ }
+
+ template<typename T>
+ Xbyak::Address EVEX_compress_addr(Xbyak::Reg64 base,
+ T raw_offt, bool bcast = false)
+ {
+ using Xbyak::Zmm;
+ using Xbyak::Reg64;
+ using Xbyak::Address;
+ using Xbyak::RegExp;
+
+ assert(raw_offt <= INT_MAX);
+ auto offt = static_cast<int>(raw_offt);
+
+ int scale = 0;
+
+ if (EVEX_max_8b_offt <= offt && offt < 3 * EVEX_max_8b_offt) {
+ offt = offt - 2 * EVEX_max_8b_offt;
+ scale = 1;
+ } else if (3 * EVEX_max_8b_offt <= offt && offt < 5 * EVEX_max_8b_offt) {
+ offt = offt - 4 * EVEX_max_8b_offt;
+ scale = 2;
+ }
+
+ auto re = RegExp() + base + offt;
+ if (scale)
+ re = re + reg_EVEX_max_8b_offt * scale;
+
+ if (bcast)
+ return zword_b [re];
+ else
+ return zword [re];
+ }
+
+ Xbyak::Address make_safe_addr(const Xbyak::Reg64 &reg_out, size_t offt,
+ const Xbyak::Reg64 &tmp_reg, bool bcast = false) {
+ if (offt > INT_MAX) {
+ mov(tmp_reg, offt);
+ return bcast ? ptr_b[reg_out + tmp_reg] : ptr[reg_out + tmp_reg];
+ } else {
+ return bcast ? ptr_b[reg_out + offt] : ptr[reg_out + offt];
+ }
+ }
+
+ Xbyak::Address EVEX_compress_addr_safe(const Xbyak::Reg64 &base,
+ size_t raw_offt, const Xbyak::Reg64 &reg_offt, bool bcast = false) {
+ if (raw_offt > INT_MAX) {
+ return make_safe_addr(base, raw_offt, reg_offt, bcast);
+ } else {
+ return EVEX_compress_addr(base, raw_offt, bcast);
+ }
+ }
+
+ void safe_add(const Xbyak::Reg64 &base, size_t raw_offt,
+ const Xbyak::Reg64 &reg_offt) {
+ if (raw_offt > INT_MAX) {
+ mov(reg_offt, raw_offt);
+ add(base, reg_offt);
+ } else {
+ add(base, raw_offt);
+ }
+ }
+
+ void safe_sub(const Xbyak::Reg64 &base, size_t raw_offt,
+ const Xbyak::Reg64 &reg_offt) {
+ if (raw_offt > INT_MAX) {
+ mov(reg_offt, raw_offt);
+ sub(base, reg_offt);
+ } else {
+ sub(base, raw_offt);
+ }
+ }
+
+ // Disallow char-based labels completely
+ void L(const char *label) = delete;
+ void L(Xbyak::Label& label) { Xbyak::CodeGenerator::L(label); }
+
+ void uni_vpxor(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2,
+ const Xbyak::Operand &op) {
+ assert(x1.getIdx() == x2.getIdx());
+ pxor(x2, op);
+ }
+ void uni_vpxor(const Xbyak::Ymm &x1, const Xbyak::Ymm &x2,
+ const Xbyak::Operand &op) {
+ if (mayiuse(avx2)) {
+ vpxor(x1, x2, op);
+ } else {
+ vxorps(x1, x2, op);
+ }
+ }
+ void uni_vpxor(const Xbyak::Zmm &x1, const Xbyak::Zmm &x2,
+ const Xbyak::Operand &op) {
+ vpxord(x1, x2, op);
+ }
+
+ void uni_vmovss(const Xbyak::Address& addr, const Xbyak::Xmm &x) {
+ movss(addr, x);
+ }
+ void uni_vmovss(const Xbyak::Address& addr, const Xbyak::Ymm &x) {
+ vmovss(addr, x);
+ }
+ void uni_vmovss(const Xbyak::Xmm &x, const Xbyak::Address& addr) {
+ movss(x, addr);
+ }
+ void uni_vmovss(const Xbyak::Ymm &x, const Xbyak::Address& addr) {
+ vmovss(x, addr);
+ }
+
+ void uni_vmovsd(const Xbyak::Address& addr, const Xbyak::Xmm &x) {
+ movsd(addr, x);
+ }
+ void uni_vmovsd(const Xbyak::Address& addr, const Xbyak::Ymm &x) {
+ vmovsd(addr, x);
+ }
+ void uni_vmovsd(const Xbyak::Xmm &x, const Xbyak::Address& addr) {
+ movsd(x, addr);
+ }
+ void uni_vmovsd(const Xbyak::Ymm &x, const Xbyak::Address& addr) {
+ vmovsd(x, addr);
+ }
+
+ void uni_vmovdqu(const Xbyak::Address &addr, const Xbyak::Xmm &x) {
+ movdqu(addr, x);
+ }
+ void uni_vmovdqu(const Xbyak::Address &addr, const Xbyak::Ymm &x) {
+ vmovdqu(addr, x);
+ }
+ void uni_vmovdqu(const Xbyak::Address &addr, const Xbyak::Zmm &x) {
+ vmovdqu32(addr, x);
+ }
+
+ void uni_vmovdqu(const Xbyak::Xmm &x, const Xbyak::Address &addr) {
+ movdqu(x, addr);
+ }
+ void uni_vmovdqu(const Xbyak::Ymm &x, const Xbyak::Address &addr) {
+ vmovdqu(x, addr);
+ }
+ void uni_vmovdqu(const Xbyak::Zmm &x, const Xbyak::Address &addr) {
+ vmovdqu32(x, addr);
+ }
+
+ void uni_vmovups(const Xbyak::Address &addr, const Xbyak::Xmm &x) {
+ movups(addr, x);
+ }
+ void uni_vmovups(const Xbyak::Address &addr, const Xbyak::Ymm &x) {
+ vmovups(addr, x);
+ }
+
+ void uni_vmovups(const Xbyak::Xmm &x, const Xbyak::Operand &op) {
+ movups(x, op);
+ }
+ void uni_vmovups(const Xbyak::Ymm &x, const Xbyak::Operand &op) {
+ vmovups(x, op);
+ }
+
+ void uni_vmovntps(const Xbyak::Address &addr, const Xbyak::Xmm &x) {
+ movntps(addr, x);
+ }
+ void uni_vmovntps(const Xbyak::Address &addr, const Xbyak::Ymm &x) {
+ vmovntps(addr, x);
+ }
+
+ void uni_vbroadcastss(const Xbyak::Xmm &x, const Xbyak::Operand &op) {
+ movss(x, op);
+ shufps(x, x, 0x0);
+ }
+ void uni_vbroadcastss(const Xbyak::Ymm &x, const Xbyak::Operand &op) {
+ if (op.isMEM() || mayiuse(avx2)) {
+ vbroadcastss(x, op);
+ } else {
+ Xbyak::Xmm t(x.getIdx());
+ if (t.getIdx() != op.getIdx()) movss(t, op);
+ vinsertf128(x, x, t, 1);
+ vshufps(x, x, x, 0);
+ }
+ }
+
+ void uni_vpbroadcastd(const Xbyak::Xmm &x, const Xbyak::Operand &op) {
+ movsd(x, op);
+ pshufd(x, x, 0x0);
+ }
+ void uni_vpbroadcastd(const Xbyak::Ymm &x, const Xbyak::Operand &op) {
+ if (mayiuse(avx2)) {
+ vpbroadcastd(x, op);
+ } else {
+ Xbyak::Xmm t(x.getIdx());
+ if (t.getIdx() != op.getIdx()) movsd(t, op);
+ vinsertf128(x, x, t, 1);
+ vshufps(x, x, x, 0);
+ }
+ }
+
+ void uni_vrcpss(const Xbyak::Xmm &x, const Xbyak::Operand &op) {
+ rcpss(x, op);
+ }
+ void uni_vrcpss(const Xbyak::Ymm &x1, const Xbyak::Xmm &x2) {
+ Xbyak::Xmm x1_(x1.getIdx());
+ Xbyak::Xmm x2_(x2.getIdx());
+ vrcpss(x1_, x1_, x2_);
+ }
+ void uni_vrcpss(const Xbyak::Ymm &x, const Xbyak::Address &op) {
+ Xbyak::Xmm x_(x.getIdx());
+ vrcpss(x_, x_, op);
+ }
+
+ void uni_vrcpps(const Xbyak::Xmm &x, const Xbyak::Operand &op) {
+ rcpps(x, op);
+ }
+ void uni_vrcpps(const Xbyak::Ymm &x, const Xbyak::Operand &op) {
+ vrcpps(x, op);
+ }
+ void uni_vrcpps(const Xbyak::Zmm &x, const Xbyak::Operand &op) {
+ vrcp14ps(x, op);
+ }
+
+ void uni_vdivps(const Xbyak::Xmm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ assert(x.getIdx() == op1.getIdx());
+ divps(x, op2);
+ }
+ void uni_vdivps(const Xbyak::Ymm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ vdivps(x, op1, op2);
+ }
+
+ void uni_vdivps(const Xbyak::Xmm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2, const Xbyak::Xmm &buf) {
+ movups(buf, op1);
+ divps(buf, op2);
+ if (x.getIdx() != buf.getIdx()) {
+ movups(x, buf);
+ }
+ }
+
+ void uni_vdivps(const Xbyak::Ymm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2, const Xbyak::Ymm &buf) {
+ vdivps(x, op1, op2);
+ }
+
+ void uni_vaddps(const Xbyak::Xmm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ assert(x.getIdx() == op1.getIdx());
+ addps(x, op2);
+ }
+ void uni_vaddps(const Xbyak::Ymm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ vaddps(x, op1, op2);
+ }
+
+ void uni_vpsignd(const Xbyak::Xmm& x1, const Xbyak::Xmm& x2,
+ const Xbyak::Operand& op) {
+ assert(x1.getIdx() == x2.getIdx());
+ psignd(x1, op);
+ }
+ void uni_vpsignd(const Xbyak::Ymm& x1, const Xbyak::Ymm& x2,
+ const Xbyak::Operand& op) {
+ vpsignd(x1, x2, op);
+ }
+
+ void uni_vsubps(const Xbyak::Xmm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ assert(x.getIdx() == op1.getIdx());
+ subps(x, op2);
+ }
+ void uni_vsubps(const Xbyak::Ymm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ vsubps(x, op1, op2);
+ }
+
+ void uni_vsubps(const Xbyak::Xmm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2, const Xbyak::Xmm &buf) {
+ movups(buf, op1);
+ subps(buf, op2);
+ if (x.getIdx() != buf.getIdx()) {
+ movups(x, buf);
+ }
+ }
+
+ void uni_vsubps(const Xbyak::Ymm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2, const Xbyak::Ymm &buf) {
+ vsubps(x, op1, op2);
+ }
+
+ void uni_vmulps(const Xbyak::Xmm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ assert(x.getIdx() == op1.getIdx());
+ mulps(x, op2);
+ }
+ void uni_vmulps(const Xbyak::Ymm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ vmulps(x, op1, op2);
+ }
+
+ void uni_vfmadd213ps(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2,
+ const Xbyak::Operand &op) {
+ mulps(x1, x2);
+ addps(x1, op);
+ }
+ void uni_vfmadd213ps(const Xbyak::Ymm &x1, const Xbyak::Ymm &x2,
+ const Xbyak::Operand &op) {
+ vfmadd213ps(x1, x2, op);
+ }
+
+ void uni_vfmadd231ps(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2,
+ const Xbyak::Operand &op) {
+ mulps(x2, op);
+ addps(x1, x2);
+ }
+ void uni_vfmadd231ps(const Xbyak::Ymm &x1, const Xbyak::Ymm &x2,
+ const Xbyak::Operand &op) {
+ vfmadd231ps(x1, x2, op);
+ }
+
+ void uni_vfnmadd231ps(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2,
+ const Xbyak::Operand &op) {
+ mulps(x2, op);
+ subps(x1, x2);
+ }
+
+ void uni_vfnmadd231ps(const Xbyak::Ymm &x1, const Xbyak::Ymm &x2,
+ const Xbyak::Operand &op) {
+ vfnmadd231ps(x1, x2, op);
+ }
+
+ void uni_vsqrtps(const Xbyak::Xmm &x, const Xbyak::Operand &op) {
+ sqrtps(x, op);
+ }
+ void uni_vsqrtps(const Xbyak::Ymm &x, const Xbyak::Operand &op) {
+ vsqrtps(x, op);
+ }
+
+ void uni_vpaddd(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2,
+ const Xbyak::Operand &op) {
+ assert(x1.getIdx() == x2.getIdx());
+ paddd(x2, op);
+ }
+ void uni_vpaddd(const Xbyak::Ymm &x1, const Xbyak::Xmm &x2,
+ const Xbyak::Operand &op) {
+ vpaddd(x1, x2, op);
+ }
+
+ void uni_vandps(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2,
+ const Xbyak::Operand &op = Xbyak::Operand()) {
+ assert(x1.getIdx() == x2.getIdx());
+ andps(x1, op);
+ }
+ void uni_vandps(const Xbyak::Ymm &x1, const Xbyak::Ymm &x2,
+ const Xbyak::Operand &op = Xbyak::Operand()) {
+ if (!mayiuse(avx512_common) || x1.getBit() < 512)
+ vandps(x1, x2, op);
+ else
+ vpandd(x1, x2, op);
+ }
+
+ void uni_vorps(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2,
+ const Xbyak::Operand &op = Xbyak::Operand()) {
+ assert(x1.getIdx() == x2.getIdx());
+ orps(x1, op);
+ }
+ void uni_vorps(const Xbyak::Ymm &x1, const Xbyak::Ymm &x2,
+ const Xbyak::Operand &op = Xbyak::Operand()) {
+ if (!mayiuse(avx512_common) || x1.getBit() < 512)
+ vorps(x1, x2, op);
+ else
+ vpord(x1, x2, op);
+ }
+
+ void uni_vpslld(const Xbyak::Xmm &x, const Xbyak::Operand &op,
+ const int imm) {
+ assert(x.getIdx() == op.getIdx());
+ pslld(x, imm);
+ }
+ void uni_vpslld(const Xbyak::Ymm &x, const Xbyak::Operand &op,
+ const int imm) {
+ vpslld(x, op, imm);
+ }
+
+ void uni_vpsrld(const Xbyak::Xmm &x, const Xbyak::Operand &op,
+ const int imm) {
+ assert(x.getIdx() == op.getIdx());
+ psrld(x, imm);
+ }
+ void uni_vpsrld(const Xbyak::Ymm &x, const Xbyak::Operand &op,
+ const int imm) {
+ vpsrld(x, op, imm);
+ }
+
+ void uni_vmaxps(const Xbyak::Xmm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ assert(x.getIdx() == op1.getIdx());
+ maxps(x, op2);
+ }
+ void uni_vmaxps(const Xbyak::Ymm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ vmaxps(x, op1, op2);
+ }
+
+ void uni_vminps(const Xbyak::Xmm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ assert(x.getIdx() == op1.getIdx());
+ minps(x, op2);
+ }
+ void uni_vminps(const Xbyak::Ymm &x, const Xbyak::Operand &op1,
+ const Xbyak::Operand &op2 = Xbyak::Operand()) {
+ vminps(x, op1, op2);
+ }
+
+ void uni_vcmpgtps(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2,
+ const Xbyak::Operand &op) {
+ assert(x1.getIdx() == x2.getIdx());
+ cmpps(x1, op, _cmp_nle_us);
+ }
+
+ void uni_vcmpgtps(const Xbyak::Ymm &x1, const Xbyak::Ymm &x2,
+ const Xbyak::Operand &op) {
+ vcmpgtps(x1, x2, op);
+ }
+
+ void uni_vcmpgeps(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2,
+ const Xbyak::Operand &op) {
+ assert(x1.getIdx() == x2.getIdx());
+ cmpps(x1, op, _cmp_nlt_us);
+ }
+
+ void uni_vcmpgeps(const Xbyak::Ymm &x1, const Xbyak::Ymm &x2,
+ const Xbyak::Operand &op) {
+ vcmpps(x1, x2, op, _cmp_nlt_us);
+ }
+
+ void uni_vtestps(const Xbyak::Xmm &x1, const Xbyak::Operand &op) {
+ ptest(x1, op);
+ }
+
+ void uni_vtestps(const Xbyak::Ymm &x1, const Xbyak::Operand &op) {
+ assert(!(x1.isZMM() || op.isZMM()));
+ vtestps(x1, op);
+ }
+
+ void uni_vblendvps(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2,
+ const Xbyak::Operand &op, const Xbyak::Xmm &msk) {
+ assert(x1.getIdx() == x2.getIdx());
+ assert(msk.getIdx() == 0);
+ blendvps(x1, op);
+ }
+ void uni_vblendvps(const Xbyak::Ymm &x1, const Xbyak::Ymm &x2,
+ const Xbyak::Operand &op, const Xbyak::Ymm &msk) {
+ vblendvps(x1, x2, op, msk);
+ }
+
+ void uni_vroundps(const Xbyak::Xmm &x, const Xbyak::Operand &op,
+ const int imm) {
+ roundps(x, op, imm);
+ }
+ void uni_vroundps(const Xbyak::Ymm &x, const Xbyak::Operand &op,
+ const int imm) {
+ vroundps(x, op, imm);
+ }
+
+ void uni_vcvtps2dq(const Xbyak::Xmm &x, const Xbyak::Operand &op) {
+ cvtps2dq(x, op);
+ }
+ void uni_vcvtps2dq(const Xbyak::Ymm &x, const Xbyak::Operand &op) {
+ vcvtps2dq(x, op);
+ }
+
+ void uni_vcvtdq2ps(const Xbyak::Xmm &x, const Xbyak::Operand &op) {
+ cvtdq2ps(x, op);
+ }
+ void uni_vcvtdq2ps(const Xbyak::Ymm &x, const Xbyak::Operand &op) {
+ vcvtdq2ps(x, op);
+ }
+
+ void uni_vmovmskps(const Xbyak::Reg &x1, const Xbyak::Xmm &x2) {
+ movmskps(x1.cvt64(), x2);
+ }
+ void uni_vmovmskps(const Xbyak::Reg &x1, const Xbyak::Ymm &x2) {
+ vmovmskps(x1, x2);
+ }
+
+ void uni_vpackssdw(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2, const Xbyak::Operand &op){
+ assert(x1.getIdx() == x1.getIdx());
+ packssdw(x1, op);
+ }
+ void uni_vpackssdw(const Xbyak::Ymm &x1, const Xbyak::Ymm &x2, const Xbyak::Operand &op){
+ vpackssdw(x1, x2, op);
+ }
+
+ void uni_vpackuswb(const Xbyak::Xmm &x1, const Xbyak::Xmm &x2, const Xbyak::Operand &op){
+ assert(x1.getIdx() == x1.getIdx());
+ packuswb(x1, op);
+ }
+ void uni_vpackuswb(const Xbyak::Ymm &x1, const Xbyak::Ymm &x2, const Xbyak::Operand &op){
+ vpackuswb(x1, x2, op);
+ }
+
+
+ void mul_by_const(const Xbyak::Reg &out,
+ const Xbyak::Reg64 &tmp, int value) {
+ // Generates a shift + add sequence for multiplicating contents of the
+ // out register by a known JIT-time value. Clobbers the tmp register.
+ //
+ // Pros compared to mul/imul:
+ // - does not require using known registers
+ // - not microcoded on Intel(R) Xeon Phi(TM) processors
+ // Still, there are probably a lot of cases when mul/imul is faster on
+ // Intel(R) Core(TM) processors. Not intended for critical path.
+
+ // TODO: detect when overflow is emminent (Roma)
+ // TODO: detect when using mul/imul is a better option (Roma)
+
+ int p = 0; // the current power of 2
+ int old_p = 0; // the last seen power of 2 such that value[old_p] != 0
+
+ xor_(tmp, tmp);
+ while (value) {
+ if (value & 1) {
+ int shift = p - old_p;
+ if (shift) {
+ shl(out, shift);
+ old_p = p;
+ }
+ add(tmp, out);
+ }
+ value >>= 1;
+ p++;
+ }
+ mov(out, tmp);
+ }
+
+public:
+ jit_generator(
+ void *code_ptr = nullptr,
+ size_t code_size = 256 * 1024
+ ) : Xbyak::CodeGenerator(code_size, code_ptr)
+ {
+ }
+ virtual ~jit_generator() {}
+
+ virtual const char *name() const = 0;
+ virtual const char *source_file() const = 0;
+
+ const Xbyak::uint8 *getCode() {
+ const Xbyak::uint8 *code = CodeGenerator::getCode();
+ size_t code_size = getSize();
+ jit_utils::register_jit_code(code, code_size, name(), source_file());
+ return code;
+ }
+
+ template<typename F> const F getCode() {
+ return (const F)getCode();
+ }
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_primitive_conf.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_primitive_conf.hpp
new file mode 100644
index 0000000000..56d7f592e2
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_primitive_conf.hpp
@@ -0,0 +1,481 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_PRIMITIVE_CONF_HPP
+#define JIT_PRIMITIVE_CONF_HPP
+
+#include <stdint.h>
+
+#include "common/primitive_attr.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+/* convolution */
+enum conv_version_t {ver_unused, ver_fma, ver_avx512_core, ver_4fma, ver_vnni};
+enum conv_loop_order_t {loop_cgn, loop_gnc, loop_ngc, loop_gncw, loop_cwgn,
+ loop_ngcw, loop_nhwcg, loop_nwcg};
+enum conv_1x1_loop_order_t {loop_rbl, loop_rlb, loop_lbr, loop_lrb, loop_blr,
+ loop_brl};
+enum conv_kernel_kind_t {embd_bcast, expl_bcast};
+
+enum {
+ FLAG_MB_FIRST = 1 << 0, FLAG_MB_LAST = 1 << 1,
+ FLAG_OC_FIRST = 1 << 2, FLAG_OC_LAST = 1 << 3,
+ FLAG_IC_FIRST = 1 << 4, FLAG_IC_LAST = 1 << 5,
+ FLAG_SP_FIRST = 1 << 6, FLAG_SP_LAST = 1 << 7,
+ FLAG_REDUCE_FIRST = 1<<8, FLAG_REDUCE_LAST = 1<<9,
+ FLAG_ZERO_FILTER = 1 << 0, /* Controls whether the inner kernel skips
+ loading weights-data from memory; this
+ needs to happen on the first Group/16
+ iteration. */
+ FLAG_ZERO_BIAS = 1 << 1, /* Controls whether the inner kernel skip
+ loading bias data from memory */
+ FLAG_COMPUTE_BIAS = 1 << 2, /* Controls bias computation during execution
+ pass */
+};
+
+struct jit_conv_conf_t {
+ prop_kind_t prop_kind;
+ conv_version_t ver;
+ conv_loop_order_t loop_order;
+
+ int simd_w;
+ int ndims;
+ int mb;
+ int ngroups, ic, oc, oc_without_padding, ic_without_padding;
+ int id, ih, iw, od, oh, ow;
+ int f_pad, l_pad, t_pad;
+ int back_pad, r_pad, b_pad;
+ int kd, kh, kw;
+ int stride_d, stride_h, stride_w;
+ int dilate_d, dilate_h, dilate_w;
+ format_tag_t src_tag, wei_tag, dst_tag; // temporary workaround
+ bool with_bias;
+ bool with_sum;
+ bool with_eltwise;
+
+ post_ops_t::entry_t::eltwise_t eltwise;
+
+ int nthr, nthr_mb, nthr_g, nthr_oc_b, nthr_ic_b;
+
+ int idp, ihp, iwp, ohp, owp;
+ int nb_ic, ic_block;
+ int nb_oc, oc_block;
+ int nb_ow, ow_block;
+ int nb_oc_blocking; /* used in jit kernels for nb_oc work bloking taking
+ into account vector registers distribution */
+ int nb_oc_blocking_thr_chunk; /* used for distibution of nb_oc work
+ within threads */
+ int nb_ic_blocking, nb_ic_blocking_max; // blocking of nb_ic work
+ int nb_ic_L2;
+ int h_blocking;
+ int nb_oc_L2;
+ int ur_h, ur_w;
+ int ur_w_tail;
+ bool is_1stconv;
+ int nonblk_group_off;
+ /* fma avx512_core */
+ conv_kernel_kind_t kernel_kind;
+ /* 4fma */
+ int tr_iw;
+ int tr_src_num_guard_elems;
+ /* 1st conv: 4fma */
+ int tr_ld;
+ int kh_step;
+ /* 4vnni */
+ int typesize_in;
+ int typesize_out;
+ int typesize_bia;
+ int typesize_acc;
+ /* avx512_u8s8u8 */
+ int ic_nb1, ic_nb2;
+ int oc_nb1;
+ int ur_ow_max, ur_ow, ur_ow_tail;
+ int ur_ow_nsteps;
+ data_type_t bia_dt;
+ data_type_t dst_dt;
+ /* avx512: max possible value is nregs(32) - aux_regs(4) */
+ int src_offsets[28];
+ int src_count;
+ bool expl_bcast;
+ bool large_spatial;
+ int is_oc_scale;
+ int max_regs_ur; // maximum accumulation registers
+ // dw conv
+ int nb_ch, ch_block, nb_ch_blocking;
+ bool is_depthwise, is_fast_depthwise, is_resrc_depthwise;
+ int aligned_threads;
+ // large spatial
+ int oh_blk_size;
+ // s8s8 convolution
+ bool signed_input;
+ float wei_adj_scale;
+};
+
+struct jit_conv_conf_2x3_wino_t {
+ conv_version_t ver;
+
+ int m;
+ int r;
+ int alpha;
+ int tile_h, tile_w;
+
+ int mb;
+ int ngroups, ic, oc, oc_without_padding;
+ int ih, iw, oh, ow;
+ int l_pad, t_pad;
+ int r_pad, b_pad;
+ int kh, kw;
+ int stride_h, stride_w;
+ int dilate_h, dilate_w;
+
+ int nb_ic, ic_block;
+ int nb_oc, oc_block;
+
+ int w_block_size, h_block_size;
+
+ data_type_t bia_dt;
+ data_type_t dst_dt;
+
+ int is_oc_scale;
+ int typesize_in;
+ int typesize_out;
+ int typesize_bia;
+ int typesize_acc;
+
+ format_tag_t src_tag, dst_tag; // temporary workaround
+ bool with_bias;
+ bool small_mb;
+
+ int xb, yb;
+ int inp_stride;
+ int out_stride;
+ int wei_stride;
+ int bia_stride;
+
+ int M, N, K;
+ int m_block, n_block, k_block;
+ int n2_block, n_chunks;
+ int k2_block, k_chunks;
+
+ int mb_block, nb_mb;
+
+ size_t size_wino_src, size_wino_wei, size_wino_dst;
+
+ int nthr;
+};
+
+/*
+ Winograd sched policy:
+
+ Computation Unit:
+ W: weights transform
+ S: src transform
+ D: dst transform
+ G: gemm
+
+ Thread grouping by:
+ i: nb_ic
+ o: nb_oc
+ t: tile_block
+ e: element in tile
+
+ Note: 'i' and 'o' are omited if
+ i. not comblined with t or
+ ii. with discrete transforms
+
+ Current policies supported:
+*/
+enum winograd_sched_t {
+ WSCHED_INVALID = 0,
+
+ /* Forward & backward-data */
+ /* W_S_G_D implements discrete transforms */
+ WSCHED_DATA_W_S_G_D,
+ /* W_SGD implements tiled transforms s.t. GEMM could reuse data in L2*/
+ WSCHED_DATA_W_SGD,
+
+ /* Backward-weights */
+ WSCHED_WEI_S_D_G_W,
+ WSCHED_WEI_SDGtWo,
+ WSCHED_WEI_S_D_Giot_W,
+ WSCHED_WEI_SDGt_W,
+};
+
+struct jit_conv_winograd_conf_t : public jit_conv_conf_t {
+ int itiles;
+ int jtiles;
+ int ntiles;
+ int ic_simd_block=16;
+ int tile_4fma_padding;
+ int tile_4fma;
+ int oc_simd_block=16;
+ int oc_reg_block;
+ int ic_reg_block;
+ int tile_block;
+ int tile_block_ur;
+ int nb_tile_block_ur;
+
+ bool double_buffering;
+ bool with_relu_postsum;
+ int zmm_start;
+ int nb_reg;
+
+ int dimK;
+ int dimK_4fma;
+ int dimK_reg_block;
+ int dimK_block;
+ int dimK_nb_block;
+
+ int dimM;
+ int dimM_reg_block;
+ int dimM_simd_block;
+ int dimM_block;
+ int dimM_nb_block;
+
+ int dimN;
+ int dimN_reg_block;
+ int dimN_bcast_ur;
+ int dimN_block;
+ int dimN_nb_block;
+
+ winograd_sched_t sched_policy;
+};
+
+struct jit_conv_call_s {
+ const void *src; /* hack, non-const for backward_data */
+ const void *dst; /* hack, non-const for forward */
+ const void *filt; /* hack, non-const for backward_weights */
+ const void *bias; /* hack, non-const for backward_bias */
+ const void *src_prf;
+ const void *dst_prf;
+ const void *filt_prf;
+ const void *bias_prf;
+ const void *scales;
+ const void *acc_s32;
+ const void *compensation;
+ size_t kd_offset;
+ size_t kd_offset_prf;
+ size_t d_index;
+ size_t d_index_prf;
+ size_t d_worksize;
+ size_t d_worksize_prf;
+ size_t kd_padding;
+ size_t kd_padding_prf;
+ size_t kh_padding;
+ size_t kh_padding_prf;
+ size_t owb;
+ size_t owb_prf;
+ size_t kw_padding;
+ size_t channel;
+ size_t channel_prf;
+ size_t oc_blocks;
+ size_t ur_w;
+ size_t ur_str_w;
+ size_t ch_blocks;
+ size_t t_overflow;
+ size_t b_overflow;
+ int flags;
+};
+
+struct jit_deconv_call_s {
+ const void *src; /* hack, non-const for backward_data */
+ const void *dst; /* hack, non-const for forward */
+ const void *filt; /* hack, non-const for backward_weights */
+ const void *bias; /* hack, non-const for backward_bias */
+ const void *scales;
+ const void *compensation;
+ size_t t_overflow;
+ size_t b_overflow;
+ size_t kh_padding;
+ size_t oc_blocks;
+};
+
+struct jit_dw_conv_call_s {
+ const void *input;
+ const void *output;
+ const void *filter;
+ const void *bias;
+ size_t kh_count;
+ size_t oh_count;
+ size_t oh_index;
+ size_t filter_pad_off;
+ unsigned char
+ exec_flags; /* Flags passed by driver execution to inner kernel */
+};
+
+struct jit_wino_transform_call_s {
+ size_t tile_block;
+ size_t tile_block_ur;
+ size_t nb_tile_block_ur;
+ size_t tile_count;
+ size_t tj;
+ size_t ti;
+ void *src;
+ void *dst;
+ void *Mw;
+ void *M;
+ void *T;
+ void *G;
+ void *bias;
+};
+
+struct jit_1x1_conv_conf_t {
+ prop_kind_t prop_kind;
+ conv_version_t ver;
+
+ int mb;
+ int ngroups, ic, oc, oc_without_padding, ic_without_padding;
+ int iw, ih, ow, oh;
+ int l_pad, t_pad;
+ int kh, kw;
+ int stride_h, stride_w;
+ format_tag_t src_tag, wei_tag, dst_tag; // temporary workaround
+ bool with_bias;
+ bool with_sum;
+ bool with_eltwise;
+
+ post_ops_t::entry_t::eltwise_t eltwise;
+
+ int is, os;
+ int ic_block, oc_block;
+
+ int ur, ur_tail;
+
+ int reduce_dim, reduce_block, nb_reduce,
+ nb_reduce_blocking, nb_reduce_blocking_max;
+ int load_dim, load_block, nb_load,
+ nb_load_blocking, nb_load_blocking_max, nb_load_chunk;
+ int bcast_dim, bcast_block, nb_bcast,
+ nb_bcast_blocking, nb_bcast_blocking_max;
+
+ int reduce_loop_unroll, reduce_loop_bcast_step, reduce_loop_load_step;
+ int load_loop_load_step, load_loop_iter_step;
+ int bcast_loop_output_step, bcast_loop_output_substep;
+ int bcast_loop_bcast_step, bcast_loop_bcast_substep;
+ int fma_step;
+ int load_grp_count;
+ conv_1x1_loop_order_t loop_order;
+ bool use_vmovntps;
+ /* avx512 core */
+ bool expl_bcast;
+ /* 4vnni */
+ int typesize_in;
+ int typesize_out;
+ int typesize_bia;
+ int typesize_acc;
+ /* 4fma */
+ bool transpose_src;
+ int tr_is;
+ int nthr, nthr_mb, nthr_g, nthr_oc_b, nthr_ic_b;
+ int is_oc_scale;
+ data_type_t bia_dt;
+ data_type_t dst_dt;
+ bool signed_input;
+ float wei_adj_scale;
+};
+
+struct jit_gemm_conv_conf_t {
+ prop_kind_t prop_kind;
+
+ int mb;
+ int ngroups, ic, oc;
+ int iw, ih, id, ow, oh, od;
+ int l_pad, t_pad, f_pad;
+ int kh, kw, kd;
+ int stride_h, stride_w, stride_d;
+ int dilate_h, dilate_w, dilate_d;
+ bool with_bias;
+
+ int is, os, ks;
+ int ic_block, oc_block;
+
+ int nthr;
+ ptrdiff_t im2col_sz;
+ bool need_wei_reduction;
+ bool signed_input;
+ int oh_block;
+ int ow_block;
+ bool outer_threading;
+};
+
+struct jit_1x1_conv_call_s {
+ const void *bcast_data;
+ const void *load_data;
+ const void *output_data;
+ const void *bias_data; // used in forward and backward_weights only
+ const void *acc_s32;
+ const void *scales;
+ const void *compensation;
+
+ size_t load_dim;
+ size_t bcast_dim;
+ size_t reduce_dim;
+
+ size_t output_stride; // used in backward_weights only
+
+ size_t first_last_flag;
+};
+
+/* pooling */
+struct jit_pool_conf_t {
+ int ndims;
+ int mb, c;
+ int id, ih, iw, od, oh, ow;
+ int stride_d, stride_h, stride_w;
+ int kd, kh, kw;
+ int f_pad, t_pad, l_pad;
+ alg_kind_t alg;
+ bool is_training;
+ bool pad_w_is_null;
+ bool is_backward;
+ bool simple_alg;
+ data_type_t ind_dt;
+
+ int c_block, c_tail, nb_c;
+ int ur_c, ur_c_tail;
+ int ur_w;
+ int ur_w_tail;
+ size_t tail[4];
+ data_type_t src_dt;
+ data_type_t dst_dt;
+};
+
+struct jit_pool_call_s {
+ const float *src;
+ const float *dst;
+ const void *indices;
+ const float *src_prf;
+ const float *dst_prf;
+ const void *indices_prf;
+ size_t oh;
+ size_t kd_padding;
+ size_t kh_padding;
+ size_t kh_padding_shift;
+ size_t kd_padding_shift;
+ size_t kw_padding;
+ const float* init_value;
+ float ker_area_h;
+};
+
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_conv_kernel_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_conv_kernel_f32.cpp
new file mode 100644
index 0000000000..94d2101d6e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_conv_kernel_f32.cpp
@@ -0,0 +1,677 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+#include "cpu_memory.hpp"
+
+#include "jit_sse42_1x1_conv_kernel_f32.hpp"
+
+#define GET_OFF(field) offsetof(jit_1x1_conv_call_s, field)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::utils;
+
+using namespace Xbyak;
+
+void jit_sse42_1x1_conv_kernel_f32::generate_bcast_loop(int load_loop_blk)
+{
+ mov(aux1_reg_bcast_data, reg_bcast_data);
+ mov(aux_reg_output_data, reg_output_data);
+ mov(bcast_loop_iter, reg_bcast_loop_work);
+
+ Label bcast_loop;
+ Label bcast_loop_tail;
+
+ cmp(bcast_loop_iter, jcp.ur);
+ jl(bcast_loop_tail, T_NEAR);
+
+ L(bcast_loop); {
+ assert(jcp.bcast_block % jcp.ur == 0);
+ int num_substeps = jcp.bcast_block / jcp.ur;
+ assert(num_substeps > 0 && num_substeps < 10);
+ for (int i = 0; i < num_substeps; i++) {
+ generate_reduce_loop(load_loop_blk, jcp.ur);
+ if (i < num_substeps - 1) {
+ add(aux1_reg_bcast_data, jcp.bcast_loop_bcast_substep);
+ add(aux_reg_output_data, jcp.bcast_loop_output_substep);
+ } else {
+ add(aux1_reg_bcast_data, jcp.bcast_loop_bcast_step
+ - (num_substeps - 1) * jcp.bcast_loop_bcast_substep);
+ add(aux_reg_output_data, jcp.bcast_loop_output_step
+ - (num_substeps - 1) * jcp.bcast_loop_output_substep);
+ }
+ }
+ sub(bcast_loop_iter, jcp.bcast_block);
+ cmp(bcast_loop_iter, jcp.bcast_block);
+ jge(bcast_loop, T_NEAR);
+ }
+
+ L(bcast_loop_tail);
+ if (jcp.ur_tail) {
+ Label bcast_loop_tail_out;
+ cmp(bcast_loop_iter, 0);
+ jz(bcast_loop_tail_out, T_NEAR);
+ generate_reduce_loop(load_loop_blk, jcp.ur_tail);
+ L(bcast_loop_tail_out);
+ }
+}
+
+void jit_sse42_1x1_conv_kernel_f32::generate_reduce_loop(
+ int load_loop_blk, int ur)
+{
+ auto reg_load = [=](int i, int n) {
+ return Xmm(2*ur * load_loop_blk + 2*i + n + 1);
+ };
+
+ auto reg_accum = [=](int i, int j, int n) {
+ return Xmm(2*j * load_loop_blk + 2*i + n + 1);
+ };
+
+ auto bias_ptr = [=](int i, int n) {
+ return ptr[reg_bias_data + sizeof(float) * jcp.oc_block * i + n*4*sizeof(float)];
+ };
+
+ auto bcast_ptr = [=](int u, int j) {
+ assert(j < jcp.ur);
+ assert(u <= jcp.reduce_loop_unroll);
+ size_t offt;
+ if (one_of(jcp.prop_kind,
+ forward_training, forward_inference, backward_data)) {
+ assert(jcp.reduce_loop_unroll == (jcp.prop_kind == backward_data)
+ ? jcp.oc_block : jcp.ic_block);
+ auto height = (jcp.prop_kind == backward_data) ? jcp.os : jcp.is;
+ offt = (u == jcp.reduce_loop_unroll)
+ ? (height + j) * jcp.reduce_loop_unroll
+ : j * jcp.reduce_loop_unroll + u;
+ } else
+ offt = u * jcp.ic_block + j;
+ return ptr[aux_reg_bcast_data + sizeof(float) * offt];
+ };
+
+ auto load_ptr = [=](int u, int i, int n) {
+ size_t offt;
+ size_t u0 = u % jcp.reduce_loop_unroll;
+ size_t u1 = u / jcp.reduce_loop_unroll;
+ switch (jcp.prop_kind) {
+ case backward_data:
+ offt = (i * jcp.oc_block + u0) * jcp.ic_block;
+ break;
+ case backward_weights:
+ offt = (i * jcp.os + u0) * jcp.oc_block;
+ break;
+ default:
+ offt = (i * jcp.ic + u0) * jcp.oc_block;
+ }
+ return ptr[aux_reg_load_data
+ + u1 * jcp.reduce_loop_load_step + sizeof(float) * offt + n * 4 * sizeof(float)];
+ };
+
+ auto output_ptr = [=](int i, int j, int n) {
+ switch (jcp.prop_kind) {
+ case backward_data:
+ return ptr[aux_reg_output_data +
+ (i * jcp.is + j) * jcp.ic_block * sizeof(float) + n * 4 * sizeof(float)];
+ case backward_weights:
+ return ptr[aux_reg_output_data
+ + (i ? reg_output_stride * i : 0) // TODO: Xbyak should allow 0 scale
+ + sizeof(float) * jcp.oc_block * j + n * 4 * sizeof(float)];
+ default:
+ return ptr[aux_reg_output_data +
+ (i * jcp.os + j) * jcp.oc_block * sizeof(float) + n*4*sizeof(float)];
+ }
+ };
+
+ auto init = [=]() {
+ Label init_done;
+ Label init_zero;
+
+ if (jcp.with_bias && one_of(jcp.prop_kind, forward_training,
+ forward_inference)) {
+ test(reg_reduce_pos_flag, FLAG_REDUCE_FIRST);
+ jz(init_zero);
+
+ for (int i = 0; i < load_loop_blk; i++)
+ for (int j = 0; j < ur; ++j) {
+ movups(reg_accum(i, j, 0), bias_ptr(i, 0));
+ movups(reg_accum(i, j, 1), bias_ptr(i, 1));
+ }
+ jmp(init_done);
+ }
+
+ L(init_zero);
+ for (int i = 0; i < load_loop_blk; ++i)
+ for (int j = 0; j < ur; ++j) {
+ auto r0 = reg_accum(i, j, 0);
+ auto r1 = reg_accum(i, j, 1);
+ xorps(r0, r0);
+ xorps(r1, r1);
+ }
+
+ L(init_done);
+
+ // load weights
+ for (int i = 0; i < load_loop_blk; ++i) {
+ movups(reg_load(i, 0), load_ptr(0, i, 0));
+ movups(reg_load(i, 1), load_ptr(0, i, 1));
+ }
+
+ movss(reg_bcast, bcast_ptr(0, 0));
+ shufps(reg_bcast, reg_bcast, 0);
+ }; // init()
+
+ auto store = [=]() {
+ Label store_noadd;
+
+ if (!jcp.with_sum) {
+ test(reg_reduce_pos_flag, FLAG_REDUCE_FIRST);
+ jnz(store_noadd, T_NEAR);
+ }
+
+ for (int j = 0; j < ur; ++j)
+ for (int i = 0; i < load_loop_blk; ++i) {
+ auto r0 = reg_accum(i, j, 0);
+ auto r1 = reg_accum(i, j, 1);
+ addps(r0, output_ptr(i, j, 0));
+ addps(r1, output_ptr(i, j, 1));
+ }
+
+ L(store_noadd);
+
+ if (jcp.with_eltwise) {
+ assert(ur * load_loop_blk < 14);
+
+ Label store_norelu;
+ test(reg_reduce_pos_flag, FLAG_REDUCE_LAST);
+ jz(store_norelu, T_NEAR);
+
+ eltwise_injector_->compute_vector_range(1,
+ 2 * ur * load_loop_blk + 1);
+
+ L(store_norelu);
+ }
+
+ for (int j = 0; j < ur; ++j)
+ for (int i = 0; i < load_loop_blk; ++i) {
+ movups(output_ptr(i, j, 0), reg_accum(i, j, 0));
+ movups(output_ptr(i, j, 1), reg_accum(i, j, 1));
+ }
+ };
+
+ auto fma_block = [=](bool last_block) {
+ for (int u = 0; u < jcp.reduce_loop_unroll; ++u) {
+ for (int j = 0; j < ur; ++j) {
+ for (int i = 0; i < load_loop_blk; ++i) {
+ mulps(reg_load(i, 0), reg_bcast);
+ mulps(reg_load(i, 1), reg_bcast);
+ addps(reg_accum(i, j, 0), reg_load(i, 0));
+ addps(reg_accum(i, j, 1), reg_load(i, 1));
+
+ if (j == ur - 1 && !(last_block && u == jcp.reduce_loop_unroll - 1)) {
+ movups(reg_load(i, 0), load_ptr(u + 1, i, 0));
+ movups(reg_load(i, 1), load_ptr(u + 1, i, 1));
+ }
+ }
+ if (j < ur - 1) {
+ movss(reg_bcast, bcast_ptr(u, j + 1));
+ shufps(reg_bcast, reg_bcast, 0);
+ }
+ } // for ur
+ if (!last_block || u < jcp.reduce_loop_unroll - 1) {
+ movss(reg_bcast, bcast_ptr(u + 1, 0));
+ shufps(reg_bcast, reg_bcast, 0);
+ }
+ } // for reduce_loop_unroll
+ };
+
+ Label reduce_loop;
+ Label reduce_loop_tail;
+
+ mov(aux_reg_load_data, reg_load_data);
+ mov(aux_reg_bcast_data, aux1_reg_bcast_data);
+
+ init();
+
+ mov(reduce_loop_iter, reg_reduce_loop_work);
+ sub(reduce_loop_iter, jcp.reduce_loop_unroll);
+ jle(reduce_loop_tail, T_NEAR);
+
+ L(reduce_loop); {
+ fma_block(false);
+ add(aux_reg_bcast_data, jcp.reduce_loop_bcast_step);
+ add(aux_reg_load_data, jcp.reduce_loop_load_step);
+ sub(reduce_loop_iter, jcp.reduce_loop_unroll);
+ jg(reduce_loop, T_NEAR);
+ }
+
+ L(reduce_loop_tail);
+ fma_block(true);
+
+ store();
+} // reduce_loop()
+
+void jit_sse42_1x1_conv_kernel_f32::generate_diff_bias_loop(int load_loop_blk)
+{
+ if (!jcp.with_bias || jcp.prop_kind != backward_weights)
+ return;
+
+ Label diff_bias_loop, diff_bias_loop_out, diff_bias_init_out;
+ Label diff_bias_load;
+
+ auto diff_bias_ptr = [=](int i, int n) {
+ return ptr[reg_diff_bias_data + i * jcp.oc_block * sizeof(float)+ 4*n*sizeof(float)];
+ };
+
+ auto load_ptr = [=](int u, int i, int n) {
+ return ptr[aux_reg_load_data
+ + (i * jcp.os + u) * jcp.oc_block * sizeof(float) + 4*n*sizeof(float)];
+ };
+
+ auto diff_bias_reg = [=](int i, int n) { return Xmm(2*i + n + 1); };
+
+ mov(reg_diff_bias_data, ptr[rsp + reg_diff_bias_data_stack_offt]);
+ cmp(reg_diff_bias_data, 0);
+ je(diff_bias_loop_out, T_NEAR);
+
+ test(reg_reduce_pos_flag, FLAG_REDUCE_FIRST);
+ jz(diff_bias_load, T_NEAR);
+
+ for (int i = 0; i < load_loop_blk; ++i) {
+ auto r0 = diff_bias_reg(i, 0);
+ auto r1 = diff_bias_reg(i, 1);
+ xorps(r0, r0);
+ xorps(r1, r1);
+ }
+ jmp(diff_bias_init_out, T_NEAR);
+
+ L(diff_bias_load);
+ for (int i = 0; i < load_loop_blk; ++i) {
+ movups(diff_bias_reg(i, 0), diff_bias_ptr(i, 0));
+ movups(diff_bias_reg(i, 1), diff_bias_ptr(i, 1));
+ }
+
+ L(diff_bias_init_out);
+ mov(aux_reg_load_data, reg_load_data);
+ mov(reduce_loop_iter, reg_reduce_loop_work);
+ L(diff_bias_loop); {
+ for(int u = 0; u < jcp.reduce_loop_unroll; ++u)
+ for (int i = 0; i < load_loop_blk; ++i) {
+ addps(diff_bias_reg(i, 0), load_ptr(u, i, 0));
+ addps(diff_bias_reg(i, 1), load_ptr(u, i, 1));
+ }
+ assert(jcp.reduce_dim % jcp.reduce_loop_unroll == 0);
+ add(aux_reg_load_data, jcp.reduce_loop_load_step);
+ sub(reduce_loop_iter, jcp.reduce_loop_unroll);
+ jnz(diff_bias_loop, T_NEAR);
+ }
+
+ for (int i = 0; i < load_loop_blk; i++) {
+ movups(diff_bias_ptr(i, 0), diff_bias_reg(i, 0));
+ movups(diff_bias_ptr(i, 1), diff_bias_reg(i, 1));
+ }
+
+ add(reg_diff_bias_data, load_loop_blk * jcp.oc_block * sizeof(float));
+ mov(ptr[rsp + reg_diff_bias_data_stack_offt], reg_diff_bias_data);
+
+ L(diff_bias_loop_out);
+}
+
+void jit_sse42_1x1_conv_kernel_f32::generate()
+{
+ preamble();
+
+ mov(reg_bcast_data, ptr[param1 + GET_OFF(bcast_data)]);
+ mov(reg_load_data, ptr[param1 + GET_OFF(load_data)]);
+ mov(reg_output_data, ptr[param1 + GET_OFF(output_data)]);
+ if (jcp.with_bias) {
+ if (jcp.prop_kind == backward_weights) {
+ sub(rsp, stack_space_needed);
+ mov(reg_diff_bias_data, ptr[param1 + GET_OFF(bias_data)]);
+ mov(ptr[rsp + reg_diff_bias_data_stack_offt], reg_diff_bias_data);
+ } else
+ mov(reg_bias_data, ptr[param1 + GET_OFF(bias_data)]);
+ }
+
+ mov(reg_load_loop_work, ptr[param1 + GET_OFF(load_dim)]);
+ mov(reg_bcast_loop_work, ptr[param1 + GET_OFF(bcast_dim)]);
+ mov(reg_reduce_loop_work, ptr[param1 + GET_OFF(reduce_dim)]);
+ mov(reg_reduce_pos_flag, ptr[param1 + GET_OFF(first_last_flag)]);
+ if (jcp.prop_kind == backward_weights)
+ mov(reg_output_stride, ptr[param1 + GET_OFF(output_stride)]);
+
+ auto generate_load_loop_body = [=] (int load_loop_blk) {
+ generate_bcast_loop(load_loop_blk);
+ add(reg_load_data, load_loop_blk * jcp.load_loop_load_step);
+ switch (jcp.prop_kind) {
+ case forward_training:
+ case forward_inference:
+ add(reg_bias_data, load_loop_blk * jcp.oc_block * sizeof(float));
+ add(reg_output_data,
+ load_loop_blk * jcp.os * jcp.oc_block * sizeof(float));
+ break;
+ case backward_data:
+ add(reg_output_data,
+ load_loop_blk * jcp.is * jcp.ic_block * sizeof(float));
+ break;
+ case backward_weights:
+ for (int i = 0; i < load_loop_blk; i++)
+ add(reg_output_data, reg_output_stride);
+ break;
+ default:
+ assert(!"invalid prop_kind");
+ }
+ sub(reg_load_loop_work, load_loop_blk * jcp.load_loop_iter_step);
+ };
+
+ Label load_loop_blk_8;
+ Label load_loop_blk_16;
+ Label load_loop_blk_24;
+ Label load_loop_blk_end;
+
+ cmp(reg_load_loop_work, 8);
+ jle(load_loop_blk_8, T_NEAR);
+
+ cmp(reg_load_loop_work, 32);
+ je(load_loop_blk_16, T_NEAR);
+
+ cmp(reg_load_loop_work, 16);
+ jle(load_loop_blk_16, T_NEAR);
+
+ L(load_loop_blk_24); {
+ generate_diff_bias_loop(3);
+ generate_load_loop_body(3);
+ cmp(reg_load_loop_work, 32);
+ je(load_loop_blk_16);
+ cmp(reg_load_loop_work, 24);
+ jge(load_loop_blk_24);
+ }
+
+ cmp(reg_load_loop_work, 8);
+ jle(load_loop_blk_8, T_NEAR);
+
+ L(load_loop_blk_16); {
+ generate_diff_bias_loop(2);
+ generate_load_loop_body(2);
+ cmp(reg_load_loop_work, 16);
+ jge(load_loop_blk_16);
+ }
+
+ L(load_loop_blk_8); {
+ cmp(reg_load_loop_work, 0);
+ je(load_loop_blk_end, T_NEAR);
+ generate_diff_bias_loop(1);
+ generate_load_loop_body(1);
+ }
+
+ L(load_loop_blk_end);
+
+ if (jcp.with_bias && jcp.prop_kind == backward_weights)
+ add(rsp, stack_space_needed);
+
+ postamble();
+
+ if (jcp.with_eltwise)
+ eltwise_injector_->prepare_table();
+}
+
+bool jit_sse42_1x1_conv_kernel_f32::post_ops_ok(
+ jit_1x1_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ const auto &p = attr.post_ops_;
+
+ auto is_eltwise = [&](int idx) { return p.entry_[idx].is_eltwise(); };
+ auto is_sum = [&](int idx) { return p.entry_[idx].is_sum(); };
+
+ switch (p.len_) {
+ case 0: return true; // no post_ops
+ case 1: return is_eltwise(0) || is_sum(0); // sum OR eltwise
+ case 2: return is_sum(0) && is_eltwise(1); // sum -> eltwise
+ default: return false;
+ }
+
+ return false;
+}
+
+status_t jit_sse42_1x1_conv_kernel_f32::init_conf(jit_1x1_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d, const memory_desc_wrapper &dst_d,
+ const primitive_attr_t &attr)
+{
+ if (!mayiuse(sse42))
+ return status::unimplemented;
+
+ // TODO (Roma): this code is duplicated from the generic kernel; maybe the
+ // configuration struct could do some stuff below
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+ const int ndims = src_d.ndims();
+
+ jcp.prop_kind = cd.prop_kind;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+
+ jcp.ih = (ndims == 3) ? 1 : src_d.dims()[2];
+ jcp.iw = src_d.dims()[ndims - 1];
+ jcp.oh = (ndims == 3) ? 1 : dst_d.dims()[2];
+ jcp.ow = dst_d.dims()[ndims - 1];
+
+ jcp.kh = (ndims == 3) ? 1 : weights_d.dims()[with_groups + 2];
+ jcp.kw = weights_d.dims()[with_groups + ndims - 1];
+
+ jcp.t_pad = (ndims == 3) ? 0 : cd.padding[0][0];
+ jcp.l_pad = cd.padding[0][ndims - 3];
+
+ jcp.stride_h = (ndims == 3) ? 1 : cd.strides[0];
+ jcp.stride_w = cd.strides[ndims - 3];
+
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+
+ jcp.os = jcp.oh * jcp.ow;
+ jcp.is = jcp.ih * jcp.iw;
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ jcp.with_sum = p.find(primitive_kind::sum) != -1;
+ const int eltwise_ind = p.find(primitive_kind::eltwise);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise)
+ jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+
+ const int is_bwd_d = jcp.prop_kind == backward_data;
+
+ format_tag_t dat_tag = ndims == 3 ? nCw8c : nChw8c;
+ format_tag_t wei_tag = with_groups
+ ? utils::pick(2 * ndims - 6 + is_bwd_d, gOIw8i8o, gOIw8o8i, gOIhw8i8o,
+ gOIhw8o8i)
+ : utils::pick(2 * ndims - 6 + is_bwd_d, OIw8i8o, OIw8o8i, OIhw8i8o,
+ OIhw8o8i);
+
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ jcp.wei_tag = weights_d.matches_one_of_tag(wei_tag);
+ jcp.dst_tag = dst_d.matches_one_of_tag(dat_tag);
+
+ bool args_ok = true
+ && jcp.ngroups == 1
+ && jcp.src_tag == dat_tag
+ && jcp.wei_tag == wei_tag
+ && jcp.dst_tag == dat_tag;
+ if (!args_ok) return status::unimplemented;
+
+ const int simd_w = 4;
+ jcp.ic_block = jcp.oc_block = simd_w*2;
+
+ args_ok = true
+ && jcp.oc % jcp.oc_block == 0
+ && jcp.ic % jcp.ic_block == 0
+ && jcp.t_pad == 0 && jcp.l_pad == 0
+ && jcp.stride_w == 1 && jcp.stride_h == 1 // TODO: support some strides
+ && jcp.kh == 1 && jcp.kw == 1;
+ if (!args_ok) return status::unimplemented;
+
+ jcp.ur = 1;
+
+ int load_blocking{ 0 };
+ int load_blocking_max{ 0 };
+ int bcast_blocking{ 0 };
+ int bcast_blocking_max{ 0 };
+ int reduce_blocking{ 0 };
+
+ if (one_of(jcp.prop_kind, forward_training, forward_inference)) {
+ jcp.reduce_dim = jcp.ic;
+ jcp.reduce_block = jcp.ic_block;
+
+ jcp.load_dim = jcp.oc;
+ jcp.load_block = jcp.oc_block;
+
+ jcp.bcast_dim = jcp.is;
+ jcp.bcast_block = jcp.ur;
+
+ jcp.reduce_loop_unroll = jcp.reduce_block;
+ jcp.reduce_loop_bcast_step
+ = jcp.reduce_loop_unroll * jcp.is * sizeof(float);
+ jcp.reduce_loop_load_step
+ = jcp.reduce_loop_unroll * jcp.oc_block * sizeof(float);
+
+ jcp.bcast_loop_output_step = jcp.ur * jcp.oc_block * sizeof(float);
+ jcp.bcast_loop_output_substep = -1; // unused
+ jcp.bcast_loop_bcast_step = jcp.ur * jcp.ic_block * sizeof(float);
+ jcp.bcast_loop_bcast_substep = -1; // unused
+
+ jcp.load_loop_load_step = jcp.ic * jcp.oc_block * sizeof(float);
+ jcp.load_loop_iter_step = jcp.oc_block;
+
+ load_blocking = 120; // assumes the kernel is jcp.ur x 3
+ load_blocking_max = 144;
+ bcast_blocking = 128; // affects load balancing across threads
+ bcast_blocking_max = 192;
+ reduce_blocking = 128; // affects L1$ utilization
+ } else if (jcp.prop_kind == backward_data) {
+ jcp.reduce_dim = jcp.oc;
+ jcp.reduce_block = jcp.oc_block;
+
+ jcp.load_dim = jcp.ic;
+ jcp.load_block = jcp.oc_block;
+
+ jcp.bcast_dim = jcp.os;
+ jcp.bcast_block = jcp.ur;
+
+ jcp.reduce_loop_unroll = jcp.reduce_block;
+ jcp.reduce_loop_bcast_step
+ = jcp.reduce_loop_unroll * jcp.os * sizeof(float);
+ jcp.reduce_loop_load_step
+ = jcp.reduce_loop_unroll * jcp.ic * sizeof(float);
+
+ jcp.bcast_loop_output_step = jcp.ur * jcp.ic_block * sizeof(float);
+ jcp.bcast_loop_output_substep = -1; // unused
+ jcp.bcast_loop_bcast_step = jcp.ur * jcp.oc_block * sizeof(float);
+ jcp.bcast_loop_bcast_substep = -1; // unused
+
+ jcp.load_loop_load_step = jcp.oc_block * jcp.ic_block * sizeof(float);
+ jcp.load_loop_iter_step = jcp.ic_block;
+
+ load_blocking = 96; // assumes the kernel is jcp.ur x 3
+ load_blocking_max = 144;
+ bcast_blocking = 128; // affects load balancing across threads
+ bcast_blocking_max = 196;
+ reduce_blocking = 64; // affects L1$ utilization
+ } else if (jcp.prop_kind == backward_weights) {
+ jcp.reduce_dim = jcp.os;
+ jcp.reduce_block = 1;
+
+ jcp.load_dim = jcp.oc;
+ jcp.load_block = jcp.oc_block;
+
+ jcp.bcast_dim = jcp.ic;
+ jcp.bcast_block = jcp.ic_block;
+
+ jcp.reduce_loop_unroll = jcp.reduce_block;
+ jcp.reduce_loop_bcast_step
+ = jcp.reduce_loop_unroll * jcp.ic_block * sizeof(float);
+ jcp.reduce_loop_load_step
+ = jcp.reduce_loop_unroll * jcp.oc_block * sizeof(float);
+
+ jcp.bcast_loop_output_step = jcp.oc_block * jcp.ic_block * sizeof(float);
+ jcp.bcast_loop_output_substep = jcp.oc_block * jcp.ur * sizeof(float);
+ jcp.bcast_loop_bcast_step = jcp.ic_block * jcp.is * sizeof(float);
+ jcp.bcast_loop_bcast_substep = jcp.ur * sizeof(float);
+
+ jcp.load_loop_load_step = jcp.oc_block * jcp.os * sizeof(float);
+ jcp.load_loop_iter_step = jcp.oc_block;
+
+ /* --- */
+
+ load_blocking = div_up(jcp.load_dim, jcp.load_block);
+ while (true) {
+ if (load_blocking <= 32) break;
+ else if (load_blocking % 2 == 0) load_blocking /= 2;
+ else if (load_blocking % 3 == 0) load_blocking /= 3;
+ else break;
+ }
+ load_blocking *= jcp.load_block;
+ load_blocking_max = load_blocking;
+ assert(jcp.load_dim % load_blocking == 0);
+
+ bcast_blocking = div_up(jcp.bcast_dim, jcp.bcast_block);
+ while (true) {
+ if (bcast_blocking <= 9) break;
+ else if (bcast_blocking % 2 == 0) bcast_blocking /= 2;
+ else if (bcast_blocking % 3 == 0) bcast_blocking /= 3;
+ else break;
+ }
+ bcast_blocking *= jcp.bcast_block;
+ bcast_blocking_max = bcast_blocking;
+ assert(jcp.bcast_dim % bcast_blocking == 0);
+
+ reduce_blocking = 128; // affects L1$ utilization
+ } else
+ return status::unimplemented;
+
+ assert(load_blocking);
+ assert(load_blocking_max);
+ assert(bcast_blocking);
+ assert(bcast_blocking_max);
+ assert(reduce_blocking);
+
+ assert(jcp.bcast_block % jcp.ur == 0);
+ jcp.ur_tail = jcp.bcast_dim % jcp.ur;
+
+ jcp.nb_bcast_blocking = bcast_blocking / jcp.bcast_block;
+ jcp.nb_bcast_blocking_max = bcast_blocking_max / jcp.bcast_block;
+ jcp.nb_load_blocking = load_blocking / jcp.load_block;
+ jcp.nb_load_blocking_max = load_blocking_max / jcp.load_block;
+ jcp.nb_reduce_blocking = reduce_blocking / jcp.reduce_block;
+
+ jcp.nb_bcast = div_up(jcp.bcast_dim, jcp.bcast_block);
+ jcp.nb_load = div_up(jcp.load_dim, jcp.load_block);
+ jcp.nb_reduce = div_up(jcp.reduce_dim, jcp.reduce_block);
+
+ return status::success;
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_conv_kernel_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_conv_kernel_f32.hpp
new file mode 100644
index 0000000000..b314a5098c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_conv_kernel_f32.hpp
@@ -0,0 +1,104 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_SSE42_1x1_CONV_KERNEL_F32_HPP
+#define JIT_SSE42_1x1_CONV_KERNEL_F32_HPP
+
+#include "c_types_map.hpp"
+#include "cpu_memory.hpp"
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+#include "jit_uni_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_sse42_1x1_conv_kernel_f32: public jit_generator {
+ jit_sse42_1x1_conv_kernel_f32(jit_1x1_conv_conf_t ajcp,
+ const primitive_attr_t &attr)
+ : jcp(ajcp), attr_(attr), eltwise_injector_(nullptr)
+ {
+ if (jcp.with_eltwise)
+ eltwise_injector_ = new jit_uni_eltwise_injector_f32<sse42>(this,
+ jcp.eltwise);
+
+ this->generate();
+ jit_ker = (void (*)(jit_1x1_conv_call_s *))this->getCode();
+ }
+
+ ~jit_sse42_1x1_conv_kernel_f32() {
+ delete eltwise_injector_;
+ }
+
+ static bool post_ops_ok(jit_1x1_conv_conf_t &jcp,
+ const primitive_attr_t &attr);
+
+ static status_t init_conf(jit_1x1_conv_conf_t &jcp,
+ const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d,
+ const primitive_attr_t &attr);
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_sse42_1x1_conv_kernel_f32)
+
+ jit_1x1_conv_conf_t jcp;
+ const primitive_attr_t &attr_;
+ void (*jit_ker)(jit_1x1_conv_call_s *);
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ using xmm_t = const Xbyak::Xmm;
+
+ reg64_t reg_bcast_data = rax;
+ reg64_t reg_load_data = rsi;
+ reg64_t reg_output_data = rbx;
+ reg64_t aux_reg_bcast_data = rdx;
+ reg64_t aux1_reg_bcast_data = abi_not_param1;
+ reg64_t aux_reg_load_data = abi_param1;
+ reg64_t aux_reg_output_data = rbp;
+ reg64_t reg_load_loop_work = r9;
+ reg64_t reg_bcast_loop_work = r10;
+ reg64_t reg_reduce_loop_work = r11;
+ reg64_t load_loop_iter = r13;
+ reg64_t imm_addr64 = load_loop_iter;
+ reg64_t bcast_loop_iter = r14;
+ reg64_t reduce_loop_iter = r15;
+ reg64_t reg_reduce_pos_flag = r8;
+ reg64_t reg_output_stride = r12;
+ reg64_t reg_bias_data = r12;
+ reg64_t reg_diff_bias_data = bcast_loop_iter;
+
+ int reg_diff_bias_data_stack_offt = 0;
+ int stack_space_needed = 8;
+
+ xmm_t reg_bcast = xmm_t(15);
+
+ jit_uni_eltwise_injector_f32<sse42> *eltwise_injector_;
+
+ void generate_bcast_loop(int load_loop_blk);
+ void generate_reduce_loop(int load_loop_blk, int ur);
+ void generate_diff_bias_loop(int load_loop_blk);
+
+ void generate();
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_convolution.cpp
new file mode 100644
index 0000000000..30c137641e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_convolution.cpp
@@ -0,0 +1,134 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn_types.h"
+
+#include "c_types_map.hpp"
+#include "jit_sse42_1x1_convolution.hpp"
+#include "utils.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+#define data_blk_off(f, n, c, h, w) \
+ ((ndims == 3) \
+ ? (f).blk_off(n, c, w) \
+ : (f).blk_off(n, c, h, w))
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::utils;
+
+void jit_sse42_1x1_convolution_fwd_t::execute_forward(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+ const int ndims = src_d.ndims();
+
+ const int work_amount = jcp.mb * jcp.ngroups * jcp.nb_bcast;
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ // TODO (Roma): remove this restriction
+ assert(jcp.stride_w == 1 && jcp.stride_h == 1);
+
+ auto par_conv = jit_1x1_conv_call_s();
+
+ const int nb_oc = jcp.nb_load;
+ const int nb_ic = jcp.nb_reduce;
+ const int nb_ic_blocking = jcp.nb_reduce_blocking;
+ const int os_block = jcp.bcast_block;
+
+ int start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+
+ int iwork = start;
+ while (iwork < end) {
+ int n{0}, g{0}, osb{0};
+ nd_iterator_init(iwork, n, jcp.mb, g, jcp.ngroups, osb,
+ jcp.nb_bcast);
+
+ const int bcast_step_rem = jcp.nb_bcast - osb;
+ int bcast_step = bcast_step_rem <= jcp.nb_bcast_blocking_max
+ ? bcast_step_rem : jcp.nb_bcast_blocking;
+ bcast_step = nstl::min<int>(bcast_step, end - iwork);
+
+ const int os = osb * os_block;
+ const int ow = os % jcp.ow;
+ const int oh = os / jcp.ow;
+ const int iw = nstl::max<int>(ow * jcp.stride_w - jcp.l_pad, 0);
+ const int ih = nstl::max<int>(oh * jcp.stride_h - jcp.t_pad, 0);
+
+ par_conv.bcast_dim = this_block_size(os, jcp.os,
+ bcast_step * os_block);
+
+ int ocb = 0;
+ while (ocb < jcp.nb_load) {
+ const int load_step_rem = jcp.nb_load - ocb;
+ const int load_step = load_step_rem < jcp.nb_load_blocking_max
+ ? load_step_rem : jcp.nb_load_blocking;
+
+ const size_t _ocb = g * nb_oc + ocb;
+ par_conv.load_dim = this_block_size(ocb * jcp.oc_block, jcp.oc,
+ load_step * jcp.oc_block);
+
+ const size_t dst_off = data_blk_off(dst_d, n, _ocb, oh, ow);
+ par_conv.output_data = &dst[dst_off];
+
+ par_conv.bias_data = &bias[_ocb * jcp.oc_block];
+
+ for (int icb = 0; icb < nb_ic; icb += nb_ic_blocking) {
+ par_conv.first_last_flag = 0
+ | (icb == 0) * FLAG_REDUCE_FIRST
+ | (icb + nb_ic_blocking >= nb_ic) * FLAG_REDUCE_LAST;
+
+ par_conv.reduce_dim = this_block_size(icb * jcp.ic_block,
+ jcp.ic, nb_ic_blocking * jcp.ic_block);
+
+ const size_t _icb = g * nb_ic + icb;
+ const size_t src_off = data_blk_off(src_d, n, _icb, ih, iw);
+ par_conv.bcast_data = &src[src_off];
+
+ par_conv.load_data = &weights[pd()->with_groups()
+ ? weights_d.blk_off(g, ocb, icb)
+ : weights_d.blk_off(ocb, icb)];
+
+ kernel_->jit_ker(&par_conv);
+ }
+
+ ocb += load_step;
+ }
+
+ iwork += bcast_step;
+ }
+ });
+
+ if (pd()->wants_zero_pad_dst())
+ ctx.memory(MKLDNN_ARG_DST)->zero_pad();
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_convolution.hpp
new file mode 100644
index 0000000000..b32b1e4784
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_1x1_convolution.hpp
@@ -0,0 +1,96 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_SSE42_1x1_CONVOLUTION_HPP
+#define CPU_JIT_SSE42_1x1_CONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+#include "jit_sse42_1x1_conv_kernel_f32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_sse42_1x1_convolution_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_1x1:", sse42, ""),
+ jit_sse42_1x1_convolution_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ return jit_sse42_1x1_conv_kernel_f32::init_conf(jcp_, *desc(),
+ *src_md(), *weights_md(), *dst_md(), *attr());
+ }
+
+ jit_1x1_conv_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c);
+ auto wei_tag = with_groups()
+ ? utils::pick(ndims() - 3, gOIw8i8o, gOIhw8i8o)
+ : utils::pick(ndims() - 3, OIw8i8o, OIhw8i8o);
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ jit_sse42_1x1_convolution_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {
+ kernel_ = new jit_sse42_1x1_conv_kernel_f32(pd()->jcp_, *pd()->attr());
+ }
+ ~jit_sse42_1x1_convolution_fwd_t() { delete kernel_; };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ jit_sse42_1x1_conv_kernel_f32 *kernel_;
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_conv_kernel_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_conv_kernel_f32.cpp
new file mode 100644
index 0000000000..17cabc1186
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_conv_kernel_f32.cpp
@@ -0,0 +1,497 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "cpu_memory.hpp"
+
+#include "jit_sse42_conv_kernel_f32.hpp"
+
+#define GET_OFF(field) offsetof(jit_conv_call_s, field)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::utils;
+
+using namespace Xbyak;
+
+void jit_sse42_conv_fwd_kernel_f32::oh_step_unroll_kw(int ur_w,
+ int pad_l, int pad_r, int oc_blocks)
+{
+ int iw = jcp.iw;
+ int ih = jcp.ih;
+ int kw = jcp.kw;
+ int kh = jcp.kh;
+ int nb_ic = jcp.nb_ic;
+ int stride_w = jcp.stride_w;
+ int dilate_w = jcp.dilate_w + 1;
+ int ic_blk = jcp.ic_block;
+ int oc_blk = jcp.oc_block;
+
+ for (int ki = 0; ki < kw; ki++) {
+ int jj_start = nstl::max(0, div_up(pad_l - ki * dilate_w, stride_w));
+ int jj_end = ur_w
+ - nstl::max(0, div_up(ki*dilate_w + pad_r - (kw-1)*dilate_w, stride_w));
+ for (int ifm2 = 0; ifm2 < ic_blk; ifm2++) {
+ for (int jj = jj_start; jj < jj_end; jj++) {
+ int inp_off;
+ if (one_of(jcp.src_tag, ncw, nchw))
+ inp_off = ifm2*ih*iw + (ki*dilate_w + jj*stride_w - pad_l);
+ else
+ inp_off = (ki*dilate_w + jj*stride_w - pad_l)*ic_blk + ifm2;
+
+ movss(Xmm(oc_blocks * ur_w + jj + 1),
+ ptr[aux_reg_input + sizeof(float) * inp_off]);
+ shufps(Xmm(oc_blocks * ur_w + jj + 1),
+ Xmm(oc_blocks * ur_w + jj + 1), 0x0);
+ }
+
+ for (int ii = 0; ii < oc_blocks; ii++) {
+ int ker_off = ii * nb_ic * kh * kw * ic_blk * oc_blk
+ + ki * ic_blk * oc_blk + ifm2 * oc_blk;
+
+ for (int jj = jj_start; jj < jj_end; jj++)
+ {
+ movups(xmm0,
+ ptr[aux_reg_kernel + sizeof(float) * ker_off]);
+ mulps(xmm0, Xmm(oc_blocks * ur_w + jj + 1));
+ addps(Xmm(ur_w * ii + jj + 1), xmm0);
+ }
+ }
+ }
+ }
+}
+
+void jit_sse42_conv_fwd_kernel_f32::oh_step_nopad(int ur_w,
+ int pad_l, int pad_r, int oc_blocks)
+{
+ Label kw_loop;
+
+ int iw = jcp.iw;
+ int ih = jcp.ih;
+ int kw = jcp.kw;
+ int kh = jcp.kh;
+ int nb_ic = jcp.nb_ic;
+ int stride_w = jcp.stride_w;
+ int dilate_w = jcp.dilate_w + 1;
+ int ic_blk = jcp.ic_block;
+ int oc_blk = jcp.oc_block;
+
+ xor_(ki_iter, ki_iter);
+ L(kw_loop);
+ {
+ int jj_start = 0;
+ int jj_end = ur_w;
+ for (int ifm2 = 0; ifm2 < ic_blk; ifm2++) {
+ for (int jj = jj_start; jj < jj_end; jj++) {
+ int inp_off;
+ if (one_of(jcp.src_tag, ncw, nchw))
+ inp_off = ifm2 * ih * iw + (jj * stride_w - pad_l);
+ else
+ inp_off = (jj * stride_w - pad_l) * ic_blk + ifm2;
+
+ movss(Xmm(oc_blocks * ur_w + jj + 1),
+ ptr[aux_reg_input + sizeof(float) * inp_off]);
+ shufps(Xmm(oc_blocks * ur_w + jj + 1),
+ Xmm(oc_blocks * ur_w + jj + 1), 0x0);
+ }
+ for (int ii = 0; ii < oc_blocks; ii++) {
+ int aux_kernel_offset = ii * nb_ic * kh * kw * ic_blk * oc_blk
+ + ifm2 * oc_blk;
+ for (int jj = jj_start; jj < jj_end; jj++) {
+ movups(xmm0,
+ ptr[aux_reg_kernel + sizeof(float) * aux_kernel_offset]);
+ mulps(xmm0, Xmm(oc_blocks * ur_w + jj + 1));
+ addps(Xmm(ur_w * ii + jj + 1), xmm0);
+ }
+ }
+ }
+ add(aux_reg_kernel, sizeof(float) * oc_blk * ic_blk);
+ add(aux_reg_input, sizeof(float) * (one_of(jcp.src_tag, ncw, nchw) ?
+ dilate_w : ic_blk * dilate_w));
+
+ inc(ki_iter);
+ cmp(ki_iter, kw);
+ jl(kw_loop, T_NEAR);
+ }
+}
+
+void jit_sse42_conv_fwd_kernel_f32::width_blk_step(int ur_w,
+ int pad_l, int pad_r, int oc_blocks)
+{
+ int iw = jcp.iw;
+ int kw = jcp.kw;
+ int ow = jcp.ow;
+ int oh = jcp.oh;
+ int dilate_h = jcp.dilate_h + 1;
+ int dilate_w = jcp.dilate_w + 1;
+ int ic_blk = jcp.ic_block;
+ int oc_blk = jcp.oc_block;
+ const int inp_mult = one_of(jcp.src_tag, ncw, nchw)
+ ? dilate_h : ic_blk * dilate_h;
+ const int inp_off = one_of(jcp.src_tag, ncw, nchw)
+ ? dilate_w : ic_blk * dilate_w;
+
+ xor_(simd_iter, simd_iter);
+
+ mov(aux_reg_input, reg_input);
+ mov(aux_reg_kernel, reg_kernel);
+
+ Label init_simd_iter_loop;
+ Label init_done;
+ Label init_first;
+
+ L(init_simd_iter_loop);
+
+ if (!jcp.with_sum) {
+ test(reg_ci_flag, FLAG_IC_FIRST);
+ jne(init_first, T_NEAR);
+ }
+
+ for (int ii = 0; ii < oc_blocks; ii++)
+ for (int jj = 0; jj < ur_w; jj++)
+ movups(Xmm(ur_w * ii + jj + 1), xword[reg_output
+ + sizeof(float) * (ii * oh * ow + jj) * oc_blk]);
+
+ if (jcp.with_sum && jcp.with_bias) {
+ test(reg_ci_flag, FLAG_IC_FIRST);
+ je(init_done, T_NEAR);
+
+ for (int ii = 0; ii < oc_blocks; ii++)
+ for (int jj = 0; jj < ur_w; jj++)
+ addps(Xmm(ur_w * ii + jj + 1),
+ xword[reg_bias + sizeof(float) * ii * oc_blk]);
+ }
+
+ jmp(init_done);
+
+ L(init_first);
+ if (this->jcp.with_bias) {
+ for (int ii = 0; ii < oc_blocks; ii++)
+ for (int jj = 0; jj < ur_w; jj++)
+ movups(Xmm(ur_w * ii + jj + 1),
+ xword[reg_bias + sizeof(float) * ii * oc_blk]);
+ } else {
+ for (int ii = 0; ii < oc_blocks; ii++)
+ for (int jj = 0; jj < ur_w; jj++)
+ pxor(Xmm(ur_w * ii + jj + 1), Xmm(ur_w * ii + jj + 1));
+ }
+
+ L(init_done);
+
+ Label skip_kh_loop;
+ mov(kj, reg_kh);
+ if ((jcp.dilate_h >= jcp.ih)
+ || (jcp.kh - 1) * (jcp.dilate_h + 1) < nstl::max(jcp.t_pad, jcp.b_pad)) {
+ cmp(kj, 0);
+ je(skip_kh_loop, T_NEAR);
+ }
+ Label kh_loop;
+ L(kh_loop);
+ {
+ if (jcp.kw >= 5 && pad_l == 0 && pad_r == 0) {
+ oh_step_nopad(ur_w, pad_l, pad_r, oc_blocks);
+ sub(aux_reg_input, sizeof(float) * kw * inp_off);
+ add(aux_reg_input, sizeof(float) * iw * inp_mult);
+ } else {
+ oh_step_unroll_kw(ur_w, pad_l, pad_r, oc_blocks);
+ add(aux_reg_kernel, sizeof(float) * kw * oc_blk * ic_blk);
+ add(aux_reg_input, sizeof(float) * iw * inp_mult);
+ }
+
+ dec(kj);
+ cmp(kj, 0);
+ jg(kh_loop, T_NEAR);
+ }
+
+ L(skip_kh_loop);
+
+ if (jcp.with_eltwise) {
+ Label regular_store;
+ test(reg_ci_flag, FLAG_IC_LAST);
+ je(regular_store, T_NEAR);
+
+ eltwise_injector_->compute_vector_range(1, oc_blocks * ur_w + 1);
+
+ L(regular_store);
+ }
+
+ for (int ii = 0; ii < oc_blocks; ii++) {
+ for (int jj = 0; jj < ur_w; jj++) {
+ const size_t o_off = (ii * oh * ow + jj) * oc_blk;
+
+ Xmm reg_out = Xmm(ur_w * ii + jj + 1);
+ movups(xword[reg_output + sizeof(float) * o_off], reg_out);
+ }
+ }
+
+ mov(aux_reg_kernel, reg_kernel);
+ mov(aux_reg_input, reg_input);
+ add(aux_reg_kernel, sizeof(float) * 4);
+ add(reg_output, sizeof(float) * 4);
+ add(reg_bias, sizeof(float) * 4);
+
+ inc(simd_iter);
+ cmp(simd_iter, 2);
+ jl(init_simd_iter_loop, T_NEAR);
+
+ sub(reg_output, sizeof(float) * 8);
+ sub(reg_bias, sizeof(float) * 8);
+}
+
+inline void jit_sse42_conv_fwd_kernel_f32::solve_common(int oc_blocks)
+{
+ int ur_w = jcp.ur_w;
+ int ur_w_tail = jcp.ur_w_tail;
+ int n_oi = jcp.ow / ur_w;
+ int iw = jcp.iw;
+ int kw = jcp.kw;
+ int ic_blk = jcp.ic_block;
+ int oc_blk = jcp.oc_block;
+ int dilate_w = jcp.dilate_w + 1;
+ int str_w = jcp.stride_w;
+ const int inp_mult = one_of(jcp.src_tag, ncw, nchw) ? 1 : ic_blk;
+
+ int l_pad = jcp.l_pad;
+ int r_pad = nstl::max(0, (int(jcp.ow) - 1) * str_w + (kw - 1) * dilate_w
+ - (iw + l_pad - 1));
+ int r_pad1 = (ur_w * n_oi - 1) * str_w + (kw - 1) * dilate_w
+ - (iw + l_pad - 1);
+ if (r_pad1 > 0) n_oi--;
+
+ if (l_pad > 0) {
+ n_oi--;
+ if (n_oi < 0 && r_pad1 > 0)
+ width_blk_step(ur_w, l_pad, r_pad1, oc_blocks); // "lrpad"
+ else
+ width_blk_step(ur_w, l_pad, 0, oc_blocks); // "lpad"
+ add(reg_input, sizeof(float) * (ur_w * str_w - l_pad) * inp_mult);
+ add(reg_output, sizeof(float) * ur_w * oc_blk);
+ }
+
+ Label ow_loop;
+ xor_(oi_iter, oi_iter);
+
+ if (n_oi > 0) {
+ L(ow_loop);
+
+ width_blk_step(ur_w, 0, 0, oc_blocks); // "middle"
+ add(reg_input, sizeof(float) * ur_w * str_w * inp_mult);
+ add(reg_output, sizeof(float) * ur_w * oc_blk);
+
+ inc(oi_iter);
+ cmp(oi_iter, n_oi);
+ jl(ow_loop, T_NEAR);
+ }
+
+ if (r_pad1 > 0 && n_oi >=0) {
+ width_blk_step(ur_w, 0, r_pad1, oc_blocks); // "rpad"
+ add(reg_input, sizeof(float) * ur_w * str_w * inp_mult);
+ add(reg_output, sizeof(float) * ur_w * oc_blk);
+ }
+
+ if (ur_w_tail != 0)
+ width_blk_step(ur_w_tail, 0, r_pad, oc_blocks); // "tail"
+}
+
+void jit_sse42_conv_fwd_kernel_f32::generate()
+{
+ this->preamble();
+
+ mov(reg_input, ptr[this->param1 + GET_OFF(src)]);
+ mov(reg_output, ptr[this->param1 + GET_OFF(dst)]);
+ mov(reg_kernel, ptr[this->param1 + GET_OFF(filt)]);
+ if (jcp.with_bias)
+ mov(reg_bias, ptr[this->param1 + GET_OFF(bias)]);
+ mov(reg_kh, ptr[this->param1 + GET_OFF(kh_padding)]);
+ mov(reg_ci_flag, ptr[this->param1 + GET_OFF(flags)]);
+ mov(reg_oc_blocks, ptr[this->param1 + GET_OFF(oc_blocks)]);
+
+ int nb_oc_tail = jcp.nb_oc % jcp.nb_oc_blocking;
+ Label tail, exit;
+
+ cmp(reg_oc_blocks, jcp.nb_oc_blocking);
+ jne(nb_oc_tail ? tail : exit, T_NEAR);
+
+ solve_common(jcp.nb_oc_blocking);
+ jmp(exit, T_NEAR);
+
+ if (nb_oc_tail) {
+ L(tail);
+ cmp(reg_oc_blocks, nb_oc_tail);
+ jne(exit, T_NEAR);
+ solve_common(nb_oc_tail);
+ }
+
+ L(exit);
+
+ this->postamble();
+
+ if (jcp.with_eltwise)
+ eltwise_injector_->prepare_table();
+}
+
+bool jit_sse42_conv_fwd_kernel_f32::post_ops_ok(
+ jit_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ const auto &p = attr.post_ops_;
+
+ auto is_eltwise = [&](int idx) { return p.entry_[idx].is_eltwise(); };
+ auto is_sum = [&](int idx) { return p.entry_[idx].is_sum(); };
+
+ switch (p.len_) {
+ case 0: return true; // no post_ops
+ case 1: return is_eltwise(0) || is_sum(0); // sum OR eltwise
+ case 2: return is_sum(0) && is_eltwise(1); // sum -> eltwise
+ default: return false;
+ }
+
+ return false;
+}
+
+status_t jit_sse42_conv_fwd_kernel_f32::init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d, const memory_desc_wrapper &dst_d,
+ const primitive_attr_t &attr)
+{
+ if (!mayiuse(sse42)) return status::unimplemented;
+
+ jcp.prop_kind = cd.prop_kind;
+
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+ const int ndims = src_d.ndims();
+ jcp.ndims = ndims;
+
+ jcp.ngroups = with_groups ? weights_d.dims()[0] : 1;
+ jcp.mb = src_d.dims()[0];
+
+ jcp.oc = dst_d.dims()[1] / jcp.ngroups;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+
+ jcp.ih = (ndims == 3) ? 1 : src_d.dims()[2];
+ jcp.iw = src_d.dims()[ndims - 1];
+ jcp.oh = (ndims == 3) ? 1 : dst_d.dims()[2];
+ jcp.ow = dst_d.dims()[ndims - 1];
+
+ jcp.kh = (ndims == 3) ? 1 : weights_d.dims()[with_groups + 2];
+ jcp.kw = weights_d.dims()[with_groups + ndims - 1];
+
+ jcp.t_pad = (ndims == 3) ? 0 : cd.padding[0][0];
+ jcp.l_pad = cd.padding[0][ndims - 3];
+
+ jcp.stride_h = (ndims == 3) ? 1 : cd.strides[0];
+ jcp.stride_w = cd.strides[ndims - 3];
+
+ jcp.dilate_h = (ndims == 3) ? 0 : cd.dilates[0];
+ jcp.dilate_w = cd.dilates[ndims - 3];
+ jcp.b_pad = (jcp.oh - 1) * jcp.stride_h + (jcp.kh - 1) * (jcp.dilate_h + 1)
+ - (jcp.ih + jcp.t_pad - 1);
+
+ if (ndims == 3) {
+ jcp.src_tag = src_d.matches_one_of_tag(ncw, nwc, nCw8c);
+ jcp.wei_tag = weights_d.matches_one_of_tag(
+ Owi8o, gOwi8o, OIw8i8o, gOIw8i8o);
+ jcp.dst_tag = dst_d.matches_one_of_tag(nCw8c);
+ } else if (ndims == 4) {
+ jcp.src_tag = src_d.matches_one_of_tag(nchw, nhwc, nChw8c);
+ jcp.wei_tag = weights_d.matches_one_of_tag(
+ Ohwi8o, gOhwi8o, OIhw8i8o, gOIhw8i8o);
+ jcp.dst_tag = dst_d.matches_one_of_tag(nChw8c);
+ }
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ jcp.with_sum = p.find(primitive_kind::sum) != -1;
+ const int eltwise_ind = p.find(primitive_kind::eltwise);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise)
+ jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+
+ const bool flat = jcp.ic == 3;
+ const bool mimo = !flat;
+
+ bool args_ok = true
+ && IMPLICATION(flat, one_of(jcp.src_tag, ncw, nwc, nchw, nhwc)
+ && one_of(jcp.wei_tag, Owi8o, gOwi8o, Ohwi8o, gOhwi8o))
+ && IMPLICATION(mimo, one_of(jcp.src_tag, nCw8c, nChw8c)
+ && one_of(jcp.wei_tag, OIw8i8o, gOIw8i8o, OIhw8i8o, gOIhw8i8o))
+ && one_of(jcp.dst_tag, nCw8c, nChw8c);
+ if (!args_ok) return status::unimplemented;
+
+ const int simd_w = 8; // 2 SSE vectors processing at once
+
+ jcp.ur_h = 1; /* no code-unrolling by h so far */
+ jcp.ur_w = 3;
+ if (jcp.ow < jcp.ur_w) jcp.ur_w = jcp.ow;
+ jcp.ur_w_tail = jcp.ow % jcp.ur_w;
+
+ jcp.nb_oc_blocking = 4; /* the optimal value for the kernel */
+
+ args_ok = true
+ && jcp.oc % simd_w == 0
+ && jcp.l_pad <= jcp.ur_w
+ && IMPLICATION(jcp.kw > 7, (jcp.t_pad == 0 && jcp.l_pad == 0)
+ || (jcp.stride_w == 1 && jcp.stride_h == 1))
+ && IMPLICATION(mimo, jcp.ic % simd_w == 0);
+ if (!args_ok) return status::unimplemented;
+
+ int r_pad_no_tail = nstl::max(0, (jcp.ow - jcp.ur_w_tail - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1) - (jcp.iw + jcp.l_pad - 1));
+
+ // kernel needs 1 temporary YMM register
+ const int num_avail_regs = 15;
+ if (r_pad_no_tail > jcp.ur_w * jcp.stride_w && jcp.ow / jcp.ur_w > 1) {
+ /* recalculate ur_w, nb_oc_blocking and ur_w_tail */
+ jcp.ur_w = nstl::min(r_pad_no_tail / jcp.stride_w + jcp.ur_w_tail,
+ nstl::min(jcp.ow, num_avail_regs / 2));
+ jcp.nb_oc_blocking = (num_avail_regs - jcp.ur_w) / jcp.ur_w;
+ jcp.ur_w_tail = jcp.ow % jcp.ur_w;
+ /* check again ... */
+ r_pad_no_tail = nstl::max(0, (jcp.ow - jcp.ur_w_tail - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1) - (jcp.iw + jcp.l_pad - 1));
+ if (jcp.ur_w < nstl::max(jcp.l_pad, r_pad_no_tail))
+ return status::unimplemented;
+ }
+ assert(jcp.nb_oc_blocking > 0);
+ assert(jcp.ur_w * (jcp.nb_oc_blocking + 1) <= num_avail_regs);
+
+ jcp.ic_block = (jcp.ic % simd_w != 0) ? jcp.ic : simd_w;
+ jcp.nb_ic = jcp.ic / jcp.ic_block;
+
+ jcp.oc_block = simd_w;
+ jcp.nb_oc = jcp.oc / jcp.oc_block;
+
+ if (one_of(jcp.prop_kind, forward_training, forward_inference)) {
+ jcp.nb_ic_blocking = 12;
+ jcp.nb_ic_blocking_max = 16;
+ } else {
+ jcp.nb_ic_blocking = 1;
+ jcp.nb_ic_blocking_max = jcp.nb_ic_blocking;
+ }
+
+ return status::success;
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_conv_kernel_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_conv_kernel_f32.hpp
new file mode 100644
index 0000000000..33c26ef081
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_conv_kernel_f32.hpp
@@ -0,0 +1,93 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_SSE42_CONV_KERNEL_F32_HPP
+#define JIT_SSE42_CONV_KERNEL_F32_HPP
+
+#include "c_types_map.hpp"
+#include "cpu_memory.hpp"
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+#include "jit_uni_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_sse42_conv_fwd_kernel_f32: public jit_generator {
+ jit_sse42_conv_fwd_kernel_f32(jit_conv_conf_t ajcp,
+ const primitive_attr_t &attr)
+ : jcp(ajcp), attr_(attr), eltwise_injector_(nullptr)
+ {
+ if (jcp.with_eltwise)
+ eltwise_injector_ = new jit_uni_eltwise_injector_f32<sse42>(this,
+ jcp.eltwise);
+
+ this->generate();
+ jit_ker = (void (*)(jit_conv_call_s *))this->getCode();
+ }
+
+ ~jit_sse42_conv_fwd_kernel_f32() {
+ delete eltwise_injector_;
+ }
+
+ static bool post_ops_ok(jit_conv_conf_t &jcp,
+ const primitive_attr_t &attr);
+
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d, const primitive_attr_t &attr);
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_sse42_conv_fwd_kernel_f32)
+ jit_conv_conf_t jcp;
+ const primitive_attr_t &attr_;
+ void (*jit_ker)(jit_conv_call_s *);
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ reg64_t reg_input = rax;
+ reg64_t aux_reg_input = r8;
+ reg64_t reg_kernel = rdx;
+ reg64_t aux_reg_kernel = r9;
+ reg64_t reg_output = rsi;
+ reg64_t reg_bias = rbx;
+
+ reg64_t kj = r10;
+ reg64_t oi_iter = r11;
+ reg64_t ki_iter = r12;
+ reg64_t reg_kh = abi_not_param1;
+ reg64_t simd_iter = r15;
+ reg64_t reg_oc_blocks = r14;
+ reg64_t imm_addr64 = reg_oc_blocks;
+ Xbyak::Reg32 reg_ci_flag = r13d;
+
+ jit_uni_eltwise_injector_f32<sse42> *eltwise_injector_;
+
+ inline void oh_step_unroll_kw(int ur_w, int pad_l, int pad_r,
+ int oc_blocks);
+ inline void oh_step_nopad(int ur_w, int pad_l, int pad_r, int oc_blocks);
+ inline void width_blk_step(int ur_w, int pad_l, int pad_r, int oc_blocks);
+ inline void solve_common(int oc_blocks);
+
+ void generate();
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_convolution.cpp
new file mode 100644
index 0000000000..5f77d692f5
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_convolution.cpp
@@ -0,0 +1,136 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn_types.h"
+
+#include "c_types_map.hpp"
+#include "jit_sse42_convolution.hpp"
+#include "mkldnn_thread.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::utils;
+
+#define src_blk_off(f, n, c, h, w) \
+ (pd()->ndims() == 3) \
+ ? (f).blk_off(n, c, w) \
+ : (f).blk_off(n, c, h, w)
+
+#define wht_blk_off_(f, g, ...) \
+ pd()->with_groups() \
+ ? (f).blk_off(g, __VA_ARGS__) \
+ : (f).blk_off(__VA_ARGS__)
+#define wht_blk_off(f, g, oc, ic, kh, kw) \
+ pd()->ndims() == 3 \
+ ? wht_blk_off_(f, g, oc, ic, kw) \
+ : wht_blk_off_(f, g, oc, ic, kh, kw)
+
+void jit_sse42_convolution_fwd_t::execute_forward(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ const auto &jcp = kernel_->jcp;
+
+ int ocb_work = div_up(jcp.nb_oc, jcp.nb_oc_blocking);
+ const size_t work_amount = jcp.mb * jcp.ngroups * ocb_work * jcp.oh;
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ size_t start{ 0 }, end{ 0 };
+ balance211(work_amount, nthr, ithr, start, end);
+
+ int icbb = 0;
+ while (icbb < jcp.nb_ic) {
+ int icb_step = jcp.nb_ic_blocking;
+ int icb_step_rem = jcp.nb_ic - icbb;
+ if (icb_step_rem < jcp.nb_ic_blocking_max)
+ icb_step = icb_step_rem;
+
+ size_t n{0}, g{0}, ocbb{0}, oh{0};
+ nd_iterator_init(start, n, jcp.mb, g, jcp.ngroups, ocbb, ocb_work,
+ oh, jcp.oh);
+ for (size_t iwork = start; iwork < end; ++iwork) {
+ int ocb = ocbb * jcp.nb_oc_blocking;
+ int ocb_num = jcp.nb_oc_blocking;
+
+ for (int icb = icbb; icb < icbb + icb_step; ++icb) {
+ auto par_conv = jit_conv_call_s();
+
+ const int ij = oh * jcp.stride_h;
+ const int i_t_overflow = nstl::max(0, jcp.t_pad - ij);
+ const int i_b_overflow = nstl::max(jcp.ih, ij
+ + (jcp.kh-1) * (jcp.dilate_h+1) - jcp.t_pad+1) - jcp.ih;
+
+ const size_t _oc = g * jcp.nb_oc + ocb;
+ const size_t _ic = g * jcp.nb_ic + icb;
+
+ const int ih = nstl::max(ij - jcp.t_pad
+ + div_up(i_t_overflow,
+ (jcp.dilate_h+1)) * (jcp.dilate_h + 1), 0);
+ par_conv.src = &src[src_blk_off(src_d, n,
+ jcp.ic == 3 ? 0 : _ic, ih, 0)];
+
+ par_conv.dst = &dst[src_blk_off(dst_d, n, _oc, oh, 0)];
+
+ const int wh = div_up(i_t_overflow, (jcp.dilate_h + 1));
+ par_conv.filt = &weights[wht_blk_off(weights_d, g, ocb,
+ jcp.ic == 3 ? 0 : icb, wh, 0)];
+
+ if (icb == 0) {
+ if (bias)
+ par_conv.bias =
+ &bias[bias_d.blk_off(_oc * jcp.oc_block)];
+ par_conv.flags |= FLAG_IC_FIRST;
+ }
+
+ if (jcp.with_eltwise && icb + 1 == jcp.nb_ic) {
+ par_conv.flags |= FLAG_IC_LAST;
+ }
+
+ par_conv.oc_blocks =
+ nstl::min(ocb + ocb_num, jcp.nb_oc) - ocb;
+
+ par_conv.kw_padding = 0;
+ const int kh_padding = jcp.kh
+ - div_up(i_t_overflow, (jcp.dilate_h + 1))
+ - div_up(i_b_overflow, (jcp.dilate_h + 1));
+ par_conv.kh_padding = nstl::max(0, kh_padding);
+ kernel_->jit_ker(&par_conv);
+ }
+ nd_iterator_step(n, jcp.mb, g, jcp.ngroups, ocbb, ocb_work,
+ oh, jcp.oh);
+ }
+ icbb += icb_step;
+ }
+ });
+
+ if (pd()->wants_zero_pad_dst())
+ ctx.memory(MKLDNN_ARG_DST)->zero_pad();
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_convolution.hpp
new file mode 100644
index 0000000000..d2f0a38c5c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_sse42_convolution.hpp
@@ -0,0 +1,103 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_SSE42_CONVOLUTION_HPP
+#define CPU_JIT_SSE42_CONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "utils.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "jit_primitive_conf.hpp"
+#include "jit_sse42_conv_kernel_f32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_sse42_convolution_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", sse42, ""),
+ jit_sse42_convolution_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ return jit_sse42_conv_fwd_kernel_f32::init_conf(jcp_, *desc(),
+ *src_md(), *weights_md(), *dst_md(), *attr());
+ }
+
+ jit_conv_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ const bool flat = IC() == 3;
+ auto src_tag = flat
+ ? utils::pick(ndims() - 3, ncw, nchw, ncdhw)
+ : utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c);
+ auto dst_tag =
+ utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c);
+ auto wei_tag = with_groups()
+ ? utils::pick(2 * ndims() - 6 + flat, gOIw8i8o, gOwi8o,
+ gOIhw8i8o, gOhwi8o, gOIdhw8i8o, gOdhwi8o)
+ : utils::pick(2 * ndims() - 6 + flat, OIw8i8o, Owi8o,
+ OIhw8i8o, Ohwi8o, OIdhw8i8o, Odhwi8o);
+
+ return set_default_formats_common(src_tag, wei_tag, dst_tag);
+ }
+ };
+
+ jit_sse42_convolution_fwd_t(const pd_t *apd): cpu_primitive_t(apd)
+ { kernel_ = new jit_sse42_conv_fwd_kernel_f32(pd()->jcp_, *pd()->attr()); }
+ ~jit_sse42_convolution_fwd_t() { delete kernel_; };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ jit_sse42_conv_fwd_kernel_f32 *kernel_;
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_transpose_src_utils.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_transpose_src_utils.cpp
new file mode 100644
index 0000000000..0e734f7265
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_transpose_src_utils.cpp
@@ -0,0 +1,1192 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "nstl.hpp"
+#include "utils.hpp"
+#include "jit_generator.hpp"
+#include "cpu_barrier.hpp"
+
+#include "jit_transpose_src_utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace Xbyak;
+
+#define GET_OFF(x) offsetof(ctx_t, x)
+
+struct jit_trans_iw_ic_t: public jit_trans_src_t, public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_trans_iw_ic_t)
+
+ jit_trans_iw_ic_t(const jit_conv_conf_t *conf): jit_trans_src_t(conf) {
+ generate();
+ ker_ = (decltype(ker_))this->getCode();
+ }
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ using reg32_t = const Xbyak::Reg32;
+ using opmask_t = const Xbyak::Opmask;
+
+ enum { typesize = sizeof(float), transpose_size = 16, small_spatial = 14 };
+ int src_stride, tr_src_stride;
+ int tail;
+ bool enable_prefetch;
+
+ opmask_t k3333 = k1;
+ opmask_t k5555 = k2;
+ opmask_t kAAAA = k3;
+ opmask_t kCCCC = k4;
+ opmask_t k0F0F = k5;
+ opmask_t kF0F0 = k6;
+ opmask_t kTail = k7;
+
+ reg64_t reg_src = r8;
+ reg64_t reg_tr_src = r9;
+ reg64_t reg_src_prf = r10;
+ reg64_t reg_tr_src_prf = r11;
+ reg64_t reg_loop = r12;
+ reg64_t reg_tr_src_tmp = r13;
+ reg32_t regw_tmp = r14d;
+
+ void transpose(int nrows, int l_pad, int r_pad, bool nontemporal_stores);
+ void generate();
+};
+
+void jit_trans_iw_ic_t::transpose(int nrows, int l_pad, int r_pad,
+ bool nontemporal_stores) {
+ assert(nrows >= 0 && nrows <= transpose_size);
+ static_assert(transpose_size == 16, "Unsupported transpose size");
+ if (!nrows)
+ return;
+
+ auto pf_src_t0 = [=](int i) {
+ if(enable_prefetch) prefetcht0(EVEX_compress_addr(reg_src,
+ (transpose_size + i) * src_stride));
+ };
+
+ auto pf_tr_src_t0 = [=](int i) {
+ int offset = (transpose_size) * typesize + i * tr_src_stride;
+ if(enable_prefetch) prefetcht0(EVEX_compress_addr(reg_tr_src, offset));
+ if(enable_prefetch) prefetcht0(EVEX_compress_addr(reg_tr_src,
+ offset + 64));
+ };
+
+ auto pf_src_t1 = [=](int i) {
+ if(enable_prefetch) prefetcht1(EVEX_compress_addr(reg_src_prf,
+ i * src_stride));
+ };
+
+ auto pf_tr_src_t1 = [=](int i) {
+ if(enable_prefetch) prefetchwt1(EVEX_compress_addr(reg_tr_src_prf,
+ i * tr_src_stride));
+ };
+
+ auto src_zmm = [=](int i) {
+ assert(i >= 0 && i < 16);
+ return Zmm(i);
+ };
+
+ auto tmp_zmm = [=](int i) {
+ assert(i >= 0 && i < 16);
+ return Zmm(16 + i);
+ };
+
+ auto load = [=](int i) {
+ vmovups(src_zmm(i), EVEX_compress_addr(reg_src, i * src_stride));
+ };
+
+ auto store = [=](Zmm r, int i) {
+ auto kmovw = [=](Opmask k, unsigned w) {
+ mov(regw_tmp, w);
+ jit_generator::kmovw(k, regw_tmp);
+ };
+
+ auto padding = [=] (Reg64 reg, int pad) {
+ kmovw(kTail, (1 << pad) - 1);
+ auto k = kTail;
+ auto base = reg;
+ base.setOpmaskIdx(k.getIdx(), true);
+
+ auto zmm_zero = r;
+ vpxord(zmm_zero, zmm_zero, zmm_zero);
+ auto addr = EVEX_compress_addr(base, i * tr_src_stride);
+ vmovups(addr, zmm_zero);
+ };
+
+ mov(reg_tr_src_tmp, reg_tr_src);
+ if (l_pad > 0)
+ add(reg_tr_src_tmp, l_pad * typesize);
+
+ if (tail != transpose_size)
+ kmovw(kTail, (1 << tail) - 1);
+
+ // Xbyak does not allow k0 to be specified explicitly via the '|'
+ // operator, so we have to do this via a method call (implicitly
+ // EVEX encoding uses k0 to mean 'no mask')
+ bool partial_store = nrows < 16;
+ auto k = partial_store ? kTail : k0;
+ auto base = reg_tr_src_tmp;
+ base.setOpmaskIdx(k.getIdx(), true);
+
+ auto addr = EVEX_compress_addr(base, i * tr_src_stride);
+ if (nontemporal_stores && !partial_store)
+ vmovntps(addr, r);
+ else
+ vmovups(addr, r);
+
+ if (r_pad > 0) {
+ add(reg_tr_src_tmp, tail * typesize);
+ padding(reg_tr_src_tmp, r_pad);
+ }
+
+ if (l_pad > 0) {
+ padding(reg_tr_src, l_pad);
+ }
+ };
+
+ auto transpose16x8 = [=](int base_idx) {
+ assert(base_idx == 0 || base_idx == 8);
+
+ // swap 1
+ for (int i = 0; i < 4; i++) {
+ int src_idx0 = base_idx + i * 2;
+ int src_idx1 = src_idx0 + 1;
+
+ int next_src_idx0 = src_idx0 + 2;
+ int next_src_idx1 = src_idx1 + 2;
+ bool load_next = base_idx == 0 || i < 3;
+
+ if (base_idx == 0 && i == 0) {
+ load(src_idx0);
+ load(src_idx1);
+ }
+
+ auto tmp0 = tmp_zmm(src_idx0);
+ auto tmp1 = tmp_zmm(src_idx1);
+ auto src0 = src_zmm(src_idx0);
+ auto src1 = src_zmm(src_idx1);
+
+ if (next_src_idx0 < nrows && load_next)
+ load(next_src_idx0);
+ valignd(tmp0, src0, src0, 0x1);
+ pf_src_t1(base_idx + i);
+
+ if (next_src_idx1 < nrows && load_next)
+ load(next_src_idx1);
+ valignd(tmp1, src1, src1, 0xf);
+ pf_src_t0(base_idx + i);
+
+ vmovaps(src0 | kAAAA, tmp1);
+ vmovaps(src1 | k5555, tmp0);
+ }
+ // swap 2
+ for (int i = 0; i < 4; i++) {
+ int select_half = (i < 2) ? 0 : 2;
+ int src_idx0 = base_idx + i + select_half + 0;
+ int src_idx2 = src_idx0 + 2;
+
+ auto tmp0 = tmp_zmm(src_idx0);
+ auto tmp1 = tmp_zmm(src_idx2);
+ auto src0 = src_zmm(src_idx0);
+ auto src2 = src_zmm(src_idx2);
+
+ valignd(tmp0, src0, src0, 0x2);
+ pf_src_t1(base_idx + 4 + i);
+ valignd(tmp1, src2, src2, 0xe);
+ pf_src_t0(base_idx + 4 + i);
+ vmovaps(src2 | k3333, tmp0);
+ vmovaps(src0 | kCCCC, tmp1);
+ }
+
+ // swap 4
+ for (int i = 0; i < 4; i++) {
+ int src_idx0 = base_idx + i;
+ int src_idx4 = src_idx0 + 4;
+
+ auto tmp0 = tmp_zmm(src_idx0);
+ auto src0 = src_zmm(src_idx0);
+ auto src4 = src_zmm(src_idx4);
+
+ vmovaps(tmp0, src0);
+ vshuff32x4(src0 | kF0F0, src4, src4, 0xb1);
+ pf_tr_src_t1(base_idx / 2 + i);
+ vshuff32x4(src4 | k0F0F, tmp0, tmp0, 0xb1);
+ pf_tr_src_t0(base_idx / 2 + i);
+ }
+ };
+
+ auto fixup16x16 = [=]() {
+ // swap 8
+ for (int i = 0; i < 8; i++) {
+ auto tmp = tmp_zmm(i);
+ auto src0 = src_zmm(i);
+ auto src8 = src_zmm(8 + i);
+ vshuff64x2(tmp, src0, src8, 0x44);
+ store(tmp, i);
+ if (i % 2 == 0) {
+ pf_tr_src_t1(8 + i / 2);
+ pf_tr_src_t0(8 + i / 2);
+ }
+ }
+
+ for (int i = 0; i < 8; i++) {
+ auto tmp = tmp_zmm(8 + i);
+ auto src0 = src_zmm(i);
+ auto src8 = src_zmm(8 + i);
+ vshuff64x2(tmp, src0, src8, 0xee);
+ store(tmp, 8 + i);
+ if (i % 2 == 0) {
+ pf_tr_src_t1(12 + i / 2);
+ pf_tr_src_t0(12 + i / 2);
+ }
+ }
+ };
+
+ transpose16x8(0);
+ transpose16x8(8);
+ fixup16x16();
+}
+
+void jit_trans_iw_ic_t::generate() {
+ preamble();
+
+ const int ic_block = conf_->ic_block;
+ const int iw = conf_->iw;
+ const int tr_iw = conf_->tr_iw;
+ const int transposes = utils::div_up(iw, transpose_size);
+ int loop_iters = nstl::max(0, transposes - 1);
+ tail = iw - loop_iters * transpose_size;
+
+ src_stride = ic_block * typesize;
+ assert(src_stride == 64);
+ tr_src_stride = tr_iw * typesize;
+
+ bool nontemporal_stores = false;
+ enable_prefetch = iw > small_spatial ? 1 : 0;
+
+ assert(transpose_size == ic_block);
+ const int src_step = ic_block * transpose_size * typesize;
+ const int tr_src_step = ic_block * typesize;
+
+ const int left_pad = conf_->l_pad;
+ const int right_pad = tr_iw - iw - left_pad;
+
+ mov(reg_src, ptr [param1 + GET_OFF(src)]);
+ mov(reg_tr_src, ptr [param1 + GET_OFF(tr_src)]);
+ mov(reg_src_prf, ptr [param1 + GET_OFF(src_prf)]);
+ mov(reg_tr_src_prf, ptr [param1 + GET_OFF(tr_src_prf)]);
+
+ auto kmovw = [=](Opmask k, unsigned w) {
+ mov(regw_tmp, w);
+ jit_generator::kmovw(k, regw_tmp);
+ };
+
+ kmovw(k3333, 0x3333); // 0011001100110011
+ kmovw(k5555, 0x5555); // 0101010101010101
+ kmovw(kAAAA, 0xaaaa); // 1010101010101010
+ kmovw(kCCCC, 0xcccc); // 1100110011001100
+ kmovw(k0F0F, 0x0f0f); // 0000111100001111
+ kmovw(kF0F0, 0xf0f0); // 1111000011110000
+
+ if (left_pad > 0 && loop_iters > 0) {
+ loop_iters--;
+ transpose(transpose_size, left_pad, 0, nontemporal_stores);
+ add(reg_src, src_step);
+ add(reg_tr_src, tr_src_step + left_pad * typesize);
+ add(reg_src_prf, src_step);
+ add(reg_tr_src_prf, tr_src_step + left_pad * typesize);
+ }
+
+ if (loop_iters) {
+ mov(reg_loop, loop_iters);
+ Label loop;
+ L(loop); {
+ transpose(transpose_size, 0, 0, nontemporal_stores);
+ add(reg_src, src_step);
+ add(reg_tr_src, tr_src_step);
+ add(reg_src_prf, src_step);
+ add(reg_tr_src_prf, tr_src_step);
+ sub(reg_loop, 1);
+ jnz(loop);
+ }
+ }
+ if (transposes > 1)
+ transpose(tail, 0, right_pad, nontemporal_stores);
+ else
+ transpose(tail, left_pad, right_pad, nontemporal_stores);
+
+ postamble();
+}
+
+struct jit_trans_iw_ic_int16_t: public jit_trans_src_t, public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_trans_iw_ic_int16_t)
+ jit_trans_iw_ic_int16_t(const jit_conv_conf_t *conf):
+ jit_trans_src_t(conf) {
+ generate();
+ ker_ = (decltype(ker_))this->getCode();
+ }
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ using reg32_t = const Xbyak::Reg32;
+ using opmask_t = const Xbyak::Opmask;
+
+ enum { typesize = sizeof(int16_t), transpose_size = 16, small_spatial = 14 };
+ int src_stride, tr_src_stride;
+ int tail;
+ bool enable_prefetch;
+
+ opmask_t kFFFF = k1;
+ opmask_t k5555 = k2;
+ opmask_t kAAAA = k3;
+ opmask_t kAA = k4;
+ opmask_t k55 = k5;
+ opmask_t kCC = k6;
+ opmask_t k33 = k7;
+ opmask_t kTail = k1;
+
+ reg64_t reg_src = r8;
+ reg64_t reg_tr_src = r9;
+ reg64_t reg_src_prf = r10;
+ reg64_t reg_tr_src_prf = r11;
+ reg64_t reg_loop = r12;
+ reg64_t reg_tr_src_tmp = r13;
+ reg32_t regw_tmp = r14d;
+ reg64_t imm_addr64 = rbx;
+
+ Xbyak::Zmm vidx1 = zmm31;
+ Xbyak::Zmm vidx2 = zmm30;
+ Xbyak::Zmm vidx3 = zmm29;
+ Xbyak::Zmm vidx4 = zmm28;
+ Xbyak::Zmm vidx5 = zmm27;
+ Xbyak::Zmm zmm_tmp = zmm26;
+
+
+ void transpose(int nrows, int l_pad, int r_pad, bool nontemporal_stores);
+ void generate();
+};
+
+void jit_trans_iw_ic_int16_t::transpose(int nrows, int l_pad, int r_pad,
+ bool nontemporal_stores) {
+ assert(nrows >= 0 && nrows <= transpose_size);
+ static_assert(transpose_size == 16, "Unsupported transpose size");
+ if (!nrows)
+ return;
+
+ auto src_zmm = [=](int i) {
+ return Zmm(i);
+ };
+
+ auto src_ymm = [=](int i) {
+ assert(i >= 0 && i < 16);
+ return Ymm(i);
+ };
+
+ auto load_ymm = [=](int i) {
+ vmovups(src_ymm(i), EVEX_compress_addr(reg_src, i * src_stride));
+ };
+
+ auto kmovw = [=](Opmask k, unsigned w) {
+ mov(regw_tmp, w);
+ jit_generator::kmovw(k, regw_tmp);
+ };
+
+ auto store = [=](Zmm r, int i) {
+
+ auto padding = [=] (Reg64 reg, int pad) {
+ kmovw(kTail, (1 << pad) - 1);
+ auto k = kTail;
+ auto base = reg;
+ base.setOpmaskIdx(k.getIdx(), true);
+
+ auto zmm_zero = zmm_tmp;
+ vpxord(zmm_zero, zmm_zero, zmm_zero);
+ auto addr = EVEX_compress_addr(base, i * tr_src_stride);
+ vmovups(addr, zmm_zero);
+ };
+
+ int store_tail = (nrows%2) ? nrows+1 : nrows;
+
+ int store_pad = (l_pad%2) ? l_pad/2 + 1 : l_pad/2;
+ mov(reg_tr_src_tmp, reg_tr_src);
+ if (l_pad > 0) {
+ padding(reg_tr_src, store_pad);
+ add(reg_tr_src_tmp, l_pad * typesize);
+ }
+ if (r_pad > 0) {
+ store_pad = (r_pad%2) ? r_pad/2 + 1 : r_pad/2;
+ int addr_shift = (r_pad%2) ? 1 : 0;
+ add(reg_tr_src_tmp, (nrows - addr_shift) * typesize);
+ padding(reg_tr_src_tmp, store_pad);
+ }
+
+ mov(reg_tr_src_tmp, reg_tr_src);
+ add(reg_tr_src_tmp, l_pad * typesize);
+
+ kmovw(kTail, (1 << store_tail/2) - 1);
+ auto k = kTail;
+ auto base = reg_tr_src_tmp;
+ base.setOpmaskIdx(k.getIdx(), true);
+
+ auto addr = EVEX_compress_addr(base, i * tr_src_stride);
+ vmovups(addr, r);
+
+ };
+
+ kmovw(kFFFF, 0xffff);
+ //all loads
+ for (int i=0; i<16; i++){
+ vpxord(src_zmm(i), src_zmm(i), src_zmm(i));
+ }
+
+ for (int i = 0; i < nrows/2; i++) {
+ auto src0 = src_ymm(2*i);
+ auto src1 = src_ymm(2*i+1);
+ auto zmm_src0 = src_zmm(2*i);
+ load_ymm(2*i);
+
+ vpunpcklwd(src1, src0,
+ EVEX_compress_addr(reg_src, (2*i+1) * src_stride));
+ vpunpckhwd(src0, src0,
+ EVEX_compress_addr(reg_src, (2*i+1) * src_stride));
+ vinserti64x4(zmm_src0, zmm_src0, src1, 1);
+ vpermps(zmm_src0 | kFFFF, vidx4, zmm_src0);
+ }
+
+ // for odd numbers we need to mix row with zeroes
+ if (nrows%2) {
+ int i = nrows-1;
+ auto src0 = src_ymm(i);
+ auto src1 = src_ymm(i+1); //zero
+
+ auto zmm_src0 = src_zmm(i);
+ vpxor(src1, src1, src1);
+
+ load_ymm(i);
+ vpunpckhwd(src0, src0, src1);
+ vinserti64x4(zmm_tmp, zmm_tmp, src0, 0);
+ vpxor(src0, src0, src0);
+ load_ymm(i);
+ vpunpcklwd(src1, src0, src1);
+ vinserti64x4(zmm_tmp, zmm_tmp, src1, 1);
+ vpxord(zmm_src0, zmm_src0, zmm_src0);
+ vmovups(zmm_src0, zmm_tmp);
+ vpermps(zmm_src0 | kFFFF, vidx4, zmm_src0);
+ }
+
+ // swap 1
+ for (int i=0; i<4; i++) {
+ auto zmm0 = src_zmm(4*i);
+ auto zmm1 = src_zmm(4*i+2);
+ auto tmp0 = src_zmm(4*i+1);
+ auto tmp1 = src_zmm(4*i+3);
+
+ vmovups(tmp0, zmm0);
+ vmovups(tmp1, zmm1);
+
+ vpermps(tmp0 | kAAAA, vidx3, zmm1);
+ vpermps(tmp1 | k5555, vidx3, zmm0);
+ }
+ // swap 2
+ int base_idx;
+ base_idx=0;
+ for (int i=0; i<2; i++) {
+ auto zmm0 = src_zmm(base_idx+2*i+1);
+ auto zmm1 = src_zmm(base_idx+2*i+5);
+
+ auto tmp0 = src_zmm(base_idx+2*i);
+ auto tmp1 = src_zmm(base_idx+2*i+4);
+
+ vmovupd(tmp0, zmm0);
+ vmovupd(tmp1, zmm1);
+
+ vpermpd(tmp0 | kAA, vidx2, zmm1);
+ vpermpd(tmp1 | k55, vidx2, zmm0);
+ }
+ base_idx=8;
+ for (int i=0; i<2; i++) {
+ auto zmm0 = src_zmm(base_idx+2*i+1);
+ auto zmm1 = src_zmm(base_idx+2*i+5);
+
+ auto tmp0 = src_zmm(base_idx+2*i);
+ auto tmp1 = src_zmm(base_idx+2*i+4);
+
+ vmovupd(tmp0, zmm0);
+ vmovupd(tmp1, zmm1);
+
+ vpermpd(tmp0 | kAA, vidx2, zmm1);
+ vpermpd(tmp1 | k55, vidx2, zmm0);
+ }
+
+ // swap 3
+ for (int i=0; i<4; i++) {
+ auto zmm0 = src_zmm(2*i);
+ auto zmm1 = src_zmm(2*i+8);
+
+ auto tmp0 = src_zmm(2*i+1);
+ auto tmp1 = src_zmm(2*i+9);
+
+ vmovupd(tmp0, zmm0);
+ vmovupd(tmp1, zmm1);
+
+ vpermpd(tmp0 | kCC, vidx1, zmm1);
+ vpermpd(tmp1 | k33, vidx1, zmm0);
+ }
+
+ // all stores
+ for (int i=0; i<8; i++)
+ vextracti64x4(src_ymm(2*i), src_zmm(2*i+1), 1);
+
+ store(src_zmm(1), 0);
+ store(src_zmm(0), 1);
+ store(src_zmm(3), 2);
+ store(src_zmm(2), 3);
+ store(src_zmm(9), 4);
+ store(src_zmm(8), 5);
+ store(src_zmm(11), 6);
+ store(src_zmm(10), 7);
+ store(src_zmm(5), 8);
+ store(src_zmm(4), 9);
+ store(src_zmm(7), 10);
+ store(src_zmm(6), 11);
+ store(src_zmm(13), 12);
+ store(src_zmm(12), 13);
+ store(src_zmm(15), 14);
+ store(src_zmm(14), 15);
+
+}
+
+void jit_trans_iw_ic_int16_t::generate() {
+ preamble();
+
+ alignas(64) static constexpr const int64_t idx1[8]
+ = { 2, 3, 0, 1, 6, 7, 4, 5 };
+ alignas(64) static constexpr const int64_t idx2[8]
+ = { 1, 0, 3, 2, 5, 4, 7, 6 };
+ alignas(64) static constexpr const int32_t idx3[16]
+ = { 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14 };
+ alignas(64) static constexpr const int32_t idx4[16]
+ = { 8, 10, 12, 14, 0, 2, 4, 6, 9, 11, 13, 15, 1, 3, 5, 7 };
+ alignas(64) static constexpr const int32_t idx5[16]
+ = { 8, 10, 12, 14, 0, 2, 4, 6, 9, 11, 13, 15, 1, 3, 5, 7 };
+
+ const int ic_block = conf_->ic_block;
+ const int iw = conf_->iw;
+ const int tr_iw = conf_->tr_iw;
+ const int transposes = utils::div_up(iw, transpose_size);
+ int loop_iters = nstl::max(0, transposes - 1);
+ tail = iw - loop_iters * transpose_size;
+
+ src_stride = ic_block * typesize;
+ tr_src_stride = tr_iw * typesize;
+
+ bool nontemporal_stores = false;
+ enable_prefetch = iw > small_spatial ? 1 : 0;
+
+ assert(transpose_size == ic_block);
+ const int src_step = ic_block * transpose_size * typesize;
+ const int tr_src_step = ic_block * typesize;
+
+ const int left_pad = conf_->l_pad;
+ const int right_pad = tr_iw - iw - left_pad;
+
+ mov(reg_src, ptr [param1 + GET_OFF(src)]);
+ mov(reg_tr_src, ptr [param1 + GET_OFF(tr_src)]);
+ mov(reg_src_prf, ptr [param1 + GET_OFF(src_prf)]);
+ mov(reg_tr_src_prf, ptr [param1 + GET_OFF(tr_src_prf)]);
+
+ auto kmovw = [=](Opmask k, unsigned w) {
+ mov(regw_tmp, w);
+ jit_generator::kmovw(k, regw_tmp);
+ };
+
+ kmovw(kFFFF, 0xffff);
+ kmovw(k5555, 0x5555);
+ kmovw(kAAAA, 0xaaaa);
+ kmovw(kAA, 0xaa);
+ kmovw(k55, 0x55);
+ kmovw(kCC, 0xcc);
+ kmovw(k33, 0x33);
+
+ auto vmovdqa64 = [=](Zmm z, const int64_t *addr) {
+ mov(imm_addr64, reinterpret_cast<size_t>(addr));
+ jit_generator::vmovdqa64(z, ptr[imm_addr64]);
+ };
+
+ auto vmovdqa32 = [=](Zmm z, const int32_t *addr) {
+ mov(imm_addr64, reinterpret_cast<size_t>(addr));
+ jit_generator::vmovdqa32(z, ptr[imm_addr64]);
+ };
+
+ vmovdqa64(vidx1, idx1);
+ vmovdqa64(vidx2, idx2);
+ vmovdqa32(vidx3, idx3);
+ vmovdqa32(vidx4, idx4);
+ vmovdqa32(vidx5, idx5);
+
+ if (left_pad > 0 && loop_iters > 0) {
+ loop_iters--;
+ transpose(transpose_size, left_pad, 0, nontemporal_stores);
+ add(reg_src, src_step);
+ add(reg_tr_src, tr_src_step + left_pad * typesize);
+ add(reg_src_prf, src_step);
+ add(reg_tr_src_prf, tr_src_step + left_pad * typesize);
+ }
+
+ if (loop_iters) {
+ mov(reg_loop, loop_iters);
+ Label loop;
+ L(loop); {
+ transpose(transpose_size, 0, 0, nontemporal_stores);
+ add(reg_src, src_step);
+ add(reg_tr_src, tr_src_step);
+ add(reg_src_prf, src_step);
+ add(reg_tr_src_prf, tr_src_step);
+ sub(reg_loop, 1);
+ jnz(loop);
+ }
+ }
+ if (transposes > 1)
+ transpose(tail, 0, right_pad, nontemporal_stores);
+ else
+ transpose(tail, left_pad, right_pad, nontemporal_stores);
+
+ postamble();
+
+}
+
+struct jit_trans_ow_oc_t: public jit_trans_dst_t, public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_trans_ow_oc_t)
+ jit_trans_ow_oc_t(const jit_conv_conf_t *conf): jit_trans_dst_t(conf) {
+ generate();
+ ker_ = (decltype(ker_))this->getCode();
+ }
+
+private:
+ using reg64_t = const Xbyak::Reg64;
+ using reg32_t = const Xbyak::Reg32;
+ using opmask_t = const Xbyak::Opmask;
+ using zmm = const Xbyak::Zmm;
+
+ enum { typesize = sizeof(int16_t), transpose_size = 16, small_spatial = 14 };
+ int src_stride, tr_src_stride;
+ int tail;
+ bool enable_prefetch;
+
+ opmask_t kFF = k1;
+
+ zmm vidx1 = zmm31;
+
+ reg64_t reg_src = r8;
+ reg64_t reg_tr_src = r9;
+ reg64_t reg_src_prf = r10;
+ reg64_t reg_tr_src_prf = r11;
+ reg64_t reg_loop = r12;
+ reg64_t reg_tr_src_tmp = r13;
+ reg32_t regw_tmp = r14d;
+ reg64_t imm_addr64 = rbx;
+
+ void transpose(int nrows, int l_pad, int r_pad, bool nontemporal_stores);
+ void generate();
+};
+
+void jit_trans_ow_oc_t::transpose(int nrows, int l_pad, int r_pad,
+ bool nontemporal_stores) {
+ assert(nrows >= 0 && nrows <= transpose_size);
+ static_assert(transpose_size == 16, "Unsupported transpose size");
+ if (!nrows)
+ return;
+
+ auto src_zmm = [=](int i) {
+ return Zmm(i);
+ };
+
+ auto src_ymm = [=](int i) {
+ assert(i >= 0 && i < 16);
+ return Ymm(i);
+ };
+
+ auto load_ymm = [=](int i) {
+ vmovups(src_ymm(i), EVEX_compress_addr(reg_src, i * src_stride));
+ };
+
+
+ auto store = [=](Zmm r, int i) {
+ auto addr = EVEX_compress_addr(reg_tr_src, i * tr_src_stride);
+ if (nontemporal_stores)
+ vmovntps(addr, r);
+ else
+ vmovups(addr, r);
+ };
+
+ for (int i = 0; i < nrows/2; i++) {
+ auto src0 = src_ymm(2*i);
+ auto src1 = src_ymm(2*i+1);
+ auto zmm_src0 = src_zmm(2*i);
+ load_ymm(2*i);
+ vpunpcklwd(src1, src0,
+ EVEX_compress_addr(reg_src, (2*i+1) * src_stride));
+ vpunpckhwd(src0, src0,
+ EVEX_compress_addr(reg_src, (2*i+1) * src_stride));
+ vinserti64x4(zmm_src0, zmm_src0, src1, 1);
+ vpermpd(zmm_src0 | kFF, vidx1, zmm_src0);
+ store(zmm_src0, 2*i);
+ }
+ if (r_pad > 0) {
+ auto src0 = src_ymm(nrows-1);
+ auto src1 = src_ymm(nrows);
+ auto zmm_src0 = src_zmm(30);
+ load_ymm(nrows-1);
+
+ vpxor(src1, src1, src1);
+ vpunpckhwd(src1, src0, src1);
+ vinserti64x4(zmm_src0, zmm_src0, src1, 0);
+ vpxor(src1, src1, src1);
+ vpunpcklwd(src0, src0, src1);
+ vinserti64x4(zmm_src0, zmm_src0, src0, 1);
+ vpermpd(zmm_src0 | kFF, vidx1, zmm_src0);
+ store(zmm_src0, nrows-1);
+ }
+}
+
+void jit_trans_ow_oc_t::generate() {
+ preamble();
+
+ alignas(64) static constexpr const int64_t idx1[8]
+ = { 4, 5, 0, 1, 6, 7, 2, 3 };
+
+ const int oc_block = conf_->oc_block;
+ const int ow = conf_->ow;
+ const int transposes = utils::div_up(ow, transpose_size);
+ int loop_iters = nstl::max(0, transposes - 1);
+ tail = ow - loop_iters * transpose_size;
+
+ src_stride = oc_block * typesize;
+ tr_src_stride = oc_block * typesize;
+
+ bool nontemporal_stores = false;
+ enable_prefetch = ow > small_spatial ? 1 : 0;
+
+ const int src_step = oc_block * transpose_size * typesize;
+ const int tr_src_step = oc_block * transpose_size * typesize;
+ const int right_pad = ow % 2;
+
+ mov(reg_src, ptr [param1 + GET_OFF(src)]);
+ mov(reg_tr_src, ptr [param1 + GET_OFF(tr_src)]);
+ mov(reg_src_prf, ptr [param1 + GET_OFF(src_prf)]);
+ mov(reg_tr_src_prf, ptr [param1 + GET_OFF(tr_src_prf)]);
+
+ auto kmovw = [=](Opmask k, unsigned w) {
+ mov(regw_tmp, w);
+ jit_generator::kmovw(k, regw_tmp);
+ };
+
+ kmovw(kFF, 0xFF);
+
+ auto vmovdqa64 = [=](Zmm z, const int64_t *addr) {
+ mov(imm_addr64, reinterpret_cast<size_t>(addr));
+ jit_generator::vmovdqa64(z, ptr[imm_addr64]);
+ };
+
+ vmovdqa64(vidx1, idx1);
+ if (loop_iters) {
+ mov(reg_loop, loop_iters);
+ Label loop;
+ L(loop); {
+ transpose(transpose_size, 0, 0, nontemporal_stores);
+ add(reg_src, src_step);
+ add(reg_tr_src, tr_src_step);
+ add(reg_src_prf, src_step);
+ add(reg_tr_src_prf, tr_src_step);
+ sub(reg_loop, 1);
+ jnz(loop);
+ }
+ }
+ transpose(tail, 0, right_pad, nontemporal_stores);
+
+ postamble();
+}
+
+struct jit_trans_iw_x4_4x_t: public jit_trans_src_t, public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_trans_iw_x4_4x_t)
+
+ jit_trans_iw_x4_4x_t(const jit_conv_conf_t *conf): jit_trans_src_t(conf) {
+ generate();
+ ker_ = (decltype(ker_))this->getCode();
+ }
+
+ void generate();
+ enum { typesize = (int)sizeof(float) };
+};
+
+/** @brief transposition of the form [:][iw/4][4] -> [:][4][iw/4]
+ * required for 1st 4fma backward by weights convolution */
+void jit_trans_iw_x4_4x_t::generate() {
+ using namespace utils;
+
+ /* TODO: put into code */
+ static int mask[16] = {
+ 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15, };
+
+ const auto &c = *conf_;
+ const int simd_w = cpu_isa_traits<avx512_common>::vlen / typesize;
+ const int niters = c.tr_ld / simd_w;
+
+ assert(niters <= 4); /* [bwd_w:tr_src:r1] */
+
+ Reg64 reg_ptr_src = r8;
+ Reg64 reg_ptr_tr_src = r9;
+
+ Reg64 reg_ih = rax;
+ Reg64 reg_ih_end = rbx;
+
+ Reg64 reg_nthr_oc_b = rsi;
+ Reg64 reg_ptr_tr_src_bctx = abi_not_param1;
+
+ Reg64 reg_tmp = rdx;
+
+ Zmm vmsk = Zmm(31);
+ Opmask kmsk = k7;
+
+ auto emit_tr_sync = [&]() {
+ simple_barrier::generate(*this, reg_ptr_tr_src_bctx, reg_nthr_oc_b);
+ };
+
+ auto emit_tr_iw = [&]() {
+ auto vreg = [](int iter, int i) {
+ assert(4 * iter + i < 24);
+ return Zmm(4 * iter + i);
+ };
+ auto vtmp = [](int i) { return Zmm(24 + i); };
+
+ auto emit_load = [&](int iter) {
+ for (int i = 0; i < 4; ++i) {
+ auto v = vreg(iter, i);
+ const int off = (iter * 4 + i) * simd_w;
+
+ if (off + simd_w <= c.iw)
+ vmovups(v, ptr[reg_ptr_src + off * typesize]);
+ else if (off < c.iw)
+ vmovups(v | kmsk | T_z, ptr[reg_ptr_src + off * typesize]);
+ else
+ vpxord(v, v, v);
+ }
+ };
+
+ auto emit_tr = [&](int iter) {
+ for (int i = 0; i < 4; ++i)
+ vpermps(vreg(iter, i), vmsk, vreg(iter, i));
+
+ vshuff32x4(vtmp(0), vreg(iter, 0), vreg(iter, 1), 0x88);
+ vshuff32x4(vtmp(1), vreg(iter, 0), vreg(iter, 1), 0xdd);
+ vshuff32x4(vtmp(2), vreg(iter, 2), vreg(iter, 3), 0x88);
+ vshuff32x4(vtmp(3), vreg(iter, 2), vreg(iter, 3), 0xdd);
+
+ vshuff32x4(vreg(iter, 0), vtmp(0), vtmp(2), 0x88);
+ vshuff32x4(vreg(iter, 2), vtmp(0), vtmp(2), 0xdd);
+ vshuff32x4(vreg(iter, 1), vtmp(1), vtmp(3), 0x88);
+ vshuff32x4(vreg(iter, 3), vtmp(1), vtmp(3), 0xdd);
+ };
+
+ auto emit_store = [&]() {
+ for (int i = 0; i < 4; ++i) {
+ for (int iter = 0; iter < niters; ++iter) {
+ const size_t off = i * c.tr_ld + iter * simd_w;
+ vmovups(ptr[reg_ptr_tr_src + off * typesize], vreg(iter, i));
+ }
+ }
+ };
+
+ for (int iter = 0; iter < niters; ++iter)
+ emit_load(iter);
+
+ for (int iter = 0; iter < niters; ++iter)
+ emit_tr(iter);
+
+ emit_store();
+ };
+
+ preamble();
+
+ mov(reg_ptr_src, ptr[abi_param1 + GET_OFF(src)]);
+ mov(reg_ptr_tr_src, ptr[abi_param1 + GET_OFF(tr_src)]);
+
+ mov(reg_nthr_oc_b.cvt32(), ptr[abi_param1 + GET_OFF(nthr_oc_b)]);
+ mov(reg_ih.cvt32(), ptr[abi_param1 + GET_OFF(tr_src_ih_start)]);
+ mov(reg_ih_end.cvt32(), ptr[abi_param1 + GET_OFF(tr_src_ih_end)]);
+ mov(reg_ptr_tr_src_bctx, ptr[abi_param1 + GET_OFF(tr_src_bctx)]);
+
+ emit_tr_sync();
+
+ Label l_ih_loop, l_tr_done;
+ cmp(reg_ih, reg_ih_end);
+ je(l_tr_done, T_NEAR);
+
+ mov(reg_tmp, (size_t)&mask[0]);
+ vmovups(vmsk, ptr[reg_tmp]);
+
+ if (c.iw % simd_w) {
+ const char load_mask = (1 << (c.iw % simd_w)) - 1;
+ mov(reg_tmp, load_mask);
+ kmovw(kmsk, reg_tmp.cvt32());
+ }
+
+ /* src += ih_start * c.iw; */
+ imul(reg_tmp, reg_ih, c.iw * typesize);
+ add(reg_ptr_src, reg_tmp);
+ /* tr_src += ih_start * c.stride_w * c.tr_ld; */
+ imul(reg_tmp, reg_ih, c.stride_w * c.tr_ld * typesize);
+ add(reg_ptr_tr_src, reg_tmp);
+
+ L(l_ih_loop); {
+ emit_tr_iw();
+
+ add(reg_ptr_src, c.iw * typesize);
+ add(reg_ptr_tr_src, c.stride_w * c.tr_ld * typesize);
+
+ inc(reg_ih);
+ cmp(reg_ih, reg_ih_end);
+ jl(l_ih_loop, T_NEAR);
+ }
+
+ L(l_tr_done);
+
+ emit_tr_sync();
+
+ postamble();
+}
+
+/*
+// -------------------------------------------------
+// jit_transpose4x16_src
+// -------------------------------------------------
+*/
+
+void jit_transpose4x16_src::transpose(int nrows)
+{
+ assert(nrows >= 0 && nrows <= transpose_size);
+ static_assert(transpose_size == 4, "Unsupported transpose size");
+ if (!nrows)
+ return;
+
+ auto pf_src_t0 = [=](int i) {
+ if (tparams->src_pf0_distance)
+ prefetcht0(EVEX_compress_addr(
+ reg_src, (tparams->src_pf0_distance + i) * src_stride));
+ };
+
+ auto pf_tr_src_t0 = [=](int i) {
+ if (tparams->tr_src_pf0_distance)
+ prefetcht0(EVEX_compress_addr(reg_tr_src,
+ (tparams->tr_src_pf0_distance + i) * src_stride));
+ };
+
+ auto pf_src_t1 = [=](int i) {
+ if (tparams->src_pf1)
+ prefetcht1(EVEX_compress_addr(reg_src_prf, i * src_stride));
+ };
+
+ auto pf_tr_src_t1 = [=](int i) {
+ if (tparams->tr_src_pf1)
+ prefetchwt1(EVEX_compress_addr(reg_tr_src_prf, i * tr_src_stride));
+ };
+
+ auto src_zmm = [=](int i) {
+ assert(i >= 0 && i < 4);
+ return Zmm(i);
+ };
+
+ auto tmp_zmm = [=](int i) {
+ assert(i >= 0 && i < 4);
+ return Zmm(4 + i);
+ };
+
+ auto load = [=](int i) {
+ vmovups(src_zmm(i), EVEX_compress_addr(reg_src, i * src_stride));
+ };
+
+ auto store = [=](Zmm r, int i) {
+ vmovups(EVEX_compress_addr(reg_tr_src, i * tr_src_stride), r);
+ };
+
+ auto tmp0 = tmp_zmm(0);
+ auto tmp1 = tmp_zmm(1);
+ auto tmp2 = tmp_zmm(2);
+ auto tmp3 = tmp_zmm(3);
+
+ auto src0 = src_zmm(0);
+ auto src1 = src_zmm(1);
+ auto src2 = src_zmm(2);
+ auto src3 = src_zmm(3);
+ for (int i = 0; i < nrows; i++) {
+ load(i);
+ }
+
+ for (size_t i = nrows; i < 4; i++) {
+ vpxord(src_zmm(i), src_zmm(i), src_zmm(i));
+ }
+
+ vmovupd(tmp0, src0);
+ vmovupd(tmp1, src1);
+ pf_src_t0(0);
+ vpermpd(tmp0 | kF0, vidx01, src2);
+ vpermpd(tmp1 | kF0, vidx01, src3);
+
+ valignd(src0, src0, src0, 8);
+ valignd(src1, src1, src1, 8);
+ pf_src_t0(1);
+ vmovupd(tmp2, src0);
+ vmovupd(tmp3, src1);
+ pf_src_t0(2);
+ vpermpd(tmp2 | kF0, vidx10, src2);
+ vpermpd(tmp3 | kF0, vidx10, src3);
+ pf_src_t0(3);
+
+ vmovupd(src0, tmp0);
+ pf_src_t1(0);
+ vmovupd(src1, tmp2);
+ pf_src_t1(1);
+ vmovupd(src2, tmp1);
+ pf_src_t1(2);
+ vmovupd(src3, tmp3);
+ pf_src_t1(3);
+ vpermpd(src0 | kCC, vidx1, tmp1);
+ vpermpd(src1 | kCC, vidx1, tmp3);
+ pf_tr_src_t0(0);
+ vpermpd(src2 | k33, vidx1, tmp0);
+ vpermpd(src3 | k33, vidx1, tmp2);
+ pf_tr_src_t0(1);
+
+ vmovupd(tmp0, src0);
+ vmovupd(tmp1, src2);
+ pf_tr_src_t0(2);
+ vmovupd(tmp2, src1);
+ vmovupd(tmp3, src3);
+ pf_tr_src_t0(3);
+ vpermps(tmp0 | kFFFF, vidxP, src0);
+ pf_tr_src_t1(0);
+ vpermps(tmp1 | kFFFF, vidxP, src2);
+ pf_tr_src_t1(1);
+ vpermps(tmp2 | kFFFF, vidxP, src1);
+ pf_tr_src_t1(3);
+ vpermps(tmp3 | kFFFF, vidxP, src3);
+ pf_tr_src_t1(4);
+
+ store(tmp0, 0);
+ store(tmp1, 1);
+ store(tmp2, 2);
+ store(tmp3, 3);
+}
+
+alignas(64) static constexpr const int64_t idx01[8]
+ = { 0, 0, 0, 0, 0, 1, 2, 3 };
+alignas(64) static constexpr const int64_t idx10[8]
+ = { 0, 0, 0, 0, 4, 5, 6, 7 };
+alignas(64) static constexpr const int64_t idx1[8] = { 2, 3, 0, 1, 6, 7, 4, 5 };
+alignas(64) static constexpr const int32_t idxP[16]
+ = { 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 };
+
+void jit_transpose4x16_src::generate()
+{
+ preamble();
+
+ const int ic_block = params->ic_block;
+ const int is = params->is;
+ int tail = is % transpose_size;
+
+ src_stride = ic_block * typesize;
+ assert(src_stride == 64);
+ tr_src_stride = ic_block * typesize;
+
+ const int src_step = ic_block * transpose_size * typesize;
+ const int tr_src_step = ic_block * transpose_size * typesize;
+
+#define GET_TR_OFF(x) offsetof(jit_src_transpose_s, x)
+ mov(reg_loop, ptr[param1 + GET_TR_OFF(size)]);
+ mov(reg_src, ptr[param1 + GET_TR_OFF(src)]);
+ mov(reg_tr_src, ptr[param1 + GET_TR_OFF(tr_src)]);
+ mov(reg_src_prf, ptr[param1 + GET_TR_OFF(src_prf)]);
+ mov(reg_tr_src_prf, ptr[param1 + GET_TR_OFF(tr_src_prf)]);
+#undef GET_TR_OFF
+
+ auto kmovw = [=](Opmask k, unsigned w) {
+ mov(regw_tmp, w);
+ jit_generator::kmovw(k, regw_tmp);
+ };
+
+ auto vmovdqa64 = [=](Zmm z, const int64_t *addr) {
+ mov(imm_addr64, reinterpret_cast<size_t>(addr));
+ jit_generator::vmovdqa64(z, ptr[imm_addr64]);
+ };
+
+ auto vmovdqa32 = [=](Zmm z, const int32_t *addr) {
+ mov(imm_addr64, reinterpret_cast<size_t>(addr));
+ jit_generator::vmovdqa32(z, ptr[imm_addr64]);
+ };
+
+ kmovw(kF0, 0xf0); // 11110000
+ kmovw(kCC, 0xcc); // 11001100
+ kmovw(k33, 0x33); // 00110011
+ kmovw(kFFFF, 0xffff); // 1111111111111111
+
+ vmovdqa64(vidx01, idx01);
+ vmovdqa64(vidx10, idx10);
+ vmovdqa64(vidx1, idx1);
+ vmovdqa32(vidxP, idxP);
+
+ Label loop_label;
+ Label tail_label;
+
+ cmp(reg_loop, transpose_size);
+ jl(tail_label, T_NEAR);
+
+ L(loop_label);
+ {
+ transpose(transpose_size);
+ add(reg_src, src_step);
+ add(reg_tr_src, tr_src_step);
+ add(reg_src_prf, src_step);
+ add(reg_tr_src_prf, tr_src_step);
+ sub(reg_loop, transpose_size);
+ cmp(reg_loop, transpose_size);
+ jge(loop_label, T_NEAR);
+ }
+ L(tail_label);
+ transpose(tail);
+
+ postamble();
+}
+
+jit_trans_src_t *create_trans_src(const jit_conv_conf_t *conf) {
+ if (conf->ver == ver_4fma && !conf->is_1stconv)
+ return new jit_trans_iw_ic_t(conf);
+ if (conf->ver == ver_4fma && conf->is_1stconv)
+ return new jit_trans_iw_x4_4x_t(conf);
+ assert(!"unsupported configuration");
+ return nullptr;
+}
+
+jit_trans_dst_t *create_trans_dst(const jit_conv_conf_t *conf) {
+ assert(!"unsupported configuration");
+ return nullptr;
+}
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_transpose_src_utils.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_transpose_src_utils.hpp
new file mode 100644
index 0000000000..565e97e4fc
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_transpose_src_utils.hpp
@@ -0,0 +1,145 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_TRANSPOSE_SRC_HPP
+#define CPU_JIT_TRANSPOSE_SRC_HPP
+
+#include "cpu_barrier.hpp"
+#include "jit_primitive_conf.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_trans_src_t {
+ struct ctx_t {
+ const void *src;
+ const void *tr_src;
+ const void *src_prf;
+ const void *tr_src_prf;
+
+ /* 1st conv 4fma: backward by weights */
+ int nthr_oc_b; /* number of threads process given src image */
+ int tr_src_ih_start, tr_src_ih_end; /* thread's transposition bounds */
+ simple_barrier::ctx_t *tr_src_bctx; /* transposition synchronization */
+ };
+
+ jit_trans_src_t(const jit_conv_conf_t *conf)
+ : conf_(conf), ker_(nullptr) {}
+ virtual ~jit_trans_src_t() {}
+
+ void operator()(const ctx_t *ctx)
+ { assert(ker_); ker_(ctx); }
+
+ const jit_conv_conf_t *conf_;
+ void (*ker_)(const ctx_t *);
+};
+
+struct jit_src_transpose_s {
+ size_t size;
+ const void *src;
+ const void *tr_src;
+ const void *src_prf;
+ const void *tr_src_prf;
+};
+
+struct jit_trans_dst_t {
+ struct ctx_t {
+ const void *src;
+ const void *tr_src;
+ const void *src_prf;
+ const void *tr_src_prf;
+
+ /* 1st conv 4fma: backward by weights */
+ int nthr_oc_b; /* number of threads process given src image */
+ int tr_src_ih_start, tr_src_ih_end; /* thread's transposition bounds */
+ simple_barrier::ctx_t *tr_src_bctx; /* transposition synchronization */
+ };
+
+ jit_trans_dst_t(const jit_conv_conf_t *conf)
+ : conf_(conf), ker_(nullptr) {}
+ virtual ~jit_trans_dst_t() {}
+
+ void operator()(const ctx_t *ctx)
+ { assert(ker_); ker_(ctx); }
+
+ const jit_conv_conf_t *conf_;
+ void (*ker_)(const ctx_t *);
+};
+
+struct jit_transpose4x16_src_t {
+ int src_pf0_distance;
+ int tr_src_pf0_distance;
+ bool src_pf1;
+ bool tr_src_pf1;
+};
+
+struct jit_transpose4x16_src : public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_transpose4x16_src)
+
+ jit_transpose4x16_src(const jit_1x1_conv_conf_t *aparams,
+ jit_transpose4x16_src_t *tparams_)
+ : params(aparams), tparams(tparams_)
+ {
+ this->generate();
+ jit_ker = (decltype(jit_ker))this->getCode();
+ }
+
+ const jit_1x1_conv_conf_t *params;
+ const jit_transpose4x16_src_t *tparams;
+ void (*jit_ker)(jit_src_transpose_s *);
+
+ void operator()(jit_src_transpose_s *arg) { jit_ker(arg); }
+
+ static const int transpose_size = 4;
+private:
+ static const int typesize = sizeof(float);
+
+ int src_stride, tr_src_stride;
+
+ Xbyak::Reg64 imm_addr64 = rbx;
+
+ Xbyak::Opmask kF0 = k1;
+ Xbyak::Opmask kCC = k2;
+ Xbyak::Opmask k33 = k3;
+ Xbyak::Opmask kFFFF = k4;
+
+ Xbyak::Zmm vidx01 = zmm31;
+ Xbyak::Zmm vidx10 = zmm30;
+ Xbyak::Zmm vidx1 = zmm29;
+ Xbyak::Zmm vidxP = zmm28;
+
+ Xbyak::Reg64 reg_src = r8;
+ Xbyak::Reg64 reg_tr_src = r9;
+ Xbyak::Reg64 reg_src_prf = r10;
+ Xbyak::Reg64 reg_tr_src_prf = r11;
+ Xbyak::Reg64 reg_loop = r12;
+ Xbyak::Reg64 reg_tr_src_tmp = r13;
+ Xbyak::Reg32 regw_tmp = r14d;
+
+ void transpose_block(int ur, int nrows);
+ void transpose(int nrows);
+ void generate();
+};
+
+jit_trans_src_t *create_trans_src(const jit_conv_conf_t *conf);
+jit_trans_dst_t *create_trans_dst(const jit_conv_conf_t *conf);
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_1x1_conv_utils.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_1x1_conv_utils.hpp
new file mode 100644
index 0000000000..53313f9f01
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_1x1_conv_utils.hpp
@@ -0,0 +1,327 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_UNI_1x1_CONV_UTILS_HPP
+#define JIT_UNI_1x1_CONV_UTILS_HPP
+
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::utils;
+
+struct reduce_to_unit_stride_t {
+ convolution_desc_t conv_d_;
+ bool reduce_src_;
+ size_t space_per_thread_;
+};
+
+/* 1x1-kernel does not support non-unit strides so far, so the idea is:
+ * - for fwd or bwd_weights: to copy src to a scratch memory (with strides
+ * equal to 1) and then call the kernel
+ * - for bwd_data: reduce the problem to the one with unit stride by
+ * performing computations in a scratch memory (with strides equal to 1)
+ * and then copy the result to diff_src */
+template <typename conv_pd_t>
+inline void rtus_prepare(conv_pd_t *self, const convolution_desc_t *&conv_d,
+ const memory_desc_t *&src_d, const memory_desc_t *dst_d) {
+ const bool is_bwd_data = self->desc()->prop_kind
+ == prop_kind::backward_data;
+
+ const int ndims = src_d->ndims;
+ const auto dat_tag = ndims == 3
+ ? memory_desc_wrapper(dst_d).matches_one_of_tag(
+ format_tag::nCw8c, format_tag::nCw16c)
+ : memory_desc_wrapper(dst_d).matches_one_of_tag(
+ format_tag::nChw8c, format_tag::nChw16c);
+
+ bool rtus_applicable = true
+ && utils::pick(ndims - 3,
+ (conv_d->strides[0] != 1 && !one_of(conv_d->src_desc.data_type,
+ data_type::s32)),
+ (conv_d->strides[0] != 1 || conv_d->strides[1] != 1))
+ && dat_tag != format_tag::undef;
+ for (int d = 2; d < ndims; ++d) {
+ /* TODO: relax these conditions (by improving reducer) */
+ rtus_applicable = rtus_applicable
+ && conv_d->padding[0][d - 2] == 0
+ && dst_d->dims[d] * conv_d->strides[d - 2] == src_d->dims[d];
+ }
+
+ if (rtus_applicable) {
+ self->rtus_.reduce_src_ = true;
+ conv_d = &(self->rtus_.conv_d_ = *conv_d);
+ self->rtus_.conv_d_.strides[0] = 1;
+ if (ndims == 4)
+ self->rtus_.conv_d_.strides[1] = 1;
+ utils::array_set(self->rtus_.conv_d_.padding[0], 0, 2);
+ if (ndims == 4)
+ utils::array_set(self->rtus_.conv_d_.padding[1], 0, 2);
+ const int ic = src_d->dims[1];
+ if (is_bwd_data) {
+ src_d = &(self->rtus_.conv_d_.diff_src_desc = *dst_d);
+ self->rtus_.conv_d_.diff_src_desc.dims[1] = ic;
+ memory_desc_wrapper::compute_blocking(
+ self->rtus_.conv_d_.diff_src_desc, dat_tag);
+ } else {
+ data_type_t data_type = self->rtus_.conv_d_.src_desc.data_type;
+ src_d = &(self->rtus_.conv_d_.src_desc = *dst_d);
+ self->rtus_.conv_d_.src_desc.dims[1] = ic;
+ self->rtus_.conv_d_.src_desc.data_type = data_type;
+ memory_desc_wrapper::compute_blocking(
+ self->rtus_.conv_d_.src_desc, dat_tag);
+ }
+ }
+}
+
+template <typename conv_pd_t>
+inline void rtus_prepare_space_info(conv_pd_t *self,
+ memory_tracking::registrar_t &scratchpad) {
+ const auto &jcp = self->jcp_;
+
+ const int max_threads = mkldnn_get_max_threads();
+ const size_t factor = utils::pick_by_prop_kind(self->desc()->prop_kind,
+ jcp.nb_reduce, jcp.nb_load_blocking_max, jcp.nb_bcast_blocking);
+ size_t typesize = types::data_type_size(
+ conv_prop_invariant_src_d(self->desc())->data_type);
+
+ self->rtus_.space_per_thread_ = factor * jcp.is * jcp.ic_block;
+ scratchpad.book(memory_tracking::names::key_conv_rtus_space,
+ typesize * max_threads * self->rtus_.space_per_thread_);
+}
+
+template <cpu_isa_t isa>
+struct rtus_driver_t: public jit_generator {
+
+ struct call_params_t {
+ const void *ws; /* reduced image (w/ strides = 1) */
+ const void *src; /* source image (w/ non-unit strides) */
+ size_t icb;
+ size_t os;
+ size_t iw_start;
+ };
+
+ void (*ker_)(const call_params_t *p);
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(rtus_driver_t)
+
+ /* cpu specific part */
+ using Vmm = typename utils::conditional<isa == avx2, Xbyak::Ymm,
+ Xbyak::Zmm>::type;
+
+ Xbyak::Reg64 reg_ws = abi_param1;
+ Xbyak::Reg64 reg_src = abi_not_param1;
+ Xbyak::Reg64 reg_icb = rdx;
+ Xbyak::Reg64 reg_os = r11;
+ Xbyak::Reg64 reg_iw_start = r8;
+
+ Xbyak::Reg64 reg_cur_os = rax;
+ Xbyak::Reg64 reg_cur_iw = r9;
+ Xbyak::Reg64 reg_cur_src = r10;
+
+ int iw_, stride_w_;
+ int src_step_h_, src_step_icb_, ws_step_icb_, vlen_, vlen_shift_;
+ bool src_to_ws_;
+ size_t typesize_;
+ Vmm reg_zero;
+ Vmm reg_v;
+
+ rtus_driver_t(int iw, int stride_w, int src_step_h,
+ int src_step_icb, int ws_step_icb, bool src_to_ws, size_t typesize)
+ : iw_(iw), stride_w_(stride_w), src_step_h_(src_step_h)
+ , src_step_icb_(src_step_icb), ws_step_icb_(ws_step_icb)
+ , src_to_ws_(src_to_ws), typesize_(typesize)
+ {
+ using namespace Xbyak;
+ vlen_ = cpu_isa_traits<isa>::vlen;
+ vlen_shift_ = cpu_isa_traits<isa>::vlen_shift;
+ if (typesize_ == 2) {
+ vlen_ /= 2;
+ vlen_shift_--;
+ }
+
+ reg_zero = Vmm(0);
+ reg_v = Vmm(1);
+
+ generate();
+ }
+
+ void loop_is() {
+ using namespace Xbyak;
+
+ mov(reg_cur_src, reg_src);
+ mov(reg_cur_iw, reg_iw_start);
+ mov(reg_cur_os, reg_os);
+
+ Label is_loop, skip_h_step;
+ L(is_loop);
+
+ if (src_to_ws_) {
+ vmovups(reg_v, ptr[reg_cur_src]);
+ vmovups(ptr[reg_ws], reg_v);
+ } else {
+ vmovups(reg_v, ptr[reg_ws]);
+ vmovups(ptr[reg_cur_src], reg_v);
+ for (int w = 1; w < stride_w_; ++w)
+ vmovups(ptr[reg_cur_src + w * vlen_], reg_zero);
+ }
+
+ add(reg_ws, vlen_);
+
+ add(reg_cur_iw, stride_w_);
+ add(reg_cur_src, stride_w_ * vlen_);
+
+ cmp(reg_cur_iw, iw_);
+ jl(skip_h_step);
+ /* for 1d convolution the loop over h should be skipped */
+ if (src_step_icb_ == iw_) jmp(skip_h_step);
+
+ if (src_to_ws_) {
+ add(reg_cur_src, (src_step_h_ - iw_) * vlen_);
+ } else {
+ Xbyak::Reg64 reg_cur_src_fin = reg_cur_iw; /* just reuse */
+ mov(reg_cur_src_fin, reg_cur_src);
+ add(reg_cur_src_fin, (src_step_h_ - iw_) * vlen_);
+ Label ih_loop;
+ L(ih_loop);
+
+ for (int w = 0; w < stride_w_; ++w)
+ vmovups(ptr[reg_cur_src + w * vlen_], reg_zero);
+
+ add(reg_cur_src, stride_w_ * vlen_);
+ cmp(reg_cur_src, reg_cur_src_fin);
+ jl(ih_loop);
+ }
+ xor_(reg_cur_iw, reg_cur_iw);
+
+ L(skip_h_step);
+
+ sub(reg_cur_os, vlen_);
+ jnz(is_loop);
+
+ /* restore dst */
+ sub(reg_ws, reg_os);
+ }
+
+ void generate() {
+ using namespace Xbyak;
+ assert(isa == avx2 || isa == avx512_common
+ || isa == avx512_core || isa == avx512_mic);
+
+#if defined(_WIN32)
+ assert(reg_src == abi_not_param1 && abi_not_param1 == rdi);
+ push(rdi);
+#endif
+
+#define READ_PARAM(what) \
+ mov(reg_ ## what, ptr[abi_param1 + offsetof(call_params_t, what)])
+ READ_PARAM(src);
+ READ_PARAM(icb);
+ READ_PARAM(os);
+ READ_PARAM(iw_start);
+
+ assert(reg_ws == abi_param1);
+ READ_PARAM(ws); /* reg_ws should always be read the last */
+#undef READ_PARAM
+
+ shl(reg_os, vlen_shift_);
+
+ if (!src_to_ws_)
+ uni_vpxor(reg_zero, reg_zero, reg_zero);
+
+ Label icb_loop;
+ L(icb_loop);
+
+ loop_is();
+
+ add(reg_ws, ws_step_icb_ * vlen_);
+ add(reg_src, src_step_icb_ * vlen_);
+
+ dec(reg_icb);
+ jnz(icb_loop, T_NEAR);
+
+#if defined(_WIN32)
+ pop(rdi);
+#endif
+
+ uni_vzeroupper();
+ ret();
+ this->ker_ = reinterpret_cast<decltype(ker_)>(const_cast<uint8_t*>(
+ this->getCode()));
+ }
+};
+
+template <cpu_isa_t isa, typename conv_t>
+inline void init_rtus_driver(conv_t *self) {
+ const auto &conf = *self->pd();
+ if (!conf.rtus_.reduce_src_) return;
+
+ const auto &cd = *conf.desc();
+ const int ndims = conf.ndims();
+ const int stride_h = (conf.ndims() == 3) ? 1 : cd.strides[0];
+ const int stride_w = cd.strides[ndims - 3];
+
+ const bool is_bwd_data = cd.prop_kind == prop_kind::backward_data;
+ const auto &src_d = is_bwd_data ? *conf.diff_src_md() : *conf.src_md();
+
+ const int ih = ndims == 3 ? 1 : src_d.dims[2];
+ const int iw = src_d.dims[ndims - 1];
+
+ const int src_step_h = stride_h * iw;
+ const int src_step_icb = ih * iw;
+ const int ws_step_icb = conf.jcp_.is;
+ const bool src_to_ws = !is_bwd_data;
+ const size_t typesize = types::data_type_size(
+ conv_prop_invariant_src_d(self->pd()->desc())->data_type);
+
+ self->rtus_driver_ = new rtus_driver_t<isa>(iw, stride_w, src_step_h,
+ src_step_icb, ws_step_icb, src_to_ws, typesize);
+}
+
+inline int best_divider(int value, int min_divider, int max_divider,
+ bool find_max, int step = 1)
+{
+ max_divider = nstl::max(1, nstl::min(max_divider, value));
+ min_divider = nstl::max(1, nstl::min(min_divider, max_divider));
+
+ auto loss_ratio = [](int total, int chunk)
+ { return float(rnd_up(total, chunk) - total) / rnd_up(total, chunk); };
+
+ float min_loss = FLT_MAX;
+ int x_divider = max_divider;
+ for (int divider = max_divider; divider >= min_divider; divider -= step) {
+ const float loss = loss_ratio(value, divider);
+ if ((find_max && loss < min_loss) || (!find_max && loss <= min_loss)) {
+ min_loss = loss;
+ x_divider = divider;
+ }
+ }
+ return x_divider;
+}
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_batch_normalization.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_batch_normalization.cpp
new file mode 100644
index 0000000000..72fe3a8109
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_batch_normalization.cpp
@@ -0,0 +1,1407 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "math_utils.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_barrier.hpp"
+#include "cpu_batch_normalization_utils.hpp"
+#include "jit_generator.hpp"
+
+#include "jit_uni_batch_normalization.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace {
+
+using namespace memory_tracking::names;
+
+using namespace Xbyak;
+namespace barrier = simple_barrier;
+
+typedef float data_t;
+
+template <cpu_isa_t isa>
+struct jit_bnorm_t: public jit_generator {
+ struct call_params_t {
+ // keep all sizes at 8 bytes -- jit code expects this
+ size_t N_ithr, N_nthr;
+ size_t coff_max, soff_max;
+ size_t mb_stride_Bc, spat_size, spat_size_loc;
+ size_t S_s, S_tail;
+ size_t is_cblk_tail;
+ data_t chan_size, eps, one;
+ const data_t *scale_shift;
+ const data_t *mean, *var;
+ const data_t *diff_scale_shift;
+ const data_t *src, *dst;
+ const data_t *diff_src, *diff_dst;
+ const data_t *rbuf1, *rbuf2;
+ const uint8_t *ws;
+ barrier::ctx_t *barrier;
+ };
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_bnorm_t)
+
+ /* cpu specific part */
+ using Vmm = typename utils::conditional3<isa == sse42, Xmm,
+ isa == avx2, Ymm, Zmm>::type;
+ const AddressFrame &vmmword = (isa == sse42) ? xword :
+ (isa == avx2) ? yword : zword;
+
+ const int vlen = isa == sse42 ? 32 : cpu_isa_traits<isa>::vlen;
+
+ const batch_normalization_pd_t *bdesc_;
+ bool is_spatial_thr_;
+
+ void (*ker)(const call_params_t *);
+ void operator()(const call_params_t *p) { (*ker)(p); }
+
+ Reg64 reg_param = abi_param1;
+
+ Reg64 reg_scale_shift = rbx;
+ Reg64 reg_rbuf1 = abi_not_param1;
+ Reg64 reg_rbuf2 = rdx;
+
+ Reg64 reg_mean = rbp;
+ Reg64 reg_var = reg_param;
+ Reg64 reg_diff_scale_shift = rax;
+
+ Reg64 reg_coff = r8;
+ Reg64 reg_coff_max = r9;
+ Reg64 reg_soff = r10;
+ Reg64 reg_soff_max = r11;
+ Reg64 reg_ctr = r12;
+ Reg64 reg_roff = r13;
+
+ Reg64 reg_mb_stride_Bc = r14;
+
+ Reg64 reg_src = r15;
+ Reg64 reg_diff_src = reg_rbuf1;
+ Reg64 reg_dst = rsi;
+ Reg64 reg_diff_dst = reg_dst;
+
+ Reg64 reg_tmp_off = reg_roff;
+
+ // Reuse loop counters
+ Reg64 reg_bar = reg_coff;
+ Reg64 reg_nnthr = reg_soff; // must be usable w/ loops over coff
+ Reg64 reg_tmp = reg_ctr;
+
+ // Relu section
+ bool with_relu, with_relu_inf_only;
+ Vmm vzero; // is_fwd() ? vdiff_beta : vbeta
+ Reg64 reg_ws = reg_roff;
+ Label l_relu_mask_avx2;
+ Opmask kstore_mask = Opmask(1);
+
+ // channel tail processing
+ Opmask ktail_mask = Opmask(2);
+
+ size_t unroll_blocks;
+ size_t unroll_regs;
+ Vmm vbuf = Vmm(isa == avx512_common ? 20 : 5);
+ Vmm vdiff_beta = Vmm(isa == avx512_common ? 21 : 6);
+ Vmm vdiff_gamma = Vmm(isa == avx512_common ? 22 : 7);
+ Vmm vsqrtvar = Vmm(isa == avx512_common ? 23 : 8);
+ Vmm vone = Vmm(isa == avx512_common ? 24 : 9);
+ Vmm vmean = Vmm(isa == avx512_common ? 25 : 10);
+ Vmm vgamma = Vmm(isa == avx512_common ? 26 : 11);
+ Vmm vbeta = Vmm(isa == avx512_common ? 27 : 12);
+ Vmm veps = Vmm(isa == avx512_common ? 28 : 13);
+ Vmm vchan_size = Vmm(isa == avx512_common ? 29 : 14);
+ Vmm vtail_mask = Vmm(isa == avx512_common ? 30 : 15);
+
+ size_t t0_pf_offt;
+ size_t t1_pf_offt;
+ size_t spat_size;
+ size_t chan_data_offt;
+
+ enum {
+ stack_off_N_nthr = 0,
+ stack_off_N_ithr = 8,
+ stack_off_src = 16,
+ stack_off_dst = 24,
+ stack_off_diff_src = 32,
+ stack_off_diff_dst = 40,
+ stack_off_diff_scale_shift = 48,
+ stack_off_ws = 56,
+ stack_off_barrier = 64,
+ stack_off_spat_size_loc = 72,
+ stack_off_s_s = 80,
+ stack_off_s_tail = 88,
+ stack_off_is_cblk_tail = 96,
+ stack_size_required = 104,
+ };
+
+ bool is_c_padded() const {
+ const memory_desc_wrapper data_d(bdesc_->src_md());
+ return bdesc_->C() != data_d.padded_dims()[1];
+ }
+
+ void compute_static_strides() {
+ spat_size = bdesc_->D() * bdesc_->W() * bdesc_->H();
+ chan_data_offt = bdesc_->C() * sizeof(data_t);
+
+ if (isa == avx512_mic) {
+ t0_pf_offt = 4096;
+ t1_pf_offt = 0;
+ } else {
+ t0_pf_offt = 0;
+ t1_pf_offt = 0;
+ }
+ }
+
+ void load_common_params() {
+# define PARAM_OFF(x) offsetof(call_params_t, x)
+ mov(reg_rbuf1, ptr[reg_param + PARAM_OFF(rbuf1)]);
+ if (bdesc_->is_bwd())
+ mov(reg_rbuf2, ptr[reg_param + PARAM_OFF(rbuf2)]);
+ mov(reg_coff_max, ptr[reg_param + PARAM_OFF(coff_max)]);
+ mov(reg_soff_max, ptr[reg_param + PARAM_OFF(soff_max)]);
+ mov(reg_mb_stride_Bc, ptr[reg_param + PARAM_OFF(mb_stride_Bc)]);
+ shl(reg_coff_max, 2);
+ shl(reg_soff_max, 2);
+ shl(reg_mb_stride_Bc, 2);
+
+ mov(reg_mean, ptr[reg_param + PARAM_OFF(mean)]);
+ mov(reg_scale_shift, ptr[reg_param + PARAM_OFF(scale_shift)]);
+
+ uni_vbroadcastss(vchan_size, vmmword[reg_param + PARAM_OFF(chan_size)]);
+ uni_vbroadcastss(vone, vmmword[reg_param + PARAM_OFF(one)]);
+ uni_vbroadcastss(veps, vmmword[reg_param + PARAM_OFF(eps)]);
+
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(N_nthr)]);
+ mov(ptr[rsp + stack_off_N_nthr], reg_tmp);
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(N_ithr)]);
+ mov(ptr[rsp + stack_off_N_ithr], reg_tmp);
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(src)]);
+ mov(ptr[rsp + stack_off_src], reg_tmp);
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(dst)]);
+ mov(ptr[rsp + stack_off_dst], reg_tmp);
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(diff_src)]);
+ mov(ptr[rsp + stack_off_diff_src], reg_tmp);
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(diff_dst)]);
+ mov(ptr[rsp + stack_off_diff_dst], reg_tmp);
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(ws)]);
+ mov(ptr[rsp + stack_off_ws], reg_tmp);
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(barrier)]);
+ mov(ptr[rsp + stack_off_barrier], reg_tmp);
+ if (is_spatial_thr_) {
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(spat_size_loc)]);
+ mov(ptr[rsp + stack_off_spat_size_loc], reg_tmp);
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(S_s)]);
+ mov(ptr[rsp + stack_off_s_s], reg_tmp);
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(S_tail)]);
+ mov(ptr[rsp + stack_off_s_tail], reg_tmp);
+ }
+ if (is_c_padded()) {
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(is_cblk_tail)]);
+ mov(ptr[rsp + stack_off_is_cblk_tail], reg_tmp);
+ }
+
+ if (bdesc_->is_fwd()) {
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(var)]);
+ mov(reg_var, reg_tmp);
+ } else {
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(diff_scale_shift)]);
+ mov(ptr[rsp + stack_off_diff_scale_shift], reg_tmp);
+ mov(reg_tmp, ptr[reg_param + PARAM_OFF(var)]);
+ mov(reg_var, reg_tmp);
+ }
+# undef PARAM_OFF
+ }
+
+ void prepare_tail_mask_avx512_common() {
+ if (!is_c_padded()) return;
+
+ const int tail = bdesc_->C() % (int)(vlen / sizeof(float));
+ const int mask = (1 << tail) - 1;
+
+ Reg32 regw_tmp = reg_tmp.cvt32();
+ mov(regw_tmp, mask);
+ kmovw(ktail_mask, regw_tmp);
+ }
+
+ void prepare_tail_mask_avx2_common() {
+ if (!is_c_padded()) return;
+
+ const int tail = bdesc_->C() % (int)(vlen / sizeof(float));
+ static const uint32_t mask[16] = {0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0, 0, 0, 0, 0, 0, 0, 0};
+
+ mov(reg_tmp, reinterpret_cast<size_t>(&mask[8 - tail]));
+ vmovups(vtail_mask, ptr[reg_tmp]);
+ }
+
+ void prepare_relu() {
+ with_relu = bdesc_->is_fwd()
+ ? bdesc_->with_relu_post_op() || bdesc_->fuse_bn_relu()
+ : bdesc_->fuse_bn_relu();
+ with_relu_inf_only = with_relu && bdesc_->is_fwd()
+ && !(bdesc_->fuse_bn_relu() && bdesc_->is_training());
+
+ vzero = bdesc_->is_fwd() ? vdiff_beta : vbeta;
+ if (with_relu) {
+ uni_vpxor(vzero, vzero, vzero);
+ if (!bdesc_->is_fwd() && isa == avx2)
+ prepare_l_relu_mask_avx2();
+ }
+ }
+
+ void prepare_l_relu_mask_avx2() {
+ Label l_mask_after;
+ jmp(l_mask_after);
+ align(32);
+ L(l_relu_mask_avx2); /* [0x80 0x40 0x20 0x10 0x08 0x04 0x02 0x01] */
+ for (int i = 0; i < 8; ++i) dd(1<<i);
+ L(l_mask_after);
+ }
+
+ void fwd_process_relu_avx2(Vmm vdst, int offt, Vmm vstore_mask) {
+ Reg64 reg_store_mask = reg_diff_scale_shift;
+ shr(reg_soff, 5);
+ vcmpps(vstore_mask, vzero, vdst, _cmp_lt_os);
+ vmovmskps(reg_store_mask, vstore_mask);
+ mov(ptr[reg_ws + reg_soff + offt / (1 << 5)], reg_store_mask.cvt8());
+ vblendvps(vdst, vzero, vdst, vstore_mask);
+ shl(reg_soff, 5);
+ }
+
+ void fwd_process_relu_avx512_common(Vmm vdst, int offt) {
+ shr(reg_soff, 5);
+ vcmpps(kstore_mask, vzero, vdst, _cmp_lt_os);
+ kmovw(ptr[reg_ws + reg_soff + offt / (1 << 5)], kstore_mask);
+ vblendmps(vdst | kstore_mask, vzero, vdst);
+ shl(reg_soff, 5);
+ }
+
+ void bwd_process_relu_avx2(Vmm vdiff_dst, int offt, Vmm vstore_mask) {
+ shr(reg_soff, 5);
+ vpbroadcastb(vstore_mask, ptr[reg_ws + reg_soff + offt / (1 << 5)]);
+ vpand(vstore_mask, vstore_mask, ptr[rip + l_relu_mask_avx2]);
+ vpcmpeqd(vstore_mask, vstore_mask, ptr[rip + l_relu_mask_avx2]);
+ vblendvps(vdiff_dst, vzero, vdiff_dst, vstore_mask);
+ shl(reg_soff, 5);
+ }
+
+ void bwd_process_relu_avx512_common(Vmm vdiff_dst, int offt) {
+ shr(reg_soff, 5);
+ kmovw(kstore_mask, ptr[reg_ws + reg_soff + offt / (1 << 5)]);
+ vmovups(vdiff_dst | kstore_mask | T_z, vdiff_dst);
+ shl(reg_soff, 5);
+ }
+
+ void uni_vmovups_tail_avx2_common(const Operand &dst,
+ const Operand &src, Label &l_ret) {
+ if (dst.isMEM()) {
+ vmaskmovps(dst.getAddress(), vtail_mask, Vmm(src.getIdx()));
+ } else {
+ vmaskmovps(Vmm(dst.getIdx()), vtail_mask, src.getAddress());
+ }
+ jmp(l_ret);
+ }
+
+ void uni_vmovups_tail_avx512_common(const Operand &dst,
+ const Operand &src, Label &l_ret) {
+ if (dst.isMEM())
+ uni_vmovups(dst.getAddress() | ktail_mask | T_z, Vmm(src.getIdx()));
+ else
+ uni_vmovups(Vmm(dst.getIdx()) | ktail_mask | T_z, src.getAddress());
+
+ jmp(l_ret);
+ }
+
+ void uni_vmovups_maybe_tail(const Operand &dst, const Operand &src) {
+ Label l_no_mask, l_ret;
+
+ if (is_c_padded()) {
+ mov(reg_tmp, ptr[rsp + stack_off_is_cblk_tail]);
+ cmp(reg_tmp, 0);
+ jz(l_no_mask);
+
+ lea(reg_tmp, ptr[reg_coff + vlen]);
+ cmp(reg_tmp, reg_coff_max);
+ jl(l_no_mask);
+ assert(isa == avx512_common || isa == avx2);
+ if (isa == avx512_common)
+ uni_vmovups_tail_avx512_common(dst, src, l_ret);
+ else if (isa == avx2)
+ uni_vmovups_tail_avx2_common(dst, src, l_ret);
+ }
+ L(l_no_mask);
+ if (dst.isMEM())
+ uni_vmovups(dst.getAddress(), Vmm(src.getIdx()));
+ else
+ uni_vmovups(Vmm(dst.getIdx()), src.getAddress());
+
+ L(l_ret);
+ }
+
+ void barrier() {
+ mov(reg_nnthr, ptr[rsp + stack_off_N_nthr]);
+ mov(reg_bar, ptr[rsp + stack_off_barrier]);
+ simple_barrier::generate(*this, reg_bar, reg_nnthr);
+ }
+
+ Address mean_ptr(size_t offt = 0) {
+ return vmmword[reg_mean + reg_coff + offt + 0 * chan_data_offt];
+ }
+
+ Address var_ptr(size_t offt = 0) {
+ return vmmword[reg_var + reg_coff + offt + 0 * chan_data_offt];
+ }
+
+ Address diff_gamma_ptr(size_t offt = 0) {
+ return vmmword[reg_diff_scale_shift + reg_coff + offt
+ + 0 * chan_data_offt];
+ }
+
+ Address diff_beta_ptr(size_t offt = 0) {
+ return vmmword[reg_diff_scale_shift + reg_coff + offt
+ + 1 * chan_data_offt];
+ }
+
+ Address gamma_ptr(size_t offt = 0) {
+ return vmmword[reg_scale_shift + reg_coff + offt + 0 * chan_data_offt];
+ }
+
+ Address beta_ptr(size_t offt = 0) {
+ return vmmword[reg_scale_shift + reg_coff + offt + 1 * chan_data_offt];
+ }
+
+ template <typename init_t, typename body_t, typename fini_t>
+ void spat_loop(size_t len, size_t blocks, size_t regs,
+ init_t init, body_t body, fini_t fini) {
+ size_t factor = regs * blocks;
+ size_t loop_unroll = len / factor * factor;
+ size_t loop_tail = len - loop_unroll;
+ size_t num_active_regs = (len < regs) ? len : regs;
+ for (size_t i = 0; i < num_active_regs; i++)
+ init(i);
+ if (loop_unroll) {
+ if (is_spatial_thr_) {
+ mov(reg_ctr, ptr[rsp + stack_off_spat_size_loc]);
+ add(reg_soff, ptr[rsp + stack_off_s_s]);
+ } else {
+ mov(reg_ctr, loop_unroll);
+ }
+ Label label;
+ L(label); {
+ for (size_t i = 0; i < factor; i++) {
+ size_t base_reg = i % regs;
+ body(base_reg, i);
+ }
+ add(reg_soff, factor * vlen);
+ sub(reg_ctr, factor);
+ jnz(label);
+ }
+ if (is_spatial_thr_) {
+ add(reg_soff, ptr[rsp + stack_off_s_tail]);
+ }
+ }
+
+ for (size_t i = 0; i < loop_tail; i++) {
+ size_t base_reg = i % regs;
+ body(base_reg, i);
+ }
+ if (loop_tail)
+ add(reg_soff, loop_tail * vlen);
+
+ for (size_t i = 0; i < num_active_regs; i++)
+ fini(i);
+ }
+
+ void mean_channels() {
+ Label ch_label;
+ L(ch_label); {
+ uni_vmovups(Vmm(0), vmmword[reg_rbuf1 + reg_coff]);
+ spat_loop(spat_size, unroll_blocks,
+ unroll_regs,
+ [=](size_t base_reg) {
+ Vmm v = Vmm(base_reg * 2);
+ if (base_reg)
+ uni_vpxor(v, v, v);
+ },
+ [=](size_t base_reg, size_t i) {
+ Vmm v0 = Vmm(base_reg * 2 + 0);
+ Vmm v1 = Vmm(base_reg * 2 + 1);
+ size_t offt = i * vlen;
+ uni_vmovups(v1,
+ vmmword[reg_src + reg_soff + offt]);
+ uni_vaddps(v0, v0, v1);
+ mic_prefetcht0(ptr[reg_src + reg_soff + offt
+ + t0_pf_offt]);
+ mic_prefetcht1(ptr[reg_src + reg_soff + offt
+ + t1_pf_offt]);
+ },
+ [=](size_t base_reg) {
+ Vmm b = Vmm(0);
+ Vmm v = Vmm(base_reg * 2);
+ if (base_reg)
+ uni_vaddps(b, b, v);
+ });
+ uni_vmovups(vmmword[reg_rbuf1 + reg_coff], Vmm(0));
+
+ add(reg_coff, vlen);
+ cmp(reg_coff, reg_coff_max);
+ jl(ch_label);
+ }
+ }
+
+ void var_channels() {
+ Label ch_label;
+ L(ch_label); {
+ uni_vmovups_maybe_tail(vmean, mean_ptr());
+ uni_vmovups(Vmm(0), vmmword[reg_rbuf1 + reg_coff]);
+ spat_loop(spat_size, unroll_blocks, unroll_regs,
+ [=](size_t base_reg) {
+ Vmm v = Vmm(base_reg * 3);
+ if (base_reg > 0)
+ uni_vpxor(v, v, v);
+ },
+ [=](size_t base_reg, size_t i) {
+ Vmm v = Vmm(3 * base_reg);
+ Vmm vtmp0 = Vmm(3 * base_reg + 1);
+ Vmm vtmp1 = Vmm(3 * base_reg + 2);
+ size_t offt = i * vlen;
+ uni_vmovups(vtmp0,
+ vmmword[reg_src + reg_soff + offt]);
+ if (isa == sse42) {
+ movups(vtmp1, vmean);
+ subps(vtmp1, vtmp0);
+ } else {
+ vsubps(vtmp1, vmean, vtmp0);
+ }
+ uni_vfmadd231ps(v, vtmp1, vtmp1);
+
+ mic_prefetcht0(ptr[reg_src + reg_soff + offt
+ + t0_pf_offt]);
+ mic_prefetcht1(ptr[reg_src + reg_soff + offt
+ + t1_pf_offt]);
+ },
+ [=](size_t base_reg) {
+ Vmm b = Vmm(0);
+ Vmm v = Vmm(base_reg * 3);
+ if (base_reg)
+ uni_vaddps(b, b, v);
+ });
+ uni_vmovups(vmmword[reg_rbuf1 + reg_coff], Vmm(0));
+ add(reg_coff, vlen);
+ cmp(reg_coff, reg_coff_max);
+ jl(ch_label);
+ }
+ }
+
+ void compute_mean_variance() {
+ uni_vpxor(Vmm(0), Vmm(0), Vmm(0));
+ xor_(reg_coff, reg_coff);
+ Label zero_rbuf;
+ L(zero_rbuf); {
+ uni_vmovups(vmmword[reg_rbuf1 + reg_coff], Vmm(0));
+ add(reg_coff, isa == sse42 ? vlen / 2 : vlen);
+ cmp(reg_coff, reg_coff_max);
+ jne(zero_rbuf);
+ }
+
+ mov(reg_src, ptr[rsp + stack_off_src]);
+
+ xor_(reg_soff, reg_soff);
+ Label mean_spatial;
+ L(mean_spatial); {
+ xor_(reg_coff, reg_coff);
+
+ if (isa == sse42)
+ mov(reg_tmp_off, reg_soff);
+
+ mean_channels();
+
+ if (isa == sse42) {
+ mov(reg_soff, reg_tmp_off);
+ add(reg_src, vlen / 2);
+ mov(reg_coff, vlen / 2);
+
+ mean_channels();
+
+ sub(reg_src, vlen / 2);
+ }
+
+ add(reg_soff, reg_mb_stride_Bc);
+ cmp(reg_soff, reg_soff_max);
+ jne(mean_spatial);
+ }
+
+ Label no_mean_reduction;
+ barrier(); {
+ mov(reg_tmp, ptr[rsp + stack_off_N_ithr]);
+ cmp(reg_tmp, 0);
+ jne(no_mean_reduction);
+ mov(reg_nnthr, ptr[rsp + stack_off_N_nthr]);
+ xor_(reg_coff, reg_coff);
+ Label mean_reduction_channels;
+ L(mean_reduction_channels); {
+ mov(reg_roff, reg_coff);
+ uni_vpxor(Vmm(0), Vmm(0), Vmm(0));
+ uni_vpxor(Vmm(1), Vmm(1), Vmm(1));
+ mov(reg_ctr, reg_nnthr);
+ Label mean_reduction_thrs;
+ L(mean_reduction_thrs); {
+ uni_vaddps(Vmm(1), Vmm(1), vmmword[reg_rbuf1 + reg_roff]);
+ uni_vmovups(vmmword[reg_rbuf1 + reg_roff], Vmm(0));
+ add(reg_roff, reg_coff_max);
+ sub(reg_ctr, 1);
+ jnz(mean_reduction_thrs);
+ }
+ uni_vdivps(Vmm(1), Vmm(1), vchan_size);
+ uni_vmovups_maybe_tail(mean_ptr(), Vmm(1));
+
+ add(reg_coff, isa == sse42 ? vlen / 2 : vlen);
+
+ cmp(reg_coff, reg_coff_max);
+ jne(mean_reduction_channels);
+ }
+ }
+ L(no_mean_reduction);
+ barrier();
+
+ xor_(reg_soff, reg_soff);
+ Label var_spatial;
+ L(var_spatial); {
+ xor_(reg_coff, reg_coff);
+
+ if (isa == sse42)
+ mov(reg_tmp_off, reg_soff);
+
+ var_channels();
+
+ if (isa == sse42) {
+ mov(reg_soff, reg_tmp_off);
+ add(reg_src, vlen / 2);
+ mov(reg_coff, vlen / 2);
+
+ var_channels();
+
+ sub(reg_src, vlen / 2);
+ }
+
+ add(reg_soff, reg_mb_stride_Bc);
+ cmp(reg_soff, reg_soff_max);
+ jne(var_spatial);
+ }
+
+ Label no_var_reduction;
+ barrier(); {
+ mov(reg_tmp, ptr[rsp + stack_off_N_ithr]);
+ cmp(reg_tmp, 0);
+ jne(no_var_reduction);
+
+ mov(reg_nnthr, ptr[rsp + stack_off_N_nthr]);
+ xor_(reg_coff, reg_coff);
+ Label var_reduction_channels;
+ L(var_reduction_channels); {
+ mov(reg_roff, reg_coff);
+ uni_vpxor(Vmm(1), Vmm(1), Vmm(1));
+ mov(reg_ctr, reg_nnthr);
+ Label var_reduction_thrs;
+ L(var_reduction_thrs); { // TODO: unroll (?)
+ uni_vaddps(Vmm(1), Vmm(1), vmmword[reg_rbuf1 + reg_roff]);
+ add(reg_roff, reg_coff_max);
+ sub(reg_ctr, 1);
+ jnz(var_reduction_thrs);
+ }
+ uni_vdivps(Vmm(1), Vmm(1), vchan_size);
+ uni_vmovups_maybe_tail(var_ptr(), Vmm(1));
+ add(reg_coff, isa == sse42 ? vlen / 2 : vlen);
+
+ cmp(reg_coff, reg_coff_max);
+ jne(var_reduction_channels);
+ }
+ }
+ L(no_var_reduction);
+ barrier();
+ }
+
+ void forward_channels() {
+ Label ch_label;
+ L(ch_label); {
+ uni_vmovups_maybe_tail(vmean, mean_ptr());
+ uni_vmovups_maybe_tail(vsqrtvar, var_ptr());
+ uni_vaddps(vsqrtvar, vsqrtvar, veps);
+ uni_vsqrtps(vsqrtvar, vsqrtvar);
+
+ if (bdesc_->use_scaleshift()) {
+ uni_vmovups_maybe_tail(vgamma, gamma_ptr());
+ uni_vmovups_maybe_tail(vbeta, beta_ptr());
+ }
+
+ Vmm vscale = bdesc_->use_scaleshift() ? vgamma : vone;
+ Vmm vdiv = bdesc_->use_scaleshift() ? vgamma : vsqrtvar;
+
+ if (isa == sse42) {
+ movups(vbuf, vscale);
+ divps(vbuf, vsqrtvar);
+ movups(vdiv, vbuf);
+ } else {
+ vdivps(vdiv, vscale, vsqrtvar);
+ }
+
+ auto compute = [=](bool output_is_aligned) {
+ spat_loop(spat_size, unroll_blocks, unroll_regs,
+ [](size_t base_reg) {UNUSED(base_reg);},
+ [=](size_t base_reg, size_t i) {
+ Vmm v = Vmm(base_reg);
+ size_t offt = i * vlen;
+ uni_vmovups(v,
+ vmmword[reg_src + reg_soff + offt]);
+ mic_prefetcht0(ptr[reg_src + reg_soff + offt
+ + t0_pf_offt]);
+ mic_prefetcht1(ptr[reg_src + reg_soff + offt
+ + t1_pf_offt]);
+ uni_vsubps(v, v, vmean);
+ if (bdesc_->use_scaleshift()) {
+ uni_vfmadd213ps(v, vgamma, vbeta);
+ } else {
+ uni_vmulps(v, v, vsqrtvar);
+ }
+ if (with_relu_inf_only) {
+ uni_vmaxps(v, v, vzero);
+ } else if (with_relu) {
+ if (isa == avx512_common)
+ fwd_process_relu_avx512_common(v, offt);
+ else
+ fwd_process_relu_avx2(v, offt, Vmm(3));
+ }
+ if (output_is_aligned) {
+ uni_vmovntps(
+ vmmword[reg_dst + reg_soff + offt], v);
+ } else {
+ uni_vmovups(
+ vmmword[reg_dst + reg_soff + offt], v);
+ }
+ },
+ [](size_t base_reg) {UNUSED(base_reg);});
+ };
+
+ Label unaligned_store, end_store;
+ test(reg_dst, vlen - 1);
+ jnz(unaligned_store, T_NEAR);
+ compute(true);
+ jmp(end_store, T_NEAR);
+ L(unaligned_store); {
+ compute(false);
+ }
+ L(end_store);
+
+ add(reg_coff, vlen);
+ cmp(reg_coff, reg_coff_max);
+ jl(ch_label);
+ }
+ }
+
+ void forward() {
+ mov(reg_src, ptr[rsp + stack_off_src]);
+ mov(reg_dst, ptr[rsp + stack_off_dst]);
+ mov(reg_ws, ptr[rsp + stack_off_ws]);
+
+ xor_(reg_soff, reg_soff);
+ Label dst_spatial;
+ L(dst_spatial); {
+ xor_(reg_coff, reg_coff);
+ if (isa == sse42)
+ mov(reg_tmp_off, reg_soff);
+
+ forward_channels();
+
+ if (isa == sse42) {
+ mov(reg_soff, reg_tmp_off);
+ add(reg_src, vlen / 2);
+ add(reg_dst, vlen / 2);
+ mov(reg_coff, vlen / 2);
+
+ forward_channels();
+
+ sub(reg_src, vlen / 2);
+ sub(reg_dst, vlen / 2);
+ }
+
+ add(reg_soff, reg_mb_stride_Bc);
+ cmp(reg_soff, reg_soff_max);
+ jnz(dst_spatial);
+ }
+ }
+
+ void backward_sh_channels() {
+ Label sh_channels;
+ L(sh_channels); {
+ uni_vmovups_maybe_tail(vmean, mean_ptr());
+ uni_vmovups(Vmm(0), vmmword[reg_rbuf1 + reg_coff]);
+ uni_vmovups(Vmm(1), vmmword[reg_rbuf2 + reg_coff]);
+ spat_loop(spat_size, 1, 1,
+ [=](size_t base_reg) {
+ if (base_reg > 0) {
+ for (int i = 0; i < 2; i++) {
+ Vmm v(base_reg * 5 + i);
+ uni_vpxor(v, v, v);
+ }
+ }
+ },
+ [=](size_t base_reg, size_t i) {
+ Vmm o0 = Vmm(base_reg * 5 + 0);
+ Vmm o1 = Vmm(base_reg * 5 + 1);
+ Vmm t1 = Vmm(base_reg * 5 + 2);
+ Vmm t2 = Vmm(base_reg * 5 + 3);
+ Vmm t3 = Vmm(base_reg * 5 + 4);
+ size_t offt = i * vlen;
+ uni_vmovups(t1, vmmword[reg_src + reg_soff + offt]);
+ uni_vmovups(t2, vmmword[reg_diff_dst + reg_soff
+ + offt]);
+ if (with_relu) {
+ if (isa == avx512_common)
+ bwd_process_relu_avx512_common(t2, offt);
+ else if (isa == avx2)
+ bwd_process_relu_avx2(t2, offt, t3);
+ else
+ assert(false);
+ }
+ uni_vsubps(t3, vmean, t1, t3);
+ if (isa == sse42) {
+ mulps(t3, t2);
+ subps(o0, t3);
+ } else {
+ vfnmadd231ps(o0, t3, t2);
+ }
+ uni_vaddps(o1, o1, t2);
+ mic_prefetcht0(ptr[reg_diff_dst + reg_soff + offt
+ + t0_pf_offt]);
+ mic_prefetcht0(ptr[reg_src + reg_soff + offt
+ + t0_pf_offt]);
+ mic_prefetcht1(ptr[reg_diff_dst + reg_soff + offt
+ + t1_pf_offt]);
+ mic_prefetcht1(ptr[reg_src + reg_soff + offt
+ + t1_pf_offt]);
+ },
+ [=](size_t base_reg) {
+ Vmm b0 = Vmm(0);
+ Vmm b1 = Vmm(1);
+ if (base_reg) {
+ uni_vaddps(b0, b0, Vmm(base_reg * 5 + 0));
+ uni_vaddps(b1, b1, Vmm(base_reg * 5 + 1));
+ }
+ });
+ uni_vmovups(vmmword[reg_rbuf1 + reg_coff], Vmm(0));
+ uni_vmovups(vmmword[reg_rbuf2 + reg_coff], Vmm(1));
+ add(reg_coff, vlen);
+ cmp(reg_coff, reg_coff_max);
+ jl(sh_channels);
+ }
+ }
+
+ void backward_diff_channels() {
+ Label diff_channels;
+ L(diff_channels); {
+ uni_vmovups_maybe_tail(vmean, mean_ptr());
+ uni_vmovups_maybe_tail(vsqrtvar, var_ptr());
+ uni_vaddps(vsqrtvar, vsqrtvar, veps);
+ uni_vsqrtps(vsqrtvar, vsqrtvar);
+ uni_vdivps(vsqrtvar, vone, vsqrtvar, vbuf);
+ if (bdesc_->use_scaleshift())
+ uni_vmovups_maybe_tail(vgamma, gamma_ptr());
+ uni_vmovups_maybe_tail(vdiff_gamma, diff_gamma_ptr());
+ uni_vmovups_maybe_tail(vdiff_beta, diff_beta_ptr());
+ uni_vmulps(vdiff_gamma, vdiff_gamma, vsqrtvar);
+ uni_vdivps(vdiff_beta, vdiff_beta, vchan_size);
+ uni_vdivps(vdiff_gamma, vdiff_gamma, vchan_size);
+
+ auto compute = [=](bool output_is_aligned) {
+ spat_loop(spat_size, unroll_blocks, unroll_regs,
+ [=](size_t base_reg) {UNUSED(base_reg);},
+ [=](size_t base_reg, size_t i) {
+ Vmm v(base_reg * 2 + 0);
+ Vmm t(base_reg * 2 + 1);
+ Vmm t1(base_reg * 2 + 2);
+ size_t offt = i * vlen;
+ uni_vmovups(v, vmmword[reg_diff_dst + reg_soff
+ + offt]);
+ if (with_relu) {
+ if (isa == avx512_common)
+ bwd_process_relu_avx512_common(v, offt);
+ else if (isa == avx2)
+ bwd_process_relu_avx2(v, offt, t);
+ else
+ assert(false);
+ }
+ if (!bdesc_->use_global_stats()) {
+ uni_vsubps(v, v, vdiff_beta);
+ uni_vmovups(t, vmmword[reg_src + reg_soff
+ + offt]);
+ uni_vsubps(t, vmean, t, t1);
+ uni_vmulps(t, t, vdiff_gamma);
+ uni_vaddps(v, v, t);
+ }
+ uni_vmulps(v, v, vsqrtvar);
+ if (bdesc_->use_scaleshift()) {
+ uni_vmulps(v, v, vgamma);
+ }
+ if (output_is_aligned) {
+ uni_vmovntps(
+ vmmword[reg_diff_src + reg_soff + offt],
+ v);
+ } else {
+ uni_vmovups(
+ vmmword[reg_diff_src + reg_soff + offt],
+ v);
+ }
+ mic_prefetcht0(ptr[reg_diff_dst + reg_soff + offt
+ + t0_pf_offt]);
+ mic_prefetcht0(ptr[reg_src + reg_soff + offt
+ + t0_pf_offt]);
+ mic_prefetcht1(ptr[reg_diff_dst + reg_soff
+ + offt + t1_pf_offt]);
+ mic_prefetcht1(ptr[reg_src + reg_soff + offt
+ + t1_pf_offt]);
+ },
+ [=](size_t base_reg) {UNUSED(base_reg);});
+ };
+
+ Label unaligned_store, end_store;
+ test(reg_diff_src, vlen - 1);
+ jnz(unaligned_store, T_NEAR);
+ compute(true);
+ jmp(end_store, T_NEAR);
+ L(unaligned_store); {
+ compute(false);
+ }
+ L(end_store);
+
+ add(reg_coff, vlen);
+ cmp(reg_coff, reg_coff_max);
+ jl(diff_channels);
+ }
+ }
+
+ void backward() {
+ uni_vpxor(Vmm(0), Vmm(0), Vmm(0));
+ xor_(reg_coff, reg_coff);
+ Label zero_rbuf, sh_spatial;
+
+ L(zero_rbuf); {
+ uni_vmovups(vmmword[reg_rbuf1 + reg_coff], Vmm(0));
+ uni_vmovups(vmmword[reg_rbuf2 + reg_coff], Vmm(0));
+ add(reg_coff, isa == sse42 ? vlen / 2 : vlen);
+ cmp(reg_coff, reg_coff_max);
+ jne(zero_rbuf);
+ }
+
+ mov(reg_src, ptr[rsp + stack_off_src]);
+ mov(reg_diff_dst, ptr[rsp + stack_off_diff_dst]);
+ if (with_relu) {
+ assert(isa == avx2 || isa == avx512_common);
+ mov(reg_ws, ptr[rsp + stack_off_ws]);
+ }
+
+ xor_(reg_soff, reg_soff);
+ L(sh_spatial); {
+ xor_(reg_coff, reg_coff);
+ if (isa == sse42) {
+ mov(reg_tmp_off, reg_soff);
+ }
+ backward_sh_channels();
+ if (isa == sse42) {
+ mov(reg_soff, reg_tmp_off);
+ add(reg_diff_dst, vlen / 2);
+ add(reg_src, vlen / 2);
+ mov(reg_coff, vlen / 2);
+ backward_sh_channels();
+ sub(reg_diff_dst, vlen / 2);
+ sub(reg_src, vlen / 2);
+ }
+ add(reg_soff, reg_mb_stride_Bc);
+ cmp(reg_soff, reg_soff_max);
+ jne(sh_spatial);
+ }
+
+ mov(reg_diff_scale_shift, ptr[rsp + stack_off_diff_scale_shift]);
+
+ Label no_sh_reduction;
+ barrier(); {
+ mov(reg_tmp, ptr[rsp + stack_off_N_ithr]);
+ cmp(reg_tmp, 0);
+ Label sh_reduction_channels;
+ jne(no_sh_reduction, T_NEAR);
+
+ mov(reg_nnthr, ptr[rsp + stack_off_N_nthr]);
+ xor_(reg_coff, reg_coff);
+ L(sh_reduction_channels); {
+ mov(reg_roff, reg_coff);
+ uni_vpxor(Vmm(0), Vmm(0), Vmm(0));
+ uni_vpxor(Vmm(1), Vmm(1), Vmm(1));
+ uni_vmovups_maybe_tail(vsqrtvar, var_ptr());
+ uni_vaddps(vsqrtvar, vsqrtvar, veps);
+ uni_vsqrtps(vsqrtvar, vsqrtvar);
+ uni_vdivps(vsqrtvar, vone, vsqrtvar, vbuf);
+ mov(reg_ctr, reg_nnthr);
+ Label sh_reduction_thrs;
+ L(sh_reduction_thrs); { // TODO: unroll (?)
+ uni_vaddps(Vmm(0), Vmm(0), vmmword[reg_rbuf1 + reg_roff]);
+ uni_vaddps(Vmm(1), Vmm(1), vmmword[reg_rbuf2 + reg_roff]);
+ add(reg_roff, reg_coff_max);
+ sub(reg_ctr, 1);
+ jnz(sh_reduction_thrs);
+ }
+ uni_vmulps(Vmm(0), Vmm(0), vsqrtvar);
+ uni_vmovups_maybe_tail(diff_gamma_ptr(), Vmm(0));
+ uni_vmovups_maybe_tail(diff_beta_ptr(), Vmm(1));
+ add(reg_coff, isa == sse42 ? vlen / 2 : vlen);
+ cmp(reg_coff, reg_coff_max);
+ jne(sh_reduction_channels);
+ }
+ }
+ L(no_sh_reduction);
+ barrier();
+
+ mov(reg_diff_src, ptr[rsp + stack_off_diff_src]);
+ if (with_relu) {
+ assert(isa == avx2 || isa == avx512_common);
+ mov(reg_ws, ptr[rsp + stack_off_ws]);
+ }
+
+ xor_(reg_soff, reg_soff);
+ Label diff_spatial;
+ L(diff_spatial); {
+ xor_(reg_coff, reg_coff);
+ if (isa == sse42) {
+ mov(reg_tmp_off, reg_soff);
+ }
+ backward_diff_channels();
+ if (isa == sse42) {
+ mov(reg_soff, reg_tmp_off);
+ add(reg_diff_dst, vlen / 2);
+ add(reg_diff_src, vlen / 2);
+ add(reg_src, vlen / 2);
+ mov(reg_coff, vlen / 2);
+ backward_diff_channels();
+ sub(reg_diff_dst, vlen / 2);
+ sub(reg_diff_src, vlen / 2);
+ sub(reg_src, vlen / 2);
+ }
+ add(reg_soff, reg_mb_stride_Bc);
+ cmp(reg_soff, reg_soff_max);
+ jne(diff_spatial);
+ }
+ }
+
+ jit_bnorm_t(const batch_normalization_pd_t *bdesc): bdesc_(bdesc) {
+ static_assert(isa == sse42 || isa == avx2 || isa == avx512_common
+ || isa == avx512_mic, "unsupported isa");
+
+ const int simd_w = isa == sse42 ? 8 :
+ cpu_isa_traits<isa>::vlen / sizeof(data_t);
+ is_spatial_thr_ =
+ bnorm_utils::is_spatial_thr(bdesc_, simd_w, sizeof(data_t));
+
+ unroll_blocks = isa == avx512_common && !is_spatial_thr_ ? 4 : 1;
+ unroll_regs = isa == avx512_common && !is_spatial_thr_ ? 4 : 1;
+
+ preamble();
+
+ if (isa == avx512_common)
+ prepare_tail_mask_avx512_common();
+ else if (isa == avx2)
+ prepare_tail_mask_avx2_common();
+
+ compute_static_strides();
+ sub(rsp, stack_size_required);
+ load_common_params();
+ prepare_relu();
+
+ if (bdesc_->is_fwd()) {
+ if (!bdesc_->stats_is_src()) {
+ compute_mean_variance();
+ }
+ forward();
+ } else {
+ backward();
+ }
+ add(rsp, stack_size_required);
+ postamble();
+
+ ker = reinterpret_cast<decltype(ker)>(const_cast<uint8_t*>(
+ this->getCode()));
+ }
+};
+
+template <cpu_isa_t isa>
+struct uni_bnorm_driver_t: public c_compatible {
+ uni_bnorm_driver_t(const batch_normalization_pd_t *bdesc)
+ : bdesc_(bdesc), ker_(bdesc_)
+ {
+ const int nthrs = mkldnn_get_max_threads();
+ const dim_t C_PADDED = get_c_padded(bdesc_);
+
+ size_t data_size = sizeof(data_t) * bdesc_->MB() * C_PADDED
+ * bdesc_->D() * bdesc_->H() * bdesc_->W();
+ l3_size_ = get_cache_size(3, true) * nthrs / 2;
+ do_blocking_ = (data_size >= l3_size_ / 2 && l3_size_ > 0);
+ }
+
+ ~uni_bnorm_driver_t() {}
+
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const batch_normalization_pd_t *bdesc) {
+ int nthrs = mkldnn_get_max_threads();
+ dim_t C_PADDED = get_c_padded(bdesc);
+
+ int sbuf_sz = use_tmp_stats(bdesc) * 2 * C_PADDED;
+ int pbuf_sz = use_tmp_diff_scale_shift(bdesc) * 2 * C_PADDED;
+ int rbuf_sz = (bdesc->is_fwd() ? 1 : 2) * C_PADDED * nthrs;
+
+ scratchpad.book(key_bnorm_tmp_stats, sizeof(data_t) * sbuf_sz);
+ scratchpad.book(key_bnorm_tmp_diff_ss, sizeof(data_t) * pbuf_sz);
+ scratchpad.book(key_bnorm_reduction, sizeof(data_t) * rbuf_sz);
+
+ if (mkldnn_thr_syncable()) {
+ int n_barriers = C_PADDED / simd_w;
+ scratchpad.book(key_barrier, sizeof(barrier::ctx_t) * n_barriers);
+ }
+ }
+
+ void exec(int ithr, int nthr, const data_t *src, data_t *diff_src,
+ data_t *dst, const data_t *diff_dst, const data_t *scale_shift,
+ data_t *diff_scale_shift, const data_t *mean, const data_t *var,
+ const uint8_t *ws, const memory_tracking::grantor_t &scratchpad) {
+ auto sbuf = scratchpad.get<data_t>(key_bnorm_tmp_stats);
+ auto pbuf = scratchpad.get<data_t>(key_bnorm_tmp_diff_ss);
+ auto rbuf = scratchpad.get<data_t>(key_bnorm_reduction);
+ auto barriers = scratchpad.get<barrier::ctx_t>(key_barrier);
+
+ dim_t N = bdesc_->MB();
+ dim_t C = bdesc_->C();
+ dim_t C_PADDED = get_c_padded(bdesc_);
+ dim_t D = bdesc_->D();
+ dim_t H = bdesc_->H();
+ dim_t W = bdesc_->W();
+ dim_t SP = D * H * W;
+ dim_t img_size = C_PADDED * D * H * W;
+ const int vlen = isa == sse42 ? 32 : cpu_isa_traits<isa>::vlen;
+
+ typename jit_bnorm_t<isa>::call_params_t p;
+
+ p.eps = bdesc_->desc()->batch_norm_epsilon;
+ p.one = 1.0f;
+ p.spat_size = D * H * W;
+ p.chan_size = 1.0f * N * p.spat_size;
+
+ dim_t C_blks = C_PADDED / simd_w;
+
+ int C_ithr{0}, C_nthr{0}, N_ithr{0}, N_nthr{0}, S_ithr{0}, S_nthr{0};
+ dim_t C_blk_s{0}, C_blk_e{0}, N_s{0}, N_e{0}, S_s{0}, S_e{0};
+
+ dim_t C_blks_per_iter{ 1 };
+ int64_t iters{ 1 };
+ if (do_blocking_) {
+ int num_tensors = bdesc_->is_fwd() ? 1 : 2;
+ size_t working_set_size
+ = (N * D * H * W * simd_w * sizeof(data_t)) * num_tensors;
+ bnorm_utils::cache_balance(working_set_size, C_blks,
+ C_blks_per_iter, iters);
+ }
+
+ bool spatial_thr_allowed = bnorm_utils::thread_balance(do_blocking_,
+ true, ithr, nthr, N, do_blocking_ ? C_blks_per_iter : C_blks,
+ SP, C_ithr, C_nthr, C_blk_s, C_blk_e, N_ithr, N_nthr, N_s, N_e,
+ S_ithr, S_nthr, S_s, S_e);
+
+ int SP_N_ithr = N_ithr * S_nthr + S_ithr;
+ int SP_N_nthr = N_nthr * S_nthr;
+ assert(IMPLICATION(!mkldnn_thr_syncable(), SP_N_nthr == 1));
+
+ p.N_ithr = SP_N_ithr;
+ p.N_nthr = SP_N_nthr;
+
+ int last_iter_blks = C_blks - (iters - 1) * C_blks_per_iter;
+ int global_C_blk_s;
+ int global_barriers_per_iter = C_nthr;
+
+ for (int64_t it = 0; it < iters; it++) {
+ if (it == iters - 1 && iters > 1) {
+ C_blk_s = C_blk_e = N_s = N_e = 0;
+ spatial_thr_allowed = bnorm_utils::thread_balance(do_blocking_,
+ spatial_thr_allowed, ithr, nthr, N, last_iter_blks, SP,
+ C_ithr, C_nthr, C_blk_s, C_blk_e, N_ithr, N_nthr, N_s,
+ N_e, S_ithr, S_nthr, S_s, S_e);
+
+ // Update call parameters for JIT, last iteration
+ p.N_ithr = N_ithr * S_nthr + S_ithr;
+ p.N_nthr = N_nthr * S_nthr;
+ }
+
+ global_C_blk_s = do_blocking_ ?
+ (C_blk_s == -1) ? -1 : it * C_blks_per_iter + C_blk_s :
+ C_blk_s;
+
+ int C_blks_thr = C_blk_e - C_blk_s;
+ int N_thr = N_e - N_s;
+
+ size_t coff_base = global_C_blk_s * simd_w;
+ size_t soff_base
+ = global_C_blk_s * p.spat_size * simd_w + N_s * img_size;
+
+ p.spat_size_loc = S_e - S_s;
+ p.S_s = S_s * vlen;
+ p.S_tail = (p.spat_size - S_e) * vlen;
+ p.coff_max = C_blks_thr * simd_w;
+ p.mean = (use_tmp_stats(bdesc_) ? sbuf : mean) + coff_base;
+ p.var = (use_tmp_stats(bdesc_) ? sbuf + C_PADDED : var) + coff_base;
+ p.scale_shift = scale_shift + coff_base;
+ p.diff_scale_shift = (use_tmp_diff_scale_shift(bdesc_)
+ ? pbuf : diff_scale_shift) + coff_base;
+
+ p.soff_max = N_thr * img_size;
+ p.src = src + soff_base;
+ p.dst = dst + soff_base;
+ p.diff_src = diff_src + soff_base;
+ p.diff_dst = diff_dst + soff_base;
+ p.ws = ws + soff_base / 8;
+
+ p.mb_stride_Bc = img_size - p.coff_max * p.spat_size;
+
+ // use SP_N_nthr which is the same as p.N_nthr except maybe for
+ // the last iteration.
+ p.rbuf1 = rbuf + ((it * C_blks_per_iter) * SP_N_nthr
+ + C_blk_s * p.N_nthr + p.N_ithr * C_blks_thr) * simd_w;
+ // rbuf1 and rbuf2 have to be disjoint
+ p.rbuf2 = p.rbuf1 + C_PADDED * nthr;
+ p.is_cblk_tail = (it * C_blks_per_iter + C_blk_e) * simd_w > C;
+
+ size_t iter_bariers
+ = do_blocking_ ? it * global_barriers_per_iter : 0;
+ p.barrier = barriers + C_ithr + iter_bariers;
+ if (p.soff_max != 0 && p.coff_max != 0)
+ ker_(&p);
+ }
+ }
+
+ void init_barriers(const memory_tracking::grantor_t &scratchpad) {
+ auto barriers = scratchpad.get<barrier::ctx_t>(key_barrier);
+ if (barriers) {
+ const int n_barriers = get_c_padded(bdesc_) / simd_w;
+ for (int i = 0; i < n_barriers; ++i)
+ barrier::ctx_init(&barriers[i]);
+ }
+ }
+
+private:
+ enum {
+ simd_w = isa == sse42 ? 8 : cpu_isa_traits<isa>::vlen / sizeof(data_t)
+ };
+
+ static bool use_tmp_stats(const batch_normalization_pd_t *bdesc) {
+ return true
+ && !bdesc->stats_is_src()
+ && bdesc->desc()->prop_kind == prop_kind::forward_inference;
+ }
+
+ static bool use_tmp_diff_scale_shift(const batch_normalization_pd_t *bdesc)
+ {
+ return false
+ || (bdesc->is_bwd() && !bdesc->use_scaleshift())
+ || bdesc->desc()->prop_kind == prop_kind::backward_data;
+ }
+
+ static dim_t get_c_padded(const batch_normalization_pd_t *bdesc)
+ { return bdesc->src_md()->padded_dims[1]; }
+
+ const batch_normalization_pd_t *bdesc_;
+ bool do_blocking_;
+ size_t l3_size_;
+
+ jit_bnorm_t<isa> ker_;
+};
+
+}
+
+using namespace data_type;
+using namespace format_tag;
+using namespace utils;
+
+/* fwd */
+
+template <cpu_isa_t isa>
+status_t jit_uni_batch_normalization_fwd_t<isa>::pd_t::init() {
+ auto desired_fmt_tag = (ndims() == 4)
+ ? isa == avx512_common ? nChw16c : nChw8c
+ : isa == avx512_common ? nCdhw16c : nCdhw8c;
+
+ bool ok = true
+ && mayiuse(isa)
+ && is_fwd()
+ && !has_zero_dim_memory()
+ && one_of(ndims(), 4, 5)
+ && src_md()->data_type == f32
+ && IMPLICATION(use_scaleshift(), weights_md()->data_type == f32)
+ && memory_desc_matches_tag(*src_md(), desired_fmt_tag)
+ && (attr()->has_default_values() || this->with_relu_post_op());
+ if (!ok) return status::unimplemented;
+
+ if (is_training() && fuse_bn_relu()) {
+ if (isa < avx2) return status::unimplemented;
+ init_default_ws(1);
+ }
+
+ if (memory_desc_wrapper(src_md()).padded_dims()[1] != C()
+ && isa < avx2)
+ return status::unimplemented;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ uni_bnorm_driver_t<isa>::init_scratchpad(scratchpad, this);
+
+ return status::success;
+}
+
+template <cpu_isa_t isa>
+jit_uni_batch_normalization_fwd_t<isa>::jit_uni_batch_normalization_fwd_t(
+ const pd_t *apd): cpu_primitive_t(apd)
+{ bnorm_driver_ = new uni_bnorm_driver_t<isa>(pd()); }
+
+template <cpu_isa_t isa>
+status_t jit_uni_batch_normalization_fwd_t<isa>::execute(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto scale_shift = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SCALE_SHIFT);
+
+ auto mean = pd()->stats_is_src()
+ ? const_cast<data_t *>(CTX_IN_MEM(const data_t *, MKLDNN_ARG_MEAN))
+ : CTX_OUT_MEM(data_t *, MKLDNN_ARG_MEAN);
+ auto var = pd()->stats_is_src()
+ ? const_cast<data_t *>(CTX_IN_MEM(const data_t *, MKLDNN_ARG_VARIANCE))
+ : CTX_OUT_MEM(data_t *, MKLDNN_ARG_VARIANCE);
+
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+ auto ws = CTX_OUT_MEM(uint8_t *, MKLDNN_ARG_WORKSPACE);
+
+ auto scratchpad = this->scratchpad(ctx);
+
+ bnorm_driver_->init_barriers(scratchpad);
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ bnorm_driver_->exec(ithr, nthr, src, nullptr, dst, nullptr,
+ scale_shift, nullptr, mean, var, ws, scratchpad);
+ });
+
+ return status::success;
+}
+
+template <cpu_isa_t isa>
+jit_uni_batch_normalization_fwd_t<isa>::~jit_uni_batch_normalization_fwd_t()
+{ delete bnorm_driver_; }
+
+/* bwd */
+
+template <cpu_isa_t isa>
+status_t jit_uni_batch_normalization_bwd_t<isa>::pd_t::init() {
+ auto desired_fmt_tag = (ndims() == 4)
+ ? one_of(isa, sse42, avx2) ? nChw8c : nChw16c
+ : one_of(isa, sse42, avx2) ? nCdhw8c : nCdhw16c;
+
+ bool ok = true
+ && mayiuse(isa)
+ && is_bwd()
+ && !has_zero_dim_memory()
+ && one_of(ndims(), 4, 5)
+ && everyone_is(f32, src_md()->data_type, diff_src_md()->data_type)
+ && IMPLICATION(use_scaleshift(),
+ utils::everyone_is(f32,
+ weights_md()->data_type,
+ diff_weights_md()->data_type))
+ && memory_desc_matches_tag(*src_md(), desired_fmt_tag)
+ && memory_desc_matches_tag(*diff_src_md(), desired_fmt_tag)
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ if (memory_desc_wrapper(src_md()).padded_dims()[1] != C()
+ && isa < avx2)
+ return status::unimplemented;
+
+ if (fuse_bn_relu()) {
+ if (isa < avx2) return status::unimplemented;
+ init_default_ws(1);
+ if (!compare_ws(hint_fwd_pd_))
+ return status::unimplemented;
+ }
+
+ /* TODO: extra checks required */
+
+ auto scratchpad = scratchpad_registry().registrar();
+ uni_bnorm_driver_t<isa>::init_scratchpad(scratchpad, this);
+
+ return status::success;
+}
+
+template <cpu_isa_t isa>
+jit_uni_batch_normalization_bwd_t<isa>::jit_uni_batch_normalization_bwd_t(
+ const pd_t *apd): cpu_primitive_t(apd)
+{ bnorm_driver_ = new uni_bnorm_driver_t<isa>(pd()); }
+
+template <cpu_isa_t isa>
+status_t jit_uni_batch_normalization_bwd_t<isa>::execute(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto mean = CTX_IN_MEM(const data_t *, MKLDNN_ARG_MEAN);
+ auto var = CTX_IN_MEM(const data_t *, MKLDNN_ARG_VARIANCE);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto scale_shift = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SCALE_SHIFT);
+ auto ws = CTX_IN_MEM(const uint8_t *, MKLDNN_ARG_WORKSPACE);
+
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+ auto diff_scale_shift = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SCALE_SHIFT);
+
+ auto scratchpad = this->scratchpad(ctx);
+
+ bnorm_driver_->init_barriers(scratchpad);
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ bnorm_driver_->exec(ithr, nthr, src, diff_src, nullptr, diff_dst,
+ scale_shift, diff_scale_shift, mean, var, ws, scratchpad);
+ });
+
+ return status::success;
+}
+
+template <cpu_isa_t isa>
+jit_uni_batch_normalization_bwd_t<isa>::~jit_uni_batch_normalization_bwd_t()
+{ delete bnorm_driver_; }
+
+/* struct instantiation */
+template struct jit_uni_batch_normalization_fwd_t<sse42>;
+template struct jit_uni_batch_normalization_bwd_t<sse42>;
+template struct jit_uni_batch_normalization_fwd_t<avx2>;
+template struct jit_uni_batch_normalization_bwd_t<avx2>;
+template struct jit_uni_batch_normalization_fwd_t<avx512_common>;
+template struct jit_uni_batch_normalization_bwd_t<avx512_common>;
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_batch_normalization.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_batch_normalization.hpp
new file mode 100644
index 0000000000..96410ec84e
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_batch_normalization.hpp
@@ -0,0 +1,100 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_UNI_BATCH_NORMALIZATION_HPP
+#define JIT_UNI_BATCH_NORMALIZATION_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_batch_normalization_pd.hpp"
+#include "cpu_isa_traits.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace { template <cpu_isa_t isa> struct uni_bnorm_driver_t; }
+
+template <cpu_isa_t isa>
+struct jit_uni_batch_normalization_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_batch_normalization_fwd_pd_t {
+ pd_t(engine_t *engine, const batch_normalization_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const batch_normalization_fwd_pd_t *hint_fwd_pd)
+ : cpu_batch_normalization_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", isa, ""),
+ jit_uni_batch_normalization_fwd_t<isa>);
+
+ status_t init();
+ };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ jit_uni_batch_normalization_fwd_t(const pd_t *apd);
+ ~jit_uni_batch_normalization_fwd_t();
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override;
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ uni_bnorm_driver_t<isa> *bnorm_driver_;
+};
+
+template <cpu_isa_t isa>
+struct jit_uni_batch_normalization_bwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_batch_normalization_bwd_pd_t {
+ pd_t(engine_t *engine, const batch_normalization_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const batch_normalization_fwd_pd_t *hint_fwd_pd)
+ : cpu_batch_normalization_bwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", isa, ""),
+ jit_uni_batch_normalization_bwd_t<isa>);
+
+ status_t init();
+ };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ jit_uni_batch_normalization_bwd_t(const pd_t *apd);
+ ~jit_uni_batch_normalization_bwd_t();
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override;
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ uni_bnorm_driver_t<isa> *bnorm_driver_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_conv_kernel_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_conv_kernel_f32.cpp
new file mode 100644
index 0000000000..b7dc5f85c5
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_conv_kernel_f32.cpp
@@ -0,0 +1,1302 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+#include "cpu_memory.hpp"
+
+#include "jit_uni_dw_conv_kernel_f32.hpp"
+
+#define GET_OFF(field) offsetof(jit_conv_call_s, field)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::prop_kind;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+
+using namespace Xbyak;
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_fwd_kernel_f32<isa>::load_src(int ur_ch_blocks, int ur_w) {
+ int repeats = isa == sse42 ? 2 : 1;
+ for (int i = 0; i < repeats; i++) {
+ for (int ch = 0; ch < ur_ch_blocks; ch++) {
+ for (int ow = 0; ow < ur_w; ow++) {
+ Vmm vmm_acc = get_acc_reg(i*ur_ch_blocks*ur_w + ch*ur_w + ow);
+
+ int b_off = ch*jcp.ch_block + i*4;
+ if (this->jcp.with_bias)
+ uni_vmovups(vmm_acc,
+ vmmword[reg_bias + b_off*sizeof(float)]);
+ else
+ uni_vpxor(vmm_acc, vmm_acc, vmm_acc);
+
+ int o_off = ch*jcp.oh*jcp.ow*jcp.ch_block
+ + ow*jcp.ch_block + i*4;
+ if (this->jcp.with_sum)
+ uni_vaddps(vmm_acc, vmm_acc,
+ vmmword[reg_output + o_off*sizeof(float)]);
+ }
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_fwd_kernel_f32<isa>::apply_filter(
+ int ur_ch_blocks, int ur_w) {
+ int ch_blk = jcp.ch_block;
+ int dilate_h = jcp.dilate_h + 1;
+ int dilate_w = jcp.dilate_w + 1;
+ int stride_w = jcp.stride_w;
+
+ Label iter_exit_label;
+
+ cmp(reg_kh, 0);
+ je(iter_exit_label, T_NEAR);
+ cmp(reg_kw, 0);
+ je(iter_exit_label, T_NEAR);
+
+ mov(iter_kh, reg_kh);
+ Label kh_label;
+ L(kh_label); {
+ mov(iter_kw, reg_kw);
+ mov(aux1_reg_input, aux_reg_input);
+ mov(aux1_reg_kernel, aux_reg_kernel);
+
+ Label kw_label;
+ L(kw_label); {
+ int repeats = isa == sse42 ? 2 : 1;
+ for (int i = 0; i < repeats; i++) {
+ for (int ch = 0; ch < ur_ch_blocks; ch++) {
+ int ker_off = ch*jcp.kh*jcp.kw*ch_blk + i*4;
+ Vmm vmm_ker = get_ker_reg(0);
+ uni_vmovups(vmm_ker, ptr[aux1_reg_kernel
+ + ker_off*sizeof(float)]);
+
+ for (int ow = 0; ow < ur_w; ow++) {
+ int inp_off = ch*jcp.ih*jcp.iw*ch_blk
+ + ow*stride_w*ch_blk + i*4;
+ Vmm vmm_src = get_src_reg(0);
+ uni_vmovups(vmm_src, ptr[aux1_reg_input
+ + inp_off*sizeof(float)]);
+
+ Vmm vmm_acc = get_acc_reg(i*ur_ch_blocks*ur_w
+ + ch*ur_w + ow);
+ uni_vfmadd231ps(vmm_acc, vmm_src, vmm_ker);
+ }
+ }
+ }
+ add(aux1_reg_kernel, ch_blk*sizeof(float));
+ add(aux1_reg_input, ch_blk*dilate_w*sizeof(float));
+
+ dec(iter_kw);
+ cmp(iter_kw, 0);
+ jg(kw_label, T_NEAR);
+ }
+ add(aux_reg_kernel, jcp.kw*ch_blk*sizeof(float));
+ add(aux_reg_input, jcp.iw*ch_blk*dilate_h*sizeof(float));
+
+ dec(iter_kh);
+ cmp(iter_kh, 0);
+ jg(kh_label, T_NEAR);
+ }
+
+ L(iter_exit_label);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_fwd_kernel_f32<isa>::apply_filter_unrolled(
+ int ur_ch_blocks, int ur_w) {
+ int ch_blk = jcp.ch_block;
+ int dilate_h = jcp.dilate_h + 1;
+ int dilate_w = jcp.dilate_w + 1;
+ int stride_w = jcp.stride_w;
+
+ Label iter_exit_label;
+
+ cmp(reg_kh, 0);
+ je(iter_exit_label, T_NEAR);
+
+ mov(iter_kh, reg_kh);
+ Label kh_label;
+ L(kh_label); {
+ int repeats = isa == sse42 ? 2 : 1;
+ for (int i = 0; i < repeats; i++) {
+ for (int ch = 0; ch < ur_ch_blocks; ch++) {
+ for (int kw = 0; kw < jcp.kw; kw++) {
+ int ker_off = ch*jcp.kh*jcp.kw*ch_blk + kw*ch_blk + i*4;
+
+ Vmm vmm_ker = get_ker_reg(0);
+ uni_vmovups(vmm_ker, ptr[aux_reg_kernel
+ + ker_off*sizeof(float)]);
+
+ for (int ow = 0; ow < ur_w; ow++) {
+ int inp_off = ch*jcp.ih*jcp.iw*ch_blk
+ + ow*stride_w*ch_blk + kw*ch_blk*dilate_w + i*4;
+
+ Vmm vmm_src = get_src_reg(0);
+ uni_vmovups(vmm_src, ptr[aux_reg_input
+ + inp_off*sizeof(float)]);
+
+ Vmm vmm_acc = get_acc_reg(i*ur_ch_blocks*ur_w
+ + ch*ur_w + ow);
+ uni_vfmadd231ps(vmm_acc, vmm_src, vmm_ker);
+ }
+ }
+ }
+ }
+
+ add(aux_reg_kernel, jcp.kw*ch_blk*sizeof(float));
+ add(aux_reg_input, jcp.iw*ch_blk*dilate_h*sizeof(float));
+
+ dec(iter_kh);
+ cmp(iter_kh, 0);
+ jg(kh_label, T_NEAR);
+ }
+
+ L(iter_exit_label);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_fwd_kernel_f32<isa>::apply_activation(
+ int ur_ch_blocks, int ur_w) {
+ if (this->jcp.with_eltwise) {
+ int repeats = isa == sse42 ? 2 : 1;
+ eltwise_injector_->compute_vector_range(4, repeats * ur_w * ur_ch_blocks + 4);
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_fwd_kernel_f32<isa>::store_dst(
+ int ur_ch_blocks, int ur_w) {
+ int ch_blk = jcp.ch_block;
+
+ int repeats = isa == sse42 ? 2 : 1;
+ for (int i = 0; i < repeats; i++) {
+ for (int ch = 0; ch < ur_ch_blocks; ch++) {
+ for (int ow = 0; ow < ur_w; ow++) {
+ int o_off = ch*jcp.oh*jcp.ow*ch_blk + ow*ch_blk + i*4;
+ Vmm vmm_dst = get_acc_reg(i*ur_ch_blocks*ur_w + ch*ur_w + ow);
+
+ uni_vmovups(vmmword[reg_output + o_off*sizeof(float)], vmm_dst);
+ }
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_fwd_kernel_f32<isa>::loop_body(int ur_ch_blocks) {
+ Label unrolled_w_label;
+ Label tail_w_label;
+ Label exit_label;
+
+ L(unrolled_w_label); {
+ int ur_w = jcp.ur_w;
+
+ cmp(reg_ur_w, ur_w);
+ jl(tail_w_label, T_NEAR);
+
+ mov(aux_reg_input, reg_input);
+ mov(aux_reg_kernel, reg_kernel);
+
+ load_src(ur_ch_blocks, ur_w);
+ apply_filter_unrolled(ur_ch_blocks, ur_w);
+ apply_activation(ur_ch_blocks, ur_w);
+ store_dst(ur_ch_blocks, ur_w);
+
+ add(reg_input, sizeof(float) * ur_w * jcp.ch_block * jcp.stride_w);
+ add(reg_output, sizeof(float) * ur_w * jcp.ch_block);
+
+ sub(reg_ur_w, ur_w);
+ jmp(unrolled_w_label);
+ }
+
+ L(tail_w_label); {
+ int ur_w = 1;
+
+ cmp(reg_ur_w, ur_w);
+ jl(exit_label, T_NEAR);
+
+ mov(aux_reg_input, reg_input);
+ mov(aux_reg_kernel, reg_kernel);
+
+ load_src(ur_ch_blocks, ur_w);
+ apply_filter(ur_ch_blocks, ur_w);
+ apply_activation(ur_ch_blocks, ur_w);
+ store_dst(ur_ch_blocks, ur_w);
+
+ add(reg_input, sizeof(float) * ur_w * jcp.ch_block * jcp.stride_w);
+ add(reg_output, sizeof(float) * ur_w * jcp.ch_block);
+
+ sub(reg_ur_w, ur_w);
+ jmp(tail_w_label);
+ }
+
+ L(exit_label);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_fwd_kernel_f32<isa>::generate() {
+ this->preamble();
+
+ mov(reg_input, ptr[this->param1 + GET_OFF(src)]);
+ mov(reg_output, ptr[this->param1 + GET_OFF(dst)]);
+ mov(reg_kernel, ptr[this->param1 + GET_OFF(filt)]);
+ if (jcp.with_bias)
+ mov(reg_bias, ptr[this->param1 + GET_OFF(bias)]);
+ mov(reg_kh, ptr[this->param1 + GET_OFF(kh_padding)]);
+ mov(reg_kw, ptr[this->param1 + GET_OFF(kw_padding)]);
+ mov(reg_ch_blocks, ptr[this->param1 + GET_OFF(ch_blocks)]);
+ mov(reg_ur_w, ptr[this->param1 + GET_OFF(ur_w)]);
+
+ Label ch_blocks_tail_label;
+ Label exit_label;
+
+ int ch_blocks_tail = jcp.nb_ch % jcp.nb_ch_blocking;
+
+ cmp(reg_ch_blocks, jcp.nb_ch_blocking);
+ jne(ch_blocks_tail ? ch_blocks_tail_label : exit_label, T_NEAR);
+
+ loop_body(jcp.nb_ch_blocking); // channel main loop
+
+ if (ch_blocks_tail) {
+ L(ch_blocks_tail_label);
+
+ cmp(reg_ch_blocks, ch_blocks_tail);
+ jne(exit_label, T_NEAR);
+
+ loop_body(ch_blocks_tail); // channel tail loop
+ }
+
+ L(exit_label);
+
+ this->postamble();
+
+ if (jcp.with_eltwise)
+ eltwise_injector_->prepare_table();
+}
+
+template <cpu_isa_t isa>
+bool jit_uni_dw_conv_fwd_kernel_f32<isa>::post_ops_ok(
+ jit_conv_conf_t &jcp, const primitive_attr_t &attr) {
+ const auto &p = attr.post_ops_;
+
+ auto is_eltwise = [&](int idx) { return p.entry_[idx].is_eltwise(); };
+ auto is_sum = [&](int idx) { return p.entry_[idx].is_sum(); };
+
+ switch (p.len_) {
+ case 0: return true; // no post_ops
+ case 1: return is_eltwise(0) || is_sum(0); // sum OR eltwise
+ case 2: return is_sum(0) && is_eltwise(1); // sum -> eltwise
+ default: return false;
+ }
+
+ return false;
+}
+
+template <cpu_isa_t isa>
+status_t jit_uni_dw_conv_fwd_kernel_f32<isa>::init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d, const memory_desc_wrapper &dst_d,
+ const primitive_attr_t &attr)
+{
+ if (!mayiuse(isa)) return status::unimplemented;
+
+ const int simd_w = isa == avx512_common ? 16 : 8;
+
+ jcp.prop_kind = cd.prop_kind;
+
+ const bool with_groups = weights_d.ndims() == src_d.ndims() + 1;
+ if (!with_groups) return status::unimplemented;
+
+ jcp.ngroups = weights_d.dims()[0];
+ jcp.mb = src_d.dims()[0];
+
+ jcp.oc = dst_d.dims()[1];
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = src_d.dims()[1];
+
+ jcp.ih = src_d.dims()[2];
+ jcp.iw = src_d.dims()[3];
+ jcp.oh = dst_d.dims()[2];
+ jcp.ow = dst_d.dims()[3];
+
+ jcp.kh = weights_d.dims()[3];
+ jcp.kw = weights_d.dims()[4];
+
+ jcp.t_pad = cd.padding[0][0];
+ jcp.l_pad = cd.padding[0][1];
+ jcp.b_pad = cd.padding[1][0];
+ jcp.r_pad = cd.padding[1][1];
+
+ jcp.stride_h = cd.strides[0];
+ jcp.stride_w = cd.strides[1];
+
+ jcp.dilate_h = cd.dilates[0];
+ jcp.dilate_w = cd.dilates[1];
+
+ jcp.with_bias = cd.bias_desc.format_kind != format_kind::undef;
+
+ if (!post_ops_ok(jcp, attr))
+ return status::unimplemented;
+
+ const auto &p = attr.post_ops_;
+ jcp.with_sum = p.find(primitive_kind::sum) != -1;
+ const int eltwise_ind = p.find(primitive_kind::eltwise);
+ jcp.with_eltwise = eltwise_ind != -1;
+ if (jcp.with_eltwise)
+ jcp.eltwise = p.entry_[eltwise_ind].eltwise;
+
+ bool ok_to_pad_channels = true
+ && jcp.oc == jcp.ngroups
+ && jcp.ic == jcp.ngroups
+ && one_of(isa, avx512_common, avx2);
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ jcp.ic = rnd_up(jcp.oc, simd_w);
+ jcp.ngroups = rnd_up(jcp.ngroups, simd_w);
+ }
+
+ auto dat_tag = isa == avx512_common ? nChw16c : nChw8c;
+ auto wei_tag = isa == avx512_common ? Goihw16g : Goihw8g;
+
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ jcp.wei_tag = weights_d.matches_one_of_tag(wei_tag);
+ jcp.dst_tag = dst_d.matches_one_of_tag(dat_tag);
+
+ bool args_ok = true
+ && jcp.oc == jcp.ngroups
+ && jcp.ic == jcp.ngroups
+ && jcp.ngroups % simd_w == 0
+ && jcp.src_tag == dat_tag
+ && jcp.wei_tag == wei_tag
+ && jcp.dst_tag == dat_tag
+ && jcp.ic <= src_d.padded_dims()[1]
+ && jcp.oc <= dst_d.padded_dims()[1]
+ && jcp.ngroups <= weights_d.padded_dims()[0];
+ if (!args_ok) return status::unimplemented;
+
+ jcp.ur_w = isa == avx512_common ? 6 : isa == avx2 ? 4 : 3;
+
+ jcp.ch_block = simd_w;
+ jcp.nb_ch = jcp.oc / jcp.ch_block;
+ jcp.nb_ch_blocking = isa == avx512_common ? 4 : isa == avx2 ? 3 : 2;
+ if (jcp.nb_ch < jcp.nb_ch_blocking)
+ jcp.nb_ch_blocking = jcp.nb_ch;
+
+ return status::success;
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_fwd_kernel_f32<isa>::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad, const jit_conv_conf_t &jcp) {
+ if (jcp.with_bias && jcp.oc_without_padding != jcp.oc)
+ scratchpad.book(key_conv_padded_bias, sizeof(float) * jcp.oc);
+}
+
+template struct jit_uni_dw_conv_fwd_kernel_f32<avx512_common>;
+template struct jit_uni_dw_conv_fwd_kernel_f32<avx2>;
+template struct jit_uni_dw_conv_fwd_kernel_f32<sse42>;
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_data_kernel_f32<isa>::load_ddst(
+ int ur_ch_blocks, int ur_str_w) {
+ int repeats = isa == sse42 ? 2 : 1;
+ for (int i = 0; i < repeats; i++) {
+ for (int ch = 0; ch < ur_ch_blocks; ch++) {
+ for (int w = 0; w < ur_str_w; w++) {
+ Vmm vmm_acc = get_acc_reg(i*ur_ch_blocks*ur_str_w
+ + ch*ur_str_w + w);
+ uni_vpxor(vmm_acc, vmm_acc, vmm_acc);
+ }
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_data_kernel_f32<isa>::apply_filter(
+ int ur_ch_blocks, int ur_str_w) {
+ int kw = jcp.kw;
+ int kh = jcp.kh;
+ int ow = jcp.ow;
+ int oh = jcp.oh;
+
+ int ch_blk = jcp.ch_block;
+ int stride_h = jcp.stride_h;
+ int stride_w = jcp.stride_w;
+
+ Label iter_exit_label;
+
+ cmp(reg_kh, 0);
+ je(iter_exit_label, T_NEAR);
+
+ cmp(reg_kw, 0);
+ je(iter_exit_label, T_NEAR);
+
+ mov(iter_kh, reg_kh);
+ Label kh_label;
+ L(kh_label); {
+ mov(aux1_reg_ddst, aux_reg_ddst);
+ mov(aux1_reg_kernel, aux_reg_kernel);
+
+ mov(iter_kw, reg_kw);
+ Label kw_label;
+ L(kw_label); {
+ int repeats = isa == sse42 ? 2 : 1;
+ for (int i = 0; i < repeats; i++) {
+ for (int ch = 0; ch < ur_ch_blocks; ch++) {
+ int ker_off = ch*kh*kw*ch_blk + i*4;
+ Vmm vmm_ker = get_ker_reg(0);
+ uni_vmovups(vmm_ker, ptr[aux1_reg_kernel
+ + ker_off*sizeof(float)]);
+
+ for (int w = 0; w < ur_str_w; w++) {
+ int ddst_off = (ch*oh*ow + w)*ch_blk + i*4;
+
+ Vmm vmm_src = get_src_reg(0);
+ uni_vmovups(vmm_src, ptr[aux1_reg_ddst
+ + ddst_off*sizeof(float)]);
+
+ Vmm vmm_acc = get_acc_reg(i*ur_ch_blocks*ur_str_w
+ + ch*ur_str_w + w);
+ uni_vfmadd231ps(vmm_acc, vmm_src, vmm_ker);
+ }
+ }
+ }
+
+ add(aux1_reg_kernel, ch_blk*stride_w*sizeof(float));
+ sub(aux1_reg_ddst, ch_blk*sizeof(float));
+
+ sub(iter_kw, stride_w);
+ cmp(iter_kw, 0);
+ jg(kw_label, T_NEAR);
+ }
+
+ add(aux_reg_kernel, kw*ch_blk*stride_h*sizeof(float));
+ sub(aux_reg_ddst, ow*ch_blk*sizeof(float));
+
+ sub(iter_kh, stride_h);
+ cmp(iter_kh, 0);
+ jg(kh_label, T_NEAR);
+ }
+
+ L(iter_exit_label);
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_data_kernel_f32<isa>::store_dsrc(
+ int ur_ch_blocks, int ur_str_w) {
+ int ch_blk = jcp.ch_block;
+ int iw = jcp.iw;
+ int ih = jcp.ih;
+ int stride_w = jcp.stride_w;
+
+ int repeats = isa == sse42 ? 2 : 1;
+ for (int i = 0; i < repeats; i++) {
+ for (int ch = 0; ch < ur_ch_blocks; ch++) {
+ for (int w = 0; w < ur_str_w; w++) {
+ int dsrc_off = (ch*ih*iw + w*stride_w)*ch_blk + i*4;
+ Vmm vmm_acc = get_acc_reg(i*ur_ch_blocks*ur_str_w
+ + ch*ur_str_w + w);
+
+ uni_vmovups(ptr[reg_dsrc + dsrc_off*sizeof(float)], vmm_acc);
+ }
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_data_kernel_f32<isa>::loop_body(
+ int ur_ch_blocks) {
+ Label unrolled_w_label;
+ Label tail_w_label;
+ Label exit_label;
+
+ L(unrolled_w_label); {
+ int ur_w = jcp.ur_w;
+
+ cmp(reg_ur_str_w, ur_w);
+ jl(tail_w_label, T_NEAR);
+
+ mov(aux_reg_ddst, reg_ddst);
+ mov(aux_reg_kernel, reg_kernel);
+
+ load_ddst(ur_ch_blocks, ur_w);
+ apply_filter(ur_ch_blocks, ur_w);
+ store_dsrc(ur_ch_blocks, ur_w);
+
+ add(reg_dsrc, sizeof(float) * ur_w * jcp.ch_block * jcp.stride_w);
+ add(reg_ddst, sizeof(float) * ur_w * jcp.ch_block);
+
+ sub(reg_ur_str_w, ur_w);
+ jmp(unrolled_w_label);
+ }
+
+ L(tail_w_label); {
+ int ur_w = 1;
+
+ cmp(reg_ur_str_w, ur_w);
+ jl(exit_label, T_NEAR);
+
+ mov(aux_reg_ddst, reg_ddst);
+ mov(aux_reg_kernel, reg_kernel);
+
+ load_ddst(ur_ch_blocks, ur_w);
+ apply_filter(ur_ch_blocks, ur_w);
+ store_dsrc(ur_ch_blocks, ur_w);
+
+ add(reg_dsrc, sizeof(float) * ur_w * jcp.ch_block * jcp.stride_w);
+ add(reg_ddst, sizeof(float) * ur_w * jcp.ch_block);
+
+ sub(reg_ur_str_w, ur_w);
+ jmp(tail_w_label);
+ }
+
+ L(exit_label);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_bwd_data_kernel_f32<isa>::generate() {
+ preamble();
+
+ mov(reg_dsrc, ptr[this->param1 + GET_OFF(src)]);
+ mov(reg_ddst, ptr[this->param1 + GET_OFF(dst)]);
+ mov(reg_kernel, ptr[this->param1 + GET_OFF(filt)]);
+ mov(reg_kh, ptr[this->param1 + GET_OFF(kh_padding)]);
+ mov(reg_kw, ptr[this->param1 + GET_OFF(kw_padding)]);
+ mov(reg_ch_blocks, ptr[this->param1 + GET_OFF(ch_blocks)]);
+ mov(reg_ur_str_w, ptr[this->param1 + GET_OFF(ur_str_w)]);
+
+ Label ch_blocks_tail_label;
+ Label exit_label;
+
+ int ch_blocks_tail = jcp.nb_ch % jcp.nb_ch_blocking;
+
+ cmp(reg_ch_blocks, jcp.nb_ch_blocking);
+ jne(ch_blocks_tail ? ch_blocks_tail_label : exit_label, T_NEAR);
+
+ loop_body(jcp.nb_ch_blocking); // channel main loop
+
+ if (ch_blocks_tail) {
+ L(ch_blocks_tail_label);
+
+ cmp(reg_ch_blocks, ch_blocks_tail);
+ jne(exit_label, T_NEAR);
+
+ loop_body(ch_blocks_tail); // channel tail loop
+ }
+
+ L(exit_label);
+
+ this->postamble();
+}
+
+template <cpu_isa_t isa>
+status_t jit_uni_dw_conv_bwd_data_kernel_f32<isa>::init_conf(
+ jit_conv_conf_t &jcp, const convolution_desc_t &cd,
+ const memory_desc_wrapper &diff_src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &diff_dst_d) {
+ if (!mayiuse(isa)) return status::unimplemented;
+
+ const int simd_w = isa == avx512_common ? 16 : 8;
+
+ const bool with_groups = weights_d.ndims() == diff_src_d.ndims() + 1;
+ if (!with_groups) return status::unimplemented;
+
+ jcp.ngroups = weights_d.dims()[0];
+ jcp.mb = diff_src_d.dims()[0];
+
+ jcp.oc = diff_dst_d.dims()[1];
+ jcp.oc_without_padding = jcp.oc;
+ jcp.ic = diff_src_d.dims()[1];
+
+ jcp.ih = diff_src_d.dims()[2];
+ jcp.iw = diff_src_d.dims()[3];
+ jcp.oh = diff_dst_d.dims()[2];
+ jcp.ow = diff_dst_d.dims()[3];
+
+ jcp.kh = weights_d.dims()[3];
+ jcp.kw = weights_d.dims()[4];
+
+ jcp.t_pad = cd.padding[0][0];
+ jcp.l_pad = cd.padding[0][1];
+ jcp.b_pad = cd.padding[1][0];
+ jcp.r_pad = cd.padding[1][1];
+
+ jcp.stride_h = cd.strides[0];
+ jcp.stride_w = cd.strides[1];
+
+ jcp.dilate_h = cd.dilates[0];
+ jcp.dilate_w = cd.dilates[1];
+
+ jcp.ihp = jcp.ih + jcp.t_pad + jcp.b_pad;
+ jcp.iwp = jcp.iw + jcp.l_pad + jcp.r_pad;
+
+ bool ok_to_pad_channels = true
+ && jcp.oc == jcp.ngroups
+ && jcp.ic == jcp.ngroups
+ && one_of(isa, avx512_common, avx2);
+ if (ok_to_pad_channels) {
+ jcp.oc = rnd_up(jcp.oc, simd_w);
+ jcp.ic = rnd_up(jcp.oc, simd_w);
+ jcp.ngroups = rnd_up(jcp.ngroups, simd_w);
+ }
+
+ auto dat_tag = isa == avx512_common ? nChw16c : nChw8c;
+ auto wei_tag = isa == avx512_common ? Goihw16g : Goihw8g;
+
+ jcp.src_tag = diff_src_d.matches_one_of_tag(dat_tag);
+ jcp.wei_tag = weights_d.matches_one_of_tag(wei_tag);
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(dat_tag);
+
+ bool args_ok = true
+ && jcp.oc == jcp.ngroups
+ && jcp.ic == jcp.ngroups
+ && jcp.ngroups % simd_w == 0
+ && jcp.dilate_h == 0
+ && jcp.dilate_w == 0
+ && jcp.src_tag == dat_tag
+ && jcp.wei_tag == wei_tag
+ && jcp.dst_tag == dat_tag
+ && jcp.oh == (jcp.ihp - jcp.kh) / jcp.stride_h + 1
+ && jcp.ow == (jcp.iwp - jcp.kw) / jcp.stride_w + 1
+ && jcp.ic <= diff_src_d.padded_dims()[1]
+ && jcp.oc <= diff_dst_d.padded_dims()[1]
+ && jcp.ngroups <= weights_d.padded_dims()[0];
+ if (!args_ok) return status::unimplemented;
+
+ jcp.ur_w = isa == avx512_common ? 6 : isa == avx2 ? 4 : 3;
+
+ jcp.ch_block = simd_w;
+ jcp.nb_ch = jcp.ic / jcp.ch_block;
+ jcp.nb_ch_blocking = isa == avx512_common ? 4 : isa == avx2 ? 3 : 2;
+ if (jcp.nb_ch < jcp.nb_ch_blocking)
+ jcp.nb_ch_blocking = jcp.nb_ch;
+
+ return status::success;
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_bwd_data_kernel_f32<isa>::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad, const jit_conv_conf_t &jcp) {
+ UNUSED(scratchpad);
+ UNUSED(jcp);
+}
+
+template struct jit_uni_dw_conv_bwd_data_kernel_f32<avx512_common>;
+template struct jit_uni_dw_conv_bwd_data_kernel_f32<avx2>;
+template struct jit_uni_dw_conv_bwd_data_kernel_f32<sse42>;
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::zero_filter() {
+ for (int r = 0; r < reg_repeats; ++r) {
+ for (int i = 0; i < jcp.kw; ++i) {
+ Vmm vmm_acc = get_acc_reg(r * jcp.kw + i);
+ uni_vpxor(vmm_acc, vmm_acc, vmm_acc);
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::load_filter() {
+ for (int r = 0; r < reg_repeats; ++r) {
+ const int reg_set = r * jcp.kw;
+ for (int i = 0; i < jcp.kw; ++i) {
+ int off_filter = (reg_set + i) * simd_w;
+ Vmm vmm_acc = get_acc_reg(reg_set + i);
+ uni_vmovups(vmm_acc,
+ vmmword[reg_tmp_filter + off_filter * sizeof(float)]);
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::zero_bias() {
+ for (int r = 0; r < reg_repeats; ++r) {
+ Vmm vmm_bias = get_bias_reg(r);
+ uni_vpxor(vmm_bias, vmm_bias, vmm_bias);
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::load_bias() {
+ for (int r = 0; r < reg_repeats; ++r) {
+ Vmm vmm_bias = get_bias_reg(r);
+ uni_vmovups(
+ vmm_bias, vmmword[reg_bias_baddr + r * simd_w * sizeof(float)]);
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::compute_ow_step_unroll(
+ int unroll_w, int l_pad, int pad_offset, int ow_block) {
+
+ const int iw_block = ow_block * jcp.stride_w;
+ const int right_border = jcp.iw - iw_block;
+
+ const int cascade_input = nstl::min(jcp.stride_w, jcp.kw);
+
+ /* preamble count for number of cascaded LOAD + FMA operation */
+ const int input_overlap = nstl::max(jcp.kw - l_pad, 0);
+
+ /* LOAD initial input registers, then cascade LOADs and FMAs*/
+ for (int r = 0; r < reg_repeats; ++r) {
+ for (int i_ur = 0; i_ur < unroll_w; ++i_ur) {
+ int off_output = (i_ur * reg_repeats + r) * simd_w;
+ Vmm vmm_output = get_output_reg(r);
+ uni_vmovups(vmm_output,
+ ptr[reg_tmp_output + off_output * sizeof(float)]);
+ if (i_ur == 0) {
+ for (int c = 0; c < input_overlap; ++c) {
+ int off_input
+ = ((c - pad_offset) * reg_repeats + r) * simd_w;
+ Vmm vmm_input
+ = get_input_reg((c % jcp.kw) * reg_repeats + r);
+ uni_vmovups(vmm_input,
+ ptr[reg_tmp_input + off_input * sizeof(float)]);
+ }
+ } else {
+ for (int c = 0; c < cascade_input; ++c) {
+ int overlap = (i_ur - 1) * jcp.stride_w + input_overlap;
+ int off_input
+ = ((overlap + c - pad_offset) * reg_repeats + r)
+ * simd_w;
+ Vmm vmm_input = get_input_reg(
+ ((overlap + c) % jcp.kw) * reg_repeats + r);
+ uni_vmovups(vmm_input,
+ ptr[reg_tmp_input + off_input * sizeof(float)]);
+ }
+ }
+
+ for (int i_kw = 0; i_kw < jcp.kw; ++i_kw) {
+ int io_overlap = i_kw + (i_ur * jcp.stride_w);
+
+ /* Don't apply FMAs that fall into the padded region */
+ if (io_overlap - l_pad < 0
+ || io_overlap - jcp.l_pad >= right_border)
+ continue;
+
+ Vmm vmm_input = get_input_reg(
+ ((io_overlap - l_pad) % jcp.kw) * reg_repeats + r);
+ Vmm vmm_acc = get_acc_reg(i_kw * reg_repeats + r);
+ Vmm vmm_aux = isa == sse42 ? get_aux_reg() : vmm_input;
+ if (isa == sse42)
+ uni_vmovups(vmm_aux, vmm_input);
+ uni_vfmadd231ps(vmm_acc, vmm_aux, vmm_output);
+ }
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+inline void
+jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::compute_bias_step_unroll(
+ const int unroll_w) {
+ for (int r = 0; r < reg_repeats; ++r) {
+ for (int i = 0; i < unroll_w; ++i) {
+ Vmm vmm_bias = get_bias_reg(r);
+ int off_output = (i * reg_repeats + r) * simd_w;
+ if (isa == sse42) {
+ /* Need to support unaligned address loads for SSE42*/
+ Vmm vmm_output = get_output_reg(1 + r);
+ uni_vmovups(vmm_output,
+ ptr[reg_tmp_output + off_output * sizeof(float)]);
+ uni_vaddps(vmm_bias, vmm_bias, vmm_output);
+ } else {
+ uni_vaddps(vmm_bias, vmm_bias,
+ vmmword[reg_tmp_output + off_output * sizeof(float)]);
+ }
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::store_filter() {
+ for (int r = 0; r < reg_repeats; ++r) {
+ const int reg_set = r * jcp.kw;
+ for (int i = 0; i < jcp.kw; ++i) {
+ int off_filter = (i + reg_set) * simd_w;
+ Vmm vmm_acc = get_acc_reg(i + reg_set);
+ uni_vmovups(vmmword[reg_tmp_filter + off_filter * sizeof(float)],
+ vmm_acc);
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::store_bias() {
+ for (int r = 0; r < reg_repeats; ++r) {
+ Vmm vmm_bias = get_bias_reg(r);
+ uni_vmovups(
+ vmmword[reg_bias_baddr + r * simd_w * sizeof(float)], vmm_bias);
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::compute_bias_loop(
+ const int block_size) {
+ Label oh_label;
+ Label ow_blk_label;
+
+ const int unroll_w = nstl::min(block_size, jcp.ow);
+ const int unroll_w_trips = jcp.ow / unroll_w;
+ const int tail_w = jcp.ow > block_size ? jcp.ow % block_size : 0;
+
+ const int ch_offset = jcp.ch_block;
+
+ mov(reg_oh, ptr[this->param1 + offsetof(jit_dw_conv_call_s, oh_index)]);
+ mov(reg_oh_worksize,
+ ptr[this->param1 + offsetof(jit_dw_conv_call_s, oh_count)]);
+
+ mov(reg_tmp_output, reg_output_baddr);
+ L(oh_label);
+ {
+
+ mov(iter_ow_blk, unroll_w_trips);
+ L(ow_blk_label);
+ {
+
+ compute_bias_step_unroll(unroll_w);
+ add(reg_tmp_output, unroll_w * ch_offset * sizeof(float));
+
+ dec(iter_ow_blk);
+ cmp(iter_ow_blk, 0);
+ jg(ow_blk_label, T_NEAR);
+ }
+
+ if (tail_w > 0) {
+ compute_bias_step_unroll(tail_w);
+ add(reg_tmp_output, tail_w * ch_offset * sizeof(float));
+ }
+
+ inc(reg_oh);
+ cmp(reg_oh, reg_oh_worksize);
+ jl(oh_label, T_NEAR);
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::compute_zero_filter() {
+
+ const int ch_offset = jcp.ch_block;
+
+ Label kh_loop_label, skip_zeroing_label;
+
+ mov(reg_exec_flags,
+ ptr[this->param1 + offsetof(jit_dw_conv_call_s, exec_flags)]);
+ and_(reg_exec_flags, FLAG_ZERO_FILTER);
+ test(reg_exec_flags, reg_exec_flags);
+ je(skip_zeroing_label);
+
+ zero_filter();
+
+ mov(reg_tmp_filter, reg_filter_baddr);
+ mov(reg_kh, jcp.kh);
+ L(kh_loop_label);
+ {
+ store_filter();
+
+ add(reg_tmp_filter, jcp.kw * ch_offset * sizeof(float));
+ dec(reg_kh);
+ cmp(reg_kh, 0);
+ jg(kh_loop_label);
+ }
+
+ /* Comeback pointers */
+ sub(reg_tmp_filter, jcp.kh * jcp.kw * ch_offset * sizeof(float));
+
+ L(skip_zeroing_label);
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::compute_h_step(
+ int unroll_w, int l_pad, int pad_offset, int ow_block) {
+
+ const int ch_offset = jcp.ch_block;
+
+ Label kh_loop_label, skip_loop_label;
+
+ cmp(reg_kh_count, 0);
+ je(skip_loop_label, T_NEAR);
+
+ mov(reg_kh, reg_kh_count);
+ L(kh_loop_label);
+ {
+ load_filter();
+ compute_ow_step_unroll(unroll_w, l_pad, pad_offset, ow_block);
+ store_filter();
+
+ add(reg_tmp_filter, jcp.kw * ch_offset * sizeof(float));
+ add(reg_tmp_input, jcp.iw * ch_offset * sizeof(float));
+ dec(reg_kh);
+ cmp(reg_kh, 0);
+ jg(kh_loop_label);
+ }
+
+ /* Comeback pointers */
+ Label kh_comeback_label;
+ mov(reg_kh, reg_kh_count);
+ L(kh_comeback_label);
+ {
+ sub(reg_tmp_input, jcp.iw * ch_offset * sizeof(float));
+ sub(reg_tmp_filter, jcp.kw * ch_offset * sizeof(float));
+ dec(reg_kh);
+ cmp(reg_kh, 0);
+ jg(kh_comeback_label, T_NEAR);
+ }
+
+ L(skip_loop_label);
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::compute_h_loop(
+ int unroll_w, int l_pad, int pad_offset, int ow_block) {
+
+ const size_t io_overlap = jcp.ih / jcp.stride_h < jcp.oh ?
+ jcp.ih / jcp.stride_h - 1 :
+ jcp.oh - jcp.b_pad - 1;
+ const int ch_offset = jcp.ch_block;
+ const int t_overlap_off = jcp.t_pad % jcp.stride_h == 0 ? jcp.stride_h : 1;
+ const int b_overlap_off = jcp.b_pad % jcp.stride_h == 0 ? jcp.stride_h : 1;
+
+ Label tpad_loop_label, h_loop_label, skip_tpad_label, skip_bpad_label,
+ end_h_loop_label;
+
+ mov(reg_oh, ptr[this->param1 + offsetof(jit_dw_conv_call_s, oh_index)]);
+ mov(reg_oh_worksize,
+ ptr[this->param1 + offsetof(jit_dw_conv_call_s, oh_count)]);
+ mov(reg_kh_count,
+ ptr[this->param1 + offsetof(jit_dw_conv_call_s, kh_count)]);
+
+ mov(reg_tmp_output, reg_output_baddr);
+ mov(reg_tmp_input, reg_input_baddr);
+ mov(reg_tmp_filter, reg_filter_baddr);
+
+ L(h_loop_label);
+ {
+
+ compute_h_step(unroll_w, l_pad, pad_offset, ow_block);
+
+ add(reg_tmp_output, jcp.ow * ch_offset * sizeof(float));
+
+ /* If within the top_pad region */
+ if (jcp.t_pad > 0) {
+ /* Skip t_pad area if no longer in initial h_block */
+ cmp(reg_oh, jcp.t_pad);
+ jg(skip_tpad_label, T_NEAR);
+
+ cmp(reg_kh_count, jcp.kh);
+ jge(skip_tpad_label, T_NEAR);
+
+ add(reg_kh_count, t_overlap_off);
+ sub(reg_tmp_filter,
+ t_overlap_off * jcp.kw * ch_offset * sizeof(float));
+
+ /* kernel has moved beyond padding (adjust for stride effects) */
+ if (jcp.t_pad % jcp.stride_h != 0) {
+ int inp_corr = jcp.stride_h - jcp.t_pad % jcp.stride_h;
+ add(reg_tmp_input,
+ inp_corr * jcp.iw * ch_offset * sizeof(float));
+ }
+ jmp(tpad_loop_label, T_NEAR);
+ }
+
+ L(skip_tpad_label);
+
+ cmp(reg_oh, io_overlap);
+ jl(skip_bpad_label, T_NEAR);
+ sub(reg_kh_count, b_overlap_off);
+
+ L(skip_bpad_label);
+ add(reg_tmp_input, jcp.stride_h * jcp.iw * ch_offset * sizeof(float));
+
+ L(tpad_loop_label);
+
+ cmp(reg_oh, jcp.ih / jcp.stride_h);
+ jge(end_h_loop_label, T_NEAR);
+
+ inc(reg_oh);
+
+ cmp(reg_oh, reg_oh_worksize);
+ jl(h_loop_label, T_NEAR);
+ }
+ L(end_h_loop_label);
+}
+
+template <cpu_isa_t isa>
+inline void
+jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::compute_ow_block_unroll() {
+
+ const int ch_offset = jcp.ch_block;
+ int ow = jcp.ow;
+ int pad_offset = 0;
+ int l_pad = jcp.l_pad;
+
+ /* Calculate effective padding */
+ int r_pad = nstl::max(0, (ow - 1) * jcp.stride_w
+ + (jcp.kw - 1) * (jcp.dilate_w + 1)
+ - (jcp.iw + jcp.l_pad - 1));
+
+ /* Is this strictly defined by:
+ * -code-size (?)
+ * -address size (?) */
+ const int max_unroll_w = 30;
+ const int block_size = 15;
+
+ int unroll_w_tail = 0;
+ int unroll_w = 0;
+ int unroll_w_trips = 0;
+
+ if (jcp.ow > max_unroll_w) {
+ unroll_w = nstl::min(block_size, jcp.ow);
+ unroll_w_trips = ow / unroll_w;
+ /* calculate tail */
+ unroll_w_tail = ow % unroll_w;
+ /* Perform some rebalancing if tail too small*/
+ if ((unroll_w_tail == 0 && r_pad != 0)
+ || (r_pad > 0 && r_pad >= unroll_w_tail)) {
+ if (unroll_w_trips > 1) {
+ unroll_w_tail += unroll_w;
+ unroll_w_trips--;
+ } else {
+ /* Idealy, this case shouldn't happen */
+ unroll_w_tail += (unroll_w - unroll_w / 2);
+ unroll_w = unroll_w / 2;
+ }
+ }
+ } else {
+ unroll_w = jcp.ow;
+ unroll_w_trips = nstl::max(1, ow / unroll_w);
+ }
+ if (jcp.with_bias) {
+ Label skip_load_bias;
+ mov(reg_bias_baddr,
+ ptr[this->param1 + offsetof(jit_dw_conv_call_s, bias)]);
+
+ zero_bias();
+
+ mov(reg_exec_flags,
+ ptr[this->param1 + offsetof(jit_dw_conv_call_s, exec_flags)]);
+ and_(reg_exec_flags, FLAG_ZERO_BIAS);
+ test(reg_exec_flags, reg_exec_flags);
+ jne(skip_load_bias);
+
+ load_bias();
+
+ L(skip_load_bias);
+ compute_bias_loop(block_size);
+
+ store_bias();
+ }
+
+ /* Pass filter address, then offset for h_padding. */
+ compute_zero_filter();
+ mov(reg_kh_offset,
+ ptr[this->param1 + offsetof(jit_dw_conv_call_s, filter_pad_off)]);
+ add(reg_filter_baddr, reg_kh_offset);
+
+ /* compute left padded block */
+ if (l_pad) {
+ compute_h_loop(unroll_w, l_pad, 0, 0);
+ add(reg_output_baddr, unroll_w * ch_offset * sizeof(float));
+ add(reg_input_baddr,
+ unroll_w * jcp.stride_w * ch_offset * sizeof(float));
+ unroll_w_trips--;
+ pad_offset = l_pad;
+ l_pad = 0;
+ }
+
+ /* compute middle block */
+ Label ow_blk_label;
+
+ /* Insert loop for 'ow' block when middle block needs to execute more
+ * than once */
+ bool do_ow_blk_loop = unroll_w_trips > 1;
+ if (do_ow_blk_loop) {
+ mov(iter_ow_blk, unroll_w_trips);
+ L(ow_blk_label);
+ }
+ if (unroll_w_trips > 0) {
+ compute_h_loop(unroll_w, l_pad, pad_offset, 0);
+ add(reg_output_baddr, unroll_w * ch_offset * sizeof(float));
+ add(reg_input_baddr,
+ unroll_w * jcp.stride_w * ch_offset * sizeof(float));
+ }
+ if (do_ow_blk_loop) {
+ dec(iter_ow_blk);
+ cmp(iter_ow_blk, 0);
+ jg(ow_blk_label, T_NEAR);
+ }
+
+ /* compute right padded block */
+ if (unroll_w_tail) {
+ compute_h_loop(unroll_w_tail, 0, pad_offset, jcp.ow - unroll_w_tail);
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::generate() {
+ preamble();
+
+ mov(reg_input_baddr,
+ ptr[this->param1 + offsetof(jit_dw_conv_call_s, input)]);
+ mov(reg_output_baddr,
+ ptr[this->param1 + offsetof(jit_dw_conv_call_s, output)]);
+ mov(reg_filter_baddr,
+ ptr[this->param1 + offsetof(jit_dw_conv_call_s, filter)]);
+
+ compute_ow_block_unroll();
+
+ this->postamble();
+}
+
+template <cpu_isa_t isa>
+status_t jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::init_conf(
+ jit_conv_conf_t &jcp, const convolution_desc_t &cd,
+ const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &diff_weights_d,
+ const memory_desc_wrapper &diff_dst_d, int nthreads) {
+ if (!mayiuse(isa))
+ return status::unimplemented;
+
+ jcp.ngroups = diff_weights_d.dims()[0];
+ jcp.oc = diff_dst_d.dims()[1] / jcp.ngroups;
+ jcp.ic = src_d.dims()[1] / jcp.ngroups;
+
+ const bool with_groups = diff_weights_d.ndims() == src_d.ndims() + 1;
+
+ jcp.is_depthwise = true && with_groups && everyone_is(1, jcp.oc, jcp.ic);
+
+ if (!jcp.is_depthwise)
+ return status::unimplemented;
+
+ jcp.ch_block = isa == avx512_common ? 16 : 8;
+
+ jcp.mb = src_d.dims()[0];
+
+ jcp.ih = src_d.dims()[2];
+ jcp.iw = src_d.dims()[3];
+ jcp.oh = diff_dst_d.dims()[2];
+ jcp.ow = diff_dst_d.dims()[3];
+
+ jcp.kh = diff_weights_d.dims()[3];
+ jcp.kw = diff_weights_d.dims()[4];
+
+ jcp.stride_h = cd.strides[0];
+ jcp.stride_w = cd.strides[1];
+
+ jcp.t_pad = cd.padding[0][0];
+ jcp.b_pad = cd.padding[1][0];
+
+ jcp.l_pad = cd.padding[0][1];
+ jcp.r_pad = cd.padding[1][1];
+
+ jcp.dilate_h = cd.dilates[0];
+ jcp.dilate_w = cd.dilates[1];
+
+ jcp.ihp = jcp.ih + jcp.t_pad + jcp.b_pad;
+ jcp.iwp = jcp.iw + jcp.l_pad + jcp.r_pad;
+
+ jcp.with_bias = cd.diff_bias_desc.format_kind != format_kind::undef;
+
+ auto dat_tag = isa == avx512_common ? nChw16c : nChw8c;
+ auto wei_tag = isa == avx512_common ? Goihw16g : Goihw8g;
+
+ jcp.src_tag = src_d.matches_one_of_tag(dat_tag);
+ jcp.wei_tag = diff_weights_d.matches_one_of_tag(wei_tag);
+ jcp.dst_tag = diff_dst_d.matches_one_of_tag(dat_tag);
+
+ bool args_ok = true
+ && jcp.src_tag == dat_tag
+ && jcp.wei_tag == wei_tag
+ && jcp.dst_tag == dat_tag
+ && jcp.ngroups % jcp.ch_block == 0 && jcp.dilate_h == 0
+ && jcp.dilate_w == 0 && jcp.kw <= 3
+ && jcp.oh == (jcp.ihp - jcp.kh) / jcp.stride_h + 1
+ && jcp.ow == (jcp.iwp - jcp.kw) / jcp.stride_w + 1;
+ if (!args_ok)
+ return status::unimplemented;
+
+ jcp.nb_ch = jcp.ngroups / jcp.ch_block;
+
+ /* kernel applicability check wrt boundaries
+ * the conditions are quite general across the kernels we have,
+ * but ideally the check should belong to a specific kernel... */
+ const int max_hpad = (jcp.kh - 1 + 1) / 2;
+ const int max_wpad = (jcp.kw - 1 + 1) / 2;
+ const bool boundaries_ok = true && jcp.t_pad <= max_hpad
+ && jcp.b_pad <= max_hpad && jcp.l_pad <= max_wpad
+ && jcp.r_pad <= max_wpad;
+ if (!boundaries_ok)
+ return status::unimplemented;
+
+ balance(jcp, nthreads);
+
+ return status::success;
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::init_scratchpad(
+ memory_tracking::registrar_t &scratchpad, const jit_conv_conf_t &jcp) {
+ /* Notes: if splitting thread work on 'mb', then a reduction has to take
+ * place. Hence, book a per-thread, local weights-buffer for the
+ * reduction */
+ if (jcp.nthr_mb > 1) {
+ const size_t wei_size = jcp.ngroups * jcp.kh * jcp.kw;
+ scratchpad.book(key_conv_wei_reduction,
+ sizeof(float) * wei_size * (jcp.nthr_mb - 1));
+
+ if (jcp.with_bias)
+ scratchpad.book(key_conv_bia_reduction,
+ sizeof(float) * jcp.ngroups * (jcp.nthr_mb - 1));
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::balance(jit_conv_conf_t &jcp,
+ int nthreads) {
+ jcp.nthr = nthreads;
+ jcp.nthr_g = jcp.nthr_mb = 1;
+
+ /* Basic-Heuristics for parallel strategy:
+ * 1) Tries to parallel on the number of Groups (g) where tasks are
+ * independent. Otherwise,
+ * 2) Tries to split the work across g and MiniBatch (mb).
+ * Parallelizing on mb requires computing a reduction for weights.
+ *
+ * NOTE: because of 'task partitioning' scheme, there will be unbalanced
+ * per-thread load when the number of threads is high (e.g. > 16).
+ */
+ jcp.nthr_g = nstl::min(jcp.nb_ch, jcp.nthr);
+ jcp.nthr_mb = nstl::min(nstl::max(1, jcp.nthr / jcp.nthr_g), jcp.mb);
+
+ jcp.nthr = jcp.nthr_g * jcp.nthr_mb;
+}
+
+template struct jit_uni_dw_conv_bwd_weights_kernel_f32<avx512_common>;
+template struct jit_uni_dw_conv_bwd_weights_kernel_f32<avx2>;
+template struct jit_uni_dw_conv_bwd_weights_kernel_f32<sse42>;
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_conv_kernel_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_conv_kernel_f32.hpp
new file mode 100644
index 0000000000..9c08fc4a09
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_conv_kernel_f32.hpp
@@ -0,0 +1,253 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_UNI_DW_CONV_KERNEL_F32_HPP
+#define JIT_UNI_DW_CONV_KERNEL_F32_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+#include "jit_uni_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <cpu_isa_t isa>
+struct jit_uni_dw_conv_fwd_kernel_f32: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_uni_dw_conv_fwd_kernel_f32)
+
+ jit_uni_dw_conv_fwd_kernel_f32(jit_conv_conf_t ajcp)
+ : jcp(ajcp), eltwise_injector_(nullptr)
+ {
+ if (jcp.with_eltwise)
+ eltwise_injector_ = new jit_uni_eltwise_injector_f32<isa>(this,
+ jcp.eltwise);
+
+ this->generate();
+ jit_ker = (void (*)(jit_conv_call_s *))this->getCode();
+ }
+
+ ~jit_uni_dw_conv_fwd_kernel_f32() {
+ delete eltwise_injector_;
+ }
+
+ static bool post_ops_ok(jit_conv_conf_t &jcp,
+ const primitive_attr_t &attr);
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &dst_d, const primitive_attr_t &attr);
+
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_conf_t &jcp);
+
+ jit_conv_conf_t jcp;
+ void (*jit_ker)(jit_conv_call_s *);
+
+private:
+ using Vmm = typename utils::conditional3<isa == sse42, Xbyak::Xmm,
+ isa == avx2, Xbyak::Ymm, Xbyak::Zmm>::type;
+ using reg64_t = const Xbyak::Reg64;
+ const Xbyak::AddressFrame &vmmword = (isa == sse42)
+ ? xword : (isa == avx2) ? yword : zword;
+ const int vlen = cpu_isa_traits<isa>::vlen;
+
+ // dw convolution
+ reg64_t reg_input = r8;
+ reg64_t aux_reg_input = r9;
+ reg64_t aux1_reg_input = r10;
+ reg64_t reg_kernel = r11;
+ reg64_t aux_reg_kernel = r12;
+ reg64_t aux1_reg_kernel = r13;
+ reg64_t reg_output = r14;
+ reg64_t reg_bias = r15;
+ reg64_t reg_kh = rax;
+ reg64_t reg_kw = rbx;
+ reg64_t iter_kh = rdx;
+ reg64_t iter_kw = rsi;
+ reg64_t reg_ur_w = rbp;
+ reg64_t reg_ch_blocks = aux1_reg_input;
+ reg64_t imm_addr64 = aux1_reg_input;
+
+ inline Vmm get_ker_reg(int idx) { return Vmm(idx + 0); }
+ inline Vmm get_src_reg(int idx) { return Vmm(idx + 1); }
+ inline Vmm get_acc_reg(int idx) { return Vmm(idx + 4); }
+
+ inline void load_src(int ur_ch_blocks, int ur_w);
+ inline void apply_filter(int ur_ch_blocks, int ur_w);
+ inline void apply_filter_unrolled(int ur_ch_blocks, int ur_w);
+ inline void apply_activation(int ur_ch_blocks, int ur_w);
+ inline void store_dst(int ur_ch_blocks, int ur_w);
+ inline void loop_body(int ur_ch_blocks);
+
+ jit_uni_eltwise_injector_f32<isa> *eltwise_injector_;
+
+ void generate();
+};
+
+template <cpu_isa_t isa>
+struct jit_uni_dw_conv_bwd_data_kernel_f32: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_uni_dw_conv_bwd_data_kernel_f32)
+
+ jit_uni_dw_conv_bwd_data_kernel_f32(jit_conv_conf_t ajcp): jcp(ajcp) {
+ this->generate();
+ jit_ker = (void (*)(jit_conv_call_s *))this->getCode();
+ }
+
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd,
+ const memory_desc_wrapper &diff_src_d,
+ const memory_desc_wrapper &weights_d,
+ const memory_desc_wrapper &diff_dst_d);
+
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_conf_t &jcp);
+
+ jit_conv_conf_t jcp;
+ void (*jit_ker)(jit_conv_call_s *);
+
+private:
+ using Vmm = typename utils::conditional3<isa == sse42, Xbyak::Xmm,
+ isa == avx2, Xbyak::Ymm, Xbyak::Zmm>::type;
+ using reg64_t = const Xbyak::Reg64;
+
+ inline Vmm get_ker_reg(int idx) { return Vmm(idx + 0); }
+ inline Vmm get_src_reg(int idx) { return Vmm(idx + 1); }
+ inline Vmm get_acc_reg(int idx) { return Vmm(idx + 4); }
+
+ reg64_t reg_ddst = rax;
+ reg64_t aux_reg_ddst = r8;
+ reg64_t aux1_reg_ddst = abi_not_param1;
+ reg64_t reg_kernel = rdx;
+ reg64_t aux_reg_kernel = r10;
+ reg64_t aux1_reg_kernel = rbp;
+ reg64_t reg_dsrc = rsi;
+
+ reg64_t reg_ur_str_w = r9;
+ reg64_t reg_ch_blocks = rbx;
+
+ reg64_t iter_kh = r11;
+ reg64_t iter_kw = r12;
+ reg64_t reg_kh = r13;
+ reg64_t reg_kw = r14;
+
+ inline void loop_body(int ur_ch_blocks);
+ inline void load_ddst(int ur_ch_blocks, int ur_str_w);
+ inline void apply_filter(int ur_ch_blocks, int ur_str_w);
+ inline void store_dsrc(int ur_ch_blocks, int ur_str_w);
+
+ void generate();
+};
+
+template <cpu_isa_t isa>
+struct jit_uni_dw_conv_bwd_weights_kernel_f32 : public jit_generator {
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_uni_dw_conv_bwd_weights_kernel_f32)
+
+ jit_uni_dw_conv_bwd_weights_kernel_f32(jit_conv_conf_t ajcp) : jcp(ajcp) {
+ this->generate();
+ jit_ker = (void (*)(jit_dw_conv_call_s *)) this->getCode();
+ }
+
+ static status_t init_conf(jit_conv_conf_t &jcp,
+ const convolution_desc_t &cd, const memory_desc_wrapper &src_d,
+ const memory_desc_wrapper &diff_weights_d,
+ const memory_desc_wrapper &diff_dst_d, int nthreads);
+
+ static void init_scratchpad(memory_tracking::registrar_t &scratchpad,
+ const jit_conv_conf_t &jcp);
+
+ static void balance(jit_conv_conf_t &jcp, int nthreads);
+
+ jit_conv_conf_t jcp;
+ void (*jit_ker)(jit_dw_conv_call_s *);
+
+private:
+ using Vmm = typename utils::conditional3<isa == sse42, Xbyak::Xmm,
+ isa == avx2, Xbyak::Ymm, Xbyak::Zmm>::type;
+ using reg64_t = const Xbyak::Reg64;
+ const int simd_w = cpu_isa_traits<isa>::vlen / sizeof(float);
+ const int reg_repeats = (isa == sse42) ? 2 : 1;
+
+ const Xbyak::AddressFrame &vmmword
+ = (isa == sse42) ? xword : (isa == avx2) ? yword : zword;
+
+ /* XXX: offset between input and accummulators is 3, therefore, assume 'kw'
+ * is no larger than 3*/
+ inline Vmm get_bias_reg(int idx = 0) { return Vmm(idx); }
+ inline Vmm get_output_reg(int idx) { return Vmm(idx + 1); }
+ inline Vmm get_input_reg(int idx) { return Vmm(idx + 4 * reg_repeats + 1); }
+ inline Vmm get_acc_reg(int idx) { return Vmm(idx + 1 * reg_repeats + 1); }
+ inline Vmm get_aux_reg() { return Vmm(0); }
+
+ reg64_t reg_tmp_input = r9;
+ reg64_t reg_tmp_output = r10;
+ reg64_t reg_tmp_filter = r13;
+ reg64_t reg_kh_offset = rax;
+
+ /* parameter passed by driver into kernel */
+ Xbyak::Reg8 reg_exec_flags = bl;
+
+ reg64_t reg_oh_worksize = r14;
+ reg64_t reg_oh = rax;
+
+ reg64_t iter_ow_blk = r11;
+
+ reg64_t reg_kh = rsi;
+ reg64_t reg_kh_count = rdx;
+
+ /* Base addresses for convolution parameters. */
+ reg64_t reg_input_baddr = r15;
+ reg64_t reg_output_baddr = r12;
+ reg64_t reg_filter_baddr = abi_not_param1;
+ reg64_t reg_bias_baddr = r13;
+
+ /* Micro-kernel JIT'ing, fusing 'kw' and 'ow_block' loops into unrolled FMAs
+ */
+ inline void compute_ow_step_unroll(
+ int unroll_w, int l_pad, int pad_offset, int ow_block);
+
+ /* JIT'ing the outer loops for the micro-kernel -> {kh, oh_block} */
+ inline void compute_h_step(
+ int unroll_w, int l_pad, int pad_offset, int ow_block);
+ inline void compute_h_loop(
+ int unroll_w, int l_pad, int pad_offset, int ow_block);
+
+ /* Write 'width' micro-kernel JITs; depending on the padding and convolution
+ * size, write a micro-kernel for the left ow-block, middle ow-block(s), and
+ * right ow-block.*/
+ inline void compute_ow_block_unroll();
+
+ inline void compute_zero_filter();
+ inline void load_filter();
+ inline void zero_filter();
+ inline void load_bias();
+ inline void zero_bias();
+ inline void compute_bias_step_unroll(const int unroll_w);
+ inline void compute_bias_loop(const int block_size);
+ inline void store_filter();
+ inline void store_bias();
+
+ void generate();
+};
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_convolution.cpp
new file mode 100644
index 0000000000..58449601a3
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_convolution.cpp
@@ -0,0 +1,427 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "mkldnn_thread.hpp"
+
+#include "jit_uni_dw_convolution.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace mkldnn::impl::utils;
+
+template <cpu_isa_t isa>
+void _jit_uni_dw_convolution_fwd_t<isa>::execute_forward(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ const auto &jcp = kernel_->jcp;
+
+ if (pd()->wants_padded_bias()) {
+ auto padded_bias = this->scratchpad(ctx).template get<data_t>(
+ key_conv_padded_bias);
+ utils::array_copy(padded_bias, bias, jcp.oc_without_padding);
+ utils::array_set(padded_bias + jcp.oc_without_padding, 0.f,
+ jcp.oc - jcp.oc_without_padding);
+ bias = padded_bias;
+ }
+
+ int dil_h = jcp.dilate_h + 1;
+ int dil_w = jcp.dilate_w + 1;
+ int str_h = jcp.stride_h;
+ int str_w = jcp.stride_w;
+
+ auto kernel_params = [&](int ur_w_step, int ow, int oh, int ih, int kh,
+ int kh_padding, int ch, int ch_num, int n) {
+ auto par_conv = jit_conv_call_s();
+
+ const int i_l_overflow = nstl::max(0, (jcp.l_pad - ow * str_w));
+ const int i_r_overflow = nstl::max(jcp.iw, (ow * str_w
+ + (jcp.kw - 1)*dil_w - jcp.l_pad + 1)) - jcp.iw;
+
+ const int iw = nstl::max((ow*str_w - jcp.l_pad
+ + div_up(i_l_overflow, dil_w)*dil_w), 0);
+ const int kw = div_up(i_l_overflow, dil_w);
+
+ const int kw_padding = jcp.kw - div_up(i_l_overflow, dil_w)
+ - div_up(i_r_overflow, dil_w);
+
+ par_conv.src = &src[src_d.blk_off(n, ch, ih, iw)];
+ par_conv.dst = &dst[dst_d.blk_off(n, ch, oh, ow)];
+
+ par_conv.filt = &weights[weights_d.blk_off(ch, 0, 0, kh, kw)];
+ if (bias) par_conv.bias = &bias[bias_d.blk_off(ch*jcp.ch_block)];
+
+ par_conv.kh_padding = (size_t)nstl::max(0, kh_padding);
+ par_conv.kw_padding = (size_t)nstl::max(0, kw_padding);
+
+ par_conv.ur_w = (size_t)ur_w_step;
+
+ par_conv.ch_blocks = nstl::min(ch + ch_num, jcp.nb_ch) - ch;
+
+ return par_conv;
+ };
+
+ const int chb_work = utils::div_up(jcp.nb_ch, jcp.nb_ch_blocking);
+ parallel_nd(jcp.mb, chb_work, jcp.oh,
+ [&](int n, int chb, int oh) {
+ int ch = chb * jcp.nb_ch_blocking;
+ int ch_num = jcp.nb_ch_blocking;
+
+ const int i_t_overflow = nstl::max(0, (int)(jcp.t_pad - oh*str_h));
+ const int i_b_overflow = nstl::max(jcp.ih,
+ (int)(oh*str_h + (jcp.kh - 1)*dil_h - jcp.t_pad + 1)) - jcp.ih;
+
+ const int ih = nstl::max((int)(oh*str_h - jcp.t_pad
+ + div_up(i_t_overflow, dil_h)*dil_h), 0);
+ const int kh = div_up(i_t_overflow, dil_h);
+ const int kh_padding = jcp.kh - div_up(i_t_overflow, dil_h)
+ - div_up(i_b_overflow, dil_h);
+
+ // left border
+ int ow = 0;
+ int l_border = nstl::min(div_up(jcp.l_pad, str_w), jcp.ow);
+ int ur_w_step = 1;
+ for (; ow < l_border; ow++) {
+ jit_conv_call_s par_conv = kernel_params(ur_w_step, ow, oh, ih,
+ kh, kh_padding, ch, ch_num, n);
+
+ kernel_->jit_ker(&par_conv);
+ }
+
+ // main loop
+ ur_w_step = (jcp.iw - (jcp.kw - 1)*dil_w + jcp.l_pad - 1)
+ / jcp.stride_w - ow + 1;
+ if (ur_w_step > 0) {
+ jit_conv_call_s par_conv = kernel_params(ur_w_step, ow, oh, ih,
+ kh, kh_padding, ch, ch_num, n);
+
+ kernel_->jit_ker(&par_conv);
+
+ ow += ur_w_step;
+ }
+
+ // right border
+ ur_w_step = 1;
+ for (; ow < jcp.ow; ow++) {
+ jit_conv_call_s par_conv = kernel_params(ur_w_step, ow, oh, ih,
+ kh, kh_padding, ch, ch_num, n);
+
+ kernel_->jit_ker(&par_conv);
+ }
+ });
+
+ if (pd()->wants_zero_pad_dst())
+ ctx.memory(MKLDNN_ARG_DST)->zero_pad();
+}
+
+template struct _jit_uni_dw_convolution_fwd_t<avx512_common>;
+template struct _jit_uni_dw_convolution_fwd_t<avx2>;
+template struct _jit_uni_dw_convolution_fwd_t<sse42>;
+
+template <cpu_isa_t isa>
+void _jit_uni_dw_convolution_bwd_data_t<isa>::execute_backward_data(
+ const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+
+ const auto &jcp = kernel_->jcp;
+
+ auto kernel_params = [&](int ur_str_w, int iw, int oh, int ih,
+ int i_t_overflow, int i_b_overflow, int stride_off_h,
+ int ch, int ch_num, int n) {
+ auto par_conv = jit_conv_call_s();
+
+ const int i_l_overflow = nstl::max(0, (jcp.kw - 1 - iw - jcp.l_pad));
+ const int i_r_overflow = nstl::max(0, (jcp.kw - 1 - (jcp.iw - 1 - iw)
+ - jcp.r_pad));
+
+ int ow = iw + jcp.l_pad - i_r_overflow;
+ int stride_off_w = ow % jcp.stride_w;
+ ow /= jcp.stride_w;
+
+ par_conv.src = &diff_src[diff_src_d.blk_off(n, ch, ih, iw)];
+ par_conv.dst = &diff_dst[diff_dst_d.blk_off(n, ch, oh, ow)];
+ par_conv.filt = &weights[weights_d.blk_off(ch, 0, 0, i_b_overflow
+ + stride_off_h, i_r_overflow + stride_off_w)];
+
+ par_conv.kh_padding = nstl::max(0, jcp.kh - i_t_overflow - i_b_overflow
+ - stride_off_h);
+ par_conv.kw_padding = nstl::max(0, jcp.kw - i_l_overflow - i_r_overflow
+ - stride_off_w);
+
+ par_conv.ur_str_w = ur_str_w;
+
+ par_conv.ch_blocks = nstl::min(ch + ch_num, jcp.nb_ch) - ch;
+
+ return par_conv;
+ };
+
+ const int chb_work = utils::div_up(jcp.nb_ch, jcp.nb_ch_blocking);
+ parallel_nd(jcp.mb, chb_work, jcp.ih,
+ [&](int n, int chb, int ih) {
+ int ch = chb * jcp.nb_ch_blocking;
+ int ch_num = jcp.nb_ch_blocking;
+
+ const int i_t_overflow = nstl::max(0, (int)(jcp.kh - 1 - ih
+ - jcp.t_pad));
+ const int i_b_overflow = nstl::max(0, (int)(jcp.kh - 1
+ - (jcp.ih - 1 - ih) - jcp.b_pad));
+
+ int oh = ih + jcp.t_pad - i_b_overflow;
+ int stride_off_h = oh % jcp.stride_h;
+ oh /= jcp.stride_h;
+
+ for (int i_str_w = 0; i_str_w < jcp.stride_w; i_str_w++) {
+ // left border
+ int iw = i_str_w;
+ int l_border = nstl::min(jcp.kw - 1 - jcp.l_pad, jcp.iw);
+ int ur_str_w = 1;
+ for (; iw < l_border; iw += jcp.stride_w) {
+ jit_conv_call_s par_conv = kernel_params(ur_str_w, iw, oh,
+ ih, i_t_overflow, i_b_overflow,
+ stride_off_h, ch, ch_num, n);
+
+ kernel_->jit_ker(&par_conv);
+ }
+
+ // main loop
+ ur_str_w = nstl::min((jcp.iw - jcp.kw + jcp.r_pad - iw)
+ / jcp.stride_w, jcp.iw);
+ if (ur_str_w > 0) {
+ jit_conv_call_s par_conv = kernel_params(ur_str_w, iw, oh,
+ ih, i_t_overflow, i_b_overflow,
+ stride_off_h, ch, ch_num, n);
+
+ kernel_->jit_ker(&par_conv);
+
+ iw += ur_str_w * jcp.stride_w;
+ }
+
+ // right border
+ ur_str_w = 1;
+ for (; iw < jcp.iw; iw += jcp.stride_w) {
+ jit_conv_call_s par_conv = kernel_params(ur_str_w, iw, oh,
+ ih, i_t_overflow, i_b_overflow,
+ stride_off_h, ch, ch_num, n);
+
+ kernel_->jit_ker(&par_conv);
+ }
+ }
+ });
+}
+
+template struct _jit_uni_dw_convolution_bwd_data_t<avx512_common>;
+template struct _jit_uni_dw_convolution_bwd_data_t<avx2>;
+template struct _jit_uni_dw_convolution_bwd_data_t<sse42>;
+
+template <cpu_isa_t isa>
+_jit_uni_dw_convolution_bwd_weights_t<isa>::
+_jit_uni_dw_convolution_bwd_weights_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , kernel_(nullptr), acc_ker_(nullptr)
+{
+ kernel_ = new jit_uni_dw_conv_bwd_weights_kernel_f32<isa>(pd()->jcp_);
+ if (pd()->jcp_.nthr_mb > 1 && do_parallel_reduction())
+ acc_ker_ = new cpu_accumulator_1d_t<data_type::f32>();
+}
+
+template <cpu_isa_t isa>
+void _jit_uni_dw_convolution_bwd_weights_t<isa>::execute_backward_weights(
+ const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_weights = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_WEIGHTS);
+ auto diff_bias = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_BIAS);
+
+ auto diff_wei_reduction_buf =
+ scratchpad(ctx).template get<data_t>(key_conv_wei_reduction);
+ auto diff_bia_reduction_buf =
+ scratchpad(ctx).template get<data_t>(key_conv_bia_reduction);
+
+ const auto &jcp = kernel_->jcp;
+
+ /* Used when executing a parallel reduction */
+ simple_barrier::ctx_t reduction_bctx;
+ simple_barrier::ctx_init(&reduction_bctx);
+
+ const size_t wei_size = jcp.ngroups * jcp.kh * jcp.kw;
+ const size_t bias_size = jcp.with_bias ? jcp.ngroups : 0;
+
+ const int ch_block = jcp.ch_block;
+
+ auto set_kernel_params = [&](jit_dw_conv_call_s *conv_params,
+ const int batch, const int group, const int oh_start,
+ const int work_size, const unsigned char exec_flag,
+ const size_t kh_padding, const size_t filter_off) {
+ const int tpad_underflow_off = jcp.t_pad - filter_off;
+
+ conv_params->exec_flags = exec_flag;
+ conv_params->kh_count = jcp.kh - kh_padding;
+
+ const int oh_s = oh_start;
+ const int oh_e = oh_start + work_size;
+ const int ih_s = oh_s * jcp.stride_h;
+
+ conv_params->filter_pad_off
+ = filter_off * jcp.kw * ch_block * sizeof(float);
+ conv_params->oh_index = oh_s;
+ conv_params->oh_count = oh_e;
+
+ size_t diff_dst_off
+ = ((batch * (jcp.ngroups / ch_block) + group) * jcp.oh
+ + oh_start)
+ * jcp.ow;
+
+ size_t src_off = ((batch * (jcp.ngroups / ch_block) + group) * jcp.ih
+ + ih_s - tpad_underflow_off) * jcp.iw;
+
+ conv_params->output = &diff_dst[diff_dst_off * ch_block];
+ conv_params->input = &src[src_off * ch_block];
+ };
+
+ parallel(jcp.nthr, [&](const int ithr, const int nthr) {
+ assert(nthr == jcp.nthr);
+
+ auto conv_params = jit_dw_conv_call_s();
+ const int h_block_size = 15;
+
+ /* assign iteration space to thread */
+ const int ithr_g = ithr % jcp.nthr_g;
+ const int ithr_mb = (ithr / jcp.nthr_g) % jcp.nthr_mb;
+
+ /* split dimensions */
+ int g_start{ 0 }, g_end{ 0 };
+ balance211(jcp.nb_ch, jcp.nthr_g, ithr_g, g_start, g_end);
+
+ int mb_start{ 0 }, mb_end{ 0 };
+ balance211(jcp.mb, jcp.nthr_mb, ithr_mb, mb_start, mb_end);
+
+ auto diff_wei = ithr_mb == 0
+ ? diff_weights : diff_wei_reduction_buf + (ithr_mb - 1) * wei_size;
+ auto diff_bia = ithr_mb == 0
+ ? diff_bias : diff_bia_reduction_buf + (ithr_mb - 1) * bias_size;
+
+ for (int g = g_start; g < g_end; ++g) {
+ unsigned char zero_filter_flag = FLAG_ZERO_FILTER;
+ unsigned char zero_bias_flag = jcp.with_bias ? FLAG_ZERO_BIAS : 0;
+
+ size_t diff_wei_off = g * jcp.kh * jcp.kw;
+ conv_params.filter = &diff_wei[diff_wei_off * ch_block];
+
+ if (jcp.with_bias)
+ conv_params.bias = &diff_bia[g * ch_block];
+
+ for (int mb = mb_start; mb < mb_end; ++mb) {
+ int oh = 0;
+ while (oh < jcp.oh) {
+ const int h_work = nstl::min(h_block_size, jcp.oh - oh);
+ auto kh_t_padding = nstl::max(0, jcp.t_pad - oh);
+ auto kh_b_padding
+ = (oh * jcp.stride_h + jcp.kh - 1 > jcp.ih) ?
+ jcp.b_pad - (h_work - 1) :
+ 0;
+
+ set_kernel_params(&conv_params, mb, g, oh, h_work,
+ zero_filter_flag | zero_bias_flag,
+ kh_t_padding + kh_b_padding, kh_t_padding);
+ kernel_->jit_ker(&conv_params);
+
+ zero_bias_flag &= ~FLAG_ZERO_BIAS;
+ zero_filter_flag &= ~FLAG_ZERO_FILTER;
+ oh += h_work;
+ }
+ }
+ }
+
+ if (do_parallel_reduction() && jcp.nthr_mb > 1) {
+ size_t reduct_start{ 0 }, reduct_end{ 0 };
+ balance211(wei_size, nthr, ithr, reduct_start, reduct_end);
+
+ const int acc_size = reduct_end - reduct_start;
+ const size_t reduct_off = reduct_start;
+ auto *acc_data = diff_weights + reduct_off;
+
+ simple_barrier::barrier(&reduction_bctx, nthr);
+
+ for (int thr_mb = 1; thr_mb < jcp.nthr_mb; ++thr_mb) {
+ auto *src_data = diff_wei_reduction_buf
+ + (thr_mb - 1) * wei_size + reduct_off;
+ acc_ker_->accumulate(acc_data, src_data, acc_size);
+ }
+ }
+ });
+
+ if (jcp.nthr_mb <= 1) return;
+
+ /* Apply single-threaded 'mb' reduction */
+ for (int thr_mb = 1; thr_mb < jcp.nthr_mb; ++thr_mb) {
+ size_t mb_accum_offset = (thr_mb - 1) * wei_size;
+ size_t b_accum_offset = (thr_mb - 1) * bias_size;
+
+ for (int g = 0; g < jcp.nb_ch; ++g) {
+ /* Reduction on Bias */
+ if (jcp.with_bias) {
+ PRAGMA_OMP_SIMD()
+ for (int g_block = 0; g_block < ch_block; ++g_block) {
+ size_t bias_offset = g * ch_block + g_block;
+ diff_bias[bias_offset] += diff_bia_reduction_buf[
+ b_accum_offset + bias_offset];
+ }
+ }
+
+ if (do_parallel_reduction()) continue;
+
+ for (int kh = 0; kh < jcp.kh; ++kh)
+ for (int kw = 0; kw < jcp.kw; ++kw)
+ {
+ size_t wei_offset = (g * jcp.kh + kh) * jcp.kw + kw;
+ PRAGMA_OMP_SIMD()
+ for (int g_block = 0; g_block < ch_block; ++g_block) {
+ const size_t off = wei_offset * ch_block + g_block;
+ diff_weights[off] +=
+ diff_wei_reduction_buf[mb_accum_offset + off];
+ }
+ }
+ }
+ }
+}
+
+template struct _jit_uni_dw_convolution_bwd_weights_t<avx512_common>;
+template struct _jit_uni_dw_convolution_bwd_weights_t<avx2>;
+template struct _jit_uni_dw_convolution_bwd_weights_t<sse42>;
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_convolution.hpp
new file mode 100644
index 0000000000..ca53749ec2
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_dw_convolution.hpp
@@ -0,0 +1,266 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_UNI_DW_CONVOLUTION_HPP
+#define CPU_JIT_UNI_DW_CONVOLUTION_HPP
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+
+#include "cpu_barrier.hpp"
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+#include "cpu_reducer.hpp"
+
+#include "jit_uni_dw_conv_kernel_f32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <cpu_isa_t isa>
+struct _jit_uni_dw_convolution_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_fwd_pd_t {
+ pd_t(engine_t *engine, const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const typename pd_t::base_class *hint_fwd_pd)
+ : cpu_convolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_dw:", isa, ""),
+ _jit_uni_dw_convolution_fwd_t<isa>);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_uni_dw_conv_fwd_kernel_f32<isa>::init_conf(
+ jcp_, *desc(), src_md(), *weights_md(), *dst_md(), *attr());
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_uni_dw_conv_fwd_kernel_f32<isa>::init_scratchpad(scratchpad,
+ jcp_);
+
+ return status::success;
+ }
+
+ jit_conv_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = isa == avx512_common ? nChw16c : nChw8c;
+ auto wei_tag = isa == avx512_common ? Goihw16g : Goihw8g;
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ _jit_uni_dw_convolution_fwd_t(const pd_t *apd): cpu_primitive_t(apd)
+ { kernel_ = new jit_uni_dw_conv_fwd_kernel_f32<isa>(pd()->jcp_); }
+
+ ~_jit_uni_dw_convolution_fwd_t() { delete kernel_; }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_uni_dw_conv_fwd_kernel_f32<isa> *kernel_;
+};
+
+using jit_avx512_common_dw_convolution_fwd_t =
+ _jit_uni_dw_convolution_fwd_t<avx512_common>;
+using jit_avx2_dw_convolution_fwd_t = _jit_uni_dw_convolution_fwd_t<avx2>;
+using jit_sse42_dw_convolution_fwd_t = _jit_uni_dw_convolution_fwd_t<sse42>;
+
+template <cpu_isa_t isa>
+struct _jit_uni_dw_convolution_bwd_data_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_data_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_data_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_()
+ {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_dw:", isa, ""),
+ _jit_uni_dw_convolution_bwd_data_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_data
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::undef, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+
+ if (!ok) return status::unimplemented;
+
+ status_t status = jit_uni_dw_conv_bwd_data_kernel_f32<isa>::
+ init_conf(jcp_, *desc(), *diff_src_md(), *weights_md(),
+ *diff_dst_md());
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_uni_dw_conv_bwd_data_kernel_f32<isa>::init_scratchpad(
+ scratchpad, jcp_);
+
+ return status::success;
+ }
+
+ jit_conv_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = isa == avx512_common ? nChw16c : nChw8c;
+ auto wei_tag = isa == avx512_common ? Goihw16g : Goihw8g;
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ _jit_uni_dw_convolution_bwd_data_t(const pd_t *apd): cpu_primitive_t(apd)
+ { kernel_ = new jit_uni_dw_conv_bwd_data_kernel_f32<isa>(pd()->jcp_); }
+ ~_jit_uni_dw_convolution_bwd_data_t() { delete kernel_; };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_data(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_data(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_uni_dw_conv_bwd_data_kernel_f32<isa> *kernel_;
+};
+
+using jit_avx512_common_dw_convolution_bwd_data_t =
+ _jit_uni_dw_convolution_bwd_data_t<avx512_common>;
+using jit_avx2_dw_convolution_bwd_data_t =
+ _jit_uni_dw_convolution_bwd_data_t<avx2>;
+using jit_sse42_dw_convolution_bwd_data_t =
+ _jit_uni_dw_convolution_bwd_data_t<sse42>;
+
+template <cpu_isa_t isa>
+struct _jit_uni_dw_convolution_bwd_weights_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_weights_pd_t {
+ pd_t(engine_t *engine,
+ const convolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const convolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_convolution_bwd_weights_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , jcp_() {}
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit_dw:", isa, ""),
+ _jit_uni_dw_convolution_bwd_weights_t<isa>);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_weights
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(data_type::f32, data_type::f32,
+ data_type::f32, data_type::f32, data_type::f32)
+ && !has_zero_dim_memory()
+ && set_default_formats();
+ if (!ok) return status::unimplemented;
+
+ const int max_threads = mkldnn_in_parallel()
+ ? 1 : mkldnn_get_max_threads();
+
+ status_t status = jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::
+ init_conf(jcp_, *desc(), *src_md(), *diff_weights_md(),
+ *diff_dst_md(), max_threads);
+ if (status != status::success) return status;
+
+ auto scratchpad = scratchpad_registry().registrar();
+ jit_uni_dw_conv_bwd_weights_kernel_f32<isa>::init_scratchpad(
+ scratchpad, jcp_);
+
+ return status::success;
+ }
+
+ jit_conv_conf_t jcp_;
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+
+ auto dat_tag = isa == avx512_common ? nChw16c : nChw8c;
+ auto wei_tag = isa == avx512_common ? Goihw16g : Goihw8g;
+
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ _jit_uni_dw_convolution_bwd_weights_t(const pd_t *apd);
+ ~_jit_uni_dw_convolution_bwd_weights_t() {
+ delete kernel_;
+ delete acc_ker_;
+ };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_weights(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_weights(const exec_ctx_t &ctx) const;
+ bool do_parallel_reduction() const { return false; }
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_uni_dw_conv_bwd_weights_kernel_f32<isa> *kernel_;
+ cpu_accumulator_1d_t<data_type::f32> *acc_ker_;
+};
+
+using jit_avx512_common_dw_convolution_bwd_weights_t =
+ _jit_uni_dw_convolution_bwd_weights_t<avx512_common>;
+using jit_avx2_dw_convolution_bwd_weights_t =
+ _jit_uni_dw_convolution_bwd_weights_t<avx2>;
+using jit_sse42_dw_convolution_bwd_weights_t =
+ _jit_uni_dw_convolution_bwd_weights_t<sse42>;
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_eltwise.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_eltwise.cpp
new file mode 100644
index 0000000000..2af6435871
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_eltwise.cpp
@@ -0,0 +1,1142 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "nstl.hpp"
+#include "utils.hpp"
+
+#include "jit_uni_eltwise.hpp"
+
+#define GET_OFF(field) offsetof(jit_args, field)
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace Xbyak;
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::injector_preamble(size_t start_idx,
+ size_t end_idx) {
+ preserved_vecs_count = 0;
+ vecs_to_preserve = (size_t)aux_vecs_count(alg_);
+ start_idx_tail = start_idx;
+
+ // For sse42 mask register has to be Xmm(0)
+ if (isa == sse42 && vecs_to_preserve > 0) {
+ size_t idx = 0;
+ assert(idx < start_idx);
+ preserved_vec_idxs[preserved_vecs_count++] = idx;
+ }
+
+ for (size_t idx = preserved_vecs_count; idx < vecs_count; idx++) {
+ if (preserved_vecs_count >= vecs_to_preserve) break;
+ if (start_idx <= idx && idx < end_idx) continue;
+
+ preserved_vec_idxs[preserved_vecs_count++] = idx;
+ }
+
+ size_t preserved_vecs_count_tail = vecs_to_preserve - preserved_vecs_count;
+ for (size_t i = 0; i < preserved_vecs_count_tail; i++) {
+ preserved_vec_idxs[preserved_vecs_count++] = start_idx_tail++;
+ }
+
+ assert(preserved_vecs_count == vecs_to_preserve);
+
+ if (save_state_) {
+ h->push(p_table);
+
+ if (preserved_vecs_count)
+ h->sub(h->rsp, preserved_vecs_count * vlen);
+
+ for (size_t i = 0; i < preserved_vecs_count; ++i)
+ h->uni_vmovups(h->ptr[h->rsp + i * vlen],
+ Vmm(preserved_vec_idxs[i]));
+
+ load_table_addr();
+ }
+
+ assign_regs();
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::injector_preamble_tail(size_t start_idx)
+{
+ size_t tail_vecs_to_preserve = start_idx_tail - start_idx;
+ if (tail_vecs_to_preserve == 0) return;
+
+ const int idx_off = vecs_to_preserve - tail_vecs_to_preserve;
+
+ if (save_state_) {
+ if (idx_off)
+ h->add(h->rsp, idx_off * vlen);
+
+ for (size_t i = 0; i < tail_vecs_to_preserve; ++i)
+ h->uni_vmovups(Vmm(preserved_vec_idxs[idx_off + i]),
+ h->ptr[h->rsp + i * vlen]);
+ }
+
+ for (size_t i = 0; i < tail_vecs_to_preserve; ++i)
+ preserved_vec_idxs[idx_off + i] += tail_vecs_to_preserve;
+
+ if (save_state_) {
+ for (size_t i = 0; i < tail_vecs_to_preserve; ++i)
+ h->uni_vmovups(h->ptr[h->rsp + i * vlen],
+ Vmm(preserved_vec_idxs[idx_off + i]));
+
+ if (idx_off)
+ h->sub(h->rsp, idx_off * vlen);
+ }
+
+ assign_regs();
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::injector_postamble() {
+ if (!save_state_) return;
+
+ for (size_t i = 0; i < preserved_vecs_count; ++i)
+ h->uni_vmovups(Vmm(preserved_vec_idxs[i]),
+ h->ptr[h->rsp + i * vlen]);
+
+ if (preserved_vecs_count)
+ h->add(h->rsp, preserved_vecs_count * vlen);
+
+ h->pop(p_table);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::assign_regs() {
+ vmm_mask = Vmm(preserved_vec_idxs[0]);
+ vmm_aux0 = Vmm(preserved_vec_idxs[0]);
+ vmm_aux1 = Vmm(preserved_vec_idxs[1]);
+ vmm_aux2 = Vmm(preserved_vec_idxs[2]);
+ vmm_aux3 = Vmm(preserved_vec_idxs[3]);
+ vmm_aux4 = Vmm(preserved_vec_idxs[4]);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::exp_compute_vector(const Vmm &vmm_src) {
+ h->uni_vminps(vmm_src, vmm_src, table_val(10));
+ h->uni_vmaxps(vmm_src, vmm_src, table_val(11));
+ h->uni_vmovups(vmm_aux0, vmm_src);
+ //calculate exp(x)
+ // fx = x * log2ef + 0.5
+ h->uni_vmulps(vmm_src, vmm_src, table_val(2));
+ h->uni_vaddps(vmm_src, vmm_src, table_val(1));
+
+ // tmp = floorf(fx)
+ if (isa == avx512_common) {
+ h->vcvtps2dq(vmm_aux1 | h->T_rd_sae, vmm_src);
+ h->vcvtdq2ps(vmm_aux1, vmm_aux1);
+
+ h->vcmpps(k_mask, vmm_aux1, vmm_src, _cmp_nle_us);
+ h->vmovups(vmm_aux3 | k_mask | h->T_z, table_val(0));
+
+ h->uni_vsubps(vmm_aux1, vmm_aux1, vmm_aux3);
+ } else {
+ h->uni_vroundps(vmm_aux1, vmm_src, _op_floor);
+ }
+
+ //keep fx for further computations
+ h->uni_vmovups(vmm_src, vmm_aux1); //vmm_src = fx
+
+ //x = x - fx * ln2
+ h->uni_vfnmadd231ps(vmm_aux0, vmm_aux1, table_val(3));
+
+ // compute 2^n
+ h->uni_vcvtps2dq(vmm_aux1, vmm_src);
+ h->uni_vpaddd(vmm_aux1, vmm_aux1, table_val(4));
+ h->uni_vpslld(vmm_aux1, vmm_aux1, 23); //Vmm(6) = 2^-fx
+
+ // y = p5
+ h->uni_vmovups(vmm_src, table_val(9));
+ // y = y * x + p4
+ h->uni_vfmadd213ps(vmm_src, vmm_aux0, table_val(8));
+ // y = y * x + p3
+ h->uni_vfmadd213ps(vmm_src, vmm_aux0, table_val(7));
+ // y = y * x + p2
+ h->uni_vfmadd213ps(vmm_src, vmm_aux0, table_val(6));
+ // y = y * x + p1
+ h->uni_vfmadd213ps(vmm_src, vmm_aux0, table_val(0));
+ // y = y * x + p0
+ h->uni_vfmadd213ps(vmm_src, vmm_aux0, table_val(5)); //exp(q)
+ // y = y * 2^n
+ h->uni_vmulps(vmm_src, vmm_src, vmm_aux1);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::relu_compute_vector(const Vmm &vmm_src)
+{
+ const int alpha_off = 0, zero_off = 1;
+
+ h->uni_vmovups(vmm_aux1, vmm_src);
+ if (isa == sse42) {
+ h->movups(vmm_mask, vmm_src);
+ h->mulps(vmm_src, table_val(alpha_off));
+ h->cmpps(vmm_mask, table_val(zero_off), _cmp_nle_us);
+ h->blendvps(vmm_src, vmm_aux1);
+ } else if (isa == avx2) {
+ h->vmulps(vmm_src, vmm_src, table_val(alpha_off));
+ h->vcmpgtps(vmm_mask, vmm_aux1, table_val(zero_off));
+ h->vblendvps(vmm_src, vmm_src, vmm_aux1, vmm_mask);
+ } else if (isa == avx512_common) {
+ h->vmulps(vmm_src, vmm_src, table_val(alpha_off));
+ h->vcmpps(k_mask, vmm_aux1, table_val(zero_off), _cmp_nle_us);
+ h->vblendmps(vmm_src | k_mask, vmm_src, vmm_aux1);
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::relu_zero_ns_compute_vector(
+ const Vmm &vmm_src) {
+ const int zero_off = 1;
+ h->uni_vmaxps(vmm_src, vmm_src, table_val(zero_off));
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::elu_compute_vector(const Vmm &vmm_src) {
+ const int alpha_off = 23, zero_off = 24;
+
+ // compute exponent
+ h->uni_vmovups(vmm_aux2, vmm_src);
+ exp_compute_vector(vmm_src);
+
+ // alpha * (exp(x) - 1)
+ h->uni_vsubps(vmm_src, vmm_src, table_val(0));
+ h->uni_vmulps(vmm_src, vmm_src, table_val(alpha_off));
+
+ // combine with mask
+ if (isa == sse42) {
+ h->pxor(vmm_mask, vmm_mask);
+ h->cmpps(vmm_mask, vmm_aux2, _cmp_le_os);
+ h->blendvps(vmm_src, vmm_aux2);
+ } else if (isa == avx2) {
+ h->uni_vcmpgtps(vmm_mask, vmm_aux2, table_val(zero_off));
+ h->uni_vblendvps(vmm_src, vmm_src, vmm_aux2, vmm_mask);
+ } else if (isa == avx512_common) {
+ h->vcmpps(k_mask, vmm_aux2, table_val(zero_off), _cmp_nle_us);
+ h->vblendmps(vmm_src | k_mask, vmm_src, vmm_aux2);
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::tanh_compute_vector(const Vmm &vmm_src)
+{
+ // # comes from Taylor expansion error bound
+ // > linear_sat_point = single(sqrt(3) * 1b-12);
+ // # comes from the exp formula cancellation
+ // > exp_bound_point = (single(log(3)/2));
+ // # comes from rounding accuracy in float
+ // > one_sat_point = round(atanh(1 - 1b-25), single, RU);
+ // > P = fpminimax(f, [|1, 3, 5, 7, 9|], [|24... |],
+ // [linear_sat_point, exp_bound_point], relative, floating);
+ // > err_bound = D(sup(supnorm(P, tanh(x),
+ // [linear_sat_point, exp_bound_point], relative, theta)));
+ // 0x1.fffd6f00b9539p-25
+ // > P;
+ // x * (0x1.fffffep-1 + x^0x1p1 * (-0x1.55539ep-2 + x^0x1p1 *
+ // (0x1.10be3ep-3 + x^0x1p1 * (-0x1.ae57b4p-5
+ // + x^0x1p1 * 0x1.09fa1p-6))))
+
+ // register mapping
+ // vmm_src contains input
+ // vmm_aux0 contains mask of currently valid results.
+ // 1 is need computation, 0 is already computed
+ // vmm_aux1 contains current output
+ // vmm_aux2, vmm_aux3 contains auxiliary values
+ // vmm_aux4 contains the original sign of inputs
+
+ Label end_tanh_label;
+
+ auto test_exit =[&](Xbyak::Address threshold){
+ // is not necessary for >AVX, but should not matter on perf
+ h->uni_vmovups(vmm_aux0, vmm_src);
+ if (isa == avx512_common){
+ h->vcmpps(k_mask, vmm_aux0, threshold, 0x5);
+ h->kortestw(k_mask, k_mask);
+ } else {
+ h->uni_vcmpgeps(vmm_aux0, vmm_aux0, threshold);
+ h->uni_vtestps(vmm_aux0, vmm_aux0);
+ }
+ h->jz(end_tanh_label, Xbyak::CodeGenerator::T_NEAR);
+ };
+
+ auto blend_results=[&](Vmm vmm_partial_res){
+ if (isa == avx512_common)
+ h->vblendmps(vmm_aux1 | k_mask, vmm_aux1, vmm_partial_res);
+ else
+ h->uni_vblendvps(vmm_aux1, vmm_aux1, vmm_partial_res, vmm_aux0);
+ };
+
+ // because tanh(x) = -tanh(-x), we extract sign to make x postive
+ // and reapply sign at the end
+ // mov is not necessary for >AVX, but should not matter for performance
+ h->uni_vmovups(vmm_aux4, vmm_src);
+ h->uni_vandps(vmm_aux4, vmm_aux4, table_val(12));
+ h->uni_vandps(vmm_src, vmm_src, table_val(17));
+
+ // if x < linear_sat_point for all inputs, we just return the input
+ h->uni_vmovups(vmm_aux1, vmm_src);
+ test_exit(table_val(13));
+
+ // if one of the mask is one, we have to compute an better approx
+ h->uni_vmovups(vmm_aux2, vmm_src);
+ h->uni_vmulps(vmm_aux2, vmm_aux2, vmm_aux2);
+ h->uni_vmovups(vmm_aux3, table_val(22));
+ h->uni_vfmadd213ps(vmm_aux3, vmm_aux2, table_val(21));
+ h->uni_vfmadd213ps(vmm_aux3, vmm_aux2, table_val(20));
+ h->uni_vfmadd213ps(vmm_aux3, vmm_aux2, table_val(19));
+ h->uni_vfmadd213ps(vmm_aux3, vmm_aux2, table_val(18));
+ h->uni_vmulps(vmm_aux3, vmm_aux3, vmm_src);
+
+ // we blend only the result that need update
+ blend_results(vmm_aux3);
+
+ // if x < exp_bound_point, we go to return point
+ test_exit(table_val(14));
+
+ // if not we use a better approx 1 - 2 / (1 + exp(2x))
+ // compute 2x
+ h->uni_vmovups(vmm_aux3, vmm_src);
+ h->uni_vaddps(vmm_aux3, vmm_aux3, vmm_aux3);
+
+ // Compute exp(2x)
+ // We need to save kmask, vmm_aux0, vmm_aux1 and vmm_src as exp can use them
+ // vmm_src is not more read afterwards, so we do not have to save it
+ auto stack_size = 3 * vlen + (isa == avx512_common) * 4;
+ h->sub(h->rsp, stack_size);
+ h->uni_vmovups(h->ptr[h->rsp + 0 * vlen], vmm_aux0);
+ h->uni_vmovups(h->ptr[h->rsp + 1 * vlen], vmm_aux1);
+ h->uni_vmovups(h->ptr[h->rsp + 2 * vlen], vmm_src);
+ if (isa == avx512_common)
+ h->kmovw(h->ptr[h->rsp + 3 * vlen], k_mask);
+
+ exp_compute_vector(vmm_aux3);
+
+ h->uni_vmovups(vmm_aux0, h->ptr[h->rsp + 0 * vlen]);
+ h->uni_vmovups(vmm_aux1, h->ptr[h->rsp + 1 * vlen]);
+ h->uni_vmovups(vmm_src, h->ptr[h->rsp + 2 * vlen]);
+ if (isa == avx512_common)
+ h->kmovw(k_mask, h->ptr[h->rsp + 3 * vlen]);
+ h->add(h->rsp, stack_size);
+
+ // 1 + exp(2x)
+ h->uni_vaddps(vmm_aux3, vmm_aux3, table_val(0));
+
+ // 1 - 2 / (1 + exp(2x))
+ h->uni_vmovups(vmm_aux2, table_val(16));
+ h->uni_vdivps(vmm_aux2, vmm_aux2, vmm_aux3);
+ h->uni_vaddps(vmm_aux2, vmm_aux2, table_val(0));
+
+ // we blend only the result that need update
+ blend_results(vmm_aux2);
+
+ // finally, we saturate to 1 if needed
+ // TODO: maybe move that up if most inputs saturate in practice
+ if (isa == avx512_common)
+ h->vcmpps(k_mask, vmm_aux0, table_val(15), 0x5);
+ else {
+ h->uni_vmovups(vmm_aux0, vmm_src);
+ h->uni_vcmpgeps(vmm_aux0, vmm_aux0, table_val(15));
+ }
+ h->uni_vmovups(vmm_aux2, table_val(0));
+ blend_results(vmm_aux2);
+
+ h->L(end_tanh_label);
+ {
+ // we apply the sign of x to the result and we are done
+ h->uni_vmovups(vmm_src, vmm_aux1);
+ h->uni_vpxor(vmm_src, vmm_src, vmm_aux4);
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::square_compute_vector(
+ const Vmm &vmm_src) {
+ h->uni_vmulps(vmm_src, vmm_src, vmm_src);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::abs_compute_vector(const Vmm &vmm_src) {
+ // compute abs(x) = _mm_and_ps(x, 01111..111));
+ h->uni_vandps(vmm_src, vmm_src, table_val(0));
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::sqrt_compute_vector(const Vmm &vmm_src)
+{
+ if (isa == avx512_common) {
+ h->vcmpps(k_mask, vmm_src, table_val(0), _cmp_nle_us);
+ h->uni_vsqrtps(vmm_aux1, vmm_src);
+ h->uni_vmovups(vmm_src, table_val(0));
+ h->vblendmps(vmm_src | k_mask, vmm_src, vmm_aux1);
+ } else {
+ h->uni_vmovups(vmm_mask, vmm_src);
+ h->uni_vcmpgtps(vmm_mask, vmm_mask, table_val(0));
+ h->uni_vsqrtps(vmm_aux1, vmm_src);
+ h->uni_vmovups(vmm_src, table_val(0));
+ h->uni_vblendvps(vmm_src, vmm_src, vmm_aux1, vmm_mask);
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::linear_compute_vector(
+ const Vmm &vmm_src) {
+ // compute x = alpha * x + beta;
+ h->uni_vmovups(vmm_aux0, table_val(0));
+ h->uni_vfmadd213ps(vmm_src, vmm_aux0, table_val(1));
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::bounded_relu_compute_vector(
+ const Vmm &vmm_src) {
+ // compute bounded relu */
+ h->uni_vmaxps(vmm_src, vmm_src, table_val(1));
+ h->uni_vminps(vmm_src, vmm_src, table_val(0));
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::soft_relu_compute_vector(
+ const Vmm &vmm_src) {
+ // duplicate src
+ h->uni_vmovups(vmm_aux2, vmm_src);
+
+ h->uni_vminps(vmm_src, vmm_src, table_val(24));
+ h->uni_vmaxps(vmm_src, vmm_src, table_val(25));
+ h->uni_vmovups(vmm_aux1, vmm_src);
+ // calculate exp(x)
+ // fx = x * log2ef + 0.5
+ h->uni_vmulps(vmm_src, vmm_src, table_val(2));
+ h->uni_vaddps(vmm_src, vmm_src, table_val(1));
+
+ // tmp = floorf(fx)
+ if (isa == avx512_common) {
+ h->vcvtps2dq(vmm_aux0 | h->T_rd_sae, vmm_src);
+ h->vcvtdq2ps(vmm_aux0, vmm_aux0);
+
+ h->vcmpps(k_mask, vmm_aux0, vmm_src, _cmp_nle_us);
+ h->vmovups(vmm_aux3 | k_mask | h->T_z, table_val(0));
+
+ h->vsubps(vmm_aux0, vmm_aux0, vmm_aux3);
+ } else {
+ h->uni_vroundps(vmm_aux0, vmm_src, _op_floor);
+ }
+
+ // keep fx for further computations
+ h->uni_vmovups(vmm_src, vmm_aux0); //vmm_src = fx
+ // calculation fx * ln2
+ h->uni_vmulps(vmm_aux0, vmm_aux0, table_val(3));
+ // x = x - fx * ln2
+ h->uni_vsubps(vmm_aux1, vmm_aux1, vmm_aux0);
+ // y = p5
+ h->uni_vmovups(vmm_aux3, table_val(22));
+ // y = y * x + p4
+ h->uni_vfmadd213ps(vmm_aux3, vmm_aux1, table_val(21));
+ // y = y * x + p3
+ h->uni_vfmadd213ps(vmm_aux3, vmm_aux1, table_val(20));
+ // y = y * x + p2
+ h->uni_vfmadd213ps(vmm_aux3, vmm_aux1, table_val(19));
+ // y = y * x + p1
+ h->uni_vfmadd213ps(vmm_aux3, vmm_aux1, table_val(0));
+ // y = y * x + p0
+ h->uni_vfmadd213ps(vmm_aux3, vmm_aux1, table_val(17));
+
+ // compute 2^(-n)
+ if (isa == avx512_common) {
+ h->vmulps(vmm_aux1, vmm_src, table_val(23));
+ h->vcvtps2dq(vmm_aux1, vmm_aux1);
+ } else {
+ h->uni_vcvtps2dq(vmm_aux1, vmm_src);
+ h->uni_vpsignd(vmm_aux1, vmm_aux1, table_val(23));
+ }
+
+ h->uni_vpaddd(vmm_aux1, vmm_aux1, table_val(4));
+ h->uni_vpslld(vmm_aux1, vmm_aux1, 23); //vmm_aux1 = 2^-fx
+ // calculate ln(1 + y)
+ h->uni_vaddps(vmm_aux3, vmm_aux3, vmm_aux1);
+ // x = y; y is free; keep x for further computations
+ h->uni_vmovups(vmm_src, vmm_aux3);
+ // frexp()
+ h->uni_vpsrld(vmm_src, vmm_src, 23);
+ h->uni_vcvtdq2ps(vmm_src, vmm_src);
+ // got n. where n is x = 2^n * y. y = 0.5 .. 1
+ h->uni_vsubps(vmm_src, vmm_src, table_val(5));
+
+ h->uni_vandps(vmm_aux3, vmm_aux3, table_val(6));
+ // got y. (mantisa) 0.5 < y < 1
+ h->uni_vorps(vmm_aux3, vmm_aux3, table_val(7));
+ // y = y - 1
+ h->uni_vsubps(vmm_aux3, vmm_aux3, table_val(0));
+ // y = p8
+ h->uni_vmovups(vmm_aux1, table_val(16));
+ // y = y * x + p7
+ h->uni_vfmadd213ps(vmm_aux1, vmm_aux3, table_val(15));
+ // y = y * x + p6
+ h->uni_vfmadd213ps(vmm_aux1, vmm_aux3, table_val(14));
+ // y = y * x + p5
+ h->uni_vfmadd213ps(vmm_aux1, vmm_aux3, table_val(13));
+ // y = y * x + p4
+ h->uni_vfmadd213ps(vmm_aux1, vmm_aux3, table_val(12));
+ // y = y * x + p3
+ h->uni_vfmadd213ps(vmm_aux1, vmm_aux3, table_val(11));
+ // y = y * x + p2
+ h->uni_vfmadd213ps(vmm_aux1, vmm_aux3, table_val(10));
+ // y = y * x + p1
+ h->uni_vfmadd213ps(vmm_aux1, vmm_aux3, table_val(9));
+ // y = y * x + p0 ; p0 = 0
+ h->uni_vfmadd213ps(vmm_aux1, vmm_aux3, table_val(8));
+ //calculate ln(2) * n
+ h->uni_vmulps(vmm_src, vmm_src, table_val(3));
+ h->uni_vaddps(vmm_aux1, vmm_aux1, vmm_src);
+ h->uni_vaddps(vmm_aux1, vmm_aux1, vmm_aux0);
+
+ // get vmm_mask = src > max logf
+ h->uni_vmovups(vmm_mask, vmm_aux2);
+ if (isa == avx512_common) {
+ // y = (x < max log f) ? soft_relu(x) : x
+ h->vcmpps(k_mask, vmm_mask, table_val(24), _cmp_nle_us);
+ h->vblendmps(vmm_aux1 | k_mask, vmm_aux1, vmm_aux2);
+ } else {
+ // y = (x < max log f) ? soft_relu(x) : x
+ h->uni_vcmpgtps(vmm_mask, vmm_mask, table_val(24));
+ h->uni_vblendvps(vmm_aux1, vmm_aux1, vmm_aux2, vmm_mask);
+ }
+
+ h->uni_vmovups(vmm_src, vmm_aux1);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::logistic_compute_vector(
+ const Vmm &vmm_src) {
+ // we store the original sign and make x negative
+ // IMPORTANT: we assume vmm_aux0 to be xmm0, as for sse4.2 path it is required
+ // IMPORTANT: we use vmm_aux2 for the mask as exp_compute does not use it.
+ h->uni_vmovups(vmm_aux2, vmm_src);
+ h->uni_vandps(vmm_aux2, vmm_aux2, table_val(12));
+ h->uni_vorps(vmm_src, vmm_src, table_val(12));
+
+ exp_compute_vector(vmm_src);
+ // dup exp(x)
+ h->uni_vmovups(vmm_aux1, vmm_src);
+ // (exp(x) + 1)
+ h->uni_vaddps(vmm_aux1, vmm_aux1, table_val(0));
+ // y = exp(x) / (exp(x) + 1)
+ h->uni_vdivps(vmm_src, vmm_src, vmm_aux1);
+
+ // Now we have to apply the "symmetry" based on original sign
+ h->uni_vmovups(vmm_aux3, table_val(0));
+ h->uni_vsubps(vmm_aux3, vmm_aux3, vmm_src);
+ if (isa == avx512_common) {
+ h->vptestmd(k_mask, vmm_aux2, vmm_aux2);
+ h->vblendmps(vmm_aux3 | k_mask, vmm_aux3, vmm_src);
+ } else {
+ h->uni_vmovups(vmm_aux0, vmm_aux2);// The mask should be xmm0 for sse4.2
+ h->uni_vblendvps(vmm_aux3, vmm_aux3, vmm_src, vmm_aux0);
+ }
+ h->uni_vmovups(vmm_src, vmm_aux3);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::relu_prepare_table() {
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) h->dd(float2int(alpha_));
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) h->dd(0);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::elu_prepare_table() {
+ const unsigned int cvals[] = {
+ 0x3f800000, // [0] 1.0f
+ 0x3f000000, // [1] 0.5f
+ 0x3fb8aa3b, // [2] log2ef = 1.44269502f
+ 0x3f317218, // [3] ln2f = 0.69314718f
+ 0x0000007f, // [4] 0x7f
+ // exp(x) polynom
+ 0x3f800001, // [5] p0 = 1.0000001f
+ 0x3efffe85, // [6] p2 = 0.4999887f
+ 0x3e2aaa3e, // [7] p3 = 0.16666505f
+ 0x3d2bb1b1, // [8] p4 = 0.041917507f
+ 0x3c091ec1, // [9] p5 = 0.008369149f
+ 0x42b0c0a5, //[10] max logf = 88.3762589f
+ 0xc1766666, //[11] min logf = -14.5f
+ // tanh(x) constants,
+ 0x80000000, //[12] mask to extract sign
+ 0x39ddb3d7, //[13] arg below which tanh(x) = x
+ 0x3f0c9f54, //[14] arg below which pol approx is valid
+ 0x41102cb4, //[15] arg after which tanh(x) = 1
+ 0xc0000000, //[16] -2.0f
+ 0x7fffffff, //[17] mask to make positive
+ // tanh pol approx
+ 0x3f7fffff, //[18] p0
+ 0xbeaaa9cf, //[19] p1
+ 0x3e085f1f, //[20] p2
+ 0xbd572bda, //[21] p3
+ 0x3c84fd08, //[22] p4
+ };
+
+ for (size_t i = 0; i < sizeof(cvals) / sizeof(cvals[0]); ++i) {
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) h->dd(cvals[i]);
+ }
+
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) h->dd(float2int(alpha_));
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) h->dd(0);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::soft_relu_prepare_table() {
+ const unsigned int cvals[] = {
+ 0x3f800000, // [0] 1.0f
+ 0x3f000000, // [1] 0.5f
+ 0x3fb8aa3b, // [2] log2ef = 1.44269502f
+ 0x3f317218, // [3] ln2f = 0.69314718f
+ 0x0000007f, // [4] 0x7f
+ 0x42fc0000, // [5] 126
+ 0x807fffff, // [6] and with (to get 0.5 * mantissa)
+ 0x3f000000, // [7] or with (to get 0.5 * mantissa)
+ // ln(1 + x) polynomial
+ 0xb2b4637d, // [8] p0 = 0.0000000244f
+ 0x3f7fff8e, // [9] p1 = 0.9999976971f
+ 0xbf001759, //[10] p2 = -0.5002478215f
+ 0x3ea70608, //[11] p3 = 0.3272714505f
+ 0xbea3d7bf, //[12] p4 = -0.3153830071f
+ 0xbe361d04, //[13] p5 = -0.1701777461f
+ 0xbfa8f1e6, //[14] p6 = -1.3254635147f
+ 0xbfe1e812, //[15] p7 = -1.7971917960f
+ 0xbfc4d30e, //[16] p8 = -1.5652673123f
+ // exp(x) polynomial
+ 0x3f800001, //[17] p0 = 1.0000001f
+ 0x3f800000, //[18] p1 = 1.0f
+ 0x3efffe85, //[19] p2 = 0.4999887f
+ 0x3e2aaa3e, //[20] p3 = 0.16666505f
+ 0x3d2bb1b1, //[21] p4 = 0.041917507f
+ 0x3c091ec1, //[22] p5 = 0.008369149f
+ 0xbf800000, //[23] is required for sign changing
+ 0x42b0c0a5, //[24] max logf = 88.3762589f
+ 0xc1766666 //[25] min logf = -14.5f
+ };
+
+ for (size_t i = 0; i < sizeof(cvals) / sizeof(cvals[0]); ++i) {
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) {
+ h->dd(cvals[i]);
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::abs_prepare_table() {
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) h->dd(0x7fffffff);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::sqrt_prepare_table() {
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) h->dd(0);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::linear_prepare_table() {
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) h->dd(float2int(alpha_));
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) h->dd(float2int(beta_));
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::bounded_relu_prepare_table() {
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) h->dd(float2int(alpha_));
+ for (size_t d = 0; d < vlen / sizeof(float); ++d) h->dd(0);
+}
+
+template <cpu_isa_t isa>
+int jit_uni_eltwise_injector_f32<isa>::aux_vecs_count(alg_kind_t alg_) {
+ switch (alg_) {
+ case alg_kind::eltwise_relu: return (alpha_ == 0.f) ? 0 : 2;
+ case alg_kind::eltwise_elu: return 4;
+ case alg_kind::eltwise_tanh: return 5;
+ case alg_kind::eltwise_square: return 0;
+ case alg_kind::eltwise_abs: return 0;
+ case alg_kind::eltwise_sqrt: return 2;
+ case alg_kind::eltwise_linear: return 1;
+ case alg_kind::eltwise_bounded_relu: return 0;
+ case alg_kind::eltwise_soft_relu: return 4;
+ case alg_kind::eltwise_logistic: return 4;
+ default: assert(!"unsupported eltwise algorithm");
+ }
+
+ return 0;
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::compute_body(size_t start_idx,
+ size_t end_idx) {
+ using namespace alg_kind;
+ for (size_t idx = start_idx; idx < end_idx; idx++) {
+ switch (alg_) {
+ case eltwise_relu:
+ if (alpha_ == 0.f) relu_zero_ns_compute_vector(Vmm(idx));
+ else relu_compute_vector(Vmm(idx));
+ break;
+ case eltwise_elu: elu_compute_vector(Vmm(idx)); break;
+ case eltwise_tanh: tanh_compute_vector(Vmm(idx)); break;
+ case eltwise_square: square_compute_vector(Vmm(idx)); break;
+ case eltwise_abs: abs_compute_vector(Vmm(idx)); break;
+ case eltwise_sqrt: sqrt_compute_vector(Vmm(idx)); break;
+ case eltwise_linear: linear_compute_vector(Vmm(idx)); break;
+ case eltwise_bounded_relu: bounded_relu_compute_vector(Vmm(idx)); break;
+ case eltwise_soft_relu: soft_relu_compute_vector(Vmm(idx)); break;
+ case eltwise_logistic: logistic_compute_vector(Vmm(idx)); break;
+ default: assert(!"unsupported eltwise algorithm");
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::compute_vector_range(size_t start_idx,
+ size_t end_idx) {
+ assert(start_idx < end_idx && end_idx <= vecs_count);
+
+ injector_preamble(start_idx, end_idx);
+ compute_body(start_idx_tail, end_idx);
+ injector_preamble_tail(start_idx);
+ compute_body(start_idx, start_idx_tail);
+ injector_postamble();
+}
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_injector_f32<isa>::prepare_table(bool gen_table) {
+ using namespace alg_kind;
+
+ h->align(64);
+ h->L(l_table);
+
+ if (gen_table) {
+ switch (alg_) {
+ case eltwise_relu: relu_prepare_table(); break;
+ case eltwise_elu:
+ case eltwise_tanh:
+ case eltwise_logistic:
+ elu_prepare_table(); break;
+ case eltwise_soft_relu: soft_relu_prepare_table(); break;
+ case eltwise_abs: abs_prepare_table(); break;
+ case eltwise_sqrt: sqrt_prepare_table(); break;
+ case eltwise_linear: linear_prepare_table(); break;
+ case eltwise_bounded_relu: bounded_relu_prepare_table(); break;
+ case eltwise_square: break;
+ default: assert(!"unsupported eltwise algorithm");
+ }
+ }
+}
+
+template struct jit_uni_eltwise_injector_f32<avx512_common>;
+template struct jit_uni_eltwise_injector_f32<avx2>;
+template struct jit_uni_eltwise_injector_f32<sse42>;
+
+
+struct jit_args {
+ const float *from;
+ const float *for_comparison;
+ const float *to;
+ size_t work_amount;
+};
+
+struct jit_uni_eltwise_kernel_f32 : public c_compatible {
+ const eltwise_desc_t &desc_;
+
+ void (*ker_)(const jit_args *);
+ void operator()(const jit_args *args) { assert(ker_); ker_(args); }
+
+ jit_uni_eltwise_kernel_f32(const eltwise_desc_t &desc)
+ : desc_(desc), ker_(nullptr) {}
+ virtual ~jit_uni_eltwise_kernel_f32() {}
+
+protected:
+ bool is_bwd() const { return desc_.prop_kind == prop_kind::backward_data; }
+};
+
+/* jit kernels */
+namespace {
+
+template <cpu_isa_t isa>
+struct jit_uni_relu_kernel_f32 : public jit_uni_eltwise_kernel_f32,
+ public jit_generator
+{
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_uni_relu_kernel_f32)
+
+ void compute_step(bool vectorize, const int uf, const int shift) {
+ for (int i = 0; i < uf; i++) {
+ if (vectorize) {
+ uni_vmovups(Vmm(i + 1), ptr[reg_from + i * shift]);
+ if (is_bwd())
+ uni_vmovups(Vmm(uf + i + 1),
+ ptr[reg_for_comparison + i * shift]);
+ } else {
+ movss(Xmm(i + 1), ptr[reg_from + i * shift]);
+ if (is_bwd())
+ movss(Xmm(uf + i + 1),
+ ptr[reg_for_comparison + i * shift]);
+ }
+ }
+
+ if (isa == sse42) {
+ for (int i = 0; i < uf; i++) {
+ movups(Vmm(2 * uf + i + 1), Vmm(i + 1));
+ mulps(Vmm(2 * uf + i + 1), vmm_ns);
+
+ Vmm mask = Vmm(0);
+ if (is_bwd()) {
+ movups(mask, Vmm(uf + i + 1));
+ cmpps(mask, vmm_zero, _cmp_nle_us);
+ } else {
+ movups(mask, Vmm(i + 1));
+ cmpps(mask, vmm_zero, _cmp_nle_us);
+ }
+ blendvps(Vmm(2 * uf + i + 1), Vmm(i + 1));
+ }
+ } else {
+ for (int i = 0; i < uf; i++) {
+ vmulps(Vmm(2 * uf + i + 1), Vmm(i + 1), vmm_ns);
+ if (isa == avx2) {
+ if (is_bwd())
+ vcmpgtps(vmm_mask, Vmm(uf + i + 1), vmm_zero);
+ else
+ vcmpgtps(vmm_mask, Vmm(i + 1), vmm_zero);
+
+ vblendvps(Vmm(2 * uf + i + 1), Vmm(2 * uf + i + 1),
+ Vmm(i + 1), vmm_mask);
+
+ } else {
+ if (is_bwd())
+ vcmpps(k_mask, Vmm(uf + i + 1), vmm_zero, _cmp_nle_us);
+ else
+ vcmpps(k_mask, Vmm(i + 1), vmm_zero, _cmp_nle_us);
+ vblendmps(Vmm(2 * uf + i + 1) | k_mask, Vmm(2 * uf + i + 1),
+ Vmm(i + 1));
+ }
+ }
+ }
+
+ for (int i = 0; i < uf; i++) {
+ if (vectorize) {
+ uni_vmovups(ptr[reg_to + i * shift], Vmm(2 * uf + i + 1));
+ } else {
+ movss(ptr[reg_to + i * shift], Xmm(2 * uf + i + 1));
+ }
+ }
+ }
+
+ jit_uni_relu_kernel_f32(const eltwise_desc_t &desc)
+ : jit_uni_eltwise_kernel_f32(desc), jit_generator() {
+ assert(desc.alg_kind == alg_kind::eltwise_relu);
+ assert(isa == sse42 || isa == avx2 || isa == avx512_common);
+
+ Reg64 param = abi_param1;
+
+ const int simd_w = cpu_isa_traits<isa>::vlen / sizeof(float);
+ const int loop_dec[] = {simd_w, 1};
+ const int uf[] = {1, 1};
+ const int shift[] = {cpu_isa_traits<isa>::vlen, sizeof(float)};
+ const bool loop_vectorize[] = {true, false};
+
+ this->preamble();
+
+ mov(reg_from, ptr[param + GET_OFF(from)]);
+ if (is_bwd())
+ mov(reg_for_comparison, ptr[param + GET_OFF(for_comparison)]);
+ mov(reg_to, ptr[param + GET_OFF(to)]);
+ mov(reg_work_amount, ptr[param + GET_OFF(work_amount)]);
+
+ mov(imm_addr64, float2int(desc.alpha));
+ movq(xmm_ns, imm_addr64);
+ uni_vbroadcastss(vmm_ns, xmm_ns);
+
+ uni_vpxor(vmm_zero, vmm_zero, vmm_zero);
+
+ Label loop_label[3];
+
+ for (int id = 0; id < 2; id++) {
+ L(loop_label[id]);
+ cmp(reg_work_amount, uf[id] * loop_dec[id] - 1);
+ jle(loop_label[id + 1], T_NEAR);
+
+ compute_step(loop_vectorize[id], uf[id], shift[id]);
+
+ add(reg_from, uf[id] * shift[id]);
+ add(reg_to, uf[id] * shift[id]);
+ if (is_bwd())
+ add(reg_for_comparison, uf[id] * shift[id]);
+
+ sub(reg_work_amount, uf[id] * loop_dec[id]);
+ jmp(loop_label[id]);
+ }
+
+ L(loop_label[2]);
+ this->postamble();
+
+ ker_ = (decltype(ker_))this->getCode();
+ }
+
+private:
+ using Vmm = typename utils::conditional3<isa == sse42, Xmm,
+ isa == avx2, Ymm, Zmm>::type;
+
+ Reg64 reg_from = rax;
+ Reg64 reg_for_comparison = is_bwd() ? rdx : reg_from;
+ Reg64 reg_to = r8;
+ Reg64 reg_work_amount = rsi;
+ Reg64 imm_addr64 = rbx;
+
+ Xmm xmm_ns = Xmm(14);
+
+ Vmm vmm_ns = Vmm(isa == avx512_common ? 30 : 14);
+ Vmm vmm_zero = Vmm(isa == avx512_common ? 31 : 15);
+
+ Vmm vmm_mask = Vmm(isa == avx512_common ? 28 : 12);
+ Opmask k_mask = Opmask(1);
+};
+
+template <cpu_isa_t isa>
+struct jit_uni_kernel_fwd_f32: public jit_uni_eltwise_kernel_f32,
+ public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_uni_kernel_fwd_f32)
+
+ jit_uni_kernel_fwd_f32(const eltwise_desc_t &desc)
+ : jit_uni_eltwise_kernel_f32(desc), jit_generator() {
+
+ eltwise_injector_ = new jit_uni_eltwise_injector_f32<isa>(this,
+ desc.alg_kind, desc.alpha, desc.beta, false, r9, Opmask(1));
+
+ using namespace alg_kind;
+
+ assert(is_bwd() == false);
+ assert(utils::one_of(desc.alg_kind, eltwise_tanh, eltwise_elu,
+ eltwise_square, eltwise_abs, eltwise_sqrt, eltwise_linear,
+ eltwise_bounded_relu, eltwise_soft_relu, eltwise_logistic));
+
+ preamble();
+
+ Reg64 param = abi_param1;
+ mov(reg_from, ptr[param + GET_OFF(from)]);
+ mov(reg_to, ptr[param + GET_OFF(to)]);
+ mov(reg_work_amount, ptr[param + GET_OFF(work_amount)]);
+ eltwise_injector_->load_table_addr();
+
+ Label reminder_loop_start, reminder_loop_end;
+ Label vectorized_loop_start, vectorized_loop_end;
+
+ cmp(reg_work_amount, simd_w);
+ jl(reminder_loop_start, T_NEAR);
+
+ L(vectorized_loop_start);
+
+ uni_vmovups(vmm_src, ptr[reg_from]);
+ eltwise_injector_->compute_vector(vmm_src.getIdx());
+ uni_vmovups(ptr[reg_to], vmm_src);
+
+ add(reg_from, vlen);
+ add(reg_to, vlen);
+
+ sub(reg_work_amount, simd_w);
+ cmp(reg_work_amount, simd_w);
+ jge(vectorized_loop_start, T_NEAR);
+
+ L(vectorized_loop_end);
+
+ L(reminder_loop_start);
+
+ cmp(reg_work_amount, 0);
+ jle(reminder_loop_end, T_NEAR);
+
+ movss(xmm_src, ptr[reg_from]);
+ eltwise_injector_->compute_vector(xmm_src.getIdx());
+ movss(ptr[reg_to], xmm_src);
+
+ add(reg_from, sizeof(float));
+ add(reg_to, sizeof(float));
+
+ dec(reg_work_amount);
+ jmp(reminder_loop_start, T_NEAR);
+
+ L(reminder_loop_end);
+
+ postamble();
+
+ eltwise_injector_->prepare_table();
+
+ ker_ = (decltype(ker_))this->getCode();
+ }
+
+ ~jit_uni_kernel_fwd_f32() { delete eltwise_injector_; }
+
+private:
+ using Vmm = typename utils::conditional3<isa == sse42, Xmm,
+ isa == avx2, Ymm, Zmm>::type;
+
+ const int simd_w = cpu_isa_traits<isa>::vlen / sizeof(float);
+ const int vlen = cpu_isa_traits<isa>::vlen;
+
+ Reg64 reg_from = rax;
+ Reg64 reg_to = r8;
+ Reg64 reg_work_amount = rsi;
+ Reg64 imm_addr64 = rbx;
+
+ Xmm xmm_src = Xmm(1);
+ Vmm vmm_src = Vmm(1);
+
+ jit_uni_eltwise_injector_f32<isa> *eltwise_injector_;
+};
+
+} /* namespace */
+
+template <cpu_isa_t isa>
+status_t jit_uni_eltwise_fwd_t<isa>::pd_t::init() {
+ using namespace alg_kind;
+
+ bool ok = true
+ && mayiuse(isa)
+ && is_fwd()
+ && utils::everyone_is(data_type::f32, desc()->data_desc.data_type)
+ && !has_zero_dim_memory()
+ && utils::one_of(desc()->alg_kind, eltwise_relu, eltwise_tanh,
+ eltwise_elu, eltwise_square, eltwise_abs, eltwise_sqrt,
+ eltwise_linear, eltwise_bounded_relu, eltwise_soft_relu,
+ eltwise_logistic)
+ && memory_desc_wrapper(src_md()).is_dense(true)
+ && IMPLICATION(!memory_desc_wrapper(src_md()).is_dense(false),
+ math::eltwise_fwd_preserves_zero(desc()->alg_kind, true))
+ && attr()->has_default_values();
+
+ return ok ? status::success : status::unimplemented;
+}
+
+template <cpu_isa_t isa>
+jit_uni_eltwise_fwd_t<isa>::jit_uni_eltwise_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd), kernel_(nullptr) {
+ const auto &desc = *pd()->desc();
+ switch (desc.alg_kind) {
+ case alg_kind::eltwise_relu:
+ kernel_ = new jit_uni_relu_kernel_f32<isa>(desc); break;
+ default:
+ kernel_ = new jit_uni_kernel_fwd_f32<isa>(desc);
+ }
+}
+
+template <cpu_isa_t isa>
+jit_uni_eltwise_fwd_t<isa>::~jit_uni_eltwise_fwd_t()
+{ delete kernel_; }
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_fwd_t<isa>::execute_forward(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+
+ const size_t nelems = data_d.nelems(true);
+
+ src += data_d.offset0();
+ dst += data_d.offset0();
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ size_t start{0}, end{0};
+
+ const int cache_line = 16;
+
+ balance211(utils::div_up(nelems, cache_line), nthr, ithr, start, end);
+ start = nstl::min(nelems, start * cache_line);
+ end = nstl::min(nelems, end * cache_line);
+
+ auto arg = jit_args();
+ arg.from = &src[start];
+ arg.for_comparison = &src[start];
+ arg.to = &dst[start];
+ arg.work_amount = end - start;
+ if (arg.work_amount)
+ (*kernel_)(&arg);
+ });
+}
+
+template <cpu_isa_t isa>
+status_t jit_uni_eltwise_bwd_t<isa>::pd_t::init() {
+ bool ok = true
+ && !is_fwd()
+ && utils::one_of(desc()->alg_kind, alg_kind::eltwise_relu)
+ && src_md()->data_type == data_type::f32
+ && !has_zero_dim_memory()
+ && mayiuse(isa)
+ && memory_desc_wrapper(src_md()).is_dense()
+ && memory_desc_wrapper(diff_dst_md()) == memory_desc_wrapper(src_md())
+ && attr()->has_default_values();
+
+ return ok ? status::success : status::unimplemented;
+}
+
+template <cpu_isa_t isa>
+jit_uni_eltwise_bwd_t<isa>::jit_uni_eltwise_bwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd), kernel_(nullptr) {
+ const auto &desc = *pd()->desc();
+ switch (desc.alg_kind) {
+ case alg_kind::eltwise_relu:
+ kernel_ = new jit_uni_relu_kernel_f32<isa>(desc); break;
+ default: assert(!"unknown eltwise alg_kind");
+ }
+}
+
+template <cpu_isa_t isa>
+jit_uni_eltwise_bwd_t<isa>::~jit_uni_eltwise_bwd_t()
+{ delete kernel_; }
+
+template <cpu_isa_t isa>
+void jit_uni_eltwise_bwd_t<isa>::execute_backward(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+ const memory_desc_wrapper diff_data_d(pd()->diff_src_md());
+
+ const size_t nelems = data_d.nelems();
+
+ src += data_d.offset0();
+ diff_dst += diff_data_d.offset0();
+ diff_src += diff_data_d.offset0();
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ size_t start{0}, end{0};
+
+ const int cache_line = 16;
+
+ balance211(utils::div_up(nelems, cache_line), nthr, ithr, start, end);
+ start = nstl::min(nelems, start * cache_line);
+ end = nstl::min(nelems, end * cache_line);
+
+ auto arg = jit_args();
+ arg.from = &diff_dst[start];
+ arg.to = &diff_src[start];
+ arg.for_comparison = &src[start];
+ arg.work_amount = end - start;
+ if (arg.work_amount)
+ (*kernel_)(&arg);
+ });
+}
+
+template struct jit_uni_eltwise_fwd_t<sse42>;
+template struct jit_uni_eltwise_bwd_t<sse42>;
+template struct jit_uni_eltwise_fwd_t<avx2>;
+template struct jit_uni_eltwise_bwd_t<avx2>;
+template struct jit_uni_eltwise_fwd_t<avx512_common>;
+template struct jit_uni_eltwise_bwd_t<avx512_common>;
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_eltwise.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_eltwise.hpp
new file mode 100644
index 0000000000..45436b9f46
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_eltwise.hpp
@@ -0,0 +1,193 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_UNI_ELTWISE_HPP
+#define CPU_JIT_UNI_ELTWISE_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_eltwise_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <cpu_isa_t isa>
+struct jit_uni_eltwise_injector_f32 {
+ using Vmm = typename utils::conditional3<isa == sse42, Xbyak::Xmm,
+ isa == avx2, Xbyak::Ymm, Xbyak::Zmm>::type;
+
+ jit_uni_eltwise_injector_f32(jit_generator *host, alg_kind_t alg,
+ float alpha, float beta, bool save_state = true,
+ Xbyak::Reg64 p_table = Xbyak::util::rax,
+ Xbyak::Opmask k_mask = Xbyak::Opmask(1))
+ : alg_(alg), alpha_(alpha), beta_(beta), h(host)
+ , save_state_(save_state), p_table(p_table), k_mask(k_mask)
+ {
+ using namespace alg_kind;
+ assert(utils::one_of(isa, sse42, avx2, avx512_common));
+ assert(utils::one_of(alg_, eltwise_relu, eltwise_tanh, eltwise_elu,
+ eltwise_square, eltwise_abs, eltwise_sqrt, eltwise_linear,
+ eltwise_bounded_relu, eltwise_soft_relu, eltwise_logistic));
+ }
+
+ // note that eltwise.scale is ignored
+ jit_uni_eltwise_injector_f32(jit_generator *host,
+ const post_ops_t::entry_t::eltwise_t &eltwise,
+ bool save_state = true, Xbyak::Reg64 p_table = Xbyak::util::rax,
+ Xbyak::Opmask k_mask = Xbyak::Opmask(1))
+ : jit_uni_eltwise_injector_f32(host, eltwise.alg, eltwise.alpha,
+ eltwise.beta, save_state, p_table, k_mask) {}
+
+ void compute_vector_range(size_t start_idx, size_t end_idx);
+ void compute_vector(size_t idx) { compute_vector_range(idx, idx + 1); }
+ void prepare_table(bool gen_table=true);
+ void load_table_addr() { h->mov(p_table, l_table); }
+
+ const alg_kind_t alg_;
+ const float alpha_;
+ const float beta_;
+
+ jit_generator * const h;
+
+ const bool save_state_;
+ const Xbyak::Reg64 p_table;
+ const Xbyak::Opmask k_mask;
+ Xbyak::Label l_table;
+
+private:
+ // if only the injector was inherited from jit_generator...
+ enum {
+ _cmp_le_os = jit_generator::_cmp_le_os,
+ _cmp_nle_us = jit_generator::_cmp_nle_us,
+ _op_floor = jit_generator::_op_floor,
+ };
+
+ size_t vlen = cpu_isa_traits<isa>::vlen;
+
+ const static size_t preserved_vecs_max = 5;
+
+ size_t vecs_to_preserve = 0;
+ size_t vecs_count = isa == avx512_common ? 32 : 16;
+ size_t preserved_vecs_count = 0;
+ size_t preserved_vec_idxs[preserved_vecs_max] = {0};
+ size_t start_idx_tail = 0;
+
+ Vmm vmm_mask, vmm_aux0, vmm_aux1, vmm_aux2, vmm_aux3, vmm_aux4;
+
+ Xbyak::Address table_val(int index)
+ { return h->ptr[p_table + index * vlen]; }
+
+ int aux_vecs_count(alg_kind_t alg);
+
+ void compute_body(size_t start_idx, size_t end_idx);
+ void injector_preamble(size_t start_idx, size_t end_idx);
+ void injector_preamble_tail(size_t start_idx);
+ void injector_postamble();
+ void assign_regs();
+
+ void exp_compute_vector(const Vmm &vmm_src);
+ void relu_compute_vector(const Vmm &vmm_src);
+ void relu_zero_ns_compute_vector(const Vmm &vmm_src);
+ void elu_compute_vector(const Vmm &vmm_src);
+ void tanh_compute_vector(const Vmm &vmm_src);
+ void square_compute_vector(const Vmm &vmm_src);
+ void abs_compute_vector(const Vmm &vmm_src);
+ void sqrt_compute_vector(const Vmm &vmm_src);
+ void linear_compute_vector(const Vmm &vmm_src);
+ void bounded_relu_compute_vector(const Vmm &vmm_src);
+ void soft_relu_compute_vector(const Vmm &vmm_src);
+ void logistic_compute_vector(const Vmm &vmm_src);
+
+ void relu_prepare_table();
+ void elu_prepare_table();
+ void soft_relu_prepare_table();
+ void abs_prepare_table();
+ void sqrt_prepare_table();
+ void linear_prepare_table();
+ void bounded_relu_prepare_table();
+};
+
+struct jit_uni_eltwise_kernel_f32;
+
+template <cpu_isa_t isa>
+struct jit_uni_eltwise_fwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_eltwise_fwd_pd_t {
+ using cpu_eltwise_fwd_pd_t::cpu_eltwise_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", isa, ""),
+ jit_uni_eltwise_fwd_t<isa>);
+
+ status_t init();
+ };
+
+ jit_uni_eltwise_fwd_t(const pd_t *apd);
+ ~jit_uni_eltwise_fwd_t();
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ jit_uni_eltwise_kernel_f32 *kernel_;
+};
+
+template <cpu_isa_t isa>
+struct jit_uni_eltwise_bwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_eltwise_bwd_pd_t {
+ using cpu_eltwise_bwd_pd_t::cpu_eltwise_bwd_pd_t;
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", isa, ""),
+ jit_uni_eltwise_bwd_t<isa>);
+
+ status_t init();
+ };
+
+ jit_uni_eltwise_bwd_t(const pd_t *apd);
+ ~jit_uni_eltwise_bwd_t();
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ jit_uni_eltwise_kernel_f32 *kernel_;
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_i8i8_pooling.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_i8i8_pooling.cpp
new file mode 100644
index 0000000000..a3ca6273a0
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_i8i8_pooling.cpp
@@ -0,0 +1,949 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "jit_uni_i8i8_pooling.hpp"
+
+#include <math.h>
+
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace Xbyak;
+
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::types;
+using namespace alg_kind;
+
+template <cpu_isa_t isa>
+struct jit_uni_i8i8_pooling_fwd_ker_t: public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_uni_i8i8_pooling_fwd_ker_t)
+
+ struct call_params_t {
+ const char *src_i8;
+ const char *dst_i8;
+ size_t kw_range;
+ size_t kh_range;
+ float idivider;
+ };
+
+ using Vmm = typename cpu_isa_traits<isa>::Vmm;
+ Xmm xreg(int idx) const { return Xmm(idx); }
+ Ymm yreg(int idx) const { return Ymm(xreg(idx).getIdx()); }
+ Vmm vreg(int idx) const { return Vmm(xreg(idx).getIdx()); }
+
+ // In case of avx2 with data type i8 we need to use
+ // maskmovdqu instruction which has its destination hardcoded in rdi.
+ // Windows ABI: abi_param1 is rcx - nothing to do else
+ // Unix ABI: abi_param1 is rdi - copy it to rcx and use it as abi_param1
+ Reg64 reg_param = rcx; // Our "unified abi_param1"
+ Reg64 reg_ptr_src_i8 = r8;
+ Reg64 reg_ptr_dst_i8 = r9;
+ Reg64 reg_ptr_maskmovdqu_dst = rdi; // store destination - must be rdi
+
+ Reg64 ki = r10;
+ Reg64 kj = r11;
+ Reg64 reg_kw = r12;
+ Reg64 reg_kh = r13;
+ Reg64 c_iter = r14;
+
+ Reg64 aux_reg_src_h = rax;
+ Reg64 aux_reg_src_w = rbx;
+
+ Reg64 reg_tmp = rdx;
+
+ Reg64 reg_mask = r15;
+
+ Opmask k_cmp_mask = Opmask(7);
+
+ Opmask mask(int idx) {
+ return Opmask(6 - idx);
+ }
+
+ // ref to any of XYZ-regs via xreg/yreg/vreg functions
+ Xmm xmm_tmp = xreg(0); // temp to init vreg_tmp
+ Vmm vreg_tmp = vreg(0); // max pooling : holds minimum values for data_type
+ Vmm vreg_zeros = vreg(1);
+
+ // only in case of <isa> == avx2
+ Vmm vreg_mask = vreg(2); // full byte-mask
+ Xmm xreg_mask_lo = xreg(2); // low 128-bits part of byte-mask (alias for xmm part of vreg_mask)
+ Xmm xreg_mask_hi = xreg(3); // "max" - high 128-bits part of byte-mask (stored separately)
+ Xmm xreg_mask_q = xreg(3); // "avg" - 1/4 part of the mask for s8/u8 operations
+ Vmm vreg_mask_q = vreg(3); // "avg" - 1/4 part for non-zero tails
+
+ enum:int {vidx_base = isa == avx2 ? 4 : 2};
+ Vmm base_vr(int idx) const { return vreg(vidx_base + idx); }
+
+ size_t sizeof_src_dt() const { return data_type_size(jpp.src_dt); }
+ size_t sizeof_dst_dt() const { return data_type_size(jpp.dst_dt); }
+
+ /* max pooling */
+ Vmm vreg_src(int idx) const { return base_vr(idx); } // [0 .. ur_c-1]
+ Vmm vreg_dst(int idx) const { return base_vr(jpp.ur_c + idx); } // [ur_c .. 2*ur_c-1]
+
+ /* avg pooling */
+ // s32 used for processing of s8/u8 data
+ // thus we need to take into account ratio of sizes s32/i8 = 4
+ static constexpr data_type_t avg_proc_dt = data_type::s32;
+ enum:int {
+ s32_to_i8_ratio = sizeof(typename prec_traits<avg_proc_dt>::type)
+ / sizeof(typename prec_traits<data_type::u8>::type),
+ max_num_ll = s32_to_i8_ratio
+ };
+ Vmm vreg_src_s32(int jj, int ll) { return base_vr(3*max_num_ll*jj + ll + 0*max_num_ll); } // ll: 0..4 [0..3]
+ Vmm vreg_dst_s32(int jj, int ll) { return base_vr(3*max_num_ll*jj + ll + 1*max_num_ll); } // ll: 0..4 [4..7]
+ Vmm vreg_dst_f32(int jj, int ll) { return base_vr(3*max_num_ll*jj + ll + 2*max_num_ll); } // ll: 0..4 [8..11]
+
+ void (*ker_)(const call_params_t *);
+ jit_pool_conf_t jpp;
+
+ void init_tmp_reg();
+ void init_mask();
+
+ void load_vreg_mask_q(int ll) {};
+
+ void load_src_max_op(int jj, int ll, size_t offset, bool masked, uint64_t msk);
+ void load_src_avg_op(int jj, int ll, size_t offset, bool masked, uint64_t msk);
+ void load_src(int jj, int ll, int c_tail);
+
+ void store_dst_max_op(int jj, int ll, size_t offset, bool masked, uint64_t msk);
+ void store_dst_avg_op(int jj, int ll, size_t offset, bool masked, uint64_t msk);
+ void store_dst(int jj, int ll, int c_tail);
+
+ void compute_avg_step(int ur_c, int c_tail);
+ void compute_max_op(const int jj);
+ void compute_max_step(int ur_c, int c_tail);
+ void compute_step(int ur_c, int c_tail);
+
+ void compute_c_block();
+ void generate();
+
+ static status_t init_conf(jit_pool_conf_t &jpp, const pooling_pd_t *ppd);
+
+ jit_uni_i8i8_pooling_fwd_ker_t(const jit_pool_conf_t &jpp_)
+ : jpp(jpp_) {
+ generate();
+ ker_ = reinterpret_cast<decltype(ker_)>(const_cast<uint8_t*>(
+ getCode()));
+ }
+};
+
+template <>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx2>::load_vreg_mask_q(int ll) {
+
+ // extract ll-th part of mask (ll-th QWORD)
+ vpblendd(vreg_mask_q, vreg_zeros, vreg_mask, 0x3 << ll); // 0x3 - mask for 2 x DWORD
+
+ // Move mask from ll-th pos to 0-th pos
+ if (ll>0)
+ vpermq(vreg_mask_q, vreg_mask_q, ll);
+};
+
+template <>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx2>::load_src_max_op(int jj, int ll,
+ size_t offset, bool masked, uint64_t msk) {
+ using namespace data_type;
+
+ if (masked) {
+ if (jpp.src_dt == s32) {
+ vpblendd(vreg_src(jj), vreg_tmp, ptr[aux_reg_src_w + offset], static_cast<uint8_t>(msk));
+ } else {
+ vpblendvb(vreg_src(jj), vreg_tmp, ptr[aux_reg_src_w + offset], vreg_mask);
+ }
+ } else
+ vmovups(vreg_src(jj), ptr[aux_reg_src_w + offset]);
+};
+
+template <>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx512_core>::load_src_max_op(int jj, int ll,
+ size_t offset, bool masked, uint64_t msk) {
+ using namespace data_type;
+
+ if (masked) {
+ if (jpp.src_dt == s32)
+ vmovups(vreg_src(jj) | mask(0), ptr[aux_reg_src_w + offset]);
+ else
+ vmovdqu8(vreg_src(jj) | mask(0), ptr[aux_reg_src_w + offset]);
+ } else
+ vmovups(vreg_src(jj), ptr[aux_reg_src_w + offset]);
+};
+
+template <>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx2>::load_src_avg_op(int jj, int ll,
+ size_t offset, bool masked, uint64_t msk) {
+ using namespace data_type;
+
+ // Don't generate useless code
+ if (masked && !msk)
+ return;
+
+ auto load_i8 = [&](bool is_signed, const Vmm& vr_src) {
+
+ // Need to use mask of tail?
+ if (masked) {
+
+ // load ll-th part of mask into vreg_mask_q
+ load_vreg_mask_q(ll);
+
+ // Load by mask from mem into register vr_src
+ vpblendvb(vr_src, vreg_zeros, ptr[aux_reg_src_w + offset], vreg_mask_q);
+
+ // Conversion s8/u8 -> s32
+ if (is_signed)
+ vpmovsxbd(vr_src, vr_src);
+ else
+ vpmovzxbd(vr_src, vr_src);
+ } else {
+
+ // Load from mem into vr_src with conversion
+ if (is_signed)
+ vpmovsxbd(vr_src, ptr[aux_reg_src_w + offset]);
+ else
+ vpmovzxbd(vr_src, ptr[aux_reg_src_w + offset]);
+ }
+ };
+
+ switch (jpp.src_dt) {
+ case s32:
+ if (masked)
+ vpblendd(vreg_src_s32(jj, ll), vreg_zeros, ptr[aux_reg_src_w + offset],
+ static_cast<uint8_t>(msk));
+ else
+ vmovups(vreg_src_s32(jj, ll), ptr[aux_reg_src_w + offset]);
+ break;
+ case s8:
+ load_i8(true, vreg_src_s32(jj, ll));
+ break;
+ case u8:
+ load_i8(false, vreg_src_s32(jj, ll));
+ break;
+ default: assert(!"unsupported src data type");
+ }
+};
+
+template <>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx512_core>::load_src_avg_op(int jj, int ll,
+ size_t offset, bool masked, uint64_t msk) {
+ using namespace data_type;
+
+ // Don't generate useless code
+ if (masked && !msk)
+ return;
+
+ const Vmm& vr_src = masked ?
+ vreg_src_s32(jj, ll) | mask(ll) :
+ vreg_src_s32(jj, ll);
+
+ switch (jpp.src_dt) {
+ case s32:
+ vmovups(vr_src, ptr[aux_reg_src_w + offset]);
+ break;
+ case s8:
+ vpmovsxbd(vr_src, ptr[aux_reg_src_w + offset]);
+ break;
+ case u8:
+ vpmovzxbd(vr_src, ptr[aux_reg_src_w + offset]);
+ break;
+ default: assert(!"unsupported src data type");
+ }
+};
+
+template <cpu_isa_t isa>
+void jit_uni_i8i8_pooling_fwd_ker_t<isa>::load_src(int jj, int ll, int c_tail) {
+ using namespace data_type;
+
+ int c_block = jpp.c_block;
+ int ur_c = jpp.ur_c;
+
+ switch (jpp.alg) {
+ case pooling_max: {
+ auto offset = jj*c_block*sizeof_src_dt();
+ bool masked = jj == ur_c - 1 && c_tail;
+ load_src_max_op(jj, ll, offset, masked, jpp.tail[0]);
+ break;
+ }
+ case pooling_avg_include_padding:
+ case pooling_avg_exclude_padding: {
+ auto offset = (ll*(c_block/max_num_ll) + jj*c_block)*sizeof_src_dt();
+ bool masked = jj == ur_c - 1 && c_tail;
+ load_src_avg_op(jj, ll, offset, masked, jpp.tail[ll]);
+ break;
+ }
+ default: assert(!"unsupported algorithm");
+ }
+}
+
+template <>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx2>::store_dst_max_op(int jj, int ll,
+ size_t offset, bool masked, uint64_t msk) {
+ using namespace data_type;
+
+ int c_block = jpp.c_block;
+
+ if (masked) {
+ switch (jpp.src_dt) {
+ case s32:
+ vpmaskmovd(ptr[reg_ptr_dst_i8 + offset], vreg_mask, vreg_dst(jj));
+ break;
+ case s8:
+ case u8: {
+ // Store low half by mask (bytes 0...15)
+ lea(reg_ptr_maskmovdqu_dst, ptr[reg_ptr_dst_i8 + offset]);
+ maskmovdqu(vreg_dst(jj), xreg_mask_lo);
+
+ // Do we need to store high half (bytes 16...31) ?
+ const uint64_t low_mask = (1ULL << (c_block/2))-1;
+ if (msk & ~low_mask) {
+ vextracti128(Xmm(vreg_dst(jj).getIdx()), vreg_dst(jj), 1);
+ add(reg_ptr_maskmovdqu_dst, c_block / 2);
+ maskmovdqu(vreg_dst(jj), xreg_mask_hi);
+ }
+ } break;
+ default: assert(!"unsupported src data type");
+ }
+ } else
+ vmovups(ptr[reg_ptr_dst_i8 + offset], vreg_dst(jj));
+}
+
+template <>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx512_core>::store_dst_max_op(int jj, int ll,
+ size_t offset, bool masked, uint64_t msk) {
+ using namespace data_type;
+
+ if (masked) {
+ switch (jpp.src_dt) {
+ case s32:
+ vmovups(ptr[reg_ptr_dst_i8 + offset], vreg_dst(jj) | mask(0));
+ break;
+ case s8:
+ case u8:
+ vmovdqu8(ptr[reg_ptr_dst_i8 + offset], vreg_dst(jj) | mask(0));
+ break;
+ default: assert(!"unsupported src data type");
+ }
+ } else
+ vmovups(ptr[reg_ptr_dst_i8 + offset], vreg_dst(jj));
+}
+
+template <>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx2>::store_dst_avg_op(int jj, int ll,
+ size_t offset, bool masked, uint64_t msk){
+ using namespace data_type;
+
+ // Don't generate useless code
+ if (masked && !msk)
+ return;
+
+ auto s32_to_i8 = [&](bool is_signed, const Vmm& vr_dst) {
+
+ // conversion: s32 -> s16/u16 : {8 x s32}{8 x 0} -> {16 x s16/u16}
+ // Result QWORDs (qw0, qw1) permuted: {qw0, 0, qw1, 0}
+ if (is_signed)
+ vpackssdw(vr_dst, vr_dst, vreg_zeros);
+ else
+ vpackusdw(vr_dst, vr_dst, vreg_zeros);
+
+ // Permute qwords to restore original order
+ // {qw0, 0, qw1, 0} -> {qw0, qw1, 0, 0}
+ vpermq(vr_dst, vr_dst, 0x58);
+
+ // conversion: s16/u16 -> s8/u8 : {16 x s16/u16}{16 x 0} -> {32 x s8/u8}
+ // Target QWORD qw = {8 x s8/u8} has proper position: {qw, xx, xx, xx}
+ if (is_signed)
+ vpacksswb(vr_dst, vr_dst, vreg_zeros);
+ else
+ vpackuswb(vr_dst, vr_dst, vreg_zeros);
+
+ };
+
+ auto store_i8 = [&](bool is_signed, bool is_masked, const Vmm& vr_dst) {
+
+ // Conversion s32 -> s8/u8
+ s32_to_i8(is_signed, vr_dst);
+
+ // Need to use mask of tail?
+ if (is_masked) {
+ // load ll-th part of mask into vreg_mask_q
+ load_vreg_mask_q(ll);
+ }
+
+ // store 8 bytes
+ lea(reg_ptr_maskmovdqu_dst, ptr[reg_ptr_dst_i8 + offset]);
+ maskmovdqu(vr_dst, xreg_mask_q);
+ };
+
+ switch (jpp.dst_dt) {
+ case s32:
+ if (masked) {
+ vpmaskmovd(ptr[reg_ptr_dst_i8 + offset], vreg_mask, vreg_dst_s32(jj, ll));
+ } else
+ vmovups(ptr[reg_ptr_dst_i8 + offset], vreg_dst_s32(jj, ll));
+ break;
+ case s8:
+ store_i8(true, masked, vreg_dst_s32(jj, ll));
+ break;
+ case u8:
+ store_i8(false, masked, vreg_dst_s32(jj, ll));
+ break;
+ default: assert(!"unsuppotred dst data_type");
+ }
+}
+
+template <>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx512_core>::store_dst_avg_op(int jj, int ll,
+ size_t offset, bool masked, uint64_t msk) {
+ using namespace data_type;
+
+ // Don't generate useless code
+ if (masked && !msk)
+ return;
+
+ const Vmm& vr_dst = masked ?
+ vreg_dst_s32(jj, ll) | mask(ll) :
+ vreg_dst_s32(jj, ll);
+
+ switch (jpp.dst_dt) {
+ case s32:
+ vmovups(ptr[reg_ptr_dst_i8 + offset], vr_dst);
+ break;
+ case s8:
+ vpmovdb(ptr[reg_ptr_dst_i8 + offset], vr_dst);
+ break;
+ case u8:
+ vpmovusdb(ptr[reg_ptr_dst_i8 + offset], vr_dst);
+ break;
+ default: assert(!"unsupported dst data_type");
+ }
+}
+
+
+template <cpu_isa_t isa>
+void jit_uni_i8i8_pooling_fwd_ker_t<isa>::store_dst(int jj, int ll,
+ int c_tail) {
+ using namespace data_type;
+
+ int c_block = jpp.c_block;
+ int ur_c = jpp.ur_c;
+
+ switch(jpp.alg) {
+ case pooling_max: {
+ auto offset = jj*c_block*sizeof_dst_dt();
+ bool masked = jj == ur_c - 1 && c_tail;
+ store_dst_max_op(jj, ll, offset, masked, jpp.tail[ll]);
+ break;
+ }
+ case pooling_avg_include_padding:
+ case pooling_avg_exclude_padding: {
+ auto offset = (ll*(c_block/max_num_ll) + jj*c_block)*sizeof_dst_dt();
+ bool masked = jj == ur_c - 1 && c_tail;
+ store_dst_avg_op(jj, ll, offset, masked, jpp.tail[ll]);
+ break;
+ }
+ default: assert(!"unsupported pooling algorithm");
+ }
+}
+
+template <>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx2>::compute_max_op(const int jj)
+{
+ using namespace data_type;
+ switch (jpp.src_dt) {
+ case s32:
+ vpmaxsd(vreg_dst(jj), vreg_dst(jj), vreg_src(jj));
+ break;
+ case s8:
+ vpmaxsb(vreg_dst(jj), vreg_dst(jj), vreg_src(jj));
+ break;
+ case u8:
+ vpmaxub(vreg_dst(jj), vreg_dst(jj), vreg_src(jj));
+ break;
+ default: assert(!"unsupported src data type");
+ }
+}
+
+template <>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx512_core>::compute_max_op(const int jj)
+{
+ using namespace data_type;
+
+ // Compare
+ switch (jpp.src_dt) {
+ case s32:
+ vpcmpd(k_cmp_mask, vreg_dst(jj), vreg_src(jj), _cmp_lt_os);
+ break;
+ case s8:
+ vpcmpb(k_cmp_mask, vreg_dst(jj), vreg_src(jj), _cmp_lt_os);
+ break;
+ case u8:
+ vpcmpub(k_cmp_mask, vreg_dst(jj), vreg_src(jj), _cmp_lt_os);
+ break;
+ default: assert(!"unsupported src data type");
+ }
+
+ // move max values into vreg_dst
+ if (jpp.src_dt == s32)
+ vpblendmd(vreg_dst(jj) | k_cmp_mask, vreg_dst(jj), vreg_src(jj));
+ else
+ vpblendmb(vreg_dst(jj) | k_cmp_mask, vreg_dst(jj), vreg_src(jj));
+}
+
+
+template <cpu_isa_t isa>
+void jit_uni_i8i8_pooling_fwd_ker_t<isa>::compute_max_step(int ur_c, int c_tail)
+{
+ Label l_kw, l_kh;
+
+ int iw = jpp.iw;
+ int c = jpp.c;
+
+ for (int jj = 0; jj < ur_c; jj++)
+ vmovups(vreg_dst(jj), vreg_tmp);
+
+ mov(aux_reg_src_h, reg_ptr_src_i8);
+
+ xor_(kj, kj);
+ L(l_kh);
+ {
+ mov(aux_reg_src_w, aux_reg_src_h);
+ xor_(ki, ki);
+ L(l_kw);
+ {
+ for (int jj = 0; jj < ur_c; jj++) {
+ load_src(jj, 0, c_tail);
+ compute_max_op(jj);
+ }
+ add(aux_reg_src_w, c * sizeof_src_dt());
+ inc(ki);
+ cmp(ki, reg_kw);
+ jl(l_kw, T_NEAR);
+ }
+ add(aux_reg_src_h, iw * c * sizeof_src_dt());
+ inc(kj);
+ cmp(kj, reg_kh);
+ jl(l_kh, T_NEAR);
+ }
+
+ for (int jj = 0; jj < ur_c; jj++)
+ store_dst(jj, 0, c_tail);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_i8i8_pooling_fwd_ker_t<isa>::compute_avg_step(int ur_c, int c_tail)
+{
+ using namespace data_type;
+
+ Label l_kw, l_kh;
+
+ int iw = jpp.iw;
+ int c = jpp.c;
+
+ const int num_ll = data_type_size(avg_proc_dt)/data_type_size(jpp.src_dt);
+
+ for (int jj = 0; jj < ur_c; jj++) {
+ for (int ll = 0; ll < num_ll; ll++) {
+ bool masked = jj == ur_c - 1 && c_tail;
+ size_t msk = jpp.tail[ll];
+ if (!(masked && !msk)) {
+ uni_vpxor(vreg_src_s32(jj, ll), vreg_src_s32(jj, ll), vreg_src_s32(jj, ll));
+ uni_vpxor(vreg_dst_s32(jj, ll), vreg_dst_s32(jj, ll), vreg_dst_s32(jj, ll));
+ }
+ }
+ }
+
+ mov(aux_reg_src_h, reg_ptr_src_i8);
+
+ xor_(kj, kj);
+ L(l_kh);
+ {
+ mov(aux_reg_src_w, aux_reg_src_h);
+ xor_(ki, ki);
+ L(l_kw);
+ {
+ for (int jj = 0; jj < ur_c; jj++) {
+ for (int ll = 0; ll < num_ll; ll++) {
+ bool masked = jj == ur_c - 1 && c_tail;
+ size_t msk = jpp.tail[ll];
+ if (!(masked && !msk)) {
+ load_src(jj, ll, c_tail);
+ vpaddd(vreg_dst_s32(jj, ll), vreg_dst_s32(jj, ll),
+ vreg_src_s32(jj, ll));
+ }
+ }
+ }
+ add(aux_reg_src_w, c * sizeof_src_dt());
+ inc(ki);
+ cmp(ki, reg_kw);
+ jl(l_kw, T_NEAR);
+ }
+ add(aux_reg_src_h, iw * c * sizeof_src_dt());
+ inc(kj);
+ cmp(kj, reg_kh);
+ jl(l_kh, T_NEAR);
+ }
+
+ for (int jj = 0; jj < ur_c; jj++) {
+ for (int ll = 0; ll < num_ll; ll++) {
+ bool masked = jj == ur_c - 1 && c_tail;
+ size_t msk = jpp.tail[ll];
+ if (!(masked && !msk)) {
+ vcvtdq2ps(vreg_dst_f32(jj, ll), vreg_dst_s32(jj, ll));
+ vfmadd132ps(vreg_dst_f32(jj, ll), vreg_zeros, vreg_tmp);
+ vcvtps2dq(vreg_dst_s32(jj, ll), vreg_dst_f32(jj, ll));
+ store_dst(jj, ll, c_tail);
+ }
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_i8i8_pooling_fwd_ker_t<isa>::compute_step(int ur_c, int c_tail) {
+ switch (jpp.alg) {
+ case pooling_max:
+ compute_max_step(ur_c, c_tail); break;
+ case pooling_avg_include_padding:
+ case pooling_avg_exclude_padding:
+ compute_avg_step(ur_c, c_tail); break;
+ default: assert(!"unsupported pooling algorithm");
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_i8i8_pooling_fwd_ker_t<isa>::compute_c_block(){
+ Label l_main_loop;
+
+ int nb_c = jpp.nb_c;
+ int c_block = jpp.c_block;
+ int ur_c = jpp.ur_c;
+ int ur_c_tail = jpp.ur_c_tail;
+ int c_steps = nb_c / ur_c;
+ int c_tail = jpp.c_tail;
+
+ xor_(c_iter, c_iter);
+ if (c_steps > 0) {
+ L(l_main_loop); {
+ compute_step(ur_c, 0);
+ add(reg_ptr_src_i8, ur_c*c_block*sizeof_src_dt());
+ add(reg_ptr_dst_i8, ur_c*c_block*sizeof_dst_dt());
+ inc(c_iter);
+ cmp(c_iter, c_steps);
+ jl(l_main_loop, T_NEAR);
+ }
+ }
+
+ if (ur_c_tail != 0) {
+ compute_step(ur_c_tail, c_tail);
+ }
+}
+
+template<>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx2>::init_mask() {
+ using namespace data_type;
+ using cpu_isa = cpu_isa_traits<avx2>;
+
+ // AVX2 mask initialization: mask stored in Ymm-regs
+ auto init = [&](uint64_t bit_mask, bool init_mask_q) {
+ const size_t QW_PER_VREG = cpu_isa::vlen / sizeof(uint64_t);
+
+ uint64_t vmask[QW_PER_VREG];
+ for (size_t i = 0; i < QW_PER_VREG; i++){
+
+ uint64_t qw_vmask=0ULL;
+ const size_t DBITS = 8*sizeof_src_dt();
+ const uint64_t VMSK = 1ULL << (DBITS-1);
+ const size_t D_PER_QW = (8*sizeof(qw_vmask))/DBITS;
+ for (size_t j = 0; j < D_PER_QW; j++) {
+ if (bit_mask & 1)
+ qw_vmask |= VMSK << DBITS * j;
+ bit_mask >>= 1;
+ }
+ vmask[i] = qw_vmask;
+ }
+
+ // Put QWORDS with target mask into xmm regs
+ const int xdst_i[QW_PER_VREG] = {
+ xreg_mask_lo.getIdx(),
+ xreg_mask_lo.getIdx(),
+ xreg_mask_hi.getIdx(),
+ xreg_mask_hi.getIdx()
+ };
+ const int xsrc_i[QW_PER_VREG] = {
+ vreg_zeros.getIdx(), // 0-th qword insert in zeros -> {qw0, 0}
+ xreg_mask_lo.getIdx(), // 1-st and 0-th merge -> {qw0,qw1}
+ vreg_zeros.getIdx(),
+ xreg_mask_hi.getIdx()
+ };
+ const uint8 qw_dst_idx[QW_PER_VREG] = {0, 1, 0, 1}; // qword index in 128-bit xreg
+
+ for (size_t i = 0; i < QW_PER_VREG; i++) {
+ mov(reg_mask, vmask[i]);
+ vpinsrq(Xmm(xdst_i[i]), Xmm(xsrc_i[i]), reg_mask, qw_dst_idx[i]);
+ }
+
+ // Merge Low (xreg_mask_lo alias for vreg_mask.xreg)
+ // and High (xreg_mask_hi) into full vreg_mask
+ // vreg_mask -> {xreg_mask_hi, vreg_mask.xreg}
+ vinserti128(vreg_mask, vreg_mask, xreg_mask_hi, 1);
+
+ // Keep only low qword of mask in xreg_mask_q
+ if (init_mask_q) {
+ mov(reg_mask, vmask[0]);
+ vpinsrq(xreg_mask_q, Xmm(vreg_zeros.getIdx()), reg_mask, 0);
+ }
+ };
+
+ uint64_t tail_mask = (1ULL << jpp.c_tail) - 1;
+ switch (jpp.alg) {
+ case pooling_max:
+ // For "max" we need mask only in case of non-zero tail
+ if (tail_mask)
+ init(tail_mask, false);
+ break;
+ case pooling_avg_include_padding:
+ case pooling_avg_exclude_padding:
+ // For "avg" we need mask:
+ // - s32 - in case of the non-zero tail
+ // - s8/u8 - irrespective of the tail
+ switch (jpp.src_dt) {
+ case s32:
+ if (tail_mask)
+ init(tail_mask, false);
+ break;
+ case s8:
+ case u8:
+ init(tail_mask ? tail_mask : ~0ULL, tail_mask == 0);
+ break;
+ default: assert(!"unsupported src data type");
+ }
+ break;
+ default: assert(!"unsupported pooling algorithm");
+ }
+}
+
+template<>
+void jit_uni_i8i8_pooling_fwd_ker_t<avx512_core>::init_mask() {
+
+ for (int ll = 0; ll < max_num_ll; ll++) {
+ mov(reg_mask, jpp.tail[ll]);
+ kmovq(mask(ll), reg_mask);
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_i8i8_pooling_fwd_ker_t<isa>::init_tmp_reg() {
+ using namespace data_type;
+
+ switch (jpp.alg) {
+ case pooling_avg_include_padding:
+ case pooling_avg_exclude_padding:
+ mov(reg_tmp, ptr[reg_param + offsetof(call_params_t, idivider)]);
+ movq(xmm_tmp, reg_tmp);
+ vpbroadcastd(vreg_tmp, xmm_tmp);
+ break;
+ case pooling_max:
+ switch (jpp.src_dt) {
+ case s32:
+ mov(reg_tmp, nstl::numeric_limits<int32_t>::lowest());
+ break;
+ case s8:
+ mov(reg_tmp, nstl::numeric_limits<int8_t>::lowest());
+ break;
+ case u8:
+ mov(reg_tmp, nstl::numeric_limits<uint8_t>::lowest());
+ break;
+ default: assert(!"unsupported src data_type");
+ }
+
+ movq(xmm_tmp, reg_tmp);
+ if (jpp.src_dt == s32)
+ vpbroadcastd(vreg_tmp, xmm_tmp);
+ else
+ vpbroadcastb(vreg_tmp, xmm_tmp);
+ break;
+ default: assert(!"unsupported pooling algorithm");
+ }
+
+}
+
+template <cpu_isa_t isa>
+void jit_uni_i8i8_pooling_fwd_ker_t<isa>::generate() {
+ preamble();
+
+#if !defined(_WIN32)
+ // Always use rcx as abi_param1 -
+ // see the note about maskmovdqu near reg_param.
+ mov(rcx, rdi);
+#endif
+
+# define READ_PARAM(reg, field) \
+ mov(reg, ptr[reg_param + offsetof(call_params_t, field)])
+ READ_PARAM(reg_ptr_src_i8, src_i8);
+ READ_PARAM(reg_ptr_dst_i8, dst_i8);
+ READ_PARAM(reg_kw, kw_range);
+ READ_PARAM(reg_kh, kh_range);
+
+# undef READ_PARAM
+
+ uni_vpxor(vreg_zeros, vreg_zeros, vreg_zeros);
+
+ init_mask();
+
+ init_tmp_reg();
+
+ compute_c_block();
+
+ postamble();
+}
+
+template <cpu_isa_t isa>
+status_t jit_uni_i8i8_pooling_fwd_ker_t<isa>::init_conf(jit_pool_conf_t &jpp,
+ const pooling_pd_t *ppd) {
+ if (!mayiuse(isa))
+ return status::unimplemented;
+
+ const auto &pd = *ppd->desc();
+ const memory_desc_wrapper src_d(ppd->src_md());
+ const memory_desc_wrapper dst_d(ppd->dst_md());
+
+ jpp.mb = src_d.dims()[0];
+ jpp.c = src_d.dims()[1];
+ jpp.ih = src_d.dims()[2];
+ jpp.iw = src_d.dims()[3];
+ jpp.oh = dst_d.dims()[2];
+ jpp.ow = dst_d.dims()[3];
+
+ jpp.stride_h = pd.strides[0];
+ jpp.stride_w = pd.strides[1];
+ jpp.kh = pd.kernel[0];
+ jpp.kw = pd.kernel[1];
+
+ jpp.t_pad = pd.padding[0][0];
+ jpp.l_pad = pd.padding[0][1];
+
+ jpp.alg = pd.alg_kind;
+
+ jpp.src_dt = pd.src_desc.data_type;
+ jpp.dst_dt = pd.dst_desc.data_type;
+
+ // data_type items per one vreg on the <isa>
+ // isa == avx2 : 32 bytes -> 32 for s8/u8, 8 for s32
+ // isa == avx512* : 64 bytes -> 64 for s8/u8, 16 for s32
+ int simd_w = cpu_isa_traits<isa>::vlen / data_type_size(jpp.src_dt);
+
+ jpp.c_block = simd_w;
+ jpp.c_tail = jpp.c % jpp.c_block;
+ jpp.nb_c = jpp.c / jpp.c_block;
+ jpp.ur_c = 1;
+ jpp.ur_c_tail = jpp.nb_c - (jpp.nb_c / jpp.ur_c)*jpp.ur_c +
+ (jpp.c_tail != 0);
+
+ size_t tail_mask = (1ULL << jpp.c_tail) - 1;
+
+ switch (jpp.alg) {
+ case pooling_max:
+ jpp.tail[0] = tail_mask;
+ jpp.tail[1] = 0;
+ jpp.tail[2] = 0;
+ jpp.tail[3] = 0;
+ break;
+ case pooling_avg_include_padding:
+ case pooling_avg_exclude_padding: {
+ // avg_proc_dt (s32) defines granularity (because u8/s8 processed as s32)
+ // avx2 : 8, avx512 : 16
+ const size_t msk_gran = cpu_isa_traits<isa>::vlen / data_type_size(avg_proc_dt);
+ const size_t msk_msk = (1ULL << msk_gran) - 1;
+ size_t m = tail_mask;
+ for (size_t ll = 0; ll < max_num_ll; ll++) {
+ jpp.tail[ll] = m & msk_msk;
+ m = m >> msk_gran;
+ }
+ break;
+ }
+ default: return status::unimplemented;
+ }
+
+ return status::success;
+}
+
+template <cpu_isa_t isa>
+status_t jit_uni_i8i8_pooling_fwd_t<isa>::pd_t::jit_conf() {
+ return jit_uni_i8i8_pooling_fwd_ker_t<isa>::init_conf(jpp_, this);
+}
+
+template <cpu_isa_t isa>
+jit_uni_i8i8_pooling_fwd_t<isa>::
+jit_uni_i8i8_pooling_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd), ker_(nullptr)
+{ ker_ = new jit_uni_i8i8_pooling_fwd_ker_t<isa>(pd()->jpp_); }
+
+template <cpu_isa_t isa>
+jit_uni_i8i8_pooling_fwd_t<isa>::
+~jit_uni_i8i8_pooling_fwd_t() { delete ker_; }
+
+template <cpu_isa_t isa>
+void jit_uni_i8i8_pooling_fwd_t<isa>::execute_forward(
+ const exec_ctx_t &ctx) const {
+ auto src_i8 = CTX_IN_MEM(const char *, MKLDNN_ARG_SRC);
+ auto dst_i8 = CTX_OUT_MEM(char *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+
+ const auto &jpp = pd()->jpp_;
+
+ parallel_nd(jpp.mb, jpp.oh, jpp.ow,
+ [&](int n, int oh, int ow) {
+ const int ih = nstl::max(oh*jpp.stride_h - jpp.t_pad, 0);
+ const int iw = nstl::max(ow*jpp.stride_w - jpp.l_pad, 0);
+
+ const int kh_start = nstl::max(0, jpp.t_pad - oh * jpp.stride_h);
+ const int kh_end = nstl::min(jpp.kh,
+ jpp.ih + jpp.t_pad - oh * jpp.stride_h);
+ const int kw_start = nstl::max(0, jpp.l_pad - ow * jpp.stride_w);
+ const int kw_end = nstl::min(jpp.kw,
+ jpp.iw + jpp.l_pad - ow * jpp.stride_w);
+
+ auto p = typename jit_uni_i8i8_pooling_fwd_ker_t<isa>::call_params_t();
+ p.src_i8 = &src_i8[
+ src_d.blk_off(n, 0, ih, iw) * src_d.data_type_size()];
+ p.dst_i8 = &dst_i8[
+ dst_d.blk_off(n, 0, oh, ow) * dst_d.data_type_size()];
+ p.kw_range = (size_t)(kw_end - kw_start);
+ p.kh_range = (size_t)(kh_end - kh_start);
+ p.idivider = 1.0f / ((jpp.alg == pooling_avg_exclude_padding) ?
+ p.kh_range*p.kw_range : jpp.kw*jpp.kh);
+
+ ker_->ker_(&p);
+ });
+}
+
+// Explicit instantiation only for supported <isa> values.
+//
+template struct jit_uni_i8i8_pooling_fwd_ker_t<avx512_core>;
+template struct jit_uni_i8i8_pooling_fwd_t<avx512_core>;
+
+template struct jit_uni_i8i8_pooling_fwd_ker_t<avx2>;
+template struct jit_uni_i8i8_pooling_fwd_t<avx2>;
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_i8i8_pooling.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_i8i8_pooling.hpp
new file mode 100644
index 0000000000..d757679df5
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_i8i8_pooling.hpp
@@ -0,0 +1,89 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_UNI_I8I8_POOLING_HPP
+#define CPU_JIT_UNI_I8I8_POOLING_HPP
+
+#include "c_types_map.hpp"
+
+#include "cpu_pooling_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "cpu_isa_traits.hpp"
+#include "jit_primitive_conf.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <cpu_isa_t isa>
+struct jit_uni_i8i8_pooling_fwd_ker_t;
+
+template <cpu_isa_t isa>
+struct jit_uni_i8i8_pooling_fwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_pooling_fwd_pd_t {
+ using cpu_pooling_fwd_pd_t::cpu_pooling_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", isa, ""),
+ jit_uni_i8i8_pooling_fwd_t<isa>);
+
+ status_t init() {
+ bool ok = true
+ && mayiuse(isa)
+ && ndims() == 4
+ && set_default_params() == status::success
+ && desc()->prop_kind == prop_kind::forward_inference
+ && utils::one_of(desc()->alg_kind, alg_kind::pooling_max,
+ alg_kind::pooling_avg_include_padding,
+ alg_kind::pooling_avg_exclude_padding)
+ && utils::one_of(src_md()->data_type, data_type::s32,
+ data_type::s8, data_type::u8)
+ && src_md()->data_type == dst_md()->data_type
+ && attr()->has_default_values()
+ && memory_desc_matches_tag(*src_md(), format_tag::nhwc)
+ && memory_desc_matches_tag(*dst_md(), format_tag::nhwc);
+ if (!ok) return status::unimplemented;
+
+ return jit_conf();
+ }
+
+ jit_pool_conf_t jpp_;
+
+ protected:
+ status_t jit_conf();
+ };
+
+ jit_uni_i8i8_pooling_fwd_t(const pd_t *apd);
+ ~jit_uni_i8i8_pooling_fwd_t();
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_uni_i8i8_pooling_fwd_ker_t<isa> *ker_;
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn.cpp
new file mode 100644
index 0000000000..2c5a8e8973
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn.cpp
@@ -0,0 +1,305 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_uni_lrn_kernel_f32.hpp"
+#include "jit_uni_lrn.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::utils;
+
+template <cpu_isa_t isa>
+jit_uni_lrn_fwd_t<isa>::jit_uni_lrn_fwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd), ker_(nullptr)
+ , ker_first_(nullptr), ker_last_(nullptr)
+{
+ using namespace alg_kind;
+
+ const int C = pd()->C();
+ const int H = pd()->H();
+ const int W = pd()->W();
+ const int ls = pd()->desc()->local_size;
+ float A = pd()->desc()->lrn_alpha / ls;
+ float K = pd()->desc()->lrn_k;
+
+ auto pk = pd()->desc()->prop_kind;
+ auto ak = pd()->desc()->alg_kind;
+ auto dat_tag = pd()->dat_tag_;
+
+ if (dat_tag == nChw8c && ls == 5 && ak == lrn_across_channels) {
+ ker_ = new jit_uni_lrn_fwd_kernel_f32<isa>(
+ nchw8c_across(H, W, 0), A, K, pk);
+ ker_first_ = new jit_uni_lrn_fwd_kernel_f32<isa>(
+ nchw8c_across(H, W, -1), A, K, pk);
+ ker_last_ = new jit_uni_lrn_fwd_kernel_f32<isa>(
+ nchw8c_across(H, W, +1), A, K, pk);
+ } else if (dat_tag == nChw8c && ak == lrn_within_channel) {
+ /* within channel, local_size (x) local_size */
+ A /= ls; /* XXX: why? */
+ ker_ = new jit_uni_lrn_fwd_kernel_f32<isa>(
+ nchw8c_within(H, W, ls), A, K, pk);
+ } else if (dat_tag == nchw && ls == 5 && ak == lrn_across_channels) {
+ ker_ = new jit_uni_lrn_fwd_kernel_f32<isa>(
+ nchw_across(C, H*W, 0), A, K, pk);
+ int remind = (H*W) % VECTOR_LENGTH;
+ if (remind != 0) {
+ ker_last_ = new jit_uni_lrn_fwd_kernel_f32<isa>(
+ nchw_across(C, H*W, remind), A, K, pk);
+ }
+ } else if (true /* XXX: why */) {
+ ker_ = new jit_uni_lrn_fwd_kernel_f32<isa>(nhwc_across(C), A, K, pk);
+ }
+}
+
+template <cpu_isa_t isa>
+jit_uni_lrn_fwd_t<isa>::~jit_uni_lrn_fwd_t()
+{ delete ker_; delete ker_first_; delete ker_last_; }
+
+template <cpu_isa_t isa>
+void jit_uni_lrn_fwd_t<isa>::execute_forward(const exec_ctx_t &ctx) const {
+ using namespace alg_kind;
+
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+ auto ws = CTX_OUT_MEM(data_t *, MKLDNN_ARG_WORKSPACE);
+
+ const int N = pd()->MB();
+ const int C = pd()->C();
+ const int HW = pd()->H() * pd()->W();
+ const int ls = pd()->desc()->local_size;
+
+ auto ak = pd()->desc()->alg_kind;
+ auto dat_tag = pd()->dat_tag_;
+
+ if (dat_tag == nChw8c && ls == 5 && ak == lrn_across_channels) {
+ parallel_nd(N, C / VECTOR_LENGTH, [&](int n, int c8) {
+ jit_args_fwd_t args;
+ args.src = &src[n*HW*C + c8 * HW * VECTOR_LENGTH];
+ args.dst = &dst[n*HW*C + c8 * HW * VECTOR_LENGTH];
+ args.scratch = &ws[n*HW*C + c8 * HW * VECTOR_LENGTH];
+ if (c8 == 0)
+ (*ker_first_)(&args);
+ else if (c8 == C / VECTOR_LENGTH - 1)
+ (*ker_last_)(&args);
+ else
+ (*ker_)(&args);
+ });
+ }
+ else if (dat_tag == nChw8c && ak == lrn_within_channel) {
+ parallel_nd(N, C / VECTOR_LENGTH, [&](int n, int c8) {
+ jit_args_fwd_t args;
+ args.src = &src[n*HW*C + c8 * HW * VECTOR_LENGTH];
+ args.dst = &dst[n*HW*C + c8 * HW * VECTOR_LENGTH];
+ args.scratch = &ws[n*HW*C + c8 * HW * VECTOR_LENGTH];
+ (*ker_)(&args);
+ });
+ }
+ else if (dat_tag == nchw && ls == 5 && ak == lrn_across_channels) {
+ parallel_nd(N, (HW + VECTOR_LENGTH - 1) / VECTOR_LENGTH,
+ [&](int n, int hw8) {
+ jit_args_fwd_t args;
+ args.src = &src[n*HW*C + hw8 * VECTOR_LENGTH];
+ args.dst = &dst[n*HW*C + hw8 * VECTOR_LENGTH];
+ args.scratch = &ws[n*HW*C + hw8 * VECTOR_LENGTH];
+ if ((hw8 + 1)*VECTOR_LENGTH > HW)
+ (*ker_last_)(&args);
+ else
+ (*ker_)(&args);
+ });
+ }
+ else { // nhwc
+ parallel_nd(N, HW, [&](int n, int hw) {
+ jit_args_fwd_t args;
+ args.src = &src[n*HW*C + hw * C];
+ args.dst = &dst[n*HW*C + hw * C];
+ args.scratch = &ws[n*HW*C + hw * C];
+ (*ker_)(&args);
+ });
+ }
+}
+
+template <cpu_isa_t isa>
+status_t jit_uni_lrn_fwd_t<isa>::pd_t::init() {
+ using namespace prop_kind;
+ using namespace alg_kind;
+
+ const memory_desc_wrapper data_d(src_md());
+ bool ok = true
+ && mayiuse(isa)
+ && is_fwd()
+ && everyone_is(data_type::f32, data_d.data_type())
+ && !has_zero_dim_memory()
+ && data_d.ndims() == 4
+ && data_d.dims()[1] % VECTOR_LENGTH == 0
+ && data_d.dims()[1] >= 2 * VECTOR_LENGTH
+ && desc()->lrn_beta == 0.75
+ && attr()->has_default_values();
+ if (!ok) return unimplemented;
+
+ if (desc_.prop_kind == forward_training) ws_md_ = *src_md();
+
+ dat_tag_ = memory_desc_matches_one_of_tag(*src_md(), nChw8c, nchw, nhwc);
+
+ bool args_ok_across = true
+ && desc()->alg_kind == lrn_across_channels
+ && desc()->local_size == 5
+ && one_of(dat_tag_, nChw8c, nchw, nhwc);
+
+ const int jit_max_local_size = 5; // bigger size triggers too big code size
+ bool args_ok_within = true
+ && desc()->alg_kind == lrn_within_channel
+ && desc()->local_size <= ( jit_max_local_size <= MAX_LOCAL_SIZE
+ ? jit_max_local_size : MAX_LOCAL_SIZE)
+ && data_d.dims()[2] >= desc()->local_size
+ && data_d.dims()[3] >= desc()->local_size
+ && one_of(dat_tag_, nChw8c);
+
+ return args_ok_across || args_ok_within ? success : unimplemented;
+}
+
+template <cpu_isa_t isa>
+jit_uni_lrn_bwd_t<isa>::jit_uni_lrn_bwd_t(const pd_t *apd)
+ : cpu_primitive_t(apd)
+ , ker_(nullptr), ker_first_(nullptr), ker_last_(nullptr)
+{
+ using namespace alg_kind;
+ const int C = pd()->C();
+ const int H = pd()->H();
+ const int W = pd()->W();
+ const int ls = pd()->desc()->local_size;
+ float A = pd()->desc()->lrn_alpha / ls;
+ float B = pd()->desc()->lrn_beta;
+
+ int use_h_parallelizm = 0;// XXX
+ if (C / VECTOR_LENGTH == 1) {
+ ker_ = new jit_uni_lrn_bwd_kernel_f32<isa>(
+ nchw8c_across(H, W, 3), A, B, use_h_parallelizm);
+ }
+ else {
+ ker_ = new jit_uni_lrn_bwd_kernel_f32<isa>(
+ nchw8c_across(H, W, 0), A, B, use_h_parallelizm);
+ ker_first_ = new jit_uni_lrn_bwd_kernel_f32<isa>(
+ nchw8c_across(H, W, -1), A, B, use_h_parallelizm);
+ ker_last_ = new jit_uni_lrn_bwd_kernel_f32<isa>(
+ nchw8c_across(H, W, +1), A, B, use_h_parallelizm);
+ }
+}
+
+template <cpu_isa_t isa>
+jit_uni_lrn_bwd_t<isa>::~jit_uni_lrn_bwd_t()
+{
+ delete ker_; delete ker_first_; delete ker_last_;
+}
+
+template <cpu_isa_t isa>
+void jit_uni_lrn_bwd_t<isa>::execute_backward(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto ws = CTX_IN_MEM(const data_t *, MKLDNN_ARG_WORKSPACE);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const int N = pd()->MB();
+ const int C = pd()->C();
+ const int H = pd()->H();
+ const int W = pd()->W();
+
+ int use_h_parallelizm = 0; // XXX
+ if (use_h_parallelizm) {
+ parallel_nd(N, C / VECTOR_LENGTH, H, [&](int n, int c8, int h) {
+ auto offset = n*C*H*W + c8*H*W*VECTOR_LENGTH
+ + h*W*VECTOR_LENGTH;
+ jit_args_bwd_t args;
+ args.src = &src[offset];
+ args.diff_dst = &diff_dst[offset];
+ args.scratch = &ws[offset];
+ args.diff_src = &diff_src[offset];
+ if (C / VECTOR_LENGTH == 1)
+ (*ker_)(&args);
+ else if (c8 == 0)
+ (*ker_first_)(&args);
+ else if (c8 == C / VECTOR_LENGTH - 1)
+ (*ker_last_)(&args);
+ else
+ (*ker_)(&args);
+ });
+ }
+ else {
+ parallel_nd(N, C / VECTOR_LENGTH, [&](int n, int c8) {
+ auto offset = n*C*H*W + c8*H*W*VECTOR_LENGTH;
+ jit_args_bwd_t args;
+ args.src = &src[offset];
+ args.diff_dst = &diff_dst[offset];
+ args.scratch = &ws[offset];
+ args.diff_src = &diff_src[offset];
+ if (C / VECTOR_LENGTH == 1)
+ (*ker_)(&args);
+ else if (c8 == 0)
+ (*ker_first_)(&args);
+ else if (c8 == C / VECTOR_LENGTH - 1)
+ (*ker_last_)(&args);
+ else
+ (*ker_)(&args);
+ });
+ }
+}
+
+template <cpu_isa_t isa>
+status_t jit_uni_lrn_bwd_t<isa>::pd_t::init() {
+ using namespace prop_kind;
+ using namespace alg_kind;
+
+ const memory_desc_wrapper data_d(src_md());
+ bool ok = true
+ && mayiuse(isa)
+ && !is_fwd()
+ && utils::everyone_is(data_type::f32, data_d.data_type())
+ && !has_zero_dim_memory()
+ && data_d.ndims() == 4
+ && data_d.dims()[1] % VECTOR_LENGTH == 0
+ && desc()->lrn_beta == 0.75
+ && attr()->has_default_values();
+ if (!ok) return unimplemented;
+
+ ws_md_ = *src_md();
+ if (!compare_ws(hint_fwd_pd_)) return unimplemented;
+
+ dat_tag_ = memory_desc_matches_one_of_tag(*src_md(), nChw8c);
+
+ bool args_ok_across = true
+ && desc()->alg_kind == lrn_across_channels
+ && desc()->local_size == 5
+ && utils::one_of(dat_tag_, nChw8c);
+
+ return args_ok_across ? success : unimplemented;
+}
+
+template struct jit_uni_lrn_fwd_t<sse42>;
+template struct jit_uni_lrn_fwd_t<avx2>;
+template struct jit_uni_lrn_bwd_t<avx2>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn.hpp
new file mode 100644
index 0000000000..333cd3396d
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn.hpp
@@ -0,0 +1,103 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_UNI_LRN_HPP
+#define CPU_JIT_UNI_LRN_HPP
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_isa_traits.hpp"
+#include "cpu_lrn_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <cpu_isa_t isa> struct jit_uni_lrn_fwd_kernel_f32;
+template <cpu_isa_t isa> struct jit_uni_lrn_bwd_kernel_f32;
+
+template <cpu_isa_t isa>
+struct jit_uni_lrn_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_lrn_fwd_pd_t {
+ using cpu_lrn_fwd_pd_t::cpu_lrn_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", isa, ""),
+ jit_uni_lrn_fwd_t<isa>);
+
+ status_t init();
+
+ format_tag_t dat_tag_;
+ };
+
+ jit_uni_lrn_fwd_t(const pd_t *apd);
+ ~jit_uni_lrn_fwd_t();
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_uni_lrn_fwd_kernel_f32<isa> *ker_, *ker_first_, *ker_last_;
+};
+
+template <cpu_isa_t isa>
+struct jit_uni_lrn_bwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_lrn_bwd_pd_t {
+ using cpu_lrn_bwd_pd_t::cpu_lrn_bwd_pd_t;
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", isa, ""),
+ jit_uni_lrn_bwd_t<isa>);
+
+ status_t init();
+
+ format_tag_t dat_tag_;
+ };
+
+ jit_uni_lrn_bwd_t(const pd_t *apd);
+ ~jit_uni_lrn_bwd_t();
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ jit_uni_lrn_bwd_kernel_f32<isa> *ker_, *ker_first_, *ker_last_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn_kernel_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn_kernel_f32.cpp
new file mode 100644
index 0000000000..89af47272c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn_kernel_f32.cpp
@@ -0,0 +1,1487 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "utils.hpp"
+
+#include "jit_uni_lrn_kernel_f32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace Xbyak;
+
+//////////////////////////////////////////////////////////////////////////////
+// forward kernel
+template<cpu_isa_t isa>
+void jit_uni_lrn_fwd_kernel_f32<isa>::within_body(
+ int hoff, int Hoff, int woff, int Woff, int stride,
+ Xbyak::Ymm ysum, Xbyak::Ymm ydst, Xbyak::Ymm ytmp, Xbyak::Ymm ysum2,
+ prop_kind_t pk)
+{
+ vxorps(ysum, ysum, ysum);
+ for (int i = hoff; i <= Hoff; ++i)
+ {
+ for (int j = woff; j <= Woff; ++j)
+ {
+ if (i == 0 && j == 0)
+ {
+ vmovups(ydst, ptr[src]);
+ vfmadd231ps(ysum, ydst, ydst);
+ }
+ else
+ {
+ vmovups(ytmp, ptr[src + (i*stride + j)*VECTOR_LENGTH*4]);
+ vfmadd231ps(ysum, ytmp, ytmp);
+ }
+ }
+ }
+ vfmadd132ps(ysum, yk, yalpha); // ysum <- ysum*yalpha+yk
+ vmovaps(ytmp, ysum);
+ if (pk != prop_kind::forward_inference)
+ vmovups(ptr[scratch], ytmp);
+ vmulps(ysum2, ysum, ysum);
+ vmulps(ysum, ysum, ysum2); // ysum = (ysum*yalpha+yk)^3;
+ vsqrtps(ysum, ysum);
+ vsqrtps(ysum, ysum); // ysum = (ysum*yalpha+yk)^0.75
+ vdivps(ydst, ydst, ysum); // ydst <- ydst / ysum
+ vmovups(ptr[dst], ydst);
+ add(src, 32);
+ add(dst, 32);
+ if (pk != prop_kind::forward_inference)
+ add(scratch, 32);
+}
+
+template<cpu_isa_t isa>
+void jit_uni_lrn_fwd_kernel_f32<isa>::within_body_sse42(
+ int hoff, int Hoff, int woff, int Woff, int stride, prop_kind_t pk)
+{
+ Xbyak::Xmm xtmp_lo = xmm12;
+ Xbyak::Xmm xtmp_hi = xmm13;
+ Xbyak::Xmm xsum_lo = xmm8;
+ Xbyak::Xmm xsum_hi = xmm9;
+ Xbyak::Xmm xdst_lo = xmm10;
+ Xbyak::Xmm xdst_hi = xmm11;
+ Xbyak::Xmm xsum2_lo = xmm14;
+ Xbyak::Xmm xsum2_hi = xmm15;
+
+ xorps(xsum_lo, xsum_lo);
+ xorps(xsum_hi, xsum_hi);
+ for (int i = hoff; i <= Hoff; ++i)
+ {
+ for (int j = woff; j <= Woff; ++j)
+ {
+ if (i == 0 && j == 0)
+ {
+ movups(xdst_lo, ptr[src]);
+ movups(xdst_hi, ptr[src + 4 * sizeof(float)]);
+ mulps(xdst_lo, xdst_lo);
+ mulps(xdst_hi, xdst_hi);
+ addps(xsum_lo, xdst_lo);
+ addps(xsum_hi, xdst_hi);
+ }
+ else
+ {
+ movups(xtmp_lo, ptr[src + (i*stride + j)*VECTOR_LENGTH * 4]);
+ movups(xtmp_hi, ptr[src + (i*stride + j)*VECTOR_LENGTH * 4 + 4 * sizeof(float)]);
+ mulps(xtmp_lo, xtmp_lo);
+ mulps(xtmp_hi, xtmp_hi);
+ addps(xsum_lo, xtmp_lo);
+ addps(xsum_hi, xtmp_hi);
+ }
+ }
+ }
+ mulps(xsum_lo, xalpha);
+ mulps(xsum_hi, xalpha);
+ addps(xsum_lo, xk);
+ addps(xsum_hi, xk); // xsum <- xsum*xalpha+xk
+ movaps(xtmp_lo, xsum_lo);
+ movaps(xtmp_hi, xsum_hi);
+ if (pk != prop_kind::forward_inference) {
+ movups(ptr[scratch], xtmp_lo);
+ movups(ptr[scratch + 4 * sizeof(float)], xtmp_hi);
+ }
+ movaps(xsum2_lo, xsum_lo);
+ movaps(xsum2_hi, xsum_hi);
+ mulps(xsum2_lo, xsum_lo);
+ mulps(xsum2_hi, xsum_hi);
+ mulps(xsum_lo, xsum2_lo);
+ mulps(xsum_hi, xsum2_hi); // xsum = (xsum*xalpha+xk)^3;
+
+ sqrtps(xsum_lo, xsum_lo);
+ sqrtps(xsum_hi, xsum_hi);
+ sqrtps(xsum_lo, xsum_lo);
+ sqrtps(xsum_hi, xsum_hi); // xsum = (xsum*xalpha+xk)^0.75
+
+ movups(xdst_lo, ptr[src]);
+ movups(xdst_hi, ptr[src + 4 * sizeof(float)]);
+ divps(xdst_lo, xsum_lo);
+ divps(xdst_hi, xsum_hi); // xdst <- xdst / xsum
+
+ movups(ptr[dst], xdst_lo);
+ movups(ptr[dst + 4 * sizeof(float)], xdst_hi);
+ add(src, 32);
+ add(dst, 32);
+ if (pk != prop_kind::forward_inference)
+ add(scratch, 32);
+}
+
+template <cpu_isa_t isa>
+jit_uni_lrn_fwd_kernel_f32<isa>::jit_uni_lrn_fwd_kernel_f32(
+ const struct nchw8c_within &J,
+ float A,
+ float K,
+ prop_kind_t pk,
+ void *code_ptr,
+ size_t code_size)
+ : jit_generator(code_ptr, code_size)
+ , alpha(A), k(K)
+{
+ Xbyak::Reg64 h = r9;
+ Xbyak::Reg64 w = r10;
+ Vmm ysum = Vmm(isa == avx2 ? 9 : 9);
+ Vmm ysum2 = Vmm(isa == avx2 ? 10 : 10);
+ Vmm ydst = Vmm(isa == avx2 ? 11 : 11);
+ Vmm ytmp = Vmm(isa == avx2 ? 12 : 12);
+
+ this->preamble();
+
+ mov(src, ptr[this->param1 + 0]);
+ mov(dst, ptr[this->param1 + 8]);
+ if (pk != prop_kind::forward_inference)
+ mov(scratch, ptr[this->param1 + 16]);
+
+ mov(imm_addr64, float2int(this->alpha));
+ movq(xalpha, imm_addr64);
+ if (isa == avx2) {
+ vbroadcastss(yalpha, xalpha);
+ } else {
+ shufps(xalpha, xalpha, 0);
+ }
+
+ mov(imm_addr64, float2int(this->k));
+ movq(xk, imm_addr64);
+ if (isa == avx2) {
+ vbroadcastss(yk, xk);
+ } else {
+ shufps(xk, xk, 0);
+ }
+
+ int s2 = (J.size - 1) / 2, S2 = J.size - s2 - 1;
+
+ for (int i = 0; i < s2; ++i)
+ {
+ Label label_t;
+ for (int j = 0; j < s2; ++j) {
+ if (isa == avx2) {
+ within_body(-i, S2, -j, S2, J.W, ysum, ydst, ytmp, ysum2, pk);
+ }
+ else {
+ within_body_sse42(-i, S2, -j, S2, J.W, pk);
+ }
+ }
+ mov(w, J.W - J.size + 1);
+ L(label_t);
+ if (isa == avx2) {
+ within_body(-i, S2, -s2, S2, J.W, ysum, ydst, ytmp, ysum2, pk);
+ } else {
+ within_body_sse42(-i, S2, -s2, S2, J.W, pk);
+ }
+ dec(w);
+ cmp(w, 0);
+ jne(label_t, T_NEAR);
+ for (int j = J.W - S2; j < J.W; ++j) {
+ if (isa == avx2) {
+ within_body(-i, S2, -s2, J.W - 1 - j, J.W,
+ ysum, ydst, ytmp, ysum2, pk);
+ } else {
+ within_body_sse42(-i, S2, -s2, J.W - 1 - j, J.W, pk);
+ }
+ }
+ }
+
+ mov(h, J.H - J.size + 1);
+ Label lrn_loop_h;
+ L(lrn_loop_h);
+ for (int j = 0; j < s2; ++j) {
+ if (isa == avx2) {
+ within_body(-s2, S2, -j, S2, J.W, ysum, ydst, ytmp, ysum2, pk);
+ } else {
+ within_body_sse42(-s2, S2, -j, S2, J.W, pk);
+ }
+ }
+ mov(w, J.W - J.size + 1);
+ Label lrn_loop_w;
+ L(lrn_loop_w);
+ if (isa == avx2) {
+ within_body(-s2, S2, -s2, S2, J.W, ysum, ydst, ytmp, ysum2, pk);
+ } else {
+ within_body_sse42(-s2, S2, -s2, S2, J.W, pk);
+ }
+ dec(w);
+ cmp(w, 0);
+ jne(lrn_loop_w, T_NEAR);
+ for (int j = J.W - S2; j < J.W; ++j) {
+ if (isa == avx2) {
+ within_body(-s2, S2, -s2, J.W - 1 - j, J.W,
+ ysum, ydst, ytmp, ysum2, pk);
+ } else {
+ within_body_sse42(-s2, S2, -s2, J.W - 1 - j, J.W, pk);
+ }
+ }
+ dec(h);
+ cmp(h, 0);
+ jne(lrn_loop_h, T_NEAR);
+
+ for (int i = J.H - S2; i < J.H; ++i)
+ {
+ for (int j = 0; j < s2; ++j) {
+ if (isa == avx2) {
+ within_body(-s2, J.H - 1 - i, -j, S2, J.W,
+ ysum, ydst, ytmp, ysum2, pk);
+ } else {
+ within_body_sse42(-s2, J.H - 1 - i, -j, S2, J.W, pk);
+ }
+ }
+
+ mov(w, J.W - J.size + 1);
+ Label label_b;
+ L(label_b);
+ if (isa == avx2) {
+ within_body(-s2, J.H - 1 - i, -s2, S2, J.W,
+ ysum, ydst, ytmp, ysum2, pk);
+ } else {
+ within_body_sse42(-s2, J.H - 1 - i, -s2, S2, J.W, pk);
+ }
+ dec(w);
+ cmp(w, 0);
+ jne(label_b, T_NEAR);
+
+ for (int j = J.W - S2; j < J.W; ++j) {
+ if (isa == avx2) {
+ within_body(-s2, J.H - 1 - i, -s2, J.W - 1 - j, J.W,
+ ysum, ydst, ytmp, ysum2, pk);
+ } else {
+ within_body_sse42(-s2, J.H - 1 - i, -s2, J.W - 1 - j, J.W, pk);
+ }
+ }
+ }
+
+ this->postamble();
+
+ ker = reinterpret_cast<decltype(ker)>(const_cast<uint8_t*>(
+ this->getCode()));
+}
+
+template<>
+jit_uni_lrn_fwd_kernel_f32<avx2>::jit_uni_lrn_fwd_kernel_f32(
+ const struct nchw8c_across &J,
+ float A,
+ float K,
+ prop_kind_t pk,
+ void *code_ptr,
+ size_t code_size)
+ : jit_generator(code_ptr, code_size)
+ , alpha(A), k(K)
+{
+ Xbyak::Reg64 t = rsp;
+ Xbyak::Reg64 hw = r9;
+ Xbyak::Xmm xsrc_prev = xmm2;
+ Xbyak::Ymm ysrc = ymm3;
+ Xbyak::Ymm yc = ymm3;
+ Xbyak::Xmm xsrc_next = xmm4;
+ Xbyak::Ymm ya = ymm5;
+ Xbyak::Ymm yb = ymm6;
+ Xbyak::Ymm yd = ymm7;
+ Xbyak::Ymm ye = ymm8;
+ Xbyak::Ymm ysum = ymm9;
+ Xbyak::Ymm ysum2 = ymm10;
+ Xbyak::Ymm ydst = ymm11;
+ Xbyak::Ymm ybase = ymm12;
+
+ this->preamble();
+
+ mov(src, ptr[this->param1 + 0]);
+ mov(dst, ptr[this->param1 + 8]);
+ if (pk != prop_kind::forward_inference)
+ mov(scratch, ptr[this->param1 + 16]);
+ sub(t, 64);
+ mov(imm_addr64, float2int(this->alpha));
+ movq(xalpha, imm_addr64);
+ vbroadcastss(yalpha, xalpha);
+
+ mov(imm_addr64, float2int(this->k));
+ movq(xk, imm_addr64);
+ vbroadcastss(yk, xk);
+
+ if (J.version == -1)
+ {
+ vxorps(xsrc_prev, xsrc_prev, xsrc_prev);
+ vmovups(ptr[t + 0], xsrc_prev);
+ }
+ if (J.version == +1)
+ {
+ vxorps(xsrc_next, xsrc_next, xsrc_next);
+ vmovups(ptr[t + 48], xsrc_next);
+ }
+
+ mov(hw, J.H*J.W);
+
+ Label lrn_loop;
+ L(lrn_loop);
+
+ if (J.version != -1) vmovups(xsrc_prev, ptr[src - J.H*J.W * 32 + 16]);
+ vmovups(ysrc, ptr[src]);
+ if (J.version != +1) vmovups(xsrc_next, ptr[src + J.H*J.W * 32]);
+
+ if (J.version != -1) vmovups(ptr[t + 0], xsrc_prev);
+ vmovups(ptr[t + 16], ysrc);
+ if (J.version != +1) vmovups(ptr[t + 48], xsrc_next);
+
+ vmovups(ya, ptr[t + 16 - 8]);
+ vmovups(yb, ptr[t + 16 - 4]);
+ vmovups(yd, ptr[t + 16 + 4]);
+ vmovups(ye, ptr[t + 16 + 8]);
+ vmulps(ysum, yc, yc);
+ vfmadd231ps(ysum, ya, ya); // ysum <- ysum + ya*ya
+ vfmadd231ps(ysum, yb, yb);
+ vfmadd231ps(ysum, yd, yd);
+ vfmadd231ps(ysum, ye, ye);
+ vfmadd132ps(ysum, yk, yalpha); // ysum <- ysum*yalpha+yk
+
+ vmovaps(ybase, ysum);
+ if (pk != prop_kind::forward_inference)
+ vmovups(ptr[scratch], ybase);
+ vmulps(ysum2, ysum, ysum);
+ vmulps(ysum, ysum, ysum2); // ysum = ybase^3;
+ vsqrtps(ysum, ysum);
+ vsqrtps(ysum, ysum); // ysum = ybase^0.75
+ vdivps(ydst, ysrc, ysum); // ydst = ysrc / ysum
+ vmovups(ptr[dst], ydst);
+
+ add(src, 32);
+ add(dst, 32);
+ if (pk != prop_kind::forward_inference)
+ add(scratch, 32);
+ dec(hw);
+ cmp(hw, 0);
+ jne(lrn_loop, T_NEAR);
+
+ add(t, 64);
+ this->postamble();
+
+ ker = reinterpret_cast<decltype(ker)>(const_cast<uint8_t*>(
+ this->getCode()));
+}
+
+template<>
+jit_uni_lrn_fwd_kernel_f32<sse42>::jit_uni_lrn_fwd_kernel_f32(
+ const struct nchw8c_across &J,
+ float A,
+ float K,
+ prop_kind_t pk,
+ void *code_ptr,
+ size_t code_size)
+ : jit_generator(code_ptr, code_size)
+ , alpha(A), k(K)
+{
+ Xbyak::Reg64 t = rsp;
+ Xbyak::Reg64 hw = r9;
+
+ Xbyak::Xmm xsrc_lo = xmm2;
+ Xbyak::Xmm xsrc_hi = xmm3;
+ Xbyak::Xmm xc_lo = xmm4;
+ Xbyak::Xmm xc_hi = xmm5;
+ Xbyak::Xmm xsum_lo = xc_lo;
+ Xbyak::Xmm xsum_hi = xc_hi;
+ Xbyak::Xmm xsrc_prev = xmm6;
+ Xbyak::Xmm xsrc_next = xmm7;
+ Xbyak::Xmm xa_lo = xmm8;
+ Xbyak::Xmm xa_hi = xmm9;
+ Xbyak::Xmm xb_lo = xmm10;
+ Xbyak::Xmm xb_hi = xmm11;
+ Xbyak::Xmm xd_lo = xmm12;
+ Xbyak::Xmm xd_hi = xmm13;
+ Xbyak::Xmm xe_lo = xmm14;
+ Xbyak::Xmm xe_hi = xmm15;
+ Xbyak::Xmm xbase_lo = xmm14;
+ Xbyak::Xmm xbase_hi = xmm15;
+
+ this->preamble();
+
+ mov(src, ptr[this->param1 + 0]);
+ mov(dst, ptr[this->param1 + 8]);
+ if (pk != prop_kind::forward_inference)
+ mov(scratch, ptr[this->param1 + 16]);
+ sub(t, 64);
+ mov(imm_addr64, float2int(this->alpha));
+ movq(xalpha, imm_addr64);
+ shufps(xalpha, xalpha, 0);
+
+ mov(imm_addr64, float2int(this->k));
+ movq(xk, imm_addr64);
+ shufps(xk, xk, 0);
+
+ if (J.version == -1)
+ {
+ xorps(xsrc_prev, xsrc_prev);
+ movups(ptr[t + 0], xsrc_prev);
+ }
+ if (J.version == +1)
+ {
+ xorps(xsrc_next, xsrc_next);
+ movups(ptr[t + 48], xsrc_next);
+ }
+
+ mov(hw, J.H*J.W);
+ Label lrn_loop;
+ L(lrn_loop);
+
+ if (J.version != -1) movups(xsrc_prev, ptr[src - J.H*J.W * 32 + 16]);
+ movups(xsrc_lo, ptr[src]);
+ movups(xsrc_hi, ptr[src + 4 * sizeof(float)]);
+ if (J.version != +1) movups(xsrc_next, ptr[src + J.H*J.W * 32]);
+
+ if (J.version != -1) movups(ptr[t + 0], xsrc_prev);
+ movups(ptr[t + 16], xsrc_lo);
+ movups(ptr[t + 16 + 4 * sizeof(float)], xsrc_hi);
+ if (J.version != +1) movups(ptr[t + 48], xsrc_next);
+
+ movups(xa_lo, ptr[t + 16 - 8]);
+ movups(xa_hi, ptr[t + 16 - 8 + 4 * sizeof(float)]);
+ movups(xb_lo, ptr[t + 16 - 4]);
+ movups(xb_hi, ptr[t + 16 - 4 + 4 * sizeof(float)]);
+ movups(xd_lo, ptr[t + 16 + 4]);
+ movups(xd_hi, ptr[t + 16 + 4 + 4 * sizeof(float)]);
+ movups(xe_lo, ptr[t + 16 + 8]);
+ movups(xe_hi, ptr[t + 16 + 8 + 4 * sizeof(float)]);
+ movaps(xc_lo, xsrc_lo);
+ movaps(xc_hi, xsrc_hi);
+ mulps(xsum_lo, xc_lo);
+ mulps(xsum_hi, xc_hi);
+ mulps(xa_lo, xa_lo);
+ mulps(xa_hi, xa_hi);
+ addps(xsum_lo, xa_lo);
+ addps(xsum_hi, xa_hi); // xsum <- xsum + xa*xa
+ mulps(xb_lo, xb_lo);
+ mulps(xb_hi, xb_hi);
+ addps(xsum_lo, xb_lo);
+ addps(xsum_hi, xb_hi);
+ mulps(xd_lo, xd_lo);
+ mulps(xd_hi, xd_hi);
+ addps(xsum_lo, xd_lo);
+ addps(xsum_hi, xd_hi);
+ mulps(xe_lo, xe_lo);
+ mulps(xe_hi, xe_hi);
+ addps(xsum_lo, xe_lo);
+ addps(xsum_hi, xe_hi);
+
+ mulps(xsum_lo, xalpha);
+ mulps(xsum_hi, xalpha);
+ addps(xsum_lo, xk);
+ addps(xsum_hi, xk); // xsum <- xsum*xalpha+xk
+
+ movaps(xbase_lo, xsum_lo);
+ movaps(xbase_hi, xsum_hi);
+ if (pk != prop_kind::forward_inference) {
+ movups(ptr[scratch], xbase_lo);
+ movups(ptr[scratch + 4 * sizeof(float)], xbase_hi);
+ }
+ mulps(xsum_lo, xsum_lo);
+ mulps(xsum_hi, xsum_hi);
+ mulps(xsum_lo, xbase_lo);
+ mulps(xsum_hi, xbase_hi); // xsum = xbase^3;
+ sqrtps(xsum_lo, xsum_lo);
+ sqrtps(xsum_hi, xsum_hi);
+ sqrtps(xsum_lo, xsum_lo);
+ sqrtps(xsum_hi, xsum_hi); // xsum = xbase^0.75
+ divps(xsrc_lo, xsum_lo);
+ divps(xsrc_hi, xsum_hi); // xdst = xsrc / xsum
+ movups(ptr[dst], xsrc_lo);
+ movups(ptr[dst + 4 * sizeof(float)], xsrc_hi);
+
+ add(src, 32);
+ add(dst, 32);
+ if (pk != prop_kind::forward_inference)
+ add(scratch, 32);
+ dec(hw);
+ cmp(hw, 0);
+ jne(lrn_loop, T_NEAR);
+
+ add(t, 64);
+ this->postamble();
+
+ ker = reinterpret_cast<decltype(ker)>(const_cast<uint8_t*>(
+ this->getCode()));
+}
+
+template<>
+jit_uni_lrn_fwd_kernel_f32<avx2>::jit_uni_lrn_fwd_kernel_f32(
+ const struct nhwc_across &J,
+ float A,
+ float K,
+ prop_kind_t pk,
+ void *code_ptr,
+ size_t code_size)
+ : jit_generator(code_ptr, code_size)
+ , alpha(A), k(K)
+{
+ static const uint32_t mask[] = {
+ 0, 0, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
+ 0x80000000, 0x80000000, 0x80000000, 0, 0
+ };
+
+ Xbyak::Reg64 c = r9;
+ Xbyak::Ymm ya = ymm2;
+ Xbyak::Ymm yb = ymm3;
+ Xbyak::Ymm yc = ymm4;
+ Xbyak::Ymm yd = ymm5;
+ Xbyak::Ymm ye = ymm6;
+ Xbyak::Ymm ysum = ymm7;
+ Xbyak::Ymm ydst = ymm8;
+ Xbyak::Ymm ybase = ymm9;
+ Xbyak::Ymm ymask = ymm10;
+
+ this->preamble();
+
+ mov(src, ptr[this->param1 + 0]);
+ mov(dst, ptr[this->param1 + 8]);
+ if (pk != prop_kind::forward_inference)
+ mov(scratch, ptr[this->param1 + 16]);
+ mov(imm_addr64, float2int(this->alpha));
+ movq(xalpha, imm_addr64);
+ vbroadcastss(yalpha, xalpha);
+
+ mov(imm_addr64, float2int(this->k));
+ movq(xk, imm_addr64);
+ vbroadcastss(yk, xk);
+
+ vxorps(ysum, ysum, ysum);
+
+ mov(imm_addr64, reinterpret_cast<size_t>(&mask[0]));
+ vmovups(ymask, ptr[imm_addr64]);
+ vmaskmovps(ya, ymask, ptr[src - 8]);
+ vfmadd231ps(ysum, ya, ya); // ysum <- ysum + ya^2+yb^2+yc^2+yd^2+ye^2
+
+ mov(imm_addr64, reinterpret_cast<size_t>(&mask[1]));
+ vmovups(ymask, ptr[imm_addr64]);
+ vmaskmovps(yb, ymask, ptr[src - 4]);
+ vfmadd231ps(ysum, yb, yb);
+
+ mov(c, J.C / 8 - 1);
+ Label lrn_loop;
+ L(lrn_loop);
+
+ vmovups(yc, ptr[src]);
+ vmovups(yd, ptr[src + 4]);
+ vmovups(ye, ptr[src + 8]);
+ vfmadd231ps(ysum, yc, yc);
+ vfmadd231ps(ysum, yd, yd);
+ vfmadd231ps(ysum, ye, ye);
+
+ vmovups(ydst, ysum);
+ vfmadd132ps(ydst, yk, yalpha); // ydst <- ysum*yalpha+yk
+
+ vmovaps(ybase, ydst);
+ if (pk != prop_kind::forward_inference)
+ vmovups(ptr[scratch], ybase);
+ vmulps(ydst, ydst, ydst);
+ vmulps(ydst, ydst, ybase); // ydst = (ysum*yalpha+yk)^3;
+ vsqrtps(ydst, ydst);
+ vsqrtps(ydst, ydst); // ydst = (ysum*yalpha+yk)^0.75
+
+ vdivps(ydst, yc, ydst); // ydst = ysrc / (ysum*yalpha+yk)^0.75
+ vmovups(ptr[dst], ydst);
+
+ vxorps(ysum, ysum, ysum);
+
+ add(src, 32);
+ add(dst, 32);
+ if (pk != prop_kind::forward_inference)
+ add(scratch, 32);
+
+ vmovups(ya, ptr[src - 8]);
+ vfmadd231ps(ysum, ya, ya);
+ vmovups(yb, ptr[src - 4]);
+ vfmadd231ps(ysum, yb, yb);
+
+ dec(c);
+ cmp(c, 0);
+ jne(lrn_loop, T_NEAR);
+
+ vmovups(yc, ptr[src]);
+ vfmadd231ps(ysum, yc, yc);
+
+ mov(imm_addr64, reinterpret_cast<size_t>(&mask[2]));
+ vmovups(ymask, ptr[imm_addr64]);
+ vmaskmovps(yd, ymask, ptr[src + 4]);
+ vfmadd231ps(ysum, yd, yd); // ysum <- ysum + ya^2+yb^2+yc^2+yd^2+ye^2
+
+ mov(imm_addr64, reinterpret_cast<size_t>(&mask[3]));
+ vmovups(ymask, ptr[imm_addr64]);
+ vmaskmovps(ye, ymask, ptr[src + 8]);
+ vfmadd231ps(ysum, ye, ye);
+
+ vmovups(ydst, ysum);
+ vfmadd132ps(ydst, yk, yalpha); // ydst <- ysum*yalpha+yk
+
+ vmovaps(ybase, ydst);
+ if (pk != prop_kind::forward_inference)
+ vmovups(ptr[scratch], ybase);
+ vmulps(ydst, ydst, ydst);
+ vmulps(ydst, ydst, ybase); // ydst = (ysum*yalpha+yk)^3;
+ vsqrtps(ydst, ydst);
+ vsqrtps(ydst, ydst); // ydst = (ysum*yalpha+yk)^0.75
+ vdivps(ydst, yc, ydst); // ydst = ysrc / (ysum*yalpha+yk)^0.75
+
+ vmovups(ptr[dst], ydst);
+
+ this->postamble();
+
+ ker = reinterpret_cast<decltype(ker)>(const_cast<uint8_t*>(
+ this->getCode()));
+}
+
+template<>
+jit_uni_lrn_fwd_kernel_f32<sse42>::jit_uni_lrn_fwd_kernel_f32(
+ const struct nhwc_across &J,
+ float A,
+ float K,
+ prop_kind_t pk,
+ void *code_ptr,
+ size_t code_size)
+ : jit_generator(code_ptr, code_size)
+ , alpha(A), k(K)
+{
+ static const uint32_t mask[] = {
+ 0, 0, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0, 0
+ };
+
+ static uint32_t store[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ Xbyak::Reg64 c = r9;
+
+ Xbyak::Xmm xdst_lo = xmm0;
+ Xbyak::Xmm xdst_hi = xmm1;
+ Xbyak::Xmm xa_lo = xmm2;
+ Xbyak::Xmm xa_hi = xmm3;
+ Xbyak::Xmm xb_lo = xmm2;
+ Xbyak::Xmm xb_hi = xmm3;
+ Xbyak::Xmm xc_lo = xmm4;
+ Xbyak::Xmm xc_hi = xmm5;
+ Xbyak::Xmm xd_lo = xmm6;
+ Xbyak::Xmm xd_hi = xmm7;
+ Xbyak::Xmm xe_lo = xmm8;
+ Xbyak::Xmm xe_hi = xmm9;
+ Xbyak::Xmm xsum_lo = xmm10;
+ Xbyak::Xmm xsum_hi = xmm11;
+ Xbyak::Xmm xmask_lo = xmm12;
+ Xbyak::Xmm xmask_hi = xmm13;
+ Xbyak::Xmm xbase_lo = xmm14;
+ Xbyak::Xmm xbase_hi = xmm15;
+
+ this->preamble();
+
+ mov(src, ptr[this->param1 + 0]);
+ mov(dst, ptr[this->param1 + 8]);
+ if (pk != prop_kind::forward_inference)
+ mov(scratch, ptr[this->param1 + 16]);
+ mov(imm_addr64, float2int(this->alpha));
+ movq(xalpha, imm_addr64);
+ shufps(xalpha, xalpha, 0);
+
+ mov(imm_addr64, float2int(this->k));
+ movq(xk, imm_addr64);
+ shufps(xk, xk, 0);
+
+ mov(store_addr, reinterpret_cast<size_t>(&store[0]));
+ and_(store_addr, -15);
+ movups(ptr[store_addr], xalpha);
+ movups(ptr[store_addr + 4 * sizeof(float)], xk);
+
+ xorps(xsum_lo, xsum_lo);
+ xorps(xsum_hi, xsum_hi);
+
+ mov(imm_addr64, reinterpret_cast<size_t>(&mask[0]));
+ movups(xmask_lo, ptr[imm_addr64]);
+ movups(xmask_hi, ptr[imm_addr64 + 4 * sizeof(float)]);
+ movups(xa_lo, ptr[src - 8]);
+ movups(xa_hi, ptr[src - 8 + 4 * sizeof(float)]);
+ andps(xa_lo, xmask_lo);
+ andps(xa_hi, xmask_hi);
+ mulps(xa_lo, xa_lo);
+ mulps(xa_hi, xa_hi);
+ addps(xsum_lo, xa_lo);
+ addps(xsum_hi, xa_hi); // xsum <- xsum + xa^2+xb^2+xc^2+xd^2+xe^2
+
+ mov(imm_addr64, reinterpret_cast<size_t>(&mask[1]));
+ movups(xmask_lo, ptr[imm_addr64]);
+ movups(xmask_hi, ptr[imm_addr64 + 4 * sizeof(float)]);
+ movups(xb_lo, ptr[src - 4]);
+ movups(xb_hi, ptr[src - 4 + 4 * sizeof(float)]);
+ andps(xb_lo, xmask_lo);
+ andps(xb_hi, xmask_hi);
+ mulps(xb_lo, xb_lo);
+ mulps(xb_hi, xb_hi);
+ addps(xsum_lo, xb_lo);
+ addps(xsum_hi, xb_hi);
+
+ mov(c, J.C / 8 - 1);
+ Label lrn_loop;
+ L(lrn_loop);
+
+ movups(xc_lo, ptr[src]);
+ movups(xc_hi, ptr[src + 4 * sizeof(float)]);
+ movups(xd_lo, ptr[src + 4]);
+ movups(xd_hi, ptr[src + 4 + 4 * sizeof(float)]);
+ movups(xe_lo, ptr[src + 8]);
+ movups(xe_hi, ptr[src + 8 + 4 * sizeof(float)]);
+ mulps(xc_lo, xc_lo);
+ mulps(xc_hi, xc_hi);
+ addps(xsum_lo, xc_lo);
+ addps(xsum_hi, xc_hi);
+ mulps(xd_lo, xd_lo);
+ mulps(xd_hi, xd_hi);
+ addps(xsum_lo, xd_lo);
+ addps(xsum_hi, xd_hi);
+ mulps(xe_lo, xe_lo);
+ mulps(xe_hi, xe_hi);
+ addps(xsum_lo, xe_lo);
+ addps(xsum_hi, xe_hi);
+
+ movaps(xdst_lo, xsum_lo);
+ movaps(xdst_hi, xsum_hi);
+ // xdst <- xsum*xalpha+xk
+ mulps(xdst_lo, ptr[store_addr]);
+ mulps(xdst_hi, ptr[store_addr]);
+ addps(xdst_lo, ptr[store_addr + 4 * sizeof(float)]);
+ addps(xdst_hi, ptr[store_addr + 4 * sizeof(float)]);
+
+ movaps(xbase_lo, xdst_lo);
+ movaps(xbase_hi, xdst_hi);
+ if (pk != prop_kind::forward_inference) {
+ movups(ptr[scratch], xbase_lo);
+ movups(ptr[scratch + 4 * sizeof(float)], xbase_hi);
+ }
+ mulps(xdst_lo, xdst_lo);
+ mulps(xdst_hi, xdst_hi);
+ mulps(xdst_lo, xbase_lo);
+ mulps(xdst_hi, xbase_hi); // xdst = (xsum*xalpha+xk)^3;
+ sqrtps(xdst_lo, xdst_lo);
+ sqrtps(xdst_hi, xdst_hi);
+ sqrtps(xdst_lo, xdst_lo);
+ sqrtps(xdst_hi, xdst_hi); // xdst = (xsum*xalpha+xk)^0.75
+
+ movups(xc_lo, ptr[src]);
+ movups(xc_hi, ptr[src + 4 * sizeof(float)]);
+ divps(xc_lo, xdst_lo);
+ divps(xc_hi, xdst_hi); // xdst = xsrc / (xsum*xalpha+xk)^0.75
+ movups(ptr[dst], xc_lo);
+ movups(ptr[dst + 4 * sizeof(float)], xc_hi);
+
+ xorps(xsum_lo, xsum_lo);
+ xorps(xsum_hi, xsum_hi);
+
+ add(src, 32);
+ add(dst, 32);
+ if (pk != prop_kind::forward_inference)
+ add(scratch, 32);
+
+ movups(xa_lo, ptr[src - 8]);
+ movups(xa_hi, ptr[src - 8 + 4 * sizeof(float)]);
+ mulps(xa_lo, xa_lo);
+ mulps(xa_hi, xa_hi);
+ addps(xsum_lo, xa_lo);
+ addps(xsum_hi, xa_hi);
+ movups(xb_lo, ptr[src - 4]);
+ movups(xb_hi, ptr[src - 4 + 4 * sizeof(float)]);
+ mulps(xb_lo, xb_lo);
+ mulps(xb_hi, xb_hi);
+ addps(xsum_lo, xb_lo);
+ addps(xsum_hi, xb_hi);
+
+ dec(c);
+ cmp(c, 0);
+ jne(lrn_loop, T_NEAR);
+
+ movups(xc_lo, ptr[src]);
+ movups(xc_hi, ptr[src + 4 * sizeof(float)]);
+ mulps(xc_lo, xc_lo);
+ mulps(xc_hi, xc_hi);
+ addps(xsum_lo, xc_lo);
+ addps(xsum_hi, xc_hi);
+
+ mov(imm_addr64, reinterpret_cast<size_t>(&mask[2]));
+ movups(xmask_lo, ptr[imm_addr64]);
+ movups(xmask_hi, ptr[imm_addr64 + 4 * sizeof(float)]);
+ movups(xd_lo, ptr[src + 4]);
+ movups(xd_hi, ptr[src + 4 + 4 * sizeof(float)]);
+ andps(xd_lo, xmask_lo);
+ andps(xd_hi, xmask_hi);
+ mulps(xd_lo, xd_lo);
+ mulps(xd_hi, xd_hi);
+ addps(xsum_lo, xd_lo);
+ addps(xsum_hi, xd_hi); // xsum <- xsum + xa^2+xb^2+xc^2+xd^2+xe^2
+
+ mov(imm_addr64, reinterpret_cast<size_t>(&mask[3]));
+ movups(xmask_lo, ptr[imm_addr64]);
+ movups(xmask_hi, ptr[imm_addr64 + 4 * sizeof(float)]);
+ movups(xe_lo, ptr[src + 8]);
+ movups(xe_hi, ptr[src + 8 + 4 * sizeof(float)]);
+ andps(xe_lo, xmask_lo);
+ andps(xe_hi, xmask_hi);
+ mulps(xe_lo, xe_lo);
+ mulps(xe_hi, xe_hi);
+ addps(xsum_lo, xe_lo);
+ addps(xsum_hi, xe_hi);
+
+ movups(xdst_lo, xsum_lo);
+ movups(xdst_hi, xsum_hi);
+ // xdst <- xsum*xalpha+xk
+ mulps(xdst_lo, ptr[store_addr]);
+ mulps(xdst_hi, ptr[store_addr]);
+ addps(xdst_lo, ptr[store_addr + 4 * sizeof(float)]);
+ addps(xdst_hi, ptr[store_addr + 4 * sizeof(float)]);
+
+ movaps(xbase_lo, xdst_lo);
+ movaps(xbase_hi, xdst_hi);
+ if (pk != prop_kind::forward_inference) {
+ movups(ptr[scratch], xbase_lo);
+ movups(ptr[scratch + 4 * sizeof(float)], xbase_hi);
+ }
+ mulps(xdst_lo, xdst_lo);
+ mulps(xdst_hi, xdst_hi);
+ mulps(xdst_lo, xbase_lo);
+ mulps(xdst_hi, xbase_hi); // xdst = (xsum*xalpha+xk)^3;
+ sqrtps(xdst_lo, xdst_lo);
+ sqrtps(xdst_hi, xdst_hi);
+ sqrtps(xdst_lo, xdst_lo);
+ sqrtps(xdst_hi, xdst_hi); // xdst = (xsum*xalpha+xk)^0.75
+ movups(xc_lo, ptr[src]);
+ movups(xc_hi, ptr[src + 4 * sizeof(float)]);
+ divps(xc_lo, xdst_lo);
+ divps(xc_hi, xdst_hi); // xdst = xsrc / (xsum*xalpha+xk)^0.75
+
+ movups(ptr[dst], xc_lo);
+ movups(ptr[dst + 4 * sizeof(float)], xc_hi);
+
+ this->postamble();
+
+ ker = reinterpret_cast<decltype(ker)>(const_cast<uint8_t*>(
+ this->getCode()));
+}
+
+template<>
+void jit_uni_lrn_fwd_kernel_f32<sse42>::nchw_body(
+ int tail, int HW, prop_kind_t pk,
+ Xbyak::Ymm ymask,
+ Xbyak::Ymm ya,
+ Xbyak::Ymm yb,
+ Xbyak::Ymm yc,
+ Xbyak::Ymm yd,
+ Xbyak::Ymm ye,
+ Xbyak::Ymm ysum) {}
+
+template<>
+void jit_uni_lrn_fwd_kernel_f32<avx2>::nchw_body(
+ int tail, int HW, prop_kind_t pk,
+ Xbyak::Ymm ymask,
+ Xbyak::Ymm ya,
+ Xbyak::Ymm yb,
+ Xbyak::Ymm yc,
+ Xbyak::Ymm yd,
+ Xbyak::Ymm ye,
+ Xbyak::Ymm ysum)
+{
+ Xbyak::Ymm ydst = ymm14;
+ Xbyak::Ymm ybase = ymm15;
+
+ vfmadd231ps(ysum, ye, ye);
+
+ vmovups(ydst, ysum);
+ vfmadd132ps(ydst, yk, yalpha); // ydst <- ysum*yalpha+yk
+
+ vmovaps(ybase, ydst);
+ if (pk != prop_kind::forward_inference)
+ {
+ if (tail != 0)
+ vmaskmovps(ptr[scratch], ymask, ybase);
+ else
+ vmovups(ptr[scratch], ybase);
+ }
+ vmulps(ydst, ydst, ydst);
+ vmulps(ydst, ydst, ybase); // ydst = (ysum*yalpha+yk)^3;
+ vsqrtps(ydst, ydst);
+ vsqrtps(ydst, ydst); // ydst = (ysum*yalpha+yk)^0.75
+ vdivps(ydst, yc, ydst); // ydst = ysrc / (ysum*yalpha+yk)^0.75
+
+ if (tail != 0)
+ vmaskmovps(ptr[dst], ymask, ydst);
+ else
+ vmovups(ptr[dst], ydst);
+
+
+ vfnmadd231ps(ysum, ya, ya);
+ vmovups(ya, yb);
+ vmovups(yb, yc);
+ vmovups(yc, yd);
+ vmovups(yd, ye);
+}
+
+template<>
+void jit_uni_lrn_fwd_kernel_f32<avx2>::nchw_tail_sse42(
+ int tail, Xbyak::Reg64 reg_dst, Xbyak::Xmm xtail_lo, Xbyak::Xmm xtail_hi)
+{}
+
+template<>
+void jit_uni_lrn_fwd_kernel_f32<sse42>::nchw_tail_sse42(
+ int tail, Xbyak::Reg64 reg_dst, Xbyak::Xmm xtail_lo, Xbyak::Xmm xtail_hi)
+{
+ Xbyak::Xmm xmm_tmp = xmm10;
+ movaps(xmm_tmp, xtail_lo);
+ size_t offset = 0;
+
+ if (tail > 4) {
+ movups(ptr[reg_dst], xtail_lo);
+ movaps(xmm_tmp, xtail_hi);
+ offset += 4 * sizeof(float);
+ tail -= 4;
+ }
+ movss(ptr[reg_dst + offset], xmm_tmp);
+ for (int i = 1; i < tail; i++)
+ {
+ psrldq(xmm_tmp, 4);
+ movss(ptr[reg_dst + offset + i * sizeof(float)], xmm_tmp);
+ }
+}
+
+template<>
+void jit_uni_lrn_fwd_kernel_f32<sse42>::nchw_body_sse42(
+ int tail, int HW, prop_kind_t pk,
+ Xbyak::Xmm xmask_lo, Xbyak::Xmm xmask_hi,
+ Xbyak::Xmm xe_lo, Xbyak::Xmm xe_hi,
+ Xbyak::Xmm xsum_lo, Xbyak::Xmm xsum_hi)
+{
+ Xbyak::Xmm xdst_lo = xmm0;
+ Xbyak::Xmm xdst_hi = xmm1;
+ Xbyak::Xmm xbase_lo = xmm6;
+ Xbyak::Xmm xbase_hi = xmm7;
+ Xbyak::Xmm xtmp_lo = xmm8;
+ Xbyak::Xmm xtmp_hi = xmm9;
+ Xbyak::Xmm xa_lo = xmm6;
+ Xbyak::Xmm xa_hi = xmm7;
+ Xbyak::Xmm xb_lo = xmm8;
+ Xbyak::Xmm xb_hi = xmm9;
+ Xbyak::Xmm xc_lo = xmm10;
+ Xbyak::Xmm xc_hi = xmm11;
+ Xbyak::Xmm xd_lo = xmm12;
+ Xbyak::Xmm xd_hi = xmm13;
+
+ // store xe
+ movaps(ptr[store_addr + 10 * 4 * sizeof(float)], xe_lo);
+ movaps(ptr[store_addr + 11 * 4 * sizeof(float)], xe_hi);
+
+ mulps(xe_lo, xe_lo);
+ mulps(xe_hi, xe_hi);
+ addps(xsum_lo, xe_lo);
+ addps(xsum_hi, xe_hi);
+
+ // xdst <- xsum*xalpha+xk
+ movaps(xdst_lo, xsum_lo);
+ movaps(xdst_hi, xsum_hi);
+ mulps(xdst_lo, ptr[store_addr + 0 * 4 * sizeof(float)]);
+ mulps(xdst_hi, ptr[store_addr + 0 * 4 * sizeof(float)]);
+ addps(xdst_lo, ptr[store_addr + 1 * 4 * sizeof(float)]);
+ addps(xdst_hi, ptr[store_addr + 1 * 4 * sizeof(float)]);
+
+ movaps(xbase_lo, xdst_lo);
+ movaps(xbase_hi, xdst_hi);
+ if (pk != prop_kind::forward_inference)
+ {
+ if (tail != 0) {
+ nchw_tail_sse42(tail, scratch, xbase_lo, xbase_hi);
+ }
+ else {
+ movups(ptr[scratch], xbase_lo);
+ movups(ptr[scratch + 4 * sizeof(float)], xbase_hi);
+ }
+ }
+ mulps(xdst_lo, xdst_lo);
+ mulps(xdst_hi, xdst_hi);
+ mulps(xdst_lo, xbase_lo);
+ mulps(xdst_hi, xbase_hi); // xdst = (xsum*xalpha+xk)^3;
+ sqrtps(xdst_lo, xdst_lo);
+ sqrtps(xdst_hi, xdst_hi);
+ sqrtps(xdst_lo, xdst_lo);
+ sqrtps(xdst_hi, xdst_hi); // xdst = (xsum*xalpha+xk)^0.75
+ movaps(xtmp_lo, ptr[store_addr + 6 * 4 * sizeof(float)]);
+ movaps(xtmp_hi, ptr[store_addr + 7 * 4 * sizeof(float)]);
+ divps(xtmp_lo, xdst_lo);
+ divps(xtmp_hi, xdst_hi); // xdst = xsrc / (xsum*xalpha+xk)^0.75
+ movaps(xdst_lo, xtmp_lo);
+ movaps(xdst_hi, xtmp_hi);
+
+ if (tail != 0) {
+ nchw_tail_sse42(tail, dst, xdst_lo, xdst_hi);
+ }
+ else {
+ movups(ptr[dst], xdst_lo);
+ movups(ptr[dst + 4 * sizeof(float)], xdst_hi);
+ }
+
+ movaps(xa_lo, ptr[store_addr + 2 * 4 * sizeof(float)]);
+ movaps(xa_hi, ptr[store_addr + 3 * 4 * sizeof(float)]);
+ mulps(xa_lo, xa_lo);
+ mulps(xa_hi, xa_hi);
+ subps(xsum_lo, xa_lo);
+ subps(xsum_hi, xa_hi);
+
+ // xa <- xb
+ movaps(xb_lo, ptr[store_addr + 4 * 4 * sizeof(float)]);
+ movaps(xb_hi, ptr[store_addr + 5 * 4 * sizeof(float)]);
+ movaps(ptr[store_addr + 2 * 4 * sizeof(float)], xb_lo);
+ movaps(ptr[store_addr + 3 * 4 * sizeof(float)], xb_hi);
+
+ // xb <- xc
+ movaps(xc_lo, ptr[store_addr + 6 * 4 * sizeof(float)]);
+ movaps(xc_hi, ptr[store_addr + 7 * 4 * sizeof(float)]);
+ movaps(ptr[store_addr + 4 * 4 * sizeof(float)], xc_lo);
+ movaps(ptr[store_addr + 5 * 4 * sizeof(float)], xc_hi);
+
+ // xc <- xd
+ movaps(xd_lo, ptr[store_addr + 8 * 4 * sizeof(float)]);
+ movaps(xd_hi, ptr[store_addr + 9 * 4 * sizeof(float)]);
+ movaps(ptr[store_addr + 6 * 4 * sizeof(float)], xd_lo);
+ movaps(ptr[store_addr + 7 * 4 * sizeof(float)], xd_hi);
+
+ // xd <- xe
+ movaps(xe_lo, ptr[store_addr + 10 * 4 * sizeof(float)]);
+ movaps(xe_hi, ptr[store_addr + 11 * 4 * sizeof(float)]);
+ movaps(ptr[store_addr + 8 * 4 * sizeof(float)], xe_lo);
+ movaps(ptr[store_addr + 9 * 4 * sizeof(float)], xe_hi);
+}
+
+template<>
+void jit_uni_lrn_fwd_kernel_f32<avx2>::nchw_body_sse42(
+ int tail, int HW, prop_kind_t pk,
+ Xbyak::Xmm xmask_lo, Xbyak::Xmm xmask_hi,
+ Xbyak::Xmm xe_lo, Xbyak::Xmm xe_hi,
+ Xbyak::Xmm xsum_lo, Xbyak::Xmm xsum_hi) {}
+
+template<>
+jit_uni_lrn_fwd_kernel_f32<avx2>::jit_uni_lrn_fwd_kernel_f32(
+ struct nchw_across J,
+ float A,
+ float K,
+ prop_kind_t pk,
+ void* code_ptr,
+ size_t code_size)
+ : jit_generator(code_ptr, code_size)
+ , alpha(A), k(K)
+{
+ static const uint32_t mask[] = {
+ 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000,
+ 0x80000000, 0x80000000, 0, 0, 0, 0, 0, 0, 0
+ };
+ Xbyak::Reg64 c = r10;
+ Xbyak::Ymm ymask = ymm2;
+ Xbyak::Ymm ye = ymm3;
+ Xbyak::Ymm ya = ymm4;
+ Xbyak::Ymm yb = ymm5;
+ Xbyak::Ymm yc = ymm6;
+ Xbyak::Ymm yd = ymm7;
+ Xbyak::Ymm ysum = ymm8;
+
+ this->preamble();
+
+ if (J.tail != 0)
+ {
+ mov(imm_addr64, reinterpret_cast<size_t>(&mask[7 - J.tail]));
+ vmovups(ymask, ptr[imm_addr64]);
+ }
+ mov(imm_addr64, float2int(this->alpha));
+ movq(xalpha, imm_addr64);
+ vbroadcastss(yalpha, xalpha);
+
+ mov(imm_addr64, float2int(this->k));
+ movq(xk, imm_addr64);
+ vbroadcastss(yk, xk);
+
+ mov(src, ptr[this->param1 + 0]);
+ mov(dst, ptr[this->param1 + 8]);
+ if (pk != prop_kind::forward_inference)
+ mov(scratch, ptr[this->param1 + 16]);
+
+ vxorps(ya, ya, ya);
+ vxorps(yb, yb, yb);
+ if (J.tail != 0)
+ vmaskmovps(yc, ymask, ptr[src + J.HW * 0]);
+ else
+ vmovups(yc, ptr[src + J.HW * 0]);
+ if (J.tail != 0)
+ vmaskmovps(yd, ymask, ptr[src + J.HW * 4]);
+ else
+ vmovups(yd, ptr[src + J.HW * 4]);
+
+ vxorps(ysum, ysum, ysum);
+ vfmadd231ps(ysum, yc, yc); // ysum <- ysum + ya^2+yb^2+yc^2+yd^2+ye^2
+ vfmadd231ps(ysum, yd, yd);
+
+ mov(c, J.C - 2);
+ Label lrn_loop;
+ L(lrn_loop);
+
+ if (J.tail != 0)
+ vmaskmovps(ye, ymask, ptr[src + J.HW * 8]);
+ else
+ vmovups(ye, ptr[src + J.HW * 8]);
+
+ nchw_body(J.tail, J.HW, pk, ymask, ya, yb, yc, yd, ye, ysum);
+
+ add(src, J.HW * 4);
+ add(dst, J.HW * 4);
+ if (pk != prop_kind::forward_inference)
+ add(scratch, J.HW * 4);
+ dec(c);
+ cmp(c, 0);
+ jne(lrn_loop, T_NEAR);
+
+ vxorps(ye, ye, ye);
+
+ nchw_body(J.tail, J.HW, pk, ymask, ya, yb, yc, yd, ye, ysum);
+ add(src, J.HW * 4);
+ add(dst, J.HW * 4);
+ if (pk != prop_kind::forward_inference)
+ add(scratch, J.HW * 4);
+
+ nchw_body(J.tail, J.HW, pk, ymask, ya, yb, yc, yd, ye, ysum);
+
+ this->postamble();
+
+ ker = reinterpret_cast<decltype(ker)>(const_cast<uint8_t*>(
+ this->getCode()));
+}
+
+template<>
+jit_uni_lrn_fwd_kernel_f32<sse42>::jit_uni_lrn_fwd_kernel_f32(
+ struct nchw_across J,
+ float A,
+ float K,
+ prop_kind_t pk,
+ void* code_ptr,
+ size_t code_size)
+ : jit_generator(code_ptr, code_size)
+ , alpha(A), k(K)
+{
+ static const uint32_t mask[] = {
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ Xbyak::Reg64 c = r10;
+
+ Xbyak::Xmm xmask_lo = xmm2;
+ Xbyak::Xmm xmask_hi = xmm3;
+ Xbyak::Xmm xsum_lo = xmm4;
+ Xbyak::Xmm xsum_hi = xmm5;
+ Xbyak::Xmm xa_lo = xmm6;
+ Xbyak::Xmm xa_hi = xmm7;
+ Xbyak::Xmm xb_lo = xmm8;
+ Xbyak::Xmm xb_hi = xmm9;
+ Xbyak::Xmm xc_lo = xmm10;
+ Xbyak::Xmm xc_hi = xmm11;
+ Xbyak::Xmm xd_lo = xmm12;
+ Xbyak::Xmm xd_hi = xmm13;
+ Xbyak::Xmm xe_lo = xmm14;
+ Xbyak::Xmm xe_hi = xmm15;
+
+ this->preamble();
+
+ mov(src, ptr[this->param1 + 0]);
+ mov(dst, ptr[this->param1 + 8]);
+ if (pk != prop_kind::forward_inference)
+ mov(scratch, ptr[this->param1 + 16]);
+
+ sub(rsp, stack_space_needed);
+ mov(store_addr, rsp);
+ and_(store_addr, -15);
+
+ mov(imm_addr64, float2int(this->alpha));
+ movq(xalpha, imm_addr64);
+ shufps(xalpha, xalpha, 0);
+
+ mov(imm_addr64, float2int(this->k));
+ movq(xk, imm_addr64);
+ shufps(xk, xk, 0);
+
+ // put alpha and k into store (free up regs)
+ movaps(ptr[store_addr + 0 * 4 * sizeof(float)], xalpha);
+ movaps(ptr[store_addr + 1 * 4 * sizeof(float)], xk);
+
+ if (J.tail != 0)
+ {
+ mov(imm_addr64, reinterpret_cast<size_t>(&mask[7 - J.tail]));
+ movups(xmask_lo, ptr[imm_addr64]);
+ movups(xmask_hi, ptr[imm_addr64 + 4 * sizeof(float)]);
+ }
+ // init xa, xb
+ xorps(xa_lo, xa_lo);
+ xorps(xa_hi, xa_hi);
+ xorps(xb_lo, xb_lo);
+ xorps(xb_hi, xb_hi);
+
+ // read xc, xd
+ if (J.tail != 0) {
+ movups(xc_lo, ptr[src + J.HW * 0]);
+ movups(xc_hi, ptr[src + J.HW * 0 + 4 * sizeof(float)]);
+ andps(xc_lo, xmask_lo);
+ andps(xc_hi, xmask_hi);
+ }
+ else {
+ movups(xc_lo, ptr[src + J.HW * 0]);
+ movups(xc_hi, ptr[src + J.HW * 0 + 4 * sizeof(float)]);
+ }
+ if (J.tail != 0) {
+ movups(xd_lo, ptr[src + J.HW * 4]);
+ movups(xd_hi, ptr[src + J.HW * 4 + 4 * sizeof(float)]);
+ andps(xd_lo, xmask_lo);
+ andps(xd_hi, xmask_hi);
+ }
+ else {
+ movups(xd_lo, ptr[src + J.HW * 4]);
+ movups(xd_hi, ptr[src + J.HW * 4 + 4 * sizeof(float)]);
+ }
+
+ // put xa, xb, xc, xd into store to free-up regs
+ movaps(ptr[store_addr + 2 * 4 * sizeof(float)], xa_lo);
+ movaps(ptr[store_addr + 3 * 4 * sizeof(float)], xa_hi);
+ movaps(ptr[store_addr + 4 * 4 * sizeof(float)], xb_lo);
+ movaps(ptr[store_addr + 5 * 4 * sizeof(float)], xb_hi);
+ movaps(ptr[store_addr + 6 * 4 * sizeof(float)], xc_lo);
+ movaps(ptr[store_addr + 7 * 4 * sizeof(float)], xc_hi);
+ movaps(ptr[store_addr + 8 * 4 * sizeof(float)], xd_lo);
+ movaps(ptr[store_addr + 9 * 4 * sizeof(float)], xd_hi);
+
+ xorps(xsum_lo, xsum_lo);
+ xorps(xsum_hi, xsum_hi);
+ mulps(xc_lo, xc_lo);
+ mulps(xc_hi, xc_hi);
+ addps(xsum_lo, xc_lo);
+ addps(xsum_hi, xc_hi);
+ mulps(xd_lo, xd_lo);
+ mulps(xd_hi, xd_hi);
+ addps(xsum_lo, xd_lo);
+ addps(xsum_hi, xd_hi); // xsum <- xsum + xa^2+xb^2+xc^2+xd^2+xe^2
+
+ mov(c, J.C - 2);
+ Label lrn_loop;
+ L(lrn_loop);
+
+ if (J.tail != 0) {
+ movups(xe_lo, ptr[src + J.HW * 8]);
+ movups(xe_hi, ptr[src + J.HW * 8 + 4 * sizeof(float)]);
+ andps(xe_lo, xmask_lo);
+ andps(xe_hi, xmask_hi);
+ }
+ else {
+ movups(xe_lo, ptr[src + J.HW * 8]);
+ movups(xe_hi, ptr[src + J.HW * 8 + 4 * sizeof(float)]);
+ }
+
+ nchw_body_sse42(J.tail, J.HW, pk, xmask_lo, xmask_hi,
+ xe_lo, xe_hi,
+ xsum_lo, xsum_hi);
+
+ add(src, J.HW * 4);
+ add(dst, J.HW * 4);
+ if (pk != prop_kind::forward_inference)
+ add(scratch, J.HW * 4);
+ dec(c);
+ cmp(c, 0);
+ jne(lrn_loop, T_NEAR);
+
+ xorps(xe_lo, xe_lo);
+ xorps(xe_hi, xe_hi);
+
+ nchw_body_sse42(J.tail, J.HW, pk, xmask_lo, xmask_hi,
+ xe_lo, xe_hi,
+ xsum_lo, xsum_hi);
+ add(src, J.HW * 4);
+ add(dst, J.HW * 4);
+ if (pk != prop_kind::forward_inference)
+ add(scratch, J.HW * 4);
+
+ nchw_body_sse42(J.tail, J.HW, pk, xmask_lo, xmask_hi,
+ xe_lo, xe_hi,
+ xsum_lo, xsum_hi);
+
+ add(rsp, stack_space_needed);
+
+ this->postamble();
+
+ ker = reinterpret_cast<decltype(ker)>(const_cast<uint8_t*>(
+ this->getCode()));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// backward kernel
+template <cpu_isa_t isa>
+jit_uni_lrn_bwd_kernel_f32<isa>::jit_uni_lrn_bwd_kernel_f32(
+ const struct nchw8c_across &J,
+ float A,
+ float B,
+ int use_h_parallel,
+ void *code_ptr,
+ size_t code_size)
+ : jit_generator(code_ptr, code_size)
+ , nalphabeta(-2 * A*B)
+ , use_h_parallelizm(use_h_parallel)
+{
+ Xbyak::Reg64 t = rsp;
+ Xbyak::Reg64 hw = r10;
+
+ Xbyak::Xmm xsrc_prev = xmm1;
+ Xbyak::Xmm xws_prev = xmm2;
+ Xbyak::Xmm xdiffdst_prev = xmm3;
+ Xbyak::Ymm ysrc = ymm4;
+ Xbyak::Ymm yws = ymm5;
+ Xbyak::Ymm ydiffdst = ymm6;
+ Xbyak::Xmm xsrc_next = xmm7;
+ Xbyak::Xmm xws_next = xmm8;
+ Xbyak::Xmm xdiffdst_next = xmm9;
+ Xbyak::Ymm ya = ymm10;
+ Xbyak::Xmm xa = xmm10;
+ Xbyak::Ymm yb = ymm11;
+ Xbyak::Ymm yd = ymm12;
+ Xbyak::Ymm ye = ymm13;
+ Xbyak::Ymm ysum = ymm14;
+ Xbyak::Ymm ydiffsrc = ymm15;
+
+ this->preamble();
+
+ mov(src, ptr[this->param1 + 0]);
+ mov(diffdst, ptr[this->param1 + 8]);
+ mov(workspace, ptr[this->param1 + 16]);
+ mov(diffsrc, ptr[this->param1 + 24]);
+
+ sub(t, 64);
+ mov(imm_addr64, float2int(this->nalphabeta));
+ movq(xnalphabeta, imm_addr64);
+ vbroadcastss(ynalphabeta, xnalphabeta);
+
+ bool is_single = J.version == 3;
+ bool is_first = J.version == -1 || J.version == -2;
+ bool is_last = J.version == +1 || J.version == -2;
+
+ if (is_first || is_single) {
+ vxorps(xsrc_prev, xsrc_prev, xsrc_prev);
+ vmovups(ptr[t + 0], xsrc_prev);
+ }
+ if (is_last || is_single) {
+ vxorps(xsrc_next, xsrc_next, xsrc_next);
+ vmovups(ptr[t + 48], xsrc_next);
+ }
+ mov(hw, this->use_h_parallelizm ? J.W : J.H*J.W);
+ Label lrn_loop;
+ L(lrn_loop);
+ {
+ if (!is_first && !is_single) {
+ vmovups(xws_prev, ptr[workspace - J.H*J.W * 32 + 16]);
+ vmovups(xsrc_prev, ptr[src - J.H*J.W * 32 + 16]);
+ vmovups(xdiffdst_prev, ptr[diffdst - J.H*J.W * 32 + 16]);
+ vmulps(xa, xws_prev, xws_prev);
+ vmulps(xa, xa, xws_prev);
+ vsqrtps(xa, xa);
+ vsqrtps(xa, xa);
+ vmulps(xa, xa, xws_prev);
+ vdivps(xsrc_prev, xsrc_prev, xa);
+ vmulps(xdiffdst_prev, xdiffdst_prev, xsrc_prev);
+ }
+
+ vmovups(ysrc, ptr[src]);
+ vmovups(yws, ptr[workspace]);
+ vmovups(ydiffdst, ptr[diffdst]);
+ vmulps(ya, yws, yws);
+ vmulps(ya, ya, yws);
+ vsqrtps(ya, ya);
+ vsqrtps(ya, ya);
+ vdivps(ydiffsrc, ydiffdst, ya);
+ vdivps(ysum, ydiffsrc, yws);
+ vmulps(ysum, ysum, ysrc);
+
+ if (!is_last && !is_single) {
+ vmovups(xws_next, ptr[workspace + J.H*J.W * 32]);
+ vmovups(xsrc_next, ptr[src + J.H*J.W * 32]);
+ vmovups(xdiffdst_next, ptr[diffdst + J.H*J.W * 32]);
+ vmulps(xa, xws_next, xws_next);
+ vmulps(xa, xa, xws_next);
+ vsqrtps(xa, xa);
+ vsqrtps(xa, xa);
+ vmulps(xa, xa, xws_next);
+ vdivps(xsrc_next, xsrc_next, xa);
+ vdivps(xsrc_next, xsrc_next, xws_next);
+ vmulps(xdiffdst_next, xdiffdst_next, xsrc_next);
+ }
+
+ if (!is_first && !is_single) vmovups(ptr[t + 0], xdiffdst_prev);
+ vmovups(ptr[t + 16], ysum);
+ if (!is_last && !is_single) vmovups(ptr[t + 48], xdiffdst_next);
+
+ vmovups(ya, ptr[t + 16 - 8]);
+ vmovups(yb, ptr[t + 16 - 4]);
+ vaddps(ysum, ysum, ya);
+ vmulps(ysrc, ysrc, ynalphabeta);
+ vaddps(ysum, ysum, yb);
+
+ vmovups(yd, ptr[t + 16 + 4]);
+ vmovups(ye, ptr[t + 16 + 8]);
+ vaddps(ysum, ysum, yd);
+ vaddps(ysum, ysum, ye);
+
+ vfmadd231ps(ydiffsrc, ysum, ysrc);
+
+ vmovups(ptr[diffsrc], ydiffsrc);
+
+ add(src, 32);
+ add(diffsrc, 32);
+ add(diffdst, 32);
+ add(workspace, 32);
+
+ dec(hw);
+ cmp(hw, 0);
+ jne(lrn_loop, T_NEAR);
+ }
+
+ add(t, 64);
+ this->postamble();
+
+ ker = reinterpret_cast<decltype(ker)>(const_cast<uint8_t*>(
+ this->getCode()));
+}
+
+template struct jit_uni_lrn_fwd_kernel_f32<sse42>;
+template struct jit_uni_lrn_fwd_kernel_f32<avx2>;
+template struct jit_uni_lrn_bwd_kernel_f32<avx2>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn_kernel_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn_kernel_f32.hpp
new file mode 100644
index 0000000000..2b3ed43cd4
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_lrn_kernel_f32.hpp
@@ -0,0 +1,183 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_UNI_LRN_KERNEL_F32_HPP
+#define CPU_JIT_UNI_LRN_KERNEL_F32_HPP
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+
+#include "jit_generator.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace Xbyak;
+
+enum params { VECTOR_LENGTH = 8, MAX_LOCAL_SIZE = 32 };
+
+typedef struct {
+ const float *src;
+ float *dst, *scratch;
+} jit_args_fwd_t;
+
+typedef struct {
+ const float *src, *diff_dst, *scratch;
+ float *diff_src;
+} jit_args_bwd_t;
+
+struct nchw8c_across {
+ /* version:
+ * -1: channels 0..7,
+ * 1: channels C-8 .. C-1,
+ * 0: other channels
+ * 3: channels only for this kernel(without prev and next)
+ */
+ int H, W, version;
+ nchw8c_across(int h, int w, int v) : H(h), W(w), version(v) {}
+};
+
+struct nchw8c_within {
+ int H, W, size;
+ nchw8c_within(int h, int w, int s) : H(h), W(w), size(s) {}
+};
+
+struct nchw_across {
+ int C, HW, tail;
+ nchw_across(int c, int hw, int t) : C(c), HW(hw), tail(t) {}
+};
+
+struct nhwc_across {
+ int C;
+ nhwc_across(int c) : C(c) {}
+};
+
+template <cpu_isa_t isa>
+struct jit_uni_lrn_fwd_kernel_f32 : public jit_generator {
+ Xbyak::Reg64 src = rax;
+ Xbyak::Reg64 dst = r8;
+ Xbyak::Reg64 scratch = rdx;
+ Xbyak::Reg64 imm_addr64 = rbx;
+ Xbyak::Reg64 store_addr = rbp;
+
+ Xbyak::Xmm xalpha = xmm0;
+ Xbyak::Ymm yalpha = ymm0;
+ Xbyak::Xmm xk = xmm1;
+ Xbyak::Ymm yk = ymm1;
+
+ float alpha;
+ float k;
+
+ int stack_space_needed = 11 * 4 * sizeof(float) + 16;
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_uni_lrn_fwd_kernel_f32)
+
+ /* cpu specific part */
+ using Vmm = typename utils::conditional<isa == avx2, Ymm, Zmm>::type;
+
+ jit_uni_lrn_fwd_kernel_f32(
+ const struct nchw8c_within &J,
+ float A,
+ float K,
+ prop_kind_t pk,
+ void *code_ptr = nullptr,
+ size_t code_size = 4 * Xbyak::DEFAULT_MAX_CODE_SIZE);
+ jit_uni_lrn_fwd_kernel_f32(
+ const struct nchw8c_across &J,
+ float A,
+ float K,
+ prop_kind_t pk,
+ void *code_ptr = nullptr,
+ size_t code_size = 1 * Xbyak::DEFAULT_MAX_CODE_SIZE);
+ jit_uni_lrn_fwd_kernel_f32(
+ const struct nhwc_across &J,
+ float A,
+ float K,
+ prop_kind_t pk,
+ void *code_ptr = nullptr,
+ size_t code_size = 1 * Xbyak::DEFAULT_MAX_CODE_SIZE);
+ jit_uni_lrn_fwd_kernel_f32(
+ struct nchw_across J,
+ float A,
+ float K,
+ prop_kind_t pk,
+ void* code_ptr = nullptr,
+ size_t code_size = 2 * Xbyak::DEFAULT_MAX_CODE_SIZE);
+
+ void within_body(
+ int hoff, int Hoff, int woff, int Woff, int stride,
+ Xbyak::Ymm ysum, Xbyak::Ymm ydst, Xbyak::Ymm ytmp, Xbyak::Ymm ysum2,
+ prop_kind_t pk);
+ void within_body_sse42(
+ int hoff, int Hoff, int woff, int Woff, int stride, prop_kind_t pk);
+
+
+ void nchw_body(int tail, int HW, prop_kind_t pk,
+ Xbyak::Ymm ymask,
+ Xbyak::Ymm ya,
+ Xbyak::Ymm yb,
+ Xbyak::Ymm yc,
+ Xbyak::Ymm yd,
+ Xbyak::Ymm ye,
+ Xbyak::Ymm ysum);
+ void nchw_body_sse42(int tail, int HW, prop_kind_t pk,
+ Xbyak::Xmm xmask_lo, Xbyak::Xmm xmask_hi,
+ Xbyak::Xmm xe_lo, Xbyak::Xmm xe_hi,
+ Xbyak::Xmm xsum_lo, Xbyak::Xmm xsum_hi);
+ void nchw_tail_sse42(int tail, Xbyak::Reg64 reg_dst,
+ Xbyak::Xmm xtail_lo, Xbyak::Xmm xtail_hi);
+
+ void operator()(jit_args_fwd_t *arg) { ker(arg); }
+ void(*ker)(jit_args_fwd_t *);
+};
+
+template <cpu_isa_t isa>
+struct jit_uni_lrn_bwd_kernel_f32 : public jit_generator {
+ Xbyak::Reg64 src = rax;
+ Xbyak::Reg64 diffsrc = r8;
+ Xbyak::Reg64 diffdst = r9;
+ Xbyak::Reg64 workspace = rdx;
+ Xbyak::Reg64 imm_addr64 = rsi;
+
+ Xbyak::Xmm xnalphabeta = xmm0;
+ Xbyak::Ymm ynalphabeta = ymm0;
+
+ float nalphabeta;
+
+ int use_h_parallelizm;
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_uni_lrn_bwd_kernel_f32)
+
+ jit_uni_lrn_bwd_kernel_f32(
+ const struct nchw8c_across &J,
+ float A,
+ float B,
+ int use_h_parallel,
+ void *code_ptr = nullptr,
+ size_t code_size = 1 * Xbyak::DEFAULT_MAX_CODE_SIZE);
+
+ void operator()(jit_args_bwd_t *arg) { ker(arg); }
+ void(*ker)(jit_args_bwd_t *);
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pool_kernel_f32.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pool_kernel_f32.cpp
new file mode 100644
index 0000000000..bf8e609d23
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pool_kernel_f32.cpp
@@ -0,0 +1,699 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+* Copyright 2018 YANDEX LLC
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "utils.hpp"
+#include "cpu_pooling_pd.hpp"
+
+#include "jit_uni_pool_kernel_f32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace Xbyak;
+using namespace alg_kind;
+
+#define GET_OFF(field) offsetof(jit_pool_call_s, field)
+
+template <cpu_isa_t isa>
+status_t jit_uni_pool_kernel_f32<isa>::init_conf(jit_pool_conf_t &jpp,
+ const pooling_pd_t *ppd) {
+ const auto &pd = *ppd->desc();
+ const memory_desc_wrapper src_d(
+ ppd->is_fwd() ? ppd->src_md() : ppd->diff_src_md());
+ const memory_desc_wrapper dst_d(
+ ppd->is_fwd() ? ppd->dst_md() : ppd->diff_dst_md());
+
+ bool args_ok = true
+ && mayiuse(isa)
+ && utils::one_of(pd.alg_kind, pooling_max,
+ pooling_avg_include_padding,
+ pooling_avg_exclude_padding);
+ if (!args_ok) return status::unimplemented;
+
+ const int simd_w = isa == avx512_common ? 16 : 8;
+ const int ndims = src_d.ndims();
+
+ jpp.ndims = ndims;
+ jpp.mb = src_d.dims()[0];
+
+ jpp.c = utils::rnd_up(src_d.dims()[1], simd_w);
+ if (jpp.c > src_d.padded_dims()[1])
+ return status::unimplemented;
+
+ jpp.id = (ndims == 5) ? src_d.dims()[2] : 1;
+ jpp.ih = src_d.dims()[ndims-2];
+ jpp.iw = src_d.dims()[ndims-1];
+ jpp.od = (ndims == 5) ? dst_d.dims()[2] : 1;
+ jpp.oh = dst_d.dims()[ndims-2];
+ jpp.ow = dst_d.dims()[ndims-1];
+
+ jpp.stride_d = (ndims == 5 ) ? pd.strides[0] : 1;
+ jpp.stride_h = pd.strides[ndims-4];
+ jpp.stride_w = pd.strides[ndims-3];
+ jpp.kd = (ndims == 5) ? pd.kernel[0] : 1;
+ jpp.kh = pd.kernel[ndims-4];
+ jpp.kw = pd.kernel[ndims-3];
+
+ jpp.f_pad = (ndims == 5 ) ? pd.padding[0][0] : 0;
+ jpp.t_pad = pd.padding[0][ndims-4];
+ jpp.l_pad = pd.padding[0][ndims-3];
+
+ jpp.alg = pd.alg_kind;
+
+ jpp.is_training = pd.prop_kind == prop_kind::forward_training;
+ jpp.is_backward = pd.prop_kind == prop_kind::backward_data;
+ jpp.ind_dt = ppd->workspace_md()
+ ? ppd->workspace_md()->data_type : data_type::undef;
+
+ jpp.simple_alg = jpp.is_training
+ || IMPLICATION(jpp.is_backward, jpp.kd <= jpp.stride_d);
+
+ jpp.c_block = simd_w;
+
+ jpp.nb_c = jpp.c / jpp.c_block;
+ if (jpp.alg == pooling_max) {
+ jpp.ur_w = isa == avx512_common ? 16 : 4;
+ if (jpp.is_training)
+ jpp.ur_w = isa == avx512_common ? 9 : 3;
+ else if (jpp.is_backward)
+ jpp.ur_w = isa == avx512_common ? 6 : 3;
+ } else {
+ if (jpp.is_backward)
+ jpp.ur_w = isa == avx512_common ? 12 : 6;
+ else
+ jpp.ur_w = isa == avx512_common ? 24 : 12;
+ }
+ if (jpp.ow < jpp.ur_w) jpp.ur_w = jpp.ow;
+ if (jpp.l_pad > jpp.ur_w) return status::unimplemented;
+
+ jpp.ur_w_tail = jpp.ow % jpp.ur_w;
+
+ return status::success;
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_pool_kernel_f32<isa>::maybe_recalculate_divisor(int jj,
+ int ur_w, int pad_l, int pad_r) {
+ if (jpp.alg == pooling_avg_exclude_padding) {
+ int kw = jpp.kw;
+ int stride_w = jpp.stride_w;
+
+ int non_zero_kw = kw;
+ non_zero_kw -= nstl::max(0, pad_l - jj*stride_w);
+ non_zero_kw -= nstl::max(0, pad_r - (ur_w - 1 - jj)*stride_w);
+
+ if (non_zero_kw != prev_kw) {
+ mov(tmp_gpr, float2int((float)non_zero_kw));
+ movq(xmm_tmp, tmp_gpr);
+ uni_vbroadcastss(vmm_tmp, xmm_tmp);
+ uni_vmulps(vmm_tmp, vmm_tmp, vmm_ker_area_h);
+ prev_kw = non_zero_kw;
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_pool_kernel_f32<isa>::avg_step(int ur_w, int pad_l,
+ int pad_r) {
+
+ int iw = jpp.iw;
+ int kw = jpp.kw;
+ int stride_w = jpp.stride_w;
+ int c_block = jpp.c_block;
+ Label kd_label, kh_label;
+
+ for (int jj = 0; jj < ur_w; jj++) {
+ if (jpp.is_backward) {
+ uni_vmovups(vreg(jj), ptr[reg_output + sizeof(float)*jj*c_block]);
+ maybe_recalculate_divisor(jj, ur_w, pad_l, pad_r);
+ uni_vdivps(vreg(jj), vreg(jj), vmm_tmp);
+ } else {
+ uni_vpxor(vreg(jj), vreg(jj), vreg(jj));
+ }
+ }
+
+ if (jpp.simple_alg && jpp.ndims == 5) {
+ push(reg_input);
+ push(reg_output);
+ mov(aux_reg_input_d, reg_input);
+ mov(ki, ptr[reg_param + GET_OFF(kd_padding)]);
+ L(kd_label);
+ mov(aux_reg_input, aux_reg_input_d);
+ } else {
+ mov(aux_reg_input, reg_input);
+ }
+
+ xor_(kj, kj);
+ L(kh_label);
+ {
+ for (int ki = 0; ki < kw; ki++) {
+ int jj_start = nstl::max(0, pad_l - ki);
+ int jj_end = ur_w
+ - utils::div_up(nstl::max(0, ki + pad_r - (kw-1)), stride_w);
+ for (int jj = jj_start; jj < jj_end; jj++) {
+ int aux_input_offset = (ki+jj*stride_w-pad_l)* c_block;
+ if (aux_input_offset > iw * c_block)
+ continue;
+ int input_offset = sizeof(float)*aux_input_offset;
+ if (jpp.is_backward) {
+ uni_vmovups(vreg(ur_w+jj),
+ ptr[aux_reg_input + input_offset]);
+ uni_vaddps(vreg(ur_w+jj), vreg(ur_w+jj), vreg(jj));
+ uni_vmovups(vmmword[aux_reg_input + input_offset],
+ vreg(ur_w+jj));
+ } else {
+ uni_vaddps(vreg(jj), vreg(jj),
+ ptr[aux_reg_input + input_offset]);
+ }
+ }
+ }
+ add(aux_reg_input, sizeof(float) * iw * c_block);
+ inc(kj);
+ cmp(kj, reg_kh);
+ jl(kh_label, T_NEAR);
+ }
+
+ if (jpp.simple_alg && jpp.ndims == 5)
+ {
+ add(aux_reg_input_d, sizeof(float) * jpp.ih * iw * c_block);
+ dec(ki);
+ cmp(ki, 0);
+ jg(kd_label, T_NEAR);
+ pop(reg_output);
+ pop(reg_input);
+ }
+
+ if (!jpp.is_backward) {
+ for (int jj = 0; jj < ur_w; jj++) {
+ maybe_recalculate_divisor(jj, ur_w, pad_l, pad_r);
+ uni_vdivps(vreg(jj), vreg(jj), vmm_tmp);
+ uni_vmovups(vmmword[reg_output + sizeof(float)*jj*c_block],
+ vreg(jj));
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_pool_kernel_f32<isa>::max_step_fwd(int ur_w, int pad_l,
+ int pad_r) {
+ int iw = jpp.iw;
+ int kw = jpp.kw;
+ int stride_w = jpp.stride_w;
+ int c_block = jpp.c_block;
+ Label kd_label, kh_label;
+
+ mov(tmp_gpr, float2int(nstl::numeric_limits<float>::lowest()));
+ movq(xmm_tmp, tmp_gpr);
+ uni_vbroadcastss(vmm_tmp, xmm_tmp);
+
+ for (int jj = 0; jj < ur_w; jj++) {
+ uni_vmovups(vreg(jj), vmm_tmp);
+ if (jpp.is_training)
+ uni_vpxor(vreg(2*ur_w+jj), vreg(2*ur_w+jj), vreg(2*ur_w+jj));
+ }
+ if (jpp.is_training)
+ {
+ movq(xmm_tmp, reg_k_shift);
+ uni_vpbroadcastd(vmm_k_offset, xmm_tmp);
+ }
+
+ if (jpp.ndims == 5) {
+ push(reg_input);
+ push(reg_output);
+ mov(aux_reg_input_d, reg_input);
+ mov(ki, ptr[reg_param + GET_OFF(kd_padding)]);
+ L(kd_label);
+ mov(aux_reg_input, aux_reg_input_d);
+ } else {
+ mov(aux_reg_input, reg_input);
+ }
+ xor_(kj, kj);
+ L(kh_label);
+ {
+ for (int ki = 0; ki < kw; ki++) {
+ int jj_start = nstl::max(0, pad_l - ki);
+ int jj_end = ur_w
+ - utils::div_up(nstl::max(0, ki + pad_r - (kw-1)), stride_w);
+ for (int jj = jj_start; jj < jj_end; jj++) {
+ int aux_input_offset = (ki+jj*stride_w-pad_l)* c_block;
+ if (aux_input_offset > iw * c_block)
+ continue;
+ int input_offset = sizeof(float)*aux_input_offset;
+ uni_vmovups(vreg(ur_w+jj), ptr[aux_reg_input + input_offset]);
+ if (isa == sse42) {
+ movups(vmm_mask, vreg(jj));
+ cmpps(vmm_mask, vreg(ur_w+jj), _cmp_lt_os);
+ blendvps(vreg(jj), vreg(ur_w+jj));
+ if (jpp.is_training)
+ blendvps(vreg(2*ur_w+jj), vmm_k_offset);
+ } else if (isa == avx) {
+ vcmpps(vreg(3*ur_w+jj), vreg(jj), vreg(ur_w+jj),
+ _cmp_lt_os);
+ vblendvps(vreg(jj), vreg(jj), vreg(ur_w+jj),
+ vreg(3*ur_w+jj));
+ if (jpp.is_training)
+ vblendvps(vreg(2*ur_w+jj), vreg(2*ur_w+jj),
+ vmm_k_offset, vreg(3*ur_w+jj));
+ } else {
+ vcmpps(k_store_mask, vreg(jj), vreg(ur_w+jj), _cmp_lt_os);
+ vblendmps(vreg(jj) | k_store_mask, vreg(jj), vreg(ur_w+jj));
+ if (jpp.is_training)
+ vblendmps(vreg(2*ur_w+jj) | k_store_mask,
+ vreg(2*ur_w+jj), vmm_k_offset);
+ }
+ }
+ if (jpp.is_training) {
+ if (isa == avx && !mayiuse(avx2)) {
+ avx_vpadd1(vmm_k_offset, vmm_one, xmm_tmp);
+ } else {
+ uni_vpaddd(vmm_k_offset, vmm_k_offset, vmm_one);
+ }
+ }
+ }
+ add(aux_reg_input, sizeof(float) * iw * c_block);
+ inc(kj);
+ cmp(kj, reg_kh);
+ jl(kh_label, T_NEAR);
+ }
+
+ if (jpp.ndims == 5)
+ {
+ add(aux_reg_input_d, sizeof(float) * jpp.ih * iw * c_block);
+ if (jpp.is_training) {
+ mov(tmp_gpr, ptr[reg_param + GET_OFF(kd_padding_shift)]);
+ movq(xmm_tmp, tmp_gpr);
+ uni_vpbroadcastd(vmm_tmp, xmm_tmp);
+ if (isa == avx && !mayiuse(avx2)) {
+ Xmm t(vmm_mask.getIdx());
+ avx_vpadd1(vmm_k_offset, xmm_tmp, t);
+ } else {
+ uni_vpaddd(vmm_k_offset, vmm_k_offset, vmm_tmp);
+ }
+ }
+
+ dec(ki);
+ cmp(ki, 0);
+ jg(kd_label, T_NEAR);
+ pop(reg_output);
+ pop(reg_input);
+ }
+
+ for (int jj = 0; jj < ur_w; jj++) {
+ uni_vmovups(vmmword[reg_output + sizeof(float)*jj*c_block], vreg(jj));
+ if (jpp.is_training) {
+ const size_t step_index
+ = jj * c_block * types::data_type_size(jpp.ind_dt);
+
+ auto x = xreg(2 * ur_w + jj);
+ if (jpp.ind_dt == data_type::u8) {
+ if (isa == sse42) {
+ for (int i = 0; i < 4; ++i)
+ pextrb(ptr[reg_index + step_index + i], x, 4*i);
+ } else if (isa == avx) {
+ auto y = yreg(2 * ur_w + jj);
+ if (jj == 0) {
+ movd(xmm_tmp, reg_shuf_mask);
+ uni_vpbroadcastd(vmm_tmp, xmm_tmp);
+ }
+ if (mayiuse(avx2)) {
+ vpshufb(y, y, vmm_tmp);
+ movd(ptr[reg_index + step_index], x);
+ vperm2i128(y, y, y, 0x1u);
+ movd(ptr[reg_index + step_index + 4], x);
+ } else {
+ Xmm t(vmm_mask.getIdx());
+ vextractf128(t, y, 0);
+ vpshufb(t, t, xmm_tmp);
+ movd(ptr[reg_index + step_index], t);
+ vextractf128(t, y, 1);
+ vpshufb(t, t, xmm_tmp); // ymm_tmp[:128]==ymm_tmp[127:0]
+ movd(ptr[reg_index + step_index + 4], t);
+ }
+ } else {
+ auto v = vreg(2 * ur_w + jj);
+ vpmovusdb(x, v);
+ vmovups(ptr[reg_index + step_index], v | k_index_mask);
+ }
+ } else {
+ uni_vmovups(ptr[reg_index + step_index], vreg(2*ur_w+jj));
+ }
+ }
+ }
+}
+
+template <cpu_isa_t isa>
+inline void jit_uni_pool_kernel_f32<isa>::max_step_bwd(int ur_w, int pad_l,
+ int pad_r) {
+
+ int iw = jpp.iw;
+ int kw = jpp.kw;
+ int stride_w = jpp.stride_w;
+ int c_block = jpp.c_block;
+ Label kd_label, kh_label;
+
+ for (int jj = 0; jj < ur_w; jj++) {
+ uni_vmovups(vreg(jj), ptr[reg_output + sizeof(float)*jj*c_block]);
+
+ const size_t step_index
+ = jj * c_block * types::data_type_size(jpp.ind_dt);
+ if (jpp.ind_dt == data_type::u8) {
+ if (isa == sse42) {
+ movd(xreg(ur_w+jj), ptr[reg_index + step_index]);
+ pmovzxbd(vreg(ur_w+jj), xreg(ur_w+jj));
+ } else if (isa == avx) {
+ movq(xreg(ur_w+jj), ptr[reg_index + step_index]);
+ if (!mayiuse(avx2)) {
+ avx_pmovzxbd(vreg(ur_w+jj), xreg(ur_w+jj), xmm_tmp);
+ } else {
+ vpmovzxbd(vreg(ur_w+jj), xreg(ur_w+jj));
+ }
+ } else {
+ vmovups(vreg(ur_w+jj) | k_index_mask,
+ ptr[reg_index + step_index]);
+ vpmovzxbd(vreg(ur_w+jj), xreg(ur_w+jj));
+ }
+ } else {
+ uni_vmovups(vreg(ur_w+jj), ptr[reg_index + step_index]);
+ }
+ }
+ movq(xmm_tmp, reg_k_shift);
+ uni_vpbroadcastd(vmm_k_offset, xmm_tmp);
+
+ if (jpp.simple_alg && jpp.ndims == 5) {
+ push(reg_input);
+ push(reg_output);
+ if (isa == sse42) {
+ // Save rdi since it is used in maskmovdqu
+ assert(dst_ptr == rdi);
+ push(dst_ptr);
+ }
+ mov(aux_reg_input_d, reg_input);
+ mov(ki, ptr[reg_param + GET_OFF(kd_padding)]);
+ mov(reg_kd_pad_shift, ptr[reg_param + GET_OFF(kd_padding_shift)]);
+ L(kd_label);
+ mov(aux_reg_input, aux_reg_input_d);
+ } else {
+ mov(aux_reg_input, reg_input);
+ }
+
+ xor_(kj, kj);
+ L(kh_label);
+ {
+ for (int ki = 0; ki < kw; ki++) {
+ int jj_start = nstl::max(0, pad_l - ki);
+ int jj_end = ur_w
+ - utils::div_up(nstl::max(0, ki + pad_r - (kw-1)), stride_w);
+ for (int jj = jj_start; jj < jj_end; jj++) {
+ int aux_input_offset = (ki+jj*stride_w-pad_l)* c_block;
+ if (aux_input_offset > iw * c_block)
+ continue;
+ int input_offset = sizeof(float)*aux_input_offset;
+ uni_vmovups(vreg(2*ur_w+jj), ptr[aux_reg_input + input_offset]);
+ if (isa == sse42) {
+ mov(dst_ptr, aux_reg_input);
+ add(dst_ptr, input_offset);
+
+ movups(vreg(3*ur_w+jj), vreg(ur_w+jj));
+ pcmpeqd(vreg(3*ur_w+jj), vmm_k_offset);
+ addps(vreg(2*ur_w+jj), vreg(jj));
+ maskmovdqu(vreg(2*ur_w+jj), vreg(3*ur_w+jj));
+ } else if (isa == avx) {
+ if (mayiuse(avx2)) {
+ vpcmpeqd(vreg(3*ur_w+jj), vreg(ur_w+jj), vmm_k_offset);
+ } else {
+ avx_pcmpeqd(vreg(3*ur_w+jj), vreg(ur_w+jj), vmm_k_offset, xmm_tmp);
+ }
+ vaddps(vreg(2*ur_w+jj), vreg(2*ur_w+jj), vreg(jj));
+ vmaskmovps(vmmword[aux_reg_input + input_offset],
+ vreg(3*ur_w+jj), vreg(2*ur_w+jj));
+ } else {
+ vpcmpeqd(k_store_mask, vreg(ur_w+jj), vmm_k_offset);
+ vblendmps(vmm_tmp | k_store_mask | T_z, vreg(jj), vreg(jj));
+ vaddps(vreg(2*ur_w+jj), vreg(2*ur_w+jj), vmm_tmp);
+ vmovups(vmmword[aux_reg_input +
+ sizeof(float)*aux_input_offset], vreg(2*ur_w+jj));
+ }
+ }
+ if (isa == avx && !mayiuse(avx2)) {
+ avx_vpadd1(vmm_k_offset, vmm_one, xmm_tmp);
+ } else {
+ uni_vpaddd(vmm_k_offset, vmm_k_offset, vmm_one);
+ }
+ }
+ add(aux_reg_input, sizeof(float) * iw * c_block);
+ inc(kj);
+ cmp(kj, reg_kh);
+ jl(kh_label, T_NEAR);
+ }
+ if (jpp.simple_alg && jpp.ndims == 5)
+ {
+ add(aux_reg_input_d, sizeof(float) * jpp.ih * iw * c_block);
+
+ mov(tmp_gpr, reg_kd_pad_shift);
+ movq(xmm_tmp, tmp_gpr);
+ uni_vpbroadcastd(vmm_tmp, xmm_tmp);
+ if (isa == avx && !mayiuse(avx2)) {
+ Xmm t(vmm_mask.getIdx());
+ avx_vpadd1(vmm_k_offset, vmm_tmp, t);
+ } else {
+ uni_vpaddd(vmm_k_offset, vmm_k_offset, vmm_tmp);
+ }
+
+ dec(ki);
+ cmp(ki, 0);
+ jg(kd_label, T_NEAR);
+ if (isa == sse42) {
+ // Save rdi since it is used in maskmovdqu
+ assert(dst_ptr == rdi);
+ pop(dst_ptr);
+ }
+ pop(reg_output);
+ pop(reg_input);
+ }
+}
+
+template <cpu_isa_t isa>
+void jit_uni_pool_kernel_f32<isa>::maybe_zero_diff_src() {
+ assert(jpp.c_block * sizeof(float) % cpu_isa_traits<isa>::vlen == 0);
+ Label l_skip, l_zero;
+
+ auto reg_oh = tmp_gpr;
+ mov(reg_oh, ptr[reg_param + GET_OFF(oh)]);
+ cmp(reg_oh, 0);
+ jz(l_skip, T_NEAR);
+
+ if (jpp.ndims == 5) {
+ mov(zero_size, ptr[reg_param + GET_OFF(oh)]);
+ mov(tmp_gpr, jpp.ih * jpp.iw * jpp.c_block * sizeof(float));
+ imul(zero_size, tmp_gpr);
+ }
+
+ auto vzero = vmm_tmp;
+ uni_vpxor(vzero, vzero, vzero);
+
+ auto reg_off = tmp_gpr;
+ xor_(reg_off, reg_off);
+
+ L(l_zero);
+ {
+ const int dim = jpp.iw * jpp.c_block * sizeof(float);
+ for (int i = 0; i < dim; i += cpu_isa_traits<isa>::vlen)
+ uni_vmovups(ptr[reg_input + reg_off + i], vzero);
+ add(reg_off, dim);
+ if (jpp.ndims == 5) cmp(reg_off, zero_size);
+ else cmp(reg_off, jpp.ih * dim);
+ jl(l_zero, T_NEAR);
+ }
+
+ L(l_skip);
+}
+
+template <cpu_isa_t isa>
+void jit_uni_pool_kernel_f32<isa>::generate() {
+
+ this->preamble();
+
+ int ow = jpp.ow;
+ int iw = jpp.iw;
+ int kw = jpp.kw;
+ int kh = jpp.kh;
+ int ur_w = jpp.ur_w;
+ int c_block = jpp.c_block;
+ int stride_w = jpp.stride_w;
+ int l_pad = jpp.l_pad;
+ int ur_w_tail = jpp.ur_w_tail;
+
+ int n_oi = ow / ur_w;
+
+ prev_kw = 0;
+
+ int vlen = cpu_isa_traits<isa>::vlen;
+
+#if defined(_WIN32)
+ // Always mimic the Unix ABI (see the note about maskmovdqu in the header
+ // file).
+ xor_(rdi, rcx);
+ xor_(rcx, rdi);
+ xor_(rdi, rcx);
+#endif
+
+ mov(reg_input, ptr[reg_param + GET_OFF(src)]);
+ mov(reg_output, ptr[reg_param + GET_OFF(dst)]);
+ if (jpp.alg == pooling_max && (jpp.is_training || jpp.is_backward))
+ mov(reg_index, ptr[reg_param + GET_OFF(indices)]);
+ mov(reg_kh, ptr[reg_param + GET_OFF(kh_padding)]);
+ mov(reg_k_shift, ptr[reg_param + GET_OFF(kh_padding_shift)]);
+ mov(reg_ker_area_h, ptr[reg_param + GET_OFF(ker_area_h)]);
+
+ if (jpp.is_backward)
+ maybe_zero_diff_src();
+
+ if (jpp.alg == pooling_max && (jpp.is_training || jpp.is_backward)) {
+ mov(tmp_gpr, 1);
+ movq(xmm_one, tmp_gpr);
+ uni_vpbroadcastd(vmm_one, xmm_one);
+
+ if (isa == avx) {
+ mov(reg_shuf_mask, 0x0c080400);
+ } else if (isa >= avx512_common) {
+ mov(tmp_gpr.cvt32(), 0x000f);
+ kmovw(k_index_mask, tmp_gpr.cvt32());
+ }
+ }
+
+ int r_pad = nstl::max(0, ((ow-1)*stride_w) + kw - 1 - (iw + l_pad - 1));
+ int r_pad1 = (ur_w*n_oi - 1)*stride_w + kw - 1 - (iw + l_pad - 1);
+ if (r_pad1 > 0) n_oi--;
+
+ if (jpp.alg == pooling_avg_exclude_padding) {
+ movq(xmm_ker_area_h, reg_ker_area_h);
+ uni_vpbroadcastd(vmm_ker_area_h, xmm_ker_area_h);
+ }
+
+ if (jpp.alg == pooling_avg_include_padding) {
+ mov(tmp_gpr, float2int((float)(kw * kh * jpp.kd)));
+ movq(xmm_tmp, tmp_gpr);
+ uni_vpbroadcastd(vmm_tmp, xmm_tmp);
+ }
+ if (l_pad > 0) {
+ n_oi--;
+ if (n_oi < 0 && r_pad1 > 0) {
+ step(ur_w, l_pad, r_pad1);
+ } else {
+ step(ur_w, l_pad, 0);
+ }
+
+ if (isa == sse42) {
+ if (n_oi < 0 && r_pad1 > 0) {
+ step_high_half(ur_w, l_pad, r_pad1);
+ } else {
+ step_high_half(ur_w, l_pad, 0);
+ }
+ }
+
+ if (isa == sse42) {
+ add(reg_input, sizeof(float)*(ur_w*stride_w-l_pad)*c_block - vlen);
+ add(reg_output, sizeof(float)*ur_w*c_block - vlen);
+ if (jpp.alg == pooling_max && (jpp.is_training || jpp.is_backward))
+ add(reg_index, (2 * ur_w - 1) * c_block / 2
+ * types::data_type_size(jpp.ind_dt));
+ } else {
+ add(reg_input, sizeof(float)*(ur_w*stride_w - l_pad)*c_block);
+ add(reg_output, sizeof(float)*ur_w*c_block);
+ if (jpp.alg == pooling_max && (jpp.is_training || jpp.is_backward))
+ add(reg_index, ur_w * c_block
+ * types::data_type_size(jpp.ind_dt));
+ }
+ }
+
+ xor_(oi_iter, oi_iter);
+ if (n_oi > 0) {
+ Label ow_loop;
+ L(ow_loop); {
+ step(ur_w, 0, 0);
+
+ if (isa == sse42) {
+ step_high_half(ur_w, 0, 0);
+ }
+
+ if (isa == sse42) {
+ add(reg_input, sizeof(float)*ur_w*stride_w*c_block - vlen);
+ add(reg_output, sizeof(float)*ur_w*c_block - vlen);
+ if (jpp.alg == pooling_max &&
+ (jpp.is_training || jpp.is_backward))
+ add(reg_index, (2 * ur_w - 1) * c_block / 2
+ * types::data_type_size(jpp.ind_dt));
+ } else {
+ add(reg_input, sizeof(float)*ur_w*stride_w*c_block);
+ add(reg_output, sizeof(float)*ur_w*c_block);
+ if (jpp.alg == pooling_max &&
+ (jpp.is_training || jpp.is_backward))
+ add(reg_index, ur_w * c_block
+ * types::data_type_size(jpp.ind_dt));
+ }
+
+ inc(oi_iter);
+ cmp(oi_iter, n_oi);
+ jl(ow_loop, T_NEAR);
+ }
+ }
+
+ if (r_pad1 > 0 && n_oi >= 0) {
+ step(ur_w, 0, r_pad1);
+
+ if (isa == sse42) {
+ step_high_half(ur_w, 0, r_pad1);
+ }
+
+ if (isa == sse42) {
+ add(reg_input, sizeof(float)*ur_w*stride_w*c_block - vlen);
+ add(reg_output, sizeof(float)*ur_w*c_block - vlen);
+ if (jpp.alg == pooling_max && (jpp.is_training || jpp.is_backward))
+ add(reg_index, (2 * ur_w - 1) * c_block / 2
+ * types::data_type_size(jpp.ind_dt));
+ } else {
+ add(reg_input, sizeof(float)*ur_w*stride_w*c_block);
+ add(reg_output, sizeof(float)*ur_w*c_block);
+ if (jpp.alg == pooling_max && (jpp.is_training || jpp.is_backward))
+ add(reg_index, ur_w * c_block
+ * types::data_type_size(jpp.ind_dt));
+ }
+ }
+
+ if (ur_w_tail != 0) {
+ step(ur_w_tail, 0, r_pad);
+
+ if (isa == sse42) {
+ step_high_half(ur_w_tail, 0, r_pad);
+ }
+ }
+
+ this->postamble();
+}
+
+template struct jit_uni_pool_kernel_f32<sse42>;
+template struct jit_uni_pool_kernel_f32<avx>; // implements both <avx> and <avx2>
+template struct jit_uni_pool_kernel_f32<avx512_common>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pool_kernel_f32.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pool_kernel_f32.hpp
new file mode 100644
index 0000000000..992b526587
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pool_kernel_f32.hpp
@@ -0,0 +1,192 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+* Copyright 2018 YANDEX LLC
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_UNI_POOL_KERNEL_F32_HPP
+#define JIT_UNI_POOL_KERNEL_F32_HPP
+
+#include <cfloat>
+
+#include "c_types_map.hpp"
+#include "pooling_pd.hpp"
+#include "type_helpers.hpp"
+
+#include "jit_generator.hpp"
+#include "jit_primitive_conf.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace Xbyak;
+
+template <cpu_isa_t isa>
+struct jit_uni_pool_kernel_f32: public jit_generator {
+ jit_uni_pool_kernel_f32(jit_pool_conf_t ajpp): jpp(ajpp)
+ {
+ this->generate();
+ jit_ker = (decltype(jit_ker))this->getCode();
+ }
+
+ jit_pool_conf_t jpp;
+
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_uni_pool_kernel_f32)
+
+ void operator()(jit_pool_call_s *arg) { jit_ker(arg); }
+ static status_t init_conf(jit_pool_conf_t &jbp, const pooling_pd_t *ppd);
+
+private:
+ using Vmm = typename utils::conditional3<isa == sse42, Xmm, isa == avx,
+ Ymm, Zmm>::type;
+ Xmm xreg(int idx) { return Xmm((isa == avx512_common ? 31 : 15) - idx); }
+ Ymm yreg(int idx) { return Ymm(xreg(idx).getIdx()); }
+ Vmm vreg(int idx) { return Vmm(xreg(idx).getIdx()); }
+
+ const AddressFrame &vmmword = (isa == sse42) ? xword :
+ (isa == avx) ? yword : zword;
+
+ Xmm vmm_mask = Xmm(0);
+ Xmm xmm_ker_area_h = Xmm(2);
+ Xmm xmm_one = Xmm(2);
+ Xmm xmm_tmp = Xmm(3);
+
+ Vmm vmm_ker_area_h = Vmm(2);
+ Vmm vmm_one = Vmm(2);
+ Vmm vmm_tmp = Vmm(3);
+
+ Vmm vmm_k_offset = Vmm(1);
+
+ Opmask k_index_mask = Opmask(6);
+ Opmask k_store_mask = Opmask(7);
+
+ // Here be some (tame) dragons. This kernel does not follow the regular
+ // OS-agnostic ABI pattern because when isa is sse42 it uses maskmovdqu
+ // instruction which has its destination hardcoded in rdi. Therefore:
+ // - all registers are hardcoded
+ // - on Windows rdi and rcx are swapped to mimic the Unix x86_64 ABI
+ //
+ // While this is only required by the backward pass, the quirk above
+ // is applied to the forward pass as well to keep things simpler.
+
+ using reg64_t = const Xbyak::Reg64;
+ reg64_t reg_param = rdi; // Always mimic the Unix ABI
+ reg64_t reg_input = r8;
+ reg64_t aux_reg_input = r9;
+ reg64_t reg_index = r10;
+ reg64_t reg_output = r12;
+ reg64_t reg_kd_pad_shift = r13;
+ reg64_t dst_ptr = rdi; // Must be rdi due to maskmovdqu
+
+ reg64_t kj = r14;
+ reg64_t oi_iter = r15;
+ reg64_t reg_kh = rax;
+ reg64_t reg_k_shift = rbx;
+ reg64_t tmp_gpr = rcx; // Must be rcx because rdi is used above
+ reg64_t reg_ker_area_h = rdx;
+
+ reg64_t zero_size = r15;
+ reg64_t ki = r12;
+ reg64_t aux_reg_input_d = r8;
+
+ Xbyak::Reg32 reg_shuf_mask = esi;
+
+ int prev_kw;
+ void (*jit_ker)(jit_pool_call_s *);
+
+ void maybe_recalculate_divisor(int jj, int ur_w, int pad_l, int pad_r);
+ void avg_step(int ur_w, int pad_l, int pad_r);
+ void max_step_fwd(int ur_w, int pad_l, int pad_r);
+ void max_step_bwd(int ur_w, int pad_l, int pad_r);
+
+ void maybe_zero_diff_src();
+
+ void step(int ur_w, int pad_l, int pad_r) {
+ if (jpp.alg == alg_kind::pooling_max) {
+ if(jpp.is_backward)
+ max_step_bwd(ur_w, pad_l, pad_r);
+ else
+ max_step_fwd(ur_w, pad_l, pad_r);
+ }
+ else
+ avg_step(ur_w, pad_l, pad_r);
+ }
+
+ void step_high_half(int ur_w, int pad_l, int pad_r) {
+ add(reg_input, sizeof(float) * 4);
+ add(reg_output, sizeof(float) * 4);
+ if (jpp.alg == alg_kind::pooling_max &&
+ (jpp.is_training || jpp.is_backward))
+ add(reg_index, types::data_type_size(jpp.ind_dt) * 4);
+
+ step(ur_w, pad_l, pad_r);
+ }
+
+ void generate();
+
+ void avx_vpadd1(const Ymm& y0, const Xmm& x1, const Xmm& xtmp) {
+ assert(y0.getIdx() != x1.getIdx());
+ vextractf128(xtmp, y0, 0);
+ vpaddd(xtmp, xtmp, x1);
+ vinsertf128(y0, y0, xtmp, 0);
+ vextractf128(xtmp, y0, 1);
+ vpaddd(xtmp, xtmp, x1);
+ vinsertf128(y0, y0, xtmp, 1);
+ }
+
+ void avx_vpadd1(const Xmm& x0, const Xmm& x1, const Xmm&) {
+ assert(false /*function should not be used*/);
+ paddd(x0, x1);
+ }
+
+ void avx_pmovzxbd(const Ymm& y0, const Xmm& x1, const Xmm& xtmp) {
+ Xmm x0(y0.getIdx());
+ pshufd(xmm_tmp, x1, 1);
+ pmovzxbd(x0, x1);
+ pmovzxbd(xmm_tmp, xmm_tmp);
+ vinsertf128(y0, y0, xmm_tmp, 1);
+ }
+
+ void avx_pmovzxbd(const Xmm& x0, const Xmm& x1, const Xmm&) {
+ assert(false /*function should not be used*/);
+ pmovzxbd(x0, x1);
+ }
+
+ void avx_pcmpeqd(const Ymm& y0, const Ymm& y1, const Ymm& y2, const Xmm& xtmp) {
+ assert(y0.getIdx() != y1.getIdx());
+ assert(y0.getIdx() != y2.getIdx());
+ Xmm x0(y0.getIdx());
+ Xmm x2(y2.getIdx());
+ vextractf128(x0, y1, 1);
+ vextractf128(xtmp, y2, 1);
+ pcmpeqd(xtmp, x0);
+ vextractf128(x0, y1, 0);
+ pcmpeqd(x0, x2);
+ vinsertf128(y0, y0, xtmp, 1);
+ }
+
+ void avx_pcmpeqd(const Xmm& x0, const Xmm& x1, const Xmm&, const Xmm&) {
+ assert(false /*function should not be used*/);
+ pcmpeqd(x0, x1);
+ }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pooling.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pooling.cpp
new file mode 100644
index 0000000000..afbcf996d8
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pooling.cpp
@@ -0,0 +1,264 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn_types.h"
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "nstl.hpp"
+
+#include "jit_uni_pooling.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <cpu_isa_t isa>
+void jit_uni_pooling_fwd_t<isa>::execute_forward(const data_t *src,
+ data_t *dst, char *indices) const {
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper indices_d(pd()->workspace_md());
+ const size_t ind_dt_size = indices
+ ? types::data_type_size(indices_d.data_type()) : 0;
+
+ const auto &jpp = pd()->jpp_;
+
+ auto ker = [&](int n, int b_c, int oh) {
+ auto arg = jit_pool_call_s();
+
+ const int ij = oh * jpp.stride_h;
+ const int i_t_overflow = nstl::max(0, jpp.t_pad-ij);
+ const int i_b_overflow = nstl::max(jpp.ih, ij+jpp.kh-jpp.t_pad)-jpp.ih;
+ const int ih = nstl::max(ij - jpp.t_pad, 0);
+
+ arg.src = &src[src_d.blk_off(n, b_c, ih)];
+ arg.dst = &dst[dst_d.blk_off(n, b_c, oh)];
+ if (indices) {
+ const size_t ind_off = indices_d.blk_off(n, b_c, oh);
+ arg.indices = &indices[ind_off * ind_dt_size];
+ }
+ arg.oh = oh == 0;
+ arg.kh_padding = jpp.kh - i_t_overflow - i_b_overflow;
+ arg.kh_padding_shift = i_t_overflow*jpp.kw;
+ arg.kw_padding = 0;
+ arg.ker_area_h = (float)(jpp.kh -
+ nstl::max(0, oh*jpp.stride_h - jpp.t_pad + jpp.kh - jpp.ih) -
+ nstl::max(0, jpp.t_pad - oh*jpp.stride_h));
+ (*kernel_)(&arg);
+ };
+
+ parallel_nd(jpp.mb, jpp.nb_c, jpp.oh,
+ [&](int n, int b_c, int oh) {
+ ker(n, b_c, oh);
+ });
+}
+
+template <cpu_isa_t isa>
+void jit_uni_pooling_fwd_t<isa>::execute_forward_3d(const data_t *src,
+ data_t *dst, char *indices) const {
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper indices_d(pd()->workspace_md());
+ const size_t ind_dt_size = indices
+ ? types::data_type_size(indices_d.data_type()) : 0;
+
+ const auto &jpp = pd()->jpp_;
+
+ auto ker = [&](int n, int b_c, int od, int oh, int id, int d_t_overflow,
+ int d_b_overflow) {
+ auto arg = jit_pool_call_s();
+
+ const int ij = oh * jpp.stride_h;
+ const int i_t_overflow = nstl::max(0, jpp.t_pad-ij);
+ const int i_b_overflow = nstl::max(jpp.ih, ij+jpp.kh-jpp.t_pad)-jpp.ih;
+ const int ih = nstl::max(ij - jpp.t_pad, 0);
+
+ arg.src = &src[src_d.blk_off(n, b_c, id, ih)];
+ arg.dst = &dst[dst_d.blk_off(n, b_c, od, oh)];
+ if (indices) {
+ const size_t ind_off = indices_d.blk_off(n, b_c, od, oh);
+ arg.indices = &indices[ind_off * ind_dt_size];
+ }
+ arg.oh = (oh + od == 0);
+ arg.kd_padding = jpp.kd - d_t_overflow - d_b_overflow;
+ arg.kh_padding = jpp.kh - i_t_overflow - i_b_overflow;
+ arg.kh_padding_shift = i_t_overflow*jpp.kw + d_t_overflow*jpp.kw*jpp.kh;
+ arg.kd_padding_shift = (i_t_overflow + i_b_overflow)*jpp.kw;
+ arg.kw_padding = 0;
+ arg.ker_area_h = (float)(jpp.kh -
+ nstl::max(0, oh*jpp.stride_h - jpp.t_pad + jpp.kh - jpp.ih) -
+ nstl::max(0, jpp.t_pad - oh*jpp.stride_h)) * (jpp.kd -
+ nstl::max(0, od*jpp.stride_d - jpp.f_pad + jpp.kd - jpp.id) -
+ nstl::max(0, jpp.f_pad - od*jpp.stride_d));
+
+
+ (*kernel_)(&arg);
+ };
+
+ parallel_nd(jpp.mb, jpp.nb_c, jpp.od,
+ [&](int n, int b_c, int od) {
+ const int ik = od * jpp.stride_d;
+ const int d_t_overflow = nstl::max(0, jpp.f_pad-ik);
+ const int d_b_overflow = nstl::max(jpp.id, ik+jpp.kd-jpp.f_pad)
+ -jpp.id;
+ const int id = nstl::max(ik - jpp.f_pad, 0);
+ for (int oh = 0; oh < jpp.oh; ++oh) {
+ ker(n, b_c, od, oh, id, d_t_overflow, d_b_overflow);
+ }
+ });
+}
+
+template <cpu_isa_t isa>
+void jit_uni_pooling_bwd_t<isa>::execute_backward(const data_t *diff_dst,
+ const char *indices, data_t *diff_src) const {
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper indices_d(pd()->workspace_md());
+ const size_t ind_dt_size = indices
+ ? types::data_type_size(indices_d.data_type()) : 0;
+
+ const auto &jpp = pd()->jpp_;
+
+ auto ker = [&](int n, int b_c, int oh) {
+ auto arg = jit_pool_call_s();
+
+ const int ij = oh * jpp.stride_h;
+ const int i_t_overflow = nstl::max(0, jpp.t_pad-ij);
+ const int i_b_overflow = nstl::max(jpp.ih, ij+jpp.kh-jpp.t_pad)-jpp.ih;
+ const int ih = nstl::max(ij - jpp.t_pad, 0);
+
+ arg.src = &diff_src[diff_src_d.blk_off(n, b_c, ih)];
+ arg.dst = &diff_dst[diff_dst_d.blk_off(n, b_c, oh)];
+ if (indices) {
+ const size_t ind_off = indices_d.blk_off(n, b_c, oh);
+ arg.indices = &indices[ind_off * ind_dt_size];
+ }
+ arg.oh = (oh == 0);
+ arg.kh_padding = jpp.kh - i_t_overflow - i_b_overflow;
+ arg.kh_padding_shift = i_t_overflow*jpp.kw;
+ arg.kw_padding = 0;
+ arg.ker_area_h = (float)(jpp.kh -
+ nstl::max(0, oh*jpp.stride_h - jpp.t_pad + jpp.kh - jpp.ih) -
+ nstl::max(0, jpp.t_pad - oh*jpp.stride_h));
+
+ (*kernel_)(&arg);
+ };
+
+ parallel_nd(jpp.mb, jpp.nb_c, [&](int n, int b_c) {
+ for (int oh = 0; oh < jpp.oh; ++oh) {
+ ker(n, b_c, oh);
+ }
+ });
+}
+
+template <cpu_isa_t isa>
+void jit_uni_pooling_bwd_t<isa>::execute_backward_3d(const data_t *diff_dst,
+ const char *indices, data_t *diff_src) const {
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper indices_d(pd()->workspace_md());
+ const size_t ind_dt_size = indices
+ ? types::data_type_size(indices_d.data_type()) : 0;
+
+ const auto &jpp = pd()->jpp_;
+
+ auto ker = [&](int n, int b_c, int od, int oh, int id, int d_t_overflow,
+ int d_b_overflow, int zero_size, int kd) {
+ auto arg = jit_pool_call_s();
+
+ const int ij = oh * jpp.stride_h;
+ const int i_t_overflow = nstl::max(0, jpp.t_pad-ij);
+ const int i_b_overflow = nstl::max(jpp.ih, ij+jpp.kh-jpp.t_pad)-jpp.ih;
+ const int ih = nstl::max(ij - jpp.t_pad, 0);
+
+ arg.src = &diff_src[diff_src_d.blk_off(n, b_c, id + kd, ih)];
+ arg.dst = &diff_dst[diff_dst_d.blk_off(n, b_c, od, oh)];
+ if (indices) {
+ const size_t ind_off = indices_d.blk_off(n, b_c, od, oh);
+ arg.indices = &indices[ind_off * ind_dt_size];
+ }
+ arg.oh = zero_size;
+ arg.kd_padding = jpp.kd - d_t_overflow - d_b_overflow;
+ arg.kh_padding = jpp.kh - i_t_overflow - i_b_overflow;
+ arg.kh_padding_shift = i_t_overflow*jpp.kw + d_t_overflow*jpp.kw*jpp.kh
+ + kd * jpp.kw * jpp.kh;
+ arg.kd_padding_shift = (i_t_overflow + i_b_overflow)*jpp.kw;
+ arg.kw_padding = 0;
+ arg.ker_area_h = (float)(jpp.kh -
+ nstl::max(0, oh*jpp.stride_h - jpp.t_pad + jpp.kh - jpp.ih) -
+ nstl::max(0, jpp.t_pad - oh*jpp.stride_h)) * (jpp.kd -
+ nstl::max(0, od*jpp.stride_d - jpp.f_pad + jpp.kd - jpp.id) -
+ nstl::max(0, jpp.f_pad - od*jpp.stride_d));
+
+ (*kernel_)(&arg);
+ };
+
+ if (jpp.simple_alg) {
+
+ parallel_nd(jpp.mb, jpp.nb_c, jpp.od,
+ [&](int n, int b_c, int od) {
+ const int ik = od * jpp.stride_d;
+ const int d_t_overflow = nstl::max(0, jpp.f_pad - ik);
+ const int d_b_overflow = nstl::max(jpp.id, ik + jpp.kd
+ - jpp.f_pad) - jpp.id;
+ const int id = nstl::max(ik - jpp.f_pad, 0);
+ int zero_s = jpp.stride_d - d_t_overflow - (nstl::max(
+ jpp.id, ik + jpp.stride_d - jpp.f_pad) - jpp.id);
+ for (int oh = 0; oh < jpp.oh; ++oh) {
+ ker(n, b_c, od, oh, id, d_t_overflow, d_b_overflow,
+ (oh == 0) ? zero_s : 0, 0);
+ }
+ });
+ } else {
+ ptrdiff_t nelems = (ptrdiff_t)jpp.mb * (ptrdiff_t)jpp.c
+ * (ptrdiff_t)jpp.id * (ptrdiff_t)jpp.ih * (ptrdiff_t)jpp.iw;
+
+ parallel_nd(nelems, [&](ptrdiff_t i) { diff_src[i] = 0.f; });
+
+ for (int kd = 0; kd < jpp.kd; ++kd) {
+ parallel_nd(jpp.mb, jpp.nb_c, [&](int n, int b_c) {
+ for (int od = 0; od < jpp.od; ++od) {
+ const int ik = od * jpp.stride_d;
+ const int d_t_overflow = nstl::max(0, jpp.f_pad-ik);
+ const int d_b_overflow = nstl::max(jpp.id, ik + jpp.kd
+ - jpp.f_pad) - jpp.id;
+ if (kd >= jpp.kd - d_t_overflow - d_b_overflow)
+ continue;
+ const int id = nstl::max(ik - jpp.f_pad, 0);
+ for (int oh = 0; oh < jpp.oh; ++oh) {
+ ker(n, b_c, od, oh, id, d_t_overflow, d_b_overflow,
+ 0, kd);
+ }
+ }
+ });
+ }
+ }
+}
+
+
+template struct jit_uni_pooling_fwd_t<sse42>;
+template struct jit_uni_pooling_bwd_t<sse42>;
+template struct jit_uni_pooling_fwd_t<avx>;
+template struct jit_uni_pooling_bwd_t<avx>;
+template struct jit_uni_pooling_fwd_t<avx512_common>;
+template struct jit_uni_pooling_bwd_t<avx512_common>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pooling.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pooling.hpp
new file mode 100644
index 0000000000..57bebacdee
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_pooling.hpp
@@ -0,0 +1,182 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_JIT_UNI_POOLING_HPP
+#define CPU_JIT_UNI_POOLING_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_pooling_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "jit_uni_pool_kernel_f32.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <cpu_isa_t isa>
+struct jit_uni_pooling_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_pooling_fwd_pd_t {
+ using cpu_pooling_fwd_pd_t::cpu_pooling_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", isa, ""),
+ jit_uni_pooling_fwd_t<isa>);
+
+ status_t init() {
+ using namespace utils;
+
+ bool ok = true
+ && set_default_params() == status::success
+ && is_fwd()
+ && !has_zero_dim_memory()
+ && everyone_is(data_type::f32,
+ src_md()->data_type,
+ dst_md()->data_type)
+ && attr()->has_default_values()
+ && memory_desc_matches_tag(*src_md(), desired_fmt_tag())
+ && memory_desc_matches_tag(*dst_md(), desired_fmt_tag());
+ if (!ok) return status::unimplemented;
+
+ bool is_training = desc_.prop_kind == prop_kind::forward_training;
+ if (desc()->alg_kind == alg_kind::pooling_max && is_training)
+ init_default_ws();
+
+ return jit_uni_pool_kernel_f32<isa>::init_conf(jpp_, this);
+ }
+
+ format_tag_t desired_fmt_tag() {
+ using namespace format_tag;
+ return ndims() == 4
+ ? isa == avx512_common ? nChw16c : nChw8c
+ : isa == avx512_common ? nCdhw16c : nCdhw8c;
+ }
+
+ jit_pool_conf_t jpp_;
+ };
+
+ jit_uni_pooling_fwd_t(const pd_t *apd): cpu_primitive_t(apd)
+ { kernel_ = new jit_uni_pool_kernel_f32<isa>(pd()->jpp_); }
+
+ ~jit_uni_pooling_fwd_t() { delete kernel_; }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+ auto ws = CTX_OUT_MEM(char *, MKLDNN_ARG_WORKSPACE);
+
+ if (pd()->ndims() == 5)
+ execute_forward_3d(src, dst, ws);
+ else
+ execute_forward(src, dst, ws);
+
+ return status::success;
+ }
+
+private:
+ void execute_forward(const data_t *src, data_t *dst, char *indices) const;
+ void execute_forward_3d(const data_t *src, data_t *dst,
+ char *indices) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ jit_uni_pool_kernel_f32<isa> *kernel_;
+};
+
+template <cpu_isa_t isa>
+struct jit_uni_pooling_bwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_pooling_bwd_pd_t {
+ using cpu_pooling_bwd_pd_t::cpu_pooling_bwd_pd_t;
+
+ DECLARE_COMMON_PD_T(
+ JIT_IMPL_NAME_HELPER("jit:", isa, ""),
+ jit_uni_pooling_bwd_t<isa>);
+
+ status_t init() {
+ using namespace utils;
+
+ bool ok = true
+ && set_default_params() == status::success
+ && !is_fwd()
+ && !has_zero_dim_memory()
+ && everyone_is(data_type::f32,
+ diff_src_md()->data_type,
+ diff_dst_md()->data_type)
+ && attr()->has_default_values()
+ && memory_desc_matches_tag(*diff_dst_md(), desired_fmt_tag())
+ && memory_desc_matches_tag(*diff_src_md(), desired_fmt_tag());
+ if (!ok) return status::unimplemented;
+
+ if (desc()->alg_kind == alg_kind::pooling_max) {
+ init_default_ws();
+ if (!compare_ws(hint_fwd_pd_))
+ return status::unimplemented;
+ }
+
+ return jit_uni_pool_kernel_f32<isa>::init_conf(jpp_, this);
+ }
+
+ format_tag_t desired_fmt_tag() {
+ using namespace format_tag;
+ return ndims()
+ ? isa == avx512_common ? nChw16c : nChw8c
+ : isa == avx512_common ? nCdhw16c : nCdhw8c;
+ }
+
+ jit_pool_conf_t jpp_;
+ };
+
+ jit_uni_pooling_bwd_t(const pd_t *apd): cpu_primitive_t(apd)
+ { kernel_ = new jit_uni_pool_kernel_f32<isa>(pd()->jpp_); }
+
+ ~jit_uni_pooling_bwd_t() { delete kernel_; }
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto ws = CTX_IN_MEM(const char *, MKLDNN_ARG_WORKSPACE);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ if (pd()->ndims() == 5)
+ execute_backward_3d(diff_dst, ws, diff_src);
+ else
+ execute_backward(diff_dst, ws, diff_src);
+
+ return status::success;
+ }
+
+private:
+ void execute_backward(const data_t *diff_dst, const char *indices,
+ data_t *diff_src) const;
+ void execute_backward_3d(const data_t *diff_dst, const char *indices,
+ data_t *diff_src) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ jit_uni_pool_kernel_f32<isa> *kernel_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder.cpp
new file mode 100644
index 0000000000..98796503b7
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder.cpp
@@ -0,0 +1,1006 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory_desc_wrapper.hpp"
+#include "mkldnn_debug.h"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+
+#include "cpu_primitive.hpp"
+#include "cpu_reorder_pd.hpp"
+#include "jit_uni_reorder.hpp"
+
+#include "jit_generator.hpp"
+
+// #define TR_DEBUG
+#if defined(TR_DEBUG)
+#define DEBUg(...) do { __VA_ARGS__ } while (0)
+#else
+#define DEBUg(...)
+#endif
+#define DEBUG(...) DEBUg(__VA_ARGS__)
+
+#ifdef _WIN32
+/* seems like s_addr is a reserved macro on Windows */
+#undef s_addr
+#endif
+
+using namespace Xbyak;
+using namespace mkldnn::impl::types;
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace tr {
+
+/** Minimal reasonable/desirable kernel size.
+ * The constant might be used to determine how a problem should be split
+ * between kernel and threading driver. */
+const size_t ker_prb_size_min = 64;
+
+/* kernel */
+struct jit_uni_reorder_kernel_f32: public kernel_t, public jit_generator {
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_uni_reorder_kernel_f32)
+
+ enum {
+ len_unroll_max = 256,
+ ndims_jit_loop_max = 3,
+ };
+
+ struct simple_impl_desc_t {
+ int ndims_full_unroll;
+ int len_last_dim_unroll;
+ int len_unroll;
+ };
+
+ static bool simple_impl_desc_init(const prb_t &prb,
+ simple_impl_desc_t *desc) {
+ const int ndims = prb.ndims;
+
+ int ndims_full_unroll = 0;
+ int len_last_dim_unroll = 1;
+ int len_unroll = 1;
+
+ for (int d = 0; d < ndims; ++d) {
+ auto &node = prb.nodes[d];
+ if (len_unroll * node.n <= len_unroll_max) {
+ ndims_full_unroll++;
+ len_unroll *= node.n;
+ } else {
+ len_last_dim_unroll = len_unroll_max / len_unroll;
+ while (node.n % len_last_dim_unroll)
+ --len_last_dim_unroll;
+ len_unroll *= len_last_dim_unroll;
+ break;
+ }
+ }
+
+ if (prb.ndims - ndims_full_unroll > ndims_jit_loop_max)
+ return false;
+
+ if (desc) {
+ desc->ndims_full_unroll = ndims_full_unroll;
+ desc->len_last_dim_unroll = len_last_dim_unroll;
+ desc->len_unroll = len_unroll;
+ }
+
+ return true;
+ }
+
+ static bool applicable(const prb_t &p) {
+ using namespace data_type;
+
+ bool ok = true
+ && p.ndims > 0
+ && utils::one_of(p.itype, f32, s32, s8, u8)
+ && utils::one_of(p.otype, f32, s32, s8, u8)
+ && utils::everyone_is(0, p.ioff, p.ooff) /* do we need this? */
+ && utils::one_of(p.beta, 0.f, 1.f) /* anything else? */
+ && simple_impl_desc_init(p, nullptr)
+ && mayiuse(sse42)
+ && IMPLICATION(!utils::everyone_is(f32, p.itype, p.otype),
+ mayiuse(avx));
+ if (!ok) return false;
+
+ const ptrdiff_t max_stride = (1LL<<31) - 1;
+ for (int d = 0; d < p.ndims; ++d) {
+ const ptrdiff_t cms = max_stride / p.nodes[d].n;
+ bool strides_ok = true
+ && p.nodes[d].is < cms / (int)data_type_size(p.itype)
+ && p.nodes[d].os < cms / (int)data_type_size(p.otype);
+ if (!strides_ok) return false;
+ }
+
+ return true;
+ }
+
+ int n(int d) { assert(d < prb_.ndims); return (int)prb_.nodes[d].n; }
+ int is(int d) { assert(d < prb_.ndims); return (int)prb_.nodes[d].is; }
+ int os(int d) { assert(d < prb_.ndims); return (int)prb_.nodes[d].os; }
+ int ss(int d) { assert(d < prb_.ndims); return (int)prb_.nodes[d].ss; }
+
+ Address i_addr(int i_off)
+ { return ptr[reg_ptr_in + reg_off_in + i_off * itype_sz]; }
+
+ Address o_addr(int o_off)
+ { return ptr[reg_ptr_out + reg_off_out + o_off * otype_sz]; }
+
+ Address s_addr(int s_off)
+ { return ptr[reg_ptr_scale + reg_off_scale + s_off * stype_sz]; }
+
+ void step(int off, int prev_i_off, int prev_o_off, int prev_s_off,
+ int &i_off, int &o_off, int &s_off, int step_size = 1) {
+ i_off = prev_i_off;
+ o_off = prev_o_off;
+ s_off = prev_s_off;
+
+ if (off == 0) return;
+
+ int start_dim = 0, dims_prod = 1;
+ for (; start_dim < prb_.ndims && dims_prod != step_size; ++start_dim)
+ dims_prod *= n(start_dim);
+ assert(start_dim < prb_.ndims);
+ off /= step_size;
+
+ for (int d = start_dim; d < prb_.ndims; ++d) {
+ i_off += is(d);
+ o_off += os(d);
+ s_off += ss(d);
+
+ if (off % n(d)) break;
+
+ i_off += - n(d) * is(d);
+ o_off += - n(d) * os(d);
+ s_off += - n(d) * ss(d);
+ off /= n(d);
+
+ if (off == 0) break; /* FIXME: is it really required? */
+ }
+ }
+
+ void step(int off, int prev_i_off, int prev_o_off, int &i_off, int &o_off,
+ int step_size = 1) {
+ int dummy = 0;
+ step(off, prev_i_off, prev_o_off, dummy, i_off, o_off, dummy,
+ step_size);
+ }
+
+ void tr8x8_avx2(int i_off, int o_off) {
+ for (int i = 0; i < 8; i++)
+ vmovups(Ymm(i), i_addr(i_off + i * 8));
+
+ for (int i = 0; i < 8 / 2; i++) {
+ vunpcklps(Ymm(8 + i), Ymm(2 * i), Ymm(2 * i + 1));
+ vunpckhps(Ymm(i), Ymm(2 * i), Ymm(2 * i + 1));
+ }
+
+ const unsigned int lfloat = 0x44;
+ const unsigned int ufloat = 0xee;
+ for (int i = 0; i < 8 / 2; i++) {
+ int j = i % 2 == 0 ? 8 + i : i - 1;
+ vshufps(Ymm(8 / 2 + 2 * i), Ymm(j), Ymm(j + 1), lfloat);
+ vshufps(Ymm(8 / 2 + 2 * i + 1), Ymm(j), Ymm(j + 1), ufloat);
+ }
+
+ const unsigned int lquad = 0x20;
+ for (int i = 0; i < 8 / 2; i++)
+ vperm2f128(Ymm(i), Ymm(8 / 2 + i), Ymm(8 + i), lquad);
+
+ const unsigned int uquad = 0x31;
+ for (int i = 8 / 2; i < 8; i++)
+ vperm2f128(Ymm(i), Ymm(i), Ymm(8 / 2 + i), uquad);
+
+ for (int i = 0; i < 8; i++)
+ vmovups(o_addr(o_off + i * 8), Ymm(i));
+ }
+
+ bool process_unroll_tr8x8(int len) {
+ bool can_do = true
+ && mayiuse(avx2)
+ && prb_.ndims >= 2
+ && utils::everyone_is(4, itype_sz, otype_sz)
+ && utils::everyone_is(8, n(0), n(1))
+ && utils::everyone_is(1, os(0), is(1))
+ && utils::everyone_is(8, os(1), is(0))
+ && prb_.scale_type == scale_type_t::NONE
+ && prb_.beta == 0.f;
+ if (!can_do) return false;
+
+ const int step_size = n(0) * n(1);
+ int i_off = 0, o_off = 0;
+ for (int off = 0; off < len; off += step_size) {
+ step(off, i_off, o_off, i_off, o_off, step_size);
+ tr8x8_avx2(i_off, o_off);
+ }
+
+ return true;
+ }
+
+ template <cpu_isa_t isa>
+ bool process_direct_copy(int len) {
+ using namespace data_type;
+
+ using Vmm = typename cpu_isa_traits<isa>::Vmm;
+ const int simd_w = cpu_isa_traits<isa>::vlen / itype_sz;
+
+ bool can_do = true
+ && mayiuse(isa)
+ && utils::everyone_is(1, os(0), is(0))
+ && (false
+ || prb_.itype == prb_.otype
+ || (prb_.itype == s32 && prb_.otype == f32)
+ || (prb_.itype == f32 && prb_.otype == s32)
+ )
+ && len % simd_w == 0
+ && n(0) % len == 0
+ && prb_.scale_type == scale_type_t::NONE
+ && prb_.beta == 0.f;
+ if (!can_do) return false;
+
+ for (int off = 0; off < len;) {
+ const int unroll = nstl::min(16, (len - off) / simd_w);
+
+ for (int ur = 0; ur < unroll; ++ur)
+ uni_vmovups(Vmm(ur), i_addr(off + ur * simd_w));
+
+ if (prb_.itype != prb_.otype) {
+ for (int ur = 0; ur < unroll; ++ur) {
+ if (prb_.itype == s32 && prb_.otype == f32)
+ uni_vcvtdq2ps(Vmm(ur), Vmm(ur));
+ else if (prb_.itype == f32 && prb_.otype == s32)
+ uni_vcvtps2dq(Vmm(ur), Vmm(ur));
+ else assert(!"unreachable");
+ }
+ }
+
+ for (int ur = 0; ur < unroll; ++ur)
+ uni_vmovups(o_addr(off + ur * simd_w), Vmm(ur));
+
+ off += unroll * simd_w;
+ }
+
+ return true;
+ }
+
+ void process_unroll_generic_step(int reg_unroll, const int *i_off,
+ const int *o_off, const int *s_off) {
+ using namespace data_type;
+
+ auto cvt2ps = [=](const Xmm &dst, const Operand &src, data_type_t idt) {
+ Xmm dst_pure = Xmm(dst.getIdx());
+ switch (idt) {
+ case f32:
+ if (src.isMEM() || src.getIdx() != dst.getIdx())
+ vmovups(dst, src);
+ break;
+ case s32: vcvtdq2ps(dst, src); break;
+ case s8: vpmovsxbd(dst, src); vcvtdq2ps(dst_pure, dst); break;
+ case u8: vpmovzxbd(dst, src); vcvtdq2ps(dst_pure, dst); break;
+ default: assert(!"unreachable");
+ }
+ };
+
+ auto cvt2int = [=](const Xmm &xmm, data_type_t odt, data_type_t idt) {
+ switch (odt) {
+ case s32:
+ if (idt == f32) vcvtps2dq(xmm, xmm);
+ else if (idt == s8) vpmovsxbd(xmm, xmm);
+ else if (idt == u8) vpmovzxbd(xmm, xmm);
+ break;
+ case s8:
+ if (idt == f32) vcvtps2dq(xmm, xmm);
+ if (idt == f32 || idt == s32) {
+ if (mayiuse(avx512_core)) {
+ vpmovsdb(xmm, xmm);
+ } else {
+ vpackssdw(xmm, xmm, xmm_zero);
+ vpacksswb(xmm, xmm, xmm_zero);
+ }
+ }
+ if (idt == u8) vpminub(xmm, xmm, xmm_4x127b);
+ break;
+ case u8:
+ if (idt == f32) vcvtps2dq(xmm, xmm);
+ if (idt == f32 || idt == s32) {
+ if (mayiuse(avx512_core)) {
+ vpmaxsd(xmm, xmm, xmm_zero);
+ vpmovusdb(xmm, xmm);
+ } else {
+ vpackssdw(xmm, xmm, xmm_zero);
+ vpackuswb(xmm, xmm, xmm_zero);
+ }
+ }
+ if (idt == s8) vpmaxsb(xmm, xmm, xmm_zero);
+ break;
+ default: assert(!"unreachable");
+ }
+ };
+
+ auto load = [=](const Xmm &xmm, const Address &addr, int size) {
+ switch (size) {
+ case 16: movups(xmm, addr); break;
+ case 4: movss(xmm, addr); break;
+ case 1: pinsrb(xmm, addr, 0x0); break;
+ default: assert(!"unreachable");
+ }
+ };
+
+ auto store = [=](const Address &addr, const Xmm &xmm, int size) {
+ switch (size) {
+ case 16: movups(addr, xmm); break;
+ case 4: movss(addr, xmm); break;
+ case 1: pextrb(addr, xmm, 0x0); break;
+ default: assert(!"unreachable");
+ }
+ };
+
+ /* check whether loading 4 values at once is possible */
+ bool can_load_xmm = mayiuse(avx) && reg_unroll % 4 == 0;
+ for (int ur = 1; ur < reg_unroll; ++ur)
+ if (i_off[ur] != i_off[ur - 1] + 1)
+ can_load_xmm = false;
+ const int load_step = can_load_xmm ? 4 : 1;
+
+ /* check whether storing 4 values at once is possible */
+ bool can_store_xmm = reg_unroll % 4 == 0;
+ for (int ur = 1; ur < reg_unroll; ++ur)
+ if (o_off[ur] != o_off[ur - 1] + 1)
+ can_store_xmm = false;
+ const int ur_step = can_store_xmm ? 4 : 1;
+
+ const bool interim_f32 = false
+ || utils::one_of(f32, prb_.itype, prb_.otype)
+ || prb_.scale_type != scale_type_t::NONE
+ || prb_.beta != 0.f;
+
+ if (!can_load_xmm && can_store_xmm) {
+ assert(ur_step == 4);
+ /* load with stride */
+ for (int ur = 0; ur < reg_unroll; ur += ur_step) {
+ for (int r = 0; r < ur_step; ++r) {
+ if (itype_sz == 4)
+ pinsrd(Xmm(ur), i_addr(i_off[ur + r]), r);
+ else
+ pinsrb(Xmm(ur), i_addr(i_off[ur + r]), r);
+ }
+ }
+ } else {
+ for (int ur = 0; ur < reg_unroll; ur += load_step)
+ load(Xmm(ur), i_addr(i_off[ur]), load_step * itype_sz);
+ }
+
+ /* xmm[:] <-- (f32)xmm[:] */
+ if (interim_f32) {
+ const int cvt_step = nstl::max(load_step, ur_step);
+ for (int ur = 0; ur < reg_unroll; ur += cvt_step)
+ cvt2ps(Xmm(ur), Xmm(ur), prb_.itype);
+ }
+
+ if (can_load_xmm && !can_store_xmm) {
+ const bool fast_return = true // transposition on the fly
+ && prb_.scale_type != scale_type_t::MANY
+ && prb_.beta == 0.f;
+ if (fast_return) {
+ for (int ur = 0; ur < reg_unroll; ur += load_step) {
+ if (prb_.scale_type == scale_type_t::COMMON)
+ mulps(Xmm(ur), xmm_scale);
+ if (prb_.otype != f32)
+ cvt2int(Xmm(ur), prb_.otype,
+ interim_f32 ? f32 : prb_.itype);
+ for (int r = 0; r < load_step; ++r) {
+ if (otype_sz == 4)
+ pextrd(o_addr(o_off[ur + r]), Xmm(ur), r);
+ else
+ pextrb(o_addr(o_off[ur + r]), Xmm(ur), r);
+ }
+ }
+ return;
+ }
+
+ /* scatter elements of xmm into 4 xmms */
+ if (itype_sz == 4 || interim_f32) {
+ for (int ur = 0; ur < reg_unroll; ur += load_step)
+ for (int r = 1; r < load_step; ++r)
+ vshufps(Xmm(ur + r), Xmm(ur), Xmm(ur), r);
+ } else {
+ for (int ur = 0; ur < reg_unroll; ur += load_step)
+ for (int r = 1; r < load_step; ++r)
+ vpalignr(Xmm(ur + r), Xmm(ur), Xmm(ur), r);
+ }
+ }
+
+ /* scale and beta processing */
+ if (can_store_xmm) {
+ /* xmm <-- scale * xmm[:] */
+ if (prb_.scale_type == scale_type_t::COMMON) {
+ for (int ur = 0; ur < reg_unroll; ur += ur_step)
+ mulps(Xmm(ur), xmm_scale);
+ } else if (prb_.scale_type == scale_type_t::MANY) {
+ enum class scale_load_type_t { bcast, load, gather };
+
+ for (int ur = 0; ur < reg_unroll; ur += ur_step) {
+ scale_load_type_t scale_load_type =
+ scale_load_type_t::bcast; // the best case
+
+ for (int r = ur + 1; r < ur + ur_step; ++r)
+ if (s_off[r] != s_off[r - 1] + 0)
+ scale_load_type = scale_load_type_t::load;
+
+ if (scale_load_type == scale_load_type_t::bcast) {
+ movss(xmm_scale, s_addr(s_off[ur]));
+ shufps(xmm_scale, xmm_scale, 0x0);
+ mulps(Xmm(ur), xmm_scale);
+ continue;
+ }
+
+ // bcast doesn't work, the next try -- load
+ for (int r = ur + 1; r < ur + ur_step; ++r)
+ if (s_off[r] != s_off[r - 1] + 1)
+ scale_load_type = scale_load_type_t::gather;
+
+ if (scale_load_type == scale_load_type_t::load) {
+ movups(xmm_scale, s_addr(s_off[ur]));
+ mulps(Xmm(ur), xmm_scale);
+ continue;
+ }
+
+ // load doesn't work as well
+ // so gather the scale factors one by one
+ for (int r = ur; r < ur + ur_step; ++r)
+ pinsrd(xmm_scale, s_addr(s_off[r]), r - ur);
+ mulps(Xmm(ur), xmm_scale);
+ }
+ }
+
+ /* dst <-- beta * dst + xmm[:] */
+ assert(prb_.beta == 0.f || prb_.beta == 1.f);
+ if (prb_.beta == 1.f) {
+ for (int ur = 0; ur < reg_unroll; ur += ur_step) {
+ if (prb_.otype == f32) {
+ /* non VEX instructions do not support unaligned
+ * memory for instructions other than movups. */
+ if (mayiuse(avx)) {
+ vaddps(Xmm(ur), o_addr(o_off[ur]));
+ } else {
+ /* register xmm(1) is unused */
+ movups(Xmm(1), o_addr(o_off[ur]));
+ addps(Xmm(ur), Xmm(1));
+ }
+ } else {
+ cvt2ps(Xmm(1), o_addr(o_off[ur]), prb_.otype);
+ vaddps(Xmm(ur), Xmm(1));
+ }
+ }
+ }
+ } else {
+ /* xmm[0] <-- scale * xmm[0] */
+ if (prb_.scale_type == scale_type_t::COMMON) {
+ for (int ur = 0; ur < reg_unroll; ur += ur_step)
+ mulss(Xmm(ur), xmm_scale);
+ } else if (prb_.scale_type == scale_type_t::MANY) {
+ for (int ur = 0; ur < reg_unroll; ur += ur_step) {
+ mulss(Xmm(ur), s_addr(s_off[ur]));
+ }
+ }
+
+ /* dst <-- beta * dst + xmm[0] */
+ assert(prb_.beta == 0.f || prb_.beta == 1.f);
+ if (prb_.beta == 1.f) {
+ for (int ur = 0; ur < reg_unroll; ur += ur_step) {
+ if (prb_.otype == f32) {
+ addss(Xmm(ur), o_addr(o_off[ur]));
+ } else {
+ if (prb_.otype == s32) {
+ vmovss(xmm_tmp, o_addr(o_off[ur]));
+ } else if (utils::one_of(prb_.otype, s8, u8)) {
+ pinsrb(xmm_tmp, o_addr(o_off[ur]), 0x0);
+ } else {
+ assert(!"unsupported o_type");
+ }
+ cvt2ps(xmm_tmp, xmm_tmp, prb_.otype);
+ addps(Xmm(ur), xmm_tmp);
+ }
+ }
+ }
+ }
+
+ for (int ur = 0; ur < reg_unroll; ur += ur_step) {
+ if (prb_.otype != f32)
+ cvt2int(Xmm(ur), prb_.otype, interim_f32 ? f32 : prb_.itype);
+ store(o_addr(o_off[ur]), Xmm(ur), ur_step * otype_sz);
+ }
+ }
+
+ void process_unroll_generic(int len) {
+ const int blk = 8;
+
+ int i_off[2 * blk] = {0};
+ int o_off[2 * blk] = {0};
+ int s_off[2 * blk] = {0};
+
+ int curr = 0; // will switch between 0 and 1
+
+ for (int off = 0; off < len; off += blk) {
+ const int reg_unroll = nstl::min(off + blk, len) - off;
+
+ /* compute offsets */
+ for (int ur = off != 0 ? 0 : 1; ur < reg_unroll; ++ur) {
+ const int ur_c = curr * blk + ur;
+ const int ur_p = (ur_c - 1 + 2 * blk) % (2 * blk); // prev ur
+ step(off + ur,
+ i_off[ur_p], o_off[ur_p], s_off[ur_p],
+ i_off[ur_c], o_off[ur_c], s_off[ur_c]);
+ }
+
+ process_unroll_generic_step(reg_unroll, i_off + curr * blk,
+ o_off + curr * blk, s_off + curr * blk);
+
+ curr = 1 - curr;
+ }
+ }
+
+ void loop_begin(Label &l, Reg64 reg_cnt, int len) {
+ mov(reg_cnt, len);
+ L(l);
+ }
+
+ void loop_end(Label &l, Reg64 reg_cnt, int len,
+ int i_step, int o_step, int s_step) {
+ add(reg_off_in, i_step * itype_sz);
+ add(reg_off_out, o_step * otype_sz);
+ if (prb_.scale_type == scale_type_t::MANY)
+ add(reg_off_scale, s_step * stype_sz);
+ dec(reg_cnt);
+ jnz(l);
+
+ sub(reg_off_in, len * i_step * itype_sz);
+ sub(reg_off_out, len * o_step * otype_sz);
+ if (prb_.scale_type == scale_type_t::MANY)
+ sub(reg_off_scale, len * s_step * stype_sz);
+ }
+
+ bool simple_impl() {
+ simple_impl_desc_t d;
+ if (!simple_impl_desc_init(prb_, &d)) return false;
+
+ const int nfu = d.ndims_full_unroll;
+ const int ldu = d.len_last_dim_unroll;
+ const int n_jit_loops = prb_.ndims - d.ndims_full_unroll;
+ assert(n_jit_loops <= ndims_jit_loop_max);
+
+ xor_(reg_off_in, reg_off_in);
+ xor_(reg_off_out, reg_off_out);
+ if (prb_.scale_type == scale_type_t::MANY)
+ xor_(reg_off_scale, reg_off_scale);
+
+ Label l_loop[3];
+ Reg64 reg_cnt[3] = {r15, r14, r13};
+
+ if (n_jit_loops > 2)
+ loop_begin(l_loop[2], reg_cnt[2], n(nfu + 2));
+
+ if (n_jit_loops > 1)
+ loop_begin(l_loop[1], reg_cnt[1], n(nfu + 1));
+
+ if (n_jit_loops > 0)
+ loop_begin(l_loop[0], reg_cnt[0], n(nfu + 0) / ldu);
+
+ const bool optimized = false
+ || process_direct_copy<avx>(d.len_unroll)
+ || process_direct_copy<sse42>(d.len_unroll)
+ || process_unroll_tr8x8(d.len_unroll);
+ if (!optimized)
+ process_unroll_generic(d.len_unroll);
+
+ if (n_jit_loops > 0)
+ loop_end(l_loop[0], reg_cnt[0],
+ n(nfu + 0) / ldu, is(nfu + 0) * ldu, os(nfu + 0) * ldu,
+ ss(nfu + 0) * ldu);
+
+ if (n_jit_loops > 1)
+ loop_end(l_loop[1], reg_cnt[1],
+ n(nfu + 1), is(nfu + 1), os(nfu + 1), ss(nfu + 1));
+
+ if (n_jit_loops > 2)
+ loop_end(l_loop[2], reg_cnt[2],
+ n(nfu + 2), is(nfu + 2), os(nfu + 2), ss(nfu + 2));
+
+ return true;
+ }
+
+ void impl() {
+ if (simple_impl()) return;
+ assert(!"no implementation available");
+ }
+
+ jit_uni_reorder_kernel_f32(const desc_t &desc)
+ : kernel_t(desc), jit_generator() {
+ itype_sz = data_type_size(prb_.itype);
+ otype_sz = data_type_size(prb_.otype);
+ stype_sz = sizeof(float);
+
+ preamble();
+# define PARAM(x) ptr[abi_param1 + offsetof(call_param_t, x)]
+ if (prb_.scale_type == scale_type_t::COMMON) {
+ auto reg_ptr_scale_tmp = reg_ptr_in;
+ mov(reg_ptr_scale_tmp, PARAM(scale));
+ movups(xmm_scale, ptr[reg_ptr_scale_tmp]);
+ } else if (prb_.scale_type == scale_type_t::MANY) {
+ mov(reg_ptr_scale, PARAM(scale));
+ }
+ mov(reg_ptr_in, PARAM(in));
+ mov(reg_ptr_out, PARAM(out));
+# undef PARAM
+
+ if (mayiuse(avx)) {
+ vxorps(xmm_zero, xmm_zero, xmm_zero);
+
+ if (prb_.itype == data_type::u8 && prb_.otype == data_type::s8) {
+ mov(reg_tmp.cvt32(), 0x7f7f7f7f);
+ movd(xmm_4x127b, reg_tmp.cvt32());
+ }
+ }
+
+ impl();
+ postamble();
+ ker_ = (void (*)(const call_param_t *))getCode();
+ }
+
+private:
+ int itype_sz;
+ int otype_sz;
+ int stype_sz;
+
+ Reg64 reg_ptr_in = rsi;
+ Reg64 reg_ptr_out = rdx;
+ Reg64 reg_ptr_scale = abi_not_param1;
+
+ Reg64 reg_off_in = r8;
+ Reg64 reg_off_out = r9;
+ Reg64 reg_off_scale = r10;
+
+ Reg64 reg_tmp = rax;
+
+ Xmm xmm_scale = xmm15;
+ Xmm xmm_zero = xmm14;
+ Xmm xmm_4x127b = xmm13; // TODO: unite with xmm_zero
+ Xmm xmm_tmp = xmm12;
+};
+
+status_t kernel_t::desc_init(kernel_t::desc_t &desc, const prb_t &prb,
+ int ndims_ker_max) {
+ desc.prb = prb;
+ desc.prb.ioff = desc.prb.ooff = 0;
+
+ if (ndims_ker_max > prb.ndims)
+ return status::invalid_arguments;
+
+ auto ndims_ker_max_f = [&]() {
+ size_t cur_size = 1;
+ for (int d = 0; d < prb.ndims; cur_size *= prb.nodes[d++].n)
+ if (cur_size >= ker_prb_size_min) return d;
+ return prb.ndims;
+ };
+
+ if (ndims_ker_max <= 0)
+ ndims_ker_max = ndims_ker_max_f();
+
+ /* traverse through kernel implementations */
+ /* TODO: find a better way to do that... */
+ desc.id = 0;
+ for (int ndims_ker = ndims_ker_max; ndims_ker > 0; --ndims_ker) {
+ desc.prb.ndims = ndims_ker;
+ if (jit_uni_reorder_kernel_f32::applicable(desc.prb))
+ return status::success;
+ }
+
+ return status::unimplemented;
+}
+
+kernel_t *kernel_t::create(const kernel_t::desc_t &desc) {
+ switch (desc.id) {
+ case 0: return new jit_uni_reorder_kernel_f32(desc);
+ default: assert(!"unknown kernel id"); return nullptr;
+ }
+
+ return nullptr;
+}
+
+}
+
+static void prb_block_for_cache(tr::prb_t &prb) {
+ if (prb.nodes[0].is % 64 == 0 && prb.nodes[0].n > 16) {
+ /** an attempt to use caches more efficient and
+ * address the 4K-aliasing issue */
+ /* TODO: improve the logic around here */
+ int j = 1;
+ for (; j < prb.ndims && prb.nodes[j].is != 1; ++j);
+ if (j == prb.ndims) return;
+
+ /* it makes sense to re-prioritize sequential read over
+ * sequential write if the former would not trash the
+ * cache, i.e. is == 1 and os % 2^smth != 0. Smth is
+ * set to 2 at the moment */
+ const int move_to = prb.nodes[j].os % 4 != 0 ? 0 : 1;
+ if (j == move_to) return;
+
+ if (prb.nodes[j].n > 16 && prb.nodes[j].n % 16 == 0)
+ prb_node_split(prb, j, 16);
+
+ prb_node_move(prb, j, move_to);
+ DEBUG({ printf("cache: "); prb_dump(prb); });
+ }
+}
+
+/** finds the maximum number of dimension the kernel should process and
+ * optionally splits one of the dimension to achieve better balance between
+ * parallel driver and the kernel. */
+static void prb_thread_kernel_balance(tr::prb_t &prb, int &ndims_ker_max) {
+ size_t sz_total = 1;
+ for (int d = 0; d < prb.ndims; ++d)
+ sz_total *= prb.nodes[d].n;
+
+ /* sz_drv_min is the minimal size for the parallel
+ * driver required for good parallelization */
+ const size_t sz_drv_min = nstl::min<size_t>(
+ 16 * mkldnn_get_max_threads(),
+ utils::div_up(sz_total, 1024));
+
+ /* kdims -- # of dimensions processed by a kernel
+ * sz_ker_cur -- product of the dimension processed by a kernel
+ * sz_drv_cur -- product of the dimension processed by a driver */
+
+ int kdims = prb.ndims;
+ size_t sz_drv_cur = 1;
+ for (; kdims > 1 && sz_drv_cur < sz_drv_min; --kdims)
+ sz_drv_cur *= prb.nodes[kdims - 1].n;
+
+ size_t sz_ker_cur = 1;
+ for (int d = 0; d < kdims; ++d)
+ sz_ker_cur *= prb.nodes[d].n;
+
+ /* Initially kdims is chosen so that sz_drv_cur >= sz_drv_min.
+ *
+ * It might happen that for chosen kdims the sz_ker_cur is too small
+ * (less than tr::ker_prb_size_min). In that case try to split the
+ * innermost driver dimension into two, to increase sz_ker_cur. */
+ bool want_borrow_ker_from_drv = true
+ && kdims < prb.ndims
+ && sz_ker_cur < tr::ker_prb_size_min
+ && sz_drv_cur > sz_drv_min;
+ if (want_borrow_ker_from_drv) {
+ /* sz_want_borrow is the minimal sz, so that:
+ * o) sz_ker_cur * sz_want_borrow >= tr::ker_prb_size_min
+ * o) current innermost driver dimension is divisible by
+ * sz_want_borrow (so that we can evenly split that
+ * dimension into two)
+ *
+ * In the worst case the minimal sz_want_borrow is equal
+ * to the innermost driver dimension itself. In that case
+ * we will sacrifice it in favor of kernel (is it fine?). */
+ size_t sz_want_borrow
+ = utils::div_up(tr::ker_prb_size_min, sz_ker_cur);
+ for (; prb.nodes[kdims].n % sz_want_borrow; ++sz_want_borrow);
+ if (sz_want_borrow != prb.nodes[kdims].n)
+ prb_node_split(prb, kdims, sz_want_borrow);
+ kdims += 1;
+ }
+
+ /* On the other hand it might happen that for chosen kdims
+ * the sz_drv_cur is too small (less than sz_drv_min). In that case
+ * try to split the outermost kernel dimension into two, to increase
+ * sz_drv_cur. */
+ bool want_borrow_drv_from_ker = true
+ && sz_ker_cur > tr::ker_prb_size_min
+ && sz_drv_cur < sz_drv_min;
+ if (want_borrow_drv_from_ker) {
+ size_t sz_want_borrow = utils::div_up(sz_drv_min, sz_drv_cur);
+ for (; prb.nodes[kdims - 1].n % sz_want_borrow; ++sz_want_borrow);
+ if (sz_want_borrow != prb.nodes[kdims - 1].n)
+ prb_node_split(prb, kdims - 1,
+ prb.nodes[kdims - 1].n / sz_want_borrow);
+ }
+
+ ndims_ker_max = kdims;
+
+ if (want_borrow_ker_from_drv || want_borrow_drv_from_ker) {
+ DEBUG({ printf("split: "); prb_dump(prb);
+ printf("ndims_ker_max = %d\n", ndims_ker_max); });
+ }
+}
+
+struct jit_uni_reorder_t : public cpu_primitive_t {
+ struct pd_t : public cpu_reorder_pd_t {
+ using cpu_reorder_pd_t::cpu_reorder_pd_t;
+
+ DECLARE_COMMON_PD_T("jit:uni", jit_uni_reorder_t);
+
+ static status_t create(reorder_pd_t **reorder_pd,
+ engine_t *engine, const primitive_attr_t *attr,
+ engine_t *src_engine, const memory_desc_t *src_md,
+ engine_t *dst_engine, const memory_desc_t *dst_md) {
+ auto prb = tr::prb_t();
+
+ status_t prb_init_status = prb_init(prb, *src_md, *dst_md, attr);
+ if (prb_init_status != status::success) return prb_init_status;
+
+ DEBUG({ printf("init : "); prb_dump(prb); });
+ prb_normalize(prb);
+ DEBUG({ printf("norm : "); prb_dump(prb); });
+ prb_simplify(prb);
+ DEBUG({ printf("smpl : "); prb_dump(prb); });
+
+ prb_block_for_cache(prb);
+
+ int ndims_ker_max;
+ prb_thread_kernel_balance(prb, ndims_ker_max);
+
+ tr::kernel_t::desc_t ker_desc;
+ status_t ker_init_status
+ = tr::kernel_t::desc_init(ker_desc, prb, ndims_ker_max);
+ if (ker_init_status != status::success) return ker_init_status;
+
+ const int ndims_driver = prb.ndims - ker_desc.prb.ndims;
+ if (ndims_driver > jit_uni_reorder_t::ndims_driver_max)
+ return status::unimplemented;
+
+ DEBUG({ printf("ker : "); prb_dump(ker_desc.prb); });
+
+ auto _pd = new pd_t(engine, attr, src_engine, src_md, dst_engine,
+ dst_md);
+ if (_pd == nullptr) return status::out_of_memory;
+ if (_pd->init() != status::success) {
+ delete _pd;
+ return status::unimplemented;
+ }
+ _pd->prb_ = prb;
+ _pd->ker_desc_ = ker_desc;
+ return safe_ptr_assign<reorder_pd_t>(*reorder_pd, _pd);
+ }
+
+ tr::prb_t prb_;
+ tr::kernel_t::desc_t ker_desc_;
+ };
+
+ jit_uni_reorder_t(const pd_t *apd): cpu_primitive_t(apd) {
+ kernel_ = tr::kernel_t::create(pd()->ker_desc_);
+ assert(kernel_);
+ }
+ ~jit_uni_reorder_t() { delete kernel_; }
+
+ void omp_driver_0d(int off, const char *in, char *out,
+ const float *scale) const {
+ tr::call_param_t c{in, out, scale};
+ (*kernel_)(&c);
+ }
+
+ void omp_driver_1d(int ithr, int nthr, int off, const char *in, char *out,
+ const float *scale) const {
+ const tr::node_t *ns = pd()->prb_.nodes + off;
+ for_nd(ithr, nthr, (ptrdiff_t)ns[0].n, [&](ptrdiff_t d0) {
+ auto c = tr::call_param_t();
+ c.in = in + d0 * ns[0].is * data_type_size(pd()->prb_.itype);
+ c.out = out + d0 * ns[0].os * data_type_size(pd()->prb_.otype);
+ c.scale = scale + d0 * ns[0].ss;
+ (*kernel_)(&c);
+ });
+ }
+
+ void omp_driver_2d(int ithr, int nthr, int off, const char *in, char *out,
+ const float *scale) const {
+ const tr::node_t *ns = pd()->prb_.nodes + off;
+ for_nd(ithr, nthr, (ptrdiff_t)ns[1].n, (ptrdiff_t)ns[0].n,
+ [&](ptrdiff_t d1, ptrdiff_t d0) {
+ auto c = tr::call_param_t();
+ c.in = in + (d0 * ns[0].is + d1 * ns[1].is)
+ * data_type_size(pd()->prb_.itype);
+ c.out = out + (d0 * ns[0].os + d1 * ns[1].os)
+ * data_type_size(pd()->prb_.otype);
+ c.scale = scale + d0 * ns[0].ss + d1 * ns[1].ss;
+ (*kernel_)(&c);
+ });
+ }
+
+ void omp_driver_3d(int ithr, int nthr, int off, const char *in, char *out,
+ const float *scale) const {
+ const tr::node_t *ns = pd()->prb_.nodes + off;
+ for_nd(ithr, nthr, (ptrdiff_t)ns[2].n, (ptrdiff_t)ns[1].n,
+ (ptrdiff_t)ns[0].n,
+ [&](ptrdiff_t d2, ptrdiff_t d1, ptrdiff_t d0) {
+ auto c = tr::call_param_t();
+ c.in = in + (d0 * ns[0].is + d1 * ns[1].is + d2 * ns[2].is)
+ * data_type_size(pd()->prb_.itype);
+ c.out = out + (d0 * ns[0].os + d1 * ns[1].os + d2 * ns[2].os)
+ * data_type_size(pd()->prb_.otype);
+ c.scale = scale + d0 * ns[0].ss + d1 * ns[1].ss + d2 * ns[2].ss;
+ (*kernel_)(&c);
+ });
+ }
+
+ void omp_driver_4d(int ithr, int nthr, int off, const char *in, char *out,
+ const float *scale) const {
+ const tr::node_t *ns = pd()->prb_.nodes + off;
+ for_nd(ithr, nthr, (ptrdiff_t)ns[3].n, (ptrdiff_t)ns[2].n,
+ (ptrdiff_t)ns[1].n, (ptrdiff_t)ns[0].n,
+ [&](ptrdiff_t d3, ptrdiff_t d2, ptrdiff_t d1, ptrdiff_t d0) {
+ auto c = tr::call_param_t();
+ c.in = in + (d0 * ns[0].is + d1 * ns[1].is + d2 * ns[2].is
+ + d3 * ns[3].is) * data_type_size(pd()->prb_.itype);
+ c.out = out + (d0 * ns[0].os + d1 * ns[1].os + d2 * ns[2].os
+ + d3 * ns[3].os) * data_type_size(pd()->prb_.otype);
+ c.scale = scale + d0 * ns[0].ss + d1 * ns[1].ss + d2 * ns[2].ss
+ + d3 * ns[3].ss;
+ (*kernel_)(&c);
+ });
+ }
+
+ void omp_driver(const char *in, char *out, const float *scale) const {
+ in += pd()->prb_.ioff * data_type_size(pd()->prb_.itype);
+ out += pd()->prb_.ooff * data_type_size(pd()->prb_.otype);
+
+ DEBUG({ printf("prb : "); tr::prb_dump(pd()->prb_); });
+ DEBUG({ printf("ker : "); tr::prb_dump(pd()->ker_desc_.prb); });
+
+ int ndims = pd()->prb_.ndims;
+ int ndims_ker = pd()->ker_desc_.prb.ndims;
+ assert(ndims - ndims_ker <= ndims_driver_max);
+
+ if (ndims - ndims_ker == 0) {
+ omp_driver_0d(ndims_ker, in, out, scale);
+ } else {
+ parallel(0, [&](const int ithr, const int nthr) {
+ switch (ndims - ndims_ker) {
+ case 1: omp_driver_1d(ithr, nthr, ndims_ker, in, out, scale); break;
+ case 2: omp_driver_2d(ithr, nthr, ndims_ker, in, out, scale); break;
+ case 3: omp_driver_3d(ithr, nthr, ndims_ker, in, out, scale); break;
+ case 4: omp_driver_4d(ithr, nthr, ndims_ker, in, out, scale); break;
+ default: assert(!"unimplemented");
+ }
+ });
+ }
+ }
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ auto in = CTX_IN_MEM(const char *, MKLDNN_ARG_FROM);
+ auto out = CTX_OUT_MEM(char *, MKLDNN_ARG_TO);
+
+ omp_driver(in, out, pd()->attr()->output_scales_.scales_);
+
+ return status::success;
+ }
+
+ enum { ndims_driver_max = 4 };
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ tr::kernel_t *kernel_;
+};
+
+status_t jit_uni_reorder_create(reorder_pd_t **reorder_pd,
+ engine_t *engine, const primitive_attr_t *attr,
+ engine_t *src_engine, const memory_desc_t *src_md,
+ engine_t *dst_engine, const memory_desc_t *dst_md) {
+ return jit_uni_reorder_t::pd_t::create(reorder_pd, engine, attr,
+ src_engine, src_md, dst_engine, dst_md);
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder.hpp
new file mode 100644
index 0000000000..0746ea61d3
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder.hpp
@@ -0,0 +1,127 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef _JIT_UNI_REORDER_HPP
+#define _JIT_UNI_REORDER_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+
+#include "cpu_primitive.hpp"
+#include "cpu_reorder_pd.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace tr {
+
+constexpr int max_ndims = MKLDNN_MAX_NDIMS;
+
+struct node_t {
+ size_t n;
+ ptrdiff_t is; // input stride
+ ptrdiff_t os; // output stride
+ ptrdiff_t ss; // scale stride
+};
+
+enum class scale_type_t { NONE, COMMON, MANY };
+
+struct prb_t {
+ data_type_t itype;
+ data_type_t otype;
+ int ndims;
+ node_t nodes[max_ndims];
+ ptrdiff_t ioff;
+ ptrdiff_t ooff;
+ scale_type_t scale_type;
+ float beta;
+};
+
+status_t prb_init(prb_t &prb, const memory_desc_t &imd,
+ const memory_desc_t &omd, const primitive_attr_t *attr);
+
+/** sorts the problem nodes so that output strides come in ascending order */
+void prb_normalize(prb_t &p);
+
+/** folds nodes together if possible */
+void prb_simplify(prb_t &p);
+
+/** splits the node dim into two of sizes n1 and n / n1
+ * @warning n must be multiple of n1 */
+void prb_node_split(prb_t &p, int dim, size_t n1);
+
+/** swaps d0 and d1 nodes */
+void prb_node_swap(prb_t &p, int d0, int d1);
+
+/** moves node d0 to the d1 position.
+ * nodes (d0, d1] are shifted to the left if d0 < d1 or
+ * to the right if d0 > d1 */
+void prb_node_move(prb_t &p, int d0, int d1);
+
+/** dumps the problem to stdout */
+void prb_dump(const prb_t &p);
+
+struct call_param_t {
+ const void *in;
+ void *out;
+ const float *scale;
+};
+
+struct kernel_t {
+ struct desc_t {
+ int id;
+ prb_t prb;
+ };
+
+ kernel_t(const desc_t &desc): desc_(desc), ker_(nullptr) {}
+ void operator()(const call_param_t *c) const { assert(ker_); ker_(c); }
+ virtual ~kernel_t() {}
+
+ /** inits kernel descriptor:
+ * desc -- kernel descriptor (output)
+ * prb -- transposition problem (input)
+ * ndims_ker_max -- limit the maximum number of dimensions kernel
+ * will process (optional, 0 -- no limitation) */
+ static status_t desc_init(desc_t &desc, const prb_t &prb,
+ int ndims_ker_max = 0);
+
+ /** creates kernel for the problem described in desc */
+ static kernel_t *create(const desc_t &desc);
+
+protected:
+ const desc_t desc_;
+ const prb_t &prb_ = desc_.prb;
+ void (*ker_)(const call_param_t *);
+};
+
+/* TODO: add trans_t class */
+
+}
+
+/* for cpu reorder list */
+status_t jit_uni_reorder_create(reorder_pd_t **reorder_pd,
+ engine_t *engine, const primitive_attr_t *attr,
+ engine_t *src_engine, const memory_desc_t *src_md,
+ engine_t *dst_engine, const memory_desc_t *dst_md);
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder_utils.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder_utils.cpp
new file mode 100644
index 0000000000..69b7a33604
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_uni_reorder_utils.cpp
@@ -0,0 +1,313 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory_desc_wrapper.hpp"
+#include "mkldnn_debug.h"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "jit_uni_reorder.hpp"
+
+using namespace mkldnn::impl::types;
+using namespace mkldnn::impl::status;
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace tr {
+
+/** ad-hoc structure to describe blocked memory layout */
+struct layout_desc_t {
+ data_type_t dt;
+ int ndims;
+ dims_t id;
+ dims_t dims;
+ strides_t strides;
+};
+
+status_t cvt_mem_desc_to_layout_desc(const memory_desc_t &md_,
+ layout_desc_t &ld) {
+ const auto md = memory_desc_wrapper(md_);
+
+ bool ok = true
+ && md.is_blocking_desc()
+ && md.extra().flags == 0;
+ if (!ok) return invalid_arguments;
+
+ const auto &bd = md.blocking_desc();
+
+ ld.ndims = 0;
+ ld.dt = md.data_type();
+
+ auto P = [&ld](int id, int dim, ptrdiff_t stride) {
+ assert((size_t)ld.ndims < sizeof(ld.dims) / sizeof(ld.dims[0]));
+ ld.id[ld.ndims] = id;
+ ld.dims[ld.ndims] = dim;
+ ld.strides[ld.ndims] = stride;
+ ++ld.ndims;
+ };
+
+ dims_t blocks;
+ md.compute_blocks(blocks);
+
+ for (int d = 0; d < md.ndims(); ++d) {
+ const int ld_ndims_start = ld.ndims;
+ if (blocks[d] != 1) {
+ stride_t stride = 1;
+ for (int iblk = bd.inner_nblks - 1; iblk >= 0; --iblk) {
+ if (bd.inner_idxs[iblk] == d)
+ P(d, bd.inner_blks[iblk], stride);
+ stride *= bd.inner_blks[iblk];
+ }
+ }
+ P(d, md.padded_dims()[d] / blocks[d], bd.strides[d]);
+
+ // TODO: NOW: revisit, do we need a reverse?
+ // TODO: NOW: consider using strides instead of block sizes in md
+ // reverse the order of dims
+ for (int ld_d = 0; ld_d < (ld.ndims - ld_ndims_start) / 2; ++ld_d) {
+ const int idx0 = ld_ndims_start + ld_d;
+ const int idx1 = ld.ndims - 1 - ld_d;
+ nstl::swap(ld.dims[idx0], ld.dims[idx1]);
+ nstl::swap(ld.strides[idx0], ld.strides[idx1]);
+ }
+ }
+
+ return success;
+}
+
+status_t prb_init(prb_t &p, const memory_desc_t &imd, const memory_desc_t &omd,
+ const primitive_attr_t *attr) {
+ auto im_d = memory_desc_wrapper(imd);
+ auto om_d = memory_desc_wrapper(omd);
+
+ bool ok = true
+ && im_d.is_blocking_desc()
+ && om_d.is_blocking_desc()
+ && !im_d.has_zero_dim()
+ && !om_d.has_zero_dim();
+ if (!ok)
+ return unimplemented;
+
+ dims_t iblocks, oblocks;
+ im_d.compute_blocks(iblocks);
+ om_d.compute_blocks(oblocks);
+
+ /* padding_dim consistency check */
+ for (int d = 0; d < im_d.ndims(); ++d) {
+ const auto pdim = im_d.padded_dims()[d];
+ bool ok = true
+ && pdim == om_d.padded_dims()[d]
+ && pdim % iblocks[d] == 0
+ && pdim % oblocks[d] == 0;
+ if (!ok) return unimplemented;
+ }
+
+ layout_desc_t ild, old;
+ status_t status = cvt_mem_desc_to_layout_desc(imd, ild);
+ if (status != success) return status;
+ status = cvt_mem_desc_to_layout_desc(omd, old);
+ if (status != success) return status;
+
+ p.itype = ild.dt;
+ p.otype = old.dt;
+
+ p.scale_type = attr->output_scales_.has_default_values()
+ ? scale_type_t::NONE
+ : (attr->output_scales_.mask_ == 0
+ ? scale_type_t::COMMON
+ : scale_type_t::MANY);
+
+ ptrdiff_t ss[max_ndims] = {0};
+ if (p.scale_type == scale_type_t::MANY) {
+ ptrdiff_t last_ss = 1;
+ for (int d = old.ndims - 1; d >=0; --d) {
+ assert((d == 0 || old.id[d - 1] <= old.id[d])
+ && "logical dimensions should be in ascending order");
+ if (attr->output_scales_.mask_ & (1 << old.id[d])) {
+ ss[d] = last_ss;
+ last_ss *= old.dims[d];
+ }
+ }
+ }
+
+ int ndims = 0;
+
+ int i_pos = 0; /* state for input -- current dimension */
+ int o_pos = 0; /* state for output -- current dimension */
+
+ while (i_pos < ild.ndims && o_pos < old.ndims) {
+ assert(ild.id[i_pos] == old.id[o_pos]);
+ if (ild.id[i_pos] != old.id[o_pos])
+ return runtime_error;
+
+ assert(ndims < max_ndims);
+ if (ndims == max_ndims)
+ return runtime_error;
+
+ if (ild.dims[i_pos] == old.dims[o_pos]) {
+ p.nodes[ndims].n = ild.dims[i_pos];
+ p.nodes[ndims].is = ild.strides[i_pos];
+ p.nodes[ndims].os = old.strides[o_pos];
+ p.nodes[ndims].ss = ss[o_pos];
+ ++ndims;
+ ++i_pos;
+ ++o_pos;
+ } else if (ild.dims[i_pos] < old.dims[o_pos]) {
+ assert(old.dims[o_pos] % ild.dims[i_pos] == 0);
+ int factor = old.dims[o_pos] / ild.dims[i_pos];
+ p.nodes[ndims].n = ild.dims[i_pos];
+ p.nodes[ndims].is = ild.strides[i_pos];
+ p.nodes[ndims].os = old.strides[o_pos] * factor;
+ p.nodes[ndims].ss = ss[o_pos] * factor;
+ ++ndims;
+ ++i_pos;
+ old.dims[o_pos] = factor;
+ } else if (ild.dims[i_pos] > old.dims[o_pos]) {
+ assert(ild.dims[i_pos] % old.dims[o_pos] == 0);
+ int factor = ild.dims[i_pos] / old.dims[o_pos];
+ p.nodes[ndims].n = old.dims[o_pos];
+ p.nodes[ndims].is = ild.strides[i_pos] * factor;
+ p.nodes[ndims].os = old.strides[o_pos];
+ p.nodes[ndims].ss = ss[o_pos];
+ ++ndims;
+ ++o_pos;
+ ild.dims[i_pos] = factor;
+ }
+ }
+ p.ndims = ndims;
+
+ dims_t zero_pos = {0};
+ p.ioff = memory_desc_wrapper(imd).off_v(zero_pos);
+ p.ooff = memory_desc_wrapper(omd).off_v(zero_pos);
+
+ const int sum_idx = attr->post_ops_.find(primitive_kind::sum);
+ p.beta = sum_idx == -1 ? 0.f : attr->post_ops_.entry_[sum_idx].sum.scale;
+
+ return success;
+}
+
+void prb_normalize(prb_t &p) {
+ for (int d = 0; d < p.ndims; ++d) {
+ int min_pos = d;
+ for (int j = d + 1; j < p.ndims; ++j) {
+ bool new_min = false
+ || p.nodes[j].os < p.nodes[min_pos].os
+ || (true
+ && p.nodes[j].os == p.nodes[min_pos].os
+ && p.nodes[j].n < p.nodes[min_pos].n);
+ if (new_min) min_pos = j;
+ }
+ if (min_pos != d)
+ nstl::swap(p.nodes[d], p.nodes[min_pos]);
+ }
+}
+
+void prb_simplify(prb_t &p) {
+#if defined(__GNUC__) && __GNUC__ >= 4
+/* GCC produces bogus array subscript is above array bounds warning for
+ * the `p.nodes[j - 1] = p.nodes[j]` line below, so disable it for now. */
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#endif
+ for (int d = 0; d < p.ndims - 1; ++d) {
+ auto &this_node = p.nodes[d + 0];
+ auto &next_node = p.nodes[d + 1];
+ const bool fold = false
+ || next_node.n == (size_t)1 // trivial case, just drop next node
+ || (true // or real folding if possible
+ && next_node.is == (ptrdiff_t)this_node.n * this_node.is
+ && next_node.os == (ptrdiff_t)this_node.n * this_node.os
+ && next_node.ss == (ptrdiff_t)this_node.n * this_node.ss);
+ if (fold) {
+ this_node.n *= next_node.n;
+ for (int j = d + 2; j < p.ndims; ++j)
+ p.nodes[j - 1] = p.nodes[j];
+ --p.ndims;
+ --d; // make another try
+ }
+ }
+#if defined(__GNUC__) && __GNUC__ >= 4
+#pragma GCC diagnostic pop
+#endif
+}
+
+void prb_node_split(prb_t &p, int dim, size_t n1) {
+ assert(dim < p.ndims);
+ assert(p.ndims < max_ndims);
+ assert(p.nodes[dim].n % n1 == 0);
+
+ p.ndims += 1;
+
+ for (int d = p.ndims; d > dim + 1; --d)
+ p.nodes[d] = p.nodes[d - 1];
+
+ p.nodes[dim + 1].n = p.nodes[dim].n / n1;
+ p.nodes[dim + 1].is = p.nodes[dim].is * n1;
+ p.nodes[dim + 1].os = p.nodes[dim].os * n1;
+ p.nodes[dim + 1].ss = p.nodes[dim].ss * n1;
+
+ p.nodes[dim].n = n1;
+}
+
+void prb_node_swap(prb_t &p, int d0, int d1) {
+ assert(d0 < p.ndims);
+ assert(d1 < p.ndims);
+ assert(p.ndims < max_ndims);
+
+ if (d0 == d1) return;
+
+ nstl::swap(p.nodes[d0], p.nodes[d1]);
+}
+
+void prb_node_move(prb_t &p, int d0, int d1) {
+ assert(d0 < p.ndims);
+ assert(d1 < p.ndims);
+ assert(p.ndims < max_ndims);
+
+ if (d0 == d1) return;
+
+ node_t node = p.nodes[d0];
+
+ if (d0 < d1)
+ for (int d = d0; d < d1; ++d)
+ p.nodes[d] = p.nodes[d + 1];
+ else
+ for (int d = d0; d > d1; --d)
+ p.nodes[d] = p.nodes[d - 1];
+
+ p.nodes[d1] = node;
+}
+
+void prb_dump(const prb_t &p) {
+ printf("@@@ type:%s:%s ndims:%d ", mkldnn_dt2str(p.itype),
+ mkldnn_dt2str(p.otype), p.ndims);
+ for (int d = 0; d < p.ndims; ++d)
+ printf("[%zu:%td:%td:%td]",
+ p.nodes[d].n, p.nodes[d].is, p.nodes[d].os, p.nodes[d].ss);
+ printf(" off:%zu:%zu\n", p.ioff, p.ooff);
+}
+
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jit_utils.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jit_utils.cpp
new file mode 100644
index 0000000000..08747aa89c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jit_utils.cpp
@@ -0,0 +1,115 @@
+/*******************************************************************************
+* Copyright 2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <mutex>
+
+#include "utils.hpp"
+
+#ifndef MKLDNN_ENABLE_JIT_PROFILING
+#define MKLDNN_ENABLE_JIT_PROFILING 1
+#endif
+
+#ifndef MKLDNN_ENABLE_JIT_DUMP
+#define MKLDNN_ENABLE_JIT_DUMP 1
+#endif
+
+#if MKLDNN_ENABLE_JIT_PROFILING
+#include "jitprofiling/jitprofiling.h"
+#endif
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+namespace jit_utils {
+
+// WARNING: These functions are not thread safe and must be protected by a
+// mutex
+
+void dump_jit_code(const void *code, size_t code_size, const char *code_name)
+{
+#if MKLDNN_ENABLE_JIT_DUMP
+ if (code && jit_dump_enabled()) {
+ static int counter = 0;
+#define MAX_FNAME_LEN 256
+ char fname[MAX_FNAME_LEN + 1];
+ // TODO (Roma): support prefix for code / linux perf dumps
+ snprintf(fname, MAX_FNAME_LEN, "mkldnn_dump_%s.%d.bin", code_name,
+ counter);
+ counter++;
+
+ FILE *fp = fopen(fname, "w+");
+ // Failure to dump code is not fatal
+ if (fp) {
+ size_t unused = fwrite(code, code_size, 1, fp);
+ UNUSED(unused);
+ fclose(fp);
+ }
+ }
+#undef MAX_FNAME_LEN
+#else
+ UNUSED(code);
+ UNUSED(code_size);
+ UNUSED(code_name);
+#endif
+}
+
+void register_jit_code_vtune(const void *code, size_t code_size,
+ const char *code_name, const char *source_file_name)
+{
+#if MKLDNN_ENABLE_JIT_PROFILING
+ if (iJIT_IsProfilingActive() == iJIT_SAMPLING_ON) {
+ auto jmethod = iJIT_Method_Load();
+ jmethod.method_id = iJIT_GetNewMethodID(); // XXX: not thread-safe
+ jmethod.method_name = (char *)code_name; // XXX: dropping const
+ jmethod.class_file_name = NULL;
+ jmethod.source_file_name = (char *)source_file_name; // XXX: dropping const
+ jmethod.method_load_address = (void *)code;
+ jmethod.method_size = (unsigned int)code_size;
+
+ iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED,
+ (void*)&jmethod);
+ }
+#else
+ UNUSED(code);
+ UNUSED(code_size);
+ UNUSED(code_name);
+ UNUSED(source_file_name);
+#endif
+}
+
+void register_jit_code(const void *code, size_t code_size,
+ const char *code_name, const char *source_file_name)
+{
+ // The #ifdef guards are required to avoid generating a function that only
+ // consists of lock and unlock code
+#if MKLDNN_ENABLE_JIT_PROFILING || MKLDNN_ENABLE_JIT_DUMP
+ static std::mutex m;
+ std::lock_guard<std::mutex> guard(m);
+
+ dump_jit_code(code, code_size, code_name);
+ register_jit_code_vtune(code, code_size, code_name, source_file_name);
+#else
+ UNUSED(code);
+ UNUSED(code_size);
+ UNUSED(code_name);
+ UNUSED(source_file_name);
+#endif
+}
+
+}
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jit_utils.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jit_utils.hpp
new file mode 100644
index 0000000000..2f52dba4ac
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jit_utils.hpp
@@ -0,0 +1,32 @@
+/*******************************************************************************
+* Copyright 2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef JIT_SUPPORT_HPP
+#define JIT_SUPPORT_HPP
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+namespace jit_utils {
+
+void register_jit_code(const void *code, size_t code_size,
+ const char *code_name, const char *source_file_name);
+
+}
+}
+}
+}
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/LICENSE.BSD b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/LICENSE.BSD
new file mode 100644
index 0000000000..4fd21cea57
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/LICENSE.BSD
@@ -0,0 +1,27 @@
+Copyright (c) 2011, Intel Corporation
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/README.md b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/README.md
new file mode 100644
index 0000000000..fc67c4f134
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/README.md
@@ -0,0 +1 @@
+This code is from [Intel SEAPI library](https://github.com/intel/IntelSEAPI)
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/ittnotify_config.h b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/ittnotify_config.h
new file mode 100644
index 0000000000..edbf4a15f0
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/ittnotify_config.h
@@ -0,0 +1,595 @@
+/* <copyright>
+
+ Contact Information:
+ http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/
+
+ BSD LICENSE
+
+ Copyright (c) 2005-2014 Intel Corporation. All rights reserved.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</copyright> */
+#ifndef _ITTNOTIFY_CONFIG_H_
+#define _ITTNOTIFY_CONFIG_H_
+
+/** @cond exclude_from_documentation */
+#ifndef ITT_OS_WIN
+# define ITT_OS_WIN 1
+#endif /* ITT_OS_WIN */
+
+#ifndef ITT_OS_LINUX
+# define ITT_OS_LINUX 2
+#endif /* ITT_OS_LINUX */
+
+#ifndef ITT_OS_MAC
+# define ITT_OS_MAC 3
+#endif /* ITT_OS_MAC */
+
+#ifndef ITT_OS_FREEBSD
+# define ITT_OS_FREEBSD 4
+#endif /* ITT_OS_FREEBSD */
+
+#ifndef ITT_OS
+# if defined WIN32 || defined _WIN32
+# define ITT_OS ITT_OS_WIN
+# elif defined( __APPLE__ ) && defined( __MACH__ )
+# define ITT_OS ITT_OS_MAC
+# elif defined( __FreeBSD__ )
+# define ITT_OS ITT_OS_FREEBSD
+# else
+# define ITT_OS ITT_OS_LINUX
+# endif
+#endif /* ITT_OS */
+
+#ifndef ITT_PLATFORM_WIN
+# define ITT_PLATFORM_WIN 1
+#endif /* ITT_PLATFORM_WIN */
+
+#ifndef ITT_PLATFORM_POSIX
+# define ITT_PLATFORM_POSIX 2
+#endif /* ITT_PLATFORM_POSIX */
+
+#ifndef ITT_PLATFORM_MAC
+# define ITT_PLATFORM_MAC 3
+#endif /* ITT_PLATFORM_MAC */
+
+#ifndef ITT_PLATFORM_FREEBSD
+# define ITT_PLATFORM_FREEBSD 4
+#endif /* ITT_PLATFORM_FREEBSD */
+
+#ifndef ITT_PLATFORM
+# if ITT_OS==ITT_OS_WIN
+# define ITT_PLATFORM ITT_PLATFORM_WIN
+# elif ITT_OS==ITT_OS_MAC
+# define ITT_PLATFORM ITT_PLATFORM_MAC
+# elif ITT_OS==ITT_OS_FREEBSD
+# define ITT_PLATFORM ITT_PLATFORM_FREEBSD
+# else
+# define ITT_PLATFORM ITT_PLATFORM_POSIX
+# endif
+#endif /* ITT_PLATFORM */
+
+#if defined(_UNICODE) && !defined(UNICODE)
+#define UNICODE
+#endif
+
+#include <stddef.h>
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+#include <tchar.h>
+#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+#include <stdint.h>
+#if defined(UNICODE) || defined(_UNICODE)
+#include <wchar.h>
+#endif /* UNICODE || _UNICODE */
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+
+#ifndef ITTAPI_CDECL
+# if ITT_PLATFORM==ITT_PLATFORM_WIN
+# define ITTAPI_CDECL __cdecl
+# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+# if defined _M_IX86 || defined __i386__
+# define ITTAPI_CDECL __attribute__ ((cdecl))
+# else /* _M_IX86 || __i386__ */
+# define ITTAPI_CDECL /* actual only on x86 platform */
+# endif /* _M_IX86 || __i386__ */
+# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+#endif /* ITTAPI_CDECL */
+
+#ifndef STDCALL
+# if ITT_PLATFORM==ITT_PLATFORM_WIN
+# define STDCALL __stdcall
+# else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+# if defined _M_IX86 || defined __i386__
+# define STDCALL __attribute__ ((stdcall))
+# else /* _M_IX86 || __i386__ */
+# define STDCALL /* supported only on x86 platform */
+# endif /* _M_IX86 || __i386__ */
+# endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+#endif /* STDCALL */
+
+#define ITTAPI ITTAPI_CDECL
+#define LIBITTAPI ITTAPI_CDECL
+
+/* TODO: Temporary for compatibility! */
+#define ITTAPI_CALL ITTAPI_CDECL
+#define LIBITTAPI_CALL ITTAPI_CDECL
+
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+/* use __forceinline (VC++ specific) */
+#define ITT_INLINE __forceinline
+#define ITT_INLINE_ATTRIBUTE /* nothing */
+#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+/*
+ * Generally, functions are not inlined unless optimization is specified.
+ * For functions declared inline, this attribute inlines the function even
+ * if no optimization level was specified.
+ */
+#ifdef __STRICT_ANSI__
+#define ITT_INLINE static
+#define ITT_INLINE_ATTRIBUTE __attribute__((unused))
+#else /* __STRICT_ANSI__ */
+#define ITT_INLINE static inline
+#define ITT_INLINE_ATTRIBUTE __attribute__((always_inline, unused))
+#endif /* __STRICT_ANSI__ */
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+/** @endcond */
+
+#ifndef ITT_ARCH_IA32
+# define ITT_ARCH_IA32 1
+#endif /* ITT_ARCH_IA32 */
+
+#ifndef ITT_ARCH_IA32E
+# define ITT_ARCH_IA32E 2
+#endif /* ITT_ARCH_IA32E */
+
+#ifndef ITT_ARCH_ARM
+# define ITT_ARCH_ARM 4
+#endif /* ITT_ARCH_ARM */
+
+#ifndef ITT_ARCH_PPC64
+# define ITT_ARCH_PPC64 5
+#endif /* ITT_ARCH_PPC64 */
+
+#ifndef ITT_ARCH
+# if defined _M_IX86 || defined __i386__
+# define ITT_ARCH ITT_ARCH_IA32
+# elif defined _M_X64 || defined _M_AMD64 || defined __x86_64__
+# define ITT_ARCH ITT_ARCH_IA32E
+# elif defined _M_IA64 || defined __ia64__
+# define ITT_ARCH ITT_ARCH_IA64
+# elif defined _M_ARM || defined __arm__
+# define ITT_ARCH ITT_ARCH_ARM
+# elif defined __powerpc64__
+# define ITT_ARCH ITT_ARCH_PPC64
+# endif
+#endif
+
+#ifdef __cplusplus
+# define ITT_EXTERN_C extern "C"
+# define ITT_EXTERN_C_BEGIN extern "C" {
+# define ITT_EXTERN_C_END }
+#else
+# define ITT_EXTERN_C /* nothing */
+# define ITT_EXTERN_C_BEGIN /* nothing */
+# define ITT_EXTERN_C_END /* nothing */
+#endif /* __cplusplus */
+
+#define ITT_TO_STR_AUX(x) #x
+#define ITT_TO_STR(x) ITT_TO_STR_AUX(x)
+
+#define __ITT_BUILD_ASSERT(expr, suffix) do { \
+ static char __itt_build_check_##suffix[(expr) ? 1 : -1]; \
+ __itt_build_check_##suffix[0] = 0; \
+} while(0)
+#define _ITT_BUILD_ASSERT(expr, suffix) __ITT_BUILD_ASSERT((expr), suffix)
+#define ITT_BUILD_ASSERT(expr) _ITT_BUILD_ASSERT((expr), __LINE__)
+
+#define ITT_MAGIC { 0xED, 0xAB, 0xAB, 0xEC, 0x0D, 0xEE, 0xDA, 0x30 }
+
+/* Replace with snapshot date YYYYMMDD for promotion build. */
+#define API_VERSION_BUILD 20151119
+
+#ifndef API_VERSION_NUM
+#define API_VERSION_NUM 0.0.0
+#endif /* API_VERSION_NUM */
+
+#define API_VERSION "ITT-API-Version " ITT_TO_STR(API_VERSION_NUM) \
+ " (" ITT_TO_STR(API_VERSION_BUILD) ")"
+
+/* OS communication functions */
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+#include <windows.h>
+typedef HMODULE lib_t;
+typedef DWORD TIDT;
+typedef CRITICAL_SECTION mutex_t;
+#define MUTEX_INITIALIZER { 0 }
+#define strong_alias(name, aliasname) /* empty for Windows */
+#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+#include <dlfcn.h>
+#if defined(UNICODE) || defined(_UNICODE)
+#include <wchar.h>
+#endif /* UNICODE */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1 /* need for PTHREAD_MUTEX_RECURSIVE */
+#endif /* _GNU_SOURCE */
+#ifndef __USE_UNIX98
+#define __USE_UNIX98 1 /* need for PTHREAD_MUTEX_RECURSIVE, on SLES11.1 with gcc 4.3.4 wherein pthread.h missing dependency on __USE_XOPEN2K8 */
+#endif /*__USE_UNIX98*/
+#include <pthread.h>
+typedef void* lib_t;
+typedef pthread_t TIDT;
+typedef pthread_mutex_t mutex_t;
+#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+#define _strong_alias(name, aliasname) \
+ extern __typeof (name) aliasname __attribute__ ((alias (#name)));
+#define strong_alias(name, aliasname) _strong_alias(name, aliasname)
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+#define __itt_get_proc(lib, name) GetProcAddress(lib, name)
+#define __itt_mutex_init(mutex) InitializeCriticalSection(mutex)
+#define __itt_mutex_lock(mutex) EnterCriticalSection(mutex)
+#define __itt_mutex_unlock(mutex) LeaveCriticalSection(mutex)
+#define __itt_load_lib(name) LoadLibraryA(name)
+#define __itt_unload_lib(handle) FreeLibrary(handle)
+#define __itt_system_error() (int)GetLastError()
+#define __itt_fstrcmp(s1, s2) lstrcmpA(s1, s2)
+#define __itt_fstrnlen(s, l) strnlen_s(s, l)
+#define __itt_fstrcpyn(s1, b, s2, l) strncpy_s(s1, b, s2, l)
+#define __itt_fstrdup(s) _strdup(s)
+#define __itt_thread_id() GetCurrentThreadId()
+#define __itt_thread_yield() SwitchToThread()
+#ifndef ITT_SIMPLE_INIT
+ITT_INLINE long
+__itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE;
+ITT_INLINE long __itt_interlocked_increment(volatile long* ptr)
+{
+ return InterlockedIncrement(ptr);
+}
+#endif /* ITT_SIMPLE_INIT */
+
+#define DL_SYMBOLS (1)
+#define PTHREAD_SYMBOLS (1)
+
+#else /* ITT_PLATFORM!=ITT_PLATFORM_WIN */
+#define __itt_get_proc(lib, name) dlsym(lib, name)
+#define __itt_mutex_init(mutex) {\
+ pthread_mutexattr_t mutex_attr; \
+ int error_code = pthread_mutexattr_init(&mutex_attr); \
+ if (error_code) \
+ __itt_report_error(__itt_error_system, "pthread_mutexattr_init", \
+ error_code); \
+ error_code = pthread_mutexattr_settype(&mutex_attr, \
+ PTHREAD_MUTEX_RECURSIVE); \
+ if (error_code) \
+ __itt_report_error(__itt_error_system, "pthread_mutexattr_settype", \
+ error_code); \
+ error_code = pthread_mutex_init(mutex, &mutex_attr); \
+ if (error_code) \
+ __itt_report_error(__itt_error_system, "pthread_mutex_init", \
+ error_code); \
+ error_code = pthread_mutexattr_destroy(&mutex_attr); \
+ if (error_code) \
+ __itt_report_error(__itt_error_system, "pthread_mutexattr_destroy", \
+ error_code); \
+}
+#define __itt_mutex_lock(mutex) pthread_mutex_lock(mutex)
+#define __itt_mutex_unlock(mutex) pthread_mutex_unlock(mutex)
+#define __itt_load_lib(name) dlopen(name, RTLD_LAZY)
+#define __itt_unload_lib(handle) dlclose(handle)
+#define __itt_system_error() errno
+#define __itt_fstrcmp(s1, s2) strcmp(s1, s2)
+
+/* makes customer code define safe APIs for SDL_STRNLEN_S and SDL_STRNCPY_S */
+#ifdef SDL_STRNLEN_S
+#define __itt_fstrnlen(s, l) SDL_STRNLEN_S(s, l)
+#else
+#define __itt_fstrnlen(s, l) strlen(s)
+#endif /* SDL_STRNLEN_S */
+#ifdef SDL_STRNCPY_S
+#define __itt_fstrcpyn(s1, b, s2, l) SDL_STRNCPY_S(s1, b, s2, l)
+#else
+#define __itt_fstrcpyn(s1, b, s2, l) strncpy(s1, s2, l)
+#endif /* SDL_STRNCPY_S */
+
+#define __itt_fstrdup(s) strdup(s)
+#define __itt_thread_id() pthread_self()
+#define __itt_thread_yield() sched_yield()
+#if ITT_ARCH==ITT_ARCH_IA64
+#ifdef __INTEL_COMPILER
+#define __TBB_machine_fetchadd4(addr, val) __fetchadd4_acq((void *)addr, val)
+#else /* __INTEL_COMPILER */
+/* TODO: Add Support for not Intel compilers for IA-64 architecture */
+#endif /* __INTEL_COMPILER */
+#elif ITT_ARCH==ITT_ARCH_IA32 || ITT_ARCH==ITT_ARCH_IA32E /* ITT_ARCH!=ITT_ARCH_IA64 */
+ITT_INLINE long
+__TBB_machine_fetchadd4(volatile void* ptr, long addend) ITT_INLINE_ATTRIBUTE;
+ITT_INLINE long __TBB_machine_fetchadd4(volatile void* ptr, long addend)
+{
+ long result;
+ __asm__ __volatile__("lock\nxadd %0,%1"
+ : "=r"(result),"=m"(*(int*)ptr)
+ : "0"(addend), "m"(*(int*)ptr)
+ : "memory");
+ return result;
+}
+#elif ITT_ARCH==ITT_ARCH_ARM || ITT_ARCH==ITT_ARCH_PPC64
+#define __TBB_machine_fetchadd4(addr, val) __sync_fetch_and_add(addr, val)
+#endif /* ITT_ARCH==ITT_ARCH_IA64 */
+#ifndef ITT_SIMPLE_INIT
+ITT_INLINE long
+__itt_interlocked_increment(volatile long* ptr) ITT_INLINE_ATTRIBUTE;
+ITT_INLINE long __itt_interlocked_increment(volatile long* ptr)
+{
+ return __TBB_machine_fetchadd4(ptr, 1) + 1L;
+}
+#endif /* ITT_SIMPLE_INIT */
+
+void* dlopen(const char*, int) __attribute__((weak));
+void* dlsym(void*, const char*) __attribute__((weak));
+int dlclose(void*) __attribute__((weak));
+#define DL_SYMBOLS (dlopen && dlsym && dlclose)
+
+int pthread_mutex_init(pthread_mutex_t*, const pthread_mutexattr_t*) __attribute__((weak));
+int pthread_mutex_lock(pthread_mutex_t*) __attribute__((weak));
+int pthread_mutex_unlock(pthread_mutex_t*) __attribute__((weak));
+int pthread_mutex_destroy(pthread_mutex_t*) __attribute__((weak));
+int pthread_mutexattr_init(pthread_mutexattr_t*) __attribute__((weak));
+int pthread_mutexattr_settype(pthread_mutexattr_t*, int) __attribute__((weak));
+int pthread_mutexattr_destroy(pthread_mutexattr_t*) __attribute__((weak));
+pthread_t pthread_self(void) __attribute__((weak));
+#define PTHREAD_SYMBOLS (pthread_mutex_init && pthread_mutex_lock && pthread_mutex_unlock && pthread_mutex_destroy && pthread_mutexattr_init && pthread_mutexattr_settype && pthread_mutexattr_destroy && pthread_self)
+
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+
+typedef enum {
+ __itt_collection_normal = 0,
+ __itt_collection_paused = 1
+} __itt_collection_state;
+
+typedef enum {
+ __itt_thread_normal = 0,
+ __itt_thread_ignored = 1
+} __itt_thread_state;
+
+#pragma pack(push, 8)
+
+typedef struct ___itt_thread_info
+{
+ const char* nameA; /*!< Copy of original name in ASCII. */
+#if defined(UNICODE) || defined(_UNICODE)
+ const wchar_t* nameW; /*!< Copy of original name in UNICODE. */
+#else /* UNICODE || _UNICODE */
+ void* nameW;
+#endif /* UNICODE || _UNICODE */
+ TIDT tid;
+ __itt_thread_state state; /*!< Thread state (paused or normal) */
+ int extra1; /*!< Reserved to the runtime */
+ void* extra2; /*!< Reserved to the runtime */
+ struct ___itt_thread_info* next;
+} __itt_thread_info;
+
+#include "ittnotify_types.h" /* For __itt_group_id definition */
+
+typedef struct ___itt_api_info_20101001
+{
+ const char* name;
+ void** func_ptr;
+ void* init_func;
+ __itt_group_id group;
+} __itt_api_info_20101001;
+
+typedef struct ___itt_api_info
+{
+ const char* name;
+ void** func_ptr;
+ void* init_func;
+ void* null_func;
+ __itt_group_id group;
+} __itt_api_info;
+
+typedef struct __itt_counter_info
+{
+ const char* nameA; /*!< Copy of original name in ASCII. */
+#if defined(UNICODE) || defined(_UNICODE)
+ const wchar_t* nameW; /*!< Copy of original name in UNICODE. */
+#else /* UNICODE || _UNICODE */
+ void* nameW;
+#endif /* UNICODE || _UNICODE */
+ const char* domainA; /*!< Copy of original name in ASCII. */
+#if defined(UNICODE) || defined(_UNICODE)
+ const wchar_t* domainW; /*!< Copy of original name in UNICODE. */
+#else /* UNICODE || _UNICODE */
+ void* domainW;
+#endif /* UNICODE || _UNICODE */
+ int type;
+ long index;
+ int extra1; /*!< Reserved to the runtime */
+ void* extra2; /*!< Reserved to the runtime */
+ struct __itt_counter_info* next;
+} __itt_counter_info_t;
+
+struct ___itt_domain;
+struct ___itt_string_handle;
+
+typedef struct ___itt_global
+{
+ unsigned char magic[8];
+ unsigned long version_major;
+ unsigned long version_minor;
+ unsigned long version_build;
+ volatile long api_initialized;
+ volatile long mutex_initialized;
+ volatile long atomic_counter;
+ mutex_t mutex;
+ lib_t lib;
+ void* error_handler;
+ const char** dll_path_ptr;
+ __itt_api_info* api_list_ptr;
+ struct ___itt_global* next;
+ /* Joinable structures below */
+ __itt_thread_info* thread_list;
+ struct ___itt_domain* domain_list;
+ struct ___itt_string_handle* string_list;
+ __itt_collection_state state;
+ __itt_counter_info_t* counter_list;
+} __itt_global;
+
+#pragma pack(pop)
+
+#define NEW_THREAD_INFO_W(gptr,h,h_tail,t,s,n) { \
+ h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \
+ if (h != NULL) { \
+ h->tid = t; \
+ h->nameA = NULL; \
+ h->nameW = n ? _wcsdup(n) : NULL; \
+ h->state = s; \
+ h->extra1 = 0; /* reserved */ \
+ h->extra2 = NULL; /* reserved */ \
+ h->next = NULL; \
+ if (h_tail == NULL) \
+ (gptr)->thread_list = h; \
+ else \
+ h_tail->next = h; \
+ } \
+}
+
+#define NEW_THREAD_INFO_A(gptr,h,h_tail,t,s,n) { \
+ h = (__itt_thread_info*)malloc(sizeof(__itt_thread_info)); \
+ if (h != NULL) { \
+ h->tid = t; \
+ h->nameA = n ? __itt_fstrdup(n) : NULL; \
+ h->nameW = NULL; \
+ h->state = s; \
+ h->extra1 = 0; /* reserved */ \
+ h->extra2 = NULL; /* reserved */ \
+ h->next = NULL; \
+ if (h_tail == NULL) \
+ (gptr)->thread_list = h; \
+ else \
+ h_tail->next = h; \
+ } \
+}
+
+#define NEW_DOMAIN_W(gptr,h,h_tail,name) { \
+ h = (__itt_domain*)malloc(sizeof(__itt_domain)); \
+ if (h != NULL) { \
+ h->flags = 1; /* domain is enabled by default */ \
+ h->nameA = NULL; \
+ h->nameW = name ? _wcsdup(name) : NULL; \
+ h->extra1 = 0; /* reserved */ \
+ h->extra2 = NULL; /* reserved */ \
+ h->next = NULL; \
+ if (h_tail == NULL) \
+ (gptr)->domain_list = h; \
+ else \
+ h_tail->next = h; \
+ } \
+}
+
+#define NEW_DOMAIN_A(gptr,h,h_tail,name) { \
+ h = (__itt_domain*)malloc(sizeof(__itt_domain)); \
+ if (h != NULL) { \
+ h->flags = 1; /* domain is enabled by default */ \
+ h->nameA = name ? __itt_fstrdup(name) : NULL; \
+ h->nameW = NULL; \
+ h->extra1 = 0; /* reserved */ \
+ h->extra2 = NULL; /* reserved */ \
+ h->next = NULL; \
+ if (h_tail == NULL) \
+ (gptr)->domain_list = h; \
+ else \
+ h_tail->next = h; \
+ } \
+}
+
+#define NEW_STRING_HANDLE_W(gptr,h,h_tail,name) { \
+ h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \
+ if (h != NULL) { \
+ h->strA = NULL; \
+ h->strW = name ? _wcsdup(name) : NULL; \
+ h->extra1 = 0; /* reserved */ \
+ h->extra2 = NULL; /* reserved */ \
+ h->next = NULL; \
+ if (h_tail == NULL) \
+ (gptr)->string_list = h; \
+ else \
+ h_tail->next = h; \
+ } \
+}
+
+#define NEW_STRING_HANDLE_A(gptr,h,h_tail,name) { \
+ h = (__itt_string_handle*)malloc(sizeof(__itt_string_handle)); \
+ if (h != NULL) { \
+ h->strA = name ? __itt_fstrdup(name) : NULL; \
+ h->strW = NULL; \
+ h->extra1 = 0; /* reserved */ \
+ h->extra2 = NULL; /* reserved */ \
+ h->next = NULL; \
+ if (h_tail == NULL) \
+ (gptr)->string_list = h; \
+ else \
+ h_tail->next = h; \
+ } \
+}
+
+#define NEW_COUNTER_W(gptr,h,h_tail,name,domain,type) { \
+ h = (__itt_counter_info_t*)malloc(sizeof(__itt_counter_info_t)); \
+ if (h != NULL) { \
+ h->nameA = NULL; \
+ h->nameW = name ? _wcsdup(name) : NULL; \
+ h->domainA = NULL; \
+ h->domainW = name ? _wcsdup(domain) : NULL; \
+ h->type = type; \
+ h->index = 0; \
+ h->next = NULL; \
+ if (h_tail == NULL) \
+ (gptr)->counter_list = h; \
+ else \
+ h_tail->next = h; \
+ } \
+}
+
+#define NEW_COUNTER_A(gptr,h,h_tail,name,domain,type) { \
+ h = (__itt_counter_info_t*)malloc(sizeof(__itt_counter_info_t)); \
+ if (h != NULL) { \
+ h->nameA = name ? __itt_fstrdup(name) : NULL; \
+ h->nameW = NULL; \
+ h->domainA = domain ? __itt_fstrdup(domain) : NULL; \
+ h->domainW = NULL; \
+ h->type = type; \
+ h->index = 0; \
+ h->next = NULL; \
+ if (h_tail == NULL) \
+ (gptr)->counter_list = h; \
+ else \
+ h_tail->next = h; \
+ } \
+}
+
+#endif /* _ITTNOTIFY_CONFIG_H_ */
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/ittnotify_types.h b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/ittnotify_types.h
new file mode 100644
index 0000000000..99fbc24054
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/ittnotify_types.h
@@ -0,0 +1,94 @@
+/* <copyright>
+
+ Contact Information:
+ http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/
+
+ BSD LICENSE
+
+ Copyright (c) 2005-2014 Intel Corporation. All rights reserved.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</copyright> */
+
+#ifndef _ITTNOTIFY_TYPES_H_
+#define _ITTNOTIFY_TYPES_H_
+
+typedef enum ___itt_group_id
+{
+ __itt_group_none = 0,
+ __itt_group_legacy = 1<<0,
+ __itt_group_control = 1<<1,
+ __itt_group_thread = 1<<2,
+ __itt_group_mark = 1<<3,
+ __itt_group_sync = 1<<4,
+ __itt_group_fsync = 1<<5,
+ __itt_group_jit = 1<<6,
+ __itt_group_model = 1<<7,
+ __itt_group_splitter_min = 1<<7,
+ __itt_group_counter = 1<<8,
+ __itt_group_frame = 1<<9,
+ __itt_group_stitch = 1<<10,
+ __itt_group_heap = 1<<11,
+ __itt_group_splitter_max = 1<<12,
+ __itt_group_structure = 1<<12,
+ __itt_group_suppress = 1<<13,
+ __itt_group_arrays = 1<<14,
+ __itt_group_all = -1
+} __itt_group_id;
+
+#pragma pack(push, 8)
+
+typedef struct ___itt_group_list
+{
+ __itt_group_id id;
+ const char* name;
+} __itt_group_list;
+
+#pragma pack(pop)
+
+#define ITT_GROUP_LIST(varname) \
+ static __itt_group_list varname[] = { \
+ { __itt_group_all, "all" }, \
+ { __itt_group_control, "control" }, \
+ { __itt_group_thread, "thread" }, \
+ { __itt_group_mark, "mark" }, \
+ { __itt_group_sync, "sync" }, \
+ { __itt_group_fsync, "fsync" }, \
+ { __itt_group_jit, "jit" }, \
+ { __itt_group_model, "model" }, \
+ { __itt_group_counter, "counter" }, \
+ { __itt_group_frame, "frame" }, \
+ { __itt_group_stitch, "stitch" }, \
+ { __itt_group_heap, "heap" }, \
+ { __itt_group_structure, "structure" }, \
+ { __itt_group_suppress, "suppress" }, \
+ { __itt_group_arrays, "arrays" }, \
+ { __itt_group_none, NULL } \
+ }
+
+#endif /* _ITTNOTIFY_TYPES_H_ */
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/jitprofiling.c b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/jitprofiling.c
new file mode 100644
index 0000000000..15f4b9929b
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/jitprofiling.c
@@ -0,0 +1,293 @@
+/* <copyright>
+
+ Contact Information:
+ http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/
+
+ BSD LICENSE
+
+ Copyright (c) 2005-2014 Intel Corporation. All rights reserved.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</copyright> */
+
+#include "ittnotify_config.h"
+
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+#include <windows.h>
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+#if ITT_PLATFORM != ITT_PLATFORM_MAC && ITT_PLATFORM != ITT_PLATFORM_FREEBSD
+#include <malloc.h>
+#endif
+#include <stdlib.h>
+
+#include "jitprofiling.h"
+
+static const char rcsid[] = "\n@(#) $Revision: 471937 $\n";
+
+#define DLL_ENVIRONMENT_VAR "VS_PROFILER"
+
+#ifndef NEW_DLL_ENVIRONMENT_VAR
+#if ITT_ARCH==ITT_ARCH_IA32
+#define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER32"
+#else
+#define NEW_DLL_ENVIRONMENT_VAR "INTEL_JIT_PROFILER64"
+#endif
+#endif /* NEW_DLL_ENVIRONMENT_VAR */
+
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+#define DEFAULT_DLLNAME "JitPI.dll"
+HINSTANCE m_libHandle = NULL;
+#elif ITT_PLATFORM==ITT_PLATFORM_MAC
+#define DEFAULT_DLLNAME "libJitPI.dylib"
+void* m_libHandle = NULL;
+#else
+#define DEFAULT_DLLNAME "libJitPI.so"
+void* m_libHandle = NULL;
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+
+/* default location of JIT profiling agent on Android */
+#define ANDROID_JIT_AGENT_PATH "/data/intel/libittnotify.so"
+
+/* the function pointers */
+typedef unsigned int(JITAPI *TPInitialize)(void);
+static TPInitialize FUNC_Initialize=NULL;
+
+typedef unsigned int(JITAPI *TPNotify)(unsigned int, void*);
+static TPNotify FUNC_NotifyEvent=NULL;
+
+static iJIT_IsProfilingActiveFlags executionMode = iJIT_NOTHING_RUNNING;
+
+/* end collector dll part. */
+
+/* loadiJIT_Funcs() : this function is called just in the beginning
+ * and is responsible to load the functions from BistroJavaCollector.dll
+ * result:
+ * on success: the functions loads, iJIT_DLL_is_missing=0, return value = 1
+ * on failure: the functions are NULL, iJIT_DLL_is_missing=1, return value = 0
+ */
+static int loadiJIT_Funcs(void);
+
+/* global representing whether the collector can't be loaded */
+static int iJIT_DLL_is_missing = 0;
+
+ITT_EXTERN_C int JITAPI
+iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData)
+{
+ int ReturnValue = 0;
+
+ /* initialization part - the collector has not been loaded yet. */
+ if (!FUNC_NotifyEvent)
+ {
+ if (iJIT_DLL_is_missing)
+ return 0;
+
+ if (!loadiJIT_Funcs())
+ return 0;
+ }
+
+ if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED ||
+ event_type == iJVM_EVENT_TYPE_METHOD_UPDATE)
+ {
+ if (((piJIT_Method_Load)EventSpecificData)->method_id == 0)
+ return 0;
+ }
+ else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2)
+ {
+ if (((piJIT_Method_Load_V2)EventSpecificData)->method_id == 0)
+ return 0;
+ }
+ else if (event_type == iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V3)
+ {
+ if (((piJIT_Method_Load_V3)EventSpecificData)->method_id == 0)
+ return 0;
+ }
+ else if (event_type == iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED)
+ {
+ if (((piJIT_Method_Inline_Load)EventSpecificData)->method_id == 0 ||
+ ((piJIT_Method_Inline_Load)EventSpecificData)->parent_method_id == 0)
+ return 0;
+ }
+
+ ReturnValue = (int)FUNC_NotifyEvent(event_type, EventSpecificData);
+
+ return ReturnValue;
+}
+
+ITT_EXTERN_C iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive()
+{
+ if (!iJIT_DLL_is_missing)
+ {
+ loadiJIT_Funcs();
+ }
+
+ return executionMode;
+}
+
+/* This function loads the collector dll and the relevant functions.
+ * on success: all functions load, iJIT_DLL_is_missing = 0, return value = 1
+ * on failure: all functions are NULL, iJIT_DLL_is_missing = 1, return value = 0
+ */
+static int loadiJIT_Funcs()
+{
+ static int bDllWasLoaded = 0;
+ char *dllName = (char*)rcsid; /* !! Just to avoid unused code elimination */
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+ DWORD dNameLength = 0;
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+
+ if(bDllWasLoaded)
+ {
+ /* dll was already loaded, no need to do it for the second time */
+ return 1;
+ }
+
+ /* Assumes that the DLL will not be found */
+ iJIT_DLL_is_missing = 1;
+ FUNC_NotifyEvent = NULL;
+
+ if (m_libHandle)
+ {
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+ FreeLibrary(m_libHandle);
+#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+ dlclose(m_libHandle);
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+ m_libHandle = NULL;
+ }
+
+ /* Try to get the dll name from the environment */
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+ dNameLength = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR, NULL, 0);
+ if (dNameLength)
+ {
+ DWORD envret = 0;
+ dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
+ if(dllName != NULL)
+ {
+ envret = GetEnvironmentVariableA(NEW_DLL_ENVIRONMENT_VAR,
+ dllName, dNameLength);
+ if (envret)
+ {
+ /* Try to load the dll from the PATH... */
+ m_libHandle = LoadLibraryExA(dllName,
+ NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
+ }
+ free(dllName);
+ }
+ } else {
+ /* Try to use old VS_PROFILER variable */
+ dNameLength = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR, NULL, 0);
+ if (dNameLength)
+ {
+ DWORD envret = 0;
+ dllName = (char*)malloc(sizeof(char) * (dNameLength + 1));
+ if(dllName != NULL)
+ {
+ envret = GetEnvironmentVariableA(DLL_ENVIRONMENT_VAR,
+ dllName, dNameLength);
+ if (envret)
+ {
+ /* Try to load the dll from the PATH... */
+ m_libHandle = LoadLibraryA(dllName);
+ }
+ free(dllName);
+ }
+ }
+ }
+#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+ dllName = getenv(NEW_DLL_ENVIRONMENT_VAR);
+ if (!dllName)
+ dllName = getenv(DLL_ENVIRONMENT_VAR);
+#if defined(__ANDROID__) || defined(ANDROID)
+ if (!dllName)
+ dllName = ANDROID_JIT_AGENT_PATH;
+#endif
+ if (dllName)
+ {
+ /* Try to load the dll from the PATH... */
+ m_libHandle = dlopen(dllName, RTLD_LAZY);
+ }
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+
+ if (!m_libHandle)
+ {
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+ m_libHandle = LoadLibraryA(DEFAULT_DLLNAME);
+#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+ m_libHandle = dlopen(DEFAULT_DLLNAME, RTLD_LAZY);
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+ }
+
+ /* if the dll wasn't loaded - exit. */
+ if (!m_libHandle)
+ {
+ iJIT_DLL_is_missing = 1; /* don't try to initialize
+ * JIT agent the second time
+ */
+ return 0;
+ }
+
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+ FUNC_NotifyEvent = (TPNotify)GetProcAddress(m_libHandle, "NotifyEvent");
+#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+ FUNC_NotifyEvent = (TPNotify)dlsym(m_libHandle, "NotifyEvent");
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+ if (!FUNC_NotifyEvent)
+ {
+ FUNC_Initialize = NULL;
+ return 0;
+ }
+
+#if ITT_PLATFORM==ITT_PLATFORM_WIN
+ FUNC_Initialize = (TPInitialize)GetProcAddress(m_libHandle, "Initialize");
+#else /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+ FUNC_Initialize = (TPInitialize)dlsym(m_libHandle, "Initialize");
+#endif /* ITT_PLATFORM==ITT_PLATFORM_WIN */
+ if (!FUNC_Initialize)
+ {
+ FUNC_NotifyEvent = NULL;
+ return 0;
+ }
+
+ executionMode = (iJIT_IsProfilingActiveFlags)FUNC_Initialize();
+
+ bDllWasLoaded = 1;
+ iJIT_DLL_is_missing = 0; /* DLL is ok. */
+
+ return 1;
+}
+
+ITT_EXTERN_C unsigned int JITAPI iJIT_GetNewMethodID()
+{
+ static unsigned int methodID = 1;
+
+ if (methodID == 0)
+ return 0; /* ERROR : this is not a valid value */
+
+ return methodID++;
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/jitprofiling.h b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/jitprofiling.h
new file mode 100644
index 0000000000..bf0489b1a1
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/jit_utils/jitprofiling/jitprofiling.h
@@ -0,0 +1,673 @@
+/* <copyright>
+
+ Contact Information:
+ http://software.intel.com/en-us/articles/intel-vtune-amplifier-xe/
+
+ BSD LICENSE
+
+ Copyright (c) 2005-2014 Intel Corporation. All rights reserved.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ * Neither the name of Intel Corporation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+</copyright> */
+
+#ifndef __JITPROFILING_H__
+#define __JITPROFILING_H__
+
+/**
+ * @brief JIT Profiling APIs
+ *
+ * The JIT Profiling API is used to report information about just-in-time
+ * generated code that can be used by performance tools. The user inserts
+ * calls in the code generator to report information before JIT-compiled
+ * code goes to execution. This information is collected at runtime and used
+ * by tools like Intel(R) VTune(TM) Amplifier to display performance metrics
+ * associated with JIT-compiled code.
+ *
+ * These APIs can be used to\n
+ * - **Profile trace-based and method-based JIT-compiled
+ * code**. Some examples of environments that you can profile with these APIs:
+ * dynamic JIT compilation of JavaScript code traces, JIT execution in OpenCL(TM)
+ * software technology, Java/.NET managed execution environments, and custom
+ * ISV JIT engines.
+ * @code
+ * #include <jitprofiling.h>
+ *
+ * if (iJIT_IsProfilingActive != iJIT_SAMPLING_ON) {
+ * return;
+ * }
+ *
+ * iJIT_Method_Load jmethod = {0};
+ * jmethod.method_id = iJIT_GetNewMethodID();
+ * jmethod.method_name = "method_name";
+ * jmethod.class_file_name = "class_name";
+ * jmethod.source_file_name = "source_file_name";
+ * jmethod.method_load_address = code_addr;
+ * jmethod.method_size = code_size;
+ *
+ * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&jmethod);
+ * iJIT_NotifyEvent(iJVM_EVENT_TYPE_SHUTDOWN, NULL);
+ * @endcode
+ *
+ * * Expected behavior:
+ * * If any iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event overwrites an
+ * already reported method, then such a method becomes invalid and its
+ * memory region is treated as unloaded. VTune Amplifier displays the metrics
+ * collected by the method until it is overwritten.
+ * * If supplied line number information contains multiple source lines for
+ * the same assembly instruction (code location), then VTune Amplifier picks up
+ * the first line number.
+ * * Dynamically generated code can be associated with a module name.
+ * Use the iJIT_Method_Load_V2 structure.\n
+ * Clarification of some cases:
+ * * If you register a function with the same method ID multiple times,
+ * specifying different module names, then the VTune Amplifier picks up
+ * the module name registered first. If you want to distinguish the same
+ * function between different JIT engines, supply different method IDs for
+ * each function. Other symbolic information (for example, source file)
+ * can be identical.
+ *
+ * - **Analyze split functions** (multiple joint or disjoint code regions
+ * belonging to the same function) **including re-JIT**
+ * with potential overlapping of code regions in time, which is common in
+ * resource-limited environments.
+ * @code
+ * #include <jitprofiling.h>
+ *
+ * unsigned int method_id = iJIT_GetNewMethodID();
+ *
+ * iJIT_Method_Load a = {0};
+ * a.method_id = method_id;
+ * a.method_load_address = 0x100;
+ * a.method_size = 0x20;
+ *
+ * iJIT_Method_Load b = {0};
+ * b.method_id = method_id;
+ * b.method_load_address = 0x200;
+ * b.method_size = 0x30;
+ *
+ * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&a);
+ * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&b);
+ * @endcode
+ *
+ * * Expected behaviour:
+ * * If a iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED event overwrites an
+ * already reported method, then such a method becomes invalid and
+ * its memory region is treated as unloaded.
+ * * All code regions reported with the same method ID are considered as
+ * belonging to the same method. Symbolic information (method name,
+ * source file name) will be taken from the first notification, and all
+ * subsequent notifications with the same method ID will be processed
+ * only for line number table information. So, the VTune Amplifier will map
+ * samples to a source line using the line number table from the current
+ * notification while taking the source file name from the very first one.\n
+ * Clarification of some cases:\n
+ * * If you register a second code region with a different source file
+ * name and the same method ID, then this information will be saved and
+ * will not be considered as an extension of the first code region, but
+ * VTune Amplifier will use the source file of the first code region and map
+ * performance metrics incorrectly.
+ * * If you register a second code region with the same source file as
+ * for the first region and the same method ID, then the source file will be
+ * discarded but VTune Amplifier will map metrics to the source file correctly.
+ * * If you register a second code region with a null source file and
+ * the same method ID, then provided line number info will be associated
+ * with the source file of the first code region.
+ *
+ * - **Explore inline functions** including multi-level hierarchy of
+ * nested inline methods which shows how performance metrics are distributed through them.
+ * @code
+ * #include <jitprofiling.h>
+ *
+ * // method_id parent_id
+ * // [-- c --] 3000 2000
+ * // [---- d -----] 2001 1000
+ * // [---- b ----] 2000 1000
+ * // [------------ a ----------------] 1000 n/a
+ *
+ * iJIT_Method_Load a = {0};
+ * a.method_id = 1000;
+ *
+ * iJIT_Method_Inline_Load b = {0};
+ * b.method_id = 2000;
+ * b.parent_method_id = 1000;
+ *
+ * iJIT_Method_Inline_Load c = {0};
+ * c.method_id = 3000;
+ * c.parent_method_id = 2000;
+ *
+ * iJIT_Method_Inline_Load d = {0};
+ * d.method_id = 2001;
+ * d.parent_method_id = 1000;
+ *
+ * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, (void*)&a);
+ * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&b);
+ * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&c);
+ * iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, (void*)&d);
+ * @endcode
+ *
+ * * Requirements:
+ * * Each inline (iJIT_Method_Inline_Load) method should be associated
+ * with two method IDs: one for itself; one for its immediate parent.
+ * * Address regions of inline methods of the same parent method cannot
+ * overlap each other.
+ * * Execution of the parent method must not be started until it and all
+ * its inline methods are reported.
+ * * Expected behaviour:
+ * * In case of nested inline methods an order of
+ * iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED events is not important.
+ * * If any event overwrites either inline method or top parent method,
+ * then the parent, including inline methods, becomes invalid and its memory
+ * region is treated as unloaded.
+ *
+ * **Life time of allocated data**\n
+ * The client sends an event notification to the agent with event-specific
+ * data, which is a structure. The pointers in the structure refer to memory
+ * allocated by the client, which responsible for releasing it. The pointers are
+ * used by the iJIT_NotifyEvent method to copy client's data in a trace file,
+ * and they are not used after the iJIT_NotifyEvent method returns.
+ */
+
+/**
+ * @defgroup jitapi JIT Profiling
+ * @ingroup internal
+ * @{
+ */
+
+/**
+ * @brief Enumerator for the types of notifications
+ */
+typedef enum iJIT_jvm_event
+{
+ iJVM_EVENT_TYPE_SHUTDOWN = 2, /**<\brief Send this to shutdown the agent.
+ * Use NULL for event data. */
+
+ iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED = 13, /**<\brief Send when dynamic code is
+ * JIT compiled and loaded into
+ * memory by the JIT engine, but
+ * before the code is executed.
+ * Use iJIT_Method_Load as event
+ * data. */
+/** @cond exclude_from_documentation */
+ iJVM_EVENT_TYPE_METHOD_UNLOAD_START, /**<\brief Send when compiled dynamic
+ * code is being unloaded from memory.
+ * Use iJIT_Method_Load as event data.*/
+/** @endcond */
+
+ iJVM_EVENT_TYPE_METHOD_UPDATE, /**<\brief Send to provide new content for
+ * a previously reported dynamic code.
+ * The previous content will be invalidated
+ * starting from the time of the notification.
+ * Use iJIT_Method_Load as event data but
+ * required fields are following:
+ * - method_id identify the code to update.
+ * - method_load_address specify start address
+ * within identified code range
+ * where update should be started.
+ * - method_size specify length of updated code
+ * range. */
+
+
+ iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED, /**<\brief Send when an inline dynamic
+ * code is JIT compiled and loaded
+ * into memory by the JIT engine,
+ * but before the parent code region
+ * starts executing.
+ * Use iJIT_Method_Inline_Load as event data.*/
+
+/** @cond exclude_from_documentation */
+ iJVM_EVENT_TYPE_METHOD_UPDATE_V2,
+/** @endcond */
+
+ iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2 = 21, /**<\brief Send when a dynamic code is
+ * JIT compiled and loaded into
+ * memory by the JIT engine, but
+ * before the code is executed.
+ * Use iJIT_Method_Load_V2 as event data. */
+
+ iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V3 /**<\brief Send when a dynamic code is
+ * JIT compiled and loaded into
+ * memory by the JIT engine, but
+ * before the code is executed.
+ * Use iJIT_Method_Load_V3 as event data. */
+} iJIT_JVM_EVENT;
+
+/**
+ * @brief Enumerator for the agent's mode
+ */
+typedef enum _iJIT_IsProfilingActiveFlags
+{
+ iJIT_NOTHING_RUNNING = 0x0000, /**<\brief The agent is not running;
+ * iJIT_NotifyEvent calls will
+ * not be processed. */
+ iJIT_SAMPLING_ON = 0x0001, /**<\brief The agent is running and
+ * ready to process notifications. */
+} iJIT_IsProfilingActiveFlags;
+
+/**
+ * @brief Description of a single entry in the line number information of a code region.
+ * @details A table of line number entries gives information about how the reported code region
+ * is mapped to source file.
+ * Intel(R) VTune(TM) Amplifier uses line number information to attribute
+ * the samples (virtual address) to a line number. \n
+ * It is acceptable to report different code addresses for the same source line:
+ * @code
+ * Offset LineNumber
+ * 1 2
+ * 12 4
+ * 15 2
+ * 18 1
+ * 21 30
+ *
+ * VTune Amplifier constructs the following table using the client data
+ *
+ * Code subrange Line number
+ * 0-1 2
+ * 1-12 4
+ * 12-15 2
+ * 15-18 1
+ * 18-21 30
+ * @endcode
+ */
+typedef struct _LineNumberInfo
+{
+ unsigned int Offset; /**<\brief Offset from the begining of the code region. */
+ unsigned int LineNumber; /**<\brief Matching source line number offset (from beginning of source file). */
+
+} *pLineNumberInfo, LineNumberInfo;
+
+/**
+ * @brief Enumerator for the code architecture.
+ */
+typedef enum _iJIT_CodeArchitecture
+{
+ iJIT_CA_NATIVE = 0, /**<\brief Native to the process architecture that is calling it. */
+
+ iJIT_CA_32, /**<\brief 32-bit machine code. */
+
+ iJIT_CA_64 /**<\brief 64-bit machine code. */
+
+} iJIT_CodeArchitecture;
+
+#pragma pack(push, 8)
+
+/**
+ * @brief Description of a JIT-compiled method
+ * @details When you use the iJIT_Method_Load structure to describe
+ * the JIT compiled method, use iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED
+ * as an event type to report it.
+ */
+typedef struct _iJIT_Method_Load
+{
+ unsigned int method_id; /**<\brief Unique method ID. Cannot be 0.
+ * You must either use the API function
+ * iJIT_GetNewMethodID to get a valid and unique
+ * method ID, or else manage ID uniqueness
+ * and correct range by yourself.\n
+ * You must use the same method ID for all code
+ * regions of the same method, otherwise different
+ * method IDs specify different methods. */
+
+ char* method_name; /**<\brief The name of the method. It can be optionally
+ * prefixed with its class name and appended with
+ * its complete signature. Can't be NULL. */
+
+ void* method_load_address; /**<\brief The start virtual address of the method code
+ * region. If NULL, data provided with
+ * event are not accepted. */
+
+ unsigned int method_size; /**<\brief The code size of the method in memory.
+ * If 0, then data provided with the event are not
+ * accepted. */
+
+ unsigned int line_number_size; /**<\brief The number of entries in the line number
+ * table.0 if none. */
+
+ pLineNumberInfo line_number_table; /**<\brief Pointer to the line numbers info
+ * array. Can be NULL if
+ * line_number_size is 0. See
+ * LineNumberInfo Structure for a
+ * description of a single entry in
+ * the line number info array */
+
+ unsigned int class_id; /**<\brief This field is obsolete. */
+
+ char* class_file_name; /**<\brief Class name. Can be NULL.*/
+
+ char* source_file_name; /**<\brief Source file name. Can be NULL.*/
+
+} *piJIT_Method_Load, iJIT_Method_Load;
+
+/**
+ * @brief Description of a JIT-compiled method
+ * @details When you use the iJIT_Method_Load_V2 structure to describe
+ * the JIT compiled method, use iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V2
+ * as an event type to report it.
+ */
+typedef struct _iJIT_Method_Load_V2
+{
+ unsigned int method_id; /**<\brief Unique method ID. Cannot be 0.
+ * You must either use the API function
+ * iJIT_GetNewMethodID to get a valid and unique
+ * method ID, or else manage ID uniqueness
+ * and correct range by yourself.\n
+ * You must use the same method ID for all code
+ * regions of the same method, otherwise different
+ * method IDs specify different methods. */
+
+ char* method_name; /**<\brief The name of the method. It can be optionally
+ * prefixed with its class name and appended with
+ * its complete signature. Can't be NULL. */
+
+ void* method_load_address; /**<\brief The start virtual address of the method code
+ * region. If NULL, then data provided with the
+ * event are not accepted. */
+
+ unsigned int method_size; /**<\brief The code size of the method in memory.
+ * If 0, then data provided with the event are not
+ * accepted. */
+
+ unsigned int line_number_size; /**<\brief The number of entries in the line number
+ * table. 0 if none. */
+
+ pLineNumberInfo line_number_table; /**<\brief Pointer to the line numbers info
+ * array. Can be NULL if
+ * line_number_size is 0. See
+ * LineNumberInfo Structure for a
+ * description of a single entry in
+ * the line number info array. */
+
+ char* class_file_name; /**<\brief Class name. Can be NULL. */
+
+ char* source_file_name; /**<\brief Source file name. Can be NULL. */
+
+ char* module_name; /**<\brief Module name. Can be NULL.
+ The module name can be useful for distinguishing among
+ different JIT engines. VTune Amplifier will display
+ reported methods grouped by specific module. */
+
+} *piJIT_Method_Load_V2, iJIT_Method_Load_V2;
+
+/**
+ * @brief Description of a JIT-compiled method
+ * @details The iJIT_Method_Load_V3 structure is the same as iJIT_Method_Load_V2
+ * with a newly introduced 'arch' field that specifies architecture of the code region.
+ * When you use the iJIT_Method_Load_V3 structure to describe
+ * the JIT compiled method, use iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED_V3
+ * as an event type to report it.
+ */
+typedef struct _iJIT_Method_Load_V3
+{
+ unsigned int method_id; /**<\brief Unique method ID. Cannot be 0.
+ * You must either use the API function
+ * iJIT_GetNewMethodID to get a valid and unique
+ * method ID, or manage ID uniqueness
+ * and correct range by yourself.\n
+ * You must use the same method ID for all code
+ * regions of the same method, otherwise they are
+ * treated as regions of different methods. */
+
+ char* method_name; /**<\brief The name of the method. It can be optionally
+ * prefixed with its class name and appended with
+ * its complete signature. Cannot be NULL. */
+
+ void* method_load_address; /**<\brief The start virtual address of the method code
+ * region. If NULL, then data provided with the
+ * event are not accepted. */
+
+ unsigned int method_size; /**<\brief The code size of the method in memory.
+ * If 0, then data provided with the event are not
+ * accepted. */
+
+ unsigned int line_number_size; /**<\brief The number of entries in the line number
+ * table. 0 if none. */
+
+ pLineNumberInfo line_number_table; /**<\brief Pointer to the line numbers info
+ * array. Can be NULL if
+ * line_number_size is 0. See
+ * LineNumberInfo Structure for a
+ * description of a single entry in
+ * the line number info array. */
+
+ char* class_file_name; /**<\brief Class name. Can be NULL. */
+
+ char* source_file_name; /**<\brief Source file name. Can be NULL. */
+
+ char* module_name; /**<\brief Module name. Can be NULL.
+ * The module name can be useful for distinguishing among
+ * different JIT engines. VTune Amplifier will display
+ * reported methods grouped by specific module. */
+
+ iJIT_CodeArchitecture module_arch; /**<\brief Architecture of the method's code region.
+ * By default, it is the same as the process
+ * architecture that is calling it.
+ * For example, you can use it if your 32-bit JIT
+ * engine generates 64-bit code.
+ *
+ * If JIT engine reports both 32-bit and 64-bit types
+ * of methods then VTune Amplifier splits the methods
+ * with the same module name but with different
+ * architectures in two different modules. VTune Amplifier
+ * modifies the original name provided with a 64-bit method
+ * version by ending it with '(64)' */
+
+} *piJIT_Method_Load_V3, iJIT_Method_Load_V3;
+
+/**
+ * @brief Description of an inline JIT-compiled method
+ * @details When you use the_iJIT_Method_Inline_Load structure to describe
+ * the JIT compiled method, use iJVM_EVENT_TYPE_METHOD_INLINE_LOAD_FINISHED
+ * as an event type to report it.
+ */
+typedef struct _iJIT_Method_Inline_Load
+{
+ unsigned int method_id; /**<\brief Unique method ID. Cannot be 0.
+ * You must either use the API function
+ * iJIT_GetNewMethodID to get a valid and unique
+ * method ID, or else manage ID uniqueness
+ * and correct range by yourself. */
+
+ unsigned int parent_method_id; /**<\brief Unique immediate parent's method ID.
+ * Cannot be 0.
+ * You must either use the API function
+ * iJIT_GetNewMethodID to get a valid and unique
+ * method ID, or else manage ID uniqueness
+ * and correct range by yourself. */
+
+ char* method_name; /**<\brief The name of the method. It can be optionally
+ * prefixed with its class name and appended with
+ * its complete signature. Can't be NULL. */
+
+ void* method_load_address; /** <\brief The virtual address on which the method
+ * is inlined. If NULL, then data provided with
+ * the event are not accepted. */
+
+ unsigned int method_size; /**<\brief The code size of the method in memory.
+ * If 0, then data provided with the event are not
+ * accepted. */
+
+ unsigned int line_number_size; /**<\brief The number of entries in the line number
+ * table. 0 if none. */
+
+ pLineNumberInfo line_number_table; /**<\brief Pointer to the line numbers info
+ * array. Can be NULL if
+ * line_number_size is 0. See
+ * LineNumberInfo Structure for a
+ * description of a single entry in
+ * the line number info array */
+
+ char* class_file_name; /**<\brief Class name. Can be NULL.*/
+
+ char* source_file_name; /**<\brief Source file name. Can be NULL.*/
+
+} *piJIT_Method_Inline_Load, iJIT_Method_Inline_Load;
+
+/** @cond exclude_from_documentation */
+/**
+ * @brief Description of a segment type
+ * @details Use the segment type to specify a type of data supplied
+ * with the iJVM_EVENT_TYPE_METHOD_UPDATE_V2 event to be applied to
+ * a certain code trace.
+ */
+typedef enum _iJIT_SegmentType
+{
+ iJIT_CT_UNKNOWN = 0,
+
+ iJIT_CT_CODE, /**<\brief Executable code. */
+
+ iJIT_CT_DATA, /**<\brief Data (not executable code).
+ * VTune Amplifier uses the format string
+ * (see iJIT_Method_Update) to represent
+ * this data in the VTune Amplifier GUI */
+
+ iJIT_CT_KEEP, /**<\brief Use the previous markup for the trace.
+ * Can be used for the following
+ * iJVM_EVENT_TYPE_METHOD_UPDATE_V2 events,
+ * if the type of the previously reported segment
+ * type is the same. */
+ iJIT_CT_EOF
+} iJIT_SegmentType;
+
+/**
+ * @brief Description of a dynamic update of the content within JIT-compiled method
+ * @details The JIT engine may generate the methods that are updated at runtime
+ * partially by mixed (data + executable code) content. When you use the iJIT_Method_Update
+ * structure to describe the update of the content within a JIT-compiled method,
+ * use iJVM_EVENT_TYPE_METHOD_UPDATE_V2 as an event type to report it.
+ *
+ * On the first Update event, VTune Amplifier copies the original code range reported by
+ * the iJVM_EVENT_TYPE_METHOD_LOAD event, then modifies it with the supplied bytes and
+ * adds the modified range to the original method. For next update events, VTune Amplifier
+ * does the same but it uses the latest modified version of a code region for update.
+ * Eventually, VTune Amplifier GUI displays multiple code ranges for the method reported by
+ * the iJVM_EVENT_TYPE_METHOD_LOAD event.
+ * Notes:
+ * - Multiple update events with different types for the same trace are allowed
+ * but they must be reported for the same code ranges.
+ * Example,
+ * @code
+ * [-- data---] Allowed
+ * [-- code --] Allowed
+ * [code] Ignored
+ * [-- data---] Allowed
+ * [-- code --] Allowed
+ * [------------ trace ---------]
+ * @endcode
+ * - The types of previously reported events can be changed but they must be reported
+ * for the same code ranges.
+ * Example,
+ * @code
+ * [-- data---] Allowed
+ * [-- code --] Allowed
+ * [-- data---] Allowed
+ * [-- code --] Allowed
+ * [------------ trace ---------]
+ * @endcode
+ */
+
+typedef struct _iJIT_Method_Update
+{
+ void* load_address; /**<\brief Start address of the update within a method */
+
+ unsigned int size; /**<\brief The update size */
+
+ iJIT_SegmentType type; /**<\brief Type of the update */
+
+ const char* data_format; /**<\brief C string that contains a format string
+ * that follows the same specifications as format in printf.
+ * The format string is used for iJIT_CT_CODE only
+ * and cannot be NULL.
+ * Format can be changed on the fly. */
+} *piJIT_Method_Update, iJIT_Method_Update;
+
+/** @endcond */
+
+#pragma pack(pop)
+
+/** @cond exclude_from_documentation */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef JITAPI_CDECL
+# if defined WIN32 || defined _WIN32
+# define JITAPI_CDECL __cdecl
+# else /* defined WIN32 || defined _WIN32 */
+# if defined _M_IX86 || defined __i386__
+# define JITAPI_CDECL __attribute__ ((cdecl))
+# else /* _M_IX86 || __i386__ */
+# define JITAPI_CDECL /* actual only on x86_64 platform */
+# endif /* _M_IX86 || __i386__ */
+# endif /* defined WIN32 || defined _WIN32 */
+#endif /* JITAPI_CDECL */
+
+#define JITAPI JITAPI_CDECL
+/** @endcond */
+
+/**
+ * @brief Generates a new unique method ID.
+ *
+ * You must use this API to obtain unique and valid method IDs for methods or
+ * traces reported to the agent if you don't have your own mechanism to generate
+ * unique method IDs.
+ *
+ * @return a new unique method ID. When out of unique method IDs, this API
+ * returns 0, which is not an accepted value.
+ */
+unsigned int JITAPI iJIT_GetNewMethodID(void);
+
+/**
+ * @brief Returns the current mode of the agent.
+ *
+ * @return iJIT_SAMPLING_ON, indicating that agent is running, or
+ * iJIT_NOTHING_RUNNING if no agent is running.
+ */
+iJIT_IsProfilingActiveFlags JITAPI iJIT_IsProfilingActive(void);
+
+/**
+ * @brief Reports infomation about JIT-compiled code to the agent.
+ *
+ * The reported information is used to attribute samples obtained from any
+ * Intel(R) VTune(TM) Amplifier collector. This API needs to be called
+ * after JIT compilation and before the first entry into the JIT-compiled
+ * code.
+ *
+ * @param[in] event_type - type of the data sent to the agent
+ * @param[in] EventSpecificData - pointer to event-specific data
+ *
+ * @returns 1 on success, otherwise 0.
+ */
+int JITAPI iJIT_NotifyEvent(iJIT_JVM_EVENT event_type, void *EventSpecificData);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+/** @endcond */
+
+/** @} jitapi group */
+
+#endif /* __JITPROFILING_H__ */
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/nchw_pooling.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/nchw_pooling.cpp
new file mode 100644
index 0000000000..ef4c42bacf
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/nchw_pooling.cpp
@@ -0,0 +1,317 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <math.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+#include "nstl.hpp"
+
+#include "nchw_pooling.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t data_type>
+void nchw_pooling_fwd_t<data_type>::execute_forward(
+ const exec_ctx_t &ctx) const {
+ using namespace alg_kind;
+
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+ auto ws = CTX_OUT_MEM(unsigned char *, MKLDNN_ARG_WORKSPACE);
+
+ const memory_desc_wrapper ws_d(pd()->workspace_md());
+ const data_type_t ws_dt = ws ? ws_d.data_type() : data_type::undef;
+
+ const int MB = pd()->MB();
+ const int C = pd()->C();
+ const int OD = pd()->OD();
+ const int OH = pd()->OH();
+ const int OW = pd()->OW();
+ const int ID = pd()->ID();
+ const int IH = pd()->IH();
+ const int IW = pd()->IW();
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+ const int SD = pd()->KSD();
+ const int SH = pd()->KSH();
+ const int SW = pd()->KSW();
+ const int padF = pd()->padFront();
+ const int padT = pd()->padT();
+ const int padL = pd()->padL();
+
+ auto alg = pd()->desc()->alg_kind;
+
+ auto apply_offset = [=](int index, int offset) {
+ return (index > offset) ? index - offset : 0;
+ };
+
+ auto set_ws = [=](int mb, int c, int od, int oh, int ow, int value) {
+ if (ws) {
+ assert(ws_dt == data_type::u8 || ws_dt == data_type::s32);
+ size_t ws_offset
+ = (size_t)OW * OH * OD * C * mb
+ + (size_t)OW * OH * OD * c
+ + (size_t)OW * OH * od
+ + (size_t)OW * oh
+ + (size_t)ow;
+ if (ws_dt == data_type::u8) {
+ assert(0 <= value && value <= 255);
+ ws[ws_offset] = value;
+ } else
+ reinterpret_cast<int *>(ws)[ws_offset] = value;
+ }
+ };
+
+ auto ker_max = [=](data_t *d, int mb, int c, int od, int oh, int ow) {
+ for (int kd = 0; kd < KD; ++kd) {
+ for (int kh = 0; kh < KH; ++kh) {
+ for (int kw = 0; kw < KW; ++kw) {
+ const int id = od * SD - padF + kd;
+ const int ih = oh * SH - padT + kh;
+ const int iw = ow * SW - padL + kw;
+
+ if (id < 0 || id >= ID) continue;
+ if (ih < 0 || ih >= IH) continue;
+ if (iw < 0 || iw >= IW) continue;
+
+ auto src_offset
+ = (size_t)IW * IH * ID * C * mb
+ + (size_t)IW * IH * ID * c
+ + (size_t)IW * IH * id
+ + (size_t)IW * ih
+ + (size_t)iw;
+ auto s = src[src_offset];
+ if (s > d[0]) {
+ d[0] = s;
+ set_ws(mb, c, od, oh, ow, kd*KH*KW + kh*KW + kw);
+ }
+ }
+ }
+ }
+ };
+
+ auto ker_avg = [=](data_t *d, int mb, int c, int od, int oh, int ow) {
+ auto id_start = apply_offset(od*SD, padF);
+ auto ih_start = apply_offset(oh*SH, padT);
+ auto iw_start = apply_offset(ow*SW, padL);
+ auto id_end = nstl::min(od*SD - padF + KD, ID);
+ auto ih_end = nstl::min(oh*SH - padT + KH, IH);
+ auto iw_end = nstl::min(ow*SW - padL + KW, IW);
+
+ auto num_summands = (alg == pooling_avg_include_padding) ? KD*KW*KH
+ : (id_end - id_start)*(ih_end - ih_start)*(iw_end - iw_start);
+
+ for (int id = id_start; id < id_end; ++id) {
+ for (int ih = ih_start; ih < ih_end; ++ih) {
+ for (int iw = iw_start; iw < iw_end; ++iw) {
+ auto src_offset
+ = (size_t)IW * IH * ID * C * mb
+ + (size_t)IW * IH * ID * c
+ + (size_t)IW * IH * id
+ + (size_t)IW * ih
+ + (size_t)iw;
+ d[0] += src[src_offset];
+ }
+ }
+ }
+
+ d[0] = math::out_round<data_t>((float)d[0] / num_summands);
+ };
+
+
+ if (pd()->desc()->alg_kind == pooling_max) {
+ parallel_nd(MB, C, OD, OH, OW,
+ [&](int mb, int c, int od, int oh, int ow) {
+ size_t dst_offset
+ = (size_t)OW * OH * OD * C * mb
+ + (size_t)OW * OH * OD * c
+ + (size_t)OW * OH * od
+ + (size_t)OW * oh
+ + (size_t)ow;
+ data_t *d = &dst[dst_offset];
+ d[0] = nstl::numeric_limits<data_t>::lowest();
+ set_ws(mb, c, od, oh, ow, 0);
+ ker_max(d, mb, c, od, oh, ow);
+ });
+ } else {
+ parallel_nd(MB, C, OD, OH, OW,
+ [&](int mb, int c, int od, int oh, int ow) {
+ size_t dst_offset
+ = (size_t)OW * OH * OD * C * mb
+ + (size_t)OW * OH * OD * c
+ + (size_t)OW * OH * od
+ + (size_t)OW * oh
+ + (size_t)ow;
+ data_t *d = &dst[dst_offset];
+ d[0] = 0;
+ ker_avg(d, mb, c, od, oh, ow);
+ });
+ }
+}
+
+template <impl::data_type_t data_type>
+void nchw_pooling_bwd_t<data_type>::execute_backward(
+ const exec_ctx_t &ctx) const {
+ using namespace alg_kind;
+
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto ws = CTX_IN_MEM(const unsigned char *, MKLDNN_ARG_WORKSPACE);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper ws_d(pd()->workspace_md());
+
+ const int MB = pd()->MB();
+ const int C = pd()->C();
+ const int OD = pd()->OD();
+ const int OH = pd()->OH();
+ const int OW = pd()->OW();
+ const int ID = pd()->ID();
+ const int IH = pd()->IH();
+ const int IW = pd()->IW();
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+ const int SD = pd()->KSD();
+ const int SH = pd()->KSH();
+ const int SW = pd()->KSW();
+ const int padF = pd()->padFront();
+ const int padT = pd()->padT();
+ const int padL = pd()->padL();
+
+ const bool is_3d = pd()->desc()->diff_src_desc.ndims == 5;
+
+ auto alg = pd()->desc()->alg_kind;
+
+ auto apply_offset = [=](int index, int offset) {
+ return (index > offset) ? index - offset : 0;
+ };
+
+ auto ker_zero = [=](int mb, int c) {
+ size_t diff_src_offset = (size_t)mb*C*ID*IH*IW + (size_t)c*ID*IH*IW;
+ for (int id = 0; id < ID; ++id) {
+ for (int ih = 0; ih < IH; ++ih) {
+ for (int iw = 0; iw < IW; ++iw) {
+ diff_src[diff_src_offset++] = 0;
+ }
+ }
+ }
+ };
+
+ auto ker_max = [=](const data_t *d, int mb, int c, int od, int oh, int ow) {
+ auto b_c = ws_d.blocking_desc().inner_nblks == 0
+ ? 1 : ws_d.blocking_desc().inner_blks[0];
+ auto ws_offset = is_3d
+ ? ws_d.blk_off(mb, c / b_c, od, oh, ow) + c % b_c
+ : ws_d.blk_off(mb, c / b_c, oh, ow) + c % b_c;
+
+ const int index = ws_d.data_type() == data_type::u8
+ ? (int)ws[ws_offset] : ((const int *)ws)[ws_offset];
+ const int kw = index % KW;
+ const int kh = (index / KW) % KH;
+ const int kd = (index / KW) / KH;
+
+ const int id = od * SD - padF + kd;
+ const int ih = oh * SH - padT + kh;
+ const int iw = ow * SW - padL + kw;
+
+ // If padding area could fit the kernel,
+ // then input displacement would be out of bounds.
+ // No need to back propagate there as padding is
+ // virtual in pooling_max case.
+ if (id < 0 || id >= ID)
+ return;
+ if (ih < 0 || ih >= IH)
+ return;
+ if (iw < 0 || iw >= IW)
+ return;
+
+ size_t diff_src_offset =
+ (size_t)mb*C*ID*IH*IW + (size_t)c*ID*IH*IW + (size_t)id*IH*IW
+ + (size_t)ih*IW + (size_t)iw;
+ diff_src[diff_src_offset] += d[0];
+ };
+
+ auto ker_avg = [=](const data_t *d, int mb, int c, int od, int oh, int ow) {
+ auto id_start = apply_offset(od*SD, padF);
+ auto ih_start = apply_offset(oh*SH, padT);
+ auto iw_start = apply_offset(ow*SW, padL);
+ auto id_end = nstl::min(od*SD - padF + KD, ID);
+ auto ih_end = nstl::min(oh*SH - padT + KH, IH);
+ auto iw_end = nstl::min(ow*SW - padL + KW, IW);
+
+ size_t num_summands = (alg == pooling_avg_include_padding)
+ ? (size_t)KW*KH*KD
+ : (size_t)(id_end - id_start)*(ih_end - ih_start)
+ *(iw_end - iw_start);
+
+ for (int id = id_start; id < id_end; ++id) {
+ for (int ih = ih_start; ih < ih_end; ++ih) {
+ for (int iw = iw_start; iw < iw_end; ++iw) {
+ size_t diff_src_offset = (size_t)mb*C*ID*IH*IW
+ + (size_t)c*ID*IH*IW + (size_t)id*IH*IW
+ + (size_t)ih*IW + (size_t)iw;
+ diff_src[diff_src_offset] += d[0] / num_summands;
+ }
+ }
+ }
+ };
+
+ if (pd()->desc()->alg_kind == pooling_max) {
+ parallel_nd(MB, C, [&](int mb, int c) {
+ size_t diff_dst_offset = (size_t)mb*C*OD*OH*OW
+ + (size_t)c*OD*OH*OW;
+ ker_zero(mb, c);
+ for (int od = 0; od < OD; ++od) {
+ for (int oh = 0; oh < OH; ++oh) {
+ for (int ow = 0; ow < OW; ++ow) {
+ const data_t *d = &diff_dst[diff_dst_offset++];
+ ker_max(d, mb, c, od, oh, ow);
+ }
+ }
+ }
+ });
+ } else {
+ parallel_nd(MB, C, [&](int mb, int c) {
+ size_t diff_dst_offset = (size_t)mb*C*OD*OH*OW
+ + (size_t)c*OD*OH*OW;
+ ker_zero(mb, c);
+ for (int od = 0; od < OD; ++od) {
+ for (int oh = 0; oh < OH; ++oh) {
+ for (int ow = 0; ow < OW; ++ow) {
+ const data_t *d = &diff_dst[diff_dst_offset++];
+ ker_avg(d, mb, c, od, oh, ow);
+ }
+ }
+ }
+ });
+ }
+}
+
+template struct nchw_pooling_fwd_t<data_type::f32>;
+template struct nchw_pooling_bwd_t<data_type::f32>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/nchw_pooling.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/nchw_pooling.hpp
new file mode 100644
index 0000000000..bbdd04f6b9
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/nchw_pooling.hpp
@@ -0,0 +1,147 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_NCHW_POOLING_HPP
+#define CPU_NCHW_POOLING_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_pooling_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t data_type>
+struct nchw_pooling_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_pooling_fwd_pd_t {
+ using cpu_pooling_fwd_pd_t::cpu_pooling_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T("nchw_pooling:any", nchw_pooling_fwd_t);
+
+ status_t init() {
+ const format_tag_t desired_fmt_tag =
+ ndims() == 4 ? format_tag::nchw : format_tag::ncdhw;
+
+ bool ok = true
+ && set_default_params() == status::success
+ && is_fwd()
+ && utils::one_of(desc()->alg_kind, alg_kind::pooling_max,
+ alg_kind::pooling_avg_include_padding,
+ alg_kind::pooling_avg_exclude_padding)
+ && !has_zero_dim_memory()
+ && utils::everyone_is(data_type, src_md()->data_type,
+ dst_md()->data_type)
+ && attr()->has_default_values()
+ && memory_desc_matches_tag(*src_md(), desired_fmt_tag)
+ && memory_desc_matches_tag(*dst_md(), desired_fmt_tag);
+ if (!ok) return status::unimplemented;
+
+ bool is_training = desc_.prop_kind == prop_kind::forward_training;
+ if (desc()->alg_kind == alg_kind::pooling_max && is_training)
+ init_default_ws();
+
+ return status::success;
+ }
+ };
+
+ nchw_pooling_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t data_type>
+struct nchw_pooling_bwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_pooling_bwd_pd_t {
+ using cpu_pooling_bwd_pd_t::cpu_pooling_bwd_pd_t;
+
+ DECLARE_COMMON_PD_T("nchw:any", nchw_pooling_bwd_t);
+
+ status_t init() {
+ const format_tag_t desired_fmt_tag =
+ ndims() == 4 ? format_tag::nchw : format_tag::ncdhw;
+
+ bool ok = true
+ && set_default_params() == status::success
+ && !is_fwd()
+ && utils::one_of(desc()->alg_kind, alg_kind::pooling_max,
+ alg_kind::pooling_avg_include_padding,
+ alg_kind::pooling_avg_exclude_padding)
+ && !has_zero_dim_memory()
+ && utils::everyone_is(data_type,
+ diff_dst_md()->data_type,
+ diff_src_md()->data_type)
+ && attr()->has_default_values()
+ && memory_desc_matches_tag(*diff_dst_md(), desired_fmt_tag)
+ && memory_desc_matches_tag(*diff_src_md(), desired_fmt_tag);
+ if (!ok) return status::unimplemented;
+
+ if (desc()->alg_kind == alg_kind::pooling_max) {
+ bool ws_ok = true
+ && hint_fwd_pd_
+ && hint_fwd_pd_->workspace_md();
+ if (!ws_ok)
+ return status::unimplemented;
+
+ const auto &ws_blk =
+ hint_fwd_pd_->workspace_md()->format_desc.blocking;
+ ws_ok = ws_ok
+ && ws_blk.inner_nblks < 1
+ && IMPLICATION(ws_blk.inner_nblks == 1,
+ ws_blk.inner_idxs[0] == 1);
+ if (!ws_ok)
+ return status::unimplemented;
+
+ ws_md_ = *hint_fwd_pd_->workspace_md();
+ }
+
+ return status::success;
+ }
+ };
+
+ nchw_pooling_bwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ncsp_batch_normalization.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/ncsp_batch_normalization.cpp
new file mode 100644
index 0000000000..c0e93fefe4
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ncsp_batch_normalization.cpp
@@ -0,0 +1,382 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <math.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+
+#include "cpu_batch_normalization_utils.hpp"
+#include "jit_generator.hpp"
+
+#include "ncsp_batch_normalization.hpp"
+
+// clang 6 and 7 generate incorrect code with OMP_SIMD in some particular cases
+#if (defined __clang_major__) && (__clang_major__ >= 6)
+#define SAFE_TO_USE_OMP_SIMD 0
+#else
+#define SAFE_TO_USE_OMP_SIMD 1
+#endif
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace memory_tracking::names;
+
+void ncsp_batch_normalization_fwd_t::execute_forward(
+ const exec_ctx_t &ctx) const {
+ const bool calculate_stats = !pd()->stats_is_src();
+ const bool save_stats = pd()->is_training();
+ const bool is_training = pd()->is_training();
+ const bool fuse_bn_relu = pd()->fuse_bn_relu();
+
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto scaleshift = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SCALE_SHIFT);
+
+ auto scratchpad = this->scratchpad(ctx);
+ auto *ws_reduce = scratchpad.get<data_t>(key_bnorm_reduction);
+
+ data_t *mean, *variance;
+ if (!calculate_stats) {
+ mean = const_cast<data_t *>(
+ CTX_IN_MEM(const data_t *, MKLDNN_ARG_MEAN));
+ variance = const_cast<data_t *>(
+ CTX_IN_MEM(const data_t *, MKLDNN_ARG_VARIANCE));
+ } else {
+ if (save_stats) {
+ mean = CTX_OUT_MEM(data_t *, MKLDNN_ARG_MEAN);
+ variance = CTX_OUT_MEM(data_t *, MKLDNN_ARG_VARIANCE);
+ } else {
+ mean = scratchpad.get<data_t>(key_bnorm_tmp_mean);
+ variance = scratchpad.get<data_t>(key_bnorm_tmp_var);
+ }
+ }
+
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+ auto ws = CTX_OUT_MEM(uint8_t *, MKLDNN_ARG_WORKSPACE);
+
+ const float eps = pd()->desc()->batch_norm_epsilon;
+ const bool use_scaleshift = pd()->use_scaleshift();
+ const bool with_relu = pd()->with_relu_post_op();
+ auto maybe_post_op
+ = [&](data_t res) { return (with_relu && res < 0) ? 0 : res; };
+ const bool has_spatial = utils::one_of(pd()->ndims(), 4, 5);
+ dim_t SP = (has_spatial) ? pd()->H() * pd()->W() * pd()->D() : 1;
+ dim_t N = pd()->MB();
+ dim_t C = pd()->C();
+
+ int nthr = mkldnn_get_max_threads();
+ size_t l3_size_ = get_cache_size(3, true) * nthr / 2;
+ size_t data_size = N * C * SP * sizeof(data_t);
+ bool do_blocking = (data_size >= l3_size_ / 2 && l3_size_ > 0);
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ int C_ithr = 0, C_nthr = 0;
+ int N_ithr = 0, N_nthr = 0;
+ int S_ithr = 0, S_nthr = 0;
+
+ dim_t C_blk_gl_s = 0, C_blk_gl_e = 0, C_blk_s = 0, C_blk_e = 0;
+ dim_t N_s = 0, N_e = 0;
+ dim_t S_s = 0, S_e = 0;
+
+ dim_t C_blks_per_iter = 1;
+ int64_t iters = 1;
+
+ if (do_blocking) {
+ size_t working_set_size = N * SP * sizeof(data_t);
+ bnorm_utils::cache_balance(
+ working_set_size, C, C_blks_per_iter, iters);
+ } else
+ C_blks_per_iter = C;
+ int64_t last_iter_blks = C - (iters - 1) * C_blks_per_iter;
+ bool spatial_thr_allowed
+ = bnorm_utils::thread_balance(do_blocking, true, ithr, nthr, N,
+ C_blks_per_iter, SP, C_ithr, C_nthr, C_blk_s, C_blk_e,
+ N_ithr, N_nthr, N_s, N_e, S_ithr, S_nthr, S_s, S_e);
+ balance211(C_blks_per_iter, nthr, ithr, C_blk_gl_s, C_blk_gl_e);
+ int SP_N_ithr = N_ithr * S_nthr + S_ithr;
+ int SP_N_nthr = N_nthr * S_nthr;
+ for (int64_t it = 0; it < iters; ++it) {
+ if (it == iters - 1 && iters > 1) {
+ // On the last iteration the access pattern to ws_reduce
+ // might change (due to re-balance on C). So sync the
+ // threads if they are not synced by the algorithm.
+ if (SP_N_nthr == 1 && mkldnn_thr_syncable())
+ mkldnn_thr_barrier();
+
+ S_s = S_e = C_blk_s = C_blk_e = N_s = N_e = 0;
+ spatial_thr_allowed = bnorm_utils::thread_balance(do_blocking,
+ spatial_thr_allowed, ithr, nthr, N, last_iter_blks, SP,
+ C_ithr, C_nthr, C_blk_s, C_blk_e, N_ithr, N_nthr, N_s,
+ N_e, S_ithr, S_nthr, S_s, S_e);
+ balance211(last_iter_blks, nthr, ithr, C_blk_gl_s, C_blk_gl_e);
+ SP_N_ithr = N_ithr * S_nthr + S_ithr;
+ SP_N_nthr = N_nthr * S_nthr;
+ }
+ size_t C_off = it * C_blks_per_iter;
+ // On the last iteration the access pattern to ws_reduce
+ // might change (due to re-balance on C). Since sync is not always
+ // possible (in case of TBB) use different parts of ws for each
+ // iteration if threads are not synced by the algorithm.
+ size_t ws_iter_off = (mkldnn_thr_syncable() ? 0 : 1) * C_off;
+
+ if (calculate_stats) {
+ data_t *mean_blk = mean + C_off;
+ data_t *variance_blk = variance + C_off;
+ for (dim_t c = C_blk_s; c < C_blk_e; c++) {
+ size_t off = (c + C_off) * SP;
+ data_t sum = 0;
+ for (dim_t n = N_s; n < N_e; ++n)
+ PRAGMA_OMP_SIMD(reduction(+ : sum))
+ for (dim_t sp = S_s; sp < S_e; ++sp) {
+ sum += src[off + n * C * SP + sp];
+ }
+ ws_reduce[ws_iter_off + SP_N_ithr * C_blks_per_iter + c]
+ = sum;
+ }
+
+ if (SP_N_nthr > 1) mkldnn_thr_barrier();
+
+ for (dim_t c = C_blk_gl_s; c < C_blk_gl_e; c++) {
+ mean_blk[c] = 0.;
+ for (dim_t n = 0; n < SP_N_nthr; n++)
+ mean_blk[c] += ws_reduce[ws_iter_off
+ + n * C_blks_per_iter + c];
+ mean_blk[c] /= (N * SP);
+ }
+
+ if (SP_N_nthr > 1) mkldnn_thr_barrier();
+
+ for (dim_t c = C_blk_s; c < C_blk_e; c++) {
+ size_t off = c + C_off;
+ data_t sum = 0.;
+ for (dim_t n = N_s; n < N_e; ++n)
+ PRAGMA_OMP_SIMD(reduction(+ : sum))
+ for (dim_t sp = S_s; sp < S_e; ++sp) {
+ data_t m = src[off * SP + n * C * SP + sp]
+ - mean[off];
+ sum += m * m;
+ }
+ ws_reduce[ws_iter_off + SP_N_ithr * C_blks_per_iter + c]
+ = sum;
+ }
+
+ if (SP_N_nthr > 1) mkldnn_thr_barrier();
+
+ for (dim_t c = C_blk_gl_s; c < C_blk_gl_e; c++) {
+ variance_blk[c] = 0.;
+ for (dim_t n = 0; n < SP_N_nthr; n++)
+ variance_blk[c] += ws_reduce[ws_iter_off
+ + n * C_blks_per_iter + c];
+ variance_blk[c] /= (N * SP);
+ }
+
+ if (SP_N_nthr > 1) mkldnn_thr_barrier();
+ }
+
+ for (dim_t c = C_blk_s; c < C_blk_e; c++) {
+ size_t off = c + C_off;
+ data_t sqrt_variance
+ = static_cast<data_t>(sqrtf(variance[off] + eps));
+ data_t sm = (use_scaleshift ? scaleshift[off] : 1.0f) / sqrt_variance;
+ data_t sv = use_scaleshift ? scaleshift[C + off] : 0;
+ for (dim_t n = N_s; n < N_e; ++n)
+#if SAFE_TO_USE_OMP_SIMD
+ PRAGMA_OMP_SIMD()
+#endif
+ for (dim_t sp = S_s; sp < S_e; ++sp) {
+ size_t d_off = off * SP + n * C * SP + sp;
+ data_t bn_res
+ = sm * (src[d_off] - mean[off]) + sv;
+ if (fuse_bn_relu) {
+ if (bn_res <= 0) {
+ bn_res = 0;
+ if (is_training)
+ ws[d_off] = 0;
+ } else {
+ if (is_training)
+ ws[d_off] = 1;
+ }
+ }
+ dst[d_off] = maybe_post_op(bn_res);
+ }
+ }
+ }
+ });
+}
+
+void ncsp_batch_normalization_bwd_t::execute_backward(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto mean = CTX_IN_MEM(const data_t *, MKLDNN_ARG_MEAN);
+ auto variance = CTX_IN_MEM(const data_t *, MKLDNN_ARG_VARIANCE);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto scaleshift = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SCALE_SHIFT);
+ auto ws = CTX_IN_MEM(const uint8_t *, MKLDNN_ARG_WORKSPACE);
+
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+ auto diff_scaleshift = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SCALE_SHIFT);
+
+ auto scratchpad = this->scratchpad(ctx);
+ auto *ws_reduce = scratchpad.get<data_t>(key_bnorm_reduction);
+
+ if (diff_scaleshift == nullptr)
+ diff_scaleshift = scratchpad.get<data_t>(key_bnorm_tmp_diff_ss);
+
+ const bool has_spatial = utils::one_of(pd()->ndims(), 4, 5);
+ dim_t SP = (has_spatial) ? pd()->H() * pd()->W() * pd()->D() : 1;
+ dim_t C = pd()->C(), N = pd()->MB();
+ const bool use_scaleshift = pd()->use_scaleshift();
+ const float eps = pd()->desc()->batch_norm_epsilon;
+ const bool calculate_diff_stats = !pd()->use_global_stats();
+ const bool fuse_bn_relu = pd()->fuse_bn_relu();
+
+ int nthr = mkldnn_get_max_threads();
+ size_t l3_size_ = get_cache_size(3, true) * nthr / 2;
+ size_t data_size = N * C * SP * sizeof(data_t);
+ bool do_blocking = (data_size >= l3_size_ / 2 && l3_size_ > 0);
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ int C_ithr = 0, C_nthr = 0;
+ int N_ithr = 0, N_nthr = 0;
+ int S_ithr = 0, S_nthr = 0;
+
+ dim_t C_blk_gl_s = 0, C_blk_gl_e = 0, C_blk_s = 0, C_blk_e = 0;
+ dim_t N_s = 0, N_e = 0;
+ dim_t S_s = 0, S_e = 0;
+
+ dim_t C_blks_per_iter = 1;
+ int64_t iters = 1;
+
+ if (do_blocking) {
+ size_t working_set_size = 2 * N * SP * sizeof(data_t);
+ bnorm_utils::cache_balance(
+ working_set_size, C, C_blks_per_iter, iters);
+ } else
+ C_blks_per_iter = C;
+ int64_t last_iter_blks = C - (iters - 1) * C_blks_per_iter;
+ bool spatial_thr_allowed
+ = bnorm_utils::thread_balance(do_blocking, true, ithr, nthr, N,
+ C_blks_per_iter, SP, C_ithr, C_nthr, C_blk_s, C_blk_e,
+ N_ithr, N_nthr, N_s, N_e, S_ithr, S_nthr, S_s, S_e);
+ balance211(C_blks_per_iter, nthr, ithr, C_blk_gl_s, C_blk_gl_e);
+ int SP_N_ithr = N_ithr * S_nthr + S_ithr;
+ int SP_N_nthr = N_nthr * S_nthr;
+
+ for (int64_t it = 0; it < iters; ++it) {
+ if (it == iters - 1 && iters > 1) {
+ // On the last iteration the access pattern to ws_reduce
+ // might change (due to re-balance on C). So sync the
+ // threads if they are not synced by the algorithm.
+ if (SP_N_nthr == 1 && mkldnn_thr_syncable())
+ mkldnn_thr_barrier();
+
+ C_blk_s = C_blk_e = N_s = N_e = 0;
+ spatial_thr_allowed = bnorm_utils::thread_balance(do_blocking,
+ spatial_thr_allowed, ithr, nthr, N, last_iter_blks, SP,
+ C_ithr, C_nthr, C_blk_s, C_blk_e, N_ithr, N_nthr, N_s,
+ N_e, S_ithr, S_nthr, S_s, S_e);
+ balance211(last_iter_blks, nthr, ithr, C_blk_gl_s, C_blk_gl_e);
+ SP_N_ithr = N_ithr * S_nthr + S_ithr;
+ SP_N_nthr = N_nthr * S_nthr;
+ }
+ size_t C_off = it * C_blks_per_iter;
+ // On the last iteration the access pattern to ws_reduce
+ // might change (due to re-balance on C). Since sync is not always
+ // possible (in case of TBB) use different parts of ws for each
+ // iteration if threads are not synced by the algorithm.
+ size_t ws_iter_off = (mkldnn_thr_syncable() ? 0 : 1) * 2 * C_off;
+
+ data_t *diff_gamma_blk = diff_scaleshift + C_off;
+ data_t *diff_beta_blk = diff_scaleshift + C + C_off;
+ for (dim_t c = C_blk_s; c < C_blk_e; c++) {
+ size_t off = c + C_off;
+ data_t diff_gamma = 0.0, diff_beta = 0.0;
+ data_t v_mean = mean[off];
+ for (dim_t n = N_s; n < N_e; ++n)
+ PRAGMA_OMP_SIMD(reduction(+ : diff_gamma, diff_beta))
+ for (dim_t sp = S_s; sp < S_e; ++sp) {
+ const size_t d_off = off * SP + n * C * SP + sp;
+ data_t dd;
+ if (fuse_bn_relu)
+ dd = (!ws[d_off]) ? 0 : diff_dst[d_off];
+ else
+ dd = diff_dst[d_off];
+ diff_gamma += (src[d_off] - v_mean) * dd;
+ diff_beta += dd;
+ }
+ ws_reduce[ws_iter_off + SP_N_ithr * C_blks_per_iter + c]
+ = diff_gamma;
+ ws_reduce[ws_iter_off + SP_N_nthr * C_blks_per_iter
+ + SP_N_ithr * C_blks_per_iter + c] = diff_beta;
+ }
+
+ if (SP_N_nthr > 1) mkldnn_thr_barrier();
+
+ for (dim_t c = C_blk_gl_s; c < C_blk_gl_e; c++) {
+ data_t sqrt_variance = static_cast<data_t>(
+ 1.0f / sqrtf(variance[c + C_off] + eps));
+ diff_gamma_blk[c] = 0.;
+ diff_beta_blk[c] = 0.;
+ for (dim_t n = 0; n < SP_N_nthr; n++) {
+ diff_gamma_blk[c] += ws_reduce[ws_iter_off
+ + n * C_blks_per_iter + c];
+ diff_beta_blk[c] += ws_reduce[ws_iter_off
+ + SP_N_nthr * C_blks_per_iter + n * C_blks_per_iter
+ + c];
+ }
+ diff_gamma_blk[c] *= sqrt_variance;
+ }
+
+ if (SP_N_nthr > 1) mkldnn_thr_barrier();
+
+ for (dim_t c = C_blk_s; c < C_blk_e; c++) {
+ size_t off = c + C_off;
+ data_t gamma = use_scaleshift ? scaleshift[off] : 1;
+ data_t sqrt_variance
+ = static_cast<data_t>(1.0f / sqrtf(variance[off] + eps));
+ data_t v_mean = mean[off];
+ for (dim_t n = N_s; n < N_e; ++n)
+#if SAFE_TO_USE_OMP_SIMD
+ PRAGMA_OMP_SIMD()
+#endif
+ for (dim_t sp = S_s; sp < S_e; ++sp) {
+ const size_t d_off = off * SP + n * C * SP + sp;
+
+ data_t v_diff_src;
+ if (fuse_bn_relu)
+ v_diff_src = (!ws[d_off]) ? 0 : diff_dst[d_off];
+ else
+ v_diff_src = diff_dst[d_off];
+ if (calculate_diff_stats) {
+ v_diff_src -= diff_beta_blk[c] / (SP * N)
+ + (src[d_off] - v_mean) * diff_gamma_blk[c]
+ * sqrt_variance / (SP * N);
+ }
+ v_diff_src *= gamma * sqrt_variance;
+ diff_src[d_off] = v_diff_src;
+ }
+ }
+ }
+ });
+}
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ncsp_batch_normalization.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ncsp_batch_normalization.hpp
new file mode 100644
index 0000000000..97ca3b003f
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ncsp_batch_normalization.hpp
@@ -0,0 +1,160 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_NCSP_BATCH_NORMALIZATION_HPP
+#define CPU_NCSP_BATCH_NORMALIZATION_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_batch_normalization_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct ncsp_batch_normalization_fwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_batch_normalization_fwd_pd_t {
+ using cpu_batch_normalization_fwd_pd_t::cpu_batch_normalization_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ncsp_bnorm:any", ncsp_batch_normalization_fwd_t);
+
+ status_t init() {
+ using namespace data_type;
+ using namespace prop_kind;
+ using namespace format_tag;
+
+ bool ok = true
+ && is_fwd()
+ && !has_zero_dim_memory()
+ && src_md()->data_type == f32
+ && IMPLICATION(use_scaleshift(), weights_md()->data_type == f32)
+ && memory_desc_matches_one_of_tag(*src_md(), ncdhw, nchw, nc)
+ && (attr()->has_default_values() || this->with_relu_post_op());
+ if (!ok) return status::unimplemented;
+
+ if (is_training() && fuse_bn_relu()) init_default_ws(8);
+
+ init_scratchpad();
+
+ return status::success;
+ }
+
+ private:
+ void init_scratchpad() {
+ using namespace memory_tracking::names;
+ auto scratchpad = scratchpad_registry().registrar();
+ if (!stats_is_src()) {
+ scratchpad.book(key_bnorm_reduction,
+ sizeof(data_t) * C() * mkldnn_get_max_threads());
+
+ if (!is_training()) {
+ scratchpad.book(key_bnorm_tmp_mean, sizeof(data_t) * C());
+ scratchpad.book(key_bnorm_tmp_var, sizeof(data_t) * C());
+ }
+ }
+ }
+ };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ ncsp_batch_normalization_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ ~ncsp_batch_normalization_fwd_t() {}
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+struct ncsp_batch_normalization_bwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_batch_normalization_bwd_pd_t {
+ using cpu_batch_normalization_bwd_pd_t::cpu_batch_normalization_bwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ncsp_bnorm:any", ncsp_batch_normalization_bwd_t);
+
+ status_t init() {
+ using namespace data_type;
+ using namespace format_tag;
+
+ bool ok = true
+ && is_bwd()
+ && !has_zero_dim_memory()
+ && utils::everyone_is(f32, src_md()->data_type,
+ diff_src_md()->data_type)
+ && IMPLICATION(use_scaleshift(),
+ utils::everyone_is(f32,
+ weights_md()->data_type,
+ diff_weights_md()->data_type))
+ && memory_desc_matches_one_of_tag(*src_md(), ncdhw, nchw, nc)
+ && memory_desc_matches_one_of_tag(*diff_src_md(), ncdhw, nchw, nc)
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ if (fuse_bn_relu()) {
+ init_default_ws(8);
+ if (!compare_ws(hint_fwd_pd_))
+ return status::unimplemented;
+ }
+
+ init_scratchpad();
+
+ return status::success;
+ }
+
+ private:
+ void init_scratchpad() {
+ using namespace memory_tracking::names;
+ auto scratchpad = scratchpad_registry().registrar();
+ scratchpad.book(key_bnorm_reduction,
+ sizeof(data_t) * 2 * C() * mkldnn_get_max_threads());
+ if (!(use_scaleshift() && desc()->prop_kind == prop_kind::backward))
+ scratchpad.book(key_bnorm_tmp_diff_ss,
+ sizeof(data_t) * 2 * C());
+ }
+ };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ ncsp_batch_normalization_bwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ ~ncsp_batch_normalization_bwd_t() {}
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/nhwc_pooling.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/nhwc_pooling.cpp
new file mode 100644
index 0000000000..38cfb28dce
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/nhwc_pooling.cpp
@@ -0,0 +1,392 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <math.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+#include "nstl.hpp"
+
+#include "nhwc_pooling.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+#define MEM_D(name) name##_d
+
+#define DECLARE_READ_STRIDES(name) \
+ const size_t name##_n_stride = MEM_D(name).blocking_desc().strides[0]; \
+ const size_t name##_d_stride = (!is_3d) \
+ ? 0 \
+ : MEM_D(name).blocking_desc().strides[2]; \
+ const size_t name##_h_stride = (!is_3d) \
+ ? MEM_D(name).blocking_desc().strides[2] \
+ : MEM_D(name).blocking_desc().strides[3]; \
+ const size_t name##_w_stride = (!is_3d) \
+ ? MEM_D(name).blocking_desc().strides[3] \
+ : MEM_D(name).blocking_desc().strides[4];
+
+namespace nhwc_pooling {
+ size_t strided_offset(const int _n, const size_t _sn,
+ const int _d, const size_t _sd,
+ const int _h, const size_t _sh,
+ const int _w, const size_t _sw)
+ {
+ return _n * _sn
+ + _d * _sd
+ + _h * _sh
+ + _w * _sw;
+ }
+}
+
+template <impl::data_type_t data_type>
+void nhwc_pooling_fwd_t<data_type>::array_div_by_const(const int n,
+ const data_t *src, const size_t num, data_t *dst) const
+{
+ for (int i = 0; i < n; ++i)
+ {
+ float ftmp = (float)src[i];
+ ftmp = ftmp / num;
+ dst[i] = math::out_round<data_t>(ftmp);
+ }
+}
+
+template <impl::data_type_t data_type>
+void nhwc_pooling_fwd_t<data_type>::array_add(const int n, const data_t *src,
+ data_t *dst) const
+{
+ for (int i = 0; i < n; ++i)
+ {
+ dst[i] += src[i];
+ }
+}
+
+template <impl::data_type_t data_type>
+void nhwc_pooling_fwd_t<data_type>::execute_forward(
+ const exec_ctx_t &ctx) const {
+ using namespace alg_kind;
+ using namespace prop_kind;
+ using namespace nhwc_pooling;
+
+ auto alg = pd()->desc()->alg_kind;
+
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+ auto ws = CTX_OUT_MEM(unsigned char *, MKLDNN_ARG_WORKSPACE);
+
+ const memory_desc_wrapper MEM_D(src)(pd()->src_md());
+ const memory_desc_wrapper MEM_D(dst)(pd()->dst_md());
+ const memory_desc_wrapper MEM_D(ws)(pd()->workspace_md());
+
+ const int ID = pd()->ID();
+ const int IH = pd()->IH();
+ const int IW = pd()->IW();
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+ const int SD = pd()->KSD();
+ const int SH = pd()->KSH();
+ const int SW = pd()->KSW();
+ const int padF = pd()->padFront();
+ const int padT = pd()->padT();
+ const int padL = pd()->padL();
+ const int MB = pd()->MB();
+ const int OC = pd()->C();
+ const int OD = pd()->OD();
+ const int OH = pd()->OH();
+ const int OW = pd()->OW();
+
+ const bool is_3d = pd()->desc()->src_desc.ndims == 5;
+ const data_type_t ws_dt = ws ? ws_d.data_type() : data_type::undef;
+
+ DECLARE_READ_STRIDES(src);
+ DECLARE_READ_STRIDES(dst);
+
+ auto apply_offset = [=](int index, int offset) {
+ return (index > offset) ? index - offset : 0;
+ };
+
+ parallel_nd(MB, OD, OH, OW,
+ [&](int mb, int od, int oh, int ow) {
+ size_t dst_offset_init = strided_offset(mb, dst_n_stride,
+ od, dst_d_stride,
+ oh, dst_h_stride,
+ ow, dst_w_stride);
+ if (alg == pooling_max) {
+ size_t ws_offset_init = 0;
+ if (ws)
+ {
+ DECLARE_READ_STRIDES(ws);
+ ws_offset_init = strided_offset(mb, ws_n_stride,
+ od, ws_d_stride,
+ oh, ws_h_stride,
+ ow, ws_w_stride);
+ }
+ // Note: GCC 4.8.5 won't vectorize below
+ // simple loops unless they are singled out
+ // into separate helper routines:
+ // array_nhwc_initialize, array_nhwc_max
+ if (!ws)
+ array_nhwc_initialize<false>(OC, dst + dst_offset_init,
+ ws, ws_offset_init, ws_dt);
+ else
+ array_nhwc_initialize<true>(OC, dst + dst_offset_init,
+ ws, ws_offset_init, ws_dt);
+
+
+ for (int kd = 0; kd < KD; ++kd)
+ for (int kh = 0; kh < KH; ++kh)
+ for (int kw = 0; kw < KW; ++kw) {
+ const int id = od * SD - padF + kd;
+ const int ih = oh * SH - padT + kh;
+ const int iw = ow * SW - padL + kw;
+
+ if (id < 0 || id >= ID)
+ continue;
+ if (ih < 0 || ih >= IH)
+ continue;
+ if (iw < 0 || iw >= IW)
+ continue;
+
+ size_t src_offset_init = strided_offset(mb, src_n_stride,
+ id, src_d_stride,
+ ih, src_h_stride,
+ iw, src_w_stride);
+
+ if (!ws)
+ array_nhwc_max<false>(OC,
+ dst + dst_offset_init,
+ src + src_offset_init,
+ ws, ws_offset_init,
+ ws_dt,
+ kd * KH * KW + kh * KW + kw
+ );
+ else
+ array_nhwc_max<true>(OC,
+ dst + dst_offset_init,
+ src + src_offset_init,
+ ws, ws_offset_init,
+ ws_dt,
+ kd * KH * KW + kh * KW + kw
+ );
+ }
+ } else {
+ // pooling_avg
+ auto d = dst + dst_offset_init;
+
+ utils::array_set(d, 0, OC);
+
+ auto id_start = apply_offset(od * SD, padF);
+ auto ih_start = apply_offset(oh * SH, padT);
+ auto iw_start = apply_offset(ow * SW, padL);
+ auto id_end = nstl::min(od * SD - padF + KD, ID);
+ auto ih_end = nstl::min(oh * SH - padT + KH, IH);
+ auto iw_end = nstl::min(ow * SW - padL + KW, IW);
+
+ // it is cheaper to actually count this in a loop
+ // as the typical kernel is small
+ size_t num_summands = 0;
+
+ for (int id = id_start; id < id_end; ++id)
+ for (int ih = ih_start; ih < ih_end; ++ih)
+ for (int iw = iw_start; iw < iw_end; ++iw) {
+ size_t src_offset_init = strided_offset(mb, src_n_stride,
+ id, src_d_stride,
+ ih, src_h_stride,
+ iw, src_w_stride);
+ auto s = src + src_offset_init;
+
+ // need to move the loop to separate function
+ // for GCC 4.8.5 to vectorize
+ array_add(OC, s, d);
+
+ num_summands++;
+ }
+
+ num_summands = (alg == pooling_avg_include_padding) ?
+ KW * KH * KD : num_summands;
+
+ // need to move the loop to separate function
+ // for GCC 4.8.5 to vectorize
+ array_div_by_const(OC, d, num_summands, d);
+ }
+ });
+}
+
+template <impl::data_type_t data_type>
+void nhwc_pooling_bwd_t<data_type>::execute_backward(
+ const exec_ctx_t &ctx) const {
+ using namespace alg_kind;
+ using namespace nhwc_pooling;
+
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto ws = CTX_IN_MEM(const unsigned char *, MKLDNN_ARG_WORKSPACE);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper MEM_D(diff_src)(pd()->diff_src_md());
+ const memory_desc_wrapper MEM_D(diff_dst)(pd()->diff_dst_md());
+ const memory_desc_wrapper MEM_D(ws)(pd()->workspace_md());
+
+ const int ID = pd()->ID();
+ const int IH = pd()->IH();
+ const int IW = pd()->IW();
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+ const int SD = pd()->KSD();
+ const int SH = pd()->KSH();
+ const int SW = pd()->KSW();
+ const int OC = pd()->C();
+ const int padF = pd()->padFront();
+ const int padT = pd()->padT();
+ const int padL = pd()->padL();
+ const int OD = pd()->OD();
+ const int OH = pd()->OH();
+ const int OW = pd()->OW();
+
+ const bool is_3d = pd()->desc()->diff_src_desc.ndims == 5;
+ auto alg = pd()->desc()->alg_kind;
+
+ DECLARE_READ_STRIDES(diff_src);
+ DECLARE_READ_STRIDES(diff_dst);
+
+ auto apply_offset = [=](int index, int offset) {
+ return (index > offset) ? index - offset : 0;
+ };
+
+ const int MB = pd()->MB();
+
+ parallel_nd(MB, ID, IH, IW,
+ [&](int mb, int id, int ih, int iw) {
+ size_t src_offset_init = strided_offset(mb, diff_src_n_stride,
+ id, diff_src_d_stride,
+ ih, diff_src_h_stride,
+ iw, diff_src_w_stride);
+
+ // check if kernel windows are disjoint, in this case there's no
+ // update needed and we just write there once, no initialization
+ // required.
+ if (!(KD == SD && KH == SH && KW == SW))
+ for (int oc = 0; oc < OC; ++oc)
+ diff_src[src_offset_init + oc] = data_type_t(0);
+
+ // Find out which output cells may correspond to current
+ // input position. Current input postition divided by
+ // stride, with integer divide rounding down, is the
+ // right-most output.
+ // Left-most output may be computed if we decrement input
+ // by (kernel_size - 1) and then do the same division by
+ // stride.
+ int od_left = nstl::max((id + padF - KD + 1) / SD, 0);
+ int oh_left = nstl::max((ih + padT - KH + 1) / SH, 0);
+ int ow_left = nstl::max((iw + padL - KW + 1) / SW, 0);
+ // Notice +1 here to preserve the C loop "less than"
+ // condition for continuing the for loop.
+ int od_right = nstl::min((id + padF) / SD + 1 , OD);
+ int oh_right = nstl::min((ih + padT) / SH + 1 , OH);
+ int ow_right = nstl::min((iw + padL) / SW + 1 , OW);
+
+ for (int od = od_left; od < od_right; ++od)
+ for (int oh = oh_left; oh < oh_right; ++oh)
+ for (int ow = ow_left; ow < ow_right; ++ow) {
+ const int kd = id - od*SD + padF;
+ const int kh = ih - oh*SH + padT;
+ const int kw = iw - ow*SW + padL;
+
+ if (kd < 0 || kd >= KD)
+ continue;
+ if (kh < 0 || kh >= KH)
+ continue;
+ if (kw < 0 || kw >= KW)
+ continue;
+
+ size_t dst_offset_init = strided_offset(mb, diff_dst_n_stride,
+ od, diff_dst_d_stride,
+ oh, diff_dst_h_stride,
+ ow, diff_dst_w_stride);
+
+ if (alg == pooling_max) {
+ DECLARE_READ_STRIDES(ws);
+ size_t ws_offset_init = strided_offset(mb, ws_n_stride,
+ od, ws_d_stride,
+ oh, ws_h_stride,
+ ow, ws_w_stride);
+ const int index = kd * KH * KW + kh * KW + kw;
+
+ PRAGMA_OMP_SIMD()
+ for (int oc = 0; oc < OC; ++oc) {
+ const int index_from_ws =
+ (MEM_D(ws).data_type() == data_type::u8)
+ ? (int)ws[ws_offset_init + oc]
+ : ((int *)ws)[ws_offset_init + oc];
+
+ const data_t d = diff_dst[dst_offset_init + oc];
+
+ // Check if kernel windows are disjoint, in this case
+ // there's no update needed and we just write there once
+ // otherwise we add value to the contents.
+ if (!(KD == SD && KH == SH && KW == SW))
+ diff_src[src_offset_init + oc] +=
+ (index_from_ws == index)
+ ? d
+ : data_type_t(0);
+ else
+ diff_src[src_offset_init + oc] =
+ (index_from_ws == index)
+ ? d
+ : data_type_t(0);
+ }
+ } else {
+ // pooling_avg
+ auto id_start = apply_offset(od*SD, padF);
+ auto ih_start = apply_offset(oh*SH, padT);
+ auto iw_start = apply_offset(ow*SW, padL);
+ auto id_end = nstl::min(od*SD - padF + KD, ID);
+ auto ih_end = nstl::min(oh*SH - padT + KH, IH);
+ auto iw_end = nstl::min(ow*SW - padL + KW, IW);
+
+ auto num_summands = (alg == pooling_avg_include_padding)
+ ? KW*KH*KD
+ : (ih_end - ih_start)*(iw_end - iw_start)*(id_end - id_start);
+
+ PRAGMA_OMP_SIMD()
+ for (int oc = 0; oc < OC; ++oc) {
+ const data_t d = diff_dst[dst_offset_init + oc];
+ // Check if kernel windows are disjoint, in this case
+ // there's no update needed and we just write there once
+ // otherwise we add value to the contents.
+ if (!(KD == SD && KH == SH && KW == SW))
+ diff_src[src_offset_init + oc] += d / num_summands;
+ else
+ diff_src[src_offset_init + oc] = d / num_summands;
+ }
+ }
+ }
+ });
+}
+
+template struct nhwc_pooling_fwd_t<data_type::f32>;
+template struct nhwc_pooling_bwd_t<data_type::f32>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/nhwc_pooling.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/nhwc_pooling.hpp
new file mode 100644
index 0000000000..7e33b6869f
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/nhwc_pooling.hpp
@@ -0,0 +1,210 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_NHWC_POOLING_HPP
+#define CPU_NHWC_POOLING_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_pooling_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace nhwc_pooling {
+size_t strided_offset(const int _n, const size_t _sn, const int _d,
+ const size_t _sd, const int _h, const size_t _sh, const int _w,
+ const size_t _sw);
+}
+
+template <impl::data_type_t data_type>
+struct nhwc_pooling_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_pooling_fwd_pd_t {
+ using cpu_pooling_fwd_pd_t::cpu_pooling_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T("nhwc_pooling:any", nhwc_pooling_fwd_t);
+
+ status_t init() {
+ const format_tag_t desired_fmt_tag =
+ ndims() == 4 ? format_tag::nhwc : format_tag::ndhwc;
+
+ bool ok = true
+ && set_default_params() == status::success
+ && is_fwd()
+ && utils::one_of(desc()->alg_kind, alg_kind::pooling_max,
+ alg_kind::pooling_avg_include_padding,
+ alg_kind::pooling_avg_exclude_padding)
+ && utils::everyone_is(data_type,
+ src_md()->data_type,
+ dst_md()->data_type)
+ && attr()->has_default_values()
+ && memory_desc_matches_tag(*src_md(), desired_fmt_tag)
+ && memory_desc_matches_tag(*dst_md(), desired_fmt_tag);
+ if (!ok) return status::unimplemented;
+
+ bool is_training = desc_.prop_kind == prop_kind::forward_training;
+ if (desc()->alg_kind == alg_kind::pooling_max && is_training)
+ init_default_ws();
+
+ return status::success;
+ }
+ };
+
+ nhwc_pooling_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ void array_div_by_const(const int n, const data_t *src, const size_t num,
+ data_t *dst) const;
+ void array_add(const int n, const data_t *src, data_t *dst) const;
+
+ template <bool use_workspace>
+ void array_nhwc_max(const int n, data_t *dst, const data_t *src,
+ unsigned char *ws, const size_t ws_offset, const data_type_t ws_dt,
+ const int index) const {
+ assert(!((use_workspace == false) ^ (!ws))); // ensure ws pointer exists
+ PRAGMA_OMP_SIMD()
+ for (int oc = 0; oc < n; ++oc) {
+ auto s = src[oc];
+ data_t mv = dst[oc];
+
+ // update index of maximum
+#if defined __INTEL_COMPILER
+ if ((use_workspace) && (s > mv)) {
+ assert(ws_dt == data_type::u8 || ws_dt == data_type::s32);
+ if (ws_dt == data_type::u8) {
+ assert(0 <= index && index <= 255);
+ ws[ws_offset + oc] = index;
+ } else
+ reinterpret_cast<int *>(ws)[ws_offset + oc] = index;
+ }
+#else
+ // Need to add explicit predicates for GCC to vectorize this.
+ // And although the resulting code is ugly, it is still 4 times
+ // faster than scalar
+ if (use_workspace) {
+ assert(ws_dt == data_type::u8 || ws_dt == data_type::s32);
+
+ if (ws_dt == data_type::u8) {
+ assert(0 <= index && index <= 255);
+ unsigned char predicate = (s > mv) ? 0xff : 0;
+ unsigned char current_value = ws[ws_offset + oc];
+ current_value = (predicate & (unsigned char)index)
+ | ((~predicate) & current_value);
+ ws[ws_offset + oc] = current_value;
+ } else {
+ auto wint = reinterpret_cast<int *>(ws);
+ unsigned int predicate = (s > mv) ? 0xffffffff : 0;
+ unsigned int current_value = wint[ws_offset + oc];
+ current_value = (predicate & (unsigned int)index)
+ | ((~predicate) & current_value);
+ wint[ws_offset + oc] = current_value;
+ }
+ }
+#endif
+ // update maximum
+ dst[oc] = nstl::max(s, mv);
+ }
+ }
+
+ template <bool use_workspace>
+ void array_nhwc_initialize(const int n, data_t *dst, unsigned char *ws,
+ const size_t ws_offset, const data_type_t ws_dt) const {
+ assert(!((use_workspace == false) ^ (!ws))); // ensure ws pointer exists
+ for (int oc = 0; oc < n; ++oc) {
+ if (use_workspace) {
+ assert(ws_dt == data_type::u8 || ws_dt == data_type::s32);
+ if (ws_dt == data_type::u8) {
+ ws[ws_offset + oc] = 0;
+ } else
+ reinterpret_cast<int *>(ws)[ws_offset + oc] = 0;
+ }
+ dst[oc] = nstl::numeric_limits<data_t>::lowest();
+ }
+ }
+
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t data_type>
+struct nhwc_pooling_bwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_pooling_bwd_pd_t {
+ using cpu_pooling_bwd_pd_t::cpu_pooling_bwd_pd_t;
+
+ DECLARE_COMMON_PD_T("nhwc:any", nhwc_pooling_bwd_t);
+
+ status_t init() {
+ const format_tag_t desired_fmt_tag =
+ ndims() == 4 ? format_tag::nchw : format_tag::ncdhw;
+
+ bool ok = true
+ && set_default_params() == status::success
+ && !is_fwd()
+ && utils::one_of(desc()->alg_kind, alg_kind::pooling_max,
+ alg_kind::pooling_avg_include_padding,
+ alg_kind::pooling_avg_exclude_padding)
+ && utils::everyone_is(data_type,
+ diff_dst_md()->data_type,
+ diff_src_md()->data_type)
+ && attr()->has_default_values()
+ && memory_desc_matches_tag(*diff_dst_md(), desired_fmt_tag)
+ && memory_desc_matches_tag(*diff_src_md(), desired_fmt_tag);
+ if (!ok) return status::unimplemented;
+
+ if (desc()->alg_kind == alg_kind::pooling_max) {
+ init_default_ws();
+ if (!compare_ws(hint_fwd_pd_))
+ return status::unimplemented;
+ }
+
+ return status::success;
+ }
+ };
+
+ nhwc_pooling_bwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}// namespace cpu
+}// namespace impl
+}// namespace mkldnn
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/nspc_batch_normalization.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/nspc_batch_normalization.cpp
new file mode 100644
index 0000000000..e20333e66f
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/nspc_batch_normalization.cpp
@@ -0,0 +1,288 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <math.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+
+#include "cpu_batch_normalization_utils.hpp"
+#include "jit_generator.hpp"
+
+#include "nspc_batch_normalization.hpp"
+
+// clang 6 and 7 generate incorrect code with OMP_SIMD in some particular cases
+#if (defined __clang_major__) && (__clang_major__ >= 6)
+#define SAFE_TO_USE_OMP_SIMD 0
+#else
+#define SAFE_TO_USE_OMP_SIMD 1
+#endif
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace memory_tracking::names;
+
+void nspc_batch_normalization_fwd_t::execute_forward(
+ const exec_ctx_t &ctx) const {
+ const bool save_stats = pd()->is_training();
+ const bool is_training = pd()->is_training();
+ const bool fuse_bn_relu = pd()->fuse_bn_relu();
+ const bool calculate_stats = !pd()->stats_is_src();
+ const bool with_relu = pd()->with_relu_post_op();
+
+ auto scratchpad = this->scratchpad(ctx);
+ auto tmp_mean = scratchpad.get<data_t>(key_bnorm_tmp_mean);
+ auto tmp_var = scratchpad.get<data_t>(key_bnorm_tmp_var);
+ auto *ws_reduce = scratchpad.get<data_t>(key_bnorm_reduction);
+
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto scaleshift = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SCALE_SHIFT);
+
+ data_t *mean, *variance;
+ if (!calculate_stats) {
+ mean = const_cast<data_t *>(
+ CTX_IN_MEM(const data_t *, MKLDNN_ARG_MEAN));
+ variance = const_cast<data_t *>(
+ CTX_IN_MEM(const data_t *, MKLDNN_ARG_VARIANCE));
+ } else {
+ if (save_stats) {
+ mean = CTX_OUT_MEM(data_t *, MKLDNN_ARG_MEAN);
+ variance = CTX_OUT_MEM(data_t *, MKLDNN_ARG_VARIANCE);
+ } else {
+ mean = tmp_mean;
+ variance = tmp_var;
+ }
+ }
+
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+ auto ws = CTX_OUT_MEM(uint8_t *, MKLDNN_ARG_WORKSPACE);
+
+ const dim_t N = pd()->MB();
+ const dim_t C = pd()->C();
+ const dim_t SP = pd()->H() * pd()->W() * pd()->D();
+
+ const float eps = pd()->desc()->batch_norm_epsilon;
+ const bool use_scaleshift = pd()->use_scaleshift();
+ auto maybe_post_op
+ = [&](data_t res) { return (with_relu && res < 0) ? 0 : res; };
+
+ assert(mkldnn_thr_syncable());
+ parallel(0, [&](const int ithr, const int nthr) {
+ dim_t N_s = 0, N_e = 0, C_s = 0, C_e = 0;
+ balance211(N, nthr, ithr, N_s, N_e);
+ balance211(C, nthr, ithr, C_s, C_e);
+ data_t *mean_loc = tmp_mean + nstl::max(C, (dim_t)16) * ithr;
+ data_t *variance_loc = tmp_var + nstl::max(C, (dim_t)16) * ithr;
+
+ if (calculate_stats) {
+ for (dim_t c = 0; c < C; c++)
+ ws_reduce[C * ithr + c] = 0.;
+
+ for (dim_t n = N_s; n < N_e; n++)
+ for (dim_t sp = 0; sp < SP; sp++)
+ PRAGMA_OMP_SIMD()
+ for (dim_t c = 0; c < C; c++)
+ ws_reduce[C * ithr + c] += src[(size_t)n * SP * C
+ + sp * C + c];
+
+ mkldnn_thr_barrier();
+
+ for (dim_t c = C_s; c < C_e; c++) {
+ mean[c] = 0;
+ for (dim_t n = 0; n < nthr; n++)
+ mean[c] += ws_reduce[C * n + c];
+ mean[c] /= SP * N;
+ }
+
+ mkldnn_thr_barrier();
+
+ for (dim_t c = 0; c < C; c++) {
+ mean_loc[c] = mean[c];
+ ws_reduce[C * ithr + c] = 0.;
+ }
+
+ for (dim_t n = N_s; n < N_e; n++)
+ for (dim_t sp = 0; sp < SP; sp++)
+ PRAGMA_OMP_SIMD()
+ for (dim_t c = 0; c < C; c++) {
+ data_t m = src[(size_t)n * SP * C + sp * C + c]
+ - mean_loc[c];
+ ws_reduce[C * ithr + c] += m * m;
+ }
+
+ mkldnn_thr_barrier();
+
+ for (dim_t c = C_s; c < C_e; c++) {
+ variance[c] = 0;
+ for (dim_t n = 0; n < nthr; n++)
+ variance[c] += ws_reduce[C * n + c];
+ variance[c] /= SP * N;
+ }
+
+ mkldnn_thr_barrier();
+
+ for (dim_t c = 0; c < C; c++)
+ variance_loc[c] = variance[c];
+ } else {
+ variance_loc = variance;
+ mean_loc = mean;
+ }
+
+ for (dim_t n = N_s; n < N_e; n++) {
+ for (dim_t sp = 0; sp < SP; sp++) {
+#if SAFE_TO_USE_OMP_SIMD
+ PRAGMA_OMP_SIMD()
+#endif
+ for (dim_t c = 0; c < C; c++) {
+ data_t sqrt_variance = static_cast<data_t>(
+ sqrtf(variance_loc[c] + eps));
+ data_t sm = (use_scaleshift ? scaleshift[c] : 1.0f) / sqrt_variance;
+ data_t sv = use_scaleshift ? scaleshift[C + c] : 0;
+ size_t d_off = (size_t)n * SP * C + sp * C + c;
+ data_t bn_res = sm * (src[d_off] - mean_loc[c]) + sv;
+ if (fuse_bn_relu) {
+ if (bn_res <= 0) {
+ bn_res = 0;
+ if (is_training)
+ ws[d_off] = 0;
+ } else {
+ if (is_training)
+ ws[d_off] = 1;
+ }
+ }
+ dst[d_off] = maybe_post_op(bn_res);
+ }
+ }
+ }
+ });
+}
+
+void nspc_batch_normalization_bwd_t::execute_backward(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto mean = CTX_IN_MEM(const data_t *, MKLDNN_ARG_MEAN);
+ auto variance = CTX_IN_MEM(const data_t *, MKLDNN_ARG_VARIANCE);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto scaleshift = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SCALE_SHIFT);
+ auto ws = CTX_IN_MEM(const uint8_t *, MKLDNN_ARG_WORKSPACE);
+
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+ auto diff_scaleshift = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SCALE_SHIFT);
+
+ auto scratchpad = this->scratchpad(ctx);
+ auto tmp_diff_ss = scratchpad.get<data_t>(key_bnorm_tmp_diff_ss);
+
+ if (diff_scaleshift == nullptr)
+ diff_scaleshift = tmp_diff_ss;
+
+ const dim_t N = pd()->MB();
+ const dim_t C = pd()->C();
+ const dim_t SP = pd()->D() * pd()->H() * pd()->W();
+ data_t *diff_gamma = diff_scaleshift, *diff_beta = diff_scaleshift + C;
+ auto *ws_reduce = scratchpad.get<data_t>(key_bnorm_reduction);
+
+ const float eps = pd()->desc()->batch_norm_epsilon;
+ const bool use_scaleshift = pd()->use_scaleshift();
+ const bool calculate_diff_stats = !pd()->use_global_stats();
+ const bool fuse_bn_relu = pd()->fuse_bn_relu();
+
+ assert(mkldnn_thr_syncable());
+ parallel(0, [&](const int ithr, const int nthr) {
+ dim_t N_s = 0, N_e = 0, C_s = 0, C_e = 0;
+ balance211(N, nthr, ithr, N_s, N_e);
+ balance211(C, nthr, ithr, C_s, C_e);
+
+ data_t *diff_gamma_loc = tmp_diff_ss + 2 * C + C * ithr;
+ data_t *diff_beta_loc = tmp_diff_ss + 2 * C + C * (nthr + ithr);
+
+ for (dim_t c = 0; c < C; c++) {
+ ws_reduce[C * ithr + c] = 0.;
+ ws_reduce[C * nthr + C * ithr + c] = 0.;
+ }
+
+ for (dim_t n = N_s; n < N_e; n++)
+ for (dim_t sp = 0; sp < SP; sp++)
+#if SAFE_TO_USE_OMP_SIMD
+ PRAGMA_OMP_SIMD()
+#endif
+ for (dim_t c = 0; c < C; c++) {
+ const size_t d_off = (size_t)n * SP * C + sp * C + c;
+ data_t dd;
+ if (fuse_bn_relu)
+ dd = (!ws[d_off]) ? 0 : diff_dst[d_off];
+ else
+ dd = diff_dst[d_off];
+ ws_reduce[C * ithr + c] += (src[d_off] - mean[c]) * dd;
+ ws_reduce[C * nthr + C * ithr + c] += dd;
+ }
+
+ mkldnn_thr_barrier();
+
+ for (dim_t c = C_s; c < C_e; c++) {
+ data_t sqrt_variance
+ = static_cast<data_t>(1.0f / sqrtf(variance[c] + eps));
+ diff_gamma[c] = 0;
+ diff_beta[c] = 0;
+ for (dim_t n = 0; n < nthr; n++) {
+ diff_gamma[c] += ws_reduce[C * n + c];
+ diff_beta[c] += ws_reduce[C * nthr + C * n + c];
+ }
+ diff_gamma[c] *= sqrt_variance;
+ }
+
+ mkldnn_thr_barrier();
+
+ for (dim_t c = 0; c < C; c++) {
+ diff_gamma_loc[c] = diff_gamma[c];
+ diff_beta_loc[c] = diff_beta[c];
+ }
+
+ for (dim_t n = N_s; n < N_e; n++) {
+ for (dim_t sp = 0; sp < SP; sp++) {
+#if SAFE_TO_USE_OMP_SIMD
+ PRAGMA_OMP_SIMD()
+#endif
+ for (dim_t c = 0; c < C; c++) {
+ const size_t d_off = (size_t)n * SP * C + sp * C + c;
+ data_t gamma = use_scaleshift ? scaleshift[c] : 1;
+ data_t sqrt_variance
+ = static_cast<data_t>(1.0f / sqrtf(variance[c] + eps));
+ data_t v_diff_src;
+ if (fuse_bn_relu)
+ v_diff_src = (!ws[d_off]) ? 0 : diff_dst[d_off];
+ else
+ v_diff_src = diff_dst[d_off];
+ if (calculate_diff_stats) {
+ v_diff_src -= diff_beta_loc[c] / (SP * N)
+ + (src[d_off] - mean[c]) * diff_gamma_loc[c]
+ * sqrt_variance / (SP * N);
+ }
+ v_diff_src *= gamma * sqrt_variance;
+ diff_src[d_off] = v_diff_src;
+ }
+ }
+ }
+ });
+}
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/nspc_batch_normalization.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/nspc_batch_normalization.hpp
new file mode 100644
index 0000000000..aad86b05a7
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/nspc_batch_normalization.hpp
@@ -0,0 +1,169 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_NSPC_BATCH_NORMALIZATION_HPP
+#define CPU_NSPC_BATCH_NORMALIZATION_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_batch_normalization_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct nspc_batch_normalization_fwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_batch_normalization_fwd_pd_t {
+ pd_t(engine_t *engine, const batch_normalization_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const batch_normalization_fwd_pd_t *hint_fwd_pd)
+ : cpu_batch_normalization_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ {}
+
+ DECLARE_COMMON_PD_T("nspc_bnorm:any", nspc_batch_normalization_fwd_t);
+
+ status_t init() {
+ using namespace data_type;
+ using namespace prop_kind;
+
+ bool ok = true
+ /* the algorithm requires barriers while switching
+ * between parallelization over N and C dimensions */
+ && mkldnn_thr_syncable()
+ && is_fwd()
+ && !has_zero_dim_memory()
+ && src_md()->data_type == f32
+ && IMPLICATION(use_scaleshift(), weights_md()->data_type == f32)
+ && memory_desc_matches_tag(*src_md(), format_tag::nhwc)
+ && (attr()->has_default_values() || this->with_relu_post_op());
+ if (!ok) return status::unimplemented;
+
+ if (is_training() && fuse_bn_relu()) init_default_ws(8);
+
+ init_scratchpad();
+
+ return status::success;
+ }
+
+ private:
+ void init_scratchpad() {
+ using namespace memory_tracking::names;
+ auto scratchpad = scratchpad_registry().registrar();
+ if (!stats_is_src()) {
+ dim_t sz = nstl::max<dim_t>(C(), 16) * mkldnn_get_max_threads();
+ scratchpad.book(key_bnorm_reduction, sizeof(data_t) * sz);
+ scratchpad.book(key_bnorm_tmp_mean, sizeof(data_t) * sz);
+ scratchpad.book(key_bnorm_tmp_var, sizeof(data_t) * sz);
+ }
+ }
+ };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ nspc_batch_normalization_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ ~nspc_batch_normalization_fwd_t() {}
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+struct nspc_batch_normalization_bwd_t : public cpu_primitive_t {
+ struct pd_t : public cpu_batch_normalization_bwd_pd_t {
+ pd_t(engine_t *engine, const batch_normalization_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const batch_normalization_fwd_pd_t *hint_fwd_pd)
+ : cpu_batch_normalization_bwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ {}
+
+ DECLARE_COMMON_PD_T("nspc_bnorm:any", nspc_batch_normalization_bwd_t);
+
+ status_t init() {
+ using namespace data_type;
+ using namespace prop_kind;
+
+ bool ok = true
+ /* the algorithm requires barriers while switching
+ * between parallelization over N and C dimensions */
+ && mkldnn_thr_syncable()
+ && is_bwd()
+ && !has_zero_dim_memory()
+ && utils::everyone_is(f32, src_md()->data_type,
+ diff_src_md()->data_type)
+ && IMPLICATION(use_scaleshift(),
+ utils::everyone_is(f32,
+ weights_md()->data_type,
+ diff_weights_md()->data_type))
+ && memory_desc_matches_tag(*src_md(), format_tag::nhwc)
+ && memory_desc_matches_tag(*diff_src_md(), format_tag::nhwc)
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ if (fuse_bn_relu()) {
+ init_default_ws(8);
+ if (!compare_ws(hint_fwd_pd_))
+ return status::unimplemented;
+ }
+
+ init_scratchpad();
+
+ return status::success;
+ }
+
+ private:
+ void init_scratchpad() {
+ using namespace memory_tracking::names;
+ auto scratchpad = scratchpad_registry().registrar();
+ scratchpad.book(key_bnorm_reduction,
+ sizeof(data_t) * 2 * C() * mkldnn_get_max_threads());
+ scratchpad.book(key_bnorm_tmp_diff_ss, sizeof(data_t) * 2 * C()
+ * (mkldnn_get_max_threads() + 1));
+ }
+ };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ nspc_batch_normalization_bwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ ~nspc_batch_normalization_bwd_t() {}
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_batch_normalization.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_batch_normalization.cpp
new file mode 100644
index 0000000000..d79b1a034b
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_batch_normalization.cpp
@@ -0,0 +1,265 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <math.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "mkldnn_thread.hpp"
+#include "simple_q10n.hpp"
+
+#include "ref_batch_normalization.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t data_type>
+void ref_batch_normalization_fwd_t<data_type>::execute_forward(
+ const exec_ctx_t &ctx) const {
+ /* fast return */
+ if (this->pd()->has_zero_dim_memory()) return;
+
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto scaleshift = CTX_IN_MEM(const float *, MKLDNN_ARG_SCALE_SHIFT);
+
+ auto mean = pd()->stats_is_src()
+ ? const_cast<float *>(CTX_IN_MEM(const float *, MKLDNN_ARG_MEAN))
+ : CTX_OUT_MEM(float *, MKLDNN_ARG_MEAN);
+ auto variance = pd()->stats_is_src()
+ ? const_cast<float *>(CTX_IN_MEM(const float *, MKLDNN_ARG_VARIANCE))
+ : CTX_OUT_MEM(float *, MKLDNN_ARG_VARIANCE);
+
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+ auto ws = CTX_OUT_MEM(uint8_t *, MKLDNN_ARG_WORKSPACE);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+ const memory_desc_wrapper scaleshift_d(pd()->weights_md());
+
+ const dim_t N = pd()->MB();
+ const dim_t C = pd()->C();
+ dim_t H = 1, W = 1, D = 1;
+ const bool has_spatial = utils::one_of(data_d.ndims(), 4, 5);
+ if (has_spatial) {
+ D = pd()->D();
+ H = pd()->H();
+ W = pd()->W();
+ }
+
+ const float eps = pd()->desc()->batch_norm_epsilon;
+ const bool use_scaleshift = pd()->use_scaleshift();;
+ const bool save_stats = pd()->is_training();
+ const bool is_training = pd()->is_training();
+ const bool fuse_bn_relu = pd()->fuse_bn_relu();
+ const bool calculate_stats = !pd()->stats_is_src();
+
+ const bool with_relu = pd()->with_relu_post_op();
+ auto maybe_post_op = [&](float res) {
+ return (with_relu && res < 0.0f) ? 0.0f : res;
+ };
+ const bool is_3d = data_d.ndims() == 5;
+
+ auto data_offset = [&](const memory_desc_wrapper &data_d, dim_t n, dim_t c,
+ dim_t d, dim_t h, dim_t w) {
+ if (has_spatial) {
+ if (is_3d)
+ return data_d.off(n, c, d, h, w);
+ else
+ return data_d.off(n, c, h, w);
+ } else
+ return data_d.off(n, c);
+ };
+
+ parallel_nd(C, [&](dim_t c) {
+ float v_mean = calculate_stats ? 0 : mean[c];
+ float v_variance = calculate_stats ? 0 : variance[c];
+
+ if (calculate_stats) {
+ for (dim_t n = 0; n < N; ++n)
+ for (dim_t d = 0; d < D; ++d)
+ for (dim_t h = 0; h < H; ++h)
+ for (dim_t w = 0; w < W; ++w)
+ v_mean += src[data_offset(data_d, n, c, d, h, w)];
+ v_mean /= W*N*H*D;
+
+ for (dim_t n = 0; n < N; ++n)
+ for (dim_t d = 0; d < D; ++d)
+ for (dim_t h = 0; h < H; ++h)
+ for (dim_t w = 0; w < W; ++w) {
+ float m = src[data_offset(data_d, n, c, d, h, w)] - v_mean;
+ v_variance += m*m;
+ }
+ v_variance /= W*H*N*D;
+ }
+
+ float sqrt_variance = sqrtf(v_variance + eps);
+ float sm = (use_scaleshift
+ ? scaleshift[scaleshift_d.off(0, c)]
+ : 1.0f) / sqrt_variance;
+ float sv = use_scaleshift ? scaleshift[scaleshift_d.off(1, c)] : 0;
+
+ for (dim_t n = 0; n < N; ++n)
+ for (dim_t d = 0; d < D; ++d)
+ for (dim_t h = 0; h < H; ++h)
+ for (dim_t w = 0; w < W; ++w) {
+ auto d_off = data_offset(data_d,n,c,d,h,w);
+ float bn_res = sm * ((float)src[d_off] - v_mean) + sv;
+ if (fuse_bn_relu) {
+ if (bn_res <= 0) {
+ bn_res = 0;
+ if (is_training)
+ ws[d_off] = 0;
+ } else {
+ if (is_training)
+ ws[d_off] = 1;
+ }
+ }
+ if (data_type == data_type::s8) {
+ dst[d_off] = qz_a1b0<float, data_t>()(maybe_post_op(bn_res));
+ } else {
+ dst[d_off] = static_cast<data_t>(maybe_post_op(bn_res));
+ }
+ }
+
+ if (calculate_stats) {
+ if (save_stats) {
+ mean[c] = v_mean;
+ variance[c] = v_variance;
+ }
+ }
+ });
+}
+
+template struct ref_batch_normalization_fwd_t<data_type::f32>;
+template struct ref_batch_normalization_fwd_t<data_type::s8>;
+
+template <impl::data_type_t data_type>
+void ref_batch_normalization_bwd_t<data_type>::execute_backward(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto mean = CTX_IN_MEM(const data_t *, MKLDNN_ARG_MEAN);
+ auto variance = CTX_IN_MEM(const data_t *, MKLDNN_ARG_VARIANCE);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto scaleshift = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SCALE_SHIFT);
+ auto ws = CTX_IN_MEM(const uint8_t *, MKLDNN_ARG_WORKSPACE);
+
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+ auto diff_scaleshift = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SCALE_SHIFT);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+ const memory_desc_wrapper diff_data_d(pd()->diff_src_md());
+ const memory_desc_wrapper scaleshift_d(pd()->weights_md());
+ const memory_desc_wrapper diff_scaleshift_d(pd()->diff_weights_md());
+
+ const dim_t C = pd()->C();
+
+ /* fast return */
+ if (this->pd()->has_zero_dim_memory()) {
+ if (diff_scaleshift) {
+ for (dim_t c = 0; c < C; ++c) {
+ diff_scaleshift[diff_scaleshift_d.off(0, c)] = 0;
+ diff_scaleshift[diff_scaleshift_d.off(1, c)] = 0;
+ }
+ }
+ return;
+ }
+
+ const dim_t N = pd()->MB();
+ dim_t H = 1, W = 1, D = 1;
+ const bool has_spatial = utils::one_of(data_d.ndims(), 4, 5);
+ if (has_spatial) {
+ D = pd()->D();
+ H = pd()->H();
+ W = pd()->W();
+ }
+
+ const float eps = pd()->desc()->batch_norm_epsilon;
+ const bool use_scaleshift = pd()->use_scaleshift();
+ const bool calculate_diff_stats = !pd()->use_global_stats();
+ const bool fuse_bn_relu = pd()->fuse_bn_relu();
+
+ const bool is_3d = data_d.ndims() == 5;
+
+ auto data_offset = [&](const memory_desc_wrapper &data_d, dim_t n, dim_t c,
+ dim_t d, dim_t h, dim_t w) {
+ if (has_spatial) {
+ if (is_3d)
+ return data_d.off(n, c, d, h, w);
+ else
+ return data_d.off(n, c, h, w);
+ } else
+ return data_d.off(n, c);
+ };
+
+ parallel_nd(C, [&](dim_t c) {
+ data_t v_mean = mean[c];
+ data_t v_variance = variance[c];
+ data_t sqrt_variance = static_cast<data_t>(1.0f / sqrtf(v_variance + eps));
+ data_t gamma = use_scaleshift ? scaleshift[scaleshift_d.off(0, c)] : 1;
+ data_t diff_gamma = data_t(0);
+ data_t diff_beta = data_t(0);
+ diff_gamma = 0.0;
+ diff_beta = 0.0;
+
+ for (dim_t n = 0; n < N; ++n)
+ for (dim_t d = 0; d < D; ++d)
+ for (dim_t h = 0; h < H; ++h)
+ for (dim_t w = 0; w < W; ++w) {
+ const size_t s_off = data_offset(data_d, n, c, d, h, w);
+ data_t dd = diff_dst[data_offset(diff_data_d, n, c, d, h, w)];
+ if (fuse_bn_relu && !ws[s_off])
+ dd = 0;
+
+ diff_gamma += (src[s_off] - v_mean) * dd;
+ diff_beta += dd;
+ }
+ diff_gamma *= sqrt_variance;
+
+ if (diff_scaleshift) {
+ diff_scaleshift[diff_scaleshift_d.off(0, c)] = diff_gamma;
+ diff_scaleshift[diff_scaleshift_d.off(1, c)] = diff_beta;
+ }
+
+ for (dim_t n = 0; n < N; ++n)
+ for (dim_t d = 0; d < D; ++d)
+ for (dim_t h = 0; h < H; ++h)
+ for (dim_t w = 0; w < W; ++w) {
+ const size_t s_off = data_offset(data_d, n, c, d, h, w);
+ const size_t dd_off = data_offset(diff_data_d, n, c, d, h, w);
+ data_t dd = diff_dst[dd_off];
+ if (fuse_bn_relu && !ws[s_off])
+ dd = 0;
+
+ data_t v_diff_src = dd;
+ if (calculate_diff_stats) {
+ v_diff_src -= diff_beta/(D*W*H*N) +
+ (src[s_off] - v_mean) *
+ diff_gamma*sqrt_variance/(D*W*H*N);
+ }
+ v_diff_src *= gamma*sqrt_variance;
+ diff_src[dd_off] = v_diff_src;
+ }
+ });
+}
+
+template struct ref_batch_normalization_bwd_t<data_type::f32>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_batch_normalization.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_batch_normalization.hpp
new file mode 100644
index 0000000000..aa9f74125a
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_batch_normalization.hpp
@@ -0,0 +1,127 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REF_BATCH_NORMALIZATION_HPP
+#define CPU_REF_BATCH_NORMALIZATION_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_batch_normalization_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t data_type>
+struct ref_batch_normalization_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_batch_normalization_fwd_pd_t {
+ pd_t(engine_t *engine, const batch_normalization_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const batch_normalization_fwd_pd_t *hint_fwd_pd)
+ : cpu_batch_normalization_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ {}
+
+ DECLARE_COMMON_PD_T("ref:any", ref_batch_normalization_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && src_md()->data_type == data_type
+ && IMPLICATION(use_scaleshift(),
+ weights_md()->data_type == data_type::f32)
+ && (attr()->has_default_values() || with_relu_post_op());
+ if (!ok) return status::unimplemented;
+
+ if (src_md()->data_type == data_type::s8 && !stats_is_src())
+ return status::unimplemented;
+
+ if (is_training() && fuse_bn_relu()) init_default_ws(8);
+
+ return status::success;
+ }
+ };
+
+ ref_batch_normalization_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t data_type>
+struct ref_batch_normalization_bwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_batch_normalization_bwd_pd_t {
+ pd_t(engine_t *engine, const batch_normalization_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const batch_normalization_fwd_pd_t *hint_fwd_pd)
+ : cpu_batch_normalization_bwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ {}
+
+ DECLARE_COMMON_PD_T("ref:any", ref_batch_normalization_bwd_t);
+
+ status_t init() {
+ bool ok = true
+ && is_bwd()
+ && utils::everyone_is(data_type, src_md()->data_type,
+ diff_src_md()->data_type)
+ && IMPLICATION(use_scaleshift(), utils::everyone_is(data_type,
+ weights_md()->data_type,
+ diff_weights_md()->data_type))
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ if (fuse_bn_relu()) {
+ init_default_ws(8);
+ if (!compare_ws(hint_fwd_pd_))
+ return status::unimplemented;
+ }
+
+ return status::success;
+ }
+ };
+
+ ref_batch_normalization_bwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_concat.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_concat.hpp
new file mode 100644
index 0000000000..4c534b5508
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_concat.hpp
@@ -0,0 +1,97 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef REF_CONCAT_HPP
+#define REF_CONCAT_HPP
+
+#include "reorder_pd.hpp"
+
+#include "cpu_concat_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct ref_concat_t: public cpu_primitive_t {
+ struct pd_t: public cpu_concat_pd_t {
+ using cpu_concat_pd_t::cpu_concat_pd_t;
+
+ pd_t(const pd_t &rhs): cpu_concat_pd_t(rhs) {
+ for (size_t i = 0; i < rhs.reorder_pds_.size(); ++i)
+ reorder_pds_.push_back(
+ (const reorder_pd_t *)rhs.reorder_pds_[i]->clone());
+ }
+ ~pd_t() { for (auto &rpd: reorder_pds_) delete rpd; }
+
+ DECLARE_CONCAT_PD_T("ref:any", ref_concat_t);
+
+ status_t init() {
+ bool ok = cpu_concat_pd_t::init() == status::success;
+ if (!ok) return status::unimplemented;
+
+ for (int i = 0; i < n_; ++i) {
+ auto r_impls = engine_->get_reorder_implementation_list();
+ for (auto r = r_impls; *r; ++r) {
+ const primitive_attr_t attr; /* alpha == 1. */
+ reorder_pd_t *r_pd = nullptr;
+ if ((*r)(&r_pd, engine_, &attr, engine_, src_md(i),
+ engine_, src_image_md(i)) == status::success) {
+ r_pd->init_info();
+ reorder_pds_.push_back(r_pd);
+ break;
+ }
+ }
+ }
+
+ ok = reorder_pds_.size() == (size_t)n_;
+ return ok ? status::success : status::unimplemented;
+ }
+
+ nstl::vector<const reorder_pd_t *> reorder_pds_;
+ };
+
+ ref_concat_t(const pd_t *apd): cpu_primitive_t(apd) {
+ const int n = pd()->n_inputs();
+ reorders_.resize(n);
+ for (int i = 0; i < n; ++i)
+ pd()->reorder_pds_[i]->create_primitive(&reorders_[i]);
+ }
+
+ ~ref_concat_t() { for (auto &r: reorders_) delete r; }
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ const auto n = pd()->n_inputs();
+ for (int i = 0; i < n; ++i) {
+ exec_args_t r_args;
+ r_args[MKLDNN_ARG_SRC] = ctx.args().at(MKLDNN_ARG_MULTIPLE_SRC + i);
+ r_args[MKLDNN_ARG_DST] = ctx.args().at(MKLDNN_ARG_DST);
+ exec_ctx_t r_ctx(ctx.stream(), std::move(r_args));
+ reorders_[i]->execute(r_ctx);
+ }
+ return status::success;
+ }
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ nstl::vector<primitive_t *> reorders_;
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_convolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_convolution.cpp
new file mode 100644
index 0000000000..c0a979c4cf
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_convolution.cpp
@@ -0,0 +1,395 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+#include "mkldnn_traits.hpp"
+#include "type_helpers.hpp"
+
+#include "ref_convolution.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using math::saturate;
+using math::get_bias;
+
+template <data_type_t src_type, data_type_t wei_type,
+ data_type_t dst_type, data_type_t acc_type>
+void ref_convolution_fwd_t<src_type, wei_type, dst_type, acc_type>::
+execute_forward(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ const bool with_groups = pd()->with_groups();
+
+ const int G = pd()->G();
+ const int MB = pd()->MB();
+ const int OD = pd()->OD();
+ const int OH = pd()->OH();
+ const int OW = pd()->OW();
+ const int ID = pd()->ID();
+ const int IH = pd()->IH();
+ const int IW = pd()->IW();
+
+ const int OC = pd()->OC() / G;
+ const int IC = pd()->IC() / G;
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+
+ const int KSD = pd()->KSD();
+ const int KSH = pd()->KSH();
+ const int KSW = pd()->KSW();
+
+ const int KDD = pd()->KDD();
+ const int KDH = pd()->KDH();
+ const int KDW = pd()->KDW();
+
+ const int padFront = pd()->padFront();
+ const int padT = pd()->padT();
+ const int padL = pd()->padL();
+
+ const bool with_relu = 0; // TODO: change if support post_ops
+ const float nslope = 0.f;
+
+ const int ndims = pd()->desc()->src_desc.ndims;
+
+ auto ker = [=](int g, int mb, int oc, int od, int oh,
+ int ow) {
+ acc_data_t d = 0;
+ for (int ic = 0; ic < IC; ++ic)
+ for (int kd = 0; kd < KD; ++kd)
+ for (int kh = 0; kh < KH; ++kh)
+ for (int kw = 0; kw < KW; ++kw) {
+ const int id = od * KSD - padFront + kd * (1 + KDD);
+ const int ih = oh * KSH - padT + kh * (1 + KDH);
+ const int iw = ow * KSW - padL + kw * (1 + KDW);
+
+ if (id < 0 || id >= ID) continue;
+ if (ih < 0 || ih >= IH) continue;
+ if (iw < 0 || iw >= IW) continue;
+
+ if (ndims == 5)
+ d += (acc_data_t)src[src_d.off(mb, g*IC + ic, id, ih, iw)]
+ * (with_groups
+ ? weights[weights_d.off(g, oc, ic, kd, kh, kw)]
+ : weights[weights_d.off(oc, ic, kd, kh, kw)]);
+ else if (ndims == 4)
+ d += (acc_data_t)src[src_d.off(mb, g*IC + ic, ih, iw)]
+ * (with_groups
+ ? weights[weights_d.off(g, oc, ic, kh, kw)]
+ : weights[weights_d.off(oc, ic, kh, kw)]);
+ else if (ndims == 3)
+ d += (acc_data_t)src[src_d.off(mb, g*IC + ic, iw)]
+ * (with_groups
+ ? weights[weights_d.off(g, oc, ic, kw)]
+ : weights[weights_d.off(oc, ic, kw)]);
+ else
+ assert(false);
+
+ }
+ return d;
+ };
+
+ parallel_nd(G, MB, OC, OD, OH, OW,
+ [&](int g, int mb, int oc, int od, int oh, int ow) {
+ float a = bias
+ ? get_bias(bias, bias_d.off(g * OC + oc),
+ pd()->desc()->bias_desc.data_type)
+ : 0;
+ a += ker(g, mb, oc, od, oh, ow);
+ if (with_relu && a < 0)
+ a = a * nslope;
+ if (ndims == 5)
+ dst[dst_d.off(mb, g*OC + oc, od, oh, ow)] = saturate<dst_data_t>(a);
+ else if (ndims == 4)
+ dst[dst_d.off(mb, g*OC + oc, oh, ow)] = saturate<dst_data_t>(a);
+ else if (ndims == 3)
+ dst[dst_d.off(mb, g*OC + oc, ow)] = saturate<dst_data_t>(a);
+ else
+ assert(false);
+ });
+}
+
+template <data_type_t diff_src_type, data_type_t wei_type,
+ data_type_t diff_dst_type, data_type_t acc_type>
+void ref_convolution_bwd_data_t<diff_src_type, wei_type, diff_dst_type,
+ acc_type>::execute_backward_data(const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const diff_dst_data_t *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto diff_src = CTX_OUT_MEM(diff_src_data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ const bool with_groups = pd()->with_groups();
+
+ const int G = pd()->G();
+ const int MB = pd()->MB();
+ const int OD = pd()->OD();
+ const int OH = pd()->OH();
+ const int OW = pd()->OW();
+ const int ID = pd()->ID();
+ const int IH = pd()->IH();
+ const int IW = pd()->IW();
+
+ const int OC = pd()->OC() / G;
+ const int IC = pd()->IC() / G;
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+
+ const int KSD = pd()->KSD();
+ const int KSH = pd()->KSH();
+ const int KSW = pd()->KSW();
+
+ const int KDD = pd()->KDD();
+ const int KDH = pd()->KDH();
+ const int KDW = pd()->KDW();
+
+ const int padFront = pd()->padFront();
+ const int padT = pd()->padT();
+ const int padL = pd()->padL();
+
+ const int ndims = pd()->desc()->diff_src_desc.ndims;
+
+ auto ker = [=](int g, int mb, int ic, int id, int ih,
+ int iw) {
+ acc_data_t d = 0;
+ for (int oc = 0; oc < OC; ++oc)
+ for (int kd = 0; kd < KD; ++kd)
+ for (int kh = 0; kh < KH; ++kh)
+ for (int kw = 0; kw < KW; ++kw) {
+ if (iw + padL < kw * (1 + KDW)
+ || ih + padT < kh * (1 + KDH)
+ || id + padFront < kd * (1 + KDD))
+ continue;
+ int ow = iw - kw * (1 + KDW) + padL;
+ int oh = ih - kh * (1 + KDH) + padT;
+ int od = id - kd * (1 + KDD) + padFront;
+ if (ow % KSW != 0 || oh % KSH != 0 || od % KSD != 0)
+ continue;
+
+ ow /= KSW;
+ oh /= KSH;
+ od /= KSD;
+
+ if (od < OD && oh < OH && ow < OW) {
+ if (ndims == 5)
+ d += (acc_data_t)diff_dst[diff_dst_d.off(mb, g*OC
+ + oc, od, oh, ow)] * (with_groups
+ ? weights[weights_d.off(g, oc, ic, kd, kh, kw)]
+ : weights[weights_d.off(oc, ic, kd, kh, kw)]);
+ else if (ndims == 4)
+ d += (acc_data_t)diff_dst[diff_dst_d.off(mb, g*OC
+ + oc, oh, ow)] * (with_groups
+ ? weights[weights_d.off(g, oc, ic, kh, kw)]
+ : weights[weights_d.off(oc, ic, kh, kw)]);
+ else if (ndims == 3)
+ d += (acc_data_t)diff_dst[diff_dst_d.off(mb, g*OC
+ + oc, ow)] * (with_groups
+ ? weights[weights_d.off(g, oc, ic, kw)]
+ : weights[weights_d.off(oc, ic, kw)]);
+ else
+ assert(false);
+ }
+ }
+ return d;
+ };
+
+ parallel_nd(G, MB, IC, ID, IH, IW,
+ [&](int g, int mb, int ic, int id, int ih, int iw) {
+ auto ds_idx = (ndims == 5)
+ ? diff_src_d.off(mb, g*IC + ic, id, ih, iw)
+ : (ndims == 4)
+ ? diff_src_d.off(mb, g*IC + ic, ih, iw)
+ : diff_src_d.off(mb, g*IC + ic, iw);
+ float a = bias
+ ? get_bias(bias, bias_d.off(g * IC + ic),
+ pd()->desc()->bias_desc.data_type)
+ : 0;
+ a += ker(g, mb, ic, id, ih, iw);
+ diff_src[ds_idx] = saturate<diff_src_data_t>(a);
+ });
+}
+
+template <data_type_t src_type, data_type_t diff_wei_type,
+ data_type_t diff_dst_type, data_type_t acc_type>
+void ref_convolution_bwd_weights_t<src_type, diff_wei_type, diff_dst_type,
+ acc_type>::execute_backward_weights(const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const diff_dst_data_t *, MKLDNN_ARG_DIFF_DST);
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto diff_weights = CTX_OUT_MEM(diff_wei_data_t *, MKLDNN_ARG_DIFF_WEIGHTS);
+ auto diff_bias = CTX_OUT_MEM(diff_wei_data_t *, MKLDNN_ARG_DIFF_BIAS);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_weights_d(pd()->diff_weights_md(0));
+ const memory_desc_wrapper diff_bias_d(pd()->diff_weights_md(1));
+
+ const bool with_groups = pd()->with_groups();
+
+ const int G = pd()->G();
+ const int MB = pd()->MB();
+ const int OD = pd()->OD();
+ const int OH = pd()->OH();
+ const int OW = pd()->OW();
+ const int ID = pd()->ID();
+ const int IH = pd()->IH();
+ const int IW = pd()->IW();
+
+ const int OC = pd()->OC() / G;
+ const int IC = pd()->IC() / G;
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+
+ const int KSD = pd()->KSD();
+ const int KSH = pd()->KSH();
+ const int KSW = pd()->KSW();
+
+ const int KDD = pd()->KDD();
+ const int KDH = pd()->KDH();
+ const int KDW = pd()->KDW();
+
+ const int padFront = pd()->padFront();
+ const int padT = pd()->padT();
+ const int padL = pd()->padL();
+
+ const int ndims = pd()->desc()->src_desc.ndims;
+
+auto ker = [=](acc_data_t &d, int g, int oc, int ic, int kd, int kh, int kw) {
+ for (int mb = 0; mb < MB; ++mb)
+ for (int od = 0; od < OD; ++od)
+ for (int oh = 0; oh < OH; ++oh)
+ for (int ow = 0; ow < OW; ++ow) {
+ if (ow*KSW + kw * (1 + KDW) < padL
+ || oh*KSH + kh * (1 + KDH) < padT
+ || od*KSD + kd * (1 + KDD) < padFront
+ || ow*KSW + kw * (1 + KDW) >= IW + padL
+ || oh*KSH + kh * (1 + KDH) >= IH + padT
+ || od*KSD + kd * (1 + KDD) >= ID + padFront)
+ continue;
+
+ int id = od*KSD - padFront + kd * (1 + KDD);
+ int ih = oh*KSH - padT + kh * (1 + KDH);
+ int iw = ow*KSW - padL + kw * (1 + KDW);
+ if (ndims == 5)
+ d += (acc_data_t)diff_dst[diff_dst_d.off(mb, g*OC + oc, od,
+ oh, ow)] * src[src_d.off(mb, g*IC + ic, id, ih, iw)];
+ else if (ndims == 4)
+ d += (acc_data_t)diff_dst[diff_dst_d.off(mb, g*OC + oc, oh, ow)]
+ * src[src_d.off(mb, g*IC + ic, ih, iw)];
+ else if (ndims == 3)
+ d += (acc_data_t)diff_dst[diff_dst_d.off(mb, g*OC + oc, ow)]
+ * src[src_d.off(mb, g*IC + ic, iw)];
+ else
+ assert(false);
+ }
+ };
+
+ auto ker_bias = [=](acc_data_t &d, int g, int oc) {
+ for (int mb = 0; mb < MB; ++mb)
+ for (int od = 0; od < OD; ++od)
+ for (int oh = 0; oh < OH; ++oh)
+ for (int ow = 0; ow < OW; ++ow) {
+ if (ndims == 5)
+ d += (acc_data_t)diff_dst[diff_dst_d.off(mb, g*OC + oc, od, oh,
+ ow)];
+ else if (ndims == 4)
+ d += (acc_data_t)diff_dst[diff_dst_d.off(mb, g*OC + oc, oh,
+ ow)];
+ else if (ndims == 3)
+ d += (acc_data_t)diff_dst[diff_dst_d.off(mb, g*OC + oc, ow)];
+ else
+ assert(false);
+ }
+ };
+
+ parallel_nd(G, OC, [&](int g, int oc) {
+ if (diff_bias) {
+ // XXX: loss of precision when bias is a float...
+ acc_data_t db = 0;
+ ker_bias(db, g, oc);
+ diff_bias[diff_bias_d.off(g*OC+oc)]
+ = saturate<diff_wei_data_t>(db);
+ }
+
+ for (int ic = 0; ic < IC; ++ic)
+ for (int kd = 0; kd < KD; ++kd)
+ for (int kh = 0; kh < KH; ++kh)
+ for (int kw = 0; kw < KW; ++kw) {
+ acc_data_t dw = 0;
+ ker(dw, g, oc, ic, kd, kh, kw);
+
+ if (ndims == 5) {
+ auto idx = with_groups
+ ? diff_weights_d.off(g, oc, ic, kd, kh, kw)
+ : diff_weights_d.off(oc, ic, kd, kh, kw);
+ diff_weights[idx] = saturate<diff_wei_data_t>(dw);
+ } else if (ndims == 4) {
+ auto idx = with_groups
+ ? diff_weights_d.off(g, oc, ic, kh, kw)
+ : diff_weights_d.off(oc, ic, kh, kw);
+ diff_weights[idx] = saturate<diff_wei_data_t>(dw);
+ } else if (ndims == 3) {
+ auto idx = with_groups
+ ? diff_weights_d.off(g, oc, ic, kw)
+ : diff_weights_d.off(oc, ic, kw);
+ diff_weights[idx] = saturate<diff_wei_data_t>(dw);
+ } else {
+ assert(false);
+ }
+ }
+ });
+}
+
+using namespace data_type;
+
+template struct ref_convolution_fwd_t<f32>;
+
+template struct ref_convolution_fwd_t<u8, s8, f32, s32>;
+template struct ref_convolution_fwd_t<u8, s8, s32, s32>;
+template struct ref_convolution_fwd_t<u8, s8, s8, s32>;
+template struct ref_convolution_fwd_t<u8, s8, u8, s32>;
+
+template struct ref_convolution_bwd_data_t<f32, f32, f32, f32>;
+
+template struct ref_convolution_bwd_data_t<f32, s8, u8, s32>;
+template struct ref_convolution_bwd_data_t<s32, s8, u8, s32>;
+template struct ref_convolution_bwd_data_t<s8, s8, u8, s32>;
+template struct ref_convolution_bwd_data_t<u8, s8, u8, s32>;
+
+template struct ref_convolution_bwd_weights_t<f32, f32, f32, f32>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_convolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_convolution.hpp
new file mode 100644
index 0000000000..7c83d0c6d4
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_convolution.hpp
@@ -0,0 +1,194 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REF_CONVOLUTION_HPP
+#define CPU_REF_CONVOLUTION_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t src_type,
+ impl::data_type_t wei_type = src_type,
+ impl::data_type_t dst_type = src_type,
+ impl::data_type_t acc_type = dst_type>
+struct ref_convolution_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_fwd_pd_t {
+ using cpu_convolution_fwd_pd_t::cpu_convolution_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_convolution_fwd_t);
+
+ status_t init() {
+ using namespace data_type;
+
+ bool ok = true
+ && is_fwd()
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(src_type, wei_type, data_type::undef,
+ dst_type, acc_type)
+ && IMPLICATION(with_bias(), true
+ && IMPLICATION(src_type == u8,
+ utils::one_of(bias_md_.data_type, f32, s32, s8, u8))
+ && IMPLICATION(src_type == f32,
+ bias_md_.data_type == f32))
+ && set_default_formats()
+ && attr()->has_default_values();
+ return ok ? status::success : status::unimplemented;
+ }
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+ auto dat_tag = utils::pick(ndims() - 3, ncw, nchw, ncdhw);
+ auto wei_tag = with_groups()
+ ? utils::pick(ndims() - 3, goiw, goihw, goidhw)
+ : utils::pick(ndims() - 3, oiw, oihw, oidhw);
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ ref_convolution_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<wei_type>::type wei_data_t;
+ typedef typename prec_traits<dst_type>::type dst_data_t;
+ typedef typename prec_traits<acc_type>::type acc_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t diff_src_type, impl::data_type_t wei_type,
+ impl::data_type_t diff_dst_type,
+ impl::data_type_t acc_type = diff_src_type>
+struct ref_convolution_bwd_data_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_data_pd_t {
+ using cpu_convolution_bwd_data_pd_t::cpu_convolution_bwd_data_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_convolution_bwd_data_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_data
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(diff_src_type, wei_type, data_type::undef,
+ diff_dst_type, acc_type)
+ && set_default_formats()
+ && attr()->has_default_values();
+
+ return ok ? status::success : status::unimplemented;
+ }
+
+ virtual bool support_bias() const override { return true; }
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+ auto dat_tag = utils::pick(ndims() - 3, ncw, nchw, ncdhw);
+ auto wei_tag = with_groups()
+ ? utils::pick(ndims() - 3, goiw, goihw, goidhw)
+ : utils::pick(ndims() - 3, oiw, oihw, oidhw);
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ ref_convolution_bwd_data_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ typedef typename prec_traits<diff_src_type>::type diff_src_data_t;
+ typedef typename prec_traits<wei_type>::type wei_data_t;
+ typedef typename prec_traits<diff_dst_type>::type diff_dst_data_t;
+ typedef typename prec_traits<acc_type>::type acc_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_data(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_data(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t src_type, impl::data_type_t diff_wei_type,
+ impl::data_type_t diff_dst_type,
+ impl::data_type_t acc_type = diff_wei_type>
+struct ref_convolution_bwd_weights_t: public cpu_primitive_t {
+ struct pd_t: public cpu_convolution_bwd_weights_pd_t {
+ using cpu_convolution_bwd_weights_pd_t::cpu_convolution_bwd_weights_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_convolution_bwd_weights_t);
+
+ status_t init() {
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_weights
+ && set_default_alg_kind(alg_kind::convolution_direct)
+ && expect_data_types(src_type, diff_wei_type, diff_wei_type,
+ diff_dst_type, acc_type)
+ && set_default_formats()
+ && attr()->has_default_values();
+ return ok ? status::success : status::unimplemented;
+ }
+
+ protected:
+ bool set_default_formats() {
+ using namespace format_tag;
+ auto dat_tag = utils::pick(ndims() - 3, ncw, nchw, ncdhw);
+ auto wei_tag = with_groups()
+ ? utils::pick(ndims() - 3, goiw, goihw, goidhw)
+ : utils::pick(ndims() - 3, oiw, oihw, oidhw);
+ return set_default_formats_common(dat_tag, wei_tag, dat_tag);
+ }
+ };
+
+ ref_convolution_bwd_weights_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<diff_wei_type>::type diff_wei_data_t;
+ typedef typename prec_traits<diff_dst_type>::type diff_dst_data_t;
+ typedef typename prec_traits<acc_type>::type acc_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_weights(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_weights(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_deconvolution.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_deconvolution.cpp
new file mode 100644
index 0000000000..541a303aab
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_deconvolution.cpp
@@ -0,0 +1,199 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "mkldnn_thread.hpp"
+#include "mkldnn_traits.hpp"
+#include "math_utils.hpp"
+
+#include "ref_deconvolution.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+void ref_deconvolution_fwd_t::compute_fwd_bias(const data_t *bias,
+ data_t *dst) const {
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+
+ const int G = pd()->G();
+ const int MB = pd()->MB();
+ const int OH = pd()->OH();
+ const int OW = pd()->OW();
+ const int OD = pd()->OD();
+ const int OC = pd()->OC() / G;
+ const int ndims = pd()->desc()->src_desc.ndims;
+
+ parallel_nd(MB, G, OC, OD, OH, OW,
+ [&](int mb, int g, int oc, int od, int oh, int ow) {
+ auto b = bias[g * OC + oc];
+ switch (ndims) {
+ case 5: dst[dst_d.off(mb, g * OC + oc, od, oh, ow)] += b; break;
+ case 4: dst[dst_d.off(mb, g * OC + oc, oh, ow)] += b; break;
+ case 3: dst[dst_d.off(mb, g * OC + oc, ow)] += b; break;
+ default: assert(!"invalid dimension size");
+ }
+ });
+}
+
+void ref_deconvolution_fwd_t::compute_fwd_bias_ncdhw(const data_t *bias,
+ data_t *dst) const {
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+
+ const int MB = pd()->MB();
+ const int OC = pd()->OC();
+ const int SP = pd()->OW()*pd()->OH()*pd()->OD();
+
+ parallel_nd(MB, OC, [&](int mb, int oc) {
+ PRAGMA_OMP_SIMD()
+ for (int sp = 0; sp < SP; ++sp) {
+ auto offset = (size_t)(mb * OC + oc) * SP + sp;
+ dst[offset] += bias[oc];
+ }
+ });
+}
+
+template <int blksize>
+void ref_deconvolution_fwd_t::compute_fwd_bias_nCdhwXc(const data_t *bias,
+ data_t *dst) const {
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+
+ const int MB = pd()->MB();
+ const int OC = pd()->OC();
+ const int SP = pd()->OW() * pd()->OH() * pd()->OD();
+
+ const ptrdiff_t stride_mb = dst_d.blocking_desc().strides[0];
+
+ parallel_nd(MB, utils::div_up(OC, blksize), SP,
+ [&](int mb, int oc_blk, int sp) {
+ int oc = oc_blk * blksize;
+ auto offset = mb * stride_mb + oc * SP + sp * blksize;
+ const int blk = nstl::min(blksize, OC - oc);
+
+ PRAGMA_OMP_SIMD()
+ for (int i = 0; i < blk; ++i)
+ dst[offset + i] += bias[oc + i];
+ });
+}
+
+void ref_deconvolution_bwd_weights_t::compute_bwd_bias(const data_t *diff_dst,
+ data_t *diff_bias) const {
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+
+ const int G = pd()->G();
+ const int MB = pd()->MB();
+ const int OH = pd()->OH();
+ const int OW = pd()->OW();
+ const int OC = pd()->OC() / G;
+ const int OD = pd()->OD();
+ const int ndims = pd()->desc()->src_desc.ndims;
+
+ parallel_nd(G, OC, [&](int g, int oc) {
+ data_t db = 0;
+ for (int mb = 0; mb < MB; ++mb) {
+ for (int od = 0; od < OD; ++od) {
+ for (int oh = 0; oh < OH; ++oh) {
+ for (int ow = 0; ow < OW; ++ow) {
+ switch (ndims) {
+ case 5:
+ db += diff_dst[diff_dst_d.off(
+ mb, g * OC + oc, od, oh, ow)];
+ break;
+ case 4:
+ db += diff_dst[diff_dst_d.off(
+ mb, g * OC + oc, oh, ow)];
+ break;
+ case 3:
+ db += diff_dst[diff_dst_d.off(mb, g * OC + oc, ow)];
+ break;
+ default: assert(!"invalid dimension size");
+ }
+ }
+ }
+ }
+ }
+ diff_bias[g * OC + oc] = db;
+ });
+}
+
+void ref_deconvolution_bwd_weights_t::compute_bwd_bias_ncdhw(
+ const data_t *diff_dst, data_t *diff_bias) const {
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+
+ const int OC = pd()->OC();
+ const int MB = pd()->MB();
+ const int SP = pd()->OH()*pd()->OW()*pd()->OD();
+
+ parallel_nd(OC, [&](int oc) {
+ data_t db = 0;
+ for (int mb = 0; mb < MB; ++mb) {
+ PRAGMA_OMP_SIMD()
+ for (int sp = 0; sp < SP; ++sp) {
+ auto offset = (size_t)(mb * OC + oc) * SP + sp;
+ db += diff_dst[offset];
+ }
+ }
+ diff_bias[oc] = db;
+ });
+}
+
+template <int blksize>
+void ref_deconvolution_bwd_weights_t::compute_bwd_bias_nCdhwXc(
+ const data_t *diff_dst, data_t *diff_bias) const {
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+
+ const int OC = pd()->OC();
+ const int MB = pd()->MB();
+ const int SP = pd()->OH() * pd()->OW() * pd()->OD();
+
+ const ptrdiff_t stride_mb = diff_dst_d.blocking_desc().strides[0];
+
+ parallel_nd(utils::div_up(OC, blksize), [&](int ocb) {
+ data_t db[blksize] = {0};
+
+ for (int mb = 0; mb < MB; ++mb) {
+ for (int sp = 0; sp < SP; ++sp) {
+ auto offset = mb * stride_mb + (ocb * SP + sp) * blksize;
+
+ PRAGMA_OMP_SIMD()
+ for (int i = 0; i < blksize; ++i)
+ db[i] += diff_dst[offset+i];
+ }
+ }
+
+ const int blk = nstl::min(blksize, OC - ocb * blksize);
+
+ PRAGMA_OMP_SIMD()
+ for (int i = 0; i < blk; ++i)
+ diff_bias[ocb * blksize + i] = db[i];
+ });
+}
+
+template void ref_deconvolution_fwd_t::compute_fwd_bias_nCdhwXc<8>(
+ const data_t *diff_dst, data_t *diff_bias) const;
+template void ref_deconvolution_fwd_t::compute_fwd_bias_nCdhwXc<16>(
+ const data_t *diff_dst, data_t *diff_bias) const;
+template void ref_deconvolution_bwd_weights_t::compute_bwd_bias_nCdhwXc<8>(
+ const data_t *diff_dst, data_t *diff_bias) const;
+template void ref_deconvolution_bwd_weights_t::compute_bwd_bias_nCdhwXc<16>(
+ const data_t *diff_dst, data_t *diff_bias) const;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_deconvolution.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_deconvolution.hpp
new file mode 100644
index 0000000000..d61903c32d
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_deconvolution.hpp
@@ -0,0 +1,502 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REF_DECONVOLUTION_HPP
+#define CPU_REF_DECONVOLUTION_HPP
+
+#include <assert.h>
+#include <string.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+#include "primitive_iterator.hpp"
+
+#include "cpu_convolution_pd.hpp"
+#include "cpu_deconvolution_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+static status_t compute_blocked_format(bool with_groups,
+ const memory_desc_t *oi_md, memory_desc_t *io_md)
+{
+ /* Computes blocking for *i*o* format from *o*i* format */
+
+ bool sanity_check_ok = true
+ && oi_md->ndims == io_md->ndims
+ && oi_md->format_kind == format_kind::blocked;
+ if (!sanity_check_ok) return status::invalid_arguments;
+
+ const blocking_desc_t &oi_blk = oi_md->format_desc.blocking;
+ blocking_desc_t io_blk = io_md->format_desc.blocking;
+
+ io_md->format_kind = format_kind::blocked;
+ io_blk = oi_blk;
+
+ const int ID_OC = 0 + with_groups;
+ const int ID_IC = 1 + with_groups;
+
+ nstl::swap(io_blk.strides[ID_OC], io_blk.strides[ID_IC]);
+ for (int i_blk = 0; i_blk < io_blk.inner_nblks; ++i_blk) {
+ if (utils::one_of(io_blk.inner_idxs[i_blk], ID_OC, ID_IC)) {
+ io_blk.inner_idxs[i_blk] =
+ (io_blk.inner_idxs[i_blk] == ID_OC ? ID_IC : ID_OC);
+ }
+ }
+
+ return memory_desc_init_by_blocking_desc(*io_md, io_blk);
+}
+
+static status_t conv_descr_create(const deconvolution_desc_t *dd,
+ convolution_desc_t *cd)
+{
+ using namespace prop_kind;
+ alg_kind_t alg_kind = dd->alg_kind == alg_kind::deconvolution_direct
+ ? alg_kind::convolution_direct : alg_kind::convolution_winograd;
+
+ const memory_desc_t *src_md, *dst_md, *d_weights_d;
+ prop_kind_t prop_kind;
+ memory_desc_t c_weights_d;
+ if (utils::one_of(dd->prop_kind, forward_training, forward_inference)) {
+ prop_kind = backward_data;
+ src_md = &dd->dst_desc;
+ dst_md = &dd->src_desc;
+ d_weights_d = &dd->weights_desc;
+ } else if (dd->prop_kind == backward_data) {
+ prop_kind = forward_training;
+ src_md = &dd->diff_dst_desc;
+ dst_md = &dd->diff_src_desc;
+ d_weights_d = &dd->weights_desc;
+ } else {
+ prop_kind = dd->prop_kind;
+ src_md = &dd->diff_dst_desc;
+ dst_md = &dd->src_desc;
+ d_weights_d = &dd->diff_weights_desc;
+ }
+
+ const bool with_groups = d_weights_d->ndims == src_md->ndims + 1;
+
+ /* create weights desc for convolution */
+ c_weights_d = *d_weights_d;
+
+ const int ID_OC = 0 + with_groups;
+ const int ID_IC = 1 + with_groups;
+
+ nstl::swap(c_weights_d.dims[ID_OC], c_weights_d.dims[ID_IC]);
+ nstl::swap(c_weights_d.padded_dims[ID_OC], c_weights_d.padded_dims[ID_IC]);
+ nstl::swap(c_weights_d.padded_offsets[ID_OC], c_weights_d.padded_offsets[ID_IC]);
+
+ if (c_weights_d.format_kind != format_kind::any)
+ CHECK(compute_blocked_format(with_groups, d_weights_d, &c_weights_d));
+
+ return conv_desc_init(cd, prop_kind, alg_kind, src_md, &c_weights_d,
+ prop_kind != backward_weights ? &dd->bias_desc : nullptr,
+ dst_md, dd->strides, dd->dilates,
+ dd->padding[0], dd->padding[1], dd->padding_kind);
+}
+
+struct ref_deconvolution_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_deconvolution_fwd_pd_t {
+ pd_t(engine_t *engine,
+ const deconvolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const deconvolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_deconvolution_fwd_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , conv_pd_(nullptr)
+ {}
+
+ pd_t(const pd_t &other)
+ : cpu_deconvolution_fwd_pd_t(other)
+ , conv_pd_(other.conv_pd_->clone())
+ , conv_supports_bias_(other.conv_supports_bias_)
+ , dst_tag_(other.dst_tag_)
+ {}
+
+ ~pd_t() { delete conv_pd_; }
+
+ DECLARE_COMMON_PD_T(conv_pd_->name(), ref_deconvolution_fwd_t);
+
+ status_t init_convolution() {
+ using namespace types;
+
+ convolution_desc_t cd;
+ CHECK(conv_descr_create(desc(), &cd));
+
+ mkldnn_primitive_desc_iterator it(engine_, (op_desc_t *)&cd,
+ &attr_, nullptr);
+ while (++it != it.end()) {
+ conv_pd_ = *it;
+ conv_supports_bias_ =
+ static_cast<cpu_convolution_bwd_data_pd_t *>(conv_pd_)
+ ->support_bias();
+ bool output_f32 = utils::everyone_is(data_type::f32,
+ desc()->accum_data_type, desc()->dst_desc.data_type);
+
+ bool ok = true
+ && conv_pd_->weights_md()->extra.flags == 0
+ /* deconv reference code can process only f32 bias */
+ && IMPLICATION(with_bias(),
+ conv_supports_bias_ || output_f32);
+ if (ok) return status::success;
+
+ delete conv_pd_;
+ }
+ conv_pd_ = nullptr;
+ return status::unimplemented;
+ }
+
+ status_t init() {
+ using namespace format_tag;
+ bool ok = true
+ && is_fwd()
+ && utils::one_of(desc()->alg_kind,
+ alg_kind::deconvolution_direct,
+ alg_kind::deconvolution_winograd)
+ && attr()->post_ops_.has_default_values();
+
+ if (ok) {
+ CHECK(init_convolution());
+ if (weights_md_.format_kind == format_kind::any) {
+ CHECK(compute_blocked_format(with_groups(),
+ conv_pd_->weights_md(), &desc_.weights_desc));
+ weights_md_ = desc_.weights_desc;
+ }
+ if (src_md_.format_kind == format_kind::any)
+ src_md_ = *conv_pd_->diff_dst_md();
+ if (dst_md_.format_kind == format_kind::any)
+ dst_md_ = *conv_pd_->diff_src_md();
+ if (bias_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(bias_md_, x));
+
+ dst_tag_ = memory_desc_matches_one_of_tag(dst_md_,
+ utils::pick(ndims() - 3, ncw, nchw, ncdhw),
+ utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c),
+ utils::pick(ndims() - 3, nCw16c, nChw16c, nCdhw16c));
+
+ return status::success;
+ }
+
+ return status::unimplemented;
+ }
+
+ virtual void init_scratchpad_md() override {
+ scratchpad_md_ = *conv_pd_->scratchpad_md();
+ }
+
+ primitive_desc_t *conv_pd_;
+ bool conv_supports_bias_;
+ format_tag_t dst_tag_;
+ };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ ref_deconvolution_fwd_t(const pd_t *apd): cpu_primitive_t(apd)
+ { pd()->conv_pd_->create_primitive((primitive_t **)&conv_p_); }
+ ~ref_deconvolution_fwd_t() { delete conv_p_; }
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ const auto &args = ctx.args();
+ exec_args_t conv_args;
+ conv_args[MKLDNN_ARG_DIFF_DST] = args.at(MKLDNN_ARG_SRC);
+ conv_args[MKLDNN_ARG_WEIGHTS] = args.at(MKLDNN_ARG_WEIGHTS);
+ if (pd()->with_bias() && pd()->conv_supports_bias_)
+ conv_args[MKLDNN_ARG_BIAS] = args.at(MKLDNN_ARG_BIAS);
+ conv_args[MKLDNN_ARG_DIFF_SRC] = args.at(MKLDNN_ARG_DST);
+ if (!types::is_zero_md(pd()->scratchpad_md()))
+ conv_args[MKLDNN_ARG_SCRATCHPAD] = args.at(MKLDNN_ARG_SCRATCHPAD);
+ const exec_ctx_t conv_ctx(ctx.stream(), std::move(conv_args));
+
+ conv_p_->execute(conv_ctx);
+
+ if (pd()->with_bias() && !pd()->conv_supports_bias_) {
+ using namespace format_tag;
+
+ auto bias = CTX_IN_MEM(const data_t *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ switch (pd()->dst_tag_) {
+ case ncdhw: case nchw: case ncw:
+ compute_fwd_bias_ncdhw(bias, dst);
+ break;
+ case nCdhw8c: case nChw8c: case nCw8c:
+ compute_fwd_bias_nCdhwXc<8>(bias, dst);
+ break;
+ case nCdhw16c: case nChw16c: case nCw16c:
+ compute_fwd_bias_nCdhwXc<16>(bias, dst);
+ break;
+ default:
+ compute_fwd_bias(bias, dst);
+ break;
+ }
+ }
+ return status::success;
+ }
+
+private:
+ void compute_fwd_bias(const data_t *bias, data_t *dst) const;
+ void compute_fwd_bias_ncdhw(const data_t *bias, data_t *dst) const;
+ template <int blksize> void compute_fwd_bias_nCdhwXc(const data_t *bias,
+ data_t *dst) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ primitive_t *conv_p_;
+};
+
+struct ref_deconvolution_bwd_data_t: public cpu_primitive_t {
+ struct pd_t: public cpu_deconvolution_bwd_data_pd_t {
+ pd_t(engine_t *engine, const deconvolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const deconvolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_deconvolution_bwd_data_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , conv_pd_(nullptr)
+ {}
+
+ pd_t(const pd_t &other)
+ : cpu_deconvolution_bwd_data_pd_t(other)
+ , conv_pd_(other.conv_pd_->clone()) {}
+
+ ~pd_t() { delete conv_pd_; }
+
+ DECLARE_COMMON_PD_T(conv_pd_->name(), ref_deconvolution_bwd_data_t);
+
+ status_t init_convolution() {
+ using namespace types;
+
+ convolution_desc_t cd;
+ status_t status = conv_descr_create(desc(), &cd);
+ if (status != status::success) return status;
+
+ mkldnn_primitive_desc_iterator it(engine_, (op_desc_t *)&cd,
+ &attr_, nullptr);
+ while (++it != it.end()) {
+ conv_pd_ = *it;
+ if (conv_pd_->weights_md()->extra.flags == 0)
+ return status::success;
+ delete conv_pd_;
+ }
+
+ return status::unimplemented;
+ }
+
+ status_t init() {
+ using namespace data_type;
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_data
+ && utils::everyone_is(data_type::f32,
+ desc()->diff_src_desc.data_type,
+ desc()->weights_desc.data_type,
+ desc()->diff_dst_desc.data_type)
+ && utils::one_of(desc()->alg_kind,
+ alg_kind::deconvolution_direct,
+ alg_kind::deconvolution_winograd);
+
+ if (ok) {
+ CHECK(init_convolution());
+ if (weights_md_.format_kind == format_kind::any) {
+ CHECK(compute_blocked_format(with_groups(),
+ conv_pd_->weights_md(), &desc_.weights_desc));
+ weights_md_ = desc_.weights_desc;
+ }
+ if (diff_src_md_.format_kind == format_kind::any)
+ diff_src_md_ = *conv_pd_->dst_md();
+ if (diff_dst_md_.format_kind == format_kind::any)
+ diff_dst_md_ = *conv_pd_->src_md();
+
+ return status::success;
+ }
+
+ return status::unimplemented;
+ }
+
+ virtual void init_scratchpad_md() override {
+ scratchpad_md_ = *conv_pd_->scratchpad_md();
+ }
+
+ primitive_desc_t *conv_pd_;
+ };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ ref_deconvolution_bwd_data_t(const pd_t *apd): cpu_primitive_t(apd)
+ { pd()->conv_pd_->create_primitive((primitive_t **)&conv_p_); }
+ ~ref_deconvolution_bwd_data_t() { delete conv_p_; }
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ const auto &args = ctx.args();
+ exec_args_t conv_args;
+ conv_args[MKLDNN_ARG_SRC] = args.at(MKLDNN_ARG_DIFF_DST);
+ conv_args[MKLDNN_ARG_WEIGHTS] = args.at(MKLDNN_ARG_WEIGHTS);
+ conv_args[MKLDNN_ARG_DST] = args.at(MKLDNN_ARG_DIFF_SRC);
+ if (!types::is_zero_md(pd()->scratchpad_md()))
+ conv_args[MKLDNN_ARG_SCRATCHPAD] = args.at(MKLDNN_ARG_SCRATCHPAD);
+ const exec_ctx_t conv_ctx(ctx.stream(), std::move(conv_args));
+
+ conv_p_->execute(conv_ctx);
+ return status::success;
+ }
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ primitive_t *conv_p_;
+};
+
+struct ref_deconvolution_bwd_weights_t: public cpu_primitive_t {
+ struct pd_t: public cpu_deconvolution_bwd_weights_pd_t {
+ pd_t(engine_t *engine,
+ const deconvolution_desc_t *adesc,
+ const primitive_attr_t *attr,
+ const deconvolution_fwd_pd_t *hint_fwd_pd)
+ : cpu_deconvolution_bwd_weights_pd_t(engine, adesc, attr, hint_fwd_pd)
+ , conv_pd_(nullptr)
+ {}
+
+ pd_t(const pd_t &other)
+ : cpu_deconvolution_bwd_weights_pd_t(other)
+ , conv_pd_(other.conv_pd_->clone())
+ , dst_tag_(other.dst_tag_)
+ {}
+
+ ~pd_t() { delete conv_pd_; }
+
+ DECLARE_COMMON_PD_T(conv_pd_->name(), ref_deconvolution_bwd_weights_t);
+
+ status_t init_convolution() {
+ using namespace types;
+
+ convolution_desc_t cd;
+ status_t status = conv_descr_create(desc(), &cd);
+ if (status != status::success) return status;
+
+ mkldnn_primitive_desc_iterator it(engine_, (op_desc_t *)&cd,
+ &attr_, nullptr);
+ while (++it != it.end()) {
+ conv_pd_ = *it;
+ if (conv_pd_->diff_weights_md()->extra.flags == 0)
+ return status::success;
+ delete conv_pd_;
+ }
+ return status::unimplemented;
+ }
+
+ status_t init() {
+ using namespace format_tag;
+ bool ok = true
+ && desc()->prop_kind == prop_kind::backward_weights
+ && utils::everyone_is(data_type::f32,
+ desc()->src_desc.data_type,
+ desc()->diff_weights_desc.data_type,
+ desc()->diff_dst_desc.data_type)
+ && utils::one_of(desc()->alg_kind,
+ alg_kind::deconvolution_direct,
+ alg_kind::deconvolution_winograd)
+ && attr()->has_default_values();
+ if (ok) {
+ CHECK(init_convolution());
+ if (diff_weights_md_.format_kind == format_kind::any) {
+ CHECK(compute_blocked_format(with_groups(),
+ conv_pd_->diff_weights_md(),
+ &desc_.diff_weights_desc));
+ diff_weights_md_ = desc_.diff_weights_desc;
+ }
+ if (src_md_.format_kind == format_kind::any)
+ src_md_ = *conv_pd_->diff_dst_md();
+ if (diff_dst_md_.format_kind == format_kind::any)
+ diff_dst_md_ = *conv_pd_->src_md();
+ if (diff_bias_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(diff_bias_md_, x));
+
+ dst_tag_ = memory_desc_matches_one_of_tag(diff_dst_md_,
+ utils::pick(ndims() - 3, ncw, nchw, ncdhw),
+ utils::pick(ndims() - 3, nCw8c, nChw8c, nCdhw8c),
+ utils::pick(ndims() - 3, nCw16c, nChw16c, nCdhw16c));
+
+ return status::success;
+ }
+
+ return status::unimplemented;
+ }
+
+ virtual void init_scratchpad_md() override {
+ scratchpad_md_ = *conv_pd_->scratchpad_md();
+ }
+
+ primitive_desc_t *conv_pd_;
+ format_tag_t dst_tag_;
+ };
+
+ typedef typename prec_traits<data_type::f32>::type data_t;
+
+ ref_deconvolution_bwd_weights_t(const pd_t *apd): cpu_primitive_t(apd)
+ { pd()->conv_pd_->create_primitive((primitive_t **)&conv_p_); }
+ ~ref_deconvolution_bwd_weights_t() { delete conv_p_; }
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ const auto &args = ctx.args();
+ exec_args_t conv_args;
+ conv_args[MKLDNN_ARG_DIFF_DST] = args.at(MKLDNN_ARG_SRC);
+ conv_args[MKLDNN_ARG_SRC] = args.at(MKLDNN_ARG_DIFF_DST);
+ conv_args[MKLDNN_ARG_DIFF_WEIGHTS] = args.at(MKLDNN_ARG_DIFF_WEIGHTS);
+ if (!types::is_zero_md(pd()->scratchpad_md()))
+ conv_args[MKLDNN_ARG_SCRATCHPAD] = args.at(MKLDNN_ARG_SCRATCHPAD);
+ const exec_ctx_t conv_ctx(ctx.stream(), std::move(conv_args));
+
+ status_t status = conv_p_->execute(conv_ctx);
+ if (status != status::success) return status;
+
+ if (pd()->with_bias()) {
+ using namespace format_tag;
+
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto diff_bias = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_BIAS);
+
+ switch (pd()->dst_tag_) {
+ case ncdhw: case nchw: case ncw:
+ compute_bwd_bias_ncdhw(diff_dst, diff_bias);
+ break;
+ case nCdhw8c: case nChw8c: case nCw8c:
+ compute_bwd_bias_nCdhwXc<8>(diff_dst, diff_bias);
+ break;
+ case nCdhw16c: case nChw16c: case nCw16c:
+ compute_bwd_bias_nCdhwXc<16>(diff_dst, diff_bias);
+ break;
+ default:
+ compute_bwd_bias(diff_dst, diff_bias);
+ break;
+ }
+ }
+ return status::success;
+ }
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ void compute_bwd_bias(const data_t *diff_dst, data_t *diff_bias) const;
+ void compute_bwd_bias_ncdhw(const data_t *diff_dst,
+ data_t *diff_bias) const;
+ template <int blksize> void compute_bwd_bias_nCdhwXc(
+ const data_t *diff_dst, data_t *diff_bias) const;
+
+ primitive_t *conv_p_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_eltwise.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_eltwise.cpp
new file mode 100644
index 0000000000..7beee8d323
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_eltwise.cpp
@@ -0,0 +1,297 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+
+#include "ref_eltwise.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace alg_kind;
+using namespace math;
+
+ref_eltwise_scalar_fwd_t::ref_eltwise_scalar_fwd_t(alg_kind_t alg, float alpha,
+ float beta): alg_(alg), alpha_(alpha), beta_(beta) {
+ assert(utils::one_of(alg_, eltwise_relu, eltwise_tanh, eltwise_elu,
+ eltwise_square, eltwise_abs, eltwise_sqrt, eltwise_linear,
+ eltwise_bounded_relu, eltwise_soft_relu, eltwise_logistic));
+}
+
+ref_eltwise_scalar_fwd_t::ref_eltwise_scalar_fwd_t(
+ const post_ops_t::entry_t::eltwise_t &eltwise)
+ : ref_eltwise_scalar_fwd_t(eltwise.alg, eltwise.alpha, eltwise.beta) {}
+
+float ref_eltwise_scalar_fwd_t::compute_scalar(float s) {
+ switch (alg_) {
+ case eltwise_relu: return relu_fwd(s, alpha_);
+ case eltwise_tanh: return tanh_fwd(s);
+ case eltwise_elu: return elu_fwd(s, alpha_);
+ case eltwise_square: return square_fwd(s);
+ case eltwise_abs: return abs_fwd(s);
+ case eltwise_sqrt: return sqrt_fwd(s);
+ case eltwise_linear: return linear_fwd(s, alpha_, beta_);
+ case eltwise_bounded_relu: return bounded_relu_fwd(s, alpha_);
+ case eltwise_soft_relu: return soft_relu_fwd(s);
+ case eltwise_logistic: return logistic_fwd(s);
+ default: assert(!"unknown eltwise alg_kind");
+ }
+
+ return 0.f;
+}
+
+template <impl::data_type_t data_type>
+void ref_eltwise_fwd_t<data_type>::execute_forward_nCspBc_padded(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+ const blocking_desc_t &blk = data_d.blocking_desc();
+ const int block = blk.inner_blks[0];
+
+ const int MB = pd()->MB();
+ const int C = pd()->C() / block;
+ const int C_PADDED = data_d.padded_dims()[1] / block;
+ const int tail = pd()->C() % block;
+ const int SP = pd()->D() * pd()->H() * pd()->W();
+ const auto alg_kind = pd()->desc()->alg_kind;
+ const float alpha = pd()->desc()->alpha;
+ const float beta = pd()->desc()->beta;
+
+ auto ker = [=] (data_t &d, data_t s) {
+ switch (alg_kind) {
+ case eltwise_linear: d = linear_fwd(s, alpha, beta); break;
+ case eltwise_bounded_relu:
+ d = bounded_relu_fwd(s, alpha); break;
+ case eltwise_soft_relu: d = soft_relu_fwd(s); break;
+ case eltwise_logistic: d = logistic_fwd(s); break;
+ default: assert(!"unknown eltwise alg_kind");
+ }
+ };
+
+ // FIXME: integer overflow?
+
+ parallel_nd(MB, C_PADDED, SP,
+ [&](int n, int c, int sp) {
+ auto d_off = (n*C_PADDED*SP + c*SP + sp) * block;
+ if (c < C) {
+ for (int v = 0; v < block; v++)
+ ker(dst[d_off + v], src[d_off + v]);
+ } else {
+ for (int v = 0; v < tail; v++)
+ ker(dst[d_off + v], src[d_off + v]);
+ }
+ });
+}
+
+template <impl::data_type_t data_type>
+void ref_eltwise_fwd_t<data_type>::execute_forward_generic(
+ const exec_ctx_t &ctx) const {
+ /* fast return */
+ if (pd()->has_zero_dim_memory()) return;
+
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+
+ const int MB = pd()->MB();
+ const int C = pd()->C();
+ const int D = pd()->D();
+ const int H = pd()->H();
+ const int W = pd()->W();
+ const auto alg_kind = pd()->desc()->alg_kind;
+ const float alpha = pd()->desc()->alpha;
+ const float beta = pd()->desc()->beta;
+ const bool is_3d = pd()->desc()->data_desc.ndims == 5;
+
+ parallel_nd(MB, C, D, H, W,
+ [&](int n, int c, int id, int h, int w) {
+ auto d_off = is_3d
+ ? data_d.off(n, c, id, h, w) : data_d.off(n, c, h, w);
+ data_t s = src[d_off];
+ data_t &d = dst[d_off];
+ switch (alg_kind) {
+ case eltwise_relu: d = relu_fwd(s, alpha); break;
+ case eltwise_tanh: d = tanh_fwd(s); break;
+ case eltwise_elu: d = elu_fwd(s, alpha); break;
+ case eltwise_square: d = square_fwd(s); break;
+ case eltwise_abs: d = abs_fwd(s); break;
+ case eltwise_sqrt: d = sqrt_fwd(s); break;
+ case eltwise_linear: d = linear_fwd(s, alpha, beta); break;
+ case eltwise_bounded_relu:
+ d = bounded_relu_fwd(s, alpha); break;
+ case eltwise_soft_relu: d = soft_relu_fwd(s); break;
+ case eltwise_logistic: d = logistic_fwd(s); break;
+ default: assert(!"unknown eltwise alg_kind");
+ }
+ });
+}
+
+template <impl::data_type_t data_type>
+void ref_eltwise_fwd_t<data_type>::execute_forward_dense(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+
+ const ptrdiff_t nelems = static_cast<ptrdiff_t>(data_d.nelems(true));
+ const auto alg_kind = pd()->desc()->alg_kind;
+ const float alpha = pd()->desc()->alpha;
+ const float beta = pd()->desc()->beta;
+
+ src += data_d.offset0();
+ dst += data_d.offset0();
+
+ if (alg_kind == eltwise_relu) {
+ // a fast path for relu as the most popular activation
+ parallel_nd(nelems, [&](ptrdiff_t e) {
+ dst[e] = relu_fwd(src[e], alpha);
+ });
+ return;
+ }
+
+ parallel_nd(nelems, [&](ptrdiff_t e) {
+ const data_t s = src[e];
+ data_t &d = dst[e];
+
+ switch (alg_kind) {
+ case eltwise_tanh: d = tanh_fwd(s); break;
+ case eltwise_elu: d = elu_fwd(s, alpha); break;
+ case eltwise_square: d = square_fwd(s); break;
+ case eltwise_abs: d = abs_fwd(s); break;
+ case eltwise_sqrt: d = sqrt_fwd(s); break;
+ case eltwise_linear: d = linear_fwd(s, alpha, beta); break;
+ case eltwise_bounded_relu: d = bounded_relu_fwd(s, alpha); break;
+ case eltwise_soft_relu: d = soft_relu_fwd(s); break;
+ case eltwise_logistic: d = logistic_fwd(s); break;
+ default: assert(!"unknown eltwise alg_kind");
+ }
+ });
+}
+
+template <impl::data_type_t data_type>
+void ref_eltwise_bwd_t<data_type>::execute_backward_generic(
+ const exec_ctx_t &ctx) const {
+ /* fast return */
+ if (pd()->has_zero_dim_memory()) return;
+
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+ const memory_desc_wrapper diff_data_d(pd()->diff_src_md());
+
+ const int MB = pd()->MB();
+ const int C = pd()->C();
+ const int D = pd()->D();
+ const int H = pd()->H();
+ const int W = pd()->W();
+ const auto alg_kind = pd()->desc()->alg_kind;
+ const float alpha = pd()->desc()->alpha;
+ const float beta = pd()->desc()->beta;
+ const bool is_3d = pd()->desc()->data_desc.ndims == 5;
+
+ parallel_nd(MB, C, D, H, W,
+ [&](int n, int c, int d, int h, int w) {
+ auto data_off = is_3d
+ ? data_d.off(n, c, d, h, w) : data_d.off(n, c, h, w);
+ auto diff_data_off = is_3d
+ ? diff_data_d.off(n, c, d, h, w)
+ : diff_data_d.off(n, c, h, w);
+ data_t s = src[data_off];
+ data_t dd = diff_dst[diff_data_off];
+ data_t &ds = diff_src[diff_data_off];
+ switch (alg_kind) {
+ case eltwise_relu: ds = relu_bwd(dd, s, alpha); break;
+ case eltwise_tanh: ds = tanh_bwd(dd, s); break;
+ case eltwise_elu: ds = elu_bwd(dd, s, alpha); break;
+ case eltwise_square: ds = square_bwd(dd, s); break;
+ case eltwise_abs: ds = abs_bwd(dd, s); break;
+ case eltwise_sqrt: ds = sqrt_bwd(dd, s); break;
+ case eltwise_linear:
+ ds = linear_bwd(dd, s, alpha, beta); break;
+ case eltwise_bounded_relu:
+ ds = bounded_relu_bwd(dd, s, alpha); break;
+ case eltwise_soft_relu: ds = soft_relu_bwd(dd, s); break;
+ case eltwise_logistic: ds = logistic_bwd(dd, s); break;
+ default: assert(!"unknown eltwise alg_kind");
+ }
+ });
+}
+
+template <impl::data_type_t data_type>
+void ref_eltwise_bwd_t<data_type>::execute_backward_dense(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+ const memory_desc_wrapper diff_data_d(pd()->diff_src_md());
+
+ const ptrdiff_t nelems = static_cast<ptrdiff_t>(data_d.nelems(true));
+ const auto alg_kind = pd()->desc()->alg_kind;
+ const float alpha = pd()->desc()->alpha;
+ const float beta = pd()->desc()->beta;
+
+ src += data_d.offset0();
+ diff_dst += diff_data_d.offset0();
+ diff_src += diff_data_d.offset0();
+
+ parallel_nd(nelems, [&](ptrdiff_t e) {
+ const data_t dd = diff_dst[e];
+ const data_t s = src[e];
+ data_t &ds = diff_src[e];
+
+ switch (alg_kind) {
+ case eltwise_relu: ds = relu_bwd(dd, s, alpha); break;
+ case eltwise_tanh: ds = tanh_bwd(dd, s); break;
+ case eltwise_elu: ds = elu_bwd(dd, s, alpha); break;
+ case eltwise_square: ds = square_bwd(dd, s); break;
+ case eltwise_abs: ds = abs_bwd(dd, s); break;
+ case eltwise_sqrt: ds = sqrt_bwd(dd, s); break;
+ case eltwise_linear: ds = linear_bwd(dd, s, alpha, beta); break;
+ case eltwise_bounded_relu: ds = bounded_relu_bwd(dd, s, alpha); break;
+ case eltwise_soft_relu: ds = soft_relu_bwd(dd, s); break;
+ case eltwise_logistic: ds = logistic_bwd(dd, s); break;
+ default: assert(!"unknown eltwise alg_kind");
+ }
+ });
+}
+
+template struct ref_eltwise_fwd_t<data_type::f32>;
+template struct ref_eltwise_fwd_t<data_type::s32>;
+template struct ref_eltwise_fwd_t<data_type::s8>;
+template struct ref_eltwise_fwd_t<data_type::u8>;
+
+template struct ref_eltwise_bwd_t<data_type::f32>;
+template struct ref_eltwise_bwd_t<data_type::s32>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_eltwise.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_eltwise.hpp
new file mode 100644
index 0000000000..8f4ab35413
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_eltwise.hpp
@@ -0,0 +1,168 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REF_ELTWISE_HPP
+#define CPU_REF_ELTWISE_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_eltwise_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct ref_eltwise_scalar_fwd_t {
+public:
+ ref_eltwise_scalar_fwd_t(alg_kind_t alg, float alpha, float beta);
+
+ // note that eltwise.scale is ignored
+ ref_eltwise_scalar_fwd_t(const post_ops_t::entry_t::eltwise_t &eltwise);
+
+ float compute_scalar(float s);
+
+ const alg_kind_t alg_;
+ const float alpha_;
+ const float beta_;
+};
+
+template <impl::data_type_t data_type>
+struct ref_eltwise_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_eltwise_fwd_pd_t {
+ using cpu_eltwise_fwd_pd_t::cpu_eltwise_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_eltwise_fwd_t);
+
+ status_t init() {
+ using namespace utils;
+
+ auto src_d = memory_desc_wrapper(src_md());
+
+ use_dense_ = false
+ || src_d.is_dense()
+ || (src_d.is_dense(true) && is_zero_preserved());
+
+ use_nCspBc_padded_ = !use_dense_
+ && src_d.blocking_desc().inner_nblks == 1
+ && one_of(src_d.blocking_desc().inner_blks[0], 8, 16)
+ && src_d.blocking_desc().inner_idxs[0] == 1
+ && src_d.only_padded_dim(1)
+ && src_d.is_dense(true);
+
+ if (has_zero_dim_memory())
+ use_dense_ = use_nCspBc_padded_ = false;
+
+ const bool use_generic = !use_dense_ && !use_nCspBc_padded_;
+
+ bool ok = true
+ && is_fwd()
+ && everyone_is(data_type, desc()->data_desc.data_type)
+ && IMPLICATION(use_generic, one_of(src_d.ndims(), 4, 5))
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ return status::success;
+ }
+
+ bool use_dense_, use_nCspBc_padded_;
+ };
+
+ ref_eltwise_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ if (pd()->use_dense_)
+ execute_forward_dense(ctx);
+ else if (pd()->use_nCspBc_padded_)
+ execute_forward_nCspBc_padded(ctx);
+ else
+ execute_forward_generic(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward_nCspBc_padded(const exec_ctx_t &ctx) const;
+ void execute_forward_dense(const exec_ctx_t &ctx) const;
+ void execute_forward_generic(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t data_type>
+struct ref_eltwise_bwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_eltwise_bwd_pd_t {
+ using cpu_eltwise_bwd_pd_t::cpu_eltwise_bwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_eltwise_bwd_t);
+
+ status_t init() {
+ using namespace utils;
+
+ bool ok = true
+ && !is_fwd()
+ && everyone_is(data_type,
+ desc()->data_desc.data_type,
+ desc()->diff_data_desc.data_type)
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ auto diff_dst_d = memory_desc_wrapper(diff_dst_md());
+ const bool same_fmt_ = diff_dst_d == memory_desc_wrapper(src_md());
+
+ use_dense_ = true
+ && same_fmt_
+ && diff_dst_d.is_dense(true)
+ && is_zero_preserved()
+ && !has_zero_dim_memory();
+ const bool use_generic = !use_dense_;
+
+ if (use_generic && !one_of(diff_dst_d.ndims(), 4, 5))
+ return status::unimplemented;
+
+ return status::success;
+ }
+
+ bool use_dense_;
+ };
+
+ ref_eltwise_bwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ if (pd()->use_dense_)
+ execute_backward_dense(ctx);
+ else
+ execute_backward_generic(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_dense(const exec_ctx_t &ctx) const;
+ void execute_backward_generic(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_inner_product.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_inner_product.cpp
new file mode 100644
index 0000000000..c807a9ffd0
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_inner_product.cpp
@@ -0,0 +1,285 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "mkldnn_thread.hpp"
+#include "mkldnn_traits.hpp"
+#include "math_utils.hpp"
+
+#include "ref_inner_product.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using math::saturate;
+using math::get_bias;
+
+template <data_type_t src_type, data_type_t wei_type, data_type_t dst_type,
+ data_type_t acc_type>
+void ref_inner_product_fwd_t<src_type, wei_type, dst_type, acc_type>::
+execute_forward(const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto bias = CTX_IN_MEM(const char *, MKLDNN_ARG_BIAS);
+ auto dst = CTX_OUT_MEM(dst_data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper bias_d(pd()->weights_md(1));
+
+ const int MB = pd()->MB();
+ const int OC = pd()->OC();
+ const int IC = pd()->IC();
+
+ const bool src_has_spatial = utils::one_of(src_d.ndims(), 3, 4, 5);
+ const int ndims = src_d.ndims() - 2;
+
+ const auto &post_ops = pd()->attr()->post_ops_;
+ const bool do_relu = post_ops.len_ == 1;
+ const float nslope = do_relu ? post_ops.entry_[0].eltwise.alpha : 0.f;
+
+ auto ker_has_spatial = [=](int mb, int oc) {
+ acc_data_t d = 0;
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+ for (int ic = 0; ic < IC; ++ic) {
+ for (int kd = 0; kd < KD; ++kd) {
+ for (int kh = 0; kh < KH; ++kh) {
+ for (int kw = 0; kw < KW; ++kw) {
+ switch (ndims) {
+ case 3:
+ d += (acc_data_t)src[src_d.off(mb, ic, kd, kh, kw)]
+ * weights[weights_d.off(
+ oc, ic, kd, kh, kw)];
+ break;
+ case 2:
+ d += (acc_data_t)src[src_d.off(mb, ic, kh, kw)]
+ * weights[weights_d.off(oc, ic, kh, kw)];
+ break;
+ case 1:
+ d += (acc_data_t)src[src_d.off(mb, ic, kw)]
+ * weights[weights_d.off(oc, ic, kw)];
+ break;
+ default: assert(!"unsupported ndims size");
+ }
+ }
+ }
+ }
+ }
+ return d;
+ };
+
+ auto ker_no_spatial = [=](int mb, int oc) {
+ acc_data_t d = 0;
+ for (int ic = 0; ic < IC; ++ic) {
+ d += (acc_data_t)src[src_d.off(mb, ic)]
+ * weights[weights_d.off(oc, ic)];
+ }
+ return d;
+ };
+
+ parallel_nd(MB, OC, [&](int mb, int oc) {
+ float a = bias
+ ? get_bias(bias, bias_d.off(oc), pd()->desc()->bias_desc.data_type)
+ : 0;
+ if (src_has_spatial)
+ a += ker_has_spatial(mb, oc);
+ else
+ a += ker_no_spatial(mb, oc);
+ if (do_relu && a < (acc_data_t)0)
+ a *= nslope;
+ dst[dst_d.off(mb, oc)] = saturate<dst_data_t>(a);
+ });
+}
+
+using namespace data_type;
+template struct ref_inner_product_fwd_t<f32>;
+template struct ref_inner_product_fwd_t<u8, s8, f32, s32>;
+template struct ref_inner_product_fwd_t<u8, s8, s32, s32>;
+template struct ref_inner_product_fwd_t<u8, s8, s8, s32>;
+template struct ref_inner_product_fwd_t<u8, s8, u8, s32>;
+
+template <data_type_t diff_src_type, data_type_t wei_type,
+ data_type_t diff_dst_type, data_type_t acc_type>
+void ref_inner_product_bwd_data_t<diff_src_type, wei_type, diff_dst_type,
+ acc_type>::execute_backward_data(const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const diff_dst_data_t *, MKLDNN_ARG_DIFF_DST);
+ auto weights = CTX_IN_MEM(const wei_data_t *, MKLDNN_ARG_WEIGHTS);
+ auto diff_src = CTX_OUT_MEM(diff_src_data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper weights_d(pd()->weights_md(0));
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+
+ const int MB = pd()->MB();
+ const int OC = pd()->OC();
+ const int IC = pd()->IC();
+
+ const bool diff_src_has_spatial
+ = utils::one_of(diff_src_d.ndims(), 3, 4, 5);
+ const int ndims = diff_src_d.ndims() - 2;
+
+ parallel_nd(MB, IC, [&](int mb, int ic) {
+ if (diff_src_has_spatial) {
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+ for (int kd = 0; kd < KD; ++kd)
+ for (int kh = 0; kh < KH; ++kh)
+ for (int kw = 0; kw < KW; ++kw) {
+ acc_data_t ds = acc_data_t(0);
+ for (int oc = 0; oc < OC; ++oc) {
+ switch (ndims) {
+ case 3:
+ ds += (acc_data_t)(diff_dst[diff_dst_d.off(mb, oc)]
+ * weights[weights_d.off(oc, ic, kd, kh, kw)]);
+ break;
+ case 2:
+ ds += (acc_data_t)(diff_dst[diff_dst_d.off(mb, oc)]
+ * weights[weights_d.off(oc, ic, kh, kw)]);
+ break;
+ case 1:
+ ds += (acc_data_t)(diff_dst[diff_dst_d.off(mb, oc)]
+ * weights[weights_d.off(oc, ic, kw)]);
+ break;
+ default: assert(!"unsupported ndims size");
+ }
+ }
+ switch (ndims) {
+ case 3:
+ diff_src[diff_src_d.off(mb, ic, kd, kh, kw)]
+ = (diff_src_data_t)ds;
+ break;
+ case 2:
+ diff_src[diff_src_d.off(mb, ic, kh, kw)]
+ = (diff_src_data_t)ds;
+ break;
+ case 1:
+ diff_src[diff_src_d.off(mb, ic, kw)] = (diff_src_data_t)ds;
+ break;
+ default: assert(!"unsupported ndims size");
+ }
+ }
+ } else {
+ acc_data_t ds = acc_data_t(0);
+ for (int oc = 0; oc < OC; ++oc) {
+ ds += (acc_data_t)(diff_dst[diff_dst_d.off(mb, oc)] *
+ weights[weights_d.off(oc, ic)]);
+ }
+ diff_src[diff_src_d.off(mb, ic)] = (diff_src_data_t)ds;
+ }
+ });
+}
+
+template struct ref_inner_product_bwd_data_t<f32, f32, f32, f32>;
+
+template <impl::data_type_t data_type>
+void ref_inner_product_bwd_weights_t<data_type>::execute_backward_weights(
+ const exec_ctx_t &ctx) const {
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_weights = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_WEIGHTS);
+ auto diff_bias = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_BIAS);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_weights_d(pd()->diff_weights_md(0));
+ const memory_desc_wrapper diff_bias_d(pd()->diff_weights_md(1));
+
+ const int MB = pd()->MB();
+ const int OC = pd()->OC();
+ const int IC = pd()->IC();
+
+ const bool src_has_spatial = utils::one_of(src_d.ndims(), 3, 4 ,5);
+ const int ndims = src_d.ndims() - 2;
+
+ parallel_nd(OC, IC, [&](int oc, int ic) {
+ if (src_has_spatial) {
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+ for (int kd = 0; kd < KD; ++kd) {
+ for (int kh = 0; kh < KH; ++kh) {
+ for (int kw = 0; kw < KW; ++kw) {
+ data_t *dw(nullptr);
+ switch (ndims) {
+ case 3:
+ dw = &diff_weights[diff_weights_d.off(
+ oc, ic, kd, kh, kw)];
+ break;
+ case 2:
+ dw = &diff_weights[diff_weights_d.off(
+ oc, ic, kh, kw)];
+ break;
+ case 1:
+ dw = &diff_weights[diff_weights_d.off(oc, ic, kw)];
+ break;
+ default: assert(!"unsupported ndims size");
+ }
+ *dw = data_t(0);
+ for (int mb = 0; mb < MB; ++mb) {
+ switch (ndims) {
+ case 3:
+ *dw += diff_dst[diff_dst_d.off(mb, oc)]
+ * src[src_d.off(mb, ic, kd, kh, kw)];
+ break;
+ case 2:
+ *dw += diff_dst[diff_dst_d.off(mb, oc)]
+ * src[src_d.off(mb, ic, kh, kw)];
+ break;
+ case 1:
+ *dw += diff_dst[diff_dst_d.off(mb, oc)]
+ * src[src_d.off(mb, ic, kw)];
+ break;
+ default: assert(!"unsupported ndims size");
+ }
+ }
+ }
+ }
+ }
+ } else {
+ data_t *dw = &diff_weights[diff_weights_d.off(oc, ic)];
+ *dw = data_t(0);
+ for (int mb = 0; mb < MB; ++mb) {
+ *dw += diff_dst[diff_dst_d.off(mb, oc)] *
+ src[src_d.off(mb, ic)];
+ }
+ }
+ });
+
+ if (diff_bias) {
+ diff_bias += diff_bias_d.offset0();
+
+ parallel_nd(OC, [&](int oc) {
+ data_t *db = &diff_bias[oc];
+ *db = data_t(0);
+ for (int mb = 0; mb < MB; ++mb)
+ *db += diff_dst[diff_dst_d.off(mb, oc)];
+ });
+ }
+}
+
+template struct ref_inner_product_bwd_weights_t<data_type::f32>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_inner_product.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_inner_product.hpp
new file mode 100644
index 0000000000..bf87dbd514
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_inner_product.hpp
@@ -0,0 +1,159 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REF_INNER_PRODUCT_HPP
+#define CPU_REF_INNER_PRODUCT_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_inner_product_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t src_type, impl::data_type_t wei_type = src_type,
+ impl::data_type_t dst_type = src_type,
+ impl::data_type_t acc_type = dst_type>
+struct ref_inner_product_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_inner_product_fwd_pd_t {
+ using cpu_inner_product_fwd_pd_t::cpu_inner_product_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_inner_product_fwd_t);
+
+ status_t init() {
+ using namespace data_type;
+
+ bool ok = true
+ && set_default_params() == status::success
+ && is_fwd()
+ && src_md()->data_type == src_type
+ && weights_md()->data_type == wei_type
+ && desc()->accum_data_type == acc_type
+ && dst_md()->data_type == dst_type
+ && IMPLICATION(with_bias(), utils::one_of(
+ weights_md(1)->data_type, f32, s32, s8, u8))
+ && attr()->output_scales_.has_default_values()
+ && attr()->post_ops_.len_ <= 1
+ && IMPLICATION(attr()->post_ops_.len_ == 1,
+ attr()->post_ops_.entry_[0].is_relu(true, false));
+ return ok ? status::success : status::unimplemented;
+ }
+ };
+
+ ref_inner_product_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<wei_type>::type wei_data_t;
+ typedef typename prec_traits<dst_type>::type dst_data_t;
+ typedef typename prec_traits<acc_type>::type acc_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t diff_src_type, impl::data_type_t wei_type,
+ impl::data_type_t diff_dst_type,
+ impl::data_type_t acc_type = diff_src_type>
+struct ref_inner_product_bwd_data_t: public cpu_primitive_t {
+ struct pd_t: public cpu_inner_product_bwd_data_pd_t {
+ using cpu_inner_product_bwd_data_pd_t::cpu_inner_product_bwd_data_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_inner_product_bwd_data_t);
+
+ status_t init() {
+ bool ok = true
+ && set_default_params() == status::success
+ && desc()->prop_kind == prop_kind::backward_data
+ && diff_src_md()->data_type == diff_src_type
+ && weights_md()->data_type == wei_type
+ && desc()->accum_data_type == acc_type
+ && diff_dst_md()->data_type == diff_dst_type
+ && attr()->has_default_values();
+ return ok ? status::success : status::unimplemented;
+ }
+ };
+
+ ref_inner_product_bwd_data_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ typedef typename prec_traits<diff_src_type>::type diff_src_data_t;
+ typedef typename prec_traits<wei_type>::type wei_data_t;
+ typedef typename prec_traits<diff_dst_type>::type diff_dst_data_t;
+ typedef typename prec_traits<acc_type>::type acc_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_data(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_data(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t data_type>
+struct ref_inner_product_bwd_weights_t: public cpu_primitive_t {
+ struct pd_t: public cpu_inner_product_bwd_weights_pd_t {
+ using cpu_inner_product_bwd_weights_pd_t::cpu_inner_product_bwd_weights_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_inner_product_bwd_weights_t);
+
+ status_t init() {
+ bool ok = true
+ && set_default_params() == status::success
+ && desc()->prop_kind == prop_kind::backward_weights
+ && utils::everyone_is(data_type,
+ src_md()->data_type,
+ diff_dst_md()->data_type,
+ diff_weights_md()->data_type)
+ && IMPLICATION(with_bias(),
+ data_type == diff_weights_md(1)->data_type)
+ && attr()->has_default_values();
+ return ok ? status::success : status::unimplemented;
+ }
+ };
+
+ ref_inner_product_bwd_weights_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward_weights(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_weights(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_lrn.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_lrn.cpp
new file mode 100644
index 0000000000..325e97963b
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_lrn.cpp
@@ -0,0 +1,252 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <math.h>
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+
+#include "ref_lrn.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+static inline float fast_negative_powf(float omega, float beta) {
+ float Y;
+/*
+ * Y = omega^(-3/4) =
+ * = 1.0f / sqrtf(omega) * sqrtf(1.0f / sqrtf(omega))
+ * = sqrtf(1.0f / sqrtf(omega)) * 1.0f / sqrtf(omega)
+ * = sqrtf(1.0f / sqrtf(omega)) / sqrtf(omega)
+ * = sqrtf(1.0f / sqrtf(omega) / omega)
+ * = sqrtf(1.0f / (sqrtf(omega) * omega))
+ */
+ if (beta == 0.75f) {
+ Y = sqrtf(1.0f / (sqrtf(omega) * omega));
+ } else {
+ Y = 1.0f / powf(omega, beta);
+ }
+ return Y;
+};
+
+template <impl::data_type_t data_type>
+template <impl::format_tag_t tag>
+void ref_lrn_fwd_t<data_type>::execute_forward(const exec_ctx_t &ctx) const {
+ using namespace alg_kind;
+ using namespace format_tag;
+
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+
+ const int C = pd()->C();
+ const int H = pd()->H();
+ const int W = pd()->W();
+ const size_t stride_mb = data_d.blocking_desc().strides[0];
+ const bool across_channels = pd()->desc()->alg_kind == lrn_across_channels;
+ constexpr int blksize = tag == nChw16c ? 16 : 8;
+
+ auto data_off = [&](int mb, int c, int h, int w) -> size_t {
+ switch (tag) {
+ case nChw16c:
+ case nChw8c: return mb * stride_mb + c / blksize * H * W * blksize
+ + h * W * blksize + w * blksize + c % blksize;
+ case nchw: return mb * stride_mb + c * H * W + h * W + w;
+ case nhwc: return mb * stride_mb + h * W * C + w * C + c;
+ default: return data_d.off(mb, c, h, w);
+ }
+ };
+
+ auto ker = [=](data_t *d, int mb, int oc, int oh, int ow) {
+ const float alpha = static_cast<float>(pd()->desc()->lrn_alpha);
+ const float beta = static_cast<float>(pd()->desc()->lrn_beta);
+ const float k = static_cast<float>(pd()->desc()->lrn_k);
+
+ const int size = pd()->desc()->local_size;
+ const int half_size = (size - 1) / 2;
+
+ float sum = 0;
+ if (across_channels) {
+ const int c_st = nstl::max(oc - half_size + 0, 0);
+ const int c_en = nstl::min(oc + half_size + 1, C);
+
+ for (int c = c_st; c < c_en; ++c) {
+ const float s = src[data_off(mb, c, oh, ow)];
+ sum += s * s;
+ }
+ } else {
+ int h_st = nstl::max(oh - half_size + 0, 0);
+ int h_en = nstl::min(oh + half_size + 1, H);
+ int w_st = nstl::max(ow - half_size + 0, 0);
+ int w_en = nstl::min(ow + half_size + 1, W);
+ for (int h = h_st; h < h_en; ++h) {
+ for (int w = w_st; w < w_en; ++w) {
+ const float s = src[data_off(mb, oc, h, w)];
+ sum += s * s;
+ }
+ }
+ }
+ const int summands = across_channels ? size : size * size;
+ sum = k + alpha * sum / summands;
+ size_t off = data_off(mb, oc, oh, ow);
+ d[0] = static_cast<data_t>(src[off] * fast_negative_powf(sum, beta));
+ };
+
+ const int MB = pd()->MB();
+ if (tag == nChw16c || tag == nChw8c) {
+ parallel_nd(MB, utils::div_up(C, blksize), H, W,
+ [&](int mb, int c_blk, int h, int w) {
+ int c = c_blk * blksize;
+ const size_t off = mb * stride_mb + c * H * W
+ + (h * W + w) * blksize;
+ PRAGMA_OMP_SIMD()
+ for (int cc = 0; cc < nstl::min(blksize, C - c); ++cc)
+ ker(&dst[off + cc], mb, c + cc, h, w);
+ });
+ } else if (tag == nhwc) {
+ parallel_nd(MB, H, W, C,
+ [&](int mb, int h, int w, int c) {
+ const size_t off = mb * stride_mb + h * W * C + w * C + c;
+ ker(&dst[off], mb, c, h, w);
+ });
+ } else {
+ parallel_nd(MB, C, H, W,
+ [&](int mb, int c, int h, int w) {
+ const size_t off = data_off(mb, c, h, w);
+ ker(&dst[off], mb, c, h, w);
+ });
+ }
+}
+
+template <impl::data_type_t data_type>
+template <mkldnn_format_tag_t tag>
+void ref_lrn_bwd_t<data_type>::execute_backward(const exec_ctx_t &ctx) const {
+ using namespace alg_kind;
+ using namespace format_tag;
+
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+
+ const int MB = pd()->MB();
+ const int C = pd()->C();
+ const int H = pd()->H();
+ const int W = pd()->W();
+ const size_t stride_mb = data_d.blocking_desc().strides[0];
+ constexpr int blksize = tag == nChw16c ? 16 : 8;
+
+ const float alpha = static_cast<float>(pd()->desc()->lrn_alpha);
+ const float beta = static_cast<float>(pd()->desc()->lrn_beta);
+ const float k = static_cast<float>(pd()->desc()->lrn_k);
+ const int kernel_size = pd()->desc()->local_size;
+ const int half_ksize = (kernel_size - 1) / 2;
+
+ auto data_off = [&](int mb, int c, int h, int w) -> size_t {
+ switch (tag) {
+ case nChw16c:
+ case nChw8c: return mb * stride_mb + c/blksize * H * W * blksize
+ + h * W * blksize + w * blksize + c%blksize;
+ case nchw: return mb * stride_mb + c * H * W + h * W + w;
+ case nhwc: return mb * stride_mb + h * W * C + w * C + c;
+ default: return data_d.off(mb, c, h, w);
+ }
+ };
+
+ auto ker = [=](data_t *d, int mb, int oc, int oh, int ow) {
+ const int c_st = nstl::max(oc - half_ksize + 0, 0);
+ const int c_en = nstl::min(oc + half_ksize + 1, C);
+
+ float A = 0, B = 0, omega_mid = 0;
+ for (int c = c_st; c < c_en; c++) {
+ float sum = 0.0;
+ const int i_st = nstl::max(c - half_ksize, 0);
+ const int i_en = nstl::min(c + kernel_size - half_ksize, C);
+
+ for (int i = i_st; i < i_en; ++i) {
+ const float value = src[data_off(mb, i, oh, ow)];
+ sum += value * value;
+ }
+ const float omega = static_cast<float>(k + sum * alpha / kernel_size);
+ if (c == oc) omega_mid = omega;
+ float t = src[data_off(mb, c, oh, ow)]
+ * fast_negative_powf(omega, beta);
+ B += 1.0f / omega * t * diff_dst[data_off(mb, c, oh, ow)];
+ }
+
+ const size_t off = data_off(mb, oc, oh, ow);
+ A = fast_negative_powf(omega_mid, beta) * diff_dst[off];
+ B *= src[off];
+ B *= (2.0f * alpha * beta) / kernel_size;
+ *d = static_cast<data_t>(A - B); // final cast down to data_t
+ };
+
+ if (tag == nChw16c || tag == nChw8c) {
+ parallel_nd(MB, utils::div_up(C, blksize), H, W,
+ [&](int mb, int c_blk, int h, int w) {
+ int c = c_blk * blksize;
+ const size_t off = mb * stride_mb + c * H * W +
+ (h * W + w) * blksize;
+ PRAGMA_OMP_SIMD()
+ for (int cc = 0; cc < nstl::min(blksize, C - c); ++cc)
+ ker(&diff_src[off + cc], mb, c + cc, h, w);
+ });
+ } else if (tag == nhwc) {
+ parallel_nd(MB, H, W, C,
+ [&](int mb, int h, int w, int c) {
+ const size_t off = mb * stride_mb + h * W * C + w * C + c;
+ ker(&diff_src[off], mb, c, h, w);
+ });
+ } else {
+ parallel_nd(MB, C, H, W,
+ [&](int mb, int c, int h, int w) {
+ const size_t off = data_off(mb, c, h, w);
+ ker(&diff_src[off], mb, c, h, w);
+ });
+ }
+}
+
+template void ref_lrn_fwd_t<data_type::f32>::
+execute_forward<format_tag::nChw16c>(const exec_ctx_t &ctx) const;
+template void ref_lrn_fwd_t<data_type::f32>::
+execute_forward<format_tag::nChw8c>(const exec_ctx_t &ctx) const;
+template void ref_lrn_fwd_t<data_type::f32>::
+execute_forward<format_tag::nchw>(const exec_ctx_t &ctx) const;
+template void ref_lrn_fwd_t<data_type::f32>::
+execute_forward<format_tag::nhwc>(const exec_ctx_t &ctx) const;
+template void ref_lrn_fwd_t<data_type::f32>::
+execute_forward<format_tag::any>(const exec_ctx_t &ctx) const;
+template void ref_lrn_bwd_t<data_type::f32>::
+execute_backward<format_tag::nChw16c>(const exec_ctx_t &ctx) const;
+template void ref_lrn_bwd_t<data_type::f32>::
+execute_backward<format_tag::nChw8c>(const exec_ctx_t &ctx) const;
+template void ref_lrn_bwd_t<data_type::f32>::
+execute_backward<format_tag::nchw>(const exec_ctx_t &ctx) const;
+template void ref_lrn_bwd_t<data_type::f32>::
+execute_backward<format_tag::nhwc>(const exec_ctx_t &ctx) const;
+template void ref_lrn_bwd_t<data_type::f32>::
+execute_backward<format_tag::any>(const exec_ctx_t &ctx) const;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_lrn.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_lrn.hpp
new file mode 100644
index 0000000000..f25cfb7fae
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_lrn.hpp
@@ -0,0 +1,136 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REF_LRN_HPP
+#define CPU_REF_LRN_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_lrn_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t data_type>
+struct ref_lrn_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_lrn_fwd_pd_t {
+ using cpu_lrn_fwd_pd_t::cpu_lrn_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_lrn_fwd_t);
+
+ status_t init() {
+ using namespace format_tag;
+
+ bool ok = true
+ && is_fwd()
+ && src_md()->data_type == data_type
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ dat_tag_ = memory_desc_matches_one_of_tag(
+ *src_md(), nChw16c, nChw8c, nchw, nhwc);
+
+ return status::success;
+ }
+
+ format_tag_t dat_tag_;
+ };
+
+ ref_lrn_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ using namespace format_tag;
+ switch (pd()->dat_tag_) {
+ case nChw16c: execute_forward<nChw16c>(ctx); break;
+ case nChw8c: execute_forward<nChw8c>(ctx); break;
+ case nchw: execute_forward<nchw>(ctx); break;
+ case nhwc: execute_forward<nhwc>(ctx); break;
+ default: execute_forward<any>(ctx);
+ }
+ return status::success;
+ }
+
+private:
+ template<format_tag_t tag>
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t data_type>
+struct ref_lrn_bwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_lrn_bwd_pd_t {
+ using cpu_lrn_bwd_pd_t::cpu_lrn_bwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_lrn_bwd_t);
+
+ status_t init() {
+ using namespace format_tag;
+ using namespace alg_kind;
+
+ bool ok = true
+ && !is_fwd()
+ && utils::one_of(desc()->alg_kind, lrn_across_channels
+ /*, lrn_within_channel */) // not supported yet
+ && utils::everyone_is(data_type,
+ src_md()->data_type,
+ diff_src_md()->data_type)
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ dat_tag_ = memory_desc_matches_one_of_tag(
+ *src_md(), nChw16c, nChw8c, nchw, nhwc);
+
+ return status::success;
+ }
+
+ format_tag_t dat_tag_;
+ };
+
+ ref_lrn_bwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ using namespace format_tag;
+ switch (pd()->dat_tag_) {
+ case nChw16c: execute_backward<nChw16c>(ctx); break;
+ case nChw8c: execute_backward<nChw8c>(ctx); break;
+ case nchw: execute_backward<nchw>(ctx); break;
+ case nhwc: execute_backward<nhwc>(ctx); break;
+ default: execute_backward<any>(ctx);
+ }
+ return status::success;
+ }
+
+private:
+ template<format_tag_t tag>
+ void execute_backward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_pooling.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_pooling.cpp
new file mode 100644
index 0000000000..65b934e123
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_pooling.cpp
@@ -0,0 +1,381 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <math.h>
+
+#include "c_types_map.hpp"
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+
+#include "ref_pooling.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <data_type_t data_type, data_type_t acc_type>
+void ref_pooling_fwd_t<data_type, acc_type>::execute_forward(
+ const exec_ctx_t &ctx) const {
+ using namespace alg_kind;
+ using namespace prop_kind;
+
+ auto alg = pd()->desc()->alg_kind;
+
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+ auto ws = CTX_OUT_MEM(unsigned char *, MKLDNN_ARG_WORKSPACE);
+
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+ const memory_desc_wrapper ws_d(pd()->workspace_md());
+ const data_type_t ws_dt = ws ? ws_d.data_type() : data_type::undef;
+
+ const int ID = pd()->ID();
+ const int IH = pd()->IH();
+ const int IW = pd()->IW();
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+ const int SD = pd()->KSD();
+ const int SH = pd()->KSH();
+ const int SW = pd()->KSW();
+ const int padF = pd()->padFront();
+ const int padT = pd()->padT();
+ const int padL = pd()->padL();
+
+ const bool is_3d = pd()->desc()->src_desc.ndims == 5;
+
+ auto apply_offset = [=](int index, int offset) {
+ return (index > offset) ? index - offset : 0;
+ };
+
+ auto set_ws = [=](int mb, int oc, int od, int oh, int ow, int value) {
+ if (ws) {
+ assert(ws_dt == data_type::u8 || ws_dt == data_type::s32);
+ size_t offset = is_3d
+ ? ws_d.off(mb, oc, od, oh, ow) : ws_d.off(mb, oc, oh, ow);;
+ if (ws_dt == data_type::u8) {
+ assert(0 <= value && value <= 255);
+ ws[offset] = value;
+ } else
+ reinterpret_cast<int *>(ws)[offset] = value;
+ }
+ };
+
+ auto ker_max = [=](data_t *d, int mb, int oc, int oh, int ow) {
+ for (int kh = 0; kh < KH; ++kh) {
+ for (int kw = 0; kw < KW; ++kw) {
+ const int ih = oh * SH - padT + kh;
+ const int iw = ow * SW - padL + kw;
+
+ if (ih < 0 || ih >= IH) continue;
+ if (iw < 0 || iw >= IW) continue;
+
+ auto s = src[src_d.off(mb, oc, ih, iw)];
+ if (s > d[0]) {
+ d[0] = s;
+ set_ws(mb, oc, 1, oh, ow, kh*KW + kw);
+ }
+ }
+ }
+ };
+
+ auto ker_avg = [=](data_t *d, int mb, int oc, int oh, int ow) {
+ auto ih_start = apply_offset(oh*SH, padT);
+ auto iw_start = apply_offset(ow*SW, padL);
+ auto ih_end = nstl::min(oh*SH - padT + KH, IH);
+ auto iw_end = nstl::min(ow*SW - padL + KW, IW);
+
+ auto num_summands = (alg == pooling_avg_include_padding) ? KW*KH
+ : (ih_end - ih_start)*(iw_end - iw_start);
+
+ acc_data_t dst = 0;
+ for (int ih = ih_start; ih < ih_end; ++ih) {
+ for (int iw = iw_start; iw < iw_end; ++iw) {
+ dst += src[src_d.off(mb, oc, ih, iw)];
+ }
+ }
+
+ d[0] = math::out_round<data_t>((float)dst / num_summands);
+ };
+
+ auto ker_max_3d = [=](data_t *d, int mb, int oc, int od, int oh, int ow) {
+ for (int kd = 0; kd < KD; ++kd) {
+ for (int kh = 0; kh < KH; ++kh) {
+ for (int kw = 0; kw < KW; ++kw) {
+ const int id = od * SD - padF + kd;
+ const int ih = oh * SH - padT + kh;
+ const int iw = ow * SW - padL + kw;
+
+ if (id < 0 || id >= ID) continue;
+ if (ih < 0 || ih >= IH) continue;
+ if (iw < 0 || iw >= IW) continue;
+
+ auto s = src[src_d.off(mb, oc, id, ih, iw)];
+ if (s > d[0]) {
+ d[0] = s;
+ set_ws(mb, oc, od, oh, ow, kd * KH * KW + kh*KW + kw);
+ }
+ }
+ }
+ }
+ };
+
+ auto ker_avg_3d = [=](data_t *d, int mb, int oc, int od, int oh, int ow) {
+ auto id_start = apply_offset(od*SD, padF);
+ auto ih_start = apply_offset(oh*SH, padT);
+ auto iw_start = apply_offset(ow*SW, padL);
+ auto id_end = nstl::min(od*SD - padF + KD, ID);
+ auto ih_end = nstl::min(oh*SH - padT + KH, IH);
+ auto iw_end = nstl::min(ow*SW - padL + KW, IW);
+
+ auto num_summands = (alg == pooling_avg_include_padding) ? KW*KH*KD
+ : (ih_end - ih_start)*(iw_end - iw_start)*(id_end - id_start);
+
+ acc_data_t dst = 0;
+ for (int id = id_start; id < id_end; ++id) {
+ for (int ih = ih_start; ih < ih_end; ++ih) {
+ for (int iw = iw_start; iw < iw_end; ++iw) {
+ dst += src[src_d.off(mb, oc, id, ih, iw)];
+ }
+ }
+ }
+
+ d[0] = math::out_round<data_t>((float)dst / num_summands);
+ };
+
+ const int MB = pd()->MB();
+ const int OC = pd()->C();
+ const int OD = pd()->OD();
+ const int OH = pd()->OH();
+ const int OW = pd()->OW();
+
+ if (alg == pooling_max) {
+ parallel_nd(MB, OC, OD, OH, OW,
+ [&](int mb, int oc, int od, int oh, int ow) {
+ data_t *d = is_3d
+ ? &dst[dst_d.off(mb, oc, od, oh, ow)]
+ : &dst[dst_d.off(mb, oc, oh, ow)];
+ d[0] = nstl::numeric_limits<data_t>::lowest();
+ set_ws(mb, oc, od, oh, ow, 0);
+ if (is_3d) ker_max_3d(d, mb, oc, od, oh, ow);
+ else ker_max(d, mb, oc, oh, ow);
+ });
+ } else {
+ parallel_nd(MB, OC, OD, OH, OW,
+ [&](int mb, int oc, int od, int oh, int ow) {
+ data_t *d = is_3d
+ ? &dst[dst_d.off(mb, oc, od, oh, ow)]
+ : &dst[dst_d.off(mb, oc, oh, ow)];
+ d[0] = 0;
+ if (is_3d) ker_avg_3d(d, mb, oc, od, oh, ow);
+ else ker_avg(d, mb, oc, oh, ow);
+ });
+ }
+}
+
+template <data_type_t data_type, data_type_t acc_type>
+void ref_pooling_bwd_t<data_type, acc_type>::execute_backward(
+ const exec_ctx_t &ctx) const {
+ using namespace alg_kind;
+
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto ws = CTX_IN_MEM(const unsigned char *, MKLDNN_ARG_WORKSPACE);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper diff_dst_d(pd()->diff_dst_md());
+ const memory_desc_wrapper diff_src_d(pd()->diff_src_md());
+ const memory_desc_wrapper ws_d(pd()->workspace_md());
+
+ const int ID = pd()->ID();
+ const int IH = pd()->IH();
+ const int IW = pd()->IW();
+ const int KD = pd()->KD();
+ const int KH = pd()->KH();
+ const int KW = pd()->KW();
+ const int SD = pd()->KSD();
+ const int SH = pd()->KSH();
+ const int SW = pd()->KSW();
+ const int padF = pd()->padFront();
+ const int padT = pd()->padT();
+ const int padL = pd()->padL();
+
+ const bool is_3d = pd()->desc()->diff_src_desc.ndims == 5;
+
+ auto alg = pd()->desc()->alg_kind;
+
+ auto apply_offset = [=](int index, int offset) {
+ return (index > offset) ? index - offset : 0;
+ };
+
+ auto ker_zero = [=](int _mb, int _oc) {
+ for (int ih = 0; ih < IH; ++ih) {
+ for (int iw = 0; iw < IW; ++iw) {
+ diff_src[diff_src_d.off(_mb, _oc, ih, iw)] = data_type_t(0);
+ }
+ }
+ };
+
+ auto ker_max = [=](const data_t *d, int mb, int oc, int oh, int ow) {
+ const size_t ws_off = ws_d.off(mb, oc, oh, ow);
+ const int index = ws_d.data_type() == data_type::u8
+ ? (int)ws[ws_off] : ((int *)ws)[ws_off];
+ const int kw = index % KW;
+ const int kh = index / KW;
+ const int ih = oh * SH - padT + kh;
+ const int iw = ow * SW - padL + kw;
+
+ // If padding area could fit the kernel,
+ // then input displacement would be out of bounds.
+ // No need to back propagate there as padding is
+ // virtual in pooling_max case.
+ if (ih < 0 || ih >= IH)
+ return;
+ if (iw < 0 || iw >= IW)
+ return;
+
+ diff_src[diff_src_d.off(mb, oc, ih, iw)] += d[0];
+ };
+
+ auto ker_avg = [=](const data_t *d, int mb, int oc, int oh, int ow) {
+ auto ih_start = apply_offset(oh*SH, padT);
+ auto iw_start = apply_offset(ow*SW, padL);
+ auto ih_end = nstl::min(oh*SH - padT + KH, IH);
+ auto iw_end = nstl::min(ow*SW - padL + KW, IW);
+
+ auto num_summands = (alg == pooling_avg_include_padding) ? KW*KH
+ : (ih_end - ih_start)*(iw_end - iw_start);
+
+ for (int ih = ih_start; ih < ih_end; ++ih) {
+ for (int iw = iw_start; iw < iw_end; ++iw) {
+ diff_src[diff_src_d.off(mb, oc, ih, iw)] += d[0] / num_summands;
+ }
+ }
+ };
+
+ auto ker_zero_3d = [=](int _mb, int _oc) {
+ for (int id = 0; id < ID; ++id) {
+ for (int ih = 0; ih < IH; ++ih) {
+ for (int iw = 0; iw < IW; ++iw) {
+ diff_src[diff_src_d.off(_mb, _oc, id, ih, iw)] =
+ data_type_t(0);
+ }
+ }
+ }
+ };
+
+ auto ker_max_3d = [=](const data_t *d, int mb, int oc, int od, int oh,
+ int ow) {
+ const size_t ws_off = ws_d.off(mb, oc, od, oh, ow);
+ const int index = ws_d.data_type() == data_type::u8
+ ? (int)ws[ws_off] : ((int *)ws)[ws_off];
+ const int kw = index % KW;
+ const int kh = (index / KW) % KH;
+ const int kd = (index / KW) / KH;
+ const int id = od * SD - padF + kd;
+ const int ih = oh * SH - padT + kh;
+ const int iw = ow * SW - padL + kw;
+
+ // If padding area could fit the kernel,
+ // then input displacement would be out of bounds.
+ // No need to back propagate there as padding is
+ // virtual in pooling_max case.
+ if (id < 0 || id >= ID)
+ return;
+ if (ih < 0 || ih >= IH)
+ return;
+ if (iw < 0 || iw >= IW)
+ return;
+
+ diff_src[diff_src_d.off(mb, oc, id, ih, iw)] += d[0];
+ };
+
+ auto ker_avg_3d = [=](const data_t *d, int mb, int oc, int od, int oh,
+ int ow) {
+ auto id_start = apply_offset(od*SD, padF);
+ auto ih_start = apply_offset(oh*SH, padT);
+ auto iw_start = apply_offset(ow*SW, padL);
+ auto id_end = nstl::min(od*SD - padF + KD, ID);
+ auto ih_end = nstl::min(oh*SH - padT + KH, IH);
+ auto iw_end = nstl::min(ow*SW - padL + KW, IW);
+
+ auto num_summands = (alg == pooling_avg_include_padding) ? KW*KH*KD
+ : (ih_end - ih_start)*(iw_end - iw_start)*(id_end - id_start);
+
+ for (int id = id_start; id < id_end; ++id)
+ for (int ih = ih_start; ih < ih_end; ++ih)
+ for (int iw = iw_start; iw < iw_end; ++iw) {
+ diff_src[diff_src_d.off(mb, oc, id, ih, iw)] += d[0] / num_summands;
+ }
+ };
+
+ const int MB = pd()->MB();
+ const int OC = pd()->C();
+ const int OD = pd()->OD();
+ const int OH = pd()->OH();
+ const int OW = pd()->OW();
+
+ if (pd()->desc()->alg_kind == alg_kind::pooling_max) {
+ parallel_nd(MB, OC, [&](int mb, int oc) {
+ if (is_3d) ker_zero_3d(mb, oc);
+ else ker_zero(mb, oc);
+ for (int od = 0; od < OD; ++od) {
+ for (int oh = 0; oh < OH; ++oh) {
+ for (int ow = 0; ow < OW; ++ow) {
+ const data_t *d = is_3d
+ ? &diff_dst[diff_dst_d.off(mb, oc, od, oh, ow)]
+ : &diff_dst[diff_dst_d.off(mb, oc, oh, ow)];
+ if (is_3d) ker_max_3d(d, mb, oc, od, oh, ow);
+ else ker_max(d, mb, oc, oh, ow);
+ }
+ }
+ }
+ });
+ } else {
+ parallel_nd(MB, OC, [&](int mb, int oc) {
+ if (is_3d) ker_zero_3d(mb, oc);
+ else ker_zero(mb, oc);
+ for (int od = 0; od < OD; ++od) {
+ for (int oh = 0; oh < OH; ++oh) {
+ for (int ow = 0; ow < OW; ++ow) {
+ const data_t *d = is_3d
+ ? &diff_dst[diff_dst_d.off(mb, oc, od, oh, ow)]
+ : &diff_dst[diff_dst_d.off(mb, oc, oh, ow)];
+ if (is_3d) ker_avg_3d(d, mb, oc, od, oh, ow);
+ else ker_avg(d, mb, oc, oh, ow);
+ }
+ }
+ }
+ });
+ }
+}
+
+template struct ref_pooling_fwd_t<data_type::f32>;
+template struct ref_pooling_fwd_t<data_type::s32>;
+template struct ref_pooling_fwd_t<data_type::s8, data_type::s32>;
+template struct ref_pooling_fwd_t<data_type::u8, data_type::s32>;
+
+template struct ref_pooling_bwd_t<data_type::f32>;
+template struct ref_pooling_bwd_t<data_type::s32>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_pooling.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_pooling.hpp
new file mode 100644
index 0000000000..e43ceaa82b
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_pooling.hpp
@@ -0,0 +1,119 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REF_POOLING_HPP
+#define CPU_REF_POOLING_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_pooling_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t data_type, impl::data_type_t acc_type = data_type>
+struct ref_pooling_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_pooling_fwd_pd_t {
+ using cpu_pooling_fwd_pd_t::cpu_pooling_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_pooling_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && set_default_params() == status::success
+ && is_fwd()
+ && utils::everyone_is(data_type, src_md()->data_type,
+ dst_md()->data_type)
+ && desc()->accum_data_type == acc_type
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ bool is_training = desc_.prop_kind == prop_kind::forward_training;
+ if (desc()->alg_kind == alg_kind::pooling_max && is_training)
+ init_default_ws();
+
+ return status::success;
+ }
+ };
+
+ ref_pooling_fwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ typedef typename prec_traits<data_type>::type data_t;
+ typedef typename prec_traits<acc_type>::type acc_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_forward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <impl::data_type_t data_type, impl::data_type_t acc_type = data_type>
+struct ref_pooling_bwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_pooling_bwd_pd_t {
+ using cpu_pooling_bwd_pd_t::cpu_pooling_bwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_pooling_bwd_t);
+
+ status_t init() {
+ bool ok = true
+ && set_default_params() == status::success
+ && !is_fwd()
+ && utils::everyone_is(data_type, diff_dst_md()->data_type,
+ diff_src_md()->data_type)
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ if (desc()->alg_kind == alg_kind::pooling_max) {
+ init_default_ws();
+ if (!compare_ws(hint_fwd_pd_))
+ return status::unimplemented;
+ }
+
+ return status::success;
+ }
+ };
+
+ ref_pooling_bwd_t(const pd_t *apd): cpu_primitive_t(apd) {}
+ typedef typename prec_traits<data_type>::type data_t;
+ typedef typename prec_traits<acc_type>::type acc_data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_backward(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_shuffle.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_shuffle.cpp
new file mode 100644
index 0000000000..af27743110
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_shuffle.cpp
@@ -0,0 +1,153 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <math.h>
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+
+#include "ref_shuffle.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace format_tag;
+
+template <int data_type_size>
+template <mkldnn_format_tag_t tag>
+void ref_shuffle_t<data_type_size>::execute_(const exec_ctx_t &ctx) const {
+ using namespace prop_kind;
+ using namespace utils;
+
+ const memory_desc_wrapper data_d(pd()->data_md());
+
+ auto i_arg = pd()->is_fwd() ? MKLDNN_ARG_SRC : MKLDNN_ARG_DIFF_DST;
+ auto o_arg = pd()->is_fwd() ? MKLDNN_ARG_DST : MKLDNN_ARG_DIFF_SRC;
+ auto input = CTX_IN_MEM(const data_t *, i_arg);
+ auto output = CTX_OUT_MEM(data_t *, o_arg);
+
+ const int axis = pd()->axis();
+ const int axis_size = pd()->axis_size();
+
+ const int MB = pd()->MB();
+ const int C = pd()->C();
+ int H = 1, W = 1, D = 1, HW = 1, SP = 1;
+ const bool has_spatial = utils::one_of(data_d.ndims(), 3, 4 ,5);
+ if (has_spatial)
+ {
+ D = pd()->D();
+ H = pd()->H();
+ W = pd()->W();
+ HW = H * W;
+ SP = D * HW;
+ }
+ const size_t stride_mb = data_d.blocking_desc().strides[0];
+ constexpr int blksize = one_of(tag, nChw16c, nCdhw16c) ? 16 : 8;
+
+ if (axis == 1 && one_of(tag, nChw16c, nChw8c, nCdhw16c, nCdhw16c)) {
+#if MKLDNN_THR == MKLDNN_THR_OMP
+# pragma omp parallel for collapse(3) schedule(static)
+ for (int mb = 0; mb < MB; ++mb)
+ for (int cb = 0; cb < C; cb += blksize)
+ for (int sp = 0; sp < SP; ++sp) {
+ const size_t off = mb * stride_mb + sp * blksize;
+ const size_t output_off = off + cb * SP;
+ PRAGMA_OMP_SIMD()
+ for (int cc = 0; cc < nstl::min(blksize, C - cb); ++cc)
+ {
+ int input_c = rev_transposed_[cb + cc];
+ const size_t input_off = off + input_c / blksize * SP * blksize
+ + input_c % blksize;
+ output[output_off + cc] = input[input_off];
+ }
+ }
+#else
+ parallel_nd(MB, utils::div_up(C, blksize), SP, [&](int mb, int c,
+ int sp) {
+ const size_t off = mb * stride_mb + sp * blksize;
+ const int cb = c * blksize;
+ const size_t output_off = off + cb * SP;
+ for (int cc = 0; cc < nstl::min(blksize, C - cb); ++cc)
+ {
+ int input_c = rev_transposed_[cb + cc];
+ const size_t input_off = off + input_c / blksize * SP * blksize
+ + input_c % blksize;
+ output[output_off + cc] = input[input_off];
+ }
+ });
+#endif
+ } else if (axis == 1 && one_of(tag, nhwc, ndhwc)) {
+ parallel_nd(MB, SP, [&](int mb, int sp) {
+ const size_t off = mb * stride_mb + sp * C;
+ PRAGMA_OMP_SIMD()
+ for (int c = 0; c < C; ++c)
+ output[off + c] = input[off + rev_transposed_[c]];
+ });
+ } else if (axis == 1 && one_of(tag, nchw, ncdhw)) {
+ parallel_nd(MB, C, [&](int mb, int c) {
+ const size_t output_off = mb * stride_mb + c * SP;
+ const size_t input_off = mb * stride_mb + rev_transposed_[c] * SP;
+ PRAGMA_OMP_SIMD()
+ for (int sp = 0; sp < SP; ++sp) {
+ output[output_off + sp] = input[input_off + sp];
+ }
+ });
+ } else {
+ auto dims = pd()->desc()->data_desc.dims;
+ auto ndims = pd()->desc()->data_desc.ndims;
+ const size_t outer_size = utils::array_product(dims, axis);
+ const size_t inner_size = utils::array_product(dims + axis + 1,
+ ndims - axis - 1);
+ const size_t dim = axis_size * inner_size;
+
+ parallel_nd(outer_size, axis_size, inner_size, [&](size_t ou, int a,
+ size_t in)
+ {
+ const size_t off = ou * dim + in;
+ auto &o = output[data_d.off_l(off + a * inner_size)];
+ o = input[data_d.off_l(off + rev_transposed_[a] * inner_size)];
+ });
+ }
+}
+
+template void ref_shuffle_t<4>::execute_<nCdhw16c>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<4>::execute_<nChw16c>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<4>::execute_<nCdhw8c>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<4>::execute_<nChw8c>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<4>::execute_<ncdhw>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<4>::execute_<nchw>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<4>::execute_<ndhwc>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<4>::execute_<nhwc>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<4>::execute_<any>(const exec_ctx_t &ctx) const;
+
+template void ref_shuffle_t<1>::execute_<nCdhw16c>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<1>::execute_<nChw16c>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<1>::execute_<nCdhw8c>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<1>::execute_<nChw8c>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<1>::execute_<ncdhw>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<1>::execute_<nchw>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<1>::execute_<ndhwc>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<1>::execute_<nhwc>(const exec_ctx_t &ctx) const;
+template void ref_shuffle_t<1>::execute_<any>(const exec_ctx_t &ctx) const;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_shuffle.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_shuffle.hpp
new file mode 100644
index 0000000000..5e09a1a69b
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_shuffle.hpp
@@ -0,0 +1,111 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REF_SHUFFLE_HPP
+#define CPU_REF_SHUFFLE_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_shuffle_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template<int data_type_size>
+struct ref_shuffle_t : public cpu_primitive_t {
+ using shuffle_class = ref_shuffle_t<data_type_size>;
+
+ struct pd_t: public cpu_shuffle_pd_t {
+ using cpu_shuffle_pd_t::cpu_shuffle_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", shuffle_class);
+
+ status_t init() {
+ using namespace format_tag;
+
+ bool ok = true
+ && data_type_size
+ == types::data_type_size(data_md()->data_type);
+ if (!ok) return status::unimplemented;
+
+ if (ndims() == 5) {
+ dat_tag_ = memory_desc_matches_one_of_tag(
+ *data_md(), nCdhw16c, nCdhw8c, ncdhw, ndhwc);
+ } else if (ndims() == 4) {
+ dat_tag_ = memory_desc_matches_one_of_tag(
+ *data_md(), nChw16c, nChw8c, nchw, nhwc);
+ } else
+ dat_tag_ = any;
+
+ return status::success;
+ }
+
+ format_tag_t dat_tag_;
+ };
+
+ ref_shuffle_t(const pd_t *apd): cpu_primitive_t(apd) {
+ const int axis_size = pd()->axis_size();
+ const int group_size = pd()->group_size();
+ const int transpose_row = pd()->is_fwd() ? group_size
+ : axis_size / group_size;
+ const int transpose_col = pd()->is_fwd() ? axis_size / group_size
+ : group_size;
+ rev_transposed_ = (int *)malloc(axis_size * sizeof(int), 64);
+ parallel_nd(transpose_col, transpose_row, [&](int i, int j) {
+ rev_transposed_[j * transpose_col + i] = i * transpose_row + j;
+ });
+ }
+
+ ~ref_shuffle_t() { free(rev_transposed_); }
+
+ typedef typename typesize_traits<data_type_size>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ using namespace format_tag;
+ switch (pd()->dat_tag_) {
+ case nCdhw16c: execute_<nCdhw16c>(ctx); break;
+ case nChw16c: execute_<nChw16c>(ctx); break;
+ case nCdhw8c: execute_<nCdhw8c>(ctx); break;
+ case nChw8c: execute_<nChw8c>(ctx); break;
+ case ncdhw: execute_<ncdhw>(ctx); break;
+ case nchw: execute_<nchw>(ctx); break;
+ case ndhwc: execute_<ndhwc>(ctx); break;
+ case nhwc: execute_<nhwc>(ctx); break;
+ default: execute_<any>(ctx); break;
+ }
+ return status::success;
+ }
+
+private:
+ template<format_tag_t tag>
+ void execute_(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ int *rev_transposed_;
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_softmax.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_softmax.cpp
new file mode 100644
index 0000000000..36d5237f56
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_softmax.cpp
@@ -0,0 +1,264 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include <assert.h>
+#include <float.h>
+#include <math.h>
+
+#include "c_types_map.hpp"
+#include "mkldnn_thread.hpp"
+#include "type_helpers.hpp"
+
+#include "ref_softmax.hpp"
+#include "gemm/os_blas.hpp"
+
+#ifdef USE_MKL
+#include "mkl_vml_functions.h"
+#endif
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t data_type>
+void ref_softmax_fwd_t<data_type>::execute_forward_dense(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ parallel_nd(outer_size_, [&](int ou) {
+ const data_t *src_data = src + ou * channels_;
+ data_t *dst_data = dst + ou * channels_;
+ data_t scalar = 0;
+
+ _max(channels_, src_data, &scalar);
+ _sub(channels_, scalar, src_data, dst_data);
+ _exp(channels_, dst_data, dst_data);
+ _sum(channels_, dst_data, &scalar);
+ _scal(channels_, data_t(1)/scalar, dst_data);
+ });
+}
+
+template <impl::data_type_t data_type>
+void ref_softmax_fwd_t<data_type>::execute_forward_generic(
+ const exec_ctx_t &ctx) const {
+ auto src = CTX_IN_MEM(const data_t *, MKLDNN_ARG_SRC);
+ auto dst = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ data_t space_max_val = 0, space_denom_val = 0;
+ data_t *space_max = &space_max_val, *space_denom = &space_denom_val;
+ if (inner_size_ > 1) {
+ using namespace memory_tracking::names;
+ space_max = scratchpad(ctx).template get<data_t>(key_softmax_reduction);
+ space_denom = space_max + inner_size_;
+ }
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+ const size_t dim = channels_ * inner_size_;
+
+ for (int ou = 0; ou < outer_size_; ou++) {
+ utils::array_set(space_max, -FLT_MAX, inner_size_);
+ utils::array_set(space_denom, 0, inner_size_);
+
+ for (int c = 0; c < channels_; c++) {
+ for(int in = 0; in < inner_size_; in++) {
+ size_t off = data_d.off_l(ou * dim + c * inner_size_ + in);
+ space_max[in] = nstl::max(space_max[in], src[off]);
+ }
+ }
+
+ for (int c = 0; c < channels_; c++) {
+ for(int in = 0; in < inner_size_; in++) {
+ size_t off = data_d.off_l(ou * dim + c * inner_size_ + in);
+ space_denom[in] += dst[off] = exp(src[off] - space_max[in]);
+ }
+ }
+
+ for (int c = 0; c < channels_; c++) {
+ for (int in = 0; in < inner_size_; in++) {
+ size_t off = data_d.off_l(ou * dim + c * inner_size_ + in);
+ dst[off] /= space_denom[in];
+ }
+ }
+ }
+}
+
+template <impl::data_type_t data_type>
+void ref_softmax_fwd_t<data_type>::_max(int n, const data_t *x,
+ data_t *max_data) const {
+// Intel(R) C++ Compiler generates the maxps + shuffle pattern
+// for the max search which works faster
+#if !defined(__INTEL_COMPILER)
+ // The code below makes a compiler to generate maxps instruction
+ // rather than maxss, which is generated for the 'else' code path
+ auto max_wrapper = [](data_t a, data_t b) { return nstl::max(a, b); };
+ auto min_wrapper = [](int a, int b) { return nstl::min(a, b); };
+
+ constexpr int unroll_factor = 32;
+ data_t max_values[unroll_factor];
+
+ if (n < unroll_factor) {
+ data_t max_val = x[0];
+ for (int i = 1; i < n; i++) {
+ max_val = max_wrapper(max_val, x[i]);
+ }
+ max_data[0] = max_val;
+ return;
+ }
+ for (int i = 0; i < unroll_factor; i++) {
+ max_values[i] = x[i];
+ }
+ for (int i = unroll_factor; i < n; i += unroll_factor) {
+ int offset = min_wrapper(i, n - unroll_factor);
+ for (int j = 0; j < unroll_factor; j++) {
+ max_values[j] = max_wrapper(max_values[j], x[offset + j]);
+ }
+ }
+ data_t max_val = max_values[0];
+ for (int i = 1; i < unroll_factor; i++) {
+ max_val = max_wrapper(max_val, max_values[i]);
+ }
+ max_data[0] = max_val;
+#else
+ max_data[0] = x[0];
+ for (int c = 1; c < n; ++c)
+ max_data[0] = nstl::max(max_data[0], x[c]);
+#endif
+}
+
+template <impl::data_type_t data_type>
+void ref_softmax_fwd_t<data_type>::_sub(int n, data_t alpha, const data_t *x,
+ data_t *y) const {
+ constexpr int unroll_factor = 32;
+ int tail = n % unroll_factor;
+ for (int i = 0; i < n - tail; i += unroll_factor) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < unroll_factor; j++) {
+ y[i + j] = x[i + j] - alpha;
+ }
+ }
+ PRAGMA_OMP_SIMD()
+ for (int i = n - tail; i < n; i++) {
+ y[i] = x[i] - alpha;
+ }
+}
+
+template <impl::data_type_t data_type>
+void ref_softmax_fwd_t<data_type>::_exp(int n, const data_t *a,
+ data_t *r) const {
+#ifdef USE_MKL
+ if (data_type == data_type::f32) {
+ vsExp(n, a, r);
+ return;
+ }
+#endif
+ parallel_nd(n, [&](int c) { r[c] = expf(a[c]); });
+}
+
+template <impl::data_type_t data_type>
+void ref_softmax_fwd_t<data_type>::_sum(int n, const data_t *x,
+ data_t *sum_data) const {
+#ifdef USE_CBLAS
+ // Here we are summing x's eg. e^z , which are positives
+ // so we can use BLAS ASUM
+ if (data_type == data_type::f32) {
+ sum_data[0] = cblas_sasum(n, x, 1);
+ return;
+ }
+#endif
+ data_t tsum = static_cast<data_t>(0);
+ PRAGMA_OMP_SIMD(reduction(+ : tsum))
+ for (int c = 0; c < n; ++c)
+ tsum += x[c];
+ sum_data[0] = tsum;
+}
+
+template <impl::data_type_t data_type>
+void ref_softmax_fwd_t<data_type>::_scal(int n, data_t alpha, data_t *x) const {
+#ifdef USE_CBLAS
+ if (data_type == data_type::f32) {
+ cblas_sscal(n, alpha, x, 1);
+ return;
+ }
+#endif
+ parallel_nd(n, [&](int c) { x[c] *= alpha; });
+}
+
+template struct ref_softmax_fwd_t<data_type::f32>;
+
+
+// NC/NCHW softmax for along final axe (1 for NC, 3 for NCHW)
+template <impl::data_type_t data_type>
+void ref_softmax_bwd_t<data_type>::execute_backward_dense(
+ const exec_ctx_t &ctx) const {
+ auto dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DST);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ parallel_nd(outer_size_, [&](int ou) {
+ data_t sbr = 0;
+ size_t off = channels_*ou;
+ for (int c = 0; c < channels_; c++) {
+ size_t loff = off + c;
+ data_t ldata = dst[loff];
+ sbr += diff_dst[loff]*ldata;
+ diff_src[loff] = ldata;
+ }
+
+ for(int c=0; c < channels_ ; ++c) {
+ size_t loff = off + c;
+ diff_src[loff] *= (diff_dst[loff] - sbr);
+ }
+ });
+}
+
+template <impl::data_type_t data_type>
+void ref_softmax_bwd_t<data_type>::execute_backward_generic(
+ const exec_ctx_t &ctx) const {
+ auto dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DST);
+ auto diff_dst = CTX_IN_MEM(const data_t *, MKLDNN_ARG_DIFF_DST);
+ auto diff_src = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DIFF_SRC);
+
+ const memory_desc_wrapper diff_d(pd()->diff_src_md());
+ const memory_desc_wrapper data_d(pd()->dst_md());
+
+ const size_t dim = channels_ * inner_size_;
+
+ parallel_nd(outer_size_, [&](int ou) {
+ for (int in = 0; in < inner_size_; in++) {
+ data_t sbr = 0;
+ for (int c = 0; c < channels_; c++) {
+ size_t off_diff = diff_d.off_l(ou * dim + c * inner_size_ + in);
+ size_t off_data = diff_d.off_l(ou * dim + c * inner_size_ + in);
+ sbr += diff_dst[off_diff] * dst[off_data];
+ }
+
+ for(int c=0; c < channels_ ; ++c) {
+ size_t off_diff = diff_d.off_l(ou * dim + c * inner_size_ + in);
+ size_t off_data = data_d.off_l(ou * dim + c * inner_size_ + in);
+ diff_src[off_diff] = dst[off_data] * (diff_dst[off_diff] - sbr);
+ }
+ }
+ });
+}
+
+template struct ref_softmax_bwd_t<data_type::f32>;
+
+}
+}
+}
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_softmax.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_softmax.hpp
new file mode 100644
index 0000000000..5cb74d8007
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_softmax.hpp
@@ -0,0 +1,186 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REF_SOFTMAX_HPP
+#define CPU_REF_SOFTMAX_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "cpu_softmax_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <impl::data_type_t data_type>
+struct ref_softmax_fwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_softmax_fwd_pd_t {
+ using cpu_softmax_fwd_pd_t::cpu_softmax_fwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_softmax_fwd_t);
+
+ status_t init() {
+ bool ok = true
+ && is_fwd()
+ && src_md()->data_type == data_type
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ init_scratchpad();
+
+ return status::success;
+ }
+
+ private:
+ void init_scratchpad() {
+ const int inner_size = utils::array_product(
+ desc()->data_desc.dims + desc()->softmax_axis + 1,
+ desc()->data_desc.ndims - desc()->softmax_axis - 1);
+
+ if (inner_size > 1) {
+ auto scratchpad = scratchpad_registry().registrar();
+ scratchpad.book(memory_tracking::names::key_softmax_reduction,
+ sizeof(data_t) * 2 * inner_size);
+ }
+ }
+ };
+
+ ref_softmax_fwd_t(const pd_t *apd): cpu_primitive_t(apd)
+ {
+ auto ndims = pd()->desc()->data_desc.ndims;
+ auto dims = pd()->desc()->data_desc.dims;
+ auto axis = pd()->desc()->softmax_axis;
+
+ outer_size_ = utils::array_product(dims, axis);
+ channels_ = dims[axis];
+ inner_size_ = utils::array_product(dims + axis + 1, ndims - axis - 1);
+
+ const memory_desc_wrapper data_d(pd()->src_md());
+
+ bool no_axis_blocking = true;
+ for (int iblk = 0; iblk < data_d.blocking_desc().inner_nblks; ++iblk)
+ if (data_d.blocking_desc().inner_idxs[iblk] == axis)
+ no_axis_blocking = false;
+
+ use_dense_ = inner_size_ == 1 && data_d.is_dense()
+ && no_axis_blocking
+ && data_d.blocking_desc().strides[axis] == 1;
+ }
+
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ if (use_dense_)
+ execute_forward_dense(ctx);
+ else
+ execute_forward_generic(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_forward_dense(const exec_ctx_t &ctx) const;
+ void execute_forward_generic(const exec_ctx_t &ctx) const;
+
+ void _max(int n, const data_t *x, data_t *max_data) const;
+ void _sub(int n, data_t alpha, const data_t *x, data_t *y) const;
+ void _exp(int n, const data_t *a, data_t *r) const;
+ void _sum(int n, const data_t *x, data_t *sum_data) const;
+ void _scal(int n, data_t alpha, data_t *x) const;
+
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ bool use_dense_;
+ int outer_size_, channels_, inner_size_;
+};
+
+template <impl::data_type_t data_type>
+struct ref_softmax_bwd_t: public cpu_primitive_t {
+ struct pd_t: public cpu_softmax_bwd_pd_t {
+ using cpu_softmax_bwd_pd_t::cpu_softmax_bwd_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", ref_softmax_bwd_t);
+
+ status_t init() {
+ bool ok = true
+ && !is_fwd()
+ && utils::everyone_is(data_type,
+ dst_md()->data_type,
+ diff_src_md()->data_type)
+ && attr()->has_default_values();
+ if (!ok) return status::unimplemented;
+
+ return status::success;
+ }
+ };
+
+ ref_softmax_bwd_t(const pd_t *apd): cpu_primitive_t(apd) {
+ auto dims = pd()->desc()->diff_desc.dims;
+ auto axis = pd()->desc()->softmax_axis;
+ auto ndims = pd()->desc()->diff_desc.ndims;
+
+ outer_size_ = utils::array_product(dims, axis);
+ channels_ = dims[axis];
+ inner_size_ = utils::array_product(dims + axis + 1, ndims - axis - 1);
+
+ const memory_desc_wrapper data_d(pd()->dst_md());
+ const memory_desc_wrapper diff_d(pd()->diff_dst_md());
+
+ bool no_axis_blocking = true;
+ for (int iblk = 0; iblk < diff_d.blocking_desc().inner_nblks; ++iblk)
+ if (diff_d.blocking_desc().inner_idxs[iblk] == axis)
+ no_axis_blocking = false;
+
+ use_dense_ = true
+ && inner_size_ == 1
+ && diff_d == data_d
+ && diff_d.is_dense()
+ && no_axis_blocking
+ && diff_d.blocking_desc().strides[axis] == 1;
+ }
+
+ typedef typename prec_traits<data_type>::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ if (use_dense_)
+ execute_backward_dense(ctx);
+ else
+ execute_backward_generic(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_backward_dense(const exec_ctx_t &ctx) const;
+ void execute_backward_generic(const exec_ctx_t &ctx) const;
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ bool use_dense_;
+ int outer_size_, channels_, inner_size_;
+};
+
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/ref_sum.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/ref_sum.hpp
new file mode 100644
index 0000000000..3b2a75d99b
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/ref_sum.hpp
@@ -0,0 +1,101 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef REF_SUM_HPP
+#define REF_SUM_HPP
+
+#include "reorder_pd.hpp"
+
+#include "cpu_sum_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct ref_sum_t: public cpu_primitive_t {
+ struct pd_t: public cpu_sum_pd_t {
+ using cpu_sum_pd_t::cpu_sum_pd_t;
+
+ pd_t(const pd_t &rhs): cpu_sum_pd_t(rhs) {
+ for (size_t i = 0; i < rhs.reorder_pds_.size(); ++i)
+ reorder_pds_.push_back(
+ (const reorder_pd_t *)rhs.reorder_pds_[i]->clone());
+ }
+
+ ~pd_t() { for (auto &rpd: reorder_pds_) delete rpd; }
+
+ DECLARE_SUM_PD_T("ref:any", ref_sum_t);
+
+ status_t init() {
+ bool ok = cpu_sum_pd_t::init() == status::success;
+ if (!ok) return status::unimplemented;
+
+ for (int i = 0; i < n_; ++i) {
+ auto r_impls = engine_->get_reorder_implementation_list();
+ for (auto r = r_impls; *r; ++r) {
+ primitive_attr_t attr;
+ attr.output_scales_.set(scales_[i]);
+ if (i != 0) attr.post_ops_.append_sum(1.0);
+
+ reorder_pd_t *r_pd;
+ if ((*r)(&r_pd, engine_, &attr, engine_, src_md(i),
+ engine_, dst_md()) == status::success) {
+ r_pd->init_info();
+ reorder_pds_.push_back(r_pd);
+ break;
+ }
+ }
+ }
+
+ ok = reorder_pds_.size() == (size_t)n_;
+ return ok ? status::success : status::unimplemented;
+ }
+
+ nstl::vector<const reorder_pd_t *> reorder_pds_;
+ };
+
+ ref_sum_t(const pd_t *apd): cpu_primitive_t(apd) {
+ const int n = pd()->n_inputs();
+ reorders_.resize(n);
+ for (int i = 0; i < n; ++i)
+ pd()->reorder_pds_[i]->create_primitive(&reorders_[i]);
+ }
+
+ ~ref_sum_t() { for (auto &r: reorders_) delete r; }
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ const auto n = pd()->n_inputs();
+ for (int i = 0; i < n; ++i) {
+ exec_args_t r_args;
+ r_args[MKLDNN_ARG_SRC] = ctx.args().at(MKLDNN_ARG_MULTIPLE_SRC + i);
+ r_args[MKLDNN_ARG_DST] = ctx.args().at(MKLDNN_ARG_DST);
+ exec_ctx_t r_ctx(ctx.stream(), std::move(r_args));
+ reorders_[i]->execute(r_ctx);
+ }
+ return status::success;
+ }
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ nstl::vector<primitive_t *> reorders_;
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_common.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_common.cpp
new file mode 100644
index 0000000000..537084db91
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_common.cpp
@@ -0,0 +1,90 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/*
+ * Common for RNN and LSTM cell execution
+ */
+#include "ref_rnn.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+using namespace rnn_utils;
+
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+rnn_cell_execution_sig(
+ (_ref_rnn_common_t<aprop, src_type, weights_type>::cell_execution)) {
+ if (!rnn.merge_gemm_layer) {
+ (this->*gemm_layer_func)('N', 'N', rnn.n_gates * rnn.dic, rnn.mb,
+ rnn.slc, 1.0, w_layer_[0], rnn.weights_layer_ld,
+ states_t_lm1_, rnn.states_ws_ld, 0.0, ws_gates_,
+ rnn.gates_ws_ld);
+ }
+ (this->*gemm_iter_func)('N', 'N', rnn.n_gates * rnn.dic, rnn.mb, rnn.sic,
+ 1.0, w_iter_[0], rnn.weights_iter_ld, states_tm1_l_,
+ rnn.states_ws_ld, 1.0, ws_gates_, rnn.gates_ws_ld);
+
+ if (rnn_postgemm_ != nullptr)
+ rnn_postgemm_->execute<src_data_t, acc_data_t>(rnn, ws_gates_, states_t_l_, c_states_t_l_,
+ states_tm1_l_, c_states_tm1_l_, diff_states_t_l_,
+ diff_states_t_lp1_, diff_states_tp1_l_, bias_[0], ws_grid_,
+ ws_cell_);
+ else
+ (this->*elemwise_func)(rnn, ws_gates_, states_t_l_, c_states_t_l_,
+ states_tm1_l_, c_states_tm1_l_, diff_states_t_l_,
+ diff_states_t_lp1_, diff_states_tp1_l_, bias_[0], ws_grid_,
+ ws_cell_);
+}
+template rnn_cell_execution_sig(ref_rnn_fwd_f32_t::cell_execution);
+template rnn_cell_execution_sig(ref_rnn_fwd_u8s8_t::cell_execution);
+
+template <>
+rnn_cell_execution_sig(ref_rnn_bwd_f32_t::cell_execution) {
+ ws_diff_states_aoc_t diff_states_t_l(rnn, diff_states_t_l_);
+ (this->*elemwise_func)(rnn, ws_gates_, states_t_l_, c_states_t_l_,
+ states_tm1_l_, c_states_tm1_l_, diff_states_t_l_,
+ diff_states_t_lp1_, diff_states_tp1_l_, bias_[0], ws_grid_,
+ ws_cell_);
+
+ /// bwd by data on the cell
+ (this->*gemm_iter_func)('N', 'N', rnn.sic, rnn.mb, rnn.n_gates * rnn.dic,
+ 1.0, w_iter_[0], rnn.weights_iter_ld, ws_gates_, rnn.gates_ws_ld,
+ 0.0, diff_states_t_l_, rnn.states_ws_ld);
+
+ if (!rnn.merge_gemm_layer) {
+ (this->*gemm_layer_func)('N', 'N', rnn.slc, rnn.mb,
+ rnn.n_gates * rnn.dic, 1.0, w_layer_[0],
+ rnn.weights_layer_ld, ws_gates_, rnn.gates_ws_ld, 0.0,
+ &diff_states_t_l(rnn.n_states, 0, 0), rnn.states_ws_ld);
+
+ /// bwd by weights on the cell
+ gemm('N', 'T', rnn.n_gates * rnn.dic, rnn.slc, rnn.mb, 1.0, ws_gates_,
+ rnn.gates_ws_ld, states_t_lm1_, rnn.states_ws_ld, 1.0,
+ diff_w_layer_, rnn.diff_weights_layer_ld);
+ }
+
+ if (!rnn.merge_gemm_iter)
+ gemm('N', 'T', rnn.n_gates * rnn.dic, rnn.sic, rnn.mb, 1.0, ws_gates_,
+ rnn.gates_ws_ld, states_tm1_l_, rnn.states_ws_ld, 1.0,
+ diff_w_iter_, rnn.diff_weights_iter_ld);
+
+ /// bwd by bias we just accumulate diffs from the gates
+ gates_reduction(rnn, ws_gates_, diff_bias_);
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_gru.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_gru.cpp
new file mode 100644
index 0000000000..e1a61d4c62
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_gru.cpp
@@ -0,0 +1,180 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/*
+ * Cell execution GRU
+ */
+
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+
+#include "ref_rnn.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::math;
+using namespace rnn_utils;
+
+#define AOC array_offset_calculator
+template <>
+rnn_cell_execution_sig(ref_rnn_fwd_f32_t::cell_execution_gru) {
+ ws_gates_aoc_t ws_gates(rnn, ws_gates_);
+ bias_aoc_t bias(rnn, bias_[0]);
+ ws_states_aoc_t states_t_l(rnn, states_t_l_);
+ ws_states_aoc_t states_tm1_l(rnn, states_tm1_l_);
+
+ // 1. gemm Wx[0-2],x
+ if (!rnn.merge_gemm_layer) {
+ (this->*gemm_layer_func)('N', 'N', rnn.n_gates * rnn.dic, rnn.mb,
+ rnn.slc, 1.0, w_layer_[0], rnn.weights_layer_ld,
+ states_t_lm1_, rnn.states_ws_ld, 0.0, ws_gates_,
+ rnn.gates_ws_ld);
+ }
+
+ // 2. gemm Wh[0-1],h
+ (this->*gemm_iter_func)('N', 'N', (rnn.n_gates - 1) * rnn.dic, rnn.mb,
+ rnn.sic, 1.0, w_iter_[0], rnn.weights_iter_ld, states_tm1_l_,
+ rnn.states_ws_ld, 1.0, ws_gates_, rnn.gates_ws_ld);
+
+ // 3. activation zt and rt + elemwise multiplication rt,ht-1
+ parallel_nd(rnn.mb, [&](int i) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < rnn.dic; j++) {
+ ws_gates(i, 0, j) = logistic_fwd(ws_gates(i, 0, j) + bias(0, j));
+ ws_gates(i, 1, j) = logistic_fwd(ws_gates(i, 1, j) + bias(1, j));
+ states_t_l(i, j) = states_tm1_l(i, j) * ws_gates(i, 1, j);
+ }
+ });
+
+ // 4. gemm Wh[2],h~t
+ (this->*gemm_iter_func)('N', 'N', rnn.dic, rnn.mb, rnn.sic, 1.0, w_iter_[1],
+ rnn.weights_iter_ld, states_t_l_, rnn.states_ws_ld, 1.0,
+ &(ws_gates(0, 2, 0)), rnn.gates_ws_ld);
+
+ // 5. activation h~t + calculate ht
+ parallel_nd(rnn.mb, [&](int i) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < rnn.dic; j++) {
+ ws_gates(i, 2, j) = tanh_fwd(ws_gates(i, 2, j) + bias(2, j));
+ states_t_l(i, j) = states_tm1_l(i, j) * ws_gates(i, 0, j)
+ + (1.0f - ws_gates(i, 0, j)) * ws_gates(i, 2, j);
+ }
+ });
+}
+
+template <>
+rnn_cell_execution_sig(ref_rnn_fwd_u8s8_t::cell_execution_gru) {
+ assert(!"GRU int8 is not supported");
+}
+
+template <>
+rnn_cell_execution_sig(ref_rnn_bwd_f32_t::cell_execution_gru) {
+ ws_gates_aoc_t ws_gates(rnn, ws_gates_);
+ ws_states_aoc_t states_t_l(rnn, states_t_l_);
+ ws_states_aoc_t states_tm1_l(rnn, states_tm1_l_);
+ ws_diff_w_iter_aoc_t diff_w_iter(rnn, diff_w_iter_);
+ ws_diff_states_aoc_t diff_states_t_l(rnn, diff_states_t_l_);
+ ws_diff_states_aoc_t diff_states_tp1_l(rnn, diff_states_tp1_l_);
+ ws_diff_states_aoc_t diff_states_t_lp1(rnn, diff_states_t_lp1_);
+
+ // use state memory for intermediate computations
+ // TODO: use cell ws for that
+ float *dhG1_ = &(diff_states_t_l(rnn.n_states, 0, 0));
+ float *hG1_ = dhG1_;
+ AOC<float, 2> dhG1(dhG1_, rnn.states_nld, rnn.states_ws_ld);
+ AOC<float, 2> hG1(hG1_, rnn.states_nld, rnn.states_ws_ld);
+
+ // 1. calculate dG2, dG1, and part of dht-1
+ // dG2^ = dh * (1 - G0) * (1 - G2^2)
+ // dG0^ = dh * (ht-1 - G2) * u * (1 - G0)
+ // dht-1 (part) = dh * G0
+ parallel_nd(rnn.mb, [&](int i) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < rnn.dic; j++) {
+ float h = states_tm1_l(i, j);
+ float dHt = diff_states_tp1_l(0, i, j)
+ + diff_states_t_lp1(rnn.n_states, i, j);
+ float dG2 = (1.0f - ws_gates(i, 0, j)) * dHt
+ * one_m_square(ws_gates(i, 2, j));
+ float dG0 = (h - ws_gates(i, 2, j)) * dHt
+ * x_m_square(ws_gates(i, 0, j));
+
+ diff_states_t_l(0, i, j) = dHt * ws_gates(i, 0, j);
+ ws_gates(i, 0, j) = dG0;
+ ws_gates(i, 2, j) = dG2;
+ }
+ });
+
+ // 2. calculate intermediate d(hG1)
+ // d(hG1) = dG2 * W2h^t
+ (this->*gemm_iter_func)('N', 'N', rnn.sic, rnn.mb, rnn.dic, 1.0, w_iter_[1],
+ rnn.weights_iter_ld, &(ws_gates(0, 2, 0)), rnn.gates_ws_ld, 0.0,
+ dhG1_, rnn.states_ws_ld);
+
+ // 3. calculate dG1^ and part of dht-1
+ // dG1^ = d(hG1) * h * G1 * (1 - G1)
+ // dht-1 (part) += d(hG1) * G1
+ // h * G1 (required for dWh)
+ parallel_nd(rnn.mb, [&](int i) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < rnn.dic; j++) {
+ float h = states_tm1_l(i, j);
+ float G1 = ws_gates(i, 1, j);
+ diff_states_t_l(0, i, j) += dhG1(i, j) * G1;
+ ws_gates(i, 1, j) = dhG1(i, j) * h * x_m_square(G1);
+ hG1(i, j) = G1 * h;
+ }
+ });
+
+ // 4. calculate diff weights
+ // dWh1 += dG1 * h, dWh2 += dG2 * h, dWh3 += dG3 * (G1(*)h)
+ gemm('N', 'T', (rnn.n_gates - 1) * rnn.dic, rnn.sic, rnn.mb, 1.0, ws_gates_,
+ rnn.gates_ws_ld, states_tm1_l_, rnn.states_ws_ld, 1.0, diff_w_iter_,
+ rnn.diff_weights_iter_ld);
+ gemm('N', 'T', rnn.dic, rnn.sic, rnn.mb, 1.0, &(ws_gates(0, 2, 0)),
+ rnn.gates_ws_ld, hG1_, rnn.states_ws_ld, 1.0,
+ &(diff_w_iter(0, 2, 0)), rnn.diff_weights_iter_ld);
+
+ // 5. calculate diff states
+ // dht-1 += dG1 * W1h + dG0 * W0h
+ (this->*gemm_iter_func)('N', 'N', rnn.sic, rnn.mb,
+ (rnn.n_gates - 1) * rnn.dic, 1.0, w_iter_[0],
+ rnn.weights_iter_ld, ws_gates_, rnn.gates_ws_ld, 1.0,
+ diff_states_t_l_, rnn.states_ws_ld);
+
+ if (!rnn.merge_gemm_layer) {
+ // dWx += [dG0 dG1 dG2] * [x]
+ gemm('N', 'T', rnn.n_gates * rnn.dic, rnn.slc, rnn.mb, 1.0, ws_gates_,
+ rnn.gates_ws_ld, states_t_lm1_, rnn.states_ws_ld, 1.0,
+ diff_w_layer_, rnn.diff_weights_layer_ld);
+ // dx = dG2 * W2x + dG1 * W1x + dG0 * W0x
+ (this->*gemm_layer_func)('N', 'N', rnn.slc, rnn.mb,
+ rnn.n_gates * rnn.dic, 1.0, w_layer_[0],
+ rnn.weights_layer_ld, ws_gates_, rnn.gates_ws_ld, 0.0,
+ &(diff_states_t_l(rnn.n_states, 0, 0)), rnn.states_ws_ld);
+ }
+
+ // 6. calculate diff bias
+ gates_reduction(rnn, ws_gates_, diff_bias_);
+}
+#undef AOC
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_gru_lbr.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_gru_lbr.cpp
new file mode 100644
index 0000000000..8dea8c90a4
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_gru_lbr.cpp
@@ -0,0 +1,170 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/*
+ * Cell execution GRU with linear before reset
+ */
+
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+
+#include "ref_rnn.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::math;
+using namespace rnn_utils;
+#define AOC array_offset_calculator
+
+template <>
+rnn_elemwise_sig(ref_rnn_fwd_f32_t::gru_lbr_elemwise) {
+ ws_gates_aoc_t ws_gates(rnn, ws_gates_);
+ bias_aoc_t bias(rnn, bias_);
+ ws_states_aoc_t states_t_l(rnn, states_t_l_);
+ ws_states_aoc_t states_tm1_l(rnn, states_tm1_l_);
+ ws_gates_aoc_t ws_gemm_state(rnn, ws_cell_);
+ AOC<float, 2> ws_Wh_b(ws_grid_, rnn.mb, rnn.dic);
+
+ parallel_nd(rnn.mb, [&](int i) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < rnn.dic; j++) {
+ float Wh_b = ws_gemm_state(i, 2, j) + bias(3, j);
+ ws_gates(i, 0, j) = logistic_fwd(
+ ws_gates(i, 0, j) + ws_gemm_state(i, 0, j) + bias(0, j));
+ ws_gates(i, 1, j) = logistic_fwd(
+ ws_gates(i, 1, j) + ws_gemm_state(i, 1, j) + bias(1, j));
+ ws_gates(i, 2, j) = tanh_fwd(
+ ws_gates(i, 2, j) + ws_gates(i, 1, j) * Wh_b + bias(2, j));
+ states_t_l(i, j) = states_tm1_l(i, j) * ws_gates(i, 0, j)
+ + (1.0f - ws_gates(i, 0, j)) * ws_gates(i, 2, j);
+ if (rnn.is_training)
+ ws_Wh_b(i, j) = Wh_b;
+ }
+ });
+}
+
+template <>
+rnn_elemwise_sig(ref_rnn_fwd_u8s8_t::gru_lbr_elemwise) {
+ assert(!"GRU LBR int8 is not supported");
+}
+
+template <>
+rnn_cell_execution_sig(ref_rnn_fwd_f32_t::cell_execution_gru_lbr) {
+ if (!rnn.merge_gemm_layer) {
+ (this->*gemm_layer_func)('N', 'N', rnn.n_gates * rnn.dic, rnn.mb,
+ rnn.slc, 1.0, w_layer_[0], rnn.weights_layer_ld,
+ states_t_lm1_, rnn.states_ws_ld, 0.0, ws_gates_,
+ rnn.gates_ws_ld);
+ }
+ (this->*gemm_iter_func)('N', 'N', rnn.n_gates * rnn.dic, rnn.mb, rnn.sic,
+ 1.0, w_iter_[0], rnn.weights_iter_ld, states_tm1_l_,
+ rnn.states_ws_ld, 0.0, ws_cell_, rnn.gates_ws_ld);
+ (this->*elemwise_func)(rnn, ws_gates_, states_t_l_, c_states_t_l_,
+ states_tm1_l_, c_states_tm1_l_, diff_states_t_l_,
+ diff_states_t_lp1_, diff_states_tp1_l_, bias_[0], ws_grid_,
+ ws_cell_);
+}
+
+template <>
+rnn_cell_execution_sig(ref_rnn_fwd_u8s8_t::cell_execution_gru_lbr) {
+ assert(!"GRU LBR int8 is not supported");
+}
+
+template <>
+rnn_elemwise_sig(ref_rnn_bwd_f32_t::gru_lbr_elemwise) {
+ ws_gates_aoc_t ws_gates(rnn, ws_gates_);
+ ws_states_aoc_t states_tm1_l(rnn, states_tm1_l_);
+ ws_diff_states_aoc_t diff_states_t_l(rnn, diff_states_t_l_);
+ ws_diff_states_aoc_t diff_states_tp1_l(rnn, diff_states_tp1_l_);
+ ws_diff_states_aoc_t diff_states_t_lp1(rnn, diff_states_t_lp1_);
+ ws_gates_aoc_t ws_gates_r(rnn, ws_cell_);
+ AOC<float, 2> ws_Wh_b(ws_grid_, rnn.mb, rnn.dic);
+
+ // 1. calculate dG1 dG2 dG3
+ // dG0 = (dht - G2) * dht * (1 - G0) * G0
+ // dG1 = (W*h + b) * dG2 * (1 - G1) * G1
+ // dG2 = (1 - G0) * dht * (1 - G2*G2)
+ parallel_nd(rnn.mb, [&](int i) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < rnn.dic; j++) {
+ float h = states_tm1_l(i, j);
+ float dHt = diff_states_tp1_l(0, i, j)
+ + diff_states_t_lp1(rnn.n_states, i, j);
+ float dG0 = (h - ws_gates(i, 2, j)) * dHt
+ * x_m_square(ws_gates(i, 0, j));
+ float dG2 = (1.0f - ws_gates(i, 0, j))
+ * one_m_square(ws_gates(i, 2, j)) * dHt;
+ float dG1 = ws_Wh_b(i, j) * dG2 * x_m_square(ws_gates(i, 1, j));
+
+ diff_states_t_l(0, i, j) = dHt * ws_gates(i, 0, j);
+ ws_gates(i, 2, j) = dG2;
+ ws_gates_r(i, 2, j) = dG2 * ws_gates(i, 1, j);
+ ws_gates(i, 0, j) = ws_gates_r(i, 0, j) = dG0;
+ ws_gates(i, 1, j) = ws_gates_r(i, 1, j) = dG1;
+ }
+ });
+}
+
+template <>
+rnn_cell_execution_sig(ref_rnn_bwd_f32_t::cell_execution_gru_lbr) {
+ ws_gates_aoc_t ws_gates_r(rnn, ws_cell_);
+ ws_diff_states_aoc_t diff_states_t_l(rnn, diff_states_t_l_);
+
+ (this->*elemwise_func)(rnn, ws_gates_, states_t_l_, c_states_t_l_,
+ states_tm1_l_, c_states_tm1_l_, diff_states_t_l_,
+ diff_states_t_lp1_, diff_states_tp1_l_, bias_[0], ws_grid_,
+ ws_cell_);
+
+ if (!rnn.merge_gemm_layer) {
+ // dx = dG * Wx^t
+ (this->*gemm_layer_func)('N', 'N', rnn.slc, rnn.mb,
+ rnn.n_gates * rnn.dic, 1.0, w_layer_[0],
+ rnn.weights_layer_ld, ws_gates_, rnn.gates_ws_ld, 0.0,
+ &diff_states_t_l(rnn.n_states, 0, 0), rnn.states_ws_ld);
+ // dWx += dG^t * x
+ gemm('N', 'T', rnn.n_gates * rnn.dic, rnn.slc, rnn.mb, 1.0, ws_gates_,
+ rnn.gates_ws_ld, states_t_lm1_, rnn.states_ws_ld, 1.0,
+ diff_w_layer_, rnn.diff_weights_layer_ld);
+ }
+ // dh += dGr * Wh^t
+ (this->*gemm_iter_func)('N', 'N', rnn.sic, rnn.mb, rnn.n_gates * rnn.dic,
+ 1.0, w_iter_[0], rnn.weights_iter_ld, ws_cell_, rnn.gates_ws_ld,
+ 1.0, diff_states_t_l_, rnn.states_ws_ld);
+
+ // dWh += dGr^t * h
+ gemm('N', 'T', rnn.n_gates * rnn.dic, rnn.sic, rnn.mb, 1.0, ws_cell_,
+ rnn.gates_ws_ld, states_tm1_l_, rnn.states_ws_ld, 1.0, diff_w_iter_,
+ rnn.diff_weights_layer_ld);
+
+ // db1-3 += e * dG
+ // db4 += e * (r * dG2)
+ gates_reduction(rnn, ws_gates_, diff_bias_);
+
+ parallel_nd(rnn.dic, [&](int j) {
+ for (int i = 0; i < rnn.mb; i++) {
+ diff_bias_[3 * rnn.dic + j] += ws_gates_r(i, 2, j);
+ }
+ });
+}
+
+#undef AOC
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_lstm.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_lstm.cpp
new file mode 100644
index 0000000000..a15ba00d4c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_lstm.cpp
@@ -0,0 +1,143 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/*
+ * Cell execution LSTM
+ */
+
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+
+#include "../simple_q10n.hpp"
+#include "ref_rnn.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::math;
+using namespace rnn_utils;
+
+template <>
+rnn_elemwise_sig(ref_rnn_fwd_f32_t::lstm_elemwise) {
+ ws_gates_aoc_t ws_gates(rnn, ws_gates_);
+ bias_aoc_t bias(rnn, bias_);
+ ws_states_aoc_t states_t_l(rnn, states_t_l_);
+ ws_states_aoc_t c_states_t_l(rnn, c_states_t_l_);
+ ws_states_aoc_t c_states_tm1_l(rnn, c_states_tm1_l_);
+
+ parallel_nd(rnn.mb, [&](int i) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < rnn.dic; j++) {
+ ws_gates(i, 0, j) = logistic_fwd(ws_gates(i, 0, j) + bias(0, j));
+ ws_gates(i, 1, j) = logistic_fwd(ws_gates(i, 1, j) + bias(1, j));
+ ws_gates(i, 2, j) = tanh_fwd(ws_gates(i, 2, j) + bias(2, j));
+ ws_gates(i, 3, j) = logistic_fwd(ws_gates(i, 3, j) + bias(3, j));
+
+ float tmp = ws_gates(i, 1, j) * c_states_tm1_l(i, j)
+ + ws_gates(i, 0, j) * ws_gates(i, 2, j);
+ states_t_l(i, j) = ws_gates(i, 3, j) * tanh_fwd(tmp);
+ c_states_t_l(i, j) = tmp;
+ }
+ });
+}
+
+template <>
+rnn_elemwise_sig(ref_rnn_fwd_u8s8_t::lstm_elemwise) {
+ ws_gates_aoc_s32_t ws_gates_s32(rnn, ws_gates_);
+ bias_aoc_t bias(rnn, bias_);
+ ws_states_aoc_u8_t states_t_l(rnn, states_t_l_);
+ ws_states_aoc_t c_states_t_l(rnn, c_states_t_l_);
+ ws_states_aoc_t c_states_tm1_l(rnn, c_states_tm1_l_);
+
+ float *weights_scales = pd()->attr()->rnn_weights_qparams_.scales_;
+ float data_shift = pd()->attr()->rnn_data_qparams_.shift_;
+ float data_scale = pd()->attr()->rnn_data_qparams_.scale_;
+
+ auto q_d = [&](float f) {
+ float qf = f * data_scale + data_shift;
+ return qz_a1b0<float, src_data_t>()(qf);
+ };
+
+ auto deq_w = [&](acc_data_t s, int gate, int j) {
+ return pd()->attr()->rnn_weights_qparams_.mask_ == 0 ?
+ saturate<float>(s) * (1.f / (weights_scales[0] * data_scale)) :
+ saturate<float>(s) * (1.f / (weights_scales[gate * rnn.dic + j]
+ * data_scale));
+ };
+
+ parallel_nd(rnn.mb, [&](int i) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < rnn.dic; j++) {
+ float G0 = logistic_fwd<float>(
+ deq_w(ws_gates_s32(i, 0, j), 0, j) + bias(0, j));
+ float G1 = logistic_fwd<float>(
+ deq_w(ws_gates_s32(i, 1, j), 1, j) + bias(1, j));
+ float G2 = tanh_fwd<float>(
+ deq_w(ws_gates_s32(i, 2, j), 2, j) + bias(2, j));
+ float G3 = logistic_fwd<float>(
+ deq_w(ws_gates_s32(i, 3, j), 3, j) + bias(3, j));
+ float tmp = G1 * c_states_tm1_l(i, j) + G0 * G2;
+ states_t_l(i, j) = q_d(G3 * tanh_fwd(tmp));
+ c_states_t_l(i, j) = tmp;
+ }
+ });
+}
+
+template <>
+rnn_elemwise_sig(ref_rnn_bwd_f32_t::lstm_elemwise) {
+ ws_gates_aoc_t ws_gates(rnn, ws_gates_);
+ bias_aoc_t bias(rnn, bias_);
+ ws_states_aoc_t c_states_t_l(rnn, c_states_t_l_);
+ ws_states_aoc_t c_states_tm1_l(rnn, c_states_tm1_l_);
+ ws_diff_states_aoc_t diff_states_t_l(rnn, diff_states_t_l_);
+ ws_diff_states_aoc_t diff_states_tp1_l(rnn, diff_states_tp1_l_);
+ ws_diff_states_aoc_t diff_states_t_lp1(rnn, diff_states_t_lp1_);
+
+ parallel_nd(rnn.mb, [&](int i) {
+ PRAGMA_OMP_SIMD()
+ for (int j = 0; j < rnn.dic; j++) {
+ float Ct = c_states_t_l(i, j);
+ /// @todo save it in the workspace in fwd pass or recompute it to
+ /// save bw
+ float tanhCt = tanh_fwd(Ct);
+ // we have 2 incoming diffs on Ht
+ float dHt = diff_states_tp1_l(0, i, j)
+ + diff_states_t_lp1(rnn.n_states, i, j);
+ float dCt = diff_states_tp1_l(1, i, j)
+ + one_m_square(tanhCt) * ws_gates(i, 3, j) * dHt;
+
+ float dG1 = c_states_tm1_l(i, j) * dCt
+ * x_m_square(ws_gates(i, 1, j));
+ float dG0 = ws_gates(i, 2, j) * dCt * x_m_square(ws_gates(i, 0, j));
+ float dG3 = tanhCt * dHt * x_m_square(ws_gates(i, 3, j));
+ float dG2
+ = ws_gates(i, 0, j) * dCt * one_m_square(ws_gates(i, 2, j));
+
+ diff_states_t_l(1, i, j) = dCt * ws_gates(i, 1, j);
+
+ ws_gates(i, 0, j) = dG0;
+ ws_gates(i, 1, j) = dG1;
+ ws_gates(i, 2, j) = dG2;
+ ws_gates(i, 3, j) = dG3;
+ }
+ });
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_rnn.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_rnn.cpp
new file mode 100644
index 0000000000..4536e8dfad
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cell_rnn.cpp
@@ -0,0 +1,113 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/*
+ * Cell execution of Vanilla RNN
+ */
+
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+
+#include "ref_rnn.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::math;
+using namespace rnn_utils;
+
+template <>
+float activation<alg_kind::eltwise_relu, prop_kind::forward>(
+ float dd, float s, float alpha, float cliping) {
+ return relu_fwd<float>(s, alpha);
+}
+
+template <>
+float activation<alg_kind::eltwise_relu, prop_kind::backward>(
+ float dd, float s, float alpha, float cliping) {
+ return relu_bwd<float>(dd, s, alpha);
+}
+
+template <>
+float activation<alg_kind::eltwise_tanh, prop_kind::forward>(
+ float dd, float s, float alpha, float cliping) {
+ return tanh_fwd<float>(s);
+}
+
+template <>
+float activation<alg_kind::eltwise_tanh, prop_kind::backward>(
+ float dd, float s, float alpha, float cliping) {
+ return dd * one_m_square<float>(s);
+}
+
+template <>
+float activation<alg_kind::eltwise_logistic, prop_kind::forward>(
+ float dd, float s, float alpha, float cliping) {
+ return logistic_fwd<float>(s);
+}
+
+template <>
+float activation<alg_kind::eltwise_logistic, prop_kind::backward>(
+ float dd, float s, float alpha, float cliping) {
+ return dd * x_m_square<float>(s);
+}
+
+template <>
+rnn_elemwise_sig(ref_rnn_fwd_f32_t::rnn_elemwise) {
+ ws_gates_aoc_t ws_gates(rnn, ws_gates_);
+ bias_aoc_t bias(rnn, bias_);
+ ws_states_aoc_t states_t_l(rnn, states_t_l_);
+ ws_states_aoc_t states_tm1_l(rnn, states_tm1_l_);
+
+ parallel_nd(rnn.mb, [&](int i) {
+ for (int j = 0; j < rnn.dic; j++) {
+ const float h
+ = activation_func(0, ws_gates(i, 0, j) + bias(0, j), 0, 0);
+ ws_gates(i, 0, j) = states_t_l(i, j) = h;
+ }
+ });
+}
+
+template <>
+rnn_elemwise_sig(ref_rnn_fwd_u8s8_t::rnn_elemwise) {
+ assert(!"VANILLA RNN int8 is not supported");
+}
+
+template <>
+rnn_elemwise_sig(ref_rnn_bwd_f32_t::rnn_elemwise) {
+ ws_gates_aoc_t ws_gates(rnn, ws_gates_);
+ bias_aoc_t bias(rnn, bias_);
+ ws_states_aoc_t states_t_l(rnn, states_t_l_);
+ ws_states_aoc_t states_tm1_l(rnn, states_tm1_l_);
+ ws_diff_states_aoc_t diff_states_t_l(rnn, diff_states_t_l_);
+ ws_diff_states_aoc_t diff_states_tp1_l(rnn, diff_states_tp1_l_);
+ ws_diff_states_aoc_t diff_states_t_lp1(rnn, diff_states_t_lp1_);
+
+ parallel_nd(rnn.mb, [&](int i) {
+ for (int j = 0; j < rnn.dic; ++j) {
+ const float dH = diff_states_t_lp1(rnn.n_states, i, j)
+ + diff_states_tp1_l(0, i, j);
+ auto g = ws_gates(i, 0, j);
+ ws_gates(i, 0, j) = activation_func(dH, g, 0, 0);
+ }
+ });
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cpu_rnn_pd.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cpu_rnn_pd.hpp
new file mode 100644
index 0000000000..b39427caf9
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/cpu_rnn_pd.hpp
@@ -0,0 +1,191 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_RNN_PD_HPP
+#define CPU_RNN_PD_HPP
+
+#include "c_types_map.hpp"
+#include "nstl.hpp"
+#include "rnn_pd.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+#include "rnn_utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct cpu_rnn_fwd_pd_t : public rnn_fwd_pd_t {
+ using rnn_fwd_pd_t::rnn_fwd_pd_t;
+
+protected:
+ status_t set_default_params() {
+ using namespace format_tag;
+ if (src_layer_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(src_layer_md_, tnc));
+ if (dst_layer_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(dst_layer_md_, tnc));
+
+ // Optional parameters
+ if (with_src_iter() && src_iter_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(src_iter_md_, ldsnc));
+ if (with_bias() && bias_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(bias_md_, ldgo));
+ if (with_dst_iter() && dst_iter_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(dst_iter_md_, ldsnc));
+
+ return status::success;
+ }
+
+ status_t check_layout_consistency() {
+ using namespace format_tag;
+ using namespace data_type;
+ using namespace types;
+
+ auto is_blocked = [&](memory_desc_t md, int ndims) {
+ return md.format_kind == format_kind::blocked && md.ndims == ndims;
+ };
+
+ bool ok = true;
+ ok = ok && is_blocked(src_layer_md_, 3)
+ && is_blocked(dst_layer_md_, 3);
+ ok = ok && IMPLICATION(!is_zero_md(&src_iter_md_),
+ is_blocked(src_iter_md_, 5))
+ && IMPLICATION(!is_zero_md(&dst_iter_md_),
+ is_blocked(dst_iter_md_, 5));
+
+ if (weights_layer_md_.format_kind == format_kind::rnn_packed)
+ ok = ok && (weights_layer_md_.format_desc.rnn_packed_desc.format
+ == mkldnn_ldigo_p);
+ else
+ ok = ok && rnn_utils::is_ldigo(&weights_layer_md_);
+
+ if (weights_iter_md_.format_kind == format_kind::rnn_packed)
+ ok = ok && (weights_iter_md_.format_desc.rnn_packed_desc.format
+ == mkldnn_ldigo_p);
+ else
+ ok = ok && rnn_utils::is_ldigo(&weights_iter_md_);
+
+ ok = ok && IMPLICATION(!is_zero_md(&bias_md_),
+ memory_desc_matches_tag(bias_md_, ldgo));
+
+ /* Int8 is supported only for packed weights */
+ data_type_t weights_iter_dt = weights_iter_md_.data_type;
+ data_type_t weights_layer_dt = weights_layer_md_.data_type;
+ ok = ok && IMPLICATION(
+ weights_iter_dt == s8, weights_iter_md_.format_kind
+ == format_kind::rnn_packed);
+ ok = ok && IMPLICATION(
+ weights_layer_dt == s8, weights_layer_md_.format_kind
+ == format_kind::rnn_packed);
+
+ return ok ? status::success : status::unimplemented;
+ }
+};
+
+struct cpu_rnn_bwd_pd_t : public rnn_bwd_pd_t {
+ using rnn_bwd_pd_t::rnn_bwd_pd_t;
+
+protected:
+ status_t set_default_params() {
+ using namespace format_tag;
+ if (src_layer_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(src_layer_md_, tnc));
+ if (dst_layer_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(dst_layer_md_, tnc));
+
+ if (diff_src_layer_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(diff_src_layer_md_, tnc));
+ if (diff_weights_layer_md_.format_kind == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(diff_weights_layer_md_, ldigo));
+ CHECK(rnn_utils::set_good_strides(diff_weights_layer_md_, ldigo));
+ }
+ if (diff_weights_iter_md_.format_kind == format_kind::any) {
+ CHECK(memory_desc_init_by_tag(diff_weights_iter_md_, ldigo));
+ CHECK(rnn_utils::set_good_strides(diff_weights_iter_md_, ldigo));
+ }
+ if (diff_dst_layer_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(diff_dst_layer_md_, tnc));
+
+ // Optional parameters
+ if (with_src_iter() && src_iter_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(src_iter_md_, ldsnc));
+ if (with_bias() && bias_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(bias_md_, ldgo));
+ if (with_dst_iter() && dst_iter_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(dst_iter_md_, ldsnc));
+
+ if (with_src_iter() && diff_src_iter_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(diff_src_iter_md_, ldsnc));
+ if (with_bias() && diff_bias_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(diff_bias_md_, ldgo));
+ if (with_dst_iter() && diff_dst_iter_md_.format_kind == format_kind::any)
+ CHECK(memory_desc_init_by_tag(diff_dst_iter_md_, ldsnc));
+
+ return status::success;
+ }
+
+ status_t check_layout_consistency() {
+ using namespace format_tag;
+ using namespace types;
+
+ auto is_blocked = [&](memory_desc_t md, int ndims) {
+ return md.format_kind == format_kind::blocked && md.ndims == ndims;
+ };
+
+ bool ok = true;
+ ok = ok && is_blocked(src_layer_md_, 3)
+ && is_blocked(dst_layer_md_, 3);
+ ok = ok && IMPLICATION(!is_zero_md(&src_iter_md_),
+ is_blocked(src_iter_md_, 5))
+ && IMPLICATION(!is_zero_md(&dst_iter_md_),
+ is_blocked(dst_iter_md_, 5));
+
+ if (weights_layer_md_.format_kind == format_kind::rnn_packed)
+ ok = ok && (weights_layer_md_.format_desc.rnn_packed_desc.format
+ == mkldnn_ldgoi_p);
+ else
+ ok = ok && rnn_utils::is_ldgoi(&weights_layer_md_);
+
+ if (weights_iter_md_.format_kind == format_kind::rnn_packed)
+ ok = ok && (weights_iter_md_.format_desc.rnn_packed_desc.format
+ == mkldnn_ldgoi_p);
+ else
+ ok = ok && rnn_utils::is_ldgoi(&weights_iter_md_);
+
+ ok = ok && IMPLICATION(!is_zero_md(&bias_md_),
+ memory_desc_matches_tag(bias_md_, ldgo));
+
+ ok = ok && is_blocked(diff_src_layer_md_, 3)
+ && is_blocked(diff_dst_layer_md_, 3);
+ ok = ok && IMPLICATION(!is_zero_md(&diff_src_iter_md_),
+ is_blocked(diff_src_iter_md_, 5))
+ && IMPLICATION(!is_zero_md(&diff_dst_iter_md_),
+ is_blocked(diff_dst_iter_md_, 5));
+
+ ok = ok && rnn_utils::is_ldigo(&diff_weights_layer_md_)
+ && rnn_utils::is_ldigo(&diff_weights_iter_md_);
+ ok = ok && IMPLICATION(!is_zero_md(&diff_bias_md_),
+ memory_desc_matches_tag(diff_bias_md_, ldgo));
+
+ return ok ? status::success : status::unimplemented;
+ }
+};
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/jit_uni_rnn_postgemm.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/jit_uni_rnn_postgemm.hpp
new file mode 100644
index 0000000000..09445648aa
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/jit_uni_rnn_postgemm.hpp
@@ -0,0 +1,401 @@
+/*******************************************************************************
+* Copyright 2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/*
+ * Cell execution LSTM
+ */
+
+#include "rnn_utils.hpp"
+#include "../jit_generator.hpp"
+#include "../jit_uni_eltwise.hpp"
+#include "c_types_map.hpp"
+#include "utils.hpp"
+
+#include "mkldnn_thread.hpp"
+
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+struct jit_uni_rnn_postgemm_kernel : public jit_generator {
+
+ typedef void (*kernel_t)(void *gates_, const void *bias, void *states_t_l_,
+ void *c_states_t_l_, void *c_states_tm1_l_);
+
+ jit_uni_rnn_postgemm_kernel(const rnn_utils::rnn_conf_t &rnn, const primitive_attr_t *attr): rnn_(rnn), attr_(attr){}
+
+ virtual void init() = 0;
+
+template <typename src_data_t, typename acc_data_t>
+ rnn_elemwise_sig(execute) {
+ rnn_utils::ws_gates_aoc<acc_data_t> ws_gates(rnn, ws_gates_);
+ rnn_utils::bias_aoc_t bias(rnn, bias_);
+ rnn_utils::ws_states_aoc<src_data_t> states_t_l(rnn, states_t_l_);
+ rnn_utils::ws_states_aoc_t c_states_t_l(rnn, c_states_t_l_);
+ rnn_utils::ws_states_aoc_t c_states_tm1_l(rnn, c_states_tm1_l_);
+
+ // Todo: add parallelization on dic for the batch 1 case
+ // Assumption: the kernel runs a loop on dic elements
+ parallel_nd(rnn.mb, [&](int i) {
+ auto b_ = &bias(0, 0);
+ auto g_ = &ws_gates(i, 0, 0);
+ auto s_tl_ = &states_t_l(i, 0);
+ auto c_tl_ = &c_states_t_l(i, 0);
+ auto c_tm1l_ = &c_states_tm1_l(i, 0);
+ kernel_(g_, b_, s_tl_, c_tm1l_, c_tl_);
+ });
+ }
+
+protected:
+ kernel_t kernel_;
+ const rnn_utils::rnn_conf_t &rnn_;
+ const primitive_attr_t *attr_;
+};
+
+template <cpu_isa_t isa, impl::data_type_t src_data_t>
+struct jit_uni_lstm_postgemm_kernel_fwd: public jit_uni_rnn_postgemm_kernel
+{
+ DECLARE_CPU_JIT_AUX_FUNCTIONS(jit_uni_lstm_postgemm_kernel_fwd)
+
+ typedef typename utils::conditional<src_data_t == data_type::u8, int32_t,
+ float>::type acc_data_t;
+ typedef typename utils::conditional<isa == avx512_core,
+ jit_uni_eltwise_injector_f32<avx512_common>,
+ jit_uni_eltwise_injector_f32<isa>>::type injector_t;
+
+ jit_uni_lstm_postgemm_kernel_fwd(const rnn_utils::rnn_conf_t &rnn, const primitive_attr_t *attr)
+ : jit_uni_rnn_postgemm_kernel(rnn, attr){}
+
+ void init() override {
+ // we use rax for both constant tables as they use the same table
+ sigmoid_injector_ = new injector_t(this,
+ alg_kind::eltwise_logistic, 0.0f, 0.0f, true, rax);
+ tanh_injector_ = new injector_t(this,
+ alg_kind::eltwise_tanh, 0.0f, 0.0f, true, rax);
+ generate();
+ kernel_ = (kernel_t) this->getCode();
+ }
+
+protected:
+ injector_t *sigmoid_injector_;
+ injector_t *tanh_injector_;
+
+ // register size in bytes
+ using Vmm = typename jit_uni_eltwise_injector_f32<isa>::Vmm;
+ size_t vlen = cpu_isa_traits<isa>::vlen;
+ size_t vlen_dst = (src_data_t == data_type::u8) ? vlen/4 : vlen;
+ size_t cstate_dt_size = sizeof(float);
+ size_t hstate_dt_size = (src_data_t == data_type::u8) ? sizeof(uint8_t) : sizeof(float);
+ size_t gate_dt_size = (src_data_t == data_type::u8) ? sizeof(uint32_t) : sizeof(float);
+ size_t qscale_dt_size = sizeof(float);
+ size_t bias_dt_size = sizeof(float);
+
+ void generate() {
+ using namespace Xbyak;
+
+ int mask = attr_->rnn_weights_qparams_.mask_;
+ float *weights_scales = attr_->rnn_weights_qparams_.scales_;
+ float data_scale = attr_->rnn_data_qparams_.scale_;
+ float data_shift = attr_->rnn_data_qparams_.shift_;
+
+ // Labels declaration
+ Label vector_loop_start_label, vector_loop_end_label;
+ Label rem_loop_start_label, rem_loop_end_label;
+ Label table_label;
+
+ // Register map
+ Reg64 loop_cnt(r11); // loop counter
+ Reg64 table_reg(rbx); // table is used for data scale and shifts
+ Reg64 weights_scales_reg(r13);
+ // We skip vmm0 as it can be used by the injector for masks on sse4.2
+ Vmm G0(1), G1(2), G2(3), G3(4), tmp1_vmm(5), tmp2_vmm(6), zero_vmm(7);
+
+ // constant table map
+ Address dscale_off_addr = ptr[table_reg];
+ Address dshift_off_addr = ptr[table_reg + vlen];
+ Address ymm_perm_mask_addr = ptr[table_reg + 2*vlen];
+ Address zmm_perm_mask_addr = ptr[table_reg + 2*vlen + cpu_isa_traits<avx>::vlen];
+
+ // quantize from float to u8
+ auto q_d = [&](Vmm f, Vmm tmp_vmm) {
+ uni_vpxor(tmp_vmm, tmp_vmm, tmp_vmm);
+ uni_vmulps(f, f, dscale_off_addr); // apply scale
+ uni_vaddps(f, f, dshift_off_addr); // apply shift
+ uni_vcvtps2dq(f, f); // convert to int32
+ uni_vpackssdw(f, f, tmp_vmm); // convert from s32 to s16
+ uni_vpackuswb(f, f, tmp_vmm); // convert from s16 to u8 with saturation
+ // Note that the results are interleaved by 128 bit chunks, so we need to merge them together
+ switch (vlen) {
+ case 64: { //avx512
+ Zmm fz(f.getIdx()), tmpz(tmp_vmm.getIdx());
+ uni_vmovups(tmpz, zmm_perm_mask_addr);
+ vpermd(fz, tmpz, fz);
+ break; }
+ case 32: { //avx
+ Ymm fy(f.getIdx()), tmpy(tmp_vmm.getIdx());
+ uni_vmovups(tmpy, ymm_perm_mask_addr);
+ vpermd(fy, tmpy, fy);
+ break; }
+ case 16: // sse: nothing to do
+ break;
+ default: assert(!"Unsupported case");
+ };
+ };
+
+ auto fast_recip =[&](Vmm s, Vmm tmp, bool packed) {
+ if (packed)
+ uni_vrcpps(tmp, s);
+ else
+ uni_vrcpss(tmp, s); // prevent divide by zero
+ // we add one Newton iteration
+ uni_vmulps(s, s, tmp);
+ uni_vmulps(s, s, tmp); // s <- s * tmp^2
+ uni_vaddps(tmp, tmp, tmp);
+ uni_vsubps(tmp, tmp, s);
+ uni_vmovups(s, tmp); // s <- 2 * tmp - s * tmp^2
+ };
+
+ // dequantize from s32 to float
+ auto deq_w = [&](Vmm s, Vmm tmp1, Vmm tmp2, int gate, bool packed) {
+ // TODO: if mask is 0 precompute mul and inverse
+ if (mask == 0)
+ uni_vbroadcastss(tmp1, ptr[weights_scales_reg]);
+ else
+ uni_vmovups(tmp1, ptr[weights_scales_reg + gate * rnn_.dic * qscale_dt_size]);
+ uni_vcvtdq2ps(s, s);
+ uni_vmulps(tmp1, tmp1, dscale_off_addr);
+ fast_recip(tmp1, tmp2, packed);
+ uni_vmulps(s, s, tmp1);
+ };
+
+ // We start code generations here
+ preamble();
+
+ // extract addresses passed as parameter
+#ifdef _WIN32
+ auto addr_ws_gates_reg = abi_param1;
+ auto addr_bias_reg = abi_param2;
+ auto addr_states_t_l_reg = abi_param3;
+ auto addr_c_states_tm1_l_reg = abi_param4;
+ auto addr_c_states_t_l_reg = r10;
+ // Here we cannot use rbp to have initial stack pointer so we
+ // use rsp and offset it with the size of pushed registers in
+ // preamble
+ mov(addr_c_states_t_l_reg, ptr[rsp + get_size_of_abi_save_regs() + 40]);
+#else
+ auto addr_ws_gates_reg = abi_param1;
+ auto addr_bias_reg = abi_param2;
+ auto addr_states_t_l_reg = abi_param3;
+ auto addr_c_states_tm1_l_reg = abi_param4;
+ auto addr_c_states_t_l_reg = abi_param5;
+#endif
+
+ // initialize registers with addresses and constants
+ mov(table_reg, table_label);
+ mov(weights_scales_reg, size_t(weights_scales));
+ // both sigmoid and tanh use the same table so load address just once in rax
+ sigmoid_injector_->load_table_addr();
+
+ mov(loop_cnt, rnn_.dic * gate_dt_size);
+ cmp(loop_cnt, vlen);
+ jl(vector_loop_end_label, Xbyak::CodeGenerator::T_NEAR);
+
+ L(vector_loop_start_label);
+ {
+ // load G0 G1 G2 G3
+ uni_vmovups(G0, ptr[addr_ws_gates_reg + 0 * rnn_.dic * gate_dt_size]);
+ uni_vmovups(G1, ptr[addr_ws_gates_reg + 1 * rnn_.dic * gate_dt_size]);
+ uni_vmovups(G2, ptr[addr_ws_gates_reg + 2 * rnn_.dic * gate_dt_size]);
+ uni_vmovups(G3, ptr[addr_ws_gates_reg + 3 * rnn_.dic * gate_dt_size]);
+
+ // dequantize the gates from s32 to f32 if needed
+ if (src_data_t == data_type::u8){
+ deq_w(G0, tmp1_vmm, tmp2_vmm, 0, true);
+ deq_w(G1, tmp1_vmm, tmp2_vmm, 1, true);
+ deq_w(G2, tmp1_vmm, tmp2_vmm, 2, true);
+ deq_w(G3, tmp1_vmm, tmp2_vmm, 3, true);
+ }
+
+ // add biases
+ uni_vaddps(G0, G0, ptr[addr_bias_reg + 0 * rnn_.dic * bias_dt_size]);
+ uni_vaddps(G1, G1, ptr[addr_bias_reg + 1 * rnn_.dic * bias_dt_size]);
+ uni_vaddps(G2, G2, ptr[addr_bias_reg + 2 * rnn_.dic * bias_dt_size]);
+ uni_vaddps(G3, G3, ptr[addr_bias_reg + 3 * rnn_.dic * bias_dt_size]);
+
+ // inject eltwise code
+ sigmoid_injector_->compute_vector(G0.getIdx());
+ sigmoid_injector_->compute_vector(G1.getIdx());
+ tanh_injector_->compute_vector(G2.getIdx());
+ sigmoid_injector_->compute_vector(G3.getIdx());
+
+ // compute c_states_t_l = G1 * c_tm1_l + G0 * G2
+ uni_vmovups(tmp1_vmm, ptr[addr_c_states_tm1_l_reg]);
+ uni_vmulps(tmp1_vmm, tmp1_vmm, G1);
+ uni_vfmadd231ps(tmp1_vmm, G0, G2);
+ uni_vmovups(ptr[addr_c_states_t_l_reg], tmp1_vmm);
+
+ // states_t_l = G3 * tanh(c_states_t_l)
+ tanh_injector_->compute_vector(tmp1_vmm.getIdx());
+ uni_vmulps(tmp1_vmm, tmp1_vmm, G3);
+
+ // if int8, we quantize the resulting state
+ if (src_data_t == data_type::u8)
+ q_d(tmp1_vmm, tmp2_vmm);
+
+ // write back the result
+ if(vlen_dst == vlen)
+ uni_vmovups(ptr[addr_states_t_l_reg], tmp1_vmm);
+ else
+ // we write only 1/4 of the register
+ switch(vlen_dst){
+ case 16: uni_vmovups(ptr[addr_states_t_l_reg], Xmm(tmp1_vmm.getIdx())); break;
+ case 8: uni_vmovsd(ptr[addr_states_t_l_reg], Xmm(tmp1_vmm.getIdx())); break;
+ case 4: uni_vmovss(ptr[addr_states_t_l_reg], Xmm(tmp1_vmm.getIdx())); break;
+ default:
+ assert(!"Unsuported vector length for quantization");
+ }
+
+ // increment address pointers
+ add(addr_ws_gates_reg, vlen);
+ add(addr_bias_reg, vlen);
+ add(addr_states_t_l_reg, vlen_dst);
+ add(addr_c_states_tm1_l_reg, vlen);
+ add(addr_c_states_t_l_reg, vlen);
+ if (mask != 0)
+ add(weights_scales_reg, vlen);
+
+ // increment loop counter
+ sub(loop_cnt, vlen);
+ cmp(loop_cnt, vlen);
+ jge(vector_loop_start_label);
+ }
+ L(vector_loop_end_label);
+
+ cmp(loop_cnt, 0);
+ je(rem_loop_end_label, Xbyak::CodeGenerator::T_NEAR);
+ // Same code as above, we just use movuss for accessing inputs
+ // TODO: smarter handling of tails with Zmm -> Ymm -> Xmm -> scalar
+ L(rem_loop_start_label);
+ {
+ // remaping registers to Xmms
+ Xmm G0s(G0.getIdx()), G1s(G1.getIdx()), G2s(G2.getIdx()), G3s(G3.getIdx());
+ Xmm tmp1s_vmm(tmp1_vmm.getIdx());
+
+ // load G0 G1 G2 G3
+ uni_vmovss(G0s, ptr[addr_ws_gates_reg + 0 * rnn_.dic * gate_dt_size]);
+ uni_vmovss(G1s, ptr[addr_ws_gates_reg + 1 * rnn_.dic * gate_dt_size]);
+ uni_vmovss(G2s, ptr[addr_ws_gates_reg + 2 * rnn_.dic * gate_dt_size]);
+ uni_vmovss(G3s, ptr[addr_ws_gates_reg + 3 * rnn_.dic * gate_dt_size]);
+
+ // dequantize the gates from s32 to f32 if needed
+ if (src_data_t == data_type::u8){
+ deq_w(G0, tmp1_vmm, tmp2_vmm, 0, false);
+ deq_w(G1, tmp1_vmm, tmp2_vmm, 1, false);
+ deq_w(G2, tmp1_vmm, tmp2_vmm, 2, false);
+ deq_w(G3, tmp1_vmm, tmp2_vmm, 3, false);
+ }
+
+ // add biases
+ uni_vmovss(tmp1s_vmm, ptr[addr_bias_reg + 0 * rnn_.dic * bias_dt_size]);
+ uni_vaddps(G0s, G0s, tmp1s_vmm);
+ uni_vmovss(tmp1s_vmm, ptr[addr_bias_reg + 1 * rnn_.dic * bias_dt_size]);
+ uni_vaddps(G1s, G1s, tmp1s_vmm);
+ uni_vmovss(tmp1s_vmm, ptr[addr_bias_reg + 2 * rnn_.dic * bias_dt_size]);
+ uni_vaddps(G2s, G2s, tmp1s_vmm);
+ uni_vmovss(tmp1s_vmm, ptr[addr_bias_reg + 3 * rnn_.dic * bias_dt_size]);
+ uni_vaddps(G3s, G3s, tmp1s_vmm);
+
+ // inject eltwise code
+ sigmoid_injector_->compute_vector(G0s.getIdx());
+ sigmoid_injector_->compute_vector(G1s.getIdx());
+ tanh_injector_->compute_vector(G2s.getIdx());
+ sigmoid_injector_->compute_vector(G3s.getIdx());
+
+ // compute c_states_t_l = G1 * c_tm1_l + G0s * G2
+ uni_vmovups(tmp1s_vmm, ptr[addr_c_states_tm1_l_reg]);
+ uni_vmulps(tmp1s_vmm, tmp1s_vmm, G1s);
+ uni_vfmadd231ps(tmp1s_vmm, G0s, G2s);
+ uni_vmovss(ptr[addr_c_states_t_l_reg], tmp1s_vmm);
+
+ // states_t_l = G3 * tanh(c_states_t_l)
+ tanh_injector_->compute_vector(tmp1s_vmm.getIdx());
+ uni_vmulps(tmp1s_vmm, tmp1s_vmm, G3s);
+
+ // if int8, we quantize the resulting state
+ if (src_data_t == data_type::u8)
+ q_d(tmp1_vmm, tmp2_vmm);
+
+ // write back the result
+ if(vlen_dst == vlen)
+ uni_vmovups(ptr[addr_states_t_l_reg], tmp1s_vmm);
+ else
+ // we write only 1/4 of the register
+ switch(vlen_dst){
+ case 16: uni_vmovups(ptr[addr_states_t_l_reg], Xmm(tmp1s_vmm.getIdx())); break;
+ case 8: uni_vmovsd(ptr[addr_states_t_l_reg], Xmm(tmp1s_vmm.getIdx())); break;
+ case 4: uni_vmovss(ptr[addr_states_t_l_reg], Xmm(tmp1s_vmm.getIdx())); break;
+ default:
+ assert(!"Unsuported vector length for quantization");
+ }
+
+ // increment address pointers
+ add(addr_ws_gates_reg, gate_dt_size);
+ add(addr_bias_reg, bias_dt_size);
+ add(addr_states_t_l_reg, hstate_dt_size);
+ add(addr_c_states_tm1_l_reg, cstate_dt_size);
+ add(addr_c_states_t_l_reg, cstate_dt_size);
+ if (mask != 0)
+ add(weights_scales_reg, qscale_dt_size);
+
+ // increment loop counter
+ sub(loop_cnt, gate_dt_size);
+ cmp(loop_cnt, 0);
+ jg(rem_loop_start_label);
+
+ }
+ L(rem_loop_end_label);
+
+ postamble();
+
+ // Again, only one table is needed and shared between sigmoid and tanh
+ sigmoid_injector_->prepare_table(false);
+ tanh_injector_->prepare_table(true);
+
+ L(table_label);
+ {
+ for (size_t i = 0; i < vlen / sizeof(float); i++) dd(float2int(data_scale));
+ for (size_t i = 0; i < vlen / sizeof(float); i++) dd(float2int(data_shift));
+ // perm mask for ymm
+ dd(0); dd(4); dd(2); dd(3); dd(1); dd(5); dd(6); dd(7);
+ // perm mask for zmm
+ dd(0); dd(4); dd(8); dd(12); dd(1); dd(5); dd(6); dd(7);
+ dd(2); dd(9); dd(10); dd(11); dd(3); dd(12); dd(13); dd(14);
+ }
+ }
+
+};
+
+template struct jit_uni_lstm_postgemm_kernel_fwd<sse42, data_type::f32>;
+template struct jit_uni_lstm_postgemm_kernel_fwd<avx2, data_type::f32>;
+template struct jit_uni_lstm_postgemm_kernel_fwd<avx512_core, data_type::f32>;
+
+template struct jit_uni_lstm_postgemm_kernel_fwd<sse42, data_type::u8>;
+template struct jit_uni_lstm_postgemm_kernel_fwd<avx2, data_type::u8>;
+template struct jit_uni_lstm_postgemm_kernel_fwd<avx512_core, data_type::u8>;
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/ref_rnn.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/ref_rnn.cpp
new file mode 100644
index 0000000000..ead536816c
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/ref_rnn.cpp
@@ -0,0 +1,788 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/*
+ General architecture
+
+ for diff states, we have n_states + 1 as we have n_states diff
+ to propagate to the previous iteration and 1 states to propagate
+ to the previous layer
+ index 0 is dh for cell(t-1, l) to consume
+ index 1 is dc for cell(t-1, l) to consume
+ index 2 is dh for cell(t, l-1) to consume
+ this indexing enables to have the same indexing for states in elemwise
+ function
+ only the cell execution function should be impacted
+
+ */
+
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+
+#include "ref_rnn.hpp"
+#include "../gemm/gemm.hpp"
+#include "../simple_q10n.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::utils;
+using namespace mkldnn::impl::memory_tracking::names;
+using namespace rnn_utils;
+#define AOC array_offset_calculator
+
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+void _ref_rnn_common_t<aprop, src_type, weights_type>::gates_reduction(
+ const rnn_conf_t &rnn, const acc_data_t *ws_gates_,
+ float *diff_bias_) const {
+ auto body = [&](int i, int k) {
+ for (int j = 0; j < rnn.mb; j++)
+ diff_bias_[i * rnn.dic + k]
+ += ws_gates_[j * rnn.gates_ws_ld + i * rnn.dic + k];
+ };
+
+ // @todo block k on simd-width
+#if MKLDNN_THR == MKLDNN_THR_OMP && _OPENMP >= 201307 \
+ /* icc 17.0 has a problem with simd collapse */ \
+ && !((defined __INTEL_COMPILER) && (__INTEL_COMPILER == 1700))
+#pragma omp parallel for simd collapse(2)
+ for (int i = 0; i < rnn.n_gates; i++)
+ for (int k = 0; k < rnn.dic; k++)
+ body(i, k);
+#else
+ parallel_nd(rnn.n_gates, rnn.dic, body);
+#endif
+}
+
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+rnn_gemm_sig((_ref_rnn_common_t<aprop, src_type, weights_type>::gemm)) {
+ assert(ldA * ldB * ldC != 0);
+ extended_sgemm(&transA, &transB, &m, &n, &k, &alpha, a_, &ldA, b_, &ldB,
+ &beta, c_, &ldC, nullptr, pd()->rnn_.use_jit_gemm);
+}
+
+template <>
+rnn_gemm_sig((ref_rnn_fwd_u8s8_t::gemm)) {
+ assert(!"non packed gemm is disabled for int8");
+}
+
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+rnn_gemm_sig((_ref_rnn_common_t<aprop, src_type, weights_type>::packed_gemm)) {
+#if (USE_MKL_PACKED_GEMM)
+ assert(transA == 'N');
+ cblas_sgemm_compute(CblasColMajor, CblasPacked,
+ (transB == 'T') ? CblasTrans : CblasNoTrans, m, n, k, a_, ldA, b_,
+ ldB, beta, c_, ldC);
+#else
+ UNUSED(transA);
+ UNUSED(transB);
+ UNUSED(m);
+ UNUSED(n);
+ UNUSED(k);
+ UNUSED(alpha);
+ UNUSED(ldA);
+ UNUSED(b_);
+ UNUSED(ldB);
+ UNUSED(beta);
+ UNUSED(c_);
+ UNUSED(ldC);
+ assert(!"packed gemm is disabled");
+#endif
+}
+
+template <>
+rnn_gemm_sig((ref_rnn_fwd_u8s8_t::packed_gemm)) {
+#if (USE_MKL_PACKED_GEMM)
+ int8_t offseta = 0, offsetb = 0;
+ int32_t offsetc = 0;
+ cblas_gemm_s8u8s32_compute(CblasColMajor, (CBLAS_TRANSPOSE)CblasPacked,
+ CblasNoTrans, CblasFixOffset, m, n, k, alpha, a_, ldA, offseta, b_,
+ ldB, offsetb, beta, c_, ldC, &offsetc);
+#else
+ UNUSED(transA);
+ UNUSED(transB);
+ UNUSED(m);
+ UNUSED(n);
+ UNUSED(k);
+ UNUSED(alpha);
+ UNUSED(ldA);
+ UNUSED(b_);
+ UNUSED(ldB);
+ UNUSED(beta);
+ UNUSED(c_);
+ UNUSED(ldC);
+ assert(!"packed gemm is disabled");
+#endif
+}
+
+//*************** Grid computations strategy: linear ***************//
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+rnn_grid_execution_sig(
+ (_ref_rnn_common_t<aprop, src_type, weights_type>::linear_execution)) {
+ AOC<src_data_t, 4> ws_states(ws_states_, rnn.n_layer + 1, rnn.n_dir,
+ rnn.n_iter + 1, rnn.states_nld * rnn.states_ws_ld);
+ AOC<float, 4> ws_c_states(ws_c_states_, rnn.n_layer + 1, rnn.n_dir,
+ rnn.n_iter + 1, rnn.states_nld * rnn.states_ws_ld);
+ AOC<float, 5> ws_diff_states(ws_diff_states_, rnn.n_layer + 1, rnn.n_dir,
+ (rnn.n_states + 1), rnn.n_iter + 1,
+ rnn.states_nld * rnn.states_ws_ld);
+ AOC<acc_data_t, 4> ws_gates(ws_gates_, rnn.n_layer, rnn.n_dir, rnn.n_iter,
+ rnn.gates_nld * rnn.gates_ws_ld);
+ AOC<weights_data_t *, 3> weights_input(
+ weights_layer_, rnn.n_layer, rnn.n_dir, rnn.n_parts_weights_layer);
+ AOC<weights_data_t *, 3> weights_states(
+ weights_states_, rnn.n_layer, rnn.n_dir, rnn.n_parts_weights_iter);
+ AOC<float*, 3> bias(
+ bias_, rnn.n_layer, rnn.n_dir, rnn.n_parts_bias);
+ AOC<float, 3> diff_weights_layer(diff_weights_layer_, rnn.n_layer,
+ rnn.n_dir,
+ rnn.diff_weights_layer_nld * rnn.diff_weights_layer_ld);
+ AOC<float, 3> diff_weights_iter(diff_weights_iter_, rnn.n_layer, rnn.n_dir,
+ rnn.diff_weights_iter_nld * rnn.diff_weights_iter_ld);
+ AOC<float, 3> diff_bias(
+ diff_bias_, rnn.n_layer, rnn.n_dir, rnn.n_bias * rnn.dic);
+ AOC<float, 4> ws_grid(
+ ws_grid_, rnn.n_layer, rnn.n_dir, rnn.n_iter, (int)rnn.ws_per_cell);
+
+ // We run the grid of computation
+ for (int dir = 0; dir < rnn.n_dir; dir++) {
+ for (int j = 0; j < rnn.n_layer; j++) {
+ int lay = (aprop == prop_kind::forward) ? j : rnn.n_layer - j - 1;
+
+ if ((aprop == prop_kind::forward) && rnn.merge_gemm_layer) {
+ (this->*gemm_layer_func)('N', 'N', rnn.n_gates * rnn.dic,
+ rnn.mb * rnn.n_iter, rnn.slc, 1.0,
+ weights_input(lay, dir, 0), rnn.weights_iter_ld,
+ &(ws_states(lay, dir, 1, 0)), rnn.states_ws_ld, 0.0,
+ &(ws_gates(lay, dir, 0, 0)), rnn.gates_ws_ld);
+ }
+
+ for (int i = 0; i < rnn.n_iter; i++) {
+ int iter = (aprop == prop_kind::forward) ? i : rnn.n_iter - i - 1;
+ (this->*cell_func)(rnn,
+ &(ws_states(lay + 1, dir, iter + 1, 0)),
+ &(ws_c_states(lay + 1, dir, iter + 1, 0)),
+ &(ws_diff_states(lay, dir, 0, iter, 0)),
+ &(weights_input(lay, dir, 0)),
+ &(weights_states(lay, dir, 0)),
+ &(bias(lay, dir, 0)),
+ &(ws_states(lay, dir, iter + 1, 0)),
+ &(ws_states(lay + 1, dir, iter, 0)),
+ &(ws_c_states(lay + 1, dir, iter, 0)),
+ &(ws_diff_states(lay + 1, dir, 0, iter, 0)),
+ &(ws_diff_states(lay, dir, 0, iter + 1, 0)),
+ &(diff_weights_layer(lay, dir, 0)),
+ &(diff_weights_iter(lay, dir, 0)),
+ &(diff_bias(lay, dir, 0)),
+ &(ws_gates(lay, dir, iter, 0)),
+ &(ws_grid(lay, dir, iter, 0)),
+ ws_cell_);
+ }
+
+ if ((aprop == prop_kind::backward) && rnn.merge_gemm_layer) {
+ (this->*gemm_layer_func)('N', 'N', rnn.slc, rnn.mb * rnn.n_iter,
+ rnn.n_gates * rnn.dic, 1.0, weights_input(lay, dir, 0),
+ rnn.weights_layer_ld,
+ (src_data_t *)(&(ws_gates(lay, dir, 0, 0))),
+ rnn.gates_ws_ld, 0.0,
+ (acc_data_t *)(&(ws_diff_states(
+ lay, dir, rnn.n_states, 0, 0))),
+ rnn.states_ws_ld);
+ gemm('N', 'T', rnn.n_gates * rnn.dic, rnn.slc,
+ rnn.mb * rnn.n_iter, 1.0,
+ (weights_data_t *)(&(ws_gates(lay, dir, 0, 0))),
+ rnn.gates_ws_ld,
+ (src_data_t *)(&(ws_states(lay, dir, 1, 0))),
+ rnn.states_ws_ld, 1.0,
+ (acc_data_t *)(&(diff_weights_layer(lay, dir, 0))),
+ rnn.diff_weights_layer_ld);
+ }
+ if ((aprop == prop_kind::backward) && rnn.merge_gemm_iter) {
+ gemm('N', 'T', rnn.n_gates * rnn.dic, rnn.sic,
+ rnn.mb * rnn.n_iter, 1.0,
+ (weights_data_t *)(&(ws_gates(lay, dir, 0, 0))),
+ rnn.gates_ws_ld,
+ (src_data_t *)(&(ws_states(lay + 1, dir, 0, 0))),
+ rnn.states_ws_ld, 1.0,
+ (acc_data_t *)(&(diff_weights_iter(lay, dir, 0))),
+ rnn.diff_weights_iter_ld);
+ }
+ }
+ }
+}
+
+//********* GRID computations strategy: utility functions **********//
+
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+void _ref_rnn_common_t<aprop, src_type, weights_type>::copy_init_layer(
+ const rnn_conf_t &rnn, src_data_t *__restrict ws_states_,
+ float *__restrict ws_diff_states_, const src_data_t *__restrict xt_,
+ const float *__restrict diff_dst_layer_) const {
+
+ AOC<src_data_t, 4> ws_states(
+ ws_states_, rnn.n_dir, rnn.n_iter + 1, rnn.mb, rnn.states_ws_ld);
+ auto xt_d = memory_desc_wrapper(pd()->src_md(0));
+
+ parallel_nd(rnn.n_iter, rnn.mb, [&](int it, int b) {
+ auto xxt = xt_ + xt_d.blk_off(it, b);
+ src_data_t *ws_l2r_ptr = &(ws_states(0, it + 1, b, 0));
+ src_data_t *ws_r2l_ptr = &(ws_states(rnn.n_dir - 1, rnn.n_iter - it, b, 0));
+ if (rnn.exec_dir != r2l)
+ for (int c = 0; c < rnn.slc; c++)
+ ws_l2r_ptr[c] = xxt[c];
+ if (rnn.exec_dir != l2r)
+ for (int c = 0; c < rnn.slc; c++)
+ ws_r2l_ptr[c] = xxt[c];
+ });
+}
+
+template <>
+void ref_rnn_bwd_f32_t::copy_init_layer(const rnn_conf_t &rnn,
+ src_data_t *ws_states_, float *ws_diff_states_, const src_data_t *xt_,
+ const float *diff_dst_layer_) const {
+ AOC<float, 6> ws_diff_states(ws_diff_states_, rnn.n_layer + 1, rnn.n_dir,
+ (rnn.n_states + 1), rnn.n_iter + 1, rnn.mb, rnn.states_ws_ld);
+ auto diff_dst_layer_d = memory_desc_wrapper(pd()->diff_dst_md(0));
+
+ switch (rnn.exec_dir) {
+ case bi_concat:
+ parallel_nd(rnn.n_iter, rnn.mb, [&](int it, int b) {
+ auto diff_dst_layer_x
+ = diff_dst_layer_ + diff_dst_layer_d.blk_off(it, b);
+ for (int s = 0; s < rnn.dic; s++) {
+ ws_diff_states(rnn.n_layer, 0, rnn.n_states, it, b, s)
+ = diff_dst_layer_x[s];
+ ws_diff_states(
+ rnn.n_layer, 1, rnn.n_states, rnn.n_iter - it - 1, b, s)
+ = diff_dst_layer_x[rnn.dic + s];
+ }
+ });
+ break;
+ case bi_sum:
+ parallel_nd(rnn.n_iter, rnn.mb, [&](int it, int b) {
+ auto diff_dst_layer_x
+ = diff_dst_layer_ + diff_dst_layer_d.blk_off(it, b);
+ for (int s = 0; s < rnn.dic; s++) {
+ ws_diff_states(rnn.n_layer, 0, rnn.n_states, it, b, s)
+ = diff_dst_layer_x[s];
+ ws_diff_states(
+ rnn.n_layer, 1, rnn.n_states, rnn.n_iter - it - 1, b, s)
+ = diff_dst_layer_x[s];
+ }
+ });
+ break;
+ case l2r:
+ parallel_nd(rnn.n_iter, rnn.mb, [&](int it, int b) {
+ auto diff_dst_layer_x
+ = diff_dst_layer_ + diff_dst_layer_d.blk_off(it, b);
+ for (int s = 0; s < rnn.dic; s++) {
+ ws_diff_states(rnn.n_layer, 0, rnn.n_states, it, b, s)
+ = diff_dst_layer_x[s];
+ }
+ });
+ break;
+ case r2l:
+ parallel_nd(rnn.n_iter, rnn.mb, [&](int it, int b) {
+ auto diff_dst_layer_x = diff_dst_layer_
+ + diff_dst_layer_d.blk_off(rnn.n_iter - it - 1, b);
+ for (int s = 0; s < rnn.dic; s++) {
+ ws_diff_states(rnn.n_layer, 0, rnn.n_states, it, b, s)
+ = diff_dst_layer_x[s];
+ }
+ });
+ break;
+ default: assert(!"Unsupported direction"); break;
+ }
+}
+
+/* For int8 configuration, input iteration states may be of types f32 or u8
+ * Internally h_state is always stored in u8 and c_state is always stored in f32
+ * If input states are of type u8 then h state is copied and c state is dequantized
+ * If input states are of type f32 then h state is quantized and c_state is copied
+ * */
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+template <typename input_data_t>
+void _ref_rnn_common_t<aprop, src_type, weights_type>::copy_init_iter(
+ const rnn_conf_t &rnn, src_data_t *__restrict ws_states_,
+ float *__restrict ws_c_states_, float *__restrict ws_diff_states_,
+ const input_data_t *__restrict firstit_states_,
+ const float *__restrict diff_dst_iter_) const {
+ AOC<src_data_t, 5> ws_states(ws_states_, rnn.n_layer + 1, rnn.n_dir,
+ rnn.n_iter + 1, rnn.mb, rnn.states_ws_ld);
+ AOC<float, 5> ws_c_states(ws_c_states_, rnn.n_layer + 1, rnn.n_dir,
+ rnn.n_iter + 1, rnn.mb, rnn.states_ws_ld);
+ float data_shift = pd()->attr()->rnn_data_qparams_.shift_;
+ float data_scale = pd()->attr()->rnn_data_qparams_.scale_;
+
+ const bool quantize = pd()->with_src_iter()
+ && pd()->src_md(1)->data_type == data_type::f32
+ && rnn.dt_conf != all_f32;
+ auto maybe_q = [&](input_data_t f) {
+ if (quantize) {
+ float qf = f * data_scale + data_shift;
+ return qz_a1b0<float, src_data_t>()(qf);
+ } else
+ return (src_data_t)f;
+ };
+
+ const bool dequantize = pd()->with_src_iter()
+ && pd()->src_md(1)->data_type == data_type::u8;
+ auto maybe_deq = [&](input_data_t s) {
+ if (dequantize)
+ return (((float)s - data_shift) / data_scale);
+ else
+ return (float)s;
+ };
+ auto firstit_states_d = memory_desc_wrapper(pd()->src_md(1));
+ if (firstit_states_) {
+ parallel_nd(
+ rnn.n_layer, rnn.n_dir, rnn.mb, [&](int lay, int dir, int b) {
+ for (int s = 0; s < rnn.sic; s++)
+ ws_states(lay + 1, dir, 0, b, s) = maybe_q(
+ firstit_states_[firstit_states_d.blk_off(
+ lay, dir, 0, b, s)]);
+ if (pd()->cell_kind() == alg_kind::vanilla_lstm)
+ for (int s = 0; s < rnn.sic; s++)
+ ws_c_states(lay + 1, dir, 0, b, s) = maybe_deq(
+ firstit_states_[firstit_states_d.blk_off(
+ lay, dir, 1, b, s)]);
+ });
+ } else {
+ parallel_nd(
+ rnn.n_layer, rnn.n_dir, rnn.mb, [&](int lay, int dir, int b) {
+ for (int j = 0; j < rnn.sic; j++) {
+ ws_states(lay + 1, dir, 0, b, j) = (src_data_t)0;
+ ws_c_states(lay + 1, dir, 0, b, j) = 0.0f;
+ }
+ });
+ }
+}
+
+template <>
+template <typename input_data_t>
+void ref_rnn_bwd_f32_t::copy_init_iter(const rnn_conf_t &rnn,
+ src_data_t *ws_states_, float *ws_c_states_, float *ws_diff_states_,
+ const input_data_t *firstit_states_,
+ const float *diff_dst_iter_) const {
+ AOC<float, 6> ws_diff_states(ws_diff_states_, rnn.n_layer + 1, rnn.n_dir,
+ rnn.n_states + 1, rnn.n_iter + 1, rnn.mb, rnn.states_ws_ld);
+ auto diff_dst_iter_d = memory_desc_wrapper(pd()->diff_dst_md(1));
+ if (diff_dst_iter_) {
+ parallel_nd(rnn.n_layer, rnn.n_dir, rnn.n_states, rnn.mb,
+ [&](int lay, int dir, int state, int b) {
+ array_copy(&(ws_diff_states(
+ lay, dir, state, rnn.n_iter, b, 0)),
+ diff_dst_iter_
+ + diff_dst_iter_d.blk_off(
+ lay, dir, state, b),
+ rnn.dic);
+ });
+ } else {
+ parallel_nd(rnn.n_layer, rnn.n_dir, rnn.n_states, rnn.mb,
+ [&](int lay, int dir, int state, int i) {
+ for (int j = 0; j < rnn.dic; j++)
+ ws_diff_states(lay, dir, state, rnn.n_iter, i, j)
+ = 0.0f;
+ });
+ }
+}
+
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+template <typename dst_data_t>
+void _ref_rnn_common_t<aprop, src_type, weights_type>::copy_res_layer(
+ const rnn_conf_t &rnn, dst_data_t *dst_layer_, float *diff_src_layer,
+ const src_data_t *ws_states_, const float *ws_diff_states_) const {
+
+ auto dst_layer_d = memory_desc_wrapper(pd()->dst_md(0));
+ AOC<const src_data_t, 5> ws_states(ws_states_, rnn.n_layer + 1, rnn.n_dir,
+ rnn.n_iter + 1, rnn.mb, rnn.states_ws_ld);
+ float shift = (pd()->attr()->rnn_data_qparams_.shift_);
+ float scale = (pd()->attr()->rnn_data_qparams_.scale_);
+
+ const bool dequantize = pd()->dst_md(0)->data_type == data_type::f32
+ && rnn.dt_conf != all_f32;
+ auto maybe_deq = [&](src_data_t s) {
+ if (dequantize)
+ return (dst_data_t)(((float)s - shift) / scale);
+ else
+ return (dst_data_t)s;
+ };
+ parallel_nd(rnn.n_iter, rnn.mb, [&](int it, int b) {
+ int dir = 0;
+ if (rnn.exec_dir != r2l) {
+ for (int s = 0; s < rnn.dic; s++) {
+ dst_layer_[dst_layer_d.blk_off(it, b, dir * rnn.dic + s)]
+ = maybe_deq(ws_states(rnn.n_layer, dir, it + 1, b, s));
+ }
+ dir = 1;
+ }
+ if (rnn.exec_dir != l2r) {
+ for (int s = 0; s < rnn.dic; s++)
+ switch (rnn.exec_dir) {
+ case bi_sum:
+ dst_layer_[dst_layer_d.blk_off(it, b, s)]
+ += maybe_deq(ws_states(
+ rnn.n_layer, dir, rnn.n_iter - it, b, s));
+ break;
+ default:
+ dst_layer_[dst_layer_d.blk_off(it, b, dir * rnn.dic + s)]
+ = maybe_deq(ws_states(
+ rnn.n_layer, dir, rnn.n_iter - it, b, s));
+ }
+ }
+ });
+}
+
+template <>
+template <typename dst_data_t>
+void ref_rnn_bwd_f32_t::copy_res_layer(
+ const rnn_conf_t &rnn, dst_data_t *dst_layer_, float *diff_src_layer_,
+ const src_data_t *ws_states_, const float *ws_diff_states_) const {
+ auto diff_src_layer_d = memory_desc_wrapper(pd()->diff_src_md(0));
+ AOC<const float, 6> ws_diff_states(ws_diff_states_, rnn.n_layer + 1,
+ rnn.n_dir, rnn.n_states + 1, rnn.n_iter + 1, rnn.mb,
+ rnn.states_ws_ld);
+
+ parallel_nd(rnn.n_iter, rnn.mb, [&](int it, int b) {
+ int dir = 0;
+ for (int s = 0; s < rnn.slc; s++) {
+ float *dst_addr = diff_src_layer_
+ + diff_src_layer_d.blk_off(
+ (rnn.exec_dir == r2l) ? rnn.n_iter - 1 - it : it,
+ b, dir * rnn.slc + s);
+ float res = ws_diff_states(0, 0, rnn.n_states, it, b, s);
+ if (rnn.n_dir - 1)
+ res += ws_diff_states(
+ 0, 1, rnn.n_states, rnn.n_iter - 1 - it, b, s);
+ dst_addr[0] = res;
+ }
+ });
+}
+
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+template <typename output_data_t>
+void _ref_rnn_common_t<aprop, src_type, weights_type>::copy_res_iter(
+ const rnn_conf_t &rnn, output_data_t *dst_iter_, float *diff_src_iter_,
+ const src_data_t *ws_states_, float *ws_c_states_,
+ const float *ws_diff_states_) const {
+ auto dst_iter_d = memory_desc_wrapper(pd()->dst_md(1));
+ AOC<const src_data_t, 5> ws_states(ws_states_, rnn.n_layer + 1, rnn.n_dir,
+ rnn.n_iter + 1, rnn.mb, rnn.states_ws_ld);
+ AOC<const float, 5> ws_c_states(ws_c_states_, rnn.n_layer + 1, rnn.n_dir,
+ rnn.n_iter + 1, rnn.mb, rnn.states_ws_ld);
+ float data_shift = pd()->attr()->rnn_data_qparams_.shift_;
+ float data_scale = pd()->attr()->rnn_data_qparams_.scale_;
+
+ const bool quantize = pd()->with_dst_iter()
+ && pd()->dst_md(1)->data_type == data_type::u8
+ && rnn.dt_conf != all_f32;
+ auto maybe_q = [&](float f) {
+ if (quantize) {
+ float qf = f * data_scale + data_shift;
+ return qz_a1b0<float, output_data_t>()(qf);
+ } else
+ return (output_data_t)f;
+ };
+
+ const bool dequantize = pd()->with_dst_iter()
+ && pd()->dst_md(1)->data_type == data_type::f32
+ && rnn.dt_conf != all_f32;
+ auto maybe_deq = [&](src_data_t s) {
+ if (dequantize)
+ return (output_data_t)(((float)s - data_shift) / data_scale);
+ else
+ return (output_data_t)s;
+ };
+ if (dst_iter_) {
+ parallel_nd(rnn.n_layer, rnn.n_dir, rnn.mb,
+ [&](int lay, int dir, int b) {
+ for (int s = 0; s < rnn.dic; s++) {
+ dst_iter_[dst_iter_d.blk_off(lay, dir, 0, b, s)]
+ = maybe_deq(ws_states(lay + 1, dir, rnn.n_iter, b, s));
+ }
+ if (pd()->cell_kind() == alg_kind::vanilla_lstm)
+ for (int s = 0; s < rnn.dic; s++) {
+ dst_iter_[dst_iter_d.blk_off(lay, dir, 1, b, s)]
+ = maybe_q(ws_c_states(
+ lay + 1, dir, rnn.n_iter, b, s));
+ }
+ });
+ }
+}
+
+template <>
+template <typename output_data_t>
+void ref_rnn_bwd_f32_t::copy_res_iter(
+ const rnn_conf_t &rnn, output_data_t *dst_iter_, float *diff_src_iter_,
+ const src_data_t *ws_states_, float *ws_c_states_,
+ const float *ws_diff_states_) const {
+ auto diff_src_iter_d = memory_desc_wrapper(pd()->diff_src_md(1));
+ AOC<const float, 6> ws_diff_states(ws_diff_states_, rnn.n_layer + 1,
+ rnn.n_dir, rnn.n_states + 1, rnn.n_iter + 1, rnn.mb,
+ rnn.states_ws_ld);
+ if (diff_src_iter_) {
+ parallel_nd(rnn.n_layer, rnn.n_dir, rnn.n_states, rnn.mb,
+ [&](int lay, int dir, int state, int b) {
+ for (int s = 0; s < rnn.sic; s++) {
+ diff_src_iter_[diff_src_iter_d.blk_off(
+ lay, dir, state, b, s)]
+ = ws_diff_states(lay, dir, state, 0, b, s);
+ }
+ });
+ }
+}
+
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+rnn_bias_prepare_sig((_ref_rnn_common_t<aprop, src_type, weights_type>::bias_prepare)) {
+ /* Original set of bias provided by the user */
+ AOC<const float, 5> b(
+ b_, rnn.n_layer, rnn.n_dir, rnn.n_bias * rnn.dic);
+ /* Array of pointers initialized in packing */
+ AOC<float *, 3> bias(bias_, rnn.n_layer, rnn.n_dir, rnn.n_parts_bias);
+ AOC<float, 3> scratch_bias(
+ scratch_bias_, rnn.n_layer, rnn.n_dir, rnn.n_bias * rnn.dic);
+
+ if (rnn.copy_bias) {
+ parallel_nd(rnn.n_layer * rnn.n_dir * rnn.n_bias * rnn.dic,
+ [&](size_t i) { scratch_bias_[i] = b_[i]; });
+ }
+
+ for (int i = 0; i < rnn.n_layer; i++) {
+ for (int d = 0; d < rnn.n_dir; d++) {
+ int offset_bias = 0;
+ for (int p = 0; p < rnn.n_parts_bias; p++) {
+ bias(i, d, p) = rnn.copy_bias
+ ? (float *) &scratch_bias(i, d, offset_bias)
+ : (float *) &b(i, d, offset_bias);
+ offset_bias += rnn.parts_bias[p] * rnn.dic;
+ }
+ }
+ }
+
+}
+
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+rnn_bias_finalize_sig(
+ (_ref_rnn_common_t<aprop, src_type, weights_type>::bias_finalize)) {
+ if (rnn.dt_conf != all_f32) {
+ float data_shift = pd()->attr()->rnn_data_qparams_.shift_;
+ float data_scale = pd()->attr()->rnn_data_qparams_.scale_;
+ float *weights_scales = pd()->attr()->rnn_weights_qparams_.scales_;
+ bool scale_per_oc = pd()->attr()->rnn_weights_qparams_.mask_ != 0;
+ for (int i = 0; i < rnn.n_layer * rnn.n_dir; i++)
+ for (int j = 0; j < rnn.n_bias * rnn.dic; j++) {
+ size_t off = i * rnn.n_bias * rnn.dic + j;
+ float weights_scale
+ = scale_per_oc ? weights_scales[j] : weights_scales[0];
+ scratch_bias_[off] -= (w_iter_comp[off] + w_layer_comp[off])
+ * data_shift / (weights_scale * data_scale);
+ }
+ }
+}
+
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+rnn_weights_assign_sig((_ref_rnn_common_t<aprop, src_type,
+ weights_type>::assign_packed_weights)) {
+ assert(md->format_kind == format_kind::rnn_packed);
+ const auto packed_desc = md->format_desc.rnn_packed_desc;
+ AOC<weights_data_t *, 3> weights(weights_,
+ rnn.n_layer, rnn.n_dir, packed_desc.n_parts);
+
+ size_t offset_packed = 0;
+ for (int l = 0; l < rnn.n_layer; l++)
+ for (int d = 0; d < rnn.n_dir; d++) {
+ for (int p = 0; p < packed_desc.n_parts; p++) {
+ weights(l, d, p) = (weights_data_t *)&w_[offset_packed];
+ offset_packed
+ += packed_desc.part_pack_size[p] / sizeof(weights_data_t);
+ }
+ }
+}
+
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+rnn_weights_assign_sig(
+ (_ref_rnn_common_t<aprop, src_type, weights_type>::assign_weights)) {
+ assert(md->format_kind == format_kind::blocked);
+ const auto &blk = md->format_desc.blocking;
+ /* Original set of weights provided by the user */
+ AOC<const weights_data_t, 3> w(w_,
+ rnn.n_layer, rnn.n_dir, (int)blk.strides[1]);
+ /* Array of pointers for each part of weights */
+ AOC<weights_data_t *, 3> weights(weights_, rnn.n_layer, rnn.n_dir, n_parts);
+
+ for (int i = 0; i < rnn.n_layer; i++)
+ for (int d = 0; d < rnn.n_dir; d++) {
+ size_t offset_weights = 0;
+ for (int p = 0; p < n_parts; p++) {
+ weights(i, d, p) = (weights_data_t *)&w(i, d, offset_weights);
+ offset_weights += gates_per_part[p] * blk.strides[3];
+ }
+ }
+}
+
+//********************* Execution function *********************//
+template <prop_kind_t aprop, data_type_t src_type, data_type_t weights_type>
+void _ref_rnn_common_t<aprop, src_type, weights_type>::execute_(
+ const exec_ctx_t &ctx) const {
+ const rnn_conf_t &rnn = this->pd()->rnn_;
+ auto input = CTX_IN_MEM(const src_data_t *, MKLDNN_ARG_SRC_LAYER);
+ auto states = CTX_IN_MEM(const char *, MKLDNN_ARG_SRC_ITER);
+ auto layer_weights_n_comp = CTX_IN_MEM(const char *, MKLDNN_ARG_WEIGHTS_LAYER);
+ auto iter_weights_n_comp = CTX_IN_MEM(const char *, MKLDNN_ARG_WEIGHTS_ITER);
+ auto bias = CTX_IN_MEM(const float *, MKLDNN_ARG_BIAS);
+
+ auto dst_last_layer = rnn.is_fwd
+ ? CTX_OUT_MEM(char *, MKLDNN_ARG_DST_LAYER)
+ : const_cast<char *>(CTX_IN_MEM(const char *, MKLDNN_ARG_DST_LAYER));
+ auto dst_last_iter = rnn.is_fwd
+ ? CTX_OUT_MEM(char *, MKLDNN_ARG_DST_ITER)
+ : const_cast<char *>(CTX_IN_MEM(const char *, MKLDNN_ARG_DST_ITER));
+
+ auto diff_dst_layer = CTX_IN_MEM(const float *, MKLDNN_ARG_DIFF_DST_LAYER);
+ auto diff_dst_iter = CTX_IN_MEM(const float *, MKLDNN_ARG_DIFF_DST_ITER);
+
+ auto w_layer = reinterpret_cast<const weights_data_t *>(layer_weights_n_comp);
+ auto w_iter = reinterpret_cast<const weights_data_t *>(iter_weights_n_comp);
+ auto w_iter_comp = reinterpret_cast<const float *>(
+ iter_weights_n_comp + rnn.weights_iter_comp_offset);
+ auto w_layer_comp = reinterpret_cast<const float *>(
+ layer_weights_n_comp + rnn.weights_layer_comp_offset);
+
+ auto scratchpad = this->scratchpad(ctx);
+
+ auto ptr_wei_layer
+ = scratchpad.template get<weights_data_t *>(key_rnn_ptrs_wei_layer);
+ auto ptr_wei_iter
+ = scratchpad.template get<weights_data_t *>(key_rnn_ptrs_wei_iter);
+ auto ptr_bias =
+ scratchpad.template get<float *>(key_rnn_ptrs_bia);
+
+ // fetchihg buffers from the workspace
+ // if no workspace was provided we use the scratchpad
+ char *scratch_ptr = scratchpad.template get<char>(key_rnn_space);
+ char *ws_ptr = nullptr;
+ if (rnn.use_workspace)
+ ws_ptr = rnn.is_fwd
+ ? CTX_OUT_MEM(char *, MKLDNN_ARG_WORKSPACE)
+ : const_cast<char *>(CTX_IN_MEM(const char *, MKLDNN_ARG_WORKSPACE));
+
+ char *base_ptr = rnn.use_workspace ? ws_ptr : scratch_ptr;
+ acc_data_t *ws_gates = (acc_data_t *)(base_ptr + ws_gates_offset_);
+ src_data_t *ws_states = (src_data_t *)(base_ptr + ws_states_offset_);
+ float *ws_c_states = (float *)(base_ptr + ws_c_states_offset_);
+ float *ws_diff_states = (float *)(base_ptr + ws_diff_states_offset_);
+ float *ws_grid = (float *)(base_ptr + ws_grid_comp_offset_);
+ float *ws_cell = (float *)(base_ptr + ws_cell_comp_offset_);
+
+ auto diff_src_layer = CTX_OUT_MEM(float *, MKLDNN_ARG_DIFF_SRC_LAYER);
+ auto diff_src_iter = CTX_OUT_MEM(float *, MKLDNN_ARG_DIFF_SRC_ITER);
+
+ auto diff_weights_layer = CTX_OUT_MEM(float *, MKLDNN_ARG_DIFF_WEIGHTS_LAYER);
+ auto diff_weights_iter = CTX_OUT_MEM(float *, MKLDNN_ARG_DIFF_WEIGHTS_ITER);
+ auto diff_bias = CTX_OUT_MEM(float *, MKLDNN_ARG_DIFF_BIAS);
+
+ // Fetching extra buffers from scratchpad
+ float *ws_bias = (float *)(scratch_ptr + ws_bias_offset_);
+
+ // initialize diff_states to 0
+ if (aprop == prop_kind::backward)
+ array_set(ws_diff_states, 0.0f, rnn.ws_diff_states_size / sizeof(float));
+
+ /* Pack(if using packed gemm API) or copy(if input arrays have bad leading
+ * dimension */
+ (this->*bias_preparation_func)(rnn, ptr_bias, bias, ws_bias);
+
+ (this->*weights_iter_assign_func)(rnn, pd()->weights_md(1),
+ rnn.weights_iter_nld, rnn.weights_iter_ld, rnn.dic,
+ rnn.sic, rnn.n_parts_weights_iter, rnn.parts_weights_iter,
+ rnn.part_weights_iter_pack_size, ptr_wei_iter, w_iter,
+ ptr_bias, bias, ws_bias);
+ (this->*weights_layer_assign_func)(rnn, pd()->weights_md(0),
+ rnn.weights_layer_nld, rnn.weights_layer_ld, rnn.dic, rnn.slc,
+ rnn.n_parts_weights_layer, rnn.parts_weights_layer,
+ rnn.part_weights_layer_pack_size, ptr_wei_layer, w_layer, ptr_bias,
+ bias, ws_bias);
+
+ (this->*bias_finalization_func)(rnn, ws_bias, w_iter_comp, w_layer_comp);
+
+ // we first need to copy the initial states and input into ws
+ copy_init_layer(rnn, ws_states, ws_diff_states, input, diff_dst_layer);
+ if (rnn.dt_conf == f32u8f32u8 || rnn.dt_conf == f32u8f32f32
+ || rnn.dt_conf == all_f32)
+ copy_init_iter(rnn, ws_states, ws_c_states, ws_diff_states,
+ (const float *)states, diff_dst_iter);
+ else if (rnn.dt_conf == u8u8u8u8 || rnn.dt_conf == u8u8u8f32)
+ copy_init_iter(rnn, ws_states, ws_c_states, ws_diff_states,
+ (const uint8_t *)states, diff_dst_iter);
+ else
+ assert(!"unimplemented");
+
+ // run the execution on the grid
+ (this->*grid_computation)(rnn, ptr_wei_layer, ptr_wei_iter, ptr_bias,
+ ws_states, ws_c_states, ws_diff_states, ws_gates, ws_cell, ws_grid,
+ diff_weights_layer, diff_weights_iter, diff_bias);
+
+ // Finally we copy the results to the result buffers
+ if (rnn.dt_conf == u8u8u8f32 || rnn.dt_conf == f32u8f32f32
+ || rnn.dt_conf == all_f32)
+ copy_res_layer(rnn, (float *)dst_last_layer, diff_src_layer, ws_states,
+ ws_diff_states);
+ else if (rnn.dt_conf == u8u8u8u8 || rnn.dt_conf == f32u8f32u8)
+ copy_res_layer(rnn, (uint8_t *)dst_last_layer, diff_src_layer,
+ ws_states, ws_diff_states);
+ else
+ assert(!"unimplemented");
+
+ if (rnn.dt_conf == f32u8f32u8 || rnn.dt_conf == f32u8f32f32
+ || rnn.dt_conf == all_f32)
+ copy_res_iter(rnn, (float *)dst_last_iter, diff_src_iter, ws_states,
+ ws_c_states, ws_diff_states);
+ else if (rnn.dt_conf == u8u8u8u8 || rnn.dt_conf == u8u8u8f32)
+ copy_res_iter(rnn, (uint8_t *)dst_last_iter, diff_src_iter, ws_states,
+ ws_c_states, ws_diff_states);
+ else
+ assert(!"unimplemented");
+};
+
+/* Fix for MSVS warning C4661 */
+template<> rnn_cell_execution_sig(ref_rnn_fwd_f32_t::cell_execution);
+template<> rnn_cell_execution_sig(ref_rnn_fwd_u8s8_t::cell_execution);
+template<> rnn_cell_execution_sig(ref_rnn_bwd_f32_t::cell_execution);
+template<> rnn_cell_execution_sig(ref_rnn_fwd_f32_t::cell_execution_gru);
+template<> rnn_cell_execution_sig(ref_rnn_fwd_u8s8_t::cell_execution_gru);
+template<> rnn_cell_execution_sig(ref_rnn_bwd_f32_t::cell_execution_gru);
+template<> rnn_cell_execution_sig(ref_rnn_fwd_f32_t::cell_execution_gru_lbr);
+template<> rnn_cell_execution_sig(ref_rnn_fwd_u8s8_t::cell_execution_gru_lbr);
+template<> rnn_cell_execution_sig(ref_rnn_bwd_f32_t::cell_execution_gru_lbr);
+template<> rnn_elemwise_sig(ref_rnn_fwd_f32_t::rnn_elemwise);
+template<> rnn_elemwise_sig(ref_rnn_fwd_u8s8_t::rnn_elemwise);
+template<> rnn_elemwise_sig(ref_rnn_bwd_f32_t::rnn_elemwise);
+template<> rnn_elemwise_sig(ref_rnn_fwd_f32_t::lstm_elemwise);
+template<> rnn_elemwise_sig(ref_rnn_fwd_u8s8_t::lstm_elemwise);
+template<> rnn_elemwise_sig(ref_rnn_bwd_f32_t::lstm_elemwise);
+template<> rnn_elemwise_sig(ref_rnn_fwd_f32_t::gru_lbr_elemwise);
+template<> rnn_elemwise_sig(ref_rnn_fwd_u8s8_t::gru_lbr_elemwise);
+template<> rnn_elemwise_sig(ref_rnn_bwd_f32_t::gru_lbr_elemwise);
+
+template struct _ref_rnn_common_t<prop_kind::forward, data_type::f32, data_type::f32>;
+template struct _ref_rnn_common_t<prop_kind::forward, data_type::u8, data_type::s8>;
+template struct _ref_rnn_common_t<prop_kind::backward, data_type::f32, data_type::f32>;
+
+#undef AOC
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/ref_rnn.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/ref_rnn.hpp
new file mode 100644
index 0000000000..6f449a9016
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/ref_rnn.hpp
@@ -0,0 +1,328 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_REF_RNN_HPP
+#define CPU_REF_RNN_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "memory_tracking.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+#include "../cpu_isa_traits.hpp"
+#include "../gemm/os_blas.hpp"
+
+#include "cpu_rnn_pd.hpp"
+#include "../cpu_primitive.hpp"
+#include "rnn_utils.hpp"
+#include "jit_uni_rnn_postgemm.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <alg_kind_t alg_kind, prop_kind_t prop_kind>
+float activation(float s, float alpha, float cliping, float dd);
+
+template <prop_kind_t aprop, impl::data_type_t src_type,
+ impl::data_type_t weights_type>
+struct _ref_rnn_common_t : public cpu_primitive_t {
+ typedef typename prec_traits<src_type>::type src_data_t;
+ typedef typename prec_traits<weights_type>::type weights_data_t;
+ typedef typename utils::conditional<src_type == data_type::u8, int32_t,
+ float>::type acc_data_t;
+
+ using class_name = _ref_rnn_common_t<aprop, src_type, weights_type>;
+
+ typedef rnn_elemwise_sig((class_name::*elemwise_f));
+ typedef rnn_cell_execution_sig((class_name::*cell_execution_f));
+ typedef rnn_grid_execution_sig((class_name::*grid_execution_f));
+
+ typedef rnn_gemm_sig((class_name::*gemm_t));
+ typedef rnn_bias_prepare_sig((class_name::*bias_prepare_t));
+ typedef rnn_bias_finalize_sig((class_name::*bias_finalize_t));
+ typedef rnn_weights_assign_sig((class_name::*weights_assign_t));
+
+ using base_pd_t =
+ typename utils::conditional<false || aprop == prop_kind::forward,
+ cpu_rnn_fwd_pd_t, cpu_rnn_bwd_pd_t>::type;
+
+ struct pd_t : public base_pd_t {
+ using base_pd_t::base_pd_t;
+
+ DECLARE_COMMON_PD_T("ref:any", class_name);
+
+ status_t init() {
+ using namespace prop_kind;
+ using namespace utils;
+ using namespace format_tag;
+ using namespace rnn_utils;
+ const alg_kind_t cell_kind = this->desc()->cell_desc.cell_kind;
+
+ data_type_t src_layer_dt = this->desc()->src_layer_desc.data_type;
+ data_type_t weights_iter_dt
+ = this->desc()->weights_iter_desc.data_type;
+ data_type_t weights_layer_dt
+ = this->desc()->weights_layer_desc.data_type;
+
+ bool ok = true
+ && one_of(cell_kind, alg_kind::vanilla_rnn,
+ alg_kind::vanilla_lstm, alg_kind::vanilla_gru,
+ alg_kind::gru_linear_before_reset)
+ && IMPLICATION(aprop == prop_kind::forward,
+ one_of(this->desc()->prop_kind, forward_training,
+ forward_inference))
+ && IMPLICATION(aprop == backward,
+ one_of(this->desc()->prop_kind, backward))
+ && src_layer_dt == src_type
+ && everyone_is(
+ weights_type, weights_iter_dt, weights_layer_dt)
+ && this->set_default_params() == status::success
+ && this->with_bias();
+ if (!ok)
+ return status::unimplemented;
+
+ init_conf(rnn_, *this->desc(), this->src_md(0), this->src_md(1),
+ this->weights_md(0), this->weights_md(1), this->dst_md(0));
+
+ if (rnn_.dt_conf == all_f32)
+ ok = ok && this->attr()->has_default_values();
+
+ // Set weights descriptors to desired format
+ memory_desc_t new_weights_layer_md = *this->weights_md(0);
+ CHECK(set_expected_desc(rnn_, new_weights_layer_md, false));
+ if (this->weights_layer_md_.format_kind == format_kind::any) {
+ this->weights_layer_md_ = new_weights_layer_md;
+ } else if (this->weights_layer_md_.format_kind
+ == format_kind::rnn_packed) {
+ if (this->weights_layer_md_ != new_weights_layer_md)
+ return status::unimplemented;
+ }
+
+ memory_desc_t new_weights_iter_md = *this->weights_md(1);
+ CHECK(set_expected_desc(rnn_, new_weights_iter_md, true));
+ if (this->weights_iter_md_.format_kind == format_kind::any) {
+ this->weights_iter_md_ = new_weights_iter_md;
+ } else if (this->weights_iter_md_.format_kind
+ == format_kind::rnn_packed) {
+ if (this->weights_iter_md_ != new_weights_iter_md)
+ return status::unimplemented;
+ }
+
+ CHECK(this->check_layout_consistency());
+
+ set_conf(rnn_, *this->desc(), this->weights_md(0),
+ this->weights_md(1), this->diff_weights_md(0),
+ this->diff_weights_md(1));
+
+ size_t scratchpad_sz{0}, ws_sz{0};
+ get_scratchpad_and_workspace_sizes(rnn_, scratchpad_sz, ws_sz);
+
+ // initialize the workspace if needed
+ if (rnn_.is_training) {
+ dims_t ws_dims = { (int)ws_sz };
+ mkldnn_memory_desc_init_by_tag(&this->ws_md_, 1, ws_dims,
+ data_type::u8, format_tag::x);
+ }
+
+ init_scratchpad(scratchpad_sz);
+
+ return status::success;
+ }
+
+ rnn_utils::rnn_conf_t rnn_;
+
+ private:
+ void init_scratchpad(size_t scratchpad_sz) {
+ using namespace memory_tracking::names;
+ auto scratchpad = this->scratchpad_registry().registrar();
+ scratchpad.book(key_rnn_space, sizeof(float) * scratchpad_sz, 4096);
+
+ int max_nparts = this->cell_kind() == alg_kind::vanilla_gru ? 2 : 1;
+ int ptr_wei_sz = rnn_.n_layer * rnn_.n_dir * max_nparts;
+ scratchpad.book(key_rnn_ptrs_wei_layer,
+ sizeof(float *) * ptr_wei_sz);
+ scratchpad.book(key_rnn_ptrs_wei_iter,
+ sizeof(float *) * ptr_wei_sz);
+ scratchpad.book(key_rnn_ptrs_bia,
+ sizeof(float *) * ptr_wei_sz);
+ }
+ };
+
+ _ref_rnn_common_t(const pd_t *apd)
+ : cpu_primitive_t(apd, true), rnn_postgemm_(nullptr) {
+ /// @todo set max_feature_size assuming that we limit the number of
+ /// iterations and layer to one if slc != dic and sic != dic
+ /// respectively
+
+ bias_preparation_func = &class_name::bias_prepare;
+ bias_finalization_func = &class_name::bias_finalize;
+
+ auto set_gemm_funcs
+ = [](bool packed_gemm, gemm_t &g, weights_assign_t &a) {
+ if (packed_gemm) {
+ g = &class_name::packed_gemm;
+ a = &class_name::assign_packed_weights;
+ } else {
+ g = &class_name::gemm;
+ a = &class_name::assign_weights;
+ }
+ };
+ set_gemm_funcs(pd()->rnn_.use_iter_packed_gemm, gemm_iter_func,
+ weights_iter_assign_func);
+
+ set_gemm_funcs(pd()->rnn_.use_layer_packed_gemm, gemm_layer_func,
+ weights_layer_assign_func);
+
+ switch (pd()->cell_kind()) {
+ case alg_kind::vanilla_lstm:
+ cell_func = &class_name::cell_execution;
+ if (aprop == prop_kind::forward) {
+ if (mayiuse(avx512_core))
+ rnn_postgemm_ = new jit_uni_lstm_postgemm_kernel_fwd<avx512_core, src_type>(
+ pd()->rnn_, pd()->attr());
+ else if (mayiuse(avx2))
+ rnn_postgemm_ = new jit_uni_lstm_postgemm_kernel_fwd<avx2, src_type>(
+ pd()->rnn_, pd()->attr());
+ else if (mayiuse(sse42))
+ rnn_postgemm_ = new jit_uni_lstm_postgemm_kernel_fwd<sse42, src_type>(
+ pd()->rnn_, pd()->attr());
+ assert(rnn_postgemm_ != nullptr);
+ rnn_postgemm_->init();
+ }
+ elemwise_func = &class_name::lstm_elemwise;
+ break;
+ case alg_kind::vanilla_rnn: // @todo switch on cell kind
+ cell_func = &class_name::cell_execution;
+ elemwise_func = &class_name::rnn_elemwise;
+ switch (pd()->activation_kind()) {
+ case alg_kind::eltwise_relu:
+ activation_func = &activation<alg_kind::eltwise_relu, aprop>;
+ break;
+ case alg_kind::eltwise_tanh:
+ activation_func = &activation<alg_kind::eltwise_tanh, aprop>;
+ break;
+ case alg_kind::eltwise_logistic:
+ activation_func = &activation<alg_kind::eltwise_logistic, aprop>;
+ break;
+ default: break;
+ }
+ break;
+ case alg_kind::vanilla_gru:
+ cell_func = &class_name::cell_execution_gru;
+ break;
+ case alg_kind::gru_linear_before_reset:
+ cell_func = &class_name::cell_execution_gru_lbr;
+ elemwise_func = &class_name::gru_lbr_elemwise;
+ break;
+ default: break;
+ }
+
+ grid_computation = &class_name::linear_execution;
+
+ size_t scratchpad_size, workspace_size;
+ rnn_utils::set_offsets(pd()->rnn_, ws_gates_offset_, ws_states_offset_,
+ ws_c_states_offset_, ws_diff_states_offset_,
+ ws_grid_comp_offset_, ws_cell_comp_offset_,
+ ws_bias_offset_, scratchpad_size, workspace_size);
+ }
+
+ ~_ref_rnn_common_t() {}
+
+ // typedef typename prec_traits::type data_t;
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ execute_(ctx);
+ return status::success;
+ }
+
+private:
+ void execute_(const exec_ctx_t &ctx) const;
+ rnn_grid_execution_sig(linear_execution);
+ rnn_cell_execution_sig(cell_execution);
+ rnn_cell_execution_sig(cell_execution_gru);
+ rnn_cell_execution_sig(cell_execution_gru_lbr);
+ rnn_elemwise_sig(rnn_elemwise);
+ rnn_elemwise_sig(lstm_elemwise);
+ rnn_elemwise_sig(gru_lbr_elemwise);
+ rnn_gemm_sig(gemm);
+ rnn_gemm_sig(packed_gemm);
+ rnn_bias_prepare_sig(bias_prepare);
+ rnn_bias_finalize_sig(bias_finalize);
+ rnn_weights_assign_sig(assign_weights);
+ rnn_weights_assign_sig(assign_packed_weights);
+
+ float (*activation_func)(float dd, float s, float alpha, float cliping);
+
+ void copy_init_layer(const rnn_utils::rnn_conf_t &rnn,
+ src_data_t *ws_states_, float *ws_diff_states_,
+ const src_data_t *xt_, const float *diff_dst_layer) const;
+
+ template <typename input_data_t>
+ void copy_init_iter(const rnn_utils::rnn_conf_t &rnn,
+ src_data_t *ws_states_, float *ws_c_states, float *ws_diff_states_,
+ const input_data_t *firstit_states_,
+ const float *diff_dst_iter) const;
+
+ template <typename dst_data_t>
+ void copy_res_layer(const rnn_utils::rnn_conf_t &rnn,
+ dst_data_t *dst_layer_, float *diff_src_layer,
+ const src_data_t *ws_states_, const float *ws_diff_states_) const;
+
+ template <typename output_data_t>
+ void copy_res_iter(const rnn_utils::rnn_conf_t &rnn,
+ output_data_t *dst_iter_, float *diff_src_iter,
+ const src_data_t *ws_states_, float *ws_c_states,
+ const float *ws_diff_states_) const;
+
+ void gates_reduction(const rnn_utils::rnn_conf_t &rnn,
+ const acc_data_t *ws_gates_, float *diff_bias_) const;
+
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+
+ size_t ws_gates_offset_;
+ size_t ws_states_offset_;
+ size_t ws_c_states_offset_;
+ size_t ws_bias_offset_;
+ size_t ws_diff_states_offset_;
+ size_t ws_grid_comp_offset_;
+ size_t ws_cell_comp_offset_;
+ jit_uni_rnn_postgemm_kernel *rnn_postgemm_;
+
+ grid_execution_f grid_computation;
+ cell_execution_f cell_func;
+
+ bias_prepare_t bias_preparation_func;
+ bias_finalize_t bias_finalization_func;
+ weights_assign_t weights_layer_assign_func;
+ weights_assign_t weights_iter_assign_func;
+
+ gemm_t gemm_layer_func;
+ gemm_t gemm_iter_func;
+ elemwise_f elemwise_func;
+};
+
+using ref_rnn_fwd_f32_t = _ref_rnn_common_t<prop_kind::forward, data_type::f32, data_type::f32>;
+using ref_rnn_bwd_f32_t = _ref_rnn_common_t<prop_kind::backward, data_type::f32, data_type::f32>;
+using ref_rnn_fwd_u8s8_t = _ref_rnn_common_t<prop_kind::forward, data_type::u8, data_type::s8>;
+}
+}
+}
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_reorders.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_reorders.hpp
new file mode 100644
index 0000000000..597c63e3f8
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_reorders.hpp
@@ -0,0 +1,380 @@
+/*******************************************************************************
+ * Copyright 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+
+#ifndef CPU_RNN_REORDERS_HPP
+#define CPU_RNN_REORDERS_HPP
+
+#include <assert.h>
+
+#include "type_helpers.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+#include "simple_q10n.hpp"
+#include "cpu_reorder_pd.hpp"
+#include "../gemm/os_blas.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <data_type_t type_i, data_type_t type_o>
+struct rnn_data_reorder_t : public cpu_primitive_t {
+ struct pd_t : public cpu_reorder_pd_t {
+ using cpu_reorder_pd_t::cpu_reorder_pd_t;
+
+ DECLARE_COMMON_PD_T("rnn_data_reorder", rnn_data_reorder_t);
+
+ static status_t create(reorder_pd_t **reorder_pd,
+ engine_t *engine, const primitive_attr_t *attr,
+ engine_t *src_engine, const memory_desc_t *src_md,
+ engine_t *dst_engine, const memory_desc_t *dst_md) {
+ const memory_desc_wrapper id(src_md), od(dst_md);
+ bool args_ok = true
+ && id.data_type() == type_i
+ && od.data_type() == type_o
+ && id.matches_one_of_tag(format_tag::tnc, format_tag::ldsnc)
+ && od == id;
+ if (!args_ok) return status::invalid_arguments;
+
+ auto _pd = new pd_t(engine, attr, src_engine, src_md, dst_engine,
+ dst_md);
+ if (_pd == nullptr) return out_of_memory;
+ if (_pd->init() != success) { delete _pd; return unimplemented; }
+ return safe_ptr_assign<reorder_pd_t>(*reorder_pd, _pd);
+ }
+ };
+
+private:
+ typedef typename prec_traits<type_i>::type in_data_t;
+ typedef typename prec_traits<type_o>::type out_data_t;
+
+ rnn_data_reorder_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ auto input = CTX_IN_MEM(const in_data_t *, MKLDNN_ARG_FROM);
+ auto output = CTX_OUT_MEM(out_data_t *, MKLDNN_ARG_TO);
+ const memory_desc_wrapper &input_d = pd()->src_md();
+ const memory_desc_wrapper &output_d = pd()->dst_md();
+ const size_t nelems = input_d.nelems();
+ const float scale = pd()->attr()->rnn_data_qparams_.scale_;
+ const float shift = pd()->attr()->rnn_data_qparams_.shift_;
+
+ parallel_nd(nelems, [&](size_t i) {
+ float in = (float)input[input_d.off_l(i)] * scale + shift;
+ output[output_d.off_l(i)] = qz_a1b0<float, out_data_t>()(in);
+ });
+
+ return status::success;
+ }
+
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <data_type_t type_i, data_type_t type_o>
+struct rnn_weights_reorder_t : public cpu_primitive_t {
+ struct pd_t : public cpu_reorder_pd_t {
+ using cpu_reorder_pd_t::cpu_reorder_pd_t;
+
+ DECLARE_COMMON_PD_T("rnn_weights_reorder", rnn_weights_reorder_t);
+
+ static status_t create(reorder_pd_t **reorder_pd,
+ engine_t *engine, const primitive_attr_t *attr,
+ engine_t *src_engine, const memory_desc_t *src_md,
+ engine_t *dst_engine, const memory_desc_t *dst_md) {
+#if !USE_MKL_PACKED_GEMM
+ return status::unimplemented;
+#endif
+ const memory_desc_wrapper id(src_md), od(dst_md);
+ bool args_ok = true
+ && id.data_type() == type_i
+ && od.data_type() == type_o
+ && od.format_kind() == format_kind::rnn_packed
+ && od.rnn_packed_desc().format == mkldnn_ldigo_p
+ && od.rnn_packed_desc().n_parts == 1
+ && attr != nullptr;
+ if (!args_ok) return status::invalid_arguments;
+
+ format_tag_t itag = id.matches_one_of_tag(
+ format_tag::ldigo, format_tag::ldgoi);
+ if (itag == format_tag::undef) return status::invalid_arguments;
+
+ const int mask = attr->rnn_weights_qparams_.mask_;
+ if (!utils::one_of(mask, 0, 3)) return status::unimplemented;
+
+ auto _pd = new pd_t(engine, attr, src_engine, src_md, dst_engine,
+ dst_md);
+ if (_pd == nullptr) return out_of_memory;
+ _pd->itag_ = itag;
+ if (_pd->init() != success) { delete _pd; return unimplemented; }
+ return safe_ptr_assign<reorder_pd_t>(*reorder_pd, _pd);
+ }
+
+ status_t init() {
+ status_t status = cpu_reorder_pd_t::init();
+ if (status != status::success) return status;
+
+ init_scratchpad();
+
+ return status::success;
+ }
+
+ format_tag_t itag_;
+
+ private:
+ void init_scratchpad() {
+ const memory_desc_wrapper id(src_md());
+ const size_t nelems = id.nelems();
+ const auto &dims = id.dims();
+
+ using namespace memory_tracking::names;
+ auto scratchpad = scratchpad_registry().registrar();
+ size_t quantization_size = sizeof(int8_t) * nelems;
+ size_t reduction_size = itag_ == ldigo
+ ? sizeof(int32_t) * mkldnn_get_max_threads() * dims[0]
+ * dims[1] * dims[3] * dims[4]
+ : 0;
+ scratchpad.book(
+ key_reorder_rnn_weights_quantization, quantization_size);
+ scratchpad.book(key_reorder_rnn_weights_reduction, reduction_size);
+ }
+ };
+
+private:
+ typedef typename prec_traits<type_i>::type in_data_t;
+ typedef typename prec_traits<type_o>::type out_data_t;
+
+ rnn_weights_reorder_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+#if USE_MKL_PACKED_GEMM
+ auto input = CTX_IN_MEM(const in_data_t *, MKLDNN_ARG_FROM);
+ auto output = CTX_OUT_MEM(char *, MKLDNN_ARG_TO);
+ const memory_desc_wrapper &input_d = pd()->src_md();
+ const memory_desc_wrapper &output_d = pd()->dst_md();
+ const auto &dims = input_d.dims();
+
+ const int L = dims[0];
+ const int D = dims[1];
+ const int I = dims[2];
+ const int G = dims[3];
+ const int O = dims[4];
+
+ const bool is_igo = pd()->itag_ == format_tag::ldigo;
+
+ /* Quantize input & compute compensation */
+ auto quantized = (int8_t * __restrict)scratchpad(ctx).template get<void>(
+ memory_tracking::names::key_reorder_rnn_weights_quantization);
+ auto reduction = (int32_t * __restrict)scratchpad(ctx).template get<void>(
+ memory_tracking::names::key_reorder_rnn_weights_reduction);
+ float *comp = reinterpret_cast<float *>(
+ output + output_d.rnn_packed_desc().offset_compensation);
+ const float *scales = pd()->attr()->rnn_weights_qparams_.scales_;
+ const int mask = pd()->attr()->rnn_weights_qparams_.mask_;
+
+ if (is_igo) {
+ int nthr = mkldnn_get_max_threads();
+ int LD_nthr = nstl::min(L * D, nthr);
+ int I_nthr = nstl::min(I, nthr / LD_nthr);
+ parallel(nthr, [&](const int ithr, const int nthr) {
+ int LD_ithr = -1, LD_s = -1, LD_e = -1;
+ int I_ithr = -1, I_s = -1, I_e = -1;
+ if (ithr < LD_nthr * I_nthr) {
+ LD_ithr = ithr % LD_nthr;
+ I_ithr = ithr / LD_nthr;
+ balance211(L * D, LD_nthr, LD_ithr, LD_s, LD_e);
+ balance211(I, I_nthr, I_ithr, I_s, I_e);
+ }
+ int32_t *comp_ithr = reduction + I_ithr * L * D * G * O;
+ for (int ld = LD_s; ld < LD_e; ld++) {
+ for (int go = 0; go < G * O; go++)
+ comp_ithr[ld * G * O + go] = 0;
+ for (int i = I_s; i < I_e; i++) {
+ PRAGMA_OMP_SIMD()
+ for (int go = 0; go < G * O; go++) {
+ const float s = scales[(mask == 0) ? 0 : go];
+ int8_t q = qz_b0<in_data_t, out_data_t>()(
+ input[ld * I * G * O + i * G * O + go], s);
+ quantized[ld * I * G * O + i * G * O + go]
+ = (int32_t)q;
+ comp_ithr[ld * G * O + go] += (int32_t)q;
+ }
+ }
+ }
+ });
+ parallel_nd(L * D * G * O,
+ [&](int s) { comp[s] = saturate<float>(reduction[s]); });
+ for (int i = 1; i < I_nthr; i++) {
+ parallel_nd(L * D * G * O, [&](int s) {
+ comp[s] += saturate<float>(
+ reduction[i * L * D * G * O + s]);
+ });
+ }
+ } else {
+ parallel_nd(L * D, G * O, [&](int ld, int go) {
+ int32_t compensation = 0;
+ const float s = scales[(mask == 0) ? 0 : go];
+ PRAGMA_OMP_SIMD()
+ for (int i = 0; i < I; i++) {
+ int8_t q = qz_b0<in_data_t, out_data_t>()(
+ input[ld * G * O * I + go * I + i], s);
+ compensation += (int32_t)q;
+ quantized[ld * G * O * I + go * I + i] = q;
+ }
+ comp[ld * G * O + go] = saturate<float>(compensation);
+ });
+ }
+
+ /* Pack */
+ auto off_igo = [&](int l, int d, int i, int g, int o) {
+ return l * D * I * G * O + d * I * G * O + i * G * O + g * O + o;
+ };
+ auto off_goi = [&](int l, int d, int i, int g, int o) {
+ return l * D * G * O * I + d * G * O * I + g * O * I + o * I + i;
+ };
+ int n_parts = output_d.rnn_packed_desc().n_parts;
+ const size_t *size_packed_cell
+ = output_d.rnn_packed_desc().part_pack_size;
+ const int *parts = output_d.rnn_packed_desc().parts;
+ const int n = output_d.rnn_packed_desc().n;
+ char *to_pack = output;
+ for (int l = 0; l < L; l++) {
+ for (int d = 0; d < D; d++) {
+ for (int p = 0; p < n_parts; p++) {
+ int g = (p > 0) ? parts[p - 1] : 0;
+ int m_p = parts[p] * O;
+ int k_p = I;
+ cblas_gemm_s8u8s32_pack(CblasColMajor, CblasAMatrix,
+ is_igo ? CblasNoTrans : CblasTrans, m_p, n, k_p,
+ &quantized[is_igo ? off_igo(l, d, 0, g, 0) :
+ off_goi(l, d, g, 0, 0)],
+ is_igo ? G * O : I, to_pack);
+ to_pack += size_packed_cell[p];
+ }
+ }
+ }
+#endif
+ return status::success;
+ }
+
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+template <>
+struct rnn_weights_reorder_t<data_type::f32, data_type::f32>
+ : public cpu_primitive_t {
+ struct pd_t : public cpu_reorder_pd_t {
+ using cpu_reorder_pd_t::cpu_reorder_pd_t;
+
+ DECLARE_COMMON_PD_T("rnn_weights_reorder", rnn_weights_reorder_t);
+
+ static status_t create(reorder_pd_t **reorder_pd,
+ engine_t *engine, const primitive_attr_t *attr,
+ engine_t *src_engine, const memory_desc_t *src_md,
+ engine_t *dst_engine, const memory_desc_t *dst_md) {
+#if !USE_MKL_PACKED_GEMM
+ return status::unimplemented;
+#endif
+ const memory_desc_wrapper id(src_md), od(dst_md);
+ bool args_ok = true
+ && id.data_type() == data_type::f32
+ && od.data_type() == data_type::f32
+ && od.format_kind() == format_kind::rnn_packed
+ && utils::one_of(od.rnn_packed_desc().format,
+ mkldnn_ldigo_p, mkldnn_ldgoi_p)
+ && attr->has_default_values();
+ if (!args_ok) return status::invalid_arguments;
+
+ format_tag_t itag = id.matches_one_of_tag(
+ format_tag::ldigo, format_tag::ldgoi);
+ if (itag == format_tag::undef) return status::invalid_arguments;
+
+ const int mask = attr->rnn_weights_qparams_.mask_;
+ if (!utils::one_of(mask, 0, 3)) return status::unimplemented;
+
+ auto _pd = new pd_t(engine, attr, src_engine, src_md, dst_engine,
+ dst_md);
+ if (_pd == nullptr) return out_of_memory;
+ if (_pd->init() != success) { delete _pd; return unimplemented; }
+ _pd->itag_ = itag;
+ return safe_ptr_assign<reorder_pd_t>(*reorder_pd, _pd);
+ }
+
+ format_tag_t itag_;
+ };
+
+private:
+ rnn_weights_reorder_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+#if USE_MKL_PACKED_GEMM
+ auto input = CTX_IN_MEM(const float *, MKLDNN_ARG_FROM);
+ auto output = CTX_OUT_MEM(float *, MKLDNN_ARG_TO);
+ const memory_desc_wrapper &input_d = pd()->src_md();
+ const memory_desc_wrapper &output_d = pd()->dst_md();
+ const auto &dims = input_d.dims();
+ const rnn_packed_desc_t &rnn_pdata = output_d.rnn_packed_desc();
+ const int L = dims[0];
+ const int D = dims[1];
+ const int I = dims[2];
+ const int G = dims[3];
+ const int O = dims[4];
+
+ /* Pack */
+ bool cross_case = false
+ || (pd()->itag_ == format_tag::ldigo
+ && rnn_pdata.format == mkldnn_ldgoi_p)
+ || (pd()->itag_ == format_tag::ldgoi
+ && rnn_pdata.format == mkldnn_ldigo_p);
+ auto trans = cross_case ? CblasTrans : CblasNoTrans;
+ int n_parts = rnn_pdata.n_parts;
+ const size_t *size_packed_cell = rnn_pdata.part_pack_size;
+ const int *parts = rnn_pdata.parts;
+ const int n = rnn_pdata.n;
+
+ const bool is_igo = pd()->itag_ == format_tag::ldigo;
+ auto off_igo = [&](int l, int d, int i, int g, int o) {
+ return l * D * I * G * O + d * I * G * O + i * G * O + g * O + o;
+ };
+ auto off_goi = [&](int l, int d, int i, int g, int o) {
+ return l * D * G * O * I + d * G * O * I + g * O * I + o * I + i;
+ };
+ for (int l = 0; l < L; l++) {
+ for (int d = 0; d < D; d++) {
+ for (int p = 0; p < n_parts; p++) {
+ int g = (p > 0) ? parts[p - 1] : 0;
+ int m_p = is_igo ? parts[p] * O : I;
+ int k_p = is_igo ? I : parts[p] * O;
+ int ld = is_igo ? G * O : I;
+ cblas_sgemm_pack(CblasColMajor, CblasAMatrix, trans, m_p, n,
+ k_p, 1.0f, &input[is_igo ? off_igo(l, d, 0, g, 0) :
+ off_goi(l, d, 0, g, 0)],
+ ld, output);
+ output += size_packed_cell[p] / sizeof(float);
+ }
+ }
+ }
+#endif
+ return status::success;
+ }
+
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+} // namespace cpu
+} // namespace impl
+} // namespace mkldnn
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_utils.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_utils.cpp
new file mode 100644
index 0000000000..1d60415cbc
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_utils.cpp
@@ -0,0 +1,426 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "c_types_map.hpp"
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+
+#include "ref_rnn.hpp"
+#include "rnn_utils.hpp"
+#include "type_helpers.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::utils;
+using namespace rnn_utils;
+using namespace format_tag;
+using namespace rnn_packed_format;
+using namespace data_type;
+
+bool rnn_utils::is_ldigo(const memory_desc_wrapper &md) {
+ if (md.format_kind() != format_kind::blocked)
+ return false;
+
+ auto blk = md.blocking_desc();
+ auto str = blk.strides;
+ auto dims = md.dims();
+ return md.ndims() == 5 && blk.inner_nblks == 0 && str[4] == 1
+ && str[3] == dims[4] && str[1] == str[2] * dims[2]
+ && str[0] == str[1] * dims[1];
+};
+
+bool rnn_utils::is_ldgoi(const memory_desc_wrapper &md) {
+ if (md.format_kind() != format_kind::blocked)
+ return false;
+
+ auto blk = md.blocking_desc();
+ auto str = blk.strides;
+ auto dims = md.dims();
+ return md.ndims() == 5 && blk.inner_nblks == 0 && str[2] == 1
+ && str[3] == dims[4] * str[4] && str[1] == str[3] * dims[3]
+ && str[0] == str[1] * dims[1];
+};
+
+void rnn_utils::init_conf(rnn_conf_t &rnn, const rnn_desc_t &rd,
+ const memory_desc_wrapper &src_layer_d,
+ const memory_desc_wrapper &src_iter_d,
+ const memory_desc_wrapper &weights_layer_d,
+ const memory_desc_wrapper &weights_iter_d,
+ const memory_desc_wrapper &dst_layer_d) {
+ rnn.is_fwd = utils::one_of(rd.prop_kind, prop_kind::forward_training,
+ prop_kind::forward_inference);
+ rnn.is_training = utils::one_of(
+ rd.prop_kind, prop_kind::forward_training, prop_kind::backward);
+ rnn.is_lbr = rd.cell_desc.cell_kind == mkldnn_gru_linear_before_reset;
+
+ switch (rd.direction) {
+ case mkldnn_unidirectional_left2right: rnn.exec_dir = l2r; break;
+ case mkldnn_unidirectional_right2left: rnn.exec_dir = r2l; break;
+ case mkldnn_bidirectional_concat: rnn.exec_dir = bi_concat; break;
+ case mkldnn_bidirectional_sum: rnn.exec_dir = bi_sum; break;
+ default: break;
+ }
+
+ if (everyone_is(f32, src_layer_d.data_type(), dst_layer_d.data_type(),
+ weights_layer_d.data_type()))
+ rnn.dt_conf = all_f32;
+ else if (dst_layer_d.data_type() == u8) {
+ if (IMPLICATION(src_iter_d.md_, src_iter_d.data_type() == u8))
+ rnn.dt_conf = u8u8u8u8;
+ else
+ rnn.dt_conf = f32u8f32u8;
+ } else {
+ if (IMPLICATION(src_iter_d.md_, src_iter_d.data_type() == u8))
+ rnn.dt_conf = u8u8u8f32;
+ else
+ rnn.dt_conf = f32u8f32f32;
+ }
+
+ rnn.n_layer = weights_layer_d.dims()[0];
+ rnn.n_iter = src_layer_d.dims()[0];
+ rnn.n_dir = weights_layer_d.dims()[1];
+ rnn.n_gates = weights_layer_d.dims()[3];
+ rnn.n_states = mkldnn_rnn_cell_get_states_count(&rd.cell_desc);
+ rnn.n_bias = rnn.n_gates + rnn.is_lbr;
+ rnn.mb = src_layer_d.dims()[1];
+ rnn.sic = weights_iter_d.dims()[2];
+ rnn.slc = weights_layer_d.dims()[2];
+ rnn.dic = weights_layer_d.dims()[4];
+ rnn.dlc = dst_layer_d.dims()[2];
+
+ rnn.gates_ld = rnn.dic * rnn.n_gates;
+ rnn.gates_nld = rnn.mb;
+ rnn.states_nld = rnn.mb;
+
+ /* Set the correct number of weights parts */
+ bool is_orig_gru = rd.cell_desc.cell_kind == alg_kind::vanilla_gru;
+ rnn.n_parts_weights_layer = 1;
+ rnn.parts_weights_layer[0] = rnn.n_gates;
+ rnn.parts_weights_layer[1] = 0;
+
+ rnn.n_parts_weights_iter = is_orig_gru ? 2 : 1;
+ rnn.parts_weights_iter[0] = is_orig_gru ? 2 : rnn.n_gates;
+ rnn.parts_weights_iter[1] = is_orig_gru ? 1 : 0;
+
+ rnn.n_parts_bias = 1;
+ rnn.parts_bias[0] = rnn.n_bias;
+ rnn.parts_bias[1] = 0;
+
+ /* Decide wich gemm implementation to use: packed/nonpacked jit/cblas
+ * and if to mergre gemm across iterations */
+ bool is_int8 = rnn.dt_conf != all_f32;
+ rnn.merge_gemm_layer = ((rnn.is_fwd && rnn.mb < 128) || !rnn.is_fwd)
+ || is_int8;
+ bool is_gru = utils::one_of(rd.cell_desc.cell_kind, alg_kind::vanilla_gru,
+ alg_kind::gru_linear_before_reset);
+ rnn.merge_gemm_iter = !(rnn.is_fwd || is_gru) || is_int8;
+ bool is_inference = !rnn.is_training;
+
+ rnn.use_jit_gemm = !mayiuse(avx512_mic)
+ && ((is_inference && (rnn.n_layer > 1 || rnn.mb < 100))
+ || (rnn.is_training && rnn.dic < 500));
+
+ /* Decide to copy bias */
+ rnn.copy_bias = rnn.dt_conf != all_f32;
+
+#if USE_MKL_PACKED_GEMM
+ rnn.use_layer_packed_gemm
+ = (weights_layer_d.format_kind() == format_kind::any
+ && rnn.slc > 760 && rnn.dic > 760 && is_inference)
+ || is_int8; // packed gemm is the only supported option for int8
+ rnn.use_iter_packed_gemm
+ = (weights_iter_d.format_kind() == format_kind::any && rnn.sic > 760
+ && rnn.dic > 760 && is_inference)
+ || is_int8;
+#else
+ rnn.use_layer_packed_gemm = false;
+ rnn.use_iter_packed_gemm = false;
+#endif
+
+ /* Set packed gemm sizes */
+ if (rnn.use_layer_packed_gemm) {
+ rnn.weights_layer_pack_size = 0;
+ for (int p = 0; p < rnn.n_parts_weights_layer; p++) {
+ int m_p = rnn.is_fwd
+ ? (rnn.parts_weights_layer[p] * rnn.dic)
+ : rnn.slc;
+ int k_p = rnn.is_fwd
+ ? rnn.slc
+ : (rnn.parts_weights_layer[p] * rnn.dic);
+ int n_p = rnn.merge_gemm_layer ? rnn.mb * rnn.n_iter : rnn.mb;
+
+#if USE_MKL_PACKED_GEMM
+ if (rnn.dt_conf == all_f32)
+ rnn.part_weights_layer_pack_size[p] = cblas_sgemm_pack_get_size(
+ CblasAMatrix, m_p, n_p, k_p);
+ else
+ rnn.part_weights_layer_pack_size[p]
+ = cblas_gemm_s8u8s32_pack_get_size(
+ CblasAMatrix, m_p, n_p, k_p);
+#else
+ UNUSED(m_p);
+ UNUSED(k_p);
+ UNUSED(n_p);
+ rnn.part_weights_layer_pack_size[p] = 0;
+#endif
+ rnn.weights_layer_pack_size += rnn.n_layer * rnn.n_dir
+ * rnn.part_weights_layer_pack_size[p];
+ }
+ rnn.weights_layer_comp_offset = rnn.weights_layer_pack_size;
+ rnn.weights_layer_pack_size += rnn.dt_conf == all_f32 ? 0 : rnn.n_layer
+ * rnn.n_dir * rnn.n_gates * rnn.dlc * sizeof(float);
+ }
+
+ if (rnn.use_iter_packed_gemm) {
+ rnn.weights_iter_pack_size = 0;
+ for (int p = 0; p < rnn.n_parts_weights_iter; p++) {
+ int m_p = rnn.is_fwd ? (rnn.parts_weights_iter[p] * rnn.dic) :
+ rnn.sic;
+ int k_p = rnn.is_fwd ? rnn.sic :
+ (rnn.parts_weights_iter[p] * rnn.dic);
+ int n_p = rnn.merge_gemm_iter ? rnn.mb * rnn.n_iter : rnn.mb;
+
+#if USE_MKL_PACKED_GEMM
+ if (rnn.dt_conf == all_f32)
+ rnn.part_weights_iter_pack_size[p] = cblas_sgemm_pack_get_size(
+ CblasAMatrix, m_p, n_p, k_p);
+ else
+ rnn.part_weights_iter_pack_size[p]
+ = cblas_gemm_s8u8s32_pack_get_size(
+ CblasAMatrix, m_p, n_p, k_p);
+#else
+ UNUSED(m_p);
+ UNUSED(k_p);
+ UNUSED(n_p);
+ rnn.part_weights_iter_pack_size[p] = 0;
+#endif
+ rnn.weights_iter_pack_size += rnn.n_layer * rnn.n_dir
+ * rnn.part_weights_iter_pack_size[p];
+ }
+ rnn.weights_iter_comp_offset = rnn.weights_iter_pack_size;
+ rnn.weights_iter_pack_size += rnn.dt_conf == all_f32 ? 0 : rnn.n_layer
+ * rnn.n_dir * rnn.n_gates * rnn.dic * sizeof(float);
+ }
+
+}
+
+void rnn_utils::set_conf(rnn_conf_t &rnn, const rnn_desc_t &rd,
+ const memory_desc_wrapper &weights_layer_d,
+ const memory_desc_wrapper &weights_iter_d,
+ const memory_desc_wrapper &diff_weights_layer_d,
+ const memory_desc_wrapper &diff_weights_iter_d) {
+
+ /* Set leading dimensions for input weights arrays depending on input format
+ */
+ rnn.weights_layer_is_packed
+ = weights_layer_d.format_kind() == format_kind::rnn_packed;
+ rnn.weights_iter_is_packed
+ = weights_iter_d.format_kind() == format_kind::rnn_packed;
+
+ auto set_dims = [&](const memory_desc_wrapper &md, int &ld, int &nld) {
+ ld = 0; nld = 0;
+ if (md.is_blocking_desc()) {
+ if (is_ldigo(md)) {
+ ld = (int)md.blocking_desc().strides[2];
+ nld = md.dims()[2];
+ } else if (is_ldgoi(md)) {
+ ld = (int)md.blocking_desc().strides[4];
+ nld = md.dims()[3] * md.dims()[4];
+ } else
+ assert(!"unsupported weights format");
+ }
+ };
+ set_dims(weights_layer_d, rnn.weights_layer_ld, rnn.weights_layer_nld);
+ set_dims(weights_iter_d, rnn.weights_iter_ld, rnn.weights_iter_nld);
+ if (!rnn.is_fwd) {
+ set_dims(diff_weights_layer_d, rnn.diff_weights_layer_ld,
+ rnn.diff_weights_layer_nld);
+ set_dims(diff_weights_iter_d, rnn.diff_weights_iter_ld,
+ rnn.diff_weights_iter_nld);
+ }
+
+ int sizeof_states_dt
+ = rnn.dt_conf == all_f32 ? sizeof(float) : sizeof(uint8_t);
+ rnn.states_ws_ld
+ = get_good_ld(nstl::max(rnn.slc, nstl::max(rnn.sic, rnn.dic)),
+ sizeof_states_dt);
+ rnn.gates_ws_ld = get_good_ld(rnn.gates_ld, sizeof(float));
+
+ /* Set workspace sizes to store:
+ * states to copmute a pass
+ * diff states to copmute bwd pass (training only)
+ * intermediate results from the gates
+ */
+ rnn.use_workspace = rnn.is_training;
+ rnn.ws_states_size = (size_t)(rnn.n_layer + 1) * rnn.n_dir
+ * (rnn.n_iter + 1) * rnn.mb * rnn.states_ws_ld * sizeof_states_dt;
+ bool is_lstm = rd.cell_desc.cell_kind == mkldnn_vanilla_lstm;
+ rnn.ws_c_states_size = is_lstm
+ ? (size_t)(rnn.n_layer + 1) * rnn.n_dir * (rnn.n_iter + 1) * rnn.mb
+ * rnn.states_ws_ld * sizeof(float)
+ : 0;
+ rnn.ws_diff_states_size = rnn.is_training
+ ? (size_t)(rnn.n_layer + 1) * rnn.n_dir * (rnn.n_iter + 1)
+ * (rnn.n_states + 1) * rnn.mb * rnn.states_ws_ld
+ * sizeof(float)
+ : (size_t)0;
+ rnn.ws_gates_size = (size_t)rnn.n_layer * rnn.n_dir * rnn.n_iter * rnn.mb
+ * rnn.gates_ws_ld * sizeof(float);
+
+ /* set other sizes */
+ rnn.ws_per_cell = (size_t)rnn.is_lbr * rnn.mb * rnn.dic * sizeof(float);
+ rnn.ws_cell_comp_size
+ = rnn.is_lbr || rnn.dt_conf != all_f32
+ ? (size_t) rnn.gates_nld * rnn.gates_ws_ld * sizeof(float)
+ : 0;
+ rnn.ws_grid_comp_size = (size_t)rnn.is_lbr * rnn.is_training * rnn.n_layer
+ * rnn.n_dir * rnn.n_iter * rnn.ws_per_cell * sizeof(float);
+ rnn.ws_bias_size = (size_t)rnn.n_layer * rnn.n_dir * rnn.n_bias * rnn.dic
+ * sizeof(float);
+}
+
+int rnn_utils::get_good_ld(int dim, int sizeof_dt) {
+ // we want matrices leading dimentions to be 64-byte aligned,
+ // and not divisible by 256 to avoid 4K aliasing effects
+ int ld = rnd_up(dim, 64 / sizeof_dt);
+ return (ld % 256 == 0) ? ld + 64 / sizeof_dt : ld;
+}
+
+void rnn_utils::set_offsets(const rnn_conf_t &rnn, size_t &ws_gates_offset,
+ size_t &ws_states_offset, size_t &ws_c_states_offset,
+ size_t &ws_diff_states_offset, size_t &ws_grid_comp_offset,
+ size_t &ws_cell_comp_offset, size_t &ws_bias_offset,
+ size_t &scratchpad_size, size_t &workspace_size) {
+
+ const size_t page_size = 4096; // 2097152;
+ size_t current_offset;
+ /* Mandatory workspaces: go to workspace if use_workspace, scratchpad
+ * otherwise */
+ current_offset = 0; // assumes the workspace base pointer is page aligned
+ ws_gates_offset = current_offset;
+ current_offset += rnn.ws_gates_size;
+
+ current_offset = utils::rnd_up(current_offset, page_size);
+ ws_states_offset = current_offset;
+ current_offset += rnn.ws_states_size;
+
+ current_offset = utils::rnd_up(current_offset, page_size);
+ ws_c_states_offset = current_offset;
+ current_offset += rnn.ws_c_states_size;
+
+ current_offset = utils::rnd_up(current_offset, page_size);
+ ws_diff_states_offset = current_offset;
+ current_offset += rnn.ws_diff_states_size;
+
+ current_offset = utils::rnd_up(current_offset, page_size);
+ ws_grid_comp_offset = current_offset;
+ current_offset += rnn.ws_grid_comp_size;
+
+ current_offset = utils::rnd_up(current_offset, page_size);
+ ws_cell_comp_offset = current_offset;
+ current_offset += rnn.ws_cell_comp_size;
+
+ workspace_size = rnn.use_workspace ? current_offset : 0;
+
+ /* Optional scratchpads */
+ // Assumes the scratchpad base pointer is page aligned.
+ // If use_workspace, the following goes to scratchpad alone,
+ // otherwise, all goes to scratchpad and continue incrementing offset
+ current_offset = rnn.use_workspace ? 0 : current_offset;
+
+ if (rnn.copy_bias) {
+ current_offset = utils::rnd_up(current_offset, page_size);
+ ws_bias_offset = current_offset;
+ current_offset += rnn.ws_bias_size;
+ }
+
+ scratchpad_size = current_offset;
+}
+
+void rnn_utils::get_scratchpad_and_workspace_sizes(const rnn_conf_t &rnn,
+ size_t &scratchpad_size, size_t &workspace_size) {
+ size_t ws_gates_offset, ws_states_offset, ws_c_states_offset,
+ ws_diff_states_offset, ws_grid_comp_offset, ws_cell_comp_offset,
+ ws_bias_offset;
+ set_offsets(rnn, ws_gates_offset, ws_states_offset, ws_diff_states_offset,
+ ws_c_states_offset, ws_grid_comp_offset, ws_cell_comp_offset,
+ ws_bias_offset, scratchpad_size, workspace_size);
+}
+
+status_t rnn_utils::set_good_strides(
+ memory_desc_t &weights_md, format_tag_t tag) {
+ auto &strides = weights_md.format_desc.blocking.strides;
+ auto dims = weights_md.dims;
+
+ if (tag == ldigo) {
+ strides[2] = rnn_utils::get_good_ld((int)strides[2],
+ (int)types::data_type_size(weights_md.data_type));
+ strides[1] = dims[2] * strides[2];
+ strides[0] = dims[1] * strides[1];
+ } else if (tag == ldgoi) {
+ strides[4] = rnn_utils::get_good_ld((int)strides[4],
+ (int)types::data_type_size(weights_md.data_type));
+ strides[3] = dims[4] * strides[4];
+ strides[1] = dims[3] * strides[3];
+ strides[0] = dims[1] * strides[1];
+ } else
+ return status::unimplemented;
+
+ return status::success;
+}
+
+status_t rnn_utils::set_expected_desc(rnn_conf_t &rnn,
+ memory_desc_t &weights_md, bool is_iter) {
+ using namespace format_tag;
+ bool use_packed_gemm = is_iter
+ ? rnn.use_iter_packed_gemm
+ : rnn.use_layer_packed_gemm;
+ if (use_packed_gemm) {
+ weights_md.format_kind = format_kind::rnn_packed;
+ rnn_packed_desc_t &rnn_pdata = weights_md.format_desc.rnn_packed_desc;
+ rnn_pdata.format = rnn.is_fwd ? mkldnn_ldigo_p : mkldnn_ldgoi_p;
+ if (is_iter) {
+ rnn_pdata.n = rnn.mb;
+ rnn_pdata.n_parts = rnn.n_parts_weights_iter;
+ array_copy(rnn_pdata.parts, rnn.parts_weights_iter,
+ MKLDNN_RNN_MAX_N_PARTS);
+ array_copy(rnn_pdata.part_pack_size,
+ rnn.part_weights_iter_pack_size, MKLDNN_RNN_MAX_N_PARTS);
+ rnn_pdata.offset_compensation = rnn.weights_iter_comp_offset;
+ rnn_pdata.size = rnn.weights_iter_pack_size;
+ } else {
+ rnn_pdata.n = rnn.merge_gemm_layer ? rnn.n_iter * rnn.mb : rnn.mb;
+ rnn_pdata.n_parts = rnn.n_parts_weights_layer;
+ array_copy(rnn_pdata.parts, rnn.parts_weights_layer,
+ MKLDNN_RNN_MAX_N_PARTS);
+ array_copy(rnn_pdata.part_pack_size,
+ rnn.part_weights_layer_pack_size, MKLDNN_RNN_MAX_N_PARTS);
+ rnn_pdata.offset_compensation = rnn.weights_layer_comp_offset;
+ rnn_pdata.size = rnn.weights_layer_pack_size;
+ }
+ } else {
+ CHECK(memory_desc_init_by_tag(weights_md, rnn.is_fwd ? ldigo : ldgoi));
+ // Adjust strides for good leading dimension in GEMM
+ CHECK(set_good_strides(weights_md, rnn.is_fwd ? ldigo : ldgoi));
+ }
+ return status::success;
+}
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_utils.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_utils.hpp
new file mode 100644
index 0000000000..99eb787a64
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/rnn/rnn_utils.hpp
@@ -0,0 +1,225 @@
+/*******************************************************************************
+* Copyright 2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef RNN_UTILS_HPP
+#define RNN_UTILS_HPP
+
+#include "mkldnn.h"
+
+#include "cpu_rnn_pd.hpp"
+
+
+#define rnn_elemwise_sig(f) \
+ void f(const rnn_utils::rnn_conf_t &rnn, acc_data_t *ws_gates_, \
+ src_data_t *states_t_l_, float *c_states_t_l_, \
+ src_data_t *states_tm1_l_, float *c_states_tm1_l_, \
+ float *diff_states_t_l_, float *diff_states_t_lp1_, \
+ float *diff_states_tp1_l_, float *bias_, float *ws_grid_, \
+ float *ws_cell_) const
+
+#define rnn_cell_execution_sig(f) \
+ void f(const rnn_utils::rnn_conf_t &rnn, src_data_t *states_t_l_, \
+ float *c_states_t_l_, float *diff_states_t_l_, \
+ weights_data_t **w_layer_, weights_data_t **w_iter_, \
+ float **bias_, src_data_t *states_t_lm1_, \
+ src_data_t *states_tm1_l_, float *c_states_tm1_l_, \
+ float *diff_states_t_lp1_, float *diff_states_tp1_l_, \
+ float *diff_w_layer_, float *diff_w_iter_, float *diff_bias_, \
+ acc_data_t *ws_gates_, float *ws_grid_, float *ws_cell_) const
+
+#define rnn_grid_execution_sig(f) \
+ void f(const rnn_utils::rnn_conf_t &rnn, weights_data_t **weights_layer_, \
+ weights_data_t **weights_states_, float **bias_, \
+ src_data_t *ws_states_, float *ws_c_states_, \
+ float *ws_diff_states_, acc_data_t *ws_gates_, float *ws_cell_, \
+ float *ws_grid_, float *diff_weights_layer_, \
+ float *diff_weights_iter_, float *diff_bias_) const
+
+#define rnn_gemm_sig(f) \
+ void f(const char transA, const char transB, int m, int n, int k, \
+ const float alpha, const weights_data_t *a_, const int ldA, \
+ const src_data_t *b_, const int ldB, const float beta, \
+ acc_data_t *c_, const int ldC) const
+
+#define rnn_bias_prepare_sig(f) \
+ void f(const rnn_utils::rnn_conf_t &rnn, float **bias_, const float *b_, \
+ float *scratch_bias_) const
+
+#define rnn_bias_finalize_sig(f) \
+ void f(const rnn_utils::rnn_conf_t &rnn, float *scratch_bias_, \
+ const float *w_iter_comp, const float *w_layer_comp) const
+
+#define rnn_weights_assign_sig(f) \
+ void f(const rnn_utils::rnn_conf_t &rnn, const memory_desc_t *md, int nld, \
+ int ld, int OC_size, int IC_size, const int n_parts, \
+ const int *gates_per_part, const size_t *part_weights_pack_size, \
+ weights_data_t **weights_, const weights_data_t *w_, \
+ float **bias_, const float *b_, float *scratch_bias_) const
+
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+namespace rnn_utils {
+
+using namespace mkldnn::impl::utils;
+
+enum execution_direction_t {
+ l2r,
+ r2l,
+ bi_concat,
+ bi_sum,
+};
+
+enum data_type_conf_t {
+ all_f32,
+ u8u8u8f32,
+ f32u8f32f32,
+ u8u8u8u8,
+ f32u8f32u8
+};
+
+struct rnn_conf_t {
+ execution_direction_t exec_dir;
+ data_type_conf_t dt_conf;
+ int n_layer, n_iter, n_dir, n_gates, n_states;
+ int mb;
+ int slc, sic, dic, dlc;
+ int gates_ld, gates_nld, gates_ws_ld;
+ int n_parts_weights_layer, parts_weights_layer[MKLDNN_RNN_MAX_N_PARTS];
+ int n_parts_weights_iter, parts_weights_iter[MKLDNN_RNN_MAX_N_PARTS];
+ int n_bias, n_parts_bias, parts_bias[MKLDNN_RNN_MAX_N_PARTS];
+ size_t part_weights_iter_pack_size[MKLDNN_RNN_MAX_N_PARTS],
+ part_weights_layer_pack_size[MKLDNN_RNN_MAX_N_PARTS];
+ bool weights_layer_is_packed, weights_iter_is_packed;
+ /* Size of packed data in bytes */
+ size_t weights_layer_comp_offset, weights_layer_pack_size,
+ weights_iter_comp_offset, weights_iter_pack_size;
+
+ bool copy_bias;
+ int weights_layer_ld, weights_layer_nld;
+ int diff_weights_layer_ld, diff_weights_layer_nld;
+ int weights_iter_ld, weights_iter_nld;
+ int diff_weights_iter_ld, diff_weights_iter_nld;
+ int states_nld, states_ws_ld;
+ int weights_iter_compensation_size, weights_layer_compensation_size;
+ bool is_fwd, is_training, is_lbr;
+ bool use_workspace;
+
+ /* Size of workspace for each tensor in bytes */
+ size_t ws_gates_size, ws_states_size, ws_c_states_size, ws_diff_states_size,
+ ws_cell_comp_size, ws_grid_comp_size, ws_per_cell, ws_bias_size;
+ bool merge_gemm_iter, merge_gemm_layer, use_jit_gemm, use_layer_packed_gemm,
+ use_iter_packed_gemm;
+};
+
+bool is_ldigo(const memory_desc_wrapper &md);
+bool is_ldgoi(const memory_desc_wrapper &md);
+
+int get_good_ld(int dim, int sizeof_dt);
+
+void init_conf(rnn_conf_t &rnn, const rnn_desc_t &rd,
+ const memory_desc_wrapper &src_layer_d,
+ const memory_desc_wrapper &src_iter_d,
+ const memory_desc_wrapper &weights_layer_d,
+ const memory_desc_wrapper &weights_iter_d,
+ const memory_desc_wrapper &dst_layer_d);
+
+void set_conf(rnn_conf_t &rnn, const rnn_desc_t &rd,
+ const memory_desc_wrapper &weights_layer_d,
+ const memory_desc_wrapper &weights_iter_d,
+ const memory_desc_wrapper &diff_weights_layer_d,
+ const memory_desc_wrapper &diff_weights_iter_d);
+
+void set_offsets(const rnn_conf_t &rnn, size_t &ws_gates_offset,
+ size_t &ws_h_state_offset, size_t &ws_c_state_offset,
+ size_t &ws_diff_states_offset, size_t &ws_grid_comp_offset,
+ size_t &ws_cell_comp_offset, size_t &ws_bias_offset,
+ size_t &scratchpad_size, size_t &workspace_size);
+
+void get_scratchpad_and_workspace_sizes(const rnn_conf_t &rnn,
+ size_t &scratchpad_size, size_t &workspace_size);
+status_t set_expected_desc(
+ rnn_conf_t &rnn, memory_desc_t &weights_md, bool is_iter);
+status_t set_good_strides(memory_desc_t &weights_md, format_tag_t tag);
+
+template <typename T>
+struct ws_gates_aoc {
+ ws_gates_aoc(const rnn_conf_t &rnn, T *data)
+ : gates_(data, rnn.gates_nld, rnn.gates_ws_ld), DIC_(rnn.dic) {}
+ T &operator()(int batch, int gate, int dic) {
+ return gates_(batch, gate * DIC_ + dic);
+ }
+
+private:
+ mkldnn::impl::utils::array_offset_calculator<T, 2> gates_;
+ int DIC_;
+};
+using ws_gates_aoc_t = ws_gates_aoc<float>;
+using ws_gates_aoc_s32_t = ws_gates_aoc<int32_t>;
+
+struct bias_aoc_t {
+ bias_aoc_t(const rnn_conf_t &rnn, const float *data)
+ : bias_(data, rnn.n_bias, rnn.dic) {}
+ const float &operator()(int bias_n, int dic) { return bias_(bias_n, dic); }
+
+private:
+ mkldnn::impl::utils::array_offset_calculator<const float, 2> bias_;
+};
+
+template <typename T>
+struct ws_states_aoc {
+ ws_states_aoc(const rnn_conf_t &rnn, T *data)
+ : state_(data, rnn.states_nld, rnn.states_ws_ld) {}
+ T &operator()(int batch, int dic) { return state_(batch, dic); }
+
+private:
+ mkldnn::impl::utils::array_offset_calculator<T, 2> state_;
+};
+using ws_states_aoc_t = ws_states_aoc<float>;
+using ws_states_aoc_u8_t = ws_states_aoc<uint8_t>;
+
+struct ws_diff_states_aoc_t {
+ ws_diff_states_aoc_t(const rnn_conf_t &rnn, float *data)
+ : diff_states_(data, rnn.n_states + 1, rnn.n_iter + 1, rnn.states_nld,
+ rnn.states_ws_ld) {}
+ float &operator()(int state_n, int batch, int dic) {
+ return diff_states_(state_n, 0, batch, dic);
+ }
+
+private:
+ mkldnn::impl::utils::array_offset_calculator<float, 4> diff_states_;
+};
+
+struct ws_diff_w_iter_aoc_t {
+ ws_diff_w_iter_aoc_t(const rnn_conf_t &rnn, float *data)
+ : diff_weights_iter_(
+ data, rnn.diff_weights_iter_nld, rnn.diff_weights_iter_ld)
+ , DIC_(rnn.dic) {}
+ float &operator()(int sic, int gate, int dic) {
+ return diff_weights_iter_(sic, gate * DIC_ + dic);
+ }
+
+private:
+ mkldnn::impl::utils::array_offset_calculator<float, 2> diff_weights_iter_;
+ int DIC_;
+};
+}
+}
+}
+}
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/simple_concat.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/simple_concat.cpp
new file mode 100644
index 0000000000..0420f87aa5
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/simple_concat.cpp
@@ -0,0 +1,126 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn_thread.hpp"
+
+#include "simple_concat.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace memory_tracking::names;
+
+template <data_type_t data_type>
+status_t simple_concat_t<data_type>::execute(const exec_ctx_t &ctx) const {
+ auto scratchpad = this->scratchpad(ctx);
+ auto iptrs = scratchpad.template get<const data_t *>(key_concat_iptrs);
+ auto optrs = scratchpad.template get<data_t *>(key_concat_optrs);
+ auto nelems_to_copy = scratchpad.template get<dim_t>(key_concat_nelems);
+ auto is = scratchpad.template get<strides_t>(key_concat_istrides);
+
+ const int num_arrs = pd()->n_inputs();
+ const int *perm = pd()->perm_, *iperm = pd()->iperm_;
+ const int concat_dim = pd()->concat_dim();
+ auto o_base_ptr = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ for (int a = 0; a < num_arrs; ++a) {
+ const memory_desc_wrapper i_d(pd()->src_md(a));
+ const memory_desc_wrapper o_d(pd()->src_image_md(a));
+
+ iptrs[a] = CTX_IN_MEM(const data_t *, MKLDNN_ARG_MULTIPLE_SRC + a)
+ + i_d.blk_off(0);
+ optrs[a] = o_base_ptr + o_d.blk_off(0);
+ nelems_to_copy[a] = pd()->nelems_to_concat(i_d);
+ for (int i = 0; i < MKLDNN_MAX_NDIMS; i++) {
+ if (i < perm[concat_dim])
+ is[a][i] = size_t(i_d.blocking_desc().strides[iperm[i]]);
+ else
+ is[a][i] = 0;
+ }
+ }
+
+ const memory_desc_wrapper o_d(pd()->src_image_md(0));
+
+ strides_t os = { 0 };
+ for (int i = 0; i < perm[concat_dim]; i++)
+ os[i] = o_d.blocking_desc().strides[iperm[i]];
+
+ dims_t phys_dims;
+ for (size_t i = 0; i < sizeof(phys_dims)/sizeof(phys_dims[0]); i++)
+ phys_dims[i] = (i < (size_t)perm[concat_dim])
+ ? o_d.dims()[iperm[i]] / pd()->blocks_[iperm[i]] : 1;
+
+ if (perm[concat_dim] == 0) {
+ for (int a = 0; a < num_arrs; ++a) {
+ const data_t *i = &iptrs[a][0];
+ data_t *o = &optrs[a][0];
+ parallel_nd((ptrdiff_t)nelems_to_copy[a],
+ [&](ptrdiff_t e) { o[e] = i[e]; });
+ }
+ } else {
+ parallel_nd(phys_dims[0], phys_dims[1], phys_dims[2], phys_dims[3],
+ phys_dims[4], num_arrs,
+ [&](dim_t n0, dim_t n1, dim_t n2, dim_t n3, dim_t n4, int a) {
+ // XXX: this code may access uninitialized values in is[*][0-4] --
+ // that's why we have to set them to zero although this is
+ // probably benign
+ size_t in_off = is[a][0] * n0 + is[a][1] * n1 + is[a][2] * n2
+ + is[a][3] * n3 + is[a][4] * n4;
+ size_t out_off = os[0] * n0 + os[1] * n1 + os[2] * n2
+ + os[3] * n3 + os[4] * n4;
+ const data_t *i = &iptrs[a][in_off];
+ data_t *o = &optrs[a][out_off];
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+ // The code below performs data copying: o[e] = i[e]
+ // and uses a workaround to make GNU compilers optimize it
+ uint8_t *ptro = reinterpret_cast<uint8_t *>(o);
+ const uint8_t *ptri = reinterpret_cast<const uint8_t *>(i);
+ const dim_t main_part =
+ nelems_to_copy[a] * sizeof(data_t) / sizeof(uint32_t);
+ const dim_t tail_part =
+ nelems_to_copy[a] % sizeof(data_t) / sizeof(uint32_t);
+
+ PRAGMA_OMP_SIMD()
+ for (dim_t e = 0; e < main_part; ++e) {
+ *(reinterpret_cast<uint32_t *>(ptro))
+ = *(reinterpret_cast<const uint32_t *>(ptri));
+ ptro += sizeof(uint32_t);
+ ptri += sizeof(uint32_t);
+ }
+ for (dim_t e = 0; e < tail_part; ++e) {
+ *ptro = *ptri;
+ ++ptro;
+ ++ptri;
+ }
+#else
+ PRAGMA_OMP_SIMD()
+ for (dim_t e = 0; e < nelems_to_copy[a]; ++e) o[e] = i[e];
+#endif
+ });
+ }
+
+ return status::success;
+}
+
+template struct simple_concat_t<data_type::f32>;
+template struct simple_concat_t<data_type::u8>;
+template struct simple_concat_t<data_type::s8>;
+template struct simple_concat_t<data_type::s32>;
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/simple_concat.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/simple_concat.hpp
new file mode 100644
index 0000000000..5177275452
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/simple_concat.hpp
@@ -0,0 +1,155 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef SIMPLE_CONCAT_HPP
+#define SIMPLE_CONCAT_HPP
+
+#include "memory_tracking.hpp"
+
+#include "cpu_concat_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <data_type_t data_type>
+struct simple_concat_t: public cpu_primitive_t {
+ struct pd_t: public cpu_concat_pd_t {
+ using cpu_concat_pd_t::cpu_concat_pd_t;
+
+ pd_t(const pd_t &rhs): cpu_concat_pd_t(rhs) {
+ int ndims = rhs.dst_md_.ndims;
+ utils::array_copy(perm_, rhs.perm_, ndims);
+ utils::array_copy(iperm_, rhs.iperm_, ndims);
+ utils::array_copy(blocks_, rhs.blocks_, ndims);
+ }
+
+ DECLARE_CONCAT_PD_T("simple:any", simple_concat_t);
+
+ status_t init() {
+ const memory_desc_wrapper dst_d(dst_md());
+ bool ok = true
+ && cpu_concat_pd_t::init() == status::success
+ && dst_d.ndims() <= 6;
+ if (!ok) return status::unimplemented;
+
+ for (size_t i = 0; i < src_mds_.size(); ++i) {
+ const memory_desc_wrapper i_d(&src_mds_[i]);
+ const memory_desc_wrapper o_d(&src_image_mds_[i]);
+
+ const int ignore_strides = 0;
+
+ ok = ok
+ && utils::everyone_is(data_type, i_d.data_type(),
+ o_d.data_type())
+ && utils::everyone_is(format_kind::blocked,
+ i_d.format_kind(), o_d.format_kind())
+ && types::blocking_desc_is_equal(i_d.blocking_desc(),
+ o_d.blocking_desc(), ignore_strides)
+ && types::blocking_desc_is_equal(i_d.blocking_desc(),
+ dst_d.blocking_desc(), ignore_strides)
+ && !i_d.is_additional_buffer();
+ if (!ok) return status::unimplemented;
+ }
+
+ dst_d.compute_blocks(blocks_);
+ format_perm();
+
+ // start dim is the first dimension after which the concatenation
+ // would happen contiguously
+ const int start_dim = perm_[concat_dim()];
+
+ // check that contiguous part is indeed contiguous (i.e. dense)
+ if (nelems_to_concat(dst_d) !=
+ dst_d.padded_dims()[concat_dim()] / blocks_[concat_dim()]
+ * dst_d.blocking_desc().strides[concat_dim()])
+ return status::unimplemented;
+
+ // check that all inputs have the same strides for the
+ // contiguous part [concat_dim .. ndims] for the *major* dims.
+ // the block part is already checked above
+ for (size_t i = 0; i < src_mds_.size(); ++i) {
+ const memory_desc_wrapper i_d(&src_mds_[i]);
+ for (int d = start_dim; d < dst_d.ndims(); ++d) {
+ if (dst_d.blocking_desc().strides[iperm_[d]]
+ != i_d.blocking_desc().strides[iperm_[d]])
+ return status::unimplemented;
+ }
+ }
+
+ init_scratchpad();
+
+ return status::success;
+ }
+
+ int perm_[MKLDNN_MAX_NDIMS];
+ int iperm_[MKLDNN_MAX_NDIMS];
+ dims_t blocks_;
+
+ dim_t nelems_to_concat(const memory_desc_wrapper &data_d) const {
+ const int ndims = data_d.ndims();
+
+ dim_t nelems = 1;
+ for (int i = perm_[concat_dim()]; i < ndims; i++)
+ nelems *= data_d.dims()[iperm_[i]] / blocks_[iperm_[i]];
+ for (int i = 0; i < ndims; i++)
+ nelems *= blocks_[i];
+
+ return nelems;
+ }
+
+ private:
+ void format_perm() {
+ const memory_desc_wrapper dst_d(dst_md());
+ const int ndims = dst_d.ndims();
+
+ strides_t strides;
+ utils::array_copy(strides, dst_d.blocking_desc().strides, ndims);
+ for (int i = 0; i < ndims; i++) iperm_[i] = i;
+
+ utils::simultaneous_sort(strides, iperm_, ndims,
+ [](stride_t a, stride_t b) { return b - a; });
+
+ for (int i = 0; i < ndims; i++) perm_[iperm_[i]] = i;
+ }
+
+ void init_scratchpad() {
+ using namespace memory_tracking::names;
+ auto scratchpad = scratchpad_registry().registrar();
+ scratchpad.book(key_concat_iptrs, sizeof(data_t *) * n_inputs());
+ scratchpad.book(key_concat_optrs, sizeof(data_t *) * n_inputs());
+ scratchpad.book(key_concat_nelems, sizeof(dim_t) * n_inputs());
+ scratchpad.book(key_concat_istrides,
+ sizeof(strides_t) * n_inputs());
+ }
+ };
+
+ simple_concat_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override;
+
+ typedef typename prec_traits<data_type>::type data_t;
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/simple_q10n.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/simple_q10n.hpp
new file mode 100644
index 0000000000..e6c3b8d7af
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/simple_q10n.hpp
@@ -0,0 +1,98 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_SIMPLE_Q10N_HPP
+#define CPU_SIMPLE_Q10N_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "math_utils.hpp"
+#include "nstl.hpp"
+#include "type_helpers.hpp"
+#include "utils.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::math;
+
+template <typename out_t>
+inline out_t round_and_saturate(float f)
+{ return math::saturate<out_t>(out_round<int>(f)); }
+
+/* Quantization with alpha == 1 and beta == 0 */
+template <typename in_t, typename out_t, typename enabled = void>
+struct qz_a1b0 {
+ out_t operator()(in_t in)
+ { return round_and_saturate<out_t>((float)in); }
+};
+
+template <typename in_t, typename out_t>
+struct qz_a1b0<in_t, out_t,
+ typename utils::enable_if<true
+ && nstl::is_integral<in_t>::value
+ && !is_subset<in_t, out_t>::value
+ >::type> {
+ out_t operator()(in_t in) { return math::saturate<out_t>(in); }
+};
+
+template <typename in_t, typename out_t>
+struct qz_a1b0<in_t, out_t,
+ typename utils::enable_if<is_subset<in_t, out_t>::value>::type> {
+ out_t operator()(in_t in) { return (out_t)in; }
+};
+
+/* Quantization with alpha == 1 */
+template <typename in_t, typename out_t> struct qz_a1 {
+ out_t operator()(in_t in, out_t out, float beta)
+ { return round_and_saturate<out_t>((float)in + beta * out); }
+};
+
+template <typename in_t> struct qz_a1<in_t, float> {
+ float operator()(in_t in, float out, float beta)
+ { return (float)in + beta * out; }
+};
+
+/* Quantization with beta == 0 */
+template <typename in_t, typename out_t> struct qz_b0 {
+ out_t operator()(in_t in, float alpha)
+ { return round_and_saturate<out_t>(alpha * in); }
+};
+
+template <typename in_t> struct qz_b0<in_t, float> {
+ float operator()(in_t in, float alpha) { return alpha * in; }
+};
+
+/* Quantization */
+template <typename in_t, typename out_t> struct qz {
+ out_t operator()(in_t in, out_t out, float alpha, float beta) {
+ return round_and_saturate<out_t>(
+ alpha * in + (beta ? beta * out : 0));
+ }
+};
+
+template <typename in_t> struct qz<in_t, float> {
+ float operator()(in_t in, float out, float alpha, float beta)
+ { return alpha * in + (beta ? beta * out : 0); }
+};
+
+}
+}
+}
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/simple_reorder.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/simple_reorder.hpp
new file mode 100644
index 0000000000..ff845f5bd3
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/simple_reorder.hpp
@@ -0,0 +1,1022 @@
+/*******************************************************************************
+* Copyright 2016-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef CPU_SIMPLE_REORDER_HPP
+#define CPU_SIMPLE_REORDER_HPP
+
+#include <assert.h>
+
+#include "c_types_map.hpp"
+#include "type_helpers.hpp"
+#include "math_utils.hpp"
+#include "mkldnn_thread.hpp"
+#include "utils.hpp"
+
+#include "tag_traits.hpp"
+#include "cpu_reorder_pd.hpp"
+#include "cpu_primitive.hpp"
+
+#include "simple_q10n.hpp"
+#include "cpu_isa_traits.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+using namespace mkldnn::impl::status;
+using namespace mkldnn::impl::format_tag;
+using namespace mkldnn::impl::data_type;
+
+using bd = block_dim_t;
+using ib = inner_blk_t;
+
+using namespace mkldnn::impl::utils;
+using math::saturate;
+
+template<impl::data_type_t type>
+using data_t = typename prec_traits<type>::type;
+
+template<impl::data_type_t type_i, impl::data_type_t type_o>
+using _qz_a1b0 = qz_a1b0<data_t<type_i>, data_t<type_o>>;
+
+template<impl::data_type_t type_i, impl::data_type_t type_o>
+using _qz = qz<data_t<type_i>, data_t<type_o>>;
+
+namespace fmt_order {
+ const bool keep = true;
+ const bool reverse = false;
+ const bool any = keep;
+}
+
+namespace spec {
+struct direct_copy {};
+struct direct_copy_except_dim_0 {};
+struct reference {};
+struct conv_s8s8 {};
+}
+
+#define SIMPLE_REORDER_TEMPL_DECL \
+ impl::data_type_t type_i, impl::format_tag_t tag_i, \
+ impl::data_type_t type_o, impl::format_tag_t tag_o, bool order_keep
+#define SIMPLE_REORDER_TEMPL_CALL \
+ type_i, tag_i, type_o, tag_o, order_keep
+
+#define DECLARE_COMMON_PARAMS() \
+ const memory_desc_wrapper &input_d = pd->src_md(); \
+ const memory_desc_wrapper &output_d = pd->dst_md(); \
+ const float alpha = pd->alpha(); MAYBE_UNUSED(alpha); \
+ const float beta = pd->beta(); MAYBE_UNUSED(beta);
+
+/* specific reorders: common template */
+template <SIMPLE_REORDER_TEMPL_DECL, typename spec = void>
+struct simple_reorder_impl {};
+
+namespace {
+inline bool simple_fmt_check(bool order_keep, impl::format_tag_t tag_i,
+ impl::format_tag_t tag_o, const memory_desc_wrapper &input_d,
+ const memory_desc_wrapper &output_d) {
+ return input_d.matches_tag(order_keep ? tag_i : tag_o)
+ && output_d.matches_tag(order_keep ? tag_o : tag_i);
+}
+inline bool simple_attr_check(const primitive_attr_t *attr, bool many_scales_support) {
+ if (many_scales_support)
+ return true;
+ return IMPLICATION(attr, attr->output_scales_.mask_ == 0);
+}
+}
+
+/* specific reorders: implementation */
+template <SIMPLE_REORDER_TEMPL_DECL>
+struct simple_reorder_impl<SIMPLE_REORDER_TEMPL_CALL,
+typename utils::enable_if<tag_i == any && (false
+ || tag_o == hwio
+ || tag_o == hwigo)
+ , spec::conv_s8s8>::type>
+{
+ static bool is_applicable(const memory_desc_wrapper &input_d,
+ const memory_desc_wrapper &output_d, const primitive_attr_t *attr)
+ {
+ const size_t D_mask = utils::array_product(input_d.dims(),
+ math::ilog2q(attr->output_scales_.mask_ + 1));
+ const int oc = (input_d.dims()[tag_o == hwigo + 0]);
+ const int g = (tag_o == hwigo) ? (input_d.dims()[0]) : 1;
+
+ return output_d.matches_tag(tag_o)
+ && (output_d.extra().flags & memory_extra_flags::compensation_conv_s8s8)
+ && (input_d.data_type() == f32 || input_d.data_type() == s8)
+ && output_d.data_type() == s8
+ && (D_mask == 1 || D_mask == (size_t)g * oc);
+ }
+
+ static status_t execute(const cpu_reorder_pd_t *pd,
+ const data_t<type_i> *input, data_t<type_o> *output) {
+ DECLARE_COMMON_PARAMS();
+
+ static constexpr bool w_groups = tag_o == hwigo;
+
+ const auto &dims = input_d.dims();
+ const auto &pdims = output_d.padded_dims();
+
+ const int G = w_groups ? dims[0] : 1;
+ const int OC = dims[w_groups + 0];
+ const int IC = dims[w_groups + 1];
+ const int H = dims[w_groups + 2];
+ const int W = dims[w_groups + 3];
+
+ const float *scales = pd->attr()->output_scales_.scales_;
+ const size_t D_mask = utils::array_product(input_d.dims(),
+ math::ilog2q(pd->attr()->output_scales_.mask_ + 1));
+
+ assert(output_d.extra().flags
+ & memory_extra_flags::compensation_conv_s8s8);
+ float adj_scale =
+ (output_d.extra().flags & memory_extra_flags::scale_adjust)
+ ? output_d.extra().scale_adjust : 1.f;
+
+ size_t offset = G * pdims[w_groups + 0] * pdims[w_groups + 1] * H * W;
+ int32_t *cp = reinterpret_cast<int32_t *>(output + offset);
+
+ parallel_nd(G, OC, [&](int g, int oc) {
+ cp[g * OC + oc] = 0;
+ for (int ic = 0; ic < IC; ic++)
+ for (int h = 0; h < H; h++)
+ for (int w = 0; w < W; w++) {
+ auto i = input[input_d.blk_off<!w_groups>(g, oc, ic, h, w)];
+ auto &o = output[output_d.blk_off<!w_groups>(g, oc, ic, h, w)];
+ const float s = scales[(D_mask == 1) ? 0 : g * OC + oc];
+
+ o = qz_b0<data_t<type_i>, data_t<type_o>>()(
+ i, s * adj_scale);
+ cp[g * OC + oc] -= (int32_t)o;
+ }
+ cp [g * OC + oc] *= 128;
+ });
+ return success;
+ }
+};
+
+template <SIMPLE_REORDER_TEMPL_DECL>
+struct simple_reorder_impl<SIMPLE_REORDER_TEMPL_CALL,
+ typename utils::enable_if<
+ (tag_i == goiw && tag_o == gOIw4i16o4i)
+ || (tag_i == oiw && tag_o == OIw4i16o4i)
+ || (tag_i == goihw && tag_o == gOIhw4i16o4i)
+ || (tag_i == oihw && tag_o == OIhw4i16o4i)
+ || (tag_i == goihw && tag_o == gOIhw2i8o4i)
+ || (tag_i == goihw && tag_o == gOIhw4o4i)
+ , spec::conv_s8s8>::type>
+{
+ static bool is_applicable(const memory_desc_wrapper &input_d,
+ const memory_desc_wrapper &output_d, const primitive_attr_t *attr)
+ {
+ const size_t D_mask = utils::array_product(input_d.dims(),
+ math::ilog2q(attr->output_scales_.mask_ + 1));
+ const bool w_groups = !utils::one_of(tag_o, OIw4i16o4i, OIhw4i16o4i);
+ const int oc = (input_d.dims()[w_groups ? 1 : 0]);
+ const int g = w_groups ? input_d.dims()[0] : 1;
+
+ return input_d.matches_tag(tag_i)
+ && output_d.matches_tag(tag_o)
+ && (output_d.extra().flags & memory_extra_flags::compensation_conv_s8s8)
+ && (input_d.data_type() == f32 || input_d.data_type() == s8)
+ && output_d.data_type() == s8
+ && (D_mask == 1 || D_mask == (size_t)g * oc);
+ }
+
+ static status_t execute(const cpu_reorder_pd_t *pd,
+ const data_t<type_i> *input, data_t<type_o> *output) {
+ DECLARE_COMMON_PARAMS();
+
+ static constexpr bool w_groups =
+ !utils::one_of(tag_o, OIw4i16o4i, OIhw4i16o4i);
+ constexpr int is_1d =
+ utils::one_of(tag_o, gOIw4i16o4i, OIw4i16o4i);
+ constexpr int blksize = tag_traits<tag_o>::inner_blks == ib::_4b4c
+ ? 4
+ : tag_traits<tag_o>::inner_blks == ib::_2c8b4c
+ ? 8
+ : 16;
+
+ const auto &_g_oihw_d = order_keep ? input_d : output_d;
+ const auto &dims = input_d.dims();
+ const auto &pdims = order_keep
+ ? output_d.padded_dims()
+ : input_d.padded_dims();
+
+ const int G = w_groups ? dims[0] : 1;
+ const int OC = dims[w_groups + 0];
+ const int NB_OC = pdims[w_groups + 0] / blksize;
+ const int IC = dims[w_groups + 1];
+ const int NB_IC = pdims[w_groups + 1] / blksize;
+ const int H = is_1d ? 1 : dims[w_groups + 2];
+ const int W = dims[w_groups + 3 - is_1d];
+
+ const float *scales = pd->attr()->output_scales_.scales_;
+ const size_t D_mask = utils::array_product(input_d.dims(),
+ math::ilog2q(pd->attr()->output_scales_.mask_ + 1));
+
+ assert(output_d.extra().flags
+ & memory_extra_flags::compensation_conv_s8s8);
+ float adj_scale =
+ (output_d.extra().flags & memory_extra_flags::scale_adjust)
+ ? output_d.extra().scale_adjust : 1.f;
+
+ auto ker = [&](const data_t<type_i> *inp, data_t<type_o> *out,
+ int32_t *c, const float *s, const int oc_block, const int ic_block) {
+# define index AB_or_BC_blk_off<tag_traits<tag_o>::inner_blks>
+
+ for (int ic = 0; ic < ic_block; ++ic) {
+ for (int oc = 0; oc < oc_block; ++oc) {
+ const auto _g_oihw_off =
+ oc * _g_oihw_d.blocking_desc().strides[w_groups + 0]
+ + ic * _g_oihw_d.blocking_desc().strides[w_groups + 1];
+ out[index(oc, ic)]
+ = qz_b0<data_t<type_i>, data_t<type_o>>()(
+ inp[_g_oihw_off], s[oc] * adj_scale);
+ c[oc] -= (128 * (int32_t)(out[index(oc, ic)]));
+ }
+ }
+# undef index
+ };
+
+ constexpr int i_mult = blksize;
+ constexpr int o_mult = 1;
+
+ size_t offset = G * pdims[w_groups+0] * pdims[w_groups+1] * H * W;
+ int32_t *cp = reinterpret_cast<int32_t *>(output + offset);
+ parallel_nd(G * NB_OC * blksize, [&](int i) {
+ cp[i] = 0;
+ });
+
+# define wei_blk_off(md, g, o, i, h, w) \
+ (is_1d ? (md).blk_off<!w_groups>(g, o, i, w) \
+ : (md).blk_off<!w_groups>(g, o, i, h, w))
+
+ parallel_nd(G, NB_OC, [&](int g, int O) {
+ for (int I = 0; I < NB_IC; I++)
+ for (int h = 0; h < H; h++)
+ for (int w = 0; w < W; w++) {
+ auto i = &input[wei_blk_off(
+ input_d, g, i_mult * O, i_mult * I, h, w)];
+ auto o = &output[wei_blk_off(
+ output_d, g, o_mult * O, o_mult * I, h, w)];
+ const int oc_block = nstl::min(blksize, OC - O * blksize);
+ const int ic_block = nstl::min(blksize, IC - I * blksize);
+
+ int _offset = (g * NB_OC + O) * blksize;
+ ker(i, o, (order_keep) ? &cp[_offset] : nullptr,
+ &scales[(D_mask == 1) ? 0 : _offset],
+ oc_block, ic_block);
+ }
+ });
+
+# undef wei_blk_off
+
+ return success;
+ }
+};
+
+template <SIMPLE_REORDER_TEMPL_DECL>
+struct simple_reorder_impl<SIMPLE_REORDER_TEMPL_CALL,
+ typename utils::enable_if<false
+ ||(tag_i == goiw && tag_o == Goiw16g)
+ ||(tag_i == goihw && tag_o == Goihw16g)
+ , spec::conv_s8s8>::type>
+{
+ static bool is_applicable(const memory_desc_wrapper &input_d,
+ const memory_desc_wrapper &output_d, const primitive_attr_t *attr) {
+ const size_t D_mask = utils::array_product(input_d.dims(),
+ math::ilog2q(attr->output_scales_.mask_ + 1));
+ const int oc = input_d.dims()[1];
+ const int g = input_d.dims()[0];
+
+ return true
+ && order_keep
+ && input_d.matches_tag(tag_i)
+ && output_d.matches_tag(tag_o)
+ && (output_d.extra().flags & memory_extra_flags::compensation_conv_s8s8)
+ && (input_d.data_type() == f32 || input_d.data_type() == s8)
+ && output_d.data_type() == s8
+ && (D_mask == 1 || D_mask == (size_t)g * oc);
+ }
+
+ static status_t execute(const cpu_reorder_pd_t *pd,
+ const data_t<type_i> *input, data_t<type_o> *output) {
+ DECLARE_COMMON_PARAMS();
+
+ constexpr bool is_1d = tag_i == goiw;
+ constexpr int blksize = 16;
+
+ const auto &dims = input_d.dims();
+ const auto &pdims = output_d.padded_dims();
+ const int G = dims[0];
+ const int Gp = pdims[0];
+ const int OC = dims[1];
+ const int IC = dims[2];
+ const int H = is_1d ? 1 : dims[3];
+ const int W = dims[4 - is_1d];
+
+ const size_t D_mask = utils::array_product(input_d.dims(),
+ math::ilog2q(pd->attr()->output_scales_.mask_ + 1));
+ const float *scales = pd->attr()->output_scales_.scales_;
+
+ assert(output_d.extra().flags
+ & memory_extra_flags::compensation_conv_s8s8);
+ float adj_scale =
+ (output_d.extra().flags & memory_extra_flags::scale_adjust)
+ ? output_d.extra().scale_adjust : 1.f;
+
+ auto ker = [&](const data_t<type_i> *inp, data_t<type_o> *out,
+ int32_t *cp, const float *s, const int g_block) {
+ PRAGMA_OMP_SIMD()
+ for (int g = 0; g < g_block; g++) {
+ const auto i_off = g * input_d.blocking_desc().strides[0];
+ out[g] = qz_b0<data_t<type_i>, data_t<type_o>>()(
+ inp[i_off], s[g * OC] * adj_scale);
+ cp[g * OC] -= 128 * (int32_t)(out[g]);
+ }
+ };
+
+ size_t cp_offset = output_d.size() - output_d.additional_buffer_size();
+ int32_t *cp = reinterpret_cast<int32_t *>(output + cp_offset);
+ parallel_nd((Gp/blksize) * OC, [&](int ib) {
+ PRAGMA_OMP_SIMD()
+ for (int i = 0; i < blksize; i++)
+ cp[ib * blksize + i] = 0;
+ });
+
+# define wei_blk_off(md, g, o, i, h, w) \
+ (is_1d ? (md).blk_off(g, o, i, w) : (md).blk_off(g, o, i, h, w))
+
+ parallel_nd(Gp/blksize, OC, [&](int gb, int O) {
+ for (int I = 0; I < IC; I++) {
+ for (int h = 0; h < H; h++)
+ for (int w = 0; w < W; w++)
+ {
+ const int g_block = nstl::min(G - gb * blksize, blksize);
+ const auto inp = &input[wei_blk_off(
+ input_d, gb * blksize, O, I, h, w)];
+ const auto out = &output[wei_blk_off(
+ output_d, gb, O, I, h, w)];
+ int offset = gb * blksize + O;
+ ker(inp, out, &cp[offset],
+ &scales[(D_mask == 1) ? 0 : offset], g_block);
+ }
+ }
+ });
+
+# undef wei_blk_off
+
+ return success;
+ }
+};
+
+/* reorders with tail support */
+
+template <SIMPLE_REORDER_TEMPL_DECL>
+struct simple_reorder_impl<SIMPLE_REORDER_TEMPL_CALL,
+typename utils::enable_if<false
+ || (tag_i == nCdhw8c && tag_o == nCdhw16c)
+ || (tag_i == nChw8c && tag_o == nChw16c)
+ || (tag_i == nCw8c && tag_o == nCw16c)
+ >::type>
+{
+ static bool is_applicable(const memory_desc_wrapper &input_d,
+ const memory_desc_wrapper &output_d, const primitive_attr_t *attr)
+ {
+ return simple_fmt_check(order_keep, tag_i, tag_o, input_d, output_d)
+ && simple_attr_check(attr, false);
+ }
+
+ static status_t execute(const cpu_reorder_pd_t *pd,
+ const data_t<type_i> *input, data_t<type_o> *output) {
+ DECLARE_COMMON_PARAMS();
+
+ constexpr int is_1d = tag_i == nCw8c;
+ constexpr int is_3d = tag_i == nCdhw8c;
+ constexpr int blksize_16 = 16;
+ constexpr int blksize_8 = 8;
+ constexpr int ic_mult = order_keep ? 2 : 1;
+ constexpr int oc_mult = order_keep ? 1 : 2;
+
+ const auto &dims = input_d.dims();
+ const auto &pdims = order_keep ? output_d.padded_dims()
+ : input_d.padded_dims();
+
+ const int C = dims[1];
+ const int D = is_3d ? dims[2] : 1;
+ const int H = is_1d ? 1 : dims[2 + is_3d];
+ const int W = dims[3 + is_3d - is_1d];
+
+ auto ker = [&](const data_t<type_i> *i, data_t<type_o> *o,
+ const int block_16) {
+ const int nb = (block_16 - 1) / blksize_8 + 1;
+ if (alpha == 1.0 && beta == 0.0) {
+ for (int b = 0; b < nb; ++b) {
+ const ptrdiff_t i_off = order_keep ? b : b * blksize_8;
+ const ptrdiff_t o_off = order_keep ? b * blksize_8 : b;
+ const int block_8 = nstl::min(blksize_8,
+ block_16 - b * blksize_8);
+ for (int c = 0; c < block_8; ++c) {
+ o[o_off + c] = _qz_a1b0<type_i, type_o>()(
+ i[i_off + c]);
+ }
+ }
+ } else {
+ for (int b = 0; b < nb; ++b) {
+ const ptrdiff_t i_off = order_keep ? b : b * blksize_8;
+ const ptrdiff_t o_off = order_keep ? b * blksize_8 : b;
+ const int block_8 = nstl::min(blksize_8,
+ block_16 - b * blksize_8);
+ for (int c = 0; c < block_8; ++c) {
+ o[o_off + c] = _qz<type_i, type_o>()(i[i_off + c],
+ o[o_off + c], alpha, beta);
+ }
+ }
+ }
+ };
+
+# define data_blk_off(md, n, c, d, h, w) \
+ ( is_1d ? (md).blk_off(n, c, w) \
+ : is_3d ? (md).blk_off(n, c, d, h, w) : (md).blk_off(n, c, h, w))
+
+ parallel_nd(dims[0], pdims[1] / blksize_16, D, H, W,
+ [&](int n, int nb_c, int d, int h, int w) {
+ auto i = &input[data_blk_off(input_d, n, ic_mult * nb_c, d, h, w)];
+ auto o = &output[data_blk_off(output_d, n, oc_mult * nb_c, d, h, w)];
+ const int block_16 = nstl::min(blksize_16, C - nb_c * blksize_16);
+ ker(i, o, block_16);
+ });
+
+# undef data_blk_off
+
+ return success;
+ }
+};
+
+#define PLAIN_TO_BLOCKED_IS_APPLICABLE() \
+ static bool is_applicable(const memory_desc_wrapper &input_d, \
+ const memory_desc_wrapper &output_d, const primitive_attr_t *attr) { \
+ return simple_attr_check(attr, false) && (order_keep \
+ ? output_d.matches_tag(tag_o) && input_d.is_plain() \
+ : input_d.matches_tag(tag_o) && output_d.is_plain()); \
+ }
+
+template <SIMPLE_REORDER_TEMPL_DECL>
+struct simple_reorder_impl<SIMPLE_REORDER_TEMPL_CALL,
+typename utils::enable_if<tag_i == any
+ && (tag_traits<tag_o>::block_dims == bd::_A
+ || tag_traits<tag_o>::block_dims == bd::_B)
+ && tag_traits<tag_o>::ndims >= 3
+ && tag_traits<tag_o>::ndims <= 6
+ >::type>
+{
+ PLAIN_TO_BLOCKED_IS_APPLICABLE();
+
+ static status_t execute(const cpu_reorder_pd_t *pd,
+ const data_t<type_i> *input, data_t<type_o> *output) {
+ DECLARE_COMMON_PARAMS();
+
+ const auto &flat_d = order_keep ? input_d : output_d;
+ const auto &block_d = order_keep ? output_d : input_d;
+ const auto &dims = input_d.dims();
+ const auto &pdims = block_d.padded_dims();
+
+ constexpr int ndims = tag_traits<tag_o>::ndims;
+ constexpr int blk_idx = tag_traits<tag_o>::block_dims == bd::_A ? 0 : 1;
+
+ const dim_t H0 = dims[0];
+ const dim_t H1 = dims[1];
+ const dim_t M0 = ndims >= 6 ? dims[ndims - 4] : 1;
+ const dim_t M1 = ndims >= 5 ? dims[ndims - 3] : 1;
+ const dim_t M2 = ndims >= 4 ? dims[ndims - 2] : 1;
+ const dim_t L = dims[ndims - 1];
+ const dim_t l_blk_stride = block_d.blocking_desc().strides[ndims - 1];
+
+ constexpr int blksize = false ? 0
+ : utils::one_of(tag_traits<tag_o>::inner_blks, ib::_4a, ib::_4b) ? 4
+ : utils::one_of(tag_traits<tag_o>::inner_blks, ib::_8a, ib::_8b) ? 8
+ : 16;
+
+ auto ker = [&](const data_t<type_i> *i, data_t<type_o> *o, int block) {
+ if (alpha == 1.0 && beta == 0.0) {
+ for (int l = 0; l < L; ++l)
+ for (int blk = 0; blk < block; ++blk) {
+ const dim_t flat_off = 0
+ + blk * flat_d.blocking_desc().strides[blk_idx]
+ + l * flat_d.blocking_desc().strides[ndims - 1];
+ if (order_keep) {
+ o[l * l_blk_stride + blk] = _qz_a1b0<type_i, type_o>()(
+ i[flat_off]);
+ } else {
+ o[flat_off] = _qz_a1b0<type_i, type_o>()(
+ i[l * l_blk_stride + blk]);
+ }
+ }
+ } else {
+ for (int l = 0; l < L; ++l)
+ for (int blk = 0; blk < block; ++blk) {
+ const dim_t flat_off = 0
+ + blk * flat_d.blocking_desc().strides[blk_idx]
+ + l * flat_d.blocking_desc().strides[ndims - 1];
+ if (order_keep) {
+ o[l * l_blk_stride + blk] = _qz<type_i, type_o>()(
+ i[flat_off], o[l * blksize + blk],
+ alpha, beta);
+ } else {
+ o[flat_off] = _qz<type_i, type_o>()(
+ i[l * l_blk_stride + blk], o[flat_off],
+ alpha, beta);
+ }
+ }
+ }
+ };
+
+# define off(md, h0, h1, m0, m1, m2) \
+ (ndims >= 6 ? (md).blk_off(h0, h1, m0, m1, m2) \
+ : ndims >= 5 ? (md).blk_off(h0, h1, m1, m2) \
+ : ndims >= 4 ? (md).blk_off(h0, h1, m2) \
+ : /* ndims >= 3 ? */ (md).blk_off(h0, h1))
+
+ constexpr int i_mult = order_keep ? blksize : 1;
+ constexpr int o_mult = order_keep ? 1 : blksize;
+
+ if (blk_idx == 0) {
+ const dim_t BH0 = pdims[0] / blksize;
+ parallel_nd(BH0, H1, M0, M1, M2,
+ [&](dim_t bh0, dim_t h1, dim_t m0, dim_t m1, dim_t m2) {
+ auto i = &input[off(input_d, bh0 * i_mult, h1, m0, m1, m2)];
+ auto o = &output[off(output_d, bh0 * o_mult, h1, m0, m1, m2)];
+ const int block = nstl::min<int>(blksize, H0 - bh0 * blksize);
+ ker(i, o, block);
+ });
+ } else if (blk_idx == 1) {
+ const dim_t BH1 = pdims[1] / blksize;
+ parallel_nd(H0, BH1, M0, M1, M2,
+ [&](dim_t h0, dim_t bh1, dim_t m0, dim_t m1, dim_t m2) {
+ auto i = &input[off(input_d, h0, bh1 * i_mult, m0, m1, m2)];
+ auto o = &output[off(output_d, h0, bh1 * o_mult, m0, m1, m2)];
+ const int block = nstl::min<int>(blksize, H1 - bh1 * blksize);
+ ker(i, o, block);
+ });
+ } else {
+ assert(!"unimplemented");
+ }
+
+# undef off
+
+ return success;
+ }
+};
+
+template <SIMPLE_REORDER_TEMPL_DECL>
+struct simple_reorder_impl<SIMPLE_REORDER_TEMPL_CALL,
+typename utils::enable_if<tag_i == any
+ && (tag_traits<tag_o>::block_dims == bd::_AB
+ || tag_traits<tag_o>::block_dims == bd::_BC)
+ && IMPLICATION(tag_traits<tag_o>::block_dims == bd::_AB,
+ tag_traits<tag_o>::ndims >= 3 && tag_traits<tag_o>::ndims <= 5)
+ && IMPLICATION(tag_traits<tag_o>::block_dims == bd::_BC,
+ tag_traits<tag_o>::ndims >= 4 && tag_traits<tag_o>::ndims <= 6)
+ >::type>
+{
+ PLAIN_TO_BLOCKED_IS_APPLICABLE();
+
+ static status_t execute(const cpu_reorder_pd_t *pd,
+ const data_t<type_i> *input, data_t<type_o> *output) {
+ DECLARE_COMMON_PARAMS();
+
+ const auto &flat_d = order_keep ? input_d : output_d;
+ const auto &dims = input_d.dims();
+ const auto &pdims = order_keep
+ ? output_d.padded_dims()
+ : input_d.padded_dims();
+
+ constexpr int ndims = tag_traits<tag_o>::ndims;
+
+ static constexpr bool with_g = tag_traits<tag_o>::block_dims == bd::_BC;
+ const dim_t G = with_g ? dims[0] : 1;
+
+ const dim_t H0 = dims[0 + with_g];
+ const dim_t H1 = dims[1 + with_g];
+
+ const dim_t M0 = ndims >= 5 + with_g ? dims[ndims - 3] : 1;
+ const dim_t M1 = ndims >= 4 + with_g ? dims[ndims - 2] : 1;
+ const dim_t M2 = ndims >= 3 + with_g ? dims[ndims - 1] : 1;
+
+ constexpr int blksize_0 = false ? 0
+ : utils::one_of(tag_traits<tag_o>::inner_blks,
+ ib::_4b4a, ib::_4b4c, ib::_4c4b)
+ ? 4
+ : utils::one_of(tag_traits<tag_o>::inner_blks,
+ ib::_8a8b, ib::_8b8a, ib::_8b8c, ib::_8c8b, ib::_2c8b4c)
+ ? 8
+ : utils::one_of(tag_traits<tag_o>::inner_blks,
+ ib::_16a16b, ib::_16a4b, ib::_16b16a, ib::_16b4c,
+ ib::_16b16c, ib::_16c16b, ib::_8a16b2a, ib::_4b16a4b,
+ ib::_8b16a2b, ib::_8b16c2b, ib::_4c16b4c, ib::_8c16b2c)
+ ? 16 : INT_MIN;
+
+ constexpr int blksize_1 = utils::one_of(tag_traits<tag_o>::inner_blks,
+ ib::_8a8b, ib::_8b8a, ib::_8b8c, ib::_8c8b, ib::_2c8b4c)
+ ? 8
+ : utils::one_of(tag_traits<tag_o>::inner_blks,
+ ib::_16a16b, ib::_16b16a, ib::_16b16c, ib::_16c16b,
+ ib::_8a16b2a, ib::_4b16a4b, ib::_8b16a2b, ib::_8b16c2b,
+ ib::_4c16b4c, ib::_8c16b2c)
+ ? 16
+ : utils::one_of(tag_traits<tag_o>::inner_blks,
+ ib::_4b4a, ib::_4b4c, ib::_4c4b,
+ ib::_16a4b, ib::_16b4c)
+ ? 4
+ : INT_MIN;
+
+ const dim_t NB_H0 = pdims[0 + with_g] / blksize_0;
+ const dim_t NB_H1 = pdims[1 + with_g] / blksize_1;
+
+ auto ker = [&](const data_t<type_i> *i, data_t<type_o> *o,
+ const int block_h0, const int block_h1) {
+# define blk_off AB_or_BC_blk_off<tag_traits<tag_o>::inner_blks>
+
+ if (alpha == 1.0 && beta == 0.0) {
+ for (int h0 = 0; h0 < block_h0; ++h0)
+ for (int h1 = 0; h1 < block_h1; ++h1) {
+ const dim_t flat_off = 0
+ + h0 * flat_d.blocking_desc().strides[with_g + 0]
+ + h1 * flat_d.blocking_desc().strides[with_g + 1];
+ if (order_keep) {
+ o[blk_off(h0, h1)] = _qz_a1b0<type_i, type_o>()(
+ i[flat_off]);
+ } else {
+ o[flat_off] = _qz_a1b0<type_i, type_o>()(
+ i[blk_off(h0, h1)]);
+ }
+ }
+ } else {
+ for (int h0 = 0; h0 < block_h0; ++h0)
+ for (int h1 = 0; h1 < block_h1; ++h1) {
+ const dim_t flat_off = 0
+ + h0 * flat_d.blocking_desc().strides[with_g + 0]
+ + h1 * flat_d.blocking_desc().strides[with_g + 1];
+ if (order_keep) {
+ o[blk_off(h0, h1)] = _qz<type_i, type_o>()(i[flat_off],
+ o[blk_off(h0, h1)], alpha, beta);
+ } else {
+ o[flat_off] = _qz<type_i, type_o>()(i[blk_off(h0, h1)],
+ o[flat_off], alpha, beta);
+ }
+ }
+ }
+
+# undef blk_off
+ };
+
+ constexpr int i_mult_0 = order_keep ? blksize_0 : 1;
+ constexpr int o_mult_0 = order_keep ? 1 : blksize_0;
+
+ constexpr int i_mult_1 = order_keep ? blksize_1 : 1;
+ constexpr int o_mult_1 = order_keep ? 1 : blksize_1;
+
+# define off(md, g, h0, h1, m0, m1, m2) \
+ (ndims >= 5 + with_g ? (md).blk_off<!with_g>(g, h0, h1, m0, m1, m2) \
+ : ndims >= 4 + with_g ? (md).blk_off<!with_g>(g, h0, h1, m1, m2) \
+ : /* ndims >= 3 + with_g ? */ (md).blk_off<!with_g>(g, h0, h1, m2))
+
+ parallel_nd(G, NB_H0, NB_H1, M0, M1, M2,
+ [&](dim_t g, dim_t nb_h0, dim_t nb_h1, dim_t m0, dim_t m1, dim_t m2) {
+ auto i = &input[off(input_d,
+ g, i_mult_0 * nb_h0, i_mult_1 * nb_h1, m0, m1, m2)];
+ auto o = &output[off(output_d,
+ g, o_mult_0 * nb_h0, o_mult_1 * nb_h1, m0, m1, m2)];
+ const int block_h0 = nstl::min<int>(blksize_0, H0 - nb_h0 * blksize_0);
+ const int block_h1 = nstl::min<int>(blksize_1, H1 - nb_h1 * blksize_1);
+ ker(i, o, block_h0, block_h1);
+ });
+
+# undef off
+
+ return success;
+ }
+};
+
+/* generic and direct-copy reorders */
+
+template <SIMPLE_REORDER_TEMPL_DECL>
+struct simple_reorder_impl<SIMPLE_REORDER_TEMPL_CALL,
+ typename utils::enable_if<
+ tag_i == any && tag_o == any && order_keep == fmt_order::any,
+ spec::direct_copy>::type>
+{
+ static bool is_applicable(const memory_desc_wrapper &input_d,
+ const memory_desc_wrapper &output_d, const primitive_attr_t *attr) {
+ /* FIXME: is the formula correct? */
+ return input_d.similar_to(output_d, true, false, 0)
+ && input_d.is_dense() && output_d.is_dense()
+ && simple_attr_check(attr, false);
+ }
+
+ static status_t execute(const cpu_reorder_pd_t *pd,
+ const data_t<type_i> *input, data_t<type_o> *output) {
+ DECLARE_COMMON_PARAMS();
+
+ assert(input_d.is_dense());
+
+ input += input_d.blk_off(0);
+ output += output_d.blk_off(0);
+
+ const size_t nelems = input_d.nelems();
+
+ constexpr int block_size = 16;
+ const auto num_blocks = nelems / block_size;
+ const auto rem_elems = nelems % block_size;
+
+ parallel(0, [&](const int ithr, const int nthr) {
+ size_t start{0}, end{0};
+ balance211(num_blocks, nthr, ithr, start, end);
+ start = start * block_size;
+ end = end * block_size;
+
+ if (alpha == 1.0 && beta == 0.0) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start; e < end; ++e) {
+ output[e] = qz_a1b0<data_t<type_i>, data_t<type_o>>()
+ (input[e]);
+ }
+ } else if (alpha == 1.0) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start; e < end; ++e) {
+ output[e] = qz_a1<data_t<type_i>, data_t<type_o>>()
+ (input[e], output[e], beta);
+ }
+ } else if (beta == 0.0) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start; e < end; ++e) {
+ output[e] = qz_b0<data_t<type_i>, data_t<type_o>>()
+ (input[e], alpha);
+ }
+ } else {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start; e < end; ++e) {
+ output[e] = qz<data_t<type_i>, data_t<type_o>>()
+ (input[e], output[e], alpha, beta);
+ }
+ }
+
+ if (rem_elems != 0 && ithr == nthr - 1){
+ if (alpha == 1.0 && beta == 0.0) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = nelems - rem_elems; e < nelems; ++e) {
+ output[e] = qz_a1b0<data_t<type_i>,
+ data_t<type_o>>()(input[e]);
+ }
+ } else if (alpha == 1.0) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = nelems - rem_elems; e < nelems; ++e) {
+ output[e] = qz_a1<data_t<type_i>,
+ data_t<type_o>>()(input[e], output[e], beta);
+ }
+ } else if (beta == 0.0) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = nelems - rem_elems; e < nelems; ++e) {
+ output[e] = qz_b0<data_t<type_i>,
+ data_t<type_o>>()(input[e], alpha);
+ }
+ } else {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = nelems - rem_elems; e < nelems; ++e) {
+ output[e] = qz<data_t<type_i>, data_t<type_o>>()
+ (input[e], output[e], alpha, beta);
+ }
+ }
+ }
+ });
+ return success;
+ }
+};
+
+template <SIMPLE_REORDER_TEMPL_DECL>
+struct simple_reorder_impl<SIMPLE_REORDER_TEMPL_CALL,
+ typename utils::enable_if<
+ tag_i == any && tag_o == any && order_keep == fmt_order::any,
+ spec::direct_copy_except_dim_0>::type>
+{
+ static bool is_applicable(const memory_desc_wrapper &input_d,
+ const memory_desc_wrapper &output_d, const primitive_attr_t *attr) {
+ auto is_dense_no_0 = [](const memory_desc_wrapper &data_d) {
+ return nelems_no_dim_0(data_d) == _size_no_dim_0(data_d);
+ };
+ /* FIXME: is the formula correct? */
+ return input_d.similar_to(output_d, true, false, 1)
+ && is_dense_no_0(input_d) && is_dense_no_0(output_d)
+ && simple_attr_check(attr, false);
+ }
+
+ static status_t execute(const cpu_reorder_pd_t *pd,
+ const data_t<type_i> *input, data_t<type_o> *output) {
+ DECLARE_COMMON_PARAMS();
+
+ input += input_d.blk_off(0);
+ output += output_d.blk_off(0);
+
+ const int N = input_d.dims()[0];
+ const dim_t is = input_d.blocking_desc().strides[0];
+ const dim_t os = output_d.blocking_desc().strides[0];
+ const dim_t nelems_no_d0 = nelems_no_dim_0(input_d);
+ const dim_t work_amount = N * nelems_no_d0;
+
+ if (alpha == 1.0 && beta == 0.0) {
+ parallel(0, [&](const int ithr, const int nthr) {
+ dim_t n{0}, dim1_s{0};
+ dim_t start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+ nd_iterator_init(start, n, N, dim1_s, nelems_no_d0);
+ while(start < end) {
+ dim_t work_rem = end - start;
+ dim_t dim1_e = dim1_s + work_rem > nelems_no_d0
+ ? nelems_no_d0 : dim1_s + work_rem;
+ PRAGMA_OMP_SIMD()
+ for (dim_t e = dim1_s; e < dim1_e; ++e) {
+ output[os * n + e] = _qz_a1b0<type_i, type_o>()(
+ input[is * n + e]);
+ }
+ nd_iterator_jump(start, end, n, N, dim1_s, nelems_no_d0);
+ }
+ });
+ } else {
+ parallel(0, [&](const int ithr, const int nthr) {
+ dim_t n{0}, dim1_s{0};
+ dim_t start{0}, end{0};
+ balance211(work_amount, nthr, ithr, start, end);
+ nd_iterator_init(start, n, N, dim1_s, nelems_no_d0);
+ while(start < end) {
+ dim_t work_rem = end - start;
+ dim_t dim1_e =
+ dim1_s + work_rem > nelems_no_d0 ? nelems_no_d0
+ : dim1_s + work_rem;
+ PRAGMA_OMP_SIMD()
+ for (dim_t e = dim1_s; e < dim1_e; ++e){
+ output[os * n + e] = _qz<type_i, type_o>()(
+ input[is * n + e], output[os * n + e], alpha,
+ beta);
+ }
+ nd_iterator_jump(start, end, n, N, dim1_s, nelems_no_d0);
+ }
+ });
+ }
+
+ return success;
+ }
+
+private:
+ static dim_t nelems_no_dim_0(const memory_desc_wrapper &data_d) {
+ const int ndims = data_d.ndims();
+ if (ndims <= 1) return 1;
+ return utils::array_product(data_d.dims() + 1, data_d.ndims() - 1);
+ }
+
+ static dim_t _size_no_dim_0(const memory_desc_wrapper &data_d) {
+ dims_t blocks;
+ data_d.compute_blocks(blocks);
+
+ const auto &blk = data_d.blocking_desc();
+
+ dim_t blk_size = 1;
+ for (int iblk = 0; iblk < blk.inner_nblks; ++iblk)
+ blk_size *= blk.inner_blks[iblk];
+
+ dim_t max_size = blk_size;
+ for (int d = 1; d < data_d.ndims(); ++d) {
+ max_size = nstl::max(max_size,
+ data_d.padded_dims()[d] / blocks[d] * blk.strides[d]);
+ }
+
+ return max_size;
+ }
+};
+
+template <SIMPLE_REORDER_TEMPL_DECL>
+struct simple_reorder_impl<SIMPLE_REORDER_TEMPL_CALL,
+ typename utils::enable_if<
+ tag_i == any && tag_o == any && order_keep == fmt_order::any,
+ spec::reference>::type>
+{
+ static bool is_applicable(const memory_desc_wrapper &input_d,
+ const memory_desc_wrapper &output_d, const primitive_attr_t *attr) {
+ /* supported smask: 0x0...011..10...0,
+ * i.e. 1 should be contiguous */
+ int smask = attr ? attr->output_scales_.mask_ : 0;
+ for (; smask > 0 && !(smask & 0x1); smask >>= 1);
+ for (; smask > 0 && smask & 0x1; smask >>= 1);
+ return true
+ && input_d.is_blocking_desc()
+ && output_d.is_blocking_desc()
+ && !output_d.is_additional_buffer()
+ && !input_d.is_additional_buffer()
+ && smask == 0;
+ }
+
+ static status_t execute(const cpu_reorder_pd_t *pd,
+ const data_t<type_i> *input, data_t<type_o> *output) {
+ DECLARE_COMMON_PARAMS();
+
+ const size_t nelems = input_d.nelems();
+
+ int ndims_start = 0, ndims_mask = 0;
+ int smask = pd->attr()->output_scales_.mask_;
+ for (; smask > 0 && !(smask & 0x1); smask >>= 1) ++ndims_start;
+ for (; smask > 0 && smask & 0x1; smask >>= 1) ++ndims_mask;
+ assert(smask == 0);
+
+ const ptrdiff_t D_start
+ = utils::array_product(input_d.dims(), ndims_start);
+ const ptrdiff_t D_mask
+ = utils::array_product(input_d.dims() + ndims_start, ndims_mask);
+ const ptrdiff_t D_rest = nelems / D_start / D_mask;
+
+ const float *scales = pd->attr()->output_scales_.scales_;
+
+ parallel_nd(D_start, D_mask, D_rest,
+ [&](ptrdiff_t ds, ptrdiff_t dm, ptrdiff_t dr) {
+ const float scale = scales[dm];
+
+ const size_t e = (ds * D_mask + dm) * D_rest + dr;
+ const auto &i = input[input_d.off_l(e)];
+ auto &o = output[output_d.off_l(e)];
+
+ o = _qz<type_i, type_o>()(i, o, scale, beta);
+ });
+
+ return success;
+ }
+};
+
+
+/* high level class declaration */
+
+template <SIMPLE_REORDER_TEMPL_DECL, typename spec = void>
+struct simple_reorder_t: public cpu_primitive_t {
+ struct pd_t: public cpu_reorder_pd_t {
+ using cpu_reorder_pd_t::cpu_reorder_pd_t;
+
+ DECLARE_COMMON_PD_T("simple:any", simple_reorder_t);
+
+ static status_t create(reorder_pd_t **reorder_pd,
+ engine_t *engine, const primitive_attr_t *attr,
+ engine_t *src_engine, const memory_desc_t *src_md,
+ engine_t *dst_engine, const memory_desc_t *dst_md) {
+ bool args_ok = true
+ && src_md->data_type == type_i
+ && dst_md->data_type == type_o
+ && simple_reorder_impl<SIMPLE_REORDER_TEMPL_CALL, spec>::
+ is_applicable(src_md, dst_md, attr);
+ if (!args_ok)
+ return status::invalid_arguments;
+
+ auto _pd = new pd_t(engine, attr, src_engine, src_md, dst_engine,
+ dst_md);
+ if (_pd == nullptr) return status::out_of_memory;
+ if (_pd->init() != status::success) {
+ delete _pd;
+ return status::unimplemented;
+ }
+ return safe_ptr_assign<reorder_pd_t>(*reorder_pd, _pd);
+ }
+ };
+
+ simple_reorder_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ auto input = CTX_IN_MEM(const data_t<type_i> *, MKLDNN_ARG_FROM);
+ auto output = CTX_OUT_MEM(data_t<type_o> *, MKLDNN_ARG_TO);
+ simple_reorder_impl<SIMPLE_REORDER_TEMPL_CALL, spec>::execute(
+ pd(), input, output);
+ return status::success;
+ }
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+#undef SIMPLE_REORDER_TEMPL_DECL
+#undef SIMPLE_REORDER_TEMPL_CALL
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/simple_sum.cpp b/thirdparty/oidn/mkl-dnn/src/cpu/simple_sum.cpp
new file mode 100644
index 0000000000..f0947573a9
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/simple_sum.cpp
@@ -0,0 +1,91 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#include "mkldnn_thread.hpp"
+
+#include "simple_sum.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <data_type_t data_type>
+status_t simple_sum_t<data_type>::execute(const exec_ctx_t &ctx) const {
+ auto output = CTX_OUT_MEM(data_t *, MKLDNN_ARG_DST);
+
+ const memory_desc_wrapper o_d(pd()->dst_md());
+ output += o_d.blk_off(0);
+
+ const int num_arrs = pd()->n_inputs();
+ const data_t *input_ptrs[max_num_arrs];
+ const size_t nelems = o_d.nelems();
+
+ for (int a = 0; a < num_arrs; ++a) {
+ const memory_desc_wrapper i_d(pd()->src_md(a));
+ input_ptrs[a] = CTX_IN_MEM(const data_t *, MKLDNN_ARG_MULTIPLE_SRC + a)
+ + i_d.blk_off(0);
+ }
+
+ const size_t block_size = 16 * 1024 / sizeof(data_type);
+ const size_t blocks_number = nelems / block_size;
+ const size_t tail = nelems % block_size;
+
+ const auto scales = pd()->scales();
+ parallel(0, [&](const int ithr, const int nthr) {
+ size_t start{0}, end{0};
+ balance211(blocks_number, nthr, ithr, start, end);
+
+ for (size_t nb = start; nb < end; ++nb) {
+ size_t start_e = nb * block_size;
+ size_t end_e = start_e + block_size;
+
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start_e; e < end_e; e++) {
+ output[e] = data_t(scales[0] * input_ptrs[0][e]);
+ }
+ for (int a = 1; a < num_arrs; a++) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start_e; e < end_e; e++) {
+ output[e] += data_t(scales[a] * input_ptrs[a][e]);
+ }
+ }
+ }
+
+ if (tail != 0 && ithr == nthr - 1) {
+ size_t start_e = nelems - tail;
+ size_t end_e = nelems;
+
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start_e; e < end_e; e++) {
+ output[e] = data_t(scales[0] * input_ptrs[0][e]);
+ }
+ for (int a = 1; a < num_arrs; a++) {
+ PRAGMA_OMP_SIMD()
+ for (size_t e = start_e; e < end_e; e++) {
+ output[e] += data_t(scales[a] * input_ptrs[a][e]);
+ }
+ }
+ }
+ });
+
+ return status::success;
+}
+
+template struct simple_sum_t<data_type::f32>;
+
+}
+}
+}
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/simple_sum.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/simple_sum.hpp
new file mode 100644
index 0000000000..2a0187a184
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/simple_sum.hpp
@@ -0,0 +1,74 @@
+/*******************************************************************************
+* Copyright 2017-2018 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+#ifndef SIMPLE_SUM_HPP
+#define SIMPLE_SUM_HPP
+
+#include "cpu_sum_pd.hpp"
+#include "cpu_primitive.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <data_type_t data_type>
+struct simple_sum_t: public cpu_primitive_t {
+ struct pd_t: public cpu_sum_pd_t {
+ using cpu_sum_pd_t::cpu_sum_pd_t;
+
+ DECLARE_SUM_PD_T("simple:any", simple_sum_t);
+
+ status_t init() {
+ const int n = n_inputs();
+
+ bool ok = true
+ && cpu_sum_pd_t::init() == status::success
+ && n <= max_num_arrs;
+ if (!ok) return status::unimplemented;
+
+ const memory_desc_wrapper o_d(dst_md());
+ ok = ok
+ && o_d.data_type() == data_type
+ && o_d.is_dense();
+ if (!ok) return status::unimplemented;
+
+ for (int i = 0; i < n; ++i) {
+ const memory_desc_wrapper i_d(src_md(i));
+ if (i_d != o_d) return status::unimplemented;
+ }
+
+ return status::success;
+ }
+ };
+
+ simple_sum_t(const pd_t *apd): cpu_primitive_t(apd) {}
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override;
+
+ enum {max_num_arrs = 16 };
+ typedef typename prec_traits<data_type>::type data_t;
+
+private:
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+};
+
+}
+}
+}
+
+#endif
+
+// vim: et ts=4 sw=4 cindent cino^=l0,\:0,N-s
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/wino_reorder.hpp b/thirdparty/oidn/mkl-dnn/src/cpu/wino_reorder.hpp
new file mode 100644
index 0000000000..c2082d7d62
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/wino_reorder.hpp
@@ -0,0 +1,376 @@
+/*******************************************************************************
+ * Copyright 2017-2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *******************************************************************************/
+
+#ifndef CPU_WINO_REORDER_HPP
+#define CPU_WINO_REORDER_HPP
+
+#include "mkldnn_thread.hpp"
+
+#include "simple_q10n.hpp"
+
+namespace mkldnn {
+namespace impl {
+namespace cpu {
+
+template <data_type_t type_i, data_type_t type_o>
+struct wino_reorder_t : public cpu_primitive_t {
+ struct pd_t : public cpu_reorder_pd_t {
+ using cpu_reorder_pd_t::cpu_reorder_pd_t;
+
+ DECLARE_COMMON_PD_T("wino_reorder", wino_reorder_t);
+
+ static status_t create(reorder_pd_t **reorder_pd,
+ engine_t *engine, const primitive_attr_t *attr,
+ engine_t *src_engine, const memory_desc_t *src_md,
+ engine_t *dst_engine, const memory_desc_t *dst_md) {
+ const memory_desc_wrapper id(src_md), od(dst_md);
+ bool args_ok = true
+ && id.data_type() == type_i
+ && od.data_type() == type_o
+ && id.matches_tag(utils::pick(id.ndims() - 4,
+ format_tag::oihw, format_tag::goihw))
+ && od.format_kind() == format_kind::wino
+ && utils::one_of(od.wino_desc().wino_format,
+ mkldnn_wino_wei_aaOIoi, mkldnn_wino_wei_aaOio,
+ mkldnn_wino_wei_aaOBiOo, mkldnn_wino_wei_OBaaIBOIio);
+ if (!args_ok) return status::invalid_arguments;
+
+ auto _pd = new pd_t(engine, attr, src_engine, src_md, dst_engine,
+ dst_md);
+ if (_pd == nullptr) return status::out_of_memory;
+ if (_pd->init() != status::success) {
+ delete _pd;
+ return status::unimplemented;
+ }
+ return safe_ptr_assign<reorder_pd_t>(*reorder_pd, _pd);
+ }
+
+ status_t init() {
+ status_t status = cpu_reorder_pd_t::init();
+ if (status != status::success) return status;
+
+ init_scratchpad();
+
+ return status::success;
+ }
+
+ private:
+ void init_scratchpad() {
+ auto &o = memory_desc_wrapper(dst_md()).wino_desc();
+ size_t transform_space_size = (size_t)o.r * o.alpha * o.oc_block;
+ size_t plain_size = (size_t)o.alpha * o.alpha * o.oc * o.ic;
+
+ using namespace memory_tracking::names;
+ auto scratchpad = scratchpad_registry().registrar();
+ scratchpad.book(key_reorder_wino_transform_space,
+ sizeof(in_data_t) * transform_space_size);
+ scratchpad.book(key_reorder_wino_plain,
+ sizeof(out_data_t) * plain_size);
+ }
+ };
+
+private:
+ typedef typename prec_traits<type_i>::type in_data_t;
+ typedef typename prec_traits<type_o>::type out_data_t;
+ const int unsign_val_in_wino_domain_ = 5;
+
+ wino_reorder_t(const pd_t *apd): cpu_primitive_t(apd) {
+ const memory_desc_wrapper src_d(pd()->src_md());
+ const memory_desc_wrapper dst_d(pd()->dst_md());
+
+ r_ = dst_d.wino_desc().r;
+ w_alpha_ = dst_d.wino_desc().alpha;
+ wino_format_ = dst_d.wino_desc().wino_format;
+
+ const auto &in_dims = src_d.dims();
+ int groups;
+ int groups_offset;
+ if (src_d.ndims() == 5) {
+ groups = in_dims[0];
+ groups_offset = 1;
+ } else {
+ groups = 1;
+ groups_offset = 0;
+ }
+ assert(groups == 1); // groups are not supported now
+ MAYBE_UNUSED(groups);
+
+ or_oc_ = in_dims[0 + groups_offset];
+ or_ic_ = in_dims[1 + groups_offset];
+ kh_ = in_dims[2 + groups_offset];
+ kw_ = in_dims[3 + groups_offset];
+
+ oc_ = dst_d.wino_desc().oc;
+ ic_ = dst_d.wino_desc().ic;
+ oc_block_ = dst_d.wino_desc().oc_block;
+ ic_block_ = dst_d.wino_desc().ic_block;
+ assert(oc_ % oc_block_ == 0 && ic_ % ic_block_ == 0);
+ nb_oc_ = oc_ / oc_block_;
+ nb_ic_ = ic_ / ic_block_;
+ ic2_block_ = 1;
+ if (wino_format_ == mkldnn_wino_wei_OBaaIBOIio)
+ ic2_block_ = dst_d.wino_desc().ic2_block;
+ oc2_block_ = dst_d.wino_desc().oc2_block;
+ assert(nb_ic_ % ic2_block_ == 0 && nb_oc_ % oc2_block_ == 0);
+
+ adj_scale_ = dst_d.wino_desc().adj_scale;
+
+ size_wino_wei_ = w_alpha_ * w_alpha_ * oc_ * ic_;
+ size_wspace_ = r_ * w_alpha_ * oc_block_;
+ }
+
+ void transform(out_data_t *__restrict tmp_wei,
+ const in_data_t *__restrict input,
+ in_data_t *__restrict wspace) const {
+ const memory_desc_wrapper src_d(pd()->src_md());
+
+ const int smask = pd()->attr()->output_scales_.mask_;
+ const int ndims_mask = math::ilog2q(smask + 1);
+ const size_t D_mask = utils::array_product(src_d.dims(), ndims_mask);
+ const float *__restrict scales = pd()->attr()->output_scales_.scales_;
+ assert(D_mask == 1 || D_mask == (size_t)oc_);
+
+ /* transform weights to winograd domain */
+ const float G_2x2_3x3[4][3] = { { 1.0, 0.0, 0.0 }, { 0.5, 0.5, 0.5 },
+ { 0.5, -0.5, 0.5 }, { 0.0, 0.0, 1.0 } };
+
+ const float G_4x4_3x3[6][3] = { { 1.13777777777778f, 0.f, 0.f },
+ { -0.688403361344538f, -0.430252100840336f, -0.26890756302521f },
+ { -0.688403361344538f, 0.430252100840336f, -0.26890756302521f },
+ { 0.119514472455649f, 0.179271708683473f, 0.26890756302521f },
+ { 0.119514472455649f, -0.179271708683473f, 0.26890756302521f },
+ { 0.f, 0.f, 1.f } };
+
+ float *__restrict g;
+ if (utils::one_of(wino_format_, mkldnn_wino_wei_aaOIoi,
+ mkldnn_wino_wei_aaOio, mkldnn_wino_wei_aaOBiOo))
+ g = (float *)G_2x2_3x3;
+ else if (wino_format_ == mkldnn_wino_wei_OBaaIBOIio)
+ g = (float *)G_4x4_3x3;
+ else {
+ assert("Unknown winograd weights target layout");
+ return;
+ }
+
+ int Z = oc_ * ic_;
+ assert(r_ == kh_ && r_ == kw_);
+
+ for (int iic = 0; iic < ic_; iic++) {
+ for (int ob = 0; ob < nb_oc_; ob++) {
+ const in_data_t *__restrict _inp
+ = input + (ob * oc_block_ * or_ic_ + iic) * kh_ * kw_;
+ out_data_t *__restrict _out
+ = tmp_wei + (iic * nb_oc_ + ob) * oc_block_;
+
+ for_nd(0, 1, size_wspace_, [&](int i) { wspace[i] = 0.f; });
+
+ for_nd(0, 1, r_, w_alpha_, oc_block_,
+ [&](int ih, int j, int ioc) {
+ for (int iw = 0; iw < r_; ++iw) {
+ int inp_oc = ob * oc_block_ + ioc;
+ int inp_ic = iic;
+ in_data_t inp_v = (inp_ic < or_ic_ && inp_oc < or_oc_)
+ ? _inp[ioc * or_ic_ * kh_ * kw_ + ih * kw_ + iw]
+ : 0.f;
+ wspace[(ih * w_alpha_ + j) * oc_block_ + ioc]
+ += inp_v * g[j * r_ + iw];
+ }
+ });
+
+ for_nd(0, 1, w_alpha_, w_alpha_, oc_block_,
+ [&](int i, int j, int ioc) {
+ float t = 0;
+ for (int k = 0; k < r_; ++k)
+ t += g[i * r_ + k]
+ * wspace[(k * w_alpha_ + j) * oc_block_ + ioc];
+ if (type_o == data_type::s8) {
+ const float scale = (D_mask == 1)
+ ? scales[0]
+ : scales[ob * oc_block_ + ioc];
+ _out[(i * w_alpha_ + j) * Z + ioc]
+ = qz_b0<in_data_t, out_data_t>()(
+ (in_data_t)t, scale * adj_scale_);
+ } else {
+ _out[(i * w_alpha_ + j) * Z + ioc] = (out_data_t)t;
+ }
+ });
+ }}
+ }
+
+ void reorder_to_aaOIoi(out_data_t *__restrict output,
+ const out_data_t *__restrict tmp_wei) const {
+ int32_t *__restrict dst_bias = nullptr;
+ if (type_o == data_type::s8) {
+ const auto bias_shift = sizeof(out_data_t) * size_wino_wei_;
+ const size_t bias_size = w_alpha_ * w_alpha_ * oc_;
+
+ dst_bias = (int32_t *)(output + bias_shift);
+ utils::array_set((int32_t *)dst_bias, 0, bias_size);
+ }
+ int index = 0;
+ for (int u_h = 0; u_h < w_alpha_; u_h++) {
+ for (int u_w = 0; u_w < w_alpha_; u_w++) {
+ for_nd(0, 1, nb_oc_, oc_block_, [&](int ob, int o) {
+ int u_h_shift = u_h * w_alpha_ * ic_ * oc_;
+ int u_w_shift = u_w * ic_ * oc_;
+ int u_h_shift_b = u_h * w_alpha_ * oc_;
+ int u_w_shift_b = u_w * oc_;
+ int oc_block_shift = ob * oc_block_ * ic_ + o * ic_block_;
+ for (int ib = 0; ib < nb_ic_; ib++) {
+ for (int i = 0; i < ic_block_; i++) {
+ int _i = ib * ic_block_;
+ int _o = ob * oc_block_;
+ int ic_shift = (_i + i) * oc_;
+ int oc_shift = (_o + o);
+ int ic_block_shift = ib * oc_block_ * ic_block_ + i;
+ int src_offset =
+ u_h_shift + u_w_shift + ic_shift + oc_shift;
+ int dst_offset = u_h_shift + u_w_shift + oc_block_shift
+ + ic_block_shift;
+
+ output[dst_offset] = tmp_wei[src_offset];
+ if (type_o == data_type::s8) {
+ int bias_offset = u_h_shift_b + u_w_shift_b + oc_shift;
+ if (index != unsign_val_in_wino_domain_)
+ dst_bias[bias_offset]
+ -= (128 * (int32_t)output[dst_offset]);
+ else
+ dst_bias[bias_offset] = 0;
+ }
+ }}
+ });
+ index++;
+ }}
+ }
+
+ void reorder_to_aaOio(out_data_t *__restrict output,
+ const out_data_t *__restrict tmp_wei) const {
+ for_nd(0, 1, w_alpha_, w_alpha_, nb_oc_,
+ [&](int u_h, int u_w, int ob) {
+ for (int ib = 0; ib < nb_ic_; ib++) {
+ for (int i = 0; i < ic_block_; i++) {
+ for (int o = 0; o < oc_block_; o++) {
+ int src_offset = u_h * w_alpha_ * ic_ * oc_ + u_w * ic_ * oc_
+ + (ib * ic_block_ + i) * oc_ + (ob * oc_block_ + o);
+
+ int dst_offset
+ = u_h * w_alpha_ * nb_oc_ * nb_ic_ * ic_block_ * oc_block_
+ + u_w * nb_oc_ * nb_ic_ * ic_block_ * oc_block_
+ + ob * nb_ic_ * ic_block_ * oc_block_
+ + ib * ic_block_ * oc_block_ + i * oc_block_ + o;
+ output[dst_offset] = tmp_wei[src_offset];
+ }}}
+ });
+ }
+
+ void reorder_to_aaOBiOo(out_data_t *__restrict output,
+ const out_data_t *__restrict tmp_wei) const {
+ int oc_chunks = nb_oc_ / oc2_block_;
+
+ for_nd(0, 1, w_alpha_, w_alpha_, oc_chunks,
+ [&](int u_h, int u_w, int occ) {
+ for (int ib = 0; ib < nb_ic_; ib++) {
+ out_data_t *__restrict wei_ptr = output
+ + (((u_h * w_alpha_ + u_w) * oc_chunks + occ) * nb_ic_ + ib)
+ * oc2_block_ * ic_block_ * oc_block_;
+ int wei_offset = 0;
+ for (int i = 0; i < ic_block_; i++) {
+ for (int ob2 = 0; ob2 < oc2_block_; ob2++) {
+ for (int o = 0; o < oc_block_; o++) {
+ int icp = ib * ic_block_ + i;
+ int ocp =
+ occ * oc2_block_ * oc_block_ + ob2 * oc_block_ + o;
+
+ int src_offset = u_h * w_alpha_ * ic_ * oc_
+ + u_w * ic_ * oc_ + icp * oc_ + ocp;
+ wei_ptr[wei_offset + o] = tmp_wei[src_offset];
+ }
+ wei_offset += oc_block_;
+ }}
+ }
+ });
+ }
+
+ void reorder_to_OBaaIBOIio(out_data_t *__restrict output,
+ const out_data_t *__restrict tmp_wei) const {
+ int ic_chunks = nb_ic_ / ic2_block_;
+ int oc_chunks = nb_oc_ / oc2_block_;
+
+ for_nd(0, 1, oc_chunks, w_alpha_, w_alpha_,
+ [&](int occ, int u_h, int u_w) {
+ for (int icc = 0; icc < ic_chunks; icc++) {
+ for (int ob = 0; ob < oc2_block_; ob++) {
+ int ocp = (occ * oc2_block_ + ob) * oc_block_;
+ for (int ib = 0; ib < ic2_block_; ib++) {
+ for (int i = 0; i < ic_block_; i++) {
+ int icp = (icc * ic2_block_ + ib) * ic_block_ + i;
+
+ int src_offset = u_h * w_alpha_ * ic_ * oc_
+ + u_w * ic_ * oc_ + icp * oc_ + ocp;
+ int wei_offset
+ = ((((((occ * w_alpha_ + u_h) * w_alpha_ + u_w)
+ * ic_chunks + icc) * oc2_block_ + ob) * ic2_block_
+ + ib) * ic_block_ + i) * oc_block_;
+ for (int o = 0; o < oc_block_; o++)
+ output[wei_offset + o] = tmp_wei[src_offset + o];
+ }}
+ }}
+ });
+ }
+
+ virtual status_t execute(const exec_ctx_t &ctx) const override {
+ auto input = CTX_IN_MEM(const in_data_t *, MKLDNN_ARG_FROM);
+ auto output = CTX_OUT_MEM(out_data_t *, MKLDNN_ARG_TO);
+
+ auto wspace = (in_data_t *__restrict)scratchpad(ctx).template get<void>(
+ memory_tracking::names::key_reorder_wino_transform_space);
+ auto tmp_wei = (out_data_t *__restrict)scratchpad(ctx).template get<void>(
+ memory_tracking::names::key_reorder_wino_plain);
+
+ transform(tmp_wei, input, wspace);
+
+ /* reorder to winograd domain */
+ switch (wino_format_) {
+ case mkldnn_wino_wei_aaOIoi:
+ reorder_to_aaOIoi(output, tmp_wei); break;
+ case mkldnn_wino_wei_aaOio:
+ reorder_to_aaOio(output, tmp_wei); break;
+ case mkldnn_wino_wei_aaOBiOo:
+ reorder_to_aaOBiOo(output, tmp_wei); break;
+ case mkldnn_wino_wei_OBaaIBOIio:
+ reorder_to_OBaaIBOIio(output, tmp_wei); break;
+ default: assert("Unknown wino format"); break;
+ }
+
+ return status::success;
+ }
+
+ const pd_t *pd() const { return (const pd_t *)primitive_t::pd(); }
+ int r_, w_alpha_;
+ int ic_, oc_, or_ic_, or_oc_, kh_, kw_;
+ int oc_block_, ic_block_, oc2_block_, ic2_block_;
+ float adj_scale_;
+ int nb_oc_, nb_ic_;
+ mkldnn_wino_memory_format_t wino_format_;
+ int size_wino_wei_;
+ int size_wspace_;
+};
+
+} // namespace cpu
+} // namespace impl
+} // namespace mkldnn
+
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/COPYRIGHT b/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/COPYRIGHT
new file mode 100644
index 0000000000..66b6ea55d0
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/COPYRIGHT
@@ -0,0 +1,47 @@
+
+Copyright (c) 2007 MITSUNARI Shigeo
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this
+list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+Neither the name of the copyright owner nor the names of its contributors may
+be used to endorse or promote products derived from this software without
+specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+THE POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+ソースコード形å¼ã‹ãƒã‚¤ãƒŠãƒªå½¢å¼ã‹ã€å¤‰æ›´ã™ã‚‹ã‹ã—ãªã„ã‹ã‚’å•ã‚ãšã€ä»¥ä¸‹ã®æ¡ä»¶ã‚’満ãŸ
+ã™å ´åˆã«é™ã‚Šã€å†é ’布ãŠã‚ˆã³ä½¿ç”¨ãŒè¨±å¯ã•れã¾ã™ã€‚
+
+ソースコードをå†é ’布ã™ã‚‹å ´åˆã€ä¸Šè¨˜ã®è‘—ä½œæ¨©è¡¨ç¤ºã€æœ¬æ¡ä»¶ä¸€è¦§ã€ãŠã‚ˆã³ä¸‹è¨˜å…責æ¡é …
+ã‚’å«ã‚ã‚‹ã“ã¨ã€‚
+ãƒã‚¤ãƒŠãƒªå½¢å¼ã§å†é ’布ã™ã‚‹å ´åˆã€é ’布物ã«ä»˜å±žã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆç­‰ã®è³‡æ–™ã«ã€ä¸Šè¨˜ã®è‘—作
+æ¨©è¡¨ç¤ºã€æœ¬æ¡ä»¶ä¸€è¦§ã€ãŠã‚ˆã³ä¸‹è¨˜å…責æ¡é …ã‚’å«ã‚ã‚‹ã“ã¨ã€‚
+書é¢ã«ã‚ˆã‚‹ç‰¹åˆ¥ã®è¨±å¯ãªã—ã«ã€æœ¬ã‚½ãƒ•トウェアã‹ã‚‰æ´¾ç”Ÿã—ãŸè£½å“ã®å®£ä¼ã¾ãŸã¯è²©å£²ä¿ƒé€²
+ã«ã€è‘—作権者ã®åå‰ã¾ãŸã¯ã‚³ãƒ³ãƒˆãƒªãƒ“ューターã®åå‰ã‚’使用ã—ã¦ã¯ãªã‚‰ãªã„。
+本ソフトウェアã¯ã€è‘—作権者ãŠã‚ˆã³ã‚³ãƒ³ãƒˆãƒªãƒ“ューターã«ã‚ˆã£ã¦ã€Œç¾çжã®ã¾ã¾ã€æä¾›ã•
+れã¦ãŠã‚Šã€æ˜Žç¤ºé»™ç¤ºã‚’å•ã‚ãšã€å•†æ¥­çš„ãªä½¿ç”¨å¯èƒ½æ€§ã€ãŠã‚ˆã³ç‰¹å®šã®ç›®çš„ã«å¯¾ã™ã‚‹é©åˆæ€§
+ã«é–¢ã™ã‚‹æš—é»™ã®ä¿è¨¼ã‚‚å«ã‚ã€ã¾ãŸãれã«é™å®šã•れãªã„ã€ã„ã‹ãªã‚‹ä¿è¨¼ã‚‚ã‚りã¾ã›ã‚“。
+著作権者もコントリビューターもã€äº‹ç”±ã®ã„ã‹ã‚“ã‚’å•ã‚ãšã€ æå®³ç™ºç”Ÿã®åŽŸå› ã„ã‹ã‚“ã‚’
+å•ã‚ãšã€ã‹ã¤è²¬ä»»ã®æ ¹æ‹ ãŒå¥‘ç´„ã§ã‚ã‚‹ã‹åŽ³æ ¼è²¬ä»»ã§ã‚ã‚‹ã‹ï¼ˆéŽå¤±ãã®ä»–ã®ï¼‰ä¸æ³•行為ã§
+ã‚ã‚‹ã‹ã‚’å•ã‚ãšã€ä»®ã«ãã®ã‚ˆã†ãªæå®³ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ã‚’知らã•れã¦ã„ãŸã¨ã—ã¦ã‚‚ã€
+本ソフトウェアã®ä½¿ç”¨ã«ã‚ˆã£ã¦ç™ºç”Ÿã—ãŸï¼ˆä»£æ›¿å“ã¾ãŸã¯ä»£ç”¨ã‚µãƒ¼ãƒ“スã®èª¿é”ã€ä½¿ç”¨ã®
+喪失ã€ãƒ‡ãƒ¼ã‚¿ã®å–ªå¤±ã€åˆ©ç›Šã®å–ªå¤±ã€æ¥­å‹™ã®ä¸­æ–­ã‚‚å«ã‚ã€ã¾ãŸãれã«é™å®šã•れãªã„)直接
+æå®³ã€é–“接æå®³ã€å¶ç™ºçš„ãªæå®³ã€ç‰¹åˆ¥æå®³ã€æ‡²ç½°çš„æå®³ã€ã¾ãŸã¯çµæžœæå®³ã«ã¤ã„ã¦ã€
+一切責任を負ã‚ãªã„ã‚‚ã®ã¨ã—ã¾ã™ã€‚
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak.h b/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak.h
new file mode 100644
index 0000000000..cf5771332f
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak.h
@@ -0,0 +1,2658 @@
+/*******************************************************************************
+* Copyright 2016-2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/*******************************************************************************
+* Copyright (c) 2007 MITSUNARI Shigeo
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+* Neither the name of the copyright owner nor the names of its contributors may
+* be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+#pragma once
+#ifndef XBYAK_XBYAK_H_
+#define XBYAK_XBYAK_H_
+/*!
+ @file xbyak.h
+ @brief Xbyak ; JIT assembler for x86(IA32)/x64 by C++
+ @author herumi
+ @url https://github.com/herumi/xbyak
+ @note modified new BSD license
+ http://opensource.org/licenses/BSD-3-Clause
+*/
+#ifndef XBYAK_NO_OP_NAMES
+ #if not +0 // trick to detect whether 'not' is operator or not
+ #error "use -fno-operator-names option if you want to use and(), or(), xor(), not() as function names, Or define XBYAK_NO_OP_NAMES and use and_(), or_(), xor_(), not_()."
+ #endif
+#endif
+
+#include <stdio.h> // for debug print
+#include <assert.h>
+#include <list>
+#include <string>
+#include <algorithm>
+#ifndef NDEBUG
+#include <iostream>
+#endif
+
+// #define XBYAK_DISABLE_AVX512
+
+//#define XBYAK_USE_MMAP_ALLOCATOR
+#if !defined(__GNUC__) || defined(__MINGW32__)
+ #undef XBYAK_USE_MMAP_ALLOCATOR
+#endif
+
+#ifdef __GNUC__
+ #define XBYAK_GNUC_PREREQ(major, minor) ((__GNUC__) * 100 + (__GNUC_MINOR__) >= (major) * 100 + (minor))
+#else
+ #define XBYAK_GNUC_PREREQ(major, minor) 0
+#endif
+
+// This covers -std=(gnu|c)++(0x|11|1y), -stdlib=libc++, and modern Microsoft.
+#if ((defined(_MSC_VER) && (_MSC_VER >= 1600)) || defined(_LIBCPP_VERSION) ||\
+ ((__cplusplus >= 201103) || defined(__GXX_EXPERIMENTAL_CXX0X__)))
+ #include <unordered_set>
+ #define XBYAK_STD_UNORDERED_SET std::unordered_set
+ #include <unordered_map>
+ #define XBYAK_STD_UNORDERED_MAP std::unordered_map
+ #define XBYAK_STD_UNORDERED_MULTIMAP std::unordered_multimap
+
+/*
+ Clang/llvm-gcc and ICC-EDG in 'GCC-mode' always claim to be GCC 4.2, using
+ libstdcxx 20070719 (from GCC 4.2.1, the last GPL 2 version).
+*/
+#elif XBYAK_GNUC_PREREQ(4, 5) || (XBYAK_GNUC_PREREQ(4, 2) && __GLIBCXX__ >= 20070719) || defined(__INTEL_COMPILER) || defined(__llvm__)
+ #include <tr1/unordered_set>
+ #define XBYAK_STD_UNORDERED_SET std::tr1::unordered_set
+ #include <tr1/unordered_map>
+ #define XBYAK_STD_UNORDERED_MAP std::tr1::unordered_map
+ #define XBYAK_STD_UNORDERED_MULTIMAP std::tr1::unordered_multimap
+
+#elif defined(_MSC_VER) && (_MSC_VER >= 1500) && (_MSC_VER < 1600)
+ #include <unordered_set>
+ #define XBYAK_STD_UNORDERED_SET std::tr1::unordered_set
+ #include <unordered_map>
+ #define XBYAK_STD_UNORDERED_MAP std::tr1::unordered_map
+ #define XBYAK_STD_UNORDERED_MULTIMAP std::tr1::unordered_multimap
+
+#else
+ #include <set>
+ #define XBYAK_STD_UNORDERED_SET std::set
+ #include <map>
+ #define XBYAK_STD_UNORDERED_MAP std::map
+ #define XBYAK_STD_UNORDERED_MULTIMAP std::multimap
+#endif
+#ifdef _WIN32
+ #include <winsock2.h>
+ #include <windows.h>
+ #include <malloc.h>
+#elif defined(__GNUC__)
+ #include <unistd.h>
+ #include <sys/mman.h>
+ #include <stdlib.h>
+#endif
+#if !defined(_MSC_VER) || (_MSC_VER >= 1600)
+ #include <stdint.h>
+#endif
+
+#if defined(_WIN64) || defined(__MINGW64__) || (defined(__CYGWIN__) && defined(__x86_64__))
+ #define XBYAK64_WIN
+#elif defined(__x86_64__)
+ #define XBYAK64_GCC
+#endif
+#if !defined(XBYAK64) && !defined(XBYAK32)
+ #if defined(XBYAK64_GCC) || defined(XBYAK64_WIN)
+ #define XBYAK64
+ #else
+ #define XBYAK32
+ #endif
+#endif
+
+#if (__cplusplus >= 201103) || (_MSC_VER >= 1800)
+ #define XBYAK_VARIADIC_TEMPLATE
+#endif
+
+#ifdef _MSC_VER
+ #pragma warning(push)
+ #pragma warning(disable : 4514) /* remove inline function */
+ #pragma warning(disable : 4786) /* identifier is too long */
+ #pragma warning(disable : 4503) /* name is too long */
+ #pragma warning(disable : 4127) /* constant expresison */
+#endif
+
+namespace Xbyak {
+
+enum {
+ DEFAULT_MAX_CODE_SIZE = 4096,
+ VERSION = 0x5760 /* 0xABCD = A.BC(D) */
+};
+
+#ifndef MIE_INTEGER_TYPE_DEFINED
+#define MIE_INTEGER_TYPE_DEFINED
+#ifdef _MSC_VER
+ typedef unsigned __int64 uint64;
+ typedef __int64 sint64;
+#else
+ typedef uint64_t uint64;
+ typedef int64_t sint64;
+#endif
+typedef unsigned int uint32;
+typedef unsigned short uint16;
+typedef unsigned char uint8;
+#endif
+
+#ifndef MIE_ALIGN
+ #ifdef _MSC_VER
+ #define MIE_ALIGN(x) __declspec(align(x))
+ #else
+ #define MIE_ALIGN(x) __attribute__((aligned(x)))
+ #endif
+#endif
+#ifndef MIE_PACK // for shufps
+ #define MIE_PACK(x, y, z, w) ((x) * 64 + (y) * 16 + (z) * 4 + (w))
+#endif
+
+enum {
+ ERR_NONE = 0,
+ ERR_BAD_ADDRESSING,
+ ERR_CODE_IS_TOO_BIG,
+ ERR_BAD_SCALE,
+ ERR_ESP_CANT_BE_INDEX,
+ ERR_BAD_COMBINATION,
+ ERR_BAD_SIZE_OF_REGISTER,
+ ERR_IMM_IS_TOO_BIG,
+ ERR_BAD_ALIGN,
+ ERR_LABEL_IS_REDEFINED,
+ ERR_LABEL_IS_TOO_FAR,
+ ERR_LABEL_IS_NOT_FOUND,
+ ERR_CODE_ISNOT_COPYABLE,
+ ERR_BAD_PARAMETER,
+ ERR_CANT_PROTECT,
+ ERR_CANT_USE_64BIT_DISP,
+ ERR_OFFSET_IS_TOO_BIG,
+ ERR_MEM_SIZE_IS_NOT_SPECIFIED,
+ ERR_BAD_MEM_SIZE,
+ ERR_BAD_ST_COMBINATION,
+ ERR_OVER_LOCAL_LABEL, // not used
+ ERR_UNDER_LOCAL_LABEL,
+ ERR_CANT_ALLOC,
+ ERR_ONLY_T_NEAR_IS_SUPPORTED_IN_AUTO_GROW,
+ ERR_BAD_PROTECT_MODE,
+ ERR_BAD_PNUM,
+ ERR_BAD_TNUM,
+ ERR_BAD_VSIB_ADDRESSING,
+ ERR_CANT_CONVERT,
+ ERR_LABEL_ISNOT_SET_BY_L,
+ ERR_LABEL_IS_ALREADY_SET_BY_L,
+ ERR_BAD_LABEL_STR,
+ ERR_MUNMAP,
+ ERR_OPMASK_IS_ALREADY_SET,
+ ERR_ROUNDING_IS_ALREADY_SET,
+ ERR_K0_IS_INVALID,
+ ERR_EVEX_IS_INVALID,
+ ERR_SAE_IS_INVALID,
+ ERR_ER_IS_INVALID,
+ ERR_INVALID_BROADCAST,
+ ERR_INVALID_OPMASK_WITH_MEMORY,
+ ERR_INVALID_ZERO,
+ ERR_INVALID_RIP_IN_AUTO_GROW,
+ ERR_INVALID_MIB_ADDRESS,
+ ERR_INTERNAL,
+ ERR_X2APIC_IS_NOT_SUPPORTED
+};
+
+class Error : public std::exception {
+ int err_;
+public:
+ explicit Error(int err) : err_(err)
+ {
+ if (err_ < 0 || err_ > ERR_INTERNAL) {
+ fprintf(stderr, "bad err=%d in Xbyak::Error\n", err_);
+ //exit(1);
+ }
+ }
+ operator int() const { return err_; }
+ const char *what() const throw()
+ {
+ static const char *errTbl[] = {
+ "none",
+ "bad addressing",
+ "code is too big",
+ "bad scale",
+ "esp can't be index",
+ "bad combination",
+ "bad size of register",
+ "imm is too big",
+ "bad align",
+ "label is redefined",
+ "label is too far",
+ "label is not found",
+ "code is not copyable",
+ "bad parameter",
+ "can't protect",
+ "can't use 64bit disp(use (void*))",
+ "offset is too big",
+ "MEM size is not specified",
+ "bad mem size",
+ "bad st combination",
+ "over local label",
+ "under local label",
+ "can't alloc",
+ "T_SHORT is not supported in AutoGrow",
+ "bad protect mode",
+ "bad pNum",
+ "bad tNum",
+ "bad vsib addressing",
+ "can't convert",
+ "label is not set by L()",
+ "label is already set by L()",
+ "bad label string",
+ "err munmap",
+ "opmask is already set",
+ "rounding is already set",
+ "k0 is invalid",
+ "evex is invalid",
+ "sae(suppress all exceptions) is invalid",
+ "er(embedded rounding) is invalid",
+ "invalid broadcast",
+ "invalid opmask with memory",
+ "invalid zero",
+ "invalid rip in AutoGrow",
+ "invalid mib address",
+ "internal error",
+ "x2APIC is not supported"
+ };
+ assert((size_t)err_ < sizeof(errTbl) / sizeof(*errTbl));
+ return errTbl[err_];
+ }
+};
+
+inline const char *ConvertErrorToString(const Error& err)
+{
+ return err.what();
+}
+
+inline void *AlignedMalloc(size_t size, size_t alignment)
+{
+#ifdef __MINGW32__
+ return __mingw_aligned_malloc(size, alignment);
+#elif defined(_WIN32)
+ return _aligned_malloc(size, alignment);
+#else
+ void *p;
+ int ret = posix_memalign(&p, alignment, size);
+ return (ret == 0) ? p : 0;
+#endif
+}
+
+inline void AlignedFree(void *p)
+{
+#ifdef __MINGW32__
+ __mingw_aligned_free(p);
+#elif defined(_MSC_VER)
+ _aligned_free(p);
+#else
+ free(p);
+#endif
+}
+
+template<class To, class From>
+inline const To CastTo(From p) throw()
+{
+ return (const To)(size_t)(p);
+}
+namespace inner {
+
+static const size_t ALIGN_PAGE_SIZE = 4096;
+
+inline bool IsInDisp8(uint32 x) { return 0xFFFFFF80 <= x || x <= 0x7F; }
+inline bool IsInInt32(uint64 x) { return ~uint64(0x7fffffffu) <= x || x <= 0x7FFFFFFFU; }
+
+inline uint32 VerifyInInt32(uint64 x)
+{
+#ifdef XBYAK64
+ if (!IsInInt32(x)) throw Error(ERR_OFFSET_IS_TOO_BIG);
+#endif
+ return static_cast<uint32>(x);
+}
+
+enum LabelMode {
+ LasIs, // as is
+ Labs, // absolute
+ LaddTop // (addr + top) for mov(reg, label) with AutoGrow
+};
+
+} // inner
+
+/*
+ custom allocator
+*/
+struct Allocator {
+ virtual uint8 *alloc(size_t size) { return reinterpret_cast<uint8*>(AlignedMalloc(size, inner::ALIGN_PAGE_SIZE)); }
+ virtual void free(uint8 *p) { AlignedFree(p); }
+ virtual ~Allocator() {}
+ /* override to return false if you call protect() manually */
+ virtual bool useProtect() const { return true; }
+};
+
+#ifdef XBYAK_USE_MMAP_ALLOCATOR
+class MmapAllocator : Allocator {
+ typedef XBYAK_STD_UNORDERED_MAP<uintptr_t, size_t> SizeList;
+ SizeList sizeList_;
+public:
+ uint8 *alloc(size_t size)
+ {
+ const size_t alignedSizeM1 = inner::ALIGN_PAGE_SIZE - 1;
+ size = (size + alignedSizeM1) & ~alignedSizeM1;
+#ifdef MAP_ANONYMOUS
+ const int mode = MAP_PRIVATE | MAP_ANONYMOUS;
+#elif defined(MAP_ANON)
+ const int mode = MAP_PRIVATE | MAP_ANON;
+#else
+ #error "not supported"
+#endif
+ void *p = mmap(NULL, size, PROT_READ | PROT_WRITE, mode, -1, 0);
+ if (p == MAP_FAILED) throw Error(ERR_CANT_ALLOC);
+ assert(p);
+ sizeList_[(uintptr_t)p] = size;
+ return (uint8*)p;
+ }
+ void free(uint8 *p)
+ {
+ if (p == 0) return;
+ SizeList::iterator i = sizeList_.find((uintptr_t)p);
+ if (i == sizeList_.end()) throw Error(ERR_BAD_PARAMETER);
+ if (munmap((void*)i->first, i->second) < 0) throw Error(ERR_MUNMAP);
+ sizeList_.erase(i);
+ }
+};
+#endif
+
+class Address;
+class Reg;
+
+class Operand {
+ static const uint8 EXT8BIT = 0x20;
+ unsigned int idx_:6; // 0..31 + EXT8BIT = 1 if spl/bpl/sil/dil
+ unsigned int kind_:9;
+ unsigned int bit_:10;
+protected:
+ unsigned int zero_:1;
+ unsigned int mask_:3;
+ unsigned int rounding_:3;
+ void setIdx(int idx) { idx_ = idx; }
+public:
+ enum Kind {
+ NONE = 0,
+ MEM = 1 << 0,
+ REG = 1 << 1,
+ MMX = 1 << 2,
+ FPU = 1 << 3,
+ XMM = 1 << 4,
+ YMM = 1 << 5,
+ ZMM = 1 << 6,
+ OPMASK = 1 << 7,
+ BNDREG = 1 << 8
+ };
+ enum Code {
+#ifdef XBYAK64
+ RAX = 0, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8, R9, R10, R11, R12, R13, R14, R15,
+ R8D = 8, R9D, R10D, R11D, R12D, R13D, R14D, R15D,
+ R8W = 8, R9W, R10W, R11W, R12W, R13W, R14W, R15W,
+ R8B = 8, R9B, R10B, R11B, R12B, R13B, R14B, R15B,
+ SPL = 4, BPL, SIL, DIL,
+#endif
+ EAX = 0, ECX, EDX, EBX, ESP, EBP, ESI, EDI,
+ AX = 0, CX, DX, BX, SP, BP, SI, DI,
+ AL = 0, CL, DL, BL, AH, CH, DH, BH
+ };
+ Operand() : idx_(0), kind_(0), bit_(0), zero_(0), mask_(0), rounding_(0) { }
+ Operand(int idx, Kind kind, int bit, bool ext8bit = 0)
+ : idx_(static_cast<uint8>(idx | (ext8bit ? EXT8BIT : 0)))
+ , kind_(kind)
+ , bit_(bit)
+ , zero_(0), mask_(0), rounding_(0)
+ {
+ assert((bit_ & (bit_ - 1)) == 0); // bit must be power of two
+ }
+ Kind getKind() const { return static_cast<Kind>(kind_); }
+ int getIdx() const { return idx_ & (EXT8BIT - 1); }
+ bool isNone() const { return kind_ == 0; }
+ bool isMMX() const { return is(MMX); }
+ bool isXMM() const { return is(XMM); }
+ bool isYMM() const { return is(YMM); }
+ bool isZMM() const { return is(ZMM); }
+ bool isXMEM() const { return is(XMM | MEM); }
+ bool isYMEM() const { return is(YMM | MEM); }
+ bool isZMEM() const { return is(ZMM | MEM); }
+ bool isOPMASK() const { return is(OPMASK); }
+ bool isBNDREG() const { return is(BNDREG); }
+ bool isREG(int bit = 0) const { return is(REG, bit); }
+ bool isMEM(int bit = 0) const { return is(MEM, bit); }
+ bool isFPU() const { return is(FPU); }
+ bool isExt8bit() const { return (idx_ & EXT8BIT) != 0; }
+ bool isExtIdx() const { return (getIdx() & 8) != 0; }
+ bool isExtIdx2() const { return (getIdx() & 16) != 0; }
+ bool hasEvex() const { return isZMM() || isExtIdx2() || getOpmaskIdx() || getRounding(); }
+ bool hasRex() const { return isExt8bit() || isREG(64) || isExtIdx(); }
+ bool hasZero() const { return zero_; }
+ int getOpmaskIdx() const { return mask_; }
+ int getRounding() const { return rounding_; }
+ void setKind(Kind kind)
+ {
+ if ((kind & (XMM|YMM|ZMM)) == 0) return;
+ kind_ = kind;
+ bit_ = kind == XMM ? 128 : kind == YMM ? 256 : 512;
+ }
+ void setBit(int bit) { bit_ = bit; }
+ void setOpmaskIdx(int idx, bool ignore_idx0 = false)
+ {
+ if (!ignore_idx0 && idx == 0) throw Error(ERR_K0_IS_INVALID);
+ if (mask_) throw Error(ERR_OPMASK_IS_ALREADY_SET);
+ mask_ = idx;
+ }
+ void setRounding(int idx)
+ {
+ if (rounding_) throw Error(ERR_ROUNDING_IS_ALREADY_SET);
+ rounding_ = idx;
+ }
+ void setZero() { zero_ = true; }
+ // ah, ch, dh, bh?
+ bool isHigh8bit() const
+ {
+ if (!isBit(8)) return false;
+ if (isExt8bit()) return false;
+ const int idx = getIdx();
+ return AH <= idx && idx <= BH;
+ }
+ // any bit is accetable if bit == 0
+ bool is(int kind, uint32 bit = 0) const
+ {
+ return (kind == 0 || (kind_ & kind)) && (bit == 0 || (bit_ & bit)); // cf. you can set (8|16)
+ }
+ bool isBit(uint32 bit) const { return (bit_ & bit) != 0; }
+ uint32 getBit() const { return bit_; }
+ const char *toString() const
+ {
+ const int idx = getIdx();
+ if (kind_ == REG) {
+ if (isExt8bit()) {
+ static const char *tbl[4] = { "spl", "bpl", "sil", "dil" };
+ return tbl[idx - 4];
+ }
+ static const char *tbl[4][16] = {
+ { "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh", "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b" },
+ { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di", "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w" },
+ { "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi", "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" },
+ { "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" },
+ };
+ return tbl[bit_ == 8 ? 0 : bit_ == 16 ? 1 : bit_ == 32 ? 2 : 3][idx];
+ } else if (isOPMASK()) {
+ static const char *tbl[8] = { "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7" };
+ return tbl[idx];
+ } else if (isZMM()) {
+ static const char *tbl[32] = {
+ "zmm0", "zmm1", "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7", "zmm8", "zmm9", "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15",
+ "zmm16", "zmm17", "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23", "zmm24", "zmm25", "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31"
+ };
+ return tbl[idx];
+ } else if (isYMM()) {
+ static const char *tbl[32] = {
+ "ymm0", "ymm1", "ymm2", "ymm3", "ymm4", "ymm5", "ymm6", "ymm7", "ymm8", "ymm9", "ymm10", "ymm11", "ymm12", "ymm13", "ymm14", "ymm15",
+ "ymm16", "ymm17", "ymm18", "ymm19", "ymm20", "ymm21", "ymm22", "ymm23", "ymm24", "ymm25", "ymm26", "ymm27", "ymm28", "ymm29", "ymm30", "ymm31"
+ };
+ return tbl[idx];
+ } else if (isXMM()) {
+ static const char *tbl[32] = {
+ "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
+ "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23", "xmm24", "xmm25", "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31"
+ };
+ return tbl[idx];
+ } else if (isMMX()) {
+ static const char *tbl[8] = { "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7" };
+ return tbl[idx];
+ } else if (isFPU()) {
+ static const char *tbl[8] = { "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7" };
+ return tbl[idx];
+ } else if (isBNDREG()) {
+ static const char *tbl[4] = { "bnd0", "bnd1", "bnd2", "bnd3" };
+ return tbl[idx];
+ }
+ throw Error(ERR_INTERNAL);
+ }
+ bool isEqualIfNotInherited(const Operand& rhs) const { return idx_ == rhs.idx_ && kind_ == rhs.kind_ && bit_ == rhs.bit_ && zero_ == rhs.zero_ && mask_ == rhs.mask_ && rounding_ == rhs.rounding_; }
+ bool operator==(const Operand& rhs) const;
+ bool operator!=(const Operand& rhs) const { return !operator==(rhs); }
+ const Address& getAddress() const;
+ const Reg& getReg() const;
+};
+
+class Label;
+
+struct Reg8;
+struct Reg16;
+struct Reg32;
+#ifdef XBYAK64
+struct Reg64;
+#endif
+class Reg : public Operand {
+public:
+ Reg() { }
+ Reg(int idx, Kind kind, int bit = 0, bool ext8bit = false) : Operand(idx, kind, bit, ext8bit) { }
+ Reg changeBit(int bit) const { return Reg(getIdx(), getKind(), bit, isExt8bit()); }
+ uint8 getRexW() const { return isREG(64) ? 8 : 0; }
+ uint8 getRexR() const { return isExtIdx() ? 4 : 0; }
+ uint8 getRexX() const { return isExtIdx() ? 2 : 0; }
+ uint8 getRexB() const { return isExtIdx() ? 1 : 0; }
+ uint8 getRex(const Reg& base = Reg()) const
+ {
+ uint8 rex = getRexW() | getRexR() | base.getRexW() | base.getRexB();
+ if (rex || isExt8bit() || base.isExt8bit()) rex |= 0x40;
+ return rex;
+ }
+ Reg8 cvt8() const;
+ Reg16 cvt16() const;
+ Reg32 cvt32() const;
+#ifdef XBYAK64
+ Reg64 cvt64() const;
+#endif
+};
+
+inline const Reg& Operand::getReg() const
+{
+ assert(!isMEM());
+ return static_cast<const Reg&>(*this);
+}
+
+struct Reg8 : public Reg {
+ explicit Reg8(int idx = 0, bool ext8bit = false) : Reg(idx, Operand::REG, 8, ext8bit) { }
+};
+
+struct Reg16 : public Reg {
+ explicit Reg16(int idx = 0) : Reg(idx, Operand::REG, 16) { }
+};
+
+struct Mmx : public Reg {
+ explicit Mmx(int idx = 0, Kind kind = Operand::MMX, int bit = 64) : Reg(idx, kind, bit) { }
+};
+
+struct EvexModifierRounding {
+ enum {
+ T_RN_SAE = 1,
+ T_RD_SAE = 2,
+ T_RU_SAE = 3,
+ T_RZ_SAE = 4,
+ T_SAE = 5
+ };
+ explicit EvexModifierRounding(int rounding) : rounding(rounding) {}
+ int rounding;
+};
+struct EvexModifierZero{EvexModifierZero() {}};
+
+struct Xmm : public Mmx {
+ explicit Xmm(int idx = 0, Kind kind = Operand::XMM, int bit = 128) : Mmx(idx, kind, bit) { }
+ Xmm(Kind kind, int idx) : Mmx(idx, kind, kind == XMM ? 128 : kind == YMM ? 256 : 512) { }
+ Xmm operator|(const EvexModifierRounding& emr) const { Xmm r(*this); r.setRounding(emr.rounding); return r; }
+ Xmm copyAndSetIdx(int idx) const { Xmm ret(*this); ret.setIdx(idx); return ret; }
+ Xmm copyAndSetKind(Operand::Kind kind) const { Xmm ret(*this); ret.setKind(kind); return ret; }
+};
+
+struct Ymm : public Xmm {
+ explicit Ymm(int idx = 0, Kind kind = Operand::YMM, int bit = 256) : Xmm(idx, kind, bit) { }
+ Ymm operator|(const EvexModifierRounding& emr) const { Ymm r(*this); r.setRounding(emr.rounding); return r; }
+};
+
+struct Zmm : public Ymm {
+ explicit Zmm(int idx = 0) : Ymm(idx, Operand::ZMM, 512) { }
+ Zmm operator|(const EvexModifierRounding& emr) const { Zmm r(*this); r.setRounding(emr.rounding); return r; }
+};
+
+struct Opmask : public Reg {
+ explicit Opmask(int idx = 0) : Reg(idx, Operand::OPMASK, 64) {}
+};
+
+struct BoundsReg : public Reg {
+ explicit BoundsReg(int idx = 0) : Reg(idx, Operand::BNDREG, 128) {}
+};
+
+template<class T>T operator|(const T& x, const Opmask& k) { T r(x); r.setOpmaskIdx(k.getIdx()); return r; }
+template<class T>T operator|(const T& x, const EvexModifierZero&) { T r(x); r.setZero(); return r; }
+template<class T>T operator|(const T& x, const EvexModifierRounding& emr) { T r(x); r.setRounding(emr.rounding); return r; }
+
+struct Fpu : public Reg {
+ explicit Fpu(int idx = 0) : Reg(idx, Operand::FPU, 32) { }
+};
+
+struct Reg32e : public Reg {
+ explicit Reg32e(int idx, int bit) : Reg(idx, Operand::REG, bit) {}
+};
+struct Reg32 : public Reg32e {
+ explicit Reg32(int idx = 0) : Reg32e(idx, 32) {}
+};
+#ifdef XBYAK64
+struct Reg64 : public Reg32e {
+ explicit Reg64(int idx = 0) : Reg32e(idx, 64) {}
+};
+struct RegRip {
+ sint64 disp_;
+ const Label* label_;
+ bool isAddr_;
+ explicit RegRip(sint64 disp = 0, const Label* label = 0, bool isAddr = false) : disp_(disp), label_(label), isAddr_(isAddr) {}
+ friend const RegRip operator+(const RegRip& r, int disp) {
+ return RegRip(r.disp_ + disp, r.label_, r.isAddr_);
+ }
+ friend const RegRip operator-(const RegRip& r, int disp) {
+ return RegRip(r.disp_ - disp, r.label_, r.isAddr_);
+ }
+ friend const RegRip operator+(const RegRip& r, sint64 disp) {
+ return RegRip(r.disp_ + disp, r.label_, r.isAddr_);
+ }
+ friend const RegRip operator-(const RegRip& r, sint64 disp) {
+ return RegRip(r.disp_ - disp, r.label_, r.isAddr_);
+ }
+ friend const RegRip operator+(const RegRip& r, const Label& label) {
+ if (r.label_ || r.isAddr_) throw Error(ERR_BAD_ADDRESSING);
+ return RegRip(r.disp_, &label);
+ }
+ friend const RegRip operator+(const RegRip& r, const void *addr) {
+ if (r.label_ || r.isAddr_) throw Error(ERR_BAD_ADDRESSING);
+ return RegRip(r.disp_ + (sint64)addr, 0, true);
+ }
+};
+#endif
+
+inline Reg8 Reg::cvt8() const
+{
+ const int idx = getIdx();
+ if (isBit(8)) return Reg8(idx, isExt8bit());
+#ifdef XBYAK32
+ if (idx >= 4) throw Error(ERR_CANT_CONVERT);
+#endif
+ return Reg8(idx, 4 <= idx && idx < 8);
+}
+
+inline Reg16 Reg::cvt16() const
+{
+ const int idx = getIdx();
+ if (isBit(8) && (4 <= idx && idx < 8) && !isExt8bit()) throw Error(ERR_CANT_CONVERT);
+ return Reg16(idx);
+}
+
+inline Reg32 Reg::cvt32() const
+{
+ const int idx = getIdx();
+ if (isBit(8) && (4 <= idx && idx < 8) && !isExt8bit()) throw Error(ERR_CANT_CONVERT);
+ return Reg32(idx);
+}
+
+#ifdef XBYAK64
+inline Reg64 Reg::cvt64() const
+{
+ const int idx = getIdx();
+ if (isBit(8) && (4 <= idx && idx < 8) && !isExt8bit()) throw Error(ERR_CANT_CONVERT);
+ return Reg64(idx);
+}
+#endif
+
+#ifndef XBYAK_DISABLE_SEGMENT
+// not derived from Reg
+class Segment {
+ int idx_;
+public:
+ enum {
+ es, cs, ss, ds, fs, gs
+ };
+ explicit Segment(int idx) : idx_(idx) { assert(0 <= idx_ && idx_ < 6); }
+ int getIdx() const { return idx_; }
+ const char *toString() const
+ {
+ static const char tbl[][3] = {
+ "es", "cs", "ss", "ds", "fs", "gs"
+ };
+ return tbl[idx_];
+ }
+};
+#endif
+
+class RegExp {
+public:
+#ifdef XBYAK64
+ enum { i32e = 32 | 64 };
+#else
+ enum { i32e = 32 };
+#endif
+ RegExp(size_t disp = 0) : scale_(0), disp_(disp) { }
+ RegExp(const Reg& r, int scale = 1)
+ : scale_(scale)
+ , disp_(0)
+ {
+ if (!r.isREG(i32e) && !r.is(Reg::XMM|Reg::YMM|Reg::ZMM)) throw Error(ERR_BAD_SIZE_OF_REGISTER);
+ if (scale == 0) return;
+ if (scale != 1 && scale != 2 && scale != 4 && scale != 8) throw Error(ERR_BAD_SCALE);
+ if (r.getBit() >= 128 || scale != 1) { // xmm/ymm is always index
+ index_ = r;
+ } else {
+ base_ = r;
+ }
+ }
+ bool isVsib(int bit = 128 | 256 | 512) const { return index_.isBit(bit); }
+ RegExp optimize() const
+ {
+ RegExp exp = *this;
+ // [reg * 2] => [reg + reg]
+ if (index_.isBit(i32e) && !base_.getBit() && scale_ == 2) {
+ exp.base_ = index_;
+ exp.scale_ = 1;
+ }
+ return exp;
+ }
+ bool operator==(const RegExp& rhs) const
+ {
+ return base_ == rhs.base_ && index_ == rhs.index_ && disp_ == rhs.disp_ && scale_ == rhs.scale_;
+ }
+ const Reg& getBase() const { return base_; }
+ const Reg& getIndex() const { return index_; }
+ int getScale() const { return scale_; }
+ size_t getDisp() const { return disp_; }
+ void verify() const
+ {
+ if (base_.getBit() >= 128) throw Error(ERR_BAD_SIZE_OF_REGISTER);
+ if (index_.getBit() && index_.getBit() <= 64) {
+ if (index_.getIdx() == Operand::ESP) throw Error(ERR_ESP_CANT_BE_INDEX);
+ if (base_.getBit() && base_.getBit() != index_.getBit()) throw Error(ERR_BAD_SIZE_OF_REGISTER);
+ }
+ }
+ friend RegExp operator+(const RegExp& a, const RegExp& b);
+ friend RegExp operator-(const RegExp& e, size_t disp);
+ uint8 getRex() const
+ {
+ uint8 rex = index_.getRexX() | base_.getRexB();
+ return rex ? uint8(rex | 0x40) : 0;
+ }
+private:
+ /*
+ [base_ + index_ * scale_ + disp_]
+ base : Reg32e, index : Reg32e(w/o esp), Xmm, Ymm
+ */
+ Reg base_;
+ Reg index_;
+ int scale_;
+ size_t disp_;
+};
+
+inline RegExp operator+(const RegExp& a, const RegExp& b)
+{
+ if (a.index_.getBit() && b.index_.getBit()) throw Error(ERR_BAD_ADDRESSING);
+ RegExp ret = a;
+ if (!ret.index_.getBit()) { ret.index_ = b.index_; ret.scale_ = b.scale_; }
+ if (b.base_.getBit()) {
+ if (ret.base_.getBit()) {
+ if (ret.index_.getBit()) throw Error(ERR_BAD_ADDRESSING);
+ // base + base => base + index * 1
+ ret.index_ = b.base_;
+ // [reg + esp] => [esp + reg]
+ if (ret.index_.getIdx() == Operand::ESP) std::swap(ret.base_, ret.index_);
+ ret.scale_ = 1;
+ } else {
+ ret.base_ = b.base_;
+ }
+ }
+ ret.disp_ += b.disp_;
+ return ret;
+}
+inline RegExp operator*(const Reg& r, int scale)
+{
+ return RegExp(r, scale);
+}
+inline RegExp operator-(const RegExp& e, size_t disp)
+{
+ RegExp ret = e;
+ ret.disp_ -= disp;
+ return ret;
+}
+
+// 2nd parameter for constructor of CodeArray(maxSize, userPtr, alloc)
+void *const AutoGrow = (void*)1; //-V566
+void *const DontSetProtectRWE = (void*)2; //-V566
+
+class CodeArray {
+ enum Type {
+ USER_BUF = 1, // use userPtr(non alignment, non protect)
+ ALLOC_BUF, // use new(alignment, protect)
+ AUTO_GROW // automatically move and grow memory if necessary
+ };
+ CodeArray(const CodeArray& rhs);
+ void operator=(const CodeArray&);
+ bool isAllocType() const { return type_ == ALLOC_BUF || type_ == AUTO_GROW; }
+ struct AddrInfo {
+ size_t codeOffset; // position to write
+ size_t jmpAddr; // value to write
+ int jmpSize; // size of jmpAddr
+ inner::LabelMode mode;
+ AddrInfo(size_t _codeOffset, size_t _jmpAddr, int _jmpSize, inner::LabelMode _mode)
+ : codeOffset(_codeOffset), jmpAddr(_jmpAddr), jmpSize(_jmpSize), mode(_mode) {}
+ uint64 getVal(const uint8 *top) const
+ {
+ uint64 disp = (mode == inner::LaddTop) ? jmpAddr + size_t(top) : (mode == inner::LasIs) ? jmpAddr : jmpAddr - size_t(top);
+ if (jmpSize == 4) disp = inner::VerifyInInt32(disp);
+ return disp;
+ }
+ };
+ typedef std::list<AddrInfo> AddrInfoList;
+ AddrInfoList addrInfoList_;
+ const Type type_;
+#ifdef XBYAK_USE_MMAP_ALLOCATOR
+ MmapAllocator defaultAllocator_;
+#else
+ Allocator defaultAllocator_;
+#endif
+ Allocator *alloc_;
+protected:
+ size_t maxSize_;
+ uint8 *top_;
+ size_t size_;
+ bool isCalledCalcJmpAddress_;
+
+ bool useProtect() const { return alloc_->useProtect(); }
+ /*
+ allocate new memory and copy old data to the new area
+ */
+ void growMemory()
+ {
+ const size_t newSize = (std::max<size_t>)(DEFAULT_MAX_CODE_SIZE, maxSize_ * 2);
+ uint8 *newTop = alloc_->alloc(newSize);
+ if (newTop == 0) throw Error(ERR_CANT_ALLOC);
+ for (size_t i = 0; i < size_; i++) newTop[i] = top_[i];
+ alloc_->free(top_);
+ top_ = newTop;
+ maxSize_ = newSize;
+ }
+ /*
+ calc jmp address for AutoGrow mode
+ */
+ void calcJmpAddress()
+ {
+ if (isCalledCalcJmpAddress_) return;
+ for (AddrInfoList::const_iterator i = addrInfoList_.begin(), ie = addrInfoList_.end(); i != ie; ++i) {
+ uint64 disp = i->getVal(top_);
+ rewrite(i->codeOffset, disp, i->jmpSize);
+ }
+ isCalledCalcJmpAddress_ = true;
+ }
+public:
+ enum ProtectMode {
+ PROTECT_RW = 0, // read/write
+ PROTECT_RWE = 1, // read/write/exec
+ PROTECT_RE = 2 // read/exec
+ };
+ explicit CodeArray(size_t maxSize, void *userPtr = 0, Allocator *allocator = 0)
+ : type_(userPtr == AutoGrow ? AUTO_GROW : (userPtr == 0 || userPtr == DontSetProtectRWE) ? ALLOC_BUF : USER_BUF)
+ , alloc_(allocator ? allocator : (Allocator*)&defaultAllocator_)
+ , maxSize_(maxSize)
+ , top_(type_ == USER_BUF ? reinterpret_cast<uint8*>(userPtr) : alloc_->alloc((std::max<size_t>)(maxSize, 1)))
+ , size_(0)
+ , isCalledCalcJmpAddress_(false)
+ {
+ if (maxSize_ > 0 && top_ == 0) throw Error(ERR_CANT_ALLOC);
+ if ((type_ == ALLOC_BUF && userPtr != DontSetProtectRWE && useProtect()) && !setProtectMode(PROTECT_RWE, false)) {
+ alloc_->free(top_);
+ throw Error(ERR_CANT_PROTECT);
+ }
+ }
+ virtual ~CodeArray()
+ {
+ if (isAllocType()) {
+ if (useProtect()) setProtectModeRW(false);
+ alloc_->free(top_);
+ }
+ }
+ bool setProtectMode(ProtectMode mode, bool throwException = true)
+ {
+ bool isOK = protect(top_, maxSize_, mode);
+ if (isOK) return true;
+ if (throwException) throw Error(ERR_CANT_PROTECT);
+ return false;
+ }
+ bool setProtectModeRE(bool throwException = true) { return setProtectMode(PROTECT_RE, throwException); }
+ bool setProtectModeRW(bool throwException = true) { return setProtectMode(PROTECT_RW, throwException); }
+ void resetSize()
+ {
+ size_ = 0;
+ addrInfoList_.clear();
+ isCalledCalcJmpAddress_ = false;
+ }
+ void db(int code)
+ {
+ if (size_ >= maxSize_) {
+ if (type_ == AUTO_GROW) {
+ growMemory();
+ } else {
+ throw Error(ERR_CODE_IS_TOO_BIG);
+ }
+ }
+ top_[size_++] = static_cast<uint8>(code);
+ }
+ void db(const uint8 *code, size_t codeSize)
+ {
+ for (size_t i = 0; i < codeSize; i++) db(code[i]);
+ }
+ void db(uint64 code, size_t codeSize)
+ {
+ if (codeSize > 8) throw Error(ERR_BAD_PARAMETER);
+ for (size_t i = 0; i < codeSize; i++) db(static_cast<uint8>(code >> (i * 8)));
+ }
+ void dw(uint32 code) { db(code, 2); }
+ void dd(uint32 code) { db(code, 4); }
+ void dq(uint64 code) { db(code, 8); }
+ const uint8 *getCode() const { return top_; }
+ template<class F>
+ const F getCode() const { return reinterpret_cast<F>(top_); }
+ const uint8 *getCurr() const { return &top_[size_]; }
+ template<class F>
+ const F getCurr() const { return reinterpret_cast<F>(&top_[size_]); }
+ size_t getSize() const { return size_; }
+ void setSize(size_t size)
+ {
+ if (size > maxSize_) throw Error(ERR_OFFSET_IS_TOO_BIG);
+ size_ = size;
+ }
+ void dump() const
+ {
+ const uint8 *p = getCode();
+ size_t bufSize = getSize();
+ size_t remain = bufSize;
+ for (int i = 0; i < 4; i++) {
+ size_t disp = 16;
+ if (remain < 16) {
+ disp = remain;
+ }
+ for (size_t j = 0; j < 16; j++) {
+ if (j < disp) {
+ printf("%02X", p[i * 16 + j]);
+ }
+ }
+ putchar('\n');
+ remain -= disp;
+ if (remain == 0) {
+ break;
+ }
+ }
+ }
+ /*
+ @param offset [in] offset from top
+ @param disp [in] offset from the next of jmp
+ @param size [in] write size(1, 2, 4, 8)
+ */
+ void rewrite(size_t offset, uint64 disp, size_t size)
+ {
+ assert(offset < maxSize_);
+ if (size != 1 && size != 2 && size != 4 && size != 8) throw Error(ERR_BAD_PARAMETER);
+ uint8 *const data = top_ + offset;
+ for (size_t i = 0; i < size; i++) {
+ data[i] = static_cast<uint8>(disp >> (i * 8));
+ }
+ }
+ void save(size_t offset, size_t val, int size, inner::LabelMode mode)
+ {
+ addrInfoList_.push_back(AddrInfo(offset, val, size, mode));
+ }
+ bool isAutoGrow() const { return type_ == AUTO_GROW; }
+ bool isCalledCalcJmpAddress() const { return isCalledCalcJmpAddress_; }
+ /**
+ change exec permission of memory
+ @param addr [in] buffer address
+ @param size [in] buffer size
+ @param protectMode [in] mode(RW/RWE/RE)
+ @return true(success), false(failure)
+ */
+ static inline bool protect(const void *addr, size_t size, int protectMode)
+ {
+#if defined(_WIN32)
+ const DWORD c_rw = PAGE_READWRITE;
+ const DWORD c_rwe = PAGE_EXECUTE_READWRITE;
+ const DWORD c_re = PAGE_EXECUTE_READ;
+ DWORD mode;
+#else
+ const int c_rw = PROT_READ | PROT_WRITE;
+ const int c_rwe = PROT_READ | PROT_WRITE | PROT_EXEC;
+ const int c_re = PROT_READ | PROT_EXEC;
+ int mode;
+#endif
+ switch (protectMode) {
+ case PROTECT_RW: mode = c_rw; break;
+ case PROTECT_RWE: mode = c_rwe; break;
+ case PROTECT_RE: mode = c_re; break;
+ default:
+ return false;
+ }
+#if defined(_WIN32)
+ DWORD oldProtect;
+ return VirtualProtect(const_cast<void*>(addr), size, mode, &oldProtect) != 0;
+#elif defined(__GNUC__)
+ size_t pageSize = sysconf(_SC_PAGESIZE);
+ size_t iaddr = reinterpret_cast<size_t>(addr);
+ size_t roundAddr = iaddr & ~(pageSize - static_cast<size_t>(1));
+#ifndef NDEBUG
+ if (pageSize != 4096) fprintf(stderr, "large page(%zd) is used. not tested enough.\n", pageSize);
+#endif
+ return mprotect(reinterpret_cast<void*>(roundAddr), size + (iaddr - roundAddr), mode) == 0;
+#else
+ return true;
+#endif
+ }
+ /**
+ get aligned memory pointer
+ @param addr [in] address
+ @param alignedSize [in] power of two
+ @return aligned addr by alingedSize
+ */
+ static inline uint8 *getAlignedAddress(uint8 *addr, size_t alignedSize = 16)
+ {
+ return reinterpret_cast<uint8*>((reinterpret_cast<size_t>(addr) + alignedSize - 1) & ~(alignedSize - static_cast<size_t>(1)));
+ }
+};
+
+class Address : public Operand {
+public:
+ enum Mode {
+ M_ModRM,
+ M_64bitDisp,
+ M_rip,
+ M_ripAddr
+ };
+ Address(uint32 sizeBit, bool broadcast, const RegExp& e)
+ : Operand(0, MEM, sizeBit), e_(e), label_(0), mode_(M_ModRM), broadcast_(broadcast)
+ {
+ e_.verify();
+ }
+#ifdef XBYAK64
+ explicit Address(size_t disp)
+ : Operand(0, MEM, 64), e_(disp), label_(0), mode_(M_64bitDisp), broadcast_(false){ }
+ Address(uint32 sizeBit, bool broadcast, const RegRip& addr)
+ : Operand(0, MEM, sizeBit), e_(addr.disp_), label_(addr.label_), mode_(addr.isAddr_ ? M_ripAddr : M_rip), broadcast_(broadcast) { }
+#endif
+ RegExp getRegExp(bool optimize = true) const
+ {
+ return optimize ? e_.optimize() : e_;
+ }
+ Mode getMode() const { return mode_; }
+ bool is32bit() const { return e_.getBase().getBit() == 32 || e_.getIndex().getBit() == 32; }
+ bool isOnlyDisp() const { return !e_.getBase().getBit() && !e_.getIndex().getBit(); } // for mov eax
+ size_t getDisp() const { return e_.getDisp(); }
+ uint8 getRex() const
+ {
+ if (mode_ != M_ModRM) return 0;
+ return getRegExp().getRex();
+ }
+ bool is64bitDisp() const { return mode_ == M_64bitDisp; } // for moffset
+ bool isBroadcast() const { return broadcast_; }
+ const Label* getLabel() const { return label_; }
+ bool operator==(const Address& rhs) const
+ {
+ return getBit() == rhs.getBit() && e_ == rhs.e_ && label_ == rhs.label_ && mode_ == rhs.mode_ && broadcast_ == rhs.broadcast_;
+ }
+ bool operator!=(const Address& rhs) const { return !operator==(rhs); }
+ bool isVsib() const { return e_.isVsib(); }
+private:
+ RegExp e_;
+ const Label* label_;
+ Mode mode_;
+ bool broadcast_;
+};
+
+inline const Address& Operand::getAddress() const
+{
+ assert(isMEM());
+ return static_cast<const Address&>(*this);
+}
+
+inline bool Operand::operator==(const Operand& rhs) const
+{
+ if (isMEM() && rhs.isMEM()) return this->getAddress() == rhs.getAddress();
+ return isEqualIfNotInherited(rhs);
+}
+
+class AddressFrame {
+ void operator=(const AddressFrame&);
+ AddressFrame(const AddressFrame&);
+public:
+ const uint32 bit_;
+ const bool broadcast_;
+ explicit AddressFrame(uint32 bit, bool broadcast = false) : bit_(bit), broadcast_(broadcast) { }
+ Address operator[](const RegExp& e) const
+ {
+ return Address(bit_, broadcast_, e);
+ }
+ Address operator[](const void *disp) const
+ {
+ return Address(bit_, broadcast_, RegExp(reinterpret_cast<size_t>(disp)));
+ }
+#ifdef XBYAK64
+ Address operator[](uint64 disp) const { return Address(disp); }
+ Address operator[](const RegRip& addr) const { return Address(bit_, broadcast_, addr); }
+#endif
+};
+
+struct JmpLabel {
+ size_t endOfJmp; /* offset from top to the end address of jmp */
+ int jmpSize;
+ inner::LabelMode mode;
+ size_t disp; // disp for [rip + disp]
+ explicit JmpLabel(size_t endOfJmp = 0, int jmpSize = 0, inner::LabelMode mode = inner::LasIs, size_t disp = 0)
+ : endOfJmp(endOfJmp), jmpSize(jmpSize), mode(mode), disp(disp)
+ {
+ }
+};
+
+class LabelManager;
+
+class Label {
+ mutable LabelManager *mgr;
+ mutable int id;
+ friend class LabelManager;
+public:
+ Label() : mgr(0), id(0) {}
+ Label(const Label& rhs);
+ Label& operator=(const Label& rhs);
+ ~Label();
+ void clear() { mgr = 0; id = 0; }
+ int getId() const { return id; }
+ const uint8 *getAddress() const;
+
+ // backward compatibility
+ static inline std::string toStr(int num)
+ {
+ char buf[16];
+#if defined(_MSC_VER) && (_MSC_VER < 1900)
+ _snprintf_s
+#else
+ snprintf
+#endif
+ (buf, sizeof(buf), ".%08x", num);
+ return buf;
+ }
+};
+
+class LabelManager {
+ // for string label
+ struct SlabelVal {
+ size_t offset;
+ SlabelVal(size_t offset) : offset(offset) {}
+ };
+ typedef XBYAK_STD_UNORDERED_MAP<std::string, SlabelVal> SlabelDefList;
+ typedef XBYAK_STD_UNORDERED_MULTIMAP<std::string, const JmpLabel> SlabelUndefList;
+ struct SlabelState {
+ SlabelDefList defList;
+ SlabelUndefList undefList;
+ };
+ typedef std::list<SlabelState> StateList;
+ // for Label class
+ struct ClabelVal {
+ ClabelVal(size_t offset = 0) : offset(offset), refCount(1) {}
+ size_t offset;
+ int refCount;
+ };
+ typedef XBYAK_STD_UNORDERED_MAP<int, ClabelVal> ClabelDefList;
+ typedef XBYAK_STD_UNORDERED_MULTIMAP<int, const JmpLabel> ClabelUndefList;
+ typedef XBYAK_STD_UNORDERED_SET<Label*> LabelPtrList;
+
+ CodeArray *base_;
+ // global : stateList_.front(), local : stateList_.back()
+ StateList stateList_;
+ mutable int labelId_;
+ ClabelDefList clabelDefList_;
+ ClabelUndefList clabelUndefList_;
+ LabelPtrList labelPtrList_;
+
+ int getId(const Label& label) const
+ {
+ if (label.id == 0) label.id = labelId_++;
+ return label.id;
+ }
+ template<class DefList, class UndefList, class T>
+ void define_inner(DefList& defList, UndefList& undefList, const T& labelId, size_t addrOffset)
+ {
+ // add label
+ typename DefList::value_type item(labelId, addrOffset);
+ std::pair<typename DefList::iterator, bool> ret = defList.insert(item);
+ if (!ret.second) throw Error(ERR_LABEL_IS_REDEFINED);
+ // search undefined label
+ for (;;) {
+ typename UndefList::iterator itr = undefList.find(labelId);
+ if (itr == undefList.end()) break;
+ const JmpLabel *jmp = &itr->second;
+ const size_t offset = jmp->endOfJmp - jmp->jmpSize;
+ size_t disp;
+ if (jmp->mode == inner::LaddTop) {
+ disp = addrOffset;
+ } else if (jmp->mode == inner::Labs) {
+ disp = size_t(base_->getCurr());
+ } else {
+ disp = addrOffset - jmp->endOfJmp + jmp->disp;
+#ifdef XBYAK64
+ if (jmp->jmpSize <= 4 && !inner::IsInInt32(disp)) throw Error(ERR_OFFSET_IS_TOO_BIG);
+#endif
+ if (jmp->jmpSize == 1 && !inner::IsInDisp8((uint32)disp)) throw Error(ERR_LABEL_IS_TOO_FAR);
+ }
+ if (base_->isAutoGrow()) {
+ base_->save(offset, disp, jmp->jmpSize, jmp->mode);
+ } else {
+ base_->rewrite(offset, disp, jmp->jmpSize);
+ }
+ undefList.erase(itr);
+ }
+ }
+ template<class DefList, class T>
+ bool getOffset_inner(const DefList& defList, size_t *offset, const T& label) const
+ {
+ typename DefList::const_iterator i = defList.find(label);
+ if (i == defList.end()) return false;
+ *offset = i->second.offset;
+ return true;
+ }
+ friend class Label;
+ void incRefCount(int id, Label *label)
+ {
+ clabelDefList_[id].refCount++;
+ labelPtrList_.insert(label);
+ }
+ void decRefCount(int id, Label *label)
+ {
+ labelPtrList_.erase(label);
+ ClabelDefList::iterator i = clabelDefList_.find(id);
+ if (i == clabelDefList_.end()) return;
+ if (i->second.refCount == 1) {
+ clabelDefList_.erase(id);
+ } else {
+ --i->second.refCount;
+ }
+ }
+ template<class T>
+ bool hasUndefinedLabel_inner(const T& list) const
+ {
+#ifndef NDEBUG
+ for (typename T::const_iterator i = list.begin(); i != list.end(); ++i) {
+ std::cerr << "undefined label:" << i->first << std::endl;
+ }
+#endif
+ return !list.empty();
+ }
+ // detach all labels linked to LabelManager
+ void resetLabelPtrList()
+ {
+ for (LabelPtrList::iterator i = labelPtrList_.begin(), ie = labelPtrList_.end(); i != ie; ++i) {
+ (*i)->clear();
+ }
+ labelPtrList_.clear();
+ }
+public:
+ LabelManager()
+ {
+ reset();
+ }
+ ~LabelManager()
+ {
+ resetLabelPtrList();
+ }
+ void reset()
+ {
+ base_ = 0;
+ labelId_ = 1;
+ stateList_.clear();
+ stateList_.push_back(SlabelState());
+ stateList_.push_back(SlabelState());
+ clabelDefList_.clear();
+ clabelUndefList_.clear();
+ resetLabelPtrList();
+ }
+ void enterLocal()
+ {
+ stateList_.push_back(SlabelState());
+ }
+ void leaveLocal()
+ {
+ if (stateList_.size() <= 2) throw Error(ERR_UNDER_LOCAL_LABEL);
+ if (hasUndefinedLabel_inner(stateList_.back().undefList)) throw Error(ERR_LABEL_IS_NOT_FOUND);
+ stateList_.pop_back();
+ }
+ void set(CodeArray *base) { base_ = base; }
+ void defineSlabel(std::string label)
+ {
+ if (label == "@b" || label == "@f") throw Error(ERR_BAD_LABEL_STR);
+ if (label == "@@") {
+ SlabelDefList& defList = stateList_.front().defList;
+ SlabelDefList::iterator i = defList.find("@f");
+ if (i != defList.end()) {
+ defList.erase(i);
+ label = "@b";
+ } else {
+ i = defList.find("@b");
+ if (i != defList.end()) {
+ defList.erase(i);
+ }
+ label = "@f";
+ }
+ }
+ SlabelState& st = *label.c_str() == '.' ? stateList_.back() : stateList_.front();
+ define_inner(st.defList, st.undefList, label, base_->getSize());
+ }
+ void defineClabel(Label& label)
+ {
+ define_inner(clabelDefList_, clabelUndefList_, getId(label), base_->getSize());
+ label.mgr = this;
+ labelPtrList_.insert(&label);
+ }
+ void assign(Label& dst, const Label& src)
+ {
+ ClabelDefList::const_iterator i = clabelDefList_.find(src.id);
+ if (i == clabelDefList_.end()) throw Error(ERR_LABEL_ISNOT_SET_BY_L);
+ define_inner(clabelDefList_, clabelUndefList_, dst.id, i->second.offset);
+ dst.mgr = this;
+ labelPtrList_.insert(&dst);
+ }
+ bool getOffset(size_t *offset, std::string& label) const
+ {
+ const SlabelDefList& defList = stateList_.front().defList;
+ if (label == "@b") {
+ if (defList.find("@f") != defList.end()) {
+ label = "@f";
+ } else if (defList.find("@b") == defList.end()) {
+ throw Error(ERR_LABEL_IS_NOT_FOUND);
+ }
+ } else if (label == "@f") {
+ if (defList.find("@f") != defList.end()) {
+ label = "@b";
+ }
+ }
+ const SlabelState& st = *label.c_str() == '.' ? stateList_.back() : stateList_.front();
+ return getOffset_inner(st.defList, offset, label);
+ }
+ bool getOffset(size_t *offset, const Label& label) const
+ {
+ return getOffset_inner(clabelDefList_, offset, getId(label));
+ }
+ void addUndefinedLabel(const std::string& label, const JmpLabel& jmp)
+ {
+ SlabelState& st = *label.c_str() == '.' ? stateList_.back() : stateList_.front();
+ st.undefList.insert(SlabelUndefList::value_type(label, jmp));
+ }
+ void addUndefinedLabel(const Label& label, const JmpLabel& jmp)
+ {
+ clabelUndefList_.insert(ClabelUndefList::value_type(label.id, jmp));
+ }
+ bool hasUndefSlabel() const
+ {
+ for (StateList::const_iterator i = stateList_.begin(), ie = stateList_.end(); i != ie; ++i) {
+ if (hasUndefinedLabel_inner(i->undefList)) return true;
+ }
+ return false;
+ }
+ bool hasUndefClabel() const { return hasUndefinedLabel_inner(clabelUndefList_); }
+ const uint8 *getCode() const { return base_->getCode(); }
+ bool isReady() const { return !base_->isAutoGrow() || base_->isCalledCalcJmpAddress(); }
+};
+
+inline Label::Label(const Label& rhs)
+{
+ id = rhs.id;
+ mgr = rhs.mgr;
+ if (mgr) mgr->incRefCount(id, this);
+}
+inline Label& Label::operator=(const Label& rhs)
+{
+ if (id) throw Error(ERR_LABEL_IS_ALREADY_SET_BY_L);
+ id = rhs.id;
+ mgr = rhs.mgr;
+ if (mgr) mgr->incRefCount(id, this);
+ return *this;
+}
+inline Label::~Label()
+{
+ if (id && mgr) mgr->decRefCount(id, this);
+}
+inline const uint8* Label::getAddress() const
+{
+ if (mgr == 0 || !mgr->isReady()) return 0;
+ size_t offset;
+ if (!mgr->getOffset(&offset, *this)) return 0;
+ return mgr->getCode() + offset;
+}
+
+class CodeGenerator : public CodeArray {
+public:
+ enum LabelType {
+ T_SHORT,
+ T_NEAR,
+ T_AUTO // T_SHORT if possible
+ };
+private:
+ CodeGenerator operator=(const CodeGenerator&); // don't call
+#ifdef XBYAK64
+ enum { i32e = 32 | 64, BIT = 64 };
+ static const size_t dummyAddr = (size_t(0x11223344) << 32) | 55667788;
+ typedef Reg64 NativeReg;
+#else
+ enum { i32e = 32, BIT = 32 };
+ static const size_t dummyAddr = 0x12345678;
+ typedef Reg32 NativeReg;
+#endif
+ // (XMM, XMM|MEM)
+ static inline bool isXMM_XMMorMEM(const Operand& op1, const Operand& op2)
+ {
+ return op1.isXMM() && (op2.isXMM() || op2.isMEM());
+ }
+ // (MMX, MMX|MEM) or (XMM, XMM|MEM)
+ static inline bool isXMMorMMX_MEM(const Operand& op1, const Operand& op2)
+ {
+ return (op1.isMMX() && (op2.isMMX() || op2.isMEM())) || isXMM_XMMorMEM(op1, op2);
+ }
+ // (XMM, MMX|MEM)
+ static inline bool isXMM_MMXorMEM(const Operand& op1, const Operand& op2)
+ {
+ return op1.isXMM() && (op2.isMMX() || op2.isMEM());
+ }
+ // (MMX, XMM|MEM)
+ static inline bool isMMX_XMMorMEM(const Operand& op1, const Operand& op2)
+ {
+ return op1.isMMX() && (op2.isXMM() || op2.isMEM());
+ }
+ // (XMM, REG32|MEM)
+ static inline bool isXMM_REG32orMEM(const Operand& op1, const Operand& op2)
+ {
+ return op1.isXMM() && (op2.isREG(i32e) || op2.isMEM());
+ }
+ // (REG32, XMM|MEM)
+ static inline bool isREG32_XMMorMEM(const Operand& op1, const Operand& op2)
+ {
+ return op1.isREG(i32e) && (op2.isXMM() || op2.isMEM());
+ }
+ // (REG32, REG32|MEM)
+ static inline bool isREG32_REG32orMEM(const Operand& op1, const Operand& op2)
+ {
+ return op1.isREG(i32e) && ((op2.isREG(i32e) && op1.getBit() == op2.getBit()) || op2.isMEM());
+ }
+ void rex(const Operand& op1, const Operand& op2 = Operand())
+ {
+ uint8 rex = 0;
+ const Operand *p1 = &op1, *p2 = &op2;
+ if (p1->isMEM()) std::swap(p1, p2);
+ if (p1->isMEM()) throw Error(ERR_BAD_COMBINATION);
+ if (p2->isMEM()) {
+ const Address& addr = p2->getAddress();
+ if (BIT == 64 && addr.is32bit()) db(0x67);
+ rex = addr.getRex() | p1->getReg().getRex();
+ } else {
+ // ModRM(reg, base);
+ rex = op2.getReg().getRex(op1.getReg());
+ }
+ // except movsx(16bit, 32/64bit)
+ if ((op1.isBit(16) && !op2.isBit(i32e)) || (op2.isBit(16) && !op1.isBit(i32e))) db(0x66);
+ if (rex) db(rex);
+ }
+ enum AVXtype {
+ // low 3 bit
+ T_N1 = 1,
+ T_N2 = 2,
+ T_N4 = 3,
+ T_N8 = 4,
+ T_N16 = 5,
+ T_N32 = 6,
+ T_NX_MASK = 7,
+ //
+ T_N_VL = 1 << 3, // N * (1, 2, 4) for VL
+ T_DUP = 1 << 4, // N = (8, 32, 64)
+ T_66 = 1 << 5,
+ T_F3 = 1 << 6,
+ T_F2 = 1 << 7,
+ T_0F = 1 << 8,
+ T_0F38 = 1 << 9,
+ T_0F3A = 1 << 10,
+ T_L0 = 1 << 11,
+ T_L1 = 1 << 12,
+ T_W0 = 1 << 13,
+ T_W1 = 1 << 14,
+ T_EW0 = 1 << 15,
+ T_EW1 = 1 << 16,
+ T_YMM = 1 << 17, // support YMM, ZMM
+ T_EVEX = 1 << 18,
+ T_ER_X = 1 << 19, // xmm{er}
+ T_ER_Y = 1 << 20, // ymm{er}
+ T_ER_Z = 1 << 21, // zmm{er}
+ T_SAE_X = 1 << 22, // xmm{sae}
+ T_SAE_Y = 1 << 23, // ymm{sae}
+ T_SAE_Z = 1 << 24, // zmm{sae}
+ T_MUST_EVEX = 1 << 25, // contains T_EVEX
+ T_B32 = 1 << 26, // m32bcst
+ T_B64 = 1 << 27, // m64bcst
+ T_M_K = 1 << 28, // mem{k}
+ T_VSIB = 1 << 29,
+ T_MEM_EVEX = 1 << 30, // use evex if mem
+ T_XXX
+ };
+ void vex(const Reg& reg, const Reg& base, const Operand *v, int type, int code, bool x = false)
+ {
+ int w = (type & T_W1) ? 1 : 0;
+ bool is256 = (type & T_L1) ? true : (type & T_L0) ? false : reg.isYMM();
+ bool r = reg.isExtIdx();
+ bool b = base.isExtIdx();
+ int idx = v ? v->getIdx() : 0;
+ if ((idx | reg.getIdx() | base.getIdx()) >= 16) throw Error(ERR_BAD_COMBINATION);
+ uint32 pp = (type & T_66) ? 1 : (type & T_F3) ? 2 : (type & T_F2) ? 3 : 0;
+ uint32 vvvv = (((~idx) & 15) << 3) | (is256 ? 4 : 0) | pp;
+ if (!b && !x && !w && (type & T_0F)) {
+ db(0xC5); db((r ? 0 : 0x80) | vvvv);
+ } else {
+ uint32 mmmm = (type & T_0F) ? 1 : (type & T_0F38) ? 2 : (type & T_0F3A) ? 3 : 0;
+ db(0xC4); db((r ? 0 : 0x80) | (x ? 0 : 0x40) | (b ? 0 : 0x20) | mmmm); db((w << 7) | vvvv);
+ }
+ db(code);
+ }
+ void verifySAE(const Reg& r, int type) const
+ {
+ if (((type & T_SAE_X) && r.isXMM()) || ((type & T_SAE_Y) && r.isYMM()) || ((type & T_SAE_Z) && r.isZMM())) return;
+ throw Error(ERR_SAE_IS_INVALID);
+ }
+ void verifyER(const Reg& r, int type) const
+ {
+ if (((type & T_ER_X) && r.isXMM()) || ((type & T_ER_Y) && r.isYMM()) || ((type & T_ER_Z) && r.isZMM())) return;
+ throw Error(ERR_ER_IS_INVALID);
+ }
+ // (a, b, c) contains non zero two or three values then err
+ int verifyDuplicate(int a, int b, int c, int err)
+ {
+ int v = a | b | c;
+ if ((a > 0 && a != v) + (b > 0 && b != v) + (c > 0 && c != v) > 0) return Error(err);
+ return v;
+ }
+ int evex(const Reg& reg, const Reg& base, const Operand *v, int type, int code, bool x = false, bool b = false, int aaa = 0, uint32 VL = 0, bool Hi16Vidx = false)
+ {
+ if (!(type & (T_EVEX | T_MUST_EVEX))) throw Error(ERR_EVEX_IS_INVALID);
+ int w = (type & T_EW1) ? 1 : 0;
+ uint32 mm = (type & T_0F) ? 1 : (type & T_0F38) ? 2 : (type & T_0F3A) ? 3 : 0;
+ uint32 pp = (type & T_66) ? 1 : (type & T_F3) ? 2 : (type & T_F2) ? 3 : 0;
+
+ int idx = v ? v->getIdx() : 0;
+ uint32 vvvv = ~idx;
+
+ bool R = !reg.isExtIdx();
+ bool X = x ? false : !base.isExtIdx2();
+ bool B = !base.isExtIdx();
+ bool Rp = !reg.isExtIdx2();
+ int LL;
+ int rounding = verifyDuplicate(reg.getRounding(), base.getRounding(), v ? v->getRounding() : 0, ERR_ROUNDING_IS_ALREADY_SET);
+ int disp8N = 1;
+ if (rounding) {
+ if (rounding == EvexModifierRounding::T_SAE) {
+ verifySAE(base, type); LL = 0;
+ } else {
+ verifyER(base, type); LL = rounding - 1;
+ }
+ b = true;
+ } else {
+ if (v) VL = (std::max)(VL, v->getBit());
+ VL = (std::max)((std::max)(reg.getBit(), base.getBit()), VL);
+ LL = (VL == 512) ? 2 : (VL == 256) ? 1 : 0;
+ if (b) {
+ disp8N = (type & T_B32) ? 4 : 8;
+ } else if (type & T_DUP) {
+ disp8N = VL == 128 ? 8 : VL == 256 ? 32 : 64;
+ } else {
+ if ((type & (T_NX_MASK | T_N_VL)) == 0) {
+ type |= T_N16 | T_N_VL; // default
+ }
+ int low = type & T_NX_MASK;
+ if (low > 0) {
+ disp8N = 1 << (low - 1);
+ if (type & T_N_VL) disp8N *= (VL == 512 ? 4 : VL == 256 ? 2 : 1);
+ }
+ }
+ }
+ bool Vp = !((v ? v->isExtIdx2() : 0) | Hi16Vidx);
+ bool z = reg.hasZero() || base.hasZero() || (v ? v->hasZero() : false);
+ if (aaa == 0) aaa = verifyDuplicate(base.getOpmaskIdx(), reg.getOpmaskIdx(), (v ? v->getOpmaskIdx() : 0), ERR_OPMASK_IS_ALREADY_SET);
+ db(0x62);
+ db((R ? 0x80 : 0) | (X ? 0x40 : 0) | (B ? 0x20 : 0) | (Rp ? 0x10 : 0) | (mm & 3));
+ db((w == 1 ? 0x80 : 0) | ((vvvv & 15) << 3) | 4 | (pp & 3));
+ db((z ? 0x80 : 0) | ((LL & 3) << 5) | (b ? 0x10 : 0) | (Vp ? 8 : 0) | (aaa & 7));
+ db(code);
+ return disp8N;
+ }
+ void setModRM(int mod, int r1, int r2)
+ {
+ db(static_cast<uint8>((mod << 6) | ((r1 & 7) << 3) | (r2 & 7)));
+ }
+ void setSIB(const RegExp& e, int reg, int disp8N = 0)
+ {
+ size_t disp64 = e.getDisp();
+#ifdef XBYAK64
+ size_t high = disp64 >> 32;
+ if (high != 0 && high != 0xFFFFFFFF) throw Error(ERR_OFFSET_IS_TOO_BIG);
+#endif
+ uint32 disp = static_cast<uint32>(disp64);
+ const Reg& base = e.getBase();
+ const Reg& index = e.getIndex();
+ const int baseIdx = base.getIdx();
+ const int baseBit = base.getBit();
+ const int indexBit = index.getBit();
+ enum {
+ mod00 = 0, mod01 = 1, mod10 = 2
+ };
+ int mod = mod10; // disp32
+ if (!baseBit || ((baseIdx & 7) != Operand::EBP && disp == 0)) {
+ mod = mod00;
+ } else {
+ if (disp8N == 0) {
+ if (inner::IsInDisp8(disp)) {
+ mod = mod01;
+ }
+ } else {
+ // disp must be casted to signed
+ uint32 t = static_cast<uint32>(static_cast<int>(disp) / disp8N);
+ if ((disp % disp8N) == 0 && inner::IsInDisp8(t)) {
+ disp = t;
+ mod = mod01;
+ }
+ }
+ }
+ const int newBaseIdx = baseBit ? (baseIdx & 7) : Operand::EBP;
+ /* ModR/M = [2:3:3] = [Mod:reg/code:R/M] */
+ bool hasSIB = indexBit || (baseIdx & 7) == Operand::ESP;
+#ifdef XBYAK64
+ if (!baseBit && !indexBit) hasSIB = true;
+#endif
+ if (hasSIB) {
+ setModRM(mod, reg, Operand::ESP);
+ /* SIB = [2:3:3] = [SS:index:base(=rm)] */
+ const int idx = indexBit ? (index.getIdx() & 7) : Operand::ESP;
+ const int scale = e.getScale();
+ const int SS = (scale == 8) ? 3 : (scale == 4) ? 2 : (scale == 2) ? 1 : 0;
+ setModRM(SS, idx, newBaseIdx);
+ } else {
+ setModRM(mod, reg, newBaseIdx);
+ }
+ if (mod == mod01) {
+ db(disp);
+ } else if (mod == mod10 || (mod == mod00 && !baseBit)) {
+ dd(disp);
+ }
+ }
+ LabelManager labelMgr_;
+ bool isInDisp16(uint32 x) const { return 0xFFFF8000 <= x || x <= 0x7FFF; }
+ void opModR(const Reg& reg1, const Reg& reg2, int code0, int code1 = NONE, int code2 = NONE)
+ {
+ rex(reg2, reg1);
+ db(code0 | (reg1.isBit(8) ? 0 : 1)); if (code1 != NONE) db(code1); if (code2 != NONE) db(code2);
+ setModRM(3, reg1.getIdx(), reg2.getIdx());
+ }
+ void opModM(const Address& addr, const Reg& reg, int code0, int code1 = NONE, int code2 = NONE, int immSize = 0)
+ {
+ if (addr.is64bitDisp()) throw Error(ERR_CANT_USE_64BIT_DISP);
+ rex(addr, reg);
+ db(code0 | (reg.isBit(8) ? 0 : 1)); if (code1 != NONE) db(code1); if (code2 != NONE) db(code2);
+ opAddr(addr, reg.getIdx(), immSize);
+ }
+ void opMIB(const Address& addr, const Reg& reg, int code0, int code1)
+ {
+ if (addr.is64bitDisp()) throw Error(ERR_CANT_USE_64BIT_DISP);
+ if (addr.getMode() != Address::M_ModRM) throw Error(ERR_INVALID_MIB_ADDRESS);
+ if (BIT == 64 && addr.is32bit()) db(0x67);
+ const RegExp& regExp = addr.getRegExp(false);
+ uint8 rex = regExp.getRex();
+ if (rex) db(rex);
+ db(code0); db(code1);
+ setSIB(regExp, reg.getIdx());
+ }
+ void makeJmp(uint32 disp, LabelType type, uint8 shortCode, uint8 longCode, uint8 longPref)
+ {
+ const int shortJmpSize = 2;
+ const int longHeaderSize = longPref ? 2 : 1;
+ const int longJmpSize = longHeaderSize + 4;
+ if (type != T_NEAR && inner::IsInDisp8(disp - shortJmpSize)) {
+ db(shortCode); db(disp - shortJmpSize);
+ } else {
+ if (type == T_SHORT) throw Error(ERR_LABEL_IS_TOO_FAR);
+ if (longPref) db(longPref);
+ db(longCode); dd(disp - longJmpSize);
+ }
+ }
+ template<class T>
+ void opJmp(T& label, LabelType type, uint8 shortCode, uint8 longCode, uint8 longPref)
+ {
+ if (isAutoGrow() && size_ + 16 >= maxSize_) growMemory(); /* avoid splitting code of jmp */
+ size_t offset = 0;
+ if (labelMgr_.getOffset(&offset, label)) { /* label exists */
+ makeJmp(inner::VerifyInInt32(offset - size_), type, shortCode, longCode, longPref);
+ } else {
+ int jmpSize = 0;
+ if (type == T_NEAR) {
+ jmpSize = 4;
+ if (longPref) db(longPref);
+ db(longCode); dd(0);
+ } else {
+ jmpSize = 1;
+ db(shortCode); db(0);
+ }
+ JmpLabel jmp(size_, jmpSize, inner::LasIs);
+ labelMgr_.addUndefinedLabel(label, jmp);
+ }
+ }
+ void opJmpAbs(const void *addr, LabelType type, uint8 shortCode, uint8 longCode, uint8 longPref = 0)
+ {
+ if (isAutoGrow()) {
+ if (type != T_NEAR) throw Error(ERR_ONLY_T_NEAR_IS_SUPPORTED_IN_AUTO_GROW);
+ if (size_ + 16 >= maxSize_) growMemory();
+ if (longPref) db(longPref);
+ db(longCode);
+ dd(0);
+ save(size_ - 4, size_t(addr) - size_, 4, inner::Labs);
+ } else {
+ makeJmp(inner::VerifyInInt32(reinterpret_cast<const uint8*>(addr) - getCurr()), type, shortCode, longCode, longPref);
+ }
+
+ }
+ // reg is reg field of ModRM
+ // immSize is the size for immediate value
+ // disp8N = 0(normal), disp8N = 1(force disp32), disp8N = {2, 4, 8} ; compressed displacement
+ void opAddr(const Address &addr, int reg, int immSize = 0, int disp8N = 0, bool permitVisb = false)
+ {
+ if (!permitVisb && addr.isVsib()) throw Error(ERR_BAD_VSIB_ADDRESSING);
+ if (addr.getMode() == Address::M_ModRM) {
+ setSIB(addr.getRegExp(), reg, disp8N);
+ } else if (addr.getMode() == Address::M_rip || addr.getMode() == Address::M_ripAddr) {
+ setModRM(0, reg, 5);
+ if (addr.getLabel()) { // [rip + Label]
+ putL_inner(*addr.getLabel(), true, addr.getDisp() - immSize);
+ } else {
+ size_t disp = addr.getDisp();
+ if (addr.getMode() == Address::M_ripAddr) {
+ if (isAutoGrow()) throw Error(ERR_INVALID_RIP_IN_AUTO_GROW);
+ disp -= (size_t)getCurr() + 4 + immSize;
+ }
+ dd(inner::VerifyInInt32(disp));
+ }
+ }
+ }
+ /* preCode is for SSSE3/SSE4 */
+ void opGen(const Operand& reg, const Operand& op, int code, int pref, bool isValid(const Operand&, const Operand&), int imm8 = NONE, int preCode = NONE)
+ {
+ if (isValid && !isValid(reg, op)) throw Error(ERR_BAD_COMBINATION);
+ if (pref != NONE) db(pref);
+ if (op.isMEM()) {
+ opModM(op.getAddress(), reg.getReg(), 0x0F, preCode, code, (imm8 != NONE) ? 1 : 0);
+ } else {
+ opModR(reg.getReg(), op.getReg(), 0x0F, preCode, code);
+ }
+ if (imm8 != NONE) db(imm8);
+ }
+ void opMMX_IMM(const Mmx& mmx, int imm8, int code, int ext)
+ {
+ if (mmx.isXMM()) db(0x66);
+ opModR(Reg32(ext), mmx, 0x0F, code);
+ db(imm8);
+ }
+ void opMMX(const Mmx& mmx, const Operand& op, int code, int pref = 0x66, int imm8 = NONE, int preCode = NONE)
+ {
+ opGen(mmx, op, code, mmx.isXMM() ? pref : NONE, isXMMorMMX_MEM, imm8, preCode);
+ }
+ void opMovXMM(const Operand& op1, const Operand& op2, int code, int pref)
+ {
+ if (pref != NONE) db(pref);
+ if (op1.isXMM() && op2.isMEM()) {
+ opModM(op2.getAddress(), op1.getReg(), 0x0F, code);
+ } else if (op1.isMEM() && op2.isXMM()) {
+ opModM(op1.getAddress(), op2.getReg(), 0x0F, code | 1);
+ } else {
+ throw Error(ERR_BAD_COMBINATION);
+ }
+ }
+ void opExt(const Operand& op, const Mmx& mmx, int code, int imm, bool hasMMX2 = false)
+ {
+ if (hasMMX2 && op.isREG(i32e)) { /* pextrw is special */
+ if (mmx.isXMM()) db(0x66);
+ opModR(op.getReg(), mmx, 0x0F, 0xC5); db(imm);
+ } else {
+ opGen(mmx, op, code, 0x66, isXMM_REG32orMEM, imm, 0x3A);
+ }
+ }
+ void opR_ModM(const Operand& op, int bit, int ext, int code0, int code1 = NONE, int code2 = NONE, bool disableRex = false, int immSize = 0)
+ {
+ int opBit = op.getBit();
+ if (disableRex && opBit == 64) opBit = 32;
+ if (op.isREG(bit)) {
+ opModR(Reg(ext, Operand::REG, opBit), op.getReg().changeBit(opBit), code0, code1, code2);
+ } else if (op.isMEM()) {
+ opModM(op.getAddress(), Reg(ext, Operand::REG, opBit), code0, code1, code2, immSize);
+ } else {
+ throw Error(ERR_BAD_COMBINATION);
+ }
+ }
+ void opShift(const Operand& op, int imm, int ext)
+ {
+ verifyMemHasSize(op);
+ opR_ModM(op, 0, ext, (0xC0 | ((imm == 1 ? 1 : 0) << 4)), NONE, NONE, false, (imm != 1) ? 1 : 0);
+ if (imm != 1) db(imm);
+ }
+ void opShift(const Operand& op, const Reg8& _cl, int ext)
+ {
+ if (_cl.getIdx() != Operand::CL) throw Error(ERR_BAD_COMBINATION);
+ opR_ModM(op, 0, ext, 0xD2);
+ }
+ void opModRM(const Operand& op1, const Operand& op2, bool condR, bool condM, int code0, int code1 = NONE, int code2 = NONE, int immSize = 0)
+ {
+ if (condR) {
+ opModR(op1.getReg(), op2.getReg(), code0, code1, code2);
+ } else if (condM) {
+ opModM(op2.getAddress(), op1.getReg(), code0, code1, code2, immSize);
+ } else {
+ throw Error(ERR_BAD_COMBINATION);
+ }
+ }
+ void opShxd(const Operand& op, const Reg& reg, uint8 imm, int code, const Reg8 *_cl = 0)
+ {
+ if (_cl && _cl->getIdx() != Operand::CL) throw Error(ERR_BAD_COMBINATION);
+ opModRM(reg, op, (op.isREG(16 | i32e) && op.getBit() == reg.getBit()), op.isMEM() && (reg.isREG(16 | i32e)), 0x0F, code | (_cl ? 1 : 0), NONE, _cl ? 0 : 1);
+ if (!_cl) db(imm);
+ }
+ // (REG, REG|MEM), (MEM, REG)
+ void opRM_RM(const Operand& op1, const Operand& op2, int code)
+ {
+ if (op1.isREG() && op2.isMEM()) {
+ opModM(op2.getAddress(), op1.getReg(), code | 2);
+ } else {
+ opModRM(op2, op1, op1.isREG() && op1.getKind() == op2.getKind(), op1.isMEM() && op2.isREG(), code);
+ }
+ }
+ // (REG|MEM, IMM)
+ void opRM_I(const Operand& op, uint32 imm, int code, int ext)
+ {
+ verifyMemHasSize(op);
+ uint32 immBit = inner::IsInDisp8(imm) ? 8 : isInDisp16(imm) ? 16 : 32;
+ if (op.isBit(8)) immBit = 8;
+ if (op.getBit() < immBit) throw Error(ERR_IMM_IS_TOO_BIG);
+ if (op.isBit(32|64) && immBit == 16) immBit = 32; /* don't use MEM16 if 32/64bit mode */
+ if (op.isREG() && op.getIdx() == 0 && (op.getBit() == immBit || (op.isBit(64) && immBit == 32))) { // rax, eax, ax, al
+ rex(op);
+ db(code | 4 | (immBit == 8 ? 0 : 1));
+ } else {
+ int tmp = immBit < (std::min)(op.getBit(), 32U) ? 2 : 0;
+ opR_ModM(op, 0, ext, 0x80 | tmp, NONE, NONE, false, immBit / 8);
+ }
+ db(imm, immBit / 8);
+ }
+ void opIncDec(const Operand& op, int code, int ext)
+ {
+ verifyMemHasSize(op);
+#ifndef XBYAK64
+ if (op.isREG() && !op.isBit(8)) {
+ rex(op); db(code | op.getIdx());
+ return;
+ }
+#endif
+ code = 0xFE;
+ if (op.isREG()) {
+ opModR(Reg(ext, Operand::REG, op.getBit()), op.getReg(), code);
+ } else {
+ opModM(op.getAddress(), Reg(ext, Operand::REG, op.getBit()), code);
+ }
+ }
+ void opPushPop(const Operand& op, int code, int ext, int alt)
+ {
+ int bit = op.getBit();
+ if (bit == 16 || bit == BIT) {
+ if (bit == 16) db(0x66);
+ if (op.isREG()) {
+ if (op.getReg().getIdx() >= 8) db(0x41);
+ db(alt | (op.getIdx() & 7));
+ return;
+ }
+ if (op.isMEM()) {
+ opModM(op.getAddress(), Reg(ext, Operand::REG, 32), code);
+ return;
+ }
+ }
+ throw Error(ERR_BAD_COMBINATION);
+ }
+ void verifyMemHasSize(const Operand& op) const
+ {
+ if (op.isMEM() && op.getBit() == 0) throw Error(ERR_MEM_SIZE_IS_NOT_SPECIFIED);
+ }
+ /*
+ mov(r, imm) = db(imm, mov_imm(r, imm))
+ */
+ int mov_imm(const Reg& reg, size_t imm)
+ {
+ int bit = reg.getBit();
+ const int idx = reg.getIdx();
+ int code = 0xB0 | ((bit == 8 ? 0 : 1) << 3);
+ if (bit == 64 && (imm & ~size_t(0xffffffffu)) == 0) {
+ rex(Reg32(idx));
+ bit = 32;
+ } else {
+ rex(reg);
+ if (bit == 64 && inner::IsInInt32(imm)) {
+ db(0xC7);
+ code = 0xC0;
+ bit = 32;
+ }
+ }
+ db(code | (idx & 7));
+ return bit / 8;
+ }
+ template<class T>
+ void putL_inner(T& label, bool relative = false, size_t disp = 0)
+ {
+ const int jmpSize = relative ? 4 : (int)sizeof(size_t);
+ if (isAutoGrow() && size_ + 16 >= maxSize_) growMemory();
+ size_t offset = 0;
+ if (labelMgr_.getOffset(&offset, label)) {
+ if (relative) {
+ db(inner::VerifyInInt32(offset + disp - size_ - jmpSize), jmpSize);
+ } else if (isAutoGrow()) {
+ db(uint64(0), jmpSize);
+ save(size_ - jmpSize, offset, jmpSize, inner::LaddTop);
+ } else {
+ db(size_t(top_) + offset, jmpSize);
+ }
+ return;
+ }
+ db(uint64(0), jmpSize);
+ JmpLabel jmp(size_, jmpSize, (relative ? inner::LasIs : isAutoGrow() ? inner::LaddTop : inner::Labs), disp);
+ labelMgr_.addUndefinedLabel(label, jmp);
+ }
+ void opMovxx(const Reg& reg, const Operand& op, uint8 code)
+ {
+ if (op.isBit(32)) throw Error(ERR_BAD_COMBINATION);
+ int w = op.isBit(16);
+#ifdef XBYAK64
+ if (op.isHigh8bit()) throw Error(ERR_BAD_COMBINATION);
+#endif
+ bool cond = reg.isREG() && (reg.getBit() > op.getBit());
+ opModRM(reg, op, cond && op.isREG(), cond && op.isMEM(), 0x0F, code | w);
+ }
+ void opFpuMem(const Address& addr, uint8 m16, uint8 m32, uint8 m64, uint8 ext, uint8 m64ext)
+ {
+ if (addr.is64bitDisp()) throw Error(ERR_CANT_USE_64BIT_DISP);
+ uint8 code = addr.isBit(16) ? m16 : addr.isBit(32) ? m32 : addr.isBit(64) ? m64 : 0;
+ if (!code) throw Error(ERR_BAD_MEM_SIZE);
+ if (m64ext && addr.isBit(64)) ext = m64ext;
+
+ rex(addr, st0);
+ db(code);
+ opAddr(addr, ext);
+ }
+ // use code1 if reg1 == st0
+ // use code2 if reg1 != st0 && reg2 == st0
+ void opFpuFpu(const Fpu& reg1, const Fpu& reg2, uint32 code1, uint32 code2)
+ {
+ uint32 code = reg1.getIdx() == 0 ? code1 : reg2.getIdx() == 0 ? code2 : 0;
+ if (!code) throw Error(ERR_BAD_ST_COMBINATION);
+ db(uint8(code >> 8));
+ db(uint8(code | (reg1.getIdx() | reg2.getIdx())));
+ }
+ void opFpu(const Fpu& reg, uint8 code1, uint8 code2)
+ {
+ db(code1); db(code2 | reg.getIdx());
+ }
+ void opVex(const Reg& r, const Operand *p1, const Operand& op2, int type, int code, int imm8 = NONE)
+ {
+ if (op2.isMEM()) {
+ const Address& addr = op2.getAddress();
+ const RegExp& regExp = addr.getRegExp();
+ const Reg& base = regExp.getBase();
+ const Reg& index = regExp.getIndex();
+ if (BIT == 64 && addr.is32bit()) db(0x67);
+ int disp8N = 0;
+ bool x = index.isExtIdx();
+ if ((type & (T_MUST_EVEX|T_MEM_EVEX)) || r.hasEvex() || (p1 && p1->hasEvex()) || addr.isBroadcast() || addr.getOpmaskIdx()) {
+ int aaa = addr.getOpmaskIdx();
+ if (aaa && !(type & T_M_K)) throw Error(ERR_INVALID_OPMASK_WITH_MEMORY);
+ bool b = false;
+ if (addr.isBroadcast()) {
+ if (!(type & (T_B32 | T_B64))) throw Error(ERR_INVALID_BROADCAST);
+ b = true;
+ }
+ int VL = regExp.isVsib() ? index.getBit() : 0;
+ disp8N = evex(r, base, p1, type, code, x, b, aaa, VL, index.isExtIdx2());
+ } else {
+ vex(r, base, p1, type, code, x);
+ }
+ opAddr(addr, r.getIdx(), (imm8 != NONE) ? 1 : 0, disp8N, (type & T_VSIB) != 0);
+ } else {
+ const Reg& base = op2.getReg();
+ if ((type & T_MUST_EVEX) || r.hasEvex() || (p1 && p1->hasEvex()) || base.hasEvex()) {
+ evex(r, base, p1, type, code);
+ } else {
+ vex(r, base, p1, type, code);
+ }
+ setModRM(3, r.getIdx(), base.getIdx());
+ }
+ if (imm8 != NONE) db(imm8);
+ }
+ // (r, r, r/m) if isR_R_RM
+ // (r, r/m, r)
+ void opGpr(const Reg32e& r, const Operand& op1, const Operand& op2, int type, uint8 code, bool isR_R_RM, int imm8 = NONE)
+ {
+ const Operand *p1 = &op1;
+ const Operand *p2 = &op2;
+ if (!isR_R_RM) std::swap(p1, p2);
+ const unsigned int bit = r.getBit();
+ if (p1->getBit() != bit || (p2->isREG() && p2->getBit() != bit)) throw Error(ERR_BAD_COMBINATION);
+ type |= (bit == 64) ? T_W1 : T_W0;
+ opVex(r, p1, *p2, type, code, imm8);
+ }
+ void opAVX_X_X_XM(const Xmm& x1, const Operand& op1, const Operand& op2, int type, int code0, int imm8 = NONE)
+ {
+ const Xmm *x2 = static_cast<const Xmm*>(&op1);
+ const Operand *op = &op2;
+ if (op2.isNone()) { // (x1, op1) -> (x1, x1, op1)
+ x2 = &x1;
+ op = &op1;
+ }
+ // (x1, x2, op)
+ if (!((x1.isXMM() && x2->isXMM()) || ((type & T_YMM) && ((x1.isYMM() && x2->isYMM()) || (x1.isZMM() && x2->isZMM()))))) throw Error(ERR_BAD_COMBINATION);
+ opVex(x1, x2, *op, type, code0, imm8);
+ }
+ void opAVX_K_X_XM(const Opmask& k, const Xmm& x2, const Operand& op3, int type, int code0, int imm8 = NONE)
+ {
+ if (!op3.isMEM() && (x2.getKind() != op3.getKind())) throw Error(ERR_BAD_COMBINATION);
+ opVex(k, &x2, op3, type, code0, imm8);
+ }
+ // (x, x/m), (y, x/m256), (z, y/m)
+ void checkCvt1(const Operand& x, const Operand& op) const
+ {
+ if (!op.isMEM() && !(x.is(Operand::XMM | Operand::YMM) && op.isXMM()) && !(x.isZMM() && op.isYMM())) throw Error(ERR_BAD_COMBINATION);
+ }
+ // (x, x/m), (x, y/m256), (y, z/m)
+ void checkCvt2(const Xmm& x, const Operand& op) const
+ {
+ if (!(x.isXMM() && op.is(Operand::XMM | Operand::YMM | Operand::MEM)) && !(x.isYMM() && op.is(Operand::ZMM | Operand::MEM))) throw Error(ERR_BAD_COMBINATION);
+ }
+ void opCvt2(const Xmm& x, const Operand& op, int type, int code)
+ {
+ checkCvt2(x, op);
+ Operand::Kind kind = x.isXMM() ? (op.isBit(256) ? Operand::YMM : Operand::XMM) : Operand::ZMM;
+ opVex(x.copyAndSetKind(kind), &xm0, op, type, code);
+ }
+ void opCvt3(const Xmm& x1, const Xmm& x2, const Operand& op, int type, int type64, int type32, uint8 code)
+ {
+ if (!(x1.isXMM() && x2.isXMM() && (op.isREG(i32e) || op.isMEM()))) throw Error(ERR_BAD_SIZE_OF_REGISTER);
+ Xmm x(op.getIdx());
+ const Operand *p = op.isREG() ? &x : &op;
+ opVex(x1, &x2, *p, type | (op.isBit(64) ? type64 : type32), code);
+ }
+ const Xmm& cvtIdx0(const Operand& x) const
+ {
+ return x.isZMM() ? zm0 : x.isYMM() ? ym0 : xm0;
+ }
+ // support (x, x/m, imm), (y, y/m, imm)
+ void opAVX_X_XM_IMM(const Xmm& x, const Operand& op, int type, int code, int imm8 = NONE)
+ {
+ opAVX_X_X_XM(x, cvtIdx0(x), op, type, code, imm8);
+ }
+ // QQQ:need to refactor
+ void opSp1(const Reg& reg, const Operand& op, uint8 pref, uint8 code0, uint8 code1)
+ {
+ if (reg.isBit(8)) throw Error(ERR_BAD_SIZE_OF_REGISTER);
+ bool is16bit = reg.isREG(16) && (op.isREG(16) || op.isMEM());
+ if (!is16bit && !(reg.isREG(i32e) && (op.isREG(reg.getBit()) || op.isMEM()))) throw Error(ERR_BAD_COMBINATION);
+ if (is16bit) db(0x66);
+ db(pref); opModRM(reg.changeBit(i32e == 32 ? 32 : reg.getBit()), op, op.isREG(), true, code0, code1);
+ }
+ void opGather(const Xmm& x1, const Address& addr, const Xmm& x2, int type, uint8 code, int mode)
+ {
+ const RegExp& regExp = addr.getRegExp();
+ if (!regExp.isVsib(128 | 256)) throw Error(ERR_BAD_VSIB_ADDRESSING);
+ const int y_vx_y = 0;
+ const int y_vy_y = 1;
+// const int x_vy_x = 2;
+ const bool isAddrYMM = regExp.getIndex().getBit() == 256;
+ if (!x1.isXMM() || isAddrYMM || !x2.isXMM()) {
+ bool isOK = false;
+ if (mode == y_vx_y) {
+ isOK = x1.isYMM() && !isAddrYMM && x2.isYMM();
+ } else if (mode == y_vy_y) {
+ isOK = x1.isYMM() && isAddrYMM && x2.isYMM();
+ } else { // x_vy_x
+ isOK = !x1.isYMM() && isAddrYMM && !x2.isYMM();
+ }
+ if (!isOK) throw Error(ERR_BAD_VSIB_ADDRESSING);
+ }
+ opAVX_X_X_XM(isAddrYMM ? Ymm(x1.getIdx()) : x1, isAddrYMM ? Ymm(x2.getIdx()) : x2, addr, type, code);
+ }
+ enum {
+ xx_yy_zz = 0,
+ xx_yx_zy = 1,
+ xx_xy_yz = 2
+ };
+ void checkGather2(const Xmm& x1, const Reg& x2, int mode) const
+ {
+ if (x1.isXMM() && x2.isXMM()) return;
+ switch (mode) {
+ case xx_yy_zz: if ((x1.isYMM() && x2.isYMM()) || (x1.isZMM() && x2.isZMM())) return;
+ break;
+ case xx_yx_zy: if ((x1.isYMM() && x2.isXMM()) || (x1.isZMM() && x2.isYMM())) return;
+ break;
+ case xx_xy_yz: if ((x1.isXMM() && x2.isYMM()) || (x1.isYMM() && x2.isZMM())) return;
+ break;
+ }
+ throw Error(ERR_BAD_VSIB_ADDRESSING);
+ }
+ void opGather2(const Xmm& x, const Address& addr, int type, uint8 code, int mode)
+ {
+ if (x.hasZero()) throw Error(ERR_INVALID_ZERO);
+ checkGather2(x, addr.getRegExp().getIndex(), mode);
+ opVex(x, 0, addr, type, code);
+ }
+ /*
+ xx_xy_yz ; mode = true
+ xx_xy_xz ; mode = false
+ */
+ void opVmov(const Operand& op, const Xmm& x, int type, uint8 code, bool mode)
+ {
+ if (mode) {
+ if (!op.isMEM() && !((op.isXMM() && x.isXMM()) || (op.isXMM() && x.isYMM()) || (op.isYMM() && x.isZMM()))) throw Error(ERR_BAD_COMBINATION);
+ } else {
+ if (!op.isMEM() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION);
+ }
+ opVex(x, 0, op, type, code);
+ }
+ void opGatherFetch(const Address& addr, const Xmm& x, int type, uint8 code, Operand::Kind kind)
+ {
+ if (addr.hasZero()) throw Error(ERR_INVALID_ZERO);
+ if (addr.getRegExp().getIndex().getKind() != kind) throw Error(ERR_BAD_VSIB_ADDRESSING);
+ opVex(x, 0, addr, type, code);
+ }
+public:
+ unsigned int getVersion() const { return VERSION; }
+ using CodeArray::db;
+ const Mmx mm0, mm1, mm2, mm3, mm4, mm5, mm6, mm7;
+ const Xmm xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7;
+ const Ymm ymm0, ymm1, ymm2, ymm3, ymm4, ymm5, ymm6, ymm7;
+ const Zmm zmm0, zmm1, zmm2, zmm3, zmm4, zmm5, zmm6, zmm7;
+ const Xmm &xm0, &xm1, &xm2, &xm3, &xm4, &xm5, &xm6, &xm7;
+ const Ymm &ym0, &ym1, &ym2, &ym3, &ym4, &ym5, &ym6, &ym7;
+ const Ymm &zm0, &zm1, &zm2, &zm3, &zm4, &zm5, &zm6, &zm7;
+ const Reg32 eax, ecx, edx, ebx, esp, ebp, esi, edi;
+ const Reg16 ax, cx, dx, bx, sp, bp, si, di;
+ const Reg8 al, cl, dl, bl, ah, ch, dh, bh;
+ const AddressFrame ptr, byte, word, dword, qword, xword, yword, zword; // xword is same as oword of NASM
+ const AddressFrame ptr_b, xword_b, yword_b, zword_b; // broadcast such as {1to2}, {1to4}, {1to8}, {1to16}, {b}
+ const Fpu st0, st1, st2, st3, st4, st5, st6, st7;
+ const Opmask k0, k1, k2, k3, k4, k5, k6, k7;
+ const BoundsReg bnd0, bnd1, bnd2, bnd3;
+ const EvexModifierRounding T_sae, T_rn_sae, T_rd_sae, T_ru_sae, T_rz_sae; // {sae}, {rn-sae}, {rd-sae}, {ru-sae}, {rz-sae}
+ const EvexModifierZero T_z; // {z}
+#ifdef XBYAK64
+ const Reg64 rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15;
+ const Reg32 r8d, r9d, r10d, r11d, r12d, r13d, r14d, r15d;
+ const Reg16 r8w, r9w, r10w, r11w, r12w, r13w, r14w, r15w;
+ const Reg8 r8b, r9b, r10b, r11b, r12b, r13b, r14b, r15b;
+ const Reg8 spl, bpl, sil, dil;
+ const Xmm xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15;
+ const Xmm xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23;
+ const Xmm xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31;
+ const Ymm ymm8, ymm9, ymm10, ymm11, ymm12, ymm13, ymm14, ymm15;
+ const Ymm ymm16, ymm17, ymm18, ymm19, ymm20, ymm21, ymm22, ymm23;
+ const Ymm ymm24, ymm25, ymm26, ymm27, ymm28, ymm29, ymm30, ymm31;
+ const Zmm zmm8, zmm9, zmm10, zmm11, zmm12, zmm13, zmm14, zmm15;
+ const Zmm zmm16, zmm17, zmm18, zmm19, zmm20, zmm21, zmm22, zmm23;
+ const Zmm zmm24, zmm25, zmm26, zmm27, zmm28, zmm29, zmm30, zmm31;
+ const Xmm &xm8, &xm9, &xm10, &xm11, &xm12, &xm13, &xm14, &xm15; // for my convenience
+ const Xmm &xm16, &xm17, &xm18, &xm19, &xm20, &xm21, &xm22, &xm23;
+ const Xmm &xm24, &xm25, &xm26, &xm27, &xm28, &xm29, &xm30, &xm31;
+ const Ymm &ym8, &ym9, &ym10, &ym11, &ym12, &ym13, &ym14, &ym15;
+ const Ymm &ym16, &ym17, &ym18, &ym19, &ym20, &ym21, &ym22, &ym23;
+ const Ymm &ym24, &ym25, &ym26, &ym27, &ym28, &ym29, &ym30, &ym31;
+ const Zmm &zm8, &zm9, &zm10, &zm11, &zm12, &zm13, &zm14, &zm15;
+ const Zmm &zm16, &zm17, &zm18, &zm19, &zm20, &zm21, &zm22, &zm23;
+ const Zmm &zm24, &zm25, &zm26, &zm27, &zm28, &zm29, &zm30, &zm31;
+ const RegRip rip;
+#endif
+#ifndef XBYAK_DISABLE_SEGMENT
+ const Segment es, cs, ss, ds, fs, gs;
+#endif
+ void L(const std::string& label) { labelMgr_.defineSlabel(label); }
+ void L(Label& label) { labelMgr_.defineClabel(label); }
+ Label L() { Label label; L(label); return label; }
+ void inLocalLabel() { labelMgr_.enterLocal(); }
+ void outLocalLabel() { labelMgr_.leaveLocal(); }
+ /*
+ assign src to dst
+ require
+ dst : does not used by L()
+ src : used by L()
+ */
+ void assignL(Label& dst, const Label& src) { labelMgr_.assign(dst, src); }
+ /*
+ put address of label to buffer
+ @note the put size is 4(32-bit), 8(64-bit)
+ */
+ void putL(std::string label) { putL_inner(label); }
+ void putL(const Label& label) { putL_inner(label); }
+
+ void jmp(const Operand& op) { opR_ModM(op, BIT, 4, 0xFF, NONE, NONE, true); }
+ void jmp(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0xEB, 0xE9, 0); }
+ void jmp(const char *label, LabelType type = T_AUTO) { jmp(std::string(label), type); }
+ void jmp(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0xEB, 0xE9, 0); }
+ void jmp(const void *addr, LabelType type = T_AUTO) { opJmpAbs(addr, type, 0xEB, 0xE9); }
+
+ void call(const Operand& op) { opR_ModM(op, 16 | i32e, 2, 0xFF, NONE, NONE, true); }
+ // call(string label), not const std::string&
+ void call(std::string label) { opJmp(label, T_NEAR, 0, 0xE8, 0); }
+ void call(const char *label) { call(std::string(label)); }
+ void call(const Label& label) { opJmp(label, T_NEAR, 0, 0xE8, 0); }
+ // call(function pointer)
+#ifdef XBYAK_VARIADIC_TEMPLATE
+ template<class Ret, class... Params>
+ void call(Ret(*func)(Params...)) { call(reinterpret_cast<const void*>(func)); }
+#endif
+ void call(const void *addr) { opJmpAbs(addr, T_NEAR, 0, 0xE8); }
+
+ void test(const Operand& op, const Reg& reg)
+ {
+ opModRM(reg, op, op.isREG() && (op.getKind() == reg.getKind()), op.isMEM(), 0x84);
+ }
+ void test(const Operand& op, uint32 imm)
+ {
+ verifyMemHasSize(op);
+ int immSize = (std::min)(op.getBit() / 8, 4U);
+ if (op.isREG() && op.getIdx() == 0) { // al, ax, eax
+ rex(op);
+ db(0xA8 | (op.isBit(8) ? 0 : 1));
+ } else {
+ opR_ModM(op, 0, 0, 0xF6, NONE, NONE, false, immSize);
+ }
+ db(imm, immSize);
+ }
+ void imul(const Reg& reg, const Operand& op)
+ {
+ opModRM(reg, op, op.isREG() && (reg.getKind() == op.getKind()), op.isMEM(), 0x0F, 0xAF);
+ }
+ void imul(const Reg& reg, const Operand& op, int imm)
+ {
+ int s = inner::IsInDisp8(imm) ? 1 : 0;
+ int immSize = s ? 1 : reg.isREG(16) ? 2 : 4;
+ opModRM(reg, op, op.isREG() && (reg.getKind() == op.getKind()), op.isMEM(), 0x69 | (s << 1), NONE, NONE, immSize);
+ db(imm, immSize);
+ }
+ void push(const Operand& op) { opPushPop(op, 0xFF, 6, 0x50); }
+ void pop(const Operand& op) { opPushPop(op, 0x8F, 0, 0x58); }
+ void push(const AddressFrame& af, uint32 imm)
+ {
+ if (af.bit_ == 8 && inner::IsInDisp8(imm)) {
+ db(0x6A); db(imm);
+ } else if (af.bit_ == 16 && isInDisp16(imm)) {
+ db(0x66); db(0x68); dw(imm);
+ } else {
+ db(0x68); dd(imm);
+ }
+ }
+ /* use "push(word, 4)" if you want "push word 4" */
+ void push(uint32 imm)
+ {
+ if (inner::IsInDisp8(imm)) {
+ push(byte, imm);
+ } else {
+ push(dword, imm);
+ }
+ }
+ void mov(const Operand& reg1, const Operand& reg2)
+ {
+ const Reg *reg = 0;
+ const Address *addr = 0;
+ uint8 code = 0;
+ if (reg1.isREG() && reg1.getIdx() == 0 && reg2.isMEM()) { // mov eax|ax|al, [disp]
+ reg = &reg1.getReg();
+ addr= &reg2.getAddress();
+ code = 0xA0;
+ } else
+ if (reg1.isMEM() && reg2.isREG() && reg2.getIdx() == 0) { // mov [disp], eax|ax|al
+ reg = &reg2.getReg();
+ addr= &reg1.getAddress();
+ code = 0xA2;
+ }
+#ifdef XBYAK64
+ if (addr && addr->is64bitDisp()) {
+ if (code) {
+ rex(*reg);
+ db(reg1.isREG(8) ? 0xA0 : reg1.isREG() ? 0xA1 : reg2.isREG(8) ? 0xA2 : 0xA3);
+ db(addr->getDisp(), 8);
+ } else {
+ throw Error(ERR_BAD_COMBINATION);
+ }
+ } else
+#else
+ if (code && addr->isOnlyDisp()) {
+ rex(*reg, *addr);
+ db(code | (reg->isBit(8) ? 0 : 1));
+ dd(static_cast<uint32>(addr->getDisp()));
+ } else
+#endif
+ {
+ opRM_RM(reg1, reg2, 0x88);
+ }
+ }
+ void mov(const Operand& op, size_t imm)
+ {
+ if (op.isREG()) {
+ const int size = mov_imm(op.getReg(), imm);
+ db(imm, size);
+ } else if (op.isMEM()) {
+ verifyMemHasSize(op);
+ int immSize = op.getBit() / 8;
+ if (immSize <= 4) {
+ sint64 s = sint64(imm) >> (immSize * 8);
+ if (s != 0 && s != -1) throw Error(ERR_IMM_IS_TOO_BIG);
+ } else {
+ if (!inner::IsInInt32(imm)) throw Error(ERR_IMM_IS_TOO_BIG);
+ immSize = 4;
+ }
+ opModM(op.getAddress(), Reg(0, Operand::REG, op.getBit()), 0xC6, NONE, NONE, immSize);
+ db(static_cast<uint32>(imm), immSize);
+ } else {
+ throw Error(ERR_BAD_COMBINATION);
+ }
+ }
+ void mov(const NativeReg& reg, const char *label) // can't use std::string
+ {
+ if (label == 0) {
+ mov(static_cast<const Operand&>(reg), 0); // call imm
+ return;
+ }
+ mov_imm(reg, dummyAddr);
+ putL(label);
+ }
+ void mov(const NativeReg& reg, const Label& label)
+ {
+ mov_imm(reg, dummyAddr);
+ putL(label);
+ }
+ void xchg(const Operand& op1, const Operand& op2)
+ {
+ const Operand *p1 = &op1, *p2 = &op2;
+ if (p1->isMEM() || (p2->isREG(16 | i32e) && p2->getIdx() == 0)) {
+ p1 = &op2; p2 = &op1;
+ }
+ if (p1->isMEM()) throw Error(ERR_BAD_COMBINATION);
+ if (p2->isREG() && (p1->isREG(16 | i32e) && p1->getIdx() == 0)
+#ifdef XBYAK64
+ && (p2->getIdx() != 0 || !p1->isREG(32))
+#endif
+ ) {
+ rex(*p2, *p1); db(0x90 | (p2->getIdx() & 7));
+ return;
+ }
+ opModRM(*p1, *p2, (p1->isREG() && p2->isREG() && (p1->getBit() == p2->getBit())), p2->isMEM(), 0x86 | (p1->isBit(8) ? 0 : 1));
+ }
+
+#ifndef XBYAK_DISABLE_SEGMENT
+ void push(const Segment& seg)
+ {
+ switch (seg.getIdx()) {
+ case Segment::es: db(0x06); break;
+ case Segment::cs: db(0x0E); break;
+ case Segment::ss: db(0x16); break;
+ case Segment::ds: db(0x1E); break;
+ case Segment::fs: db(0x0F); db(0xA0); break;
+ case Segment::gs: db(0x0F); db(0xA8); break;
+ default:
+ assert(0);
+ }
+ }
+ void pop(const Segment& seg)
+ {
+ switch (seg.getIdx()) {
+ case Segment::es: db(0x07); break;
+ case Segment::cs: throw Error(ERR_BAD_COMBINATION);
+ case Segment::ss: db(0x17); break;
+ case Segment::ds: db(0x1F); break;
+ case Segment::fs: db(0x0F); db(0xA1); break;
+ case Segment::gs: db(0x0F); db(0xA9); break;
+ default:
+ assert(0);
+ }
+ }
+ void putSeg(const Segment& seg)
+ {
+ switch (seg.getIdx()) {
+ case Segment::es: db(0x2E); break;
+ case Segment::cs: db(0x36); break;
+ case Segment::ss: db(0x3E); break;
+ case Segment::ds: db(0x26); break;
+ case Segment::fs: db(0x64); break;
+ case Segment::gs: db(0x65); break;
+ default:
+ assert(0);
+ }
+ }
+ void mov(const Operand& op, const Segment& seg)
+ {
+ opModRM(Reg8(seg.getIdx()), op, op.isREG(16|i32e), op.isMEM(), 0x8C);
+ }
+ void mov(const Segment& seg, const Operand& op)
+ {
+ opModRM(Reg8(seg.getIdx()), op.isREG(16|i32e) ? static_cast<const Operand&>(op.getReg().cvt32()) : op, op.isREG(16|i32e), op.isMEM(), 0x8E);
+ }
+#endif
+
+ enum { NONE = 256 };
+ // constructor
+ CodeGenerator(size_t maxSize = DEFAULT_MAX_CODE_SIZE, void *userPtr = 0, Allocator *allocator = 0)
+ : CodeArray(maxSize, userPtr, allocator)
+ , mm0(0), mm1(1), mm2(2), mm3(3), mm4(4), mm5(5), mm6(6), mm7(7)
+ , xmm0(0), xmm1(1), xmm2(2), xmm3(3), xmm4(4), xmm5(5), xmm6(6), xmm7(7)
+ , ymm0(0), ymm1(1), ymm2(2), ymm3(3), ymm4(4), ymm5(5), ymm6(6), ymm7(7)
+ , zmm0(0), zmm1(1), zmm2(2), zmm3(3), zmm4(4), zmm5(5), zmm6(6), zmm7(7)
+ // for my convenience
+ , xm0(xmm0), xm1(xmm1), xm2(xmm2), xm3(xmm3), xm4(xmm4), xm5(xmm5), xm6(xmm6), xm7(xmm7)
+ , ym0(ymm0), ym1(ymm1), ym2(ymm2), ym3(ymm3), ym4(ymm4), ym5(ymm5), ym6(ymm6), ym7(ymm7)
+ , zm0(zmm0), zm1(zmm1), zm2(zmm2), zm3(zmm3), zm4(zmm4), zm5(zmm5), zm6(zmm6), zm7(zmm7)
+
+ , eax(Operand::EAX), ecx(Operand::ECX), edx(Operand::EDX), ebx(Operand::EBX), esp(Operand::ESP), ebp(Operand::EBP), esi(Operand::ESI), edi(Operand::EDI)
+ , ax(Operand::AX), cx(Operand::CX), dx(Operand::DX), bx(Operand::BX), sp(Operand::SP), bp(Operand::BP), si(Operand::SI), di(Operand::DI)
+ , al(Operand::AL), cl(Operand::CL), dl(Operand::DL), bl(Operand::BL), ah(Operand::AH), ch(Operand::CH), dh(Operand::DH), bh(Operand::BH)
+ , ptr(0), byte(8), word(16), dword(32), qword(64), xword(128), yword(256), zword(512)
+ , ptr_b(0, true), xword_b(128, true), yword_b(256, true), zword_b(512, true)
+ , st0(0), st1(1), st2(2), st3(3), st4(4), st5(5), st6(6), st7(7)
+ , k0(0), k1(1), k2(2), k3(3), k4(4), k5(5), k6(6), k7(7)
+ , bnd0(0), bnd1(1), bnd2(2), bnd3(3)
+ , T_sae(EvexModifierRounding::T_SAE), T_rn_sae(EvexModifierRounding::T_RN_SAE), T_rd_sae(EvexModifierRounding::T_RD_SAE), T_ru_sae(EvexModifierRounding::T_RU_SAE), T_rz_sae(EvexModifierRounding::T_RZ_SAE)
+ , T_z()
+#ifdef XBYAK64
+ , rax(Operand::RAX), rcx(Operand::RCX), rdx(Operand::RDX), rbx(Operand::RBX), rsp(Operand::RSP), rbp(Operand::RBP), rsi(Operand::RSI), rdi(Operand::RDI), r8(Operand::R8), r9(Operand::R9), r10(Operand::R10), r11(Operand::R11), r12(Operand::R12), r13(Operand::R13), r14(Operand::R14), r15(Operand::R15)
+ , r8d(8), r9d(9), r10d(10), r11d(11), r12d(12), r13d(13), r14d(14), r15d(15)
+ , r8w(8), r9w(9), r10w(10), r11w(11), r12w(12), r13w(13), r14w(14), r15w(15)
+ , r8b(8), r9b(9), r10b(10), r11b(11), r12b(12), r13b(13), r14b(14), r15b(15)
+ , spl(Operand::SPL, true), bpl(Operand::BPL, true), sil(Operand::SIL, true), dil(Operand::DIL, true)
+ , xmm8(8), xmm9(9), xmm10(10), xmm11(11), xmm12(12), xmm13(13), xmm14(14), xmm15(15)
+ , xmm16(16), xmm17(17), xmm18(18), xmm19(19), xmm20(20), xmm21(21), xmm22(22), xmm23(23)
+ , xmm24(24), xmm25(25), xmm26(26), xmm27(27), xmm28(28), xmm29(29), xmm30(30), xmm31(31)
+ , ymm8(8), ymm9(9), ymm10(10), ymm11(11), ymm12(12), ymm13(13), ymm14(14), ymm15(15)
+ , ymm16(16), ymm17(17), ymm18(18), ymm19(19), ymm20(20), ymm21(21), ymm22(22), ymm23(23)
+ , ymm24(24), ymm25(25), ymm26(26), ymm27(27), ymm28(28), ymm29(29), ymm30(30), ymm31(31)
+ , zmm8(8), zmm9(9), zmm10(10), zmm11(11), zmm12(12), zmm13(13), zmm14(14), zmm15(15)
+ , zmm16(16), zmm17(17), zmm18(18), zmm19(19), zmm20(20), zmm21(21), zmm22(22), zmm23(23)
+ , zmm24(24), zmm25(25), zmm26(26), zmm27(27), zmm28(28), zmm29(29), zmm30(30), zmm31(31)
+ // for my convenience
+ , xm8(xmm8), xm9(xmm9), xm10(xmm10), xm11(xmm11), xm12(xmm12), xm13(xmm13), xm14(xmm14), xm15(xmm15)
+ , xm16(xmm16), xm17(xmm17), xm18(xmm18), xm19(xmm19), xm20(xmm20), xm21(xmm21), xm22(xmm22), xm23(xmm23)
+ , xm24(xmm24), xm25(xmm25), xm26(xmm26), xm27(xmm27), xm28(xmm28), xm29(xmm29), xm30(xmm30), xm31(xmm31)
+ , ym8(ymm8), ym9(ymm9), ym10(ymm10), ym11(ymm11), ym12(ymm12), ym13(ymm13), ym14(ymm14), ym15(ymm15)
+ , ym16(ymm16), ym17(ymm17), ym18(ymm18), ym19(ymm19), ym20(ymm20), ym21(ymm21), ym22(ymm22), ym23(ymm23)
+ , ym24(ymm24), ym25(ymm25), ym26(ymm26), ym27(ymm27), ym28(ymm28), ym29(ymm29), ym30(ymm30), ym31(ymm31)
+ , zm8(zmm8), zm9(zmm9), zm10(zmm10), zm11(zmm11), zm12(zmm12), zm13(zmm13), zm14(zmm14), zm15(zmm15)
+ , zm16(zmm16), zm17(zmm17), zm18(zmm18), zm19(zmm19), zm20(zmm20), zm21(zmm21), zm22(zmm22), zm23(zmm23)
+ , zm24(zmm24), zm25(zmm25), zm26(zmm26), zm27(zmm27), zm28(zmm28), zm29(zmm29), zm30(zmm30), zm31(zmm31)
+ , rip()
+#endif
+#ifndef XBYAK_DISABLE_SEGMENT
+ , es(Segment::es), cs(Segment::cs), ss(Segment::ss), ds(Segment::ds), fs(Segment::fs), gs(Segment::gs)
+#endif
+ {
+ labelMgr_.set(this);
+ }
+ void reset()
+ {
+ resetSize();
+ labelMgr_.reset();
+ labelMgr_.set(this);
+ }
+ bool hasUndefinedLabel() const { return labelMgr_.hasUndefSlabel() || labelMgr_.hasUndefClabel(); }
+ /*
+ MUST call ready() to complete generating code if you use AutoGrow mode.
+ It is not necessary for the other mode if hasUndefinedLabel() is true.
+ */
+ void ready(ProtectMode mode = PROTECT_RWE)
+ {
+ if (hasUndefinedLabel()) throw Error(ERR_LABEL_IS_NOT_FOUND);
+ if (isAutoGrow()) {
+ calcJmpAddress();
+ if (useProtect()) setProtectMode(mode);
+ }
+ }
+ // set read/exec
+ void readyRE() { return ready(PROTECT_RE); }
+#ifdef XBYAK_TEST
+ void dump(bool doClear = true)
+ {
+ CodeArray::dump();
+ if (doClear) size_ = 0;
+ }
+#endif
+
+#ifdef XBYAK_UNDEF_JNL
+ #undef jnl
+#endif
+
+ /*
+ use single byte nop if useMultiByteNop = false
+ */
+ void nop(size_t size = 1, bool useMultiByteNop = true)
+ {
+ if (!useMultiByteNop) {
+ for (size_t i = 0; i < size; i++) {
+ db(0x90);
+ }
+ return;
+ }
+ /*
+ Intel Architectures Software Developer's Manual Volume 2
+ recommended multi-byte sequence of NOP instruction
+ AMD and Intel seem to agree on the same sequences for up to 9 bytes:
+ https://support.amd.com/TechDocs/55723_SOG_Fam_17h_Processors_3.00.pdf
+ */
+ static const uint8 nopTbl[9][9] = {
+ {0x90},
+ {0x66, 0x90},
+ {0x0F, 0x1F, 0x00},
+ {0x0F, 0x1F, 0x40, 0x00},
+ {0x0F, 0x1F, 0x44, 0x00, 0x00},
+ {0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00},
+ {0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00},
+ {0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
+ {0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
+ };
+ const size_t n = sizeof(nopTbl) / sizeof(nopTbl[0]);
+ while (size > 0) {
+ size_t len = (std::min)(n, size);
+ const uint8 *seq = nopTbl[len - 1];
+ db(seq, len);
+ size -= len;
+ }
+ }
+
+#ifndef XBYAK_DONT_READ_LIST
+#include "xbyak_mnemonic.h"
+ /*
+ use single byte nop if useMultiByteNop = false
+ */
+ void align(size_t x = 16, bool useMultiByteNop = true)
+ {
+ if (x == 1) return;
+ if (x < 1 || (x & (x - 1))) throw Error(ERR_BAD_ALIGN);
+ if (isAutoGrow() && x > inner::ALIGN_PAGE_SIZE) fprintf(stderr, "warning:autoGrow mode does not support %d align\n", (int)x);
+ size_t remain = size_t(getCurr()) % x;
+ if (remain) {
+ nop(x - remain, useMultiByteNop);
+ }
+ }
+#endif
+};
+
+namespace util {
+static const Mmx mm0(0), mm1(1), mm2(2), mm3(3), mm4(4), mm5(5), mm6(6), mm7(7);
+static const Xmm xmm0(0), xmm1(1), xmm2(2), xmm3(3), xmm4(4), xmm5(5), xmm6(6), xmm7(7);
+static const Ymm ymm0(0), ymm1(1), ymm2(2), ymm3(3), ymm4(4), ymm5(5), ymm6(6), ymm7(7);
+static const Zmm zmm0(0), zmm1(1), zmm2(2), zmm3(3), zmm4(4), zmm5(5), zmm6(6), zmm7(7);
+static const Reg32 eax(Operand::EAX), ecx(Operand::ECX), edx(Operand::EDX), ebx(Operand::EBX), esp(Operand::ESP), ebp(Operand::EBP), esi(Operand::ESI), edi(Operand::EDI);
+static const Reg16 ax(Operand::AX), cx(Operand::CX), dx(Operand::DX), bx(Operand::BX), sp(Operand::SP), bp(Operand::BP), si(Operand::SI), di(Operand::DI);
+static const Reg8 al(Operand::AL), cl(Operand::CL), dl(Operand::DL), bl(Operand::BL), ah(Operand::AH), ch(Operand::CH), dh(Operand::DH), bh(Operand::BH);
+static const AddressFrame ptr(0), byte(8), word(16), dword(32), qword(64), xword(128), yword(256), zword(512);
+static const AddressFrame ptr_b(0, true), xword_b(128, true), yword_b(256, true), zword_b(512, true);
+static const Fpu st0(0), st1(1), st2(2), st3(3), st4(4), st5(5), st6(6), st7(7);
+static const Opmask k0(0), k1(1), k2(2), k3(3), k4(4), k5(5), k6(6), k7(7);
+static const BoundsReg bnd0(0), bnd1(1), bnd2(2), bnd3(3);
+static const EvexModifierRounding T_sae(EvexModifierRounding::T_SAE), T_rn_sae(EvexModifierRounding::T_RN_SAE), T_rd_sae(EvexModifierRounding::T_RD_SAE), T_ru_sae(EvexModifierRounding::T_RU_SAE), T_rz_sae(EvexModifierRounding::T_RZ_SAE);
+static const EvexModifierZero T_z;
+#ifdef XBYAK64
+static const Reg64 rax(Operand::RAX), rcx(Operand::RCX), rdx(Operand::RDX), rbx(Operand::RBX), rsp(Operand::RSP), rbp(Operand::RBP), rsi(Operand::RSI), rdi(Operand::RDI), r8(Operand::R8), r9(Operand::R9), r10(Operand::R10), r11(Operand::R11), r12(Operand::R12), r13(Operand::R13), r14(Operand::R14), r15(Operand::R15);
+static const Reg32 r8d(8), r9d(9), r10d(10), r11d(11), r12d(12), r13d(13), r14d(14), r15d(15);
+static const Reg16 r8w(8), r9w(9), r10w(10), r11w(11), r12w(12), r13w(13), r14w(14), r15w(15);
+static const Reg8 r8b(8), r9b(9), r10b(10), r11b(11), r12b(12), r13b(13), r14b(14), r15b(15), spl(Operand::SPL, true), bpl(Operand::BPL, true), sil(Operand::SIL, true), dil(Operand::DIL, true);
+static const Xmm xmm8(8), xmm9(9), xmm10(10), xmm11(11), xmm12(12), xmm13(13), xmm14(14), xmm15(15);
+static const Xmm xmm16(16), xmm17(17), xmm18(18), xmm19(19), xmm20(20), xmm21(21), xmm22(22), xmm23(23);
+static const Xmm xmm24(24), xmm25(25), xmm26(26), xmm27(27), xmm28(28), xmm29(29), xmm30(30), xmm31(31);
+static const Ymm ymm8(8), ymm9(9), ymm10(10), ymm11(11), ymm12(12), ymm13(13), ymm14(14), ymm15(15);
+static const Ymm ymm16(16), ymm17(17), ymm18(18), ymm19(19), ymm20(20), ymm21(21), ymm22(22), ymm23(23);
+static const Ymm ymm24(24), ymm25(25), ymm26(26), ymm27(27), ymm28(28), ymm29(29), ymm30(30), ymm31(31);
+static const Zmm zmm8(8), zmm9(9), zmm10(10), zmm11(11), zmm12(12), zmm13(13), zmm14(14), zmm15(15);
+static const Zmm zmm16(16), zmm17(17), zmm18(18), zmm19(19), zmm20(20), zmm21(21), zmm22(22), zmm23(23);
+static const Zmm zmm24(24), zmm25(25), zmm26(26), zmm27(27), zmm28(28), zmm29(29), zmm30(30), zmm31(31);
+static const RegRip rip;
+#endif
+#ifndef XBYAK_DISABLE_SEGMENT
+static const Segment es(Segment::es), cs(Segment::cs), ss(Segment::ss), ds(Segment::ds), fs(Segment::fs), gs(Segment::gs);
+#endif
+} // util
+
+#ifdef _MSC_VER
+ #pragma warning(pop)
+#endif
+
+} // end of namespace
+
+#endif // XBYAK_XBYAK_H_
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_bin2hex.h b/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_bin2hex.h
new file mode 100644
index 0000000000..a22e5224c3
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_bin2hex.h
@@ -0,0 +1,303 @@
+/*******************************************************************************
+* Copyright 2016-2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/*******************************************************************************
+* Copyright (c) 2007 MITSUNARI Shigeo
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+* Neither the name of the copyright owner nor the names of its contributors may
+* be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+enum {
+ B00000000= 0,
+ B00000001= 1,
+ B00000010= 2,
+ B00000011= 3,
+ B00000100= 4,
+ B00000101= 5,
+ B00000110= 6,
+ B00000111= 7,
+ B00001000= 8,
+ B00001001= 9,
+ B00001010= 10,
+ B00001011= 11,
+ B00001100= 12,
+ B00001101= 13,
+ B00001110= 14,
+ B00001111= 15,
+ B00010000= 16,
+ B00010001= 17,
+ B00010010= 18,
+ B00010011= 19,
+ B00010100= 20,
+ B00010101= 21,
+ B00010110= 22,
+ B00010111= 23,
+ B00011000= 24,
+ B00011001= 25,
+ B00011010= 26,
+ B00011011= 27,
+ B00011100= 28,
+ B00011101= 29,
+ B00011110= 30,
+ B00011111= 31,
+ B00100000= 32,
+ B00100001= 33,
+ B00100010= 34,
+ B00100011= 35,
+ B00100100= 36,
+ B00100101= 37,
+ B00100110= 38,
+ B00100111= 39,
+ B00101000= 40,
+ B00101001= 41,
+ B00101010= 42,
+ B00101011= 43,
+ B00101100= 44,
+ B00101101= 45,
+ B00101110= 46,
+ B00101111= 47,
+ B00110000= 48,
+ B00110001= 49,
+ B00110010= 50,
+ B00110011= 51,
+ B00110100= 52,
+ B00110101= 53,
+ B00110110= 54,
+ B00110111= 55,
+ B00111000= 56,
+ B00111001= 57,
+ B00111010= 58,
+ B00111011= 59,
+ B00111100= 60,
+ B00111101= 61,
+ B00111110= 62,
+ B00111111= 63,
+ B01000000= 64,
+ B01000001= 65,
+ B01000010= 66,
+ B01000011= 67,
+ B01000100= 68,
+ B01000101= 69,
+ B01000110= 70,
+ B01000111= 71,
+ B01001000= 72,
+ B01001001= 73,
+ B01001010= 74,
+ B01001011= 75,
+ B01001100= 76,
+ B01001101= 77,
+ B01001110= 78,
+ B01001111= 79,
+ B01010000= 80,
+ B01010001= 81,
+ B01010010= 82,
+ B01010011= 83,
+ B01010100= 84,
+ B01010101= 85,
+ B01010110= 86,
+ B01010111= 87,
+ B01011000= 88,
+ B01011001= 89,
+ B01011010= 90,
+ B01011011= 91,
+ B01011100= 92,
+ B01011101= 93,
+ B01011110= 94,
+ B01011111= 95,
+ B01100000= 96,
+ B01100001= 97,
+ B01100010= 98,
+ B01100011= 99,
+ B01100100= 100,
+ B01100101= 101,
+ B01100110= 102,
+ B01100111= 103,
+ B01101000= 104,
+ B01101001= 105,
+ B01101010= 106,
+ B01101011= 107,
+ B01101100= 108,
+ B01101101= 109,
+ B01101110= 110,
+ B01101111= 111,
+ B01110000= 112,
+ B01110001= 113,
+ B01110010= 114,
+ B01110011= 115,
+ B01110100= 116,
+ B01110101= 117,
+ B01110110= 118,
+ B01110111= 119,
+ B01111000= 120,
+ B01111001= 121,
+ B01111010= 122,
+ B01111011= 123,
+ B01111100= 124,
+ B01111101= 125,
+ B01111110= 126,
+ B01111111= 127,
+ B10000000= 128,
+ B10000001= 129,
+ B10000010= 130,
+ B10000011= 131,
+ B10000100= 132,
+ B10000101= 133,
+ B10000110= 134,
+ B10000111= 135,
+ B10001000= 136,
+ B10001001= 137,
+ B10001010= 138,
+ B10001011= 139,
+ B10001100= 140,
+ B10001101= 141,
+ B10001110= 142,
+ B10001111= 143,
+ B10010000= 144,
+ B10010001= 145,
+ B10010010= 146,
+ B10010011= 147,
+ B10010100= 148,
+ B10010101= 149,
+ B10010110= 150,
+ B10010111= 151,
+ B10011000= 152,
+ B10011001= 153,
+ B10011010= 154,
+ B10011011= 155,
+ B10011100= 156,
+ B10011101= 157,
+ B10011110= 158,
+ B10011111= 159,
+ B10100000= 160,
+ B10100001= 161,
+ B10100010= 162,
+ B10100011= 163,
+ B10100100= 164,
+ B10100101= 165,
+ B10100110= 166,
+ B10100111= 167,
+ B10101000= 168,
+ B10101001= 169,
+ B10101010= 170,
+ B10101011= 171,
+ B10101100= 172,
+ B10101101= 173,
+ B10101110= 174,
+ B10101111= 175,
+ B10110000= 176,
+ B10110001= 177,
+ B10110010= 178,
+ B10110011= 179,
+ B10110100= 180,
+ B10110101= 181,
+ B10110110= 182,
+ B10110111= 183,
+ B10111000= 184,
+ B10111001= 185,
+ B10111010= 186,
+ B10111011= 187,
+ B10111100= 188,
+ B10111101= 189,
+ B10111110= 190,
+ B10111111= 191,
+ B11000000= 192,
+ B11000001= 193,
+ B11000010= 194,
+ B11000011= 195,
+ B11000100= 196,
+ B11000101= 197,
+ B11000110= 198,
+ B11000111= 199,
+ B11001000= 200,
+ B11001001= 201,
+ B11001010= 202,
+ B11001011= 203,
+ B11001100= 204,
+ B11001101= 205,
+ B11001110= 206,
+ B11001111= 207,
+ B11010000= 208,
+ B11010001= 209,
+ B11010010= 210,
+ B11010011= 211,
+ B11010100= 212,
+ B11010101= 213,
+ B11010110= 214,
+ B11010111= 215,
+ B11011000= 216,
+ B11011001= 217,
+ B11011010= 218,
+ B11011011= 219,
+ B11011100= 220,
+ B11011101= 221,
+ B11011110= 222,
+ B11011111= 223,
+ B11100000= 224,
+ B11100001= 225,
+ B11100010= 226,
+ B11100011= 227,
+ B11100100= 228,
+ B11100101= 229,
+ B11100110= 230,
+ B11100111= 231,
+ B11101000= 232,
+ B11101001= 233,
+ B11101010= 234,
+ B11101011= 235,
+ B11101100= 236,
+ B11101101= 237,
+ B11101110= 238,
+ B11101111= 239,
+ B11110000= 240,
+ B11110001= 241,
+ B11110010= 242,
+ B11110011= 243,
+ B11110100= 244,
+ B11110101= 245,
+ B11110110= 246,
+ B11110111= 247,
+ B11111000= 248,
+ B11111001= 249,
+ B11111010= 250,
+ B11111011= 251,
+ B11111100= 252,
+ B11111101= 253,
+ B11111110= 254,
+ B11111111= 255
+};
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_mnemonic.h b/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_mnemonic.h
new file mode 100644
index 0000000000..28d2d222f9
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_mnemonic.h
@@ -0,0 +1,2017 @@
+/*******************************************************************************
+* Copyright 2016-2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/*******************************************************************************
+* Copyright (c) 2007 MITSUNARI Shigeo
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+* Neither the name of the copyright owner nor the names of its contributors may
+* be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+const char *getVersionString() const { return "5.76"; }
+void adc(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x10, 2); }
+void adc(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x10); }
+void adcx(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0x66, isREG32_REG32orMEM, NONE, 0x38); }
+void add(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x00, 0); }
+void add(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x00); }
+void addpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x58, 0x66, isXMM_XMMorMEM); }
+void addps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x58, 0x100, isXMM_XMMorMEM); }
+void addsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x58, 0xF2, isXMM_XMMorMEM); }
+void addss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x58, 0xF3, isXMM_XMMorMEM); }
+void addsubpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xD0, 0x66, isXMM_XMMorMEM); }
+void addsubps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xD0, 0xF2, isXMM_XMMorMEM); }
+void adox(const Reg32e& reg, const Operand& op) { opGen(reg, op, 0xF6, 0xF3, isREG32_REG32orMEM, NONE, 0x38); }
+void aesdec(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xDE, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void aesdeclast(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xDF, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void aesenc(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xDC, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void aesenclast(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xDD, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void aesimc(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xDB, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void aeskeygenassist(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0xDF, 0x66, isXMM_XMMorMEM, imm, 0x3A); }
+void and_(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x20, 4); }
+void and_(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x20); }
+void andn(const Reg32e& r1, const Reg32e& r2, const Operand& op) { opGpr(r1, r2, op, T_0F38, 0xf2, true); }
+void andnpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x55, 0x66, isXMM_XMMorMEM); }
+void andnps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x55, 0x100, isXMM_XMMorMEM); }
+void andpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x54, 0x66, isXMM_XMMorMEM); }
+void andps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x54, 0x100, isXMM_XMMorMEM); }
+void bextr(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opGpr(r1, op, r2, T_0F38, 0xf7, false); }
+void blendpd(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, 0x0D, 0x66, isXMM_XMMorMEM, static_cast<uint8>(imm), 0x3A); }
+void blendps(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, 0x0C, 0x66, isXMM_XMMorMEM, static_cast<uint8>(imm), 0x3A); }
+void blendvpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x15, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void blendvps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x14, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void blsi(const Reg32e& r, const Operand& op) { opGpr(Reg32e(3, r.getBit()), op, r, T_0F38, 0xf3, false); }
+void blsmsk(const Reg32e& r, const Operand& op) { opGpr(Reg32e(2, r.getBit()), op, r, T_0F38, 0xf3, false); }
+void blsr(const Reg32e& r, const Operand& op) { opGpr(Reg32e(1, r.getBit()), op, r, T_0F38, 0xf3, false); }
+void bnd() { db(0xF2); }
+void bndcl(const BoundsReg& bnd, const Operand& op) { db(0xF3); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1A, NONE, !op.isMEM()); }
+void bndcn(const BoundsReg& bnd, const Operand& op) { db(0xF2); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1B, NONE, !op.isMEM()); }
+void bndcu(const BoundsReg& bnd, const Operand& op) { db(0xF2); opR_ModM(op, i32e, bnd.getIdx(), 0x0F, 0x1A, NONE, !op.isMEM()); }
+void bndldx(const BoundsReg& bnd, const Address& addr) { opMIB(addr, bnd, 0x0F, 0x1A); }
+void bndmk(const BoundsReg& bnd, const Address& addr) { db(0xF3); opModM(addr, bnd, 0x0F, 0x1B); }
+void bndmov(const Address& addr, const BoundsReg& bnd) { db(0x66); opModM(addr, bnd, 0x0F, 0x1B); }
+void bndmov(const BoundsReg& bnd, const Operand& op) { db(0x66); opModRM(bnd, op, op.isBNDREG(), op.isMEM(), 0x0F, 0x1A); }
+void bndstx(const Address& addr, const BoundsReg& bnd) { opMIB(addr, bnd, 0x0F, 0x1B); }
+void bsf(const Reg&reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0xBC); }
+void bsr(const Reg&reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0xBD); }
+void bswap(const Reg32e& reg) { opModR(Reg32(1), reg, 0x0F); }
+void bt(const Operand& op, const Reg& reg) { opModRM(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), 0x0f, 0xA3); }
+void bt(const Operand& op, uint8 imm) { opR_ModM(op, 16|32|64, 4, 0x0f, 0xba, NONE, false, 1); db(imm); }
+void btc(const Operand& op, const Reg& reg) { opModRM(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), 0x0f, 0xBB); }
+void btc(const Operand& op, uint8 imm) { opR_ModM(op, 16|32|64, 7, 0x0f, 0xba, NONE, false, 1); db(imm); }
+void btr(const Operand& op, const Reg& reg) { opModRM(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), 0x0f, 0xB3); }
+void btr(const Operand& op, uint8 imm) { opR_ModM(op, 16|32|64, 6, 0x0f, 0xba, NONE, false, 1); db(imm); }
+void bts(const Operand& op, const Reg& reg) { opModRM(reg, op, op.isREG(16|32|64) && op.getBit() == reg.getBit(), op.isMEM(), 0x0f, 0xAB); }
+void bts(const Operand& op, uint8 imm) { opR_ModM(op, 16|32|64, 5, 0x0f, 0xba, NONE, false, 1); db(imm); }
+void bzhi(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opGpr(r1, op, r2, T_0F38, 0xf5, false); }
+void cbw() { db(0x66); db(0x98); }
+void cdq() { db(0x99); }
+void clc() { db(0xF8); }
+void cld() { db(0xFC); }
+void clflush(const Address& addr) { opModM(addr, Reg32(7), 0x0F, 0xAE); }
+void cli() { db(0xFA); }
+void cmc() { db(0xF5); }
+void cmova(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 7); }//-V524
+void cmovae(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 3); }//-V524
+void cmovb(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 2); }//-V524
+void cmovbe(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 6); }//-V524
+void cmovc(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 2); }//-V524
+void cmove(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 4); }//-V524
+void cmovg(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 15); }//-V524
+void cmovge(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 13); }//-V524
+void cmovl(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 12); }//-V524
+void cmovle(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 14); }//-V524
+void cmovna(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 6); }//-V524
+void cmovnae(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 2); }//-V524
+void cmovnb(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 3); }//-V524
+void cmovnbe(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 7); }//-V524
+void cmovnc(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 3); }//-V524
+void cmovne(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 5); }//-V524
+void cmovng(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 14); }//-V524
+void cmovnge(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 12); }//-V524
+void cmovnl(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 13); }//-V524
+void cmovnle(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 15); }//-V524
+void cmovno(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 1); }//-V524
+void cmovnp(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 11); }//-V524
+void cmovns(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 9); }//-V524
+void cmovnz(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 5); }//-V524
+void cmovo(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 0); }//-V524
+void cmovp(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 10); }//-V524
+void cmovpe(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 10); }//-V524
+void cmovpo(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 11); }//-V524
+void cmovs(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 8); }//-V524
+void cmovz(const Reg& reg, const Operand& op) { opModRM(reg, op, op.isREG(16 | i32e), op.isMEM(), 0x0F, 0x40 | 4); }//-V524
+void cmp(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x38, 7); }
+void cmp(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x38); }
+void cmpeqpd(const Xmm& x, const Operand& op) { cmppd(x, op, 0); }
+void cmpeqps(const Xmm& x, const Operand& op) { cmpps(x, op, 0); }
+void cmpeqsd(const Xmm& x, const Operand& op) { cmpsd(x, op, 0); }
+void cmpeqss(const Xmm& x, const Operand& op) { cmpss(x, op, 0); }
+void cmplepd(const Xmm& x, const Operand& op) { cmppd(x, op, 2); }
+void cmpleps(const Xmm& x, const Operand& op) { cmpps(x, op, 2); }
+void cmplesd(const Xmm& x, const Operand& op) { cmpsd(x, op, 2); }
+void cmpless(const Xmm& x, const Operand& op) { cmpss(x, op, 2); }
+void cmpltpd(const Xmm& x, const Operand& op) { cmppd(x, op, 1); }
+void cmpltps(const Xmm& x, const Operand& op) { cmpps(x, op, 1); }
+void cmpltsd(const Xmm& x, const Operand& op) { cmpsd(x, op, 1); }
+void cmpltss(const Xmm& x, const Operand& op) { cmpss(x, op, 1); }
+void cmpneqpd(const Xmm& x, const Operand& op) { cmppd(x, op, 4); }
+void cmpneqps(const Xmm& x, const Operand& op) { cmpps(x, op, 4); }
+void cmpneqsd(const Xmm& x, const Operand& op) { cmpsd(x, op, 4); }
+void cmpneqss(const Xmm& x, const Operand& op) { cmpss(x, op, 4); }
+void cmpnlepd(const Xmm& x, const Operand& op) { cmppd(x, op, 6); }
+void cmpnleps(const Xmm& x, const Operand& op) { cmpps(x, op, 6); }
+void cmpnlesd(const Xmm& x, const Operand& op) { cmpsd(x, op, 6); }
+void cmpnless(const Xmm& x, const Operand& op) { cmpss(x, op, 6); }
+void cmpnltpd(const Xmm& x, const Operand& op) { cmppd(x, op, 5); }
+void cmpnltps(const Xmm& x, const Operand& op) { cmpps(x, op, 5); }
+void cmpnltsd(const Xmm& x, const Operand& op) { cmpsd(x, op, 5); }
+void cmpnltss(const Xmm& x, const Operand& op) { cmpss(x, op, 5); }
+void cmpordpd(const Xmm& x, const Operand& op) { cmppd(x, op, 7); }
+void cmpordps(const Xmm& x, const Operand& op) { cmpps(x, op, 7); }
+void cmpordsd(const Xmm& x, const Operand& op) { cmpsd(x, op, 7); }
+void cmpordss(const Xmm& x, const Operand& op) { cmpss(x, op, 7); }
+void cmppd(const Xmm& xmm, const Operand& op, uint8 imm8) { opGen(xmm, op, 0xC2, 0x66, isXMM_XMMorMEM, imm8); }
+void cmpps(const Xmm& xmm, const Operand& op, uint8 imm8) { opGen(xmm, op, 0xC2, 0x100, isXMM_XMMorMEM, imm8); }
+void cmpsb() { db(0xA6); }
+void cmpsd() { db(0xA7); }
+void cmpsd(const Xmm& xmm, const Operand& op, uint8 imm8) { opGen(xmm, op, 0xC2, 0xF2, isXMM_XMMorMEM, imm8); }
+void cmpss(const Xmm& xmm, const Operand& op, uint8 imm8) { opGen(xmm, op, 0xC2, 0xF3, isXMM_XMMorMEM, imm8); }
+void cmpsw() { db(0x66); db(0xA7); }
+void cmpunordpd(const Xmm& x, const Operand& op) { cmppd(x, op, 3); }
+void cmpunordps(const Xmm& x, const Operand& op) { cmpps(x, op, 3); }
+void cmpunordsd(const Xmm& x, const Operand& op) { cmpsd(x, op, 3); }
+void cmpunordss(const Xmm& x, const Operand& op) { cmpss(x, op, 3); }
+void cmpxchg(const Operand& op, const Reg& reg) { opModRM(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), 0x0F, 0xB0 | (reg.isBit(8) ? 0 : 1)); }
+void cmpxchg8b(const Address& addr) { opModM(addr, Reg32(1), 0x0F, 0xC7); }
+void comisd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x2F, 0x66, isXMM_XMMorMEM); }
+void comiss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x2F, 0x100, isXMM_XMMorMEM); }
+void cpuid() { db(0x0F); db(0xA2); }
+void crc32(const Reg32e& reg, const Operand& op) { if (reg.isBit(32) && op.isBit(16)) db(0x66); db(0xF2); opModRM(reg, op, op.isREG(), op.isMEM(), 0x0F, 0x38, 0xF0 | (op.isBit(8) ? 0 : 1)); }
+void cvtdq2pd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xE6, 0xF3, isXMM_XMMorMEM); }
+void cvtdq2ps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5B, 0x100, isXMM_XMMorMEM); }
+void cvtpd2dq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xE6, 0xF2, isXMM_XMMorMEM); }
+void cvtpd2pi(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2D, 0x66, isMMX_XMMorMEM); }
+void cvtpd2ps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5A, 0x66, isXMM_XMMorMEM); }
+void cvtpi2pd(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2A, 0x66, isXMM_MMXorMEM); }
+void cvtpi2ps(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2A, 0x100, isXMM_MMXorMEM); }
+void cvtps2dq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5B, 0x66, isXMM_XMMorMEM); }
+void cvtps2pd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5A, 0x100, isXMM_XMMorMEM); }
+void cvtps2pi(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2D, 0x100, isMMX_XMMorMEM); }
+void cvtsd2si(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2D, 0xF2, isREG32_XMMorMEM); }
+void cvtsd2ss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5A, 0xF2, isXMM_XMMorMEM); }
+void cvtsi2sd(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2A, 0xF2, isXMM_REG32orMEM); }
+void cvtsi2ss(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2A, 0xF3, isXMM_REG32orMEM); }
+void cvtss2sd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5A, 0xF3, isXMM_XMMorMEM); }
+void cvtss2si(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2D, 0xF3, isREG32_XMMorMEM); }
+void cvttpd2dq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xE6, 0x66, isXMM_XMMorMEM); }
+void cvttpd2pi(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2C, 0x66, isMMX_XMMorMEM); }
+void cvttps2dq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5B, 0xF3, isXMM_XMMorMEM); }
+void cvttps2pi(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2C, 0x100, isMMX_XMMorMEM); }
+void cvttsd2si(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2C, 0xF2, isREG32_XMMorMEM); }
+void cvttss2si(const Operand& reg, const Operand& op) { opGen(reg, op, 0x2C, 0xF3, isREG32_XMMorMEM); }
+void cwd() { db(0x66); db(0x99); }
+void cwde() { db(0x98); }
+void dec(const Operand& op) { opIncDec(op, 0x48, 1); }
+void div(const Operand& op) { opR_ModM(op, 0, 6, 0xF6); }
+void divpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5E, 0x66, isXMM_XMMorMEM); }
+void divps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5E, 0x100, isXMM_XMMorMEM); }
+void divsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5E, 0xF2, isXMM_XMMorMEM); }
+void divss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5E, 0xF3, isXMM_XMMorMEM); }
+void dppd(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, 0x41, 0x66, isXMM_XMMorMEM, static_cast<uint8>(imm), 0x3A); }
+void dpps(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, 0x40, 0x66, isXMM_XMMorMEM, static_cast<uint8>(imm), 0x3A); }
+void emms() { db(0x0F); db(0x77); }
+void extractps(const Operand& op, const Xmm& xmm, uint8 imm) { opExt(op, xmm, 0x17, imm); }
+void f2xm1() { db(0xD9); db(0xF0); }
+void fabs() { db(0xD9); db(0xE1); }
+void fadd(const Address& addr) { opFpuMem(addr, 0x00, 0xD8, 0xDC, 0, 0); }
+void fadd(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xD8C0, 0xDCC0); }
+void fadd(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xD8C0, 0xDCC0); }
+void faddp() { db(0xDE); db(0xC1); }
+void faddp(const Fpu& reg1) { opFpuFpu(reg1, st0, 0x0000, 0xDEC0); }
+void faddp(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0x0000, 0xDEC0); }
+void fchs() { db(0xD9); db(0xE0); }
+void fcmovb(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDAC0, 0x00C0); }
+void fcmovb(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDAC0, 0x00C0); }
+void fcmovbe(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDAD0, 0x00D0); }
+void fcmovbe(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDAD0, 0x00D0); }
+void fcmove(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDAC8, 0x00C8); }
+void fcmove(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDAC8, 0x00C8); }
+void fcmovnb(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDBC0, 0x00C0); }
+void fcmovnb(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDBC0, 0x00C0); }
+void fcmovnbe(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDBD0, 0x00D0); }
+void fcmovnbe(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDBD0, 0x00D0); }
+void fcmovne(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDBC8, 0x00C8); }
+void fcmovne(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDBC8, 0x00C8); }
+void fcmovnu(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDBD8, 0x00D8); }
+void fcmovnu(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDBD8, 0x00D8); }
+void fcmovu(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDAD8, 0x00D8); }
+void fcmovu(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDAD8, 0x00D8); }
+void fcom() { db(0xD8); db(0xD1); }
+void fcom(const Address& addr) { opFpuMem(addr, 0x00, 0xD8, 0xDC, 2, 0); }
+void fcom(const Fpu& reg) { opFpu(reg, 0xD8, 0xD0); }
+void fcomi(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDBF0, 0x00F0); }
+void fcomi(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDBF0, 0x00F0); }
+void fcomip(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDFF0, 0x00F0); }
+void fcomip(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDFF0, 0x00F0); }
+void fcomp() { db(0xD8); db(0xD9); }
+void fcomp(const Address& addr) { opFpuMem(addr, 0x00, 0xD8, 0xDC, 3, 0); }
+void fcomp(const Fpu& reg) { opFpu(reg, 0xD8, 0xD8); }
+void fcompp() { db(0xDE); db(0xD9); }
+void fcos() { db(0xD9); db(0xFF); }
+void fdecstp() { db(0xD9); db(0xF6); }
+void fdiv(const Address& addr) { opFpuMem(addr, 0x00, 0xD8, 0xDC, 6, 0); }
+void fdiv(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xD8F0, 0xDCF8); }
+void fdiv(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xD8F0, 0xDCF8); }
+void fdivp() { db(0xDE); db(0xF9); }
+void fdivp(const Fpu& reg1) { opFpuFpu(reg1, st0, 0x0000, 0xDEF8); }
+void fdivp(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0x0000, 0xDEF8); }
+void fdivr(const Address& addr) { opFpuMem(addr, 0x00, 0xD8, 0xDC, 7, 0); }
+void fdivr(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xD8F8, 0xDCF0); }
+void fdivr(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xD8F8, 0xDCF0); }
+void fdivrp() { db(0xDE); db(0xF1); }
+void fdivrp(const Fpu& reg1) { opFpuFpu(reg1, st0, 0x0000, 0xDEF0); }
+void fdivrp(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0x0000, 0xDEF0); }
+void ffree(const Fpu& reg) { opFpu(reg, 0xDD, 0xC0); }
+void fiadd(const Address& addr) { opFpuMem(addr, 0xDE, 0xDA, 0x00, 0, 0); }
+void ficom(const Address& addr) { opFpuMem(addr, 0xDE, 0xDA, 0x00, 2, 0); }
+void ficomp(const Address& addr) { opFpuMem(addr, 0xDE, 0xDA, 0x00, 3, 0); }
+void fidiv(const Address& addr) { opFpuMem(addr, 0xDE, 0xDA, 0x00, 6, 0); }
+void fidivr(const Address& addr) { opFpuMem(addr, 0xDE, 0xDA, 0x00, 7, 0); }
+void fild(const Address& addr) { opFpuMem(addr, 0xDF, 0xDB, 0xDF, 0, 5); }
+void fimul(const Address& addr) { opFpuMem(addr, 0xDE, 0xDA, 0x00, 1, 0); }
+void fincstp() { db(0xD9); db(0xF7); }
+void finit() { db(0x9B); db(0xDB); db(0xE3); }
+void fist(const Address& addr) { opFpuMem(addr, 0xDF, 0xDB, 0x00, 2, 0); }
+void fistp(const Address& addr) { opFpuMem(addr, 0xDF, 0xDB, 0xDF, 3, 7); }
+void fisttp(const Address& addr) { opFpuMem(addr, 0xDF, 0xDB, 0xDD, 1, 0); }
+void fisub(const Address& addr) { opFpuMem(addr, 0xDE, 0xDA, 0x00, 4, 0); }
+void fisubr(const Address& addr) { opFpuMem(addr, 0xDE, 0xDA, 0x00, 5, 0); }
+void fld(const Address& addr) { opFpuMem(addr, 0x00, 0xD9, 0xDD, 0, 0); }
+void fld(const Fpu& reg) { opFpu(reg, 0xD9, 0xC0); }
+void fld1() { db(0xD9); db(0xE8); }
+void fldcw(const Address& addr) { opModM(addr, Reg32(5), 0xD9, 0x100); }
+void fldl2e() { db(0xD9); db(0xEA); }
+void fldl2t() { db(0xD9); db(0xE9); }
+void fldlg2() { db(0xD9); db(0xEC); }
+void fldln2() { db(0xD9); db(0xED); }
+void fldpi() { db(0xD9); db(0xEB); }
+void fldz() { db(0xD9); db(0xEE); }
+void fmul(const Address& addr) { opFpuMem(addr, 0x00, 0xD8, 0xDC, 1, 0); }
+void fmul(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xD8C8, 0xDCC8); }
+void fmul(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xD8C8, 0xDCC8); }
+void fmulp() { db(0xDE); db(0xC9); }
+void fmulp(const Fpu& reg1) { opFpuFpu(reg1, st0, 0x0000, 0xDEC8); }
+void fmulp(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0x0000, 0xDEC8); }
+void fninit() { db(0xDB); db(0xE3); }
+void fnop() { db(0xD9); db(0xD0); }
+void fpatan() { db(0xD9); db(0xF3); }
+void fprem() { db(0xD9); db(0xF8); }
+void fprem1() { db(0xD9); db(0xF5); }
+void fptan() { db(0xD9); db(0xF2); }
+void frndint() { db(0xD9); db(0xFC); }
+void fscale() { db(0xD9); db(0xFD); }
+void fsin() { db(0xD9); db(0xFE); }
+void fsincos() { db(0xD9); db(0xFB); }
+void fsqrt() { db(0xD9); db(0xFA); }
+void fst(const Address& addr) { opFpuMem(addr, 0x00, 0xD9, 0xDD, 2, 0); }
+void fst(const Fpu& reg) { opFpu(reg, 0xDD, 0xD0); }
+void fstcw(const Address& addr) { db(0x9B); opModM(addr, Reg32(7), 0xD9, NONE); }
+void fstp(const Address& addr) { opFpuMem(addr, 0x00, 0xD9, 0xDD, 3, 0); }
+void fstp(const Fpu& reg) { opFpu(reg, 0xDD, 0xD8); }
+void fsub(const Address& addr) { opFpuMem(addr, 0x00, 0xD8, 0xDC, 4, 0); }
+void fsub(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xD8E0, 0xDCE8); }
+void fsub(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xD8E0, 0xDCE8); }
+void fsubp() { db(0xDE); db(0xE9); }
+void fsubp(const Fpu& reg1) { opFpuFpu(reg1, st0, 0x0000, 0xDEE8); }
+void fsubp(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0x0000, 0xDEE8); }
+void fsubr(const Address& addr) { opFpuMem(addr, 0x00, 0xD8, 0xDC, 5, 0); }
+void fsubr(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xD8E8, 0xDCE0); }
+void fsubr(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xD8E8, 0xDCE0); }
+void fsubrp() { db(0xDE); db(0xE1); }
+void fsubrp(const Fpu& reg1) { opFpuFpu(reg1, st0, 0x0000, 0xDEE0); }
+void fsubrp(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0x0000, 0xDEE0); }
+void ftst() { db(0xD9); db(0xE4); }
+void fucom() { db(0xDD); db(0xE1); }
+void fucom(const Fpu& reg) { opFpu(reg, 0xDD, 0xE0); }
+void fucomi(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDBE8, 0x00E8); }
+void fucomi(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDBE8, 0x00E8); }
+void fucomip(const Fpu& reg1) { opFpuFpu(st0, reg1, 0xDFE8, 0x00E8); }
+void fucomip(const Fpu& reg1, const Fpu& reg2) { opFpuFpu(reg1, reg2, 0xDFE8, 0x00E8); }
+void fucomp() { db(0xDD); db(0xE9); }
+void fucomp(const Fpu& reg) { opFpu(reg, 0xDD, 0xE8); }
+void fucompp() { db(0xDA); db(0xE9); }
+void fwait() { db(0x9B); }
+void fxam() { db(0xD9); db(0xE5); }
+void fxch() { db(0xD9); db(0xC9); }
+void fxch(const Fpu& reg) { opFpu(reg, 0xD9, 0xC8); }
+void fxtract() { db(0xD9); db(0xF4); }
+void fyl2x() { db(0xD9); db(0xF1); }
+void fyl2xp1() { db(0xD9); db(0xF9); }
+void gf2p8affineinvqb(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, 0xCF, 0x66, isXMM_XMMorMEM, static_cast<uint8>(imm), 0x3A); }
+void gf2p8affineqb(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, 0xCE, 0x66, isXMM_XMMorMEM, static_cast<uint8>(imm), 0x3A); }
+void gf2p8mulb(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xCF, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void haddpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x7C, 0x66, isXMM_XMMorMEM); }
+void haddps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x7C, 0xF2, isXMM_XMMorMEM); }
+void hsubpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x7D, 0x66, isXMM_XMMorMEM); }
+void hsubps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x7D, 0xF2, isXMM_XMMorMEM); }
+void idiv(const Operand& op) { opR_ModM(op, 0, 7, 0xF6); }
+void imul(const Operand& op) { opR_ModM(op, 0, 5, 0xF6); }
+void inc(const Operand& op) { opIncDec(op, 0x40, 0); }
+void insertps(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x21, 0x66, isXMM_XMMorMEM, imm, 0x3A); }
+void ja(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x77, 0x87, 0x0F); }//-V524
+void ja(const char *label, LabelType type = T_AUTO) { ja(std::string(label), type); }//-V524
+void ja(const void *addr) { opJmpAbs(addr, T_NEAR, 0x77, 0x87, 0x0F); }//-V524
+void ja(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x77, 0x87, 0x0F); }//-V524
+void jae(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); }//-V524
+void jae(const char *label, LabelType type = T_AUTO) { jae(std::string(label), type); }//-V524
+void jae(const void *addr) { opJmpAbs(addr, T_NEAR, 0x73, 0x83, 0x0F); }//-V524
+void jae(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); }//-V524
+void jb(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); }//-V524
+void jb(const char *label, LabelType type = T_AUTO) { jb(std::string(label), type); }//-V524
+void jb(const void *addr) { opJmpAbs(addr, T_NEAR, 0x72, 0x82, 0x0F); }//-V524
+void jb(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); }//-V524
+void jbe(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x76, 0x86, 0x0F); }//-V524
+void jbe(const char *label, LabelType type = T_AUTO) { jbe(std::string(label), type); }//-V524
+void jbe(const void *addr) { opJmpAbs(addr, T_NEAR, 0x76, 0x86, 0x0F); }//-V524
+void jbe(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x76, 0x86, 0x0F); }//-V524
+void jc(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); }//-V524
+void jc(const char *label, LabelType type = T_AUTO) { jc(std::string(label), type); }//-V524
+void jc(const void *addr) { opJmpAbs(addr, T_NEAR, 0x72, 0x82, 0x0F); }//-V524
+void jc(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); }//-V524
+void je(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x74, 0x84, 0x0F); }//-V524
+void je(const char *label, LabelType type = T_AUTO) { je(std::string(label), type); }//-V524
+void je(const void *addr) { opJmpAbs(addr, T_NEAR, 0x74, 0x84, 0x0F); }//-V524
+void je(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x74, 0x84, 0x0F); }//-V524
+void jg(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7F, 0x8F, 0x0F); }//-V524
+void jg(const char *label, LabelType type = T_AUTO) { jg(std::string(label), type); }//-V524
+void jg(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7F, 0x8F, 0x0F); }//-V524
+void jg(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7F, 0x8F, 0x0F); }//-V524
+void jge(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7D, 0x8D, 0x0F); }//-V524
+void jge(const char *label, LabelType type = T_AUTO) { jge(std::string(label), type); }//-V524
+void jge(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7D, 0x8D, 0x0F); }//-V524
+void jge(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7D, 0x8D, 0x0F); }//-V524
+void jl(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7C, 0x8C, 0x0F); }//-V524
+void jl(const char *label, LabelType type = T_AUTO) { jl(std::string(label), type); }//-V524
+void jl(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7C, 0x8C, 0x0F); }//-V524
+void jl(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7C, 0x8C, 0x0F); }//-V524
+void jle(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7E, 0x8E, 0x0F); }//-V524
+void jle(const char *label, LabelType type = T_AUTO) { jle(std::string(label), type); }//-V524
+void jle(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7E, 0x8E, 0x0F); }//-V524
+void jle(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7E, 0x8E, 0x0F); }//-V524
+void jna(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x76, 0x86, 0x0F); }//-V524
+void jna(const char *label, LabelType type = T_AUTO) { jna(std::string(label), type); }//-V524
+void jna(const void *addr) { opJmpAbs(addr, T_NEAR, 0x76, 0x86, 0x0F); }//-V524
+void jna(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x76, 0x86, 0x0F); }//-V524
+void jnae(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); }//-V524
+void jnae(const char *label, LabelType type = T_AUTO) { jnae(std::string(label), type); }//-V524
+void jnae(const void *addr) { opJmpAbs(addr, T_NEAR, 0x72, 0x82, 0x0F); }//-V524
+void jnae(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x72, 0x82, 0x0F); }//-V524
+void jnb(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); }//-V524
+void jnb(const char *label, LabelType type = T_AUTO) { jnb(std::string(label), type); }//-V524
+void jnb(const void *addr) { opJmpAbs(addr, T_NEAR, 0x73, 0x83, 0x0F); }//-V524
+void jnb(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); }//-V524
+void jnbe(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x77, 0x87, 0x0F); }//-V524
+void jnbe(const char *label, LabelType type = T_AUTO) { jnbe(std::string(label), type); }//-V524
+void jnbe(const void *addr) { opJmpAbs(addr, T_NEAR, 0x77, 0x87, 0x0F); }//-V524
+void jnbe(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x77, 0x87, 0x0F); }//-V524
+void jnc(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); }//-V524
+void jnc(const char *label, LabelType type = T_AUTO) { jnc(std::string(label), type); }//-V524
+void jnc(const void *addr) { opJmpAbs(addr, T_NEAR, 0x73, 0x83, 0x0F); }//-V524
+void jnc(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x73, 0x83, 0x0F); }//-V524
+void jne(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x75, 0x85, 0x0F); }//-V524
+void jne(const char *label, LabelType type = T_AUTO) { jne(std::string(label), type); }//-V524
+void jne(const void *addr) { opJmpAbs(addr, T_NEAR, 0x75, 0x85, 0x0F); }//-V524
+void jne(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x75, 0x85, 0x0F); }//-V524
+void jng(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7E, 0x8E, 0x0F); }//-V524
+void jng(const char *label, LabelType type = T_AUTO) { jng(std::string(label), type); }//-V524
+void jng(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7E, 0x8E, 0x0F); }//-V524
+void jng(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7E, 0x8E, 0x0F); }//-V524
+void jnge(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7C, 0x8C, 0x0F); }//-V524
+void jnge(const char *label, LabelType type = T_AUTO) { jnge(std::string(label), type); }//-V524
+void jnge(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7C, 0x8C, 0x0F); }//-V524
+void jnge(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7C, 0x8C, 0x0F); }//-V524
+void jnl(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7D, 0x8D, 0x0F); }//-V524
+void jnl(const char *label, LabelType type = T_AUTO) { jnl(std::string(label), type); }//-V524
+void jnl(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7D, 0x8D, 0x0F); }//-V524
+void jnl(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7D, 0x8D, 0x0F); }//-V524
+void jnle(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7F, 0x8F, 0x0F); }//-V524
+void jnle(const char *label, LabelType type = T_AUTO) { jnle(std::string(label), type); }//-V524
+void jnle(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7F, 0x8F, 0x0F); }//-V524
+void jnle(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7F, 0x8F, 0x0F); }//-V524
+void jno(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x71, 0x81, 0x0F); }//-V524
+void jno(const char *label, LabelType type = T_AUTO) { jno(std::string(label), type); }//-V524
+void jno(const void *addr) { opJmpAbs(addr, T_NEAR, 0x71, 0x81, 0x0F); }//-V524
+void jno(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x71, 0x81, 0x0F); }//-V524
+void jnp(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7B, 0x8B, 0x0F); }//-V524
+void jnp(const char *label, LabelType type = T_AUTO) { jnp(std::string(label), type); }//-V524
+void jnp(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7B, 0x8B, 0x0F); }//-V524
+void jnp(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7B, 0x8B, 0x0F); }//-V524
+void jns(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x79, 0x89, 0x0F); }//-V524
+void jns(const char *label, LabelType type = T_AUTO) { jns(std::string(label), type); }//-V524
+void jns(const void *addr) { opJmpAbs(addr, T_NEAR, 0x79, 0x89, 0x0F); }//-V524
+void jns(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x79, 0x89, 0x0F); }//-V524
+void jnz(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x75, 0x85, 0x0F); }//-V524
+void jnz(const char *label, LabelType type = T_AUTO) { jnz(std::string(label), type); }//-V524
+void jnz(const void *addr) { opJmpAbs(addr, T_NEAR, 0x75, 0x85, 0x0F); }//-V524
+void jnz(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x75, 0x85, 0x0F); }//-V524
+void jo(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x70, 0x80, 0x0F); }//-V524
+void jo(const char *label, LabelType type = T_AUTO) { jo(std::string(label), type); }//-V524
+void jo(const void *addr) { opJmpAbs(addr, T_NEAR, 0x70, 0x80, 0x0F); }//-V524
+void jo(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x70, 0x80, 0x0F); }//-V524
+void jp(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7A, 0x8A, 0x0F); }//-V524
+void jp(const char *label, LabelType type = T_AUTO) { jp(std::string(label), type); }//-V524
+void jp(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7A, 0x8A, 0x0F); }//-V524
+void jp(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7A, 0x8A, 0x0F); }//-V524
+void jpe(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7A, 0x8A, 0x0F); }//-V524
+void jpe(const char *label, LabelType type = T_AUTO) { jpe(std::string(label), type); }//-V524
+void jpe(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7A, 0x8A, 0x0F); }//-V524
+void jpe(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7A, 0x8A, 0x0F); }//-V524
+void jpo(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x7B, 0x8B, 0x0F); }//-V524
+void jpo(const char *label, LabelType type = T_AUTO) { jpo(std::string(label), type); }//-V524
+void jpo(const void *addr) { opJmpAbs(addr, T_NEAR, 0x7B, 0x8B, 0x0F); }//-V524
+void jpo(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x7B, 0x8B, 0x0F); }//-V524
+void js(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x78, 0x88, 0x0F); }//-V524
+void js(const char *label, LabelType type = T_AUTO) { js(std::string(label), type); }//-V524
+void js(const void *addr) { opJmpAbs(addr, T_NEAR, 0x78, 0x88, 0x0F); }//-V524
+void js(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x78, 0x88, 0x0F); }//-V524
+void jz(const Label& label, LabelType type = T_AUTO) { opJmp(label, type, 0x74, 0x84, 0x0F); }//-V524
+void jz(const char *label, LabelType type = T_AUTO) { jz(std::string(label), type); }//-V524
+void jz(const void *addr) { opJmpAbs(addr, T_NEAR, 0x74, 0x84, 0x0F); }//-V524
+void jz(std::string label, LabelType type = T_AUTO) { opJmp(label, type, 0x74, 0x84, 0x0F); }//-V524
+void lahf() { db(0x9F); }
+void lddqu(const Xmm& xmm, const Address& addr) { db(0xF2); opModM(addr, xmm, 0x0F, 0xF0); }
+void ldmxcsr(const Address& addr) { opModM(addr, Reg32(2), 0x0F, 0xAE); }
+void lea(const Reg& reg, const Address& addr) { if (!reg.isBit(16 | i32e)) throw Error(ERR_BAD_SIZE_OF_REGISTER); opModM(addr, reg, 0x8D); }
+void lfence() { db(0x0F); db(0xAE); db(0xE8); }
+void lock() { db(0xF0); }
+void lzcnt(const Reg&reg, const Operand& op) { opSp1(reg, op, 0xF3, 0x0F, 0xBD); }
+void maskmovdqu(const Xmm& reg1, const Xmm& reg2) { db(0x66); opModR(reg1, reg2, 0x0F, 0xF7); }
+void maskmovq(const Mmx& reg1, const Mmx& reg2) { if (!reg1.isMMX() || !reg2.isMMX()) throw Error(ERR_BAD_COMBINATION); opModR(reg1, reg2, 0x0F, 0xF7); }
+void maxpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5F, 0x66, isXMM_XMMorMEM); }
+void maxps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5F, 0x100, isXMM_XMMorMEM); }
+void maxsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5F, 0xF2, isXMM_XMMorMEM); }
+void maxss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5F, 0xF3, isXMM_XMMorMEM); }
+void mfence() { db(0x0F); db(0xAE); db(0xF0); }
+void minpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5D, 0x66, isXMM_XMMorMEM); }
+void minps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5D, 0x100, isXMM_XMMorMEM); }
+void minsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5D, 0xF2, isXMM_XMMorMEM); }
+void minss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5D, 0xF3, isXMM_XMMorMEM); }
+void monitor() { db(0x0F); db(0x01); db(0xC8); }
+void movapd(const Address& addr, const Xmm& xmm) { db(0x66); opModM(addr, xmm, 0x0F, 0x29); }
+void movapd(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x28, 0x66); }
+void movaps(const Address& addr, const Xmm& xmm) { opModM(addr, xmm, 0x0F, 0x29); }
+void movaps(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x28, 0x100); }
+void movbe(const Address& addr, const Reg& reg) { opModM(addr, reg, 0x0F, 0x38, 0xF1); }
+void movbe(const Reg& reg, const Address& addr) { opModM(addr, reg, 0x0F, 0x38, 0xF0); }
+void movd(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, 0x0F, 0x7E); }
+void movd(const Mmx& mmx, const Address& addr) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, 0x0F, 0x6E); }
+void movd(const Mmx& mmx, const Reg32& reg) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, 0x0F, 0x6E); }
+void movd(const Reg32& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, 0x0F, 0x7E); }
+void movddup(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x12, 0xF2, isXMM_XMMorMEM, NONE, NONE); }
+void movdq2q(const Mmx& mmx, const Xmm& xmm) { db(0xF2); opModR(mmx, xmm, 0x0F, 0xD6); }
+void movdqa(const Address& addr, const Xmm& xmm) { db(0x66); opModM(addr, xmm, 0x0F, 0x7F); }
+void movdqa(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x6F, 0x66); }
+void movdqu(const Address& addr, const Xmm& xmm) { db(0xF3); opModM(addr, xmm, 0x0F, 0x7F); }
+void movdqu(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x6F, 0xF3); }
+void movhlps(const Xmm& reg1, const Xmm& reg2) { opModR(reg1, reg2, 0x0F, 0x12); }
+void movhpd(const Operand& op1, const Operand& op2) { opMovXMM(op1, op2, 0x16, 0x66); }
+void movhps(const Operand& op1, const Operand& op2) { opMovXMM(op1, op2, 0x16, 0x100); }
+void movlhps(const Xmm& reg1, const Xmm& reg2) { opModR(reg1, reg2, 0x0F, 0x16); }
+void movlpd(const Operand& op1, const Operand& op2) { opMovXMM(op1, op2, 0x12, 0x66); }
+void movlps(const Operand& op1, const Operand& op2) { opMovXMM(op1, op2, 0x12, 0x100); }
+void movmskpd(const Reg32e& reg, const Xmm& xmm) { db(0x66); movmskps(reg, xmm); }
+void movmskps(const Reg32e& reg, const Xmm& xmm) { opModR(reg, xmm, 0x0F, 0x50); }
+void movntdq(const Address& addr, const Xmm& reg) { opModM(addr, Reg16(reg.getIdx()), 0x0F, 0xE7); }
+void movntdqa(const Xmm& xmm, const Address& addr) { db(0x66); opModM(addr, xmm, 0x0F, 0x38, 0x2A); }
+void movnti(const Address& addr, const Reg32e& reg) { opModM(addr, reg, 0x0F, 0xC3); }
+void movntpd(const Address& addr, const Xmm& reg) { opModM(addr, Reg16(reg.getIdx()), 0x0F, 0x2B); }
+void movntps(const Address& addr, const Xmm& xmm) { opModM(addr, Mmx(xmm.getIdx()), 0x0F, 0x2B); }
+void movntq(const Address& addr, const Mmx& mmx) { if (!mmx.isMMX()) throw Error(ERR_BAD_COMBINATION); opModM(addr, mmx, 0x0F, 0xE7); }
+void movq(const Address& addr, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModM(addr, mmx, 0x0F, mmx.isXMM() ? 0xD6 : 0x7F); }
+void movq(const Mmx& mmx, const Operand& op) { if (mmx.isXMM()) db(0xF3); opModRM(mmx, op, (mmx.getKind() == op.getKind()), op.isMEM(), 0x0F, mmx.isXMM() ? 0x7E : 0x6F); }
+void movq2dq(const Xmm& xmm, const Mmx& mmx) { db(0xF3); opModR(xmm, mmx, 0x0F, 0xD6); }
+void movsb() { db(0xA4); }
+void movsd() { db(0xA5); }
+void movsd(const Address& addr, const Xmm& xmm) { db(0xF2); opModM(addr, xmm, 0x0F, 0x11); }
+void movsd(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x10, 0xF2); }
+void movshdup(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x16, 0xF3, isXMM_XMMorMEM, NONE, NONE); }
+void movsldup(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x12, 0xF3, isXMM_XMMorMEM, NONE, NONE); }
+void movss(const Address& addr, const Xmm& xmm) { db(0xF3); opModM(addr, xmm, 0x0F, 0x11); }
+void movss(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x10, 0xF3); }
+void movsw() { db(0x66); db(0xA5); }
+void movsx(const Reg& reg, const Operand& op) { opMovxx(reg, op, 0xBE); }
+void movupd(const Address& addr, const Xmm& xmm) { db(0x66); opModM(addr, xmm, 0x0F, 0x11); }
+void movupd(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x10, 0x66); }
+void movups(const Address& addr, const Xmm& xmm) { opModM(addr, xmm, 0x0F, 0x11); }
+void movups(const Xmm& xmm, const Operand& op) { opMMX(xmm, op, 0x10, 0x100); }
+void movzx(const Reg& reg, const Operand& op) { opMovxx(reg, op, 0xB6); }
+void mpsadbw(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, 0x42, 0x66, isXMM_XMMorMEM, static_cast<uint8>(imm), 0x3A); }
+void mul(const Operand& op) { opR_ModM(op, 0, 4, 0xF6); }
+void mulpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x59, 0x66, isXMM_XMMorMEM); }
+void mulps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x59, 0x100, isXMM_XMMorMEM); }
+void mulsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x59, 0xF2, isXMM_XMMorMEM); }
+void mulss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x59, 0xF3, isXMM_XMMorMEM); }
+void mulx(const Reg32e& r1, const Reg32e& r2, const Operand& op) { opGpr(r1, r2, op, T_F2 | T_0F38, 0xf6, true); }
+void mwait() { db(0x0F); db(0x01); db(0xC9); }
+void neg(const Operand& op) { opR_ModM(op, 0, 3, 0xF6); }
+void not_(const Operand& op) { opR_ModM(op, 0, 2, 0xF6); }
+void or_(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x08, 1); }
+void or_(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x08); }
+void orpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x56, 0x66, isXMM_XMMorMEM); }
+void orps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x56, 0x100, isXMM_XMMorMEM); }
+void pabsb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x1C, 0x66, NONE, 0x38); }
+void pabsd(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x1E, 0x66, NONE, 0x38); }
+void pabsw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x1D, 0x66, NONE, 0x38); }
+void packssdw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x6B); }
+void packsswb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x63); }
+void packusdw(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x2B, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void packuswb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x67); }
+void paddb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xFC); }
+void paddd(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xFE); }
+void paddq(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xD4); }
+void paddsb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xEC); }
+void paddsw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xED); }
+void paddusb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xDC); }
+void paddusw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xDD); }
+void paddw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xFD); }
+void palignr(const Mmx& mmx, const Operand& op, int imm) { opMMX(mmx, op, 0x0f, 0x66, static_cast<uint8>(imm), 0x3a); }
+void pand(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xDB); }
+void pandn(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xDF); }
+void pause() { db(0xF3); db(0x90); }
+void pavgb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xE0); }
+void pavgw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xE3); }
+void pblendvb(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x10, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pblendw(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, 0x0E, 0x66, isXMM_XMMorMEM, static_cast<uint8>(imm), 0x3A); }
+void pclmulhqhdq(const Xmm& xmm, const Operand& op) { pclmulqdq(xmm, op, 0x11); }
+void pclmulhqlqdq(const Xmm& xmm, const Operand& op) { pclmulqdq(xmm, op, 0x01); }
+void pclmullqhdq(const Xmm& xmm, const Operand& op) { pclmulqdq(xmm, op, 0x10); }
+void pclmullqlqdq(const Xmm& xmm, const Operand& op) { pclmulqdq(xmm, op, 0x00); }
+void pclmulqdq(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, 0x44, 0x66, isXMM_XMMorMEM, static_cast<uint8>(imm), 0x3A); }
+void pcmpeqb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x74); }
+void pcmpeqd(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x76); }
+void pcmpeqq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x29, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pcmpeqw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x75); }
+void pcmpestri(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x61, 0x66, isXMM_XMMorMEM, imm, 0x3A); }
+void pcmpestrm(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x60, 0x66, isXMM_XMMorMEM, imm, 0x3A); }
+void pcmpgtb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x64); }
+void pcmpgtd(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x66); }
+void pcmpgtq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x37, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pcmpgtw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x65); }
+void pcmpistri(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x63, 0x66, isXMM_XMMorMEM, imm, 0x3A); }
+void pcmpistrm(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x62, 0x66, isXMM_XMMorMEM, imm, 0x3A); }
+void pdep(const Reg32e& r1, const Reg32e& r2, const Operand& op) { opGpr(r1, r2, op, T_F2 | T_0F38, 0xf5, true); }
+void pext(const Reg32e& r1, const Reg32e& r2, const Operand& op) { opGpr(r1, r2, op, T_F3 | T_0F38, 0xf5, true); }
+void pextrb(const Operand& op, const Xmm& xmm, uint8 imm) { opExt(op, xmm, 0x14, imm); }
+void pextrd(const Operand& op, const Xmm& xmm, uint8 imm) { opExt(op, xmm, 0x16, imm); }
+void pextrw(const Operand& op, const Mmx& xmm, uint8 imm) { opExt(op, xmm, 0x15, imm, true); }
+void phaddd(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x02, 0x66, NONE, 0x38); }
+void phaddsw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x03, 0x66, NONE, 0x38); }
+void phaddw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x01, 0x66, NONE, 0x38); }
+void phminposuw(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x41, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void phsubd(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x06, 0x66, NONE, 0x38); }
+void phsubsw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x07, 0x66, NONE, 0x38); }
+void phsubw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x05, 0x66, NONE, 0x38); }
+void pinsrb(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x20, 0x66, isXMM_REG32orMEM, imm, 0x3A); }
+void pinsrd(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x22, 0x66, isXMM_REG32orMEM, imm, 0x3A); }
+void pinsrw(const Mmx& mmx, const Operand& op, int imm) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opGen(mmx, op, 0xC4, mmx.isXMM() ? 0x66 : NONE, 0, imm); }
+void pmaddubsw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x04, 0x66, NONE, 0x38); }
+void pmaddwd(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xF5); }
+void pmaxsb(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x3C, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmaxsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x3D, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmaxsw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xEE); }
+void pmaxub(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xDE); }
+void pmaxud(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x3F, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmaxuw(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x3E, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pminsb(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x38, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pminsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x39, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pminsw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xEA); }
+void pminub(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xDA); }
+void pminud(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x3B, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pminuw(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x3A, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovmskb(const Reg32e& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(reg, mmx, 0x0F, 0xD7); }
+void pmovsxbd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x21, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovsxbq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x22, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovsxbw(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x20, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovsxdq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x25, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovsxwd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x23, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovsxwq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x24, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovzxbd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x31, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovzxbq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x32, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovzxbw(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x30, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovzxdq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x35, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovzxwd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x33, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmovzxwq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x34, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmuldq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x28, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmulhrsw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x0B, 0x66, NONE, 0x38); }
+void pmulhuw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xE4); }
+void pmulhw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xE5); }
+void pmulld(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x40, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void pmullw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xD5); }
+void pmuludq(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xF4); }
+void popcnt(const Reg&reg, const Operand& op) { opSp1(reg, op, 0xF3, 0x0F, 0xB8); }
+void popf() { db(0x9D); }
+void por(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xEB); }
+void prefetchnta(const Address& addr) { opModM(addr, Reg32(0), 0x0F, 0x18); }
+void prefetcht0(const Address& addr) { opModM(addr, Reg32(1), 0x0F, 0x18); }
+void prefetcht1(const Address& addr) { opModM(addr, Reg32(2), 0x0F, 0x18); }
+void prefetcht2(const Address& addr) { opModM(addr, Reg32(3), 0x0F, 0x18); }
+void prefetchw(const Address& addr) { opModM(addr, Reg32(1), 0x0F, 0x0D); }
+void prefetchwt1(const Address& addr) { opModM(addr, Reg32(2), 0x0F, 0x0D); }
+void psadbw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xF6); }
+void pshufb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x00, 0x66, NONE, 0x38); }
+void pshufd(const Mmx& mmx, const Operand& op, uint8 imm8) { opMMX(mmx, op, 0x70, 0x66, imm8); }
+void pshufhw(const Mmx& mmx, const Operand& op, uint8 imm8) { opMMX(mmx, op, 0x70, 0xF3, imm8); }
+void pshuflw(const Mmx& mmx, const Operand& op, uint8 imm8) { opMMX(mmx, op, 0x70, 0xF2, imm8); }
+void pshufw(const Mmx& mmx, const Operand& op, uint8 imm8) { opMMX(mmx, op, 0x70, 0x00, imm8); }
+void psignb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x08, 0x66, NONE, 0x38); }
+void psignd(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x0A, 0x66, NONE, 0x38); }
+void psignw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x09, 0x66, NONE, 0x38); }
+void pslld(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xF2); }
+void pslld(const Mmx& mmx, int imm8) { opMMX_IMM(mmx, imm8, 0x72, 6); }
+void pslldq(const Xmm& xmm, int imm8) { opMMX_IMM(xmm, imm8, 0x73, 7); }
+void psllq(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xF3); }
+void psllq(const Mmx& mmx, int imm8) { opMMX_IMM(mmx, imm8, 0x73, 6); }
+void psllw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xF1); }
+void psllw(const Mmx& mmx, int imm8) { opMMX_IMM(mmx, imm8, 0x71, 6); }
+void psrad(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xE2); }
+void psrad(const Mmx& mmx, int imm8) { opMMX_IMM(mmx, imm8, 0x72, 4); }
+void psraw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xE1); }
+void psraw(const Mmx& mmx, int imm8) { opMMX_IMM(mmx, imm8, 0x71, 4); }
+void psrld(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xD2); }
+void psrld(const Mmx& mmx, int imm8) { opMMX_IMM(mmx, imm8, 0x72, 2); }
+void psrldq(const Xmm& xmm, int imm8) { opMMX_IMM(xmm, imm8, 0x73, 3); }
+void psrlq(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xD3); }
+void psrlq(const Mmx& mmx, int imm8) { opMMX_IMM(mmx, imm8, 0x73, 2); }
+void psrlw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xD1); }
+void psrlw(const Mmx& mmx, int imm8) { opMMX_IMM(mmx, imm8, 0x71, 2); }
+void psubb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xF8); }
+void psubd(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xFA); }
+void psubq(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xFB); }
+void psubsb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xE8); }
+void psubsw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xE9); }
+void psubusb(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xD8); }
+void psubusw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xD9); }
+void psubw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xF9); }
+void ptest(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x17, 0x66, isXMM_XMMorMEM, NONE, 0x38); }
+void punpckhbw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x68); }
+void punpckhdq(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x6A); }
+void punpckhqdq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x6D, 0x66, isXMM_XMMorMEM); }
+void punpckhwd(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x69); }
+void punpcklbw(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x60); }
+void punpckldq(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x62); }
+void punpcklqdq(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x6C, 0x66, isXMM_XMMorMEM); }
+void punpcklwd(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0x61); }
+void pushf() { db(0x9C); }
+void pxor(const Mmx& mmx, const Operand& op) { opMMX(mmx, op, 0xEF); }
+void rcl(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 2); }
+void rcl(const Operand& op, int imm) { opShift(op, imm, 2); }
+void rcpps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x53, 0x100, isXMM_XMMorMEM); }
+void rcpss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x53, 0xF3, isXMM_XMMorMEM); }
+void rcr(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 3); }
+void rcr(const Operand& op, int imm) { opShift(op, imm, 3); }
+void rdmsr() { db(0x0F); db(0x32); }
+void rdpmc() { db(0x0F); db(0x33); }
+void rdrand(const Reg& r) { if (r.isBit(8)) throw Error(ERR_BAD_SIZE_OF_REGISTER); opModR(Reg(6, Operand::REG, r.getBit()), r, 0x0F, 0xC7); }
+void rdseed(const Reg& r) { if (r.isBit(8)) throw Error(ERR_BAD_SIZE_OF_REGISTER); opModR(Reg(7, Operand::REG, r.getBit()), r, 0x0F, 0xC7); }
+void rdtsc() { db(0x0F); db(0x31); }
+void rdtscp() { db(0x0F); db(0x01); db(0xF9); }
+void rep() { db(0xF3); }
+void ret(int imm = 0) { if (imm) { db(0xC2); dw(imm); } else { db(0xC3); } }
+void rol(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 0); }
+void rol(const Operand& op, int imm) { opShift(op, imm, 0); }
+void ror(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 1); }
+void ror(const Operand& op, int imm) { opShift(op, imm, 1); }
+void rorx(const Reg32e& r, const Operand& op, uint8 imm) { opGpr(r, op, Reg32e(0, r.getBit()), T_0F3A | T_F2, 0xF0, false, imm); }
+void roundpd(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x09, 0x66, isXMM_XMMorMEM, imm, 0x3A); }
+void roundps(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0x08, 0x66, isXMM_XMMorMEM, imm, 0x3A); }
+void roundsd(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, 0x0B, 0x66, isXMM_XMMorMEM, static_cast<uint8>(imm), 0x3A); }
+void roundss(const Xmm& xmm, const Operand& op, int imm) { opGen(xmm, op, 0x0A, 0x66, isXMM_XMMorMEM, static_cast<uint8>(imm), 0x3A); }
+void rsqrtps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x52, 0x100, isXMM_XMMorMEM); }
+void rsqrtss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x52, 0xF3, isXMM_XMMorMEM); }
+void sahf() { db(0x9E); }
+void sal(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 4); }
+void sal(const Operand& op, int imm) { opShift(op, imm, 4); }
+void sar(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 7); }
+void sar(const Operand& op, int imm) { opShift(op, imm, 7); }
+void sarx(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opGpr(r1, op, r2, T_F3 | T_0F38, 0xf7, false); }
+void sbb(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x18, 3); }
+void sbb(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x18); }
+void scasb() { db(0xAE); }
+void scasd() { db(0xAF); }
+void scasw() { db(0x66); db(0xAF); }
+void seta(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 7); }//-V524
+void setae(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 3); }//-V524
+void setb(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 2); }//-V524
+void setbe(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 6); }//-V524
+void setc(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 2); }//-V524
+void sete(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 4); }//-V524
+void setg(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 15); }//-V524
+void setge(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 13); }//-V524
+void setl(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 12); }//-V524
+void setle(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 14); }//-V524
+void setna(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 6); }//-V524
+void setnae(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 2); }//-V524
+void setnb(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 3); }//-V524
+void setnbe(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 7); }//-V524
+void setnc(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 3); }//-V524
+void setne(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 5); }//-V524
+void setng(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 14); }//-V524
+void setnge(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 12); }//-V524
+void setnl(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 13); }//-V524
+void setnle(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 15); }//-V524
+void setno(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 1); }//-V524
+void setnp(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 11); }//-V524
+void setns(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 9); }//-V524
+void setnz(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 5); }//-V524
+void seto(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 0); }//-V524
+void setp(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 10); }//-V524
+void setpe(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 10); }//-V524
+void setpo(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 11); }//-V524
+void sets(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 8); }//-V524
+void setz(const Operand& op) { opR_ModM(op, 8, 0, 0x0F, 0x90 | 4); }//-V524
+void sfence() { db(0x0F); db(0xAE); db(0xF8); }
+void sha1msg1(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xC9, NONE, isXMM_XMMorMEM, NONE, 0x38); }
+void sha1msg2(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xCA, NONE, isXMM_XMMorMEM, NONE, 0x38); }
+void sha1nexte(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xC8, NONE, isXMM_XMMorMEM, NONE, 0x38); }
+void sha1rnds4(const Xmm& xmm, const Operand& op, uint8 imm) { opGen(xmm, op, 0xCC, NONE, isXMM_XMMorMEM, imm, 0x3A); }
+void sha256msg1(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xCC, NONE, isXMM_XMMorMEM, NONE, 0x38); }
+void sha256msg2(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xCD, NONE, isXMM_XMMorMEM, NONE, 0x38); }
+void sha256rnds2(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0xCB, NONE, isXMM_XMMorMEM, NONE, 0x38); }
+void shl(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 4); }
+void shl(const Operand& op, int imm) { opShift(op, imm, 4); }
+void shld(const Operand& op, const Reg& reg, const Reg8& _cl) { opShxd(op, reg, 0, 0xA4, &_cl); }
+void shld(const Operand& op, const Reg& reg, uint8 imm) { opShxd(op, reg, imm, 0xA4); }
+void shlx(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opGpr(r1, op, r2, T_66 | T_0F38, 0xf7, false); }
+void shr(const Operand& op, const Reg8& _cl) { opShift(op, _cl, 5); }
+void shr(const Operand& op, int imm) { opShift(op, imm, 5); }
+void shrd(const Operand& op, const Reg& reg, const Reg8& _cl) { opShxd(op, reg, 0, 0xAC, &_cl); }
+void shrd(const Operand& op, const Reg& reg, uint8 imm) { opShxd(op, reg, imm, 0xAC); }
+void shrx(const Reg32e& r1, const Operand& op, const Reg32e& r2) { opGpr(r1, op, r2, T_F2 | T_0F38, 0xf7, false); }
+void shufpd(const Xmm& xmm, const Operand& op, uint8 imm8) { opGen(xmm, op, 0xC6, 0x66, isXMM_XMMorMEM, imm8); }
+void shufps(const Xmm& xmm, const Operand& op, uint8 imm8) { opGen(xmm, op, 0xC6, 0x100, isXMM_XMMorMEM, imm8); }
+void sqrtpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x51, 0x66, isXMM_XMMorMEM); }
+void sqrtps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x51, 0x100, isXMM_XMMorMEM); }
+void sqrtsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x51, 0xF2, isXMM_XMMorMEM); }
+void sqrtss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x51, 0xF3, isXMM_XMMorMEM); }
+void stac() { db(0x0F); db(0x01); db(0xCB); }
+void stc() { db(0xF9); }
+void std() { db(0xFD); }
+void sti() { db(0xFB); }
+void stmxcsr(const Address& addr) { opModM(addr, Reg32(3), 0x0F, 0xAE); }
+void stosb() { db(0xAA); }
+void stosd() { db(0xAB); }
+void stosw() { db(0x66); db(0xAB); }
+void sub(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x28, 5); }
+void sub(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x28); }
+void subpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5C, 0x66, isXMM_XMMorMEM); }
+void subps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5C, 0x100, isXMM_XMMorMEM); }
+void subsd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5C, 0xF2, isXMM_XMMorMEM); }
+void subss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x5C, 0xF3, isXMM_XMMorMEM); }
+void tzcnt(const Reg&reg, const Operand& op) { opSp1(reg, op, 0xF3, 0x0F, 0xBC); }
+void ucomisd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x2E, 0x66, isXMM_XMMorMEM); }
+void ucomiss(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x2E, 0x100, isXMM_XMMorMEM); }
+void ud2() { db(0x0F); db(0x0B); }
+void unpckhpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x15, 0x66, isXMM_XMMorMEM); }
+void unpckhps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x15, 0x100, isXMM_XMMorMEM); }
+void unpcklpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x14, 0x66, isXMM_XMMorMEM); }
+void unpcklps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x14, 0x100, isXMM_XMMorMEM); }
+void vaddpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x58); }
+void vaddps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x58); }
+void vaddsd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F2 | T_EW1 | T_EVEX | T_ER_Z | T_N8, 0x58); }
+void vaddss(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F3 | T_EW0 | T_EVEX | T_ER_Z | T_N4, 0x58); }
+void vaddsubpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_66 | T_0F | T_YMM, 0xD0); }
+void vaddsubps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_F2 | T_0F | T_YMM, 0xD0); }
+void vaesdec(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_66 | T_0F38 | T_YMM | T_EVEX, 0xDE); }
+void vaesdeclast(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_66 | T_0F38 | T_YMM | T_EVEX, 0xDF); }
+void vaesenc(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_66 | T_0F38 | T_YMM | T_EVEX, 0xDC); }
+void vaesenclast(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_66 | T_0F38 | T_YMM | T_EVEX, 0xDD); }
+void vaesimc(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F38 | T_W0, 0xDB); }
+void vaeskeygenassist(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F3A, 0xDF, imm); }
+void vandnpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x55); }
+void vandnps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x55); }
+void vandpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x54); }
+void vandps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x54); }
+void vblendpd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W0 | T_YMM, 0x0D, imm); }
+void vblendps(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W0 | T_YMM, 0x0C, imm); }
+void vblendvpd(const Xmm& x1, const Xmm& x2, const Operand& op, const Xmm& x4) { opAVX_X_X_XM(x1, x2, op, T_0F3A | T_66 | T_YMM, 0x4B, x4.getIdx() << 4); }
+void vblendvps(const Xmm& x1, const Xmm& x2, const Operand& op, const Xmm& x4) { opAVX_X_X_XM(x1, x2, op, T_0F3A | T_66 | T_YMM, 0x4A, x4.getIdx() << 4); }
+void vbroadcastf128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x1A); }
+void vbroadcasti128(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x5A); }
+void vbroadcastsd(const Ymm& y, const Operand& op) { if (!op.isMEM() && !(y.isYMM() && op.isXMM()) && !(y.isZMM() && op.isXMM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(y, op, T_0F38 | T_66 | T_W0 | T_YMM | T_EVEX | T_EW1 | T_N8, 0x19); }
+void vbroadcastss(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(x, op, T_N4 | T_66 | T_0F38 | T_W0 | T_YMM | T_EVEX, 0x18); }
+void vcmpeq_ospd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 16); }
+void vcmpeq_osps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 16); }
+void vcmpeq_ossd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 16); }
+void vcmpeq_osss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 16); }
+void vcmpeq_uqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 8); }
+void vcmpeq_uqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 8); }
+void vcmpeq_uqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 8); }
+void vcmpeq_uqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 8); }
+void vcmpeq_uspd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 24); }
+void vcmpeq_usps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 24); }
+void vcmpeq_ussd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 24); }
+void vcmpeq_usss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 24); }
+void vcmpeqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 0); }
+void vcmpeqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 0); }
+void vcmpeqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 0); }
+void vcmpeqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 0); }
+void vcmpfalse_ospd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 27); }
+void vcmpfalse_osps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 27); }
+void vcmpfalse_ossd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 27); }
+void vcmpfalse_osss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 27); }
+void vcmpfalsepd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 11); }
+void vcmpfalseps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 11); }
+void vcmpfalsesd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 11); }
+void vcmpfalsess(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 11); }
+void vcmpge_oqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 29); }
+void vcmpge_oqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 29); }
+void vcmpge_oqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 29); }
+void vcmpge_oqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 29); }
+void vcmpgepd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 13); }
+void vcmpgeps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 13); }
+void vcmpgesd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 13); }
+void vcmpgess(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 13); }
+void vcmpgt_oqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 30); }
+void vcmpgt_oqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 30); }
+void vcmpgt_oqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 30); }
+void vcmpgt_oqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 30); }
+void vcmpgtpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 14); }
+void vcmpgtps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 14); }
+void vcmpgtsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 14); }
+void vcmpgtss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 14); }
+void vcmple_oqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 18); }
+void vcmple_oqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 18); }
+void vcmple_oqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 18); }
+void vcmple_oqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 18); }
+void vcmplepd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 2); }
+void vcmpleps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 2); }
+void vcmplesd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 2); }
+void vcmpless(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 2); }
+void vcmplt_oqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 17); }
+void vcmplt_oqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 17); }
+void vcmplt_oqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 17); }
+void vcmplt_oqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 17); }
+void vcmpltpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 1); }
+void vcmpltps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 1); }
+void vcmpltsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 1); }
+void vcmpltss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 1); }
+void vcmpneq_oqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 12); }
+void vcmpneq_oqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 12); }
+void vcmpneq_oqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 12); }
+void vcmpneq_oqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 12); }
+void vcmpneq_ospd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 28); }
+void vcmpneq_osps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 28); }
+void vcmpneq_ossd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 28); }
+void vcmpneq_osss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 28); }
+void vcmpneq_uspd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 20); }
+void vcmpneq_usps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 20); }
+void vcmpneq_ussd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 20); }
+void vcmpneq_usss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 20); }
+void vcmpneqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 4); }
+void vcmpneqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 4); }
+void vcmpneqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 4); }
+void vcmpneqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 4); }
+void vcmpnge_uqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 25); }
+void vcmpnge_uqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 25); }
+void vcmpnge_uqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 25); }
+void vcmpnge_uqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 25); }
+void vcmpngepd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 9); }
+void vcmpngeps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 9); }
+void vcmpngesd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 9); }
+void vcmpngess(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 9); }
+void vcmpngt_uqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 26); }
+void vcmpngt_uqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 26); }
+void vcmpngt_uqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 26); }
+void vcmpngt_uqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 26); }
+void vcmpngtpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 10); }
+void vcmpngtps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 10); }
+void vcmpngtsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 10); }
+void vcmpngtss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 10); }
+void vcmpnle_uqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 22); }
+void vcmpnle_uqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 22); }
+void vcmpnle_uqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 22); }
+void vcmpnle_uqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 22); }
+void vcmpnlepd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 6); }
+void vcmpnleps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 6); }
+void vcmpnlesd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 6); }
+void vcmpnless(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 6); }
+void vcmpnlt_uqpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 21); }
+void vcmpnlt_uqps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 21); }
+void vcmpnlt_uqsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 21); }
+void vcmpnlt_uqss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 21); }
+void vcmpnltpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 5); }
+void vcmpnltps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 5); }
+void vcmpnltsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 5); }
+void vcmpnltss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 5); }
+void vcmpord_spd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 23); }
+void vcmpord_sps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 23); }
+void vcmpord_ssd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 23); }
+void vcmpord_sss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 23); }
+void vcmpordpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 7); }
+void vcmpordps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 7); }
+void vcmpordsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 7); }
+void vcmpordss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 7); }
+void vcmppd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM, 0xC2, imm); }
+void vcmpps(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_0F | T_YMM, 0xC2, imm); }
+void vcmpsd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_F2 | T_0F, 0xC2, imm); }
+void vcmpss(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_F3 | T_0F, 0xC2, imm); }
+void vcmptrue_uspd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 31); }
+void vcmptrue_usps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 31); }
+void vcmptrue_ussd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 31); }
+void vcmptrue_usss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 31); }
+void vcmptruepd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 15); }
+void vcmptrueps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 15); }
+void vcmptruesd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 15); }
+void vcmptruess(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 15); }
+void vcmpunord_spd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 19); }
+void vcmpunord_sps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 19); }
+void vcmpunord_ssd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 19); }
+void vcmpunord_sss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 19); }
+void vcmpunordpd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmppd(x1, x2, op, 3); }
+void vcmpunordps(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpps(x1, x2, op, 3); }
+void vcmpunordsd(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpsd(x1, x2, op, 3); }
+void vcmpunordss(const Xmm& x1, const Xmm& x2, const Operand& op) { vcmpss(x1, x2, op, 3); }
+void vcomisd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N8 | T_66 | T_0F | T_EW1 | T_EVEX | T_SAE_X, 0x2F); }
+void vcomiss(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N4 | T_0F | T_EW0 | T_EVEX | T_SAE_X, 0x2F); }
+void vcvtdq2pd(const Xmm& x, const Operand& op) { checkCvt1(x, op); opVex(x, 0, op, T_0F | T_F3 | T_YMM | T_EVEX | T_EW0 | T_B32 | T_N8 | T_N_VL, 0xE6); }
+void vcvtdq2ps(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x5B); }
+void vcvtpd2dq(const Xmm& x, const Operand& op) { opCvt2(x, op, T_0F | T_F2 | T_YMM | T_EVEX | T_EW1 | T_B64 | T_ER_Z, 0xE6); }
+void vcvtpd2ps(const Xmm& x, const Operand& op) { opCvt2(x, op, T_0F | T_66 | T_YMM | T_EVEX | T_EW1 | T_B64 | T_ER_Z, 0x5A); }
+void vcvtph2ps(const Xmm& x, const Operand& op) { checkCvt1(x, op); opVex(x, 0, op, T_0F38 | T_66 | T_W0 | T_EVEX | T_EW0 | T_N8 | T_N_VL | T_SAE_Y, 0x13); }
+void vcvtps2dq(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x5B); }
+void vcvtps2pd(const Xmm& x, const Operand& op) { checkCvt1(x, op); opVex(x, 0, op, T_0F | T_YMM | T_EVEX | T_EW0 | T_B32 | T_N8 | T_N_VL | T_SAE_Y, 0x5A); }
+void vcvtps2ph(const Operand& op, const Xmm& x, uint8 imm) { checkCvt1(x, op); opVex(x, 0, op, T_0F3A | T_66 | T_W0 | T_EVEX | T_EW0 | T_N8 | T_N_VL | T_SAE_Y, 0x1D, imm); }
+void vcvtsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F2 | T_W0 | T_EVEX | T_EW0 | T_N4 | T_ER_X, 0x2D); }
+void vcvtsd2ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_F2 | T_0F | T_EW1 | T_EVEX | T_ER_X, 0x5A); }
+void vcvtsi2sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opCvt3(x1, x2, op, T_0F | T_F2 | T_EVEX, T_W1 | T_EW1 | T_ER_X | T_N8, T_W0 | T_EW0 | T_N4, 0x2A); }
+void vcvtsi2ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opCvt3(x1, x2, op, T_0F | T_F3 | T_EVEX | T_ER_X, T_W1 | T_EW1 | T_N8, T_W0 | T_EW0 | T_N4, 0x2A); }
+void vcvtss2sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_F3 | T_0F | T_EW0 | T_EVEX | T_SAE_X, 0x5A); }
+void vcvtss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W0 | T_EVEX | T_EW0 | T_ER_X | T_N8, 0x2D); }
+void vcvttpd2dq(const Xmm& x, const Operand& op) { opCvt2(x, op, T_66 | T_0F | T_YMM | T_EVEX |T_EW1 | T_B64 | T_ER_Z, 0xE6); }
+void vcvttps2dq(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_F3 | T_0F | T_EW0 | T_YMM | T_EVEX | T_SAE_Z | T_B32, 0x5B); }
+void vcvttsd2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F2 | T_W0 | T_EVEX | T_EW0 | T_N4 | T_SAE_X, 0x2C); }
+void vcvttss2si(const Reg32& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W0 | T_EVEX | T_EW0 | T_SAE_X | T_N8, 0x2C); }
+void vdivpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x5E); }
+void vdivps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x5E); }
+void vdivsd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F2 | T_EW1 | T_EVEX | T_ER_Z | T_N8, 0x5E); }
+void vdivss(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F3 | T_EW0 | T_EVEX | T_ER_Z | T_N4, 0x5E); }
+void vdppd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W0, 0x41, imm); }
+void vdpps(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W0 | T_YMM, 0x40, imm); }
+void vextractf128(const Operand& op, const Ymm& y, uint8 imm) { if (!(op.isXMEM() && y.isYMM())) throw Error(ERR_BAD_COMBINATION); opVex(y, 0, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x19, imm); }
+void vextracti128(const Operand& op, const Ymm& y, uint8 imm) { if (!(op.isXMEM() && y.isYMM())) throw Error(ERR_BAD_COMBINATION); opVex(y, 0, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x39, imm); }
+void vextractps(const Operand& op, const Xmm& x, uint8 imm) { if (!((op.isREG(32) || op.isMEM()) && x.isXMM())) throw Error(ERR_BAD_COMBINATION); opVex(x, 0, op, T_0F3A | T_66 | T_W0 | T_EVEX | T_N4, 0x17, imm); }
+void vfmadd132pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x98); }
+void vfmadd132ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x98); }
+void vfmadd132sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0x99); }
+void vfmadd132ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0x99); }
+void vfmadd213pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xA8); }
+void vfmadd213ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xA8); }
+void vfmadd213sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0xA9); }
+void vfmadd213ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0xA9); }
+void vfmadd231pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xB8); }
+void vfmadd231ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xB8); }
+void vfmadd231sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0xB9); }
+void vfmadd231ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0xB9); }
+void vfmaddsub132pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x96); }
+void vfmaddsub132ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x96); }
+void vfmaddsub213pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xA6); }
+void vfmaddsub213ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xA6); }
+void vfmaddsub231pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xB6); }
+void vfmaddsub231ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xB6); }
+void vfmsub132pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x9A); }
+void vfmsub132ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x9A); }
+void vfmsub132sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0x9B); }
+void vfmsub132ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0x9B); }
+void vfmsub213pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xAA); }
+void vfmsub213ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xAA); }
+void vfmsub213sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0xAB); }
+void vfmsub213ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0xAB); }
+void vfmsub231pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xBA); }
+void vfmsub231ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xBA); }
+void vfmsub231sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0xBB); }
+void vfmsub231ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0xBB); }
+void vfmsubadd132pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x97); }
+void vfmsubadd132ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x97); }
+void vfmsubadd213pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xA7); }
+void vfmsubadd213ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xA7); }
+void vfmsubadd231pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xB7); }
+void vfmsubadd231ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xB7); }
+void vfnmadd132pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x9C); }
+void vfnmadd132ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x9C); }
+void vfnmadd132sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0x9D); }
+void vfnmadd132ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0x9D); }
+void vfnmadd213pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xAC); }
+void vfnmadd213ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xAC); }
+void vfnmadd213sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0xAD); }
+void vfnmadd213ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0xAD); }
+void vfnmadd231pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xBC); }
+void vfnmadd231ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xBC); }
+void vfnmadd231sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0xBD); }
+void vfnmadd231ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0xBD); }
+void vfnmsub132pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x9E); }
+void vfnmsub132ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x9E); }
+void vfnmsub132sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0x9F); }
+void vfnmsub132ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0x9F); }
+void vfnmsub213pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xAE); }
+void vfnmsub213ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xAE); }
+void vfnmsub213sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0xAF); }
+void vfnmsub213ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0xAF); }
+void vfnmsub231pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0xBE); }
+void vfnmsub231ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0xBE); }
+void vfnmsub231sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_W1 | T_EW1 | T_EVEX | T_ER_X, 0xBF); }
+void vfnmsub231ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_W0 | T_EW0 | T_EVEX | T_ER_X, 0xBF); }
+void vgatherdpd(const Xmm& x1, const Address& addr, const Xmm& x2) { opGather(x1, addr, x2, T_0F38 | T_66 | T_YMM | T_VSIB | T_W1, 0x92, 0); }
+void vgatherdps(const Xmm& x1, const Address& addr, const Xmm& x2) { opGather(x1, addr, x2, T_0F38 | T_66 | T_YMM | T_VSIB | T_W0, 0x92, 1); }
+void vgatherqpd(const Xmm& x1, const Address& addr, const Xmm& x2) { opGather(x1, addr, x2, T_0F38 | T_66 | T_YMM | T_VSIB | T_W1, 0x93, 1); }
+void vgatherqps(const Xmm& x1, const Address& addr, const Xmm& x2) { opGather(x1, addr, x2, T_0F38 | T_66 | T_YMM | T_VSIB | T_W0, 0x93, 2); }
+void vgf2p8affineinvqb(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W1 | T_EW1 | T_YMM | T_EVEX | T_SAE_Z | T_B64, 0xCF, imm); }
+void vgf2p8affineqb(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W1 | T_EW1 | T_YMM | T_EVEX | T_SAE_Z | T_B64, 0xCE, imm); }
+void vgf2p8mulb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_SAE_Z, 0xCF); }
+void vhaddpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_66 | T_0F | T_YMM, 0x7C); }
+void vhaddps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_F2 | T_0F | T_YMM, 0x7C); }
+void vhsubpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_66 | T_0F | T_YMM, 0x7D); }
+void vhsubps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_F2 | T_0F | T_YMM, 0x7D); }
+void vinsertf128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { if (!(y1.isYMM() && y2.isYMM() && op.isXMEM())) throw Error(ERR_BAD_COMBINATION); opVex(y1, &y2, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x18, imm); }
+void vinserti128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { if (!(y1.isYMM() && y2.isYMM() && op.isXMEM())) throw Error(ERR_BAD_COMBINATION); opVex(y1, &y2, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x38, imm); }
+void vinsertps(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F3A | T_W0 | T_EW0 | T_EVEX, 0x21, imm); }
+void vlddqu(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, cvtIdx0(x), addr, T_0F | T_F2 | T_W0 | T_YMM, 0xF0); }
+void vldmxcsr(const Address& addr) { opAVX_X_X_XM(xm2, xm0, addr, T_0F, 0xAE); }
+void vmaskmovdqu(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, T_0F | T_66, 0xF7); }
+void vmaskmovpd(const Address& addr, const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x2, x1, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x2F); }
+void vmaskmovpd(const Xmm& x1, const Xmm& x2, const Address& addr) { opAVX_X_X_XM(x1, x2, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x2D); }
+void vmaskmovps(const Address& addr, const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x2, x1, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x2E); }
+void vmaskmovps(const Xmm& x1, const Xmm& x2, const Address& addr) { opAVX_X_X_XM(x1, x2, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x2C); }
+void vmaxpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x5F); }
+void vmaxps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x5F); }
+void vmaxsd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F2 | T_EW1 | T_EVEX | T_ER_Z | T_N8, 0x5F); }
+void vmaxss(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F3 | T_EW0 | T_EVEX | T_ER_Z | T_N4, 0x5F); }
+void vminpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x5D); }
+void vminps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x5D); }
+void vminsd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F2 | T_EW1 | T_EVEX | T_ER_Z | T_N8, 0x5D); }
+void vminss(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F3 | T_EW0 | T_EVEX | T_ER_Z | T_N4, 0x5D); }
+void vmovapd(const Address& addr, const Xmm& xmm) { opAVX_X_XM_IMM(xmm, addr, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_M_K, 0x29); }
+void vmovapd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX, 0x28); }
+void vmovaps(const Address& addr, const Xmm& xmm) { opAVX_X_XM_IMM(xmm, addr, T_0F | T_EW0 | T_YMM | T_EVEX | T_M_K, 0x29); }
+void vmovaps(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_EW0 | T_YMM | T_EVEX, 0x28); }
+void vmovd(const Operand& op, const Xmm& x) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, xm0, op, T_0F | T_66 | T_W0 | T_EVEX | T_N4, 0x7E); }
+void vmovd(const Xmm& x, const Operand& op) { if (!op.isREG(32) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, xm0, op, T_0F | T_66 | T_W0 | T_EVEX | T_N4, 0x6E); }
+void vmovddup(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_DUP | T_F2 | T_0F | T_EW1 | T_YMM | T_EVEX | T_ER_X | T_ER_Y | T_ER_Z, 0x12); }
+void vmovdqa(const Address& addr, const Xmm& xmm) { opAVX_X_XM_IMM(xmm, addr, T_66 | T_0F | T_YMM, 0x7F); }
+void vmovdqa(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F | T_YMM, 0x6F); }
+void vmovdqu(const Address& addr, const Xmm& xmm) { opAVX_X_XM_IMM(xmm, addr, T_F3 | T_0F | T_YMM, 0x7F); }
+void vmovdqu(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_F3 | T_0F | T_YMM, 0x6F); }
+void vmovhlps(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, T_0F | T_EVEX | T_EW0, 0x12); }
+void vmovhpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_66 | T_EVEX | T_EW1 | T_N8, 0x17); }
+void vmovhpd(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, op1, op2, T_0F | T_66 | T_EVEX | T_EW1 | T_N8, 0x16); }
+void vmovhps(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_EVEX | T_EW0 | T_N8, 0x17); }
+void vmovhps(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, op1, op2, T_0F | T_EVEX | T_EW0 | T_N8, 0x16); }
+void vmovlhps(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, T_0F | T_EVEX | T_EW0, 0x16); }
+void vmovlpd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_66 | T_EVEX | T_EW1 | T_N8, 0x13); }
+void vmovlpd(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, op1, op2, T_0F | T_66 | T_EVEX | T_EW1 | T_N8, 0x12); }
+void vmovlps(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_EVEX | T_EW0 | T_N8, 0x13); }
+void vmovlps(const Xmm& x, const Operand& op1, const Operand& op2 = Operand()) { if (!op2.isNone() && !op2.isMEM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x, op1, op2, T_0F | T_EVEX | T_EW0 | T_N8, 0x12); }
+void vmovmskpd(const Reg& r, const Xmm& x) { if (!r.isBit(i32e)) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x.isXMM() ? Xmm(r.getIdx()) : Ymm(r.getIdx()), cvtIdx0(x), x, T_0F | T_66 | T_W0 | T_YMM, 0x50); }
+void vmovmskps(const Reg& r, const Xmm& x) { if (!r.isBit(i32e)) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x.isXMM() ? Xmm(r.getIdx()) : Ymm(r.getIdx()), cvtIdx0(x), x, T_0F | T_W0 | T_YMM, 0x50); }
+void vmovntdq(const Address& addr, const Xmm& x) { opVex(x, 0, addr, T_0F | T_66 | T_YMM | T_EVEX | T_EW0, 0xE7); }
+void vmovntdqa(const Xmm& x, const Address& addr) { opVex(x, 0, addr, T_0F38 | T_66 | T_YMM | T_EVEX | T_EW0, 0x2A); }
+void vmovntpd(const Address& addr, const Xmm& x) { opVex(x, 0, addr, T_0F | T_66 | T_YMM | T_EVEX | T_EW1, 0x2B); }
+void vmovntps(const Address& addr, const Xmm& x) { opVex(x, 0, addr, T_0F | T_YMM | T_EVEX | T_EW0, 0x2B); }
+void vmovq(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_0F | T_66 | T_EVEX | T_EW1 | T_N8, x.getIdx() < 16 ? 0xD6 : 0x7E); }
+void vmovq(const Xmm& x, const Address& addr) { int type, code; if (x.getIdx() < 16) { type = T_0F | T_F3; code = 0x7E; } else { type = T_0F | T_66 | T_EVEX | T_EW1 | T_N8; code = 0x6E; } opAVX_X_X_XM(x, xm0, addr, type, code); }
+void vmovq(const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x1, xm0, x2, T_0F | T_F3 | T_EVEX | T_EW1 | T_N8, 0x7E); }
+void vmovsd(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_N8 | T_F2 | T_0F | T_EW1 | T_EVEX | T_M_K, 0x11); }
+void vmovsd(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, T_N8 | T_F2 | T_0F | T_EW1 | T_EVEX, 0x10); }
+void vmovsd(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, T_N8 | T_F2 | T_0F | T_EW1 | T_EVEX, 0x10); }
+void vmovshdup(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_F3 | T_0F | T_EW0 | T_YMM | T_EVEX, 0x16); }
+void vmovsldup(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_F3 | T_0F | T_EW0 | T_YMM | T_EVEX, 0x12); }
+void vmovss(const Address& addr, const Xmm& x) { opAVX_X_X_XM(x, xm0, addr, T_N4 | T_F3 | T_0F | T_EW0 | T_EVEX | T_M_K, 0x11); }
+void vmovss(const Xmm& x, const Address& addr) { opAVX_X_X_XM(x, xm0, addr, T_N4 | T_F3 | T_0F | T_EW0 | T_EVEX, 0x10); }
+void vmovss(const Xmm& x1, const Xmm& x2, const Operand& op = Operand()) { if (!op.isNone() && !op.isXMM()) throw Error(ERR_BAD_COMBINATION); opAVX_X_X_XM(x1, x2, op, T_N4 | T_F3 | T_0F | T_EW0 | T_EVEX, 0x10); }
+void vmovupd(const Address& addr, const Xmm& xmm) { opAVX_X_XM_IMM(xmm, addr, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_M_K, 0x11); }
+void vmovupd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX, 0x10); }
+void vmovups(const Address& addr, const Xmm& xmm) { opAVX_X_XM_IMM(xmm, addr, T_0F | T_EW0 | T_YMM | T_EVEX | T_M_K, 0x11); }
+void vmovups(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_EW0 | T_YMM | T_EVEX, 0x10); }
+void vmpsadbw(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W0 | T_YMM, 0x42, imm); }
+void vmulpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x59); }
+void vmulps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x59); }
+void vmulsd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F2 | T_EW1 | T_EVEX | T_ER_Z | T_N8, 0x59); }
+void vmulss(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F3 | T_EW0 | T_EVEX | T_ER_Z | T_N4, 0x59); }
+void vorpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x56); }
+void vorps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x56); }
+void vpabsb(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F38 | T_YMM | T_EVEX, 0x1C); }
+void vpabsd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x1E); }
+void vpabsw(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F38 | T_YMM | T_EVEX, 0x1D); }
+void vpackssdw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW0 | T_YMM | T_EVEX | T_B32, 0x6B); }
+void vpacksswb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0x63); }
+void vpackusdw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x2B); }
+void vpackuswb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0x67); }
+void vpaddb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xFC); }
+void vpaddd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW0 | T_YMM | T_EVEX | T_B32, 0xFE); }
+void vpaddq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_B64, 0xD4); }
+void vpaddsb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xEC); }
+void vpaddsw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xED); }
+void vpaddusb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xDC); }
+void vpaddusw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xDD); }
+void vpaddw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xFD); }
+void vpalignr(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_YMM | T_EVEX, 0x0F, imm); }
+void vpand(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM, 0xDB); }
+void vpandn(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM, 0xDF); }
+void vpavgb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xE0); }
+void vpavgw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xE3); }
+void vpblendd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W0 | T_YMM, 0x02, imm); }
+void vpblendvb(const Xmm& x1, const Xmm& x2, const Operand& op, const Xmm& x4) { opAVX_X_X_XM(x1, x2, op, T_0F3A | T_66 | T_YMM, 0x4C, x4.getIdx() << 4); }
+void vpblendw(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W0 | T_YMM, 0x0E, imm); }
+void vpbroadcastb(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(x, op, T_N1 | T_66 | T_0F38 | T_W0 | T_YMM | T_EVEX, 0x78); }
+void vpbroadcastd(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(x, op, T_N4 | T_66 | T_0F38 | T_W0 | T_YMM | T_EVEX, 0x58); }
+void vpbroadcastq(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(x, op, T_N8 | T_66 | T_0F38 | T_W0 | T_EW1 | T_YMM | T_EVEX, 0x59); }
+void vpbroadcastw(const Xmm& x, const Operand& op) { if (!(op.isXMM() || op.isMEM())) throw Error(ERR_BAD_COMBINATION); opAVX_X_XM_IMM(x, op, T_N2 | T_66 | T_0F38 | T_W0 | T_YMM | T_EVEX, 0x79); }
+void vpclmulqdq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W0 | T_YMM | T_EVEX, 0x44, imm); }
+void vpcmpeqb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM, 0x74); }
+void vpcmpeqd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM, 0x76); }
+void vpcmpeqq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM, 0x29); }
+void vpcmpeqw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM, 0x75); }
+void vpcmpestri(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F3A, 0x61, imm); }
+void vpcmpestrm(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F3A, 0x60, imm); }
+void vpcmpgtb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM, 0x64); }
+void vpcmpgtd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM, 0x66); }
+void vpcmpgtq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM, 0x37); }
+void vpcmpgtw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM, 0x65); }
+void vpcmpistri(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F3A, 0x63, imm); }
+void vpcmpistrm(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F3A, 0x62, imm); }
+void vperm2f128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { if (!(y1.isYMM() && y2.isYMM() && op.isYMEM())) throw Error(ERR_BAD_COMBINATION); opVex(y1, &y2, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x06, imm); }
+void vperm2i128(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { if (!(y1.isYMM() && y2.isYMM() && op.isYMEM())) throw Error(ERR_BAD_COMBINATION); opVex(y1, &y2, op, T_0F3A | T_66 | T_W0 | T_YMM, 0x46, imm); }
+void vpermd(const Ymm& y1, const Ymm& y2, const Operand& op) { opAVX_X_X_XM(y1, y2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x36); }
+void vpermilpd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x0D); }
+void vpermilpd(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_EVEX | T_B64, 0x05, imm); }
+void vpermilps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x0C); }
+void vpermilps(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_EVEX | T_B32, 0x04, imm); }
+void vpermpd(const Ymm& y, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(y, op, T_66 | T_0F3A | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x01, imm); }
+void vpermpd(const Ymm& y1, const Ymm& y2, const Operand& op) { opAVX_X_X_XM(y1, y2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x16); }
+void vpermps(const Ymm& y1, const Ymm& y2, const Operand& op) { opAVX_X_X_XM(y1, y2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x16); }
+void vpermq(const Ymm& y, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(y, op, T_66 | T_0F3A | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x00, imm); }
+void vpermq(const Ymm& y1, const Ymm& y2, const Operand& op) { opAVX_X_X_XM(y1, y2, op, T_66 | T_0F38 | T_W0 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x36); }
+void vpextrb(const Operand& op, const Xmm& x, uint8 imm) { if (!((op.isREG(8|16|i32e) || op.isMEM()) && x.isXMM())) throw Error(ERR_BAD_COMBINATION); opVex(x, 0, op, T_0F3A | T_66 | T_EVEX | T_N1, 0x14, imm); }
+void vpextrd(const Operand& op, const Xmm& x, uint8 imm) { if (!((op.isREG(32) || op.isMEM()) && x.isXMM())) throw Error(ERR_BAD_COMBINATION); opVex(x, 0, op, T_0F3A | T_66 | T_W0 | T_EVEX | T_EW0 | T_N4, 0x16, imm); }
+void vpextrq(const Operand& op, const Xmm& x, uint8 imm) { if (!((op.isREG(64) || op.isMEM()) && x.isXMM())) throw Error(ERR_BAD_COMBINATION); opVex(x, 0, op, T_0F3A | T_66 | T_W1 | T_EVEX | T_EW1 | T_N8, 0x16, imm); }
+void vpextrw(const Operand& op, const Xmm& x, uint8 imm) { if (!((op.isREG(16|i32e) || op.isMEM()) && x.isXMM())) throw Error(ERR_BAD_COMBINATION); if (op.isREG() && x.getIdx() < 16) { opAVX_X_X_XM(Xmm(op.getIdx()), xm0, x, T_0F | T_66, 0xC5, imm); } else { opVex(x, 0, op, T_0F3A | T_66 | T_EVEX | T_N2, 0x15, imm); } }
+void vpgatherdd(const Xmm& x1, const Address& addr, const Xmm& x2) { opGather(x1, addr, x2, T_0F38 | T_66 | T_YMM | T_VSIB | T_W0, 0x90, 1); }
+void vpgatherdq(const Xmm& x1, const Address& addr, const Xmm& x2) { opGather(x1, addr, x2, T_0F38 | T_66 | T_YMM | T_VSIB | T_W1, 0x90, 0); }
+void vpgatherqd(const Xmm& x1, const Address& addr, const Xmm& x2) { opGather(x1, addr, x2, T_0F38 | T_66 | T_YMM | T_VSIB | T_W0, 0x91, 2); }
+void vpgatherqq(const Xmm& x1, const Address& addr, const Xmm& x2) { opGather(x1, addr, x2, T_0F38 | T_66 | T_YMM | T_VSIB | T_W1, 0x91, 1); }
+void vphaddd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM, 0x02); }
+void vphaddsw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM, 0x03); }
+void vphaddw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM, 0x01); }
+void vphminposuw(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F38, 0x41); }
+void vphsubd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM, 0x06); }
+void vphsubsw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM, 0x07); }
+void vphsubw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM, 0x05); }
+void vpinsrb(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!(x1.isXMM() && x2.isXMM() && (op.isREG(32) || op.isMEM()))) throw Error(ERR_BAD_COMBINATION); opVex(x1, &x2, op, T_0F3A | T_66 | T_EVEX | T_N1, 0x20, imm); }
+void vpinsrd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!(x1.isXMM() && x2.isXMM() && (op.isREG(32) || op.isMEM()))) throw Error(ERR_BAD_COMBINATION); opVex(x1, &x2, op, T_0F3A | T_66 | T_W0 | T_EVEX | T_EW0 | T_N4, 0x22, imm); }
+void vpinsrq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!(x1.isXMM() && x2.isXMM() && (op.isREG(64) || op.isMEM()))) throw Error(ERR_BAD_COMBINATION); opVex(x1, &x2, op, T_0F3A | T_66 | T_W1 | T_EVEX | T_EW1 | T_N8, 0x22, imm); }
+void vpinsrw(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { if (!(x1.isXMM() && x2.isXMM() && (op.isREG(32) || op.isMEM()))) throw Error(ERR_BAD_COMBINATION); opVex(x1, &x2, op, T_0F | T_66 | T_EVEX | T_N2, 0xC4, imm); }
+void vpmaddubsw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM | T_EVEX, 0x04); }
+void vpmaddwd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xF5); }
+void vpmaskmovd(const Address& addr, const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x2, x1, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x8E); }
+void vpmaskmovd(const Xmm& x1, const Xmm& x2, const Address& addr) { opAVX_X_X_XM(x1, x2, addr, T_0F38 | T_66 | T_W0 | T_YMM, 0x8C); }
+void vpmaskmovq(const Address& addr, const Xmm& x1, const Xmm& x2) { opAVX_X_X_XM(x2, x1, addr, T_0F38 | T_66 | T_W1 | T_YMM, 0x8E); }
+void vpmaskmovq(const Xmm& x1, const Xmm& x2, const Address& addr) { opAVX_X_X_XM(x1, x2, addr, T_0F38 | T_66 | T_W1 | T_YMM, 0x8C); }
+void vpmaxsb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM | T_EVEX, 0x3C); }
+void vpmaxsd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x3D); }
+void vpmaxsw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xEE); }
+void vpmaxub(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xDE); }
+void vpmaxud(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x3F); }
+void vpmaxuw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM | T_EVEX, 0x3E); }
+void vpminsb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM | T_EVEX, 0x38); }
+void vpminsd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x39); }
+void vpminsw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xEA); }
+void vpminub(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xDA); }
+void vpminud(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x3B); }
+void vpminuw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM | T_EVEX, 0x3A); }
+void vpmovmskb(const Reg32e& r, const Xmm& x) { if (!x.is(Operand::XMM | Operand::YMM)) throw Error(ERR_BAD_COMBINATION); opVex(x.isYMM() ? Ymm(r.getIdx()) : Xmm(r.getIdx()), 0, x, T_0F | T_66 | T_YMM, 0xD7); }
+void vpmovsxbd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N4 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x21); }
+void vpmovsxbq(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N2 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x22); }
+void vpmovsxbw(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N8 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x20); }
+void vpmovsxdq(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N8 | T_N_VL | T_66 | T_0F38 | T_EW0 | T_YMM | T_EVEX, 0x25); }
+void vpmovsxwd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N8 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x23); }
+void vpmovsxwq(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N4 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x24); }
+void vpmovzxbd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N4 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x31); }
+void vpmovzxbq(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N2 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x32); }
+void vpmovzxbw(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N8 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x30); }
+void vpmovzxdq(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N8 | T_N_VL | T_66 | T_0F38 | T_EW0 | T_YMM | T_EVEX, 0x35); }
+void vpmovzxwd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N8 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x33); }
+void vpmovzxwq(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N4 | T_N_VL | T_66 | T_0F38 | T_YMM | T_EVEX, 0x34); }
+void vpmuldq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x28); }
+void vpmulhrsw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM | T_EVEX, 0x0B); }
+void vpmulhuw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xE4); }
+void vpmulhw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xE5); }
+void vpmulld(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x40); }
+void vpmullw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xD5); }
+void vpmuludq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_B64, 0xF4); }
+void vpor(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM, 0xEB); }
+void vpsadbw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xF6); }
+void vpshufb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM | T_EVEX, 0x00); }
+void vpshufd(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F | T_EW0 | T_YMM | T_EVEX | T_B32, 0x70, imm); }
+void vpshufhw(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_F3 | T_0F | T_YMM | T_EVEX, 0x70, imm); }
+void vpshuflw(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_F2 | T_0F | T_YMM | T_EVEX, 0x70, imm); }
+void vpsignb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM, 0x08); }
+void vpsignd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM, 0x0A); }
+void vpsignw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_YMM, 0x09); }
+void vpslld(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 6), x, op, T_66 | T_0F | T_EW0 | T_YMM | T_EVEX | T_B32 | T_MEM_EVEX, 0x72, imm); }
+void vpslld(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N16 | T_66 | T_0F | T_EW0 | T_YMM | T_EVEX, 0xF2); }
+void vpslldq(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 7), x, op, T_66 | T_0F | T_YMM | T_EVEX | T_MEM_EVEX, 0x73, imm); }
+void vpsllq(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 6), x, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_B64 | T_MEM_EVEX, 0x73, imm); }
+void vpsllq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N16 | T_66 | T_0F | T_EW1 | T_YMM | T_EVEX, 0xF3); }
+void vpsllvd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x47); }
+void vpsllvq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x47); }
+void vpsllw(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 6), x, op, T_66 | T_0F | T_YMM | T_EVEX | T_MEM_EVEX, 0x71, imm); }
+void vpsllw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N16 | T_66 | T_0F | T_YMM | T_EVEX, 0xF1); }
+void vpsrad(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 4), x, op, T_66 | T_0F | T_EW0 | T_YMM | T_EVEX | T_B32 | T_MEM_EVEX, 0x72, imm); }
+void vpsrad(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N16 | T_66 | T_0F | T_EW0 | T_YMM | T_EVEX, 0xE2); }
+void vpsravd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x46); }
+void vpsraw(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 4), x, op, T_66 | T_0F | T_YMM | T_EVEX | T_MEM_EVEX, 0x71, imm); }
+void vpsraw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N16 | T_66 | T_0F | T_YMM | T_EVEX, 0xE1); }
+void vpsrld(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 2), x, op, T_66 | T_0F | T_EW0 | T_YMM | T_EVEX | T_B32 | T_MEM_EVEX, 0x72, imm); }
+void vpsrld(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N16 | T_66 | T_0F | T_EW0 | T_YMM | T_EVEX, 0xD2); }
+void vpsrldq(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 3), x, op, T_66 | T_0F | T_YMM | T_EVEX | T_MEM_EVEX, 0x73, imm); }
+void vpsrlq(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 2), x, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_B64 | T_MEM_EVEX, 0x73, imm); }
+void vpsrlq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N16 | T_66 | T_0F | T_EW1 | T_YMM | T_EVEX, 0xD3); }
+void vpsrlvd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W0 | T_EW0 | T_YMM | T_EVEX | T_B32, 0x45); }
+void vpsrlvq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_W1 | T_EW1 | T_YMM | T_EVEX | T_B64, 0x45); }
+void vpsrlw(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 2), x, op, T_66 | T_0F | T_YMM | T_EVEX | T_MEM_EVEX, 0x71, imm); }
+void vpsrlw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N16 | T_66 | T_0F | T_YMM | T_EVEX, 0xD1); }
+void vpsubb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xF8); }
+void vpsubd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW0 | T_YMM | T_EVEX | T_B32, 0xFA); }
+void vpsubq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_B64, 0xFB); }
+void vpsubsb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xE8); }
+void vpsubsw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xE9); }
+void vpsubusb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xD8); }
+void vpsubusw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xD9); }
+void vpsubw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0xF9); }
+void vptest(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F38 | T_YMM, 0x17); }
+void vpunpckhbw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0x68); }
+void vpunpckhdq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW0 | T_YMM | T_EVEX | T_B32, 0x6A); }
+void vpunpckhqdq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_B64, 0x6D); }
+void vpunpckhwd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0x69); }
+void vpunpcklbw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0x60); }
+void vpunpckldq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW0 | T_YMM | T_EVEX | T_B32, 0x62); }
+void vpunpcklqdq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_B64, 0x6C); }
+void vpunpcklwd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM | T_EVEX, 0x61); }
+void vpxor(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_YMM, 0xEF); }
+void vrcpps(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_YMM, 0x53); }
+void vrcpss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_F3 | T_0F, 0x53); }
+void vroundpd(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F3A | T_YMM, 0x09, imm); }
+void vroundps(const Xmm& xm, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F3A | T_YMM, 0x08, imm); }
+void vroundsd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W0, 0x0B, imm); }
+void vroundss(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_W0, 0x0A, imm); }
+void vrsqrtps(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_YMM, 0x52); }
+void vrsqrtss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_F3 | T_0F, 0x52); }
+void vshufpd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_B64, 0xC6, imm); }
+void vshufps(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_0F | T_EW0 | T_YMM | T_EVEX | T_B32, 0xC6, imm); }
+void vsqrtpd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x51); }
+void vsqrtps(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x51); }
+void vsqrtsd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_F2 | T_0F | T_EW1 | T_EVEX | T_ER_X, 0x51); }
+void vsqrtss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_F3 | T_0F | T_EW0 | T_EVEX | T_ER_X, 0x51); }
+void vstmxcsr(const Address& addr) { opAVX_X_X_XM(xm3, xm0, addr, T_0F, 0xAE); }
+void vsubpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x5C); }
+void vsubps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x5C); }
+void vsubsd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F2 | T_EW1 | T_EVEX | T_ER_Z | T_N8, 0x5C); }
+void vsubss(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_F3 | T_EW0 | T_EVEX | T_ER_Z | T_N4, 0x5C); }
+void vtestpd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F38 | T_YMM, 0x0F); }
+void vtestps(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_66 | T_0F38 | T_YMM, 0x0E); }
+void vucomisd(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N8 | T_66 | T_0F | T_EW1 | T_EVEX | T_SAE_X, 0x2E); }
+void vucomiss(const Xmm& xm, const Operand& op) { opAVX_X_XM_IMM(xm, op, T_N4 | T_0F | T_EW0 | T_EVEX | T_SAE_X, 0x2E); }
+void vunpckhpd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_B64, 0x15); }
+void vunpckhps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_0F | T_EW0 | T_YMM | T_EVEX | T_B32, 0x15); }
+void vunpcklpd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_EVEX | T_B64, 0x14); }
+void vunpcklps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_0F | T_EW0 | T_YMM | T_EVEX | T_B32, 0x14); }
+void vxorpd(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_66 | T_EW1 | T_YMM | T_EVEX | T_ER_Z | T_B64, 0x57); }
+void vxorps(const Xmm& xmm, const Operand& op1, const Operand& op2 = Operand()) { opAVX_X_X_XM(xmm, op1, op2, T_0F | T_EW0 | T_YMM | T_EVEX | T_ER_Z | T_B32, 0x57); }
+void vzeroall() { db(0xC5); db(0xFC); db(0x77); }
+void vzeroupper() { db(0xC5); db(0xF8); db(0x77); }
+void wait() { db(0x9B); }
+void wbinvd() { db(0x0F); db(0x09); }
+void wrmsr() { db(0x0F); db(0x30); }
+void xadd(const Operand& op, const Reg& reg) { opModRM(reg, op, (op.isREG() && reg.isREG() && op.getBit() == reg.getBit()), op.isMEM(), 0x0F, 0xC0 | (reg.isBit(8) ? 0 : 1)); }
+void xgetbv() { db(0x0F); db(0x01); db(0xD0); }
+void xlatb() { db(0xD7); }
+void xor_(const Operand& op, uint32 imm) { opRM_I(op, imm, 0x30, 6); }
+void xor_(const Operand& op1, const Operand& op2) { opRM_RM(op1, op2, 0x30); }
+void xorpd(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x57, 0x66, isXMM_XMMorMEM); }
+void xorps(const Xmm& xmm, const Operand& op) { opGen(xmm, op, 0x57, 0x100, isXMM_XMMorMEM); }
+#ifdef XBYAK_ENABLE_OMITTED_OPERAND
+void vblendpd(const Xmm& x, const Operand& op, uint8 imm) { vblendpd(x, x, op, imm); }
+void vblendps(const Xmm& x, const Operand& op, uint8 imm) { vblendps(x, x, op, imm); }
+void vblendvpd(const Xmm& x1, const Operand& op, const Xmm& x4) { vblendvpd(x1, x1, op, x4); }
+void vblendvps(const Xmm& x1, const Operand& op, const Xmm& x4) { vblendvps(x1, x1, op, x4); }
+void vcmpeq_ospd(const Xmm& x, const Operand& op) { vcmpeq_ospd(x, x, op); }
+void vcmpeq_osps(const Xmm& x, const Operand& op) { vcmpeq_osps(x, x, op); }
+void vcmpeq_ossd(const Xmm& x, const Operand& op) { vcmpeq_ossd(x, x, op); }
+void vcmpeq_osss(const Xmm& x, const Operand& op) { vcmpeq_osss(x, x, op); }
+void vcmpeq_uqpd(const Xmm& x, const Operand& op) { vcmpeq_uqpd(x, x, op); }
+void vcmpeq_uqps(const Xmm& x, const Operand& op) { vcmpeq_uqps(x, x, op); }
+void vcmpeq_uqsd(const Xmm& x, const Operand& op) { vcmpeq_uqsd(x, x, op); }
+void vcmpeq_uqss(const Xmm& x, const Operand& op) { vcmpeq_uqss(x, x, op); }
+void vcmpeq_uspd(const Xmm& x, const Operand& op) { vcmpeq_uspd(x, x, op); }
+void vcmpeq_usps(const Xmm& x, const Operand& op) { vcmpeq_usps(x, x, op); }
+void vcmpeq_ussd(const Xmm& x, const Operand& op) { vcmpeq_ussd(x, x, op); }
+void vcmpeq_usss(const Xmm& x, const Operand& op) { vcmpeq_usss(x, x, op); }
+void vcmpeqpd(const Xmm& x, const Operand& op) { vcmpeqpd(x, x, op); }
+void vcmpeqps(const Xmm& x, const Operand& op) { vcmpeqps(x, x, op); }
+void vcmpeqsd(const Xmm& x, const Operand& op) { vcmpeqsd(x, x, op); }
+void vcmpeqss(const Xmm& x, const Operand& op) { vcmpeqss(x, x, op); }
+void vcmpfalse_ospd(const Xmm& x, const Operand& op) { vcmpfalse_ospd(x, x, op); }
+void vcmpfalse_osps(const Xmm& x, const Operand& op) { vcmpfalse_osps(x, x, op); }
+void vcmpfalse_ossd(const Xmm& x, const Operand& op) { vcmpfalse_ossd(x, x, op); }
+void vcmpfalse_osss(const Xmm& x, const Operand& op) { vcmpfalse_osss(x, x, op); }
+void vcmpfalsepd(const Xmm& x, const Operand& op) { vcmpfalsepd(x, x, op); }
+void vcmpfalseps(const Xmm& x, const Operand& op) { vcmpfalseps(x, x, op); }
+void vcmpfalsesd(const Xmm& x, const Operand& op) { vcmpfalsesd(x, x, op); }
+void vcmpfalsess(const Xmm& x, const Operand& op) { vcmpfalsess(x, x, op); }
+void vcmpge_oqpd(const Xmm& x, const Operand& op) { vcmpge_oqpd(x, x, op); }
+void vcmpge_oqps(const Xmm& x, const Operand& op) { vcmpge_oqps(x, x, op); }
+void vcmpge_oqsd(const Xmm& x, const Operand& op) { vcmpge_oqsd(x, x, op); }
+void vcmpge_oqss(const Xmm& x, const Operand& op) { vcmpge_oqss(x, x, op); }
+void vcmpgepd(const Xmm& x, const Operand& op) { vcmpgepd(x, x, op); }
+void vcmpgeps(const Xmm& x, const Operand& op) { vcmpgeps(x, x, op); }
+void vcmpgesd(const Xmm& x, const Operand& op) { vcmpgesd(x, x, op); }
+void vcmpgess(const Xmm& x, const Operand& op) { vcmpgess(x, x, op); }
+void vcmpgt_oqpd(const Xmm& x, const Operand& op) { vcmpgt_oqpd(x, x, op); }
+void vcmpgt_oqps(const Xmm& x, const Operand& op) { vcmpgt_oqps(x, x, op); }
+void vcmpgt_oqsd(const Xmm& x, const Operand& op) { vcmpgt_oqsd(x, x, op); }
+void vcmpgt_oqss(const Xmm& x, const Operand& op) { vcmpgt_oqss(x, x, op); }
+void vcmpgtpd(const Xmm& x, const Operand& op) { vcmpgtpd(x, x, op); }
+void vcmpgtps(const Xmm& x, const Operand& op) { vcmpgtps(x, x, op); }
+void vcmpgtsd(const Xmm& x, const Operand& op) { vcmpgtsd(x, x, op); }
+void vcmpgtss(const Xmm& x, const Operand& op) { vcmpgtss(x, x, op); }
+void vcmple_oqpd(const Xmm& x, const Operand& op) { vcmple_oqpd(x, x, op); }
+void vcmple_oqps(const Xmm& x, const Operand& op) { vcmple_oqps(x, x, op); }
+void vcmple_oqsd(const Xmm& x, const Operand& op) { vcmple_oqsd(x, x, op); }
+void vcmple_oqss(const Xmm& x, const Operand& op) { vcmple_oqss(x, x, op); }
+void vcmplepd(const Xmm& x, const Operand& op) { vcmplepd(x, x, op); }
+void vcmpleps(const Xmm& x, const Operand& op) { vcmpleps(x, x, op); }
+void vcmplesd(const Xmm& x, const Operand& op) { vcmplesd(x, x, op); }
+void vcmpless(const Xmm& x, const Operand& op) { vcmpless(x, x, op); }
+void vcmplt_oqpd(const Xmm& x, const Operand& op) { vcmplt_oqpd(x, x, op); }
+void vcmplt_oqps(const Xmm& x, const Operand& op) { vcmplt_oqps(x, x, op); }
+void vcmplt_oqsd(const Xmm& x, const Operand& op) { vcmplt_oqsd(x, x, op); }
+void vcmplt_oqss(const Xmm& x, const Operand& op) { vcmplt_oqss(x, x, op); }
+void vcmpltpd(const Xmm& x, const Operand& op) { vcmpltpd(x, x, op); }
+void vcmpltps(const Xmm& x, const Operand& op) { vcmpltps(x, x, op); }
+void vcmpltsd(const Xmm& x, const Operand& op) { vcmpltsd(x, x, op); }
+void vcmpltss(const Xmm& x, const Operand& op) { vcmpltss(x, x, op); }
+void vcmpneq_oqpd(const Xmm& x, const Operand& op) { vcmpneq_oqpd(x, x, op); }
+void vcmpneq_oqps(const Xmm& x, const Operand& op) { vcmpneq_oqps(x, x, op); }
+void vcmpneq_oqsd(const Xmm& x, const Operand& op) { vcmpneq_oqsd(x, x, op); }
+void vcmpneq_oqss(const Xmm& x, const Operand& op) { vcmpneq_oqss(x, x, op); }
+void vcmpneq_ospd(const Xmm& x, const Operand& op) { vcmpneq_ospd(x, x, op); }
+void vcmpneq_osps(const Xmm& x, const Operand& op) { vcmpneq_osps(x, x, op); }
+void vcmpneq_ossd(const Xmm& x, const Operand& op) { vcmpneq_ossd(x, x, op); }
+void vcmpneq_osss(const Xmm& x, const Operand& op) { vcmpneq_osss(x, x, op); }
+void vcmpneq_uspd(const Xmm& x, const Operand& op) { vcmpneq_uspd(x, x, op); }
+void vcmpneq_usps(const Xmm& x, const Operand& op) { vcmpneq_usps(x, x, op); }
+void vcmpneq_ussd(const Xmm& x, const Operand& op) { vcmpneq_ussd(x, x, op); }
+void vcmpneq_usss(const Xmm& x, const Operand& op) { vcmpneq_usss(x, x, op); }
+void vcmpneqpd(const Xmm& x, const Operand& op) { vcmpneqpd(x, x, op); }
+void vcmpneqps(const Xmm& x, const Operand& op) { vcmpneqps(x, x, op); }
+void vcmpneqsd(const Xmm& x, const Operand& op) { vcmpneqsd(x, x, op); }
+void vcmpneqss(const Xmm& x, const Operand& op) { vcmpneqss(x, x, op); }
+void vcmpnge_uqpd(const Xmm& x, const Operand& op) { vcmpnge_uqpd(x, x, op); }
+void vcmpnge_uqps(const Xmm& x, const Operand& op) { vcmpnge_uqps(x, x, op); }
+void vcmpnge_uqsd(const Xmm& x, const Operand& op) { vcmpnge_uqsd(x, x, op); }
+void vcmpnge_uqss(const Xmm& x, const Operand& op) { vcmpnge_uqss(x, x, op); }
+void vcmpngepd(const Xmm& x, const Operand& op) { vcmpngepd(x, x, op); }
+void vcmpngeps(const Xmm& x, const Operand& op) { vcmpngeps(x, x, op); }
+void vcmpngesd(const Xmm& x, const Operand& op) { vcmpngesd(x, x, op); }
+void vcmpngess(const Xmm& x, const Operand& op) { vcmpngess(x, x, op); }
+void vcmpngt_uqpd(const Xmm& x, const Operand& op) { vcmpngt_uqpd(x, x, op); }
+void vcmpngt_uqps(const Xmm& x, const Operand& op) { vcmpngt_uqps(x, x, op); }
+void vcmpngt_uqsd(const Xmm& x, const Operand& op) { vcmpngt_uqsd(x, x, op); }
+void vcmpngt_uqss(const Xmm& x, const Operand& op) { vcmpngt_uqss(x, x, op); }
+void vcmpngtpd(const Xmm& x, const Operand& op) { vcmpngtpd(x, x, op); }
+void vcmpngtps(const Xmm& x, const Operand& op) { vcmpngtps(x, x, op); }
+void vcmpngtsd(const Xmm& x, const Operand& op) { vcmpngtsd(x, x, op); }
+void vcmpngtss(const Xmm& x, const Operand& op) { vcmpngtss(x, x, op); }
+void vcmpnle_uqpd(const Xmm& x, const Operand& op) { vcmpnle_uqpd(x, x, op); }
+void vcmpnle_uqps(const Xmm& x, const Operand& op) { vcmpnle_uqps(x, x, op); }
+void vcmpnle_uqsd(const Xmm& x, const Operand& op) { vcmpnle_uqsd(x, x, op); }
+void vcmpnle_uqss(const Xmm& x, const Operand& op) { vcmpnle_uqss(x, x, op); }
+void vcmpnlepd(const Xmm& x, const Operand& op) { vcmpnlepd(x, x, op); }
+void vcmpnleps(const Xmm& x, const Operand& op) { vcmpnleps(x, x, op); }
+void vcmpnlesd(const Xmm& x, const Operand& op) { vcmpnlesd(x, x, op); }
+void vcmpnless(const Xmm& x, const Operand& op) { vcmpnless(x, x, op); }
+void vcmpnlt_uqpd(const Xmm& x, const Operand& op) { vcmpnlt_uqpd(x, x, op); }
+void vcmpnlt_uqps(const Xmm& x, const Operand& op) { vcmpnlt_uqps(x, x, op); }
+void vcmpnlt_uqsd(const Xmm& x, const Operand& op) { vcmpnlt_uqsd(x, x, op); }
+void vcmpnlt_uqss(const Xmm& x, const Operand& op) { vcmpnlt_uqss(x, x, op); }
+void vcmpnltpd(const Xmm& x, const Operand& op) { vcmpnltpd(x, x, op); }
+void vcmpnltps(const Xmm& x, const Operand& op) { vcmpnltps(x, x, op); }
+void vcmpnltsd(const Xmm& x, const Operand& op) { vcmpnltsd(x, x, op); }
+void vcmpnltss(const Xmm& x, const Operand& op) { vcmpnltss(x, x, op); }
+void vcmpord_spd(const Xmm& x, const Operand& op) { vcmpord_spd(x, x, op); }
+void vcmpord_sps(const Xmm& x, const Operand& op) { vcmpord_sps(x, x, op); }
+void vcmpord_ssd(const Xmm& x, const Operand& op) { vcmpord_ssd(x, x, op); }
+void vcmpord_sss(const Xmm& x, const Operand& op) { vcmpord_sss(x, x, op); }
+void vcmpordpd(const Xmm& x, const Operand& op) { vcmpordpd(x, x, op); }
+void vcmpordps(const Xmm& x, const Operand& op) { vcmpordps(x, x, op); }
+void vcmpordsd(const Xmm& x, const Operand& op) { vcmpordsd(x, x, op); }
+void vcmpordss(const Xmm& x, const Operand& op) { vcmpordss(x, x, op); }
+void vcmppd(const Xmm& x, const Operand& op, uint8 imm) { vcmppd(x, x, op, imm); }
+void vcmpps(const Xmm& x, const Operand& op, uint8 imm) { vcmpps(x, x, op, imm); }
+void vcmpsd(const Xmm& x, const Operand& op, uint8 imm) { vcmpsd(x, x, op, imm); }
+void vcmpss(const Xmm& x, const Operand& op, uint8 imm) { vcmpss(x, x, op, imm); }
+void vcmptrue_uspd(const Xmm& x, const Operand& op) { vcmptrue_uspd(x, x, op); }
+void vcmptrue_usps(const Xmm& x, const Operand& op) { vcmptrue_usps(x, x, op); }
+void vcmptrue_ussd(const Xmm& x, const Operand& op) { vcmptrue_ussd(x, x, op); }
+void vcmptrue_usss(const Xmm& x, const Operand& op) { vcmptrue_usss(x, x, op); }
+void vcmptruepd(const Xmm& x, const Operand& op) { vcmptruepd(x, x, op); }
+void vcmptrueps(const Xmm& x, const Operand& op) { vcmptrueps(x, x, op); }
+void vcmptruesd(const Xmm& x, const Operand& op) { vcmptruesd(x, x, op); }
+void vcmptruess(const Xmm& x, const Operand& op) { vcmptruess(x, x, op); }
+void vcmpunord_spd(const Xmm& x, const Operand& op) { vcmpunord_spd(x, x, op); }
+void vcmpunord_sps(const Xmm& x, const Operand& op) { vcmpunord_sps(x, x, op); }
+void vcmpunord_ssd(const Xmm& x, const Operand& op) { vcmpunord_ssd(x, x, op); }
+void vcmpunord_sss(const Xmm& x, const Operand& op) { vcmpunord_sss(x, x, op); }
+void vcmpunordpd(const Xmm& x, const Operand& op) { vcmpunordpd(x, x, op); }
+void vcmpunordps(const Xmm& x, const Operand& op) { vcmpunordps(x, x, op); }
+void vcmpunordsd(const Xmm& x, const Operand& op) { vcmpunordsd(x, x, op); }
+void vcmpunordss(const Xmm& x, const Operand& op) { vcmpunordss(x, x, op); }
+void vcvtsd2ss(const Xmm& x, const Operand& op) { vcvtsd2ss(x, x, op); }
+void vcvtsi2sd(const Xmm& x, const Operand& op) { vcvtsi2sd(x, x, op); }
+void vcvtsi2ss(const Xmm& x, const Operand& op) { vcvtsi2ss(x, x, op); }
+void vcvtss2sd(const Xmm& x, const Operand& op) { vcvtss2sd(x, x, op); }
+void vdppd(const Xmm& x, const Operand& op, uint8 imm) { vdppd(x, x, op, imm); }
+void vdpps(const Xmm& x, const Operand& op, uint8 imm) { vdpps(x, x, op, imm); }
+void vinsertps(const Xmm& x, const Operand& op, uint8 imm) { vinsertps(x, x, op, imm); }
+void vmpsadbw(const Xmm& x, const Operand& op, uint8 imm) { vmpsadbw(x, x, op, imm); }
+void vpackssdw(const Xmm& x, const Operand& op) { vpackssdw(x, x, op); }
+void vpacksswb(const Xmm& x, const Operand& op) { vpacksswb(x, x, op); }
+void vpackusdw(const Xmm& x, const Operand& op) { vpackusdw(x, x, op); }
+void vpackuswb(const Xmm& x, const Operand& op) { vpackuswb(x, x, op); }
+void vpaddb(const Xmm& x, const Operand& op) { vpaddb(x, x, op); }
+void vpaddd(const Xmm& x, const Operand& op) { vpaddd(x, x, op); }
+void vpaddq(const Xmm& x, const Operand& op) { vpaddq(x, x, op); }
+void vpaddsb(const Xmm& x, const Operand& op) { vpaddsb(x, x, op); }
+void vpaddsw(const Xmm& x, const Operand& op) { vpaddsw(x, x, op); }
+void vpaddusb(const Xmm& x, const Operand& op) { vpaddusb(x, x, op); }
+void vpaddusw(const Xmm& x, const Operand& op) { vpaddusw(x, x, op); }
+void vpaddw(const Xmm& x, const Operand& op) { vpaddw(x, x, op); }
+void vpalignr(const Xmm& x, const Operand& op, uint8 imm) { vpalignr(x, x, op, imm); }
+void vpand(const Xmm& x, const Operand& op) { vpand(x, x, op); }
+void vpandn(const Xmm& x, const Operand& op) { vpandn(x, x, op); }
+void vpavgb(const Xmm& x, const Operand& op) { vpavgb(x, x, op); }
+void vpavgw(const Xmm& x, const Operand& op) { vpavgw(x, x, op); }
+void vpblendd(const Xmm& x, const Operand& op, uint8 imm) { vpblendd(x, x, op, imm); }
+void vpblendvb(const Xmm& x1, const Operand& op, const Xmm& x4) { vpblendvb(x1, x1, op, x4); }
+void vpblendw(const Xmm& x, const Operand& op, uint8 imm) { vpblendw(x, x, op, imm); }
+void vpclmulqdq(const Xmm& x, const Operand& op, uint8 imm) { vpclmulqdq(x, x, op, imm); }
+void vpcmpeqb(const Xmm& x, const Operand& op) { vpcmpeqb(x, x, op); }
+void vpcmpeqd(const Xmm& x, const Operand& op) { vpcmpeqd(x, x, op); }
+void vpcmpeqq(const Xmm& x, const Operand& op) { vpcmpeqq(x, x, op); }
+void vpcmpeqw(const Xmm& x, const Operand& op) { vpcmpeqw(x, x, op); }
+void vpcmpgtb(const Xmm& x, const Operand& op) { vpcmpgtb(x, x, op); }
+void vpcmpgtd(const Xmm& x, const Operand& op) { vpcmpgtd(x, x, op); }
+void vpcmpgtq(const Xmm& x, const Operand& op) { vpcmpgtq(x, x, op); }
+void vpcmpgtw(const Xmm& x, const Operand& op) { vpcmpgtw(x, x, op); }
+void vphaddd(const Xmm& x, const Operand& op) { vphaddd(x, x, op); }
+void vphaddsw(const Xmm& x, const Operand& op) { vphaddsw(x, x, op); }
+void vphaddw(const Xmm& x, const Operand& op) { vphaddw(x, x, op); }
+void vphsubd(const Xmm& x, const Operand& op) { vphsubd(x, x, op); }
+void vphsubsw(const Xmm& x, const Operand& op) { vphsubsw(x, x, op); }
+void vphsubw(const Xmm& x, const Operand& op) { vphsubw(x, x, op); }
+void vpinsrb(const Xmm& x, const Operand& op, uint8 imm) { vpinsrb(x, x, op, imm); }
+void vpinsrd(const Xmm& x, const Operand& op, uint8 imm) { vpinsrd(x, x, op, imm); }
+void vpinsrq(const Xmm& x, const Operand& op, uint8 imm) { vpinsrq(x, x, op, imm); }
+void vpinsrw(const Xmm& x, const Operand& op, uint8 imm) { vpinsrw(x, x, op, imm); }
+void vpmaddubsw(const Xmm& x, const Operand& op) { vpmaddubsw(x, x, op); }
+void vpmaddwd(const Xmm& x, const Operand& op) { vpmaddwd(x, x, op); }
+void vpmaxsb(const Xmm& x, const Operand& op) { vpmaxsb(x, x, op); }
+void vpmaxsd(const Xmm& x, const Operand& op) { vpmaxsd(x, x, op); }
+void vpmaxsw(const Xmm& x, const Operand& op) { vpmaxsw(x, x, op); }
+void vpmaxub(const Xmm& x, const Operand& op) { vpmaxub(x, x, op); }
+void vpmaxud(const Xmm& x, const Operand& op) { vpmaxud(x, x, op); }
+void vpmaxuw(const Xmm& x, const Operand& op) { vpmaxuw(x, x, op); }
+void vpminsb(const Xmm& x, const Operand& op) { vpminsb(x, x, op); }
+void vpminsd(const Xmm& x, const Operand& op) { vpminsd(x, x, op); }
+void vpminsw(const Xmm& x, const Operand& op) { vpminsw(x, x, op); }
+void vpminub(const Xmm& x, const Operand& op) { vpminub(x, x, op); }
+void vpminud(const Xmm& x, const Operand& op) { vpminud(x, x, op); }
+void vpminuw(const Xmm& x, const Operand& op) { vpminuw(x, x, op); }
+void vpmuldq(const Xmm& x, const Operand& op) { vpmuldq(x, x, op); }
+void vpmulhrsw(const Xmm& x, const Operand& op) { vpmulhrsw(x, x, op); }
+void vpmulhuw(const Xmm& x, const Operand& op) { vpmulhuw(x, x, op); }
+void vpmulhw(const Xmm& x, const Operand& op) { vpmulhw(x, x, op); }
+void vpmulld(const Xmm& x, const Operand& op) { vpmulld(x, x, op); }
+void vpmullw(const Xmm& x, const Operand& op) { vpmullw(x, x, op); }
+void vpmuludq(const Xmm& x, const Operand& op) { vpmuludq(x, x, op); }
+void vpor(const Xmm& x, const Operand& op) { vpor(x, x, op); }
+void vpsadbw(const Xmm& x, const Operand& op) { vpsadbw(x, x, op); }
+void vpsignb(const Xmm& x, const Operand& op) { vpsignb(x, x, op); }
+void vpsignd(const Xmm& x, const Operand& op) { vpsignd(x, x, op); }
+void vpsignw(const Xmm& x, const Operand& op) { vpsignw(x, x, op); }
+void vpslld(const Xmm& x, const Operand& op) { vpslld(x, x, op); }
+void vpslld(const Xmm& x, uint8 imm) { vpslld(x, x, imm); }
+void vpslldq(const Xmm& x, uint8 imm) { vpslldq(x, x, imm); }
+void vpsllq(const Xmm& x, const Operand& op) { vpsllq(x, x, op); }
+void vpsllq(const Xmm& x, uint8 imm) { vpsllq(x, x, imm); }
+void vpsllw(const Xmm& x, const Operand& op) { vpsllw(x, x, op); }
+void vpsllw(const Xmm& x, uint8 imm) { vpsllw(x, x, imm); }
+void vpsrad(const Xmm& x, const Operand& op) { vpsrad(x, x, op); }
+void vpsrad(const Xmm& x, uint8 imm) { vpsrad(x, x, imm); }
+void vpsraw(const Xmm& x, const Operand& op) { vpsraw(x, x, op); }
+void vpsraw(const Xmm& x, uint8 imm) { vpsraw(x, x, imm); }
+void vpsrld(const Xmm& x, const Operand& op) { vpsrld(x, x, op); }
+void vpsrld(const Xmm& x, uint8 imm) { vpsrld(x, x, imm); }
+void vpsrldq(const Xmm& x, uint8 imm) { vpsrldq(x, x, imm); }
+void vpsrlq(const Xmm& x, const Operand& op) { vpsrlq(x, x, op); }
+void vpsrlq(const Xmm& x, uint8 imm) { vpsrlq(x, x, imm); }
+void vpsrlw(const Xmm& x, const Operand& op) { vpsrlw(x, x, op); }
+void vpsrlw(const Xmm& x, uint8 imm) { vpsrlw(x, x, imm); }
+void vpsubb(const Xmm& x, const Operand& op) { vpsubb(x, x, op); }
+void vpsubd(const Xmm& x, const Operand& op) { vpsubd(x, x, op); }
+void vpsubq(const Xmm& x, const Operand& op) { vpsubq(x, x, op); }
+void vpsubsb(const Xmm& x, const Operand& op) { vpsubsb(x, x, op); }
+void vpsubsw(const Xmm& x, const Operand& op) { vpsubsw(x, x, op); }
+void vpsubusb(const Xmm& x, const Operand& op) { vpsubusb(x, x, op); }
+void vpsubusw(const Xmm& x, const Operand& op) { vpsubusw(x, x, op); }
+void vpsubw(const Xmm& x, const Operand& op) { vpsubw(x, x, op); }
+void vpunpckhbw(const Xmm& x, const Operand& op) { vpunpckhbw(x, x, op); }
+void vpunpckhdq(const Xmm& x, const Operand& op) { vpunpckhdq(x, x, op); }
+void vpunpckhqdq(const Xmm& x, const Operand& op) { vpunpckhqdq(x, x, op); }
+void vpunpckhwd(const Xmm& x, const Operand& op) { vpunpckhwd(x, x, op); }
+void vpunpcklbw(const Xmm& x, const Operand& op) { vpunpcklbw(x, x, op); }
+void vpunpckldq(const Xmm& x, const Operand& op) { vpunpckldq(x, x, op); }
+void vpunpcklqdq(const Xmm& x, const Operand& op) { vpunpcklqdq(x, x, op); }
+void vpunpcklwd(const Xmm& x, const Operand& op) { vpunpcklwd(x, x, op); }
+void vpxor(const Xmm& x, const Operand& op) { vpxor(x, x, op); }
+void vrcpss(const Xmm& x, const Operand& op) { vrcpss(x, x, op); }
+void vroundsd(const Xmm& x, const Operand& op, uint8 imm) { vroundsd(x, x, op, imm); }
+void vroundss(const Xmm& x, const Operand& op, uint8 imm) { vroundss(x, x, op, imm); }
+void vrsqrtss(const Xmm& x, const Operand& op) { vrsqrtss(x, x, op); }
+void vshufpd(const Xmm& x, const Operand& op, uint8 imm) { vshufpd(x, x, op, imm); }
+void vshufps(const Xmm& x, const Operand& op, uint8 imm) { vshufps(x, x, op, imm); }
+void vsqrtsd(const Xmm& x, const Operand& op) { vsqrtsd(x, x, op); }
+void vsqrtss(const Xmm& x, const Operand& op) { vsqrtss(x, x, op); }
+void vunpckhpd(const Xmm& x, const Operand& op) { vunpckhpd(x, x, op); }
+void vunpckhps(const Xmm& x, const Operand& op) { vunpckhps(x, x, op); }
+void vunpcklpd(const Xmm& x, const Operand& op) { vunpcklpd(x, x, op); }
+void vunpcklps(const Xmm& x, const Operand& op) { vunpcklps(x, x, op); }
+#endif
+#ifdef XBYAK64
+void jecxz(std::string label) { db(0x67); opJmp(label, T_SHORT, 0xe3, 0, 0); }
+void jecxz(const Label& label) { db(0x67); opJmp(label, T_SHORT, 0xe3, 0, 0); }
+void jrcxz(std::string label) { opJmp(label, T_SHORT, 0xe3, 0, 0); }
+void jrcxz(const Label& label) { opJmp(label, T_SHORT, 0xe3, 0, 0); }
+void cdqe() { db(0x48); db(0x98); }
+void cqo() { db(0x48); db(0x99); }
+void cmpsq() { db(0x48); db(0xA7); }
+void movsq() { db(0x48); db(0xA5); }
+void scasq() { db(0x48); db(0xAF); }
+void stosq() { db(0x48); db(0xAB); }
+void cmpxchg16b(const Address& addr) { opModM(addr, Reg64(1), 0x0F, 0xC7); }
+void movq(const Reg64& reg, const Mmx& mmx) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, 0x0F, 0x7E); }
+void movq(const Mmx& mmx, const Reg64& reg) { if (mmx.isXMM()) db(0x66); opModR(mmx, reg, 0x0F, 0x6E); }
+void movsxd(const Reg64& reg, const Operand& op) { if (!op.isBit(32)) throw Error(ERR_BAD_COMBINATION); opModRM(reg, op, op.isREG(), op.isMEM(), 0x63); }
+void pextrq(const Operand& op, const Xmm& xmm, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opGen(Reg64(xmm.getIdx()), op, 0x16, 0x66, 0, imm, 0x3A); }
+void pinsrq(const Xmm& xmm, const Operand& op, uint8 imm) { if (!op.isREG(64) && !op.isMEM()) throw Error(ERR_BAD_COMBINATION); opGen(Reg64(xmm.getIdx()), op, 0x22, 0x66, 0, imm, 0x3A); }
+void vcvtss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W1 | T_EVEX | T_EW1 | T_ER_X | T_N8, 0x2D); }
+void vcvttss2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F3 | T_W1 | T_EVEX | T_EW1 | T_SAE_X | T_N8, 0x2C); }
+void vcvtsd2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F2 | T_W1 | T_EVEX | T_EW1 | T_N4 | T_ER_X, 0x2D); }
+void vcvttsd2si(const Reg64& r, const Operand& op) { opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, T_0F | T_F2 | T_W1 | T_EVEX | T_EW1 | T_N4 | T_SAE_X, 0x2C); }
+void vmovq(const Xmm& x, const Reg64& r) { opAVX_X_X_XM(x, xm0, Xmm(r.getIdx()), T_66 | T_0F | T_W1 | T_EVEX | T_EW1, 0x6E); }
+void vmovq(const Reg64& r, const Xmm& x) { opAVX_X_X_XM(x, xm0, Xmm(r.getIdx()), T_66 | T_0F | T_W1 | T_EVEX | T_EW1, 0x7E); }
+#else
+void jcxz(std::string label) { db(0x67); opJmp(label, T_SHORT, 0xe3, 0, 0); }
+void jcxz(const Label& label) { db(0x67); opJmp(label, T_SHORT, 0xe3, 0, 0); }
+void jecxz(std::string label) { opJmp(label, T_SHORT, 0xe3, 0, 0); }
+void jecxz(const Label& label) { opJmp(label, T_SHORT, 0xe3, 0, 0); }
+void aaa() { db(0x37); }
+void aad() { db(0xD5); db(0x0A); }
+void aam() { db(0xD4); db(0x0A); }
+void aas() { db(0x3F); }
+void daa() { db(0x27); }
+void das() { db(0x2F); }
+void popad() { db(0x61); }
+void popfd() { db(0x9D); }
+void pusha() { db(0x60); }
+void pushad() { db(0x60); }
+void pushfd() { db(0x9C); }
+void popa() { db(0x61); }
+#endif
+#ifndef XBYAK_NO_OP_NAMES
+void and(const Operand& op1, const Operand& op2) { and_(op1, op2); }
+void and(const Operand& op, uint32 imm) { and_(op, imm); }
+void or(const Operand& op1, const Operand& op2) { or_(op1, op2); }
+void or(const Operand& op, uint32 imm) { or_(op, imm); }
+void xor(const Operand& op1, const Operand& op2) { xor_(op1, op2); }
+void xor(const Operand& op, uint32 imm) { xor_(op, imm); }
+void not(const Operand& op) { not_(op); }
+#endif
+#ifndef XBYAK_DISABLE_AVX512
+void kaddb(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W0, 0x4A); }
+void kaddd(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W1, 0x4A); }
+void kaddq(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W1, 0x4A); }
+void kaddw(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W0, 0x4A); }
+void kandb(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W0, 0x41); }
+void kandd(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W1, 0x41); }
+void kandnb(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W0, 0x42); }
+void kandnd(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W1, 0x42); }
+void kandnq(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W1, 0x42); }
+void kandnw(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W0, 0x42); }
+void kandq(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W1, 0x41); }
+void kandw(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W0, 0x41); }
+void kmovb(const Address& addr, const Opmask& k) { opVex(k, 0, addr, T_L0 | T_0F | T_66 | T_W0, 0x91); }
+void kmovb(const Opmask& k, const Operand& op) { opVex(k, 0, op, T_L0 | T_0F | T_66 | T_W0, 0x90); }
+void kmovb(const Opmask& k, const Reg32& r) { opVex(k, 0, r, T_L0 | T_0F | T_66 | T_W0, 0x92); }
+void kmovb(const Reg32& r, const Opmask& k) { opVex(r, 0, k, T_L0 | T_0F | T_66 | T_W0, 0x93); }
+void kmovd(const Address& addr, const Opmask& k) { opVex(k, 0, addr, T_L0 | T_0F | T_66 | T_W1, 0x91); }
+void kmovd(const Opmask& k, const Operand& op) { opVex(k, 0, op, T_L0 | T_0F | T_66 | T_W1, 0x90); }
+void kmovd(const Opmask& k, const Reg32& r) { opVex(k, 0, r, T_L0 | T_0F | T_F2 | T_W0, 0x92); }
+void kmovd(const Reg32& r, const Opmask& k) { opVex(r, 0, k, T_L0 | T_0F | T_F2 | T_W0, 0x93); }
+void kmovq(const Address& addr, const Opmask& k) { opVex(k, 0, addr, T_L0 | T_0F | T_W1, 0x91); }
+void kmovq(const Opmask& k, const Operand& op) { opVex(k, 0, op, T_L0 | T_0F | T_W1, 0x90); }
+void kmovw(const Address& addr, const Opmask& k) { opVex(k, 0, addr, T_L0 | T_0F | T_W0, 0x91); }
+void kmovw(const Opmask& k, const Operand& op) { opVex(k, 0, op, T_L0 | T_0F | T_W0, 0x90); }
+void kmovw(const Opmask& k, const Reg32& r) { opVex(k, 0, r, T_L0 | T_0F | T_W0, 0x92); }
+void kmovw(const Reg32& r, const Opmask& k) { opVex(r, 0, k, T_L0 | T_0F | T_W0, 0x93); }
+void knotb(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_66 | T_W0, 0x44); }
+void knotd(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_66 | T_W1, 0x44); }
+void knotq(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_W1, 0x44); }
+void knotw(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_W0, 0x44); }
+void korb(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W0, 0x45); }
+void kord(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W1, 0x45); }
+void korq(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W1, 0x45); }
+void kortestb(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_66 | T_W0, 0x98); }
+void kortestd(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_66 | T_W1, 0x98); }
+void kortestq(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_W1, 0x98); }
+void kortestw(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_W0, 0x98); }
+void korw(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W0, 0x45); }
+void kshiftlb(const Opmask& r1, const Opmask& r2, uint8 imm) { opVex(r1, 0, r2, T_66 | T_0F3A | T_W0, 0x32, imm); }
+void kshiftld(const Opmask& r1, const Opmask& r2, uint8 imm) { opVex(r1, 0, r2, T_66 | T_0F3A | T_W0, 0x33, imm); }
+void kshiftlq(const Opmask& r1, const Opmask& r2, uint8 imm) { opVex(r1, 0, r2, T_66 | T_0F3A | T_W1, 0x33, imm); }
+void kshiftlw(const Opmask& r1, const Opmask& r2, uint8 imm) { opVex(r1, 0, r2, T_66 | T_0F3A | T_W1, 0x32, imm); }
+void kshiftrb(const Opmask& r1, const Opmask& r2, uint8 imm) { opVex(r1, 0, r2, T_66 | T_0F3A | T_W0, 0x30, imm); }
+void kshiftrd(const Opmask& r1, const Opmask& r2, uint8 imm) { opVex(r1, 0, r2, T_66 | T_0F3A | T_W0, 0x31, imm); }
+void kshiftrq(const Opmask& r1, const Opmask& r2, uint8 imm) { opVex(r1, 0, r2, T_66 | T_0F3A | T_W1, 0x31, imm); }
+void kshiftrw(const Opmask& r1, const Opmask& r2, uint8 imm) { opVex(r1, 0, r2, T_66 | T_0F3A | T_W1, 0x30, imm); }
+void ktestb(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_66 | T_W0, 0x99); }
+void ktestd(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_66 | T_W1, 0x99); }
+void ktestq(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_W1, 0x99); }
+void ktestw(const Opmask& r1, const Opmask& r2) { opVex(r1, 0, r2, T_0F | T_W0, 0x99); }
+void kunpckbw(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W0, 0x4B); }
+void kunpckdq(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W1, 0x4B); }
+void kunpckwd(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W0, 0x4B); }
+void kxnorb(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W0, 0x46); }
+void kxnord(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W1, 0x46); }
+void kxnorq(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W1, 0x46); }
+void kxnorw(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W0, 0x46); }
+void kxorb(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W0, 0x47); }
+void kxord(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_66 | T_W1, 0x47); }
+void kxorq(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W1, 0x47); }
+void kxorw(const Opmask& r1, const Opmask& r2, const Opmask& r3) { opVex(r1, &r2, r3, T_L1 | T_0F | T_W0, 0x47); }
+void v4fmaddps(const Zmm& z1, const Zmm& z2, const Address& addr) { opAVX_X_X_XM(z1, z2, addr, T_0F38 | T_F2 | T_EW0 | T_YMM | T_MUST_EVEX | T_N16, 0x9A); }
+void v4fmaddss(const Xmm& x1, const Xmm& x2, const Address& addr) { opAVX_X_X_XM(x1, x2, addr, T_0F38 | T_F2 | T_EW0 | T_MUST_EVEX | T_N16, 0x9B); }
+void v4fnmaddps(const Zmm& z1, const Zmm& z2, const Address& addr) { opAVX_X_X_XM(z1, z2, addr, T_0F38 | T_F2 | T_EW0 | T_YMM | T_MUST_EVEX | T_N16, 0xAA); }
+void v4fnmaddss(const Xmm& x1, const Xmm& x2, const Address& addr) { opAVX_X_X_XM(x1, x2, addr, T_0F38 | T_F2 | T_EW0 | T_MUST_EVEX | T_N16, 0xAB); }
+void valignd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x03, imm); }
+void valignq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX, 0x03, imm); }
+void vblendmpd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x65); }
+void vblendmps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x65); }
+void vbroadcastf32x2(const Ymm& y, const Operand& op) { opAVX_X_XM_IMM(y, op, T_66 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW0 | T_N8, 0x19); }
+void vbroadcastf32x4(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, T_66 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW0 | T_N16, 0x1A); }
+void vbroadcastf32x8(const Zmm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, T_66 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW0 | T_N32, 0x1B); }
+void vbroadcastf64x2(const Ymm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, T_66 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW1 | T_N16, 0x1A); }
+void vbroadcastf64x4(const Zmm& y, const Address& addr) { opAVX_X_XM_IMM(y, addr, T_66 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW1 | T_N32, 0x1B); }
+void vbroadcasti32x2(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW0 | T_N8, 0x59); }
+void vbroadcasti32x4(const Ymm& y, const Operand& op) { opAVX_X_XM_IMM(y, op, T_66 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW0 | T_N16, 0x5A); }
+void vbroadcasti32x8(const Zmm& z, const Operand& op) { opAVX_X_XM_IMM(z, op, T_66 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW0 | T_N32, 0x5B); }
+void vbroadcasti64x2(const Ymm& y, const Operand& op) { opAVX_X_XM_IMM(y, op, T_66 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW1 | T_N16, 0x5A); }
+void vbroadcasti64x4(const Zmm& z, const Operand& op) { opAVX_X_XM_IMM(z, op, T_66 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW1 | T_N32, 0x5B); }
+void vcmppd(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_66 | T_0F | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX, 0xC2, imm); }
+void vcmpps(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_0F | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX, 0xC2, imm); }
+void vcmpsd(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_N8 | T_F2 | T_0F | T_EW1 | T_SAE_Z | T_MUST_EVEX, 0xC2, imm); }
+void vcmpss(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_N4 | T_F3 | T_0F | T_EW0 | T_SAE_Z | T_MUST_EVEX, 0xC2, imm); }
+void vcompressb(const Operand& op, const Xmm& x) { opAVX_X_XM_IMM(x, op, T_N1 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x63); }
+void vcompresspd(const Operand& op, const Xmm& x) { opAVX_X_XM_IMM(x, op, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x8A); }
+void vcompressps(const Operand& op, const Xmm& x) { opAVX_X_XM_IMM(x, op, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x8A); }
+void vcompressw(const Operand& op, const Xmm& x) { opAVX_X_XM_IMM(x, op, T_N2 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x63); }
+void vcvtpd2qq(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F | T_EW1 | T_YMM | T_ER_Z | T_MUST_EVEX | T_B64, 0x7B); }
+void vcvtpd2udq(const Xmm& x, const Operand& op) { opCvt2(x, op, T_0F | T_YMM | T_MUST_EVEX | T_EW1 | T_B64 | T_ER_Z, 0x79); }
+void vcvtpd2uqq(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F | T_EW1 | T_YMM | T_ER_Z | T_MUST_EVEX | T_B64, 0x79); }
+void vcvtps2qq(const Xmm& x, const Operand& op) { checkCvt1(x, op); opVex(x, 0, op, T_66 | T_0F | T_YMM | T_MUST_EVEX | T_EW0 | T_B32 | T_N8 | T_N_VL | T_ER_Y, 0x7B); }
+void vcvtps2udq(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_0F | T_EW0 | T_YMM | T_ER_Z | T_MUST_EVEX | T_B32, 0x79); }
+void vcvtps2uqq(const Xmm& x, const Operand& op) { checkCvt1(x, op); opVex(x, 0, op, T_66 | T_0F | T_YMM | T_MUST_EVEX | T_EW0 | T_B32 | T_N8 | T_N_VL | T_ER_Y, 0x79); }
+void vcvtqq2pd(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_F3 | T_0F | T_EW1 | T_YMM | T_ER_Z | T_MUST_EVEX | T_B64, 0xE6); }
+void vcvtqq2ps(const Xmm& x, const Operand& op) { opCvt2(x, op, T_0F | T_YMM | T_MUST_EVEX | T_EW1 | T_B64 | T_ER_Z, 0x5B); }
+void vcvtsd2usi(const Reg32e& r, const Operand& op) { int type = (T_F2 | T_0F | T_MUST_EVEX | T_N8 | T_ER_X) | (r.isREG(64) ? T_EW1 : T_EW0); opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, type, 0x79); }
+void vcvtss2usi(const Reg32e& r, const Operand& op) { int type = (T_F3 | T_0F | T_MUST_EVEX | T_N4 | T_ER_X) | (r.isREG(64) ? T_EW1 : T_EW0); opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, type, 0x79); }
+void vcvttpd2qq(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x7A); }
+void vcvttpd2udq(const Xmm& x, const Operand& op) { opCvt2(x, op, T_0F | T_YMM | T_MUST_EVEX | T_EW1 | T_B64 | T_SAE_Z, 0x78); }
+void vcvttpd2uqq(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x78); }
+void vcvttps2qq(const Xmm& x, const Operand& op) { checkCvt1(x, op); opVex(x, 0, op, T_66 | T_0F | T_YMM | T_MUST_EVEX | T_EW0 | T_B32 | T_N8 | T_N_VL | T_SAE_Y, 0x7A); }
+void vcvttps2udq(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_0F | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x78); }
+void vcvttps2uqq(const Xmm& x, const Operand& op) { checkCvt1(x, op); opVex(x, 0, op, T_66 | T_0F | T_YMM | T_MUST_EVEX | T_EW0 | T_B32 | T_N8 | T_N_VL | T_SAE_Y, 0x78); }
+void vcvttsd2usi(const Reg32e& r, const Operand& op) { int type = (T_F2 | T_0F | T_MUST_EVEX | T_N8 | T_SAE_X) | (r.isREG(64) ? T_EW1 : T_EW0); opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, type, 0x78); }
+void vcvttss2usi(const Reg32e& r, const Operand& op) { int type = (T_F3 | T_0F | T_MUST_EVEX | T_N4 | T_SAE_X) | (r.isREG(64) ? T_EW1 : T_EW0); opAVX_X_X_XM(Xmm(r.getIdx()), xm0, op, type, 0x78); }
+void vcvtudq2pd(const Xmm& x, const Operand& op) { checkCvt1(x, op); opVex(x, 0, op, T_F3 | T_0F | T_YMM | T_MUST_EVEX | T_EW0 | T_B32 | T_N8 | T_N_VL, 0x7A); }
+void vcvtudq2ps(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_F2 | T_0F | T_EW0 | T_YMM | T_ER_Z | T_MUST_EVEX | T_B32, 0x7A); }
+void vcvtuqq2pd(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_F3 | T_0F | T_EW1 | T_YMM | T_ER_Z | T_MUST_EVEX | T_B64, 0x7A); }
+void vcvtuqq2ps(const Xmm& x, const Operand& op) { opCvt2(x, op, T_F2 | T_0F | T_YMM | T_MUST_EVEX | T_EW1 | T_B64 | T_ER_Z, 0x7A); }
+void vcvtusi2sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opCvt3(x1, x2, op, T_F2 | T_0F | T_MUST_EVEX, T_W1 | T_EW1 | T_ER_X | T_N8, T_W0 | T_EW0 | T_N4, 0x7B); }
+void vcvtusi2ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opCvt3(x1, x2, op, T_F3 | T_0F | T_MUST_EVEX | T_ER_X, T_W1 | T_EW1 | T_N8, T_W0 | T_EW0 | T_N4, 0x7B); }
+void vdbpsadbw(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x42, imm); }
+void vexp2pd(const Zmm& z, const Operand& op) { opAVX_X_XM_IMM(z, op, T_66 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW1 | T_B64 | T_SAE_Z, 0xC8); }
+void vexp2ps(const Zmm& z, const Operand& op) { opAVX_X_XM_IMM(z, op, T_66 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW0 | T_B32 | T_SAE_Z, 0xC8); }
+void vexpandpd(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x88); }
+void vexpandps(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x88); }
+void vextractf32x4(const Operand& op, const Ymm& r, uint8 imm) { if (!op.is(Operand::MEM | Operand::XMM)) throw Error(ERR_BAD_COMBINATION); opVex(r, 0, op, T_N16 | T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x19, imm); }
+void vextractf32x8(const Operand& op, const Zmm& r, uint8 imm) { if (!op.is(Operand::MEM | Operand::YMM)) throw Error(ERR_BAD_COMBINATION); opVex(r, 0, op, T_N32 | T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x1B, imm); }
+void vextractf64x2(const Operand& op, const Ymm& r, uint8 imm) { if (!op.is(Operand::MEM | Operand::XMM)) throw Error(ERR_BAD_COMBINATION); opVex(r, 0, op, T_N16 | T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX, 0x19, imm); }
+void vextractf64x4(const Operand& op, const Zmm& r, uint8 imm) { if (!op.is(Operand::MEM | Operand::YMM)) throw Error(ERR_BAD_COMBINATION); opVex(r, 0, op, T_N32 | T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX, 0x1B, imm); }
+void vextracti32x4(const Operand& op, const Ymm& r, uint8 imm) { if (!op.is(Operand::MEM | Operand::XMM)) throw Error(ERR_BAD_COMBINATION); opVex(r, 0, op, T_N16 | T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x39, imm); }
+void vextracti32x8(const Operand& op, const Zmm& r, uint8 imm) { if (!op.is(Operand::MEM | Operand::YMM)) throw Error(ERR_BAD_COMBINATION); opVex(r, 0, op, T_N32 | T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x3B, imm); }
+void vextracti64x2(const Operand& op, const Ymm& r, uint8 imm) { if (!op.is(Operand::MEM | Operand::XMM)) throw Error(ERR_BAD_COMBINATION); opVex(r, 0, op, T_N16 | T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX, 0x39, imm); }
+void vextracti64x4(const Operand& op, const Zmm& r, uint8 imm) { if (!op.is(Operand::MEM | Operand::YMM)) throw Error(ERR_BAD_COMBINATION); opVex(r, 0, op, T_N32 | T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX, 0x3B, imm); }
+void vfixupimmpd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x54, imm); }
+void vfixupimmps(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x54, imm); }
+void vfixupimmsd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F3A | T_EW1 | T_SAE_Z | T_MUST_EVEX, 0x55, imm); }
+void vfixupimmss(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F3A | T_EW0 | T_SAE_Z | T_MUST_EVEX, 0x55, imm); }
+void vfpclasspd(const Opmask& k, const Operand& op, uint8 imm) { if (!op.isBit(128|256|512)) throw Error(ERR_BAD_MEM_SIZE); Reg x = k; x.setBit(op.getBit()); opVex(x, 0, op, T_66 | T_0F3A | T_MUST_EVEX | T_YMM | T_EW1 | T_B64, 0x66, imm); }
+void vfpclassps(const Opmask& k, const Operand& op, uint8 imm) { if (!op.isBit(128|256|512)) throw Error(ERR_BAD_MEM_SIZE); Reg x = k; x.setBit(op.getBit()); opVex(x, 0, op, T_66 | T_0F3A | T_MUST_EVEX | T_YMM | T_EW0 | T_B32, 0x66, imm); }
+void vfpclasssd(const Opmask& k, const Operand& op, uint8 imm) { if (!op.isXMEM()) throw Error(ERR_BAD_MEM_SIZE); opVex(k, 0, op, T_66 | T_0F3A | T_MUST_EVEX | T_EW1 | T_N8, 0x67, imm); }
+void vfpclassss(const Opmask& k, const Operand& op, uint8 imm) { if (!op.isXMEM()) throw Error(ERR_BAD_MEM_SIZE); opVex(k, 0, op, T_66 | T_0F3A | T_MUST_EVEX | T_EW0 | T_N4, 0x67, imm); }
+void vgatherdpd(const Xmm& x, const Address& addr) { opGather2(x, addr, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_VSIB, 0x92, 1); }
+void vgatherdps(const Xmm& x, const Address& addr) { opGather2(x, addr, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_VSIB, 0x92, 0); }
+void vgatherpf0dpd(const Address& addr) { opGatherFetch(addr, zm1, T_N8 | T_66 | T_0F38 | T_EW1 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC6, Operand::YMM); }
+void vgatherpf0dps(const Address& addr) { opGatherFetch(addr, zm1, T_N4 | T_66 | T_0F38 | T_EW0 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC6, Operand::ZMM); }
+void vgatherpf0qpd(const Address& addr) { opGatherFetch(addr, zm1, T_N8 | T_66 | T_0F38 | T_EW1 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC7, Operand::ZMM); }
+void vgatherpf0qps(const Address& addr) { opGatherFetch(addr, zm1, T_N4 | T_66 | T_0F38 | T_EW0 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC7, Operand::ZMM); }
+void vgatherpf1dpd(const Address& addr) { opGatherFetch(addr, zm2, T_N8 | T_66 | T_0F38 | T_EW1 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC6, Operand::YMM); }
+void vgatherpf1dps(const Address& addr) { opGatherFetch(addr, zm2, T_N4 | T_66 | T_0F38 | T_EW0 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC6, Operand::ZMM); }
+void vgatherpf1qpd(const Address& addr) { opGatherFetch(addr, zm2, T_N8 | T_66 | T_0F38 | T_EW1 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC7, Operand::ZMM); }
+void vgatherpf1qps(const Address& addr) { opGatherFetch(addr, zm2, T_N4 | T_66 | T_0F38 | T_EW0 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC7, Operand::ZMM); }
+void vgatherqpd(const Xmm& x, const Address& addr) { opGather2(x, addr, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_VSIB, 0x93, 0); }
+void vgatherqps(const Xmm& x, const Address& addr) { opGather2(x, addr, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_VSIB, 0x93, 2); }
+void vgetexppd(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x42); }
+void vgetexpps(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x42); }
+void vgetexpsd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_EW1 | T_SAE_X | T_MUST_EVEX, 0x43); }
+void vgetexpss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_EW0 | T_SAE_X | T_MUST_EVEX, 0x43); }
+void vgetmantpd(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(x, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x26, imm); }
+void vgetmantps(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(x, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x26, imm); }
+void vgetmantsd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F3A | T_EW1 | T_SAE_X | T_MUST_EVEX, 0x27, imm); }
+void vgetmantss(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F3A | T_EW0 | T_SAE_X | T_MUST_EVEX, 0x27, imm); }
+void vinsertf32x4(const Ymm& r1, const Ymm& r2, const Operand& op, uint8 imm) {if (!(r1.getKind() == r2.getKind() && op.is(Operand::MEM | Operand::XMM))) throw Error(ERR_BAD_COMBINATION); opVex(r1, &r2, op, T_N16 | T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x18, imm); }
+void vinsertf32x8(const Zmm& r1, const Zmm& r2, const Operand& op, uint8 imm) {if (!op.is(Operand::MEM | Operand::YMM)) throw Error(ERR_BAD_COMBINATION); opVex(r1, &r2, op, T_N32 | T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x1A, imm); }
+void vinsertf64x2(const Ymm& r1, const Ymm& r2, const Operand& op, uint8 imm) {if (!(r1.getKind() == r2.getKind() && op.is(Operand::MEM | Operand::XMM))) throw Error(ERR_BAD_COMBINATION); opVex(r1, &r2, op, T_N16 | T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX, 0x18, imm); }
+void vinsertf64x4(const Zmm& r1, const Zmm& r2, const Operand& op, uint8 imm) {if (!op.is(Operand::MEM | Operand::YMM)) throw Error(ERR_BAD_COMBINATION); opVex(r1, &r2, op, T_N32 | T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX, 0x1A, imm); }
+void vinserti32x4(const Ymm& r1, const Ymm& r2, const Operand& op, uint8 imm) {if (!(r1.getKind() == r2.getKind() && op.is(Operand::MEM | Operand::XMM))) throw Error(ERR_BAD_COMBINATION); opVex(r1, &r2, op, T_N16 | T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x38, imm); }
+void vinserti32x8(const Zmm& r1, const Zmm& r2, const Operand& op, uint8 imm) {if (!op.is(Operand::MEM | Operand::YMM)) throw Error(ERR_BAD_COMBINATION); opVex(r1, &r2, op, T_N32 | T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x3A, imm); }
+void vinserti64x2(const Ymm& r1, const Ymm& r2, const Operand& op, uint8 imm) {if (!(r1.getKind() == r2.getKind() && op.is(Operand::MEM | Operand::XMM))) throw Error(ERR_BAD_COMBINATION); opVex(r1, &r2, op, T_N16 | T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX, 0x38, imm); }
+void vinserti64x4(const Zmm& r1, const Zmm& r2, const Operand& op, uint8 imm) {if (!op.is(Operand::MEM | Operand::YMM)) throw Error(ERR_BAD_COMBINATION); opVex(r1, &r2, op, T_N32 | T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX, 0x3A, imm); }
+void vmovdqa32(const Address& addr, const Xmm& x) { opAVX_X_XM_IMM(x, addr, T_66 | T_0F | T_EW0 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX | T_M_K, 0x7F); }
+void vmovdqa32(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F | T_EW0 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX, 0x6F); }
+void vmovdqa64(const Address& addr, const Xmm& x) { opAVX_X_XM_IMM(x, addr, T_66 | T_0F | T_EW1 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX | T_M_K, 0x7F); }
+void vmovdqa64(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F | T_EW1 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX, 0x6F); }
+void vmovdqu16(const Address& addr, const Xmm& x) { opAVX_X_XM_IMM(x, addr, T_F2 | T_0F | T_EW1 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX | T_M_K, 0x7F); }
+void vmovdqu16(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_F2 | T_0F | T_EW1 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX, 0x6F); }
+void vmovdqu32(const Address& addr, const Xmm& x) { opAVX_X_XM_IMM(x, addr, T_F3 | T_0F | T_EW0 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX | T_M_K, 0x7F); }
+void vmovdqu32(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_F3 | T_0F | T_EW0 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX, 0x6F); }
+void vmovdqu64(const Address& addr, const Xmm& x) { opAVX_X_XM_IMM(x, addr, T_F3 | T_0F | T_EW1 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX | T_M_K, 0x7F); }
+void vmovdqu64(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_F3 | T_0F | T_EW1 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX, 0x6F); }
+void vmovdqu8(const Address& addr, const Xmm& x) { opAVX_X_XM_IMM(x, addr, T_F2 | T_0F | T_EW0 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX | T_M_K, 0x7F); }
+void vmovdqu8(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_F2 | T_0F | T_EW0 | T_YMM | T_ER_X | T_ER_Y | T_ER_Z | T_MUST_EVEX, 0x6F); }
+void vp4dpwssd(const Zmm& z1, const Zmm& z2, const Address& addr) { opAVX_X_X_XM(z1, z2, addr, T_0F38 | T_F2 | T_EW0 | T_YMM | T_MUST_EVEX | T_N16, 0x52); }
+void vp4dpwssds(const Zmm& z1, const Zmm& z2, const Address& addr) { opAVX_X_X_XM(z1, z2, addr, T_0F38 | T_F2 | T_EW0 | T_YMM | T_MUST_EVEX | T_N16, 0x53); }
+void vpabsq(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_MUST_EVEX | T_EW1 | T_B64 | T_YMM, 0x1F); }
+void vpandd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0xDB); }
+void vpandnd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0xDF); }
+void vpandnq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0xDF); }
+void vpandq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0xDB); }
+void vpblendmb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x66); }
+void vpblendmd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x64); }
+void vpblendmq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x64); }
+void vpblendmw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x66); }
+void vpbroadcastb(const Xmm& x, const Reg8& r) { opVex(x, 0, r, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x7A); }
+void vpbroadcastd(const Xmm& x, const Reg32& r) { opVex(x, 0, r, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x7C); }
+void vpbroadcastmb2q(const Xmm& x, const Opmask& k) { opVex(x, 0, k, T_F3 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW1, 0x2A); }
+void vpbroadcastmw2d(const Xmm& x, const Opmask& k) { opVex(x, 0, k, T_F3 | T_0F38 | T_YMM | T_MUST_EVEX | T_EW0, 0x3A); }
+void vpbroadcastw(const Xmm& x, const Reg16& r) { opVex(x, 0, r, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x7B); }
+void vpcmpb(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x3F, imm); }
+void vpcmpd(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x1F, imm); }
+void vpcmpeqb(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F | T_YMM | T_MUST_EVEX, 0x74); }
+void vpcmpeqd(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F | T_YMM | T_MUST_EVEX | T_B32, 0x76); }
+void vpcmpeqq(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x29); }
+void vpcmpeqw(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F | T_YMM | T_MUST_EVEX, 0x75); }
+void vpcmpgtb(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F | T_YMM | T_MUST_EVEX, 0x64); }
+void vpcmpgtd(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x66); }
+void vpcmpgtq(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x37); }
+void vpcmpgtw(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F | T_YMM | T_MUST_EVEX, 0x65); }
+void vpcmpq(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x1F, imm); }
+void vpcmpub(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX, 0x3E, imm); }
+void vpcmpud(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x1E, imm); }
+void vpcmpuq(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x1E, imm); }
+void vpcmpuw(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX, 0x3E, imm); }
+void vpcmpw(const Opmask& k, const Xmm& x, const Operand& op, uint8 imm) { opAVX_K_X_XM(k, x, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX, 0x3F, imm); }
+void vpcompressd(const Operand& op, const Xmm& x) { opAVX_X_XM_IMM(x, op, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x8B); }
+void vpcompressq(const Operand& op, const Xmm& x) { opAVX_X_XM_IMM(x, op, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x8B); }
+void vpconflictd(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0xC4); }
+void vpconflictq(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0xC4); }
+void vpdpbusd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x50); }
+void vpdpbusds(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x51); }
+void vpdpwssd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x52); }
+void vpdpwssds(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x53); }
+void vpermb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x8D); }
+void vpermi2b(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x75); }
+void vpermi2d(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x76); }
+void vpermi2pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x77); }
+void vpermi2ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x77); }
+void vpermi2q(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x76); }
+void vpermi2w(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x75); }
+void vpermt2b(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x7D); }
+void vpermt2d(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x7E); }
+void vpermt2pd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x7F); }
+void vpermt2ps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x7F); }
+void vpermt2q(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x7E); }
+void vpermt2w(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x7D); }
+void vpermw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x8D); }
+void vpexpandb(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_N1 | T_66 | T_0F38 | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX, 0x62); }
+void vpexpandd(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x89); }
+void vpexpandq(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x89); }
+void vpexpandw(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_N2 | T_66 | T_0F38 | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX, 0x62); }
+void vpgatherdd(const Xmm& x, const Address& addr) { opGather2(x, addr, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_VSIB, 0x90, 0); }
+void vpgatherdq(const Xmm& x, const Address& addr) { opGather2(x, addr, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_VSIB, 0x90, 1); }
+void vpgatherqd(const Xmm& x, const Address& addr) { opGather2(x, addr, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_VSIB, 0x91, 2); }
+void vpgatherqq(const Xmm& x, const Address& addr) { opGather2(x, addr, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_VSIB, 0x91, 0); }
+void vplzcntd(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x44); }
+void vplzcntq(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x44); }
+void vpmadd52huq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0xB5); }
+void vpmadd52luq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0xB4); }
+void vpmaxsq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x3D); }
+void vpmaxuq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x3F); }
+void vpminsq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x39); }
+void vpminuq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x3B); }
+void vpmovb2m(const Opmask& k, const Xmm& x) { opVex(k, 0, x, T_F3 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW0, 0x29); }
+void vpmovd2m(const Opmask& k, const Xmm& x) { opVex(k, 0, x, T_F3 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW0, 0x39); }
+void vpmovdb(const Operand& op, const Xmm& x) { opVmov(op, x, T_N4 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x31, false); }
+void vpmovdw(const Operand& op, const Xmm& x) { opVmov(op, x, T_N8 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x33, true); }
+void vpmovm2b(const Xmm& x, const Opmask& k) { opVex(x, 0, k, T_F3 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW0, 0x28); }
+void vpmovm2d(const Xmm& x, const Opmask& k) { opVex(x, 0, k, T_F3 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW0, 0x38); }
+void vpmovm2q(const Xmm& x, const Opmask& k) { opVex(x, 0, k, T_F3 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW1, 0x38); }
+void vpmovm2w(const Xmm& x, const Opmask& k) { opVex(x, 0, k, T_F3 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW1, 0x28); }
+void vpmovq2m(const Opmask& k, const Xmm& x) { opVex(k, 0, x, T_F3 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW1, 0x39); }
+void vpmovqb(const Operand& op, const Xmm& x) { opVmov(op, x, T_N2 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x32, false); }
+void vpmovqd(const Operand& op, const Xmm& x) { opVmov(op, x, T_N8 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x35, true); }
+void vpmovqw(const Operand& op, const Xmm& x) { opVmov(op, x, T_N4 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x34, false); }
+void vpmovsdb(const Operand& op, const Xmm& x) { opVmov(op, x, T_N4 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x21, false); }
+void vpmovsdw(const Operand& op, const Xmm& x) { opVmov(op, x, T_N8 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x23, true); }
+void vpmovsqb(const Operand& op, const Xmm& x) { opVmov(op, x, T_N2 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x22, false); }
+void vpmovsqd(const Operand& op, const Xmm& x) { opVmov(op, x, T_N8 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x25, true); }
+void vpmovsqw(const Operand& op, const Xmm& x) { opVmov(op, x, T_N4 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x24, false); }
+void vpmovswb(const Operand& op, const Xmm& x) { opVmov(op, x, T_N8 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x20, true); }
+void vpmovusdb(const Operand& op, const Xmm& x) { opVmov(op, x, T_N4 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x11, false); }
+void vpmovusdw(const Operand& op, const Xmm& x) { opVmov(op, x, T_N8 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x13, true); }
+void vpmovusqb(const Operand& op, const Xmm& x) { opVmov(op, x, T_N2 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x12, false); }
+void vpmovusqd(const Operand& op, const Xmm& x) { opVmov(op, x, T_N8 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x15, true); }
+void vpmovusqw(const Operand& op, const Xmm& x) { opVmov(op, x, T_N4 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x14, false); }
+void vpmovuswb(const Operand& op, const Xmm& x) { opVmov(op, x, T_N8 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x10, true); }
+void vpmovw2m(const Opmask& k, const Xmm& x) { opVex(k, 0, x, T_F3 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW1, 0x29); }
+void vpmovwb(const Operand& op, const Xmm& x) { opVmov(op, x, T_N8 | T_N_VL | T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x30, true); }
+void vpmullq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x40); }
+void vpmultishiftqb(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x83); }
+void vpopcntb(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX, 0x54); }
+void vpopcntd(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x55); }
+void vpopcntq(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x55); }
+void vpopcntw(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX, 0x54); }
+void vpord(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0xEB); }
+void vporq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0xEB); }
+void vprold(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 1), x, op, T_66 | T_0F | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x72, imm); }
+void vprolq(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 1), x, op, T_66 | T_0F | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x72, imm); }
+void vprolvd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x15); }
+void vprolvq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x15); }
+void vprord(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 0), x, op, T_66 | T_0F | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x72, imm); }
+void vprorq(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 0), x, op, T_66 | T_0F | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x72, imm); }
+void vprorvd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x14); }
+void vprorvq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x14); }
+void vpscatterdd(const Address& addr, const Xmm& x) { opGather2(x, addr, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_M_K | T_VSIB, 0xA0, 0); }
+void vpscatterdq(const Address& addr, const Xmm& x) { opGather2(x, addr, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_M_K | T_VSIB, 0xA0, 1); }
+void vpscatterqd(const Address& addr, const Xmm& x) { opGather2(x, addr, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_M_K | T_VSIB, 0xA1, 2); }
+void vpscatterqq(const Address& addr, const Xmm& x) { opGather2(x, addr, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_M_K | T_VSIB, 0xA1, 0); }
+void vpshldd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x71, imm); }
+void vpshldq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x71, imm); }
+void vpshldvd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x71); }
+void vpshldvq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x71); }
+void vpshldvw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX, 0x70); }
+void vpshldw(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX, 0x70, imm); }
+void vpshrdd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x73, imm); }
+void vpshrdq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x73, imm); }
+void vpshrdvd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x73); }
+void vpshrdvq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x73); }
+void vpshrdvw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX, 0x72); }
+void vpshrdw(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX, 0x72, imm); }
+void vpshufbitqmb(const Opmask& k, const Xmm& x, const Operand& op) { opVex(k, &x, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x8F); }
+void vpsllvw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x12); }
+void vpsraq(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_X_XM(Xmm(x.getKind(), 4), x, op, T_66 | T_0F | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x72, imm); }
+void vpsraq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N16 | T_66 | T_0F | T_EW1 | T_YMM | T_MUST_EVEX, 0xE2); }
+void vpsravq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x46); }
+void vpsravw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x11); }
+void vpsrlvw(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x10); }
+void vpternlogd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x25, imm); }
+void vpternlogq(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x25, imm); }
+void vptestmb(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x26); }
+void vptestmd(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x27); }
+void vptestmq(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x27); }
+void vptestmw(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x26); }
+void vptestnmb(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x26); }
+void vptestnmd(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_F3 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x27); }
+void vptestnmq(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_F3 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x27); }
+void vptestnmw(const Opmask& k, const Xmm& x, const Operand& op) { opAVX_K_X_XM(k, x, op, T_F3 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x26); }
+void vpxord(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0xEF); }
+void vpxorq(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0xEF); }
+void vrangepd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x50, imm); }
+void vrangeps(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x50, imm); }
+void vrangesd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F3A | T_EW1 | T_SAE_X | T_MUST_EVEX, 0x51, imm); }
+void vrangess(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F3A | T_EW0 | T_SAE_X | T_MUST_EVEX, 0x51, imm); }
+void vrcp14pd(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x4C); }
+void vrcp14ps(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x4C); }
+void vrcp14sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_EW1 | T_MUST_EVEX, 0x4D); }
+void vrcp14ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_EW0 | T_MUST_EVEX, 0x4D); }
+void vrcp28pd(const Zmm& z, const Operand& op) { opAVX_X_XM_IMM(z, op, T_66 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW1 | T_B64 | T_SAE_Z, 0xCA); }
+void vrcp28ps(const Zmm& z, const Operand& op) { opAVX_X_XM_IMM(z, op, T_66 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW0 | T_B32 | T_SAE_Z, 0xCA); }
+void vrcp28sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_EW1 | T_SAE_X | T_MUST_EVEX, 0xCB); }
+void vrcp28ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_EW0 | T_SAE_X | T_MUST_EVEX, 0xCB); }
+void vreducepd(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(x, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B64, 0x56, imm); }
+void vreduceps(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(x, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_SAE_Z | T_MUST_EVEX | T_B32, 0x56, imm); }
+void vreducesd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F3A | T_EW1 | T_SAE_X | T_MUST_EVEX, 0x57, imm); }
+void vreducess(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F3A | T_EW0 | T_SAE_X | T_MUST_EVEX, 0x57, imm); }
+void vrndscalepd(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(x, op, T_66 | T_0F3A | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x09, imm); }
+void vrndscaleps(const Xmm& x, const Operand& op, uint8 imm) { opAVX_X_XM_IMM(x, op, T_66 | T_0F3A | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x08, imm); }
+void vrndscalesd(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F3A | T_EW1 | T_MUST_EVEX, 0x0B, imm); }
+void vrndscaless(const Xmm& x1, const Xmm& x2, const Operand& op, uint8 imm) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F3A | T_EW0 | T_MUST_EVEX, 0x0A, imm); }
+void vrsqrt14pd(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_B64, 0x4E); }
+void vrsqrt14ps(const Xmm& x, const Operand& op) { opAVX_X_XM_IMM(x, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_B32, 0x4E); }
+void vrsqrt14sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x4F); }
+void vrsqrt14ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX, 0x4F); }
+void vrsqrt28pd(const Zmm& z, const Operand& op) { opAVX_X_XM_IMM(z, op, T_66 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW1 | T_B64 | T_SAE_Z, 0xCC); }
+void vrsqrt28ps(const Zmm& z, const Operand& op) { opAVX_X_XM_IMM(z, op, T_66 | T_0F38 | T_MUST_EVEX | T_YMM | T_EW0 | T_B32 | T_SAE_Z, 0xCC); }
+void vrsqrt28sd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_EW1 | T_SAE_X | T_MUST_EVEX, 0xCD); }
+void vrsqrt28ss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_EW0 | T_SAE_X | T_MUST_EVEX, 0xCD); }
+void vscalefpd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW1 | T_YMM | T_ER_Z | T_MUST_EVEX | T_B64, 0x2C); }
+void vscalefps(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_66 | T_0F38 | T_EW0 | T_YMM | T_ER_Z | T_MUST_EVEX | T_B32, 0x2C); }
+void vscalefsd(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N8 | T_66 | T_0F38 | T_EW1 | T_ER_X | T_MUST_EVEX, 0x2D); }
+void vscalefss(const Xmm& x1, const Xmm& x2, const Operand& op) { opAVX_X_X_XM(x1, x2, op, T_N4 | T_66 | T_0F38 | T_EW0 | T_ER_X | T_MUST_EVEX, 0x2D); }
+void vscatterdpd(const Address& addr, const Xmm& x) { opGather2(x, addr, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_M_K | T_VSIB, 0xA2, 1); }
+void vscatterdps(const Address& addr, const Xmm& x) { opGather2(x, addr, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_M_K | T_VSIB, 0xA2, 0); }
+void vscatterpf0dpd(const Address& addr) { opGatherFetch(addr, zm5, T_N8 | T_66 | T_0F38 | T_EW1 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC6, Operand::YMM); }
+void vscatterpf0dps(const Address& addr) { opGatherFetch(addr, zm5, T_N4 | T_66 | T_0F38 | T_EW0 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC6, Operand::ZMM); }
+void vscatterpf0qpd(const Address& addr) { opGatherFetch(addr, zm5, T_N8 | T_66 | T_0F38 | T_EW1 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC7, Operand::ZMM); }
+void vscatterpf0qps(const Address& addr) { opGatherFetch(addr, zm5, T_N4 | T_66 | T_0F38 | T_EW0 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC7, Operand::ZMM); }
+void vscatterpf1dpd(const Address& addr) { opGatherFetch(addr, zm6, T_N8 | T_66 | T_0F38 | T_EW1 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC6, Operand::YMM); }
+void vscatterpf1dps(const Address& addr) { opGatherFetch(addr, zm6, T_N4 | T_66 | T_0F38 | T_EW0 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC6, Operand::ZMM); }
+void vscatterpf1qpd(const Address& addr) { opGatherFetch(addr, zm6, T_N8 | T_66 | T_0F38 | T_EW1 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC7, Operand::ZMM); }
+void vscatterpf1qps(const Address& addr) { opGatherFetch(addr, zm6, T_N4 | T_66 | T_0F38 | T_EW0 | T_MUST_EVEX | T_M_K | T_VSIB, 0xC7, Operand::ZMM); }
+void vscatterqpd(const Address& addr, const Xmm& x) { opGather2(x, addr, T_N8 | T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX | T_M_K | T_VSIB, 0xA3, 0); }
+void vscatterqps(const Address& addr, const Xmm& x) { opGather2(x, addr, T_N4 | T_66 | T_0F38 | T_EW0 | T_YMM | T_MUST_EVEX | T_M_K | T_VSIB, 0xA3, 2); }
+void vshuff32x4(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XM(y1, y2, op, T_66 | T_0F3A | T_YMM | T_MUST_EVEX | T_EW0 | T_B32, 0x23, imm); }
+void vshuff64x2(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XM(y1, y2, op, T_66 | T_0F3A | T_YMM | T_MUST_EVEX | T_EW1 | T_B64, 0x23, imm); }
+void vshufi32x4(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XM(y1, y2, op, T_66 | T_0F3A | T_YMM | T_MUST_EVEX | T_EW0 | T_B32, 0x43, imm); }
+void vshufi64x2(const Ymm& y1, const Ymm& y2, const Operand& op, uint8 imm) { opAVX_X_X_XM(y1, y2, op, T_66 | T_0F3A | T_YMM | T_MUST_EVEX | T_EW1 | T_B64, 0x43, imm); }
+#ifdef XBYAK64
+void kmovq(const Opmask& k, const Reg64& r) { opVex(k, 0, r, T_L0 | T_0F | T_F2 | T_W1, 0x92); }
+void kmovq(const Reg64& r, const Opmask& k) { opVex(r, 0, k, T_L0 | T_0F | T_F2 | T_W1, 0x93); }
+void vpbroadcastq(const Xmm& x, const Reg64& r) { opVex(x, 0, r, T_66 | T_0F38 | T_EW1 | T_YMM | T_MUST_EVEX, 0x7C); }
+#endif
+#endif
diff --git a/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_util.h b/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_util.h
new file mode 100644
index 0000000000..8ef076e680
--- /dev/null
+++ b/thirdparty/oidn/mkl-dnn/src/cpu/xbyak/xbyak_util.h
@@ -0,0 +1,772 @@
+/*******************************************************************************
+* Copyright 2016-2019 Intel Corporation
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*******************************************************************************/
+
+/*******************************************************************************
+* Copyright (c) 2007 MITSUNARI Shigeo
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+*
+* Redistributions of source code must retain the above copyright notice, this
+* list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+* Neither the name of the copyright owner nor the names of its contributors may
+* be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+* THE POSSIBILITY OF SUCH DAMAGE.
+*******************************************************************************/
+
+#ifndef XBYAK_XBYAK_UTIL_H_
+#define XBYAK_XBYAK_UTIL_H_
+
+/**
+ utility class and functions for Xbyak
+ Xbyak::util::Clock ; rdtsc timer
+ Xbyak::util::Cpu ; detect CPU
+ @note this header is UNDER CONSTRUCTION!
+*/
+#include "xbyak.h"
+
+#if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
+ #define XBYAK_INTEL_CPU_SPECIFIC
+#endif
+
+#ifdef XBYAK_INTEL_CPU_SPECIFIC
+#ifdef _MSC_VER
+ #if (_MSC_VER < 1400) && defined(XBYAK32)
+ static inline __declspec(naked) void __cpuid(int[4], int)
+ {
+ __asm {
+ push ebx
+ push esi
+ mov eax, dword ptr [esp + 4 * 2 + 8] // eaxIn
+ cpuid
+ mov esi, dword ptr [esp + 4 * 2 + 4] // data
+ mov dword ptr [esi], eax
+ mov dword ptr [esi + 4], ebx
+ mov dword ptr [esi + 8], ecx
+ mov dword ptr [esi + 12], edx
+ pop esi
+ pop ebx
+ ret
+ }
+ }
+ #else
+ #include <intrin.h> // for __cpuid
+ #endif
+#else
+ #ifndef __GNUC_PREREQ
+ #define __GNUC_PREREQ(major, minor) ((((__GNUC__) << 16) + (__GNUC_MINOR__)) >= (((major) << 16) + (minor)))
+ #endif
+ #if __GNUC_PREREQ(4, 3) && !defined(__APPLE__)
+ #include <cpuid.h>
+ #else
+ #if defined(__APPLE__) && defined(XBYAK32) // avoid err : can't find a register in class `BREG' while reloading `asm'
+ #define __cpuid(eaxIn, a, b, c, d) __asm__ __volatile__("pushl %%ebx\ncpuid\nmovl %%ebp, %%esi\npopl %%ebx" : "=a"(a), "=S"(b), "=c"(c), "=d"(d) : "0"(eaxIn))
+ #define __cpuid_count(eaxIn, ecxIn, a, b, c, d) __asm__ __volatile__("pushl %%ebx\ncpuid\nmovl %%ebp, %%esi\npopl %%ebx" : "=a"(a), "=S"(b), "=c"(c), "=d"(d) : "0"(eaxIn), "2"(ecxIn))
+ #else
+ #define __cpuid(eaxIn, a, b, c, d) __asm__ __volatile__("cpuid\n" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(eaxIn))
+ #define __cpuid_count(eaxIn, ecxIn, a, b, c, d) __asm__ __volatile__("cpuid\n" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "0"(eaxIn), "2"(ecxIn))
+ #endif
+ #endif
+#endif
+#endif
+
+namespace Xbyak { namespace util {
+
+typedef enum {
+ SmtLevel = 1,
+ CoreLevel = 2
+} IntelCpuTopologyLevel;
+
+/**
+ CPU detection class
+*/
+class Cpu {
+ uint64 type_;
+ //system topology
+ bool x2APIC_supported_;
+ static const size_t maxTopologyLevels = 2;
+ unsigned int numCores_[maxTopologyLevels];
+
+ static const unsigned int maxNumberCacheLevels = 10;
+ unsigned int dataCacheSize_[maxNumberCacheLevels];
+ unsigned int coresSharignDataCache_[maxNumberCacheLevels];
+ unsigned int dataCacheLevels_;
+
+ unsigned int get32bitAsBE(const char *x) const
+ {
+ return x[0] | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
+ }
+ unsigned int mask(int n) const
+ {
+ return (1U << n) - 1;
+ }
+ void setFamily()
+ {
+ unsigned int data[4] = {};
+ getCpuid(1, data);
+ stepping = data[0] & mask(4);
+ model = (data[0] >> 4) & mask(4);
+ family = (data[0] >> 8) & mask(4);
+ // type = (data[0] >> 12) & mask(2);
+ extModel = (data[0] >> 16) & mask(4);
+ extFamily = (data[0] >> 20) & mask(8);
+ if (family == 0x0f) {
+ displayFamily = family + extFamily;
+ } else {
+ displayFamily = family;
+ }
+ if (family == 6 || family == 0x0f) {
+ displayModel = (extModel << 4) + model;
+ } else {
+ displayModel = model;
+ }
+ }
+ unsigned int extractBit(unsigned int val, unsigned int base, unsigned int end)
+ {
+ return (val >> base) & ((1u << (end - base)) - 1);
+ }
+ void setNumCores()
+ {
+ if ((type_ & tINTEL) == 0) return;
+
+ unsigned int data[4] = {};
+
+ /* CAUTION: These numbers are configuration as shipped by Intel. */
+ getCpuidEx(0x0, 0, data);
+ if (data[0] >= 0xB) {
+ /*
+ if leaf 11 exists(x2APIC is supported),
+ we use it to get the number of smt cores and cores on socket
+
+ leaf 0xB can be zeroed-out by a hypervisor
+ */
+ x2APIC_supported_ = true;
+ for (unsigned int i = 0; i < maxTopologyLevels; i++) {
+ getCpuidEx(0xB, i, data);
+ IntelCpuTopologyLevel level = (IntelCpuTopologyLevel)extractBit(data[2], 8, 15);
+ if (level == SmtLevel || level == CoreLevel) {
+ numCores_[level - 1] = extractBit(data[1], 0, 15);
+ }
+ }
+ } else {
+ /*
+ Failed to deremine num of cores without x2APIC support.
+ TODO: USE initial APIC ID to determine ncores.
+ */
+ numCores_[SmtLevel - 1] = 0;
+ numCores_[CoreLevel - 1] = 0;
+ }
+
+ }
+ void setCacheHierarchy()
+ {
+ if ((type_ & tINTEL) == 0) return;
+ const unsigned int NO_CACHE = 0;
+ const unsigned int DATA_CACHE = 1;
+// const unsigned int INSTRUCTION_CACHE = 2;
+ const unsigned int UNIFIED_CACHE = 3;
+ unsigned int smt_width = 0;
+ unsigned int logical_cores = 0;
+ unsigned int data[4] = {};
+
+ if (x2APIC_supported_) {
+ smt_width = numCores_[0];
+ logical_cores = numCores_[1];
+ }
+
+ /*
+ Assumptions:
+ the first level of data cache is not shared (which is the
+ case for every existing architecture) and use this to
+ determine the SMT width for arch not supporting leaf 11.
+ when leaf 4 reports a number of core less than numCores_
+ on socket reported by leaf 11, then it is a correct number
+ of cores not an upperbound.
+ */
+ for (int i = 0; dataCacheLevels_ < maxNumberCacheLevels; i++) {
+ getCpuidEx(0x4, i, data);
+ unsigned int cacheType = extractBit(data[0], 0, 4);
+ if (cacheType == NO_CACHE) break;
+ if (cacheType == DATA_CACHE || cacheType == UNIFIED_CACHE) {
+ unsigned int actual_logical_cores = extractBit(data[0], 14, 25) + 1;
+ if (logical_cores != 0) { // true only if leaf 0xB is supported and valid
+ actual_logical_cores = (std::min)(actual_logical_cores, logical_cores);
+ }
+ assert(actual_logical_cores != 0);
+ dataCacheSize_[dataCacheLevels_] =
+ (extractBit(data[1], 22, 31) + 1)
+ * (extractBit(data[1], 12, 21) + 1)
+ * (extractBit(data[1], 0, 11) + 1)
+ * (data[2] + 1);
+ if (cacheType == DATA_CACHE && smt_width == 0) smt_width = actual_logical_cores;
+ assert(smt_width != 0);
+ // FIXME: check and fix number of cores sharing L3 cache for different configurations
+ // (HT-, 2 sockets), (HT-, 1 socket), (HT+, 2 sockets), (HT+, 1 socket)
+ coresSharignDataCache_[dataCacheLevels_] = (std::max)(actual_logical_cores / smt_width, 1u);
+ dataCacheLevels_++;
+ }
+ }
+ }
+
+public:
+ int model;
+ int family;
+ int stepping;
+ int extModel;
+ int extFamily;
+ int displayFamily; // family + extFamily
+ int displayModel; // model + extModel
+
+ unsigned int getNumCores(IntelCpuTopologyLevel level) {
+ if (level != SmtLevel && level != CoreLevel) throw Error(ERR_BAD_PARAMETER);
+ if (!x2APIC_supported_) throw Error(ERR_X2APIC_IS_NOT_SUPPORTED);
+ return (level == CoreLevel)
+ ? numCores_[level - 1] / numCores_[SmtLevel - 1]
+ : numCores_[level - 1];
+ }
+
+ unsigned int getDataCacheLevels() const { return dataCacheLevels_; }
+ unsigned int getCoresSharingDataCache(unsigned int i) const
+ {
+ if (i >= dataCacheLevels_) throw Error(ERR_BAD_PARAMETER);
+ return coresSharignDataCache_[i];
+ }
+ unsigned int getDataCacheSize(unsigned int i) const
+ {
+ if (i >= dataCacheLevels_) throw Error(ERR_BAD_PARAMETER);
+ return dataCacheSize_[i];
+ }
+
+ /*
+ data[] = { eax, ebx, ecx, edx }
+ */
+ static inline void getCpuid(unsigned int eaxIn, unsigned int data[4])
+ {
+#ifdef XBYAK_INTEL_CPU_SPECIFIC
+ #ifdef _MSC_VER
+ __cpuid(reinterpret_cast<int*>(data), eaxIn);
+ #else
+ __cpuid(eaxIn, data[0], data[1], data[2], data[3]);
+ #endif
+#else
+ (void)eaxIn;
+ (void)data;
+#endif
+ }
+ static inline void getCpuidEx(unsigned int eaxIn, unsigned int ecxIn, unsigned int data[4])
+ {
+#ifdef XBYAK_INTEL_CPU_SPECIFIC
+ #ifdef _MSC_VER
+ __cpuidex(reinterpret_cast<int*>(data), eaxIn, ecxIn);
+ #else
+ __cpuid_count(eaxIn, ecxIn, data[0], data[1], data[2], data[3]);
+ #endif
+#else
+ (void)eaxIn;
+ (void)ecxIn;
+ (void)data;
+#endif
+ }
+ static inline uint64 getXfeature()
+ {
+#ifdef XBYAK_INTEL_CPU_SPECIFIC
+ #ifdef _MSC_VER
+ return _xgetbv(0);
+ #else
+ unsigned int eax, edx;
+ // xgetvb is not support on gcc 4.2
+// __asm__ volatile("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
+ __asm__ volatile(".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0));
+ return ((uint64)edx << 32) | eax;
+ #endif
+#else
+ return 0;
+#endif
+ }
+ typedef uint64 Type;
+
+ static const Type NONE = 0;
+ static const Type tMMX = 1 << 0;
+ static const Type tMMX2 = 1 << 1;
+ static const Type tCMOV = 1 << 2;
+ static const Type tSSE = 1 << 3;
+ static const Type tSSE2 = 1 << 4;
+ static const Type tSSE3 = 1 << 5;
+ static const Type tSSSE3 = 1 << 6;
+ static const Type tSSE41 = 1 << 7;
+ static const Type tSSE42 = 1 << 8;
+ static const Type tPOPCNT = 1 << 9;
+ static const Type tAESNI = 1 << 10;
+ static const Type tSSE5 = 1 << 11;
+ static const Type tOSXSAVE = 1 << 12;
+ static const Type tPCLMULQDQ = 1 << 13;
+ static const Type tAVX = 1 << 14;
+ static const Type tFMA = 1 << 15;
+
+ static const Type t3DN = 1 << 16;
+ static const Type tE3DN = 1 << 17;
+ static const Type tSSE4a = 1 << 18;
+ static const Type tRDTSCP = 1 << 19;
+ static const Type tAVX2 = 1 << 20;
+ static const Type tBMI1 = 1 << 21; // andn, bextr, blsi, blsmsk, blsr, tzcnt
+ static const Type tBMI2 = 1 << 22; // bzhi, mulx, pdep, pext, rorx, sarx, shlx, shrx
+ static const Type tLZCNT = 1 << 23;
+
+ static const Type tINTEL = 1 << 24;
+ static const Type tAMD = 1 << 25;
+
+ static const Type tENHANCED_REP = 1 << 26; // enhanced rep movsb/stosb
+ static const Type tRDRAND = 1 << 27;
+ static const Type tADX = 1 << 28; // adcx, adox
+ static const Type tRDSEED = 1 << 29; // rdseed
+ static const Type tSMAP = 1 << 30; // stac
+ static const Type tHLE = uint64(1) << 31; // xacquire, xrelease, xtest
+ static const Type tRTM = uint64(1) << 32; // xbegin, xend, xabort
+ static const Type tF16C = uint64(1) << 33; // vcvtph2ps, vcvtps2ph
+ static const Type tMOVBE = uint64(1) << 34; // mobve
+ static const Type tAVX512F = uint64(1) << 35;
+ static const Type tAVX512DQ = uint64(1) << 36;
+ static const Type tAVX512_IFMA = uint64(1) << 37;
+ static const Type tAVX512IFMA = tAVX512_IFMA;
+ static const Type tAVX512PF = uint64(1) << 38;
+ static const Type tAVX512ER = uint64(1) << 39;
+ static const Type tAVX512CD = uint64(1) << 40;
+ static const Type tAVX512BW = uint64(1) << 41;
+ static const Type tAVX512VL = uint64(1) << 42;
+ static const Type tAVX512_VBMI = uint64(1) << 43;
+ static const Type tAVX512VBMI = tAVX512_VBMI; // changed by Intel's manual
+ static const Type tAVX512_4VNNIW = uint64(1) << 44;
+ static const Type tAVX512_4FMAPS = uint64(1) << 45;
+ static const Type tPREFETCHWT1 = uint64(1) << 46;
+ static const Type tPREFETCHW = uint64(1) << 47;
+ static const Type tSHA = uint64(1) << 48;
+ static const Type tMPX = uint64(1) << 49;
+ static const Type tAVX512_VBMI2 = uint64(1) << 50;
+ static const Type tGFNI = uint64(1) << 51;
+ static const Type tVAES = uint64(1) << 52;
+ static const Type tVPCLMULQDQ = uint64(1) << 53;
+ static const Type tAVX512_VNNI = uint64(1) << 54;
+ static const Type tAVX512_BITALG = uint64(1) << 55;
+ static const Type tAVX512_VPOPCNTDQ = uint64(1) << 56;
+
+ Cpu()
+ : type_(NONE)
+ , x2APIC_supported_(false)
+ , numCores_()
+ , dataCacheSize_()
+ , coresSharignDataCache_()
+ , dataCacheLevels_(0)
+ {
+ unsigned int data[4] = {};
+ const unsigned int& EAX = data[0];
+ const unsigned int& EBX = data[1];
+ const unsigned int& ECX = data[2];
+ const unsigned int& EDX = data[3];
+ getCpuid(0, data);
+ const unsigned int maxNum = EAX;
+ static const char intel[] = "ntel";
+ static const char amd[] = "cAMD";
+ if (ECX == get32bitAsBE(amd)) {
+ type_ |= tAMD;
+ getCpuid(0x80000001, data);
+ if (EDX & (1U << 31)) type_ |= t3DN;
+ if (EDX & (1U << 15)) type_ |= tCMOV;
+ if (EDX & (1U << 30)) type_ |= tE3DN;
+ if (EDX & (1U << 22)) type_ |= tMMX2;
+ if (EDX & (1U << 27)) type_ |= tRDTSCP;
+ }
+ if (ECX == get32bitAsBE(intel)) {
+ type_ |= tINTEL;
+ getCpuid(0x80000001, data);
+ if (EDX & (1U << 27)) type_ |= tRDTSCP;
+ if (ECX & (1U << 5)) type_ |= tLZCNT;
+ if (ECX & (1U << 8)) type_ |= tPREFETCHW;
+ }
+ getCpuid(1, data);
+ if (ECX & (1U << 0)) type_ |= tSSE3;
+ if (ECX & (1U << 9)) type_ |= tSSSE3;
+ if (ECX & (1U << 19)) type_ |= tSSE41;
+ if (ECX & (1U << 20)) type_ |= tSSE42;
+ if (ECX & (1U << 22)) type_ |= tMOVBE;
+ if (ECX & (1U << 23)) type_ |= tPOPCNT;
+ if (ECX & (1U << 25)) type_ |= tAESNI;
+ if (ECX & (1U << 1)) type_ |= tPCLMULQDQ;
+ if (ECX & (1U << 27)) type_ |= tOSXSAVE;
+ if (ECX & (1U << 30)) type_ |= tRDRAND;
+ if (ECX & (1U << 29)) type_ |= tF16C;
+
+ if (EDX & (1U << 15)) type_ |= tCMOV;
+ if (EDX & (1U << 23)) type_ |= tMMX;
+ if (EDX & (1U << 25)) type_ |= tMMX2 | tSSE;
+ if (EDX & (1U << 26)) type_ |= tSSE2;
+
+ if (type_ & tOSXSAVE) {
+ // check XFEATURE_ENABLED_MASK[2:1] = '11b'
+ uint64 bv = getXfeature();
+ if ((bv & 6) == 6) {
+ if (ECX & (1U << 28)) type_ |= tAVX;
+ if (ECX & (1U << 12)) type_ |= tFMA;
+ if (((bv >> 5) & 7) == 7) {
+ getCpuidEx(7, 0, data);
+ if (EBX & (1U << 16)) type_ |= tAVX512F;
+ if (type_ & tAVX512F) {
+ if (EBX & (1U << 17)) type_ |= tAVX512DQ;
+ if (EBX & (1U << 21)) type_ |= tAVX512_IFMA;
+ if (EBX & (1U << 26)) type_ |= tAVX512PF;
+ if (EBX & (1U << 27)) type_ |= tAVX512ER;
+ if (EBX & (1U << 28)) type_ |= tAVX512CD;
+ if (EBX & (1U << 30)) type_ |= tAVX512BW;
+ if (EBX & (1U << 31)) type_ |= tAVX512VL;
+ if (ECX & (1U << 1)) type_ |= tAVX512_VBMI;
+ if (ECX & (1U << 6)) type_ |= tAVX512_VBMI2;
+ if (ECX & (1U << 8)) type_ |= tGFNI;
+ if (ECX & (1U << 9)) type_ |= tVAES;
+ if (ECX & (1U << 10)) type_ |= tVPCLMULQDQ;
+ if (ECX & (1U << 11)) type_ |= tAVX512_VNNI;
+ if (ECX & (1U << 12)) type_ |= tAVX512_BITALG;
+ if (ECX & (1U << 14)) type_ |= tAVX512_VPOPCNTDQ;
+ if (EDX & (1U << 2)) type_ |= tAVX512_4VNNIW;
+ if (EDX & (1U << 3)) type_ |= tAVX512_4FMAPS;
+ }
+ }
+ }
+ }
+ if (maxNum >= 7) {
+ getCpuidEx(7, 0, data);
+ if (type_ & tAVX && (EBX & (1U << 5))) type_ |= tAVX2;
+ if (EBX & (1U << 3)) type_ |= tBMI1;
+ if (EBX & (1U << 8)) type_ |= tBMI2;
+ if (EBX & (1U << 9)) type_ |= tENHANCED_REP;
+ if (EBX & (1U << 18)) type_ |= tRDSEED;
+ if (EBX & (1U << 19)) type_ |= tADX;
+ if (EBX & (1U << 20)) type_ |= tSMAP;
+ if (EBX & (1U << 4)) type_ |= tHLE;
+ if (EBX & (1U << 11)) type_ |= tRTM;
+ if (EBX & (1U << 14)) type_ |= tMPX;
+ if (EBX & (1U << 29)) type_ |= tSHA;
+ if (ECX & (1U << 0)) type_ |= tPREFETCHWT1;
+ }
+ setFamily();
+ setNumCores();
+ setCacheHierarchy();
+ }
+ void putFamily() const
+ {
+ printf("family=%d, model=%X, stepping=%d, extFamily=%d, extModel=%X\n",
+ family, model, stepping, extFamily, extModel);
+ printf("display:family=%X, model=%X\n", displayFamily, displayModel);
+ }
+ bool has(Type type) const
+ {
+ return (type & type_) != 0;
+ }
+};
+
+class Clock {
+public:
+ static inline uint64 getRdtsc()
+ {
+#ifdef XBYAK_INTEL_CPU_SPECIFIC
+ #ifdef _MSC_VER
+ return __rdtsc();
+ #else
+ unsigned int eax, edx;
+ __asm__ volatile("rdtsc" : "=a"(eax), "=d"(edx));
+ return ((uint64)edx << 32) | eax;
+ #endif
+#else
+ // TODO: Need another impl of Clock or rdtsc-equivalent for non-x86 cpu
+ return 0;
+#endif
+ }
+ Clock()
+ : clock_(0)
+ , count_(0)
+ {
+ }
+ void begin()
+ {
+ clock_ -= getRdtsc();
+ }
+ void end()
+ {
+ clock_ += getRdtsc();
+ count_++;
+ }
+ int getCount() const { return count_; }
+ uint64 getClock() const { return clock_; }
+ void clear() { count_ = 0; clock_ = 0; }
+private:
+ uint64 clock_;
+ int count_;
+};
+
+#ifdef XBYAK64
+const int UseRCX = 1 << 6;
+const int UseRDX = 1 << 7;
+
+class Pack {
+ static const size_t maxTblNum = 15;
+ const Xbyak::Reg64 *tbl_[maxTblNum];
+ size_t n_;
+public:
+ Pack() : tbl_(), n_(0) {}
+ Pack(const Xbyak::Reg64 *tbl, size_t n) { init(tbl, n); }
+ Pack(const Pack& rhs)
+ : n_(rhs.n_)
+ {
+ for (size_t i = 0; i < n_; i++) tbl_[i] = rhs.tbl_[i];
+ }
+ Pack& operator=(const Pack& rhs)
+ {
+ n_ = rhs.n_;
+ for (size_t i = 0; i < n_; i++) tbl_[i] = rhs.tbl_[i];
+ return *this;
+ }
+ Pack(const Xbyak::Reg64& t0)
+ { n_ = 1; tbl_[0] = &t0; }
+ Pack(const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
+ { n_ = 2; tbl_[0] = &t0; tbl_[1] = &t1; }
+ Pack(const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
+ { n_ = 3; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; }
+ Pack(const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
+ { n_ = 4; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; }
+ Pack(const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
+ { n_ = 5; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; }
+ Pack(const Xbyak::Reg64& t5, const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
+ { n_ = 6; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; tbl_[5] = &t5; }
+ Pack(const Xbyak::Reg64& t6, const Xbyak::Reg64& t5, const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
+ { n_ = 7; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; tbl_[5] = &t5; tbl_[6] = &t6; }
+ Pack(const Xbyak::Reg64& t7, const Xbyak::Reg64& t6, const Xbyak::Reg64& t5, const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
+ { n_ = 8; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; tbl_[5] = &t5; tbl_[6] = &t6; tbl_[7] = &t7; }
+ Pack(const Xbyak::Reg64& t8, const Xbyak::Reg64& t7, const Xbyak::Reg64& t6, const Xbyak::Reg64& t5, const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
+ { n_ = 9; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; tbl_[5] = &t5; tbl_[6] = &t6; tbl_[7] = &t7; tbl_[8] = &t8; }
+ Pack(const Xbyak::Reg64& t9, const Xbyak::Reg64& t8, const Xbyak::Reg64& t7, const Xbyak::Reg64& t6, const Xbyak::Reg64& t5, const Xbyak::Reg64& t4, const Xbyak::Reg64& t3, const Xbyak::Reg64& t2, const Xbyak::Reg64& t1, const Xbyak::Reg64& t0)
+ { n_ = 10; tbl_[0] = &t0; tbl_[1] = &t1; tbl_[2] = &t2; tbl_[3] = &t3; tbl_[4] = &t4; tbl_[5] = &t5; tbl_[6] = &t6; tbl_[7] = &t7; tbl_[8] = &t8; tbl_[9] = &t9; }
+ Pack& append(const Xbyak::Reg64& t)
+ {
+ if (n_ == maxTblNum) {
+ fprintf(stderr, "ERR Pack::can't append\n");
+ throw Error(ERR_BAD_PARAMETER);
+ }
+ tbl_[n_++] = &t;
+ return *this;
+ }
+ void init(const Xbyak::Reg64 *tbl, size_t n)
+ {
+ if (n > maxTblNum) {
+ fprintf(stderr, "ERR Pack::init bad n=%d\n", (int)n);
+ throw Error(ERR_BAD_PARAMETER);
+ }
+ n_ = n;
+ for (size_t i = 0; i < n; i++) {
+ tbl_[i] = &tbl[i];
+ }
+ }
+ const Xbyak::Reg64& operator[](size_t n) const
+ {
+ if (n >= n_) {
+ fprintf(stderr, "ERR Pack bad n=%d(%d)\n", (int)n, (int)n_);
+ throw Error(ERR_BAD_PARAMETER);
+ }
+ return *tbl_[n];
+ }
+ size_t size() const { return n_; }
+ /*
+ get tbl[pos, pos + num)
+ */
+ Pack sub(size_t pos, size_t num = size_t(-1)) const
+ {
+ if (num == size_t(-1)) num = n_ - pos;
+ if (pos + num > n_) {
+ fprintf(stderr, "ERR Pack::sub bad pos=%d, num=%d\n", (int)pos, (int)num);
+ throw Error(ERR_BAD_PARAMETER);
+ }
+ Pack pack;
+ pack.n_ = num;
+ for (size_t i = 0; i < num; i++) {
+ pack.tbl_[i] = tbl_[pos + i];
+ }
+ return pack;
+ }
+ void put() const
+ {
+ for (size_t i = 0; i < n_; i++) {
+ printf("%s ", tbl_[i]->toString());
+ }
+ printf("\n");
+ }
+};
+
+class StackFrame {
+#ifdef XBYAK64_WIN
+ static const int noSaveNum = 6;
+ static const int rcxPos = 0;
+ static const int rdxPos = 1;
+#else
+ static const int noSaveNum = 8;
+ static const int rcxPos = 3;
+ static const int rdxPos = 2;
+#endif
+ static const int maxRegNum = 14; // maxRegNum = 16 - rsp - rax
+ Xbyak::CodeGenerator *code_;
+ int pNum_;
+ int tNum_;
+ bool useRcx_;
+ bool useRdx_;
+ int saveNum_;
+ int P_;
+ bool makeEpilog_;
+ Xbyak::Reg64 pTbl_[4];
+ Xbyak::Reg64 tTbl_[maxRegNum];
+ Pack p_;
+ Pack t_;
+ StackFrame(const StackFrame&);
+ void operator=(const StackFrame&);
+public:
+ const Pack& p;
+ const Pack& t;
+ /*
+ make stack frame
+ @param sf [in] this
+ @param pNum [in] num of function parameter(0 <= pNum <= 4)
+ @param tNum [in] num of temporary register(0 <= tNum, with UseRCX, UseRDX) #{pNum + tNum [+rcx] + [rdx]} <= 14
+ @param stackSizeByte [in] local stack size
+ @param makeEpilog [in] automatically call close() if true
+
+ you can use
+ rax
+ gp0, ..., gp(pNum - 1)
+ gt0, ..., gt(tNum-1)
+ rcx if tNum & UseRCX
+ rdx if tNum & UseRDX
+ rsp[0..stackSizeByte - 1]
+ */
+ StackFrame(Xbyak::CodeGenerator *code, int pNum, int tNum = 0, int stackSizeByte = 0, bool makeEpilog = true)
+ : code_(code)
+ , pNum_(pNum)
+ , tNum_(tNum & ~(UseRCX | UseRDX))
+ , useRcx_((tNum & UseRCX) != 0)
+ , useRdx_((tNum & UseRDX) != 0)
+ , saveNum_(0)
+ , P_(0)
+ , makeEpilog_(makeEpilog)
+ , p(p_)
+ , t(t_)
+ {
+ using namespace Xbyak;
+ if (pNum < 0 || pNum > 4) throw Error(ERR_BAD_PNUM);
+ const int allRegNum = pNum + tNum_ + (useRcx_ ? 1 : 0) + (useRdx_ ? 1 : 0);
+ if (tNum_ < 0 || allRegNum > maxRegNum) throw Error(ERR_BAD_TNUM);
+ const Reg64& _rsp = code->rsp;
+ saveNum_ = (std::max)(0, allRegNum - noSaveNum);
+ const int *tbl = getOrderTbl() + noSaveNum;
+ for (int i = 0; i < saveNum_; i++) {
+ code->push(Reg64(tbl[i]));
+ }
+ P_ = (stackSizeByte + 7) / 8;
+ if (P_ > 0 && (P_ & 1) == (saveNum_ & 1)) P_++; // (rsp % 16) == 8, then increment P_ for 16 byte alignment
+ P_ *= 8;
+ if (P_ > 0) code->sub(_rsp, P_);
+ int pos = 0;
+ for (int i = 0; i < pNum; i++) {
+ pTbl_[i] = Xbyak::Reg64(getRegIdx(pos));
+ }
+ for (int i = 0; i < tNum_; i++) {
+ tTbl_[i] = Xbyak::Reg64(getRegIdx(pos));
+ }
+ if (useRcx_ && rcxPos < pNum) code_->mov(code_->r10, code_->rcx);
+ if (useRdx_ && rdxPos < pNum) code_->mov(code_->r11, code_->rdx);
+ p_.init(pTbl_, pNum);
+ t_.init(tTbl_, tNum_);
+ }
+ /*
+ make epilog manually
+ @param callRet [in] call ret() if true
+ */
+ void close(bool callRet = true)
+ {
+ using namespace Xbyak;
+ const Reg64& _rsp = code_->rsp;
+ const int *tbl = getOrderTbl() + noSaveNum;
+ if (P_ > 0) code_->add(_rsp, P_);
+ for (int i = 0; i < saveNum_; i++) {
+ code_->pop(Reg64(tbl[saveNum_ - 1 - i]));
+ }
+
+ if (callRet) code_->ret();
+ }
+ ~StackFrame()
+ {
+ if (!makeEpilog_) return;
+ try {
+ close();
+ } catch (std::exception& e) {
+ printf("ERR:StackFrame %s\n", e.what());
+ //exit(1);
+ }
+ }
+private:
+ const int *getOrderTbl() const
+ {
+ using namespace Xbyak;
+ static const int tbl[] = {
+#ifdef XBYAK64_WIN
+ Operand::RCX, Operand::RDX, Operand::R8, Operand::R9, Operand::R10, Operand::R11, Operand::RDI, Operand::RSI,
+#else
+ Operand::RDI, Operand::RSI, Operand::RDX, Operand::RCX, Operand::R8, Operand::R9, Operand::R10, Operand::R11,
+#endif
+ Operand::RBX, Operand::RBP, Operand::R12, Operand::R13, Operand::R14, Operand::R15
+ };
+ return &tbl[0];
+ }
+ int getRegIdx(int& pos) const
+ {
+ assert(pos < maxRegNum);
+ using namespace Xbyak;
+ const int *tbl = getOrderTbl();
+ int r = tbl[pos++];
+ if (useRcx_) {
+ if (r == Operand::RCX) { return Operand::R10; }
+ if (r == Operand::R10) { r = tbl[pos++]; }
+ }
+ if (useRdx_) {
+ if (r == Operand::RDX) { return Operand::R11; }
+ if (r == Operand::R11) { return tbl[pos++]; }
+ }
+ return r;
+ }
+};
+#endif
+
+} } // end of util
+#endif
diff --git a/thirdparty/oidn/weights/rtlightmap_hdr.tza b/thirdparty/oidn/weights/rtlightmap_hdr.tza
new file mode 100644
index 0000000000..12459a33bc
--- /dev/null
+++ b/thirdparty/oidn/weights/rtlightmap_hdr.tza
Binary files differ
diff --git a/thirdparty/pcre2/src/config.h b/thirdparty/pcre2/src/config.h
index 25d45eeb38..787bb9c999 100644
--- a/thirdparty/pcre2/src/config.h
+++ b/thirdparty/pcre2/src/config.h
@@ -218,7 +218,7 @@ sure both macros are undefined; an emulation function will then be used. */
#define PACKAGE_NAME "PCRE2"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "PCRE2 10.33"
+#define PACKAGE_STRING "PCRE2 10.34"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "pcre2"
@@ -227,7 +227,7 @@ sure both macros are undefined; an emulation function will then be used. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "10.33"
+#define PACKAGE_VERSION "10.34"
/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
parentheses (of any kind) in a pattern. This limits the amount of system
@@ -352,7 +352,7 @@ sure both macros are undefined; an emulation function will then be used. */
#endif
/* Version number of package */
-#define VERSION "10.33"
+#define VERSION "10.34"
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
diff --git a/thirdparty/pcre2/src/pcre2.h b/thirdparty/pcre2/src/pcre2.h
index 102b5d91f1..cb9d61a35b 100644
--- a/thirdparty/pcre2/src/pcre2.h
+++ b/thirdparty/pcre2/src/pcre2.h
@@ -5,7 +5,7 @@
/* This is the public header file for the PCRE library, second API, to be
#included by applications that call PCRE2 functions.
- Copyright (c) 2016-2018 University of Cambridge
+ Copyright (c) 2016-2019 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -42,9 +42,9 @@ POSSIBILITY OF SUCH DAMAGE.
/* The current PCRE version information. */
#define PCRE2_MAJOR 10
-#define PCRE2_MINOR 33
+#define PCRE2_MINOR 34
#define PCRE2_PRERELEASE
-#define PCRE2_DATE 2019-04-16
+#define PCRE2_DATE 2019-11-21
/* When an application links to a PCRE DLL in Windows, the symbols that are
imported have to be identified as such. When building PCRE2, the appropriate
@@ -142,6 +142,7 @@ D is inspected during pcre2_dfa_match() execution
#define PCRE2_USE_OFFSET_LIMIT 0x00800000u /* J M D */
#define PCRE2_EXTENDED_MORE 0x01000000u /* C */
#define PCRE2_LITERAL 0x02000000u /* C */
+#define PCRE2_MATCH_INVALID_UTF 0x04000000u /* J M D */
/* An additional compile options word is available in the compile context. */
@@ -305,6 +306,8 @@ pcre2_pattern_convert(). */
#define PCRE2_ERROR_INVALID_HYPHEN_IN_OPTIONS 194
#define PCRE2_ERROR_ALPHA_ASSERTION_UNKNOWN 195
#define PCRE2_ERROR_SCRIPT_RUN_NOT_AVAILABLE 196
+#define PCRE2_ERROR_TOO_MANY_CAPTURES 197
+#define PCRE2_ERROR_CONDITION_ATOMIC_ASSERTION_EXPECTED 198
/* "Expected" matching error codes: no match and partial match. */
@@ -390,6 +393,7 @@ released, the numbers must not be changed. */
#define PCRE2_ERROR_HEAPLIMIT (-63)
#define PCRE2_ERROR_CONVERT_SYNTAX (-64)
#define PCRE2_ERROR_INTERNAL_DUPMATCH (-65)
+#define PCRE2_ERROR_DFA_UINVALID_UTF (-66)
/* Request types for pcre2_pattern_info() */
@@ -580,7 +584,7 @@ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_bsr(pcre2_compile_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
- pcre2_set_character_tables(pcre2_compile_context *, const unsigned char *); \
+ pcre2_set_character_tables(pcre2_compile_context *, const uint8_t *); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_set_compile_extra_options(pcre2_compile_context *, uint32_t); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
@@ -675,6 +679,8 @@ PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
pcre2_match_data_free(pcre2_match_data *); \
PCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \
pcre2_get_mark(pcre2_match_data *); \
+PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
+ pcre2_get_match_data_size(pcre2_match_data *); \
PCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \
pcre2_get_ovector_count(pcre2_match_data *); \
PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
@@ -773,7 +779,8 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_get_error_message(int, PCRE2_UCHAR *, PCRE2_SIZE); \
PCRE2_EXP_DECL const uint8_t PCRE2_CALL_CONVENTION \
*pcre2_maketables(pcre2_general_context *); \
-
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_maketables_free(pcre2_general_context *, const uint8_t *);
/* Define macros that generate width-specific names from generic versions. The
three-level macro scheme is necessary to get the macros expanded when we want
@@ -838,6 +845,7 @@ pcre2_compile are called by application code. */
#define pcre2_general_context_free PCRE2_SUFFIX(pcre2_general_context_free_)
#define pcre2_get_error_message PCRE2_SUFFIX(pcre2_get_error_message_)
#define pcre2_get_mark PCRE2_SUFFIX(pcre2_get_mark_)
+#define pcre2_get_match_data_size PCRE2_SUFFIX(pcre2_get_match_data_size_)
#define pcre2_get_ovector_pointer PCRE2_SUFFIX(pcre2_get_ovector_pointer_)
#define pcre2_get_ovector_count PCRE2_SUFFIX(pcre2_get_ovector_count_)
#define pcre2_get_startchar PCRE2_SUFFIX(pcre2_get_startchar_)
@@ -848,6 +856,7 @@ pcre2_compile are called by application code. */
#define pcre2_jit_stack_create PCRE2_SUFFIX(pcre2_jit_stack_create_)
#define pcre2_jit_stack_free PCRE2_SUFFIX(pcre2_jit_stack_free_)
#define pcre2_maketables PCRE2_SUFFIX(pcre2_maketables_)
+#define pcre2_maketables_free PCRE2_SUFFIX(pcre2_maketables_free_)
#define pcre2_match PCRE2_SUFFIX(pcre2_match_)
#define pcre2_match_context_copy PCRE2_SUFFIX(pcre2_match_context_copy_)
#define pcre2_match_context_create PCRE2_SUFFIX(pcre2_match_context_create_)
diff --git a/thirdparty/pcre2/src/pcre2_auto_possess.c b/thirdparty/pcre2/src/pcre2_auto_possess.c
index 6d7b7c4a4d..5b95b9b8a8 100644
--- a/thirdparty/pcre2/src/pcre2_auto_possess.c
+++ b/thirdparty/pcre2/src/pcre2_auto_possess.c
@@ -624,6 +624,13 @@ for(;;)
case OP_ASSERTBACK_NOT:
case OP_ONCE:
return !entered_a_group;
+
+ /* Non-atomic assertions - don't possessify last iterator. This needs
+ more thought. */
+
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
+ return FALSE;
}
/* Skip over the bracket and inspect what comes next. */
diff --git a/thirdparty/pcre2/src/pcre2_compile.c b/thirdparty/pcre2/src/pcre2_compile.c
index 068735ae8e..f2e6b6b5bd 100644
--- a/thirdparty/pcre2/src/pcre2_compile.c
+++ b/thirdparty/pcre2/src/pcre2_compile.c
@@ -135,6 +135,9 @@ static BOOL
set_lookbehind_lengths(uint32_t **, int *, int *, parsed_recurse_check *,
compile_block *);
+static int
+ check_lookbehinds(uint32_t *, uint32_t **, parsed_recurse_check *,
+ compile_block *);
/*************************************************
@@ -250,36 +253,41 @@ is present where expected in a conditional group. */
#define META_LOOKBEHIND 0x80250000u /* (?<= */
#define META_LOOKBEHINDNOT 0x80260000u /* (?<! */
+/* These cannot be conditions */
+
+#define META_LOOKAHEAD_NA 0x80270000u /* (*napla: */
+#define META_LOOKBEHIND_NA 0x80280000u /* (*naplb: */
+
/* These must be kept in this order, with consecutive values, and the _ARG
versions of COMMIT, PRUNE, SKIP, and THEN immediately after their non-argument
versions. */
-#define META_MARK 0x80270000u /* (*MARK) */
-#define META_ACCEPT 0x80280000u /* (*ACCEPT) */
-#define META_FAIL 0x80290000u /* (*FAIL) */
-#define META_COMMIT 0x802a0000u /* These */
-#define META_COMMIT_ARG 0x802b0000u /* pairs */
-#define META_PRUNE 0x802c0000u /* must */
-#define META_PRUNE_ARG 0x802d0000u /* be */
-#define META_SKIP 0x802e0000u /* kept */
-#define META_SKIP_ARG 0x802f0000u /* in */
-#define META_THEN 0x80300000u /* this */
-#define META_THEN_ARG 0x80310000u /* order */
+#define META_MARK 0x80290000u /* (*MARK) */
+#define META_ACCEPT 0x802a0000u /* (*ACCEPT) */
+#define META_FAIL 0x802b0000u /* (*FAIL) */
+#define META_COMMIT 0x802c0000u /* These */
+#define META_COMMIT_ARG 0x802d0000u /* pairs */
+#define META_PRUNE 0x802e0000u /* must */
+#define META_PRUNE_ARG 0x802f0000u /* be */
+#define META_SKIP 0x80300000u /* kept */
+#define META_SKIP_ARG 0x80310000u /* in */
+#define META_THEN 0x80320000u /* this */
+#define META_THEN_ARG 0x80330000u /* order */
/* These must be kept in groups of adjacent 3 values, and all together. */
-#define META_ASTERISK 0x80320000u /* * */
-#define META_ASTERISK_PLUS 0x80330000u /* *+ */
-#define META_ASTERISK_QUERY 0x80340000u /* *? */
-#define META_PLUS 0x80350000u /* + */
-#define META_PLUS_PLUS 0x80360000u /* ++ */
-#define META_PLUS_QUERY 0x80370000u /* +? */
-#define META_QUERY 0x80380000u /* ? */
-#define META_QUERY_PLUS 0x80390000u /* ?+ */
-#define META_QUERY_QUERY 0x803a0000u /* ?? */
-#define META_MINMAX 0x803b0000u /* {n,m} repeat */
-#define META_MINMAX_PLUS 0x803c0000u /* {n,m}+ repeat */
-#define META_MINMAX_QUERY 0x803d0000u /* {n,m}? repeat */
+#define META_ASTERISK 0x80340000u /* * */
+#define META_ASTERISK_PLUS 0x80350000u /* *+ */
+#define META_ASTERISK_QUERY 0x80360000u /* *? */
+#define META_PLUS 0x80370000u /* + */
+#define META_PLUS_PLUS 0x80380000u /* ++ */
+#define META_PLUS_QUERY 0x80390000u /* +? */
+#define META_QUERY 0x803a0000u /* ? */
+#define META_QUERY_PLUS 0x803b0000u /* ?+ */
+#define META_QUERY_QUERY 0x803c0000u /* ?? */
+#define META_MINMAX 0x803d0000u /* {n,m} repeat */
+#define META_MINMAX_PLUS 0x803e0000u /* {n,m}+ repeat */
+#define META_MINMAX_QUERY 0x803f0000u /* {n,m}? repeat */
#define META_FIRST_QUANTIFIER META_ASTERISK
#define META_LAST_QUANTIFIER META_MINMAX_QUERY
@@ -335,6 +343,8 @@ static unsigned char meta_extra_lengths[] = {
0, /* META_LOOKAHEADNOT */
SIZEOFFSET, /* META_LOOKBEHIND */
SIZEOFFSET, /* META_LOOKBEHINDNOT */
+ 0, /* META_LOOKAHEAD_NA */
+ SIZEOFFSET, /* META_LOOKBEHIND_NA */
1, /* META_MARK - plus the string length */
0, /* META_ACCEPT */
0, /* META_FAIL */
@@ -634,10 +644,14 @@ typedef struct alasitem {
static const char alasnames[] =
STRING_pla0
STRING_plb0
+ STRING_napla0
+ STRING_naplb0
STRING_nla0
STRING_nlb0
STRING_positive_lookahead0
STRING_positive_lookbehind0
+ STRING_non_atomic_positive_lookahead0
+ STRING_non_atomic_positive_lookbehind0
STRING_negative_lookahead0
STRING_negative_lookbehind0
STRING_atomic0
@@ -649,10 +663,14 @@ static const char alasnames[] =
static const alasitem alasmeta[] = {
{ 3, META_LOOKAHEAD },
{ 3, META_LOOKBEHIND },
+ { 5, META_LOOKAHEAD_NA },
+ { 5, META_LOOKBEHIND_NA },
{ 3, META_LOOKAHEADNOT },
{ 3, META_LOOKBEHINDNOT },
{ 18, META_LOOKAHEAD },
{ 19, META_LOOKBEHIND },
+ { 29, META_LOOKAHEAD_NA },
+ { 30, META_LOOKBEHIND_NA },
{ 18, META_LOOKAHEADNOT },
{ 19, META_LOOKBEHINDNOT },
{ 6, META_ATOMIC },
@@ -746,8 +764,8 @@ are allowed. */
#define PUBLIC_LITERAL_COMPILE_OPTIONS \
(PCRE2_ANCHORED|PCRE2_AUTO_CALLOUT|PCRE2_CASELESS|PCRE2_ENDANCHORED| \
- PCRE2_FIRSTLINE|PCRE2_LITERAL|PCRE2_NO_START_OPTIMIZE| \
- PCRE2_NO_UTF_CHECK|PCRE2_USE_OFFSET_LIMIT|PCRE2_UTF)
+ PCRE2_FIRSTLINE|PCRE2_LITERAL|PCRE2_MATCH_INVALID_UTF| \
+ PCRE2_NO_START_OPTIMIZE|PCRE2_NO_UTF_CHECK|PCRE2_USE_OFFSET_LIMIT|PCRE2_UTF)
#define PUBLIC_COMPILE_OPTIONS \
(PUBLIC_LITERAL_COMPILE_OPTIONS| \
@@ -781,7 +799,7 @@ enum { ERR0 = COMPILE_ERROR_BASE,
ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70,
ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80,
ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90,
- ERR91, ERR92, ERR93, ERR94, ERR95, ERR96 };
+ ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98 };
/* This is a table of start-of-pattern options such as (*UTF) and settings such
as (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward
@@ -1012,6 +1030,7 @@ for (;;)
case META_NOCAPTURE: fprintf(stderr, "META (?:"); break;
case META_LOOKAHEAD: fprintf(stderr, "META (?="); break;
case META_LOOKAHEADNOT: fprintf(stderr, "META (?!"); break;
+ case META_LOOKAHEAD_NA: fprintf(stderr, "META (*napla:"); break;
case META_SCRIPT_RUN: fprintf(stderr, "META (*sr:"); break;
case META_KET: fprintf(stderr, "META )"); break;
case META_ALT: fprintf(stderr, "META | %d", meta_arg); break;
@@ -1043,6 +1062,12 @@ for (;;)
fprintf(stderr, "%zd", offset);
break;
+ case META_LOOKBEHIND_NA:
+ fprintf(stderr, "META (*naplb: %d offset=", meta_arg);
+ GETOFFSET(offset, pptr);
+ fprintf(stderr, "%zd", offset);
+ break;
+
case META_LOOKBEHINDNOT:
fprintf(stderr, "META (?<! %d offset=", meta_arg);
GETOFFSET(offset, pptr);
@@ -1419,9 +1444,6 @@ the result is "not a repeat quantifier". */
EXIT:
if (yield || *errorcodeptr != 0) *ptrptr = p;
return yield;
-
-
-
}
@@ -2450,8 +2472,9 @@ must be last. */
enum { RANGE_NO, RANGE_STARTED, RANGE_OK_ESCAPED, RANGE_OK_LITERAL };
-/* Only in 32-bit mode can there be literals > META_END. A macros encapsulates
-the storing of literal values in the parsed pattern. */
+/* Only in 32-bit mode can there be literals > META_END. A macro encapsulates
+the storing of literal values in the main parsed pattern, where they can always
+be quantified. */
#if PCRE2_CODE_UNIT_WIDTH == 32
#define PARSED_LITERAL(c, p) \
@@ -2474,6 +2497,7 @@ uint32_t delimiter;
uint32_t namelen;
uint32_t class_range_state;
uint32_t *verblengthptr = NULL; /* Value avoids compiler warning */
+uint32_t *verbstartptr = NULL;
uint32_t *previous_callout = NULL;
uint32_t *parsed_pattern = cb->parsed_pattern;
uint32_t *parsed_pattern_end = cb->parsed_pattern_end;
@@ -2600,10 +2624,20 @@ while (ptr < ptrend)
errorcode = ERR28;
goto FAILED;
}
- if (!inverbname && after_manual_callout-- <= 0)
- parsed_pattern = manage_callouts(thisptr, &previous_callout,
- auto_callout, parsed_pattern, cb);
- PARSED_LITERAL(c, parsed_pattern);
+ if (inverbname)
+ { /* Don't use PARSED_LITERAL() because it */
+#if PCRE2_CODE_UNIT_WIDTH == 32 /* sets okquantifier. */
+ if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;
+#endif
+ *parsed_pattern++ = c;
+ }
+ else
+ {
+ if (after_manual_callout-- <= 0)
+ parsed_pattern = manage_callouts(thisptr, &previous_callout,
+ auto_callout, parsed_pattern, cb);
+ PARSED_LITERAL(c, parsed_pattern);
+ }
meta_quantifier = 0;
}
continue; /* Next character */
@@ -2640,13 +2674,15 @@ while (ptr < ptrend)
switch(c)
{
- default:
- PARSED_LITERAL(c, parsed_pattern);
+ default: /* Don't use PARSED_LITERAL() because it */
+#if PCRE2_CODE_UNIT_WIDTH == 32 /* sets okquantifier. */
+ if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;
+#endif
+ *parsed_pattern++ = c;
break;
case CHAR_RIGHT_PARENTHESIS:
inverbname = FALSE;
- okquantifier = FALSE; /* Was probably set by literals */
/* This is the length in characters */
verbnamelength = (PCRE2_SIZE)(parsed_pattern - verblengthptr - 1);
/* But the limit on the length is in code units */
@@ -2680,8 +2716,11 @@ while (ptr < ptrend)
switch(escape)
{
- case 0:
- PARSED_LITERAL(c, parsed_pattern);
+ case 0: /* Don't use PARSED_LITERAL() because it */
+#if PCRE2_CODE_UNIT_WIDTH == 32 /* sets okquantifier. */
+ if (c >= META_END) *parsed_pattern++ = META_BIGVALUE;
+#endif
+ *parsed_pattern++ = c;
break;
case ESC_Q:
@@ -3135,6 +3174,21 @@ while (ptr < ptrend)
goto FAILED_BACK;
}
+ /* Most (*VERB)s are not allowed to be quantified, but an ungreedy
+ quantifier can be useful for (*ACCEPT) - meaning "succeed on backtrack", a
+ sort of negated (*COMMIT). We therefore allow (*ACCEPT) to be quantified by
+ wrapping it in non-capturing brackets, but we have to allow for a preceding
+ (*MARK) for when (*ACCEPT) has an argument. */
+
+ if (parsed_pattern[-1] == META_ACCEPT)
+ {
+ uint32_t *p;
+ for (p = parsed_pattern - 1; p >= verbstartptr; p--) p[1] = p[0];
+ *verbstartptr = META_NOCAPTURE;
+ parsed_pattern[1] = META_KET;
+ parsed_pattern += 2;
+ }
+
/* Now we can put the quantifier into the parsed pattern vector. At this
stage, we have only the basic quantifier. The check for a following + or ?
modifier happens at the top of the loop, after any intervening comments
@@ -3581,6 +3635,8 @@ while (ptr < ptrend)
if (c == CHAR_RIGHT_SQUARE_BRACKET && !inescq) break;
} /* End of class-processing loop */
+ /* -] at the end of a class is a literal '-' */
+
if (class_range_state == RANGE_STARTED)
{
parsed_pattern[-1] = CHAR_MINUS;
@@ -3611,6 +3667,11 @@ while (ptr < ptrend)
nest_depth++;
if ((options & PCRE2_NO_AUTO_CAPTURE) == 0)
{
+ if (cb->bracount >= MAX_GROUP_NUMBER)
+ {
+ errorcode = ERR97;
+ goto FAILED;
+ }
cb->bracount++;
*parsed_pattern++ = META_CAPTURE | cb->bracount;
}
@@ -3658,19 +3719,20 @@ while (ptr < ptrend)
goto FAILED;
}
- /* Check for expecting an assertion condition. If so, only lookaround
- assertions are valid. */
+ /* Check for expecting an assertion condition. If so, only atomic
+ lookaround assertions are valid. */
meta = alasmeta[i].meta;
if (prev_expect_cond_assert > 0 &&
(meta < META_LOOKAHEAD || meta > META_LOOKBEHINDNOT))
{
- errorcode = ERR28; /* Assertion expected */
+ errorcode = (meta == META_LOOKAHEAD_NA || meta == META_LOOKBEHIND_NA)?
+ ERR98 : ERR28; /* (Atomic) assertion expected */
goto FAILED;
}
- /* The lookaround alphabetic synonyms can be almost entirely handled by
- jumping to the code that handles the traditional symbolic forms. */
+ /* The lookaround alphabetic synonyms can mostly be handled by jumping
+ to the code that handles the traditional symbolic forms. */
switch(meta)
{
@@ -3684,11 +3746,17 @@ while (ptr < ptrend)
case META_LOOKAHEAD:
goto POSITIVE_LOOK_AHEAD;
+ case META_LOOKAHEAD_NA:
+ *parsed_pattern++ = meta;
+ ptr++;
+ goto POST_ASSERTION;
+
case META_LOOKAHEADNOT:
goto NEGATIVE_LOOK_AHEAD;
case META_LOOKBEHIND:
case META_LOOKBEHINDNOT:
+ case META_LOOKBEHIND_NA:
*parsed_pattern++ = meta;
ptr--;
goto POST_LOOKBEHIND;
@@ -3770,6 +3838,12 @@ while (ptr < ptrend)
goto FAILED;
}
+ /* Remember where this verb, possibly with a preceding (*MARK), starts,
+ for handling quantified (*ACCEPT). */
+
+ verbstartptr = parsed_pattern;
+ okquantifier = (verbs[i].meta == META_ACCEPT);
+
/* It appears that Perl allows any characters whatsoever, other than a
closing parenthesis, to appear in arguments ("names"), so we no longer
insist on letters, digits, and underscores. Perl does not, however, do
@@ -4386,7 +4460,7 @@ while (ptr < ptrend)
*parsed_pattern++ = (ptr[1] == CHAR_EQUALS_SIGN)?
META_LOOKBEHIND : META_LOOKBEHINDNOT;
- POST_LOOKBEHIND: /* Come from (*plb: and (*nlb: */
+ POST_LOOKBEHIND: /* Come from (*plb: (*naplb: and (*nlb: */
*has_lookbehind = TRUE;
offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2);
PUTOFFSET(offset, parsed_pattern);
@@ -4435,6 +4509,11 @@ while (ptr < ptrend)
/* We have a name for this capturing group. It is also assigned a number,
which is its primary means of identification. */
+ if (cb->bracount >= MAX_GROUP_NUMBER)
+ {
+ errorcode = ERR97;
+ goto FAILED;
+ }
cb->bracount++;
*parsed_pattern++ = META_CAPTURE | cb->bracount;
nest_depth++;
@@ -4661,6 +4740,7 @@ for (;;)
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
+ case OP_ASSERTBACK_NA:
if (!skipassert) return code;
do code += GET(code, 1); while (*code == OP_ALT);
code += PRIV(OP_lengths)[*code];
@@ -5221,8 +5301,10 @@ PCRE2_UCHAR *tempcode;
PCRE2_UCHAR *previous = NULL;
PCRE2_UCHAR op_previous;
BOOL groupsetfirstcu = FALSE;
+BOOL had_accept = FALSE;
BOOL matched_char = FALSE;
BOOL previous_matched_char = FALSE;
+BOOL reset_caseful = FALSE;
const uint8_t *cbits = cb->cbits;
uint8_t classbits[32];
@@ -5355,7 +5437,7 @@ for (;; pptr++)
if (meta < META_ASTERISK || meta > META_MINMAX_QUERY)
{
previous = code;
- if (matched_char) okreturn = 1;
+ if (matched_char && !had_accept) okreturn = 1;
}
previous_matched_char = matched_char;
@@ -5499,7 +5581,45 @@ for (;; pptr++)
} /* End of 1-char optimization */
/* Handle character classes that contain more than just one literal
- character. */
+ character. If there are exactly two characters in a positive class, see if
+ they are case partners. This can be optimized to generate a caseless single
+ character match (which also sets first/required code units if relevant). */
+
+ if (meta == META_CLASS && pptr[1] < META_END && pptr[2] < META_END &&
+ pptr[3] == META_CLASS_END)
+ {
+ uint32_t c = pptr[1];
+
+#ifdef SUPPORT_UNICODE
+ if (UCD_CASESET(c) == 0)
+#endif
+ {
+ uint32_t d;
+
+#ifdef SUPPORT_UNICODE
+ if (utf && c > 127) d = UCD_OTHERCASE(c); else
+#endif
+ {
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ if (c > 255) d = c; else
+#endif
+ d = TABLE_GET(c, cb->fcc, c);
+ }
+
+ if (c != d && pptr[2] == d)
+ {
+ pptr += 3; /* Move on to class end */
+ meta = c;
+ if ((options & PCRE2_CASELESS) == 0)
+ {
+ reset_caseful = TRUE;
+ options |= PCRE2_CASELESS;
+ req_caseopt = REQ_CASELESS;
+ }
+ goto CLASS_CASELESS_CHAR;
+ }
+ }
+ }
/* If a non-extended class contains a negative special such as \S, we need
to flip the negation flag at the end, so that support for characters > 255
@@ -5994,7 +6114,7 @@ for (;; pptr++)
workspace overflow. Do not set firstcu after *ACCEPT. */
case META_ACCEPT:
- cb->had_accept = TRUE;
+ cb->had_accept = had_accept = TRUE;
for (oc = cb->open_caps;
oc != NULL && oc->assert_depth >= cb->assert_depth;
oc = oc->next)
@@ -6252,6 +6372,11 @@ for (;; pptr++)
cb->assert_depth += 1;
goto GROUP_PROCESS;
+ case META_LOOKAHEAD_NA:
+ bravalue = OP_ASSERT_NA;
+ cb->assert_depth += 1;
+ goto GROUP_PROCESS;
+
/* Optimize (?!) to (*FAIL) unless it is quantified - which is a weird
thing to do, but Perl allows all assertions to be quantified, and when
they contain capturing parentheses there may be a potential use for
@@ -6283,6 +6408,11 @@ for (;; pptr++)
cb->assert_depth += 1;
goto GROUP_PROCESS;
+ case META_LOOKBEHIND_NA:
+ bravalue = OP_ASSERTBACK_NA;
+ cb->assert_depth += 1;
+ goto GROUP_PROCESS;
+
case META_ATOMIC:
bravalue = OP_ONCE;
goto GROUP_PROCESS_NOTE_EMPTY;
@@ -6341,7 +6471,7 @@ for (;; pptr++)
/* If we've just compiled an assertion, pop the assert depth. */
- if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT)
+ if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NA)
cb->assert_depth -= 1;
/* At the end of compiling, code is still pointing to the start of the
@@ -6491,8 +6621,8 @@ for (;; pptr++)
we must only take the reqcu when the group also set a firstcu. Otherwise,
in that example, 'X' ends up set for both. */
- else if (bravalue == OP_ASSERT && subreqcuflags >= 0 &&
- subfirstcuflags >= 0)
+ else if ((bravalue == OP_ASSERT || bravalue == OP_ASSERT_NA) &&
+ subreqcuflags >= 0 && subfirstcuflags >= 0)
{
reqcu = subreqcu;
reqcuflags = subreqcuflags;
@@ -6713,10 +6843,6 @@ for (;; pptr++)
reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;
op_type = 0;
- /* If the repeat is {1} we can ignore it. */
-
- if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;
-
/* Adjust first and required code units for a zero repeat. */
if (repeat_min == 0)
@@ -6759,7 +6885,10 @@ for (;; pptr++)
tempcode = previous;
op_previous = *previous;
- /* Now handle repetition for the different types of item. */
+ /* Now handle repetition for the different types of item. If the repeat
+ minimum and the repeat maximum are both 1, we can ignore the quantifier for
+ non-parenthesized items, as they have only one alternative. For anything in
+ parentheses, we must not ignore if {1} is possessive. */
switch (op_previous)
{
@@ -6773,6 +6902,7 @@ for (;; pptr++)
case OP_CHARI:
case OP_NOT:
case OP_NOTI:
+ if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;
op_type = chartypeoffset[op_previous - OP_CHAR];
/* Deal with UTF characters that take up more than one code unit. */
@@ -6819,6 +6949,7 @@ for (;; pptr++)
code = previous;
goto END_REPEAT;
}
+ if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;
if (repeat_min == 0 && repeat_max == REPEAT_UNLIMITED)
*code++ = OP_CRSTAR + repeat_type;
@@ -6853,6 +6984,8 @@ for (;; pptr++)
repetition. */
case OP_RECURSE:
+ if (repeat_max == 1 && repeat_min == 1 && !possessive_quantifier)
+ goto END_REPEAT;
/* Generate unwrapped repeats for a non-zero minimum, except when the
minimum is 1 and the maximum unlimited, because that can be handled with
@@ -6923,8 +7056,10 @@ for (;; pptr++)
case OP_ASSERT:
case OP_ASSERT_NOT:
+ case OP_ASSERT_NA:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
+ case OP_ASSERTBACK_NA:
case OP_ONCE:
case OP_SCRIPT_RUN:
case OP_BRA:
@@ -6935,6 +7070,9 @@ for (;; pptr++)
PCRE2_UCHAR *bralink = NULL;
PCRE2_UCHAR *brazeroptr = NULL;
+ if (repeat_max == 1 && repeat_min == 1 && !possessive_quantifier)
+ goto END_REPEAT;
+
/* Repeating a DEFINE group (or any group where the condition is always
FALSE and there is only one branch) is pointless, but Perl allows the
syntax, so we just ignore the repeat. */
@@ -7151,11 +7289,12 @@ for (;; pptr++)
and SCRIPT_RUN groups at runtime, but in a different way.]
Then, if the quantifier was possessive and the bracket is not a
- conditional, we convert the BRA code to the POS form, and the KET code to
- KETRPOS. (It turns out to be convenient at runtime to detect this kind of
- subpattern at both the start and at the end.) The use of special opcodes
- makes it possible to reduce greatly the stack usage in pcre2_match(). If
- the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO.
+ conditional, we convert the BRA code to the POS form, and the KET code
+ to KETRPOS. (It turns out to be convenient at runtime to detect this
+ kind of subpattern at both the start and at the end.) The use of
+ special opcodes makes it possible to reduce greatly the stack usage in
+ pcre2_match(). If the group is preceded by OP_BRAZERO, convert this to
+ OP_BRAPOSZERO.
Then, if the minimum number of matches is 1 or 0, cancel the possessive
flag so that the default action below, of wrapping everything inside
@@ -7256,6 +7395,8 @@ for (;; pptr++)
int prop_type, prop_value;
PCRE2_UCHAR *oldcode;
+ if (repeat_max == 1 && repeat_min == 1) goto END_REPEAT;
+
op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */
mclength = 0; /* Not a character */
@@ -7718,9 +7859,15 @@ for (;; pptr++)
}
#endif
- /* Caseful matches, or not one of the multicase characters. Get the
- character's code units into mcbuffer, with the length in mclength. When not
- in UTF mode, the length is always 1. */
+ /* Caseful matches, or caseless and not one of the multicase characters. We
+ come here by goto in the case of a positive class that contains only
+ case-partners of a character with just two cases; matched_char has already
+ been set TRUE and options fudged if necessary. */
+
+ CLASS_CASELESS_CHAR:
+
+ /* Get the character's code units into mcbuffer, with the length in
+ mclength. When not in UTF mode, the length is always 1. */
#ifdef SUPPORT_UNICODE
if (utf) mclength = PRIV(ord2utf)(meta, mcbuffer); else
@@ -7752,8 +7899,9 @@ for (;; pptr++)
zeroreqcu = reqcu;
zeroreqcuflags = reqcuflags;
- /* If the character is more than one code unit long, we can set firstcu
- only if it is not to be matched caselessly. */
+ /* If the character is more than one code unit long, we can set a single
+ firstcu only if it is not to be matched caselessly. Multiple possible
+ starting code units may be picked up later in the studying code. */
if (mclength == 1 || req_caseopt == 0)
{
@@ -7783,7 +7931,17 @@ for (;; pptr++)
reqcuflags = req_caseopt | cb->req_varyopt;
}
}
- break; /* End default meta handling */
+
+ /* If caselessness was temporarily instated, reset it. */
+
+ if (reset_caseful)
+ {
+ options &= ~PCRE2_CASELESS;
+ req_caseopt = 0;
+ reset_caseful = FALSE;
+ }
+
+ break; /* End literal character handling */
} /* End of big switch */
} /* End of big loop */
@@ -7874,7 +8032,10 @@ length = 2 + 2*LINK_SIZE + skipunits;
/* Remember if this is a lookbehind assertion, and if it is, save its length
and skip over the pattern offset. */
-lookbehind = *code == OP_ASSERTBACK || *code == OP_ASSERTBACK_NOT;
+lookbehind = *code == OP_ASSERTBACK ||
+ *code == OP_ASSERTBACK_NOT ||
+ *code == OP_ASSERTBACK_NA;
+
if (lookbehind)
{
lookbehindlength = META_DATA(pptr[-1]);
@@ -7948,7 +8109,7 @@ for (;;)
/* If this is not the first branch, the first char and reqcu have to
match the values from all the previous branches, except that if the
previous value for reqcu didn't have REQ_VARY set, it can still match,
- and we set REQ_VARY for the regex. */
+ and we set REQ_VARY for the group from this branch's value. */
else
{
@@ -7987,7 +8148,7 @@ for (;;)
else
{
reqcu = branchreqcu;
- reqcuflags |= branchreqcuflags; /* To "or" REQ_VARY */
+ reqcuflags |= branchreqcuflags; /* To "or" REQ_VARY if present */
}
}
}
@@ -8167,7 +8328,7 @@ do {
/* Positive forward assertion */
- else if (op == OP_ASSERT)
+ else if (op == OP_ASSERT || op == OP_ASSERT_NA)
{
if (!is_anchored(scode, bracket_map, cb, atomcount, TRUE)) return FALSE;
}
@@ -8305,7 +8466,7 @@ do {
/* Positive forward assertions */
- else if (op == OP_ASSERT)
+ else if (op == OP_ASSERT || op == OP_ASSERT_NA)
{
if (!is_startline(scode, bracket_map, cb, atomcount, TRUE))
return FALSE;
@@ -8547,9 +8708,11 @@ do {
case OP_CBRAPOS:
case OP_SCBRAPOS:
case OP_ASSERT:
+ case OP_ASSERT_NA:
case OP_ONCE:
case OP_SCRIPT_RUN:
- d = find_firstassertedcu(scode, &dflags, inassert + ((op==OP_ASSERT)?1:0));
+ d = find_firstassertedcu(scode, &dflags, inassert +
+ ((op == OP_ASSERT || op == OP_ASSERT_NA)?1:0));
if (dflags < 0)
return 0;
if (cflags < 0) { c = d; cflags = dflags; }
@@ -8578,6 +8741,19 @@ do {
case OP_MINPLUSI:
case OP_POSPLUSI:
if (inassert == 0) return 0;
+
+ /* If the character is more than one code unit long, we cannot set its
+ first code unit when matching caselessly. Later scanning may pick up
+ multiple code units. */
+
+#ifdef SUPPORT_UNICODE
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (scode[1] >= 0x80) return 0;
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+ if (scode[1] >= 0xd800 && scode[1] <= 0xdfff) return 0;
+#endif
+#endif
+
if (cflags < 0) { c = scode[1]; cflags = REQ_CASELESS; }
else if (c != scode[1]) return 0;
break;
@@ -8745,8 +8921,10 @@ for (;; pptr++)
case META_COND_VERSION:
case META_LOOKAHEAD:
case META_LOOKAHEADNOT:
+ case META_LOOKAHEAD_NA:
case META_LOOKBEHIND:
case META_LOOKBEHINDNOT:
+ case META_LOOKBEHIND_NA:
case META_NOCAPTURE:
case META_SCRIPT_RUN:
nestlevel++;
@@ -8798,7 +8976,7 @@ Returns: the group length or a negative number
static int
get_grouplength(uint32_t **pptrptr, BOOL isinline, int *errcodeptr, int *lcptr,
- int group, parsed_recurse_check *recurses, compile_block *cb)
+ int group, parsed_recurse_check *recurses, compile_block *cb)
{
int branchlength;
int grouplength = -1;
@@ -8847,8 +9025,7 @@ return -1;
*************************************************/
/* Return a fixed length for a branch in a lookbehind, giving an error if the
-length is not fixed. If any lookbehinds are encountered on the way, they get
-their length set. On entry, *pptrptr points to the first element inside the
+length is not fixed. On entry, *pptrptr points to the first element inside the
branch. On exit it is set to point to the ALT or KET.
Arguments:
@@ -8978,15 +9155,16 @@ for (;; pptr++)
}
break;
- /* Lookaheads can be ignored, but we must start the skip inside the group
- so that it isn't treated as a group within the branch. */
+ /* Lookaheads do not contribute to the length of this branch, but they may
+ contain lookbehinds within them whose lengths need to be set. */
case META_LOOKAHEAD:
case META_LOOKAHEADNOT:
- pptr = parsed_skip(pptr + 1, PSKIP_KET);
- if (pptr == NULL) goto PARSED_SKIP_FAILED;
+ case META_LOOKAHEAD_NA:
+ *errcodeptr = check_lookbehinds(pptr + 1, &pptr, recurses, cb);
+ if (*errcodeptr != 0) return -1;
- /* Also ignore any qualifiers that follow a lookahead assertion. */
+ /* Ignore any qualifiers that follow a lookahead assertion. */
switch (pptr[1])
{
@@ -9013,10 +9191,12 @@ for (;; pptr++)
}
break;
- /* Lookbehinds can be ignored, but must themselves be checked. */
+ /* A nested lookbehind does not contribute any length to this lookbehind,
+ but must itself be checked and have its lengths set. */
case META_LOOKBEHIND:
case META_LOOKBEHINDNOT:
+ case META_LOOKBEHIND_NA:
if (!set_lookbehind_lengths(&pptr, errcodeptr, lcptr, recurses, cb))
return -1;
break;
@@ -9178,8 +9358,26 @@ for (;; pptr++)
case META_MINMAX_QUERY:
if (pptr[1] == pptr[2])
{
- if (pptr[1] == 0) branchlength -= lastitemlength;
- else itemlength = (pptr[1] - 1) * lastitemlength;
+ switch(pptr[1])
+ {
+ case 0:
+ branchlength -= lastitemlength;
+ break;
+
+ case 1:
+ itemlength = 0;
+ break;
+
+ default: /* Check for integer overflow */
+ if (lastitemlength != 0 && /* Should not occur, but just in case */
+ INT_MAX/lastitemlength < pptr[1] - 1)
+ {
+ *errcodeptr = ERR87; /* Integer overflow; lookbehind too big */
+ return -1;
+ }
+ itemlength = (pptr[1] - 1) * lastitemlength;
+ break;
+ }
pptr += 2;
break;
}
@@ -9193,24 +9391,23 @@ for (;; pptr++)
return -1;
}
- /* Add the item length to the branchlength, and save it for use if the next
- thing is a quantifier. */
-
- branchlength += itemlength;
- lastitemlength = itemlength;
-
- /* Ensure that the length does not overflow the limit. */
+ /* Add the item length to the branchlength, checking for integer overflow and
+ for the branch length exceeding the limit. */
- if (branchlength > LOOKBEHIND_MAX)
+ if (INT_MAX - branchlength < (int)itemlength ||
+ (branchlength += itemlength) > LOOKBEHIND_MAX)
{
*errcodeptr = ERR87;
return -1;
}
+
+ /* Save this item length for use if the next item is a quantifier. */
+
+ lastitemlength = itemlength;
}
EXIT:
*pptrptr = pptr;
-if (branchlength > cb->max_lookbehind) cb->max_lookbehind = branchlength;
return branchlength;
PARSED_SKIP_FAILED:
@@ -9229,6 +9426,11 @@ branches. An error occurs if any branch does not have a fixed length that is
less than the maximum (65535). On exit, the pointer must be left on the final
ket.
+The function also maintains the max_lookbehind value. Any lookbehind branch
+that contains a nested lookbehind may actually look further back than the
+length of the branch. The additional amount is passed back from
+get_branchlength() as an "extra" value.
+
Arguments:
pptrptr pointer to pointer in the parsed pattern
errcodeptr pointer to error code
@@ -9262,6 +9464,7 @@ do
if (cb->erroroffset == PCRE2_UNSET) cb->erroroffset = offset;
return FALSE;
}
+ if (branchlength > cb->max_lookbehind) cb->max_lookbehind = branchlength;
*bptr |= branchlength; /* branchlength never more than 65535 */
bptr = *pptrptr;
}
@@ -9282,20 +9485,30 @@ set_lookbehind_lengths() for each one. At the start, the errorcode is zero and
the error offset is marked unset. The enables the functions above not to
override settings from deeper nestings.
-Arguments cb points to the compile block
-Returns: 0 on success, or an errorcode (cb->erroroffset will be set)
+This function is called recursively from get_branchlength() for lookaheads in
+order to process any lookbehinds that they may contain. It stops when it hits a
+non-nested closing parenthesis in this case, returning a pointer to it.
+
+Arguments
+ pptr points to where to start (start of pattern or start of lookahead)
+ retptr if not NULL, return the ket pointer here
+ recurses chain of recurse_check to catch mutual recursion
+ cb points to the compile block
+
+Returns: 0 on success, or an errorcode (cb->erroroffset will be set)
*/
static int
-check_lookbehinds(compile_block *cb)
+check_lookbehinds(uint32_t *pptr, uint32_t **retptr,
+ parsed_recurse_check *recurses, compile_block *cb)
{
-uint32_t *pptr;
int errorcode = 0;
int loopcount = 0;
+int nestlevel = 0;
cb->erroroffset = PCRE2_UNSET;
-for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++)
+for (; *pptr != META_END; pptr++)
{
if (*pptr < META_END) continue; /* Literal */
@@ -9309,14 +9522,31 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++)
pptr += 1;
break;
+ case META_KET:
+ if (--nestlevel < 0)
+ {
+ if (retptr != NULL) *retptr = pptr;
+ return 0;
+ }
+ break;
+
+ case META_ATOMIC:
+ case META_CAPTURE:
+ case META_COND_ASSERT:
+ case META_LOOKAHEAD:
+ case META_LOOKAHEADNOT:
+ case META_LOOKAHEAD_NA:
+ case META_NOCAPTURE:
+ case META_SCRIPT_RUN:
+ nestlevel++;
+ break;
+
case META_ACCEPT:
case META_ALT:
case META_ASTERISK:
case META_ASTERISK_PLUS:
case META_ASTERISK_QUERY:
- case META_ATOMIC:
case META_BACKREF:
- case META_CAPTURE:
case META_CIRCUMFLEX:
case META_CLASS:
case META_CLASS_EMPTY:
@@ -9324,14 +9554,9 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++)
case META_CLASS_END:
case META_CLASS_NOT:
case META_COMMIT:
- case META_COND_ASSERT:
case META_DOLLAR:
case META_DOT:
case META_FAIL:
- case META_KET:
- case META_LOOKAHEAD:
- case META_LOOKAHEADNOT:
- case META_NOCAPTURE:
case META_PLUS:
case META_PLUS_PLUS:
case META_PLUS_QUERY:
@@ -9341,7 +9566,6 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++)
case META_QUERY_QUERY:
case META_RANGE_ESCAPED:
case META_RANGE_LITERAL:
- case META_SCRIPT_RUN:
case META_SKIP:
case META_THEN:
break;
@@ -9351,13 +9575,22 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++)
break;
case META_BACKREF_BYNAME:
+ case META_RECURSE_BYNAME:
+ pptr += 1 + SIZEOFFSET;
+ break;
+
case META_COND_DEFINE:
case META_COND_NAME:
case META_COND_NUMBER:
case META_COND_RNAME:
case META_COND_RNUMBER:
- case META_RECURSE_BYNAME:
pptr += 1 + SIZEOFFSET;
+ nestlevel++;
+ break;
+
+ case META_COND_VERSION:
+ pptr += 3;
+ nestlevel++;
break;
case META_CALLOUT_STRING:
@@ -9378,7 +9611,6 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++)
break;
case META_CALLOUT_NUMBER:
- case META_COND_VERSION:
pptr += 3;
break;
@@ -9392,7 +9624,8 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++)
case META_LOOKBEHIND:
case META_LOOKBEHINDNOT:
- if (!set_lookbehind_lengths(&pptr, &errorcode, &loopcount, NULL, cb))
+ case META_LOOKBEHIND_NA:
+ if (!set_lookbehind_lengths(&pptr, &errorcode, &loopcount, recurses, cb))
return errorcode;
break;
}
@@ -9494,6 +9727,10 @@ if (pattern == NULL)
if (ccontext == NULL)
ccontext = (pcre2_compile_context *)(&PRIV(default_compile_context));
+/* PCRE2_MATCH_INVALID_UTF implies UTF */
+
+if ((options & PCRE2_MATCH_INVALID_UTF) != 0) options |= PCRE2_UTF;
+
/* Check that all undefined public option bits are zero. */
if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0 ||
@@ -9672,7 +9909,7 @@ if ((options & PCRE2_LITERAL) == 0)
ptr += skipatstart;
-/* Can't support UTF or UCP unless PCRE2 has been compiled with UTF support. */
+/* Can't support UTF or UCP if PCRE2 was built without Unicode support. */
#ifndef SUPPORT_UNICODE
if ((cb.external_options & (PCRE2_UTF|PCRE2_UCP)) != 0)
@@ -9842,7 +10079,7 @@ lengths. */
if (has_lookbehind)
{
- errorcode = check_lookbehinds(&cb);
+ errorcode = check_lookbehinds(cb.parsed_pattern, NULL, NULL, &cb);
if (errorcode != 0) goto HAD_CB_ERROR;
}
@@ -9990,8 +10227,9 @@ re->max_lookbehind = cb.max_lookbehind;
if (cb.had_accept)
{
- reqcu = 0; /* Must disable after (*ACCEPT) */
+ reqcu = 0; /* Must disable after (*ACCEPT) */
reqcuflags = REQ_NONE;
+ re->flags |= PCRE2_HASACCEPT; /* Disables minimum length */
}
/* Fill in the final opcode and check for disastrous overflow. If no overflow,
@@ -10112,6 +10350,8 @@ unit. */
if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
{
+ int minminlength = 0; /* For minimal minlength from first/required CU */
+
/* If we do not have a first code unit, see if there is one that is asserted
(these are not saved during the compile because they can cause conflicts with
actual literals that follow). */
@@ -10119,12 +10359,14 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
if (firstcuflags < 0)
firstcu = find_firstassertedcu(codestart, &firstcuflags, 0);
- /* Save the data for a first code unit. */
+ /* Save the data for a first code unit. The existence of one means the
+ minimum length must be at least 1. */
if (firstcuflags >= 0)
{
re->first_codeunit = firstcu;
re->flags |= PCRE2_FIRSTSET;
+ minminlength++;
/* Handle caseless first code units. */
@@ -10158,39 +10400,72 @@ if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
is_startline(codestart, 0, &cb, 0, FALSE))
re->flags |= PCRE2_STARTLINE;
- /* Handle the "required code unit", if one is set. In the case of an anchored
- pattern, do this only if it follows a variable length item in the pattern. */
+ /* Handle the "required code unit", if one is set. In the UTF case we can
+ increment the minimum minimum length only if we are sure this really is a
+ different character and not a non-starting code unit of the first character,
+ because the minimum length count is in characters, not code units. */
- if (reqcuflags >= 0 &&
- ((re->overall_options & PCRE2_ANCHORED) == 0 ||
- (reqcuflags & REQ_VARY) != 0))
+ if (reqcuflags >= 0)
{
- re->last_codeunit = reqcu;
- re->flags |= PCRE2_LASTSET;
+#if PCRE2_CODE_UNIT_WIDTH == 16
+ if ((re->overall_options & PCRE2_UTF) == 0 || /* Not UTF */
+ firstcuflags < 0 || /* First not set */
+ (firstcu & 0xf800) != 0xd800 || /* First not surrogate */
+ (reqcu & 0xfc00) != 0xdc00) /* Req not low surrogate */
+#elif PCRE2_CODE_UNIT_WIDTH == 8
+ if ((re->overall_options & PCRE2_UTF) == 0 || /* Not UTF */
+ firstcuflags < 0 || /* First not set */
+ (firstcu & 0x80) == 0 || /* First is ASCII */
+ (reqcu & 0x80) == 0) /* Req is ASCII */
+#endif
+ {
+ minminlength++;
+ }
- /* Handle caseless required code units as for first code units (above). */
+ /* In the case of an anchored pattern, set up the value only if it follows
+ a variable length item in the pattern. */
- if ((reqcuflags & REQ_CASELESS) != 0)
+ if ((re->overall_options & PCRE2_ANCHORED) == 0 ||
+ (reqcuflags & REQ_VARY) != 0)
{
- if (reqcu < 128 || (!utf && reqcu < 255))
+ re->last_codeunit = reqcu;
+ re->flags |= PCRE2_LASTSET;
+
+ /* Handle caseless required code units as for first code units (above). */
+
+ if ((reqcuflags & REQ_CASELESS) != 0)
{
- if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS;
- }
+ if (reqcu < 128 || (!utf && reqcu < 255))
+ {
+ if (cb.fcc[reqcu] != reqcu) re->flags |= PCRE2_LASTCASELESS;
+ }
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 8
- else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu)
- re->flags |= PCRE2_LASTCASELESS;
+ else if (reqcu <= MAX_UTF_CODE_POINT && UCD_OTHERCASE(reqcu) != reqcu)
+ re->flags |= PCRE2_LASTCASELESS;
#endif
+ }
}
}
- /* Finally, study the compiled pattern to set up information such as a bitmap
- of starting code units and a minimum matching length. */
+ /* Study the compiled pattern to set up information such as a bitmap of
+ starting code units and a minimum matching length. */
if (PRIV(study)(re) != 0)
{
errorcode = ERR31;
goto HAD_CB_ERROR;
}
+
+ /* If study() set a bitmap of starting code units, it implies a minimum
+ length of at least one. */
+
+ if ((re->flags & PCRE2_FIRSTMAPSET) != 0 && minminlength == 0)
+ minminlength = 1;
+
+ /* If the minimum length set (or not set) by study() is less than the minimum
+ implied by required code units, override it. */
+
+ if (re->minlength < minminlength) re->minlength = minminlength;
} /* End of start-of-match optimizations. */
/* Control ends up here in all cases. When running under valgrind, make a
diff --git a/thirdparty/pcre2/src/pcre2_context.c b/thirdparty/pcre2/src/pcre2_context.c
index 9c2886a6d0..f904a494a0 100644
--- a/thirdparty/pcre2/src/pcre2_context.c
+++ b/thirdparty/pcre2/src/pcre2_context.c
@@ -323,7 +323,7 @@ data. */
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_set_character_tables(pcre2_compile_context *ccontext,
- const unsigned char *tables)
+ const uint8_t *tables)
{
ccontext->tables = tables;
return 0;
diff --git a/thirdparty/pcre2/src/pcre2_dfa_match.c b/thirdparty/pcre2/src/pcre2_dfa_match.c
index bbf3e21064..7d8ffe8a3e 100644
--- a/thirdparty/pcre2/src/pcre2_dfa_match.c
+++ b/thirdparty/pcre2/src/pcre2_dfa_match.c
@@ -173,6 +173,8 @@ static const uint8_t coptable[] = {
0, /* Assert not */
0, /* Assert behind */
0, /* Assert behind not */
+ 0, /* NA assert */
+ 0, /* NA assert behind */
0, /* ONCE */
0, /* SCRIPT_RUN */
0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
@@ -248,6 +250,8 @@ static const uint8_t poptable[] = {
0, /* Assert not */
0, /* Assert behind */
0, /* Assert behind not */
+ 0, /* NA assert */
+ 0, /* NA assert behind */
0, /* ONCE */
0, /* SCRIPT_RUN */
0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */
@@ -962,7 +966,7 @@ for (;;)
if (ptr >= end_subject)
{
if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
- could_continue = TRUE;
+ return PCRE2_ERROR_PARTIAL;
else { ADD_ACTIVE(state_offset + 1, 0); }
}
break;
@@ -1011,10 +1015,12 @@ for (;;)
/*-----------------------------------------------------------------*/
case OP_EODN:
- if (clen == 0 && (mb->moptions & PCRE2_PARTIAL_HARD) != 0)
- could_continue = TRUE;
- else if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - mb->nllen))
- { ADD_ACTIVE(state_offset + 1, 0); }
+ if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - mb->nllen))
+ {
+ if ((mb->moptions & PCRE2_PARTIAL_HARD) != 0)
+ return PCRE2_ERROR_PARTIAL;
+ ADD_ACTIVE(state_offset + 1, 0);
+ }
break;
/*-----------------------------------------------------------------*/
@@ -3152,8 +3158,8 @@ for (;;)
/* We have finished the processing at the current subject character. If no
new states have been set for the next character, we have found all the
- matches that we are going to find. If we are at the top level and partial
- matching has been requested, check for appropriate conditions.
+ matches that we are going to find. If partial matching has been requested,
+ check for appropriate conditions.
The "forced_ fail" variable counts the number of (*F) encountered for the
character. If it is equal to the original active_count (saved in
@@ -3165,22 +3171,24 @@ for (;;)
if (new_count <= 0)
{
- if (rlevel == 1 && /* Top level, and */
- could_continue && /* Some could go on, and */
+ if (could_continue && /* Some could go on, and */
forced_fail != workspace[1] && /* Not all forced fail & */
( /* either... */
(mb->moptions & PCRE2_PARTIAL_HARD) != 0 /* Hard partial */
|| /* or... */
((mb->moptions & PCRE2_PARTIAL_SOFT) != 0 && /* Soft partial and */
- match_count < 0) /* no matches */
+ match_count < 0) /* no matches */
) && /* And... */
(
- partial_newline || /* Either partial NL */
- ( /* or ... */
- ptr >= end_subject && /* End of subject and */
- ptr > mb->start_used_ptr) /* Inspected non-empty string */
+ partial_newline || /* Either partial NL */
+ ( /* or ... */
+ ptr >= end_subject && /* End of subject and */
+ ( /* either */
+ ptr > mb->start_used_ptr || /* Inspected non-empty string */
+ mb->allowemptypartial /* or pattern has lookbehind */
+ ) /* or could match empty */
)
- )
+ ))
match_count = PCRE2_ERROR_PARTIAL;
break; /* Exit from loop along the subject string */
}
@@ -3246,6 +3254,11 @@ BOOL utf, anchored, startline, firstline;
BOOL has_first_cu = FALSE;
BOOL has_req_cu = FALSE;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+BOOL memchr_not_found_first_cu = FALSE;
+BOOL memchr_not_found_first_cu2 = FALSE;
+#endif
+
PCRE2_UCHAR first_cu = 0;
PCRE2_UCHAR first_cu2 = 0;
PCRE2_UCHAR req_cu = 0;
@@ -3295,6 +3308,11 @@ if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
return PCRE2_ERROR_BADOPTION;
+/* Invalid UTF support is not available for DFA matching. */
+
+if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)
+ return PCRE2_ERROR_DFA_UINVALID_UTF;
+
/* Check that the first field in the block is the magic number. If it is not,
return with PCRE2_ERROR_BADMAGIC. */
@@ -3404,6 +3422,8 @@ mb->tables = re->tables;
mb->start_subject = subject;
mb->end_subject = end_subject;
mb->start_offset = start_offset;
+mb->allowemptypartial = (re->max_lookbehind > 0) ||
+ (re->flags & PCRE2_MATCH_EMPTY) != 0;
mb->moptions = options;
mb->poptions = re->overall_options;
mb->match_call_count = 0;
@@ -3619,7 +3639,10 @@ for (;;)
/* Not anchored. Advance to a unique first code unit if there is one. In
8-bit mode, the use of memchr() gives a big speed up, even though we have
to call it twice in caseless mode, in order to find the earliest occurrence
- of the character in either of its cases. */
+ of the character in either of its cases. If a call to memchr() that
+ searches the rest of the subject fails to find one case, remember that in
+ order not to keep on repeating the search. This can make a huge difference
+ when the strings are very long and only one case is present. */
else
{
@@ -3633,11 +3656,29 @@ for (;;)
(smc = UCHAR21TEST(start_match)) != first_cu &&
smc != first_cu2)
start_match++;
+
#else /* 8-bit code units */
- PCRE2_SPTR pp1 =
- memchr(start_match, first_cu, end_subject-start_match);
- PCRE2_SPTR pp2 =
- memchr(start_match, first_cu2, end_subject-start_match);
+ PCRE2_SPTR pp1 = NULL;
+ PCRE2_SPTR pp2 = NULL;
+ PCRE2_SIZE cu2size = end_subject - start_match;
+
+ if (!memchr_not_found_first_cu)
+ {
+ pp1 = memchr(start_match, first_cu, end_subject - start_match);
+ if (pp1 == NULL) memchr_not_found_first_cu = TRUE;
+ else cu2size = pp1 - start_match;
+ }
+
+ /* If pp1 is not NULL, we have arranged to search only as far as pp1,
+ to see if the other case is earlier, so we can set "not found" only
+ when both searches have returned NULL. */
+
+ if (!memchr_not_found_first_cu2)
+ {
+ pp2 = memchr(start_match, first_cu2, cu2size);
+ memchr_not_found_first_cu2 = (pp2 == NULL && pp1 == NULL);
+ }
+
if (pp1 == NULL)
start_match = (pp2 == NULL)? end_subject : pp2;
else
@@ -3653,7 +3694,7 @@ for (;;)
while (start_match < end_subject && UCHAR21TEST(start_match) !=
first_cu)
start_match++;
-#else
+#else /* 8-bit code units */
start_match = memchr(start_match, first_cu, end_subject - start_match);
if (start_match == NULL) start_match = end_subject;
#endif
@@ -3740,6 +3781,8 @@ for (;;)
if ((mb->moptions & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) == 0)
{
+ PCRE2_SPTR p;
+
/* The minimum matching length is a lower bound; no actual string of that
length may actually match the pattern. Although the value is, strictly,
in characters, we treat it as code units to avoid spending too much time
@@ -3753,37 +3796,63 @@ for (;;)
point. This optimization can save a huge amount of backtracking in
patterns with nested unlimited repeats that aren't going to match.
Writing separate code for cased/caseless versions makes it go faster, as
- does using an autoincrement and backing off on a match.
+ does using an autoincrement and backing off on a match. As in the case of
+ the first code unit, using memchr() in the 8-bit library gives a big
+ speed up. Unlike the first_cu check above, we do not need to call
+ memchr() twice in the caseless case because we only need to check for the
+ presence of the character in either case, not find the first occurrence.
+
+ The search can be skipped if the code unit was found later than the
+ current starting point in a previous iteration of the bumpalong loop.
HOWEVER: when the subject string is very, very long, searching to its end
can take a long time, and give bad performance on quite ordinary
patterns. This showed up when somebody was matching something like
/^\d+C/ on a 32-megabyte string... so we don't do this when the string is
- sufficiently long. */
+ sufficiently long, but it's worth searching a lot more for unanchored
+ patterns. */
- if (has_req_cu && end_subject - start_match < REQ_CU_MAX)
+ p = start_match + (has_first_cu? 1:0);
+ if (has_req_cu && p > req_cu_ptr)
{
- PCRE2_SPTR p = start_match + (has_first_cu? 1:0);
-
- /* We don't need to repeat the search if we haven't yet reached the
- place we found it at last time. */
+ PCRE2_SIZE check_length = end_subject - start_match;
- if (p > req_cu_ptr)
+ if (check_length < REQ_CU_MAX ||
+ (!anchored && check_length < REQ_CU_MAX * 1000))
{
- if (req_cu != req_cu2)
+ if (req_cu != req_cu2) /* Caseless */
{
+#if PCRE2_CODE_UNIT_WIDTH != 8
while (p < end_subject)
{
uint32_t pp = UCHAR21INCTEST(p);
if (pp == req_cu || pp == req_cu2) { p--; break; }
}
+#else /* 8-bit code units */
+ PCRE2_SPTR pp = p;
+ p = memchr(pp, req_cu, end_subject - pp);
+ if (p == NULL)
+ {
+ p = memchr(pp, req_cu2, end_subject - pp);
+ if (p == NULL) p = end_subject;
+ }
+#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */
}
+
+ /* The caseful case */
+
else
{
+#if PCRE2_CODE_UNIT_WIDTH != 8
while (p < end_subject)
{
if (UCHAR21INCTEST(p) == req_cu) { p--; break; }
}
+
+#else /* 8-bit code units */
+ p = memchr(p, req_cu, end_subject - p);
+ if (p == NULL) p = end_subject;
+#endif
}
/* If we can't find the required code unit, break the matching loop,
diff --git a/thirdparty/pcre2/src/pcre2_error.c b/thirdparty/pcre2/src/pcre2_error.c
index 1d02cf14a3..c61648cb7f 100644
--- a/thirdparty/pcre2/src/pcre2_error.c
+++ b/thirdparty/pcre2/src/pcre2_error.c
@@ -184,6 +184,8 @@ static const unsigned char compile_error_texts[] =
/* 95 */
"(*alpha_assertion) not recognized\0"
"script runs require Unicode support, which this version of PCRE2 does not have\0"
+ "too many capturing groups (maximum 65535)\0"
+ "atomic assertion expected after (?( or (?(?C)\0"
;
/* Match-time and UTF error texts are in the same format. */
@@ -268,6 +270,7 @@ static const unsigned char match_error_texts[] =
"invalid syntax\0"
/* 65 */
"internal error - duplicate substitution match\0"
+ "PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\0"
;
diff --git a/thirdparty/pcre2/src/pcre2_internal.h b/thirdparty/pcre2/src/pcre2_internal.h
index 814d91bddb..fe8ffe5c80 100644
--- a/thirdparty/pcre2/src/pcre2_internal.h
+++ b/thirdparty/pcre2/src/pcre2_internal.h
@@ -517,6 +517,7 @@ bytes in a code unit in that mode. */
#define PCRE2_HASBKPORX 0x00100000 /* contains \P, \p, or \X */
#define PCRE2_DUPCAPUSED 0x00200000 /* contains (?| */
#define PCRE2_HASBKC 0x00400000 /* contains \C */
+#define PCRE2_HASACCEPT 0x00800000 /* contains (*ACCEPT) */
#define PCRE2_MODE_MASK (PCRE2_MODE8 | PCRE2_MODE16 | PCRE2_MODE32)
@@ -535,13 +536,14 @@ enum { PCRE2_MATCHEDBY_INTERPRETER, /* pcre2_match() */
#define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */
/* The maximum remaining length of subject we are prepared to search for a
-req_unit match. In 8-bit mode, memchr() is used and is much faster than the
-search loop that has to be used in 16-bit and 32-bit modes. */
+req_unit match from an anchored pattern. In 8-bit mode, memchr() is used and is
+much faster than the search loop that has to be used in 16-bit and 32-bit
+modes. */
#if PCRE2_CODE_UNIT_WIDTH == 8
-#define REQ_CU_MAX 2000
+#define REQ_CU_MAX 5000
#else
-#define REQ_CU_MAX 1000
+#define REQ_CU_MAX 2000
#endif
/* Offsets for the bitmap tables in the cbits set of tables. Each table
@@ -881,12 +883,16 @@ a positive value. */
#define STRING_atomic0 "atomic\0"
#define STRING_pla0 "pla\0"
#define STRING_plb0 "plb\0"
+#define STRING_napla0 "napla\0"
+#define STRING_naplb0 "naplb\0"
#define STRING_nla0 "nla\0"
#define STRING_nlb0 "nlb\0"
#define STRING_sr0 "sr\0"
#define STRING_asr0 "asr\0"
#define STRING_positive_lookahead0 "positive_lookahead\0"
#define STRING_positive_lookbehind0 "positive_lookbehind\0"
+#define STRING_non_atomic_positive_lookahead0 "non_atomic_positive_lookahead\0"
+#define STRING_non_atomic_positive_lookbehind0 "non_atomic_positive_lookbehind\0"
#define STRING_negative_lookahead0 "negative_lookahead\0"
#define STRING_negative_lookbehind0 "negative_lookbehind\0"
#define STRING_script_run0 "script_run\0"
@@ -1171,12 +1177,16 @@ only. */
#define STRING_atomic0 STR_a STR_t STR_o STR_m STR_i STR_c "\0"
#define STRING_pla0 STR_p STR_l STR_a "\0"
#define STRING_plb0 STR_p STR_l STR_b "\0"
+#define STRING_napla0 STR_n STR_a STR_p STR_l STR_a "\0"
+#define STRING_naplb0 STR_n STR_a STR_p STR_l STR_b "\0"
#define STRING_nla0 STR_n STR_l STR_a "\0"
#define STRING_nlb0 STR_n STR_l STR_b "\0"
#define STRING_sr0 STR_s STR_r "\0"
#define STRING_asr0 STR_a STR_s STR_r "\0"
#define STRING_positive_lookahead0 STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0"
#define STRING_positive_lookbehind0 STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0"
+#define STRING_non_atomic_positive_lookahead0 STR_n STR_o STR_n STR_UNDERSCORE STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0"
+#define STRING_non_atomic_positive_lookbehind0 STR_n STR_o STR_n STR_UNDERSCORE STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0"
#define STRING_negative_lookahead0 STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0"
#define STRING_negative_lookbehind0 STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0"
#define STRING_script_run0 STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n "\0"
@@ -1301,7 +1311,7 @@ enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in
order to the list of escapes immediately above. Furthermore, values up to
OP_DOLLM must not be changed without adjusting the table called autoposstab in
-pcre2_auto_possess.c
+pcre2_auto_possess.c.
Whenever this list is updated, the two macro definitions that follow must be
updated to match. The possessification table called "opcode_possessify" in
@@ -1499,80 +1509,81 @@ enum {
OP_KETRMIN, /* 123 order. They are for groups the repeat for ever. */
OP_KETRPOS, /* 124 Possessive unlimited repeat. */
- /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four
- asserts must remain in order. */
+ /* The assertions must come before BRA, CBRA, ONCE, and COND. */
OP_REVERSE, /* 125 Move pointer back - used in lookbehind assertions */
OP_ASSERT, /* 126 Positive lookahead */
OP_ASSERT_NOT, /* 127 Negative lookahead */
OP_ASSERTBACK, /* 128 Positive lookbehind */
OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */
+ OP_ASSERT_NA, /* 130 Positive non-atomic lookahead */
+ OP_ASSERTBACK_NA, /* 131 Positive non-atomic lookbehind */
/* ONCE, SCRIPT_RUN, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come
immediately after the assertions, with ONCE first, as there's a test for >=
ONCE for a subpattern that isn't an assertion. The POS versions must
immediately follow the non-POS versions in each case. */
- OP_ONCE, /* 130 Atomic group, contains captures */
- OP_SCRIPT_RUN, /* 131 Non-capture, but check characters' scripts */
- OP_BRA, /* 132 Start of non-capturing bracket */
- OP_BRAPOS, /* 133 Ditto, with unlimited, possessive repeat */
- OP_CBRA, /* 134 Start of capturing bracket */
- OP_CBRAPOS, /* 135 Ditto, with unlimited, possessive repeat */
- OP_COND, /* 136 Conditional group */
+ OP_ONCE, /* 132 Atomic group, contains captures */
+ OP_SCRIPT_RUN, /* 133 Non-capture, but check characters' scripts */
+ OP_BRA, /* 134 Start of non-capturing bracket */
+ OP_BRAPOS, /* 135 Ditto, with unlimited, possessive repeat */
+ OP_CBRA, /* 136 Start of capturing bracket */
+ OP_CBRAPOS, /* 137 Ditto, with unlimited, possessive repeat */
+ OP_COND, /* 138 Conditional group */
/* These five must follow the previous five, in the same order. There's a
check for >= SBRA to distinguish the two sets. */
- OP_SBRA, /* 137 Start of non-capturing bracket, check empty */
- OP_SBRAPOS, /* 138 Ditto, with unlimited, possessive repeat */
- OP_SCBRA, /* 139 Start of capturing bracket, check empty */
- OP_SCBRAPOS, /* 140 Ditto, with unlimited, possessive repeat */
- OP_SCOND, /* 141 Conditional group, check empty */
+ OP_SBRA, /* 139 Start of non-capturing bracket, check empty */
+ OP_SBRAPOS, /* 149 Ditto, with unlimited, possessive repeat */
+ OP_SCBRA, /* 141 Start of capturing bracket, check empty */
+ OP_SCBRAPOS, /* 142 Ditto, with unlimited, possessive repeat */
+ OP_SCOND, /* 143 Conditional group, check empty */
/* The next two pairs must (respectively) be kept together. */
- OP_CREF, /* 142 Used to hold a capture number as condition */
- OP_DNCREF, /* 143 Used to point to duplicate names as a condition */
- OP_RREF, /* 144 Used to hold a recursion number as condition */
- OP_DNRREF, /* 145 Used to point to duplicate names as a condition */
- OP_FALSE, /* 146 Always false (used by DEFINE and VERSION) */
- OP_TRUE, /* 147 Always true (used by VERSION) */
+ OP_CREF, /* 144 Used to hold a capture number as condition */
+ OP_DNCREF, /* 145 Used to point to duplicate names as a condition */
+ OP_RREF, /* 146 Used to hold a recursion number as condition */
+ OP_DNRREF, /* 147 Used to point to duplicate names as a condition */
+ OP_FALSE, /* 148 Always false (used by DEFINE and VERSION) */
+ OP_TRUE, /* 149 Always true (used by VERSION) */
- OP_BRAZERO, /* 148 These two must remain together and in this */
- OP_BRAMINZERO, /* 149 order. */
- OP_BRAPOSZERO, /* 150 */
+ OP_BRAZERO, /* 150 These two must remain together and in this */
+ OP_BRAMINZERO, /* 151 order. */
+ OP_BRAPOSZERO, /* 152 */
/* These are backtracking control verbs */
- OP_MARK, /* 151 always has an argument */
- OP_PRUNE, /* 152 */
- OP_PRUNE_ARG, /* 153 same, but with argument */
- OP_SKIP, /* 154 */
- OP_SKIP_ARG, /* 155 same, but with argument */
- OP_THEN, /* 156 */
- OP_THEN_ARG, /* 157 same, but with argument */
- OP_COMMIT, /* 158 */
- OP_COMMIT_ARG, /* 159 same, but with argument */
+ OP_MARK, /* 153 always has an argument */
+ OP_PRUNE, /* 154 */
+ OP_PRUNE_ARG, /* 155 same, but with argument */
+ OP_SKIP, /* 156 */
+ OP_SKIP_ARG, /* 157 same, but with argument */
+ OP_THEN, /* 158 */
+ OP_THEN_ARG, /* 159 same, but with argument */
+ OP_COMMIT, /* 160 */
+ OP_COMMIT_ARG, /* 161 same, but with argument */
/* These are forced failure and success verbs. FAIL and ACCEPT do accept an
argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL)
without the need for a special opcode. */
- OP_FAIL, /* 160 */
- OP_ACCEPT, /* 161 */
- OP_ASSERT_ACCEPT, /* 162 Used inside assertions */
- OP_CLOSE, /* 163 Used before OP_ACCEPT to close open captures */
+ OP_FAIL, /* 162 */
+ OP_ACCEPT, /* 163 */
+ OP_ASSERT_ACCEPT, /* 164 Used inside assertions */
+ OP_CLOSE, /* 165 Used before OP_ACCEPT to close open captures */
/* This is used to skip a subpattern with a {0} quantifier */
- OP_SKIPZERO, /* 164 */
+ OP_SKIPZERO, /* 166 */
/* This is used to identify a DEFINE group during compilation so that it can
be checked for having only one branch. It is changed to OP_FALSE before
compilation finishes. */
- OP_DEFINE, /* 165 */
+ OP_DEFINE, /* 167 */
/* This is not an opcode, but is used to check that tables indexed by opcode
are the correct length, in order to catch updating errors - there have been
@@ -1585,7 +1596,7 @@ enum {
/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro
definitions that follow must also be updated to match. There are also tables
called "opcode_possessify" in pcre2_compile.c and "coptable" and "poptable" in
-pcre2_dfa_exec.c that must be updated. */
+pcre2_dfa_match.c that must be updated. */
/* This macro defines textual names for all the opcodes. These are used only
@@ -1618,7 +1629,9 @@ some cases doesn't actually use these names at all). */
"class", "nclass", "xclass", "Ref", "Refi", "DnRef", "DnRefi", \
"Recurse", "Callout", "CalloutStr", \
"Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \
- "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \
+ "Reverse", "Assert", "Assert not", \
+ "Assert back", "Assert back not", \
+ "Non-atomic assert", "Non-atomic assert back", \
"Once", \
"Script run", \
"Bra", "BraPos", "CBra", "CBraPos", \
@@ -1703,6 +1716,8 @@ in UTF-8 mode. The code that uses this table must know about such things. */
1+LINK_SIZE, /* Assert not */ \
1+LINK_SIZE, /* Assert behind */ \
1+LINK_SIZE, /* Assert behind not */ \
+ 1+LINK_SIZE, /* NA Assert */ \
+ 1+LINK_SIZE, /* NA Assert behind */ \
1+LINK_SIZE, /* ONCE */ \
1+LINK_SIZE, /* SCRIPT_RUN */ \
1+LINK_SIZE, /* BRA */ \
diff --git a/thirdparty/pcre2/src/pcre2_intmodedep.h b/thirdparty/pcre2/src/pcre2_intmodedep.h
index bf3a235984..ea3b3ec698 100644
--- a/thirdparty/pcre2/src/pcre2_intmodedep.h
+++ b/thirdparty/pcre2/src/pcre2_intmodedep.h
@@ -205,19 +205,19 @@ whether its argument, which is assumed to be one code unit, is less than 256.
The CHMAX_255 macro does not assume one code unit. The maximum length of a MARK
name must fit in one code unit; currently it is set to 255 or 65535. The
TABLE_GET macro is used to access elements of tables containing exactly 256
-items. When code points can be greater than 255, a check is needed before
-accessing these tables. */
+items. Its argument is a code unit. When code points can be greater than 255, a
+check is needed before accessing these tables. */
#if PCRE2_CODE_UNIT_WIDTH == 8
#define MAX_255(c) TRUE
#define MAX_MARK ((1u << 8) - 1)
+#define TABLE_GET(c, table, default) ((table)[c])
#ifdef SUPPORT_UNICODE
#define SUPPORT_WIDE_CHARS
#define CHMAX_255(c) ((c) <= 255u)
#else
#define CHMAX_255(c) TRUE
#endif /* SUPPORT_UNICODE */
-#define TABLE_GET(c, table, default) ((table)[c])
#else /* Code units are 16 or 32 bits */
#define CHMAX_255(c) ((c) <= 255u)
@@ -228,7 +228,6 @@ accessing these tables. */
#endif
-
/* ----------------- Character-handling macros ----------------- */
/* There is a proposed future special "UTF-21" mode, in which only the lowest
@@ -854,6 +853,7 @@ typedef struct match_block {
uint32_t match_call_count; /* Number of times a new frame is created */
BOOL hitend; /* Hit the end of the subject at some point */
BOOL hasthen; /* Pattern contains (*THEN) */
+ BOOL allowemptypartial; /* Allow empty hard partial */
const uint8_t *lcc; /* Points to lower casing table */
const uint8_t *fcc; /* Points to case-flipping table */
const uint8_t *ctypes; /* Points to table of type maps */
@@ -866,6 +866,7 @@ typedef struct match_block {
PCRE2_SPTR name_table; /* Table of group names */
PCRE2_SPTR start_code; /* For use when recursing */
PCRE2_SPTR start_subject; /* Start of the subject string */
+ PCRE2_SPTR check_subject; /* Where UTF-checked from */
PCRE2_SPTR end_subject; /* End of the subject string */
PCRE2_SPTR end_match_ptr; /* Subject position at end match */
PCRE2_SPTR start_used_ptr; /* Earliest consulted character */
@@ -908,6 +909,7 @@ typedef struct dfa_match_block {
uint32_t poptions; /* Pattern options */
uint32_t nltype; /* Newline type */
uint32_t nllen; /* Newline string length */
+ BOOL allowemptypartial; /* Allow empty hard partial */
PCRE2_UCHAR nl[4]; /* Newline string when fixed */
uint16_t bsr_convention; /* \R interpretation */
pcre2_callout_block *cb; /* Points to a callout block */
diff --git a/thirdparty/pcre2/src/pcre2_jit_compile.c b/thirdparty/pcre2/src/pcre2_jit_compile.c
index 1f21bfb6ad..f564127c2a 100644
--- a/thirdparty/pcre2/src/pcre2_jit_compile.c
+++ b/thirdparty/pcre2/src/pcre2_jit_compile.c
@@ -6,8 +6,9 @@
and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
+ This module by Zoltan Herczeg
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2018 University of Cambridge
+ New API code Copyright (c) 2016-2019 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -212,12 +213,6 @@ typedef struct stub_list {
struct stub_list *next;
} stub_list;
-typedef struct label_addr_list {
- struct sljit_label *label;
- sljit_uw *update_addr;
- struct label_addr_list *next;
-} label_addr_list;
-
enum frame_types {
no_frame = -1,
no_stack = -2
@@ -271,6 +266,8 @@ typedef struct bracket_backtrack {
assert_backtrack *assert;
/* For OP_ONCE. Less than 0 if not needed. */
int framesize;
+ /* For brackets with >3 alternatives. */
+ struct sljit_put_label *matching_put_label;
} u;
/* Points to our private memory word on the stack. */
int private_data_ptr;
@@ -416,6 +413,8 @@ typedef struct compiler_common {
sljit_sw lcc;
/* Mode can be PCRE2_JIT_COMPLETE and others. */
int mode;
+ /* TRUE, when empty match is accepted for partial matching. */
+ BOOL allow_empty_partial;
/* TRUE, when minlength is greater than 0. */
BOOL might_be_empty;
/* \K is found in the pattern. */
@@ -454,7 +453,6 @@ typedef struct compiler_common {
struct sljit_label *accept_label;
struct sljit_label *ff_newline_shortcut;
stub_list *stubs;
- label_addr_list *label_addrs;
recurse_entry *entries;
recurse_entry *currententry;
jump_list *partialmatch;
@@ -563,6 +561,12 @@ typedef struct compare_context {
#define ARGUMENTS SLJIT_S4
#define RETURN_ADDR SLJIT_R4
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+#define HAS_VIRTUAL_REGISTERS 1
+#else
+#define HAS_VIRTUAL_REGISTERS 0
+#endif
+
/* Local space layout. */
/* These two locals can be used by the current opcode. */
#define LOCALS0 (0 * sizeof(sljit_sw))
@@ -696,11 +700,12 @@ the start pointers when the end of the capturing group has not yet reached. */
#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \
{ \
- if (ptr[-1] <= 0x7f) \
- c = *ptr--; \
+ c = ptr[-1]; \
+ if (c <= 0x7f) \
+ ptr--; \
else if (ptr - 1 > start && ptr[-1] >= 0x80 && ptr[-1] < 0xc0) \
{ \
- c = ptr[-1] - 0x80; \
+ c -= 0x80; \
\
if (ptr[-2] >= 0xc2 && ptr[-2] <= 0xdf) \
{ \
@@ -775,11 +780,12 @@ the start pointers when the end of the capturing group has not yet reached. */
#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \
{ \
- if (ptr[-1] < 0xd800 || ptr[-1] >= 0xe000) \
- c = *ptr--; \
- else if (ptr[-1] >= 0xdc00 && ptr - 1 > start && ptr[-2] >= 0xd800 && ptr[-2] < 0xdc00) \
+ c = ptr[-1]; \
+ if (c < 0xd800 || c >= 0xe000) \
+ ptr--; \
+ else if (c >= 0xdc00 && ptr - 1 > start && ptr[-2] >= 0xd800 && ptr[-2] < 0xdc00) \
{ \
- c = (((ptr[-2] - 0xd800) << 10) | (ptr[-1] - 0xdc00)) + 0x10000; \
+ c = (((ptr[-2] - 0xd800) << 10) | (c - 0xdc00)) + 0x10000; \
ptr -= 2; \
} \
else \
@@ -793,7 +799,7 @@ the start pointers when the end of the capturing group has not yet reached. */
#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \
{ \
- if (ptr[0] < 0x110000) \
+ if (ptr[0] < 0xd800 || (ptr[0] >= 0xe000 && ptr[0] < 0x110000)) \
c = *ptr++; \
else \
{ \
@@ -801,6 +807,17 @@ the start pointers when the end of the capturing group has not yet reached. */
} \
}
+#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \
+ { \
+ c = ptr[-1]; \
+ if (ptr[-1] < 0xd800 || (ptr[-1] >= 0xe000 && ptr[-1] < 0x110000)) \
+ ptr--; \
+ else \
+ { \
+ invalid_action; \
+ } \
+ }
+
#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
#endif /* SUPPORT_UNICODE */
@@ -1033,8 +1050,8 @@ switch(*cc)
return cc + 1 + 2 + cc[1];
default:
- /* All opcodes are supported now! */
- SLJIT_UNREACHABLE();
+ /* Unsupported opcodes: OP_ASSERT_NA and OP_ASSERTBACK_NA */
+ /* SLJIT_UNREACHABLE(); */
return NULL;
}
}
@@ -2371,14 +2388,14 @@ if (base_reg != TMP2)
else
{
status.saved_tmp_regs[1] = RETURN_ADDR;
- if (sljit_get_register_index(RETURN_ADDR) == -1)
+ if (HAS_VIRTUAL_REGISTERS)
status.tmp_regs[1] = STR_PTR;
else
status.tmp_regs[1] = RETURN_ADDR;
}
status.saved_tmp_regs[2] = TMP3;
-if (sljit_get_register_index(TMP3) == -1)
+if (HAS_VIRTUAL_REGISTERS)
status.tmp_regs[2] = STR_END;
else
status.tmp_regs[2] = TMP3;
@@ -2829,20 +2846,6 @@ while (list_item)
common->stubs = NULL;
}
-static void add_label_addr(compiler_common *common, sljit_uw *update_addr)
-{
-DEFINE_COMPILER;
-label_addr_list *label_addr;
-
-label_addr = sljit_alloc_memory(compiler, sizeof(label_addr_list));
-if (label_addr == NULL)
- return;
-label_addr->label = LABEL();
-label_addr->update_addr = update_addr;
-label_addr->next = common->label_addrs;
-common->label_addrs = label_addr;
-}
-
static SLJIT_INLINE void count_match(compiler_common *common)
{
DEFINE_COMPILER;
@@ -2985,12 +2988,18 @@ else
}
}
-OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
+if (!HAS_VIRTUAL_REGISTERS)
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, stack));
+else
+ OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
+
if (common->mark_ptr != 0)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, SLJIT_IMM, 0);
if (common->control_head_ptr != 0)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr, SLJIT_IMM, 0);
-OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
+if (HAS_VIRTUAL_REGISTERS)
+ OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
+
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, end));
}
@@ -3029,21 +3038,36 @@ BOOL has_pre;
OP1(SLJIT_MOV, SLJIT_S2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(1));
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(1), STR_PTR, 0);
-OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
-if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
-OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount));
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0);
-if (common->mark_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
-OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, match_data),
- SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE));
+if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, SLJIT_R0, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
+ if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
+ OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, oveccount));
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0);
+ if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R2, 0);
+ OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, match_data),
+ SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE));
+ }
+else
+ {
+ OP1(SLJIT_MOV, SLJIT_S0, 0, SLJIT_MEM1(SLJIT_SP), common->start_ptr);
+ OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, match_data));
+ if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
+ OP1(SLJIT_MOV_U32, SLJIT_R1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, oveccount));
+ OP1(SLJIT_MOV, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_S0, 0);
+ if (common->mark_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_R0, 0);
+ OP2(SLJIT_ADD, SLJIT_R2, 0, SLJIT_R2, 0, SLJIT_IMM, SLJIT_OFFSETOF(pcre2_match_data, ovector) - sizeof(PCRE2_SIZE));
+ }
has_pre = sljit_emit_mem(compiler, SLJIT_MOV | SLJIT_MEM_SUPP | SLJIT_MEM_PRE, SLJIT_S1, SLJIT_MEM1(SLJIT_S0), sizeof(sljit_sw)) == SLJIT_SUCCESS;
GET_LOCAL_BASE(SLJIT_S0, 0, OVECTOR_START - (has_pre ? sizeof(sljit_sw) : 0));
-OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_R0), SLJIT_OFFSETOF(jit_arguments, begin));
+OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? SLJIT_R0 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
loop = LABEL();
@@ -3105,20 +3129,22 @@ static SLJIT_INLINE void return_with_partial_match(compiler_common *common, stru
{
DEFINE_COMPILER;
sljit_s32 mov_opcode;
+sljit_s32 arguments_reg = !HAS_VIRTUAL_REGISTERS ? ARGUMENTS : SLJIT_R1;
SLJIT_COMPILE_ASSERT(STR_END == SLJIT_S0, str_end_must_be_saved_reg0);
SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
&& (common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start != 0 : common->hit_start == 0));
-OP1(SLJIT_MOV, SLJIT_R1, 0, ARGUMENTS, 0);
+if (arguments_reg != ARGUMENTS)
+ OP1(SLJIT_MOV, arguments_reg, 0, ARGUMENTS, 0);
OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP),
common->mode == PCRE2_JIT_PARTIAL_SOFT ? common->hit_start : common->start_ptr);
OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_PARTIAL);
/* Store match begin and end. */
-OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, begin));
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0);
-OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(SLJIT_R1), SLJIT_OFFSETOF(jit_arguments, match_data));
+OP1(SLJIT_MOV, SLJIT_S1, 0, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, begin));
+OP1(SLJIT_MOV, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, startchar_ptr), SLJIT_R2, 0);
+OP1(SLJIT_MOV, SLJIT_R1, 0, SLJIT_MEM1(arguments_reg), SLJIT_OFFSETOF(jit_arguments, match_data));
mov_opcode = (sizeof(PCRE2_SIZE) == 4) ? SLJIT_MOV_U32 : SLJIT_MOV;
@@ -3279,7 +3305,7 @@ SLJIT_ASSERT(!force || common->mode != PCRE2_JIT_COMPLETE);
if (common->mode == PCRE2_JIT_COMPLETE)
return;
-if (!force)
+if (!force && !common->allow_empty_partial)
jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
else if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
jump = CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1);
@@ -3341,7 +3367,11 @@ if (common->mode == PCRE2_JIT_COMPLETE)
/* Partial matching mode. */
jump = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
-add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
+if (!common->allow_empty_partial)
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
+else if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, SLJIT_IMM, -1));
+
if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
{
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
@@ -3357,6 +3387,35 @@ else
JUMPHERE(jump);
}
+static void process_partial_match(compiler_common *common)
+{
+DEFINE_COMPILER;
+struct sljit_jump *jump;
+
+/* Partial matching mode. */
+if (common->mode == PCRE2_JIT_PARTIAL_SOFT)
+ {
+ jump = CMP(SLJIT_GREATER_EQUAL, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->hit_start, SLJIT_IMM, 0);
+ JUMPHERE(jump);
+ }
+else if (common->mode == PCRE2_JIT_PARTIAL_HARD)
+ {
+ if (common->partialmatchlabel != NULL)
+ CMPTO(SLJIT_LESS, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0, common->partialmatchlabel);
+ else
+ add_jump(compiler, &common->partialmatch, CMP(SLJIT_LESS, SLJIT_MEM1(SLJIT_SP), common->start_used_ptr, STR_PTR, 0));
+ }
+}
+
+static void detect_partial_match_to(compiler_common *common, struct sljit_label *label)
+{
+DEFINE_COMPILER;
+
+CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, label);
+process_partial_match(common);
+}
+
static void peek_char(compiler_common *common, sljit_u32 max, sljit_s32 dst, sljit_sw dstw, jump_list **backtracks)
{
/* Reads the character into TMP1, keeps STR_PTR.
@@ -3420,12 +3479,21 @@ if (common->utf)
#elif PCRE2_CODE_UNIT_WIDTH == 32
if (common->invalid_utf)
{
+ if (max < 0xd800) return;
+
if (backtracks != NULL)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));
+ }
else
{
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000);
CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
+ OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);
+ CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
}
}
#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
@@ -3490,8 +3558,12 @@ if (common->utf)
JUMPHERE(jump);
}
#elif PCRE2_CODE_UNIT_WIDTH == 32
- if (common->invalid_utf)
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));
+if (common->invalid_utf)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));
+ }
#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
#endif /* SUPPORT_UNICODE */
}
@@ -3653,7 +3725,7 @@ if (common->utf)
/* Skip low surrogate if necessary. */
OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
- if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && sljit_get_register_index(RETURN_ADDR) >= 0)
+ if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && !HAS_VIRTUAL_REGISTERS)
{
if (options & READ_CHAR_UPDATE_STR_PTR)
OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
@@ -3677,11 +3749,18 @@ if (common->utf)
if (common->invalid_utf)
{
if (backtracks != NULL)
+ {
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000));
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800));
+ }
else
{
+ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000);
CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
+ OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800);
+ CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR);
}
}
#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */
@@ -3832,7 +3911,7 @@ if (common->utf && negated)
{
OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
- if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && sljit_get_register_index(RETURN_ADDR) >= 0)
+ if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && !HAS_VIRTUAL_REGISTERS)
{
OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x400);
@@ -3865,9 +3944,9 @@ if (common->utf && negated)
static void move_back(compiler_common *common, jump_list **backtracks, BOOL must_be_valid)
{
-/* Goes one character back. TMP2 must contain the start of
-the subject buffer. Affects STR_PTR and TMP1. Does not modify
-STR_PTR for invalid character sequences. */
+/* Goes one character back. Affects STR_PTR and TMP1. If must_be_valid is TRUE,
+TMP2 is not used. Otherwise TMP2 must contain the start of the subject buffer,
+and it is destroyed. Does not modify STR_PTR for invalid character sequences. */
DEFINE_COMPILER;
SLJIT_UNUSED_ARG(backtracks);
@@ -4407,7 +4486,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
static void do_utfpeakcharback(compiler_common *common)
{
-/* Peak a character back. */
+/* Peak a character back. Does not modify STR_PTR. */
DEFINE_COMPILER;
struct sljit_jump *jump[2];
@@ -4444,7 +4523,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
static void do_utfpeakcharback_invalid(compiler_common *common)
{
-/* Peak a character back. */
+/* Peak a character back. Does not modify STR_PTR. */
DEFINE_COMPILER;
sljit_s32 i;
sljit_s32 has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV);
@@ -4672,7 +4751,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
static void do_utfpeakcharback_invalid(compiler_common *common)
{
-/* Peak a character back. */
+/* Peak a character back. Does not modify STR_PTR. */
DEFINE_COMPILER;
struct sljit_jump *jump;
struct sljit_jump *exit_invalid[3];
@@ -4786,18 +4865,12 @@ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
-// PH hacking
-//fprintf(stderr, "~~A\n");
- OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
-
+/* TMP2 is multiplied by 12. Same as (TMP2 << 2) + ((TMP2 << 2) << 1). */
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 1);
- OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 0);
-
-// OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
}
@@ -4866,15 +4939,27 @@ else if ((overall_options & PCRE2_USE_OFFSET_LIMIT) != 0)
/* Check whether offset limit is set and valid. */
SLJIT_ASSERT(common->match_end_ptr != 0);
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit));
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, offset_limit));
+ }
+ else
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, offset_limit));
+
OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);
end = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET);
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ if (HAS_VIRTUAL_REGISTERS)
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ else
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
+
#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
#endif /* PCRE2_CODE_UNIT_WIDTH == [16|32] */
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+ if (HAS_VIRTUAL_REGISTERS)
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
end2 = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0);
OP1(SLJIT_MOV, TMP2, 0, STR_END, 0);
@@ -5434,699 +5519,56 @@ CMPTO(SLJIT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00, label);
}
#endif
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND)
+#include "pcre2_jit_simd_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-static struct sljit_jump *jump_if_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg)
-{
-#if PCRE2_CODE_UNIT_WIDTH == 8
-OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0);
-return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0x80);
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00);
-return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00);
-#else
-#error "Unknown code width"
-#endif
-}
-#endif
-
-static sljit_s32 character_to_int32(PCRE2_UCHAR chr)
-{
-sljit_u32 value = chr;
-#if PCRE2_CODE_UNIT_WIDTH == 8
-#define SSE2_COMPARE_TYPE_INDEX 0
-return (sljit_s32)((value << 24) | (value << 16) | (value << 8) | value);
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-#define SSE2_COMPARE_TYPE_INDEX 1
-return (sljit_s32)((value << 16) | value);
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-#define SSE2_COMPARE_TYPE_INDEX 2
-return (sljit_s32)(value);
-#else
-#error "Unsupported unit width"
-#endif
-}
+#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD
-static void load_from_mem_sse2(struct sljit_compiler *compiler, sljit_s32 dst_xmm_reg, sljit_s32 src_general_reg)
+static BOOL check_fast_forward_char_pair_simd(compiler_common *common, fast_forward_char_data *chars, int max)
{
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-sljit_u8 instruction[5];
-#else
-sljit_u8 instruction[4];
-#endif
-
-SLJIT_ASSERT(dst_xmm_reg < 8);
-
-/* MOVDQA xmm1, xmm2/m128 */
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
-if (src_general_reg < 8)
- {
- instruction[0] = 0x66;
- instruction[1] = 0x0f;
- instruction[2] = 0x6f;
- instruction[3] = (dst_xmm_reg << 3) | src_general_reg;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-else
- {
- instruction[0] = 0x66;
- instruction[1] = 0x41;
- instruction[2] = 0x0f;
- instruction[3] = 0x6f;
- instruction[4] = (dst_xmm_reg << 3) | (src_general_reg & 0x7);
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-#else
-instruction[0] = 0x66;
-instruction[1] = 0x0f;
-instruction[2] = 0x6f;
-instruction[3] = (dst_xmm_reg << 3) | src_general_reg;
-sljit_emit_op_custom(compiler, instruction, 4);
-#endif
-}
-
-static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, PCRE2_UCHAR char1, PCRE2_UCHAR char2,
- sljit_u32 bit, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind)
-{
-sljit_u8 instruction[4];
-instruction[0] = 0x66;
-instruction[1] = 0x0f;
-
-if (char1 == char2 || bit != 0)
- {
- if (bit != 0)
- {
- /* POR xmm1, xmm2/m128 */
- /* instruction[0] = 0x66; */
- /* instruction[1] = 0x0f; */
- instruction[2] = 0xeb;
- instruction[3] = 0xc0 | (dst_ind << 3) | cmp2_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-
- /* PCMPEQB/W/D xmm1, xmm2/m128 */
- /* instruction[0] = 0x66; */
- /* instruction[1] = 0x0f; */
- instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
- instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-else
- {
- /* MOVDQA xmm1, xmm2/m128 */
- /* instruction[0] = 0x66; */
- /* instruction[1] = 0x0f; */
- instruction[2] = 0x6f;
- instruction[3] = 0xc0 | (tmp_ind << 3) | dst_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
-
- /* PCMPEQB/W/D xmm1, xmm2/m128 */
- /* instruction[0] = 0x66; */
- /* instruction[1] = 0x0f; */
- instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
- instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
-
- instruction[3] = 0xc0 | (tmp_ind << 3) | cmp2_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
-
- /* POR xmm1, xmm2/m128 */
- /* instruction[0] = 0x66; */
- /* instruction[1] = 0x0f; */
- instruction[2] = 0xeb;
- instruction[3] = 0xc0 | (dst_ind << 3) | tmp_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-}
-
-static void fast_forward_first_char2_sse2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
-{
-DEFINE_COMPILER;
-struct sljit_label *start;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_label *restart;
-#endif
-struct sljit_jump *quit;
-struct sljit_jump *partial_quit[2];
-sljit_u8 instruction[8];
-sljit_s32 tmp1_ind = sljit_get_register_index(TMP1);
-sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR);
-sljit_s32 data_ind = 0;
-sljit_s32 tmp_ind = 1;
-sljit_s32 cmp1_ind = 2;
-sljit_s32 cmp2_ind = 3;
-sljit_u32 bit = 0;
-
-SLJIT_UNUSED_ARG(offset);
-
-if (char1 != char2)
- {
- bit = char1 ^ char2;
- if (!is_powerof2(bit))
- bit = 0;
- }
-
-partial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, &common->failed_match, partial_quit[0]);
-
-/* First part (unaligned start) */
-
-OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));
-
-SLJIT_ASSERT(tmp1_ind < 8);
-
-/* MOVD xmm, r/m32 */
-instruction[0] = 0x66;
-instruction[1] = 0x0f;
-instruction[2] = 0x6e;
-instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-if (char1 != char2)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));
-
- /* MOVD xmm, r/m32 */
- instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-
-OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
-
-/* PSHUFD xmm1, xmm2/m128, imm8 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x70;
-instruction[3] = 0xc0 | (cmp1_ind << 3) | 2;
-instruction[4] = 0;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-if (char1 != char2)
- {
- /* PSHUFD xmm1, xmm2/m128, imm8 */
- instruction[3] = 0xc0 | (cmp2_ind << 3) | 3;
- sljit_emit_op_custom(compiler, instruction, 5);
- }
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-restart = LABEL();
-#endif
-OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
-
-load_from_mem_sse2(compiler, data_ind, str_ptr_ind);
-fast_forward_char_pair_sse2_compare(compiler, char1, char2, bit, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
-/* PMOVMSKB reg, xmm */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xd7;
-instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-/* BSF r32, r/m32 */
-instruction[0] = 0x0f;
-instruction[1] = 0xbc;
-instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
-sljit_emit_op_custom(compiler, instruction, 3);
-sljit_set_current_flags(compiler, SLJIT_SET_Z);
-
-quit = JUMP(SLJIT_NOT_ZERO);
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
-start = LABEL();
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
-
-partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
-if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, &common->failed_match, partial_quit[1]);
-
-/* Second part (aligned) */
-
-load_from_mem_sse2(compiler, 0, str_ptr_ind);
-fast_forward_char_pair_sse2_compare(compiler, char1, char2, bit, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
-
-/* PMOVMSKB reg, xmm */
-instruction[0] = 0x66;
-instruction[1] = 0x0f;
-instruction[2] = 0xd7;
-instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* BSF r32, r/m32 */
-instruction[0] = 0x0f;
-instruction[1] = 0xbc;
-instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
-sljit_emit_op_custom(compiler, instruction, 3);
-sljit_set_current_flags(compiler, SLJIT_SET_Z);
-
-JUMPTO(SLJIT_ZERO, start);
-
-JUMPHERE(quit);
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-
-if (common->mode != PCRE2_JIT_COMPLETE)
- {
- JUMPHERE(partial_quit[0]);
- JUMPHERE(partial_quit[1]);
- OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
- CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
- }
-else
- add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-if (common->utf && offset > 0)
- {
- SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
-
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
-
- quit = jump_if_utf_char_start(compiler, TMP1);
-
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
- OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, restart);
-
- JUMPHERE(quit);
- }
-#endif
-}
-
-#ifndef _WIN64
-
-static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_sse2_offset(void)
-{
-#if PCRE2_CODE_UNIT_WIDTH == 8
-return 15;
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-return 7;
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-return 3;
-#else
-#error "Unsupported unit width"
-#endif
-}
-
-static void fast_forward_char_pair_sse2(compiler_common *common, sljit_s32 offs1,
- PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)
-{
-DEFINE_COMPILER;
-sljit_u32 bit1 = 0;
-sljit_u32 bit2 = 0;
-sljit_u32 diff = IN_UCHARS(offs1 - offs2);
-sljit_s32 tmp1_ind = sljit_get_register_index(TMP1);
-sljit_s32 tmp2_ind = sljit_get_register_index(TMP2);
-sljit_s32 str_ptr_ind = sljit_get_register_index(STR_PTR);
-sljit_s32 data1_ind = 0;
-sljit_s32 data2_ind = 1;
-sljit_s32 tmp_ind = 2;
-sljit_s32 cmp1a_ind = 3;
-sljit_s32 cmp1b_ind = 4;
-sljit_s32 cmp2a_ind = 5;
-sljit_s32 cmp2b_ind = 6;
-struct sljit_label *start;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-struct sljit_label *restart;
-#endif
-struct sljit_jump *jump[2];
-
-sljit_u8 instruction[8];
-
-SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);
-SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_sse2_offset()));
-SLJIT_ASSERT(tmp1_ind < 8 && tmp2_ind == 1);
-
-/* Initialize. */
-if (common->match_end_ptr != 0)
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
- OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
-
- OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
- CMOV(SLJIT_LESS, STR_END, TMP1, 0);
- }
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
-add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-/* MOVD xmm, r/m32 */
-instruction[0] = 0x66;
-instruction[1] = 0x0f;
-instruction[2] = 0x6e;
-
-if (char1a == char1b)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));
-else
- {
- bit1 = char1a ^ char1b;
- if (is_powerof2(bit1))
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a | bit1));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit1));
- }
- else
- {
- bit1 = 0;
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char1b));
- }
- }
-
-instruction[3] = 0xc0 | (cmp1a_ind << 3) | tmp1_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-if (char1a != char1b)
- {
- instruction[3] = 0xc0 | (cmp1b_ind << 3) | tmp2_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-
-if (char2a == char2b)
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));
-else
- {
- bit2 = char2a ^ char2b;
- if (is_powerof2(bit2))
- {
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a | bit2));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit2));
- }
- else
- {
- bit2 = 0;
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char2b));
- }
- }
-
-instruction[3] = 0xc0 | (cmp2a_ind << 3) | tmp1_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-if (char2a != char2b)
- {
- instruction[3] = 0xc0 | (cmp2b_ind << 3) | tmp2_ind;
- sljit_emit_op_custom(compiler, instruction, 4);
- }
-
-/* PSHUFD xmm1, xmm2/m128, imm8 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x70;
-instruction[4] = 0;
-
-instruction[3] = 0xc0 | (cmp1a_ind << 3) | cmp1a_ind;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-if (char1a != char1b)
- {
- instruction[3] = 0xc0 | (cmp1b_ind << 3) | cmp1b_ind;
- sljit_emit_op_custom(compiler, instruction, 5);
- }
-
-instruction[3] = 0xc0 | (cmp2a_ind << 3) | cmp2a_ind;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-if (char2a != char2b)
- {
- instruction[3] = 0xc0 | (cmp2b_ind << 3) | cmp2b_ind;
- sljit_emit_op_custom(compiler, instruction, 5);
- }
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-restart = LABEL();
-#endif
-
-OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1 - offs2));
-OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
-OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
-OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, ~0xf);
-
-load_from_mem_sse2(compiler, data1_ind, str_ptr_ind);
-
-jump[0] = CMP(SLJIT_EQUAL, STR_PTR, 0, TMP1, 0);
-
-load_from_mem_sse2(compiler, data2_ind, tmp1_ind);
-
-/* MOVDQA xmm1, xmm2/m128 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x6f;
-instruction[3] = 0xc0 | (tmp_ind << 3) | data1_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* PSLLDQ xmm1, xmm2/m128, imm8 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x73;
-instruction[3] = 0xc0 | (7 << 3) | tmp_ind;
-instruction[4] = diff;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-/* PSRLDQ xmm1, xmm2/m128, imm8 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-/* instruction[2] = 0x73; */
-instruction[3] = 0xc0 | (3 << 3) | data2_ind;
-instruction[4] = 16 - diff;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-/* POR xmm1, xmm2/m128 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xeb;
-instruction[3] = 0xc0 | (data2_ind << 3) | tmp_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-jump[1] = JUMP(SLJIT_JUMP);
-
-JUMPHERE(jump[0]);
-
-/* MOVDQA xmm1, xmm2/m128 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x6f;
-instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* PSLLDQ xmm1, xmm2/m128, imm8 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x73;
-instruction[3] = 0xc0 | (7 << 3) | data2_ind;
-instruction[4] = diff;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-JUMPHERE(jump[1]);
-
-OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
-
-fast_forward_char_pair_sse2_compare(compiler, char2a, char2b, bit2, data2_ind, cmp2a_ind, cmp2b_ind, tmp_ind);
-fast_forward_char_pair_sse2_compare(compiler, char1a, char1b, bit1, data1_ind, cmp1a_ind, cmp1b_ind, tmp_ind);
-
-/* PAND xmm1, xmm2/m128 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xdb;
-instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* PMOVMSKB reg, xmm */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xd7;
-instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* Ignore matches before the first STR_PTR. */
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
-
-/* BSF r32, r/m32 */
-instruction[0] = 0x0f;
-instruction[1] = 0xbc;
-instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
-sljit_emit_op_custom(compiler, instruction, 3);
-sljit_set_current_flags(compiler, SLJIT_SET_Z);
-
-jump[0] = JUMP(SLJIT_NOT_ZERO);
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
-
-/* Main loop. */
-instruction[0] = 0x66;
-instruction[1] = 0x0f;
-
-start = LABEL();
-
-load_from_mem_sse2(compiler, data2_ind, str_ptr_ind);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
-add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-load_from_mem_sse2(compiler, data1_ind, str_ptr_ind);
-
-/* PSRLDQ xmm1, xmm2/m128, imm8 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x73;
-instruction[3] = 0xc0 | (3 << 3) | data2_ind;
-instruction[4] = 16 - diff;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-/* MOVDQA xmm1, xmm2/m128 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x6f;
-instruction[3] = 0xc0 | (tmp_ind << 3) | data1_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* PSLLDQ xmm1, xmm2/m128, imm8 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0x73;
-instruction[3] = 0xc0 | (7 << 3) | tmp_ind;
-instruction[4] = diff;
-sljit_emit_op_custom(compiler, instruction, 5);
-
-/* POR xmm1, xmm2/m128 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xeb;
-instruction[3] = 0xc0 | (data2_ind << 3) | tmp_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-fast_forward_char_pair_sse2_compare(compiler, char1a, char1b, bit1, data1_ind, cmp1a_ind, cmp1b_ind, tmp_ind);
-fast_forward_char_pair_sse2_compare(compiler, char2a, char2b, bit2, data2_ind, cmp2a_ind, cmp2b_ind, tmp_ind);
-
-/* PAND xmm1, xmm2/m128 */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xdb;
-instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* PMOVMSKB reg, xmm */
-/* instruction[0] = 0x66; */
-/* instruction[1] = 0x0f; */
-instruction[2] = 0xd7;
-instruction[3] = 0xc0 | (tmp1_ind << 3) | 0;
-sljit_emit_op_custom(compiler, instruction, 4);
-
-/* BSF r32, r/m32 */
-instruction[0] = 0x0f;
-instruction[1] = 0xbc;
-instruction[2] = 0xc0 | (tmp1_ind << 3) | tmp1_ind;
-sljit_emit_op_custom(compiler, instruction, 3);
-sljit_set_current_flags(compiler, SLJIT_SET_Z);
-
-JUMPTO(SLJIT_ZERO, start);
-
-JUMPHERE(jump[0]);
-
-OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-
-add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-
-if (common->match_end_ptr != 0)
- OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-if (common->utf)
- {
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1));
-
- jump[0] = jump_if_utf_char_start(compiler, TMP1);
-
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart);
-
- add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP));
-
- JUMPHERE(jump[0]);
- }
-#endif
-
-OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
-
-if (common->match_end_ptr != 0)
- OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
-}
-
-static BOOL check_fast_forward_char_pair_sse2(compiler_common *common, fast_forward_char_data *chars, int max)
-{
-sljit_s32 i, j, priority, count;
-sljit_u32 priorities;
-PCRE2_UCHAR a1, a2, b1, b2;
-
-priorities = 0;
-
-count = 0;
-for (i = 0; i < max; i++)
- {
- if (chars[i].last_count > 2)
- {
- SLJIT_ASSERT(chars[i].last_count <= 7);
-
- priorities |= (1 << chars[i].last_count);
- count++;
- }
- }
-
-if (count < 2)
- return FALSE;
-
-for (priority = 7; priority > 2; priority--)
- {
- if ((priorities & (1 << priority)) == 0)
- continue;
+ sljit_s32 i, j, max_i = 0, max_j = 0;
+ sljit_u32 max_pri = 0;
+ PCRE2_UCHAR a1, a2, a_pri, b1, b2, b_pri;
for (i = max - 1; i >= 1; i--)
- if (chars[i].last_count >= priority)
+ {
+ if (chars[i].last_count > 2)
{
- SLJIT_ASSERT(chars[i].count <= 2 && chars[i].count >= 1);
-
a1 = chars[i].chars[0];
a2 = chars[i].chars[1];
+ a_pri = chars[i].last_count;
- j = i - max_fast_forward_char_pair_sse2_offset();
+ j = i - max_fast_forward_char_pair_offset();
if (j < 0)
j = 0;
while (j < i)
{
- if (chars[j].last_count >= priority)
+ b_pri = chars[j].last_count;
+ if (b_pri > 2 && a_pri + b_pri >= max_pri)
{
b1 = chars[j].chars[0];
b2 = chars[j].chars[1];
if (a1 != b1 && a1 != b2 && a2 != b1 && a2 != b2)
{
- fast_forward_char_pair_sse2(common, i, a1, a2, j, b1, b2);
- return TRUE;
+ max_pri = a_pri + b_pri;
+ max_i = i;
+ max_j = j;
}
}
j++;
}
}
- }
-
-return FALSE;
-}
+ }
-#endif
+if (max_pri == 0)
+ return FALSE;
-#undef SSE2_COMPARE_TYPE_INDEX
+fast_forward_char_pair_simd(common, max_i, chars[max_i].chars[0], chars[max_i].chars[1], max_j, chars[max_j].chars[0], chars[max_j].chars[1]);
+return TRUE;
+}
-#endif
+#endif /* JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD */
static void fast_forward_first_char2(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
{
@@ -6154,13 +5596,11 @@ if (has_match_end)
CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
}
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND)
+#ifdef JIT_HAS_FAST_FORWARD_CHAR_SIMD
-/* SSE2 accelerated first character search. */
-
-if (sljit_has_cpu_feature(SLJIT_HAS_SSE2))
+if (JIT_HAS_FAST_FORWARD_CHAR_SIMD)
{
- fast_forward_first_char2_sse2(common, char1, char2, offset);
+ fast_forward_char_simd(common, char1, char2, offset);
if (offset > 0)
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offset));
@@ -6267,8 +5707,8 @@ for (i = 0; i < max; i++)
chars[i].last_count = (chars[i].count == 255) ? 0 : 1;
}
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND) && !(defined _WIN64)
-if (sljit_has_cpu_feature(SLJIT_HAS_SSE2) && check_fast_forward_char_pair_sse2(common, chars, max))
+#ifdef JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD
+if (JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD && check_fast_forward_char_pair_simd(common, chars, max))
return TRUE;
#endif
@@ -6353,18 +5793,21 @@ if (common->match_end_ptr != 0)
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
- OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
+ OP2(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
+ add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS));
OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_END, 0, TMP1, 0);
CMOV(SLJIT_GREATER, STR_END, TMP1, 0);
}
else
- OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
+ add_jump(compiler, &common->failed_match, JUMP(SLJIT_LESS));
+ }
SLJIT_ASSERT(range_right >= 0);
-#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);
-#endif
+if (!HAS_VIRTUAL_REGISTERS)
+ OP1(SLJIT_MOV, RETURN_ADDR, 0, SLJIT_IMM, (sljit_sw)update_table);
start = LABEL();
add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0));
@@ -6375,11 +5818,11 @@ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right));
OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(range_right + 1) - 1);
#endif
-#if !(defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);
-#else
-OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);
-#endif
+if (!HAS_VIRTUAL_REGISTERS)
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(RETURN_ADDR, TMP1), 0);
+else
+ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)update_table);
+
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, start);
@@ -6473,9 +5916,17 @@ if (common->match_end_ptr != 0)
if (common->nltype == NLTYPE_FIXED && common->newline > 255)
{
lastchar = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
@@ -6503,9 +5954,15 @@ if (common->nltype == NLTYPE_FIXED && common->newline > 255)
return;
}
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ }
+else
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
+
/* Example: match /^/ to \r\n from offset 1. */
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
move_back(common, NULL, FALSE);
@@ -6586,7 +6043,7 @@ if (!optimize_class(common, start_bits, (start_bits[31] & 0x80) != 0, FALSE, &ma
OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);
- if (sljit_get_register_index(TMP3) >= 0)
+ if (!HAS_VIRTUAL_REGISTERS)
{
OP2(SLJIT_SHL, TMP3, 0, SLJIT_IMM, 1, TMP2, 0);
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, TMP3, 0);
@@ -6693,7 +6150,7 @@ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), -sizeof(sljit_sw));
jump = CMP(SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0);
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
-if (sljit_get_register_index(TMP3) < 0)
+if (HAS_VIRTUAL_REGISTERS)
{
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw)));
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(STACK_TOP), -(3 * sizeof(sljit_sw)));
@@ -6718,7 +6175,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
JUMPHERE(jump);
OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
-if (sljit_get_register_index(TMP3) < 0)
+if (HAS_VIRTUAL_REGISTERS)
{
OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw)));
OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
@@ -6737,7 +6194,11 @@ static void check_wordboundary(compiler_common *common)
DEFINE_COMPILER;
struct sljit_jump *skipread;
jump_list *skipread_list = NULL;
-jump_list *invalid_utf = NULL;
+#ifdef SUPPORT_UNICODE
+struct sljit_label *valid_utf;
+jump_list *invalid_utf1 = NULL;
+#endif /* SUPPORT_UNICODE */
+jump_list *invalid_utf2 = NULL;
#if PCRE2_CODE_UNIT_WIDTH != 8 || defined SUPPORT_UNICODE
struct sljit_jump *jump;
#endif /* PCRE2_CODE_UNIT_WIDTH != 8 || SUPPORT_UNICODE */
@@ -6751,14 +6212,30 @@ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
-if (common->mode == PCRE2_JIT_COMPLETE)
- peek_char_back(common, READ_CHAR_MAX, &invalid_utf);
+#ifdef SUPPORT_UNICODE
+if (common->invalid_utf)
+ {
+ peek_char_back(common, READ_CHAR_MAX, &invalid_utf1);
+
+ if (common->mode != PCRE2_JIT_COMPLETE)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
+ move_back(common, NULL, TRUE);
+ check_start_used_ptr(common);
+ OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);
+ }
+ }
else
+#endif /* SUPPORT_UNICODE */
{
- move_back(common, &invalid_utf, FALSE);
- check_start_used_ptr(common);
- /* No need precise read since match fails anyway. */
- read_char(common, 0, READ_CHAR_MAX, &invalid_utf, READ_CHAR_UPDATE_STR_PTR);
+ if (common->mode == PCRE2_JIT_COMPLETE)
+ peek_char_back(common, READ_CHAR_MAX, NULL);
+ else
+ {
+ move_back(common, NULL, TRUE);
+ check_start_used_ptr(common);
+ read_char(common, 0, READ_CHAR_MAX, NULL, READ_CHAR_UPDATE_STR_PTR);
+ }
}
/* Testing char type. */
@@ -6802,10 +6279,13 @@ JUMPHERE(skipread);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
check_str_end(common, &skipread_list);
-peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf);
+peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf2);
/* Testing char type. This is a code duplication. */
#ifdef SUPPORT_UNICODE
+
+valid_utf = LABEL();
+
if (common->use_ucp)
{
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
@@ -6851,13 +6331,19 @@ sljit_emit_fast_return(compiler, TMP1, 0);
#ifdef SUPPORT_UNICODE
if (common->invalid_utf)
{
- SLJIT_ASSERT(invalid_utf != NULL);
+ set_jumps(invalid_utf1, LABEL());
+
+ peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, NULL);
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR, valid_utf);
- set_jumps(invalid_utf, LABEL());
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, -1);
sljit_emit_fast_return(compiler, TMP1, 0);
- return;
+
+ set_jumps(invalid_utf2, LABEL());
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+ OP1(SLJIT_MOV, TMP2, 0, TMP3, 0);
+ sljit_emit_fast_return(compiler, TMP1, 0);
}
#endif /* SUPPORT_UNICODE */
}
@@ -7225,7 +6711,7 @@ struct sljit_label *label;
int char1_reg;
int char2_reg;
-if (sljit_get_register_index(TMP3) < 0)
+if (HAS_VIRTUAL_REGISTERS)
{
char1_reg = STR_END;
char2_reg = STACK_TOP;
@@ -7307,7 +6793,7 @@ int char2_reg;
int lcc_table;
int opt_type = 0;
-if (sljit_get_register_index(TMP3) < 0)
+if (HAS_VIRTUAL_REGISTERS)
{
char2_reg = STACK_TOP;
lcc_table = STACK_LIMIT;
@@ -7790,8 +7276,6 @@ if (needstype || needsscript)
if (needsscript)
{
// PH hacking
-//fprintf(stderr, "~~B\n");
-
OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
@@ -7845,7 +7329,6 @@ if (needstype || needsscript)
if (!needschar)
{
// PH hacking
-//fprintf(stderr, "~~C\n");
OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
@@ -7860,7 +7343,6 @@ if (needstype || needsscript)
else
{
// PH hacking
-//fprintf(stderr, "~~D\n");
OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 2);
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
@@ -8174,14 +7656,24 @@ struct sljit_label *label;
switch(type)
{
case OP_SOD:
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
+ else
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
return cc;
case OP_SOM:
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ }
+ else
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
return cc;
@@ -8191,9 +7683,7 @@ switch(type)
#ifdef SUPPORT_UNICODE
if (common->invalid_utf)
{
- OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_SIG_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);
- add_jump(compiler, backtracks, JUMP(SLJIT_SIG_LESS));
- add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO));
+ add_jump(compiler, backtracks, CMP((type == OP_NOT_WORD_BOUNDARY) ? SLJIT_NOT_EQUAL : SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0));
return cc;
}
#endif /* SUPPORT_UNICODE */
@@ -8267,17 +7757,24 @@ switch(type)
JUMPHERE(jump[3]);
}
JUMPHERE(jump[0]);
- check_partial(common, FALSE);
+ if (common->mode != PCRE2_JIT_COMPLETE)
+ check_partial(common, TRUE);
return cc;
case OP_EOD:
add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0));
- check_partial(common, FALSE);
+ if (common->mode != PCRE2_JIT_COMPLETE)
+ check_partial(common, TRUE);
return cc;
case OP_DOLL:
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
- OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
+ }
+ else
+ OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
if (!common->endonly)
@@ -8291,8 +7788,13 @@ switch(type)
case OP_DOLLM:
jump[1] = CMP(SLJIT_LESS, STR_PTR, 0, STR_END, 0);
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
- OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
+ }
+ else
+ OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTEOL);
add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
check_partial(common, FALSE);
jump[0] = JUMP(SLJIT_JUMP);
@@ -8327,18 +7829,38 @@ switch(type)
return cc;
case OP_CIRC:
- OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
- add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
- OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
- add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
+ OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
+ add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0));
+ OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
+ add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
+ }
return cc;
case OP_CIRCM:
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
- jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);
- OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
+ /* TMP2 might be used by peek_char_back. */
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);
+ OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
+ jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0);
+ OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL);
+ }
add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32));
jump[0] = JUMP(SLJIT_JUMP);
JUMPHERE(jump[1]);
@@ -8367,11 +7889,16 @@ switch(type)
length = GET(cc, 0);
if (length == 0)
return cc + LINK_SIZE;
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
+ }
+ else
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, begin));
#ifdef SUPPORT_UNICODE
if (common->utf)
{
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, length);
label = LABEL();
add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0));
@@ -8382,9 +7909,8 @@ switch(type)
else
#endif
{
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
- add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP1, 0));
+ add_jump(compiler, backtracks, CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0));
}
check_start_used_ptr(common);
return cc + LINK_SIZE;
@@ -8402,12 +7928,12 @@ static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc)
PCRE2_SPTR start_subject = args->begin;
PCRE2_SPTR end_subject = args->end;
int lgb, rgb, ricount;
-PCRE2_SPTR prevcc, startcc, bptr;
+PCRE2_SPTR prevcc, endcc, bptr;
BOOL first = TRUE;
uint32_t c;
prevcc = cc;
-startcc = NULL;
+endcc = NULL;
do
{
GETCHARINC(c, cc);
@@ -8416,7 +7942,7 @@ do
if (first)
{
lgb = rgb;
- startcc = cc;
+ endcc = cc;
first = FALSE;
continue;
}
@@ -8455,25 +7981,27 @@ do
lgb != ucp_gbExtended_Pictographic)
lgb = rgb;
- prevcc = startcc;
- startcc = cc;
+ prevcc = endcc;
+ endcc = cc;
}
while (cc < end_subject);
-return startcc;
+return endcc;
}
+#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
+
static PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SPTR cc)
{
PCRE2_SPTR start_subject = args->begin;
PCRE2_SPTR end_subject = args->end;
int lgb, rgb, ricount;
-PCRE2_SPTR prevcc, startcc, bptr;
+PCRE2_SPTR prevcc, endcc, bptr;
BOOL first = TRUE;
uint32_t c;
prevcc = cc;
-startcc = NULL;
+endcc = NULL;
do
{
GETCHARINC_INVALID(c, cc, end_subject, break);
@@ -8482,7 +8010,7 @@ do
if (first)
{
lgb = rgb;
- startcc = cc;
+ endcc = cc;
first = FALSE;
continue;
}
@@ -8520,16 +8048,14 @@ do
lgb != ucp_gbExtended_Pictographic)
lgb = rgb;
- prevcc = startcc;
- startcc = cc;
+ prevcc = endcc;
+ endcc = cc;
}
while (cc < end_subject);
-return startcc;
+return endcc;
}
-#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
-
static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc)
{
PCRE2_SPTR start_subject = args->begin;
@@ -8538,7 +8064,10 @@ int lgb, rgb, ricount;
PCRE2_SPTR bptr;
uint32_t c;
-GETCHARINC(c, cc);
+/* Patch by PH */
+/* GETCHARINC(c, cc); */
+c = *cc++;
+
#if PCRE2_CODE_UNIT_WIDTH == 32
if (c >= 0x110000)
return NULL;
@@ -8800,8 +8329,10 @@ switch(type)
if (common->invalid_utf)
add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
#else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_extuni_no_utf));
- add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM,
+ common->invalid_utf ? SLJIT_FUNC_OFFSET(do_extuni_utf_invalid) : SLJIT_FUNC_OFFSET(do_extuni_no_utf));
+ if (!common->utf || common->invalid_utf)
+ add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
#endif
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
@@ -9198,8 +8729,6 @@ if (common->utf && *cc == OP_REFI)
CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop);
// PH hacking
-//fprintf(stderr, "~~E\n");
-
OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
@@ -10759,10 +10288,23 @@ if (ket != OP_KET || bra != OP_BRA)
if (offset != 0)
stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
+/* Skip and count the other alternatives. */
+i = 1;
+while (*cc == OP_ALT)
+ {
+ cc += GET(cc, 1);
+ i++;
+ }
+
if (has_alternatives)
{
if (opcode != OP_ONCE)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ {
+ if (i <= 3)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
+ else
+ BACKTRACK_AS(bracket_backtrack)->u.matching_put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
+ }
if (ket != OP_KETRMAX)
BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
}
@@ -10851,9 +10393,6 @@ if (bra == OP_BRAMINZERO)
if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
count_match(common);
-/* Skip the other alternatives. */
-while (*cc == OP_ALT)
- cc += GET(cc, 1);
cc += 1 + LINK_SIZE;
if (opcode == OP_ONCE)
@@ -11412,174 +10951,232 @@ switch(opcode)
JUMPTO(SLJIT_JUMP, label);
if (jump != NULL)
JUMPHERE(jump);
+ BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
+ break;
}
- else
- {
- charpos_enabled = FALSE;
- charpos_char = 0;
- charpos_othercasebit = 0;
-
- if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI))
- {
- charpos_enabled = TRUE;
#ifdef SUPPORT_UNICODE
- charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]);
-#endif
- if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1))
- {
- charpos_othercasebit = char_get_othercase_bit(common, end + 1);
- if (charpos_othercasebit == 0)
- charpos_enabled = FALSE;
- }
-
- if (charpos_enabled)
- {
- charpos_char = end[1];
- /* Consumpe the OP_CHAR opcode. */
- end += 2;
-#if PCRE2_CODE_UNIT_WIDTH == 8
- SLJIT_ASSERT((charpos_othercasebit >> 8) == 0);
-#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
- SLJIT_ASSERT((charpos_othercasebit >> 9) == 0);
- if ((charpos_othercasebit & 0x100) != 0)
- charpos_othercasebit = (charpos_othercasebit & 0xff) << 8;
+ else if (type == OP_ALLANY && !common->invalid_utf)
+#else
+ else if (type == OP_ALLANY)
#endif
- if (charpos_othercasebit != 0)
- charpos_char |= charpos_othercasebit;
-
- BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE;
- BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char;
- BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit;
- }
- }
-
- if (charpos_enabled)
+ {
+ if (opcode == OP_STAR)
{
- if (opcode == OP_UPTO)
- OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1);
+ if (private_data_ptr == 0)
+ allocate_stack(common, 2);
- /* Search the first instance of charpos_char. */
- jump = JUMP(SLJIT_JUMP);
- label = LABEL();
- if (opcode == OP_UPTO)
- {
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO));
- }
- compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
- JUMPHERE(jump);
+ OP1(SLJIT_MOV, base, offset0, STR_END, 0);
+ OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
- detect_partial_match(common, &backtrack->topbacktracks);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- if (charpos_othercasebit != 0)
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
+ OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
+ process_partial_match(common);
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_END, 0);
+ BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
+ break;
+ }
+#ifdef SUPPORT_UNICODE
+ else if (!common->utf)
+#else
+ else
+#endif
+ {
if (private_data_ptr == 0)
allocate_stack(common, 2);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+
OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
- if (opcode == OP_UPTO)
- {
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
- }
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(max));
- /* Search the last instance of charpos_char. */
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
- detect_partial_match(common, &no_match);
- OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
- if (charpos_othercasebit != 0)
- OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
- if (opcode == OP_STAR)
+ if (common->mode == PCRE2_JIT_COMPLETE)
{
- CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
+ CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
}
else
{
- jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, STR_END, 0);
+ process_partial_match(common);
JUMPHERE(jump);
}
- if (opcode == OP_UPTO)
- {
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, label);
- }
- else
- JUMPTO(SLJIT_JUMP, label);
-
- set_jumps(no_match, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
+ break;
}
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- else if (common->utf)
+ }
+
+ charpos_enabled = FALSE;
+ charpos_char = 0;
+ charpos_othercasebit = 0;
+
+ if ((type != OP_CHAR && type != OP_CHARI) && (*end == OP_CHAR || *end == OP_CHARI))
+ {
+#ifdef SUPPORT_UNICODE
+ charpos_enabled = !common->utf || !HAS_EXTRALEN(end[1]);
+#else
+ charpos_enabled = TRUE;
+#endif
+ if (charpos_enabled && *end == OP_CHARI && char_has_othercase(common, end + 1))
{
- if (private_data_ptr == 0)
- allocate_stack(common, 2);
+ charpos_othercasebit = char_get_othercase_bit(common, end + 1);
+ if (charpos_othercasebit == 0)
+ charpos_enabled = FALSE;
+ }
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
+ if (charpos_enabled)
+ {
+ charpos_char = end[1];
+ /* Consumpe the OP_CHAR opcode. */
+ end += 2;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ SLJIT_ASSERT((charpos_othercasebit >> 8) == 0);
+#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
+ SLJIT_ASSERT((charpos_othercasebit >> 9) == 0);
+ if ((charpos_othercasebit & 0x100) != 0)
+ charpos_othercasebit = (charpos_othercasebit & 0xff) << 8;
+#endif
+ if (charpos_othercasebit != 0)
+ charpos_char |= charpos_othercasebit;
- if (opcode == OP_UPTO)
- OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
+ BACKTRACK_AS(char_iterator_backtrack)->u.charpos.enabled = TRUE;
+ BACKTRACK_AS(char_iterator_backtrack)->u.charpos.chr = charpos_char;
+ BACKTRACK_AS(char_iterator_backtrack)->u.charpos.othercasebit = charpos_othercasebit;
+ }
+ }
- label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ if (charpos_enabled)
+ {
+ if (opcode == OP_UPTO)
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max + 1);
- if (opcode == OP_UPTO)
- {
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, label);
- }
- else
- JUMPTO(SLJIT_JUMP, label);
+ /* Search the first instance of charpos_char. */
+ jump = JUMP(SLJIT_JUMP);
+ label = LABEL();
+ if (opcode == OP_UPTO)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_ZERO));
+ }
+ compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks, FALSE);
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ JUMPHERE(jump);
- set_jumps(no_match, LABEL());
- OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ detect_partial_match(common, &backtrack->topbacktracks);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (charpos_othercasebit != 0)
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
+
+ if (private_data_ptr == 0)
+ allocate_stack(common, 2);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
+ if (opcode == OP_UPTO)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
+ }
+
+ /* Search the last instance of charpos_char. */
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ detect_partial_match(common, &no_match);
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
+ if (charpos_othercasebit != 0)
+ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, charpos_othercasebit);
+ if (opcode == OP_STAR)
+ {
+ CMPTO(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char, label);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
}
-#endif
else
{
- if (private_data_ptr == 0)
- allocate_stack(common, 2);
+ jump = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, charpos_char);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ JUMPHERE(jump);
+ }
- OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
- if (opcode == OP_UPTO)
- OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
+ if (opcode == OP_UPTO)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ JUMPTO(SLJIT_NOT_ZERO, label);
+ }
+ else
+ JUMPTO(SLJIT_JUMP, label);
- label = LABEL();
- detect_partial_match(common, &no_match);
- compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
- if (opcode == OP_UPTO)
- {
- OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, label);
- OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- }
- else
- JUMPTO(SLJIT_JUMP, label);
+ set_jumps(no_match, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ }
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ else if (common->utf)
+ {
+ if (private_data_ptr == 0)
+ allocate_stack(common, 2);
- set_jumps(no_char1_match, LABEL());
- OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
- set_jumps(no_match, LABEL());
- OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
- if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
+
+ if (opcode == OP_UPTO)
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
+
+ detect_partial_match(common, &no_match);
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+
+ if (opcode == OP_UPTO)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
+ }
+
+ detect_partial_match_to(common, label);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+ set_jumps(no_match, LABEL());
+ OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ }
+#endif
+ else
+ {
+ if (private_data_ptr == 0)
+ allocate_stack(common, 2);
+
+ OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
+ if (opcode == OP_UPTO)
+ OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
+
+ detect_partial_match(common, &no_match);
+ label = LABEL();
+ compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
+ if (opcode == OP_UPTO)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
+ add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
}
+
+ detect_partial_match_to(common, label);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
+ set_jumps(no_char1_match, LABEL());
+ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ set_jumps(no_match, LABEL());
+ OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
}
+
BACKTRACK_AS(char_iterator_backtrack)->matchingpath = LABEL();
break;
@@ -11616,25 +11213,47 @@ switch(opcode)
break;
case OP_POSSTAR:
+#if defined SUPPORT_UNICODE
+ if (type == OP_ALLANY && !common->invalid_utf)
+#else
+ if (type == OP_ALLANY)
+#endif
+ {
+ OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
+ process_partial_match(common);
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_END, 0);
+ break;
+ }
+
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
if (common->utf)
{
OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
+ detect_partial_match(common, &no_match);
label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
+ compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
- JUMPTO(SLJIT_JUMP, label);
+ detect_partial_match_to(common, label);
+
set_jumps(no_match, LABEL());
OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
if (fast_str_ptr != 0)
- OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ {
+ if (tmp_base == TMP3)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, TMP3, 0);
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ }
break;
}
#endif
- label = LABEL();
detect_partial_match(common, &no_match);
+ label = LABEL();
compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
- JUMPTO(SLJIT_JUMP, label);
+ detect_partial_match_to(common, label);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
set_jumps(no_char1_match, LABEL());
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
set_jumps(no_match, LABEL());
@@ -11649,23 +11268,52 @@ switch(opcode)
{
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);
OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
+
+ detect_partial_match(common, &no_match);
label = LABEL();
- compile_char1_matchingpath(common, type, cc, &no_match, TRUE);
+ compile_char1_matchingpath(common, type, cc, &no_match, FALSE);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1, STR_PTR, 0);
OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, label);
+ add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
+ detect_partial_match_to(common, label);
+
set_jumps(no_match, LABEL());
OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), POSSESSIVE1);
break;
}
#endif
+
+ if (type == OP_ALLANY)
+ {
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(max));
+
+ if (common->mode == PCRE2_JIT_COMPLETE)
+ {
+ OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
+ CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
+ }
+ else
+ {
+ jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, STR_END, 0);
+ process_partial_match(common);
+ JUMPHERE(jump);
+ }
+
+ if (fast_str_ptr != 0)
+ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), fast_str_ptr, STR_PTR, 0);
+ break;
+ }
+
OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
- label = LABEL();
+
detect_partial_match(common, &no_match);
+ label = LABEL();
compile_char1_matchingpath(common, type, cc, &no_char1_match, FALSE);
OP2(SLJIT_SUB | SLJIT_SET_Z, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
- JUMPTO(SLJIT_NOT_ZERO, label);
+ add_jump(compiler, &no_match, JUMP(SLJIT_ZERO));
+ detect_partial_match_to(common, label);
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+
set_jumps(no_char1_match, LABEL());
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
set_jumps(no_match, LABEL());
@@ -11719,8 +11367,15 @@ if (common->accept_label == NULL)
add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0)));
else
CMPTO(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0), common->accept_label);
-OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
-OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));
+
+if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options));
+ }
+else
+ OP1(SLJIT_MOV_U32, TMP2, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, options));
+
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY);
add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_NOT_ZERO));
OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, PCRE2_NOTEMPTY_ATSTART);
@@ -11728,7 +11383,8 @@ if (common->accept_label == NULL)
add_jump(compiler, &common->accept, JUMP(SLJIT_ZERO));
else
JUMPTO(SLJIT_ZERO, common->accept_label);
-OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+
+OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
if (common->accept_label == NULL)
add_jump(compiler, &common->accept, CMP(SLJIT_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
else
@@ -11778,10 +11434,11 @@ if (opcode == OP_SKIP)
if (opcode == OP_COMMIT_ARG || opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
{
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ if (HAS_VIRTUAL_REGISTERS)
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
}
return ccend;
@@ -12072,11 +11729,12 @@ while (cc < ccend)
SLJIT_ASSERT(common->mark_ptr != 0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->mark_ptr);
allocate_stack(common, common->has_skip_arg ? 5 : 1);
- OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ if (HAS_VIRTUAL_REGISTERS)
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->mark_ptr, TMP2, 0);
- OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
+ OP1(SLJIT_MOV, SLJIT_MEM1(HAS_VIRTUAL_REGISTERS ? TMP1 : ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
if (common->has_skip_arg)
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->control_head_ptr);
@@ -12403,16 +12061,15 @@ PCRE2_SPTR ccprev;
PCRE2_UCHAR bra = OP_BRA;
PCRE2_UCHAR ket;
assert_backtrack *assert;
-sljit_uw *next_update_addr = NULL;
BOOL has_alternatives;
BOOL needs_control_head = FALSE;
struct sljit_jump *brazero = NULL;
-struct sljit_jump *alt1 = NULL;
-struct sljit_jump *alt2 = NULL;
+struct sljit_jump *next_alt = NULL;
struct sljit_jump *once = NULL;
struct sljit_jump *cond = NULL;
struct sljit_label *rmin_label = NULL;
struct sljit_label *exact_label = NULL;
+struct sljit_put_label *put_label = NULL;
if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
{
@@ -12561,7 +12218,7 @@ else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND)
free_stack(common, 1);
alt_max = 2;
- alt1 = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
+ next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
}
}
else if (has_alternatives)
@@ -12569,21 +12226,15 @@ else if (has_alternatives)
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
free_stack(common, 1);
- if (alt_max > 4)
+ if (alt_max > 3)
{
- /* Table jump if alt_max is greater than 4. */
- next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw));
- if (SLJIT_UNLIKELY(next_update_addr == NULL))
- return;
- sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr);
- add_label_addr(common, next_update_addr++);
+ sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0);
+
+ SLJIT_ASSERT(CURRENT_AS(bracket_backtrack)->u.matching_put_label);
+ sljit_set_put_label(CURRENT_AS(bracket_backtrack)->u.matching_put_label, LABEL());
}
else
- {
- if (alt_max == 4)
- alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
- alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
- }
+ next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
}
COMPILE_BACKTRACKINGPATH(current->top);
@@ -12620,7 +12271,7 @@ if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
if (has_alternatives)
{
- alt_count = sizeof(sljit_uw);
+ alt_count = 1;
do
{
current->top = NULL;
@@ -12699,7 +12350,12 @@ if (has_alternatives)
stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
if (opcode != OP_ONCE)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);
+ {
+ if (alt_max <= 3)
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);
+ else
+ put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
+ }
if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
{
@@ -12712,24 +12368,18 @@ if (has_alternatives)
if (opcode != OP_ONCE)
{
- if (alt_max > 4)
- add_label_addr(common, next_update_addr++);
- else
+ if (alt_max <= 3)
{
- if (alt_count != 2 * sizeof(sljit_uw))
- {
- JUMPHERE(alt1);
- if (alt_max == 3 && alt_count == sizeof(sljit_uw))
- alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
- }
- else
+ JUMPHERE(next_alt);
+ alt_count++;
+ if (alt_count < alt_max)
{
- JUMPHERE(alt2);
- if (alt_max == 4)
- alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw));
+ SLJIT_ASSERT(alt_count == 2 && alt_max == 3);
+ next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 1);
}
}
- alt_count += sizeof(sljit_uw);
+ else
+ sljit_set_put_label(put_label, LABEL());
}
COMPILE_BACKTRACKINGPATH(current->top);
@@ -13219,11 +12869,10 @@ int private_data_size = get_recurse_data_length(common, ccbegin, ccend, &needs_c
int alt_count, alt_max, local_size;
backtrack_common altbacktrack;
jump_list *match = NULL;
-sljit_uw *next_update_addr = NULL;
-struct sljit_jump *alt1 = NULL;
-struct sljit_jump *alt2 = NULL;
+struct sljit_jump *next_alt = NULL;
struct sljit_jump *accept_exit = NULL;
struct sljit_label *quit;
+struct sljit_put_label *put_label;
/* Recurse captures then. */
common->then_trap = NULL;
@@ -13284,7 +12933,12 @@ while (1)
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), common->recursive_head_ptr);
if (alt_max > 1 || has_accept)
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count);
+ {
+ if (alt_max > 3)
+ put_label = sljit_emit_put_label(compiler, SLJIT_MEM1(STACK_TOP), STACK(1));
+ else
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count);
+ }
add_jump(compiler, &match, JUMP(SLJIT_JUMP));
@@ -13298,7 +12952,7 @@ while (1)
sljit_emit_fast_enter(compiler, TMP1, 0);
if (has_accept)
- accept_exit = CMP(SLJIT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_max * sizeof (sljit_sw));
+ accept_exit = CMP(SLJIT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, -1);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
/* Save return address. */
@@ -13311,44 +12965,30 @@ while (1)
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
free_stack(common, 2);
- if (alt_max > 4)
+ if (alt_max > 3)
{
- /* Table jump if alt_max is greater than 4. */
- next_update_addr = allocate_read_only_data(common, alt_max * sizeof(sljit_uw));
- if (SLJIT_UNLIKELY(next_update_addr == NULL))
- return;
- sljit_emit_ijump(compiler, SLJIT_JUMP, SLJIT_MEM1(TMP1), (sljit_sw)next_update_addr);
- add_label_addr(common, next_update_addr++);
+ sljit_emit_ijump(compiler, SLJIT_JUMP, TMP1, 0);
+ sljit_set_put_label(put_label, LABEL());
}
else
- {
- if (alt_max == 4)
- alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
- alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, sizeof(sljit_uw));
- }
+ next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
}
else
free_stack(common, has_accept ? 2 : 1);
}
- else if (alt_max > 4)
- add_label_addr(common, next_update_addr++);
+ else if (alt_max > 3)
+ sljit_set_put_label(put_label, LABEL());
else
{
- if (alt_count != 2 * sizeof(sljit_uw))
- {
- JUMPHERE(alt1);
- if (alt_max == 3 && alt_count == sizeof(sljit_uw))
- alt2 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_uw));
- }
- else
+ JUMPHERE(next_alt);
+ if (alt_count + 1 < alt_max)
{
- JUMPHERE(alt2);
- if (alt_max == 4)
- alt1 = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_uw));
+ SLJIT_ASSERT(alt_count == 1 && alt_max == 3);
+ next_alt = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 1);
}
}
- alt_count += sizeof(sljit_uw);
+ alt_count++;
compile_backtrackingpath(common, altbacktrack.top);
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
@@ -13409,7 +13049,7 @@ if (common->accept != NULL)
OP1(SLJIT_MOV, TMP2, 0, STACK_TOP, 0);
allocate_stack(common, 2);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, -1);
}
set_jumps(match, LABEL());
@@ -13444,7 +13084,6 @@ executable_functions *functions;
void *executable_func;
sljit_uw executable_size;
sljit_uw total_length;
-label_addr_list *label_addr;
struct sljit_label *mainloop_label = NULL;
struct sljit_label *continue_match_label;
struct sljit_label *empty_match_found_label = NULL;
@@ -13459,6 +13098,14 @@ struct sljit_jump *end_anchor_failed = NULL;
SLJIT_ASSERT(tables);
+#if HAS_VIRTUAL_REGISTERS == 1
+SLJIT_ASSERT(sljit_get_register_index(TMP3) < 0 && sljit_get_register_index(ARGUMENTS) < 0 && sljit_get_register_index(RETURN_ADDR) < 0);
+#elif HAS_VIRTUAL_REGISTERS == 0
+SLJIT_ASSERT(sljit_get_register_index(TMP3) >= 0 && sljit_get_register_index(ARGUMENTS) >= 0 && sljit_get_register_index(RETURN_ADDR) >= 0);
+#else
+#error "Invalid value for HAS_VIRTUAL_REGISTERS"
+#endif
+
memset(&rootbacktrack, 0, sizeof(backtrack_common));
memset(common, 0, sizeof(compiler_common));
common->re = re;
@@ -13476,6 +13123,7 @@ common->fcc = tables + fcc_offset;
common->lcc = (sljit_sw)(tables + lcc_offset);
common->mode = mode;
common->might_be_empty = re->minlength == 0;
+common->allow_empty_partial = (re->max_lookbehind > 0) || (re->flags & PCRE2_MATCH_EMPTY) != 0;
common->nltype = NLTYPE_FIXED;
switch(re->newline_convention)
{
@@ -13742,7 +13390,7 @@ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
sljit_free_compiler(compiler);
SLJIT_FREE(common->optimized_cbracket, allocator_data);
SLJIT_FREE(common->private_data_ptrs, allocator_data);
- PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
+ PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
return PCRE2_ERROR_NOMEMORY;
}
@@ -13796,7 +13444,7 @@ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
sljit_free_compiler(compiler);
SLJIT_FREE(common->optimized_cbracket, allocator_data);
SLJIT_FREE(common->private_data_ptrs, allocator_data);
- PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
+ PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
return PCRE2_ERROR_NOMEMORY;
}
@@ -13885,7 +13533,7 @@ while (common->currententry != NULL)
sljit_free_compiler(compiler);
SLJIT_FREE(common->optimized_cbracket, allocator_data);
SLJIT_FREE(common->private_data_ptrs, allocator_data);
- PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
+ PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
return PCRE2_ERROR_NOMEMORY;
}
flush_stubs(common);
@@ -14028,16 +13676,11 @@ SLJIT_FREE(common->private_data_ptrs, allocator_data);
executable_func = sljit_generate_code(compiler);
executable_size = sljit_get_generated_code_size(compiler);
-label_addr = common->label_addrs;
-while (label_addr != NULL)
- {
- *label_addr->update_addr = sljit_get_label_addr(label_addr->label);
- label_addr = label_addr->next;
- }
sljit_free_compiler(compiler);
+
if (executable_func == NULL)
{
- PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
+ PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
return PCRE2_ERROR_NOMEMORY;
}
@@ -14052,7 +13695,7 @@ else
/* This case is highly unlikely since we just recently
freed a lot of memory. Not impossible though. */
sljit_free_code(executable_func);
- PRIV(jit_free_rodata)(common->read_only_data_head, compiler->allocator_data);
+ PRIV(jit_free_rodata)(common->read_only_data_head, allocator_data);
return PCRE2_ERROR_NOMEMORY;
}
memset(functions, 0, sizeof(executable_functions));
@@ -14097,18 +13740,12 @@ Returns: 0: success or (*NOJIT) was used
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_jit_compile(pcre2_code *code, uint32_t options)
{
-#ifndef SUPPORT_JIT
-
-(void)code;
-(void)options;
-return PCRE2_ERROR_JIT_BADOPTION;
-
-#else /* SUPPORT_JIT */
-
pcre2_real_code *re = (pcre2_real_code *)code;
-executable_functions *functions;
-uint32_t excluded_options;
-int result;
+
+#ifdef SUPPORT_JIT
+executable_functions *functions = (executable_functions *)re->executable_jit;
+static int executable_allocator_is_working = 0;
+#endif
if (code == NULL)
return PCRE2_ERROR_NULL;
@@ -14116,30 +13753,98 @@ if (code == NULL)
if ((options & ~PUBLIC_JIT_COMPILE_OPTIONS) != 0)
return PCRE2_ERROR_JIT_BADOPTION;
+/* Support for invalid UTF was first introduced in JIT, with the option
+PCRE2_JIT_INVALID_UTF. Later, support was added to the interpreter, and the
+compile-time option PCRE2_MATCH_INVALID_UTF was created. This is now the
+preferred feature, with the earlier option deprecated. However, for backward
+compatibility, if the earlier option is set, it forces the new option so that
+if JIT matching falls back to the interpreter, there is still support for
+invalid UTF. However, if this function has already been successfully called
+without PCRE2_JIT_INVALID_UTF and without PCRE2_MATCH_INVALID_UTF (meaning that
+non-invalid-supporting JIT code was compiled), give an error.
+
+If in the future support for PCRE2_JIT_INVALID_UTF is withdrawn, the following
+actions are needed:
+
+ 1. Remove the definition from pcre2.h.in and from the list in
+ PUBLIC_JIT_COMPILE_OPTIONS above.
+
+ 2. Replace PCRE2_JIT_INVALID_UTF with a local flag in this module.
+
+ 3. Replace PCRE2_JIT_INVALID_UTF in pcre2_jit_test.c.
+
+ 4. Delete the following short block of code. The setting of "re" and
+ "functions" can be moved into the JIT-only block below, but if that is
+ done, (void)re and (void)functions will be needed in the non-JIT case, to
+ avoid compiler warnings.
+*/
+
+if ((options & PCRE2_JIT_INVALID_UTF) != 0)
+ {
+ if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) == 0)
+ {
+#ifdef SUPPORT_JIT
+ if (functions != NULL) return PCRE2_ERROR_JIT_BADOPTION;
+#endif
+ re->overall_options |= PCRE2_MATCH_INVALID_UTF;
+ }
+ }
+
+/* The above tests are run with and without JIT support. This means that
+PCRE2_JIT_INVALID_UTF propagates back into the regex options (ensuring
+interpreter support) even in the absence of JIT. But now, if there is no JIT
+support, give an error return. */
+
+#ifndef SUPPORT_JIT
+return PCRE2_ERROR_JIT_BADOPTION;
+#else /* SUPPORT_JIT */
+
+/* There is JIT support. Do the necessary. */
+
if ((re->flags & PCRE2_NOJIT) != 0) return 0;
-functions = (executable_functions *)re->executable_jit;
+if (executable_allocator_is_working == 0)
+ {
+ /* Checks whether the executable allocator is working. This check
+ might run multiple times in multi-threaded environments, but the
+ result should not be affected by it. */
+ void *ptr = SLJIT_MALLOC_EXEC(32);
+
+ executable_allocator_is_working = -1;
+
+ if (ptr != NULL)
+ {
+ SLJIT_FREE_EXEC(((sljit_u8*)(ptr)) + SLJIT_EXEC_OFFSET(ptr));
+ executable_allocator_is_working = 1;
+ }
+ }
+
+if (executable_allocator_is_working < 0)
+ return PCRE2_ERROR_NOMEMORY;
+
+if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)
+ options |= PCRE2_JIT_INVALID_UTF;
if ((options & PCRE2_JIT_COMPLETE) != 0 && (functions == NULL
|| functions->executable_funcs[0] == NULL)) {
- excluded_options = (PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_PARTIAL_HARD);
- result = jit_compile(code, options & ~excluded_options);
+ uint32_t excluded_options = (PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_PARTIAL_HARD);
+ int result = jit_compile(code, options & ~excluded_options);
if (result != 0)
return result;
}
if ((options & PCRE2_JIT_PARTIAL_SOFT) != 0 && (functions == NULL
|| functions->executable_funcs[1] == NULL)) {
- excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_HARD);
- result = jit_compile(code, options & ~excluded_options);
+ uint32_t excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_HARD);
+ int result = jit_compile(code, options & ~excluded_options);
if (result != 0)
return result;
}
if ((options & PCRE2_JIT_PARTIAL_HARD) != 0 && (functions == NULL
|| functions->executable_funcs[2] == NULL)) {
- excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT);
- result = jit_compile(code, options & ~excluded_options);
+ uint32_t excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT);
+ int result = jit_compile(code, options & ~excluded_options);
if (result != 0)
return result;
}
diff --git a/thirdparty/pcre2/src/pcre2_jit_match.c b/thirdparty/pcre2/src/pcre2_jit_match.c
index eee038644d..7e13b8cfee 100644
--- a/thirdparty/pcre2/src/pcre2_jit_match.c
+++ b/thirdparty/pcre2/src/pcre2_jit_match.c
@@ -74,7 +74,6 @@ Arguments:
options option bits
match_data points to a match_data block
mcontext points to a match context
- jit_stack points to a JIT stack
Returns: > 0 => success; value is the number of ovector pairs filled
= 0 => success, but ovector is not big enough
diff --git a/thirdparty/pcre2/src/pcre2_jit_neon_inc.h b/thirdparty/pcre2/src/pcre2_jit_neon_inc.h
new file mode 100644
index 0000000000..55b1f32ac9
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_jit_neon_inc.h
@@ -0,0 +1,321 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ This module by Zoltan Herczeg and Sebastian Pop
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016-2019 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+# if defined(FFCS)
+# if defined(FF_UTF)
+# define FF_FUN ffcs_utf
+# else
+# define FF_FUN ffcs
+# endif
+
+# elif defined(FFCS_2)
+# if defined(FF_UTF)
+# define FF_FUN ffcs_2_utf
+# else
+# define FF_FUN ffcs_2
+# endif
+
+# elif defined(FFCS_MASK)
+# if defined(FF_UTF)
+# define FF_FUN ffcs_mask_utf
+# else
+# define FF_FUN ffcs_mask
+# endif
+
+# elif defined(FFCPS_0)
+# if defined (FF_UTF)
+# define FF_FUN ffcps_0_utf
+# else
+# define FF_FUN ffcps_0
+# endif
+
+# elif defined (FFCPS_1)
+# if defined (FF_UTF)
+# define FF_FUN ffcps_1_utf
+# else
+# define FF_FUN ffcps_1
+# endif
+
+# elif defined (FFCPS_DEFAULT)
+# if defined (FF_UTF)
+# define FF_FUN ffcps_default_utf
+# else
+# define FF_FUN ffcps_default
+# endif
+# endif
+
+static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 *str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars)
+#undef FF_FUN
+{
+quad_word qw;
+int_char ic;
+ic.x = chars;
+
+#if defined(FFCS)
+sljit_u8 c1 = ic.c.c1;
+vect_t vc1 = VDUPQ(c1);
+
+#elif defined(FFCS_2)
+sljit_u8 c1 = ic.c.c1;
+vect_t vc1 = VDUPQ(c1);
+sljit_u8 c2 = ic.c.c2;
+vect_t vc2 = VDUPQ(c2);
+
+#elif defined(FFCS_MASK)
+sljit_u8 c1 = ic.c.c1;
+vect_t vc1 = VDUPQ(c1);
+sljit_u8 mask = ic.c.c2;
+vect_t vmask = VDUPQ(mask);
+#endif
+
+#if defined(FFCPS)
+compare_type compare1_type = compare_match1;
+compare_type compare2_type = compare_match1;
+vect_t cmp1a, cmp1b, cmp2a, cmp2b;
+const sljit_u32 diff = IN_UCHARS(offs1 - offs2);
+PCRE2_UCHAR char1a = ic.c.c1;
+PCRE2_UCHAR char2a = ic.c.c3;
+
+# ifdef FFCPS_CHAR1A2A
+cmp1a = VDUPQ(char1a);
+cmp2a = VDUPQ(char2a);
+# else
+PCRE2_UCHAR char1b = ic.c.c2;
+PCRE2_UCHAR char2b = ic.c.c4;
+if (char1a == char1b)
+ cmp1a = VDUPQ(char1a);
+else
+ {
+ sljit_u32 bit1 = char1a ^ char1b;
+ if (is_powerof2(bit1))
+ {
+ compare1_type = compare_match1i;
+ cmp1a = VDUPQ(char1a | bit1);
+ cmp1b = VDUPQ(bit1);
+ }
+ else
+ {
+ compare1_type = compare_match2;
+ cmp1a = VDUPQ(char1a);
+ cmp1b = VDUPQ(char1b);
+ }
+ }
+
+if (char2a == char2b)
+ cmp2a = VDUPQ(char2a);
+else
+ {
+ sljit_u32 bit2 = char2a ^ char2b;
+ if (is_powerof2(bit2))
+ {
+ compare2_type = compare_match1i;
+ cmp2a = VDUPQ(char2a | bit2);
+ cmp2b = VDUPQ(bit2);
+ }
+ else
+ {
+ compare2_type = compare_match2;
+ cmp2a = VDUPQ(char2a);
+ cmp2b = VDUPQ(char2b);
+ }
+ }
+# endif
+
+str_ptr += IN_UCHARS(offs1);
+#endif
+
+#if PCRE2_CODE_UNIT_WIDTH != 8
+vect_t char_mask = VDUPQ(0xff);
+#endif
+
+#if defined(FF_UTF)
+restart:;
+#endif
+
+#if defined(FFCPS)
+sljit_u8 *p1 = str_ptr - diff;
+#endif
+sljit_s32 align_offset = ((uint64_t)str_ptr & 0xf);
+str_ptr = (sljit_u8 *) ((uint64_t)str_ptr & ~0xf);
+vect_t data = VLD1Q(str_ptr);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+data = VANDQ(data, char_mask);
+#endif
+
+#if defined(FFCS)
+vect_t eq = VCEQQ(data, vc1);
+
+#elif defined(FFCS_2)
+vect_t eq1 = VCEQQ(data, vc1);
+vect_t eq2 = VCEQQ(data, vc2);
+vect_t eq = VORRQ(eq1, eq2);
+
+#elif defined(FFCS_MASK)
+vect_t eq = VORRQ(data, vmask);
+eq = VCEQQ(eq, vc1);
+
+#elif defined(FFCPS)
+# if defined(FFCPS_DIFF1)
+vect_t prev_data = data;
+# endif
+
+vect_t data2;
+if (p1 < str_ptr)
+ {
+ data2 = VLD1Q(str_ptr - diff);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ data2 = VANDQ(data2, char_mask);
+#endif
+ }
+else
+ data2 = shift_left_n_lanes(data, offs1 - offs2);
+
+data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
+data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
+vect_t eq = VANDQ(data, data2);
+#endif
+
+VST1Q(qw.mem, eq);
+/* Ignore matches before the first STR_PTR. */
+if (align_offset < 8)
+ {
+ qw.dw[0] >>= align_offset * 8;
+ if (qw.dw[0])
+ {
+ str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8;
+ goto match;
+ }
+ if (qw.dw[1])
+ {
+ str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;
+ goto match;
+ }
+ }
+else
+ {
+ qw.dw[1] >>= (align_offset - 8) * 8;
+ if (qw.dw[1])
+ {
+ str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8;
+ goto match;
+ }
+ }
+str_ptr += 16;
+
+while (str_ptr < str_end)
+ {
+ vect_t orig_data = VLD1Q(str_ptr);
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ orig_data = VANDQ(orig_data, char_mask);
+#endif
+ data = orig_data;
+
+#if defined(FFCS)
+ eq = VCEQQ(data, vc1);
+
+#elif defined(FFCS_2)
+ eq1 = VCEQQ(data, vc1);
+ eq2 = VCEQQ(data, vc2);
+ eq = VORRQ(eq1, eq2);
+
+#elif defined(FFCS_MASK)
+ eq = VORRQ(data, vmask);
+ eq = VCEQQ(eq, vc1);
+#endif
+
+#if defined(FFCPS)
+# if defined (FFCPS_DIFF1)
+ data2 = VEXTQ(prev_data, data, VECTOR_FACTOR - 1);
+# else
+ data2 = VLD1Q(str_ptr - diff);
+# if PCRE2_CODE_UNIT_WIDTH != 8
+ data2 = VANDQ(data2, char_mask);
+# endif
+# endif
+
+# ifdef FFCPS_CHAR1A2A
+ data = VCEQQ(data, cmp1a);
+ data2 = VCEQQ(data2, cmp2a);
+# else
+ data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
+ data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
+# endif
+
+ eq = VANDQ(data, data2);
+#endif
+
+ VST1Q(qw.mem, eq);
+ if (qw.dw[0])
+ str_ptr += __builtin_ctzll(qw.dw[0]) / 8;
+ else if (qw.dw[1])
+ str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;
+ else {
+ str_ptr += 16;
+#if defined (FFCPS_DIFF1)
+ prev_data = orig_data;
+#endif
+ continue;
+ }
+
+match:;
+ if (str_ptr >= str_end)
+ /* Failed match. */
+ return NULL;
+
+#if defined(FF_UTF)
+ if (utf_continue(str_ptr + IN_UCHARS(-offs1)))
+ {
+ /* Not a match. */
+ str_ptr += IN_UCHARS(1);
+ goto restart;
+ }
+#endif
+
+ /* Match. */
+#if defined (FFCPS)
+ str_ptr -= IN_UCHARS(offs1);
+#endif
+ return str_ptr;
+ }
+
+/* Failed match. */
+return NULL;
+}
diff --git a/thirdparty/pcre2/src/pcre2_jit_simd_inc.h b/thirdparty/pcre2/src/pcre2_jit_simd_inc.h
new file mode 100644
index 0000000000..f7d56b29f8
--- /dev/null
+++ b/thirdparty/pcre2/src/pcre2_jit_simd_inc.h
@@ -0,0 +1,993 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ This module by Zoltan Herczeg
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016-2019 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND)
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+static struct sljit_jump *jump_if_utf_char_start(struct sljit_compiler *compiler, sljit_s32 reg)
+{
+#if PCRE2_CODE_UNIT_WIDTH == 8
+OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xc0);
+return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0x80);
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+OP2(SLJIT_AND, reg, 0, reg, 0, SLJIT_IMM, 0xfc00);
+return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00);
+#else
+#error "Unknown code width"
+#endif
+}
+#endif
+
+static sljit_s32 character_to_int32(PCRE2_UCHAR chr)
+{
+sljit_u32 value = chr;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+#define SSE2_COMPARE_TYPE_INDEX 0
+return (sljit_s32)((value << 24) | (value << 16) | (value << 8) | value);
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+#define SSE2_COMPARE_TYPE_INDEX 1
+return (sljit_s32)((value << 16) | value);
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+#define SSE2_COMPARE_TYPE_INDEX 2
+return (sljit_s32)(value);
+#else
+#error "Unsupported unit width"
+#endif
+}
+
+static void load_from_mem_sse2(struct sljit_compiler *compiler, sljit_s32 dst_xmm_reg, sljit_s32 src_general_reg, sljit_s8 offset)
+{
+sljit_u8 instruction[5];
+
+SLJIT_ASSERT(dst_xmm_reg < 8);
+SLJIT_ASSERT(src_general_reg < 8);
+
+/* MOVDQA xmm1, xmm2/m128 */
+instruction[0] = ((sljit_u8)offset & 0xf) == 0 ? 0x66 : 0xf3;
+instruction[1] = 0x0f;
+instruction[2] = 0x6f;
+
+if (offset == 0)
+ {
+ instruction[3] = (dst_xmm_reg << 3) | src_general_reg;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ return;
+ }
+
+instruction[3] = 0x40 | (dst_xmm_reg << 3) | src_general_reg;
+instruction[4] = (sljit_u8)offset;
+sljit_emit_op_custom(compiler, instruction, 5);
+}
+
+typedef enum {
+ sse2_compare_match1,
+ sse2_compare_match1i,
+ sse2_compare_match2,
+} sse2_compare_type;
+
+static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, sse2_compare_type compare_type,
+ int step, sljit_s32 dst_ind, sljit_s32 cmp1_ind, sljit_s32 cmp2_ind, sljit_s32 tmp_ind)
+{
+sljit_u8 instruction[4];
+instruction[0] = 0x66;
+instruction[1] = 0x0f;
+
+SLJIT_ASSERT(step >= 0 && step <= 3);
+
+if (compare_type != sse2_compare_match2)
+ {
+ if (step == 0)
+ {
+ if (compare_type == sse2_compare_match1i)
+ {
+ /* POR xmm1, xmm2/m128 */
+ /* instruction[0] = 0x66; */
+ /* instruction[1] = 0x0f; */
+ instruction[2] = 0xeb;
+ instruction[3] = 0xc0 | (dst_ind << 3) | cmp2_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+ return;
+ }
+
+ if (step != 2)
+ return;
+
+ /* PCMPEQB/W/D xmm1, xmm2/m128 */
+ /* instruction[0] = 0x66; */
+ /* instruction[1] = 0x0f; */
+ instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
+ instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ return;
+ }
+
+switch (step)
+ {
+ case 0:
+ /* MOVDQA xmm1, xmm2/m128 */
+ /* instruction[0] = 0x66; */
+ /* instruction[1] = 0x0f; */
+ instruction[2] = 0x6f;
+ instruction[3] = 0xc0 | (tmp_ind << 3) | dst_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ return;
+
+ case 1:
+ /* PCMPEQB/W/D xmm1, xmm2/m128 */
+ /* instruction[0] = 0x66; */
+ /* instruction[1] = 0x0f; */
+ instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
+ instruction[3] = 0xc0 | (dst_ind << 3) | cmp1_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ return;
+
+ case 2:
+ /* PCMPEQB/W/D xmm1, xmm2/m128 */
+ /* instruction[0] = 0x66; */
+ /* instruction[1] = 0x0f; */
+ instruction[2] = 0x74 + SSE2_COMPARE_TYPE_INDEX;
+ instruction[3] = 0xc0 | (tmp_ind << 3) | cmp2_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ return;
+
+ case 3:
+ /* POR xmm1, xmm2/m128 */
+ /* instruction[0] = 0x66; */
+ /* instruction[1] = 0x0f; */
+ instruction[2] = 0xeb;
+ instruction[3] = 0xc0 | (dst_ind << 3) | tmp_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ return;
+ }
+}
+
+#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2))
+
+static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
+{
+DEFINE_COMPILER;
+struct sljit_label *start;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+struct sljit_label *restart;
+#endif
+struct sljit_jump *quit;
+struct sljit_jump *partial_quit[2];
+sse2_compare_type compare_type = sse2_compare_match1;
+sljit_u8 instruction[8];
+sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);
+sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);
+sljit_s32 data_ind = 0;
+sljit_s32 tmp_ind = 1;
+sljit_s32 cmp1_ind = 2;
+sljit_s32 cmp2_ind = 3;
+sljit_u32 bit = 0;
+int i;
+
+SLJIT_UNUSED_ARG(offset);
+
+if (char1 != char2)
+ {
+ bit = char1 ^ char2;
+ compare_type = sse2_compare_match1i;
+
+ if (!is_powerof2(bit))
+ {
+ bit = 0;
+ compare_type = sse2_compare_match2;
+ }
+ }
+
+partial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+if (common->mode == PCRE2_JIT_COMPLETE)
+ add_jump(compiler, &common->failed_match, partial_quit[0]);
+
+/* First part (unaligned start) */
+
+OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1 | bit));
+
+SLJIT_ASSERT(tmp1_reg_ind < 8);
+
+/* MOVD xmm, r/m32 */
+instruction[0] = 0x66;
+instruction[1] = 0x0f;
+instruction[2] = 0x6e;
+instruction[3] = 0xc0 | (cmp1_ind << 3) | tmp1_reg_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (char1 != char2)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(bit != 0 ? bit : char2));
+
+ /* MOVD xmm, r/m32 */
+ instruction[3] = 0xc0 | (cmp2_ind << 3) | tmp1_reg_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+
+OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
+
+/* PSHUFD xmm1, xmm2/m128, imm8 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x70;
+instruction[3] = 0xc0 | (cmp1_ind << 3) | cmp1_ind;
+instruction[4] = 0;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+if (char1 != char2)
+ {
+ /* PSHUFD xmm1, xmm2/m128, imm8 */
+ instruction[3] = 0xc0 | (cmp2_ind << 3) | cmp2_ind;
+ sljit_emit_op_custom(compiler, instruction, 5);
+ }
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+restart = LABEL();
+#endif
+OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
+
+load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);
+for (i = 0; i < 4; i++)
+ fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
+
+/* PMOVMSKB reg, xmm */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xd7;
+instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
+
+quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);
+
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+/* Second part (aligned) */
+start = LABEL();
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
+
+partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+if (common->mode == PCRE2_JIT_COMPLETE)
+ add_jump(compiler, &common->failed_match, partial_quit[1]);
+
+load_from_mem_sse2(compiler, data_ind, str_ptr_reg_ind, 0);
+for (i = 0; i < 4; i++)
+ fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
+
+/* PMOVMSKB reg, xmm */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xd7;
+instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | data_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);
+
+JUMPHERE(quit);
+
+/* BSF r32, r/m32 */
+instruction[0] = 0x0f;
+instruction[1] = 0xbc;
+instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;
+sljit_emit_op_custom(compiler, instruction, 3);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+
+if (common->mode != PCRE2_JIT_COMPLETE)
+ {
+ JUMPHERE(partial_quit[0]);
+ JUMPHERE(partial_quit[1]);
+ OP2(SLJIT_SUB | SLJIT_SET_GREATER, SLJIT_UNUSED, 0, STR_PTR, 0, STR_END, 0);
+ CMOV(SLJIT_GREATER, STR_PTR, STR_END, 0);
+ }
+else
+ add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+if (common->utf && offset > 0)
+ {
+ SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
+
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
+
+ quit = jump_if_utf_char_start(compiler, TMP1);
+
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+ OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, restart);
+
+ JUMPHERE(quit);
+ }
+#endif
+}
+
+#ifndef _WIN64
+
+static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void)
+{
+#if PCRE2_CODE_UNIT_WIDTH == 8
+return 15;
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+return 7;
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+return 3;
+#else
+#error "Unsupported unit width"
+#endif
+}
+
+#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SSE2))
+
+static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1,
+ PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)
+{
+DEFINE_COMPILER;
+sse2_compare_type compare1_type = sse2_compare_match1;
+sse2_compare_type compare2_type = sse2_compare_match1;
+sljit_u32 bit1 = 0;
+sljit_u32 bit2 = 0;
+sljit_u32 diff = IN_UCHARS(offs1 - offs2);
+sljit_s32 tmp1_reg_ind = sljit_get_register_index(TMP1);
+sljit_s32 tmp2_reg_ind = sljit_get_register_index(TMP2);
+sljit_s32 str_ptr_reg_ind = sljit_get_register_index(STR_PTR);
+sljit_s32 data1_ind = 0;
+sljit_s32 data2_ind = 1;
+sljit_s32 tmp1_ind = 2;
+sljit_s32 tmp2_ind = 3;
+sljit_s32 cmp1a_ind = 4;
+sljit_s32 cmp1b_ind = 5;
+sljit_s32 cmp2a_ind = 6;
+sljit_s32 cmp2b_ind = 7;
+struct sljit_label *start;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+struct sljit_label *restart;
+#endif
+struct sljit_jump *jump[2];
+sljit_u8 instruction[8];
+int i;
+
+SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);
+SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset()));
+SLJIT_ASSERT(tmp1_reg_ind < 8 && tmp2_reg_ind == 1);
+
+/* Initialize. */
+if (common->match_end_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+ OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
+
+ OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
+ CMOV(SLJIT_LESS, STR_END, TMP1, 0);
+ }
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
+add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+/* MOVD xmm, r/m32 */
+instruction[0] = 0x66;
+instruction[1] = 0x0f;
+instruction[2] = 0x6e;
+
+if (char1a == char1b)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));
+else
+ {
+ bit1 = char1a ^ char1b;
+ if (is_powerof2(bit1))
+ {
+ compare1_type = sse2_compare_match1i;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a | bit1));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit1));
+ }
+ else
+ {
+ compare1_type = sse2_compare_match2;
+ bit1 = 0;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char1a));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char1b));
+ }
+ }
+
+instruction[3] = 0xc0 | (cmp1a_ind << 3) | tmp1_reg_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (char1a != char1b)
+ {
+ instruction[3] = 0xc0 | (cmp1b_ind << 3) | tmp2_reg_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+
+if (char2a == char2b)
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));
+else
+ {
+ bit2 = char2a ^ char2b;
+ if (is_powerof2(bit2))
+ {
+ compare2_type = sse2_compare_match1i;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a | bit2));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(bit2));
+ }
+ else
+ {
+ compare2_type = sse2_compare_match2;
+ bit2 = 0;
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, character_to_int32(char2a));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, character_to_int32(char2b));
+ }
+ }
+
+instruction[3] = 0xc0 | (cmp2a_ind << 3) | tmp1_reg_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+if (char2a != char2b)
+ {
+ instruction[3] = 0xc0 | (cmp2b_ind << 3) | tmp2_reg_ind;
+ sljit_emit_op_custom(compiler, instruction, 4);
+ }
+
+/* PSHUFD xmm1, xmm2/m128, imm8 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x70;
+instruction[4] = 0;
+
+instruction[3] = 0xc0 | (cmp1a_ind << 3) | cmp1a_ind;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+if (char1a != char1b)
+ {
+ instruction[3] = 0xc0 | (cmp1b_ind << 3) | cmp1b_ind;
+ sljit_emit_op_custom(compiler, instruction, 5);
+ }
+
+instruction[3] = 0xc0 | (cmp2a_ind << 3) | cmp2a_ind;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+if (char2a != char2b)
+ {
+ instruction[3] = 0xc0 | (cmp2b_ind << 3) | cmp2b_ind;
+ sljit_emit_op_custom(compiler, instruction, 5);
+ }
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+restart = LABEL();
+#endif
+
+OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, diff);
+OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
+OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~0xf);
+
+load_from_mem_sse2(compiler, data1_ind, str_ptr_reg_ind, 0);
+
+jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0);
+
+load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff);
+jump[1] = JUMP(SLJIT_JUMP);
+
+JUMPHERE(jump[0]);
+
+/* MOVDQA xmm1, xmm2/m128 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x6f;
+instruction[3] = 0xc0 | (data2_ind << 3) | data1_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+/* PSLLDQ xmm1, imm8 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0x73;
+instruction[3] = 0xc0 | (7 << 3) | data2_ind;
+instruction[4] = diff;
+sljit_emit_op_custom(compiler, instruction, 5);
+
+JUMPHERE(jump[1]);
+
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
+
+for (i = 0; i < 4; i++)
+ {
+ fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);
+ fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);
+ }
+
+/* PAND xmm1, xmm2/m128 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xdb;
+instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+/* PMOVMSKB reg, xmm */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xd7;
+instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | 0;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+/* Ignore matches before the first STR_PTR. */
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
+
+jump[0] = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);
+
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
+
+/* Main loop. */
+start = LABEL();
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
+add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+load_from_mem_sse2(compiler, data1_ind, str_ptr_reg_ind, 0);
+load_from_mem_sse2(compiler, data2_ind, str_ptr_reg_ind, -(sljit_s8)diff);
+
+for (i = 0; i < 4; i++)
+ {
+ fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind);
+ fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind);
+ }
+
+/* PAND xmm1, xmm2/m128 */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xdb;
+instruction[3] = 0xc0 | (data1_ind << 3) | data2_ind;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+/* PMOVMSKB reg, xmm */
+/* instruction[0] = 0x66; */
+/* instruction[1] = 0x0f; */
+instruction[2] = 0xd7;
+instruction[3] = 0xc0 | (tmp1_reg_ind << 3) | 0;
+sljit_emit_op_custom(compiler, instruction, 4);
+
+CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);
+
+JUMPHERE(jump[0]);
+
+/* BSF r32, r/m32 */
+instruction[0] = 0x0f;
+instruction[1] = 0xbc;
+instruction[2] = 0xc0 | (tmp1_reg_ind << 3) | tmp1_reg_ind;
+sljit_emit_op_custom(compiler, instruction, 3);
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+
+add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+if (common->match_end_ptr != 0)
+ OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1));
+
+ jump[0] = jump_if_utf_char_start(compiler, TMP1);
+
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart);
+
+ add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP));
+
+ JUMPHERE(jump[0]);
+ }
+#endif
+
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
+
+if (common->match_end_ptr != 0)
+ OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
+}
+
+#endif /* !_WIN64 */
+
+#undef SSE2_COMPARE_TYPE_INDEX
+
+#endif /* SLJIT_CONFIG_X86 && !SUPPORT_VALGRIND */
+
+#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 && (defined __ARM_NEON || defined __ARM_NEON__))
+
+#include <arm_neon.h>
+
+typedef union {
+ unsigned int x;
+ struct { unsigned char c1, c2, c3, c4; } c;
+} int_char;
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+static SLJIT_INLINE int utf_continue(sljit_u8 *s)
+{
+#if PCRE2_CODE_UNIT_WIDTH == 8
+return (*s & 0xc0) == 0x80;
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+return (*s & 0xfc00) == 0xdc00;
+#else
+#error "Unknown code width"
+#endif
+}
+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+# define VECTOR_FACTOR 16
+# define vect_t uint8x16_t
+# define VLD1Q(X) vld1q_u8((sljit_u8 *)(X))
+# define VCEQQ vceqq_u8
+# define VORRQ vorrq_u8
+# define VST1Q vst1q_u8
+# define VDUPQ vdupq_n_u8
+# define VEXTQ vextq_u8
+# define VANDQ vandq_u8
+typedef union {
+ uint8_t mem[16];
+ uint64_t dw[2];
+} quad_word;
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+# define VECTOR_FACTOR 8
+# define vect_t uint16x8_t
+# define VLD1Q(X) vld1q_u16((sljit_u16 *)(X))
+# define VCEQQ vceqq_u16
+# define VORRQ vorrq_u16
+# define VST1Q vst1q_u16
+# define VDUPQ vdupq_n_u16
+# define VEXTQ vextq_u16
+# define VANDQ vandq_u16
+typedef union {
+ uint16_t mem[8];
+ uint64_t dw[2];
+} quad_word;
+#else
+# define VECTOR_FACTOR 4
+# define vect_t uint32x4_t
+# define VLD1Q(X) vld1q_u32((sljit_u32 *)(X))
+# define VCEQQ vceqq_u32
+# define VORRQ vorrq_u32
+# define VST1Q vst1q_u32
+# define VDUPQ vdupq_n_u32
+# define VEXTQ vextq_u32
+# define VANDQ vandq_u32
+typedef union {
+ uint32_t mem[4];
+ uint64_t dw[2];
+} quad_word;
+#endif
+
+#define FFCS
+#include "pcre2_jit_neon_inc.h"
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+# define FF_UTF
+# include "pcre2_jit_neon_inc.h"
+# undef FF_UTF
+#endif
+#undef FFCS
+
+#define FFCS_2
+#include "pcre2_jit_neon_inc.h"
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+# define FF_UTF
+# include "pcre2_jit_neon_inc.h"
+# undef FF_UTF
+#endif
+#undef FFCS_2
+
+#define FFCS_MASK
+#include "pcre2_jit_neon_inc.h"
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+# define FF_UTF
+# include "pcre2_jit_neon_inc.h"
+# undef FF_UTF
+#endif
+#undef FFCS_MASK
+
+#define JIT_HAS_FAST_FORWARD_CHAR_SIMD 1
+
+static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
+{
+DEFINE_COMPILER;
+int_char ic;
+struct sljit_jump *partial_quit;
+/* Save temporary registers. */
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0);
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP3, 0);
+
+/* Prepare function arguments */
+OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0);
+OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0);
+OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, offset);
+
+if (char1 == char2)
+ {
+ ic.c.c1 = char1;
+ ic.c.c2 = char2;
+ OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf && offset > 0)
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_utf));
+ else
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs));
+#else
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs));
+#endif
+ }
+else
+ {
+ PCRE2_UCHAR mask = char1 ^ char2;
+ if (is_powerof2(mask))
+ {
+ ic.c.c1 = char1 | mask;
+ ic.c.c2 = mask;
+ OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf && offset > 0)
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_mask_utf));
+ else
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_mask));
+#else
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_mask));
+#endif
+ }
+ else
+ {
+ ic.c.c1 = char1;
+ ic.c.c2 = char2;
+ OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);
+
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf && offset > 0)
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_2_utf));
+ else
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_2));
+#else
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(UW) | SLJIT_ARG3(UW) | SLJIT_ARG4(UW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcs_2));
+#endif
+ }
+ }
+/* Restore registers. */
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1);
+
+/* Check return value. */
+partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+if (common->mode == PCRE2_JIT_COMPLETE)
+ add_jump(compiler, &common->failed_match, partial_quit);
+
+/* Fast forward STR_PTR to the result of memchr. */
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
+
+if (common->mode != PCRE2_JIT_COMPLETE)
+ JUMPHERE(partial_quit);
+}
+
+typedef enum {
+ compare_match1,
+ compare_match1i,
+ compare_match2,
+} compare_type;
+
+static inline vect_t fast_forward_char_pair_compare(compare_type ctype, vect_t dst, vect_t cmp1, vect_t cmp2)
+{
+if (ctype == compare_match2)
+ {
+ vect_t tmp = dst;
+ dst = VCEQQ(dst, cmp1);
+ tmp = VCEQQ(tmp, cmp2);
+ dst = VORRQ(dst, tmp);
+ return dst;
+ }
+
+if (ctype == compare_match1i)
+ dst = VORRQ(dst, cmp2);
+dst = VCEQQ(dst, cmp1);
+return dst;
+}
+
+static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void)
+{
+#if PCRE2_CODE_UNIT_WIDTH == 8
+return 15;
+#elif PCRE2_CODE_UNIT_WIDTH == 16
+return 7;
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+return 3;
+#else
+#error "Unsupported unit width"
+#endif
+}
+
+/* ARM doesn't have a shift left across lanes. */
+static SLJIT_INLINE vect_t shift_left_n_lanes(vect_t a, sljit_u8 n)
+{
+vect_t zero = VDUPQ(0);
+SLJIT_ASSERT(0 < n && n < VECTOR_FACTOR);
+/* VEXTQ takes an immediate as last argument. */
+#define C(X) case X: return VEXTQ(zero, a, VECTOR_FACTOR - X);
+switch (n)
+ {
+ C(1); C(2); C(3);
+#if PCRE2_CODE_UNIT_WIDTH != 32
+ C(4); C(5); C(6); C(7);
+# if PCRE2_CODE_UNIT_WIDTH != 16
+ C(8); C(9); C(10); C(11); C(12); C(13); C(14); C(15);
+# endif
+#endif
+ default:
+ /* Based on the ASSERT(0 < n && n < VECTOR_FACTOR) above, this won't
+ happen. The return is still here for compilers to not warn. */
+ return a;
+ }
+}
+
+#define FFCPS
+#define FFCPS_DIFF1
+#define FFCPS_CHAR1A2A
+
+#define FFCPS_0
+#include "pcre2_jit_neon_inc.h"
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+# define FF_UTF
+# include "pcre2_jit_neon_inc.h"
+# undef FF_UTF
+#endif
+#undef FFCPS_0
+
+#undef FFCPS_CHAR1A2A
+
+#define FFCPS_1
+#include "pcre2_jit_neon_inc.h"
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+# define FF_UTF
+# include "pcre2_jit_neon_inc.h"
+# undef FF_UTF
+#endif
+#undef FFCPS_1
+
+#undef FFCPS_DIFF1
+
+#define FFCPS_DEFAULT
+#include "pcre2_jit_neon_inc.h"
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+# define FF_UTF
+# include "pcre2_jit_neon_inc.h"
+# undef FF_UTF
+#endif
+#undef FFCPS
+
+#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD 1
+
+static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1,
+ PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)
+{
+DEFINE_COMPILER;
+sljit_u32 diff = IN_UCHARS(offs1 - offs2);
+struct sljit_jump *partial_quit;
+int_char ic;
+SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);
+SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset()));
+SLJIT_ASSERT(compiler->scratches == 5);
+
+/* Save temporary register STR_PTR. */
+OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS0, STR_PTR, 0);
+
+/* Prepare arguments for the function call. */
+if (common->match_end_ptr == 0)
+ OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0);
+else
+ {
+ OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+ OP2(SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
+
+ OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, STR_END, 0, SLJIT_R0, 0);
+ CMOV(SLJIT_LESS, SLJIT_R0, STR_END, 0);
+ }
+
+OP1(SLJIT_MOV, SLJIT_R1, 0, STR_PTR, 0);
+OP1(SLJIT_MOV_S32, SLJIT_R2, 0, SLJIT_IMM, offs1);
+OP1(SLJIT_MOV_S32, SLJIT_R3, 0, SLJIT_IMM, offs2);
+ic.c.c1 = char1a;
+ic.c.c2 = char1b;
+ic.c.c3 = char2a;
+ic.c.c4 = char2b;
+OP1(SLJIT_MOV_U32, SLJIT_R4, 0, SLJIT_IMM, ic.x);
+
+if (diff == 1) {
+ if (char1a == char1b && char2a == char2b) {
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf)
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_0_utf));
+ else
+#endif
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_0));
+ } else {
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf)
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_1_utf));
+ else
+#endif
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_1));
+ }
+} else {
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+ if (common->utf)
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_default_utf));
+ else
+#endif
+ sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW),
+ SLJIT_IMM, SLJIT_FUNC_OFFSET(ffcps_default));
+}
+
+/* Restore STR_PTR register. */
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS0);
+
+/* Check return value. */
+partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+add_jump(compiler, &common->failed_match, partial_quit);
+
+/* Fast forward STR_PTR to the result of memchr. */
+OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
+
+JUMPHERE(partial_quit);
+}
+
+#endif /* SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 */
diff --git a/thirdparty/pcre2/src/pcre2_maketables.c b/thirdparty/pcre2/src/pcre2_maketables.c
index 5921e90793..8c93b4b573 100644
--- a/thirdparty/pcre2/src/pcre2_maketables.c
+++ b/thirdparty/pcre2/src/pcre2_maketables.c
@@ -147,4 +147,15 @@ for (i = 0; i < 256; i++)
return yield;
}
+#ifndef DFTABLES
+PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
+pcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables)
+{
+ if (gcontext)
+ gcontext->memctl.free((void *)tables, gcontext->memctl.memory_data);
+ else
+ free((void *)tables);
+}
+#endif
+
/* End of pcre2_maketables.c */
diff --git a/thirdparty/pcre2/src/pcre2_match.c b/thirdparty/pcre2/src/pcre2_match.c
index 419561fd64..48e7b9dbb2 100644
--- a/thirdparty/pcre2/src/pcre2_match.c
+++ b/thirdparty/pcre2/src/pcre2_match.c
@@ -415,8 +415,7 @@ if (caseless)
else
#endif
- /* Not in UTF mode */
-
+ /* Not in UTF mode */
{
for (; length > 0; length--)
{
@@ -491,27 +490,32 @@ heap is used for a larger vector.
*************************************************/
/* These macros pack up tests that are used for partial matching several times
-in the code. We set the "hit end" flag if the pointer is at the end of the
-subject and also past the earliest inspected character (i.e. something has been
-matched, even if not part of the actual matched string). For hard partial
-matching, we then return immediately. The second one is used when we already
-know we are past the end of the subject. */
+in the code. The second one is used when we already know we are past the end of
+the subject. We set the "hit end" flag if the pointer is at the end of the
+subject and either (a) the pointer is past the earliest inspected character
+(i.e. something has been matched, even if not part of the actual matched
+string), or (b) the pattern contains a lookbehind. These are the conditions for
+which adding more characters may allow the current match to continue.
+
+For hard partial matching, we immediately return a partial match. Otherwise,
+carrying on means that a complete match on the current subject will be sought.
+A partial match is returned only if no complete match can be found. */
#define CHECK_PARTIAL()\
- if (mb->partial != 0 && Feptr >= mb->end_subject && \
- Feptr > mb->start_used_ptr) \
+ if (Feptr >= mb->end_subject) \
{ \
- mb->hitend = TRUE; \
- if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \
+ SCHECK_PARTIAL(); \
}
#define SCHECK_PARTIAL()\
- if (mb->partial != 0 && Feptr > mb->start_used_ptr) \
+ if (mb->partial != 0 && \
+ (Feptr > mb->start_used_ptr || mb->allowemptypartial)) \
{ \
mb->hitend = TRUE; \
if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \
}
+
/* These macros are used to implement backtracking. They simulate a recursive
call to the match() function by means of a local vector of frames which
remember the backtracking points. */
@@ -5127,6 +5131,8 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
case OP_ASSERT:
case OP_ASSERTBACK:
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
Lframe_type = GF_NOCAPTURE | Fop;
for (;;)
{
@@ -5412,7 +5418,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
{
while (number-- > 0)
{
- if (Feptr <= mb->start_subject) RRETURN(MATCH_NOMATCH);
+ if (Feptr <= mb->check_subject) RRETURN(MATCH_NOMATCH);
Feptr--;
BACKCHAR(Feptr);
}
@@ -5420,7 +5426,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
else
#endif
- /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
+ /* No UTF-8 support, or not in UTF-8 mode: count is code unit count */
{
if ((ptrdiff_t)number > Feptr - mb->start_subject) RRETURN(MATCH_NOMATCH);
@@ -5472,15 +5478,16 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
/* If we are at the end of an assertion that is a condition, return a
match, discarding any intermediate backtracking points. Copy back the
- captures into the frame before N so that they are set on return. Doing
- this for all assertions, both positive and negative, seems to match what
- Perl does. */
+ mark setting and the captures into the frame before N so that they are
+ set on return. Doing this for all assertions, both positive and negative,
+ seems to match what Perl does. */
if (GF_IDMASK(N->group_frame_type) == GF_CONDASSERT)
{
memcpy((char *)P + offsetof(heapframe, ovector), Fovector,
Foffset_top * sizeof(PCRE2_SIZE));
P->offset_top = Foffset_top;
+ P->mark = Fmark;
Fback_frame = (char *)F - (char *)P;
RRETURN(MATCH_MATCH);
}
@@ -5496,10 +5503,20 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
case OP_SCOND:
break;
- /* Positive assertions are like OP_ONCE, except that in addition the
+ /* Non-atomic positive assertions are like OP_BRA, except that the
subject pointer must be put back to where it was at the start of the
assertion. */
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
+ if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
+ Feptr = P->eptr;
+ break;
+
+ /* Atomic positive assertions are like OP_ONCE, except that in addition
+ the subject pointer must be put back to where it was at the start of the
+ assertion. */
+
case OP_ASSERT:
case OP_ASSERTBACK:
if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
@@ -5640,7 +5657,11 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
case OP_EOD:
if (Feptr < mb->end_subject) RRETURN(MATCH_NOMATCH);
- SCHECK_PARTIAL();
+ if (mb->partial != 0)
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
+ }
Fecode++;
break;
@@ -5665,7 +5686,11 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
/* Either at end of string or \n before end. */
- SCHECK_PARTIAL();
+ if (mb->partial != 0)
+ {
+ mb->hitend = TRUE;
+ if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
+ }
Fecode++;
break;
@@ -5743,7 +5768,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode);
case OP_NOT_WORD_BOUNDARY:
case OP_WORD_BOUNDARY:
- if (Feptr == mb->start_subject) prev_is_word = FALSE; else
+ if (Feptr == mb->check_subject) prev_is_word = FALSE; else
{
PCRE2_SPTR lastptr = Feptr - 1;
#ifdef SUPPORT_UNICODE
@@ -5946,6 +5971,7 @@ in rrc. */
#define LBL(val) case val: goto L_RM##val;
RETURN_SWITCH:
+if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
if (Frdepth == 0) return rrc; /* Exit from the top level */
F = (heapframe *)((char *)F - Fback_frame); /* Backtrack */
mb->cb->callout_flags |= PCRE2_CALLOUT_BACKTRACK; /* Note for callouts */
@@ -5999,9 +6025,9 @@ Arguments:
Returns: > 0 => success; value is the number of ovector pairs filled
= 0 => success, but ovector is not big enough
- -1 => failed to match (PCRE2_ERROR_NOMATCH)
- -2 => partial match (PCRE2_ERROR_PARTIAL)
- < -2 => some kind of unexpected problem
+ = -1 => failed to match (PCRE2_ERROR_NOMATCH)
+ = -2 => partial match (PCRE2_ERROR_PARTIAL)
+ < -2 => some kind of unexpected problem
*/
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
@@ -6014,7 +6040,6 @@ int was_zero_terminated = 0;
const uint8_t *start_bits = NULL;
const pcre2_real_code *re = (const pcre2_real_code *)code;
-
BOOL anchored;
BOOL firstline;
BOOL has_first_cu = FALSE;
@@ -6022,6 +6047,11 @@ BOOL has_req_cu = FALSE;
BOOL startline;
BOOL utf;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+BOOL memchr_not_found_first_cu = FALSE;
+BOOL memchr_not_found_first_cu2 = FALSE;
+#endif
+
PCRE2_UCHAR first_cu = 0;
PCRE2_UCHAR first_cu2 = 0;
PCRE2_UCHAR req_cu = 0;
@@ -6029,10 +6059,23 @@ PCRE2_UCHAR req_cu2 = 0;
PCRE2_SPTR bumpalong_limit;
PCRE2_SPTR end_subject;
+PCRE2_SPTR true_end_subject;
PCRE2_SPTR start_match = subject + start_offset;
PCRE2_SPTR req_cu_ptr = start_match - 1;
-PCRE2_SPTR start_partial = NULL;
-PCRE2_SPTR match_partial = NULL;
+PCRE2_SPTR start_partial;
+PCRE2_SPTR match_partial;
+
+#ifdef SUPPORT_JIT
+BOOL use_jit;
+#endif
+
+#ifdef SUPPORT_UNICODE
+BOOL allow_invalid;
+uint32_t fragment_options = 0;
+#ifdef SUPPORT_JIT
+BOOL jit_checked_utf = FALSE;
+#endif
+#endif
PCRE2_SIZE frame_size;
@@ -6059,7 +6102,7 @@ if (length == PCRE2_ZERO_TERMINATED)
length = PRIV(strlen)(subject);
was_zero_terminated = 1;
}
-end_subject = subject + length;
+true_end_subject = end_subject = subject + length;
/* Plausibility checks */
@@ -6095,12 +6138,24 @@ options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));
#undef FF
#undef OO
-/* These two settings are used in the code for checking a UTF string that
-follows immediately afterwards. Other values in the mb block are used only
-during interpretive processing, not when the JIT support is in use, so they are
-set up later. */
+/* If the pattern was successfully studied with JIT support, we will run the
+JIT executable instead of the rest of this function. Most options must be set
+at compile time for the JIT code to be usable. */
+
+#ifdef SUPPORT_JIT
+use_jit = (re->executable_jit != NULL &&
+ (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0);
+#endif
+
+/* Initialize UTF parameters. */
utf = (re->overall_options & PCRE2_UTF) != 0;
+#ifdef SUPPORT_UNICODE
+allow_invalid = (re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0;
+#endif
+
+/* Convert the partial matching flags into an integer. */
+
mb->partial = ((options & PCRE2_PARTIAL_HARD) != 0)? 2 :
((options & PCRE2_PARTIAL_SOFT) != 0)? 1 : 0;
@@ -6111,88 +6166,107 @@ if (mb->partial != 0 &&
((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
return PCRE2_ERROR_BADOPTION;
-/* Check a UTF string for validity if required. For 8-bit and 16-bit strings,
-we must also check that a starting offset does not point into the middle of a
-multiunit character. We check only the portion of the subject that is going to
-be inspected during matching - from the offset minus the maximum back reference
-to the given length. This saves time when a small part of a large subject is
-being matched by the use of a starting offset. Note that the maximum lookbehind
-is a number of characters, not code units. */
+/* It is an error to set an offset limit without setting the flag at compile
+time. */
-#ifdef SUPPORT_UNICODE
-if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
+if (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET &&
+ (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
+ return PCRE2_ERROR_BADOFFSETLIMIT;
+
+/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,
+free the memory that was obtained. Set the field to NULL for no match cases. */
+
+if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
{
- PCRE2_SPTR check_subject = start_match; /* start_match includes offset */
+ match_data->memctl.free((void *)match_data->subject,
+ match_data->memctl.memory_data);
+ match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;
+ }
+match_data->subject = NULL;
+
+/* Zero the error offset in case the first code unit is invalid UTF. */
+
+match_data->startchar = 0;
+
+
+/* ============================= JIT matching ============================== */
+
+/* Prepare for JIT matching. Check a UTF string for validity unless no check is
+requested or invalid UTF can be handled. We check only the portion of the
+subject that might be be inspected during matching - from the offset minus the
+maximum lookbehind to the given length. This saves time when a small part of a
+large subject is being matched by the use of a starting offset. Note that the
+maximum lookbehind is a number of characters, not code units. */
- if (start_offset > 0)
+#ifdef SUPPORT_JIT
+if (use_jit)
+ {
+#ifdef SUPPORT_UNICODE
+ if (utf && (options & PCRE2_NO_UTF_CHECK) == 0 && !allow_invalid)
{
#if PCRE2_CODE_UNIT_WIDTH != 32
unsigned int i;
+#endif
+
+ /* For 8-bit and 16-bit UTF, check that the first code unit is a valid
+ character start. */
+
+#if PCRE2_CODE_UNIT_WIDTH != 32
if (start_match < end_subject && NOT_FIRSTCU(*start_match))
- return PCRE2_ERROR_BADUTFOFFSET;
- for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--)
{
- check_subject--;
- while (check_subject > subject &&
+ if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
+#else
+ return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
+#endif
+ }
+#endif /* WIDTH != 32 */
+
+ /* Move back by the maximum lookbehind, just in case it happens at the very
+ start of matching. */
+
+#if PCRE2_CODE_UNIT_WIDTH != 32
+ for (i = re->max_lookbehind; i > 0 && start_match > subject; i--)
+ {
+ start_match--;
+ while (start_match > subject &&
#if PCRE2_CODE_UNIT_WIDTH == 8
- (*check_subject & 0xc0) == 0x80)
+ (*start_match & 0xc0) == 0x80)
#else /* 16-bit */
- (*check_subject & 0xfc00) == 0xdc00)
-#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
- check_subject--;
+ (*start_match & 0xfc00) == 0xdc00)
+#endif
+ start_match--;
}
-#else
+#else /* PCRE2_CODE_UNIT_WIDTH != 32 */
+
/* In the 32-bit library, one code unit equals one character. However,
we cannot just subtract the lookbehind and then compare pointers, because
a very large lookbehind could create an invalid pointer. */
if (start_offset >= re->max_lookbehind)
- check_subject -= re->max_lookbehind;
+ start_match -= re->max_lookbehind;
else
- check_subject = subject;
+ start_match = subject;
#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
- }
- /* Validate the relevant portion of the subject. After an error, adjust the
- offset to be an absolute offset in the whole string. */
+ /* Validate the relevant portion of the subject. Adjust the offset of an
+ invalid code point to be an absolute offset in the whole string. */
- match_data->rc = PRIV(valid_utf)(check_subject,
- length - (check_subject - subject), &(match_data->startchar));
- if (match_data->rc != 0)
- {
- match_data->startchar += check_subject - subject;
- return match_data->rc;
+ match_data->rc = PRIV(valid_utf)(start_match,
+ length - (start_match - subject), &(match_data->startchar));
+ if (match_data->rc != 0)
+ {
+ match_data->startchar += start_match - subject;
+ return match_data->rc;
+ }
+ jit_checked_utf = TRUE;
}
- }
#endif /* SUPPORT_UNICODE */
-/* It is an error to set an offset limit without setting the flag at compile
-time. */
-
-if (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET &&
- (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
- return PCRE2_ERROR_BADOFFSETLIMIT;
-
-/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,
-free the memory that was obtained. Set the field to NULL for no match cases. */
+ /* If JIT returns BADOPTION, which means that the selected complete or
+ partial matching mode was not compiled, fall through to the interpreter. */
-if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
- {
- match_data->memctl.free((void *)match_data->subject,
- match_data->memctl.memory_data);
- match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;
- }
-match_data->subject = NULL;
-
-/* If the pattern was successfully studied with JIT support, run the JIT
-executable instead of the rest of this function. Most options must be set at
-compile time for the JIT code to be usable. Fallback to the normal code path if
-an unsupported option is set or if JIT returns BADOPTION (which means that the
-selected normal or partial matching mode was not compiled). */
-
-#ifdef SUPPORT_JIT
-if (re->executable_jit != NULL && (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0)
- {
rc = pcre2_jit_match(code, subject, length, start_offset, options,
match_data, mcontext);
if (rc != PCRE2_ERROR_JIT_BADOPTION)
@@ -6209,10 +6283,152 @@ if (re->executable_jit != NULL && (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0)
return rc;
}
}
+#endif /* SUPPORT_JIT */
+
+/* ========================= End of JIT matching ========================== */
+
+
+/* Proceed with non-JIT matching. The default is to allow lookbehinds to the
+start of the subject. A UTF check when there is a non-zero offset may change
+this. */
+
+mb->check_subject = subject;
+
+/* If a UTF subject string was not checked for validity in the JIT code above,
+check it here, and handle support for invalid UTF strings. The check above
+happens only when invalid UTF is not supported and PCRE2_NO_CHECK_UTF is unset.
+If we get here in those circumstances, it means the subject string is valid,
+but for some reason JIT matching was not successful. There is no need to check
+the subject again.
+
+We check only the portion of the subject that might be be inspected during
+matching - from the offset minus the maximum lookbehind to the given length.
+This saves time when a small part of a large subject is being matched by the
+use of a starting offset. Note that the maximum lookbehind is a number of
+characters, not code units.
+
+Note also that support for invalid UTF forces a check, overriding the setting
+of PCRE2_NO_CHECK_UTF. */
+
+#ifdef SUPPORT_UNICODE
+if (utf &&
+#ifdef SUPPORT_JIT
+ !jit_checked_utf &&
+#endif
+ ((options & PCRE2_NO_UTF_CHECK) == 0 || allow_invalid))
+ {
+#if PCRE2_CODE_UNIT_WIDTH != 32
+ BOOL skipped_bad_start = FALSE;
+#endif
+
+ /* For 8-bit and 16-bit UTF, check that the first code unit is a valid
+ character start. If we are handling invalid UTF, just skip over such code
+ units. Otherwise, give an appropriate error. */
+
+#if PCRE2_CODE_UNIT_WIDTH != 32
+ if (allow_invalid)
+ {
+ while (start_match < end_subject && NOT_FIRSTCU(*start_match))
+ {
+ start_match++;
+ skipped_bad_start = TRUE;
+ }
+ }
+ else if (start_match < end_subject && NOT_FIRSTCU(*start_match))
+ {
+ if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
+#else
+ return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
+#endif
+ }
+#endif /* WIDTH != 32 */
+
+ /* The mb->check_subject field points to the start of UTF checking;
+ lookbehinds can go back no further than this. */
+
+ mb->check_subject = start_match;
+
+ /* Move back by the maximum lookbehind, just in case it happens at the very
+ start of matching, but don't do this if we skipped bad 8-bit or 16-bit code
+ units above. */
+
+#if PCRE2_CODE_UNIT_WIDTH != 32
+ if (!skipped_bad_start)
+ {
+ unsigned int i;
+ for (i = re->max_lookbehind; i > 0 && mb->check_subject > subject; i--)
+ {
+ mb->check_subject--;
+ while (mb->check_subject > subject &&
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ (*mb->check_subject & 0xc0) == 0x80)
+#else /* 16-bit */
+ (*mb->check_subject & 0xfc00) == 0xdc00)
+#endif
+ mb->check_subject--;
+ }
+ }
+#else /* PCRE2_CODE_UNIT_WIDTH != 32 */
+
+ /* In the 32-bit library, one code unit equals one character. However,
+ we cannot just subtract the lookbehind and then compare pointers, because
+ a very large lookbehind could create an invalid pointer. */
+
+ if (start_offset >= re->max_lookbehind)
+ mb->check_subject -= re->max_lookbehind;
+ else
+ mb->check_subject = subject;
+#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
+
+ /* Validate the relevant portion of the subject. There's a loop in case we
+ encounter bad UTF in the characters preceding start_match which we are
+ scanning because of a lookbehind. */
+
+ for (;;)
+ {
+ match_data->rc = PRIV(valid_utf)(mb->check_subject,
+ length - (mb->check_subject - subject), &(match_data->startchar));
+
+ if (match_data->rc == 0) break; /* Valid UTF string */
+
+ /* Invalid UTF string. Adjust the offset to be an absolute offset in the
+ whole string. If we are handling invalid UTF strings, set end_subject to
+ stop before the bad code unit, and set the options to "not end of line".
+ Otherwise return the error. */
+
+ match_data->startchar += mb->check_subject - subject;
+ if (!allow_invalid || match_data->rc > 0) return match_data->rc;
+ end_subject = subject + match_data->startchar;
+
+ /* If the end precedes start_match, it means there is invalid UTF in the
+ extra code units we reversed over because of a lookbehind. Advance past the
+ first bad code unit, and then skip invalid character starting code units in
+ 8-bit and 16-bit modes, and try again. */
+
+ if (end_subject < start_match)
+ {
+ mb->check_subject = end_subject + 1;
+#if PCRE2_CODE_UNIT_WIDTH != 32
+ while (mb->check_subject < start_match && NOT_FIRSTCU(*mb->check_subject))
+ mb->check_subject++;
#endif
+ }
+
+ /* Otherwise, set the not end of line option, and do the match. */
+
+ else
+ {
+ fragment_options = PCRE2_NOTEOL;
+ break;
+ }
+ }
+ }
+#endif /* SUPPORT_UNICODE */
-/* Carry on with non-JIT matching. A NULL match context means "use a default
-context", but we take the memory control functions from the pattern. */
+/* A NULL match context means "use a default context", but we take the memory
+control functions from the pattern. */
if (mcontext == NULL)
{
@@ -6224,8 +6440,8 @@ else mb->memctl = mcontext->memctl;
anchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0;
firstline = (re->overall_options & PCRE2_FIRSTLINE) != 0;
startline = (re->flags & PCRE2_STARTLINE) != 0;
-bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)?
- end_subject : subject + mcontext->offset_limit;
+bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)?
+ true_end_subject : subject + mcontext->offset_limit;
/* Initialize and set up the fixed fields in the callout block, with a pointer
in the match block. */
@@ -6236,7 +6452,8 @@ cb.subject = subject;
cb.subject_length = (PCRE2_SIZE)(end_subject - subject);
cb.callout_flags = 0;
-/* Fill in the remaining fields in the match block. */
+/* Fill in the remaining fields in the match block, except for moptions, which
+gets set later. */
mb->callout = mcontext->callout;
mb->callout_data = mcontext->callout_data;
@@ -6245,13 +6462,11 @@ mb->start_subject = subject;
mb->start_offset = start_offset;
mb->end_subject = end_subject;
mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0;
-
-mb->moptions = options; /* Match options */
-mb->poptions = re->overall_options; /* Pattern options */
-
+mb->allowemptypartial = (re->max_lookbehind > 0) ||
+ (re->flags & PCRE2_MATCH_EMPTY) != 0;
+mb->poptions = re->overall_options; /* Pattern options */
mb->ignore_skip_arg = 0;
-mb->mark = mb->nomatch_mark = NULL; /* In case never set */
-mb->hitend = FALSE;
+mb->mark = mb->nomatch_mark = NULL; /* In case never set */
/* The name table is needed for finding all the numbers associated with a
given name, for condition testing. The code follows the name table. */
@@ -6404,6 +6619,13 @@ if ((re->flags & PCRE2_LASTSET) != 0)
/* Loop for handling unanchored repeated matching attempts; for anchored regexs
the loop runs just once. */
+#ifdef SUPPORT_UNICODE
+FRAGMENT_RESTART:
+#endif
+
+start_partial = match_partial = NULL;
+mb->hitend = FALSE;
+
for(;;)
{
PCRE2_SPTR new_start_match;
@@ -6473,7 +6695,10 @@ for(;;)
/* Not anchored. Advance to a unique first code unit if there is one. In
8-bit mode, the use of memchr() gives a big speed up, even though we have
to call it twice in caseless mode, in order to find the earliest occurrence
- of the character in either of its cases. */
+ of the character in either of its cases. If a call to memchr() that
+ searches the rest of the subject fails to find one case, remember that in
+ order not to keep on repeating the search. This can make a huge difference
+ when the strings are very long and only one case is present. */
else
{
@@ -6487,11 +6712,29 @@ for(;;)
(smc = UCHAR21TEST(start_match)) != first_cu &&
smc != first_cu2)
start_match++;
+
#else /* 8-bit code units */
- PCRE2_SPTR pp1 =
- memchr(start_match, first_cu, end_subject-start_match);
- PCRE2_SPTR pp2 =
- memchr(start_match, first_cu2, end_subject-start_match);
+ PCRE2_SPTR pp1 = NULL;
+ PCRE2_SPTR pp2 = NULL;
+ PCRE2_SIZE cu2size = end_subject - start_match;
+
+ if (!memchr_not_found_first_cu)
+ {
+ pp1 = memchr(start_match, first_cu, end_subject - start_match);
+ if (pp1 == NULL) memchr_not_found_first_cu = TRUE;
+ else cu2size = pp1 - start_match;
+ }
+
+ /* If pp1 is not NULL, we have arranged to search only as far as pp1,
+ to see if the other case is earlier, so we can set "not found" only
+ when both searches have returned NULL. */
+
+ if (!memchr_not_found_first_cu2)
+ {
+ pp2 = memchr(start_match, first_cu2, cu2size);
+ memchr_not_found_first_cu2 = (pp2 == NULL && pp1 == NULL);
+ }
+
if (pp1 == NULL)
start_match = (pp2 == NULL)? end_subject : pp2;
else
@@ -6523,7 +6766,7 @@ for(;;)
we also let the cycle run, because the matching string is legitimately
allowed to start with the first code unit of a newline. */
- if (!mb->partial && start_match >= mb->end_subject)
+ if (mb->partial == 0 && start_match >= mb->end_subject)
{
rc = MATCH_NOMATCH;
break;
@@ -6582,7 +6825,7 @@ for(;;)
/* See comment above in first_cu checking about the next few lines. */
- if (!mb->partial && start_match >= mb->end_subject)
+ if (mb->partial == 0 && start_match >= mb->end_subject)
{
rc = MATCH_NOMATCH;
break;
@@ -6596,8 +6839,10 @@ for(;;)
/* The following two optimizations must be disabled for partial matching. */
- if (!mb->partial)
+ if (mb->partial == 0)
{
+ PCRE2_SPTR p;
+
/* The minimum matching length is a lower bound; no string of that length
may actually match the pattern. Although the value is, strictly, in
characters, we treat it as code units to avoid spending too much time in
@@ -6621,60 +6866,57 @@ for(;;)
memchr() twice in the caseless case because we only need to check for the
presence of the character in either case, not find the first occurrence.
+ The search can be skipped if the code unit was found later than the
+ current starting point in a previous iteration of the bumpalong loop.
+
HOWEVER: when the subject string is very, very long, searching to its end
can take a long time, and give bad performance on quite ordinary
- patterns. This showed up when somebody was matching something like
- /^\d+C/ on a 32-megabyte string... so we don't do this when the string is
- sufficiently long. */
+ anchored patterns. This showed up when somebody was matching something
+ like /^\d+C/ on a 32-megabyte string... so we don't do this when the
+ string is sufficiently long, but it's worth searching a lot more for
+ unanchored patterns. */
- if (has_req_cu && end_subject - start_match < REQ_CU_MAX)
+ p = start_match + (has_first_cu? 1:0);
+ if (has_req_cu && p > req_cu_ptr)
{
- PCRE2_SPTR p = start_match + (has_first_cu? 1:0);
-
- /* We don't need to repeat the search if we haven't yet reached the
- place we found it last time round the bumpalong loop. */
+ PCRE2_SIZE check_length = end_subject - start_match;
- if (p > req_cu_ptr)
+ if (check_length < REQ_CU_MAX ||
+ (!anchored && check_length < REQ_CU_MAX * 1000))
{
- if (p < end_subject)
+ if (req_cu != req_cu2) /* Caseless */
{
- if (req_cu != req_cu2) /* Caseless */
- {
#if PCRE2_CODE_UNIT_WIDTH != 8
- do
- {
- uint32_t pp = UCHAR21INCTEST(p);
- if (pp == req_cu || pp == req_cu2) { p--; break; }
- }
- while (p < end_subject);
-
+ while (p < end_subject)
+ {
+ uint32_t pp = UCHAR21INCTEST(p);
+ if (pp == req_cu || pp == req_cu2) { p--; break; }
+ }
#else /* 8-bit code units */
- PCRE2_SPTR pp = p;
- p = memchr(pp, req_cu, end_subject - pp);
- if (p == NULL)
- {
- p = memchr(pp, req_cu2, end_subject - pp);
- if (p == NULL) p = end_subject;
- }
-#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */
+ PCRE2_SPTR pp = p;
+ p = memchr(pp, req_cu, end_subject - pp);
+ if (p == NULL)
+ {
+ p = memchr(pp, req_cu2, end_subject - pp);
+ if (p == NULL) p = end_subject;
}
+#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */
+ }
- /* The caseful case */
+ /* The caseful case */
- else
- {
+ else
+ {
#if PCRE2_CODE_UNIT_WIDTH != 8
- do
- {
- if (UCHAR21INCTEST(p) == req_cu) { p--; break; }
- }
- while (p < end_subject);
+ while (p < end_subject)
+ {
+ if (UCHAR21INCTEST(p) == req_cu) { p--; break; }
+ }
#else /* 8-bit code units */
- p = memchr(p, req_cu, end_subject - p);
- if (p == NULL) p = end_subject;
+ p = memchr(p, req_cu, end_subject - p);
+ if (p == NULL) p = end_subject;
#endif
- }
}
/* If we can't find the required code unit, break the bumpalong loop,
@@ -6714,6 +6956,11 @@ for(;;)
mb->start_used_ptr = start_match;
mb->last_used_ptr = start_match;
+#ifdef SUPPORT_UNICODE
+ mb->moptions = options | fragment_options;
+#else
+ mb->moptions = options;
+#endif
mb->match_call_count = 0;
mb->end_offset_top = 0;
mb->skip_arg_count = 0;
@@ -6839,6 +7086,68 @@ for(;;)
ENDLOOP:
+/* If end_subject != true_end_subject, it means we are handling invalid UTF,
+and have just processed a non-terminal fragment. If this resulted in no match
+or a partial match we must carry on to the next fragment (a partial match is
+returned to the caller only at the very end of the subject). A loop is used to
+avoid trying to match against empty fragments; if the pattern can match an
+empty string it would have done so already. */
+
+#ifdef SUPPORT_UNICODE
+if (utf && end_subject != true_end_subject &&
+ (rc == MATCH_NOMATCH || rc == PCRE2_ERROR_PARTIAL))
+ {
+ for (;;)
+ {
+ /* Advance past the first bad code unit, and then skip invalid character
+ starting code units in 8-bit and 16-bit modes. */
+
+ start_match = end_subject + 1;
+#if PCRE2_CODE_UNIT_WIDTH != 32
+ while (start_match < true_end_subject && NOT_FIRSTCU(*start_match))
+ start_match++;
+#endif
+
+ /* If we have hit the end of the subject, there isn't another non-empty
+ fragment, so give up. */
+
+ if (start_match >= true_end_subject)
+ {
+ rc = MATCH_NOMATCH; /* In case it was partial */
+ break;
+ }
+
+ /* Check the rest of the subject */
+
+ mb->check_subject = start_match;
+ rc = PRIV(valid_utf)(start_match, length - (start_match - subject),
+ &(match_data->startchar));
+
+ /* The rest of the subject is valid UTF. */
+
+ if (rc == 0)
+ {
+ mb->end_subject = end_subject = true_end_subject;
+ fragment_options = PCRE2_NOTBOL;
+ goto FRAGMENT_RESTART;
+ }
+
+ /* A subsequent UTF error has been found; if the next fragment is
+ non-empty, set up to process it. Otherwise, let the loop advance. */
+
+ else if (rc < 0)
+ {
+ mb->end_subject = end_subject = start_match + match_data->startchar;
+ if (end_subject > start_match)
+ {
+ fragment_options = PCRE2_NOTBOL|PCRE2_NOTEOL;
+ goto FRAGMENT_RESTART;
+ }
+ }
+ }
+ }
+#endif /* SUPPORT_UNICODE */
+
/* Release an enlarged frame vector that is on the heap. */
if (mb->match_frames != mb->stack_frames)
diff --git a/thirdparty/pcre2/src/pcre2_match_data.c b/thirdparty/pcre2/src/pcre2_match_data.c
index ccc5f6740e..53e4698707 100644
--- a/thirdparty/pcre2/src/pcre2_match_data.c
+++ b/thirdparty/pcre2/src/pcre2_match_data.c
@@ -7,7 +7,7 @@ and semantics are as close as possible to those of the Perl 5 language.
Written by Philip Hazel
Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2018 University of Cambridge
+ New API code Copyright (c) 2016-2019 University of Cambridge
-----------------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
@@ -150,4 +150,17 @@ pcre2_get_startchar(pcre2_match_data *match_data)
return match_data->startchar;
}
+
+
+/*************************************************
+* Get size of match data block *
+*************************************************/
+
+PCRE2_EXP_DEFN PCRE2_SIZE PCRE2_CALL_CONVENTION
+pcre2_get_match_data_size(pcre2_match_data *match_data)
+{
+return offsetof(pcre2_match_data, ovector) +
+ 2 * (match_data->oveccount) * sizeof(PCRE2_SIZE);
+}
+
/* End of pcre2_match_data.c */
diff --git a/thirdparty/pcre2/src/pcre2_study.c b/thirdparty/pcre2/src/pcre2_study.c
index e883c2eb4c..2883868618 100644
--- a/thirdparty/pcre2/src/pcre2_study.c
+++ b/thirdparty/pcre2/src/pcre2_study.c
@@ -88,11 +88,13 @@ Arguments:
countptr pointer to call count (to catch over complexity)
backref_cache vector for caching back references.
+This function is no longer called when the pattern contains (*ACCEPT); however,
+the old code for returning -1 is retained, just in case.
+
Returns: the minimum length
-1 \C in UTF-8 mode
or (*ACCEPT)
or pattern too complicated
- or back reference to duplicate name/number
-2 internal error (missing capturing bracket)
-3 internal error (opcode not listed)
*/
@@ -103,6 +105,7 @@ find_minlength(const pcre2_real_code *re, PCRE2_SPTR code,
int *backref_cache)
{
int length = -1;
+int branchlength = 0;
int prev_cap_recno = -1;
int prev_cap_d = 0;
int prev_recurse_recno = -1;
@@ -110,9 +113,9 @@ int prev_recurse_d = 0;
uint32_t once_fudge = 0;
BOOL had_recurse = FALSE;
BOOL dupcapused = (re->flags & PCRE2_DUPCAPUSED) != 0;
-recurse_check this_recurse;
-int branchlength = 0;
+PCRE2_SPTR nextbranch = code + GET(code, 1);
PCRE2_UCHAR *cc = (PCRE2_UCHAR *)code + 1 + LINK_SIZE;
+recurse_check this_recurse;
/* If this is a "could be empty" group, its minimum length is 0. */
@@ -128,16 +131,20 @@ if ((*countptr)++ > 1000) return -1;
/* Scan along the opcodes for this branch. If we get to the end of the branch,
check the length against that of the other branches. If the accumulated length
-passes 16-bits, stop. */
+passes 16-bits, reset to that value and skip the rest of the branch. */
for (;;)
{
int d, min, recno;
- PCRE2_UCHAR *cs, *ce;
- PCRE2_UCHAR op = *cc;
+ PCRE2_UCHAR op, *cs, *ce;
- if (branchlength >= UINT16_MAX) return UINT16_MAX;
+ if (branchlength >= UINT16_MAX)
+ {
+ branchlength = UINT16_MAX;
+ cc = (PCRE2_UCHAR *)nextbranch;
+ }
+ op = *cc;
switch (op)
{
case OP_COND:
@@ -206,7 +213,9 @@ for (;;)
cc += 1 + LINK_SIZE;
break;
- /* ACCEPT makes things far too complicated; we have to give up. */
+ /* ACCEPT makes things far too complicated; we have to give up. In fact,
+ from 10.34 onwards, if a pattern contains (*ACCEPT), this function is not
+ used. However, leave the code in place, just in case. */
case OP_ACCEPT:
case OP_ASSERT_ACCEPT:
@@ -214,9 +223,9 @@ for (;;)
/* Reached end of a branch; if it's a ket it is the end of a nested
call. If it's ALT it is an alternation in a nested call. If it is END it's
- the end of the outer call. All can be handled by the same code. If an
- ACCEPT was previously encountered, use the length that was in force at that
- time, and pass back the shortest ACCEPT length. */
+ the end of the outer call. All can be handled by the same code. If the
+ length of any branch is zero, there is no need to scan any subsequent
+ branches. */
case OP_ALT:
case OP_KET:
@@ -226,7 +235,8 @@ for (;;)
case OP_END:
if (length < 0 || (!had_recurse && branchlength < length))
length = branchlength;
- if (op != OP_ALT) return length;
+ if (op != OP_ALT || length == 0) return length;
+ nextbranch = cc + GET(cc, 1);
cc += 1 + LINK_SIZE;
branchlength = 0;
had_recurse = FALSE;
@@ -238,6 +248,8 @@ for (;;)
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
+ case OP_ASSERT_NA:
+ case OP_ASSERTBACK_NA:
do cc += GET(cc, 1); while (*cc == OP_ALT);
/* Fall through */
@@ -451,15 +463,17 @@ for (;;)
If PCRE2_MATCH_UNSET_BACKREF is set, a backreference to an unset bracket
matches an empty string (by default it causes a matching failure), so in
- that case we must set the minimum length to zero. */
+ that case we must set the minimum length to zero.
+
+ For backreferenes, if duplicate numbers are present in the pattern we check
+ for a reference to a duplicate. If it is, we don't know which version will
+ be referenced, so we have to set the minimum length to zero. */
- /* Duplicate named pattern back reference. We cannot reliably find a length
- for this if duplicate numbers are present in the pattern. */
+ /* Duplicate named pattern back reference. */
case OP_DNREF:
case OP_DNREFI:
- if (dupcapused) return -1;
- if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)
+ if (!dupcapused && (re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)
{
int count = GET2(cc, 1+IMM2_SIZE);
PCRE2_UCHAR *slot =
@@ -482,28 +496,32 @@ for (;;)
ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno);
if (cs == NULL) return -2;
do ce += GET(ce, 1); while (*ce == OP_ALT);
- if (cc > cs && cc < ce) /* Simple recursion */
- {
- dd = 0;
- had_recurse = TRUE;
- }
- else
+
+ dd = 0;
+ if (!dupcapused ||
+ (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL)
{
- recurse_check *r = recurses;
- for (r = recurses; r != NULL; r = r->prev)
- if (r->group == cs) break;
- if (r != NULL) /* Mutual recursion */
+ if (cc > cs && cc < ce) /* Simple recursion */
{
- dd = 0;
had_recurse = TRUE;
}
else
{
- this_recurse.prev = recurses;
- this_recurse.group = cs;
- dd = find_minlength(re, cs, startcode, utf, &this_recurse,
- countptr, backref_cache);
- if (dd < 0) return dd;
+ recurse_check *r = recurses;
+ for (r = recurses; r != NULL; r = r->prev)
+ if (r->group == cs) break;
+ if (r != NULL) /* Mutual recursion */
+ {
+ had_recurse = TRUE;
+ }
+ else
+ {
+ this_recurse.prev = recurses; /* No recursion */
+ this_recurse.group = cs;
+ dd = find_minlength(re, cs, startcode, utf, &this_recurse,
+ countptr, backref_cache);
+ if (dd < 0) return dd;
+ }
}
}
@@ -521,48 +539,51 @@ for (;;)
cc += 1 + 2*IMM2_SIZE;
goto REPEAT_BACK_REFERENCE;
- /* Single back reference. We cannot find a length for this if duplicate
- numbers are present in the pattern. */
+ /* Single back reference by number. References by name are converted to by
+ number when there is no duplication. */
case OP_REF:
case OP_REFI:
- if (dupcapused) return -1;
recno = GET2(cc, 1);
if (recno <= backref_cache[0] && backref_cache[recno] >= 0)
d = backref_cache[recno];
else
{
int i;
+ d = 0;
+
if ((re->overall_options & PCRE2_MATCH_UNSET_BACKREF) == 0)
{
ce = cs = (PCRE2_UCHAR *)PRIV(find_bracket)(startcode, utf, recno);
if (cs == NULL) return -2;
do ce += GET(ce, 1); while (*ce == OP_ALT);
- if (cc > cs && cc < ce) /* Simple recursion */
- {
- d = 0;
- had_recurse = TRUE;
- }
- else
+
+ if (!dupcapused ||
+ (PCRE2_UCHAR *)PRIV(find_bracket)(ce, utf, recno) == NULL)
{
- recurse_check *r = recurses;
- for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;
- if (r != NULL) /* Mutual recursion */
+ if (cc > cs && cc < ce) /* Simple recursion */
{
- d = 0;
had_recurse = TRUE;
}
else
{
- this_recurse.prev = recurses;
- this_recurse.group = cs;
- d = find_minlength(re, cs, startcode, utf, &this_recurse, countptr,
- backref_cache);
- if (d < 0) return d;
+ recurse_check *r = recurses;
+ for (r = recurses; r != NULL; r = r->prev) if (r->group == cs) break;
+ if (r != NULL) /* Mutual recursion */
+ {
+ had_recurse = TRUE;
+ }
+ else /* No recursion */
+ {
+ this_recurse.prev = recurses;
+ this_recurse.group = cs;
+ d = find_minlength(re, cs, startcode, utf, &this_recurse, countptr,
+ backref_cache);
+ if (d < 0) return d;
+ }
}
}
}
- else d = 0;
backref_cache[recno] = d;
for (i = backref_cache[0] + 1; i < recno; i++) backref_cache[i] = -1;
@@ -888,7 +909,7 @@ if (table_limit != 32) for (c = 24; c < 32; c++) re->start_bitmap[c] = 0xff;
/*************************************************
-* Create bitmap of starting bytes *
+* Create bitmap of starting code units *
*************************************************/
/* This function scans a compiled unanchored expression recursively and
@@ -938,6 +959,9 @@ do
{
int rc;
uint8_t *classmap = NULL;
+#ifdef SUPPORT_WIDE_CHARS
+ PCRE2_UCHAR xclassflags;
+#endif
switch(*tcode)
{
@@ -1078,6 +1102,7 @@ do
case OP_ONCE:
case OP_SCRIPT_RUN:
case OP_ASSERT:
+ case OP_ASSERT_NA:
rc = set_start_bits(re, tcode, utf);
if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc;
if (rc == SSB_DONE) try_next = FALSE; else
@@ -1120,6 +1145,7 @@ do
case OP_ASSERT_NOT:
case OP_ASSERTBACK:
case OP_ASSERTBACK_NOT:
+ case OP_ASSERTBACK_NA:
do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
tcode += 1 + LINK_SIZE;
break;
@@ -1444,20 +1470,59 @@ do
negative XCLASS without a map, give up. If there are no property checks,
there must be wide characters on the XCLASS list, because otherwise an
XCLASS would not have been created. This means that code points >= 255
- are always potential starters. */
+ are potential starters. In the UTF-8 case we can scan them and set bits
+ for the relevant leading bytes. */
#ifdef SUPPORT_WIDE_CHARS
case OP_XCLASS:
- if ((tcode[1 + LINK_SIZE] & XCL_HASPROP) != 0 ||
- (tcode[1 + LINK_SIZE] & (XCL_MAP|XCL_NOT)) == XCL_NOT)
+ xclassflags = tcode[1 + LINK_SIZE];
+ if ((xclassflags & XCL_HASPROP) != 0 ||
+ (xclassflags & (XCL_MAP|XCL_NOT)) == XCL_NOT)
return SSB_FAIL;
/* We have a positive XCLASS or a negative one without a map. Set up the
map pointer if there is one, and fall through. */
- classmap = ((tcode[1 + LINK_SIZE] & XCL_MAP) == 0)? NULL :
+ classmap = ((xclassflags & XCL_MAP) == 0)? NULL :
(uint8_t *)(tcode + 1 + LINK_SIZE + 1);
-#endif
+
+ /* In UTF-8 mode, scan the character list and set bits for leading bytes,
+ then jump to handle the map. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (utf && (xclassflags & XCL_NOT) == 0)
+ {
+ PCRE2_UCHAR b, e;
+ PCRE2_SPTR p = tcode + 1 + LINK_SIZE + 1 + ((classmap == NULL)? 0:32);
+ tcode += GET(tcode, 1);
+
+ for (;;) switch (*p++)
+ {
+ case XCL_SINGLE:
+ b = *p++;
+ while ((*p & 0xc0) == 0x80) p++;
+ re->start_bitmap[b/8] |= (1u << (b&7));
+ break;
+
+ case XCL_RANGE:
+ b = *p++;
+ while ((*p & 0xc0) == 0x80) p++;
+ e = *p++;
+ while ((*p & 0xc0) == 0x80) p++;
+ for (; b <= e; b++)
+ re->start_bitmap[b/8] |= (1u << (b&7));
+ break;
+
+ case XCL_END:
+ goto HANDLE_CLASSMAP;
+
+ default:
+ return SSB_UNKNOWN; /* Internal error, should not occur */
+ }
+ }
+#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
+#endif /* SUPPORT_WIDE_CHARS */
+
/* It seems that the fall through comment must be outside the #ifdef if
it is to avoid the gcc compiler warning. */
@@ -1499,6 +1564,9 @@ do
greater than 127. In fact, there are only two possible starting bytes for
characters in the range 128 - 255. */
+#if defined SUPPORT_WIDE_CHARS && PCRE2_CODE_UNIT_WIDTH == 8
+ HANDLE_CLASSMAP:
+#endif
if (classmap != NULL)
{
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8
@@ -1569,7 +1637,9 @@ return yield;
/* This function is handed a compiled expression that it must study to produce
information that will speed up the matching.
-Argument: points to the compiled expression
+Argument:
+ re points to the compiled expression
+
Returns: 0 normally; non-zero should never normally occur
1 unknown opcode in set_start_bits
2 missing capturing bracket
@@ -1579,7 +1649,6 @@ Returns: 0 normally; non-zero should never normally occur
int
PRIV(study)(pcre2_real_code *re)
{
-int min;
int count = 0;
PCRE2_UCHAR *code;
BOOL utf = (re->overall_options & PCRE2_UTF) != 0;
@@ -1597,25 +1666,121 @@ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)
{
int rc = set_start_bits(re, code, utf);
if (rc == SSB_UNKNOWN) return 1;
- if (rc == SSB_DONE) re->flags |= PCRE2_FIRSTMAPSET;
+
+ /* If a list of starting code units was set up, scan the list to see if only
+ one or two were listed. Having only one listed is rare because usually a
+ single starting code unit will have been recognized and PCRE2_FIRSTSET set.
+ If two are listed, see if they are caseless versions of the same character;
+ if so we can replace the list with a caseless first code unit. This gives
+ better performance and is plausibly worth doing for patterns such as [Ww]ord
+ or (word|WORD). */
+
+ if (rc == SSB_DONE)
+ {
+ int i;
+ int a = -1;
+ int b = -1;
+ uint8_t *p = re->start_bitmap;
+ uint32_t flags = PCRE2_FIRSTMAPSET;
+
+ for (i = 0; i < 256; p++, i += 8)
+ {
+ uint8_t x = *p;
+ if (x != 0)
+ {
+ int c;
+ uint8_t y = x & (~x + 1); /* Least significant bit */
+ if (y != x) goto DONE; /* More than one bit set */
+
+ /* In the 16-bit and 32-bit libraries, the bit for 0xff means "0xff and
+ all wide characters", so we cannot use it here. */
+
+#if PCRE2_CODE_UNIT_WIDTH != 8
+ if (i == 248 && x == 0x80) goto DONE;
+#endif
+
+ /* Compute the character value */
+
+ c = i;
+ switch (x)
+ {
+ case 1: break;
+ case 2: c += 1; break; case 4: c += 2; break;
+ case 8: c += 3; break; case 16: c += 4; break;
+ case 32: c += 5; break; case 64: c += 6; break;
+ case 128: c += 7; break;
+ }
+
+ /* c contains the code unit value, in the range 0-255. In 8-bit UTF
+ mode, only values < 128 can be used. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (c > 127) goto DONE;
+#endif
+ if (a < 0) a = c; /* First one found */
+ else if (b < 0) /* Second one found */
+ {
+ int d = TABLE_GET((unsigned int)c, re->tables + fcc_offset, c);
+
+#ifdef SUPPORT_UNICODE
+#if PCRE2_CODE_UNIT_WIDTH == 8
+ if (utf && UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */
+#else /* 16-bit or 32-bit */
+ if (UCD_CASESET(c) != 0) goto DONE; /* Multiple case set */
+ if (utf && c > 127) d = UCD_OTHERCASE(c);
+#endif /* Code width */
+#endif /* SUPPORT_UNICODE */
+
+ if (d != a) goto DONE; /* Not other case of a */
+ b = c;
+ }
+ else goto DONE; /* More than two characters found */
+ }
+ }
+
+ /* Replace the start code unit bits with a first code unit, but only if it
+ is not the same as a required later code unit. This is because a search for
+ a required code unit starts after an explicit first code unit, but at a
+ code unit found from the bitmap. Patterns such as /a*a/ don't work
+ if both the start unit and required unit are the same. */
+
+ if (a >= 0 &&
+ (
+ (re->flags & PCRE2_LASTSET) == 0 ||
+ (
+ re->last_codeunit != (uint32_t)a &&
+ (b < 0 || re->last_codeunit != (uint32_t)b)
+ )
+ ))
+ {
+ re->first_codeunit = a;
+ flags = PCRE2_FIRSTSET;
+ if (b >= 0) flags |= PCRE2_FIRSTCASELESS;
+ }
+
+ DONE:
+ re->flags |= flags;
+ }
}
/* Find the minimum length of subject string. If the pattern can match an empty
-string, the minimum length is already known. If there are more back references
-than the size of the vector we are going to cache them in, do nothing. A
-pattern that complicated will probably take a long time to analyze and may in
-any case turn out to be too complicated. Note that back reference minima are
-held as 16-bit numbers. */
-
-if ((re->flags & PCRE2_MATCH_EMPTY) == 0 &&
+string, the minimum length is already known. If the pattern contains (*ACCEPT)
+all bets are off, and we don't even try to find a minimum length. If there are
+more back references than the size of the vector we are going to cache them in,
+do nothing. A pattern that complicated will probably take a long time to
+analyze and may in any case turn out to be too complicated. Note that back
+reference minima are held as 16-bit numbers. */
+
+if ((re->flags & (PCRE2_MATCH_EMPTY|PCRE2_HASACCEPT)) == 0 &&
re->top_backref <= MAX_CACHE_BACKREF)
{
+ int min;
int backref_cache[MAX_CACHE_BACKREF+1];
backref_cache[0] = 0; /* Highest one that is set */
min = find_minlength(re, code, code, utf, NULL, &count, backref_cache);
switch(min)
{
- case -1: /* \C in UTF mode or (*ACCEPT) or over-complex regex */
+ case -1: /* \C in UTF mode or over-complex regex */
break; /* Leave minlength unchanged (will be zero) */
case -2:
@@ -1625,8 +1790,7 @@ if ((re->flags & PCRE2_MATCH_EMPTY) == 0 &&
return 3; /* unrecognized opcode */
default:
- if (min > UINT16_MAX) min = UINT16_MAX;
- re->minlength = min;
+ re->minlength = (min > UINT16_MAX)? UINT16_MAX : min;
break;
}
}
diff --git a/thirdparty/pcre2/src/pcre2_tables.c b/thirdparty/pcre2/src/pcre2_tables.c
index 84019361fc..25531d98c6 100644
--- a/thirdparty/pcre2/src/pcre2_tables.c
+++ b/thirdparty/pcre2/src/pcre2_tables.c
@@ -279,6 +279,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
#define STRING_Duployan0 STR_D STR_u STR_p STR_l STR_o STR_y STR_a STR_n "\0"
#define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
#define STRING_Elbasan0 STR_E STR_l STR_b STR_a STR_s STR_a STR_n "\0"
+#define STRING_Elymaic0 STR_E STR_l STR_y STR_m STR_a STR_i STR_c "\0"
#define STRING_Ethiopic0 STR_E STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0"
#define STRING_Georgian0 STR_G STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0"
#define STRING_Glagolitic0 STR_G STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0"
@@ -348,6 +349,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
#define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0"
#define STRING_N0 STR_N "\0"
#define STRING_Nabataean0 STR_N STR_a STR_b STR_a STR_t STR_a STR_e STR_a STR_n "\0"
+#define STRING_Nandinagari0 STR_N STR_a STR_n STR_d STR_i STR_n STR_a STR_g STR_a STR_r STR_i "\0"
#define STRING_Nd0 STR_N STR_d "\0"
#define STRING_New_Tai_Lue0 STR_N STR_e STR_w STR_UNDERSCORE STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_u STR_e "\0"
#define STRING_Newa0 STR_N STR_e STR_w STR_a "\0"
@@ -355,6 +357,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
#define STRING_Nl0 STR_N STR_l "\0"
#define STRING_No0 STR_N STR_o "\0"
#define STRING_Nushu0 STR_N STR_u STR_s STR_h STR_u "\0"
+#define STRING_Nyiakeng_Puachue_Hmong0 STR_N STR_y STR_i STR_a STR_k STR_e STR_n STR_g STR_UNDERSCORE STR_P STR_u STR_a STR_c STR_h STR_u STR_e STR_UNDERSCORE STR_H STR_m STR_o STR_n STR_g "\0"
#define STRING_Ogham0 STR_O STR_g STR_h STR_a STR_m "\0"
#define STRING_Ol_Chiki0 STR_O STR_l STR_UNDERSCORE STR_C STR_h STR_i STR_k STR_i "\0"
#define STRING_Old_Hungarian0 STR_O STR_l STR_d STR_UNDERSCORE STR_H STR_u STR_n STR_g STR_a STR_r STR_i STR_a STR_n "\0"
@@ -419,6 +422,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */
#define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0"
#define STRING_Unknown0 STR_U STR_n STR_k STR_n STR_o STR_w STR_n "\0"
#define STRING_Vai0 STR_V STR_a STR_i "\0"
+#define STRING_Wancho0 STR_W STR_a STR_n STR_c STR_h STR_o "\0"
#define STRING_Warang_Citi0 STR_W STR_a STR_r STR_a STR_n STR_g STR_UNDERSCORE STR_C STR_i STR_t STR_i "\0"
#define STRING_Xan0 STR_X STR_a STR_n "\0"
#define STRING_Xps0 STR_X STR_p STR_s "\0"
@@ -474,6 +478,7 @@ const char PRIV(utt_names)[] =
STRING_Duployan0
STRING_Egyptian_Hieroglyphs0
STRING_Elbasan0
+ STRING_Elymaic0
STRING_Ethiopic0
STRING_Georgian0
STRING_Glagolitic0
@@ -543,6 +548,7 @@ const char PRIV(utt_names)[] =
STRING_Myanmar0
STRING_N0
STRING_Nabataean0
+ STRING_Nandinagari0
STRING_Nd0
STRING_New_Tai_Lue0
STRING_Newa0
@@ -550,6 +556,7 @@ const char PRIV(utt_names)[] =
STRING_Nl0
STRING_No0
STRING_Nushu0
+ STRING_Nyiakeng_Puachue_Hmong0
STRING_Ogham0
STRING_Ol_Chiki0
STRING_Old_Hungarian0
@@ -614,6 +621,7 @@ const char PRIV(utt_names)[] =
STRING_Ugaritic0
STRING_Unknown0
STRING_Vai0
+ STRING_Wancho0
STRING_Warang_Citi0
STRING_Xan0
STRING_Xps0
@@ -669,158 +677,162 @@ const ucp_type_table PRIV(utt)[] = {
{ 299, PT_SC, ucp_Duployan },
{ 308, PT_SC, ucp_Egyptian_Hieroglyphs },
{ 329, PT_SC, ucp_Elbasan },
- { 337, PT_SC, ucp_Ethiopic },
- { 346, PT_SC, ucp_Georgian },
- { 355, PT_SC, ucp_Glagolitic },
- { 366, PT_SC, ucp_Gothic },
- { 373, PT_SC, ucp_Grantha },
- { 381, PT_SC, ucp_Greek },
- { 387, PT_SC, ucp_Gujarati },
- { 396, PT_SC, ucp_Gunjala_Gondi },
- { 410, PT_SC, ucp_Gurmukhi },
- { 419, PT_SC, ucp_Han },
- { 423, PT_SC, ucp_Hangul },
- { 430, PT_SC, ucp_Hanifi_Rohingya },
- { 446, PT_SC, ucp_Hanunoo },
- { 454, PT_SC, ucp_Hatran },
- { 461, PT_SC, ucp_Hebrew },
- { 468, PT_SC, ucp_Hiragana },
- { 477, PT_SC, ucp_Imperial_Aramaic },
- { 494, PT_SC, ucp_Inherited },
- { 504, PT_SC, ucp_Inscriptional_Pahlavi },
- { 526, PT_SC, ucp_Inscriptional_Parthian },
- { 549, PT_SC, ucp_Javanese },
- { 558, PT_SC, ucp_Kaithi },
- { 565, PT_SC, ucp_Kannada },
- { 573, PT_SC, ucp_Katakana },
- { 582, PT_SC, ucp_Kayah_Li },
- { 591, PT_SC, ucp_Kharoshthi },
- { 602, PT_SC, ucp_Khmer },
- { 608, PT_SC, ucp_Khojki },
- { 615, PT_SC, ucp_Khudawadi },
- { 625, PT_GC, ucp_L },
- { 627, PT_LAMP, 0 },
- { 630, PT_SC, ucp_Lao },
- { 634, PT_SC, ucp_Latin },
- { 640, PT_SC, ucp_Lepcha },
- { 647, PT_SC, ucp_Limbu },
- { 653, PT_SC, ucp_Linear_A },
- { 662, PT_SC, ucp_Linear_B },
- { 671, PT_SC, ucp_Lisu },
- { 676, PT_PC, ucp_Ll },
- { 679, PT_PC, ucp_Lm },
- { 682, PT_PC, ucp_Lo },
- { 685, PT_PC, ucp_Lt },
- { 688, PT_PC, ucp_Lu },
- { 691, PT_SC, ucp_Lycian },
- { 698, PT_SC, ucp_Lydian },
- { 705, PT_GC, ucp_M },
- { 707, PT_SC, ucp_Mahajani },
- { 716, PT_SC, ucp_Makasar },
- { 724, PT_SC, ucp_Malayalam },
- { 734, PT_SC, ucp_Mandaic },
- { 742, PT_SC, ucp_Manichaean },
- { 753, PT_SC, ucp_Marchen },
- { 761, PT_SC, ucp_Masaram_Gondi },
- { 775, PT_PC, ucp_Mc },
- { 778, PT_PC, ucp_Me },
- { 781, PT_SC, ucp_Medefaidrin },
- { 793, PT_SC, ucp_Meetei_Mayek },
- { 806, PT_SC, ucp_Mende_Kikakui },
- { 820, PT_SC, ucp_Meroitic_Cursive },
- { 837, PT_SC, ucp_Meroitic_Hieroglyphs },
- { 858, PT_SC, ucp_Miao },
- { 863, PT_PC, ucp_Mn },
- { 866, PT_SC, ucp_Modi },
- { 871, PT_SC, ucp_Mongolian },
- { 881, PT_SC, ucp_Mro },
- { 885, PT_SC, ucp_Multani },
- { 893, PT_SC, ucp_Myanmar },
- { 901, PT_GC, ucp_N },
- { 903, PT_SC, ucp_Nabataean },
- { 913, PT_PC, ucp_Nd },
- { 916, PT_SC, ucp_New_Tai_Lue },
- { 928, PT_SC, ucp_Newa },
- { 933, PT_SC, ucp_Nko },
- { 937, PT_PC, ucp_Nl },
- { 940, PT_PC, ucp_No },
- { 943, PT_SC, ucp_Nushu },
- { 949, PT_SC, ucp_Ogham },
- { 955, PT_SC, ucp_Ol_Chiki },
- { 964, PT_SC, ucp_Old_Hungarian },
- { 978, PT_SC, ucp_Old_Italic },
- { 989, PT_SC, ucp_Old_North_Arabian },
- { 1007, PT_SC, ucp_Old_Permic },
- { 1018, PT_SC, ucp_Old_Persian },
- { 1030, PT_SC, ucp_Old_Sogdian },
- { 1042, PT_SC, ucp_Old_South_Arabian },
- { 1060, PT_SC, ucp_Old_Turkic },
- { 1071, PT_SC, ucp_Oriya },
- { 1077, PT_SC, ucp_Osage },
- { 1083, PT_SC, ucp_Osmanya },
- { 1091, PT_GC, ucp_P },
- { 1093, PT_SC, ucp_Pahawh_Hmong },
- { 1106, PT_SC, ucp_Palmyrene },
- { 1116, PT_SC, ucp_Pau_Cin_Hau },
- { 1128, PT_PC, ucp_Pc },
- { 1131, PT_PC, ucp_Pd },
- { 1134, PT_PC, ucp_Pe },
- { 1137, PT_PC, ucp_Pf },
- { 1140, PT_SC, ucp_Phags_Pa },
- { 1149, PT_SC, ucp_Phoenician },
- { 1160, PT_PC, ucp_Pi },
- { 1163, PT_PC, ucp_Po },
- { 1166, PT_PC, ucp_Ps },
- { 1169, PT_SC, ucp_Psalter_Pahlavi },
- { 1185, PT_SC, ucp_Rejang },
- { 1192, PT_SC, ucp_Runic },
- { 1198, PT_GC, ucp_S },
- { 1200, PT_SC, ucp_Samaritan },
- { 1210, PT_SC, ucp_Saurashtra },
- { 1221, PT_PC, ucp_Sc },
- { 1224, PT_SC, ucp_Sharada },
- { 1232, PT_SC, ucp_Shavian },
- { 1240, PT_SC, ucp_Siddham },
- { 1248, PT_SC, ucp_SignWriting },
- { 1260, PT_SC, ucp_Sinhala },
- { 1268, PT_PC, ucp_Sk },
- { 1271, PT_PC, ucp_Sm },
- { 1274, PT_PC, ucp_So },
- { 1277, PT_SC, ucp_Sogdian },
- { 1285, PT_SC, ucp_Sora_Sompeng },
- { 1298, PT_SC, ucp_Soyombo },
- { 1306, PT_SC, ucp_Sundanese },
- { 1316, PT_SC, ucp_Syloti_Nagri },
- { 1329, PT_SC, ucp_Syriac },
- { 1336, PT_SC, ucp_Tagalog },
- { 1344, PT_SC, ucp_Tagbanwa },
- { 1353, PT_SC, ucp_Tai_Le },
- { 1360, PT_SC, ucp_Tai_Tham },
- { 1369, PT_SC, ucp_Tai_Viet },
- { 1378, PT_SC, ucp_Takri },
- { 1384, PT_SC, ucp_Tamil },
- { 1390, PT_SC, ucp_Tangut },
- { 1397, PT_SC, ucp_Telugu },
- { 1404, PT_SC, ucp_Thaana },
- { 1411, PT_SC, ucp_Thai },
- { 1416, PT_SC, ucp_Tibetan },
- { 1424, PT_SC, ucp_Tifinagh },
- { 1433, PT_SC, ucp_Tirhuta },
- { 1441, PT_SC, ucp_Ugaritic },
- { 1450, PT_SC, ucp_Unknown },
- { 1458, PT_SC, ucp_Vai },
- { 1462, PT_SC, ucp_Warang_Citi },
- { 1474, PT_ALNUM, 0 },
- { 1478, PT_PXSPACE, 0 },
- { 1482, PT_SPACE, 0 },
- { 1486, PT_UCNC, 0 },
- { 1490, PT_WORD, 0 },
- { 1494, PT_SC, ucp_Yi },
- { 1497, PT_GC, ucp_Z },
- { 1499, PT_SC, ucp_Zanabazar_Square },
- { 1516, PT_PC, ucp_Zl },
- { 1519, PT_PC, ucp_Zp },
- { 1522, PT_PC, ucp_Zs }
+ { 337, PT_SC, ucp_Elymaic },
+ { 345, PT_SC, ucp_Ethiopic },
+ { 354, PT_SC, ucp_Georgian },
+ { 363, PT_SC, ucp_Glagolitic },
+ { 374, PT_SC, ucp_Gothic },
+ { 381, PT_SC, ucp_Grantha },
+ { 389, PT_SC, ucp_Greek },
+ { 395, PT_SC, ucp_Gujarati },
+ { 404, PT_SC, ucp_Gunjala_Gondi },
+ { 418, PT_SC, ucp_Gurmukhi },
+ { 427, PT_SC, ucp_Han },
+ { 431, PT_SC, ucp_Hangul },
+ { 438, PT_SC, ucp_Hanifi_Rohingya },
+ { 454, PT_SC, ucp_Hanunoo },
+ { 462, PT_SC, ucp_Hatran },
+ { 469, PT_SC, ucp_Hebrew },
+ { 476, PT_SC, ucp_Hiragana },
+ { 485, PT_SC, ucp_Imperial_Aramaic },
+ { 502, PT_SC, ucp_Inherited },
+ { 512, PT_SC, ucp_Inscriptional_Pahlavi },
+ { 534, PT_SC, ucp_Inscriptional_Parthian },
+ { 557, PT_SC, ucp_Javanese },
+ { 566, PT_SC, ucp_Kaithi },
+ { 573, PT_SC, ucp_Kannada },
+ { 581, PT_SC, ucp_Katakana },
+ { 590, PT_SC, ucp_Kayah_Li },
+ { 599, PT_SC, ucp_Kharoshthi },
+ { 610, PT_SC, ucp_Khmer },
+ { 616, PT_SC, ucp_Khojki },
+ { 623, PT_SC, ucp_Khudawadi },
+ { 633, PT_GC, ucp_L },
+ { 635, PT_LAMP, 0 },
+ { 638, PT_SC, ucp_Lao },
+ { 642, PT_SC, ucp_Latin },
+ { 648, PT_SC, ucp_Lepcha },
+ { 655, PT_SC, ucp_Limbu },
+ { 661, PT_SC, ucp_Linear_A },
+ { 670, PT_SC, ucp_Linear_B },
+ { 679, PT_SC, ucp_Lisu },
+ { 684, PT_PC, ucp_Ll },
+ { 687, PT_PC, ucp_Lm },
+ { 690, PT_PC, ucp_Lo },
+ { 693, PT_PC, ucp_Lt },
+ { 696, PT_PC, ucp_Lu },
+ { 699, PT_SC, ucp_Lycian },
+ { 706, PT_SC, ucp_Lydian },
+ { 713, PT_GC, ucp_M },
+ { 715, PT_SC, ucp_Mahajani },
+ { 724, PT_SC, ucp_Makasar },
+ { 732, PT_SC, ucp_Malayalam },
+ { 742, PT_SC, ucp_Mandaic },
+ { 750, PT_SC, ucp_Manichaean },
+ { 761, PT_SC, ucp_Marchen },
+ { 769, PT_SC, ucp_Masaram_Gondi },
+ { 783, PT_PC, ucp_Mc },
+ { 786, PT_PC, ucp_Me },
+ { 789, PT_SC, ucp_Medefaidrin },
+ { 801, PT_SC, ucp_Meetei_Mayek },
+ { 814, PT_SC, ucp_Mende_Kikakui },
+ { 828, PT_SC, ucp_Meroitic_Cursive },
+ { 845, PT_SC, ucp_Meroitic_Hieroglyphs },
+ { 866, PT_SC, ucp_Miao },
+ { 871, PT_PC, ucp_Mn },
+ { 874, PT_SC, ucp_Modi },
+ { 879, PT_SC, ucp_Mongolian },
+ { 889, PT_SC, ucp_Mro },
+ { 893, PT_SC, ucp_Multani },
+ { 901, PT_SC, ucp_Myanmar },
+ { 909, PT_GC, ucp_N },
+ { 911, PT_SC, ucp_Nabataean },
+ { 921, PT_SC, ucp_Nandinagari },
+ { 933, PT_PC, ucp_Nd },
+ { 936, PT_SC, ucp_New_Tai_Lue },
+ { 948, PT_SC, ucp_Newa },
+ { 953, PT_SC, ucp_Nko },
+ { 957, PT_PC, ucp_Nl },
+ { 960, PT_PC, ucp_No },
+ { 963, PT_SC, ucp_Nushu },
+ { 969, PT_SC, ucp_Nyiakeng_Puachue_Hmong },
+ { 992, PT_SC, ucp_Ogham },
+ { 998, PT_SC, ucp_Ol_Chiki },
+ { 1007, PT_SC, ucp_Old_Hungarian },
+ { 1021, PT_SC, ucp_Old_Italic },
+ { 1032, PT_SC, ucp_Old_North_Arabian },
+ { 1050, PT_SC, ucp_Old_Permic },
+ { 1061, PT_SC, ucp_Old_Persian },
+ { 1073, PT_SC, ucp_Old_Sogdian },
+ { 1085, PT_SC, ucp_Old_South_Arabian },
+ { 1103, PT_SC, ucp_Old_Turkic },
+ { 1114, PT_SC, ucp_Oriya },
+ { 1120, PT_SC, ucp_Osage },
+ { 1126, PT_SC, ucp_Osmanya },
+ { 1134, PT_GC, ucp_P },
+ { 1136, PT_SC, ucp_Pahawh_Hmong },
+ { 1149, PT_SC, ucp_Palmyrene },
+ { 1159, PT_SC, ucp_Pau_Cin_Hau },
+ { 1171, PT_PC, ucp_Pc },
+ { 1174, PT_PC, ucp_Pd },
+ { 1177, PT_PC, ucp_Pe },
+ { 1180, PT_PC, ucp_Pf },
+ { 1183, PT_SC, ucp_Phags_Pa },
+ { 1192, PT_SC, ucp_Phoenician },
+ { 1203, PT_PC, ucp_Pi },
+ { 1206, PT_PC, ucp_Po },
+ { 1209, PT_PC, ucp_Ps },
+ { 1212, PT_SC, ucp_Psalter_Pahlavi },
+ { 1228, PT_SC, ucp_Rejang },
+ { 1235, PT_SC, ucp_Runic },
+ { 1241, PT_GC, ucp_S },
+ { 1243, PT_SC, ucp_Samaritan },
+ { 1253, PT_SC, ucp_Saurashtra },
+ { 1264, PT_PC, ucp_Sc },
+ { 1267, PT_SC, ucp_Sharada },
+ { 1275, PT_SC, ucp_Shavian },
+ { 1283, PT_SC, ucp_Siddham },
+ { 1291, PT_SC, ucp_SignWriting },
+ { 1303, PT_SC, ucp_Sinhala },
+ { 1311, PT_PC, ucp_Sk },
+ { 1314, PT_PC, ucp_Sm },
+ { 1317, PT_PC, ucp_So },
+ { 1320, PT_SC, ucp_Sogdian },
+ { 1328, PT_SC, ucp_Sora_Sompeng },
+ { 1341, PT_SC, ucp_Soyombo },
+ { 1349, PT_SC, ucp_Sundanese },
+ { 1359, PT_SC, ucp_Syloti_Nagri },
+ { 1372, PT_SC, ucp_Syriac },
+ { 1379, PT_SC, ucp_Tagalog },
+ { 1387, PT_SC, ucp_Tagbanwa },
+ { 1396, PT_SC, ucp_Tai_Le },
+ { 1403, PT_SC, ucp_Tai_Tham },
+ { 1412, PT_SC, ucp_Tai_Viet },
+ { 1421, PT_SC, ucp_Takri },
+ { 1427, PT_SC, ucp_Tamil },
+ { 1433, PT_SC, ucp_Tangut },
+ { 1440, PT_SC, ucp_Telugu },
+ { 1447, PT_SC, ucp_Thaana },
+ { 1454, PT_SC, ucp_Thai },
+ { 1459, PT_SC, ucp_Tibetan },
+ { 1467, PT_SC, ucp_Tifinagh },
+ { 1476, PT_SC, ucp_Tirhuta },
+ { 1484, PT_SC, ucp_Ugaritic },
+ { 1493, PT_SC, ucp_Unknown },
+ { 1501, PT_SC, ucp_Vai },
+ { 1505, PT_SC, ucp_Wancho },
+ { 1512, PT_SC, ucp_Warang_Citi },
+ { 1524, PT_ALNUM, 0 },
+ { 1528, PT_PXSPACE, 0 },
+ { 1532, PT_SPACE, 0 },
+ { 1536, PT_UCNC, 0 },
+ { 1540, PT_WORD, 0 },
+ { 1544, PT_SC, ucp_Yi },
+ { 1547, PT_GC, ucp_Z },
+ { 1549, PT_SC, ucp_Zanabazar_Square },
+ { 1566, PT_PC, ucp_Zl },
+ { 1569, PT_PC, ucp_Zp },
+ { 1572, PT_PC, ucp_Zs }
};
const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
diff --git a/thirdparty/pcre2/src/pcre2_ucd.c b/thirdparty/pcre2/src/pcre2_ucd.c
index cc53c24001..55ba03bd43 100644
--- a/thirdparty/pcre2/src/pcre2_ucd.c
+++ b/thirdparty/pcre2/src/pcre2_ucd.c
@@ -20,7 +20,7 @@ needed. */
/* Unicode character database. */
/* This file was autogenerated by the MultiStage2.py script. */
-/* Total size: 97152 bytes, block size: 128. */
+/* Total size: 99316 bytes, block size: 128. */
/* The tables herein are needed only when UCP support is built,
and in PCRE2 that happens automatically with UTF support.
@@ -39,7 +39,7 @@ const uint16_t PRIV(ucd_stage2)[] = {0};
const uint32_t PRIV(ucd_caseless_sets)[] = {0};
#else
-const char *PRIV(unicode_version) = "11.0.0";
+const char *PRIV(unicode_version) = "12.1.0";
/* If the 32-bit library is run in non-32-bit mode, character values
greater than 0x10ffff may be encountered. For these we set up a
@@ -116,7 +116,7 @@ set of decimal digits. It is used to ensure that all the digits in
a script run come from the same set. */
const uint32_t PRIV(ucd_digit_sets)[] = {
- 61, /* Number of subsequent values */
+ 63, /* Number of subsequent values */
0x00039, 0x00669, 0x006f9, 0x007c9, 0x0096f, 0x009ef, 0x00a6f, 0x00aef,
0x00b6f, 0x00bef, 0x00c6f, 0x00cef, 0x00d6f, 0x00def, 0x00e59, 0x00ed9,
0x00f29, 0x01049, 0x01099, 0x017e9, 0x01819, 0x0194f, 0x019d9, 0x01a89,
@@ -124,7 +124,7 @@ const uint32_t PRIV(ucd_digit_sets)[] = {
0x0a9d9, 0x0a9f9, 0x0aa59, 0x0abf9, 0x0ff19, 0x104a9, 0x10d39, 0x1106f,
0x110f9, 0x1113f, 0x111d9, 0x112f9, 0x11459, 0x114d9, 0x11659, 0x116c9,
0x11739, 0x118e9, 0x11c59, 0x11d59, 0x11da9, 0x16a69, 0x16b59, 0x1d7d7,
- 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e959,
+ 0x1d7e1, 0x1d7eb, 0x1d7f5, 0x1d7ff, 0x1e149, 0x1e2f9, 0x1e959,
};
/* This vector is a list of lists of scripts for the Script Extension
@@ -145,38 +145,42 @@ const uint8_t PRIV(ucd_script_sets)[] = {
/* 31 */ 13, 34, 0,
/* 34 */ 13, 118, 0,
/* 37 */ 15, 107, 0,
- /* 40 */ 15, 100, 0,
- /* 43 */ 15, 54, 0,
- /* 46 */ 17, 34, 0,
- /* 49 */ 107, 54, 0,
- /* 52 */ 21, 108, 0,
- /* 55 */ 22, 129, 0,
- /* 58 */ 27, 30, 0,
- /* 61 */ 38, 65, 0,
- /* 64 */ 1, 50, 56, 0,
- /* 68 */ 3, 96, 49, 0,
- /* 72 */ 96, 39, 53, 0,
- /* 76 */ 12, 110, 36, 0,
- /* 80 */ 15, 107, 29, 0,
- /* 84 */ 15, 107, 34, 0,
- /* 88 */ 23, 27, 30, 0,
- /* 92 */ 69, 34, 39, 0,
- /* 96 */ 1, 144, 50, 56, 0,
- /* 101 */ 3, 15, 107, 29, 0,
- /* 106 */ 7, 25, 52, 51, 0,
- /* 111 */ 15, 142, 85, 111, 0,
- /* 116 */ 4, 24, 23, 27, 30, 0,
- /* 122 */ 4, 24, 23, 27, 30, 61, 0,
- /* 129 */ 15, 29, 37, 44, 54, 55, 0,
- /* 136 */ 132, 1, 95, 112, 121, 144, 148, 50, 0,
- /* 145 */ 15, 142, 21, 22, 108, 85, 111, 114, 109, 102, 124, 0,
- /* 157 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 54, 55, 124, 0,
- /* 170 */ 15, 142, 21, 22, 108, 29, 85, 111, 114, 109, 102, 124, 0,
- /* 183 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 100, 54, 55, 124, 0,
- /* 197 */ 15, 142, 21, 22, 108, 29, 85, 111, 37, 114, 109, 102, 124, 0,
- /* 211 */ 3, 15, 142, 143, 107, 21, 22, 29, 111, 37, 44, 109, 48, 49, 102, 54, 55, 124, 0,
- /* 230 */ 3, 15, 142, 143, 107, 21, 22, 29, 35, 111, 37, 44, 109, 48, 49, 102, 54, 55, 124, 0,
- /* 250 */
+ /* 40 */ 15, 150, 0,
+ /* 43 */ 15, 100, 0,
+ /* 46 */ 15, 54, 0,
+ /* 49 */ 17, 34, 0,
+ /* 52 */ 107, 54, 0,
+ /* 55 */ 21, 108, 0,
+ /* 58 */ 22, 129, 0,
+ /* 61 */ 27, 30, 0,
+ /* 64 */ 29, 150, 0,
+ /* 67 */ 34, 38, 0,
+ /* 70 */ 38, 65, 0,
+ /* 73 */ 1, 50, 56, 0,
+ /* 77 */ 3, 96, 49, 0,
+ /* 81 */ 96, 39, 53, 0,
+ /* 85 */ 12, 110, 36, 0,
+ /* 89 */ 15, 107, 29, 0,
+ /* 93 */ 15, 107, 34, 0,
+ /* 97 */ 23, 27, 30, 0,
+ /* 101 */ 69, 34, 39, 0,
+ /* 105 */ 1, 144, 50, 56, 0,
+ /* 110 */ 3, 15, 107, 29, 0,
+ /* 115 */ 7, 25, 52, 51, 0,
+ /* 120 */ 15, 142, 85, 111, 0,
+ /* 125 */ 4, 24, 23, 27, 30, 0,
+ /* 131 */ 4, 24, 23, 27, 30, 61, 0,
+ /* 138 */ 15, 29, 37, 44, 54, 55, 0,
+ /* 145 */ 132, 1, 95, 112, 121, 144, 148, 50, 0,
+ /* 154 */ 3, 15, 107, 29, 150, 44, 55, 124, 0,
+ /* 163 */ 15, 142, 21, 22, 108, 85, 111, 114, 109, 102, 124, 0,
+ /* 175 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 54, 55, 124, 0,
+ /* 188 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 100, 54, 55, 124, 0,
+ /* 202 */ 15, 142, 21, 22, 108, 29, 85, 111, 114, 150, 109, 102, 124, 0,
+ /* 216 */ 15, 142, 21, 22, 108, 29, 85, 111, 37, 114, 150, 109, 102, 124, 0,
+ /* 231 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0,
+ /* 252 */ 3, 15, 142, 143, 138, 107, 21, 22, 29, 35, 111, 37, 150, 44, 109, 48, 49, 102, 54, 55, 124, 0,
+ /* 274 */
};
/* These are the main two-stage UCD tables. The fields in each record are:
@@ -185,7 +189,7 @@ offset to multichar other cases or zero (8 bits), offset to other case
or zero (32 bits, signed), script extension (16 bits, signed), and a dummy
16-bit field to make the whole thing a multiple of 4 bytes. */
-const ucd_record PRIV(ucd_records)[] = { /* 11136 bytes, record size 12 */
+const ucd_record PRIV(ucd_records)[] = { /* 11508 bytes, record size 12 */
{ 10, 0, 2, 0, 0, 10, 256, }, /* 0 */
{ 10, 0, 2, 0, 0, 10, 0, }, /* 1 */
{ 10, 0, 1, 0, 0, 10, 0, }, /* 2 */
@@ -288,832 +292,863 @@ const ucd_record PRIV(ucd_records)[] = { /* 11136 bytes, record size 12 */
{ 34, 5, 12, 0, -214, 34, 0, }, /* 99 */
{ 34, 5, 12, 0, 10727, 34, 0, }, /* 100 */
{ 34, 5, 12, 0, -218, 34, 0, }, /* 101 */
- { 34, 5, 12, 0, 42282, 34, 0, }, /* 102 */
- { 34, 5, 12, 0, -69, 34, 0, }, /* 103 */
- { 34, 5, 12, 0, -217, 34, 0, }, /* 104 */
- { 34, 5, 12, 0, -71, 34, 0, }, /* 105 */
- { 34, 5, 12, 0, -219, 34, 0, }, /* 106 */
- { 34, 5, 12, 0, 42261, 34, 0, }, /* 107 */
- { 34, 5, 12, 0, 42258, 34, 0, }, /* 108 */
- { 34, 6, 12, 0, 0, 34, 0, }, /* 109 */
- { 10, 6, 12, 0, 0, 10, 0, }, /* 110 */
- { 4, 24, 12, 0, 0, 4, 0, }, /* 111 */
- { 28, 12, 3, 0, 0, 28, 0, }, /* 112 */
- { 28, 12, 3, 0, 0, 20, 0, }, /* 113 */
- { 28, 12, 3, 21, 116, 20, 0, }, /* 114 */
- { 28, 12, 3, 0, 0, 34, 0, }, /* 115 */
- { 20, 9, 12, 0, 1, 20, 0, }, /* 116 */
- { 20, 5, 12, 0, -1, 20, 0, }, /* 117 */
- { 20, 24, 12, 0, 0, 20, 0, }, /* 118 */
- { 0, 2, 12, 0, 0, 0, 0, }, /* 119 */
- { 20, 6, 12, 0, 0, 20, 0, }, /* 120 */
- { 20, 5, 12, 0, 130, 20, 0, }, /* 121 */
- { 20, 9, 12, 0, 116, 20, 0, }, /* 122 */
- { 20, 9, 12, 0, 38, 20, 0, }, /* 123 */
- { 20, 9, 12, 0, 37, 20, 0, }, /* 124 */
- { 20, 9, 12, 0, 64, 20, 0, }, /* 125 */
- { 20, 9, 12, 0, 63, 20, 0, }, /* 126 */
- { 20, 5, 12, 0, 0, 20, 0, }, /* 127 */
- { 20, 9, 12, 0, 32, 20, 0, }, /* 128 */
- { 20, 9, 12, 34, 32, 20, 0, }, /* 129 */
- { 20, 9, 12, 59, 32, 20, 0, }, /* 130 */
- { 20, 9, 12, 38, 32, 20, 0, }, /* 131 */
- { 20, 9, 12, 21, 32, 20, 0, }, /* 132 */
- { 20, 9, 12, 51, 32, 20, 0, }, /* 133 */
- { 20, 9, 12, 26, 32, 20, 0, }, /* 134 */
- { 20, 9, 12, 47, 32, 20, 0, }, /* 135 */
- { 20, 9, 12, 55, 32, 20, 0, }, /* 136 */
- { 20, 9, 12, 30, 32, 20, 0, }, /* 137 */
- { 20, 9, 12, 43, 32, 20, 0, }, /* 138 */
- { 20, 9, 12, 96, 32, 20, 0, }, /* 139 */
- { 20, 5, 12, 0, -38, 20, 0, }, /* 140 */
- { 20, 5, 12, 0, -37, 20, 0, }, /* 141 */
- { 20, 5, 12, 0, -32, 20, 0, }, /* 142 */
- { 20, 5, 12, 34, -32, 20, 0, }, /* 143 */
- { 20, 5, 12, 59, -32, 20, 0, }, /* 144 */
- { 20, 5, 12, 38, -32, 20, 0, }, /* 145 */
- { 20, 5, 12, 21, -116, 20, 0, }, /* 146 */
- { 20, 5, 12, 51, -32, 20, 0, }, /* 147 */
- { 20, 5, 12, 26, -775, 20, 0, }, /* 148 */
- { 20, 5, 12, 47, -32, 20, 0, }, /* 149 */
- { 20, 5, 12, 55, -32, 20, 0, }, /* 150 */
- { 20, 5, 12, 30, 1, 20, 0, }, /* 151 */
- { 20, 5, 12, 30, -32, 20, 0, }, /* 152 */
- { 20, 5, 12, 43, -32, 20, 0, }, /* 153 */
- { 20, 5, 12, 96, -32, 20, 0, }, /* 154 */
- { 20, 5, 12, 0, -64, 20, 0, }, /* 155 */
- { 20, 5, 12, 0, -63, 20, 0, }, /* 156 */
- { 20, 9, 12, 0, 8, 20, 0, }, /* 157 */
- { 20, 5, 12, 34, -30, 20, 0, }, /* 158 */
- { 20, 5, 12, 38, -25, 20, 0, }, /* 159 */
- { 20, 9, 12, 0, 0, 20, 0, }, /* 160 */
- { 20, 5, 12, 43, -15, 20, 0, }, /* 161 */
- { 20, 5, 12, 47, -22, 20, 0, }, /* 162 */
- { 20, 5, 12, 0, -8, 20, 0, }, /* 163 */
- { 11, 9, 12, 0, 1, 11, 0, }, /* 164 */
- { 11, 5, 12, 0, -1, 11, 0, }, /* 165 */
- { 20, 5, 12, 51, -54, 20, 0, }, /* 166 */
- { 20, 5, 12, 55, -48, 20, 0, }, /* 167 */
- { 20, 5, 12, 0, 7, 20, 0, }, /* 168 */
- { 20, 5, 12, 0, -116, 20, 0, }, /* 169 */
- { 20, 9, 12, 38, -60, 20, 0, }, /* 170 */
- { 20, 5, 12, 59, -64, 20, 0, }, /* 171 */
- { 20, 25, 12, 0, 0, 20, 0, }, /* 172 */
- { 20, 9, 12, 0, -7, 20, 0, }, /* 173 */
- { 20, 9, 12, 0, -130, 20, 0, }, /* 174 */
- { 13, 9, 12, 0, 80, 13, 0, }, /* 175 */
- { 13, 9, 12, 0, 32, 13, 0, }, /* 176 */
- { 13, 9, 12, 63, 32, 13, 0, }, /* 177 */
- { 13, 9, 12, 67, 32, 13, 0, }, /* 178 */
- { 13, 9, 12, 71, 32, 13, 0, }, /* 179 */
- { 13, 9, 12, 75, 32, 13, 0, }, /* 180 */
- { 13, 9, 12, 79, 32, 13, 0, }, /* 181 */
- { 13, 9, 12, 84, 32, 13, 0, }, /* 182 */
- { 13, 5, 12, 0, -32, 13, 0, }, /* 183 */
- { 13, 5, 12, 63, -32, 13, 0, }, /* 184 */
- { 13, 5, 12, 67, -32, 13, 0, }, /* 185 */
- { 13, 5, 12, 71, -32, 13, 0, }, /* 186 */
- { 13, 5, 12, 75, -32, 13, 0, }, /* 187 */
- { 13, 5, 12, 79, -32, 13, 0, }, /* 188 */
- { 13, 5, 12, 84, -32, 13, 0, }, /* 189 */
- { 13, 5, 12, 0, -80, 13, 0, }, /* 190 */
- { 13, 9, 12, 0, 1, 13, 0, }, /* 191 */
- { 13, 5, 12, 0, -1, 13, 0, }, /* 192 */
- { 13, 9, 12, 88, 1, 13, 0, }, /* 193 */
- { 13, 5, 12, 88, -1, 13, 0, }, /* 194 */
- { 13, 26, 12, 0, 0, 13, 0, }, /* 195 */
- { 13, 12, 3, 0, 0, -34, 0, }, /* 196 */
- { 13, 12, 3, 0, 0, -28, 0, }, /* 197 */
- { 28, 12, 3, 0, 0, -31, 0, }, /* 198 */
- { 13, 11, 3, 0, 0, 13, 0, }, /* 199 */
- { 13, 9, 12, 0, 15, 13, 0, }, /* 200 */
- { 13, 5, 12, 0, -15, 13, 0, }, /* 201 */
- { 2, 9, 12, 0, 48, 2, 0, }, /* 202 */
- { 2, 6, 12, 0, 0, 2, 0, }, /* 203 */
- { 2, 21, 12, 0, 0, 2, 0, }, /* 204 */
- { 2, 5, 12, 0, 0, 2, 0, }, /* 205 */
- { 2, 5, 12, 0, -48, 2, 0, }, /* 206 */
- { 10, 21, 12, 0, 0, -13, 0, }, /* 207 */
- { 2, 17, 12, 0, 0, 2, 0, }, /* 208 */
- { 2, 26, 12, 0, 0, 2, 0, }, /* 209 */
- { 2, 23, 12, 0, 0, 2, 0, }, /* 210 */
- { 26, 12, 3, 0, 0, 26, 0, }, /* 211 */
- { 26, 17, 12, 0, 0, 26, 0, }, /* 212 */
- { 26, 21, 12, 0, 0, 26, 0, }, /* 213 */
- { 26, 7, 12, 0, 0, 26, 0, }, /* 214 */
- { 1, 1, 4, 0, 0, 1, 0, }, /* 215 */
- { 10, 1, 4, 0, 0, 10, 0, }, /* 216 */
- { 1, 25, 12, 0, 0, 1, 0, }, /* 217 */
- { 1, 21, 12, 0, 0, 1, 0, }, /* 218 */
- { 1, 23, 12, 0, 0, 1, 0, }, /* 219 */
- { 10, 21, 12, 0, 0, -96, 0, }, /* 220 */
- { 1, 26, 12, 0, 0, 1, 0, }, /* 221 */
- { 1, 12, 3, 0, 0, 1, 0, }, /* 222 */
- { 1, 1, 2, 0, 0, -64, 0, }, /* 223 */
- { 1, 7, 12, 0, 0, 1, 0, }, /* 224 */
- { 10, 6, 12, 0, 0, -136, 0, }, /* 225 */
- { 28, 12, 3, 0, 0, -7, 0, }, /* 226 */
- { 1, 13, 12, 0, 0, -10, 0, }, /* 227 */
- { 1, 21, 12, 0, 0, -4, 0, }, /* 228 */
- { 1, 6, 12, 0, 0, 1, 0, }, /* 229 */
- { 1, 13, 12, 0, 0, 1, 0, }, /* 230 */
- { 50, 21, 12, 0, 0, 50, 0, }, /* 231 */
- { 50, 1, 4, 0, 0, 50, 0, }, /* 232 */
- { 50, 7, 12, 0, 0, 50, 0, }, /* 233 */
- { 50, 12, 3, 0, 0, 50, 0, }, /* 234 */
- { 56, 7, 12, 0, 0, 56, 0, }, /* 235 */
- { 56, 12, 3, 0, 0, 56, 0, }, /* 236 */
- { 64, 13, 12, 0, 0, 64, 0, }, /* 237 */
- { 64, 7, 12, 0, 0, 64, 0, }, /* 238 */
- { 64, 12, 3, 0, 0, 64, 0, }, /* 239 */
- { 64, 6, 12, 0, 0, 64, 0, }, /* 240 */
- { 64, 26, 12, 0, 0, 64, 0, }, /* 241 */
- { 64, 21, 12, 0, 0, 64, 0, }, /* 242 */
- { 64, 23, 12, 0, 0, 64, 0, }, /* 243 */
- { 90, 7, 12, 0, 0, 90, 0, }, /* 244 */
- { 90, 12, 3, 0, 0, 90, 0, }, /* 245 */
- { 90, 6, 12, 0, 0, 90, 0, }, /* 246 */
- { 90, 21, 12, 0, 0, 90, 0, }, /* 247 */
- { 95, 7, 12, 0, 0, 95, 0, }, /* 248 */
- { 95, 12, 3, 0, 0, 95, 0, }, /* 249 */
- { 95, 21, 12, 0, 0, 95, 0, }, /* 250 */
- { 15, 12, 3, 0, 0, 15, 0, }, /* 251 */
- { 15, 10, 5, 0, 0, 15, 0, }, /* 252 */
- { 15, 7, 12, 0, 0, 15, 0, }, /* 253 */
- { 28, 12, 3, 0, 0, -183, 0, }, /* 254 */
- { 28, 12, 3, 0, 0, -157, 0, }, /* 255 */
- { 10, 21, 12, 0, 0, -211, 0, }, /* 256 */
- { 10, 21, 12, 0, 0, -230, 0, }, /* 257 */
- { 15, 13, 12, 0, 0, -111, 0, }, /* 258 */
- { 15, 21, 12, 0, 0, 15, 0, }, /* 259 */
- { 15, 6, 12, 0, 0, 15, 0, }, /* 260 */
- { 3, 7, 12, 0, 0, 3, 0, }, /* 261 */
- { 3, 12, 3, 0, 0, 3, 0, }, /* 262 */
- { 3, 10, 5, 0, 0, 3, 0, }, /* 263 */
- { 3, 10, 3, 0, 0, 3, 0, }, /* 264 */
- { 3, 13, 12, 0, 0, -68, 0, }, /* 265 */
- { 3, 23, 12, 0, 0, 3, 0, }, /* 266 */
- { 3, 15, 12, 0, 0, 3, 0, }, /* 267 */
- { 3, 26, 12, 0, 0, 3, 0, }, /* 268 */
- { 3, 21, 12, 0, 0, 3, 0, }, /* 269 */
- { 22, 12, 3, 0, 0, 22, 0, }, /* 270 */
- { 22, 10, 5, 0, 0, 22, 0, }, /* 271 */
- { 22, 7, 12, 0, 0, 22, 0, }, /* 272 */
- { 22, 13, 12, 0, 0, -55, 0, }, /* 273 */
- { 22, 21, 12, 0, 0, 22, 0, }, /* 274 */
- { 21, 12, 3, 0, 0, 21, 0, }, /* 275 */
- { 21, 10, 5, 0, 0, 21, 0, }, /* 276 */
- { 21, 7, 12, 0, 0, 21, 0, }, /* 277 */
- { 21, 13, 12, 0, 0, -52, 0, }, /* 278 */
- { 21, 21, 12, 0, 0, 21, 0, }, /* 279 */
- { 21, 23, 12, 0, 0, 21, 0, }, /* 280 */
- { 44, 12, 3, 0, 0, 44, 0, }, /* 281 */
- { 44, 10, 5, 0, 0, 44, 0, }, /* 282 */
- { 44, 7, 12, 0, 0, 44, 0, }, /* 283 */
- { 44, 10, 3, 0, 0, 44, 0, }, /* 284 */
- { 44, 13, 12, 0, 0, 44, 0, }, /* 285 */
- { 44, 26, 12, 0, 0, 44, 0, }, /* 286 */
- { 44, 15, 12, 0, 0, 44, 0, }, /* 287 */
- { 54, 12, 3, 0, 0, 54, 0, }, /* 288 */
- { 54, 7, 12, 0, 0, 54, 0, }, /* 289 */
- { 54, 10, 3, 0, 0, 54, 0, }, /* 290 */
- { 54, 10, 5, 0, 0, 54, 0, }, /* 291 */
- { 54, 13, 12, 0, 0, -49, 0, }, /* 292 */
- { 54, 15, 12, 0, 0, -49, 0, }, /* 293 */
- { 54, 26, 12, 0, 0, -49, 0, }, /* 294 */
- { 54, 26, 12, 0, 0, 54, 0, }, /* 295 */
- { 54, 23, 12, 0, 0, 54, 0, }, /* 296 */
- { 55, 12, 3, 0, 0, 55, 0, }, /* 297 */
- { 55, 10, 5, 0, 0, 55, 0, }, /* 298 */
- { 55, 7, 12, 0, 0, 55, 0, }, /* 299 */
- { 55, 13, 12, 0, 0, 55, 0, }, /* 300 */
- { 55, 15, 12, 0, 0, 55, 0, }, /* 301 */
- { 55, 26, 12, 0, 0, 55, 0, }, /* 302 */
- { 29, 7, 12, 0, 0, 29, 0, }, /* 303 */
- { 29, 12, 3, 0, 0, 29, 0, }, /* 304 */
- { 29, 10, 5, 0, 0, 29, 0, }, /* 305 */
- { 29, 21, 12, 0, 0, 29, 0, }, /* 306 */
- { 29, 10, 3, 0, 0, 29, 0, }, /* 307 */
- { 29, 13, 12, 0, 0, 29, 0, }, /* 308 */
- { 37, 12, 3, 0, 0, 37, 0, }, /* 309 */
- { 37, 10, 5, 0, 0, 37, 0, }, /* 310 */
- { 37, 7, 12, 0, 0, 37, 0, }, /* 311 */
- { 37, 10, 3, 0, 0, 37, 0, }, /* 312 */
- { 37, 7, 4, 0, 0, 37, 0, }, /* 313 */
- { 37, 26, 12, 0, 0, 37, 0, }, /* 314 */
- { 37, 15, 12, 0, 0, 37, 0, }, /* 315 */
- { 37, 13, 12, 0, 0, 37, 0, }, /* 316 */
- { 48, 10, 5, 0, 0, 48, 0, }, /* 317 */
- { 48, 7, 12, 0, 0, 48, 0, }, /* 318 */
- { 48, 12, 3, 0, 0, 48, 0, }, /* 319 */
- { 48, 10, 3, 0, 0, 48, 0, }, /* 320 */
- { 48, 13, 12, 0, 0, 48, 0, }, /* 321 */
- { 48, 21, 12, 0, 0, 48, 0, }, /* 322 */
- { 57, 7, 12, 0, 0, 57, 0, }, /* 323 */
- { 57, 12, 3, 0, 0, 57, 0, }, /* 324 */
- { 57, 7, 5, 0, 0, 57, 0, }, /* 325 */
- { 57, 6, 12, 0, 0, 57, 0, }, /* 326 */
- { 57, 21, 12, 0, 0, 57, 0, }, /* 327 */
- { 57, 13, 12, 0, 0, 57, 0, }, /* 328 */
- { 33, 7, 12, 0, 0, 33, 0, }, /* 329 */
- { 33, 12, 3, 0, 0, 33, 0, }, /* 330 */
- { 33, 7, 5, 0, 0, 33, 0, }, /* 331 */
- { 33, 6, 12, 0, 0, 33, 0, }, /* 332 */
- { 33, 13, 12, 0, 0, 33, 0, }, /* 333 */
- { 58, 7, 12, 0, 0, 58, 0, }, /* 334 */
- { 58, 26, 12, 0, 0, 58, 0, }, /* 335 */
- { 58, 21, 12, 0, 0, 58, 0, }, /* 336 */
- { 58, 12, 3, 0, 0, 58, 0, }, /* 337 */
- { 58, 13, 12, 0, 0, 58, 0, }, /* 338 */
- { 58, 15, 12, 0, 0, 58, 0, }, /* 339 */
- { 58, 22, 12, 0, 0, 58, 0, }, /* 340 */
- { 58, 18, 12, 0, 0, 58, 0, }, /* 341 */
- { 58, 10, 5, 0, 0, 58, 0, }, /* 342 */
- { 39, 7, 12, 0, 0, 39, 0, }, /* 343 */
- { 39, 10, 12, 0, 0, 39, 0, }, /* 344 */
- { 39, 12, 3, 0, 0, 39, 0, }, /* 345 */
- { 39, 10, 5, 0, 0, 39, 0, }, /* 346 */
- { 39, 13, 12, 0, 0, -72, 0, }, /* 347 */
- { 39, 21, 12, 0, 0, 39, 0, }, /* 348 */
- { 39, 13, 12, 0, 0, 39, 0, }, /* 349 */
- { 39, 26, 12, 0, 0, 39, 0, }, /* 350 */
- { 17, 9, 12, 0, 7264, 17, 0, }, /* 351 */
- { 17, 5, 12, 0, 3008, 17, 0, }, /* 352 */
- { 10, 21, 12, 0, 0, -46, 0, }, /* 353 */
- { 17, 6, 12, 0, 0, 17, 0, }, /* 354 */
- { 24, 7, 6, 0, 0, 24, 0, }, /* 355 */
- { 24, 7, 7, 0, 0, 24, 0, }, /* 356 */
- { 24, 7, 8, 0, 0, 24, 0, }, /* 357 */
- { 16, 7, 12, 0, 0, 16, 0, }, /* 358 */
- { 16, 12, 3, 0, 0, 16, 0, }, /* 359 */
- { 16, 21, 12, 0, 0, 16, 0, }, /* 360 */
- { 16, 15, 12, 0, 0, 16, 0, }, /* 361 */
- { 16, 26, 12, 0, 0, 16, 0, }, /* 362 */
- { 9, 9, 12, 0, 38864, 9, 0, }, /* 363 */
- { 9, 9, 12, 0, 8, 9, 0, }, /* 364 */
- { 9, 5, 12, 0, -8, 9, 0, }, /* 365 */
- { 8, 17, 12, 0, 0, 8, 0, }, /* 366 */
- { 8, 7, 12, 0, 0, 8, 0, }, /* 367 */
- { 8, 21, 12, 0, 0, 8, 0, }, /* 368 */
- { 41, 29, 12, 0, 0, 41, 0, }, /* 369 */
- { 41, 7, 12, 0, 0, 41, 0, }, /* 370 */
- { 41, 22, 12, 0, 0, 41, 0, }, /* 371 */
- { 41, 18, 12, 0, 0, 41, 0, }, /* 372 */
- { 46, 7, 12, 0, 0, 46, 0, }, /* 373 */
- { 46, 14, 12, 0, 0, 46, 0, }, /* 374 */
- { 51, 7, 12, 0, 0, 51, 0, }, /* 375 */
- { 51, 12, 3, 0, 0, 51, 0, }, /* 376 */
- { 25, 7, 12, 0, 0, 25, 0, }, /* 377 */
- { 25, 12, 3, 0, 0, 25, 0, }, /* 378 */
- { 10, 21, 12, 0, 0, -106, 0, }, /* 379 */
- { 7, 7, 12, 0, 0, 7, 0, }, /* 380 */
- { 7, 12, 3, 0, 0, 7, 0, }, /* 381 */
- { 52, 7, 12, 0, 0, 52, 0, }, /* 382 */
- { 52, 12, 3, 0, 0, 52, 0, }, /* 383 */
- { 32, 7, 12, 0, 0, 32, 0, }, /* 384 */
- { 32, 12, 3, 0, 0, 32, 0, }, /* 385 */
- { 32, 10, 5, 0, 0, 32, 0, }, /* 386 */
- { 32, 21, 12, 0, 0, 32, 0, }, /* 387 */
- { 32, 6, 12, 0, 0, 32, 0, }, /* 388 */
- { 32, 23, 12, 0, 0, 32, 0, }, /* 389 */
- { 32, 13, 12, 0, 0, 32, 0, }, /* 390 */
- { 32, 15, 12, 0, 0, 32, 0, }, /* 391 */
- { 38, 21, 12, 0, 0, 38, 0, }, /* 392 */
- { 10, 21, 12, 0, 0, -61, 0, }, /* 393 */
- { 38, 17, 12, 0, 0, 38, 0, }, /* 394 */
- { 38, 12, 3, 0, 0, 38, 0, }, /* 395 */
- { 38, 1, 2, 0, 0, 38, 0, }, /* 396 */
- { 38, 13, 12, 0, 0, 38, 0, }, /* 397 */
- { 38, 7, 12, 0, 0, 38, 0, }, /* 398 */
- { 38, 6, 12, 0, 0, 38, 0, }, /* 399 */
- { 35, 7, 12, 0, 0, 35, 0, }, /* 400 */
- { 35, 12, 3, 0, 0, 35, 0, }, /* 401 */
- { 35, 10, 5, 0, 0, 35, 0, }, /* 402 */
- { 35, 26, 12, 0, 0, 35, 0, }, /* 403 */
- { 35, 21, 12, 0, 0, 35, 0, }, /* 404 */
- { 35, 13, 12, 0, 0, 35, 0, }, /* 405 */
- { 53, 7, 12, 0, 0, 53, 0, }, /* 406 */
- { 40, 7, 12, 0, 0, 40, 0, }, /* 407 */
- { 40, 13, 12, 0, 0, 40, 0, }, /* 408 */
- { 40, 15, 12, 0, 0, 40, 0, }, /* 409 */
- { 40, 26, 12, 0, 0, 40, 0, }, /* 410 */
- { 32, 26, 12, 0, 0, 32, 0, }, /* 411 */
- { 6, 7, 12, 0, 0, 6, 0, }, /* 412 */
- { 6, 12, 3, 0, 0, 6, 0, }, /* 413 */
- { 6, 10, 5, 0, 0, 6, 0, }, /* 414 */
- { 6, 21, 12, 0, 0, 6, 0, }, /* 415 */
- { 91, 7, 12, 0, 0, 91, 0, }, /* 416 */
- { 91, 10, 5, 0, 0, 91, 0, }, /* 417 */
- { 91, 12, 3, 0, 0, 91, 0, }, /* 418 */
- { 91, 10, 12, 0, 0, 91, 0, }, /* 419 */
- { 91, 13, 12, 0, 0, 91, 0, }, /* 420 */
- { 91, 21, 12, 0, 0, 91, 0, }, /* 421 */
- { 91, 6, 12, 0, 0, 91, 0, }, /* 422 */
- { 28, 11, 3, 0, 0, 28, 0, }, /* 423 */
- { 62, 12, 3, 0, 0, 62, 0, }, /* 424 */
- { 62, 10, 5, 0, 0, 62, 0, }, /* 425 */
- { 62, 7, 12, 0, 0, 62, 0, }, /* 426 */
- { 62, 13, 12, 0, 0, 62, 0, }, /* 427 */
- { 62, 21, 12, 0, 0, 62, 0, }, /* 428 */
- { 62, 26, 12, 0, 0, 62, 0, }, /* 429 */
- { 76, 12, 3, 0, 0, 76, 0, }, /* 430 */
- { 76, 10, 5, 0, 0, 76, 0, }, /* 431 */
- { 76, 7, 12, 0, 0, 76, 0, }, /* 432 */
- { 76, 13, 12, 0, 0, 76, 0, }, /* 433 */
- { 93, 7, 12, 0, 0, 93, 0, }, /* 434 */
- { 93, 12, 3, 0, 0, 93, 0, }, /* 435 */
- { 93, 10, 5, 0, 0, 93, 0, }, /* 436 */
- { 93, 21, 12, 0, 0, 93, 0, }, /* 437 */
- { 70, 7, 12, 0, 0, 70, 0, }, /* 438 */
- { 70, 10, 5, 0, 0, 70, 0, }, /* 439 */
- { 70, 12, 3, 0, 0, 70, 0, }, /* 440 */
- { 70, 21, 12, 0, 0, 70, 0, }, /* 441 */
- { 70, 13, 12, 0, 0, 70, 0, }, /* 442 */
- { 73, 13, 12, 0, 0, 73, 0, }, /* 443 */
- { 73, 7, 12, 0, 0, 73, 0, }, /* 444 */
- { 73, 6, 12, 0, 0, 73, 0, }, /* 445 */
- { 73, 21, 12, 0, 0, 73, 0, }, /* 446 */
- { 13, 5, 12, 63, -6222, 13, 0, }, /* 447 */
- { 13, 5, 12, 67, -6221, 13, 0, }, /* 448 */
- { 13, 5, 12, 71, -6212, 13, 0, }, /* 449 */
- { 13, 5, 12, 75, -6210, 13, 0, }, /* 450 */
- { 13, 5, 12, 79, -6210, 13, 0, }, /* 451 */
- { 13, 5, 12, 79, -6211, 13, 0, }, /* 452 */
- { 13, 5, 12, 84, -6204, 13, 0, }, /* 453 */
- { 13, 5, 12, 88, -6180, 13, 0, }, /* 454 */
- { 13, 5, 12, 108, 35267, 13, 0, }, /* 455 */
- { 17, 9, 12, 0, -3008, 17, 0, }, /* 456 */
- { 76, 21, 12, 0, 0, 76, 0, }, /* 457 */
- { 28, 12, 3, 0, 0, -101, 0, }, /* 458 */
- { 28, 12, 3, 0, 0, 15, 0, }, /* 459 */
- { 10, 21, 12, 0, 0, -37, 0, }, /* 460 */
- { 28, 12, 3, 0, 0, -16, 0, }, /* 461 */
- { 28, 12, 3, 0, 0, -40, 0, }, /* 462 */
- { 28, 12, 3, 0, 0, -129, 0, }, /* 463 */
- { 10, 10, 5, 0, 0, -16, 0, }, /* 464 */
- { 10, 7, 12, 0, 0, 15, 0, }, /* 465 */
- { 10, 7, 12, 0, 0, -16, 0, }, /* 466 */
- { 10, 10, 5, 0, 0, -37, 0, }, /* 467 */
- { 28, 12, 3, 0, 0, -80, 0, }, /* 468 */
- { 10, 10, 5, 0, 0, 3, 0, }, /* 469 */
- { 28, 12, 3, 0, 0, -37, 0, }, /* 470 */
- { 13, 5, 12, 0, 0, 13, 0, }, /* 471 */
- { 13, 6, 12, 0, 0, 13, 0, }, /* 472 */
- { 34, 5, 12, 0, 35332, 34, 0, }, /* 473 */
- { 34, 5, 12, 0, 3814, 34, 0, }, /* 474 */
- { 34, 9, 12, 92, 1, 34, 0, }, /* 475 */
- { 34, 5, 12, 92, -1, 34, 0, }, /* 476 */
- { 34, 5, 12, 92, -58, 34, 0, }, /* 477 */
- { 34, 9, 12, 0, -7615, 34, 0, }, /* 478 */
- { 20, 5, 12, 0, 8, 20, 0, }, /* 479 */
- { 20, 9, 12, 0, -8, 20, 0, }, /* 480 */
- { 20, 5, 12, 0, 74, 20, 0, }, /* 481 */
- { 20, 5, 12, 0, 86, 20, 0, }, /* 482 */
- { 20, 5, 12, 0, 100, 20, 0, }, /* 483 */
- { 20, 5, 12, 0, 128, 20, 0, }, /* 484 */
- { 20, 5, 12, 0, 112, 20, 0, }, /* 485 */
- { 20, 5, 12, 0, 126, 20, 0, }, /* 486 */
- { 20, 8, 12, 0, -8, 20, 0, }, /* 487 */
- { 20, 5, 12, 0, 9, 20, 0, }, /* 488 */
- { 20, 9, 12, 0, -74, 20, 0, }, /* 489 */
- { 20, 8, 12, 0, -9, 20, 0, }, /* 490 */
- { 20, 5, 12, 21, -7173, 20, 0, }, /* 491 */
- { 20, 9, 12, 0, -86, 20, 0, }, /* 492 */
- { 20, 9, 12, 0, -100, 20, 0, }, /* 493 */
- { 20, 9, 12, 0, -112, 20, 0, }, /* 494 */
- { 20, 9, 12, 0, -128, 20, 0, }, /* 495 */
- { 20, 9, 12, 0, -126, 20, 0, }, /* 496 */
- { 28, 1, 3, 0, 0, 28, 0, }, /* 497 */
- { 28, 1, 13, 0, 0, 28, 0, }, /* 498 */
- { 10, 27, 2, 0, 0, 10, 0, }, /* 499 */
- { 10, 28, 2, 0, 0, 10, 0, }, /* 500 */
- { 10, 21, 14, 0, 0, 10, 0, }, /* 501 */
- { 0, 2, 2, 0, 0, 0, 0, }, /* 502 */
- { 28, 12, 3, 0, 0, -84, 0, }, /* 503 */
- { 10, 9, 12, 0, 0, 10, 0, }, /* 504 */
- { 10, 5, 12, 0, 0, 10, 0, }, /* 505 */
- { 20, 9, 12, 96, -7517, 20, 0, }, /* 506 */
- { 34, 9, 12, 100, -8383, 34, 0, }, /* 507 */
- { 34, 9, 12, 104, -8262, 34, 0, }, /* 508 */
- { 34, 9, 12, 0, 28, 34, 0, }, /* 509 */
- { 10, 7, 12, 0, 0, 10, 0, }, /* 510 */
- { 10, 5, 14, 0, 0, 10, 0, }, /* 511 */
- { 34, 5, 12, 0, -28, 34, 0, }, /* 512 */
- { 34, 14, 12, 0, 16, 34, 0, }, /* 513 */
- { 34, 14, 12, 0, -16, 34, 0, }, /* 514 */
- { 34, 14, 12, 0, 0, 34, 0, }, /* 515 */
- { 10, 25, 14, 0, 0, 10, 0, }, /* 516 */
- { 10, 26, 12, 0, 26, 10, 0, }, /* 517 */
- { 10, 26, 14, 0, 26, 10, 0, }, /* 518 */
- { 10, 26, 12, 0, -26, 10, 0, }, /* 519 */
- { 5, 26, 12, 0, 0, 5, 0, }, /* 520 */
- { 18, 9, 12, 0, 48, 18, 0, }, /* 521 */
- { 18, 5, 12, 0, -48, 18, 0, }, /* 522 */
- { 34, 9, 12, 0, -10743, 34, 0, }, /* 523 */
- { 34, 9, 12, 0, -3814, 34, 0, }, /* 524 */
- { 34, 9, 12, 0, -10727, 34, 0, }, /* 525 */
- { 34, 5, 12, 0, -10795, 34, 0, }, /* 526 */
- { 34, 5, 12, 0, -10792, 34, 0, }, /* 527 */
- { 34, 9, 12, 0, -10780, 34, 0, }, /* 528 */
- { 34, 9, 12, 0, -10749, 34, 0, }, /* 529 */
- { 34, 9, 12, 0, -10783, 34, 0, }, /* 530 */
- { 34, 9, 12, 0, -10782, 34, 0, }, /* 531 */
- { 34, 9, 12, 0, -10815, 34, 0, }, /* 532 */
- { 11, 5, 12, 0, 0, 11, 0, }, /* 533 */
- { 11, 26, 12, 0, 0, 11, 0, }, /* 534 */
- { 11, 12, 3, 0, 0, 11, 0, }, /* 535 */
- { 11, 21, 12, 0, 0, 11, 0, }, /* 536 */
- { 11, 15, 12, 0, 0, 11, 0, }, /* 537 */
- { 17, 5, 12, 0, -7264, 17, 0, }, /* 538 */
- { 59, 7, 12, 0, 0, 59, 0, }, /* 539 */
- { 59, 6, 12, 0, 0, 59, 0, }, /* 540 */
- { 59, 21, 12, 0, 0, 59, 0, }, /* 541 */
- { 59, 12, 3, 0, 0, 59, 0, }, /* 542 */
- { 13, 12, 3, 0, 0, 13, 0, }, /* 543 */
- { 10, 21, 12, 0, 0, -28, 0, }, /* 544 */
- { 23, 26, 12, 0, 0, 23, 0, }, /* 545 */
- { 10, 21, 12, 0, 0, -122, 0, }, /* 546 */
- { 10, 21, 12, 0, 0, -116, 0, }, /* 547 */
- { 23, 6, 12, 0, 0, 23, 0, }, /* 548 */
- { 10, 7, 12, 0, 0, 23, 0, }, /* 549 */
- { 23, 14, 12, 0, 0, 23, 0, }, /* 550 */
- { 10, 22, 12, 0, 0, -122, 0, }, /* 551 */
- { 10, 18, 12, 0, 0, -122, 0, }, /* 552 */
- { 10, 26, 12, 0, 0, -116, 0, }, /* 553 */
- { 10, 17, 12, 0, 0, -116, 0, }, /* 554 */
- { 10, 22, 12, 0, 0, -116, 0, }, /* 555 */
- { 10, 18, 12, 0, 0, -116, 0, }, /* 556 */
- { 28, 12, 3, 0, 0, -19, 0, }, /* 557 */
- { 24, 10, 3, 0, 0, 24, 0, }, /* 558 */
- { 10, 17, 14, 0, 0, -116, 0, }, /* 559 */
- { 10, 6, 12, 0, 0, -58, 0, }, /* 560 */
- { 10, 7, 12, 0, 0, -88, 0, }, /* 561 */
- { 10, 21, 14, 0, 0, -88, 0, }, /* 562 */
- { 10, 26, 12, 0, 0, 23, 0, }, /* 563 */
- { 27, 7, 12, 0, 0, 27, 0, }, /* 564 */
- { 28, 12, 3, 0, 0, -58, 0, }, /* 565 */
- { 10, 24, 12, 0, 0, -58, 0, }, /* 566 */
- { 27, 6, 12, 0, 0, 27, 0, }, /* 567 */
- { 10, 17, 12, 0, 0, -58, 0, }, /* 568 */
- { 30, 7, 12, 0, 0, 30, 0, }, /* 569 */
- { 30, 6, 12, 0, 0, 30, 0, }, /* 570 */
- { 4, 7, 12, 0, 0, 4, 0, }, /* 571 */
- { 24, 7, 12, 0, 0, 24, 0, }, /* 572 */
- { 10, 15, 12, 0, 0, 23, 0, }, /* 573 */
- { 24, 26, 12, 0, 0, 24, 0, }, /* 574 */
- { 10, 26, 14, 0, 0, 23, 0, }, /* 575 */
- { 30, 26, 12, 0, 0, 30, 0, }, /* 576 */
- { 23, 7, 12, 0, 0, 23, 0, }, /* 577 */
- { 61, 7, 12, 0, 0, 61, 0, }, /* 578 */
- { 61, 6, 12, 0, 0, 61, 0, }, /* 579 */
- { 61, 26, 12, 0, 0, 61, 0, }, /* 580 */
- { 86, 7, 12, 0, 0, 86, 0, }, /* 581 */
- { 86, 6, 12, 0, 0, 86, 0, }, /* 582 */
- { 86, 21, 12, 0, 0, 86, 0, }, /* 583 */
- { 77, 7, 12, 0, 0, 77, 0, }, /* 584 */
- { 77, 6, 12, 0, 0, 77, 0, }, /* 585 */
- { 77, 21, 12, 0, 0, 77, 0, }, /* 586 */
- { 77, 13, 12, 0, 0, 77, 0, }, /* 587 */
- { 13, 9, 12, 108, 1, 13, 0, }, /* 588 */
- { 13, 5, 12, 108, -35267, 13, 0, }, /* 589 */
- { 13, 7, 12, 0, 0, 13, 0, }, /* 590 */
- { 13, 21, 12, 0, 0, 13, 0, }, /* 591 */
- { 79, 7, 12, 0, 0, 79, 0, }, /* 592 */
- { 79, 14, 12, 0, 0, 79, 0, }, /* 593 */
- { 79, 12, 3, 0, 0, 79, 0, }, /* 594 */
- { 79, 21, 12, 0, 0, 79, 0, }, /* 595 */
- { 34, 9, 12, 0, -35332, 34, 0, }, /* 596 */
- { 34, 9, 12, 0, -42280, 34, 0, }, /* 597 */
- { 34, 9, 12, 0, -42308, 34, 0, }, /* 598 */
- { 34, 9, 12, 0, -42319, 34, 0, }, /* 599 */
- { 34, 9, 12, 0, -42315, 34, 0, }, /* 600 */
- { 34, 9, 12, 0, -42305, 34, 0, }, /* 601 */
- { 34, 9, 12, 0, -42258, 34, 0, }, /* 602 */
- { 34, 9, 12, 0, -42282, 34, 0, }, /* 603 */
- { 34, 9, 12, 0, -42261, 34, 0, }, /* 604 */
- { 34, 9, 12, 0, 928, 34, 0, }, /* 605 */
- { 49, 7, 12, 0, 0, 49, 0, }, /* 606 */
- { 49, 12, 3, 0, 0, 49, 0, }, /* 607 */
- { 49, 10, 5, 0, 0, 49, 0, }, /* 608 */
- { 49, 26, 12, 0, 0, 49, 0, }, /* 609 */
- { 10, 15, 12, 0, 0, -197, 0, }, /* 610 */
- { 10, 15, 12, 0, 0, -170, 0, }, /* 611 */
- { 10, 26, 12, 0, 0, -145, 0, }, /* 612 */
- { 10, 23, 12, 0, 0, -145, 0, }, /* 613 */
- { 65, 7, 12, 0, 0, 65, 0, }, /* 614 */
- { 65, 21, 12, 0, 0, 65, 0, }, /* 615 */
- { 75, 10, 5, 0, 0, 75, 0, }, /* 616 */
- { 75, 7, 12, 0, 0, 75, 0, }, /* 617 */
- { 75, 12, 3, 0, 0, 75, 0, }, /* 618 */
- { 75, 21, 12, 0, 0, 75, 0, }, /* 619 */
- { 75, 13, 12, 0, 0, 75, 0, }, /* 620 */
- { 15, 12, 3, 0, 0, -16, 0, }, /* 621 */
- { 15, 7, 12, 0, 0, -43, 0, }, /* 622 */
- { 69, 13, 12, 0, 0, 69, 0, }, /* 623 */
- { 69, 7, 12, 0, 0, 69, 0, }, /* 624 */
- { 69, 12, 3, 0, 0, 69, 0, }, /* 625 */
- { 10, 21, 12, 0, 0, -92, 0, }, /* 626 */
- { 69, 21, 12, 0, 0, 69, 0, }, /* 627 */
- { 74, 7, 12, 0, 0, 74, 0, }, /* 628 */
- { 74, 12, 3, 0, 0, 74, 0, }, /* 629 */
- { 74, 10, 5, 0, 0, 74, 0, }, /* 630 */
- { 74, 21, 12, 0, 0, 74, 0, }, /* 631 */
- { 84, 12, 3, 0, 0, 84, 0, }, /* 632 */
- { 84, 10, 5, 0, 0, 84, 0, }, /* 633 */
- { 84, 7, 12, 0, 0, 84, 0, }, /* 634 */
- { 84, 21, 12, 0, 0, 84, 0, }, /* 635 */
- { 10, 6, 12, 0, 0, -22, 0, }, /* 636 */
- { 84, 13, 12, 0, 0, 84, 0, }, /* 637 */
- { 39, 6, 12, 0, 0, 39, 0, }, /* 638 */
- { 68, 7, 12, 0, 0, 68, 0, }, /* 639 */
- { 68, 12, 3, 0, 0, 68, 0, }, /* 640 */
- { 68, 10, 5, 0, 0, 68, 0, }, /* 641 */
- { 68, 13, 12, 0, 0, 68, 0, }, /* 642 */
- { 68, 21, 12, 0, 0, 68, 0, }, /* 643 */
- { 92, 7, 12, 0, 0, 92, 0, }, /* 644 */
- { 92, 12, 3, 0, 0, 92, 0, }, /* 645 */
- { 92, 6, 12, 0, 0, 92, 0, }, /* 646 */
- { 92, 21, 12, 0, 0, 92, 0, }, /* 647 */
- { 87, 7, 12, 0, 0, 87, 0, }, /* 648 */
- { 87, 10, 5, 0, 0, 87, 0, }, /* 649 */
- { 87, 12, 3, 0, 0, 87, 0, }, /* 650 */
- { 87, 21, 12, 0, 0, 87, 0, }, /* 651 */
- { 87, 6, 12, 0, 0, 87, 0, }, /* 652 */
- { 34, 5, 12, 0, -928, 34, 0, }, /* 653 */
- { 9, 5, 12, 0, -38864, 9, 0, }, /* 654 */
- { 87, 13, 12, 0, 0, 87, 0, }, /* 655 */
- { 24, 7, 9, 0, 0, 24, 0, }, /* 656 */
- { 24, 7, 10, 0, 0, 24, 0, }, /* 657 */
- { 0, 4, 2, 0, 0, 0, 0, }, /* 658 */
- { 0, 3, 12, 0, 0, 0, 0, }, /* 659 */
- { 26, 25, 12, 0, 0, 26, 0, }, /* 660 */
- { 1, 24, 12, 0, 0, 1, 0, }, /* 661 */
- { 1, 7, 12, 0, 0, -10, 0, }, /* 662 */
- { 1, 26, 12, 0, 0, -10, 0, }, /* 663 */
- { 10, 6, 3, 0, 0, -58, 0, }, /* 664 */
- { 36, 7, 12, 0, 0, 36, 0, }, /* 665 */
- { 10, 21, 12, 0, 0, -25, 0, }, /* 666 */
- { 10, 15, 12, 0, 0, -76, 0, }, /* 667 */
- { 10, 26, 12, 0, 0, -25, 0, }, /* 668 */
- { 20, 14, 12, 0, 0, 20, 0, }, /* 669 */
- { 20, 15, 12, 0, 0, 20, 0, }, /* 670 */
- { 20, 26, 12, 0, 0, 20, 0, }, /* 671 */
- { 71, 7, 12, 0, 0, 71, 0, }, /* 672 */
- { 67, 7, 12, 0, 0, 67, 0, }, /* 673 */
- { 28, 12, 3, 0, 0, -1, 0, }, /* 674 */
- { 10, 15, 12, 0, 0, -1, 0, }, /* 675 */
- { 42, 7, 12, 0, 0, 42, 0, }, /* 676 */
- { 42, 15, 12, 0, 0, 42, 0, }, /* 677 */
- { 19, 7, 12, 0, 0, 19, 0, }, /* 678 */
- { 19, 14, 12, 0, 0, 19, 0, }, /* 679 */
- { 118, 7, 12, 0, 0, 118, 0, }, /* 680 */
- { 118, 12, 3, 0, 0, 118, 0, }, /* 681 */
- { 60, 7, 12, 0, 0, 60, 0, }, /* 682 */
- { 60, 21, 12, 0, 0, 60, 0, }, /* 683 */
- { 43, 7, 12, 0, 0, 43, 0, }, /* 684 */
- { 43, 21, 12, 0, 0, 43, 0, }, /* 685 */
- { 43, 14, 12, 0, 0, 43, 0, }, /* 686 */
- { 14, 9, 12, 0, 40, 14, 0, }, /* 687 */
- { 14, 5, 12, 0, -40, 14, 0, }, /* 688 */
- { 47, 7, 12, 0, 0, 47, 0, }, /* 689 */
- { 45, 7, 12, 0, 0, 45, 0, }, /* 690 */
- { 45, 13, 12, 0, 0, 45, 0, }, /* 691 */
- { 136, 9, 12, 0, 40, 136, 0, }, /* 692 */
- { 136, 5, 12, 0, -40, 136, 0, }, /* 693 */
- { 106, 7, 12, 0, 0, 106, 0, }, /* 694 */
- { 104, 7, 12, 0, 0, 104, 0, }, /* 695 */
- { 104, 21, 12, 0, 0, 104, 0, }, /* 696 */
- { 110, 7, 12, 0, 0, 110, 0, }, /* 697 */
- { 12, 7, 12, 0, 0, 12, 0, }, /* 698 */
- { 81, 7, 12, 0, 0, 81, 0, }, /* 699 */
- { 81, 21, 12, 0, 0, 81, 0, }, /* 700 */
- { 81, 15, 12, 0, 0, 81, 0, }, /* 701 */
- { 120, 7, 12, 0, 0, 120, 0, }, /* 702 */
- { 120, 26, 12, 0, 0, 120, 0, }, /* 703 */
- { 120, 15, 12, 0, 0, 120, 0, }, /* 704 */
- { 116, 7, 12, 0, 0, 116, 0, }, /* 705 */
- { 116, 15, 12, 0, 0, 116, 0, }, /* 706 */
- { 128, 7, 12, 0, 0, 128, 0, }, /* 707 */
- { 128, 15, 12, 0, 0, 128, 0, }, /* 708 */
- { 66, 7, 12, 0, 0, 66, 0, }, /* 709 */
- { 66, 15, 12, 0, 0, 66, 0, }, /* 710 */
- { 66, 21, 12, 0, 0, 66, 0, }, /* 711 */
- { 72, 7, 12, 0, 0, 72, 0, }, /* 712 */
- { 72, 21, 12, 0, 0, 72, 0, }, /* 713 */
- { 98, 7, 12, 0, 0, 98, 0, }, /* 714 */
- { 97, 7, 12, 0, 0, 97, 0, }, /* 715 */
- { 97, 15, 12, 0, 0, 97, 0, }, /* 716 */
- { 31, 7, 12, 0, 0, 31, 0, }, /* 717 */
- { 31, 12, 3, 0, 0, 31, 0, }, /* 718 */
- { 31, 15, 12, 0, 0, 31, 0, }, /* 719 */
- { 31, 21, 12, 0, 0, 31, 0, }, /* 720 */
- { 88, 7, 12, 0, 0, 88, 0, }, /* 721 */
- { 88, 15, 12, 0, 0, 88, 0, }, /* 722 */
- { 88, 21, 12, 0, 0, 88, 0, }, /* 723 */
- { 117, 7, 12, 0, 0, 117, 0, }, /* 724 */
- { 117, 15, 12, 0, 0, 117, 0, }, /* 725 */
- { 112, 7, 12, 0, 0, 112, 0, }, /* 726 */
- { 112, 26, 12, 0, 0, 112, 0, }, /* 727 */
- { 112, 12, 3, 0, 0, 112, 0, }, /* 728 */
- { 112, 15, 12, 0, 0, 112, 0, }, /* 729 */
- { 112, 21, 12, 0, 0, 112, 0, }, /* 730 */
- { 78, 7, 12, 0, 0, 78, 0, }, /* 731 */
- { 78, 21, 12, 0, 0, 78, 0, }, /* 732 */
- { 83, 7, 12, 0, 0, 83, 0, }, /* 733 */
- { 83, 15, 12, 0, 0, 83, 0, }, /* 734 */
- { 82, 7, 12, 0, 0, 82, 0, }, /* 735 */
- { 82, 15, 12, 0, 0, 82, 0, }, /* 736 */
- { 121, 7, 12, 0, 0, 121, 0, }, /* 737 */
- { 121, 21, 12, 0, 0, 121, 0, }, /* 738 */
- { 121, 15, 12, 0, 0, 121, 0, }, /* 739 */
- { 89, 7, 12, 0, 0, 89, 0, }, /* 740 */
- { 130, 9, 12, 0, 64, 130, 0, }, /* 741 */
- { 130, 5, 12, 0, -64, 130, 0, }, /* 742 */
- { 130, 15, 12, 0, 0, 130, 0, }, /* 743 */
- { 144, 7, 12, 0, 0, 144, 0, }, /* 744 */
- { 144, 12, 3, 0, 0, 144, 0, }, /* 745 */
- { 144, 13, 12, 0, 0, 144, 0, }, /* 746 */
- { 1, 15, 12, 0, 0, 1, 0, }, /* 747 */
- { 147, 7, 12, 0, 0, 147, 0, }, /* 748 */
- { 147, 15, 12, 0, 0, 147, 0, }, /* 749 */
- { 148, 7, 12, 0, 0, 148, 0, }, /* 750 */
- { 148, 12, 3, 0, 0, 148, 0, }, /* 751 */
- { 148, 15, 12, 0, 0, 148, 0, }, /* 752 */
- { 148, 21, 12, 0, 0, 148, 0, }, /* 753 */
- { 94, 10, 5, 0, 0, 94, 0, }, /* 754 */
- { 94, 12, 3, 0, 0, 94, 0, }, /* 755 */
- { 94, 7, 12, 0, 0, 94, 0, }, /* 756 */
- { 94, 21, 12, 0, 0, 94, 0, }, /* 757 */
- { 94, 15, 12, 0, 0, 94, 0, }, /* 758 */
- { 94, 13, 12, 0, 0, 94, 0, }, /* 759 */
- { 85, 12, 3, 0, 0, 85, 0, }, /* 760 */
- { 85, 10, 5, 0, 0, 85, 0, }, /* 761 */
- { 85, 7, 12, 0, 0, 85, 0, }, /* 762 */
- { 85, 21, 12, 0, 0, 85, 0, }, /* 763 */
- { 85, 1, 4, 0, 0, 85, 0, }, /* 764 */
- { 101, 7, 12, 0, 0, 101, 0, }, /* 765 */
- { 101, 13, 12, 0, 0, 101, 0, }, /* 766 */
- { 96, 12, 3, 0, 0, 96, 0, }, /* 767 */
- { 96, 7, 12, 0, 0, 96, 0, }, /* 768 */
- { 96, 10, 5, 0, 0, 96, 0, }, /* 769 */
- { 96, 13, 12, 0, 0, 96, 0, }, /* 770 */
- { 96, 21, 12, 0, 0, 96, 0, }, /* 771 */
- { 111, 7, 12, 0, 0, 111, 0, }, /* 772 */
- { 111, 12, 3, 0, 0, 111, 0, }, /* 773 */
- { 111, 21, 12, 0, 0, 111, 0, }, /* 774 */
- { 100, 12, 3, 0, 0, 100, 0, }, /* 775 */
- { 100, 10, 5, 0, 0, 100, 0, }, /* 776 */
- { 100, 7, 12, 0, 0, 100, 0, }, /* 777 */
- { 100, 7, 4, 0, 0, 100, 0, }, /* 778 */
- { 100, 21, 12, 0, 0, 100, 0, }, /* 779 */
- { 100, 13, 12, 0, 0, 100, 0, }, /* 780 */
- { 48, 15, 12, 0, 0, 48, 0, }, /* 781 */
- { 108, 7, 12, 0, 0, 108, 0, }, /* 782 */
- { 108, 10, 5, 0, 0, 108, 0, }, /* 783 */
- { 108, 12, 3, 0, 0, 108, 0, }, /* 784 */
- { 108, 21, 12, 0, 0, 108, 0, }, /* 785 */
- { 129, 7, 12, 0, 0, 129, 0, }, /* 786 */
- { 129, 21, 12, 0, 0, 129, 0, }, /* 787 */
- { 109, 7, 12, 0, 0, 109, 0, }, /* 788 */
- { 109, 12, 3, 0, 0, 109, 0, }, /* 789 */
- { 109, 10, 5, 0, 0, 109, 0, }, /* 790 */
- { 109, 13, 12, 0, 0, 109, 0, }, /* 791 */
- { 107, 12, 3, 0, 0, 107, 0, }, /* 792 */
- { 107, 12, 3, 0, 0, -49, 0, }, /* 793 */
- { 107, 10, 5, 0, 0, 107, 0, }, /* 794 */
- { 107, 10, 5, 0, 0, -49, 0, }, /* 795 */
- { 107, 7, 12, 0, 0, 107, 0, }, /* 796 */
- { 28, 12, 3, 0, 0, -49, 0, }, /* 797 */
- { 107, 10, 3, 0, 0, 107, 0, }, /* 798 */
- { 135, 7, 12, 0, 0, 135, 0, }, /* 799 */
- { 135, 10, 5, 0, 0, 135, 0, }, /* 800 */
- { 135, 12, 3, 0, 0, 135, 0, }, /* 801 */
- { 135, 21, 12, 0, 0, 135, 0, }, /* 802 */
- { 135, 13, 12, 0, 0, 135, 0, }, /* 803 */
- { 124, 7, 12, 0, 0, 124, 0, }, /* 804 */
- { 124, 10, 3, 0, 0, 124, 0, }, /* 805 */
- { 124, 10, 5, 0, 0, 124, 0, }, /* 806 */
- { 124, 12, 3, 0, 0, 124, 0, }, /* 807 */
- { 124, 21, 12, 0, 0, 124, 0, }, /* 808 */
- { 124, 13, 12, 0, 0, 124, 0, }, /* 809 */
- { 123, 7, 12, 0, 0, 123, 0, }, /* 810 */
- { 123, 10, 3, 0, 0, 123, 0, }, /* 811 */
- { 123, 10, 5, 0, 0, 123, 0, }, /* 812 */
- { 123, 12, 3, 0, 0, 123, 0, }, /* 813 */
- { 123, 21, 12, 0, 0, 123, 0, }, /* 814 */
- { 114, 7, 12, 0, 0, 114, 0, }, /* 815 */
- { 114, 10, 5, 0, 0, 114, 0, }, /* 816 */
- { 114, 12, 3, 0, 0, 114, 0, }, /* 817 */
- { 114, 21, 12, 0, 0, 114, 0, }, /* 818 */
- { 114, 13, 12, 0, 0, 114, 0, }, /* 819 */
- { 102, 7, 12, 0, 0, 102, 0, }, /* 820 */
- { 102, 12, 3, 0, 0, 102, 0, }, /* 821 */
- { 102, 10, 5, 0, 0, 102, 0, }, /* 822 */
- { 102, 13, 12, 0, 0, 102, 0, }, /* 823 */
- { 126, 7, 12, 0, 0, 126, 0, }, /* 824 */
- { 126, 12, 3, 0, 0, 126, 0, }, /* 825 */
- { 126, 10, 5, 0, 0, 126, 0, }, /* 826 */
- { 126, 13, 12, 0, 0, 126, 0, }, /* 827 */
- { 126, 15, 12, 0, 0, 126, 0, }, /* 828 */
- { 126, 21, 12, 0, 0, 126, 0, }, /* 829 */
- { 126, 26, 12, 0, 0, 126, 0, }, /* 830 */
- { 142, 7, 12, 0, 0, 142, 0, }, /* 831 */
- { 142, 10, 5, 0, 0, 142, 0, }, /* 832 */
- { 142, 12, 3, 0, 0, 142, 0, }, /* 833 */
- { 142, 21, 12, 0, 0, 142, 0, }, /* 834 */
- { 125, 9, 12, 0, 32, 125, 0, }, /* 835 */
- { 125, 5, 12, 0, -32, 125, 0, }, /* 836 */
- { 125, 13, 12, 0, 0, 125, 0, }, /* 837 */
- { 125, 15, 12, 0, 0, 125, 0, }, /* 838 */
- { 125, 7, 12, 0, 0, 125, 0, }, /* 839 */
- { 141, 7, 12, 0, 0, 141, 0, }, /* 840 */
- { 141, 12, 3, 0, 0, 141, 0, }, /* 841 */
- { 141, 10, 5, 0, 0, 141, 0, }, /* 842 */
- { 141, 7, 4, 0, 0, 141, 0, }, /* 843 */
- { 141, 21, 12, 0, 0, 141, 0, }, /* 844 */
- { 140, 7, 12, 0, 0, 140, 0, }, /* 845 */
- { 140, 12, 3, 0, 0, 140, 0, }, /* 846 */
- { 140, 10, 5, 0, 0, 140, 0, }, /* 847 */
- { 140, 7, 4, 0, 0, 140, 0, }, /* 848 */
- { 140, 21, 12, 0, 0, 140, 0, }, /* 849 */
- { 122, 7, 12, 0, 0, 122, 0, }, /* 850 */
- { 133, 7, 12, 0, 0, 133, 0, }, /* 851 */
- { 133, 10, 5, 0, 0, 133, 0, }, /* 852 */
- { 133, 12, 3, 0, 0, 133, 0, }, /* 853 */
- { 133, 21, 12, 0, 0, 133, 0, }, /* 854 */
- { 133, 13, 12, 0, 0, 133, 0, }, /* 855 */
- { 133, 15, 12, 0, 0, 133, 0, }, /* 856 */
- { 134, 21, 12, 0, 0, 134, 0, }, /* 857 */
- { 134, 7, 12, 0, 0, 134, 0, }, /* 858 */
- { 134, 12, 3, 0, 0, 134, 0, }, /* 859 */
- { 134, 10, 5, 0, 0, 134, 0, }, /* 860 */
- { 138, 7, 12, 0, 0, 138, 0, }, /* 861 */
- { 138, 12, 3, 0, 0, 138, 0, }, /* 862 */
- { 138, 7, 4, 0, 0, 138, 0, }, /* 863 */
- { 138, 13, 12, 0, 0, 138, 0, }, /* 864 */
- { 143, 7, 12, 0, 0, 143, 0, }, /* 865 */
- { 143, 10, 5, 0, 0, 143, 0, }, /* 866 */
- { 143, 12, 3, 0, 0, 143, 0, }, /* 867 */
- { 143, 13, 12, 0, 0, 143, 0, }, /* 868 */
- { 145, 7, 12, 0, 0, 145, 0, }, /* 869 */
- { 145, 12, 3, 0, 0, 145, 0, }, /* 870 */
- { 145, 10, 5, 0, 0, 145, 0, }, /* 871 */
- { 145, 21, 12, 0, 0, 145, 0, }, /* 872 */
- { 63, 7, 12, 0, 0, 63, 0, }, /* 873 */
- { 63, 14, 12, 0, 0, 63, 0, }, /* 874 */
- { 63, 21, 12, 0, 0, 63, 0, }, /* 875 */
- { 80, 7, 12, 0, 0, 80, 0, }, /* 876 */
- { 127, 7, 12, 0, 0, 127, 0, }, /* 877 */
- { 115, 7, 12, 0, 0, 115, 0, }, /* 878 */
- { 115, 13, 12, 0, 0, 115, 0, }, /* 879 */
- { 115, 21, 12, 0, 0, 115, 0, }, /* 880 */
- { 103, 7, 12, 0, 0, 103, 0, }, /* 881 */
- { 103, 12, 3, 0, 0, 103, 0, }, /* 882 */
- { 103, 21, 12, 0, 0, 103, 0, }, /* 883 */
- { 119, 7, 12, 0, 0, 119, 0, }, /* 884 */
- { 119, 12, 3, 0, 0, 119, 0, }, /* 885 */
- { 119, 21, 12, 0, 0, 119, 0, }, /* 886 */
- { 119, 26, 12, 0, 0, 119, 0, }, /* 887 */
- { 119, 6, 12, 0, 0, 119, 0, }, /* 888 */
- { 119, 13, 12, 0, 0, 119, 0, }, /* 889 */
- { 119, 15, 12, 0, 0, 119, 0, }, /* 890 */
- { 146, 9, 12, 0, 32, 146, 0, }, /* 891 */
- { 146, 5, 12, 0, -32, 146, 0, }, /* 892 */
- { 146, 15, 12, 0, 0, 146, 0, }, /* 893 */
- { 146, 21, 12, 0, 0, 146, 0, }, /* 894 */
- { 99, 7, 12, 0, 0, 99, 0, }, /* 895 */
- { 99, 10, 5, 0, 0, 99, 0, }, /* 896 */
- { 99, 12, 3, 0, 0, 99, 0, }, /* 897 */
- { 99, 6, 12, 0, 0, 99, 0, }, /* 898 */
- { 137, 6, 12, 0, 0, 137, 0, }, /* 899 */
- { 139, 6, 12, 0, 0, 139, 0, }, /* 900 */
- { 137, 7, 12, 0, 0, 137, 0, }, /* 901 */
- { 139, 7, 12, 0, 0, 139, 0, }, /* 902 */
- { 105, 7, 12, 0, 0, 105, 0, }, /* 903 */
- { 105, 26, 12, 0, 0, 105, 0, }, /* 904 */
- { 105, 12, 3, 0, 0, 105, 0, }, /* 905 */
- { 105, 21, 12, 0, 0, 105, 0, }, /* 906 */
- { 10, 1, 2, 0, 0, 105, 0, }, /* 907 */
- { 10, 10, 3, 0, 0, 10, 0, }, /* 908 */
- { 10, 10, 5, 0, 0, 10, 0, }, /* 909 */
- { 20, 12, 3, 0, 0, 20, 0, }, /* 910 */
- { 131, 26, 12, 0, 0, 131, 0, }, /* 911 */
- { 131, 12, 3, 0, 0, 131, 0, }, /* 912 */
- { 131, 21, 12, 0, 0, 131, 0, }, /* 913 */
- { 18, 12, 3, 0, 0, 18, 0, }, /* 914 */
- { 113, 7, 12, 0, 0, 113, 0, }, /* 915 */
- { 113, 15, 12, 0, 0, 113, 0, }, /* 916 */
- { 113, 12, 3, 0, 0, 113, 0, }, /* 917 */
- { 132, 9, 12, 0, 34, 132, 0, }, /* 918 */
- { 132, 5, 12, 0, -34, 132, 0, }, /* 919 */
- { 132, 12, 3, 0, 0, 132, 0, }, /* 920 */
- { 132, 13, 12, 0, 0, 132, 0, }, /* 921 */
- { 132, 21, 12, 0, 0, 132, 0, }, /* 922 */
- { 0, 2, 14, 0, 0, 0, 0, }, /* 923 */
- { 10, 26, 11, 0, 0, 10, 0, }, /* 924 */
- { 27, 26, 12, 0, 0, 27, 0, }, /* 925 */
- { 10, 24, 3, 0, 0, 10, 0, }, /* 926 */
- { 10, 1, 3, 0, 0, 10, 0, }, /* 927 */
+ { 34, 5, 12, 0, 42307, 34, 0, }, /* 102 */
+ { 34, 5, 12, 0, 42282, 34, 0, }, /* 103 */
+ { 34, 5, 12, 0, -69, 34, 0, }, /* 104 */
+ { 34, 5, 12, 0, -217, 34, 0, }, /* 105 */
+ { 34, 5, 12, 0, -71, 34, 0, }, /* 106 */
+ { 34, 5, 12, 0, -219, 34, 0, }, /* 107 */
+ { 34, 5, 12, 0, 42261, 34, 0, }, /* 108 */
+ { 34, 5, 12, 0, 42258, 34, 0, }, /* 109 */
+ { 34, 6, 12, 0, 0, 34, 0, }, /* 110 */
+ { 10, 6, 12, 0, 0, 10, 0, }, /* 111 */
+ { 4, 24, 12, 0, 0, 4, 0, }, /* 112 */
+ { 28, 12, 3, 0, 0, 28, 0, }, /* 113 */
+ { 28, 12, 3, 0, 0, 20, 0, }, /* 114 */
+ { 28, 12, 3, 21, 116, 20, 0, }, /* 115 */
+ { 28, 12, 3, 0, 0, 34, 0, }, /* 116 */
+ { 20, 9, 12, 0, 1, 20, 0, }, /* 117 */
+ { 20, 5, 12, 0, -1, 20, 0, }, /* 118 */
+ { 20, 24, 12, 0, 0, 20, 0, }, /* 119 */
+ { 0, 2, 12, 0, 0, 0, 0, }, /* 120 */
+ { 20, 6, 12, 0, 0, 20, 0, }, /* 121 */
+ { 20, 5, 12, 0, 130, 20, 0, }, /* 122 */
+ { 20, 9, 12, 0, 116, 20, 0, }, /* 123 */
+ { 20, 9, 12, 0, 38, 20, 0, }, /* 124 */
+ { 20, 9, 12, 0, 37, 20, 0, }, /* 125 */
+ { 20, 9, 12, 0, 64, 20, 0, }, /* 126 */
+ { 20, 9, 12, 0, 63, 20, 0, }, /* 127 */
+ { 20, 5, 12, 0, 0, 20, 0, }, /* 128 */
+ { 20, 9, 12, 0, 32, 20, 0, }, /* 129 */
+ { 20, 9, 12, 34, 32, 20, 0, }, /* 130 */
+ { 20, 9, 12, 59, 32, 20, 0, }, /* 131 */
+ { 20, 9, 12, 38, 32, 20, 0, }, /* 132 */
+ { 20, 9, 12, 21, 32, 20, 0, }, /* 133 */
+ { 20, 9, 12, 51, 32, 20, 0, }, /* 134 */
+ { 20, 9, 12, 26, 32, 20, 0, }, /* 135 */
+ { 20, 9, 12, 47, 32, 20, 0, }, /* 136 */
+ { 20, 9, 12, 55, 32, 20, 0, }, /* 137 */
+ { 20, 9, 12, 30, 32, 20, 0, }, /* 138 */
+ { 20, 9, 12, 43, 32, 20, 0, }, /* 139 */
+ { 20, 9, 12, 96, 32, 20, 0, }, /* 140 */
+ { 20, 5, 12, 0, -38, 20, 0, }, /* 141 */
+ { 20, 5, 12, 0, -37, 20, 0, }, /* 142 */
+ { 20, 5, 12, 0, -32, 20, 0, }, /* 143 */
+ { 20, 5, 12, 34, -32, 20, 0, }, /* 144 */
+ { 20, 5, 12, 59, -32, 20, 0, }, /* 145 */
+ { 20, 5, 12, 38, -32, 20, 0, }, /* 146 */
+ { 20, 5, 12, 21, -116, 20, 0, }, /* 147 */
+ { 20, 5, 12, 51, -32, 20, 0, }, /* 148 */
+ { 20, 5, 12, 26, -775, 20, 0, }, /* 149 */
+ { 20, 5, 12, 47, -32, 20, 0, }, /* 150 */
+ { 20, 5, 12, 55, -32, 20, 0, }, /* 151 */
+ { 20, 5, 12, 30, 1, 20, 0, }, /* 152 */
+ { 20, 5, 12, 30, -32, 20, 0, }, /* 153 */
+ { 20, 5, 12, 43, -32, 20, 0, }, /* 154 */
+ { 20, 5, 12, 96, -32, 20, 0, }, /* 155 */
+ { 20, 5, 12, 0, -64, 20, 0, }, /* 156 */
+ { 20, 5, 12, 0, -63, 20, 0, }, /* 157 */
+ { 20, 9, 12, 0, 8, 20, 0, }, /* 158 */
+ { 20, 5, 12, 34, -30, 20, 0, }, /* 159 */
+ { 20, 5, 12, 38, -25, 20, 0, }, /* 160 */
+ { 20, 9, 12, 0, 0, 20, 0, }, /* 161 */
+ { 20, 5, 12, 43, -15, 20, 0, }, /* 162 */
+ { 20, 5, 12, 47, -22, 20, 0, }, /* 163 */
+ { 20, 5, 12, 0, -8, 20, 0, }, /* 164 */
+ { 11, 9, 12, 0, 1, 11, 0, }, /* 165 */
+ { 11, 5, 12, 0, -1, 11, 0, }, /* 166 */
+ { 20, 5, 12, 51, -54, 20, 0, }, /* 167 */
+ { 20, 5, 12, 55, -48, 20, 0, }, /* 168 */
+ { 20, 5, 12, 0, 7, 20, 0, }, /* 169 */
+ { 20, 5, 12, 0, -116, 20, 0, }, /* 170 */
+ { 20, 9, 12, 38, -60, 20, 0, }, /* 171 */
+ { 20, 5, 12, 59, -64, 20, 0, }, /* 172 */
+ { 20, 25, 12, 0, 0, 20, 0, }, /* 173 */
+ { 20, 9, 12, 0, -7, 20, 0, }, /* 174 */
+ { 20, 9, 12, 0, -130, 20, 0, }, /* 175 */
+ { 13, 9, 12, 0, 80, 13, 0, }, /* 176 */
+ { 13, 9, 12, 0, 32, 13, 0, }, /* 177 */
+ { 13, 9, 12, 63, 32, 13, 0, }, /* 178 */
+ { 13, 9, 12, 67, 32, 13, 0, }, /* 179 */
+ { 13, 9, 12, 71, 32, 13, 0, }, /* 180 */
+ { 13, 9, 12, 75, 32, 13, 0, }, /* 181 */
+ { 13, 9, 12, 79, 32, 13, 0, }, /* 182 */
+ { 13, 9, 12, 84, 32, 13, 0, }, /* 183 */
+ { 13, 5, 12, 0, -32, 13, 0, }, /* 184 */
+ { 13, 5, 12, 63, -32, 13, 0, }, /* 185 */
+ { 13, 5, 12, 67, -32, 13, 0, }, /* 186 */
+ { 13, 5, 12, 71, -32, 13, 0, }, /* 187 */
+ { 13, 5, 12, 75, -32, 13, 0, }, /* 188 */
+ { 13, 5, 12, 79, -32, 13, 0, }, /* 189 */
+ { 13, 5, 12, 84, -32, 13, 0, }, /* 190 */
+ { 13, 5, 12, 0, -80, 13, 0, }, /* 191 */
+ { 13, 9, 12, 0, 1, 13, 0, }, /* 192 */
+ { 13, 5, 12, 0, -1, 13, 0, }, /* 193 */
+ { 13, 9, 12, 88, 1, 13, 0, }, /* 194 */
+ { 13, 5, 12, 88, -1, 13, 0, }, /* 195 */
+ { 13, 26, 12, 0, 0, 13, 0, }, /* 196 */
+ { 13, 12, 3, 0, 0, -34, 0, }, /* 197 */
+ { 13, 12, 3, 0, 0, -28, 0, }, /* 198 */
+ { 28, 12, 3, 0, 0, -31, 0, }, /* 199 */
+ { 13, 11, 3, 0, 0, 13, 0, }, /* 200 */
+ { 13, 9, 12, 0, 15, 13, 0, }, /* 201 */
+ { 13, 5, 12, 0, -15, 13, 0, }, /* 202 */
+ { 2, 9, 12, 0, 48, 2, 0, }, /* 203 */
+ { 2, 6, 12, 0, 0, 2, 0, }, /* 204 */
+ { 2, 21, 12, 0, 0, 2, 0, }, /* 205 */
+ { 2, 5, 12, 0, 0, 2, 0, }, /* 206 */
+ { 2, 5, 12, 0, -48, 2, 0, }, /* 207 */
+ { 10, 21, 12, 0, 0, -13, 0, }, /* 208 */
+ { 2, 17, 12, 0, 0, 2, 0, }, /* 209 */
+ { 2, 26, 12, 0, 0, 2, 0, }, /* 210 */
+ { 2, 23, 12, 0, 0, 2, 0, }, /* 211 */
+ { 26, 12, 3, 0, 0, 26, 0, }, /* 212 */
+ { 26, 17, 12, 0, 0, 26, 0, }, /* 213 */
+ { 26, 21, 12, 0, 0, 26, 0, }, /* 214 */
+ { 26, 7, 12, 0, 0, 26, 0, }, /* 215 */
+ { 1, 1, 4, 0, 0, 1, 0, }, /* 216 */
+ { 10, 1, 4, 0, 0, 10, 0, }, /* 217 */
+ { 1, 25, 12, 0, 0, 1, 0, }, /* 218 */
+ { 1, 21, 12, 0, 0, 1, 0, }, /* 219 */
+ { 1, 23, 12, 0, 0, 1, 0, }, /* 220 */
+ { 10, 21, 12, 0, 0, -105, 0, }, /* 221 */
+ { 1, 26, 12, 0, 0, 1, 0, }, /* 222 */
+ { 1, 12, 3, 0, 0, 1, 0, }, /* 223 */
+ { 1, 1, 2, 0, 0, -73, 0, }, /* 224 */
+ { 1, 7, 12, 0, 0, 1, 0, }, /* 225 */
+ { 10, 6, 12, 0, 0, -145, 0, }, /* 226 */
+ { 28, 12, 3, 0, 0, -7, 0, }, /* 227 */
+ { 1, 13, 12, 0, 0, -10, 0, }, /* 228 */
+ { 1, 21, 12, 0, 0, -4, 0, }, /* 229 */
+ { 1, 6, 12, 0, 0, 1, 0, }, /* 230 */
+ { 1, 13, 12, 0, 0, 1, 0, }, /* 231 */
+ { 50, 21, 12, 0, 0, 50, 0, }, /* 232 */
+ { 50, 1, 4, 0, 0, 50, 0, }, /* 233 */
+ { 50, 7, 12, 0, 0, 50, 0, }, /* 234 */
+ { 50, 12, 3, 0, 0, 50, 0, }, /* 235 */
+ { 56, 7, 12, 0, 0, 56, 0, }, /* 236 */
+ { 56, 12, 3, 0, 0, 56, 0, }, /* 237 */
+ { 64, 13, 12, 0, 0, 64, 0, }, /* 238 */
+ { 64, 7, 12, 0, 0, 64, 0, }, /* 239 */
+ { 64, 12, 3, 0, 0, 64, 0, }, /* 240 */
+ { 64, 6, 12, 0, 0, 64, 0, }, /* 241 */
+ { 64, 26, 12, 0, 0, 64, 0, }, /* 242 */
+ { 64, 21, 12, 0, 0, 64, 0, }, /* 243 */
+ { 64, 23, 12, 0, 0, 64, 0, }, /* 244 */
+ { 90, 7, 12, 0, 0, 90, 0, }, /* 245 */
+ { 90, 12, 3, 0, 0, 90, 0, }, /* 246 */
+ { 90, 6, 12, 0, 0, 90, 0, }, /* 247 */
+ { 90, 21, 12, 0, 0, 90, 0, }, /* 248 */
+ { 95, 7, 12, 0, 0, 95, 0, }, /* 249 */
+ { 95, 12, 3, 0, 0, 95, 0, }, /* 250 */
+ { 95, 21, 12, 0, 0, 95, 0, }, /* 251 */
+ { 15, 12, 3, 0, 0, 15, 0, }, /* 252 */
+ { 15, 10, 5, 0, 0, 15, 0, }, /* 253 */
+ { 15, 7, 12, 0, 0, 15, 0, }, /* 254 */
+ { 28, 12, 3, 0, 0, -188, 0, }, /* 255 */
+ { 28, 12, 3, 0, 0, -175, 0, }, /* 256 */
+ { 10, 21, 12, 0, 0, -231, 0, }, /* 257 */
+ { 10, 21, 12, 0, 0, -252, 0, }, /* 258 */
+ { 15, 13, 12, 0, 0, -120, 0, }, /* 259 */
+ { 15, 21, 12, 0, 0, 15, 0, }, /* 260 */
+ { 15, 6, 12, 0, 0, 15, 0, }, /* 261 */
+ { 3, 7, 12, 0, 0, 3, 0, }, /* 262 */
+ { 3, 12, 3, 0, 0, 3, 0, }, /* 263 */
+ { 3, 10, 5, 0, 0, 3, 0, }, /* 264 */
+ { 3, 10, 3, 0, 0, 3, 0, }, /* 265 */
+ { 3, 13, 12, 0, 0, -77, 0, }, /* 266 */
+ { 3, 23, 12, 0, 0, 3, 0, }, /* 267 */
+ { 3, 15, 12, 0, 0, 3, 0, }, /* 268 */
+ { 3, 26, 12, 0, 0, 3, 0, }, /* 269 */
+ { 3, 21, 12, 0, 0, 3, 0, }, /* 270 */
+ { 22, 12, 3, 0, 0, 22, 0, }, /* 271 */
+ { 22, 10, 5, 0, 0, 22, 0, }, /* 272 */
+ { 22, 7, 12, 0, 0, 22, 0, }, /* 273 */
+ { 22, 13, 12, 0, 0, -58, 0, }, /* 274 */
+ { 22, 21, 12, 0, 0, 22, 0, }, /* 275 */
+ { 21, 12, 3, 0, 0, 21, 0, }, /* 276 */
+ { 21, 10, 5, 0, 0, 21, 0, }, /* 277 */
+ { 21, 7, 12, 0, 0, 21, 0, }, /* 278 */
+ { 21, 13, 12, 0, 0, -55, 0, }, /* 279 */
+ { 21, 21, 12, 0, 0, 21, 0, }, /* 280 */
+ { 21, 23, 12, 0, 0, 21, 0, }, /* 281 */
+ { 44, 12, 3, 0, 0, 44, 0, }, /* 282 */
+ { 44, 10, 5, 0, 0, 44, 0, }, /* 283 */
+ { 44, 7, 12, 0, 0, 44, 0, }, /* 284 */
+ { 44, 10, 3, 0, 0, 44, 0, }, /* 285 */
+ { 44, 13, 12, 0, 0, 44, 0, }, /* 286 */
+ { 44, 26, 12, 0, 0, 44, 0, }, /* 287 */
+ { 44, 15, 12, 0, 0, 44, 0, }, /* 288 */
+ { 54, 12, 3, 0, 0, 54, 0, }, /* 289 */
+ { 54, 7, 12, 0, 0, 54, 0, }, /* 290 */
+ { 54, 10, 3, 0, 0, 54, 0, }, /* 291 */
+ { 54, 10, 5, 0, 0, 54, 0, }, /* 292 */
+ { 54, 13, 12, 0, 0, -52, 0, }, /* 293 */
+ { 54, 15, 12, 0, 0, -52, 0, }, /* 294 */
+ { 54, 26, 12, 0, 0, -52, 0, }, /* 295 */
+ { 54, 26, 12, 0, 0, 54, 0, }, /* 296 */
+ { 54, 23, 12, 0, 0, 54, 0, }, /* 297 */
+ { 55, 12, 3, 0, 0, 55, 0, }, /* 298 */
+ { 55, 10, 5, 0, 0, 55, 0, }, /* 299 */
+ { 55, 7, 12, 0, 0, 55, 0, }, /* 300 */
+ { 55, 13, 12, 0, 0, 55, 0, }, /* 301 */
+ { 55, 21, 12, 0, 0, 55, 0, }, /* 302 */
+ { 55, 15, 12, 0, 0, 55, 0, }, /* 303 */
+ { 55, 26, 12, 0, 0, 55, 0, }, /* 304 */
+ { 29, 7, 12, 0, 0, 29, 0, }, /* 305 */
+ { 29, 12, 3, 0, 0, 29, 0, }, /* 306 */
+ { 29, 10, 5, 0, 0, 29, 0, }, /* 307 */
+ { 29, 21, 12, 0, 0, 29, 0, }, /* 308 */
+ { 29, 10, 3, 0, 0, 29, 0, }, /* 309 */
+ { 29, 13, 12, 0, 0, -64, 0, }, /* 310 */
+ { 37, 12, 3, 0, 0, 37, 0, }, /* 311 */
+ { 37, 10, 5, 0, 0, 37, 0, }, /* 312 */
+ { 37, 7, 12, 0, 0, 37, 0, }, /* 313 */
+ { 37, 10, 3, 0, 0, 37, 0, }, /* 314 */
+ { 37, 7, 4, 0, 0, 37, 0, }, /* 315 */
+ { 37, 26, 12, 0, 0, 37, 0, }, /* 316 */
+ { 37, 15, 12, 0, 0, 37, 0, }, /* 317 */
+ { 37, 13, 12, 0, 0, 37, 0, }, /* 318 */
+ { 48, 10, 5, 0, 0, 48, 0, }, /* 319 */
+ { 48, 7, 12, 0, 0, 48, 0, }, /* 320 */
+ { 48, 12, 3, 0, 0, 48, 0, }, /* 321 */
+ { 48, 10, 3, 0, 0, 48, 0, }, /* 322 */
+ { 48, 13, 12, 0, 0, 48, 0, }, /* 323 */
+ { 48, 21, 12, 0, 0, 48, 0, }, /* 324 */
+ { 57, 7, 12, 0, 0, 57, 0, }, /* 325 */
+ { 57, 12, 3, 0, 0, 57, 0, }, /* 326 */
+ { 57, 7, 5, 0, 0, 57, 0, }, /* 327 */
+ { 57, 6, 12, 0, 0, 57, 0, }, /* 328 */
+ { 57, 21, 12, 0, 0, 57, 0, }, /* 329 */
+ { 57, 13, 12, 0, 0, 57, 0, }, /* 330 */
+ { 33, 7, 12, 0, 0, 33, 0, }, /* 331 */
+ { 33, 12, 3, 0, 0, 33, 0, }, /* 332 */
+ { 33, 7, 5, 0, 0, 33, 0, }, /* 333 */
+ { 33, 6, 12, 0, 0, 33, 0, }, /* 334 */
+ { 33, 13, 12, 0, 0, 33, 0, }, /* 335 */
+ { 58, 7, 12, 0, 0, 58, 0, }, /* 336 */
+ { 58, 26, 12, 0, 0, 58, 0, }, /* 337 */
+ { 58, 21, 12, 0, 0, 58, 0, }, /* 338 */
+ { 58, 12, 3, 0, 0, 58, 0, }, /* 339 */
+ { 58, 13, 12, 0, 0, 58, 0, }, /* 340 */
+ { 58, 15, 12, 0, 0, 58, 0, }, /* 341 */
+ { 58, 22, 12, 0, 0, 58, 0, }, /* 342 */
+ { 58, 18, 12, 0, 0, 58, 0, }, /* 343 */
+ { 58, 10, 5, 0, 0, 58, 0, }, /* 344 */
+ { 39, 7, 12, 0, 0, 39, 0, }, /* 345 */
+ { 39, 10, 12, 0, 0, 39, 0, }, /* 346 */
+ { 39, 12, 3, 0, 0, 39, 0, }, /* 347 */
+ { 39, 10, 5, 0, 0, 39, 0, }, /* 348 */
+ { 39, 13, 12, 0, 0, -81, 0, }, /* 349 */
+ { 39, 21, 12, 0, 0, 39, 0, }, /* 350 */
+ { 39, 13, 12, 0, 0, 39, 0, }, /* 351 */
+ { 39, 26, 12, 0, 0, 39, 0, }, /* 352 */
+ { 17, 9, 12, 0, 7264, 17, 0, }, /* 353 */
+ { 17, 5, 12, 0, 3008, 17, 0, }, /* 354 */
+ { 10, 21, 12, 0, 0, -49, 0, }, /* 355 */
+ { 17, 6, 12, 0, 0, 17, 0, }, /* 356 */
+ { 24, 7, 6, 0, 0, 24, 0, }, /* 357 */
+ { 24, 7, 7, 0, 0, 24, 0, }, /* 358 */
+ { 24, 7, 8, 0, 0, 24, 0, }, /* 359 */
+ { 16, 7, 12, 0, 0, 16, 0, }, /* 360 */
+ { 16, 12, 3, 0, 0, 16, 0, }, /* 361 */
+ { 16, 21, 12, 0, 0, 16, 0, }, /* 362 */
+ { 16, 15, 12, 0, 0, 16, 0, }, /* 363 */
+ { 16, 26, 12, 0, 0, 16, 0, }, /* 364 */
+ { 9, 9, 12, 0, 38864, 9, 0, }, /* 365 */
+ { 9, 9, 12, 0, 8, 9, 0, }, /* 366 */
+ { 9, 5, 12, 0, -8, 9, 0, }, /* 367 */
+ { 8, 17, 12, 0, 0, 8, 0, }, /* 368 */
+ { 8, 7, 12, 0, 0, 8, 0, }, /* 369 */
+ { 8, 26, 12, 0, 0, 8, 0, }, /* 370 */
+ { 8, 21, 12, 0, 0, 8, 0, }, /* 371 */
+ { 41, 29, 12, 0, 0, 41, 0, }, /* 372 */
+ { 41, 7, 12, 0, 0, 41, 0, }, /* 373 */
+ { 41, 22, 12, 0, 0, 41, 0, }, /* 374 */
+ { 41, 18, 12, 0, 0, 41, 0, }, /* 375 */
+ { 46, 7, 12, 0, 0, 46, 0, }, /* 376 */
+ { 46, 14, 12, 0, 0, 46, 0, }, /* 377 */
+ { 51, 7, 12, 0, 0, 51, 0, }, /* 378 */
+ { 51, 12, 3, 0, 0, 51, 0, }, /* 379 */
+ { 25, 7, 12, 0, 0, 25, 0, }, /* 380 */
+ { 25, 12, 3, 0, 0, 25, 0, }, /* 381 */
+ { 10, 21, 12, 0, 0, -115, 0, }, /* 382 */
+ { 7, 7, 12, 0, 0, 7, 0, }, /* 383 */
+ { 7, 12, 3, 0, 0, 7, 0, }, /* 384 */
+ { 52, 7, 12, 0, 0, 52, 0, }, /* 385 */
+ { 52, 12, 3, 0, 0, 52, 0, }, /* 386 */
+ { 32, 7, 12, 0, 0, 32, 0, }, /* 387 */
+ { 32, 12, 3, 0, 0, 32, 0, }, /* 388 */
+ { 32, 10, 5, 0, 0, 32, 0, }, /* 389 */
+ { 32, 21, 12, 0, 0, 32, 0, }, /* 390 */
+ { 32, 6, 12, 0, 0, 32, 0, }, /* 391 */
+ { 32, 23, 12, 0, 0, 32, 0, }, /* 392 */
+ { 32, 13, 12, 0, 0, 32, 0, }, /* 393 */
+ { 32, 15, 12, 0, 0, 32, 0, }, /* 394 */
+ { 38, 21, 12, 0, 0, 38, 0, }, /* 395 */
+ { 10, 21, 12, 0, 0, -70, 0, }, /* 396 */
+ { 38, 17, 12, 0, 0, 38, 0, }, /* 397 */
+ { 38, 12, 3, 0, 0, 38, 0, }, /* 398 */
+ { 38, 1, 2, 0, 0, 38, 0, }, /* 399 */
+ { 38, 13, 12, 0, 0, 38, 0, }, /* 400 */
+ { 38, 7, 12, 0, 0, 38, 0, }, /* 401 */
+ { 38, 6, 12, 0, 0, 38, 0, }, /* 402 */
+ { 35, 7, 12, 0, 0, 35, 0, }, /* 403 */
+ { 35, 12, 3, 0, 0, 35, 0, }, /* 404 */
+ { 35, 10, 5, 0, 0, 35, 0, }, /* 405 */
+ { 35, 26, 12, 0, 0, 35, 0, }, /* 406 */
+ { 35, 21, 12, 0, 0, 35, 0, }, /* 407 */
+ { 35, 13, 12, 0, 0, 35, 0, }, /* 408 */
+ { 53, 7, 12, 0, 0, 53, 0, }, /* 409 */
+ { 40, 7, 12, 0, 0, 40, 0, }, /* 410 */
+ { 40, 13, 12, 0, 0, 40, 0, }, /* 411 */
+ { 40, 15, 12, 0, 0, 40, 0, }, /* 412 */
+ { 40, 26, 12, 0, 0, 40, 0, }, /* 413 */
+ { 32, 26, 12, 0, 0, 32, 0, }, /* 414 */
+ { 6, 7, 12, 0, 0, 6, 0, }, /* 415 */
+ { 6, 12, 3, 0, 0, 6, 0, }, /* 416 */
+ { 6, 10, 5, 0, 0, 6, 0, }, /* 417 */
+ { 6, 21, 12, 0, 0, 6, 0, }, /* 418 */
+ { 91, 7, 12, 0, 0, 91, 0, }, /* 419 */
+ { 91, 10, 5, 0, 0, 91, 0, }, /* 420 */
+ { 91, 12, 3, 0, 0, 91, 0, }, /* 421 */
+ { 91, 10, 12, 0, 0, 91, 0, }, /* 422 */
+ { 91, 13, 12, 0, 0, 91, 0, }, /* 423 */
+ { 91, 21, 12, 0, 0, 91, 0, }, /* 424 */
+ { 91, 6, 12, 0, 0, 91, 0, }, /* 425 */
+ { 28, 11, 3, 0, 0, 28, 0, }, /* 426 */
+ { 62, 12, 3, 0, 0, 62, 0, }, /* 427 */
+ { 62, 10, 5, 0, 0, 62, 0, }, /* 428 */
+ { 62, 7, 12, 0, 0, 62, 0, }, /* 429 */
+ { 62, 10, 3, 0, 0, 62, 0, }, /* 430 */
+ { 62, 13, 12, 0, 0, 62, 0, }, /* 431 */
+ { 62, 21, 12, 0, 0, 62, 0, }, /* 432 */
+ { 62, 26, 12, 0, 0, 62, 0, }, /* 433 */
+ { 76, 12, 3, 0, 0, 76, 0, }, /* 434 */
+ { 76, 10, 5, 0, 0, 76, 0, }, /* 435 */
+ { 76, 7, 12, 0, 0, 76, 0, }, /* 436 */
+ { 76, 13, 12, 0, 0, 76, 0, }, /* 437 */
+ { 93, 7, 12, 0, 0, 93, 0, }, /* 438 */
+ { 93, 12, 3, 0, 0, 93, 0, }, /* 439 */
+ { 93, 10, 5, 0, 0, 93, 0, }, /* 440 */
+ { 93, 21, 12, 0, 0, 93, 0, }, /* 441 */
+ { 70, 7, 12, 0, 0, 70, 0, }, /* 442 */
+ { 70, 10, 5, 0, 0, 70, 0, }, /* 443 */
+ { 70, 12, 3, 0, 0, 70, 0, }, /* 444 */
+ { 70, 21, 12, 0, 0, 70, 0, }, /* 445 */
+ { 70, 13, 12, 0, 0, 70, 0, }, /* 446 */
+ { 73, 13, 12, 0, 0, 73, 0, }, /* 447 */
+ { 73, 7, 12, 0, 0, 73, 0, }, /* 448 */
+ { 73, 6, 12, 0, 0, 73, 0, }, /* 449 */
+ { 73, 21, 12, 0, 0, 73, 0, }, /* 450 */
+ { 13, 5, 12, 63, -6222, 13, 0, }, /* 451 */
+ { 13, 5, 12, 67, -6221, 13, 0, }, /* 452 */
+ { 13, 5, 12, 71, -6212, 13, 0, }, /* 453 */
+ { 13, 5, 12, 75, -6210, 13, 0, }, /* 454 */
+ { 13, 5, 12, 79, -6210, 13, 0, }, /* 455 */
+ { 13, 5, 12, 79, -6211, 13, 0, }, /* 456 */
+ { 13, 5, 12, 84, -6204, 13, 0, }, /* 457 */
+ { 13, 5, 12, 88, -6180, 13, 0, }, /* 458 */
+ { 13, 5, 12, 108, 35267, 13, 0, }, /* 459 */
+ { 17, 9, 12, 0, -3008, 17, 0, }, /* 460 */
+ { 76, 21, 12, 0, 0, 76, 0, }, /* 461 */
+ { 28, 12, 3, 0, 0, -110, 0, }, /* 462 */
+ { 28, 12, 3, 0, 0, 15, 0, }, /* 463 */
+ { 10, 21, 12, 0, 0, -37, 0, }, /* 464 */
+ { 28, 12, 3, 0, 0, -16, 0, }, /* 465 */
+ { 28, 12, 3, 0, 0, -43, 0, }, /* 466 */
+ { 28, 12, 3, 0, 0, -138, 0, }, /* 467 */
+ { 10, 10, 5, 0, 0, -16, 0, }, /* 468 */
+ { 10, 7, 12, 0, 0, -40, 0, }, /* 469 */
+ { 10, 7, 12, 0, 0, -16, 0, }, /* 470 */
+ { 10, 7, 12, 0, 0, 15, 0, }, /* 471 */
+ { 10, 7, 12, 0, 0, -154, 0, }, /* 472 */
+ { 10, 7, 12, 0, 0, -37, 0, }, /* 473 */
+ { 28, 12, 3, 0, 0, -89, 0, }, /* 474 */
+ { 10, 10, 5, 0, 0, 3, 0, }, /* 475 */
+ { 28, 12, 3, 0, 0, -37, 0, }, /* 476 */
+ { 10, 7, 12, 0, 0, 150, 0, }, /* 477 */
+ { 13, 5, 12, 0, 0, 13, 0, }, /* 478 */
+ { 13, 6, 12, 0, 0, 13, 0, }, /* 479 */
+ { 34, 5, 12, 0, 35332, 34, 0, }, /* 480 */
+ { 34, 5, 12, 0, 3814, 34, 0, }, /* 481 */
+ { 34, 5, 12, 0, 35384, 34, 0, }, /* 482 */
+ { 34, 9, 12, 92, 1, 34, 0, }, /* 483 */
+ { 34, 5, 12, 92, -1, 34, 0, }, /* 484 */
+ { 34, 5, 12, 92, -58, 34, 0, }, /* 485 */
+ { 34, 9, 12, 0, -7615, 34, 0, }, /* 486 */
+ { 20, 5, 12, 0, 8, 20, 0, }, /* 487 */
+ { 20, 9, 12, 0, -8, 20, 0, }, /* 488 */
+ { 20, 5, 12, 0, 74, 20, 0, }, /* 489 */
+ { 20, 5, 12, 0, 86, 20, 0, }, /* 490 */
+ { 20, 5, 12, 0, 100, 20, 0, }, /* 491 */
+ { 20, 5, 12, 0, 128, 20, 0, }, /* 492 */
+ { 20, 5, 12, 0, 112, 20, 0, }, /* 493 */
+ { 20, 5, 12, 0, 126, 20, 0, }, /* 494 */
+ { 20, 8, 12, 0, -8, 20, 0, }, /* 495 */
+ { 20, 5, 12, 0, 9, 20, 0, }, /* 496 */
+ { 20, 9, 12, 0, -74, 20, 0, }, /* 497 */
+ { 20, 8, 12, 0, -9, 20, 0, }, /* 498 */
+ { 20, 5, 12, 21, -7173, 20, 0, }, /* 499 */
+ { 20, 9, 12, 0, -86, 20, 0, }, /* 500 */
+ { 20, 9, 12, 0, -100, 20, 0, }, /* 501 */
+ { 20, 9, 12, 0, -112, 20, 0, }, /* 502 */
+ { 20, 9, 12, 0, -128, 20, 0, }, /* 503 */
+ { 20, 9, 12, 0, -126, 20, 0, }, /* 504 */
+ { 28, 1, 3, 0, 0, 28, 0, }, /* 505 */
+ { 28, 1, 13, 0, 0, 28, 0, }, /* 506 */
+ { 10, 27, 2, 0, 0, 10, 0, }, /* 507 */
+ { 10, 28, 2, 0, 0, 10, 0, }, /* 508 */
+ { 10, 29, 12, 0, 0, -67, 0, }, /* 509 */
+ { 10, 21, 14, 0, 0, 10, 0, }, /* 510 */
+ { 0, 2, 2, 0, 0, 0, 0, }, /* 511 */
+ { 28, 12, 3, 0, 0, -93, 0, }, /* 512 */
+ { 10, 9, 12, 0, 0, 10, 0, }, /* 513 */
+ { 10, 5, 12, 0, 0, 10, 0, }, /* 514 */
+ { 20, 9, 12, 96, -7517, 20, 0, }, /* 515 */
+ { 34, 9, 12, 100, -8383, 34, 0, }, /* 516 */
+ { 34, 9, 12, 104, -8262, 34, 0, }, /* 517 */
+ { 34, 9, 12, 0, 28, 34, 0, }, /* 518 */
+ { 10, 7, 12, 0, 0, 10, 0, }, /* 519 */
+ { 10, 5, 14, 0, 0, 10, 0, }, /* 520 */
+ { 34, 5, 12, 0, -28, 34, 0, }, /* 521 */
+ { 34, 14, 12, 0, 16, 34, 0, }, /* 522 */
+ { 34, 14, 12, 0, -16, 34, 0, }, /* 523 */
+ { 34, 14, 12, 0, 0, 34, 0, }, /* 524 */
+ { 10, 25, 14, 0, 0, 10, 0, }, /* 525 */
+ { 10, 26, 12, 0, 26, 10, 0, }, /* 526 */
+ { 10, 26, 14, 0, 26, 10, 0, }, /* 527 */
+ { 10, 26, 12, 0, -26, 10, 0, }, /* 528 */
+ { 5, 26, 12, 0, 0, 5, 0, }, /* 529 */
+ { 18, 9, 12, 0, 48, 18, 0, }, /* 530 */
+ { 18, 5, 12, 0, -48, 18, 0, }, /* 531 */
+ { 34, 9, 12, 0, -10743, 34, 0, }, /* 532 */
+ { 34, 9, 12, 0, -3814, 34, 0, }, /* 533 */
+ { 34, 9, 12, 0, -10727, 34, 0, }, /* 534 */
+ { 34, 5, 12, 0, -10795, 34, 0, }, /* 535 */
+ { 34, 5, 12, 0, -10792, 34, 0, }, /* 536 */
+ { 34, 9, 12, 0, -10780, 34, 0, }, /* 537 */
+ { 34, 9, 12, 0, -10749, 34, 0, }, /* 538 */
+ { 34, 9, 12, 0, -10783, 34, 0, }, /* 539 */
+ { 34, 9, 12, 0, -10782, 34, 0, }, /* 540 */
+ { 34, 9, 12, 0, -10815, 34, 0, }, /* 541 */
+ { 11, 5, 12, 0, 0, 11, 0, }, /* 542 */
+ { 11, 26, 12, 0, 0, 11, 0, }, /* 543 */
+ { 11, 12, 3, 0, 0, 11, 0, }, /* 544 */
+ { 11, 21, 12, 0, 0, 11, 0, }, /* 545 */
+ { 11, 15, 12, 0, 0, 11, 0, }, /* 546 */
+ { 17, 5, 12, 0, -7264, 17, 0, }, /* 547 */
+ { 59, 7, 12, 0, 0, 59, 0, }, /* 548 */
+ { 59, 6, 12, 0, 0, 59, 0, }, /* 549 */
+ { 59, 21, 12, 0, 0, 59, 0, }, /* 550 */
+ { 59, 12, 3, 0, 0, 59, 0, }, /* 551 */
+ { 13, 12, 3, 0, 0, 13, 0, }, /* 552 */
+ { 10, 21, 12, 0, 0, -28, 0, }, /* 553 */
+ { 23, 26, 12, 0, 0, 23, 0, }, /* 554 */
+ { 10, 21, 12, 0, 0, -131, 0, }, /* 555 */
+ { 10, 21, 12, 0, 0, -125, 0, }, /* 556 */
+ { 23, 6, 12, 0, 0, 23, 0, }, /* 557 */
+ { 10, 7, 12, 0, 0, 23, 0, }, /* 558 */
+ { 23, 14, 12, 0, 0, 23, 0, }, /* 559 */
+ { 10, 22, 12, 0, 0, -131, 0, }, /* 560 */
+ { 10, 18, 12, 0, 0, -131, 0, }, /* 561 */
+ { 10, 26, 12, 0, 0, -125, 0, }, /* 562 */
+ { 10, 17, 12, 0, 0, -125, 0, }, /* 563 */
+ { 10, 22, 12, 0, 0, -125, 0, }, /* 564 */
+ { 10, 18, 12, 0, 0, -125, 0, }, /* 565 */
+ { 28, 12, 3, 0, 0, -19, 0, }, /* 566 */
+ { 24, 10, 3, 0, 0, 24, 0, }, /* 567 */
+ { 10, 17, 14, 0, 0, -125, 0, }, /* 568 */
+ { 10, 6, 12, 0, 0, -61, 0, }, /* 569 */
+ { 10, 7, 12, 0, 0, -97, 0, }, /* 570 */
+ { 10, 21, 14, 0, 0, -97, 0, }, /* 571 */
+ { 10, 26, 12, 0, 0, 23, 0, }, /* 572 */
+ { 27, 7, 12, 0, 0, 27, 0, }, /* 573 */
+ { 28, 12, 3, 0, 0, -61, 0, }, /* 574 */
+ { 10, 24, 12, 0, 0, -61, 0, }, /* 575 */
+ { 27, 6, 12, 0, 0, 27, 0, }, /* 576 */
+ { 10, 17, 12, 0, 0, -61, 0, }, /* 577 */
+ { 30, 7, 12, 0, 0, 30, 0, }, /* 578 */
+ { 30, 6, 12, 0, 0, 30, 0, }, /* 579 */
+ { 4, 7, 12, 0, 0, 4, 0, }, /* 580 */
+ { 24, 7, 12, 0, 0, 24, 0, }, /* 581 */
+ { 10, 15, 12, 0, 0, 23, 0, }, /* 582 */
+ { 24, 26, 12, 0, 0, 24, 0, }, /* 583 */
+ { 10, 26, 14, 0, 0, 23, 0, }, /* 584 */
+ { 30, 26, 12, 0, 0, 30, 0, }, /* 585 */
+ { 23, 7, 12, 0, 0, 23, 0, }, /* 586 */
+ { 61, 7, 12, 0, 0, 61, 0, }, /* 587 */
+ { 61, 6, 12, 0, 0, 61, 0, }, /* 588 */
+ { 61, 26, 12, 0, 0, 61, 0, }, /* 589 */
+ { 86, 7, 12, 0, 0, 86, 0, }, /* 590 */
+ { 86, 6, 12, 0, 0, 86, 0, }, /* 591 */
+ { 86, 21, 12, 0, 0, 86, 0, }, /* 592 */
+ { 77, 7, 12, 0, 0, 77, 0, }, /* 593 */
+ { 77, 6, 12, 0, 0, 77, 0, }, /* 594 */
+ { 77, 21, 12, 0, 0, 77, 0, }, /* 595 */
+ { 77, 13, 12, 0, 0, 77, 0, }, /* 596 */
+ { 13, 9, 12, 108, 1, 13, 0, }, /* 597 */
+ { 13, 5, 12, 108, -35267, 13, 0, }, /* 598 */
+ { 13, 7, 12, 0, 0, 13, 0, }, /* 599 */
+ { 13, 21, 12, 0, 0, 13, 0, }, /* 600 */
+ { 79, 7, 12, 0, 0, 79, 0, }, /* 601 */
+ { 79, 14, 12, 0, 0, 79, 0, }, /* 602 */
+ { 79, 12, 3, 0, 0, 79, 0, }, /* 603 */
+ { 79, 21, 12, 0, 0, 79, 0, }, /* 604 */
+ { 34, 9, 12, 0, -35332, 34, 0, }, /* 605 */
+ { 34, 9, 12, 0, -42280, 34, 0, }, /* 606 */
+ { 34, 5, 12, 0, 48, 34, 0, }, /* 607 */
+ { 34, 9, 12, 0, -42308, 34, 0, }, /* 608 */
+ { 34, 9, 12, 0, -42319, 34, 0, }, /* 609 */
+ { 34, 9, 12, 0, -42315, 34, 0, }, /* 610 */
+ { 34, 9, 12, 0, -42305, 34, 0, }, /* 611 */
+ { 34, 9, 12, 0, -42258, 34, 0, }, /* 612 */
+ { 34, 9, 12, 0, -42282, 34, 0, }, /* 613 */
+ { 34, 9, 12, 0, -42261, 34, 0, }, /* 614 */
+ { 34, 9, 12, 0, 928, 34, 0, }, /* 615 */
+ { 34, 9, 12, 0, -48, 34, 0, }, /* 616 */
+ { 34, 9, 12, 0, -42307, 34, 0, }, /* 617 */
+ { 34, 9, 12, 0, -35384, 34, 0, }, /* 618 */
+ { 49, 7, 12, 0, 0, 49, 0, }, /* 619 */
+ { 49, 12, 3, 0, 0, 49, 0, }, /* 620 */
+ { 49, 10, 5, 0, 0, 49, 0, }, /* 621 */
+ { 49, 26, 12, 0, 0, 49, 0, }, /* 622 */
+ { 10, 15, 12, 0, 0, -216, 0, }, /* 623 */
+ { 10, 15, 12, 0, 0, -202, 0, }, /* 624 */
+ { 10, 26, 12, 0, 0, -163, 0, }, /* 625 */
+ { 10, 23, 12, 0, 0, -163, 0, }, /* 626 */
+ { 65, 7, 12, 0, 0, 65, 0, }, /* 627 */
+ { 65, 21, 12, 0, 0, 65, 0, }, /* 628 */
+ { 75, 10, 5, 0, 0, 75, 0, }, /* 629 */
+ { 75, 7, 12, 0, 0, 75, 0, }, /* 630 */
+ { 75, 12, 3, 0, 0, 75, 0, }, /* 631 */
+ { 75, 21, 12, 0, 0, 75, 0, }, /* 632 */
+ { 75, 13, 12, 0, 0, 75, 0, }, /* 633 */
+ { 15, 12, 3, 0, 0, -16, 0, }, /* 634 */
+ { 15, 7, 12, 0, 0, -46, 0, }, /* 635 */
+ { 69, 13, 12, 0, 0, 69, 0, }, /* 636 */
+ { 69, 7, 12, 0, 0, 69, 0, }, /* 637 */
+ { 69, 12, 3, 0, 0, 69, 0, }, /* 638 */
+ { 10, 21, 12, 0, 0, -101, 0, }, /* 639 */
+ { 69, 21, 12, 0, 0, 69, 0, }, /* 640 */
+ { 74, 7, 12, 0, 0, 74, 0, }, /* 641 */
+ { 74, 12, 3, 0, 0, 74, 0, }, /* 642 */
+ { 74, 10, 5, 0, 0, 74, 0, }, /* 643 */
+ { 74, 21, 12, 0, 0, 74, 0, }, /* 644 */
+ { 84, 12, 3, 0, 0, 84, 0, }, /* 645 */
+ { 84, 10, 5, 0, 0, 84, 0, }, /* 646 */
+ { 84, 7, 12, 0, 0, 84, 0, }, /* 647 */
+ { 84, 21, 12, 0, 0, 84, 0, }, /* 648 */
+ { 10, 6, 12, 0, 0, -22, 0, }, /* 649 */
+ { 84, 13, 12, 0, 0, 84, 0, }, /* 650 */
+ { 39, 6, 12, 0, 0, 39, 0, }, /* 651 */
+ { 68, 7, 12, 0, 0, 68, 0, }, /* 652 */
+ { 68, 12, 3, 0, 0, 68, 0, }, /* 653 */
+ { 68, 10, 5, 0, 0, 68, 0, }, /* 654 */
+ { 68, 13, 12, 0, 0, 68, 0, }, /* 655 */
+ { 68, 21, 12, 0, 0, 68, 0, }, /* 656 */
+ { 92, 7, 12, 0, 0, 92, 0, }, /* 657 */
+ { 92, 12, 3, 0, 0, 92, 0, }, /* 658 */
+ { 92, 6, 12, 0, 0, 92, 0, }, /* 659 */
+ { 92, 21, 12, 0, 0, 92, 0, }, /* 660 */
+ { 87, 7, 12, 0, 0, 87, 0, }, /* 661 */
+ { 87, 10, 5, 0, 0, 87, 0, }, /* 662 */
+ { 87, 12, 3, 0, 0, 87, 0, }, /* 663 */
+ { 87, 21, 12, 0, 0, 87, 0, }, /* 664 */
+ { 87, 6, 12, 0, 0, 87, 0, }, /* 665 */
+ { 34, 5, 12, 0, -928, 34, 0, }, /* 666 */
+ { 9, 5, 12, 0, -38864, 9, 0, }, /* 667 */
+ { 87, 13, 12, 0, 0, 87, 0, }, /* 668 */
+ { 24, 7, 9, 0, 0, 24, 0, }, /* 669 */
+ { 24, 7, 10, 0, 0, 24, 0, }, /* 670 */
+ { 0, 4, 12, 0, 0, 0, 0, }, /* 671 */
+ { 0, 3, 12, 0, 0, 0, 0, }, /* 672 */
+ { 26, 25, 12, 0, 0, 26, 0, }, /* 673 */
+ { 1, 24, 12, 0, 0, 1, 0, }, /* 674 */
+ { 1, 7, 12, 0, 0, -10, 0, }, /* 675 */
+ { 1, 26, 12, 0, 0, -10, 0, }, /* 676 */
+ { 10, 6, 3, 0, 0, -61, 0, }, /* 677 */
+ { 36, 7, 12, 0, 0, 36, 0, }, /* 678 */
+ { 10, 21, 12, 0, 0, -25, 0, }, /* 679 */
+ { 10, 15, 12, 0, 0, -85, 0, }, /* 680 */
+ { 10, 26, 12, 0, 0, -25, 0, }, /* 681 */
+ { 20, 14, 12, 0, 0, 20, 0, }, /* 682 */
+ { 20, 15, 12, 0, 0, 20, 0, }, /* 683 */
+ { 20, 26, 12, 0, 0, 20, 0, }, /* 684 */
+ { 71, 7, 12, 0, 0, 71, 0, }, /* 685 */
+ { 67, 7, 12, 0, 0, 67, 0, }, /* 686 */
+ { 28, 12, 3, 0, 0, -1, 0, }, /* 687 */
+ { 10, 15, 12, 0, 0, -1, 0, }, /* 688 */
+ { 42, 7, 12, 0, 0, 42, 0, }, /* 689 */
+ { 42, 15, 12, 0, 0, 42, 0, }, /* 690 */
+ { 19, 7, 12, 0, 0, 19, 0, }, /* 691 */
+ { 19, 14, 12, 0, 0, 19, 0, }, /* 692 */
+ { 118, 7, 12, 0, 0, 118, 0, }, /* 693 */
+ { 118, 12, 3, 0, 0, 118, 0, }, /* 694 */
+ { 60, 7, 12, 0, 0, 60, 0, }, /* 695 */
+ { 60, 21, 12, 0, 0, 60, 0, }, /* 696 */
+ { 43, 7, 12, 0, 0, 43, 0, }, /* 697 */
+ { 43, 21, 12, 0, 0, 43, 0, }, /* 698 */
+ { 43, 14, 12, 0, 0, 43, 0, }, /* 699 */
+ { 14, 9, 12, 0, 40, 14, 0, }, /* 700 */
+ { 14, 5, 12, 0, -40, 14, 0, }, /* 701 */
+ { 47, 7, 12, 0, 0, 47, 0, }, /* 702 */
+ { 45, 7, 12, 0, 0, 45, 0, }, /* 703 */
+ { 45, 13, 12, 0, 0, 45, 0, }, /* 704 */
+ { 136, 9, 12, 0, 40, 136, 0, }, /* 705 */
+ { 136, 5, 12, 0, -40, 136, 0, }, /* 706 */
+ { 106, 7, 12, 0, 0, 106, 0, }, /* 707 */
+ { 104, 7, 12, 0, 0, 104, 0, }, /* 708 */
+ { 104, 21, 12, 0, 0, 104, 0, }, /* 709 */
+ { 110, 7, 12, 0, 0, 110, 0, }, /* 710 */
+ { 12, 7, 12, 0, 0, 12, 0, }, /* 711 */
+ { 81, 7, 12, 0, 0, 81, 0, }, /* 712 */
+ { 81, 21, 12, 0, 0, 81, 0, }, /* 713 */
+ { 81, 15, 12, 0, 0, 81, 0, }, /* 714 */
+ { 120, 7, 12, 0, 0, 120, 0, }, /* 715 */
+ { 120, 26, 12, 0, 0, 120, 0, }, /* 716 */
+ { 120, 15, 12, 0, 0, 120, 0, }, /* 717 */
+ { 116, 7, 12, 0, 0, 116, 0, }, /* 718 */
+ { 116, 15, 12, 0, 0, 116, 0, }, /* 719 */
+ { 128, 7, 12, 0, 0, 128, 0, }, /* 720 */
+ { 128, 15, 12, 0, 0, 128, 0, }, /* 721 */
+ { 66, 7, 12, 0, 0, 66, 0, }, /* 722 */
+ { 66, 15, 12, 0, 0, 66, 0, }, /* 723 */
+ { 66, 21, 12, 0, 0, 66, 0, }, /* 724 */
+ { 72, 7, 12, 0, 0, 72, 0, }, /* 725 */
+ { 72, 21, 12, 0, 0, 72, 0, }, /* 726 */
+ { 98, 7, 12, 0, 0, 98, 0, }, /* 727 */
+ { 97, 7, 12, 0, 0, 97, 0, }, /* 728 */
+ { 97, 15, 12, 0, 0, 97, 0, }, /* 729 */
+ { 31, 7, 12, 0, 0, 31, 0, }, /* 730 */
+ { 31, 12, 3, 0, 0, 31, 0, }, /* 731 */
+ { 31, 15, 12, 0, 0, 31, 0, }, /* 732 */
+ { 31, 21, 12, 0, 0, 31, 0, }, /* 733 */
+ { 88, 7, 12, 0, 0, 88, 0, }, /* 734 */
+ { 88, 15, 12, 0, 0, 88, 0, }, /* 735 */
+ { 88, 21, 12, 0, 0, 88, 0, }, /* 736 */
+ { 117, 7, 12, 0, 0, 117, 0, }, /* 737 */
+ { 117, 15, 12, 0, 0, 117, 0, }, /* 738 */
+ { 112, 7, 12, 0, 0, 112, 0, }, /* 739 */
+ { 112, 26, 12, 0, 0, 112, 0, }, /* 740 */
+ { 112, 12, 3, 0, 0, 112, 0, }, /* 741 */
+ { 112, 15, 12, 0, 0, 112, 0, }, /* 742 */
+ { 112, 21, 12, 0, 0, 112, 0, }, /* 743 */
+ { 78, 7, 12, 0, 0, 78, 0, }, /* 744 */
+ { 78, 21, 12, 0, 0, 78, 0, }, /* 745 */
+ { 83, 7, 12, 0, 0, 83, 0, }, /* 746 */
+ { 83, 15, 12, 0, 0, 83, 0, }, /* 747 */
+ { 82, 7, 12, 0, 0, 82, 0, }, /* 748 */
+ { 82, 15, 12, 0, 0, 82, 0, }, /* 749 */
+ { 121, 7, 12, 0, 0, 121, 0, }, /* 750 */
+ { 121, 21, 12, 0, 0, 121, 0, }, /* 751 */
+ { 121, 15, 12, 0, 0, 121, 0, }, /* 752 */
+ { 89, 7, 12, 0, 0, 89, 0, }, /* 753 */
+ { 130, 9, 12, 0, 64, 130, 0, }, /* 754 */
+ { 130, 5, 12, 0, -64, 130, 0, }, /* 755 */
+ { 130, 15, 12, 0, 0, 130, 0, }, /* 756 */
+ { 144, 7, 12, 0, 0, 144, 0, }, /* 757 */
+ { 144, 12, 3, 0, 0, 144, 0, }, /* 758 */
+ { 144, 13, 12, 0, 0, 144, 0, }, /* 759 */
+ { 1, 15, 12, 0, 0, 1, 0, }, /* 760 */
+ { 147, 7, 12, 0, 0, 147, 0, }, /* 761 */
+ { 147, 15, 12, 0, 0, 147, 0, }, /* 762 */
+ { 148, 7, 12, 0, 0, 148, 0, }, /* 763 */
+ { 148, 12, 3, 0, 0, 148, 0, }, /* 764 */
+ { 148, 15, 12, 0, 0, 148, 0, }, /* 765 */
+ { 148, 21, 12, 0, 0, 148, 0, }, /* 766 */
+ { 149, 7, 12, 0, 0, 149, 0, }, /* 767 */
+ { 94, 10, 5, 0, 0, 94, 0, }, /* 768 */
+ { 94, 12, 3, 0, 0, 94, 0, }, /* 769 */
+ { 94, 7, 12, 0, 0, 94, 0, }, /* 770 */
+ { 94, 21, 12, 0, 0, 94, 0, }, /* 771 */
+ { 94, 15, 12, 0, 0, 94, 0, }, /* 772 */
+ { 94, 13, 12, 0, 0, 94, 0, }, /* 773 */
+ { 85, 12, 3, 0, 0, 85, 0, }, /* 774 */
+ { 85, 10, 5, 0, 0, 85, 0, }, /* 775 */
+ { 85, 7, 12, 0, 0, 85, 0, }, /* 776 */
+ { 85, 21, 12, 0, 0, 85, 0, }, /* 777 */
+ { 85, 1, 4, 0, 0, 85, 0, }, /* 778 */
+ { 101, 7, 12, 0, 0, 101, 0, }, /* 779 */
+ { 101, 13, 12, 0, 0, 101, 0, }, /* 780 */
+ { 96, 12, 3, 0, 0, 96, 0, }, /* 781 */
+ { 96, 7, 12, 0, 0, 96, 0, }, /* 782 */
+ { 96, 10, 5, 0, 0, 96, 0, }, /* 783 */
+ { 96, 13, 12, 0, 0, 96, 0, }, /* 784 */
+ { 96, 21, 12, 0, 0, 96, 0, }, /* 785 */
+ { 111, 7, 12, 0, 0, 111, 0, }, /* 786 */
+ { 111, 12, 3, 0, 0, 111, 0, }, /* 787 */
+ { 111, 21, 12, 0, 0, 111, 0, }, /* 788 */
+ { 100, 12, 3, 0, 0, 100, 0, }, /* 789 */
+ { 100, 10, 5, 0, 0, 100, 0, }, /* 790 */
+ { 100, 7, 12, 0, 0, 100, 0, }, /* 791 */
+ { 100, 7, 4, 0, 0, 100, 0, }, /* 792 */
+ { 100, 21, 12, 0, 0, 100, 0, }, /* 793 */
+ { 100, 13, 12, 0, 0, 100, 0, }, /* 794 */
+ { 48, 15, 12, 0, 0, 48, 0, }, /* 795 */
+ { 108, 7, 12, 0, 0, 108, 0, }, /* 796 */
+ { 108, 10, 5, 0, 0, 108, 0, }, /* 797 */
+ { 108, 12, 3, 0, 0, 108, 0, }, /* 798 */
+ { 108, 21, 12, 0, 0, 108, 0, }, /* 799 */
+ { 129, 7, 12, 0, 0, 129, 0, }, /* 800 */
+ { 129, 21, 12, 0, 0, 129, 0, }, /* 801 */
+ { 109, 7, 12, 0, 0, 109, 0, }, /* 802 */
+ { 109, 12, 3, 0, 0, 109, 0, }, /* 803 */
+ { 109, 10, 5, 0, 0, 109, 0, }, /* 804 */
+ { 109, 13, 12, 0, 0, 109, 0, }, /* 805 */
+ { 107, 12, 3, 0, 0, 107, 0, }, /* 806 */
+ { 107, 12, 3, 0, 0, -52, 0, }, /* 807 */
+ { 107, 10, 5, 0, 0, 107, 0, }, /* 808 */
+ { 107, 10, 5, 0, 0, -52, 0, }, /* 809 */
+ { 107, 7, 12, 0, 0, 107, 0, }, /* 810 */
+ { 28, 12, 3, 0, 0, -52, 0, }, /* 811 */
+ { 107, 10, 3, 0, 0, 107, 0, }, /* 812 */
+ { 135, 7, 12, 0, 0, 135, 0, }, /* 813 */
+ { 135, 10, 5, 0, 0, 135, 0, }, /* 814 */
+ { 135, 12, 3, 0, 0, 135, 0, }, /* 815 */
+ { 135, 21, 12, 0, 0, 135, 0, }, /* 816 */
+ { 135, 13, 12, 0, 0, 135, 0, }, /* 817 */
+ { 124, 7, 12, 0, 0, 124, 0, }, /* 818 */
+ { 124, 10, 3, 0, 0, 124, 0, }, /* 819 */
+ { 124, 10, 5, 0, 0, 124, 0, }, /* 820 */
+ { 124, 12, 3, 0, 0, 124, 0, }, /* 821 */
+ { 124, 21, 12, 0, 0, 124, 0, }, /* 822 */
+ { 124, 13, 12, 0, 0, 124, 0, }, /* 823 */
+ { 123, 7, 12, 0, 0, 123, 0, }, /* 824 */
+ { 123, 10, 3, 0, 0, 123, 0, }, /* 825 */
+ { 123, 10, 5, 0, 0, 123, 0, }, /* 826 */
+ { 123, 12, 3, 0, 0, 123, 0, }, /* 827 */
+ { 123, 21, 12, 0, 0, 123, 0, }, /* 828 */
+ { 114, 7, 12, 0, 0, 114, 0, }, /* 829 */
+ { 114, 10, 5, 0, 0, 114, 0, }, /* 830 */
+ { 114, 12, 3, 0, 0, 114, 0, }, /* 831 */
+ { 114, 21, 12, 0, 0, 114, 0, }, /* 832 */
+ { 114, 13, 12, 0, 0, 114, 0, }, /* 833 */
+ { 102, 7, 12, 0, 0, 102, 0, }, /* 834 */
+ { 102, 12, 3, 0, 0, 102, 0, }, /* 835 */
+ { 102, 10, 5, 0, 0, 102, 0, }, /* 836 */
+ { 102, 13, 12, 0, 0, 102, 0, }, /* 837 */
+ { 126, 7, 12, 0, 0, 126, 0, }, /* 838 */
+ { 126, 12, 3, 0, 0, 126, 0, }, /* 839 */
+ { 126, 10, 5, 0, 0, 126, 0, }, /* 840 */
+ { 126, 13, 12, 0, 0, 126, 0, }, /* 841 */
+ { 126, 15, 12, 0, 0, 126, 0, }, /* 842 */
+ { 126, 21, 12, 0, 0, 126, 0, }, /* 843 */
+ { 126, 26, 12, 0, 0, 126, 0, }, /* 844 */
+ { 142, 7, 12, 0, 0, 142, 0, }, /* 845 */
+ { 142, 10, 5, 0, 0, 142, 0, }, /* 846 */
+ { 142, 12, 3, 0, 0, 142, 0, }, /* 847 */
+ { 142, 21, 12, 0, 0, 142, 0, }, /* 848 */
+ { 125, 9, 12, 0, 32, 125, 0, }, /* 849 */
+ { 125, 5, 12, 0, -32, 125, 0, }, /* 850 */
+ { 125, 13, 12, 0, 0, 125, 0, }, /* 851 */
+ { 125, 15, 12, 0, 0, 125, 0, }, /* 852 */
+ { 125, 7, 12, 0, 0, 125, 0, }, /* 853 */
+ { 150, 7, 12, 0, 0, 150, 0, }, /* 854 */
+ { 150, 10, 5, 0, 0, 150, 0, }, /* 855 */
+ { 150, 12, 3, 0, 0, 150, 0, }, /* 856 */
+ { 150, 21, 12, 0, 0, 150, 0, }, /* 857 */
+ { 141, 7, 12, 0, 0, 141, 0, }, /* 858 */
+ { 141, 12, 3, 0, 0, 141, 0, }, /* 859 */
+ { 141, 10, 5, 0, 0, 141, 0, }, /* 860 */
+ { 141, 7, 4, 0, 0, 141, 0, }, /* 861 */
+ { 141, 21, 12, 0, 0, 141, 0, }, /* 862 */
+ { 140, 7, 12, 0, 0, 140, 0, }, /* 863 */
+ { 140, 12, 3, 0, 0, 140, 0, }, /* 864 */
+ { 140, 10, 5, 0, 0, 140, 0, }, /* 865 */
+ { 140, 7, 4, 0, 0, 140, 0, }, /* 866 */
+ { 140, 21, 12, 0, 0, 140, 0, }, /* 867 */
+ { 122, 7, 12, 0, 0, 122, 0, }, /* 868 */
+ { 133, 7, 12, 0, 0, 133, 0, }, /* 869 */
+ { 133, 10, 5, 0, 0, 133, 0, }, /* 870 */
+ { 133, 12, 3, 0, 0, 133, 0, }, /* 871 */
+ { 133, 21, 12, 0, 0, 133, 0, }, /* 872 */
+ { 133, 13, 12, 0, 0, 133, 0, }, /* 873 */
+ { 133, 15, 12, 0, 0, 133, 0, }, /* 874 */
+ { 134, 21, 12, 0, 0, 134, 0, }, /* 875 */
+ { 134, 7, 12, 0, 0, 134, 0, }, /* 876 */
+ { 134, 12, 3, 0, 0, 134, 0, }, /* 877 */
+ { 134, 10, 5, 0, 0, 134, 0, }, /* 878 */
+ { 138, 7, 12, 0, 0, 138, 0, }, /* 879 */
+ { 138, 12, 3, 0, 0, 138, 0, }, /* 880 */
+ { 138, 7, 4, 0, 0, 138, 0, }, /* 881 */
+ { 138, 13, 12, 0, 0, 138, 0, }, /* 882 */
+ { 143, 7, 12, 0, 0, 143, 0, }, /* 883 */
+ { 143, 10, 5, 0, 0, 143, 0, }, /* 884 */
+ { 143, 12, 3, 0, 0, 143, 0, }, /* 885 */
+ { 143, 13, 12, 0, 0, 143, 0, }, /* 886 */
+ { 145, 7, 12, 0, 0, 145, 0, }, /* 887 */
+ { 145, 12, 3, 0, 0, 145, 0, }, /* 888 */
+ { 145, 10, 5, 0, 0, 145, 0, }, /* 889 */
+ { 145, 21, 12, 0, 0, 145, 0, }, /* 890 */
+ { 54, 15, 12, 0, 0, 54, 0, }, /* 891 */
+ { 54, 21, 12, 0, 0, 54, 0, }, /* 892 */
+ { 63, 7, 12, 0, 0, 63, 0, }, /* 893 */
+ { 63, 14, 12, 0, 0, 63, 0, }, /* 894 */
+ { 63, 21, 12, 0, 0, 63, 0, }, /* 895 */
+ { 80, 7, 12, 0, 0, 80, 0, }, /* 896 */
+ { 80, 1, 2, 0, 0, 80, 0, }, /* 897 */
+ { 127, 7, 12, 0, 0, 127, 0, }, /* 898 */
+ { 115, 7, 12, 0, 0, 115, 0, }, /* 899 */
+ { 115, 13, 12, 0, 0, 115, 0, }, /* 900 */
+ { 115, 21, 12, 0, 0, 115, 0, }, /* 901 */
+ { 103, 7, 12, 0, 0, 103, 0, }, /* 902 */
+ { 103, 12, 3, 0, 0, 103, 0, }, /* 903 */
+ { 103, 21, 12, 0, 0, 103, 0, }, /* 904 */
+ { 119, 7, 12, 0, 0, 119, 0, }, /* 905 */
+ { 119, 12, 3, 0, 0, 119, 0, }, /* 906 */
+ { 119, 21, 12, 0, 0, 119, 0, }, /* 907 */
+ { 119, 26, 12, 0, 0, 119, 0, }, /* 908 */
+ { 119, 6, 12, 0, 0, 119, 0, }, /* 909 */
+ { 119, 13, 12, 0, 0, 119, 0, }, /* 910 */
+ { 119, 15, 12, 0, 0, 119, 0, }, /* 911 */
+ { 146, 9, 12, 0, 32, 146, 0, }, /* 912 */
+ { 146, 5, 12, 0, -32, 146, 0, }, /* 913 */
+ { 146, 15, 12, 0, 0, 146, 0, }, /* 914 */
+ { 146, 21, 12, 0, 0, 146, 0, }, /* 915 */
+ { 99, 7, 12, 0, 0, 99, 0, }, /* 916 */
+ { 99, 12, 3, 0, 0, 99, 0, }, /* 917 */
+ { 99, 10, 5, 0, 0, 99, 0, }, /* 918 */
+ { 99, 6, 12, 0, 0, 99, 0, }, /* 919 */
+ { 137, 6, 12, 0, 0, 137, 0, }, /* 920 */
+ { 139, 6, 12, 0, 0, 139, 0, }, /* 921 */
+ { 137, 7, 12, 0, 0, 137, 0, }, /* 922 */
+ { 139, 7, 12, 0, 0, 139, 0, }, /* 923 */
+ { 105, 7, 12, 0, 0, 105, 0, }, /* 924 */
+ { 105, 26, 12, 0, 0, 105, 0, }, /* 925 */
+ { 105, 12, 3, 0, 0, 105, 0, }, /* 926 */
+ { 105, 21, 12, 0, 0, 105, 0, }, /* 927 */
+ { 10, 1, 2, 0, 0, 105, 0, }, /* 928 */
+ { 10, 10, 3, 0, 0, 10, 0, }, /* 929 */
+ { 10, 10, 5, 0, 0, 10, 0, }, /* 930 */
+ { 20, 12, 3, 0, 0, 20, 0, }, /* 931 */
+ { 131, 26, 12, 0, 0, 131, 0, }, /* 932 */
+ { 131, 12, 3, 0, 0, 131, 0, }, /* 933 */
+ { 131, 21, 12, 0, 0, 131, 0, }, /* 934 */
+ { 18, 12, 3, 0, 0, 18, 0, }, /* 935 */
+ { 151, 7, 12, 0, 0, 151, 0, }, /* 936 */
+ { 151, 12, 3, 0, 0, 151, 0, }, /* 937 */
+ { 151, 6, 12, 0, 0, 151, 0, }, /* 938 */
+ { 151, 13, 12, 0, 0, 151, 0, }, /* 939 */
+ { 151, 26, 12, 0, 0, 151, 0, }, /* 940 */
+ { 152, 7, 12, 0, 0, 152, 0, }, /* 941 */
+ { 152, 12, 3, 0, 0, 152, 0, }, /* 942 */
+ { 152, 13, 12, 0, 0, 152, 0, }, /* 943 */
+ { 152, 23, 12, 0, 0, 152, 0, }, /* 944 */
+ { 113, 7, 12, 0, 0, 113, 0, }, /* 945 */
+ { 113, 15, 12, 0, 0, 113, 0, }, /* 946 */
+ { 113, 12, 3, 0, 0, 113, 0, }, /* 947 */
+ { 132, 9, 12, 0, 34, 132, 0, }, /* 948 */
+ { 132, 5, 12, 0, -34, 132, 0, }, /* 949 */
+ { 132, 12, 3, 0, 0, 132, 0, }, /* 950 */
+ { 132, 6, 12, 0, 0, 132, 0, }, /* 951 */
+ { 132, 13, 12, 0, 0, 132, 0, }, /* 952 */
+ { 132, 21, 12, 0, 0, 132, 0, }, /* 953 */
+ { 0, 2, 14, 0, 0, 0, 0, }, /* 954 */
+ { 10, 26, 11, 0, 0, 10, 0, }, /* 955 */
+ { 27, 26, 12, 0, 0, 27, 0, }, /* 956 */
+ { 10, 24, 3, 0, 0, 10, 0, }, /* 957 */
+ { 10, 1, 3, 0, 0, 10, 0, }, /* 958 */
};
const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
@@ -1150,37 +1185,37 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F000 */
126,126, 98, 98,127,128,129,130,131,131,132,133,134,135,136,137, /* U+F800 */
138,139,140,141,142,143,144,145,146,147,148,142,149,149,150,142, /* U+10000 */
-151,152,153,154,155,156,157,158,159,160,161,142,162,142,163,142, /* U+10800 */
-164,165,166,167,168,169,170,142,171,172,142,173,174,175,176,142, /* U+11000 */
-177,178,142,142,179,180,142,142,181,182,183,184,142,185,142,142, /* U+11800 */
-186,186,186,186,186,186,186,187,188,186,189,142,142,142,142,142, /* U+12000 */
+151,152,153,154,155,156,157,158,159,160,161,142,162,142,163,164, /* U+10800 */
+165,166,167,168,169,170,171,142,172,173,142,174,175,176,177,142, /* U+11000 */
+178,179,142,180,181,182,142,142,183,184,185,186,142,187,142,188, /* U+11800 */
+189,189,189,189,189,189,189,190,191,189,192,142,142,142,142,142, /* U+12000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+12800 */
-190,190,190,190,190,190,190,190,191,142,142,142,142,142,142,142, /* U+13000 */
+193,193,193,193,193,193,193,193,194,142,142,142,142,142,142,142, /* U+13000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+13800 */
-142,142,142,142,142,142,142,142,192,192,192,192,193,142,142,142, /* U+14000 */
+142,142,142,142,142,142,142,142,195,195,195,195,196,142,142,142, /* U+14000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+14800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+15000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+15800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+16000 */
-194,194,194,194,195,196,197,198,142,142,142,142,199,200,201,202, /* U+16800 */
-203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, /* U+17000 */
-203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, /* U+17800 */
-203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,204, /* U+18000 */
-203,203,203,203,203,205,142,142,142,142,142,142,142,142,142,142, /* U+18800 */
+197,197,197,197,198,199,200,201,142,142,142,142,202,203,204,205, /* U+16800 */
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, /* U+17000 */
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, /* U+17800 */
+206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,207, /* U+18000 */
+206,206,206,206,206,208,142,142,142,142,142,142,142,142,142,142, /* U+18800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+19000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+19800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1A000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1A800 */
-206,207,208,209,209,210,142,142,142,142,142,142,142,142,142,142, /* U+1B000 */
-142,142,142,142,142,142,142,142,211,212,142,142,142,142,142,142, /* U+1B800 */
+209,210,211,212,212,213,142,142,142,142,142,142,142,142,142,142, /* U+1B000 */
+142,142,142,142,142,142,142,142,214,215,142,142,142,142,142,142, /* U+1B800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1C000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1C800 */
- 71,213,214,215,216,217,218,142,219,220,221,222,223,224,225,226, /* U+1D000 */
-227,227,227,227,228,229,142,142,142,142,142,142,142,142,142,142, /* U+1D800 */
-230,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1E000 */
-231,232,233,142,142,142,142,142,234,235,142,142,236,237,142,142, /* U+1E800 */
-238,239,240,241,242,243,244,245,244,244,246,244,247,248,249,250, /* U+1F000 */
-251,252,253,254,255,243,243,243,243,243,243,243,243,243,243,256, /* U+1F800 */
+ 71,216,217,218,219,220,221,142,222,223,224,225,226,227,228,229, /* U+1D000 */
+230,230,230,230,231,232,142,142,142,142,142,142,142,142,142,142, /* U+1D800 */
+233,142,234,142,142,235,142,142,142,142,142,142,142,142,142,142, /* U+1E000 */
+236,237,238,142,142,142,142,142,239,240,241,142,242,243,142,142, /* U+1E800 */
+244,245,246,247,248,249,250,251,250,250,252,250,253,254,255,256, /* U+1F000 */
+257,258,259,260,261,262,249,249,249,249,249,249,249,249,249,263, /* U+1F800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+20000 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+20800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+21000 */
@@ -1201,18 +1236,18 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+28800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+29000 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+29800 */
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,257, 98, 98, /* U+2A000 */
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,264, 98, 98, /* U+2A000 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2A800 */
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,258, 98, /* U+2B000 */
-259, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2B800 */
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,265, 98, /* U+2B000 */
+266, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2B800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2C000 */
- 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,260, 98, 98, /* U+2C800 */
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,267, 98, 98, /* U+2C800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2D000 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2D800 */
98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+2E000 */
- 98, 98, 98, 98, 98, 98, 98,261,142,142,142,142,142,142,142,142, /* U+2E800 */
+ 98, 98, 98, 98, 98, 98, 98,268,142,142,142,142,142,142,142,142, /* U+2E800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+2F000 */
- 98, 98, 98, 98,262,142,142,142,142,142,142,142,142,142,142,142, /* U+2F800 */
+ 98, 98, 98, 98,269,142,142,142,142,142,142,142,142,142,142,142, /* U+2F800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+30000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+30800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+31000 */
@@ -1565,8 +1600,8 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DE800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DF000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DF800 */
-263,264,265,266,264,264,264,264,264,264,264,264,264,264,264,264, /* U+E0000 */
-264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264, /* U+E0800 */
+270,271,272,273,271,271,271,271,271,271,271,271,271,271,271,271, /* U+E0000 */
+271,271,271,271,271,271,271,271,271,271,271,271,271,271,271,271, /* U+E0800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E1000 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E1800 */
142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E2000 */
@@ -1628,7 +1663,7 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FE000 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FE800 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FF000 */
-126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,267, /* U+FF800 */
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,274, /* U+FF800 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+100000 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+100800 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+101000 */
@@ -1660,10 +1695,10 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10E000 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10E800 */
126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10F000 */
-126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,267, /* U+10F800 */
+126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,274, /* U+10F800 */
};
-const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
+const uint16_t PRIV(ucd_stage2)[] = { /* 70400 bytes, block = 128 */
/* block 0 */
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -1715,534 +1750,534 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
35, 97, 98, 35, 35, 99, 35, 35, 35, 35, 35, 35, 35,100, 35, 35,
/* block 5 */
-101, 35, 35,101, 35, 35, 35,102,101,103,104,104,105, 35, 35, 35,
- 35, 35,106, 35, 22, 35, 35, 35, 35, 35, 35, 35, 35,107,108, 35,
+101, 35,102,101, 35, 35, 35,103,101,104,105,105,106, 35, 35, 35,
+ 35, 35,107, 35, 22, 35, 35, 35, 35, 35, 35, 35, 35,108,109, 35,
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
-109,109,109,109,109,109,109,109,109,110,110,110,110,110,110,110,
-110,110, 15, 15, 15, 15,110,110,110,110,110,110,110,110,110,110,
-110,110, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-109,109,109,109,109, 15, 15, 15, 15, 15,111,111,110, 15,110, 15,
+110,110,110,110,110,110,110,110,110,111,111,111,111,111,111,111,
+111,111, 15, 15, 15, 15,111,111,111,111,111,111,111,111,111,111,
+111,111, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+110,110,110,110,110, 15, 15, 15, 15, 15,112,112,111, 15,111, 15,
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
/* block 6 */
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,113,112,112,114,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,115,115,115,115,115,115,115,115,115,115,115,115,115,
-116,117,116,117,110,118,116,117,119,119,120,121,121,121, 5,122,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,114,113,113,115,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,116,116,116,116,116,116,116,116,116,116,116,116,116,
+117,118,117,118,111,119,117,118,120,120,121,122,122,122, 5,123,
/* block 7 */
-119,119,119,119,118, 15,123, 5,124,124,124,119,125,119,126,126,
-127,128,129,128,128,130,128,128,131,132,133,128,134,128,128,128,
-135,136,119,137,128,128,138,128,128,139,128,128,140,141,141,141,
-127,142,143,142,142,144,142,142,145,146,147,142,148,142,142,142,
-149,150,151,152,142,142,153,142,142,154,142,142,155,156,156,157,
-158,159,160,160,160,161,162,163,116,117,116,117,116,117,116,117,
-116,117,164,165,164,165,164,165,164,165,164,165,164,165,164,165,
-166,167,168,169,170,171,172,116,117,173,116,117,127,174,174,174,
+120,120,120,120,119, 15,124, 5,125,125,125,120,126,120,127,127,
+128,129,130,129,129,131,129,129,132,133,134,129,135,129,129,129,
+136,137,120,138,129,129,139,129,129,140,129,129,141,142,142,142,
+128,143,144,143,143,145,143,143,146,147,148,143,149,143,143,143,
+150,151,152,153,143,143,154,143,143,155,143,143,156,157,157,158,
+159,160,161,161,161,162,163,164,117,118,117,118,117,118,117,118,
+117,118,165,166,165,166,165,166,165,166,165,166,165,166,165,166,
+167,168,169,170,171,172,173,117,118,174,117,118,128,175,175,175,
/* block 8 */
-175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,
-176,176,177,176,178,176,176,176,176,176,176,176,176,176,179,176,
-176,180,181,176,176,176,176,176,176,176,182,176,176,176,176,176,
-183,183,184,183,185,183,183,183,183,183,183,183,183,183,186,183,
-183,187,188,183,183,183,183,183,183,183,189,183,183,183,183,183,
-190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,
-191,192,193,194,191,192,191,192,191,192,191,192,191,192,191,192,
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
+176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,176,
+177,177,178,177,179,177,177,177,177,177,177,177,177,177,180,177,
+177,181,182,177,177,177,177,177,177,177,183,177,177,177,177,177,
+184,184,185,184,186,184,184,184,184,184,184,184,184,184,187,184,
+184,188,189,184,184,184,184,184,184,184,190,184,184,184,184,184,
+191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,191,
+192,193,194,195,192,193,192,193,192,193,192,193,192,193,192,193,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
/* block 9 */
-191,192,195,196,197,198,198,197,199,199,191,192,191,192,191,192,
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
-200,191,192,191,192,191,192,191,192,191,192,191,192,191,192,201,
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
+192,193,196,197,198,199,199,198,200,200,192,193,192,193,192,193,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
+201,192,193,192,193,192,193,192,193,192,193,192,193,192,193,202,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
/* block 10 */
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
-119,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
-202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,
-202,202,202,202,202,202,202,119,119,203,204,204,204,204,204,204,
-205,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
-206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
+120,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,
+203,203,203,203,203,203,203,120,120,204,205,205,205,205,205,205,
+206,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
+207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,207,
/* block 11 */
-206,206,206,206,206,206,206,205,205,207,208,119,119,209,209,210,
-119,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
-211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,211,
-211,211,211,211,211,211,211,211,211,211,211,211,211,211,212,211,
-213,211,211,213,211,211,213,211,119,119,119,119,119,119,119,119,
-214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,214,
-214,214,214,214,214,214,214,214,214,214,214,119,119,119,119,214,
-214,214,214,213,213,119,119,119,119,119,119,119,119,119,119,119,
+207,207,207,207,207,207,207,206,206,208,209,120,120,210,210,211,
+120,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,212,
+212,212,212,212,212,212,212,212,212,212,212,212,212,212,213,212,
+214,212,212,214,212,212,214,212,120,120,120,120,120,120,120,120,
+215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,215,
+215,215,215,215,215,215,215,215,215,215,215,120,120,120,120,215,
+215,215,215,214,214,120,120,120,120,120,120,120,120,120,120,120,
/* block 12 */
-215,215,215,215,215,216,217,217,217,218,218,219,220,218,221,221,
-222,222,222,222,222,222,222,222,222,222,222,220,223,119,218,220,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-225,224,224,224,224,224,224,224,224,224,224,226,226,226,226,226,
-226,226,226,226,226,226,222,222,222,222,222,222,222,222,222,222,
-227,227,227,227,227,227,227,227,227,227,218,218,218,218,224,224,
-226,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+216,216,216,216,216,217,218,218,218,219,219,220,221,219,222,222,
+223,223,223,223,223,223,223,223,223,223,223,221,224,120,219,221,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+226,225,225,225,225,225,225,225,225,225,225,227,227,227,227,227,
+227,227,227,227,227,227,223,223,223,223,223,223,223,223,223,223,
+228,228,228,228,228,228,228,228,228,228,219,219,219,219,225,225,
+227,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
/* block 13 */
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,228,224,222,222,222,222,222,222,222,216,221,222,
-222,222,222,222,222,229,229,222,222,221,222,222,222,222,224,224,
-230,230,230,230,230,230,230,230,230,230,224,224,224,221,221,224,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,229,225,223,223,223,223,223,223,223,217,222,223,
+223,223,223,223,223,230,230,223,223,222,223,223,223,223,225,225,
+231,231,231,231,231,231,231,231,231,231,225,225,225,222,222,225,
/* block 14 */
-231,231,231,231,231,231,231,231,231,231,231,231,231,231,119,232,
-233,234,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
-233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,233,
+232,232,232,232,232,232,232,232,232,232,232,232,232,232,120,233,
+234,235,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,234,
-234,234,234,234,234,234,234,234,234,234,234,119,119,233,233,233,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
+235,235,235,235,235,235,235,235,235,235,235,120,120,234,234,234,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
/* block 15 */
-235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
-235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,235,
-235,235,235,235,235,235,236,236,236,236,236,236,236,236,236,236,
-236,235,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-237,237,237,237,237,237,237,237,237,237,238,238,238,238,238,238,
-238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,
-238,238,238,238,238,238,238,238,238,238,238,239,239,239,239,239,
-239,239,239,239,240,240,241,242,242,242,240,119,119,239,243,243,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,
+236,236,236,236,236,236,237,237,237,237,237,237,237,237,237,237,
+237,236,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+238,238,238,238,238,238,238,238,238,238,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,239,
+239,239,239,239,239,239,239,239,239,239,239,240,240,240,240,240,
+240,240,240,240,241,241,242,243,243,243,241,120,120,240,244,244,
/* block 16 */
-244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,244,
-244,244,244,244,244,244,245,245,245,245,246,245,245,245,245,245,
-245,245,245,245,246,245,245,245,246,245,245,245,245,245,119,119,
-247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,119,
-248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,
-248,248,248,248,248,248,248,248,248,249,249,249,119,119,250,119,
-233,233,233,233,233,233,233,233,233,233,233,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,245,
+245,245,245,245,245,245,246,246,246,246,247,246,246,246,246,246,
+246,246,246,246,247,246,246,246,247,246,246,246,246,246,120,120,
+248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,120,
+249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,249,
+249,249,249,249,249,249,249,249,249,250,250,250,120,120,251,120,
+234,234,234,234,234,234,234,234,234,234,234,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 17 */
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,119,224,224,224,224,224,224,224,224,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,222,222,222,222,222,222,222,222,222,222,222,222,222,
-222,222,216,222,222,222,222,222,222,222,222,222,222,222,222,222,
-222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,222,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,120,225,225,225,225,225,225,225,225,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,217,223,223,223,223,223,223,223,223,223,223,223,223,223,
+223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,223,
/* block 18 */
-251,251,251,252,253,253,253,253,253,253,253,253,253,253,253,253,
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
-253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
-253,253,253,253,253,253,253,253,253,253,251,252,251,253,252,252,
-252,251,251,251,251,251,251,251,251,252,252,252,252,251,252,252,
-253,254,255,251,251,251,251,251,253,253,253,253,253,253,253,253,
-253,253,251,251,256,257,258,258,258,258,258,258,258,258,258,258,
-259,260,253,253,253,253,253,253,253,253,253,253,253,253,253,253,
+252,252,252,253,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
+254,254,254,254,254,254,254,254,254,254,252,253,252,254,253,253,
+253,252,252,252,252,252,252,252,252,253,253,253,253,252,253,253,
+254,255,256,113,113,252,252,252,254,254,254,254,254,254,254,254,
+254,254,252,252,257,258,259,259,259,259,259,259,259,259,259,259,
+260,261,254,254,254,254,254,254,254,254,254,254,254,254,254,254,
/* block 19 */
-261,262,263,263,119,261,261,261,261,261,261,261,261,119,119,261,
-261,119,119,261,261,261,261,261,261,261,261,261,261,261,261,261,
-261,261,261,261,261,261,261,261,261,119,261,261,261,261,261,261,
-261,119,261,119,119,119,261,261,261,261,119,119,262,261,264,263,
-263,262,262,262,262,119,119,263,263,119,119,263,263,262,261,119,
-119,119,119,119,119,119,119,264,119,119,119,119,261,261,119,261,
-261,261,262,262,119,119,265,265,265,265,265,265,265,265,265,265,
-261,261,266,266,267,267,267,267,267,267,268,266,261,269,262,119,
+262,263,264,264,120,262,262,262,262,262,262,262,262,120,120,262,
+262,120,120,262,262,262,262,262,262,262,262,262,262,262,262,262,
+262,262,262,262,262,262,262,262,262,120,262,262,262,262,262,262,
+262,120,262,120,120,120,262,262,262,262,120,120,263,262,265,264,
+264,263,263,263,263,120,120,264,264,120,120,264,264,263,262,120,
+120,120,120,120,120,120,120,265,120,120,120,120,262,262,120,262,
+262,262,263,263,120,120,266,266,266,266,266,266,266,266,266,266,
+262,262,267,267,268,268,268,268,268,268,269,267,262,270,263,120,
/* block 20 */
-119,270,270,271,119,272,272,272,272,272,272,119,119,119,119,272,
-272,119,119,272,272,272,272,272,272,272,272,272,272,272,272,272,
-272,272,272,272,272,272,272,272,272,119,272,272,272,272,272,272,
-272,119,272,272,119,272,272,119,272,272,119,119,270,119,271,271,
-271,270,270,119,119,119,119,270,270,119,119,270,270,270,119,119,
-119,270,119,119,119,119,119,119,119,272,272,272,272,119,272,119,
-119,119,119,119,119,119,273,273,273,273,273,273,273,273,273,273,
-270,270,272,272,272,270,274,119,119,119,119,119,119,119,119,119,
+120,271,271,272,120,273,273,273,273,273,273,120,120,120,120,273,
+273,120,120,273,273,273,273,273,273,273,273,273,273,273,273,273,
+273,273,273,273,273,273,273,273,273,120,273,273,273,273,273,273,
+273,120,273,273,120,273,273,120,273,273,120,120,271,120,272,272,
+272,271,271,120,120,120,120,271,271,120,120,271,271,271,120,120,
+120,271,120,120,120,120,120,120,120,273,273,273,273,120,273,120,
+120,120,120,120,120,120,274,274,274,274,274,274,274,274,274,274,
+271,271,273,273,273,271,275,120,120,120,120,120,120,120,120,120,
/* block 21 */
-119,275,275,276,119,277,277,277,277,277,277,277,277,277,119,277,
-277,277,119,277,277,277,277,277,277,277,277,277,277,277,277,277,
-277,277,277,277,277,277,277,277,277,119,277,277,277,277,277,277,
-277,119,277,277,119,277,277,277,277,277,119,119,275,277,276,276,
-276,275,275,275,275,275,119,275,275,276,119,276,276,275,119,119,
-277,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-277,277,275,275,119,119,278,278,278,278,278,278,278,278,278,278,
-279,280,119,119,119,119,119,119,119,277,275,275,275,275,275,275,
+120,276,276,277,120,278,278,278,278,278,278,278,278,278,120,278,
+278,278,120,278,278,278,278,278,278,278,278,278,278,278,278,278,
+278,278,278,278,278,278,278,278,278,120,278,278,278,278,278,278,
+278,120,278,278,120,278,278,278,278,278,120,120,276,278,277,277,
+277,276,276,276,276,276,120,276,276,277,120,277,277,276,120,120,
+278,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+278,278,276,276,120,120,279,279,279,279,279,279,279,279,279,279,
+280,281,120,120,120,120,120,120,120,278,276,276,276,276,276,276,
/* block 22 */
-119,281,282,282,119,283,283,283,283,283,283,283,283,119,119,283,
-283,119,119,283,283,283,283,283,283,283,283,283,283,283,283,283,
-283,283,283,283,283,283,283,283,283,119,283,283,283,283,283,283,
-283,119,283,283,119,283,283,283,283,283,119,119,281,283,284,281,
-282,281,281,281,281,119,119,282,282,119,119,282,282,281,119,119,
-119,119,119,119,119,119,281,284,119,119,119,119,283,283,119,283,
-283,283,281,281,119,119,285,285,285,285,285,285,285,285,285,285,
-286,283,287,287,287,287,287,287,119,119,119,119,119,119,119,119,
+120,282,283,283,120,284,284,284,284,284,284,284,284,120,120,284,
+284,120,120,284,284,284,284,284,284,284,284,284,284,284,284,284,
+284,284,284,284,284,284,284,284,284,120,284,284,284,284,284,284,
+284,120,284,284,120,284,284,284,284,284,120,120,282,284,285,282,
+283,282,282,282,282,120,120,283,283,120,120,283,283,282,120,120,
+120,120,120,120,120,120,282,285,120,120,120,120,284,284,120,284,
+284,284,282,282,120,120,286,286,286,286,286,286,286,286,286,286,
+287,284,288,288,288,288,288,288,120,120,120,120,120,120,120,120,
/* block 23 */
-119,119,288,289,119,289,289,289,289,289,289,119,119,119,289,289,
-289,119,289,289,289,289,119,119,119,289,289,119,289,119,289,289,
-119,119,119,289,289,119,119,119,289,289,289,119,119,119,289,289,
-289,289,289,289,289,289,289,289,289,289,119,119,119,119,290,291,
-288,291,291,119,119,119,291,291,291,119,291,291,291,288,119,119,
-289,119,119,119,119,119,119,290,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,292,292,292,292,292,292,292,292,292,292,
-293,293,293,294,295,295,295,295,295,296,295,119,119,119,119,119,
+120,120,289,290,120,290,290,290,290,290,290,120,120,120,290,290,
+290,120,290,290,290,290,120,120,120,290,290,120,290,120,290,290,
+120,120,120,290,290,120,120,120,290,290,290,120,120,120,290,290,
+290,290,290,290,290,290,290,290,290,290,120,120,120,120,291,292,
+289,292,292,120,120,120,292,292,292,120,292,292,292,289,120,120,
+290,120,120,120,120,120,120,291,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,293,293,293,293,293,293,293,293,293,293,
+294,294,294,295,296,296,296,296,296,297,296,120,120,120,120,120,
/* block 24 */
-297,298,298,298,297,299,299,299,299,299,299,299,299,119,299,299,
-299,119,299,299,299,299,299,299,299,299,299,299,299,299,299,299,
-299,299,299,299,299,299,299,299,299,119,299,299,299,299,299,299,
-299,299,299,299,299,299,299,299,299,299,119,119,119,299,297,297,
-297,298,298,298,298,119,297,297,297,119,297,297,297,297,119,119,
-119,119,119,119,119,297,297,119,299,299,299,119,119,119,119,119,
-299,299,297,297,119,119,300,300,300,300,300,300,300,300,300,300,
-119,119,119,119,119,119,119,119,301,301,301,301,301,301,301,302,
+298,299,299,299,298,300,300,300,300,300,300,300,300,120,300,300,
+300,120,300,300,300,300,300,300,300,300,300,300,300,300,300,300,
+300,300,300,300,300,300,300,300,300,120,300,300,300,300,300,300,
+300,300,300,300,300,300,300,300,300,300,120,120,120,300,298,298,
+298,299,299,299,299,120,298,298,298,120,298,298,298,298,120,120,
+120,120,120,120,120,298,298,120,300,300,300,120,120,120,120,120,
+300,300,298,298,120,120,301,301,301,301,301,301,301,301,301,301,
+120,120,120,120,120,120,120,302,303,303,303,303,303,303,303,304,
/* block 25 */
-303,304,305,305,306,303,303,303,303,303,303,303,303,119,303,303,
-303,119,303,303,303,303,303,303,303,303,303,303,303,303,303,303,
-303,303,303,303,303,303,303,303,303,119,303,303,303,303,303,303,
-303,303,303,303,119,303,303,303,303,303,119,119,304,303,305,304,
-305,305,307,305,305,119,304,305,305,119,305,305,304,304,119,119,
-119,119,119,119,119,307,307,119,119,119,119,119,119,119,303,119,
-303,303,304,304,119,119,308,308,308,308,308,308,308,308,308,308,
-119,303,303,119,119,119,119,119,119,119,119,119,119,119,119,119,
+305,306,307,307,308,305,305,305,305,305,305,305,305,120,305,305,
+305,120,305,305,305,305,305,305,305,305,305,305,305,305,305,305,
+305,305,305,305,305,305,305,305,305,120,305,305,305,305,305,305,
+305,305,305,305,120,305,305,305,305,305,120,120,306,305,307,306,
+307,307,309,307,307,120,306,307,307,120,307,307,306,306,120,120,
+120,120,120,120,120,309,309,120,120,120,120,120,120,120,305,120,
+305,305,306,306,120,120,310,310,310,310,310,310,310,310,310,310,
+120,305,305,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 26 */
-309,309,310,310,119,311,311,311,311,311,311,311,311,119,311,311,
-311,119,311,311,311,311,311,311,311,311,311,311,311,311,311,311,
-311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,
-311,311,311,311,311,311,311,311,311,311,311,309,309,311,312,310,
-310,309,309,309,309,119,310,310,310,119,310,310,310,309,313,314,
-119,119,119,119,311,311,311,312,315,315,315,315,315,315,315,311,
-311,311,309,309,119,119,316,316,316,316,316,316,316,316,316,316,
-315,315,315,315,315,315,315,315,315,314,311,311,311,311,311,311,
+311,311,312,312,120,313,313,313,313,313,313,313,313,120,313,313,
+313,120,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
+313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,313,
+313,313,313,313,313,313,313,313,313,313,313,311,311,313,314,312,
+312,311,311,311,311,120,312,312,312,120,312,312,312,311,315,316,
+120,120,120,120,313,313,313,314,317,317,317,317,317,317,317,313,
+313,313,311,311,120,120,318,318,318,318,318,318,318,318,318,318,
+317,317,317,317,317,317,317,317,317,316,313,313,313,313,313,313,
/* block 27 */
-119,119,317,317,119,318,318,318,318,318,318,318,318,318,318,318,
-318,318,318,318,318,318,318,119,119,119,318,318,318,318,318,318,
-318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,
-318,318,119,318,318,318,318,318,318,318,318,318,119,318,119,119,
-318,318,318,318,318,318,318,119,119,119,319,119,119,119,119,320,
-317,317,319,319,319,119,319,119,317,317,317,317,317,317,317,320,
-119,119,119,119,119,119,321,321,321,321,321,321,321,321,321,321,
-119,119,317,317,322,119,119,119,119,119,119,119,119,119,119,119,
+120,120,319,319,120,320,320,320,320,320,320,320,320,320,320,320,
+320,320,320,320,320,320,320,120,120,120,320,320,320,320,320,320,
+320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,
+320,320,120,320,320,320,320,320,320,320,320,320,120,320,120,120,
+320,320,320,320,320,320,320,120,120,120,321,120,120,120,120,322,
+319,319,321,321,321,120,321,120,319,319,319,319,319,319,319,322,
+120,120,120,120,120,120,323,323,323,323,323,323,323,323,323,323,
+120,120,319,319,324,120,120,120,120,120,120,120,120,120,120,120,
/* block 28 */
-119,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
-323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
-323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,
-323,324,323,325,324,324,324,324,324,324,324,119,119,119,119, 6,
-323,323,323,323,323,323,326,324,324,324,324,324,324,324,324,327,
-328,328,328,328,328,328,328,328,328,328,327,327,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+120,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,
+325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,
+325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,325,
+325,326,325,327,326,326,326,326,326,326,326,120,120,120,120, 6,
+325,325,325,325,325,325,328,326,326,326,326,326,326,326,326,329,
+330,330,330,330,330,330,330,330,330,330,329,329,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 29 */
-119,329,329,119,329,119,119,329,329,119,329,119,119,329,119,119,
-119,119,119,119,329,329,329,329,119,329,329,329,329,329,329,329,
-119,329,329,329,119,329,119,329,119,119,329,329,119,329,329,329,
-329,330,329,331,330,330,330,330,330,330,119,330,330,329,119,119,
-329,329,329,329,329,119,332,119,330,330,330,330,330,330,119,119,
-333,333,333,333,333,333,333,333,333,333,119,119,329,329,329,329,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+120,331,331,120,331,120,331,331,331,331,331,120,331,331,331,331,
+331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,331,
+331,331,331,331,120,331,120,331,331,331,331,331,331,331,331,331,
+331,332,331,333,332,332,332,332,332,332,332,332,332,331,120,120,
+331,331,331,331,331,120,334,120,332,332,332,332,332,332,120,120,
+335,335,335,335,335,335,335,335,335,335,120,120,331,331,331,331,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 30 */
-334,335,335,335,336,336,336,336,336,336,336,336,336,336,336,336,
-336,336,336,335,336,335,335,335,337,337,335,335,335,335,335,335,
-338,338,338,338,338,338,338,338,338,338,339,339,339,339,339,339,
-339,339,339,339,335,337,335,337,335,337,340,341,340,341,342,342,
-334,334,334,334,334,334,334,334,119,334,334,334,334,334,334,334,
-334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,
-334,334,334,334,334,334,334,334,334,334,334,334,334,119,119,119,
-119,337,337,337,337,337,337,337,337,337,337,337,337,337,337,342,
+336,337,337,337,338,338,338,338,338,338,338,338,338,338,338,338,
+338,338,338,337,338,337,337,337,339,339,337,337,337,337,337,337,
+340,340,340,340,340,340,340,340,340,340,341,341,341,341,341,341,
+341,341,341,341,337,339,337,339,337,339,342,343,342,343,344,344,
+336,336,336,336,336,336,336,336,120,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,336,
+336,336,336,336,336,336,336,336,336,336,336,336,336,120,120,120,
+120,339,339,339,339,339,339,339,339,339,339,339,339,339,339,344,
/* block 31 */
-337,337,337,337,337,336,337,337,334,334,334,334,334,337,337,337,
-337,337,337,337,337,337,337,337,119,337,337,337,337,337,337,337,
-337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,
-337,337,337,337,337,337,337,337,337,337,337,337,337,119,335,335,
-335,335,335,335,335,335,337,335,335,335,335,335,335,119,335,335,
-336,336,336,336,336, 20, 20, 20, 20,336,336,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+339,339,339,339,339,338,339,339,336,336,336,336,336,339,339,339,
+339,339,339,339,339,339,339,339,120,339,339,339,339,339,339,339,
+339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,
+339,339,339,339,339,339,339,339,339,339,339,339,339,120,337,337,
+337,337,337,337,337,337,339,337,337,337,337,337,337,120,337,337,
+338,338,338,338,338, 20, 20, 20, 20,338,338,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 32 */
-343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,
-343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,
-343,343,343,343,343,343,343,343,343,343,343,344,344,345,345,345,
-345,346,345,345,345,345,345,345,344,345,345,346,346,345,345,343,
-347,347,347,347,347,347,347,347,347,347,348,348,348,348,348,348,
-343,343,343,343,343,343,346,346,345,345,343,343,343,343,345,345,
-345,343,344,344,344,343,343,344,344,344,344,344,344,344,343,343,
-343,345,345,345,345,343,343,343,343,343,343,343,343,343,343,343,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+345,345,345,345,345,345,345,345,345,345,345,346,346,347,347,347,
+347,348,347,347,347,347,347,347,346,347,347,348,348,347,347,345,
+349,349,349,349,349,349,349,349,349,349,350,350,350,350,350,350,
+345,345,345,345,345,345,348,348,347,347,345,345,345,345,347,347,
+347,345,346,346,346,345,345,346,346,346,346,346,346,346,345,345,
+345,347,347,347,347,345,345,345,345,345,345,345,345,345,345,345,
/* block 33 */
-343,343,345,344,346,345,345,344,344,344,344,344,344,345,343,344,
-349,349,349,349,349,349,349,349,349,349,344,344,344,345,350,350,
-351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,
-351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,
-351,351,351,351,351,351,119,351,119,119,119,119,119,351,119,119,
-352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,
-352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,352,
-352,352,352,352,352,352,352,352,352,352,352,353,354,352,352,352,
+345,345,347,346,348,347,347,346,346,346,346,346,346,347,345,346,
+351,351,351,351,351,351,351,351,351,351,346,346,346,347,352,352,
+353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,
+353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,353,
+353,353,353,353,353,353,120,353,120,120,120,120,120,353,120,120,
+354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,
+354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,354,
+354,354,354,354,354,354,354,354,354,354,354,355,356,354,354,354,
/* block 34 */
-355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,
-355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,
-355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,
-355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,
-355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,
-355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,
-356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
-356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
-
-/* block 35 */
-356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
-356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
-356,356,356,356,356,356,356,356,357,357,357,357,357,357,357,357,
357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
-
-/* block 36 */
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,119,358,358,358,358,119,119,
-358,358,358,358,358,358,358,119,358,119,358,358,358,358,119,119,
+
+/* block 35 */
358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+358,358,358,358,358,358,358,358,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+
+/* block 36 */
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,120,360,360,360,360,120,120,
+360,360,360,360,360,360,360,120,360,120,360,360,360,360,120,120,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
/* block 37 */
-358,358,358,358,358,358,358,358,358,119,358,358,358,358,119,119,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,119,358,358,358,358,119,119,358,358,358,358,358,358,358,119,
-358,119,358,358,358,358,119,119,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+360,360,360,360,360,360,360,360,360,120,360,360,360,360,120,120,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,120,
+360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
/* block 38 */
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,119,358,358,358,358,119,119,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,358,358,358,358,119,119,359,359,359,
-360,360,360,360,360,360,360,360,360,361,361,361,361,361,361,361,
-361,361,361,361,361,361,361,361,361,361,361,361,361,119,119,119,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,120,360,360,360,360,120,120,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,360,360,360,360,120,120,361,361,361,
+362,362,362,362,362,362,362,362,362,363,363,363,363,363,363,363,
+363,363,363,363,363,363,363,363,363,363,363,363,363,120,120,120,
/* block 39 */
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-362,362,362,362,362,362,362,362,362,362,119,119,119,119,119,119,
-363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,
-363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,
-363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,
-363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,
-363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,
-364,364,364,364,364,364,119,119,365,365,365,365,365,365,119,119,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+364,364,364,364,364,364,364,364,364,364,120,120,120,120,120,120,
+365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
+365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
+365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
+365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
+365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,365,
+366,366,366,366,366,366,120,120,367,367,367,367,367,367,120,120,
/* block 40 */
-366,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
+368,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
/* block 41 */
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
/* block 42 */
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,368,368,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,370,371,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
/* block 43 */
-369,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370,
-370,370,370,370,370,370,370,370,370,370,370,371,372,119,119,119,
-373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
-373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
-373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
-373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
-373,373,373,373,373,373,373,373,373,373,373, 5, 5, 5,374,374,
-374,373,373,373,373,373,373,373,373,119,119,119,119,119,119,119,
+372,373,373,373,373,373,373,373,373,373,373,373,373,373,373,373,
+373,373,373,373,373,373,373,373,373,373,373,374,375,120,120,120,
+376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,
+376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,
+376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,
+376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,376,
+376,376,376,376,376,376,376,376,376,376,376, 5, 5, 5,377,377,
+377,376,376,376,376,376,376,376,376,120,120,120,120,120,120,120,
/* block 44 */
-375,375,375,375,375,375,375,375,375,375,375,375,375,119,375,375,
-375,375,376,376,376,119,119,119,119,119,119,119,119,119,119,119,
-377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,
-377,377,378,378,378,379,379,119,119,119,119,119,119,119,119,119,
+378,378,378,378,378,378,378,378,378,378,378,378,378,120,378,378,
+378,378,379,379,379,120,120,120,120,120,120,120,120,120,120,120,
380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,
-380,380,381,381,119,119,119,119,119,119,119,119,119,119,119,119,
-382,382,382,382,382,382,382,382,382,382,382,382,382,119,382,382,
-382,119,383,383,119,119,119,119,119,119,119,119,119,119,119,119,
+380,380,381,381,381,382,382,120,120,120,120,120,120,120,120,120,
+383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,383,
+383,383,384,384,120,120,120,120,120,120,120,120,120,120,120,120,
+385,385,385,385,385,385,385,385,385,385,385,385,385,120,385,385,
+385,120,386,386,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 45 */
-384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,
-384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,
-384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,
-384,384,384,384,385,385,386,385,385,385,385,385,385,385,386,386,
-386,386,386,386,386,386,385,386,386,385,385,385,385,385,385,385,
-385,385,385,385,387,387,387,388,387,387,387,389,384,385,119,119,
-390,390,390,390,390,390,390,390,390,390,119,119,119,119,119,119,
-391,391,391,391,391,391,391,391,391,391,119,119,119,119,119,119,
+387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
+387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
+387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,387,
+387,387,387,387,388,388,389,388,388,388,388,388,388,388,389,389,
+389,389,389,389,389,389,388,389,389,388,388,388,388,388,388,388,
+388,388,388,388,390,390,390,391,390,390,390,392,387,388,120,120,
+393,393,393,393,393,393,393,393,393,393,120,120,120,120,120,120,
+394,394,394,394,394,394,394,394,394,394,120,120,120,120,120,120,
/* block 46 */
-392,392,393,393,392,393,394,392,392,392,392,395,395,395,396,119,
-397,397,397,397,397,397,397,397,397,397,119,119,119,119,119,119,
-398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,
-398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,
-398,398,398,399,398,398,398,398,398,398,398,398,398,398,398,398,
-398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,
-398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,
-398,398,398,398,398,398,398,398,398,119,119,119,119,119,119,119,
+395,395,396,396,395,396,397,395,395,395,395,398,398,398,399,120,
+400,400,400,400,400,400,400,400,400,400,120,120,120,120,120,120,
+401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
+401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
+401,401,401,402,401,401,401,401,401,401,401,401,401,401,401,401,
+401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
+401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
+401,401,401,401,401,401,401,401,401,120,120,120,120,120,120,120,
/* block 47 */
-398,398,398,398,398,395,395,398,398,398,398,398,398,398,398,398,
-398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,
-398,398,398,398,398,398,398,398,398,395,398,119,119,119,119,119,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,
-367,367,367,367,367,367,119,119,119,119,119,119,119,119,119,119,
+401,401,401,401,401,398,398,401,401,401,401,401,401,401,401,401,
+401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,401,
+401,401,401,401,401,401,401,401,401,398,401,120,120,120,120,120,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,369,
+369,369,369,369,369,369,120,120,120,120,120,120,120,120,120,120,
/* block 48 */
-400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,
-400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,119,
-401,401,401,402,402,402,402,401,401,402,402,402,119,119,119,119,
-402,402,401,402,402,402,402,402,402,401,401,401,119,119,119,119,
-403,119,119,119,404,404,405,405,405,405,405,405,405,405,405,405,
-406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,
-406,406,406,406,406,406,406,406,406,406,406,406,406,406,119,119,
-406,406,406,406,406,119,119,119,119,119,119,119,119,119,119,119,
+403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,
+403,403,403,403,403,403,403,403,403,403,403,403,403,403,403,120,
+404,404,404,405,405,405,405,404,404,405,405,405,120,120,120,120,
+405,405,404,405,405,405,405,405,405,404,404,404,120,120,120,120,
+406,120,120,120,407,407,408,408,408,408,408,408,408,408,408,408,
+409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,409,
+409,409,409,409,409,409,409,409,409,409,409,409,409,409,120,120,
+409,409,409,409,409,120,120,120,120,120,120,120,120,120,120,120,
/* block 49 */
-407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,
-407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,
-407,407,407,407,407,407,407,407,407,407,407,407,119,119,119,119,
-407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,
-407,407,407,407,407,407,407,407,407,407,119,119,119,119,119,119,
-408,408,408,408,408,408,408,408,408,408,409,119,119,119,410,410,
-411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,
-411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,410,410,120,120,120,120,
+410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,410,
+410,410,410,410,410,410,410,410,410,410,120,120,120,120,120,120,
+411,411,411,411,411,411,411,411,411,411,412,120,120,120,413,413,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
+414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,414,
/* block 50 */
-412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,
-412,412,412,412,412,412,412,413,413,414,414,413,119,119,415,415,
-416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
-416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
-416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,
-416,416,416,416,416,417,418,417,418,418,418,418,418,418,418,119,
-418,419,418,419,419,418,418,418,418,418,418,418,418,417,417,417,
-417,417,417,418,418,418,418,418,418,418,418,418,418,119,119,418,
+415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,415,
+415,415,415,415,415,415,415,416,416,417,417,416,120,120,418,418,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,419,
+419,419,419,419,419,420,421,420,421,421,421,421,421,421,421,120,
+421,422,421,422,422,421,421,421,421,421,421,421,421,420,420,420,
+420,420,420,421,421,421,421,421,421,421,421,421,421,120,120,421,
/* block 51 */
-420,420,420,420,420,420,420,420,420,420,119,119,119,119,119,119,
-420,420,420,420,420,420,420,420,420,420,119,119,119,119,119,119,
-421,421,421,421,421,421,421,422,421,421,421,421,421,421,119,119,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,423,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+423,423,423,423,423,423,423,423,423,423,120,120,120,120,120,120,
+423,423,423,423,423,423,423,423,423,423,120,120,120,120,120,120,
+424,424,424,424,424,424,424,425,424,424,424,424,424,424,120,120,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,426,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 52 */
-424,424,424,424,425,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,
-426,426,426,426,424,425,424,424,424,424,424,425,424,425,425,425,
-425,425,424,425,425,426,426,426,426,426,426,426,119,119,119,119,
-427,427,427,427,427,427,427,427,427,427,428,428,428,428,428,428,
-428,429,429,429,429,429,429,429,429,429,429,424,424,424,424,424,
-424,424,424,424,429,429,429,429,429,429,429,429,429,119,119,119,
+427,427,427,427,428,429,429,429,429,429,429,429,429,429,429,429,
+429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
+429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,429,
+429,429,429,429,427,430,427,427,427,427,427,428,427,428,428,428,
+428,428,427,428,428,429,429,429,429,429,429,429,120,120,120,120,
+431,431,431,431,431,431,431,431,431,431,432,432,432,432,432,432,
+432,433,433,433,433,433,433,433,433,433,433,427,427,427,427,427,
+427,427,427,427,433,433,433,433,433,433,433,433,433,120,120,120,
/* block 53 */
-430,430,431,432,432,432,432,432,432,432,432,432,432,432,432,432,
-432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,
-432,431,430,430,430,430,431,431,430,430,431,430,430,430,432,432,
-433,433,433,433,433,433,433,433,433,433,432,432,432,432,432,432,
-434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,
-434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,
-434,434,434,434,434,434,435,436,435,435,436,436,436,435,436,435,
-435,435,436,436,119,119,119,119,119,119,119,119,437,437,437,437,
-
-/* block 54 */
+434,434,435,436,436,436,436,436,436,436,436,436,436,436,436,436,
+436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,436,
+436,435,434,434,434,434,435,435,434,434,435,434,434,434,436,436,
+437,437,437,437,437,437,437,437,437,437,436,436,436,436,436,436,
438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,438,
-438,438,438,438,439,439,439,439,439,439,439,439,440,440,440,440,
-440,440,440,440,439,439,440,440,119,119,119,441,441,441,441,441,
-442,442,442,442,442,442,442,442,442,442,119,119,119,438,438,438,
-443,443,443,443,443,443,443,443,443,443,444,444,444,444,444,444,
-444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,
-444,444,444,444,444,444,444,444,445,445,445,445,445,445,446,446,
+438,438,438,438,438,438,439,440,439,439,440,440,440,439,440,439,
+439,439,440,440,120,120,120,120,120,120,120,120,441,441,441,441,
+
+/* block 54 */
+442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,
+442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,442,
+442,442,442,442,443,443,443,443,443,443,443,443,444,444,444,444,
+444,444,444,444,443,443,444,444,120,120,120,445,445,445,445,445,
+446,446,446,446,446,446,446,446,446,446,120,120,120,442,442,442,
+447,447,447,447,447,447,447,447,447,447,448,448,448,448,448,448,
+448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,448,
+448,448,448,448,448,448,448,448,449,449,449,449,449,449,450,450,
/* block 55 */
-447,448,449,450,451,452,453,454,455,119,119,119,119,119,119,119,
-456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,
-456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,
-456,456,456,456,456,456,456,456,456,456,456,119,119,456,456,456,
-457,457,457,457,457,457,457,457,119,119,119,119,119,119,119,119,
-458,459,458,460,459,461,461,462,461,462,463,459,462,462,459,459,
-462,464,459,459,459,459,459,459,459,465,466,465,465,461,465,465,
-465,465,467,467,468,466,466,469,470,470,119,119,119,119,119,119,
+451,452,453,454,455,456,457,458,459,120,120,120,120,120,120,120,
+460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
+460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,460,
+460,460,460,460,460,460,460,460,460,460,460,120,120,460,460,460,
+461,461,461,461,461,461,461,461,120,120,120,120,120,120,120,120,
+462,463,462,464,463,465,465,466,465,466,467,463,466,466,463,463,
+466,468,463,463,463,463,463,463,463,469,470,471,471,465,471,471,
+471,471,472,473,474,470,470,475,476,476,477,120,120,120,120,120,
/* block 56 */
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35,127,127,127,127,127,471,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,120,120,120,
-120,120,109,109,109,109,120,120,120,120,120, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35,472,473, 35, 35, 35,474, 35, 35,
+ 35, 35, 35, 35, 35, 35,128,128,128,128,128,478,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,121,121,121,
+121,121,110,110,110,110,121,121,121,121,121, 35, 35, 35, 35, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35,479,480, 35, 35, 35,481, 35, 35,
/* block 57 */
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,
-109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,120,
-113,113,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,119,112,112,112,112,112,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,482, 35,
+ 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,
+110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,121,
+114,114,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,120,113,113,113,113,113,
/* block 58 */
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
@@ -2251,12 +2286,12 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
-475,476, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
+483,484, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
/* block 59 */
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
- 32, 33, 32, 33, 32, 33, 35, 35, 35, 35, 35,477, 35, 35,478, 35,
+ 32, 33, 32, 33, 32, 33, 35, 35, 35, 35, 35,485, 35, 35,486, 35,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
@@ -2265,58 +2300,58 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
/* block 60 */
-479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480,
-479,479,479,479,479,479,119,119,480,480,480,480,480,480,119,119,
-479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480,
-479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480,
-479,479,479,479,479,479,119,119,480,480,480,480,480,480,119,119,
-127,479,127,479,127,479,127,479,119,480,119,480,119,480,119,480,
-479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480,
-481,481,482,482,482,482,483,483,484,484,485,485,486,486,119,119,
+487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488,
+487,487,487,487,487,487,120,120,488,488,488,488,488,488,120,120,
+487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488,
+487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488,
+487,487,487,487,487,487,120,120,488,488,488,488,488,488,120,120,
+128,487,128,487,128,487,128,487,120,488,120,488,120,488,120,488,
+487,487,487,487,487,487,487,487,488,488,488,488,488,488,488,488,
+489,489,490,490,490,490,491,491,492,492,493,493,494,494,120,120,
/* block 61 */
-479,479,479,479,479,479,479,479,487,487,487,487,487,487,487,487,
-479,479,479,479,479,479,479,479,487,487,487,487,487,487,487,487,
-479,479,479,479,479,479,479,479,487,487,487,487,487,487,487,487,
-479,479,127,488,127,119,127,127,480,480,489,489,490,118,491,118,
-118,118,127,488,127,119,127,127,492,492,492,492,490,118,118,118,
-479,479,127,127,119,119,127,127,480,480,493,493,119,118,118,118,
-479,479,127,127,127,168,127,127,480,480,494,494,173,118,118,118,
-119,119,127,488,127,119,127,127,495,495,496,496,490,118,118,119,
+487,487,487,487,487,487,487,487,495,495,495,495,495,495,495,495,
+487,487,487,487,487,487,487,487,495,495,495,495,495,495,495,495,
+487,487,487,487,487,487,487,487,495,495,495,495,495,495,495,495,
+487,487,128,496,128,120,128,128,488,488,497,497,498,119,499,119,
+119,119,128,496,128,120,128,128,500,500,500,500,498,119,119,119,
+487,487,128,128,120,120,128,128,488,488,501,501,120,119,119,119,
+487,487,128,128,128,169,128,128,488,488,502,502,174,119,119,119,
+120,120,128,496,128,120,128,128,503,503,504,504,498,119,119,120,
/* block 62 */
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24,497,498, 24, 24,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24,505,506, 24, 24,
10, 10, 10, 10, 10, 10, 5, 5, 23, 27, 7, 23, 23, 27, 7, 23,
- 5, 5, 5, 5, 5, 5, 5, 5,499,500, 24, 24, 24, 24, 24, 4,
- 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, 27, 5,501, 5, 5, 16,
- 16, 5, 5, 5, 9, 7, 8, 5, 5,501, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,507,508, 24, 24, 24, 24, 24,509,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, 27, 5,510, 5, 5, 16,
+ 16, 5, 5, 5, 9, 7, 8, 5, 5,510, 5, 5, 5, 5, 5, 5,
5, 5, 9, 5, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4,
- 24, 24, 24, 24, 24,502, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
- 25,109,119,119, 25, 25, 25, 25, 25, 25, 9, 9, 9, 7, 8,109,
+ 24, 24, 24, 24, 24,511, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 25,110,120,120, 25, 25, 25, 25, 25, 25, 9, 9, 9, 7, 8,110,
/* block 63 */
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 9, 9, 9, 7, 8,119,
-109,109,109,109,109,109,109,109,109,109,109,109,109,119,119,119,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 9, 9, 9, 7, 8,120,
+110,110,110,110,110,110,110,110,110,110,110,110,110,120,120,120,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-112,112,112,112,112,112,112,112,112,112,112,112,112,423,423,423,
-423,112,423,423,423,112,112,112,112,112,112,112,112,112,112,112,
-503,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+113,113,113,113,113,113,113,113,113,113,113,113,113,426,426,426,
+426,113,426,426,426,113,113,113,113,113,113,113,113,113,113,113,
+512,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 64 */
- 20, 20,504, 20, 20, 20, 20,504, 20, 20,505,504,504,504,505,505,
-504,504,504,505, 20,504, 20, 20, 9,504,504,504,504,504, 20, 20,
- 20, 20, 21, 20,504, 20,506, 20,504, 20,507,508,504,504, 20,505,
-504,504,509,504,505,510,510,510,510,511, 20, 20,505,505,504,504,
- 9, 9, 9, 9, 9,504,505,505,505,505, 20, 9, 20, 20,512, 20,
+ 20, 20,513, 20, 20, 20, 20,513, 20, 20,514,513,513,513,514,514,
+513,513,513,514, 20,513, 20, 20, 9,513,513,513,513,513, 20, 20,
+ 20, 20, 21, 20,513, 20,515, 20,513, 20,516,517,513,513, 20,514,
+513,513,518,513,514,519,519,519,519,520, 20, 20,514,514,513,513,
+ 9, 9, 9, 9, 9,513,514,514,514,514, 20, 9, 20, 20,521, 20,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
-514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
+523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,
/* block 65 */
-515,515,515, 32, 33,515,515,515,515, 25, 20, 20,119,119,119,119,
- 9, 9, 9, 9,516, 21, 21, 21, 21, 21, 9, 9, 20, 20, 20, 20,
+524,524,524, 32, 33,524,524,524,524, 25, 20, 20,120,120,120,120,
+ 9, 9, 9, 9,525, 21, 21, 21, 21, 21, 9, 9, 20, 20, 20, 20,
9, 20, 20, 9, 20, 20, 9, 20, 20, 21, 21, 20, 20, 20, 9, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 9, 9,
@@ -2357,10 +2392,10 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
/* block 69 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+ 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
@@ -2368,10 +2403,10 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20,517,517,517,517,517,517,517,517,517,517,
-517,517,518,517,517,517,517,517,517,517,517,517,517,517,517,517,
-519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,
-519,519,519,519,519,519,519,519,519,519, 25, 25, 25, 25, 25, 25,
+ 20, 20, 20, 20, 20, 20,526,526,526,526,526,526,526,526,526,526,
+526,526,527,526,526,526,526,526,526,526,526,526,526,526,526,526,
+528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,528,
+528,528,528,528,528,528,528,528,528,528, 25, 25, 25, 25, 25, 25,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
/* block 71 */
@@ -2392,7 +2427,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
21, 9, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 9, 9, 9,516,516,516,516, 9,
+ 20, 20, 20, 20, 20, 20, 20, 20, 9, 9, 9,525,525,525,525, 9,
/* block 73 */
21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -2401,7 +2436,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,516,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,525,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
/* block 74 */
@@ -2435,20 +2470,20 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
/* block 77 */
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
-520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
+529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,529,
/* block 78 */
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
- 9, 9, 9, 9,516,516, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9,525,525, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
@@ -2472,167 +2507,167 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
9, 9, 9, 9, 9, 20, 20, 9, 9, 9, 9, 9, 9, 20, 20, 20,
21, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20,119,119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
/* block 81 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20,119,119, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20,119, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119,
/* block 82 */
-521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,
-521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,
-521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,119,
-522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
-522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,
-522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,119,
- 32, 33,523,524,525,526,527, 32, 33, 32, 33, 32, 33,528,529,530,
-531, 35, 32, 33, 35, 32, 33, 35, 35, 35, 35, 35,109,109,532,532,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,
+530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,120,
+531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,
+531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,
+531,531,531,531,531,531,531,531,531,531,531,531,531,531,531,120,
+ 32, 33,532,533,534,535,536, 32, 33, 32, 33, 32, 33,537,538,539,
+540, 35, 32, 33, 35, 32, 33, 35, 35, 35, 35, 35,110,110,541,541,
/* block 83 */
-164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165,
-164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165,
-164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165,
-164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165,
-164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165,
-164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165,
-164,165,164,165,533,534,534,534,534,534,534,164,165,164,165,535,
-535,535,164,165,119,119,119,119,119,536,536,536,536,537,536,536,
+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,
+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,
+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,
+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,
+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,
+165,166,165,166,165,166,165,166,165,166,165,166,165,166,165,166,
+165,166,165,166,542,543,543,543,543,543,543,165,166,165,166,544,
+544,544,165,166,120,120,120,120,120,545,545,545,545,546,545,545,
/* block 84 */
-538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
-538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,
-538,538,538,538,538,538,119,538,119,119,119,119,119,538,119,119,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,
-539,539,539,539,539,539,539,539,119,119,119,119,119,119,119,540,
-541,119,119,119,119,119,119,119,119,119,119,119,119,119,119,542,
+547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,
+547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,547,
+547,547,547,547,547,547,120,547,120,120,120,120,120,547,120,120,
+548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
+548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
+548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,548,
+548,548,548,548,548,548,548,548,120,120,120,120,120,120,120,549,
+550,120,120,120,120,120,120,120,120,120,120,120,120,120,120,551,
/* block 85 */
-358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
-358,358,358,358,358,358,358,119,119,119,119,119,119,119,119,119,
-358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119,
-358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119,
-358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119,
-358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
-543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,
+360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,
+360,360,360,360,360,360,360,120,120,120,120,120,120,120,120,120,
+360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120,
+360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120,
+360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120,
+360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120,
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
+552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,
/* block 86 */
5, 5, 23, 27, 23, 27, 5, 5, 5, 23, 27, 5, 23, 27, 5, 5,
5, 5, 5, 5, 5, 5, 5, 10, 5, 5, 10, 5, 23, 27, 5, 5,
- 23, 27, 7, 8, 7, 8, 7, 8, 7, 8, 5, 5, 5, 5, 5,110,
+ 23, 27, 7, 8, 7, 8, 7, 8, 7, 8, 5, 5, 5, 5, 5,111,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 5, 5, 5, 5,
- 10, 5, 7,544, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+ 10, 5, 7,553, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 87 */
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,119,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,119,119,119,119,119,119,119,119,119,119,119,119,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,120,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 88 */
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
/* block 89 */
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,
-545,545,545,545,545,545,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,554,
+554,554,554,554,554,554,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,
/* block 90 */
- 4,546,546,547, 20,548,549,550,551,552,551,552,551,552,551,552,
-551,552, 20,553,551,552,551,552,551,552,551,552,554,555,556,556,
- 20,550,550,550,550,550,550,550,550,550,557,557,557,557,558,558,
-559,560,560,560,560,560, 20,553,550,550,550,548,561,562,563,563,
-119,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
+ 4,555,555,556, 20,557,558,559,560,561,560,561,560,561,560,561,
+560,561, 20,562,560,561,560,561,560,561,560,561,563,564,565,565,
+ 20,559,559,559,559,559,559,559,559,559,566,566,566,566,567,567,
+568,569,569,569,569,569, 20,562,559,559,559,557,570,571,572,572,
+120,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
/* block 91 */
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,119,119,565,565,566,566,567,567,564,
-568,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
-569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
-569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
-569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
-569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
-569,569,569,569,569,569,569,569,569,569,569,546,560,570,570,569,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,120,120,574,574,575,575,576,576,573,
+577,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+578,578,578,578,578,578,578,578,578,578,578,555,569,579,579,578,
/* block 92 */
-119,119,119,119,119,571,571,571,571,571,571,571,571,571,571,571,
-571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
-571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
-119,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
-572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
-572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
-572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
-572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
+120,120,120,120,120,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+120,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
+581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
+581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
+581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
+581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
/* block 93 */
-572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,119,
-563,563,573,573,573,573,563,563,563,563,563,563,563,563,563,563,
-571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,
-571,571,571,571,571,571,571,571,571,571,571,119,119,119,119,119,
-563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563,563,563,563,119,119,119,119,119,119,119,119,119,119,119,119,
-569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
+581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,120,
+572,572,582,582,582,582,572,572,572,572,572,572,572,572,572,572,
+580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
+580,580,580,580,580,580,580,580,580,580,580,120,120,120,120,120,
+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
+572,572,572,572,120,120,120,120,120,120,120,120,120,120,120,120,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
/* block 94 */
-574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,
-574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,119,
-573,573,573,573,573,573,573,573,573,573,563,563,563,563,563,563,
-563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563,563,563,563,563,563,563,563, 25, 25, 25, 25, 25, 25, 25, 25,
+583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,
+583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,120,
+582,582,582,582,582,582,582,582,582,582,572,572,572,572,572,572,
+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
+572,572,572,572,572,572,572,572, 25, 25, 25, 25, 25, 25, 25, 25,
20, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,
-574,574,574,574,574,574,574,574,574,574,574,574,574,574,574, 20,
+583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,583,
+583,583,583,583,583,583,583,583,583,583,583,583,583,583,583, 20,
/* block 95 */
-573,573,573,573,573,573,573,573,573,573,563,563,563,563,563,563,
-563,563,563,563,563,563,563,575,563,575,563,563,563,563,563,563,
-563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-563,563,563,563,563,563,563,563,563,563,563,563, 20, 20, 20, 20,
-576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,
-576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,
-576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,119,
+582,582,582,582,582,582,582,582,582,582,572,572,572,572,572,572,
+572,572,572,572,572,572,572,584,572,584,572,572,572,572,572,572,
+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
+572, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+572,572,572,572,572,572,572,572,572,572,572,572, 20, 20, 20, 20,
+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,
+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,
+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,572,
/* block 96 */
-576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,
-576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,
-576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,
-576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,
-576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,
-576,576,576,576,576,576,576,576,563,563,563,563,563,563,563,563,
-563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,563,563,563,563,563,
+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,
+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,
+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,
+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,
+585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,585,
+585,585,585,585,585,585,585,585,572,572,572,572,572,572,572,572,
+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
+572, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,572,572,572,572,572,
/* block 97 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
@@ -2641,1160 +2676,1190 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,
-563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, 20,
+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
+572,572,572,572,572,572,572,572,572,572,572,572,572,572,572, 20,
/* block 98 */
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
/* block 99 */
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,119,119,119,119,119,119,119,119,119,119,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,120,120,120,120,120,120,120,120,120,120,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
/* block 100 */
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 101 */
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,579,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,588,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
/* block 102 */
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
-578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
+587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,587,
/* block 103 */
-578,578,578,578,578,578,578,578,578,578,578,578,578,119,119,119,
-580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
-580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
-580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,580,
-580,580,580,580,580,580,580,119,119,119,119,119,119,119,119,119,
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
-581,581,581,581,581,581,581,581,582,582,582,582,582,582,583,583,
+587,587,587,587,587,587,587,587,587,587,587,587,587,120,120,120,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,589,
+589,589,589,589,589,589,589,120,120,120,120,120,120,120,120,120,
+590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,
+590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,590,
+590,590,590,590,590,590,590,590,591,591,591,591,591,591,592,592,
/* block 104 */
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
/* block 105 */
-584,584,584,584,584,584,584,584,584,584,584,584,585,586,586,586,
-584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,
-587,587,587,587,587,587,587,587,587,587,584,584,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-191,192,191,192,191,192,191,192,191,192,588,589,191,192,191,192,
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,590,197,
-199,199,199,591,543,543,543,543,543,543,543,543,543,543,591,472,
+593,593,593,593,593,593,593,593,593,593,593,593,594,595,595,595,
+593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,593,
+596,596,596,596,596,596,596,596,596,596,593,593,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+192,193,192,193,192,193,192,193,192,193,597,598,192,193,192,193,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,599,198,
+200,200,200,600,552,552,552,552,552,552,552,552,552,552,600,479,
/* block 106 */
-191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192,
-191,192,191,192,191,192,191,192,191,192,191,192,472,472,543,543,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,593,593,593,593,593,593,593,593,593,593,
-594,594,595,595,595,595,595,595,119,119,119,119,119,119,119,119,
+192,193,192,193,192,193,192,193,192,193,192,193,192,193,192,193,
+192,193,192,193,192,193,192,193,192,193,192,193,479,479,552,552,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,602,602,602,602,602,602,602,602,602,602,
+603,603,604,604,604,604,604,604,120,120,120,120,120,120,120,120,
/* block 107 */
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15,110,110,110,110,110,110,110,110,110,
+ 15, 15, 15, 15, 15, 15, 15,111,111,111,111,111,111,111,111,111,
15, 15, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
35, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
-109, 35, 35, 35, 35, 35, 35, 35, 35, 32, 33, 32, 33,596, 32, 33,
+110, 35, 35, 35, 35, 35, 35, 35, 35, 32, 33, 32, 33,605, 32, 33,
/* block 108 */
- 32, 33, 32, 33, 32, 33, 32, 33,110, 15, 15, 32, 33,597, 35, 22,
- 32, 33, 32, 33, 35, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
- 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,598,599,600,601,598, 35,
-602,603,604,605, 32, 33, 32, 33, 32, 33,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119, 22,109,109, 35, 22, 22, 22, 22, 22,
+ 32, 33, 32, 33, 32, 33, 32, 33,111, 15, 15, 32, 33,606, 35, 22,
+ 32, 33, 32, 33,607, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
+ 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,608,609,610,611,608, 35,
+612,613,614,615, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33,
+120,120, 32, 33,616,617,618,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120, 22,110,110, 35, 22, 22, 22, 22, 22,
/* block 109 */
-606,606,607,606,606,606,607,606,606,606,606,607,606,606,606,606,
-606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,
-606,606,606,608,608,607,607,608,609,609,609,609,119,119,119,119,
-610,610,610,611,611,611,612,612,613,612,119,119,119,119,119,119,
-614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,
-614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,
-614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,
-614,614,614,614,615,615,615,615,119,119,119,119,119,119,119,119,
+619,619,620,619,619,619,620,619,619,619,619,620,619,619,619,619,
+619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,
+619,619,619,621,621,620,620,621,622,622,622,622,120,120,120,120,
+623,623,623,624,624,624,625,625,626,625,120,120,120,120,120,120,
+627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,
+627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,
+627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,627,
+627,627,627,627,628,628,628,628,120,120,120,120,120,120,120,120,
/* block 110 */
-616,616,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,
-617,617,617,617,616,616,616,616,616,616,616,616,616,616,616,616,
-616,616,616,616,618,618,119,119,119,119,119,119,119,119,619,619,
-620,620,620,620,620,620,620,620,620,620,119,119,119,119,119,119,
-251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,
-251,621,253,622,253,253,253,253,259,259,259,253,259,253,253,251,
+629,629,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
+630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
+630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,
+630,630,630,630,629,629,629,629,629,629,629,629,629,629,629,629,
+629,629,629,629,631,631,120,120,120,120,120,120,120,120,632,632,
+633,633,633,633,633,633,633,633,633,633,120,120,120,120,120,120,
+252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,252,
+252,634,254,635,254,254,254,254,260,260,260,254,260,254,254,252,
/* block 111 */
-623,623,623,623,623,623,623,623,623,623,624,624,624,624,624,624,
-624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,
-624,624,624,624,624,624,625,625,625,625,625,625,625,625,626,627,
-628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,
-628,628,628,628,628,628,628,629,629,629,629,629,629,629,629,629,
-629,629,630,630,119,119,119,119,119,119,119,119,119,119,119,631,
-355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,
-355,355,355,355,355,355,355,355,355,355,355,355,355,119,119,119,
+636,636,636,636,636,636,636,636,636,636,637,637,637,637,637,637,
+637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,637,
+637,637,637,637,637,637,638,638,638,638,638,638,638,638,639,640,
+641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,641,
+641,641,641,641,641,641,641,642,642,642,642,642,642,642,642,642,
+642,642,643,643,120,120,120,120,120,120,120,120,120,120,120,644,
+357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
+357,357,357,357,357,357,357,357,357,357,357,357,357,120,120,120,
/* block 112 */
-632,632,632,633,634,634,634,634,634,634,634,634,634,634,634,634,
-634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,
-634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,
-634,634,634,632,633,633,632,632,632,632,633,633,632,633,633,633,
-633,635,635,635,635,635,635,635,635,635,635,635,635,635,119,636,
-637,637,637,637,637,637,637,637,637,637,119,119,119,119,635,635,
-343,343,343,343,343,345,638,343,343,343,343,343,343,343,343,343,
-349,349,349,349,349,349,349,349,349,349,343,343,343,343,343,119,
+645,645,645,646,647,647,647,647,647,647,647,647,647,647,647,647,
+647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,
+647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,
+647,647,647,645,646,646,645,645,645,645,646,646,645,645,646,646,
+646,648,648,648,648,648,648,648,648,648,648,648,648,648,120,649,
+650,650,650,650,650,650,650,650,650,650,120,120,120,120,648,648,
+345,345,345,345,345,347,651,345,345,345,345,345,345,345,345,345,
+351,351,351,351,351,351,351,351,351,351,345,345,345,345,345,120,
/* block 113 */
-639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,
-639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,
-639,639,639,639,639,639,639,639,639,640,640,640,640,640,640,641,
-641,640,640,641,641,640,640,119,119,119,119,119,119,119,119,119,
-639,639,639,640,639,639,639,639,639,639,639,639,640,641,119,119,
-642,642,642,642,642,642,642,642,642,642,119,119,643,643,643,643,
-343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,
-638,343,343,343,343,343,343,350,350,350,343,344,345,344,343,343,
+652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,
+652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,652,
+652,652,652,652,652,652,652,652,652,653,653,653,653,653,653,654,
+654,653,653,654,654,653,653,120,120,120,120,120,120,120,120,120,
+652,652,652,653,652,652,652,652,652,652,652,652,653,654,120,120,
+655,655,655,655,655,655,655,655,655,655,120,120,656,656,656,656,
+345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,345,
+651,345,345,345,345,345,345,352,352,352,345,346,347,346,345,345,
/* block 114 */
-644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,
-644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,
-644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,
-645,644,645,645,645,644,644,645,645,644,644,644,644,644,645,645,
-644,645,644,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,644,644,646,647,647,
-648,648,648,648,648,648,648,648,648,648,648,649,650,650,649,649,
-651,651,648,652,652,649,650,119,119,119,119,119,119,119,119,119,
+657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
+657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
+657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
+658,657,658,658,658,657,657,658,658,657,657,657,657,657,658,658,
+657,658,657,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,657,657,659,660,660,
+661,661,661,661,661,661,661,661,661,661,661,662,663,663,662,662,
+664,664,661,665,665,662,663,120,120,120,120,120,120,120,120,120,
/* block 115 */
-119,358,358,358,358,358,358,119,119,358,358,358,358,358,358,119,
-119,358,358,358,358,358,358,119,119,119,119,119,119,119,119,119,
-358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119,
+120,360,360,360,360,360,360,120,120,360,360,360,360,360,360,120,
+120,360,360,360,360,360,360,120,120,120,120,120,120,120,120,120,
+360,360,360,360,360,360,360,120,360,360,360,360,360,360,360,120,
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
- 35, 35, 35,653, 35, 35, 35, 35, 35, 35, 35, 15,109,109,109,109,
- 35, 35, 35, 35, 35,127,119,119,119,119,119,119,119,119,119,119,
-654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,
+ 35, 35, 35,666, 35, 35, 35, 35, 35, 35, 35, 15,110,110,110,110,
+ 35, 35, 35, 35, 35,128, 35, 35,120,120,120,120,120,120,120,120,
+667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
/* block 116 */
-654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,
-654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,
-654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,
-654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,
-648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,
-648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,648,
-648,648,648,649,649,650,649,649,650,649,649,651,649,650,119,119,
-655,655,655,655,655,655,655,655,655,655,119,119,119,119,119,119,
+667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
+667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
+667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
+667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
+661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,
+661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,661,
+661,661,661,662,662,663,662,662,663,662,662,664,662,663,120,120,
+668,668,668,668,668,668,668,668,668,668,120,120,120,120,120,120,
/* block 117 */
-656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
+669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
/* block 118 */
-657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657,
+670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
/* block 119 */
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
/* block 120 */
-657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657,
+670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
/* block 121 */
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
/* block 122 */
-657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657,
+670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
/* block 123 */
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,656,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,656,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+669,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,669,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,669,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
/* block 124 */
-657,657,657,657,657,657,657,657,656,657,657,657,657,657,657,657,
-657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,
-657,657,657,657,119,119,119,119,119,119,119,119,119,119,119,119,
-356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,
-356,356,356,356,356,356,356,119,119,119,119,357,357,357,357,357,
-357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
-357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,357,
-357,357,357,357,357,357,357,357,357,357,357,357,119,119,119,119,
+670,670,670,670,670,670,670,670,669,670,670,670,670,670,670,670,
+670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,670,
+670,670,670,670,120,120,120,120,120,120,120,120,120,120,120,120,
+358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,
+358,358,358,358,358,358,358,120,120,120,120,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,
+359,359,359,359,359,359,359,359,359,359,359,359,120,120,120,120,
/* block 125 */
-658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
-658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
-658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
-658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
-658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
-658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
-658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
-658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,658,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
+671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
/* block 126 */
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
/* block 127 */
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,119,119,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
/* block 128 */
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 129 */
- 35, 35, 35, 35, 35, 35, 35,119,119,119,119,119,119,119,119,119,
-119,119,119,205,205,205,205,205,119,119,119,119,119,214,211,214,
-214,214,214,214,214,214,214,214,214,660,214,214,214,214,214,214,
-214,214,214,214,214,214,214,119,214,214,214,214,214,119,214,119,
-214,214,119,214,214,119,214,214,214,214,214,214,214,214,214,214,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+ 35, 35, 35, 35, 35, 35, 35,120,120,120,120,120,120,120,120,120,
+120,120,120,206,206,206,206,206,120,120,120,120,120,215,212,215,
+215,215,215,215,215,215,215,215,215,673,215,215,215,215,215,215,
+215,215,215,215,215,215,215,120,215,215,215,215,215,120,215,120,
+215,215,120,215,215,120,215,215,215,215,215,215,215,215,215,215,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
/* block 130 */
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,661,661,661,661,661,661,661,661,661,661,661,661,661,661,
-661,661,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,674,674,674,674,674,674,674,674,674,674,674,674,674,674,
+674,674,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
/* block 131 */
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
/* block 132 */
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224, 8, 7,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225, 8, 7,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
/* block 133 */
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-119,119,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-224,224,662,224,224,224,224,224,224,224,224,224,219,663,119,119,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+120,120,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+225,225,675,225,225,225,225,225,225,225,225,225,220,676,120,120,
/* block 134 */
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
- 5, 5, 5, 5, 5, 5, 5, 7, 8, 5,119,119,119,119,119,119,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,543,543,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+ 5, 5, 5, 5, 5, 5, 5, 7, 8, 5,120,120,120,120,120,120,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,552,552,
5, 10, 10, 16, 16, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7,
- 8, 7, 8, 7, 8,547,547, 7, 8, 5, 5, 5, 5, 16, 16, 16,
- 5, 5, 5,119, 5, 5, 5, 5, 10, 7, 8, 7, 8, 7, 8, 5,
- 5, 5, 9, 10, 9, 9, 9,119, 5, 6, 5, 5,119,119,119,119,
-224,224,224,224,224,119,224,224,224,224,224,224,224,224,224,224,
+ 8, 7, 8, 7, 8,556,556, 7, 8, 5, 5, 5, 5, 16, 16, 16,
+ 5, 5, 5,120, 5, 5, 5, 5, 10, 7, 8, 7, 8, 7, 8, 5,
+ 5, 5, 9, 10, 9, 9, 9,120, 5, 6, 5, 5,120,120,120,120,
+225,225,225,225,225,120,225,225,225,225,225,225,225,225,225,225,
/* block 135 */
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,119,119, 24,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,120,120, 24,
/* block 136 */
-119, 5, 5, 5, 6, 5, 5, 5, 7, 8, 5, 9, 5, 10, 5, 5,
+120, 5, 5, 5, 6, 5, 5, 5, 7, 8, 5, 9, 5, 10, 5, 5,
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 5, 5, 9, 9, 9, 5,
5, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 5, 8, 15, 16,
15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 7, 9, 8, 9, 7,
- 8,546,551,552,546,546,569,569,569,569,569,569,569,569,569,569,
-560,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
+ 8,555,560,561,555,555,578,578,578,578,578,578,578,578,578,578,
+569,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
/* block 137 */
-569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,
-569,569,569,569,569,569,569,569,569,569,569,569,569,569,664,664,
-572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,
-572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,119,
-119,119,572,572,572,572,572,572,119,119,572,572,572,572,572,572,
-119,119,572,572,572,572,572,572,119,119,572,572,572,119,119,119,
- 6, 6, 9, 15, 20, 6, 6,119, 20, 9, 9, 9, 9, 20, 20,119,
-502,502,502,502,502,502,502,502,502, 24, 24, 24, 20, 20,119,119,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,
+578,578,578,578,578,578,578,578,578,578,578,578,578,578,677,677,
+581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,
+581,581,581,581,581,581,581,581,581,581,581,581,581,581,581,120,
+120,120,581,581,581,581,581,581,120,120,581,581,581,581,581,581,
+120,120,581,581,581,581,581,581,120,120,581,581,581,120,120,120,
+ 6, 6, 9, 15, 20, 6, 6,120, 20, 9, 9, 9, 9, 20, 20,120,
+511,511,511,511,511,511,511,511,511, 24, 24, 24, 20, 20,120,120,
/* block 138 */
-665,665,665,665,665,665,665,665,665,665,665,665,119,665,665,665,
-665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
-665,665,665,665,665,665,665,119,665,665,665,665,665,665,665,665,
-665,665,665,665,665,665,665,665,665,665,665,119,665,665,119,665,
-665,665,665,665,665,665,665,665,665,665,665,665,665,665,119,119,
-665,665,665,665,665,665,665,665,665,665,665,665,665,665,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+678,678,678,678,678,678,678,678,678,678,678,678,120,678,678,678,
+678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
+678,678,678,678,678,678,678,120,678,678,678,678,678,678,678,678,
+678,678,678,678,678,678,678,678,678,678,678,120,678,678,120,678,
+678,678,678,678,678,678,678,678,678,678,678,678,678,678,120,120,
+678,678,678,678,678,678,678,678,678,678,678,678,678,678,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 139 */
-665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
-665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
-665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
-665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
-665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
-665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
-665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,
-665,665,665,665,665,665,665,665,665,665,665,119,119,119,119,119,
+678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
+678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
+678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
+678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
+678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
+678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
+678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
+678,678,678,678,678,678,678,678,678,678,678,120,120,120,120,120,
/* block 140 */
-666,666,666,119,119,119,119,667,667,667,667,667,667,667,667,667,
-667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
-667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,667,
-667,667,667,667,119,119,119,668,668,668,668,668,668,668,668,668,
-669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,
-669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,
-669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,
-669,669,669,669,669,670,670,670,670,671,671,671,671,671,671,671,
+679,679,679,120,120,120,120,680,680,680,680,680,680,680,680,680,
+680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,
+680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,
+680,680,680,680,120,120,120,681,681,681,681,681,681,681,681,681,
+682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,
+682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,
+682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,
+682,682,682,682,682,683,683,683,683,684,684,684,684,684,684,684,
/* block 141 */
-671,671,671,671,671,671,671,671,671,671,670,670,671,671,671,119,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119,
-671,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+684,684,684,684,684,684,684,684,684,684,683,683,684,684,684,120,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,
+684,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,112,119,119,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,113,120,120,
/* block 142 */
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 143 */
-672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
-672,672,672,672,672,672,672,672,672,672,672,672,672,119,119,119,
-673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
-673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
-673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,
-673,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-674,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,
-675,675,675,675,675,675,675,675,675,675,675,675,119,119,119,119,
+685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,685,
+685,685,685,685,685,685,685,685,685,685,685,685,685,120,120,120,
+686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
+686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
+686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,686,
+686,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+687,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,
+688,688,688,688,688,688,688,688,688,688,688,688,120,120,120,120,
/* block 144 */
-676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,
-676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,
-677,677,677,677,119,119,119,119,119,119,119,119,119,676,676,676,
-678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,
-678,679,678,678,678,678,678,678,678,678,679,119,119,119,119,119,
-680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,
-680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,
-680,680,680,680,680,680,681,681,681,681,681,119,119,119,119,119,
+689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,
+689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,
+690,690,690,690,120,120,120,120,120,120,120,120,120,689,689,689,
+691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,691,
+691,692,691,691,691,691,691,691,691,691,692,120,120,120,120,120,
+693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,
+693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,
+693,693,693,693,693,693,694,694,694,694,694,120,120,120,120,120,
/* block 145 */
-682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,682,
-682,682,682,682,682,682,682,682,682,682,682,682,682,682,119,683,
-684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,
-684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,
-684,684,684,684,119,119,119,119,684,684,684,684,684,684,684,684,
-685,686,686,686,686,686,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,
+695,695,695,695,695,695,695,695,695,695,695,695,695,695,120,696,
+697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
+697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
+697,697,697,697,120,120,120,120,697,697,697,697,697,697,697,697,
+698,699,699,699,699,699,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 146 */
-687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,
-687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,687,
-687,687,687,687,687,687,687,687,688,688,688,688,688,688,688,688,
-688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,
-688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,688,
-689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,
-689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,
-689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,
+700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,700,
+700,700,700,700,700,700,700,700,701,701,701,701,701,701,701,701,
+701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,
+701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,701,
+702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
+702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
+702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
/* block 147 */
-690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,690,
-690,690,690,690,690,690,690,690,690,690,690,690,690,690,119,119,
-691,691,691,691,691,691,691,691,691,691,119,119,119,119,119,119,
-692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,
-692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,
-692,692,692,692,119,119,119,119,693,693,693,693,693,693,693,693,
-693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,693,
-693,693,693,693,693,693,693,693,693,693,693,693,119,119,119,119,
+703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,703,
+703,703,703,703,703,703,703,703,703,703,703,703,703,703,120,120,
+704,704,704,704,704,704,704,704,704,704,120,120,120,120,120,120,
+705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,
+705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,
+705,705,705,705,120,120,120,120,706,706,706,706,706,706,706,706,
+706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,706,
+706,706,706,706,706,706,706,706,706,706,706,706,120,120,120,120,
/* block 148 */
-694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,
-694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,694,
-694,694,694,694,694,694,694,694,119,119,119,119,119,119,119,119,
-695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,
-695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,
-695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,
-695,695,695,695,119,119,119,119,119,119,119,119,119,119,119,696,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
+707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
+707,707,707,707,707,707,707,707,120,120,120,120,120,120,120,120,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,708,
+708,708,708,708,120,120,120,120,120,120,120,120,120,120,120,709,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 149 */
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
/* block 150 */
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,697,119,119,119,119,119,119,119,119,119,
-697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,
-697,697,697,697,697,697,119,119,119,119,119,119,119,119,119,119,
-697,697,697,697,697,697,697,697,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,710,120,120,120,120,120,120,120,120,120,
+710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,710,
+710,710,710,710,710,710,120,120,120,120,120,120,120,120,120,120,
+710,710,710,710,710,710,710,710,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 151 */
-698,698,698,698,698,698,119,119,698,119,698,698,698,698,698,698,
-698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,
-698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,698,
-698,698,698,698,698,698,119,698,698,119,119,119,698,119,119,698,
-699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,
-699,699,699,699,699,699,119,700,701,701,701,701,701,701,701,701,
-702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,702,
-702,702,702,702,702,702,702,703,703,704,704,704,704,704,704,704,
+711,711,711,711,711,711,120,120,711,120,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,711,
+711,711,711,711,711,711,120,711,711,120,120,120,711,120,120,711,
+712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
+712,712,712,712,712,712,120,713,714,714,714,714,714,714,714,714,
+715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,
+715,715,715,715,715,715,715,716,716,717,717,717,717,717,717,717,
/* block 152 */
-705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,
-705,705,705,705,705,705,705,705,705,705,705,705,705,705,705,119,
-119,119,119,119,119,119,119,706,706,706,706,706,706,706,706,706,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,
-707,707,707,119,707,707,119,119,119,119,119,708,708,708,708,708,
+718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,
+718,718,718,718,718,718,718,718,718,718,718,718,718,718,718,120,
+120,120,120,120,120,120,120,719,719,719,719,719,719,719,719,719,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,
+720,720,720,120,720,720,120,120,120,120,120,721,721,721,721,721,
/* block 153 */
-709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,
-709,709,709,709,709,709,710,710,710,710,710,710,119,119,119,711,
-712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712,
-712,712,712,712,712,712,712,712,712,712,119,119,119,119,119,713,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,722,
+722,722,722,722,722,722,723,723,723,723,723,723,120,120,120,724,
+725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,725,
+725,725,725,725,725,725,725,725,725,725,120,120,120,120,120,726,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 154 */
-714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,
-714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,
-715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,715,
-715,715,715,715,715,715,715,715,119,119,119,119,716,716,715,715,
-716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,
-119,119,716,716,716,716,716,716,716,716,716,716,716,716,716,716,
-716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,
-716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,
+727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,
+727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,
+728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,728,
+728,728,728,728,728,728,728,728,120,120,120,120,729,729,728,728,
+729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,
+120,120,729,729,729,729,729,729,729,729,729,729,729,729,729,729,
+729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,
+729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,729,
/* block 155 */
-717,718,718,718,119,718,718,119,119,119,119,119,718,718,718,718,
-717,717,717,717,119,717,717,717,119,717,717,717,717,717,717,717,
-717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,
-717,717,717,717,717,717,119,119,718,718,718,119,119,119,119,718,
-719,719,719,719,719,719,719,719,719,119,119,119,119,119,119,119,
-720,720,720,720,720,720,720,720,720,119,119,119,119,119,119,119,
-721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,
-721,721,721,721,721,721,721,721,721,721,721,721,721,722,722,723,
+730,731,731,731,120,731,731,120,120,120,120,120,731,731,731,731,
+730,730,730,730,120,730,730,730,120,730,730,730,730,730,730,730,
+730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,730,
+730,730,730,730,730,730,120,120,731,731,731,120,120,120,120,731,
+732,732,732,732,732,732,732,732,732,120,120,120,120,120,120,120,
+733,733,733,733,733,733,733,733,733,120,120,120,120,120,120,120,
+734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,734,
+734,734,734,734,734,734,734,734,734,734,734,734,734,735,735,736,
/* block 156 */
-724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,
-724,724,724,724,724,724,724,724,724,724,724,724,724,725,725,725,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-726,726,726,726,726,726,726,726,727,726,726,726,726,726,726,726,
-726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,726,
-726,726,726,726,726,728,728,119,119,119,119,729,729,729,729,729,
-730,730,730,730,730,730,730,119,119,119,119,119,119,119,119,119,
+737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
+737,737,737,737,737,737,737,737,737,737,737,737,737,738,738,738,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+739,739,739,739,739,739,739,739,740,739,739,739,739,739,739,739,
+739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,739,
+739,739,739,739,739,741,741,120,120,120,120,742,742,742,742,742,
+743,743,743,743,743,743,743,120,120,120,120,120,120,120,120,120,
/* block 157 */
-731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,
-731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,
-731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,731,
-731,731,731,731,731,731,119,119,119,732,732,732,732,732,732,732,
-733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,
-733,733,733,733,733,733,119,119,734,734,734,734,734,734,734,734,
-735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,
-735,735,735,119,119,119,119,119,736,736,736,736,736,736,736,736,
+744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
+744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
+744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
+744,744,744,744,744,744,120,120,120,745,745,745,745,745,745,745,
+746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,746,
+746,746,746,746,746,746,120,120,747,747,747,747,747,747,747,747,
+748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,
+748,748,748,120,120,120,120,120,749,749,749,749,749,749,749,749,
/* block 158 */
-737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,
-737,737,119,119,119,119,119,119,119,738,738,738,738,119,119,119,
-119,119,119,119,119,119,119,119,119,739,739,739,739,739,739,739,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,
+750,750,120,120,120,120,120,120,120,751,751,751,751,120,120,120,
+120,120,120,120,120,120,120,120,120,752,752,752,752,752,752,752,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 159 */
-740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,
-740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,
-740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,
-740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,740,
-740,740,740,740,740,740,740,740,740,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
+753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
+753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
+753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,753,
+753,753,753,753,753,753,753,753,753,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 160 */
-741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
-741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
-741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,
-741,741,741,119,119,119,119,119,119,119,119,119,119,119,119,119,
-742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,
-742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,
-742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,
-742,742,742,119,119,119,119,119,119,119,743,743,743,743,743,743,
+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,
+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,
+754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,754,
+754,754,754,120,120,120,120,120,120,120,120,120,120,120,120,120,
+755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,
+755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,
+755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,755,
+755,755,755,120,120,120,120,120,120,120,756,756,756,756,756,756,
/* block 161 */
-744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
-744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,744,
-744,744,744,744,745,745,745,745,119,119,119,119,119,119,119,119,
-746,746,746,746,746,746,746,746,746,746,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,
+757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,757,
+757,757,757,757,758,758,758,758,120,120,120,120,120,120,120,120,
+759,759,759,759,759,759,759,759,759,759,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 162 */
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,
-747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,119,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,
+760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,120,
/* block 163 */
-748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,
-748,748,748,748,748,748,748,748,748,748,748,748,748,749,749,749,
-749,749,749,749,749,749,749,748,119,119,119,119,119,119,119,119,
-750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,
-750,750,750,750,750,750,751,751,751,751,751,751,751,751,751,751,
-751,752,752,752,752,753,753,753,753,753,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,761,
+761,761,761,761,761,761,761,761,761,761,761,761,761,762,762,762,
+762,762,762,762,762,762,762,761,120,120,120,120,120,120,120,120,
+763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,763,
+763,763,763,763,763,763,764,764,764,764,764,764,764,764,764,764,
+764,765,765,765,765,766,766,766,766,766,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 164 */
-754,755,754,756,756,756,756,756,756,756,756,756,756,756,756,756,
-756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,
-756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,756,
-756,756,756,756,756,756,756,756,755,755,755,755,755,755,755,755,
-755,755,755,755,755,755,755,757,757,757,757,757,757,757,119,119,
-119,119,758,758,758,758,758,758,758,758,758,758,758,758,758,758,
-758,758,758,758,758,758,759,759,759,759,759,759,759,759,759,759,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,755,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,767,
+767,767,767,767,767,767,767,120,120,120,120,120,120,120,120,120,
/* block 165 */
-760,760,761,762,762,762,762,762,762,762,762,762,762,762,762,762,
-762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,
-762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,762,
-761,761,761,760,760,760,760,761,761,760,760,763,763,764,763,763,
-763,763,119,119,119,119,119,119,119,119,119,119,119,764,119,119,
-765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,765,
-765,765,765,765,765,765,765,765,765,119,119,119,119,119,119,119,
-766,766,766,766,766,766,766,766,766,766,119,119,119,119,119,119,
+768,769,768,770,770,770,770,770,770,770,770,770,770,770,770,770,
+770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,
+770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,770,
+770,770,770,770,770,770,770,770,769,769,769,769,769,769,769,769,
+769,769,769,769,769,769,769,771,771,771,771,771,771,771,120,120,
+120,120,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
+772,772,772,772,772,772,773,773,773,773,773,773,773,773,773,773,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,769,
/* block 166 */
-767,767,767,768,768,768,768,768,768,768,768,768,768,768,768,768,
-768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,
-768,768,768,768,768,768,768,767,767,767,767,767,769,767,767,767,
-767,767,767,767,767,119,770,770,770,770,770,770,770,770,770,770,
-771,771,771,771,768,769,769,119,119,119,119,119,119,119,119,119,
-772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
-772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,
-772,772,772,773,774,774,772,119,119,119,119,119,119,119,119,119,
+774,774,775,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,776,
+775,775,775,774,774,774,774,775,775,774,774,777,777,778,777,777,
+777,777,120,120,120,120,120,120,120,120,120,120,120,778,120,120,
+779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,779,
+779,779,779,779,779,779,779,779,779,120,120,120,120,120,120,120,
+780,780,780,780,780,780,780,780,780,780,120,120,120,120,120,120,
/* block 167 */
-775,775,776,777,777,777,777,777,777,777,777,777,777,777,777,777,
-777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,
-777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,
-777,777,777,776,776,776,775,775,775,775,775,775,775,775,775,776,
-776,777,778,778,777,779,779,779,779,775,775,775,775,779,119,119,
-780,780,780,780,780,780,780,780,780,780,777,779,777,779,779,779,
-119,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781,
-781,781,781,781,781,119,119,119,119,119,119,119,119,119,119,119,
+781,781,781,782,782,782,782,782,782,782,782,782,782,782,782,782,
+782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,
+782,782,782,782,782,782,782,781,781,781,781,781,783,781,781,781,
+781,781,781,781,781,120,784,784,784,784,784,784,784,784,784,784,
+785,785,785,785,782,783,783,120,120,120,120,120,120,120,120,120,
+786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,
+786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,
+786,786,786,787,788,788,786,120,120,120,120,120,120,120,120,120,
/* block 168 */
-782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,
-782,782,119,782,782,782,782,782,782,782,782,782,782,782,782,782,
-782,782,782,782,782,782,782,782,782,782,782,782,783,783,783,784,
-784,784,783,783,784,783,784,784,785,785,785,785,785,785,784,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+789,789,790,791,791,791,791,791,791,791,791,791,791,791,791,791,
+791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,
+791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,791,
+791,791,791,790,790,790,789,789,789,789,789,789,789,789,789,790,
+790,791,792,792,791,793,793,793,793,789,789,789,789,793,120,120,
+794,794,794,794,794,794,794,794,794,794,791,793,791,793,793,793,
+120,795,795,795,795,795,795,795,795,795,795,795,795,795,795,795,
+795,795,795,795,795,120,120,120,120,120,120,120,120,120,120,120,
/* block 169 */
-786,786,786,786,786,786,786,119,786,119,786,786,786,786,119,786,
-786,786,786,786,786,786,786,786,786,786,786,786,786,786,119,786,
-786,786,786,786,786,786,786,786,786,787,119,119,119,119,119,119,
-788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,
-788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,
-788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,789,
-790,790,790,789,789,789,789,789,789,789,789,119,119,119,119,119,
-791,791,791,791,791,791,791,791,791,791,119,119,119,119,119,119,
+796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,120,796,796,796,796,796,796,796,796,796,796,796,796,796,
+796,796,796,796,796,796,796,796,796,796,796,796,797,797,797,798,
+798,798,797,797,798,797,798,798,799,799,799,799,799,799,798,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 170 */
-792,793,794,795,119,796,796,796,796,796,796,796,796,119,119,796,
-796,119,119,796,796,796,796,796,796,796,796,796,796,796,796,796,
-796,796,796,796,796,796,796,796,796,119,796,796,796,796,796,796,
-796,119,796,796,119,796,796,796,796,796,119,797,793,796,798,794,
-792,794,794,794,794,119,119,794,794,119,119,794,794,794,119,119,
-796,119,119,119,119,119,119,798,119,119,119,119,119,796,796,796,
-796,796,794,794,119,119,792,792,792,792,792,792,792,119,119,119,
-792,792,792,792,792,119,119,119,119,119,119,119,119,119,119,119,
+800,800,800,800,800,800,800,120,800,120,800,800,800,800,120,800,
+800,800,800,800,800,800,800,800,800,800,800,800,800,800,120,800,
+800,800,800,800,800,800,800,800,800,801,120,120,120,120,120,120,
+802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,
+802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,
+802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,803,
+804,804,804,803,803,803,803,803,803,803,803,120,120,120,120,120,
+805,805,805,805,805,805,805,805,805,805,120,120,120,120,120,120,
/* block 171 */
-799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,
-799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,
-799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,
-799,799,799,799,799,800,800,800,801,801,801,801,801,801,801,801,
-800,800,801,801,801,800,801,799,799,799,799,802,802,802,802,802,
-803,803,803,803,803,803,803,803,803,803,119,802,119,802,801,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+806,807,808,809,120,810,810,810,810,810,810,810,810,120,120,810,
+810,120,120,810,810,810,810,810,810,810,810,810,810,810,810,810,
+810,810,810,810,810,810,810,810,810,120,810,810,810,810,810,810,
+810,120,810,810,120,810,810,810,810,810,120,811,807,810,812,808,
+806,808,808,808,808,120,120,808,808,120,120,808,808,808,120,120,
+810,120,120,120,120,120,120,812,120,120,120,120,120,810,810,810,
+810,810,808,808,120,120,806,806,806,806,806,806,806,120,120,120,
+806,806,806,806,806,120,120,120,120,120,120,120,120,120,120,120,
/* block 172 */
-804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,
-804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,
-804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,
-805,806,806,807,807,807,807,807,807,806,807,806,806,805,806,807,
-807,806,807,807,804,804,808,804,119,119,119,119,119,119,119,119,
-809,809,809,809,809,809,809,809,809,809,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,
+813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,
+813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,813,
+813,813,813,813,813,814,814,814,815,815,815,815,815,815,815,815,
+814,814,815,815,815,814,815,813,813,813,813,816,816,816,816,816,
+817,817,817,817,817,817,817,817,817,817,120,816,120,816,815,813,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 173 */
-810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,
-810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,
-810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,811,
-812,812,813,813,813,813,119,119,812,812,812,812,813,813,812,813,
-813,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814,
-814,814,814,814,814,814,814,814,810,810,810,810,813,813,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,
+818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,
+818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,818,
+819,820,820,821,821,821,821,821,821,820,821,820,820,819,820,821,
+821,820,821,821,818,818,822,818,120,120,120,120,120,120,120,120,
+823,823,823,823,823,823,823,823,823,823,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 174 */
-815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,
-815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,
-815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,
-816,816,816,817,817,817,817,817,817,817,817,816,816,817,816,817,
-817,818,818,818,815,119,119,119,119,119,119,119,119,119,119,119,
-819,819,819,819,819,819,819,819,819,819,119,119,119,119,119,119,
-392,392,392,392,392,392,392,392,392,392,392,392,392,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
+824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
+824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,825,
+826,826,827,827,827,827,120,120,826,826,826,826,827,827,826,827,
+827,828,828,828,828,828,828,828,828,828,828,828,828,828,828,828,
+828,828,828,828,828,828,828,828,824,824,824,824,827,827,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 175 */
-820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,
-820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,
-820,820,820,820,820,820,820,820,820,820,820,821,822,821,822,822,
-821,821,821,821,821,821,822,821,119,119,119,119,119,119,119,119,
-823,823,823,823,823,823,823,823,823,823,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
+829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
+829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,
+830,830,830,831,831,831,831,831,831,831,831,830,830,831,830,831,
+831,832,832,832,829,120,120,120,120,120,120,120,120,120,120,120,
+833,833,833,833,833,833,833,833,833,833,120,120,120,120,120,120,
+395,395,395,395,395,395,395,395,395,395,395,395,395,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 176 */
-824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,824,
-824,824,824,824,824,824,824,824,824,824,824,119,119,825,825,825,
-826,826,825,825,825,825,826,825,825,825,825,825,119,119,119,119,
-827,827,827,827,827,827,827,827,827,827,828,828,829,829,829,830,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,
+834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,834,
+834,834,834,834,834,834,834,834,834,834,834,835,836,835,836,836,
+835,835,835,835,835,835,836,835,834,120,120,120,120,120,120,120,
+837,837,837,837,837,837,837,837,837,837,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 177 */
-831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,
-831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,
-831,831,831,831,831,831,831,831,831,831,831,831,832,832,832,833,
-833,833,833,833,833,833,833,833,832,833,833,834,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838,
+838,838,838,838,838,838,838,838,838,838,838,120,120,839,839,839,
+840,840,839,839,839,839,840,839,839,839,839,839,120,120,120,120,
+841,841,841,841,841,841,841,841,841,841,842,842,843,843,843,844,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 178 */
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,
-835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,835,
-836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,
-836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,
-837,837,837,837,837,837,837,837,837,837,838,838,838,838,838,838,
-838,838,838,119,119,119,119,119,119,119,119,119,119,119,119,839,
-
-/* block 179 */
-840,841,841,841,841,841,841,841,841,841,841,840,840,840,840,840,
-840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,
-840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,
-840,840,840,841,841,841,841,841,841,842,843,841,841,841,841,844,
-844,844,844,844,844,844,844,841,119,119,119,119,119,119,119,119,
-845,846,846,846,846,846,846,847,847,846,846,846,845,845,845,845,
845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,
845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,845,
+845,845,845,845,845,845,845,845,845,845,845,845,846,846,846,847,
+847,847,847,847,847,847,847,847,846,847,847,848,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 180 */
-845,845,845,845,119,119,848,848,848,848,846,846,846,846,846,846,
-846,846,846,846,846,846,846,847,846,846,849,849,849,845,849,849,
-849,849,849,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,
+/* block 179 */
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,
+849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,
850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,
850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,850,
-850,850,850,850,850,850,850,850,850,119,119,119,119,119,119,119,
+851,851,851,851,851,851,851,851,851,851,852,852,852,852,852,852,
+852,852,852,120,120,120,120,120,120,120,120,120,120,120,120,853,
+
+/* block 180 */
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+854,854,854,854,854,854,854,854,120,120,854,854,854,854,854,854,
+854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,
+854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,854,
+854,855,855,855,856,856,856,856,120,120,856,856,855,855,855,855,
+856,854,857,854,855,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 181 */
-851,851,851,851,851,851,851,851,851,119,851,851,851,851,851,851,
-851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,
-851,851,851,851,851,851,851,851,851,851,851,851,851,851,851,852,
-853,853,853,853,853,853,853,119,853,853,853,853,853,853,852,853,
-851,854,854,854,854,854,119,119,119,119,119,119,119,119,119,119,
-855,855,855,855,855,855,855,855,855,855,856,856,856,856,856,856,
-856,856,856,856,856,856,856,856,856,856,856,856,856,119,119,119,
-857,857,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
+858,859,859,859,859,859,859,859,859,859,859,858,858,858,858,858,
+858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
+858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
+858,858,858,859,859,859,859,859,859,860,861,859,859,859,859,862,
+862,862,862,862,862,862,862,859,120,120,120,120,120,120,120,120,
+863,864,864,864,864,864,864,865,865,864,864,864,863,863,863,863,
+863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,
+863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,863,
/* block 182 */
-858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,
-119,119,859,859,859,859,859,859,859,859,859,859,859,859,859,859,
-859,859,859,859,859,859,859,859,119,860,859,859,859,859,859,859,
-859,860,859,859,860,859,859,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+863,863,863,863,866,866,866,866,866,866,864,864,864,864,864,864,
+864,864,864,864,864,864,864,865,864,864,867,867,867,863,867,867,
+867,867,867,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,
+868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,
+868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,868,
+868,868,868,868,868,868,868,868,868,120,120,120,120,120,120,120,
/* block 183 */
-861,861,861,861,861,861,861,119,861,861,119,861,861,861,861,861,
-861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,
-861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,
-861,862,862,862,862,862,862,119,119,119,862,119,862,862,119,862,
-862,862,862,862,862,862,863,862,119,119,119,119,119,119,119,119,
-864,864,864,864,864,864,864,864,864,864,119,119,119,119,119,119,
-865,865,865,865,865,865,119,865,865,119,865,865,865,865,865,865,
-865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,
+869,869,869,869,869,869,869,869,869,120,869,869,869,869,869,869,
+869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,
+869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,870,
+871,871,871,871,871,871,871,120,871,871,871,871,871,871,870,871,
+869,872,872,872,872,872,120,120,120,120,120,120,120,120,120,120,
+873,873,873,873,873,873,873,873,873,873,874,874,874,874,874,874,
+874,874,874,874,874,874,874,874,874,874,874,874,874,120,120,120,
+875,875,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
/* block 184 */
-865,865,865,865,865,865,865,865,865,865,866,866,866,866,866,119,
-867,867,119,866,866,867,866,867,865,119,119,119,119,119,119,119,
-868,868,868,868,868,868,868,868,868,868,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
+120,120,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
+877,877,877,877,877,877,877,877,120,878,877,877,877,877,877,877,
+877,878,877,877,878,877,877,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 185 */
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,
-869,869,869,870,870,871,871,872,872,119,119,119,119,119,119,119,
+879,879,879,879,879,879,879,120,879,879,120,879,879,879,879,879,
+879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,
+879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,879,
+879,880,880,880,880,880,880,120,120,120,880,120,880,880,120,880,
+880,880,880,880,880,880,881,880,120,120,120,120,120,120,120,120,
+882,882,882,882,882,882,882,882,882,882,120,120,120,120,120,120,
+883,883,883,883,883,883,120,883,883,120,883,883,883,883,883,883,
+883,883,883,883,883,883,883,883,883,883,883,883,883,883,883,883,
/* block 186 */
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
+883,883,883,883,883,883,883,883,883,883,884,884,884,884,884,120,
+885,885,120,884,884,885,884,885,883,120,120,120,120,120,120,120,
+886,886,886,886,886,886,886,886,886,886,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 187 */
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,873,873,873,873,873,873,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+887,887,887,887,887,887,887,887,887,887,887,887,887,887,887,887,
+887,887,887,888,888,889,889,890,890,120,120,120,120,120,120,120,
/* block 188 */
-874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,
-874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,
-874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,
-874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,
-874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,
-874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,
-874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,119,
-875,875,875,875,875,119,119,119,119,119,119,119,119,119,119,119,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,
+294,294,891,294,891,296,296,296,296,296,296,296,296,297,297,297,
+297,296,296,296,296,296,296,296,296,296,296,296,296,296,296,296,
+296,296,120,120,120,120,120,120,120,120,120,120,120,120,120,892,
/* block 189 */
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,
-873,873,873,873,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
/* block 190 */
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,893,893,893,893,893,893,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 191 */
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,
-876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
+894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
+894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
+894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
+894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
+894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,
+894,894,894,894,894,894,894,894,894,894,894,894,894,894,894,120,
+895,895,895,895,895,120,120,120,120,120,120,120,120,120,120,120,
/* block 192 */
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
+893,893,893,893,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 193 */
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,
-877,877,877,877,877,877,877,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
/* block 194 */
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
+896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,120,
+897,897,897,897,897,897,897,897,897,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 195 */
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,
-592,592,592,592,592,592,592,592,592,119,119,119,119,119,119,119,
-878,878,878,878,878,878,878,878,878,878,878,878,878,878,878,878,
-878,878,878,878,878,878,878,878,878,878,878,878,878,878,878,119,
-879,879,879,879,879,879,879,879,879,879,119,119,119,119,880,880,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
/* block 196 */
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,881,
-881,881,881,881,881,881,881,881,881,881,881,881,881,881,119,119,
-882,882,882,882,882,883,119,119,119,119,119,119,119,119,119,119,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,898,
+898,898,898,898,898,898,898,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 197 */
-884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,
-884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,
-884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,
-885,885,885,885,885,885,885,886,886,886,886,886,887,887,887,887,
-888,888,888,888,886,887,119,119,119,119,119,119,119,119,119,119,
-889,889,889,889,889,889,889,889,889,889,119,890,890,890,890,890,
-890,890,119,884,884,884,884,884,884,884,884,884,884,884,884,884,
-884,884,884,884,884,884,884,884,119,119,119,119,119,884,884,884,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
/* block 198 */
-884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,601,
+601,601,601,601,601,601,601,601,601,120,120,120,120,120,120,120,
+899,899,899,899,899,899,899,899,899,899,899,899,899,899,899,899,
+899,899,899,899,899,899,899,899,899,899,899,899,899,899,899,120,
+900,900,900,900,900,900,900,900,900,900,120,120,120,120,901,901,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 199 */
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,
-891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,
-892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,
-892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,892,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
+902,902,902,902,902,902,902,902,902,902,902,902,902,902,120,120,
+903,903,903,903,903,904,120,120,120,120,120,120,120,120,120,120,
/* block 200 */
-893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,
-893,893,893,893,893,893,893,894,894,894,894,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,
+905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,
+905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,
+906,906,906,906,906,906,906,907,907,907,907,907,908,908,908,908,
+909,909,909,909,907,908,120,120,120,120,120,120,120,120,120,120,
+910,910,910,910,910,910,910,910,910,910,120,911,911,911,911,911,
+911,911,120,905,905,905,905,905,905,905,905,905,905,905,905,905,
+905,905,905,905,905,905,905,905,120,120,120,120,120,905,905,905,
/* block 201 */
-895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,
-895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,
-895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,
-895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,
-895,895,895,895,895,119,119,119,119,119,119,119,119,119,119,119,
-895,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,
-896,896,896,896,896,896,896,896,896,896,896,896,896,896,896,119,
+905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,905,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 202 */
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,897,
-897,897,897,898,898,898,898,898,898,898,898,898,898,898,898,898,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-899,900,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,
+912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,
+913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,
+913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,913,
/* block 203 */
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
+914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,914,
+914,914,914,914,914,914,914,915,915,915,915,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 204 */
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,
+916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,
+916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,
+916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,916,
+916,916,916,916,916,916,916,916,916,916,916,120,120,120,120,917,
+916,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
+918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
+918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
/* block 205 */
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,
-901,901,901,119,119,119,119,119,119,119,119,119,119,119,119,119,
+918,918,918,918,918,918,918,918,120,120,120,120,120,120,120,917,
+917,917,917,919,919,919,919,919,919,919,919,919,919,919,919,919,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+920,921, 5,111,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 206 */
-569,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
/* block 207 */
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,120,120,120,120,120,120,120,120,
/* block 208 */
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,
-564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,922,
+922,922,922,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 209 */
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
+578,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
/* block 210 */
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,
-902,902,902,902,902,902,902,902,902,902,902,902,119,119,119,119,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
/* block 211 */
-903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,
-903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,
-903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,
-903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,
-903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,
-903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,
-903,903,903,903,903,903,903,903,903,903,903,119,119,119,119,119,
-903,903,903,903,903,903,903,903,903,903,903,903,903,119,119,119,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
+573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+573,573,573,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,578,578,578,578,120,120,120,120,120,120,120,120,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
/* block 212 */
-903,903,903,903,903,903,903,903,903,119,119,119,119,119,119,119,
-903,903,903,903,903,903,903,903,903,903,119,119,904,905,905,906,
-907,907,907,907,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
/* block 213 */
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+923,923,923,923,923,923,923,923,923,923,923,923,120,120,120,120,
+
+/* block 214 */
+924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
+924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
+924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
+924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
+924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
+924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
+924,924,924,924,924,924,924,924,924,924,924,120,120,120,120,120,
+924,924,924,924,924,924,924,924,924,924,924,924,924,120,120,120,
+
+/* block 215 */
+924,924,924,924,924,924,924,924,924,120,120,120,120,120,120,120,
+924,924,924,924,924,924,924,924,924,924,120,120,925,926,926,927,
+928,928,928,928,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 216 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
@@ -3802,309 +3867,339 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119,119,119,119,
+ 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,120,120,120,
-/* block 214 */
+/* block 217 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20,119,119, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20,120,120, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20,908,909,112,112,112, 20, 20, 20,909,908,908,
-908,908,908, 24, 24, 24, 24, 24, 24, 24, 24,112,112,112,112,112,
+ 20, 20, 20, 20, 20,929,930,113,113,113, 20, 20, 20,930,929,929,
+929,929,929, 24, 24, 24, 24, 24, 24, 24, 24,113,113,113,113,113,
-/* block 215 */
-112,112,112, 20, 20,112,112,112,112,112,112,112, 20, 20, 20, 20,
+/* block 218 */
+113,113,113, 20, 20,113,113,113,113,113,113,113, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,112,112,112,112, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,113,113,113,113, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 216 */
-671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
-671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
-671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
-671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,671,
-671,671,910,910,910,671,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+/* block 219 */
+684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,
+684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,
+684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,
+684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,684,
+684,684,931,931,931,684,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 217 */
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+/* block 220 */
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25,119,119,119,119,119,119,119,119,119,119,119,119,
+ 25, 25, 25, 25,120,120,120,120,120,120,120,120,120,120,120,120,
-/* block 218 */
+/* block 221 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119,119,119,
-573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,
-573,573, 25, 25, 25, 25, 25, 25, 25,119,119,119,119,119,119,119,
-
-/* block 219 */
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,504,504,504,504,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,505,505,
-505,505,505,505,505,119,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
-
-/* block 220 */
-504,504,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,504,119,504,504,
-119,119,504,119,119,504,504,119,119,504,504,504,504,119,504,504,
-504,504,504,504,504,504,505,505,505,505,119,505,119,505,505,505,
-505,505,505,505,119,505,505,505,505,505,505,505,505,505,505,505,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-
-/* block 221 */
-505,505,505,505,504,504,119,504,504,504,504,119,119,504,504,504,
-504,504,504,504,504,119,504,504,504,504,504,504,504,119,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,504,504,119,504,504,504,504,119,
-504,504,504,504,504,119,504,119,119,119,504,504,504,504,504,504,
-504,119,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
+ 20, 20, 20, 20, 20, 20, 20,120,120,120,120,120,120,120,120,120,
+582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,
+582,582, 25, 25, 25, 25, 25, 25, 25,120,120,120,120,120,120,120,
/* block 222 */
-504,504,504,504,504,504,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,504,504,504,504,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,514,514,
+514,514,514,514,514,120,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
/* block 223 */
-505,505,505,505,505,505,505,505,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
-504,504,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
+513,513,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,513,120,513,513,
+120,120,513,120,120,513,513,120,120,513,513,513,513,120,513,513,
+513,513,513,513,513,513,514,514,514,514,120,514,120,514,514,514,
+514,514,514,514,120,514,514,514,514,514,514,514,514,514,514,514,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
/* block 224 */
-504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,119,119,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
-504, 9,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505, 9,505,505,505,505,
-505,505,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,504, 9,505,505,505,505,
+514,514,514,514,513,513,120,513,513,513,513,120,120,513,513,513,
+513,513,513,513,513,120,513,513,513,513,513,513,513,120,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,513,513,120,513,513,513,513,120,
+513,513,513,513,513,120,513,120,120,120,513,513,513,513,513,513,
+513,120,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
/* block 225 */
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505, 9,505,505,505,505,505,505,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
-504,504,504,504,504, 9,505,505,505,505,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, 9,
-505,505,505,505,505,505,504,504,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, 9,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
+513,513,513,513,513,513,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
/* block 226 */
-505,505,505,505,505,505,505,505,505, 9,505,505,505,505,505,505,
-504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,
-504,504,504,504,504,504,504,504,504, 9,505,505,505,505,505,505,
-505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,
-505,505,505, 9,505,505,505,505,505,505,504,505,119,119, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+514,514,514,514,514,514,514,514,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
/* block 227 */
-911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
-911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
-911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
-911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
-911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
-911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
-911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
-911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,
+513,513,513,513,513,513,513,513,513,513,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,120,120,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513, 9,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514, 9,514,514,514,514,
+514,514,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513, 9,514,514,514,514,
/* block 228 */
-912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,
-912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,
-912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,
-912,912,912,912,912,912,912,911,911,911,911,912,912,912,912,912,
-912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,
-912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,
-912,912,912,912,912,912,912,912,912,912,912,912,912,911,911,911,
-911,911,911,911,911,912,911,911,911,911,911,911,911,911,911,911,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514, 9,514,514,514,514,514,514,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513, 9,514,514,514,514,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514, 9,
+514,514,514,514,514,514,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513, 9,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
/* block 229 */
-911,911,911,911,912,911,911,913,913,913,913,913,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,912,912,912,912,912,
-119,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+514,514,514,514,514,514,514,514,514, 9,514,514,514,514,514,514,
+513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,513,
+513,513,513,513,513,513,513,513,513, 9,514,514,514,514,514,514,
+514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,514,
+514,514,514, 9,514,514,514,514,514,514,513,514,120,120, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
/* block 230 */
-914,914,914,914,914,914,914,119,914,914,914,914,914,914,914,914,
-914,914,914,914,914,914,914,914,914,119,119,914,914,914,914,914,
-914,914,119,914,914,119,914,914,914,914,914,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
+932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
+932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
+932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
+932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
+932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
+932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
+932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,932,
/* block 231 */
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
+933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
+933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
+933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
+933,933,933,933,933,933,933,932,932,932,932,933,933,933,933,933,
+933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
+933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
+933,933,933,933,933,933,933,933,933,933,933,933,933,932,932,932,
+932,932,932,932,932,933,932,932,932,932,932,932,932,932,932,932,
/* block 232 */
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,915,
-915,915,915,915,915,119,119,916,916,916,916,916,916,916,916,916,
-917,917,917,917,917,917,917,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+932,932,932,932,933,932,932,934,934,934,934,934,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,933,933,933,933,933,
+120,933,933,933,933,933,933,933,933,933,933,933,933,933,933,933,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 233 */
-918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
-918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,918,
-918,918,919,919,919,919,919,919,919,919,919,919,919,919,919,919,
-919,919,919,919,919,919,919,919,919,919,919,919,919,919,919,919,
-919,919,919,919,920,920,920,920,920,920,920,119,119,119,119,119,
-921,921,921,921,921,921,921,921,921,921,119,119,119,119,922,922,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+935,935,935,935,935,935,935,120,935,935,935,935,935,935,935,935,
+935,935,935,935,935,935,935,935,935,120,120,935,935,935,935,935,
+935,935,120,935,935,120,935,935,935,935,935,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 234 */
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,
+936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,936,
+936,936,936,936,936,936,936,936,936,936,936,936,936,120,120,120,
+937,937,937,937,937,937,937,938,938,938,938,938,938,938,120,120,
+939,939,939,939,939,939,939,939,939,939,120,120,120,120,936,940,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 235 */
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25, 25, 25,
- 6, 25, 25, 25, 25,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,
+941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,941,
+941,941,941,941,941,941,941,941,941,941,941,941,942,942,942,942,
+943,943,943,943,943,943,943,943,943,943,120,120,120,120,120,944,
/* block 236 */
-224,224,224,224,119,224,224,224,224,224,224,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,
-119,224,224,119,224,119,119,224,119,224,224,224,224,224,224,224,
-224,224,224,119,224,224,224,224,119,224,119,224,119,119,119,119,
-119,119,224,119,119,119,119,224,119,224,119,224,119,224,224,224,
-119,224,224,119,224,119,119,224,119,224,119,224,119,224,119,224,
-119,224,224,119,224,119,119,224,224,224,224,119,224,224,224,224,
-224,224,224,119,224,224,224,224,119,224,224,224,224,119,224,119,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
/* block 237 */
-224,224,224,224,224,224,224,224,224,224,119,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,119,119,119,119,
-119,224,224,224,119,224,224,224,224,224,119,224,224,224,224,224,
-224,224,224,224,224,224,224,224,224,224,224,224,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-217,217,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,945,
+945,945,945,945,945,120,120,946,946,946,946,946,946,946,946,946,
+947,947,947,947,947,947,947,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 238 */
+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
+948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,948,
+948,948,949,949,949,949,949,949,949,949,949,949,949,949,949,949,
+949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,949,
+949,949,949,949,950,950,950,950,950,950,950,951,120,120,120,120,
+952,952,952,952,952,952,952,952,952,952,120,120,120,120,953,953,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 239 */
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+
+/* block 240 */
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25, 25, 25,
+ 6, 25, 25, 25, 25,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 241 */
+120, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 20, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 242 */
+225,225,225,225,120,225,225,225,225,225,225,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,225,
+120,225,225,120,225,120,120,225,120,225,225,225,225,225,225,225,
+225,225,225,120,225,225,225,225,120,225,120,225,120,120,120,120,
+120,120,225,120,120,120,120,225,120,225,120,225,120,225,225,225,
+120,225,225,120,225,120,120,225,120,225,120,225,120,225,120,225,
+120,225,225,120,225,120,120,225,225,225,225,120,225,225,225,225,
+225,225,225,120,225,225,225,225,120,225,225,225,225,120,225,120,
+
+/* block 243 */
+225,225,225,225,225,225,225,225,225,225,120,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,120,120,120,120,
+120,225,225,225,120,225,225,225,225,225,120,225,225,225,225,225,
+225,225,225,225,225,225,225,225,225,225,225,225,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+218,218,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 244 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923,923,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-/* block 239 */
+/* block 245 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,
-923, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-923, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-923, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,
+954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+954, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21,923,923,923,923,923,923,923,923,923,923,
+ 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,
-/* block 240 */
- 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,923,923,923,
+/* block 246 */
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,954,954,954,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,954,954,954,
21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21,
-/* block 241 */
+/* block 247 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20,
20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,924,924,924,924,924,924,924,924,924,924,
-924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,924,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,955,955,955,955,955,955,955,955,955,955,
+955,955,955,955,955,955,955,955,955,955,955,955,955,955,955,955,
-/* block 242 */
-925, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923,923,
+/* block 248 */
+956, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,954,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,
- 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20,923,923,923,923,
- 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923,923,
-575,575,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
- 21, 21, 21, 21, 21, 21,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+ 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20,954,954,954,954,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954,
+584,584,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+ 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-/* block 243 */
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+/* block 249 */
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-/* block 244 */
+/* block 250 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -4114,7 +4209,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-/* block 245 */
+/* block 251 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -4122,9 +4217,9 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,926,926,926,926,926,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,957,957,957,957,957,
-/* block 246 */
+/* block 252 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -4134,7 +4229,7 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-/* block 247 */
+/* block 253 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -4144,17 +4239,17 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-/* block 248 */
+/* block 254 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923,923,923,923,
+ 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954,954,
-/* block 249 */
+/* block 255 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
@@ -4162,187 +4257,197 @@ const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20,923,923,923,923,923,923,923,923,923,923,923,923,
+ 20, 20, 20, 20,954,954,954,954,954,954,954,954,954,954,954,954,
-/* block 250 */
+/* block 256 */
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 21, 21, 21, 21,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+ 20, 20, 20, 20, 20, 21, 21, 21, 21,954,954,954,954,954,954,954,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-/* block 251 */
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,
+/* block 257 */
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923,923,923,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923,
+ 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954,954,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-/* block 252 */
- 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923,923,923,
+/* block 258 */
+ 20, 20, 20, 20, 20, 20, 20, 20,954,954,954,954,954,954,954,954,
20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
-/* block 253 */
- 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,
+/* block 259 */
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,954, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 21,923,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21,923,923, 21, 21, 21, 21,923,923,923, 21,923, 21, 21, 21, 21,
+ 21, 21,954, 21, 21, 21, 21,954,954,954, 21, 21, 21, 21, 21, 21,
-/* block 254 */
+/* block 260 */
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923,923,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923,923,923,923,
- 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923,923,
+ 21, 21, 21,954,954, 21, 21, 21, 21, 21, 21,954,954,954, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-
-/* block 255 */
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
- 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-
-/* block 256 */
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,
-923,923,923,923,923,923,923,923,923,923,923,923,923,923,119,119,
-
-/* block 257 */
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-
-/* block 258 */
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,119,119,119,119,119,119,119,119,119,119,119,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-
-/* block 259 */
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,119,119,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-
-/* block 260 */
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
/* block 261 */
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,954,954,
+ 21, 21, 21, 21,954,954,954,954, 21, 21, 21,954,954,954,954,954,
/* block 262 */
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,
-577,577,577,577,577,577,577,577,577,577,577,577,577,577,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
-119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,
+ 21, 21, 21,954,954,954,954,954,954,954,954,954,954,954,954,954,
+ 21, 21, 21, 21, 21, 21,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
/* block 263 */
-502, 24,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,
-927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,
-927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,
-927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,
-927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,
-927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,954,
+954,954,954,954,954,954,954,954,954,954,954,954,954,954,120,120,
/* block 264 */
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
/* block 265 */
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,120,120,120,120,120,120,120,120,120,120,120,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
/* block 266 */
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,
-502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
/* block 267 */
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,
-659,659,659,659,659,659,659,659,659,659,659,659,659,659,119,119,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+
+/* block 268 */
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 269 */
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,
+586,586,586,586,586,586,586,586,586,586,586,586,586,586,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,
+
+/* block 270 */
+511, 24,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
+958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
+958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
+958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
+958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
+958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,958,
+
+/* block 271 */
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+
+/* block 272 */
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+
+/* block 273 */
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,113,
+511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,511,
+
+/* block 274 */
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,
+672,672,672,672,672,672,672,672,672,672,672,672,672,672,120,120,
};
diff --git a/thirdparty/pcre2/src/pcre2_ucp.h b/thirdparty/pcre2/src/pcre2_ucp.h
index 483abd18fc..84b22fb064 100644
--- a/thirdparty/pcre2/src/pcre2_ucp.h
+++ b/thirdparty/pcre2/src/pcre2_ucp.h
@@ -281,7 +281,12 @@ enum {
ucp_Makasar,
ucp_Medefaidrin,
ucp_Old_Sogdian,
- ucp_Sogdian
+ ucp_Sogdian,
+ /* New for Unicode 12.0.0 */
+ ucp_Elymaic,
+ ucp_Nandinagari,
+ ucp_Nyiakeng_Puachue_Hmong,
+ ucp_Wancho
};
#endif /* PCRE2_UCP_H_IDEMPOTENT_GUARD */
diff --git a/thirdparty/pcre2/src/sljit/sljitConfigInternal.h b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h
index ba60311e45..acba9da4be 100644
--- a/thirdparty/pcre2/src/sljit/sljitConfigInternal.h
+++ b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h
@@ -214,6 +214,10 @@
#define SLJIT_MEMCPY(dest, src, len) memcpy(dest, src, len)
#endif
+#ifndef SLJIT_MEMMOVE
+#define SLJIT_MEMMOVE(dest, src, len) memmove(dest, src, len)
+#endif
+
#ifndef SLJIT_ZEROMEM
#define SLJIT_ZEROMEM(dest, len) memset(dest, 0, len)
#endif
diff --git a/thirdparty/pcre2/src/sljit/sljitExecAllocator.c b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c
index 3b37a9751f..92ddb94914 100644
--- a/thirdparty/pcre2/src/sljit/sljitExecAllocator.c
+++ b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c
@@ -118,10 +118,20 @@ static SLJIT_INLINE int get_map_jit_flag()
if (map_jit_flag == -1) {
struct utsname name;
+ map_jit_flag = 0;
uname(&name);
/* Kernel version for 10.14.0 (Mojave) */
- map_jit_flag = (atoi(name.release) >= 18) ? MAP_JIT : 0;
+ if (atoi(name.release) >= 18) {
+ /* Only use MAP_JIT if a hardened runtime is used, because MAP_JIT is incompatible with fork(). */
+ void *ptr = mmap(NULL, getpagesize(), PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+
+ if (ptr == MAP_FAILED) {
+ map_jit_flag = MAP_JIT;
+ } else {
+ munmap(ptr, getpagesize());
+ }
+ }
}
return map_jit_flag;
@@ -137,6 +147,7 @@ static SLJIT_INLINE int get_map_jit_flag()
static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
{
void *retval;
+ const int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
#ifdef MAP_ANON
@@ -146,16 +157,25 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size)
flags |= get_map_jit_flag();
#endif
- retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, flags, -1, 0);
+ retval = mmap(NULL, size, prot, flags, -1, 0);
#else /* !MAP_ANON */
if (dev_zero < 0) {
if (open_dev_zero())
return NULL;
}
- retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0);
+ retval = mmap(NULL, size, prot, MAP_PRIVATE, dev_zero, 0);
#endif /* MAP_ANON */
- return (retval != MAP_FAILED) ? retval : NULL;
+ if (retval == MAP_FAILED)
+ retval = NULL;
+ else {
+ if (mprotect(retval, size, prot) < 0) {
+ munmap(retval, size);
+ retval = NULL;
+ }
+ }
+
+ return retval;
}
static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size)
diff --git a/thirdparty/pcre2/src/sljit/sljitLir.c b/thirdparty/pcre2/src/sljit/sljitLir.c
index ded9541b31..9bab0c3ec6 100644
--- a/thirdparty/pcre2/src/sljit/sljitLir.c
+++ b/thirdparty/pcre2/src/sljit/sljitLir.c
@@ -144,6 +144,7 @@
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
# define PATCH_MD 0x10
#endif
+# define TYPE_SHIFT 13
#endif
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
@@ -521,6 +522,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw
}
}
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label)
+{
+ if (SLJIT_LIKELY(!!put_label))
+ put_label->label = label;
+}
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
{
SLJIT_UNUSED_ARG(compiler);
@@ -620,6 +627,30 @@ static SLJIT_INLINE sljit_s32 get_arg_count(sljit_s32 arg_types)
return arg_count;
}
+#if !(defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+
+static SLJIT_INLINE sljit_uw compute_next_addr(struct sljit_label *label, struct sljit_jump *jump,
+ struct sljit_const *const_, struct sljit_put_label *put_label)
+{
+ sljit_uw result = ~(sljit_uw)0;
+
+ if (label)
+ result = label->size;
+
+ if (jump && jump->addr < result)
+ result = jump->addr;
+
+ if (const_ && const_->addr < result)
+ result = const_->addr;
+
+ if (put_label && put_label->addr < result)
+ result = put_label->addr;
+
+ return result;
+}
+
+#endif /* !SLJIT_CONFIG_X86 */
+
static SLJIT_INLINE void set_emit_enter(struct sljit_compiler *compiler,
sljit_s32 options, sljit_s32 args, sljit_s32 scratches, sljit_s32 saveds,
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
@@ -687,6 +718,19 @@ static SLJIT_INLINE void set_const(struct sljit_const *const_, struct sljit_comp
compiler->last_const = const_;
}
+static SLJIT_INLINE void set_put_label(struct sljit_put_label *put_label, struct sljit_compiler *compiler, sljit_uw offset)
+{
+ put_label->next = NULL;
+ put_label->label = NULL;
+ put_label->addr = compiler->size - offset;
+ put_label->flags = 0;
+ if (compiler->last_put_label)
+ compiler->last_put_label->next = put_label;
+ else
+ compiler->put_labels = put_label;
+ compiler->last_put_label = put_label;
+}
+
#define ADDRESSING_DEPENDS_ON(exp, reg) \
(((exp) & SLJIT_MEM) && (((exp) & REG_MASK) == reg || OFFS_REG(exp) == reg))
@@ -1905,6 +1949,21 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil
CHECK_RETURN_OK;
}
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ FUNCTION_CHECK_DST(dst, dstw, 0);
+#endif
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " put_label ");
+ sljit_verbose_param(compiler, dst, dstw);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif
+ CHECK_RETURN_OK;
+}
+
#endif /* SLJIT_ARGUMENT_CHECKS || SLJIT_VERBOSE */
#define SELECT_FOP1_OPERATION_WITH_CHECKS(compiler, op, dst, dstw, src, srcw) \
@@ -2581,6 +2640,14 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
return NULL;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(dst);
+ SLJIT_UNUSED_ARG(dstw);
+ return NULL;
+}
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
SLJIT_UNUSED_ARG(addr);
@@ -2597,4 +2664,4 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
SLJIT_UNREACHABLE();
}
-#endif
+#endif /* !SLJIT_CONFIG_UNSUPPORTED */
diff --git a/thirdparty/pcre2/src/sljit/sljitLir.h b/thirdparty/pcre2/src/sljit/sljitLir.h
index e71890cf7b..836d25cf71 100644
--- a/thirdparty/pcre2/src/sljit/sljitLir.h
+++ b/thirdparty/pcre2/src/sljit/sljitLir.h
@@ -348,13 +348,20 @@ struct sljit_label {
struct sljit_jump {
struct sljit_jump *next;
sljit_uw addr;
- sljit_sw flags;
+ sljit_uw flags;
union {
sljit_uw target;
- struct sljit_label* label;
+ struct sljit_label *label;
} u;
};
+struct sljit_put_label {
+ struct sljit_put_label *next;
+ struct sljit_label *label;
+ sljit_uw addr;
+ sljit_uw flags;
+};
+
struct sljit_const {
struct sljit_const *next;
sljit_uw addr;
@@ -366,10 +373,12 @@ struct sljit_compiler {
struct sljit_label *labels;
struct sljit_jump *jumps;
+ struct sljit_put_label *put_labels;
struct sljit_const *consts;
struct sljit_label *last_label;
struct sljit_jump *last_jump;
struct sljit_const *last_const;
+ struct sljit_put_label *last_put_label;
void *allocator_data;
struct sljit_memory_fragment *buf;
@@ -1314,10 +1323,17 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil
Flags: - (may destroy flags) */
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset);
-/* The constant can be changed runtime (see: sljit_set_const)
+/* Store a value that can be changed runtime (see: sljit_get_const_addr / sljit_set_const)
Flags: - (does not modify flags) */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value);
+/* Store the value of a label (see: sljit_set_put_label)
+ Flags: - (does not modify flags) */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
+
+/* Set the value stored by put_label to this label. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_put_label(struct sljit_put_label *put_label, struct sljit_label *label);
+
/* After the code generation the address for label, jump and const instructions
are computed. Since these structures are freed by sljit_free_compiler, the
addresses must be preserved by the user program elsewere. */
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c
index 6d61eed9a7..71f7bcdadb 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_32.c
@@ -583,8 +583,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
sljit_uw *buf_end;
sljit_uw size;
sljit_uw word_count;
+ sljit_uw next_addr;
sljit_sw executable_offset;
- sljit_sw jump_addr;
+ sljit_sw addr;
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
sljit_uw cpool_size;
sljit_uw cpool_skip_alignment;
@@ -597,6 +598,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
struct sljit_label *label;
struct sljit_jump *jump;
struct sljit_const *const_;
+ struct sljit_put_label *put_label;
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_generate_code(compiler));
@@ -625,11 +627,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = code;
word_count = 0;
+ next_addr = 1;
executable_offset = SLJIT_EXEC_OFFSET(code);
label = compiler->labels;
jump = compiler->jumps;
const_ = compiler->consts;
+ put_label = compiler->put_labels;
if (label && label->size == 0) {
label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
@@ -669,35 +673,45 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
else if ((*buf_ptr & 0xff000000) != PUSH_POOL) {
#endif
*code_ptr = *buf_ptr++;
+ if (next_addr == word_count) {
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
+
/* These structures are ordered by their address. */
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- if (jump && jump->addr == word_count) {
+ if (jump && jump->addr == word_count) {
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- if (detect_jump_type(jump, code_ptr, code, executable_offset))
- code_ptr--;
- jump->addr = (sljit_uw)code_ptr;
+ if (detect_jump_type(jump, code_ptr, code, executable_offset))
+ code_ptr--;
+ jump->addr = (sljit_uw)code_ptr;
#else
- jump->addr = (sljit_uw)(code_ptr - 2);
- if (detect_jump_type(jump, code_ptr, code, executable_offset))
- code_ptr -= 2;
+ jump->addr = (sljit_uw)(code_ptr - 2);
+ if (detect_jump_type(jump, code_ptr, code, executable_offset))
+ code_ptr -= 2;
#endif
- jump = jump->next;
- }
- if (label && label->size == word_count) {
- /* code_ptr can be affected above. */
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset);
- label->size = (code_ptr + 1) - code;
- label = label->next;
- }
- if (const_ && const_->addr == word_count) {
+ jump = jump->next;
+ }
+ if (label && label->size == word_count) {
+ /* code_ptr can be affected above. */
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr + 1, executable_offset);
+ label->size = (code_ptr + 1) - code;
+ label = label->next;
+ }
+ if (const_ && const_->addr == word_count) {
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- const_->addr = (sljit_uw)code_ptr;
+ const_->addr = (sljit_uw)code_ptr;
#else
- const_->addr = (sljit_uw)(code_ptr - 1);
+ const_->addr = (sljit_uw)(code_ptr - 1);
#endif
- const_ = const_->next;
+ const_ = const_->next;
+ }
+ if (put_label && put_label->addr == word_count) {
+ SLJIT_ASSERT(put_label->label);
+ put_label->addr = (sljit_uw)code_ptr;
+ put_label = put_label->next;
+ }
+ next_addr = compute_next_addr(label, jump, const_, put_label);
}
code_ptr++;
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
@@ -725,6 +739,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(!label);
SLJIT_ASSERT(!jump);
SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(!put_label);
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
SLJIT_ASSERT(cpool_size == 0);
@@ -755,15 +770,15 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
buf_ptr = (sljit_uw *)jump->addr;
if (jump->flags & PATCH_B) {
- jump_addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);
+ addr = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(buf_ptr + 2, executable_offset);
if (!(jump->flags & JUMP_ADDR)) {
SLJIT_ASSERT(jump->flags & JUMP_LABEL);
- SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - jump_addr) >= -0x02000000);
- *buf_ptr |= (((sljit_sw)jump->u.label->addr - jump_addr) >> 2) & 0x00ffffff;
+ SLJIT_ASSERT(((sljit_sw)jump->u.label->addr - addr) <= 0x01ffffff && ((sljit_sw)jump->u.label->addr - addr) >= -0x02000000);
+ *buf_ptr |= (((sljit_sw)jump->u.label->addr - addr) >> 2) & 0x00ffffff;
}
else {
- SLJIT_ASSERT(((sljit_sw)jump->u.target - jump_addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - jump_addr) >= -0x02000000);
- *buf_ptr |= (((sljit_sw)jump->u.target - jump_addr) >> 2) & 0x00ffffff;
+ SLJIT_ASSERT(((sljit_sw)jump->u.target - addr) <= 0x01ffffff && ((sljit_sw)jump->u.target - addr) >= -0x02000000);
+ *buf_ptr |= (((sljit_sw)jump->u.target - addr) >> 2) & 0x00ffffff;
}
}
else if (jump->flags & SLJIT_REWRITABLE_JUMP) {
@@ -813,6 +828,22 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
}
#endif
+ put_label = compiler->put_labels;
+ while (put_label) {
+ addr = put_label->label->addr;
+ buf_ptr = (sljit_uw*)put_label->addr;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ SLJIT_ASSERT((buf_ptr[0] & 0xffff0000) == 0xe59f0000);
+ buf_ptr[((buf_ptr[0] & 0xfff) >> 2) + 2] = addr;
+#else
+ SLJIT_ASSERT((buf_ptr[-1] & 0xfff00000) == MOVW && (buf_ptr[0] & 0xfff00000) == MOVT);
+ buf_ptr[-1] |= ((addr << 4) & 0xf0000) | (addr & 0xfff);
+ buf_ptr[0] |= ((addr >> 12) & 0xf0000) | ((addr >> 16) & 0xfff);
+#endif
+ put_label = put_label->next;
+ }
+
SLJIT_ASSERT(code_ptr - code <= (sljit_s32)size);
compiler->error = SLJIT_ERR_COMPILED;
@@ -2639,28 +2670,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem(struct sljit_compiler *compile
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
{
struct sljit_const *const_;
- sljit_s32 reg;
+ sljit_s32 dst_r;
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
ADJUST_LOCAL_OFFSET(dst, dstw);
+ dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG2;
+
+#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
+ PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), init_value));
+ compiler->patches++;
+#else
+ PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value));
+#endif
+
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
PTR_FAIL_IF(!const_);
+ set_const(const_, compiler);
- reg = SLOW_IS_REG(dst) ? dst : TMP_REG2;
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));
+ return const_;
+}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ struct sljit_put_label *put_label;
+ sljit_s32 dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ dst_r = SLOW_IS_REG(dst) ? dst : TMP_REG2;
#if (defined SLJIT_CONFIG_ARM_V5 && SLJIT_CONFIG_ARM_V5)
- PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, reg, TMP_PC, 0), init_value));
+ PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), 0));
compiler->patches++;
#else
- PTR_FAIL_IF(emit_imm(compiler, reg, init_value));
+ PTR_FAIL_IF(emit_imm(compiler, dst_r, 0));
#endif
- set_const(const_, compiler);
+
+ put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
+ PTR_FAIL_IF(!put_label);
+ set_put_label(put_label, compiler, 0);
if (dst & SLJIT_MEM)
PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));
- return const_;
+ return put_label;
}
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c
index b015695c52..e15b3451e8 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c
@@ -161,7 +161,7 @@ static SLJIT_INLINE void modify_imm64_const(sljit_ins* inst, sljit_uw new_imm)
inst[3] = MOVK | dst | ((new_imm >> 48) << 5) | (3 << 21);
}
-static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
+static SLJIT_INLINE sljit_sw detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
{
sljit_sw diff;
sljit_uw target_addr;
@@ -196,14 +196,14 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in
return 4;
}
- if (target_addr <= 0xffffffffl) {
+ if (target_addr < 0x100000000l) {
if (jump->flags & IS_COND)
code_ptr[-5] -= (2 << 5);
code_ptr[-2] = code_ptr[0];
return 2;
}
- if (target_addr <= 0xffffffffffffl) {
+ if (target_addr < 0x1000000000000l) {
if (jump->flags & IS_COND)
code_ptr[-5] -= (1 << 5);
jump->flags |= PATCH_ABS48;
@@ -215,6 +215,22 @@ static SLJIT_INLINE sljit_s32 detect_jump_type(struct sljit_jump *jump, sljit_in
return 0;
}
+static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
+{
+ if (max_label < 0x100000000l) {
+ put_label->flags = 0;
+ return 2;
+ }
+
+ if (max_label < 0x1000000000000l) {
+ put_label->flags = 1;
+ return 1;
+ }
+
+ put_label->flags = 2;
+ return 0;
+}
+
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
{
struct sljit_memory_fragment *buf;
@@ -223,6 +239,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
sljit_ins *buf_ptr;
sljit_ins *buf_end;
sljit_uw word_count;
+ sljit_uw next_addr;
sljit_sw executable_offset;
sljit_uw addr;
sljit_s32 dst;
@@ -230,6 +247,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
struct sljit_label *label;
struct sljit_jump *jump;
struct sljit_const *const_;
+ struct sljit_put_label *put_label;
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_generate_code(compiler));
@@ -241,34 +259,47 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = code;
word_count = 0;
+ next_addr = 0;
executable_offset = SLJIT_EXEC_OFFSET(code);
label = compiler->labels;
jump = compiler->jumps;
const_ = compiler->consts;
+ put_label = compiler->put_labels;
do {
buf_ptr = (sljit_ins*)buf->memory;
buf_end = buf_ptr + (buf->used_size >> 2);
do {
*code_ptr = *buf_ptr++;
- /* These structures are ordered by their address. */
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- if (label && label->size == word_count) {
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = code_ptr - code;
- label = label->next;
- }
- if (jump && jump->addr == word_count) {
- jump->addr = (sljit_uw)(code_ptr - 4);
- code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
- jump = jump->next;
- }
- if (const_ && const_->addr == word_count) {
- const_->addr = (sljit_uw)code_ptr;
- const_ = const_->next;
+ if (next_addr == word_count) {
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
+
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
+ jump->addr = (sljit_uw)(code_ptr - 4);
+ code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == word_count) {
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ if (put_label && put_label->addr == word_count) {
+ SLJIT_ASSERT(put_label->label);
+ put_label->addr = (sljit_uw)(code_ptr - 3);
+ code_ptr -= put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
+ put_label = put_label->next;
+ }
+ next_addr = compute_next_addr(label, jump, const_, put_label);
}
code_ptr ++;
word_count ++;
@@ -286,6 +317,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(!label);
SLJIT_ASSERT(!jump);
SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(!put_label);
SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
jump = compiler->jumps;
@@ -323,6 +355,23 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
jump = jump->next;
}
+ put_label = compiler->put_labels;
+ while (put_label) {
+ addr = put_label->label->addr;
+ buf_ptr = (sljit_ins *)put_label->addr;
+
+ buf_ptr[0] |= (addr & 0xffff) << 5;
+ buf_ptr[1] |= ((addr >> 16) & 0xffff) << 5;
+
+ if (put_label->flags >= 1)
+ buf_ptr[2] |= ((addr >> 32) & 0xffff) << 5;
+
+ if (put_label->flags >= 2)
+ buf_ptr[3] |= ((addr >> 48) & 0xffff) << 5;
+
+ put_label = put_label->next;
+ }
+
compiler->error = SLJIT_ERR_COMPILED;
compiler->executable_offset = executable_offset;
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
@@ -1947,6 +1996,28 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
return const_;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ struct sljit_put_label *put_label;
+ sljit_s32 dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+ PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, 0));
+
+ put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
+ PTR_FAIL_IF(!put_label);
+ set_put_label(put_label, compiler, 1);
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
+
+ return put_label;
+}
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_ins* inst = (sljit_ins*)addr;
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c
index d7024b6d7d..cdfe4a4d24 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_T2_32.c
@@ -365,11 +365,13 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
sljit_u16 *buf_ptr;
sljit_u16 *buf_end;
sljit_uw half_count;
+ sljit_uw next_addr;
sljit_sw executable_offset;
struct sljit_label *label;
struct sljit_jump *jump;
struct sljit_const *const_;
+ struct sljit_put_label *put_label;
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_generate_code(compiler));
@@ -381,34 +383,46 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = code;
half_count = 0;
+ next_addr = 0;
executable_offset = SLJIT_EXEC_OFFSET(code);
label = compiler->labels;
jump = compiler->jumps;
const_ = compiler->consts;
+ put_label = compiler->put_labels;
do {
buf_ptr = (sljit_u16*)buf->memory;
buf_end = buf_ptr + (buf->used_size >> 1);
do {
*code_ptr = *buf_ptr++;
- /* These structures are ordered by their address. */
- SLJIT_ASSERT(!label || label->size >= half_count);
- SLJIT_ASSERT(!jump || jump->addr >= half_count);
- SLJIT_ASSERT(!const_ || const_->addr >= half_count);
- if (label && label->size == half_count) {
- label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
- label->size = code_ptr - code;
- label = label->next;
- }
- if (jump && jump->addr == half_count) {
- jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8);
- code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
- jump = jump->next;
- }
- if (const_ && const_->addr == half_count) {
- const_->addr = (sljit_uw)code_ptr;
- const_ = const_->next;
+ if (next_addr == half_count) {
+ SLJIT_ASSERT(!label || label->size >= half_count);
+ SLJIT_ASSERT(!jump || jump->addr >= half_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= half_count);
+ SLJIT_ASSERT(!put_label || put_label->addr >= half_count);
+
+ /* These structures are ordered by their address. */
+ if (label && label->size == half_count) {
+ label->addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == half_count) {
+ jump->addr = (sljit_uw)code_ptr - ((jump->flags & IS_COND) ? 10 : 8);
+ code_ptr -= detect_jump_type(jump, code_ptr, code, executable_offset);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == half_count) {
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ if (put_label && put_label->addr == half_count) {
+ SLJIT_ASSERT(put_label->label);
+ put_label->addr = (sljit_uw)code_ptr;
+ put_label = put_label->next;
+ }
+ next_addr = compute_next_addr(label, jump, const_, put_label);
}
code_ptr ++;
half_count ++;
@@ -426,6 +440,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(!label);
SLJIT_ASSERT(!jump);
SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(!put_label);
SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
jump = compiler->jumps;
@@ -434,6 +449,12 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
jump = jump->next;
}
+ put_label = compiler->put_labels;
+ while (put_label) {
+ modify_imm32_const((sljit_u16 *)put_label->addr, put_label->label->addr);
+ put_label = put_label->next;
+ }
+
compiler->error = SLJIT_ERR_COMPILED;
compiler->executable_offset = executable_offset;
compiler->executable_size = (code_ptr - code) * sizeof(sljit_u16);
@@ -2311,6 +2332,27 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
return const_;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ struct sljit_put_label *put_label;
+ sljit_s32 dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
+ PTR_FAIL_IF(!put_label);
+ set_put_label(put_label, compiler, 0);
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+ PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, 0));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
+ return put_label;
+}
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
sljit_u16 *inst = (sljit_u16*)addr;
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c
index ad970bf25a..16dec052fe 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c
@@ -425,6 +425,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
@@ -435,6 +436,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c
index e0d6a3f085..7d1d087496 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c
@@ -449,6 +449,55 @@ static __attribute__ ((noinline)) void sljit_cache_flush(void* code, void* code_
}
#endif
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+
+static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
+{
+ if (max_label < 0x80000000l) {
+ put_label->flags = 0;
+ return 1;
+ }
+
+ if (max_label < 0x800000000000l) {
+ put_label->flags = 1;
+ return 3;
+ }
+
+ put_label->flags = 2;
+ return 5;
+}
+
+static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label)
+{
+ sljit_uw addr = put_label->label->addr;
+ sljit_ins *inst = (sljit_ins *)put_label->addr;
+ sljit_s32 reg = *inst;
+
+ if (put_label->flags == 0) {
+ SLJIT_ASSERT(addr < 0x80000000l);
+ inst[0] = LUI | T(reg) | IMM(addr >> 16);
+ }
+ else if (put_label->flags == 1) {
+ SLJIT_ASSERT(addr < 0x800000000000l);
+ inst[0] = LUI | T(reg) | IMM(addr >> 32);
+ inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
+ inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
+ inst += 2;
+ }
+ else {
+ inst[0] = LUI | T(reg) | IMM(addr >> 48);
+ inst[1] = ORI | S(reg) | T(reg) | IMM((addr >> 32) & 0xffff);
+ inst[2] = DSLL | T(reg) | D(reg) | SH_IMM(16);
+ inst[3] = ORI | S(reg) | T(reg) | IMM((addr >> 16) & 0xffff);
+ inst[4] = DSLL | T(reg) | D(reg) | SH_IMM(16);
+ inst += 4;
+ }
+
+ inst[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);
+}
+
+#endif
+
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
{
struct sljit_memory_fragment *buf;
@@ -457,12 +506,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
sljit_ins *buf_ptr;
sljit_ins *buf_end;
sljit_uw word_count;
+ sljit_uw next_addr;
sljit_sw executable_offset;
sljit_uw addr;
struct sljit_label *label;
struct sljit_jump *jump;
struct sljit_const *const_;
+ struct sljit_put_label *put_label;
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_generate_code(compiler));
@@ -474,39 +525,54 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = code;
word_count = 0;
+ next_addr = 0;
executable_offset = SLJIT_EXEC_OFFSET(code);
label = compiler->labels;
jump = compiler->jumps;
const_ = compiler->consts;
+ put_label = compiler->put_labels;
do {
buf_ptr = (sljit_ins*)buf->memory;
buf_end = buf_ptr + (buf->used_size >> 2);
do {
*code_ptr = *buf_ptr++;
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- /* These structures are ordered by their address. */
- if (label && label->size == word_count) {
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = code_ptr - code;
- label = label->next;
- }
- if (jump && jump->addr == word_count) {
+ if (next_addr == word_count) {
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
+
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
- jump->addr = (sljit_uw)(code_ptr - 3);
+ jump->addr = (sljit_uw)(code_ptr - 3);
#else
- jump->addr = (sljit_uw)(code_ptr - 7);
+ jump->addr = (sljit_uw)(code_ptr - 7);
#endif
- code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
- jump = jump->next;
- }
- if (const_ && const_->addr == word_count) {
- /* Just recording the address. */
- const_->addr = (sljit_uw)code_ptr;
- const_ = const_->next;
+ code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == word_count) {
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ if (put_label && put_label->addr == word_count) {
+ SLJIT_ASSERT(put_label->label);
+ put_label->addr = (sljit_uw)code_ptr;
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+ code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
+ word_count += 5;
+#endif
+ put_label = put_label->next;
+ }
+ next_addr = compute_next_addr(label, jump, const_, put_label);
}
code_ptr ++;
word_count ++;
@@ -524,6 +590,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(!label);
SLJIT_ASSERT(!jump);
SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(!put_label);
SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
jump = compiler->jumps;
@@ -571,6 +638,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
jump = jump->next;
}
+ put_label = compiler->put_labels;
+ while (put_label) {
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ addr = put_label->label->addr;
+ buf_ptr = (sljit_ins *)put_label->addr;
+
+ SLJIT_ASSERT((buf_ptr[0] & 0xffe00000) == LUI && (buf_ptr[1] & 0xfc000000) == ORI);
+ buf_ptr[0] |= (addr >> 16) & 0xffff;
+ buf_ptr[1] |= addr & 0xffff;
+#else
+ put_label_set(put_label);
+#endif
+ put_label = put_label->next;
+ }
+
compiler->error = SLJIT_ERR_COMPILED;
compiler->executable_offset = executable_offset;
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
@@ -2157,7 +2239,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
{
struct sljit_const *const_;
- sljit_s32 reg;
+ sljit_s32 dst_r;
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
@@ -2167,11 +2249,38 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
PTR_FAIL_IF(!const_);
set_const(const_, compiler);
- reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
-
- PTR_FAIL_IF(emit_const(compiler, reg, init_value));
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
if (dst & SLJIT_MEM)
PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+
return const_;
}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ struct sljit_put_label *put_label;
+ sljit_s32 dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
+ PTR_FAIL_IF(!put_label);
+ set_put_label(put_label, compiler, 0);
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
+ PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
+#else
+ PTR_FAIL_IF(push_inst(compiler, dst_r, UNMOVABLE_INS));
+ compiler->size += 5;
+#endif
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+
+ return put_label;
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c
index fc185f7847..3ce741153f 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_32.c
@@ -259,6 +259,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
@@ -269,6 +270,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
inst[0] = (inst[0] & 0xffff0000) | ((new_constant >> 16) & 0xffff);
inst[1] = (inst[1] & 0xffff0000) | (new_constant & 0xffff);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c
index 706b2ba20b..3b73021cc8 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_64.c
@@ -35,9 +35,6 @@
#error "Must implement count leading zeroes"
#endif
-#define RLDI(dst, src, sh, mb, type) \
- (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20))
-
#define PUSH_RLDICR(reg, shift) \
push_inst(compiler, RLDI(reg, reg, 63 - shift, shift, 1))
diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c
index b34e3965ed..e827514315 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c
@@ -231,6 +231,9 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
#define SIMM_MIN (-0x8000)
#define UIMM_MAX (0xffff)
+#define RLDI(dst, src, sh, mb, type) \
+ (HI(30) | S(src) | A(dst) | ((type) << 2) | (((sh) & 0x1f) << 11) | (((sh) & 0x20) >> 4) | (((mb) & 0x1f) << 6) | ((mb) & 0x20))
+
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_function_context(void** func_ptr, struct sljit_function_context* context, sljit_sw addr, void* func)
{
@@ -324,6 +327,55 @@ keep_address:
return 0;
}
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+
+static SLJIT_INLINE sljit_sw put_label_get_length(struct sljit_put_label *put_label, sljit_uw max_label)
+{
+ if (max_label < 0x100000000l) {
+ put_label->flags = 0;
+ return 1;
+ }
+
+ if (max_label < 0x1000000000000l) {
+ put_label->flags = 1;
+ return 3;
+ }
+
+ put_label->flags = 2;
+ return 4;
+}
+
+static SLJIT_INLINE void put_label_set(struct sljit_put_label *put_label)
+{
+ sljit_uw addr = put_label->label->addr;
+ sljit_ins *inst = (sljit_ins *)put_label->addr;
+ sljit_s32 reg = *inst;
+
+ if (put_label->flags == 0) {
+ SLJIT_ASSERT(addr < 0x100000000l);
+ inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 16);
+ }
+ else {
+ if (put_label->flags == 1) {
+ SLJIT_ASSERT(addr < 0x1000000000000l);
+ inst[0] = ORI | S(TMP_ZERO) | A(reg) | IMM(addr >> 32);
+ }
+ else {
+ inst[0] = ORIS | S(TMP_ZERO) | A(reg) | IMM(addr >> 48);
+ inst[1] = ORI | S(reg) | A(reg) | IMM((addr >> 32) & 0xffff);
+ inst ++;
+ }
+
+ inst[1] = RLDI(reg, reg, 32, 31, 1);
+ inst[2] = ORIS | S(reg) | A(reg) | IMM((addr >> 16) & 0xffff);
+ inst += 2;
+ }
+
+ inst[1] = ORI | S(reg) | A(reg) | IMM(addr & 0xffff);
+}
+
+#endif
+
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler)
{
struct sljit_memory_fragment *buf;
@@ -332,12 +384,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
sljit_ins *buf_ptr;
sljit_ins *buf_end;
sljit_uw word_count;
+ sljit_uw next_addr;
sljit_sw executable_offset;
sljit_uw addr;
struct sljit_label *label;
struct sljit_jump *jump;
struct sljit_const *const_;
+ struct sljit_put_label *put_label;
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_generate_code(compiler));
@@ -356,71 +410,87 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = code;
word_count = 0;
+ next_addr = 0;
executable_offset = SLJIT_EXEC_OFFSET(code);
label = compiler->labels;
jump = compiler->jumps;
const_ = compiler->consts;
+ put_label = compiler->put_labels;
do {
buf_ptr = (sljit_ins*)buf->memory;
buf_end = buf_ptr + (buf->used_size >> 2);
do {
*code_ptr = *buf_ptr++;
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- /* These structures are ordered by their address. */
- if (label && label->size == word_count) {
- /* Just recording the address. */
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = code_ptr - code;
- label = label->next;
- }
- if (jump && jump->addr == word_count) {
+ if (next_addr == word_count) {
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
+
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ /* Just recording the address. */
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- jump->addr = (sljit_uw)(code_ptr - 3);
+ jump->addr = (sljit_uw)(code_ptr - 3);
#else
- jump->addr = (sljit_uw)(code_ptr - 6);
+ jump->addr = (sljit_uw)(code_ptr - 6);
#endif
- if (detect_jump_type(jump, code_ptr, code, executable_offset)) {
+ if (detect_jump_type(jump, code_ptr, code, executable_offset)) {
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
- code_ptr[-3] = code_ptr[0];
- code_ptr -= 3;
-#else
- if (jump->flags & PATCH_ABS32) {
+ code_ptr[-3] = code_ptr[0];
code_ptr -= 3;
- code_ptr[-1] = code_ptr[2];
- code_ptr[0] = code_ptr[3];
- }
- else if (jump->flags & PATCH_ABS48) {
- code_ptr--;
- code_ptr[-1] = code_ptr[0];
- code_ptr[0] = code_ptr[1];
- /* rldicr rX,rX,32,31 -> rX,rX,16,47 */
- SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6);
- code_ptr[-3] ^= 0x8422;
- /* oris -> ori */
- code_ptr[-2] ^= 0x4000000;
- }
- else {
- code_ptr[-6] = code_ptr[0];
- code_ptr -= 6;
- }
+#else
+ if (jump->flags & PATCH_ABS32) {
+ code_ptr -= 3;
+ code_ptr[-1] = code_ptr[2];
+ code_ptr[0] = code_ptr[3];
+ }
+ else if (jump->flags & PATCH_ABS48) {
+ code_ptr--;
+ code_ptr[-1] = code_ptr[0];
+ code_ptr[0] = code_ptr[1];
+ /* rldicr rX,rX,32,31 -> rX,rX,16,47 */
+ SLJIT_ASSERT((code_ptr[-3] & 0xfc00ffff) == 0x780007c6);
+ code_ptr[-3] ^= 0x8422;
+ /* oris -> ori */
+ code_ptr[-2] ^= 0x4000000;
+ }
+ else {
+ code_ptr[-6] = code_ptr[0];
+ code_ptr -= 6;
+ }
#endif
- if (jump->flags & REMOVE_COND) {
- code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);
- code_ptr++;
- jump->addr += sizeof(sljit_ins);
- code_ptr[0] = Bx;
- jump->flags -= IS_COND;
+ if (jump->flags & REMOVE_COND) {
+ code_ptr[0] = BCx | (2 << 2) | ((code_ptr[0] ^ (8 << 21)) & 0x03ff0001);
+ code_ptr++;
+ jump->addr += sizeof(sljit_ins);
+ code_ptr[0] = Bx;
+ jump->flags -= IS_COND;
+ }
}
+ jump = jump->next;
}
- jump = jump->next;
- }
- if (const_ && const_->addr == word_count) {
- const_->addr = (sljit_uw)code_ptr;
- const_ = const_->next;
+ if (const_ && const_->addr == word_count) {
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ if (put_label && put_label->addr == word_count) {
+ SLJIT_ASSERT(put_label->label);
+ put_label->addr = (sljit_uw)code_ptr;
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ code_ptr += put_label_get_length(put_label, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
+ word_count += 4;
+#endif
+ put_label = put_label->next;
+ }
+ next_addr = compute_next_addr(label, jump, const_, put_label);
}
code_ptr ++;
word_count ++;
@@ -438,6 +508,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(!label);
SLJIT_ASSERT(!jump);
SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(!put_label);
+
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins)));
#else
@@ -503,6 +575,21 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
jump = jump->next;
}
+ put_label = compiler->put_labels;
+ while (put_label) {
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ addr = put_label->label->addr;
+ buf_ptr = (sljit_ins *)put_label->addr;
+
+ SLJIT_ASSERT((buf_ptr[0] & 0xfc1f0000) == ADDIS && (buf_ptr[1] & 0xfc000000) == ORI);
+ buf_ptr[0] |= (addr >> 16) & 0xffff;
+ buf_ptr[1] |= addr & 0xffff;
+#else
+ put_label_set(put_label);
+#endif
+ put_label = put_label->next;
+ }
+
compiler->error = SLJIT_ERR_COMPILED;
compiler->executable_offset = executable_offset;
compiler->executable_size = (code_ptr - code) * sizeof(sljit_ins);
@@ -2261,7 +2348,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fmem(struct sljit_compiler *compil
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
{
struct sljit_const *const_;
- sljit_s32 reg;
+ sljit_s32 dst_r;
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
@@ -2271,11 +2358,38 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
PTR_FAIL_IF(!const_);
set_const(const_, compiler);
- reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
-
- PTR_FAIL_IF(emit_const(compiler, reg, init_value));
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
if (dst & SLJIT_MEM)
PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+
return const_;
}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ struct sljit_put_label *put_label;
+ sljit_s32 dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
+ PTR_FAIL_IF(!put_label);
+ set_put_label(put_label, compiler, 0);
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
+ PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
+#else
+ PTR_FAIL_IF(push_inst(compiler, dst_r));
+ compiler->size += 4;
+#endif
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+
+ return put_label;
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c
index 0671b130cc..8079fad8df 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_32.c
@@ -267,6 +267,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000));
inst[0] = (inst[0] & 0xffc00000) | ((new_target >> 10) & 0x3fffff);
inst[1] = (inst[1] & 0xfffffc00) | (new_target & 0x3ff);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
@@ -277,6 +278,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_consta
{
sljit_ins *inst = (sljit_ins *)addr;
+ SLJIT_ASSERT(((inst[0] & 0xc1c00000) == 0x01000000) && ((inst[1] & 0xc1f82000) == 0x80102000));
inst[0] = (inst[0] & 0xffc00000) | ((new_constant >> 10) & 0x3fffff);
inst[1] = (inst[1] & 0xfffffc00) | (new_constant & 0x3ff);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c
index 669ecd8152..bfa4ecede2 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeSPARC_common.c
@@ -298,12 +298,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
sljit_ins *buf_ptr;
sljit_ins *buf_end;
sljit_uw word_count;
+ sljit_uw next_addr;
sljit_sw executable_offset;
sljit_uw addr;
struct sljit_label *label;
struct sljit_jump *jump;
struct sljit_const *const_;
+ struct sljit_put_label *put_label;
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_generate_code(compiler));
@@ -315,40 +317,52 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code_ptr = code;
word_count = 0;
+ next_addr = 0;
executable_offset = SLJIT_EXEC_OFFSET(code);
label = compiler->labels;
jump = compiler->jumps;
const_ = compiler->consts;
+ put_label = compiler->put_labels;
do {
buf_ptr = (sljit_ins*)buf->memory;
buf_end = buf_ptr + (buf->used_size >> 2);
do {
*code_ptr = *buf_ptr++;
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
- /* These structures are ordered by their address. */
- if (label && label->size == word_count) {
- /* Just recording the address. */
- label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- label->size = code_ptr - code;
- label = label->next;
- }
- if (jump && jump->addr == word_count) {
+ if (next_addr == word_count) {
+ SLJIT_ASSERT(!label || label->size >= word_count);
+ SLJIT_ASSERT(!jump || jump->addr >= word_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ SLJIT_ASSERT(!put_label || put_label->addr >= word_count);
+
+ /* These structures are ordered by their address. */
+ if (label && label->size == word_count) {
+ /* Just recording the address. */
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ }
+ if (jump && jump->addr == word_count) {
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
- jump->addr = (sljit_uw)(code_ptr - 3);
+ jump->addr = (sljit_uw)(code_ptr - 3);
#else
- jump->addr = (sljit_uw)(code_ptr - 6);
+ jump->addr = (sljit_uw)(code_ptr - 6);
#endif
- code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
- jump = jump->next;
- }
- if (const_ && const_->addr == word_count) {
- /* Just recording the address. */
- const_->addr = (sljit_uw)code_ptr;
- const_ = const_->next;
+ code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
+ jump = jump->next;
+ }
+ if (const_ && const_->addr == word_count) {
+ /* Just recording the address. */
+ const_->addr = (sljit_uw)code_ptr;
+ const_ = const_->next;
+ }
+ if (put_label && put_label->addr == word_count) {
+ SLJIT_ASSERT(put_label->label);
+ put_label->addr = (sljit_uw)code_ptr;
+ put_label = put_label->next;
+ }
+ next_addr = compute_next_addr(label, jump, const_, put_label);
}
code_ptr ++;
word_count ++;
@@ -366,6 +380,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(!label);
SLJIT_ASSERT(!jump);
SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(!put_label);
SLJIT_ASSERT(code_ptr - code <= (sljit_s32)compiler->size);
jump = compiler->jumps;
@@ -389,8 +404,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
/* Set the fields of immediate loads. */
#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
- buf_ptr[0] = (buf_ptr[0] & 0xffc00000) | ((addr >> 10) & 0x3fffff);
- buf_ptr[1] = (buf_ptr[1] & 0xfffffc00) | (addr & 0x3ff);
+ SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000));
+ buf_ptr[0] |= (addr >> 10) & 0x3fffff;
+ buf_ptr[1] |= addr & 0x3ff;
#else
#error "Implementation required"
#endif
@@ -398,6 +414,20 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
jump = jump->next;
}
+ put_label = compiler->put_labels;
+ while (put_label) {
+ addr = put_label->label->addr;
+ buf_ptr = (sljit_ins *)put_label->addr;
+
+#if (defined SLJIT_CONFIG_SPARC_32 && SLJIT_CONFIG_SPARC_32)
+ SLJIT_ASSERT(((buf_ptr[0] & 0xc1cfffff) == 0x01000000) && ((buf_ptr[1] & 0xc1f83fff) == 0x80102000));
+ buf_ptr[0] |= (addr >> 10) & 0x3fffff;
+ buf_ptr[1] |= addr & 0x3ff;
+#else
+#error "Implementation required"
+#endif
+ put_label = put_label->next;
+ }
compiler->error = SLJIT_ERR_COMPILED;
compiler->executable_offset = executable_offset;
@@ -1465,8 +1495,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil
SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
{
- sljit_s32 reg;
struct sljit_const *const_;
+ sljit_s32 dst_r;
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
@@ -1476,11 +1506,31 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
PTR_FAIL_IF(!const_);
set_const(const_, compiler);
- reg = FAST_IS_REG(dst) ? dst : TMP_REG2;
-
- PTR_FAIL_IF(emit_const(compiler, reg, init_value));
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
if (dst & SLJIT_MEM)
PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
return const_;
}
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ struct sljit_put_label *put_label;
+ sljit_s32 dst_r;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
+ PTR_FAIL_IF(!put_label);
+ set_put_label(put_label, compiler, 0);
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ PTR_FAIL_IF(emit_const(compiler, dst_r, 0));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
+ return put_label;
+}
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c
index 074e64b9f2..34a3a3d940 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_32.c
@@ -38,8 +38,10 @@ static sljit_s32 emit_do_imm(struct sljit_compiler *compiler, sljit_u8 opcode, s
return SLJIT_SUCCESS;
}
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset)
+static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset)
{
+ sljit_s32 type = jump->flags >> TYPE_SHIFT;
+
if (type == SLJIT_JUMP) {
*code_ptr++ = JMP_i32;
jump->addr++;
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c
index 8506565614..5758711954 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_64.c
@@ -39,8 +39,10 @@ static sljit_s32 emit_load_imm64(struct sljit_compiler *compiler, sljit_s32 reg,
return SLJIT_SUCCESS;
}
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type)
+static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr)
{
+ sljit_s32 type = jump->flags >> TYPE_SHIFT;
+
int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && !(jump->flags & JUMP_LABEL) && (jump->u.target <= 0xffffffff);
/* The relative jump below specialized for this case. */
@@ -72,6 +74,56 @@ static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_
return code_ptr;
}
+static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label)
+{
+ if (max_label > HALFWORD_MAX) {
+ put_label->addr -= put_label->flags;
+ put_label->flags = PATCH_MD;
+ return code_ptr;
+ }
+
+ if (put_label->flags == 0) {
+ /* Destination is register. */
+ code_ptr = (sljit_u8*)put_label->addr - 2 - sizeof(sljit_uw);
+
+ SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
+ SLJIT_ASSERT((code_ptr[1] & 0xf8) == MOV_r_i32);
+
+ if ((code_ptr[0] & 0x07) != 0) {
+ code_ptr[0] = (sljit_u8)(code_ptr[0] & ~0x08);
+ code_ptr += 2 + sizeof(sljit_s32);
+ }
+ else {
+ code_ptr[0] = code_ptr[1];
+ code_ptr += 1 + sizeof(sljit_s32);
+ }
+
+ put_label->addr = (sljit_uw)code_ptr;
+ return code_ptr;
+ }
+
+ code_ptr -= put_label->flags + (2 + sizeof(sljit_uw));
+ SLJIT_MEMMOVE(code_ptr, code_ptr + (2 + sizeof(sljit_uw)), put_label->flags);
+
+ SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
+
+ if ((code_ptr[1] & 0xf8) == MOV_r_i32) {
+ code_ptr += 2 + sizeof(sljit_uw);
+ SLJIT_ASSERT((code_ptr[0] & 0xf8) == REX_W);
+ }
+
+ SLJIT_ASSERT(code_ptr[1] == MOV_rm_r);
+
+ code_ptr[0] = (sljit_u8)(code_ptr[0] & ~0x4);
+ code_ptr[1] = MOV_rm_i32;
+ code_ptr[2] = (sljit_u8)(code_ptr[2] & ~(0x7 << 3));
+
+ code_ptr = (sljit_u8*)(put_label->addr - (2 + sizeof(sljit_uw)) + sizeof(sljit_s32));
+ put_label->addr = (sljit_uw)code_ptr;
+ put_label->flags = 0;
+ return code_ptr;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compiler,
sljit_s32 options, sljit_s32 arg_types, sljit_s32 scratches, sljit_s32 saveds,
sljit_s32 fscratches, sljit_s32 fsaveds, sljit_s32 local_size)
diff --git a/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c b/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c
index 6f02ee3e8b..6296da5382 100644
--- a/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c
+++ b/thirdparty/pcre2/src/sljit/sljitNativeX86_common.c
@@ -428,13 +428,15 @@ static sljit_u8 get_jump_code(sljit_s32 type)
}
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type, sljit_sw executable_offset);
+static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_sw executable_offset);
#else
-static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_s32 type);
+static sljit_u8* generate_far_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr);
+static sljit_u8* generate_put_label_code(struct sljit_put_label *put_label, sljit_u8 *code_ptr, sljit_uw max_label);
#endif
-static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_s32 type, sljit_sw executable_offset)
+static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code_ptr, sljit_u8 *code, sljit_sw executable_offset)
{
+ sljit_s32 type = jump->flags >> TYPE_SHIFT;
sljit_s32 short_jump;
sljit_uw label_addr;
@@ -447,7 +449,7 @@ static sljit_u8* generate_near_jump_code(struct sljit_jump *jump, sljit_u8 *code
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
if ((sljit_sw)(label_addr - (jump->addr + 1)) > HALFWORD_MAX || (sljit_sw)(label_addr - (jump->addr + 1)) < HALFWORD_MIN)
- return generate_far_jump_code(jump, code_ptr, type);
+ return generate_far_jump_code(jump, code_ptr);
#endif
if (type == SLJIT_JUMP) {
@@ -497,6 +499,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
struct sljit_label *label;
struct sljit_jump *jump;
struct sljit_const *const_;
+ struct sljit_put_label *put_label;
CHECK_ERROR_PTR();
CHECK_PTR(check_sljit_generate_code(compiler));
@@ -511,6 +514,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
label = compiler->labels;
jump = compiler->jumps;
const_ = compiler->consts;
+ put_label = compiler->put_labels;
executable_offset = SLJIT_EXEC_OFFSET(code);
do {
@@ -525,27 +529,38 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
buf_ptr += len;
}
else {
- if (*buf_ptr >= 2) {
+ switch (*buf_ptr) {
+ case 0:
+ label->addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ label->size = code_ptr - code;
+ label = label->next;
+ break;
+ case 1:
jump->addr = (sljit_uw)code_ptr;
if (!(jump->flags & SLJIT_REWRITABLE_JUMP))
- code_ptr = generate_near_jump_code(jump, code_ptr, code, *buf_ptr - 2, executable_offset);
+ code_ptr = generate_near_jump_code(jump, code_ptr, code, executable_offset);
else {
#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
- code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2, executable_offset);
+ code_ptr = generate_far_jump_code(jump, code_ptr, executable_offset);
#else
- code_ptr = generate_far_jump_code(jump, code_ptr, *buf_ptr - 2);
+ code_ptr = generate_far_jump_code(jump, code_ptr);
#endif
}
jump = jump->next;
- }
- else if (*buf_ptr == 0) {
- label->addr = ((sljit_uw)code_ptr) + executable_offset;
- label->size = code_ptr - code;
- label = label->next;
- }
- else { /* *buf_ptr is 1 */
+ break;
+ case 2:
const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);
const_ = const_->next;
+ break;
+ default:
+ SLJIT_ASSERT(*buf_ptr == 3);
+ SLJIT_ASSERT(put_label->label);
+ put_label->addr = (sljit_uw)code_ptr;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ code_ptr = generate_put_label_code(put_label, code_ptr, (sljit_uw)(SLJIT_ADD_EXEC_OFFSET(code, executable_offset) + put_label->label->size));
+#endif
+ put_label = put_label->next;
+ break;
}
buf_ptr++;
}
@@ -557,6 +572,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(!label);
SLJIT_ASSERT(!jump);
SLJIT_ASSERT(!const_);
+ SLJIT_ASSERT(!put_label);
+ SLJIT_ASSERT(code_ptr <= code + compiler->size);
jump = compiler->jumps;
while (jump) {
@@ -591,8 +608,24 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
jump = jump->next;
}
- /* Some space may be wasted because of short jumps. */
- SLJIT_ASSERT(code_ptr <= code + compiler->size);
+ put_label = compiler->put_labels;
+ while (put_label) {
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr);
+#else
+ if (put_label->flags & PATCH_MD) {
+ SLJIT_ASSERT(put_label->label->addr > HALFWORD_MAX);
+ sljit_unaligned_store_sw((void*)(put_label->addr - sizeof(sljit_sw)), (sljit_sw)put_label->label->addr);
+ }
+ else {
+ SLJIT_ASSERT(put_label->label->addr <= HALFWORD_MAX);
+ sljit_unaligned_store_s32((void*)(put_label->addr - sizeof(sljit_s32)), (sljit_s32)put_label->label->addr);
+ }
+#endif
+
+ put_label = put_label->next;
+ }
+
compiler->error = SLJIT_ERR_COMPILED;
compiler->executable_offset = executable_offset;
compiler->executable_size = code_ptr - code;
@@ -2481,7 +2514,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
PTR_FAIL_IF_NULL(jump);
- set_jump(jump, compiler, type & SLJIT_REWRITABLE_JUMP);
+ set_jump(jump, compiler, (type & SLJIT_REWRITABLE_JUMP) | ((type & 0xff) << TYPE_SHIFT));
type &= 0xff;
/* Worst case size. */
@@ -2495,7 +2528,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
PTR_FAIL_IF_NULL(inst);
*inst++ = 0;
- *inst++ = type + 2;
+ *inst++ = 1;
return jump;
}
@@ -2513,7 +2546,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
if (src == SLJIT_IMM) {
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
FAIL_IF_NULL(jump);
- set_jump(jump, compiler, JUMP_ADDR);
+ set_jump(jump, compiler, JUMP_ADDR | (type << TYPE_SHIFT));
jump->u.target = srcw;
/* Worst case size. */
@@ -2527,7 +2560,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
FAIL_IF_NULL(inst);
*inst++ = 0;
- *inst++ = type + 2;
+ *inst++ = 1;
}
else {
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
@@ -2831,7 +2864,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
PTR_FAIL_IF(!inst);
*inst++ = 0;
- *inst++ = 1;
+ *inst++ = 2;
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
if (dst & SLJIT_MEM)
@@ -2842,6 +2875,54 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
return const_;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_put_label* sljit_emit_put_label(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+{
+ struct sljit_put_label *put_label;
+ sljit_u8 *inst;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ sljit_s32 reg;
+ sljit_uw start_size;
+#endif
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_put_label(compiler, dst, dstw));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+
+ put_label = (struct sljit_put_label*)ensure_abuf(compiler, sizeof(struct sljit_put_label));
+ PTR_FAIL_IF(!put_label);
+ set_put_label(put_label, compiler, 0);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+ reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
+
+ if (emit_load_imm64(compiler, reg, 0))
+ return NULL;
+#else
+ if (emit_mov(compiler, dst, dstw, SLJIT_IMM, 0))
+ return NULL;
+#endif
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (dst & SLJIT_MEM) {
+ start_size = compiler->size;
+ if (emit_mov(compiler, dst, dstw, TMP_REG1, 0))
+ return NULL;
+ put_label->flags = compiler->size - start_size;
+ }
+#endif
+
+ inst = (sljit_u8*)ensure_buf(compiler, 2);
+ PTR_FAIL_IF(!inst);
+
+ *inst++ = 0;
+ *inst++ = 3;
+
+ return put_label;
+}
+
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
SLJIT_UNUSED_ARG(executable_offset);
diff --git a/thirdparty/pcre2/src/sljit/sljitUtils.c b/thirdparty/pcre2/src/sljit/sljitUtils.c
index 5c2a838932..857492a174 100644
--- a/thirdparty/pcre2/src/sljit/sljitUtils.c
+++ b/thirdparty/pcre2/src/sljit/sljitUtils.c
@@ -154,7 +154,13 @@ SLJIT_API_FUNC_ATTRIBUTE void SLJIT_FUNC sljit_release_lock(void)
#include "windows.h"
#else
/* Provides mmap function. */
+#include <sys/types.h>
#include <sys/mman.h>
+#ifndef MAP_ANON
+#ifdef MAP_ANONYMOUS
+#define MAP_ANON MAP_ANONYMOUS
+#endif
+#endif
/* For detecting the page size. */
#include <unistd.h>
diff --git a/thirdparty/recastnavigation/Recast/Include/Recast.h b/thirdparty/recastnavigation/Recast/Include/Recast.h
index e85c0d2e29..4d557389b5 100644
--- a/thirdparty/recastnavigation/Recast/Include/Recast.h
+++ b/thirdparty/recastnavigation/Recast/Include/Recast.h
@@ -332,6 +332,8 @@ struct rcCompactSpan
/// @ingroup recast
struct rcCompactHeightfield
{
+ rcCompactHeightfield();
+ ~rcCompactHeightfield();
int width; ///< The width of the heightfield. (Along the x-axis in cell units.)
int height; ///< The height of the heightfield. (Along the z-axis in cell units.)
int spanCount; ///< The number of spans in the heightfield.
@@ -376,6 +378,8 @@ struct rcHeightfieldLayer
/// @see rcAllocHeightfieldLayerSet, rcFreeHeightfieldLayerSet
struct rcHeightfieldLayerSet
{
+ rcHeightfieldLayerSet();
+ ~rcHeightfieldLayerSet();
rcHeightfieldLayer* layers; ///< The layers in the set. [Size: #nlayers]
int nlayers; ///< The number of layers in the set.
};
@@ -395,6 +399,8 @@ struct rcContour
/// @ingroup recast
struct rcContourSet
{
+ rcContourSet();
+ ~rcContourSet();
rcContour* conts; ///< An array of the contours in the set. [Size: #nconts]
int nconts; ///< The number of contours in the set.
float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)]
@@ -411,6 +417,8 @@ struct rcContourSet
/// @ingroup recast
struct rcPolyMesh
{
+ rcPolyMesh();
+ ~rcPolyMesh();
unsigned short* verts; ///< The mesh vertices. [Form: (x, y, z) * #nverts]
unsigned short* polys; ///< Polygon and neighbor data. [Length: #maxpolys * 2 * #nvp]
unsigned short* regs; ///< The region id assigned to each polygon. [Length: #maxpolys]
diff --git a/thirdparty/recastnavigation/Recast/Include/RecastAlloc.h b/thirdparty/recastnavigation/Recast/Include/RecastAlloc.h
index 3cdd450d42..e436af9a01 100644
--- a/thirdparty/recastnavigation/Recast/Include/RecastAlloc.h
+++ b/thirdparty/recastnavigation/Recast/Include/RecastAlloc.h
@@ -20,6 +20,9 @@
#define RECASTALLOC_H
#include <stddef.h>
+#include <stdint.h>
+
+#include <RecastAssert.h>
/// Provides hint values to the memory allocator on how long the
/// memory is expected to be used.
@@ -58,64 +61,257 @@ void* rcAlloc(size_t size, rcAllocHint hint);
/// @see rcAlloc
void rcFree(void* ptr);
+/// An implementation of operator new usable for placement new. The default one is part of STL (which we don't use).
+/// rcNewTag is a dummy type used to differentiate our operator from the STL one, in case users import both Recast
+/// and STL.
+struct rcNewTag {};
+inline void* operator new(size_t, const rcNewTag&, void* p) { return p; }
+inline void operator delete(void*, const rcNewTag&, void*) {}
-/// A simple dynamic array of integers.
-class rcIntArray
-{
- int* m_data;
- int m_size, m_cap;
+/// Signed to avoid warnnings when comparing to int loop indexes, and common error with comparing to zero.
+/// MSVC2010 has a bug where ssize_t is unsigned (!!!).
+typedef intptr_t rcSizeType;
+#define RC_SIZE_MAX INTPTR_MAX
- void doResize(int n);
-
- // Explicitly disabled copy constructor and copy assignment operator.
- rcIntArray(const rcIntArray&);
- rcIntArray& operator=(const rcIntArray&);
+/// Macros to hint to the compiler about the likeliest branch. Please add a benchmark that demonstrates a performance
+/// improvement before introducing use cases.
+#if defined(__GNUC__) || defined(__clang__)
+#define rcLikely(x) __builtin_expect((x), true)
+#define rcUnlikely(x) __builtin_expect((x), false)
+#else
+#define rcLikely(x) (x)
+#define rcUnlikely(x) (x)
+#endif
-public:
- /// Constructs an instance with an initial array size of zero.
- rcIntArray() : m_data(0), m_size(0), m_cap(0) {}
+/// Variable-sized storage type. Mimics the interface of std::vector<T> with some notable differences:
+/// * Uses rcAlloc()/rcFree() to handle storage.
+/// * No support for a custom allocator.
+/// * Uses signed size instead of size_t to avoid warnings in for loops: "for (int i = 0; i < foo.size(); i++)"
+/// * Omits methods of limited utility: insert/erase, (bad performance), at (we don't use exceptions), operator=.
+/// * assign() and the pre-sizing constructor follow C++11 semantics -- they don't construct a temporary if no value is provided.
+/// * push_back() and resize() support adding values from the current vector. Range-based constructors and assign(begin, end) do not.
+/// * No specialization for bool.
+template <typename T, rcAllocHint H>
+class rcVectorBase {
+ rcSizeType m_size;
+ rcSizeType m_cap;
+ T* m_data;
+ // Constructs a T at the give address with either the copy constructor or the default.
+ static void construct(T* p, const T& v) { ::new(rcNewTag(), (void*)p) T(v); }
+ static void construct(T* p) { ::new(rcNewTag(), (void*)p) T; }
+ static void construct_range(T* begin, T* end);
+ static void construct_range(T* begin, T* end, const T& value);
+ static void copy_range(T* dst, const T* begin, const T* end);
+ void destroy_range(rcSizeType begin, rcSizeType end);
+ // Creates an array of the given size, copies all of this vector's data into it, and returns it.
+ T* allocate_and_copy(rcSizeType size);
+ void resize_impl(rcSizeType size, const T* value);
+ public:
+ typedef rcSizeType size_type;
+ typedef T value_type;
- /// Constructs an instance initialized to the specified size.
- /// @param[in] n The initial size of the integer array.
- rcIntArray(int n) : m_data(0), m_size(0), m_cap(0) { resize(n); }
- ~rcIntArray() { rcFree(m_data); }
+ rcVectorBase() : m_size(0), m_cap(0), m_data(0) {};
+ rcVectorBase(const rcVectorBase<T, H>& other) : m_size(0), m_cap(0), m_data(0) { assign(other.begin(), other.end()); }
+ explicit rcVectorBase(rcSizeType count) : m_size(0), m_cap(0), m_data(0) { resize(count); }
+ rcVectorBase(rcSizeType count, const T& value) : m_size(0), m_cap(0), m_data(0) { resize(count, value); }
+ rcVectorBase(const T* begin, const T* end) : m_size(0), m_cap(0), m_data(0) { assign(begin, end); }
+ ~rcVectorBase() { destroy_range(0, m_size); rcFree(m_data); }
- /// Specifies the new size of the integer array.
- /// @param[in] n The new size of the integer array.
- void resize(int n)
- {
- if (n > m_cap)
- doResize(n);
-
- m_size = n;
+ // Unlike in std::vector, we return a bool to indicate whether the alloc was successful.
+ bool reserve(rcSizeType size);
+
+ void assign(rcSizeType count, const T& value) { clear(); resize(count, value); }
+ void assign(const T* begin, const T* end);
+
+ void resize(rcSizeType size) { resize_impl(size, NULL); }
+ void resize(rcSizeType size, const T& value) { resize_impl(size, &value); }
+ // Not implemented as resize(0) because resize requires T to be default-constructible.
+ void clear() { destroy_range(0, m_size); m_size = 0; }
+
+ void push_back(const T& value);
+ void pop_back() { rcAssert(m_size > 0); back().~T(); m_size--; }
+
+ rcSizeType size() const { return m_size; }
+ rcSizeType capacity() const { return m_cap; }
+ bool empty() const { return size() == 0; }
+
+ const T& operator[](rcSizeType i) const { rcAssert(i >= 0 && i < m_size); return m_data[i]; }
+ T& operator[](rcSizeType i) { rcAssert(i >= 0 && i < m_size); return m_data[i]; }
+
+ const T& front() const { rcAssert(m_size); return m_data[0]; }
+ T& front() { rcAssert(m_size); return m_data[0]; }
+ const T& back() const { rcAssert(m_size); return m_data[m_size - 1]; };
+ T& back() { rcAssert(m_size); return m_data[m_size - 1]; };
+ const T* data() const { return m_data; }
+ T* data() { return m_data; }
+
+ T* begin() { return m_data; }
+ T* end() { return m_data + m_size; }
+ const T* begin() const { return m_data; }
+ const T* end() const { return m_data + m_size; }
+
+ void swap(rcVectorBase<T, H>& other);
+
+ // Explicitly deleted.
+ rcVectorBase& operator=(const rcVectorBase<T, H>& other);
+};
+
+template<typename T, rcAllocHint H>
+bool rcVectorBase<T, H>::reserve(rcSizeType count) {
+ if (count <= m_cap) {
+ return true;
+ }
+ T* new_data = allocate_and_copy(count);
+ if (!new_data) {
+ return false;
+ }
+ destroy_range(0, m_size);
+ rcFree(m_data);
+ m_data = new_data;
+ m_cap = count;
+ return true;
+}
+template <typename T, rcAllocHint H>
+T* rcVectorBase<T, H>::allocate_and_copy(rcSizeType size) {
+ rcAssert(RC_SIZE_MAX / static_cast<rcSizeType>(sizeof(T)) >= size);
+ T* new_data = static_cast<T*>(rcAlloc(sizeof(T) * size, H));
+ if (new_data) {
+ copy_range(new_data, m_data, m_data + m_size);
+ }
+ return new_data;
+}
+template <typename T, rcAllocHint H>
+void rcVectorBase<T, H>::assign(const T* begin, const T* end) {
+ clear();
+ reserve(end - begin);
+ m_size = end - begin;
+ copy_range(m_data, begin, end);
+}
+template <typename T, rcAllocHint H>
+void rcVectorBase<T, H>::push_back(const T& value) {
+ // rcLikely increases performance by ~50% on BM_rcVector_PushPreallocated,
+ // and by ~2-5% on BM_rcVector_Push.
+ if (rcLikely(m_size < m_cap)) {
+ construct(m_data + m_size++, value);
+ return;
}
- /// Push the specified integer onto the end of the array and increases the size by one.
- /// @param[in] item The new value.
- void push(int item) { resize(m_size+1); m_data[m_size-1] = item; }
+ rcAssert(RC_SIZE_MAX / 2 >= m_size);
+ rcSizeType new_cap = m_size ? 2*m_size : 1;
+ T* data = allocate_and_copy(new_cap);
+ // construct between allocate and destroy+free in case value is
+ // in this vector.
+ construct(data + m_size, value);
+ destroy_range(0, m_size);
+ m_size++;
+ m_cap = new_cap;
+ rcFree(m_data);
+ m_data = data;
+}
+template <typename T, rcAllocHint H>
+void rcVectorBase<T, H>::resize_impl(rcSizeType size, const T* value) {
+ if (size < m_size) {
+ destroy_range(size, m_size);
+ m_size = size;
+ } else if (size > m_size) {
+ T* new_data = allocate_and_copy(size);
+ // We defer deconstructing/freeing old data until after constructing
+ // new elements in case "value" is there.
+ if (value) {
+ construct_range(new_data + m_size, new_data + size, *value);
+ } else {
+ construct_range(new_data + m_size, new_data + size);
+ }
+ destroy_range(0, m_size);
+ rcFree(m_data);
+ m_data = new_data;
+ m_cap = size;
+ m_size = size;
+ }
+}
+template <typename T, rcAllocHint H>
+void rcVectorBase<T, H>::swap(rcVectorBase<T, H>& other) {
+ // TODO: Reorganize headers so we can use rcSwap here.
+ rcSizeType tmp_cap = other.m_cap;
+ rcSizeType tmp_size = other.m_size;
+ T* tmp_data = other.m_data;
- /// Returns the value at the end of the array and reduces the size by one.
- /// @return The value at the end of the array.
- int pop()
- {
- if (m_size > 0)
- m_size--;
-
- return m_data[m_size];
+ other.m_cap = m_cap;
+ other.m_size = m_size;
+ other.m_data = m_data;
+
+ m_cap = tmp_cap;
+ m_size = tmp_size;
+ m_data = tmp_data;
+}
+// static
+template <typename T, rcAllocHint H>
+void rcVectorBase<T, H>::construct_range(T* begin, T* end) {
+ for (T* p = begin; p < end; p++) {
+ construct(p);
+ }
+}
+// static
+template <typename T, rcAllocHint H>
+void rcVectorBase<T, H>::construct_range(T* begin, T* end, const T& value) {
+ for (T* p = begin; p < end; p++) {
+ construct(p, value);
+ }
+}
+// static
+template <typename T, rcAllocHint H>
+void rcVectorBase<T, H>::copy_range(T* dst, const T* begin, const T* end) {
+ for (rcSizeType i = 0 ; i < end - begin; i++) {
+ construct(dst + i, begin[i]);
}
+}
+template <typename T, rcAllocHint H>
+void rcVectorBase<T, H>::destroy_range(rcSizeType begin, rcSizeType end) {
+ for (rcSizeType i = begin; i < end; i++) {
+ m_data[i].~T();
+ }
+}
- /// The value at the specified array index.
- /// @warning Does not provide overflow protection.
- /// @param[in] i The index of the value.
- const int& operator[](int i) const { return m_data[i]; }
+template <typename T>
+class rcTempVector : public rcVectorBase<T, RC_ALLOC_TEMP> {
+ typedef rcVectorBase<T, RC_ALLOC_TEMP> Base;
+public:
+ rcTempVector() : Base() {}
+ explicit rcTempVector(rcSizeType size) : Base(size) {}
+ rcTempVector(rcSizeType size, const T& value) : Base(size, value) {}
+ rcTempVector(const rcTempVector<T>& other) : Base(other) {}
+ rcTempVector(const T* begin, const T* end) : Base(begin, end) {}
+};
+template <typename T>
+class rcPermVector : public rcVectorBase<T, RC_ALLOC_PERM> {
+ typedef rcVectorBase<T, RC_ALLOC_PERM> Base;
+public:
+ rcPermVector() : Base() {}
+ explicit rcPermVector(rcSizeType size) : Base(size) {}
+ rcPermVector(rcSizeType size, const T& value) : Base(size, value) {}
+ rcPermVector(const rcPermVector<T>& other) : Base(other) {}
+ rcPermVector(const T* begin, const T* end) : Base(begin, end) {}
+};
- /// The value at the specified array index.
- /// @warning Does not provide overflow protection.
- /// @param[in] i The index of the value.
- int& operator[](int i) { return m_data[i]; }
- /// The current size of the integer array.
- int size() const { return m_size; }
+/// Legacy class. Prefer rcVector<int>.
+class rcIntArray
+{
+ rcTempVector<int> m_impl;
+public:
+ rcIntArray() {}
+ rcIntArray(int n) : m_impl(n, 0) {}
+ void push(int item) { m_impl.push_back(item); }
+ void resize(int size) { m_impl.resize(size); }
+ int pop()
+ {
+ int v = m_impl.back();
+ m_impl.pop_back();
+ return v;
+ }
+ int size() const { return static_cast<int>(m_impl.size()); }
+ int& operator[](int index) { return m_impl[index]; }
+ int operator[](int index) const { return m_impl[index]; }
};
/// A simple helper class used to delete an array when it goes out of scope.
diff --git a/thirdparty/recastnavigation/Recast/Source/Recast.cpp b/thirdparty/recastnavigation/Recast/Source/Recast.cpp
index 8308d1973e..1b71710cdc 100644
--- a/thirdparty/recastnavigation/Recast/Source/Recast.cpp
+++ b/thirdparty/recastnavigation/Recast/Source/Recast.cpp
@@ -23,11 +23,34 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
-#include <new>
#include "Recast.h"
#include "RecastAlloc.h"
#include "RecastAssert.h"
+namespace
+{
+/// Allocates and constructs an object of the given type, returning a pointer.
+/// TODO: Support constructor args.
+/// @param[in] hint Hint to the allocator.
+template <typename T>
+T* rcNew(rcAllocHint hint) {
+ T* ptr = (T*)rcAlloc(sizeof(T), hint);
+ ::new(rcNewTag(), (void*)ptr) T();
+ return ptr;
+}
+
+/// Destroys and frees an object allocated with rcNew.
+/// @param[in] ptr The object pointer to delete.
+template <typename T>
+void rcDelete(T* ptr) {
+ if (ptr) {
+ ptr->~T();
+ rcFree((void*)ptr);
+ }
+}
+} // namespace
+
+
float rcSqrt(float x)
{
return sqrtf(x);
@@ -73,9 +96,8 @@ void rcContext::log(const rcLogCategory category, const char* format, ...)
rcHeightfield* rcAllocHeightfield()
{
- return new (rcAlloc(sizeof(rcHeightfield), RC_ALLOC_PERM)) rcHeightfield;
+ return rcNew<rcHeightfield>(RC_ALLOC_PERM);
}
-
rcHeightfield::rcHeightfield()
: width()
, height()
@@ -104,84 +126,133 @@ rcHeightfield::~rcHeightfield()
void rcFreeHeightField(rcHeightfield* hf)
{
- if (!hf) return;
- hf->~rcHeightfield();
- rcFree(hf);
+ rcDelete(hf);
}
rcCompactHeightfield* rcAllocCompactHeightfield()
{
- rcCompactHeightfield* chf = (rcCompactHeightfield*)rcAlloc(sizeof(rcCompactHeightfield), RC_ALLOC_PERM);
- memset(chf, 0, sizeof(rcCompactHeightfield));
- return chf;
+ return rcNew<rcCompactHeightfield>(RC_ALLOC_PERM);
}
void rcFreeCompactHeightfield(rcCompactHeightfield* chf)
{
- if (!chf) return;
- rcFree(chf->cells);
- rcFree(chf->spans);
- rcFree(chf->dist);
- rcFree(chf->areas);
- rcFree(chf);
+ rcDelete(chf);
}
-rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet()
+rcCompactHeightfield::rcCompactHeightfield()
+ : width(),
+ height(),
+ spanCount(),
+ walkableHeight(),
+ walkableClimb(),
+ borderSize(),
+ maxDistance(),
+ maxRegions(),
+ bmin(),
+ bmax(),
+ cs(),
+ ch(),
+ cells(),
+ spans(),
+ dist(),
+ areas()
{
- rcHeightfieldLayerSet* lset = (rcHeightfieldLayerSet*)rcAlloc(sizeof(rcHeightfieldLayerSet), RC_ALLOC_PERM);
- memset(lset, 0, sizeof(rcHeightfieldLayerSet));
- return lset;
+}
+rcCompactHeightfield::~rcCompactHeightfield()
+{
+ rcFree(cells);
+ rcFree(spans);
+ rcFree(dist);
+ rcFree(areas);
}
+rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet()
+{
+ return rcNew<rcHeightfieldLayerSet>(RC_ALLOC_PERM);
+}
void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset)
{
- if (!lset) return;
- for (int i = 0; i < lset->nlayers; ++i)
+ rcDelete(lset);
+}
+
+rcHeightfieldLayerSet::rcHeightfieldLayerSet()
+ : layers(), nlayers() {}
+rcHeightfieldLayerSet::~rcHeightfieldLayerSet()
+{
+ for (int i = 0; i < nlayers; ++i)
{
- rcFree(lset->layers[i].heights);
- rcFree(lset->layers[i].areas);
- rcFree(lset->layers[i].cons);
+ rcFree(layers[i].heights);
+ rcFree(layers[i].areas);
+ rcFree(layers[i].cons);
}
- rcFree(lset->layers);
- rcFree(lset);
+ rcFree(layers);
}
rcContourSet* rcAllocContourSet()
{
- rcContourSet* cset = (rcContourSet*)rcAlloc(sizeof(rcContourSet), RC_ALLOC_PERM);
- memset(cset, 0, sizeof(rcContourSet));
- return cset;
+ return rcNew<rcContourSet>(RC_ALLOC_PERM);
}
-
void rcFreeContourSet(rcContourSet* cset)
{
- if (!cset) return;
- for (int i = 0; i < cset->nconts; ++i)
+ rcDelete(cset);
+}
+
+rcContourSet::rcContourSet()
+ : conts(),
+ nconts(),
+ bmin(),
+ bmax(),
+ cs(),
+ ch(),
+ width(),
+ height(),
+ borderSize(),
+ maxError() {}
+rcContourSet::~rcContourSet()
+{
+ for (int i = 0; i < nconts; ++i)
{
- rcFree(cset->conts[i].verts);
- rcFree(cset->conts[i].rverts);
+ rcFree(conts[i].verts);
+ rcFree(conts[i].rverts);
}
- rcFree(cset->conts);
- rcFree(cset);
+ rcFree(conts);
}
+
rcPolyMesh* rcAllocPolyMesh()
{
- rcPolyMesh* pmesh = (rcPolyMesh*)rcAlloc(sizeof(rcPolyMesh), RC_ALLOC_PERM);
- memset(pmesh, 0, sizeof(rcPolyMesh));
- return pmesh;
+ return rcNew<rcPolyMesh>(RC_ALLOC_PERM);
}
-
void rcFreePolyMesh(rcPolyMesh* pmesh)
{
- if (!pmesh) return;
- rcFree(pmesh->verts);
- rcFree(pmesh->polys);
- rcFree(pmesh->regs);
- rcFree(pmesh->flags);
- rcFree(pmesh->areas);
- rcFree(pmesh);
+ rcDelete(pmesh);
+}
+
+rcPolyMesh::rcPolyMesh()
+ : verts(),
+ polys(),
+ regs(),
+ flags(),
+ areas(),
+ nverts(),
+ npolys(),
+ maxpolys(),
+ nvp(),
+ bmin(),
+ bmax(),
+ cs(),
+ ch(),
+ borderSize(),
+ maxEdgeError() {}
+
+rcPolyMesh::~rcPolyMesh()
+{
+ rcFree(verts);
+ rcFree(polys);
+ rcFree(regs);
+ rcFree(flags);
+ rcFree(areas);
}
rcPolyMeshDetail* rcAllocPolyMeshDetail()
diff --git a/thirdparty/recastnavigation/Recast/Source/RecastAlloc.cpp b/thirdparty/recastnavigation/Recast/Source/RecastAlloc.cpp
index 453b5fa6a6..bdc366116e 100644
--- a/thirdparty/recastnavigation/Recast/Source/RecastAlloc.cpp
+++ b/thirdparty/recastnavigation/Recast/Source/RecastAlloc.cpp
@@ -58,29 +58,3 @@ void rcFree(void* ptr)
if (ptr)
sRecastFreeFunc(ptr);
}
-
-/// @class rcIntArray
-///
-/// While it is possible to pre-allocate a specific array size during
-/// construction or by using the #resize method, certain methods will
-/// automatically resize the array as needed.
-///
-/// @warning The array memory is not initialized to zero when the size is
-/// manually set during construction or when using #resize.
-
-/// @par
-///
-/// Using this method ensures the array is at least large enough to hold
-/// the specified number of elements. This can improve performance by
-/// avoiding auto-resizing during use.
-void rcIntArray::doResize(int n)
-{
- if (!m_cap) m_cap = n;
- while (m_cap < n) m_cap *= 2;
- int* newData = (int*)rcAlloc(m_cap*sizeof(int), RC_ALLOC_TEMP);
- rcAssert(newData);
- if (m_size && newData) memcpy(newData, m_data, m_size*sizeof(int));
- rcFree(m_data);
- m_data = newData;
-}
-
diff --git a/thirdparty/recastnavigation/Recast/Source/RecastContour.cpp b/thirdparty/recastnavigation/Recast/Source/RecastContour.cpp
index 277ab01501..6574c11b6b 100644
--- a/thirdparty/recastnavigation/Recast/Source/RecastContour.cpp
+++ b/thirdparty/recastnavigation/Recast/Source/RecastContour.cpp
@@ -1009,7 +1009,7 @@ bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf,
if (cset.nconts > 0)
{
// Calculate winding of all polygons.
- rcScopedDelete<char> winding((char*)rcAlloc(sizeof(char)*cset.nconts, RC_ALLOC_TEMP));
+ rcScopedDelete<signed char> winding((signed char*)rcAlloc(sizeof(signed char)*cset.nconts, RC_ALLOC_TEMP));
if (!winding)
{
ctx->log(RC_LOG_ERROR, "rcBuildContours: Out of memory 'hole' (%d).", cset.nconts);
diff --git a/thirdparty/recastnavigation/Recast/Source/RecastMeshDetail.cpp b/thirdparty/recastnavigation/Recast/Source/RecastMeshDetail.cpp
index f953132f74..9a423cab8a 100644
--- a/thirdparty/recastnavigation/Recast/Source/RecastMeshDetail.cpp
+++ b/thirdparty/recastnavigation/Recast/Source/RecastMeshDetail.cpp
@@ -557,15 +557,16 @@ static float polyMinExtent(const float* verts, const int nverts)
inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; }
inline int next(int i, int n) { return i+1 < n ? i+1 : 0; }
-static void triangulateHull(const int /*nverts*/, const float* verts, const int nhull, const int* hull, rcIntArray& tris)
+static void triangulateHull(const int /*nverts*/, const float* verts, const int nhull, const int* hull, const int nin, rcIntArray& tris)
{
int start = 0, left = 1, right = nhull-1;
// Start from an ear with shortest perimeter.
// This tends to favor well formed triangles as starting point.
- float dmin = 0;
+ float dmin = FLT_MAX;
for (int i = 0; i < nhull; i++)
{
+ if (hull[i] >= nin) continue; // Ears are triangles with original vertices as middle vertex while others are actually line segments on edges
int pi = prev(i, nhull);
int ni = next(i, nhull);
const float* pv = &verts[hull[pi]*3];
@@ -770,7 +771,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
// If the polygon minimum extent is small (sliver or small triangle), do not try to add internal points.
if (minExtent < sampleDist*2)
{
- triangulateHull(nverts, verts, nhull, hull, tris);
+ triangulateHull(nverts, verts, nhull, hull, nin, tris);
return true;
}
@@ -778,7 +779,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
// We're using the triangulateHull instead of delaunayHull as it tends to
// create a bit better triangulation for long thin triangles when there
// are no internal points.
- triangulateHull(nverts, verts, nhull, hull, tris);
+ triangulateHull(nverts, verts, nhull, hull, nin, tris);
if (tris.size() == 0)
{
@@ -1140,7 +1141,8 @@ static void getHeightData(rcContext* ctx, const rcCompactHeightfield& chf,
static unsigned char getEdgeFlags(const float* va, const float* vb,
const float* vpoly, const int npoly)
{
- // Return true if edge (va,vb) is part of the polygon.
+ // The flag returned by this function matches dtDetailTriEdgeFlags in Detour.
+ // Figure out if edge (va,vb) is part of the polygon boundary.
static const float thrSqr = rcSqr(0.001f);
for (int i = 0, j = npoly-1; i < npoly; j=i++)
{
diff --git a/thirdparty/recastnavigation/Recast/Source/RecastRegion.cpp b/thirdparty/recastnavigation/Recast/Source/RecastRegion.cpp
index 38a2bd6bfa..e1fc0ee788 100644
--- a/thirdparty/recastnavigation/Recast/Source/RecastRegion.cpp
+++ b/thirdparty/recastnavigation/Recast/Source/RecastRegion.cpp
@@ -25,8 +25,17 @@
#include "Recast.h"
#include "RecastAlloc.h"
#include "RecastAssert.h"
-#include <new>
+namespace
+{
+struct LevelStackEntry
+{
+ LevelStackEntry(int x_, int y_, int index_) : x(x_), y(y_), index(index_) {}
+ int x;
+ int y;
+ int index;
+};
+} // namespace
static void calculateDistanceField(rcCompactHeightfield& chf, unsigned short* src, unsigned short& maxDist)
{
@@ -245,17 +254,15 @@ static bool floodRegion(int x, int y, int i,
unsigned short level, unsigned short r,
rcCompactHeightfield& chf,
unsigned short* srcReg, unsigned short* srcDist,
- rcIntArray& stack)
+ rcTempVector<LevelStackEntry>& stack)
{
const int w = chf.width;
const unsigned char area = chf.areas[i];
// Flood fill mark region.
- stack.resize(0);
- stack.push((int)x);
- stack.push((int)y);
- stack.push((int)i);
+ stack.clear();
+ stack.push_back(LevelStackEntry(x, y, i));
srcReg[i] = r;
srcDist[i] = 0;
@@ -264,9 +271,11 @@ static bool floodRegion(int x, int y, int i,
while (stack.size() > 0)
{
- int ci = stack.pop();
- int cy = stack.pop();
- int cx = stack.pop();
+ LevelStackEntry& back = stack.back();
+ int cx = back.x;
+ int cy = back.y;
+ int ci = back.index;
+ stack.pop_back();
const rcCompactSpan& cs = chf.spans[ci];
@@ -332,9 +341,7 @@ static bool floodRegion(int x, int y, int i,
{
srcReg[ai] = r;
srcDist[ai] = 0;
- stack.push(ax);
- stack.push(ay);
- stack.push(ai);
+ stack.push_back(LevelStackEntry(ax, ay, ai));
}
}
}
@@ -343,12 +350,20 @@ static bool floodRegion(int x, int y, int i,
return count > 0;
}
-static unsigned short* expandRegions(int maxIter, unsigned short level,
- rcCompactHeightfield& chf,
- unsigned short* srcReg, unsigned short* srcDist,
- unsigned short* dstReg, unsigned short* dstDist,
- rcIntArray& stack,
- bool fillStack)
+// Struct to keep track of entries in the region table that have been changed.
+struct DirtyEntry
+{
+ DirtyEntry(int index_, unsigned short region_, unsigned short distance2_)
+ : index(index_), region(region_), distance2(distance2_) {}
+ int index;
+ unsigned short region;
+ unsigned short distance2;
+};
+static void expandRegions(int maxIter, unsigned short level,
+ rcCompactHeightfield& chf,
+ unsigned short* srcReg, unsigned short* srcDist,
+ rcTempVector<LevelStackEntry>& stack,
+ bool fillStack)
{
const int w = chf.width;
const int h = chf.height;
@@ -356,7 +371,7 @@ static unsigned short* expandRegions(int maxIter, unsigned short level,
if (fillStack)
{
// Find cells revealed by the raised level.
- stack.resize(0);
+ stack.clear();
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
@@ -366,9 +381,7 @@ static unsigned short* expandRegions(int maxIter, unsigned short level,
{
if (chf.dist[i] >= level && srcReg[i] == 0 && chf.areas[i] != RC_NULL_AREA)
{
- stack.push(x);
- stack.push(y);
- stack.push(i);
+ stack.push_back(LevelStackEntry(x, y, i));
}
}
}
@@ -377,27 +390,26 @@ static unsigned short* expandRegions(int maxIter, unsigned short level,
else // use cells in the input stack
{
// mark all cells which already have a region
- for (int j=0; j<stack.size(); j+=3)
+ for (int j=0; j<stack.size(); j++)
{
- int i = stack[j+2];
+ int i = stack[j].index;
if (srcReg[i] != 0)
- stack[j+2] = -1;
+ stack[j].index = -1;
}
}
+ rcTempVector<DirtyEntry> dirtyEntries;
int iter = 0;
while (stack.size() > 0)
{
int failed = 0;
+ dirtyEntries.clear();
- memcpy(dstReg, srcReg, sizeof(unsigned short)*chf.spanCount);
- memcpy(dstDist, srcDist, sizeof(unsigned short)*chf.spanCount);
-
- for (int j = 0; j < stack.size(); j += 3)
+ for (int j = 0; j < stack.size(); j++)
{
- int x = stack[j+0];
- int y = stack[j+1];
- int i = stack[j+2];
+ int x = stack[j].x;
+ int y = stack[j].y;
+ int i = stack[j].index;
if (i < 0)
{
failed++;
@@ -426,9 +438,8 @@ static unsigned short* expandRegions(int maxIter, unsigned short level,
}
if (r)
{
- stack[j+2] = -1; // mark as used
- dstReg[i] = r;
- dstDist[i] = d2;
+ stack[j].index = -1; // mark as used
+ dirtyEntries.push_back(DirtyEntry(i, r, d2));
}
else
{
@@ -436,11 +447,14 @@ static unsigned short* expandRegions(int maxIter, unsigned short level,
}
}
- // rcSwap source and dest.
- rcSwap(srcReg, dstReg);
- rcSwap(srcDist, dstDist);
+ // Copy entries that differ between src and dst to keep them in sync.
+ for (int i = 0; i < dirtyEntries.size(); i++) {
+ int idx = dirtyEntries[i].index;
+ srcReg[idx] = dirtyEntries[i].region;
+ srcDist[idx] = dirtyEntries[i].distance2;
+ }
- if (failed*3 == stack.size())
+ if (failed == stack.size())
break;
if (level > 0)
@@ -450,16 +464,14 @@ static unsigned short* expandRegions(int maxIter, unsigned short level,
break;
}
}
-
- return srcReg;
}
static void sortCellsByLevel(unsigned short startLevel,
rcCompactHeightfield& chf,
- unsigned short* srcReg,
- unsigned int nbStacks, rcIntArray* stacks,
+ const unsigned short* srcReg,
+ unsigned int nbStacks, rcTempVector<LevelStackEntry>* stacks,
unsigned short loglevelsPerStack) // the levels per stack (2 in our case) as a bit shift
{
const int w = chf.width;
@@ -467,7 +479,7 @@ static void sortCellsByLevel(unsigned short startLevel,
startLevel = startLevel >> loglevelsPerStack;
for (unsigned int j=0; j<nbStacks; ++j)
- stacks[j].resize(0);
+ stacks[j].clear();
// put all cells in the level range into the appropriate stacks
for (int y = 0; y < h; ++y)
@@ -487,26 +499,23 @@ static void sortCellsByLevel(unsigned short startLevel,
if (sId < 0)
sId = 0;
- stacks[sId].push(x);
- stacks[sId].push(y);
- stacks[sId].push(i);
+ stacks[sId].push_back(LevelStackEntry(x, y, i));
}
}
}
}
-static void appendStacks(rcIntArray& srcStack, rcIntArray& dstStack,
- unsigned short* srcReg)
+static void appendStacks(const rcTempVector<LevelStackEntry>& srcStack,
+ rcTempVector<LevelStackEntry>& dstStack,
+ const unsigned short* srcReg)
{
- for (int j=0; j<srcStack.size(); j+=3)
+ for (int j=0; j<srcStack.size(); j++)
{
- int i = srcStack[j+2];
+ int i = srcStack[j].index;
if ((i < 0) || (srcReg[i] != 0))
continue;
- dstStack.push(srcStack[j]);
- dstStack.push(srcStack[j+1]);
- dstStack.push(srcStack[j+2]);
+ dstStack.push_back(srcStack[j]);
}
}
@@ -671,7 +680,7 @@ static bool isRegionConnectedToBorder(const rcRegion& reg)
return false;
}
-static bool isSolidEdge(rcCompactHeightfield& chf, unsigned short* srcReg,
+static bool isSolidEdge(rcCompactHeightfield& chf, const unsigned short* srcReg,
int x, int y, int i, int dir)
{
const rcCompactSpan& s = chf.spans[i];
@@ -690,7 +699,7 @@ static bool isSolidEdge(rcCompactHeightfield& chf, unsigned short* srcReg,
static void walkContour(int x, int y, int i, int dir,
rcCompactHeightfield& chf,
- unsigned short* srcReg,
+ const unsigned short* srcReg,
rcIntArray& cont)
{
int startDir = dir;
@@ -786,16 +795,15 @@ static bool mergeAndFilterRegions(rcContext* ctx, int minRegionArea, int mergeRe
const int h = chf.height;
const int nreg = maxRegionId+1;
- rcRegion* regions = (rcRegion*)rcAlloc(sizeof(rcRegion)*nreg, RC_ALLOC_TEMP);
- if (!regions)
- {
+ rcTempVector<rcRegion> regions;
+ if (!regions.reserve(nreg)) {
ctx->log(RC_LOG_ERROR, "mergeAndFilterRegions: Out of memory 'regions' (%d).", nreg);
return false;
}
// Construct regions
for (int i = 0; i < nreg; ++i)
- new(&regions[i]) rcRegion((unsigned short)i);
+ regions.push_back(rcRegion((unsigned short) i));
// Find edge of a region and find connections around the contour.
for (int y = 0; y < h; ++y)
@@ -1021,11 +1029,6 @@ static bool mergeAndFilterRegions(rcContext* ctx, int minRegionArea, int mergeRe
if (regions[i].overlap)
overlaps.push(regions[i].id);
- for (int i = 0; i < nreg; ++i)
- regions[i].~rcRegion();
- rcFree(regions);
-
-
return true;
}
@@ -1041,22 +1044,21 @@ static void addUniqueConnection(rcRegion& reg, int n)
static bool mergeAndFilterLayerRegions(rcContext* ctx, int minRegionArea,
unsigned short& maxRegionId,
rcCompactHeightfield& chf,
- unsigned short* srcReg, rcIntArray& /*overlaps*/)
+ unsigned short* srcReg)
{
const int w = chf.width;
const int h = chf.height;
const int nreg = maxRegionId+1;
- rcRegion* regions = (rcRegion*)rcAlloc(sizeof(rcRegion)*nreg, RC_ALLOC_TEMP);
- if (!regions)
- {
+ rcTempVector<rcRegion> regions;
+
+ // Construct regions
+ if (!regions.reserve(nreg)) {
ctx->log(RC_LOG_ERROR, "mergeAndFilterLayerRegions: Out of memory 'regions' (%d).", nreg);
return false;
}
-
- // Construct regions
for (int i = 0; i < nreg; ++i)
- new(&regions[i]) rcRegion((unsigned short)i);
+ regions.push_back(rcRegion((unsigned short) i));
// Find region neighbours and overlapping regions.
rcIntArray lregs(32);
@@ -1234,10 +1236,6 @@ static bool mergeAndFilterLayerRegions(rcContext* ctx, int minRegionArea,
srcReg[i] = regions[srcReg[i]].id;
}
- for (int i = 0; i < nreg; ++i)
- regions[i].~rcRegion();
- rcFree(regions);
-
return true;
}
@@ -1391,9 +1389,9 @@ bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf,
paintRectRegion(w-bw, w, 0, h, id|RC_BORDER_REG, chf, srcReg); id++;
paintRectRegion(0, w, 0, bh, id|RC_BORDER_REG, chf, srcReg); id++;
paintRectRegion(0, w, h-bh, h, id|RC_BORDER_REG, chf, srcReg); id++;
-
- chf.borderSize = borderSize;
}
+
+ chf.borderSize = borderSize;
rcIntArray prev(256);
@@ -1535,7 +1533,7 @@ bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
const int w = chf.width;
const int h = chf.height;
- rcScopedDelete<unsigned short> buf((unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount*4, RC_ALLOC_TEMP));
+ rcScopedDelete<unsigned short> buf((unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount*2, RC_ALLOC_TEMP));
if (!buf)
{
ctx->log(RC_LOG_ERROR, "rcBuildRegions: Out of memory 'tmp' (%d).", chf.spanCount*4);
@@ -1546,17 +1544,15 @@ bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
const int LOG_NB_STACKS = 3;
const int NB_STACKS = 1 << LOG_NB_STACKS;
- rcIntArray lvlStacks[NB_STACKS];
+ rcTempVector<LevelStackEntry> lvlStacks[NB_STACKS];
for (int i=0; i<NB_STACKS; ++i)
- lvlStacks[i].resize(1024);
+ lvlStacks[i].reserve(256);
- rcIntArray stack(1024);
- rcIntArray visited(1024);
+ rcTempVector<LevelStackEntry> stack;
+ stack.reserve(256);
unsigned short* srcReg = buf;
unsigned short* srcDist = buf+chf.spanCount;
- unsigned short* dstReg = buf+chf.spanCount*2;
- unsigned short* dstDist = buf+chf.spanCount*3;
memset(srcReg, 0, sizeof(unsigned short)*chf.spanCount);
memset(srcDist, 0, sizeof(unsigned short)*chf.spanCount);
@@ -1581,9 +1577,9 @@ bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
paintRectRegion(w-bw, w, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
paintRectRegion(0, w, 0, bh, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
paintRectRegion(0, w, h-bh, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
-
- chf.borderSize = borderSize;
}
+
+ chf.borderSize = borderSize;
int sId = -1;
while (level > 0)
@@ -1604,22 +1600,19 @@ bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
rcScopedTimer timerExpand(ctx, RC_TIMER_BUILD_REGIONS_EXPAND);
// Expand current regions until no empty connected cells found.
- if (expandRegions(expandIters, level, chf, srcReg, srcDist, dstReg, dstDist, lvlStacks[sId], false) != srcReg)
- {
- rcSwap(srcReg, dstReg);
- rcSwap(srcDist, dstDist);
- }
+ expandRegions(expandIters, level, chf, srcReg, srcDist, lvlStacks[sId], false);
}
{
rcScopedTimer timerFloor(ctx, RC_TIMER_BUILD_REGIONS_FLOOD);
// Mark new regions with IDs.
- for (int j = 0; j<lvlStacks[sId].size(); j += 3)
+ for (int j = 0; j<lvlStacks[sId].size(); j++)
{
- int x = lvlStacks[sId][j];
- int y = lvlStacks[sId][j+1];
- int i = lvlStacks[sId][j+2];
+ LevelStackEntry current = lvlStacks[sId][j];
+ int x = current.x;
+ int y = current.y;
+ int i = current.index;
if (i >= 0 && srcReg[i] == 0)
{
if (floodRegion(x, y, i, level, regionId, chf, srcReg, srcDist, stack))
@@ -1638,11 +1631,7 @@ bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
}
// Expand current regions until no empty connected cells found.
- if (expandRegions(expandIters*8, 0, chf, srcReg, srcDist, dstReg, dstDist, stack, true) != srcReg)
- {
- rcSwap(srcReg, dstReg);
- rcSwap(srcDist, dstDist);
- }
+ expandRegions(expandIters*8, 0, chf, srcReg, srcDist, stack, true);
ctx->stopTimer(RC_TIMER_BUILD_REGIONS_WATERSHED);
@@ -1709,9 +1698,9 @@ bool rcBuildLayerRegions(rcContext* ctx, rcCompactHeightfield& chf,
paintRectRegion(w-bw, w, 0, h, id|RC_BORDER_REG, chf, srcReg); id++;
paintRectRegion(0, w, 0, bh, id|RC_BORDER_REG, chf, srcReg); id++;
paintRectRegion(0, w, h-bh, h, id|RC_BORDER_REG, chf, srcReg); id++;
-
- chf.borderSize = borderSize;
}
+
+ chf.borderSize = borderSize;
rcIntArray prev(256);
@@ -1809,9 +1798,8 @@ bool rcBuildLayerRegions(rcContext* ctx, rcCompactHeightfield& chf,
rcScopedTimer timerFilter(ctx, RC_TIMER_BUILD_REGIONS_FILTER);
// Merge monotone regions to layers and remove small regions.
- rcIntArray overlaps;
chf.maxRegions = id;
- if (!mergeAndFilterLayerRegions(ctx, minRegionArea, chf.maxRegions, chf, srcReg, overlaps))
+ if (!mergeAndFilterLayerRegions(ctx, minRegionArea, chf.maxRegions, chf, srcReg))
return false;
}
diff --git a/thirdparty/tinyexr/tinyexr.h b/thirdparty/tinyexr/tinyexr.h
index bfc52b51a5..7e8956f7d3 100644
--- a/thirdparty/tinyexr/tinyexr.h
+++ b/thirdparty/tinyexr/tinyexr.h
@@ -105,6 +105,19 @@ extern "C" {
// http://computation.llnl.gov/projects/floating-point-compression
#endif
+#ifndef TINYEXR_USE_THREAD
+#define TINYEXR_USE_THREAD (0) // No threaded loading.
+// http://computation.llnl.gov/projects/floating-point-compression
+#endif
+
+#ifndef TINYEXR_USE_OPENMP
+#ifdef _OPENMP
+#define TINYEXR_USE_OPENMP (1)
+#else
+#define TINYEXR_USE_OPENMP (0)
+#endif
+#endif
+
#define TINYEXR_SUCCESS (0)
#define TINYEXR_ERROR_INVALID_MAGIC_NUMBER (-1)
#define TINYEXR_ERROR_INVALID_EXR_VERSION (-2)
@@ -118,6 +131,7 @@ extern "C" {
#define TINYEXR_ERROR_UNSUPPORTED_FEATURE (-10)
#define TINYEXR_ERROR_CANT_WRITE_FILE (-11)
#define TINYEXR_ERROR_SERIALZATION_FAILED (-12)
+#define TINYEXR_ERROR_LAYER_NOT_FOUND (-13)
// @note { OpenEXR file format: http://www.openexr.com/openexrfilelayout.pdf }
@@ -263,7 +277,7 @@ typedef struct _DeepImage {
int pad0;
} DeepImage;
-// @deprecated { to be removed. }
+// @deprecated { For backward compatibility. Not recommended to use. }
// Loads single-frame OpenEXR image. Assume EXR image contains A(single channel
// alpha) or RGB(A) channels.
// Application must free image data as returned by `out_rgba`
@@ -273,6 +287,27 @@ typedef struct _DeepImage {
extern int LoadEXR(float **out_rgba, int *width, int *height,
const char *filename, const char **err);
+// Loads single-frame OpenEXR image by specifing layer name. Assume EXR image contains A(single channel
+// alpha) or RGB(A) channels.
+// Application must free image data as returned by `out_rgba`
+// Result image format is: float x RGBA x width x hight
+// Returns negative value and may set error string in `err` when there's an
+// error
+// When the specified layer name is not found in the EXR file, the function will return `TINYEXR_ERROR_LAYER_NOT_FOUND`.
+extern int LoadEXRWithLayer(float **out_rgba, int *width, int *height,
+ const char *filename, const char *layer_name, const char **err);
+
+//
+// Get layer infos from EXR file.
+//
+// @param[out] layer_names List of layer names. Application must free memory after using this.
+// @param[out] num_layers The number of layers
+// @param[out] err Error string(wll be filled when the function returns error code). Free it using FreeEXRErrorMessage after using this value.
+//
+// @return TINYEXR_SUCCEES upon success.
+//
+extern int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, const char **err);
+
// @deprecated { to be removed. }
// Simple wrapper API for ParseEXRHeaderFromFile.
// checking given file is a EXR file(by just look up header)
@@ -472,7 +507,7 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
#include <cstring>
#include <sstream>
-//#include <iostream> // debug
+// #include <iostream> // debug
#include <limits>
#include <string>
@@ -481,9 +516,15 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
#if __cplusplus > 199711L
// C++11
#include <cstdint>
+
+#if TINYEXR_USE_THREAD
+#include <atomic>
+#include <thread>
+#endif
+
#endif // __cplusplus > 199711L
-#ifdef _OPENMP
+#if TINYEXR_USE_OPENMP
#include <omp.h>
#endif
@@ -6917,6 +6958,10 @@ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename,
}
#endif
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
#endif // MINIZ_HEADER_FILE_ONLY
/*
@@ -6952,9 +6997,6 @@ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename,
#pragma clang diagnostic pop
#endif
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
} // namespace miniz
#else
@@ -9954,9 +9996,9 @@ static bool DecodePixelData(/* out */ unsigned char **out_images,
return false;
}
- if (!tinyexr::DecompressRle(reinterpret_cast<unsigned char *>(&outBuf.at(0)),
- dstLen, data_ptr,
- static_cast<unsigned long>(data_len))) {
+ if (!tinyexr::DecompressRle(
+ reinterpret_cast<unsigned char *>(&outBuf.at(0)), dstLen, data_ptr,
+ static_cast<unsigned long>(data_len))) {
return false;
}
@@ -10272,7 +10314,7 @@ static bool DecodePixelData(/* out */ unsigned char **out_images,
return true;
}
-static void DecodeTiledPixelData(
+static bool DecodeTiledPixelData(
unsigned char **out_images, int *width, int *height,
const int *requested_pixel_types, const unsigned char *data_ptr,
size_t data_len, int compression_type, int line_order, int data_width,
@@ -10298,11 +10340,11 @@ static void DecodeTiledPixelData(
}
// Image size = tile size.
- DecodePixelData(out_images, requested_pixel_types, data_ptr, data_len,
- compression_type, line_order, (*width), tile_size_y,
- /* stride */ tile_size_x, /* y */ 0, /* line_no */ 0,
- (*height), pixel_data_size, num_attributes, attributes,
- num_channels, channels, channel_offset_list);
+ return DecodePixelData(out_images, requested_pixel_types, data_ptr, data_len,
+ compression_type, line_order, (*width), tile_size_y,
+ /* stride */ tile_size_x, /* y */ 0, /* line_no */ 0,
+ (*height), pixel_data_size, num_attributes, attributes,
+ num_channels, channels, channel_offset_list);
}
static bool ComputeChannelLayout(std::vector<size_t> *channel_offset_list,
@@ -10851,85 +10893,141 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
exr_image->tiles = static_cast<EXRTile *>(
calloc(sizeof(EXRTile), static_cast<size_t>(num_tiles)));
+ int err_code = TINYEXR_SUCCESS;
+
+#if (__cplusplus > 199711L) && (TINYEXR_USE_THREAD > 0)
+
+ std::vector<std::thread> workers;
+ std::atomic<size_t> tile_count(0);
+
+ int num_threads = std::max(1, int(std::thread::hardware_concurrency()));
+ if (num_threads > int(num_tiles)) {
+ num_threads = int(num_tiles);
+ }
+
+ for (int t = 0; t < num_threads; t++) {
+ workers.emplace_back(std::thread([&]() {
+ size_t tile_idx = 0;
+ while ((tile_idx = tile_count++) < num_tiles) {
+
+#else
for (size_t tile_idx = 0; tile_idx < num_tiles; tile_idx++) {
- // Allocate memory for each tile.
- exr_image->tiles[tile_idx].images = tinyexr::AllocateImage(
- num_channels, exr_header->channels, exr_header->requested_pixel_types,
- exr_header->tile_size_x, exr_header->tile_size_y);
-
- // 16 byte: tile coordinates
- // 4 byte : data size
- // ~ : data(uncompressed or compressed)
- if (offsets[tile_idx] + sizeof(int) * 5 > size) {
- if (err) {
- (*err) += "Insufficient data size.\n";
- }
- return TINYEXR_ERROR_INVALID_DATA;
- }
+#endif
+ // Allocate memory for each tile.
+ exr_image->tiles[tile_idx].images = tinyexr::AllocateImage(
+ num_channels, exr_header->channels,
+ exr_header->requested_pixel_types, exr_header->tile_size_x,
+ exr_header->tile_size_y);
+
+ // 16 byte: tile coordinates
+ // 4 byte : data size
+ // ~ : data(uncompressed or compressed)
+ if (offsets[tile_idx] + sizeof(int) * 5 > size) {
+ // TODO(LTE): atomic
+ if (err) {
+ (*err) += "Insufficient data size.\n";
+ }
+ err_code = TINYEXR_ERROR_INVALID_DATA;
+ break;
+ }
- size_t data_size = size_t(size - (offsets[tile_idx] + sizeof(int) * 5));
- const unsigned char *data_ptr =
- reinterpret_cast<const unsigned char *>(head + offsets[tile_idx]);
+ size_t data_size =
+ size_t(size - (offsets[tile_idx] + sizeof(int) * 5));
+ const unsigned char *data_ptr =
+ reinterpret_cast<const unsigned char *>(head + offsets[tile_idx]);
+
+ int tile_coordinates[4];
+ memcpy(tile_coordinates, data_ptr, sizeof(int) * 4);
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&tile_coordinates[0]));
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&tile_coordinates[1]));
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&tile_coordinates[2]));
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&tile_coordinates[3]));
+
+ // @todo{ LoD }
+ if (tile_coordinates[2] != 0) {
+ err_code = TINYEXR_ERROR_UNSUPPORTED_FEATURE;
+ break;
+ }
+ if (tile_coordinates[3] != 0) {
+ err_code = TINYEXR_ERROR_UNSUPPORTED_FEATURE;
+ break;
+ }
- int tile_coordinates[4];
- memcpy(tile_coordinates, data_ptr, sizeof(int) * 4);
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&tile_coordinates[0]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&tile_coordinates[1]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&tile_coordinates[2]));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&tile_coordinates[3]));
+ int data_len;
+ memcpy(&data_len, data_ptr + 16,
+ sizeof(int)); // 16 = sizeof(tile_coordinates)
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
- // @todo{ LoD }
- if (tile_coordinates[2] != 0) {
- return TINYEXR_ERROR_UNSUPPORTED_FEATURE;
- }
- if (tile_coordinates[3] != 0) {
- return TINYEXR_ERROR_UNSUPPORTED_FEATURE;
- }
+ if (data_len < 4 || size_t(data_len) > data_size) {
+ // TODO(LTE): atomic
+ if (err) {
+ (*err) += "Insufficient data length.\n";
+ }
+ err_code = TINYEXR_ERROR_INVALID_DATA;
+ break;
+ }
- int data_len;
- memcpy(&data_len, data_ptr + 16,
- sizeof(int)); // 16 = sizeof(tile_coordinates)
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+ // Move to data addr: 20 = 16 + 4;
+ data_ptr += 20;
+
+ bool ret = tinyexr::DecodeTiledPixelData(
+ exr_image->tiles[tile_idx].images,
+ &(exr_image->tiles[tile_idx].width),
+ &(exr_image->tiles[tile_idx].height),
+ exr_header->requested_pixel_types, data_ptr,
+ static_cast<size_t>(data_len), exr_header->compression_type,
+ exr_header->line_order, data_width, data_height,
+ tile_coordinates[0], tile_coordinates[1], exr_header->tile_size_x,
+ exr_header->tile_size_y, static_cast<size_t>(pixel_data_size),
+ static_cast<size_t>(exr_header->num_custom_attributes),
+ exr_header->custom_attributes,
+ static_cast<size_t>(exr_header->num_channels),
+ exr_header->channels, channel_offset_list);
+
+ if (!ret) {
+ // TODO(LTE): atomic
+ if (err) {
+ (*err) += "Failed to decode tile data.\n";
+ }
+ err_code = TINYEXR_ERROR_INVALID_DATA;
+ }
- if (data_len < 4 || size_t(data_len) > data_size) {
- if (err) {
- (*err) += "Insufficient data length.\n";
+ exr_image->tiles[tile_idx].offset_x = tile_coordinates[0];
+ exr_image->tiles[tile_idx].offset_y = tile_coordinates[1];
+ exr_image->tiles[tile_idx].level_x = tile_coordinates[2];
+ exr_image->tiles[tile_idx].level_y = tile_coordinates[3];
+
+#if (__cplusplus > 199711L) && (TINYEXR_USE_THREAD > 0)
}
- return TINYEXR_ERROR_INVALID_DATA;
- }
+ }));
+ } // num_thread loop
- // Move to data addr: 20 = 16 + 4;
- data_ptr += 20;
-
- tinyexr::DecodeTiledPixelData(
- exr_image->tiles[tile_idx].images,
- &(exr_image->tiles[tile_idx].width),
- &(exr_image->tiles[tile_idx].height),
- exr_header->requested_pixel_types, data_ptr,
- static_cast<size_t>(data_len), exr_header->compression_type,
- exr_header->line_order, data_width, data_height, tile_coordinates[0],
- tile_coordinates[1], exr_header->tile_size_x, exr_header->tile_size_y,
- static_cast<size_t>(pixel_data_size),
- static_cast<size_t>(exr_header->num_custom_attributes),
- exr_header->custom_attributes,
- static_cast<size_t>(exr_header->num_channels), exr_header->channels,
- channel_offset_list);
-
- exr_image->tiles[tile_idx].offset_x = tile_coordinates[0];
- exr_image->tiles[tile_idx].offset_y = tile_coordinates[1];
- exr_image->tiles[tile_idx].level_x = tile_coordinates[2];
- exr_image->tiles[tile_idx].level_y = tile_coordinates[3];
-
- exr_image->num_tiles = static_cast<int>(num_tiles);
+ for (auto &t : workers) {
+ t.join();
}
+
+#else
+ }
+#endif
+
+ if (err_code != TINYEXR_SUCCESS) {
+ return err_code;
+ }
+
+ exr_image->num_tiles = static_cast<int>(num_tiles);
} else { // scanline format
// Don't allow too large image(256GB * pixel_data_size or more). Workaround
// for #104.
size_t total_data_len =
size_t(data_width) * size_t(data_height) * size_t(num_channels);
- const bool total_data_len_overflown = sizeof(void*) == 8 ? (total_data_len >= 0x4000000000) : false;
- if ((total_data_len == 0) || total_data_len_overflown ) {
+ const bool total_data_len_overflown =
+ sizeof(void *) == 8 ? (total_data_len >= 0x4000000000) : false;
+ if ((total_data_len == 0) || total_data_len_overflown) {
if (err) {
std::stringstream ss;
ss << "Image data size is zero or too large: width = " << data_width
@@ -10944,85 +11042,118 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
num_channels, exr_header->channels, exr_header->requested_pixel_types,
data_width, data_height);
-#ifdef _OPENMP
+#if (__cplusplus > 199711L) && (TINYEXR_USE_THREAD > 0)
+ std::vector<std::thread> workers;
+ std::atomic<int> y_count(0);
+
+ int num_threads = std::max(1, int(std::thread::hardware_concurrency()));
+ if (num_threads > int(num_blocks)) {
+ num_threads = int(num_blocks);
+ }
+
+ for (int t = 0; t < num_threads; t++) {
+ workers.emplace_back(std::thread([&]() {
+ int y = 0;
+ while ((y = y_count++) < int(num_blocks)) {
+
+#else
+
+#if TINYEXR_USE_OPENMP
#pragma omp parallel for
#endif
for (int y = 0; y < static_cast<int>(num_blocks); y++) {
- size_t y_idx = static_cast<size_t>(y);
-
- if (offsets[y_idx] + sizeof(int) * 2 > size) {
- invalid_data = true;
- } else {
- // 4 byte: scan line
- // 4 byte: data size
- // ~ : pixel data(uncompressed or compressed)
- size_t data_size = size_t(size - (offsets[y_idx] + sizeof(int) * 2));
- const unsigned char *data_ptr =
- reinterpret_cast<const unsigned char *>(head + offsets[y_idx]);
-
- int line_no;
- memcpy(&line_no, data_ptr, sizeof(int));
- int data_len;
- memcpy(&data_len, data_ptr + 4, sizeof(int));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&line_no));
- tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
-
- if (size_t(data_len) > data_size) {
- invalid_data = true;
-
- } else if ((line_no > (2 << 20)) || (line_no < -(2 << 20))) {
- // Too large value. Assume this is invalid
- // 2**20 = 1048576 = heuristic value.
- invalid_data = true;
- } else if (data_len == 0) {
- // TODO(syoyo): May be ok to raise the threshold for example `data_len
- // < 4`
- invalid_data = true;
- } else {
- // line_no may be negative.
- int end_line_no = (std::min)(line_no + num_scanline_blocks,
- (exr_header->data_window[3] + 1));
- int num_lines = end_line_no - line_no;
+#endif
+ size_t y_idx = static_cast<size_t>(y);
- if (num_lines <= 0) {
+ if (offsets[y_idx] + sizeof(int) * 2 > size) {
invalid_data = true;
} else {
- // Move to data addr: 8 = 4 + 4;
- data_ptr += 8;
-
- // Adjust line_no with data_window.bmin.y
-
- // overflow check
- tinyexr_int64 lno = static_cast<tinyexr_int64>(line_no) - static_cast<tinyexr_int64>(exr_header->data_window[1]);
- if (lno > std::numeric_limits<int>::max()) {
- line_no = -1; // invalid
- } else if (lno < -std::numeric_limits<int>::max()) {
- line_no = -1; // invalid
- } else {
- line_no -= exr_header->data_window[1];
- }
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(uncompressed or compressed)
+ size_t data_size =
+ size_t(size - (offsets[y_idx] + sizeof(int) * 2));
+ const unsigned char *data_ptr =
+ reinterpret_cast<const unsigned char *>(head + offsets[y_idx]);
+
+ int line_no;
+ memcpy(&line_no, data_ptr, sizeof(int));
+ int data_len;
+ memcpy(&data_len, data_ptr + 4, sizeof(int));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&line_no));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+
+ if (size_t(data_len) > data_size) {
+ invalid_data = true;
- if (line_no < 0) {
+ } else if ((line_no > (2 << 20)) || (line_no < -(2 << 20))) {
+ // Too large value. Assume this is invalid
+ // 2**20 = 1048576 = heuristic value.
+ invalid_data = true;
+ } else if (data_len == 0) {
+ // TODO(syoyo): May be ok to raise the threshold for example
+ // `data_len < 4`
invalid_data = true;
} else {
- if (!tinyexr::DecodePixelData(
- exr_image->images, exr_header->requested_pixel_types,
- data_ptr, static_cast<size_t>(data_len),
- exr_header->compression_type, exr_header->line_order,
- data_width, data_height, data_width, y, line_no,
- num_lines, static_cast<size_t>(pixel_data_size),
- static_cast<size_t>(exr_header->num_custom_attributes),
- exr_header->custom_attributes,
- static_cast<size_t>(exr_header->num_channels),
- exr_header->channels, channel_offset_list)) {
+ // line_no may be negative.
+ int end_line_no = (std::min)(line_no + num_scanline_blocks,
+ (exr_header->data_window[3] + 1));
+
+ int num_lines = end_line_no - line_no;
+
+ if (num_lines <= 0) {
invalid_data = true;
+ } else {
+ // Move to data addr: 8 = 4 + 4;
+ data_ptr += 8;
+
+ // Adjust line_no with data_window.bmin.y
+
+ // overflow check
+ tinyexr_int64 lno =
+ static_cast<tinyexr_int64>(line_no) -
+ static_cast<tinyexr_int64>(exr_header->data_window[1]);
+ if (lno > std::numeric_limits<int>::max()) {
+ line_no = -1; // invalid
+ } else if (lno < -std::numeric_limits<int>::max()) {
+ line_no = -1; // invalid
+ } else {
+ line_no -= exr_header->data_window[1];
+ }
+
+ if (line_no < 0) {
+ invalid_data = true;
+ } else {
+ if (!tinyexr::DecodePixelData(
+ exr_image->images, exr_header->requested_pixel_types,
+ data_ptr, static_cast<size_t>(data_len),
+ exr_header->compression_type, exr_header->line_order,
+ data_width, data_height, data_width, y, line_no,
+ num_lines, static_cast<size_t>(pixel_data_size),
+ static_cast<size_t>(
+ exr_header->num_custom_attributes),
+ exr_header->custom_attributes,
+ static_cast<size_t>(exr_header->num_channels),
+ exr_header->channels, channel_offset_list)) {
+ invalid_data = true;
+ }
+ }
}
}
}
+
+#if (__cplusplus > 199711L) && (TINYEXR_USE_THREAD > 0)
}
- }
+ }));
+ }
+
+ for (auto &t : workers) {
+ t.join();
+ }
+#else
} // omp parallel
+#endif
}
if (invalid_data) {
@@ -11219,6 +11350,9 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header,
tinyexr::SetErrorMessage(e, err);
}
+#if 1
+ FreeEXRImage(exr_image);
+#else
// release memory(if exists)
if ((exr_header->num_channels > 0) && exr_image && exr_image->images) {
for (size_t c = 0; c < size_t(exr_header->num_channels); c++) {
@@ -11230,16 +11364,114 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header,
free(exr_image->images);
exr_image->images = NULL;
}
+#endif
}
return ret;
}
}
+static void GetLayers(const EXRHeader& exr_header, std::vector<std::string>& layer_names) {
+ // Naive implementation
+ // Group channels by layers
+ // go over all channel names, split by periods
+ // collect unique names
+ layer_names.clear();
+ for (int c = 0; c < exr_header.num_channels; c++) {
+ std::string full_name(exr_header.channels[c].name);
+ const size_t pos = full_name.find_last_of('.');
+ if (pos != std::string::npos && pos != 0 && pos + 1 < full_name.size()) {
+ full_name.erase(pos);
+ if (std::find(layer_names.begin(), layer_names.end(), full_name) == layer_names.end())
+ layer_names.push_back(full_name);
+ }
+ }
+}
+
+struct LayerChannel {
+ explicit LayerChannel (size_t i, std::string n)
+ : index(i)
+ , name(n)
+ {}
+ size_t index;
+ std::string name;
+};
+
+static void ChannelsInLayer(const EXRHeader& exr_header, const std::string layer_name, std::vector<LayerChannel>& channels) {
+ channels.clear();
+ for (int c = 0; c < exr_header.num_channels; c++) {
+ std::string ch_name(exr_header.channels[c].name);
+ if (layer_name.empty()) {
+ const size_t pos = ch_name.find_last_of('.');
+ if (pos != std::string::npos && pos < ch_name.size()) {
+ ch_name = ch_name.substr(pos + 1);
+ }
+ } else {
+ const size_t pos = ch_name.find(layer_name + '.');
+ if (pos == std::string::npos)
+ continue;
+ if (pos == 0) {
+ ch_name = ch_name.substr(layer_name.size() + 1);
+ }
+ }
+ LayerChannel ch(size_t(c), ch_name);
+ channels.push_back(ch);
+ }
+}
+
} // namespace tinyexr
+int EXRLayers(const char *filename, const char **layer_names[], int *num_layers, const char **err) {
+ EXRVersion exr_version;
+ EXRHeader exr_header;
+ InitEXRHeader(&exr_header);
+
+ {
+ int ret = ParseEXRVersionFromFile(&exr_version, filename);
+ if (ret != TINYEXR_SUCCESS) {
+ tinyexr::SetErrorMessage("Invalid EXR header.", err);
+ return ret;
+ }
+
+ if (exr_version.multipart || exr_version.non_image) {
+ tinyexr::SetErrorMessage(
+ "Loading multipart or DeepImage is not supported in LoadEXR() API",
+ err);
+ return TINYEXR_ERROR_INVALID_DATA; // @fixme.
+ }
+ }
+
+ int ret = ParseEXRHeaderFromFile(&exr_header, &exr_version, filename, err);
+ if (ret != TINYEXR_SUCCESS) {
+ FreeEXRHeader(&exr_header);
+ return ret;
+ }
+
+ std::vector<std::string> layer_vec;
+ tinyexr::GetLayers(exr_header, layer_vec);
+
+ (*num_layers) = int(layer_vec.size());
+ (*layer_names) = static_cast<const char **>(
+ malloc(sizeof(const char *) * static_cast<size_t>(layer_vec.size())));
+ for (size_t c = 0; c < static_cast<size_t>(layer_vec.size()); c++) {
+#ifdef _MSC_VER
+ (*layer_names)[c] = _strdup(layer_vec[c].c_str());
+#else
+ (*layer_names)[c] = strdup(layer_vec[c].c_str());
+#endif
+ }
+
+ FreeEXRHeader(&exr_header);
+ return TINYEXR_SUCCESS;
+}
+
int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
const char **err) {
+ return LoadEXRWithLayer(out_rgba, width, height, filename, /* layername */NULL, err);
+}
+
+int LoadEXRWithLayer(float **out_rgba, int *width, int *height, const char *filename, const char *layername,
+ const char **err) {
if (out_rgba == NULL) {
tinyexr::SetErrorMessage("Invalid argument for LoadEXR()", err);
return TINYEXR_ERROR_INVALID_ARGUMENT;
@@ -11254,7 +11486,9 @@ int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
{
int ret = ParseEXRVersionFromFile(&exr_version, filename);
if (ret != TINYEXR_SUCCESS) {
- tinyexr::SetErrorMessage("Invalid EXR header.", err);
+ std::stringstream ss;
+ ss << "Failed to open EXR file or read version info from EXR file. code(" << ret << ")";
+ tinyexr::SetErrorMessage(ss.str(), err);
return ret;
}
@@ -11281,6 +11515,7 @@ int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
}
}
+ // TODO: Probably limit loading to layers (channels) selected by layer index
{
int ret = LoadEXRImageFromFile(&exr_image, &exr_header, filename, err);
if (ret != TINYEXR_SUCCESS) {
@@ -11294,19 +11529,40 @@ int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
int idxG = -1;
int idxB = -1;
int idxA = -1;
- for (int c = 0; c < exr_header.num_channels; c++) {
- if (strcmp(exr_header.channels[c].name, "R") == 0) {
- idxR = c;
- } else if (strcmp(exr_header.channels[c].name, "G") == 0) {
- idxG = c;
- } else if (strcmp(exr_header.channels[c].name, "B") == 0) {
- idxB = c;
- } else if (strcmp(exr_header.channels[c].name, "A") == 0) {
- idxA = c;
+
+ std::vector<std::string> layer_names;
+ tinyexr::GetLayers(exr_header, layer_names);
+
+ std::vector<tinyexr::LayerChannel> channels;
+ tinyexr::ChannelsInLayer(exr_header, layername == NULL ? "" : std::string(layername), channels);
+
+ if (channels.size() < 1) {
+ tinyexr::SetErrorMessage("Layer Not Found", err);
+ FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
+ return TINYEXR_ERROR_LAYER_NOT_FOUND;
+ }
+
+ size_t ch_count = channels.size() < 4 ? channels.size() : 4;
+ for (size_t c = 0; c < ch_count; c++) {
+ const tinyexr::LayerChannel &ch = channels[c];
+
+ if (ch.name == "R") {
+ idxR = int(ch.index);
+ }
+ else if (ch.name == "G") {
+ idxG = int(ch.index);
+ }
+ else if (ch.name == "B") {
+ idxB = int(ch.index);
+ }
+ else if (ch.name == "A") {
+ idxA = int(ch.index);
}
}
- if (exr_header.num_channels == 1) {
+ if (channels.size() == 1) {
+ int chIdx = int(channels.front().index);
// Grayscale channel only.
(*out_rgba) = reinterpret_cast<float *>(
@@ -11333,19 +11589,19 @@ int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
const int srcIdx = i + j * exr_header.tile_size_x;
unsigned char **src = exr_image.tiles[it].images;
(*out_rgba)[4 * idx + 0] =
- reinterpret_cast<float **>(src)[0][srcIdx];
+ reinterpret_cast<float **>(src)[chIdx][srcIdx];
(*out_rgba)[4 * idx + 1] =
- reinterpret_cast<float **>(src)[0][srcIdx];
+ reinterpret_cast<float **>(src)[chIdx][srcIdx];
(*out_rgba)[4 * idx + 2] =
- reinterpret_cast<float **>(src)[0][srcIdx];
+ reinterpret_cast<float **>(src)[chIdx][srcIdx];
(*out_rgba)[4 * idx + 3] =
- reinterpret_cast<float **>(src)[0][srcIdx];
+ reinterpret_cast<float **>(src)[chIdx][srcIdx];
}
}
}
} else {
for (int i = 0; i < exr_image.width * exr_image.height; i++) {
- const float val = reinterpret_cast<float **>(exr_image.images)[0][i];
+ const float val = reinterpret_cast<float **>(exr_image.images)[chIdx][i];
(*out_rgba)[4 * i + 0] = val;
(*out_rgba)[4 * i + 1] = val;
(*out_rgba)[4 * i + 2] = val;
@@ -11358,22 +11614,22 @@ int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
if (idxR == -1) {
tinyexr::SetErrorMessage("R channel not found", err);
- // @todo { free exr_image }
FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
return TINYEXR_ERROR_INVALID_DATA;
}
if (idxG == -1) {
tinyexr::SetErrorMessage("G channel not found", err);
- // @todo { free exr_image }
FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
return TINYEXR_ERROR_INVALID_DATA;
}
if (idxB == -1) {
tinyexr::SetErrorMessage("B channel not found", err);
- // @todo { free exr_image }
FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
return TINYEXR_ERROR_INVALID_DATA;
}
@@ -11446,7 +11702,7 @@ int IsEXR(const char *filename) {
int ret = ParseEXRVersionFromFile(&exr_version, filename);
if (ret != TINYEXR_SUCCESS) {
- return TINYEXR_ERROR_INVALID_HEADER;
+ return ret;
}
return TINYEXR_SUCCESS;
@@ -11509,7 +11765,9 @@ int LoadEXRFromMemory(float **out_rgba, int *width, int *height,
int ret = ParseEXRVersionFromMemory(&exr_version, memory, size);
if (ret != TINYEXR_SUCCESS) {
- tinyexr::SetErrorMessage("Failed to parse EXR version", err);
+ std::stringstream ss;
+ ss << "Failed to parse EXR version. code(" << ret << ")";
+ tinyexr::SetErrorMessage(ss.str(), err);
return ret;
}
@@ -11967,9 +12225,11 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image,
}
#endif
+ // TOOD(LTE): C++11 thread
+
// Use signed int since some OpenMP compiler doesn't allow unsigned type for
// `parallel for`
-#ifdef _OPENMP
+#if TINYEXR_USE_OPENMP
#pragma omp parallel for
#endif
for (int i = 0; i < num_blocks; i++) {
diff --git a/thirdparty/vhacd/0005-fix-scale-calculation.patch b/thirdparty/vhacd/0005-fix-scale-calculation.patch
new file mode 100644
index 0000000000..4b05f64fbf
--- /dev/null
+++ b/thirdparty/vhacd/0005-fix-scale-calculation.patch
@@ -0,0 +1,20 @@
+diff --git a/thirdparty/vhacd/inc/vhacdVolume.h b/thirdparty/vhacd/inc/vhacdVolume.h
+index 8c47fa1e2c..c445f20122 100644
+--- a/thirdparty/vhacd/inc/vhacdVolume.h
++++ b/thirdparty/vhacd/inc/vhacdVolume.h
+@@ -316,13 +316,13 @@ void Volume::Voxelize(const T* const points, const uint32_t stridePoints, const
+
+ double d[3] = { m_maxBB[0] - m_minBB[0], m_maxBB[1] - m_minBB[1], m_maxBB[2] - m_minBB[2] };
+ double r;
+- if (d[0] > d[1] && d[0] > d[2]) {
++ if (d[0] >= d[1] && d[0] >= d[2]) {
+ r = d[0];
+ m_dim[0] = dim;
+ m_dim[1] = 2 + static_cast<size_t>(dim * d[1] / d[0]);
+ m_dim[2] = 2 + static_cast<size_t>(dim * d[2] / d[0]);
+ }
+- else if (d[1] > d[0] && d[1] > d[2]) {
++ else if (d[1] >= d[0] && d[1] >= d[2]) {
+ r = d[1];
+ m_dim[1] = dim;
+ m_dim[0] = 2 + static_cast<size_t>(dim * d[0] / d[1]);
diff --git a/thirdparty/vhacd/inc/vhacdVolume.h b/thirdparty/vhacd/inc/vhacdVolume.h
index 8c47fa1e2c..c445f20122 100644
--- a/thirdparty/vhacd/inc/vhacdVolume.h
+++ b/thirdparty/vhacd/inc/vhacdVolume.h
@@ -316,13 +316,13 @@ void Volume::Voxelize(const T* const points, const uint32_t stridePoints, const
double d[3] = { m_maxBB[0] - m_minBB[0], m_maxBB[1] - m_minBB[1], m_maxBB[2] - m_minBB[2] };
double r;
- if (d[0] > d[1] && d[0] > d[2]) {
+ if (d[0] >= d[1] && d[0] >= d[2]) {
r = d[0];
m_dim[0] = dim;
m_dim[1] = 2 + static_cast<size_t>(dim * d[1] / d[0]);
m_dim[2] = 2 + static_cast<size_t>(dim * d[2] / d[0]);
}
- else if (d[1] > d[0] && d[1] > d[2]) {
+ else if (d[1] >= d[0] && d[1] >= d[2]) {
r = d[1];
m_dim[1] = dim;
m_dim[0] = 2 + static_cast<size_t>(dim * d[0] / d[1]);
diff --git a/thirdparty/xatlas/LICENSE b/thirdparty/xatlas/LICENSE
index 9e61e15fb7..7af8b33238 100644
--- a/thirdparty/xatlas/LICENSE
+++ b/thirdparty/xatlas/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2018-2019 Jonathan Young
+Copyright (c) 2018-2020 Jonathan Young
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/thirdparty/xatlas/xatlas.cpp b/thirdparty/xatlas/xatlas.cpp
index 80cacf9746..43aec33a9f 100644
--- a/thirdparty/xatlas/xatlas.cpp
+++ b/thirdparty/xatlas/xatlas.cpp
@@ -1,7 +1,7 @@
/*
MIT License
-Copyright (c) 2018-2019 Jonathan Young
+Copyright (c) 2018-2020 Jonathan Young
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -90,8 +90,8 @@ Copyright (c) 2012 Brandon Pelfrey
#endif
#define XA_ALLOC(tag, type) (type *)internal::Realloc(nullptr, sizeof(type), tag, __FILE__, __LINE__)
-#define XA_ALLOC_ARRAY(tag, type, num) (type *)internal::Realloc(nullptr, sizeof(type) * num, tag, __FILE__, __LINE__)
-#define XA_REALLOC(tag, ptr, type, num) (type *)internal::Realloc(ptr, sizeof(type) * num, tag, __FILE__, __LINE__)
+#define XA_ALLOC_ARRAY(tag, type, num) (type *)internal::Realloc(nullptr, sizeof(type) * (num), tag, __FILE__, __LINE__)
+#define XA_REALLOC(tag, ptr, type, num) (type *)internal::Realloc(ptr, sizeof(type) * (num), tag, __FILE__, __LINE__)
#define XA_REALLOC_SIZE(tag, ptr, size) (uint8_t *)internal::Realloc(ptr, size, tag, __FILE__, __LINE__)
#define XA_FREE(ptr) internal::Realloc(ptr, 0, internal::MemTag::Default, __FILE__, __LINE__)
#define XA_NEW(tag, type) new (XA_ALLOC(tag, type)) type()
@@ -122,11 +122,12 @@ Copyright (c) 2012 Brandon Pelfrey
#define XA_DEBUG_HEAP 0
#define XA_DEBUG_SINGLE_CHART 0
+#define XA_DEBUG_ALL_CHARTS_INVALID 0
#define XA_DEBUG_EXPORT_ATLAS_IMAGES 0
#define XA_DEBUG_EXPORT_ATLAS_IMAGES_PER_CHART 0 // Export an atlas image after each chart is added.
#define XA_DEBUG_EXPORT_BOUNDARY_GRID 0
#define XA_DEBUG_EXPORT_TGA (XA_DEBUG_EXPORT_ATLAS_IMAGES || XA_DEBUG_EXPORT_BOUNDARY_GRID)
-#define XA_DEBUG_EXPORT_OBJ_SOURCE_MESHES 0
+#define XA_DEBUG_EXPORT_OBJ_FACE_GROUPS 0
#define XA_DEBUG_EXPORT_OBJ_CHART_GROUPS 0
#define XA_DEBUG_EXPORT_OBJ_PLANAR_REGIONS 0
#define XA_DEBUG_EXPORT_OBJ_CHARTS 0
@@ -137,7 +138,7 @@ Copyright (c) 2012 Brandon Pelfrey
#define XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS 0
#define XA_DEBUG_EXPORT_OBJ (0 \
- || XA_DEBUG_EXPORT_OBJ_SOURCE_MESHES \
+ || XA_DEBUG_EXPORT_OBJ_FACE_GROUPS \
|| XA_DEBUG_EXPORT_OBJ_CHART_GROUPS \
|| XA_DEBUG_EXPORT_OBJ_PLANAR_REGIONS \
|| XA_DEBUG_EXPORT_OBJ_CHARTS \
@@ -163,6 +164,83 @@ static FreeFunc s_free = free;
static PrintFunc s_print = printf;
static bool s_printVerbose = false;
+#if XA_PROFILE
+#define XA_PROFILE_START(var) const clock_t var##Start = clock();
+#define XA_PROFILE_END(var) internal::s_profile.var += clock() - var##Start;
+#define XA_PROFILE_PRINT_AND_RESET(label, var) XA_PRINT("%s%.2f seconds (%g ms)\n", label, internal::clockToSeconds(internal::s_profile.var), internal::clockToMs(internal::s_profile.var)); internal::s_profile.var = 0;
+#define XA_PROFILE_ALLOC 0
+
+struct ProfileData
+{
+#if XA_PROFILE_ALLOC
+ std::atomic<clock_t> alloc;
+#endif
+ clock_t addMeshReal;
+ clock_t addMeshCopyData;
+ std::atomic<clock_t> addMeshThread;
+ std::atomic<clock_t> addMeshCreateColocals;
+ clock_t computeChartsReal;
+ std::atomic<clock_t> computeChartsThread;
+ std::atomic<clock_t> createFaceGroups;
+ std::atomic<clock_t> extractInvalidMeshGeometry;
+ std::atomic<clock_t> chartGroupComputeChartsReal;
+ std::atomic<clock_t> chartGroupComputeChartsThread;
+ std::atomic<clock_t> createChartGroupMesh;
+ std::atomic<clock_t> createChartGroupMeshColocals;
+ std::atomic<clock_t> createChartGroupMeshBoundaries;
+ std::atomic<clock_t> buildAtlas;
+ std::atomic<clock_t> buildAtlasInit;
+ std::atomic<clock_t> planarCharts;
+ std::atomic<clock_t> clusteredCharts;
+ std::atomic<clock_t> clusteredChartsPlaceSeeds;
+ std::atomic<clock_t> clusteredChartsPlaceSeedsBoundaryIntersection;
+ std::atomic<clock_t> clusteredChartsRelocateSeeds;
+ std::atomic<clock_t> clusteredChartsReset;
+ std::atomic<clock_t> clusteredChartsGrow;
+ std::atomic<clock_t> clusteredChartsGrowBoundaryIntersection;
+ std::atomic<clock_t> clusteredChartsMerge;
+ std::atomic<clock_t> clusteredChartsFillHoles;
+ std::atomic<clock_t> copyChartFaces;
+ clock_t parameterizeChartsReal;
+ std::atomic<clock_t> parameterizeChartsThread;
+ std::atomic<clock_t> createChartMesh;
+ std::atomic<clock_t> fixChartMeshTJunctions;
+ std::atomic<clock_t> closeChartMeshHoles;
+ std::atomic<clock_t> parameterizeChartsOrthogonal;
+ std::atomic<clock_t> parameterizeChartsLSCM;
+ std::atomic<clock_t> parameterizeChartsRecompute;
+ std::atomic<clock_t> parameterizeChartsPiecewise;
+ std::atomic<clock_t> parameterizeChartsPiecewiseBoundaryIntersection;
+ std::atomic<clock_t> parameterizeChartsEvaluateQuality;
+ clock_t packCharts;
+ clock_t packChartsAddCharts;
+ std::atomic<clock_t> packChartsAddChartsThread;
+ std::atomic<clock_t> packChartsAddChartsRestoreTexcoords;
+ clock_t packChartsRasterize;
+ clock_t packChartsDilate;
+ clock_t packChartsFindLocation;
+ clock_t packChartsBlit;
+ clock_t buildOutputMeshes;
+};
+
+static ProfileData s_profile;
+
+static double clockToMs(clock_t c)
+{
+ return c * 1000.0 / CLOCKS_PER_SEC;
+}
+
+static double clockToSeconds(clock_t c)
+{
+ return c / (double)CLOCKS_PER_SEC;
+}
+#else
+#define XA_PROFILE_START(var)
+#define XA_PROFILE_END(var)
+#define XA_PROFILE_PRINT_AND_RESET(label, var)
+#define XA_PROFILE_ALLOC 0
+#endif
+
struct MemTag
{
enum
@@ -170,7 +248,6 @@ struct MemTag
Default,
BitImage,
BVH,
- FullVector,
Matrix,
Mesh,
MeshBoundaries,
@@ -180,6 +257,7 @@ struct MemTag
MeshNormals,
MeshPositions,
MeshTexcoords,
+ OpenNL,
SegmentAtlasChartCandidates,
SegmentAtlasChartFaces,
SegmentAtlasMeshData,
@@ -305,7 +383,6 @@ static void PrintMemoryUsage()
"Default",
"BitImage",
"BVH",
- "FullVector",
"Matrix",
"Mesh",
"MeshBoundaries",
@@ -315,6 +392,7 @@ static void PrintMemoryUsage()
"MeshNormals",
"MeshPositions",
"MeshTexcoords",
+ "OpenNL",
"SegmentAtlasChartCandidates",
"SegmentAtlasChartFaces",
"SegmentAtlasMeshData",
@@ -335,79 +413,21 @@ static void *Realloc(void *ptr, size_t size, int /*tag*/, const char * /*file*/,
s_free(ptr);
return nullptr;
}
+#if XA_PROFILE_ALLOC
+ XA_PROFILE_START(alloc)
+#endif
void *mem = s_realloc(ptr, size);
- if (size > 0) {
- XA_DEBUG_ASSERT(mem);
- }
+#if XA_PROFILE_ALLOC
+ XA_PROFILE_END(alloc)
+#endif
+ XA_DEBUG_ASSERT(size <= 0 || (size > 0 && mem));
return mem;
}
#define XA_PRINT_MEM_USAGE
#endif
-#if XA_PROFILE
-#define XA_PROFILE_START(var) const clock_t var##Start = clock();
-#define XA_PROFILE_END(var) internal::s_profile.var += clock() - var##Start;
-#define XA_PROFILE_PRINT_AND_RESET(label, var) XA_PRINT("%s%.2f seconds (%g ms)\n", label, internal::clockToSeconds(internal::s_profile.var), internal::clockToMs(internal::s_profile.var)); internal::s_profile.var = 0;
-
-struct ProfileData
-{
- clock_t addMeshReal;
- clock_t addMeshCopyData;
- std::atomic<clock_t> addMeshThread;
- std::atomic<clock_t> addMeshCreateColocals;
- std::atomic<clock_t> addMeshCreateFaceGroups;
- std::atomic<clock_t> addMeshCreateChartGroupsReal;
- std::atomic<clock_t> addMeshCreateChartGroupsThread;
- clock_t computeChartsReal;
- std::atomic<clock_t> computeChartsThread;
- std::atomic<clock_t> buildAtlas;
- std::atomic<clock_t> buildAtlasInit;
- std::atomic<clock_t> buildAtlasPlaceSeeds;
- std::atomic<clock_t> buildAtlasRelocateSeeds;
- std::atomic<clock_t> buildAtlasResetCharts;
- std::atomic<clock_t> buildAtlasGrowCharts;
- std::atomic<clock_t> buildAtlasMergeCharts;
- std::atomic<clock_t> buildAtlasFillHoles;
- std::atomic<clock_t> createChartMeshesReal;
- std::atomic<clock_t> createChartMeshesThread;
- std::atomic<clock_t> fixChartMeshTJunctions;
- std::atomic<clock_t> closeChartMeshHoles;
- clock_t parameterizeChartsReal;
- std::atomic<clock_t> parameterizeChartsThread;
- std::atomic<clock_t> parameterizeChartsOrthogonal;
- std::atomic<clock_t> parameterizeChartsLSCM;
- std::atomic<clock_t> parameterizeChartsEvaluateQuality;
- clock_t packCharts;
- clock_t packChartsAddCharts;
- std::atomic<clock_t> packChartsAddChartsThread;
- std::atomic<clock_t> packChartsAddChartsRestoreTexcoords;
- clock_t packChartsRasterize;
- clock_t packChartsDilate;
- clock_t packChartsFindLocation;
- clock_t packChartsBlit;
- clock_t buildOutputMeshes;
-};
-
-static ProfileData s_profile;
-
-static double clockToMs(clock_t c)
-{
- return c * 1000.0 / CLOCKS_PER_SEC;
-}
-
-static double clockToSeconds(clock_t c)
-{
- return c / (double)CLOCKS_PER_SEC;
-}
-#else
-#define XA_PROFILE_START(var)
-#define XA_PROFILE_END(var)
-#define XA_PROFILE_PRINT_AND_RESET(label, var)
-#endif
-
static constexpr float kPi = 3.14159265358979323846f;
static constexpr float kPi2 = 6.28318530717958647692f;
-static constexpr float kPi4 = 12.56637061435917295384f;
static constexpr float kEpsilon = 0.0001f;
static constexpr float kAreaEpsilon = FLT_EPSILON;
static constexpr float kNormalEpsilon = 0.001f;
@@ -517,33 +537,6 @@ static uint32_t nextPowerOfTwo(uint32_t x)
return x + 1;
}
-static uint32_t sdbmHash(const void *data_in, uint32_t size, uint32_t h = 5381)
-{
- const uint8_t *data = (const uint8_t *) data_in;
- uint32_t i = 0;
- while (i < size) {
- h = (h << 16) + (h << 6) - h + (uint32_t ) data[i++];
- }
- return h;
-}
-
-template <typename T>
-static uint32_t hash(const T &t, uint32_t h = 5381)
-{
- return sdbmHash(&t, sizeof(T), h);
-}
-
-// Functors for hash table:
-template <typename Key> struct Hash
-{
- uint32_t operator()(const Key &k) const { return hash(k); }
-};
-
-template <typename Key> struct Equal
-{
- bool operator()(const Key &k0, const Key &k1) const { return k0 == k1; }
-};
-
class Vector2
{
public:
@@ -860,6 +853,14 @@ struct Extents2
{
Vector2 min, max;
+ Extents2() {}
+
+ Extents2(Vector2 p1, Vector2 p2)
+ {
+ min = xatlas::internal::min(p1, p2);
+ max = xatlas::internal::max(p1, p2);
+ }
+
void reset()
{
min.x = min.y = FLT_MAX;
@@ -877,7 +878,7 @@ struct Extents2
return Vector2(min.x + (max.x - min.x) * 0.5f, min.y + (max.y - min.y) * 0.5f);
}
- static bool intersect(Extents2 e1, Extents2 e2)
+ static bool intersect(const Extents2 &e1, const Extents2 &e2)
{
return e1.min.x <= e2.max.x && e1.max.x >= e2.min.x && e1.min.y <= e2.max.y && e1.max.y >= e2.min.y;
}
@@ -1123,6 +1124,15 @@ struct ArrayBase
size--;
}
+ // Element at index is swapped with the last element, then the array length is decremented.
+ void removeAtFast(uint32_t index)
+ {
+ XA_DEBUG_ASSERT(index >= 0 && index < size);
+ if (size != 1 && index != size - 1)
+ memcpy(buffer + elementSize * index, buffer + elementSize * (size - 1), elementSize);
+ size--;
+ }
+
void reserve(uint32_t desiredSize)
{
if (desiredSize > capacity)
@@ -1164,9 +1174,9 @@ struct ArrayBase
}
#if XA_DEBUG_HEAP
- void setMemTag(int memTag)
+ void setMemTag(int _memTag)
{
- this->memTag = memTag;
+ this->memTag = _memTag;
}
#endif
@@ -1221,6 +1231,7 @@ public:
void copyTo(Array &other) const { m_base.copyTo(other.m_base); }
XA_INLINE const T *data() const { return (const T *)m_base.buffer; }
XA_INLINE T *data() { return (T *)m_base.buffer; }
+ void destroy() { m_base.destroy(); }
XA_INLINE T *end() { return (T *)m_base.buffer + m_base.size; }
XA_INLINE bool isEmpty() const { return m_base.size == 0; }
void insertAt(uint32_t index, const T &value) { m_base.insertAt(index, (const uint8_t *)&value); }
@@ -1229,6 +1240,7 @@ public:
void push_back(const Array &other) { m_base.push_back(other.m_base); }
void pop_back() { m_base.pop_back(); }
void removeAt(uint32_t index) { m_base.removeAt(index); }
+ void removeAtFast(uint32_t index) { m_base.removeAtFast(index); }
void reserve(uint32_t desiredSize) { m_base.reserve(desiredSize); }
void resize(uint32_t newSize) { m_base.resize(newSize, true); }
@@ -1244,13 +1256,18 @@ public:
((T *)m_base.buffer)[i].~T();
}
- void setAll(const T &value)
+ void fill(const T &value)
{
auto buffer = (T *)m_base.buffer;
for (uint32_t i = 0; i < m_base.size; i++)
buffer[i] = value;
}
+ void fillBytes(uint8_t value)
+ {
+ memset(m_base.buffer, (int)value, m_base.size * m_base.elementSize);
+ }
+
#if XA_DEBUG_HEAP
void setMemTag(int memTag) { m_base.setMemTag(memTag); }
#endif
@@ -1265,6 +1282,7 @@ private:
template<typename T>
struct ArrayView
{
+ ArrayView() : data(nullptr), length(0) {}
ArrayView(Array<T> &a) : data(a.data()), length(a.size()) {}
ArrayView(T *data, uint32_t length) : data(data), length(length) {}
ArrayView &operator=(Array<T> &a) { data = a.data(); length = a.size(); return *this; }
@@ -1276,6 +1294,7 @@ struct ArrayView
template<typename T>
struct ConstArrayView
{
+ ConstArrayView() : data(nullptr), length(0) {}
ConstArrayView(const Array<T> &a) : data(a.data()), length(a.size()) {}
ConstArrayView(const T *data, uint32_t length) : data(data), length(length) {}
ConstArrayView &operator=(const Array<T> &a) { data = a.data(); length = a.size(); return *this; }
@@ -1340,7 +1359,13 @@ public:
void set(uint32_t index)
{
XA_DEBUG_ASSERT(index < m_size);
- m_wordArray[index >> 5] |= (1 << (index & 31));
+ m_wordArray[index >> 5] |= (1 << (index & 31));
+ }
+
+ void unset(uint32_t index)
+ {
+ XA_DEBUG_ASSERT(index < m_size);
+ m_wordArray[index >> 5] &= ~(1 << (index & 31));
}
void zeroOutMemory()
@@ -1927,26 +1952,38 @@ private:
}
};
-/// Fixed size vector class.
-class FullVector
+static uint32_t sdbmHash(const void *data_in, uint32_t size, uint32_t h = 5381)
{
-public:
- FullVector(uint32_t dim) : m_array(MemTag::FullVector) { m_array.resize(dim); }
- FullVector(const FullVector &v) : m_array(MemTag::FullVector) { v.m_array.copyTo(m_array); }
- FullVector &operator=(const FullVector &v) = delete;
- XA_INLINE uint32_t dimension() const { return m_array.size(); }
- XA_INLINE const float &operator[](uint32_t index) const { return m_array[index]; }
- XA_INLINE float &operator[](uint32_t index) { return m_array[index]; }
-
- void fill(float f)
- {
- const uint32_t dim = dimension();
- for (uint32_t i = 0; i < dim; i++)
- m_array[i] = f;
+ const uint8_t *data = (const uint8_t *) data_in;
+ uint32_t i = 0;
+ while (i < size) {
+ h = (h << 16) + (h << 6) - h + (uint32_t ) data[i++];
}
+ return h;
+}
-private:
- Array<float> m_array;
+template <typename T>
+static uint32_t hash(const T &t, uint32_t h = 5381)
+{
+ return sdbmHash(&t, sizeof(T), h);
+}
+
+template <typename Key>
+struct Hash
+{
+ uint32_t operator()(const Key &k) const { return hash(k); }
+};
+
+template <typename Key>
+struct PassthroughHash
+{
+ uint32_t operator()(const Key &k) const { return (uint32_t)k; }
+};
+
+template <typename Key>
+struct Equal
+{
+ bool operator()(const Key &k0, const Key &k1) const { return k0 == k1; }
};
template<typename Key, typename H = Hash<Key>, typename E = Equal<Key> >
@@ -1963,7 +2000,17 @@ public:
XA_FREE(m_slots);
}
- void add(const Key &key)
+ void destroy()
+ {
+ if (m_slots) {
+ XA_FREE(m_slots);
+ m_slots = nullptr;
+ }
+ m_keys.destroy();
+ m_next.destroy();
+ }
+
+ uint32_t add(const Key &key)
{
if (!m_slots)
alloc();
@@ -1971,6 +2018,7 @@ public:
m_keys.push_back(key);
m_next.push_back(m_slots[hash]);
m_slots[hash] = m_next.size() - 1;
+ return m_keys.size() - 1;
}
uint32_t get(const Key &key) const
@@ -2066,7 +2114,7 @@ public:
y ^= (y << 5);
uint64_t t = 698769069ULL * z + c;
c = (t >> 32);
- return (x + y + (z = (uint32_t)t)) % range;
+ return (x + y + (z = (uint32_t)t)) % (range + 1);
}
private:
@@ -2079,45 +2127,38 @@ private:
class RadixSort
{
public:
- RadixSort() : m_size(0), m_ranks(nullptr), m_ranks2(nullptr), m_validRanks(false) {}
-
- ~RadixSort()
+ void sort(const float *input, uint32_t count)
{
- // Release everything
- XA_FREE(m_ranks2);
- XA_FREE(m_ranks);
- }
-
- RadixSort &sort(const float *input, uint32_t count)
- {
- if (input == nullptr || count == 0) return *this;
- // Resize lists if needed
- if (count != m_size) {
- if (count > m_size) {
- m_ranks2 = XA_REALLOC(MemTag::Default, m_ranks2, uint32_t, count);
- m_ranks = XA_REALLOC(MemTag::Default, m_ranks, uint32_t, count);
- }
- m_size = count;
- m_validRanks = false;
+ if (input == nullptr || count == 0) {
+ m_buffer1.clear();
+ m_buffer2.clear();
+ m_ranks = m_buffer1.data();
+ m_ranks2 = m_buffer2.data();
+ return;
}
- if (count < 32) {
+ // Resize lists if needed
+ m_buffer1.resize(count);
+ m_buffer2.resize(count);
+ m_ranks = m_buffer1.data();
+ m_ranks2 = m_buffer2.data();
+ m_validRanks = false;
+ if (count < 32)
insertionSort(input, count);
- } else {
+ else {
// @@ Avoid touching the input multiple times.
for (uint32_t i = 0; i < count; i++) {
- FloatFlip((uint32_t &)input[i]);
+ floatFlip((uint32_t &)input[i]);
}
radixSort<uint32_t>((const uint32_t *)input, count);
for (uint32_t i = 0; i < count; i++) {
- IFloatFlip((uint32_t &)input[i]);
+ ifloatFlip((uint32_t &)input[i]);
}
}
- return *this;
}
- RadixSort &sort(const Array<float> &input)
+ void sort(const Array<float> &input)
{
- return sort(input.data(), input.size());
+ sort(input.data(), input.size());
}
// Access to results. m_ranks is a list of indices in sorted order, i.e. in the order you may further process your data
@@ -2127,25 +2168,18 @@ public:
return m_ranks;
}
- uint32_t *ranks()
- {
- XA_DEBUG_ASSERT(m_validRanks);
- return m_ranks;
- }
-
private:
- uint32_t m_size;
- uint32_t *m_ranks;
- uint32_t *m_ranks2;
+ uint32_t *m_ranks, *m_ranks2;
+ Array<uint32_t> m_buffer1, m_buffer2;
bool m_validRanks;
- void FloatFlip(uint32_t &f)
+ void floatFlip(uint32_t &f)
{
int32_t mask = (int32_t(f) >> 31) | 0x80000000; // Warren Hunt, Manchor Ko.
f ^= mask;
}
- void IFloatFlip(uint32_t &f)
+ void ifloatFlip(uint32_t &f)
{
uint32_t mask = ((f >> 31) - 1) | 0x80000000; // Michael Herf.
f ^= mask;
@@ -2179,7 +2213,8 @@ private:
}
}
- template <typename T> void insertionSort(const T *input, uint32_t count)
+ template <typename T>
+ void insertionSort(const T *input, uint32_t count)
{
if (!m_validRanks) {
m_ranks[0] = 0;
@@ -2210,7 +2245,8 @@ private:
}
}
- template <typename T> void radixSort(const T *input, uint32_t count)
+ template <typename T>
+ void radixSort(const T *input, uint32_t count)
{
const uint32_t P = sizeof(T); // pass count
// Allocate histograms & offsets on the stack
@@ -2247,9 +2283,8 @@ private:
}
// All values were equal, generate linear ranks.
if (!m_validRanks) {
- for (uint32_t i = 0; i < count; i++) {
+ for (uint32_t i = 0; i < count; i++)
m_ranks[i] = i;
- }
m_validRanks = true;
}
}
@@ -2327,9 +2362,8 @@ private:
m_coords.resize(inputCount);
for (uint32_t i = 0; i < inputCount; i++)
m_coords[i] = input[i].x;
- RadixSort radix;
- radix.sort(m_coords);
- const uint32_t *ranks = radix.ranks();
+ m_radix.sort(m_coords);
+ const uint32_t *ranks = m_radix.ranks();
m_top.clear();
m_bottom.clear();
m_top.reserve(inputCount);
@@ -2389,6 +2423,7 @@ private:
Array<Vector2> m_boundaryVertices;
Array<float> m_coords;
Array<Vector2> m_top, m_bottom, m_hull;
+ RadixSort m_radix;
};
static uint32_t meshEdgeFace(uint32_t edge) { return edge / 3; }
@@ -2404,9 +2439,8 @@ struct MeshFlags
{
enum
{
- HasFaceGroups = 1<<0,
- HasIgnoredFaces = 1<<1,
- HasNormals = 1<<2
+ HasIgnoredFaces = 1<<0,
+ HasNormals = 1<<1
};
};
@@ -2416,20 +2450,17 @@ static void meshGetBoundaryLoops(const Mesh &mesh, Array<uint32_t> &boundaryLoop
class Mesh
{
public:
- Mesh(float epsilon, uint32_t approxVertexCount, uint32_t approxFaceCount, uint32_t flags = 0, uint32_t id = UINT32_MAX) : m_epsilon(epsilon), m_flags(flags), m_id(id), m_faceIgnore(MemTag::Mesh), m_ignoredFaceCount(0), m_indices(MemTag::MeshIndices), m_positions(MemTag::MeshPositions), m_normals(MemTag::MeshNormals), m_texcoords(MemTag::MeshTexcoords), m_faceGroups(MemTag::Mesh), m_faceGroupFirstFace(MemTag::Mesh), m_faceGroupNextFace(MemTag::Mesh), m_faceGroupFaceCounts(MemTag::Mesh), m_colocalVertexCount(0), m_nextColocalVertex(MemTag::MeshColocals), m_boundaryEdges(MemTag::MeshBoundaries), m_oppositeEdges(MemTag::MeshBoundaries), m_nextBoundaryEdges(MemTag::MeshBoundaries), m_edgeMap(MemTag::MeshEdgeMap, approxFaceCount * 3)
+ Mesh(float epsilon, uint32_t approxVertexCount, uint32_t approxFaceCount, uint32_t flags = 0, uint32_t id = UINT32_MAX) : m_epsilon(epsilon), m_flags(flags), m_id(id), m_faceIgnore(MemTag::Mesh), m_indices(MemTag::MeshIndices), m_positions(MemTag::MeshPositions), m_normals(MemTag::MeshNormals), m_texcoords(MemTag::MeshTexcoords), m_nextColocalVertex(MemTag::MeshColocals), m_boundaryEdges(MemTag::MeshBoundaries), m_oppositeEdges(MemTag::MeshBoundaries), m_nextBoundaryEdges(MemTag::MeshBoundaries), m_edgeMap(MemTag::MeshEdgeMap, approxFaceCount * 3)
{
m_indices.reserve(approxFaceCount * 3);
m_positions.reserve(approxVertexCount);
m_texcoords.reserve(approxVertexCount);
- if (m_flags & MeshFlags::HasFaceGroups)
- m_faceGroups.reserve(approxFaceCount);
if (m_flags & MeshFlags::HasIgnoredFaces)
m_faceIgnore.reserve(approxFaceCount);
if (m_flags & MeshFlags::HasNormals)
m_normals.reserve(approxVertexCount);
}
- static constexpr uint16_t kInvalidFaceGroup = UINT16_MAX;
uint32_t flags() const { return m_flags; }
uint32_t id() const { return m_id; }
@@ -2451,37 +2482,30 @@ public:
};
};
- AddFaceResult::Enum addFace(uint32_t v0, uint32_t v1, uint32_t v2, bool ignore = false, bool hashEdge = true)
+ AddFaceResult::Enum addFace(uint32_t v0, uint32_t v1, uint32_t v2, bool ignore = false)
{
uint32_t indexArray[3];
indexArray[0] = v0;
indexArray[1] = v1;
indexArray[2] = v2;
- return addFace(indexArray, ignore, hashEdge);
+ return addFace(indexArray, ignore);
}
- AddFaceResult::Enum addFace(const uint32_t *indices, bool ignore = false, bool hashEdge = true)
+ AddFaceResult::Enum addFace(const uint32_t *indices, bool ignore = false)
{
AddFaceResult::Enum result = AddFaceResult::OK;
- if (m_flags & MeshFlags::HasFaceGroups)
- m_faceGroups.push_back(kInvalidFaceGroup);
- if (m_flags & MeshFlags::HasIgnoredFaces) {
+ if (m_flags & MeshFlags::HasIgnoredFaces)
m_faceIgnore.push_back(ignore);
- if (ignore)
- m_ignoredFaceCount++;
- }
const uint32_t firstIndex = m_indices.size();
for (uint32_t i = 0; i < 3; i++)
m_indices.push_back(indices[i]);
- if (hashEdge) {
- for (uint32_t i = 0; i < 3; i++) {
- const uint32_t vertex0 = m_indices[firstIndex + i];
- const uint32_t vertex1 = m_indices[firstIndex + (i + 1) % 3];
- const EdgeKey key(vertex0, vertex1);
- if (m_edgeMap.get(key) != UINT32_MAX)
- result = AddFaceResult::DuplicateEdge;
- m_edgeMap.add(key);
- }
+ for (uint32_t i = 0; i < 3; i++) {
+ const uint32_t vertex0 = m_indices[firstIndex + i];
+ const uint32_t vertex1 = m_indices[firstIndex + (i + 1) % 3];
+ const EdgeKey key(vertex0, vertex1);
+ if (m_edgeMap.get(key) != UINT32_MAX)
+ result = AddFaceResult::DuplicateEdge;
+ m_edgeMap.add(key);
}
return result;
}
@@ -2496,10 +2520,8 @@ public:
BVH bvh(aabbs);
Array<uint32_t> colocals(MemTag::MeshColocals);
Array<uint32_t> potential(MemTag::MeshColocals);
- m_colocalVertexCount = 0;
m_nextColocalVertex.resize(vertexCount);
- for (uint32_t i = 0; i < vertexCount; i++)
- m_nextColocalVertex[i] = UINT32_MAX;
+ m_nextColocalVertex.fillBytes(0xff);
for (uint32_t i = 0; i < vertexCount; i++) {
if (m_nextColocalVertex[i] != UINT32_MAX)
continue; // Already linked.
@@ -2517,7 +2539,6 @@ public:
m_nextColocalVertex[i] = i;
continue;
}
- m_colocalVertexCount += colocals.size();
// Link in ascending order.
insertionSort(colocals.data(), colocals.size());
for (uint32_t j = 0; j < colocals.size(); j++)
@@ -2526,99 +2547,6 @@ public:
}
}
- // Check if the face duplicates any edges of any face already in the group.
- bool faceDuplicatesGroupEdge(uint16_t group, uint32_t face) const
- {
- for (FaceEdgeIterator edgeIt(this, face); !edgeIt.isDone(); edgeIt.advance()) {
- for (ColocalEdgeIterator colocalEdgeIt(this, edgeIt.vertex0(), edgeIt.vertex1()); !colocalEdgeIt.isDone(); colocalEdgeIt.advance()) {
- if (m_faceGroups[meshEdgeFace(colocalEdgeIt.edge())] == group)
- return true;
- }
- }
- return false;
- }
-
- void createFaceGroups()
- {
- uint32_t firstUnassignedFace = 0;
- uint16_t group = 0;
- Array<uint32_t> growFaces;
- const uint32_t n = faceCount();
- m_faceGroupNextFace.resize(n);
- for (;;) {
- // Find an unassigned face.
- uint32_t face = UINT32_MAX;
- for (uint32_t f = firstUnassignedFace; f < n; f++) {
- if (m_faceGroups[f] == kInvalidFaceGroup && !isFaceIgnored(f)) {
- face = f;
- firstUnassignedFace = f + 1;
- break;
- }
- }
- if (face == UINT32_MAX)
- break; // All faces assigned to a group (except ignored faces).
- m_faceGroups[face] = group;
- m_faceGroupNextFace[face] = UINT32_MAX;
- m_faceGroupFirstFace.push_back(face);
- growFaces.clear();
- growFaces.push_back(face);
- uint32_t prevFace = face, groupFaceCount = 1;
- // Find faces connected to the face and assign them to the same group as the face, unless they are already assigned to another group.
- for (;;) {
- if (growFaces.isEmpty())
- break;
- const uint32_t f = growFaces.back();
- growFaces.pop_back();
- for (FaceEdgeIterator edgeIt(this, f); !edgeIt.isDone(); edgeIt.advance()) {
- // Iterate opposite edges. There may be more than one - non-manifold geometry can have duplicate edges.
- // Prioritize the one with exact vertex match, not just colocal.
- // If *any* of the opposite edges are already assigned to this group, don't do anything.
- bool alreadyAssignedToThisGroup = false;
- uint32_t bestConnectedFace = UINT32_MAX;
- for (ColocalEdgeIterator oppositeEdgeIt(this, edgeIt.vertex1(), edgeIt.vertex0()); !oppositeEdgeIt.isDone(); oppositeEdgeIt.advance()) {
- const uint32_t oppositeEdge = oppositeEdgeIt.edge();
- const uint32_t oppositeFace = meshEdgeFace(oppositeEdge);
- if (isFaceIgnored(oppositeFace))
- continue; // Don't add ignored faces to group.
- if (m_faceGroups[oppositeFace] == group) {
- alreadyAssignedToThisGroup = true;
- break;
- }
- if (m_faceGroups[oppositeFace] != kInvalidFaceGroup)
- continue; // Connected face is already assigned to another group.
- if (faceDuplicatesGroupEdge(group, oppositeFace))
- continue; // Don't want duplicate edges in a group.
- const uint32_t oppositeVertex0 = m_indices[meshEdgeIndex0(oppositeEdge)];
- const uint32_t oppositeVertex1 = m_indices[meshEdgeIndex1(oppositeEdge)];
- if (bestConnectedFace == UINT32_MAX || (oppositeVertex0 == edgeIt.vertex1() && oppositeVertex1 == edgeIt.vertex0()))
- bestConnectedFace = oppositeFace;
-#if 0
- else {
- // Choose the opposite face with the smallest dihedral angle.
- const float d1 = 1.0f - dot(computeFaceNormal(f), computeFaceNormal(bestConnectedFace));
- const float d2 = 1.0f - dot(computeFaceNormal(f), computeFaceNormal(oppositeFace));
- if (d2 < d1)
- bestConnectedFace = oppositeFace;
- }
-#endif
- }
- if (!alreadyAssignedToThisGroup && bestConnectedFace != UINT32_MAX) {
- m_faceGroups[bestConnectedFace] = group;
- m_faceGroupNextFace[bestConnectedFace] = UINT32_MAX;
- if (prevFace != UINT32_MAX)
- m_faceGroupNextFace[prevFace] = bestConnectedFace;
- prevFace = bestConnectedFace;
- groupFaceCount++;
- growFaces.push_back(bestConnectedFace);
- }
- }
- }
- m_faceGroupFaceCounts.push_back(groupFaceCount);
- group++;
- XA_ASSERT(group < kInvalidFaceGroup);
- }
- }
-
void createBoundaries()
{
const uint32_t edgeCount = m_indices.size();
@@ -2783,6 +2711,15 @@ public:
return result;
}
+ // Edge map can be destroyed when no longer used to reduce memory usage. It's used by:
+ // * Mesh::createBoundaries()
+ // * Mesh::ColocalEdgeIterator (used by MeshFaceGroups)
+ // * meshCloseHole()
+ void destroyEdgeMap()
+ {
+ m_edgeMap.destroy();
+ }
+
#if XA_DEBUG_EXPORT_OBJ
void writeObjVertices(FILE *file) const
{
@@ -2796,11 +2733,11 @@ public:
fprintf(file, "vt %g %g\n", m_texcoords[i].x, m_texcoords[i].y);
}
- void writeObjFace(FILE *file, uint32_t face) const
+ void writeObjFace(FILE *file, uint32_t face, uint32_t offset = 0) const
{
fprintf(file, "f ");
for (uint32_t j = 0; j < 3; j++) {
- const uint32_t index = m_indices[face * 3 + j] + 1; // 1-indexed
+ const uint32_t index = m_indices[face * 3 + j] + 1 + offset; // 1-indexed
fprintf(file, "%d/%d/%d%c", index, index, index, j == 2 ? '\n' : ' ');
}
}
@@ -2866,12 +2803,13 @@ public:
return area;
}
+ // Returned value is always positive, even if some triangles are flipped.
float computeParametricArea() const
{
float area = 0;
for (uint32_t f = 0; f < faceCount(); f++)
- area += computeFaceParametricArea(f);
- return fabsf(area); // May be negative, depends on texcoord winding.
+ area += fabsf(computeFaceParametricArea(f)); // May be negative, depends on texcoord winding.
+ return area;
}
float computeFaceArea(uint32_t face) const
@@ -2978,45 +2916,32 @@ public:
XA_INLINE bool isBoundaryEdge(uint32_t edge) const { return m_oppositeEdges[edge] == UINT32_MAX; }
XA_INLINE const Array<uint32_t> &boundaryEdges() const { return m_boundaryEdges; }
XA_INLINE bool isBoundaryVertex(uint32_t vertex) const { return m_isBoundaryVertex.get(vertex); }
- XA_INLINE uint32_t colocalVertexCount() const { return m_colocalVertexCount; }
XA_INLINE uint32_t vertexCount() const { return m_positions.size(); }
XA_INLINE uint32_t vertexAt(uint32_t i) const { return m_indices[i]; }
XA_INLINE const Vector3 &position(uint32_t vertex) const { return m_positions[vertex]; }
+ XA_INLINE const Vector3 *positions() const { return m_positions.data(); }
XA_INLINE const Vector3 &normal(uint32_t vertex) const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasNormals); return m_normals[vertex]; }
XA_INLINE const Vector2 &texcoord(uint32_t vertex) const { return m_texcoords[vertex]; }
XA_INLINE Vector2 &texcoord(uint32_t vertex) { return m_texcoords[vertex]; }
XA_INLINE const Vector2 *texcoords() const { return m_texcoords.data(); }
XA_INLINE Vector2 *texcoords() { return m_texcoords.data(); }
- XA_INLINE uint32_t ignoredFaceCount() const { return m_ignoredFaceCount; }
XA_INLINE uint32_t faceCount() const { return m_indices.size() / 3; }
- XA_INLINE uint16_t faceGroupAt(uint32_t face) const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasFaceGroups); return m_faceGroups[face]; }
- XA_INLINE uint32_t faceGroupCount() const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasFaceGroups); return m_faceGroupFaceCounts.size(); }
- XA_INLINE uint32_t faceGroupNextFace(uint32_t face) const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasFaceGroups); return m_faceGroupNextFace[face]; }
- XA_INLINE uint32_t faceGroupFaceCount(uint32_t group) const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasFaceGroups); return m_faceGroupFaceCounts[group]; }
XA_INLINE const uint32_t *indices() const { return m_indices.data(); }
XA_INLINE uint32_t indexCount() const { return m_indices.size(); }
+ XA_INLINE bool isFaceIgnored(uint32_t face) const { return (m_flags & MeshFlags::HasIgnoredFaces) && m_faceIgnore[face]; }
private:
- bool isFaceIgnored(uint32_t face) const { return (m_flags & MeshFlags::HasIgnoredFaces) && m_faceIgnore[face]; }
float m_epsilon;
uint32_t m_flags;
uint32_t m_id;
Array<bool> m_faceIgnore;
- uint32_t m_ignoredFaceCount;
Array<uint32_t> m_indices;
Array<Vector3> m_positions;
Array<Vector3> m_normals;
Array<Vector2> m_texcoords;
- // Populated by createFaceGroups
- Array<uint16_t> m_faceGroups;
- Array<uint32_t> m_faceGroupFirstFace;
- Array<uint32_t> m_faceGroupNextFace; // In: face. Out: the next face in the same group.
- Array<uint32_t> m_faceGroupFaceCounts; // In: face group. Out: number of faces in the group.
-
// Populated by createColocals
- uint32_t m_colocalVertexCount;
Array<uint32_t> m_nextColocalVertex; // In: vertex index. Out: the vertex index of the next colocal position.
// Populated by createBoundaries
@@ -3029,7 +2954,6 @@ private:
struct EdgeKey
{
- EdgeKey() {}
EdgeKey(const EdgeKey &k) : v0(k.v0), v1(k.v1) {}
EdgeKey(uint32_t v0, uint32_t v1) : v0(v0), v1(v1) {}
bool operator==(const EdgeKey &k) const { return v0 == k.v0 && v1 == k.v1; }
@@ -3252,19 +3176,123 @@ public:
uint32_t m_edge;
uint32_t m_relativeEdge;
};
+};
+
+struct MeshFaceGroups
+{
+ typedef uint32_t Handle;
+ static constexpr Handle kInvalid = UINT32_MAX;
- class GroupFaceIterator
+ MeshFaceGroups(const Mesh *mesh) : m_mesh(mesh), m_groups(MemTag::Mesh), m_firstFace(MemTag::Mesh), m_nextFace(MemTag::Mesh), m_faceCount(MemTag::Mesh) {}
+ XA_INLINE Handle groupAt(uint32_t face) const { return m_groups[face]; }
+ XA_INLINE uint32_t groupCount() const { return m_faceCount.size(); }
+ XA_INLINE uint32_t nextFace(uint32_t face) const { return m_nextFace[face]; }
+ XA_INLINE uint32_t faceCount(uint32_t group) const { return m_faceCount[group]; }
+
+ void compute()
+ {
+ m_groups.resize(m_mesh->faceCount());
+ m_groups.fillBytes(0xff); // Set all faces to kInvalid
+ uint32_t firstUnassignedFace = 0;
+ Handle group = 0;
+ Array<uint32_t> growFaces;
+ const uint32_t n = m_mesh->faceCount();
+ m_nextFace.resize(n);
+ for (;;) {
+ // Find an unassigned face.
+ uint32_t face = UINT32_MAX;
+ for (uint32_t f = firstUnassignedFace; f < n; f++) {
+ if (m_groups[f] == kInvalid && !m_mesh->isFaceIgnored(f)) {
+ face = f;
+ firstUnassignedFace = f + 1;
+ break;
+ }
+ }
+ if (face == UINT32_MAX)
+ break; // All faces assigned to a group (except ignored faces).
+ m_groups[face] = group;
+ m_nextFace[face] = UINT32_MAX;
+ m_firstFace.push_back(face);
+ growFaces.clear();
+ growFaces.push_back(face);
+ uint32_t prevFace = face, groupFaceCount = 1;
+ // Find faces connected to the face and assign them to the same group as the face, unless they are already assigned to another group.
+ for (;;) {
+ if (growFaces.isEmpty())
+ break;
+ const uint32_t f = growFaces.back();
+ growFaces.pop_back();
+ for (Mesh::FaceEdgeIterator edgeIt(m_mesh, f); !edgeIt.isDone(); edgeIt.advance()) {
+ // Iterate opposite edges. There may be more than one - non-manifold geometry can have duplicate edges.
+ // Prioritize the one with exact vertex match, not just colocal.
+ // If *any* of the opposite edges are already assigned to this group, don't do anything.
+ bool alreadyAssignedToThisGroup = false;
+ uint32_t bestConnectedFace = UINT32_MAX;
+ for (Mesh::ColocalEdgeIterator oppositeEdgeIt(m_mesh, edgeIt.vertex1(), edgeIt.vertex0()); !oppositeEdgeIt.isDone(); oppositeEdgeIt.advance()) {
+ const uint32_t oppositeEdge = oppositeEdgeIt.edge();
+ const uint32_t oppositeFace = meshEdgeFace(oppositeEdge);
+#if 0
+ // Reject opposite face if dihedral angle >= 90 degrees.
+ {
+ Vector3 a = m_mesh->computeFaceNormal(f);
+ Vector3 b = m_mesh->computeFaceNormal(oppositeFace);
+ if (dot(a, b) <= 0.0f)
+ continue;
+ }
+#endif
+ if (m_mesh->isFaceIgnored(oppositeFace))
+ continue; // Don't add ignored faces to group.
+ if (m_groups[oppositeFace] == group) {
+ alreadyAssignedToThisGroup = true;
+ break;
+ }
+ if (m_groups[oppositeFace] != kInvalid)
+ continue; // Connected face is already assigned to another group.
+ if (faceDuplicatesGroupEdge(group, oppositeFace))
+ continue; // Don't want duplicate edges in a group.
+ const uint32_t oppositeVertex0 = m_mesh->vertexAt(meshEdgeIndex0(oppositeEdge));
+ const uint32_t oppositeVertex1 = m_mesh->vertexAt(meshEdgeIndex1(oppositeEdge));
+ if (bestConnectedFace == UINT32_MAX || (oppositeVertex0 == edgeIt.vertex1() && oppositeVertex1 == edgeIt.vertex0()))
+ bestConnectedFace = oppositeFace;
+#if 0
+ else {
+ // Choose the opposite face with the smallest dihedral angle.
+ const float d1 = 1.0f - dot(computeFaceNormal(f), computeFaceNormal(bestConnectedFace));
+ const float d2 = 1.0f - dot(computeFaceNormal(f), computeFaceNormal(oppositeFace));
+ if (d2 < d1)
+ bestConnectedFace = oppositeFace;
+ }
+#endif
+ }
+ if (!alreadyAssignedToThisGroup && bestConnectedFace != UINT32_MAX) {
+ m_groups[bestConnectedFace] = group;
+ m_nextFace[bestConnectedFace] = UINT32_MAX;
+ if (prevFace != UINT32_MAX)
+ m_nextFace[prevFace] = bestConnectedFace;
+ prevFace = bestConnectedFace;
+ groupFaceCount++;
+ growFaces.push_back(bestConnectedFace);
+ }
+ }
+ }
+ m_faceCount.push_back(groupFaceCount);
+ group++;
+ XA_ASSERT(group < kInvalid);
+ }
+ }
+
+ class Iterator
{
public:
- GroupFaceIterator(const Mesh *mesh, uint32_t group) : m_mesh(mesh)
+ Iterator(const MeshFaceGroups *meshFaceGroups, Handle group) : m_meshFaceGroups(meshFaceGroups)
{
- XA_DEBUG_ASSERT(group != UINT32_MAX);
- m_current = mesh->m_faceGroupFirstFace[group];
+ XA_DEBUG_ASSERT(group != kInvalid);
+ m_current = m_meshFaceGroups->m_firstFace[group];
}
void advance()
{
- m_current = m_mesh->m_faceGroupNextFace[m_current];
+ m_current = m_meshFaceGroups->m_nextFace[m_current];
}
bool isDone() const
@@ -3278,12 +3306,31 @@ public:
}
private:
- const Mesh *m_mesh;
+ const MeshFaceGroups *m_meshFaceGroups;
uint32_t m_current;
};
+
+private:
+ // Check if the face duplicates any edges of any face already in the group.
+ bool faceDuplicatesGroupEdge(Handle group, uint32_t face) const
+ {
+ for (Mesh::FaceEdgeIterator edgeIt(m_mesh, face); !edgeIt.isDone(); edgeIt.advance()) {
+ for (Mesh::ColocalEdgeIterator colocalEdgeIt(m_mesh, edgeIt.vertex0(), edgeIt.vertex1()); !colocalEdgeIt.isDone(); colocalEdgeIt.advance()) {
+ if (m_groups[meshEdgeFace(colocalEdgeIt.edge())] == group)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ const Mesh *m_mesh;
+ Array<Handle> m_groups;
+ Array<uint32_t> m_firstFace;
+ Array<uint32_t> m_nextFace; // In: face. Out: the next face in the same group.
+ Array<uint32_t> m_faceCount; // In: face group. Out: number of faces in the group.
};
-constexpr uint16_t Mesh::kInvalidFaceGroup;
+constexpr MeshFaceGroups::Handle MeshFaceGroups::kInvalid;
static bool meshCloseHole(Mesh *mesh, const Array<uint32_t> &holeVertices, const Vector3 &normal)
{
@@ -3748,7 +3795,7 @@ public:
return handle;
}
- void run(TaskGroupHandle handle, Task task)
+ void run(TaskGroupHandle handle, const Task &task)
{
XA_DEBUG_ASSERT(handle.value != UINT32_MAX);
TaskGroup &group = m_groups[handle.value];
@@ -3810,9 +3857,9 @@ private:
};
TaskGroup *m_groups;
- uint32_t m_maxGroups;
Array<Worker> m_workers;
std::atomic<bool> m_shutdown;
+ uint32_t m_maxGroups;
static thread_local uint32_t m_threadIndex;
static void workerThread(TaskScheduler *scheduler, Worker *worker, uint32_t threadIndex)
@@ -4024,7 +4071,7 @@ public:
bool intersect(Vector2 v1, Vector2 v2, float epsilon)
{
const uint32_t edgeCount = m_edges.size();
- bool bruteForce = edgeCount <= 64;
+ bool bruteForce = edgeCount <= 20;
if (!bruteForce && m_cellDataOffsets.isEmpty())
bruteForce = !createGrid();
if (bruteForce) {
@@ -4048,31 +4095,72 @@ public:
return false;
}
- bool intersectSelf(float epsilon)
+ // If edges is empty, checks for intersection with all edges in the grid.
+ bool intersect(float epsilon, ConstArrayView<uint32_t> edges = ConstArrayView<uint32_t>(), ConstArrayView<uint32_t> ignoreEdges = ConstArrayView<uint32_t>())
{
- const uint32_t edgeCount = m_edges.size();
- bool bruteForce = edgeCount <= 64;
+ bool bruteForce = m_edges.size() <= 20;
if (!bruteForce && m_cellDataOffsets.isEmpty())
bruteForce = !createGrid();
- for (uint32_t i = 0; i < edgeCount; i++) {
- const uint32_t edge1 = m_edges[i];
+ const uint32_t *edges1, *edges2 = nullptr;
+ uint32_t edges1Count, edges2Count = 0;
+ if (edges.length == 0) {
+ edges1 = m_edges.data();
+ edges1Count = m_edges.size();
+ } else {
+ edges1 = edges.data;
+ edges1Count = edges.length;
+ }
+ if (bruteForce) {
+ edges2 = m_edges.data();
+ edges2Count = m_edges.size();
+ }
+ for (uint32_t i = 0; i < edges1Count; i++) {
+ const uint32_t edge1 = edges1[i];
+ const uint32_t edge1Vertex[2] = { vertexAt(meshEdgeIndex0(edge1)), vertexAt(meshEdgeIndex1(edge1)) };
+ const Vector2 &edge1Position1 = m_positions[edge1Vertex[0]];
+ const Vector2 &edge1Position2 = m_positions[edge1Vertex[1]];
+ const Extents2 edge1Extents(edge1Position1, edge1Position2);
+ uint32_t j = 0;
if (bruteForce) {
- for (uint32_t j = 0; j < edgeCount; j++) {
- const uint32_t edge2 = m_edges[j];
- if (edgesIntersect(edge1, edge2, epsilon))
- return true;
+ // If checking against self, test each edge pair only once.
+ if (edges.length == 0) {
+ j = i + 1;
+ if (j == edges1Count)
+ break;
}
} else {
computePotentialEdges(edgePosition0(edge1), edgePosition1(edge1));
- uint32_t prevEdge = UINT32_MAX;
- for (uint32_t j = 0; j < m_potentialEdges.size(); j++) {
- const uint32_t edge2 = m_potentialEdges[j];
- if (edge2 == prevEdge)
- continue;
- if (edgesIntersect(edge1, edge2, epsilon))
- return true;
- prevEdge = edge2;
+ edges2 = m_potentialEdges.data();
+ edges2Count = m_potentialEdges.size();
+ }
+ uint32_t prevEdge = UINT32_MAX; // Handle potential edges duplicates.
+ for (; j < edges2Count; j++) {
+ const uint32_t edge2 = edges2[j];
+ if (edge1 == edge2)
+ continue;
+ if (edge2 == prevEdge)
+ continue;
+ prevEdge = edge2;
+ // Check if edge2 is ignored.
+ bool ignore = false;
+ for (uint32_t k = 0; k < ignoreEdges.length; k++) {
+ if (edge2 == ignoreEdges[k]) {
+ ignore = true;
+ break;
+ }
}
+ if (ignore)
+ continue;
+ const uint32_t edge2Vertex[2] = { vertexAt(meshEdgeIndex0(edge2)), vertexAt(meshEdgeIndex1(edge2)) };
+ // Ignore connected edges, since they can't intersect (only overlap), and may be detected as false positives.
+ if (edge1Vertex[0] == edge2Vertex[0] || edge1Vertex[0] == edge2Vertex[1] || edge1Vertex[1] == edge2Vertex[0] || edge1Vertex[1] == edge2Vertex[1])
+ continue;
+ const Vector2 &edge2Position1 = m_positions[edge2Vertex[0]];
+ const Vector2 &edge2Position2 = m_positions[edge2Vertex[1]];
+ if (!Extents2::intersect(edge1Extents, Extents2(edge2Position1, edge2Position2)))
+ continue;
+ if (linesIntersect(edge1Position1, edge1Position2, edge2Position1, edge2Position2, epsilon))
+ return true;
}
}
return false;
@@ -4218,11 +4306,11 @@ private:
}
if (currentCell[0] >= m_gridWidth || currentCell[1] >= m_gridHeight)
break;
- if (stepX == 0 && currentCell[0] < lastCell[0])
+ if (stepX == -1 && currentCell[0] < lastCell[0])
break;
if (stepX == 1 && currentCell[0] > lastCell[0])
break;
- if (stepY == 0 && currentCell[1] < lastCell[1])
+ if (stepY == -1 && currentCell[1] < lastCell[1])
break;
if (stepY == 1 && currentCell[1] > lastCell[1])
break;
@@ -4230,18 +4318,6 @@ private:
}
}
- bool edgesIntersect(uint32_t edge1, uint32_t edge2, float epsilon) const
- {
- if (edge1 == edge2)
- return false;
- const uint32_t ai[2] = { vertexAt(meshEdgeIndex0(edge1)), vertexAt(meshEdgeIndex1(edge1)) };
- const uint32_t bi[2] = { vertexAt(meshEdgeIndex0(edge2)), vertexAt(meshEdgeIndex1(edge2)) };
- // Ignore connected edges, since they can't intersect (only overlap), and may be detected as false positives.
- if (ai[0] == bi[0] || ai[0] == bi[1] || ai[1] == bi[0] || ai[1] == bi[1])
- return false;
- return linesIntersect(m_positions[ai[0]], m_positions[ai[1]], m_positions[bi[0]], m_positions[bi[1]], epsilon);
- }
-
uint32_t cellX(float x) const
{
return min((uint32_t)max(0.0f, (x - m_gridOrigin.x) / m_cellSize), m_gridWidth - 1u);
@@ -4301,6 +4377,807 @@ struct UvMeshInstance
bool rotateCharts;
};
+/*
+ * Copyright (c) 2004-2010, Bruno Levy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * * Neither the name of the ALICE Project-Team nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * If you modify this software, you should include a notice giving the
+ * name of the person performing the modification, the date of modification,
+ * and the reason for such modification.
+ *
+ * Contact: Bruno Levy
+ *
+ * levy@loria.fr
+ *
+ * ALICE Project
+ * LORIA, INRIA Lorraine,
+ * Campus Scientifique, BP 239
+ * 54506 VANDOEUVRE LES NANCY CEDEX
+ * FRANCE
+ */
+namespace opennl {
+#define NL_NEW(T) XA_ALLOC(MemTag::OpenNL, T)
+#define NL_NEW_ARRAY(T,NB) XA_ALLOC_ARRAY(MemTag::OpenNL, T, NB)
+#define NL_RENEW_ARRAY(T,x,NB) XA_REALLOC(MemTag::OpenNL, x, T, NB)
+#define NL_DELETE(x) XA_FREE(x); x = nullptr
+#define NL_DELETE_ARRAY(x) XA_FREE(x); x = nullptr
+#define NL_CLEAR(x, T) memset(x, 0, sizeof(T));
+#define NL_CLEAR_ARRAY(T,x,NB) memset(x, 0, (size_t)(NB)*sizeof(T))
+#define NL_NEW_VECTOR(dim) XA_ALLOC_ARRAY(MemTag::OpenNL, double, dim)
+#define NL_DELETE_VECTOR(ptr) XA_FREE(ptr)
+
+struct NLMatrixStruct;
+typedef NLMatrixStruct * NLMatrix;
+typedef void (*NLDestroyMatrixFunc)(NLMatrix M);
+typedef void (*NLMultMatrixVectorFunc)(NLMatrix M, const double* x, double* y);
+
+#define NL_MATRIX_SPARSE_DYNAMIC 0x1001
+#define NL_MATRIX_CRS 0x1002
+#define NL_MATRIX_OTHER 0x1006
+
+struct NLMatrixStruct
+{
+ uint32_t m;
+ uint32_t n;
+ uint32_t type;
+ NLDestroyMatrixFunc destroy_func;
+ NLMultMatrixVectorFunc mult_func;
+};
+
+/* Dynamic arrays for sparse row/columns */
+
+struct NLCoeff
+{
+ uint32_t index;
+ double value;
+};
+
+struct NLRowColumn
+{
+ uint32_t size;
+ uint32_t capacity;
+ NLCoeff* coeff;
+};
+
+/* Compressed Row Storage */
+
+struct NLCRSMatrix
+{
+ uint32_t m;
+ uint32_t n;
+ uint32_t type;
+ NLDestroyMatrixFunc destroy_func;
+ NLMultMatrixVectorFunc mult_func;
+ double* val;
+ uint32_t* rowptr;
+ uint32_t* colind;
+ uint32_t nslices;
+ uint32_t* sliceptr;
+};
+
+/* SparseMatrix data structure */
+
+struct NLSparseMatrix
+{
+ uint32_t m;
+ uint32_t n;
+ uint32_t type;
+ NLDestroyMatrixFunc destroy_func;
+ NLMultMatrixVectorFunc mult_func;
+ uint32_t diag_size;
+ uint32_t diag_capacity;
+ NLRowColumn* row;
+ NLRowColumn* column;
+ double* diag;
+ uint32_t row_capacity;
+ uint32_t column_capacity;
+};
+
+/* NLContext data structure */
+
+struct NLBufferBinding
+{
+ void* base_address;
+ uint32_t stride;
+};
+
+#define NL_BUFFER_ITEM(B,i) *(double*)((void*)((char*)((B).base_address)+((i)*(B).stride)))
+
+struct NLContext
+{
+ NLBufferBinding *variable_buffer;
+ double *variable_value;
+ bool *variable_is_locked;
+ uint32_t *variable_index;
+ uint32_t n;
+ NLMatrix M;
+ NLMatrix P;
+ NLMatrix B;
+ NLRowColumn af;
+ NLRowColumn al;
+ double *x;
+ double *b;
+ uint32_t nb_variables;
+ uint32_t nb_systems;
+ uint32_t current_row;
+ uint32_t max_iterations;
+ bool max_iterations_defined;
+ double threshold;
+ double omega;
+ uint32_t used_iterations;
+ double error;
+};
+
+static void nlDeleteMatrix(NLMatrix M)
+{
+ if (!M)
+ return;
+ M->destroy_func(M);
+ NL_DELETE(M);
+}
+
+static void nlMultMatrixVector(NLMatrix M, const double* x, double* y)
+{
+ M->mult_func(M, x, y);
+}
+
+static void nlRowColumnConstruct(NLRowColumn* c)
+{
+ c->size = 0;
+ c->capacity = 0;
+ c->coeff = nullptr;
+}
+
+static void nlRowColumnDestroy(NLRowColumn* c)
+{
+ NL_DELETE_ARRAY(c->coeff);
+ c->size = 0;
+ c->capacity = 0;
+}
+
+static void nlRowColumnGrow(NLRowColumn* c)
+{
+ if (c->capacity != 0) {
+ c->capacity = 2 * c->capacity;
+ c->coeff = NL_RENEW_ARRAY(NLCoeff, c->coeff, c->capacity);
+ } else {
+ c->capacity = 4;
+ c->coeff = NL_NEW_ARRAY(NLCoeff, c->capacity);
+ NL_CLEAR_ARRAY(NLCoeff, c->coeff, c->capacity);
+ }
+}
+
+static void nlRowColumnAdd(NLRowColumn* c, uint32_t index, double value)
+{
+ for (uint32_t i = 0; i < c->size; i++) {
+ if (c->coeff[i].index == index) {
+ c->coeff[i].value += value;
+ return;
+ }
+ }
+ if (c->size == c->capacity)
+ nlRowColumnGrow(c);
+ c->coeff[c->size].index = index;
+ c->coeff[c->size].value = value;
+ c->size++;
+}
+
+/* Does not check whether the index already exists */
+static void nlRowColumnAppend(NLRowColumn* c, uint32_t index, double value)
+{
+ if (c->size == c->capacity)
+ nlRowColumnGrow(c);
+ c->coeff[c->size].index = index;
+ c->coeff[c->size].value = value;
+ c->size++;
+}
+
+static void nlRowColumnZero(NLRowColumn* c)
+{
+ c->size = 0;
+}
+
+static void nlRowColumnClear(NLRowColumn* c)
+{
+ c->size = 0;
+ c->capacity = 0;
+ NL_DELETE_ARRAY(c->coeff);
+}
+
+static int nlCoeffCompare(const void* p1, const void* p2)
+{
+ return (((NLCoeff*)(p2))->index < ((NLCoeff*)(p1))->index);
+}
+
+static void nlRowColumnSort(NLRowColumn* c)
+{
+ qsort(c->coeff, c->size, sizeof(NLCoeff), nlCoeffCompare);
+}
+
+/* CRSMatrix data structure */
+
+static void nlCRSMatrixDestroy(NLCRSMatrix* M)
+{
+ NL_DELETE_ARRAY(M->val);
+ NL_DELETE_ARRAY(M->rowptr);
+ NL_DELETE_ARRAY(M->colind);
+ NL_DELETE_ARRAY(M->sliceptr);
+ M->m = 0;
+ M->n = 0;
+ M->nslices = 0;
+}
+
+static void nlCRSMatrixMultSlice(NLCRSMatrix* M, const double* x, double* y, uint32_t Ibegin, uint32_t Iend)
+{
+ for (uint32_t i = Ibegin; i < Iend; ++i) {
+ double sum = 0.0;
+ for (uint32_t j = M->rowptr[i]; j < M->rowptr[i + 1]; ++j)
+ sum += M->val[j] * x[M->colind[j]];
+ y[i] = sum;
+ }
+}
+
+static void nlCRSMatrixMult(NLCRSMatrix* M, const double* x, double* y)
+{
+ int nslices = (int)(M->nslices);
+ for (int slice = 0; slice < nslices; ++slice)
+ nlCRSMatrixMultSlice(M, x, y, M->sliceptr[slice], M->sliceptr[slice + 1]);
+}
+
+static void nlCRSMatrixConstruct(NLCRSMatrix* M, uint32_t m, uint32_t n, uint32_t nnz, uint32_t nslices)
+{
+ M->m = m;
+ M->n = n;
+ M->type = NL_MATRIX_CRS;
+ M->destroy_func = (NLDestroyMatrixFunc)nlCRSMatrixDestroy;
+ M->mult_func = (NLMultMatrixVectorFunc)nlCRSMatrixMult;
+ M->nslices = nslices;
+ M->val = NL_NEW_ARRAY(double, nnz);
+ NL_CLEAR_ARRAY(double, M->val, nnz);
+ M->rowptr = NL_NEW_ARRAY(uint32_t, m + 1);
+ NL_CLEAR_ARRAY(uint32_t, M->rowptr, m + 1);
+ M->colind = NL_NEW_ARRAY(uint32_t, nnz);
+ NL_CLEAR_ARRAY(uint32_t, M->colind, nnz);
+ M->sliceptr = NL_NEW_ARRAY(uint32_t, nslices + 1);
+ NL_CLEAR_ARRAY(uint32_t, M->sliceptr, nslices + 1);
+}
+
+/* SparseMatrix data structure */
+
+static void nlSparseMatrixDestroyRowColumns(NLSparseMatrix* M)
+{
+ for (uint32_t i = 0; i < M->m; i++)
+ nlRowColumnDestroy(&(M->row[i]));
+ NL_DELETE_ARRAY(M->row);
+}
+
+static void nlSparseMatrixDestroy(NLSparseMatrix* M)
+{
+ XA_DEBUG_ASSERT(M->type == NL_MATRIX_SPARSE_DYNAMIC);
+ nlSparseMatrixDestroyRowColumns(M);
+ NL_DELETE_ARRAY(M->diag);
+}
+
+static void nlSparseMatrixAdd(NLSparseMatrix* M, uint32_t i, uint32_t j, double value)
+{
+ XA_DEBUG_ASSERT(i >= 0 && i <= M->m - 1);
+ XA_DEBUG_ASSERT(j >= 0 && j <= M->n - 1);
+ if (i == j)
+ M->diag[i] += value;
+ nlRowColumnAdd(&(M->row[i]), j, value);
+}
+
+/* Returns the number of non-zero coefficients */
+static uint32_t nlSparseMatrixNNZ(NLSparseMatrix* M)
+{
+ uint32_t nnz = 0;
+ for (uint32_t i = 0; i < M->m; i++)
+ nnz += M->row[i].size;
+ return nnz;
+}
+
+static void nlSparseMatrixSort(NLSparseMatrix* M)
+{
+ for (uint32_t i = 0; i < M->m; i++)
+ nlRowColumnSort(&(M->row[i]));
+}
+
+/* SparseMatrix x Vector routines, internal helper routines */
+
+static void nlSparseMatrix_mult_rows(NLSparseMatrix* A, const double* x, double* y)
+{
+ /*
+ * Note: OpenMP does not like unsigned ints
+ * (causes some floating point exceptions),
+ * therefore I use here signed ints for all
+ * indices.
+ */
+ int m = (int)(A->m);
+ NLCoeff* c = nullptr;
+ NLRowColumn* Ri = nullptr;
+ for (int i = 0; i < m; i++) {
+ Ri = &(A->row[i]);
+ y[i] = 0;
+ for (int ij = 0; ij < (int)(Ri->size); ij++) {
+ c = &(Ri->coeff[ij]);
+ y[i] += c->value * x[c->index];
+ }
+ }
+}
+
+static void nlSparseMatrixMult(NLSparseMatrix* A, const double* x, double* y)
+{
+ XA_DEBUG_ASSERT(A->type == NL_MATRIX_SPARSE_DYNAMIC);
+ nlSparseMatrix_mult_rows(A, x, y);
+}
+
+static void nlSparseMatrixConstruct(NLSparseMatrix* M, uint32_t m, uint32_t n)
+{
+ M->m = m;
+ M->n = n;
+ M->type = NL_MATRIX_SPARSE_DYNAMIC;
+ M->destroy_func = (NLDestroyMatrixFunc)nlSparseMatrixDestroy;
+ M->mult_func = (NLMultMatrixVectorFunc)nlSparseMatrixMult;
+ M->row = NL_NEW_ARRAY(NLRowColumn, m);
+ NL_CLEAR_ARRAY(NLRowColumn, M->row, m);
+ M->row_capacity = m;
+ for (uint32_t i = 0; i < n; i++)
+ nlRowColumnConstruct(&(M->row[i]));
+ M->row_capacity = 0;
+ M->column = nullptr;
+ M->column_capacity = 0;
+ M->diag_size = min(m, n);
+ M->diag_capacity = M->diag_size;
+ M->diag = NL_NEW_ARRAY(double, M->diag_size);
+ NL_CLEAR_ARRAY(double, M->diag, M->diag_size);
+}
+
+static NLMatrix nlCRSMatrixNewFromSparseMatrix(NLSparseMatrix* M)
+{
+ uint32_t nnz = nlSparseMatrixNNZ(M);
+ uint32_t nslices = 8; /* TODO: get number of cores */
+ uint32_t slice, cur_bound, cur_NNZ, cur_row;
+ uint32_t k;
+ uint32_t slice_size = nnz / nslices;
+ NLCRSMatrix* CRS = NL_NEW(NLCRSMatrix);
+ NL_CLEAR(CRS, NLCRSMatrix);
+ nlCRSMatrixConstruct(CRS, M->m, M->n, nnz, nslices);
+ nlSparseMatrixSort(M);
+ /* Convert matrix to CRS format */
+ k = 0;
+ for (uint32_t i = 0; i < M->m; ++i) {
+ NLRowColumn* Ri = &(M->row[i]);
+ CRS->rowptr[i] = k;
+ for (uint32_t ij = 0; ij < Ri->size; ij++) {
+ NLCoeff* c = &(Ri->coeff[ij]);
+ CRS->val[k] = c->value;
+ CRS->colind[k] = c->index;
+ ++k;
+ }
+ }
+ CRS->rowptr[M->m] = k;
+ /* Create "slices" to be used by parallel sparse matrix vector product */
+ if (CRS->sliceptr) {
+ cur_bound = slice_size;
+ cur_NNZ = 0;
+ cur_row = 0;
+ CRS->sliceptr[0] = 0;
+ for (slice = 1; slice < nslices; ++slice) {
+ while (cur_NNZ < cur_bound && cur_row < M->m) {
+ ++cur_row;
+ cur_NNZ += CRS->rowptr[cur_row + 1] - CRS->rowptr[cur_row];
+ }
+ CRS->sliceptr[slice] = cur_row;
+ cur_bound += slice_size;
+ }
+ CRS->sliceptr[nslices] = M->m;
+ }
+ return (NLMatrix)CRS;
+}
+
+static void nlMatrixCompress(NLMatrix* M)
+{
+ NLMatrix CRS = nullptr;
+ if ((*M)->type != NL_MATRIX_SPARSE_DYNAMIC)
+ return;
+ CRS = nlCRSMatrixNewFromSparseMatrix((NLSparseMatrix*)*M);
+ nlDeleteMatrix(*M);
+ *M = CRS;
+}
+
+static NLContext *nlNewContext()
+{
+ NLContext* result = NL_NEW(NLContext);
+ NL_CLEAR(result, NLContext);
+ result->max_iterations = 100;
+ result->threshold = 1e-6;
+ result->omega = 1.5;
+ result->nb_systems = 1;
+ return result;
+}
+
+static void nlDeleteContext(NLContext *context)
+{
+ nlDeleteMatrix(context->M);
+ context->M = nullptr;
+ nlDeleteMatrix(context->P);
+ context->P = nullptr;
+ nlDeleteMatrix(context->B);
+ context->B = nullptr;
+ nlRowColumnDestroy(&context->af);
+ nlRowColumnDestroy(&context->al);
+ NL_DELETE_ARRAY(context->variable_value);
+ NL_DELETE_ARRAY(context->variable_buffer);
+ NL_DELETE_ARRAY(context->variable_is_locked);
+ NL_DELETE_ARRAY(context->variable_index);
+ NL_DELETE_ARRAY(context->x);
+ NL_DELETE_ARRAY(context->b);
+ NL_DELETE(context);
+}
+
+static double ddot(int n, const double *x, const double *y)
+{
+ double sum = 0.0;
+ for (int i = 0; i < n; i++)
+ sum += x[i] * y[i];
+ return sum;
+}
+
+static void daxpy(int n, double a, const double *x, double *y)
+{
+ for (int i = 0; i < n; i++)
+ y[i] = a * x[i] + y[i];
+}
+
+static void dscal(int n, double a, double *x)
+{
+ for (int i = 0; i < n; i++)
+ x[i] *= a;
+}
+
+/*
+ * The implementation of the solvers is inspired by
+ * the lsolver library, by Christian Badura, available from:
+ * http://www.mathematik.uni-freiburg.de
+ * /IAM/Research/projectskr/lin_solver/
+ *
+ * About the Conjugate Gradient, details can be found in:
+ * Ashby, Manteuffel, Saylor
+ * A taxononmy for conjugate gradient methods
+ * SIAM J Numer Anal 27, 1542-1568 (1990)
+ *
+ * This version is completely abstract, the same code can be used for
+ * CPU/GPU, dense matrix / sparse matrix etc...
+ * Abstraction is realized through:
+ * - Abstract matrix interface (NLMatrix), that can implement different
+ * versions of matrix x vector product (CPU/GPU, sparse/dense ...)
+ */
+
+static uint32_t nlSolveSystem_PRE_CG(NLMatrix M, NLMatrix P, double* b, double* x, double eps, uint32_t max_iter, double *sq_bnorm, double *sq_rnorm)
+{
+ int N = (int)M->n;
+ double* r = NL_NEW_VECTOR(N);
+ double* d = NL_NEW_VECTOR(N);
+ double* h = NL_NEW_VECTOR(N);
+ double *Ad = h;
+ uint32_t its = 0;
+ double rh, alpha, beta;
+ double b_square = ddot(N, b, b);
+ double err = eps * eps*b_square;
+ double curr_err;
+ nlMultMatrixVector(M, x, r);
+ daxpy(N, -1., b, r);
+ nlMultMatrixVector(P, r, d);
+ memcpy(h, d, N * sizeof(double));
+ rh = ddot(N, r, h);
+ curr_err = ddot(N, r, r);
+ while (curr_err > err && its < max_iter) {
+ nlMultMatrixVector(M, d, Ad);
+ alpha = rh / ddot(N, d, Ad);
+ daxpy(N, -alpha, d, x);
+ daxpy(N, -alpha, Ad, r);
+ nlMultMatrixVector(P, r, h);
+ beta = 1. / rh;
+ rh = ddot(N, r, h);
+ beta *= rh;
+ dscal(N, beta, d);
+ daxpy(N, 1., h, d);
+ ++its;
+ curr_err = ddot(N, r, r);
+ }
+ NL_DELETE_VECTOR(r);
+ NL_DELETE_VECTOR(d);
+ NL_DELETE_VECTOR(h);
+ *sq_bnorm = b_square;
+ *sq_rnorm = curr_err;
+ return its;
+}
+
+static uint32_t nlSolveSystemIterative(NLContext *context, NLMatrix M, NLMatrix P, double* b_in, double* x_in, double eps, uint32_t max_iter)
+{
+ uint32_t result = 0;
+ double rnorm = 0.0;
+ double bnorm = 0.0;
+ double* b = b_in;
+ double* x = x_in;
+ XA_DEBUG_ASSERT(M->m == M->n);
+ double sq_bnorm, sq_rnorm;
+ result = nlSolveSystem_PRE_CG(M, P, b, x, eps, max_iter, &sq_bnorm, &sq_rnorm);
+ /* Get residual norm and rhs norm */
+ bnorm = sqrt(sq_bnorm);
+ rnorm = sqrt(sq_rnorm);
+ if (bnorm == 0.0)
+ context->error = rnorm;
+ else
+ context->error = rnorm / bnorm;
+ context->used_iterations = result;
+ return result;
+}
+
+static bool nlSolveIterative(NLContext *context)
+{
+ double* b = context->b;
+ double* x = context->x;
+ uint32_t n = context->n;
+ NLMatrix M = context->M;
+ NLMatrix P = context->P;
+ for (uint32_t k = 0; k < context->nb_systems; ++k) {
+ nlSolveSystemIterative(context, M, P, b, x, context->threshold, context->max_iterations);
+ b += n;
+ x += n;
+ }
+ return true;
+}
+
+struct NLJacobiPreconditioner
+{
+ uint32_t m;
+ uint32_t n;
+ uint32_t type;
+ NLDestroyMatrixFunc destroy_func;
+ NLMultMatrixVectorFunc mult_func;
+ double* diag_inv;
+};
+
+static void nlJacobiPreconditionerDestroy(NLJacobiPreconditioner* M)
+{
+ NL_DELETE_ARRAY(M->diag_inv);
+}
+
+static void nlJacobiPreconditionerMult(NLJacobiPreconditioner* M, const double* x, double* y)
+{
+ for (uint32_t i = 0; i < M->n; ++i)
+ y[i] = x[i] * M->diag_inv[i];
+}
+
+static NLMatrix nlNewJacobiPreconditioner(NLMatrix M_in)
+{
+ NLSparseMatrix* M = nullptr;
+ NLJacobiPreconditioner* result = nullptr;
+ XA_DEBUG_ASSERT(M_in->type == NL_MATRIX_SPARSE_DYNAMIC);
+ XA_DEBUG_ASSERT(M_in->m == M_in->n);
+ M = (NLSparseMatrix*)M_in;
+ result = NL_NEW(NLJacobiPreconditioner);
+ NL_CLEAR(result, NLJacobiPreconditioner);
+ result->m = M->m;
+ result->n = M->n;
+ result->type = NL_MATRIX_OTHER;
+ result->destroy_func = (NLDestroyMatrixFunc)nlJacobiPreconditionerDestroy;
+ result->mult_func = (NLMultMatrixVectorFunc)nlJacobiPreconditionerMult;
+ result->diag_inv = NL_NEW_ARRAY(double, M->n);
+ NL_CLEAR_ARRAY(double, result->diag_inv, M->n);
+ for (uint32_t i = 0; i < M->n; ++i)
+ result->diag_inv[i] = (M->diag[i] == 0.0) ? 1.0 : 1.0 / M->diag[i];
+ return (NLMatrix)result;
+}
+
+#define NL_NB_VARIABLES 0x101
+#define NL_MAX_ITERATIONS 0x103
+
+static void nlSolverParameteri(NLContext *context, uint32_t pname, int param)
+{
+ if (pname == NL_NB_VARIABLES) {
+ XA_DEBUG_ASSERT(param > 0);
+ context->nb_variables = (uint32_t)param;
+ } else if (pname == NL_MAX_ITERATIONS) {
+ XA_DEBUG_ASSERT(param > 0);
+ context->max_iterations = (uint32_t)param;
+ context->max_iterations_defined = true;
+ }
+}
+
+static void nlSetVariable(NLContext *context, uint32_t index, double value)
+{
+ XA_DEBUG_ASSERT(index >= 0 && index <= context->nb_variables - 1);
+ NL_BUFFER_ITEM(context->variable_buffer[0], index) = value;
+}
+
+static double nlGetVariable(NLContext *context, uint32_t index)
+{
+ XA_DEBUG_ASSERT(index >= 0 && index <= context->nb_variables - 1);
+ return NL_BUFFER_ITEM(context->variable_buffer[0], index);
+}
+
+static void nlLockVariable(NLContext *context, uint32_t index)
+{
+ XA_DEBUG_ASSERT(index >= 0 && index <= context->nb_variables - 1);
+ context->variable_is_locked[index] = true;
+}
+
+static void nlVariablesToVector(NLContext *context)
+{
+ uint32_t n = context->n;
+ XA_DEBUG_ASSERT(context->x);
+ for (uint32_t k = 0; k < context->nb_systems; ++k) {
+ for (uint32_t i = 0; i < context->nb_variables; ++i) {
+ if (!context->variable_is_locked[i]) {
+ uint32_t index = context->variable_index[i];
+ XA_DEBUG_ASSERT(index < context->n);
+ double value = NL_BUFFER_ITEM(context->variable_buffer[k], i);
+ context->x[index + k * n] = value;
+ }
+ }
+ }
+}
+
+static void nlVectorToVariables(NLContext *context)
+{
+ uint32_t n = context->n;
+ XA_DEBUG_ASSERT(context->x);
+ for (uint32_t k = 0; k < context->nb_systems; ++k) {
+ for (uint32_t i = 0; i < context->nb_variables; ++i) {
+ if (!context->variable_is_locked[i]) {
+ uint32_t index = context->variable_index[i];
+ XA_DEBUG_ASSERT(index < context->n);
+ double value = context->x[index + k * n];
+ NL_BUFFER_ITEM(context->variable_buffer[k], i) = value;
+ }
+ }
+ }
+}
+
+static void nlCoefficient(NLContext *context, uint32_t index, double value)
+{
+ XA_DEBUG_ASSERT(index >= 0 && index <= context->nb_variables - 1);
+ if (context->variable_is_locked[index]) {
+ /*
+ * Note: in al, indices are NLvariable indices,
+ * within [0..nb_variables-1]
+ */
+ nlRowColumnAppend(&(context->al), index, value);
+ } else {
+ /*
+ * Note: in af, indices are system indices,
+ * within [0..n-1]
+ */
+ nlRowColumnAppend(&(context->af), context->variable_index[index], value);
+ }
+}
+
+#define NL_SYSTEM 0x0
+#define NL_MATRIX 0x1
+#define NL_ROW 0x2
+
+static void nlBegin(NLContext *context, uint32_t prim)
+{
+ if (prim == NL_SYSTEM) {
+ XA_DEBUG_ASSERT(context->nb_variables > 0);
+ context->variable_buffer = NL_NEW_ARRAY(NLBufferBinding, context->nb_systems);
+ NL_CLEAR_ARRAY(NLBufferBinding, context->variable_buffer, context->nb_systems);
+ context->variable_value = NL_NEW_ARRAY(double, context->nb_variables * context->nb_systems);
+ NL_CLEAR_ARRAY(double, context->variable_value, context->nb_variables * context->nb_systems);
+ for (uint32_t k = 0; k < context->nb_systems; ++k) {
+ context->variable_buffer[k].base_address =
+ context->variable_value +
+ k * context->nb_variables;
+ context->variable_buffer[k].stride = sizeof(double);
+ }
+ context->variable_is_locked = NL_NEW_ARRAY(bool, context->nb_variables);
+ NL_CLEAR_ARRAY(bool, context->variable_is_locked, context->nb_variables);
+ context->variable_index = NL_NEW_ARRAY(uint32_t, context->nb_variables);
+ NL_CLEAR_ARRAY(uint32_t, context->variable_index, context->nb_variables);
+ } else if (prim == NL_MATRIX) {
+ if (context->M)
+ return;
+ uint32_t n = 0;
+ for (uint32_t i = 0; i < context->nb_variables; i++) {
+ if (!context->variable_is_locked[i]) {
+ context->variable_index[i] = n;
+ n++;
+ } else
+ context->variable_index[i] = (uint32_t)~0;
+ }
+ context->n = n;
+ if (!context->max_iterations_defined)
+ context->max_iterations = n * 5;
+ context->M = (NLMatrix)(NL_NEW(NLSparseMatrix));
+ NL_CLEAR(context->M, NLSparseMatrix);
+ nlSparseMatrixConstruct((NLSparseMatrix*)(context->M), n, n);
+ context->x = NL_NEW_ARRAY(double, n*context->nb_systems);
+ NL_CLEAR_ARRAY(double, context->x, n*context->nb_systems);
+ context->b = NL_NEW_ARRAY(double, n*context->nb_systems);
+ NL_CLEAR_ARRAY(double, context->b, n*context->nb_systems);
+ nlVariablesToVector(context);
+ nlRowColumnConstruct(&context->af);
+ nlRowColumnConstruct(&context->al);
+ context->current_row = 0;
+ } else if (prim == NL_ROW) {
+ nlRowColumnZero(&context->af);
+ nlRowColumnZero(&context->al);
+ }
+}
+
+static void nlEnd(NLContext *context, uint32_t prim)
+{
+ if (prim == NL_MATRIX) {
+ nlRowColumnClear(&context->af);
+ nlRowColumnClear(&context->al);
+ } else if (prim == NL_ROW) {
+ NLRowColumn* af = &context->af;
+ NLRowColumn* al = &context->al;
+ NLSparseMatrix* M = (NLSparseMatrix*)context->M;
+ double* b = context->b;
+ uint32_t nf = af->size;
+ uint32_t nl = al->size;
+ uint32_t n = context->n;
+ double S;
+ /*
+ * least_squares : we want to solve
+ * A'A x = A'b
+ */
+ for (uint32_t i = 0; i < nf; i++) {
+ for (uint32_t j = 0; j < nf; j++) {
+ nlSparseMatrixAdd(M, af->coeff[i].index, af->coeff[j].index, af->coeff[i].value * af->coeff[j].value);
+ }
+ }
+ for (uint32_t k = 0; k < context->nb_systems; ++k) {
+ S = 0.0;
+ for (uint32_t jj = 0; jj < nl; ++jj) {
+ uint32_t j = al->coeff[jj].index;
+ S += al->coeff[jj].value * NL_BUFFER_ITEM(context->variable_buffer[k], j);
+ }
+ for (uint32_t jj = 0; jj < nf; jj++)
+ b[k*n + af->coeff[jj].index] -= af->coeff[jj].value * S;
+ }
+ context->current_row++;
+ }
+}
+
+static bool nlSolve(NLContext *context)
+{
+ nlDeleteMatrix(context->P);
+ context->P = nlNewJacobiPreconditioner(context->M);
+ nlMatrixCompress(&context->M);
+ bool result = nlSolveIterative(context);
+ nlVectorToVariables(context);
+ return result;
+}
+} // namespace opennl
+
namespace raster {
class ClippedTriangle
{
@@ -4314,6 +5191,7 @@ public:
m_verticesA[2] = c;
m_vertexBuffers[0] = m_verticesA;
m_vertexBuffers[1] = m_verticesB;
+ m_area = 0;
}
void clipHorizontalPlane(float offset, float clipdirection)
@@ -4409,12 +5287,8 @@ typedef bool (*SamplingCallback)(void *param, int x, int y);
/// A triangle for rasterization.
struct Triangle
{
- Triangle(const Vector2 &v0, const Vector2 &v1, const Vector2 &v2)
+ Triangle(const Vector2 &_v0, const Vector2 &_v1, const Vector2 &_v2) : v1(_v0), v2(_v2), v3(_v1)
{
- // Init vertices.
- this->v1 = v0;
- this->v2 = v2;
- this->v3 = v1;
// make sure every triangle is front facing.
flipBackface();
// Compute deltas.
@@ -4554,252 +5428,6 @@ static bool drawTriangle(const Vector2 &extents, const Vector2 v[3], SamplingCal
} // namespace raster
-// Full and sparse vector and matrix classes. BLAS subset.
-// Pseudo-BLAS interface.
-namespace sparse {
-
-/**
-* Sparse matrix class. The matrix is assumed to be sparse and to have
-* very few non-zero elements, for this reason it's stored in indexed
-* format. To multiply column vectors efficiently, the matrix stores
-* the elements in indexed-column order, there is a list of indexed
-* elements for each row of the matrix. As with the FullVector the
-* dimension of the matrix is constant.
-**/
-class Matrix
-{
-public:
- // An element of the sparse array.
- struct Coefficient
- {
- uint32_t x; // column
- float v; // value
- };
-
- Matrix(uint32_t d) : m_width(d), m_array(MemTag::Matrix)
- {
- m_array.resize(d);
- m_array.runCtors();
-#if XA_DEBUG_HEAP
- for (uint32_t i = 0; i < d; i++)
- m_array[i].setMemTag(MemTag::Matrix);
-#endif
- }
-
- Matrix(uint32_t w, uint32_t h) : m_width(w), m_array(MemTag::Matrix)
- {
- m_array.resize(h);
- m_array.runCtors();
-#if XA_DEBUG_HEAP
- for (uint32_t i = 0; i < h; i++)
- m_array[i].setMemTag(MemTag::Matrix);
-#endif
- }
-
- ~Matrix()
- {
- m_array.runDtors();
- }
-
- Matrix(const Matrix &m) = delete;
- Matrix &operator=(const Matrix &m) = delete;
- uint32_t width() const { return m_width; }
- uint32_t height() const { return m_array.size(); }
- bool isSquare() const { return width() == height(); }
-
- // x is column, y is row
- float getCoefficient(uint32_t x, uint32_t y) const
- {
- XA_DEBUG_ASSERT( x < width() );
- XA_DEBUG_ASSERT( y < height() );
- const uint32_t count = m_array[y].size();
- for (uint32_t i = 0; i < count; i++) {
- if (m_array[y][i].x == x) return m_array[y][i].v;
- }
- return 0.0f;
- }
-
- void setCoefficient(uint32_t x, uint32_t y, float f)
- {
- XA_DEBUG_ASSERT( x < width() );
- XA_DEBUG_ASSERT( y < height() );
- const uint32_t count = m_array[y].size();
- for (uint32_t i = 0; i < count; i++) {
- if (m_array[y][i].x == x) {
- m_array[y][i].v = f;
- return;
- }
- }
- if (f != 0.0f) {
- Coefficient c = { x, f };
- m_array[y].push_back( c );
- }
- }
-
- float dotRow(uint32_t y, const FullVector &v) const
- {
- XA_DEBUG_ASSERT( y < height() );
- const uint32_t count = m_array[y].size();
- float sum = 0;
- for (uint32_t i = 0; i < count; i++) {
- sum += m_array[y][i].v * v[m_array[y][i].x];
- }
- return sum;
- }
-
- void madRow(uint32_t y, float alpha, FullVector &v) const
- {
- XA_DEBUG_ASSERT(y < height());
- const uint32_t count = m_array[y].size();
- for (uint32_t i = 0; i < count; i++) {
- v[m_array[y][i].x] += alpha * m_array[y][i].v;
- }
- }
-
- void clearRow(uint32_t y)
- {
- XA_DEBUG_ASSERT( y < height() );
- m_array[y].clear();
- }
-
- const Array<Coefficient> &getRow(uint32_t y) const { return m_array[y]; }
-
-private:
- /// Number of columns.
- const uint32_t m_width;
-
- /// Array of matrix elements.
- Array< Array<Coefficient> > m_array;
-};
-
-// y = a * x + y
-static void saxpy(float a, const FullVector &x, FullVector &y)
-{
- XA_DEBUG_ASSERT(x.dimension() == y.dimension());
- const uint32_t dim = x.dimension();
- for (uint32_t i = 0; i < dim; i++) {
- y[i] += a * x[i];
- }
-}
-
-static void copy(const FullVector &x, FullVector &y)
-{
- XA_DEBUG_ASSERT(x.dimension() == y.dimension());
- const uint32_t dim = x.dimension();
- for (uint32_t i = 0; i < dim; i++) {
- y[i] = x[i];
- }
-}
-
-static void scal(float a, FullVector &x)
-{
- const uint32_t dim = x.dimension();
- for (uint32_t i = 0; i < dim; i++) {
- x[i] *= a;
- }
-}
-
-static float dot(const FullVector &x, const FullVector &y)
-{
- XA_DEBUG_ASSERT(x.dimension() == y.dimension());
- const uint32_t dim = x.dimension();
- float sum = 0;
- for (uint32_t i = 0; i < dim; i++) {
- sum += x[i] * y[i];
- }
- return sum;
-}
-
-// y = M * x
-static void mult(const Matrix &M, const FullVector &x, FullVector &y)
-{
- uint32_t w = M.width();
- uint32_t h = M.height();
- XA_DEBUG_ASSERT( w == x.dimension() );
- XA_UNUSED(w);
- XA_DEBUG_ASSERT( h == y.dimension() );
- for (uint32_t i = 0; i < h; i++)
- y[i] = M.dotRow(i, x);
-}
-
-// y = alpha*A*x + beta*y
-static void sgemv(float alpha, const Matrix &A, const FullVector &x, float beta, FullVector &y)
-{
- const uint32_t w = A.width();
- const uint32_t h = A.height();
- XA_DEBUG_ASSERT( w == x.dimension() );
- XA_DEBUG_ASSERT( h == y.dimension() );
- XA_UNUSED(w);
- XA_UNUSED(h);
- for (uint32_t i = 0; i < h; i++)
- y[i] = alpha * A.dotRow(i, x) + beta * y[i];
-}
-
-// dot y-row of A by x-column of B
-static float dotRowColumn(int y, const Matrix &A, int x, const Matrix &B)
-{
- const Array<Matrix::Coefficient> &row = A.getRow(y);
- const uint32_t count = row.size();
- float sum = 0.0f;
- for (uint32_t i = 0; i < count; i++) {
- const Matrix::Coefficient &c = row[i];
- sum += c.v * B.getCoefficient(x, c.x);
- }
- return sum;
-}
-
-static void transpose(const Matrix &A, Matrix &B)
-{
- XA_DEBUG_ASSERT(A.width() == B.height());
- XA_DEBUG_ASSERT(B.width() == A.height());
- const uint32_t w = A.width();
- for (uint32_t x = 0; x < w; x++) {
- B.clearRow(x);
- }
- const uint32_t h = A.height();
- for (uint32_t y = 0; y < h; y++) {
- const Array<Matrix::Coefficient> &row = A.getRow(y);
- const uint32_t count = row.size();
- for (uint32_t i = 0; i < count; i++) {
- const Matrix::Coefficient &c = row[i];
- XA_DEBUG_ASSERT(c.x < w);
- B.setCoefficient(y, c.x, c.v);
- }
- }
-}
-
-static void sgemm(float alpha, const Matrix &A, const Matrix &B, float beta, Matrix &C)
-{
- const uint32_t w = C.width();
- const uint32_t h = C.height();
-#if XA_DEBUG
- const uint32_t aw = A.width();
- const uint32_t ah = A.height();
- const uint32_t bw = B.width();
- const uint32_t bh = B.height();
- XA_DEBUG_ASSERT(aw == bh);
- XA_DEBUG_ASSERT(bw == ah);
- XA_DEBUG_ASSERT(w == bw);
- XA_DEBUG_ASSERT(h == ah);
-#endif
- for (uint32_t y = 0; y < h; y++) {
- for (uint32_t x = 0; x < w; x++) {
- float c = beta * C.getCoefficient(x, y);
- // dot y-row of A by x-column of B.
- c += alpha * dotRowColumn(y, A, x, B);
- C.setCoefficient(x, y, c);
- }
- }
-}
-
-// C = A * B
-static void mult(const Matrix &A, const Matrix &B, Matrix &C)
-{
- sgemm(1.0f, A, B, 0.0f, C);
-}
-
-} // namespace sparse
-
namespace segment {
// - Insertion is o(n)
@@ -4866,88 +5494,92 @@ private:
Array<Pair> m_pairs;
};
-struct Chart
+struct AtlasData
{
- Chart() : faces(MemTag::SegmentAtlasChartFaces) {}
+ ChartOptions options;
+ const Mesh *mesh = nullptr;
+ Array<float> edgeDihedralAngles;
+ Array<float> edgeLengths;
+ Array<float> faceAreas;
+ Array<Vector3> faceNormals;
+ BitArray isFaceInChart;
- int id = -1;
- Basis basis; // Best fit normal.
- float area = 0.0f;
- float boundaryLength = 0.0f;
- Vector3 centroidSum = Vector3(0.0f); // Sum of chart face centroids.
- Vector3 centroid = Vector3(0.0f); // Average centroid of chart faces.
- Array<uint32_t> seeds;
- Array<uint32_t> faces;
- Array<uint32_t> failedPlanarRegions;
- CostQueue candidates;
-};
+ AtlasData() : edgeDihedralAngles(MemTag::SegmentAtlasMeshData), edgeLengths(MemTag::SegmentAtlasMeshData), faceAreas(MemTag::SegmentAtlasMeshData), faceNormals(MemTag::SegmentAtlasMeshData) {}
-struct Atlas
-{
- Atlas() : m_edgeLengths(MemTag::SegmentAtlasMeshData), m_faceAreas(MemTag::SegmentAtlasMeshData), m_faceNormals(MemTag::SegmentAtlasMeshData), m_texcoords(MemTag::SegmentAtlasMeshData), m_bestTriangles(10), m_nextPlanarRegionFace(MemTag::SegmentAtlasPlanarRegions), m_facePlanarRegionId(MemTag::SegmentAtlasPlanarRegions) {}
-
- ~Atlas()
+ void compute()
{
- const uint32_t chartCount = m_charts.size();
- for (uint32_t i = 0; i < chartCount; i++) {
- m_charts[i]->~Chart();
- XA_FREE(m_charts[i]);
+ const uint32_t faceCount = mesh->faceCount();
+ const uint32_t edgeCount = mesh->edgeCount();
+ edgeDihedralAngles.resize(edgeCount);
+ edgeLengths.resize(edgeCount);
+ faceAreas.resize(faceCount);
+ faceNormals.resize(faceCount);
+ isFaceInChart.resize(faceCount);
+ isFaceInChart.zeroOutMemory();
+ for (uint32_t f = 0; f < faceCount; f++) {
+ for (uint32_t i = 0; i < 3; i++) {
+ const uint32_t edge = f * 3 + i;
+ const Vector3 &p0 = mesh->position(mesh->vertexAt(meshEdgeIndex0(edge)));
+ const Vector3 &p1 = mesh->position(mesh->vertexAt(meshEdgeIndex1(edge)));
+ edgeLengths[edge] = length(p1 - p0);
+ XA_DEBUG_ASSERT(edgeLengths[edge] > 0.0f);
+ }
+ faceAreas[f] = mesh->computeFaceArea(f);
+ XA_DEBUG_ASSERT(faceAreas[f] > 0.0f);
+ faceNormals[f] = mesh->computeFaceNormal(f);
+ }
+ for (uint32_t face = 0; face < faceCount; face++) {
+ for (uint32_t i = 0; i < 3; i++) {
+ const uint32_t edge = face * 3 + i;
+ const uint32_t oedge = mesh->oppositeEdge(edge);
+ if (oedge == UINT32_MAX)
+ edgeDihedralAngles[edge] = FLT_MAX;
+ else {
+ const uint32_t oface = meshEdgeFace(oedge);
+ edgeDihedralAngles[edge] = edgeDihedralAngles[oedge] = dot(faceNormals[face], faceNormals[oface]);
+ }
+ }
}
}
+};
+
+#if XA_DEBUG_EXPORT_OBJ_PLANAR_REGIONS
+static uint32_t s_planarRegionsCurrentRegion;
+static uint32_t s_planarRegionsCurrentVertex;
+#endif
- uint32_t facesLeft() const { return m_facesLeft; }
+struct PlanarCharts
+{
+ PlanarCharts(AtlasData &data) : m_data(data), m_nextRegionFace(MemTag::SegmentAtlasPlanarRegions), m_faceToRegionId(MemTag::SegmentAtlasPlanarRegions) {}
+ const Basis &chartBasis(uint32_t chartIndex) const { return m_chartBasis[chartIndex]; }
uint32_t chartCount() const { return m_charts.size(); }
- const Array<uint32_t> &chartFaces(uint32_t i) const { return m_charts[i]->faces; }
- const Basis &chartBasis(uint32_t chartIndex) const { return m_charts[chartIndex]->basis; }
+
+ ConstArrayView<uint32_t> chartFaces(uint32_t chartIndex) const
+ {
+ const Chart &chart = m_charts[chartIndex];
+ return ConstArrayView<uint32_t>(&m_chartFaces[chart.firstFace], chart.faceCount);
+ }
+
+ uint32_t regionIdFromFace(uint32_t face) const { return m_faceToRegionId[face]; }
+ uint32_t nextRegionFace(uint32_t face) const { return m_nextRegionFace[face]; }
+ float regionArea(uint32_t region) const { return m_regionAreas[region]; }
- void reset(uint32_t meshId, uint32_t chartGroupId, const Mesh *mesh, const ChartOptions &options)
+ void compute()
{
- XA_UNUSED(meshId);
- XA_UNUSED(chartGroupId);
- XA_PROFILE_START(buildAtlasInit)
- m_mesh = mesh;
- const uint32_t faceCount = m_mesh->faceCount();
- m_facesLeft = faceCount;
- m_options = options;
- m_rand.reset();
- const uint32_t chartCount = m_charts.size();
- for (uint32_t i = 0; i < chartCount; i++) {
- m_charts[i]->~Chart();
- XA_FREE(m_charts[i]);
- }
- m_charts.clear();
- m_faceCharts.resize(faceCount);
- m_faceCharts.setAll(-1);
- m_texcoords.resize(faceCount * 3);
- // Precompute edge lengths and face areas.
- const uint32_t edgeCount = m_mesh->edgeCount();
- m_edgeLengths.resize(edgeCount);
- m_faceAreas.resize(faceCount);
- m_faceNormals.resize(faceCount);
- for (uint32_t f = 0; f < faceCount; f++) {
- for (uint32_t i = 0; i < 3; i++) {
- const uint32_t edge = f * 3 + i;
- const Vector3 &p0 = mesh->position(m_mesh->vertexAt(meshEdgeIndex0(edge)));
- const Vector3 &p1 = mesh->position(m_mesh->vertexAt(meshEdgeIndex1(edge)));
- m_edgeLengths[edge] = length(p1 - p0);
- XA_DEBUG_ASSERT(m_edgeLengths[edge] > 0.0f);
- }
- m_faceAreas[f] = m_mesh->computeFaceArea(f);
- XA_DEBUG_ASSERT(m_faceAreas[f] > 0.0f);
- m_faceNormals[f] = m_mesh->computeFaceNormal(f);
- }
+ const uint32_t faceCount = m_data.mesh->faceCount();
// Precompute regions of coplanar incident faces.
- m_nextPlanarRegionFace.resize(faceCount);
- m_facePlanarRegionId.resize(faceCount);
+ m_regionFirstFace.clear();
+ m_nextRegionFace.resize(faceCount);
+ m_faceToRegionId.resize(faceCount);
for (uint32_t f = 0; f < faceCount; f++) {
- m_nextPlanarRegionFace[f] = f;
- m_facePlanarRegionId[f] = UINT32_MAX;
+ m_nextRegionFace[f] = f;
+ m_faceToRegionId[f] = UINT32_MAX;
}
Array<uint32_t> faceStack;
faceStack.reserve(min(faceCount, 16u));
- uint32_t planarRegionCount = 0;
+ uint32_t regionCount = 0;
for (uint32_t f = 0; f < faceCount; f++) {
- if (m_nextPlanarRegionFace[f] != f)
+ if (m_nextRegionFace[f] != f)
continue; // Already assigned.
faceStack.clear();
faceStack.push_back(f);
@@ -4955,49 +5587,207 @@ struct Atlas
if (faceStack.isEmpty())
break;
const uint32_t face = faceStack.back();
- m_facePlanarRegionId[face] = planarRegionCount;
+ m_faceToRegionId[face] = regionCount;
faceStack.pop_back();
- for (Mesh::FaceEdgeIterator it(m_mesh, face); !it.isDone(); it.advance()) {
+ for (Mesh::FaceEdgeIterator it(m_data.mesh, face); !it.isDone(); it.advance()) {
const uint32_t oface = it.oppositeFace();
if (it.isBoundary())
continue;
- if (m_nextPlanarRegionFace[oface] != oface)
+ if (m_nextRegionFace[oface] != oface)
continue; // Already assigned.
- if (!equal(dot(m_faceNormals[face], m_faceNormals[oface]), 1.0f, kEpsilon))
+ if (!equal(dot(m_data.faceNormals[face], m_data.faceNormals[oface]), 1.0f, kEpsilon))
continue; // Not coplanar.
- const uint32_t next = m_nextPlanarRegionFace[face];
- m_nextPlanarRegionFace[face] = oface;
- m_nextPlanarRegionFace[oface] = next;
- m_facePlanarRegionId[oface] = planarRegionCount;
+ const uint32_t next = m_nextRegionFace[face];
+ m_nextRegionFace[face] = oface;
+ m_nextRegionFace[oface] = next;
+ m_faceToRegionId[oface] = regionCount;
faceStack.push_back(oface);
}
}
- planarRegionCount++;
+ m_regionFirstFace.push_back(f);
+ regionCount++;
}
#if XA_DEBUG_EXPORT_OBJ_PLANAR_REGIONS
- char filename[256];
- XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_planar_regions.obj", meshId, chartGroupId);
- FILE *file;
- XA_FOPEN(file, filename, "w");
- if (file) {
- m_mesh->writeObjVertices(file);
- fprintf(file, "s off\n");
- for (uint32_t i = 0; i < planarRegionCount; i++) {
- fprintf(file, "o region%u\n", i);
- for (uint32_t j = 0; j < faceCount; j++) {
- if (m_facePlanarRegionId[j] == i)
- m_mesh->writeObjFace(file, j);
+ static std::mutex s_mutex;
+ {
+ std::lock_guard<std::mutex> lock(s_mutex);
+ FILE *file;
+ XA_FOPEN(file, "debug_mesh_planar_regions.obj", s_planarRegionsCurrentRegion == 0 ? "w" : "a");
+ if (file) {
+ m_data.mesh->writeObjVertices(file);
+ fprintf(file, "s off\n");
+ for (uint32_t i = 0; i < regionCount; i++) {
+ fprintf(file, "o region%u\n", s_planarRegionsCurrentRegion);
+ for (uint32_t j = 0; j < faceCount; j++) {
+ if (m_faceToRegionId[j] == i)
+ m_data.mesh->writeObjFace(file, j, s_planarRegionsCurrentVertex);
+ }
+ s_planarRegionsCurrentRegion++;
}
+ s_planarRegionsCurrentVertex += m_data.mesh->vertexCount();
+ fclose(file);
}
- fclose(file);
}
#endif
- XA_PROFILE_END(buildAtlasInit)
+ // Precompute planar region areas.
+ m_regionAreas.resize(regionCount);
+ m_regionAreas.zeroOutMemory();
+ for (uint32_t f = 0; f < faceCount; f++)
+ m_regionAreas[m_faceToRegionId[f]] += m_data.faceAreas[f];
+ // Create charts from suitable planar regions.
+ // The dihedral angle of all boundary edges must be >= 90 degrees.
+ m_charts.clear();
+ m_chartFaces.clear();
+ for (uint32_t region = 0; region < regionCount; region++) {
+ const uint32_t firstRegionFace = m_regionFirstFace[region];
+ uint32_t face = firstRegionFace;
+ bool createChart = true;
+ do {
+ for (Mesh::FaceEdgeIterator it(m_data.mesh, face); !it.isDone(); it.advance()) {
+ if (it.isBoundary())
+ continue; // Ignore mesh boundary edges.
+ const uint32_t oface = it.oppositeFace();
+ if (m_faceToRegionId[oface] == region)
+ continue; // Ignore internal edges.
+ const float angle = m_data.edgeDihedralAngles[it.edge()];
+ if (angle > 0.0f && angle < FLT_MAX) { // FLT_MAX on boundaries.
+ createChart = false;
+ break;
+ }
+ }
+ if (!createChart)
+ break;
+ face = m_nextRegionFace[face];
+ }
+ while (face != firstRegionFace);
+ // Create a chart.
+ if (createChart) {
+ Chart chart;
+ chart.firstFace = m_chartFaces.size();
+ chart.faceCount = 0;
+ face = firstRegionFace;
+ do {
+ m_data.isFaceInChart.set(face);
+ m_chartFaces.push_back(face);
+ chart.faceCount++;
+ face = m_nextRegionFace[face];
+ }
+ while (face != firstRegionFace);
+ m_charts.push_back(chart);
+ }
+ }
+ // Compute basis for each chart using the first face normal (all faces have the same normal).
+ m_chartBasis.resize(m_charts.size());
+ for (uint32_t c = 0; c < m_charts.size(); c++)
+ {
+ const uint32_t face = m_chartFaces[m_charts[c].firstFace];
+ Basis &basis = m_chartBasis[c];
+ basis.normal = m_data.faceNormals[face];
+ basis.tangent = Basis::computeTangent(basis.normal);
+ basis.bitangent = Basis::computeBitangent(basis.normal, basis.tangent);
+ }
+ }
+
+private:
+ struct Chart
+ {
+ uint32_t firstFace, faceCount;
+ };
+
+ AtlasData &m_data;
+ Array<uint32_t> m_regionFirstFace;
+ Array<uint32_t> m_nextRegionFace;
+ Array<uint32_t> m_faceToRegionId;
+ Array<float> m_regionAreas;
+ Array<Chart> m_charts;
+ Array<uint32_t> m_chartFaces;
+ Array<Basis> m_chartBasis;
+};
+
+struct ClusteredCharts
+{
+ ClusteredCharts(AtlasData &data, const PlanarCharts &planarCharts) : m_data(data), m_planarCharts(planarCharts), m_texcoords(MemTag::SegmentAtlasMeshData), m_bestTriangles(10), m_placingSeeds(false) {}
+
+ ~ClusteredCharts()
+ {
+ const uint32_t chartCount = m_charts.size();
+ for (uint32_t i = 0; i < chartCount; i++) {
+ m_charts[i]->~Chart();
+ XA_FREE(m_charts[i]);
+ }
+ }
+
+ uint32_t chartCount() const { return m_charts.size(); }
+ ConstArrayView<uint32_t> chartFaces(uint32_t chartIndex) const { return m_charts[chartIndex]->faces; }
+ const Basis &chartBasis(uint32_t chartIndex) const { return m_charts[chartIndex]->basis; }
+
+ void compute()
+ {
+ const uint32_t faceCount = m_data.mesh->faceCount();
+ m_facesLeft = 0;
+ for (uint32_t i = 0; i < faceCount; i++) {
+ if (!m_data.isFaceInChart.get(i))
+ m_facesLeft++;
+ }
+ const uint32_t chartCount = m_charts.size();
+ for (uint32_t i = 0; i < chartCount; i++) {
+ m_charts[i]->~Chart();
+ XA_FREE(m_charts[i]);
+ }
+ m_charts.clear();
+ m_faceCharts.resize(faceCount);
+ m_faceCharts.fill(-1);
+ m_texcoords.resize(faceCount * 3);
+ if (m_facesLeft == 0)
+ return;
+ // Create initial charts greedely.
+ placeSeeds(m_data.options.maxCost * 0.5f);
+ if (m_data.options.maxIterations == 0) {
+ XA_DEBUG_ASSERT(m_facesLeft == 0);
+ return;
+ }
+ relocateSeeds();
+ resetCharts();
+ // Restart process growing charts in parallel.
+ uint32_t iteration = 0;
+ for (;;) {
+ growCharts(m_data.options.maxCost);
+ // When charts cannot grow more: fill holes, merge charts, relocate seeds and start new iteration.
+ fillHoles(m_data.options.maxCost * 0.5f);
+#if XA_MERGE_CHARTS
+ mergeCharts();
+#endif
+ if (++iteration == m_data.options.maxIterations)
+ break;
+ if (!relocateSeeds())
+ break;
+ resetCharts();
+ }
+ // Make sure no holes are left!
+ XA_DEBUG_ASSERT(m_facesLeft == 0);
}
+private:
+ struct Chart
+ {
+ Chart() : faces(MemTag::SegmentAtlasChartFaces) {}
+
+ int id = -1;
+ Basis basis; // Best fit normal.
+ float area = 0.0f;
+ float boundaryLength = 0.0f;
+ Vector3 centroidSum = Vector3(0.0f); // Sum of chart face centroids.
+ Vector3 centroid = Vector3(0.0f); // Average centroid of chart faces.
+ Array<uint32_t> faces;
+ Array<uint32_t> failedPlanarRegions;
+ CostQueue candidates;
+ uint32_t seed;
+ };
+
void placeSeeds(float threshold)
{
- XA_PROFILE_START(buildAtlasPlaceSeeds)
+ XA_PROFILE_START(clusteredChartsPlaceSeeds)
+ m_placingSeeds = true;
// Instead of using a predefiened number of seeds:
// - Add seeds one by one, growing chart until a certain treshold.
// - Undo charts and restart growing process.
@@ -5005,14 +5795,15 @@ struct Atlas
// - those points can be found using a simple flood filling algorithm.
// - how do we weight the probabilities?
while (m_facesLeft > 0)
- createRandomChart(threshold);
- XA_PROFILE_END(buildAtlasPlaceSeeds)
+ createChart(threshold);
+ m_placingSeeds = false;
+ XA_PROFILE_END(clusteredChartsPlaceSeeds)
}
// Returns true if any of the charts can grow more.
void growCharts(float threshold)
{
- XA_PROFILE_START(buildAtlasGrowCharts)
+ XA_PROFILE_START(clusteredChartsGrow)
for (;;) {
if (m_facesLeft == 0)
break;
@@ -5030,7 +5821,7 @@ struct Atlas
break;
cost = chart->candidates.peekCost();
face = chart->candidates.peekFace();
- if (m_faceCharts[face] == -1)
+ if (!m_data.isFaceInChart.get(face))
break;
else {
// Face belongs to another chart. Pop from queue so the next best candidate can be retrieved.
@@ -5052,22 +5843,28 @@ struct Atlas
Chart *chart = m_charts[bestChart];
chart->candidates.pop(); // Pop the selected candidate from the queue.
if (!addFaceToChart(chart, bestFace))
- chart->failedPlanarRegions.push_back(m_facePlanarRegionId[bestFace]);
+ chart->failedPlanarRegions.push_back(m_planarCharts.regionIdFromFace(bestFace));
}
- XA_PROFILE_END(buildAtlasGrowCharts)
+ XA_PROFILE_END(clusteredChartsGrow)
}
void resetCharts()
{
- XA_PROFILE_START(buildAtlasResetCharts)
- const uint32_t faceCount = m_mesh->faceCount();
- for (uint32_t i = 0; i < faceCount; i++)
+ XA_PROFILE_START(clusteredChartsReset)
+ const uint32_t faceCount = m_data.mesh->faceCount();
+ for (uint32_t i = 0; i < faceCount; i++) {
+ if (m_faceCharts[i] != -1)
+ m_data.isFaceInChart.unset(i);
m_faceCharts[i] = -1;
- m_facesLeft = faceCount;
+ }
+ m_facesLeft = 0;
+ for (uint32_t i = 0; i < faceCount; i++) {
+ if (!m_data.isFaceInChart.get(i))
+ m_facesLeft++;
+ }
const uint32_t chartCount = m_charts.size();
for (uint32_t i = 0; i < chartCount; i++) {
Chart *chart = m_charts[i];
- const uint32_t seed = chart->seeds.back();
chart->area = 0.0f;
chart->boundaryLength = 0.0f;
chart->basis.normal = Vector3(0.0f);
@@ -5078,14 +5875,14 @@ struct Atlas
chart->faces.clear();
chart->candidates.clear();
chart->failedPlanarRegions.clear();
- addFaceToChart(chart, seed);
+ addFaceToChart(chart, chart->seed);
}
- XA_PROFILE_END(buildAtlasResetCharts)
+ XA_PROFILE_END(clusteredChartsReset)
}
bool relocateSeeds()
{
- XA_PROFILE_START(buildAtlasRelocateSeeds)
+ XA_PROFILE_START(clusteredChartsRelocateSeeds)
bool anySeedChanged = false;
const uint32_t chartCount = m_charts.size();
for (uint32_t i = 0; i < chartCount; i++) {
@@ -5093,22 +5890,22 @@ struct Atlas
anySeedChanged = true;
}
}
- XA_PROFILE_END(buildAtlasRelocateSeeds)
+ XA_PROFILE_END(clusteredChartsRelocateSeeds)
return anySeedChanged;
}
void fillHoles(float threshold)
{
- XA_PROFILE_START(buildAtlasFillHoles)
+ XA_PROFILE_START(clusteredChartsFillHoles)
while (m_facesLeft > 0)
- createRandomChart(threshold);
- XA_PROFILE_END(buildAtlasFillHoles)
+ createChart(threshold);
+ XA_PROFILE_END(clusteredChartsFillHoles)
}
#if XA_MERGE_CHARTS
void mergeCharts()
{
- XA_PROFILE_START(buildAtlasMergeCharts)
+ XA_PROFILE_START(clusteredChartsMerge)
const uint32_t chartCount = m_charts.size();
// Merge charts progressively until there's none left to merge.
for (;;) {
@@ -5127,13 +5924,15 @@ struct Atlas
const uint32_t faceCount = chart->faces.size();
for (uint32_t i = 0; i < faceCount; i++) {
const uint32_t f = chart->faces[i];
- for (Mesh::FaceEdgeIterator it(m_mesh, f); !it.isDone(); it.advance()) {
- const float l = m_edgeLengths[it.edge()];
+ for (Mesh::FaceEdgeIterator it(m_data.mesh, f); !it.isDone(); it.advance()) {
+ const float l = m_data.edgeLengths[it.edge()];
if (it.isBoundary()) {
externalBoundaryLength += l;
} else {
const int neighborChart = m_faceCharts[it.oppositeFace()];
- if (m_charts[neighborChart] != chart) {
+ if (neighborChart == -1)
+ externalBoundaryLength += l;
+ else if (m_charts[neighborChart] != chart) {
if ((it.isSeam() && (isNormalSeam(it.edge()) || it.isTextureSeam()))) {
externalBoundaryLength += l;
} else {
@@ -5158,9 +5957,9 @@ struct Atlas
if (dot(chart2->basis.normal, chart->basis.normal) < XA_MERGE_CHARTS_MIN_NORMAL_DEVIATION)
continue;
// Obey max chart area and boundary length.
- if (m_options.maxChartArea > 0.0f && chart->area + chart2->area > m_options.maxChartArea)
+ if (m_data.options.maxChartArea > 0.0f && chart->area + chart2->area > m_data.options.maxChartArea)
continue;
- if (m_options.maxBoundaryLength > 0.0f && chart->boundaryLength + chart2->boundaryLength - m_sharedBoundaryLengthsNoSeams[cc] > m_options.maxBoundaryLength)
+ if (m_data.options.maxBoundaryLength > 0.0f && chart->boundaryLength + chart2->boundaryLength - m_sharedBoundaryLengthsNoSeams[cc] > m_data.options.maxBoundaryLength)
continue;
// Merge if chart2 has a single face.
// chart1 must have more than 1 face.
@@ -5207,33 +6006,38 @@ struct Atlas
c++;
}
}
- XA_PROFILE_END(buildAtlasMergeCharts)
+ XA_PROFILE_END(clusteredChartsMerge)
}
#endif
private:
- void createRandomChart(float threshold)
+ void createChart(float threshold)
{
Chart *chart = XA_NEW(MemTag::Default, Chart);
chart->id = (int)m_charts.size();
m_charts.push_back(chart);
- // Pick random face that is not used by any chart yet.
- uint32_t face = m_rand.getRange(m_mesh->faceCount() - 1);
- while (m_faceCharts[face] != -1) {
- if (++face >= m_mesh->faceCount())
- face = 0;
- }
- chart->seeds.push_back(face);
- addFaceToChart(chart, face);
+ // Pick a face not used by any chart yet, belonging to the largest planar region.
+ chart->seed = 0;
+ float largestArea = 0.0f;
+ for (uint32_t f = 0; f < m_data.mesh->faceCount(); f++) {
+ if (m_data.isFaceInChart.get(f))
+ continue;
+ const float area = m_planarCharts.regionArea(m_planarCharts.regionIdFromFace(f));
+ if (area > largestArea) {
+ largestArea = area;
+ chart->seed = f;
+ }
+ }
+ addFaceToChart(chart, chart->seed);
// Grow the chart as much as possible within the given threshold.
for (;;) {
if (chart->candidates.count() == 0 || chart->candidates.peekCost() > threshold)
break;
const uint32_t f = chart->candidates.pop();
- if (m_faceCharts[f] != -1)
+ if (m_data.isFaceInChart.get(f))
continue;
if (!addFaceToChart(chart, f)) {
- chart->failedPlanarRegions.push_back(m_facePlanarRegionId[f]);
+ chart->failedPlanarRegions.push_back(m_planarCharts.regionIdFromFace(f));
continue;
}
}
@@ -5241,7 +6045,7 @@ private:
bool isChartBoundaryEdge(const Chart *chart, uint32_t edge) const
{
- const uint32_t oppositeEdge = m_mesh->oppositeEdge(edge);
+ const uint32_t oppositeEdge = m_data.mesh->oppositeEdge(edge);
const uint32_t oppositeFace = meshEdgeFace(oppositeEdge);
return oppositeEdge == UINT32_MAX || m_faceCharts[oppositeFace] != chart->id;
}
@@ -5253,7 +6057,7 @@ private:
for (uint32_t i = 0; i < faceCount; i++) {
const uint32_t f = chart->faces[i];
for (uint32_t j = 0; j < 3; j++)
- m_tempPoints[i * 3 + j] = m_mesh->position(m_mesh->vertexAt(f * 3 + j));
+ m_tempPoints[i * 3 + j] = m_data.mesh->position(m_data.mesh->vertexAt(f * 3 + j));
}
return Fit::computeBasis(m_tempPoints.data(), m_tempPoints.size(), basis);
}
@@ -5274,7 +6078,7 @@ private:
const uint32_t face = chart->faces[i];
for (uint32_t j = 0; j < 3; j++) {
const uint32_t offset = face * 3 + j;
- const Vector3 &pos = m_mesh->position(m_mesh->vertexAt(offset));
+ const Vector3 &pos = m_data.mesh->position(m_data.mesh->vertexAt(offset));
m_texcoords[offset] = Vector2(dot(chart->basis.tangent, pos), dot(chart->basis.bitangent, pos));
}
}
@@ -5293,6 +6097,8 @@ private:
if (flippedFaceCount != 0 && flippedFaceCount != faceCount)
return false;
// Check for boundary intersection in the parameterization.
+ XA_PROFILE_START(clusteredChartsPlaceSeedsBoundaryIntersection)
+ XA_PROFILE_START(clusteredChartsGrowBoundaryIntersection)
m_boundaryGrid.reset(m_texcoords.data());
for (uint32_t i = 0; i < faceCount; i++) {
const uint32_t f = chart->faces[i];
@@ -5302,23 +6108,30 @@ private:
m_boundaryGrid.append(edge);
}
}
- if (m_boundaryGrid.intersectSelf(m_mesh->epsilon()))
+ const bool intersection = m_boundaryGrid.intersect(m_data.mesh->epsilon());
+#if XA_PROFILE
+ if (m_placingSeeds)
+ XA_PROFILE_END(clusteredChartsPlaceSeedsBoundaryIntersection)
+ else
+ XA_PROFILE_END(clusteredChartsGrowBoundaryIntersection)
+#endif
+ if (intersection)
return false;
return true;
}
bool addFaceToChart(Chart *chart, uint32_t face)
{
- XA_DEBUG_ASSERT(m_faceCharts[face] == -1);
+ XA_DEBUG_ASSERT(!m_data.isFaceInChart.get(face));
const uint32_t oldFaceCount = chart->faces.size();
const bool firstFace = oldFaceCount == 0;
// Append the face and any coplanar connected faces to the chart faces array.
chart->faces.push_back(face);
- uint32_t coplanarFace = m_nextPlanarRegionFace[face];
+ uint32_t coplanarFace = m_planarCharts.nextRegionFace(face);
while (coplanarFace != face) {
- XA_DEBUG_ASSERT(m_faceCharts[coplanarFace] == -1);
+ XA_DEBUG_ASSERT(!m_data.isFaceInChart.get(coplanarFace));
chart->faces.push_back(coplanarFace);
- coplanarFace = m_nextPlanarRegionFace[coplanarFace];
+ coplanarFace = m_planarCharts.nextRegionFace(coplanarFace);
}
const uint32_t faceCount = chart->faces.size();
// Compute basis.
@@ -5326,8 +6139,8 @@ private:
if (firstFace) {
// Use the first face normal.
// Use any edge as the tangent vector.
- basis.normal = m_faceNormals[face];
- basis.tangent = normalize(m_mesh->position(m_mesh->vertexAt(face * 3 + 0)) - m_mesh->position(m_mesh->vertexAt(face * 3 + 1)), kEpsilon);
+ basis.normal = m_data.faceNormals[face];
+ basis.tangent = normalize(m_data.mesh->position(m_data.mesh->vertexAt(face * 3 + 0)) - m_data.mesh->position(m_data.mesh->vertexAt(face * 3 + 1)), kEpsilon);
basis.bitangent = cross(basis.normal, basis.tangent);
} else {
// Use best fit normal.
@@ -5335,7 +6148,7 @@ private:
chart->faces.resize(oldFaceCount);
return false;
}
- if (dot(basis.normal, m_faceNormals[face]) < 0.0f) // Flip normal if oriented in the wrong direction.
+ if (dot(basis.normal, m_data.faceNormals[face]) < 0.0f) // Flip normal if oriented in the wrong direction.
basis.normal = -basis.normal;
}
if (!firstFace) {
@@ -5358,7 +6171,8 @@ private:
const uint32_t f = chart->faces[i];
m_faceCharts[f] = chart->id;
m_facesLeft--;
- chart->centroidSum += m_mesh->computeFaceCenter(f);
+ m_data.isFaceInChart.set(f);
+ chart->centroidSum += m_data.mesh->computeFaceCenter(f);
}
chart->centroid = chart->centroidSum / float(chart->faces.size());
// Refresh candidates.
@@ -5368,15 +6182,15 @@ private:
const uint32_t f = chart->faces[i];
for (uint32_t j = 0; j < 3; j++) {
const uint32_t edge = f * 3 + j;
- const uint32_t oedge = m_mesh->oppositeEdge(edge);
+ const uint32_t oedge = m_data.mesh->oppositeEdge(edge);
if (oedge == UINT32_MAX)
continue; // Boundary edge.
const uint32_t oface = meshEdgeFace(oedge);
- if (m_faceCharts[oface] != -1)
+ if (m_data.isFaceInChart.get(oface))
continue; // Face belongs to another chart.
- if (chart->failedPlanarRegions.contains(m_facePlanarRegionId[oface]))
+ if (chart->failedPlanarRegions.contains(m_planarCharts.regionIdFromFace(oface)))
continue; // Failed to add this faces planar region to the chart before.
- const float cost = evaluateCost(chart, oface);
+ const float cost = computeCost(chart, oface);
if (cost < FLT_MAX)
chart->candidates.push(cost, oface);
}
@@ -5391,72 +6205,56 @@ private:
const uint32_t faceCount = chart->faces.size();
m_bestTriangles.clear();
for (uint32_t i = 0; i < faceCount; i++) {
- const float cost = evaluateProxyFitMetric(chart, chart->faces[i]);
+ const float cost = computeNormalDeviationMetric(chart, chart->faces[i]);
m_bestTriangles.push(cost, chart->faces[i]);
}
- // Of those, choose the least central triangle.
- uint32_t leastCentral = 0;
- float maxDistance = -1;
+ // Of those, choose the most central triangle.
+ uint32_t mostCentral = 0;
+ float minDistance = FLT_MAX;
for (;;) {
if (m_bestTriangles.count() == 0)
break;
const uint32_t face = m_bestTriangles.pop();
- Vector3 faceCentroid = m_mesh->computeFaceCenter(face);
+ Vector3 faceCentroid = m_data.mesh->computeFaceCenter(face);
const float distance = length(chart->centroid - faceCentroid);
- if (distance > maxDistance) {
- maxDistance = distance;
- leastCentral = face;
- }
- }
- XA_DEBUG_ASSERT(maxDistance >= 0);
- // In order to prevent k-means cyles we record all the previously chosen seeds.
- for (uint32_t i = 0; i < chart->seeds.size(); i++) {
- // Treat seeds belong to the same planar region as equal.
- if (chart->seeds[i] == leastCentral || m_facePlanarRegionId[chart->seeds[i]] == m_facePlanarRegionId[leastCentral]) {
- // Move new seed to the end of the seed array.
- uint32_t last = chart->seeds.size() - 1;
- swap(chart->seeds[i], chart->seeds[last]);
- return false;
+ if (distance < minDistance) {
+ minDistance = distance;
+ mostCentral = face;
}
}
- // Append new seed.
- chart->seeds.push_back(leastCentral);
+ XA_DEBUG_ASSERT(minDistance < FLT_MAX);
+ if (mostCentral == chart->seed)
+ return false;
+ chart->seed = mostCentral;
return true;
}
- // Evaluate combined metric.
- float evaluateCost(Chart *chart, uint32_t face) const
+ // Cost is combined metrics * weights.
+ float computeCost(Chart *chart, uint32_t face) const
{
- if (dot(m_faceNormals[face], chart->basis.normal) <= 0.26f) // ~75 degrees
- return FLT_MAX;
// Estimate boundary length and area:
- float newChartArea = 0.0f, newBoundaryLength = 0.0f;
- if (m_options.maxChartArea > 0.0f || m_options.roundnessMetricWeight > 0.0f)
- newChartArea = computeArea(chart, face);
- if (m_options.maxBoundaryLength > 0.0f || m_options.roundnessMetricWeight > 0.0f)
- newBoundaryLength = computeBoundaryLength(chart, face);
+ const float newChartArea = computeArea(chart, face);
+ const float newBoundaryLength = computeBoundaryLength(chart, face);
// Enforce limits strictly:
- if (m_options.maxChartArea > 0.0f && newChartArea > m_options.maxChartArea)
+ if (m_data.options.maxChartArea > 0.0f && newChartArea > m_data.options.maxChartArea)
return FLT_MAX;
- if (m_options.maxBoundaryLength > 0.0f && newBoundaryLength > m_options.maxBoundaryLength)
+ if (m_data.options.maxBoundaryLength > 0.0f && newBoundaryLength > m_data.options.maxBoundaryLength)
return FLT_MAX;
+ // Compute metrics.
float cost = 0.0f;
- if (m_options.normalSeamMetricWeight > 0.0f) {
- // Penalize faces that cross seams, reward faces that close seams or reach boundaries.
- // Make sure normal seams are fully respected:
- const float N = evaluateNormalSeamMetric(chart, face);
- if (m_options.normalSeamMetricWeight >= 1000.0f && N > 0.0f)
- return FLT_MAX;
- cost += m_options.normalSeamMetricWeight * N;
- }
- if (m_options.proxyFitMetricWeight > 0.0f)
- cost += m_options.proxyFitMetricWeight * evaluateProxyFitMetric(chart, face);
- if (m_options.roundnessMetricWeight > 0.0f)
- cost += m_options.roundnessMetricWeight * evaluateRoundnessMetric(chart, newBoundaryLength, newChartArea);
- if (m_options.straightnessMetricWeight > 0.0f)
- cost += m_options.straightnessMetricWeight * evaluateStraightnessMetric(chart, face);
- if (m_options.textureSeamMetricWeight > 0.0f)
- cost += m_options.textureSeamMetricWeight * evaluateTextureSeamMetric(chart, face);
+ const float normalDeviation = computeNormalDeviationMetric(chart, face);
+ if (normalDeviation >= 0.707f) // ~75 degrees
+ return FLT_MAX;
+ cost += m_data.options.normalDeviationWeight * normalDeviation;
+ // Penalize faces that cross seams, reward faces that close seams or reach boundaries.
+ // Make sure normal seams are fully respected:
+ const float normalSeam = computeNormalSeamMetric(chart, face);
+ if (m_data.options.normalSeamWeight >= 1000.0f && normalSeam > 0.0f)
+ return FLT_MAX;
+ cost += m_data.options.normalSeamWeight * normalSeam;
+ cost += m_data.options.roundnessWeight * computeRoundnessMetric(chart, newBoundaryLength, newChartArea);
+ cost += m_data.options.straightnessWeight * computeStraightnessMetric(chart, face);
+ cost += m_data.options.textureSeamWeight * computeTextureSeamMetric(chart, face);
//float R = evaluateCompletenessMetric(chart, face);
//float D = evaluateDihedralAngleMetric(chart, face);
// @@ Add a metric based on local dihedral angle.
@@ -5467,105 +6265,108 @@ private:
}
// Returns a value in [0-1].
- float evaluateProxyFitMetric(Chart *chart, uint32_t face) const
+ // 0 if face normal is coplanar to the chart's best fit normal.
+ // 1 if face normal is perpendicular.
+ float computeNormalDeviationMetric(Chart *chart, uint32_t face) const
{
// All faces in coplanar regions have the same normal, can use any face.
- const Vector3 faceNormal = m_faceNormals[face];
+ const Vector3 faceNormal = m_data.faceNormals[face];
// Use plane fitting metric for now:
- return 1 - dot(faceNormal, chart->basis.normal); // @@ normal deviations should be weighted by face area
+ return min(1.0f - dot(faceNormal, chart->basis.normal), 1.0f); // @@ normal deviations should be weighted by face area
}
- float evaluateRoundnessMetric(Chart *chart, float newBoundaryLength, float newChartArea) const
+ float computeRoundnessMetric(Chart *chart, float newBoundaryLength, float newChartArea) const
{
- const float roundness = square(chart->boundaryLength) / chart->area;
- const float newBoundaryLengthSq = square(newBoundaryLength);
- const float newRoundness = newBoundaryLengthSq / newChartArea;
- if (newRoundness > roundness)
- return newBoundaryLengthSq / (newChartArea * kPi4);
- // Offer no impedance to faces that improve roundness.
- return 0;
+ const float oldRoundness = square(chart->boundaryLength) / chart->area;
+ const float newRoundness = square(newBoundaryLength) / newChartArea;
+ return 1.0f - oldRoundness / newRoundness;
}
- float evaluateStraightnessMetric(Chart *chart, uint32_t firstFace) const
+ float computeStraightnessMetric(Chart *chart, uint32_t firstFace) const
{
- float l_out = 0.0f, l_in = 0.0f;
- const uint32_t planarRegionId = m_facePlanarRegionId[firstFace];
+ float l_out = 0.0f; // Length of firstFace planar region boundary that doesn't border the chart.
+ float l_in = 0.0f; // Length that does border the chart.
+ const uint32_t planarRegionId = m_planarCharts.regionIdFromFace(firstFace);
uint32_t face = firstFace;
for (;;) {
- for (Mesh::FaceEdgeIterator it(m_mesh, face); !it.isDone(); it.advance()) {
- const float l = m_edgeLengths[it.edge()];
+ for (Mesh::FaceEdgeIterator it(m_data.mesh, face); !it.isDone(); it.advance()) {
+ const float l = m_data.edgeLengths[it.edge()];
if (it.isBoundary()) {
l_out += l;
- } else if (m_facePlanarRegionId[it.oppositeFace()] != planarRegionId) {
+ } else if (m_planarCharts.regionIdFromFace(it.oppositeFace()) != planarRegionId) {
if (m_faceCharts[it.oppositeFace()] != chart->id)
l_out += l;
else
l_in += l;
}
}
- face = m_nextPlanarRegionFace[face];
+ face = m_planarCharts.nextRegionFace(face);
if (face == firstFace)
break;
}
+#if 1
XA_DEBUG_ASSERT(l_in != 0.0f); // Candidate face must be adjacent to chart. @@ This is not true if the input mesh has zero-length edges.
float ratio = (l_out - l_in) / (l_out + l_in);
return min(ratio, 0.0f); // Only use the straightness metric to close gaps.
+#else
+ return 1.0f - l_in / l_out;
+#endif
}
bool isNormalSeam(uint32_t edge) const
{
- const uint32_t oppositeEdge = m_mesh->oppositeEdge(edge);
+ const uint32_t oppositeEdge = m_data.mesh->oppositeEdge(edge);
if (oppositeEdge == UINT32_MAX)
return false; // boundary edge
- if (m_mesh->flags() & MeshFlags::HasNormals) {
- const uint32_t v0 = m_mesh->vertexAt(meshEdgeIndex0(edge));
- const uint32_t v1 = m_mesh->vertexAt(meshEdgeIndex1(edge));
- const uint32_t ov0 = m_mesh->vertexAt(meshEdgeIndex0(oppositeEdge));
- const uint32_t ov1 = m_mesh->vertexAt(meshEdgeIndex1(oppositeEdge));
+ if (m_data.mesh->flags() & MeshFlags::HasNormals) {
+ const uint32_t v0 = m_data.mesh->vertexAt(meshEdgeIndex0(edge));
+ const uint32_t v1 = m_data.mesh->vertexAt(meshEdgeIndex1(edge));
+ const uint32_t ov0 = m_data.mesh->vertexAt(meshEdgeIndex0(oppositeEdge));
+ const uint32_t ov1 = m_data.mesh->vertexAt(meshEdgeIndex1(oppositeEdge));
if (v0 == ov1 && v1 == ov0)
return false;
- return !equal(m_mesh->normal(v0), m_mesh->normal(ov1), kNormalEpsilon) || !equal(m_mesh->normal(v1), m_mesh->normal(ov0), kNormalEpsilon);
+ return !equal(m_data.mesh->normal(v0), m_data.mesh->normal(ov1), kNormalEpsilon) || !equal(m_data.mesh->normal(v1), m_data.mesh->normal(ov0), kNormalEpsilon);
}
const uint32_t f0 = meshEdgeFace(edge);
const uint32_t f1 = meshEdgeFace(oppositeEdge);
- if (m_facePlanarRegionId[f0] == m_facePlanarRegionId[f1])
+ if (m_planarCharts.regionIdFromFace(f0) == m_planarCharts.regionIdFromFace(f1))
return false;
- return !equal(m_faceNormals[f0], m_faceNormals[f1], kNormalEpsilon);
+ return !equal(m_data.faceNormals[f0], m_data.faceNormals[f1], kNormalEpsilon);
}
- float evaluateNormalSeamMetric(Chart *chart, uint32_t firstFace) const
+ float computeNormalSeamMetric(Chart *chart, uint32_t firstFace) const
{
float seamFactor = 0.0f, totalLength = 0.0f;
uint32_t face = firstFace;
for (;;) {
- for (Mesh::FaceEdgeIterator it(m_mesh, face); !it.isDone(); it.advance()) {
+ for (Mesh::FaceEdgeIterator it(m_data.mesh, face); !it.isDone(); it.advance()) {
if (it.isBoundary())
continue;
if (m_faceCharts[it.oppositeFace()] != chart->id)
continue;
- float l = m_edgeLengths[it.edge()];
+ float l = m_data.edgeLengths[it.edge()];
totalLength += l;
if (!it.isSeam())
continue;
// Make sure it's a normal seam.
if (isNormalSeam(it.edge())) {
float d;
- if (m_mesh->flags() & MeshFlags::HasNormals) {
- const Vector3 &n0 = m_mesh->normal(it.vertex0());
- const Vector3 &n1 = m_mesh->normal(it.vertex1());
- const Vector3 &on0 = m_mesh->normal(m_mesh->vertexAt(meshEdgeIndex0(it.oppositeEdge())));
- const Vector3 &on1 = m_mesh->normal(m_mesh->vertexAt(meshEdgeIndex1(it.oppositeEdge())));
+ if (m_data.mesh->flags() & MeshFlags::HasNormals) {
+ const Vector3 &n0 = m_data.mesh->normal(it.vertex0());
+ const Vector3 &n1 = m_data.mesh->normal(it.vertex1());
+ const Vector3 &on0 = m_data.mesh->normal(m_data.mesh->vertexAt(meshEdgeIndex0(it.oppositeEdge())));
+ const Vector3 &on1 = m_data.mesh->normal(m_data.mesh->vertexAt(meshEdgeIndex1(it.oppositeEdge())));
const float d0 = clamp(dot(n0, on1), 0.0f, 1.0f);
const float d1 = clamp(dot(n1, on0), 0.0f, 1.0f);
d = (d0 + d1) * 0.5f;
} else {
- d = clamp(dot(m_faceNormals[face], m_faceNormals[meshEdgeFace(it.oppositeEdge())]), 0.0f, 1.0f);
+ d = clamp(dot(m_data.faceNormals[face], m_data.faceNormals[meshEdgeFace(it.oppositeEdge())]), 0.0f, 1.0f);
}
l *= 1 - d;
seamFactor += l;
}
}
- face = m_nextPlanarRegionFace[face];
+ face = m_planarCharts.nextRegionFace(face);
if (face == firstFace)
break;
}
@@ -5574,17 +6375,17 @@ private:
return seamFactor / totalLength;
}
- float evaluateTextureSeamMetric(Chart *chart, uint32_t firstFace) const
+ float computeTextureSeamMetric(Chart *chart, uint32_t firstFace) const
{
float seamLength = 0.0f, totalLength = 0.0f;
uint32_t face = firstFace;
for (;;) {
- for (Mesh::FaceEdgeIterator it(m_mesh, face); !it.isDone(); it.advance()) {
+ for (Mesh::FaceEdgeIterator it(m_data.mesh, face); !it.isDone(); it.advance()) {
if (it.isBoundary())
continue;
if (m_faceCharts[it.oppositeFace()] != chart->id)
continue;
- float l = m_edgeLengths[it.edge()];
+ float l = m_data.edgeLengths[it.edge()];
totalLength += l;
if (!it.isSeam())
continue;
@@ -5592,7 +6393,7 @@ private:
if (it.isTextureSeam())
seamLength += l;
}
- face = m_nextPlanarRegionFace[face];
+ face = m_planarCharts.nextRegionFace(face);
if (face == firstFace)
break;
}
@@ -5606,8 +6407,8 @@ private:
float area = chart->area;
uint32_t face = firstFace;
for (;;) {
- area += m_faceAreas[face];
- face = m_nextPlanarRegionFace[face];
+ area += m_data.faceAreas[face];
+ face = m_planarCharts.nextRegionFace(face);
if (face == firstFace)
break;
}
@@ -5618,21 +6419,21 @@ private:
{
float boundaryLength = chart->boundaryLength;
// Add new edges, subtract edges shared with the chart.
- const uint32_t planarRegionId = m_facePlanarRegionId[firstFace];
+ const uint32_t planarRegionId = m_planarCharts.regionIdFromFace(firstFace);
uint32_t face = firstFace;
for (;;) {
- for (Mesh::FaceEdgeIterator it(m_mesh, face); !it.isDone(); it.advance()) {
- const float edgeLength = m_edgeLengths[it.edge()];
+ for (Mesh::FaceEdgeIterator it(m_data.mesh, face); !it.isDone(); it.advance()) {
+ const float edgeLength = m_data.edgeLengths[it.edge()];
if (it.isBoundary()) {
boundaryLength += edgeLength;
- } else if (m_facePlanarRegionId[it.oppositeFace()] != planarRegionId) {
+ } else if (m_planarCharts.regionIdFromFace(it.oppositeFace()) != planarRegionId) {
if (m_faceCharts[it.oppositeFace()] != chart->id)
boundaryLength += edgeLength;
else
boundaryLength -= edgeLength;
}
}
- face = m_nextPlanarRegionFace[face];
+ face = m_planarCharts.nextRegionFace(face);
if (face == firstFace)
break;
}
@@ -5656,7 +6457,7 @@ private:
m_faceCharts[chart->faces[i]] = chart->id;
return false;
}
- if (dot(basis.normal, m_faceNormals[owner->faces[0]]) < 0.0f) // Flip normal if oriented in the wrong direction.
+ if (dot(basis.normal, m_data.faceNormals[owner->faces[0]]) < 0.0f) // Flip normal if oriented in the wrong direction.
basis.normal = -basis.normal;
// Compute orthogonal parameterization and check that it is valid.
parameterizeChart(owner);
@@ -5679,19 +6480,14 @@ private:
return true;
}
- const Mesh *m_mesh;
- Array<float> m_edgeLengths;
- Array<float> m_faceAreas;
- Array<Vector3> m_faceNormals;
+private:
+ AtlasData &m_data;
+ const PlanarCharts &m_planarCharts;
Array<Vector2> m_texcoords;
uint32_t m_facesLeft;
Array<int> m_faceCharts;
Array<Chart *> m_charts;
CostQueue m_bestTriangles;
- KISSRng m_rand;
- ChartOptions m_options;
- Array<uint32_t> m_nextPlanarRegionFace;
- Array<uint32_t> m_facePlanarRegionId;
Array<Vector3> m_tempPoints;
UniformGrid2 m_boundaryGrid;
#if XA_MERGE_CHARTS
@@ -5700,231 +6496,63 @@ private:
Array<float> m_sharedBoundaryLengthsNoSeams;
Array<uint32_t> m_sharedBoundaryEdgeCountNoSeams;
#endif
+ bool m_placingSeeds;
};
-} // namespace segment
-
-namespace param {
-
-class JacobiPreconditioner
+struct Atlas
{
-public:
- JacobiPreconditioner(const sparse::Matrix &M, bool symmetric) : m_inverseDiagonal(M.width())
- {
- XA_ASSERT(M.isSquare());
- for (uint32_t x = 0; x < M.width(); x++) {
- float elem = M.getCoefficient(x, x);
- //XA_DEBUG_ASSERT( elem != 0.0f ); // This can be zero in the presence of zero area triangles.
- if (symmetric) {
- m_inverseDiagonal[x] = (elem != 0) ? 1.0f / sqrtf(fabsf(elem)) : 1.0f;
- } else {
- m_inverseDiagonal[x] = (elem != 0) ? 1.0f / elem : 1.0f;
- }
- }
- }
+ Atlas() : m_planarCharts(m_data), m_clusteredCharts(m_data, m_planarCharts) {}
- void apply(const FullVector &x, FullVector &y) const
+ uint32_t chartCount() const
{
- XA_DEBUG_ASSERT(x.dimension() == m_inverseDiagonal.dimension());
- XA_DEBUG_ASSERT(y.dimension() == m_inverseDiagonal.dimension());
- // @@ Wrap vector component-wise product into a separate function.
- const uint32_t D = x.dimension();
- for (uint32_t i = 0; i < D; i++) {
- y[i] = m_inverseDiagonal[i] * x[i];
- }
+ return m_planarCharts.chartCount() + m_clusteredCharts.chartCount();
}
-private:
- FullVector m_inverseDiagonal;
-};
+ ConstArrayView<uint32_t> chartFaces(uint32_t chartIndex) const
+ {
+ if (chartIndex < m_planarCharts.chartCount())
+ return m_planarCharts.chartFaces(chartIndex);
+ chartIndex -= m_planarCharts.chartCount();
+ return m_clusteredCharts.chartFaces(chartIndex);
+ }
-// Linear solvers.
-class Solver
-{
-public:
- // Solve the symmetric system: At·A·x = At·b
- static bool LeastSquaresSolver(const sparse::Matrix &A, const FullVector &b, FullVector &x, float epsilon = 1e-5f)
- {
- XA_DEBUG_ASSERT(A.width() == x.dimension());
- XA_DEBUG_ASSERT(A.height() == b.dimension());
- XA_DEBUG_ASSERT(A.height() >= A.width()); // @@ If height == width we could solve it directly...
- const uint32_t D = A.width();
- sparse::Matrix At(A.height(), A.width());
- sparse::transpose(A, At);
- FullVector Atb(D);
- sparse::mult(At, b, Atb);
- sparse::Matrix AtA(D);
- sparse::mult(At, A, AtA);
- return SymmetricSolver(AtA, Atb, x, epsilon);
- }
-
- // See section 10.4.3 in: Mesh Parameterization: Theory and Practice, Siggraph Course Notes, August 2007
- static bool LeastSquaresSolver(const sparse::Matrix &A, const FullVector &b, FullVector &x, const uint32_t *lockedParameters, uint32_t lockedCount, float epsilon = 1e-5f)
- {
- XA_DEBUG_ASSERT(A.width() == x.dimension());
- XA_DEBUG_ASSERT(A.height() == b.dimension());
- XA_DEBUG_ASSERT(A.height() >= A.width() - lockedCount);
- // @@ This is not the most efficient way of building a system with reduced degrees of freedom. It would be faster to do it on the fly.
- const uint32_t D = A.width() - lockedCount;
- XA_DEBUG_ASSERT(D > 0);
- // Compute: b - Al * xl
- FullVector b_Alxl(b);
- for (uint32_t y = 0; y < A.height(); y++) {
- const uint32_t count = A.getRow(y).size();
- for (uint32_t e = 0; e < count; e++) {
- uint32_t column = A.getRow(y)[e].x;
- bool isFree = true;
- for (uint32_t i = 0; i < lockedCount; i++) {
- isFree &= (lockedParameters[i] != column);
- }
- if (!isFree) {
- b_Alxl[y] -= x[column] * A.getRow(y)[e].v;
- }
- }
- }
- // Remove locked columns from A.
- sparse::Matrix Af(D, A.height());
- for (uint32_t y = 0; y < A.height(); y++) {
- const uint32_t count = A.getRow(y).size();
- for (uint32_t e = 0; e < count; e++) {
- uint32_t column = A.getRow(y)[e].x;
- uint32_t ix = column;
- bool isFree = true;
- for (uint32_t i = 0; i < lockedCount; i++) {
- isFree &= (lockedParameters[i] != column);
- if (column > lockedParameters[i]) ix--; // shift columns
- }
- if (isFree) {
- Af.setCoefficient(ix, y, A.getRow(y)[e].v);
- }
- }
- }
- // Remove elements from x
- FullVector xf(D);
- for (uint32_t i = 0, j = 0; i < A.width(); i++) {
- bool isFree = true;
- for (uint32_t l = 0; l < lockedCount; l++) {
- isFree &= (lockedParameters[l] != i);
- }
- if (isFree) {
- xf[j++] = x[i];
- }
- }
- // Solve reduced system.
- bool result = LeastSquaresSolver(Af, b_Alxl, xf, epsilon);
- // Copy results back to x.
- for (uint32_t i = 0, j = 0; i < A.width(); i++) {
- bool isFree = true;
- for (uint32_t l = 0; l < lockedCount; l++) {
- isFree &= (lockedParameters[l] != i);
- }
- if (isFree) {
- x[i] = xf[j++];
- }
- }
- return result;
+ const Basis &chartBasis(uint32_t chartIndex) const
+ {
+ if (chartIndex < m_planarCharts.chartCount())
+ return m_planarCharts.chartBasis(chartIndex);
+ chartIndex -= m_planarCharts.chartCount();
+ return m_clusteredCharts.chartBasis(chartIndex);
}
-private:
- /**
- * Compute the solution of the sparse linear system Ab=x using the Conjugate
- * Gradient method.
- *
- * Solving sparse linear systems:
- * (1) A·x = b
- *
- * The conjugate gradient algorithm solves (1) only in the case that A is
- * symmetric and positive definite. It is based on the idea of minimizing the
- * function
- *
- * (2) f(x) = 1/2·x·A·x - b·x
- *
- * This function is minimized when its gradient
- *
- * (3) df = A·x - b
- *
- * is zero, which is equivalent to (1). The minimization is carried out by
- * generating a succession of search directions p.k and improved minimizers x.k.
- * At each stage a quantity alfa.k is found that minimizes f(x.k + alfa.k·p.k),
- * and x.k+1 is set equal to the new point x.k + alfa.k·p.k. The p.k and x.k are
- * built up in such a way that x.k+1 is also the minimizer of f over the whole
- * vector space of directions already taken, {p.1, p.2, . . . , p.k}. After N
- * iterations you arrive at the minimizer over the entire vector space, i.e., the
- * solution to (1).
- *
- * For a really good explanation of the method see:
- *
- * "An Introduction to the Conjugate Gradient Method Without the Agonizing Pain",
- * Jonhathan Richard Shewchuk.
- *
- **/
- // Conjugate gradient with preconditioner.
- static bool ConjugateGradientSolver(const JacobiPreconditioner &preconditioner, const sparse::Matrix &A, const FullVector &b, FullVector &x, float epsilon)
- {
- XA_DEBUG_ASSERT( A.isSquare() );
- XA_DEBUG_ASSERT( A.width() == b.dimension() );
- XA_DEBUG_ASSERT( A.width() == x.dimension() );
- int i = 0;
- const int D = A.width();
- const int i_max = 4 * D; // Convergence should be linear, but in some cases, it's not.
- FullVector r(D); // residual
- FullVector p(D); // search direction
- FullVector q(D); //
- FullVector s(D); // preconditioned
- float delta_0;
- float delta_old;
- float delta_new;
- float alpha;
- float beta;
- // r = b - A·x
- sparse::copy(b, r);
- sparse::sgemv(-1, A, x, 1, r);
- // p = M^-1 · r
- preconditioner.apply(r, p);
- delta_new = sparse::dot(r, p);
- delta_0 = delta_new;
- while (i < i_max && delta_new > epsilon * epsilon * delta_0) {
- i++;
- // q = A·p
- sparse::mult(A, p, q);
- // alpha = delta_new / p·q
- const float pdotq = sparse::dot(p, q);
- if (!isFinite(pdotq) || isNan(pdotq))
- alpha = 0.0f;
- else
- alpha = delta_new / pdotq;
- // x = alfa·p + x
- sparse::saxpy(alpha, p, x);
- if ((i & 31) == 0) { // recompute r after 32 steps
- // r = b - A·x
- sparse::copy(b, r);
- sparse::sgemv(-1, A, x, 1, r);
- } else {
- // r = r - alfa·q
- sparse::saxpy(-alpha, q, r);
- }
- // s = M^-1 · r
- preconditioner.apply(r, s);
- delta_old = delta_new;
- delta_new = sparse::dot( r, s );
- beta = delta_new / delta_old;
- // p = s + beta·p
- sparse::scal(beta, p);
- sparse::saxpy(1, s, p);
- }
- return delta_new <= epsilon * epsilon * delta_0;
+ void reset(const Mesh *mesh, const ChartOptions &options)
+ {
+ XA_PROFILE_START(buildAtlasInit)
+ m_data.options = options;
+ m_data.mesh = mesh;
+ m_data.compute();
+ XA_PROFILE_END(buildAtlasInit)
}
- static bool SymmetricSolver(const sparse::Matrix &A, const FullVector &b, FullVector &x, float epsilon = 1e-5f)
+ void compute()
{
- XA_DEBUG_ASSERT(A.height() == A.width());
- XA_DEBUG_ASSERT(A.height() == b.dimension());
- XA_DEBUG_ASSERT(b.dimension() == x.dimension());
- JacobiPreconditioner jacobi(A, true);
- return ConjugateGradientSolver(jacobi, A, b, x, epsilon);
+ XA_PROFILE_START(planarCharts)
+ m_planarCharts.compute();
+ XA_PROFILE_END(planarCharts)
+ XA_PROFILE_START(clusteredCharts)
+ m_clusteredCharts.compute();
+ XA_PROFILE_END(clusteredCharts)
}
+
+private:
+ AtlasData m_data;
+ PlanarCharts m_planarCharts;
+ ClusteredCharts m_clusteredCharts;
};
+} // namespace segment
+
+namespace param {
+
// Fast sweep in 3 directions
static bool findApproximateDiameterVertices(Mesh *mesh, uint32_t *a, uint32_t *b)
{
@@ -5982,134 +6610,95 @@ static bool findApproximateDiameterVertices(Mesh *mesh, uint32_t *a, uint32_t *b
return true;
}
-// Conformal relations from Brecht Van Lommel (based on ABF):
-
-static float vec_angle_cos(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3)
-{
- Vector3 d1 = v1 - v2;
- Vector3 d2 = v3 - v2;
- return clamp(dot(d1, d2) / (length(d1) * length(d2)), -1.0f, 1.0f);
-}
-
-static float vec_angle(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3)
-{
- float dot = vec_angle_cos(v1, v2, v3);
- return acosf(dot);
-}
-
-static void triangle_angles(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3, float *a1, float *a2, float *a3)
-{
- *a1 = vec_angle(v3, v1, v2);
- *a2 = vec_angle(v1, v2, v3);
- *a3 = kPi - *a2 - *a1;
-}
-
-static void setup_abf_relations(sparse::Matrix &A, int row, int id0, int id1, int id2, const Vector3 &p0, const Vector3 &p1, const Vector3 &p2)
-{
- // @@ IC: Wouldn't it be more accurate to return cos and compute 1-cos^2?
- // It does indeed seem to be a little bit more robust.
- // @@ Need to revisit this more carefully!
- float a0, a1, a2;
- triangle_angles(p0, p1, p2, &a0, &a1, &a2);
- float s0 = sinf(a0);
- float s1 = sinf(a1);
- float s2 = sinf(a2);
- if (s1 > s0 && s1 > s2) {
- swap(s1, s2);
- swap(s0, s1);
- swap(a1, a2);
- swap(a0, a1);
- swap(id1, id2);
- swap(id0, id1);
- } else if (s0 > s1 && s0 > s2) {
- swap(s0, s2);
- swap(s0, s1);
- swap(a0, a2);
- swap(a0, a1);
- swap(id0, id2);
- swap(id0, id1);
- }
- float c0 = cosf(a0);
- float ratio = (s2 == 0.0f) ? 1.0f : s1 / s2;
- float cosine = c0 * ratio;
- float sine = s0 * ratio;
- // Note : 2*id + 0 --> u
- // 2*id + 1 --> v
- int u0_id = 2 * id0 + 0;
- int v0_id = 2 * id0 + 1;
- int u1_id = 2 * id1 + 0;
- int v1_id = 2 * id1 + 1;
- int u2_id = 2 * id2 + 0;
- int v2_id = 2 * id2 + 1;
- // Real part
- A.setCoefficient(u0_id, 2 * row + 0, cosine - 1.0f);
- A.setCoefficient(v0_id, 2 * row + 0, -sine);
- A.setCoefficient(u1_id, 2 * row + 0, -cosine);
- A.setCoefficient(v1_id, 2 * row + 0, sine);
- A.setCoefficient(u2_id, 2 * row + 0, 1);
- // Imaginary part
- A.setCoefficient(u0_id, 2 * row + 1, sine);
- A.setCoefficient(v0_id, 2 * row + 1, cosine - 1.0f);
- A.setCoefficient(u1_id, 2 * row + 1, -sine);
- A.setCoefficient(v1_id, 2 * row + 1, -cosine);
- A.setCoefficient(v2_id, 2 * row + 1, 1);
+// From OpenNL LSCM example.
+// Computes the coordinates of the vertices of a triangle in a local 2D orthonormal basis of the triangle's plane.
+static void projectTriangle(Vector3 p0, Vector3 p1, Vector3 p2, Vector2 *z0, Vector2 *z1, Vector2 *z2, float epsilon)
+{
+ Vector3 X = normalize(p1 - p0, epsilon);
+ Vector3 Z = normalize(cross(X, p2 - p0), epsilon);
+ Vector3 Y = cross(Z, X);
+ Vector3 &O = p0;
+ *z0 = Vector2(0, 0);
+ *z1 = Vector2(length(p1 - O), 0);
+ *z2 = Vector2(dot(p2 - O, X), dot(p2 - O, Y));
}
static bool computeLeastSquaresConformalMap(Mesh *mesh)
{
- // For this to work properly, mesh should not have colocals that have the same
- // attributes, unless you want the vertices to actually have different texcoords.
- const uint32_t vertexCount = mesh->vertexCount();
- const uint32_t D = 2 * vertexCount;
- const uint32_t N = 2 * mesh->faceCount();
- // N is the number of equations (one per triangle)
- // D is the number of variables (one per vertex; there are 2 pinned vertices).
- if (N < D - 4) {
- return false;
- }
- sparse::Matrix A(D, N);
- FullVector b(N);
- FullVector x(D);
- // Fill b:
- b.fill(0.0f);
- // Fill x:
- uint32_t v0, v1;
- if (!findApproximateDiameterVertices(mesh, &v0, &v1)) {
+ uint32_t lockedVertex0, lockedVertex1;
+ if (!findApproximateDiameterVertices(mesh, &lockedVertex0, &lockedVertex1)) {
// Mesh has no boundaries.
return false;
}
- if (mesh->texcoord(v0) == mesh->texcoord(v1)) {
- // LSCM expects an existing parameterization.
+ const uint32_t vertexCount = mesh->vertexCount();
+ opennl::NLContext *context = opennl::nlNewContext();
+ opennl::nlSolverParameteri(context, NL_NB_VARIABLES, int(2 * vertexCount));
+ opennl::nlSolverParameteri(context, NL_MAX_ITERATIONS, int(5 * vertexCount));
+ opennl::nlBegin(context, NL_SYSTEM);
+ const Vector2 *texcoords = mesh->texcoords();
+ for (uint32_t i = 0; i < vertexCount; i++) {
+ opennl::nlSetVariable(context, 2 * i, texcoords[i].x);
+ opennl::nlSetVariable(context, 2 * i + 1, texcoords[i].y);
+ if (i == lockedVertex0 || i == lockedVertex1) {
+ opennl::nlLockVariable(context, 2 * i);
+ opennl::nlLockVariable(context, 2 * i + 1);
+ }
+ }
+ opennl::nlBegin(context, NL_MATRIX);
+ const uint32_t faceCount = mesh->faceCount();
+ const Vector3 *positions = mesh->positions();
+ const uint32_t *indices = mesh->indices();
+ for (uint32_t f = 0; f < faceCount; f++) {
+ const uint32_t v0 = indices[f * 3 + 0];
+ const uint32_t v1 = indices[f * 3 + 1];
+ const uint32_t v2 = indices[f * 3 + 2];
+ Vector2 z0, z1, z2;
+ projectTriangle(positions[v0], positions[v1], positions[v2], &z0, &z1, &z2, mesh->epsilon());
+ double a = z1.x - z0.x;
+ double b = z1.y - z0.y;
+ double c = z2.x - z0.x;
+ double d = z2.y - z0.y;
+ XA_DEBUG_ASSERT(b == 0.0);
+ // Note : 2*id + 0 --> u
+ // 2*id + 1 --> v
+ uint32_t u0_id = 2 * v0;
+ uint32_t v0_id = 2 * v0 + 1;
+ uint32_t u1_id = 2 * v1;
+ uint32_t v1_id = 2 * v1 + 1;
+ uint32_t u2_id = 2 * v2;
+ uint32_t v2_id = 2 * v2 + 1;
+ // Note : b = 0
+ // Real part
+ opennl::nlBegin(context, NL_ROW);
+ opennl::nlCoefficient(context, u0_id, -a+c) ;
+ opennl::nlCoefficient(context, v0_id, b-d) ;
+ opennl::nlCoefficient(context, u1_id, -c) ;
+ opennl::nlCoefficient(context, v1_id, d) ;
+ opennl::nlCoefficient(context, u2_id, a);
+ opennl::nlEnd(context, NL_ROW);
+ // Imaginary part
+ opennl::nlBegin(context, NL_ROW);
+ opennl::nlCoefficient(context, u0_id, -b+d);
+ opennl::nlCoefficient(context, v0_id, -a+c);
+ opennl::nlCoefficient(context, u1_id, -d);
+ opennl::nlCoefficient(context, v1_id, -c);
+ opennl::nlCoefficient(context, v2_id, a);
+ opennl::nlEnd(context, NL_ROW);
+ }
+ opennl::nlEnd(context, NL_MATRIX);
+ opennl::nlEnd(context, NL_SYSTEM);
+ if (!opennl::nlSolve(context)) {
+ opennl::nlDeleteContext(context);
return false;
}
- for (uint32_t v = 0; v < vertexCount; v++) {
- // Initial solution.
- x[2 * v + 0] = mesh->texcoord(v).x;
- x[2 * v + 1] = mesh->texcoord(v).y;
- }
- // Fill A:
- const uint32_t faceCount = mesh->faceCount();
- for (uint32_t f = 0, t = 0; f < faceCount; f++) {
- const uint32_t vertex0 = mesh->vertexAt(f * 3 + 0);
- const uint32_t vertex1 = mesh->vertexAt(f * 3 + 1);
- const uint32_t vertex2 = mesh->vertexAt(f * 3 + 2);
- setup_abf_relations(A, t, vertex0, vertex1, vertex2, mesh->position(vertex0), mesh->position(vertex1), mesh->position(vertex2));
- t++;
- }
- const uint32_t lockedParameters[] = {
- 2 * v0 + 0,
- 2 * v0 + 1,
- 2 * v1 + 0,
- 2 * v1 + 1
- };
- // Solve
- Solver::LeastSquaresSolver(A, b, x, lockedParameters, 4, 0.000001f);
- // Map x back to texcoords:
- for (uint32_t v = 0; v < vertexCount; v++) {
- mesh->texcoord(v) = Vector2(x[2 * v + 0], x[2 * v + 1]);
- XA_DEBUG_ASSERT(!isNan(mesh->texcoord(v).x));
- XA_DEBUG_ASSERT(!isNan(mesh->texcoord(v).y));
+ for (uint32_t i = 0; i < vertexCount; i++) {
+ const double u = opennl::nlGetVariable(context, 2 * i);
+ const double v = opennl::nlGetVariable(context, 2 * i + 1);
+ mesh->texcoord(i) = Vector2((float)u, (float)v);
+ XA_DEBUG_ASSERT(!isNan(mesh->texcoord(i).x));
+ XA_DEBUG_ASSERT(!isNan(mesh->texcoord(i).y));
}
+ opennl::nlDeleteContext(context);
return true;
}
@@ -6123,12 +6712,13 @@ struct PiecewiseParam
const uint32_t vertexCount = m_mesh->vertexCount();
m_texcoords.resize(vertexCount);
m_patch.reserve(m_faceCount);
- m_faceAssigned.resize(m_faceCount);
- m_faceAssigned.zeroOutMemory();
+ m_candidates.reserve(m_faceCount);
+ m_faceInAnyPatch.resize(m_faceCount);
+ m_faceInAnyPatch.zeroOutMemory();
m_faceInvalid.resize(m_faceCount);
m_faceInPatch.resize(m_faceCount);
m_vertexInPatch.resize(vertexCount);
- m_faceInCandidates.resize(m_faceCount);
+ m_faceToCandidate.resize(m_faceCount);
}
ConstArrayView<uint32_t> chartFaces() const { return m_patch; }
@@ -6136,19 +6726,20 @@ struct PiecewiseParam
bool computeChart()
{
+ // Clear per-patch state.
m_patch.clear();
+ m_candidates.clear();
+ m_faceToCandidate.zeroOutMemory();
m_faceInvalid.zeroOutMemory();
m_faceInPatch.zeroOutMemory();
m_vertexInPatch.zeroOutMemory();
// Add the seed face (first unassigned face) to the patch.
uint32_t seed = UINT32_MAX;
for (uint32_t f = 0; f < m_faceCount; f++) {
- if (m_faceAssigned.get(f))
+ if (m_faceInAnyPatch.get(f))
continue;
seed = f;
- m_patch.push_back(seed);
- m_faceInPatch.set(seed);
- m_faceAssigned.set(seed);
+ // Add all 3 vertices.
Vector2 texcoords[3];
orthoProjectFace(seed, texcoords);
for (uint32_t i = 0; i < 3; i++) {
@@ -6156,86 +6747,94 @@ struct PiecewiseParam
m_vertexInPatch.set(vertex);
m_texcoords[vertex] = texcoords[i];
}
+ addFaceToPatch(seed);
+ // Initialize the boundary grid.
+ m_boundaryGrid.reset(m_texcoords.data(), m_mesh->indices());
+ for (Mesh::FaceEdgeIterator it(m_mesh, seed); !it.isDone(); it.advance())
+ m_boundaryGrid.append(it.edge());
break;
}
if (seed == UINT32_MAX)
return false;
for (;;) {
- findCandidates();
- if (m_candidates.isEmpty())
- break;
- for (;;) {
- // Find the candidate with the lowest cost.
- float lowestCost = FLT_MAX;
- uint32_t bestCandidate = UINT32_MAX;
- for (uint32_t i = 0; i < m_candidates.size(); i++) {
- const Candidate &candidate = m_candidates[i];
- if (m_faceInvalid.get(candidate.face)) // A candidate face may be invalidated after is was added.
- continue;
- if (candidate.maxCost < lowestCost) {
- lowestCost = candidate.maxCost;
- bestCandidate = i;
- }
+ // Find the candidate with the lowest cost.
+ float lowestCost = FLT_MAX;
+ Candidate *bestCandidate = nullptr;
+ for (uint32_t i = 0; i < m_candidates.size(); i++) {
+ Candidate *candidate = m_candidates[i];
+ if (candidate->maxCost < lowestCost) {
+ lowestCost = candidate->maxCost;
+ bestCandidate = candidate;
}
- if (bestCandidate == UINT32_MAX)
+ }
+ if (!bestCandidate)
+ break;
+ XA_DEBUG_ASSERT(!bestCandidate->prev); // Must be head of linked candidates.
+ // Compute the position by averaging linked candidates (candidates that share the same free vertex).
+ Vector2 position(0.0f);
+ uint32_t n = 0;
+ for (CandidateIterator it(bestCandidate); !it.isDone(); it.advance()) {
+ position += it.current()->position;
+ n++;
+ }
+ position *= 1.0f / (float)n;
+ const uint32_t freeVertex = bestCandidate->vertex;
+ XA_DEBUG_ASSERT(!isNan(position.x));
+ XA_DEBUG_ASSERT(!isNan(position.y));
+ m_texcoords[freeVertex] = position;
+ // Check for flipped faces. This is also done when candidates are first added, but the averaged position of the free vertex is different now, so check again.
+ bool invalid = false;
+ for (CandidateIterator it(bestCandidate); !it.isDone(); it.advance()) {
+ const uint32_t vertex0 = m_mesh->vertexAt(meshEdgeIndex0(it.current()->patchEdge));
+ const uint32_t vertex1 = m_mesh->vertexAt(meshEdgeIndex1(it.current()->patchEdge));
+ const float freeVertexOrient = orientToEdge(m_texcoords[vertex0], m_texcoords[vertex1], position);
+ if ((it.current()->patchVertexOrient < 0.0f && freeVertexOrient < 0.0f) || (it.current()->patchVertexOrient > 0.0f && freeVertexOrient > 0.0f)) {
+ invalid = true;
break;
- // Compute the position by averaging linked candidates (candidates that share the same free vertex).
- Vector2 position(0.0f);
- uint32_t n = 0;
- for (CandidateIterator it(m_candidates, bestCandidate); !it.isDone(); it.advance()) {
- position += it.current().position;
- n++;
- }
- position *= 1.0f / (float)n;
- const uint32_t freeVertex = m_candidates[bestCandidate].vertex;
- XA_DEBUG_ASSERT(!isNan(position.x));
- XA_DEBUG_ASSERT(!isNan(position.y));
- m_texcoords[freeVertex] = position;
- // Check for flipped faces. This is also done when candidates are first added, but the averaged position of the free vertex is different now, so check again.
- bool invalid = false;
- for (CandidateIterator it(m_candidates, bestCandidate); !it.isDone(); it.advance()) {
- const uint32_t vertex0 = m_mesh->vertexAt(meshEdgeIndex0(it.current().patchEdge));
- const uint32_t vertex1 = m_mesh->vertexAt(meshEdgeIndex1(it.current().patchEdge));
- const float freeVertexOrient = orientToEdge(m_texcoords[vertex0], m_texcoords[vertex1], position);
- if ((it.current().patchVertexOrient < 0.0f && freeVertexOrient < 0.0f) || (it.current().patchVertexOrient > 0.0f && freeVertexOrient > 0.0f)) {
- invalid = true;
- break;
- }
}
- // Check for boundary intersection.
- if (!invalid) {
- m_boundaryGrid.reset(m_texcoords.data(), m_mesh->indices());
- // Add edges on the patch boundary to the grid.
- // Temporarily adding candidate faces to the patch makes it simpler to detect which edges are on the boundary.
- const uint32_t oldPatchSize = m_patch.size();
- for (CandidateIterator it(m_candidates, bestCandidate); !it.isDone(); it.advance())
- m_patch.push_back(it.current().face);
- for (uint32_t i = 0; i < m_patch.size(); i++) {
- for (Mesh::FaceEdgeIterator it(m_mesh, m_patch[i]); !it.isDone(); it.advance()) {
- const uint32_t oface = it.oppositeFace();
- if (oface == UINT32_MAX || oface >= m_faceCount || !m_faceInPatch.get(oface))
- m_boundaryGrid.append(it.edge());
- }
+ }
+ // Check for boundary intersection.
+ if (!invalid) {
+ XA_PROFILE_START(parameterizeChartsPiecewiseBoundaryIntersection)
+ // Test candidate edges that would form part of the new patch boundary.
+ // Ignore boundary edges that would become internal if the candidate faces were added to the patch.
+ Array<uint32_t> newBoundaryEdges, ignoreEdges;
+ for (CandidateIterator candidateIt(bestCandidate); !candidateIt.isDone(); candidateIt.advance()) {
+ for (Mesh::FaceEdgeIterator it(m_mesh, candidateIt.current()->face); !it.isDone(); it.advance()) {
+ const uint32_t oface = it.oppositeFace();
+ if (oface == UINT32_MAX || oface >= m_faceCount || !m_faceInPatch.get(oface))
+ newBoundaryEdges.push_back(it.edge());
+ if (oface != UINT32_MAX && oface < m_faceCount && m_faceInPatch.get(oface))
+ ignoreEdges.push_back(it.oppositeEdge());
}
- invalid = m_boundaryGrid.intersectSelf(m_mesh->epsilon());
- m_patch.resize(oldPatchSize);
- }
- if (invalid) {
- // Mark all faces of linked candidates as invalid.
- for (CandidateIterator it(m_candidates, bestCandidate); !it.isDone(); it.advance())
- m_faceInvalid.set(it.current().face);
- continue;
- }
- // Add faces to the patch.
- for (CandidateIterator it(m_candidates, bestCandidate); !it.isDone(); it.advance()) {
- m_patch.push_back(it.current().face);
- m_faceInPatch.set(it.current().face);
- m_faceAssigned.set(it.current().face);
}
+ invalid = m_boundaryGrid.intersect(m_mesh->epsilon(), newBoundaryEdges, ignoreEdges);
+ XA_PROFILE_END(parameterizeChartsPiecewiseBoundaryIntersection)
+ }
+ if (invalid) {
+ // Mark all faces of linked candidates as invalid.
+ for (CandidateIterator it(bestCandidate); !it.isDone(); it.advance())
+ m_faceInvalid.set(it.current()->face);
+ removeLinkedCandidates(bestCandidate);
+ } else {
// Add vertex to the patch.
m_vertexInPatch.set(freeVertex);
+ // Add faces to the patch.
+ for (CandidateIterator it(bestCandidate); !it.isDone(); it.advance())
+ addFaceToPatch(it.current()->face);
// Successfully added candidate face(s) to patch.
- break;
+ removeLinkedCandidates(bestCandidate);
+ // Reset the grid with all edges on the patch boundary.
+ XA_PROFILE_START(parameterizeChartsPiecewiseBoundaryIntersection)
+ m_boundaryGrid.reset(m_texcoords.data(), m_mesh->indices());
+ for (uint32_t i = 0; i < m_patch.size(); i++) {
+ for (Mesh::FaceEdgeIterator it(m_mesh, m_patch[i]); !it.isDone(); it.advance()) {
+ const uint32_t oface = it.oppositeFace();
+ if (oface == UINT32_MAX || oface >= m_faceCount || !m_faceInPatch.get(oface))
+ m_boundaryGrid.append(it.edge());
+ }
+ }
+ XA_PROFILE_END(parameterizeChartsPiecewiseBoundaryIntersection)
}
}
return true;
@@ -6245,7 +6844,7 @@ private:
struct Candidate
{
uint32_t face, vertex;
- uint32_t next; // The next candidate with the same vertex.
+ Candidate *prev, *next; // The previous/next candidate with the same vertex.
Vector2 position;
float cost;
float maxCost; // Of all linked candidates.
@@ -6255,88 +6854,68 @@ private:
struct CandidateIterator
{
- CandidateIterator(Array<Candidate> &candidates, uint32_t first) : m_candidates(candidates), m_current(first) {}
- void advance() { if (m_current != UINT32_MAX) m_current = m_candidates[m_current].next; }
- bool isDone() const { return m_current == UINT32_MAX; }
- Candidate &current() { return m_candidates[m_current]; }
+ CandidateIterator(Candidate *head) : m_current(head) { XA_DEBUG_ASSERT(!head->prev); }
+ void advance() { if (m_current != nullptr) { m_current = m_current->next; } }
+ bool isDone() const { return !m_current; }
+ Candidate *current() { return m_current; }
private:
- Array<Candidate> &m_candidates;
- uint32_t m_current;
+ Candidate *m_current;
};
const Mesh *m_mesh;
uint32_t m_faceCount;
Array<Vector2> m_texcoords;
- Array<Candidate> m_candidates;
- BitArray m_faceInCandidates;
- Array<uint32_t> m_patch;
- BitArray m_faceAssigned; // Face is assigned to a previous chart or the current patch.
- BitArray m_faceInPatch, m_vertexInPatch;
+ BitArray m_faceInAnyPatch; // Face is in a previous chart patch or the current patch.
+ Array<Candidate *> m_candidates; // Incident faces to the patch.
+ Array<Candidate *> m_faceToCandidate;
+ Array<uint32_t> m_patch; // The current chart patch.
+ BitArray m_faceInPatch, m_vertexInPatch; // Face/vertex is in the current patch.
BitArray m_faceInvalid; // Face cannot be added to the patch - flipped, cost too high or causes boundary intersection.
UniformGrid2 m_boundaryGrid;
- // Find candidate faces on the patch front.
- void findCandidates()
- {
- m_candidates.clear();
- m_faceInCandidates.zeroOutMemory();
- for (uint32_t i = 0; i < m_patch.size(); i++) {
- for (Mesh::FaceEdgeIterator it(m_mesh, m_patch[i]); !it.isDone(); it.advance()) {
- const uint32_t oface = it.oppositeFace();
- if (oface == UINT32_MAX || oface >= m_faceCount || m_faceAssigned.get(oface) || m_faceInCandidates.get(oface))
- continue;
- // Found an active edge on the patch front.
- // Find the free vertex (the vertex that isn't on the active edge).
- // Compute the orientation of the other patch face vertex to the active edge.
- uint32_t freeVertex = UINT32_MAX;
- float orient = 0.0f;
- for (uint32_t j = 0; j < 3; j++) {
- const uint32_t vertex = m_mesh->vertexAt(oface * 3 + j);
- if (vertex != it.vertex0() && vertex != it.vertex1()) {
- freeVertex = vertex;
- orient = orientToEdge(m_texcoords[it.vertex0()], m_texcoords[it.vertex1()], m_texcoords[m_mesh->vertexAt(m_patch[i] * 3 + j)]);
- break;
- }
- }
- XA_DEBUG_ASSERT(freeVertex != UINT32_MAX);
- // If the free vertex is already in the patch, the face is enclosed by the patch. Add the face to the patch - don't need to assign texcoords.
- if (m_vertexInPatch.get(freeVertex)) {
- freeVertex = UINT32_MAX;
- m_patch.push_back(oface);
- m_faceAssigned.set(oface);
- continue;
- }
- // Check this here rather than above so faces enclosed by the patch are always added.
- if (m_faceInvalid.get(oface))
- continue;
- addCandidateFace(it.edge(), orient, oface, it.oppositeEdge(), freeVertex);
- }
- }
- // Link candidates that share the same vertex.
- for (uint32_t i = 0; i < m_candidates.size(); i++) {
- if (m_candidates[i].next != UINT32_MAX)
+ void addFaceToPatch(uint32_t face)
+ {
+ XA_DEBUG_ASSERT(!m_faceInPatch.get(face));
+ XA_DEBUG_ASSERT(!m_faceInAnyPatch.get(face));
+ m_patch.push_back(face);
+ m_faceInPatch.set(face);
+ m_faceInAnyPatch.set(face);
+ // Find new candidate faces on the patch incident to the newly added face.
+ for (Mesh::FaceEdgeIterator it(m_mesh, face); !it.isDone(); it.advance()) {
+ const uint32_t oface = it.oppositeFace();
+ if (oface == UINT32_MAX || oface >= m_faceCount || m_faceInAnyPatch.get(oface) || m_faceToCandidate[oface])
continue;
- uint32_t current = i;
- for (uint32_t j = i + 1; j < m_candidates.size(); j++) {
- if (m_candidates[j].vertex == m_candidates[current].vertex) {
- m_candidates[current].next = j;
- current = j;
+ // Found an active edge on the patch front.
+ // Find the free vertex (the vertex that isn't on the active edge).
+ // Compute the orientation of the other patch face vertex to the active edge.
+ uint32_t freeVertex = UINT32_MAX;
+ float orient = 0.0f;
+ for (uint32_t j = 0; j < 3; j++) {
+ const uint32_t vertex = m_mesh->vertexAt(oface * 3 + j);
+ if (vertex != it.vertex0() && vertex != it.vertex1()) {
+ freeVertex = vertex;
+ orient = orientToEdge(m_texcoords[it.vertex0()], m_texcoords[it.vertex1()], m_texcoords[m_mesh->vertexAt(face * 3 + j)]);
+ break;
}
}
- }
- // Set max cost for linked candidates.
- for (uint32_t i = 0; i < m_candidates.size(); i++) {
- float maxCost = 0.0f;
- for (CandidateIterator it(m_candidates, i); !it.isDone(); it.advance())
- maxCost = max(maxCost, it.current().cost);
- for (CandidateIterator it(m_candidates, i); !it.isDone(); it.advance())
- it.current().maxCost = maxCost;
+ XA_DEBUG_ASSERT(freeVertex != UINT32_MAX);
+ // If the free vertex is already in the patch, the face is enclosed by the patch. Add the face to the patch - don't need to assign texcoords.
+ /*if (m_vertexInPatch.get(freeVertex)) {
+ freeVertex = UINT32_MAX;
+ addFaceToPatch(oface, false);
+ continue;
+ }*/
+ // Check this here rather than above so faces enclosed by the patch are always added.
+ if (m_faceInvalid.get(oface))
+ continue;
+ addCandidateFace(it.edge(), orient, oface, it.oppositeEdge(), freeVertex);
}
}
void addCandidateFace(uint32_t patchEdge, float patchVertexOrient, uint32_t face, uint32_t edge, uint32_t freeVertex)
{
+ XA_DEBUG_ASSERT(!m_faceToCandidate[face]);
Vector2 texcoords[3];
orthoProjectFace(face, texcoords);
// Find corresponding vertices between the patch edge and candidate edge.
@@ -6357,8 +6936,9 @@ private:
const Vector2 localEdgeVec = texcoords[localVertex1] - texcoords[localVertex0];
const float len1 = length(patchEdgeVec);
const float len2 = length(localEdgeVec);
+ if (len1 <= 0.0f || len2 <= 0.0f)
+ return; // Zero length edge.
const float scale = len1 / len2;
- XA_ASSERT(scale > 0.0f);
for (uint32_t i = 0; i < 3; i++)
texcoords[i] *= scale;
// Translate to the first vertex on the patch edge.
@@ -6380,6 +6960,8 @@ private:
uv.x = x + texcoords[localVertex0].x;
uv.y = y + texcoords[localVertex0].y;
}
+ if (isNan(texcoords[localFreeVertex].x) || isNan(texcoords[localFreeVertex].y))
+ return;
// Check for local overlap (flipped triangle).
// The patch face vertex that isn't on the active edge and the free vertex should be oriented on opposite sides to the active edge.
const float freeVertexOrient = orientToEdge(m_texcoords[vertex0], m_texcoords[vertex1], texcoords[localFreeVertex]);
@@ -6400,16 +6982,68 @@ private:
}
#endif
// Add the candidate.
- Candidate candidate;
- candidate.face = face;
- candidate.vertex = freeVertex;
- candidate.position = texcoords[localFreeVertex];
- candidate.next = UINT32_MAX;
- candidate.cost = cost;
- candidate.patchEdge = patchEdge;
- candidate.patchVertexOrient = patchVertexOrient;
+ Candidate *candidate = XA_ALLOC(MemTag::Default, Candidate);
+ candidate->face = face;
+ candidate->vertex = freeVertex;
+ candidate->position = texcoords[localFreeVertex];
+ candidate->prev = candidate->next = nullptr;
+ candidate->cost = candidate->maxCost = cost;
+ candidate->patchEdge = patchEdge;
+ candidate->patchVertexOrient = patchVertexOrient;
m_candidates.push_back(candidate);
- m_faceInCandidates.set(face);
+ m_faceToCandidate[face] = candidate;
+ // Link with candidates that share the same vertex. Append to tail.
+ for (uint32_t i = 0; i < m_candidates.size() - 1; i++) {
+ if (m_candidates[i]->vertex == candidate->vertex) {
+ Candidate *tail = m_candidates[i];
+ for (;;) {
+ if (tail->next)
+ tail = tail->next;
+ else
+ break;
+ }
+ candidate->prev = tail;
+ candidate->next = nullptr;
+ tail->next = candidate;
+ break;
+ }
+ }
+ // Set max cost for linked candidates.
+ Candidate *head = linkedCandidateHead(candidate);
+ float maxCost = 0.0f;
+ for (CandidateIterator it(head); !it.isDone(); it.advance())
+ maxCost = max(maxCost, it.current()->cost);
+ for (CandidateIterator it(head); !it.isDone(); it.advance())
+ it.current()->maxCost = maxCost;
+ }
+
+ Candidate *linkedCandidateHead(Candidate *candidate)
+ {
+ Candidate *current = candidate;
+ for (;;) {
+ if (!current->prev)
+ break;
+ current = current->prev;
+ }
+ return current;
+ }
+
+ void removeLinkedCandidates(Candidate *head)
+ {
+ XA_DEBUG_ASSERT(!head->prev);
+ Candidate *current = head;
+ while (current) {
+ Candidate *next = current->next;
+ m_faceToCandidate[current->face] = nullptr;
+ for (uint32_t i = 0; i < m_candidates.size(); i++) {
+ if (m_candidates[i] == current) {
+ m_candidates.removeAt(i);
+ break;
+ }
+ }
+ XA_FREE(current);
+ current = next;
+ }
}
void orthoProjectFace(uint32_t face, Vector2 *texcoords) const
@@ -6479,7 +7113,7 @@ struct Quality
boundaryGrid.reset(mesh->texcoords(), mesh->indices(), boundaryEdgeCount);
for (uint32_t i = 0; i < boundaryEdgeCount; i++)
boundaryGrid.append(boundaryEdges[i]);
- boundaryIntersection = boundaryGrid.intersectSelf(mesh->epsilon());
+ boundaryIntersection = boundaryGrid.intersect(mesh->epsilon());
#if XA_DEBUG_EXPORT_BOUNDARY_GRID
static int exportIndex = 0;
char filename[256];
@@ -6636,41 +7270,34 @@ struct ChartCtorBuffers
Array<uint32_t> boundaryLoops;
};
-/// A chart is a connected set of faces with a certain topology (usually a disk).
class Chart
{
public:
- Chart(ChartCtorBuffers &buffers, const Basis &basis, ConstArrayView<uint32_t> faces, const Mesh *originalMesh, uint32_t meshId, uint32_t chartGroupId, uint32_t chartId) : m_basis(basis), m_mesh(nullptr), m_unifiedMesh(nullptr), m_unmodifiedUnifiedMesh(nullptr), m_type(ChartType::LSCM), m_warningFlags(0), m_closedHolesCount(0), m_fixedTJunctionsCount(0)
+ Chart(ChartCtorBuffers &buffers, const ParameterizeOptions &options, const Basis &basis, ConstArrayView<uint32_t> faces, const Mesh *sourceMesh, uint32_t chartGroupId, uint32_t chartId) : m_basis(basis), m_mesh(nullptr), m_unifiedMesh(nullptr), m_unmodifiedUnifiedMesh(nullptr), m_type(ChartType::LSCM), m_warningFlags(0), m_closedHolesCount(0), m_fixedTJunctionsCount(0), m_isInvalid(false)
{
- XA_UNUSED(meshId);
XA_UNUSED(chartGroupId);
XA_UNUSED(chartId);
- m_faceArray.copyFrom(faces.data, faces.length);
- // Copy face indices.
- m_mesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, originalMesh->epsilon(), m_faceArray.size() * 3, m_faceArray.size());
- m_unifiedMesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, originalMesh->epsilon(), m_faceArray.size() * 3, m_faceArray.size());
- Array<uint32_t> &chartMeshIndices = buffers.chartMeshIndices;
- chartMeshIndices.resize(originalMesh->vertexCount());
- chartMeshIndices.setAll(UINT32_MAX);
- Array<uint32_t> &unifiedMeshIndices = buffers.unifiedMeshIndices;
- unifiedMeshIndices.resize(originalMesh->vertexCount());
- unifiedMeshIndices.setAll(UINT32_MAX);
+ m_faceToSourceFaceMap.copyFrom(faces.data, faces.length);
+ const uint32_t approxVertexCount = min(faces.length * 3, sourceMesh->vertexCount());
+ m_mesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, sourceMesh->epsilon(), approxVertexCount, faces.length);
+ m_unifiedMesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, sourceMesh->epsilon(), approxVertexCount, faces.length);
+ HashMap<uint32_t, PassthroughHash<uint32_t>> sourceVertexToUnifiedVertexMap(MemTag::Mesh, approxVertexCount), sourceVertexToChartVertexMap(MemTag::Mesh, approxVertexCount);
// Add vertices.
- const uint32_t faceCount = m_initialFaceCount = m_faceArray.size();
+ const uint32_t faceCount = m_initialFaceCount = faces.length;
for (uint32_t f = 0; f < faceCount; f++) {
for (uint32_t i = 0; i < 3; i++) {
- const uint32_t vertex = originalMesh->vertexAt(m_faceArray[f] * 3 + i);
- const uint32_t unifiedVertex = originalMesh->firstColocal(vertex);
- if (unifiedMeshIndices[unifiedVertex] == (uint32_t)~0) {
- unifiedMeshIndices[unifiedVertex] = m_unifiedMesh->vertexCount();
- XA_DEBUG_ASSERT(equal(originalMesh->position(vertex), originalMesh->position(unifiedVertex), originalMesh->epsilon()));
- m_unifiedMesh->addVertex(originalMesh->position(vertex));
+ const uint32_t sourceVertex = sourceMesh->vertexAt(m_faceToSourceFaceMap[f] * 3 + i);
+ const uint32_t sourceUnifiedVertex = sourceMesh->firstColocal(sourceVertex);
+ uint32_t unifiedVertex = sourceVertexToUnifiedVertexMap.get(sourceUnifiedVertex);
+ if (unifiedVertex == UINT32_MAX) {
+ unifiedVertex = sourceVertexToUnifiedVertexMap.add(sourceUnifiedVertex);
+ m_unifiedMesh->addVertex(sourceMesh->position(sourceVertex));
}
- if (chartMeshIndices[vertex] == (uint32_t)~0) {
- chartMeshIndices[vertex] = m_mesh->vertexCount();
- m_chartToOriginalMap.push_back(vertex);
- m_chartToUnifiedMap.push_back(unifiedMeshIndices[unifiedVertex]);
- m_mesh->addVertex(originalMesh->position(vertex), Vector3(0.0f), originalMesh->texcoord(vertex));
+ if (sourceVertexToChartVertexMap.get(sourceVertex) == UINT32_MAX) {
+ sourceVertexToChartVertexMap.add(sourceVertex);
+ m_vertexToSourceVertexMap.push_back(sourceVertex);
+ m_chartVertexToUnifiedVertexMap.push_back(unifiedVertex);
+ m_mesh->addVertex(sourceMesh->position(sourceVertex), Vector3(0.0f), sourceMesh->texcoord(sourceVertex));
}
}
}
@@ -6678,9 +7305,12 @@ public:
for (uint32_t f = 0; f < faceCount; f++) {
uint32_t indices[3], unifiedIndices[3];
for (uint32_t i = 0; i < 3; i++) {
- const uint32_t vertex = originalMesh->vertexAt(m_faceArray[f] * 3 + i);
- indices[i] = chartMeshIndices[vertex];
- unifiedIndices[i] = unifiedMeshIndices[originalMesh->firstColocal(vertex)];
+ const uint32_t sourceVertex = sourceMesh->vertexAt(m_faceToSourceFaceMap[f] * 3 + i);
+ const uint32_t sourceUnifiedVertex = sourceMesh->firstColocal(sourceVertex);
+ indices[i] = sourceVertexToChartVertexMap.get(sourceVertex);
+ XA_DEBUG_ASSERT(indices[i] != UINT32_MAX);
+ unifiedIndices[i] = sourceVertexToUnifiedVertexMap.get(sourceUnifiedVertex);
+ XA_DEBUG_ASSERT(unifiedIndices[i] != UINT32_MAX);
}
Mesh::AddFaceResult::Enum result = m_mesh->addFace(indices);
XA_UNUSED(result);
@@ -6698,15 +7328,18 @@ public:
XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK);
}
m_mesh->createBoundaries(); // For AtlasPacker::computeBoundingBox
+ m_mesh->destroyEdgeMap(); // Only needed it for createBoundaries.
m_unifiedMesh->createBoundaries();
- if (meshIsPlanar(*m_unifiedMesh))
+ if (meshIsPlanar(*m_unifiedMesh)) {
m_type = ChartType::Planar;
- else {
- m_unifiedMesh->linkBoundaries();
+ return;
+ }
+ m_unifiedMesh->linkBoundaries();
#if XA_DEBUG_EXPORT_OBJ_BEFORE_FIX_TJUNCTION
- m_unifiedMesh->writeObjFile("debug_before_fix_tjunction.obj");
+ m_unifiedMesh->writeObjFile("debug_before_fix_tjunction.obj");
#endif
- bool duplicatedEdge = false, failed = false;
+ bool duplicatedEdge = false, failed = false;
+ if (options.fixTJunctions) {
XA_PROFILE_START(fixChartMeshTJunctions)
Mesh *fixedUnifiedMesh = meshFixTJunctions(*m_unifiedMesh, &duplicatedEdge, &failed, &m_fixedTJunctionsCount);
XA_PROFILE_END(fixChartMeshTJunctions)
@@ -6721,6 +7354,8 @@ public:
m_unifiedMesh->linkBoundaries();
m_initialFaceCount = m_unifiedMesh->faceCount(); // Fixing t-junctions rewrites faces.
}
+ }
+ if (options.closeHoles) {
// See if there are any holes that need closing.
Array<uint32_t> &boundaryLoops = buffers.boundaryLoops;
meshGetBoundaryLoops(*m_unifiedMesh, boundaryLoops);
@@ -6751,7 +7386,7 @@ public:
#if XA_DEBUG_EXPORT_OBJ_CLOSE_HOLES_ERROR
if (m_warningFlags & ChartWarningFlags::CloseHolesFailed) {
char filename[256];
- XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_chart_%03u_close_holes_error.obj", meshId, chartGroupId, chartId);
+ XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_chart_%03u_close_holes_error.obj", sourceMesh->id(), chartGroupId, chartId);
FILE *file;
XA_FOPEN(file, filename, "w");
if (file) {
@@ -6780,69 +7415,44 @@ public:
}
#if XA_RECOMPUTE_CHARTS
- Chart(ChartCtorBuffers &buffers, const Chart *parent, const Mesh *parentMesh, ConstArrayView<uint32_t> faces, const Vector2 *texcoords, const Mesh *originalMesh, uint32_t meshId, uint32_t chartGroupId, uint32_t chartId) : m_mesh(nullptr), m_unifiedMesh(nullptr), m_unmodifiedUnifiedMesh(nullptr), m_type(ChartType::Piecewise), m_warningFlags(0), m_closedHolesCount(0), m_fixedTJunctionsCount(0)
+ Chart(ChartCtorBuffers &buffers, const Chart *parent, const Mesh *parentMesh, ConstArrayView<uint32_t> faces, const Vector2 *texcoords, const Mesh *sourceMesh) : m_mesh(nullptr), m_unifiedMesh(nullptr), m_unmodifiedUnifiedMesh(nullptr), m_type(ChartType::Piecewise), m_warningFlags(0), m_closedHolesCount(0), m_fixedTJunctionsCount(0), m_isInvalid(false)
{
- XA_UNUSED(meshId);
- XA_UNUSED(chartGroupId);
- XA_UNUSED(chartId);
const uint32_t faceCount = m_initialFaceCount = faces.length;
- m_faceArray.resize(faceCount);
+ m_faceToSourceFaceMap.resize(faceCount);
for (uint32_t i = 0; i < faceCount; i++)
- m_faceArray[i] = parent->m_faceArray[faces[i]]; // Map faces to parent chart original mesh.
+ m_faceToSourceFaceMap[i] = parent->m_faceToSourceFaceMap[faces[i]]; // Map faces to parent chart source mesh.
// Copy face indices.
- m_mesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, originalMesh->epsilon(), m_faceArray.size() * 3, m_faceArray.size());
- m_unifiedMesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, originalMesh->epsilon(), m_faceArray.size() * 3, m_faceArray.size());
+ m_mesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, sourceMesh->epsilon(), m_faceToSourceFaceMap.size() * 3, m_faceToSourceFaceMap.size());
Array<uint32_t> &chartMeshIndices = buffers.chartMeshIndices;
- chartMeshIndices.resize(originalMesh->vertexCount());
- chartMeshIndices.setAll(UINT32_MAX);
- Array<uint32_t> &unifiedMeshIndices = buffers.unifiedMeshIndices;
- unifiedMeshIndices.resize(originalMesh->vertexCount());
- unifiedMeshIndices.setAll(UINT32_MAX);
+ chartMeshIndices.resize(sourceMesh->vertexCount());
+ chartMeshIndices.fillBytes(0xff);
// Add vertices.
for (uint32_t f = 0; f < faceCount; f++) {
for (uint32_t i = 0; i < 3; i++) {
- const uint32_t vertex = originalMesh->vertexAt(m_faceArray[f] * 3 + i);
- const uint32_t unifiedVertex = originalMesh->firstColocal(vertex);
+ const uint32_t vertex = sourceMesh->vertexAt(m_faceToSourceFaceMap[f] * 3 + i);
const uint32_t parentVertex = parentMesh->vertexAt(faces[f] * 3 + i);
- if (unifiedMeshIndices[unifiedVertex] == (uint32_t)~0) {
- unifiedMeshIndices[unifiedVertex] = m_unifiedMesh->vertexCount();
- XA_DEBUG_ASSERT(equal(originalMesh->position(vertex), originalMesh->position(unifiedVertex), originalMesh->epsilon()));
- m_unifiedMesh->addVertex(originalMesh->position(vertex), Vector3(0.0f), texcoords[parentVertex]);
- }
if (chartMeshIndices[vertex] == (uint32_t)~0) {
chartMeshIndices[vertex] = m_mesh->vertexCount();
- m_chartToOriginalMap.push_back(vertex);
- m_chartToUnifiedMap.push_back(unifiedMeshIndices[unifiedVertex]);
- m_mesh->addVertex(originalMesh->position(vertex), Vector3(0.0f), texcoords[parentVertex]);
+ m_vertexToSourceVertexMap.push_back(vertex);
+ m_mesh->addVertex(sourceMesh->position(vertex), Vector3(0.0f), texcoords[parentVertex]);
}
}
}
// Add faces.
for (uint32_t f = 0; f < faceCount; f++) {
- uint32_t indices[3], unifiedIndices[3];
+ uint32_t indices[3];
for (uint32_t i = 0; i < 3; i++) {
- const uint32_t vertex = originalMesh->vertexAt(m_faceArray[f] * 3 + i);
+ const uint32_t vertex = sourceMesh->vertexAt(m_faceToSourceFaceMap[f] * 3 + i);
indices[i] = chartMeshIndices[vertex];
- unifiedIndices[i] = unifiedMeshIndices[originalMesh->firstColocal(vertex)];
}
Mesh::AddFaceResult::Enum result = m_mesh->addFace(indices);
XA_UNUSED(result);
XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK);
-#if XA_DEBUG
- // Unifying colocals may create degenerate edges. e.g. if two triangle vertices are colocal.
- for (int i = 0; i < 3; i++) {
- const uint32_t index1 = unifiedIndices[i];
- const uint32_t index2 = unifiedIndices[(i + 1) % 3];
- XA_DEBUG_ASSERT(index1 != index2);
- }
-#endif
- result = m_unifiedMesh->addFace(unifiedIndices);
- XA_UNUSED(result);
- XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK);
}
m_mesh->createBoundaries(); // For AtlasPacker::computeBoundingBox
- m_unifiedMesh->createBoundaries();
- m_unifiedMesh->linkBoundaries();
+ m_mesh->destroyEdgeMap(); // Only needed it for createBoundaries.
+ // Need to store texcoords for backup/restore so packing can be run multiple times.
+ backupTexcoords();
}
#endif
@@ -6852,17 +7462,10 @@ public:
m_mesh->~Mesh();
XA_FREE(m_mesh);
}
- if (m_unifiedMesh) {
- m_unifiedMesh->~Mesh();
- XA_FREE(m_unifiedMesh);
- }
- if (m_unmodifiedUnifiedMesh) {
- m_unmodifiedUnifiedMesh->~Mesh();
- XA_FREE(m_unmodifiedUnifiedMesh);
- }
+ destroyUnifiedMesh();
}
- const Basis &basis() const { return m_basis; }
+ bool isInvalid() const { return m_isInvalid; }
ChartType::Enum type() const { return m_type; }
uint32_t warningFlags() const { return m_warningFlags; }
uint32_t closedHolesCount() const { return m_closedHolesCount; }
@@ -6872,45 +7475,67 @@ public:
#if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION
const Array<uint32_t> &paramFlippedFaces() const { return m_paramFlippedFaces; }
#endif
- uint32_t mapFaceToSourceFace(uint32_t i) const { return m_faceArray[i]; }
+ uint32_t mapFaceToSourceFace(uint32_t i) const { return m_faceToSourceFaceMap[i]; }
+ uint32_t mapChartVertexToSourceVertex(uint32_t i) const { return m_vertexToSourceVertexMap[i]; }
const Mesh *mesh() const { return m_mesh; }
Mesh *mesh() { return m_mesh; }
const Mesh *unifiedMesh() const { return m_unifiedMesh; }
- Mesh *unifiedMesh() { return m_unifiedMesh; }
const Mesh *unmodifiedUnifiedMesh() const { return m_unmodifiedUnifiedMesh; }
- uint32_t mapChartVertexToOriginalVertex(uint32_t i) const { return m_chartToOriginalMap[i]; }
-
- void evaluateOrthoQuality(UniformGrid2 &boundaryGrid)
- {
- XA_PROFILE_START(parameterizeChartsEvaluateQuality)
- m_quality.computeBoundaryIntersection(m_unifiedMesh, boundaryGrid);
- m_quality.computeFlippedFaces(m_unifiedMesh, m_initialFaceCount, nullptr);
- m_quality.computeMetrics(m_unifiedMesh, m_initialFaceCount);
- XA_PROFILE_END(parameterizeChartsEvaluateQuality)
- // Use orthogonal parameterization if quality is acceptable.
- if (!m_quality.boundaryIntersection && m_quality.totalGeometricArea > 0.0f && m_quality.stretchMetric <= 1.1f && m_quality.maxStretchMetric <= 1.25f)
- m_type = ChartType::Ortho;
- }
- void evaluateQuality(UniformGrid2 &boundaryGrid)
+ void parameterize(const ParameterizeOptions &options, UniformGrid2 &boundaryGrid)
{
- XA_PROFILE_START(parameterizeChartsEvaluateQuality)
- m_quality.computeBoundaryIntersection(m_unifiedMesh, boundaryGrid);
+ XA_PROFILE_START(parameterizeChartsOrthogonal)
+ {
+ // Project vertices to plane.
+ const uint32_t vertexCount = m_unifiedMesh->vertexCount();
+ for (uint32_t i = 0; i < vertexCount; i++)
+ m_unifiedMesh->texcoord(i) = Vector2(dot(m_basis.tangent, m_unifiedMesh->position(i)), dot(m_basis.bitangent, m_unifiedMesh->position(i)));
+ }
+ XA_PROFILE_END(parameterizeChartsOrthogonal)
+ // Computing charts checks for flipped triangles and boundary intersection. Don't need to do that again here if chart is planar.
+ if (m_type != ChartType::Planar) {
+ XA_PROFILE_START(parameterizeChartsEvaluateQuality)
+ m_quality.computeBoundaryIntersection(m_unifiedMesh, boundaryGrid);
+ m_quality.computeFlippedFaces(m_unifiedMesh, m_initialFaceCount, nullptr);
+ m_quality.computeMetrics(m_unifiedMesh, m_initialFaceCount);
+ XA_PROFILE_END(parameterizeChartsEvaluateQuality)
+ // Use orthogonal parameterization if quality is acceptable.
+ if (!m_quality.boundaryIntersection && m_quality.flippedTriangleCount == 0 && m_quality.totalGeometricArea > 0.0f && m_quality.stretchMetric <= 1.1f && m_quality.maxStretchMetric <= 1.25f)
+ m_type = ChartType::Ortho;
+ }
+ if (m_type == ChartType::LSCM) {
+ XA_PROFILE_START(parameterizeChartsLSCM)
+ if (options.func) {
+ options.func(&m_unifiedMesh->position(0).x, &m_unifiedMesh->texcoord(0).x, m_unifiedMesh->vertexCount(), m_unifiedMesh->indices(), m_unifiedMesh->indexCount());
+ }
+ else
+ computeLeastSquaresConformalMap(m_unifiedMesh);
+ XA_PROFILE_END(parameterizeChartsLSCM)
+ XA_PROFILE_START(parameterizeChartsEvaluateQuality)
+ m_quality.computeBoundaryIntersection(m_unifiedMesh, boundaryGrid);
#if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION
- m_quality.computeFlippedFaces(m_unifiedMesh, m_initialFaceCount, &m_paramFlippedFaces);
+ m_quality.computeFlippedFaces(m_unifiedMesh, m_initialFaceCount, &m_paramFlippedFaces);
#else
- m_quality.computeFlippedFaces(m_unifiedMesh, m_initialFaceCount, nullptr);
+ m_quality.computeFlippedFaces(m_unifiedMesh, m_initialFaceCount, nullptr);
#endif
- // Don't need to call computeMetrics here, that's only used in evaluateOrthoQuality to determine if quality is acceptable enough to use ortho projection.
- XA_PROFILE_END(parameterizeChartsEvaluateQuality)
- }
-
- // Transfer parameterization from unified mesh to chart mesh.
- void transferParameterization()
- {
+ // Don't need to call computeMetrics here, that's only used in evaluateOrthoQuality to determine if quality is acceptable enough to use ortho projection.
+ if (m_quality.boundaryIntersection || m_quality.flippedTriangleCount > 0)
+ m_isInvalid = true;
+ XA_PROFILE_END(parameterizeChartsEvaluateQuality)
+ }
+#if XA_DEBUG_ALL_CHARTS_INVALID
+ m_isInvalid = true;
+#endif
+ // Transfer parameterization from unified mesh to chart mesh.
const uint32_t vertexCount = m_mesh->vertexCount();
for (uint32_t v = 0; v < vertexCount; v++)
- m_mesh->texcoord(v) = m_unifiedMesh->texcoord(m_chartToUnifiedMap[v]);
+ m_mesh->texcoord(v) = m_unifiedMesh->texcoord(m_chartVertexToUnifiedVertexMap[v]);
+ // Can destroy unified mesh now.
+ // But not if the parameterization is invalid, the unified mesh will be needed for PiecewiseParameterization.
+ if (!m_isInvalid)
+ destroyUnifiedMesh();
+ // Need to store texcoords for backup/restore so packing can be run multiple times.
+ backupTexcoords();
}
Vector2 computeParametricBounds() const
@@ -6925,7 +7550,34 @@ public:
return (maxCorner - minCorner) * 0.5f;
}
+ void restoreTexcoords()
+ {
+ memcpy(m_mesh->texcoords(), m_backupTexcoords.data(), m_mesh->vertexCount() * sizeof(Vector2));
+ }
+
private:
+ void backupTexcoords()
+ {
+ m_backupTexcoords.resize(m_mesh->vertexCount());
+ memcpy(m_backupTexcoords.data(), m_mesh->texcoords(), m_mesh->vertexCount() * sizeof(Vector2));
+ }
+
+ void destroyUnifiedMesh()
+ {
+ if (m_unifiedMesh) {
+ m_unifiedMesh->~Mesh();
+ XA_FREE(m_unifiedMesh);
+ m_unifiedMesh = nullptr;
+ }
+ if (m_unmodifiedUnifiedMesh) {
+ m_unmodifiedUnifiedMesh->~Mesh();
+ XA_FREE(m_unmodifiedUnifiedMesh);
+ m_unmodifiedUnifiedMesh = nullptr;
+ }
+ // Don't need this when unified meshes are destroyed.
+ m_chartVertexToUnifiedVertexMap.destroy();
+ }
+
Basis m_basis;
Mesh *m_mesh;
Mesh *m_unifiedMesh;
@@ -6935,482 +7587,511 @@ private:
uint32_t m_initialFaceCount; // Before fixing T-junctions and/or closing holes.
uint32_t m_closedHolesCount, m_fixedTJunctionsCount;
- // List of faces of the original mesh that belong to this chart.
- Array<uint32_t> m_faceArray;
+ // List of faces of the source mesh that belong to this chart.
+ Array<uint32_t> m_faceToSourceFaceMap;
- // Map vertices of the chart mesh to vertices of the original mesh.
- Array<uint32_t> m_chartToOriginalMap;
+ // Map vertices of the chart mesh to vertices of the source mesh.
+ Array<uint32_t> m_vertexToSourceVertexMap;
- Array<uint32_t> m_chartToUnifiedMap;
+ Array<uint32_t> m_chartVertexToUnifiedVertexMap;
+
+ Array<Vector2> m_backupTexcoords;
Quality m_quality;
#if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION
Array<uint32_t> m_paramFlippedFaces;
#endif
+ bool m_isInvalid;
};
-struct CreateChartTaskArgs
+struct CreateAndParameterizeChartTaskArgs
{
- const Mesh *mesh;
const Basis *basis;
+ ThreadLocal<UniformGrid2> *boundaryGrid;
+ Chart *chart; // output
+ Array<Chart *> charts; // output (if more than one chart)
+ ThreadLocal<ChartCtorBuffers> *chartBuffers;
+ const Mesh *mesh;
+ const ParameterizeOptions *options;
+#if XA_RECOMPUTE_CHARTS
+ ThreadLocal<PiecewiseParam> *pp;
+#endif
ConstArrayView<uint32_t> faces;
- uint32_t meshId;
uint32_t chartGroupId;
uint32_t chartId;
- ThreadLocal<ChartCtorBuffers> *chartBuffers;
- Chart **chart;
};
-static void runCreateChartTask(void *userData)
+static void runCreateAndParameterizeChartTask(void *userData)
{
- XA_PROFILE_START(createChartMeshesThread)
- auto args = (CreateChartTaskArgs *)userData;
- *(args->chart) = XA_NEW_ARGS(MemTag::Default, Chart, args->chartBuffers->get(), *(args->basis), args->faces, args->mesh, args->meshId, args->chartGroupId, args->chartId);
- XA_PROFILE_END(createChartMeshesThread)
-}
-
-struct ParameterizeChartTaskArgs
-{
- Chart *chart;
- ParameterizeFunc func;
- ThreadLocal<UniformGrid2> *boundaryGrid;
-};
-
-static void runParameterizeChartTask(void *userData)
-{
- auto args = (ParameterizeChartTaskArgs *)userData;
- Mesh *mesh = args->chart->unifiedMesh();
- XA_PROFILE_START(parameterizeChartsOrthogonal)
- {
- // Project vertices to plane.
- const uint32_t vertexCount = mesh->vertexCount();
- const Basis &basis = args->chart->basis();
- for (uint32_t i = 0; i < vertexCount; i++)
- mesh->texcoord(i) = Vector2(dot(basis.tangent, mesh->position(i)), dot(basis.bitangent, mesh->position(i)));
- }
- XA_PROFILE_END(parameterizeChartsOrthogonal)
- // Computing charts checks for flipped triangles and boundary intersection. Don't need to do that again here if chart is planar.
- if (args->chart->type() != ChartType::Planar)
- args->chart->evaluateOrthoQuality(args->boundaryGrid->get());
- if (args->chart->type() == ChartType::LSCM) {
- XA_PROFILE_START(parameterizeChartsLSCM)
- if (args->func)
- args->func(&mesh->position(0).x, &mesh->texcoord(0).x, mesh->vertexCount(), mesh->indices(), mesh->indexCount());
- else
- computeLeastSquaresConformalMap(mesh);
- XA_PROFILE_END(parameterizeChartsLSCM)
- args->chart->evaluateQuality(args->boundaryGrid->get());
+ auto args = (CreateAndParameterizeChartTaskArgs *)userData;
+ XA_PROFILE_START(createChartMesh)
+ args->chart = XA_NEW_ARGS(MemTag::Default, Chart, args->chartBuffers->get(), *args->options, *args->basis, args->faces, args->mesh, args->chartGroupId, args->chartId);
+ XA_PROFILE_END(createChartMesh)
+ args->chart->parameterize(*args->options, args->boundaryGrid->get());
+#if XA_RECOMPUTE_CHARTS
+ if (!args->chart->isInvalid())
+ return;
+ // Recompute charts with invalid parameterizations.
+ XA_PROFILE_START(parameterizeChartsRecompute)
+ Chart *invalidChart = args->chart;
+ // Fixing t-junctions rewrites unified mesh faces, and we need to map faces back to input mesh. So use the unmodified unified mesh.
+ const Mesh *invalidMesh = invalidChart->unmodifiedUnifiedMesh();
+ uint32_t faceCount = 0;
+ if (invalidMesh) {
+ faceCount = invalidMesh->faceCount();
+ } else {
+ invalidMesh = invalidChart->unifiedMesh();
+ faceCount = invalidChart->initialFaceCount(); // Not invalidMesh->faceCount(). Don't want faces added by hole closing.
}
- // Transfer parameterization from unified mesh to chart mesh.
- args->chart->transferParameterization();
+ PiecewiseParam &pp = args->pp->get();
+ pp.reset(invalidMesh, faceCount);
+#if XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS
+ char filename[256];
+ XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_chart_%03u_recomputed.obj", args->mesh->id(), args->chartGroupId, args->chartId);
+ FILE *file;
+ XA_FOPEN(file, filename, "w");
+ uint32_t subChartIndex = 0;
+#endif
+ for (;;) {
+ XA_PROFILE_START(parameterizeChartsPiecewise)
+ const bool facesRemaining = pp.computeChart();
+ XA_PROFILE_END(parameterizeChartsPiecewise)
+ if (!facesRemaining)
+ break;
+ Chart *chart = XA_NEW_ARGS(MemTag::Default, Chart, args->chartBuffers->get(), invalidChart, invalidMesh, pp.chartFaces(), pp.texcoords(), args->mesh);
+ args->charts.push_back(chart);
+#if XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS
+ if (file) {
+ for (uint32_t j = 0; j < invalidMesh->vertexCount(); j++) {
+ fprintf(file, "v %g %g %g\n", invalidMesh->position(j).x, invalidMesh->position(j).y, invalidMesh->position(j).z);
+ fprintf(file, "vt %g %g\n", pp.texcoords()[j].x, pp.texcoords()[j].y);
+ }
+ fprintf(file, "o chart%03u\n", subChartIndex);
+ fprintf(file, "s off\n");
+ for (uint32_t f = 0; f < pp.chartFaces().length; f++) {
+ fprintf(file, "f ");
+ const uint32_t face = pp.chartFaces()[f];
+ for (uint32_t j = 0; j < 3; j++) {
+ const uint32_t index = invalidMesh->vertexCount() * subChartIndex + invalidMesh->vertexAt(face * 3 + j) + 1; // 1-indexed
+ fprintf(file, "%d/%d/%c", index, index, j == 2 ? '\n' : ' ');
+ }
+ }
+ }
+ subChartIndex++;
+#endif
+ }
+#if XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS
+ if (file)
+ fclose(file);
+#endif
+ XA_PROFILE_END(parameterizeChartsRecompute)
+#endif // XA_RECOMPUTE_CHARTS
}
// Set of charts corresponding to mesh faces in the same face group.
class ChartGroup
{
public:
- ChartGroup(uint32_t id, const Mesh *sourceMesh, uint16_t faceGroup) : m_sourceId(sourceMesh->id()), m_id(id), m_isVertexMap(faceGroup == Mesh::kInvalidFaceGroup), m_paramAddedChartsCount(0), m_paramDeletedChartsCount(0)
+ ChartGroup(uint32_t id, const Mesh *sourceMesh, const MeshFaceGroups *sourceMeshFaceGroups, MeshFaceGroups::Handle faceGroup) : m_id(id), m_sourceMesh(sourceMesh), m_sourceMeshFaceGroups(sourceMeshFaceGroups), m_faceGroup(faceGroup), m_faceCount(0), m_paramAddedChartsCount(0), m_paramDeletedChartsCount(0)
{
- // Create new mesh from the source mesh, using faces that belong to this group.
- const uint32_t sourceFaceCount = sourceMesh->faceCount();
- if (!m_isVertexMap) {
- m_faceToSourceFaceMap.reserve(sourceMesh->faceGroupFaceCount(faceGroup));
- for (Mesh::GroupFaceIterator it(sourceMesh, faceGroup); !it.isDone(); it.advance())
- m_faceToSourceFaceMap.push_back(it.face());
- } else {
- for (uint32_t f = 0; f < sourceFaceCount; f++) {
- if (sourceMesh->faceGroupAt(f) == faceGroup)
- m_faceToSourceFaceMap.push_back(f);
- }
- }
- // Only initial meshes have face groups and ignored faces. The only flag we care about is HasNormals.
- const uint32_t faceCount = m_faceToSourceFaceMap.size();
- XA_DEBUG_ASSERT(faceCount > 0);
- const uint32_t approxVertexCount = faceCount * 3;
- m_mesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, sourceMesh->epsilon(), approxVertexCount, faceCount, sourceMesh->flags() & MeshFlags::HasNormals);
- m_vertexToSourceVertexMap.reserve(approxVertexCount);
- HashMap<uint32_t> sourceVertexToVertexMap(MemTag::Mesh, approxVertexCount);
- for (uint32_t f = 0; f < faceCount; f++) {
- const uint32_t face = m_faceToSourceFaceMap[f];
- for (uint32_t i = 0; i < 3; i++) {
- const uint32_t vertex = sourceMesh->vertexAt(face * 3 + i);
- if (sourceVertexToVertexMap.get(vertex) == UINT32_MAX) {
- sourceVertexToVertexMap.add(vertex);
- m_vertexToSourceVertexMap.push_back(vertex);
- Vector3 normal(0.0f);
- if (sourceMesh->flags() & MeshFlags::HasNormals)
- normal = sourceMesh->normal(vertex);
- m_mesh->addVertex(sourceMesh->position(vertex), normal, sourceMesh->texcoord(vertex));
- }
- }
- }
- // Add faces.
- for (uint32_t f = 0; f < faceCount; f++) {
- const uint32_t face = m_faceToSourceFaceMap[f];
- uint32_t indices[3];
- for (uint32_t i = 0; i < 3; i++) {
- const uint32_t vertex = sourceMesh->vertexAt(face * 3 + i);
- indices[i] = sourceVertexToVertexMap.get(vertex);
- XA_DEBUG_ASSERT(indices[i] != UINT32_MAX);
- }
- // Don't copy flags, it doesn't matter if a face is ignored after this point. All ignored faces get their own vertex map (m_isVertexMap) ChartGroup.
- // Don't hash edges if m_isVertexMap, they may be degenerate.
- Mesh::AddFaceResult::Enum result = m_mesh->addFace(indices, false, !m_isVertexMap);
- XA_UNUSED(result);
- XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK);
- }
- if (!m_isVertexMap) {
- m_mesh->createColocals();
- m_mesh->createBoundaries();
- }
-#if XA_DEBUG_EXPORT_OBJ_CHART_GROUPS
- char filename[256];
- XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u.obj", m_sourceId, m_id);
- m_mesh->writeObjFile(filename);
-#else
- XA_UNUSED(m_id);
-#endif
}
~ChartGroup()
{
- m_mesh->~Mesh();
- XA_FREE(m_mesh);
for (uint32_t i = 0; i < m_charts.size(); i++) {
m_charts[i]->~Chart();
XA_FREE(m_charts[i]);
}
}
+ uint32_t segmentChartCount() const { return m_chartBasis.size(); }
uint32_t chartCount() const { return m_charts.size(); }
Chart *chartAt(uint32_t i) const { return m_charts[i]; }
+ uint32_t faceCount() const { return m_faceCount; }
uint32_t paramAddedChartsCount() const { return m_paramAddedChartsCount; }
uint32_t paramDeletedChartsCount() const { return m_paramDeletedChartsCount; }
- bool isVertexMap() const { return m_isVertexMap; }
- uint32_t mapFaceToSourceFace(uint32_t face) const { return m_faceToSourceFaceMap[face]; }
- uint32_t mapVertexToSourceVertex(uint32_t i) const { return m_vertexToSourceVertexMap[i]; }
- const Mesh *mesh() const { return m_mesh; }
- /*
- Compute charts using a simple segmentation algorithm.
-
- LSCM:
- - identify sharp features using local dihedral angles.
- - identify seed faces farthest from sharp features.
- - grow charts from these seeds.
-
- MCGIM:
- - phase 1: chart growth
- - grow all charts simultaneously using dijkstra search on the dual graph of the mesh.
- - graph edges are weighted based on planarity metric.
- - metric uses distance to global chart normal.
- - terminate when all faces have been assigned.
- - phase 2: seed computation:
- - place new seed of the chart at the most interior face.
- - most interior is evaluated using distance metric only.
-
- - method repeates the two phases, until the location of the seeds does not change.
- - cycles are detected by recording all the previous seeds and chartification terminates.
-
- D-Charts:
-
- - Uniaxial conic metric:
- - N_c = axis of the generalized cone that best fits the chart. (cone can a be cylinder or a plane).
- - omega_c = angle between the face normals and the axis.
- - Fitting error between chart C and tringle t: F(c,t) = (N_c*n_t - cos(omega_c))^2
-
- - Compactness metrics:
- - Roundness:
- - C(c,t) = pi * D(S_c,t)^2 / A_c
- - S_c = chart seed.
- - D(S_c,t) = length of the shortest path inside the chart betwen S_c and t.
- - A_c = chart area.
- - Straightness:
- - P(c,t) = l_out(c,t) / l_in(c,t)
- - l_out(c,t) = lenght of the edges not shared between C and t.
- - l_in(c,t) = lenght of the edges shared between C and t.
-
- - Combined metric:
- - Cost(c,t) = F(c,t)^alpha + C(c,t)^beta + P(c,t)^gamma
- - alpha = 1, beta = 0.7, gamma = 0.5
-
- Our basic approach:
- - Just one iteration of k-means?
- - Avoid dijkstra by greedily growing charts until a threshold is met. Increase threshold and repeat until no faces left.
- - If distortion metric is too high, split chart, add two seeds.
- - If chart size is low, try removing chart.
-
- Postprocess:
- - If topology is not disk:
- - Fill holes, if new faces fit proxy.
- - Find best cut, otherwise.
- - After parameterization:
- - If boundary self-intersects:
- - cut chart along the closest two diametral boundary vertices, repeat parametrization.
- - what if the overlap is on an appendix? How do we find that out and cut appropiately?
- - emphasize roundness metrics to prevent those cases.
- - If interior self-overlaps: preserve boundary parameterization and use mean-value map.
- */
- void computeCharts(TaskScheduler *taskScheduler, const ChartOptions &options, segment::Atlas &atlas, ThreadLocal<ChartCtorBuffers> *chartBuffers)
- {
- m_chartOptions = options;
- // This function may be called multiple times, so destroy existing charts.
- for (uint32_t i = 0; i < m_charts.size(); i++) {
- m_charts[i]->~Chart();
- XA_FREE(m_charts[i]);
- }
- m_charts.clear();
+ void computeChartFaces(const ChartOptions &options, segment::Atlas &atlas)
+ {
+ // Create mesh from source mesh, using only the faces in this face group.
+ XA_PROFILE_START(createChartGroupMesh)
+ Mesh *mesh = createMesh();
+ XA_PROFILE_END(createChartGroupMesh)
+ // Segment mesh into charts (arrays of faces).
#if XA_DEBUG_SINGLE_CHART
- Array<uint32_t> chartFaces;
- chartFaces.resize(m_mesh->faceCount());
- for (uint32_t i = 0; i < chartFaces.size(); i++)
- chartFaces[i] = i;
- Chart *chart = XA_NEW_ARGS(MemTag::Default, Chart, m_mesh, chartFaces, m_sourceId, m_id, 0);
- m_charts.push_back(chart);
+ m_chartBasis.resize(1);
+ Fit::computeBasis(&mesh->position(0), mesh->vertexCount(), &m_chartBasis[0]);
+ m_chartFaces.resize(1 + mesh->faceCount());
+ m_chartFaces[0] = mesh->faceCount();
+ for (uint32_t i = 0; i < m_chartFaces.size(); i++)
+ m_chartFaces[i + 1] = i;
#else
XA_PROFILE_START(buildAtlas)
- atlas.reset(m_sourceId, m_id, m_mesh, options);
- buildAtlas(atlas, options);
+ atlas.reset(mesh, options);
+ atlas.compute();
XA_PROFILE_END(buildAtlas)
- const uint32_t chartCount = atlas.chartCount();
- m_charts.resize(chartCount);
- Array<CreateChartTaskArgs> taskArgs;
- taskArgs.resize(chartCount);
- for (uint32_t i = 0; i < chartCount; i++) {
- CreateChartTaskArgs &args = taskArgs[i];
- args.basis = &atlas.chartBasis(i);
- args.faces = atlas.chartFaces(i);
- args.mesh = m_mesh;
- args.meshId = m_sourceId;
- args.chartGroupId = m_id;
- args.chartId = i;
- args.chartBuffers = chartBuffers;
- args.chart = &m_charts[i];
- }
- XA_PROFILE_START(createChartMeshesReal)
- TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartCount);
- for (uint32_t i = 0; i < chartCount; i++) {
- Task task;
- task.userData = &taskArgs[i];
- task.func = runCreateChartTask;
- taskScheduler->run(taskGroup, task);
- }
- taskScheduler->wait(&taskGroup);
- XA_PROFILE_END(createChartMeshesReal)
-#endif
#if XA_DEBUG_EXPORT_OBJ_CHARTS
char filename[256];
- XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_charts.obj", m_sourceId, m_id);
+ XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_charts.obj", m_sourceMesh->id(), m_id);
FILE *file;
XA_FOPEN(file, filename, "w");
if (file) {
- m_mesh->writeObjVertices(file);
- for (uint32_t i = 0; i < chartCount; i++) {
+ mesh->writeObjVertices(file);
+ for (uint32_t i = 0; i < atlas.chartCount(); i++) {
fprintf(file, "o chart_%04d\n", i);
fprintf(file, "s off\n");
- const Array<uint32_t> &faces = builder.chartFaces(i);
- for (uint32_t f = 0; f < faces.size(); f++)
- m_mesh->writeObjFace(file, faces[f]);
+ ConstArrayView<uint32_t> faces = atlas.chartFaces(i);
+ for (uint32_t f = 0; f < faces.length; f++)
+ mesh->writeObjFace(file, faces[f]);
}
- m_mesh->writeObjBoundaryEges(file);
- m_mesh->writeObjLinkedBoundaries(file);
+ mesh->writeObjBoundaryEges(file);
+ mesh->writeObjLinkedBoundaries(file);
fclose(file);
}
#endif
+ // Destroy mesh.
+ const uint32_t faceCount = mesh->faceCount();
+ mesh->~Mesh();
+ XA_FREE(mesh);
+ XA_PROFILE_START(copyChartFaces)
+ // Copy basis.
+ const uint32_t chartCount = atlas.chartCount();
+ m_chartBasis.resize(chartCount);
+ for (uint32_t i = 0; i < chartCount; i++)
+ m_chartBasis[i] = atlas.chartBasis(i);
+ // Copy faces from segment::Atlas to m_chartFaces array with <chart 0 face count> <face 0> <face n> <chart 1 face count> etc. encoding.
+ // segment::Atlas faces refer to the chart group mesh. Map them to the input mesh instead.
+ m_chartFaces.resize(chartCount + faceCount);
+ uint32_t offset = 0;
+ for (uint32_t i = 0; i < chartCount; i++) {
+ ConstArrayView<uint32_t> faces = atlas.chartFaces(i);
+ m_chartFaces[offset++] = faces.length;
+ for (uint32_t j = 0; j < faces.length; j++)
+ m_chartFaces[offset++] = m_faceToSourceFaceMap[faces[j]];
+ }
+ XA_PROFILE_END(copyChartFaces)
+#endif
}
#if XA_RECOMPUTE_CHARTS
- void parameterizeCharts(TaskScheduler *taskScheduler, ParameterizeFunc func, ThreadLocal<UniformGrid2> *boundaryGrid, ThreadLocal<ChartCtorBuffers> *chartBuffers, ThreadLocal<PiecewiseParam> *piecewiseParam)
+ void parameterizeCharts(TaskScheduler *taskScheduler, const ParameterizeOptions &options, ThreadLocal<UniformGrid2> *boundaryGrid, ThreadLocal<ChartCtorBuffers> *chartBuffers, ThreadLocal<PiecewiseParam> *piecewiseParam)
#else
- void parameterizeCharts(TaskScheduler* taskScheduler, ParameterizeFunc func, ThreadLocal<UniformGrid2>* boundaryGrid, ThreadLocal<ChartCtorBuffers>* /*chartBuffers*/)
+ void parameterizeCharts(TaskScheduler* taskScheduler, const ParameterizeOptions &options, ThreadLocal<UniformGrid2>* boundaryGrid, ThreadLocal<ChartCtorBuffers>* chartBuffers)
#endif
{
+ // This function may be called multiple times, so destroy existing charts.
+ for (uint32_t i = 0; i < m_charts.size(); i++) {
+ m_charts[i]->~Chart();
+ XA_FREE(m_charts[i]);
+ }
m_paramAddedChartsCount = 0;
- const uint32_t chartCount = m_charts.size();
- Array<ParameterizeChartTaskArgs> taskArgs;
+ const uint32_t chartCount = m_chartBasis.size();
+ Array<CreateAndParameterizeChartTaskArgs> taskArgs;
taskArgs.resize(chartCount);
+ taskArgs.runCtors(); // Has Array member.
TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartCount);
+ uint32_t offset = 0;
for (uint32_t i = 0; i < chartCount; i++) {
- ParameterizeChartTaskArgs &args = taskArgs[i];
- args.chart = m_charts[i];
- args.func = func;
+ CreateAndParameterizeChartTaskArgs &args = taskArgs[i];
+ args.basis = &m_chartBasis[i];
args.boundaryGrid = boundaryGrid;
+ args.chart = nullptr;
+ args.chartGroupId = m_id;
+ args.chartId = i;
+ args.chartBuffers = chartBuffers;
+ const uint32_t faceCount = m_chartFaces[offset++];
+ args.faces = ConstArrayView<uint32_t>(&m_chartFaces[offset], faceCount);
+ offset += faceCount;
+ args.mesh = m_sourceMesh;
+ args.options = &options;
+#if XA_RECOMPUTE_CHARTS
+ args.pp = piecewiseParam;
+#endif
Task task;
task.userData = &args;
- task.func = runParameterizeChartTask;
+ task.func = runCreateAndParameterizeChartTask;
taskScheduler->run(taskGroup, task);
}
taskScheduler->wait(&taskGroup);
#if XA_RECOMPUTE_CHARTS
- // Find charts with invalid parameterizations.
- Array<Chart *> invalidCharts;
+ // Count charts. Skip invalid ones and include new ones added by recomputing.
+ uint32_t newChartCount = 0;
for (uint32_t i = 0; i < chartCount; i++) {
- Chart *chart = m_charts[i];
- const Quality &quality = chart->quality();
- if (quality.boundaryIntersection || quality.flippedTriangleCount > 0)
- invalidCharts.push_back(chart);
+ if (taskArgs[i].chart->isInvalid())
+ newChartCount += taskArgs[i].charts.size();
+ else
+ newChartCount++;
}
- if (invalidCharts.isEmpty())
- return;
- // Recompute charts with invalid parameterizations.
- PiecewiseParam &pp = piecewiseParam->get();
- for (uint32_t i = 0; i < invalidCharts.size(); i++) {
- Chart *invalidChart = invalidCharts[i];
- // Fixing t-junctions rewrites unified mesh faces, and we need to map faces back to input mesh. So use the unmodified unified mesh.
- const Mesh *invalidMesh = invalidChart->unmodifiedUnifiedMesh();
- uint32_t faceCount = 0;
- if (invalidMesh) {
- faceCount = invalidMesh->faceCount();
- } else {
- invalidMesh = invalidChart->unifiedMesh();
- faceCount = invalidChart->initialFaceCount(); // Not invalidMesh->faceCount(). Don't want faces added by hole closing.
+ m_charts.resize(newChartCount);
+ // Add valid charts first. Destroy invalid ones.
+ uint32_t current = 0;
+ for (uint32_t i = 0; i < chartCount; i++) {
+ Chart *chart = taskArgs[i].chart;
+ if (chart->isInvalid()) {
+ chart->~Chart();
+ XA_FREE(chart);
+ m_paramDeletedChartsCount++;
+ continue;
}
- pp.reset(invalidMesh, faceCount);
-#if XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS
- char filename[256];
- XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_recomputed_chart_%03u.obj", m_sourceId, m_id, m_paramAddedChartsCount);
- FILE *file;
- XA_FOPEN(file, filename, "w");
- uint32_t subChartIndex = 0;
-#endif
- for (;;) {
- if (!pp.computeChart())
- break;
- Chart *chart = XA_NEW_ARGS(MemTag::Default, Chart, chartBuffers->get(), invalidChart, invalidMesh, pp.chartFaces(), pp.texcoords(), m_mesh, m_sourceId, m_id, m_charts.size());
- m_charts.push_back(chart);
-#if XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS
- if (file) {
- for (uint32_t j = 0; j < invalidMesh->vertexCount(); j++) {
- fprintf(file, "v %g %g %g\n", invalidMesh->position(j).x, invalidMesh->position(j).y, invalidMesh->position(j).z);
- fprintf(file, "vt %g %g\n", pp.texcoords()[j].x, pp.texcoords()[j].y);
- }
- fprintf(file, "o chart%03u\n", subChartIndex);
- fprintf(file, "s off\n");
- for (uint32_t f = 0; f < pp.chartFaces().length; f++) {
- fprintf(file, "f ");
- const uint32_t face = pp.chartFaces()[f];
- for (uint32_t j = 0; j < 3; j++) {
- const uint32_t index = invalidMesh->vertexCount() * subChartIndex + invalidMesh->vertexAt(face * 3 + j) + 1; // 1-indexed
- fprintf(file, "%d/%d/%c", index, index, j == 2 ? '\n' : ' ');
- }
- }
- }
- subChartIndex++;
-#endif
+ m_charts[current++] = chart;
+ }
+ // Now add new charts.
+ for (uint32_t i = 0; i < chartCount; i++) {
+ CreateAndParameterizeChartTaskArgs &args = taskArgs[i];
+ for (uint32_t j = 0; j < args.charts.size(); j++) {
+ m_charts[current++] = args.charts[j];
m_paramAddedChartsCount++;
}
-#if XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS
- if (file)
- fclose(file);
-#endif
- }
- // Remove and delete the invalid charts.
- for (uint32_t i = 0; i < invalidCharts.size(); i++) {
- Chart *chart = invalidCharts[i];
- removeChart(chart);
- chart->~Chart();
- XA_FREE(chart);
- m_paramDeletedChartsCount++;
}
+#else // XA_RECOMPUTE_CHARTS
+ m_charts.resize(chartCount);
+ for (uint32_t i = 0; i < chartCount; i++)
+ m_charts[i] = taskArgs[i].chart;
#endif // XA_RECOMPUTE_CHARTS
+ taskArgs.runDtors(); // Has Array member.
}
private:
- void buildAtlas(segment::Atlas &atlas, const ChartOptions &options)
+ Mesh *createMesh()
{
- if (atlas.facesLeft() == 0)
- return;
- // Create initial charts greedely.
- atlas.placeSeeds(options.maxThreshold * 0.5f);
- if (options.maxIterations == 0) {
- XA_DEBUG_ASSERT(atlas.facesLeft() == 0);
- return;
- }
- atlas.relocateSeeds();
- atlas.resetCharts();
- // Restart process growing charts in parallel.
- uint32_t iteration = 0;
- for (;;) {
- atlas.growCharts(options.maxThreshold);
- // When charts cannot grow more: fill holes, merge charts, relocate seeds and start new iteration.
- atlas.fillHoles(options.maxThreshold * 0.5f);
-#if XA_MERGE_CHARTS
- atlas.mergeCharts();
-#endif
- if (++iteration == options.maxIterations)
- break;
- if (!atlas.relocateSeeds())
- break;
- atlas.resetCharts();
+ XA_DEBUG_ASSERT(m_faceGroup != MeshFaceGroups::kInvalid);
+ // Create new mesh from the source mesh, using faces that belong to this group.
+ m_faceToSourceFaceMap.reserve(m_sourceMeshFaceGroups->faceCount(m_faceGroup));
+ for (MeshFaceGroups::Iterator it(m_sourceMeshFaceGroups, m_faceGroup); !it.isDone(); it.advance())
+ m_faceToSourceFaceMap.push_back(it.face());
+ // Only initial meshes has ignored faces. The only flag we care about is HasNormals.
+ const uint32_t faceCount = m_faceCount = m_faceToSourceFaceMap.size();
+ XA_DEBUG_ASSERT(faceCount > 0);
+ const uint32_t approxVertexCount = min(faceCount * 3, m_sourceMesh->vertexCount());
+ Mesh *mesh = XA_NEW_ARGS(MemTag::Mesh, Mesh, m_sourceMesh->epsilon(), approxVertexCount, faceCount, m_sourceMesh->flags() & MeshFlags::HasNormals);
+ HashMap<uint32_t, PassthroughHash<uint32_t>> sourceVertexToVertexMap(MemTag::Mesh, approxVertexCount);
+ for (uint32_t f = 0; f < faceCount; f++) {
+ const uint32_t face = m_faceToSourceFaceMap[f];
+ for (uint32_t i = 0; i < 3; i++) {
+ const uint32_t vertex = m_sourceMesh->vertexAt(face * 3 + i);
+ if (sourceVertexToVertexMap.get(vertex) == UINT32_MAX) {
+ sourceVertexToVertexMap.add(vertex);
+ Vector3 normal(0.0f);
+ if (m_sourceMesh->flags() & MeshFlags::HasNormals)
+ normal = m_sourceMesh->normal(vertex);
+ mesh->addVertex(m_sourceMesh->position(vertex), normal, m_sourceMesh->texcoord(vertex));
+ }
+ }
}
- // Make sure no holes are left!
- XA_DEBUG_ASSERT(atlas.facesLeft() == 0);
- }
-
- void removeChart(const Chart *chart)
- {
- for (uint32_t i = 0; i < m_charts.size(); i++) {
- if (m_charts[i] == chart) {
- m_charts.removeAt(i);
- return;
+ // Add faces.
+ for (uint32_t f = 0; f < faceCount; f++) {
+ const uint32_t face = m_faceToSourceFaceMap[f];
+ XA_DEBUG_ASSERT(!m_sourceMesh->isFaceIgnored(face));
+ uint32_t indices[3];
+ for (uint32_t i = 0; i < 3; i++) {
+ const uint32_t vertex = m_sourceMesh->vertexAt(face * 3 + i);
+ indices[i] = sourceVertexToVertexMap.get(vertex);
+ XA_DEBUG_ASSERT(indices[i] != UINT32_MAX);
}
+ // Don't copy flags - ignored faces aren't used by chart groups, they are handled by InvalidMeshGeometry.
+ Mesh::AddFaceResult::Enum result = mesh->addFace(indices);
+ XA_UNUSED(result);
+ XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK);
}
+ XA_PROFILE_START(createChartGroupMeshColocals)
+ mesh->createColocals();
+ XA_PROFILE_END(createChartGroupMeshColocals)
+ XA_PROFILE_START(createChartGroupMeshBoundaries)
+ mesh->createBoundaries();
+ mesh->destroyEdgeMap(); // Only needed it for createBoundaries.
+ XA_PROFILE_END(createChartGroupMeshBoundaries)
+#if XA_DEBUG_EXPORT_OBJ_CHART_GROUPS
+ char filename[256];
+ XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u.obj", m_sourceMesh->id(), m_id);
+ mesh->writeObjFile(filename);
+#endif
+ return mesh;
}
- uint32_t m_sourceId, m_id;
- bool m_isVertexMap;
- Mesh *m_mesh;
+ const uint32_t m_id;
+ const Mesh * const m_sourceMesh;
+ const MeshFaceGroups * const m_sourceMeshFaceGroups;
+ const MeshFaceGroups::Handle m_faceGroup;
Array<uint32_t> m_faceToSourceFaceMap; // List of faces of the source mesh that belong to this chart group.
- Array<uint32_t> m_vertexToSourceVertexMap; // Map vertices of the mesh to vertices of the source mesh.
+ Array<Basis> m_chartBasis; // Copied from segment::Atlas.
+ Array<uint32_t> m_chartFaces; // Copied from segment::Atlas. Encoding: <chart 0 face count> <face 0> <face n> <chart 1 face count> etc.
Array<Chart *> m_charts;
- ChartOptions m_chartOptions;
+ uint32_t m_faceCount; // Set by createMesh(). Used for sorting.
uint32_t m_paramAddedChartsCount; // Number of new charts added by recomputing charts with invalid parameterizations.
uint32_t m_paramDeletedChartsCount; // Number of charts with invalid parameterizations that were deleted, after charts were recomputed.
};
-struct CreateChartGroupTaskArgs
+// References invalid faces and vertices in a mesh.
+struct InvalidMeshGeometry
{
- uint16_t faceGroup;
- uint32_t groupId;
- const Mesh *mesh;
- ChartGroup **chartGroup;
+ // Invalid faces have the face groups MeshFaceGroups::kInvalid.
+ void extract(const Mesh *mesh, const MeshFaceGroups *meshFaceGroups)
+ {
+ // Copy invalid faces.
+ m_faces.clear();
+ const uint32_t meshFaceCount = mesh->faceCount();
+ for (uint32_t f = 0; f < meshFaceCount; f++) {
+ if (meshFaceGroups->groupAt(f) == MeshFaceGroups::kInvalid)
+ m_faces.push_back(f);
+ }
+ // Create *unique* list of vertices of invalid faces.
+ const uint32_t faceCount = m_faces.size();
+ m_indices.resize(faceCount * 3);
+ const uint32_t approxVertexCount = min(faceCount * 3, mesh->vertexCount());
+ m_vertexToSourceVertexMap.clear();
+ m_vertexToSourceVertexMap.reserve(approxVertexCount);
+ HashMap<uint32_t, PassthroughHash<uint32_t>> sourceVertexToVertexMap(MemTag::Mesh, approxVertexCount);
+ for (uint32_t f = 0; f < faceCount; f++) {
+ const uint32_t face = m_faces[f];
+ for (uint32_t i = 0; i < 3; i++) {
+ const uint32_t vertex = mesh->vertexAt(face * 3 + i);
+ uint32_t newVertex = sourceVertexToVertexMap.get(vertex);
+ if (newVertex == UINT32_MAX) {
+ newVertex = sourceVertexToVertexMap.add(vertex);
+ m_vertexToSourceVertexMap.push_back(vertex);
+ }
+ m_indices[f * 3 + i] = newVertex;
+ }
+ }
+ }
+
+ ConstArrayView<uint32_t> faces() const { return m_faces; }
+ ConstArrayView<uint32_t> indices() const { return m_indices; }
+ ConstArrayView<uint32_t> vertices() const { return m_vertexToSourceVertexMap; }
+
+private:
+ Array<uint32_t> m_faces, m_indices;
+ Array<uint32_t> m_vertexToSourceVertexMap; // Map face vertices to vertices of the source mesh.
+};
+
+struct ChartGroupComputeChartFacesTaskArgs
+{
+ ThreadLocal<segment::Atlas> *atlas;
+ ChartGroup *chartGroup;
+ const ChartOptions *options;
+ Progress *progress;
};
-static void runCreateChartGroupTask(void *userData)
+static void runChartGroupComputeChartFacesJob(void *userData)
{
- XA_PROFILE_START(addMeshCreateChartGroupsThread)
- auto args = (CreateChartGroupTaskArgs *)userData;
- *(args->chartGroup) = XA_NEW_ARGS(MemTag::Default, ChartGroup, args->groupId, args->mesh, args->faceGroup);
- XA_PROFILE_END(addMeshCreateChartGroupsThread)
+ auto args = (ChartGroupComputeChartFacesTaskArgs *)userData;
+ if (args->progress->cancel)
+ return;
+ XA_PROFILE_START(chartGroupComputeChartsThread)
+ args->chartGroup->computeChartFaces(*args->options, args->atlas->get());
+ XA_PROFILE_END(chartGroupComputeChartsThread)
}
-struct ComputeChartsTaskArgs
+struct MeshComputeChartFacesTaskArgs
{
- TaskScheduler *taskScheduler;
- ChartGroup *chartGroup;
+ Array<ChartGroup *> *chartGroups; // output
+ InvalidMeshGeometry *invalidMeshGeometry; // output
ThreadLocal<segment::Atlas> *atlas;
- ThreadLocal<ChartCtorBuffers> *chartBuffers;
const ChartOptions *options;
Progress *progress;
+ const Mesh *sourceMesh;
+ TaskScheduler *taskScheduler;
};
-static void runComputeChartsJob(void *userData)
+#if XA_DEBUG_EXPORT_OBJ_FACE_GROUPS
+static uint32_t s_faceGroupsCurrentVertex = 0;
+#endif
+
+static void runMeshComputeChartFacesJob(void *userData)
{
- auto args = (ComputeChartsTaskArgs *)userData;
+ auto args = (MeshComputeChartFacesTaskArgs *)userData;
if (args->progress->cancel)
return;
XA_PROFILE_START(computeChartsThread)
- args->chartGroup->computeCharts(args->taskScheduler, *args->options, args->atlas->get(), args->chartBuffers);
+ // Create face groups.
+ XA_PROFILE_START(createFaceGroups)
+ MeshFaceGroups *meshFaceGroups = XA_NEW_ARGS(MemTag::Mesh, MeshFaceGroups, args->sourceMesh);
+ meshFaceGroups->compute();
+ const uint32_t chartGroupCount = meshFaceGroups->groupCount();
+ XA_PROFILE_END(createFaceGroups)
+ if (args->progress->cancel)
+ goto cleanup;
+#if XA_DEBUG_EXPORT_OBJ_FACE_GROUPS
+ {
+ static std::mutex s_mutex;
+ std::lock_guard<std::mutex> lock(s_mutex);
+ char filename[256];
+ XA_SPRINTF(filename, sizeof(filename), "debug_face_groups.obj");
+ FILE *file;
+ XA_FOPEN(file, filename, s_faceGroupsCurrentVertex == 0 ? "w" : "a");
+ if (file) {
+ const Mesh *mesh = args->sourceMesh;
+ mesh->writeObjVertices(file);
+ // groups
+ uint32_t numGroups = 0;
+ for (uint32_t i = 0; i < mesh->faceCount(); i++) {
+ if (meshFaceGroups->groupAt(i) != MeshFaceGroups::kInvalid)
+ numGroups = max(numGroups, meshFaceGroups->groupAt(i) + 1);
+ }
+ for (uint32_t i = 0; i < numGroups; i++) {
+ fprintf(file, "o mesh_%03u_group_%04d\n", mesh->id(), i);
+ fprintf(file, "s off\n");
+ for (uint32_t f = 0; f < mesh->faceCount(); f++) {
+ if (meshFaceGroups->groupAt(f) == i)
+ mesh->writeObjFace(file, f, s_faceGroupsCurrentVertex);
+ }
+ }
+ fprintf(file, "o mesh_%03u_group_ignored\n", mesh->id());
+ fprintf(file, "s off\n");
+ for (uint32_t f = 0; f < mesh->faceCount(); f++) {
+ if (meshFaceGroups->groupAt(f) == MeshFaceGroups::kInvalid)
+ mesh->writeObjFace(file, f, s_faceGroupsCurrentVertex);
+ }
+ mesh->writeObjBoundaryEges(file);
+ s_faceGroupsCurrentVertex += mesh->vertexCount();
+ fclose(file);
+ }
+ }
+#endif
+ // Create a chart group for each face group.
+ args->chartGroups->resize(chartGroupCount);
+ for (uint32_t i = 0; i < chartGroupCount; i++)
+ (*args->chartGroups)[i] = XA_NEW_ARGS(MemTag::Default, ChartGroup, i, args->sourceMesh, meshFaceGroups, MeshFaceGroups::Handle(i));
+ // Extract invalid geometry via the invalid face group (MeshFaceGroups::kInvalid).
+ XA_PROFILE_START(extractInvalidMeshGeometry)
+ args->invalidMeshGeometry->extract(args->sourceMesh, meshFaceGroups);
+ XA_PROFILE_END(extractInvalidMeshGeometry)
+ // One task for each chart group - compute chart faces.
+ {
+ XA_PROFILE_START(chartGroupComputeChartsReal)
+ Array<ChartGroupComputeChartFacesTaskArgs> taskArgs;
+ taskArgs.resize(chartGroupCount);
+ for (uint32_t i = 0; i < chartGroupCount; i++) {
+ taskArgs[i].atlas = args->atlas;
+ taskArgs[i].chartGroup = (*args->chartGroups)[i];
+ taskArgs[i].options = args->options;
+ taskArgs[i].progress = args->progress;
+ }
+ TaskGroupHandle taskGroup = args->taskScheduler->createTaskGroup(chartGroupCount);
+ for (uint32_t i = 0; i < chartGroupCount; i++) {
+ Task task;
+ task.userData = &taskArgs[i];
+ task.func = runChartGroupComputeChartFacesJob;
+ args->taskScheduler->run(taskGroup, task);
+ }
+ args->taskScheduler->wait(&taskGroup);
+ XA_PROFILE_END(chartGroupComputeChartsReal)
+ }
XA_PROFILE_END(computeChartsThread)
args->progress->value++;
args->progress->update();
+cleanup:
+ if (meshFaceGroups) {
+ meshFaceGroups->~MeshFaceGroups();
+ XA_FREE(meshFaceGroups);
+ }
}
struct ParameterizeChartsTaskArgs
{
TaskScheduler *taskScheduler;
ChartGroup *chartGroup;
- ParameterizeFunc func;
+ const ParameterizeOptions *options;
ThreadLocal<UniformGrid2> *boundaryGrid;
ThreadLocal<ChartCtorBuffers> *chartBuffers;
#if XA_RECOMPUTE_CHARTS
@@ -7426,9 +8107,9 @@ static void runParameterizeChartsJob(void *userData)
return;
XA_PROFILE_START(parameterizeChartsThread)
#if XA_RECOMPUTE_CHARTS
- args->chartGroup->parameterizeCharts(args->taskScheduler, args->func, args->boundaryGrid, args->chartBuffers, args->piecewiseParam);
+ args->chartGroup->parameterizeCharts(args->taskScheduler, *args->options, args->boundaryGrid, args->chartBuffers, args->piecewiseParam);
#else
- args->chartGroup->parameterizeCharts(args->taskScheduler, args->func, args->boundaryGrid, args->chartBuffers);
+ args->chartGroup->parameterizeCharts(args->taskScheduler, *args->options, args->boundaryGrid, args->chartBuffers);
#endif
XA_PROFILE_END(parameterizeChartsThread)
args->progress->value++;
@@ -7439,140 +8120,83 @@ static void runParameterizeChartsJob(void *userData)
class Atlas
{
public:
- Atlas() : m_meshCount(0), m_chartsComputed(false), m_chartsParameterized(false) {}
+ Atlas() : m_chartsComputed(false), m_chartsParameterized(false) {}
~Atlas()
{
- for (uint32_t i = 0; i < m_chartGroups.size(); i++) {
- m_chartGroups[i]->~ChartGroup();
- XA_FREE(m_chartGroups[i]);
+ for (uint32_t i = 0; i < m_meshChartGroups.size(); i++) {
+ for (uint32_t j = 0; j < m_meshChartGroups[i].size(); j++) {
+ m_meshChartGroups[i][j]->~ChartGroup();
+ XA_FREE(m_meshChartGroups[i][j]);
+ }
}
+ m_meshChartGroups.runDtors();
+ m_invalidMeshGeometry.runDtors();
}
+ uint32_t meshCount() const { return m_meshes.size(); }
+ const InvalidMeshGeometry &invalidMeshGeometry(uint32_t meshIndex) const { return m_invalidMeshGeometry[meshIndex]; }
bool chartsComputed() const { return m_chartsComputed; }
bool chartsParameterized() const { return m_chartsParameterized; }
- uint32_t chartGroupCount() const { return m_chartGroups.size(); }
- const ChartGroup *chartGroupAt(uint32_t index) const { return m_chartGroups[index]; }
-
- uint32_t chartGroupCount(uint32_t mesh) const
- {
- uint32_t count = 0;
- for (uint32_t i = 0; i < m_chartGroups.size(); i++) {
- if (m_chartGroupSourceMeshes[i] == mesh)
- count++;
- }
- return count;
- }
+ uint32_t chartGroupCount(uint32_t mesh) const { return m_meshChartGroups[mesh].size(); }
+ const ChartGroup *chartGroupAt(uint32_t mesh, uint32_t group) const { return m_meshChartGroups[mesh][group]; }
- const ChartGroup *chartGroupAt(uint32_t mesh, uint32_t group) const
+ void addMesh(const Mesh *mesh)
{
- for (uint32_t c = 0; c < m_chartGroups.size(); c++) {
- if (m_chartGroupSourceMeshes[c] != mesh)
- continue;
- if (group == 0)
- return m_chartGroups[c];
- group--;
- }
- return nullptr;
- }
-
- // This function is thread safe.
- void addMesh(TaskScheduler *taskScheduler, const Mesh *mesh)
- {
- // Create one chart group per face group.
- // If there's any ignored faces in the mesh, create an extra face group for that (vertex map).
- // Chart group creation is slow since it copies a chunk of the source mesh, so use tasks.
- Array<ChartGroup *> chartGroups;
- chartGroups.resize(mesh->faceGroupCount() + (mesh->ignoredFaceCount() > 0 ? 1 : 0));
- Array<CreateChartGroupTaskArgs> taskArgs;
- taskArgs.resize(chartGroups.size());
- for (uint32_t g = 0; g < chartGroups.size(); g++) {
- CreateChartGroupTaskArgs &args = taskArgs[g];
- args.chartGroup = &chartGroups[g];
- args.faceGroup = uint16_t(g < mesh->faceGroupCount() ? g : Mesh::kInvalidFaceGroup);
- args.groupId = g;
- args.mesh = mesh;
- }
- TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartGroups.size());
- for (uint32_t g = 0; g < chartGroups.size(); g++) {
- Task task;
- task.userData = &taskArgs[g];
- task.func = runCreateChartGroupTask;
- taskScheduler->run(taskGroup, task);
- }
- taskScheduler->wait(&taskGroup);
- // Thread-safe append.
- m_addMeshMutex.lock();
- for (uint32_t g = 0; g < chartGroups.size(); g++) {
- m_chartGroups.push_back(chartGroups[g]);
- m_chartGroupSourceMeshes.push_back(mesh->id());
- }
- m_meshCount++;
- m_addMeshMutex.unlock();
- }
-
- // Chart id/index is determined by depth-first hierarchy of mesh -> chart group -> chart.
- // For chart index to be consistent here, chart groups needs to sorted by mesh index. Since addMesh is called by multithreaded tasks, order is indeterminate, so chart groups need to be explicitly sorted after all meshes are added.
- void sortChartGroups()
- {
- Array<ChartGroup *> oldChartGroups;
- oldChartGroups.resize(m_chartGroups.size());
- memcpy(oldChartGroups.data(), m_chartGroups.data(), sizeof(ChartGroup *) * m_chartGroups.size());
- Array<uint32_t> oldChartGroupSourceMeshes;
- oldChartGroupSourceMeshes.resize(m_chartGroupSourceMeshes.size());
- memcpy(oldChartGroupSourceMeshes.data(), m_chartGroupSourceMeshes.data(), sizeof(uint32_t) * m_chartGroupSourceMeshes.size());
- uint32_t current = 0;
- for (uint32_t i = 0; i < m_meshCount; i++) {
- for (uint32_t j = 0; j < oldChartGroups.size(); j++) {
- if (oldChartGroupSourceMeshes[j] == i) {
- m_chartGroups[current] = oldChartGroups[j];
- m_chartGroupSourceMeshes[current] = oldChartGroupSourceMeshes[j];
- current++;
- }
- }
- }
+ m_meshes.push_back(mesh);
}
bool computeCharts(TaskScheduler *taskScheduler, const ChartOptions &options, ProgressFunc progressFunc, void *progressUserData)
{
+#if XA_DEBUG_EXPORT_OBJ_PLANAR_REGIONS
+ segment::s_planarRegionsCurrentRegion = segment::s_planarRegionsCurrentVertex = 0;
+#endif
m_chartsComputed = false;
m_chartsParameterized = false;
- // Ignore vertex maps.
- uint32_t chartGroupCount = 0;
- for (uint32_t i = 0; i < m_chartGroups.size(); i++) {
- if (!m_chartGroups[i]->isVertexMap())
- chartGroupCount++;
+ // Clear chart groups, since this function may be called multiple times.
+ if (!m_meshChartGroups.isEmpty()) {
+ for (uint32_t i = 0; i < m_meshChartGroups.size(); i++) {
+ for (uint32_t j = 0; j < m_meshChartGroups[i].size(); j++) {
+ m_meshChartGroups[i][j]->~ChartGroup();
+ XA_FREE(m_meshChartGroups[i][j]);
+ }
+ m_meshChartGroups[i].clear();
+ }
+ XA_ASSERT(m_meshChartGroups.size() == m_meshes.size()); // The number of meshes shouldn't have changed.
}
- Progress progress(ProgressCategory::ComputeCharts, progressFunc, progressUserData, chartGroupCount);
+ m_meshChartGroups.resize(m_meshes.size());
+ m_meshChartGroups.runCtors();
+ m_invalidMeshGeometry.resize(m_meshes.size());
+ m_invalidMeshGeometry.runCtors();
+ // One task per mesh.
+ const uint32_t meshCount = m_meshes.size();
+ Progress progress(ProgressCategory::ComputeCharts, progressFunc, progressUserData, meshCount);
ThreadLocal<segment::Atlas> atlas;
- ThreadLocal<ChartCtorBuffers> chartBuffers;
- Array<ComputeChartsTaskArgs> taskArgs;
- taskArgs.reserve(chartGroupCount);
- for (uint32_t i = 0; i < m_chartGroups.size(); i++) {
- if (!m_chartGroups[i]->isVertexMap()) {
- ComputeChartsTaskArgs args;
- args.taskScheduler = taskScheduler;
- args.chartGroup = m_chartGroups[i];
- args.atlas = &atlas;
- args.chartBuffers = &chartBuffers;
- args.options = &options;
- args.progress = &progress;
- taskArgs.push_back(args);
- }
- }
- // Sort chart groups by mesh indexCount.
- m_chartGroupsRadix = RadixSort();
- Array<float> chartGroupSortData;
- chartGroupSortData.resize(chartGroupCount);
- for (uint32_t i = 0; i < chartGroupCount; i++)
- chartGroupSortData[i] = (float)taskArgs[i].chartGroup->mesh()->indexCount();
- m_chartGroupsRadix.sort(chartGroupSortData);
- // Larger chart group meshes are added first to reduce the chance of thread starvation.
- TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartGroupCount);
- for (uint32_t i = 0; i < chartGroupCount; i++) {
+ Array<MeshComputeChartFacesTaskArgs> taskArgs;
+ taskArgs.resize(meshCount);
+ for (uint32_t i = 0; i < meshCount; i++) {
+ MeshComputeChartFacesTaskArgs &args = taskArgs[i];
+ args.atlas = &atlas;
+ args.chartGroups = &m_meshChartGroups[i];
+ args.invalidMeshGeometry = &m_invalidMeshGeometry[i];
+ args.options = &options;
+ args.progress = &progress;
+ args.sourceMesh = m_meshes[i];
+ args.taskScheduler = taskScheduler;
+ }
+ // Sort meshes by indexCount.
+ Array<float> meshSortData;
+ meshSortData.resize(meshCount);
+ for (uint32_t i = 0; i < meshCount; i++)
+ meshSortData[i] = (float)m_meshes[i]->indexCount();
+ RadixSort meshSort;
+ meshSort.sort(meshSortData);
+ // Larger meshes are added first to reduce the chance of thread starvation.
+ TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(meshCount);
+ for (uint32_t i = 0; i < meshCount; i++) {
Task task;
- task.userData = &taskArgs[m_chartGroupsRadix.ranks()[chartGroupCount - i - 1]];
- task.func = runComputeChartsJob;
+ task.userData = &taskArgs[meshSort.ranks()[meshCount - i - 1]];
+ task.func = runMeshComputeChartFacesJob;
taskScheduler->run(taskGroup, task);
}
taskScheduler->wait(&taskGroup);
@@ -7582,15 +8206,12 @@ public:
return true;
}
- bool parameterizeCharts(TaskScheduler *taskScheduler, ParameterizeFunc func, ProgressFunc progressFunc, void *progressUserData)
+ bool parameterizeCharts(TaskScheduler *taskScheduler, const ParameterizeOptions &options, ProgressFunc progressFunc, void *progressUserData)
{
m_chartsParameterized = false;
- // Ignore vertex maps.
uint32_t chartGroupCount = 0;
- for (uint32_t i = 0; i < m_chartGroups.size(); i++) {
- if (!m_chartGroups[i]->isVertexMap())
- chartGroupCount++;
- }
+ for (uint32_t i = 0; i < m_meshChartGroups.size(); i++)
+ chartGroupCount += m_meshChartGroups[i].size();
Progress progress(ProgressCategory::ParameterizeCharts, progressFunc, progressUserData, chartGroupCount);
ThreadLocal<UniformGrid2> boundaryGrid; // For Quality boundary intersection.
ThreadLocal<ChartCtorBuffers> chartBuffers;
@@ -7598,27 +8219,45 @@ public:
ThreadLocal<PiecewiseParam> piecewiseParam;
#endif
Array<ParameterizeChartsTaskArgs> taskArgs;
- taskArgs.reserve(chartGroupCount);
- for (uint32_t i = 0; i < m_chartGroups.size(); i++) {
- if (!m_chartGroups[i]->isVertexMap()) {
- ParameterizeChartsTaskArgs args;
- args.taskScheduler = taskScheduler;
- args.chartGroup = m_chartGroups[i];
- args.func = func;
- args.boundaryGrid = &boundaryGrid;
- args.chartBuffers = &chartBuffers;
+ taskArgs.resize(chartGroupCount);
+ {
+ uint32_t k = 0;
+ for (uint32_t i = 0; i < m_meshChartGroups.size(); i++) {
+ const uint32_t count = m_meshChartGroups[i].size();
+ for (uint32_t j = 0; j < count; j++) {
+ ParameterizeChartsTaskArgs &args = taskArgs[k];
+ args.taskScheduler = taskScheduler;
+ args.chartGroup = m_meshChartGroups[i][j];
+ args.options = &options;
+ args.boundaryGrid = &boundaryGrid;
+ args.chartBuffers = &chartBuffers;
#if XA_RECOMPUTE_CHARTS
- args.piecewiseParam = &piecewiseParam;
+ args.piecewiseParam = &piecewiseParam;
#endif
- args.progress = &progress;
- taskArgs.push_back(args);
+ args.progress = &progress;
+ k++;
+ }
+ }
+ }
+ // Sort chart groups by face count.
+ Array<float> chartGroupSortData;
+ chartGroupSortData.resize(chartGroupCount);
+ {
+ uint32_t k = 0;
+ for (uint32_t i = 0; i < m_meshChartGroups.size(); i++) {
+ const uint32_t count = m_meshChartGroups[i].size();
+ for (uint32_t j = 0; j < count; j++) {
+ chartGroupSortData[k++] = (float)m_meshChartGroups[i][j]->faceCount();
+ }
}
}
- // Larger chart group meshes are added first to reduce the chance of thread starvation.
+ RadixSort chartGroupSort;
+ chartGroupSort.sort(chartGroupSortData);
+ // Larger chart groups are added first to reduce the chance of thread starvation.
TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartGroupCount);
for (uint32_t i = 0; i < chartGroupCount; i++) {
Task task;
- task.userData = &taskArgs[m_chartGroupsRadix.ranks()[chartGroupCount - i - 1]];
+ task.userData = &taskArgs[chartGroupSort.ranks()[chartGroupCount - i - 1]];
task.func = runParameterizeChartsJob;
taskScheduler->run(taskGroup, task);
}
@@ -7630,13 +8269,11 @@ public:
}
private:
- std::mutex m_addMeshMutex;
- uint32_t m_meshCount;
+ Array<const Mesh *> m_meshes;
+ Array<InvalidMeshGeometry> m_invalidMeshGeometry; // 1 per mesh.
+ Array<Array<ChartGroup *> > m_meshChartGroups;
bool m_chartsComputed;
bool m_chartsParameterized;
- Array<ChartGroup *> m_chartGroups;
- RadixSort m_chartGroupsRadix; // By mesh indexCount.
- Array<uint32_t> m_chartGroupSourceMeshes;
};
} // namespace param
@@ -7777,7 +8414,7 @@ static void runAddChartTask(void *userData)
auto args = (AddChartTaskArgs *)userData;
param::Chart *paramChart = args->paramChart;
XA_PROFILE_START(packChartsAddChartsRestoreTexcoords)
- paramChart->transferParameterization();
+ paramChart->restoreTexcoords();
XA_PROFILE_END(packChartsAddChartsRestoreTexcoords)
Mesh *mesh = paramChart->mesh();
Chart *chart = args->chart = XA_NEW(MemTag::Default, Chart);
@@ -7842,12 +8479,12 @@ struct Atlas
{
// Count charts.
uint32_t chartCount = 0;
- const uint32_t chartGroupsCount = paramAtlas->chartGroupCount();
- for (uint32_t i = 0; i < chartGroupsCount; i++) {
- const param::ChartGroup *chartGroup = paramAtlas->chartGroupAt(i);
- if (chartGroup->isVertexMap())
- continue;
- chartCount += chartGroup->chartCount();
+ for (uint32_t i = 0; i < paramAtlas->meshCount(); i++) {
+ const uint32_t chartGroupsCount = paramAtlas->chartGroupCount(i);
+ for (uint32_t j = 0; j < chartGroupsCount; j++) {
+ const param::ChartGroup *chartGroup = paramAtlas->chartGroupAt(i, j);
+ chartCount += chartGroup->chartCount();
+ }
}
if (chartCount == 0)
return;
@@ -7857,20 +8494,21 @@ struct Atlas
TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartCount);
uint32_t chartIndex = 0;
ThreadLocal<BoundingBox2D> boundingBox;
- for (uint32_t i = 0; i < chartGroupsCount; i++) {
- const param::ChartGroup *chartGroup = paramAtlas->chartGroupAt(i);
- if (chartGroup->isVertexMap())
- continue;
- const uint32_t count = chartGroup->chartCount();
- for (uint32_t j = 0; j < count; j++) {
- AddChartTaskArgs &args = taskArgs[chartIndex];
- args.boundingBox = &boundingBox;
- args.paramChart = chartGroup->chartAt(j);
- Task task;
- task.userData = &taskArgs[chartIndex];
- task.func = runAddChartTask;
- taskScheduler->run(taskGroup, task);
- chartIndex++;
+ for (uint32_t i = 0; i < paramAtlas->meshCount(); i++) {
+ const uint32_t chartGroupsCount = paramAtlas->chartGroupCount(i);
+ for (uint32_t j = 0; j < chartGroupsCount; j++) {
+ const param::ChartGroup *chartGroup = paramAtlas->chartGroupAt(i, j);
+ const uint32_t count = chartGroup->chartCount();
+ for (uint32_t k = 0; k < count; k++) {
+ AddChartTaskArgs &args = taskArgs[chartIndex];
+ args.boundingBox = &boundingBox;
+ args.paramChart = chartGroup->chartAt(k);
+ Task task;
+ task.userData = &taskArgs[chartIndex];
+ task.func = runAddChartTask;
+ taskScheduler->run(taskGroup, task);
+ chartIndex++;
+ }
}
}
taskScheduler->wait(&taskGroup);
@@ -8070,7 +8708,6 @@ struct Atlas
maxChartPerimeter = max(maxChartPerimeter, chartOrderArray[c]);
}
// Sort charts by perimeter.
- m_radix = RadixSort();
m_radix.sort(chartOrderArray);
const uint32_t *ranks = m_radix.ranks();
// Divide chart perimeter range into buckets.
@@ -8265,10 +8902,8 @@ struct Atlas
}
texcoord.x = best_x + t.x;
texcoord.y = best_y + t.y;
- if (!options.blockAlign) {
- texcoord.x -= (float)options.padding;
- texcoord.y -= (float)options.padding;
- }
+ texcoord.x -= (float)options.padding;
+ texcoord.y -= (float)options.padding;
XA_ASSERT(texcoord.x >= 0 && texcoord.y >= 0);
XA_ASSERT(isFinite(texcoord.x) && isFinite(texcoord.y));
}
@@ -8281,21 +8916,12 @@ struct Atlas
}
}
}
- if (options.blockAlign) {
- if (maxResolution == 0) {
- m_width = max(0, atlasSizes[0].x);
- m_height = max(0, atlasSizes[0].y);
- } else {
- m_width = m_height = maxResolution;
- }
+ // Remove padding from outer edges.
+ if (maxResolution == 0) {
+ m_width = max(0, atlasSizes[0].x - (int)options.padding * 2);
+ m_height = max(0, atlasSizes[0].y - (int)options.padding * 2);
} else {
- // Remove padding from outer edges.
- if (maxResolution == 0) {
- m_width = max(0, atlasSizes[0].x - (int)options.padding * 2);
- m_height = max(0, atlasSizes[0].y - (int)options.padding * 2);
- } else {
- m_width = m_height = maxResolution - (int)options.padding * 2;
- }
+ m_width = m_height = maxResolution - (int)options.padding * 2;
}
XA_PRINT(" %dx%d resolution\n", m_width, m_height);
m_utilization.resize(m_bitImages.size());
@@ -8557,13 +9183,13 @@ private:
struct Context
{
Atlas atlas;
- uint32_t meshCount = 0;
internal::Progress *addMeshProgress = nullptr;
internal::TaskGroupHandle addMeshTaskGroup;
internal::param::Atlas paramAtlas;
ProgressFunc progressFunc = nullptr;
void *progressUserData = nullptr;
internal::TaskScheduler *taskScheduler;
+ internal::Array<internal::Mesh *> meshes;
internal::Array<internal::UvMesh *> uvMeshes;
internal::Array<internal::UvMeshInstance *> uvMeshInstances;
};
@@ -8582,19 +9208,19 @@ static void DestroyOutputMeshes(Context *ctx)
return;
for (int i = 0; i < (int)ctx->atlas.meshCount; i++) {
Mesh &mesh = ctx->atlas.meshes[i];
- for (uint32_t j = 0; j < mesh.chartCount; j++) {
- if (mesh.chartArray[j].faceArray)
- XA_FREE(mesh.chartArray[j].faceArray);
- }
- if (mesh.chartArray)
+ if (mesh.chartArray) {
+ for (uint32_t j = 0; j < mesh.chartCount; j++) {
+ if (mesh.chartArray[j].faceArray)
+ XA_FREE(mesh.chartArray[j].faceArray);
+ }
XA_FREE(mesh.chartArray);
+ }
if (mesh.vertexArray)
XA_FREE(mesh.vertexArray);
if (mesh.indexArray)
XA_FREE(mesh.indexArray);
}
- if (ctx->atlas.meshes)
- XA_FREE(ctx->atlas.meshes);
+ XA_FREE(ctx->atlas.meshes);
ctx->atlas.meshes = nullptr;
}
@@ -8613,6 +9239,11 @@ void Destroy(Atlas *atlas)
}
ctx->taskScheduler->~TaskScheduler();
XA_FREE(ctx->taskScheduler);
+ for (uint32_t i = 0; i < ctx->meshes.size(); i++) {
+ internal::Mesh *mesh = ctx->meshes[i];
+ mesh->~Mesh();
+ XA_FREE(mesh);
+ }
for (uint32_t i = 0; i < ctx->uvMeshes.size(); i++) {
internal::UvMesh *mesh = ctx->uvMeshes[i];
for (uint32_t j = 0; j < mesh->charts.size(); j++) {
@@ -8655,56 +9286,9 @@ static void runAddMeshTask(void *userData)
}
if (progress->cancel)
goto cleanup;
- {
- XA_PROFILE_START(addMeshCreateFaceGroups)
- mesh->createFaceGroups();
- XA_PROFILE_END(addMeshCreateFaceGroups)
- }
- if (progress->cancel)
- goto cleanup;
-#if XA_DEBUG_EXPORT_OBJ_SOURCE_MESHES
- char filename[256];
- XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u.obj", mesh->id());
- FILE *file;
- XA_FOPEN(file, filename, "w");
- if (file) {
- mesh->writeObjVertices(file);
- // groups
- uint32_t numGroups = 0;
- for (uint32_t i = 0; i < mesh->faceCount(); i++) {
- if (mesh->faceGroupAt(i) != Mesh::kInvalidFaceGroup)
- numGroups = internal::max(numGroups, mesh->faceGroupAt(i) + 1);
- }
- for (uint32_t i = 0; i < numGroups; i++) {
- fprintf(file, "o group_%04d\n", i);
- fprintf(file, "s off\n");
- for (uint32_t f = 0; f < mesh->faceCount(); f++) {
- if (mesh->faceGroupAt(f) == i)
- mesh->writeObjFace(file, f);
- }
- }
- fprintf(file, "o group_ignored\n");
- fprintf(file, "s off\n");
- for (uint32_t f = 0; f < mesh->faceCount(); f++) {
- if (mesh->faceGroupAt(f) == Mesh::kInvalidFaceGroup)
- mesh->writeObjFace(file, f);
- }
- mesh->writeObjBoundaryEges(file);
- fclose(file);
- }
-#endif
- {
- XA_PROFILE_START(addMeshCreateChartGroupsReal)
- args->ctx->paramAtlas.addMesh(args->ctx->taskScheduler, mesh); // addMesh is thread safe
- XA_PROFILE_END(addMeshCreateChartGroupsReal)
- }
- if (progress->cancel)
- goto cleanup;
progress->value++;
progress->update();
cleanup:
- mesh->~Mesh();
- XA_FREE(mesh);
args->~AddMeshTaskArgs();
XA_FREE(args);
XA_PROFILE_END(addMeshThread)
@@ -8752,7 +9336,7 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh
return AddMeshError::Error;
}
#if XA_PROFILE
- if (ctx->meshCount == 0)
+ if (ctx->meshes.isEmpty())
internal::s_profile.addMeshReal = clock();
#endif
// Don't know how many times AddMesh will be called, so progress needs to adjusted each time.
@@ -8760,12 +9344,12 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh
ctx->addMeshProgress = XA_NEW_ARGS(internal::MemTag::Default, internal::Progress, ProgressCategory::AddMesh, ctx->progressFunc, ctx->progressUserData, 1);
}
else {
- ctx->addMeshProgress->setMaxValue(internal::max(ctx->meshCount + 1, meshCountHint));
+ ctx->addMeshProgress->setMaxValue(internal::max(ctx->meshes.size() + 1, meshCountHint));
}
XA_PROFILE_START(addMeshCopyData)
const bool hasIndices = meshDecl.indexCount > 0;
const uint32_t indexCount = hasIndices ? meshDecl.indexCount : meshDecl.vertexCount;
- XA_PRINT("Adding mesh %d: %u vertices, %u triangles\n", ctx->meshCount, meshDecl.vertexCount, indexCount / 3);
+ XA_PRINT("Adding mesh %d: %u vertices, %u triangles\n", ctx->meshes.size(), meshDecl.vertexCount, indexCount / 3);
// Expecting triangle faces.
if ((indexCount % 3) != 0)
return AddMeshError::InvalidIndexCount;
@@ -8777,10 +9361,10 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh
return AddMeshError::IndexOutOfRange;
}
}
- uint32_t meshFlags = internal::MeshFlags::HasFaceGroups | internal::MeshFlags::HasIgnoredFaces;
+ uint32_t meshFlags = internal::MeshFlags::HasIgnoredFaces;
if (meshDecl.vertexNormalData)
meshFlags |= internal::MeshFlags::HasNormals;
- internal::Mesh *mesh = XA_NEW_ARGS(internal::MemTag::Mesh, internal::Mesh, meshDecl.epsilon, meshDecl.vertexCount, indexCount / 3, meshFlags, ctx->meshCount);
+ internal::Mesh *mesh = XA_NEW_ARGS(internal::MemTag::Mesh, internal::Mesh, meshDecl.epsilon, meshDecl.vertexCount, indexCount / 3, meshFlags, ctx->meshes.size());
for (uint32_t i = 0; i < meshDecl.vertexCount; i++) {
internal::Vector3 normal(0.0f);
internal::Vector2 texcoord(0.0f);
@@ -8790,6 +9374,8 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh
texcoord = DecodeUv(meshDecl, i);
mesh->addVertex(DecodePosition(meshDecl, i), normal, texcoord);
}
+ const uint32_t kMaxWarnings = 50;
+ uint32_t warningCount = 0;
for (uint32_t i = 0; i < indexCount / 3; i++) {
uint32_t tri[3];
for (int j = 0; j < 3; j++)
@@ -8801,14 +9387,16 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh
const uint32_t index2 = tri[(j + 1) % 3];
if (index1 == index2) {
ignore = true;
- XA_PRINT(" Degenerate edge: index %d, index %d\n", index1, index2);
+ if (++warningCount <= kMaxWarnings)
+ XA_PRINT(" Degenerate edge: index %d, index %d\n", index1, index2);
break;
}
const internal::Vector3 &pos1 = mesh->position(index1);
const internal::Vector3 &pos2 = mesh->position(index2);
if (internal::length(pos2 - pos1) <= 0.0f) {
ignore = true;
- XA_PRINT(" Zero length edge: index %d position (%g %g %g), index %d position (%g %g %g)\n", index1, pos1.x, pos1.y, pos1.z, index2, pos2.x, pos2.y, pos2.z);
+ if (++warningCount <= kMaxWarnings)
+ XA_PRINT(" Zero length edge: index %d position (%g %g %g), index %d position (%g %g %g)\n", index1, pos1.x, pos1.y, pos1.z, index2, pos2.x, pos2.y, pos2.z);
break;
}
}
@@ -8817,14 +9405,16 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh
for (int j = 0; j < 3; j++) {
const internal::Vector3 &pos = mesh->position(tri[j]);
if (internal::isNan(pos.x) || internal::isNan(pos.y) || internal::isNan(pos.z)) {
- XA_PRINT(" NAN position in face: %d\n", i);
+ if (++warningCount <= kMaxWarnings)
+ XA_PRINT(" NAN position in face: %d\n", i);
ignore = true;
break;
}
if (meshDecl.vertexNormalData) {
const internal::Vector3 &normal = mesh->normal(tri[j]);
if (internal::isNan(normal.x) || internal::isNan(normal.y) || internal::isNan(normal.z)) {
- XA_PRINT(" NAN normal in face: %d\n", i);
+ if (++warningCount <= kMaxWarnings)
+ XA_PRINT(" NAN normal in face: %d\n", i);
ignore = true;
break;
}
@@ -8832,7 +9422,8 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh
if (meshDecl.vertexUvData) {
const internal::Vector2 &uv = mesh->texcoord(tri[j]);
if (internal::isNan(uv.x) || internal::isNan(uv.y)) {
- XA_PRINT(" NAN texture coordinate in face: %d\n", i);
+ if (++warningCount <= kMaxWarnings)
+ XA_PRINT(" NAN texture coordinate in face: %d\n", i);
ignore = true;
break;
}
@@ -8848,20 +9439,26 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh
area = internal::length(internal::cross(b - a, c - a)) * 0.5f;
if (area <= internal::kAreaEpsilon) {
ignore = true;
- XA_PRINT(" Zero area face: %d, indices (%d %d %d), area is %f\n", i, tri[0], tri[1], tri[2], area);
+ if (++warningCount <= kMaxWarnings)
+ XA_PRINT(" Zero area face: %d, indices (%d %d %d), area is %f\n", i, tri[0], tri[1], tri[2], area);
}
}
if (!ignore) {
if (internal::equal(a, b, meshDecl.epsilon) || internal::equal(a, c, meshDecl.epsilon) || internal::equal(b, c, meshDecl.epsilon)) {
ignore = true;
- XA_PRINT(" Degenerate face: %d, area is %f\n", i, area);
+ if (++warningCount <= kMaxWarnings)
+ XA_PRINT(" Degenerate face: %d, area is %f\n", i, area);
}
}
if (meshDecl.faceIgnoreData && meshDecl.faceIgnoreData[i])
ignore = true;
mesh->addFace(tri[0], tri[1], tri[2], ignore);
}
+ if (warningCount > kMaxWarnings)
+ XA_PRINT(" %u additional warnings truncated\n", warningCount - kMaxWarnings);
XA_PROFILE_END(addMeshCopyData)
+ ctx->meshes.push_back(mesh);
+ ctx->paramAtlas.addMesh(mesh);
if (ctx->addMeshTaskGroup.value == UINT32_MAX)
ctx->addMeshTaskGroup = ctx->taskScheduler->createTaskGroup();
AddMeshTaskArgs *taskArgs = XA_NEW(internal::MemTag::Default, AddMeshTaskArgs); // The task frees this.
@@ -8871,7 +9468,6 @@ AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t mesh
task.userData = taskArgs;
task.func = runAddMeshTask;
ctx->taskScheduler->run(ctx->addMeshTaskGroup, task);
- ctx->meshCount++;
return AddMeshError::Success;
}
@@ -8889,19 +9485,21 @@ void AddMeshJoin(Atlas *atlas)
ctx->addMeshProgress->~Progress();
XA_FREE(ctx->addMeshProgress);
ctx->addMeshProgress = nullptr;
- ctx->paramAtlas.sortChartGroups();
#if XA_PROFILE
- XA_PRINT("Added %u meshes\n", ctx->meshCount);
+ XA_PRINT("Added %u meshes\n", ctx->meshes.size());
internal::s_profile.addMeshReal = clock() - internal::s_profile.addMeshReal;
#endif
XA_PROFILE_PRINT_AND_RESET(" Total (real): ", addMeshReal)
XA_PROFILE_PRINT_AND_RESET(" Copy data: ", addMeshCopyData)
XA_PROFILE_PRINT_AND_RESET(" Total (thread): ", addMeshThread)
XA_PROFILE_PRINT_AND_RESET(" Create colocals: ", addMeshCreateColocals)
- XA_PROFILE_PRINT_AND_RESET(" Create face groups: ", addMeshCreateFaceGroups)
- XA_PROFILE_PRINT_AND_RESET(" Create chart groups (real): ", addMeshCreateChartGroupsReal)
- XA_PROFILE_PRINT_AND_RESET(" Create chart groups (thread): ", addMeshCreateChartGroupsThread)
+#if XA_PROFILE_ALLOC
+ XA_PROFILE_PRINT_AND_RESET(" Alloc: ", alloc)
+#endif
XA_PRINT_MEM_USAGE
+#if XA_DEBUG_EXPORT_OBJ_FACE_GROUPS
+ internal::param::s_faceGroupsCurrentVertex = 0;
+#endif
}
struct EdgeKey
@@ -8923,7 +9521,7 @@ AddMeshError::Enum AddUvMesh(Atlas *atlas, const UvMeshDecl &decl)
return AddMeshError::Error;
}
Context *ctx = (Context *)atlas;
- if (ctx->meshCount > 0) {
+ if (!ctx->meshes.isEmpty()) {
XA_PRINT_WARNING("AddUvMesh: Meshes and UV meshes cannot be added to the same atlas.\n");
return AddMeshError::Error;
}
@@ -9026,7 +9624,7 @@ AddMeshError::Enum AddUvMesh(Atlas *atlas, const UvMeshDecl &decl)
return AddMeshError::Success;
}
-void ComputeCharts(Atlas *atlas, ChartOptions chartOptions)
+void ComputeCharts(Atlas *atlas, ChartOptions options)
{
if (!atlas) {
XA_PRINT_WARNING("ComputeCharts: atlas is null.\n");
@@ -9038,69 +9636,65 @@ void ComputeCharts(Atlas *atlas, ChartOptions chartOptions)
return;
}
AddMeshJoin(atlas);
- if (ctx->meshCount == 0) {
+ if (ctx->meshes.isEmpty()) {
XA_PRINT_WARNING("ComputeCharts: No meshes. Call AddMesh first.\n");
return;
}
XA_PRINT("Computing charts\n");
- uint32_t chartCount = 0, chartsWithHolesCount = 0, holesCount = 0, chartsWithTJunctionsCount = 0, tJunctionsCount = 0;
XA_PROFILE_START(computeChartsReal)
- if (!ctx->paramAtlas.computeCharts(ctx->taskScheduler, chartOptions, ctx->progressFunc, ctx->progressUserData)) {
+ if (!ctx->paramAtlas.computeCharts(ctx->taskScheduler, options, ctx->progressFunc, ctx->progressUserData)) {
XA_PRINT(" Cancelled by user\n");
return;
}
XA_PROFILE_END(computeChartsReal)
- // Count charts and print warnings.
- for (uint32_t i = 0; i < ctx->meshCount; i++) {
+ // Count charts.
+ uint32_t chartCount = 0;
+ const uint32_t meshCount = ctx->meshes.size();
+ for (uint32_t i = 0; i < meshCount; i++) {
for (uint32_t j = 0; j < ctx->paramAtlas.chartGroupCount(i); j++) {
const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, j);
- if (chartGroup->isVertexMap())
- continue;
- for (uint32_t k = 0; k < chartGroup->chartCount(); k++) {
- const internal::param::Chart *chart = chartGroup->chartAt(k);
-#if XA_PRINT_CHART_WARNINGS
- if (chart->warningFlags() & internal::param::ChartWarningFlags::CloseHolesFailed)
- XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): failed to close holes\n", chartCount, i, j, k);
- if (chart->warningFlags() & internal::param::ChartWarningFlags::FixTJunctionsDuplicatedEdge)
- XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): fixing t-junctions created non-manifold geometry\n", chartCount, i, j, k);
- if (chart->warningFlags() & internal::param::ChartWarningFlags::FixTJunctionsFailed)
- XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): fixing t-junctions failed\n", chartCount, i, j, k);
- if (chart->warningFlags() & internal::param::ChartWarningFlags::TriangulateDuplicatedEdge)
- XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): triangulation created non-manifold geometry\n", chartCount, i, j, k);
-#endif
- holesCount += chart->closedHolesCount();
- if (chart->closedHolesCount() > 0)
- chartsWithHolesCount++;
- tJunctionsCount += chart->fixedTJunctionsCount();
- if (chart->fixedTJunctionsCount() > 0)
- chartsWithTJunctionsCount++;
- chartCount++;
- }
+ chartCount += chartGroup->segmentChartCount();
}
}
- if (holesCount > 0)
- XA_PRINT(" Closed %u holes in %u charts\n", holesCount, chartsWithHolesCount);
- if (tJunctionsCount > 0)
- XA_PRINT(" Fixed %u t-junctions in %u charts\n", tJunctionsCount, chartsWithTJunctionsCount);
XA_PRINT(" %u charts\n", chartCount);
+#if XA_PROFILE
+ XA_PRINT(" Chart groups\n");
+ uint32_t chartGroupCount = 0;
+ for (uint32_t i = 0; i < meshCount; i++) {
+ XA_PRINT(" Mesh %u: %u chart groups\n", i, ctx->paramAtlas.chartGroupCount(i));
+ chartGroupCount += ctx->paramAtlas.chartGroupCount(i);
+ }
+ XA_PRINT(" %u total\n", chartGroupCount);
+#endif
XA_PROFILE_PRINT_AND_RESET(" Total (real): ", computeChartsReal)
XA_PROFILE_PRINT_AND_RESET(" Total (thread): ", computeChartsThread)
- XA_PROFILE_PRINT_AND_RESET(" Build atlas: ", buildAtlas)
- XA_PROFILE_PRINT_AND_RESET(" Init: ", buildAtlasInit)
- XA_PROFILE_PRINT_AND_RESET(" Place seeds: ", buildAtlasPlaceSeeds)
- XA_PROFILE_PRINT_AND_RESET(" Relocate seeds: ", buildAtlasRelocateSeeds)
- XA_PROFILE_PRINT_AND_RESET(" Reset charts: ", buildAtlasResetCharts)
- XA_PROFILE_PRINT_AND_RESET(" Grow charts: ", buildAtlasGrowCharts)
- XA_PROFILE_PRINT_AND_RESET(" Merge charts: ", buildAtlasMergeCharts)
- XA_PROFILE_PRINT_AND_RESET(" Fill holes: ", buildAtlasFillHoles)
- XA_PROFILE_PRINT_AND_RESET(" Create chart meshes (real): ", createChartMeshesReal)
- XA_PROFILE_PRINT_AND_RESET(" Create chart meshes (thread): ", createChartMeshesThread)
- XA_PROFILE_PRINT_AND_RESET(" Fix t-junctions: ", fixChartMeshTJunctions)
- XA_PROFILE_PRINT_AND_RESET(" Close holes: ", closeChartMeshHoles)
+ XA_PROFILE_PRINT_AND_RESET(" Create face groups: ", createFaceGroups)
+ XA_PROFILE_PRINT_AND_RESET(" Extract invalid mesh geometry: ", extractInvalidMeshGeometry)
+ XA_PROFILE_PRINT_AND_RESET(" Chart group compute charts (real): ", chartGroupComputeChartsReal)
+ XA_PROFILE_PRINT_AND_RESET(" Chart group compute charts (thread): ", chartGroupComputeChartsThread)
+ XA_PROFILE_PRINT_AND_RESET(" Create chart group mesh: ", createChartGroupMesh)
+ XA_PROFILE_PRINT_AND_RESET(" Create colocals: ", createChartGroupMeshColocals)
+ XA_PROFILE_PRINT_AND_RESET(" Create boundaries: ", createChartGroupMeshBoundaries)
+ XA_PROFILE_PRINT_AND_RESET(" Build atlas: ", buildAtlas)
+ XA_PROFILE_PRINT_AND_RESET(" Init: ", buildAtlasInit)
+ XA_PROFILE_PRINT_AND_RESET(" Planar charts: ", planarCharts)
+ XA_PROFILE_PRINT_AND_RESET(" Clustered charts: ", clusteredCharts)
+ XA_PROFILE_PRINT_AND_RESET(" Place seeds: ", clusteredChartsPlaceSeeds)
+ XA_PROFILE_PRINT_AND_RESET(" Boundary intersection: ", clusteredChartsPlaceSeedsBoundaryIntersection)
+ XA_PROFILE_PRINT_AND_RESET(" Relocate seeds: ", clusteredChartsRelocateSeeds)
+ XA_PROFILE_PRINT_AND_RESET(" Reset: ", clusteredChartsReset)
+ XA_PROFILE_PRINT_AND_RESET(" Grow: ", clusteredChartsGrow)
+ XA_PROFILE_PRINT_AND_RESET(" Boundary intersection: ", clusteredChartsGrowBoundaryIntersection)
+ XA_PROFILE_PRINT_AND_RESET(" Merge: ", clusteredChartsMerge)
+ XA_PROFILE_PRINT_AND_RESET(" Fill holes: ", clusteredChartsFillHoles)
+ XA_PROFILE_PRINT_AND_RESET(" Copy chart faces: ", copyChartFaces)
+#if XA_PROFILE_ALLOC
+ XA_PROFILE_PRINT_AND_RESET(" Alloc: ", alloc)
+#endif
XA_PRINT_MEM_USAGE
}
-void ParameterizeCharts(Atlas *atlas, ParameterizeFunc func)
+void ParameterizeCharts(Atlas *atlas, ParameterizeOptions options)
{
if (!atlas) {
XA_PRINT_WARNING("ParameterizeCharts: atlas is null.\n");
@@ -9130,19 +9724,34 @@ void ParameterizeCharts(Atlas *atlas, ParameterizeFunc func)
DestroyOutputMeshes(ctx);
XA_PRINT("Parameterizing charts\n");
XA_PROFILE_START(parameterizeChartsReal)
- if (!ctx->paramAtlas.parameterizeCharts(ctx->taskScheduler, func, ctx->progressFunc, ctx->progressUserData)) {
+ if (!ctx->paramAtlas.parameterizeCharts(ctx->taskScheduler, options, ctx->progressFunc, ctx->progressUserData)) {
XA_PRINT(" Cancelled by user\n");
return;
}
XA_PROFILE_END(parameterizeChartsReal)
- uint32_t chartCount = 0, orthoChartsCount = 0, planarChartsCount = 0, lscmChartsCount = 0, piecewiseChartsCount = 0, chartsAddedCount = 0, chartsDeletedCount = 0;
- for (uint32_t i = 0; i < ctx->meshCount; i++) {
+ const uint32_t meshCount = ctx->meshes.size();
+ uint32_t chartCount = 0, chartsWithHolesCount = 0, holesCount = 0, chartsWithTJunctionsCount = 0, tJunctionsCount = 0, orthoChartsCount = 0, planarChartsCount = 0, lscmChartsCount = 0, piecewiseChartsCount = 0, chartsAddedCount = 0, chartsDeletedCount = 0;
+ for (uint32_t i = 0; i < meshCount; i++) {
for (uint32_t j = 0; j < ctx->paramAtlas.chartGroupCount(i); j++) {
const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, j);
- if (chartGroup->isVertexMap())
- continue;
for (uint32_t k = 0; k < chartGroup->chartCount(); k++) {
const internal::param::Chart *chart = chartGroup->chartAt(k);
+#if XA_PRINT_CHART_WARNINGS
+ if (chart->warningFlags() & internal::param::ChartWarningFlags::CloseHolesFailed)
+ XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): failed to close holes\n", chartCount, i, j, k);
+ if (chart->warningFlags() & internal::param::ChartWarningFlags::FixTJunctionsDuplicatedEdge)
+ XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): fixing t-junctions created non-manifold geometry\n", chartCount, i, j, k);
+ if (chart->warningFlags() & internal::param::ChartWarningFlags::FixTJunctionsFailed)
+ XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): fixing t-junctions failed\n", chartCount, i, j, k);
+ if (chart->warningFlags() & internal::param::ChartWarningFlags::TriangulateDuplicatedEdge)
+ XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): triangulation created non-manifold geometry\n", chartCount, i, j, k);
+#endif
+ holesCount += chart->closedHolesCount();
+ if (chart->closedHolesCount() > 0)
+ chartsWithHolesCount++;
+ tJunctionsCount += chart->fixedTJunctionsCount();
+ if (chart->fixedTJunctionsCount() > 0)
+ chartsWithTJunctionsCount++;
if (chart->type() == ChartType::Planar)
planarChartsCount++;
else if (chart->type() == ChartType::Ortho)
@@ -9157,19 +9766,21 @@ void ParameterizeCharts(Atlas *atlas, ParameterizeFunc func)
chartsDeletedCount += chartGroup->paramDeletedChartsCount();
}
}
+ if (holesCount > 0)
+ XA_PRINT(" %u holes closed in %u charts\n", holesCount, chartsWithHolesCount);
+ if (tJunctionsCount > 0)
+ XA_PRINT(" %u t-junctions fixed in %u charts\n", tJunctionsCount, chartsWithTJunctionsCount);
XA_PRINT(" %u planar charts, %u ortho charts, %u LSCM charts, %u piecewise charts\n", planarChartsCount, orthoChartsCount, lscmChartsCount, piecewiseChartsCount);
if (chartsDeletedCount > 0) {
XA_PRINT(" %u charts with invalid parameterizations replaced with %u new charts\n", chartsDeletedCount, chartsAddedCount);
XA_PRINT(" %u charts\n", chartCount);
}
uint32_t chartIndex = 0, invalidParamCount = 0;
- for (uint32_t i = 0; i < ctx->meshCount; i++) {
+ for (uint32_t i = 0; i < meshCount; i++) {
for (uint32_t j = 0; j < ctx->paramAtlas.chartGroupCount(i); j++) {
const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, j);
- if (chartGroup->isVertexMap())
- continue;
for (uint32_t k = 0; k < chartGroup->chartCount(); k++) {
- const internal::param::Chart *chart = chartGroup->chartAt(k);
+ internal::param::Chart *chart = chartGroup->chartAt(k);
const internal::param::Quality &quality = chart->quality();
#if XA_DEBUG_EXPORT_OBJ_CHARTS_AFTER_PARAMETERIZATION
{
@@ -9178,7 +9789,6 @@ void ParameterizeCharts(Atlas *atlas, ParameterizeFunc func)
chart->unifiedMesh()->writeObjFile(filename);
}
#endif
- bool invalid = false;
const char *type = "LSCM";
if (chart->type() == ChartType::Planar)
type = "planar";
@@ -9186,18 +9796,15 @@ void ParameterizeCharts(Atlas *atlas, ParameterizeFunc func)
type = "ortho";
else if (chart->type() == ChartType::Piecewise)
type = "piecewise";
- if (quality.boundaryIntersection) {
- invalid = true;
- XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u) (%s): invalid parameterization, self-intersecting boundary.\n", chartIndex, i, j, k, type);
- }
- if (quality.flippedTriangleCount > 0) {
- invalid = true;
- XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u) (%s): invalid parameterization, %u / %u flipped triangles.\n", chartIndex, i, j, k, type, quality.flippedTriangleCount, quality.totalTriangleCount);
- }
- if (invalid)
+ if (chart->isInvalid()) {
+ if (quality.boundaryIntersection) {
+ XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u) (%s): invalid parameterization, self-intersecting boundary.\n", chartIndex, i, j, k, type);
+ }
+ if (quality.flippedTriangleCount > 0) {
+ XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u) (%s): invalid parameterization, %u / %u flipped triangles.\n", chartIndex, i, j, k, type, quality.flippedTriangleCount, quality.totalTriangleCount);
+ }
invalidParamCount++;
#if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION
- if (invalid) {
char filename[256];
XA_SPRINTF(filename, sizeof(filename), "debug_chart_%03u_invalid_parameterization.obj", chartIndex);
const internal::Mesh *mesh = chart->unifiedMesh();
@@ -9218,8 +9825,8 @@ void ParameterizeCharts(Atlas *atlas, ParameterizeFunc func)
mesh->writeObjLinkedBoundaries(file);
fclose(file);
}
- }
#endif
+ }
chartIndex++;
}
}
@@ -9228,9 +9835,18 @@ void ParameterizeCharts(Atlas *atlas, ParameterizeFunc func)
XA_PRINT_WARNING(" %u charts with invalid parameterizations\n", invalidParamCount);
XA_PROFILE_PRINT_AND_RESET(" Total (real): ", parameterizeChartsReal)
XA_PROFILE_PRINT_AND_RESET(" Total (thread): ", parameterizeChartsThread)
+ XA_PROFILE_PRINT_AND_RESET(" Create chart mesh: ", createChartMesh)
+ XA_PROFILE_PRINT_AND_RESET(" Fix t-junctions: ", fixChartMeshTJunctions)
+ XA_PROFILE_PRINT_AND_RESET(" Close holes: ", closeChartMeshHoles)
XA_PROFILE_PRINT_AND_RESET(" Orthogonal: ", parameterizeChartsOrthogonal)
XA_PROFILE_PRINT_AND_RESET(" LSCM: ", parameterizeChartsLSCM)
+ XA_PROFILE_PRINT_AND_RESET(" Recompute: ", parameterizeChartsRecompute)
+ XA_PROFILE_PRINT_AND_RESET(" Piecewise: ", parameterizeChartsPiecewise)
+ XA_PROFILE_PRINT_AND_RESET(" Boundary intersection: ", parameterizeChartsPiecewiseBoundaryIntersection)
XA_PROFILE_PRINT_AND_RESET(" Evaluate quality: ", parameterizeChartsEvaluateQuality)
+#if XA_PROFILE_ALLOC
+ XA_PROFILE_PRINT_AND_RESET(" Alloc: ", alloc)
+#endif
XA_PRINT_MEM_USAGE
}
@@ -9242,7 +9858,7 @@ void PackCharts(Atlas *atlas, PackOptions packOptions)
return;
}
Context *ctx = (Context *)atlas;
- if (ctx->meshCount == 0 && ctx->uvMeshInstances.isEmpty()) {
+ if (ctx->meshes.isEmpty() && ctx->uvMeshInstances.isEmpty()) {
XA_PRINT_WARNING("PackCharts: No meshes. Call AddMesh or AddUvMesh first.\n");
return;
}
@@ -9299,7 +9915,7 @@ void PackCharts(Atlas *atlas, PackOptions packOptions)
if (packOptions.createImage) {
atlas->image = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, atlas->atlasCount * atlas->width * atlas->height);
for (uint32_t i = 0; i < atlas->atlasCount; i++)
- packAtlas.getImages()[i]->copyTo(&atlas->image[atlas->width * atlas->height * i], atlas->width, atlas->height, packOptions.blockAlign ? 0 : packOptions.padding);
+ packAtlas.getImages()[i]->copyTo(&atlas->image[atlas->width * atlas->height * i], atlas->width, atlas->height, packOptions.padding);
}
XA_PROFILE_PRINT_AND_RESET(" Total: ", packCharts)
XA_PROFILE_PRINT_AND_RESET(" Add charts (real): ", packChartsAddCharts)
@@ -9309,6 +9925,9 @@ void PackCharts(Atlas *atlas, PackOptions packOptions)
XA_PROFILE_PRINT_AND_RESET(" Dilate (padding): ", packChartsDilate)
XA_PROFILE_PRINT_AND_RESET(" Find location: ", packChartsFindLocation)
XA_PROFILE_PRINT_AND_RESET(" Blit: ", packChartsBlit)
+#if XA_PROFILE_ALLOC
+ XA_PROFILE_PRINT_AND_RESET(" Alloc: ", alloc)
+#endif
XA_PRINT_MEM_USAGE
XA_PRINT("Building output meshes\n");
XA_PROFILE_START(buildOutputMeshes)
@@ -9318,91 +9937,92 @@ void PackCharts(Atlas *atlas, PackOptions packOptions)
return;
}
if (ctx->uvMeshInstances.isEmpty())
- atlas->meshCount = ctx->meshCount;
+ atlas->meshCount = ctx->meshes.size();
else
atlas->meshCount = ctx->uvMeshInstances.size();
atlas->meshes = XA_ALLOC_ARRAY(internal::MemTag::Default, Mesh, atlas->meshCount);
memset(atlas->meshes, 0, sizeof(Mesh) * atlas->meshCount);
if (ctx->uvMeshInstances.isEmpty()) {
uint32_t chartIndex = 0;
- for (uint32_t i = 0; i < ctx->meshCount; i++) {
+ for (uint32_t i = 0; i < atlas->meshCount; i++) {
Mesh &outputMesh = atlas->meshes[i];
- // Count and alloc arrays. Ignore vertex mapped chart groups in Mesh::chartCount, since they're ignored faces.
+ // Count and alloc arrays.
+ const internal::param::InvalidMeshGeometry &invalid = ctx->paramAtlas.invalidMeshGeometry(i);
+ outputMesh.vertexCount += invalid.vertices().length;
+ outputMesh.indexCount += invalid.faces().length * 3;
for (uint32_t cg = 0; cg < ctx->paramAtlas.chartGroupCount(i); cg++) {
const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, cg);
- if (chartGroup->isVertexMap()) {
- outputMesh.vertexCount += chartGroup->mesh()->vertexCount();
- outputMesh.indexCount += chartGroup->mesh()->faceCount() * 3;
- } else {
- for (uint32_t c = 0; c < chartGroup->chartCount(); c++) {
- const internal::param::Chart *chart = chartGroup->chartAt(c);
- outputMesh.vertexCount += chart->mesh()->vertexCount();
- outputMesh.indexCount += chart->mesh()->faceCount() * 3;
- outputMesh.chartCount++;
- }
+ for (uint32_t c = 0; c < chartGroup->chartCount(); c++) {
+ const internal::param::Chart *chart = chartGroup->chartAt(c);
+ outputMesh.vertexCount += chart->mesh()->vertexCount();
+ outputMesh.indexCount += chart->mesh()->faceCount() * 3;
+ outputMesh.chartCount++;
}
}
outputMesh.vertexArray = XA_ALLOC_ARRAY(internal::MemTag::Default, Vertex, outputMesh.vertexCount);
outputMesh.indexArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputMesh.indexCount);
outputMesh.chartArray = XA_ALLOC_ARRAY(internal::MemTag::Default, Chart, outputMesh.chartCount);
- XA_PRINT(" mesh %u: %u vertices, %u triangles, %u charts\n", i, outputMesh.vertexCount, outputMesh.indexCount / 3, outputMesh.chartCount);
+ XA_PRINT(" Mesh %u: %u vertices, %u triangles, %u charts\n", i, outputMesh.vertexCount, outputMesh.indexCount / 3, outputMesh.chartCount);
// Copy mesh data.
- uint32_t firstVertex = 0, meshChartIndex = 0;
+ uint32_t firstVertex = 0;
+ {
+ const internal::param::InvalidMeshGeometry &mesh = ctx->paramAtlas.invalidMeshGeometry(i);
+ internal::ConstArrayView<uint32_t> faces = mesh.faces();
+ internal::ConstArrayView<uint32_t> indices = mesh.indices();
+ internal::ConstArrayView<uint32_t> vertices = mesh.vertices();
+ // Vertices.
+ for (uint32_t v = 0; v < vertices.length; v++) {
+ Vertex &vertex = outputMesh.vertexArray[v];
+ vertex.atlasIndex = -1;
+ vertex.chartIndex = -1;
+ vertex.uv[0] = vertex.uv[1] = 0.0f;
+ vertex.xref = vertices[v];
+ }
+ // Indices.
+ for (uint32_t f = 0; f < faces.length; f++) {
+ const uint32_t indexOffset = faces[f] * 3;
+ for (uint32_t j = 0; j < 3; j++)
+ outputMesh.indexArray[indexOffset + j] = indices[f * 3 + j];
+ }
+ firstVertex = vertices.length;
+ }
+ uint32_t meshChartIndex = 0;
for (uint32_t cg = 0; cg < ctx->paramAtlas.chartGroupCount(i); cg++) {
const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, cg);
- if (chartGroup->isVertexMap()) {
- const internal::Mesh *mesh = chartGroup->mesh();
+ for (uint32_t c = 0; c < chartGroup->chartCount(); c++) {
+ const internal::param::Chart *chart = chartGroup->chartAt(c);
+ const internal::Mesh *mesh = chart->mesh();
// Vertices.
for (uint32_t v = 0; v < mesh->vertexCount(); v++) {
Vertex &vertex = outputMesh.vertexArray[firstVertex + v];
- vertex.atlasIndex = -1;
- vertex.chartIndex = -1;
- vertex.uv[0] = vertex.uv[1] = 0.0f;
- vertex.xref = chartGroup->mapVertexToSourceVertex(v);
+ vertex.atlasIndex = packAtlas.getChart(chartIndex)->atlasIndex;
+ XA_DEBUG_ASSERT(vertex.atlasIndex >= 0);
+ vertex.chartIndex = (int32_t)chartIndex;
+ const internal::Vector2 &uv = mesh->texcoord(v);
+ vertex.uv[0] = internal::max(0.0f, uv.x);
+ vertex.uv[1] = internal::max(0.0f, uv.y);
+ vertex.xref = chart->mapChartVertexToSourceVertex(v);
}
// Indices.
for (uint32_t f = 0; f < mesh->faceCount(); f++) {
- const uint32_t indexOffset = chartGroup->mapFaceToSourceFace(f) * 3;
+ const uint32_t indexOffset = chart->mapFaceToSourceFace(f) * 3;
for (uint32_t j = 0; j < 3; j++)
outputMesh.indexArray[indexOffset + j] = firstVertex + mesh->vertexAt(f * 3 + j);
}
+ // Charts.
+ Chart *outputChart = &outputMesh.chartArray[meshChartIndex];
+ const int32_t atlasIndex = packAtlas.getChart(chartIndex)->atlasIndex;
+ XA_DEBUG_ASSERT(atlasIndex >= 0);
+ outputChart->atlasIndex = (uint32_t)atlasIndex;
+ outputChart->type = chart->isInvalid() ? ChartType::Invalid : chart->type();
+ outputChart->faceCount = mesh->faceCount();
+ outputChart->faceArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputChart->faceCount);
+ for (uint32_t f = 0; f < outputChart->faceCount; f++)
+ outputChart->faceArray[f] = chart->mapFaceToSourceFace(f);
+ outputChart->material = 0;
+ meshChartIndex++;
+ chartIndex++;
firstVertex += mesh->vertexCount();
- } else {
- for (uint32_t c = 0; c < chartGroup->chartCount(); c++) {
- const internal::param::Chart *chart = chartGroup->chartAt(c);
- const internal::Mesh *mesh = chart->mesh();
- // Vertices.
- for (uint32_t v = 0; v < mesh->vertexCount(); v++) {
- Vertex &vertex = outputMesh.vertexArray[firstVertex + v];
- vertex.atlasIndex = packAtlas.getChart(chartIndex)->atlasIndex;
- XA_DEBUG_ASSERT(vertex.atlasIndex >= 0);
- vertex.chartIndex = (int32_t)chartIndex;
- const internal::Vector2 &uv = mesh->texcoord(v);
- vertex.uv[0] = internal::max(0.0f, uv.x);
- vertex.uv[1] = internal::max(0.0f, uv.y);
- vertex.xref = chartGroup->mapVertexToSourceVertex(chart->mapChartVertexToOriginalVertex(v));
- }
- // Indices.
- for (uint32_t f = 0; f < mesh->faceCount(); f++) {
- const uint32_t indexOffset = chartGroup->mapFaceToSourceFace(chart->mapFaceToSourceFace(f)) * 3;
- for (uint32_t j = 0; j < 3; j++)
- outputMesh.indexArray[indexOffset + j] = firstVertex + mesh->vertexAt(f * 3 + j);
- }
- // Charts.
- Chart *outputChart = &outputMesh.chartArray[meshChartIndex];
- const int32_t atlasIndex = packAtlas.getChart(chartIndex)->atlasIndex;
- XA_DEBUG_ASSERT(atlasIndex >= 0);
- outputChart->atlasIndex = (uint32_t)atlasIndex;
- outputChart->type = chart->type();
- outputChart->faceCount = mesh->faceCount();
- outputChart->faceArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputChart->faceCount);
- for (uint32_t f = 0; f < outputChart->faceCount; f++)
- outputChart->faceArray[f] = chartGroup->mapFaceToSourceFace(chart->mapFaceToSourceFace(f));
- outputChart->material = 0;
- meshChartIndex++;
- chartIndex++;
- firstVertex += mesh->vertexCount();
- }
}
}
XA_DEBUG_ASSERT(outputMesh.vertexCount == firstVertex);
@@ -9476,10 +10096,13 @@ void PackCharts(Atlas *atlas, PackOptions packOptions)
ctx->progressFunc(ProgressCategory::BuildOutputMeshes, 100, ctx->progressUserData);
XA_PROFILE_END(buildOutputMeshes)
XA_PROFILE_PRINT_AND_RESET(" Total: ", buildOutputMeshes)
+#if XA_PROFILE_ALLOC
+ XA_PROFILE_PRINT_AND_RESET(" Alloc: ", alloc)
+#endif
XA_PRINT_MEM_USAGE
}
-void Generate(Atlas *atlas, ChartOptions chartOptions, ParameterizeFunc paramFunc, PackOptions packOptions)
+void Generate(Atlas *atlas, ChartOptions chartOptions, ParameterizeOptions parameterizeOptions, PackOptions packOptions)
{
if (!atlas) {
XA_PRINT_WARNING("Generate: atlas is null.\n");
@@ -9490,12 +10113,12 @@ void Generate(Atlas *atlas, ChartOptions chartOptions, ParameterizeFunc paramFun
XA_PRINT_WARNING("Generate: This function should not be called with UV meshes.\n");
return;
}
- if (ctx->meshCount == 0) {
+ if (ctx->meshes.isEmpty()) {
XA_PRINT_WARNING("Generate: No meshes. Call AddMesh first.\n");
return;
}
ComputeCharts(atlas, chartOptions);
- ParameterizeCharts(atlas, paramFunc);
+ ParameterizeCharts(atlas, parameterizeOptions);
PackCharts(atlas, packOptions);
}
diff --git a/thirdparty/xatlas/xatlas.h b/thirdparty/xatlas/xatlas.h
index e59f493287..cc47f4837e 100644
--- a/thirdparty/xatlas/xatlas.h
+++ b/thirdparty/xatlas/xatlas.h
@@ -1,7 +1,7 @@
/*
MIT License
-Copyright (c) 2018-2019 Jonathan Young
+Copyright (c) 2018-2020 Jonathan Young
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -42,18 +42,19 @@ struct ChartType
Planar,
Ortho,
LSCM,
- Piecewise
+ Piecewise,
+ Invalid
};
};
// A group of connected faces, belonging to a single atlas.
struct Chart
{
- uint32_t atlasIndex; // Sub-atlas index.
uint32_t *faceArray;
+ uint32_t atlasIndex; // Sub-atlas index.
uint32_t faceCount;
- uint32_t material;
ChartType::Enum type;
+ uint32_t material;
};
// Output vertex.
@@ -69,10 +70,10 @@ struct Vertex
struct Mesh
{
Chart *chartArray;
- uint32_t chartCount;
uint32_t *indexArray;
- uint32_t indexCount;
Vertex *vertexArray;
+ uint32_t chartCount;
+ uint32_t indexCount;
uint32_t vertexCount;
};
@@ -84,15 +85,15 @@ static const uint32_t kImageIsPaddingBit = 0x20000000;
// Empty on creation. Populated after charts are packed.
struct Atlas
{
+ uint32_t *image;
+ Mesh *meshes; // The output meshes, corresponding to each AddMesh call.
uint32_t width; // Atlas width in texels.
uint32_t height; // Atlas height in texels.
uint32_t atlasCount; // Number of sub-atlases. Equal to 0 unless PackOptions resolution is changed from default (0).
uint32_t chartCount; // Total number of charts in all meshes.
uint32_t meshCount; // Number of output meshes. Equal to the number of times AddMesh was called.
- Mesh *meshes; // The output meshes, corresponding to each AddMesh call.
float *utilization; // Normalized atlas texel utilization array. E.g. a value of 0.8 means 20% empty space. atlasCount in length.
float texelsPerUnit; // Equal to PackOptions texelsPerUnit if texelsPerUnit > 0, otherwise an estimated value to match PackOptions resolution.
- uint32_t *image;
};
// Create an empty atlas.
@@ -112,22 +113,23 @@ struct IndexFormat
// Input mesh declaration.
struct MeshDecl
{
- uint32_t vertexCount = 0;
const void *vertexPositionData = nullptr;
- uint32_t vertexPositionStride = 0;
const void *vertexNormalData = nullptr; // optional
- uint32_t vertexNormalStride = 0; // optional
const void *vertexUvData = nullptr; // optional. The input UVs are provided as a hint to the chart generator.
- uint32_t vertexUvStride = 0; // optional
- uint32_t indexCount = 0;
const void *indexData = nullptr; // optional
- int32_t indexOffset = 0; // optional. Add this offset to all indices.
- IndexFormat::Enum indexFormat = IndexFormat::UInt16;
// Optional. indexCount / 3 (triangle count) in length.
// Don't atlas faces set to true. Ignored faces still exist in the output meshes, Vertex uv is set to (0, 0) and Vertex atlasIndex to -1.
const bool *faceIgnoreData = nullptr;
+ uint32_t vertexCount = 0;
+ uint32_t vertexPositionStride = 0;
+ uint32_t vertexNormalStride = 0; // optional
+ uint32_t vertexUvStride = 0; // optional
+ uint32_t indexCount = 0;
+ int32_t indexOffset = 0; // optional. Add this offset to all indices.
+ IndexFormat::Enum indexFormat = IndexFormat::UInt16;
+
// Vertex positions within epsilon distance of each other are considered colocal.
float epsilon = 1.192092896e-07F;
};
@@ -151,14 +153,14 @@ void AddMeshJoin(Atlas *atlas);
struct UvMeshDecl
{
+ const void *vertexUvData = nullptr;
+ const void *indexData = nullptr; // optional
+ const uint32_t *faceMaterialData = nullptr; // Optional. Faces with different materials won't be assigned to the same chart. Must be indexCount / 3 in length.
uint32_t vertexCount = 0;
uint32_t vertexStride = 0;
- const void *vertexUvData = nullptr;
uint32_t indexCount = 0;
- const void *indexData = nullptr; // optional
int32_t indexOffset = 0; // optional. Add this offset to all indices.
IndexFormat::Enum indexFormat = IndexFormat::UInt16;
- const uint32_t *faceMaterialData = nullptr; // Optional. Faces with different materials won't be assigned to the same chart. Must be indexCount / 3 in length.
bool rotateCharts = true;
};
@@ -170,24 +172,31 @@ struct ChartOptions
float maxBoundaryLength = 0.0f; // Don't grow charts to have a longer boundary than this. 0 means no limit.
// Weights determine chart growth. Higher weights mean higher cost for that metric.
- float proxyFitMetricWeight = 2.0f; // Angle between face and average chart normal.
- float roundnessMetricWeight = 0.01f;
- float straightnessMetricWeight = 6.0f;
- float normalSeamMetricWeight = 4.0f; // If > 1000, normal seams are fully respected.
- float textureSeamMetricWeight = 0.5f;
+ float normalDeviationWeight = 2.0f; // Angle between face and average chart normal.
+ float roundnessWeight = 0.01f;
+ float straightnessWeight = 6.0f;
+ float normalSeamWeight = 4.0f; // If > 1000, normal seams are fully respected.
+ float textureSeamWeight = 0.5f;
- float maxThreshold = 2.0f; // If total of all metrics * weights > maxThreshold, don't grow chart. Lower values result in more charts.
+ float maxCost = 2.0f; // If total of all metrics * weights > maxCost, don't grow chart. Lower values result in more charts.
uint32_t maxIterations = 1; // Number of iterations of the chart growing and seeding phases. Higher values result in better charts.
};
// Call after all AddMesh calls. Can be called multiple times to recompute charts with different options.
-void ComputeCharts(Atlas *atlas, ChartOptions chartOptions = ChartOptions());
+void ComputeCharts(Atlas *atlas, ChartOptions options = ChartOptions());
// Custom parameterization function. texcoords initial values are an orthogonal parameterization.
typedef void (*ParameterizeFunc)(const float *positions, float *texcoords, uint32_t vertexCount, const uint32_t *indices, uint32_t indexCount);
+struct ParameterizeOptions
+{
+ ParameterizeFunc func = nullptr;
+ bool closeHoles = true; // If the custom parameterization function works with multiple boundaries, this can be set to false to improve performance.
+ bool fixTJunctions = true; // If meshes don't have T-junctions, this can be set to false to improve performance.
+};
+
// Call after ComputeCharts. Can be called multiple times to re-parameterize charts with a different ParameterizeFunc.
-void ParameterizeCharts(Atlas *atlas, ParameterizeFunc func = nullptr);
+void ParameterizeCharts(Atlas *atlas, ParameterizeOptions options = ParameterizeOptions());
struct PackOptions
{
@@ -224,7 +233,7 @@ struct PackOptions
void PackCharts(Atlas *atlas, PackOptions packOptions = PackOptions());
// Equivalent to calling ComputeCharts, ParameterizeCharts and PackCharts in sequence. Can be called multiple times to regenerate with different options.
-void Generate(Atlas *atlas, ChartOptions chartOptions = ChartOptions(), ParameterizeFunc paramFunc = nullptr, PackOptions packOptions = PackOptions());
+void Generate(Atlas *atlas, ChartOptions chartOptions = ChartOptions(), ParameterizeOptions parameterizeOptions = ParameterizeOptions(), PackOptions packOptions = PackOptions());
// Progress tracking.
struct ProgressCategory